From 7e15ef13989c72c82114097ef1a0bdee8fdfdca1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 15:05:43 +0200 Subject: [PATCH 0001/1182] first commit --- .gitignore | 3 +++ SDSLParser.sln | 27 ++++++++++++++++++++++++++ src/SDSLParser/Program.cs | 33 ++++++++++++++++++++++++++++++++ src/SDSLParser/SDSLParser.cs | 7 +++++++ src/SDSLParser/SDSLParser.csproj | 14 ++++++++++++++ src/SDSLParser/grammar.bnf | 16 ++++++++++++++++ src/SDSLParser/shader.sdsl | 3 +++ 7 files changed, 103 insertions(+) create mode 100644 .gitignore create mode 100644 SDSLParser.sln create mode 100644 src/SDSLParser/Program.cs create mode 100644 src/SDSLParser/SDSLParser.cs create mode 100644 src/SDSLParser/SDSLParser.csproj create mode 100644 src/SDSLParser/grammar.bnf create mode 100644 src/SDSLParser/shader.sdsl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..3afdc6664a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin/ +obj/ +.vscode/ \ No newline at end of file diff --git a/SDSLParser.sln b/SDSLParser.sln new file mode 100644 index 0000000000..e785c599da --- /dev/null +++ b/SDSLParser.sln @@ -0,0 +1,27 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B760-4857-BD74-296B07778B15}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParser", "src\SDSLParser\SDSLParser.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD} = {5F88D871-B760-4857-BD74-296B07778B15} + EndGlobalSection +EndGlobal diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs new file mode 100644 index 0000000000..001094fb09 --- /dev/null +++ b/src/SDSLParser/Program.cs @@ -0,0 +1,33 @@ +using Eto.Parse; +using Eto.Parse.Grammars; + +var ws = Terminals.WhiteSpace.Repeat(0); + +// parse a value with or without brackets +var valueParser = Terminals.Set('(') + .Then(Terminals.AnyChar.Repeat().Until(ws.Then(')')).Named("value")) + .Then(Terminals.Set(')')) + .SeparatedBy(ws) + .Or(Terminals.WhiteSpace.Inverse().Repeat().Named("value")); + +// our grammar +var grammar = new Grammar( + ws + .Then(valueParser.Named("first")) + .Then(valueParser.Named("second")) + .Then(Terminals.End) + .SeparatedBy(ws) +); +var grammar2 = new Grammar( + ws + .Then(Terminals.Set("shader")) + .Then(valueParser.Named("second")) + .Then(Terminals.End) + .SeparatedBy(ws) +); + +var input = " jojo ( vs dio ) "; +var matched = grammar.Match(input); +var parsed = grammar.Parse(new ParseArgs(null)); +var value = matched["second"]["value"].Value; +Console.WriteLine($"Hello, {value}!"); diff --git a/src/SDSLParser/SDSLParser.cs b/src/SDSLParser/SDSLParser.cs new file mode 100644 index 0000000000..f7e369f125 --- /dev/null +++ b/src/SDSLParser/SDSLParser.cs @@ -0,0 +1,7 @@ +namespace SDSLParser +{ + public class ShaderParser + { + + } +} \ No newline at end of file diff --git a/src/SDSLParser/SDSLParser.csproj b/src/SDSLParser/SDSLParser.csproj new file mode 100644 index 0000000000..580d8f16ed --- /dev/null +++ b/src/SDSLParser/SDSLParser.csproj @@ -0,0 +1,14 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + diff --git a/src/SDSLParser/grammar.bnf b/src/SDSLParser/grammar.bnf new file mode 100644 index 0000000000..b46f62aacb --- /dev/null +++ b/src/SDSLParser/grammar.bnf @@ -0,0 +1,16 @@ +(* := is an extension to define a literal with no whitespace between repeats and sequences *) +ws := {? Terminals.WhiteSpace ?}; + +letter or digit := ? Terminals.LetterOrDigit ?; + +simple value := letter or digit, {letter or digit}; + +bracket value = simple value, {simple value}; + +optional bracket = '(', bracket value, ')' | simple value; + +first = optional bracket; + +second = optional bracket; + +grammar = ws, first, second, ws; \ No newline at end of file diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl new file mode 100644 index 0000000000..ffb0a21a95 --- /dev/null +++ b/src/SDSLParser/shader.sdsl @@ -0,0 +1,3 @@ +shader Toto{ + float a; +} \ No newline at end of file From 635cf481dcc03c6b5cea14cbe8586fa2a3feaa68 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 15:21:01 +0200 Subject: [PATCH 0002/1182] Update parser --- src/SDSLParser/Program.cs | 32 +++++--------------------------- src/SDSLParser/SDSLGrammar.cs | 35 +++++++++++++++++++++++++++++++++++ src/SDSLParser/SDSLParser.cs | 7 ------- src/SDSLParser/shader.sdsl | 4 ++-- 4 files changed, 42 insertions(+), 36 deletions(-) create mode 100644 src/SDSLParser/SDSLGrammar.cs delete mode 100644 src/SDSLParser/SDSLParser.cs diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 001094fb09..491175e59c 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -1,33 +1,11 @@ using Eto.Parse; using Eto.Parse.Grammars; -var ws = Terminals.WhiteSpace.Repeat(0); -// parse a value with or without brackets -var valueParser = Terminals.Set('(') - .Then(Terminals.AnyChar.Repeat().Until(ws.Then(')')).Named("value")) - .Then(Terminals.Set(')')) - .SeparatedBy(ws) - .Or(Terminals.WhiteSpace.Inverse().Repeat().Named("value")); +var shaderf = File.ReadAllText("./shader.sdsl"); -// our grammar -var grammar = new Grammar( - ws - .Then(valueParser.Named("first")) - .Then(valueParser.Named("second")) - .Then(Terminals.End) - .SeparatedBy(ws) -); -var grammar2 = new Grammar( - ws - .Then(Terminals.Set("shader")) - .Then(valueParser.Named("second")) - .Then(Terminals.End) - .SeparatedBy(ws) -); +var parser = new SDSLParser.SDSLGrammar(); -var input = " jojo ( vs dio ) "; -var matched = grammar.Match(input); -var parsed = grammar.Parse(new ParseArgs(null)); -var value = matched["second"]["value"].Value; -Console.WriteLine($"Hello, {value}!"); +var matched = parser.Match(shaderf); + +Console.WriteLine($"Hello, world!"); diff --git a/src/SDSLParser/SDSLGrammar.cs b/src/SDSLParser/SDSLGrammar.cs new file mode 100644 index 0000000000..d9a28b7ad1 --- /dev/null +++ b/src/SDSLParser/SDSLGrammar.cs @@ -0,0 +1,35 @@ +using Eto.Parse; +using Eto.Parse.Parsers; + +namespace SDSLParser +{ + public class SDSLGrammar : Grammar + { + public SDSLGrammar() : base("sdsl") + { + EnableMatchEvents = false; + CaseSensitive = true; + + var shaderDeclaration = Terminals.Set("shader"); + var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0)); + var lbracket = Terminals.Set("{"); + var rbracket = Terminals.Set("}"); + + // var sdstring = new StringParser { AllowEscapeCharacters = true, Name = "string" }; + // var sdnumber = new NumberParser { AllowExponent = true, AllowSign = true, AllowDecimal = true, Name = "number" }; + // var sdboolean = new BooleanTerminal { Name = "bool", TrueValues = new string[] { "true" }, FalseValues = new string[] { "false" }, CaseSensitive = false }; + // var sdname = new StringParser { AllowEscapeCharacters = true, Name = "name" }; + // var sdnull = new LiteralTerminal { Value = "null", Name = "null", CaseSensitive = false }; + var ws = new RepeatCharTerminal(char.IsWhiteSpace); + // var commaDelimiter = new RepeatCharTerminal(new RepeatCharItem(char.IsWhiteSpace), ',', new RepeatCharItem(char.IsWhiteSpace)); + + Inner = + ws + .Then(shaderDeclaration) + .Then(name) + .Then(lbracket) + .Then(rbracket); + + } + } +} \ No newline at end of file diff --git a/src/SDSLParser/SDSLParser.cs b/src/SDSLParser/SDSLParser.cs deleted file mode 100644 index f7e369f125..0000000000 --- a/src/SDSLParser/SDSLParser.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SDSLParser -{ - public class ShaderParser - { - - } -} \ No newline at end of file diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index ffb0a21a95..2bc058c7db 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ -shader Toto{ - float a; +shader Toto { + } \ No newline at end of file From 5b00eb0d94903e5aaca72d1c760e5651e811a0bf Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 16:02:51 +0200 Subject: [PATCH 0003/1182] Grammar correction --- src/SDSLParser/Program.cs | 14 +++++++++++++- src/SDSLParser/SDSLGrammar.cs | 8 ++------ src/SDSLParser/grammar.bnf | 16 ---------------- src/SDSLParser/grammar.ebnf | 16 ++++++++++++++++ src/SDSLParser/shader.sdsl | 4 +--- 5 files changed, 32 insertions(+), 26 deletions(-) delete mode 100644 src/SDSLParser/grammar.bnf create mode 100644 src/SDSLParser/grammar.ebnf diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 491175e59c..a51d2f88f7 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -1,5 +1,6 @@ using Eto.Parse; using Eto.Parse.Grammars; +using System.Diagnostics; var shaderf = File.ReadAllText("./shader.sdsl"); @@ -8,4 +9,15 @@ var matched = parser.Match(shaderf); -Console.WriteLine($"Hello, world!"); + +var input = " hello ( parsing world ) "; + +// our grammar +var grammar = new EbnfGrammar(EbnfStyle.Iso14977).Build(File.ReadAllText("./grammar.ebnf"), "grammar"); + + +var s = new Stopwatch(); +s.Start(); +var match = grammar.Match(shaderf); +s.Stop(); +Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/SDSLParser/SDSLGrammar.cs b/src/SDSLParser/SDSLGrammar.cs index d9a28b7ad1..d81c3deb75 100644 --- a/src/SDSLParser/SDSLGrammar.cs +++ b/src/SDSLParser/SDSLGrammar.cs @@ -11,7 +11,7 @@ public SDSLGrammar() : base("sdsl") CaseSensitive = true; var shaderDeclaration = Terminals.Set("shader"); - var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter, 1, 1), new RepeatCharItem(Char.IsLetterOrDigit, 0)); + var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter), new RepeatCharItem(Char.IsLetterOrDigit, 0)); var lbracket = Terminals.Set("{"); var rbracket = Terminals.Set("}"); @@ -24,11 +24,7 @@ public SDSLGrammar() : base("sdsl") // var commaDelimiter = new RepeatCharTerminal(new RepeatCharItem(char.IsWhiteSpace), ',', new RepeatCharItem(char.IsWhiteSpace)); Inner = - ws - .Then(shaderDeclaration) - .Then(name) - .Then(lbracket) - .Then(rbracket); + ws & shaderDeclaration & ws & name & lbracket & rbracket; } } diff --git a/src/SDSLParser/grammar.bnf b/src/SDSLParser/grammar.bnf deleted file mode 100644 index b46f62aacb..0000000000 --- a/src/SDSLParser/grammar.bnf +++ /dev/null @@ -1,16 +0,0 @@ -(* := is an extension to define a literal with no whitespace between repeats and sequences *) -ws := {? Terminals.WhiteSpace ?}; - -letter or digit := ? Terminals.LetterOrDigit ?; - -simple value := letter or digit, {letter or digit}; - -bracket value = simple value, {simple value}; - -optional bracket = '(', bracket value, ')' | simple value; - -first = optional bracket; - -second = optional bracket; - -grammar = ws, first, second, ws; \ No newline at end of file diff --git a/src/SDSLParser/grammar.ebnf b/src/SDSLParser/grammar.ebnf new file mode 100644 index 0000000000..f6a0c83ad8 --- /dev/null +++ b/src/SDSLParser/grammar.ebnf @@ -0,0 +1,16 @@ +(* := is an extension to define a literal with no whitespace between repeats and sequences *) +ws := {? Terminals.WhiteSpace ?}; + +letter_or_digit := ? Terminals.LetterOrDigit ?; + +simple_value := letter_or_digit, {letter_or_digit}; + +bracket_value = simple value, {simple value}; + +expr = "{", "}"; + +first = optional_bracket; + +second = optional_bracket; + +grammar = ws, "shader", simple_value, expr; \ No newline at end of file diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index 2bc058c7db..419801ce58 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1 @@ -shader Toto { - -} \ No newline at end of file +shader Toto {} \ No newline at end of file From 9a568410a395256c4a58504efc35c5284c5d44f6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 16:46:16 +0200 Subject: [PATCH 0004/1182] update bnf eol --- src/SDSLParser/SDSLGrammar.cs | 2 +- src/SDSLParser/grammar.ebnf | 8 ++++++-- src/SDSLParser/shader.sdsl | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/SDSLParser/SDSLGrammar.cs b/src/SDSLParser/SDSLGrammar.cs index d81c3deb75..7122f5e043 100644 --- a/src/SDSLParser/SDSLGrammar.cs +++ b/src/SDSLParser/SDSLGrammar.cs @@ -9,7 +9,7 @@ public SDSLGrammar() : base("sdsl") { EnableMatchEvents = false; CaseSensitive = true; - + var shaderDeclaration = Terminals.Set("shader"); var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter), new RepeatCharItem(Char.IsLetterOrDigit, 0)); var lbracket = Terminals.Set("{"); diff --git a/src/SDSLParser/grammar.ebnf b/src/SDSLParser/grammar.ebnf index f6a0c83ad8..7de10a6a79 100644 --- a/src/SDSLParser/grammar.ebnf +++ b/src/SDSLParser/grammar.ebnf @@ -1,5 +1,7 @@ (* := is an extension to define a literal with no whitespace between repeats and sequences *) ws := {? Terminals.WhiteSpace ?}; +eol := ? Terminals.Eol ?, {? Terminals.Eol ?}; + letter_or_digit := ? Terminals.LetterOrDigit ?; @@ -7,10 +9,12 @@ simple_value := letter_or_digit, {letter_or_digit}; bracket_value = simple value, {simple value}; -expr = "{", "}"; +expr := [eol], [ws], [eol]; + +block := "{", expr, "}"; first = optional_bracket; second = optional_bracket; -grammar = ws, "shader", simple_value, expr; \ No newline at end of file +grammar = ws, "shader", simple_value, block; \ No newline at end of file diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index 419801ce58..ee7eccba51 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1 +1,3 @@ -shader Toto {} \ No newline at end of file +shader Toto { + +} \ No newline at end of file From 7188a78def71eb764f1feabca256eb71f84a4464 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 17:24:56 +0200 Subject: [PATCH 0005/1182] Added c bnf for inspiration --- src/SDSLParser/c.bnf | 231 ++++++++++++++++++++++++++++++++++++ src/SDSLParser/grammar.ebnf | 21 ++-- src/SDSLParser/shader.sdsl | 4 +- 3 files changed, 247 insertions(+), 9 deletions(-) create mode 100644 src/SDSLParser/c.bnf diff --git a/src/SDSLParser/c.bnf b/src/SDSLParser/c.bnf new file mode 100644 index 0000000000..4008ba35f5 --- /dev/null +++ b/src/SDSLParser/c.bnf @@ -0,0 +1,231 @@ +The syntax of C in Backus-Naur Form + ::= {}* + + ::= + | + + ::= {}* {}* + + ::= + | + | + + ::= auto + | register + | static + | extern + | typedef + + ::= void + | char + | short + | int + | long + | float + | double + | signed + | unsigned + | + | + | + + ::= { {}+ } + | { {}+ } + | + + ::= struct + | union + + ::= {}* + + ::= + | + + ::= + | , + + ::= + | : + | : + + ::= {}? + + ::= * {}* {}? + + ::= const + | volatile + + ::= + | ( ) + | [ {}? ] + | ( ) + | ( {}* ) + + ::= + + ::= + | ? : + + ::= + | || + + ::= + | && + + ::= + | | + + ::= + | ^ + + ::= + | & + + ::= + | == + | != + + ::= + | < + | > + | <= + | >= + + ::= + | << + | >> + + ::= + | + + | - + + ::= + | * + | / + | % + + ::= + | ( ) + + ::= + | ++ + | -- + | + | sizeof + | sizeof + + ::= + | [ ] + | ( {}* ) + | . + | -> + | ++ + | -- + + ::= + | + | + | ( ) + + ::= + | + | + | + + ::= + | , + + ::= + | + + ::= = + | *= + | /= + | %= + | += + | -= + | <<= + | >>= + | &= + | ^= + | |= + + ::= & + | * + | + + | - + | ~ + | ! + + ::= {}+ {}? + + ::= + | , ... + + ::= + | , + + ::= {}+ + | {}+ + | {}+ + + ::= + | + | + + ::= ( ) + | {}? [ {}? ] + | {}? ( {}? ) + + ::= enum { } + | enum { } + | enum + + ::= + | , + + ::= + | = + + ::= + + ::= {}+ {}* ; + + ::= + | = + + ::= + | { } + | { , } + + ::= + | , + + ::= { {}* {}* } + + ::= + | + | + | + | + | + + ::= : + | case : + | default : + + ::= {}? ; + + ::= if ( ) + | if ( ) else + | switch ( ) + + ::= while ( ) + | do while ( ) ; + | for ( {}? ; {}? ; {}? ) + + ::= goto ; + | continue ; + | break ; + | return {}? ; +This grammar was adapted from Section A13 of The C programming language, 2nd edition, by Brian W. Kernighan and Dennis M. Ritchie,Prentice Hall, 1988. \ No newline at end of file diff --git a/src/SDSLParser/grammar.ebnf b/src/SDSLParser/grammar.ebnf index 7de10a6a79..daf42703d3 100644 --- a/src/SDSLParser/grammar.ebnf +++ b/src/SDSLParser/grammar.ebnf @@ -2,10 +2,21 @@ ws := {? Terminals.WhiteSpace ?}; eol := ? Terminals.Eol ?, {? Terminals.Eol ?}; +unary_operator ::= + & + | * + | + + | - + | ~ + | !; -letter_or_digit := ? Terminals.LetterOrDigit ?; -simple_value := letter_or_digit, {letter_or_digit}; + + +letter = ? Terminals.Letter ?, {? Terminals.Letter ?}; +letter_or_digit = ? Terminals.LetterOrDigit ?, {? Terminals.LetterOrDigit ?}; + +identifier := letter, {"_", letter_or_digit}; bracket_value = simple value, {simple value}; @@ -13,8 +24,4 @@ expr := [eol], [ws], [eol]; block := "{", expr, "}"; -first = optional_bracket; - -second = optional_bracket; - -grammar = ws, "shader", simple_value, block; \ No newline at end of file +grammar = ws, "shader", identifier, block; \ No newline at end of file diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index ee7eccba51..d6c07dc9b9 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ -shader Toto { - +shader Toto_Mano { + } \ No newline at end of file From b56fd817069469cf41d52520f1bcaf192255db58 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 19 Apr 2022 17:43:37 +0200 Subject: [PATCH 0006/1182] Added constants --- src/SDSLParser/Program.cs | 2 ++ src/SDSLParser/grammar.ebnf | 21 ++++++++++++--------- src/SDSLParser/shader.sdsl | 2 +- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index a51d2f88f7..d9ade0f505 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -19,5 +19,7 @@ var s = new Stopwatch(); s.Start(); var match = grammar.Match(shaderf); +// var match = grammar.Match("1"); + s.Stop(); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/SDSLParser/grammar.ebnf b/src/SDSLParser/grammar.ebnf index daf42703d3..310586a443 100644 --- a/src/SDSLParser/grammar.ebnf +++ b/src/SDSLParser/grammar.ebnf @@ -2,16 +2,19 @@ ws := {? Terminals.WhiteSpace ?}; eol := ? Terminals.Eol ?, {? Terminals.Eol ?}; -unary_operator ::= - & - | * - | + - | - - | ~ - | !; - +unary_operator := + "&" + | "*" + | "+" + | "-" + | "~" + | "!"; +integer_cst := ? Terminals.Digit ?, {? Terminals.Digit ?}; +float_cst := integer_cst, "f" | integer_cst, ".", integer_cst; +bool_cst := "true" | "false"; +constants := integer_cst | float_cst | bool_cst; letter = ? Terminals.Letter ?, {? Terminals.Letter ?}; letter_or_digit = ? Terminals.LetterOrDigit ?, {? Terminals.LetterOrDigit ?}; @@ -20,7 +23,7 @@ identifier := letter, {"_", letter_or_digit}; bracket_value = simple value, {simple value}; -expr := [eol], [ws], [eol]; +expr := [eol], [ws | constants], [eol]; block := "{", expr, "}"; diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index d6c07dc9b9..a55a013605 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ shader Toto_Mano { - + 1 } \ No newline at end of file From 0f994fd12bfede6bb291d01217d395e5ae6d0c83 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 20 Apr 2022 12:43:42 +0200 Subject: [PATCH 0007/1182] Added more expressions --- src/SDSLParser/Program.cs | 4 +- src/SDSLParser/SDSLGrammar.cs | 2 + src/SDSLParser/grammar.ebnf | 95 +++++++++++++++++++++++++++++++++-- 3 files changed, 94 insertions(+), 7 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index d9ade0f505..e07a789d03 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -19,7 +19,7 @@ var s = new Stopwatch(); s.Start(); var match = grammar.Match(shaderf); -// var match = grammar.Match("1"); - +// var match = grammar.Match("12"); s.Stop(); +Console.WriteLine(match.ErrorMessage); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/SDSLParser/SDSLGrammar.cs b/src/SDSLParser/SDSLGrammar.cs index 7122f5e043..f22641bbb8 100644 --- a/src/SDSLParser/SDSLGrammar.cs +++ b/src/SDSLParser/SDSLGrammar.cs @@ -9,6 +9,8 @@ public SDSLGrammar() : base("sdsl") { EnableMatchEvents = false; CaseSensitive = true; + + var d = Terminals.End; var shaderDeclaration = Terminals.Set("shader"); var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter), new RepeatCharItem(Char.IsLetterOrDigit, 0)); diff --git a/src/SDSLParser/grammar.ebnf b/src/SDSLParser/grammar.ebnf index 310586a443..b9cd5202d9 100644 --- a/src/SDSLParser/grammar.ebnf +++ b/src/SDSLParser/grammar.ebnf @@ -1,6 +1,12 @@ (* := is an extension to define a literal with no whitespace between repeats and sequences *) ws := {? Terminals.WhiteSpace ?}; eol := ? Terminals.Eol ?, {? Terminals.Eol ?}; +eof := ? Terminals.End ?; + +letter = ? Terminals.Letter ?, {? Terminals.Letter ?}; +letter_or_digit = ? Terminals.LetterOrDigit ?, {? Terminals.LetterOrDigit ?}; + +identifier := letter, {"_", letter_or_digit}; unary_operator := "&" @@ -10,21 +16,100 @@ unary_operator := | "~" | "!"; +assignment_operator := + "=" + | "*=" + | "/=" + | "%=" + | "+=" + | "-=" + | "<<=" + | ">>=" + | "&=" + | "^=" + | "|="; + integer_cst := ? Terminals.Digit ?, {? Terminals.Digit ?}; float_cst := integer_cst, "f" | integer_cst, ".", integer_cst; bool_cst := "true" | "false"; constants := integer_cst | float_cst | bool_cst; -letter = ? Terminals.Letter ?, {? Terminals.Letter ?}; -letter_or_digit = ? Terminals.LetterOrDigit ?, {? Terminals.LetterOrDigit ?}; +conditional_expression := + logical_or_expression + | logical_or_expression, '?', expression, ':', conditional_expression; -identifier := letter, {"_", letter_or_digit}; +logical_or_expression := logical_and_expression + | logical_or_expression, "||", logical_and_expression; + +logical_and_expression := inclusive_or_expression + | logical_and_expression, "&&", inclusive_or_expression; + +inclusive_or_expression := exclusive_or_expression + | inclusive_or_expression, "|", exclusive_or_expression; + +exclusive_or_expression := and_expression + | exclusive_or_expression, "^", and_expression; + +and_expression := equality_expression + | and_expression, "&", equality_expression; + +equality_expression := relational_expression + | equality_expression, "==", relational_expression + | equality_expression, "!=", relational_expression; + +relational_expression := shift_expression + | relational_expression, "<", shift_expression + | relational_expression, ">", shift_expression + | relational_expression, "<=", shift_expression + | relational_expression, ">=", shift_expression; + +shift_expression := additive_expression + | shift_expression, "<<", additive_expression + | shift_expression, ">>", additive_expression; + +additive_expression := multiplicative_expression + | additive_expression, "+", multiplicative_expression + | additive_expression, "-", multiplicative_expression; + +multiplicative_expression := cast_expression + | multiplicative_expression, "*", cast_expression + | multiplicative_expression, "/", cast_expression + | multiplicative_expression, "%", cast_expression; + +cast_expression := unary_expression + | "(", type_name, ")", cast_expression; + + +unary_expression := + postfix_expression + | '++', unary_expression + | '--', unary_expression + | unary_operator, cast_expression + | 'sizeof', unary_expression + | 'sizeof', type_name; + +assignment_expression := + conditional_expression + | unary_expression, assignment_operator, assignment_expression; + +expression := + assignment_expression + | expression, assignment_expression; + + + +primary_expr := identifier | constants; + +postfix_expr := + primary_expr + | postfix_expr, '[',ex; bracket_value = simple value, {simple value}; -expr := [eol], [ws | constants], [eol]; +expr := [eol], [ws] , [constants], [eol]; block := "{", expr, "}"; -grammar = ws, "shader", identifier, block; \ No newline at end of file +grammar = ws, "shader", identifier, block; +(* grammar := integer_cst, [eof]; *) \ No newline at end of file From 21b6a2158c2a7a2c8a157fd3cb5b846673237f53 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Apr 2022 15:20:06 +0200 Subject: [PATCH 0008/1182] Added module --- .gitmodules | 3 +++ src/Eto.Parse | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 src/Eto.Parse diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..30a1b156a7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".\\src\\Eto.Parse"] + path = .\\src\\Eto.Parse + url = https://github.com/ykafia/Eto.Parse diff --git a/src/Eto.Parse b/src/Eto.Parse new file mode 160000 index 0000000000..af87b77d8c --- /dev/null +++ b/src/Eto.Parse @@ -0,0 +1 @@ +Subproject commit af87b77d8c63ef675e65815770bea71ca32e2ae7 From bd6b2cbb08bef9052d3f2ab33a143901d0427d0a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Apr 2022 15:20:17 +0200 Subject: [PATCH 0009/1182] Changed folder structure --- .gitignore | 3 +- SDSLParser.sln | 14 +++ src/SDSLParser/Program.cs | 20 ++--- src/SDSLParser/SDSLGrammar.cs | 33 ------- src/SDSLParser/SDSLParser.csproj | 9 +- src/SDSLParser/shader.sdsl | 2 +- src/Stride.Shader.Parser.Test/BasicParsing.cs | 81 +++++++++++++++++ .../Stride.Shader.Parser.Test.csproj | 28 ++++++ src/Stride.Shader.Parser/SDSLGrammar.cs | 68 +++++++++++++++ .../Stride.Shader.Parser.csproj | 13 +++ src/Stride.Shader.Parser/TestGrammar.cs | 87 +++++++++++++++++++ .../c.bnf | 0 .../grammar.ebnf | 64 +++++++++++--- 13 files changed, 358 insertions(+), 64 deletions(-) delete mode 100644 src/SDSLParser/SDSLGrammar.cs create mode 100644 src/Stride.Shader.Parser.Test/BasicParsing.cs create mode 100644 src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj create mode 100644 src/Stride.Shader.Parser/SDSLGrammar.cs create mode 100644 src/Stride.Shader.Parser/Stride.Shader.Parser.csproj create mode 100644 src/Stride.Shader.Parser/TestGrammar.cs rename src/{SDSLParser => Stride.Shader.Parser}/c.bnf (100%) rename src/{SDSLParser => Stride.Shader.Parser}/grammar.ebnf (62%) diff --git a/.gitignore b/.gitignore index 3afdc6664a..2f3aa2c250 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin/ obj/ -.vscode/ \ No newline at end of file +.vscode/ +.fake \ No newline at end of file diff --git a/SDSLParser.sln b/SDSLParser.sln index e785c599da..2a1ef67824 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -7,6 +7,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B76 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParser", "src\SDSLParser\SDSLParser.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parser", "src\Stride.Shader.Parser\Stride.Shader.Parser.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parser.Test", "src\Stride.Shader.Parser.Test\Stride.Shader.Parser.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,8 +24,18 @@ Global {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.Build.0 = Debug|Any CPU {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.ActiveCfg = Release|Any CPU {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.Build.0 = Release|Any CPU + {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Release|Any CPU.Build.0 = Release|Any CPU + {6D885FCB-C043-4065-BA7E-E4937667B219}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D885FCB-C043-4065-BA7E-E4937667B219}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D885FCB-C043-4065-BA7E-E4937667B219}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D885FCB-C043-4065-BA7E-E4937667B219}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD} = {5F88D871-B760-4857-BD74-296B07778B15} + {3A20C614-0B73-4592-B0A3-152FBA7C112C} = {5F88D871-B760-4857-BD74-296B07778B15} + {6D885FCB-C043-4065-BA7E-E4937667B219} = {5F88D871-B760-4857-BD74-296B07778B15} EndGlobalSection EndGlobal diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index e07a789d03..d613666f32 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -1,25 +1,19 @@ using Eto.Parse; using Eto.Parse.Grammars; +using Stride.Shader.Parser; using System.Diagnostics; -var shaderf = File.ReadAllText("./shader.sdsl"); - -var parser = new SDSLParser.SDSLGrammar(); - -var matched = parser.Match(shaderf); - - -var input = " hello ( parsing world ) "; - -// our grammar -var grammar = new EbnfGrammar(EbnfStyle.Iso14977).Build(File.ReadAllText("./grammar.ebnf"), "grammar"); +// var shaderf = File.ReadAllText("./shader.sdsl"); +var parser = new SDSLGrammar(); var s = new Stopwatch(); s.Start(); -var match = grammar.Match(shaderf); -// var match = grammar.Match("12"); +var match = parser.Match("(((5)))"); s.Stop(); + Console.WriteLine(match.ErrorMessage); +match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); + diff --git a/src/SDSLParser/SDSLGrammar.cs b/src/SDSLParser/SDSLGrammar.cs deleted file mode 100644 index f22641bbb8..0000000000 --- a/src/SDSLParser/SDSLGrammar.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; - -namespace SDSLParser -{ - public class SDSLGrammar : Grammar - { - public SDSLGrammar() : base("sdsl") - { - EnableMatchEvents = false; - CaseSensitive = true; - - var d = Terminals.End; - - var shaderDeclaration = Terminals.Set("shader"); - var name = Terminals.Repeat(new RepeatCharItem(Char.IsLetter), new RepeatCharItem(Char.IsLetterOrDigit, 0)); - var lbracket = Terminals.Set("{"); - var rbracket = Terminals.Set("}"); - - // var sdstring = new StringParser { AllowEscapeCharacters = true, Name = "string" }; - // var sdnumber = new NumberParser { AllowExponent = true, AllowSign = true, AllowDecimal = true, Name = "number" }; - // var sdboolean = new BooleanTerminal { Name = "bool", TrueValues = new string[] { "true" }, FalseValues = new string[] { "false" }, CaseSensitive = false }; - // var sdname = new StringParser { AllowEscapeCharacters = true, Name = "name" }; - // var sdnull = new LiteralTerminal { Value = "null", Name = "null", CaseSensitive = false }; - var ws = new RepeatCharTerminal(char.IsWhiteSpace); - // var commaDelimiter = new RepeatCharTerminal(new RepeatCharItem(char.IsWhiteSpace), ',', new RepeatCharItem(char.IsWhiteSpace)); - - Inner = - ws & shaderDeclaration & ws & name & lbracket & rbracket; - - } - } -} \ No newline at end of file diff --git a/src/SDSLParser/SDSLParser.csproj b/src/SDSLParser/SDSLParser.csproj index 580d8f16ed..e02c07bb7b 100644 --- a/src/SDSLParser/SDSLParser.csproj +++ b/src/SDSLParser/SDSLParser.csproj @@ -1,5 +1,10 @@ + + + + + Exe net6.0 @@ -7,8 +12,6 @@ enable - - - + diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index a55a013605..2a862e93c8 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ shader Toto_Mano { - 1 + 5.0f; } \ No newline at end of file diff --git a/src/Stride.Shader.Parser.Test/BasicParsing.cs b/src/Stride.Shader.Parser.Test/BasicParsing.cs new file mode 100644 index 0000000000..09501c4f3f --- /dev/null +++ b/src/Stride.Shader.Parser.Test/BasicParsing.cs @@ -0,0 +1,81 @@ +using Xunit; +using System.Linq; +using Stride.Shader.Parser; +using Eto.Parse; +using Eto.Parse.Parsers; +using System.Collections.Generic; + +namespace Stride.Shader.Parser.Test; + +public class BasicParsing +{ + SDSLGrammar Grammar; + public BasicParsing() + { + Grammar = new(); + } + [Fact] + public void TestIdentifier() + { + var matches = new List<(string Name,GrammarMatch Matching)>{ + ("myVar",Grammar.Match("myVar")), + ("my_Var",Grammar.Match("my_Var")), + ("my_Var2",Grammar.Match("my_Var2")), + ("my2Var",Grammar.Match("my2Var")), + ("myVar",Grammar.Match("myVar")) + }; + + foreach(var (Name, Matching) in matches) + { + Assert.True(Matching.HasMatches); + // Assert.True(Matching.Matches.Exists(x => x.Name == "Identifier")); + Assert.True(Matching.Matches[0].StringValue == Name); + } + + } + [Fact] + public void TestConstant() + { + var values = new string[]{ + "5", + "50", + "51.5", + "0", + "-1" + }; + var matches = + values.Select(x => (x,Grammar.Match(x))); + + foreach(var (Original, Matching) in matches) + { + Assert.True(Matching.HasMatches); + Assert.True(Matching.Matches[0].StringValue == Original); + } + } + [Fact] + public void TestAdd() + { + + } + [Fact] + public void TestMult() + { + + } + [Fact] + public void TestAssign() + { + + } + [Fact] + public void TestParenthesis() + { + + } + [Fact] + public void TestOperations() + { + + } + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj b/src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj new file mode 100644 index 0000000000..42fa97f2c5 --- /dev/null +++ b/src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj @@ -0,0 +1,28 @@ + + + + net6.0 + enable + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/src/Stride.Shader.Parser/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar.cs new file mode 100644 index 0000000000..166a2450c2 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar.cs @@ -0,0 +1,68 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public class SDSLGrammar : Grammar +{ + public SDSLGrammar() : base("sdsl") + { + EnableMatchEvents = false; + CaseSensitive = true; + + var ws = new RepeatCharTerminal(char.IsWhiteSpace); + var wso = ws.Optional(); + + var eof = End; + + var eol = Eol; + var eolo = eol.Optional(); + + var shaderDeclaration = Set("shader"); + + var ldu = LetterOrDigit | "_"; + var identifier = LetterOrDigit.Then(ldu.Repeat().Optional()).WithName("Identifier"); + + var lbr = Set("{"); + var rbr = Set("}"); + + var floatParser = new NumberParser{AllowSign = true, AllowDecimal = true, AllowExponent = true,ValueType = typeof(double), Name = "ConstantDouble", AddMatch = true, AddError = true}; + var intParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "ConstantInteger", AddMatch = true, AddError = true}; + var boolParser = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"}, FalseValues = new string[]{"false"}, AddError = true, AddMatch = true, Name = "ConstantBoolean"}; + + var constants = floatParser.Or(intParser).Or(boolParser).WithName("Constant"); + + //Step 1 parse addition + + var primary_expr = identifier.Or(constants).WithName("PrimaryExpression"); + + + + var assign = identifier.Then(Set("=")).Then(primary_expr).WithName("AssignExpression"); + + var parenthesis_expr = new SequenceParser(); + parenthesis_expr.Add( + primary_expr + .Or( + Set("(").Then(parenthesis_expr).Then(")") + ) + ); + parenthesis_expr.WithName("ParenthesisExpression"); + + var mul_expr = new SequenceParser(); + + mul_expr.Add( + parenthesis_expr.WithName("BasicMul") + .Or( + mul_expr.Then("*").Then(mul_expr) + ) + ); + mul_expr.WithName("MultExpression"); + + + + + Inner = mul_expr; + + } +} diff --git a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj new file mode 100644 index 0000000000..7a86fc8a58 --- /dev/null +++ b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj @@ -0,0 +1,13 @@ + + + + + + + + net6.0 + enable + enable + + + diff --git a/src/Stride.Shader.Parser/TestGrammar.cs b/src/Stride.Shader.Parser/TestGrammar.cs new file mode 100644 index 0000000000..9dace1a101 --- /dev/null +++ b/src/Stride.Shader.Parser/TestGrammar.cs @@ -0,0 +1,87 @@ +using Eto.Parse; +using Eto.Parse.Parsers; + +namespace SDSLParser +{ + public class TestGrammar : Grammar + { + private static bool IsLetterDigitOrUnderscore(char c) + { + return char.IsLetterOrDigit(c) || c.Equals("_"); + } + public TestGrammar() : base("test-sdsl") + { + EnableMatchEvents = false; + CaseSensitive = true; + + var ws = new RepeatCharTerminal(char.IsWhiteSpace); + var wso = ws.Optional(); + + var eof = Terminals.End; + + var eol = Terminals.Eol; + var eolo = eol.Optional(); + + var shaderDeclaration = Terminals.Set("shader"); + + var ldu = Terminals.LetterOrDigit | "_"; + var identifier = Terminals.LetterOrDigit.Then(ldu.Repeat().Optional()).Named("Identifier"); + + var lbr = Terminals.Set("{"); + var rbr = Terminals.Set("}"); + + var intParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = false, Name = "ConstantInt"}; + var floatParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = true, Name = "ConstantInt"}; + var boolParser = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"}, FalseValues = new string[]{"false"}}; + + var constants = intParser | floatParser | boolParser; + + var unary_op = + Terminals.Set("&") + | Terminals.Set("*") + | Terminals.Set("+") + | Terminals.Set("-") + | Terminals.Set("/") + | Terminals.Set("!"); + var assign_op = + Terminals.Set("=") + | Terminals.Set("*=") + | Terminals.Set("/=") + | Terminals.Set("%=") + | Terminals.Set("+=") + | Terminals.Set("-=") + | Terminals.Set("<<=") + | Terminals.Set(">>=") + | Terminals.Set("&=") + | Terminals.Set("^=") + | Terminals.Set("|="); + + var primary_expr = identifier | constants; + + var unary_expr = new SequenceParser().WithName("UnaryExpression"); + var cast_expr = new SequenceParser().WithName("CastExpression"); + var postfix_expr = new SequenceParser().WithName("PostfixExpression"); + var assign_expr = new SequenceParser().WithName("AssignmentExpression"); + var l_or_expr = new SequenceParser().WithName("LogicalOrExpression"); + var l_and_expr = new SequenceParser().WithName("LogicalAndExpression"); + var or_expr = new SequenceParser().WithName("OrExpression"); + var xor_expr = new SequenceParser().WithName("XOrExpression"); + var and_expr = new SequenceParser().WithName("AndExpression"); + var eq_expr = new SequenceParser().WithName("EqualityExpression"); + var rel_expr = new SequenceParser().WithName("RelationalExpression"); + var shift_expr = new SequenceParser().WithName("ShiftExpression"); + var add_expr = new SequenceParser().WithName("AdditiveExpression"); + var mul_expr = new SequenceParser().WithName("MultiplicativeExpression"); + + postfix_expr.Add(primary_expr.Named("Value")); + unary_expr.Add(postfix_expr.Named("Value")); + // cast_expr.Add(identifier.Named("Value")); + var tmpCast = unary_expr | Terminals.Set("(") & identifier.Named("Target") & ")" & identifier.Named("Value"); + // cast_expr.Add("(", identifier.Named("Target"), ")", identifier.Named("Value")); + cast_expr.Add(tmpCast); + + Inner = cast_expr; + + } + } +} \ No newline at end of file diff --git a/src/SDSLParser/c.bnf b/src/Stride.Shader.Parser/c.bnf similarity index 100% rename from src/SDSLParser/c.bnf rename to src/Stride.Shader.Parser/c.bnf diff --git a/src/SDSLParser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf similarity index 62% rename from src/SDSLParser/grammar.ebnf rename to src/Stride.Shader.Parser/grammar.ebnf index b9cd5202d9..82e74187a3 100644 --- a/src/SDSLParser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -29,11 +29,18 @@ assignment_operator := | "^=" | "|="; -integer_cst := ? Terminals.Digit ?, {? Terminals.Digit ?}; -float_cst := integer_cst, "f" | integer_cst, ".", integer_cst; -bool_cst := "true" | "false"; +integer_cst = ? Terminals.Digit ?, {? Terminals.Digit ?}; +float_cst = + integer_cst, "f" + | integer_cst, ".", integer_cst + | integer_cst, ".", integer_cst, "f"; -constants := integer_cst | float_cst | bool_cst; +bool_cst = "true" | "false"; + +constants = + integer_cst + | float_cst + | bool_cst; conditional_expression := logical_or_expression @@ -99,17 +106,48 @@ expression := -primary_expr := identifier | constants; +primary_expression := identifier | constants; + +postfix_expression := + primary_expression + | postfix_expression, "[", expression, "]" + | postfix_expression, "(", {assignment_expression}, ")" + | postfix_expression, ".", identifier + | postfix_expression, "->", identifier + | postfix_expression, "++" + | postfix_expression, "--"; + +expression_statement := {expression}, ";"; + +labeled_statement := identifier, ":", statement + | "case", constant-expression, ":", statement + | "default", ":", statement; + +compound_statement := "{", {[declaration | statement]}, "}"; + +selection_statement := "if", "(", expression, ")", statement + | "if", "(", expression, ")", statement, "else", statement + | "switch", "(", expression,")", statement; + +iteration_statement := "while", "(", expression, ")", statement + | "do", statement, "while", "(", expression, ")" + | "for", "(", {expression}, ";", {expression}, ";", {expression}, ")", statement; -postfix_expr := - primary_expr - | postfix_expr, '[',ex; +jump_statement := "goto", identifier, ";" + | "continue", ";" + | "break", ";" + | "return", {expression} ; -bracket_value = simple value, {simple value}; +statement := labeled_statement + | expression_statement + | compound_statement + | selection_statement + | iteration_statement + | jump_statement; -expr := [eol], [ws] , [constants], [eol]; +statements := {statement}; -block := "{", expr, "}"; +block := "{", [eol], [ws], statements, [eol], [ws], "}"; -grammar = ws, "shader", identifier, block; -(* grammar := integer_cst, [eof]; *) \ No newline at end of file +(* grammar = ws, "shader", identifier, block; *) +grammar := constants; \ No newline at end of file From c07047cbce84f904f3ac7ab35eeabd43f433f9f7 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Apr 2022 20:53:21 +0200 Subject: [PATCH 0010/1182] update parser --- src/SDSLParser/Program.cs | 2 +- src/Stride.Shader.Parser/SDSLGrammar.cs | 134 ++++++++++++++++++++---- 2 files changed, 117 insertions(+), 19 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index d613666f32..41f62400ac 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -10,7 +10,7 @@ var s = new Stopwatch(); s.Start(); -var match = parser.Match("(((5)))"); +var match = parser.Match("(a)*(5) + (2 - 3)"); s.Stop(); Console.WriteLine(match.ErrorMessage); diff --git a/src/Stride.Shader.Parser/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar.cs index 166a2450c2..b67bf46a8c 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar.cs @@ -11,7 +11,6 @@ public SDSLGrammar() : base("sdsl") CaseSensitive = true; var ws = new RepeatCharTerminal(char.IsWhiteSpace); - var wso = ws.Optional(); var eof = End; @@ -36,33 +35,132 @@ public SDSLGrammar() : base("sdsl") var primary_expr = identifier.Or(constants).WithName("PrimaryExpression"); + var assign_op = + Set("=") + | "*=" + | "/=" + | "%=" + | "+=" + | "-=" + | "<<=" + | ">>=" + | "&=" + | "^=" + | "|="; + var unary_op = + Set("&") + | "*" + | "+" + | "-" + | "~" + | "!"; + + var const_exp = new SequenceParser(); + var cond_exp = new SequenceParser(); + var lor_exp = new SequenceParser(); + var land_exp = new SequenceParser(); + var or_exp = new SequenceParser(); + var xor_exp = new SequenceParser(); + var and_exp = new SequenceParser(); + var eq_exp = new SequenceParser(); + var rel_exp = new SequenceParser(); + var shift_exp = new SequenceParser(); + var add_exp = new SequenceParser(); + var mul_exp = new SequenceParser(); + var cast_exp = new SequenceParser(); + var unary_exp = new SequenceParser(); + var postfix_exp = new SequenceParser(); + var expr = new SequenceParser(); - var assign = identifier.Then(Set("=")).Then(primary_expr).WithName("AssignExpression"); - - var parenthesis_expr = new SequenceParser(); - parenthesis_expr.Add( - primary_expr - .Or( - Set("(").Then(parenthesis_expr).Then(")") - ) + cond_exp.Add( + lor_exp.Then(expr.Then(":").Then(cond_exp).Optional()) + ); + + lor_exp.Add( + land_exp + | lor_exp.Then("||").Then(land_exp) + ); + + land_exp.Add( + or_exp + | land_exp.Then("&&").Then(or_exp) + ); + or_exp.Add( + xor_exp + | or_exp.Then("|").Then(xor_exp) + ); + + xor_exp.Add( + and_exp + | xor_exp.Then("|").Then(and_exp) + ); + + and_exp.Add( + eq_exp + | and_exp.Then("|").Then(eq_exp) ); - parenthesis_expr.WithName("ParenthesisExpression"); - var mul_expr = new SequenceParser(); + eq_exp.Add( + rel_exp + | eq_exp.Then("==").Or("!=").Then(rel_exp) + ); - mul_expr.Add( - parenthesis_expr.WithName("BasicMul") - .Or( - mul_expr.Then("*").Then(mul_expr) - ) + rel_exp.Add( + shift_exp + | rel_exp.Then( + Set("<") + | ">" + | "<=" + | ">=" + ) + .Then(shift_exp) ); - mul_expr.WithName("MultExpression"); + + + - Inner = mul_expr; + + + + // var assign = identifier.Then(Set("=")).Then(primary_expr).WithName("AssignExpression"); + // assign.SeparateChildrenBy(ws); + + + + + // var mul_expr = new SequenceParser(); + + // mul_expr.Add(primary_expr.WithName("MultLeft").Then(Set("*").Or("/").Or("%").Then(mul_expr.WithName("MultRight")).Optional())); + // mul_expr.WithName("MultExpression"); + // mul_expr.SeparateChildrenBy(ws); + // mul_expr.AddError = true; + + + // var add_expr = new SequenceParser(); + + // add_expr.Add(mul_expr.WithName("AddLeft").Then(Set("+").Or("-").Then(add_expr.WithName("AddRight")).Optional())); + // add_expr.WithName("AddExpression"); + // add_expr.SeparateChildrenBy(ws); + // add_expr.AddError = true; + + // var parenthesis_expr = new SequenceParser(); + // parenthesis_expr.Add( + // add_expr + // .Or( + // Set("(").Then(parenthesis_expr).Then(")") + // ) + // ); + // parenthesis_expr.WithName("ParenthesisExpression"); + // parenthesis_expr.SeparateChildrenBy(ws); + // parenthesis_expr.AddError = true; + + + + Inner = add_exp; } } From d0b08e3d6553e543495cfd6bfcf8df2b3e3c7a44 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 23 Apr 2022 20:01:10 +0200 Subject: [PATCH 0011/1182] change of ebnf --- .gitignore | 3 +- src/SDSLParser/Program.cs | 11 +- src/SDSLParser/SDSLParser.csproj | 4 + src/SDSLParser/shader.sdsl | 2 +- .../GrammarResource.Designer.cs | 73 +++++++ src/Stride.Shader.Parser/GrammarResource.resx | 124 +++++++++++ src/Stride.Shader.Parser/SDSL.cs | 41 ++++ src/Stride.Shader.Parser/SDSLGrammar.cs | 143 +++++++------ src/Stride.Shader.Parser/SDSLParser.cs | 25 +++ .../Stride.Shader.Parser.csproj | 19 ++ src/Stride.Shader.Parser/StrideGrammar.cs | 12 ++ src/Stride.Shader.Parser/grammar.ebnf | 195 +++++++----------- 12 files changed, 463 insertions(+), 189 deletions(-) create mode 100644 src/Stride.Shader.Parser/GrammarResource.Designer.cs create mode 100644 src/Stride.Shader.Parser/GrammarResource.resx create mode 100644 src/Stride.Shader.Parser/SDSL.cs create mode 100644 src/Stride.Shader.Parser/SDSLParser.cs create mode 100644 src/Stride.Shader.Parser/StrideGrammar.cs diff --git a/.gitignore b/.gitignore index 2f3aa2c250..5ef50099d7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ bin/ obj/ .vscode/ -.fake \ No newline at end of file +.fake +.vs/ \ No newline at end of file diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 41f62400ac..acf79d9da2 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,16 +4,19 @@ using System.Diagnostics; -// var shaderf = File.ReadAllText("./shader.sdsl"); - -var parser = new SDSLGrammar(); +var shaderf = File.ReadAllText("./shader.sdsl"); +// var parser = new SDSLGrammar(); +var parser = StrideGrammar.New(); +// var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = parser.Match("(a)*(5) + (2 - 3)"); +var match = parser.Match("(a++)+3++*2"); +// var res = SDSLPParser.Parse("My_Var"); s.Stop(); Console.WriteLine(match.ErrorMessage); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); +Console.Write(""); diff --git a/src/SDSLParser/SDSLParser.csproj b/src/SDSLParser/SDSLParser.csproj index e02c07bb7b..384acf35fc 100644 --- a/src/SDSLParser/SDSLParser.csproj +++ b/src/SDSLParser/SDSLParser.csproj @@ -12,6 +12,10 @@ enable + + + + diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index 2a862e93c8..d53a9241f7 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ shader Toto_Mano { - 5.0f; + a=3*4; } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/GrammarResource.Designer.cs b/src/Stride.Shader.Parser/GrammarResource.Designer.cs new file mode 100644 index 0000000000..a3951eee74 --- /dev/null +++ b/src/Stride.Shader.Parser/GrammarResource.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Stride.Shader.Parser { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class GrammarResource { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal GrammarResource() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Stride.Shader.Parser.GrammarResource", typeof(GrammarResource).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] grammar { + get { + object obj = ResourceManager.GetObject("grammar", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/src/Stride.Shader.Parser/GrammarResource.resx b/src/Stride.Shader.Parser/GrammarResource.resx new file mode 100644 index 0000000000..dcdde60c33 --- /dev/null +++ b/src/Stride.Shader.Parser/GrammarResource.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + grammar.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSL.cs b/src/Stride.Shader.Parser/SDSL.cs new file mode 100644 index 0000000000..dc124c7740 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSL.cs @@ -0,0 +1,41 @@ +using System.Collections.Immutable; + +namespace Stride.Shader.Parser; + +public interface ISDSL +{ +} + +public class JsonArray : ISDSL +{ + public ImmutableArray Elements { get; } + public JsonArray(ImmutableArray elements) + { + Elements = elements; + } + public override string ToString() + => $"[{string.Join(",", Elements.Select(e => e.ToString()))}]"; +} + +public class JsonObject : ISDSL +{ + public IImmutableDictionary Members { get; } + public JsonObject(IImmutableDictionary members) + { + Members = members; + } + public override string ToString() + => $"{{{string.Join(",", Members.Select(kvp => $"\"{kvp.Key}\":{kvp.Value.ToString()}"))}}}"; +} + +public class JsonString : ISDSL +{ + public string Value { get; } + public JsonString(string value) + { + Value = value; + } + + public override string ToString() + => $"\"{Value}\""; +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar.cs index b67bf46a8c..b9a9572a02 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar.cs @@ -55,71 +55,100 @@ public SDSLGrammar() : base("sdsl") | "-" | "~" | "!"; + + var incr_op = + Set("++") + | "--"; + - var const_exp = new SequenceParser(); - var cond_exp = new SequenceParser(); - var lor_exp = new SequenceParser(); - var land_exp = new SequenceParser(); - var or_exp = new SequenceParser(); - var xor_exp = new SequenceParser(); - var and_exp = new SequenceParser(); - var eq_exp = new SequenceParser(); - var rel_exp = new SequenceParser(); - var shift_exp = new SequenceParser(); - var add_exp = new SequenceParser(); - var mul_exp = new SequenceParser(); - var cast_exp = new SequenceParser(); - var unary_exp = new SequenceParser(); - var postfix_exp = new SequenceParser(); + var const_exp = new AlternativeParser{Name = "Constant"}; + var cond_exp = new AlternativeParser{Name = "cond_exp"}; + var lor_exp = new AlternativeParser{Name = "lor_exp"}; + var land_exp = new AlternativeParser{Name = "land_exp"}; + var or_exp = new AlternativeParser{Name = "or_exp"}; + var xor_exp = new AlternativeParser{Name = "xor_exp"}; + var and_exp = new AlternativeParser{Name = "and_exp"}; + var eq_exp = new AlternativeParser{Name = "eq_exp"}; + var rel_exp = new AlternativeParser{Name = "rel_exp"}; + var shift_exp = new AlternativeParser{Name = "shift_exp"}; + var add_exp = new AlternativeParser{Name = "add_exp"}; + var mul_exp = new AlternativeParser{Name = "mul_exp"}; + var cast_exp = new AlternativeParser{Name = "cast_exp"}; + var unary_exp = new AlternativeParser{Name = "unary_exp"}; + var postfix_exp = new AlternativeParser{Name = "postfix_exp"}; + var assign_exp = new AlternativeParser{Name = "assign_exp"}; + var expr = new SequenceParser(); cond_exp.Add( lor_exp.Then(expr.Then(":").Then(cond_exp).Optional()) ); - lor_exp.Add( - land_exp - | lor_exp.Then("||").Then(land_exp) - ); + lor_exp.Add(land_exp); + lor_exp.Add(lor_exp.Then("||").Then(land_exp)); - land_exp.Add( - or_exp - | land_exp.Then("&&").Then(or_exp) - ); - or_exp.Add( - xor_exp - | or_exp.Then("|").Then(xor_exp) - ); + land_exp.Add(or_exp); + land_exp.Add(land_exp.Then("&&").Then(or_exp)); - xor_exp.Add( - and_exp - | xor_exp.Then("|").Then(and_exp) - ); + or_exp.Add(xor_exp); + or_exp.Add(or_exp.Then("|").Then(xor_exp)); - and_exp.Add( - eq_exp - | and_exp.Then("|").Then(eq_exp) - ); + xor_exp.Add(and_exp); + xor_exp.Add(xor_exp.Then("|").Then(and_exp)); - eq_exp.Add( - rel_exp - | eq_exp.Then("==").Or("!=").Then(rel_exp) - ); + and_exp.Add(eq_exp); + and_exp.Add(and_exp.Then("|").Then(eq_exp)); - rel_exp.Add( - shift_exp - | rel_exp.Then( - Set("<") - | ">" - | "<=" - | ">=" - ) - .Then(shift_exp) - ); + eq_exp.Add(rel_exp); + eq_exp.Add(eq_exp.Then("==").Or("!=").Then(rel_exp)); + + rel_exp.Add(shift_exp); + rel_exp.Add(rel_exp, Set("<") | ">" | "<=" | ">=", shift_exp); + + + shift_exp.Add(add_exp.WithName("SingleTerm")); + shift_exp.Add(shift_exp.WithName("LeftTerm").Then("<<").Or(">>").Then(add_exp).WithName("RightTerm")); + add_exp.Add(mul_exp.WithName("SingleTerm")); + add_exp.Add(add_exp.WithName("LeftTerm").Then("+").Or("-").Then(mul_exp.WithName("RightTerm"))); + mul_exp.Add(cast_exp); + mul_exp.Add(mul_exp.Then("*").Or("/").Or("%").Then(cast_exp)); + + cast_exp.Add(unary_exp); + cast_exp.Add(Set("(").Then(identifier).Then(cast_exp)); + + unary_exp.Add(postfix_exp); + unary_exp.Add(Set("++") |"--" , unary_exp); + unary_exp.Add(unary_op, cast_exp); + + // postfix_exp.Add(primary_expr.WithName("PrimaryPostFix")); + var pp = Set("+").Or("-").Repeat(2,2); + var access = Set("[") & primary_expr & "]"; + + var p1 = primary_expr; + // var p2 = p1 | p1. + // postfix_exp.Add( + // primary_expr + // | tt.Then(access.Optional()) + // | tt.Then(pp.Optional().Named("Increment")).Optional()); + + // postfix_exp.Add(postfix_exp.Named("Expression"), access.Optional().Named("Accessor")); + // | postfix_exp.Then("(").Then(assign_exp).Then(")") + // | postfix_exp.Then(".").Then(identifier) + + expr.Add(assign_exp); + expr.Add(expr.Then(",").Then(assign_exp)); + + assign_exp.Add(cond_exp); + assign_exp.Add(unary_exp.Then(assign_op).Then(assign_exp)); + + + + var a = 0; + var b = (3+a++)*1; @@ -147,20 +176,16 @@ public SDSLGrammar() : base("sdsl") // add_expr.SeparateChildrenBy(ws); // add_expr.AddError = true; - // var parenthesis_expr = new SequenceParser(); - // parenthesis_expr.Add( - // add_expr - // .Or( - // Set("(").Then(parenthesis_expr).Then(")") - // ) - // ); + var parenthesis_expr = new AlternativeParser(); + parenthesis_expr.Add(primary_expr); + parenthesis_expr.Add(Set("(").Then(parenthesis_expr).Then(")")); // parenthesis_expr.WithName("ParenthesisExpression"); // parenthesis_expr.SeparateChildrenBy(ws); // parenthesis_expr.AddError = true; - - + - Inner = add_exp; + // tmp.PreventRecursion(true); + Inner = postfix_exp; } } diff --git a/src/Stride.Shader.Parser/SDSLParser.cs b/src/Stride.Shader.Parser/SDSLParser.cs new file mode 100644 index 0000000000..45c479d662 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLParser.cs @@ -0,0 +1,25 @@ +namespace Stride.Shader.Parser; +using Pidgin; +using static Pidgin.Parser; +using static Pidgin.Parser; + +public class SDSLPParser +{ + private static readonly Parser LBrace = Char('{'); + private static readonly Parser RBrace = Char('}'); + private static readonly Parser LBracket = Char('['); + private static readonly Parser RBracket = Char(']'); + private static readonly Parser Quote = Char('"'); + private static readonly Parser Colon = Char(':'); + private static readonly Parser ColonWhitespace = + Colon.Between(SkipWhitespaces); + private static readonly Parser Comma = Char(','); + private static readonly Parser Identifier = + Token(c => char.IsLetterOrDigit(c) || c.Equals('_')) + .ManyString(); + + public static Result Parse(string code) + { + return Identifier.Parse(code); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj index 7a86fc8a58..fbde38f44e 100644 --- a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj +++ b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj @@ -9,5 +9,24 @@ enable enable + + + True + True + GrammarResource.resx + + + + + + ResXFileCodeGenerator + GrammarResource.Designer.cs + + + + + + + diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs new file mode 100644 index 0000000000..129026cc65 --- /dev/null +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -0,0 +1,12 @@ +namespace Stride.Shader.Parser; + +using Eto.Parse; +using Eto.Parse.Grammars; +using System.Text; +public static class StrideGrammar +{ + public static Grammar New() + { + return new EbnfGrammar(EbnfStyle.Iso14977).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index 82e74187a3..7ae0877178 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -1,153 +1,100 @@ -(* := is an extension to define a literal with no whitespace between repeats and sequences *) -ws := {? Terminals.WhiteSpace ?}; -eol := ? Terminals.Eol ?, {? Terminals.Eol ?}; -eof := ? Terminals.End ?; +id := ? Terminals.Letter ?, {[? Terminals.LetterOrDigit ? | "_"]}; +eol = ? Terminals.Eol ?; -letter = ? Terminals.Letter ?, {? Terminals.Letter ?}; -letter_or_digit = ? Terminals.LetterOrDigit ?, {? Terminals.LetterOrDigit ?}; +eols = [eol] | {eol}; -identifier := letter, {"_", letter_or_digit}; +eof = ? Terminals.End ?; -unary_operator := - "&" - | "*" - | "+" - | "-" - | "~" - | "!"; +any_space = {wso | eols}; -assignment_operator := + +(* STRING = ? Terminals.LetterOrDigit ?,{? Terminals.LetterOrDigit ?}; *) + +assign_op = "=" - | "*=" - | "/=" - | "%=" | "+=" | "-=" - | "<<=" - | ">>=" + | "/=" + | "*=" | "&=" - | "^=" - | "|="; - -integer_cst = ? Terminals.Digit ?, {? Terminals.Digit ?}; -float_cst = - integer_cst, "f" - | integer_cst, ".", integer_cst - | integer_cst, ".", integer_cst, "f"; - -bool_cst = "true" | "false"; - -constants = - integer_cst - | float_cst - | bool_cst; - -conditional_expression := - logical_or_expression - | logical_or_expression, '?', expression, ':', conditional_expression; - -logical_or_expression := logical_and_expression - | logical_or_expression, "||", logical_and_expression; - -logical_and_expression := inclusive_or_expression - | logical_and_expression, "&&", inclusive_or_expression; - -inclusive_or_expression := exclusive_or_expression - | inclusive_or_expression, "|", exclusive_or_expression; - -exclusive_or_expression := and_expression - | exclusive_or_expression, "^", and_expression; - -and_expression := equality_expression - | and_expression, "&", equality_expression; - -equality_expression := relational_expression - | equality_expression, "==", relational_expression - | equality_expression, "!=", relational_expression; - -relational_expression := shift_expression - | relational_expression, "<", shift_expression - | relational_expression, ">", shift_expression - | relational_expression, "<=", shift_expression - | relational_expression, ">=", shift_expression; - -shift_expression := additive_expression - | shift_expression, "<<", additive_expression - | shift_expression, ">>", additive_expression; + | "|=" + | "~=" +; -additive_expression := multiplicative_expression - | additive_expression, "+", multiplicative_expression - | additive_expression, "-", multiplicative_expression; -multiplicative_expression := cast_expression - | multiplicative_expression, "*", cast_expression - | multiplicative_expression, "/", cast_expression - | multiplicative_expression, "%", cast_expression; +zero = "0"; -cast_expression := unary_expression - | "(", type_name, ")", cast_expression; +digit1 = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; +digit = zero | digit1; -unary_expression := - postfix_expression - | '++', unary_expression - | '--', unary_expression - | unary_operator, cast_expression - | 'sizeof', unary_expression - | 'sizeof', type_name; +INT = zero | (digit1, {digit}); -assignment_expression := - conditional_expression - | unary_expression, assignment_operator, assignment_expression; +ws = ? Terminals.WhiteSpace ?, {? Terminals.WhiteSpace ?}; -expression := - assignment_expression - | expression, assignment_expression; +wso = [ws]; +integer = zero | (digit1, {digit}); +term := + id + | integer + | paren_expr + ; -primary_expression := identifier | constants; +mul = + term + | mul, '*', term + | mul, '/', term + | mul, '%', term +; -postfix_expression := - primary_expression - | postfix_expression, "[", expression, "]" - | postfix_expression, "(", {assignment_expression}, ")" - | postfix_expression, ".", identifier - | postfix_expression, "->", identifier - | postfix_expression, "++" - | postfix_expression, "--"; +sum = + mul + | sum, '++' + | sum, '+', mul + | sum, '-', mul +; -expression_statement := {expression}, ";"; +primary_value = id | sum; -labeled_statement := identifier, ":", statement - | "case", constant-expression, ":", statement - | "default", ":", statement; +test + = sum + | sum, '<', sum + | sum, '>', sum + | sum, '<=', sum + | sum, '>=', sum + ; -compound_statement := "{", {[declaration | statement]}, "}"; +inc_op = "++" | "--"; +pfix_inc = primary_value, inc_op; +ifix_inc = inc_op, primary_value; -selection_statement := "if", "(", expression, ")", statement - | "if", "(", expression, ")", statement, "else", statement - | "switch", "(", expression,")", statement; -iteration_statement := "while", "(", expression, ")", statement - | "do", statement, "while", "(", expression, ")" - | "for", "(", {expression}, ";", {expression}, ";", {expression}, ")", statement; +expr := + test + | id, assign_op, expr + | "(",id,")", expr + | id, "[", expr, "]" + | (id | paren_expr), ".", id + | (id | paren_expr), "++" + ; -jump_statement := "goto", identifier, ";" - | "continue", ";" - | "break", ";" - | "return", {expression} ; +paren_expr := '(', expr, ')'; -statement := labeled_statement - | expression_statement - | compound_statement - | selection_statement - | iteration_statement - | jump_statement; +statement := + 'if', paren_expr, statement + | 'if', paren_expr, statement, 'else', statement + | 'while', paren_expr, statement + | 'do', statement, 'while', paren_expr, ';' + | '{', {statement}, '}' + | expr, ';' + | ';' + ; -statements := {statement}; +shader_class = + "shader", any_space, id, any_space, + "{", any_space, {statement}, any_space, "}"; -block := "{", [eol], [ws], statements, [eol], [ws], "}"; -(* grammar = ws, "shader", identifier, block; *) -grammar := constants; \ No newline at end of file +shader := expr; \ No newline at end of file From e337469b529e2382dc5730ffc87c9ba9d05e2c0d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Apr 2022 16:06:57 +0200 Subject: [PATCH 0012/1182] update on grammar using exclusion --- src/SDSLParser/Program.cs | 3 +- src/Stride.Shader.Parser/SDSLGrammar.cs | 2 +- src/Stride.Shader.Parser/StrideGrammar.cs | 4 +- src/Stride.Shader.Parser/grammar.ebnf | 142 +++++++++++----------- 4 files changed, 75 insertions(+), 76 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index acf79d9da2..432ccfd2e8 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -11,7 +11,7 @@ // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = parser.Match("(a++)+3++*2"); +var match = parser.Match("My_Var.value=(5+3)*2"); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); @@ -20,3 +20,4 @@ Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); + diff --git a/src/Stride.Shader.Parser/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar.cs index b9a9572a02..0771a383ee 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar.cs @@ -148,7 +148,7 @@ public SDSLGrammar() : base("sdsl") var a = 0; - var b = (3+a++)*1; + var b = ++a+3*1; diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 129026cc65..da63da79c4 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -7,6 +7,6 @@ public static class StrideGrammar { public static Grammar New() { - return new EbnfGrammar(EbnfStyle.Iso14977).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); + return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"expr"); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index 7ae0877178..bb464c6bd6 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -1,16 +1,13 @@ -id := ? Terminals.Letter ?, {[? Terminals.LetterOrDigit ? | "_"]}; -eol = ? Terminals.Eol ?; +id ::= ?Terminals.Letter? (?Terminals.LetterOrDigit? | "_")* +eol ::= ? Terminals.Eol ? -eols = [eol] | {eol}; +eols ::= eol* -eof = ? Terminals.End ?; +eof ::= ?Terminals.End ? -any_space = {wso | eols}; +any_space ::= (wso | eols)* - -(* STRING = ? Terminals.LetterOrDigit ?,{? Terminals.LetterOrDigit ?}; *) - -assign_op = +assign_op ::= "=" | "+=" | "-=" @@ -19,82 +16,83 @@ assign_op = | "&=" | "|=" | "~=" -; - - -zero = "0"; - -digit1 = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; -digit = zero | digit1; -INT = zero | (digit1, {digit}); +integer ::= "0" | ([0-9] [1-9]*) +float ::= + (integer "." [0-9] [0-9]*) + | (integer "f"?) -ws = ? Terminals.WhiteSpace ?, {? Terminals.WhiteSpace ?}; +ws ::= (? Terminals.WhiteSpace ?)* -wso = [ws]; +wso ::= ws* -integer = zero | (digit1, {digit}); - -term := +term ::= id | integer | paren_expr - ; -mul = +mul ::= term - | mul, '*', term - | mul, '/', term - | mul, '%', term -; + | mul '*' term + | mul '/' term + | mul '%' term + -sum = +sum ::= mul - | sum, '++' - | sum, '+', mul - | sum, '-', mul -; - -primary_value = id | sum; - -test - = sum - | sum, '<', sum - | sum, '>', sum - | sum, '<=', sum - | sum, '>=', sum - ; - -inc_op = "++" | "--"; -pfix_inc = primary_value, inc_op; -ifix_inc = inc_op, primary_value; - - -expr := - test - | id, assign_op, expr - | "(",id,")", expr - | id, "[", expr, "]" - | (id | paren_expr), ".", id - | (id | paren_expr), "++" - ; - -paren_expr := '(', expr, ')'; - -statement := - 'if', paren_expr, statement - | 'if', paren_expr, statement, 'else', statement - | 'while', paren_expr, statement - | 'do', statement, 'while', paren_expr, ';' - | '{', {statement}, '}' - | expr, ';' + | sum '++' + | sum '+' mul + | sum '-' mul + +primary_value ::= id | sum + +test ::= + sum + | sum '<' sum + | sum '>' sum + | sum '<=' sum + | sum '>=' sum + + +inc_op ::= "++" | "--" +pfix_inc ::= primary_value inc_op +ifix_inc ::= inc_op primary_value + +idx_accessor ::= id "[" expr "]" +accessor ::= (id | paren_expr) "." id +cast ::= "(" id ")" expr + +assign ::= + id assign_op expr + | accessor assign_op expr + | cast assign_op expr + | idx_accessor assign_op expr + + +expr ::= + (test - assign) + | (accessor - assign) + | (idx_accessor - assign) + | assign + | (paren_expr - cast) + | paren_expr + +paren_expr ::= '(' expr ')' + +statement ::= + 'if' paren_expr statement + | 'if' paren_expr statement 'else' statement + | 'while' paren_expr statement + | 'do' statement 'while' paren_expr ';' + | '{' statement* '}' + | expr ';' | ';' - ; + -shader_class = - "shader", any_space, id, any_space, - "{", any_space, {statement}, any_space, "}"; +shader_class ::= + "shader" any_space id any_space + "{" any_space statement any_space "}" -shader := expr; \ No newline at end of file +shader ::= expr \ No newline at end of file From 2437a7245cfffb2e15ce06087055394275a70238 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Apr 2022 16:52:37 +0200 Subject: [PATCH 0013/1182] added float parsing --- src/SDSLParser/Program.cs | 2 +- src/Stride.Shader.Parser/StrideGrammar.cs | 2 +- src/Stride.Shader.Parser/grammar.ebnf | 20 +++++++++++++++----- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 432ccfd2e8..dcde2f28d1 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -11,7 +11,7 @@ // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = parser.Match("My_Var.value=(5+3)*2"); +var match = parser.Match("My_Var value=(5f+3)*2f;"); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index da63da79c4..1eb7598715 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -7,6 +7,6 @@ public static class StrideGrammar { public static Grammar New() { - return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"expr"); + return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"statement"); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index bb464c6bd6..a085a1ed23 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -3,9 +3,10 @@ eol ::= ? Terminals.Eol ? eols ::= eol* -eof ::= ?Terminals.End ? +eof ::= ? Terminals.End ? any_space ::= (wso | eols)* +one_space ::= (wso | eols)+ assign_op ::= "=" @@ -29,7 +30,8 @@ wso ::= ws* term ::= id - | integer + | (integer - float) + | float | paren_expr mul ::= @@ -76,22 +78,30 @@ expr ::= | (idx_accessor - assign) | assign | (paren_expr - cast) - | paren_expr + | cast paren_expr ::= '(' expr ')' + +typename ::= id +declaration ::= typename one_space id (assign_op expr)? + +expression ::= + expr - declaration + | declaration + statement ::= 'if' paren_expr statement | 'if' paren_expr statement 'else' statement | 'while' paren_expr statement | 'do' statement 'while' paren_expr ';' | '{' statement* '}' - | expr ';' + | expression ';' | ';' shader_class ::= - "shader" any_space id any_space + "shader" one_space id any_space "{" any_space statement any_space "}" From 0a3d91ab6bf2739182950b23a2480d934c4e24c1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Apr 2022 17:23:17 +0200 Subject: [PATCH 0014/1182] first shader parsed --- src/SDSLParser/Program.cs | 2 +- src/SDSLParser/shader.sdsl | 4 ++-- src/Stride.Shader.Parser/StrideGrammar.cs | 2 +- src/Stride.Shader.Parser/grammar.ebnf | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index dcde2f28d1..45251c2f4f 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -11,7 +11,7 @@ // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = parser.Match("My_Var value=(5f+3)*2f;"); +var match = parser.Match(shaderf); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index d53a9241f7..9c34c0f1f5 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,3 @@ -shader Toto_Mano { - a=3*4; +shader BasicShader { + float a=0; } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 1eb7598715..3f6d97a77c 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -7,6 +7,6 @@ public static class StrideGrammar { public static Grammar New() { - return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"statement"); + return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index a085a1ed23..d3570bcb35 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -102,7 +102,7 @@ statement ::= shader_class ::= "shader" one_space id any_space - "{" any_space statement any_space "}" + "{" any_space (declaration ";" any_space)* any_space "}" -shader ::= expr \ No newline at end of file +shader ::= shader_class \ No newline at end of file From 58059d36195b5a4e673ae7cc9dbde794932afdf0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Apr 2022 18:54:18 +0200 Subject: [PATCH 0015/1182] Added c buffer parsing --- src/SDSLParser/shader.sdsl | 6 ++++- src/Stride.Shader.Parser/grammar.ebnf | 35 ++++++++++++++++++++------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/shader.sdsl index 9c34c0f1f5..2ccfe37e87 100644 --- a/src/SDSLParser/shader.sdsl +++ b/src/SDSLParser/shader.sdsl @@ -1,3 +1,7 @@ shader BasicShader { - float a=0; + stream float a = 0; + + c_buffer PerMaterial{ + stage float b = 0; + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index d3570bcb35..e2fc7d3b19 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -66,10 +66,10 @@ accessor ::= (id | paren_expr) "." id cast ::= "(" id ")" expr assign ::= - id assign_op expr - | accessor assign_op expr - | cast assign_op expr - | idx_accessor assign_op expr + id any_space assign_op any_space expr + | accessor any_space assign_op any_space expr + | cast any_space assign_op any_space expr + | idx_accessor any_space assign_op any_space expr expr ::= @@ -84,7 +84,15 @@ paren_expr ::= '(' expr ')' typename ::= id -declaration ::= typename one_space id (assign_op expr)? + +stage ::= "stage" +stream ::= "stream" + +declaration ::= + ((stage | stream) one_space)? typename one_space id any_space (assign_op any_space expr)? + +stage_declaration ::= + stage one_space typename one_space id any_space (assign_op any_space expr)? expression ::= expr - declaration @@ -95,14 +103,23 @@ statement ::= | 'if' paren_expr statement 'else' statement | 'while' paren_expr statement | 'do' statement 'while' paren_expr ';' - | '{' statement* '}' - | expression ';' + | '{' any_space statement* any_space '}' + | expression any_space ';' | ';' - + +c_buffer ::= + "c_buffer" one_space id any_space any_space "{" any_space (stage_declaration any_space";")* any_space "}" shader_class ::= "shader" one_space id any_space - "{" any_space (declaration ";" any_space)* any_space "}" + "{" + any_space + ( + (declaration ";" any_space)* - c_buffer + | (c_buffer) + )* + any_space + "}" shader ::= shader_class \ No newline at end of file From b7faef5858813cac5951f992fb9c037768b32ea0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Apr 2022 22:16:11 +0200 Subject: [PATCH 0016/1182] HLSL tokens --- .gitignore | 3 +- src/SDSLParser/Program.cs | 3 +- .../GrammarResource.Designer.cs | 20 + src/Stride.Shader.Parser/GrammarResource.resx | 6 + src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 | 899 ++++++++++++++++++ src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 | 426 +++++++++ src/Stride.Shader.Parser/SDSL.cs | 41 - src/Stride.Shader.Parser/SDSLExpr.ebnf | 807 ++++++++++++++++ src/Stride.Shader.Parser/SDSLParser.cs | 25 - src/Stride.Shader.Parser/SDSLTokens.ebnf | 552 +++++++++++ .../Stride.Shader.Parser.csproj | 4 - src/Stride.Shader.Parser/StrideGrammar.cs | 5 + 12 files changed, 2719 insertions(+), 72 deletions(-) create mode 100644 src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 create mode 100644 src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 delete mode 100644 src/Stride.Shader.Parser/SDSL.cs create mode 100644 src/Stride.Shader.Parser/SDSLExpr.ebnf delete mode 100644 src/Stride.Shader.Parser/SDSLParser.cs create mode 100644 src/Stride.Shader.Parser/SDSLTokens.ebnf diff --git a/.gitignore b/.gitignore index 5ef50099d7..c90ddaaba1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ bin/ obj/ .vscode/ .fake -.vs/ \ No newline at end of file +.vs/ +.antlr/ \ No newline at end of file diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 45251c2f4f..1c62e5c995 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -8,10 +8,11 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New(); +var tokens = StrideGrammar.Token(); // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = parser.Match(shaderf); +var match = tokens.Match("float4"); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); diff --git a/src/Stride.Shader.Parser/GrammarResource.Designer.cs b/src/Stride.Shader.Parser/GrammarResource.Designer.cs index a3951eee74..6fdcf2e804 100644 --- a/src/Stride.Shader.Parser/GrammarResource.Designer.cs +++ b/src/Stride.Shader.Parser/GrammarResource.Designer.cs @@ -69,5 +69,25 @@ internal static byte[] grammar { return ((byte[])(obj)); } } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] SDSLExpr { + get { + object obj = ResourceManager.GetObject("SDSLExpr", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] SDSLTokens { + get { + object obj = ResourceManager.GetObject("SDSLTokens", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/src/Stride.Shader.Parser/GrammarResource.resx b/src/Stride.Shader.Parser/GrammarResource.resx index dcdde60c33..b18e600cca 100644 --- a/src/Stride.Shader.Parser/GrammarResource.resx +++ b/src/Stride.Shader.Parser/GrammarResource.resx @@ -121,4 +121,10 @@ grammar.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + SDSLExpr.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + SDSLTokens.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 b/src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 new file mode 100644 index 0000000000..4a6d40ba40 --- /dev/null +++ b/src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 @@ -0,0 +1,899 @@ +parser grammar HlslExpr; + +@parser::header { + #pragma warning disable 3021 +} + +options { + tokenVocab = HlslAntlrLexer; +} + +compilationUnit + : Declarations+=topLevelDeclaration* EndOfFileToken=EOF + ; + +topLevelDeclaration + : classDefinition + | interfaceDefinition + | variableDeclarationStatement + | structDefinition + | constantBuffer + | functionDefinition + | functionDeclaration + ; + +classDefinition + : ClassKeyword=Class Name=Identifier BaseListOpt=baseList? + OpenBraceToken=LeftBrace classMemberDeclaration* CloseBraceToken=RightBrace + SemicolonToken=Semi + ; + +baseList + : ColonToken=Colon BaseType=Identifier + ; + +classMemberDeclaration + : variableDeclarationStatement + | functionDefinition + | functionDeclaration + ; + +constantBuffer + : CBufferKeyword=CBuffer Name=Identifier registerAllocation? + OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace + SemicolonToken=Semi? + ; + +variableDeclarationStatement + : variableDeclaration SemicolonToken=Semi + ; + +functionDefinition + : attribute* functionType (ClassName=Identifier ColonColonToken=ColonColon)? Name=Identifier + OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen + SemanticOpt=semantic? block SemicolonTokenOpt=Semi? + ; + +functionDeclaration + : attribute* functionType Name=Identifier + OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen + SemanticOpt=semantic? SemicolonToken=Semi + ; + +functionType + : type + | Void + ; + +functionParams + : functionParam (Comma functionParam)* + ; + +functionParam + : storageFlags type variableDeclarator + ; + +interfaceDefinition + : InterfaceKeyword=Interface Name=Identifier + OpenBraceToken=LeftBrace functionDeclaration* CloseBraceToken=RightBrace + SemicolonToken=Semi + ; + +structDefinition + : StructKeyword=Struct Name=Identifier + OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace + SemicolonToken=Semi + ; + +semantic + : ColonToken=Colon Name=Identifier + ; + +// -------------------------------------- +// ATTRIBUTES +// -------------------------------------- + +attributeArguments + : literalExpr (Comma literalExpr)* + ; + +attributeArgumentList + : OpenParenToken=LeftParen attributeArguments CloseParenToken=RightParen + ; + +attribute + : OpenBracketToken=LeftBracket Name=Identifier attributeArgumentList? CloseBracketToken=RightBracket + ; + +// -------------------------------------- +// STATEMENTS +// -------------------------------------- + +block + : OpenBrace=LeftBrace Stmts+=statement* CloseBrace=RightBrace + ; + +indentedEmbeddedStatement + : embeddedStatement // not a block statement + | LeftBrace Stmt=block + ; + +statement + : localDeclarationStatement + | embeddedStatement + | classDefinition + | interfaceDefinition + | structDefinition + ; + +localDeclarationStatement + : variableDeclaration SemicolonToken=Semi + ; + +forInitializer + : variableDeclaration # ForStatementDeclaration + | expression (Comma expression)* # ForStatementInitializers + ; + +forIncrementors + : expression (Comma expression)* + ; + +switchLabel + : CaseKeyword=Case Expr=expression ColonToken=Colon # CaseSwitchLabel + | DefaultKeyword=Default ColonToken=Colon # DefaultSwitchLabel + ; + +switchSection + : switchLabel+ statement+ + ; + +embeddedStatement + : SemicolonToken=Semi # EmptyStatement + | block # BlockStatement + | Expr=expression SemicolonToken=Semi # ExpressionStatement + + // Selection statement + | attribute* IfKeyword=If OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen Stmt=indentedEmbeddedStatement elseClause? # IfStatement + | attribute* SwitchKeyword=Switch OpenParenToken=LeftParen Expr=expression CloseParenToken=RightParen OpenBraceToken=LeftBrace switchSection* CloseBraceToken=RightBrace # SwitchStatement + + // Iteration statement + | attribute* WhileKeyword=While OpenParenToken=LeftParen condition=expression CloseParenToken=RightParen indentedEmbeddedStatement # WhileStatement + | attribute* DoKeyword=Do indentedEmbeddedStatement WhileKeyword=While OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen SemicolonToken=Semi # DoStatement + | attribute* ForKeyword=For OpenParenToken=LeftParen forInitializer? FirstSemicolonToken=Semi Condition=expression? SecondSemicolonToken=Semi iterator=forIncrementors? CloseParenToken=RightParen indentedEmbeddedStatement # ForStatement + + // Jump statement + | BreakKeyword=Break SemicolonToken=Semi # BreakStatement + | ContinueKeyword=Continue SemicolonToken=Semi # ContinueStatement + | DiscardKeyword=Discard SemicolonToken=Semi # DiscardStatement + | ReturnKeyword=Return Expr=expression? SemicolonToken=Semi # ReturnStatement + ; + +elseClause + : ElseKeyword=Else Stmt=indentedEmbeddedStatement + ; + +// -------------------------------------- +// EXPRESSIONS +// -------------------------------------- + +expression + : literalExpr # LiteralExpression + | Identifier # IdentifierExpression + | OpenParenToken=LeftParen expression CloseParenToken=RightParen # ParenthesizedExpression + | OpenParenToken=LeftParen type (ArrayRankSpecifiers+=arrayRankSpecifier)* CloseParenToken=RightParen Expr=expression # CastExpression + | Expr=expression DotToken=Dot Member=Identifier # MemberAccessExpression + | scalarOrVectorOrMatrixType argumentList # NumericConstructorExpression + | Expr=expression argumentList # FunctionCallExpression + | Expr=expression OpenBracket=LeftBracket Index=expression CloseBracket=RightBracket # ArrayAccessExpression + | Expr=expression Operator=postfixUnaryOperator # PostfixUnaryExpression + | Operator=prefixUnaryOperator Expr=expression # PrefixUnaryExpression + | Left=expression Operator=binaryOperator Right=expression # BinaryExpression + | Condition=expression QuestionToken=Question TrueExpr=expression ColonToken=Colon FalseExpr=expression # ConditionalExpression + | Left=expression Operator=assignmentOperator Right=expression # AssignmentExpression + ; + +literalExpr + : literal + ; + +postfixUnaryOperator + : PlusPlus + | MinusMinus + ; + +prefixUnaryOperator + : Plus + | Minus + | Not + | Tilde + | PlusPlus + | MinusMinus + ; + +binaryOperator + : Star + | Div + | Mod + | Plus + | Minus + | LeftShift + | RightShift + | Less + | Greater + | LessEqual + | GreaterEqual + | Equal + | NotEqual + | And + | Caret + | Or + | AndAnd + | OrOr + ; + +assignmentOperator + : Assign + | StarAssign + | DivAssign + | ModAssign + | PlusAssign + | MinusAssign + | LeftShiftAssign + | RightShiftAssign + | AndAssign + | XorAssign + | OrAssign + ; + +argumentList + : OpenParenToken=LeftParen arguments? CloseParenToken=RightParen + ; + +arguments + : expression (Comma expression)* + ; + + + +// -------------------------------------- +// TYPES +// -------------------------------------- + +variableDeclaration + : storageFlags type variableDeclarators + ; + +variableDeclarators + : variableDeclarator (Comma variableDeclarator)* + ; + +variableDeclarator + : Name=Identifier + (ArrayRankSpecifiers+=arrayRankSpecifier)* + packOffsetNode? + RegisterAllocation=registerAllocation? + SemanticOpt=semantic? + variableInitializer? + ; + +arrayRankSpecifier + : OpenBracketToken=LeftBracket Dimension=expression? CloseBracketToken=RightBracket + ; + +packOffsetNode + : ColonToken=Colon PackoffsetKeyword=Packoffset OpenParenToken=LeftParen + PackOffsetRegister=Identifier (DotToken=Dot PackOffsetComponent=Identifier)? + CloseParenToken=RightParen + ; + +storageFlags + : storageFlag* + ; + +storageFlag + // Type modifiers + : Const + | RowMajor + | ColumnMajor + // Storage classes + | Extern + | Precise + | Shared + | Groupshared + | Static + | Uniform + | Volatile + // Interpolation modifiers + | Linear + | Centroid + | Nointerpolation + | Noperspective + | Sample + // Parameter modifiers (only valid on function params) + | In + | Out + | Inout + // Geometry shader primitive type + | Point + | Line_ + | Triangle + | LineAdj + | TriangleAdj + ; + +type + : predefinedType + | userDefinedType + ; + +predefinedType + : bufferPredefinedType + | byteAddressBufferPredefinedType + | inlineStructPredefinedType + | patchPredefinedType + | matrixType + | genericMatrixPredefinedType + | samplerStatePredefinedType + | scalarType + | streamOutputPredefinedType + | structuredBufferPredefinedType + | texturePredefinedType + | genericTexturePredefinedType + | msTexturePredefinedType + | vectorType + | genericVectorType + ; + +bufferPredefinedType + : bufferType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater + ; + +bufferType + : Buffer + | RWBuffer + ; + +byteAddressBufferPredefinedType + : byteAddressBufferType + ; + +byteAddressBufferType + : ByteAddressBuffer + | RWByteAddressBuffer + ; + +inlineStructPredefinedType + : StructKeyword=Struct OpenBraceToken=LeftBrace + (variableDeclarationStatement)+ + CloseBraceToken=RightBrace + ; + +patchPredefinedType + : Keyword=patchType LessThanToken=Less + Name=userDefinedType CommaToken=Comma ControlPoints=IntegerLiteral + GreaterThanToken=Greater + ; + +patchType + : InputPatch + | OutputPatch + ; + +samplerStatePredefinedType + : Sampler + | SamplerState + | SamplerComparisonState + ; + +scalarType + : Bool + | Int + | Unsigned Int + | Dword + | Uint + | Half + | Float + | Double + ; + +streamOutputPredefinedType + : Keyword=streamOutputObjectType LessThanToken=Less type GreaterThanToken=Greater + ; + +streamOutputObjectType + : PointStream + | LineStream + | TriangleStream + ; + +structuredBufferPredefinedType + : Keyword=structuredBufferName LessThanToken=Less scalarOrVectorOrUserDefinedType GreaterThanToken=Greater + ; + +structuredBufferName + : AppendStructuredBuffer + | ConsumeStructuredBuffer + | RWStructuredBuffer + | StructuredBuffer + ; + +textureType + : Texture1D + | Texture1DArray + | Texture2D + | Texture2DArray + | Texture3D + | TextureCube + | TextureCubeArray + ; + +texturePredefinedType + : textureType + ; + +genericTexturePredefinedType + : textureType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater + ; + +textureTypeMS + : Texture2DMS + | Texture2DMSArray + ; + +msTexturePredefinedType + : textureTypeMS LessThanToken=Less scalarOrVectorType CommaToken=Comma Samples=IntegerLiteral GreaterThanToken=Greater + ; + +vectorType + : Vector + | Bool1 + | Bool2 + | Bool3 + | Bool4 + | Int1 + | Int2 + | Int3 + | Int4 + | Uint1 + | Uint2 + | Uint3 + | Uint4 + | Half1 + | Half2 + | Half3 + | Half4 + | Float1 + | Float2 + | Float3 + | Float4 + | Double1 + | Double2 + | Double3 + | Double4 + ; + +genericVectorType + : VectorKeyword=Vector LessThanToken=Less scalarType CommaToken=Comma + Size_=IntegerLiteral GreaterThanToken=Greater + ; + +scalarOrVectorType + : scalarType + | vectorType + ; + +scalarOrVectorOrUserDefinedType + : scalarType + | vectorType + | userDefinedType + ; + +scalarOrVectorOrMatrixType + : scalarType + | vectorType + | matrixType + ; + +matrixType + : Matrix + | Bool1x1 + | Bool1x2 + | Bool1x3 + | Bool1x4 + | Bool2x1 + | Bool2x2 + | Bool2x3 + | Bool2x4 + | Bool3x1 + | Bool3x2 + | Bool3x3 + | Bool3x4 + | Bool4x1 + | Bool4x2 + | Bool4x3 + | Bool4x4 + | Int1x1 + | Int1x2 + | Int1x3 + | Int1x4 + | Int2x1 + | Int2x2 + | Int2x3 + | Int2x4 + | Int3x1 + | Int3x2 + | Int3x3 + | Int3x4 + | Int4x1 + | Int4x2 + | Int4x3 + | Int4x4 + | Uint1x1 + | Uint1x2 + | Uint1x3 + | Uint1x4 + | Uint2x1 + | Uint2x2 + | Uint2x3 + | Uint2x4 + | Uint3x1 + | Uint3x2 + | Uint3x3 + | Uint3x4 + | Uint4x1 + | Uint4x2 + | Uint4x3 + | Uint4x4 + | Half1x1 + | Half1x2 + | Half1x3 + | Half1x4 + | Half2x1 + | Half2x2 + | Half2x3 + | Half2x4 + | Half3x1 + | Half3x2 + | Half3x3 + | Half3x4 + | Half4x1 + | Half4x2 + | Half4x3 + | Half4x4 + | Float1x1 + | Float1x2 + | Float1x3 + | Float1x4 + | Float2x1 + | Float2x2 + | Float2x3 + | Float2x4 + | Float3x1 + | Float3x2 + | Float3x3 + | Float3x4 + | Float4x1 + | Float4x2 + | Float4x3 + | Float4x4 + | Double1x1 + | Double1x2 + | Double1x3 + | Double1x4 + | Double2x1 + | Double2x2 + | Double2x3 + | Double2x4 + | Double3x1 + | Double3x2 + | Double3x3 + | Double3x4 + | Double4x1 + | Double4x2 + | Double4x3 + | Double4x4 + ; + +genericMatrixPredefinedType + : MatrixKeyword=Matrix LessThanToken=Less scalarType FirstCommaToken=Comma + Rows_=IntegerLiteral SecondCommaToken=Comma Cols_=IntegerLiteral + GreaterThanToken=Greater + ; + +userDefinedType + : Name=Identifier + ; + +registerAllocation + : RegisterColon=Colon RegisterKeyword=Register OpenParenToken=LeftParen Address=Identifier CloseParenToken=RightParen + ; + +variableInitializer + : EqualsToken=Assign standardVariableInitializer # StandardVariableInitializer_ + | OpenBraceToken=LeftBrace samplerStateProperty* CloseBraceToken=RightBrace # SamplerStateInitializer + ; + +standardVariableInitializer + : OpenBrace=LeftBrace arrayElementInitializers CloseBrace=RightBrace # ArrayVariableInitializer + | Expr=expression # ExpressionVariableInitializer + ; + +arrayElementInitializers + : standardVariableInitializer (Comma standardVariableInitializer)* Comma? + ; + +samplerStateProperty + : Name=Identifier EqualsToken=Assign Expr=expression SemicolonToken=Semi + ; + +literal + : True + | False + | FloatLiteral + | IntegerLiteral + | StringLiteral + ; + + + +// -------------------------------------- +// PREPROCESSOR DIRECTIVES +// -------------------------------------- + +directive + : ifDirective + | ifDefDirective + | ifNDefDirective + | elseDirective + | elifDirective + | endIfDirective + | objectLikeDefineDirective + | includeDirective + | lineDirective + ; + +ifDirective + : HashToken=Hash IfKeyword=If Condition=directiveExpression EndOfDirectiveToken=EndOfDirective + ; + +ifDefDirective + : HashToken=Hash IfDefKeyword=IfDef Name=Identifier EndOfDirectiveToken=EndOfDirective + ; + +ifNDefDirective + : HashToken=Hash IfNDefKeyword=IfNDef Name=Identifier EndOfDirectiveToken=EndOfDirective + ; + +elseDirective + : HashToken=Hash ElseKeyword=Else EndOfDirectiveToken=EndOfDirective + ; + +elifDirective + : HashToken=Hash ElifKeyword=Elif Condition=directiveExpression EndOfDirectiveToken=EndOfDirective + ; + +endIfDirective + : HashToken=Hash EndIfKeyword=EndIf EndOfDirectiveToken=EndOfDirective + ; + +objectLikeDefineDirective + : HashToken=Hash DefineKeyword=Define Name=identifierOrKeyword Values+=~(EndOfDirective)* EndOfDirectiveToken=EndOfDirective + ; + +includeDirective + : HashToken=Hash IncludeKeyword=Include Filename=StringLiteral EndOfDirectiveToken=EndOfDirective + ; + +lineDirective + : HashToken=Hash LineKeyword=Line_ LineNumber=IntegerLiteral Filename=StringLiteral EndOfDirectiveToken=EndOfDirective + ; + +directiveExpression + : literal # LiteralDirectiveExpression + | identifierOrKeyword # IdentifierDirectiveExpression + | OpenParenToken=LeftParen directiveExpression CloseParenToken=RightParen # ParenthesizedDirectiveExpression + | Function=Defined OpenParenToken=LeftParen Name=. CloseParenToken=RightParen # FunctionCallDirectiveExpression + | Expr=directiveExpression Operator=postfixUnaryOperator # PostfixUnaryDirectiveExpression + | Operator=prefixUnaryOperator Expr=directiveExpression # PrefixUnaryDirectiveExpression + | Left=directiveExpression Operator=binaryOperator Right=directiveExpression # BinaryDirectiveExpression + ; + +identifierOrKeyword + : AppendStructuredBuffer + | Bool + | Bool1 + | Bool2 + | Bool3 + | Bool4 + | Bool1x1 + | Bool1x2 + | Bool1x3 + | Bool1x4 + | Bool2x1 + | Bool2x2 + | Bool2x3 + | Bool2x4 + | Bool3x1 + | Bool3x2 + | Bool3x3 + | Bool3x4 + | Bool4x1 + | Bool4x2 + | Bool4x3 + | Bool4x4 + | Buffer + | ByteAddressBuffer + | Break + | Case + | CBuffer + | Centroid + | Class + | ColumnMajor + | Const + | ConsumeStructuredBuffer + | Continue + | Default + | Discard + | Do + | Double + | Double1 + | Double2 + | Double3 + | Double4 + | Double1x1 + | Double1x2 + | Double1x3 + | Double1x4 + | Double2x1 + | Double2x2 + | Double2x3 + | Double2x4 + | Double3x1 + | Double3x2 + | Double3x3 + | Double3x4 + | Double4x1 + | Double4x2 + | Double4x3 + | Double4x4 + | Else + | Extern + | Float + | Float1 + | Float2 + | Float3 + | Float4 + | Float1x1 + | Float1x2 + | Float1x3 + | Float1x4 + | Float2x1 + | Float2x2 + | Float2x3 + | Float2x4 + | Float3x1 + | Float3x2 + | Float3x3 + | Float3x4 + | Float4x1 + | Float4x2 + | Float4x3 + | Float4x4 + | For + | Groupshared + | Half + | Half1 + | Half2 + | Half3 + | Half4 + | Half1x1 + | Half1x2 + | Half1x3 + | Half1x4 + | Half2x1 + | Half2x2 + | Half2x3 + | Half2x4 + | Half3x1 + | Half3x2 + | Half3x3 + | Half3x4 + | Half4x1 + | Half4x2 + | Half4x3 + | Half4x4 + | If + | In + | Inout + | InputPatch + | Int + | Int1 + | Int2 + | Int3 + | Int4 + | Int1x1 + | Int1x2 + | Int1x3 + | Int1x4 + | Int2x1 + | Int2x2 + | Int2x3 + | Int2x4 + | Int3x1 + | Int3x2 + | Int3x3 + | Int3x4 + | Int4x1 + | Int4x2 + | Int4x3 + | Int4x4 + | Interface + | Line_ + | LineAdj + | Linear + | LineStream + | Matrix + | Nointerpolation + | Noperspective + | Out + | OutputPatch + | Packoffset + | Point + | PointStream + | Precise + | Register + | Return + | RowMajor + | RWBuffer + | RWByteAddressBuffer + | RWStructuredBuffer + | Sample + | Sampler + | SamplerComparisonState + | SamplerState + | Shared + | Static + | Struct + | StructuredBuffer + | Switch + | Texture1D + | Texture1DArray + | Texture2D + | Texture2DArray + | Texture2DMS + | Texture2DMSArray + | Texture3D + | TextureCube + | TextureCubeArray + | Triangle + | TriangleAdj + | TriangleStream + | Uniform + | Uint + | Uint1 + | Uint2 + | Uint3 + | Uint4 + | Uint1x1 + | Uint1x2 + | Uint1x3 + | Uint1x4 + | Uint2x1 + | Uint2x2 + | Uint2x3 + | Uint2x4 + | Uint3x1 + | Uint3x2 + | Uint3x3 + | Uint3x4 + | Uint4x1 + | Uint4x2 + | Uint4x3 + | Uint4x4 + | Vector + | Volatile + | Void + | While + | Identifier + ; \ No newline at end of file diff --git a/src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 b/src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 new file mode 100644 index 0000000000..a6b7593737 --- /dev/null +++ b/src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 @@ -0,0 +1,426 @@ +lexer grammar HlslTokens; + +@lexer::header {#pragma warning disable 3021} + +AppendStructuredBuffer : 'AppendStructuredBuffer'; +Bool : 'bool'; +Bool1 : 'bool1'; +Bool2 : 'bool2'; +Bool3 : 'bool3'; +Bool4 : 'bool4'; +Bool1x1 : 'bool1x1'; +Bool1x2 : 'bool1x2'; +Bool1x3 : 'bool1x3'; +Bool1x4 : 'bool1x4'; +Bool2x1 : 'bool2x1'; +Bool2x2 : 'bool2x2'; +Bool2x3 : 'bool2x3'; +Bool2x4 : 'bool2x4'; +Bool3x1 : 'bool3x1'; +Bool3x2 : 'bool3x2'; +Bool3x3 : 'bool3x3'; +Bool3x4 : 'bool3x4'; +Bool4x1 : 'bool4x1'; +Bool4x2 : 'bool4x2'; +Bool4x3 : 'bool4x3'; +Bool4x4 : 'bool4x4'; +Buffer : 'Buffer'; +ByteAddressBuffer : 'ByteAddressBuffer'; +Break : 'break'; +Case : 'case'; +CBuffer : 'cbuffer'; +Centroid : 'centroid'; +Class : 'class'; +ColumnMajor : 'column_major'; +Const : 'const'; +ConsumeStructuredBuffer : 'ConsumeStructuredBuffer'; +Continue : 'continue'; +Default : 'default'; +Discard : 'discard'; +Do : 'do'; +Double : 'double'; +Double1 : 'double1'; +Double2 : 'double2'; +Double3 : 'double3'; +Double4 : 'double4'; +Double1x1 : 'double1x1'; +Double1x2 : 'double1x2'; +Double1x3 : 'double1x3'; +Double1x4 : 'double1x4'; +Double2x1 : 'double2x1'; +Double2x2 : 'double2x2'; +Double2x3 : 'double2x3'; +Double2x4 : 'double2x4'; +Double3x1 : 'double3x1'; +Double3x2 : 'double3x2'; +Double3x3 : 'double3x3'; +Double3x4 : 'double3x4'; +Double4x1 : 'double4x1'; +Double4x2 : 'double4x2'; +Double4x3 : 'double4x3'; +Double4x4 : 'double4x4'; +Else : 'else'; +Extern : 'extern'; +Float : 'float'; +Float1 : 'float1'; +Float2 : 'float2'; +Float3 : 'float3'; +Float4 : 'float4'; +Float1x1 : 'float1x1'; +Float1x2 : 'float1x2'; +Float1x3 : 'float1x3'; +Float1x4 : 'float1x4'; +Float2x1 : 'float2x1'; +Float2x2 : 'float2x2'; +Float2x3 : 'float2x3'; +Float2x4 : 'float2x4'; +Float3x1 : 'float3x1'; +Float3x2 : 'float3x2'; +Float3x3 : 'float3x3'; +Float3x4 : 'float3x4'; +Float4x1 : 'float4x1'; +Float4x2 : 'float4x2'; +Float4x3 : 'float4x3'; +Float4x4 : 'float4x4'; +For : 'for'; +Groupshared : 'groupshared'; +Half : 'half'; +Half1 : 'half1'; +Half2 : 'half2'; +Half3 : 'half3'; +Half4 : 'half4'; +Half1x1 : 'half1x1'; +Half1x2 : 'half1x2'; +Half1x3 : 'half1x3'; +Half1x4 : 'half1x4'; +Half2x1 : 'half2x1'; +Half2x2 : 'half2x2'; +Half2x3 : 'half2x3'; +Half2x4 : 'half2x4'; +Half3x1 : 'half3x1'; +Half3x2 : 'half3x2'; +Half3x3 : 'half3x3'; +Half3x4 : 'half3x4'; +Half4x1 : 'half4x1'; +Half4x2 : 'half4x2'; +Half4x3 : 'half4x3'; +Half4x4 : 'half4x4'; +If : 'if'; +In : 'in'; +Inout : 'inout' | 'in out'; +InputPatch : 'InputPatch'; +Int : 'int'; +Int1 : 'int1'; +Int2 : 'int2'; +Int3 : 'int3'; +Int4 : 'int4'; +Int1x1 : 'int1x1'; +Int1x2 : 'int1x2'; +Int1x3 : 'int1x3'; +Int1x4 : 'int1x4'; +Int2x1 : 'int2x1'; +Int2x2 : 'int2x2'; +Int2x3 : 'int2x3'; +Int2x4 : 'int2x4'; +Int3x1 : 'int3x1'; +Int3x2 : 'int3x2'; +Int3x3 : 'int3x3'; +Int3x4 : 'int3x4'; +Int4x1 : 'int4x1'; +Int4x2 : 'int4x2'; +Int4x3 : 'int4x3'; +Int4x4 : 'int4x4'; +Interface : 'interface'; +Line_ : 'line'; +LineAdj : 'lineadj'; +Linear : 'linear'; +LineStream : 'LineStream'; +Long : 'long'; +Matrix : 'matrix'; +Nointerpolation : 'nointerpolation'; +Noperspective : 'noperspective'; +Out : 'out'; +OutputPatch : 'OutputPatch'; +Packoffset : 'packoffset'; +Point : 'point'; +PointStream : 'PointStream'; +Precise : 'precise'; +Register : 'register'; +Return : 'return'; +RowMajor : 'row_major'; +RWBuffer : 'RWBuffer'; +RWByteAddressBuffer : 'RWByteAddressBuffer'; +RWStructuredBuffer : 'RWStructuredBuffer'; +Sample : 'sample'; +Sampler : 'sampler'; +SamplerComparisonState : 'SamplerComparisonState'; +SamplerState : 'SamplerState'; +Shared : 'shared'; +Static : 'static'; +Struct : 'struct'; +StructuredBuffer : 'StructuredBuffer'; +Switch : 'switch'; +Texture1D : 'Texture1D'; +Texture1DArray : 'Texture1DArray'; +Texture2D : 'Texture2D'; +Texture2DArray : 'Texture2DArray'; +Texture2DMS : 'Texture2DMS'; +Texture2DMSArray : 'Texture2DMSArray'; +Texture3D : 'Texture3D'; +TextureCube : 'TextureCube'; +TextureCubeArray : 'TextureCubeArray'; +Triangle : 'triangle'; +TriangleAdj : 'triangleadj'; +TriangleStream : 'TriangleStream'; +Uniform : 'uniform'; +Uint : 'uint' | 'unsigned int' | 'dword'; +Uint1 : 'uint1'; +Uint2 : 'uint2'; +Uint3 : 'uint3'; +Uint4 : 'uint4'; +Uint1x1 : 'uint1x1'; +Uint1x2 : 'uint1x2'; +Uint1x3 : 'uint1x3'; +Uint1x4 : 'uint1x4'; +Uint2x1 : 'uint2x1'; +Uint2x2 : 'uint2x2'; +Uint2x3 : 'uint2x3'; +Uint2x4 : 'uint2x4'; +Uint3x1 : 'uint3x1'; +Uint3x2 : 'uint3x2'; +Uint3x3 : 'uint3x3'; +Uint3x4 : 'uint3x4'; +Uint4x1 : 'uint4x1'; +Uint4x2 : 'uint4x2'; +Uint4x3 : 'uint4x3'; +Uint4x4 : 'uint4x4'; +Vector : 'vector'; +Volatile : 'volatile'; +Void : 'void'; +While : 'while'; + +LeftParen : '('; +RightParen : ')'; +LeftBracket : '['; +RightBracket : ']'; +LeftBrace : '{'; +RightBrace : '}'; + +Less : '<'; +LessEqual : '<='; +Greater : '>'; +GreaterEqual : '>='; +LeftShift : '<<'; +RightShift : '>>'; + +Plus : '+'; +PlusPlus : '++'; +Minus : '-'; +MinusMinus : '--'; +Star : '*'; +Div : '/'; +Mod : '%'; + +And : '&'; +Or : '|'; +AndAnd : '&&'; +OrOr : '||'; +Caret : '^'; +Not : '!'; +Tilde : '~'; + +Question : '?'; +Colon : ':'; +ColonColon : '::'; +Semi : ';'; +Comma : ','; + +Assign : '='; +// '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' +StarAssign : '*='; +DivAssign : '/='; +ModAssign : '%='; +PlusAssign : '+='; +MinusAssign : '-='; +LeftShiftAssign : '<<='; +RightShiftAssign : '>>='; +AndAssign : '&='; +XorAssign : '^='; +OrAssign : '|='; + +Equal : '=='; +NotEqual : '!='; + +Dot : '.'; + +True : 'true'; +False : 'false'; + +Identifier + : Nondigit (Nondigit | Digit)* + ; + +fragment +Nondigit + : [a-zA-Z_] + ; + +fragment +Digit + : [0-9] + ; + +fragment +NonzeroDigit + : '0' | Digit + ; + +IntegerLiteral + : DecimalIntegerLiteral IntegerSuffix? + | HexadecimalIntegerLiteral IntegerSuffix? + ; + +fragment +DecimalIntegerLiteral + : Digit+ + ; + +fragment +HexadecimalIntegerLiteral + : ('0x' | '0X') HexadecimalDigit+ + ; + +fragment +HexadecimalDigit + : [0-9a-fA-F] + ; + +fragment +IntegerSuffix + : [uUlL] + ; + +FloatLiteral + : FractionalConstant ExponentPart? FloatingSuffix? + | DigitSequence ExponentPart FloatingSuffix? + ; + +fragment +FractionalConstant + : DigitSequence? '.' DigitSequence + | DigitSequence '.' + ; + +fragment +ExponentPart + : 'e' Sign? DigitSequence + | 'E' Sign? DigitSequence + ; + +fragment +Sign + : '+' | '-' + ; + +fragment +DigitSequence + : Digit+ + ; + +fragment +HexadecimalDigitSequence + : HexadecimalDigit+ + ; + +fragment +FloatingSuffix + : [flFL] + ; + +fragment +EscapeSequence + : SimpleEscapeSequence + ; + +fragment +SimpleEscapeSequence + : '\\' ['"?abfnrtv\\] + ; + +StringLiteral + : '"' SCharSequence? '"' + ; + +fragment +SCharSequence + : SChar+ + ; + +fragment +SChar + : ~["\\\r\n] + | EscapeSequence + ; + +LineDirective + : '#line' Whitespace? DecimalIntegerLiteral Whitespace? StringLiteral ~[\r\n]* + { + var regex = new System.Text.RegularExpressions.Regex("#line\\s(\\d+)\\s"); + Line = System.Convert.ToInt32(regex.Match(Text).Groups[1].Value) - 1; + } + -> skip + ; + +PragmaDirective + : '#' Whitespace? 'pragma' Whitespace ~[\r\n]* + -> skip + ; + +Whitespace + : [ \t]+ + ; + +Newline + : ( '\r' '\n'? + | '\n' + ) + ; + +PreprocessorDirective + : '#' Whitespace? PreprocessorDirectiveName + ; + +fragment +PreprocessorDirectiveName + : 'define' + | 'elif' + | 'else' + | 'endif' + | 'error' + | 'if' + | 'ifdef' + | 'ifndef' + | 'include' + | 'line' + | 'pragma' + | 'undef' + ; + +StartBlockComment + : '/*' -> more, mode(BlockCommentMode) + ; + +LineComment + : '//' ~[\r\n]* + ; + +// -------------------------------------- +// MODES +// -------------------------------------- + +mode BlockCommentMode; + + //BlockCommentNewline : Newline -> type(Newline); + BlockCommentContent : . -> more; + BlockCommentEndOfFile : EOF; + BlockComment : '*/' -> mode(DEFAULT_MODE); \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSL.cs b/src/Stride.Shader.Parser/SDSL.cs deleted file mode 100644 index dc124c7740..0000000000 --- a/src/Stride.Shader.Parser/SDSL.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Immutable; - -namespace Stride.Shader.Parser; - -public interface ISDSL -{ -} - -public class JsonArray : ISDSL -{ - public ImmutableArray Elements { get; } - public JsonArray(ImmutableArray elements) - { - Elements = elements; - } - public override string ToString() - => $"[{string.Join(",", Elements.Select(e => e.ToString()))}]"; -} - -public class JsonObject : ISDSL -{ - public IImmutableDictionary Members { get; } - public JsonObject(IImmutableDictionary members) - { - Members = members; - } - public override string ToString() - => $"{{{string.Join(",", Members.Select(kvp => $"\"{kvp.Key}\":{kvp.Value.ToString()}"))}}}"; -} - -public class JsonString : ISDSL -{ - public string Value { get; } - public JsonString(string value) - { - Value = value; - } - - public override string ToString() - => $"\"{Value}\""; -} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf new file mode 100644 index 0000000000..535e84191f --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -0,0 +1,807 @@ + + +compilationUnit::= Declarations+=topLevelDeclaration* EndOfFileToken=EOF + + +topLevelDeclaration::= classDefinition + | interfaceDefinition + | variableDeclarationStatement + | structDefinition + | constantBuffer + | functionDefinition + | functionDeclaration + + +OpenBraceToken ::= LeftBrace +CloseBraceToken ::= RightBrace +Name ::= Identifier +BaseListOpt ::= baselist? +SemicolonToken ::= Semi + +classDefinition::= ClassKeyword Name BaseListOpt? + OpenBraceToken classMemberDeclaration* CloseBraceToken + SemicolonToken + + +baseList::= ColonToken=Colon BaseType=Identifier + + +classMemberDeclaration::= variableDeclarationStatement + | functionDefinition + | functionDeclaration + + +constantBuffer::= CBufferKeyword=CBuffer Name=Identifier registerAllocation? + OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace + SemicolonToken=Semi? + + +variableDeclarationStatement::= variableDeclaration SemicolonToken=Semi + + +functionDefinition::= attribute* functionType (ClassName=Identifier ColonColonToken=ColonColon)? Name=Identifier + OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen + SemanticOpt=semantic? block SemicolonTokenOpt=Semi? + + +functionDeclaration::= attribute* functionType Name=Identifier + OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen + SemanticOpt=semantic? SemicolonToken=Semi + + +functionType::= type + | Void + + +functionParams::= functionParam (Comma functionParam)* + + +functionParam::= storageFlags type variableDeclarator + + +interfaceDefinition::= InterfaceKeyword=Interface Name=Identifier + OpenBraceToken=LeftBrace functionDeclaration* CloseBraceToken=RightBrace + SemicolonToken=Semi + + +structDefinition::= StructKeyword=Struct Name=Identifier + OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace + SemicolonToken=Semi + + +semantic::= ColonToken=Colon Name=Identifier + + +// -------------------------------------- +// ATTRIBUTES +// -------------------------------------- + +attributeArguments::= literalExpr (Comma literalExpr)* + + +attributeArgumentList::= OpenParenToken=LeftParen attributeArguments CloseParenToken=RightParen + + +attribute::= OpenBracketToken=LeftBracket Name=Identifier attributeArgumentList? CloseBracketToken=RightBracket + + +// -------------------------------------- +// STATEMENTS +// -------------------------------------- + +block::= OpenBrace=LeftBrace Stmts+=statement* CloseBrace=RightBrace + + +indentedEmbeddedStatement::= embeddedStatement // not a block statement + | LeftBrace Stmt=block + + +statement::= localDeclarationStatement + | embeddedStatement + | classDefinition + | interfaceDefinition + | structDefinition + + +localDeclarationStatement::= variableDeclaration SemicolonToken=Semi + + +forInitializer::= variableDeclaration # ForStatementDeclaration + | expression (Comma expression)* # ForStatementInitializers + + +forIncrementors::= expression (Comma expression)* + + +switchLabel::= CaseKeyword=Case Expr=expression ColonToken=Colon # CaseSwitchLabel + | DefaultKeyword=Default ColonToken=Colon # DefaultSwitchLabel + + +switchSection::= switchLabel+ statement+ + + +embeddedStatement::= SemicolonToken=Semi # EmptyStatement + | block # BlockStatement + | Expr=expression SemicolonToken=Semi # ExpressionStatement + + // Selection statement + | attribute* IfKeyword=If OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen Stmt=indentedEmbeddedStatement elseClause? # IfStatement + | attribute* SwitchKeyword=Switch OpenParenToken=LeftParen Expr=expression CloseParenToken=RightParen OpenBraceToken=LeftBrace switchSection* CloseBraceToken=RightBrace # SwitchStatement + + // Iteration statement + | attribute* WhileKeyword=While OpenParenToken=LeftParen condition=expression CloseParenToken=RightParen indentedEmbeddedStatement # WhileStatement + | attribute* DoKeyword=Do indentedEmbeddedStatement WhileKeyword=While OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen SemicolonToken=Semi # DoStatement + | attribute* ForKeyword=For OpenParenToken=LeftParen forInitializer? FirstSemicolonToken=Semi Condition=expression? SecondSemicolonToken=Semi iterator=forIncrementors? CloseParenToken=RightParen indentedEmbeddedStatement # ForStatement + + // Jump statement + | BreakKeyword=Break SemicolonToken=Semi # BreakStatement + | ContinueKeyword=Continue SemicolonToken=Semi # ContinueStatement + | DiscardKeyword=Discard SemicolonToken=Semi # DiscardStatement + | ReturnKeyword=Return Expr=expression? SemicolonToken=Semi # ReturnStatement + + +elseClause::= ElseKeyword=Else Stmt=indentedEmbeddedStatement + + +// -------------------------------------- +// EXPRESSIONS +// -------------------------------------- + +expression::= literalExpr # LiteralExpression + | Identifier # IdentifierExpression + | OpenParenToken=LeftParen expression CloseParenToken=RightParen # ParenthesizedExpression + | OpenParenToken=LeftParen type (ArrayRankSpecifiers+=arrayRankSpecifier)* CloseParenToken=RightParen Expr=expression # CastExpression + | Expr=expression DotToken=Dot Member=Identifier # MemberAccessExpression + | scalarOrVectorOrMatrixType argumentList # NumericConstructorExpression + | Expr=expression argumentList # FunctionCallExpression + | Expr=expression OpenBracket=LeftBracket Index=expression CloseBracket=RightBracket # ArrayAccessExpression + | Expr=expression Operator=postfixUnaryOperator # PostfixUnaryExpression + | Operator=prefixUnaryOperator Expr=expression # PrefixUnaryExpression + | Left=expression Operator=binaryOperator Right=expression # BinaryExpression + | Condition=expression QuestionToken=Question TrueExpr=expression ColonToken=Colon FalseExpr=expression # ConditionalExpression + | Left=expression Operator=assignmentOperator Right=expression # AssignmentExpression + + +literalExpr::= literal + + +postfixUnaryOperator::= PlusPlus + | MinusMinus + + +prefixUnaryOperator::= Plus + | Minus + | Not + | Tilde + | PlusPlus + | MinusMinus + + +binaryOperator::= Star + | Div + | Mod + | Plus + | Minus + | LeftShift + | RightShift + | Less + | Greater + | LessEqual + | GreaterEqual + | Equal + | NotEqual + | And + | Caret + | Or + | AndAnd + | OrOr + + +assignmentOperator::= Assign + | StarAssign + | DivAssign + | ModAssign + | PlusAssign + | MinusAssign + | LeftShiftAssign + | RightShiftAssign + | AndAssign + | XorAssign + | OrAssign + + +argumentList::= OpenParenToken=LeftParen arguments? CloseParenToken=RightParen + + +arguments::= expression (Comma expression)* + + + + +// -------------------------------------- +// TYPES +// -------------------------------------- + +variableDeclaration::= storageFlags type variableDeclarators + + +variableDeclarators::= variableDeclarator (Comma variableDeclarator)* + + +variableDeclarator::= Name=Identifier + (ArrayRankSpecifiers+=arrayRankSpecifier)* + packOffsetNode? + RegisterAllocation=registerAllocation? + SemanticOpt=semantic? + variableInitializer? + + +arrayRankSpecifier::= OpenBracketToken=LeftBracket Dimension=expression? CloseBracketToken=RightBracket + + +packOffsetNode::= ColonToken=Colon PackoffsetKeyword=Packoffset OpenParenToken=LeftParen + PackOffsetRegister=Identifier (DotToken=Dot PackOffsetComponent=Identifier)? + CloseParenToken=RightParen + + +storageFlags::= storageFlag* + + +storageFlag + // Type modifiers::= Const + | RowMajor + | ColumnMajor + // Storage classes + | Extern + | Precise + | Shared + | Groupshared + | Static + | Uniform + | Volatile + // Interpolation modifiers + | Linear + | Centroid + | Nointerpolation + | Noperspective + | Sample + // Parameter modifiers (only valid on function params) + | In + | Out + | Inout + // Geometry shader primitive type + | Point + | Line_ + | Triangle + | LineAdj + | TriangleAdj + + +type::= predefinedType + | userDefinedType + + +predefinedType::= bufferPredefinedType + | byteAddressBufferPredefinedType + | inlineStructPredefinedType + | patchPredefinedType + | matrixType + | genericMatrixPredefinedType + | samplerStatePredefinedType + | scalarType + | streamOutputPredefinedType + | structuredBufferPredefinedType + | texturePredefinedType + | genericTexturePredefinedType + | msTexturePredefinedType + | vectorType + | genericVectorType + + +bufferPredefinedType::= bufferType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater + + +bufferType::= Buffer + | RWBuffer + + +byteAddressBufferPredefinedType::= byteAddressBufferType + + +byteAddressBufferType::= ByteAddressBuffer + | RWByteAddressBuffer + + +inlineStructPredefinedType::= StructKeyword=Struct OpenBraceToken=LeftBrace + (variableDeclarationStatement)+ + CloseBraceToken=RightBrace + + +patchPredefinedType::= Keyword=patchType LessThanToken=Less + Name=userDefinedType CommaToken=Comma ControlPoints=IntegerLiteral + GreaterThanToken=Greater + + +patchType::= InputPatch + | OutputPatch + + +samplerStatePredefinedType::= Sampler + | SamplerState + | SamplerComparisonState + + +scalarType::= Bool + | Int + | Unsigned Int + | Dword + | Uint + | Half + | Float + | Double + + +streamOutputPredefinedType::= Keyword=streamOutputObjectType LessThanToken=Less type GreaterThanToken=Greater + + +streamOutputObjectType::= PointStream + | LineStream + | TriangleStream + + +structuredBufferPredefinedType::= Keyword=structuredBufferName LessThanToken=Less scalarOrVectorOrUserDefinedType GreaterThanToken=Greater + + +structuredBufferName::= AppendStructuredBuffer + | ConsumeStructuredBuffer + | RWStructuredBuffer + | StructuredBuffer + + +textureType::= Texture1D + | Texture1DArray + | Texture2D + | Texture2DArray + | Texture3D + | TextureCube + | TextureCubeArray + + +texturePredefinedType::= textureType + + +genericTexturePredefinedType::= textureType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater + + +textureTypeMS::= Texture2DMS + | Texture2DMSArray + + +msTexturePredefinedType::= textureTypeMS LessThanToken=Less scalarOrVectorType CommaToken=Comma Samples=IntegerLiteral GreaterThanToken=Greater + + +vectorType::= Vector + | Bool1 + | Bool2 + | Bool3 + | Bool4 + | Int1 + | Int2 + | Int3 + | Int4 + | Uint1 + | Uint2 + | Uint3 + | Uint4 + | Half1 + | Half2 + | Half3 + | Half4 + | Float1 + | Float2 + | Float3 + | Float4 + | Double1 + | Double2 + | Double3 + | Double4 + + +genericVectorType::= VectorKeyword=Vector LessThanToken=Less scalarType CommaToken=Comma + Size_=IntegerLiteral GreaterThanToken=Greater + + +scalarOrVectorType::= scalarType + | vectorType + + +scalarOrVectorOrUserDefinedType::= scalarType + | vectorType + | userDefinedType + + +scalarOrVectorOrMatrixType::= scalarType + | vectorType + | matrixType + + +matrixType::= Matrix + | Bool1x1 + | Bool1x2 + | Bool1x3 + | Bool1x4 + | Bool2x1 + | Bool2x2 + | Bool2x3 + | Bool2x4 + | Bool3x1 + | Bool3x2 + | Bool3x3 + | Bool3x4 + | Bool4x1 + | Bool4x2 + | Bool4x3 + | Bool4x4 + | Int1x1 + | Int1x2 + | Int1x3 + | Int1x4 + | Int2x1 + | Int2x2 + | Int2x3 + | Int2x4 + | Int3x1 + | Int3x2 + | Int3x3 + | Int3x4 + | Int4x1 + | Int4x2 + | Int4x3 + | Int4x4 + | Uint1x1 + | Uint1x2 + | Uint1x3 + | Uint1x4 + | Uint2x1 + | Uint2x2 + | Uint2x3 + | Uint2x4 + | Uint3x1 + | Uint3x2 + | Uint3x3 + | Uint3x4 + | Uint4x1 + | Uint4x2 + | Uint4x3 + | Uint4x4 + | Half1x1 + | Half1x2 + | Half1x3 + | Half1x4 + | Half2x1 + | Half2x2 + | Half2x3 + | Half2x4 + | Half3x1 + | Half3x2 + | Half3x3 + | Half3x4 + | Half4x1 + | Half4x2 + | Half4x3 + | Half4x4 + | Float1x1 + | Float1x2 + | Float1x3 + | Float1x4 + | Float2x1 + | Float2x2 + | Float2x3 + | Float2x4 + | Float3x1 + | Float3x2 + | Float3x3 + | Float3x4 + | Float4x1 + | Float4x2 + | Float4x3 + | Float4x4 + | Double1x1 + | Double1x2 + | Double1x3 + | Double1x4 + | Double2x1 + | Double2x2 + | Double2x3 + | Double2x4 + | Double3x1 + | Double3x2 + | Double3x3 + | Double3x4 + | Double4x1 + | Double4x2 + | Double4x3 + | Double4x4 + + +genericMatrixPredefinedType::= MatrixKeyword=Matrix LessThanToken=Less scalarType FirstCommaToken=Comma + Rows_=IntegerLiteral SecondCommaToken=Comma Cols_=IntegerLiteral + GreaterThanToken=Greater + + +userDefinedType::= Name=Identifier + + +registerAllocation::= RegisterColon=Colon RegisterKeyword=Register OpenParenToken=LeftParen Address=Identifier CloseParenToken=RightParen + + +variableInitializer::= EqualsToken=Assign standardVariableInitializer # StandardVariableInitializer_ + | OpenBraceToken=LeftBrace samplerStateProperty* CloseBraceToken=RightBrace # SamplerStateInitializer + + +standardVariableInitializer::= OpenBrace=LeftBrace arrayElementInitializers CloseBrace=RightBrace # ArrayVariableInitializer + | Expr=expression # ExpressionVariableInitializer + + +arrayElementInitializers::= standardVariableInitializer (Comma standardVariableInitializer)* Comma? + + +samplerStateProperty::= Name=Identifier EqualsToken=Assign Expr=expression SemicolonToken=Semi + + +literal::= True + | False + | FloatLiteral + | IntegerLiteral + | StringLiteral + + + + +// -------------------------------------- +// PREPROCESSOR DIRECTIVES +// -------------------------------------- + +directive::= ifDirective + | ifDefDirective + | ifNDefDirective + | elseDirective + | elifDirective + | endIfDirective + | objectLikeDefineDirective + | includeDirective + | lineDirective + + +ifDirective::= HashToken=Hash IfKeyword=If Condition=directiveExpression EndOfDirectiveToken=EndOfDirective + + +ifDefDirective::= HashToken=Hash IfDefKeyword=IfDef Name=Identifier EndOfDirectiveToken=EndOfDirective + + +ifNDefDirective::= HashToken=Hash IfNDefKeyword=IfNDef Name=Identifier EndOfDirectiveToken=EndOfDirective + + +elseDirective::= HashToken=Hash ElseKeyword=Else EndOfDirectiveToken=EndOfDirective + + +elifDirective::= HashToken=Hash ElifKeyword=Elif Condition=directiveExpression EndOfDirectiveToken=EndOfDirective + + +endIfDirective::= HashToken=Hash EndIfKeyword=EndIf EndOfDirectiveToken=EndOfDirective + + +objectLikeDefineDirective::= HashToken=Hash DefineKeyword=Define Name=identifierOrKeyword Values+=~(EndOfDirective)* EndOfDirectiveToken=EndOfDirective + + +includeDirective::= HashToken=Hash IncludeKeyword=Include Filename=StringLiteral EndOfDirectiveToken=EndOfDirective + + +lineDirective::= HashToken=Hash LineKeyword=Line_ LineNumber=IntegerLiteral Filename=StringLiteral EndOfDirectiveToken=EndOfDirective + + +directiveExpression::= literal # LiteralDirectiveExpression + | identifierOrKeyword # IdentifierDirectiveExpression + | OpenParenToken=LeftParen directiveExpression CloseParenToken=RightParen # ParenthesizedDirectiveExpression + | Function=Defined OpenParenToken=LeftParen Name=. CloseParenToken=RightParen # FunctionCallDirectiveExpression + | Expr=directiveExpression Operator=postfixUnaryOperator # PostfixUnaryDirectiveExpression + | Operator=prefixUnaryOperator Expr=directiveExpression # PrefixUnaryDirectiveExpression + | Left=directiveExpression Operator=binaryOperator Right=directiveExpression # BinaryDirectiveExpression + + +identifierOrKeyword::= AppendStructuredBuffer + | Bool + | Bool1 + | Bool2 + | Bool3 + | Bool4 + | Bool1x1 + | Bool1x2 + | Bool1x3 + | Bool1x4 + | Bool2x1 + | Bool2x2 + | Bool2x3 + | Bool2x4 + | Bool3x1 + | Bool3x2 + | Bool3x3 + | Bool3x4 + | Bool4x1 + | Bool4x2 + | Bool4x3 + | Bool4x4 + | Buffer + | ByteAddressBuffer + | Break + | Case + | CBuffer + | Centroid + | Class + | ColumnMajor + | Const + | ConsumeStructuredBuffer + | Continue + | Default + | Discard + | Do + | Double + | Double1 + | Double2 + | Double3 + | Double4 + | Double1x1 + | Double1x2 + | Double1x3 + | Double1x4 + | Double2x1 + | Double2x2 + | Double2x3 + | Double2x4 + | Double3x1 + | Double3x2 + | Double3x3 + | Double3x4 + | Double4x1 + | Double4x2 + | Double4x3 + | Double4x4 + | Else + | Extern + | Float + | Float1 + | Float2 + | Float3 + | Float4 + | Float1x1 + | Float1x2 + | Float1x3 + | Float1x4 + | Float2x1 + | Float2x2 + | Float2x3 + | Float2x4 + | Float3x1 + | Float3x2 + | Float3x3 + | Float3x4 + | Float4x1 + | Float4x2 + | Float4x3 + | Float4x4 + | For + | Groupshared + | Half + | Half1 + | Half2 + | Half3 + | Half4 + | Half1x1 + | Half1x2 + | Half1x3 + | Half1x4 + | Half2x1 + | Half2x2 + | Half2x3 + | Half2x4 + | Half3x1 + | Half3x2 + | Half3x3 + | Half3x4 + | Half4x1 + | Half4x2 + | Half4x3 + | Half4x4 + | If + | In + | Inout + | InputPatch + | Int + | Int1 + | Int2 + | Int3 + | Int4 + | Int1x1 + | Int1x2 + | Int1x3 + | Int1x4 + | Int2x1 + | Int2x2 + | Int2x3 + | Int2x4 + | Int3x1 + | Int3x2 + | Int3x3 + | Int3x4 + | Int4x1 + | Int4x2 + | Int4x3 + | Int4x4 + | Interface + | Line_ + | LineAdj + | Linear + | LineStream + | Matrix + | Nointerpolation + | Noperspective + | Out + | OutputPatch + | Packoffset + | Point + | PointStream + | Precise + | Register + | Return + | RowMajor + | RWBuffer + | RWByteAddressBuffer + | RWStructuredBuffer + | Sample + | Sampler + | SamplerComparisonState + | SamplerState + | Shared + | Static + | Struct + | StructuredBuffer + | Switch + | Texture1D + | Texture1DArray + | Texture2D + | Texture2DArray + | Texture2DMS + | Texture2DMSArray + | Texture3D + | TextureCube + | TextureCubeArray + | Triangle + | TriangleAdj + | TriangleStream + | Uniform + | Uint + | Uint1 + | Uint2 + | Uint3 + | Uint4 + | Uint1x1 + | Uint1x2 + | Uint1x3 + | Uint1x4 + | Uint2x1 + | Uint2x2 + | Uint2x3 + | Uint2x4 + | Uint3x1 + | Uint3x2 + | Uint3x3 + | Uint3x4 + | Uint4x1 + | Uint4x2 + | Uint4x3 + | Uint4x4 + | Vector + | Volatile + | Void + | While + | Identifier diff --git a/src/Stride.Shader.Parser/SDSLParser.cs b/src/Stride.Shader.Parser/SDSLParser.cs deleted file mode 100644 index 45c479d662..0000000000 --- a/src/Stride.Shader.Parser/SDSLParser.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Stride.Shader.Parser; -using Pidgin; -using static Pidgin.Parser; -using static Pidgin.Parser; - -public class SDSLPParser -{ - private static readonly Parser LBrace = Char('{'); - private static readonly Parser RBrace = Char('}'); - private static readonly Parser LBracket = Char('['); - private static readonly Parser RBracket = Char(']'); - private static readonly Parser Quote = Char('"'); - private static readonly Parser Colon = Char(':'); - private static readonly Parser ColonWhitespace = - Colon.Between(SkipWhitespaces); - private static readonly Parser Comma = Char(','); - private static readonly Parser Identifier = - Token(c => char.IsLetterOrDigit(c) || c.Equals('_')) - .ManyString(); - - public static Result Parse(string code) - { - return Identifier.Parse(code); - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf new file mode 100644 index 0000000000..94c441d587 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -0,0 +1,552 @@ +AppendStructuredBuffer ::= 'AppendStructuredBuffer' +Bool ::= 'bool' +Bool1 ::= 'bool1' +Bool2 ::= 'bool2' +Bool3 ::= 'bool3' +Bool4 ::= 'bool4' +Bool1x1 ::= 'bool1x1' +Bool1x2 ::= 'bool1x2' +Bool1x3 ::= 'bool1x3' +Bool1x4 ::= 'bool1x4' +Bool2x1 ::= 'bool2x1' +Bool2x2 ::= 'bool2x2' +Bool2x3 ::= 'bool2x3' +Bool2x4 ::= 'bool2x4' +Bool3x1 ::= 'bool3x1' +Bool3x2 ::= 'bool3x2' +Bool3x3 ::= 'bool3x3' +Bool3x4 ::= 'bool3x4' +Bool4x1 ::= 'bool4x1' +Bool4x2 ::= 'bool4x2' +Bool4x3 ::= 'bool4x3' +Bool4x4 ::= 'bool4x4' +Buffer ::= 'Buffer' +ByteAddressBuffer ::= 'ByteAddressBuffer' +Break ::= 'break' +Case ::= 'case' +CBuffer ::= 'cbuffer' +Centroid ::= 'centroid' +Class ::= 'class' +ColumnMajor ::= 'column_major' +Const ::= 'const' +ConsumeStructuredBuffer ::= 'ConsumeStructuredBuffer' +Continue ::= 'continue' +Default ::= 'default' +Discard ::= 'discard' +Do ::= 'do' +Double ::= 'double' +Double1 ::= 'double1' +Double2 ::= 'double2' +Double3 ::= 'double3' +Double4 ::= 'double4' +Double1x1 ::= 'double1x1' +Double1x2 ::= 'double1x2' +Double1x3 ::= 'double1x3' +Double1x4 ::= 'double1x4' +Double2x1 ::= 'double2x1' +Double2x2 ::= 'double2x2' +Double2x3 ::= 'double2x3' +Double2x4 ::= 'double2x4' +Double3x1 ::= 'double3x1' +Double3x2 ::= 'double3x2' +Double3x3 ::= 'double3x3' +Double3x4 ::= 'double3x4' +Double4x1 ::= 'double4x1' +Double4x2 ::= 'double4x2' +Double4x3 ::= 'double4x3' +Double4x4 ::= 'double4x4' +Else ::= 'else' +Extern ::= 'extern' +Float ::= 'float' +Float1 ::= 'float1' +Float2 ::= 'float2' +Float3 ::= 'float3' +Float4 ::= 'float4' +Float1x1 ::= 'float1x1' +Float1x2 ::= 'float1x2' +Float1x3 ::= 'float1x3' +Float1x4 ::= 'float1x4' +Float2x1 ::= 'float2x1' +Float2x2 ::= 'float2x2' +Float2x3 ::= 'float2x3' +Float2x4 ::= 'float2x4' +Float3x1 ::= 'float3x1' +Float3x2 ::= 'float3x2' +Float3x3 ::= 'float3x3' +Float3x4 ::= 'float3x4' +Float4x1 ::= 'float4x1' +Float4x2 ::= 'float4x2' +Float4x3 ::= 'float4x3' +Float4x4 ::= 'float4x4' +For ::= 'for' +Groupshared ::= 'groupshared' +Half ::= 'half' +Half1 ::= 'half1' +Half2 ::= 'half2' +Half3 ::= 'half3' +Half4 ::= 'half4' +Half1x1 ::= 'half1x1' +Half1x2 ::= 'half1x2' +Half1x3 ::= 'half1x3' +Half1x4 ::= 'half1x4' +Half2x1 ::= 'half2x1' +Half2x2 ::= 'half2x2' +Half2x3 ::= 'half2x3' +Half2x4 ::= 'half2x4' +Half3x1 ::= 'half3x1' +Half3x2 ::= 'half3x2' +Half3x3 ::= 'half3x3' +Half3x4 ::= 'half3x4' +Half4x1 ::= 'half4x1' +Half4x2 ::= 'half4x2' +Half4x3 ::= 'half4x3' +Half4x4 ::= 'half4x4' +If ::= 'if' +In ::= 'in' +Inout ::= 'inout' | 'in out' +InputPatch ::= 'InputPatch' +Int ::= 'int' +Int1 ::= 'int1' +Int2 ::= 'int2' +Int3 ::= 'int3' +Int4 ::= 'int4' +Int1x1 ::= 'int1x1' +Int1x2 ::= 'int1x2' +Int1x3 ::= 'int1x3' +Int1x4 ::= 'int1x4' +Int2x1 ::= 'int2x1' +Int2x2 ::= 'int2x2' +Int2x3 ::= 'int2x3' +Int2x4 ::= 'int2x4' +Int3x1 ::= 'int3x1' +Int3x2 ::= 'int3x2' +Int3x3 ::= 'int3x3' +Int3x4 ::= 'int3x4' +Int4x1 ::= 'int4x1' +Int4x2 ::= 'int4x2' +Int4x3 ::= 'int4x3' +Int4x4 ::= 'int4x4' +Interface ::= 'interface' +Line_ ::= 'line' +LineAdj ::= 'lineadj' +Linear ::= 'linear' +LineStream ::= 'LineStream' +Long ::= 'long' +Matrix ::= 'matrix' +Nointerpolation ::= 'nointerpolation' +Noperspective ::= 'noperspective' +Out ::= 'out' +OutputPatch ::= 'OutputPatch' +Packoffset ::= 'packoffset' +Point ::= 'point' +PointStream ::= 'PointStream' +Precise ::= 'precise' +Register ::= 'register' +Return ::= 'return' +RowMajor ::= 'row_major' +RWBuffer ::= 'RWBuffer' +RWByteAddressBuffer ::= 'RWByteAddressBuffer' +RWStructuredBuffer ::= 'RWStructuredBuffer' +Sample ::= 'sample' +Sampler ::= 'sampler' +SamplerComparisonState ::= 'SamplerComparisonState' +SamplerState ::= 'SamplerState' +Shared ::= 'shared' +Static ::= 'static' +Struct ::= 'struct' +StructuredBuffer ::= 'StructuredBuffer' +Switch ::= 'switch' +Texture1D ::= 'Texture1D' +Texture1DArray ::= 'Texture1DArray' +Texture2D ::= 'Texture2D' +Texture2DArray ::= 'Texture2DArray' +Texture2DMS ::= 'Texture2DMS' +Texture2DMSArray ::= 'Texture2DMSArray' +Texture3D ::= 'Texture3D' +TextureCube ::= 'TextureCube' +TextureCubeArray ::= 'TextureCubeArray' +Triangle ::= 'triangle' +TriangleAdj ::= 'triangleadj' +TriangleStream ::= 'TriangleStream' +Uniform ::= 'uniform' +Uint ::= 'uint' | 'unsigned int' | 'dword' +Uint1 ::= 'uint1' +Uint2 ::= 'uint2' +Uint3 ::= 'uint3' +Uint4 ::= 'uint4' +Uint1x1 ::= 'uint1x1' +Uint1x2 ::= 'uint1x2' +Uint1x3 ::= 'uint1x3' +Uint1x4 ::= 'uint1x4' +Uint2x1 ::= 'uint2x1' +Uint2x2 ::= 'uint2x2' +Uint2x3 ::= 'uint2x3' +Uint2x4 ::= 'uint2x4' +Uint3x1 ::= 'uint3x1' +Uint3x2 ::= 'uint3x2' +Uint3x3 ::= 'uint3x3' +Uint3x4 ::= 'uint3x4' +Uint4x1 ::= 'uint4x1' +Uint4x2 ::= 'uint4x2' +Uint4x3 ::= 'uint4x3' +Uint4x4 ::= 'uint4x4' +Vector ::= 'vector' +Volatile ::= 'volatile' +Void ::= 'void' +While ::= 'while' + +LeftParen ::= '(' +RightParen ::= ')' +LeftBracket ::= '[' +RightBracket ::= ']' +LeftBrace ::= '{' +RightBrace ::= '}' + +Less ::= '<' +LessEqual ::= '<=' +Greater ::= '>' +GreaterEqual ::= '>=' +LeftShift ::= '<<' +RightShift ::= '>>' + +Plus ::= '+' +PlusPlus ::= '++' +Minus ::= '-' +MinusMinus ::= '--' +Star ::= '*' +Div ::= '/' +Mod ::= '%' + +And ::= '&' +Or ::= '|' +AndAnd ::= '&&' +OrOr ::= '||' +Caret ::= '^' +Not ::= '!' +Tilde ::= '~' + +Question ::= '?' +Colon ::= ':' +ColonColon ::= '::' +Semi ::= '' +Comma ::= ',' + +Assign ::= '=' +StarAssign ::= '*=' +DivAssign ::= '/=' +ModAssign ::= '%=' +PlusAssign ::= '+=' +MinusAssign ::= '-=' +LeftShiftAssign ::= '<<=' +RightShiftAssign ::= '>>=' +AndAssign ::= '&=' +XorAssign ::= '^=' +OrAssign ::= '|=' + +Equal ::= '==' +NotEqual ::= '!=' + +Dot ::= '.' + +True ::= 'true' +False ::= 'false' + +Identifier ::= + Nondigit (Nondigit | Digit)* + +Nondigit ::= [a-zA-Z_] + +Digit ::= [0-9] + +NonzeroDigit ::= '0' | Digit + +IntegerLiteral ::= + DecimalIntegerLiteral IntegerSuffix? + | HexadecimalIntegerLiteral IntegerSuffix? + + +DecimalIntegerLiteral ::= Digit+ + +HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ + + +HexadecimalDigit ::= [0-9a-fA-F] + +IntegerSuffix ::= [uUlL] + +FloatLiteral ::= + FractionalConstant ExponentPart? FloatingSuffix? + | DigitSequence ExponentPart FloatingSuffix? + +FractionalConstant ::= + DigitSequence? '.' DigitSequence + | DigitSequence '.' + + +ExponentPart ::= + 'e' Sign? DigitSequence + | 'E' Sign? DigitSequence + +Sign ::= '+' | '-' + + +DigitSequence ::= Digit+ + + +HexadecimalDigitSequence ::= HexadecimalDigit+ + + +FloatingSuffix ::= [flFL] + + +EscapeSequence ::= SimpleEscapeSequence + + +SimpleEscapeSequence ::= '\\' ['"?abfnrtv\\] + +StringLiteral ::= '"' SCharSequence? '"' + + +SCharSequence ::= SChar+ + + +SChar ::= + (SCharSequence - ["\\\r\n]) + | EscapeSequence + +Whitespace ::= [ \t]+ + +Newline ::= ('\r' '\n'? | '\n') + +PreprocessorDirective ::= '#' Whitespace? PreprocessorDirectiveName + + +PreprocessorDirectiveName ::= + 'define' + | 'elif' + | 'else' + | 'endif' + | 'error' + | 'if' + | 'ifdef' + | 'ifndef' + | 'include' + | 'line' + | 'pragma' + | 'undef' + + +LineComment ::= '//' (SCharSequence - [\r\n]) + +BlockComment ::= '/*' SCharSequence '*/' + + + +BaseTypes ::= Float4 + +Others ::= + AppendStructuredBuffer + | Bool + | Bool1 + | Bool2 + | Bool3 + | Bool4 + | Bool1x1 + | Bool1x2 + | Bool1x3 + | Bool1x4 + | Bool2x1 + | Bool2x2 + | Bool2x3 + | Bool2x4 + | Bool3x1 + | Bool3x2 + | Bool3x3 + | Bool3x4 + | Bool4x1 + | Bool4x2 + | Bool4x3 + | Bool4x4 + | Buffer + | ByteAddressBuffer + | ConsumeStructuredBuffer + | Double + | Double1 + | Double2 + | Double3 + | Double4 + | Double1x1 + | Double1x2 + | Double1x3 + | Double1x4 + | Double2x1 + | Double2x2 + | Double2x3 + | Double2x4 + | Double3x1 + | Double3x2 + | Double3x3 + | Double3x4 + | Double4x1 + | Double4x2 + | Double4x3 + | Double4x4 + | Float + | Float1 + | Float2 + | Float3 + | Float4 + | Float1x1 + | Float1x2 + | Float1x3 + | Float1x4 + | Float2x1 + | Float2x2 + | Float2x3 + | Float2x4 + | Float3x1 + | Float3x2 + | Float3x3 + | Float3x4 + | Float4x1 + | Float4x2 + | Float4x3 + | Float4x4 + | Half + | Half1 + | Half2 + | Half3 + | Half4 + | Half1x1 + | Half1x2 + | Half1x3 + | Half1x4 + | Half2x1 + | Half2x2 + | Half2x3 + | Half2x4 + | Half3x1 + | Half3x2 + | Half3x3 + | Half3x4 + | Half4x1 + | Half4x2 + | Half4x3 + | Half4x4 + | InputPatch + | Int + | Int1 + | Int2 + | Int3 + | Int4 + | Int1x1 + | Int1x2 + | Int1x3 + | Int1x4 + | Int2x1 + | Int2x2 + | Int2x3 + | Int2x4 + | Int3x1 + | Int3x2 + | Int3x3 + | Int3x4 + | Int4x1 + | Int4x2 + | Int4x3 + | Int4x4 + | Line_ + | LineAdj + | Linear + | LineStream + | Long + | Matrix + | Nointerpolation + | Noperspective + | OutputPatch + | Packoffset + | Point + | PointStream + | Register + | RowMajor + | RWBuffer + | RWByteAddressBuffer + | RWStructuredBuffer + | Sample + | Sampler + | SamplerComparisonState + | SamplerState + | StructuredBuffer + | Texture1D + | Texture1DArray + | Texture2D + | Texture2DArray + | Texture2DMS + | Texture2DMSArray + | Texture3D + | TextureCube + | TextureCubeArray + | Triangle + | TriangleAdj + | TriangleStream + | Uint + | Uint1 + | Uint2 + | Uint3 + | Uint4 + | Uint1x1 + | Uint1x2 + | Uint1x3 + | Uint1x4 + | Uint2x1 + | Uint2x2 + | Uint2x3 + | Uint2x4 + | Uint3x1 + | Uint3x2 + | Uint3x3 + | Uint3x4 + | Uint4x1 + | Uint4x2 + | Uint4x3 + | Uint4x4 + | Vector + | Void + + + +CodeFlow ::= + For + | While + | Break + | Case + | CBuffer + | Centroid + | Class + | Interface + | Struct + | ColumnMajor + | Continue + | Default + | Discard + | Do + | Switch + | If + | Return + + + +StorageClass ::= + Volatile + | Extern + | Else + | Groupshared + | In + | Inout + | Out + | Uniform + | Const + | Precise + | Static + | Shared + diff --git a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj index fbde38f44e..bd269449a0 100644 --- a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj +++ b/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj @@ -24,9 +24,5 @@ - - - - diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 3f6d97a77c..8306e85f1b 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -9,4 +9,9 @@ public static Grammar New() { return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); } + public static Grammar Token() + { + return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.SDSLTokens),"BaseTypes"); + } + } \ No newline at end of file From 0082fae149a0f3f6dbbb765cd38eb2b8596e2c96 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 25 Apr 2022 00:54:58 +0200 Subject: [PATCH 0017/1182] Expression grammar --- src/SDSLParser/Program.cs | 2 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 314 ++++++++++++---------- src/Stride.Shader.Parser/SDSLTokens.ebnf | 213 +-------------- src/Stride.Shader.Parser/StrideGrammar.cs | 9 + 4 files changed, 181 insertions(+), 357 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 1c62e5c995..cfa6ff2b7f 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -8,7 +8,7 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New(); -var tokens = StrideGrammar.Token(); +var tokens = StrideGrammar.HlslGrammar(); // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 535e84191f..7727bcb1ee 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -1,6 +1,7 @@ +EndOfFileToken ::= EOF -compilationUnit::= Declarations+=topLevelDeclaration* EndOfFileToken=EOF +compilationUnit::= topLevelDeclaration* EndOfFileToken topLevelDeclaration::= classDefinition @@ -11,19 +12,12 @@ topLevelDeclaration::= classDefinition | functionDefinition | functionDeclaration - -OpenBraceToken ::= LeftBrace -CloseBraceToken ::= RightBrace -Name ::= Identifier -BaseListOpt ::= baselist? -SemicolonToken ::= Semi - classDefinition::= ClassKeyword Name BaseListOpt? OpenBraceToken classMemberDeclaration* CloseBraceToken SemicolonToken - -baseList::= ColonToken=Colon BaseType=Identifier +BaseType ::= Identifier +baseList::= ColonToken BaseType classMemberDeclaration::= variableDeclarationStatement @@ -31,22 +25,25 @@ classMemberDeclaration::= variableDeclarationStatement | functionDeclaration -constantBuffer::= CBufferKeyword=CBuffer Name=Identifier registerAllocation? - OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace - SemicolonToken=Semi? +constantBuffer::= CBufferKeyword Name registerAllocation? + OpenBraceToken (variableDeclarationStatement)+ CloseBraceToken + SemicolonToken? + -variableDeclarationStatement::= variableDeclaration SemicolonToken=Semi +variableDeclarationStatement ::= variableDeclaration SemicolonToken -functionDefinition::= attribute* functionType (ClassName=Identifier ColonColonToken=ColonColon)? Name=Identifier - OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen - SemanticOpt=semantic? block SemicolonTokenOpt=Semi? -functionDeclaration::= attribute* functionType Name=Identifier - OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen - SemanticOpt=semantic? SemicolonToken=Semi +functionDefinition::= attribute* functionType (ClassName ColonColonToken)? Name + OpenParenToken functionParams? CloseParenToken + SemanticOpt block SemicolonTokenOpt? + + +functionDeclaration::= attribute* functionType Name + OpenParenToken functionParams? CloseParenToken + SemanticOpt SemicolonToken functionType::= type @@ -58,42 +55,40 @@ functionParams::= functionParam (Comma functionParam)* functionParam::= storageFlags type variableDeclarator +InterfaceKeyword ::= Interface -interfaceDefinition::= InterfaceKeyword=Interface Name=Identifier - OpenBraceToken=LeftBrace functionDeclaration* CloseBraceToken=RightBrace - SemicolonToken=Semi +interfaceDefinition::= InterfaceKeyword Name + OpenBraceToken functionDeclaration* CloseBraceToken + SemicolonToken +StructKeyword ::= Struct -structDefinition::= StructKeyword=Struct Name=Identifier - OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace - SemicolonToken=Semi +structDefinition::= StructKeyword Name + OpenBraceToken (variableDeclarationStatement)+ CloseBraceToken + SemicolonToken -semantic::= ColonToken=Colon Name=Identifier +semantic::= ColonToken Name -// -------------------------------------- -// ATTRIBUTES -// -------------------------------------- attributeArguments::= literalExpr (Comma literalExpr)* -attributeArgumentList::= OpenParenToken=LeftParen attributeArguments CloseParenToken=RightParen - +attributeArgumentList::= OpenParenToken attributeArguments CloseParenToken -attribute::= OpenBracketToken=LeftBracket Name=Identifier attributeArgumentList? CloseBracketToken=RightBracket +OpenBracketToken ::= LeftBracket +CloseBracketToken ::= RightBracket +attribute::= OpenBracketToken Name attributeArgumentList? CloseBracketToken -// -------------------------------------- -// STATEMENTS -// -------------------------------------- -block::= OpenBrace=LeftBrace Stmts+=statement* CloseBrace=RightBrace +block::= LeftBrace statement* RightBrace - -indentedEmbeddedStatement::= embeddedStatement // not a block statement - | LeftBrace Stmt=block +Stmt ::= block +indentedEmbeddedStatement::= + embeddedStatement + | LeftBrace Stmt statement::= localDeclarationStatement @@ -103,63 +98,61 @@ statement::= localDeclarationStatement | structDefinition -localDeclarationStatement::= variableDeclaration SemicolonToken=Semi +localDeclarationStatement::= variableDeclaration SemicolonToken -forInitializer::= variableDeclaration # ForStatementDeclaration - | expression (Comma expression)* # ForStatementInitializers +forInitializer::= + variableDeclaration + | expression (Comma expression)* forIncrementors::= expression (Comma expression)* -switchLabel::= CaseKeyword=Case Expr=expression ColonToken=Colon # CaseSwitchLabel - | DefaultKeyword=Default ColonToken=Colon # DefaultSwitchLabel + +switchLabel::= CaseKeyword Expr ColonToken + | DefaultKeyword ColonToken switchSection::= switchLabel+ statement+ -embeddedStatement::= SemicolonToken=Semi # EmptyStatement - | block # BlockStatement - | Expr=expression SemicolonToken=Semi # ExpressionStatement +IfKeyword ::= If +embeddedStatement::= SemicolonToken + | block + | Expr SemicolonToken - // Selection statement - | attribute* IfKeyword=If OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen Stmt=indentedEmbeddedStatement elseClause? # IfStatement - | attribute* SwitchKeyword=Switch OpenParenToken=LeftParen Expr=expression CloseParenToken=RightParen OpenBraceToken=LeftBrace switchSection* CloseBraceToken=RightBrace # SwitchStatement + + | attribute* IfKeyword OpenParenToken expression CloseParenToken indentedEmbeddedStatement elseClause? + | attribute* SwitchKeyword OpenParenToken Expr CloseParenToken OpenBraceToken switchSection* CloseBraceToken - // Iteration statement - | attribute* WhileKeyword=While OpenParenToken=LeftParen condition=expression CloseParenToken=RightParen indentedEmbeddedStatement # WhileStatement - | attribute* DoKeyword=Do indentedEmbeddedStatement WhileKeyword=While OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen SemicolonToken=Semi # DoStatement - | attribute* ForKeyword=For OpenParenToken=LeftParen forInitializer? FirstSemicolonToken=Semi Condition=expression? SecondSemicolonToken=Semi iterator=forIncrementors? CloseParenToken=RightParen indentedEmbeddedStatement # ForStatement + | attribute* While OpenParenToken expression CloseParenToken indentedEmbeddedStatement + | attribute* Do indentedEmbeddedStatement While OpenParenToken expression CloseParenToken SemicolonToken + | attribute* For OpenParenToken forInitializer? FirstSemicolonToken expression? SecondSemicolonToken forIncrementors? CloseParenToken indentedEmbeddedStatement - // Jump statement - | BreakKeyword=Break SemicolonToken=Semi # BreakStatement - | ContinueKeyword=Continue SemicolonToken=Semi # ContinueStatement - | DiscardKeyword=Discard SemicolonToken=Semi # DiscardStatement - | ReturnKeyword=Return Expr=expression? SemicolonToken=Semi # ReturnStatement + | Break SemicolonToken + | Continue SemicolonToken + | Discard SemicolonToken + | Return Expr? SemicolonToken -elseClause::= ElseKeyword=Else Stmt=indentedEmbeddedStatement +elseClause::= ElseKeyword indentedEmbeddedStatement -// -------------------------------------- -// EXPRESSIONS -// -------------------------------------- -expression::= literalExpr # LiteralExpression - | Identifier # IdentifierExpression - | OpenParenToken=LeftParen expression CloseParenToken=RightParen # ParenthesizedExpression - | OpenParenToken=LeftParen type (ArrayRankSpecifiers+=arrayRankSpecifier)* CloseParenToken=RightParen Expr=expression # CastExpression - | Expr=expression DotToken=Dot Member=Identifier # MemberAccessExpression - | scalarOrVectorOrMatrixType argumentList # NumericConstructorExpression - | Expr=expression argumentList # FunctionCallExpression - | Expr=expression OpenBracket=LeftBracket Index=expression CloseBracket=RightBracket # ArrayAccessExpression - | Expr=expression Operator=postfixUnaryOperator # PostfixUnaryExpression - | Operator=prefixUnaryOperator Expr=expression # PrefixUnaryExpression - | Left=expression Operator=binaryOperator Right=expression # BinaryExpression - | Condition=expression QuestionToken=Question TrueExpr=expression ColonToken=Colon FalseExpr=expression # ConditionalExpression - | Left=expression Operator=assignmentOperator Right=expression # AssignmentExpression +expression::= literalExpr + | Identifier + | OpenParenToken expression CloseParenToken + | OpenParenToken type (arrayRankSpecifier)* CloseParenToken Expr + | Expr DotToken Identifier + | scalarOrVectorOrMatrixType argumentList + | Expr argumentList + | Expr LeftBracket expression RightBracket + | Expr postfixUnaryOperator + | prefixUnaryOperator Expr + | expression binaryOperator expression + | expression Question TrueExpr ColonToken FalseExpr + | right expression assignmentOperator expression literalExpr::= literal @@ -210,48 +203,46 @@ assignmentOperator::= Assign | OrAssign -argumentList::= OpenParenToken=LeftParen arguments? CloseParenToken=RightParen +argumentList::= OpenParenToken arguments? CloseParenToken arguments::= expression (Comma expression)* - -// -------------------------------------- -// TYPES -// -------------------------------------- - variableDeclaration::= storageFlags type variableDeclarators variableDeclarators::= variableDeclarator (Comma variableDeclarator)* -variableDeclarator::= Name=Identifier - (ArrayRankSpecifiers+=arrayRankSpecifier)* - packOffsetNode? - RegisterAllocation=registerAllocation? - SemanticOpt=semantic? - variableInitializer? +variableDeclarator::= + Name + | (ArrayRankSpecifiers)* + | packOffsetNode? + | RegisterAllocation + | SemanticOpt + | variableInitializer? + + +arrayRankSpecifier::= OpenBracketToken expression? CloseBracketToken -arrayRankSpecifier::= OpenBracketToken=LeftBracket Dimension=expression? CloseBracketToken=RightBracket -packOffsetNode::= ColonToken=Colon PackoffsetKeyword=Packoffset OpenParenToken=LeftParen - PackOffsetRegister=Identifier (DotToken=Dot PackOffsetComponent=Identifier)? - CloseParenToken=RightParen +packOffsetNode::= ColonToken Packoffset OpenParenToken + PackOffsetRegister (DotToken PackOffsetComponent)? + CloseParenToken storageFlags::= storageFlag* storageFlag - // Type modifiers::= Const + | RowMajor | ColumnMajor - // Storage classes + | Extern | Precise | Shared @@ -259,17 +250,14 @@ storageFlag | Static | Uniform | Volatile - // Interpolation modifiers | Linear | Centroid | Nointerpolation | Noperspective | Sample - // Parameter modifiers (only valid on function params) | In | Out | Inout - // Geometry shader primitive type | Point | Line_ | Triangle @@ -298,7 +286,7 @@ predefinedType::= bufferPredefinedType | genericVectorType -bufferPredefinedType::= bufferType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater +bufferPredefinedType::= bufferType Less scalarOrVectorType Greater bufferType::= Buffer @@ -312,14 +300,14 @@ byteAddressBufferType::= ByteAddressBuffer | RWByteAddressBuffer -inlineStructPredefinedType::= StructKeyword=Struct OpenBraceToken=LeftBrace +inlineStructPredefinedType::= Struct OpenBraceToken (variableDeclarationStatement)+ - CloseBraceToken=RightBrace + CloseBraceToken -patchPredefinedType::= Keyword=patchType LessThanToken=Less - Name=userDefinedType CommaToken=Comma ControlPoints=IntegerLiteral - GreaterThanToken=Greater +patchPredefinedType::= patchType Less + userDefinedType Comma IntegerLiteral + Greater patchType::= InputPatch @@ -341,7 +329,7 @@ scalarType::= Bool | Double -streamOutputPredefinedType::= Keyword=streamOutputObjectType LessThanToken=Less type GreaterThanToken=Greater +streamOutputPredefinedType::= streamOutputObjectType Less type Greater streamOutputObjectType::= PointStream @@ -349,7 +337,7 @@ streamOutputObjectType::= PointStream | TriangleStream -structuredBufferPredefinedType::= Keyword=structuredBufferName LessThanToken=Less scalarOrVectorOrUserDefinedType GreaterThanToken=Greater +structuredBufferPredefinedType::= structuredBufferName Less scalarOrVectorOrUserDefinedType Greater structuredBufferName::= AppendStructuredBuffer @@ -370,14 +358,14 @@ textureType::= Texture1D texturePredefinedType::= textureType -genericTexturePredefinedType::= textureType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater +genericTexturePredefinedType::= textureType Less scalarOrVectorType Greater textureTypeMS::= Texture2DMS | Texture2DMSArray -msTexturePredefinedType::= textureTypeMS LessThanToken=Less scalarOrVectorType CommaToken=Comma Samples=IntegerLiteral GreaterThanToken=Greater +msTexturePredefinedType::= textureTypeMS Less scalarOrVectorType Comma IntegerLiteral Greater vectorType::= Vector @@ -407,8 +395,8 @@ vectorType::= Vector | Double4 -genericVectorType::= VectorKeyword=Vector LessThanToken=Less scalarType CommaToken=Comma - Size_=IntegerLiteral GreaterThanToken=Greater +genericVectorType::= + Vector Less scalarType Comma IntegerLiteral Greater scalarOrVectorType::= scalarType @@ -524,32 +512,35 @@ matrixType::= Matrix | Double4x4 -genericMatrixPredefinedType::= MatrixKeyword=Matrix LessThanToken=Less scalarType FirstCommaToken=Comma - Rows_=IntegerLiteral SecondCommaToken=Comma Cols_=IntegerLiteral - GreaterThanToken=Greater +genericMatrixPredefinedType::= Matrix Less scalarType Comma + IntegerLiteral Comma IntegerLiteral + Greater -userDefinedType::= Name=Identifier +userDefinedType::= Name -registerAllocation::= RegisterColon=Colon RegisterKeyword=Register OpenParenToken=LeftParen Address=Identifier CloseParenToken=RightParen +registerAllocation::= Colon Register OpenParenToken Identifier CloseParenToken -variableInitializer::= EqualsToken=Assign standardVariableInitializer # StandardVariableInitializer_ - | OpenBraceToken=LeftBrace samplerStateProperty* CloseBraceToken=RightBrace # SamplerStateInitializer +variableInitializer::= + Assign standardVariableInitializer + | OpenBraceToken samplerStateProperty* CloseBraceToken -standardVariableInitializer::= OpenBrace=LeftBrace arrayElementInitializers CloseBrace=RightBrace # ArrayVariableInitializer - | Expr=expression # ExpressionVariableInitializer +standardVariableInitializer::= + LeftBrace arrayElementInitializers RightBrace + | Expr arrayElementInitializers::= standardVariableInitializer (Comma standardVariableInitializer)* Comma? -samplerStateProperty::= Name=Identifier EqualsToken=Assign Expr=expression SemicolonToken=Semi +samplerStateProperty::= Name Assign Expr SemicolonToken -literal::= True +literal::= + True | False | FloatLiteral | IntegerLiteral @@ -557,11 +548,6 @@ literal::= True - -// -------------------------------------- -// PREPROCESSOR DIRECTIVES -// -------------------------------------- - directive::= ifDirective | ifDefDirective | ifNDefDirective @@ -573,43 +559,47 @@ directive::= ifDirective | lineDirective -ifDirective::= HashToken=Hash IfKeyword=If Condition=directiveExpression EndOfDirectiveToken=EndOfDirective +ifDirective::= HashToken IfKeyword directiveExpression EndOfDirectiveToken -ifDefDirective::= HashToken=Hash IfDefKeyword=IfDef Name=Identifier EndOfDirectiveToken=EndOfDirective +ifDefDirective::= HashToken IfDef Name EndOfDirectiveToken -ifNDefDirective::= HashToken=Hash IfNDefKeyword=IfNDef Name=Identifier EndOfDirectiveToken=EndOfDirective +ifNDefDirective::= HashToken IfNDef Name EndOfDirectiveToken -elseDirective::= HashToken=Hash ElseKeyword=Else EndOfDirectiveToken=EndOfDirective +elseDirective::= HashToken ElseKeyword EndOfDirectiveToken -elifDirective::= HashToken=Hash ElifKeyword=Elif Condition=directiveExpression EndOfDirectiveToken=EndOfDirective +elifDirective::= HashToken Elif directiveExpression EndOfDirectiveToken -endIfDirective::= HashToken=Hash EndIfKeyword=EndIf EndOfDirectiveToken=EndOfDirective +endIfDirective::= HashToken EndIf EndOfDirectiveToken -objectLikeDefineDirective::= HashToken=Hash DefineKeyword=Define Name=identifierOrKeyword Values+=~(EndOfDirective)* EndOfDirectiveToken=EndOfDirective +objectLikeDefineDirective::= HashToken Define NameOrKeyword (EndOfDirective)* EndOfDirectiveToken -includeDirective::= HashToken=Hash IncludeKeyword=Include Filename=StringLiteral EndOfDirectiveToken=EndOfDirective +includeDirective::= HashToken Include StringLiteral EndOfDirectiveToken -lineDirective::= HashToken=Hash LineKeyword=Line_ LineNumber=IntegerLiteral Filename=StringLiteral EndOfDirectiveToken=EndOfDirective +lineDirective::= HashToken Line_ IntegerLiteral StringLiteral EndOfDirectiveToken +Function ::= Defined -directiveExpression::= literal # LiteralDirectiveExpression - | identifierOrKeyword # IdentifierDirectiveExpression - | OpenParenToken=LeftParen directiveExpression CloseParenToken=RightParen # ParenthesizedDirectiveExpression - | Function=Defined OpenParenToken=LeftParen Name=. CloseParenToken=RightParen # FunctionCallDirectiveExpression - | Expr=directiveExpression Operator=postfixUnaryOperator # PostfixUnaryDirectiveExpression - | Operator=prefixUnaryOperator Expr=directiveExpression # PrefixUnaryDirectiveExpression - | Left=directiveExpression Operator=binaryOperator Right=directiveExpression # BinaryDirectiveExpression +directiveExpression::= literal + | identifierOrKeyword + | OpenParenToken directiveExpression CloseParenToken + | Function OpenParenToken Identifier CloseParenToken + | directiveExpression postfixUnaryOperator + | prefixUnaryOperator directiveExpression + | directiveExpression binaryOperator directiveExpression -identifierOrKeyword::= AppendStructuredBuffer +FloatVector ::= Float1 | Float2 | Float3 | Float4 + +identifierOrKeyword ::= + AppendStructuredBuffer | Bool | Bool1 | Bool2 @@ -668,7 +658,7 @@ identifierOrKeyword::= AppendStructuredBuffer | Double4x4 | Else | Extern - | Float + | Float - FloatVector | Float1 | Float2 | Float3 @@ -805,3 +795,39 @@ identifierOrKeyword::= AppendStructuredBuffer | Void | While | Identifier + +CloseBraceToken ::= RightBrace +Name ::= Identifier +BaseListOpt ::= baselist? + +CBufferKeyword ::= CBuffer +SemanticOpt ::= semantic + +ArrayRankSpecifiers ::= arrayRankSpecifier +Condition ::= expression +CBufferKeyword ::= CBuffer + +CloseParenToken ::= RightParen +ColonColonToken ::= ColonColon +CaseKeyword ::= Case +ColonToken ::= Colon +DotToken ::= Dot +DefaultKeyword ::= Default +EqualsToken ::= Assign +Expr ::= expression +ElseKeyword ::= Else +EndOfDirectiveToken ::= EndOfDirective +HashToken ::= Hash +IfKeyword ::= If +OpenBraceToken ::= LeftBrace +OpenParenToken ::= LeftParen +OpenParenToken ::= LeftParen +PackOffsetRegister ::= Identifier +PackOffsetComponent ::= Identifier +RegisterAllocation ::= registerAllocation? +SemanticOpt ::= semantic? +SemicolonTokenOpt ::= Semi +SemicolonToken ::= Semi +SwitchKeyword ::= Switch + + diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 94c441d587..69245b9811 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -338,215 +338,4 @@ PreprocessorDirectiveName ::= LineComment ::= '//' (SCharSequence - [\r\n]) -BlockComment ::= '/*' SCharSequence '*/' - - - -BaseTypes ::= Float4 - -Others ::= - AppendStructuredBuffer - | Bool - | Bool1 - | Bool2 - | Bool3 - | Bool4 - | Bool1x1 - | Bool1x2 - | Bool1x3 - | Bool1x4 - | Bool2x1 - | Bool2x2 - | Bool2x3 - | Bool2x4 - | Bool3x1 - | Bool3x2 - | Bool3x3 - | Bool3x4 - | Bool4x1 - | Bool4x2 - | Bool4x3 - | Bool4x4 - | Buffer - | ByteAddressBuffer - | ConsumeStructuredBuffer - | Double - | Double1 - | Double2 - | Double3 - | Double4 - | Double1x1 - | Double1x2 - | Double1x3 - | Double1x4 - | Double2x1 - | Double2x2 - | Double2x3 - | Double2x4 - | Double3x1 - | Double3x2 - | Double3x3 - | Double3x4 - | Double4x1 - | Double4x2 - | Double4x3 - | Double4x4 - | Float - | Float1 - | Float2 - | Float3 - | Float4 - | Float1x1 - | Float1x2 - | Float1x3 - | Float1x4 - | Float2x1 - | Float2x2 - | Float2x3 - | Float2x4 - | Float3x1 - | Float3x2 - | Float3x3 - | Float3x4 - | Float4x1 - | Float4x2 - | Float4x3 - | Float4x4 - | Half - | Half1 - | Half2 - | Half3 - | Half4 - | Half1x1 - | Half1x2 - | Half1x3 - | Half1x4 - | Half2x1 - | Half2x2 - | Half2x3 - | Half2x4 - | Half3x1 - | Half3x2 - | Half3x3 - | Half3x4 - | Half4x1 - | Half4x2 - | Half4x3 - | Half4x4 - | InputPatch - | Int - | Int1 - | Int2 - | Int3 - | Int4 - | Int1x1 - | Int1x2 - | Int1x3 - | Int1x4 - | Int2x1 - | Int2x2 - | Int2x3 - | Int2x4 - | Int3x1 - | Int3x2 - | Int3x3 - | Int3x4 - | Int4x1 - | Int4x2 - | Int4x3 - | Int4x4 - | Line_ - | LineAdj - | Linear - | LineStream - | Long - | Matrix - | Nointerpolation - | Noperspective - | OutputPatch - | Packoffset - | Point - | PointStream - | Register - | RowMajor - | RWBuffer - | RWByteAddressBuffer - | RWStructuredBuffer - | Sample - | Sampler - | SamplerComparisonState - | SamplerState - | StructuredBuffer - | Texture1D - | Texture1DArray - | Texture2D - | Texture2DArray - | Texture2DMS - | Texture2DMSArray - | Texture3D - | TextureCube - | TextureCubeArray - | Triangle - | TriangleAdj - | TriangleStream - | Uint - | Uint1 - | Uint2 - | Uint3 - | Uint4 - | Uint1x1 - | Uint1x2 - | Uint1x3 - | Uint1x4 - | Uint2x1 - | Uint2x2 - | Uint2x3 - | Uint2x4 - | Uint3x1 - | Uint3x2 - | Uint3x3 - | Uint3x4 - | Uint4x1 - | Uint4x2 - | Uint4x3 - | Uint4x4 - | Vector - | Void - - - -CodeFlow ::= - For - | While - | Break - | Case - | CBuffer - | Centroid - | Class - | Interface - | Struct - | ColumnMajor - | Continue - | Default - | Discard - | Do - | Switch - | If - | Return - - - -StorageClass ::= - Volatile - | Extern - | Else - | Groupshared - | In - | Inout - | Out - | Uniform - | Const - | Precise - | Static - | Shared - +BlockComment ::= '/*' SCharSequence '*/' \ No newline at end of file diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 8306e85f1b..97d471e420 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -13,5 +13,14 @@ public static Grammar Token() { return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.SDSLTokens),"BaseTypes"); } + public static Grammar HlslGrammar() + { + var s = new StringBuilder(); + s + .Append(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) + .Append(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); + + return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),"identifierOrKeyword"); + } } \ No newline at end of file From cbf1574fc10ca0ea0f550a1de374adb75ce01d9f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 25 Apr 2022 12:54:23 +0200 Subject: [PATCH 0018/1182] Simplified Grammar --- src/SDSLParser/Program.cs | 2 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 137 +---------------- src/Stride.Shader.Parser/SDSLTokens.ebnf | 187 +++++++---------------- 3 files changed, 60 insertions(+), 266 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index cfa6ff2b7f..0acc7604ca 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -12,7 +12,7 @@ // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = tokens.Match("float4"); +var match = tokens.Match("float4x3"); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 7727bcb1ee..ac15dcc3a1 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -600,27 +600,6 @@ FloatVector ::= Float1 | Float2 | Float3 | Float4 identifierOrKeyword ::= AppendStructuredBuffer - | Bool - | Bool1 - | Bool2 - | Bool3 - | Bool4 - | Bool1x1 - | Bool1x2 - | Bool1x3 - | Bool1x4 - | Bool2x1 - | Bool2x2 - | Bool2x3 - | Bool2x4 - | Bool3x1 - | Bool3x2 - | Bool3x3 - | Bool3x4 - | Bool4x1 - | Bool4x2 - | Bool4x3 - | Bool4x4 | Buffer | ByteAddressBuffer | Break @@ -635,98 +614,14 @@ identifierOrKeyword ::= | Default | Discard | Do - | Double - | Double1 - | Double2 - | Double3 - | Double4 - | Double1x1 - | Double1x2 - | Double1x3 - | Double1x4 - | Double2x1 - | Double2x2 - | Double2x3 - | Double2x4 - | Double3x1 - | Double3x2 - | Double3x3 - | Double3x4 - | Double4x1 - | Double4x2 - | Double4x3 - | Double4x4 | Else | Extern - | Float - FloatVector - | Float1 - | Float2 - | Float3 - | Float4 - | Float1x1 - | Float1x2 - | Float1x3 - | Float1x4 - | Float2x1 - | Float2x2 - | Float2x3 - | Float2x4 - | Float3x1 - | Float3x2 - | Float3x3 - | Float3x4 - | Float4x1 - | Float4x2 - | Float4x3 - | Float4x4 | For | Groupshared - | Half - | Half1 - | Half2 - | Half3 - | Half4 - | Half1x1 - | Half1x2 - | Half1x3 - | Half1x4 - | Half2x1 - | Half2x2 - | Half2x3 - | Half2x4 - | Half3x1 - | Half3x2 - | Half3x3 - | Half3x4 - | Half4x1 - | Half4x2 - | Half4x3 - | Half4x4 | If | In | Inout | InputPatch - | Int - | Int1 - | Int2 - | Int3 - | Int4 - | Int1x1 - | Int1x2 - | Int1x3 - | Int1x4 - | Int2x1 - | Int2x2 - | Int2x3 - | Int2x4 - | Int3x1 - | Int3x2 - | Int3x3 - | Int3x4 - | Int4x1 - | Int4x2 - | Int4x3 - | Int4x4 | Interface | Line_ | LineAdj @@ -756,40 +651,12 @@ identifierOrKeyword ::= | Struct | StructuredBuffer | Switch - | Texture1D - | Texture1DArray - | Texture2D - | Texture2DArray - | Texture2DMS - | Texture2DMSArray - | Texture3D - | TextureCube - | TextureCubeArray + | TextureTypes | Triangle | TriangleAdj | TriangleStream | Uniform - | Uint - | Uint1 - | Uint2 - | Uint3 - | Uint4 - | Uint1x1 - | Uint1x2 - | Uint1x3 - | Uint1x4 - | Uint2x1 - | Uint2x2 - | Uint2x3 - | Uint2x4 - | Uint3x1 - | Uint3x2 - | Uint3x3 - | Uint3x4 - | Uint4x1 - | Uint4x2 - | Uint4x3 - | Uint4x4 + | ValueTypes | Vector | Volatile | Void diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 69245b9811..a2dfe6240e 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -1,25 +1,7 @@ AppendStructuredBuffer ::= 'AppendStructuredBuffer' Bool ::= 'bool' -Bool1 ::= 'bool1' -Bool2 ::= 'bool2' -Bool3 ::= 'bool3' -Bool4 ::= 'bool4' -Bool1x1 ::= 'bool1x1' -Bool1x2 ::= 'bool1x2' -Bool1x3 ::= 'bool1x3' -Bool1x4 ::= 'bool1x4' -Bool2x1 ::= 'bool2x1' -Bool2x2 ::= 'bool2x2' -Bool2x3 ::= 'bool2x3' -Bool2x4 ::= 'bool2x4' -Bool3x1 ::= 'bool3x1' -Bool3x2 ::= 'bool3x2' -Bool3x3 ::= 'bool3x3' -Bool3x4 ::= 'bool3x4' -Bool4x1 ::= 'bool4x1' -Bool4x2 ::= 'bool4x2' -Bool4x3 ::= 'bool4x3' -Bool4x4 ::= 'bool4x4' +BoolVec ::= Bool [1-4] +BoolMat ::= BoolVec 'x' [1-4] Buffer ::= 'Buffer' ByteAddressBuffer ::= 'ByteAddressBuffer' Break ::= 'break' @@ -35,97 +17,25 @@ Default ::= 'default' Discard ::= 'discard' Do ::= 'do' Double ::= 'double' -Double1 ::= 'double1' -Double2 ::= 'double2' -Double3 ::= 'double3' -Double4 ::= 'double4' -Double1x1 ::= 'double1x1' -Double1x2 ::= 'double1x2' -Double1x3 ::= 'double1x3' -Double1x4 ::= 'double1x4' -Double2x1 ::= 'double2x1' -Double2x2 ::= 'double2x2' -Double2x3 ::= 'double2x3' -Double2x4 ::= 'double2x4' -Double3x1 ::= 'double3x1' -Double3x2 ::= 'double3x2' -Double3x3 ::= 'double3x3' -Double3x4 ::= 'double3x4' -Double4x1 ::= 'double4x1' -Double4x2 ::= 'double4x2' -Double4x3 ::= 'double4x3' -Double4x4 ::= 'double4x4' +DoubleVec ::= Double [1-4] +DoubleMat ::= DoubleVec 'x' [1-4] Else ::= 'else' Extern ::= 'extern' Float ::= 'float' -Float1 ::= 'float1' -Float2 ::= 'float2' -Float3 ::= 'float3' -Float4 ::= 'float4' -Float1x1 ::= 'float1x1' -Float1x2 ::= 'float1x2' -Float1x3 ::= 'float1x3' -Float1x4 ::= 'float1x4' -Float2x1 ::= 'float2x1' -Float2x2 ::= 'float2x2' -Float2x3 ::= 'float2x3' -Float2x4 ::= 'float2x4' -Float3x1 ::= 'float3x1' -Float3x2 ::= 'float3x2' -Float3x3 ::= 'float3x3' -Float3x4 ::= 'float3x4' -Float4x1 ::= 'float4x1' -Float4x2 ::= 'float4x2' -Float4x3 ::= 'float4x3' -Float4x4 ::= 'float4x4' +FloatVec ::= Float [1-4] +FloatMat ::= FloatVec 'x' [1-4] For ::= 'for' Groupshared ::= 'groupshared' Half ::= 'half' -Half1 ::= 'half1' -Half2 ::= 'half2' -Half3 ::= 'half3' -Half4 ::= 'half4' -Half1x1 ::= 'half1x1' -Half1x2 ::= 'half1x2' -Half1x3 ::= 'half1x3' -Half1x4 ::= 'half1x4' -Half2x1 ::= 'half2x1' -Half2x2 ::= 'half2x2' -Half2x3 ::= 'half2x3' -Half2x4 ::= 'half2x4' -Half3x1 ::= 'half3x1' -Half3x2 ::= 'half3x2' -Half3x3 ::= 'half3x3' -Half3x4 ::= 'half3x4' -Half4x1 ::= 'half4x1' -Half4x2 ::= 'half4x2' -Half4x3 ::= 'half4x3' -Half4x4 ::= 'half4x4' +HalfVec ::= Half [1-4] +HalfMat ::= HalfVec 'x' [1-4] If ::= 'if' In ::= 'in' Inout ::= 'inout' | 'in out' InputPatch ::= 'InputPatch' Int ::= 'int' -Int1 ::= 'int1' -Int2 ::= 'int2' -Int3 ::= 'int3' -Int4 ::= 'int4' -Int1x1 ::= 'int1x1' -Int1x2 ::= 'int1x2' -Int1x3 ::= 'int1x3' -Int1x4 ::= 'int1x4' -Int2x1 ::= 'int2x1' -Int2x2 ::= 'int2x2' -Int2x3 ::= 'int2x3' -Int2x4 ::= 'int2x4' -Int3x1 ::= 'int3x1' -Int3x2 ::= 'int3x2' -Int3x3 ::= 'int3x3' -Int3x4 ::= 'int3x4' -Int4x1 ::= 'int4x1' -Int4x2 ::= 'int4x2' -Int4x3 ::= 'int4x3' -Int4x4 ::= 'int4x4' +IntVec ::= Int [1-4] +IntMat ::= IntVec 'x' [1-4] Interface ::= 'interface' Line_ ::= 'line' LineAdj ::= 'lineadj' @@ -156,40 +66,18 @@ Static ::= 'static' Struct ::= 'struct' StructuredBuffer ::= 'StructuredBuffer' Switch ::= 'switch' -Texture1D ::= 'Texture1D' -Texture1DArray ::= 'Texture1DArray' -Texture2D ::= 'Texture2D' -Texture2DArray ::= 'Texture2DArray' -Texture2DMS ::= 'Texture2DMS' -Texture2DMSArray ::= 'Texture2DMSArray' -Texture3D ::= 'Texture3D' -TextureCube ::= 'TextureCube' -TextureCubeArray ::= 'TextureCubeArray' +TextureTypes ::= + ('Texture' ([1-3] 'D') ('Array'?)) + | ('Texture2DMS' 'Array'?) + | ('TextureCube' 'Array'?) + Triangle ::= 'triangle' TriangleAdj ::= 'triangleadj' TriangleStream ::= 'TriangleStream' Uniform ::= 'uniform' Uint ::= 'uint' | 'unsigned int' | 'dword' -Uint1 ::= 'uint1' -Uint2 ::= 'uint2' -Uint3 ::= 'uint3' -Uint4 ::= 'uint4' -Uint1x1 ::= 'uint1x1' -Uint1x2 ::= 'uint1x2' -Uint1x3 ::= 'uint1x3' -Uint1x4 ::= 'uint1x4' -Uint2x1 ::= 'uint2x1' -Uint2x2 ::= 'uint2x2' -Uint2x3 ::= 'uint2x3' -Uint2x4 ::= 'uint2x4' -Uint3x1 ::= 'uint3x1' -Uint3x2 ::= 'uint3x2' -Uint3x3 ::= 'uint3x3' -Uint3x4 ::= 'uint3x4' -Uint4x1 ::= 'uint4x1' -Uint4x2 ::= 'uint4x2' -Uint4x3 ::= 'uint4x3' -Uint4x4 ::= 'uint4x4' +UintVec ::= Uint [1-4] +UintMat ::= UintVec 'x' [1-4] Vector ::= 'vector' Volatile ::= 'volatile' Void ::= 'void' @@ -338,4 +226,43 @@ PreprocessorDirectiveName ::= LineComment ::= '//' (SCharSequence - [\r\n]) -BlockComment ::= '/*' SCharSequence '*/' \ No newline at end of file +BlockComment ::= '/*' SCharSequence '*/' + + +BoolTypes ::= + Bool - BoolVec + | BoolVec - BoolMat + | BoolMat + +HalfTypes ::= + Half - HalfVec + | HalfVec - HalfMat + | HalfMat + +FloatTypes ::= + Float - FloatVec + | FloatVec - FloatMat + | FloatMat + +DoubleTypes ::= + Double - DoubleVec + | DoubleVec - DoubleMat + | DoubleMat + +IntTypes ::= + Int - IntVec + | IntVec - IntMat + | IntMat + +UintTypes ::= + Uint - UintVec + | UintVec - UintMat + | UintMat + +ValueTypes ::= + BoolTypes + | HalfTypes + | FloatTypes + | DoubleTypes + | IntTypes + | UintTypes From 56c4982f94238650e6afeaf100bc21af2f0fb508 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 25 Apr 2022 12:56:30 +0200 Subject: [PATCH 0019/1182] Correction Texture2dms --- src/SDSLParser/Program.cs | 2 +- src/Stride.Shader.Parser/SDSLTokens.ebnf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 0acc7604ca..7f8b149e69 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -12,7 +12,7 @@ // var tmp = new Grammar("something", Terminals.Set("a").Not()); var s = new Stopwatch(); s.Start(); -var match = tokens.Match("float4x3"); +var match = tokens.Match("Texture2DMS"); // var res = SDSLPParser.Parse("My_Var"); s.Stop(); diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index a2dfe6240e..2a497aec1d 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -67,7 +67,7 @@ Struct ::= 'struct' StructuredBuffer ::= 'StructuredBuffer' Switch ::= 'switch' TextureTypes ::= - ('Texture' ([1-3] 'D') ('Array'?)) + (('Texture' - 'Texture2DMS') ([1-3] 'D') ('Array'?)) | ('Texture2DMS' 'Array'?) | ('TextureCube' 'Array'?) From 1d4e85f14b5dd522b1714a62d15c6a61876faa7d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 25 Apr 2022 13:05:22 +0200 Subject: [PATCH 0020/1182] Reorganization --- src/Stride.Shader.Parser/SDSLExpr.ebnf | 2 -- src/Stride.Shader.Parser/SDSLTokens.ebnf | 44 ++++++++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index ac15dcc3a1..10144d05ad 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -596,8 +596,6 @@ directiveExpression::= literal | directiveExpression binaryOperator directiveExpression -FloatVector ::= Float1 | Float2 | Float3 | Float4 - identifierOrKeyword ::= AppendStructuredBuffer | Buffer diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 2a497aec1d..fb7ebf4ed6 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -90,13 +90,9 @@ RightBracket ::= ']' LeftBrace ::= '{' RightBrace ::= '}' -Less ::= '<' -LessEqual ::= '<=' -Greater ::= '>' -GreaterEqual ::= '>=' + LeftShift ::= '<<' RightShift ::= '>>' - Plus ::= '+' PlusPlus ::= '++' Minus ::= '-' @@ -105,6 +101,20 @@ Star ::= '*' Div ::= '/' Mod ::= '%' + +IncOperators ::= + PlusPlus + | MinusMinus + +Operators ::= + Plus + | Minus + | Star + | Div + | Mod + | LeftShift + | RightShift + And ::= '&' Or ::= '|' AndAnd ::= '&&' @@ -113,6 +123,14 @@ Caret ::= '^' Not ::= '!' Tilde ::= '~' +Equal ::= '==' +NotEqual ::= '!=' + +Less ::= '<' +LessEqual ::= '<=' +Greater ::= '>' +GreaterEqual ::= '>=' + Question ::= '?' Colon ::= ':' ColonColon ::= '::' @@ -131,8 +149,20 @@ AndAssign ::= '&=' XorAssign ::= '^=' OrAssign ::= '|=' -Equal ::= '==' -NotEqual ::= '!=' +AssignOperators ::= + Assign + | StarAssign + | DivAssign + | ModAssign + | PlusAssign + | MinusAssign + | LeftShiftAssign + | RightShiftAssign + | AndAssign + | XorAssign + | OrAssign + + Dot ::= '.' From d59aca677b3dd2bd550d77363ba3ede234901d3c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 25 Apr 2022 18:33:51 +0200 Subject: [PATCH 0021/1182] Correction Operations --- src/SDSLParser/Program.cs | 6 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 667 ++++++++++------------ src/Stride.Shader.Parser/SDSLTokens.ebnf | 8 +- src/Stride.Shader.Parser/StrideGrammar.cs | 9 + 4 files changed, 311 insertions(+), 379 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 7f8b149e69..5378a81e74 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -8,12 +8,10 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New(); -var tokens = StrideGrammar.HlslGrammar(); -// var tmp = new Grammar("something", Terminals.Set("a").Not()); +var tokens = StrideGrammar.HlslGrammar("directiveExpression"); var s = new Stopwatch(); s.Start(); -var match = tokens.Match("Texture2DMS"); -// var res = SDSLPParser.Parse("My_Var"); +var match = tokens.Match("(++(value))+b"); s.Stop(); Console.WriteLine(match.ErrorMessage); diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 10144d05ad..5e41dc7151 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -1,10 +1,8 @@ +compilationUnit ::= topLevelDeclaration* EOF -EndOfFileToken ::= EOF -compilationUnit::= topLevelDeclaration* EndOfFileToken - - -topLevelDeclaration::= classDefinition +topLevelDeclaration ::= + classDefinition | interfaceDefinition | variableDeclarationStatement | structDefinition @@ -12,185 +10,192 @@ topLevelDeclaration::= classDefinition | functionDefinition | functionDeclaration -classDefinition::= ClassKeyword Name BaseListOpt? - OpenBraceToken classMemberDeclaration* CloseBraceToken - SemicolonToken -BaseType ::= Identifier -baseList::= ColonToken BaseType +classDefinition ::= Class Identifier baseList? + LeftBrace classMemberDeclaration* RightBrace + Semi + +baseList ::= Colon Identifier -classMemberDeclaration::= variableDeclarationStatement + +classMemberDeclaration ::= + variableDeclarationStatement | functionDefinition | functionDeclaration -constantBuffer::= CBufferKeyword Name registerAllocation? - OpenBraceToken (variableDeclarationStatement)+ CloseBraceToken - SemicolonToken? +constantBuffer ::= CBuffer Identifier registerAllocation? + LeftBrace (variableDeclarationStatement)+ RightBrace + Semi? +variableDeclarationStatement ::= variableDeclaration Semi -variableDeclarationStatement ::= variableDeclaration SemicolonToken +functionDefinition ::= attribute* functionType (Identifier ColonColon)? Identifier + LeftParen functionParams? RightParen + semantic? block Semi? +functionDeclaration ::= attribute* functionType Identifier + LeftParen functionParams? RightParen + semantic? Semi -functionDefinition::= attribute* functionType (ClassName ColonColonToken)? Name - OpenParenToken functionParams? CloseParenToken - SemanticOpt block SemicolonTokenOpt? +functionType ::= + type + | Void -functionDeclaration::= attribute* functionType Name - OpenParenToken functionParams? CloseParenToken - SemanticOpt SemicolonToken +functionParams ::= functionParam (Comma functionParam)* -functionType::= type - | Void +functionParam ::= storageFlags type variableDeclarator -functionParams::= functionParam (Comma functionParam)* +interfaceDefinition ::= Interface Identifier + LeftBrace functionDeclaration* RightBrace + Semi -functionParam::= storageFlags type variableDeclarator -InterfaceKeyword ::= Interface +structDefinition ::= Struct Identifier + LeftBrace (variableDeclarationStatement)+ RightBrace + Semi -interfaceDefinition::= InterfaceKeyword Name - OpenBraceToken functionDeclaration* CloseBraceToken - SemicolonToken -StructKeyword ::= Struct +semantic ::= Colon Identifier -structDefinition::= StructKeyword Name - OpenBraceToken (variableDeclarationStatement)+ CloseBraceToken - SemicolonToken -semantic::= ColonToken Name +attributeArguments ::= literalExpr (Comma literalExpr)* +attributeArgumentList ::= LeftParen attributeArguments RightParen -attributeArguments::= literalExpr (Comma literalExpr)* +attribute ::= LeftBracket Identifier attributeArgumentList? RightBracket -attributeArgumentList::= OpenParenToken attributeArguments CloseParenToken -OpenBracketToken ::= LeftBracket -CloseBracketToken ::= RightBracket -attribute::= OpenBracketToken Name attributeArgumentList? CloseBracketToken +block ::= LeftBrace statement* RightBrace -block::= LeftBrace statement* RightBrace +indentedEmbeddedStatement ::= embeddedStatement | LeftBrace block -Stmt ::= block -indentedEmbeddedStatement::= - embeddedStatement - | LeftBrace Stmt - -statement::= localDeclarationStatement +statement ::= + localDeclarationStatement | embeddedStatement | classDefinition | interfaceDefinition | structDefinition -localDeclarationStatement::= variableDeclaration SemicolonToken +localDeclarationStatement ::= variableDeclaration Semi -forInitializer::= - variableDeclaration +forInitializer ::= variableDeclaration | expression (Comma expression)* -forIncrementors::= expression (Comma expression)* - - +forIncrementors ::= expression (Comma expression)* -switchLabel::= CaseKeyword Expr ColonToken - | DefaultKeyword ColonToken +switchLabel ::= Case expression Colon + | Default Colon -switchSection::= switchLabel+ statement+ +switchSection ::= switchLabel+ statement+ -IfKeyword ::= If -embeddedStatement::= SemicolonToken - | block - | Expr SemicolonToken +embeddedStatement ::= Semi + | block + | expression Semi - | attribute* IfKeyword OpenParenToken expression CloseParenToken indentedEmbeddedStatement elseClause? - | attribute* SwitchKeyword OpenParenToken Expr CloseParenToken OpenBraceToken switchSection* CloseBraceToken + | attribute* If LeftParen expression RightParen indentedEmbeddedStatement elseClause? + | attribute* Switch LeftParen expression RightParen LeftBrace switchSection* RightBrace - | attribute* While OpenParenToken expression CloseParenToken indentedEmbeddedStatement - | attribute* Do indentedEmbeddedStatement While OpenParenToken expression CloseParenToken SemicolonToken - | attribute* For OpenParenToken forInitializer? FirstSemicolonToken expression? SecondSemicolonToken forIncrementors? CloseParenToken indentedEmbeddedStatement + | attribute* While LeftParen expression RightParen indentedEmbeddedStatement + | attribute* Do indentedEmbeddedStatement While LeftParen expression RightParen Semi + | attribute* For LeftParen forInitializer? Semi expression? Semi forIncrementors? RightParen indentedEmbeddedStatement - | Break SemicolonToken - | Continue SemicolonToken - | Discard SemicolonToken - | Return Expr? SemicolonToken + | Break Semi + | Continue Semi + | Discard Semi + | Return expression? Semi -elseClause::= ElseKeyword indentedEmbeddedStatement +elseClause ::= Else indentedEmbeddedStatement -expression::= literalExpr +expression ::= + literalExpr | Identifier - | OpenParenToken expression CloseParenToken - | OpenParenToken type (arrayRankSpecifier)* CloseParenToken Expr - | Expr DotToken Identifier + | LeftParen expression RightParen + | LeftParen type (arrayRankSpecifier)* RightParen expression + | expression Dot Identifier | scalarOrVectorOrMatrixType argumentList - | Expr argumentList - | Expr LeftBracket expression RightBracket - | Expr postfixUnaryOperator - | prefixUnaryOperator Expr + | expression argumentList + | expression LeftBracket expression RightBracket + | expression postfixUnaryOperator + | prefixUnaryOperator expression | expression binaryOperator expression - | expression Question TrueExpr ColonToken FalseExpr + | expression Question expression Colon expression | right expression assignmentOperator expression -literalExpr::= literal +literalExpr ::= + + literal -postfixUnaryOperator::= PlusPlus +postfixUnaryOperator ::= + PlusPlus | MinusMinus -prefixUnaryOperator::= Plus - | Minus +prefixUnaryOperator ::= + Plus - PlusPlus + | Minus - MinusMinus | Not | Tilde | PlusPlus | MinusMinus -binaryOperator::= Star - | Div - | Mod - | Plus - | Minus - | LeftShift - | RightShift - | Less - | Greater - | LessEqual - | GreaterEqual - | Equal - | NotEqual - | And - | Caret - | Or - | AndAnd - | OrOr - - -assignmentOperator::= Assign +binaryOperator ::= + calcOperators + | testOperators + +testOperators ::= + Less - LessEqual + | Greater - GreaterEqual + | LessEqual + | GreaterEqual + | Equal + | NotEqual + | And - AndAnd + | Caret + | Or - OrOr + | AndAnd + | OrOr + +calcOperators ::= + Star + | Div + | Mod + | Plus + | Minus + | LeftShift + | RightShift + + + + +assignmentOperator ::= + Assign | StarAssign | DivAssign | ModAssign @@ -203,73 +208,78 @@ assignmentOperator::= Assign | OrAssign -argumentList::= OpenParenToken arguments? CloseParenToken +argumentList ::= LeftParen arguments? RightParen -arguments::= expression (Comma expression)* +arguments ::= expression (Comma expression)* -variableDeclaration::= storageFlags type variableDeclarators -variableDeclarators::= variableDeclarator (Comma variableDeclarator)* +variableDeclaration ::= storageFlags type variableDeclarators +variableDeclarators ::= variableDeclarator (Comma variableDeclarator)* -variableDeclarator::= - Name - | (ArrayRankSpecifiers)* - | packOffsetNode? - | RegisterAllocation - | SemanticOpt - | variableInitializer? +variableDeclarator ::= + + Identifier + (arrayRankSpecifier)* + packOffsetNode? + registerAllocation? + semantic? + variableInitializer? -arrayRankSpecifier::= OpenBracketToken expression? CloseBracketToken +arrayRankSpecifier ::= LeftBracket expression? RightBracket -packOffsetNode::= ColonToken Packoffset OpenParenToken - PackOffsetRegister (DotToken PackOffsetComponent)? - CloseParenToken +packOffsetNode ::= Colon Packoffset LeftParen + Identifier (Dot Identifier)? + RightParen -storageFlags::= storageFlag* +storageFlags ::= + storageFlag* -storageFlag +storageFlag ::= - | RowMajor + Constant + | RowMajor | ColumnMajor - - | Extern + | Extern | Precise | Shared | Groupshared | Static | Uniform | Volatile - | Linear + | Linear | Centroid | Nointerpolation | Noperspective | Sample - | In + | In | Out | Inout - | Point + | Point | Line_ | Triangle | LineAdj | TriangleAdj -type::= predefinedType +type ::= + predefinedType | userDefinedType -predefinedType::= bufferPredefinedType +predefinedType ::= + + bufferPredefinedType | byteAddressBufferPredefinedType | inlineStructPredefinedType | patchPredefinedType @@ -286,40 +296,54 @@ predefinedType::= bufferPredefinedType | genericVectorType -bufferPredefinedType::= bufferType Less scalarOrVectorType Greater +bufferPredefinedType ::= bufferType Less scalarOrVectorType Greater -bufferType::= Buffer +bufferType ::= + + Buffer | RWBuffer -byteAddressBufferPredefinedType::= byteAddressBufferType +byteAddressBufferPredefinedType ::= + + byteAddressBufferType -byteAddressBufferType::= ByteAddressBuffer +byteAddressBufferType ::= + + ByteAddressBuffer | RWByteAddressBuffer -inlineStructPredefinedType::= Struct OpenBraceToken +inlineStructPredefinedType ::= + Struct LeftBrace (variableDeclarationStatement)+ - CloseBraceToken + RightBrace -patchPredefinedType::= patchType Less +patchPredefinedType ::= + patchType Less userDefinedType Comma IntegerLiteral Greater -patchType::= InputPatch +patchType ::= + + InputPatch | OutputPatch -samplerStatePredefinedType::= Sampler +samplerStatePredefinedType ::= + + Sampler | SamplerState | SamplerComparisonState -scalarType::= Bool +scalarType ::= + + Bool | Int | Unsigned Int | Dword @@ -329,218 +353,116 @@ scalarType::= Bool | Double -streamOutputPredefinedType::= streamOutputObjectType Less type Greater +streamOutputPredefinedType ::= + streamOutputObjectType Less type Greater -streamOutputObjectType::= PointStream +streamOutputObjectType ::= + PointStream | LineStream | TriangleStream -structuredBufferPredefinedType::= structuredBufferName Less scalarOrVectorOrUserDefinedType Greater +structuredBufferPredefinedType ::= + structuredBufferName Less scalarOrVectorOrUserDefinedType Greater -structuredBufferName::= AppendStructuredBuffer +structuredBufferName ::= + + AppendStructuredBuffer | ConsumeStructuredBuffer | RWStructuredBuffer | StructuredBuffer -textureType::= Texture1D - | Texture1DArray - | Texture2D - | Texture2DArray - | Texture3D - | TextureCube - | TextureCubeArray +textureType ::= + TextureTypes -texturePredefinedType::= textureType +texturePredefinedType ::= + textureType -genericTexturePredefinedType::= textureType Less scalarOrVectorType Greater +genericTexturePredefinedType ::= textureType Less scalarOrVectorType Greater -textureTypeMS::= Texture2DMS +textureTypeMS ::= Texture2DMS | Texture2DMSArray -msTexturePredefinedType::= textureTypeMS Less scalarOrVectorType Comma IntegerLiteral Greater - - -vectorType::= Vector - | Bool1 - | Bool2 - | Bool3 - | Bool4 - | Int1 - | Int2 - | Int3 - | Int4 - | Uint1 - | Uint2 - | Uint3 - | Uint4 - | Half1 - | Half2 - | Half3 - | Half4 - | Float1 - | Float2 - | Float3 - | Float4 - | Double1 - | Double2 - | Double3 - | Double4 - - -genericVectorType::= - Vector Less scalarType Comma IntegerLiteral Greater - - -scalarOrVectorType::= scalarType +msTexturePredefinedType ::= textureTypeMS Less scalarOrVectorType Comma IntegerLiteral Greater + + +vectorType ::= + Vector + | UintVec + | IntVec + | HalfVec + | FloatVec + | DoubleVec + | BoolVec + + +genericVectorType ::= + Vector Less scalarType Comma + IntegerLiteral Greater + + +scalarOrVectorType ::= + scalarType | vectorType -scalarOrVectorOrUserDefinedType::= scalarType +scalarOrVectorOrUserDefinedType ::= + scalarType | vectorType | userDefinedType -scalarOrVectorOrMatrixType::= scalarType +scalarOrVectorOrMatrixType ::= + scalarType | vectorType | matrixType -matrixType::= Matrix - | Bool1x1 - | Bool1x2 - | Bool1x3 - | Bool1x4 - | Bool2x1 - | Bool2x2 - | Bool2x3 - | Bool2x4 - | Bool3x1 - | Bool3x2 - | Bool3x3 - | Bool3x4 - | Bool4x1 - | Bool4x2 - | Bool4x3 - | Bool4x4 - | Int1x1 - | Int1x2 - | Int1x3 - | Int1x4 - | Int2x1 - | Int2x2 - | Int2x3 - | Int2x4 - | Int3x1 - | Int3x2 - | Int3x3 - | Int3x4 - | Int4x1 - | Int4x2 - | Int4x3 - | Int4x4 - | Uint1x1 - | Uint1x2 - | Uint1x3 - | Uint1x4 - | Uint2x1 - | Uint2x2 - | Uint2x3 - | Uint2x4 - | Uint3x1 - | Uint3x2 - | Uint3x3 - | Uint3x4 - | Uint4x1 - | Uint4x2 - | Uint4x3 - | Uint4x4 - | Half1x1 - | Half1x2 - | Half1x3 - | Half1x4 - | Half2x1 - | Half2x2 - | Half2x3 - | Half2x4 - | Half3x1 - | Half3x2 - | Half3x3 - | Half3x4 - | Half4x1 - | Half4x2 - | Half4x3 - | Half4x4 - | Float1x1 - | Float1x2 - | Float1x3 - | Float1x4 - | Float2x1 - | Float2x2 - | Float2x3 - | Float2x4 - | Float3x1 - | Float3x2 - | Float3x3 - | Float3x4 - | Float4x1 - | Float4x2 - | Float4x3 - | Float4x4 - | Double1x1 - | Double1x2 - | Double1x3 - | Double1x4 - | Double2x1 - | Double2x2 - | Double2x3 - | Double2x4 - | Double3x1 - | Double3x2 - | Double3x3 - | Double3x4 - | Double4x1 - | Double4x2 - | Double4x3 - | Double4x4 - - -genericMatrixPredefinedType::= Matrix Less scalarType Comma +matrixType ::= + Matrix + | BoolMat + | UintMat + | IntMat + | HalfMat + | FloatMat + | DoubleMat + + +genericMatrixPredefinedType ::= Matrix Less scalarType Comma IntegerLiteral Comma IntegerLiteral Greater -userDefinedType::= Name +userDefinedType ::= + Identifier -registerAllocation::= Colon Register OpenParenToken Identifier CloseParenToken +registerAllocation ::= Colon Register LeftParen Identifier RightParen -variableInitializer::= - Assign standardVariableInitializer - | OpenBraceToken samplerStateProperty* CloseBraceToken +variableInitializer ::= Assign standardVariableInitializer + | LeftBrace samplerStateProperty* RightBrace -standardVariableInitializer::= - LeftBrace arrayElementInitializers RightBrace - | Expr +standardVariableInitializer ::= LeftBrace arrayElementInitializers RightBrace + | expression -arrayElementInitializers::= standardVariableInitializer (Comma standardVariableInitializer)* Comma? +arrayElementInitializers ::= standardVariableInitializer (Comma standardVariableInitializer)* Comma? -samplerStateProperty::= Name Assign Expr SemicolonToken +samplerStateProperty ::= Identifier Assign expression Semi -literal::= - True +literal ::= + True | False | FloatLiteral | IntegerLiteral @@ -548,7 +470,10 @@ literal::= -directive::= ifDirective + + +directive ::= + ifDirective | ifDefDirective | ifNDefDirective | elseDirective @@ -559,57 +484,96 @@ directive::= ifDirective | lineDirective -ifDirective::= HashToken IfKeyword directiveExpression EndOfDirectiveToken +ifDirective ::= Hash If directiveExpression EndOfDirective + + +ifDefDirective ::= Hash IfDef Identifier EndOfDirective + +ifNDefDirective ::= Hash IfNDef Identifier EndOfDirective -ifDefDirective::= HashToken IfDef Name EndOfDirectiveToken +elseDirective ::= Hash Else EndOfDirective -ifNDefDirective::= HashToken IfNDef Name EndOfDirectiveToken +elifDirective ::= Hash Elif directiveExpression EndOfDirective -elseDirective::= HashToken ElseKeyword EndOfDirectiveToken +endIfDirective ::= Hash EndIf EndOfDirective -elifDirective::= HashToken Elif directiveExpression EndOfDirectiveToken +objectLikeDefineDirective ::= Hash Define identifierOrKeyword (EndOfDirective)* EndOfDirective -endIfDirective::= HashToken EndIf EndOfDirectiveToken +includeDirective ::= Hash Include StringLiteral EndOfDirective -objectLikeDefineDirective::= HashToken Define NameOrKeyword (EndOfDirective)* EndOfDirectiveToken +lineDirective ::= Hash Line_ IntegerLiteral StringLiteral EndOfDirective -includeDirective::= HashToken Include StringLiteral EndOfDirectiveToken +IncrementExpr ::= + literal postfixUnaryOperator + | Identifier postfixUnaryOperator + | ParenExpression postfixUnaryOperator + | prefixUnaryOperator Identifier - postfixUnaryOperator + | prefixUnaryOperator ParenExpression - postfixUnaryOperator -lineDirective::= HashToken Line_ IntegerLiteral StringLiteral EndOfDirectiveToken +OperationExpression ::= directiveExpression binaryOperator directiveExpression -Function ::= Defined +Term ::= + literal + | Identifier - Keywords + | ParenExpression -directiveExpression::= literal - | identifierOrKeyword - | OpenParenToken directiveExpression CloseParenToken - | Function OpenParenToken Identifier CloseParenToken - | directiveExpression postfixUnaryOperator - | prefixUnaryOperator directiveExpression - | directiveExpression binaryOperator directiveExpression +Mul ::= + Term + | Mul Star Term + | Mul Div Term + | Mul Mod Term -identifierOrKeyword ::= +Sum ::= + Mul + | Sum PlusPlus + | Sum Plus Mul + | Sum Plus Mul + +Test ::= + Sum + | sum Less sum + | sum Greater sum + | sum LessEqual sum + | sum GreaterEqual sum + + +directiveExpression ::= + literal - (postfixUnaryOperator | binaryOperator) + | identifierOrKeyword - (postfixUnaryOperator | binaryOperator) + | IncrementExpr + | Test +/* | Identifier LeftParen RightParen*/ + +ParenExpression ::= + LeftParen directiveExpression RightParen + +identifierOrKeyword ::= + Identifier - Keywords + | Keywords + +Keywords ::= AppendStructuredBuffer - | Buffer - | ByteAddressBuffer + | Buffer - ByteAddressBuffer + | ByteAddressBuffer - Break | Break - | Case - | CBuffer - | Centroid - | Class - | ColumnMajor - | Const - | ConsumeStructuredBuffer + | Case - CBuffer + | CBuffer - Centroid + | Centroid - Class + | Class - ColumnMajor + | ColumnMajor - Const + | Const - ConsumeStructuredBuffer + | ConsumeStructuredBuffer - Continue | Continue - | Default + | Default - Discard | Discard | Do | Else @@ -640,7 +604,7 @@ identifierOrKeyword ::= | RWBuffer | RWByteAddressBuffer | RWStructuredBuffer - | Sample + | Sample - Sampler | Sampler | SamplerComparisonState | SamplerState @@ -649,7 +613,7 @@ identifierOrKeyword ::= | Struct | StructuredBuffer | Switch - | TextureTypes + | TextureTypes | Triangle | TriangleAdj | TriangleStream @@ -658,41 +622,4 @@ identifierOrKeyword ::= | Vector | Volatile | Void - | While - | Identifier - -CloseBraceToken ::= RightBrace -Name ::= Identifier -BaseListOpt ::= baselist? - -CBufferKeyword ::= CBuffer -SemanticOpt ::= semantic - -ArrayRankSpecifiers ::= arrayRankSpecifier -Condition ::= expression -CBufferKeyword ::= CBuffer - -CloseParenToken ::= RightParen -ColonColonToken ::= ColonColon -CaseKeyword ::= Case -ColonToken ::= Colon -DotToken ::= Dot -DefaultKeyword ::= Default -EqualsToken ::= Assign -Expr ::= expression -ElseKeyword ::= Else -EndOfDirectiveToken ::= EndOfDirective -HashToken ::= Hash -IfKeyword ::= If -OpenBraceToken ::= LeftBrace -OpenParenToken ::= LeftParen -OpenParenToken ::= LeftParen -PackOffsetRegister ::= Identifier -PackOffsetComponent ::= Identifier -RegisterAllocation ::= registerAllocation? -SemanticOpt ::= semantic? -SemicolonTokenOpt ::= Semi -SemicolonToken ::= Semi -SwitchKeyword ::= Switch - - + | While \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index fb7ebf4ed6..f6dc364275 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -170,7 +170,7 @@ True ::= 'true' False ::= 'false' Identifier ::= - Nondigit (Nondigit | Digit)* + [a-zA-Z_] ([a-zA-Z_] | [0-1])* Nondigit ::= [a-zA-Z_] @@ -194,12 +194,10 @@ IntegerSuffix ::= [uUlL] FloatLiteral ::= FractionalConstant ExponentPart? FloatingSuffix? - | DigitSequence ExponentPart FloatingSuffix? + | DigitSequence ExponentPart FloatingSuffix? FractionalConstant ::= DigitSequence? '.' DigitSequence - | DigitSequence '.' - ExponentPart ::= 'e' Sign? DigitSequence @@ -208,7 +206,7 @@ ExponentPart ::= Sign ::= '+' | '-' -DigitSequence ::= Digit+ +DigitSequence ::= Digit+ HexadecimalDigitSequence ::= HexadecimalDigit+ diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 97d471e420..2113d4f3fb 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -22,5 +22,14 @@ public static Grammar HlslGrammar() return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),"identifierOrKeyword"); } + public static Grammar HlslGrammar(string startParser) + { + var s = new StringBuilder(); + s + .Append(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) + .Append(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); + + return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),startParser); + } } \ No newline at end of file From a1c83df25da94a0d0ad864aa47b7fdf163648aa5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 26 Apr 2022 19:58:04 +0200 Subject: [PATCH 0022/1182] Correction expression order --- src/SDSLParser/Program.cs | 4 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 67 ++++++++++------------- src/Stride.Shader.Parser/SDSLTokens.ebnf | 44 +++++++-------- src/Stride.Shader.Parser/StrideGrammar.cs | 4 ++ src/Stride.Shader.Parser/grammar.ebnf | 4 +- 5 files changed, 55 insertions(+), 68 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 5378a81e74..4d5ae0fe5b 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -7,11 +7,11 @@ var shaderf = File.ReadAllText("./shader.sdsl"); // var parser = new SDSLGrammar(); -var parser = StrideGrammar.New(); +var parser = StrideGrammar.New("sum"); var tokens = StrideGrammar.HlslGrammar("directiveExpression"); var s = new Stopwatch(); s.Start(); -var match = tokens.Match("(++(value))+b"); +var match = tokens.Match("a*b"); s.Stop(); Console.WriteLine(match.ErrorMessage); diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 5e41dc7151..98ee52078b 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -146,9 +146,7 @@ expression ::= | right expression assignmentOperator expression -literalExpr ::= - - literal +literalExpr ::= literal postfixUnaryOperator ::= @@ -214,9 +212,6 @@ argumentList ::= LeftParen arguments? RightParen arguments ::= expression (Comma expression)* - - - variableDeclaration ::= storageFlags type variableDeclarators @@ -461,14 +456,6 @@ arrayElementInitializers ::= standardVariableInitializer (Comma standardVariab samplerStateProperty ::= Identifier Assign expression Semi -literal ::= - True - | False - | FloatLiteral - | IntegerLiteral - | StringLiteral - - @@ -520,37 +507,39 @@ IncrementExpr ::= OperationExpression ::= directiveExpression binaryOperator directiveExpression -Term ::= - literal - | Identifier - Keywords - | ParenExpression +Term ::= Identifier | ParenExpression + /*literal + | (Identifier - Keywords) + | ParenExpression*/ + Mul ::= - Term - | Mul Star Term + Term - (Term [*/%]) + | Term Star Mul + | Term Div Mul + | Term Mod Mul + + /*| Mul Star Term | Mul Div Term - | Mul Mod Term - - -Sum ::= - Mul - | Sum PlusPlus - | Sum Plus Mul - | Sum Plus Mul - -Test ::= - Sum - | sum Less sum - | sum Greater sum - | sum LessEqual sum - | sum GreaterEqual sum + | Mul Mod Term*/ + +Sum ::= + Mul - (Mul [+-]) + | Mul Plus Sum + | Mul Minus Sum + +TestExpression ::= + Sum - (Sum ("<" | ">" | "<=" | ">=")) + | Sum Less TestExpression + | Sum Greater TestExpression + | Sum LessEqual TestExpression + | Sum GreaterEqual TestExpression directiveExpression ::= - literal - (postfixUnaryOperator | binaryOperator) - | identifierOrKeyword - (postfixUnaryOperator | binaryOperator) - | IncrementExpr - | Test + TestExpression +/* | identifierOrKeyword - (postfixUnaryOperator) +/* | IncrementExpr*/ /* | Identifier LeftParen RightParen*/ ParenExpression ::= diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index f6dc364275..76ae36589e 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -93,7 +93,7 @@ RightBrace ::= '}' LeftShift ::= '<<' RightShift ::= '>>' -Plus ::= '+' +Plus ::= [+] PlusPlus ::= '++' Minus ::= '-' MinusMinus ::= '--' @@ -174,46 +174,40 @@ Identifier ::= Nondigit ::= [a-zA-Z_] -Digit ::= [0-9] +Digit1 ::= [1-9] +Digit ::= '0' | Digit1 -NonzeroDigit ::= '0' | Digit +IntegerSuffix ::= [uUlL] -IntegerLiteral ::= - DecimalIntegerLiteral IntegerSuffix? - | HexadecimalIntegerLiteral IntegerSuffix? +HexadecimalDigitSequence ::= HexadecimalDigit+ -DecimalIntegerLiteral ::= Digit+ +DecimalIntegerLiteral ::= "0" | Digit1 Digit* +HexadecimalDigit ::= [0-9a-fA-F] HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ +IntegerLiteral ::= + (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? + | HexadecimalIntegerLiteral IntegerSuffix? -HexadecimalDigit ::= [0-9a-fA-F] - -IntegerSuffix ::= [uUlL] - -FloatLiteral ::= - FractionalConstant ExponentPart? FloatingSuffix? - | DigitSequence ExponentPart FloatingSuffix? +FloatingSuffix ::= "f" FractionalConstant ::= - DigitSequence? '.' DigitSequence + DecimalIntegerLiteral? '.' Digit* ExponentPart ::= - 'e' Sign? DigitSequence - | 'E' Sign? DigitSequence + 'e' Sign? DecimalIntegerLiteral + | 'E' Sign? DecimalIntegerLiteral -Sign ::= '+' | '-' - +FloatLiteral ::= + (DecimalIntegerLiteral - FractionalConstant) ExponentPart? FloatingSuffix? + | FractionalConstant ExponentPart? FloatingSuffix? + -DigitSequence ::= Digit+ - -HexadecimalDigitSequence ::= HexadecimalDigit+ - -FloatingSuffix ::= [flFL] - +Sign ::= '+' | '-' EscapeSequence ::= SimpleEscapeSequence diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 2113d4f3fb..848d750a62 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -9,6 +9,10 @@ public static Grammar New() { return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); } + public static Grammar New(string parser) + { + return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),parser); + } public static Grammar Token() { return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.SDSLTokens),"BaseTypes"); diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf index e2fc7d3b19..81440a655c 100644 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ b/src/Stride.Shader.Parser/grammar.ebnf @@ -74,11 +74,11 @@ assign ::= expr ::= (test - assign) - | (accessor - assign) +/* | (accessor - assign) | (idx_accessor - assign) | assign | (paren_expr - cast) - | cast + | cast*/ paren_expr ::= '(' expr ')' From 0c1e85ce3b2910f5194053231719b4d02680e199 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 28 Apr 2022 13:28:59 +0200 Subject: [PATCH 0023/1182] Parsing directives --- src/SDSLParser/Program.cs | 6 +- src/SDSLParser/SDSL/Directive.sdsl | 2 + src/SDSLParser/SDSL/Expressions.sdsl | 0 src/SDSLParser/SDSL/Methods.sdsl | 0 src/SDSLParser/{ => SDSL}/shader.sdsl | 0 .../GrammarResource.Designer.cs | 10 + src/Stride.Shader.Parser/GrammarResource.resx | 3 + src/Stride.Shader.Parser/Hlsl/code.hlsl | 8 + src/Stride.Shader.Parser/SDSLDirective.ebnf | 89 +++++++ src/Stride.Shader.Parser/SDSLExpr.ebnf | 228 ++++------------- src/Stride.Shader.Parser/SDSLTokens.ebnf | 71 ++++++ src/Stride.Shader.Parser/StrideGrammar.cs | 5 +- src/Stride.Shader.Parser/c.bnf | 231 ------------------ 13 files changed, 242 insertions(+), 411 deletions(-) create mode 100644 src/SDSLParser/SDSL/Directive.sdsl create mode 100644 src/SDSLParser/SDSL/Expressions.sdsl create mode 100644 src/SDSLParser/SDSL/Methods.sdsl rename src/SDSLParser/{ => SDSL}/shader.sdsl (100%) create mode 100644 src/Stride.Shader.Parser/Hlsl/code.hlsl create mode 100644 src/Stride.Shader.Parser/SDSLDirective.ebnf delete mode 100644 src/Stride.Shader.Parser/c.bnf diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 4d5ae0fe5b..3f16ec003e 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,14 +4,14 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./shader.sdsl"); +var shaderf = File.ReadAllText("./SDSL/Directive.sdsl"); // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("sum"); -var tokens = StrideGrammar.HlslGrammar("directiveExpression"); +var tokens = StrideGrammar.HlslGrammar("directives"); var s = new Stopwatch(); s.Start(); -var match = tokens.Match("a*b"); +var match = tokens.Match(shaderf); s.Stop(); Console.WriteLine(match.ErrorMessage); diff --git a/src/SDSLParser/SDSL/Directive.sdsl b/src/SDSLParser/SDSL/Directive.sdsl new file mode 100644 index 0000000000..ce4ac9bbb9 --- /dev/null +++ b/src/SDSLParser/SDSL/Directive.sdsl @@ -0,0 +1,2 @@ +#if Mama == 5 + diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/SDSLParser/SDSL/Methods.sdsl b/src/SDSLParser/SDSL/Methods.sdsl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/SDSLParser/shader.sdsl b/src/SDSLParser/SDSL/shader.sdsl similarity index 100% rename from src/SDSLParser/shader.sdsl rename to src/SDSLParser/SDSL/shader.sdsl diff --git a/src/Stride.Shader.Parser/GrammarResource.Designer.cs b/src/Stride.Shader.Parser/GrammarResource.Designer.cs index 6fdcf2e804..4fa85252f2 100644 --- a/src/Stride.Shader.Parser/GrammarResource.Designer.cs +++ b/src/Stride.Shader.Parser/GrammarResource.Designer.cs @@ -70,6 +70,16 @@ internal static byte[] grammar { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] SDSLDirective { + get { + object obj = ResourceManager.GetObject("SDSLDirective", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/src/Stride.Shader.Parser/GrammarResource.resx b/src/Stride.Shader.Parser/GrammarResource.resx index b18e600cca..6d83d3abad 100644 --- a/src/Stride.Shader.Parser/GrammarResource.resx +++ b/src/Stride.Shader.Parser/GrammarResource.resx @@ -121,6 +121,9 @@ grammar.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + SDSLDirective.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SDSLExpr.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/src/Stride.Shader.Parser/Hlsl/code.hlsl b/src/Stride.Shader.Parser/Hlsl/code.hlsl new file mode 100644 index 0000000000..5fb572a357 --- /dev/null +++ b/src/Stride.Shader.Parser/Hlsl/code.hlsl @@ -0,0 +1,8 @@ +#if + DODO_dodo = toto +#endif + +void main() +{ + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLDirective.ebnf b/src/Stride.Shader.Parser/SDSLDirective.ebnf new file mode 100644 index 0000000000..2d6013cca7 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLDirective.ebnf @@ -0,0 +1,89 @@ + +IncrementDirectiveExpr ::= + literal postfixUnaryOperator + | Identifier postfixUnaryOperator + | ParenDirectiveExpression postfixUnaryOperator + | prefixUnaryOperator Identifier - postfixUnaryOperator + | prefixUnaryOperator ParenDirectiveExpression - postfixUnaryOperator + + +TermDirective ::= + literal + | (Identifier - Keywords) + | ParenDirectiveExpression + + +MulDirective ::= + TermDirective - (TermDirective [ \n]* [*/%]) + | TermDirective [ \n]* Star [ \n]* MulDirective + | TermDirective [ \n]* Div [ \n]* MulDirective + | TermDirective [ \n]* Mod [ \n]* MulDirective + + + +PIncExpression ::= + (Identifier - Keywords) IncOperators + + +SumDirective ::= + MulDirective - (MulDirective [ \n]* [+-]) + | MulDirective [ \n]* Plus [ \n]* SumDirective + | MulDirective [ \n]* Minus [ \n]* SumDirective + + +TestDirective ::= + SumDirective - (SumDirective [ \n]* [<>=!(]) + | SumDirective [ \n]* Less [ \n]* TestDirective + | SumDirective [ \n]* Greater [ \n]* TestDirective + | SumDirective [ \n]* LessEqual [ \n]* TestDirective + | SumDirective [ \n]* GreaterEqual [ \n]* TestDirective + | SumDirective [ \n]* Equal [ \n]* TestDirective + | SumDirective [ \n]* NotEqual [ \n]* TestDirective + +MethodCallDirective ::= + Identifier LeftParen RightParen + +directiveExpression ::= + TestDirective + | IncrementExpr - (MethodCallDirective) + | MethodCallDirective + +ParenDirectiveExpression ::= + LeftParen [ \n]* directiveExpression [ \n]* RightParen + +Hash ::= "#" +HashIf ::= Hash (If - [nd]) +HashIfDef ::= Hash (IfDef - [n]) +HashIfNDef ::= Hash IfNDef +HashElse ::= Hash Else +HashElif ::= Hash Elif +HashEndIf ::= Hash EndIf + +EndOfDirective ::= [ ]* Eol + +directive ::= + ifDirective + | ifDefDirective + | ifNDefDirective + | elseDirective + | elifDirective + +ifDirective ::= HashIf [ ]+ directiveExpression [ ]* Eol + + +ifDefDirective ::= HashIfDef [ ]+ Identifier EndOfDirective + + +ifNDefDirective ::= HashIfNDef [ ]+ Identifier EndOfDirective + + +elseDirective ::= HashElse EndOfDirective + + +elifDirective ::= HashElif [ ]+ directiveExpression EndOfDirective + + +endIfDirective ::= HashEndIf [ ]* Eol + + +/*objectLikeDefineDirective ::= Hash Define identifierOrKeyword (EndOfDirective)* EndOfDirective*/ diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 98ee52078b..308025478c 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -64,7 +64,7 @@ structDefinition ::= Struct Identifier Semi -semantic ::= Colon Identifier +semantic ::= Colon Identifier @@ -129,8 +129,35 @@ embeddedStatement ::= Semi elseClause ::= Else indentedEmbeddedStatement +TermExpression ::= + literal + | (Identifier - Keywords) + | ParenExpression + + +MulExpression ::= + TermExpression - (TermExpression [*/%]) + | TermExpression Star MulExpression + | TermExpression Div MulExpression + | TermExpression Mod MulExpression + +PIncExpression ::= + (Identifier - Keywords) IncOperators + + +SumExpression ::= + MulExpression - (MulExpression [+-]) + | MulExpression Plus SumExpression + | MulExpression Minus SumExpression expression ::= + TestExpression + | LeftParen expression RightParen + | LeftParen type (arrayRankSpecifier)* RightParen expression + | expression Dot Identifier + +ParenExpression ::= LeftParen expression RightParen +/*expression ::= literalExpr | Identifier | LeftParen expression RightParen @@ -145,7 +172,7 @@ expression ::= | expression Question expression Colon expression | right expression assignmentOperator expression - +*/ literalExpr ::= literal @@ -212,26 +239,30 @@ argumentList ::= LeftParen arguments? RightParen arguments ::= expression (Comma expression)* -variableDeclaration ::= storageFlags type variableDeclarators +variableDeclaration ::= storageFlags [ \n]+ type [ \n]+ variableDeclarators -variableDeclarators ::= variableDeclarator (Comma variableDeclarator)* +variableDeclarators ::= variableDeclarator /*(Comma variableDeclarator)**/ variableDeclarator ::= - - Identifier - (arrayRankSpecifier)* - packOffsetNode? - registerAllocation? - semantic? - variableInitializer? + (Identifier) - (Identifier [ \n]* [:]) + | Identifier [ \n]* variableDeclaratorSupplement +variableDeclaratorSupplement ::= + (arrayRankSpecifier)+ + | packOffsetNode + | registerAllocation + | semantic + | variableInitializer -arrayRankSpecifier ::= LeftBracket expression? RightBracket +arrayRankSpecifier ::= + LeftBracket expression? RightBracket -packOffsetNode ::= Colon Packoffset LeftParen +/* ": packoffset(my_var.value) " */ +packOffsetNode ::= + Colon Packoffset LeftParen Identifier (Dot Identifier)? RightParen @@ -363,7 +394,6 @@ structuredBufferPredefinedType ::= structuredBufferName ::= - AppendStructuredBuffer | ConsumeStructuredBuffer | RWStructuredBuffer @@ -378,10 +408,12 @@ texturePredefinedType ::= textureType -genericTexturePredefinedType ::= textureType Less scalarOrVectorType Greater +genericTexturePredefinedType ::= + textureType Less scalarOrVectorType Greater -textureTypeMS ::= Texture2DMS +textureTypeMS ::= + Texture2DMS | Texture2DMSArray @@ -419,7 +451,6 @@ scalarOrVectorOrMatrixType ::= | vectorType | matrixType - matrixType ::= Matrix | BoolMat @@ -429,7 +460,6 @@ matrixType ::= | FloatMat | DoubleMat - genericMatrixPredefinedType ::= Matrix Less scalarType Comma IntegerLiteral Comma IntegerLiteral Greater @@ -442,11 +472,13 @@ userDefinedType ::= registerAllocation ::= Colon Register LeftParen Identifier RightParen -variableInitializer ::= Assign standardVariableInitializer +variableInitializer ::= + Assign standardVariableInitializer | LeftBrace samplerStateProperty* RightBrace -standardVariableInitializer ::= LeftBrace arrayElementInitializers RightBrace +standardVariableInitializer ::= + LeftBrace arrayElementInitializers RightBrace | expression @@ -455,160 +487,6 @@ arrayElementInitializers ::= standardVariableInitializer (Comma standardVariab samplerStateProperty ::= Identifier Assign expression Semi - - - - -directive ::= - ifDirective - | ifDefDirective - | ifNDefDirective - | elseDirective - | elifDirective - | endIfDirective - | objectLikeDefineDirective - | includeDirective - | lineDirective - - -ifDirective ::= Hash If directiveExpression EndOfDirective - - -ifDefDirective ::= Hash IfDef Identifier EndOfDirective - - -ifNDefDirective ::= Hash IfNDef Identifier EndOfDirective - - -elseDirective ::= Hash Else EndOfDirective - - -elifDirective ::= Hash Elif directiveExpression EndOfDirective - - -endIfDirective ::= Hash EndIf EndOfDirective - - -objectLikeDefineDirective ::= Hash Define identifierOrKeyword (EndOfDirective)* EndOfDirective - - -includeDirective ::= Hash Include StringLiteral EndOfDirective - - -lineDirective ::= Hash Line_ IntegerLiteral StringLiteral EndOfDirective - - -IncrementExpr ::= - literal postfixUnaryOperator - | Identifier postfixUnaryOperator - | ParenExpression postfixUnaryOperator - | prefixUnaryOperator Identifier - postfixUnaryOperator - | prefixUnaryOperator ParenExpression - postfixUnaryOperator - -OperationExpression ::= directiveExpression binaryOperator directiveExpression - -Term ::= Identifier | ParenExpression - /*literal - | (Identifier - Keywords) - | ParenExpression*/ - - -Mul ::= - Term - (Term [*/%]) - | Term Star Mul - | Term Div Mul - | Term Mod Mul - - /*| Mul Star Term - | Mul Div Term - | Mul Mod Term*/ - -Sum ::= - Mul - (Mul [+-]) - | Mul Plus Sum - | Mul Minus Sum - -TestExpression ::= - Sum - (Sum ("<" | ">" | "<=" | ">=")) - | Sum Less TestExpression - | Sum Greater TestExpression - | Sum LessEqual TestExpression - | Sum GreaterEqual TestExpression - - -directiveExpression ::= - TestExpression -/* | identifierOrKeyword - (postfixUnaryOperator) -/* | IncrementExpr*/ -/* | Identifier LeftParen RightParen*/ - -ParenExpression ::= - LeftParen directiveExpression RightParen - identifierOrKeyword ::= Identifier - Keywords - | Keywords - -Keywords ::= - AppendStructuredBuffer - | Buffer - ByteAddressBuffer - | ByteAddressBuffer - Break - | Break - | Case - CBuffer - | CBuffer - Centroid - | Centroid - Class - | Class - ColumnMajor - | ColumnMajor - Const - | Const - ConsumeStructuredBuffer - | ConsumeStructuredBuffer - Continue - | Continue - | Default - Discard - | Discard - | Do - | Else - | Extern - | For - | Groupshared - | If - | In - | Inout - | InputPatch - | Interface - | Line_ - | LineAdj - | Linear - | LineStream - | Matrix - | Nointerpolation - | Noperspective - | Out - | OutputPatch - | Packoffset - | Point - | PointStream - | Precise - | Register - | Return - | RowMajor - | RWBuffer - | RWByteAddressBuffer - | RWStructuredBuffer - | Sample - Sampler - | Sampler - | SamplerComparisonState - | SamplerState - | Shared - | Static - | Struct - | StructuredBuffer - | Switch - | TextureTypes - | Triangle - | TriangleAdj - | TriangleStream - | Uniform - | ValueTypes - | Vector - | Volatile - | Void - | While \ No newline at end of file + | Keywords \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 76ae36589e..d3a346dc4e 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -1,3 +1,10 @@ +Eol ::= ?Terminals.Eol? +Eof ::= ?Terminals.End? +WS ::= ?Terminals.WhiteSpace? +Space ::= WS | Eol +SpacesWithLineBreak ::= WS* Eol + + AppendStructuredBuffer ::= 'AppendStructuredBuffer' Bool ::= 'bool' BoolVec ::= Bool [1-4] @@ -288,3 +295,67 @@ ValueTypes ::= | DoubleTypes | IntTypes | UintTypes + +Keywords ::= + AppendStructuredBuffer + | Buffer - ByteAddressBuffer + | ByteAddressBuffer - Break + | Break + | Case - CBuffer + | CBuffer - Centroid + | Centroid - Class + | Class - ColumnMajor + | ColumnMajor - Const + | Const - ConsumeStructuredBuffer + | ConsumeStructuredBuffer - Continue + | Continue + | Default - Discard + | Discard + | Do + | Else + | Extern + | For + | Groupshared + | If + | In + | Inout + | InputPatch + | Interface + | Line_ + | LineAdj + | Linear + | LineStream + | Matrix + | Nointerpolation + | Noperspective + | Out + | OutputPatch + | Packoffset + | Point + | PointStream + | Precise + | Register + | Return + | RowMajor + | RWBuffer + | RWByteAddressBuffer + | RWStructuredBuffer + | Sample - Sampler + | Sampler + | SamplerComparisonState + | SamplerState + | Shared + | Static + | Struct + | StructuredBuffer + | Switch + | TextureTypes + | Triangle + | TriangleAdj + | TriangleStream + | Uniform + | ValueTypes + | Vector + | Volatile + | Void + | While diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs index 848d750a62..487e4459ed 100644 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ b/src/Stride.Shader.Parser/StrideGrammar.cs @@ -30,8 +30,9 @@ public static Grammar HlslGrammar(string startParser) { var s = new StringBuilder(); s - .Append(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) - .Append(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); + .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) + .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLDirective)) + .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),startParser); } diff --git a/src/Stride.Shader.Parser/c.bnf b/src/Stride.Shader.Parser/c.bnf deleted file mode 100644 index 4008ba35f5..0000000000 --- a/src/Stride.Shader.Parser/c.bnf +++ /dev/null @@ -1,231 +0,0 @@ -The syntax of C in Backus-Naur Form - ::= {}* - - ::= - | - - ::= {}* {}* - - ::= - | - | - - ::= auto - | register - | static - | extern - | typedef - - ::= void - | char - | short - | int - | long - | float - | double - | signed - | unsigned - | - | - | - - ::= { {}+ } - | { {}+ } - | - - ::= struct - | union - - ::= {}* - - ::= - | - - ::= - | , - - ::= - | : - | : - - ::= {}? - - ::= * {}* {}? - - ::= const - | volatile - - ::= - | ( ) - | [ {}? ] - | ( ) - | ( {}* ) - - ::= - - ::= - | ? : - - ::= - | || - - ::= - | && - - ::= - | | - - ::= - | ^ - - ::= - | & - - ::= - | == - | != - - ::= - | < - | > - | <= - | >= - - ::= - | << - | >> - - ::= - | + - | - - - ::= - | * - | / - | % - - ::= - | ( ) - - ::= - | ++ - | -- - | - | sizeof - | sizeof - - ::= - | [ ] - | ( {}* ) - | . - | -> - | ++ - | -- - - ::= - | - | - | ( ) - - ::= - | - | - | - - ::= - | , - - ::= - | - - ::= = - | *= - | /= - | %= - | += - | -= - | <<= - | >>= - | &= - | ^= - | |= - - ::= & - | * - | + - | - - | ~ - | ! - - ::= {}+ {}? - - ::= - | , ... - - ::= - | , - - ::= {}+ - | {}+ - | {}+ - - ::= - | - | - - ::= ( ) - | {}? [ {}? ] - | {}? ( {}? ) - - ::= enum { } - | enum { } - | enum - - ::= - | , - - ::= - | = - - ::= - - ::= {}+ {}* ; - - ::= - | = - - ::= - | { } - | { , } - - ::= - | , - - ::= { {}* {}* } - - ::= - | - | - | - | - | - - ::= : - | case : - | default : - - ::= {}? ; - - ::= if ( ) - | if ( ) else - | switch ( ) - - ::= while ( ) - | do while ( ) ; - | for ( {}? ; {}? ; {}? ) - - ::= goto ; - | continue ; - | break ; - | return {}? ; -This grammar was adapted from Section A13 of The C programming language, 2nd edition, by Brian W. Kernighan and Dennis M. Ritchie,Prentice Hall, 1988. \ No newline at end of file From 3e3b92446fa040dcd1792e5e1ae49116f81e5379 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 28 Apr 2022 15:31:40 +0200 Subject: [PATCH 0024/1182] Expression and directive corrections --- src/SDSLParser/Program.cs | 9 ++-- src/SDSLParser/SDSL/Expressions.sdsl | 4 ++ src/Stride.Shader.Parser/SDSLDirective.ebnf | 56 +++++++++++---------- src/Stride.Shader.Parser/SDSLExpr.ebnf | 39 +++++++++----- src/Stride.Shader.Parser/SDSLTokens.ebnf | 40 +++++++++------ 5 files changed, 89 insertions(+), 59 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 3f16ec003e..fe73268145 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,17 +4,18 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/Directive.sdsl"); +var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("sum"); -var tokens = StrideGrammar.HlslGrammar("directives"); +var tokens = StrideGrammar.HlslGrammar("expression"); var s = new Stopwatch(); +var match = tokens.Match("(8)"); s.Start(); -var match = tokens.Match(shaderf); +match = tokens.Match(shaderf); s.Stop(); -Console.WriteLine(match.ErrorMessage); +Console.WriteLine(match.ErrorMessage[..(Math.Min(300,match.ErrorMessage.Length))]); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index e69de29bb2..1acec31f0a 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -0,0 +1,4 @@ +-a + ( + 2 - + myVar.value_init.x +) \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLDirective.ebnf b/src/Stride.Shader.Parser/SDSLDirective.ebnf index 2d6013cca7..0fa16114f3 100644 --- a/src/Stride.Shader.Parser/SDSLDirective.ebnf +++ b/src/Stride.Shader.Parser/SDSLDirective.ebnf @@ -14,10 +14,10 @@ TermDirective ::= MulDirective ::= - TermDirective - (TermDirective [ \n]* [*/%]) - | TermDirective [ \n]* Star [ \n]* MulDirective - | TermDirective [ \n]* Div [ \n]* MulDirective - | TermDirective [ \n]* Mod [ \n]* MulDirective + TermDirective - (TermDirective Spaces [*/%]) + | TermDirective Spaces Star Spaces MulDirective + | TermDirective Spaces Div Spaces MulDirective + | TermDirective Spaces Mod Spaces MulDirective @@ -26,19 +26,19 @@ PIncExpression ::= SumDirective ::= - MulDirective - (MulDirective [ \n]* [+-]) - | MulDirective [ \n]* Plus [ \n]* SumDirective - | MulDirective [ \n]* Minus [ \n]* SumDirective + MulDirective - (MulDirective Spaces [+-]) + | MulDirective Spaces Plus Spaces SumDirective + | MulDirective Spaces Minus Spaces SumDirective TestDirective ::= - SumDirective - (SumDirective [ \n]* [<>=!(]) - | SumDirective [ \n]* Less [ \n]* TestDirective - | SumDirective [ \n]* Greater [ \n]* TestDirective - | SumDirective [ \n]* LessEqual [ \n]* TestDirective - | SumDirective [ \n]* GreaterEqual [ \n]* TestDirective - | SumDirective [ \n]* Equal [ \n]* TestDirective - | SumDirective [ \n]* NotEqual [ \n]* TestDirective + SumDirective - (SumDirective Spaces [<>=!(]) + | SumDirective Spaces Less Spaces TestDirective + | SumDirective Spaces Greater Spaces TestDirective + | SumDirective Spaces LessEqual Spaces TestDirective + | SumDirective Spaces GreaterEqual Spaces TestDirective + | SumDirective Spaces Equal Spaces TestDirective + | SumDirective Spaces NotEqual Spaces TestDirective MethodCallDirective ::= Identifier LeftParen RightParen @@ -49,7 +49,7 @@ directiveExpression ::= | MethodCallDirective ParenDirectiveExpression ::= - LeftParen [ \n]* directiveExpression [ \n]* RightParen + LeftParen Spaces directiveExpression Spaces RightParen Hash ::= "#" HashIf ::= Hash (If - [nd]) @@ -59,31 +59,33 @@ HashElse ::= Hash Else HashElif ::= Hash Elif HashEndIf ::= Hash EndIf -EndOfDirective ::= [ ]* Eol +EndOfDirective ::= WS* (Eol | Eof) directive ::= - ifDirective - | ifDefDirective - | ifNDefDirective - | elseDirective - | elifDirective + ( + ifDirective + | ifDefDirective + | ifNDefDirective + | elseDirective + | elifDirective + ) EndOfDirective -ifDirective ::= HashIf [ ]+ directiveExpression [ ]* Eol +ifDirective ::= HashIf WS+ directiveExpression -ifDefDirective ::= HashIfDef [ ]+ Identifier EndOfDirective +ifDefDirective ::= HashIfDef WS+ Identifier -ifNDefDirective ::= HashIfNDef [ ]+ Identifier EndOfDirective +ifNDefDirective ::= HashIfNDef WS+ Identifier -elseDirective ::= HashElse EndOfDirective +elseDirective ::= HashElse -elifDirective ::= HashElif [ ]+ directiveExpression EndOfDirective +elifDirective ::= HashElif WS+ directiveExpression -endIfDirective ::= HashEndIf [ ]* Eol +endIfDirective ::= HashEndIf /*objectLikeDefineDirective ::= Hash Define identifierOrKeyword (EndOfDirective)* EndOfDirective*/ diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 308025478c..cb895a163c 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -131,32 +131,45 @@ elseClause ::= Else indentedEmbeddedStatement TermExpression ::= literal - | (Identifier - Keywords) + | Sign? (userDefinedNames - (userDefinedNames Dot)) + | Sign? userDefinedNames (Dot userDefinedNames)* | ParenExpression MulExpression ::= - TermExpression - (TermExpression [*/%]) - | TermExpression Star MulExpression - | TermExpression Div MulExpression - | TermExpression Mod MulExpression + TermExpression - (TermExpression Spaces [*/%]) + | TermExpression Spaces Star Spaces MulExpression + | TermExpression Spaces Div Spaces MulExpression + | TermExpression Spaces Mod Spaces MulExpression + + PIncExpression ::= (Identifier - Keywords) IncOperators SumExpression ::= - MulExpression - (MulExpression [+-]) - | MulExpression Plus SumExpression - | MulExpression Minus SumExpression + MulExpression - (MulExpression Spaces [+-]) + | MulExpression Spaces Plus Spaces SumExpression + | MulExpression Spaces Minus Spaces SumExpression + + +TestExpression ::= + SumExpression - (SumExpression Spaces [<>=!(]) + | SumExpression Spaces Less Spaces TestExpression + | SumExpression Spaces Greater Spaces TestExpression + | SumExpression Spaces LessEqual Spaces TestExpression + | SumExpression Spaces GreaterEqual Spaces TestExpression + | SumExpression Spaces Equal Spaces TestExpression + | SumExpression Spaces NotEqual Spaces TestExpression expression ::= TestExpression | LeftParen expression RightParen | LeftParen type (arrayRankSpecifier)* RightParen expression - | expression Dot Identifier + | (Identifier | ParenExpression) Dot Identifier -ParenExpression ::= LeftParen expression RightParen +ParenExpression ::= LeftParen Spaces expression Spaces RightParen /*expression ::= literalExpr | Identifier @@ -246,8 +259,8 @@ variableDeclarators ::= variableDeclarator /*(Comma variableDeclarator)**/ variableDeclarator ::= - (Identifier) - (Identifier [ \n]* [:]) - | Identifier [ \n]* variableDeclaratorSupplement + (Identifier) - (Identifier Spaces [:]) + | Identifier Spaces variableDeclaratorSupplement variableDeclaratorSupplement ::= (arrayRankSpecifier)+ @@ -468,6 +481,8 @@ genericMatrixPredefinedType ::= Matrix Less scalarType Comma userDefinedType ::= Identifier +userDefinedNames ::= + Identifier - Keywords registerAllocation ::= Colon Register LeftParen Identifier RightParen diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index d3a346dc4e..d0122f338b 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -1,7 +1,8 @@ -Eol ::= ?Terminals.Eol? -Eof ::= ?Terminals.End? -WS ::= ?Terminals.WhiteSpace? -Space ::= WS | Eol +WS ::= ? Terminals.Whitespace ? +Eol ::= ? Terminals.Eol ? +Eof ::= ? Terminals.End ? +Space ::= WS | Eol | Eof +Spaces ::= Space* SpacesWithLineBreak ::= WS* Eol @@ -194,9 +195,12 @@ DecimalIntegerLiteral ::= "0" | Digit1 Digit* HexadecimalDigit ::= [0-9a-fA-F] HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ -IntegerLiteral ::= - (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? - | HexadecimalIntegerLiteral IntegerSuffix? +IntegerLiteral ::= + Sign? + ( + (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? + | HexadecimalIntegerLiteral IntegerSuffix? + ) FloatingSuffix ::= "f" @@ -208,10 +212,11 @@ ExponentPart ::= | 'E' Sign? DecimalIntegerLiteral FloatLiteral ::= - (DecimalIntegerLiteral - FractionalConstant) ExponentPart? FloatingSuffix? - | FractionalConstant ExponentPart? FloatingSuffix? - - + Sign? + ( + (DecimalIntegerLiteral - FractionalConstant) ExponentPart? FloatingSuffix? + | FractionalConstant ExponentPart? FloatingSuffix? + ) Sign ::= '+' | '-' @@ -230,10 +235,13 @@ SCharSequence ::= SChar+ SChar ::= (SCharSequence - ["\\\r\n]) | EscapeSequence - -Whitespace ::= [ \t]+ - -Newline ::= ('\r' '\n'? | '\n') + + +literal ::= + IntegerLiteral - FloatLiteral + | FloatLiteral + | StringLiteral + PreprocessorDirective ::= '#' Whitespace? PreprocessorDirectiveName @@ -358,4 +366,4 @@ Keywords ::= | Vector | Volatile | Void - | While + | While \ No newline at end of file From 25aca314ea8a19bd48dcd2a662f9ea7888efca8d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 28 Apr 2022 18:45:19 +0200 Subject: [PATCH 0025/1182] Added method call as expression --- src/SDSLParser/SDSL/Expressions.sdsl | 5 +---- src/Stride.Shader.Parser/SDSLExpr.ebnf | 15 ++++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 1acec31f0a..84e206ec32 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1,4 +1 @@ --a + ( - 2 - - myVar.value_init.x -) \ No newline at end of file +2 * myFunction(1,2,3,4*1+abc) + 3 * 2 \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index cb895a163c..779b356baa 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -128,11 +128,15 @@ embeddedStatement ::= Semi elseClause ::= Else indentedEmbeddedStatement +AccessorChain ::= userDefinedNames (Dot userDefinedNames)* +MethodCall ::= userDefinedNames argumentList TermExpression ::= literal - | Sign? (userDefinedNames - (userDefinedNames Dot)) - | Sign? userDefinedNames (Dot userDefinedNames)* + | Sign? userDefinedNames - (AccessorChain | MethodCall) + | Sign? (AccessorChain - MethodCall) + | Sign? MethodCall + | Sign? scalarOrVectorOrMatrixType argumentList | ParenExpression @@ -167,7 +171,7 @@ expression ::= TestExpression | LeftParen expression RightParen | LeftParen type (arrayRankSpecifier)* RightParen expression - | (Identifier | ParenExpression) Dot Identifier + | (Identifier | ParenExpression) Dot Identifier ParenExpression ::= LeftParen Spaces expression Spaces RightParen /*expression ::= @@ -186,6 +190,7 @@ ParenExpression ::= LeftParen Spaces expression Spaces RightParen | right expression assignmentOperator expression */ + literalExpr ::= literal @@ -246,10 +251,10 @@ assignmentOperator ::= | OrAssign -argumentList ::= LeftParen arguments? RightParen +argumentList ::= LeftParen Spaces arguments? Spaces RightParen -arguments ::= expression (Comma expression)* +arguments ::= expression ( Spaces Comma Spaces expression)* variableDeclaration ::= storageFlags [ \n]+ type [ \n]+ variableDeclarators From e31e3855ef4e30c385d61c694cef3ea46c206df6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Apr 2022 01:33:41 +0200 Subject: [PATCH 0026/1182] Solved weird issue for expressions --- src/SDSLParser/Program.cs | 6 +-- src/SDSLParser/SDSL/Expressions.sdsl | 2 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 68 +++++++++++++----------- src/Stride.Shader.Parser/SDSLTokens.ebnf | 10 ++-- 4 files changed, 48 insertions(+), 38 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index fe73268145..ad120770eb 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -7,15 +7,15 @@ var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); // var parser = new SDSLGrammar(); -var parser = StrideGrammar.New("sum"); +var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); var s = new Stopwatch(); var match = tokens.Match("(8)"); s.Start(); -match = tokens.Match(shaderf); +match = tokens.Match("3 \n*3*3"); s.Stop(); -Console.WriteLine(match.ErrorMessage[..(Math.Min(300,match.ErrorMessage.Length))]); +Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 84e206ec32..e440e5c842 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1 @@ -2 * myFunction(1,2,3,4*1+abc) + 3 * 2 \ No newline at end of file +3 \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 779b356baa..965b4c4c9f 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -133,47 +133,55 @@ MethodCall ::= userDefinedNames argumentList TermExpression ::= literal - | Sign? userDefinedNames - (AccessorChain | MethodCall) + /*| Sign? userDefinedNames - (AccessorChain | MethodCall) | Sign? (AccessorChain - MethodCall) | Sign? MethodCall | Sign? scalarOrVectorOrMatrixType argumentList - | ParenExpression + | ParenExpression*/ +Multiply ::= TermExpression ([ \t#xA])* "*" ([ \t#xA])* MulExpression +Divide ::= TermExpression ([ \t#xA])* "/" ([ \t#xA])* MulExpression +Modulo ::= TermExpression ([ \t#xA])* "%" ([ \t#xA])* MulExpression -MulExpression ::= - TermExpression - (TermExpression Spaces [*/%]) - | TermExpression Spaces Star Spaces MulExpression - | TermExpression Spaces Div Spaces MulExpression - | TermExpression Spaces Mod Spaces MulExpression - - -PIncExpression ::= - (Identifier - Keywords) IncOperators +MulExpression ::= + TermExpression - (Multiply | Divide | Modulo) + | Multiply + | Divide + | Modulo +Add ::= MulExpression ([ \t#xA])* "+" ([ \t#xA])* SumExpression +Subtract ::= MulExpression ([ \t#xA])* "-" ([ \t#xA])* SumExpression SumExpression ::= - MulExpression - (MulExpression Spaces [+-]) - | MulExpression Spaces Plus Spaces SumExpression - | MulExpression Spaces Minus Spaces SumExpression - + MulExpression - (Add | Subtract) + | Add + | Subtract + +LessThan ::= SumExpression ([ \t#xA])* "<" ([ \t#xA])* TestExpression +GreaterThan ::= SumExpression ([ \t#xA])* ">" ([ \t#xA])* TestExpression +LessEqualThan ::= SumExpression ([ \t#xA])* "<=" ([ \t#xA])* TestExpression +GreaterEqualThan ::= SumExpression ([ \t#xA])* ">=" ([ \t#xA])* TestExpression +Equals ::= SumExpression ([ \t#xA])* "==" ([ \t#xA])* TestExpression +Different ::= SumExpression ([ \t#xA])* "!=" ([ \t#xA])* TestExpression + TestExpression ::= - SumExpression - (SumExpression Spaces [<>=!(]) - | SumExpression Spaces Less Spaces TestExpression - | SumExpression Spaces Greater Spaces TestExpression - | SumExpression Spaces LessEqual Spaces TestExpression - | SumExpression Spaces GreaterEqual Spaces TestExpression - | SumExpression Spaces Equal Spaces TestExpression - | SumExpression Spaces NotEqual Spaces TestExpression + SumExpression - (SumExpression ([ \t#xA])* [<>=!(]) + | LessThan + | GreaterThan + | LessEqualThan + | GreaterEqualThan + | Equals + | Different expression ::= - TestExpression - | LeftParen expression RightParen + SumExpression +/* | LeftParen expression RightParen | LeftParen type (arrayRankSpecifier)* RightParen expression - | (Identifier | ParenExpression) Dot Identifier + | (Identifier | ParenExpression) Dot Identifier */ -ParenExpression ::= LeftParen Spaces expression Spaces RightParen +ParenExpression ::= LeftParen ([ \t#xA])* expression ([ \t#xA])* RightParen /*expression ::= literalExpr | Identifier @@ -251,10 +259,10 @@ assignmentOperator ::= | OrAssign -argumentList ::= LeftParen Spaces arguments? Spaces RightParen +argumentList ::= LeftParen ([ \t#xA])* arguments? ([ \t#xA])* RightParen -arguments ::= expression ( Spaces Comma Spaces expression)* +arguments ::= expression ( ([ \t#xA])* Comma ([ \t#xA])* expression)* variableDeclaration ::= storageFlags [ \n]+ type [ \n]+ variableDeclarators @@ -264,8 +272,8 @@ variableDeclarators ::= variableDeclarator /*(Comma variableDeclarator)**/ variableDeclarator ::= - (Identifier) - (Identifier Spaces [:]) - | Identifier Spaces variableDeclaratorSupplement + (Identifier) - (Identifier ([ \t#xA])* [:]) + | Identifier ([ \t#xA])* variableDeclaratorSupplement variableDeclaratorSupplement ::= (arrayRankSpecifier)+ diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index d0122f338b..54d2378fd9 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -190,7 +190,7 @@ IntegerSuffix ::= [uUlL] HexadecimalDigitSequence ::= HexadecimalDigit+ -DecimalIntegerLiteral ::= "0" | Digit1 Digit* +DecimalIntegerLiteral ::= "0" | [1-9] [0-9]* HexadecimalDigit ::= [0-9a-fA-F] HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ @@ -201,6 +201,8 @@ IntegerLiteral ::= (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? | HexadecimalIntegerLiteral IntegerSuffix? ) +IntegerLiteral2 ::= + DecimalIntegerLiteral FloatingSuffix ::= "f" @@ -238,9 +240,9 @@ SChar ::= literal ::= - IntegerLiteral - FloatLiteral - | FloatLiteral - | StringLiteral + IntegerLiteral2 + /*| FloatLiteral + | StringLiteral*/ PreprocessorDirective ::= '#' Whitespace? PreprocessorDirectiveName From ddde1ce4ec43dc63add515a897c61f89d1f11a95 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Apr 2022 01:34:32 +0200 Subject: [PATCH 0027/1182] Put the literal error again --- src/Stride.Shader.Parser/SDSLTokens.ebnf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 54d2378fd9..743188edd4 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -240,9 +240,9 @@ SChar ::= literal ::= - IntegerLiteral2 - /*| FloatLiteral - | StringLiteral*/ + IntegerLiteral + | FloatLiteral + | StringLiteral PreprocessorDirective ::= '#' Whitespace? PreprocessorDirectiveName From 8f79aa8dc23aa8d06352eae0e714360538926c1f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Apr 2022 16:05:36 +0200 Subject: [PATCH 0028/1182] C# Implementation --- src/SDSLParser/Program.cs | 5 +- src/Stride.Shader.Parser/SDSLExpr.ebnf | 35 +- src/Stride.Shader.Parser/SDSLGrammar.cs | 191 ----------- .../SDSLGrammar.Directives.Expression.cs | 36 +++ .../SDSLGrammar/SDSLGrammar.Directives.cs | 44 +++ .../SDSLGrammar/SDSLGrammar.Literals.cs | 49 +++ .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 160 +++++++++ .../SDSLGrammar/SDSLGrammar.Tokens.cs | 304 ++++++++++++++++++ .../SDSLGrammar/SDSLGrammar.cs | 23 ++ src/Stride.Shader.Parser/SDSLTokens.ebnf | 13 +- 10 files changed, 644 insertions(+), 216 deletions(-) delete mode 100644 src/Stride.Shader.Parser/SDSLGrammar.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index ad120770eb..43ccbc0bec 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -9,10 +9,11 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); +var sdslParser = new SDSLGrammar().UsingDirectiveExpression(); var s = new Stopwatch(); -var match = tokens.Match("(8)"); +// var match = tokens.Match("(8)"); s.Start(); -match = tokens.Match("3 \n*3*3"); +var match = sdslParser.Match("a*b*c"); s.Stop(); Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf index 965b4c4c9f..82a6d83a60 100644 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ b/src/Stride.Shader.Parser/SDSLExpr.ebnf @@ -139,9 +139,9 @@ TermExpression ::= | Sign? scalarOrVectorOrMatrixType argumentList | ParenExpression*/ -Multiply ::= TermExpression ([ \t#xA])* "*" ([ \t#xA])* MulExpression -Divide ::= TermExpression ([ \t#xA])* "/" ([ \t#xA])* MulExpression -Modulo ::= TermExpression ([ \t#xA])* "%" ([ \t#xA])* MulExpression +Multiply ::= TermExpression [ \t#xA]* "*" [ \t#xA]* MulExpression +Divide ::= TermExpression [ \t#xA]* "/" [ \t#xA]* MulExpression +Modulo ::= TermExpression [ \t#xA]* "%" [ \t#xA]* MulExpression MulExpression ::= @@ -150,24 +150,24 @@ MulExpression ::= | Divide | Modulo -Add ::= MulExpression ([ \t#xA])* "+" ([ \t#xA])* SumExpression -Subtract ::= MulExpression ([ \t#xA])* "-" ([ \t#xA])* SumExpression +Add ::= MulExpression [ \t#xA]* "+" [ \t#xA]* SumExpression +Subtract ::= MulExpression [ \t#xA]* "-" [ \t#xA]* SumExpression SumExpression ::= MulExpression - (Add | Subtract) | Add | Subtract -LessThan ::= SumExpression ([ \t#xA])* "<" ([ \t#xA])* TestExpression -GreaterThan ::= SumExpression ([ \t#xA])* ">" ([ \t#xA])* TestExpression -LessEqualThan ::= SumExpression ([ \t#xA])* "<=" ([ \t#xA])* TestExpression -GreaterEqualThan ::= SumExpression ([ \t#xA])* ">=" ([ \t#xA])* TestExpression -Equals ::= SumExpression ([ \t#xA])* "==" ([ \t#xA])* TestExpression -Different ::= SumExpression ([ \t#xA])* "!=" ([ \t#xA])* TestExpression +LessThan ::= SumExpression [ \t#xA]* "<" [ \t#xA]* TestExpression +GreaterThan ::= SumExpression [ \t#xA]* ">" [ \t#xA]* TestExpression +LessEqualThan ::= SumExpression [ \t#xA]* "<=" [ \t#xA]* TestExpression +GreaterEqualThan ::= SumExpression [ \t#xA]* ">=" [ \t#xA]* TestExpression +Equals ::= SumExpression [ \t#xA]* "==" [ \t#xA]* TestExpression +Different ::= SumExpression [ \t#xA]* "!=" [ \t#xA]* TestExpression TestExpression ::= - SumExpression - (SumExpression ([ \t#xA])* [<>=!(]) + SumExpression - (SumExpression [ \t#xA]* [<>=!(]) | LessThan | GreaterThan | LessEqualThan @@ -181,7 +181,7 @@ expression ::= | LeftParen type (arrayRankSpecifier)* RightParen expression | (Identifier | ParenExpression) Dot Identifier */ -ParenExpression ::= LeftParen ([ \t#xA])* expression ([ \t#xA])* RightParen +ParenExpression ::= LeftParen [ \t#xA]* expression [ \t#xA]* RightParen /*expression ::= literalExpr | Identifier @@ -259,10 +259,10 @@ assignmentOperator ::= | OrAssign -argumentList ::= LeftParen ([ \t#xA])* arguments? ([ \t#xA])* RightParen +argumentList ::= LeftParen [ \t#xA]* arguments? [ \t#xA]* RightParen -arguments ::= expression ( ([ \t#xA])* Comma ([ \t#xA])* expression)* +arguments ::= expression ( [ \t#xA]* Comma [ \t#xA]* expression)* variableDeclaration ::= storageFlags [ \n]+ type [ \n]+ variableDeclarators @@ -272,8 +272,8 @@ variableDeclarators ::= variableDeclarator /*(Comma variableDeclarator)**/ variableDeclarator ::= - (Identifier) - (Identifier ([ \t#xA])* [:]) - | Identifier ([ \t#xA])* variableDeclaratorSupplement + (Identifier) - (Identifier [ \t#xA]* [:]) + | Identifier [ \t#xA]* variableDeclaratorSupplement variableDeclaratorSupplement ::= (arrayRankSpecifier)+ @@ -298,7 +298,6 @@ storageFlags ::= storageFlag ::= - Constant | RowMajor | ColumnMajor diff --git a/src/Stride.Shader.Parser/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar.cs deleted file mode 100644 index 0771a383ee..0000000000 --- a/src/Stride.Shader.Parser/SDSLGrammar.cs +++ /dev/null @@ -1,191 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace Stride.Shader.Parser; -public class SDSLGrammar : Grammar -{ - public SDSLGrammar() : base("sdsl") - { - EnableMatchEvents = false; - CaseSensitive = true; - - var ws = new RepeatCharTerminal(char.IsWhiteSpace); - - var eof = End; - - var eol = Eol; - var eolo = eol.Optional(); - - var shaderDeclaration = Set("shader"); - - var ldu = LetterOrDigit | "_"; - var identifier = LetterOrDigit.Then(ldu.Repeat().Optional()).WithName("Identifier"); - - var lbr = Set("{"); - var rbr = Set("}"); - - var floatParser = new NumberParser{AllowSign = true, AllowDecimal = true, AllowExponent = true,ValueType = typeof(double), Name = "ConstantDouble", AddMatch = true, AddError = true}; - var intParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "ConstantInteger", AddMatch = true, AddError = true}; - var boolParser = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"}, FalseValues = new string[]{"false"}, AddError = true, AddMatch = true, Name = "ConstantBoolean"}; - - var constants = floatParser.Or(intParser).Or(boolParser).WithName("Constant"); - - //Step 1 parse addition - - var primary_expr = identifier.Or(constants).WithName("PrimaryExpression"); - - var assign_op = - Set("=") - | "*=" - | "/=" - | "%=" - | "+=" - | "-=" - | "<<=" - | ">>=" - | "&=" - | "^=" - | "|="; - - var unary_op = - Set("&") - | "*" - | "+" - | "-" - | "~" - | "!"; - - var incr_op = - Set("++") - | "--"; - - - var const_exp = new AlternativeParser{Name = "Constant"}; - var cond_exp = new AlternativeParser{Name = "cond_exp"}; - var lor_exp = new AlternativeParser{Name = "lor_exp"}; - var land_exp = new AlternativeParser{Name = "land_exp"}; - var or_exp = new AlternativeParser{Name = "or_exp"}; - var xor_exp = new AlternativeParser{Name = "xor_exp"}; - var and_exp = new AlternativeParser{Name = "and_exp"}; - var eq_exp = new AlternativeParser{Name = "eq_exp"}; - var rel_exp = new AlternativeParser{Name = "rel_exp"}; - var shift_exp = new AlternativeParser{Name = "shift_exp"}; - var add_exp = new AlternativeParser{Name = "add_exp"}; - var mul_exp = new AlternativeParser{Name = "mul_exp"}; - var cast_exp = new AlternativeParser{Name = "cast_exp"}; - var unary_exp = new AlternativeParser{Name = "unary_exp"}; - var postfix_exp = new AlternativeParser{Name = "postfix_exp"}; - var assign_exp = new AlternativeParser{Name = "assign_exp"}; - - var expr = new SequenceParser(); - - cond_exp.Add( - lor_exp.Then(expr.Then(":").Then(cond_exp).Optional()) - ); - - lor_exp.Add(land_exp); - lor_exp.Add(lor_exp.Then("||").Then(land_exp)); - - land_exp.Add(or_exp); - land_exp.Add(land_exp.Then("&&").Then(or_exp)); - - or_exp.Add(xor_exp); - or_exp.Add(or_exp.Then("|").Then(xor_exp)); - - xor_exp.Add(and_exp); - xor_exp.Add(xor_exp.Then("|").Then(and_exp)); - - and_exp.Add(eq_exp); - and_exp.Add(and_exp.Then("|").Then(eq_exp)); - - eq_exp.Add(rel_exp); - eq_exp.Add(eq_exp.Then("==").Or("!=").Then(rel_exp)); - - rel_exp.Add(shift_exp); - rel_exp.Add(rel_exp, Set("<") | ">" | "<=" | ">=", shift_exp); - - - shift_exp.Add(add_exp.WithName("SingleTerm")); - shift_exp.Add(shift_exp.WithName("LeftTerm").Then("<<").Or(">>").Then(add_exp).WithName("RightTerm")); - - add_exp.Add(mul_exp.WithName("SingleTerm")); - add_exp.Add(add_exp.WithName("LeftTerm").Then("+").Or("-").Then(mul_exp.WithName("RightTerm"))); - - mul_exp.Add(cast_exp); - mul_exp.Add(mul_exp.Then("*").Or("/").Or("%").Then(cast_exp)); - - cast_exp.Add(unary_exp); - cast_exp.Add(Set("(").Then(identifier).Then(cast_exp)); - - unary_exp.Add(postfix_exp); - unary_exp.Add(Set("++") |"--" , unary_exp); - unary_exp.Add(unary_op, cast_exp); - - // postfix_exp.Add(primary_expr.WithName("PrimaryPostFix")); - var pp = Set("+").Or("-").Repeat(2,2); - var access = Set("[") & primary_expr & "]"; - - var p1 = primary_expr; - // var p2 = p1 | p1. - // postfix_exp.Add( - // primary_expr - // | tt.Then(access.Optional()) - // | tt.Then(pp.Optional().Named("Increment")).Optional()); - - // postfix_exp.Add(postfix_exp.Named("Expression"), access.Optional().Named("Accessor")); - // | postfix_exp.Then("(").Then(assign_exp).Then(")") - // | postfix_exp.Then(".").Then(identifier) - - - expr.Add(assign_exp); - expr.Add(expr.Then(",").Then(assign_exp)); - - assign_exp.Add(cond_exp); - assign_exp.Add(unary_exp.Then(assign_op).Then(assign_exp)); - - - - - var a = 0; - var b = ++a+3*1; - - - - - - - // var assign = identifier.Then(Set("=")).Then(primary_expr).WithName("AssignExpression"); - // assign.SeparateChildrenBy(ws); - - - - - // var mul_expr = new SequenceParser(); - - // mul_expr.Add(primary_expr.WithName("MultLeft").Then(Set("*").Or("/").Or("%").Then(mul_expr.WithName("MultRight")).Optional())); - // mul_expr.WithName("MultExpression"); - // mul_expr.SeparateChildrenBy(ws); - // mul_expr.AddError = true; - - - // var add_expr = new SequenceParser(); - - // add_expr.Add(mul_expr.WithName("AddLeft").Then(Set("+").Or("-").Then(add_expr.WithName("AddRight")).Optional())); - // add_expr.WithName("AddExpression"); - // add_expr.SeparateChildrenBy(ws); - // add_expr.AddError = true; - - var parenthesis_expr = new AlternativeParser(); - parenthesis_expr.Add(primary_expr); - parenthesis_expr.Add(Set("(").Then(parenthesis_expr).Then(")")); - // parenthesis_expr.WithName("ParenthesisExpression"); - // parenthesis_expr.SeparateChildrenBy(ws); - // parenthesis_expr.AddError = true; - - - // tmp.PreventRecursion(true); - Inner = postfix_exp; - - } -} diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs new file mode 100644 index 0000000000..5d3ca829af --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -0,0 +1,36 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser DirectiveTerm = new(); + public AlternativeParser MulExpression = new(); + + + public SDSLGrammar UsingDirectiveExpression() + { + Inner = MulExpression; + return this; + } + + public void CreateDirectiveExpressions() + { + DirectiveTerm = + Literals + | Identifier + | StringLiteral; + + var multiply = DirectiveTerm.Then("*").Then(MulExpression); + var divide = DirectiveTerm.Then(Div).Then(MulExpression); + var mod = DirectiveTerm.Then(Mod).Then(MulExpression); + + + MulExpression = + ((DirectiveTerm - multiply).WithName("Term") + | multiply).WithName("MulExpression"); + // | divide + // | mod; + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs new file mode 100644 index 0000000000..2e860a818b --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs @@ -0,0 +1,44 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + private CharTerminal Hash = Set("#"); + + private SequenceParser HashIf = new(); + private SequenceParser HashIfDef = new(); + private SequenceParser HashIfNDef = new(); + + private SequenceParser HashElse = new(); + private SequenceParser HashElif = new(); + private SequenceParser HashEndIf = new(); + + + //TODO: Identifier Parser doesn't work here ? + public SequenceParser IfDefDirective = new(); + public SequenceParser IfNDefDirective = new(); + + public SDSLGrammar UsingIfDefDirective() + { + Inner = IfDefDirective; + return this; + } + public void CreateDirectives() + { + + HashIf = Hash.Then("if").WithName("HashIf"); + HashIfDef = Hash.Then("ifdef").WithName("HashIfDef"); + HashIfNDef = Hash.Then("ifndef").WithName("HashIfNDef"); + + HashElse = Hash.Then("else").WithName("HashElse"); + HashElif = Hash.Then("elif").WithName("HashElif"); + HashEndIf = Hash.Then("endif").WithName("HashEndIf"); + + IfDefDirective = HashIfDef.WithName("directive").Then(SingleLineWhiteSpace).Then(Identifier).WithName("IfDef"); + IfNDefDirective = HashIfNDef.WithName("directive").Then(SingleLineWhiteSpace).Then(Identifier).WithName("IfNDef"); + + } + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs new file mode 100644 index 0000000000..19e9b93978 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -0,0 +1,49 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + AlternativeParser IntegerSuffix = new(); + AlternativeParser FloatSuffix = new(); + + public SequenceParser SingleLineComment = new(); + public SequenceParser BlockComment = new(); + + public StringParser StringLiteral = new(); + public SequenceParser Identifier = new(); + public SequenceParser IntegerLiteral = new(); + public SequenceParser FloatLiteral = new(); + public HexDigitTerminal HexDigits = new(); + public SequenceParser HexaDecimalLiteral = new(); + + public AlternativeParser Literals = new(); + + public void UsingLiterals() + { + Inner = Literals; + } + public void CreateLiterals() + { + IntegerSuffix = (Set("u") | "l" | "U" | "L").WithName("suffix"); + FloatSuffix = (Set("f") | "l" | "F" | "L").WithName("suffix"); + + SingleLineComment = Set("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); + BlockComment = Set("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); + + StringLiteral = new StringParser().WithName("StringLiteral"); + Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "value"}.NotFollowedBy(FloatSuffix).Then(IntegerSuffix.Optional()).WithName("IntegerLiteral"); + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "value"}.NotFollowedBy(IntegerSuffix).Then(FloatSuffix.Optional()).WithName("FloatLiteral"); + HexDigits = new(); + HexaDecimalLiteral = Set("0x").Or("0X").Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); + + Literals = + IntegerLiteral + | FloatLiteral + | HexaDecimalLiteral + | StringLiteral; + + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs new file mode 100644 index 0000000000..b4ea3a533b --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -0,0 +1,160 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser IncOperators = new(); + + public AlternativeParser Operators = new(); + public AlternativeParser AssignOperators = new(); + + public AlternativeParser BoolTypes = new(); + + public AlternativeParser HalfTypes = new(); + + public AlternativeParser FloatTypes = new(); + + public AlternativeParser DoubleTypes = new(); + + public AlternativeParser IntTypes = new(); + + public AlternativeParser UintTypes = new(); + + public AlternativeParser ValueTypes = new(); + + public AlternativeParser Keywords = new(); + + public void CreateTokenGroups() + { + IncOperators = + PlusPlus + | MinusMinus; + + Operators = + Plus + | Minus + | Star + | Div + | Mod + | LeftShift + | RightShift; + + AssignOperators = + Assign + | StarAssign + | DivAssign + | ModAssign + | PlusAssign + | MinusAssign + | LeftShiftAssign + | RightShiftAssign + | AndAssign + | XorAssign + | OrAssign; + + BoolTypes = + Bool - BoolVec + | BoolVec - BoolMat + | BoolMat; + + HalfTypes = + Half - HalfVec + | HalfVec - HalfMat + | HalfMat; + + FloatTypes = + Float - FloatVec + | FloatVec - FloatMat + | FloatMat; + + DoubleTypes = + Double - DoubleVec + | DoubleVec - DoubleMat + | DoubleMat; + + IntTypes = + Int - IntVec + | IntVec - IntMat + | IntMat; + + UintTypes = + Uint - UintVec + | UintVec - UintMat + | UintMat; + + ValueTypes = + BoolTypes + | HalfTypes + | FloatTypes + | DoubleTypes + | IntTypes + | UintTypes; + + Keywords = + AppendStructuredBuffer + | Buffer - ByteAddressBuffer + | ByteAddressBuffer - Break + | Break + | Case - CBuffer + | CBuffer - Centroid + | Centroid - Class + | Class - ColumnMajor + | ColumnMajor - Const + | Const - ConsumeStructuredBuffer + | ConsumeStructuredBuffer - Continue + | Continue + | Default - Discard + | Discard + | Do + | Else + | Extern + | For + | Groupshared + | If + | In + | Inout + | InputPatch + | Interface + | Line_ + | LineAdj + | Linear + | LineStream + | Matrix + | Nointerpolation + | Noperspective + | Out + | OutputPatch + | Packoffset + | Point + | PointStream + | Precise + | Register + | Return + | RowMajor + | RWBuffer + | RWByteAddressBuffer + | RWStructuredBuffer + | Sample - Sampler + | Sampler + | SamplerComparisonState + | SamplerState + | Shared + | Static + | Struct + | StructuredBuffer + | Switch + | TextureTypes + | Triangle + | TriangleAdj + | TriangleStream + | Uniform + | ValueTypes + | Vector + | Volatile + | Void + | While; + + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs new file mode 100644 index 0000000000..35658b9817 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -0,0 +1,304 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + private CharTerminal WS; + private AlternativeParser Space = new(); + private RepeatParser Spaces = new(); + private SequenceParser SpacesWithLineBreak = new(); + private CharTerminal AppendStructuredBuffer; + private AlternativeParser ComponentNumber = new(); + + private CharTerminal Bool; + private SequenceParser BoolVec = new(); + private SequenceParser BoolMat = new(); + private AlternativeParser Uint = new(); + private SequenceParser UintVec = new(); + private SequenceParser UintMat = new(); + private CharTerminal Int; + private SequenceParser IntVec = new(); + private SequenceParser IntMat = new(); + + private CharTerminal Half; + private SequenceParser HalfVec = new(); + private SequenceParser HalfMat = new(); + private CharTerminal Float; + private SequenceParser FloatVec = new(); + private SequenceParser FloatMat = new(); + private CharTerminal Double; + private SequenceParser DoubleVec = new(); + private SequenceParser DoubleMat = new(); + private CharTerminal Buffer; + private CharTerminal ByteAddressBuffer; + private CharTerminal Break; + private CharTerminal Case; + private CharTerminal CBuffer; + private CharTerminal Centroid; + private CharTerminal Class; + private CharTerminal ColumnMajor; + private CharTerminal Const; + private CharTerminal ConsumeStructuredBuffer; + private CharTerminal Continue; + private CharTerminal Default; + private CharTerminal Discard; + private CharTerminal Do; + private CharTerminal Else; + private CharTerminal Extern; + private CharTerminal For; + private CharTerminal Groupshared; + private CharTerminal If; + private CharTerminal In; + private AlternativeParser Inout = new(); + private CharTerminal InputPatch; + private CharTerminal Interface; + private CharTerminal Line_ = Set("line"); + private CharTerminal LineAdj; + private CharTerminal Linear; + private CharTerminal LineStream; + private CharTerminal Long; + private CharTerminal Matrix; + private CharTerminal Nointerpolation; + private CharTerminal Noperspective; + private CharTerminal Out; + private CharTerminal OutputPatch; + private CharTerminal Packoffset; + private CharTerminal Point; + private CharTerminal PointStream; + private CharTerminal Precise; + private CharTerminal Register; + private CharTerminal Return; + private CharTerminal RowMajor; + private CharTerminal RWBuffer; + private CharTerminal RWByteAddressBuffer; + private CharTerminal RWStructuredBuffer; + private CharTerminal Sample; + private CharTerminal Sampler; + private CharTerminal SamplerComparisonState; + private CharTerminal SamplerState; + private CharTerminal Shared; + private CharTerminal Static; + private CharTerminal Struct; + private CharTerminal StructuredBuffer; + private CharTerminal Switch; + private AlternativeParser TextureTypes = + (Set("Texture").NotFollowedBy("2DMS").Then(Set("1") | "2" | "3").Then("D").Then(Set("Array").Optional())) + | (Set("Texture2DMS").Then(Set("Array").Optional())) + | (Set("TextureCube").Then(Set("Array").Optional())); + private CharTerminal Triangle; + private CharTerminal TriangleAdj; + private CharTerminal TriangleStream; + private CharTerminal Uniform; + private CharTerminal Vector; + private CharTerminal Volatile; + private CharTerminal Void; + private CharTerminal While; + private CharTerminal LeftParen; + private CharTerminal RightParen; + private CharTerminal LeftBracket; + private CharTerminal RightBracket; + private CharTerminal LeftBrace; + private CharTerminal RightBrace; + + private CharTerminal LeftShift; + private CharTerminal RightShift; + private CharTerminal Plus; + private CharTerminal PlusPlus; + private CharTerminal Minus; + private CharTerminal MinusMinus; + private CharTerminal Star; + private CharTerminal Div; + private CharTerminal Mod; + private CharTerminal And; + private CharTerminal Or; + private CharTerminal AndAnd; + private CharTerminal OrOr; + private CharTerminal Caret; + private CharTerminal Not; + private CharTerminal Tilde; + private CharTerminal Equal; + private CharTerminal NotEqual; + private CharTerminal Less; + private CharTerminal LessEqual; + private CharTerminal Greater; + private CharTerminal GreaterEqual; + private CharTerminal Question; + private CharTerminal Colon; + private CharTerminal ColonColon; + private CharTerminal Semi; + private CharTerminal Comma; + private CharTerminal Assign; + private CharTerminal StarAssign; + private CharTerminal DivAssign; + private CharTerminal ModAssign; + private CharTerminal PlusAssign; + private CharTerminal MinusAssign; + private CharTerminal LeftShiftAssign; + private CharTerminal RightShiftAssign; + private CharTerminal AndAssign; + private CharTerminal XorAssign; + private CharTerminal OrAssign; + + private CharTerminal Dot; + private CharTerminal True; + private CharTerminal False; + private AlternativeParser PreprocessorDirectiveName = new(); + + public void CreateTokens() + { + WS = WhiteSpace; + Space = WhiteSpace | Eol; + Spaces = Space.Optional().Repeat(); + SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); + AppendStructuredBuffer = Set("AppendStructuredBuffer"); + ComponentNumber = Set("1") | "2" | "3" | "4"; + + Bool = Set("bool"); + BoolVec = Bool.Then(ComponentNumber); + BoolMat = BoolVec.Then("x").Then(ComponentNumber); + Uint = Set("uint") | "unsigned int" | "dword"; + UintVec = Uint.Then(ComponentNumber); + UintMat = UintVec.Then("x").Then(ComponentNumber); + Int = Set("int"); + IntVec = Int.Then(ComponentNumber); + IntMat = IntVec.Then("x").Then(ComponentNumber); + + Half = Set("half"); + HalfVec = Half.Then(ComponentNumber); + HalfMat = HalfVec.Then("x").Then(ComponentNumber); + Float = Set("float"); + FloatVec = Float.Then(ComponentNumber); + FloatMat = FloatVec.Then("x").Then(ComponentNumber); + Double = Set("double"); + DoubleVec = Double.Then(ComponentNumber); + DoubleMat = DoubleVec.Then("x").Then(ComponentNumber); + Buffer = Set("Buffer"); + ByteAddressBuffer = Set("ByteAddressBuffer"); + Break = Set("break"); + Case = Set("case"); + CBuffer = Set("cbuffer"); + Centroid = Set("centroid"); + Class = Set("class"); + ColumnMajor = Set("column_major"); + Const = Set("const"); + ConsumeStructuredBuffer = Set("ConsumeStructuredBuffer"); + Continue = Set("continue"); + Default = Set("default"); + Discard = Set("discard"); + Do = Set("do"); + Else = Set("else"); + Extern = Set("extern"); + For = Set("for"); + Groupshared = Set("groupshared"); + If = Set("if"); + In = Set("in"); + Inout = Set("inout") | "in out"; + InputPatch = Set("InputPatch"); + Interface = Set("interface"); + Line_ = Set("line"); + LineAdj = Set("lineadj"); + Linear = Set("linear"); + LineStream = Set("LineStream"); + Long = Set("long"); + Matrix = Set("matrix"); + Nointerpolation = Set("nointerpolation"); + Noperspective = Set("noperspective"); + Out = Set("out"); + OutputPatch = Set("OutputPatch"); + Packoffset = Set("packoffset"); + Point = Set("point"); + PointStream = Set("PointStream"); + Precise = Set("precise"); + Register = Set("register"); + Return = Set("return"); + RowMajor = Set("row_major"); + RWBuffer = Set("RWBuffer"); + RWByteAddressBuffer = Set("RWByteAddressBuffer"); + RWStructuredBuffer = Set("RWStructuredBuffer"); + Sample = Set("sample"); + Sampler = Set("sampler"); + SamplerComparisonState = Set("SamplerComparisonState"); + SamplerState = Set("SamplerState"); + Shared = Set("shared"); + Static = Set("static"); + Struct = Set("struct"); + StructuredBuffer = Set("StructuredBuffer"); + Switch = Set("switch"); + TextureTypes = + (Set("Texture").NotFollowedBy("2DMS").Then(Set("1") | "2" | "3").Then("D").Then(Set("Array").Optional())) + | (Set("Texture2DMS").Then(Set("Array").Optional())) + | (Set("TextureCube").Then(Set("Array").Optional())); + Triangle = Set("triangle"); + TriangleAdj = Set("triangleadj"); + TriangleStream = Set("TriangleStream"); + Uniform = Set("uniform"); + Vector = Set("vector"); + Volatile = Set("volatile"); + Void = Set("void"); + While = Set("while"); + LeftParen = Set("("); + RightParen = Set(")"); + LeftBracket = Set("["); + RightBracket = Set("]"); + LeftBrace = Set("{"); + RightBrace = Set("}"); + + LeftShift = Set("<<"); + RightShift = Set(">>"); + Plus = Set("+"); + PlusPlus = Set("++"); + Minus = Set("-"); + MinusMinus = Set("--"); + Star = Set("*"); + Div = Set("/"); + Mod = Set("%"); + And = Set("&"); + Or = Set("|"); + AndAnd = Set("&&"); + OrOr = Set("||"); + Caret = Set("^"); + Not = Set("!"); + Tilde = Set("~"); + Equal = Set("=="); + NotEqual = Set("!="); + Less = Set("<"); + LessEqual = Set("<="); + Greater = Set(">"); + GreaterEqual = Set(">="); + Question = Set("?"); + Colon = Set(":"); + ColonColon = Set("::"); + Semi = Set(";"); + Comma = Set(","); + Assign = Set("="); + StarAssign = Set("*="); + DivAssign = Set("/="); + ModAssign = Set("%="); + PlusAssign = Set("+="); + MinusAssign = Set("-="); + LeftShiftAssign = Set("<<="); + RightShiftAssign = Set(">>="); + AndAssign = Set("&="); + XorAssign = Set("^="); + OrAssign = Set("|="); + + Dot = Set("."); + True = Set("true"); + False = Set("false"); + PreprocessorDirectiveName = + Set("define") + | "elif" + | "else" + | "endif" + | "error" + | "if" + | "ifdef" + | "ifndef" + | "include" + | "line" + | "pragma" + | "undef"; + + } +} diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs new file mode 100644 index 0000000000..1380836c58 --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs @@ -0,0 +1,23 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +using EtoParser = Eto.Parse.Parser; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public SDSLGrammar() : base("sdsl") + { + CreateAll(); + } + + public void CreateAll() + { + CreateTokens(); + CreateTokenGroups(); + CreateLiterals(); + CreateDirectives(); + CreateDirectiveExpressions(); + } +} diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf index 743188edd4..c9e32b353c 100644 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ b/src/Stride.Shader.Parser/SDSLTokens.ebnf @@ -185,7 +185,7 @@ Nondigit ::= [a-zA-Z_] Digit1 ::= [1-9] Digit ::= '0' | Digit1 -IntegerSuffix ::= [uUlL] +IntegerSuffix ::= [ulUL]? HexadecimalDigitSequence ::= HexadecimalDigit+ @@ -195,14 +195,17 @@ DecimalIntegerLiteral ::= "0" | [1-9] [0-9]* HexadecimalDigit ::= [0-9a-fA-F] HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ -IntegerLiteral ::= +/*IntegerLiteral ::= Sign? ( (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? | HexadecimalIntegerLiteral IntegerSuffix? - ) -IntegerLiteral2 ::= - DecimalIntegerLiteral + )*/ +IntegerLiteral ::= + (Sign DecimalIntegerLiteral - HexadecimalIntegerLiteral + | Sign HexadecimalIntegerLiteral + | DecimalIntegerLiteral - HexadecimalIntegerLiteral + | HexadecimalIntegerLiteral) IntegerSuffix FloatingSuffix ::= "f" From 337c9afb3c80dccabfa4277f3165de621ef675a9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Apr 2022 20:12:11 +0200 Subject: [PATCH 0029/1182] Correction Expression, Needs work on literals --- src/SDSLParser/Program.cs | 2 +- .../SDSLGrammar.Directives.Expression.cs | 54 +++++++++++++++---- .../SDSLGrammar/SDSLGrammar.Literals.cs | 22 +++++--- 3 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 43ccbc0bec..038afac2eb 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -13,7 +13,7 @@ var s = new Stopwatch(); // var match = tokens.Match("(8)"); s.Start(); -var match = sdslParser.Match("a*b*c"); +var match = sdslParser.Match("5>a/b*c+5+2"); s.Stop(); Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 5d3ca829af..816bfe7637 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -6,12 +6,15 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { public AlternativeParser DirectiveTerm = new(); - public AlternativeParser MulExpression = new(); - + public AlternativeParser DirectiveMul = new(); + public AlternativeParser DirectiveSum = new(); + public AlternativeParser DirectiveTest = new(); + + public SDSLGrammar UsingDirectiveExpression() { - Inner = MulExpression; + Inner = DirectiveTest; return this; } @@ -22,14 +25,47 @@ public void CreateDirectiveExpressions() | Identifier | StringLiteral; - var multiply = DirectiveTerm.Then("*").Then(MulExpression); - var divide = DirectiveTerm.Then(Div).Then(MulExpression); - var mod = DirectiveTerm.Then(Mod).Then(MulExpression); + var mulOp = Star | Div | Mod; + + var multiply = DirectiveTerm.Then(Star).Then(DirectiveMul).Named("DirectiveMultiply"); + var divide = DirectiveTerm.Then(Div).Then(DirectiveMul).Named("DirectiveDivide"); + var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).Named("DirectiveModerand"); + + + DirectiveMul.Add( + DirectiveTerm - (multiply | divide | moderand) + | multiply - (divide | moderand) + | divide - moderand + | moderand + ); + - MulExpression = - ((DirectiveTerm - multiply).WithName("Term") - | multiply).WithName("MulExpression"); + // DirectiveMul.Add(multiply); + + var add = DirectiveMul.Then(Plus).Then(DirectiveSum).Named("DirectiveAdd"); + var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).Named("DirectiveSubtract"); + + DirectiveSum.Add( + DirectiveMul - (add | subtract) + | add - subtract + | subtract + ); + + var greater = DirectiveSum.Then(Greater).Then(DirectiveTest).Named("DirectiveGreater"); + var less = DirectiveSum.Then(Less).Then(DirectiveTest).Named("DirectiveLess"); + var greaterEqual = DirectiveSum.Then(GreaterEqual).Then(DirectiveTest).Named("DirectiveGreaterEqual"); + var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest).Named("DirectiveLessEqual"); + + DirectiveTest.Add( + DirectiveSum - (greater | less | greaterEqual | lessEqual) + | greater - (less | greaterEqual | lessEqual) + | less - (greaterEqual | lessEqual) + | greaterEqual - lessEqual + | lessEqual + ); + + //(DirectiveTerm.Except(multiply)).Or(multiply); // | divide // | mod; } diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index 19e9b93978..4df1fdffd5 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -13,8 +13,8 @@ public partial class SDSLGrammar : Grammar public StringParser StringLiteral = new(); public SequenceParser Identifier = new(); - public SequenceParser IntegerLiteral = new(); - public SequenceParser FloatLiteral = new(); + public NumberParser IntegerLiteral = new(); + public NumberParser FloatLiteral = new(); public HexDigitTerminal HexDigits = new(); public SequenceParser HexaDecimalLiteral = new(); @@ -34,16 +34,22 @@ public void CreateLiterals() StringLiteral = new StringParser().WithName("StringLiteral"); Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "value"}.NotFollowedBy(FloatSuffix).Then(IntegerSuffix.Optional()).WithName("IntegerLiteral"); - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "value"}.NotFollowedBy(IntegerSuffix).Then(FloatSuffix.Optional()).WithName("FloatLiteral"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "value"}.WithName("IntegerLiteral"); + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "value"}.WithName("FloatLiteral"); HexDigits = new(); HexaDecimalLiteral = Set("0x").Or("0X").Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); - Literals = - IntegerLiteral + Literals.Add( + IntegerLiteral.NotFollowedBy(IntegerSuffix) - FloatLiteral + | IntegerLiteral.Then(IntegerSuffix) - FloatLiteral | FloatLiteral - | HexaDecimalLiteral - | StringLiteral; + ); + // .NotFollowedBy(IntegerSuffix) - FloatLiteral + // | IntegerLiteral.Then(IntegerSuffix) - FloatLiteral + // // | FloatLiteral.NotFollowedBy(FloatSuffix) + // // | FloatLiteral.Then(FloatSuffix) + // // | HexaDecimalLiteral + // | StringLiteral; } } \ No newline at end of file From 8fc048fc74b4bb68a43f68e710d3216d5827227e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 30 Apr 2022 13:36:54 +0200 Subject: [PATCH 0030/1182] Correction literals --- src/SDSLParser/Program.cs | 4 +- .../SDSLGrammar.Directives.Expression.cs | 71 ++++++++++++++++--- .../SDSLGrammar/SDSLGrammar.Literals.cs | 17 +++-- 3 files changed, 72 insertions(+), 20 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 038afac2eb..b94a600c12 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -11,9 +11,9 @@ var tokens = StrideGrammar.HlslGrammar("expression"); var sdslParser = new SDSLGrammar().UsingDirectiveExpression(); var s = new Stopwatch(); -// var match = tokens.Match("(8)"); +var match = sdslParser.Match("(8)"); s.Start(); -var match = sdslParser.Match("5>a/b*c+5+2"); +match = sdslParser.Match(".5d"); s.Stop(); Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 816bfe7637..3041c21c31 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -10,20 +10,42 @@ public partial class SDSLGrammar : Grammar public AlternativeParser DirectiveSum = new(); public AlternativeParser DirectiveTest = new(); - + public AlternativeParser DirectiveExpr = new(); + public AlternativeParser DirectiveIncrementExpr = new(); + public AlternativeParser ParenDirectiveExpr = new(); public SDSLGrammar UsingDirectiveExpression() { - Inner = DirectiveTest; + Inner = Literals; return this; } public void CreateDirectiveExpressions() { - DirectiveTerm = + var parenMul = + LeftParen.Then(DirectiveMul).Then(RightParen); + var parenSum = + LeftParen.Then(DirectiveSum).Then(RightParen); + var parenTest = + LeftParen.Then(DirectiveTest).Then(RightParen); + + DirectiveIncrementExpr.Add( + Identifier.Then(PlusPlus).Named("IdPostIncrement") + // | Identifier.Then(MinusMinus).Named("IdPostDecrement") + // | LeftParen.Then(Identifier).Then(RightParen).NotFollowedBy(MinusMinus).Then(PlusPlus).Named("ParenPostIncrement") + // | LeftParen.Then(Identifier).Then(RightParen).Then(MinusMinus).Named("ParenPostDecrement") + ); + var userDefinedTypes = Identifier.Except(Keywords); + var increment = userDefinedTypes & "++"; + + DirectiveTerm.Add( Literals - | Identifier - | StringLiteral; + | userDefinedTypes.Then("++") + // | parenMul + // | parenSum + // | parenTest + ); + // | ParenDirectiveExpr; var mulOp = Star | Div | Mod; @@ -31,6 +53,7 @@ public void CreateDirectiveExpressions() var divide = DirectiveTerm.Then(Div).Then(DirectiveMul).Named("DirectiveDivide"); var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).Named("DirectiveModerand"); + DirectiveMul.Add( @@ -40,12 +63,11 @@ public void CreateDirectiveExpressions() | moderand ); - - // DirectiveMul.Add(multiply); - + var add = DirectiveMul.Then(Plus).Then(DirectiveSum).Named("DirectiveAdd"); var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).Named("DirectiveSubtract"); + DirectiveSum.Add( DirectiveMul - (add | subtract) | add - subtract @@ -65,8 +87,35 @@ public void CreateDirectiveExpressions() | lessEqual ); - //(DirectiveTerm.Except(multiply)).Or(multiply); - // | divide - // | mod; + + ParenDirectiveExpr.Add( + LeftParen.Then(DirectiveExpr).Then(RightParen) + ); + + + + var methodCall = Identifier.Then(LeftParen).Then(RightParen).Named("DirectiveMethodCall"); + + DirectiveExpr.Add( + DirectiveTest + | ParenDirectiveExpr + // | DirectiveIncrementExpr - methodCall + // | methodCall + ); + + + + + // IncrementDirectiveExpr ::= + // literal postfixUnaryOperator + // | Identifier postfixUnaryOperator + // | ParenDirectiveExpression postfixUnaryOperator + // | prefixUnaryOperator Identifier - postfixUnaryOperator + // | prefixUnaryOperator ParenDirectiveExpression - postfixUnaryOperator + + // directiveExpression ::= + // TestDirective + // | IncrementExpr - (MethodCallDirective) + // | MethodCallDirective } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index 4df1fdffd5..5ac07f94f8 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -26,23 +26,26 @@ public void UsingLiterals() } public void CreateLiterals() { - IntegerSuffix = (Set("u") | "l" | "U" | "L").WithName("suffix"); - FloatSuffix = (Set("f") | "l" | "F" | "L").WithName("suffix"); + IntegerSuffix = (Set("u") | "l" | "U" | "L").WithName("int_suffix"); + FloatSuffix = (Set("f") | "d" | "F" | "D").WithName("float_suffix"); SingleLineComment = Set("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); BlockComment = Set("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); StringLiteral = new StringParser().WithName("StringLiteral"); Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "value"}.WithName("IntegerLiteral"); - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "value"}.WithName("FloatLiteral"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerLiteral"); + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatLiteral"); HexDigits = new(); HexaDecimalLiteral = Set("0x").Or("0X").Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); + var floats = FloatLiteral.Then(FloatSuffix - IntegerSuffix).Named("FloatLiteral"); + var ints = IntegerLiteral.Then(IntegerSuffix - FloatSuffix).Named("IntegerLiteral"); + Literals.Add( - IntegerLiteral.NotFollowedBy(IntegerSuffix) - FloatLiteral - | IntegerLiteral.Then(IntegerSuffix) - FloatLiteral - | FloatLiteral + ints + | floats + | StringLiteral ); // .NotFollowedBy(IntegerSuffix) - FloatLiteral // | IntegerLiteral.Then(IntegerSuffix) - FloatLiteral From ee81df6bb8daa2c53b70e232149cf960f0f5fb91 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 May 2022 12:18:44 +0200 Subject: [PATCH 0031/1182] Stabilized directive expressions --- src/SDSLParser/Program.cs | 2 +- .../SDSLGrammar.Directives.Expression.cs | 32 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 41 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 491 +++++++++--------- 4 files changed, 294 insertions(+), 272 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index b94a600c12..41a7da7eef 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -13,7 +13,7 @@ var s = new Stopwatch(); var match = sdslParser.Match("(8)"); s.Start(); -match = sdslParser.Match(".5d"); +match = sdslParser.Match("(my_var--+5)"); s.Stop(); Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 3041c21c31..8b460fb02d 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -16,7 +16,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar UsingDirectiveExpression() { - Inner = Literals; + Inner = DirectiveExpr; return this; } @@ -29,18 +29,27 @@ public void CreateDirectiveExpressions() var parenTest = LeftParen.Then(DirectiveTest).Then(RightParen); + + var userDefinedTypes = Identifier.Except(Keywords); + + var incrementOp = PlusPlus | MinusMinus; + + var postfixIncrement = + (Identifier & "++").Named("Increment") + | (Identifier & "--").Named("Decrement"); + var prefixIncrement = + ("++" & Identifier).Named("Increment") + | ("--" & Identifier).Named("Decrement"); + DirectiveIncrementExpr.Add( - Identifier.Then(PlusPlus).Named("IdPostIncrement") - // | Identifier.Then(MinusMinus).Named("IdPostDecrement") - // | LeftParen.Then(Identifier).Then(RightParen).NotFollowedBy(MinusMinus).Then(PlusPlus).Named("ParenPostIncrement") - // | LeftParen.Then(Identifier).Then(RightParen).Then(MinusMinus).Named("ParenPostDecrement") + prefixIncrement + | postfixIncrement ); - var userDefinedTypes = Identifier.Except(Keywords); - var increment = userDefinedTypes & "++"; DirectiveTerm.Add( Literals - | userDefinedTypes.Then("++") + | DirectiveIncrementExpr + // | DirectiveIncrementExpr // | parenMul // | parenSum // | parenTest @@ -67,9 +76,10 @@ public void CreateDirectiveExpressions() var add = DirectiveMul.Then(Plus).Then(DirectiveSum).Named("DirectiveAdd"); var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).Named("DirectiveSubtract"); + DirectiveSum.Add( - DirectiveMul - (add | subtract) + DirectiveMul.FollowedBy(incrementOp.Optional()) - ( add | subtract) | add - subtract | subtract ); @@ -98,8 +108,8 @@ public void CreateDirectiveExpressions() DirectiveExpr.Add( DirectiveTest - | ParenDirectiveExpr - // | DirectiveIncrementExpr - methodCall + | ParenDirectiveExpr.Named("ParenthesisExpr") + // | methodCall ); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index 5ac07f94f8..735082f0ed 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -5,8 +5,8 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { - AlternativeParser IntegerSuffix = new(); - AlternativeParser FloatSuffix = new(); + AlternativeParser IntegerSuffix; + AlternativeParser FloatSuffix; public SequenceParser SingleLineComment = new(); public SequenceParser BlockComment = new(); @@ -26,25 +26,38 @@ public void UsingLiterals() } public void CreateLiterals() { - IntegerSuffix = (Set("u") | "l" | "U" | "L").WithName("int_suffix"); - FloatSuffix = (Set("f") | "d" | "F" | "D").WithName("float_suffix"); + IntegerSuffix = + Literal("u") + | Literal("l") + | Literal("U") + | Literal("L"); - SingleLineComment = Set("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); - BlockComment = Set("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); + FloatSuffix = + Literal("f") + | Literal("d") + | Literal("F") + | Literal("D"); + + SingleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); + BlockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); StringLiteral = new StringParser().WithName("StringLiteral"); Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerLiteral"); - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatLiteral"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); HexDigits = new(); - HexaDecimalLiteral = Set("0x").Or("0X").Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); - - var floats = FloatLiteral.Then(FloatSuffix - IntegerSuffix).Named("FloatLiteral"); - var ints = IntegerLiteral.Then(IntegerSuffix - FloatSuffix).Named("IntegerLiteral"); + HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); + var ints = + HexaDecimalLiteral + | IntegerLiteral.Then(IntegerSuffix.Optional().Named("suffix")).Named("IntegerLiteral"); + var floats = + FloatLiteral.Then(FloatSuffix.Optional().Named("suffix")).Named("FloatLiteral"); + // | IntegerLiteral.Then(IntegerSuffix); + Literals.Add( - ints - | floats + floats - ints + | ints | StringLiteral ); // .NotFollowedBy(IntegerSuffix) - FloatLiteral diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs index 35658b9817..7d8535abc5 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -8,141 +8,140 @@ public partial class SDSLGrammar : Grammar private AlternativeParser Space = new(); private RepeatParser Spaces = new(); private SequenceParser SpacesWithLineBreak = new(); - private CharTerminal AppendStructuredBuffer; + private LiteralTerminal AppendStructuredBuffer; private AlternativeParser ComponentNumber = new(); - private CharTerminal Bool; + private LiteralTerminal Bool; private SequenceParser BoolVec = new(); private SequenceParser BoolMat = new(); private AlternativeParser Uint = new(); private SequenceParser UintVec = new(); private SequenceParser UintMat = new(); - private CharTerminal Int; + private LiteralTerminal Int; private SequenceParser IntVec = new(); private SequenceParser IntMat = new(); - private CharTerminal Half; + private LiteralTerminal Half; private SequenceParser HalfVec = new(); private SequenceParser HalfMat = new(); - private CharTerminal Float; + private LiteralTerminal Float; private SequenceParser FloatVec = new(); private SequenceParser FloatMat = new(); - private CharTerminal Double; + private LiteralTerminal Double; private SequenceParser DoubleVec = new(); private SequenceParser DoubleMat = new(); - private CharTerminal Buffer; - private CharTerminal ByteAddressBuffer; - private CharTerminal Break; - private CharTerminal Case; - private CharTerminal CBuffer; - private CharTerminal Centroid; - private CharTerminal Class; - private CharTerminal ColumnMajor; - private CharTerminal Const; - private CharTerminal ConsumeStructuredBuffer; - private CharTerminal Continue; - private CharTerminal Default; - private CharTerminal Discard; - private CharTerminal Do; - private CharTerminal Else; - private CharTerminal Extern; - private CharTerminal For; - private CharTerminal Groupshared; - private CharTerminal If; - private CharTerminal In; + private LiteralTerminal Buffer; + private LiteralTerminal ByteAddressBuffer; + private LiteralTerminal Break; + private LiteralTerminal Case; + private LiteralTerminal CBuffer; + private LiteralTerminal Centroid; + private LiteralTerminal Class; + private LiteralTerminal ColumnMajor; + private LiteralTerminal Const; + private LiteralTerminal ConsumeStructuredBuffer; + private LiteralTerminal Continue; + private LiteralTerminal Default; + private LiteralTerminal Discard; + private LiteralTerminal Do; + private LiteralTerminal Else; + private LiteralTerminal Extern; + private LiteralTerminal For; + private LiteralTerminal Groupshared; + private LiteralTerminal If; + private LiteralTerminal In; private AlternativeParser Inout = new(); - private CharTerminal InputPatch; - private CharTerminal Interface; - private CharTerminal Line_ = Set("line"); - private CharTerminal LineAdj; - private CharTerminal Linear; - private CharTerminal LineStream; - private CharTerminal Long; - private CharTerminal Matrix; - private CharTerminal Nointerpolation; - private CharTerminal Noperspective; - private CharTerminal Out; - private CharTerminal OutputPatch; - private CharTerminal Packoffset; - private CharTerminal Point; - private CharTerminal PointStream; - private CharTerminal Precise; - private CharTerminal Register; - private CharTerminal Return; - private CharTerminal RowMajor; - private CharTerminal RWBuffer; - private CharTerminal RWByteAddressBuffer; - private CharTerminal RWStructuredBuffer; - private CharTerminal Sample; - private CharTerminal Sampler; - private CharTerminal SamplerComparisonState; - private CharTerminal SamplerState; - private CharTerminal Shared; - private CharTerminal Static; - private CharTerminal Struct; - private CharTerminal StructuredBuffer; - private CharTerminal Switch; - private AlternativeParser TextureTypes = - (Set("Texture").NotFollowedBy("2DMS").Then(Set("1") | "2" | "3").Then("D").Then(Set("Array").Optional())) - | (Set("Texture2DMS").Then(Set("Array").Optional())) - | (Set("TextureCube").Then(Set("Array").Optional())); - private CharTerminal Triangle; - private CharTerminal TriangleAdj; - private CharTerminal TriangleStream; - private CharTerminal Uniform; - private CharTerminal Vector; - private CharTerminal Volatile; - private CharTerminal Void; - private CharTerminal While; - private CharTerminal LeftParen; - private CharTerminal RightParen; - private CharTerminal LeftBracket; - private CharTerminal RightBracket; - private CharTerminal LeftBrace; - private CharTerminal RightBrace; + private LiteralTerminal InputPatch; + private LiteralTerminal Interface; - private CharTerminal LeftShift; - private CharTerminal RightShift; - private CharTerminal Plus; - private CharTerminal PlusPlus; - private CharTerminal Minus; - private CharTerminal MinusMinus; - private CharTerminal Star; - private CharTerminal Div; - private CharTerminal Mod; - private CharTerminal And; - private CharTerminal Or; - private CharTerminal AndAnd; - private CharTerminal OrOr; - private CharTerminal Caret; - private CharTerminal Not; - private CharTerminal Tilde; - private CharTerminal Equal; - private CharTerminal NotEqual; - private CharTerminal Less; - private CharTerminal LessEqual; - private CharTerminal Greater; - private CharTerminal GreaterEqual; - private CharTerminal Question; - private CharTerminal Colon; - private CharTerminal ColonColon; - private CharTerminal Semi; - private CharTerminal Comma; - private CharTerminal Assign; - private CharTerminal StarAssign; - private CharTerminal DivAssign; - private CharTerminal ModAssign; - private CharTerminal PlusAssign; - private CharTerminal MinusAssign; - private CharTerminal LeftShiftAssign; - private CharTerminal RightShiftAssign; - private CharTerminal AndAssign; - private CharTerminal XorAssign; - private CharTerminal OrAssign; + public LiteralTerminal Line_ { get; private set; } - private CharTerminal Dot; - private CharTerminal True; - private CharTerminal False; + private LiteralTerminal LineAdj; + private LiteralTerminal Linear; + private LiteralTerminal LineStream; + private LiteralTerminal Long; + private LiteralTerminal Matrix; + private LiteralTerminal Nointerpolation; + private LiteralTerminal Noperspective; + private LiteralTerminal Out; + private LiteralTerminal OutputPatch; + private LiteralTerminal Packoffset; + private LiteralTerminal Point; + private LiteralTerminal PointStream; + private LiteralTerminal Precise; + private LiteralTerminal Register; + private LiteralTerminal Return; + private LiteralTerminal RowMajor; + private LiteralTerminal RWBuffer; + private LiteralTerminal RWByteAddressBuffer; + private LiteralTerminal RWStructuredBuffer; + private LiteralTerminal Sample; + private LiteralTerminal Sampler; + private LiteralTerminal SamplerComparisonState; + private LiteralTerminal SamplerState; + private LiteralTerminal Shared; + private LiteralTerminal Static; + private LiteralTerminal Struct; + private LiteralTerminal StructuredBuffer; + private LiteralTerminal Switch; + private AlternativeParser TextureTypes; + private LiteralTerminal Triangle; + private LiteralTerminal TriangleAdj; + private LiteralTerminal TriangleStream; + private LiteralTerminal Uniform; + private LiteralTerminal Vector; + private LiteralTerminal Volatile; + private LiteralTerminal Void; + private LiteralTerminal While; + private LiteralTerminal LeftParen; + private LiteralTerminal RightParen; + private LiteralTerminal LeftBracket; + private LiteralTerminal RightBracket; + private LiteralTerminal LeftBrace; + private LiteralTerminal RightBrace; + + private LiteralTerminal LeftShift; + private LiteralTerminal RightShift; + private LiteralTerminal Plus; + private LiteralTerminal PlusPlus; + private LiteralTerminal Minus; + private LiteralTerminal MinusMinus; + private LiteralTerminal Star; + private LiteralTerminal Div; + private LiteralTerminal Mod; + private LiteralTerminal And; + private LiteralTerminal Or; + private LiteralTerminal AndAnd; + private LiteralTerminal OrOr; + private LiteralTerminal Caret; + private LiteralTerminal Not; + private LiteralTerminal Tilde; + private LiteralTerminal Equal; + private LiteralTerminal NotEqual; + private LiteralTerminal Less; + private LiteralTerminal LessEqual; + private LiteralTerminal Greater; + private LiteralTerminal GreaterEqual; + private LiteralTerminal Question; + private LiteralTerminal Colon; + private LiteralTerminal ColonColon; + private LiteralTerminal Semi; + private LiteralTerminal Comma; + private LiteralTerminal Assign; + private LiteralTerminal StarAssign; + private LiteralTerminal DivAssign; + private LiteralTerminal ModAssign; + private LiteralTerminal PlusAssign; + private LiteralTerminal MinusAssign; + private LiteralTerminal LeftShiftAssign; + private LiteralTerminal RightShiftAssign; + private LiteralTerminal AndAssign; + private LiteralTerminal XorAssign; + private LiteralTerminal OrAssign; + + private LiteralTerminal Dot; + private LiteralTerminal True; + private LiteralTerminal False; private AlternativeParser PreprocessorDirectiveName = new(); public void CreateTokens() @@ -151,154 +150,154 @@ public void CreateTokens() Space = WhiteSpace | Eol; Spaces = Space.Optional().Repeat(); SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); - AppendStructuredBuffer = Set("AppendStructuredBuffer"); - ComponentNumber = Set("1") | "2" | "3" | "4"; + AppendStructuredBuffer = Literal("AppendStructuredBuffer"); + ComponentNumber = Literal("1") | "2" | "3" | "4"; - Bool = Set("bool"); + Bool = Literal("bool"); BoolVec = Bool.Then(ComponentNumber); BoolMat = BoolVec.Then("x").Then(ComponentNumber); - Uint = Set("uint") | "unsigned int" | "dword"; + Uint = Literal("uint") | "unsigned int" | "dword"; UintVec = Uint.Then(ComponentNumber); UintMat = UintVec.Then("x").Then(ComponentNumber); - Int = Set("int"); + Int = Literal("int"); IntVec = Int.Then(ComponentNumber); IntMat = IntVec.Then("x").Then(ComponentNumber); - Half = Set("half"); + Half = Literal("half"); HalfVec = Half.Then(ComponentNumber); HalfMat = HalfVec.Then("x").Then(ComponentNumber); - Float = Set("float"); + Float = Literal("float"); FloatVec = Float.Then(ComponentNumber); FloatMat = FloatVec.Then("x").Then(ComponentNumber); - Double = Set("double"); + Double = Literal("double"); DoubleVec = Double.Then(ComponentNumber); DoubleMat = DoubleVec.Then("x").Then(ComponentNumber); - Buffer = Set("Buffer"); - ByteAddressBuffer = Set("ByteAddressBuffer"); - Break = Set("break"); - Case = Set("case"); - CBuffer = Set("cbuffer"); - Centroid = Set("centroid"); - Class = Set("class"); - ColumnMajor = Set("column_major"); - Const = Set("const"); - ConsumeStructuredBuffer = Set("ConsumeStructuredBuffer"); - Continue = Set("continue"); - Default = Set("default"); - Discard = Set("discard"); - Do = Set("do"); - Else = Set("else"); - Extern = Set("extern"); - For = Set("for"); - Groupshared = Set("groupshared"); - If = Set("if"); - In = Set("in"); - Inout = Set("inout") | "in out"; - InputPatch = Set("InputPatch"); - Interface = Set("interface"); - Line_ = Set("line"); - LineAdj = Set("lineadj"); - Linear = Set("linear"); - LineStream = Set("LineStream"); - Long = Set("long"); - Matrix = Set("matrix"); - Nointerpolation = Set("nointerpolation"); - Noperspective = Set("noperspective"); - Out = Set("out"); - OutputPatch = Set("OutputPatch"); - Packoffset = Set("packoffset"); - Point = Set("point"); - PointStream = Set("PointStream"); - Precise = Set("precise"); - Register = Set("register"); - Return = Set("return"); - RowMajor = Set("row_major"); - RWBuffer = Set("RWBuffer"); - RWByteAddressBuffer = Set("RWByteAddressBuffer"); - RWStructuredBuffer = Set("RWStructuredBuffer"); - Sample = Set("sample"); - Sampler = Set("sampler"); - SamplerComparisonState = Set("SamplerComparisonState"); - SamplerState = Set("SamplerState"); - Shared = Set("shared"); - Static = Set("static"); - Struct = Set("struct"); - StructuredBuffer = Set("StructuredBuffer"); - Switch = Set("switch"); + Buffer = Literal("Buffer"); + ByteAddressBuffer = Literal("ByteAddressBuffer"); + Break = Literal("break"); + Case = Literal("case"); + CBuffer = Literal("cbuffer"); + Centroid = Literal("centroid"); + Class = Literal("class"); + ColumnMajor = Literal("column_major"); + Const = Literal("const"); + ConsumeStructuredBuffer = Literal("ConsumeStructuredBuffer"); + Continue = Literal("continue"); + Default = Literal("default"); + Discard = Literal("discard"); + Do = Literal("do"); + Else = Literal("else"); + Extern = Literal("extern"); + For = Literal("for"); + Groupshared = Literal("groupshared"); + If = Literal("if"); + In = Literal("in"); + Inout = Literal("inout") | "in out"; + InputPatch = Literal("InputPatch"); + Interface = Literal("interface"); + Line_ = Literal("line"); + LineAdj = Literal("lineadj"); + Linear = Literal("linear"); + LineStream = Literal("LineStream"); + Long = Literal("long"); + Matrix = Literal("matrix"); + Nointerpolation = Literal("nointerpolation"); + Noperspective = Literal("noperspective"); + Out = Literal("out"); + OutputPatch = Literal("OutputPatch"); + Packoffset = Literal("packoffset"); + Point = Literal("point"); + PointStream = Literal("PointStream"); + Precise = Literal("precise"); + Register = Literal("register"); + Return = Literal("return"); + RowMajor = Literal("row_major"); + RWBuffer = Literal("RWBuffer"); + RWByteAddressBuffer = Literal("RWByteAddressBuffer"); + RWStructuredBuffer = Literal("RWStructuredBuffer"); + Sample = Literal("sample"); + Sampler = Literal("sampler"); + SamplerComparisonState = Literal("SamplerComparisonState"); + SamplerState = Literal("SamplerState"); + Shared = Literal("shared"); + Static = Literal("static"); + Struct = Literal("struct"); + StructuredBuffer = Literal("StructuredBuffer"); + Switch = Literal("switch"); TextureTypes = - (Set("Texture").NotFollowedBy("2DMS").Then(Set("1") | "2" | "3").Then("D").Then(Set("Array").Optional())) - | (Set("Texture2DMS").Then(Set("Array").Optional())) - | (Set("TextureCube").Then(Set("Array").Optional())); - Triangle = Set("triangle"); - TriangleAdj = Set("triangleadj"); - TriangleStream = Set("TriangleStream"); - Uniform = Set("uniform"); - Vector = Set("vector"); - Volatile = Set("volatile"); - Void = Set("void"); - While = Set("while"); - LeftParen = Set("("); - RightParen = Set(")"); - LeftBracket = Set("["); - RightBracket = Set("]"); - LeftBrace = Set("{"); - RightBrace = Set("}"); + (Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional())) + | (Literal("Texture2DMS").Then(Literal("Array").Optional())) + | (Literal("TextureCube").Then(Literal("Array").Optional())); + Triangle = Literal("triangle"); + TriangleAdj = Literal("triangleadj"); + TriangleStream = Literal("TriangleStream"); + Uniform = Literal("uniform"); + Vector = Literal("vector"); + Volatile = Literal("volatile"); + Void = Literal("void"); + While = Literal("while"); + LeftParen = Literal("("); + RightParen = Literal(")"); + LeftBracket = Literal("["); + RightBracket = Literal("]"); + LeftBrace = Literal("{"); + RightBrace = Literal("}"); - LeftShift = Set("<<"); - RightShift = Set(">>"); - Plus = Set("+"); - PlusPlus = Set("++"); - Minus = Set("-"); - MinusMinus = Set("--"); - Star = Set("*"); - Div = Set("/"); - Mod = Set("%"); - And = Set("&"); - Or = Set("|"); - AndAnd = Set("&&"); - OrOr = Set("||"); - Caret = Set("^"); - Not = Set("!"); - Tilde = Set("~"); - Equal = Set("=="); - NotEqual = Set("!="); - Less = Set("<"); - LessEqual = Set("<="); - Greater = Set(">"); - GreaterEqual = Set(">="); - Question = Set("?"); - Colon = Set(":"); - ColonColon = Set("::"); - Semi = Set(";"); - Comma = Set(","); - Assign = Set("="); - StarAssign = Set("*="); - DivAssign = Set("/="); - ModAssign = Set("%="); - PlusAssign = Set("+="); - MinusAssign = Set("-="); - LeftShiftAssign = Set("<<="); - RightShiftAssign = Set(">>="); - AndAssign = Set("&="); - XorAssign = Set("^="); - OrAssign = Set("|="); + LeftShift = Literal("<<"); + RightShift = Literal(">>"); + Plus = Literal("+"); + PlusPlus = Literal("++"); + Minus = Literal("-"); + MinusMinus = Literal("--"); + Star = Literal("*"); + Div = Literal("/"); + Mod = Literal("%"); + And = Literal("&"); + Or = Literal("|"); + AndAnd = Literal("&&"); + OrOr = Literal("||"); + Caret = Literal("^"); + Not = Literal("!"); + Tilde = Literal("~"); + Equal = Literal("=="); + NotEqual = Literal("!="); + Less = Literal("<"); + LessEqual = Literal("<="); + Greater = Literal(">"); + GreaterEqual = Literal(">="); + Question = Literal("?"); + Colon = Literal(":"); + ColonColon = Literal("::"); + Semi = Literal(";"); + Comma = Literal(","); + Assign = Literal("="); + StarAssign = Literal("*="); + DivAssign = Literal("/="); + ModAssign = Literal("%="); + PlusAssign = Literal("+="); + MinusAssign = Literal("-="); + LeftShiftAssign = Literal("<<="); + RightShiftAssign = Literal(">>="); + AndAssign = Literal("&="); + XorAssign = Literal("^="); + OrAssign = Literal("|="); - Dot = Set("."); - True = Set("true"); - False = Set("false"); + Dot = Literal("."); + True = Literal("true"); + False = Literal("false"); PreprocessorDirectiveName = - Set("define") - | "elif" - | "else" - | "endif" - | "error" - | "if" - | "ifdef" - | "ifndef" - | "include" - | "line" - | "pragma" - | "undef"; + Literal("define") + | Literal("elif") + | Literal("else") + | Literal("endif") + | Literal("error") + | Literal("if") + | Literal("ifdef") + | Literal("ifndef") + | Literal("include") + | Literal("line") + | Literal("pragma") + | Literal("undef"); } } From bfe2a77aaabc36192fbed1d8472c53ad1a67aa3b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 May 2022 13:40:56 +0200 Subject: [PATCH 0032/1182] Better performance for expressions --- src/SDSLParser/Program.cs | 2 +- src/SDSLParser/SDSL/Expressions.sdsl | 2 +- .../SDSLGrammar.Directives.Expression.cs | 86 +++++++++---------- 3 files changed, 41 insertions(+), 49 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 41a7da7eef..a0e2c1abb2 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -13,7 +13,7 @@ var s = new Stopwatch(); var match = sdslParser.Match("(8)"); s.Start(); -match = sdslParser.Match("(my_var--+5)"); +match = sdslParser.Match(shaderf); s.Stop(); Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index e440e5c842..25649df0a7 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1 @@ -3 \ No newline at end of file +(((3+(2*a ++)))) \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 8b460fb02d..25d2b24f8d 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -22,39 +22,37 @@ public SDSLGrammar UsingDirectiveExpression() public void CreateDirectiveExpressions() { - var parenMul = - LeftParen.Then(DirectiveMul).Then(RightParen); - var parenSum = - LeftParen.Then(DirectiveSum).Then(RightParen); - var parenTest = - LeftParen.Then(DirectiveTest).Then(RightParen); - - + var wsOrTabs = WhiteSpace.Or("\t").Repeat(0); + wsOrTabs.SkipUntil = true; var userDefinedTypes = Identifier.Except(Keywords); - var incrementOp = PlusPlus | MinusMinus; + var incrementOp = + PlusPlus + | MinusMinus; + // Identifier.Then(WhiteSpace.Repeat(0).Until("++",false,true)).Named("Something"); + var postfixIncrement = - (Identifier & "++").Named("Increment") - | (Identifier & "--").Named("Decrement"); + (Identifier & incrementOp.Named("IncrementOp")).Named("PostIncrement"); + var prefixIncrement = - ("++" & Identifier).Named("Increment") - | ("--" & Identifier).Named("Decrement"); - + (incrementOp.Named("IncrementOp") & Identifier).Named("PostIncrement"); + DirectiveIncrementExpr.Add( prefixIncrement | postfixIncrement ); + DirectiveIncrementExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); + + DirectiveTerm.Add( Literals | DirectiveIncrementExpr - // | DirectiveIncrementExpr - // | parenMul - // | parenSum - // | parenTest + | ParenDirectiveExpr.Named("ParenthesisExpr") ); - // | ParenDirectiveExpr; + // DirectiveTerm.SeparateChildrenBy(WhiteSpace.Repeat(0)); + var mulOp = Star | Div | Mod; @@ -63,14 +61,15 @@ public void CreateDirectiveExpressions() var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).Named("DirectiveModerand"); - - DirectiveMul.Add( - DirectiveTerm - (multiply | divide | moderand) + ParenDirectiveExpr + | DirectiveTerm - (multiply | divide | moderand) | multiply - (divide | moderand) | divide - moderand | moderand ); + DirectiveMul.SeparateChildrenBy(WhiteSpace.Repeat(0)); + var add = DirectiveMul.Then(Plus).Then(DirectiveSum).Named("DirectiveAdd"); @@ -79,10 +78,14 @@ public void CreateDirectiveExpressions() DirectiveSum.Add( - DirectiveMul.FollowedBy(incrementOp.Optional()) - ( add | subtract) + ParenDirectiveExpr + | postfixIncrement + | DirectiveMul.NotFollowedBy(Plus | Minus) //- (add | subtract) | add - subtract - | subtract + // | subtract ); + DirectiveSum.SeparateChildrenBy(WhiteSpace.Repeat(0)); + var greater = DirectiveSum.Then(Greater).Then(DirectiveTest).Named("DirectiveGreater"); var less = DirectiveSum.Then(Less).Then(DirectiveTest).Named("DirectiveLess"); @@ -90,42 +93,31 @@ public void CreateDirectiveExpressions() var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest).Named("DirectiveLessEqual"); DirectiveTest.Add( - DirectiveSum - (greater | less | greaterEqual | lessEqual) - | greater - (less | greaterEqual | lessEqual) - | less - (greaterEqual | lessEqual) - | greaterEqual - lessEqual + ParenDirectiveExpr + | DirectiveSum.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) + | greater.NotFollowedBy(Less | GreaterEqual | LessEqual) + | less.NotFollowedBy(GreaterEqual | LessEqual) + | greaterEqual.NotFollowedBy(LessEqual) | lessEqual ); + DirectiveTest.SeparateChildrenBy(WhiteSpace.Repeat(0)); + ParenDirectiveExpr.Add( LeftParen.Then(DirectiveExpr).Then(RightParen) ); + ParenDirectiveExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); var methodCall = Identifier.Then(LeftParen).Then(RightParen).Named("DirectiveMethodCall"); DirectiveExpr.Add( - DirectiveTest - | ParenDirectiveExpr.Named("ParenthesisExpr") - - // | methodCall + ParenDirectiveExpr + | DirectiveTest - methodCall + | methodCall ); - - - - - // IncrementDirectiveExpr ::= - // literal postfixUnaryOperator - // | Identifier postfixUnaryOperator - // | ParenDirectiveExpression postfixUnaryOperator - // | prefixUnaryOperator Identifier - postfixUnaryOperator - // | prefixUnaryOperator ParenDirectiveExpression - postfixUnaryOperator - - // directiveExpression ::= - // TestDirective - // | IncrementExpr - (MethodCallDirective) - // | MethodCallDirective + DirectiveExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); } } \ No newline at end of file From c064fa517a90111298fecca42ad75fb0351f9029 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 May 2022 20:54:42 +0200 Subject: [PATCH 0033/1182] Working on equality expressions --- src/SDSLParser/Program.cs | 2 +- src/SDSLParser/SDSL/Directive.sdsl | 3 +- src/SDSLParser/SDSL/Expressions.sdsl | 2 +- .../SDSLGrammar.Directives.Expression.cs | 74 +++++------ .../SDSLGrammar/SDSLGrammar.Directives.cs | 51 ++++--- .../SDSLGrammar/SDSLGrammar.Expression.cs | 125 ++++++++++++++++++ .../SDSLGrammar/SDSLGrammar.Literals.cs | 13 +- .../SDSLGrammar/SDSLGrammar.cs | 1 + 8 files changed, 198 insertions(+), 73 deletions(-) create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index a0e2c1abb2..4c77208fb7 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -9,7 +9,7 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingDirectiveExpression(); +var sdslParser = new SDSLGrammar().UsingPrimaryExpression(); var s = new Stopwatch(); var match = sdslParser.Match("(8)"); s.Start(); diff --git a/src/SDSLParser/SDSL/Directive.sdsl b/src/SDSLParser/SDSL/Directive.sdsl index ce4ac9bbb9..ee4bf3aa4d 100644 --- a/src/SDSLParser/SDSL/Directive.sdsl +++ b/src/SDSLParser/SDSL/Directive.sdsl @@ -1,2 +1 @@ -#if Mama == 5 - +#define qsdj true \ No newline at end of file diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 25649df0a7..1853c81d39 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1 @@ -(((3+(2*a ++)))) \ No newline at end of file +a == true \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 25d2b24f8d..494788e135 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -22,27 +22,26 @@ public SDSLGrammar UsingDirectiveExpression() public void CreateDirectiveExpressions() { - var wsOrTabs = WhiteSpace.Or("\t").Repeat(0); - wsOrTabs.SkipUntil = true; - var userDefinedTypes = Identifier.Except(Keywords); - + var ls = SingleLineWhiteSpace.Repeat(0); + var ls1 = SingleLineWhiteSpace.Repeat(1); + var incrementOp = PlusPlus | MinusMinus; - // Identifier.Then(WhiteSpace.Repeat(0).Until("++",false,true)).Named("Something"); + // Identifier.Then(SingleLineWhiteSpace.Until("++",false,true)).Named("Something"); var postfixIncrement = - (Identifier & incrementOp.Named("IncrementOp")).Named("PostIncrement"); + Identifier.Then(incrementOp.Named("IncrementOp")); var prefixIncrement = - (incrementOp.Named("IncrementOp") & Identifier).Named("PostIncrement"); + incrementOp.Named("IncrementOp").Then(Identifier); DirectiveIncrementExpr.Add( - prefixIncrement - | postfixIncrement + prefixIncrement.SeparatedBy(ls) + | postfixIncrement.SeparatedBy(ls) ); - DirectiveIncrementExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); + // DirectiveIncrementExpr.SeparateChildrenBy(SingleLineWhiteSpace); @@ -51,73 +50,68 @@ public void CreateDirectiveExpressions() | DirectiveIncrementExpr | ParenDirectiveExpr.Named("ParenthesisExpr") ); - // DirectiveTerm.SeparateChildrenBy(WhiteSpace.Repeat(0)); - - - var mulOp = Star | Div | Mod; - var multiply = DirectiveTerm.Then(Star).Then(DirectiveMul).Named("DirectiveMultiply"); - var divide = DirectiveTerm.Then(Div).Then(DirectiveMul).Named("DirectiveDivide"); - var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).Named("DirectiveModerand"); + var multiply = DirectiveTerm.Then(Star).Then(DirectiveMul).SeparatedBy(ls); + var divide = DirectiveTerm.Then(Div).Then(DirectiveMul).SeparatedBy(ls); + var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).SeparatedBy(ls); DirectiveMul.Add( ParenDirectiveExpr | DirectiveTerm - (multiply | divide | moderand) - | multiply - (divide | moderand) - | divide - moderand - | moderand + | (multiply - (divide | moderand)).Named("DirectiveMult") + | (divide - moderand).Named("DirectiveDiv") + | moderand.Named("DirectiveMod") ); - DirectiveMul.SeparateChildrenBy(WhiteSpace.Repeat(0)); + // DirectiveMul.SeparateChildrenBy(SingleLineWhiteSpace); - var add = DirectiveMul.Then(Plus).Then(DirectiveSum).Named("DirectiveAdd"); - var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).Named("DirectiveSubtract"); + var add = DirectiveMul.Then(Plus).Then(DirectiveSum).SeparatedBy(ls); + var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).SeparatedBy(ls); DirectiveSum.Add( ParenDirectiveExpr - | postfixIncrement + | postfixIncrement.SeparatedBy(ls) | DirectiveMul.NotFollowedBy(Plus | Minus) //- (add | subtract) - | add - subtract - // | subtract + | (add - subtract).Named("DirectiveAdd") + | subtract.Named("DirectiveSubtract") ); - DirectiveSum.SeparateChildrenBy(WhiteSpace.Repeat(0)); + // DirectiveSum.SeparateChildrenBy(SingleLineWhiteSpace); - var greater = DirectiveSum.Then(Greater).Then(DirectiveTest).Named("DirectiveGreater"); - var less = DirectiveSum.Then(Less).Then(DirectiveTest).Named("DirectiveLess"); - var greaterEqual = DirectiveSum.Then(GreaterEqual).Then(DirectiveTest).Named("DirectiveGreaterEqual"); - var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest).Named("DirectiveLessEqual"); + var greater = DirectiveSum.Then(Greater).Then(DirectiveTest); + var less = DirectiveSum.Then(Less).Then(DirectiveTest); + var greaterEqual = DirectiveSum.Then(GreaterEqual).Then(DirectiveTest); + var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest); DirectiveTest.Add( ParenDirectiveExpr | DirectiveSum.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) - | greater.NotFollowedBy(Less | GreaterEqual | LessEqual) - | less.NotFollowedBy(GreaterEqual | LessEqual) - | greaterEqual.NotFollowedBy(LessEqual) - | lessEqual + | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveLess") + | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveGreater") + | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("DirectiveLessEqual") + | lessEqual.SeparatedBy(ls).Named("DirectiveGreaterEqual") ); - DirectiveTest.SeparateChildrenBy(WhiteSpace.Repeat(0)); + // DirectiveTest.SeparateChildrenBy(SingleLineWhiteSpace); ParenDirectiveExpr.Add( - LeftParen.Then(DirectiveExpr).Then(RightParen) + LeftParen.Then(DirectiveExpr).Then(RightParen).SeparatedBy(ls) ); - ParenDirectiveExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); - var methodCall = Identifier.Then(LeftParen).Then(RightParen).Named("DirectiveMethodCall"); + var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("DirectiveMethodCall"); DirectiveExpr.Add( ParenDirectiveExpr | DirectiveTest - methodCall | methodCall ); - DirectiveExpr.SeparateChildrenBy(WhiteSpace.Repeat(0)); + // DirectiveExpr.SeparateChildrenBy(SingleLineWhiteSpace); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs index 2e860a818b..2b1b682c48 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs @@ -5,40 +5,39 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { - private CharTerminal Hash = Set("#"); - - private SequenceParser HashIf = new(); - private SequenceParser HashIfDef = new(); - private SequenceParser HashIfNDef = new(); - - private SequenceParser HashElse = new(); - private SequenceParser HashElif = new(); - private SequenceParser HashEndIf = new(); - - - //TODO: Identifier Parser doesn't work here ? public SequenceParser IfDefDirective = new(); public SequenceParser IfNDefDirective = new(); + public AlternativeParser Directives = new(); + public SDSLGrammar UsingIfDefDirective() { - Inner = IfDefDirective; + Inner = Directives; return this; } public void CreateDirectives() { - - HashIf = Hash.Then("if").WithName("HashIf"); - HashIfDef = Hash.Then("ifdef").WithName("HashIfDef"); - HashIfNDef = Hash.Then("ifndef").WithName("HashIfNDef"); - - HashElse = Hash.Then("else").WithName("HashElse"); - HashElif = Hash.Then("elif").WithName("HashElif"); - HashEndIf = Hash.Then("endif").WithName("HashEndIf"); - - IfDefDirective = HashIfDef.WithName("directive").Then(SingleLineWhiteSpace).Then(Identifier).WithName("IfDef"); - IfNDefDirective = HashIfNDef.WithName("directive").Then(SingleLineWhiteSpace).Then(Identifier).WithName("IfNDef"); - + var ls = SingleLineWhiteSpace.Repeat(0); + var ls1 = SingleLineWhiteSpace.Repeat(1); + var hash = Literal("#"); + var hashIfNDef = Literal("ifndef").Named("hashifndef"); + var hashIfDef = Literal("ifdef").Named("hashifdef"); + var hashIf = Literal("if").Named("hashif"); + var hashEndIf = Literal("endif").Named("HashEndIf"); + var hashElse = Literal("else").Named("HashElse"); + var hashElif = Literal("elif").Named("HashElif"); + var hashDefine = Literal("define").Named("HashElif"); + + // TODO : add if and elif + Directives.Add( + hash + .Then( + hashElse.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).Named("DirectiveElse") + | hashEndIf.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).Named("DirectiveEnd") + | (hashIfDef - (hashIfNDef | hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).Named("DirectiveIfDef") + | (hashIfNDef - (hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).Named("DirectiveIfNDef") + | hashDefine.Then(Identifier).Then(Literals).SeparatedBy(ls1).Named("DirectiveDefine") + ) + ); } - } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs new file mode 100644 index 0000000000..29d3b2149f --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs @@ -0,0 +1,125 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser TermExpression = new(); + public AlternativeParser MulExpression = new(); + public AlternativeParser SumExpression = new(); + public AlternativeParser TestExpression = new(); + public AlternativeParser IncrementExpression = new(); + public AlternativeParser ParenExpression = new(); + public AlternativeParser EqualsExpression = new(); + public AlternativeParser PrimaryExpression = new(); + + + public SDSLGrammar UsingPrimaryExpression() + { + Inner = PrimaryExpression; + return this; + } + + public void CreateExpressions() + { + var ls = WhiteSpace.Repeat(0); + var ls1 = WhiteSpace.Repeat(1); + + var incrementOp = + PlusPlus + | MinusMinus; + + // Identifier.Then(SingleLineWhiteSpace.Until("++",false,true)).Named("Something"); + + var postfixIncrement = + Identifier.Then(incrementOp.Named("IncrementOp")); + + var prefixIncrement = + incrementOp.Named("IncrementOp").Then(Identifier); + + IncrementExpression.Add( + prefixIncrement.SeparatedBy(ls).Named("PreIncrement") + | postfixIncrement.SeparatedBy(ls).Named("PostIncrement") + ); + + TermExpression.Add( + Literals + | Identifier + | IncrementExpression - (Literals | Identifier).FollowedBy(Literal("==") | "!=") + | ParenExpression.Named("ParenthesisExpr") + ); + + var multiply = TermExpression.Then(Star).Then(MulExpression).SeparatedBy(ls); + var divide = TermExpression.Then(Div).Then(MulExpression).SeparatedBy(ls); + var moderand = TermExpression.Then(Mod).Then(MulExpression).SeparatedBy(ls); + + MulExpression.Add( + TermExpression - (multiply | divide | moderand) + | (multiply - (divide | moderand)).Named("MultExpression") + | (divide - moderand).Named("DivExpression") + | moderand.Named("ModExpression") + ); + + + var add = MulExpression.Then(Plus).Then(SumExpression).SeparatedBy(ls); + var subtract = MulExpression.Then(Minus).Then(SumExpression).SeparatedBy(ls); + var incrementSum = IncrementExpression.Then(Plus | Minus).Then(SumExpression).SeparatedBy(ls); + // var postfixAdd = postfixIncrement.Then() + SumExpression.Add( + ParenExpression + | incrementSum + | MulExpression.NotFollowedBy(Plus | Minus) //- (add | subtract) + | (add - (subtract | postfixIncrement)).Named("AddExpression") + | subtract.Named("SubtractExpression") + ); + + + var greater = SumExpression.Then(Greater).Then(TestExpression); + var less = SumExpression.Then(Less).Then(TestExpression); + var greaterEqual = SumExpression.Then(GreaterEqual).Then(TestExpression); + var lessEqual = SumExpression.Then(LessEqual).Then(TestExpression); + + TestExpression.Add( + ParenExpression + | SumExpression.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) + | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("LessExpression") + | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("GreaterExpression") + | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("LessEqualExpression") + | lessEqual.SeparatedBy(ls).Named("GreaterEqualExpression") + ); + + var equalsExp = TestExpression.Then(Literal("==").Named("Operator")).Then(BooleanTerm).SeparatedBy(ls); + var notEqualExp = TestExpression.Then(Literal("!=").Named("Operator")).Then(BooleanTerm).SeparatedBy(ls); + + EqualsExpression.Add( + // ParenExpression + equalsExp.Named("EqualsExpression") + // | notEqualExp.Named("NotEqualsExpression") + // | TestExpression.NotFollowedBy(Literal("==") | "!=") + + ); + + + + ParenExpression.Add( + LeftParen.Then(PrimaryExpression).Then(RightParen)//.SeparatedBy(ls) + ); + + + + // var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); + + PrimaryExpression.Add( + ParenExpression + | EqualsExpression + // | methodCall + ); + + var assignExpression = + Identifier.Then(Equal).Then(PrimaryExpression); + + + // ExprExpression.SeparateChildrenBy(SingleLineWhiteSpace); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index 735082f0ed..fb0f2f9e28 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -2,6 +2,8 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; +using EtoParser = Eto.Parse.Parser; + namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { @@ -12,20 +14,24 @@ public partial class SDSLGrammar : Grammar public SequenceParser BlockComment = new(); public StringParser StringLiteral = new(); - public SequenceParser Identifier = new(); + public EtoParser Identifier; public NumberParser IntegerLiteral = new(); public NumberParser FloatLiteral = new(); public HexDigitTerminal HexDigits = new(); public SequenceParser HexaDecimalLiteral = new(); + + public BooleanTerminal BooleanTerm = new(); public AlternativeParser Literals = new(); - public void UsingLiterals() + public SDSLGrammar UsingLiterals() { Inner = Literals; + return this; } public void CreateLiterals() { + Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); IntegerSuffix = Literal("u") | Literal("l") @@ -42,7 +48,6 @@ public void CreateLiterals() BlockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); StringLiteral = new StringParser().WithName("StringLiteral"); - Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); HexDigits = new(); @@ -55,6 +60,8 @@ public void CreateLiterals() FloatLiteral.Then(FloatSuffix.Optional().Named("suffix")).Named("FloatLiteral"); // | IntegerLiteral.Then(IntegerSuffix); + BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; + Literals.Add( floats - ints | ints diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs index 1380836c58..f514c02488 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs @@ -19,5 +19,6 @@ public void CreateAll() CreateLiterals(); CreateDirectives(); CreateDirectiveExpressions(); + CreateExpressions(); } } From 24afc3027777e7935cdbf286bb45e214471d949e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 2 May 2022 00:27:49 +0200 Subject: [PATCH 0034/1182] Finished Directive --- src/SDSLParser/Program.cs | 4 +- src/SDSLParser/SDSL/Directive.sdsl | 2 +- .../SDSLGrammar.Directives.Expression.cs | 51 +++++++++++-------- .../SDSLGrammar/SDSLGrammar.Directives.cs | 27 +++++----- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 4c77208fb7..95fa5c5412 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,12 +4,12 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); +var shaderf = File.ReadAllText("./SDSL/Directive.sdsl"); // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingPrimaryExpression(); +var sdslParser = new SDSLGrammar().UsingDirectives(); var s = new Stopwatch(); var match = sdslParser.Match("(8)"); s.Start(); diff --git a/src/SDSLParser/SDSL/Directive.sdsl b/src/SDSLParser/SDSL/Directive.sdsl index ee4bf3aa4d..da788fd066 100644 --- a/src/SDSLParser/SDSL/Directive.sdsl +++ b/src/SDSLParser/SDSL/Directive.sdsl @@ -1 +1 @@ -#define qsdj true \ No newline at end of file +#else \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 494788e135..19e22c68a4 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -10,9 +10,10 @@ public partial class SDSLGrammar : Grammar public AlternativeParser DirectiveSum = new(); public AlternativeParser DirectiveTest = new(); - public AlternativeParser DirectiveExpr = new(); public AlternativeParser DirectiveIncrementExpr = new(); public AlternativeParser ParenDirectiveExpr = new(); + public AlternativeParser DirectiveEquals = new(); + public AlternativeParser DirectiveExpr = new(); public SDSLGrammar UsingDirectiveExpression() { @@ -29,8 +30,6 @@ public void CreateDirectiveExpressions() PlusPlus | MinusMinus; - // Identifier.Then(SingleLineWhiteSpace.Until("++",false,true)).Named("Something"); - var postfixIncrement = Identifier.Then(incrementOp.Named("IncrementOp")); @@ -41,13 +40,12 @@ public void CreateDirectiveExpressions() prefixIncrement.SeparatedBy(ls) | postfixIncrement.SeparatedBy(ls) ); - // DirectiveIncrementExpr.SeparateChildrenBy(SingleLineWhiteSpace); - - + DirectiveTerm.Add( Literals - | DirectiveIncrementExpr + | Identifier + | DirectiveIncrementExpr //- (Literals | Identifier).FollowedBy(Literal("==") | "!=") | ParenDirectiveExpr.Named("ParenthesisExpr") ); @@ -57,11 +55,11 @@ public void CreateDirectiveExpressions() DirectiveMul.Add( - ParenDirectiveExpr - | DirectiveTerm - (multiply | divide | moderand) + DirectiveTerm - (multiply | divide | moderand) | (multiply - (divide | moderand)).Named("DirectiveMult") | (divide - moderand).Named("DirectiveDiv") | moderand.Named("DirectiveMod") + | ParenDirectiveExpr ); // DirectiveMul.SeparateChildrenBy(SingleLineWhiteSpace); @@ -73,14 +71,12 @@ public void CreateDirectiveExpressions() DirectiveSum.Add( - ParenDirectiveExpr - | postfixIncrement.SeparatedBy(ls) + postfixIncrement.SeparatedBy(ls) | DirectiveMul.NotFollowedBy(Plus | Minus) //- (add | subtract) | (add - subtract).Named("DirectiveAdd") | subtract.Named("DirectiveSubtract") ); - // DirectiveSum.SeparateChildrenBy(SingleLineWhiteSpace); - + var greater = DirectiveSum.Then(Greater).Then(DirectiveTest); var less = DirectiveSum.Then(Less).Then(DirectiveTest); @@ -88,19 +84,30 @@ public void CreateDirectiveExpressions() var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest); DirectiveTest.Add( - ParenDirectiveExpr - | DirectiveSum.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) + DirectiveSum.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveLess") | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveGreater") | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("DirectiveLessEqual") | lessEqual.SeparatedBy(ls).Named("DirectiveGreaterEqual") ); - // DirectiveTest.SeparateChildrenBy(SingleLineWhiteSpace); - - + var dEquals = + (BooleanTerm | DirectiveTerm) + .Then(Literal("==")) + .Then( + BooleanTerm + | DirectiveEquals + ) + .SeparatedBy(ls).Named("Equals"); + + + DirectiveEquals.Add( + DirectiveTest - dEquals + | dEquals + ); ParenDirectiveExpr.Add( - LeftParen.Then(DirectiveExpr).Then(RightParen).SeparatedBy(ls) + LeftParen.Then(ParenDirectiveExpr).Then(RightParen).SeparatedBy(ls) + | LeftParen.Then(DirectiveExpr).Then(RightParen).SeparatedBy(ls) ); @@ -108,9 +115,9 @@ public void CreateDirectiveExpressions() var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("DirectiveMethodCall"); DirectiveExpr.Add( - ParenDirectiveExpr - | DirectiveTest - methodCall - | methodCall + DirectiveEquals + // - methodCall + // | methodCall ); // DirectiveExpr.SeparateChildrenBy(SingleLineWhiteSpace); } diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs index 2b1b682c48..bb19bf33ba 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs @@ -5,12 +5,19 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { + public SequenceParser IfDirective = new(); + public SequenceParser ElseDirective = new(); + public SequenceParser ElifDirective = new(); + public SequenceParser DefineDirective = new(); + public SequenceParser EndIfDirective = new(); + + public SequenceParser IfDefDirective = new(); public SequenceParser IfNDefDirective = new(); public AlternativeParser Directives = new(); - public SDSLGrammar UsingIfDefDirective() + public SDSLGrammar UsingDirectives() { Inner = Directives; return this; @@ -28,16 +35,12 @@ public void CreateDirectives() var hashElif = Literal("elif").Named("HashElif"); var hashDefine = Literal("define").Named("HashElif"); - // TODO : add if and elif - Directives.Add( - hash - .Then( - hashElse.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).Named("DirectiveElse") - | hashEndIf.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).Named("DirectiveEnd") - | (hashIfDef - (hashIfNDef | hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).Named("DirectiveIfDef") - | (hashIfNDef - (hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).Named("DirectiveIfNDef") - | hashDefine.Then(Identifier).Then(Literals).SeparatedBy(ls1).Named("DirectiveDefine") - ) - ); + IfDirective = hashIf.Then(DirectiveExpr).SeparatedBy(ls1).WithName("DirectiveDefine"); + ElseDirective = hashElse.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveElse"); + EndIfDirective = hashEndIf.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveEnd"); + IfDefDirective = (hashIfDef - (hashIfNDef | hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfDef"); + IfNDefDirective = (hashIfNDef - (hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfNDef"); + DefineDirective = hashDefine.Then(Identifier).Then(DirectiveExpr).SeparatedBy(ls1).WithName("DirectiveDefine"); + } } \ No newline at end of file From aa766285e8ea9ed54f39074ed0e951ee624fad01 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 2 May 2022 00:29:17 +0200 Subject: [PATCH 0035/1182] Added difference --- .../SDSLGrammar.Directives.Expression.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 19e22c68a4..cde717016e 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -61,8 +61,6 @@ public void CreateDirectiveExpressions() | moderand.Named("DirectiveMod") | ParenDirectiveExpr ); - // DirectiveMul.SeparateChildrenBy(SingleLineWhiteSpace); - var add = DirectiveMul.Then(Plus).Then(DirectiveSum).SeparatedBy(ls); @@ -91,13 +89,13 @@ public void CreateDirectiveExpressions() | lessEqual.SeparatedBy(ls).Named("DirectiveGreaterEqual") ); var dEquals = - (BooleanTerm | DirectiveTerm) - .Then(Literal("==")) - .Then( - BooleanTerm - | DirectiveEquals - ) - .SeparatedBy(ls).Named("Equals"); + (BooleanTerm | DirectiveTerm) + .Then(Literal("==") | "!=") + .Then( + BooleanTerm + | DirectiveEquals + ) + .SeparatedBy(ls).Named("Equals"); DirectiveEquals.Add( From 87615816fbc7c1caaff271b0a25bef1b097721a6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 2 May 2022 00:47:52 +0200 Subject: [PATCH 0036/1182] Primary expressions --- src/SDSLParser/Program.cs | 4 +- .../SDSLGrammar.Directives.Expression.cs | 1 - .../SDSLGrammar/SDSLGrammar.Expression.cs | 70 +++++++++---------- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 95fa5c5412..4c77208fb7 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,12 +4,12 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/Directive.sdsl"); +var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingDirectives(); +var sdslParser = new SDSLGrammar().UsingPrimaryExpression(); var s = new Stopwatch(); var match = sdslParser.Match("(8)"); s.Start(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index cde717016e..79489d1736 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -117,6 +117,5 @@ public void CreateDirectiveExpressions() // - methodCall // | methodCall ); - // DirectiveExpr.SeparateChildrenBy(SingleLineWhiteSpace); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs index 29d3b2149f..11afde508e 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs @@ -9,11 +9,11 @@ public partial class SDSLGrammar : Grammar public AlternativeParser MulExpression = new(); public AlternativeParser SumExpression = new(); public AlternativeParser TestExpression = new(); - public AlternativeParser IncrementExpression = new(); + + public AlternativeParser IncrementExprExpression = new(); public AlternativeParser ParenExpression = new(); public AlternativeParser EqualsExpression = new(); public AlternativeParser PrimaryExpression = new(); - public SDSLGrammar UsingPrimaryExpression() { @@ -23,54 +23,55 @@ public SDSLGrammar UsingPrimaryExpression() public void CreateExpressions() { - var ls = WhiteSpace.Repeat(0); - var ls1 = WhiteSpace.Repeat(1); + var ls = SingleLineWhiteSpace.Repeat(0); + var ls1 = SingleLineWhiteSpace.Repeat(1); var incrementOp = PlusPlus | MinusMinus; - // Identifier.Then(SingleLineWhiteSpace.Until("++",false,true)).Named("Something"); - var postfixIncrement = Identifier.Then(incrementOp.Named("IncrementOp")); var prefixIncrement = incrementOp.Named("IncrementOp").Then(Identifier); - IncrementExpression.Add( - prefixIncrement.SeparatedBy(ls).Named("PreIncrement") - | postfixIncrement.SeparatedBy(ls).Named("PostIncrement") + IncrementExprExpression.Add( + prefixIncrement.SeparatedBy(ls) + | postfixIncrement.SeparatedBy(ls) ); + TermExpression.Add( Literals | Identifier - | IncrementExpression - (Literals | Identifier).FollowedBy(Literal("==") | "!=") + | IncrementExprExpression //- (Literals | Identifier).FollowedBy(Literal("==") | "!=") | ParenExpression.Named("ParenthesisExpr") ); var multiply = TermExpression.Then(Star).Then(MulExpression).SeparatedBy(ls); var divide = TermExpression.Then(Div).Then(MulExpression).SeparatedBy(ls); var moderand = TermExpression.Then(Mod).Then(MulExpression).SeparatedBy(ls); + MulExpression.Add( TermExpression - (multiply | divide | moderand) | (multiply - (divide | moderand)).Named("MultExpression") | (divide - moderand).Named("DivExpression") | moderand.Named("ModExpression") + | ParenExpression ); var add = MulExpression.Then(Plus).Then(SumExpression).SeparatedBy(ls); var subtract = MulExpression.Then(Minus).Then(SumExpression).SeparatedBy(ls); - var incrementSum = IncrementExpression.Then(Plus | Minus).Then(SumExpression).SeparatedBy(ls); - // var postfixAdd = postfixIncrement.Then() + + + SumExpression.Add( - ParenExpression - | incrementSum + postfixIncrement.SeparatedBy(ls) | MulExpression.NotFollowedBy(Plus | Minus) //- (add | subtract) - | (add - (subtract | postfixIncrement)).Named("AddExpression") + | (add - subtract).Named("AddExpression") | subtract.Named("SubtractExpression") ); @@ -81,45 +82,40 @@ public void CreateExpressions() var lessEqual = SumExpression.Then(LessEqual).Then(TestExpression); TestExpression.Add( - ParenExpression - | SumExpression.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) + SumExpression.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("LessExpression") | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("GreaterExpression") | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("LessEqualExpression") | lessEqual.SeparatedBy(ls).Named("GreaterEqualExpression") ); - - var equalsExp = TestExpression.Then(Literal("==").Named("Operator")).Then(BooleanTerm).SeparatedBy(ls); - var notEqualExp = TestExpression.Then(Literal("!=").Named("Operator")).Then(BooleanTerm).SeparatedBy(ls); + var equals = + (BooleanTerm | TermExpression) + .Then(Literal("==") | "!=") + .Then( + BooleanTerm + | EqualsExpression + ) + .SeparatedBy(ls).Named("Equals"); + EqualsExpression.Add( - // ParenExpression - equalsExp.Named("EqualsExpression") - // | notEqualExp.Named("NotEqualsExpression") - // | TestExpression.NotFollowedBy(Literal("==") | "!=") - + TestExpression - equals + | equals ); - - ParenExpression.Add( - LeftParen.Then(PrimaryExpression).Then(RightParen)//.SeparatedBy(ls) + LeftParen.Then(ParenExpression).Then(RightParen).SeparatedBy(ls) + | LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) ); - // var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); + var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); PrimaryExpression.Add( - ParenExpression - | EqualsExpression + EqualsExpression + // - methodCall // | methodCall ); - - var assignExpression = - Identifier.Then(Equal).Then(PrimaryExpression); - - - // ExprExpression.SeparateChildrenBy(SingleLineWhiteSpace); } } \ No newline at end of file From c6a6940f5efbb1697e605bd2046a4017e8827b74 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 2 May 2022 21:14:55 +0200 Subject: [PATCH 0037/1182] Added method call --- src/SDSLParser/Program.cs | 5 +- src/SDSLParser/SDSL/Expressions.sdsl | 7 +- .../SDSLGrammar.Directives.Expression.cs | 90 +++++++------- .../SDSLGrammar/SDSLGrammar.Expression.cs | 115 +++++++++--------- .../SDSLGrammar/SDSLGrammar.Statements.cs | 31 +++++ .../SDSLGrammar/SDSLGrammar.cs | 1 + 6 files changed, 144 insertions(+), 105 deletions(-) create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index 4c77208fb7..bdd8e848fb 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -11,11 +11,12 @@ var tokens = StrideGrammar.HlslGrammar("expression"); var sdslParser = new SDSLGrammar().UsingPrimaryExpression(); var s = new Stopwatch(); -var match = sdslParser.Match("(8)"); +var match2 = sdslParser.Match(shaderf); s.Start(); -match = sdslParser.Match(shaderf); +var match = sdslParser.Match(shaderf); s.Stop(); + Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 1853c81d39..a911c81937 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1,6 @@ -a == true \ No newline at end of file +My_Method( + 1, + true, + a++, + 5>4 +); \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 79489d1736..e3ee93e4ab 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -8,6 +8,8 @@ public partial class SDSLGrammar : Grammar public AlternativeParser DirectiveTerm = new(); public AlternativeParser DirectiveMul = new(); public AlternativeParser DirectiveSum = new(); + public AlternativeParser DirectiveShift = new(); + public AlternativeParser DirectiveTest = new(); public AlternativeParser DirectiveIncrementExpr = new(); @@ -26,86 +28,80 @@ public void CreateDirectiveExpressions() var ls = SingleLineWhiteSpace.Repeat(0); var ls1 = SingleLineWhiteSpace.Repeat(1); + var incrementOp = - PlusPlus - | MinusMinus; + Literal("++").Named("PlusPlus") + | Literal("--").Named("MinusMinus"); var postfixIncrement = - Identifier.Then(incrementOp.Named("IncrementOp")); - + Identifier.Then(incrementOp.Repeat(0,1)).SeparatedBy(ls); var prefixIncrement = - incrementOp.Named("IncrementOp").Then(Identifier); + incrementOp.Named("IncrementOp").Then(Identifier).SeparatedBy(ls); + + DirectiveIncrementExpr.Add( - prefixIncrement.SeparatedBy(ls) - | postfixIncrement.SeparatedBy(ls) + prefixIncrement.Named("PreIncrement") + | postfixIncrement ); DirectiveTerm.Add( Literals - | Identifier - | DirectiveIncrementExpr //- (Literals | Identifier).FollowedBy(Literal("==") | "!=") - | ParenDirectiveExpr.Named("ParenthesisExpr") + | IncrementExpression + | ParenExpression.Named("ParenthesisExpr") ); - var multiply = DirectiveTerm.Then(Star).Then(DirectiveMul).SeparatedBy(ls); - var divide = DirectiveTerm.Then(Div).Then(DirectiveMul).SeparatedBy(ls); - var moderand = DirectiveTerm.Then(Mod).Then(DirectiveMul).SeparatedBy(ls); - - + var multiply = TermExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); DirectiveMul.Add( - DirectiveTerm - (multiply | divide | moderand) - | (multiply - (divide | moderand)).Named("DirectiveMult") - | (divide - moderand).Named("DirectiveDiv") - | moderand.Named("DirectiveMod") - | ParenDirectiveExpr + multiply.Named("Multiplication") + | TermExpression ); - - var add = DirectiveMul.Then(Plus).Then(DirectiveSum).SeparatedBy(ls); - var subtract = DirectiveMul.Then(Minus).Then(DirectiveSum).SeparatedBy(ls); - - - + var sumOp = (Plus - PlusPlus) | (Minus - MinusMinus); + var add = MulExpression.Then(sumOp).Then(SumExpression).SeparatedBy(ls); DirectiveSum.Add( - postfixIncrement.SeparatedBy(ls) - | DirectiveMul.NotFollowedBy(Plus | Minus) //- (add | subtract) - | (add - subtract).Named("DirectiveAdd") - | subtract.Named("DirectiveSubtract") + add.Named("Addition") + | MulExpression + ); + + var shiftOp = LeftShift | RightShift; + var shift = + SumExpression.Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ls); + + DirectiveShift.Add( + SumExpression + | shift.Named("ShiftExpression") ); - var greater = DirectiveSum.Then(Greater).Then(DirectiveTest); - var less = DirectiveSum.Then(Less).Then(DirectiveTest); - var greaterEqual = DirectiveSum.Then(GreaterEqual).Then(DirectiveTest); - var lessEqual = DirectiveSum.Then(LessEqual).Then(DirectiveTest); + var testOp = (Less - LeftShift) | LessEqual | (Greater - RightShift) | GreaterEqual; + var test = ShiftExpression.Then(testOp).Then(TestExpression).SeparatedBy(ls); DirectiveTest.Add( - DirectiveSum.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) - | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveLess") - | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("DirectiveGreater") - | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("DirectiveLessEqual") - | lessEqual.SeparatedBy(ls).Named("DirectiveGreaterEqual") + test.Named("TestExpression") + | ShiftExpression ); - var dEquals = - (BooleanTerm | DirectiveTerm) - .Then(Literal("==") | "!=") + var equality = + Literal("==").Named("Equals") + | Literal("!=").Named("NotEquals"); + var equals = + (BooleanTerm | TermExpression) + .Then(equality) .Then( BooleanTerm - | DirectiveEquals + | EqualsExpression ) .SeparatedBy(ls).Named("Equals"); DirectiveEquals.Add( - DirectiveTest - dEquals - | dEquals + TestExpression + | equals ); ParenDirectiveExpr.Add( - LeftParen.Then(ParenDirectiveExpr).Then(RightParen).SeparatedBy(ls) - | LeftParen.Then(DirectiveExpr).Then(RightParen).SeparatedBy(ls) + LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) ); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs index 11afde508e..f415705bb0 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs @@ -8,114 +8,119 @@ public partial class SDSLGrammar : Grammar public AlternativeParser TermExpression = new(); public AlternativeParser MulExpression = new(); public AlternativeParser SumExpression = new(); + public AlternativeParser ShiftExpression = new(); + public AlternativeParser TestExpression = new(); - public AlternativeParser IncrementExprExpression = new(); + public AlternativeParser IncrementExpression = new(); public AlternativeParser ParenExpression = new(); public AlternativeParser EqualsExpression = new(); public AlternativeParser PrimaryExpression = new(); public SDSLGrammar UsingPrimaryExpression() { - Inner = PrimaryExpression; + Inner = PrimaryExpression.Then(";"); return this; } public void CreateExpressions() { - var ls = SingleLineWhiteSpace.Repeat(0); - var ls1 = SingleLineWhiteSpace.Repeat(1); + var ls = WhiteSpace.Repeat(0); + var ls1 = WhiteSpace.Repeat(1); + var incrementOp = - PlusPlus - | MinusMinus; + Literal("++").Named("PlusPlus") + | Literal("--").Named("MinusMinus"); var postfixIncrement = - Identifier.Then(incrementOp.Named("IncrementOp")); - + Identifier.Then(incrementOp.Repeat(0,1)).SeparatedBy(ls); var prefixIncrement = - incrementOp.Named("IncrementOp").Then(Identifier); + incrementOp.Named("IncrementOp").Then(Identifier).SeparatedBy(ls); + - IncrementExprExpression.Add( - prefixIncrement.SeparatedBy(ls) - | postfixIncrement.SeparatedBy(ls) + + IncrementExpression.Add( + prefixIncrement.Named("PreIncrement") + | postfixIncrement ); TermExpression.Add( Literals - | Identifier - | IncrementExprExpression //- (Literals | Identifier).FollowedBy(Literal("==") | "!=") + | IncrementExpression | ParenExpression.Named("ParenthesisExpr") ); - var multiply = TermExpression.Then(Star).Then(MulExpression).SeparatedBy(ls); - var divide = TermExpression.Then(Div).Then(MulExpression).SeparatedBy(ls); - var moderand = TermExpression.Then(Mod).Then(MulExpression).SeparatedBy(ls); - - + var multiply = TermExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); MulExpression.Add( - TermExpression - (multiply | divide | moderand) - | (multiply - (divide | moderand)).Named("MultExpression") - | (divide - moderand).Named("DivExpression") - | moderand.Named("ModExpression") - | ParenExpression + multiply.Named("Multiplication") + | TermExpression ); - - - var add = MulExpression.Then(Plus).Then(SumExpression).SeparatedBy(ls); - var subtract = MulExpression.Then(Minus).Then(SumExpression).SeparatedBy(ls); - - + var parenMulExpr = + LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ls); + + var sumOp = (Plus - PlusPlus) | (Minus - MinusMinus); + var add = (parenMulExpr | MulExpression).Then(sumOp).Then(SumExpression).SeparatedBy(ls); SumExpression.Add( - postfixIncrement.SeparatedBy(ls) - | MulExpression.NotFollowedBy(Plus | Minus) //- (add | subtract) - | (add - subtract).Named("AddExpression") - | subtract.Named("SubtractExpression") + add.Named("Addition") + | MulExpression + ); + + var parenSumExpr = + LeftParen.Then(SumExpression).Then(RightParen).SeparatedBy(ls); + + var shiftOp = LeftShift | RightShift; + var shift = + (parenSumExpr | SumExpression).Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ls); + + ShiftExpression.Add( + shift.Named("ShiftExpression") + | SumExpression ); - var greater = SumExpression.Then(Greater).Then(TestExpression); - var less = SumExpression.Then(Less).Then(TestExpression); - var greaterEqual = SumExpression.Then(GreaterEqual).Then(TestExpression); - var lessEqual = SumExpression.Then(LessEqual).Then(TestExpression); + var testOp = Less | LessEqual | Greater | GreaterEqual; + var test = ShiftExpression.Then(testOp).Then(TestExpression).SeparatedBy(ls); TestExpression.Add( - SumExpression.NotFollowedBy(Greater | Less | GreaterEqual | LessEqual) - | greater.NotFollowedBy(Less | GreaterEqual | LessEqual).SeparatedBy(ls).Named("LessExpression") - | less.NotFollowedBy(GreaterEqual | LessEqual).SeparatedBy(ls).Named("GreaterExpression") - | greaterEqual.NotFollowedBy(LessEqual).SeparatedBy(ls).Named("LessEqualExpression") - | lessEqual.SeparatedBy(ls).Named("GreaterEqualExpression") + test.Named("TestExpression") + | ShiftExpression ); + + var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ls); + + var eqOp = + Literal("==").Named("Equals") + | Literal("!=").Named("NotEquals"); + var equals = - (BooleanTerm | TermExpression) - .Then(Literal("==") | "!=") + (BooleanTerm | parenTestExpr | TestExpression) + .Then(eqOp) .Then( - BooleanTerm - | EqualsExpression + BooleanTerm | EqualsExpression ) .SeparatedBy(ls).Named("Equals"); EqualsExpression.Add( - TestExpression - equals - | equals + equals + | TestExpression ); ParenExpression.Add( - LeftParen.Then(ParenExpression).Then(RightParen).SeparatedBy(ls) - | LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) + LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) ); + var parameters = EqualsExpression.Then(Comma.Then(PrimaryExpression).SeparatedBy(ls).Repeat(0)).SeparatedBy(ls); + var methodCall = Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); - var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); PrimaryExpression.Add( - EqualsExpression - // - methodCall - // | methodCall + methodCall + | EqualsExpression ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs new file mode 100644 index 0000000000..07f25798aa --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -0,0 +1,31 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser Statement = new(); + + public SDSLGrammar UsingStatements() + { + Inner = Statement.Then(";"); + return this; + } + public void CreateStatements() + { + var ls = WhiteSpace.Repeat(0); + var ls1 = WhiteSpace.Repeat(1); + + var assign = + Identifier.Optional().Named("Type") + .Then(Identifier.Named("Variable")) + .Then(AssignOperators.Named("AssignOp")) + .Then(PrimaryExpression.Named("Value")) + .SeparatedBy(ls); + + Statement.Add( + assign.Named("Assign") + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs index f514c02488..7af43abfa9 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs @@ -20,5 +20,6 @@ public void CreateAll() CreateDirectives(); CreateDirectiveExpressions(); CreateExpressions(); + CreateStatements(); } } From 25221fbd7280358e2e3c9ee284cf849167fe6a77 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 May 2022 12:44:44 +0200 Subject: [PATCH 0038/1182] Added more kind of expressions --- src/SDSLParser/SDSL/Expressions.sdsl | 7 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 79 +++++++++++++++++-- .../SDSLGrammar/SDSLGrammar.Statements.cs | 12 ++- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index a911c81937..9f6e96e951 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1,6 +1 @@ -My_Method( - 1, - true, - a++, - 5>4 -); \ No newline at end of file +5*(float)8; \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs index f415705bb0..d6c28c19c8 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs @@ -6,10 +6,19 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(); + public AlternativeParser PostFixExpression = new(); + public AlternativeParser UnaryExpression = new(); + public AlternativeParser CastExpression = new(); public AlternativeParser MulExpression = new(); public AlternativeParser SumExpression = new(); public AlternativeParser ShiftExpression = new(); + public AlternativeParser ConditionalExpression = new(); + public AlternativeParser LogicalOrExpression = new(); + public AlternativeParser LogicalAndExpression = new(); + public AlternativeParser OrExpression = new(); + public AlternativeParser XorExpression = new(); + public AlternativeParser AndExpression = new(); public AlternativeParser TestExpression = new(); public AlternativeParser IncrementExpression = new(); @@ -19,7 +28,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar UsingPrimaryExpression() { - Inner = PrimaryExpression.Then(";"); + Inner = MulExpression.Then(";"); return this; } @@ -48,14 +57,35 @@ public void CreateExpressions() TermExpression.Add( Literals - | IncrementExpression + | Identifier | ParenExpression.Named("ParenthesisExpr") ); - var multiply = TermExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); + PostFixExpression.Add( + Identifier.Then(incrementOp).SeparatedBy(ls).Named("PostfixIncrement") + | Identifier.NotFollowedBy(ls & LeftBracket).Then(Dot.Then(Identifier).Repeat(0)).Named("AccessorChain") + | ParenExpression.Or(Identifier).Then(LeftBracket).Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ls).Named("ArrayAccessor") + | TermExpression + ); + + UnaryExpression.Add( + Literal("sizeof").Then(LeftParen).Then(Identifier).Then(RightParen).Named("SizeOf") + | Literal("sizeof").Then(LeftParen).Then(UnaryExpression).Then(RightParen).Named("SizeOf") + | prefixIncrement.Named("PrefixIncrement") + | PostFixExpression + ); + + CastExpression.Add( + LeftParen.Then(Identifier).Then(RightParen).Then(UnaryExpression).SeparatedBy(ls).Named("CastExpression") + | UnaryExpression + ); + + + + var multiply = CastExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); MulExpression.Add( multiply.Named("Multiplication") - | TermExpression + | CastExpression ); var parenMulExpr = LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ls); @@ -79,7 +109,8 @@ public void CreateExpressions() shift.Named("ShiftExpression") | SumExpression ); - + + var testOp = Less | LessEqual | Greater | GreaterEqual; var test = ShiftExpression.Then(testOp).Then(TestExpression).SeparatedBy(ls); @@ -108,6 +139,42 @@ public void CreateExpressions() equals | TestExpression ); + + AndExpression.Add( + EqualsExpression.Then("&").Then(AndExpression).SeparatedBy(ls).Named("BitwiseAnd") + | EqualsExpression + ); + + XorExpression.Add( + AndExpression.Then("^").Then(XorExpression).SeparatedBy(ls).Named("BitwiseXor") + | AndExpression + ); + + OrExpression.Add( + XorExpression.Then("|").Then(OrExpression).SeparatedBy(ls).Named("BitwiseOr") + | XorExpression + ); + + LogicalAndExpression.Add( + OrExpression.Then("&&").Then(LogicalAndExpression).SeparatedBy(ls).Named("LogicalAnd") + | OrExpression + ); + LogicalOrExpression.Add( + LogicalAndExpression.Then("||").Then(LogicalOrExpression).SeparatedBy(ls).Named("LogicalOr") + | LogicalAndExpression + ); + + ConditionalExpression.Add( + LogicalOrExpression.NotFollowedBy(ls & "?") + | LogicalOrExpression + .Then("?") + .Then(PrimaryExpression) + .Then(":") + .Then(PrimaryExpression) + .SeparatedBy(ls) + .Named("Ternary") + + ); ParenExpression.Add( LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) @@ -120,7 +187,7 @@ public void CreateExpressions() PrimaryExpression.Add( methodCall - | EqualsExpression + | ConditionalExpression ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs index 07f25798aa..26441d2175 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -17,15 +17,19 @@ public void CreateStatements() var ls = WhiteSpace.Repeat(0); var ls1 = WhiteSpace.Repeat(1); - var assign = - Identifier.Optional().Named("Type") - .Then(Identifier.Named("Variable")) + var assignValue = + Identifier.Named("Variable").NotFollowedBy(Identifier) .Then(AssignOperators.Named("AssignOp")) .Then(PrimaryExpression.Named("Value")) .SeparatedBy(ls); + + var assignVar = + Identifier.Named("Type") + .Then(assignValue).SeparatedBy(ls); Statement.Add( - assign.Named("Assign") + assignValue.Named("Assign") + | assignVar ); } } \ No newline at end of file From db73df3bf180f3fca49e359b9cac6198ff41dae5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 May 2022 13:57:20 +0200 Subject: [PATCH 0039/1182] Optimized a lil bit of the parenthesis expressions --- src/SDSLParser/SDSL/Expressions.sdsl | 2 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 9f6e96e951..aca5a5344b 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1 @@ -5*(float)8; \ No newline at end of file +true ? (5+0) : (float)5; \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs index d6c28c19c8..e25e0a16b6 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs @@ -28,7 +28,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar UsingPrimaryExpression() { - Inner = MulExpression.Then(";"); + Inner = PrimaryExpression.Then(";"); return this; } @@ -109,11 +109,13 @@ public void CreateExpressions() shift.Named("ShiftExpression") | SumExpression ); + var parenShift = + LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ls); var testOp = Less | LessEqual | Greater | GreaterEqual; - var test = ShiftExpression.Then(testOp).Then(TestExpression).SeparatedBy(ls); + var test = (parenShift | ShiftExpression).Then(testOp).Then(TestExpression).SeparatedBy(ls); TestExpression.Add( test.Named("TestExpression") @@ -168,9 +170,9 @@ public void CreateExpressions() LogicalOrExpression.NotFollowedBy(ls & "?") | LogicalOrExpression .Then("?") - .Then(PrimaryExpression) + .Then(CastExpression | ParenExpression | LogicalOrExpression) .Then(":") - .Then(PrimaryExpression) + .Then(CastExpression | ParenExpression | LogicalOrExpression) .SeparatedBy(ls) .Named("Ternary") From 613d20a7e95b3498273dc441fa07221b3de665d0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 May 2022 19:06:35 +0200 Subject: [PATCH 0040/1182] first shader parsed --- src/SDSLParser/Program.cs | 2 +- src/SDSLParser/SDSL/Expressions.sdsl | 8 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 45 ++++++++++ .../SDSLGrammar/SDSLGrammar.Statements.cs | 90 +++++++++++++++++-- .../SDSLGrammar/SDSLGrammar.cs | 1 + 5 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index bdd8e848fb..f7a7fbaa46 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -9,7 +9,7 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingPrimaryExpression(); +var sdslParser = new SDSLGrammar().UsingShader(); var s = new Stopwatch(); var match2 = sdslParser.Match(shaderf); s.Start(); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index aca5a5344b..8688fc55ea 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1 +1,7 @@ -true ? (5+0) : (float)5; \ No newline at end of file +shader BaseShader +{ + float4 PSMain() + { + return float4(1); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs new file mode 100644 index 0000000000..5822bcff0c --- /dev/null +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs @@ -0,0 +1,45 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parser; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser Declarations = new(); + public AlternativeParser Shader = new(); + + + public SDSLGrammar UsingShader() + { + Inner = Shader; + return this; + } + public void CreateShader() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + var genericValue = + Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType") + | ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"); + + var generics = + Literal("<").Then(Comma.Optional().Then(genericValue).Repeat(1)).Then(">").SeparatedBy(ws); + + var mixins = + Comma.Optional().Then(Identifier).Then(generics).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); + + var shaderContentTypes = + MethodDeclaration; + + var shaderBody = + LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); + + Shader.Add( + Literal("shader") + .Then(Identifier.Then(generics).SeparatedBy(ws)).SeparatedBy(ws1) + //.Then(Literal(":").Then(mixins).SeparatedBy(ws).Optional()) + .Then(shaderBody).Named("ShaderProgram") + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs index 26441d2175..4607a41431 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -5,31 +5,103 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { + public AlternativeParser StructDefinition = new(); + public AlternativeParser Attribute = new(); public AlternativeParser Statement = new(); + public AlternativeParser ControlFlow = new(); + public AlternativeParser MethodDeclaration = new(); + public AlternativeParser Block = new(); + public SDSLGrammar UsingStatements() { - Inner = Statement.Then(";"); + Inner = ControlFlow; return this; } public void CreateStatements() { - var ls = WhiteSpace.Repeat(0); - var ls1 = WhiteSpace.Repeat(1); + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); - var assignValue = + var declare = + Identifier.Then(Identifier).SeparatedBy(ws1).Then(";").SeparatedBy(ws); + var assignVar = Identifier.Named("Variable").NotFollowedBy(Identifier) .Then(AssignOperators.Named("AssignOp")) .Then(PrimaryExpression.Named("Value")) - .SeparatedBy(ls); + .Then(Semi) + .SeparatedBy(ws); - var assignVar = + + + var declareAssign = Identifier.Named("Type") - .Then(assignValue).SeparatedBy(ls); + .Then(assignVar) + .SeparatedBy(ws1); + + var returnStatement = + Return.Then(PrimaryExpression).SeparatedBy(ws1) + .Then(Semi).SeparatedBy(ws); + + Attribute.Add( + LeftBracket + .Then(Identifier) + .Then(LeftParen) + .Then(Literals.Then(Comma.Then(Literals).Repeat(0).SeparatedBy(ws))) + .Then(RightParen) + .Then(RightBracket) + .SeparatedBy(ws) + ); + + StructDefinition.Add( + Struct.Then(Identifier).SeparatedBy(ws1) + .Then(LeftBrace) + .Then(declare.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace).Then(Semi).SeparatedBy(ws) + ); Statement.Add( - assignValue.Named("Assign") - | assignVar + Attribute.Named("Attribute") + | Block.Named("BlockExpression") + | returnStatement + | assignVar.Named("AssignExpression") + | declareAssign.Named("DeclareAssign") + | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") + ); + + Block.Add( + LeftBrace.Then(Statement.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws) + ); + var flowStatement = Statement; + + var ifStatement = + If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(flowStatement).SeparatedBy(ws); + + var elseIfStatement = + Else.Then(ifStatement).SeparatedBy(ws1); + + var elseStatement = + Else.Then(flowStatement).SeparatedBy(ws1); + + ControlFlow.Add( + Attribute.Repeat(0).Named("Attributes").Then( + ifStatement.Named("IfStatement") + | elseStatement.Named("ElseStatement") + | elseIfStatement.Named("ElseIfStatement") + ).SeparatedBy(ws) + ); + + var parameter = Identifier.Then(Identifier).SeparatedBy(ws1); + var parameterList = + LeftParen + .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) + // .Then(parameter.Then(Literal(",").Repeat(0))) + .Then(RightParen).SeparatedBy(ws); + + MethodDeclaration.Add( + Identifier.Then(Identifier).SeparatedBy(ws1) + .Then(parameterList) + .Then(LeftBrace).Then(Statement.Repeat(0)).Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs index 7af43abfa9..ea6a837cf9 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs @@ -21,5 +21,6 @@ public void CreateAll() CreateDirectiveExpressions(); CreateExpressions(); CreateStatements(); + CreateShader(); } } From 0e65535a49912a6682514791b86faf7728fae269 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 May 2022 19:15:24 +0200 Subject: [PATCH 0041/1182] added readme --- src/Readme.md | 20 +++++++++++++++++++ .../SDSLGrammar/SDSLGrammar.Literals.cs | 9 +-------- 2 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/Readme.md diff --git a/src/Readme.md b/src/Readme.md new file mode 100644 index 0000000000..d9d72a4915 --- /dev/null +++ b/src/Readme.md @@ -0,0 +1,20 @@ +# Parser for SDSL + +`Warn : this project is not official` + +## SDSL + +[SDSL](https://doc.stride3d.net/latest/en/manual/graphics/effects-and-shaders/shading-language/index.html) is a shader language created for the [Stride game engine](https://www.stride3d.net/). + +a superset of the HLSL Shading language, bringing advanced and higher level language constructions, with: + +* **extensibility** to allow shaders to be extended easily using object-oriented programming concepts such as classes, inheritance, and composition + +* **modularity** to provide a set modular shaders each focusing on a single rendering technique, more easily manageable + +* **reusability** to maximize code reuse between shaders + + +## Parser + +This language parser is built from the ground up using the [Eto.Parse](https://github.com/picoe/Eto.Parse) library. It is designed to be faster and more efficient. \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index fb0f2f9e28..bcb51c2c7a 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -66,13 +66,6 @@ public void CreateLiterals() floats - ints | ints | StringLiteral - ); - // .NotFollowedBy(IntegerSuffix) - FloatLiteral - // | IntegerLiteral.Then(IntegerSuffix) - FloatLiteral - // // | FloatLiteral.NotFollowedBy(FloatSuffix) - // // | FloatLiteral.Then(FloatSuffix) - // // | HexaDecimalLiteral - // | StringLiteral; - + ); } } \ No newline at end of file From 824204dfc8b6f7d0a0d70be6d39730da65ce708d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 May 2022 19:46:41 +0200 Subject: [PATCH 0042/1182] Moved readme --- src/Readme.md => Readme.md | 0 src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs | 1 - 2 files changed, 1 deletion(-) rename src/Readme.md => Readme.md (100%) diff --git a/src/Readme.md b/Readme.md similarity index 100% rename from src/Readme.md rename to Readme.md diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs index 4607a41431..8671e97fd5 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -95,7 +95,6 @@ public void CreateStatements() var parameterList = LeftParen .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) - // .Then(parameter.Then(Literal(",").Repeat(0))) .Then(RightParen).SeparatedBy(ws); MethodDeclaration.Add( From 3bf181d05814e31b52aa8e203e1799e618234762 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 4 May 2022 10:50:55 +0200 Subject: [PATCH 0043/1182] generic declaration --- src/SDSLParser/Program.cs | 4 +- src/SDSLParser/SDSL/Expressions.sdsl | 8 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 4 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 39 ++- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 224 +++++++++--------- 5 files changed, 149 insertions(+), 130 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index f7a7fbaa46..c2e0f4f819 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -9,7 +9,7 @@ // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingShader(); +var sdslParser = new SDSLGrammar().UsingStatements(); var s = new Stopwatch(); var match2 = sdslParser.Match(shaderf); s.Start(); @@ -17,7 +17,7 @@ s.Stop(); -Console.WriteLine(match.ErrorMessage[..Math.Min(1000,match.ErrorMessage.Length)]); +Console.WriteLine(match.ErrorMessage); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParser/SDSL/Expressions.sdsl index 8688fc55ea..abed5fdc38 100644 --- a/src/SDSLParser/SDSL/Expressions.sdsl +++ b/src/SDSLParser/SDSL/Expressions.sdsl @@ -1,7 +1 @@ -shader BaseShader -{ - float4 PSMain() - { - return float4(1); - } -} \ No newline at end of file +stream float a[4] : packoffset(a); \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index bcb51c2c7a..8285299b14 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -7,8 +7,8 @@ namespace Stride.Shader.Parser; public partial class SDSLGrammar : Grammar { - AlternativeParser IntegerSuffix; - AlternativeParser FloatSuffix; + AlternativeParser IntegerSuffix = new(); + AlternativeParser FloatSuffix = new(); public SequenceParser SingleLineComment = new(); public SequenceParser BlockComment = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs index 8671e97fd5..cc0f5f20a2 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -10,12 +10,13 @@ public partial class SDSLGrammar : Grammar public AlternativeParser Statement = new(); public AlternativeParser ControlFlow = new(); public AlternativeParser MethodDeclaration = new(); + public AlternativeParser ConstantBuffer = new(); public AlternativeParser Block = new(); public SDSLGrammar UsingStatements() { - Inner = ControlFlow; + Inner = Statement; return this; } public void CreateStatements() @@ -25,6 +26,7 @@ public void CreateStatements() var declare = Identifier.Then(Identifier).SeparatedBy(ws1).Then(";").SeparatedBy(ws); + var assignVar = Identifier.Named("Variable").NotFollowedBy(Identifier) .Then(AssignOperators.Named("AssignOp")) @@ -39,6 +41,24 @@ public void CreateStatements() .Then(assignVar) .SeparatedBy(ws1); + var declaratorSupplement = + Colon.Then( + Packoffset.Then(LeftParen).Then(Identifier.Then(Dot.Then(Identifier).Repeat(0))).Then(RightParen).SeparatedBy(ws).Named("PackOffset") + | Register.Then(LeftParen).Then(Identifier).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") + | Identifier.Named("Semantic") + ).SeparatedBy(ws).Optional(); + var arrayRank = + LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ws).Named("ArrayRankSpecifier").Optional(); + + + var genericDeclaration = + Literal("stage").Named("Stage").Optional().Then(Literal("stream").Named("Stream").Optional()) + .Then((ValueTypes | Identifier).Named("Type")) + .Then(Identifier.Named("Name").Then(arrayRank)).SeparatedBy(ws1) + .Then((AssignOperators & PrimaryExpression).SeparatedBy(ws).Optional()) + .Then(declaratorSupplement) + .Then(";").SeparatedBy(ws); + var returnStatement = Return.Then(PrimaryExpression).SeparatedBy(ws1) .Then(Semi).SeparatedBy(ws); @@ -61,12 +81,11 @@ public void CreateStatements() ); Statement.Add( - Attribute.Named("Attribute") - | Block.Named("BlockExpression") - | returnStatement - | assignVar.Named("AssignExpression") - | declareAssign.Named("DeclareAssign") - | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") + // Attribute.Named("Attribute") + // | Block.Named("BlockExpression") + // | returnStatement + genericDeclaration + // | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") ); Block.Add( @@ -102,5 +121,11 @@ public void CreateStatements() .Then(parameterList) .Then(LeftBrace).Then(Statement.Repeat(0)).Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") ); + + ConstantBuffer.Add( + Literal("cbuffer").Then(Identifier).SeparatedBy(ws1) + .Then(LeftBrace) + .Then() + ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs index 7d8535abc5..9a7dc210c3 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -6,142 +6,142 @@ public partial class SDSLGrammar : Grammar { private CharTerminal WS; private AlternativeParser Space = new(); - private RepeatParser Spaces = new(); + private RepeatParser Spaces = new(); private SequenceParser SpacesWithLineBreak = new(); - private LiteralTerminal AppendStructuredBuffer; + private LiteralTerminal AppendStructuredBuffer = new(); private AlternativeParser ComponentNumber = new(); - private LiteralTerminal Bool; + private LiteralTerminal Bool = new(); private SequenceParser BoolVec = new(); private SequenceParser BoolMat = new(); private AlternativeParser Uint = new(); private SequenceParser UintVec = new(); private SequenceParser UintMat = new(); - private LiteralTerminal Int; + private LiteralTerminal Int = new(); private SequenceParser IntVec = new(); private SequenceParser IntMat = new(); - private LiteralTerminal Half; + private LiteralTerminal Half = new(); private SequenceParser HalfVec = new(); private SequenceParser HalfMat = new(); - private LiteralTerminal Float; + private LiteralTerminal Float = new(); private SequenceParser FloatVec = new(); private SequenceParser FloatMat = new(); - private LiteralTerminal Double; + private LiteralTerminal Double = new(); private SequenceParser DoubleVec = new(); private SequenceParser DoubleMat = new(); - private LiteralTerminal Buffer; - private LiteralTerminal ByteAddressBuffer; - private LiteralTerminal Break; - private LiteralTerminal Case; - private LiteralTerminal CBuffer; - private LiteralTerminal Centroid; - private LiteralTerminal Class; - private LiteralTerminal ColumnMajor; - private LiteralTerminal Const; - private LiteralTerminal ConsumeStructuredBuffer; - private LiteralTerminal Continue; - private LiteralTerminal Default; - private LiteralTerminal Discard; - private LiteralTerminal Do; - private LiteralTerminal Else; - private LiteralTerminal Extern; - private LiteralTerminal For; - private LiteralTerminal Groupshared; - private LiteralTerminal If; - private LiteralTerminal In; + private LiteralTerminal Buffer = new(); + private LiteralTerminal ByteAddressBuffer = new(); + private LiteralTerminal Break = new(); + private LiteralTerminal Case = new(); + private LiteralTerminal CBuffer = new(); + private LiteralTerminal Centroid = new(); + private LiteralTerminal Class = new(); + private LiteralTerminal ColumnMajor = new(); + private LiteralTerminal Const = new(); + private LiteralTerminal ConsumeStructuredBuffer = new(); + private LiteralTerminal Continue = new(); + private LiteralTerminal Default = new(); + private LiteralTerminal Discard = new(); + private LiteralTerminal Do = new(); + private LiteralTerminal Else = new(); + private LiteralTerminal Extern = new(); + private LiteralTerminal For = new(); + private LiteralTerminal Groupshared = new(); + private LiteralTerminal If = new(); + private LiteralTerminal In = new(); private AlternativeParser Inout = new(); - private LiteralTerminal InputPatch; - private LiteralTerminal Interface; + private LiteralTerminal InputPatch = new(); + private LiteralTerminal Interface = new(); public LiteralTerminal Line_ { get; private set; } - private LiteralTerminal LineAdj; - private LiteralTerminal Linear; - private LiteralTerminal LineStream; - private LiteralTerminal Long; - private LiteralTerminal Matrix; - private LiteralTerminal Nointerpolation; - private LiteralTerminal Noperspective; - private LiteralTerminal Out; - private LiteralTerminal OutputPatch; - private LiteralTerminal Packoffset; - private LiteralTerminal Point; - private LiteralTerminal PointStream; - private LiteralTerminal Precise; - private LiteralTerminal Register; - private LiteralTerminal Return; - private LiteralTerminal RowMajor; - private LiteralTerminal RWBuffer; - private LiteralTerminal RWByteAddressBuffer; - private LiteralTerminal RWStructuredBuffer; - private LiteralTerminal Sample; - private LiteralTerminal Sampler; - private LiteralTerminal SamplerComparisonState; - private LiteralTerminal SamplerState; - private LiteralTerminal Shared; - private LiteralTerminal Static; - private LiteralTerminal Struct; - private LiteralTerminal StructuredBuffer; - private LiteralTerminal Switch; + private LiteralTerminal LineAdj = new(); + private LiteralTerminal Linear = new(); + private LiteralTerminal LineStream = new(); + private LiteralTerminal Long = new(); + private LiteralTerminal Matrix = new(); + private LiteralTerminal Nointerpolation = new(); + private LiteralTerminal Noperspective = new(); + private LiteralTerminal Out = new(); + private LiteralTerminal OutputPatch = new(); + private LiteralTerminal Packoffset = new(); + private LiteralTerminal Point = new(); + private LiteralTerminal PointStream = new(); + private LiteralTerminal Precise = new(); + private LiteralTerminal Register = new(); + private LiteralTerminal Return = new(); + private LiteralTerminal RowMajor = new(); + private LiteralTerminal RWBuffer = new(); + private LiteralTerminal RWByteAddressBuffer = new(); + private LiteralTerminal RWStructuredBuffer = new(); + private LiteralTerminal Sample = new(); + private LiteralTerminal Sampler = new(); + private LiteralTerminal SamplerComparisonState = new(); + private LiteralTerminal SamplerState = new(); + private LiteralTerminal Shared = new(); + private LiteralTerminal Static = new(); + private LiteralTerminal Struct = new(); + private LiteralTerminal StructuredBuffer = new(); + private LiteralTerminal Switch = new(); private AlternativeParser TextureTypes; - private LiteralTerminal Triangle; - private LiteralTerminal TriangleAdj; - private LiteralTerminal TriangleStream; - private LiteralTerminal Uniform; - private LiteralTerminal Vector; - private LiteralTerminal Volatile; - private LiteralTerminal Void; - private LiteralTerminal While; - private LiteralTerminal LeftParen; - private LiteralTerminal RightParen; - private LiteralTerminal LeftBracket; - private LiteralTerminal RightBracket; - private LiteralTerminal LeftBrace; - private LiteralTerminal RightBrace; + private LiteralTerminal Triangle = new(); + private LiteralTerminal TriangleAdj = new(); + private LiteralTerminal TriangleStream = new(); + private LiteralTerminal Uniform = new(); + private LiteralTerminal Vector = new(); + private LiteralTerminal Volatile = new(); + private LiteralTerminal Void = new(); + private LiteralTerminal While = new(); + private LiteralTerminal LeftParen = new(); + private LiteralTerminal RightParen = new(); + private LiteralTerminal LeftBracket = new(); + private LiteralTerminal RightBracket = new(); + private LiteralTerminal LeftBrace = new(); + private LiteralTerminal RightBrace = new(); - private LiteralTerminal LeftShift; - private LiteralTerminal RightShift; - private LiteralTerminal Plus; - private LiteralTerminal PlusPlus; - private LiteralTerminal Minus; - private LiteralTerminal MinusMinus; - private LiteralTerminal Star; - private LiteralTerminal Div; - private LiteralTerminal Mod; - private LiteralTerminal And; - private LiteralTerminal Or; - private LiteralTerminal AndAnd; - private LiteralTerminal OrOr; - private LiteralTerminal Caret; - private LiteralTerminal Not; - private LiteralTerminal Tilde; - private LiteralTerminal Equal; - private LiteralTerminal NotEqual; - private LiteralTerminal Less; - private LiteralTerminal LessEqual; - private LiteralTerminal Greater; - private LiteralTerminal GreaterEqual; - private LiteralTerminal Question; - private LiteralTerminal Colon; - private LiteralTerminal ColonColon; - private LiteralTerminal Semi; - private LiteralTerminal Comma; - private LiteralTerminal Assign; - private LiteralTerminal StarAssign; - private LiteralTerminal DivAssign; - private LiteralTerminal ModAssign; - private LiteralTerminal PlusAssign; - private LiteralTerminal MinusAssign; - private LiteralTerminal LeftShiftAssign; - private LiteralTerminal RightShiftAssign; - private LiteralTerminal AndAssign; - private LiteralTerminal XorAssign; - private LiteralTerminal OrAssign; + private LiteralTerminal LeftShift = new(); + private LiteralTerminal RightShift = new(); + private LiteralTerminal Plus = new(); + private LiteralTerminal PlusPlus = new(); + private LiteralTerminal Minus = new(); + private LiteralTerminal MinusMinus = new(); + private LiteralTerminal Star = new(); + private LiteralTerminal Div = new(); + private LiteralTerminal Mod = new(); + private LiteralTerminal And = new(); + private LiteralTerminal Or = new(); + private LiteralTerminal AndAnd = new(); + private LiteralTerminal OrOr = new(); + private LiteralTerminal Caret = new(); + private LiteralTerminal Not = new(); + private LiteralTerminal Tilde = new(); + private LiteralTerminal Equal = new(); + private LiteralTerminal NotEqual = new(); + private LiteralTerminal Less = new(); + private LiteralTerminal LessEqual = new(); + private LiteralTerminal Greater = new(); + private LiteralTerminal GreaterEqual = new(); + private LiteralTerminal Question = new(); + private LiteralTerminal Colon = new(); + private LiteralTerminal ColonColon = new(); + private LiteralTerminal Semi = new(); + private LiteralTerminal Comma = new(); + private LiteralTerminal Assign = new(); + private LiteralTerminal StarAssign = new(); + private LiteralTerminal DivAssign = new(); + private LiteralTerminal ModAssign = new(); + private LiteralTerminal PlusAssign = new(); + private LiteralTerminal MinusAssign = new(); + private LiteralTerminal LeftShiftAssign = new(); + private LiteralTerminal RightShiftAssign = new(); + private LiteralTerminal AndAssign = new(); + private LiteralTerminal XorAssign = new(); + private LiteralTerminal OrAssign = new(); - private LiteralTerminal Dot; - private LiteralTerminal True; - private LiteralTerminal False; + private LiteralTerminal Dot = new(); + private LiteralTerminal True = new(); + private LiteralTerminal False = new(); private AlternativeParser PreprocessorDirectiveName = new(); public void CreateTokens() From 1e06dd4e5edec7ad51c3ff24eaefce5dd4b46f8f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 4 May 2022 17:47:47 +0200 Subject: [PATCH 0044/1182] Updated value types and shader parsing --- src/SDSLParser/Program.cs | 4 ++-- src/SDSLParser/SDSL/shader.sdsl | 16 +++++++++---- .../SDSLGrammar/SDSLGrammar.Literals.cs | 7 +++--- .../SDSLGrammar/SDSLGrammar.Shader.cs | 11 ++++++--- .../SDSLGrammar/SDSLGrammar.Statements.cs | 24 +++++++++++-------- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 24 +++++++++---------- 6 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/SDSLParser/Program.cs b/src/SDSLParser/Program.cs index c2e0f4f819..a77aa08194 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParser/Program.cs @@ -4,12 +4,12 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); +var shaderf = File.ReadAllText("./SDSL/shader.sdsl"); // var parser = new SDSLGrammar(); var parser = StrideGrammar.New("expr"); var tokens = StrideGrammar.HlslGrammar("expression"); -var sdslParser = new SDSLGrammar().UsingStatements(); +var sdslParser = new SDSLGrammar().UsingShader(); var s = new Stopwatch(); var match2 = sdslParser.Match(shaderf); s.Start(); diff --git a/src/SDSLParser/SDSL/shader.sdsl b/src/SDSLParser/SDSL/shader.sdsl index 2ccfe37e87..d787bf83b0 100644 --- a/src/SDSLParser/SDSL/shader.sdsl +++ b/src/SDSLParser/SDSL/shader.sdsl @@ -1,7 +1,13 @@ -shader BasicShader { - stream float a = 0; +shader BasicMixin +{ + float myFloat = 0.2f; + stage float3 myPosition : register(b); + stage stream float2 screenPosition : register(vs, b); + + abstract void myFunc(); - c_buffer PerMaterial{ - stage float b = 0; + float4 ComputeColor() + { + return float4(1.0); } -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs index 8285299b14..4cf5ef968c 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs @@ -63,9 +63,10 @@ public void CreateLiterals() BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; Literals.Add( - floats - ints - | ints - | StringLiteral + HexaDecimalLiteral + | IntegerLiteral.NotFollowedBy(Dot | FloatSuffix).Then(IntegerSuffix.Optional()).Named("IntegerLiteral") + | FloatLiteral.Then(FloatSuffix.Optional()).Named("FloatLiteral") + | StringLiteral ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs index 5822bcff0c..9aa9bd7a3b 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs @@ -29,15 +29,20 @@ public void CreateShader() var mixins = Comma.Optional().Then(Identifier).Then(generics).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); - var shaderContentTypes = - MethodDeclaration; + var comments = + SingleLineComment + | BlockComment; + var shaderContentTypes = + comments + | GenericDeclaration + | MethodDeclaration; var shaderBody = LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); Shader.Add( Literal("shader") - .Then(Identifier.Then(generics).SeparatedBy(ws)).SeparatedBy(ws1) + .Then(Identifier.Then(generics.Optional()).SeparatedBy(ws)).SeparatedBy(ws1) //.Then(Literal(":").Then(mixins).SeparatedBy(ws).Optional()) .Then(shaderBody).Named("ShaderProgram") ); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs index cc0f5f20a2..6ecd212849 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs @@ -11,6 +11,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser ControlFlow = new(); public AlternativeParser MethodDeclaration = new(); public AlternativeParser ConstantBuffer = new(); + public AlternativeParser GenericDeclaration = new(); public AlternativeParser Block = new(); @@ -44,20 +45,21 @@ public void CreateStatements() var declaratorSupplement = Colon.Then( Packoffset.Then(LeftParen).Then(Identifier.Then(Dot.Then(Identifier).Repeat(0))).Then(RightParen).SeparatedBy(ws).Named("PackOffset") - | Register.Then(LeftParen).Then(Identifier).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") + | Register.Then(LeftParen).Then(Identifier.Then(Comma.Then(Identifier).SeparatedBy(ws).Repeat(0).SeparatedBy(ws))).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") | Identifier.Named("Semantic") ).SeparatedBy(ws).Optional(); var arrayRank = LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ws).Named("ArrayRankSpecifier").Optional(); - var genericDeclaration = + GenericDeclaration.Add( Literal("stage").Named("Stage").Optional().Then(Literal("stream").Named("Stream").Optional()) .Then((ValueTypes | Identifier).Named("Type")) .Then(Identifier.Named("Name").Then(arrayRank)).SeparatedBy(ws1) .Then((AssignOperators & PrimaryExpression).SeparatedBy(ws).Optional()) - .Then(declaratorSupplement) - .Then(";").SeparatedBy(ws); + .Then(declaratorSupplement.Optional()) + .Then(";").SeparatedBy(ws) + ); var returnStatement = Return.Then(PrimaryExpression).SeparatedBy(ws1) @@ -81,11 +83,12 @@ public void CreateStatements() ); Statement.Add( - // Attribute.Named("Attribute") - // | Block.Named("BlockExpression") - // | returnStatement - genericDeclaration - // | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") + Attribute.Named("Attribute") + | Block.Named("BlockExpression") + | returnStatement.Named("Return") + | declareAssign.Named("DeclareAssign") + | assignVar.Named("Assign") + | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") ); Block.Add( @@ -117,7 +120,8 @@ public void CreateStatements() .Then(RightParen).SeparatedBy(ws); MethodDeclaration.Add( - Identifier.Then(Identifier).SeparatedBy(ws1) + Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1).Then(parameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") + | Literal("stage").Optional().Then(Identifier).Then(Identifier).SeparatedBy(ws1) .Then(parameterList) .Then(LeftBrace).Then(Statement.Repeat(0)).Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") ); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs index b4ea3a533b..ace8fc3ee7 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -55,33 +55,33 @@ public void CreateTokenGroups() | OrAssign; BoolTypes = - Bool - BoolVec - | BoolVec - BoolMat + Bool.NotFollowedBy(Set("1234")) + | BoolVec.NotFollowedBy("x") | BoolMat; HalfTypes = - Half - HalfVec - | HalfVec - HalfMat + Half.NotFollowedBy(Set("1234")) + | HalfVec.NotFollowedBy("x") | HalfMat; FloatTypes = - Float - FloatVec - | FloatVec - FloatMat + Float.NotFollowedBy(Set("1234")) + | FloatVec.NotFollowedBy("x") | FloatMat; DoubleTypes = - Double - DoubleVec - | DoubleVec - DoubleMat + Double.NotFollowedBy(Set("1234")) + | DoubleVec.NotFollowedBy("x") | DoubleMat; IntTypes = - Int - IntVec - | IntVec - IntMat + Int.NotFollowedBy(Set("1234")) + | IntVec.NotFollowedBy("x") | IntMat; UintTypes = - Uint - UintVec - | UintVec - UintMat + Uint.NotFollowedBy(Set("1234")) + | UintVec.NotFollowedBy("x") | UintMat; ValueTypes = From 3142e2978cc59425df7c0482d462d2ba393343ad Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 4 May 2022 18:25:25 +0200 Subject: [PATCH 0045/1182] Renaming of projects --- SDSLParser.sln | 6 +- .../Program.cs | 6 +- .../SDSL/Directive.sdsl | 0 .../SDSL/Expressions.sdsl | 0 .../SDSL/Methods.sdsl | 0 .../SDSL/shader.sdsl | 2 +- .../SDSLParserExample.csproj} | 4 +- .../GrammarResource.Designer.cs | 103 ---- src/Stride.Shader.Parser/GrammarResource.resx | 133 ----- src/Stride.Shader.Parser/SDSLDirective.ebnf | 91 --- src/Stride.Shader.Parser/SDSLExpr.ebnf | 519 ------------------ src/Stride.Shader.Parser/SDSLTokens.ebnf | 374 ------------- src/Stride.Shader.Parser/StrideGrammar.cs | 40 -- src/Stride.Shader.Parser/TestGrammar.cs | 87 --- src/Stride.Shader.Parser/grammar.ebnf | 125 ----- .../BasicParsing.cs | 4 +- .../Stride.Shader.Parsing.Test.csproj} | 2 +- src/Stride.Shader.Parsing/CommentGrammar.cs | 27 + .../Hlsl/HlslExpr.g4 | 0 .../Hlsl/HlslTokens.g4 | 0 .../Hlsl/code.hlsl | 0 .../SDSLGrammar.Directives.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Directives.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 13 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 2 +- .../SDSLGrammar/SDSLGrammar.cs | 2 +- src/Stride.Shader.Parsing/SDSLParser.cs | 22 + .../Stride.Shader.Parsing.csproj} | 0 32 files changed, 75 insertions(+), 1499 deletions(-) rename src/{SDSLParser => SDSLParserExample}/Program.cs (75%) rename src/{SDSLParser => SDSLParserExample}/SDSL/Directive.sdsl (100%) rename src/{SDSLParser => SDSLParserExample}/SDSL/Expressions.sdsl (100%) rename src/{SDSLParser => SDSLParserExample}/SDSL/Methods.sdsl (100%) rename src/{SDSLParser => SDSLParserExample}/SDSL/shader.sdsl (76%) rename src/{SDSLParser/SDSLParser.csproj => SDSLParserExample/SDSLParserExample.csproj} (70%) delete mode 100644 src/Stride.Shader.Parser/GrammarResource.Designer.cs delete mode 100644 src/Stride.Shader.Parser/GrammarResource.resx delete mode 100644 src/Stride.Shader.Parser/SDSLDirective.ebnf delete mode 100644 src/Stride.Shader.Parser/SDSLExpr.ebnf delete mode 100644 src/Stride.Shader.Parser/SDSLTokens.ebnf delete mode 100644 src/Stride.Shader.Parser/StrideGrammar.cs delete mode 100644 src/Stride.Shader.Parser/TestGrammar.cs delete mode 100644 src/Stride.Shader.Parser/grammar.ebnf rename src/{Stride.Shader.Parser.Test => Stride.Shader.Parsing.Test}/BasicParsing.cs (96%) rename src/{Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj => Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj} (91%) create mode 100644 src/Stride.Shader.Parsing/CommentGrammar.cs rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/Hlsl/HlslExpr.g4 (100%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/Hlsl/HlslTokens.g4 (100%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/Hlsl/code.hlsl (100%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (99%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Directives.cs (98%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Expression.cs (99%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Literals.cs (98%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Shader.cs (85%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Statements.cs (99%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.TokenGroups.cs (99%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.Tokens.cs (99%) rename src/{Stride.Shader.Parser => Stride.Shader.Parsing}/SDSLGrammar/SDSLGrammar.cs (93%) create mode 100644 src/Stride.Shader.Parsing/SDSLParser.cs rename src/{Stride.Shader.Parser/Stride.Shader.Parser.csproj => Stride.Shader.Parsing/Stride.Shader.Parsing.csproj} (100%) diff --git a/SDSLParser.sln b/SDSLParser.sln index 2a1ef67824..e26604cf42 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -5,11 +5,11 @@ VisualStudioVersion = 16.0.30114.105 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B760-4857-BD74-296B07778B15}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParser", "src\SDSLParser\SDSLParser.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parser", "src\Stride.Shader.Parser\Stride.Shader.Parser.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parsing", "src\Stride.Shader.Parsing\Stride.Shader.Parsing.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parser.Test", "src\Stride.Shader.Parser.Test\Stride.Shader.Parser.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parsing.Test", "src\Stride.Shader.Parsing.Test\Stride.Shader.Parsing.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/SDSLParser/Program.cs b/src/SDSLParserExample/Program.cs similarity index 75% rename from src/SDSLParser/Program.cs rename to src/SDSLParserExample/Program.cs index a77aa08194..e5c6de9a96 100644 --- a/src/SDSLParser/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -1,14 +1,12 @@ using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shader.Parser; +using Stride.Shader.Parsing; using System.Diagnostics; var shaderf = File.ReadAllText("./SDSL/shader.sdsl"); -// var parser = new SDSLGrammar(); -var parser = StrideGrammar.New("expr"); -var tokens = StrideGrammar.HlslGrammar("expression"); +var parser = new SDSLParser(); var sdslParser = new SDSLGrammar().UsingShader(); var s = new Stopwatch(); var match2 = sdslParser.Match(shaderf); diff --git a/src/SDSLParser/SDSL/Directive.sdsl b/src/SDSLParserExample/SDSL/Directive.sdsl similarity index 100% rename from src/SDSLParser/SDSL/Directive.sdsl rename to src/SDSLParserExample/SDSL/Directive.sdsl diff --git a/src/SDSLParser/SDSL/Expressions.sdsl b/src/SDSLParserExample/SDSL/Expressions.sdsl similarity index 100% rename from src/SDSLParser/SDSL/Expressions.sdsl rename to src/SDSLParserExample/SDSL/Expressions.sdsl diff --git a/src/SDSLParser/SDSL/Methods.sdsl b/src/SDSLParserExample/SDSL/Methods.sdsl similarity index 100% rename from src/SDSLParser/SDSL/Methods.sdsl rename to src/SDSLParserExample/SDSL/Methods.sdsl diff --git a/src/SDSLParser/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl similarity index 76% rename from src/SDSLParser/SDSL/shader.sdsl rename to src/SDSLParserExample/SDSL/shader.sdsl index d787bf83b0..266edd6492 100644 --- a/src/SDSLParser/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -2,7 +2,7 @@ shader BasicMixin { float myFloat = 0.2f; stage float3 myPosition : register(b); - stage stream float2 screenPosition : register(vs, b); + //stage stream float2 screenPosition : register(vs, b); abstract void myFunc(); diff --git a/src/SDSLParser/SDSLParser.csproj b/src/SDSLParserExample/SDSLParserExample.csproj similarity index 70% rename from src/SDSLParser/SDSLParser.csproj rename to src/SDSLParserExample/SDSLParserExample.csproj index 384acf35fc..261e26d98f 100644 --- a/src/SDSLParser/SDSLParser.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -2,7 +2,7 @@ - + @@ -13,7 +13,7 @@ - + diff --git a/src/Stride.Shader.Parser/GrammarResource.Designer.cs b/src/Stride.Shader.Parser/GrammarResource.Designer.cs deleted file mode 100644 index 4fa85252f2..0000000000 --- a/src/Stride.Shader.Parser/GrammarResource.Designer.cs +++ /dev/null @@ -1,103 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Shader.Parser { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class GrammarResource { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal GrammarResource() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Stride.Shader.Parser.GrammarResource", typeof(GrammarResource).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] grammar { - get { - object obj = ResourceManager.GetObject("grammar", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] SDSLDirective { - get { - object obj = ResourceManager.GetObject("SDSLDirective", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] SDSLExpr { - get { - object obj = ResourceManager.GetObject("SDSLExpr", resourceCulture); - return ((byte[])(obj)); - } - } - - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] SDSLTokens { - get { - object obj = ResourceManager.GetObject("SDSLTokens", resourceCulture); - return ((byte[])(obj)); - } - } - } -} diff --git a/src/Stride.Shader.Parser/GrammarResource.resx b/src/Stride.Shader.Parser/GrammarResource.resx deleted file mode 100644 index 6d83d3abad..0000000000 --- a/src/Stride.Shader.Parser/GrammarResource.resx +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - grammar.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SDSLDirective.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SDSLExpr.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SDSLTokens.ebnf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLDirective.ebnf b/src/Stride.Shader.Parser/SDSLDirective.ebnf deleted file mode 100644 index 0fa16114f3..0000000000 --- a/src/Stride.Shader.Parser/SDSLDirective.ebnf +++ /dev/null @@ -1,91 +0,0 @@ - -IncrementDirectiveExpr ::= - literal postfixUnaryOperator - | Identifier postfixUnaryOperator - | ParenDirectiveExpression postfixUnaryOperator - | prefixUnaryOperator Identifier - postfixUnaryOperator - | prefixUnaryOperator ParenDirectiveExpression - postfixUnaryOperator - - -TermDirective ::= - literal - | (Identifier - Keywords) - | ParenDirectiveExpression - - -MulDirective ::= - TermDirective - (TermDirective Spaces [*/%]) - | TermDirective Spaces Star Spaces MulDirective - | TermDirective Spaces Div Spaces MulDirective - | TermDirective Spaces Mod Spaces MulDirective - - - -PIncExpression ::= - (Identifier - Keywords) IncOperators - - -SumDirective ::= - MulDirective - (MulDirective Spaces [+-]) - | MulDirective Spaces Plus Spaces SumDirective - | MulDirective Spaces Minus Spaces SumDirective - - -TestDirective ::= - SumDirective - (SumDirective Spaces [<>=!(]) - | SumDirective Spaces Less Spaces TestDirective - | SumDirective Spaces Greater Spaces TestDirective - | SumDirective Spaces LessEqual Spaces TestDirective - | SumDirective Spaces GreaterEqual Spaces TestDirective - | SumDirective Spaces Equal Spaces TestDirective - | SumDirective Spaces NotEqual Spaces TestDirective - -MethodCallDirective ::= - Identifier LeftParen RightParen - -directiveExpression ::= - TestDirective - | IncrementExpr - (MethodCallDirective) - | MethodCallDirective - -ParenDirectiveExpression ::= - LeftParen Spaces directiveExpression Spaces RightParen - -Hash ::= "#" -HashIf ::= Hash (If - [nd]) -HashIfDef ::= Hash (IfDef - [n]) -HashIfNDef ::= Hash IfNDef -HashElse ::= Hash Else -HashElif ::= Hash Elif -HashEndIf ::= Hash EndIf - -EndOfDirective ::= WS* (Eol | Eof) - -directive ::= - ( - ifDirective - | ifDefDirective - | ifNDefDirective - | elseDirective - | elifDirective - ) EndOfDirective - -ifDirective ::= HashIf WS+ directiveExpression - - -ifDefDirective ::= HashIfDef WS+ Identifier - - -ifNDefDirective ::= HashIfNDef WS+ Identifier - - -elseDirective ::= HashElse - - -elifDirective ::= HashElif WS+ directiveExpression - - -endIfDirective ::= HashEndIf - - -/*objectLikeDefineDirective ::= Hash Define identifierOrKeyword (EndOfDirective)* EndOfDirective*/ diff --git a/src/Stride.Shader.Parser/SDSLExpr.ebnf b/src/Stride.Shader.Parser/SDSLExpr.ebnf deleted file mode 100644 index 82a6d83a60..0000000000 --- a/src/Stride.Shader.Parser/SDSLExpr.ebnf +++ /dev/null @@ -1,519 +0,0 @@ -compilationUnit ::= topLevelDeclaration* EOF - - -topLevelDeclaration ::= - classDefinition - | interfaceDefinition - | variableDeclarationStatement - | structDefinition - | constantBuffer - | functionDefinition - | functionDeclaration - - -classDefinition ::= Class Identifier baseList? - LeftBrace classMemberDeclaration* RightBrace - Semi - - -baseList ::= Colon Identifier - - -classMemberDeclaration ::= - variableDeclarationStatement - | functionDefinition - | functionDeclaration - - -constantBuffer ::= CBuffer Identifier registerAllocation? - LeftBrace (variableDeclarationStatement)+ RightBrace - Semi? - - -variableDeclarationStatement ::= variableDeclaration Semi - - -functionDefinition ::= attribute* functionType (Identifier ColonColon)? Identifier - LeftParen functionParams? RightParen - semantic? block Semi? - - -functionDeclaration ::= attribute* functionType Identifier - LeftParen functionParams? RightParen - semantic? Semi - - -functionType ::= - type - | Void - - -functionParams ::= functionParam (Comma functionParam)* - - -functionParam ::= storageFlags type variableDeclarator - - -interfaceDefinition ::= Interface Identifier - LeftBrace functionDeclaration* RightBrace - Semi - - -structDefinition ::= Struct Identifier - LeftBrace (variableDeclarationStatement)+ RightBrace - Semi - - -semantic ::= Colon Identifier - - - -attributeArguments ::= literalExpr (Comma literalExpr)* - - -attributeArgumentList ::= LeftParen attributeArguments RightParen - - -attribute ::= LeftBracket Identifier attributeArgumentList? RightBracket - - - -block ::= LeftBrace statement* RightBrace - - -indentedEmbeddedStatement ::= embeddedStatement | LeftBrace block - - -statement ::= - localDeclarationStatement - | embeddedStatement - | classDefinition - | interfaceDefinition - | structDefinition - - -localDeclarationStatement ::= variableDeclaration Semi - - -forInitializer ::= variableDeclaration - | expression (Comma expression)* - - -forIncrementors ::= expression (Comma expression)* - - -switchLabel ::= Case expression Colon - | Default Colon - - -switchSection ::= switchLabel+ statement+ - - -embeddedStatement ::= Semi - | block - | expression Semi - - | attribute* If LeftParen expression RightParen indentedEmbeddedStatement elseClause? - | attribute* Switch LeftParen expression RightParen LeftBrace switchSection* RightBrace - - | attribute* While LeftParen expression RightParen indentedEmbeddedStatement - | attribute* Do indentedEmbeddedStatement While LeftParen expression RightParen Semi - | attribute* For LeftParen forInitializer? Semi expression? Semi forIncrementors? RightParen indentedEmbeddedStatement - - | Break Semi - | Continue Semi - | Discard Semi - | Return expression? Semi - - -elseClause ::= Else indentedEmbeddedStatement - -AccessorChain ::= userDefinedNames (Dot userDefinedNames)* -MethodCall ::= userDefinedNames argumentList - -TermExpression ::= - literal - /*| Sign? userDefinedNames - (AccessorChain | MethodCall) - | Sign? (AccessorChain - MethodCall) - | Sign? MethodCall - | Sign? scalarOrVectorOrMatrixType argumentList - | ParenExpression*/ - -Multiply ::= TermExpression [ \t#xA]* "*" [ \t#xA]* MulExpression -Divide ::= TermExpression [ \t#xA]* "/" [ \t#xA]* MulExpression -Modulo ::= TermExpression [ \t#xA]* "%" [ \t#xA]* MulExpression - - -MulExpression ::= - TermExpression - (Multiply | Divide | Modulo) - | Multiply - | Divide - | Modulo - -Add ::= MulExpression [ \t#xA]* "+" [ \t#xA]* SumExpression -Subtract ::= MulExpression [ \t#xA]* "-" [ \t#xA]* SumExpression - -SumExpression ::= - MulExpression - (Add | Subtract) - | Add - | Subtract - -LessThan ::= SumExpression [ \t#xA]* "<" [ \t#xA]* TestExpression -GreaterThan ::= SumExpression [ \t#xA]* ">" [ \t#xA]* TestExpression -LessEqualThan ::= SumExpression [ \t#xA]* "<=" [ \t#xA]* TestExpression -GreaterEqualThan ::= SumExpression [ \t#xA]* ">=" [ \t#xA]* TestExpression -Equals ::= SumExpression [ \t#xA]* "==" [ \t#xA]* TestExpression -Different ::= SumExpression [ \t#xA]* "!=" [ \t#xA]* TestExpression - - -TestExpression ::= - SumExpression - (SumExpression [ \t#xA]* [<>=!(]) - | LessThan - | GreaterThan - | LessEqualThan - | GreaterEqualThan - | Equals - | Different - -expression ::= - SumExpression -/* | LeftParen expression RightParen - | LeftParen type (arrayRankSpecifier)* RightParen expression - | (Identifier | ParenExpression) Dot Identifier */ - -ParenExpression ::= LeftParen [ \t#xA]* expression [ \t#xA]* RightParen -/*expression ::= - literalExpr - | Identifier - | LeftParen expression RightParen - | LeftParen type (arrayRankSpecifier)* RightParen expression - | expression Dot Identifier - | scalarOrVectorOrMatrixType argumentList - | expression argumentList - | expression LeftBracket expression RightBracket - | expression postfixUnaryOperator - | prefixUnaryOperator expression - | expression binaryOperator expression - | expression Question expression Colon expression - | right expression assignmentOperator expression - -*/ - -literalExpr ::= literal - - -postfixUnaryOperator ::= - PlusPlus - | MinusMinus - - -prefixUnaryOperator ::= - Plus - PlusPlus - | Minus - MinusMinus - | Not - | Tilde - | PlusPlus - | MinusMinus - - -binaryOperator ::= - calcOperators - | testOperators - -testOperators ::= - Less - LessEqual - | Greater - GreaterEqual - | LessEqual - | GreaterEqual - | Equal - | NotEqual - | And - AndAnd - | Caret - | Or - OrOr - | AndAnd - | OrOr - -calcOperators ::= - Star - | Div - | Mod - | Plus - | Minus - | LeftShift - | RightShift - - - - -assignmentOperator ::= - Assign - | StarAssign - | DivAssign - | ModAssign - | PlusAssign - | MinusAssign - | LeftShiftAssign - | RightShiftAssign - | AndAssign - | XorAssign - | OrAssign - - -argumentList ::= LeftParen [ \t#xA]* arguments? [ \t#xA]* RightParen - - -arguments ::= expression ( [ \t#xA]* Comma [ \t#xA]* expression)* - - -variableDeclaration ::= storageFlags [ \n]+ type [ \n]+ variableDeclarators - - -variableDeclarators ::= variableDeclarator /*(Comma variableDeclarator)**/ - - -variableDeclarator ::= - (Identifier) - (Identifier [ \t#xA]* [:]) - | Identifier [ \t#xA]* variableDeclaratorSupplement - -variableDeclaratorSupplement ::= - (arrayRankSpecifier)+ - | packOffsetNode - | registerAllocation - | semantic - | variableInitializer - - -arrayRankSpecifier ::= - LeftBracket expression? RightBracket - -/* ": packoffset(my_var.value) " */ -packOffsetNode ::= - Colon Packoffset LeftParen - Identifier (Dot Identifier)? - RightParen - - -storageFlags ::= - storageFlag* - - -storageFlag ::= - Constant - | RowMajor - | ColumnMajor - | Extern - | Precise - | Shared - | Groupshared - | Static - | Uniform - | Volatile - | Linear - | Centroid - | Nointerpolation - | Noperspective - | Sample - | In - | Out - | Inout - | Point - | Line_ - | Triangle - | LineAdj - | TriangleAdj - - -type ::= - predefinedType - | userDefinedType - - -predefinedType ::= - - bufferPredefinedType - | byteAddressBufferPredefinedType - | inlineStructPredefinedType - | patchPredefinedType - | matrixType - | genericMatrixPredefinedType - | samplerStatePredefinedType - | scalarType - | streamOutputPredefinedType - | structuredBufferPredefinedType - | texturePredefinedType - | genericTexturePredefinedType - | msTexturePredefinedType - | vectorType - | genericVectorType - - -bufferPredefinedType ::= bufferType Less scalarOrVectorType Greater - - -bufferType ::= - - Buffer - | RWBuffer - - -byteAddressBufferPredefinedType ::= - - byteAddressBufferType - - -byteAddressBufferType ::= - - ByteAddressBuffer - | RWByteAddressBuffer - - -inlineStructPredefinedType ::= - Struct LeftBrace - (variableDeclarationStatement)+ - RightBrace - - -patchPredefinedType ::= - patchType Less - userDefinedType Comma IntegerLiteral - Greater - - -patchType ::= - - InputPatch - | OutputPatch - - -samplerStatePredefinedType ::= - - Sampler - | SamplerState - | SamplerComparisonState - - -scalarType ::= - - Bool - | Int - | Unsigned Int - | Dword - | Uint - | Half - | Float - | Double - - -streamOutputPredefinedType ::= - streamOutputObjectType Less type Greater - - -streamOutputObjectType ::= - PointStream - | LineStream - | TriangleStream - - -structuredBufferPredefinedType ::= - structuredBufferName Less scalarOrVectorOrUserDefinedType Greater - - -structuredBufferName ::= - AppendStructuredBuffer - | ConsumeStructuredBuffer - | RWStructuredBuffer - | StructuredBuffer - - -textureType ::= - TextureTypes - - -texturePredefinedType ::= - textureType - - -genericTexturePredefinedType ::= - textureType Less scalarOrVectorType Greater - - -textureTypeMS ::= - Texture2DMS - | Texture2DMSArray - - -msTexturePredefinedType ::= textureTypeMS Less scalarOrVectorType Comma IntegerLiteral Greater - - -vectorType ::= - Vector - | UintVec - | IntVec - | HalfVec - | FloatVec - | DoubleVec - | BoolVec - - -genericVectorType ::= - Vector Less scalarType Comma - IntegerLiteral Greater - - -scalarOrVectorType ::= - scalarType - | vectorType - - -scalarOrVectorOrUserDefinedType ::= - scalarType - | vectorType - | userDefinedType - - -scalarOrVectorOrMatrixType ::= - scalarType - | vectorType - | matrixType - -matrixType ::= - Matrix - | BoolMat - | UintMat - | IntMat - | HalfMat - | FloatMat - | DoubleMat - -genericMatrixPredefinedType ::= Matrix Less scalarType Comma - IntegerLiteral Comma IntegerLiteral - Greater - - -userDefinedType ::= - Identifier - -userDefinedNames ::= - Identifier - Keywords - -registerAllocation ::= Colon Register LeftParen Identifier RightParen - - -variableInitializer ::= - Assign standardVariableInitializer - | LeftBrace samplerStateProperty* RightBrace - - -standardVariableInitializer ::= - LeftBrace arrayElementInitializers RightBrace - | expression - - -arrayElementInitializers ::= standardVariableInitializer (Comma standardVariableInitializer)* Comma? - - -samplerStateProperty ::= Identifier Assign expression Semi - -identifierOrKeyword ::= - Identifier - Keywords - | Keywords \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLTokens.ebnf b/src/Stride.Shader.Parser/SDSLTokens.ebnf deleted file mode 100644 index c9e32b353c..0000000000 --- a/src/Stride.Shader.Parser/SDSLTokens.ebnf +++ /dev/null @@ -1,374 +0,0 @@ -WS ::= ? Terminals.Whitespace ? -Eol ::= ? Terminals.Eol ? -Eof ::= ? Terminals.End ? -Space ::= WS | Eol | Eof -Spaces ::= Space* -SpacesWithLineBreak ::= WS* Eol - - -AppendStructuredBuffer ::= 'AppendStructuredBuffer' -Bool ::= 'bool' -BoolVec ::= Bool [1-4] -BoolMat ::= BoolVec 'x' [1-4] -Buffer ::= 'Buffer' -ByteAddressBuffer ::= 'ByteAddressBuffer' -Break ::= 'break' -Case ::= 'case' -CBuffer ::= 'cbuffer' -Centroid ::= 'centroid' -Class ::= 'class' -ColumnMajor ::= 'column_major' -Const ::= 'const' -ConsumeStructuredBuffer ::= 'ConsumeStructuredBuffer' -Continue ::= 'continue' -Default ::= 'default' -Discard ::= 'discard' -Do ::= 'do' -Double ::= 'double' -DoubleVec ::= Double [1-4] -DoubleMat ::= DoubleVec 'x' [1-4] -Else ::= 'else' -Extern ::= 'extern' -Float ::= 'float' -FloatVec ::= Float [1-4] -FloatMat ::= FloatVec 'x' [1-4] -For ::= 'for' -Groupshared ::= 'groupshared' -Half ::= 'half' -HalfVec ::= Half [1-4] -HalfMat ::= HalfVec 'x' [1-4] -If ::= 'if' -In ::= 'in' -Inout ::= 'inout' | 'in out' -InputPatch ::= 'InputPatch' -Int ::= 'int' -IntVec ::= Int [1-4] -IntMat ::= IntVec 'x' [1-4] -Interface ::= 'interface' -Line_ ::= 'line' -LineAdj ::= 'lineadj' -Linear ::= 'linear' -LineStream ::= 'LineStream' -Long ::= 'long' -Matrix ::= 'matrix' -Nointerpolation ::= 'nointerpolation' -Noperspective ::= 'noperspective' -Out ::= 'out' -OutputPatch ::= 'OutputPatch' -Packoffset ::= 'packoffset' -Point ::= 'point' -PointStream ::= 'PointStream' -Precise ::= 'precise' -Register ::= 'register' -Return ::= 'return' -RowMajor ::= 'row_major' -RWBuffer ::= 'RWBuffer' -RWByteAddressBuffer ::= 'RWByteAddressBuffer' -RWStructuredBuffer ::= 'RWStructuredBuffer' -Sample ::= 'sample' -Sampler ::= 'sampler' -SamplerComparisonState ::= 'SamplerComparisonState' -SamplerState ::= 'SamplerState' -Shared ::= 'shared' -Static ::= 'static' -Struct ::= 'struct' -StructuredBuffer ::= 'StructuredBuffer' -Switch ::= 'switch' -TextureTypes ::= - (('Texture' - 'Texture2DMS') ([1-3] 'D') ('Array'?)) - | ('Texture2DMS' 'Array'?) - | ('TextureCube' 'Array'?) - -Triangle ::= 'triangle' -TriangleAdj ::= 'triangleadj' -TriangleStream ::= 'TriangleStream' -Uniform ::= 'uniform' -Uint ::= 'uint' | 'unsigned int' | 'dword' -UintVec ::= Uint [1-4] -UintMat ::= UintVec 'x' [1-4] -Vector ::= 'vector' -Volatile ::= 'volatile' -Void ::= 'void' -While ::= 'while' - -LeftParen ::= '(' -RightParen ::= ')' -LeftBracket ::= '[' -RightBracket ::= ']' -LeftBrace ::= '{' -RightBrace ::= '}' - - -LeftShift ::= '<<' -RightShift ::= '>>' -Plus ::= [+] -PlusPlus ::= '++' -Minus ::= '-' -MinusMinus ::= '--' -Star ::= '*' -Div ::= '/' -Mod ::= '%' - - -IncOperators ::= - PlusPlus - | MinusMinus - -Operators ::= - Plus - | Minus - | Star - | Div - | Mod - | LeftShift - | RightShift - -And ::= '&' -Or ::= '|' -AndAnd ::= '&&' -OrOr ::= '||' -Caret ::= '^' -Not ::= '!' -Tilde ::= '~' - -Equal ::= '==' -NotEqual ::= '!=' - -Less ::= '<' -LessEqual ::= '<=' -Greater ::= '>' -GreaterEqual ::= '>=' - -Question ::= '?' -Colon ::= ':' -ColonColon ::= '::' -Semi ::= '' -Comma ::= ',' - -Assign ::= '=' -StarAssign ::= '*=' -DivAssign ::= '/=' -ModAssign ::= '%=' -PlusAssign ::= '+=' -MinusAssign ::= '-=' -LeftShiftAssign ::= '<<=' -RightShiftAssign ::= '>>=' -AndAssign ::= '&=' -XorAssign ::= '^=' -OrAssign ::= '|=' - -AssignOperators ::= - Assign - | StarAssign - | DivAssign - | ModAssign - | PlusAssign - | MinusAssign - | LeftShiftAssign - | RightShiftAssign - | AndAssign - | XorAssign - | OrAssign - - - -Dot ::= '.' - -True ::= 'true' -False ::= 'false' - -Identifier ::= - [a-zA-Z_] ([a-zA-Z_] | [0-1])* - -Nondigit ::= [a-zA-Z_] - -Digit1 ::= [1-9] -Digit ::= '0' | Digit1 - -IntegerSuffix ::= [ulUL]? - -HexadecimalDigitSequence ::= HexadecimalDigit+ - - -DecimalIntegerLiteral ::= "0" | [1-9] [0-9]* - -HexadecimalDigit ::= [0-9a-fA-F] -HexadecimalIntegerLiteral::= ('0x' | '0X') HexadecimalDigit+ - -/*IntegerLiteral ::= - Sign? - ( - (DecimalIntegerLiteral - HexadecimalIntegerLiteral) IntegerSuffix? - | HexadecimalIntegerLiteral IntegerSuffix? - )*/ -IntegerLiteral ::= - (Sign DecimalIntegerLiteral - HexadecimalIntegerLiteral - | Sign HexadecimalIntegerLiteral - | DecimalIntegerLiteral - HexadecimalIntegerLiteral - | HexadecimalIntegerLiteral) IntegerSuffix - -FloatingSuffix ::= "f" - -FractionalConstant ::= - DecimalIntegerLiteral? '.' Digit* - -ExponentPart ::= - 'e' Sign? DecimalIntegerLiteral - | 'E' Sign? DecimalIntegerLiteral - -FloatLiteral ::= - Sign? - ( - (DecimalIntegerLiteral - FractionalConstant) ExponentPart? FloatingSuffix? - | FractionalConstant ExponentPart? FloatingSuffix? - ) - - -Sign ::= '+' | '-' - -EscapeSequence ::= SimpleEscapeSequence - - -SimpleEscapeSequence ::= '\\' ['"?abfnrtv\\] - -StringLiteral ::= '"' SCharSequence? '"' - - -SCharSequence ::= SChar+ - - -SChar ::= - (SCharSequence - ["\\\r\n]) - | EscapeSequence - - -literal ::= - IntegerLiteral - | FloatLiteral - | StringLiteral - - -PreprocessorDirective ::= '#' Whitespace? PreprocessorDirectiveName - - -PreprocessorDirectiveName ::= - 'define' - | 'elif' - | 'else' - | 'endif' - | 'error' - | 'if' - | 'ifdef' - | 'ifndef' - | 'include' - | 'line' - | 'pragma' - | 'undef' - - -LineComment ::= '//' (SCharSequence - [\r\n]) - -BlockComment ::= '/*' SCharSequence '*/' - - -BoolTypes ::= - Bool - BoolVec - | BoolVec - BoolMat - | BoolMat - -HalfTypes ::= - Half - HalfVec - | HalfVec - HalfMat - | HalfMat - -FloatTypes ::= - Float - FloatVec - | FloatVec - FloatMat - | FloatMat - -DoubleTypes ::= - Double - DoubleVec - | DoubleVec - DoubleMat - | DoubleMat - -IntTypes ::= - Int - IntVec - | IntVec - IntMat - | IntMat - -UintTypes ::= - Uint - UintVec - | UintVec - UintMat - | UintMat - -ValueTypes ::= - BoolTypes - | HalfTypes - | FloatTypes - | DoubleTypes - | IntTypes - | UintTypes - -Keywords ::= - AppendStructuredBuffer - | Buffer - ByteAddressBuffer - | ByteAddressBuffer - Break - | Break - | Case - CBuffer - | CBuffer - Centroid - | Centroid - Class - | Class - ColumnMajor - | ColumnMajor - Const - | Const - ConsumeStructuredBuffer - | ConsumeStructuredBuffer - Continue - | Continue - | Default - Discard - | Discard - | Do - | Else - | Extern - | For - | Groupshared - | If - | In - | Inout - | InputPatch - | Interface - | Line_ - | LineAdj - | Linear - | LineStream - | Matrix - | Nointerpolation - | Noperspective - | Out - | OutputPatch - | Packoffset - | Point - | PointStream - | Precise - | Register - | Return - | RowMajor - | RWBuffer - | RWByteAddressBuffer - | RWStructuredBuffer - | Sample - Sampler - | Sampler - | SamplerComparisonState - | SamplerState - | Shared - | Static - | Struct - | StructuredBuffer - | Switch - | TextureTypes - | Triangle - | TriangleAdj - | TriangleStream - | Uniform - | ValueTypes - | Vector - | Volatile - | Void - | While \ No newline at end of file diff --git a/src/Stride.Shader.Parser/StrideGrammar.cs b/src/Stride.Shader.Parser/StrideGrammar.cs deleted file mode 100644 index 487e4459ed..0000000000 --- a/src/Stride.Shader.Parser/StrideGrammar.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace Stride.Shader.Parser; - -using Eto.Parse; -using Eto.Parse.Grammars; -using System.Text; -public static class StrideGrammar -{ - public static Grammar New() - { - return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),"shader"); - } - public static Grammar New(string parser) - { - return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.grammar),parser); - } - public static Grammar Token() - { - return new EbnfGrammar(EbnfStyle.W3c).Build(Encoding.UTF8.GetString(GrammarResource.SDSLTokens),"BaseTypes"); - } - public static Grammar HlslGrammar() - { - var s = new StringBuilder(); - s - .Append(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) - .Append(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); - - return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),"identifierOrKeyword"); - } - public static Grammar HlslGrammar(string startParser) - { - var s = new StringBuilder(); - s - .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLTokens)) - .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLDirective)) - .AppendLine(Encoding.UTF8.GetString(GrammarResource.SDSLExpr)); - - return new EbnfGrammar(EbnfStyle.W3c).Build(s.ToString(),startParser); - } - -} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/TestGrammar.cs b/src/Stride.Shader.Parser/TestGrammar.cs deleted file mode 100644 index 9dace1a101..0000000000 --- a/src/Stride.Shader.Parser/TestGrammar.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; - -namespace SDSLParser -{ - public class TestGrammar : Grammar - { - private static bool IsLetterDigitOrUnderscore(char c) - { - return char.IsLetterOrDigit(c) || c.Equals("_"); - } - public TestGrammar() : base("test-sdsl") - { - EnableMatchEvents = false; - CaseSensitive = true; - - var ws = new RepeatCharTerminal(char.IsWhiteSpace); - var wso = ws.Optional(); - - var eof = Terminals.End; - - var eol = Terminals.Eol; - var eolo = eol.Optional(); - - var shaderDeclaration = Terminals.Set("shader"); - - var ldu = Terminals.LetterOrDigit | "_"; - var identifier = Terminals.LetterOrDigit.Then(ldu.Repeat().Optional()).Named("Identifier"); - - var lbr = Terminals.Set("{"); - var rbr = Terminals.Set("}"); - - var intParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = false, Name = "ConstantInt"}; - var floatParser = new NumberParser{AllowSign = true, AllowDecimal = false, AllowExponent = true, Name = "ConstantInt"}; - var boolParser = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"}, FalseValues = new string[]{"false"}}; - - var constants = intParser | floatParser | boolParser; - - var unary_op = - Terminals.Set("&") - | Terminals.Set("*") - | Terminals.Set("+") - | Terminals.Set("-") - | Terminals.Set("/") - | Terminals.Set("!"); - var assign_op = - Terminals.Set("=") - | Terminals.Set("*=") - | Terminals.Set("/=") - | Terminals.Set("%=") - | Terminals.Set("+=") - | Terminals.Set("-=") - | Terminals.Set("<<=") - | Terminals.Set(">>=") - | Terminals.Set("&=") - | Terminals.Set("^=") - | Terminals.Set("|="); - - var primary_expr = identifier | constants; - - var unary_expr = new SequenceParser().WithName("UnaryExpression"); - var cast_expr = new SequenceParser().WithName("CastExpression"); - var postfix_expr = new SequenceParser().WithName("PostfixExpression"); - var assign_expr = new SequenceParser().WithName("AssignmentExpression"); - var l_or_expr = new SequenceParser().WithName("LogicalOrExpression"); - var l_and_expr = new SequenceParser().WithName("LogicalAndExpression"); - var or_expr = new SequenceParser().WithName("OrExpression"); - var xor_expr = new SequenceParser().WithName("XOrExpression"); - var and_expr = new SequenceParser().WithName("AndExpression"); - var eq_expr = new SequenceParser().WithName("EqualityExpression"); - var rel_expr = new SequenceParser().WithName("RelationalExpression"); - var shift_expr = new SequenceParser().WithName("ShiftExpression"); - var add_expr = new SequenceParser().WithName("AdditiveExpression"); - var mul_expr = new SequenceParser().WithName("MultiplicativeExpression"); - - postfix_expr.Add(primary_expr.Named("Value")); - unary_expr.Add(postfix_expr.Named("Value")); - // cast_expr.Add(identifier.Named("Value")); - var tmpCast = unary_expr | Terminals.Set("(") & identifier.Named("Target") & ")" & identifier.Named("Value"); - // cast_expr.Add("(", identifier.Named("Target"), ")", identifier.Named("Value")); - cast_expr.Add(tmpCast); - - Inner = cast_expr; - - } - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/grammar.ebnf b/src/Stride.Shader.Parser/grammar.ebnf deleted file mode 100644 index 81440a655c..0000000000 --- a/src/Stride.Shader.Parser/grammar.ebnf +++ /dev/null @@ -1,125 +0,0 @@ -id ::= ?Terminals.Letter? (?Terminals.LetterOrDigit? | "_")* -eol ::= ? Terminals.Eol ? - -eols ::= eol* - -eof ::= ? Terminals.End ? - -any_space ::= (wso | eols)* -one_space ::= (wso | eols)+ - -assign_op ::= - "=" - | "+=" - | "-=" - | "/=" - | "*=" - | "&=" - | "|=" - | "~=" - - -integer ::= "0" | ([0-9] [1-9]*) -float ::= - (integer "." [0-9] [0-9]*) - | (integer "f"?) - -ws ::= (? Terminals.WhiteSpace ?)* - -wso ::= ws* - -term ::= - id - | (integer - float) - | float - | paren_expr - -mul ::= - term - | mul '*' term - | mul '/' term - | mul '%' term - - -sum ::= - mul - | sum '++' - | sum '+' mul - | sum '-' mul - -primary_value ::= id | sum - -test ::= - sum - | sum '<' sum - | sum '>' sum - | sum '<=' sum - | sum '>=' sum - - -inc_op ::= "++" | "--" -pfix_inc ::= primary_value inc_op -ifix_inc ::= inc_op primary_value - -idx_accessor ::= id "[" expr "]" -accessor ::= (id | paren_expr) "." id -cast ::= "(" id ")" expr - -assign ::= - id any_space assign_op any_space expr - | accessor any_space assign_op any_space expr - | cast any_space assign_op any_space expr - | idx_accessor any_space assign_op any_space expr - - -expr ::= - (test - assign) -/* | (accessor - assign) - | (idx_accessor - assign) - | assign - | (paren_expr - cast) - | cast*/ - -paren_expr ::= '(' expr ')' - - -typename ::= id - -stage ::= "stage" -stream ::= "stream" - -declaration ::= - ((stage | stream) one_space)? typename one_space id any_space (assign_op any_space expr)? - -stage_declaration ::= - stage one_space typename one_space id any_space (assign_op any_space expr)? - -expression ::= - expr - declaration - | declaration - -statement ::= - 'if' paren_expr statement - | 'if' paren_expr statement 'else' statement - | 'while' paren_expr statement - | 'do' statement 'while' paren_expr ';' - | '{' any_space statement* any_space '}' - | expression any_space ';' - | ';' - -c_buffer ::= - "c_buffer" one_space id any_space any_space "{" any_space (stage_declaration any_space";")* any_space "}" - -shader_class ::= - "shader" one_space id any_space - "{" - any_space - ( - (declaration ";" any_space)* - c_buffer - | (c_buffer) - )* - any_space - "}" - - -shader ::= shader_class \ No newline at end of file diff --git a/src/Stride.Shader.Parser.Test/BasicParsing.cs b/src/Stride.Shader.Parsing.Test/BasicParsing.cs similarity index 96% rename from src/Stride.Shader.Parser.Test/BasicParsing.cs rename to src/Stride.Shader.Parsing.Test/BasicParsing.cs index 09501c4f3f..2667279823 100644 --- a/src/Stride.Shader.Parser.Test/BasicParsing.cs +++ b/src/Stride.Shader.Parsing.Test/BasicParsing.cs @@ -1,11 +1,11 @@ using Xunit; using System.Linq; -using Stride.Shader.Parser; +using Stride.Shader.Parsing; using Eto.Parse; using Eto.Parse.Parsers; using System.Collections.Generic; -namespace Stride.Shader.Parser.Test; +namespace Stride.Shader.Parsing.Test; public class BasicParsing { diff --git a/src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj b/src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj similarity index 91% rename from src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj rename to src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj index 42fa97f2c5..0c92e1b4f4 100644 --- a/src/Stride.Shader.Parser.Test/Stride.Shader.Parser.Test.csproj +++ b/src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/Stride.Shader.Parsing/CommentGrammar.cs b/src/Stride.Shader.Parsing/CommentGrammar.cs new file mode 100644 index 0000000000..10729d30df --- /dev/null +++ b/src/Stride.Shader.Parsing/CommentGrammar.cs @@ -0,0 +1,27 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing +{ + public class CommentGrammar : Grammar + { + public SequenceParser Comments = new(); + + public CommentGrammar() : base("comments-sdsl") + { + var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); + var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); + + Comments.Add( + AnyChar.Repeat(0).Until( + (singleLineComment| blockComment).Repeat(0), + false, + false) + .Repeat(0) + ); + Inner = Comments; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 b/src/Stride.Shader.Parsing/Hlsl/HlslExpr.g4 similarity index 100% rename from src/Stride.Shader.Parser/Hlsl/HlslExpr.g4 rename to src/Stride.Shader.Parsing/Hlsl/HlslExpr.g4 diff --git a/src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 b/src/Stride.Shader.Parsing/Hlsl/HlslTokens.g4 similarity index 100% rename from src/Stride.Shader.Parser/Hlsl/HlslTokens.g4 rename to src/Stride.Shader.Parsing/Hlsl/HlslTokens.g4 diff --git a/src/Stride.Shader.Parser/Hlsl/code.hlsl b/src/Stride.Shader.Parsing/Hlsl/code.hlsl similarity index 100% rename from src/Stride.Shader.Parser/Hlsl/code.hlsl rename to src/Stride.Shader.Parsing/Hlsl/code.hlsl diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index e3ee93e4ab..b978adb8b8 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser DirectiveTerm = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 98% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs index bb19bf33ba..998cd4805d 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public SequenceParser IfDirective = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 99% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index e25e0a16b6..6a8c6cb4c8 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 98% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs index 4cf5ef968c..7e609c167e 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { AlternativeParser IntegerSuffix = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 85% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 9aa9bd7a3b..a8271168c1 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); @@ -30,12 +30,12 @@ public void CreateShader() Comma.Optional().Then(Identifier).Then(generics).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); var comments = - SingleLineComment - | BlockComment; + (SingleLineComment + | BlockComment).Repeat(0); var shaderContentTypes = - comments - | GenericDeclaration - | MethodDeclaration; + GenericDeclaration + | MethodDeclaration + | comments; var shaderBody = LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); @@ -45,6 +45,7 @@ public void CreateShader() .Then(Identifier.Then(generics.Optional()).SeparatedBy(ws)).SeparatedBy(ws1) //.Then(Literal(":").Then(mixins).SeparatedBy(ws).Optional()) .Then(shaderBody).Named("ShaderProgram") + .Then(";").SeparatedBy(ws) ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 99% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index 6ecd212849..2d6fa8f30f 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser StructDefinition = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 99% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index ace8fc3ee7..1e954751ea 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser IncOperators = new(); diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 99% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs index 9a7dc210c3..4d1eb5dcd7 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -1,7 +1,7 @@ using Eto.Parse; using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { private CharTerminal WS; diff --git a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs similarity index 93% rename from src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index ea6a837cf9..af819e0836 100644 --- a/src/Stride.Shader.Parser/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parser; +namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public SDSLGrammar() : base("sdsl") diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs new file mode 100644 index 0000000000..9c97188738 --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -0,0 +1,22 @@ +namespace Stride.Shader.Parsing; + +using Eto.Parse; +using Eto.Parse.Grammars; +using System.Text; +public class SDSLParser +{ + public CommentGrammar Comments {get;set;} + public SDSLGrammar SdslGrammar {get;set;} + + public SDSLParser() + { + Comments = new(); + SdslGrammar = new(); + } + + public GrammarMatch Parse(string shader) + { + return Comments.Match(shader); + } + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parser/Stride.Shader.Parser.csproj b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj similarity index 100% rename from src/Stride.Shader.Parser/Stride.Shader.Parser.csproj rename to src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj From d6806c8e287482f7e7fc30935fc5d275522b982c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 5 May 2022 11:16:00 +0200 Subject: [PATCH 0046/1182] Comment removal parser --- src/SDSLParserExample/Program.cs | 4 ++-- src/SDSLParserExample/SDSL/comments.sdsl | 6 ++++++ src/Stride.Shader.Parsing/CommentGrammar.cs | 13 +++++++------ .../SDSLGrammar/SDSLGrammar.cs | 1 + src/Stride.Shader.Parsing/SDSLParser.cs | 12 +++++++++++- 5 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 src/SDSLParserExample/SDSL/comments.sdsl diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index e5c6de9a96..14c06fdc38 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -9,9 +9,9 @@ var parser = new SDSLParser(); var sdslParser = new SDSLGrammar().UsingShader(); var s = new Stopwatch(); -var match2 = sdslParser.Match(shaderf); +var match2 = parser.Parse(shaderf); s.Start(); -var match = sdslParser.Match(shaderf); +var match = parser.Parse(shaderf); s.Stop(); diff --git a/src/SDSLParserExample/SDSL/comments.sdsl b/src/SDSLParserExample/SDSL/comments.sdsl new file mode 100644 index 0000000000..1f1a9ca932 --- /dev/null +++ b/src/SDSLParserExample/SDSL/comments.sdsl @@ -0,0 +1,6 @@ +// my first line +// Hello second line +float a; +/* this is a block comment + And i can say a bit more on this line +*/ \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/CommentGrammar.cs b/src/Stride.Shader.Parsing/CommentGrammar.cs index 10729d30df..4439bb6da0 100644 --- a/src/Stride.Shader.Parsing/CommentGrammar.cs +++ b/src/Stride.Shader.Parsing/CommentGrammar.cs @@ -11,14 +11,15 @@ public class CommentGrammar : Grammar public CommentGrammar() : base("comments-sdsl") { - var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); + var commentStart = + Literal("//") + | Literal("/*"); + var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("LineComment"); var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); - + var anyComments = singleLineComment | blockComment; Comments.Add( - AnyChar.Repeat(0).Until( - (singleLineComment| blockComment).Repeat(0), - false, - false) + anyComments.Repeat(0).SeparatedBy(WhiteSpace.Repeat(0)).Named("Comments") + .Then(AnyChar.Repeat(0).Until(commentStart).Named("ActualCode")) .Repeat(0) ); Inner = Comments; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index af819e0836..2c573cda98 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -10,6 +10,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar() : base("sdsl") { CreateAll(); + Inner = Shader; } public void CreateAll() diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index 9c97188738..113525b7f4 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -16,7 +16,17 @@ public SDSLParser() public GrammarMatch Parse(string shader) { - return Comments.Match(shader); + var comments = Comments.Match(shader); + var actualCode = new StringBuilder(); + foreach(var m in comments.Matches) + { + if(m.Name == "ActualCode") + { + actualCode.Append(m.StringValue); + } + } + var match = SdslGrammar.Match(actualCode.ToString()); + return match; } } \ No newline at end of file From ef851f4aad8cc0b3556c149d8c225f91535e0a90 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 5 May 2022 11:21:58 +0200 Subject: [PATCH 0047/1182] correction readme --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index d9d72a4915..59ece41eaa 100644 --- a/Readme.md +++ b/Readme.md @@ -6,7 +6,7 @@ [SDSL](https://doc.stride3d.net/latest/en/manual/graphics/effects-and-shaders/shading-language/index.html) is a shader language created for the [Stride game engine](https://www.stride3d.net/). -a superset of the HLSL Shading language, bringing advanced and higher level language constructions, with: +SDSL is a superset of the HLSL Shading language, bringing advanced and higher level language constructions, with: * **extensibility** to allow shaders to be extended easily using object-oriented programming concepts such as classes, inheritance, and composition From cb9296ef566920c90ea745930e4ea729d05df984 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 6 May 2022 19:11:26 +0200 Subject: [PATCH 0048/1182] Correction space around shader + generics --- src/SDSLParserExample/SDSL/shader.sdsl | 11 +- .../SDSLGrammar/SDSLGrammar.EntryPoints.cs | 112 ++++++++++++++++++ .../SDSLGrammar/SDSLGrammar.Literals.cs | 19 +-- .../SDSLGrammar/SDSLGrammar.Shader.cs | 32 ++--- .../SDSLGrammar/SDSLGrammar.Statements.cs | 32 +++-- .../SDSLGrammar/SDSLGrammar.cs | 1 + 6 files changed, 173 insertions(+), 34 deletions(-) create mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl index 266edd6492..ea3aeb7ecc 100644 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -1,8 +1,8 @@ -shader BasicMixin -{ +// Some comments +shader BasicMixin : BasicShader, Parent2, Parent3 { float myFloat = 0.2f; stage float3 myPosition : register(b); - //stage stream float2 screenPosition : register(vs, b); + stage stream float2 screenPosition : register(vs, b); abstract void myFunc(); @@ -10,4 +10,9 @@ shader BasicMixin { return float4(1.0); } + + void PSMain() + { + streams.ColorTarget = float4(0,0,0,1); + } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs new file mode 100644 index 0000000000..2bfa791351 --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs @@ -0,0 +1,112 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser VSMain = new(); + public AlternativeParser GSMain = new(); + public AlternativeParser PSMain = new(); + public AlternativeParser CSMain = new(); + public AlternativeParser HSMain = new(); + public AlternativeParser HSConstantsMain = new(); + public AlternativeParser DSMain = new(); + public AlternativeParser Entries = new(); + + + + public SDSLGrammar UsingEntry() + { + Inner = Entries; + return this; + } + public void CreateEntryPoints() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + var vs = Literal("VSMain"); + var ps = Literal("PSMain"); + var gs = Literal("GSMain"); + var cs = Literal("CSMain"); + var ds = Literal("DSMain"); + var hs = Literal("HSMain"); + var hsc = Literal("HSConstantsMain"); + var abstractM = Literal("abstract"); + + + VSMain.Add( + abstractM.Optional().Then(Void).Then(vs).SeparatedBy(ws1) + .Then(LeftParen).Then(RightParen) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + PSMain.Add( + abstractM.Optional().Then(Void).Then(ps).SeparatedBy(ws1) + .Then(LeftParen).Then(RightParen) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + GSMain.Add( + Attribute.Repeat(0).SeparatedBy(ws) + .Then(abstractM.Optional()).Then(Void).Then(gs).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + CSMain.Add( + Attribute.Repeat(0).SeparatedBy(ws) + .Then(abstractM.Optional()).Then(Void).Then(cs).SeparatedBy(ws1) + .Then(LeftParen).Then(RightParen) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + HSMain.Add( + Attribute.Repeat(0).SeparatedBy(ws) + .Then(abstractM.Optional()).Then(Void).Then(hs).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + HSConstantsMain.Add( + Attribute.Repeat(0).SeparatedBy(ws) + .Then(abstractM.Optional()).Then(Void).Then(hsc).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + DSMain.Add( + Attribute.Repeat(0).SeparatedBy(ws) + .Then(abstractM.Optional()).Then(Void).Then(ds).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace) + .SeparatedBy(ws) + ); + + Entries.Add( + VSMain + | PSMain + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs index 7e609c167e..0784c5b8ce 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs @@ -9,12 +9,11 @@ public partial class SDSLGrammar : Grammar { AlternativeParser IntegerSuffix = new(); AlternativeParser FloatSuffix = new(); - - public SequenceParser SingleLineComment = new(); - public SequenceParser BlockComment = new(); public StringParser StringLiteral = new(); - public EtoParser Identifier; + public SequenceParser Identifier = new(); + public AlternativeParser UserDefinedId = new(); + public NumberParser IntegerLiteral = new(); public NumberParser FloatLiteral = new(); public HexDigitTerminal HexDigits = new(); @@ -31,7 +30,14 @@ public SDSLGrammar UsingLiterals() } public void CreateLiterals() { - Identifier = Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier"); + Identifier.Add( + Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier") + ); + + UserDefinedId.Add( + Identifier.Except(Keywords) + ); + IntegerSuffix = Literal("u") | Literal("l") @@ -44,8 +50,7 @@ public void CreateLiterals() | Literal("F") | Literal("D"); - SingleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol)).WithName("LineComment"); - BlockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); + StringLiteral = new StringParser().WithName("StringLiteral"); IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index a8271168c1..738064dc84 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -17,35 +17,39 @@ public SDSLGrammar UsingShader() public void CreateShader() { var ws = WhiteSpace.Repeat(0); - var ws1 = WhiteSpace.Repeat(1); + var ws1 = WhiteSpace.Repeat(1); var genericValue = Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType") - | ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"); + | ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue") + | ValueTypes; var generics = - Literal("<").Then(Comma.Optional().Then(genericValue).Repeat(1)).Then(">").SeparatedBy(ws); + Literal("<") + .Then(genericValue) + .Then( + Comma.Then(genericValue).SeparatedBy(ws).Repeat(0) + ) + .Then(">").SeparatedBy(ws); - var mixins = - Comma.Optional().Then(Identifier).Then(generics).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); - - var comments = - (SingleLineComment - | BlockComment).Repeat(0); var shaderContentTypes = GenericDeclaration - | MethodDeclaration - | comments; + | Entries + | MethodDeclaration; var shaderBody = LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); + var inheritances = Colon.Then(Identifier.Then(generics.Optional()).Then(Comma.Then(Identifier.Then(generics.Optional())).SeparatedBy(ws).Repeat(0))).SeparatedBy(ws).Optional(); + + Shader.Add( - Literal("shader") - .Then(Identifier.Then(generics.Optional()).SeparatedBy(ws)).SeparatedBy(ws1) - //.Then(Literal(":").Then(mixins).SeparatedBy(ws).Optional()) + ws.Then(Literal("shader")) + .Then(Identifier.Then(generics.Optional())).SeparatedBy(ws1).Then(inheritances.Named("Inherit")) + //.Then(Literal(":").Then(Identifier.Then(Comma.Then(Identifier).Repeat(0))).SeparatedBy(ws).Optional()) .Then(shaderBody).Named("ShaderProgram") .Then(";").SeparatedBy(ws) + .Then(ws) ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index 2d6fa8f30f..77db0ff09f 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -6,6 +6,7 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser StructDefinition = new(); + public AlternativeParser ParameterList = new(); public AlternativeParser Attribute = new(); public AlternativeParser Statement = new(); public AlternativeParser ControlFlow = new(); @@ -26,7 +27,7 @@ public void CreateStatements() var ws1 = WhiteSpace.Repeat(1); var declare = - Identifier.Then(Identifier).SeparatedBy(ws1).Then(";").SeparatedBy(ws); + Identifier.Then(Identifier).SeparatedBy(ws1).Then(Semi).SeparatedBy(ws); var assignVar = Identifier.Named("Variable").NotFollowedBy(Identifier) @@ -34,7 +35,13 @@ public void CreateStatements() .Then(PrimaryExpression.Named("Value")) .Then(Semi) .SeparatedBy(ws); - + + var assignChain = + Identifier.Then(Dot.Then(Identifier).Repeat(0)) + .Then(AssignOperators) + .Then(PrimaryExpression) + .Then(Semi) + .SeparatedBy(ws); var declareAssign = @@ -83,9 +90,9 @@ public void CreateStatements() ); Statement.Add( - Attribute.Named("Attribute") - | Block.Named("BlockExpression") + Block.Named("BlockExpression") | returnStatement.Named("Return") + | assignChain | declareAssign.Named("DeclareAssign") | assignVar.Named("Assign") | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") @@ -114,16 +121,21 @@ public void CreateStatements() ); var parameter = Identifier.Then(Identifier).SeparatedBy(ws1); - var parameterList = + ParameterList.Add( LeftParen .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) - .Then(RightParen).SeparatedBy(ws); + .Then(RightParen).SeparatedBy(ws) + ); MethodDeclaration.Add( - Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1).Then(parameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") - | Literal("stage").Optional().Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(parameterList) - .Then(LeftBrace).Then(Statement.Repeat(0)).Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") + Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) + .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") + | Literal("override").Optional().Then(Literal("stage").Optional()) + .Then(Identifier).Then(Identifier).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0)) + .Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") ); ConstantBuffer.Add( diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index 2c573cda98..f9a71f8854 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -22,6 +22,7 @@ public void CreateAll() CreateDirectiveExpressions(); CreateExpressions(); CreateStatements(); + CreateEntryPoints(); CreateShader(); } } From 69497f526164264d8da1894e5a98c4ec6f6fa66b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 6 May 2022 19:11:53 +0200 Subject: [PATCH 0049/1182] removed comments for generics --- src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 738064dc84..eb36adf622 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -46,7 +46,6 @@ public void CreateShader() Shader.Add( ws.Then(Literal("shader")) .Then(Identifier.Then(generics.Optional())).SeparatedBy(ws1).Then(inheritances.Named("Inherit")) - //.Then(Literal(":").Then(Identifier.Then(Comma.Then(Identifier).Repeat(0))).SeparatedBy(ws).Optional()) .Then(shaderBody).Named("ShaderProgram") .Then(";").SeparatedBy(ws) .Then(ws) From 402819a5be137e8293298f68ae682056aca40a2e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 6 May 2022 19:16:17 +0200 Subject: [PATCH 0050/1182] Correction + added more complex entrypoint --- src/SDSLParserExample/SDSL/shader.sdsl | 6 ++++++ src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl index ea3aeb7ecc..1e5b4a076f 100644 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -15,4 +15,10 @@ shader BasicMixin : BasicShader, Par { streams.ColorTarget = float4(0,0,0,1); } + + [maxvertexcount(GeometryShaderMaxVertexCount)] + void GSMain(triangle Input input[3], inout TriangleStream triangleStream) + { + Storage.GenerateTriangles(input, triangleStream); + } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index eb36adf622..9afee932f5 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -44,7 +44,7 @@ public void CreateShader() Shader.Add( - ws.Then(Literal("shader")) + Literal("shader") .Then(Identifier.Then(generics.Optional())).SeparatedBy(ws1).Then(inheritances.Named("Inherit")) .Then(shaderBody).Named("ShaderProgram") .Then(";").SeparatedBy(ws) From b5e29513bc6f8297f4f610cce4d781c2d9c55a6a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 8 May 2022 23:55:24 +0200 Subject: [PATCH 0051/1182] Correction accessors --- src/SDSLParserExample/Program.cs | 8 +- src/SDSLParserExample/SDSL/Expressions.sdsl | 2 +- src/SDSLParserExample/SDSL/Methods.sdsl | 8 ++ src/SDSLParserExample/SDSL/shader.sdsl | 12 +- src/Stride.Shader.Parsing/CommentGrammar.cs | 8 +- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 65 ++++++++++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 105 ++++++++-------- .../SDSLGrammar/SDSLGrammar.Literals.cs | 6 +- .../SDSLGrammar.MethodDeclaration.cs | 61 +++++++++ .../SDSLGrammar/SDSLGrammar.Shader.cs | 26 ++-- .../SDSLGrammar/SDSLGrammar.Statements.cs | 119 +++++++----------- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 29 +++++ .../SDSLGrammar/SDSLGrammar.Tokens.cs | 7 ++ .../SDSLGrammar/SDSLGrammar.cs | 8 ++ src/Stride.Shader.Parsing/SDSLParser.cs | 17 ++- 15 files changed, 326 insertions(+), 155 deletions(-) create mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs create mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 14c06fdc38..ef4842beb2 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -4,18 +4,18 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/shader.sdsl"); +var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); var parser = new SDSLParser(); -var sdslParser = new SDSLGrammar().UsingShader(); +parser.Grammar.UsingPrimaryExpression(); var s = new Stopwatch(); var match2 = parser.Parse(shaderf); s.Start(); -var match = parser.Parse(shaderf); +var match = parser.Parse("a[0].b[7].a++"); s.Stop(); -Console.WriteLine(match.ErrorMessage); +Console.WriteLine(match.ErrorMessage[..Math.Min(300, match.ErrorMessage.Length)]); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); diff --git a/src/SDSLParserExample/SDSL/Expressions.sdsl b/src/SDSLParserExample/SDSL/Expressions.sdsl index abed5fdc38..5511d62eea 100644 --- a/src/SDSLParserExample/SDSL/Expressions.sdsl +++ b/src/SDSLParserExample/SDSL/Expressions.sdsl @@ -1 +1 @@ -stream float a[4] : packoffset(a); \ No newline at end of file +float a[5]; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/Methods.sdsl b/src/SDSLParserExample/SDSL/Methods.sdsl index e69de29bb2..f65fb732e1 100644 --- a/src/SDSLParserExample/SDSL/Methods.sdsl +++ b/src/SDSLParserExample/SDSL/Methods.sdsl @@ -0,0 +1,8 @@ + + + + +void foo(in MyStruct> a : SV_POSITION, out float b) +{ + +} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl index 1e5b4a076f..868b1915c9 100644 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -1,4 +1,5 @@ // Some comments + shader BasicMixin : BasicShader, Parent2, Parent3 { float myFloat = 0.2f; stage float3 myPosition : register(b); @@ -13,12 +14,13 @@ shader BasicMixin : BasicShader, Par void PSMain() { + // float a = MyShader.Composition1.Composition2.MyFunction(1,0,true); streams.ColorTarget = float4(0,0,0,1); } - [maxvertexcount(GeometryShaderMaxVertexCount)] - void GSMain(triangle Input input[3], inout TriangleStream triangleStream) - { - Storage.GenerateTriangles(input, triangleStream); - } + // [maxvertexcount(GeometryShaderMaxVertexCount)] + // void GSMain(triangle Input input[3], inout TriangleStream triangleStream) + // { + // Storage.GenerateTriangles(input, triangleStream); + // } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/CommentGrammar.cs b/src/Stride.Shader.Parsing/CommentGrammar.cs index 4439bb6da0..37b297707c 100644 --- a/src/Stride.Shader.Parsing/CommentGrammar.cs +++ b/src/Stride.Shader.Parsing/CommentGrammar.cs @@ -14,11 +14,11 @@ public CommentGrammar() : base("comments-sdsl") var commentStart = Literal("//") | Literal("/*"); - var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("LineComment"); - var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("BlockComment"); - var anyComments = singleLineComment | blockComment; + var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("Comment"); + var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("Comment"); + var anyComments = WhiteSpace | singleLineComment | blockComment; Comments.Add( - anyComments.Repeat(0).SeparatedBy(WhiteSpace.Repeat(0)).Named("Comments") + anyComments.Repeat(0) .Then(AnyChar.Repeat(0).Until(commentStart).Named("ActualCode")) .Repeat(0) ); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs new file mode 100644 index 0000000000..33b1735094 --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -0,0 +1,65 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser ShaderValueDeclaration = new(); + public AlternativeParser ConstantBufferValueDeclaration = new(); + public SDSLGrammar UsingDeclarators() + { + var ws = WhiteSpace.Repeat(0); + Inner = ShaderValueDeclaration & Semi; + // Inner = Identifier.Then(LeftBracket).Then(PrimaryExpression).Then(RightBracket).Then(";"); + return this; + } + public void CreateDeclarators() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + var declare = + Identifier.Then(Identifier).SeparatedBy(ws1).Then(Semi).SeparatedBy(ws); + + var declaratorSupplement = + Colon.Then( + Packoffset.Then(LeftParen).Then(Identifier.Then(Dot.Then(Identifier).Repeat(0))).Then(RightParen).SeparatedBy(ws).Named("PackOffset") + | Register.Then(LeftParen).Then(Identifier.Then(Comma.Then(Identifier).SeparatedBy(ws).Repeat(0).SeparatedBy(ws))).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") + | Identifier.Named("Semantic") + ).SeparatedBy(ws).Optional(); + + var supplement = + ( + Colon & + ( + (Packoffset & LeftParen & Identifier & ((Dot & Identifier).Repeat(0)) & RightParen) + .SeparatedBy(ws).Named("PackOffset") + | (Register & LeftParen & (Identifier & (Comma & Identifier).SeparatedBy(ws)).Repeat(0).SeparateChildrenBy(ws) & RightParen) + .SeparatedBy(ws).Named("Register") + | Identifier.Named("Semantic") + ) + ).SeparatedBy(ws); + + var valueDeclaration = + (~Stage & ~Stream & ValueTypes & Identifier).SeparatedBy(ws1) + & (~(LeftBracket & Literals & RightBracket).SeparatedBy(ws)); + + + + ShaderValueDeclaration.Add( + (valueDeclaration & ~(AssignOperators & PrimaryExpression)) + .SeparatedBy(ws) + ); + ConstantBufferValueDeclaration.Add( + (valueDeclaration & ~(AssignOperators & PrimaryExpression) & ~supplement) + .SeparatedBy(ws) + ); + StructDefinition.Add( + Struct.Then(Identifier).SeparatedBy(ws1) + .Then(LeftBrace) + .Then(declare.Repeat(0).SeparatedBy(ws)) + .Then(RightBrace).Then(Semi).SeparatedBy(ws) + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 6a8c6cb4c8..4da6344b62 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -24,105 +24,110 @@ public partial class SDSLGrammar : Grammar public AlternativeParser IncrementExpression = new(); public AlternativeParser ParenExpression = new(); public AlternativeParser EqualsExpression = new(); + public AlternativeParser MethodCall = new(); public AlternativeParser PrimaryExpression = new(); public SDSLGrammar UsingPrimaryExpression() { - Inner = PrimaryExpression.Then(";"); + Inner = PostFixExpression; return this; } public void CreateExpressions() { - var ls = WhiteSpace.Repeat(0); + var ws = WhiteSpace.Repeat(0); var ls1 = WhiteSpace.Repeat(1); var incrementOp = - Literal("++").Named("PlusPlus") - | Literal("--").Named("MinusMinus"); + PlusPlus + | MinusMinus; - var postfixIncrement = - Identifier.Then(incrementOp.Repeat(0,1)).SeparatedBy(ls); - var prefixIncrement = - incrementOp.Named("IncrementOp").Then(Identifier).SeparatedBy(ls); - - - IncrementExpression.Add( - prefixIncrement.Named("PreIncrement") - | postfixIncrement + TermExpression.Add( + Literals, + Identifier, + ParenExpression.Named("ParenthesisExpr") ); + var arrayAccess = new SequenceParser(); + var chain = new SequenceParser(); + var postfixInc = new SequenceParser(); - TermExpression.Add( - Literals - | Identifier - | ParenExpression.Named("ParenthesisExpr") + + arrayAccess.Add(Identifier, LeftBracket, PrimaryExpression, RightBracket); + chain.Add( + arrayAccess.Named("ArrayAccessor") | Identifier, + (Dot & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) + ); + postfixInc.Add( + chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, + incrementOp.Named("Operator") ); PostFixExpression.Add( - Identifier.Then(incrementOp).SeparatedBy(ls).Named("PostfixIncrement") - | Identifier.NotFollowedBy(ls & LeftBracket).Then(Dot.Then(Identifier).Repeat(0)).Named("AccessorChain") - | ParenExpression.Or(Identifier).Then(LeftBracket).Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ls).Named("ArrayAccessor") - | TermExpression + arrayAccess.SeparateChildrenBy(ws).Named("ArrayAccessor").NotFollowedBy(Dot | (ws & incrementOp)), + chain.Named("ChainAccessor").NotFollowedBy(ws & incrementOp), + postfixInc.Named("PostFixIncrement"), + TermExpression ); UnaryExpression.Add( - Literal("sizeof").Then(LeftParen).Then(Identifier).Then(RightParen).Named("SizeOf") - | Literal("sizeof").Then(LeftParen).Then(UnaryExpression).Then(RightParen).Named("SizeOf") - | prefixIncrement.Named("PrefixIncrement") - | PostFixExpression + (incrementOp & ws & Identifier).Named("PrefixIncrement"), + Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf"), + // Literal("sizeof").Then(LeftParen).Then(UnaryExpression).Then(RightParen).Named("SizeOf"), + PostFixExpression ); CastExpression.Add( - LeftParen.Then(Identifier).Then(RightParen).Then(UnaryExpression).SeparatedBy(ls).Named("CastExpression") + LeftParen.Then(Identifier).Then(RightParen).Then(UnaryExpression).SeparatedBy(ws).Named("CastExpression") | UnaryExpression ); - var multiply = CastExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); + var multiply = CastExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ws); MulExpression.Add( multiply.Named("Multiplication") - | CastExpression + | TermExpression ); var parenMulExpr = - LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ls); + LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ws); var sumOp = (Plus - PlusPlus) | (Minus - MinusMinus); - var add = (parenMulExpr | MulExpression).Then(sumOp).Then(SumExpression).SeparatedBy(ls); + var add = (parenMulExpr | MulExpression).Then(sumOp).Then(SumExpression).SeparatedBy(ws); SumExpression.Add( add.Named("Addition") | MulExpression ); var parenSumExpr = - LeftParen.Then(SumExpression).Then(RightParen).SeparatedBy(ls); + LeftParen.Then(SumExpression).Then(RightParen).SeparatedBy(ws); var shiftOp = LeftShift | RightShift; var shift = - (parenSumExpr | SumExpression).Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ls); + (parenSumExpr | SumExpression).Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ws); ShiftExpression.Add( - shift.Named("ShiftExpression") - | SumExpression + TermExpression.NotFollowedBy(ws & shiftOp) + | shift.Named("ShiftExpression") + // TermExpression.Then(RightShift).Then(TermExpression).SeparatedBy(ws) ); var parenShift = - LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ls); + LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ws); var testOp = Less | LessEqual | Greater | GreaterEqual; - var test = (parenShift | ShiftExpression).Then(testOp).Then(TestExpression).SeparatedBy(ls); + var test = (parenShift | ShiftExpression).Then(testOp).Then(TestExpression).SeparatedBy(ws); TestExpression.Add( test.Named("TestExpression") | ShiftExpression ); - var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ls); + var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ws); var eqOp = Literal("==").Named("Equals") @@ -134,7 +139,7 @@ public void CreateExpressions() .Then( BooleanTerm | EqualsExpression ) - .SeparatedBy(ls).Named("Equals"); + .SeparatedBy(ws).Named("Equals"); EqualsExpression.Add( @@ -143,52 +148,54 @@ public void CreateExpressions() ); AndExpression.Add( - EqualsExpression.Then("&").Then(AndExpression).SeparatedBy(ls).Named("BitwiseAnd") + EqualsExpression.Then("&").Then(AndExpression).SeparatedBy(ws).Named("BitwiseAnd") | EqualsExpression ); XorExpression.Add( - AndExpression.Then("^").Then(XorExpression).SeparatedBy(ls).Named("BitwiseXor") + AndExpression.Then("^").Then(XorExpression).SeparatedBy(ws).Named("BitwiseXor") | AndExpression ); OrExpression.Add( - XorExpression.Then("|").Then(OrExpression).SeparatedBy(ls).Named("BitwiseOr") + XorExpression.Then("|").Then(OrExpression).SeparatedBy(ws).Named("BitwiseOr") | XorExpression ); LogicalAndExpression.Add( - OrExpression.Then("&&").Then(LogicalAndExpression).SeparatedBy(ls).Named("LogicalAnd") + OrExpression.Then("&&").Then(LogicalAndExpression).SeparatedBy(ws).Named("LogicalAnd") | OrExpression ); LogicalOrExpression.Add( - LogicalAndExpression.Then("||").Then(LogicalOrExpression).SeparatedBy(ls).Named("LogicalOr") + LogicalAndExpression.Then("||").Then(LogicalOrExpression).SeparatedBy(ws).Named("LogicalOr") | LogicalAndExpression ); ConditionalExpression.Add( - LogicalOrExpression.NotFollowedBy(ls & "?") + LogicalOrExpression.NotFollowedBy(ws & "?") | LogicalOrExpression .Then("?") .Then(CastExpression | ParenExpression | LogicalOrExpression) .Then(":") .Then(CastExpression | ParenExpression | LogicalOrExpression) - .SeparatedBy(ls) + .SeparatedBy(ws) .Named("Ternary") ); ParenExpression.Add( - LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) + LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ws) ); - var parameters = EqualsExpression.Then(Comma.Then(PrimaryExpression).SeparatedBy(ls).Repeat(0)).SeparatedBy(ls); - var methodCall = Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ls).Named("MethodCallExpression"); + var parameters = EqualsExpression.Then(Comma.Then(PrimaryExpression).SeparatedBy(ws).Repeat(0)).SeparatedBy(ws); + MethodCall.Add( + Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") + ); PrimaryExpression.Add( - methodCall + MethodCall | ConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs index 0784c5b8ce..92e1b414df 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs @@ -68,9 +68,9 @@ public void CreateLiterals() BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; Literals.Add( - HexaDecimalLiteral - | IntegerLiteral.NotFollowedBy(Dot | FloatSuffix).Then(IntegerSuffix.Optional()).Named("IntegerLiteral") - | FloatLiteral.Then(FloatSuffix.Optional()).Named("FloatLiteral") + IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Then(IntegerSuffix.Optional()).Named("IntegerLiteral") + | FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral") + | HexaDecimalLiteral | StringLiteral ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs new file mode 100644 index 0000000000..88fc5e688d --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -0,0 +1,61 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser ParameterList = new(); + public AlternativeParser ValueOrGeneric = new(); + + public AlternativeParser MethodDeclaration = new(); + + + public SDSLGrammar UsingMethodDeclare() + { + Inner = MethodDeclaration; + return this; + } + public void CreateMethodDeclaration() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + + ValueOrGeneric.Add( + ValueTypes + | Identifier.Then("<").Then(ValueOrGeneric.Then(Comma.Optional()).Repeat(1).SeparateChildrenBy(ws)).Then(">").SeparatedBy(ws) + | Identifier + ); + + var declarePost = + LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ws) + | Colon.Then(Identifier).SeparatedBy(ws); + + var parameter = + StorageFlag.Optional() + .Then(ValueOrGeneric) + .Then(Identifier.Then()) + .SeparatedBy(ws1) + .Then(declarePost.Optional()) + .SeparatedBy(ws); + + + ParameterList.Add( + LeftParen + .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) + .Then(RightParen).SeparatedBy(ws) + ); + + MethodDeclaration.Add( + Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) + .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") + | Literal("override").Optional().Then(Literal("stage").Optional()) + .Then(Identifier).Then(Identifier).SeparatedBy(ws1) + .Then(ParameterList) + .Then(LeftBrace) + .Then(Statement.Repeat(0)) + .Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 9afee932f5..2e75645494 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -19,36 +19,38 @@ public void CreateShader() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - var genericValue = + var shaderGenericValue = Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType") | ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue") | ValueTypes; - var generics = + var shaderGenerics = Literal("<") - .Then(genericValue) + .Then(shaderGenericValue) .Then( - Comma.Then(genericValue).SeparatedBy(ws).Repeat(0) + Comma.Then(shaderGenericValue).SeparatedBy(ws).Repeat(0) ) .Then(">").SeparatedBy(ws); var shaderContentTypes = - GenericDeclaration - | Entries - | MethodDeclaration; + MethodDeclaration + | ShaderValueDeclaration + // | Attribute + ; var shaderBody = LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); - var inheritances = Colon.Then(Identifier.Then(generics.Optional()).Then(Comma.Then(Identifier.Then(generics.Optional())).SeparatedBy(ws).Repeat(0))).SeparatedBy(ws).Optional(); + var inheritances = Colon.Then(Identifier.Then(shaderGenerics.Optional()).Then(Comma.Then(Identifier.Then(shaderGenerics.Optional())).SeparatedBy(ws).Repeat(0))).SeparatedBy(ws).Optional(); Shader.Add( + ws & Literal("shader") - .Then(Identifier.Then(generics.Optional())).SeparatedBy(ws1).Then(inheritances.Named("Inherit")) - .Then(shaderBody).Named("ShaderProgram") - .Then(";").SeparatedBy(ws) - .Then(ws) + .Then(Identifier.Then(shaderGenerics.Optional())).SeparatedBy(ws1) + .Then(shaderBody.Or(inheritances.Named("Inherit").Then(shaderBody).SeparatedBy(ws))) + .Then(";").SeparatedBy(ws).Named("ShaderProgram") + & ws ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index 77db0ff09f..bf87a54ffd 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -6,15 +6,13 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser StructDefinition = new(); - public AlternativeParser ParameterList = new(); public AlternativeParser Attribute = new(); public AlternativeParser Statement = new(); public AlternativeParser ControlFlow = new(); - public AlternativeParser MethodDeclaration = new(); public AlternativeParser ConstantBuffer = new(); - public AlternativeParser GenericDeclaration = new(); + public AlternativeParser ShaderMethodCall = new(); public AlternativeParser Block = new(); - + public SDSLGrammar UsingStatements() { @@ -24,11 +22,37 @@ public SDSLGrammar UsingStatements() public void CreateStatements() { var ws = WhiteSpace.Repeat(0); - var ws1 = WhiteSpace.Repeat(1); + var ws1 = WhiteSpace.Repeat(1); + + ShaderMethodCall.Add( + ( + Identifier + .Then( + ( + Dot.NotFollowedBy(MethodCall).Then(Identifier) + | Dot.Then(MethodCall) + ) + .Repeat(0) + ) + .Then(";") + ) + .SeparatedBy(ws) + ); + + var returnStatement = + Return.Then(PrimaryExpression).SeparatedBy(ws1) + .Then(Semi).SeparatedBy(ws); + + Attribute.Add( + LeftBracket + .Then(Identifier) + .Then(LeftParen) + .Then((Identifier | Literals).Then(Comma.Optional()).Repeat(0).SeparateChildrenBy(ws)) + .Then(RightParen) + .Then(RightBracket) + .SeparatedBy(ws) + ); - var declare = - Identifier.Then(Identifier).SeparatedBy(ws1).Then(Semi).SeparatedBy(ws); - var assignVar = Identifier.Named("Variable").NotFollowedBy(Identifier) .Then(AssignOperators.Named("AssignOp")) @@ -36,63 +60,26 @@ public void CreateStatements() .Then(Semi) .SeparatedBy(ws); - var assignChain = + var assignChain = Identifier.Then(Dot.Then(Identifier).Repeat(0)) .Then(AssignOperators) .Then(PrimaryExpression) .Then(Semi) .SeparatedBy(ws); - + var declareAssign = Identifier.Named("Type") .Then(assignVar) .SeparatedBy(ws1); - var declaratorSupplement = - Colon.Then( - Packoffset.Then(LeftParen).Then(Identifier.Then(Dot.Then(Identifier).Repeat(0))).Then(RightParen).SeparatedBy(ws).Named("PackOffset") - | Register.Then(LeftParen).Then(Identifier.Then(Comma.Then(Identifier).SeparatedBy(ws).Repeat(0).SeparatedBy(ws))).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") - | Identifier.Named("Semantic") - ).SeparatedBy(ws).Optional(); - var arrayRank = - LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ws).Named("ArrayRankSpecifier").Optional(); - - - GenericDeclaration.Add( - Literal("stage").Named("Stage").Optional().Then(Literal("stream").Named("Stream").Optional()) - .Then((ValueTypes | Identifier).Named("Type")) - .Then(Identifier.Named("Name").Then(arrayRank)).SeparatedBy(ws1) - .Then((AssignOperators & PrimaryExpression).SeparatedBy(ws).Optional()) - .Then(declaratorSupplement.Optional()) - .Then(";").SeparatedBy(ws) - ); - - var returnStatement = - Return.Then(PrimaryExpression).SeparatedBy(ws1) - .Then(Semi).SeparatedBy(ws); - - Attribute.Add( - LeftBracket - .Then(Identifier) - .Then(LeftParen) - .Then(Literals.Then(Comma.Then(Literals).Repeat(0).SeparatedBy(ws))) - .Then(RightParen) - .Then(RightBracket) - .SeparatedBy(ws) - ); - - StructDefinition.Add( - Struct.Then(Identifier).SeparatedBy(ws1) - .Then(LeftBrace) - .Then(declare.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace).Then(Semi).SeparatedBy(ws) - ); + Statement.Add( Block.Named("BlockExpression") | returnStatement.Named("Return") | assignChain + | ShaderMethodCall | declareAssign.Named("DeclareAssign") | assignVar.Named("Assign") | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") @@ -101,17 +88,17 @@ public void CreateStatements() Block.Add( LeftBrace.Then(Statement.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws) ); - var flowStatement = Statement; - - var ifStatement = + var flowStatement = Statement; + + var ifStatement = If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(flowStatement).SeparatedBy(ws); - - var elseIfStatement = + + var elseIfStatement = Else.Then(ifStatement).SeparatedBy(ws1); - - var elseStatement = + + var elseStatement = Else.Then(flowStatement).SeparatedBy(ws1); - + ControlFlow.Add( Attribute.Repeat(0).Named("Attributes").Then( ifStatement.Named("IfStatement") @@ -120,24 +107,10 @@ public void CreateStatements() ).SeparatedBy(ws) ); - var parameter = Identifier.Then(Identifier).SeparatedBy(ws1); - ParameterList.Add( - LeftParen - .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) - .Then(RightParen).SeparatedBy(ws) - ); + - MethodDeclaration.Add( - Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") - | Literal("override").Optional().Then(Literal("stage").Optional()) - .Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0)) - .Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") - ); + ConstantBuffer.Add( Literal("cbuffer").Then(Identifier).SeparatedBy(ws1) .Then(LeftBrace) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 1e954751ea..31ca461bae 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -23,6 +23,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser UintTypes = new(); public AlternativeParser ValueTypes = new(); + public AlternativeParser StorageFlag = new(); public AlternativeParser Keywords = new(); @@ -141,6 +142,8 @@ public void CreateTokenGroups() | SamplerComparisonState | SamplerState | Shared + | Stage + | Stream | Static | Struct | StructuredBuffer @@ -155,6 +158,32 @@ public void CreateTokenGroups() | Volatile | Void | While; + + StorageFlag.Add( + Literal("constant") + | RowMajor + | ColumnMajor + | Extern + | Precise + | Shared + | Groupshared + | Static + | Uniform + | Volatile + | Linear + | Centroid + | Nointerpolation + | Noperspective + | Sample + | In + | Out + | Inout + | Point + | Line_ + | Triangle + | LineAdj + | TriangleAdj + ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs index 4d1eb5dcd7..e23d41481f 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -144,6 +144,10 @@ public partial class SDSLGrammar : Grammar private LiteralTerminal False = new(); private AlternativeParser PreprocessorDirectiveName = new(); + private LiteralTerminal Stream = new(); + private LiteralTerminal Stage = new(); + + public void CreateTokens() { WS = WhiteSpace; @@ -299,5 +303,8 @@ public void CreateTokens() | Literal("pragma") | Literal("undef"); + Stage = Literal("stage"); + Stream = Literal("stream"); + } } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index f9a71f8854..18b9272005 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -13,6 +13,12 @@ public SDSLGrammar() : base("sdsl") Inner = Shader; } + public SDSLGrammar Using(EtoParser p) + { + Inner = p; + return this; + } + public void CreateAll() { CreateTokens(); @@ -21,6 +27,8 @@ public void CreateAll() CreateDirectives(); CreateDirectiveExpressions(); CreateExpressions(); + CreateMethodDeclaration(); + CreateDeclarators(); CreateStatements(); CreateEntryPoints(); CreateShader(); diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index 113525b7f4..e1c4c27b3a 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -6,17 +6,27 @@ namespace Stride.Shader.Parsing; public class SDSLParser { public CommentGrammar Comments {get;set;} - public SDSLGrammar SdslGrammar {get;set;} + public SDSLGrammar Grammar {get;set;} public SDSLParser() { Comments = new(); - SdslGrammar = new(); + Grammar = new(); + } + + public SDSLParser With(Parser p) + { + Grammar.Inner = p; + return this; } public GrammarMatch Parse(string shader) { var comments = Comments.Match(shader); + if(!comments.Matches.Any(x => x.Name == "Comment")) + { + return Grammar.Match(shader); + } var actualCode = new StringBuilder(); foreach(var m in comments.Matches) { @@ -25,8 +35,7 @@ public GrammarMatch Parse(string shader) actualCode.Append(m.StringValue); } } - var match = SdslGrammar.Match(actualCode.ToString()); - return match; + return Grammar.Match(actualCode.ToString()); } } \ No newline at end of file From a1785793d430d4a2a61dec4cf62fd33db5829586 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 10 May 2022 10:57:12 +0200 Subject: [PATCH 0052/1182] Refactor expressions and literals till shift expressions --- src/SDSLParserExample/Program.cs | 6 +- .../BasicExpressionParsing.cs | 97 ++++++ .../BasicParsing.cs | 81 ----- .../OperationExpressionParsing.cs | 127 +++++++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 141 +++++--- .../SDSLGrammar/SDSLGrammar.Literals.cs | 37 +-- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 313 +++++++++--------- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 64 ++-- src/Stride.Shader.Parsing/SDSLParser.cs | 7 +- 9 files changed, 540 insertions(+), 333 deletions(-) create mode 100644 src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs delete mode 100644 src/Stride.Shader.Parsing.Test/BasicParsing.cs create mode 100644 src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index ef4842beb2..77c28c7e85 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -4,14 +4,14 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("./SDSL/Expressions.sdsl"); +var shaderf = File.ReadAllText("../../../SDSL/Expressions.sdsl"); var parser = new SDSLParser(); -parser.Grammar.UsingPrimaryExpression(); +parser.Grammar.Using(parser.Grammar.ShiftExpression.Then(";")); var s = new Stopwatch(); var match2 = parser.Parse(shaderf); s.Start(); -var match = parser.Parse("a[0].b[7].a++"); +var match = parser.Parse("(MyStruct)++my_var.a[0].c+6+4*5 >>2;"); s.Stop(); diff --git a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs new file mode 100644 index 0000000000..2c8dcaa5be --- /dev/null +++ b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs @@ -0,0 +1,97 @@ +using Xunit; +using System.Linq; +using Stride.Shader.Parsing; +using Eto.Parse; +using Eto.Parse.Parsers; +using System.Collections.Generic; + +namespace Stride.Shader.Parsing.Test; + +public class BasicExpressionParsing +{ + SDSLParser parser; + public BasicExpressionParsing() + { + parser = new(); + } + [Fact] + public void TestTerms() + { + parser.Grammar.Using(parser.Grammar.TermExpression); + List matches = new(){ + parser.Parse("5"), + parser.Parse("5l"), + parser.Parse("5u"), + parser.Parse("5f"), + parser.Parse(".5"), + parser.Parse("5f"), + parser.Parse(".5d"), + parser.Parse("my_var"), + parser.Parse("\"Hello World\"") + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + [Fact] + public void TestPostfix() + { + parser.Grammar.Using(parser.Grammar.PostFixExpression.Then(";")); + List matches = new(){ + parser.Parse("my_var++;"), + parser.Parse("my_var.a;"), + parser.Parse("my_var[0];"), + parser.Parse("my_var[a];"), + parser.Parse("my_var.a[0];"), + parser.Parse("my_var.a[b];"), + parser.Parse("my_var.a[b]++;"), + parser.Parse("my_var.a[0].c;"), + parser.Parse("my_var.a[b].c;"), + parser.Parse("my_var.a[b].c++;"), + parser.Parse("my_var.a[b].c[5].b.e[7][5]++;"), + + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + + [Fact] + public void TestUnary() + { + parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); + List matches = new() + { + parser.Parse("++my_var;"), + parser.Parse("++my_var.a;"), + parser.Parse("++my_var[0];"), + parser.Parse("++my_var[a];"), + parser.Parse("++my_var.a[0];"), + parser.Parse("++my_var.a[b];"), + parser.Parse("++my_var.a[0].c;"), + parser.Parse("++my_var.a[b].c;"), + parser.Parse("++my_var.a[b].c[5].b.e[7][5];"), + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } + + [Fact] + public void TestCast() + { + parser.Grammar.Using(parser.Grammar.CastExpression.Then(";")); + List matches = new() + { + parser.Parse("(float)++my_var;"), + parser.Parse("(float)++my_var.a;"), + parser.Parse("(float4)my_var[0]++;"), + parser.Parse("(float4x4)++my_var[a];"), + parser.Parse("(MyStruct)++my_var.a[0];"), + parser.Parse("(MyStruct)my_var.a[b]++;"), + parser.Parse("(MyStruct)++my_var.a[0].c;"), + parser.Parse("(MyStruct)my_var.a[b].c++;"), + parser.Parse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } + + + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing.Test/BasicParsing.cs b/src/Stride.Shader.Parsing.Test/BasicParsing.cs deleted file mode 100644 index 2667279823..0000000000 --- a/src/Stride.Shader.Parsing.Test/BasicParsing.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Xunit; -using System.Linq; -using Stride.Shader.Parsing; -using Eto.Parse; -using Eto.Parse.Parsers; -using System.Collections.Generic; - -namespace Stride.Shader.Parsing.Test; - -public class BasicParsing -{ - SDSLGrammar Grammar; - public BasicParsing() - { - Grammar = new(); - } - [Fact] - public void TestIdentifier() - { - var matches = new List<(string Name,GrammarMatch Matching)>{ - ("myVar",Grammar.Match("myVar")), - ("my_Var",Grammar.Match("my_Var")), - ("my_Var2",Grammar.Match("my_Var2")), - ("my2Var",Grammar.Match("my2Var")), - ("myVar",Grammar.Match("myVar")) - }; - - foreach(var (Name, Matching) in matches) - { - Assert.True(Matching.HasMatches); - // Assert.True(Matching.Matches.Exists(x => x.Name == "Identifier")); - Assert.True(Matching.Matches[0].StringValue == Name); - } - - } - [Fact] - public void TestConstant() - { - var values = new string[]{ - "5", - "50", - "51.5", - "0", - "-1" - }; - var matches = - values.Select(x => (x,Grammar.Match(x))); - - foreach(var (Original, Matching) in matches) - { - Assert.True(Matching.HasMatches); - Assert.True(Matching.Matches[0].StringValue == Original); - } - } - [Fact] - public void TestAdd() - { - - } - [Fact] - public void TestMult() - { - - } - [Fact] - public void TestAssign() - { - - } - [Fact] - public void TestParenthesis() - { - - } - [Fact] - public void TestOperations() - { - - } - -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs new file mode 100644 index 0000000000..6ade9a8093 --- /dev/null +++ b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs @@ -0,0 +1,127 @@ +using Xunit; +using System.Linq; +using Stride.Shader.Parsing; +using Eto.Parse; +using Eto.Parse.Parsers; +using System.Collections.Generic; + +namespace Stride.Shader.Parsing.Test; + +public class OperationExpressionParsing +{ + SDSLParser parser; + public OperationExpressionParsing() + { + parser = new(); + } + [Fact] + public void TestMul() + { + parser.Grammar.Using(parser.Grammar.MulExpression.Then(";")); + List matches = new() + { + parser.Parse("5*3;"), + parser.Parse("5*3*4;"), + parser.Parse("5 * (float)++my_var;"), + parser.Parse("5* (float)++my_var.a;"), + parser.Parse("(float4)my_var[0]++ * 2;"), + parser.Parse("(float4x4)++my_var[a]* 2;"), + parser.Parse("(MyStruct)++my_var.a[0] * 2;"), + parser.Parse("2 * 3 * (MyStruct)my_var.a[b]++;"), + parser.Parse("(MyStruct)++my_var.a[0].c *4* 5;"), + parser.Parse("(float)my_value * (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.Parse("(float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + }; + + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + [Fact] + public void TestSum() + { + parser.Grammar.Using(parser.Grammar.SumExpression.Then(";")); + List matches = new() + { + parser.Parse("5+3;"), + parser.Parse("a + b++ * 3 + 4;"), + parser.Parse("5+3+4;"), + parser.Parse("3 + 5 * (float)++my_var;"), + parser.Parse("3 + 5* (float)++my_var.a;"), + parser.Parse("a + (float4)my_var[0]++ * 2 + 4;"), + parser.Parse("my_otherVar + (float4x4)++my_var[a]* 2 - 2;"), + parser.Parse("(float)1 + (MyStruct)++my_var.a[0] * 2;"), + parser.Parse("2 * 3 + (MyStruct)my_var.a[b]++;"), + parser.Parse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5;"), + parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.Parse("2 + (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] + ++b;"), + }; + + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + + [Fact] + public void TestShift() + { + parser.Grammar.Using(parser.Grammar.ShiftExpression.Then(";")); + List matches = new() + { + parser.Parse("5 << 5+3;"), + parser.Parse("a + b++ * 3 << 4;"), + parser.Parse("5 << 3 >> 4;"), + parser.Parse("3 + 5 * (float)++my_var;"), + parser.Parse("3 + 5* (float)++my_var.a;"), + parser.Parse("a >> (float4)my_var[0]++ * 2 + 4;"), + parser.Parse("my_otherVar << (float4x4)++my_var[a]* 2 - 2;"), + parser.Parse("(float)1 + (MyStruct)++my_var.a[0] << 2;"), + parser.Parse("2 * 3 + (MyStruct)my_var.a[b]++;"), + parser.Parse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5 >> 2;"), + parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.Parse("2 + (float)my_value << (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), + }; + + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + + [Fact] + public void TestUnary() + { + parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); + List matches = new() + { + parser.Parse("++my_var;"), + parser.Parse("++my_var.a;"), + parser.Parse("++my_var[0];"), + parser.Parse("++my_var[a];"), + parser.Parse("++my_var.a[0];"), + parser.Parse("++my_var.a[b];"), + parser.Parse("++my_var.a[0].c;"), + parser.Parse("++my_var.a[b].c;"), + parser.Parse("++my_var.a[b].c[5].b.e[7][5];"), + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } + + [Fact] + public void TestCast() + { + parser.Grammar.Using(parser.Grammar.CastExpression.Then(";")); + List matches = new() + { + parser.Parse("(float)++my_var;"), + parser.Parse("(float)++my_var.a;"), + parser.Parse("(float4)my_var[0]++;"), + parser.Parse("(float4x4)++my_var[a];"), + parser.Parse("(MyStruct)++my_var.a[0];"), + parser.Parse("(MyStruct)my_var.a[b]++;"), + parser.Parse("(MyStruct)++my_var.a[0].c;"), + parser.Parse("(MyStruct)my_var.a[b].c++;"), + parser.Parse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } + + + +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 4da6344b62..6da9bbb936 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -29,7 +29,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar UsingPrimaryExpression() { - Inner = PostFixExpression; + Inner = SumExpression.Then(";"); return this; } @@ -39,15 +39,17 @@ public void CreateExpressions() var ls1 = WhiteSpace.Repeat(1); - var incrementOp = - PlusPlus - | MinusMinus; + var incrementOp = new AlternativeParser(); + incrementOp.Add( + PlusPlus, + MinusMinus + ); TermExpression.Add( Literals, - Identifier, - ParenExpression.Named("ParenthesisExpr") + Identifier.Except(Keywords | ValueTypes) + // ,ParenExpression ); var arrayAccess = new SequenceParser(); @@ -55,64 +57,108 @@ public void CreateExpressions() var postfixInc = new SequenceParser(); - arrayAccess.Add(Identifier, LeftBracket, PrimaryExpression, RightBracket); + arrayAccess.Add( + Identifier, + ws, + (LeftBracket & ws & PrimaryExpression & ws & RightBracket).Repeat(1).SeparatedBy(ws) + ); chain.Add( arrayAccess.Named("ArrayAccessor") | Identifier, - (Dot & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) + ws, + (Dot & ws & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) ); postfixInc.Add( chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, + ws, incrementOp.Named("Operator") ); PostFixExpression.Add( - arrayAccess.SeparateChildrenBy(ws).Named("ArrayAccessor").NotFollowedBy(Dot | (ws & incrementOp)), - chain.Named("ChainAccessor").NotFollowedBy(ws & incrementOp), - postfixInc.Named("PostFixIncrement"), - TermExpression + TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), + postfixInc.Named("PostfixIncrement"), + chain.Named("AccessorChain"), + arrayAccess.Named("ArrayAccesor") + ); + + var prefixInc = new SequenceParser(); + prefixInc.Add( + incrementOp, + ws, + TermExpression.NotFollowedBy(ws & (Dot | "[")) + | chain + | arrayAccess ); UnaryExpression.Add( - (incrementOp & ws & Identifier).Named("PrefixIncrement"), - Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf"), - // Literal("sizeof").Then(LeftParen).Then(UnaryExpression).Then(RightParen).Named("SizeOf"), - PostFixExpression + PostFixExpression, + prefixInc.Named("PrefixIncrement"), + Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") + ); + + var cast = new SequenceParser(); + cast.Add( + LeftParen, + ValueTypes | Identifier, + RightParen, + UnaryExpression ); CastExpression.Add( - LeftParen.Then(Identifier).Then(RightParen).Then(UnaryExpression).SeparatedBy(ws).Named("CastExpression") - | UnaryExpression + UnaryExpression, + cast.SeparatedBy(ws).Named("CastExpression") ); - - var multiply = CastExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ws); + var mulOp = Star | Div | Mod; + var multiply = new SequenceParser(); + multiply.Add( + CastExpression, + mulOp.Named("Operator"), + MulExpression + ); + MulExpression.Add( - multiply.Named("Multiplication") - | TermExpression + CastExpression.NotFollowedBy(ws & mulOp), + multiply.SeparatedBy(ws).Named("Multiplication") ); var parenMulExpr = LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ws); - var sumOp = (Plus - PlusPlus) | (Minus - MinusMinus); - var add = (parenMulExpr | MulExpression).Then(sumOp).Then(SumExpression).SeparatedBy(ws); - SumExpression.Add( + var sumOp = new AlternativeParser(); + sumOp.Add(Plus, Minus); + + var add = new SequenceParser(); + add.Add( + parenMulExpr.NotFollowedBy(UnaryExpression) | MulExpression, + ws, + sumOp.Except(incrementOp), + ws, + SumExpression + ); + + + SumExpression.Add( + MulExpression.NotFollowedBy(ws & sumOp.Except(incrementOp)), add.Named("Addition") - | MulExpression ); var parenSumExpr = LeftParen.Then(SumExpression).Then(RightParen).SeparatedBy(ws); - var shiftOp = LeftShift | RightShift; - var shift = - (parenSumExpr | SumExpression).Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ws); + var shiftOp = (LeftShift | RightShift); + var shift = new SequenceParser(); + shift.Add( + parenSumExpr.NotFollowedBy(UnaryExpression) | SumExpression, + ws, + shiftOp.Named("Operator"), + ws, + ShiftExpression + ); ShiftExpression.Add( - TermExpression.NotFollowedBy(ws & shiftOp) - | shift.Named("ShiftExpression") - // TermExpression.Then(RightShift).Then(TermExpression).SeparatedBy(ws) + SumExpression.NotFollowedBy(ws & shiftOp), + shift.Named("ShiftExpression") ); var parenShift = LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ws); @@ -120,11 +166,16 @@ public void CreateExpressions() var testOp = Less | LessEqual | Greater | GreaterEqual; - var test = (parenShift | ShiftExpression).Then(testOp).Then(TestExpression).SeparatedBy(ws); + var test = new SequenceParser(); + test.Add( + parenShift | ShiftExpression, + testOp.Named("Operator"), + TestExpression + ); TestExpression.Add( - test.Named("TestExpression") - | ShiftExpression + test.Named("TestExpression"), + ShiftExpression ); var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ws); @@ -133,18 +184,18 @@ public void CreateExpressions() Literal("==").Named("Equals") | Literal("!=").Named("NotEquals"); - var equals = - (BooleanTerm | parenTestExpr | TestExpression) - .Then(eqOp) - .Then( - BooleanTerm | EqualsExpression - ) - .SeparatedBy(ws).Named("Equals"); - + var equals = new SequenceParser(); + equals.Add( + BooleanTerm | TestExpression, + ws, + eqOp.Named("Operator"), + ws, + BooleanTerm | EqualsExpression + ); EqualsExpression.Add( - equals - | TestExpression + equals.Named("EqualExpression"), + TestExpression ); AndExpression.Add( diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs index 92e1b414df..5f117f75c7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs @@ -38,17 +38,19 @@ public void CreateLiterals() Identifier.Except(Keywords) ); - IntegerSuffix = - Literal("u") - | Literal("l") - | Literal("U") - | Literal("L"); + IntegerSuffix.Add( + "u", + "l", + "U", + "L" + ); - FloatSuffix = - Literal("f") - | Literal("d") - | Literal("F") - | Literal("D"); + FloatSuffix.Add( + "f", + "d", + "F", + "D" + ); @@ -57,21 +59,14 @@ public void CreateLiterals() FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); HexDigits = new(); HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); - - var ints = - HexaDecimalLiteral - | IntegerLiteral.Then(IntegerSuffix.Optional().Named("suffix")).Named("IntegerLiteral"); - var floats = - FloatLiteral.Then(FloatSuffix.Optional().Named("suffix")).Named("FloatLiteral"); - // | IntegerLiteral.Then(IntegerSuffix); BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; Literals.Add( - IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Then(IntegerSuffix.Optional()).Named("IntegerLiteral") - | FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral") - | HexaDecimalLiteral - | StringLiteral + IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Named("IntegerLiteral"), + FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral"), + HexaDecimalLiteral, + StringLiteral ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 31ca461bae..39ea0b0e21 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -29,160 +29,171 @@ public partial class SDSLGrammar : Grammar public void CreateTokenGroups() { - IncOperators = - PlusPlus - | MinusMinus; - - Operators = - Plus - | Minus - | Star - | Div - | Mod - | LeftShift - | RightShift; + IncOperators.Add( + PlusPlus, + MinusMinus + ); + + Operators.Add( + Plus, + Minus, + Star, + Div, + Mod, + LeftShift, + RightShift + ); - AssignOperators = - Assign - | StarAssign - | DivAssign - | ModAssign - | PlusAssign - | MinusAssign - | LeftShiftAssign - | RightShiftAssign - | AndAssign - | XorAssign - | OrAssign; - - BoolTypes = - Bool.NotFollowedBy(Set("1234")) - | BoolVec.NotFollowedBy("x") - | BoolMat; - - HalfTypes = - Half.NotFollowedBy(Set("1234")) - | HalfVec.NotFollowedBy("x") - | HalfMat; - - FloatTypes = - Float.NotFollowedBy(Set("1234")) - | FloatVec.NotFollowedBy("x") - | FloatMat; - - DoubleTypes = - Double.NotFollowedBy(Set("1234")) - | DoubleVec.NotFollowedBy("x") - | DoubleMat; - - IntTypes = - Int.NotFollowedBy(Set("1234")) - | IntVec.NotFollowedBy("x") - | IntMat; - - UintTypes = - Uint.NotFollowedBy(Set("1234")) - | UintVec.NotFollowedBy("x") - | UintMat; - - ValueTypes = - BoolTypes - | HalfTypes - | FloatTypes - | DoubleTypes - | IntTypes - | UintTypes; - - Keywords = - AppendStructuredBuffer - | Buffer - ByteAddressBuffer - | ByteAddressBuffer - Break - | Break - | Case - CBuffer - | CBuffer - Centroid - | Centroid - Class - | Class - ColumnMajor - | ColumnMajor - Const - | Const - ConsumeStructuredBuffer - | ConsumeStructuredBuffer - Continue - | Continue - | Default - Discard - | Discard - | Do - | Else - | Extern - | For - | Groupshared - | If - | In - | Inout - | InputPatch - | Interface - | Line_ - | LineAdj - | Linear - | LineStream - | Matrix - | Nointerpolation - | Noperspective - | Out - | OutputPatch - | Packoffset - | Point - | PointStream - | Precise - | Register - | Return - | RowMajor - | RWBuffer - | RWByteAddressBuffer - | RWStructuredBuffer - | Sample - Sampler - | Sampler - | SamplerComparisonState - | SamplerState - | Shared - | Stage - | Stream - | Static - | Struct - | StructuredBuffer - | Switch - | TextureTypes - | Triangle - | TriangleAdj - | TriangleStream - | Uniform - | ValueTypes - | Vector - | Volatile - | Void - | While; + AssignOperators.Add( + Assign, + StarAssign, + DivAssign, + ModAssign, + PlusAssign, + MinusAssign, + LeftShiftAssign, + RightShiftAssign, + AndAssign, + XorAssign, + OrAssign + ); + + BoolTypes.Add( + Bool.NotFollowedBy(Set("1234")), + BoolVec.NotFollowedBy("x"), + BoolMat + ); + + HalfTypes.Add( + Half.NotFollowedBy(Set("1234")), + HalfVec.NotFollowedBy("x"), + HalfMat + ); + + FloatTypes.Add( + Float.NotFollowedBy(Set("1234")), + FloatVec.NotFollowedBy("x"), + FloatMat + ); + + DoubleTypes.Add( + Double.NotFollowedBy(Set("1234")), + DoubleVec.NotFollowedBy("x"), + DoubleMat + ); + + IntTypes.Add( + Int.NotFollowedBy(Set("1234")), + IntVec.NotFollowedBy("x"), + IntMat + ); + + UintTypes.Add( + Uint.NotFollowedBy(Set("1234")), + UintVec.NotFollowedBy("x"), + UintMat + ); + + ValueTypes.Add( + BoolTypes, + HalfTypes, + FloatTypes, + DoubleTypes, + IntTypes, + UintTypes + ); + + Keywords.Add( + AppendStructuredBuffer, + Buffer, + ByteAddressBuffer, + Break, + Case, + CBuffer, + Centroid, + Class, + ColumnMajor, + Const, + ConsumeStructuredBuffer, + Continue, + Default, + Discard, + Do, + Else, + Extern, + For, + Groupshared, + If, + In, + Inout, + InputPatch, + Interface, + Line_, + LineAdj, + Linear, + LineStream, + Matrix, + Nointerpolation, + Noperspective, + Out, + OutputPatch, + Packoffset, + Point, + PointStream, + Precise, + Register, + Return, + RowMajor, + RWBuffer, + RWByteAddressBuffer, + RWStructuredBuffer, + Sample, + Sampler, + SamplerComparisonState, + SamplerState, + Shared, + Stage, + Stream, + Static, + Struct, + StructuredBuffer, + Switch, + TextureTypes, + Triangle, + TriangleAdj, + TriangleStream, + Uniform, + ValueTypes, + Vector, + Volatile, + Void, + While + ); StorageFlag.Add( - Literal("constant") - | RowMajor - | ColumnMajor - | Extern - | Precise - | Shared - | Groupshared - | Static - | Uniform - | Volatile - | Linear - | Centroid - | Nointerpolation - | Noperspective - | Sample - | In - | Out - | Inout - | Point - | Line_ - | Triangle - | LineAdj - | TriangleAdj + Literal("constant"), + RowMajor, + ColumnMajor, + Extern, + Precise, + Shared, + Groupshared, + Static, + Uniform, + Volatile, + Linear, + Centroid, + Nointerpolation, + Noperspective, + Sample, + In, + Out, + Inout, + Point, + Line_, + Triangle, + LineAdj, + TriangleAdj ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs index e23d41481f..26a869d6ea 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -84,7 +84,7 @@ public partial class SDSLGrammar : Grammar private LiteralTerminal Struct = new(); private LiteralTerminal StructuredBuffer = new(); private LiteralTerminal Switch = new(); - private AlternativeParser TextureTypes; + private AlternativeParser TextureTypes = new(); private LiteralTerminal Triangle = new(); private LiteralTerminal TriangleAdj = new(); private LiteralTerminal TriangleStream = new(); @@ -158,24 +158,24 @@ public void CreateTokens() ComponentNumber = Literal("1") | "2" | "3" | "4"; Bool = Literal("bool"); - BoolVec = Bool.Then(ComponentNumber); - BoolMat = BoolVec.Then("x").Then(ComponentNumber); - Uint = Literal("uint") | "unsigned int" | "dword"; - UintVec = Uint.Then(ComponentNumber); - UintMat = UintVec.Then("x").Then(ComponentNumber); + BoolVec.Add(Bool,ComponentNumber); + BoolMat.Add(BoolVec,Literal("x"),ComponentNumber); + Uint.Add("uint","unsigned int", "dword"); + UintVec.Add(Uint,ComponentNumber); + UintMat.Add(UintVec,"x",ComponentNumber); Int = Literal("int"); - IntVec = Int.Then(ComponentNumber); - IntMat = IntVec.Then("x").Then(ComponentNumber); + IntVec.Add(Int,ComponentNumber); + IntMat.Add(IntVec,"x",ComponentNumber); Half = Literal("half"); - HalfVec = Half.Then(ComponentNumber); - HalfMat = HalfVec.Then("x").Then(ComponentNumber); + HalfVec.Add(Half, ComponentNumber); + HalfMat.Add(HalfVec, "x", ComponentNumber); Float = Literal("float"); - FloatVec = Float.Then(ComponentNumber); - FloatMat = FloatVec.Then("x").Then(ComponentNumber); + FloatVec.Add(Float,ComponentNumber); + FloatMat.Add(FloatVec,"x",ComponentNumber); Double = Literal("double"); - DoubleVec = Double.Then(ComponentNumber); - DoubleMat = DoubleVec.Then("x").Then(ComponentNumber); + DoubleVec.Add(Double,ComponentNumber); + DoubleMat.Add(DoubleVec,"x",ComponentNumber); Buffer = Literal("Buffer"); ByteAddressBuffer = Literal("ByteAddressBuffer"); Break = Literal("break"); @@ -228,10 +228,11 @@ public void CreateTokens() Struct = Literal("struct"); StructuredBuffer = Literal("StructuredBuffer"); Switch = Literal("switch"); - TextureTypes = - (Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional())) - | (Literal("Texture2DMS").Then(Literal("Array").Optional())) - | (Literal("TextureCube").Then(Literal("Array").Optional())); + TextureTypes.Add( + Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional()), + Literal("Texture2DMS").Then(Literal("Array").Optional()), + Literal("TextureCube").Then(Literal("Array").Optional()) + ); Triangle = Literal("triangle"); TriangleAdj = Literal("triangleadj"); TriangleStream = Literal("TriangleStream"); @@ -289,19 +290,20 @@ public void CreateTokens() Dot = Literal("."); True = Literal("true"); False = Literal("false"); - PreprocessorDirectiveName = - Literal("define") - | Literal("elif") - | Literal("else") - | Literal("endif") - | Literal("error") - | Literal("if") - | Literal("ifdef") - | Literal("ifndef") - | Literal("include") - | Literal("line") - | Literal("pragma") - | Literal("undef"); + PreprocessorDirectiveName.Add( + Literal("define"), + Literal("elif"), + Literal("else"), + Literal("endif"), + Literal("error"), + Literal("if"), + Literal("ifdef"), + Literal("ifndef"), + Literal("include"), + Literal("line"), + Literal("pragma"), + Literal("undef") + ); Stage = Literal("stage"); Stream = Literal("stream"); diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index e1c4c27b3a..fae0d6ad0f 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -35,7 +35,12 @@ public GrammarMatch Parse(string shader) actualCode.Append(m.StringValue); } } - return Grammar.Match(actualCode.ToString()); + var matches = Grammar.Match(actualCode.ToString()); + if (matches.Errors.Any()) + { + throw new Exception("Parsing Exception : " + matches.ErrorMessage); + } + return matches; } } \ No newline at end of file From 079cb76d29412f43300e2c7e2238520f199f471c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 10 May 2022 11:15:29 +0200 Subject: [PATCH 0053/1182] stabilized test expressions --- src/SDSLParserExample/Program.cs | 2 +- .../OperationExpressionParsing.cs | 24 +++++++++++++++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 29 ++++++++++--------- 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 77c28c7e85..dbfc0522ee 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -11,7 +11,7 @@ var s = new Stopwatch(); var match2 = parser.Parse(shaderf); s.Start(); -var match = parser.Parse("(MyStruct)++my_var.a[0].c+6+4*5 >>2;"); +var match = parser.Parse("(MyStruct)++my_var.a[0].c+6+4*5 >>2 < 5;"); s.Stop(); diff --git a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs index 6ade9a8093..90a5d31cf8 100644 --- a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs @@ -84,6 +84,30 @@ public void TestShift() } + [Fact] + public void TestTestExpr() + { + parser.Grammar.Using(parser.Grammar.TestExpression.Then(";")); + List matches = new() + { + parser.Parse("5 < 5+3;"), + parser.Parse("a > b++ * 3 < 4;"), + parser.Parse("5 < 3 > 4;"), + parser.Parse("3 + 5 * (float)++my_var;"), + parser.Parse("3 + 5 > (float)++my_var.a*2;"), + parser.Parse("a >> (float4)my_var[0]++ * 2 + 4;"), + parser.Parse("my_otherVar > 2;"), + parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ >(float)my_value2;"), + parser.Parse("2 + (float)my_value < (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), + }; + + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + + } + [Fact] public void TestUnary() { diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 6da9bbb936..d9564e2756 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -163,19 +163,20 @@ public void CreateExpressions() var parenShift = LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ws); - var testOp = Less | LessEqual | Greater | GreaterEqual; var test = new SequenceParser(); test.Add( - parenShift | ShiftExpression, + parenShift.NotFollowedBy(UnaryExpression) | ShiftExpression, + ws, testOp.Named("Operator"), + ws, TestExpression ); TestExpression.Add( - test.Named("TestExpression"), - ShiftExpression + ShiftExpression.NotFollowedBy(ws & testOp), + test.Named("TestExpression") ); var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ws); @@ -186,7 +187,7 @@ public void CreateExpressions() var equals = new SequenceParser(); equals.Add( - BooleanTerm | TestExpression, + BooleanTerm | parenTestExpr.NotFollowedBy(UnaryExpression) | TestExpression, ws, eqOp.Named("Operator"), ws, @@ -194,32 +195,34 @@ public void CreateExpressions() ); EqualsExpression.Add( - equals.Named("EqualExpression"), - TestExpression + TestExpression.NotFollowedBy(ws & eqOp), + equals.Named("EqualExpression") ); + //TODO: add parenthesis shortcut expressions + AndExpression.Add( + EqualsExpression.NotFollowedBy(ws & "&"), EqualsExpression.Then("&").Then(AndExpression).SeparatedBy(ws).Named("BitwiseAnd") - | EqualsExpression ); XorExpression.Add( + AndExpression.NotFollowedBy(ws & "^"), AndExpression.Then("^").Then(XorExpression).SeparatedBy(ws).Named("BitwiseXor") - | AndExpression ); OrExpression.Add( + XorExpression.NotFollowedBy(ws & "|"), XorExpression.Then("|").Then(OrExpression).SeparatedBy(ws).Named("BitwiseOr") - | XorExpression ); LogicalAndExpression.Add( + OrExpression.NotFollowedBy(ws & "&&"), OrExpression.Then("&&").Then(LogicalAndExpression).SeparatedBy(ws).Named("LogicalAnd") - | OrExpression ); LogicalOrExpression.Add( + LogicalAndExpression.NotFollowedBy(ws & "||"), LogicalAndExpression.Then("||").Then(LogicalOrExpression).SeparatedBy(ws).Named("LogicalOr") - | LogicalAndExpression ); ConditionalExpression.Add( @@ -238,7 +241,7 @@ public void CreateExpressions() LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ws) ); - + // TODO : Check if method call covers all possibilities. var parameters = EqualsExpression.Then(Comma.Then(PrimaryExpression).SeparatedBy(ws).Repeat(0)).SeparatedBy(ws); MethodCall.Add( Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") From 07d1711b3bf48a138aac4a3a39f34f4006b1e5b1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 May 2022 15:29:15 +0200 Subject: [PATCH 0054/1182] Small corrections on the expressions and operator precedence --- src/SDSLParserExample/Program.cs | 4 +- .../BasicExpressionParsing.cs | 2 +- .../OperationExpressionParsing.cs | 83 ++++++++++++----- .../SDSLGrammar/SDSLGrammar.Expression.cs | 90 +++++++++---------- 4 files changed, 107 insertions(+), 72 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index dbfc0522ee..a437c86c98 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -7,11 +7,11 @@ var shaderf = File.ReadAllText("../../../SDSL/Expressions.sdsl"); var parser = new SDSLParser(); -parser.Grammar.Using(parser.Grammar.ShiftExpression.Then(";")); +parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); var s = new Stopwatch(); var match2 = parser.Parse(shaderf); s.Start(); -var match = parser.Parse("(MyStruct)++my_var.a[0].c+6+4*5 >>2 < 5;"); +var match = parser.Parse("a >> b++ | 3 < 4;"); s.Stop(); diff --git a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs index 2c8dcaa5be..fa9debac0b 100644 --- a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs @@ -60,7 +60,7 @@ public void TestUnary() parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); List matches = new() { - parser.Parse("++my_var;"), + parser.Parse("++b;"), parser.Parse("++my_var.a;"), parser.Parse("++my_var[0];"), parser.Parse("++my_var[a];"), diff --git a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs index 90a5d31cf8..ec94cdd8e0 100644 --- a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs @@ -107,45 +107,82 @@ public void TestTestExpr() Assert.True(matches.TrueForAll(x => !x.Errors.Any())); } - [Fact] - public void TestUnary() + public void TestEqualsExpr() { - parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); + parser.Grammar.Using(parser.Grammar.EqualsExpression.Then(";")); List matches = new() { - parser.Parse("++my_var;"), - parser.Parse("++my_var.a;"), - parser.Parse("++my_var[0];"), - parser.Parse("++my_var[a];"), - parser.Parse("++my_var.a[0];"), - parser.Parse("++my_var.a[b];"), - parser.Parse("++my_var.a[0].c;"), - parser.Parse("++my_var.a[b].c;"), - parser.Parse("++my_var.a[b].c[5].b.e[7][5];"), + parser.Parse("true == false;"), + parser.Parse("true != false;"), + parser.Parse("a > b++ == 3 < 4;"), + parser.Parse("true == 3 != 4;"), + parser.Parse("3 == 5 * (float)++my_var;"), + parser.Parse("3 + 5 == (float)++my_var.a*2;"), + parser.Parse("5 == a >> (float4)my_var[0]++ * 2 + 4;"), + parser.Parse("my_otherVar > 2;"), + parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), + parser.Parse("2 + (float)my_value == (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } [Fact] - public void TestCast() + public void TestBinary() { - parser.Grammar.Using(parser.Grammar.CastExpression.Then(";")); + parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); List matches = new() { - parser.Parse("(float)++my_var;"), - parser.Parse("(float)++my_var.a;"), - parser.Parse("(float4)my_var[0]++;"), - parser.Parse("(float4x4)++my_var[a];"), - parser.Parse("(MyStruct)++my_var.a[0];"), - parser.Parse("(MyStruct)my_var.a[b]++;"), - parser.Parse("(MyStruct)++my_var.a[0].c;"), - parser.Parse("(MyStruct)my_var.a[b].c++;"), - parser.Parse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + parser.Parse("5 & 4;"), + parser.Parse("1 ^ 6;"), + parser.Parse("1 | 6;"), + parser.Parse("a >> b++ | 3 << 4;"), + parser.Parse("5 ^ 3 ^ 4;"), + parser.Parse("3 & 5 * (float)++my_var;"), + parser.Parse("3 + 5 | (float)++my_var.a*2;"), + parser.Parse("5 & a >> (float4)my_var[0]++ * 2 & 4;"), + parser.Parse("my_otherVar <> 2;"), + parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c+++(float)my_value2;"), + parser.Parse("2 ^ (float)my_value | (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } + [Fact] + public void TestConditional() + { + parser.Grammar.Using(parser.Grammar.ConditionalExpression.Then(";")); + List matches = new() + { + parser.Parse("true && true;"), + parser.Parse("true || false;"), + parser.Parse("1 || 6;"), + parser.Parse("a > b++ && 3 < 4;"), + parser.Parse("true == true || 3 != 4;"), + parser.Parse("3 || 5 * (float)++my_var;"), + parser.Parse("3 + 5 && (float)++my_var.a*2;"), + parser.Parse("5 == a && (float4)my_var[0]++ * 2 & 4;"), + parser.Parse("my_otherVar > 2 &&false;"), + parser.Parse("(float)my_value && (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), + parser.Parse("2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b;"), + parser.Parse("true ? 5 : 8;"), + + }; + Assert.True(matches.TrueForAll(x => !x.Errors.Any())); + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index d9564e2756..51c9b22c84 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -33,6 +33,14 @@ public SDSLGrammar UsingPrimaryExpression() return this; } + public Parser Parenthesis(Parser p, bool notFollowedByUnary = true) + { + if (notFollowedByUnary) + return LeftParen.Then(p).Then(RightParen).SeparatedBy(WhiteSpace.Repeat(0)).NotFollowedBy(UnaryExpression); + else + return LeftParen.Then(p).Then(RightParen).SeparatedBy(WhiteSpace.Repeat(0)); + } + public void CreateExpressions() { var ws = WhiteSpace.Repeat(0); @@ -84,7 +92,7 @@ public void CreateExpressions() prefixInc.Add( incrementOp, ws, - TermExpression.NotFollowedBy(ws & (Dot | "[")) + Identifier.NotFollowedBy(ws & (Dot | "[")) | chain | arrayAccess ); @@ -121,16 +129,13 @@ public void CreateExpressions() CastExpression.NotFollowedBy(ws & mulOp), multiply.SeparatedBy(ws).Named("Multiplication") ); - var parenMulExpr = - LeftParen.Then(MulExpression).Then(RightParen).SeparatedBy(ws); - var sumOp = new AlternativeParser(); sumOp.Add(Plus, Minus); var add = new SequenceParser(); add.Add( - parenMulExpr.NotFollowedBy(UnaryExpression) | MulExpression, + Parenthesis(MulExpression) | MulExpression, ws, sumOp.Except(incrementOp), ws, @@ -143,13 +148,11 @@ public void CreateExpressions() add.Named("Addition") ); - var parenSumExpr = - LeftParen.Then(SumExpression).Then(RightParen).SeparatedBy(ws); - + var shiftOp = (LeftShift | RightShift); var shift = new SequenceParser(); shift.Add( - parenSumExpr.NotFollowedBy(UnaryExpression) | SumExpression, + Parenthesis(SumExpression) | SumExpression, ws, shiftOp.Named("Operator"), ws, @@ -160,74 +163,69 @@ public void CreateExpressions() SumExpression.NotFollowedBy(ws & shiftOp), shift.Named("ShiftExpression") ); - var parenShift = - LeftParen.Then(ShiftExpression).Then(RightParen).SeparatedBy(ws); - + + AndExpression.Add( + ShiftExpression.NotFollowedBy(ws & And.Except(AndAnd)), + (Parenthesis(ShiftExpression) | ShiftExpression).Then(And).Then(AndExpression).SeparatedBy(ws).Named("BitwiseAnd") + ); + + XorExpression.Add( + AndExpression.NotFollowedBy(ws & "^"), + (Parenthesis(AndExpression) | AndExpression).Then("^").Then(XorExpression).SeparatedBy(ws).Named("BitwiseXor") + ); + + + OrExpression.Add( + XorExpression.NotFollowedBy(ws & Or.Except(OrOr)), + (Parenthesis(XorExpression) | XorExpression).Then(Or).Then(OrExpression).SeparatedBy(ws).Named("BitwiseOr") + ); + var testOp = Less | LessEqual | Greater | GreaterEqual; var test = new SequenceParser(); test.Add( - parenShift.NotFollowedBy(UnaryExpression) | ShiftExpression, + Parenthesis(OrExpression) | OrExpression, ws, testOp.Named("Operator"), ws, TestExpression ); - + TestExpression.Add( - ShiftExpression.NotFollowedBy(ws & testOp), + OrExpression.NotFollowedBy(ws & testOp), test.Named("TestExpression") ); - var parenTestExpr = LeftParen.Then(TestExpression).Then(RightParen).SeparatedBy(ws); - - var eqOp = - Literal("==").Named("Equals") - | Literal("!=").Named("NotEquals"); - + var eqOp = + Literal("==") + | Literal("!="); + var equals = new SequenceParser(); equals.Add( - BooleanTerm | parenTestExpr.NotFollowedBy(UnaryExpression) | TestExpression, + Parenthesis(TestExpression) | TestExpression | BooleanTerm, ws, eqOp.Named("Operator"), ws, - BooleanTerm | EqualsExpression + EqualsExpression | BooleanTerm ); - + EqualsExpression.Add( TestExpression.NotFollowedBy(ws & eqOp), equals.Named("EqualExpression") ); - //TODO: add parenthesis shortcut expressions - - AndExpression.Add( - EqualsExpression.NotFollowedBy(ws & "&"), - EqualsExpression.Then("&").Then(AndExpression).SeparatedBy(ws).Named("BitwiseAnd") - ); - - XorExpression.Add( - AndExpression.NotFollowedBy(ws & "^"), - AndExpression.Then("^").Then(XorExpression).SeparatedBy(ws).Named("BitwiseXor") - ); - - OrExpression.Add( - XorExpression.NotFollowedBy(ws & "|"), - XorExpression.Then("|").Then(OrExpression).SeparatedBy(ws).Named("BitwiseOr") - ); - LogicalAndExpression.Add( - OrExpression.NotFollowedBy(ws & "&&"), - OrExpression.Then("&&").Then(LogicalAndExpression).SeparatedBy(ws).Named("LogicalAnd") + EqualsExpression.NotFollowedBy(ws & AndAnd), + (Parenthesis(EqualsExpression) | EqualsExpression).Then(AndAnd).Then(LogicalAndExpression).SeparatedBy(ws).Named("LogicalAnd") ); LogicalOrExpression.Add( - LogicalAndExpression.NotFollowedBy(ws & "||"), - LogicalAndExpression.Then("||").Then(LogicalOrExpression).SeparatedBy(ws).Named("LogicalOr") + LogicalAndExpression.NotFollowedBy(ws & OrOr), + (Parenthesis(LogicalAndExpression) | LogicalAndExpression).Then(OrOr).Then(LogicalOrExpression).SeparatedBy(ws).Named("LogicalOr") ); ConditionalExpression.Add( LogicalOrExpression.NotFollowedBy(ws & "?") - | LogicalOrExpression + | (Parenthesis(LogicalOrExpression) | LogicalOrExpression) .Then("?") .Then(CastExpression | ParenExpression | LogicalOrExpression) .Then(":") From 7a4d135c1dd7be38659d073da5fd895765c4f9e1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 May 2022 17:00:21 +0200 Subject: [PATCH 0055/1182] Correction declarations --- src/SDSLParserExample/Program.cs | 6 +- src/SDSLParserExample/SDSL/shader.sdsl | 2 +- src/SDSLParserExample/SDSL/shader2.sdsl | 5 + .../SDSLGrammar/SDSLGrammar.Declaration.cs | 94 +++++++++++++------ .../SDSLGrammar/SDSLGrammar.Expression.cs | 16 ++-- .../SDSLGrammar/SDSLGrammar.Shader.cs | 70 ++++++++------ .../SDSLGrammar/SDSLGrammar.Statements.cs | 70 ++++++++------ .../SDSLGrammar/SDSLGrammar.cs | 2 +- 8 files changed, 162 insertions(+), 103 deletions(-) create mode 100644 src/SDSLParserExample/SDSL/shader2.sdsl diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index a437c86c98..b232785adf 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -4,14 +4,14 @@ using System.Diagnostics; -var shaderf = File.ReadAllText("../../../SDSL/Expressions.sdsl"); +var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var parser = new SDSLParser(); -parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); +//parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); var s = new Stopwatch(); var match2 = parser.Parse(shaderf); s.Start(); -var match = parser.Parse("a >> b++ | 3 < 4;"); +var match = parser.Parse(shaderf); s.Stop(); diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl index 868b1915c9..6daa767ce9 100644 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -1,7 +1,7 @@ // Some comments shader BasicMixin : BasicShader, Parent2, Parent3 { - float myFloat = 0.2f; + float myFloat=0.2f; stage float3 myPosition : register(b); stage stream float2 screenPosition : register(vs, b); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl new file mode 100644 index 0000000000..8b062ad125 --- /dev/null +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -0,0 +1,5 @@ +shader BasicMixin{ + + float4 a : packoffset(a.c); + stream float4 aqsdj; +}; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs index 33b1735094..b27a1c58d1 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -5,8 +5,10 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public AlternativeParser ShaderValueDeclaration = new(); - public AlternativeParser ConstantBufferValueDeclaration = new(); + public SequenceParser ShaderValueDeclaration = new(); + public SequenceParser ConstantBufferValueDeclaration = new(); + public SequenceParser StructDefinition = new(); + public SDSLGrammar UsingDeclarators() { var ws = WhiteSpace.Repeat(0); @@ -22,44 +24,74 @@ public void CreateDeclarators() var declare = Identifier.Then(Identifier).SeparatedBy(ws1).Then(Semi).SeparatedBy(ws); - var declaratorSupplement = - Colon.Then( - Packoffset.Then(LeftParen).Then(Identifier.Then(Dot.Then(Identifier).Repeat(0))).Then(RightParen).SeparatedBy(ws).Named("PackOffset") - | Register.Then(LeftParen).Then(Identifier.Then(Comma.Then(Identifier).SeparatedBy(ws).Repeat(0).SeparatedBy(ws))).Then(RightParen).SeparatedBy(ws).Named("RegisterAllocation") - | Identifier.Named("Semantic") - ).SeparatedBy(ws).Optional(); + var packoffset = new SequenceParser(); + packoffset.Add( + Packoffset, + LeftParen, + Identifier, + (Dot & Identifier).Repeat(0), + RightParen + ); + packoffset.Separator = ws; + + var register = new SequenceParser(); + register.Add( + Register, + LeftParen, + (Identifier & ~Comma).SeparatedBy(ws).Repeat(0).SeparatedBy(ws), + RightParen + ); + register.Separator = ws; + + var supplement = new SequenceParser(); + supplement.Add( + Colon, + ws, + packoffset.Named("PackOffset") + | register + | Identifier.Named("Semantic") + ); - var supplement = - ( - Colon & - ( - (Packoffset & LeftParen & Identifier & ((Dot & Identifier).Repeat(0)) & RightParen) - .SeparatedBy(ws).Named("PackOffset") - | (Register & LeftParen & (Identifier & (Comma & Identifier).SeparatedBy(ws)).Repeat(0).SeparateChildrenBy(ws) & RightParen) - .SeparatedBy(ws).Named("Register") - | Identifier.Named("Semantic") - ) - ).SeparatedBy(ws); + var staging = + Stage + | Stage & ws1 & Stream + | Stream; - var valueDeclaration = - (~Stage & ~Stream & ValueTypes & Identifier).SeparatedBy(ws1) - & (~(LeftBracket & Literals & RightBracket).SeparatedBy(ws)); - + var valueDeclaration = new SequenceParser(); + valueDeclaration.Add( + staging.Then(ws1).Optional(), + ValueTypes | Identifier, + ws1, + Identifier + ); + var assignOrSupplement = + (AssignOperators & PrimaryExpression & supplement).SeparatedBy(ws) + | (AssignOperators & PrimaryExpression).SeparatedBy(ws) + | supplement; ShaderValueDeclaration.Add( - (valueDeclaration & ~(AssignOperators & PrimaryExpression)) - .SeparatedBy(ws) + valueDeclaration, + assignOrSupplement.Optional(), + Semi ); + ShaderValueDeclaration.Separator = ws; + ConstantBufferValueDeclaration.Add( - (valueDeclaration & ~(AssignOperators & PrimaryExpression) & ~supplement) - .SeparatedBy(ws) + valueDeclaration, + assignOrSupplement.Optional(), + Semi ); + + ConstantBufferValueDeclaration.Separator = ws; + StructDefinition.Add( - Struct.Then(Identifier).SeparatedBy(ws1) - .Then(LeftBrace) - .Then(declare.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace).Then(Semi).SeparatedBy(ws) + Struct & ws1 & Identifier, + LeftBrace, + (declare & Semi).SeparatedBy(ws).Repeat(0).SeparatedBy(ws), + RightBrace, + Semi ); + StructDefinition.Separator = ws; } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 51c9b22c84..5d0259f6c1 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -52,11 +52,17 @@ public void CreateExpressions() PlusPlus, MinusMinus ); - + + // TODO : write tests for method calls + var parameters = PrimaryExpression.Then(Comma.Optional()).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); + MethodCall.Add( + Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") + ); TermExpression.Add( Literals, - Identifier.Except(Keywords | ValueTypes) + Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + MethodCall // ,ParenExpression ); @@ -239,12 +245,6 @@ public void CreateExpressions() LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ws) ); - // TODO : Check if method call covers all possibilities. - var parameters = EqualsExpression.Then(Comma.Then(PrimaryExpression).SeparatedBy(ws).Repeat(0)).SeparatedBy(ws); - MethodCall.Add( - Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") - ); - PrimaryExpression.Add( MethodCall diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 2e75645494..6b639967e1 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -6,12 +6,12 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); - public AlternativeParser Shader = new(); + public SequenceParser ShaderExpression = new(); public SDSLGrammar UsingShader() { - Inner = Shader; + Inner = ShaderExpression; return this; } public void CreateShader() @@ -19,38 +19,52 @@ public void CreateShader() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - var shaderGenericValue = - Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType") - | ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue") - | ValueTypes; - - var shaderGenerics = - Literal("<") - .Then(shaderGenericValue) - .Then( - Comma.Then(shaderGenericValue).SeparatedBy(ws).Repeat(0) - ) - .Then(">").SeparatedBy(ws); - - var shaderContentTypes = - MethodDeclaration - | ShaderValueDeclaration + var shaderGenericValue = new AlternativeParser(); + shaderGenericValue.Add( + Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), + ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), + ValueTypes + ); + + var shaderGenerics = new SequenceParser(); + shaderGenerics.Add( + "<", + ws, + shaderGenericValue, + ws, + Comma.Then(shaderGenericValue).SeparatedBy(ws).Repeat(0), + ws, + ">" + ); + + var shaderContentTypes = new AlternativeParser(); + shaderContentTypes.Add( + StructDefinition, + //MethodDeclaration, + ShaderValueDeclaration + // | Attribute - ; + ); - var shaderBody = - LeftBrace.Then(shaderContentTypes.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws); + var shaderBody = new SequenceParser(); + shaderBody.Add( + LeftBrace, + shaderContentTypes.Repeat(0).SeparatedBy(ws), + RightBrace + ); + shaderBody.Separator = ws; var inheritances = Colon.Then(Identifier.Then(shaderGenerics.Optional()).Then(Comma.Then(Identifier.Then(shaderGenerics.Optional())).SeparatedBy(ws).Repeat(0))).SeparatedBy(ws).Optional(); - Shader.Add( - ws & - Literal("shader") - .Then(Identifier.Then(shaderGenerics.Optional())).SeparatedBy(ws1) - .Then(shaderBody.Or(inheritances.Named("Inherit").Then(shaderBody).SeparatedBy(ws))) - .Then(";").SeparatedBy(ws).Named("ShaderProgram") - & ws + ShaderExpression.Add( + ws, + "shader" & ws1 & Identifier.Named("ShaderName").Then((ws1 & shaderGenerics).Optional()), + shaderBody.Named("Body"), + ";", + ws ); + ShaderExpression.Separator = ws; + ShaderExpression.Name = "ShaderProgram"; } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index bf87a54ffd..00273c8589 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -5,13 +5,12 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public AlternativeParser StructDefinition = new(); - public AlternativeParser Attribute = new(); + public SequenceParser Attribute = new(); public AlternativeParser Statement = new(); - public AlternativeParser ControlFlow = new(); - public AlternativeParser ConstantBuffer = new(); + public SequenceParser ControlFlow = new(); + public SequenceParser ConstantBuffer = new(); public AlternativeParser ShaderMethodCall = new(); - public AlternativeParser Block = new(); + public SequenceParser Block = new(); public SDSLGrammar UsingStatements() @@ -44,13 +43,17 @@ public void CreateStatements() .Then(Semi).SeparatedBy(ws); Attribute.Add( - LeftBracket - .Then(Identifier) - .Then(LeftParen) - .Then((Identifier | Literals).Then(Comma.Optional()).Repeat(0).SeparateChildrenBy(ws)) - .Then(RightParen) - .Then(RightBracket) - .SeparatedBy(ws) + LeftBracket, + ws, + Identifier, + ws, + LeftParen, + ws, + (Identifier | Literals).Then(Comma.Optional()).Repeat(0).SeparateChildrenBy(ws), + ws, + RightParen, + ws, + RightBracket ); var assignVar = @@ -76,17 +79,21 @@ public void CreateStatements() Statement.Add( - Block.Named("BlockExpression") - | returnStatement.Named("Return") - | assignChain - | ShaderMethodCall - | declareAssign.Named("DeclareAssign") - | assignVar.Named("Assign") - | PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") + Block.Named("BlockExpression"), + returnStatement.Named("Return"), + assignChain, + ShaderMethodCall, + declareAssign.Named("DeclareAssign"), + assignVar.Named("Assign"), + PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") ); Block.Add( - LeftBrace.Then(Statement.Repeat(0).SeparatedBy(ws)).Then(RightBrace).SeparatedBy(ws) + LeftBrace, + ws, + Statement.Repeat(0).SeparatedBy(ws), + ws, + RightBrace ); var flowStatement = Statement; @@ -100,21 +107,22 @@ public void CreateStatements() Else.Then(flowStatement).SeparatedBy(ws1); ControlFlow.Add( - Attribute.Repeat(0).Named("Attributes").Then( - ifStatement.Named("IfStatement") - | elseStatement.Named("ElseStatement") - | elseIfStatement.Named("ElseIfStatement") - ).SeparatedBy(ws) + Attribute.Repeat(0).Named("Attributes"), + ws, + ifStatement.Named("IfStatement") + | elseStatement.Named("ElseStatement") + | elseIfStatement.Named("ElseIfStatement") ); - - - ConstantBuffer.Add( - Literal("cbuffer").Then(Identifier).SeparatedBy(ws1) - .Then(LeftBrace) - .Then() + "cbuffer", + ws1, + Identifier, + ws, + LeftBrace, + ws, + RightBrace ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index 18b9272005..9166297d91 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -10,7 +10,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar() : base("sdsl") { CreateAll(); - Inner = Shader; + Inner = ShaderExpression; } public SDSLGrammar Using(EtoParser p) From d0f48ebbd634bfedc605a90ea28b6677e74dc5ce Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 May 2022 19:52:24 +0200 Subject: [PATCH 0056/1182] Method call optimization + generics --- src/SDSLParserExample/SDSL/shader2.sdsl | 20 +++++++++-- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 24 ++++++++----- .../SDSLGrammar/SDSLGrammar.Expression.cs | 19 ++++++---- .../SDSLGrammar.MethodDeclaration.cs | 33 +++++++++++------ .../SDSLGrammar/SDSLGrammar.Shader.cs | 35 ++++++++++++++----- .../SDSLGrammar/SDSLGrammar.Statements.cs | 8 ++--- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 14 +++++++- 7 files changed, 109 insertions(+), 44 deletions(-) diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 8b062ad125..bfeb5aeb4e 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,5 +1,19 @@ -shader BasicMixin{ +shader BasicMixin : ParentShader, ParentShader2, ParentShader3<5,3> { + struct MyStruct { + float a; + }; + + float b; + stage float4 a = 3*2+5; + stage stream float4 color : SV_COLOR; + stage stream float4 color2 = float4(1,float2(5,6),3+5*7,4*2) : SV_COLOR; + + + abstract void foo(); + + void MyFunctions(float a, Input b) + { + + } - float4 a : packoffset(a.c); - stream float4 aqsdj; }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs index b27a1c58d1..d9da2e6998 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -21,8 +21,14 @@ public void CreateDeclarators() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - var declare = - Identifier.Then(Identifier).SeparatedBy(ws1).Then(Semi).SeparatedBy(ws); + var declare = new SequenceParser(); + declare.Add( + ValueTypes | Identifier, + ws1, + Identifier, + ws, + Semi + ); var packoffset = new SequenceParser(); packoffset.Add( @@ -38,7 +44,7 @@ public void CreateDeclarators() register.Add( Register, LeftParen, - (Identifier & ~Comma).SeparatedBy(ws).Repeat(0).SeparatedBy(ws), + Identifier.Repeat(0).SeparatedBy(ws & Comma & ws), RightParen ); register.Separator = ws; @@ -53,7 +59,7 @@ public void CreateDeclarators() ); var staging = - Stage + Stage.NotFollowedBy(ws1 & Stream) | Stage & ws1 & Stream | Stream; @@ -65,10 +71,12 @@ public void CreateDeclarators() Identifier ); - var assignOrSupplement = + var assignOrSupplement = new AlternativeParser(); + assignOrSupplement.Add( + supplement, + (AssignOperators & PrimaryExpression).SeparatedBy(ws).NotFollowedBy(ws & supplement), (AssignOperators & PrimaryExpression & supplement).SeparatedBy(ws) - | (AssignOperators & PrimaryExpression).SeparatedBy(ws) - | supplement; + ); ShaderValueDeclaration.Add( valueDeclaration, @@ -88,7 +96,7 @@ public void CreateDeclarators() StructDefinition.Add( Struct & ws1 & Identifier, LeftBrace, - (declare & Semi).SeparatedBy(ws).Repeat(0).SeparatedBy(ws), + declare.Repeat(0).SeparatedBy(ws), RightBrace, Semi ); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 5d0259f6c1..7b8b96db36 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -24,7 +24,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser IncrementExpression = new(); public AlternativeParser ParenExpression = new(); public AlternativeParser EqualsExpression = new(); - public AlternativeParser MethodCall = new(); + public SequenceParser MethodCall = new(); public AlternativeParser PrimaryExpression = new(); public SDSLGrammar UsingPrimaryExpression() @@ -54,10 +54,8 @@ public void CreateExpressions() ); // TODO : write tests for method calls - var parameters = PrimaryExpression.Then(Comma.Optional()).SeparatedBy(ws).Repeat(0).SeparatedBy(ws); - MethodCall.Add( - Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") - ); + // TODO : Optimize method call + TermExpression.Add( Literals, @@ -244,11 +242,18 @@ public void CreateExpressions() ParenExpression.Add( LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ws) ); + + var parameters = + PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws); + + MethodCall.Add( + Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") + ); PrimaryExpression.Add( - MethodCall - | ConditionalExpression + MethodCall, + ConditionalExpression ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 88fc5e688d..7a994f81c6 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -5,8 +5,8 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public AlternativeParser ParameterList = new(); - public AlternativeParser ValueOrGeneric = new(); + public SequenceParser ParameterList = new(); + public SequenceParser ValueOrGeneric = new(); public AlternativeParser MethodDeclaration = new(); @@ -21,11 +21,18 @@ public void CreateMethodDeclaration() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); + var genericsList = new SequenceParser(); + genericsList.Add( + "<", + (Identifier & genericsList.Optional()) + .Repeat(0).SeparatedBy(ws & Comma & ws), + ">" + ); + genericsList.Separator = ws; ValueOrGeneric.Add( - ValueTypes - | Identifier.Then("<").Then(ValueOrGeneric.Then(Comma.Optional()).Repeat(1).SeparateChildrenBy(ws)).Then(">").SeparatedBy(ws) - | Identifier + ValueTypes | Identifier, + genericsList.Optional() ); var declarePost = @@ -42,19 +49,23 @@ public void CreateMethodDeclaration() ParameterList.Add( - LeftParen - .Then(Comma.Optional().Then(parameter).SeparatedBy(ws).Repeat(0).SeparatedBy(ws)) - .Then(RightParen).SeparatedBy(ws) + LeftParen, + parameter.Repeat(0).SeparatedBy(ws & Comma & ws), + RightParen ); + ParameterList.Separator = ws; MethodDeclaration.Add( + // Abstract method Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod") - | Literal("override").Optional().Then(Literal("stage").Optional()) + .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod"), + // Override or normal method + Literal("override").Optional() + .Then(Literal("stage").Optional()) .Then(Identifier).Then(Identifier).SeparatedBy(ws1) .Then(ParameterList) .Then(LeftBrace) - .Then(Statement.Repeat(0)) + .Then(Statement.Repeat(0).SeparatedBy(ws)) .Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 6b639967e1..a0899be770 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -29,18 +29,29 @@ public void CreateShader() var shaderGenerics = new SequenceParser(); shaderGenerics.Add( "<", - ws, - shaderGenericValue, - ws, - Comma.Then(shaderGenericValue).SeparatedBy(ws).Repeat(0), - ws, + shaderGenericValue.Repeat(1).SeparatedBy(ws & Comma & ws), + ">" + ); + shaderGenerics.Separator = ws; + + var inheritGenericsValues = new AlternativeParser( + ValueTypes, + Identifier, + Literals + ); + + var inheritGenerics = new SequenceParser(); + inheritGenerics.Add( + "<", + inheritGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), ">" ); + inheritGenerics.Separator = ws; var shaderContentTypes = new AlternativeParser(); shaderContentTypes.Add( StructDefinition, - //MethodDeclaration, + MethodDeclaration, ShaderValueDeclaration // | Attribute @@ -54,12 +65,20 @@ public void CreateShader() ); shaderBody.Separator = ws; - var inheritances = Colon.Then(Identifier.Then(shaderGenerics.Optional()).Then(Comma.Then(Identifier.Then(shaderGenerics.Optional())).SeparatedBy(ws).Repeat(0))).SeparatedBy(ws).Optional(); + var inheritances = + Colon + .Then( + Identifier.Then(inheritGenerics.Optional()).SeparatedBy(ws) + .Repeat(1).SeparatedBy(ws & Comma & ws) + ) + .SeparatedBy(ws); ShaderExpression.Add( ws, - "shader" & ws1 & Identifier.Named("ShaderName").Then((ws1 & shaderGenerics).Optional()), + "shader" & ws1 & Identifier.Named("ShaderName"), + shaderGenerics.Optional(), + inheritances.Optional(), shaderBody.Named("Body"), ";", ws diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index 00273c8589..f8690939b2 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -44,17 +44,13 @@ public void CreateStatements() Attribute.Add( LeftBracket, - ws, Identifier, - ws, LeftParen, - ws, - (Identifier | Literals).Then(Comma.Optional()).Repeat(0).SeparateChildrenBy(ws), - ws, + (Identifier | Literals).Repeat(0).SeparatedBy(ws & Comma & ws), RightParen, - ws, RightBracket ); + Attribute.Separator = ws; var assignVar = Identifier.Named("Variable").NotFollowedBy(Identifier) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 39ea0b0e21..0c111023e1 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -35,13 +35,25 @@ public void CreateTokenGroups() ); Operators.Add( + PlusPlus, Plus, + MinusMinus, Minus, Star, Div, Mod, LeftShift, - RightShift + RightShift, + AndAnd, + And, + OrOr, + Or, + "^", + Equal, + "==", + NotEqual, + Question + ); AssignOperators.Add( From 74ea85e7720c09819b0fba16da4de7b435d66ec0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 May 2022 20:07:29 +0200 Subject: [PATCH 0057/1182] Optimizing expressions --- .../SDSLGrammar/SDSLGrammar.Expression.cs | 92 +++++-------------- 1 file changed, 24 insertions(+), 68 deletions(-) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 7b8b96db36..75e136dcb4 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -121,115 +121,71 @@ public void CreateExpressions() ); - var mulOp = Star | Div | Mod; - var multiply = new SequenceParser(); - multiply.Add( - CastExpression, - mulOp.Named("Operator"), - MulExpression - ); - + var mulOp = Star | Div | Mod; MulExpression.Add( - CastExpression.NotFollowedBy(ws & mulOp), - multiply.SeparatedBy(ws).Named("Multiplication") - ); - - var sumOp = new AlternativeParser(); - sumOp.Add(Plus, Minus); - - var add = new SequenceParser(); - add.Add( - Parenthesis(MulExpression) | MulExpression, - ws, - sumOp.Except(incrementOp), - ws, - SumExpression + CastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) ); + var sumOp = Plus | Minus; SumExpression.Add( - MulExpression.NotFollowedBy(ws & sumOp.Except(incrementOp)), - add.Named("Addition") + (Parenthesis(MulExpression) | MulExpression) + .Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) ); - var shiftOp = (LeftShift | RightShift); - var shift = new SequenceParser(); - shift.Add( - Parenthesis(SumExpression) | SumExpression, - ws, - shiftOp.Named("Operator"), - ws, - ShiftExpression - ); + var shiftOp = LeftShift | RightShift; ShiftExpression.Add( - SumExpression.NotFollowedBy(ws & shiftOp), - shift.Named("ShiftExpression") + (Parenthesis(SumExpression) | SumExpression) + .Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) ); AndExpression.Add( - ShiftExpression.NotFollowedBy(ws & And.Except(AndAnd)), - (Parenthesis(ShiftExpression) | ShiftExpression).Then(And).Then(AndExpression).SeparatedBy(ws).Named("BitwiseAnd") + (Parenthesis(ShiftExpression) | ShiftExpression) + .Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) ); XorExpression.Add( - AndExpression.NotFollowedBy(ws & "^"), - (Parenthesis(AndExpression) | AndExpression).Then("^").Then(XorExpression).SeparatedBy(ws).Named("BitwiseXor") + (Parenthesis(AndExpression) | AndExpression) + .Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) ); OrExpression.Add( - XorExpression.NotFollowedBy(ws & Or.Except(OrOr)), - (Parenthesis(XorExpression) | XorExpression).Then(Or).Then(OrExpression).SeparatedBy(ws).Named("BitwiseOr") + (Parenthesis(XorExpression) | XorExpression) + .Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) ); var testOp = Less | LessEqual | Greater | GreaterEqual; - var test = new SequenceParser(); - test.Add( - Parenthesis(OrExpression) | OrExpression, - ws, - testOp.Named("Operator"), - ws, - TestExpression - ); TestExpression.Add( - OrExpression.NotFollowedBy(ws & testOp), - test.Named("TestExpression") + (Parenthesis(OrExpression) | OrExpression) + .Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) ); var eqOp = Literal("==") | Literal("!="); - var equals = new SequenceParser(); - equals.Add( - Parenthesis(TestExpression) | TestExpression | BooleanTerm, - ws, - eqOp.Named("Operator"), - ws, - EqualsExpression | BooleanTerm - ); - EqualsExpression.Add( - TestExpression.NotFollowedBy(ws & eqOp), - equals.Named("EqualExpression") + (Parenthesis(TestExpression) | TestExpression) + .Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) ); LogicalAndExpression.Add( - EqualsExpression.NotFollowedBy(ws & AndAnd), - (Parenthesis(EqualsExpression) | EqualsExpression).Then(AndAnd).Then(LogicalAndExpression).SeparatedBy(ws).Named("LogicalAnd") + (Parenthesis(EqualsExpression) | EqualsExpression) + .Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) ); LogicalOrExpression.Add( - LogicalAndExpression.NotFollowedBy(ws & OrOr), - (Parenthesis(LogicalAndExpression) | LogicalAndExpression).Then(OrOr).Then(LogicalOrExpression).SeparatedBy(ws).Named("LogicalOr") + (Parenthesis(LogicalAndExpression) | LogicalAndExpression) + .Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) ); ConditionalExpression.Add( - LogicalOrExpression.NotFollowedBy(ws & "?") - | (Parenthesis(LogicalOrExpression) | LogicalOrExpression) + LogicalOrExpression.NotFollowedBy(ws & "?"), + (Parenthesis(LogicalOrExpression) | LogicalOrExpression) .Then("?") .Then(CastExpression | ParenExpression | LogicalOrExpression) .Then(":") From 9ccbf932cacc0a43258d3ef4d9725ca7064e1a75 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 May 2022 20:39:06 +0200 Subject: [PATCH 0058/1182] Optimization + Directive corrections --- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 6 +- .../SDSLGrammar.Directives.Expression.cs | 255 ++++++++++++------ .../SDSLGrammar/SDSLGrammar.Expression.cs | 42 +-- .../SDSLGrammar/SDSLGrammar.Shader.cs | 27 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 4 +- 5 files changed, 206 insertions(+), 128 deletions(-) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs index d9da2e6998..8d9779fc68 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -5,9 +5,9 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public SequenceParser ShaderValueDeclaration = new(); - public SequenceParser ConstantBufferValueDeclaration = new(); - public SequenceParser StructDefinition = new(); + public SequenceParser ShaderValueDeclaration = new() { Name = "ShaderValueDeclaration" }; + public SequenceParser ConstantBufferValueDeclaration = new(){Name = "ConstantBufferValueDeclaration"}; + public SequenceParser StructDefinition = new(){Name = "StructDefinition"}; public SDSLGrammar UsingDeclarators() { diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index b978adb8b8..bd2d50232d 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -5,113 +5,198 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public AlternativeParser DirectiveTerm = new(); - public AlternativeParser DirectiveMul = new(); - public AlternativeParser DirectiveSum = new(); - public AlternativeParser DirectiveShift = new(); - - public AlternativeParser DirectiveTest = new(); - - public AlternativeParser DirectiveIncrementExpr = new(); - public AlternativeParser ParenDirectiveExpr = new(); - public AlternativeParser DirectiveEquals = new(); - public AlternativeParser DirectiveExpr = new(); + public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; + public AlternativeParser DirectivePostFixExpression = new() { Name = "DirectivePostFixExpression" }; + public AlternativeParser DirectiveUnaryExpression = new() { Name = "DirectiveUnaryExpression" }; + public AlternativeParser DirectiveCastExpression = new() { Name = "DirectiveCastExpression" }; + public AlternativeParser DirectiveMulExpression = new() { Name = "DirectiveMulExpression" }; + public AlternativeParser DirectiveSumExpression = new() { Name = "DirectiveSumExpression" }; + public AlternativeParser DirectiveShiftExpression = new() { Name = "DirectiveShiftExpression" }; + + public AlternativeParser DirectiveConditionalExpression = new() { Name = "DirectiveConditionalExpression" }; + public AlternativeParser DirectiveLogicalOrExpression = new() { Name = "DirectiveLogicalOrExpression" }; + public AlternativeParser DirectiveLogicalAndExpression = new() { Name = "DirectiveLogicalAndExpression" }; + public AlternativeParser DirectiveOrExpression = new() { Name = "DirectiveOrExpression" }; + public AlternativeParser DirectiveXorExpression = new() { Name = "DirectiveXorExpression" }; + public AlternativeParser DirectiveAndExpression = new() { Name = "DirectiveAndExpression" }; + public AlternativeParser DirectiveTestExpression = new() { Name = "DirectiveTestExpression" }; + + public AlternativeParser DirectiveIncrementExpression = new() { Name = "DirectiveIncrementExpression" }; + public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; + public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; + public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; public SDSLGrammar UsingDirectiveExpression() { - Inner = DirectiveExpr; + Inner = DirectiveExpression; return this; } public void CreateDirectiveExpressions() { - var ls = SingleLineWhiteSpace.Repeat(0); + var ws = SingleLineWhiteSpace.Repeat(0); var ls1 = SingleLineWhiteSpace.Repeat(1); - var incrementOp = - Literal("++").Named("PlusPlus") - | Literal("--").Named("MinusMinus"); - - var postfixIncrement = - Identifier.Then(incrementOp.Repeat(0,1)).SeparatedBy(ls); - var prefixIncrement = - incrementOp.Named("IncrementOp").Then(Identifier).SeparatedBy(ls); + var incrementOp = new AlternativeParser(); + incrementOp.Add( + PlusPlus, + MinusMinus + ); + + // TODO : write tests for method calls + // TODO : Optimize method call + + + DirectiveTermExpression.Add( + Literals, + Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + MethodCall + // ,DirectiveParenExpression + ); + + var arrayAccess = new SequenceParser(); + var chain = new SequenceParser(); + var postfixInc = new SequenceParser(); + arrayAccess.Add( + Identifier, + ws, + (LeftBracket & ws & DirectiveExpression & ws & RightBracket).Repeat(1).SeparatedBy(ws) + ); + chain.Add( + arrayAccess.Named("ArrayAccessor") | Identifier, + ws, + (Dot & ws & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) + ); + postfixInc.Add( + chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, + ws, + incrementOp.Named("Operator") + ); - DirectiveIncrementExpr.Add( - prefixIncrement.Named("PreIncrement") - | postfixIncrement + DirectivePostFixExpression.Add( + DirectiveTermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), + postfixInc.Named("PostfixIncrement"), + chain.Named("AccessorChain"), + arrayAccess.Named("ArrayAccesor") ); - - DirectiveTerm.Add( - Literals - | IncrementExpression - | ParenExpression.Named("ParenthesisExpr") + var prefixInc = new SequenceParser(); + prefixInc.Add( + incrementOp, + ws, + Identifier.NotFollowedBy(ws & (Dot | "[")) + | chain + | arrayAccess ); - var multiply = TermExpression.Then(Star | Div | Mod).Then(MulExpression).SeparatedBy(ls); - DirectiveMul.Add( - multiply.Named("Multiplication") - | TermExpression + DirectiveUnaryExpression.Add( + DirectivePostFixExpression, + prefixInc.Named("PrefixIncrement"), + Literal("sizeof").Then(LeftParen).Then(Identifier | DirectiveUnaryExpression).Then(RightParen).Named("SizeOf") ); - - var sumOp = (Plus - PlusPlus) | (Minus - MinusMinus); - var add = MulExpression.Then(sumOp).Then(SumExpression).SeparatedBy(ls); - DirectiveSum.Add( - add.Named("Addition") - | MulExpression + + var cast = new SequenceParser(); + cast.Add( + LeftParen, + ValueTypes | Identifier, + RightParen, + DirectiveUnaryExpression + ); + + DirectiveCastExpression.Add( + DirectiveUnaryExpression, + cast.SeparatedBy(ws).Named("DirectiveCastExpression") ); + + var mulOp = Star | Div | Mod; + DirectiveMulExpression.Add( + DirectiveCastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) + ); + + var sumOp = Plus | Minus; + + DirectiveSumExpression.Add( + (Parenthesis(DirectiveMulExpression) | DirectiveMulExpression) + .Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) + ); + + var shiftOp = LeftShift | RightShift; - var shift = - SumExpression.Then(shiftOp.Named("Operator")).Then(ShiftExpression).SeparatedBy(ls); - - DirectiveShift.Add( - SumExpression - | shift.Named("ShiftExpression") - ); - - - var testOp = (Less - LeftShift) | LessEqual | (Greater - RightShift) | GreaterEqual; - var test = ShiftExpression.Then(testOp).Then(TestExpression).SeparatedBy(ls); - - DirectiveTest.Add( - test.Named("TestExpression") - | ShiftExpression - ); - var equality = - Literal("==").Named("Equals") - | Literal("!=").Named("NotEquals"); - var equals = - (BooleanTerm | TermExpression) - .Then(equality) - .Then( - BooleanTerm - | EqualsExpression - ) - .SeparatedBy(ls).Named("Equals"); - - - DirectiveEquals.Add( - TestExpression - | equals - ); - - ParenDirectiveExpr.Add( - LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ls) - ); - - - - var methodCall = Identifier.Then(LeftParen).Then(RightParen).SeparatedBy(ls).Named("DirectiveMethodCall"); - - DirectiveExpr.Add( - DirectiveEquals - // - methodCall - // | methodCall + + DirectiveShiftExpression.Add( + (Parenthesis(DirectiveSumExpression) | DirectiveSumExpression) + .Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) + ); + + + DirectiveAndExpression.Add( + (Parenthesis(DirectiveShiftExpression) | DirectiveShiftExpression) + .Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) + ); + + DirectiveXorExpression.Add( + (Parenthesis(DirectiveAndExpression) | DirectiveAndExpression) + .Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) + ); + + + DirectiveOrExpression.Add( + (Parenthesis(DirectiveXorExpression) | DirectiveXorExpression) + .Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) + ); + + var testOp = Less | LessEqual | Greater | GreaterEqual; + + DirectiveTestExpression.Add( + (Parenthesis(DirectiveOrExpression) | DirectiveOrExpression) + .Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) + ); + + var eqOp = + Literal("==") + | Literal("!="); + + DirectiveEqualsExpression.Add( + (Parenthesis(DirectiveTestExpression) | DirectiveTestExpression) + .Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) + ); + + DirectiveLogicalAndExpression.Add( + (Parenthesis(DirectiveEqualsExpression) | DirectiveEqualsExpression) + .Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) + ); + DirectiveLogicalOrExpression.Add( + (Parenthesis(DirectiveLogicalAndExpression) | DirectiveLogicalAndExpression) + .Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) + ); + + DirectiveConditionalExpression.Add( + DirectiveLogicalOrExpression.NotFollowedBy(ws & "?"), + (Parenthesis(DirectiveLogicalOrExpression) | DirectiveLogicalOrExpression) + .Then("?") + .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) + .Then(":") + .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) + .SeparatedBy(ws) + .Named("Ternary") + + ); + + DirectiveParenExpression.Add( + LeftParen.Then(DirectiveExpression).Then(RightParen).SeparatedBy(ws) + ); + + var parameters = + DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws); + + + DirectiveExpression.Add( + MethodCall, + DirectiveConditionalExpression ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 75e136dcb4..a083af54a7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -5,27 +5,27 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public AlternativeParser TermExpression = new(); - public AlternativeParser PostFixExpression = new(); - public AlternativeParser UnaryExpression = new(); - public AlternativeParser CastExpression = new(); - public AlternativeParser MulExpression = new(); - public AlternativeParser SumExpression = new(); - public AlternativeParser ShiftExpression = new(); - - public AlternativeParser ConditionalExpression = new(); - public AlternativeParser LogicalOrExpression = new(); - public AlternativeParser LogicalAndExpression = new(); - public AlternativeParser OrExpression = new(); - public AlternativeParser XorExpression = new(); - public AlternativeParser AndExpression = new(); - public AlternativeParser TestExpression = new(); - - public AlternativeParser IncrementExpression = new(); - public AlternativeParser ParenExpression = new(); - public AlternativeParser EqualsExpression = new(); - public SequenceParser MethodCall = new(); - public AlternativeParser PrimaryExpression = new(); + public AlternativeParser TermExpression = new(){Name = "TermExpression"}; + public AlternativeParser PostFixExpression = new(){Name = "PostFixExpression"}; + public AlternativeParser UnaryExpression = new(){Name = "UnaryExpression"}; + public AlternativeParser CastExpression = new(){Name = "CastExpression"}; + public AlternativeParser MulExpression = new(){Name = "MulExpression"}; + public AlternativeParser SumExpression = new(){Name = "SumExpression"}; + public AlternativeParser ShiftExpression = new(){Name = "ShiftExpression"}; + + public AlternativeParser ConditionalExpression = new() { Name = "ConditionalExpression" }; + public AlternativeParser LogicalOrExpression = new(){Name = "LogicalOrExpression"}; + public AlternativeParser LogicalAndExpression = new(){Name = "LogicalAndExpression"}; + public AlternativeParser OrExpression = new(){Name = "OrExpression"}; + public AlternativeParser XorExpression = new(){Name = "XorExpression"}; + public AlternativeParser AndExpression = new(){Name = "AndExpression"}; + public AlternativeParser TestExpression = new(){Name = "TestExpression"}; + + public AlternativeParser IncrementExpression = new() { Name = "IncrementExpression" }; + public AlternativeParser ParenExpression = new(){Name = "ParenExpression"}; + public AlternativeParser EqualsExpression = new(){Name = "EqualsExpression"}; + public SequenceParser MethodCall = new(){Name = "MethodCall"}; + public AlternativeParser PrimaryExpression = new(){Name = "PrimaryExpression"}; public SDSLGrammar UsingPrimaryExpression() { diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index a0899be770..7c1a2c1fb1 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -19,20 +19,17 @@ public void CreateShader() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - var shaderGenericValue = new AlternativeParser(); - shaderGenericValue.Add( - Literal("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), + var shaderGenericValue = new AlternativeParser( + Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), ValueTypes - ); + ){ Name = "ShaderGeneric" }; - var shaderGenerics = new SequenceParser(); - shaderGenerics.Add( + var shaderGenerics = new SequenceParser( "<", shaderGenericValue.Repeat(1).SeparatedBy(ws & Comma & ws), ">" - ); - shaderGenerics.Separator = ws; + ){ Name = "ShaderGenerics", Separator = ws }; var inheritGenericsValues = new AlternativeParser( ValueTypes, @@ -40,13 +37,11 @@ public void CreateShader() Literals ); - var inheritGenerics = new SequenceParser(); - inheritGenerics.Add( + var inheritGenerics = new SequenceParser( "<", inheritGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), ">" - ); - inheritGenerics.Separator = ws; + ){ Separator = ws, Name = "InheritanceGenerics"}; var shaderContentTypes = new AlternativeParser(); shaderContentTypes.Add( @@ -57,13 +52,11 @@ public void CreateShader() // | Attribute ); - var shaderBody = new SequenceParser(); - shaderBody.Add( + var shaderBody = new SequenceParser( LeftBrace, shaderContentTypes.Repeat(0).SeparatedBy(ws), RightBrace - ); - shaderBody.Separator = ws; + ){Separator = ws}; var inheritances = Colon @@ -80,7 +73,7 @@ public void CreateShader() shaderGenerics.Optional(), inheritances.Optional(), shaderBody.Named("Body"), - ";", + Semi, ws ); ShaderExpression.Separator = ws; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs index 26a869d6ea..00258c2efb 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -144,8 +144,8 @@ public partial class SDSLGrammar : Grammar private LiteralTerminal False = new(); private AlternativeParser PreprocessorDirectiveName = new(); - private LiteralTerminal Stream = new(); - private LiteralTerminal Stage = new(); + private LiteralTerminal Stream = new(){Name = "Stream"}; + private LiteralTerminal Stage = new(){Name = "Stage"}; public void CreateTokens() From 12c0978d98f5560c999fc9823f611116a80ecbec Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 12 May 2022 00:34:29 +0200 Subject: [PATCH 0059/1182] Correction directives --- src/SDSLParserExample/Program.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Directives.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index b232785adf..39ff36fc76 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -9,7 +9,7 @@ var parser = new SDSLParser(); //parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); var s = new Stopwatch(); -var match2 = parser.Parse(shaderf); +var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); var match = parser.Parse(shaderf); s.Stop(); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs index 998cd4805d..92d5604010 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs @@ -35,12 +35,12 @@ public void CreateDirectives() var hashElif = Literal("elif").Named("HashElif"); var hashDefine = Literal("define").Named("HashElif"); - IfDirective = hashIf.Then(DirectiveExpr).SeparatedBy(ls1).WithName("DirectiveDefine"); + IfDirective = hashIf.Then(DirectiveExpression).SeparatedBy(ls1).WithName("DirectiveDefine"); ElseDirective = hashElse.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveElse"); EndIfDirective = hashEndIf.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveEnd"); IfDefDirective = (hashIfDef - (hashIfNDef | hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfDef"); IfNDefDirective = (hashIfNDef - (hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfNDef"); - DefineDirective = hashDefine.Then(Identifier).Then(DirectiveExpr).SeparatedBy(ls1).WithName("DirectiveDefine"); + DefineDirective = hashDefine.Then(Identifier).Then(DirectiveExpression).SeparatedBy(ls1).WithName("DirectiveDefine"); } } \ No newline at end of file From 644dea7f7b6833c0bb3275041ea261e4f1b736c8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 14:28:06 +0200 Subject: [PATCH 0060/1182] Added composition and method call chain --- src/SDSLParserExample/Program.cs | 4 +- src/SDSLParserExample/SDSL/shader2.sdsl | 45 ++++--- .../SDSLGrammar/SDSLGrammar.EntryPoints.cs | 112 ------------------ .../SDSLGrammar/SDSLGrammar.Expression.cs | 11 +- .../SDSLGrammar.MethodDeclaration.cs | 48 +++++--- .../SDSLGrammar/SDSLGrammar.Shader.cs | 23 +++- .../SDSLGrammar/SDSLGrammar.Statements.cs | 42 +++---- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 +- .../SDSLGrammar/SDSLGrammar.cs | 1 - src/Stride.Shader.Parsing/SDSLParser.cs | 8 +- 10 files changed, 110 insertions(+), 186 deletions(-) delete mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 39ff36fc76..876f1244b0 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -7,7 +7,7 @@ var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var parser = new SDSLParser(); -//parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); +//parser.Grammar.Using(parser.Grammar.ShaderMethodCall.Then(";")); var s = new Stopwatch(); var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); @@ -15,7 +15,7 @@ s.Stop(); -Console.WriteLine(match.ErrorMessage[..Math.Min(300, match.ErrorMessage.Length)]); +Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.Write(""); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index bfeb5aeb4e..9d9a674db5 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,19 +1,36 @@ -shader BasicMixin : ParentShader, ParentShader2, ParentShader3<5,3> { - struct MyStruct { - float a; - }; +// Let's add a generic for the index of refraction so it can be modified in the editor. + // A lot of these mixins actually give important data for the computation of the refraction! +shader RefractiveMaterial : ShaderBaseStream, ComputeColor, NormalStream, Texturing, PositionStream4, Transformation, Camera +{ + // The shader needs to have access to the background texture and maybe a little tint + compose ComputeColor BackgroundTexture; + compose ComputeColor DiffuseTexture; - float b; - stage float4 a = 3*2+5; - stage stream float4 color : SV_COLOR; - stage stream float4 color2 = float4(1,float2(5,6),3+5*7,4*2) : SV_COLOR; + override float4 Compute() + { + float4 normals = float4(streams.normalWS,0); + // This value gives us the position on the screen in pixel size we will later divide it by the screen size to get values between 0 and 1 + float2 pos = streams.ShadingPosition; + + // Eye (from the Camera mixin) gives us the camera's view direction + // This variable will give us a sort of direction to where we will bend the UVs + float4 refracted = refract(Eye,normals, IOR); + + // Here we add the screen position to the screen space projection of the refraction direction + float2 bend = pos.xy + mul(refracted, WorldViewProjection).xy; + // We compute the diffuse texture (before bending the UVs) just so we can add a little color to our material + float4 diffuse = DiffuseTexture.Compute(); + + // We bend the UVs + streams.TexCoord = float2( + bend.x/ViewSize.x, + bend.y/ViewSize.y + ); - abstract void foo(); - - void MyFunctions(float a, Input b) - { - - } + // And finally multiply the diffuse color with the background color to get our result + // I added a scalar because the actual result gives us a darker image. + return 6*BackgroundTexture.Compute() * diffuse ; + } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs deleted file mode 100644 index 2bfa791351..0000000000 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.EntryPoints.cs +++ /dev/null @@ -1,112 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace Stride.Shader.Parsing; -public partial class SDSLGrammar : Grammar -{ - public AlternativeParser VSMain = new(); - public AlternativeParser GSMain = new(); - public AlternativeParser PSMain = new(); - public AlternativeParser CSMain = new(); - public AlternativeParser HSMain = new(); - public AlternativeParser HSConstantsMain = new(); - public AlternativeParser DSMain = new(); - public AlternativeParser Entries = new(); - - - - public SDSLGrammar UsingEntry() - { - Inner = Entries; - return this; - } - public void CreateEntryPoints() - { - var ws = WhiteSpace.Repeat(0); - var ws1 = WhiteSpace.Repeat(1); - - var vs = Literal("VSMain"); - var ps = Literal("PSMain"); - var gs = Literal("GSMain"); - var cs = Literal("CSMain"); - var ds = Literal("DSMain"); - var hs = Literal("HSMain"); - var hsc = Literal("HSConstantsMain"); - var abstractM = Literal("abstract"); - - - VSMain.Add( - abstractM.Optional().Then(Void).Then(vs).SeparatedBy(ws1) - .Then(LeftParen).Then(RightParen) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - PSMain.Add( - abstractM.Optional().Then(Void).Then(ps).SeparatedBy(ws1) - .Then(LeftParen).Then(RightParen) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - GSMain.Add( - Attribute.Repeat(0).SeparatedBy(ws) - .Then(abstractM.Optional()).Then(Void).Then(gs).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - CSMain.Add( - Attribute.Repeat(0).SeparatedBy(ws) - .Then(abstractM.Optional()).Then(Void).Then(cs).SeparatedBy(ws1) - .Then(LeftParen).Then(RightParen) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - HSMain.Add( - Attribute.Repeat(0).SeparatedBy(ws) - .Then(abstractM.Optional()).Then(Void).Then(hs).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - HSConstantsMain.Add( - Attribute.Repeat(0).SeparatedBy(ws) - .Then(abstractM.Optional()).Then(Void).Then(hsc).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - DSMain.Add( - Attribute.Repeat(0).SeparatedBy(ws) - .Then(abstractM.Optional()).Then(Void).Then(ds).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace) - .SeparatedBy(ws) - ); - - Entries.Add( - VSMain - | PSMain - ); - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index a083af54a7..2f3fd417c0 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -72,13 +72,14 @@ public void CreateExpressions() arrayAccess.Add( Identifier, ws, - (LeftBracket & ws & PrimaryExpression & ws & RightBracket).Repeat(1).SeparatedBy(ws) + (LeftBracket & PrimaryExpression & RightBracket) + .SeparatedBy(ws) + .Repeat(1) + .SeparatedBy(ws) ); chain.Add( - arrayAccess.Named("ArrayAccessor") | Identifier, - ws, - (Dot & ws & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) - ); + (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(ws & Dot & ws) + ); postfixInc.Add( chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, ws, diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 7a994f81c6..993e6e505a 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -5,10 +5,10 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public SequenceParser ParameterList = new(); - public SequenceParser ValueOrGeneric = new(); + public SequenceParser ParameterList = new() {Name = "ParameterList"}; + public SequenceParser ValueOrGeneric = new() {Name = "ValueOrGeneric"}; - public AlternativeParser MethodDeclaration = new(); + public AlternativeParser MethodDeclaration = new() { Name = "MethodDeclaration" }; public SDSLGrammar UsingMethodDeclare() @@ -21,14 +21,19 @@ public void CreateMethodDeclaration() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - var genericsList = new SequenceParser(); + var genericsList = new SequenceParser { Name = "ShaderGenerics", Separator = ws }; + + var parameterGenericsValues = new AlternativeParser( + ValueTypes, + Identifier.Then(genericsList.Optional()).SeparatedBy(ws) + ) + { Name = "ParameterGenericValue" }; + genericsList.Add( "<", - (Identifier & genericsList.Optional()) - .Repeat(0).SeparatedBy(ws & Comma & ws), + parameterGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), ">" ); - genericsList.Separator = ws; ValueOrGeneric.Add( ValueTypes | Identifier, @@ -39,18 +44,26 @@ public void CreateMethodDeclaration() LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(ws) | Colon.Then(Identifier).SeparatedBy(ws); - var parameter = - StorageFlag.Optional() - .Then(ValueOrGeneric) - .Then(Identifier.Then()) - .SeparatedBy(ws1) - .Then(declarePost.Optional()) + var arraySpecifier = + (LeftBracket & Literals & RightBracket) .SeparatedBy(ws); - - + + var parameter = new SequenceParser( + ValueOrGeneric, + ws1, + Identifier, + arraySpecifier.Optional(), + (Equal & PrimaryExpression).SeparatedBy(ws).Optional() + ); + var parameterWithStorage = new AlternativeParser( + StorageFlag & ws1 & parameter, + parameter + ); + + ParameterList.Add( LeftParen, - parameter.Repeat(0).SeparatedBy(ws & Comma & ws), + parameterWithStorage.Repeat(0).SeparatedBy(ws & Comma & ws), RightParen ); ParameterList.Separator = ws; @@ -60,7 +73,8 @@ public void CreateMethodDeclaration() Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod"), // Override or normal method - Literal("override").Optional() + Attribute.Repeat(0).SeparatedBy(ws) + .Then(Literal("override").Optional()) .Then(Literal("stage").Optional()) .Then(Identifier).Then(Identifier).SeparatedBy(ws1) .Then(ParameterList) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 7c1a2c1fb1..3244acf101 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -43,13 +43,23 @@ public void CreateShader() ">" ){ Separator = ws, Name = "InheritanceGenerics"}; + var compositionDeclaration = new SequenceParser( + Literal("compose"), + ws1, + Identifier.Named("MixinName"), + ws1, + Identifier.Named("Name"), + ws, + Semi + ){ Name = "CompositionDeclaration"}; + + var shaderContentTypes = new AlternativeParser(); shaderContentTypes.Add( StructDefinition, + compositionDeclaration, MethodDeclaration, ShaderValueDeclaration - - // | Attribute ); var shaderBody = new SequenceParser( @@ -65,11 +75,14 @@ public void CreateShader() .Repeat(1).SeparatedBy(ws & Comma & ws) ) .SeparatedBy(ws); - - + + var shaderToken = Literal("shader").Named("ShaderToken"); + + + ShaderExpression.Add( ws, - "shader" & ws1 & Identifier.Named("ShaderName"), + shaderToken & ws1 & Identifier.Named("ShaderName"), shaderGenerics.Optional(), inheritances.Optional(), shaderBody.Named("Body"), diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index f8690939b2..4550f2c34e 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -5,12 +5,12 @@ namespace Stride.Shader.Parsing; public partial class SDSLGrammar : Grammar { - public SequenceParser Attribute = new(); - public AlternativeParser Statement = new(); - public SequenceParser ControlFlow = new(); - public SequenceParser ConstantBuffer = new(); - public AlternativeParser ShaderMethodCall = new(); - public SequenceParser Block = new(); + public SequenceParser Attribute = new() { Name = "Attribute" }; + public AlternativeParser Statement = new() { Name = "Statement"}; + public SequenceParser ControlFlow = new() { Name = "ControlFlow"}; + public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer"}; + public SequenceParser ShaderMethodCall = new() { Name = "ShaderMethodCall" }; + public SequenceParser Block = new() { Name = "Block" }; public SDSLGrammar UsingStatements() @@ -24,19 +24,12 @@ public void CreateStatements() var ws1 = WhiteSpace.Repeat(1); ShaderMethodCall.Add( - ( - Identifier - .Then( - ( - Dot.NotFollowedBy(MethodCall).Then(Identifier) - | Dot.Then(MethodCall) - ) - .Repeat(0) - ) - .Then(";") - ) - .SeparatedBy(ws) + Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("AccessorChain"), + LeftParen, + (Identifier | PrimaryExpression).Repeat(0).SeparatedBy(ws & Comma & ws).Named("Parameters"), + RightParen ); + ShaderMethodCall.Separator = ws; var returnStatement = Return.Then(PrimaryExpression).SeparatedBy(ws1) @@ -75,10 +68,10 @@ public void CreateStatements() Statement.Add( - Block.Named("BlockExpression"), + Block, returnStatement.Named("Return"), - assignChain, ShaderMethodCall, + assignChain.Named("AssignChain"), declareAssign.Named("DeclareAssign"), assignVar.Named("Assign"), PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") @@ -86,21 +79,20 @@ public void CreateStatements() Block.Add( LeftBrace, - ws, Statement.Repeat(0).SeparatedBy(ws), - ws, RightBrace ); - var flowStatement = Statement; + Block.Separator = ws; + var ifStatement = - If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(flowStatement).SeparatedBy(ws); + If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(Statement).SeparatedBy(ws); var elseIfStatement = Else.Then(ifStatement).SeparatedBy(ws1); var elseStatement = - Else.Then(flowStatement).SeparatedBy(ws1); + Else.Then(Statement).SeparatedBy(ws1); ControlFlow.Add( Attribute.Repeat(0).Named("Attributes"), diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 0c111023e1..c5349b73c4 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -198,7 +198,7 @@ public void CreateTokenGroups() Nointerpolation, Noperspective, Sample, - In, + In.NotFollowedBy(WhiteSpace.Repeat(0) & Out), Out, Inout, Point, diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index 9166297d91..7ed6e8bf87 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -30,7 +30,6 @@ public void CreateAll() CreateMethodDeclaration(); CreateDeclarators(); CreateStatements(); - CreateEntryPoints(); CreateShader(); } } diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index fae0d6ad0f..e0d5021291 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -36,10 +36,10 @@ public GrammarMatch Parse(string shader) } } var matches = Grammar.Match(actualCode.ToString()); - if (matches.Errors.Any()) - { - throw new Exception("Parsing Exception : " + matches.ErrorMessage); - } + //if (matches.Errors.Any()) + //{ + // throw new Exception("Parsing Exception : " + matches.ErrorMessage); + //} return matches; } From 7dac5c15ea6fa3bfa54597e10c2c41f02a932a41 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 16:14:27 +0200 Subject: [PATCH 0061/1182] Update expression parsing --- src/SDSLParserExample/Program.cs | 2 +- src/SDSLParserExample/SDSL/shader2.sdsl | 143 ++++++++++++++---- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 1 + .../SDSLGrammar/SDSLGrammar.Expression.cs | 66 ++++---- .../SDSLGrammar.MethodDeclaration.cs | 48 ++++-- .../SDSLGrammar/SDSLGrammar.Shader.cs | 15 +- ...ar.Statements.ConditionalFlowStatements.cs | 33 ++++ ...SLGrammar.Statements.LoopFlowStatements.cs | 50 ++++++ .../SDSLGrammar/SDSLGrammar.Statements.cs | 68 +++------ .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 + .../SDSLGrammar/SDSLGrammar.Tokens.cs | 2 + .../SDSLGrammar/SDSLGrammar.cs | 2 + src/Stride.Shader.Parsing/SDSLParser.cs | 1 + 13 files changed, 317 insertions(+), 116 deletions(-) create mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs create mode 100644 src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 876f1244b0..478f15245a 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -7,7 +7,7 @@ var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var parser = new SDSLParser(); -//parser.Grammar.Using(parser.Grammar.ShaderMethodCall.Then(";")); +//parser.Grammar.Using(parser.Grammar.PrimaryExpression.Then(";")); var s = new Stopwatch(); var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 9d9a674db5..79fac4471d 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,36 +1,117 @@ -// Let's add a generic for the index of refraction so it can be modified in the editor. - // A lot of these mixins actually give important data for the computation of the refraction! -shader RefractiveMaterial : ShaderBaseStream, ComputeColor, NormalStream, Texturing, PositionStream4, Transformation, Camera +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various math functions. +/// +shader Math { - // The shader needs to have access to the background texture and maybe a little tint - compose ComputeColor BackgroundTexture; - compose ComputeColor DiffuseTexture; + // ------------------------------------- + // constant value + // ------------------------------------- + static const float PI = 3.14159265358979323846; - override float4 Compute() + // ------------------------------------- + // methods + // ------------------------------------- + // Tests intersection between a ray and a plane + static bool RayIntersectsPlane(float3 rayPosition, + float3 rayDirection, + float3 planeNormal, + float planeDirection, out float3 position) { - float4 normals = float4(streams.normalWS,0); - // This value gives us the position on the screen in pixel size we will later divide it by the screen size to get values between 0 and 1 - float2 pos = streams.ShadingPosition; - - // Eye (from the Camera mixin) gives us the camera's view direction - // This variable will give us a sort of direction to where we will bend the UVs - float4 refracted = refract(Eye,normals, IOR); - - // Here we add the screen position to the screen space projection of the refraction direction - float2 bend = pos.xy + mul(refracted, WorldViewProjection).xy; - - // We compute the diffuse texture (before bending the UVs) just so we can add a little color to our material - float4 diffuse = DiffuseTexture.Compute(); - - // We bend the UVs - streams.TexCoord = float2( - bend.x/ViewSize.x, - bend.y/ViewSize.y - ); - - - // And finally multiply the diffuse color with the background color to get our result - // I added a scalar because the actual result gives us a darker image. - return 6*BackgroundTexture.Compute() * diffuse ; + float distance = (planeDirection - dot(planeNormal, rayPosition)) / dot(rayDirection, planeNormal); + position = rayPosition + rayDirection * distance; + return distance >= 0; + } + + // Tests intersection between a ray and a sphere + static bool RayIntersectsSphere(float3 rayPosition, float3 rayDirection, float3 spherePosition, float sphereRadius, out float distance) + { + //Source: Real-Time Collision Detection by Christer Ericson + //Reference: Page 177 + + float3 m = rayPosition - spherePosition; + + float b = dot(m, rayDirection); + float c = dot(m, m) - (sphereRadius * sphereRadius); + + if (c > 0 && b > 0) + { + distance = 0; + return false; + } + + float discriminant = b * b - c; + + if (discriminant < 0) + { + distance = 0; + return false; + } + + distance = -b - sqrt(discriminant); + + if (distance < 0) + distance = 0; + + return true; + } + + // Computes the luminance of a color + float Luminance(float3 color) { + return dot(color, float3(0.2126, 0.7152, 0.0722)); + } + + // ------------------------------------- + // Hermine interpolation + // ------------------------------------- + float Hermine(float x) { + return x * x * (3.0 - 2.0 * x); + } + float2 Hermine(float2 x) { + return x * x * (3.0 - 2.0 * x); + } + float3 Hermine(float3 x) { + return x * x * (3.0 - 2.0 * x); + } + float4 Hermine(float4 x) { + return x * x * (3.0 - 2.0 * x); + } + + // ------------------------------------- + // Quintic interpolation + // ------------------------------------- + float Quintic1(float x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float2 Quintic(float2 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float3 Quintic(float3 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float4 Quintic(float4 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + + // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) + float FastRandom(uint n) + { + n = (n << 13) ^ n; + return float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0; + } + + // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) + float FastRandom(float2 x) + { + return FastRandom(uint(x.x * 37 + x.y * 6007)); + } + + // Transforms "vec" by "mat" and does a W-divide. + float4 Project(float4 vec, float4x4 mat) + { + float4 vecProjected = mul(vec, mat); + vecProjected.xyz /= vecProjected.w; + return vecProjected; } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs index 8d9779fc68..0c1de8509a 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -66,6 +66,7 @@ public void CreateDeclarators() var valueDeclaration = new SequenceParser(); valueDeclaration.Add( staging.Then(ws1).Optional(), + StorageFlag.Then(ws1).Optional(), ValueTypes | Identifier, ws1, Identifier diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 2f3fd417c0..d0984385e2 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -40,6 +40,14 @@ public Parser Parenthesis(Parser p, bool notFollowedByUnary = true) else return LeftParen.Then(p).Then(RightParen).SeparatedBy(WhiteSpace.Repeat(0)); } + public Parser Parenthesis(Parser p, Parser f, bool notFollowedByUnary = true) + { + var ws = WhiteSpace.Repeat(0); + if (notFollowedByUnary) + return LeftParen.Then(p).Then(RightParen).SeparatedBy(WhiteSpace.Repeat(0)).NotFollowedBy(UnaryExpression).FollowedBy(ws & f); + else + return LeftParen.Then(p).Then(RightParen).SeparatedBy(WhiteSpace.Repeat(0)).FollowedBy(ws & f); + } public void CreateExpressions() { @@ -59,9 +67,9 @@ public void CreateExpressions() TermExpression.Add( Literals, - Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), - MethodCall - // ,ParenExpression + ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + MethodCall, + Parenthesis(PrimaryExpression) ); var arrayAccess = new SequenceParser(); @@ -122,48 +130,48 @@ public void CreateExpressions() ); - var mulOp = Star | Div | Mod; + var mulOp = Star | Div | Mod; MulExpression.Add( - CastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) + (Parenthesis(PrimaryExpression) | CastExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) ); var sumOp = Plus | Minus; - SumExpression.Add( - (Parenthesis(MulExpression) | MulExpression) - .Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) + SumExpression.Add( + MulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) ); var shiftOp = LeftShift | RightShift; ShiftExpression.Add( - (Parenthesis(SumExpression) | SumExpression) - .Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) + SumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) ); AndExpression.Add( - (Parenthesis(ShiftExpression) | ShiftExpression) - .Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) + ShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) ); XorExpression.Add( - (Parenthesis(AndExpression) | AndExpression) - .Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) + AndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) ); OrExpression.Add( - (Parenthesis(XorExpression) | XorExpression) - .Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) + XorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) ); - var testOp = Less | LessEqual | Greater | GreaterEqual; + var testOp = LessEqual | Less | GreaterEqual | Greater ; TestExpression.Add( - (Parenthesis(OrExpression) | OrExpression) - .Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) + OrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) ); var eqOp = @@ -171,22 +179,22 @@ public void CreateExpressions() | Literal("!="); EqualsExpression.Add( - (Parenthesis(TestExpression) | TestExpression) - .Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) + TestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) ); LogicalAndExpression.Add( - (Parenthesis(EqualsExpression) | EqualsExpression) - .Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) + EqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) ); LogicalOrExpression.Add( - (Parenthesis(LogicalAndExpression) | LogicalAndExpression) - .Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) + LogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws), + Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) ); ConditionalExpression.Add( LogicalOrExpression.NotFollowedBy(ws & "?"), - (Parenthesis(LogicalOrExpression) | LogicalOrExpression) + (Parenthesis(LogicalOrExpression).NotFollowedBy(ws & OrOr) | LogicalOrExpression) .Then("?") .Then(CastExpression | ParenExpression | LogicalOrExpression) .Then(":") @@ -207,9 +215,13 @@ public void CreateExpressions() Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") ); + var arrayDeclaration = + (LeftBrace & PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & RightBrace) + .SeparatedBy(ws); PrimaryExpression.Add( - MethodCall, + arrayDeclaration, + //MethodCall, ConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 993e6e505a..b53e70ced7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -68,19 +68,43 @@ public void CreateMethodDeclaration() ); ParameterList.Separator = ws; + var abstractMethod = new SequenceParser( + Literal("abstract"), + ws1, + ~Literal("stage"), + ws1, + Identifier, + ws1, + Identifier, + ws, + ParameterList, + ws, + Semi + ) + { Name = "AbstractMethod"}; + + var method = new SequenceParser( + Attribute.Repeat(0).SeparatedBy(ws), + ~(Literal("stage") & ws1), + ~(Literal("override") & ws1), + ~(Literal("static") & ws1), + Identifier, + ws1, + Identifier, + ws, + ParameterList, + ws, + LeftBrace, + ws, + Statement.Repeat(0).SeparatedBy(ws), + ws, + RightBrace + ) + { Name = "Method"}; + MethodDeclaration.Add( - // Abstract method - Literal("abstract").Then(Literal("stage").Optional()).Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(ParameterList).Then(Semi).SeparatedBy(ws).Named("AbstractMethod"), - // Override or normal method - Attribute.Repeat(0).SeparatedBy(ws) - .Then(Literal("override").Optional()) - .Then(Literal("stage").Optional()) - .Then(Identifier).Then(Identifier).SeparatedBy(ws1) - .Then(ParameterList) - .Then(LeftBrace) - .Then(Statement.Repeat(0).SeparatedBy(ws)) - .Then(RightBrace).SeparatedBy(ws).Named("MethodDeclaration") + abstractMethod, + method ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 3244acf101..2965eb2ef4 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -7,7 +7,8 @@ public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); public SequenceParser ShaderExpression = new(); - + public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer" }; + public SDSLGrammar UsingShader() { @@ -19,6 +20,18 @@ public void CreateShader() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); + + ConstantBuffer.Add( + "cbuffer", + ws1, + Identifier, + ws, + LeftBrace, + ws, + RightBrace + ); + + var shaderGenericValue = new AlternativeParser( Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs new file mode 100644 index 0000000000..77c5735619 --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -0,0 +1,33 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class SDSLGrammar : Grammar +{ + public SequenceParser ControlFlow = new() { Name = "ControlFlow" }; + public void CreateConditionalFlowStatements() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + + var ifStatement = + If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(Statement).SeparatedBy(ws); + + var elseIfStatement = + Else.Then(ifStatement).SeparatedBy(ws1); + + var elseStatement = + Else.Then(Statement).SeparatedBy(ws1); + + ControlFlow.Add( + Attribute.Repeat(0).Named("Attributes"), + ws, + ifStatement.Named("IfStatement") + | elseStatement.Named("ElseStatement") + | elseIfStatement.Named("ElseIfStatement") + | ForLoop + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs new file mode 100644 index 0000000000..c506092463 --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -0,0 +1,50 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class SDSLGrammar : Grammar +{ + public AlternativeParser WhileLoop = new() { Name = "ForLoop"}; + public AlternativeParser ForEachLoop = new() { Name = "ForLoop"}; + public SequenceParser ForLoop = new() { Name = "ForLoop"}; + + public void CreateLoopFlowStatements() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + var valueDeclare = new SequenceParser( + ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1), + "=", + PrimaryExpression + ) + { Separator = ws }; + var valueAssign = new SequenceParser( + Identifier, + AssignOperators, + PrimaryExpression + ) + { Separator = ws }; + + ForLoop.Add( + For, + LeftParen, + valueDeclare, + Semi, + PrimaryExpression, + Semi, + valueAssign | PrimaryExpression, + RightParen, + Semi + | ( + LeftBrace & + Statement.Repeat(0).SeparatedBy(ws) & + RightBrace + ).SeparatedBy(ws) + + ); + ForLoop.Separator = ws; + + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs index 4550f2c34e..8dde34073f 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs @@ -7,9 +7,6 @@ public partial class SDSLGrammar : Grammar { public SequenceParser Attribute = new() { Name = "Attribute" }; public AlternativeParser Statement = new() { Name = "Statement"}; - public SequenceParser ControlFlow = new() { Name = "ControlFlow"}; - public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer"}; - public SequenceParser ShaderMethodCall = new() { Name = "ShaderMethodCall" }; public SequenceParser Block = new() { Name = "Block" }; @@ -23,30 +20,38 @@ public void CreateStatements() var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); - ShaderMethodCall.Add( - Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("AccessorChain"), - LeftParen, - (Identifier | PrimaryExpression).Repeat(0).SeparatedBy(ws & Comma & ws).Named("Parameters"), - RightParen + + var returnStatement = new SequenceParser( + Return, + ws1, + PrimaryExpression, + ws, + Semi ); - ShaderMethodCall.Separator = ws; - var returnStatement = - Return.Then(PrimaryExpression).SeparatedBy(ws1) - .Then(Semi).SeparatedBy(ws); + var attrParams = + ( + LeftParen & + PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & + RightParen + ).SeparatedBy(ws); Attribute.Add( LeftBracket, Identifier, - LeftParen, - (Identifier | Literals).Repeat(0).SeparatedBy(ws & Comma & ws), - RightParen, + ~attrParams, RightBracket ); Attribute.Separator = ws; + var arraySpecifier = + (LeftBracket & PrimaryExpression & RightBracket).SeparatedBy(ws); + + + var assignVar = - Identifier.Named("Variable").NotFollowedBy(Identifier) + Identifier.Named("Variable") + .Then(arraySpecifier.Optional()) .Then(AssignOperators.Named("AssignOp")) .Then(PrimaryExpression.Named("Value")) .Then(Semi) @@ -69,8 +74,9 @@ public void CreateStatements() Statement.Add( Block, + ControlFlow, + ForLoop, returnStatement.Named("Return"), - ShaderMethodCall, assignChain.Named("AssignChain"), declareAssign.Named("DeclareAssign"), assignVar.Named("Assign"), @@ -85,32 +91,6 @@ public void CreateStatements() Block.Separator = ws; - var ifStatement = - If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(Statement).SeparatedBy(ws); - - var elseIfStatement = - Else.Then(ifStatement).SeparatedBy(ws1); - - var elseStatement = - Else.Then(Statement).SeparatedBy(ws1); - - ControlFlow.Add( - Attribute.Repeat(0).Named("Attributes"), - ws, - ifStatement.Named("IfStatement") - | elseStatement.Named("ElseStatement") - | elseIfStatement.Named("ElseIfStatement") - ); - - - ConstantBuffer.Add( - "cbuffer", - ws1, - Identifier, - ws, - LeftBrace, - ws, - RightBrace - ); + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs index c5349b73c4..e223c7eea7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -166,6 +166,7 @@ public void CreateTokenGroups() Shared, Stage, Stream, + StaticConst, Static, Struct, StructuredBuffer, @@ -190,6 +191,7 @@ public void CreateTokenGroups() Precise, Shared, Groupshared, + StaticConst, Static, Uniform, Volatile, diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs index 00258c2efb..e344880b2a 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -80,6 +80,7 @@ public partial class SDSLGrammar : Grammar private LiteralTerminal SamplerComparisonState = new(); private LiteralTerminal SamplerState = new(); private LiteralTerminal Shared = new(); + private LiteralTerminal StaticConst = new(); private LiteralTerminal Static = new(); private LiteralTerminal Struct = new(); private LiteralTerminal StructuredBuffer = new(); @@ -225,6 +226,7 @@ public void CreateTokens() SamplerState = Literal("SamplerState"); Shared = Literal("shared"); Static = Literal("static"); + StaticConst = Literal("static const"); Struct = Literal("struct"); StructuredBuffer = Literal("StructuredBuffer"); Switch = Literal("switch"); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs index 7ed6e8bf87..9fe074f7c0 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs @@ -29,6 +29,8 @@ public void CreateAll() CreateExpressions(); CreateMethodDeclaration(); CreateDeclarators(); + CreateConditionalFlowStatements(); + CreateLoopFlowStatements(); CreateStatements(); CreateShader(); } diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index e0d5021291..abc65da6f6 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -34,6 +34,7 @@ public GrammarMatch Parse(string shader) { actualCode.Append(m.StringValue); } + } var matches = Grammar.Match(actualCode.ToString()); //if (matches.Errors.Any()) From 7ec1d767dd3a761a9fb44f04ca66acac12514f06 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 19:32:47 +0200 Subject: [PATCH 0062/1182] Update on declarations --- src/SDSLParserExample/Program.cs | 2 +- src/SDSLParserExample/SDSL/shader2.sdsl | 121 ++++-------------- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 9 +- .../SDSLGrammar.MethodDeclaration.cs | 19 +-- .../SDSLGrammar/SDSLGrammar.Shader.cs | 12 +- 5 files changed, 46 insertions(+), 117 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 478f15245a..f51d1aa0f1 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -7,7 +7,7 @@ var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var parser = new SDSLParser(); -//parser.Grammar.Using(parser.Grammar.PrimaryExpression.Then(";")); +//parser.Grammar.Using(parser.Grammar.ShaderValueDeclaration); var s = new Stopwatch(); var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 79fac4471d..e4d444b36f 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,117 +1,52 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. /// -/// Various math functions. +/// Various helper functions. /// -shader Math +shader Utilities { // ------------------------------------- - // constant value + // type definition // ------------------------------------- - static const float PI = 3.14159265358979323846; - - // ------------------------------------- - // methods - // ------------------------------------- - // Tests intersection between a ray and a plane - static bool RayIntersectsPlane(float3 rayPosition, - float3 rayDirection, - float3 planeNormal, - float planeDirection, out float3 position) + typedef uint Half2; + typedef uint2 Half4; + + // Converts a Half2 to a float2 + float2 Half2ToFloat2(Half2 value) { - float distance = (planeDirection - dot(planeNormal, rayPosition)) / dot(rayDirection, planeNormal); - position = rayPosition + rayDirection * distance; - return distance >= 0; + return float2(f16tof32(value), f16tof32(value >> 16)); } - // Tests intersection between a ray and a sphere - static bool RayIntersectsSphere(float3 rayPosition, float3 rayDirection, float3 spherePosition, float sphereRadius, out float distance) + // Converts a float2 to a Half2 + Half2 Float2ToHalf2(float2 value) { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 177 - - float3 m = rayPosition - spherePosition; - - float b = dot(m, rayDirection); - float c = dot(m, m) - (sphereRadius * sphereRadius); - - if (c > 0 && b > 0) - { - distance = 0; - return false; - } - - float discriminant = b * b - c; - - if (discriminant < 0) - { - distance = 0; - return false; - } - - distance = -b - sqrt(discriminant); - - if (distance < 0) - distance = 0; - - return true; + return f32tof16(value.x) | (f32tof16(value.y) << 16); } - // Computes the luminance of a color - float Luminance(float3 color) { - return dot(color, float3(0.2126, 0.7152, 0.0722)); + // Converts a Half4 to a float4 + float4 Half4ToFloat4(Half4 value) { + return float4(f16tof32(value.x), f16tof32(value.x>>16), f16tof32(value.y), f16tof32(value.y>>16)); } - // ------------------------------------- - // Hermine interpolation - // ------------------------------------- - float Hermine(float x) { - return x * x * (3.0 - 2.0 * x); - } - float2 Hermine(float2 x) { - return x * x * (3.0 - 2.0 * x); - } - float3 Hermine(float3 x) { - return x * x * (3.0 - 2.0 * x); - } - float4 Hermine(float4 x) { - return x * x * (3.0 - 2.0 * x); - } - - // ------------------------------------- - // Quintic interpolation - // ------------------------------------- - float Quintic1(float x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float2 Quintic(float2 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float3 Quintic(float3 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float4 Quintic(float4 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + // Converts a float4 to a Half4 + Half4 Float4ToHalf4(float4 value) { + return uint2(f32tof16(value.x) | (f32tof16(value.y) << 16), f32tof16(value.z) | (f32tof16(value.w) << 16)); } - // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) - float FastRandom(uint n) + // Commpute Schlick's approximation of Fresnel + float3 FresnelSchlick(float3 specularColor, float3 eye, float3 h, float factor) { - n = (n << 13) ^ n; - return float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0; + return specularColor + (1.0f - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; } - // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) - float FastRandom(float2 x) + // Commpute Schlick's approximation of Fresnel + float3 FresnelSchlickWithGloss(float3 specularColor, float3 eye, float3 h, float factor, float gloss) { - return FastRandom(uint(x.x * 37 + x.y * 6007)); + return specularColor + (max(specularColor, gloss) - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; } - // Transforms "vec" by "mat" and does a W-divide. - float4 Project(float4 vec, float4x4 mat) - { - float4 vecProjected = mul(vec, mat); - vecProjected.xyz /= vecProjected.w; - return vecProjected; + // flip the texture coordinate if on an opengl device. + static float2 ConvertTexCoord(float2 texcoord) { + } -}; \ No newline at end of file +}; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs index 0c1de8509a..13114f5034 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -65,15 +65,14 @@ public void CreateDeclarators() var valueDeclaration = new SequenceParser(); valueDeclaration.Add( - staging.Then(ws1).Optional(), - StorageFlag.Then(ws1).Optional(), + ~(staging & ws1), + ~(StorageFlag & ws1), ValueTypes | Identifier, ws1, Identifier ); - var assignOrSupplement = new AlternativeParser(); - assignOrSupplement.Add( + var assignOrSupplement = new AlternativeParser( supplement, (AssignOperators & PrimaryExpression).SeparatedBy(ws).NotFollowedBy(ws & supplement), (AssignOperators & PrimaryExpression & supplement).SeparatedBy(ws) @@ -81,7 +80,7 @@ public void CreateDeclarators() ShaderValueDeclaration.Add( valueDeclaration, - assignOrSupplement.Optional(), + ~assignOrSupplement, Semi ); ShaderValueDeclaration.Separator = ws; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index b53e70ced7..63f538be5d 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -85,26 +85,19 @@ public void CreateMethodDeclaration() var method = new SequenceParser( Attribute.Repeat(0).SeparatedBy(ws), - ~(Literal("stage") & ws1), - ~(Literal("override") & ws1), - ~(Literal("static") & ws1), - Identifier, - ws1, - Identifier, - ws, + ~(Literal("stage") & WhiteSpace), + ~((Literal("override") | Literal("static")) & ws1), + Identifier & ws1 & Identifier, ParameterList, - ws, LeftBrace, - ws, - Statement.Repeat(0).SeparatedBy(ws), - ws, + Statement.Repeat(0).SeparatedBy(ws).Until("}"), RightBrace ) - { Name = "Method"}; + { Name = "Method", Separator = ws}; MethodDeclaration.Add( abstractMethod, - method + method ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index 2965eb2ef4..cbcc9ef437 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -34,6 +34,7 @@ public void CreateShader() var shaderGenericValue = new AlternativeParser( Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), + Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(ws1).Named("Semantic"), ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), ValueTypes ){ Name = "ShaderGeneric" }; @@ -67,19 +68,20 @@ public void CreateShader() ){ Name = "CompositionDeclaration"}; - var shaderContentTypes = new AlternativeParser(); - shaderContentTypes.Add( + var shaderContentTypes = new AlternativeParser( StructDefinition, compositionDeclaration, MethodDeclaration, ShaderValueDeclaration + ); var shaderBody = new SequenceParser( LeftBrace, - shaderContentTypes.Repeat(0).SeparatedBy(ws), + shaderContentTypes.Repeat(0).SeparatedBy(ws).Until(ws & "}"), RightBrace - ){Separator = ws}; + ) + {Name = "Body", Separator = ws}; var inheritances = Colon @@ -98,7 +100,7 @@ public void CreateShader() shaderToken & ws1 & Identifier.Named("ShaderName"), shaderGenerics.Optional(), inheritances.Optional(), - shaderBody.Named("Body"), + shaderBody, Semi, ws ); From cc32c42c023104ffb029fe5b86e650e013bb64f3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 19:44:09 +0200 Subject: [PATCH 0063/1182] Adding typedef --- .../SDSLGrammar/SDSLGrammar.Shader.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs index cbcc9ef437..20076c55ed 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs @@ -21,6 +21,16 @@ public void CreateShader() var ws1 = WhiteSpace.Repeat(1); + var typeDefinition = new SequenceParser( + Literal("typedef") & " ", + Identifier & " ", + ~("<" & (Identifier | PrimaryExpression).Repeat(1).SeparatedBy(ws & "," & ws).Until(">") & ">").Named("TypedefGenerics"), + Identifier, + Semi + ) + { Name = "TypeDef", Separator = ws}; + + ConstantBuffer.Add( "cbuffer", ws1, @@ -69,6 +79,7 @@ public void CreateShader() var shaderContentTypes = new AlternativeParser( + typeDefinition, StructDefinition, compositionDeclaration, MethodDeclaration, From a79f3228fcaf89bebe24f96bef4e2444f0a54202 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 19:50:48 +0200 Subject: [PATCH 0064/1182] Removed useless method call --- .../SDSLGrammar/SDSLGrammar.Expression.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index d0984385e2..617d75ba24 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -220,8 +220,7 @@ public void CreateExpressions() .SeparatedBy(ws); PrimaryExpression.Add( - arrayDeclaration, - //MethodCall, + arrayDeclaration ConditionalExpression ); } From 96453a9d61aa8c1d4542894d746b4e2f7bf7e466 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 May 2022 22:34:05 +0200 Subject: [PATCH 0065/1182] Directive parsing --- src/Stride.Shader.Parsing/DirectiveGrammar.cs | 15 ++++ .../SDSLGrammar.Directives.Expression.cs | 71 ++++++++++--------- .../SDSLGrammar/SDSLGrammar.Directives.cs | 63 +++++++++++----- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- src/Stride.Shader.Parsing/SDSLParser.cs | 1 + 5 files changed, 103 insertions(+), 49 deletions(-) create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar.cs diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/DirectiveGrammar.cs new file mode 100644 index 0000000000..d1b3bb2164 --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar.cs @@ -0,0 +1,15 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing +{ + public partial class DirectiveGrammar : SDSLGrammar + { + public DirectiveGrammar() : base() + { + Inner = Directives; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index bd2d50232d..0349bd32b7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -25,19 +25,18 @@ public partial class SDSLGrammar : Grammar public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; - - public SDSLGrammar UsingDirectiveExpression() + public SDSLGrammar DirectiveUsingDirectiveExpression() { Inner = DirectiveExpression; return this; } - public void CreateDirectiveExpressions() { var ws = SingleLineWhiteSpace.Repeat(0); var ls1 = SingleLineWhiteSpace.Repeat(1); + var incrementOp = new AlternativeParser(); incrementOp.Add( PlusPlus, @@ -50,9 +49,9 @@ public void CreateDirectiveExpressions() DirectiveTermExpression.Add( Literals, - Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), - MethodCall - // ,DirectiveParenExpression + ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + MethodCall, + Parenthesis(DirectiveExpression) ); var arrayAccess = new SequenceParser(); @@ -63,12 +62,13 @@ public void CreateDirectiveExpressions() arrayAccess.Add( Identifier, ws, - (LeftBracket & ws & DirectiveExpression & ws & RightBracket).Repeat(1).SeparatedBy(ws) + (LeftBracket & DirectiveExpression & RightBracket) + .SeparatedBy(ws) + .Repeat(1) + .SeparatedBy(ws) ); chain.Add( - arrayAccess.Named("ArrayAccessor") | Identifier, - ws, - (Dot & ws & (arrayAccess.Named("ArrayAccessor") | Identifier)).Repeat(1) + (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(ws & Dot & ws) ); postfixInc.Add( chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, @@ -114,46 +114,46 @@ public void CreateDirectiveExpressions() var mulOp = Star | Div | Mod; DirectiveMulExpression.Add( - DirectiveCastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) + (Parenthesis(DirectiveExpression) | DirectiveCastExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) ); var sumOp = Plus | Minus; DirectiveSumExpression.Add( - (Parenthesis(DirectiveMulExpression) | DirectiveMulExpression) - .Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) + DirectiveMulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) ); var shiftOp = LeftShift | RightShift; DirectiveShiftExpression.Add( - (Parenthesis(DirectiveSumExpression) | DirectiveSumExpression) - .Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) + DirectiveSumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) ); DirectiveAndExpression.Add( - (Parenthesis(DirectiveShiftExpression) | DirectiveShiftExpression) - .Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) + DirectiveShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) ); DirectiveXorExpression.Add( - (Parenthesis(DirectiveAndExpression) | DirectiveAndExpression) - .Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) + DirectiveAndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) ); DirectiveOrExpression.Add( - (Parenthesis(DirectiveXorExpression) | DirectiveXorExpression) - .Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) + DirectiveXorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) ); - var testOp = Less | LessEqual | Greater | GreaterEqual; + var testOp = LessEqual | Less | GreaterEqual | Greater; DirectiveTestExpression.Add( - (Parenthesis(DirectiveOrExpression) | DirectiveOrExpression) - .Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) + DirectiveOrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) ); var eqOp = @@ -161,22 +161,22 @@ public void CreateDirectiveExpressions() | Literal("!="); DirectiveEqualsExpression.Add( - (Parenthesis(DirectiveTestExpression) | DirectiveTestExpression) - .Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) + DirectiveTestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) ); DirectiveLogicalAndExpression.Add( - (Parenthesis(DirectiveEqualsExpression) | DirectiveEqualsExpression) - .Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) + DirectiveEqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) ); DirectiveLogicalOrExpression.Add( - (Parenthesis(DirectiveLogicalAndExpression) | DirectiveLogicalAndExpression) - .Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) + DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) ); DirectiveConditionalExpression.Add( DirectiveLogicalOrExpression.NotFollowedBy(ws & "?"), - (Parenthesis(DirectiveLogicalOrExpression) | DirectiveLogicalOrExpression) + (Parenthesis(DirectiveLogicalOrExpression).NotFollowedBy(ws & OrOr) | DirectiveLogicalOrExpression) .Then("?") .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) .Then(":") @@ -193,9 +193,16 @@ public void CreateDirectiveExpressions() var parameters = DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws); + MethodCall.Add( + Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("DirectiveMethodCallExpression") + ); + + var arrayDeclaration = + (LeftBrace & DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & RightBrace) + .SeparatedBy(ws); DirectiveExpression.Add( - MethodCall, + arrayDeclaration, DirectiveConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs index 92d5604010..0a53075d41 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs @@ -15,7 +15,10 @@ public partial class SDSLGrammar : Grammar public SequenceParser IfDefDirective = new(); public SequenceParser IfNDefDirective = new(); - public AlternativeParser Directives = new(); + public SequenceParser ConditionalDirectives = new(); + public SequenceParser DefineDirectives = new(); + + public SequenceParser Directives = new(); public SDSLGrammar UsingDirectives() { @@ -27,20 +30,48 @@ public void CreateDirectives() var ls = SingleLineWhiteSpace.Repeat(0); var ls1 = SingleLineWhiteSpace.Repeat(1); var hash = Literal("#"); - var hashIfNDef = Literal("ifndef").Named("hashifndef"); - var hashIfDef = Literal("ifdef").Named("hashifdef"); - var hashIf = Literal("if").Named("hashif"); - var hashEndIf = Literal("endif").Named("HashEndIf"); - var hashElse = Literal("else").Named("HashElse"); - var hashElif = Literal("elif").Named("HashElif"); - var hashDefine = Literal("define").Named("HashElif"); - - IfDirective = hashIf.Then(DirectiveExpression).SeparatedBy(ls1).WithName("DirectiveDefine"); - ElseDirective = hashElse.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveElse"); - EndIfDirective = hashEndIf.Then(ls).Then(LetterOrDigit.Or(Punctuation).Not()).WithName("DirectiveEnd"); - IfDefDirective = (hashIfDef - (hashIfNDef | hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfDef"); - IfNDefDirective = (hashIfNDef - (hashIf | hashEndIf)).Then(Identifier).SeparatedBy(ls1).WithName("DirectiveIfNDef"); - DefineDirective = hashDefine.Then(Identifier).Then(DirectiveExpression).SeparatedBy(ls1).WithName("DirectiveDefine"); - + var hashIfNDef = Literal("#ifndef").Named("hashifndef"); + var hashIfDef = Literal("#ifdef").Named("hashifdef"); + var hashIf = Literal("#if").Named("hashif"); + var hashEndIf = Literal("#endif").Named("HashEndIf"); + var hashElse = Literal("#else").Named("HashElse"); + var hashElif = Literal("#elif").Named("HashElif"); + var hashDefine = Literal("#define").Named("HashElif"); + + IfDirective.Add(hashIf, ls1, DirectiveExpression); + ElseDirective.Add(hashElse, ls, Eol); + EndIfDirective.Add(hashEndIf, ls, Eol); + IfDefDirective.Add(hashIfDef, ls1, Identifier, ls, Eol); + IfNDefDirective.Add(hashIfNDef, ls1, Identifier, ls, Eol); + DefineDirective.Add(hashDefine, ls1, Identifier, ls1, DirectiveExpression, ls, Eol); + + var anyChars = AnyChar.Repeat(0); + + var elseList = new AlternativeParser( + (ElifDirective & anyChars.Until(hashElif | hashElse | hashEndIf).Named("ElifCode")).Repeat(), + ElseDirective & anyChars.Until(hashEndIf).Named("ElseCode") + ); + + ConditionalDirectives.Add( + IfDirective, + anyChars.Until(hashElif | hashElse | hashEndIf).Named("IfCode"), + ~elseList, + EndIfDirective + ); + DefineDirective.Add( + IfDefDirective | IfNDefDirective, + ConditionalDirectives | DefineDirective | anyChars.Repeat(0).Until(hashElse | hashEndIf), + ~(ElseDirective & anyChars.Repeat().Until(EndIfDirective)), + EndIfDirective + ); + Directives.Add( + anyChars.Until(hashIf | hashIfDef | hashIfNDef).Named("UnchangedCode"), + ( + DefineDirective + | ConditionalDirectives + | anyChars.Until(hashIf | hashIfDef | hashIfNDef | End).Named("UnchangedCode") + ) + .Repeat(0) + ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs index 617d75ba24..a690c550f9 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs @@ -220,7 +220,7 @@ public void CreateExpressions() .SeparatedBy(ws); PrimaryExpression.Add( - arrayDeclaration + arrayDeclaration, ConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index abc65da6f6..5f88386b60 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -7,6 +7,7 @@ public class SDSLParser { public CommentGrammar Comments {get;set;} public SDSLGrammar Grammar {get;set;} + public DirectiveGrammar Directive { get;set;} public SDSLParser() { From fe115575beb430ce83ab7a455ecaeb8c4999cb37 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 17 May 2022 20:57:53 +0200 Subject: [PATCH 0066/1182] Created directive grammar folder + correction comment parser --- src/SDSLParserExample/SDSL/shader2.sdsl | 129 +++++--- src/Stride.Shader.Parsing/CommentGrammar.cs | 7 +- src/Stride.Shader.Parsing/DirectiveGrammar.cs | 15 - .../DirectiveGrammar.Directives.Expression.cs | 215 ++++++++++++ .../DirectiveGrammar.Directives.cs | 82 +++++ .../DirectiveGrammar.Tokens.cs | 310 ++++++++++++++++++ .../DirectiveGrammar/DirectiveGrammar.cs | 25 ++ .../DirectiveGrammar/SDSLGrammar.Literals.cs | 67 ++++ .../SDSLGrammar.TokenGroups.cs | 212 ++++++++++++ src/Stride.Shader.Parsing/SDSLParser.cs | 33 +- 10 files changed, 1022 insertions(+), 73 deletions(-) delete mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs create mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index e4d444b36f..0a85d6ee54 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,52 +1,99 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various helper functions. -/// -shader Utilities + +namespace Stride.Rendering.LightProbes { - // ------------------------------------- - // type definition - // ------------------------------------- - typedef uint Half2; - typedef uint2 Half4; - - // Converts a Half2 to a float2 - float2 Half2ToFloat2(Half2 value) + /// + /// Defines a skybox environment light + /// + shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils { - return float2(f16tof32(value), f16tof32(value >> 16)); - } + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes + { +#ifdef STRIDE_MULTISAMPLE_COUNT +#if STRIDE_MULTISAMPLE_COUNT > 1 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#else + stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#endif +#else + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#endif + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients + } - // Converts a float2 to a Half2 - Half2 Float2ToHalf2(float2 value) - { - return f32tof16(value.x) | (f32tof16(value.y) << 16); - } + void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) + { + // Early exit + if (weight == 0.0f) + return; - // Converts a Half4 to a float4 - float4 Half4ToFloat4(Half4 value) { - return float4(f16tof32(value.x), f16tof32(value.x>>16), f16tof32(value.y), f16tof32(value.y>>16)); - } + int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; + for (int i = 0; i < TOrder * TOrder; ++i) + { + // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly + sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; + } + } - // Converts a float4 to a Half4 - Half4 Float4ToHalf4(float4 value) { - return uint2(f32tof16(value.x) | (f32tof16(value.y) << 16), f32tof16(value.z) | (f32tof16(value.w) << 16)); - } + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); - // Commpute Schlick's approximation of Fresnel - float3 FresnelSchlick(float3 specularColor, float3 eye, float3 h, float factor) - { - return specularColor + (1.0f - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; - } + var ambientAccessibility = streams.matAmbientOcclusion; - // Commpute Schlick's approximation of Fresnel - float3 FresnelSchlickWithGloss(float3 specularColor, float3 eye, float3 h, float factor, float gloss) - { - return specularColor + (max(specularColor, gloss) - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; - } + var sampleDirection = streams.normalWS; + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + var shadingPosition = int3(streams.ShadingPosition.xy, 0); +#if STRIDE_MULTISAMPLE_COUNT == 1 + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); +#else + // TODO: Use SV_SampleIndex + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); +#endif + + uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); + float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); + + float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); + + // Protect ourselves against degenerate cases + // TODO: Investigate why those happen (almost coplanar tetrahedron?) + tetrahedronFactors3 = saturate(tetrahedronFactors3); + + float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); + + // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) + tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Renormalize barycentric coordinates + var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; + if (totalSum > 0.0f) + tetrahedronFactors4 /= totalSum; + + float3 sphericalColors[TOrder * TOrder]; + for (int i = 0; i < TOrder * TOrder; ++i) + sphericalColors[i] = 0.0f; - // flip the texture coordinate if on an opengl device. - static float2 ConvertTexCoord(float2 texcoord) { + FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); + FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); + FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); + FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - } -}; + streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + // TEST: + //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + //streams.envLightDiffuseColor = tetrahedronFactors3; + //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); + } + }; +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/CommentGrammar.cs b/src/Stride.Shader.Parsing/CommentGrammar.cs index 37b297707c..924edcaf08 100644 --- a/src/Stride.Shader.Parsing/CommentGrammar.cs +++ b/src/Stride.Shader.Parsing/CommentGrammar.cs @@ -16,11 +16,10 @@ public CommentGrammar() : base("comments-sdsl") | Literal("/*"); var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("Comment"); var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("Comment"); - var anyComments = WhiteSpace | singleLineComment | blockComment; + var anyComments = singleLineComment | blockComment; + var actualCode = AnyChar.Repeat(0).Until(End | "//" | "/*" ).Named("ActualCode"); Comments.Add( - anyComments.Repeat(0) - .Then(AnyChar.Repeat(0).Until(commentStart).Named("ActualCode")) - .Repeat(0) + (anyComments | actualCode).Repeat(0).Until(End) ); Inner = Comments; } diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/DirectiveGrammar.cs deleted file mode 100644 index d1b3bb2164..0000000000 --- a/src/Stride.Shader.Parsing/DirectiveGrammar.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace Stride.Shader.Parsing -{ - public partial class DirectiveGrammar : SDSLGrammar - { - public DirectiveGrammar() : base() - { - Inner = Directives; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs new file mode 100644 index 0000000000..3d9df02df5 --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs @@ -0,0 +1,215 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class DirectiveGrammar : Grammar +{ + public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; + public AlternativeParser DirectivePostFixExpression = new() { Name = "DirectivePostFixExpression" }; + public AlternativeParser DirectiveUnaryExpression = new() { Name = "DirectiveUnaryExpression" }; + public AlternativeParser DirectiveCastExpression = new() { Name = "DirectiveCastExpression" }; + public AlternativeParser DirectiveMulExpression = new() { Name = "DirectiveMulExpression" }; + public AlternativeParser DirectiveSumExpression = new() { Name = "DirectiveSumExpression" }; + public AlternativeParser DirectiveShiftExpression = new() { Name = "DirectiveShiftExpression" }; + + public AlternativeParser DirectiveConditionalExpression = new() { Name = "DirectiveConditionalExpression" }; + public AlternativeParser DirectiveLogicalOrExpression = new() { Name = "DirectiveLogicalOrExpression" }; + public AlternativeParser DirectiveLogicalAndExpression = new() { Name = "DirectiveLogicalAndExpression" }; + public AlternativeParser DirectiveOrExpression = new() { Name = "DirectiveOrExpression" }; + public AlternativeParser DirectiveXorExpression = new() { Name = "DirectiveXorExpression" }; + public AlternativeParser DirectiveAndExpression = new() { Name = "DirectiveAndExpression" }; + public AlternativeParser DirectiveTestExpression = new() { Name = "DirectiveTestExpression" }; + + public AlternativeParser DirectiveIncrementExpression = new() { Name = "DirectiveIncrementExpression" }; + public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; + public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; + public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; + public DirectiveGrammar DirectiveUsingDirectiveExpression() + { + Inner = DirectiveExpression; + return this; + } + + public Parser Parenthesis(Parser p, bool notFollowedByUnary = true) + { + if (notFollowedByUnary) + return LeftParen.Then(p).Then(RightParen).SeparatedBy(SingleLineWhiteSpace.Repeat(0)).NotFollowedBy(DirectiveUnaryExpression); + else + return LeftParen.Then(p).Then(RightParen).SeparatedBy(SingleLineWhiteSpace.Repeat(0)); + } + public void CreateDirectiveExpressions() + { + var ws = SingleLineWhiteSpace.Repeat(0); + var ls1 = SingleLineWhiteSpace.Repeat(1); + + + + var incrementOp = new AlternativeParser(); + incrementOp.Add( + PlusPlus, + MinusMinus + ); + + var parameters = + DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws); + + var MethodCall = new AlternativeParser( + Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("DirectiveMethodCallExpression") + ); + + + DirectiveTermExpression.Add( + Literals, + ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + MethodCall, + Parenthesis(DirectiveExpression) + ); + + var arrayAccess = new SequenceParser(); + var chain = new SequenceParser(); + var postfixInc = new SequenceParser(); + + + arrayAccess.Add( + Identifier, + ws, + (LeftBracket & DirectiveExpression & RightBracket) + .SeparatedBy(ws) + .Repeat(1) + .SeparatedBy(ws) + ); + chain.Add( + (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(ws & Dot & ws) + ); + postfixInc.Add( + chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, + ws, + incrementOp.Named("Operator") + ); + + DirectivePostFixExpression.Add( + DirectiveTermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), + postfixInc.Named("PostfixIncrement"), + chain.Named("AccessorChain"), + arrayAccess.Named("ArrayAccesor") + ); + + var prefixInc = new SequenceParser(); + prefixInc.Add( + incrementOp, + ws, + Identifier.NotFollowedBy(ws & (Dot | "[")) + | chain + | arrayAccess + ); + + DirectiveUnaryExpression.Add( + DirectivePostFixExpression, + prefixInc.Named("PrefixIncrement"), + Literal("sizeof").Then(LeftParen).Then(Identifier | DirectiveUnaryExpression).Then(RightParen).Named("SizeOf") + ); + + var cast = new SequenceParser(); + cast.Add( + LeftParen, + ValueTypes | Identifier, + RightParen, + DirectiveUnaryExpression + ); + + DirectiveCastExpression.Add( + DirectiveUnaryExpression, + cast.SeparatedBy(ws).Named("DirectiveCastExpression") + ); + + + var mulOp = Star | Div | Mod; + DirectiveMulExpression.Add( + (Parenthesis(DirectiveExpression) | DirectiveCastExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) + ); + + var sumOp = Plus | Minus; + + DirectiveSumExpression.Add( + DirectiveMulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) + ); + + + var shiftOp = LeftShift | RightShift; + + DirectiveShiftExpression.Add( + DirectiveSumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) + ); + + + DirectiveAndExpression.Add( + DirectiveShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) + ); + + DirectiveXorExpression.Add( + DirectiveAndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) + ); + + + DirectiveOrExpression.Add( + DirectiveXorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) + ); + + var testOp = LessEqual | Less | GreaterEqual | Greater; + + DirectiveTestExpression.Add( + DirectiveOrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) + ); + + var eqOp = + Literal("==") + | Literal("!="); + + DirectiveEqualsExpression.Add( + DirectiveTestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) + ); + + DirectiveLogicalAndExpression.Add( + DirectiveEqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) + ); + DirectiveLogicalOrExpression.Add( + DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) + ); + + DirectiveConditionalExpression.Add( + DirectiveLogicalOrExpression.NotFollowedBy(ws & "?"), + (Parenthesis(DirectiveLogicalOrExpression).NotFollowedBy(ws & OrOr) | DirectiveLogicalOrExpression) + .Then("?") + .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) + .Then(":") + .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) + .SeparatedBy(ws) + .Named("Ternary") + + ); + + DirectiveParenExpression.Add( + LeftParen.Then(DirectiveExpression).Then(RightParen).SeparatedBy(ws) + ); + + + var arrayDeclaration = + (LeftBrace & DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & RightBrace) + .SeparatedBy(ws); + + DirectiveExpression.Add( + arrayDeclaration, + DirectiveConditionalExpression + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs new file mode 100644 index 0000000000..f21ffca99e --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -0,0 +1,82 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class DirectiveGrammar : Grammar +{ + public SequenceParser IfDirective = new(){Name = "IfDirective"}; + public SequenceParser ElseDirective = new() { Name = "ElseDirective" }; + public SequenceParser ElifDirective = new(){Name = "ElifDirective"}; + public SequenceParser DefineDirective = new(){Name = "DefineDirective"}; + public SequenceParser EndIfDirective = new(){Name = "EndIfDirective"}; + + + public SequenceParser IfDefDirective = new() { Name = "IfDefDirective" }; + public SequenceParser IfNDefDirective = new(){Name = "IfNDefDirective"}; + + public SequenceParser ConditionalDirectives = new(){Name = "ConditionalDirectives"}; + public SequenceParser DefineDirectives = new(){Name = "DefineDirectives"}; + + public SequenceParser Directives = new(); + + public void CreateDirectives() + { + var ls = SingleLineWhiteSpace.Repeat(0); + var ls1 = SingleLineWhiteSpace.Repeat(1); + var hash = Literal("#"); + var hashIfNDef = Literal("#ifndef").Named("hashifndef"); + var hashIfDef = Literal("#ifdef").Named("hashifdef"); + var hashIf = Literal("#if").Named("hashif"); + var hashEndIf = Literal("#endif").Named("HashEndIf"); + var hashElse = Literal("#else").Named("HashElse"); + var hashElif = Literal("#elif").Named("HashElif"); + var hashDefine = Literal("#define").Named("HashElif"); + + IfDirective.Add(ls, hashIf, ls1, DirectiveExpression); + ElseDirective.Add(ls, hashElse, ls.Until(Eol | End)); + ElifDirective.Add(ls, hashElif, ls1, DirectiveExpression, ls.Until(Eol | End)); + EndIfDirective.Add(ls, hashEndIf, ls.Until(Eol | End)); + IfDefDirective.Add(ls, hashIfDef, ls1, Identifier, ls.Until(Eol | End)); + IfNDefDirective.Add(ls, hashIfNDef, ls1, Identifier, ls.Until(Eol | End)); + DefineDirective.Add(ls, hashDefine, ls1, Identifier, ls1, DirectiveExpression, ls.Until(Eol | End)); + + var anyChars = AnyChar.Repeat(0); + + var elseList = new AlternativeParser( + (ElifDirective & anyChars.Until(hashElif | hashElse | hashEndIf).Named("ElifCode")).Repeat(), + ElseDirective & anyChars.Until(hashEndIf).Named("ElseCode") + ); + + ConditionalDirectives.Add( + IfDirective, + anyChars.Until(hashElif | hashElse | hashEndIf).Named("IfCode"), + ~elseList, + EndIfDirective + ); + DefineDirectives.Add( + IfDefDirective | IfNDefDirective, + ConditionalDirectives | DefineDirective | anyChars.Repeat(0).Until(hashElse | hashEndIf), + ~(ElseDirective & anyChars.Repeat().Until(EndIfDirective)), + EndIfDirective + ); + + var ifDefCode = (IfDefDirective | IfNDefDirective) & AnyChar.Repeat(0).Until(hashDefine | hashIf | hashElse | hashEndIf).Named("IfDefCode"); + var elseCode = ElseDirective & AnyChar.Repeat(0).Until(hashEndIf).Named("ElseCode"); + var ifCode = IfDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("IfCode"); + var elifCode = ElifDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("ElifCode"); + + var conditional = ifCode & elifCode.Repeat(0) & ~elseCode & EndIfDirective; + var definition = + ifDefCode & + conditional & //(conditional | DefineDirective | AnyChar.Repeat(0).Until(hashElse | hashEndIf).Named("IfDefCode")) & + ~elseCode & + EndIfDirective; + + + Directives.Add( + AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode"), + ~(definition | DefineDirective | conditional | AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode")).Repeat(0).Until(End) + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs new file mode 100644 index 0000000000..28d426fa92 --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs @@ -0,0 +1,310 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; +namespace Stride.Shader.Parsing; +public partial class DirectiveGrammar : Grammar +{ + private AlternativeParser Space = new(); + private RepeatParser Spaces = new(); + private SequenceParser SpacesWithLineBreak = new(); + private LiteralTerminal AppendStructuredBuffer = new(); + private AlternativeParser ComponentNumber = new(); + + private LiteralTerminal Bool = new(); + private SequenceParser BoolVec = new(); + private SequenceParser BoolMat = new(); + private AlternativeParser Uint = new(); + private SequenceParser UintVec = new(); + private SequenceParser UintMat = new(); + private LiteralTerminal Int = new(); + private SequenceParser IntVec = new(); + private SequenceParser IntMat = new(); + + private LiteralTerminal Half = new(); + private SequenceParser HalfVec = new(); + private SequenceParser HalfMat = new(); + private LiteralTerminal Float = new(); + private SequenceParser FloatVec = new(); + private SequenceParser FloatMat = new(); + private LiteralTerminal Double = new(); + private SequenceParser DoubleVec = new(); + private SequenceParser DoubleMat = new(); + private LiteralTerminal Buffer = new(); + private LiteralTerminal ByteAddressBuffer = new(); + private LiteralTerminal Break = new(); + private LiteralTerminal Case = new(); + private LiteralTerminal CBuffer = new(); + private LiteralTerminal Centroid = new(); + private LiteralTerminal Class = new(); + private LiteralTerminal ColumnMajor = new(); + private LiteralTerminal Const = new(); + private LiteralTerminal ConsumeStructuredBuffer = new(); + private LiteralTerminal Continue = new(); + private LiteralTerminal Default = new(); + private LiteralTerminal Discard = new(); + private LiteralTerminal Do = new(); + private LiteralTerminal Else = new(); + private LiteralTerminal Extern = new(); + private LiteralTerminal For = new(); + private LiteralTerminal Groupshared = new(); + private LiteralTerminal If = new(); + private LiteralTerminal In = new(); + private AlternativeParser Inout = new(); + private LiteralTerminal InputPatch = new(); + private LiteralTerminal Interface = new(); + + + private LiteralTerminal LineAdj = new(); + private LiteralTerminal Linear = new(); + private LiteralTerminal LineStream = new(); + private LiteralTerminal Long = new(); + private LiteralTerminal Matrix = new(); + private LiteralTerminal Nointerpolation = new(); + private LiteralTerminal Noperspective = new(); + private LiteralTerminal Out = new(); + private LiteralTerminal OutputPatch = new(); + private LiteralTerminal Packoffset = new(); + private LiteralTerminal Point = new(); + private LiteralTerminal PointStream = new(); + private LiteralTerminal Precise = new(); + private LiteralTerminal Register = new(); + private LiteralTerminal Return = new(); + private LiteralTerminal RowMajor = new(); + private LiteralTerminal RWBuffer = new(); + private LiteralTerminal RWByteAddressBuffer = new(); + private LiteralTerminal RWStructuredBuffer = new(); + private LiteralTerminal Sample = new(); + private LiteralTerminal Sampler = new(); + private LiteralTerminal SamplerComparisonState = new(); + private LiteralTerminal SamplerState = new(); + private LiteralTerminal Shared = new(); + private LiteralTerminal StaticConst = new(); + private LiteralTerminal Static = new(); + private LiteralTerminal Struct = new(); + private LiteralTerminal StructuredBuffer = new(); + private LiteralTerminal Switch = new(); + private AlternativeParser TextureTypes = new(); + private LiteralTerminal Triangle = new(); + private LiteralTerminal TriangleAdj = new(); + private LiteralTerminal TriangleStream = new(); + private LiteralTerminal Uniform = new(); + private LiteralTerminal Vector = new(); + private LiteralTerminal Volatile = new(); + private LiteralTerminal Void = new(); + private LiteralTerminal While = new(); + private LiteralTerminal LeftParen = new(); + private LiteralTerminal RightParen = new(); + private LiteralTerminal LeftBracket = new(); + private LiteralTerminal RightBracket = new(); + private LiteralTerminal LeftBrace = new(); + private LiteralTerminal RightBrace = new(); + + private LiteralTerminal LeftShift = new(); + private LiteralTerminal RightShift = new(); + private LiteralTerminal Plus = new(); + private LiteralTerminal PlusPlus = new(); + private LiteralTerminal Minus = new(); + private LiteralTerminal MinusMinus = new(); + private LiteralTerminal Star = new(); + private LiteralTerminal Div = new(); + private LiteralTerminal Mod = new(); + private LiteralTerminal And = new(); + private LiteralTerminal Or = new(); + private LiteralTerminal AndAnd = new(); + private LiteralTerminal OrOr = new(); + private LiteralTerminal Caret = new(); + private LiteralTerminal Not = new(); + private LiteralTerminal Tilde = new(); + private LiteralTerminal Equal = new(); + private LiteralTerminal NotEqual = new(); + private LiteralTerminal Less = new(); + private LiteralTerminal LessEqual = new(); + private LiteralTerminal Greater = new(); + private LiteralTerminal GreaterEqual = new(); + private LiteralTerminal Question = new(); + private LiteralTerminal Colon = new(); + private LiteralTerminal ColonColon = new(); + private LiteralTerminal Semi = new(); + private LiteralTerminal Comma = new(); + private LiteralTerminal Assign = new(); + private LiteralTerminal StarAssign = new(); + private LiteralTerminal DivAssign = new(); + private LiteralTerminal ModAssign = new(); + private LiteralTerminal PlusAssign = new(); + private LiteralTerminal MinusAssign = new(); + private LiteralTerminal LeftShiftAssign = new(); + private LiteralTerminal RightShiftAssign = new(); + private LiteralTerminal AndAssign = new(); + private LiteralTerminal XorAssign = new(); + private LiteralTerminal OrAssign = new(); + + private LiteralTerminal Dot = new(); + private LiteralTerminal True = new(); + private LiteralTerminal False = new(); + private AlternativeParser PreprocessorDirectiveName = new(); + + private LiteralTerminal Stream = new(){Name = "Stream"}; + private LiteralTerminal Stage = new(){Name = "Stage"}; + + + public void CreateTokens() + { + Space = WhiteSpace | Eol; + Spaces = Space.Optional().Repeat(); + SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); + AppendStructuredBuffer = Literal("AppendStructuredBuffer"); + ComponentNumber = Literal("1") | "2" | "3" | "4"; + + Bool = Literal("bool"); + BoolVec.Add(Bool,ComponentNumber); + BoolMat.Add(BoolVec,Literal("x"),ComponentNumber); + Uint.Add("uint","unsigned int", "dword"); + UintVec.Add(Uint,ComponentNumber); + UintMat.Add(UintVec,"x",ComponentNumber); + Int = Literal("int"); + IntVec.Add(Int,ComponentNumber); + IntMat.Add(IntVec,"x",ComponentNumber); + + Half = Literal("half"); + HalfVec.Add(Half, ComponentNumber); + HalfMat.Add(HalfVec, "x", ComponentNumber); + Float = Literal("float"); + FloatVec.Add(Float,ComponentNumber); + FloatMat.Add(FloatVec,"x",ComponentNumber); + Double = Literal("double"); + DoubleVec.Add(Double,ComponentNumber); + DoubleMat.Add(DoubleVec,"x",ComponentNumber); + Buffer = Literal("Buffer"); + ByteAddressBuffer = Literal("ByteAddressBuffer"); + Break = Literal("break"); + Case = Literal("case"); + CBuffer = Literal("cbuffer"); + Centroid = Literal("centroid"); + Class = Literal("class"); + ColumnMajor = Literal("column_major"); + Const = Literal("const"); + ConsumeStructuredBuffer = Literal("ConsumeStructuredBuffer"); + Continue = Literal("continue"); + Default = Literal("default"); + Discard = Literal("discard"); + Do = Literal("do"); + Else = Literal("else"); + Extern = Literal("extern"); + For = Literal("for"); + Groupshared = Literal("groupshared"); + If = Literal("if"); + In = Literal("in"); + Inout = Literal("inout") | "in out"; + InputPatch = Literal("InputPatch"); + Interface = Literal("interface"); + LineAdj = Literal("lineadj"); + Linear = Literal("linear"); + LineStream = Literal("LineStream"); + Long = Literal("long"); + Matrix = Literal("matrix"); + Nointerpolation = Literal("nointerpolation"); + Noperspective = Literal("noperspective"); + Out = Literal("out"); + OutputPatch = Literal("OutputPatch"); + Packoffset = Literal("packoffset"); + Point = Literal("point"); + PointStream = Literal("PointStream"); + Precise = Literal("precise"); + Register = Literal("register"); + Return = Literal("return"); + RowMajor = Literal("row_major"); + RWBuffer = Literal("RWBuffer"); + RWByteAddressBuffer = Literal("RWByteAddressBuffer"); + RWStructuredBuffer = Literal("RWStructuredBuffer"); + Sample = Literal("sample"); + Sampler = Literal("sampler"); + SamplerComparisonState = Literal("SamplerComparisonState"); + SamplerState = Literal("SamplerState"); + Shared = Literal("shared"); + Static = Literal("static"); + StaticConst = Literal("static const"); + Struct = Literal("struct"); + StructuredBuffer = Literal("StructuredBuffer"); + Switch = Literal("switch"); + TextureTypes.Add( + Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional()), + Literal("Texture2DMS").Then(Literal("Array").Optional()), + Literal("TextureCube").Then(Literal("Array").Optional()) + ); + Triangle = Literal("triangle"); + TriangleAdj = Literal("triangleadj"); + TriangleStream = Literal("TriangleStream"); + Uniform = Literal("uniform"); + Vector = Literal("vector"); + Volatile = Literal("volatile"); + Void = Literal("void"); + While = Literal("while"); + LeftParen = Literal("("); + RightParen = Literal(")"); + LeftBracket = Literal("["); + RightBracket = Literal("]"); + LeftBrace = Literal("{"); + RightBrace = Literal("}"); + + LeftShift = Literal("<<"); + RightShift = Literal(">>"); + Plus = Literal("+"); + PlusPlus = Literal("++"); + Minus = Literal("-"); + MinusMinus = Literal("--"); + Star = Literal("*"); + Div = Literal("/"); + Mod = Literal("%"); + And = Literal("&"); + Or = Literal("|"); + AndAnd = Literal("&&"); + OrOr = Literal("||"); + Caret = Literal("^"); + Not = Literal("!"); + Tilde = Literal("~"); + Equal = Literal("=="); + NotEqual = Literal("!="); + Less = Literal("<"); + LessEqual = Literal("<="); + Greater = Literal(">"); + GreaterEqual = Literal(">="); + Question = Literal("?"); + Colon = Literal(":"); + ColonColon = Literal("::"); + Semi = Literal(";"); + Comma = Literal(","); + Assign = Literal("="); + StarAssign = Literal("*="); + DivAssign = Literal("/="); + ModAssign = Literal("%="); + PlusAssign = Literal("+="); + MinusAssign = Literal("-="); + LeftShiftAssign = Literal("<<="); + RightShiftAssign = Literal(">>="); + AndAssign = Literal("&="); + XorAssign = Literal("^="); + OrAssign = Literal("|="); + + Dot = Literal("."); + True = Literal("true"); + False = Literal("false"); + PreprocessorDirectiveName.Add( + Literal("define"), + Literal("elif"), + Literal("else"), + Literal("endif"), + Literal("error"), + Literal("if"), + Literal("ifdef"), + Literal("ifndef"), + Literal("include"), + Literal("line"), + Literal("pragma"), + Literal("undef") + ); + + Stage = Literal("stage"); + Stream = Literal("stream"); + + } +} diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs new file mode 100644 index 0000000000..83dd7f171f --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs @@ -0,0 +1,25 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing +{ + public partial class DirectiveGrammar + { + public DirectiveGrammar() + { + CreateAll(); + Inner = Directives; + } + + public void CreateAll() + { + CreateTokens(); + CreateTokenGroups(); + CreateLiterals(); + CreateDirectives(); + CreateDirectiveExpressions(); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs new file mode 100644 index 0000000000..c9e0ee8c38 --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs @@ -0,0 +1,67 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +using EtoParser = Eto.Parse.Parser; + +namespace Stride.Shader.Parsing; +public partial class DirectiveGrammar : Grammar +{ + AlternativeParser IntegerSuffix = new(); + AlternativeParser FloatSuffix = new(); + + public StringParser StringLiteral = new(); + public SequenceParser Identifier = new(); + public AlternativeParser UserDefinedId = new(); + + public NumberParser IntegerLiteral = new(); + public NumberParser FloatLiteral = new(); + public HexDigitTerminal HexDigits = new(); + public SequenceParser HexaDecimalLiteral = new(); + + public BooleanTerminal BooleanTerm = new(); + + public AlternativeParser Literals = new(); + + public void CreateLiterals() + { + Identifier.Add( + Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier") + ); + + UserDefinedId.Add( + Identifier.Except(Keywords) + ); + + IntegerSuffix.Add( + "u", + "l", + "U", + "L" + ); + + FloatSuffix.Add( + "f", + "d", + "F", + "D" + ); + + + + StringLiteral = new StringParser().WithName("StringLiteral"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); + HexDigits = new(); + HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); + + BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; + + Literals.Add( + IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Named("IntegerLiteral"), + FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral"), + HexaDecimalLiteral, + StringLiteral + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs new file mode 100644 index 0000000000..5487e381d5 --- /dev/null +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs @@ -0,0 +1,212 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing; +public partial class DirectiveGrammar : Grammar +{ + public AlternativeParser IncOperators = new(); + + public AlternativeParser Operators = new(); + public AlternativeParser AssignOperators = new(); + + public AlternativeParser BoolTypes = new(); + + public AlternativeParser HalfTypes = new(); + + public AlternativeParser FloatTypes = new(); + + public AlternativeParser DoubleTypes = new(); + + public AlternativeParser IntTypes = new(); + + public AlternativeParser UintTypes = new(); + + public AlternativeParser ValueTypes = new(); + public AlternativeParser StorageFlag = new(); + + public AlternativeParser Keywords = new(); + + public void CreateTokenGroups() + { + IncOperators.Add( + PlusPlus, + MinusMinus + ); + + Operators.Add( + PlusPlus, + Plus, + MinusMinus, + Minus, + Star, + Div, + Mod, + LeftShift, + RightShift, + AndAnd, + And, + OrOr, + Or, + "^", + Equal, + "==", + NotEqual, + Question + + ); + + AssignOperators.Add( + Assign, + StarAssign, + DivAssign, + ModAssign, + PlusAssign, + MinusAssign, + LeftShiftAssign, + RightShiftAssign, + AndAssign, + XorAssign, + OrAssign + ); + + BoolTypes.Add( + Bool.NotFollowedBy(Set("1234")), + BoolVec.NotFollowedBy("x"), + BoolMat + ); + + HalfTypes.Add( + Half.NotFollowedBy(Set("1234")), + HalfVec.NotFollowedBy("x"), + HalfMat + ); + + FloatTypes.Add( + Float.NotFollowedBy(Set("1234")), + FloatVec.NotFollowedBy("x"), + FloatMat + ); + + DoubleTypes.Add( + Double.NotFollowedBy(Set("1234")), + DoubleVec.NotFollowedBy("x"), + DoubleMat + ); + + IntTypes.Add( + Int.NotFollowedBy(Set("1234")), + IntVec.NotFollowedBy("x"), + IntMat + ); + + UintTypes.Add( + Uint.NotFollowedBy(Set("1234")), + UintVec.NotFollowedBy("x"), + UintMat + ); + + ValueTypes.Add( + BoolTypes, + HalfTypes, + FloatTypes, + DoubleTypes, + IntTypes, + UintTypes + ); + + Keywords.Add( + AppendStructuredBuffer, + Buffer, + ByteAddressBuffer, + Break, + Case, + CBuffer, + Centroid, + Class, + ColumnMajor, + Const, + ConsumeStructuredBuffer, + Continue, + Default, + Discard, + Do, + Else, + Extern, + For, + Groupshared, + If, + In, + Inout, + InputPatch, + Interface, + LineAdj, + Linear, + LineStream, + Matrix, + Nointerpolation, + Noperspective, + Out, + OutputPatch, + Packoffset, + Point, + PointStream, + Precise, + Register, + Return, + RowMajor, + RWBuffer, + RWByteAddressBuffer, + RWStructuredBuffer, + Sample, + Sampler, + SamplerComparisonState, + SamplerState, + Shared, + Stage, + Stream, + StaticConst, + Static, + Struct, + StructuredBuffer, + Switch, + TextureTypes, + Triangle, + TriangleAdj, + TriangleStream, + Uniform, + ValueTypes, + Vector, + Volatile, + Void, + While + ); + + StorageFlag.Add( + Literal("constant"), + RowMajor, + ColumnMajor, + Extern, + Precise, + Shared, + Groupshared, + StaticConst, + Static, + Uniform, + Volatile, + Linear, + Centroid, + Nointerpolation, + Noperspective, + Sample, + In.NotFollowedBy(WhiteSpace.Repeat(0) & Out), + Out, + Inout, + Point, + Triangle, + LineAdj, + TriangleAdj + ); + + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index 5f88386b60..6c3625267e 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -8,11 +8,13 @@ public class SDSLParser public CommentGrammar Comments {get;set;} public SDSLGrammar Grammar {get;set;} public DirectiveGrammar Directive { get;set;} + public IEnumerable Defined { get; set; } public SDSLParser() { Comments = new(); Grammar = new(); + Directive = new(); } public SDSLParser With(Parser p) @@ -24,25 +26,30 @@ public SDSLParser With(Parser p) public GrammarMatch Parse(string shader) { var comments = Comments.Match(shader); - if(!comments.Matches.Any(x => x.Name == "Comment")) + var preprocessed = new StringBuilder(); + if (!comments.Matches.Any(x => x.Name == "Comment")) { - return Grammar.Match(shader); + return Directive.Match(shader); } - var actualCode = new StringBuilder(); - foreach(var m in comments.Matches) + else { - if(m.Name == "ActualCode") + var actualCode = new StringBuilder(); + foreach (var m in comments.Matches) { - actualCode.Append(m.StringValue); - } + if (m.Name == "ActualCode") + { + actualCode.AppendLine(m.StringValue); + } + } + //preprocessed.Add(this.PreProcessor()) + return PreProcessor(actualCode.ToString()); } - var matches = Grammar.Match(actualCode.ToString()); - //if (matches.Errors.Any()) - //{ - // throw new Exception("Parsing Exception : " + matches.ErrorMessage); - //} - return matches; + } + + public GrammarMatch PreProcessor(string code) + { + return Directive.Match(code); } } \ No newline at end of file From 477fb076edcaac539edb7fd3ff99855e5c525684 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 19 May 2022 10:23:00 +0200 Subject: [PATCH 0067/1182] Directive parser update --- src/SDSLParserExample/SDSL/shader.sdsl | 119 ++++++++++++++---- src/SDSLParserExample/SDSL/shader2.sdsl | 105 ++-------------- .../DirectiveGrammar.Directives.cs | 23 ++-- 3 files changed, 116 insertions(+), 131 deletions(-) diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl index 6daa767ce9..487c3da1db 100644 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ b/src/SDSLParserExample/SDSL/shader.sdsl @@ -1,26 +1,99 @@ -// Some comments +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BasicMixin : BasicShader, Parent2, Parent3 { - float myFloat=0.2f; - stage float3 myPosition : register(b); - stage stream float2 screenPosition : register(vs, b); - - abstract void myFunc(); - - float4 ComputeColor() +namespace Stride.Rendering.LightProbes +{ + /// + /// Defines a skybox environment light + /// + shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils { - return float4(1.0); - } + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes + { +#ifdef STRIDE_MULTISAMPLE_COUNT + #if STRIDE_MULTISAMPLE_COUNT > 1 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #else + stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #endif +#else + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#endif + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients + } - void PSMain() - { - // float a = MyShader.Composition1.Composition2.MyFunction(1,0,true); - streams.ColorTarget = float4(0,0,0,1); - } - - // [maxvertexcount(GeometryShaderMaxVertexCount)] - // void GSMain(triangle Input input[3], inout TriangleStream triangleStream) - // { - // Storage.GenerateTriangles(input, triangleStream); - // } -}; \ No newline at end of file + void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) + { + // Early exit + if (weight == 0.0f) + return; + + int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; + for (int i = 0; i < TOrder * TOrder; ++i) + { + // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly + sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; + } + } + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + var ambientAccessibility = streams.matAmbientOcclusion; + + var sampleDirection = streams.normalWS; + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + var shadingPosition = int3(streams.ShadingPosition.xy, 0); +#if STRIDE_MULTISAMPLE_COUNT == 1 + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); +#else + // TODO: Use SV_SampleIndex + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); +#endif + + uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); + float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); + + float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); + + // Protect ourselves against degenerate cases + // TODO: Investigate why those happen (almost coplanar tetrahedron?) + tetrahedronFactors3 = saturate(tetrahedronFactors3); + + float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); + + // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) + tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Renormalize barycentric coordinates + var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; + if (totalSum > 0.0f) + tetrahedronFactors4 /= totalSum; + + float3 sphericalColors[TOrder * TOrder]; + for (int i = 0; i < TOrder * TOrder; ++i) + sphericalColors[i] = 0.0f; + + FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); + FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); + FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); + FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); + + streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + // TEST: + //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + //streams.envLightDiffuseColor = tetrahedronFactors3; + //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); + } + }; +} diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 0a85d6ee54..db257a0d61 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,99 +1,12 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.LightProbes -{ - /// - /// Defines a skybox environment light - /// - shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils - { - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { -#ifdef STRIDE_MULTISAMPLE_COUNT -#if STRIDE_MULTISAMPLE_COUNT > 1 - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#ifdef something +SomeCode +#if 5==5 +5 equals 5 #else - stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +5 not equals 5 #endif -#else - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID -#endif - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } - - void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) - { - // Early exit - if (weight == 0.0f) - return; - - int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; - for (int i = 0; i < TOrder * TOrder; ++i) - { - // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly - sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; - } - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - var sampleDirection = streams.normalWS; - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - var shadingPosition = int3(streams.ShadingPosition.xy, 0); -#if STRIDE_MULTISAMPLE_COUNT == 1 - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); -#else - // TODO: Use SV_SampleIndex - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); +something to do? +#if 6==6 +6 equals 6 #endif - - uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); - float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); - - float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); - - // Protect ourselves against degenerate cases - // TODO: Investigate why those happen (almost coplanar tetrahedron?) - tetrahedronFactors3 = saturate(tetrahedronFactors3); - - float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); - - // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) - tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Renormalize barycentric coordinates - var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; - if (totalSum > 0.0f) - tetrahedronFactors4 /= totalSum; - - float3 sphericalColors[TOrder * TOrder]; - for (int i = 0; i < TOrder * TOrder; ++i) - sphericalColors[i] = 0.0f; - - FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); - FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); - FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); - FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - - streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - // TEST: - //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - //streams.envLightDiffuseColor = tetrahedronFactors3; - //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); - } - }; -} \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs index f21ffca99e..98408b485f 100644 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -33,13 +33,13 @@ public void CreateDirectives() var hashElif = Literal("#elif").Named("HashElif"); var hashDefine = Literal("#define").Named("HashElif"); - IfDirective.Add(ls, hashIf, ls1, DirectiveExpression); - ElseDirective.Add(ls, hashElse, ls.Until(Eol | End)); - ElifDirective.Add(ls, hashElif, ls1, DirectiveExpression, ls.Until(Eol | End)); - EndIfDirective.Add(ls, hashEndIf, ls.Until(Eol | End)); - IfDefDirective.Add(ls, hashIfDef, ls1, Identifier, ls.Until(Eol | End)); - IfNDefDirective.Add(ls, hashIfNDef, ls1, Identifier, ls.Until(Eol | End)); - DefineDirective.Add(ls, hashDefine, ls1, Identifier, ls1, DirectiveExpression, ls.Until(Eol | End)); + IfDirective.Add(hashIf, ls1, DirectiveExpression, ls.Until(Eol | End, true)); + ElseDirective.Add(hashElse, ls.Until(Eol | End, true)); + ElifDirective.Add(hashElif, ls1, DirectiveExpression, ls.Until(Eol | End, true)); + EndIfDirective.Add(hashEndIf, ls.Until(Eol | End, true)); + IfDefDirective.Add(hashIfDef, ls1, Identifier, ls.Until(Eol | End, true)); + IfNDefDirective.Add(hashIfNDef, ls1, Identifier, ls.Until(Eol | End, true)); + DefineDirective.Add(hashDefine, ls1, Identifier, ls1, DirectiveExpression, ls.Until(Eol | End, true)); var anyChars = AnyChar.Repeat(0); @@ -63,20 +63,19 @@ public void CreateDirectives() var ifDefCode = (IfDefDirective | IfNDefDirective) & AnyChar.Repeat(0).Until(hashDefine | hashIf | hashElse | hashEndIf).Named("IfDefCode"); var elseCode = ElseDirective & AnyChar.Repeat(0).Until(hashEndIf).Named("ElseCode"); - var ifCode = IfDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("IfCode"); + var ifCode = IfDirective & AnyChar.Repeat(0).Until(hashElif | hashElse | hashEndIf).Named("IfCode"); var elifCode = ElifDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("ElifCode"); - var conditional = ifCode & elifCode.Repeat(0) & ~elseCode & EndIfDirective; + var conditional = ifCode & elifCode.Repeat(0).Until(hashElse | hashEndIf) & ~elseCode & EndIfDirective; var definition = ifDefCode & - conditional & //(conditional | DefineDirective | AnyChar.Repeat(0).Until(hashElse | hashEndIf).Named("IfDefCode")) & - ~elseCode & + (conditional.Named("Conditional") | AnyChar.Repeat(0).Until(hashEndIf | hashIf).Named("IfDefCode")).Repeat(0).Until(hashEndIf) & EndIfDirective; Directives.Add( AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode"), - ~(definition | DefineDirective | conditional | AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode")).Repeat(0).Until(End) + definition ); } } \ No newline at end of file From 11d405eab173c31d7ca60b5ad6e6c164bc83ad40 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 22 May 2022 20:04:01 +0200 Subject: [PATCH 0068/1182] Cleanup and refactoring --- src/SDSLParserExample/SDSL/shader2.sdsl | 23 +- .../AST/Directives/TokensNode.cs | 10 + src/Stride.Shader.Parsing/CommentGrammar.cs | 27 -- .../DirectiveGrammar.Tokens.cs | 310 ------------------ .../DirectiveGrammar/DirectiveGrammar.cs | 25 -- .../SDSLGrammar.TokenGroups.cs | 212 ------------ .../Grammars/CommentGrammar.cs | 26 ++ .../DirectiveGrammar.Directives.Expression.cs | 4 +- .../DirectiveGrammar.Directives.cs | 17 +- .../DirectiveGrammar.Tokens.cs | 138 ++++++++ .../DirectiveGrammar/DirectiveGrammar.cs | 24 ++ .../DirectiveGrammar/SDSLGrammar.Literals.cs | 7 +- .../SDSLGrammar.TokenGroups.cs | 69 ++++ .../SDSLGrammar/SDSLGrammar.Declaration.cs | 2 +- .../SDSLGrammar.Directives.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Directives.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.MethodDeclaration.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- ...ar.Statements.ConditionalFlowStatements.cs | 2 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 3 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 3 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 4 +- .../{ => Grammars}/SDSLGrammar/SDSLGrammar.cs | 2 +- src/Stride.Shader.Parsing/SDSLParser.cs | 6 +- 27 files changed, 317 insertions(+), 611 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs delete mode 100644 src/Stride.Shader.Parsing/CommentGrammar.cs delete mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs delete mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs delete mode 100644 src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs create mode 100644 src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs rename src/Stride.Shader.Parsing/{ => Grammars}/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/DirectiveGrammar/DirectiveGrammar.Directives.cs (87%) create mode 100644 src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs create mode 100644 src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename src/Stride.Shader.Parsing/{ => Grammars}/DirectiveGrammar/SDSLGrammar.Literals.cs (92%) create mode 100644 src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Declaration.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (99%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Directives.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Expression.cs (99%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Literals.cs (97%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Shader.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (95%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (96%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Statements.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.TokenGroups.cs (98%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.Tokens.cs (99%) rename src/Stride.Shader.Parsing/{ => Grammars}/SDSLGrammar/SDSLGrammar.cs (94%) diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index db257a0d61..1f9f327a86 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,12 +1,19 @@ -#ifdef something -SomeCode -#if 5==5 -5 equals 5 +#define Something 5 +#ifdef STRIDE_MULTISAMPLE_COUNT + #if STRIDE_MULTISAMPLE_COUNT > 1 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #else + stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #endif #else -5 not equals 5 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID #endif -something to do? -#if 6==6 -6 equals 6 +#ifndef MY_VALUE +#define MY_VALUE true #endif +#if STRIDE_MULTISAMPLE_COUNT == 1 + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); +#else + // TODO: Use SV_SampleIndex + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); #endif \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs b/src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs new file mode 100644 index 0000000000..f34e44944b --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives +{ + public abstract class TokensNode {} +} diff --git a/src/Stride.Shader.Parsing/CommentGrammar.cs b/src/Stride.Shader.Parsing/CommentGrammar.cs deleted file mode 100644 index 924edcaf08..0000000000 --- a/src/Stride.Shader.Parsing/CommentGrammar.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace Stride.Shader.Parsing -{ - public class CommentGrammar : Grammar - { - public SequenceParser Comments = new(); - - public CommentGrammar() : base("comments-sdsl") - { - var commentStart = - Literal("//") - | Literal("/*"); - var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("Comment"); - var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("Comment"); - var anyComments = singleLineComment | blockComment; - var actualCode = AnyChar.Repeat(0).Until(End | "//" | "/*" ).Named("ActualCode"); - Comments.Add( - (anyComments | actualCode).Repeat(0).Until(End) - ); - Inner = Comments; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs deleted file mode 100644 index 28d426fa92..0000000000 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Tokens.cs +++ /dev/null @@ -1,310 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; -public partial class DirectiveGrammar : Grammar -{ - private AlternativeParser Space = new(); - private RepeatParser Spaces = new(); - private SequenceParser SpacesWithLineBreak = new(); - private LiteralTerminal AppendStructuredBuffer = new(); - private AlternativeParser ComponentNumber = new(); - - private LiteralTerminal Bool = new(); - private SequenceParser BoolVec = new(); - private SequenceParser BoolMat = new(); - private AlternativeParser Uint = new(); - private SequenceParser UintVec = new(); - private SequenceParser UintMat = new(); - private LiteralTerminal Int = new(); - private SequenceParser IntVec = new(); - private SequenceParser IntMat = new(); - - private LiteralTerminal Half = new(); - private SequenceParser HalfVec = new(); - private SequenceParser HalfMat = new(); - private LiteralTerminal Float = new(); - private SequenceParser FloatVec = new(); - private SequenceParser FloatMat = new(); - private LiteralTerminal Double = new(); - private SequenceParser DoubleVec = new(); - private SequenceParser DoubleMat = new(); - private LiteralTerminal Buffer = new(); - private LiteralTerminal ByteAddressBuffer = new(); - private LiteralTerminal Break = new(); - private LiteralTerminal Case = new(); - private LiteralTerminal CBuffer = new(); - private LiteralTerminal Centroid = new(); - private LiteralTerminal Class = new(); - private LiteralTerminal ColumnMajor = new(); - private LiteralTerminal Const = new(); - private LiteralTerminal ConsumeStructuredBuffer = new(); - private LiteralTerminal Continue = new(); - private LiteralTerminal Default = new(); - private LiteralTerminal Discard = new(); - private LiteralTerminal Do = new(); - private LiteralTerminal Else = new(); - private LiteralTerminal Extern = new(); - private LiteralTerminal For = new(); - private LiteralTerminal Groupshared = new(); - private LiteralTerminal If = new(); - private LiteralTerminal In = new(); - private AlternativeParser Inout = new(); - private LiteralTerminal InputPatch = new(); - private LiteralTerminal Interface = new(); - - - private LiteralTerminal LineAdj = new(); - private LiteralTerminal Linear = new(); - private LiteralTerminal LineStream = new(); - private LiteralTerminal Long = new(); - private LiteralTerminal Matrix = new(); - private LiteralTerminal Nointerpolation = new(); - private LiteralTerminal Noperspective = new(); - private LiteralTerminal Out = new(); - private LiteralTerminal OutputPatch = new(); - private LiteralTerminal Packoffset = new(); - private LiteralTerminal Point = new(); - private LiteralTerminal PointStream = new(); - private LiteralTerminal Precise = new(); - private LiteralTerminal Register = new(); - private LiteralTerminal Return = new(); - private LiteralTerminal RowMajor = new(); - private LiteralTerminal RWBuffer = new(); - private LiteralTerminal RWByteAddressBuffer = new(); - private LiteralTerminal RWStructuredBuffer = new(); - private LiteralTerminal Sample = new(); - private LiteralTerminal Sampler = new(); - private LiteralTerminal SamplerComparisonState = new(); - private LiteralTerminal SamplerState = new(); - private LiteralTerminal Shared = new(); - private LiteralTerminal StaticConst = new(); - private LiteralTerminal Static = new(); - private LiteralTerminal Struct = new(); - private LiteralTerminal StructuredBuffer = new(); - private LiteralTerminal Switch = new(); - private AlternativeParser TextureTypes = new(); - private LiteralTerminal Triangle = new(); - private LiteralTerminal TriangleAdj = new(); - private LiteralTerminal TriangleStream = new(); - private LiteralTerminal Uniform = new(); - private LiteralTerminal Vector = new(); - private LiteralTerminal Volatile = new(); - private LiteralTerminal Void = new(); - private LiteralTerminal While = new(); - private LiteralTerminal LeftParen = new(); - private LiteralTerminal RightParen = new(); - private LiteralTerminal LeftBracket = new(); - private LiteralTerminal RightBracket = new(); - private LiteralTerminal LeftBrace = new(); - private LiteralTerminal RightBrace = new(); - - private LiteralTerminal LeftShift = new(); - private LiteralTerminal RightShift = new(); - private LiteralTerminal Plus = new(); - private LiteralTerminal PlusPlus = new(); - private LiteralTerminal Minus = new(); - private LiteralTerminal MinusMinus = new(); - private LiteralTerminal Star = new(); - private LiteralTerminal Div = new(); - private LiteralTerminal Mod = new(); - private LiteralTerminal And = new(); - private LiteralTerminal Or = new(); - private LiteralTerminal AndAnd = new(); - private LiteralTerminal OrOr = new(); - private LiteralTerminal Caret = new(); - private LiteralTerminal Not = new(); - private LiteralTerminal Tilde = new(); - private LiteralTerminal Equal = new(); - private LiteralTerminal NotEqual = new(); - private LiteralTerminal Less = new(); - private LiteralTerminal LessEqual = new(); - private LiteralTerminal Greater = new(); - private LiteralTerminal GreaterEqual = new(); - private LiteralTerminal Question = new(); - private LiteralTerminal Colon = new(); - private LiteralTerminal ColonColon = new(); - private LiteralTerminal Semi = new(); - private LiteralTerminal Comma = new(); - private LiteralTerminal Assign = new(); - private LiteralTerminal StarAssign = new(); - private LiteralTerminal DivAssign = new(); - private LiteralTerminal ModAssign = new(); - private LiteralTerminal PlusAssign = new(); - private LiteralTerminal MinusAssign = new(); - private LiteralTerminal LeftShiftAssign = new(); - private LiteralTerminal RightShiftAssign = new(); - private LiteralTerminal AndAssign = new(); - private LiteralTerminal XorAssign = new(); - private LiteralTerminal OrAssign = new(); - - private LiteralTerminal Dot = new(); - private LiteralTerminal True = new(); - private LiteralTerminal False = new(); - private AlternativeParser PreprocessorDirectiveName = new(); - - private LiteralTerminal Stream = new(){Name = "Stream"}; - private LiteralTerminal Stage = new(){Name = "Stage"}; - - - public void CreateTokens() - { - Space = WhiteSpace | Eol; - Spaces = Space.Optional().Repeat(); - SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); - AppendStructuredBuffer = Literal("AppendStructuredBuffer"); - ComponentNumber = Literal("1") | "2" | "3" | "4"; - - Bool = Literal("bool"); - BoolVec.Add(Bool,ComponentNumber); - BoolMat.Add(BoolVec,Literal("x"),ComponentNumber); - Uint.Add("uint","unsigned int", "dword"); - UintVec.Add(Uint,ComponentNumber); - UintMat.Add(UintVec,"x",ComponentNumber); - Int = Literal("int"); - IntVec.Add(Int,ComponentNumber); - IntMat.Add(IntVec,"x",ComponentNumber); - - Half = Literal("half"); - HalfVec.Add(Half, ComponentNumber); - HalfMat.Add(HalfVec, "x", ComponentNumber); - Float = Literal("float"); - FloatVec.Add(Float,ComponentNumber); - FloatMat.Add(FloatVec,"x",ComponentNumber); - Double = Literal("double"); - DoubleVec.Add(Double,ComponentNumber); - DoubleMat.Add(DoubleVec,"x",ComponentNumber); - Buffer = Literal("Buffer"); - ByteAddressBuffer = Literal("ByteAddressBuffer"); - Break = Literal("break"); - Case = Literal("case"); - CBuffer = Literal("cbuffer"); - Centroid = Literal("centroid"); - Class = Literal("class"); - ColumnMajor = Literal("column_major"); - Const = Literal("const"); - ConsumeStructuredBuffer = Literal("ConsumeStructuredBuffer"); - Continue = Literal("continue"); - Default = Literal("default"); - Discard = Literal("discard"); - Do = Literal("do"); - Else = Literal("else"); - Extern = Literal("extern"); - For = Literal("for"); - Groupshared = Literal("groupshared"); - If = Literal("if"); - In = Literal("in"); - Inout = Literal("inout") | "in out"; - InputPatch = Literal("InputPatch"); - Interface = Literal("interface"); - LineAdj = Literal("lineadj"); - Linear = Literal("linear"); - LineStream = Literal("LineStream"); - Long = Literal("long"); - Matrix = Literal("matrix"); - Nointerpolation = Literal("nointerpolation"); - Noperspective = Literal("noperspective"); - Out = Literal("out"); - OutputPatch = Literal("OutputPatch"); - Packoffset = Literal("packoffset"); - Point = Literal("point"); - PointStream = Literal("PointStream"); - Precise = Literal("precise"); - Register = Literal("register"); - Return = Literal("return"); - RowMajor = Literal("row_major"); - RWBuffer = Literal("RWBuffer"); - RWByteAddressBuffer = Literal("RWByteAddressBuffer"); - RWStructuredBuffer = Literal("RWStructuredBuffer"); - Sample = Literal("sample"); - Sampler = Literal("sampler"); - SamplerComparisonState = Literal("SamplerComparisonState"); - SamplerState = Literal("SamplerState"); - Shared = Literal("shared"); - Static = Literal("static"); - StaticConst = Literal("static const"); - Struct = Literal("struct"); - StructuredBuffer = Literal("StructuredBuffer"); - Switch = Literal("switch"); - TextureTypes.Add( - Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional()), - Literal("Texture2DMS").Then(Literal("Array").Optional()), - Literal("TextureCube").Then(Literal("Array").Optional()) - ); - Triangle = Literal("triangle"); - TriangleAdj = Literal("triangleadj"); - TriangleStream = Literal("TriangleStream"); - Uniform = Literal("uniform"); - Vector = Literal("vector"); - Volatile = Literal("volatile"); - Void = Literal("void"); - While = Literal("while"); - LeftParen = Literal("("); - RightParen = Literal(")"); - LeftBracket = Literal("["); - RightBracket = Literal("]"); - LeftBrace = Literal("{"); - RightBrace = Literal("}"); - - LeftShift = Literal("<<"); - RightShift = Literal(">>"); - Plus = Literal("+"); - PlusPlus = Literal("++"); - Minus = Literal("-"); - MinusMinus = Literal("--"); - Star = Literal("*"); - Div = Literal("/"); - Mod = Literal("%"); - And = Literal("&"); - Or = Literal("|"); - AndAnd = Literal("&&"); - OrOr = Literal("||"); - Caret = Literal("^"); - Not = Literal("!"); - Tilde = Literal("~"); - Equal = Literal("=="); - NotEqual = Literal("!="); - Less = Literal("<"); - LessEqual = Literal("<="); - Greater = Literal(">"); - GreaterEqual = Literal(">="); - Question = Literal("?"); - Colon = Literal(":"); - ColonColon = Literal("::"); - Semi = Literal(";"); - Comma = Literal(","); - Assign = Literal("="); - StarAssign = Literal("*="); - DivAssign = Literal("/="); - ModAssign = Literal("%="); - PlusAssign = Literal("+="); - MinusAssign = Literal("-="); - LeftShiftAssign = Literal("<<="); - RightShiftAssign = Literal(">>="); - AndAssign = Literal("&="); - XorAssign = Literal("^="); - OrAssign = Literal("|="); - - Dot = Literal("."); - True = Literal("true"); - False = Literal("false"); - PreprocessorDirectiveName.Add( - Literal("define"), - Literal("elif"), - Literal("else"), - Literal("endif"), - Literal("error"), - Literal("if"), - Literal("ifdef"), - Literal("ifndef"), - Literal("include"), - Literal("line"), - Literal("pragma"), - Literal("undef") - ); - - Stage = Literal("stage"); - Stream = Literal("stream"); - - } -} diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs deleted file mode 100644 index 83dd7f171f..0000000000 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace Stride.Shader.Parsing -{ - public partial class DirectiveGrammar - { - public DirectiveGrammar() - { - CreateAll(); - Inner = Directives; - } - - public void CreateAll() - { - CreateTokens(); - CreateTokenGroups(); - CreateLiterals(); - CreateDirectives(); - CreateDirectiveExpressions(); - } - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs deleted file mode 100644 index 5487e381d5..0000000000 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.TokenGroups.cs +++ /dev/null @@ -1,212 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace Stride.Shader.Parsing; -public partial class DirectiveGrammar : Grammar -{ - public AlternativeParser IncOperators = new(); - - public AlternativeParser Operators = new(); - public AlternativeParser AssignOperators = new(); - - public AlternativeParser BoolTypes = new(); - - public AlternativeParser HalfTypes = new(); - - public AlternativeParser FloatTypes = new(); - - public AlternativeParser DoubleTypes = new(); - - public AlternativeParser IntTypes = new(); - - public AlternativeParser UintTypes = new(); - - public AlternativeParser ValueTypes = new(); - public AlternativeParser StorageFlag = new(); - - public AlternativeParser Keywords = new(); - - public void CreateTokenGroups() - { - IncOperators.Add( - PlusPlus, - MinusMinus - ); - - Operators.Add( - PlusPlus, - Plus, - MinusMinus, - Minus, - Star, - Div, - Mod, - LeftShift, - RightShift, - AndAnd, - And, - OrOr, - Or, - "^", - Equal, - "==", - NotEqual, - Question - - ); - - AssignOperators.Add( - Assign, - StarAssign, - DivAssign, - ModAssign, - PlusAssign, - MinusAssign, - LeftShiftAssign, - RightShiftAssign, - AndAssign, - XorAssign, - OrAssign - ); - - BoolTypes.Add( - Bool.NotFollowedBy(Set("1234")), - BoolVec.NotFollowedBy("x"), - BoolMat - ); - - HalfTypes.Add( - Half.NotFollowedBy(Set("1234")), - HalfVec.NotFollowedBy("x"), - HalfMat - ); - - FloatTypes.Add( - Float.NotFollowedBy(Set("1234")), - FloatVec.NotFollowedBy("x"), - FloatMat - ); - - DoubleTypes.Add( - Double.NotFollowedBy(Set("1234")), - DoubleVec.NotFollowedBy("x"), - DoubleMat - ); - - IntTypes.Add( - Int.NotFollowedBy(Set("1234")), - IntVec.NotFollowedBy("x"), - IntMat - ); - - UintTypes.Add( - Uint.NotFollowedBy(Set("1234")), - UintVec.NotFollowedBy("x"), - UintMat - ); - - ValueTypes.Add( - BoolTypes, - HalfTypes, - FloatTypes, - DoubleTypes, - IntTypes, - UintTypes - ); - - Keywords.Add( - AppendStructuredBuffer, - Buffer, - ByteAddressBuffer, - Break, - Case, - CBuffer, - Centroid, - Class, - ColumnMajor, - Const, - ConsumeStructuredBuffer, - Continue, - Default, - Discard, - Do, - Else, - Extern, - For, - Groupshared, - If, - In, - Inout, - InputPatch, - Interface, - LineAdj, - Linear, - LineStream, - Matrix, - Nointerpolation, - Noperspective, - Out, - OutputPatch, - Packoffset, - Point, - PointStream, - Precise, - Register, - Return, - RowMajor, - RWBuffer, - RWByteAddressBuffer, - RWStructuredBuffer, - Sample, - Sampler, - SamplerComparisonState, - SamplerState, - Shared, - Stage, - Stream, - StaticConst, - Static, - Struct, - StructuredBuffer, - Switch, - TextureTypes, - Triangle, - TriangleAdj, - TriangleStream, - Uniform, - ValueTypes, - Vector, - Volatile, - Void, - While - ); - - StorageFlag.Add( - Literal("constant"), - RowMajor, - ColumnMajor, - Extern, - Precise, - Shared, - Groupshared, - StaticConst, - Static, - Uniform, - Volatile, - Linear, - Centroid, - Nointerpolation, - Noperspective, - Sample, - In.NotFollowedBy(WhiteSpace.Repeat(0) & Out), - Out, - Inout, - Point, - Triangle, - LineAdj, - TriangleAdj - ); - - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs b/src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs new file mode 100644 index 0000000000..e656396f5c --- /dev/null +++ b/src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs @@ -0,0 +1,26 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing.Grammars.Comments; + +public class CommentGrammar : Grammar +{ + public SequenceParser Comments = new(); + + public CommentGrammar() : base("comments-sdsl") + { + var commentStart = + Literal("//") + | Literal("/*"); + var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("Comment"); + var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("Comment"); + var anyComments = singleLineComment | blockComment; + var actualCode = AnyChar.Repeat(0).Until(End | "//" | "/*" ).Named("ActualCode"); + Comments.Add( + (anyComments | actualCode).Repeat(0).Until(End) + ); + Inner = Comments; + } +} diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 98% rename from src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs index 3d9df02df5..8c5827c396 100644 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; @@ -61,7 +61,7 @@ public void CreateDirectiveExpressions() DirectiveTermExpression.Add( Literals, - ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + ~(Plus | Minus & ws) & Identifier.Except(ValueTypes).NotFollowedBy(ws & LeftParen), MethodCall, Parenthesis(DirectiveExpression) ); diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 87% rename from src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index 98408b485f..5c6640a919 100644 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public SequenceParser IfDirective = new(){Name = "IfDirective"}; @@ -66,16 +66,19 @@ public void CreateDirectives() var ifCode = IfDirective & AnyChar.Repeat(0).Until(hashElif | hashElse | hashEndIf).Named("IfCode"); var elifCode = ElifDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("ElifCode"); - var conditional = ifCode & elifCode.Repeat(0).Until(hashElse | hashEndIf) & ~elseCode & EndIfDirective; - var definition = - ifDefCode & - (conditional.Named("Conditional") | AnyChar.Repeat(0).Until(hashEndIf | hashIf).Named("IfDefCode")).Repeat(0).Until(hashEndIf) & - EndIfDirective; + var conditional = ifCode & elifCode.Repeat(0).Until(hashEndIf | hashElse) & ~elseCode & EndIfDirective; + var definition = new SequenceParser( + ifDefCode, + (conditional.Named("Conditional") | AnyChar.Repeat(0).Until(hashEndIf | hashIf).Named("IfDefCode")).Repeat(0).Until(hashElse | hashEndIf), + ~elseCode.Named("ElseIfDef"), + EndIfDirective + ); Directives.Add( AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode"), - definition + (definition.Named("IfDefinition") | conditional.Named("Conditional") | DefineDirective | AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode")) + .Repeat(0).Until(End) ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs new file mode 100644 index 0000000000..7b727a47c7 --- /dev/null +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs @@ -0,0 +1,138 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; +namespace Stride.Shader.Parsing.Grammars.Directive; +public partial class DirectiveGrammar : Grammar +{ + private AlternativeParser Space = new(); + private RepeatParser Spaces = new(); + private SequenceParser SpacesWithLineBreak = new(); + private LiteralTerminal AppendStructuredBuffer = new(); + private AlternativeParser ComponentNumber = new(); + + private LiteralTerminal Bool = new(); + private AlternativeParser Uint = new(); + private LiteralTerminal Int = new(); + private LiteralTerminal Long = new(); + + + private LiteralTerminal Half = new(); + private LiteralTerminal Float = new(); + private LiteralTerminal Double = new(); + + private LiteralTerminal LeftParen = new(); + private LiteralTerminal RightParen = new(); + private LiteralTerminal LeftBracket = new(); + private LiteralTerminal RightBracket = new(); + private LiteralTerminal LeftBrace = new(); + private LiteralTerminal RightBrace = new(); + + private LiteralTerminal LeftShift = new(); + private LiteralTerminal RightShift = new(); + private LiteralTerminal Plus = new(); + private LiteralTerminal PlusPlus = new(); + private LiteralTerminal Minus = new(); + private LiteralTerminal MinusMinus = new(); + private LiteralTerminal Star = new(); + private LiteralTerminal Div = new(); + private LiteralTerminal Mod = new(); + private LiteralTerminal And = new(); + private LiteralTerminal Or = new(); + private LiteralTerminal AndAnd = new(); + private LiteralTerminal OrOr = new(); + private LiteralTerminal Caret = new(); + private LiteralTerminal Not = new(); + private LiteralTerminal Tilde = new(); + private LiteralTerminal Equal = new(); + private LiteralTerminal NotEqual = new(); + private LiteralTerminal Less = new(); + private LiteralTerminal LessEqual = new(); + private LiteralTerminal Greater = new(); + private LiteralTerminal GreaterEqual = new(); + private LiteralTerminal Question = new(); + private LiteralTerminal Colon = new(); + private LiteralTerminal ColonColon = new(); + private LiteralTerminal Semi = new(); + private LiteralTerminal Comma = new(); + private LiteralTerminal Assign = new(); + private LiteralTerminal StarAssign = new(); + private LiteralTerminal DivAssign = new(); + private LiteralTerminal ModAssign = new(); + private LiteralTerminal PlusAssign = new(); + private LiteralTerminal MinusAssign = new(); + private LiteralTerminal LeftShiftAssign = new(); + private LiteralTerminal RightShiftAssign = new(); + private LiteralTerminal AndAssign = new(); + private LiteralTerminal XorAssign = new(); + private LiteralTerminal OrAssign = new(); + + private LiteralTerminal Dot = new(); + + + public void CreateTokens() + { + Space = WhiteSpace | Eol; + Spaces = Space.Optional().Repeat(); + SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); + AppendStructuredBuffer = Literal("AppendStructuredBuffer"); + ComponentNumber = Literal("1") | "2" | "3" | "4"; + + Bool = Literal("bool"); + Uint.Add("uint","unsigned int", "dword"); + Int = Literal("int"); + Long = Literal("long"); + + Half = Literal("half"); + Float = Literal("float"); + Double = Literal("double"); + + LeftParen = Literal("("); + RightParen = Literal(")"); + LeftBracket = Literal("["); + RightBracket = Literal("]"); + LeftBrace = Literal("{"); + RightBrace = Literal("}"); + + LeftShift = Literal("<<"); + RightShift = Literal(">>"); + Plus = Literal("+"); + PlusPlus = Literal("++"); + Minus = Literal("-"); + MinusMinus = Literal("--"); + Star = Literal("*"); + Div = Literal("/"); + Mod = Literal("%"); + And = Literal("&"); + Or = Literal("|"); + AndAnd = Literal("&&"); + OrOr = Literal("||"); + Caret = Literal("^"); + Not = Literal("!"); + Tilde = Literal("~"); + Equal = Literal("=="); + NotEqual = Literal("!="); + Less = Literal("<"); + LessEqual = Literal("<="); + Greater = Literal(">"); + GreaterEqual = Literal(">="); + Question = Literal("?"); + Colon = Literal(":"); + ColonColon = Literal("::"); + Semi = Literal(";"); + Comma = Literal(","); + Assign = Literal("="); + StarAssign = Literal("*="); + DivAssign = Literal("/="); + ModAssign = Literal("%="); + PlusAssign = Literal("+="); + MinusAssign = Literal("-="); + LeftShiftAssign = Literal("<<="); + RightShiftAssign = Literal(">>="); + AndAssign = Literal("&="); + XorAssign = Literal("^="); + OrAssign = Literal("|="); + + Dot = Literal("."); + + } +} diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs new file mode 100644 index 0000000000..e31785a2e8 --- /dev/null +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs @@ -0,0 +1,24 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing.Grammars.Directive; + +public partial class DirectiveGrammar : Grammar +{ + public DirectiveGrammar() + { + CreateAll(); + Inner = Directives; + } + + public void CreateAll() + { + CreateTokens(); + CreateTokenGroups(); + CreateLiterals(); + CreateDirectives(); + CreateDirectiveExpressions(); + } +} diff --git a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 92% rename from src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs index c9e0ee8c38..ab9a90abe6 100644 --- a/src/Stride.Shader.Parsing/DirectiveGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { AlternativeParser IntegerSuffix = new(); @@ -12,7 +12,6 @@ public partial class DirectiveGrammar : Grammar public StringParser StringLiteral = new(); public SequenceParser Identifier = new(); - public AlternativeParser UserDefinedId = new(); public NumberParser IntegerLiteral = new(); public NumberParser FloatLiteral = new(); @@ -29,10 +28,6 @@ public void CreateLiterals() Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier") ); - UserDefinedId.Add( - Identifier.Except(Keywords) - ); - IntegerSuffix.Add( "u", "l", diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs new file mode 100644 index 0000000000..414c8bacfa --- /dev/null +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs @@ -0,0 +1,69 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shader.Parsing.Grammars.Directive; +public partial class DirectiveGrammar : Grammar +{ + public AlternativeParser IncOperators = new(); + + public AlternativeParser Operators = new(); + public AlternativeParser AssignOperators = new(); + + public AlternativeParser ValueTypes = new(); + + public void CreateTokenGroups() + { + IncOperators.Add( + PlusPlus, + MinusMinus + ); + + Operators.Add( + PlusPlus, + Plus, + MinusMinus, + Minus, + Star, + Div, + Mod, + LeftShift, + RightShift, + AndAnd, + And, + OrOr, + Or, + "^", + Equal, + "==", + NotEqual, + Question + + ); + + AssignOperators.Add( + Assign, + StarAssign, + DivAssign, + ModAssign, + PlusAssign, + MinusAssign, + LeftShiftAssign, + RightShiftAssign, + AndAssign, + XorAssign, + OrAssign + ); + + + ValueTypes.Add( + Bool, + Half, + Float, + Double, + Int, + Uint, + Long + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index 13114f5034..c3ed1b93f7 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ShaderValueDeclaration = new() { Name = "ShaderValueDeclaration" }; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 0349bd32b7..c5f159efcd 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs index 0a53075d41..674446feae 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser IfDirective = new(); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 99% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index a690c550f9..56870602bc 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(){Name = "TermExpression"}; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 97% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index 5f117f75c7..3059e099ce 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { AlternativeParser IntegerSuffix = new(); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 63f538be5d..191cb5ad49 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ParameterList = new() {Name = "ParameterList"}; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 20076c55ed..ded9443f12 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 95% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs index 77c5735619..22c099da8d 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ControlFlow = new() { Name = "ControlFlow" }; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 96% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index c506092463..60cb2b3150 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -2,7 +2,8 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; + public partial class SDSLGrammar : Grammar { public AlternativeParser WhileLoop = new() { Name = "ForLoop"}; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 8dde34073f..e03a338d74 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser Attribute = new() { Name = "Attribute" }; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 98% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index e223c7eea7..1faabea81b 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,8 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; + public partial class SDSLGrammar : Grammar { public AlternativeParser IncOperators = new(); diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 99% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index e344880b2a..a7c2c19a55 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -1,7 +1,9 @@ using Eto.Parse; using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing; + +namespace Stride.Shader.Parsing.Grammars.SDSL; + public partial class SDSLGrammar : Grammar { private CharTerminal WS; diff --git a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 94% rename from src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs index 9fe074f7c0..5983f67c0b 100644 --- a/src/Stride.Shader.Parsing/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parsing; +namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SDSLGrammar() : base("sdsl") diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index 6c3625267e..ddf6644d1a 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -2,13 +2,17 @@ namespace Stride.Shader.Parsing; using Eto.Parse; using Eto.Parse.Grammars; +using Stride.Shader.Parsing.Grammars; +using Stride.Shader.Parsing.Grammars.Comments; +using Stride.Shader.Parsing.Grammars.Directive; +using Stride.Shader.Parsing.Grammars.SDSL; using System.Text; public class SDSLParser { public CommentGrammar Comments {get;set;} public SDSLGrammar Grammar {get;set;} public DirectiveGrammar Directive { get;set;} - public IEnumerable Defined { get; set; } + //public IEnumerable Defined { get; set; } public SDSLParser() { From f8419fa3a4531b0a217fe91e29a028bb1479dec6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 23 May 2022 01:04:20 +0200 Subject: [PATCH 0069/1182] Stabilized pre processor --- src/SDSLParserExample/Program.cs | 44 +++++++- src/SDSLParserExample/SDSL/shader2.sdsl | 90 +++++++++++++++- .../AST/Directives/DirectiveNode.cs | 53 ++++++++++ .../{TokensNode.cs => ExpressionNode.cs} | 4 +- .../DirectiveGrammar.Directives.Expression.cs | 41 +++---- .../DirectiveGrammar.Directives.cs | 100 +++++++++++------- src/Stride.Shader.Parsing/SDSLParser.cs | 9 +- 7 files changed, 269 insertions(+), 72 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs rename src/Stride.Shader.Parsing/AST/Directives/{TokensNode.cs => ExpressionNode.cs} (79%) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index f51d1aa0f1..fc91bbe389 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -2,6 +2,30 @@ using Eto.Parse.Grammars; using Stride.Shader.Parsing; using System.Diagnostics; +using System.Linq; + +static void PrettyPrintMatches(Match match, int depth = 0) +{ + Console.ForegroundColor = ConsoleColor.Blue; + Console.Write(new String(' ', depth*4) + match.Name); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); + foreach (var m in match.Matches) + { + if(m.Matches.Count == 1 && m.Name.Contains("Expression")) + { + var tmp = m.Matches[0]; + while(tmp.Matches.Count == 1) + { + tmp = tmp.Matches[0]; + } + PrettyPrintMatches(tmp, depth + 1); + } + else + PrettyPrintMatches(m, depth + 1); + } +} + var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); @@ -14,10 +38,22 @@ var match = parser.Parse(shaderf); s.Stop(); +if (match.Errors.Any()) +{ + Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); + parser.UncommentedCode.ToString().Split("\n").Select((x, i) => (x, i+1)).ToList().ForEach(x => { + Console.ForegroundColor = ConsoleColor.Blue; + Console.Write(x.Item2 + " : "); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(x.x); + }); +} +else +{ + match.Matches.ForEach(x => PrettyPrintMatches(x)); + Console.WriteLine($"parsing time : {s.Elapsed}"); + Console.Write(""); +} -Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); -match.Matches.ForEach(x => Console.WriteLine(x.Name + " : " + x.Value)); -Console.WriteLine($"parsing time : {s.Elapsed}"); -Console.Write(""); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 1f9f327a86..487c3da1db 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,4 +1,19 @@ -#define Something 5 +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.LightProbes +{ + /// + /// Defines a skybox environment light + /// + shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils + { + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes + { #ifdef STRIDE_MULTISAMPLE_COUNT #if STRIDE_MULTISAMPLE_COUNT > 1 stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID @@ -8,12 +23,77 @@ #else stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID #endif -#ifndef MY_VALUE -#define MY_VALUE true -#endif + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients + } + + void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) + { + // Early exit + if (weight == 0.0f) + return; + + int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; + for (int i = 0; i < TOrder * TOrder; ++i) + { + // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly + sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; + } + } + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + var ambientAccessibility = streams.matAmbientOcclusion; + + var sampleDirection = streams.normalWS; + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + var shadingPosition = int3(streams.ShadingPosition.xy, 0); #if STRIDE_MULTISAMPLE_COUNT == 1 uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); #else // TODO: Use SV_SampleIndex uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); -#endif \ No newline at end of file +#endif + + uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); + float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); + + float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); + + // Protect ourselves against degenerate cases + // TODO: Investigate why those happen (almost coplanar tetrahedron?) + tetrahedronFactors3 = saturate(tetrahedronFactors3); + + float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); + + // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) + tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Renormalize barycentric coordinates + var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; + if (totalSum > 0.0f) + tetrahedronFactors4 /= totalSum; + + float3 sphericalColors[TOrder * TOrder]; + for (int i = 0; i < TOrder * TOrder; ++i) + sphericalColors[i] = 0.0f; + + FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); + FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); + FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); + FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); + + streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + // TEST: + //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + //streams.envLightDiffuseColor = tetrahedronFactors3; + //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); + } + }; +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs new file mode 100644 index 0000000000..04c13c78cc --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives +{ + public abstract class DirectiveNode {} + public class CodeSnippet : DirectiveNode + { + public string? Code { get; set; } + } + public abstract class DirectiveWithCodeNode : DirectiveNode + { + List CodeSnippets { get; set; } = new(); + } + public abstract class DirectiveWithChildren : DirectiveWithCodeNode + { + List Children { get; set; } = new(); + } + + public class IfDefNode : DirectiveWithChildren + { + public string ValueName { get; set; } + } + public class IfNDefNode : DirectiveWithChildren + { + public string ValueName { get; set; } + } + public class SimpleDefineNode : DirectiveNode + { + public string Name { get; set; } + } + + public class DefineNode : DirectiveNode + { + public string Name { get; set; } + public T Value { get; set; } + } + + public class IfNode : DirectiveWithChildren + { + public ExpressionNode Expression { get; set; } + } + public class ElIfNode : DirectiveWithChildren + { + public ExpressionNode Expression { get; set; } + } + public class ElseNode : DirectiveNode + { + } +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs b/src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs similarity index 79% rename from src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs rename to src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs index f34e44944b..d96fc3d150 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/TokensNode.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs @@ -6,5 +6,7 @@ namespace Stride.Shader.Parsing.AST.Directives { - public abstract class TokensNode {} + public class ExpressionNode + { + } } diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs index 8c5827c396..d73aa27370 100644 --- a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs @@ -126,46 +126,47 @@ public void CreateDirectiveExpressions() var mulOp = Star | Div | Mod; DirectiveMulExpression.Add( - (Parenthesis(DirectiveExpression) | DirectiveCastExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws) + DirectiveCastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws).Until(ws & (Eol | End)) ); var sumOp = Plus | Minus; DirectiveSumExpression.Add( - DirectiveMulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws) + DirectiveMulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws).Until(ws & (Eol | End)) ); var shiftOp = LeftShift | RightShift; DirectiveShiftExpression.Add( - DirectiveSumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws) + DirectiveSumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws).Until(ws & (Operators | Eol | End)) ); DirectiveAndExpression.Add( - DirectiveShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws) + DirectiveShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws).Until(ws & (Eol | End)) ); DirectiveXorExpression.Add( - DirectiveAndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws) + DirectiveAndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws).Until(ws & (Eol | End)) ); DirectiveOrExpression.Add( - DirectiveXorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws) + DirectiveXorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws).Until(ws & (Eol | End)) ); var testOp = LessEqual | Less | GreaterEqual | Greater; DirectiveTestExpression.Add( - DirectiveOrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws) + DirectiveOrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws).Until(ws & (Eol | End)) ); var eqOp = @@ -173,17 +174,17 @@ public void CreateDirectiveExpressions() | Literal("!="); DirectiveEqualsExpression.Add( - DirectiveTestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws) + DirectiveTestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws).Until(ws & (Eol | End)) ); DirectiveLogicalAndExpression.Add( - DirectiveEqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws) + DirectiveEqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws).Until(ws & (Eol | End)) ); DirectiveLogicalOrExpression.Add( - DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) + DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws).Until(ws & (Eol | End)), + Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws).Until(ws & (Eol | End)) ); DirectiveConditionalExpression.Add( @@ -208,7 +209,7 @@ public void CreateDirectiveExpressions() .SeparatedBy(ws); DirectiveExpression.Add( - arrayDeclaration, + BooleanTerm, DirectiveConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index 5c6640a919..c7669ca915 100644 --- a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -15,8 +15,15 @@ public partial class DirectiveGrammar : Grammar public SequenceParser IfDefDirective = new() { Name = "IfDefDirective" }; public SequenceParser IfNDefDirective = new(){Name = "IfNDefDirective"}; + public SequenceParser IfDefCode = new() { Name = "IfDefCode" }; + public SequenceParser ElseCode = new() { Name = "ElseCode" }; + public SequenceParser IfCode = new() { Name = "IfCode" }; + public SequenceParser ElifCode = new() { Name = "ElifCode" }; + + public SequenceParser ConditionalDirectives = new(){Name = "ConditionalDirectives"}; - public SequenceParser DefineDirectives = new(){Name = "DefineDirectives"}; + public SequenceParser DefinitionDirectives = new(){Name = "DefineDirectives"}; + public AlternativeParser AnyDirectives = new AlternativeParser(); public SequenceParser Directives = new(); @@ -24,14 +31,28 @@ public void CreateDirectives() { var ls = SingleLineWhiteSpace.Repeat(0); var ls1 = SingleLineWhiteSpace.Repeat(1); + var ws = WhiteSpace.Repeat(0); + var hash = Literal("#"); - var hashIfNDef = Literal("#ifndef").Named("hashifndef"); - var hashIfDef = Literal("#ifdef").Named("hashifdef"); - var hashIf = Literal("#if").Named("hashif"); - var hashEndIf = Literal("#endif").Named("HashEndIf"); - var hashElse = Literal("#else").Named("HashElse"); - var hashElif = Literal("#elif").Named("HashElif"); - var hashDefine = Literal("#define").Named("HashElif"); + var hashIfNDef = Literal("#ifndef"); + var hashIfDef = Literal("#ifdef"); + var hashIf = Literal("#if"); + var hashEndIf = Literal("#endif"); + var hashElse = Literal("#else"); + var hashElif = Literal("#elif"); + var hashDefine = Literal("#define"); + + var startHash = + hashIfNDef + | hashIfDef + | hashIf + | hashDefine; + + var anyHash = + startHash + | hashElif + | hashElse + | hashEndIf; IfDirective.Add(hashIf, ls1, DirectiveExpression, ls.Until(Eol | End, true)); ElseDirective.Add(hashElse, ls.Until(Eol | End, true)); @@ -39,46 +60,51 @@ public void CreateDirectives() EndIfDirective.Add(hashEndIf, ls.Until(Eol | End, true)); IfDefDirective.Add(hashIfDef, ls1, Identifier, ls.Until(Eol | End, true)); IfNDefDirective.Add(hashIfNDef, ls1, Identifier, ls.Until(Eol | End, true)); - DefineDirective.Add(hashDefine, ls1, Identifier, ls1, DirectiveExpression, ls.Until(Eol | End, true)); + DefineDirective.Add(hashDefine, ls1, Identifier, ~(ls1 & DirectiveExpression), ls.Until(Eol | End)); + + - var anyChars = AnyChar.Repeat(0); + var CodeOrDirective = + AnyDirectives + .Or(AnyChar.Repeat(0).Until(startHash | End).Named("CodeSnippet")) + .Repeat(1).Until(End); - var elseList = new AlternativeParser( - (ElifDirective & anyChars.Until(hashElif | hashElse | hashEndIf).Named("ElifCode")).Repeat(), - ElseDirective & anyChars.Until(hashEndIf).Named("ElseCode") + IfDefCode.Add( + IfDefDirective | IfNDefDirective, + AnyDirectives.Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) + .Repeat(0).Until(hashElse | hashEndIf).Named("Children"), + EndIfDirective | ElseCode & EndIfDirective ); - ConditionalDirectives.Add( - IfDirective, - anyChars.Until(hashElif | hashElse | hashEndIf).Named("IfCode"), - ~elseList, - EndIfDirective + ElseCode.Add( + ElseDirective, + AnyDirectives + .Or(AnyChar.Repeat(0).Until(startHash)) + .Repeat(0).Until(hashEndIf) ); - DefineDirectives.Add( - IfDefDirective | IfNDefDirective, - ConditionalDirectives | DefineDirective | anyChars.Repeat(0).Until(hashElse | hashEndIf), - ~(ElseDirective & anyChars.Repeat().Until(EndIfDirective)), - EndIfDirective + + IfCode.Add( + IfDirective, + AnyDirectives.Or(AnyChar.Repeat(0).Until(anyHash).Named("CodeSnippet")) + .Repeat(0).Until(hashElif | hashElse | hashEndIf).Named("Children"), + ElifCode.Repeat(0), + EndIfDirective | ElseCode & EndIfDirective ); - var ifDefCode = (IfDefDirective | IfNDefDirective) & AnyChar.Repeat(0).Until(hashDefine | hashIf | hashElse | hashEndIf).Named("IfDefCode"); - var elseCode = ElseDirective & AnyChar.Repeat(0).Until(hashEndIf).Named("ElseCode"); - var ifCode = IfDirective & AnyChar.Repeat(0).Until(hashElif | hashElse | hashEndIf).Named("IfCode"); - var elifCode = ElifDirective & AnyChar.Repeat(0).Until(hashElif | hashElse).Named("ElifCode"); - - var conditional = ifCode & elifCode.Repeat(0).Until(hashEndIf | hashElse) & ~elseCode & EndIfDirective; - var definition = new SequenceParser( - ifDefCode, - (conditional.Named("Conditional") | AnyChar.Repeat(0).Until(hashEndIf | hashIf).Named("IfDefCode")).Repeat(0).Until(hashElse | hashEndIf), - ~elseCode.Named("ElseIfDef"), - EndIfDirective + ElifCode.Add( + ElifDirective, + AnyDirectives.Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) + .Repeat(0).Until(hashElse | hashEndIf).Named("Children") ); + AnyDirectives.Add( + DefineDirective, + IfDefCode, + IfCode + ); Directives.Add( - AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode"), - (definition.Named("IfDefinition") | conditional.Named("Conditional") | DefineDirective | AnyChar.Repeat(0).Until(End | hashIf | hashIfDef | hashIfNDef | hashDefine).Named("UnchangedCode")) - .Repeat(0).Until(End) + CodeOrDirective.Until(End) ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index ddf6644d1a..da79c11b27 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -12,6 +12,7 @@ public class SDSLParser public CommentGrammar Comments {get;set;} public SDSLGrammar Grammar {get;set;} public DirectiveGrammar Directive { get;set;} + public StringBuilder UncommentedCode { get; set; } = new(); //public IEnumerable Defined { get; set; } public SDSLParser() @@ -30,24 +31,22 @@ public SDSLParser With(Parser p) public GrammarMatch Parse(string shader) { var comments = Comments.Match(shader); - var preprocessed = new StringBuilder(); + //var preprocessed = new StringBuilder(); if (!comments.Matches.Any(x => x.Name == "Comment")) { return Directive.Match(shader); } else { - var actualCode = new StringBuilder(); foreach (var m in comments.Matches) { if (m.Name == "ActualCode") { - actualCode.AppendLine(m.StringValue); + UncommentedCode.AppendLine(m.StringValue); } - } //preprocessed.Add(this.PreProcessor()) - return PreProcessor(actualCode.ToString()); + return PreProcessor(UncommentedCode.ToString()); } } From 26acea382341cc0badfa2b57badd1d1e4d84d06d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 10:25:48 +0200 Subject: [PATCH 0070/1182] First AST for expression --- src/SDSLParserExample/Program.cs | 46 +- .../BasicExpressionParsing.cs | 2 +- .../AST/Directives/DirectiveASTBuilder.cs | 26 ++ .../AST/Directives/DirectiveNode.cs | 81 +++- .../AST/Expressions/ExpressionToken.cs | 34 ++ .../AST/Expressions/Literals.cs | 91 ++++ .../AST/Expressions/Operations.cs | 411 ++++++++++++++++++ src/Stride.Shader.Parsing/ExpressionParser.cs | 20 + .../DirectiveGrammar.Directives.cs | 2 +- .../Grammars/ExpressionGrammar.cs | 17 + .../SDSLGrammar/SDSLGrammar.Expression.cs | 29 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 17 +- 12 files changed, 709 insertions(+), 67 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs create mode 100644 src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs create mode 100644 src/Stride.Shader.Parsing/AST/Expressions/Literals.cs create mode 100644 src/Stride.Shader.Parsing/AST/Expressions/Operations.cs create mode 100644 src/Stride.Shader.Parsing/ExpressionParser.cs create mode 100644 src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index fc91bbe389..ece0cf44db 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -1,15 +1,17 @@ using Eto.Parse; using Eto.Parse.Grammars; using Stride.Shader.Parsing; +using Stride.Shader.Parsing.Grammars.Expression; using System.Diagnostics; using System.Linq; static void PrettyPrintMatches(Match match, int depth = 0) { Console.ForegroundColor = ConsoleColor.Blue; - Console.Write(new String(' ', depth*4) + match.Name); + Console.Write(new string(' ', depth*4) + match.Name); Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); + Console.WriteLine(" : " + match.StringValue); + //Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); foreach (var m in match.Matches) { if(m.Matches.Count == 1 && m.Name.Contains("Expression")) @@ -30,30 +32,30 @@ static void PrettyPrintMatches(Match match, int depth = 0) var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); -var parser = new SDSLParser(); +var parser = new ExpressionParser(); //new SDSLParser(); //parser.Grammar.Using(parser.Grammar.ShaderValueDeclaration); var s = new Stopwatch(); -var match2 = parser.Parse("shader MyShader : Something {}"); +//var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); -var match = parser.Parse(shaderf); +var match = parser.Parse("5+5;"); s.Stop(); - -if (match.Errors.Any()) -{ - Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); - parser.UncommentedCode.ToString().Split("\n").Select((x, i) => (x, i+1)).ToList().ForEach(x => { - Console.ForegroundColor = ConsoleColor.Blue; - Console.Write(x.Item2 + " : "); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(x.x); - }); -} -else -{ - match.Matches.ForEach(x => PrettyPrintMatches(x)); - Console.WriteLine($"parsing time : {s.Elapsed}"); - Console.Write(""); -} +Console.WriteLine(match); +//if (match.Errors.Any()) +//{ +// Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); +// //parser.UncommentedCode.ToString().Split("\n").Select((x, i) => (x, i+1)).ToList().ForEach(x => { +// // Console.ForegroundColor = ConsoleColor.Blue; +// // Console.Write(x.Item2 + " : "); +// // Console.ForegroundColor = ConsoleColor.White; +// // Console.WriteLine(x.x); +// //}); +//} +//else +//{ +// match.Matches.ForEach(x => PrettyPrintMatches(x)); +// Console.WriteLine($"parsing time : {s.Elapsed}"); +// Console.Write(""); +//} diff --git a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs index fa9debac0b..7526494a22 100644 --- a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs @@ -35,7 +35,7 @@ public void TestTerms() [Fact] public void TestPostfix() { - parser.Grammar.Using(parser.Grammar.PostFixExpression.Then(";")); + parser.Grammar.Using(parser.Grammar.PostfixExpression.Then(";")); List matches = new(){ parser.Parse("my_var++;"), parser.Parse("my_var.a;"), diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs new file mode 100644 index 0000000000..aa44d69b78 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Eto.Parse.Ast; + +namespace Stride.Shader.Parsing.AST.Directives +{ + public class DirectiveASTBuilder : AstBuilder + { + public DirectiveASTBuilder() + { + var token = new Builder(); + + var shaderProgram = Create("shader", () => new Shader()); + shaderProgram.Children().HasMany().Builders.Add( + token + ); + + //token.Create("CodeSnippet", () => new CodeSnippet()).Property((o, v) => o.Snippet = v); + //token.Create("Define", () => new Define()).Property<> + + } + } +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs index 04c13c78cc..14cc817cd7 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs @@ -1,53 +1,88 @@ -using System; +using Eto.Parse; +using Stride.Shader.Parsing.Grammars.Directive; +using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives +namespace Stride.Shader.Parsing.AST.Directives; + +public abstract class DirectiveToken { }; + +public class CodeSnippet : DirectiveToken +{ + public string Snippet { get; set; } +} + +public class Define : DirectiveToken { - public abstract class DirectiveNode {} - public class CodeSnippet : DirectiveNode + public string Variable { get; set; } + public int Value { get; set; } +} + +public class Shader : DirectiveToken, IList, ICollection +{ + List nodes = new List(); + + + #region list & collection impl + + public DirectiveToken this[int index] { get => nodes[index]; set{ nodes[index] = value; } } + + public int Count => nodes.Count; + + public bool IsReadOnly => ((ICollection)nodes).IsReadOnly; + + public void Add(DirectiveToken item) { - public string? Code { get; set; } + nodes.Add(item); } - public abstract class DirectiveWithCodeNode : DirectiveNode + + public void Clear() { - List CodeSnippets { get; set; } = new(); + nodes.Clear(); } - public abstract class DirectiveWithChildren : DirectiveWithCodeNode + + public bool Contains(DirectiveToken item) { - List Children { get; set; } = new(); + return nodes.Contains(item); } - public class IfDefNode : DirectiveWithChildren + public void CopyTo(DirectiveToken[] array, int arrayIndex) { - public string ValueName { get; set; } + nodes.CopyTo(array,arrayIndex); } - public class IfNDefNode : DirectiveWithChildren + + public IEnumerator GetEnumerator() { - public string ValueName { get; set; } + return nodes.GetEnumerator(); } - public class SimpleDefineNode : DirectiveNode + + public int IndexOf(DirectiveToken item) { - public string Name { get; set; } + return nodes.IndexOf(item); } - public class DefineNode : DirectiveNode + public void Insert(int index, DirectiveToken item) { - public string Name { get; set; } - public T Value { get; set; } + nodes.Insert(index,item); } - public class IfNode : DirectiveWithChildren + public bool Remove(DirectiveToken item) { - public ExpressionNode Expression { get; set; } + return nodes.Remove(item); } - public class ElIfNode : DirectiveWithChildren + + public void RemoveAt(int index) { - public ExpressionNode Expression { get; set; } + nodes.RemoveAt(index); } - public class ElseNode : DirectiveNode + + IEnumerator IEnumerable.GetEnumerator() { + throw new NotImplementedException(); } + #endregion } diff --git a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs new file mode 100644 index 0000000000..ba79b302f0 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs @@ -0,0 +1,34 @@ +using Eto.Parse; +using Stride.Shader.Parsing.Grammars.Expression; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Expressions; + +public abstract class ExpressionToken +{ + static ExpressionGrammar grammar; + protected static ExpressionGrammar Grammar { get { return grammar ??= new ExpressionGrammar(); } } + + public Match Match { get; set; } + + public static ExpressionToken Parse(string expr) + { + var match = Grammar.Match(expr); + if (!match.Success) + throw new ArgumentOutOfRangeException("expr", string.Format("Invalid expr string: {0}", match.ErrorMessage)); + return GetToken(match.Matches.First()); + } + + internal static ExpressionToken GetToken(Match match) + { + return match.Name switch + { + "PrimaryExpression" => PrimaryExpression.GetSubToken(match), + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs b/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs new file mode 100644 index 0000000000..0de56abb4d --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs @@ -0,0 +1,91 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Expressions; + +public class NumberLiteral : ExpressionToken +{ + public bool Negative { get; set; } = false; + public object? Value { get; set; } + public string? Suffix { get; set; } + + + public NumberLiteral() { } + + public NumberLiteral(Match match) + { + Match = match; + if (!match.HasMatches) + { + Value = match.Value; + } + else + { + if (match.Name == "SignedTermExpression") + { + + } + else + { + Value = match.Matches[0].Value; + Suffix = match["Suffix"].StringValue; + } + } + } +} +public class HexLiteral : ExpressionToken +{ + public ulong Value { get; set; } + + public HexLiteral() { } + + public HexLiteral(Match match) + { + Match = match; + Value = Convert.ToUInt64(match.StringValue, 16); + } +} +public class StringLiteral : ExpressionToken +{ + public string? Value { get; set; } + + + public StringLiteral() { } + + public StringLiteral(Match match) + { + Match = match; + Value = match.StringValue; + } +} + +public class BoolLiteral : ExpressionToken +{ + public bool Value { get; set; } + + public BoolLiteral() { } + + public BoolLiteral(Match match) + { + Match = match; + Value = (bool)match.Value; + } +} + + +public class Literals +{ + public static ExpressionToken GetSubToken(Match m) + { + return m.Name switch + { + "IntegerLiteral" or "FloatLiteral" => new NumberLiteral(m), + "StringLiteral" => new StringLiteral(m), + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs new file mode 100644 index 0000000000..a13769796a --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs @@ -0,0 +1,411 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Expressions; + +public class Operation : ExpressionToken +{ + public string Op { get; set; } + public ExpressionToken Left { get; set; } + public ExpressionToken Right { get; set; } +} + +public class TermExpression +{ + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Name: "Literals" } => Literals.GetSubToken(m.Matches[0]), + { Name: "IntegerLiteral" } => new NumberLiteral(m), + + //{ Name: "VariableTerm" } => new VariableTerm(m.Matches[0]), + _ => throw new NotImplementedException() + }; + } +} + + +public class PrefixIncrement : ExpressionToken +{ + public string Operator { get; set; } + public string Name { get; set; } + public PrefixIncrement(Match m) + { + Match = m; + Operator = m.Matches[0].StringValue; + Name = m.Matches[1].StringValue; + } +} + +public class PostfixExpression : ExpressionToken +{ + + public PostfixExpression(Match m) + { + + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Name: "TermExpression" } => TermExpression.GetSubToken(m.Matches[0]), + //{ Name: "PostfixIncrement" } => new PostfixIncrement(m.Matches[0]), + //{ Name: "ArrayAccessor" } => new ArrayAccessor(m.Matches[0]), + //{ Name: "AccessorChain" } => new AccessorChain(m.Matches[0]), + _ => throw new NotImplementedException() + }; + } + +} + +public static class UnaryExpression +{ + public static ExpressionToken GetSubToken(Match m) + { + + return m switch + { + { Name: "PostfixExpression" } => PostfixExpression.GetSubToken(m.Matches[0]), + { Name: "PrefixIncrement" } => new PrefixIncrement(m), + _ => throw new NotImplementedException() + }; + } +} + +public class CastExpression : ExpressionToken +{ + public CastExpression(Match m) + { + // TODO implement cast + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => UnaryExpression.GetSubToken(m.Matches[0].Matches[0]), + { Matches.Count: > 1 } => new CastExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class MulExpression : ExpressionToken +{ + public Operation Operations; + public MulExpression(Match m) + { + var first = new Operation + { + Op = m.Matches[1].StringValue, + Left = OrExpression.GetSubToken(m.Matches[0]), + Right = OrExpression.GetSubToken(m.Matches[2]) + }; + + Operation tmp = first; + for (int i = 3; i < m.Length - 2; i += 2) + { + tmp = new Operation + { + Op = m.Matches[i].StringValue, + Left = tmp, + Right = OrExpression.GetSubToken(m.Matches[i + 1]) + }; + } + Operations = tmp; + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => CastExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new MulExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class SumExpression : ExpressionToken +{ + public Operation Operations; + public SumExpression(Match m) + { + var first = new Operation + { + Op = m.Matches[1].StringValue, + Left = MulExpression.GetSubToken(m.Matches[0]), + Right = MulExpression.GetSubToken(m.Matches[2]) + }; + + Operation tmp = first; + for (int i = 3; i < m.Length - 2; i += 2) + { + tmp = new Operation + { + Op = m.Matches[i].StringValue, + Left = tmp, + Right = MulExpression.GetSubToken(m.Matches[i + 1]) + }; + } + Operations = tmp; + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => MulExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new SumExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class ShiftExpression : ExpressionToken +{ + public Operation Operations; + public ShiftExpression(Match m) + { + var first = new Operation + { + Op = m.Matches[1].StringValue, + Left = SumExpression.GetSubToken(m.Matches[0]), + Right = SumExpression.GetSubToken(m.Matches[2]) + }; + + Operation tmp = first; + for (int i = 3; i < m.Length - 2; i += 2) + { + tmp = new Operation + { + Op = m.Matches[i].StringValue, + Left = tmp, + Right = ShiftExpression.GetSubToken(m.Matches[i + 1]) + }; + } + Operations = tmp; + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => SumExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new ShiftExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class AndExpression : ExpressionToken +{ + public IEnumerable Values; + public AndExpression(Match m) + { + Values = m.Matches.Where(x => x.Name != "Operator").Select(ShiftExpression.GetSubToken); + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => ShiftExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new AndExpression(m), + _ => throw new NotImplementedException() + }; + } +} +public class XorExpression : ExpressionToken +{ + public IEnumerable Values; + public XorExpression(Match m) + { + Values = m.Matches.Where(x => x.Name != "Operator").Select(AndExpression.GetSubToken); + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => AndExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new XorExpression(m), + _ => throw new NotImplementedException() + }; + } +} +public class OrExpression : ExpressionToken +{ + public IEnumerable Values; + public OrExpression(Match m) + { + Values = m.Matches.Where(x => x.Name != "Operator").Select(XorExpression.GetSubToken); + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => XorExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new OrExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class TestExpression : ExpressionToken +{ + public Operation Operations; + public TestExpression(Match m) + { + var first = new Operation + { + Op = m.Matches[1].StringValue, + Left = OrExpression.GetSubToken(m.Matches[0]), + Right = OrExpression.GetSubToken(m.Matches[2]) + }; + + Operation tmp = first; + for (int i = 3; i < m.Length - 2; i += 2) + { + tmp = new Operation + { + Op = m.Matches[i].StringValue, + Left = tmp, + Right = OrExpression.GetSubToken(m.Matches[i + 1]) + }; + } + Operations = tmp; + + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => OrExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new TestExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class EqualsExpression : ExpressionToken +{ + public Operation Operations; + public EqualsExpression(Match m) + { + var first = new Operation + { + Op = m.Matches[1].StringValue, + Left = TestExpression.GetSubToken(m.Matches[0]), + Right = TestExpression.GetSubToken(m.Matches[2]) + }; + + Operation tmp = first; + for (int i = 3; i < m.Length - 2; i += 2) + { + tmp = new Operation + { + Op = m.Matches[i].StringValue, + Left = tmp, + Right = TestExpression.GetSubToken(m.Matches[i + 1]) + }; + } + Operations = tmp; + + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => TestExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new EqualsExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class LogicalAndExpression : ExpressionToken +{ + public IEnumerable Values; + public LogicalAndExpression(Match m) + { + Values = m.Matches.Where(x => x.Name != "Operator").Select(EqualsExpression.GetSubToken); + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count: 1 } => EqualsExpression.GetSubToken(m.Matches[0]), + { Matches.Count: > 1 } => new LogicalAndExpression(m), + _ => throw new NotImplementedException() + }; + } +} +public class LogicalOrExpression : ExpressionToken +{ + public IEnumerable Values; + public LogicalOrExpression(Match m) + { + Values = m.Matches.Where(x => x.Name != "Operator").Select(LogicalAndExpression.GetSubToken); + } + + public static ExpressionToken GetSubToken(Match m) + { + return m switch + { + { Matches.Count : 1} => LogicalAndExpression.GetSubToken(m.Matches[0]), + { Matches.Count: >1} => new LogicalOrExpression(m), + _ => throw new NotImplementedException() + }; + } +} + +public class ConditionalExpression : ExpressionToken +{ + public ExpressionToken Condition { get; set; } + public ExpressionToken TrueOutput { get; set; } + public ExpressionToken FalseOutput { get; set; } + + + public ConditionalExpression(Match m) + { + Condition = LogicalOrExpression.GetSubToken(m.Matches[0]); + TrueOutput = LogicalOrExpression.GetSubToken(m.Matches[1]); + FalseOutput = LogicalOrExpression.GetSubToken(m.Matches[2]); + } + + public static ExpressionToken GetSubToken(Match m) + { + var tmp = m.Matches[0]; + return tmp switch + { + { Name: "LogicalOrExpression", Matches.Count: 1} => LogicalOrExpression.GetSubToken(m.Matches[0]), + { Name: "Ternary" } => new ConditionalExpression(tmp), + _ => throw new NotImplementedException() + }; + } +} + + +public class PrimaryExpression : ExpressionToken +{ + public static ExpressionToken GetSubToken(Match m) + { + return m.Matches[0].Name switch + { + "ConditionalExpression" => ConditionalExpression.GetSubToken(m.Matches[0]), + _ => throw new NotImplementedException() + }; + } +} + diff --git a/src/Stride.Shader.Parsing/ExpressionParser.cs b/src/Stride.Shader.Parsing/ExpressionParser.cs new file mode 100644 index 0000000000..fd29f5de73 --- /dev/null +++ b/src/Stride.Shader.Parsing/ExpressionParser.cs @@ -0,0 +1,20 @@ +namespace Stride.Shader.Parsing; + +using Eto.Parse; +using Eto.Parse.Grammars; +using Stride.Shader.Parsing.AST.Expressions; +using Stride.Shader.Parsing.Grammars; +using Stride.Shader.Parsing.Grammars.Comments; +using Stride.Shader.Parsing.Grammars.Directive; +using Stride.Shader.Parsing.Grammars.Expression; +using Stride.Shader.Parsing.Grammars.SDSL; +using System.Text; +public class ExpressionParser +{ + //public IEnumerable Defined { get; set; } + + public ExpressionToken Parse(string expr) + { + return ExpressionToken.Parse(expr); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index c7669ca915..ed01b762e9 100644 --- a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -79,7 +79,7 @@ public void CreateDirectives() ElseCode.Add( ElseDirective, AnyDirectives - .Or(AnyChar.Repeat(0).Until(startHash)) + .Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) .Repeat(0).Until(hashEndIf) ); diff --git a/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs b/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs new file mode 100644 index 0000000000..6ee8dbbe9d --- /dev/null +++ b/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs @@ -0,0 +1,17 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using Stride.Shader.Parsing.Grammars.SDSL; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing.Grammars.Expression; + +public class ExpressionGrammar : SDSLGrammar +{ + public ExpressionGrammar() + { + Name = "expression"; + CreateAll(); + Inner = PrimaryExpression.Then(";"); + } +} diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 56870602bc..9c09509fea 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -6,7 +6,7 @@ namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(){Name = "TermExpression"}; - public AlternativeParser PostFixExpression = new(){Name = "PostFixExpression"}; + public AlternativeParser PostfixExpression = new(){Name = "PostfixExpression"}; public AlternativeParser UnaryExpression = new(){Name = "UnaryExpression"}; public AlternativeParser CastExpression = new(){Name = "CastExpression"}; public AlternativeParser MulExpression = new(){Name = "MulExpression"}; @@ -67,7 +67,7 @@ public void CreateExpressions() TermExpression.Add( Literals, - ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); @@ -94,8 +94,9 @@ public void CreateExpressions() incrementOp.Named("Operator") ); - PostFixExpression.Add( + PostfixExpression.Add( TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), + ((Plus | Minus).Named("Sign") & ws & TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp))).Named("SignedTermExpression"), postfixInc.Named("PostfixIncrement"), chain.Named("AccessorChain"), arrayAccess.Named("ArrayAccesor") @@ -111,7 +112,7 @@ public void CreateExpressions() ); UnaryExpression.Add( - PostFixExpression, + PostfixExpression, prefixInc.Named("PrefixIncrement"), Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") ); @@ -192,16 +193,18 @@ public void CreateExpressions() Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws) ); - ConditionalExpression.Add( + var ternary = new SequenceParser( + Parenthesis(LogicalOrExpression) | LogicalOrExpression, + Question, + Parenthesis(LogicalOrExpression) | LogicalOrExpression, + Colon, + Parenthesis(LogicalOrExpression) | LogicalOrExpression + ){ Separator = ws, Name = "Ternary"}; + + + ConditionalExpression.Add( LogicalOrExpression.NotFollowedBy(ws & "?"), - (Parenthesis(LogicalOrExpression).NotFollowedBy(ws & OrOr) | LogicalOrExpression) - .Then("?") - .Then(CastExpression | ParenExpression | LogicalOrExpression) - .Then(":") - .Then(CastExpression | ParenExpression | LogicalOrExpression) - .SeparatedBy(ws) - .Named("Ternary") - + ternary ); ParenExpression.Add( diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index 3059e099ce..57a4c33606 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -7,8 +7,8 @@ namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { - AlternativeParser IntegerSuffix = new(); - AlternativeParser FloatSuffix = new(); + AlternativeParser IntegerSuffix = new() { Name = "Suffix"}; + AlternativeParser FloatSuffix = new() { Name = "Suffix"}; public StringParser StringLiteral = new(); public SequenceParser Identifier = new(); @@ -55,17 +55,20 @@ public void CreateLiterals() StringLiteral = new StringParser().WithName("StringLiteral"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); + IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "IntegerValue" }; + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "FloatValue" }; + HexDigits = new(); HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; Literals.Add( - IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Named("IntegerLiteral"), - FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral"), - HexaDecimalLiteral, + IntegerLiteral.NotFollowedBy(Dot | IntegerSuffix | FloatSuffix | Set("xX")).Named("IntegerLiteral"), + IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Then(IntegerSuffix).Named("IntegerLiteral"), + FloatLiteral.NotFollowedBy(Set("xX")).Named("FloatLiteral"), + FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix).Named("FloatLiteral"), + HexaDecimalLiteral, StringLiteral ); } From ae2c2a2ace26ba86190863a76052c78441b541c0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 10:35:05 +0200 Subject: [PATCH 0071/1182] Correction operations --- src/SDSLParserExample/Program.cs | 2 +- .../AST/Expressions/Operations.cs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index ece0cf44db..5230d974a7 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -37,7 +37,7 @@ static void PrettyPrintMatches(Match match, int depth = 0) var s = new Stopwatch(); //var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); -var match = parser.Parse("5+5;"); +var match = parser.Parse("5<<5%3;"); s.Stop(); Console.WriteLine(match); //if (match.Errors.Any()) diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs index a13769796a..52a5398fe4 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs @@ -104,12 +104,12 @@ public MulExpression(Match m) var first = new Operation { Op = m.Matches[1].StringValue, - Left = OrExpression.GetSubToken(m.Matches[0]), - Right = OrExpression.GetSubToken(m.Matches[2]) + Left = CastExpression.GetSubToken(m.Matches[0]), + Right = CastExpression.GetSubToken(m.Matches[2]) }; Operation tmp = first; - for (int i = 3; i < m.Length - 2; i += 2) + for (int i = 3; i < m.Matches.Count - 2; i += 2) { tmp = new Operation { @@ -145,7 +145,7 @@ public SumExpression(Match m) }; Operation tmp = first; - for (int i = 3; i < m.Length - 2; i += 2) + for (int i = 3; i < m.Matches.Count - 2; i += 2) { tmp = new Operation { @@ -181,13 +181,13 @@ public ShiftExpression(Match m) }; Operation tmp = first; - for (int i = 3; i < m.Length - 2; i += 2) + for (int i = 3; i < m.Matches.Count - 2; i += 2) { tmp = new Operation { Op = m.Matches[i].StringValue, Left = tmp, - Right = ShiftExpression.GetSubToken(m.Matches[i + 1]) + Right = SumExpression.GetSubToken(m.Matches[i + 1]) }; } Operations = tmp; @@ -272,7 +272,7 @@ public TestExpression(Match m) }; Operation tmp = first; - for (int i = 3; i < m.Length - 2; i += 2) + for (int i = 3; i < m.Matches.Count - 2; i += 2) { tmp = new Operation { @@ -309,7 +309,7 @@ public EqualsExpression(Match m) }; Operation tmp = first; - for (int i = 3; i < m.Length - 2; i += 2) + for (int i = 3; i < m.Matches.Count - 2; i += 2) { tmp = new Operation { From 341935edace580abc7a0000000eaea9dd100f8f7 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 13:13:27 +0200 Subject: [PATCH 0072/1182] Correction AST creation --- src/SDSLParserExample/Program.cs | 2 +- .../AST/Expressions/ExpressionToken.cs | 25 +- .../AST/Expressions/Operations.cs | 404 ++++++++---------- .../AST/Expressions/OperatorToken.cs | 58 +++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 1 - 5 files changed, 252 insertions(+), 238 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 5230d974a7..fd793f8ee8 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -37,7 +37,7 @@ static void PrettyPrintMatches(Match match, int depth = 0) var s = new Stopwatch(); //var match2 = parser.Parse("shader MyShader : Something {}"); s.Start(); -var match = parser.Parse("5<<5%3;"); +var match = parser.Parse("5 && 6 && 7;"); s.Stop(); Console.WriteLine(match); //if (match.Errors.Any()) diff --git a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs index ba79b302f0..82a9e72522 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs @@ -23,11 +23,30 @@ public static ExpressionToken Parse(string expr) return GetToken(match.Matches.First()); } - internal static ExpressionToken GetToken(Match match) + public static ExpressionToken GetToken(Match match) { - return match.Name switch + var tmp = match; + while (tmp.Matches.Count == 1) + tmp = tmp.Matches.First(); + + return tmp.Name switch { - "PrimaryExpression" => PrimaryExpression.GetSubToken(match), + "PrimaryExpression" => GetToken(tmp), + "Ternary" => new ConditionalExpression(tmp), + "LogicalOrExpression" => LogicalOrExpression.Create(tmp), + "LogicalAndExpression" => LogicalAndExpression.Create(tmp), + "EqualsExpression" => EqualsExpression.Create(tmp), + "TestExpression" => TestExpression.Create(tmp), + "OrExpression" => OrExpression.Create(tmp), + "XorExpression" => XorExpression.Create(tmp), + "AndExpression" => AndExpression.Create(tmp), + "ShiftExpression" => ShiftExpression.Create(tmp), + "SumExpression" => SumExpression.Create(tmp), + "MulExpression" => MulExpression.Create(tmp), + "CastExpression" => new CastExpression(tmp), + "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), + "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), + _ => throw new NotImplementedException() }; } diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs index 52a5398fe4..80d32ddc99 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs @@ -4,12 +4,13 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using static Stride.Shader.Parsing.AST.Expressions.OperatorTokenExtensions; namespace Stride.Shader.Parsing.AST.Expressions; public class Operation : ExpressionToken { - public string Op { get; set; } + public OperatorToken Op { get; set; } public ExpressionToken Left { get; set; } public ExpressionToken Right { get; set; } } @@ -42,331 +43,279 @@ public PrefixIncrement(Match m) } } -public class PostfixExpression : ExpressionToken +public class CastExpression : ExpressionToken { - - public PostfixExpression(Match m) - { - - } - - public static ExpressionToken GetSubToken(Match m) + public CastExpression(Match m) { - return m switch - { - { Name: "TermExpression" } => TermExpression.GetSubToken(m.Matches[0]), - //{ Name: "PostfixIncrement" } => new PostfixIncrement(m.Matches[0]), - //{ Name: "ArrayAccessor" } => new ArrayAccessor(m.Matches[0]), - //{ Name: "AccessorChain" } => new AccessorChain(m.Matches[0]), - _ => throw new NotImplementedException() - }; + // TODO implement cast } - } -public static class UnaryExpression +public class MulExpression : Operation { - public static ExpressionToken GetSubToken(Match m) + public static MulExpression Create(Match m) { - - return m switch + var first = new MulExpression { - { Name: "PostfixExpression" } => PostfixExpression.GetSubToken(m.Matches[0]), - { Name: "PrefixIncrement" } => new PrefixIncrement(m), - _ => throw new NotImplementedException() + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - } -} -public class CastExpression : ExpressionToken -{ - public CastExpression(Match m) - { - // TODO implement cast - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch + MulExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) { - { Matches.Count: 1 } => UnaryExpression.GetSubToken(m.Matches[0].Matches[0]), - { Matches.Count: > 1 } => new CastExpression(m), - _ => throw new NotImplementedException() - }; + tmp = new MulExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; } } -public class MulExpression : ExpressionToken +public class SumExpression : Operation { - public Operation Operations; - public MulExpression(Match m) + public static SumExpression Create(Match m) { - var first = new Operation + var first = new SumExpression { - Op = m.Matches[1].StringValue, - Left = CastExpression.GetSubToken(m.Matches[0]), - Right = CastExpression.GetSubToken(m.Matches[2]) + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - Operation tmp = first; + SumExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { - tmp = new Operation + tmp = new SumExpression { - Op = m.Matches[i].StringValue, + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), Left = tmp, - Right = OrExpression.GetSubToken(m.Matches[i + 1]) + Right = GetToken(m.Matches[i + 1]) }; } - Operations = tmp; - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Matches.Count: 1 } => CastExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new MulExpression(m), - _ => throw new NotImplementedException() - }; + return tmp; } } -public class SumExpression : ExpressionToken +public class ShiftExpression : Operation { - public Operation Operations; - public SumExpression(Match m) + public static ShiftExpression Create(Match m) { - var first = new Operation + var first = new ShiftExpression { - Op = m.Matches[1].StringValue, - Left = MulExpression.GetSubToken(m.Matches[0]), - Right = MulExpression.GetSubToken(m.Matches[2]) + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - Operation tmp = first; + ShiftExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { - tmp = new Operation + tmp = new ShiftExpression { - Op = m.Matches[i].StringValue, + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), Left = tmp, - Right = MulExpression.GetSubToken(m.Matches[i + 1]) + Right = GetToken(m.Matches[i + 1]) }; } - Operations = tmp; - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Matches.Count: 1 } => MulExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new SumExpression(m), - _ => throw new NotImplementedException() - }; + return tmp; } } -public class ShiftExpression : ExpressionToken +public class AndExpression : Operation { - public Operation Operations; - public ShiftExpression(Match m) + public static AndExpression Create(Match m) { - var first = new Operation + var first = new AndExpression { - Op = m.Matches[1].StringValue, - Left = SumExpression.GetSubToken(m.Matches[0]), - Right = SumExpression.GetSubToken(m.Matches[2]) + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - Operation tmp = first; + AndExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { - tmp = new Operation + tmp = new AndExpression { - Op = m.Matches[i].StringValue, + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), Left = tmp, - Right = SumExpression.GetSubToken(m.Matches[i + 1]) + Right = GetToken(m.Matches[i + 1]) }; } - Operations = tmp; - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Matches.Count: 1 } => SumExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new ShiftExpression(m), - _ => throw new NotImplementedException() - }; + return tmp; } } - -public class AndExpression : ExpressionToken +public class XorExpression : Operation { - public IEnumerable Values; - public AndExpression(Match m) - { - Values = m.Matches.Where(x => x.Name != "Operator").Select(ShiftExpression.GetSubToken); - } - - public static ExpressionToken GetSubToken(Match m) + public static XorExpression Create(Match m) { - return m switch + var first = new XorExpression { - { Matches.Count: 1 } => ShiftExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new AndExpression(m), - _ => throw new NotImplementedException() + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - } -} -public class XorExpression : ExpressionToken -{ - public IEnumerable Values; - public XorExpression(Match m) - { - Values = m.Matches.Where(x => x.Name != "Operator").Select(AndExpression.GetSubToken); - } - public static ExpressionToken GetSubToken(Match m) - { - return m switch + XorExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) { - { Matches.Count: 1 } => AndExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new XorExpression(m), - _ => throw new NotImplementedException() - }; + tmp = new XorExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; } } -public class OrExpression : ExpressionToken +public class OrExpression : Operation { - public IEnumerable Values; - public OrExpression(Match m) + public static OrExpression Create(Match m) { - Values = m.Matches.Where(x => x.Name != "Operator").Select(XorExpression.GetSubToken); - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch + var first = new OrExpression { - { Matches.Count: 1 } => XorExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new OrExpression(m), - _ => throw new NotImplementedException() + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; + + OrExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new OrExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; } } -public class TestExpression : ExpressionToken +public class TestExpression : Operation { - public Operation Operations; - public TestExpression(Match m) + public static TestExpression Create(Match m) { - var first = new Operation + var first = new TestExpression { - Op = m.Matches[1].StringValue, - Left = OrExpression.GetSubToken(m.Matches[0]), - Right = OrExpression.GetSubToken(m.Matches[2]) + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - Operation tmp = first; + TestExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { - tmp = new Operation + tmp = new TestExpression { - Op = m.Matches[i].StringValue, + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), Left = tmp, - Right = OrExpression.GetSubToken(m.Matches[i + 1]) + Right = GetToken(m.Matches[i + 1]) }; } - Operations = tmp; - - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Matches.Count: 1 } => OrExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new TestExpression(m), - _ => throw new NotImplementedException() - }; + return tmp; } } -public class EqualsExpression : ExpressionToken +public class EqualsExpression : Operation { - public Operation Operations; - public EqualsExpression(Match m) + public static EqualsExpression Create(Match m) { - var first = new Operation + var first = new EqualsExpression { - Op = m.Matches[1].StringValue, - Left = TestExpression.GetSubToken(m.Matches[0]), - Right = TestExpression.GetSubToken(m.Matches[2]) + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; - Operation tmp = first; + EqualsExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { - tmp = new Operation + tmp = new EqualsExpression { - Op = m.Matches[i].StringValue, + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), Left = tmp, - Right = TestExpression.GetSubToken(m.Matches[i + 1]) + Right = GetToken(m.Matches[i + 1]) }; } - Operations = tmp; - - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Matches.Count: 1 } => TestExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new EqualsExpression(m), - _ => throw new NotImplementedException() - }; + return tmp; } } -public class LogicalAndExpression : ExpressionToken +public class LogicalAndExpression : Operation { - public IEnumerable Values; - public LogicalAndExpression(Match m) + public static LogicalAndExpression Create(Match m) { - Values = m.Matches.Where(x => x.Name != "Operator").Select(EqualsExpression.GetSubToken); - } - - public static ExpressionToken GetSubToken(Match m) - { - return m switch + var first = new LogicalAndExpression { - { Matches.Count: 1 } => EqualsExpression.GetSubToken(m.Matches[0]), - { Matches.Count: > 1 } => new LogicalAndExpression(m), - _ => throw new NotImplementedException() + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; + + LogicalAndExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new LogicalAndExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; } + } -public class LogicalOrExpression : ExpressionToken +public class LogicalOrExpression : Operation { - public IEnumerable Values; - public LogicalOrExpression(Match m) - { - Values = m.Matches.Where(x => x.Name != "Operator").Select(LogicalAndExpression.GetSubToken); - } - - public static ExpressionToken GetSubToken(Match m) + public static LogicalOrExpression Create(Match m) { - return m switch + var first = new LogicalOrExpression { - { Matches.Count : 1} => LogicalAndExpression.GetSubToken(m.Matches[0]), - { Matches.Count: >1} => new LogicalOrExpression(m), - _ => throw new NotImplementedException() + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) }; + + LogicalOrExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new LogicalOrExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; } } @@ -379,20 +328,9 @@ public class ConditionalExpression : ExpressionToken public ConditionalExpression(Match m) { - Condition = LogicalOrExpression.GetSubToken(m.Matches[0]); - TrueOutput = LogicalOrExpression.GetSubToken(m.Matches[1]); - FalseOutput = LogicalOrExpression.GetSubToken(m.Matches[2]); - } - - public static ExpressionToken GetSubToken(Match m) - { - var tmp = m.Matches[0]; - return tmp switch - { - { Name: "LogicalOrExpression", Matches.Count: 1} => LogicalOrExpression.GetSubToken(m.Matches[0]), - { Name: "Ternary" } => new ConditionalExpression(tmp), - _ => throw new NotImplementedException() - }; + Condition = GetToken(m.Matches[0]); + TrueOutput = GetToken(m.Matches[1]); + FalseOutput = GetToken(m.Matches[2]); } } @@ -403,7 +341,7 @@ public static ExpressionToken GetSubToken(Match m) { return m.Matches[0].Name switch { - "ConditionalExpression" => ConditionalExpression.GetSubToken(m.Matches[0]), + "ConditionalExpression" => GetToken(m.Matches[0]), //ConditionalExpression.GetSubToken(m.Matches[0]), _ => throw new NotImplementedException() }; } diff --git a/src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs b/src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs new file mode 100644 index 0000000000..e36b96ba98 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Expressions; + +public enum OperatorToken +{ + Mul, + Div, + Mod, + Plus, + Minus, + LeftShift, + RightShift, + And, + Or, + Xor, + Less, + Greater, + LessEqual, + GreaterEqual, + Equals, + NotEquals, + LogicalAnd, + LogicalOr +} + +public static class OperatorTokenExtensions +{ + public static OperatorToken AsOperatorToken(this string s) + { + return s switch + { + "*" => OperatorToken.Mul, + "/" => OperatorToken.Div, + "%" => OperatorToken.Mod, + "+" => OperatorToken.Plus, + "-" => OperatorToken.Minus, + "<<" => OperatorToken.LeftShift, + ">>" => OperatorToken.RightShift, + "|" => OperatorToken.Or, + "&" => OperatorToken.And, + "^" => OperatorToken.Xor, + "<" => OperatorToken.Less, + "<=" => OperatorToken.LessEqual, + ">" => OperatorToken.Greater, + ">=" => OperatorToken.GreaterEqual, + "==" => OperatorToken.Equals, + "!=" => OperatorToken.NotEquals, + "&&" => OperatorToken.LogicalAnd, + "||" => OperatorToken.LogicalOr, + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 9c09509fea..ff54b97747 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -96,7 +96,6 @@ public void CreateExpressions() PostfixExpression.Add( TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), - ((Plus | Minus).Named("Sign") & ws & TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp))).Named("SignedTermExpression"), postfixInc.Named("PostfixIncrement"), chain.Named("AccessorChain"), arrayAccess.Named("ArrayAccesor") From 5c9f6677968a216208bc20163ebe051554d6609a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 14:23:15 +0200 Subject: [PATCH 0073/1182] AST for CastExpression --- src/SDSLParserExample/Program.cs | 9 +- .../AST/Expressions/ExpressionToken.cs | 3 +- .../AST/Expressions/Literals.cs | 27 +- .../AST/Expressions/Operations.cs | 35 +-- .../Grammars/ExpressionGrammar.cs | 6 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 19 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 13 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 272 +++++++++--------- 9 files changed, 181 insertions(+), 205 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index fd793f8ee8..3e9c5950a8 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -32,12 +32,13 @@ static void PrettyPrintMatches(Match match, int depth = 0) var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); -var parser = new ExpressionParser(); //new SDSLParser(); -//parser.Grammar.Using(parser.Grammar.ShaderValueDeclaration); +var sdsl = new SDSLParser(); +sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); -//var match2 = parser.Parse("shader MyShader : Something {}"); +var match2 = sdsl.Parse("(abab) my_var"); +var parser = new ExpressionParser(); s.Start(); -var match = parser.Parse("5 && 6 && 7;"); +var match = parser.Parse("(abab) my_var"); s.Stop(); Console.WriteLine(match); //if (match.Errors.Any()) diff --git a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs index 82a9e72522..d010277cce 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs @@ -46,7 +46,8 @@ public static ExpressionToken GetToken(Match match) "CastExpression" => new CastExpression(tmp), "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), - + "VariableTerm" => new VariableNameLiteral(tmp), + "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), _ => throw new NotImplementedException() }; } diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs b/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs index 0de56abb4d..15acb8ef08 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs @@ -77,15 +77,22 @@ public BoolLiteral(Match match) } -public class Literals +public class TypeNameLiteral : ExpressionToken { - public static ExpressionToken GetSubToken(Match m) - { - return m.Name switch - { - "IntegerLiteral" or "FloatLiteral" => new NumberLiteral(m), - "StringLiteral" => new StringLiteral(m), - _ => throw new NotImplementedException() - }; - } + public string Name { get; set; } + + public TypeNameLiteral(Match m) + { + Name = m.StringValue; + } } + +public class VariableNameLiteral : ExpressionToken +{ + public string Name { get; set; } + + public VariableNameLiteral(Match m) + { + Name = m.StringValue; + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs index 80d32ddc99..ddb905fa5d 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs @@ -15,22 +15,6 @@ public class Operation : ExpressionToken public ExpressionToken Right { get; set; } } -public class TermExpression -{ - public static ExpressionToken GetSubToken(Match m) - { - return m switch - { - { Name: "Literals" } => Literals.GetSubToken(m.Matches[0]), - { Name: "IntegerLiteral" } => new NumberLiteral(m), - - //{ Name: "VariableTerm" } => new VariableTerm(m.Matches[0]), - _ => throw new NotImplementedException() - }; - } -} - - public class PrefixIncrement : ExpressionToken { public string Operator { get; set; } @@ -45,9 +29,12 @@ public PrefixIncrement(Match m) public class CastExpression : ExpressionToken { + public TypeNameLiteral Target { get; set; } + public ExpressionToken From { get; set; } public CastExpression(Match m) { - // TODO implement cast + Target = new TypeNameLiteral(m.Matches[0]); + From = GetToken(m.Matches[1]); } } @@ -333,17 +320,3 @@ public ConditionalExpression(Match m) FalseOutput = GetToken(m.Matches[2]); } } - - -public class PrimaryExpression : ExpressionToken -{ - public static ExpressionToken GetSubToken(Match m) - { - return m.Matches[0].Name switch - { - "ConditionalExpression" => GetToken(m.Matches[0]), //ConditionalExpression.GetSubToken(m.Matches[0]), - _ => throw new NotImplementedException() - }; - } -} - diff --git a/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs b/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs index 6ee8dbbe9d..d19bd0b960 100644 --- a/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs +++ b/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs @@ -8,10 +8,8 @@ namespace Stride.Shader.Parsing.Grammars.Expression; public class ExpressionGrammar : SDSLGrammar { - public ExpressionGrammar() + public ExpressionGrammar() : base() { - Name = "expression"; - CreateAll(); - Inner = PrimaryExpression.Then(";"); + Using(PrimaryExpression); } } diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index ff54b97747..2f20c947e4 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -60,14 +60,11 @@ public void CreateExpressions() PlusPlus, MinusMinus ); - - // TODO : write tests for method calls - // TODO : Optimize method call - + TermExpression.Add( Literals, - Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + Identifier.WithName("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); @@ -116,17 +113,17 @@ public void CreateExpressions() Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") ); - var cast = new SequenceParser(); - cast.Add( + var cast = new SequenceParser( LeftParen, - ValueTypes | Identifier, + ValueTypes | Identifier.Named("TypeName"), RightParen, UnaryExpression - ); + ) + { Name = "CastExpression", Separator = ws}; CastExpression.Add( - UnaryExpression, - cast.SeparatedBy(ws).Named("CastExpression") + cast + //UnaryExpression ); diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index 57a4c33606..378b9910bb 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -2,8 +2,6 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -using EtoParser = Eto.Parse.Parser; - namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { @@ -11,7 +9,7 @@ public partial class SDSLGrammar : Grammar AlternativeParser FloatSuffix = new() { Name = "Suffix"}; public StringParser StringLiteral = new(); - public SequenceParser Identifier = new(); + public SequenceParser Identifier = new() { Name = "Identifier"}; public AlternativeParser UserDefinedId = new(); public NumberParser IntegerLiteral = new(); @@ -31,12 +29,13 @@ public SDSLGrammar UsingLiterals() public void CreateLiterals() { Identifier.Add( - Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier") + Letter | "_", + (LetterOrDigit | "_").Repeat(0).Until(AnyChar.Except(LetterOrDigit | "_")) ); - UserDefinedId.Add( - Identifier.Except(Keywords) - ); + //UserDefinedId.Add( + // Identifier.Except(Keywords) + // ); IntegerSuffix.Add( "u", diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 1faabea81b..039e122afe 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -23,7 +23,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser UintTypes = new(); - public AlternativeParser ValueTypes = new(); + public AlternativeParser ValueTypes = new() { Name = "ValueTypes"}; public AlternativeParser StorageFlag = new(); public AlternativeParser Keywords = new(); diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index a7c2c19a55..3d5c40f41e 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -6,149 +6,149 @@ namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { - private CharTerminal WS; - private AlternativeParser Space = new(); - private RepeatParser Spaces = new(); - private SequenceParser SpacesWithLineBreak = new(); - private LiteralTerminal AppendStructuredBuffer = new(); - private AlternativeParser ComponentNumber = new(); + protected CharTerminal WS; + protected AlternativeParser Space = new(); + protected RepeatParser Spaces = new(); + protected SequenceParser SpacesWithLineBreak = new(); + protected LiteralTerminal AppendStructuredBuffer = new(); + protected AlternativeParser ComponentNumber = new(); - private LiteralTerminal Bool = new(); - private SequenceParser BoolVec = new(); - private SequenceParser BoolMat = new(); - private AlternativeParser Uint = new(); - private SequenceParser UintVec = new(); - private SequenceParser UintMat = new(); - private LiteralTerminal Int = new(); - private SequenceParser IntVec = new(); - private SequenceParser IntMat = new(); + protected LiteralTerminal Bool = new(); + protected SequenceParser BoolVec = new(); + protected SequenceParser BoolMat = new(); + protected AlternativeParser Uint = new(); + protected SequenceParser UintVec = new(); + protected SequenceParser UintMat = new(); + protected LiteralTerminal Int = new(); + protected SequenceParser IntVec = new(); + protected SequenceParser IntMat = new(); - private LiteralTerminal Half = new(); - private SequenceParser HalfVec = new(); - private SequenceParser HalfMat = new(); - private LiteralTerminal Float = new(); - private SequenceParser FloatVec = new(); - private SequenceParser FloatMat = new(); - private LiteralTerminal Double = new(); - private SequenceParser DoubleVec = new(); - private SequenceParser DoubleMat = new(); - private LiteralTerminal Buffer = new(); - private LiteralTerminal ByteAddressBuffer = new(); - private LiteralTerminal Break = new(); - private LiteralTerminal Case = new(); - private LiteralTerminal CBuffer = new(); - private LiteralTerminal Centroid = new(); - private LiteralTerminal Class = new(); - private LiteralTerminal ColumnMajor = new(); - private LiteralTerminal Const = new(); - private LiteralTerminal ConsumeStructuredBuffer = new(); - private LiteralTerminal Continue = new(); - private LiteralTerminal Default = new(); - private LiteralTerminal Discard = new(); - private LiteralTerminal Do = new(); - private LiteralTerminal Else = new(); - private LiteralTerminal Extern = new(); - private LiteralTerminal For = new(); - private LiteralTerminal Groupshared = new(); - private LiteralTerminal If = new(); - private LiteralTerminal In = new(); - private AlternativeParser Inout = new(); - private LiteralTerminal InputPatch = new(); - private LiteralTerminal Interface = new(); + protected LiteralTerminal Half = new(); + protected SequenceParser HalfVec = new(); + protected SequenceParser HalfMat = new(); + protected LiteralTerminal Float = new(); + protected SequenceParser FloatVec = new(); + protected SequenceParser FloatMat = new(); + protected LiteralTerminal Double = new(); + protected SequenceParser DoubleVec = new(); + protected SequenceParser DoubleMat = new(); + protected LiteralTerminal Buffer = new(); + protected LiteralTerminal ByteAddressBuffer = new(); + protected LiteralTerminal Break = new(); + protected LiteralTerminal Case = new(); + protected LiteralTerminal CBuffer = new(); + protected LiteralTerminal Centroid = new(); + protected LiteralTerminal Class = new(); + protected LiteralTerminal ColumnMajor = new(); + protected LiteralTerminal Const = new(); + protected LiteralTerminal ConsumeStructuredBuffer = new(); + protected LiteralTerminal Continue = new(); + protected LiteralTerminal Default = new(); + protected LiteralTerminal Discard = new(); + protected LiteralTerminal Do = new(); + protected LiteralTerminal Else = new(); + protected LiteralTerminal Extern = new(); + protected LiteralTerminal For = new(); + protected LiteralTerminal Groupshared = new(); + protected LiteralTerminal If = new(); + protected LiteralTerminal In = new(); + protected AlternativeParser Inout = new(); + protected LiteralTerminal InputPatch = new(); + protected LiteralTerminal Interface = new(); - public LiteralTerminal Line_ { get; private set; } + public LiteralTerminal Line_ { get; protected set; } - private LiteralTerminal LineAdj = new(); - private LiteralTerminal Linear = new(); - private LiteralTerminal LineStream = new(); - private LiteralTerminal Long = new(); - private LiteralTerminal Matrix = new(); - private LiteralTerminal Nointerpolation = new(); - private LiteralTerminal Noperspective = new(); - private LiteralTerminal Out = new(); - private LiteralTerminal OutputPatch = new(); - private LiteralTerminal Packoffset = new(); - private LiteralTerminal Point = new(); - private LiteralTerminal PointStream = new(); - private LiteralTerminal Precise = new(); - private LiteralTerminal Register = new(); - private LiteralTerminal Return = new(); - private LiteralTerminal RowMajor = new(); - private LiteralTerminal RWBuffer = new(); - private LiteralTerminal RWByteAddressBuffer = new(); - private LiteralTerminal RWStructuredBuffer = new(); - private LiteralTerminal Sample = new(); - private LiteralTerminal Sampler = new(); - private LiteralTerminal SamplerComparisonState = new(); - private LiteralTerminal SamplerState = new(); - private LiteralTerminal Shared = new(); - private LiteralTerminal StaticConst = new(); - private LiteralTerminal Static = new(); - private LiteralTerminal Struct = new(); - private LiteralTerminal StructuredBuffer = new(); - private LiteralTerminal Switch = new(); - private AlternativeParser TextureTypes = new(); - private LiteralTerminal Triangle = new(); - private LiteralTerminal TriangleAdj = new(); - private LiteralTerminal TriangleStream = new(); - private LiteralTerminal Uniform = new(); - private LiteralTerminal Vector = new(); - private LiteralTerminal Volatile = new(); - private LiteralTerminal Void = new(); - private LiteralTerminal While = new(); - private LiteralTerminal LeftParen = new(); - private LiteralTerminal RightParen = new(); - private LiteralTerminal LeftBracket = new(); - private LiteralTerminal RightBracket = new(); - private LiteralTerminal LeftBrace = new(); - private LiteralTerminal RightBrace = new(); + protected LiteralTerminal LineAdj = new(); + protected LiteralTerminal Linear = new(); + protected LiteralTerminal LineStream = new(); + protected LiteralTerminal Long = new(); + protected LiteralTerminal Matrix = new(); + protected LiteralTerminal Nointerpolation = new(); + protected LiteralTerminal Noperspective = new(); + protected LiteralTerminal Out = new(); + protected LiteralTerminal OutputPatch = new(); + protected LiteralTerminal Packoffset = new(); + protected LiteralTerminal Point = new(); + protected LiteralTerminal PointStream = new(); + protected LiteralTerminal Precise = new(); + protected LiteralTerminal Register = new(); + protected LiteralTerminal Return = new(); + protected LiteralTerminal RowMajor = new(); + protected LiteralTerminal RWBuffer = new(); + protected LiteralTerminal RWByteAddressBuffer = new(); + protected LiteralTerminal RWStructuredBuffer = new(); + protected LiteralTerminal Sample = new(); + protected LiteralTerminal Sampler = new(); + protected LiteralTerminal SamplerComparisonState = new(); + protected LiteralTerminal SamplerState = new(); + protected LiteralTerminal Shared = new(); + protected LiteralTerminal StaticConst = new(); + protected LiteralTerminal Static = new(); + protected LiteralTerminal Struct = new(); + protected LiteralTerminal StructuredBuffer = new(); + protected LiteralTerminal Switch = new(); + protected AlternativeParser TextureTypes = new(); + protected LiteralTerminal Triangle = new(); + protected LiteralTerminal TriangleAdj = new(); + protected LiteralTerminal TriangleStream = new(); + protected LiteralTerminal Uniform = new(); + protected LiteralTerminal Vector = new(); + protected LiteralTerminal Volatile = new(); + protected LiteralTerminal Void = new(); + protected LiteralTerminal While = new(); + protected LiteralTerminal LeftParen = new(); + protected LiteralTerminal RightParen = new(); + protected LiteralTerminal LeftBracket = new(); + protected LiteralTerminal RightBracket = new(); + protected LiteralTerminal LeftBrace = new(); + protected LiteralTerminal RightBrace = new(); - private LiteralTerminal LeftShift = new(); - private LiteralTerminal RightShift = new(); - private LiteralTerminal Plus = new(); - private LiteralTerminal PlusPlus = new(); - private LiteralTerminal Minus = new(); - private LiteralTerminal MinusMinus = new(); - private LiteralTerminal Star = new(); - private LiteralTerminal Div = new(); - private LiteralTerminal Mod = new(); - private LiteralTerminal And = new(); - private LiteralTerminal Or = new(); - private LiteralTerminal AndAnd = new(); - private LiteralTerminal OrOr = new(); - private LiteralTerminal Caret = new(); - private LiteralTerminal Not = new(); - private LiteralTerminal Tilde = new(); - private LiteralTerminal Equal = new(); - private LiteralTerminal NotEqual = new(); - private LiteralTerminal Less = new(); - private LiteralTerminal LessEqual = new(); - private LiteralTerminal Greater = new(); - private LiteralTerminal GreaterEqual = new(); - private LiteralTerminal Question = new(); - private LiteralTerminal Colon = new(); - private LiteralTerminal ColonColon = new(); - private LiteralTerminal Semi = new(); - private LiteralTerminal Comma = new(); - private LiteralTerminal Assign = new(); - private LiteralTerminal StarAssign = new(); - private LiteralTerminal DivAssign = new(); - private LiteralTerminal ModAssign = new(); - private LiteralTerminal PlusAssign = new(); - private LiteralTerminal MinusAssign = new(); - private LiteralTerminal LeftShiftAssign = new(); - private LiteralTerminal RightShiftAssign = new(); - private LiteralTerminal AndAssign = new(); - private LiteralTerminal XorAssign = new(); - private LiteralTerminal OrAssign = new(); + protected LiteralTerminal LeftShift = new(); + protected LiteralTerminal RightShift = new(); + protected LiteralTerminal Plus = new(); + protected LiteralTerminal PlusPlus = new(); + protected LiteralTerminal Minus = new(); + protected LiteralTerminal MinusMinus = new(); + protected LiteralTerminal Star = new(); + protected LiteralTerminal Div = new(); + protected LiteralTerminal Mod = new(); + protected LiteralTerminal And = new(); + protected LiteralTerminal Or = new(); + protected LiteralTerminal AndAnd = new(); + protected LiteralTerminal OrOr = new(); + protected LiteralTerminal Caret = new(); + protected LiteralTerminal Not = new(); + protected LiteralTerminal Tilde = new(); + protected LiteralTerminal Equal = new(); + protected LiteralTerminal NotEqual = new(); + protected LiteralTerminal Less = new(); + protected LiteralTerminal LessEqual = new(); + protected LiteralTerminal Greater = new(); + protected LiteralTerminal GreaterEqual = new(); + protected LiteralTerminal Question = new(); + protected LiteralTerminal Colon = new(); + protected LiteralTerminal ColonColon = new(); + protected LiteralTerminal Semi = new(); + protected LiteralTerminal Comma = new(); + protected LiteralTerminal Assign = new(); + protected LiteralTerminal StarAssign = new(); + protected LiteralTerminal DivAssign = new(); + protected LiteralTerminal ModAssign = new(); + protected LiteralTerminal PlusAssign = new(); + protected LiteralTerminal MinusAssign = new(); + protected LiteralTerminal LeftShiftAssign = new(); + protected LiteralTerminal RightShiftAssign = new(); + protected LiteralTerminal AndAssign = new(); + protected LiteralTerminal XorAssign = new(); + protected LiteralTerminal OrAssign = new(); - private LiteralTerminal Dot = new(); - private LiteralTerminal True = new(); - private LiteralTerminal False = new(); - private AlternativeParser PreprocessorDirectiveName = new(); + protected LiteralTerminal Dot = new(); + protected LiteralTerminal True = new(); + protected LiteralTerminal False = new(); + protected AlternativeParser PreprocessorDirectiveName = new(); - private LiteralTerminal Stream = new(){Name = "Stream"}; - private LiteralTerminal Stage = new(){Name = "Stage"}; + protected LiteralTerminal Stream = new(){Name = "Stream"}; + protected LiteralTerminal Stage = new(){Name = "Stage"}; public void CreateTokens() From 0479f2ff7dc7c299609b7958fe6b9f8f66718df5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 14:34:03 +0200 Subject: [PATCH 0074/1182] Moved print parse tree --- src/SDSLParserExample/Program.cs | 29 +++---------------- .../Grammars/SDSLGrammar/SDSLGrammar.cs | 4 +-- src/Stride.Shader.Parsing/SDSLParser.cs | 28 ++++++++++++++++++ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3e9c5950a8..0b15621eb2 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -5,29 +5,6 @@ using System.Diagnostics; using System.Linq; -static void PrettyPrintMatches(Match match, int depth = 0) -{ - Console.ForegroundColor = ConsoleColor.Blue; - Console.Write(new string(' ', depth*4) + match.Name); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(" : " + match.StringValue); - //Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); - foreach (var m in match.Matches) - { - if(m.Matches.Count == 1 && m.Name.Contains("Expression")) - { - var tmp = m.Matches[0]; - while(tmp.Matches.Count == 1) - { - tmp = tmp.Matches[0]; - } - PrettyPrintMatches(tmp, depth + 1); - } - else - PrettyPrintMatches(m, depth + 1); - } -} - var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); @@ -35,11 +12,14 @@ static void PrettyPrintMatches(Match match, int depth = 0) var sdsl = new SDSLParser(); sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); -var match2 = sdsl.Parse("(abab) my_var"); var parser = new ExpressionParser(); +var match2 = parser.Parse("(abab) my_var"); + s.Start(); var match = parser.Parse("(abab) my_var"); s.Stop(); +Console.WriteLine($"parsing time : {s.Elapsed}"); + Console.WriteLine(match); //if (match.Errors.Any()) //{ @@ -54,7 +34,6 @@ static void PrettyPrintMatches(Match match, int depth = 0) //else //{ // match.Matches.ForEach(x => PrettyPrintMatches(x)); -// Console.WriteLine($"parsing time : {s.Elapsed}"); // Console.Write(""); //} diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs index 5983f67c0b..3634ab8aac 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -2,8 +2,6 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -using EtoParser = Eto.Parse.Parser; - namespace Stride.Shader.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { @@ -13,7 +11,7 @@ public SDSLGrammar() : base("sdsl") Inner = ShaderExpression; } - public SDSLGrammar Using(EtoParser p) + public SDSLGrammar Using(Parser p) { Inner = p; return this; diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index da79c11b27..b02d9b3dd5 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -28,6 +28,11 @@ public SDSLParser With(Parser p) return this; } + public void PrintParserTree(string shader) + { + PrettyPrintMatches(Parse(shader).Matches[0]); + } + public GrammarMatch Parse(string shader) { var comments = Comments.Match(shader); @@ -55,4 +60,27 @@ public GrammarMatch PreProcessor(string code) return Directive.Match(code); } + private static void PrettyPrintMatches(Match match, int depth = 0) + { + Console.ForegroundColor = ConsoleColor.Blue; + Console.Write(new string(' ', depth * 4) + match.Name); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(" : " + match.StringValue); + //Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); + foreach (var m in match.Matches) + { + if (m.Matches.Count == 1 && m.Name.Contains("Expression")) + { + var tmp = m.Matches[0]; + while (tmp.Matches.Count == 1) + { + tmp = tmp.Matches[0]; + } + PrettyPrintMatches(tmp, depth + 1); + } + else + PrettyPrintMatches(m, depth + 1); + } + } + } \ No newline at end of file From 58955b848ca148cd442cccfad8fe1e009c53de7f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 16:06:48 +0200 Subject: [PATCH 0075/1182] Reformatting --- src/SDSLParserExample/Program.cs | 20 +- .../AST/Directives/DirectiveASTBuilder.cs | 26 -- .../AST/Directives/DirectiveNode.cs | 88 ----- .../AST/Directives/DirectiveToken.cs | 44 +++ .../AST/Directives/Directives.cs | 32 ++ .../AST/Directives/ExpressionNode.cs | 12 - .../AST/Directives/Literals.cs | 98 ++++++ .../{Expressions => Directives}/Operations.cs | 26 +- .../OperatorToken.cs | 2 +- .../AST/Expressions/Literals.cs | 98 ------ .../AST/Shader/Literals.cs | 98 ++++++ .../AST/Shader/Operations.cs | 323 ++++++++++++++++++ .../AST/Shader/OperatorToken.cs | 58 ++++ .../ShaderToken.cs} | 21 +- src/Stride.Shader.Parsing/ExpressionParser.cs | 12 +- .../DirectiveGrammar/SDSLGrammar.Literals.cs | 3 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 5 +- src/Stride.Shader.Parsing/SDSLParser.cs | 1 + 19 files changed, 689 insertions(+), 280 deletions(-) delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs create mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs create mode 100644 src/Stride.Shader.Parsing/AST/Directives/Directives.cs delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs create mode 100644 src/Stride.Shader.Parsing/AST/Directives/Literals.cs rename src/Stride.Shader.Parsing/AST/{Expressions => Directives}/Operations.cs (92%) rename src/Stride.Shader.Parsing/AST/{Expressions => Directives}/OperatorToken.cs (96%) delete mode 100644 src/Stride.Shader.Parsing/AST/Expressions/Literals.cs create mode 100644 src/Stride.Shader.Parsing/AST/Shader/Literals.cs create mode 100644 src/Stride.Shader.Parsing/AST/Shader/Operations.cs create mode 100644 src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs rename src/Stride.Shader.Parsing/AST/{Expressions/ExpressionToken.cs => Shader/ShaderToken.cs} (68%) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 0b15621eb2..b812e43daf 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -13,29 +13,13 @@ sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); -var match2 = parser.Parse("(abab) my_var"); +var match2 = parser.Parse("false"); s.Start(); -var match = parser.Parse("(abab) my_var"); +var match = parser.Parse("true ? 5 : 8+my_var"); s.Stop(); Console.WriteLine($"parsing time : {s.Elapsed}"); Console.WriteLine(match); -//if (match.Errors.Any()) -//{ -// Console.WriteLine(match.ErrorMessage[..Math.Min(10000, match.ErrorMessage.Length)]); -// //parser.UncommentedCode.ToString().Split("\n").Select((x, i) => (x, i+1)).ToList().ForEach(x => { -// // Console.ForegroundColor = ConsoleColor.Blue; -// // Console.Write(x.Item2 + " : "); -// // Console.ForegroundColor = ConsoleColor.White; -// // Console.WriteLine(x.x); -// //}); -//} -//else -//{ -// match.Matches.ForEach(x => PrettyPrintMatches(x)); -// Console.Write(""); -//} - diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs deleted file mode 100644 index aa44d69b78..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/DirectiveASTBuilder.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Eto.Parse.Ast; - -namespace Stride.Shader.Parsing.AST.Directives -{ - public class DirectiveASTBuilder : AstBuilder - { - public DirectiveASTBuilder() - { - var token = new Builder(); - - var shaderProgram = Create("shader", () => new Shader()); - shaderProgram.Children().HasMany().Builders.Add( - token - ); - - //token.Create("CodeSnippet", () => new CodeSnippet()).Property((o, v) => o.Snippet = v); - //token.Create("Define", () => new Define()).Property<> - - } - } -} diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs deleted file mode 100644 index 14cc817cd7..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/DirectiveNode.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Eto.Parse; -using Stride.Shader.Parsing.Grammars.Directive; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives; - -public abstract class DirectiveToken { }; - -public class CodeSnippet : DirectiveToken -{ - public string Snippet { get; set; } -} - -public class Define : DirectiveToken -{ - public string Variable { get; set; } - public int Value { get; set; } -} - -public class Shader : DirectiveToken, IList, ICollection -{ - List nodes = new List(); - - - #region list & collection impl - - public DirectiveToken this[int index] { get => nodes[index]; set{ nodes[index] = value; } } - - public int Count => nodes.Count; - - public bool IsReadOnly => ((ICollection)nodes).IsReadOnly; - - public void Add(DirectiveToken item) - { - nodes.Add(item); - } - - public void Clear() - { - nodes.Clear(); - } - - public bool Contains(DirectiveToken item) - { - return nodes.Contains(item); - } - - public void CopyTo(DirectiveToken[] array, int arrayIndex) - { - nodes.CopyTo(array,arrayIndex); - } - - public IEnumerator GetEnumerator() - { - return nodes.GetEnumerator(); - } - - public int IndexOf(DirectiveToken item) - { - return nodes.IndexOf(item); - } - - public void Insert(int index, DirectiveToken item) - { - nodes.Insert(index,item); - } - - public bool Remove(DirectiveToken item) - { - return nodes.Remove(item); - } - - public void RemoveAt(int index) - { - nodes.RemoveAt(index); - } - - IEnumerator IEnumerable.GetEnumerator() - { - throw new NotImplementedException(); - } - #endregion -} diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs new file mode 100644 index 0000000000..dae33253cb --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs @@ -0,0 +1,44 @@ +using Eto.Parse; +using Stride.Shader.Parsing.AST.Shader; +using Stride.Shader.Parsing.Grammars.Expression; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + + +public class DirectiveToken +{ + public Match Match { get; set; } + public static DirectiveToken GetToken(Match match) + { + var tmp = match; + while (tmp.Matches.Count == 1) + tmp = tmp.Matches.First(); + + return tmp.Name switch + { + "Ternary" => new ConditionalExpression(tmp), + "LogicalOrExpression" => LogicalOrExpression.Create(tmp), + "LogicalAndExpression" => LogicalAndExpression.Create(tmp), + "EqualsExpression" => EqualsExpression.Create(tmp), + "TestExpression" => TestExpression.Create(tmp), + "OrExpression" => OrExpression.Create(tmp), + "XorExpression" => XorExpression.Create(tmp), + "AndExpression" => AndExpression.Create(tmp), + "ShiftExpression" => ShiftExpression.Create(tmp), + "SumExpression" => SumExpression.Create(tmp), + "MulExpression" => MulExpression.Create(tmp), + "CastExpression" => new CastExpression(tmp), + "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), + "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), + "VariableTerm" => new VariableNameLiteral(tmp), + "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), + "Boolean" => new BoolLiteral(tmp), + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/Directives.cs b/src/Stride.Shader.Parsing/AST/Directives/Directives.cs new file mode 100644 index 0000000000..784e618c86 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/Directives.cs @@ -0,0 +1,32 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + +public class DefineDirective : DirectiveToken +{ + public string VariableName { get; set; } + public DirectiveToken Value { get; set; } + + public DefineDirective(Match m) + { + Match = m; + VariableName = m.Matches[0].StringValue; + Value = GetToken(m.Matches[1]); + } +} + +public class IfDirective : DirectiveToken +{ + public DirectiveToken Condition { get; set; } + + public IfDirective(Match m) + { + Match = m; + Condition = GetToken(m.Matches[1]); + } +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs b/src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs deleted file mode 100644 index d96fc3d150..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/ExpressionNode.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives -{ - public class ExpressionNode - { - } -} diff --git a/src/Stride.Shader.Parsing/AST/Directives/Literals.cs b/src/Stride.Shader.Parsing/AST/Directives/Literals.cs new file mode 100644 index 0000000000..675aedda14 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/Literals.cs @@ -0,0 +1,98 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + +public class NumberLiteral : DirectiveToken +{ + public bool Negative { get; set; } = false; + public object? Value { get; set; } + public string? Suffix { get; set; } + + + public NumberLiteral() { } + + public NumberLiteral(Match match) + { + Match = match; + if (!match.HasMatches) + { + Value = match.Value; + } + else + { + if (match.Name == "SignedTermExpression") + { + + } + else + { + Value = match.Matches[0].Value; + Suffix = match["Suffix"].StringValue; + } + } + } +} +public class HexLiteral : DirectiveToken +{ + public ulong Value { get; set; } + + public HexLiteral() { } + + public HexLiteral(Match match) + { + Match = match; + Value = Convert.ToUInt64(match.StringValue, 16); + } +} +public class StringLiteral : DirectiveToken +{ + public string? Value { get; set; } + + + public StringLiteral() { } + + public StringLiteral(Match match) + { + Match = match; + Value = match.StringValue; + } +} + +public class BoolLiteral : DirectiveToken +{ + public bool Value { get; set; } + + public BoolLiteral() { } + + public BoolLiteral(Match match) + { + Match = match; + Value = (bool)match.Value; + } +} + + +public class TypeNameLiteral : DirectiveToken +{ + public string Name { get; set; } + + public TypeNameLiteral(Match m) + { + Name = m.StringValue; + } +} + +public class VariableNameLiteral : DirectiveToken +{ + public string Name { get; set; } + + public VariableNameLiteral(Match m) + { + Name = m.StringValue; + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs b/src/Stride.Shader.Parsing/AST/Directives/Operations.cs similarity index 92% rename from src/Stride.Shader.Parsing/AST/Expressions/Operations.cs rename to src/Stride.Shader.Parsing/AST/Directives/Operations.cs index ddb905fa5d..57aab9ff0a 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/Operations.cs @@ -4,18 +4,18 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shader.Parsing.AST.Expressions.OperatorTokenExtensions; +using static Stride.Shader.Parsing.AST.Directives.OperatorTokenExtensions; -namespace Stride.Shader.Parsing.AST.Expressions; +namespace Stride.Shader.Parsing.AST.Directives; -public class Operation : ExpressionToken +public class Operation : DirectiveToken { public OperatorToken Op { get; set; } - public ExpressionToken Left { get; set; } - public ExpressionToken Right { get; set; } + public DirectiveToken Left { get; set; } + public DirectiveToken Right { get; set; } } -public class PrefixIncrement : ExpressionToken +public class PrefixIncrement : DirectiveToken { public string Operator { get; set; } public string Name { get; set; } @@ -27,10 +27,10 @@ public PrefixIncrement(Match m) } } -public class CastExpression : ExpressionToken +public class CastExpression : DirectiveToken { public TypeNameLiteral Target { get; set; } - public ExpressionToken From { get; set; } + public DirectiveToken From { get; set; } public CastExpression(Match m) { Target = new TypeNameLiteral(m.Matches[0]); @@ -236,7 +236,7 @@ public static EqualsExpression Create(Match m) Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; - + EqualsExpression tmp = first; for (int i = 3; i < m.Matches.Count - 2; i += 2) { @@ -306,11 +306,11 @@ public static LogicalOrExpression Create(Match m) } } -public class ConditionalExpression : ExpressionToken +public class ConditionalExpression : DirectiveToken { - public ExpressionToken Condition { get; set; } - public ExpressionToken TrueOutput { get; set; } - public ExpressionToken FalseOutput { get; set; } + public DirectiveToken Condition { get; set; } + public DirectiveToken TrueOutput { get; set; } + public DirectiveToken FalseOutput { get; set; } public ConditionalExpression(Match m) diff --git a/src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs b/src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs similarity index 96% rename from src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs rename to src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs index e36b96ba98..aee471f412 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/OperatorToken.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Expressions; +namespace Stride.Shader.Parsing.AST.Directives; public enum OperatorToken { diff --git a/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs b/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs deleted file mode 100644 index 15acb8ef08..0000000000 --- a/src/Stride.Shader.Parsing/AST/Expressions/Literals.cs +++ /dev/null @@ -1,98 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Expressions; - -public class NumberLiteral : ExpressionToken -{ - public bool Negative { get; set; } = false; - public object? Value { get; set; } - public string? Suffix { get; set; } - - - public NumberLiteral() { } - - public NumberLiteral(Match match) - { - Match = match; - if (!match.HasMatches) - { - Value = match.Value; - } - else - { - if (match.Name == "SignedTermExpression") - { - - } - else - { - Value = match.Matches[0].Value; - Suffix = match["Suffix"].StringValue; - } - } - } -} -public class HexLiteral : ExpressionToken -{ - public ulong Value { get; set; } - - public HexLiteral() { } - - public HexLiteral(Match match) - { - Match = match; - Value = Convert.ToUInt64(match.StringValue, 16); - } -} -public class StringLiteral : ExpressionToken -{ - public string? Value { get; set; } - - - public StringLiteral() { } - - public StringLiteral(Match match) - { - Match = match; - Value = match.StringValue; - } -} - -public class BoolLiteral : ExpressionToken -{ - public bool Value { get; set; } - - public BoolLiteral() { } - - public BoolLiteral(Match match) - { - Match = match; - Value = (bool)match.Value; - } -} - - -public class TypeNameLiteral : ExpressionToken -{ - public string Name { get; set; } - - public TypeNameLiteral(Match m) - { - Name = m.StringValue; - } -} - -public class VariableNameLiteral : ExpressionToken -{ - public string Name { get; set; } - - public VariableNameLiteral(Match m) - { - Name = m.StringValue; - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/AST/Shader/Literals.cs new file mode 100644 index 0000000000..e9773c7b7f --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Shader/Literals.cs @@ -0,0 +1,98 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Shader; + +public class NumberLiteral : ShaderToken +{ + public bool Negative { get; set; } = false; + public object? Value { get; set; } + public string? Suffix { get; set; } + + + public NumberLiteral() { } + + public NumberLiteral(Match match) + { + Match = match; + if (!match.HasMatches) + { + Value = match.Value; + } + else + { + if (match.Name == "SignedTermExpression") + { + + } + else + { + Value = match.Matches[0].Value; + Suffix = match["Suffix"].StringValue; + } + } + } +} +public class HexLiteral : ShaderToken +{ + public ulong Value { get; set; } + + public HexLiteral() { } + + public HexLiteral(Match match) + { + Match = match; + Value = Convert.ToUInt64(match.StringValue, 16); + } +} +public class StringLiteral : ShaderToken +{ + public string? Value { get; set; } + + + public StringLiteral() { } + + public StringLiteral(Match match) + { + Match = match; + Value = match.StringValue; + } +} + +public class BoolLiteral : ShaderToken +{ + public bool Value { get; set; } + + public BoolLiteral() { } + + public BoolLiteral(Match match) + { + Match = match; + Value = (bool)match.Value; + } +} + + +public class TypeNameLiteral : ShaderToken +{ + public string Name { get; set; } + + public TypeNameLiteral(Match m) + { + Name = m.StringValue; + } +} + +public class VariableNameLiteral : ShaderToken +{ + public string Name { get; set; } + + public VariableNameLiteral(Match m) + { + Name = m.StringValue; + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs new file mode 100644 index 0000000000..52e8356078 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs @@ -0,0 +1,323 @@ +using Eto.Parse; +using Stride.Shader.Parsing.AST.Directives; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Stride.Shader.Parsing.AST.Directives.OperatorTokenExtensions; + +namespace Stride.Shader.Parsing.AST.Shader; + +public class Operation : ShaderToken +{ + public OperatorToken Op { get; set; } + public ShaderToken Left { get; set; } + public ShaderToken Right { get; set; } +} + +public class PrefixIncrement : ShaderToken +{ + public string Operator { get; set; } + public string Name { get; set; } + public PrefixIncrement(Match m) + { + Match = m; + Operator = m.Matches[0].StringValue; + Name = m.Matches[1].StringValue; + } +} + +public class CastExpression : ShaderToken +{ + public TypeNameLiteral Target { get; set; } + public ShaderToken From { get; set; } + public CastExpression(Match m) + { + Target = new TypeNameLiteral(m.Matches[0]); + From = GetToken(m.Matches[1]); + } +} + +public class MulExpression : Operation +{ + public static MulExpression Create(Match m) + { + var first = new MulExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + MulExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new MulExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class SumExpression : Operation +{ + public static SumExpression Create(Match m) + { + var first = new SumExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + SumExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new SumExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class ShiftExpression : Operation +{ + public static ShiftExpression Create(Match m) + { + var first = new ShiftExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + ShiftExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new ShiftExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class AndExpression : Operation +{ + public static AndExpression Create(Match m) + { + var first = new AndExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + AndExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new AndExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} +public class XorExpression : Operation +{ + public static XorExpression Create(Match m) + { + var first = new XorExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + XorExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new XorExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} +public class OrExpression : Operation +{ + public static OrExpression Create(Match m) + { + var first = new OrExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + OrExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new OrExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class TestExpression : Operation +{ + public static TestExpression Create(Match m) + { + var first = new TestExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + TestExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new TestExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class EqualsExpression : Operation +{ + public static EqualsExpression Create(Match m) + { + var first = new EqualsExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + EqualsExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new EqualsExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class LogicalAndExpression : Operation +{ + public static LogicalAndExpression Create(Match m) + { + var first = new LogicalAndExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + LogicalAndExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new LogicalAndExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } + +} +public class LogicalOrExpression : Operation +{ + public static LogicalOrExpression Create(Match m) + { + var first = new LogicalOrExpression + { + Match = m, + Op = m.Matches[1].StringValue.AsOperatorToken(), + Left = GetToken(m.Matches[0]), + Right = GetToken(m.Matches[2]) + }; + + LogicalOrExpression tmp = first; + for (int i = 3; i < m.Matches.Count - 2; i += 2) + { + tmp = new LogicalOrExpression + { + Match = m, + Op = m.Matches[i].StringValue.AsOperatorToken(), + Left = tmp, + Right = GetToken(m.Matches[i + 1]) + }; + } + return tmp; + } +} + +public class ConditionalExpression : ShaderToken +{ + public ShaderToken Condition { get; set; } + public ShaderToken TrueOutput { get; set; } + public ShaderToken FalseOutput { get; set; } + + + public ConditionalExpression(Match m) + { + Condition = GetToken(m.Matches[0]); + TrueOutput = GetToken(m.Matches[1]); + FalseOutput = GetToken(m.Matches[2]); + } +} diff --git a/src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs b/src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs new file mode 100644 index 0000000000..2877e5e079 --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Shader; + +public enum OperatorToken +{ + Mul, + Div, + Mod, + Plus, + Minus, + LeftShift, + RightShift, + And, + Or, + Xor, + Less, + Greater, + LessEqual, + GreaterEqual, + Equals, + NotEquals, + LogicalAnd, + LogicalOr +} + +public static class OperatorTokenExtensions +{ + public static OperatorToken AsOperatorToken(this string s) + { + return s switch + { + "*" => OperatorToken.Mul, + "/" => OperatorToken.Div, + "%" => OperatorToken.Mod, + "+" => OperatorToken.Plus, + "-" => OperatorToken.Minus, + "<<" => OperatorToken.LeftShift, + ">>" => OperatorToken.RightShift, + "|" => OperatorToken.Or, + "&" => OperatorToken.And, + "^" => OperatorToken.Xor, + "<" => OperatorToken.Less, + "<=" => OperatorToken.LessEqual, + ">" => OperatorToken.Greater, + ">=" => OperatorToken.GreaterEqual, + "==" => OperatorToken.Equals, + "!=" => OperatorToken.NotEquals, + "&&" => OperatorToken.LogicalAnd, + "||" => OperatorToken.LogicalOr, + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs b/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs similarity index 68% rename from src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs rename to src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs index d010277cce..7f6006c4b9 100644 --- a/src/Stride.Shader.Parsing/AST/Expressions/ExpressionToken.cs +++ b/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs @@ -6,24 +6,12 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Expressions; +namespace Stride.Shader.Parsing.AST.Shader; -public abstract class ExpressionToken +public abstract class ShaderToken { - static ExpressionGrammar grammar; - protected static ExpressionGrammar Grammar { get { return grammar ??= new ExpressionGrammar(); } } - - public Match Match { get; set; } - - public static ExpressionToken Parse(string expr) - { - var match = Grammar.Match(expr); - if (!match.Success) - throw new ArgumentOutOfRangeException("expr", string.Format("Invalid expr string: {0}", match.ErrorMessage)); - return GetToken(match.Matches.First()); - } - - public static ExpressionToken GetToken(Match match) + public Match? Match { get; set; } + public static ShaderToken GetToken(Match match) { var tmp = match; while (tmp.Matches.Count == 1) @@ -48,6 +36,7 @@ public static ExpressionToken GetToken(Match match) "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), "VariableTerm" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), + "Boolean" => new BoolLiteral(tmp), _ => throw new NotImplementedException() }; } diff --git a/src/Stride.Shader.Parsing/ExpressionParser.cs b/src/Stride.Shader.Parsing/ExpressionParser.cs index fd29f5de73..4f468af4fc 100644 --- a/src/Stride.Shader.Parsing/ExpressionParser.cs +++ b/src/Stride.Shader.Parsing/ExpressionParser.cs @@ -2,7 +2,7 @@ namespace Stride.Shader.Parsing; using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shader.Parsing.AST.Expressions; +using Stride.Shader.Parsing.AST.Shader; using Stride.Shader.Parsing.Grammars; using Stride.Shader.Parsing.Grammars.Comments; using Stride.Shader.Parsing.Grammars.Directive; @@ -11,10 +11,14 @@ namespace Stride.Shader.Parsing; using System.Text; public class ExpressionParser { - //public IEnumerable Defined { get; set; } + public ExpressionGrammar Grammar { get; set; } = new(); - public ExpressionToken Parse(string expr) + public ShaderToken Parse(string expr) { - return ExpressionToken.Parse(expr); + var match = Grammar.Match(expr); + if (!match.Success) + throw new ArgumentOutOfRangeException("expr", string.Format("Invalid expr string: {0}", match.ErrorMessage)); + return ShaderToken.GetToken(match.Matches.First()); } + } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs index ab9a90abe6..d6a6852e82 100644 --- a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs @@ -56,7 +56,8 @@ public void CreateLiterals() IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Named("IntegerLiteral"), FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral"), HexaDecimalLiteral, - StringLiteral + StringLiteral, + BooleanTerm ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 2f20c947e4..1dc4c77358 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -122,8 +122,8 @@ public void CreateExpressions() { Name = "CastExpression", Separator = ws}; CastExpression.Add( + UnaryExpression, cast - //UnaryExpression ); diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index 378b9910bb..e871c7b466 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -17,7 +17,7 @@ public partial class SDSLGrammar : Grammar public HexDigitTerminal HexDigits = new(); public SequenceParser HexaDecimalLiteral = new(); - public BooleanTerminal BooleanTerm = new(); + public BooleanTerminal BooleanTerm = new() { Name = "BooleanTerm"}; public AlternativeParser Literals = new(); @@ -68,7 +68,8 @@ public void CreateLiterals() FloatLiteral.NotFollowedBy(Set("xX")).Named("FloatLiteral"), FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix).Named("FloatLiteral"), HexaDecimalLiteral, - StringLiteral + StringLiteral, + BooleanTerm ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/SDSLParser.cs index b02d9b3dd5..77989cb68b 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/SDSLParser.cs @@ -2,6 +2,7 @@ namespace Stride.Shader.Parsing; using Eto.Parse; using Eto.Parse.Grammars; +using Stride.Shader.Parsing.AST.Shader; using Stride.Shader.Parsing.Grammars; using Stride.Shader.Parsing.Grammars.Comments; using Stride.Shader.Parsing.Grammars.Directive; From efec356f2c155ff966ec4b35f360ad20354a8bf5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 16:07:51 +0200 Subject: [PATCH 0076/1182] Removed resx files --- src/SDSLParserExample/SDSLParserExample.csproj | 7 ------- .../Stride.Shader.Parsing.csproj | 16 ---------------- 2 files changed, 23 deletions(-) diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj index 261e26d98f..04accbf910 100644 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -11,11 +11,4 @@ enable enable - - - - - - - diff --git a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj index bd269449a0..0c581aaf7a 100644 --- a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj +++ b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj @@ -9,20 +9,4 @@ enable enable - - - True - True - GrammarResource.resx - - - - - - ResXFileCodeGenerator - GrammarResource.Designer.cs - - - - From 9f847583165fc80612a751a258ebc702c1358c65 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 16:41:31 +0200 Subject: [PATCH 0077/1182] Unary AST --- src/SDSLParserExample/Program.cs | 4 +- .../AST/Shader/Literals.cs | 4 + .../AST/Shader/Operations.cs | 22 ------ .../AST/Shader/ShaderToken.cs | 5 +- .../AST/Shader/UnaryLiterals.cs | 76 +++++++++++++++++++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 24 +++--- 6 files changed, 98 insertions(+), 37 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index b812e43daf..afcce1c607 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -13,10 +13,10 @@ sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); -var match2 = parser.Parse("false"); +var match2 = parser.Parse("true"); s.Start(); -var match = parser.Parse("true ? 5 : 8+my_var"); +var match = parser.Parse("a.b[0]"); s.Stop(); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/Stride.Shader.Parsing/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/AST/Shader/Literals.cs index e9773c7b7f..d04a8493ea 100644 --- a/src/Stride.Shader.Parsing/AST/Shader/Literals.cs +++ b/src/Stride.Shader.Parsing/AST/Shader/Literals.cs @@ -95,4 +95,8 @@ public VariableNameLiteral(Match m) { Name = m.StringValue; } + public override string ToString() + { + return $"{{ Variable : {Name} }}" ; + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs index 52e8356078..d239c201c4 100644 --- a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs @@ -16,28 +16,6 @@ public class Operation : ShaderToken public ShaderToken Right { get; set; } } -public class PrefixIncrement : ShaderToken -{ - public string Operator { get; set; } - public string Name { get; set; } - public PrefixIncrement(Match m) - { - Match = m; - Operator = m.Matches[0].StringValue; - Name = m.Matches[1].StringValue; - } -} - -public class CastExpression : ShaderToken -{ - public TypeNameLiteral Target { get; set; } - public ShaderToken From { get; set; } - public CastExpression(Match m) - { - Target = new TypeNameLiteral(m.Matches[0]); - From = GetToken(m.Matches[1]); - } -} public class MulExpression : Operation { diff --git a/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs index 7f6006c4b9..cf7dda0462 100644 --- a/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs @@ -32,7 +32,10 @@ public static ShaderToken GetToken(Match match) "SumExpression" => SumExpression.Create(tmp), "MulExpression" => MulExpression.Create(tmp), "CastExpression" => new CastExpression(tmp), - "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), + "PostfixIncrement" => new PostfixIncrement(tmp), + "ArrayAccessor" => new ArrayAccessor(tmp), + "ChainAccessor" => new ChainAccessor(tmp), + "PrefixIncrement" => new PrefixIncrement(tmp), "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), "VariableTerm" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), diff --git a/src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs b/src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs new file mode 100644 index 0000000000..3da2a4c01e --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs @@ -0,0 +1,76 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Shader; + + +public class ChainAccessor : ShaderToken +{ + public ShaderToken Value { get; set; } + public ShaderToken Field { get; set; } + + public ChainAccessor(Match m) + { + Match = m; + Value = GetToken(m.Matches[0]); + Field = GetToken(m.Matches[1]); + } +} + +public class ArrayAccessor : ShaderToken +{ + public ShaderToken Value { get; set; } + public IEnumerable Accessors { get; set; } + + public ArrayAccessor(Match m) + { + Match = m; + Value= GetToken(m.Matches[0]); + Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); + } +} + + +public class PostfixIncrement : ShaderToken +{ + public string Operator { get; set; } + public ShaderToken Value { get; set; } + public PostfixIncrement(Match m) + { + Match = m; + Value = GetToken(m.Matches[0]); + Operator = m.Matches[1].StringValue; + } + + public override string ToString() + { + return $"{{ PostfixIncrement : [\"{Value}\", \"{Operator}\"] }}"; + } +} + +public class PrefixIncrement : ShaderToken +{ + public string Operator { get; set; } + public ShaderToken Value { get; set; } + public PrefixIncrement(Match m) + { + Match = m; + Operator = m.Matches[0].StringValue; + Value = GetToken(m.Matches[1]); + } +} + +public class CastExpression : ShaderToken +{ + public TypeNameLiteral Target { get; set; } + public ShaderToken From { get; set; } + public CastExpression(Match m) + { + Target = new TypeNameLiteral(m.Matches[0]); + From = GetToken(m.Matches[1]); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 1dc4c77358..98316591e7 100644 --- a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -69,9 +69,9 @@ public void CreateExpressions() Parenthesis(PrimaryExpression) ); - var arrayAccess = new SequenceParser(); - var chain = new SequenceParser(); - var postfixInc = new SequenceParser(); + var arrayAccess = new SequenceParser() { Name = "ArrayAccessor"}; + var chain = new SequenceParser() { Name = "ChainAccessor"}; + var postfixInc = new SequenceParser() { Name = "PostfixIncrement"}; arrayAccess.Add( @@ -86,30 +86,30 @@ public void CreateExpressions() (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(ws & Dot & ws) ); postfixInc.Add( - chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, + chain | arrayAccess | Identifier, ws, incrementOp.Named("Operator") ); PostfixExpression.Add( TermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), - postfixInc.Named("PostfixIncrement"), - chain.Named("AccessorChain"), - arrayAccess.Named("ArrayAccesor") + postfixInc, + chain, + arrayAccess ); - var prefixInc = new SequenceParser(); - prefixInc.Add( - incrementOp, + var prefixInc = new SequenceParser( + incrementOp.Named("Operator"), ws, Identifier.NotFollowedBy(ws & (Dot | "[")) | chain | arrayAccess - ); + ) + { Name = "PrefixIncrement"}; UnaryExpression.Add( PostfixExpression, - prefixInc.Named("PrefixIncrement"), + prefixInc, Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") ); From e7ed8b0266523f8b733e143a2390af5da61c82f2 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 24 May 2022 17:02:48 +0200 Subject: [PATCH 0078/1182] Duplicated code from Shader to directives --- src/SDSLParserExample/Program.cs | 2 +- .../AST/Directives/DirectiveToken.cs | 1 - .../AST/Directives/Literals.cs | 4 + .../AST/Directives/Operations.cs | 23 +----- .../AST/Directives/UnaryLiterals.cs | 76 +++++++++++++++++++ .../AST/Shader/Operations.cs | 2 +- 6 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index afcce1c607..cfaaf4ddb3 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -16,7 +16,7 @@ var match2 = parser.Parse("true"); s.Start(); -var match = parser.Parse("a.b[0]"); +var match = parser.Parse("false ? 2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b : false"); s.Stop(); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs index dae33253cb..e4d0da753e 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs @@ -1,5 +1,4 @@ using Eto.Parse; -using Stride.Shader.Parsing.AST.Shader; using Stride.Shader.Parsing.Grammars.Expression; using System; using System.Collections.Generic; diff --git a/src/Stride.Shader.Parsing/AST/Directives/Literals.cs b/src/Stride.Shader.Parsing/AST/Directives/Literals.cs index 675aedda14..15d2b5ccf1 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/Literals.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/Literals.cs @@ -95,4 +95,8 @@ public VariableNameLiteral(Match m) { Name = m.StringValue; } + public override string ToString() + { + return $"{{ Variable : {Name} }}" ; + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Directives/Operations.cs b/src/Stride.Shader.Parsing/AST/Directives/Operations.cs index 57aab9ff0a..4cd2b99a9a 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Directives/Operations.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shader.Parsing.AST.Directives; using System; using System.Collections.Generic; using System.Linq; @@ -15,28 +16,6 @@ public class Operation : DirectiveToken public DirectiveToken Right { get; set; } } -public class PrefixIncrement : DirectiveToken -{ - public string Operator { get; set; } - public string Name { get; set; } - public PrefixIncrement(Match m) - { - Match = m; - Operator = m.Matches[0].StringValue; - Name = m.Matches[1].StringValue; - } -} - -public class CastExpression : DirectiveToken -{ - public TypeNameLiteral Target { get; set; } - public DirectiveToken From { get; set; } - public CastExpression(Match m) - { - Target = new TypeNameLiteral(m.Matches[0]); - From = GetToken(m.Matches[1]); - } -} public class MulExpression : Operation { diff --git a/src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs b/src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs new file mode 100644 index 0000000000..d59159187f --- /dev/null +++ b/src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs @@ -0,0 +1,76 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + + +public class ChainAccessor : DirectiveToken +{ + public DirectiveToken Value { get; set; } + public DirectiveToken Field { get; set; } + + public ChainAccessor(Match m) + { + Match = m; + Value = GetToken(m.Matches[0]); + Field = GetToken(m.Matches[1]); + } +} + +public class ArrayAccessor : DirectiveToken +{ + public DirectiveToken Value { get; set; } + public IEnumerable Accessors { get; set; } + + public ArrayAccessor(Match m) + { + Match = m; + Value= GetToken(m.Matches[0]); + Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); + } +} + + +public class PostfixIncrement : DirectiveToken +{ + public string Operator { get; set; } + public DirectiveToken Value { get; set; } + public PostfixIncrement(Match m) + { + Match = m; + Value = GetToken(m.Matches[0]); + Operator = m.Matches[1].StringValue; + } + + public override string ToString() + { + return $"{{ PostfixIncrement : [\"{Value}\", \"{Operator}\"] }}"; + } +} + +public class PrefixIncrement : DirectiveToken +{ + public string Operator { get; set; } + public DirectiveToken Value { get; set; } + public PrefixIncrement(Match m) + { + Match = m; + Operator = m.Matches[0].StringValue; + Value = GetToken(m.Matches[1]); + } +} + +public class CastExpression : DirectiveToken +{ + public TypeNameLiteral Target { get; set; } + public DirectiveToken From { get; set; } + public CastExpression(Match m) + { + Target = new TypeNameLiteral(m.Matches[0]); + From = GetToken(m.Matches[1]); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs index d239c201c4..b292c728c1 100644 --- a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs +++ b/src/Stride.Shader.Parsing/AST/Shader/Operations.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shader.Parsing.AST.Directives.OperatorTokenExtensions; +using static Stride.Shader.Parsing.AST.Shader.OperatorTokenExtensions; namespace Stride.Shader.Parsing.AST.Shader; From b9f1e467df3bd48111ccb29e2d770ae2f86c4944 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 25 May 2022 18:53:56 +0200 Subject: [PATCH 0079/1182] added ifdefine directive pre processor --- src/SDSLParserExample/Program.cs | 10 +- src/SDSLParserExample/SDSL/shader2.sdsl | 105 +---------- .../BasicExpressionParsing.cs | 79 ++++---- .../OperationExpressionParsing.cs | 178 +++++++++--------- .../AST/Directives/DirectiveToken.cs | 43 ----- .../AST/Directives/Directives.cs | 32 ---- .../AST/Directives/Literals.cs | 102 ---------- .../AST/Directives/OperatorToken.cs | 58 ------ .../Front/AST/Directives/DirectiveToken.cs | 141 ++++++++++++++ .../Front/AST/Directives/Directives.cs | 150 +++++++++++++++ .../Front/AST/Directives/Literals.cs | 151 +++++++++++++++ .../{ => Front}/AST/Directives/Operations.cs | 153 ++++++++++++++- .../Front/AST/Directives/OperatorToken.cs | 122 ++++++++++++ .../AST/Directives/UnaryLiterals.cs | 20 +- .../{ => Front}/AST/Shader/Literals.cs | 0 .../{ => Front}/AST/Shader/Operations.cs | 0 .../{ => Front}/AST/Shader/OperatorToken.cs | 0 .../{ => Front}/AST/Shader/ShaderToken.cs | 0 .../{ => Front}/AST/Shader/UnaryLiterals.cs | 0 .../{ => Front}/ExpressionParser.cs | 0 .../{ => Front}/Grammars/CommentGrammar.cs | 0 .../DirectiveGrammar.Directives.Expression.cs | 0 .../DirectiveGrammar.Directives.cs | 18 +- .../DirectiveGrammar.Tokens.cs | 0 .../DirectiveGrammar/DirectiveGrammar.cs | 0 .../DirectiveGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.TokenGroups.cs | 0 .../{ => Front}/Grammars/ExpressionGrammar.cs | 0 .../SDSLGrammar/SDSLGrammar.Declaration.cs | 0 .../SDSLGrammar.Directives.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Directives.cs | 0 .../SDSLGrammar/SDSLGrammar.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.MethodDeclaration.cs | 0 .../SDSLGrammar/SDSLGrammar.Shader.cs | 0 ...ar.Statements.ConditionalFlowStatements.cs | 0 ...SLGrammar.Statements.LoopFlowStatements.cs | 0 .../SDSLGrammar/SDSLGrammar.Statements.cs | 0 .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 0 .../SDSLGrammar/SDSLGrammar.Tokens.cs | 0 .../Grammars/SDSLGrammar/SDSLGrammar.cs | 0 .../{ => Front}/Hlsl/HlslExpr.g4 | 0 .../{ => Front}/Hlsl/HlslTokens.g4 | 0 .../{ => Front}/Hlsl/code.hlsl | 0 .../{ => Front}/SDSLParser.cs | 47 ++++- 45 files changed, 920 insertions(+), 489 deletions(-) delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/Directives.cs delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/Literals.cs delete mode 100644 src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs create mode 100644 src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs create mode 100644 src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs create mode 100644 src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs rename src/Stride.Shader.Parsing/{ => Front}/AST/Directives/Operations.cs (59%) create mode 100644 src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs rename src/Stride.Shader.Parsing/{ => Front}/AST/Directives/UnaryLiterals.cs (74%) rename src/Stride.Shader.Parsing/{ => Front}/AST/Shader/Literals.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/AST/Shader/Operations.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/AST/Shader/OperatorToken.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/AST/Shader/ShaderToken.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/AST/Shader/UnaryLiterals.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/ExpressionParser.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/CommentGrammar.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs (87%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/DirectiveGrammar.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/ExpressionGrammar.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Grammars/SDSLGrammar/SDSLGrammar.cs (100%) rename src/Stride.Shader.Parsing/{ => Front}/Hlsl/HlslExpr.g4 (100%) rename src/Stride.Shader.Parsing/{ => Front}/Hlsl/HlslTokens.g4 (100%) rename src/Stride.Shader.Parsing/{ => Front}/Hlsl/code.hlsl (100%) rename src/Stride.Shader.Parsing/{ => Front}/SDSLParser.cs (63%) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index cfaaf4ddb3..3be42906ed 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -13,13 +13,17 @@ sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); -var match2 = parser.Parse("true"); +var match2 = sdsl.ParseDirectives("true"); s.Start(); -var match = parser.Parse("false ? 2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b : false"); +var match = sdsl.ParseDirectives(shaderf); s.Stop(); +Console.WriteLine(new string('*', 32)); +Console.WriteLine(shaderf); +Console.WriteLine(new string('*',32)); +Console.WriteLine(sdsl.FinalCode); +Console.WriteLine(new string('*', 32) + "\n\n\n"); Console.WriteLine($"parsing time : {s.Elapsed}"); -Console.WriteLine(match); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 487c3da1db..d6a680b2aa 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,99 +1,12 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.LightProbes -{ - /// - /// Defines a skybox environment light - /// - shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils - { - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { -#ifdef STRIDE_MULTISAMPLE_COUNT - #if STRIDE_MULTISAMPLE_COUNT > 1 - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #else - stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #endif -#else - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +Some code before +#define a +#ifdef a +#if 5 == 2+3 +Success, 5 equals 5 #endif - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } - - void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) - { - // Early exit - if (weight == 0.0f) - return; - - int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; - for (int i = 0; i < TOrder * TOrder; ++i) - { - // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly - sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; - } - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - var sampleDirection = streams.normalWS; - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - var shadingPosition = int3(streams.ShadingPosition.xy, 0); -#if STRIDE_MULTISAMPLE_COUNT == 1 - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); -#else - // TODO: Use SV_SampleIndex - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); #endif - uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); - float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); - - float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); - - // Protect ourselves against degenerate cases - // TODO: Investigate why those happen (almost coplanar tetrahedron?) - tetrahedronFactors3 = saturate(tetrahedronFactors3); - - float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); - - // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) - tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Renormalize barycentric coordinates - var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; - if (totalSum > 0.0f) - tetrahedronFactors4 /= totalSum; - - float3 sphericalColors[TOrder * TOrder]; - for (int i = 0; i < TOrder * TOrder; ++i) - sphericalColors[i] = 0.0f; - - FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); - FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); - FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); - FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - - streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - // TEST: - //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - //streams.envLightDiffuseColor = tetrahedronFactors3; - //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); - } - }; -} +#if 8 == 2 +This code should disappear +#endif +Some code after \ No newline at end of file diff --git a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs index 7526494a22..50cce9b0b2 100644 --- a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs @@ -19,15 +19,15 @@ public void TestTerms() { parser.Grammar.Using(parser.Grammar.TermExpression); List matches = new(){ - parser.Parse("5"), - parser.Parse("5l"), - parser.Parse("5u"), - parser.Parse("5f"), - parser.Parse(".5"), - parser.Parse("5f"), - parser.Parse(".5d"), - parser.Parse("my_var"), - parser.Parse("\"Hello World\"") + parser.TestParse("5"), + parser.TestParse("5l"), + parser.TestParse("5u"), + parser.TestParse("5f"), + parser.TestParse(".5"), + parser.TestParse("5f"), + parser.TestParse(".5d"), + parser.TestParse("my_var"), + parser.TestParse("\"Hello World\"") }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -37,17 +37,17 @@ public void TestPostfix() { parser.Grammar.Using(parser.Grammar.PostfixExpression.Then(";")); List matches = new(){ - parser.Parse("my_var++;"), - parser.Parse("my_var.a;"), - parser.Parse("my_var[0];"), - parser.Parse("my_var[a];"), - parser.Parse("my_var.a[0];"), - parser.Parse("my_var.a[b];"), - parser.Parse("my_var.a[b]++;"), - parser.Parse("my_var.a[0].c;"), - parser.Parse("my_var.a[b].c;"), - parser.Parse("my_var.a[b].c++;"), - parser.Parse("my_var.a[b].c[5].b.e[7][5]++;"), + parser.TestParse("my_var++;"), + parser.TestParse("my_var.a;"), + parser.TestParse("my_var[0];"), + parser.TestParse("my_var[a];"), + parser.TestParse("my_var.a[0];"), + parser.TestParse("my_var.a[b];"), + parser.TestParse("my_var.a[b]++;"), + parser.TestParse("my_var.a[0].c;"), + parser.TestParse("my_var.a[b].c;"), + parser.TestParse("my_var.a[b].c++;"), + parser.TestParse("my_var.a[b].c[5].b.e[7][5]++;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -60,15 +60,15 @@ public void TestUnary() parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); List matches = new() { - parser.Parse("++b;"), - parser.Parse("++my_var.a;"), - parser.Parse("++my_var[0];"), - parser.Parse("++my_var[a];"), - parser.Parse("++my_var.a[0];"), - parser.Parse("++my_var.a[b];"), - parser.Parse("++my_var.a[0].c;"), - parser.Parse("++my_var.a[b].c;"), - parser.Parse("++my_var.a[b].c[5].b.e[7][5];"), + parser.TestParse("++b;"), + parser.TestParse("++my_var.a;"), + parser.TestParse("++my_var[0];"), + parser.TestParse("++my_var[a];"), + parser.TestParse("++my_var.a[0];"), + parser.TestParse("++my_var.a[b];"), + parser.TestParse("++my_var.a[0].c;"), + parser.TestParse("++my_var.a[b].c;"), + parser.TestParse("++my_var.a[b].c[5].b.e[7][5];"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); } @@ -79,19 +79,16 @@ public void TestCast() parser.Grammar.Using(parser.Grammar.CastExpression.Then(";")); List matches = new() { - parser.Parse("(float)++my_var;"), - parser.Parse("(float)++my_var.a;"), - parser.Parse("(float4)my_var[0]++;"), - parser.Parse("(float4x4)++my_var[a];"), - parser.Parse("(MyStruct)++my_var.a[0];"), - parser.Parse("(MyStruct)my_var.a[b]++;"), - parser.Parse("(MyStruct)++my_var.a[0].c;"), - parser.Parse("(MyStruct)my_var.a[b].c++;"), - parser.Parse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + parser.TestParse("(float)++my_var;"), + parser.TestParse("(float)++my_var.a;"), + parser.TestParse("(float4)my_var[0]++;"), + parser.TestParse("(float4x4)++my_var[a];"), + parser.TestParse("(MyStruct)++my_var.a[0];"), + parser.TestParse("(MyStruct)my_var.a[b]++;"), + parser.TestParse("(MyStruct)++my_var.a[0].c;"), + parser.TestParse("(MyStruct)my_var.a[b].c++;"), + parser.TestParse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); } - - - } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs index ec94cdd8e0..5afffd44e8 100644 --- a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs +++ b/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs @@ -20,17 +20,17 @@ public void TestMul() parser.Grammar.Using(parser.Grammar.MulExpression.Then(";")); List matches = new() { - parser.Parse("5*3;"), - parser.Parse("5*3*4;"), - parser.Parse("5 * (float)++my_var;"), - parser.Parse("5* (float)++my_var.a;"), - parser.Parse("(float4)my_var[0]++ * 2;"), - parser.Parse("(float4x4)++my_var[a]* 2;"), - parser.Parse("(MyStruct)++my_var.a[0] * 2;"), - parser.Parse("2 * 3 * (MyStruct)my_var.a[b]++;"), - parser.Parse("(MyStruct)++my_var.a[0].c *4* 5;"), - parser.Parse("(float)my_value * (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.Parse("(float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5];"), + parser.TestParse("5*3;"), + parser.TestParse("5*3*4;"), + parser.TestParse("5 * (float)++my_var;"), + parser.TestParse("5* (float)++my_var.a;"), + parser.TestParse("(float4)my_var[0]++ * 2;"), + parser.TestParse("(float4x4)++my_var[a]* 2;"), + parser.TestParse("(MyStruct)++my_var.a[0] * 2;"), + parser.TestParse("2 * 3 * (MyStruct)my_var.a[b]++;"), + parser.TestParse("(MyStruct)++my_var.a[0].c *4* 5;"), + parser.TestParse("(float)my_value * (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.TestParse("(float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5];"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -42,18 +42,18 @@ public void TestSum() parser.Grammar.Using(parser.Grammar.SumExpression.Then(";")); List matches = new() { - parser.Parse("5+3;"), - parser.Parse("a + b++ * 3 + 4;"), - parser.Parse("5+3+4;"), - parser.Parse("3 + 5 * (float)++my_var;"), - parser.Parse("3 + 5* (float)++my_var.a;"), - parser.Parse("a + (float4)my_var[0]++ * 2 + 4;"), - parser.Parse("my_otherVar + (float4x4)++my_var[a]* 2 - 2;"), - parser.Parse("(float)1 + (MyStruct)++my_var.a[0] * 2;"), - parser.Parse("2 * 3 + (MyStruct)my_var.a[b]++;"), - parser.Parse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5;"), - parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.Parse("2 + (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] + ++b;"), + parser.TestParse("5+3;"), + parser.TestParse("a + b++ * 3 + 4;"), + parser.TestParse("5+3+4;"), + parser.TestParse("3 + 5 * (float)++my_var;"), + parser.TestParse("3 + 5* (float)++my_var.a;"), + parser.TestParse("a + (float4)my_var[0]++ * 2 + 4;"), + parser.TestParse("my_otherVar + (float4x4)++my_var[a]* 2 - 2;"), + parser.TestParse("(float)1 + (MyStruct)++my_var.a[0] * 2;"), + parser.TestParse("2 * 3 + (MyStruct)my_var.a[b]++;"), + parser.TestParse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5;"), + parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.TestParse("2 + (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] + ++b;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -66,18 +66,18 @@ public void TestShift() parser.Grammar.Using(parser.Grammar.ShiftExpression.Then(";")); List matches = new() { - parser.Parse("5 << 5+3;"), - parser.Parse("a + b++ * 3 << 4;"), - parser.Parse("5 << 3 >> 4;"), - parser.Parse("3 + 5 * (float)++my_var;"), - parser.Parse("3 + 5* (float)++my_var.a;"), - parser.Parse("a >> (float4)my_var[0]++ * 2 + 4;"), - parser.Parse("my_otherVar << (float4x4)++my_var[a]* 2 - 2;"), - parser.Parse("(float)1 + (MyStruct)++my_var.a[0] << 2;"), - parser.Parse("2 * 3 + (MyStruct)my_var.a[b]++;"), - parser.Parse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5 >> 2;"), - parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.Parse("2 + (float)my_value << (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), + parser.TestParse("5 << 5+3;"), + parser.TestParse("a + b++ * 3 << 4;"), + parser.TestParse("5 << 3 >> 4;"), + parser.TestParse("3 + 5 * (float)++my_var;"), + parser.TestParse("3 + 5* (float)++my_var.a;"), + parser.TestParse("a >> (float4)my_var[0]++ * 2 + 4;"), + parser.TestParse("my_otherVar << (float4x4)++my_var[a]* 2 - 2;"), + parser.TestParse("(float)1 + (MyStruct)++my_var.a[0] << 2;"), + parser.TestParse("2 * 3 + (MyStruct)my_var.a[b]++;"), + parser.TestParse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5 >> 2;"), + parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), + parser.TestParse("2 + (float)my_value << (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -90,18 +90,18 @@ public void TestTestExpr() parser.Grammar.Using(parser.Grammar.TestExpression.Then(";")); List matches = new() { - parser.Parse("5 < 5+3;"), - parser.Parse("a > b++ * 3 < 4;"), - parser.Parse("5 < 3 > 4;"), - parser.Parse("3 + 5 * (float)++my_var;"), - parser.Parse("3 + 5 > (float)++my_var.a*2;"), - parser.Parse("a >> (float4)my_var[0]++ * 2 + 4;"), - parser.Parse("my_otherVar > 2;"), - parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ >(float)my_value2;"), - parser.Parse("2 + (float)my_value < (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), + parser.TestParse("5 < 5+3;"), + parser.TestParse("a > b++ * 3 < 4;"), + parser.TestParse("5 < 3 > 4;"), + parser.TestParse("3 + 5 * (float)++my_var;"), + parser.TestParse("3 + 5 > (float)++my_var.a*2;"), + parser.TestParse("a >> (float4)my_var[0]++ * 2 + 4;"), + parser.TestParse("my_otherVar > 2;"), + parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ >(float)my_value2;"), + parser.TestParse("2 + (float)my_value < (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -113,19 +113,19 @@ public void TestEqualsExpr() parser.Grammar.Using(parser.Grammar.EqualsExpression.Then(";")); List matches = new() { - parser.Parse("true == false;"), - parser.Parse("true != false;"), - parser.Parse("a > b++ == 3 < 4;"), - parser.Parse("true == 3 != 4;"), - parser.Parse("3 == 5 * (float)++my_var;"), - parser.Parse("3 + 5 == (float)++my_var.a*2;"), - parser.Parse("5 == a >> (float4)my_var[0]++ * 2 + 4;"), - parser.Parse("my_otherVar > 2;"), - parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), - parser.Parse("2 + (float)my_value == (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), + parser.TestParse("true == false;"), + parser.TestParse("true != false;"), + parser.TestParse("a > b++ == 3 < 4;"), + parser.TestParse("true == 3 != 4;"), + parser.TestParse("3 == 5 * (float)++my_var;"), + parser.TestParse("3 + 5 == (float)++my_var.a*2;"), + parser.TestParse("5 == a >> (float4)my_var[0]++ * 2 + 4;"), + parser.TestParse("my_otherVar > 2;"), + parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), + parser.TestParse("2 + (float)my_value == (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -138,20 +138,20 @@ public void TestBinary() parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); List matches = new() { - parser.Parse("5 & 4;"), - parser.Parse("1 ^ 6;"), - parser.Parse("1 | 6;"), - parser.Parse("a >> b++ | 3 << 4;"), - parser.Parse("5 ^ 3 ^ 4;"), - parser.Parse("3 & 5 * (float)++my_var;"), - parser.Parse("3 + 5 | (float)++my_var.a*2;"), - parser.Parse("5 & a >> (float4)my_var[0]++ * 2 & 4;"), - parser.Parse("my_otherVar <> 2;"), - parser.Parse("(float)my_value + (MyStruct)my_var.a[b].c+++(float)my_value2;"), - parser.Parse("2 ^ (float)my_value | (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), + parser.TestParse("5 & 4;"), + parser.TestParse("1 ^ 6;"), + parser.TestParse("1 | 6;"), + parser.TestParse("a >> b++ | 3 << 4;"), + parser.TestParse("5 ^ 3 ^ 4;"), + parser.TestParse("3 & 5 * (float)++my_var;"), + parser.TestParse("3 + 5 | (float)++my_var.a*2;"), + parser.TestParse("5 & a >> (float4)my_var[0]++ * 2 & 4;"), + parser.TestParse("my_otherVar <> 2;"), + parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c+++(float)my_value2;"), + parser.TestParse("2 ^ (float)my_value | (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), }; Assert.True(matches.TrueForAll(x => !x.Errors.Any())); @@ -163,21 +163,21 @@ public void TestConditional() parser.Grammar.Using(parser.Grammar.ConditionalExpression.Then(";")); List matches = new() { - parser.Parse("true && true;"), - parser.Parse("true || false;"), - parser.Parse("1 || 6;"), - parser.Parse("a > b++ && 3 < 4;"), - parser.Parse("true == true || 3 != 4;"), - parser.Parse("3 || 5 * (float)++my_var;"), - parser.Parse("3 + 5 && (float)++my_var.a*2;"), - parser.Parse("5 == a && (float4)my_var[0]++ * 2 & 4;"), - parser.Parse("my_otherVar > 2 &&false;"), - parser.Parse("(float)my_value && (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), - parser.Parse("2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b;"), - parser.Parse("true ? 5 : 8;"), + parser.TestParse("true && true;"), + parser.TestParse("true || false;"), + parser.TestParse("1 || 6;"), + parser.TestParse("a > b++ && 3 < 4;"), + parser.TestParse("true == true || 3 != 4;"), + parser.TestParse("3 || 5 * (float)++my_var;"), + parser.TestParse("3 + 5 && (float)++my_var.a*2;"), + parser.TestParse("5 == a && (float4)my_var[0]++ * 2 & 4;"), + parser.TestParse("my_otherVar > 2 &&false;"), + parser.TestParse("(float)my_value && (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), + parser.TestParse("2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b;"), + parser.TestParse("true ? 5 : 8;"), }; diff --git a/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs b/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs deleted file mode 100644 index e4d0da753e..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/DirectiveToken.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Eto.Parse; -using Stride.Shader.Parsing.Grammars.Expression; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives; - - -public class DirectiveToken -{ - public Match Match { get; set; } - public static DirectiveToken GetToken(Match match) - { - var tmp = match; - while (tmp.Matches.Count == 1) - tmp = tmp.Matches.First(); - - return tmp.Name switch - { - "Ternary" => new ConditionalExpression(tmp), - "LogicalOrExpression" => LogicalOrExpression.Create(tmp), - "LogicalAndExpression" => LogicalAndExpression.Create(tmp), - "EqualsExpression" => EqualsExpression.Create(tmp), - "TestExpression" => TestExpression.Create(tmp), - "OrExpression" => OrExpression.Create(tmp), - "XorExpression" => XorExpression.Create(tmp), - "AndExpression" => AndExpression.Create(tmp), - "ShiftExpression" => ShiftExpression.Create(tmp), - "SumExpression" => SumExpression.Create(tmp), - "MulExpression" => MulExpression.Create(tmp), - "CastExpression" => new CastExpression(tmp), - "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), - "VariableTerm" => new VariableNameLiteral(tmp), - "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), - "Boolean" => new BoolLiteral(tmp), - _ => throw new NotImplementedException() - }; - } -} diff --git a/src/Stride.Shader.Parsing/AST/Directives/Directives.cs b/src/Stride.Shader.Parsing/AST/Directives/Directives.cs deleted file mode 100644 index 784e618c86..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/Directives.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives; - -public class DefineDirective : DirectiveToken -{ - public string VariableName { get; set; } - public DirectiveToken Value { get; set; } - - public DefineDirective(Match m) - { - Match = m; - VariableName = m.Matches[0].StringValue; - Value = GetToken(m.Matches[1]); - } -} - -public class IfDirective : DirectiveToken -{ - public DirectiveToken Condition { get; set; } - - public IfDirective(Match m) - { - Match = m; - Condition = GetToken(m.Matches[1]); - } -} diff --git a/src/Stride.Shader.Parsing/AST/Directives/Literals.cs b/src/Stride.Shader.Parsing/AST/Directives/Literals.cs deleted file mode 100644 index 15d2b5ccf1..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/Literals.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives; - -public class NumberLiteral : DirectiveToken -{ - public bool Negative { get; set; } = false; - public object? Value { get; set; } - public string? Suffix { get; set; } - - - public NumberLiteral() { } - - public NumberLiteral(Match match) - { - Match = match; - if (!match.HasMatches) - { - Value = match.Value; - } - else - { - if (match.Name == "SignedTermExpression") - { - - } - else - { - Value = match.Matches[0].Value; - Suffix = match["Suffix"].StringValue; - } - } - } -} -public class HexLiteral : DirectiveToken -{ - public ulong Value { get; set; } - - public HexLiteral() { } - - public HexLiteral(Match match) - { - Match = match; - Value = Convert.ToUInt64(match.StringValue, 16); - } -} -public class StringLiteral : DirectiveToken -{ - public string? Value { get; set; } - - - public StringLiteral() { } - - public StringLiteral(Match match) - { - Match = match; - Value = match.StringValue; - } -} - -public class BoolLiteral : DirectiveToken -{ - public bool Value { get; set; } - - public BoolLiteral() { } - - public BoolLiteral(Match match) - { - Match = match; - Value = (bool)match.Value; - } -} - - -public class TypeNameLiteral : DirectiveToken -{ - public string Name { get; set; } - - public TypeNameLiteral(Match m) - { - Name = m.StringValue; - } -} - -public class VariableNameLiteral : DirectiveToken -{ - public string Name { get; set; } - - public VariableNameLiteral(Match m) - { - Name = m.StringValue; - } - public override string ToString() - { - return $"{{ Variable : {Name} }}" ; - } -} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs b/src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs deleted file mode 100644 index aee471f412..0000000000 --- a/src/Stride.Shader.Parsing/AST/Directives/OperatorToken.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shader.Parsing.AST.Directives; - -public enum OperatorToken -{ - Mul, - Div, - Mod, - Plus, - Minus, - LeftShift, - RightShift, - And, - Or, - Xor, - Less, - Greater, - LessEqual, - GreaterEqual, - Equals, - NotEquals, - LogicalAnd, - LogicalOr -} - -public static class OperatorTokenExtensions -{ - public static OperatorToken AsOperatorToken(this string s) - { - return s switch - { - "*" => OperatorToken.Mul, - "/" => OperatorToken.Div, - "%" => OperatorToken.Mod, - "+" => OperatorToken.Plus, - "-" => OperatorToken.Minus, - "<<" => OperatorToken.LeftShift, - ">>" => OperatorToken.RightShift, - "|" => OperatorToken.Or, - "&" => OperatorToken.And, - "^" => OperatorToken.Xor, - "<" => OperatorToken.Less, - "<=" => OperatorToken.LessEqual, - ">" => OperatorToken.Greater, - ">=" => OperatorToken.GreaterEqual, - "==" => OperatorToken.Equals, - "!=" => OperatorToken.NotEquals, - "&&" => OperatorToken.LogicalAnd, - "||" => OperatorToken.LogicalOr, - _ => throw new NotImplementedException() - }; - } -} diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs new file mode 100644 index 0000000000..e8d9444736 --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs @@ -0,0 +1,141 @@ +using Eto.Parse; +using Stride.Shader.Parsing.Grammars.Expression; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + + +public abstract class DirectiveToken +{ + public Match Match { get; set; } + public abstract Type InferredType { get; set; } + + public abstract void EvaluateMacros(Dictionary macros); + + public static DirectiveToken GetToken(Match match) + { + var tmp = match; + while (tmp.Matches.Count == 1) + tmp = tmp.Matches.First(); + + return tmp.Name switch + { + "Directives" => new Directives(tmp), + "CodeSnippet" => new CodeSnippet(tmp), + "DefineDirective" => new DefineDirective(tmp), + "IfCode" => new IfCode(tmp), + "IfDefCode" or "IfNDefCode" => new IfDefCode(tmp), + "IfDefDirective" or "IfNDefDirective" => new IfDefineDirective(tmp), + "DirectiveTernary" => new ConditionalExpression(tmp), + "DirectiveLogicalOrExpression" => LogicalOrExpression.Create(tmp), + "DirectiveLogicalAndExpression" => LogicalAndExpression.Create(tmp), + "DirectiveEqualsExpression" => EqualsExpression.Create(tmp), + "DirectiveTestExpression" => TestExpression.Create(tmp), + "DirectiveOrExpression" => OrExpression.Create(tmp), + "DirectiveXorExpression" => XorExpression.Create(tmp), + "DirectiveAndExpression" => AndExpression.Create(tmp), + "DirectiveShiftExpression" => ShiftExpression.Create(tmp), + "DirectiveSumExpression" => SumExpression.Create(tmp), + "DirectiveMulExpression" => MulExpression.Create(tmp), + "DirectiveCastExpression" => new CastExpression(tmp), + "DirectivePrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), + "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), + "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), + "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), + "Boolean" => new BoolLiteral(tmp), + _ => throw new NotImplementedException() + }; + } + + public static void Evaluate(DirectiveToken token, Dictionary macros, StringBuilder code) + { + switch(token) + { + case Directives d: + foreach(var c in d.DirectiveList) + Evaluate(c, macros, code); + break; + case CodeSnippet snippet: + code.Append(snippet.Content); + break; + + case DefineDirective def: + macros.Add(def.VariableName, def.Value); + break; + + case IfDefCode ifdefcode: + if(CheckCondition(ifdefcode.If,macros)) + foreach (var c in ifdefcode.Children) + Evaluate(c, macros, code); + else + foreach (var c in ifdefcode.Children) + Evaluate(c, macros, code); + break; + + case IfCode ifCode: + if (CheckCondition(ifCode.If, macros)) + foreach (var c in ifCode.Children) + Evaluate(c, macros, code); + else + { + bool passed = false; + if (ifCode.Elifs is not null) + { + foreach (var e in ifCode.Elifs) + { + if (CheckCondition(e.Elif, macros)) + { + foreach (var c in e.Children) + Evaluate(c, macros, code); + passed = true; + break; + } + } + if (passed) + foreach (var c in ifCode.Children) + Evaluate(c, macros, code); + } + else if(!passed && ifCode.Else is not null) + foreach(var c in ifCode.Else.Children) + Evaluate(c, macros, code); + } + break; + default: + throw new NotImplementedException(""); + } + } + + public static bool CheckCondition(DirectiveToken token, Dictionary macros) + { + return token switch + { + IfDefineDirective ifDefine => ifDefine.IsDefined && macros.ContainsKey(ifDefine.Name), + IfDirective ifd => EvaluateExpression(ifd.Condition,macros), + ElifDirective elifd => EvaluateExpression(elifd.Condition,macros), + _ => throw new NotImplementedException("") + }; + } + + public static bool EvaluateExpression(DirectiveToken expr, Dictionary macros) + { + return expr switch + { + BoolLiteral b => b.Value, + Operation o => EvaluateOperation(o,macros), + _ => throw new Exception("Couldn't evaluate expression") + }; + } + private static bool EvaluateOperation(Operation operation, Dictionary macros) + { + operation.EvaluateMacros(macros); + return operation.ProjectConstant() switch + { + BoolLiteral b => b.Value, + _ => throw new Exception("Couldn't evaluate operation") + }; + } +} diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs new file mode 100644 index 0000000000..22442ed16b --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs @@ -0,0 +1,150 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + +public class DirectiveFlow : DirectiveToken +{ + public override Type InferredType { get => typeof(void); set { } } + + public override void EvaluateMacros(Dictionary macros) + { + throw new NotImplementedException(); + } +} + +public class Directives : DirectiveFlow +{ + public IEnumerable DirectiveList { get; set; } + public Directives(Match m) + { + Match = m; + DirectiveList = m.Matches.Select(GetToken); + } +} + +public class CodeSnippet: DirectiveFlow +{ + public string Content { get; set; } + + public CodeSnippet(Match m) + { + Match = m; + Content = m.StringValue; + } +} + +public class DefineDirective : DirectiveFlow +{ + public string VariableName { get; set; } + public DirectiveToken Value { get; set; } + + public DefineDirective(Match m) + { + Match = m; + VariableName = m.Matches[0].StringValue; + if(m.Matches.Count == 2) + Value = GetToken(m.Matches[1]); + } +} + +public class IfDefineDirective : DirectiveFlow +{ + public bool IsDefined { get; set; } + public string Name { get; set; } + + public IfDefineDirective(Match m) + { + Match = m; + IsDefined = m.Matches[0].StringValue == "ifdefine"; + Name = m.Matches[1].StringValue; + } +} + +public class IfDirective : DirectiveFlow +{ + public DirectiveToken Condition { get; set; } + + public IfDirective(Match m) + { + Match = m; + Condition = GetToken(m.Matches[1]); + } +} + +public class ElifDirective : DirectiveFlow +{ + public DirectiveToken Condition { get; set; } + + public ElifDirective(Match m) + { + Match = m; + Condition = GetToken(m.Matches[1]); + } +} + +public class ElseCode : DirectiveFlow +{ + public IEnumerable Children { get; set; } + public ElseCode(Match m) + { + Match = m; + Children = m["Children"].Matches.Select(GetToken); + } +} + +public class IfCode : DirectiveFlow +{ + public IfDirective If { get; set; } + public IEnumerable Children { get; set; } + public IEnumerable Elifs { get; set; } + public ElseCode Else { get; set; } + + + + public IfCode(Match m) + { + Match = m; + If = new IfDirective(m["IfDirective"]); + Children = m["Children"].Matches.Select(GetToken); + if(m.Matches.Any(x => x.Name == "ElifCode")) + Elifs = m.Matches.Where(x => x.Name == "ElifCode").Select(x => new ElifCode(x)); + if(m.Matches.Any(x => x.Name == "ElseCode")) + Else = new ElseCode(m["ElseCode"]); + } +} + +public class IfDefCode : DirectiveFlow +{ + public IfDefineDirective If { get; set; } + public IEnumerable Children { get; set; } + public ElseCode Else { get; set; } + + + + public IfDefCode(Match m) + { + Match = m; + If = new IfDefineDirective(m["IfDefDirective"]); + Children = m["Children"].Matches.Select(GetToken); + if (m.Matches.Any(x => x.Name == "ElseCode")) + Else = new ElseCode(m["ElseCode"]); + } +} + +public class ElifCode : DirectiveFlow +{ + public ElifDirective Elif { get; set; } + public IEnumerable Children { get; set; } + + + public ElifCode(Match m) + { + Match = m; + Children = m["Children"].Matches.Select(GetToken); + } +} diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs new file mode 100644 index 0000000000..f4c689e917 --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs @@ -0,0 +1,151 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + + +public class DirectiveLiteral : DirectiveToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override void EvaluateMacros(Dictionary macros) + { + throw new NotImplementedException(); + } +} + +public class NumberLiteral : DirectiveLiteral +{ + public bool Negative { get; set; } = false; + public object Value { get; set; } + public string? Suffix { get; set; } + + protected Type? inferredType; + + public override Type InferredType + { + get + { + if (inferredType is not null) + return inferredType; + if (Suffix is null) + return Value.GetType(); + else + { + return Suffix switch + { + "u" or "l" => typeof(long), + "f" or "d" => typeof(double), + _ => typeof(long) + }; + } + } + set => inferredType = value; + } + + public NumberLiteral() { } + + public NumberLiteral(Match match) + { + Match = match; + if (!match.HasMatches) + { + Value = match.Value; + } + else + { + if (match.Name == "SignedTermExpression") + { + + } + else + { + Value = match.Matches[0].Value; + Suffix = match["Suffix"].StringValue; + } + } + } +} +public class HexLiteral : NumberLiteral +{ + + public override Type InferredType + { + get + { + return typeof(long); + } + set => inferredType = value; + } + + + public HexLiteral() { } + + public HexLiteral(Match match) + { + Match = match; + Value = Convert.ToUInt64(match.StringValue, 16); + } +} +public class StringLiteral : DirectiveLiteral +{ + public string? Value { get; set; } + public override Type InferredType { get => typeof(string); set { } } + + public StringLiteral() { } + + public StringLiteral(Match match) + { + Match = match; + Value = match.StringValue; + } +} + +public class BoolLiteral : DirectiveLiteral +{ + public bool Value { get; set; } + public override Type InferredType { get => typeof(bool); set { } } + + public BoolLiteral() { } + + public BoolLiteral(Match match) + { + Match = match; + Value = (bool)match.Value; + } +} + + +public class TypeNameLiteral : DirectiveLiteral +{ + public string Name { get; set; } + + public TypeNameLiteral(Match m) + { + Name = m.StringValue; + } +} + +public class VariableNameLiteral : DirectiveLiteral +{ + public string Name { get; set; } + public object Value { get; set; } + + Type? inferredType; + + public override Type InferredType { get => inferredType ?? typeof(void); set => inferredType = value; } + + + public VariableNameLiteral(Match m) + { + Name = m.StringValue; + } + public override string ToString() + { + return $"{{ Variable : {Name} }}" ; + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/AST/Directives/Operations.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs similarity index 59% rename from src/Stride.Shader.Parsing/AST/Directives/Operations.cs rename to src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs index 4cd2b99a9a..a20cc94010 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/Operations.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs @@ -9,11 +9,101 @@ namespace Stride.Shader.Parsing.AST.Directives; -public class Operation : DirectiveToken +public abstract class Projector : DirectiveToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override void EvaluateMacros(Dictionary macros) + { + throw new NotImplementedException(); + } + + public abstract DirectiveToken ProjectConstant(); +} + +public class Operation : Projector { public OperatorToken Op { get; set; } + public DirectiveToken Left { get; set; } public DirectiveToken Right { get; set; } + + Type? inferredType; + public override Type InferredType + { + get => inferredType ?? typeof(void); + set => inferredType = value; + } + public override void EvaluateMacros(Dictionary macros) + { + if (Left is VariableNameLiteral vl) + { + if (macros.TryGetValue(vl.Name, out object value)) + { + Left = value switch + { + float v => new NumberLiteral { Value = v }, + double v => new NumberLiteral { Value = v }, + byte v => new NumberLiteral { Value = v }, + ushort v => new NumberLiteral { Value = v }, + uint v => new NumberLiteral { Value = v }, + ulong v => new NumberLiteral { Value = v }, + int v => new NumberLiteral { Value = v }, + long v => new NumberLiteral { Value = v }, + short v => new NumberLiteral { Value = v }, + sbyte v => new NumberLiteral { Value = v }, + bool v => new BoolLiteral { Value = v }, + string v => new StringLiteral { Value = v }, + _ => throw new Exception("Unusable type") + }; + } + else + throw new Exception("Macro does not exist"); + } + if (Right is VariableNameLiteral vr) + { + if (macros.TryGetValue(vr.Name, out object value)) + { + Right = value switch + { + float v => new NumberLiteral { Value = v }, + double v => new NumberLiteral { Value = v }, + byte v => new NumberLiteral { Value = v }, + ushort v => new NumberLiteral { Value = v }, + uint v => new NumberLiteral { Value = v }, + ulong v => new NumberLiteral { Value = v }, + int v => new NumberLiteral { Value = v }, + long v => new NumberLiteral { Value = v }, + short v => new NumberLiteral { Value = v }, + sbyte v => new NumberLiteral { Value = v }, + bool v => new BoolLiteral { Value = v }, + string v => new StringLiteral { Value = v }, + _ => throw new Exception("Unusable type") + }; + } + else + throw new Exception("Macro does not exist"); + } + } + + public override DirectiveToken ProjectConstant() + { + + if (Left is Projector) + Left = ((Projector)Left).ProjectConstant(); + if (Right is Projector) + Right = ((Projector)Right).ProjectConstant(); + + return (Left, Right) switch + { + (NumberLiteral ln, NumberLiteral rn) => ApplyOperation(Op, ln, rn), + (BoolLiteral ln, BoolLiteral rn) => ApplyOperation(Op, ln, rn), + (StringLiteral ln, StringLiteral rn) => ApplyOperation(Op, ln, rn), + _ => throw new Exception("Cannot process operation") + }; + } + + } @@ -285,12 +375,19 @@ public static LogicalOrExpression Create(Match m) } } -public class ConditionalExpression : DirectiveToken +public class ConditionalExpression : Projector { public DirectiveToken Condition { get; set; } public DirectiveToken TrueOutput { get; set; } public DirectiveToken FalseOutput { get; set; } + Type? inferredType; + + public override Type InferredType + { + get => inferredType ?? typeof(void); + set => inferredType = value; + } public ConditionalExpression(Match m) { @@ -298,4 +395,56 @@ public ConditionalExpression(Match m) TrueOutput = GetToken(m.Matches[1]); FalseOutput = GetToken(m.Matches[2]); } + + public override void EvaluateMacros(Dictionary macros) + { + if (Condition is VariableNameLiteral vcondition) + { + if (macros.TryGetValue(vcondition.Name, out object value)) + { + vcondition.Value = value; + vcondition.InferredType = value.GetType(); + } + else + throw new Exception("Macro does not exist"); + } + if (TrueOutput is VariableNameLiteral tout) + { + if (macros.TryGetValue(tout.Name, out object value)) + { + tout.Value = value; + tout.InferredType = value.GetType(); + } + else + throw new Exception("Macro does not exist"); + } + if (FalseOutput is VariableNameLiteral fout) + { + if (macros.TryGetValue(fout.Name, out object value)) + { + fout.Value = value; + fout.InferredType = value.GetType(); + } + else + throw new Exception("Macro does not exist"); + } + + } + + public override DirectiveToken ProjectConstant() + { + if (Condition is Projector) + Condition = ((Projector)Condition).ProjectConstant(); + + if (TrueOutput is Projector ) + TrueOutput= ((Projector)TrueOutput).ProjectConstant(); + + if (FalseOutput is Projector ) + FalseOutput= ((Projector)FalseOutput).ProjectConstant(); + + if (Condition is BoolLiteral c) + return c.Value ? TrueOutput : FalseOutput; + else + throw new Exception("Invalid condition"); + } } diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs new file mode 100644 index 0000000000..beb5cd283f --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Directives; + +public enum OperatorToken +{ + Mul, + Div, + Mod, + Plus, + Minus, + LeftShift, + RightShift, + And, + Or, + Xor, + Less, + Greater, + LessEqual, + GreaterEqual, + Equals, + NotEquals, + LogicalAnd, + LogicalOr +} + +public static class OperatorTokenExtensions +{ + public static OperatorToken AsOperatorToken(this string s) + { + return s switch + { + "*" => OperatorToken.Mul, + "/" => OperatorToken.Div, + "%" => OperatorToken.Mod, + "+" => OperatorToken.Plus, + "-" => OperatorToken.Minus, + "<<" => OperatorToken.LeftShift, + ">>" => OperatorToken.RightShift, + "|" => OperatorToken.Or, + "&" => OperatorToken.And, + "^" => OperatorToken.Xor, + "<" => OperatorToken.Less, + "<=" => OperatorToken.LessEqual, + ">" => OperatorToken.Greater, + ">=" => OperatorToken.GreaterEqual, + "==" => OperatorToken.Equals, + "!=" => OperatorToken.NotEquals, + "&&" => OperatorToken.LogicalAnd, + "||" => OperatorToken.LogicalOr, + _ => throw new NotImplementedException() + }; + } + + private static double OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToDouble(a); + var r = Convert.ToDouble(b); + return f.Invoke(l, r); + } + private static double OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToInt32(a); + var r = Convert.ToInt32(b); + return f.Invoke(l, r); + } + + private static bool OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToDouble(a); + var r = Convert.ToDouble(b); + return f.Invoke(l, r); + } + + public static DirectiveToken ApplyOperation(OperatorToken op, NumberLiteral l, NumberLiteral r) + { + return op switch + { + OperatorToken.Mul => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a*b) }, + OperatorToken.Div => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a / b) }, + OperatorToken.Mod => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a % b) }, + OperatorToken.Plus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a + b) }, + OperatorToken.Minus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a - b) }, + OperatorToken.LeftShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a,b) => a << b) }, + OperatorToken.RightShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a >> b) }, + OperatorToken.And => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a & b) }, + OperatorToken.Or => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a | b) }, + OperatorToken.Xor => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a ^ b) }, + OperatorToken.Less => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a < b) }, + OperatorToken.LessEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a <= b) }, + OperatorToken.Greater => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a > b) }, + OperatorToken.GreaterEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a >= b) }, + OperatorToken.Equals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a == b) }, + OperatorToken.NotEquals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a != b) }, + _ => throw new NotImplementedException() + }; + } + public static DirectiveToken ApplyOperation(OperatorToken op, BoolLiteral l, BoolLiteral r) + { + return op switch + { + OperatorToken.LogicalAnd => new BoolLiteral { Value = l.Value && r.Value }, + OperatorToken.LogicalOr => new BoolLiteral { Value = l.Value || r.Value }, + OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, + OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, + _ => throw new NotImplementedException() + }; + } + public static DirectiveToken ApplyOperation(OperatorToken op, StringLiteral l, StringLiteral r) + { + return op switch + { + OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, + OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, + _ => throw new NotImplementedException() + }; + } +} diff --git a/src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/UnaryLiterals.cs similarity index 74% rename from src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs rename to src/Stride.Shader.Parsing/Front/AST/Directives/UnaryLiterals.cs index d59159187f..8c00022ab9 100644 --- a/src/Stride.Shader.Parsing/AST/Directives/UnaryLiterals.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/UnaryLiterals.cs @@ -8,7 +8,17 @@ namespace Stride.Shader.Parsing.AST.Directives; -public class ChainAccessor : DirectiveToken +public class UnaryExpression : DirectiveToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override void EvaluateMacros(Dictionary macros) + { + throw new NotImplementedException(); + } +} + +public class ChainAccessor : UnaryExpression { public DirectiveToken Value { get; set; } public DirectiveToken Field { get; set; } @@ -21,7 +31,7 @@ public ChainAccessor(Match m) } } -public class ArrayAccessor : DirectiveToken +public class ArrayAccessor : UnaryExpression { public DirectiveToken Value { get; set; } public IEnumerable Accessors { get; set; } @@ -35,7 +45,7 @@ public ArrayAccessor(Match m) } -public class PostfixIncrement : DirectiveToken +public class PostfixIncrement : UnaryExpression { public string Operator { get; set; } public DirectiveToken Value { get; set; } @@ -52,7 +62,7 @@ public override string ToString() } } -public class PrefixIncrement : DirectiveToken +public class PrefixIncrement : UnaryExpression { public string Operator { get; set; } public DirectiveToken Value { get; set; } @@ -64,7 +74,7 @@ public PrefixIncrement(Match m) } } -public class CastExpression : DirectiveToken +public class CastExpression : UnaryExpression { public TypeNameLiteral Target { get; set; } public DirectiveToken From { get; set; } diff --git a/src/Stride.Shader.Parsing/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/AST/Shader/Literals.cs rename to src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs diff --git a/src/Stride.Shader.Parsing/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs similarity index 100% rename from src/Stride.Shader.Parsing/AST/Shader/Operations.cs rename to src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs diff --git a/src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/AST/Shader/OperatorToken.cs rename to src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs diff --git a/src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/AST/Shader/ShaderToken.cs rename to src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs diff --git a/src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs similarity index 100% rename from src/Stride.Shader.Parsing/AST/Shader/UnaryLiterals.cs rename to src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs diff --git a/src/Stride.Shader.Parsing/ExpressionParser.cs b/src/Stride.Shader.Parsing/Front/ExpressionParser.cs similarity index 100% rename from src/Stride.Shader.Parsing/ExpressionParser.cs rename to src/Stride.Shader.Parsing/Front/ExpressionParser.cs diff --git a/src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/CommentGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/CommentGrammar.cs rename to src/Stride.Shader.Parsing/Front/Grammars/CommentGrammar.cs diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 87% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index ed01b762e9..61dffbc8c9 100644 --- a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -34,13 +34,13 @@ public void CreateDirectives() var ws = WhiteSpace.Repeat(0); var hash = Literal("#"); - var hashIfNDef = Literal("#ifndef"); - var hashIfDef = Literal("#ifdef"); - var hashIf = Literal("#if"); - var hashEndIf = Literal("#endif"); - var hashElse = Literal("#else"); - var hashElif = Literal("#elif"); - var hashDefine = Literal("#define"); + var hashIfNDef = Literal("#ifndef").Named("ifndef"); + var hashIfDef = Literal("#ifdef").Named("ifdef"); + var hashIf = Literal("#if").Named("if"); + var hashEndIf = Literal("#endif").Named("endif"); + var hashElse = Literal("#else").Named("else"); + var hashElif = Literal("#elif").Named("elif"); + var hashDefine = Literal("#define").Named("define"); var startHash = hashIfNDef @@ -80,7 +80,7 @@ public void CreateDirectives() ElseDirective, AnyDirectives .Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) - .Repeat(0).Until(hashEndIf) + .Repeat(0).Until(hashEndIf).Named("Children") ); IfCode.Add( @@ -104,7 +104,7 @@ public void CreateDirectives() ); Directives.Add( - CodeOrDirective.Until(End) + CodeOrDirective.Until(End).Named("Directives") ); } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/ExpressionGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/ExpressionGrammar.cs rename to src/Stride.Shader.Parsing/Front/Grammars/ExpressionGrammar.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs diff --git a/src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Grammars/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.cs diff --git a/src/Stride.Shader.Parsing/Hlsl/HlslExpr.g4 b/src/Stride.Shader.Parsing/Front/Hlsl/HlslExpr.g4 similarity index 100% rename from src/Stride.Shader.Parsing/Hlsl/HlslExpr.g4 rename to src/Stride.Shader.Parsing/Front/Hlsl/HlslExpr.g4 diff --git a/src/Stride.Shader.Parsing/Hlsl/HlslTokens.g4 b/src/Stride.Shader.Parsing/Front/Hlsl/HlslTokens.g4 similarity index 100% rename from src/Stride.Shader.Parsing/Hlsl/HlslTokens.g4 rename to src/Stride.Shader.Parsing/Front/Hlsl/HlslTokens.g4 diff --git a/src/Stride.Shader.Parsing/Hlsl/code.hlsl b/src/Stride.Shader.Parsing/Front/Hlsl/code.hlsl similarity index 100% rename from src/Stride.Shader.Parsing/Hlsl/code.hlsl rename to src/Stride.Shader.Parsing/Front/Hlsl/code.hlsl diff --git a/src/Stride.Shader.Parsing/SDSLParser.cs b/src/Stride.Shader.Parsing/Front/SDSLParser.cs similarity index 63% rename from src/Stride.Shader.Parsing/SDSLParser.cs rename to src/Stride.Shader.Parsing/Front/SDSLParser.cs index 77989cb68b..9b966f4151 100644 --- a/src/Stride.Shader.Parsing/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/Front/SDSLParser.cs @@ -2,6 +2,7 @@ namespace Stride.Shader.Parsing; using Eto.Parse; using Eto.Parse.Grammars; +using Stride.Shader.Parsing.AST.Directives; using Stride.Shader.Parsing.AST.Shader; using Stride.Shader.Parsing.Grammars; using Stride.Shader.Parsing.Grammars.Comments; @@ -14,6 +15,10 @@ public class SDSLParser public SDSLGrammar Grammar {get;set;} public DirectiveGrammar Directive { get;set;} public StringBuilder UncommentedCode { get; set; } = new(); + public StringBuilder FinalCode { get; set; } = new(); + public Dictionary Macros { get; set; } = new(); + + public GrammarMatch? ParseTree { get; set; } //public IEnumerable Defined { get; set; } public SDSLParser() @@ -31,16 +36,15 @@ public SDSLParser With(Parser p) public void PrintParserTree(string shader) { - PrettyPrintMatches(Parse(shader).Matches[0]); + PrettyPrintMatches(ParseTree.Matches[0]); } - public GrammarMatch Parse(string shader) + private void RemoveComments(string code) { - var comments = Comments.Match(shader); - //var preprocessed = new StringBuilder(); + var comments = Comments.Match(code); if (!comments.Matches.Any(x => x.Name == "Comment")) { - return Directive.Match(shader); + UncommentedCode.Append(code); } else { @@ -51,14 +55,39 @@ public GrammarMatch Parse(string shader) UncommentedCode.AppendLine(m.StringValue); } } - //preprocessed.Add(this.PreProcessor()) - return PreProcessor(UncommentedCode.ToString()); } } - public GrammarMatch PreProcessor(string code) + public GrammarMatch TestParse(string code) + { + return Grammar.Match(code); + } + + public DirectiveToken ParseDirectives(string shader) + { + FinalCode.Clear(); + UncommentedCode.Clear(); + + RemoveComments(shader); + var matches = Directive.Match(UncommentedCode.ToString()); + if (!matches.Success) + throw new Exception($"Parsing failed : \n{matches.ErrorMessage}"); + var tokens = DirectiveToken.GetToken(matches.Matches[0]); + + DirectiveToken.Evaluate(tokens, Macros, FinalCode); + return tokens; + } + + public ShaderToken Parse(string shader) + { + RemoveComments(shader); + PreProcessor(); + return null; + } + + public void PreProcessor() { - return Directive.Match(code); + DirectiveToken.GetToken(Directive.Match(UncommentedCode.ToString())); } private static void PrettyPrintMatches(Match match, int depth = 0) From 3ad8e927679424e6abd25fd4d5f28e997dda7e9d Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 26 May 2022 16:46:58 +0200 Subject: [PATCH 0080/1182] Replaced directive parser --- .gitmodules | 3 +++ src/CppNet | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/CppNet diff --git a/.gitmodules b/.gitmodules index 30a1b156a7..3193eb8a34 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule ".\\src\\Eto.Parse"] path = .\\src\\Eto.Parse url = https://github.com/ykafia/Eto.Parse +[submodule ".\\src\\CppNet"] + path = .\\src\\CppNet + url = https://github.com/ykafia/CppNet diff --git a/src/CppNet b/src/CppNet new file mode 160000 index 0000000000..67d633d070 --- /dev/null +++ b/src/CppNet @@ -0,0 +1 @@ +Subproject commit 67d633d0704fcca074836007241f81f01d4d95a3 From f3bf6835f8dcffff454df97c0d45a63b5d794966 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 26 May 2022 16:47:21 +0200 Subject: [PATCH 0081/1182] Minor changes --- SDSLParser.sln | 26 +++-- src/CppNet.backup | 1 + src/SDSLParserExample/Program.cs | 12 +- src/SDSLParserExample/SDSL/shader2.sdsl | 15 +-- .../Front/AST/Directives/Directives.cs | 1 - .../Front/AST/Directives/Operations.cs | 4 + .../Front/AST/Shader/Literals.cs | 62 +++++++++-- .../Front/AST/Shader/Operations.cs | 62 ++++++++++- .../Front/AST/Shader/OperatorToken.cs | 64 +++++++++++ .../Front/AST/Shader/ShaderToken.cs | 32 ++++-- .../Front/AST/Shader/UnaryLiterals.cs | 15 ++- .../Front/DirectivePreprocessor.cs | 77 +++++++++++++ .../DirectiveGrammar.Directives.cs | 3 +- .../DirectiveGrammar.Tokens.cs | 10 -- .../DirectiveGrammar/DirectiveGrammar.cs | 1 - .../Front/Grammars/MacroGrammar.cs | 23 ++++ src/Stride.Shader.Parsing/Front/SDSLParser.cs | 104 ++++++++++-------- .../Stride.Shader.Parsing.csproj | 1 + 18 files changed, 410 insertions(+), 103 deletions(-) create mode 160000 src/CppNet.backup create mode 100644 src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs create mode 100644 src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs diff --git a/SDSLParser.sln b/SDSLParser.sln index e26604cf42..719ff0e976 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -1,24 +1,23 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30114.105 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32516.85 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B760-4857-BD74-296B07778B15}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parsing", "src\Stride.Shader.Parsing\Stride.Shader.Parsing.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shader.Parsing", "src\Stride.Shader.Parsing\Stride.Shader.Parsing.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shader.Parsing.Test", "src\Stride.Shader.Parsing.Test\Stride.Shader.Parsing.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shader.Parsing.Test", "src\Stride.Shader.Parsing.Test\Stride.Shader.Parsing.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "src\CppNet\CppNet.csproj", "{C2FD9262-69F8-4B75-9AB1-FF359C9143E9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -32,10 +31,21 @@ Global {6D885FCB-C043-4065-BA7E-E4937667B219}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D885FCB-C043-4065-BA7E-E4937667B219}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D885FCB-C043-4065-BA7E-E4937667B219}.Release|Any CPU.Build.0 = Release|Any CPU + {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD} = {5F88D871-B760-4857-BD74-296B07778B15} {3A20C614-0B73-4592-B0A3-152FBA7C112C} = {5F88D871-B760-4857-BD74-296B07778B15} {6D885FCB-C043-4065-BA7E-E4937667B219} = {5F88D871-B760-4857-BD74-296B07778B15} + {C2FD9262-69F8-4B75-9AB1-FF359C9143E9} = {5F88D871-B760-4857-BD74-296B07778B15} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4AF186D8-C065-4788-835B-3C253D65EAE0} EndGlobalSection EndGlobal diff --git a/src/CppNet.backup b/src/CppNet.backup new file mode 160000 index 0000000000..67d633d070 --- /dev/null +++ b/src/CppNet.backup @@ -0,0 +1 @@ +Subproject commit 67d633d0704fcca074836007241f81f01d4d95a3 diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3be42906ed..af32ed1df9 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -13,16 +13,16 @@ sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); -var match2 = sdsl.ParseDirectives("true"); +//var match2 = sdsl.Parse("#ifdef STRIDE_MULTISAMPLE_COUNT\n#endif"); +//sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", "5"); + s.Start(); -var match = sdsl.ParseDirectives(shaderf); +var match = sdsl.Parse(shaderf); s.Stop(); -Console.WriteLine(new string('*', 32)); Console.WriteLine(shaderf); -Console.WriteLine(new string('*',32)); -Console.WriteLine(sdsl.FinalCode); -Console.WriteLine(new string('*', 32) + "\n\n\n"); +Console.WriteLine(new string('*', 64)); +Console.WriteLine(match); Console.WriteLine($"parsing time : {s.Elapsed}"); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index d6a680b2aa..ad9bdf62af 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,12 +1,7 @@ -Some code before -#define a -#ifdef a -#if 5 == 2+3 -Success, 5 equals 5 -#endif -#endif +Mycode starts here +#ifdef aa -#if 8 == 2 -This code should disappear +something to code #endif -Some code after \ No newline at end of file + +code ends here \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs index 22442ed16b..488a9824c1 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs @@ -13,7 +13,6 @@ public class DirectiveFlow : DirectiveToken public override void EvaluateMacros(Dictionary macros) { - throw new NotImplementedException(); } } diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs b/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs index a20cc94010..72ff916e0c 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs @@ -36,6 +36,10 @@ public override Type InferredType } public override void EvaluateMacros(Dictionary macros) { + if(Left is Operation) + Left.EvaluateMacros(macros); + if (Right is Operation) + Right.EvaluateMacros(macros); if (Left is VariableNameLiteral vl) { if (macros.TryGetValue(vl.Name, out object value)) diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs index d04a8493ea..02f478a9c7 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs @@ -7,12 +7,40 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class NumberLiteral : ShaderToken + +public class ShaderLiteral : ShaderToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } +} + +public class NumberLiteral : ShaderLiteral { public bool Negative { get; set; } = false; - public object? Value { get; set; } + public object Value { get; set; } public string? Suffix { get; set; } + protected Type? inferredType; + + public override Type InferredType + { + get + { + if (inferredType is not null) + return inferredType; + if (Suffix is null) + return Value.GetType(); + else + { + return Suffix switch + { + "u" or "l" => typeof(long), + "f" or "d" => typeof(double), + _ => typeof(long) + }; + } + } + set => inferredType = value; + } public NumberLiteral() { } @@ -37,9 +65,18 @@ public NumberLiteral(Match match) } } } -public class HexLiteral : ShaderToken +public class HexLiteral : NumberLiteral { - public ulong Value { get; set; } + + public override Type InferredType + { + get + { + return typeof(long); + } + set => inferredType = value; + } + public HexLiteral() { } @@ -49,10 +86,10 @@ public HexLiteral(Match match) Value = Convert.ToUInt64(match.StringValue, 16); } } -public class StringLiteral : ShaderToken +public class StringLiteral : ShaderLiteral { public string? Value { get; set; } - + public override Type InferredType { get => typeof(string); set { } } public StringLiteral() { } @@ -63,9 +100,10 @@ public StringLiteral(Match match) } } -public class BoolLiteral : ShaderToken +public class BoolLiteral : ShaderLiteral { public bool Value { get; set; } + public override Type InferredType { get => typeof(bool); set { } } public BoolLiteral() { } @@ -77,7 +115,7 @@ public BoolLiteral(Match match) } -public class TypeNameLiteral : ShaderToken +public class TypeNameLiteral : ShaderLiteral { public string Name { get; set; } @@ -87,9 +125,15 @@ public TypeNameLiteral(Match m) } } -public class VariableNameLiteral : ShaderToken +public class VariableNameLiteral : ShaderLiteral { public string Name { get; set; } + public object Value { get; set; } + + Type? inferredType; + + public override Type InferredType { get => inferredType ?? typeof(void); set => inferredType = value; } + public VariableNameLiteral(Match m) { diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs index b292c728c1..fe4a76dea2 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs @@ -9,11 +9,45 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class Operation : ShaderToken +public abstract class Projector : ShaderToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public abstract ShaderToken ProjectConstant(); +} + +public class Operation : Projector { public OperatorToken Op { get; set; } + public ShaderToken Left { get; set; } public ShaderToken Right { get; set; } + + Type? inferredType; + public override Type InferredType + { + get => inferredType ?? typeof(void); + set => inferredType = value; + } + + public override ShaderToken ProjectConstant() + { + + if (Left is Projector) + Left = ((Projector)Left).ProjectConstant(); + if (Right is Projector) + Right = ((Projector)Right).ProjectConstant(); + + return (Left, Right) switch + { + (NumberLiteral ln, NumberLiteral rn) => ApplyOperation(Op, ln, rn), + (BoolLiteral ln, BoolLiteral rn) => ApplyOperation(Op, ln, rn), + (StringLiteral ln, StringLiteral rn) => ApplyOperation(Op, ln, rn), + _ => throw new Exception("Cannot process operation") + }; + } + + } @@ -285,12 +319,19 @@ public static LogicalOrExpression Create(Match m) } } -public class ConditionalExpression : ShaderToken +public class ConditionalExpression : Projector { public ShaderToken Condition { get; set; } public ShaderToken TrueOutput { get; set; } public ShaderToken FalseOutput { get; set; } + Type? inferredType; + + public override Type InferredType + { + get => inferredType ?? typeof(void); + set => inferredType = value; + } public ConditionalExpression(Match m) { @@ -298,4 +339,21 @@ public ConditionalExpression(Match m) TrueOutput = GetToken(m.Matches[1]); FalseOutput = GetToken(m.Matches[2]); } + + public override ShaderToken ProjectConstant() + { + if (Condition is Projector) + Condition = ((Projector)Condition).ProjectConstant(); + + if (TrueOutput is Projector ) + TrueOutput= ((Projector)TrueOutput).ProjectConstant(); + + if (FalseOutput is Projector ) + FalseOutput= ((Projector)FalseOutput).ProjectConstant(); + + if (Condition is BoolLiteral c) + return c.Value ? TrueOutput : FalseOutput; + else + throw new Exception("Invalid condition"); + } } diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs index 2877e5e079..eedf7c8647 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs @@ -55,4 +55,68 @@ public static OperatorToken AsOperatorToken(this string s) _ => throw new NotImplementedException() }; } + + private static double OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToDouble(a); + var r = Convert.ToDouble(b); + return f.Invoke(l, r); + } + private static double OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToInt32(a); + var r = Convert.ToInt32(b); + return f.Invoke(l, r); + } + + private static bool OperationWithCast(object a, object b, Func f) + { + var l = Convert.ToDouble(a); + var r = Convert.ToDouble(b); + return f.Invoke(l, r); + } + + public static ShaderToken ApplyOperation(OperatorToken op, NumberLiteral l, NumberLiteral r) + { + return op switch + { + OperatorToken.Mul => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a*b) }, + OperatorToken.Div => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a / b) }, + OperatorToken.Mod => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a % b) }, + OperatorToken.Plus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a + b) }, + OperatorToken.Minus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a - b) }, + OperatorToken.LeftShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a,b) => a << b) }, + OperatorToken.RightShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a >> b) }, + OperatorToken.And => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a & b) }, + OperatorToken.Or => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a | b) }, + OperatorToken.Xor => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a ^ b) }, + OperatorToken.Less => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a < b) }, + OperatorToken.LessEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a <= b) }, + OperatorToken.Greater => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a > b) }, + OperatorToken.GreaterEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a >= b) }, + OperatorToken.Equals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a == b) }, + OperatorToken.NotEquals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a != b) }, + _ => throw new NotImplementedException() + }; + } + public static ShaderToken ApplyOperation(OperatorToken op, BoolLiteral l, BoolLiteral r) + { + return op switch + { + OperatorToken.LogicalAnd => new BoolLiteral { Value = l.Value && r.Value }, + OperatorToken.LogicalOr => new BoolLiteral { Value = l.Value || r.Value }, + OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, + OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, + _ => throw new NotImplementedException() + }; + } + public static ShaderToken ApplyOperation(OperatorToken op, StringLiteral l, StringLiteral r) + { + return op switch + { + OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, + OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, + _ => throw new NotImplementedException() + }; + } } diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs index cf7dda0462..0ce147c1da 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs @@ -8,9 +8,12 @@ namespace Stride.Shader.Parsing.AST.Shader; + public abstract class ShaderToken { - public Match? Match { get; set; } + public Match Match { get; set; } + public abstract Type InferredType { get; set; } + public static ShaderToken GetToken(Match match) { var tmp = match; @@ -19,7 +22,6 @@ public static ShaderToken GetToken(Match match) return tmp.Name switch { - "PrimaryExpression" => GetToken(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), "LogicalAndExpression" => LogicalAndExpression.Create(tmp), @@ -32,15 +34,31 @@ public static ShaderToken GetToken(Match match) "SumExpression" => SumExpression.Create(tmp), "MulExpression" => MulExpression.Create(tmp), "CastExpression" => new CastExpression(tmp), - "PostfixIncrement" => new PostfixIncrement(tmp), - "ArrayAccessor" => new ArrayAccessor(tmp), - "ChainAccessor" => new ChainAccessor(tmp), - "PrefixIncrement" => new PrefixIncrement(tmp), + "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), - "VariableTerm" => new VariableNameLiteral(tmp), + "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), "Boolean" => new BoolLiteral(tmp), _ => throw new NotImplementedException() }; } + + public static ShaderToken EvaluateExpression(ShaderToken expr, Dictionary macros) + { + return expr switch + { + ShaderLiteral l => l, + Operation o => EvaluateOperation(o,macros), + _ => throw new Exception("Couldn't evaluate expression") + }; + } + private static ShaderToken EvaluateOperation(Operation operation, Dictionary macros) + { + return operation.ProjectConstant() switch + { + Operation o => o, + ShaderLiteral t => t, + _ => throw new Exception("Couldn't evaluate operation") + }; + } } diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs index 3da2a4c01e..2eeedffcde 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs @@ -8,7 +8,12 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class ChainAccessor : ShaderToken +public class UnaryExpression : ShaderToken +{ + public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } +} + +public class ChainAccessor : UnaryExpression { public ShaderToken Value { get; set; } public ShaderToken Field { get; set; } @@ -21,7 +26,7 @@ public ChainAccessor(Match m) } } -public class ArrayAccessor : ShaderToken +public class ArrayAccessor : UnaryExpression { public ShaderToken Value { get; set; } public IEnumerable Accessors { get; set; } @@ -35,7 +40,7 @@ public ArrayAccessor(Match m) } -public class PostfixIncrement : ShaderToken +public class PostfixIncrement : UnaryExpression { public string Operator { get; set; } public ShaderToken Value { get; set; } @@ -52,7 +57,7 @@ public override string ToString() } } -public class PrefixIncrement : ShaderToken +public class PrefixIncrement : UnaryExpression { public string Operator { get; set; } public ShaderToken Value { get; set; } @@ -64,7 +69,7 @@ public PrefixIncrement(Match m) } } -public class CastExpression : ShaderToken +public class CastExpression : UnaryExpression { public TypeNameLiteral Target { get; set; } public ShaderToken From { get; set; } diff --git a/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs b/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs new file mode 100644 index 0000000000..298e380782 --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs @@ -0,0 +1,77 @@ +using Stride.Shader.Parsing.AST.Directives; +using Stride.Shader.Parsing.Grammars.Comments; +using Stride.Shader.Parsing.Grammars.Directive; +using Stride.Shader.Parsing.Grammars.Macros; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing; + +public class DirectivePreprocessor +{ + Dictionary macros; + public CommentGrammar CommentParser { get; set; } + public DirectiveGrammar DirectivesParser { get; set; } = new(); + public MacroGrammar MacrosParser { get; set; } + public Dictionary Macros + { + get => macros; + set { macros = value; MacrosParser = new(macros.Keys.ToArray()); } + } + + public DirectivePreprocessor() + { + DirectivesParser = new(); + CommentParser = new(); + MacrosParser = new(); + } + + public string RemoveComments(ref string code) + { + var comments = CommentParser.Match(code); + var uncommentedCode = new StringBuilder(); + if (!comments.Matches.Any(x => x.Name == "Comment")) + { + return code; + } + else + { + foreach (var m in comments.Matches) + { + if (m.Name == "ActualCode") + { + uncommentedCode.AppendLine(m.StringValue); + } + } + return uncommentedCode.ToString(); + } + } + + public DirectiveToken ParseDirectives(in string code) + { + var parseTree = DirectivesParser.Match(code); + if (!parseTree.Success) + throw new Exception(parseTree.ErrorMessage); + return DirectiveToken.GetToken(parseTree["Directives"]); + } + + public string PreProcess(ref string shader) + { + var uncommentedCode = RemoveComments(ref shader); + var AST = ParseDirectives(uncommentedCode); + AST.EvaluateMacros(macros); + var afterDirectives = new StringBuilder(); + DirectiveToken.Evaluate(AST, macros, afterDirectives); + var matches = MacrosParser.Match(afterDirectives.ToString()); + if (!matches.Success) + throw new Exception(matches.ErrorMessage); + var replaceDefines = new StringBuilder(); + foreach(var m in matches.Matches) + replaceDefines.Append(m.Name == "ActualCode" ? m.StringValue : macros[m.StringValue]); + return replaceDefines.ToString(); + } + +} diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index 61dffbc8c9..a5b1f727ae 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -23,7 +23,7 @@ public partial class DirectiveGrammar : Grammar public SequenceParser ConditionalDirectives = new(){Name = "ConditionalDirectives"}; public SequenceParser DefinitionDirectives = new(){Name = "DefineDirectives"}; - public AlternativeParser AnyDirectives = new AlternativeParser(); + public AlternativeParser AnyDirectives = new(); public SequenceParser Directives = new(); @@ -106,5 +106,6 @@ public void CreateDirectives() Directives.Add( CodeOrDirective.Until(End).Named("Directives") ); + Inner = Directives; } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs index 7b727a47c7..f509a1e7bd 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs @@ -4,11 +4,6 @@ namespace Stride.Shader.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { - private AlternativeParser Space = new(); - private RepeatParser Spaces = new(); - private SequenceParser SpacesWithLineBreak = new(); - private LiteralTerminal AppendStructuredBuffer = new(); - private AlternativeParser ComponentNumber = new(); private LiteralTerminal Bool = new(); private AlternativeParser Uint = new(); @@ -71,11 +66,6 @@ public partial class DirectiveGrammar : Grammar public void CreateTokens() { - Space = WhiteSpace | Eol; - Spaces = Space.Optional().Repeat(); - SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); - AppendStructuredBuffer = Literal("AppendStructuredBuffer"); - ComponentNumber = Literal("1") | "2" | "3" | "4"; Bool = Literal("bool"); Uint.Add("uint","unsigned int", "dword"); diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs index e31785a2e8..13682d675b 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs @@ -10,7 +10,6 @@ public partial class DirectiveGrammar : Grammar public DirectiveGrammar() { CreateAll(); - Inner = Directives; } public void CreateAll() diff --git a/src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs b/src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs new file mode 100644 index 0000000000..1d1d637194 --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs @@ -0,0 +1,23 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shader.Parsing.Grammars.Macros; + +public class MacroGrammar : Grammar +{ + + public MacroGrammar(params string[] variableNames) : base("variables-sdsl") + { + var altVars = new AlternativeParser(variableNames.Select(Literal)) + { + Name = "MacroVariable" + }; + var grammar = new AlternativeParser( + AnyChar.Repeat(0).Until(altVars).Named("ActualCode") & altVars + | AnyChar.Repeat(0).Until(End).Named("ActualCode") + ); + Inner = grammar.Repeat(0); + } +} diff --git a/src/Stride.Shader.Parsing/Front/SDSLParser.cs b/src/Stride.Shader.Parsing/Front/SDSLParser.cs index 9b966f4151..2c38d61d0b 100644 --- a/src/Stride.Shader.Parsing/Front/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/Front/SDSLParser.cs @@ -9,23 +9,30 @@ namespace Stride.Shader.Parsing; using Stride.Shader.Parsing.Grammars.Directive; using Stride.Shader.Parsing.Grammars.SDSL; using System.Text; +using CppNet; + + public class SDSLParser { - public CommentGrammar Comments {get;set;} public SDSLGrammar Grammar {get;set;} - public DirectiveGrammar Directive { get;set;} - public StringBuilder UncommentedCode { get; set; } = new(); - public StringBuilder FinalCode { get; set; } = new(); + //public DirectivePreprocessor Preprocessor { get;set;} + public Preprocessor Preprocessor { get; set; } public Dictionary Macros { get; set; } = new(); public GrammarMatch? ParseTree { get; set; } - //public IEnumerable Defined { get; set; } public SDSLParser() { - Comments = new(); Grammar = new(); - Directive = new(); + Preprocessor = new(); + Preprocessor.addFeature(Feature.DIGRAPHS); + Preprocessor.addWarning(Warning.IMPORT); + Preprocessor.addFeature(Feature.INCLUDENEXT); + Preprocessor.addFeature(Feature.LINEMARKERS); + Preprocessor.addFeature(Feature.DEBUG); + Preprocessor.setListener(new ErrorListener()); + + } public SDSLParser With(Parser p) @@ -39,55 +46,62 @@ public void PrintParserTree(string shader) PrettyPrintMatches(ParseTree.Matches[0]); } - private void RemoveComments(string code) + public GrammarMatch TestParse(string code) { - var comments = Comments.Match(code); - if (!comments.Matches.Any(x => x.Name == "Comment")) - { - UncommentedCode.Append(code); - } - else - { - foreach (var m in comments.Matches) - { - if (m.Name == "ActualCode") - { - UncommentedCode.AppendLine(m.StringValue); - } - } - } + return Grammar.Match(code); } - public GrammarMatch TestParse(string code) + public void AddMacro(string name, string value) { - return Grammar.Match(code); + Preprocessor.addMacro(name, value); + } + public void AddMacro(string name) + { + Preprocessor.addMacro(name, string.Empty); } - public DirectiveToken ParseDirectives(string shader) + public string PreProcess(string code) { - FinalCode.Clear(); - UncommentedCode.Clear(); + var inputSource = new StringLexerSource(code, true); + Preprocessor.addInput(inputSource); + var textBuilder = new StringBuilder(); - RemoveComments(shader); - var matches = Directive.Match(UncommentedCode.ToString()); - if (!matches.Success) - throw new Exception($"Parsing failed : \n{matches.ErrorMessage}"); - var tokens = DirectiveToken.GetToken(matches.Matches[0]); + var isEndOfStream = false; + while (!isEndOfStream) + { + Token tok = Preprocessor.token(); + switch (tok.getType()) + { + case Token.EOF: + isEndOfStream = true; + break; + case Token.CCOMMENT: + var strComment = tok.getText() ?? string.Empty; + foreach (var commentChar in strComment) + { + textBuilder.Append(commentChar == '\n' ? '\n' : ' '); + } + break; + case Token.CPPCOMMENT: + break; + default: + var tokenText = tok.getText(); + if (tokenText != null) + { + textBuilder.Append(tokenText); + } + break; + } + } - DirectiveToken.Evaluate(tokens, Macros, FinalCode); - return tokens; + return textBuilder.ToString(); } - public ShaderToken Parse(string shader) + public string Parse(string shader) { - RemoveComments(shader); - PreProcessor(); - return null; - } + return PreProcess(shader); - public void PreProcessor() - { - DirectiveToken.GetToken(Directive.Match(UncommentedCode.ToString())); + //return null; } private static void PrettyPrintMatches(Match match, int depth = 0) @@ -113,4 +127,8 @@ private static void PrettyPrintMatches(Match match, int depth = 0) } } + private class ErrorListener : DefaultPreprocessorListener + { + + } } \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj index 0c581aaf7a..a5ee4d56eb 100644 --- a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj +++ b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj @@ -1,6 +1,7 @@ + From 8f0b94766bcda2235e77a36c9763e62bec5586c6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 26 May 2022 23:55:42 +0200 Subject: [PATCH 0082/1182] Added AST shader --- src/CppNet | 2 +- src/CppNet.backup | 1 - src/SDSLParserExample/Program.cs | 9 ++- src/SDSLParserExample/SDSL/shader2.sdsl | 14 ++-- .../Front/AST/Shader/Literals.cs | 7 +- .../Front/AST/Shader/Operations.cs | 2 +- .../Front/AST/Shader/ShaderProgram.cs | 72 +++++++++++++++++++ .../Front/AST/Shader/ShaderToken.cs | 4 +- .../Front/AST/Shader/UnaryLiterals.cs | 7 +- .../Front/DirectivePreprocessor.cs | 7 +- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 8 +-- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar.MethodDeclaration.cs | 6 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 4 +- src/Stride.Shader.Parsing/Front/SDSLParser.cs | 34 +++++---- 15 files changed, 138 insertions(+), 41 deletions(-) delete mode 160000 src/CppNet.backup create mode 100644 src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs diff --git a/src/CppNet b/src/CppNet index 67d633d070..a93fea69ee 160000 --- a/src/CppNet +++ b/src/CppNet @@ -1 +1 @@ -Subproject commit 67d633d0704fcca074836007241f81f01d4d95a3 +Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 diff --git a/src/CppNet.backup b/src/CppNet.backup deleted file mode 160000 index 67d633d070..0000000000 --- a/src/CppNet.backup +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67d633d0704fcca074836007241f81f01d4d95a3 diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index af32ed1df9..f9d72a17fd 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -10,16 +10,19 @@ var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var sdsl = new SDSLParser(); -sdsl.Grammar.Using(sdsl.Grammar.CastExpression); +//sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); -//var match2 = sdsl.Parse("#ifdef STRIDE_MULTISAMPLE_COUNT\n#endif"); -//sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", "5"); +var match2 = sdsl.Parse(shaderf); +sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", 5); s.Start(); var match = sdsl.Parse(shaderf); s.Stop(); + +sdsl.PrintParserTree(); + Console.WriteLine(shaderf); Console.WriteLine(new string('*', 64)); Console.WriteLine(match); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index ad9bdf62af..028cb956db 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,7 +1,9 @@ -Mycode starts here -#ifdef aa +shader MyShader { + stream MyStruct a; + stream float b; -something to code -#endif - -code ends here \ No newline at end of file + void VSMain() + { + + } +}; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs index 02f478a9c7..d5194d15a8 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs @@ -8,9 +8,14 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class ShaderLiteral : ShaderToken +public class ShaderLiteral : Projector { public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override ShaderToken ProjectConstant() + { + return this; + } } public class NumberLiteral : ShaderLiteral diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs index fe4a76dea2..e3547ea4a5 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs @@ -11,7 +11,7 @@ namespace Stride.Shader.Parsing.AST.Shader; public abstract class Projector : ShaderToken { - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public virtual Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public abstract ShaderToken ProjectConstant(); } diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs new file mode 100644 index 0000000000..651046847a --- /dev/null +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs @@ -0,0 +1,72 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Shader; + +public class ShaderMethod : ShaderToken +{ + public string Name { get; set; } + public string ReturnType { get; set; } + public IEnumerable ParameterList { get; set; } + + public ShaderMethod(Match m) + { + Match = m; + Name = m["MethodName"].StringValue; + ReturnType = m["ReturnType"].StringValue; + } +} + +public class ShaderValueDeclaration : ShaderToken +{ + public bool IsStream {get;set;} + public bool IsStaged {get;set;} + public string Name {get;set;} + public string Type {get;set;} + public ShaderToken Expression {get;set;} + + public ShaderValueDeclaration(Match m) + { + Match = m; + IsStream = m["Stream"].Success; + IsStaged = m["Stage"].Success; + Type = m["TypeName"].StringValue; + Name = m["VariableTerm"].StringValue; + } +} +public class Generics : ShaderToken +{ + public string Type { get; set; } + public string Name { get; set; } +} + +public class ShaderGenerics : ShaderToken +{ + public string Name { get; set; } + public IEnumerable Generics { get; set; } +} + +public class Mixin : ShaderToken +{ + public string Name { get; set; } + public IEnumerable GenericsValues { get; set; } +} + +public class ShaderProgram : ShaderToken +{ + public string Name {get;set;} + public IEnumerable Generics { get; set; } + public IEnumerable Mixins { get; set; } + public IEnumerable Body { get; set; } + + public ShaderProgram(Match m) + { + Match = m; + Name = m["ShaderName"].StringValue; + Body = m["Body"].Matches.Select(GetToken).ToList(); + } +} \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs index 0ce147c1da..391ce96c42 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs @@ -12,7 +12,6 @@ namespace Stride.Shader.Parsing.AST.Shader; public abstract class ShaderToken { public Match Match { get; set; } - public abstract Type InferredType { get; set; } public static ShaderToken GetToken(Match match) { @@ -22,6 +21,9 @@ public static ShaderToken GetToken(Match match) return tmp.Name switch { + "ShaderProgram" => new ShaderProgram(tmp), + "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), + "Method" => new ShaderMethod(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), "LogicalAndExpression" => LogicalAndExpression.Create(tmp), diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs index 2eeedffcde..d9360da96c 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs @@ -8,9 +8,14 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class UnaryExpression : ShaderToken +public class UnaryExpression : Projector { public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override ShaderToken ProjectConstant() + { + return this; + } } public class ChainAccessor : UnaryExpression diff --git a/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs b/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs index 298e380782..e6added42b 100644 --- a/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs +++ b/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs @@ -27,9 +27,10 @@ public DirectivePreprocessor() DirectivesParser = new(); CommentParser = new(); MacrosParser = new(); + macros = new(); } - public string RemoveComments(ref string code) + public string RemoveComments(string code) { var comments = CommentParser.Match(code); var uncommentedCode = new StringBuilder(); @@ -58,9 +59,9 @@ public DirectiveToken ParseDirectives(in string code) return DirectiveToken.GetToken(parseTree["Directives"]); } - public string PreProcess(ref string shader) + public string PreProcess(string shader) { - var uncommentedCode = RemoveComments(ref shader); + var uncommentedCode = RemoveComments(shader); var AST = ParseDirectives(uncommentedCode); AST.EvaluateMacros(macros); var afterDirectives = new StringBuilder(); diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index c3ed1b93f7..2844de5ad3 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -59,15 +59,15 @@ public void CreateDeclarators() ); var staging = - Stage.NotFollowedBy(ws1 & Stream) - | Stage & ws1 & Stream - | Stream; + Stage.NotFollowedBy(ws1 & Stream).Named("Stage") + | Stage.Named("Stage") & ws1 & Stream.Named("Stream") + | Stream.Named("Stream"); var valueDeclaration = new SequenceParser(); valueDeclaration.Add( ~(staging & ws1), ~(StorageFlag & ws1), - ValueTypes | Identifier, + (ValueTypes | Identifier).Named("TypeName"), ws1, Identifier ); diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 98316591e7..2e3232fde4 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -64,7 +64,7 @@ public void CreateExpressions() TermExpression.Add( Literals, - Identifier.WithName("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 191cb5ad49..5ce79cde78 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -85,9 +85,9 @@ public void CreateMethodDeclaration() var method = new SequenceParser( Attribute.Repeat(0).SeparatedBy(ws), - ~(Literal("stage") & WhiteSpace), - ~((Literal("override") | Literal("static")) & ws1), - Identifier & ws1 & Identifier, + ~(Stage.Named("Stage") & WhiteSpace), + ~((Literal("override").Named("Override") | Literal("static").Named("Static")) & ws1), + Identifier.Named("ReturnType") & ws1 & Identifier.Named("MethodName"), ParameterList, LeftBrace, Statement.Repeat(0).SeparatedBy(ws).Until("}"), diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index ded9443f12..82e4e6eaf4 100644 --- a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -102,13 +102,11 @@ public void CreateShader() ) .SeparatedBy(ws); - var shaderToken = Literal("shader").Named("ShaderToken"); - ShaderExpression.Add( ws, - shaderToken & ws1 & Identifier.Named("ShaderName"), + Literal("shader") & ws1 & Identifier.Named("ShaderName"), shaderGenerics.Optional(), inheritances.Optional(), shaderBody, diff --git a/src/Stride.Shader.Parsing/Front/SDSLParser.cs b/src/Stride.Shader.Parsing/Front/SDSLParser.cs index 2c38d61d0b..df694bcf5f 100644 --- a/src/Stride.Shader.Parsing/Front/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/Front/SDSLParser.cs @@ -14,8 +14,8 @@ namespace Stride.Shader.Parsing; public class SDSLParser { - public SDSLGrammar Grammar {get;set;} - //public DirectivePreprocessor Preprocessor { get;set;} + public SDSLGrammar Grammar {get;set;} + public DirectivePreprocessor DPreprocessor { get; set; } public Preprocessor Preprocessor { get; set; } public Dictionary Macros { get; set; } = new(); @@ -24,15 +24,15 @@ public class SDSLParser public SDSLParser() { Grammar = new(); + DPreprocessor = new(); + + Preprocessor = new(); Preprocessor.addFeature(Feature.DIGRAPHS); Preprocessor.addWarning(Warning.IMPORT); Preprocessor.addFeature(Feature.INCLUDENEXT); - Preprocessor.addFeature(Feature.LINEMARKERS); - Preprocessor.addFeature(Feature.DEBUG); + //Preprocessor.addFeature(Feature.LINEMARKERS); Preprocessor.setListener(new ErrorListener()); - - } public SDSLParser With(Parser p) @@ -41,7 +41,7 @@ public SDSLParser With(Parser p) return this; } - public void PrintParserTree(string shader) + public void PrintParserTree() { PrettyPrintMatches(ParseTree.Matches[0]); } @@ -51,13 +51,20 @@ public GrammarMatch TestParse(string code) return Grammar.Match(code); } - public void AddMacro(string name, string value) + public void AddMacro(string name, object value) { - Preprocessor.addMacro(name, value); + Preprocessor.addMacro(name, value.ToString()); + DPreprocessor.Macros.Add(name, value); } public void AddMacro(string name) { Preprocessor.addMacro(name, string.Empty); + DPreprocessor.Macros.Add(name, string.Empty); + } + + public string DPreProcess(string code) + { + return DPreprocessor.PreProcess(code); } public string PreProcess(string code) @@ -97,10 +104,13 @@ public string PreProcess(string code) return textBuilder.ToString(); } - public string Parse(string shader) + public ShaderToken Parse(string shader) { - return PreProcess(shader); - + var code = PreProcess(shader); + ParseTree = Grammar.Match(code); + if (!ParseTree.Success) + throw new Exception(ParseTree.ErrorMessage); + return ShaderToken.GetToken(ParseTree); //return null; } From 381fd1780f09bd46be234eca2a65ada347d3f48c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:12:12 +0200 Subject: [PATCH 0083/1182] Three address code + shader mixer --- src/SDSLParserExample/SDSL/shader2.sdsl | 2 +- .../Backend/ThreeAddressElement.cs | 53 +++++++++++++++++++ .../AST/Directives/DirectiveToken.cs | 0 .../AST/Directives/Directives.cs | 0 .../AST/Directives/Literals.cs | 0 .../AST/Directives/Operations.cs | 0 .../AST/Directives/OperatorToken.cs | 0 .../AST/Directives/UnaryLiterals.cs | 0 .../AST/Shader/Literals.cs | 0 .../AST/Shader/Operations.cs | 0 .../AST/Shader/OperatorToken.cs | 0 .../AST/Shader/ShaderProgram.cs | 10 ++++ .../AST/Shader/ShaderToken.cs | 0 .../AST/Shader/UnaryLiterals.cs | 0 .../DirectivePreprocessor.cs | 0 .../{Front => Frontend}/ExpressionParser.cs | 0 .../Grammars/CommentGrammar.cs | 0 .../DirectiveGrammar.Directives.Expression.cs | 0 .../DirectiveGrammar.Directives.cs | 0 .../DirectiveGrammar.Tokens.cs | 0 .../DirectiveGrammar/DirectiveGrammar.cs | 0 .../DirectiveGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.TokenGroups.cs | 0 .../Grammars/ExpressionGrammar.cs | 0 .../Grammars/MacroGrammar.cs | 0 .../SDSLGrammar/SDSLGrammar.Declaration.cs | 0 .../SDSLGrammar.Directives.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Directives.cs | 0 .../SDSLGrammar/SDSLGrammar.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.MethodDeclaration.cs | 0 .../SDSLGrammar/SDSLGrammar.Shader.cs | 0 ...ar.Statements.ConditionalFlowStatements.cs | 0 ...SLGrammar.Statements.LoopFlowStatements.cs | 0 .../SDSLGrammar/SDSLGrammar.Statements.cs | 0 .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 0 .../SDSLGrammar/SDSLGrammar.Tokens.cs | 0 .../Grammars/SDSLGrammar/SDSLGrammar.cs | 0 .../{Front => Frontend}/Hlsl/HlslExpr.g4 | 0 .../{Front => Frontend}/Hlsl/HlslTokens.g4 | 0 .../{Front => Frontend}/Hlsl/code.hlsl | 0 .../{Front => Frontend}/SDSLParser.cs | 0 src/Stride.Shader.Parsing/SDSLMixer.cs | 13 +++++ src/Stride.Shader.Parsing/ShaderMixin.cs | 16 ++++++ 44 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/DirectiveToken.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/Directives.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/Literals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/Operations.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/OperatorToken.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Directives/UnaryLiterals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/Literals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/Operations.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/OperatorToken.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/ShaderProgram.cs (83%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/ShaderToken.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/AST/Shader/UnaryLiterals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/DirectivePreprocessor.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/ExpressionParser.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/CommentGrammar.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/DirectiveGrammar.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/ExpressionGrammar.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/MacroGrammar.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Grammars/SDSLGrammar/SDSLGrammar.cs (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Hlsl/HlslExpr.g4 (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Hlsl/HlslTokens.g4 (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/Hlsl/code.hlsl (100%) rename src/Stride.Shader.Parsing/{Front => Frontend}/SDSLParser.cs (100%) create mode 100644 src/Stride.Shader.Parsing/SDSLMixer.cs create mode 100644 src/Stride.Shader.Parsing/ShaderMixin.cs diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 028cb956db..a2cf92ab9e 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,5 +1,5 @@ shader MyShader { - stream MyStruct a; + stream float3 a : POSITION; stream float b; void VSMain() diff --git a/src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs b/src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs new file mode 100644 index 0000000000..8bfdad93f9 --- /dev/null +++ b/src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.Backend; + + +public enum Operators +{ + Mul, + Div, + Mod, + Plus, + Minus, + LeftShift, + RightShift, + And, + Or, + Xor, + Less, + Greater, + LessEqual, + GreaterEqual, + Equals, + NotEquals, + LogicalAnd, + LogicalOr +} + + +public interface Register { } + +public struct NamedRegister : Register +{ + public string Name { get; set; } +} +public struct ValueRegister : Register +{ + public T Value { get; set; } +} + +public struct ThreeAddressOperation +{ + public string RegisterName { get; set; } + public Register Left { get; set; } + public Register Right { get; set; } + public Operators Op { get; set; } +} + + + diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/DirectiveToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/DirectiveToken.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/DirectiveToken.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/Directives.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/Directives.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/Directives.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/Literals.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/Literals.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/Operations.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/Operations.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/Operations.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/OperatorToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/OperatorToken.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/OperatorToken.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Directives/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Frontend/AST/Directives/UnaryLiterals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Directives/UnaryLiterals.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Directives/UnaryLiterals.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Shader/Literals.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/Literals.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Shader/Operations.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Shader/OperatorToken.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs similarity index 83% rename from src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs index 651046847a..ff519e10f6 100644 --- a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs @@ -9,6 +9,11 @@ namespace Stride.Shader.Parsing.AST.Shader; public class ShaderMethod : ShaderToken { + public bool IsStatic { get; set; } + public bool IsOverride { get; set; } + public bool IsStaged { get; set; } + + public string Name { get; set; } public string ReturnType { get; set; } public IEnumerable ParameterList { get; set; } @@ -16,6 +21,9 @@ public class ShaderMethod : ShaderToken public ShaderMethod(Match m) { Match = m; + IsStatic = m["Static"].Success; + IsOverride = m["Override"].Success; + IsStaged = m["Stage"].Success; Name = m["MethodName"].StringValue; ReturnType = m["ReturnType"].StringValue; } @@ -27,6 +35,7 @@ public class ShaderValueDeclaration : ShaderToken public bool IsStaged {get;set;} public string Name {get;set;} public string Type {get;set;} + public string? Semantic { get; set; } public ShaderToken Expression {get;set;} public ShaderValueDeclaration(Match m) @@ -34,6 +43,7 @@ public ShaderValueDeclaration(Match m) Match = m; IsStream = m["Stream"].Success; IsStaged = m["Stage"].Success; + Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; Type = m["TypeName"].StringValue; Name = m["VariableTerm"].StringValue; } diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Shader/ShaderToken.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs diff --git a/src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/UnaryLiterals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/AST/Shader/UnaryLiterals.cs rename to src/Stride.Shader.Parsing/Frontend/AST/Shader/UnaryLiterals.cs diff --git a/src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs b/src/Stride.Shader.Parsing/Frontend/DirectivePreprocessor.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/DirectivePreprocessor.cs rename to src/Stride.Shader.Parsing/Frontend/DirectivePreprocessor.cs diff --git a/src/Stride.Shader.Parsing/Front/ExpressionParser.cs b/src/Stride.Shader.Parsing/Frontend/ExpressionParser.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/ExpressionParser.cs rename to src/Stride.Shader.Parsing/Frontend/ExpressionParser.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/CommentGrammar.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/CommentGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/CommentGrammar.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/CommentGrammar.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/ExpressionGrammar.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/ExpressionGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/ExpressionGrammar.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/ExpressionGrammar.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/MacroGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/MacroGrammar.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/MacroGrammar.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs diff --git a/src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/Grammars/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs diff --git a/src/Stride.Shader.Parsing/Front/Hlsl/HlslExpr.g4 b/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 similarity index 100% rename from src/Stride.Shader.Parsing/Front/Hlsl/HlslExpr.g4 rename to src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 diff --git a/src/Stride.Shader.Parsing/Front/Hlsl/HlslTokens.g4 b/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 similarity index 100% rename from src/Stride.Shader.Parsing/Front/Hlsl/HlslTokens.g4 rename to src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 diff --git a/src/Stride.Shader.Parsing/Front/Hlsl/code.hlsl b/src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl similarity index 100% rename from src/Stride.Shader.Parsing/Front/Hlsl/code.hlsl rename to src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl diff --git a/src/Stride.Shader.Parsing/Front/SDSLParser.cs b/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs similarity index 100% rename from src/Stride.Shader.Parsing/Front/SDSLParser.cs rename to src/Stride.Shader.Parsing/Frontend/SDSLParser.cs diff --git a/src/Stride.Shader.Parsing/SDSLMixer.cs b/src/Stride.Shader.Parsing/SDSLMixer.cs new file mode 100644 index 0000000000..eba4cf84ac --- /dev/null +++ b/src/Stride.Shader.Parsing/SDSLMixer.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing; + +public class SDSLMixer +{ + List Mixins { get; set; } = new(); + +} diff --git a/src/Stride.Shader.Parsing/ShaderMixin.cs b/src/Stride.Shader.Parsing/ShaderMixin.cs new file mode 100644 index 0000000000..ba50b9b91c --- /dev/null +++ b/src/Stride.Shader.Parsing/ShaderMixin.cs @@ -0,0 +1,16 @@ +using Stride.Shader.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing; + +public class ShaderMixin +{ + public string Code { get; set; } + public string MixinName { get; set; } + public ShaderToken AST { get; set; } + +} From be036a53ac0cb33bfd6f8283977510c76bd30bdd Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:13:24 +0200 Subject: [PATCH 0084/1182] removed hlsl + refactor --- .../{Frontend => }/DirectivePreprocessor.cs | 0 .../Frontend/Hlsl/HlslExpr.g4 | 899 ------------------ .../Frontend/Hlsl/HlslTokens.g4 | 426 --------- .../Frontend/Hlsl/code.hlsl | 8 - 4 files changed, 1333 deletions(-) rename src/Stride.Shader.Parsing/{Frontend => }/DirectivePreprocessor.cs (100%) delete mode 100644 src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 delete mode 100644 src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 delete mode 100644 src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl diff --git a/src/Stride.Shader.Parsing/Frontend/DirectivePreprocessor.cs b/src/Stride.Shader.Parsing/DirectivePreprocessor.cs similarity index 100% rename from src/Stride.Shader.Parsing/Frontend/DirectivePreprocessor.cs rename to src/Stride.Shader.Parsing/DirectivePreprocessor.cs diff --git a/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 b/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 deleted file mode 100644 index 4a6d40ba40..0000000000 --- a/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslExpr.g4 +++ /dev/null @@ -1,899 +0,0 @@ -parser grammar HlslExpr; - -@parser::header { - #pragma warning disable 3021 -} - -options { - tokenVocab = HlslAntlrLexer; -} - -compilationUnit - : Declarations+=topLevelDeclaration* EndOfFileToken=EOF - ; - -topLevelDeclaration - : classDefinition - | interfaceDefinition - | variableDeclarationStatement - | structDefinition - | constantBuffer - | functionDefinition - | functionDeclaration - ; - -classDefinition - : ClassKeyword=Class Name=Identifier BaseListOpt=baseList? - OpenBraceToken=LeftBrace classMemberDeclaration* CloseBraceToken=RightBrace - SemicolonToken=Semi - ; - -baseList - : ColonToken=Colon BaseType=Identifier - ; - -classMemberDeclaration - : variableDeclarationStatement - | functionDefinition - | functionDeclaration - ; - -constantBuffer - : CBufferKeyword=CBuffer Name=Identifier registerAllocation? - OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace - SemicolonToken=Semi? - ; - -variableDeclarationStatement - : variableDeclaration SemicolonToken=Semi - ; - -functionDefinition - : attribute* functionType (ClassName=Identifier ColonColonToken=ColonColon)? Name=Identifier - OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen - SemanticOpt=semantic? block SemicolonTokenOpt=Semi? - ; - -functionDeclaration - : attribute* functionType Name=Identifier - OpenParenToken=LeftParen functionParams? CloseParenToken=RightParen - SemanticOpt=semantic? SemicolonToken=Semi - ; - -functionType - : type - | Void - ; - -functionParams - : functionParam (Comma functionParam)* - ; - -functionParam - : storageFlags type variableDeclarator - ; - -interfaceDefinition - : InterfaceKeyword=Interface Name=Identifier - OpenBraceToken=LeftBrace functionDeclaration* CloseBraceToken=RightBrace - SemicolonToken=Semi - ; - -structDefinition - : StructKeyword=Struct Name=Identifier - OpenBraceToken=LeftBrace (Fields+=variableDeclarationStatement)+ CloseBraceToken=RightBrace - SemicolonToken=Semi - ; - -semantic - : ColonToken=Colon Name=Identifier - ; - -// -------------------------------------- -// ATTRIBUTES -// -------------------------------------- - -attributeArguments - : literalExpr (Comma literalExpr)* - ; - -attributeArgumentList - : OpenParenToken=LeftParen attributeArguments CloseParenToken=RightParen - ; - -attribute - : OpenBracketToken=LeftBracket Name=Identifier attributeArgumentList? CloseBracketToken=RightBracket - ; - -// -------------------------------------- -// STATEMENTS -// -------------------------------------- - -block - : OpenBrace=LeftBrace Stmts+=statement* CloseBrace=RightBrace - ; - -indentedEmbeddedStatement - : embeddedStatement // not a block statement - | LeftBrace Stmt=block - ; - -statement - : localDeclarationStatement - | embeddedStatement - | classDefinition - | interfaceDefinition - | structDefinition - ; - -localDeclarationStatement - : variableDeclaration SemicolonToken=Semi - ; - -forInitializer - : variableDeclaration # ForStatementDeclaration - | expression (Comma expression)* # ForStatementInitializers - ; - -forIncrementors - : expression (Comma expression)* - ; - -switchLabel - : CaseKeyword=Case Expr=expression ColonToken=Colon # CaseSwitchLabel - | DefaultKeyword=Default ColonToken=Colon # DefaultSwitchLabel - ; - -switchSection - : switchLabel+ statement+ - ; - -embeddedStatement - : SemicolonToken=Semi # EmptyStatement - | block # BlockStatement - | Expr=expression SemicolonToken=Semi # ExpressionStatement - - // Selection statement - | attribute* IfKeyword=If OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen Stmt=indentedEmbeddedStatement elseClause? # IfStatement - | attribute* SwitchKeyword=Switch OpenParenToken=LeftParen Expr=expression CloseParenToken=RightParen OpenBraceToken=LeftBrace switchSection* CloseBraceToken=RightBrace # SwitchStatement - - // Iteration statement - | attribute* WhileKeyword=While OpenParenToken=LeftParen condition=expression CloseParenToken=RightParen indentedEmbeddedStatement # WhileStatement - | attribute* DoKeyword=Do indentedEmbeddedStatement WhileKeyword=While OpenParenToken=LeftParen Condition=expression CloseParenToken=RightParen SemicolonToken=Semi # DoStatement - | attribute* ForKeyword=For OpenParenToken=LeftParen forInitializer? FirstSemicolonToken=Semi Condition=expression? SecondSemicolonToken=Semi iterator=forIncrementors? CloseParenToken=RightParen indentedEmbeddedStatement # ForStatement - - // Jump statement - | BreakKeyword=Break SemicolonToken=Semi # BreakStatement - | ContinueKeyword=Continue SemicolonToken=Semi # ContinueStatement - | DiscardKeyword=Discard SemicolonToken=Semi # DiscardStatement - | ReturnKeyword=Return Expr=expression? SemicolonToken=Semi # ReturnStatement - ; - -elseClause - : ElseKeyword=Else Stmt=indentedEmbeddedStatement - ; - -// -------------------------------------- -// EXPRESSIONS -// -------------------------------------- - -expression - : literalExpr # LiteralExpression - | Identifier # IdentifierExpression - | OpenParenToken=LeftParen expression CloseParenToken=RightParen # ParenthesizedExpression - | OpenParenToken=LeftParen type (ArrayRankSpecifiers+=arrayRankSpecifier)* CloseParenToken=RightParen Expr=expression # CastExpression - | Expr=expression DotToken=Dot Member=Identifier # MemberAccessExpression - | scalarOrVectorOrMatrixType argumentList # NumericConstructorExpression - | Expr=expression argumentList # FunctionCallExpression - | Expr=expression OpenBracket=LeftBracket Index=expression CloseBracket=RightBracket # ArrayAccessExpression - | Expr=expression Operator=postfixUnaryOperator # PostfixUnaryExpression - | Operator=prefixUnaryOperator Expr=expression # PrefixUnaryExpression - | Left=expression Operator=binaryOperator Right=expression # BinaryExpression - | Condition=expression QuestionToken=Question TrueExpr=expression ColonToken=Colon FalseExpr=expression # ConditionalExpression - | Left=expression Operator=assignmentOperator Right=expression # AssignmentExpression - ; - -literalExpr - : literal - ; - -postfixUnaryOperator - : PlusPlus - | MinusMinus - ; - -prefixUnaryOperator - : Plus - | Minus - | Not - | Tilde - | PlusPlus - | MinusMinus - ; - -binaryOperator - : Star - | Div - | Mod - | Plus - | Minus - | LeftShift - | RightShift - | Less - | Greater - | LessEqual - | GreaterEqual - | Equal - | NotEqual - | And - | Caret - | Or - | AndAnd - | OrOr - ; - -assignmentOperator - : Assign - | StarAssign - | DivAssign - | ModAssign - | PlusAssign - | MinusAssign - | LeftShiftAssign - | RightShiftAssign - | AndAssign - | XorAssign - | OrAssign - ; - -argumentList - : OpenParenToken=LeftParen arguments? CloseParenToken=RightParen - ; - -arguments - : expression (Comma expression)* - ; - - - -// -------------------------------------- -// TYPES -// -------------------------------------- - -variableDeclaration - : storageFlags type variableDeclarators - ; - -variableDeclarators - : variableDeclarator (Comma variableDeclarator)* - ; - -variableDeclarator - : Name=Identifier - (ArrayRankSpecifiers+=arrayRankSpecifier)* - packOffsetNode? - RegisterAllocation=registerAllocation? - SemanticOpt=semantic? - variableInitializer? - ; - -arrayRankSpecifier - : OpenBracketToken=LeftBracket Dimension=expression? CloseBracketToken=RightBracket - ; - -packOffsetNode - : ColonToken=Colon PackoffsetKeyword=Packoffset OpenParenToken=LeftParen - PackOffsetRegister=Identifier (DotToken=Dot PackOffsetComponent=Identifier)? - CloseParenToken=RightParen - ; - -storageFlags - : storageFlag* - ; - -storageFlag - // Type modifiers - : Const - | RowMajor - | ColumnMajor - // Storage classes - | Extern - | Precise - | Shared - | Groupshared - | Static - | Uniform - | Volatile - // Interpolation modifiers - | Linear - | Centroid - | Nointerpolation - | Noperspective - | Sample - // Parameter modifiers (only valid on function params) - | In - | Out - | Inout - // Geometry shader primitive type - | Point - | Line_ - | Triangle - | LineAdj - | TriangleAdj - ; - -type - : predefinedType - | userDefinedType - ; - -predefinedType - : bufferPredefinedType - | byteAddressBufferPredefinedType - | inlineStructPredefinedType - | patchPredefinedType - | matrixType - | genericMatrixPredefinedType - | samplerStatePredefinedType - | scalarType - | streamOutputPredefinedType - | structuredBufferPredefinedType - | texturePredefinedType - | genericTexturePredefinedType - | msTexturePredefinedType - | vectorType - | genericVectorType - ; - -bufferPredefinedType - : bufferType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater - ; - -bufferType - : Buffer - | RWBuffer - ; - -byteAddressBufferPredefinedType - : byteAddressBufferType - ; - -byteAddressBufferType - : ByteAddressBuffer - | RWByteAddressBuffer - ; - -inlineStructPredefinedType - : StructKeyword=Struct OpenBraceToken=LeftBrace - (variableDeclarationStatement)+ - CloseBraceToken=RightBrace - ; - -patchPredefinedType - : Keyword=patchType LessThanToken=Less - Name=userDefinedType CommaToken=Comma ControlPoints=IntegerLiteral - GreaterThanToken=Greater - ; - -patchType - : InputPatch - | OutputPatch - ; - -samplerStatePredefinedType - : Sampler - | SamplerState - | SamplerComparisonState - ; - -scalarType - : Bool - | Int - | Unsigned Int - | Dword - | Uint - | Half - | Float - | Double - ; - -streamOutputPredefinedType - : Keyword=streamOutputObjectType LessThanToken=Less type GreaterThanToken=Greater - ; - -streamOutputObjectType - : PointStream - | LineStream - | TriangleStream - ; - -structuredBufferPredefinedType - : Keyword=structuredBufferName LessThanToken=Less scalarOrVectorOrUserDefinedType GreaterThanToken=Greater - ; - -structuredBufferName - : AppendStructuredBuffer - | ConsumeStructuredBuffer - | RWStructuredBuffer - | StructuredBuffer - ; - -textureType - : Texture1D - | Texture1DArray - | Texture2D - | Texture2DArray - | Texture3D - | TextureCube - | TextureCubeArray - ; - -texturePredefinedType - : textureType - ; - -genericTexturePredefinedType - : textureType LessThanToken=Less scalarOrVectorType GreaterThanToken=Greater - ; - -textureTypeMS - : Texture2DMS - | Texture2DMSArray - ; - -msTexturePredefinedType - : textureTypeMS LessThanToken=Less scalarOrVectorType CommaToken=Comma Samples=IntegerLiteral GreaterThanToken=Greater - ; - -vectorType - : Vector - | Bool1 - | Bool2 - | Bool3 - | Bool4 - | Int1 - | Int2 - | Int3 - | Int4 - | Uint1 - | Uint2 - | Uint3 - | Uint4 - | Half1 - | Half2 - | Half3 - | Half4 - | Float1 - | Float2 - | Float3 - | Float4 - | Double1 - | Double2 - | Double3 - | Double4 - ; - -genericVectorType - : VectorKeyword=Vector LessThanToken=Less scalarType CommaToken=Comma - Size_=IntegerLiteral GreaterThanToken=Greater - ; - -scalarOrVectorType - : scalarType - | vectorType - ; - -scalarOrVectorOrUserDefinedType - : scalarType - | vectorType - | userDefinedType - ; - -scalarOrVectorOrMatrixType - : scalarType - | vectorType - | matrixType - ; - -matrixType - : Matrix - | Bool1x1 - | Bool1x2 - | Bool1x3 - | Bool1x4 - | Bool2x1 - | Bool2x2 - | Bool2x3 - | Bool2x4 - | Bool3x1 - | Bool3x2 - | Bool3x3 - | Bool3x4 - | Bool4x1 - | Bool4x2 - | Bool4x3 - | Bool4x4 - | Int1x1 - | Int1x2 - | Int1x3 - | Int1x4 - | Int2x1 - | Int2x2 - | Int2x3 - | Int2x4 - | Int3x1 - | Int3x2 - | Int3x3 - | Int3x4 - | Int4x1 - | Int4x2 - | Int4x3 - | Int4x4 - | Uint1x1 - | Uint1x2 - | Uint1x3 - | Uint1x4 - | Uint2x1 - | Uint2x2 - | Uint2x3 - | Uint2x4 - | Uint3x1 - | Uint3x2 - | Uint3x3 - | Uint3x4 - | Uint4x1 - | Uint4x2 - | Uint4x3 - | Uint4x4 - | Half1x1 - | Half1x2 - | Half1x3 - | Half1x4 - | Half2x1 - | Half2x2 - | Half2x3 - | Half2x4 - | Half3x1 - | Half3x2 - | Half3x3 - | Half3x4 - | Half4x1 - | Half4x2 - | Half4x3 - | Half4x4 - | Float1x1 - | Float1x2 - | Float1x3 - | Float1x4 - | Float2x1 - | Float2x2 - | Float2x3 - | Float2x4 - | Float3x1 - | Float3x2 - | Float3x3 - | Float3x4 - | Float4x1 - | Float4x2 - | Float4x3 - | Float4x4 - | Double1x1 - | Double1x2 - | Double1x3 - | Double1x4 - | Double2x1 - | Double2x2 - | Double2x3 - | Double2x4 - | Double3x1 - | Double3x2 - | Double3x3 - | Double3x4 - | Double4x1 - | Double4x2 - | Double4x3 - | Double4x4 - ; - -genericMatrixPredefinedType - : MatrixKeyword=Matrix LessThanToken=Less scalarType FirstCommaToken=Comma - Rows_=IntegerLiteral SecondCommaToken=Comma Cols_=IntegerLiteral - GreaterThanToken=Greater - ; - -userDefinedType - : Name=Identifier - ; - -registerAllocation - : RegisterColon=Colon RegisterKeyword=Register OpenParenToken=LeftParen Address=Identifier CloseParenToken=RightParen - ; - -variableInitializer - : EqualsToken=Assign standardVariableInitializer # StandardVariableInitializer_ - | OpenBraceToken=LeftBrace samplerStateProperty* CloseBraceToken=RightBrace # SamplerStateInitializer - ; - -standardVariableInitializer - : OpenBrace=LeftBrace arrayElementInitializers CloseBrace=RightBrace # ArrayVariableInitializer - | Expr=expression # ExpressionVariableInitializer - ; - -arrayElementInitializers - : standardVariableInitializer (Comma standardVariableInitializer)* Comma? - ; - -samplerStateProperty - : Name=Identifier EqualsToken=Assign Expr=expression SemicolonToken=Semi - ; - -literal - : True - | False - | FloatLiteral - | IntegerLiteral - | StringLiteral - ; - - - -// -------------------------------------- -// PREPROCESSOR DIRECTIVES -// -------------------------------------- - -directive - : ifDirective - | ifDefDirective - | ifNDefDirective - | elseDirective - | elifDirective - | endIfDirective - | objectLikeDefineDirective - | includeDirective - | lineDirective - ; - -ifDirective - : HashToken=Hash IfKeyword=If Condition=directiveExpression EndOfDirectiveToken=EndOfDirective - ; - -ifDefDirective - : HashToken=Hash IfDefKeyword=IfDef Name=Identifier EndOfDirectiveToken=EndOfDirective - ; - -ifNDefDirective - : HashToken=Hash IfNDefKeyword=IfNDef Name=Identifier EndOfDirectiveToken=EndOfDirective - ; - -elseDirective - : HashToken=Hash ElseKeyword=Else EndOfDirectiveToken=EndOfDirective - ; - -elifDirective - : HashToken=Hash ElifKeyword=Elif Condition=directiveExpression EndOfDirectiveToken=EndOfDirective - ; - -endIfDirective - : HashToken=Hash EndIfKeyword=EndIf EndOfDirectiveToken=EndOfDirective - ; - -objectLikeDefineDirective - : HashToken=Hash DefineKeyword=Define Name=identifierOrKeyword Values+=~(EndOfDirective)* EndOfDirectiveToken=EndOfDirective - ; - -includeDirective - : HashToken=Hash IncludeKeyword=Include Filename=StringLiteral EndOfDirectiveToken=EndOfDirective - ; - -lineDirective - : HashToken=Hash LineKeyword=Line_ LineNumber=IntegerLiteral Filename=StringLiteral EndOfDirectiveToken=EndOfDirective - ; - -directiveExpression - : literal # LiteralDirectiveExpression - | identifierOrKeyword # IdentifierDirectiveExpression - | OpenParenToken=LeftParen directiveExpression CloseParenToken=RightParen # ParenthesizedDirectiveExpression - | Function=Defined OpenParenToken=LeftParen Name=. CloseParenToken=RightParen # FunctionCallDirectiveExpression - | Expr=directiveExpression Operator=postfixUnaryOperator # PostfixUnaryDirectiveExpression - | Operator=prefixUnaryOperator Expr=directiveExpression # PrefixUnaryDirectiveExpression - | Left=directiveExpression Operator=binaryOperator Right=directiveExpression # BinaryDirectiveExpression - ; - -identifierOrKeyword - : AppendStructuredBuffer - | Bool - | Bool1 - | Bool2 - | Bool3 - | Bool4 - | Bool1x1 - | Bool1x2 - | Bool1x3 - | Bool1x4 - | Bool2x1 - | Bool2x2 - | Bool2x3 - | Bool2x4 - | Bool3x1 - | Bool3x2 - | Bool3x3 - | Bool3x4 - | Bool4x1 - | Bool4x2 - | Bool4x3 - | Bool4x4 - | Buffer - | ByteAddressBuffer - | Break - | Case - | CBuffer - | Centroid - | Class - | ColumnMajor - | Const - | ConsumeStructuredBuffer - | Continue - | Default - | Discard - | Do - | Double - | Double1 - | Double2 - | Double3 - | Double4 - | Double1x1 - | Double1x2 - | Double1x3 - | Double1x4 - | Double2x1 - | Double2x2 - | Double2x3 - | Double2x4 - | Double3x1 - | Double3x2 - | Double3x3 - | Double3x4 - | Double4x1 - | Double4x2 - | Double4x3 - | Double4x4 - | Else - | Extern - | Float - | Float1 - | Float2 - | Float3 - | Float4 - | Float1x1 - | Float1x2 - | Float1x3 - | Float1x4 - | Float2x1 - | Float2x2 - | Float2x3 - | Float2x4 - | Float3x1 - | Float3x2 - | Float3x3 - | Float3x4 - | Float4x1 - | Float4x2 - | Float4x3 - | Float4x4 - | For - | Groupshared - | Half - | Half1 - | Half2 - | Half3 - | Half4 - | Half1x1 - | Half1x2 - | Half1x3 - | Half1x4 - | Half2x1 - | Half2x2 - | Half2x3 - | Half2x4 - | Half3x1 - | Half3x2 - | Half3x3 - | Half3x4 - | Half4x1 - | Half4x2 - | Half4x3 - | Half4x4 - | If - | In - | Inout - | InputPatch - | Int - | Int1 - | Int2 - | Int3 - | Int4 - | Int1x1 - | Int1x2 - | Int1x3 - | Int1x4 - | Int2x1 - | Int2x2 - | Int2x3 - | Int2x4 - | Int3x1 - | Int3x2 - | Int3x3 - | Int3x4 - | Int4x1 - | Int4x2 - | Int4x3 - | Int4x4 - | Interface - | Line_ - | LineAdj - | Linear - | LineStream - | Matrix - | Nointerpolation - | Noperspective - | Out - | OutputPatch - | Packoffset - | Point - | PointStream - | Precise - | Register - | Return - | RowMajor - | RWBuffer - | RWByteAddressBuffer - | RWStructuredBuffer - | Sample - | Sampler - | SamplerComparisonState - | SamplerState - | Shared - | Static - | Struct - | StructuredBuffer - | Switch - | Texture1D - | Texture1DArray - | Texture2D - | Texture2DArray - | Texture2DMS - | Texture2DMSArray - | Texture3D - | TextureCube - | TextureCubeArray - | Triangle - | TriangleAdj - | TriangleStream - | Uniform - | Uint - | Uint1 - | Uint2 - | Uint3 - | Uint4 - | Uint1x1 - | Uint1x2 - | Uint1x3 - | Uint1x4 - | Uint2x1 - | Uint2x2 - | Uint2x3 - | Uint2x4 - | Uint3x1 - | Uint3x2 - | Uint3x3 - | Uint3x4 - | Uint4x1 - | Uint4x2 - | Uint4x3 - | Uint4x4 - | Vector - | Volatile - | Void - | While - | Identifier - ; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 b/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 deleted file mode 100644 index a6b7593737..0000000000 --- a/src/Stride.Shader.Parsing/Frontend/Hlsl/HlslTokens.g4 +++ /dev/null @@ -1,426 +0,0 @@ -lexer grammar HlslTokens; - -@lexer::header {#pragma warning disable 3021} - -AppendStructuredBuffer : 'AppendStructuredBuffer'; -Bool : 'bool'; -Bool1 : 'bool1'; -Bool2 : 'bool2'; -Bool3 : 'bool3'; -Bool4 : 'bool4'; -Bool1x1 : 'bool1x1'; -Bool1x2 : 'bool1x2'; -Bool1x3 : 'bool1x3'; -Bool1x4 : 'bool1x4'; -Bool2x1 : 'bool2x1'; -Bool2x2 : 'bool2x2'; -Bool2x3 : 'bool2x3'; -Bool2x4 : 'bool2x4'; -Bool3x1 : 'bool3x1'; -Bool3x2 : 'bool3x2'; -Bool3x3 : 'bool3x3'; -Bool3x4 : 'bool3x4'; -Bool4x1 : 'bool4x1'; -Bool4x2 : 'bool4x2'; -Bool4x3 : 'bool4x3'; -Bool4x4 : 'bool4x4'; -Buffer : 'Buffer'; -ByteAddressBuffer : 'ByteAddressBuffer'; -Break : 'break'; -Case : 'case'; -CBuffer : 'cbuffer'; -Centroid : 'centroid'; -Class : 'class'; -ColumnMajor : 'column_major'; -Const : 'const'; -ConsumeStructuredBuffer : 'ConsumeStructuredBuffer'; -Continue : 'continue'; -Default : 'default'; -Discard : 'discard'; -Do : 'do'; -Double : 'double'; -Double1 : 'double1'; -Double2 : 'double2'; -Double3 : 'double3'; -Double4 : 'double4'; -Double1x1 : 'double1x1'; -Double1x2 : 'double1x2'; -Double1x3 : 'double1x3'; -Double1x4 : 'double1x4'; -Double2x1 : 'double2x1'; -Double2x2 : 'double2x2'; -Double2x3 : 'double2x3'; -Double2x4 : 'double2x4'; -Double3x1 : 'double3x1'; -Double3x2 : 'double3x2'; -Double3x3 : 'double3x3'; -Double3x4 : 'double3x4'; -Double4x1 : 'double4x1'; -Double4x2 : 'double4x2'; -Double4x3 : 'double4x3'; -Double4x4 : 'double4x4'; -Else : 'else'; -Extern : 'extern'; -Float : 'float'; -Float1 : 'float1'; -Float2 : 'float2'; -Float3 : 'float3'; -Float4 : 'float4'; -Float1x1 : 'float1x1'; -Float1x2 : 'float1x2'; -Float1x3 : 'float1x3'; -Float1x4 : 'float1x4'; -Float2x1 : 'float2x1'; -Float2x2 : 'float2x2'; -Float2x3 : 'float2x3'; -Float2x4 : 'float2x4'; -Float3x1 : 'float3x1'; -Float3x2 : 'float3x2'; -Float3x3 : 'float3x3'; -Float3x4 : 'float3x4'; -Float4x1 : 'float4x1'; -Float4x2 : 'float4x2'; -Float4x3 : 'float4x3'; -Float4x4 : 'float4x4'; -For : 'for'; -Groupshared : 'groupshared'; -Half : 'half'; -Half1 : 'half1'; -Half2 : 'half2'; -Half3 : 'half3'; -Half4 : 'half4'; -Half1x1 : 'half1x1'; -Half1x2 : 'half1x2'; -Half1x3 : 'half1x3'; -Half1x4 : 'half1x4'; -Half2x1 : 'half2x1'; -Half2x2 : 'half2x2'; -Half2x3 : 'half2x3'; -Half2x4 : 'half2x4'; -Half3x1 : 'half3x1'; -Half3x2 : 'half3x2'; -Half3x3 : 'half3x3'; -Half3x4 : 'half3x4'; -Half4x1 : 'half4x1'; -Half4x2 : 'half4x2'; -Half4x3 : 'half4x3'; -Half4x4 : 'half4x4'; -If : 'if'; -In : 'in'; -Inout : 'inout' | 'in out'; -InputPatch : 'InputPatch'; -Int : 'int'; -Int1 : 'int1'; -Int2 : 'int2'; -Int3 : 'int3'; -Int4 : 'int4'; -Int1x1 : 'int1x1'; -Int1x2 : 'int1x2'; -Int1x3 : 'int1x3'; -Int1x4 : 'int1x4'; -Int2x1 : 'int2x1'; -Int2x2 : 'int2x2'; -Int2x3 : 'int2x3'; -Int2x4 : 'int2x4'; -Int3x1 : 'int3x1'; -Int3x2 : 'int3x2'; -Int3x3 : 'int3x3'; -Int3x4 : 'int3x4'; -Int4x1 : 'int4x1'; -Int4x2 : 'int4x2'; -Int4x3 : 'int4x3'; -Int4x4 : 'int4x4'; -Interface : 'interface'; -Line_ : 'line'; -LineAdj : 'lineadj'; -Linear : 'linear'; -LineStream : 'LineStream'; -Long : 'long'; -Matrix : 'matrix'; -Nointerpolation : 'nointerpolation'; -Noperspective : 'noperspective'; -Out : 'out'; -OutputPatch : 'OutputPatch'; -Packoffset : 'packoffset'; -Point : 'point'; -PointStream : 'PointStream'; -Precise : 'precise'; -Register : 'register'; -Return : 'return'; -RowMajor : 'row_major'; -RWBuffer : 'RWBuffer'; -RWByteAddressBuffer : 'RWByteAddressBuffer'; -RWStructuredBuffer : 'RWStructuredBuffer'; -Sample : 'sample'; -Sampler : 'sampler'; -SamplerComparisonState : 'SamplerComparisonState'; -SamplerState : 'SamplerState'; -Shared : 'shared'; -Static : 'static'; -Struct : 'struct'; -StructuredBuffer : 'StructuredBuffer'; -Switch : 'switch'; -Texture1D : 'Texture1D'; -Texture1DArray : 'Texture1DArray'; -Texture2D : 'Texture2D'; -Texture2DArray : 'Texture2DArray'; -Texture2DMS : 'Texture2DMS'; -Texture2DMSArray : 'Texture2DMSArray'; -Texture3D : 'Texture3D'; -TextureCube : 'TextureCube'; -TextureCubeArray : 'TextureCubeArray'; -Triangle : 'triangle'; -TriangleAdj : 'triangleadj'; -TriangleStream : 'TriangleStream'; -Uniform : 'uniform'; -Uint : 'uint' | 'unsigned int' | 'dword'; -Uint1 : 'uint1'; -Uint2 : 'uint2'; -Uint3 : 'uint3'; -Uint4 : 'uint4'; -Uint1x1 : 'uint1x1'; -Uint1x2 : 'uint1x2'; -Uint1x3 : 'uint1x3'; -Uint1x4 : 'uint1x4'; -Uint2x1 : 'uint2x1'; -Uint2x2 : 'uint2x2'; -Uint2x3 : 'uint2x3'; -Uint2x4 : 'uint2x4'; -Uint3x1 : 'uint3x1'; -Uint3x2 : 'uint3x2'; -Uint3x3 : 'uint3x3'; -Uint3x4 : 'uint3x4'; -Uint4x1 : 'uint4x1'; -Uint4x2 : 'uint4x2'; -Uint4x3 : 'uint4x3'; -Uint4x4 : 'uint4x4'; -Vector : 'vector'; -Volatile : 'volatile'; -Void : 'void'; -While : 'while'; - -LeftParen : '('; -RightParen : ')'; -LeftBracket : '['; -RightBracket : ']'; -LeftBrace : '{'; -RightBrace : '}'; - -Less : '<'; -LessEqual : '<='; -Greater : '>'; -GreaterEqual : '>='; -LeftShift : '<<'; -RightShift : '>>'; - -Plus : '+'; -PlusPlus : '++'; -Minus : '-'; -MinusMinus : '--'; -Star : '*'; -Div : '/'; -Mod : '%'; - -And : '&'; -Or : '|'; -AndAnd : '&&'; -OrOr : '||'; -Caret : '^'; -Not : '!'; -Tilde : '~'; - -Question : '?'; -Colon : ':'; -ColonColon : '::'; -Semi : ';'; -Comma : ','; - -Assign : '='; -// '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' -StarAssign : '*='; -DivAssign : '/='; -ModAssign : '%='; -PlusAssign : '+='; -MinusAssign : '-='; -LeftShiftAssign : '<<='; -RightShiftAssign : '>>='; -AndAssign : '&='; -XorAssign : '^='; -OrAssign : '|='; - -Equal : '=='; -NotEqual : '!='; - -Dot : '.'; - -True : 'true'; -False : 'false'; - -Identifier - : Nondigit (Nondigit | Digit)* - ; - -fragment -Nondigit - : [a-zA-Z_] - ; - -fragment -Digit - : [0-9] - ; - -fragment -NonzeroDigit - : '0' | Digit - ; - -IntegerLiteral - : DecimalIntegerLiteral IntegerSuffix? - | HexadecimalIntegerLiteral IntegerSuffix? - ; - -fragment -DecimalIntegerLiteral - : Digit+ - ; - -fragment -HexadecimalIntegerLiteral - : ('0x' | '0X') HexadecimalDigit+ - ; - -fragment -HexadecimalDigit - : [0-9a-fA-F] - ; - -fragment -IntegerSuffix - : [uUlL] - ; - -FloatLiteral - : FractionalConstant ExponentPart? FloatingSuffix? - | DigitSequence ExponentPart FloatingSuffix? - ; - -fragment -FractionalConstant - : DigitSequence? '.' DigitSequence - | DigitSequence '.' - ; - -fragment -ExponentPart - : 'e' Sign? DigitSequence - | 'E' Sign? DigitSequence - ; - -fragment -Sign - : '+' | '-' - ; - -fragment -DigitSequence - : Digit+ - ; - -fragment -HexadecimalDigitSequence - : HexadecimalDigit+ - ; - -fragment -FloatingSuffix - : [flFL] - ; - -fragment -EscapeSequence - : SimpleEscapeSequence - ; - -fragment -SimpleEscapeSequence - : '\\' ['"?abfnrtv\\] - ; - -StringLiteral - : '"' SCharSequence? '"' - ; - -fragment -SCharSequence - : SChar+ - ; - -fragment -SChar - : ~["\\\r\n] - | EscapeSequence - ; - -LineDirective - : '#line' Whitespace? DecimalIntegerLiteral Whitespace? StringLiteral ~[\r\n]* - { - var regex = new System.Text.RegularExpressions.Regex("#line\\s(\\d+)\\s"); - Line = System.Convert.ToInt32(regex.Match(Text).Groups[1].Value) - 1; - } - -> skip - ; - -PragmaDirective - : '#' Whitespace? 'pragma' Whitespace ~[\r\n]* - -> skip - ; - -Whitespace - : [ \t]+ - ; - -Newline - : ( '\r' '\n'? - | '\n' - ) - ; - -PreprocessorDirective - : '#' Whitespace? PreprocessorDirectiveName - ; - -fragment -PreprocessorDirectiveName - : 'define' - | 'elif' - | 'else' - | 'endif' - | 'error' - | 'if' - | 'ifdef' - | 'ifndef' - | 'include' - | 'line' - | 'pragma' - | 'undef' - ; - -StartBlockComment - : '/*' -> more, mode(BlockCommentMode) - ; - -LineComment - : '//' ~[\r\n]* - ; - -// -------------------------------------- -// MODES -// -------------------------------------- - -mode BlockCommentMode; - - //BlockCommentNewline : Newline -> type(Newline); - BlockCommentContent : . -> more; - BlockCommentEndOfFile : EOF; - BlockComment : '*/' -> mode(DEFAULT_MODE); \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl b/src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl deleted file mode 100644 index 5fb572a357..0000000000 --- a/src/Stride.Shader.Parsing/Frontend/Hlsl/code.hlsl +++ /dev/null @@ -1,8 +0,0 @@ -#if - DODO_dodo = toto -#endif - -void main() -{ - -} \ No newline at end of file From 8c1aa77e6681c6a1bd9f9f340bff7ff0ab8da209 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:31:29 +0200 Subject: [PATCH 0085/1182] removed submodule --- .gitmodules | 3 +++ SDSLParser.sln | 7 +++++++ src/Stride.Shader.Parsing/SDSLMixer.cs | 1 + src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj | 1 + 4 files changed, 12 insertions(+) diff --git a/.gitmodules b/.gitmodules index 3193eb8a34..4d05647ccf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule ".\\src\\CppNet"] path = .\\src\\CppNet url = https://github.com/ykafia/CppNet +[submodule ".\\src\\Spv.Generator"] + path = .\\src\\Spv.Generator + url = https://github.com/ykafia/Spv.Generator diff --git a/SDSLParser.sln b/SDSLParser.sln index 719ff0e976..9fdc69e21c 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shader.Parsing.Test" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "src\CppNet\CppNet.csproj", "{C2FD9262-69F8-4B75-9AB1-FF359C9143E9}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spv.Generator", "src\Spv.Generator\Spv.Generator\Spv.Generator.csproj", "{09D8574D-6452-40E2-9724-9C58F446D862}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -35,6 +37,10 @@ Global {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Debug|Any CPU.Build.0 = Debug|Any CPU {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Release|Any CPU.ActiveCfg = Release|Any CPU {C2FD9262-69F8-4B75-9AB1-FF359C9143E9}.Release|Any CPU.Build.0 = Release|Any CPU + {09D8574D-6452-40E2-9724-9C58F446D862}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {09D8574D-6452-40E2-9724-9C58F446D862}.Debug|Any CPU.Build.0 = Debug|Any CPU + {09D8574D-6452-40E2-9724-9C58F446D862}.Release|Any CPU.ActiveCfg = Release|Any CPU + {09D8574D-6452-40E2-9724-9C58F446D862}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -44,6 +50,7 @@ Global {3A20C614-0B73-4592-B0A3-152FBA7C112C} = {5F88D871-B760-4857-BD74-296B07778B15} {6D885FCB-C043-4065-BA7E-E4937667B219} = {5F88D871-B760-4857-BD74-296B07778B15} {C2FD9262-69F8-4B75-9AB1-FF359C9143E9} = {5F88D871-B760-4857-BD74-296B07778B15} + {09D8574D-6452-40E2-9724-9C58F446D862} = {5F88D871-B760-4857-BD74-296B07778B15} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4AF186D8-C065-4788-835B-3C253D65EAE0} diff --git a/src/Stride.Shader.Parsing/SDSLMixer.cs b/src/Stride.Shader.Parsing/SDSLMixer.cs index eba4cf84ac..2be5301d72 100644 --- a/src/Stride.Shader.Parsing/SDSLMixer.cs +++ b/src/Stride.Shader.Parsing/SDSLMixer.cs @@ -8,6 +8,7 @@ namespace Stride.Shader.Parsing; public class SDSLMixer { + //Dictionary List Mixins { get; set; } = new(); } diff --git a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj index a5ee4d56eb..cb595e0572 100644 --- a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj +++ b/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj @@ -3,6 +3,7 @@ + From bfcd3a8965906535d2be82c14c89106dd03e234f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:32:17 +0200 Subject: [PATCH 0086/1182] removed ref submodule --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4d05647ccf..3193eb8a34 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule ".\\src\\CppNet"] path = .\\src\\CppNet url = https://github.com/ykafia/CppNet -[submodule ".\\src\\Spv.Generator"] - path = .\\src\\Spv.Generator - url = https://github.com/ykafia/Spv.Generator From 501219618e77c6340bf7240beb97244cec02a0d3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:47:11 +0200 Subject: [PATCH 0087/1182] git push --- .gitmodules | 3 +++ src/Spv.Generator | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/Spv.Generator diff --git a/.gitmodules b/.gitmodules index 3193eb8a34..4d05647ccf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule ".\\src\\CppNet"] path = .\\src\\CppNet url = https://github.com/ykafia/CppNet +[submodule ".\\src\\Spv.Generator"] + path = .\\src\\Spv.Generator + url = https://github.com/ykafia/Spv.Generator diff --git a/src/Spv.Generator b/src/Spv.Generator new file mode 160000 index 0000000000..8be457e4a6 --- /dev/null +++ b/src/Spv.Generator @@ -0,0 +1 @@ +Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 From d1bfa001575c5abd35ca619bd2fc220bb82810d6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:47:18 +0200 Subject: [PATCH 0088/1182] removed git module --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4d05647ccf..e811a1deec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule ".\\src\\Eto.Parse"] path = .\\src\\Eto.Parse url = https://github.com/ykafia/Eto.Parse -[submodule ".\\src\\CppNet"] - path = .\\src\\CppNet - url = https://github.com/ykafia/CppNet [submodule ".\\src\\Spv.Generator"] path = .\\src\\Spv.Generator url = https://github.com/ykafia/Spv.Generator From 97a725fd85015a144fd218276ae829b2e9e411cf Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:48:50 +0200 Subject: [PATCH 0089/1182] uggly restart --- src/CppNet | 1 - src/Eto.Parse | 1 - 2 files changed, 2 deletions(-) delete mode 160000 src/CppNet delete mode 160000 src/Eto.Parse diff --git a/src/CppNet b/src/CppNet deleted file mode 160000 index a93fea69ee..0000000000 --- a/src/CppNet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 diff --git a/src/Eto.Parse b/src/Eto.Parse deleted file mode 160000 index af87b77d8c..0000000000 --- a/src/Eto.Parse +++ /dev/null @@ -1 +0,0 @@ -Subproject commit af87b77d8c63ef675e65815770bea71ca32e2ae7 From 85697158dd7f8ee995e9cb82d63ada3f0670b5ca Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 20:49:36 +0200 Subject: [PATCH 0090/1182] added submodule --- .gitmodules | 3 +++ src/CppNet | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/CppNet diff --git a/.gitmodules b/.gitmodules index e811a1deec..4c41e4d886 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule ".\\src\\Spv.Generator"] path = .\\src\\Spv.Generator url = https://github.com/ykafia/Spv.Generator +[submodule ".\\src\\CppNet"] + path = .\\src\\CppNet + url = https://github.com/ykafia/CppNet diff --git a/src/CppNet b/src/CppNet new file mode 160000 index 0000000000..a93fea69ee --- /dev/null +++ b/src/CppNet @@ -0,0 +1 @@ +Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 From 2e432b0ccb60a14947396da8031fff7f3fd93d90 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 22:48:35 +0200 Subject: [PATCH 0091/1182] Removed submodules --- .gitmodules | 3 --- src/CppNet | 1 - src/Spv.Generator | 1 - 3 files changed, 5 deletions(-) delete mode 160000 src/CppNet delete mode 160000 src/Spv.Generator diff --git a/.gitmodules b/.gitmodules index 4c41e4d886..e811a1deec 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule ".\\src\\Spv.Generator"] path = .\\src\\Spv.Generator url = https://github.com/ykafia/Spv.Generator -[submodule ".\\src\\CppNet"] - path = .\\src\\CppNet - url = https://github.com/ykafia/CppNet diff --git a/src/CppNet b/src/CppNet deleted file mode 160000 index a93fea69ee..0000000000 --- a/src/CppNet +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 diff --git a/src/Spv.Generator b/src/Spv.Generator deleted file mode 160000 index 8be457e4a6..0000000000 --- a/src/Spv.Generator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 From 67b4a93d9504d5b7ce97595bfff5f41be43ebf3c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 22:55:00 +0200 Subject: [PATCH 0092/1182] removed submodules --- .gitmodules | 7 +------ src/Spv.Generator | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) create mode 160000 src/Spv.Generator diff --git a/.gitmodules b/.gitmodules index e811a1deec..8b13789179 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1 @@ -[submodule ".\\src\\Eto.Parse"] - path = .\\src\\Eto.Parse - url = https://github.com/ykafia/Eto.Parse -[submodule ".\\src\\Spv.Generator"] - path = .\\src\\Spv.Generator - url = https://github.com/ykafia/Spv.Generator + diff --git a/src/Spv.Generator b/src/Spv.Generator new file mode 160000 index 0000000000..8be457e4a6 --- /dev/null +++ b/src/Spv.Generator @@ -0,0 +1 @@ +Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 From e614b883eed47f6799c978d26d8fd931e52ac4e5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 27 May 2022 22:55:39 +0200 Subject: [PATCH 0093/1182] Commit remove spvgen --- src/Spv.Generator | 1 - 1 file changed, 1 deletion(-) delete mode 160000 src/Spv.Generator diff --git a/src/Spv.Generator b/src/Spv.Generator deleted file mode 160000 index 8be457e4a6..0000000000 --- a/src/Spv.Generator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 From 6f1a516872b471d4126849c28e9388c3b19f90ac Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 27 May 2022 23:01:00 +0200 Subject: [PATCH 0094/1182] Re added spv generator submodule --- .gitmodules | 3 +++ src/Spv.Generator | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/Spv.Generator diff --git a/.gitmodules b/.gitmodules index 8b13789179..7a48a49a24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1 +1,4 @@ +[submodule "src/Spv.Generator"] + path = src/Spv.Generator + url = https://github.com/ykafia/Spv.Generator diff --git a/src/Spv.Generator b/src/Spv.Generator new file mode 160000 index 0000000000..8be457e4a6 --- /dev/null +++ b/src/Spv.Generator @@ -0,0 +1 @@ +Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 From 8fc5de85894abfa306af2db8a5f6d9497fd92cc0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 27 May 2022 23:02:32 +0200 Subject: [PATCH 0095/1182] Added CppNet --- .gitmodules | 3 +++ src/CppNet | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/CppNet diff --git a/.gitmodules b/.gitmodules index 7a48a49a24..acde3b0884 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ [submodule "src/Spv.Generator"] path = src/Spv.Generator url = https://github.com/ykafia/Spv.Generator +[submodule "src/CppNet"] + path = src/CppNet + url = https://github.com/ykafia/CppNet diff --git a/src/CppNet b/src/CppNet new file mode 160000 index 0000000000..a93fea69ee --- /dev/null +++ b/src/CppNet @@ -0,0 +1 @@ +Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 From ff2ca286304feb586135e056c2897f73015ff094 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 27 May 2022 23:03:40 +0200 Subject: [PATCH 0096/1182] Added back Eto.Parse --- .gitmodules | 3 +++ src/Eto.Parse | 1 + 2 files changed, 4 insertions(+) create mode 160000 src/Eto.Parse diff --git a/.gitmodules b/.gitmodules index acde3b0884..9cb21aab18 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "src/CppNet"] path = src/CppNet url = https://github.com/ykafia/CppNet +[submodule "src/Eto.Parse"] + path = src/Eto.Parse + url = https://github.com/ykafia/Eto.Parse diff --git a/src/Eto.Parse b/src/Eto.Parse new file mode 160000 index 0000000000..af87b77d8c --- /dev/null +++ b/src/Eto.Parse @@ -0,0 +1 @@ +Subproject commit af87b77d8c63ef675e65815770bea71ca32e2ae7 From 368099c70ad67464396f22a5bca9cac7c3ff92d9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 28 May 2022 00:25:28 +0200 Subject: [PATCH 0097/1182] Update on shader mixin --- .../{SDSLMixer.cs => ShaderMixer.cs} | 9 ++- src/Stride.Shader.Parsing/ShaderMixin.cs | 58 ++++++++++++++++++- 2 files changed, 63 insertions(+), 4 deletions(-) rename src/Stride.Shader.Parsing/{SDSLMixer.cs => ShaderMixer.cs} (66%) diff --git a/src/Stride.Shader.Parsing/SDSLMixer.cs b/src/Stride.Shader.Parsing/ShaderMixer.cs similarity index 66% rename from src/Stride.Shader.Parsing/SDSLMixer.cs rename to src/Stride.Shader.Parsing/ShaderMixer.cs index 2be5301d72..3c103e7656 100644 --- a/src/Stride.Shader.Parsing/SDSLMixer.cs +++ b/src/Stride.Shader.Parsing/ShaderMixer.cs @@ -3,12 +3,17 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Spv.Generator; namespace Stride.Shader.Parsing; -public class SDSLMixer +public class ShaderMixer : Module { //Dictionary List Mixins { get; set; } = new(); - + + public ShaderMixer(uint version) : base(version) + { + } + } diff --git a/src/Stride.Shader.Parsing/ShaderMixin.cs b/src/Stride.Shader.Parsing/ShaderMixin.cs index ba50b9b91c..854c5c94cc 100644 --- a/src/Stride.Shader.Parsing/ShaderMixin.cs +++ b/src/Stride.Shader.Parsing/ShaderMixin.cs @@ -10,7 +10,61 @@ namespace Stride.Shader.Parsing; public class ShaderMixin { public string Code { get; set; } - public string MixinName { get; set; } - public ShaderToken AST { get; set; } + public string MixinName { get => AST != null ? AST.Name : string.Empty; } + public ShaderProgram? AST { get; set; } + Eto.Parse.Grammar EntryPointMatcher = new Eto.Parse.Grammar( + Eto.Parse.Terminals.Literal("PSMain") + | "VSMain" + | "GSMain" + | "HSMain" + | "DSMain" + | "CSMain"); + + SDSLParser Parser { get; set; } = new(); + + public ShaderMixin(string code) + { + Code = code; + } + + public void Parse() + { + AST = (ShaderProgram)Parser.Parse(Code); + } + + public IEnumerable GetStreamValues() + { + if (AST is not null) + return + AST.Body + .Where(x => x is ShaderValueDeclaration) + .Cast() + .Where(x => x.IsStream); + else + throw new Exception("AST is null"); + } + public IEnumerable GetEntryPoints() + { + if (AST is not null) + return + AST.Body + .Where(x => x is ShaderMethod) + .Cast() + .Where(x => EntryPointMatcher.Match(x.Name).Success); + else + throw new Exception("AST is null"); + } + public IEnumerable GetMethods() + { + if (AST is not null) + return + AST.Body + .Where(x => x is ShaderMethod) + .Cast() + .Where(x => !EntryPointMatcher.Match(x.Name).Success); + else + throw new Exception("AST is null"); + } + } From 29fdc285c962a2d08a7d8ad5daed66d3abd50878 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 29 May 2022 21:18:44 +0200 Subject: [PATCH 0098/1182] Correction directive method parsing + added mixer classes --- src/SDSLParserExample/SDSL/shader2.sdsl | 3 ++- .../Frontend/AST/Shader/ShaderToken.cs | 3 ++- .../Frontend/AST/Shader/Statements.cs | 17 +++++++++++++++++ .../SDSLGrammar.Directives.Expression.cs | 5 +++-- .../SDSLGrammar/SDSLGrammar.Expression.cs | 9 ++++++--- .../SDSLGrammar/SDSLGrammar.Statements.cs | 16 ++++++++-------- .../Frontend/SDSLParser.cs | 4 ++-- src/Stride.Shader.Parsing/ShaderMixer.cs | 5 +---- src/Stride.Shader.Parsing/SpirvEmitter.cs | 17 +++++++++++++++++ 9 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs create mode 100644 src/Stride.Shader.Parsing/SpirvEmitter.cs diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index a2cf92ab9e..eca27cf6d6 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,9 +1,10 @@ shader MyShader { + stream float3 a : POSITION; stream float b; void VSMain() { - + float3(1,1,1); } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs index 391ce96c42..54c85787b3 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs @@ -11,7 +11,7 @@ namespace Stride.Shader.Parsing.AST.Shader; public abstract class ShaderToken { - public Match Match { get; set; } + public Match? Match { get; set; } public static ShaderToken GetToken(Match match) { @@ -24,6 +24,7 @@ public static ShaderToken GetToken(Match match) "ShaderProgram" => new ShaderProgram(tmp), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), + "Statement" => new Statements(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), "LogicalAndExpression" => LogicalAndExpression.Create(tmp), diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs new file mode 100644 index 0000000000..3003f884f0 --- /dev/null +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs @@ -0,0 +1,17 @@ +using Eto.Parse; +using Stride.Shader.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shader.Parsing.AST.Shader; + +public class Statements : ShaderToken +{ + public Statements(Match m) + { + Match = m; + } +} diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index c5f159efcd..69019469c4 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -24,6 +24,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser DirectiveIncrementExpression = new() { Name = "DirectiveIncrementExpression" }; public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; + public SequenceParser DirectivesMethodCall = new() { Name = "DirectivesMethodCall" }; public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; public SDSLGrammar DirectiveUsingDirectiveExpression() { @@ -50,7 +51,7 @@ public void CreateDirectiveExpressions() DirectiveTermExpression.Add( Literals, ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), - MethodCall, + DirectivesMethodCall, Parenthesis(DirectiveExpression) ); @@ -193,7 +194,7 @@ public void CreateDirectiveExpressions() var parameters = DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws); - MethodCall.Add( + DirectivesMethodCall.Add( Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("DirectiveMethodCallExpression") ); diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 2e3232fde4..d220107c7c 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -207,12 +207,14 @@ public void CreateExpressions() LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(ws) ); - var parameters = - PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws); MethodCall.Add( - Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("MethodCallExpression") + Identifier, + LeftParen, + PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws).Until(RightParen), + RightParen ); + MethodCall.Separator = ws; var arrayDeclaration = (LeftBrace & PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & RightBrace) @@ -220,6 +222,7 @@ public void CreateExpressions() PrimaryExpression.Add( arrayDeclaration, + MethodCall, ConditionalExpression ); } diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index e03a338d74..ae7839ccad 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -73,14 +73,14 @@ public void CreateStatements() Statement.Add( - Block, - ControlFlow, - ForLoop, - returnStatement.Named("Return"), - assignChain.Named("AssignChain"), - declareAssign.Named("DeclareAssign"), - assignVar.Named("Assign"), - PrimaryExpression.Then(";").SeparatedBy(ws).Named("EmptyStatement") + //Block, + //ControlFlow, + //ForLoop, + //returnStatement.Named("Return"), + //assignChain.Named("AssignChain"), + //declareAssign.Named("DeclareAssign"), + //assignVar.Named("Assign"), + PrimaryExpression.Then(Semi).SeparatedBy(ws).Named("EmptyStatement") ); Block.Add( diff --git a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs b/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs index df694bcf5f..ffed0f4efa 100644 --- a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs @@ -106,8 +106,8 @@ public string PreProcess(string code) public ShaderToken Parse(string shader) { - var code = PreProcess(shader); - ParseTree = Grammar.Match(code); + //var code = PreProcess(shader); + ParseTree = Grammar.Match(shader); if (!ParseTree.Success) throw new Exception(ParseTree.ErrorMessage); return ShaderToken.GetToken(ParseTree); diff --git a/src/Stride.Shader.Parsing/ShaderMixer.cs b/src/Stride.Shader.Parsing/ShaderMixer.cs index 3c103e7656..90e18e8ccc 100644 --- a/src/Stride.Shader.Parsing/ShaderMixer.cs +++ b/src/Stride.Shader.Parsing/ShaderMixer.cs @@ -7,13 +7,10 @@ namespace Stride.Shader.Parsing; -public class ShaderMixer : Module +public class ShaderMixer { //Dictionary List Mixins { get; set; } = new(); - public ShaderMixer(uint version) : base(version) - { - } } diff --git a/src/Stride.Shader.Parsing/SpirvEmitter.cs b/src/Stride.Shader.Parsing/SpirvEmitter.cs new file mode 100644 index 0000000000..a6adaaeca2 --- /dev/null +++ b/src/Stride.Shader.Parsing/SpirvEmitter.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shader.Parsing.AST.Shader; + +namespace Stride.Shader.Parsing; + +public class SpirvEmitter : Module +{ + public SpirvEmitter(uint version) : base(version) + { + + } +} From 73d120fba93840dc75cf790ae8f1a27298ed7857 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 29 May 2022 21:28:39 +0200 Subject: [PATCH 0099/1182] Added assign chain AST --- src/SDSLParserExample/SDSL/shader2.sdsl | 2 +- .../Frontend/AST/Shader/ShaderProgram.cs | 2 ++ .../Frontend/AST/Shader/ShaderToken.cs | 2 +- .../Frontend/AST/Shader/Statements.cs | 6 ++++-- .../SDSLGrammar/SDSLGrammar.MethodDeclaration.cs | 2 +- .../Grammars/SDSLGrammar/SDSLGrammar.Statements.cs | 14 +++++++------- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index eca27cf6d6..533f61ab34 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -5,6 +5,6 @@ shader MyShader { void VSMain() { - float3(1,1,1); + streams.a = float3(1,1,1); } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs index ff519e10f6..ff3bfd940b 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs @@ -17,6 +17,7 @@ public class ShaderMethod : ShaderToken public string Name { get; set; } public string ReturnType { get; set; } public IEnumerable ParameterList { get; set; } + public IEnumerable Statements { get; set; } public ShaderMethod(Match m) { @@ -26,6 +27,7 @@ public ShaderMethod(Match m) IsStaged = m["Stage"].Success; Name = m["MethodName"].StringValue; ReturnType = m["ReturnType"].StringValue; + Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); } } diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs index 54c85787b3..16e93d492b 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs @@ -24,7 +24,7 @@ public static ShaderToken GetToken(Match match) "ShaderProgram" => new ShaderProgram(tmp), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), - "Statement" => new Statements(tmp), + "AssignChain" => new AssignChain(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), "LogicalAndExpression" => LogicalAndExpression.Create(tmp), diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs index 3003f884f0..40dc3b49ba 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs @@ -8,9 +8,11 @@ namespace Stride.Shader.Parsing.AST.Shader; -public class Statements : ShaderToken +public class Statement : ShaderToken {} + +public class AssignChain : Statement { - public Statements(Match m) + public AssignChain(Match m) { Match = m; } diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 5ce79cde78..2b7261aa5b 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -90,7 +90,7 @@ public void CreateMethodDeclaration() Identifier.Named("ReturnType") & ws1 & Identifier.Named("MethodName"), ParameterList, LeftBrace, - Statement.Repeat(0).SeparatedBy(ws).Until("}"), + Statement.Repeat(0).SeparatedBy(ws).Until("}").Named("Statements"), RightBrace ) { Name = "Method", Separator = ws}; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index ae7839ccad..614c7f1602 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -73,13 +73,13 @@ public void CreateStatements() Statement.Add( - //Block, - //ControlFlow, - //ForLoop, - //returnStatement.Named("Return"), - //assignChain.Named("AssignChain"), - //declareAssign.Named("DeclareAssign"), - //assignVar.Named("Assign"), + Block, + ControlFlow, + ForLoop, + returnStatement.Named("Return"), + assignChain.Named("AssignChain"), + declareAssign.Named("DeclareAssign"), + assignVar.Named("Assign"), PrimaryExpression.Then(Semi).SeparatedBy(ws).Named("EmptyStatement") ); From e5c8ff86a5ebf2d03a38dc1eb368174e0b3dbef3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 30 May 2022 20:29:39 +0200 Subject: [PATCH 0100/1182] added variable creation --- src/SDSLParserExample/SDSL/shader2.sdsl | 2 +- src/Spv.Generator | 2 +- .../Frontend/AST/Shader/Operations.cs | 54 ++++++++++++------- .../Frontend/AST/Shader/OperatorToken.cs | 35 +++++++++++- .../Frontend/AST/Shader/ShaderToken.cs | 2 + .../Frontend/AST/Shader/Statements.cs | 24 +++++++++ .../SDSLGrammar/SDSLGrammar.Statements.cs | 2 +- 7 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 533f61ab34..640f76fea6 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -5,6 +5,6 @@ shader MyShader { void VSMain() { - streams.a = float3(1,1,1); + float a = float3(1,1,1); } }; \ No newline at end of file diff --git a/src/Spv.Generator b/src/Spv.Generator index 8be457e4a6..07c29410e5 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 8be457e4a6bdba371d7afc0f3be530aef1403934 +Subproject commit 07c29410e56358f71467c2ba264124505db064f3 diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs index e3547ea4a5..3ac14ed55a 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs @@ -58,7 +58,7 @@ public static MulExpression Create(Match m) var first = new MulExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -69,7 +69,7 @@ public static MulExpression Create(Match m) tmp = new MulExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -85,7 +85,7 @@ public static SumExpression Create(Match m) var first = new SumExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -96,7 +96,7 @@ public static SumExpression Create(Match m) tmp = new SumExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -112,7 +112,7 @@ public static ShiftExpression Create(Match m) var first = new ShiftExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -123,7 +123,7 @@ public static ShiftExpression Create(Match m) tmp = new ShiftExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -139,7 +139,7 @@ public static AndExpression Create(Match m) var first = new AndExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -150,7 +150,7 @@ public static AndExpression Create(Match m) tmp = new AndExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -165,7 +165,7 @@ public static XorExpression Create(Match m) var first = new XorExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -176,7 +176,7 @@ public static XorExpression Create(Match m) tmp = new XorExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -191,7 +191,7 @@ public static OrExpression Create(Match m) var first = new OrExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -202,7 +202,7 @@ public static OrExpression Create(Match m) tmp = new OrExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -218,7 +218,7 @@ public static TestExpression Create(Match m) var first = new TestExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -229,7 +229,7 @@ public static TestExpression Create(Match m) tmp = new TestExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -245,7 +245,7 @@ public static EqualsExpression Create(Match m) var first = new EqualsExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -256,7 +256,7 @@ public static EqualsExpression Create(Match m) tmp = new EqualsExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -272,7 +272,7 @@ public static LogicalAndExpression Create(Match m) var first = new LogicalAndExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -283,7 +283,7 @@ public static LogicalAndExpression Create(Match m) tmp = new LogicalAndExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -299,7 +299,7 @@ public static LogicalOrExpression Create(Match m) var first = new LogicalOrExpression { Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), + Op = m.Matches[1].StringValue.ToOperatorToken(), Left = GetToken(m.Matches[0]), Right = GetToken(m.Matches[2]) }; @@ -310,7 +310,7 @@ public static LogicalOrExpression Create(Match m) tmp = new LogicalOrExpression { Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), + Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, Right = GetToken(m.Matches[i + 1]) }; @@ -357,3 +357,17 @@ public override ShaderToken ProjectConstant() throw new Exception("Invalid condition"); } } + + +public class MethodCall : ShaderToken +{ + public string MethodName { get; set; } + public IEnumerable Parameters { get; set; } + + public MethodCall(Match m) + { + Match = m; + MethodName = m.Matches.First().StringValue; + Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).ToList(); + } +} diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs index eedf7c8647..c24bb3e324 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs @@ -6,6 +6,21 @@ namespace Stride.Shader.Parsing.AST.Shader; +public enum AssignOpToken +{ + Equal, + MulEqual, + DivEqual, + ModEqual, + PlusEqual, + MinusEqual, + LeftShiftEqual, + RightShiftEqual, + AndEqual, + OrEqual, + XorEqual +} + public enum OperatorToken { Mul, @@ -30,7 +45,7 @@ public enum OperatorToken public static class OperatorTokenExtensions { - public static OperatorToken AsOperatorToken(this string s) + public static OperatorToken ToOperatorToken(this string s) { return s switch { @@ -55,6 +70,24 @@ public static OperatorToken AsOperatorToken(this string s) _ => throw new NotImplementedException() }; } + public static AssignOpToken ToAssignOp(this string s) + { + return s switch + { + "=" => AssignOpToken.Equal, + "*=" => AssignOpToken.MulEqual, + "/=" => AssignOpToken.DivEqual, + "%=" => AssignOpToken.ModEqual, + "+=" => AssignOpToken.PlusEqual, + "-=" => AssignOpToken.MinusEqual, + "<<=" => AssignOpToken.LeftShiftEqual, + ">>=" => AssignOpToken.RightShiftEqual, + "|=" => AssignOpToken.OrEqual, + "&=" => AssignOpToken.AndEqual, + "^=" => AssignOpToken.XorEqual, + _ => throw new NotImplementedException() + }; + } private static double OperationWithCast(object a, object b, Func f) { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs index 16e93d492b..0d682c0519 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs @@ -25,6 +25,8 @@ public static ShaderToken GetToken(Match match) "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), "AssignChain" => new AssignChain(tmp), + "DeclareAssign" => new DeclareAssign(tmp), + "MethodCall" => new MethodCall(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), "LogicalAndExpression" => LogicalAndExpression.Create(tmp), diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs index 40dc3b49ba..18976c596c 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs @@ -10,10 +10,34 @@ namespace Stride.Shader.Parsing.AST.Shader; public class Statement : ShaderToken {} +public class DeclareAssign : Statement +{ + public AssignOpToken AssignOp { get; set; } + public string TypeName { get; set; } + public string VariableName { get; set; } + public ShaderToken Value { get; set; } + public DeclareAssign(Match m ) + { + Match = m; + AssignOp = m["AssignOp"].StringValue.ToAssignOp(); + TypeName = m["Type"].StringValue; + VariableName = m["Variable"].StringValue; + Value = GetToken(m["Value"]); + } +} + public class AssignChain : Statement { + public AssignOpToken AssignOp { get; set; } + public bool StreamValue { get; set; } + public IEnumerable AccessNames { get; set; } + public ShaderToken Value { get; set; } public AssignChain(Match m) { Match = m; + AssignOp = m["AssignOp"].StringValue.ToAssignOp(); + StreamValue = m.Matches.First().StringValue == "stream"; + AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); + Value = GetToken(m["PrimaryExpression"]); } } diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 614c7f1602..6aebea7076 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -59,7 +59,7 @@ public void CreateStatements() var assignChain = Identifier.Then(Dot.Then(Identifier).Repeat(0)) - .Then(AssignOperators) + .Then(AssignOperators.Named("AssignOp")) .Then(PrimaryExpression) .Then(Semi) .SeparatedBy(ws); From ccd387480981afc9e78918c35e8e7bcf190c72bb Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 30 May 2022 22:01:35 +0200 Subject: [PATCH 0101/1182] More code for shader mixin --- src/SDSLParserExample/Program.cs | 3 +- .../SDSL/InheritExample/Child.sdsl | 4 ++ .../SDSL/InheritExample/Parent.sdsl | 4 ++ src/SDSLParserExample/SDSL/shader2.sdsl | 5 ++- .../Frontend/AST/Shader/ShaderToken.cs | 8 +++- .../Frontend/AST/Shader/Statements.cs | 20 +++++++++ .../Frontend/SDSLParser.cs | 4 +- src/Stride.Shader.Parsing/ShaderMixer.cs | 23 +++++++++- src/Stride.Shader.Parsing/ShaderMixin.cs | 44 ++++++++++--------- 9 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 src/SDSLParserExample/SDSL/InheritExample/Child.sdsl create mode 100644 src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index f9d72a17fd..a51d1568a3 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -7,7 +7,8 @@ -var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); +var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); +// var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var sdsl = new SDSLParser(); //sdsl.Grammar.Using(sdsl.Grammar.CastExpression); diff --git a/src/SDSLParserExample/SDSL/InheritExample/Child.sdsl b/src/SDSLParserExample/SDSL/InheritExample/Child.sdsl new file mode 100644 index 0000000000..95c9db4840 --- /dev/null +++ b/src/SDSLParserExample/SDSL/InheritExample/Child.sdsl @@ -0,0 +1,4 @@ +shader Child : Parent +{ + stream float a; +} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl b/src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl new file mode 100644 index 0000000000..70b475b760 --- /dev/null +++ b/src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl @@ -0,0 +1,4 @@ +shader Parent +{ + stream float a; +} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 640f76fea6..8f6eda6b9c 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -5,6 +5,9 @@ shader MyShader { void VSMain() { - float a = float3(1,1,1); + { + float a = float3(1,1,1); + } + return 1; } }; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs index 0d682c0519..5c8ecf9738 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs @@ -11,12 +11,16 @@ namespace Stride.Shader.Parsing.AST.Shader; public abstract class ShaderToken { + public static string[] KeepValues = { + "Block", + "Return", + }; public Match? Match { get; set; } public static ShaderToken GetToken(Match match) { var tmp = match; - while (tmp.Matches.Count == 1) + while (tmp.Matches.Count == 1 && !KeepValues.Contains(tmp.Name)) tmp = tmp.Matches.First(); return tmp.Name switch @@ -24,6 +28,8 @@ public static ShaderToken GetToken(Match match) "ShaderProgram" => new ShaderProgram(tmp), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), + "Block" => new BlockStatement(tmp), + "Return" => new ReturnStatement(tmp), "AssignChain" => new AssignChain(tmp), "DeclareAssign" => new DeclareAssign(tmp), "MethodCall" => new MethodCall(tmp), diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs index 18976c596c..28caadd03d 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs +++ b/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs @@ -41,3 +41,23 @@ public AssignChain(Match m) Value = GetToken(m["PrimaryExpression"]); } } + +public class ReturnStatement : Statement +{ + public ShaderToken ReturnValue {get;set;} + public ReturnStatement(Match m) + { + Match = m; + ReturnValue = GetToken(m["PrimaryExpression"]); + } +} + +public class BlockStatement : Statement +{ + public IEnumerable Statements {get;set;} + public BlockStatement(Match m) + { + Match = m; + Statements = m.Matches.Select(GetToken).ToList(); + } +} diff --git a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs b/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs index ffed0f4efa..df694bcf5f 100644 --- a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs +++ b/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs @@ -106,8 +106,8 @@ public string PreProcess(string code) public ShaderToken Parse(string shader) { - //var code = PreProcess(shader); - ParseTree = Grammar.Match(shader); + var code = PreProcess(shader); + ParseTree = Grammar.Match(code); if (!ParseTree.Success) throw new Exception(ParseTree.ErrorMessage); return ShaderToken.GetToken(ParseTree); diff --git a/src/Stride.Shader.Parsing/ShaderMixer.cs b/src/Stride.Shader.Parsing/ShaderMixer.cs index 90e18e8ccc..183a808bc6 100644 --- a/src/Stride.Shader.Parsing/ShaderMixer.cs +++ b/src/Stride.Shader.Parsing/ShaderMixer.cs @@ -10,7 +10,28 @@ namespace Stride.Shader.Parsing; public class ShaderMixer { //Dictionary - List Mixins { get; set; } = new(); + public SDSLParser Parser {get;set;} + public List Mixins { get; set; } = new(); + + public ShaderMixer() + { + Parser = new(); + } + public ShaderMixer(SDSLParser parser) + { + Parser = parser; + } + + public void Add(string mixin) + { + Mixins.Add(new ShaderMixin(mixin,Parser)); + } + + public void AddMacros(string name, object value) + { + Parser.AddMacro(name, value); + } + } diff --git a/src/Stride.Shader.Parsing/ShaderMixin.cs b/src/Stride.Shader.Parsing/ShaderMixin.cs index 854c5c94cc..8cfd51afc0 100644 --- a/src/Stride.Shader.Parsing/ShaderMixin.cs +++ b/src/Stride.Shader.Parsing/ShaderMixin.cs @@ -12,19 +12,21 @@ public class ShaderMixin public string Code { get; set; } public string MixinName { get => AST != null ? AST.Name : string.Empty; } public ShaderProgram? AST { get; set; } - Eto.Parse.Grammar EntryPointMatcher = new Eto.Parse.Grammar( - Eto.Parse.Terminals.Literal("PSMain") - | "VSMain" - | "GSMain" - | "HSMain" - | "DSMain" - | "CSMain"); + string[] EntryPointNames = { + "PSMain", + "VSMain", + "GSMain", + "HSMain", + "DSMain", + "CSMain" + }; - SDSLParser Parser { get; set; } = new(); + SDSLParser Parser { get; set; } - public ShaderMixin(string code) + public ShaderMixin(string code, SDSLParser parser) { Code = code; + Parser = parser; } public void Parse() @@ -36,10 +38,10 @@ public IEnumerable GetStreamValues() { if (AST is not null) return - AST.Body - .Where(x => x is ShaderValueDeclaration) - .Cast() - .Where(x => x.IsStream); + from e in AST.Body + where e is ShaderValueDeclaration v + && v.IsStream + select e as ShaderValueDeclaration; else throw new Exception("AST is null"); } @@ -47,10 +49,10 @@ public IEnumerable GetEntryPoints() { if (AST is not null) return - AST.Body - .Where(x => x is ShaderMethod) - .Cast() - .Where(x => EntryPointMatcher.Match(x.Name).Success); + from e in AST.Body + where e is ShaderMethod method + && EntryPointNames.Contains(method.Name) + select e as ShaderMethod; else throw new Exception("AST is null"); } @@ -58,10 +60,10 @@ public IEnumerable GetMethods() { if (AST is not null) return - AST.Body - .Where(x => x is ShaderMethod) - .Cast() - .Where(x => !EntryPointMatcher.Match(x.Name).Success); + from e in AST.Body + where e is ShaderMethod method + && !EntryPointNames.Contains(method.Name) + select e as ShaderMethod; else throw new Exception("AST is null"); } From 9b0ebdcbebc9a7d47e6e7cfe0996237e39420f3e Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 31 May 2022 13:24:08 +0200 Subject: [PATCH 0102/1182] project renaming --- SDSLParser.sln | 4 +- src/SDSLParserExample/Program.cs | 11 +-- .../SDSLParserExample.csproj | 2 +- .../BasicExpressionParsing.cs | 4 +- .../OperationExpressionParsing.cs | 4 +- .../Stride.Shaders.Test.csproj} | 2 +- .../Backend/ThreeAddressElement.cs | 2 +- .../DirectivePreprocessor.cs | 10 +-- .../Frontend/AST/Directives/DirectiveToken.cs | 4 +- .../Frontend/AST/Directives/Directives.cs | 2 +- .../Frontend/AST/Directives/Literals.cs | 2 +- .../Frontend/AST/Directives/Operations.cs | 6 +- .../Frontend/AST/Directives/OperatorToken.cs | 2 +- .../Frontend/AST/Directives/UnaryLiterals.cs | 2 +- .../Frontend/AST/Shader/Literals.cs | 2 +- .../Frontend/AST/Shader/Operations.cs | 6 +- .../Frontend/AST/Shader/OperatorToken.cs | 2 +- .../Frontend/AST/Shader/ShaderProgram.cs | 2 +- .../Frontend/AST/Shader/ShaderToken.cs | 4 +- .../Frontend/AST/Shader/Statements.cs | 4 +- .../Frontend/AST/Shader/UnaryLiterals.cs | 2 +- .../Frontend/ExpressionParser.cs | 14 ++-- .../Frontend/Grammars/CommentGrammar.cs | 2 +- .../DirectiveGrammar.Directives.Expression.cs | 2 +- .../DirectiveGrammar.Directives.cs | 2 +- .../DirectiveGrammar.Tokens.cs | 2 +- .../DirectiveGrammar/DirectiveGrammar.cs | 2 +- .../DirectiveGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.TokenGroups.cs | 2 +- .../Frontend/Grammars/ExpressionGrammar.cs | 4 +- .../Frontend/Grammars/MacroGrammar.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 2 +- .../SDSLGrammar.Directives.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Directives.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.MethodDeclaration.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- ...ar.Statements.ConditionalFlowStatements.cs | 2 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 2 +- .../Grammars/SDSLGrammar/SDSLGrammar.cs | 2 +- .../Frontend/SDSLParser.cs | 26 ++----- src/Stride.Shaders/ShaderClassCode.cs | 2 + .../ShaderMixer.cs | 10 +-- .../ShaderMixin.cs | 4 +- src/Stride.Shaders/ShaderSourceString.cs | 72 +++++++++++++++++++ .../SpirvEmitter.cs | 4 +- .../Stride.Shaders.csproj} | 0 51 files changed, 157 insertions(+), 100 deletions(-) rename src/{Stride.Shader.Parsing.Test => Stride.Shaders.Test}/BasicExpressionParsing.cs (97%) rename src/{Stride.Shader.Parsing.Test => Stride.Shaders.Test}/OperationExpressionParsing.cs (99%) rename src/{Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj => Stride.Shaders.Test/Stride.Shaders.Test.csproj} (91%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Backend/ThreeAddressElement.cs (94%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/DirectivePreprocessor.cs (90%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/DirectiveToken.cs (97%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/Directives.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/Literals.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/Operations.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/OperatorToken.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Directives/UnaryLiterals.cs (97%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/Literals.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/Operations.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/OperatorToken.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/ShaderProgram.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/ShaderToken.cs (96%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/Statements.cs (95%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/AST/Shader/UnaryLiterals.cs (97%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/ExpressionParser.cs (60%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/CommentGrammar.cs (93%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs (87%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs (97%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs (96%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/ExpressionGrammar.cs (68%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/MacroGrammar.cs (91%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs (97%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (95%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (96%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs (98%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs (99%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs (93%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/Frontend/SDSLParser.cs (83%) create mode 100644 src/Stride.Shaders/ShaderClassCode.cs rename src/{Stride.Shader.Parsing => Stride.Shaders}/ShaderMixer.cs (78%) rename src/{Stride.Shader.Parsing => Stride.Shaders}/ShaderMixin.cs (95%) create mode 100644 src/Stride.Shaders/ShaderSourceString.cs rename src/{Stride.Shader.Parsing => Stride.Shaders}/SpirvEmitter.cs (76%) rename src/{Stride.Shader.Parsing/Stride.Shader.Parsing.csproj => Stride.Shaders/Stride.Shaders.csproj} (100%) diff --git a/SDSLParser.sln b/SDSLParser.sln index 9fdc69e21c..1265f607eb 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -7,9 +7,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B76 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shader.Parsing", "src\Stride.Shader.Parsing\Stride.Shader.Parsing.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "src\Stride.Shaders\Stride.Shaders.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shader.Parsing.Test", "src\Stride.Shader.Parsing.Test\Stride.Shader.Parsing.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Test", "src\Stride.Shaders.Test\Stride.Shaders.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "src\CppNet\CppNet.csproj", "{C2FD9262-69F8-4B75-9AB1-FF359C9143E9}" EndProject diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index a51d1568a3..3c598ef9f6 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -1,13 +1,16 @@ using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shader.Parsing; -using Stride.Shader.Parsing.Grammars.Expression; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Grammars.Expression; using System.Diagnostics; using System.Linq; var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); +var child = File.ReadAllText("./SDSL/InheritExample/Child.sdsl"); +var parent = File.ReadAllText("./SDSL/InheritExample/Parent.sdsl"); + // var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); var sdsl = new SDSLParser(); @@ -15,14 +18,14 @@ var s = new Stopwatch(); var parser = new ExpressionParser(); var match2 = sdsl.Parse(shaderf); -sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", 5); +// sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", 5); s.Start(); var match = sdsl.Parse(shaderf); s.Stop(); -sdsl.PrintParserTree(); +// sdsl.PrintParserTree(); Console.WriteLine(shaderf); Console.WriteLine(new string('*', 64)); diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj index 04accbf910..235b3a8e38 100644 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -2,7 +2,7 @@ - + diff --git a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs b/src/Stride.Shaders.Test/BasicExpressionParsing.cs similarity index 97% rename from src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs rename to src/Stride.Shaders.Test/BasicExpressionParsing.cs index 50cce9b0b2..453b240807 100644 --- a/src/Stride.Shader.Parsing.Test/BasicExpressionParsing.cs +++ b/src/Stride.Shaders.Test/BasicExpressionParsing.cs @@ -1,11 +1,11 @@ using Xunit; using System.Linq; -using Stride.Shader.Parsing; +using Stride.Shaders.Parsing; using Eto.Parse; using Eto.Parse.Parsers; using System.Collections.Generic; -namespace Stride.Shader.Parsing.Test; +namespace Stride.Shaders.Parsing.Test; public class BasicExpressionParsing { diff --git a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs b/src/Stride.Shaders.Test/OperationExpressionParsing.cs similarity index 99% rename from src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs rename to src/Stride.Shaders.Test/OperationExpressionParsing.cs index 5afffd44e8..f3ce4974a8 100644 --- a/src/Stride.Shader.Parsing.Test/OperationExpressionParsing.cs +++ b/src/Stride.Shaders.Test/OperationExpressionParsing.cs @@ -1,11 +1,11 @@ using Xunit; using System.Linq; -using Stride.Shader.Parsing; +using Stride.Shaders.Parsing; using Eto.Parse; using Eto.Parse.Parsers; using System.Collections.Generic; -namespace Stride.Shader.Parsing.Test; +namespace Stride.Shaders.Parsing.Test; public class OperationExpressionParsing { diff --git a/src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj b/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj similarity index 91% rename from src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj rename to src/Stride.Shaders.Test/Stride.Shaders.Test.csproj index 0c92e1b4f4..ab4c79d248 100644 --- a/src/Stride.Shader.Parsing.Test/Stride.Shader.Parsing.Test.csproj +++ b/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs b/src/Stride.Shaders/Backend/ThreeAddressElement.cs similarity index 94% rename from src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs rename to src/Stride.Shaders/Backend/ThreeAddressElement.cs index 8bfdad93f9..ad056f2cd8 100644 --- a/src/Stride.Shader.Parsing/Backend/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Backend/ThreeAddressElement.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.Backend; +namespace Stride.Shaders.Parsing.Backend; public enum Operators diff --git a/src/Stride.Shader.Parsing/DirectivePreprocessor.cs b/src/Stride.Shaders/DirectivePreprocessor.cs similarity index 90% rename from src/Stride.Shader.Parsing/DirectivePreprocessor.cs rename to src/Stride.Shaders/DirectivePreprocessor.cs index e6added42b..af7eac1a78 100644 --- a/src/Stride.Shader.Parsing/DirectivePreprocessor.cs +++ b/src/Stride.Shaders/DirectivePreprocessor.cs @@ -1,14 +1,14 @@ -using Stride.Shader.Parsing.AST.Directives; -using Stride.Shader.Parsing.Grammars.Comments; -using Stride.Shader.Parsing.Grammars.Directive; -using Stride.Shader.Parsing.Grammars.Macros; +using Stride.Shaders.Parsing.AST.Directives; +using Stride.Shaders.Parsing.Grammars.Comments; +using Stride.Shaders.Parsing.Grammars.Directive; +using Stride.Shaders.Parsing.Grammars.Macros; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; public class DirectivePreprocessor { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/DirectiveToken.cs b/src/Stride.Shaders/Frontend/AST/Directives/DirectiveToken.cs similarity index 97% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/DirectiveToken.cs rename to src/Stride.Shaders/Frontend/AST/Directives/DirectiveToken.cs index e8d9444736..31895472b4 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/DirectiveToken.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/DirectiveToken.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shader.Parsing.Grammars.Expression; +using Stride.Shaders.Parsing.Grammars.Expression; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public abstract class DirectiveToken diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Directives.cs b/src/Stride.Shaders/Frontend/AST/Directives/Directives.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/Directives.cs rename to src/Stride.Shaders/Frontend/AST/Directives/Directives.cs index 488a9824c1..c4d3087c3c 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Directives.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/Directives.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public class DirectiveFlow : DirectiveToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Literals.cs b/src/Stride.Shaders/Frontend/AST/Directives/Literals.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/Literals.cs rename to src/Stride.Shaders/Frontend/AST/Directives/Literals.cs index f4c689e917..ebaa6bb12f 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Literals.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/Literals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public class DirectiveLiteral : DirectiveToken diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Operations.cs b/src/Stride.Shaders/Frontend/AST/Directives/Operations.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/Operations.cs rename to src/Stride.Shaders/Frontend/AST/Directives/Operations.cs index 72ff916e0c..db69db3e3c 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/Operations.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/Operations.cs @@ -1,13 +1,13 @@ using Eto.Parse; -using Stride.Shader.Parsing.AST.Directives; +using Stride.Shaders.Parsing.AST.Directives; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shader.Parsing.AST.Directives.OperatorTokenExtensions; +using static Stride.Shaders.Parsing.AST.Directives.OperatorTokenExtensions; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public abstract class Projector : DirectiveToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/OperatorToken.cs b/src/Stride.Shaders/Frontend/AST/Directives/OperatorToken.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/OperatorToken.cs rename to src/Stride.Shaders/Frontend/AST/Directives/OperatorToken.cs index beb5cd283f..def69e0ae0 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/OperatorToken.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/OperatorToken.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public enum OperatorToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Directives/UnaryLiterals.cs b/src/Stride.Shaders/Frontend/AST/Directives/UnaryLiterals.cs similarity index 97% rename from src/Stride.Shader.Parsing/Frontend/AST/Directives/UnaryLiterals.cs rename to src/Stride.Shaders/Frontend/AST/Directives/UnaryLiterals.cs index 8c00022ab9..2a252337eb 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Directives/UnaryLiterals.cs +++ b/src/Stride.Shaders/Frontend/AST/Directives/UnaryLiterals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Directives; +namespace Stride.Shaders.Parsing.AST.Directives; public class UnaryExpression : DirectiveToken diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Literals.cs b/src/Stride.Shaders/Frontend/AST/Shader/Literals.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/Literals.cs rename to src/Stride.Shaders/Frontend/AST/Shader/Literals.cs index d5194d15a8..4d78546d95 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/Literals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderLiteral : Projector diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs b/src/Stride.Shaders/Frontend/AST/Shader/Operations.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs rename to src/Stride.Shaders/Frontend/AST/Shader/Operations.cs index 3ac14ed55a..6ef9b9f864 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/Operations.cs @@ -1,13 +1,13 @@ using Eto.Parse; -using Stride.Shader.Parsing.AST.Directives; +using Stride.Shaders.Parsing.AST.Directives; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shader.Parsing.AST.Shader.OperatorTokenExtensions; +using static Stride.Shaders.Parsing.AST.Shader.OperatorTokenExtensions; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Projector : ShaderToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs b/src/Stride.Shaders/Frontend/AST/Shader/OperatorToken.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs rename to src/Stride.Shaders/Frontend/AST/Shader/OperatorToken.cs index c24bb3e324..6083ebe3df 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/OperatorToken.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/OperatorToken.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public enum AssignOpToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Frontend/AST/Shader/ShaderProgram.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs rename to src/Stride.Shaders/Frontend/AST/Shader/ShaderProgram.cs index ff3bfd940b..1929fe29b6 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/ShaderProgram.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderMethod : ShaderToken { diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Frontend/AST/Shader/ShaderToken.cs similarity index 96% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs rename to src/Stride.Shaders/Frontend/AST/Shader/ShaderToken.cs index 5c8ecf9738..90d9afcd3c 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/ShaderToken.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shader.Parsing.Grammars.Expression; +using Stride.Shaders.Parsing.Grammars.Expression; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public abstract class ShaderToken diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs b/src/Stride.Shaders/Frontend/AST/Shader/Statements.cs similarity index 95% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs rename to src/Stride.Shaders/Frontend/AST/Shader/Statements.cs index 28caadd03d..55bf0045a0 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/Statements.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shader.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public class Statement : ShaderToken {} diff --git a/src/Stride.Shader.Parsing/Frontend/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Frontend/AST/Shader/UnaryLiterals.cs similarity index 97% rename from src/Stride.Shader.Parsing/Frontend/AST/Shader/UnaryLiterals.cs rename to src/Stride.Shaders/Frontend/AST/Shader/UnaryLiterals.cs index d9360da96c..129823dae5 100644 --- a/src/Stride.Shader.Parsing/Frontend/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Frontend/AST/Shader/UnaryLiterals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing.AST.Shader; +namespace Stride.Shaders.Parsing.AST.Shader; public class UnaryExpression : Projector diff --git a/src/Stride.Shader.Parsing/Frontend/ExpressionParser.cs b/src/Stride.Shaders/Frontend/ExpressionParser.cs similarity index 60% rename from src/Stride.Shader.Parsing/Frontend/ExpressionParser.cs rename to src/Stride.Shaders/Frontend/ExpressionParser.cs index 4f468af4fc..4564ad610c 100644 --- a/src/Stride.Shader.Parsing/Frontend/ExpressionParser.cs +++ b/src/Stride.Shaders/Frontend/ExpressionParser.cs @@ -1,13 +1,13 @@ -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shader.Parsing.AST.Shader; -using Stride.Shader.Parsing.Grammars; -using Stride.Shader.Parsing.Grammars.Comments; -using Stride.Shader.Parsing.Grammars.Directive; -using Stride.Shader.Parsing.Grammars.Expression; -using Stride.Shader.Parsing.Grammars.SDSL; +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.Grammars; +using Stride.Shaders.Parsing.Grammars.Comments; +using Stride.Shaders.Parsing.Grammars.Directive; +using Stride.Shaders.Parsing.Grammars.Expression; +using Stride.Shaders.Parsing.Grammars.SDSL; using System.Text; public class ExpressionParser { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/CommentGrammar.cs b/src/Stride.Shaders/Frontend/Grammars/CommentGrammar.cs similarity index 93% rename from src/Stride.Shader.Parsing/Frontend/Grammars/CommentGrammar.cs rename to src/Stride.Shaders/Frontend/Grammars/CommentGrammar.cs index e656396f5c..dc50dde5eb 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/CommentGrammar.cs +++ b/src/Stride.Shaders/Frontend/Grammars/CommentGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Comments; +namespace Stride.Shaders.Parsing.Grammars.Comments; public class CommentGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs index d73aa27370..6cb3b98a2d 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index a5b1f727ae..07916cf6b2 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public SequenceParser IfDirective = new(){Name = "IfDirective"}; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs index f509a1e7bd..3298dec9e3 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs @@ -1,7 +1,7 @@ using Eto.Parse; using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs similarity index 87% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs index 13682d675b..904e5d1b08 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 97% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs index d6a6852e82..f851ca6ba1 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { AlternativeParser IntegerSuffix = new(); diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs similarity index 96% rename from src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs index 414c8bacfa..eee7e85528 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Directive; +namespace Stride.Shaders.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public AlternativeParser IncOperators = new(); diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/ExpressionGrammar.cs b/src/Stride.Shaders/Frontend/Grammars/ExpressionGrammar.cs similarity index 68% rename from src/Stride.Shader.Parsing/Frontend/Grammars/ExpressionGrammar.cs rename to src/Stride.Shaders/Frontend/Grammars/ExpressionGrammar.cs index d19bd0b960..8886514473 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/ExpressionGrammar.cs +++ b/src/Stride.Shaders/Frontend/Grammars/ExpressionGrammar.cs @@ -1,10 +1,10 @@ using Eto.Parse; using Eto.Parse.Parsers; -using Stride.Shader.Parsing.Grammars.SDSL; +using Stride.Shaders.Parsing.Grammars.SDSL; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Expression; +namespace Stride.Shaders.Parsing.Grammars.Expression; public class ExpressionGrammar : SDSLGrammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/MacroGrammar.cs b/src/Stride.Shaders/Frontend/Grammars/MacroGrammar.cs similarity index 91% rename from src/Stride.Shader.Parsing/Frontend/Grammars/MacroGrammar.cs rename to src/Stride.Shaders/Frontend/Grammars/MacroGrammar.cs index 1d1d637194..cb17333f29 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/MacroGrammar.cs +++ b/src/Stride.Shaders/Frontend/Grammars/MacroGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.Macros; +namespace Stride.Shaders.Parsing.Grammars.Macros; public class MacroGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index 2844de5ad3..5f90ed3d33 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ShaderValueDeclaration = new() { Name = "ShaderValueDeclaration" }; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 69019469c4..2b43890046 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs index 674446feae..01c87bfa04 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser IfDirective = new(); diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index d220107c7c..ed5cc03ac8 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(){Name = "TermExpression"}; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 97% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index e871c7b466..d1f056b827 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { AlternativeParser IntegerSuffix = new() { Name = "Suffix"}; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 2b7261aa5b..e560cc1ebe 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ParameterList = new() {Name = "ParameterList"}; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 82e4e6eaf4..a52795f10e 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 95% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs index 22c099da8d..17647af14d 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ControlFlow = new() { Name = "ControlFlow" }; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 96% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index 60cb2b3150..109fcbf1cd 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 6aebea7076..08d976e58f 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser Attribute = new() { Name = "Attribute" }; diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 98% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 039e122afe..078d496cf2 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 99% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index 3d5c40f41e..01e951db7f 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 93% rename from src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs index 3634ab8aac..3030c5c364 100644 --- a/src/Stride.Shader.Parsing/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shader.Parsing.Grammars.SDSL; +namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SDSLGrammar() : base("sdsl") diff --git a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs b/src/Stride.Shaders/Frontend/SDSLParser.cs similarity index 83% rename from src/Stride.Shader.Parsing/Frontend/SDSLParser.cs rename to src/Stride.Shaders/Frontend/SDSLParser.cs index df694bcf5f..b705e11673 100644 --- a/src/Stride.Shader.Parsing/Frontend/SDSLParser.cs +++ b/src/Stride.Shaders/Frontend/SDSLParser.cs @@ -1,13 +1,13 @@ -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shader.Parsing.AST.Directives; -using Stride.Shader.Parsing.AST.Shader; -using Stride.Shader.Parsing.Grammars; -using Stride.Shader.Parsing.Grammars.Comments; -using Stride.Shader.Parsing.Grammars.Directive; -using Stride.Shader.Parsing.Grammars.SDSL; +using Stride.Shaders.Parsing.AST.Directives; +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.Grammars; +using Stride.Shaders.Parsing.Grammars.Comments; +using Stride.Shaders.Parsing.Grammars.Directive; +using Stride.Shaders.Parsing.Grammars.SDSL; using System.Text; using CppNet; @@ -17,7 +17,6 @@ public class SDSLParser public SDSLGrammar Grammar {get;set;} public DirectivePreprocessor DPreprocessor { get; set; } public Preprocessor Preprocessor { get; set; } - public Dictionary Macros { get; set; } = new(); public GrammarMatch? ParseTree { get; set; } @@ -51,17 +50,6 @@ public GrammarMatch TestParse(string code) return Grammar.Match(code); } - public void AddMacro(string name, object value) - { - Preprocessor.addMacro(name, value.ToString()); - DPreprocessor.Macros.Add(name, value); - } - public void AddMacro(string name) - { - Preprocessor.addMacro(name, string.Empty); - DPreprocessor.Macros.Add(name, string.Empty); - } - public string DPreProcess(string code) { return DPreprocessor.PreProcess(code); diff --git a/src/Stride.Shaders/ShaderClassCode.cs b/src/Stride.Shaders/ShaderClassCode.cs new file mode 100644 index 0000000000..83210aa55f --- /dev/null +++ b/src/Stride.Shaders/ShaderClassCode.cs @@ -0,0 +1,2 @@ + +namespace Stride.Shaders.Parsing; \ No newline at end of file diff --git a/src/Stride.Shader.Parsing/ShaderMixer.cs b/src/Stride.Shaders/ShaderMixer.cs similarity index 78% rename from src/Stride.Shader.Parsing/ShaderMixer.cs rename to src/Stride.Shaders/ShaderMixer.cs index 183a808bc6..31bd0762d1 100644 --- a/src/Stride.Shader.Parsing/ShaderMixer.cs +++ b/src/Stride.Shaders/ShaderMixer.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using Spv.Generator; -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; public class ShaderMixer { @@ -26,12 +26,4 @@ public void Add(string mixin) { Mixins.Add(new ShaderMixin(mixin,Parser)); } - - public void AddMacros(string name, object value) - { - Parser.AddMacro(name, value); - } - - - } diff --git a/src/Stride.Shader.Parsing/ShaderMixin.cs b/src/Stride.Shaders/ShaderMixin.cs similarity index 95% rename from src/Stride.Shader.Parsing/ShaderMixin.cs rename to src/Stride.Shaders/ShaderMixin.cs index 8cfd51afc0..0a72bf4145 100644 --- a/src/Stride.Shader.Parsing/ShaderMixin.cs +++ b/src/Stride.Shaders/ShaderMixin.cs @@ -1,11 +1,11 @@ -using Stride.Shader.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; public class ShaderMixin { diff --git a/src/Stride.Shaders/ShaderSourceString.cs b/src/Stride.Shaders/ShaderSourceString.cs new file mode 100644 index 0000000000..6fd60b448a --- /dev/null +++ b/src/Stride.Shaders/ShaderSourceString.cs @@ -0,0 +1,72 @@ +using Stride.Shaders.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Parsing; + +public class ShaderSourceString +{ + public string Code { get; set; } + public string ClassName { get => AST != null ? AST.Name : string.Empty; } + public ShaderProgram? AST { get; set; } + string[] EntryPointNames = { + "PSMain", + "VSMain", + "GSMain", + "HSMain", + "DSMain", + "CSMain" + }; + + SDSLParser Parser { get; set; } + + public ShaderSourceString(string code, SDSLParser parser) + { + Code = code; + Parser = parser; + } + + public void Parse() + { + AST = (ShaderProgram)Parser.Parse(Code); + } + + public IEnumerable GetStreamValues() + { + if (AST is not null) + return + from e in AST.Body + where e is ShaderValueDeclaration v + && v.IsStream + select e as ShaderValueDeclaration; + else + throw new Exception("AST is null"); + } + public IEnumerable GetEntryPoints() + { + if (AST is not null) + return + from e in AST.Body + where e is ShaderMethod method + && EntryPointNames.Contains(method.Name) + select e as ShaderMethod; + else + throw new Exception("AST is null"); + } + public IEnumerable GetMethods() + { + if (AST is not null) + return + from e in AST.Body + where e is ShaderMethod method + && !EntryPointNames.Contains(method.Name) + select e as ShaderMethod; + else + throw new Exception("AST is null"); + } + + +} diff --git a/src/Stride.Shader.Parsing/SpirvEmitter.cs b/src/Stride.Shaders/SpirvEmitter.cs similarity index 76% rename from src/Stride.Shader.Parsing/SpirvEmitter.cs rename to src/Stride.Shaders/SpirvEmitter.cs index a6adaaeca2..bf95b8c4bd 100644 --- a/src/Stride.Shader.Parsing/SpirvEmitter.cs +++ b/src/Stride.Shaders/SpirvEmitter.cs @@ -4,9 +4,9 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shader.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader; -namespace Stride.Shader.Parsing; +namespace Stride.Shaders.Parsing; public class SpirvEmitter : Module { diff --git a/src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj b/src/Stride.Shaders/Stride.Shaders.csproj similarity index 100% rename from src/Stride.Shader.Parsing/Stride.Shader.Parsing.csproj rename to src/Stride.Shaders/Stride.Shaders.csproj From 2e3b1a5c90d98aa8cb942ea9b7a24a2188fb4425 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 31 May 2022 15:36:46 +0200 Subject: [PATCH 0103/1182] Folders Rename --- src/SDSLParserExample/Program.cs | 18 ++- .../SDSLParserExample.csproj | 7 ++ .../BasicExpressionParsing.cs | 2 +- .../OperationExpressionParsing.cs | 2 +- .../Stride.Shaders.Test.csproj | 2 +- .../{ => Compiler}/SpirvEmitter.cs | 2 +- .../ThreeAddressElement.cs | 0 .../AST/Directives/DirectiveToken.cs | 0 .../AST/Directives/Directives.cs | 0 .../AST/Directives/Literals.cs | 0 .../AST/Directives/Operations.cs | 0 .../AST/Directives/OperatorToken.cs | 0 .../AST/Directives/UnaryLiterals.cs | 0 .../AST/Shader/Literals.cs | 0 .../AST/Shader/Operations.cs | 0 .../AST/Shader/OperatorToken.cs | 0 .../AST/Shader/ShaderProgram.cs | 0 .../AST/Shader/ShaderToken.cs | 0 .../AST/Shader/Statements.cs | 0 .../AST/Shader/UnaryLiterals.cs | 0 .../{ => Parsers}/DirectivePreprocessor.cs | 0 .../{Frontend => Parsers}/ExpressionParser.cs | 0 .../Grammars/CommentGrammar.cs | 0 .../DirectiveGrammar.Directives.Expression.cs | 0 .../DirectiveGrammar.Directives.cs | 0 .../DirectiveGrammar.Tokens.cs | 0 .../DirectiveGrammar/DirectiveGrammar.cs | 0 .../DirectiveGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.TokenGroups.cs | 0 .../Grammars/ExpressionGrammar.cs | 0 .../Grammars/MacroGrammar.cs | 0 .../SDSLGrammar/SDSLGrammar.Declaration.cs | 0 .../SDSLGrammar.Directives.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Directives.cs | 0 .../SDSLGrammar/SDSLGrammar.Expression.cs | 0 .../SDSLGrammar/SDSLGrammar.Literals.cs | 0 .../SDSLGrammar.MethodDeclaration.cs | 0 .../SDSLGrammar/SDSLGrammar.Shader.cs | 40 +++++-- ...ar.Statements.ConditionalFlowStatements.cs | 0 ...SLGrammar.Statements.LoopFlowStatements.cs | 0 .../SDSLGrammar/SDSLGrammar.Statements.cs | 0 .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 0 .../SDSLGrammar/SDSLGrammar.Tokens.cs | 0 .../Grammars/SDSLGrammar/SDSLGrammar.cs | 2 +- .../ShaderMixinParser.cs} | 8 +- src/Stride.Shaders/ShaderClassCode.cs | 34 +++++- src/Stride.Shaders/ShaderClassSource.cs | 108 ++++++++++++++++++ src/Stride.Shaders/ShaderMixer.cs | 25 +++- src/Stride.Shaders/ShaderMixin.cs | 9 +- src/Stride.Shaders/ShaderSource.cs | 11 ++ src/Stride.Shaders/ShaderSourceString.cs | 7 +- 51 files changed, 242 insertions(+), 35 deletions(-) rename src/Stride.Shaders/{ => Compiler}/SpirvEmitter.cs (89%) rename src/Stride.Shaders/{Backend => Compiler}/ThreeAddressElement.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/DirectiveToken.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/Directives.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/Literals.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/Operations.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/OperatorToken.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Directives/UnaryLiterals.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/Literals.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/Operations.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/OperatorToken.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/ShaderProgram.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/ShaderToken.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/Statements.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/AST/Shader/UnaryLiterals.cs (100%) rename src/Stride.Shaders/{ => Parsers}/DirectivePreprocessor.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/ExpressionParser.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/CommentGrammar.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/DirectiveGrammar.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/ExpressionGrammar.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/MacroGrammar.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs (75%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs (100%) rename src/Stride.Shaders/{Frontend => Parsers}/Grammars/SDSLGrammar/SDSLGrammar.cs (95%) rename src/Stride.Shaders/{Frontend/SDSLParser.cs => Parsers/ShaderMixinParser.cs} (95%) create mode 100644 src/Stride.Shaders/ShaderClassSource.cs create mode 100644 src/Stride.Shaders/ShaderSource.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3c598ef9f6..516d66f2d6 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -4,16 +4,18 @@ using Stride.Shaders.Parsing.Grammars.Expression; using System.Diagnostics; using System.Linq; +using Stride.Core.Shaders.Grammar; +using Stride.Core.Shaders; +using Stride.Core.Shaders.Parser; +using Stride.Core.Shaders.Grammar.Stride; - - -var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); +var shaderf = File.ReadAllText("./SDSL/shader.sdsl"); var child = File.ReadAllText("./SDSL/InheritExample/Child.sdsl"); var parent = File.ReadAllText("./SDSL/InheritExample/Parent.sdsl"); // var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); -var sdsl = new SDSLParser(); +var sdsl = new Stride.Shaders.Parsing.ShaderMixinParser(); //sdsl.Grammar.Using(sdsl.Grammar.CastExpression); var s = new Stopwatch(); var parser = new ExpressionParser(); @@ -32,5 +34,13 @@ Console.WriteLine(match); Console.WriteLine($"parsing time : {s.Elapsed}"); +var grammar = ShaderParser.GetGrammar(); + +var p = ShaderParser.GetParser(); +p.Parse(shaderf,"./SDSL/shader2.sdsl"); +s.Start(); +var result = p.Parse(shaderf,"./SDSL/shader2.sdsl"); +s.Stop(); +Console.WriteLine($"irony parsing time : {s.Elapsed}"); diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj index 235b3a8e38..b14a54141e 100644 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -5,6 +5,13 @@ + + + + + + + Exe net6.0 diff --git a/src/Stride.Shaders.Test/BasicExpressionParsing.cs b/src/Stride.Shaders.Test/BasicExpressionParsing.cs index 453b240807..108cde0b52 100644 --- a/src/Stride.Shaders.Test/BasicExpressionParsing.cs +++ b/src/Stride.Shaders.Test/BasicExpressionParsing.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Parsing.Test; public class BasicExpressionParsing { - SDSLParser parser; + ShaderMixinParser parser; public BasicExpressionParsing() { parser = new(); diff --git a/src/Stride.Shaders.Test/OperationExpressionParsing.cs b/src/Stride.Shaders.Test/OperationExpressionParsing.cs index f3ce4974a8..619f82f995 100644 --- a/src/Stride.Shaders.Test/OperationExpressionParsing.cs +++ b/src/Stride.Shaders.Test/OperationExpressionParsing.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Parsing.Test; public class OperationExpressionParsing { - SDSLParser parser; + ShaderMixinParser parser; public OperationExpressionParsing() { parser = new(); diff --git a/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj b/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj index ab4c79d248..521754b0dd 100644 --- a/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj +++ b/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/Stride.Shaders/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/SpirvEmitter.cs similarity index 89% rename from src/Stride.Shaders/SpirvEmitter.cs rename to src/Stride.Shaders/Compiler/SpirvEmitter.cs index bf95b8c4bd..1711b2cec5 100644 --- a/src/Stride.Shaders/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/SpirvEmitter.cs @@ -6,7 +6,7 @@ using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; -namespace Stride.Shaders.Parsing; +namespace Stride.Shaders; public class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Backend/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/ThreeAddressElement.cs similarity index 100% rename from src/Stride.Shaders/Backend/ThreeAddressElement.cs rename to src/Stride.Shaders/Compiler/ThreeAddressElement.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/DirectiveToken.cs b/src/Stride.Shaders/Parsers/AST/Directives/DirectiveToken.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/DirectiveToken.cs rename to src/Stride.Shaders/Parsers/AST/Directives/DirectiveToken.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/Directives.cs b/src/Stride.Shaders/Parsers/AST/Directives/Directives.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/Directives.cs rename to src/Stride.Shaders/Parsers/AST/Directives/Directives.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/Literals.cs b/src/Stride.Shaders/Parsers/AST/Directives/Literals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/Literals.cs rename to src/Stride.Shaders/Parsers/AST/Directives/Literals.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/Operations.cs b/src/Stride.Shaders/Parsers/AST/Directives/Operations.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/Operations.cs rename to src/Stride.Shaders/Parsers/AST/Directives/Operations.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/OperatorToken.cs b/src/Stride.Shaders/Parsers/AST/Directives/OperatorToken.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/OperatorToken.cs rename to src/Stride.Shaders/Parsers/AST/Directives/OperatorToken.cs diff --git a/src/Stride.Shaders/Frontend/AST/Directives/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Directives/UnaryLiterals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Directives/UnaryLiterals.cs rename to src/Stride.Shaders/Parsers/AST/Directives/UnaryLiterals.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/Literals.cs rename to src/Stride.Shaders/Parsers/AST/Shader/Literals.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/Operations.cs rename to src/Stride.Shaders/Parsers/AST/Shader/Operations.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/OperatorToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/OperatorToken.cs rename to src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/ShaderProgram.cs rename to src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/ShaderToken.cs rename to src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/Statements.cs rename to src/Stride.Shaders/Parsers/AST/Shader/Statements.cs diff --git a/src/Stride.Shaders/Frontend/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/AST/Shader/UnaryLiterals.cs rename to src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs diff --git a/src/Stride.Shaders/DirectivePreprocessor.cs b/src/Stride.Shaders/Parsers/DirectivePreprocessor.cs similarity index 100% rename from src/Stride.Shaders/DirectivePreprocessor.cs rename to src/Stride.Shaders/Parsers/DirectivePreprocessor.cs diff --git a/src/Stride.Shaders/Frontend/ExpressionParser.cs b/src/Stride.Shaders/Parsers/ExpressionParser.cs similarity index 100% rename from src/Stride.Shaders/Frontend/ExpressionParser.cs rename to src/Stride.Shaders/Parsers/ExpressionParser.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/CommentGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/CommentGrammar.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/CommentGrammar.cs rename to src/Stride.Shaders/Parsers/Grammars/CommentGrammar.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/ExpressionGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/ExpressionGrammar.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/ExpressionGrammar.cs rename to src/Stride.Shaders/Parsers/Grammars/ExpressionGrammar.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/MacroGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/MacroGrammar.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/MacroGrammar.cs rename to src/Stride.Shaders/Parsers/Grammars/MacroGrammar.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 75% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index a52795f10e..61e3cf3650 100644 --- a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -7,8 +7,10 @@ public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); public SequenceParser ShaderExpression = new(); + public SequenceParser RGroup = new() { Name = "RGroup" }; public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer" }; - + public SequenceParser NamespaceExpression = new() {Name = "Namespace"}; + public AlternativeParser ShaderFile = new(){Name = "ShaderFile"}; public SDSLGrammar UsingShader() { @@ -32,14 +34,19 @@ public void CreateShader() ConstantBuffer.Add( - "cbuffer", - ws1, - Identifier, - ws, + "cbuffer" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), LeftBrace, - ws, + ShaderValueDeclaration.Repeat(0).SeparatedBy(ws), RightBrace ); + ConstantBuffer.Separator = ws; + RGroup.Add( + "rgoup" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + LeftBrace, + ShaderValueDeclaration.Repeat(0).SeparatedBy(ws), + RightBrace + ); + RGroup.Separator = ws; var shaderGenericValue = new AlternativeParser( @@ -81,6 +88,8 @@ public void CreateShader() var shaderContentTypes = new AlternativeParser( typeDefinition, StructDefinition, + ConstantBuffer, + RGroup, compositionDeclaration, MethodDeclaration, ShaderValueDeclaration @@ -105,15 +114,28 @@ public void CreateShader() ShaderExpression.Add( - ws, Literal("shader") & ws1 & Identifier.Named("ShaderName"), shaderGenerics.Optional(), inheritances.Optional(), shaderBody, - Semi, - ws + Semi ); ShaderExpression.Separator = ws; ShaderExpression.Name = "ShaderProgram"; + + NamespaceExpression.Add( + ws, + Literal("namespace") & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + LeftBrace, + ShaderExpression, + RightBrace, + ws + ); + NamespaceExpression.Separator = ws; + + ShaderFile.Add( + NamespaceExpression, + ws & ShaderExpression & ws + ); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 100% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs diff --git a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 95% rename from src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs rename to src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs index 3030c5c364..67c251017f 100644 --- a/src/Stride.Shaders/Frontend/Grammars/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -8,7 +8,7 @@ public partial class SDSLGrammar : Grammar public SDSLGrammar() : base("sdsl") { CreateAll(); - Inner = ShaderExpression; + Inner = ShaderFile; } public SDSLGrammar Using(Parser p) diff --git a/src/Stride.Shaders/Frontend/SDSLParser.cs b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs similarity index 95% rename from src/Stride.Shaders/Frontend/SDSLParser.cs rename to src/Stride.Shaders/Parsers/ShaderMixinParser.cs index b705e11673..2e5eff4e10 100644 --- a/src/Stride.Shaders/Frontend/SDSLParser.cs +++ b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Parsing; using CppNet; -public class SDSLParser +public class ShaderMixinParser { public SDSLGrammar Grammar {get;set;} public DirectivePreprocessor DPreprocessor { get; set; } @@ -20,7 +20,7 @@ public class SDSLParser public GrammarMatch? ParseTree { get; set; } - public SDSLParser() + public ShaderMixinParser() { Grammar = new(); DPreprocessor = new(); @@ -31,10 +31,10 @@ public SDSLParser() Preprocessor.addWarning(Warning.IMPORT); Preprocessor.addFeature(Feature.INCLUDENEXT); //Preprocessor.addFeature(Feature.LINEMARKERS); - Preprocessor.setListener(new ErrorListener()); + // Preprocessor.setListener(new ErrorListener()); } - public SDSLParser With(Parser p) + public ShaderMixinParser With(Parser p) { Grammar.Inner = p; return this; diff --git a/src/Stride.Shaders/ShaderClassCode.cs b/src/Stride.Shaders/ShaderClassCode.cs index 83210aa55f..ba4d9a9cea 100644 --- a/src/Stride.Shaders/ShaderClassCode.cs +++ b/src/Stride.Shaders/ShaderClassCode.cs @@ -1,2 +1,34 @@ -namespace Stride.Shaders.Parsing; \ No newline at end of file +using System.Text; + +namespace Stride.Shaders; + + public abstract class ShaderClassCode : ShaderSource +{ + public string ClassName { get; set; } + public string[] GenericArguments { get; set; } + + public Dictionary GenericParametersArguments { get; set; } + + public string ToClassName() + { + if (GenericArguments == null) + return ClassName; + + var result = new StringBuilder(); + result.Append(ClassName); + if (GenericArguments != null && GenericArguments.Length > 0) + { + result.Append('<'); + result.Append(string.Join(",", GenericArguments)); + result.Append('>'); + } + + return result.ToString(); + } + + public override string ToString() + { + return ToClassName(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderClassSource.cs b/src/Stride.Shaders/ShaderClassSource.cs new file mode 100644 index 0000000000..fd29de1a08 --- /dev/null +++ b/src/Stride.Shaders/ShaderClassSource.cs @@ -0,0 +1,108 @@ +using System.Globalization; + +namespace Stride.Shaders; + +public sealed class ShaderClassSource : ShaderClassCode, IEquatable +{ + + /// + /// Initializes a new instance of the class. + /// + public ShaderClassSource() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + public ShaderClassSource(string className) + : this(className, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + /// The generic parameters. + public ShaderClassSource(string className, params string[] genericArguments) + { + ClassName = className; + GenericArguments = genericArguments; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + /// The generic parameters. + public ShaderClassSource(string className, params object[] genericArguments) + { + ClassName = className; + if (genericArguments != null) + { + GenericArguments = new string[genericArguments.Length]; + for (int i = 0; i < genericArguments.Length; ++i) + { + var genArg = genericArguments[i]; + if (genArg is bool) + GenericArguments[i] = ((bool)genArg) ? "true" : "false"; + else + GenericArguments[i] = genArg == null ? "null" : Convert.ToString(genArg, CultureInfo.InvariantCulture); + } + } + } + + public bool Equals(ShaderClassSource shaderClassSource) + { + if (ReferenceEquals(null, shaderClassSource)) return false; + if (ReferenceEquals(this, shaderClassSource)) return true; + return string.Equals(ClassName, shaderClassSource.ClassName) + && GenericArguments.OrderBy(x => x).SequenceEqual(shaderClassSource.GenericArguments.OrderBy(x => x)); + // Utilities.Compare(GenericArguments, shaderClassSource.GenericArguments); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((ShaderClassSource)obj); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = ClassName?.GetHashCode() ?? 0; + if (GenericArguments != null) + { + foreach (var current in GenericArguments) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + + return hashCode; + } + } + + public override object Clone() + { + return new ShaderClassSource(ClassName, GenericArguments = GenericArguments != null ? GenericArguments.ToArray() : null); + } + + public override string ToString() + { + return ToClassName(); + } + + /// + /// Performs an implicit conversion from to . + /// + /// Name of the class. + /// The result of the conversion. + public static implicit operator ShaderClassSource(string className) + { + return new ShaderClassSource(className); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderMixer.cs b/src/Stride.Shaders/ShaderMixer.cs index 31bd0762d1..64fd231239 100644 --- a/src/Stride.Shaders/ShaderMixer.cs +++ b/src/Stride.Shaders/ShaderMixer.cs @@ -4,20 +4,20 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; +using Stride.Shaders.Parsing; -namespace Stride.Shaders.Parsing; +namespace Stride.Shaders; -public class ShaderMixer +public class ShaderMixer : ShaderSource { - //Dictionary - public SDSLParser Parser {get;set;} + public ShaderMixinParser Parser {get;set;} public List Mixins { get; set; } = new(); public ShaderMixer() { Parser = new(); } - public ShaderMixer(SDSLParser parser) + public ShaderMixer(ShaderMixinParser parser) { Parser = parser; } @@ -26,4 +26,19 @@ public void Add(string mixin) { Mixins.Add(new ShaderMixin(mixin,Parser)); } + + public override object Clone() + { + throw new NotImplementedException(); + } + + public override bool Equals(object against) + { + throw new NotImplementedException(); + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } } diff --git a/src/Stride.Shaders/ShaderMixin.cs b/src/Stride.Shaders/ShaderMixin.cs index 0a72bf4145..3be73ea421 100644 --- a/src/Stride.Shaders/ShaderMixin.cs +++ b/src/Stride.Shaders/ShaderMixin.cs @@ -1,11 +1,12 @@ -using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing; +namespace Stride.Shaders; public class ShaderMixin { @@ -21,9 +22,9 @@ public class ShaderMixin "CSMain" }; - SDSLParser Parser { get; set; } + ShaderMixinParser Parser { get; set; } - public ShaderMixin(string code, SDSLParser parser) + public ShaderMixin(string code, ShaderMixinParser parser) { Code = code; Parser = parser; diff --git a/src/Stride.Shaders/ShaderSource.cs b/src/Stride.Shaders/ShaderSource.cs new file mode 100644 index 0000000000..3c824cc60f --- /dev/null +++ b/src/Stride.Shaders/ShaderSource.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders; +public abstract class ShaderSource +{ + public bool Discard { get; set; } + + public abstract object Clone(); + + public abstract override bool Equals(object against); + + public abstract override int GetHashCode(); +} \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderSourceString.cs b/src/Stride.Shaders/ShaderSourceString.cs index 6fd60b448a..1d2b945312 100644 --- a/src/Stride.Shaders/ShaderSourceString.cs +++ b/src/Stride.Shaders/ShaderSourceString.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.AST.Shader; using System; using System.Collections.Generic; @@ -5,7 +6,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing; +namespace Stride.Shaders; public class ShaderSourceString { @@ -21,9 +22,9 @@ public class ShaderSourceString "CSMain" }; - SDSLParser Parser { get; set; } + ShaderMixinParser Parser { get; set; } - public ShaderSourceString(string code, SDSLParser parser) + public ShaderSourceString(string code, ShaderMixinParser parser) { Code = code; Parser = parser; From 407d5d574c40cca92c3298d5c6599b9aa50d053e Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 31 May 2022 16:05:45 +0200 Subject: [PATCH 0104/1182] update types and rgroup --- src/SDSLParserExample/SDSL/shader2.sdsl | 19 ++++++++++--------- .../Parsers/AST/Shader/ShaderToken.cs | 4 +++- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.MethodDeclaration.cs | 6 +++--- .../SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 6 ++++-- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 13 ++++++++++++- 8 files changed, 35 insertions(+), 19 deletions(-) diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 8f6eda6b9c..2ad6b82e72 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,13 +1,14 @@ -shader MyShader { +shader MyShader +{ - stream float3 a : POSITION; - stream float b; - - void VSMain() + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes { - { - float a = float3(1,1,1); - } - return 1; + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients } }; \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 90d9afcd3c..33b24fc794 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -8,7 +8,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; - +public class Empty : ShaderToken{} public abstract class ShaderToken { public static string[] KeepValues = { @@ -26,6 +26,8 @@ public static ShaderToken GetToken(Match match) return tmp.Name switch { "ShaderProgram" => new ShaderProgram(tmp), + "RGroup" => new Empty(), + "ConstantBuffer" => new Empty(), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), "Block" => new BlockStatement(tmp), diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index ed5cc03ac8..2eb18ffa81 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -64,7 +64,7 @@ public void CreateExpressions() TermExpression.Add( Literals, - Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + ~((Plus | Minus) & ws) & Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index d1f056b827..be2885b45f 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -65,8 +65,8 @@ public void CreateLiterals() Literals.Add( IntegerLiteral.NotFollowedBy(Dot | IntegerSuffix | FloatSuffix | Set("xX")).Named("IntegerLiteral"), IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Then(IntegerSuffix).Named("IntegerLiteral"), - FloatLiteral.NotFollowedBy(Set("xX")).Named("FloatLiteral"), FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix).Named("FloatLiteral"), + FloatLiteral.NotFollowedBy(Set("xX")).Named("FloatLiteral"), HexaDecimalLiteral, StringLiteral, BooleanTerm diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index e560cc1ebe..647991e7ce 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -45,14 +45,14 @@ public void CreateMethodDeclaration() | Colon.Then(Identifier).SeparatedBy(ws); var arraySpecifier = - (LeftBracket & Literals & RightBracket) + (LeftBracket & PrimaryExpression & RightBracket) .SeparatedBy(ws); var parameter = new SequenceParser( ValueOrGeneric, ws1, - Identifier, - arraySpecifier.Optional(), + Identifier & ws & arraySpecifier + | Identifier, (Equal & PrimaryExpression).SeparatedBy(ws).Optional() ); var parameterWithStorage = new AlternativeParser( diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 61e3cf3650..f55766ca6a 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -41,7 +41,7 @@ public void CreateShader() ); ConstantBuffer.Separator = ws; RGroup.Add( - "rgoup" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + "rgroup" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), LeftBrace, ShaderValueDeclaration.Repeat(0).SeparatedBy(ws), RightBrace diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index 078d496cf2..afe83e1aff 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -113,7 +113,9 @@ public void CreateTokenGroups() FloatTypes, DoubleTypes, IntTypes, - UintTypes + UintTypes, + BufferTypes, + TextureTypes ); Keywords.Add( @@ -172,7 +174,7 @@ public void CreateTokenGroups() Struct, StructuredBuffer, Switch, - TextureTypes, + TextureBase, Triangle, TriangleAdj, TriangleStream, diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index 01e951db7f..ee0a51ee97 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -87,7 +87,10 @@ public partial class SDSLGrammar : Grammar protected LiteralTerminal Struct = new(); protected LiteralTerminal StructuredBuffer = new(); protected LiteralTerminal Switch = new(); + protected AlternativeParser TextureBase = new(); protected AlternativeParser TextureTypes = new(); + + protected AlternativeParser BufferTypes = new(); protected LiteralTerminal Triangle = new(); protected LiteralTerminal TriangleAdj = new(); protected LiteralTerminal TriangleStream = new(); @@ -232,11 +235,19 @@ public void CreateTokens() Struct = Literal("struct"); StructuredBuffer = Literal("StructuredBuffer"); Switch = Literal("switch"); - TextureTypes.Add( + TextureBase.Add( Literal("Texture").NotFollowedBy("2DMS").Then(Literal("1") | "2" | "3").Then("D").Then(Literal("Array").Optional()), Literal("Texture2DMS").Then(Literal("Array").Optional()), Literal("TextureCube").Then(Literal("Array").Optional()) ); + TextureTypes.Add( + (TextureBase & "<" & ValueTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), + TextureBase + ); + BufferTypes.Add( + (Buffer & "<" & ValueTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), + Buffer + ); Triangle = Literal("triangle"); TriangleAdj = Literal("triangleadj"); TriangleStream = Literal("TriangleStream"); From 47f5a9ebbccc413a1ac8356312b95c2be2146bb8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 31 May 2022 18:11:42 +0200 Subject: [PATCH 0105/1182] updates on statements --- src/SDSLParserExample/Program.cs | 4 +-- src/Stride.Shaders/Compiler/ReadMe.md | 34 +++++++++++++++++++ .../Parsers/AST/Shader/ShaderToken.cs | 13 ++++--- .../Parsers/AST/Shader/Statements.cs | 3 ++ .../SDSLGrammar/SDSLGrammar.Expression.cs | 5 +-- .../SDSLGrammar/SDSLGrammar.Literals.cs | 3 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 6 +--- .../SDSLGrammar/SDSLGrammar.Statements.cs | 5 ++- 8 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 src/Stride.Shaders/Compiler/ReadMe.md diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 516d66f2d6..b5e5dd4122 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -37,9 +37,9 @@ var grammar = ShaderParser.GetGrammar(); var p = ShaderParser.GetParser(); -p.Parse(shaderf,"./SDSL/shader2.sdsl"); +p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); s.Start(); -var result = p.Parse(shaderf,"./SDSL/shader2.sdsl"); +var result = p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); s.Stop(); Console.WriteLine($"irony parsing time : {s.Elapsed}"); diff --git a/src/Stride.Shaders/Compiler/ReadMe.md b/src/Stride.Shaders/Compiler/ReadMe.md new file mode 100644 index 0000000000..5798330ee6 --- /dev/null +++ b/src/Stride.Shaders/Compiler/ReadMe.md @@ -0,0 +1,34 @@ +# Design for generating spirv + +A shader will be described as different kinds : + +* A single shader +* An array of shader to compose as one shader +* A mixin shader for effect composition + +## Single Shader + +A single shader should be a full shader, defining all methods and variables in one single shader object (no mixins) + +## Array shader + +An array of shader will contain multiple shader definition all linked by inheritances. It can be created from one shader requiring parent shaders to find in a shader dictionary/storage of some sort. + +### Spirv design + +#### RGroup and CBuffer + +Each members of both will be queried from all shadercodes, merged together to form a fuller version of both rgroup and cbuffer. + +#### Static methods and members + +Methods and members that are marked as static/staged will be generated once (with a check on duplicates) as spirv methods. +Temporary IDs will be generated (maybe GuID?) and later converted to actual available IDs for the spirv module. + +#### NonStatic/Inherited members, stream values... + +Needs a bit of research. +Instead of generating full methods, we generate a list of statements for each methods then combine them depending the order. + + +## Mixin shader \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 33b24fc794..bbf93be214 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -8,12 +8,12 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class Empty : ShaderToken{} public abstract class ShaderToken { public static string[] KeepValues = { "Block", "Return", + "EmptyStatement", }; public Match? Match { get; set; } @@ -25,15 +25,19 @@ public static ShaderToken GetToken(Match match) return tmp.Name switch { + "Namespace" => GetToken(tmp.Matches.Last()), "ShaderProgram" => new ShaderProgram(tmp), - "RGroup" => new Empty(), - "ConstantBuffer" => new Empty(), + "RGroup" => throw new NotImplementedException(), + "ConstantBuffer" => throw new NotImplementedException(), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), + "ControlFlow" => throw new NotImplementedException(), "Block" => new BlockStatement(tmp), "Return" => new ReturnStatement(tmp), "AssignChain" => new AssignChain(tmp), "DeclareAssign" => new DeclareAssign(tmp), + "SimpleDeclare" => throw new NotImplementedException(), + "EmptyStatement" => new EmptyStatement(), "MethodCall" => new MethodCall(tmp), "Ternary" => new ConditionalExpression(tmp), "LogicalOrExpression" => LogicalOrExpression.Create(tmp), @@ -48,7 +52,8 @@ public static ShaderToken GetToken(Match match) "MulExpression" => MulExpression.Create(tmp), "CastExpression" => new CastExpression(tmp), "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), + "ChainAccessor" => throw new NotImplementedException(), + "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp), "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), "Boolean" => new BoolLiteral(tmp), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 55bf0045a0..2652cca6f9 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -8,8 +8,11 @@ namespace Stride.Shaders.Parsing.AST.Shader; + public class Statement : ShaderToken {} +public class EmptyStatement : Statement{} + public class DeclareAssign : Statement { public AssignOpToken AssignOp { get; set; } diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 2eb18ffa81..9fa3804a41 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -64,7 +64,7 @@ public void CreateExpressions() TermExpression.Add( Literals, - ~((Plus | Minus) & ws) & Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); @@ -109,6 +109,7 @@ public void CreateExpressions() UnaryExpression.Add( PostfixExpression, + (Plus | Minus) & ws & PostfixExpression, prefixInc, Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") ); @@ -222,7 +223,7 @@ public void CreateExpressions() PrimaryExpression.Add( arrayDeclaration, - MethodCall, + // MethodCall, ConditionalExpression ); } diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index be2885b45f..85fb1e132a 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Eto.Parse; using Eto.Parse.Parsers; using static Eto.Parse.Terminals; @@ -55,7 +56,7 @@ public void CreateLiterals() StringLiteral = new StringParser().WithName("StringLiteral"); IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "IntegerValue" }; - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "FloatValue" }; + FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Culture = new CultureInfo("en-US") , Name = "FloatValue" }; HexDigits = new(); HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index 109fcbf1cd..524b15a779 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -38,11 +38,7 @@ public void CreateLoopFlowStatements() valueAssign | PrimaryExpression, RightParen, Semi - | ( - LeftBrace & - Statement.Repeat(0).SeparatedBy(ws) & - RightBrace - ).SeparatedBy(ws) + | Statement ); ForLoop.Separator = ws; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 08d976e58f..65d622a64e 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -70,7 +70,9 @@ public void CreateStatements() .Then(assignVar) .SeparatedBy(ws1); - + var simpleDeclare = + ((ValueTypes | Identifier) & Identifier & arraySpecifier).SeparatedBy(ws) + | ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws); Statement.Add( Block, @@ -79,6 +81,7 @@ public void CreateStatements() returnStatement.Named("Return"), assignChain.Named("AssignChain"), declareAssign.Named("DeclareAssign"), + simpleDeclare.Named("SimpleDeclare"), assignVar.Named("Assign"), PrimaryExpression.Then(Semi).SeparatedBy(ws).Named("EmptyStatement") ); From 3b1e0ee23223929918822cc6c122f926e48cca5e Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Wed, 1 Jun 2022 18:25:27 +0200 Subject: [PATCH 0106/1182] update parsing --- src/SDSLParserExample/SDSL/shader2.sdsl | 109 ++++++++++++++++-- .../Parsers/AST/Shader/ControlFlow.cs | 74 ++++++++++++ .../Parsers/AST/Shader/ShaderProgram.cs | 22 ++++ .../Parsers/AST/Shader/ShaderToken.cs | 8 +- .../Parsers/AST/Shader/Statements.cs | 3 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 18 +-- ...ar.Statements.ConditionalFlowStatements.cs | 17 ++- .../SDSLGrammar/SDSLGrammar.Statements.cs | 6 +- 8 files changed, 222 insertions(+), 35 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 2ad6b82e72..487c3da1db 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,14 +1,99 @@ -shader MyShader +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.LightProbes { + /// + /// Defines a skybox environment light + /// + shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils + { + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes + { +#ifdef STRIDE_MULTISAMPLE_COUNT + #if STRIDE_MULTISAMPLE_COUNT > 1 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #else + stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #endif +#else + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#endif + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients + } + + void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) + { + // Early exit + if (weight == 0.0f) + return; + + int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; + for (int i = 0; i < TOrder * TOrder; ++i) + { + // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly + sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; + } + } + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + var ambientAccessibility = streams.matAmbientOcclusion; + + var sampleDirection = streams.normalWS; + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + var shadingPosition = int3(streams.ShadingPosition.xy, 0); +#if STRIDE_MULTISAMPLE_COUNT == 1 + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); +#else + // TODO: Use SV_SampleIndex + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); +#endif + + uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); + float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); + + float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); + + // Protect ourselves against degenerate cases + // TODO: Investigate why those happen (almost coplanar tetrahedron?) + tetrahedronFactors3 = saturate(tetrahedronFactors3); + + float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); + + // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) + tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Renormalize barycentric coordinates + var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; + if (totalSum > 0.0f) + tetrahedronFactors4 /= totalSum; + + float3 sphericalColors[TOrder * TOrder]; + for (int i = 0; i < TOrder * TOrder; ++i) + sphericalColors[i] = 0.0f; + + FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); + FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); + FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); + FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } -}; \ No newline at end of file + streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + // TEST: + //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + //streams.envLightDiffuseColor = tetrahedronFactors3; + //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); + } + }; +} diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs new file mode 100644 index 0000000000..5c06a35a5a --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs @@ -0,0 +1,74 @@ +using Eto.Parse; + +namespace Stride.Shaders.Parsing.AST.Shader; + + +public class IfStatement : ControlFlow +{ + public ShaderToken Attributes {get;set;} + public ShaderToken Condition {get;set;} + public ShaderToken Statements {get;set;} + public IfStatement(Match m) + { + Match = m; + if(m["Attributes"].HasMatches) + throw new NotImplementedException(); + Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); + Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + } +} + +public class ElseIfStatement : ControlFlow +{ + public ShaderToken Attributes {get;set;} + public ShaderToken Condition {get;set;} + public ShaderToken Statements {get;set;} + public ElseIfStatement(Match m) + { + Match = m; + if(m["Attributes"].HasMatches) + throw new NotImplementedException(); + Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); + Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + } +} + +public class ElseStatement : ControlFlow +{ + public ShaderToken Attributes {get;set;} + public ShaderToken Condition {get;set;} + public ShaderToken Statements {get;set;} + public ElseStatement(Match m) + { + Match = m; + if(m["Attributes"].HasMatches) + throw new NotImplementedException(); + Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); + Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + } +} + +public class ConditionalFlow : ControlFlow +{ + public IfStatement If {get;set;} + public List ElseIfs {get;set;} + public ElseStatement Else {get;set;} + public ConditionalFlow(Match m) + { + Match = m["ConditionalFlow"]; + throw new NotImplementedException(); + } +} + + +public class ControlFlow : ShaderToken +{ + public static ControlFlow Create(Match m) + { + return m.Matches[1].Name switch + { + "ConditionalFlow" => new ConditionalFlow(m), + _ => throw new NotImplementedException() + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index 1929fe29b6..53b2970d0b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -7,6 +7,28 @@ namespace Stride.Shaders.Parsing.AST.Shader; +public class ResourceGroup : ShaderToken +{ + public IEnumerable Variables {get;set;} + + public ResourceGroup(Match m) + { + Match = m; + Variables = m["Variables"].Matches.Select(GetToken).ToList(); + + } +} +public class ConstantBuffer : ShaderToken +{ + public IEnumerable Variables {get;set;} + + public ConstantBuffer(Match m) + { + Match = m; + Variables = m["Variables"].Matches.Select(GetToken).ToList(); + + } +} public class ShaderMethod : ShaderToken { public bool IsStatic { get; set; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index bbf93be214..4ff70f608f 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -14,6 +14,8 @@ public abstract class ShaderToken "Block", "Return", "EmptyStatement", + "ConstantBuffer", + "ResourceGroup", }; public Match? Match { get; set; } @@ -27,11 +29,11 @@ public static ShaderToken GetToken(Match match) { "Namespace" => GetToken(tmp.Matches.Last()), "ShaderProgram" => new ShaderProgram(tmp), - "RGroup" => throw new NotImplementedException(), - "ConstantBuffer" => throw new NotImplementedException(), + "ResourceGroup" => new ResourceGroup(tmp), + "ConstantBuffer" => new ConstantBuffer(tmp), "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), "Method" => new ShaderMethod(tmp), - "ControlFlow" => throw new NotImplementedException(), + "ControlFlow" => ControlFlow.Create(tmp), "Block" => new BlockStatement(tmp), "Return" => new ReturnStatement(tmp), "AssignChain" => new AssignChain(tmp), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 2652cca6f9..15ac387070 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -51,7 +51,8 @@ public class ReturnStatement : Statement public ReturnStatement(Match m) { Match = m; - ReturnValue = GetToken(m["PrimaryExpression"]); + if(m.HasMatches) + ReturnValue = GetToken(m["PrimaryExpression"]); } } diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index f55766ca6a..5af00eb23a 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -7,7 +7,7 @@ public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); public SequenceParser ShaderExpression = new(); - public SequenceParser RGroup = new() { Name = "RGroup" }; + public SequenceParser ResourceGroup = new() { Name = "ResourceGroup" }; public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer" }; public SequenceParser NamespaceExpression = new() {Name = "Namespace"}; public AlternativeParser ShaderFile = new(){Name = "ShaderFile"}; @@ -34,19 +34,19 @@ public void CreateShader() ConstantBuffer.Add( - "cbuffer" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + "cbuffer" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("GroupName"), LeftBrace, - ShaderValueDeclaration.Repeat(0).SeparatedBy(ws), + ShaderValueDeclaration.Repeat(0).SeparatedBy(ws).Named("Variables"), RightBrace ); ConstantBuffer.Separator = ws; - RGroup.Add( - "rgroup" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + ResourceGroup.Add( + "rgroup" & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("GroupName"), LeftBrace, - ShaderValueDeclaration.Repeat(0).SeparatedBy(ws), + ShaderValueDeclaration.Repeat(0).SeparatedBy(ws).Named("Variables"), RightBrace ); - RGroup.Separator = ws; + ResourceGroup.Separator = ws; var shaderGenericValue = new AlternativeParser( @@ -89,7 +89,7 @@ public void CreateShader() typeDefinition, StructDefinition, ConstantBuffer, - RGroup, + ResourceGroup, compositionDeclaration, MethodDeclaration, ShaderValueDeclaration @@ -125,7 +125,7 @@ public void CreateShader() NamespaceExpression.Add( ws, - Literal("namespace") & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws), + Literal("namespace") & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("Namespace"), LeftBrace, ShaderExpression, RightBrace, diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs index 17647af14d..47630581f9 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -13,20 +13,25 @@ public void CreateConditionalFlowStatements() var ifStatement = - If.Then(LeftParen).Then(PrimaryExpression).Then(RightParen).Then(Statement).SeparatedBy(ws); + If.Then(LeftParen).Then(PrimaryExpression.Named("Condition")).Then(RightParen).Then(Statement).SeparatedBy(ws).Named("IfStatement"); var elseIfStatement = - Else.Then(ifStatement).SeparatedBy(ws1); + Else.Then(ifStatement).SeparatedBy(ws1).Named("ElseIfStatement"); var elseStatement = - Else.Then(Statement).SeparatedBy(ws1); + Else.Then(Statement).SeparatedBy(ws1).Named("ElseStatement"); + + var conditionalFlow = new AlternativeParser( + ifStatement & ws & elseIfStatement.Repeat(0).SeparatedBy(ws) & elseStatement, + ifStatement & ws & elseIfStatement.Repeat(0).SeparatedBy(ws), + ifStatement & ws & elseStatement, + ifStatement + ){Name = "ConditionalFlow"}; ControlFlow.Add( Attribute.Repeat(0).Named("Attributes"), ws, - ifStatement.Named("IfStatement") - | elseStatement.Named("ElseStatement") - | elseIfStatement.Named("ElseIfStatement") + conditionalFlow | ForLoop ); } diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 65d622a64e..b6048afea4 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -23,10 +23,8 @@ public void CreateStatements() var returnStatement = new SequenceParser( Return, - ws1, - PrimaryExpression, - ws, - Semi + (ws1 & PrimaryExpression & ws & Semi) + |(ws & Semi) ); var attrParams = From fa447e170033f12296d385a63d29f1ab0cc5d4a3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 3 Jun 2022 14:39:03 +0200 Subject: [PATCH 0107/1182] More control flow parsing --- .../Parsers/AST/Shader/ControlFlow.cs | 30 +++++++++++++++--- ...ar.Statements.ConditionalFlowStatements.cs | 9 ++++-- ...SLGrammar.Statements.LoopFlowStatements.cs | 31 +++++++++++++++---- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs index 5c06a35a5a..f33db16a1b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs @@ -3,6 +3,20 @@ namespace Stride.Shaders.Parsing.AST.Shader; +public class ForLoop : ControlFlow +{ + public DeclareAssign Initializer {get;set;} + public ShaderToken Condition {get;set;} + public ShaderToken Updater {get;set;} + public ForLoop(Match m) + { + Match = m; + + + } +} + + public class IfStatement : ControlFlow { public ShaderToken Attributes {get;set;} @@ -13,8 +27,8 @@ public IfStatement(Match m) Match = m; if(m["Attributes"].HasMatches) throw new NotImplementedException(); - Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); - Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + Condition = GetToken(m["Condition"]); + Statements = GetToken(m["Statement"]); } } @@ -56,19 +70,25 @@ public class ConditionalFlow : ControlFlow public ConditionalFlow(Match m) { Match = m["ConditionalFlow"]; - throw new NotImplementedException(); + If = new IfStatement(Match["IfStatement"]); + if(Match.Matches.Any(x => x.Name == "ElseIfStatement")) + ElseIfs = Match.Matches.Where(x => x.Name == "ElseIfStatement").Select(x => new ElseIfStatement(x)).ToList(); + if(Match["ElseStatement"]) + Else = new ElseStatement(Match["ElseStatement"]); } } -public class ControlFlow : ShaderToken +public class ControlFlow : Statement { public static ControlFlow Create(Match m) { return m.Matches[1].Name switch { "ConditionalFlow" => new ConditionalFlow(m), + "ForLoop" => new ForLoop(m), _ => throw new NotImplementedException() }; } -} \ No newline at end of file +} + diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs index 47630581f9..70c4173f69 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -12,8 +12,13 @@ public void CreateConditionalFlowStatements() var ws1 = WhiteSpace.Repeat(1); - var ifStatement = - If.Then(LeftParen).Then(PrimaryExpression.Named("Condition")).Then(RightParen).Then(Statement).SeparatedBy(ws).Named("IfStatement"); + var ifStatement = new SequenceParser( + If, + LeftParen, + PrimaryExpression.Named("Condition"), + RightParen, + Statement + ){Name = "IfStatement", Separator = ws}; var elseIfStatement = Else.Then(ifStatement).SeparatedBy(ws1).Named("ElseIfStatement"); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index 524b15a779..81c3381e86 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -6,8 +6,8 @@ namespace Stride.Shaders.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { - public AlternativeParser WhileLoop = new() { Name = "ForLoop"}; - public AlternativeParser ForEachLoop = new() { Name = "ForLoop"}; + public SequenceParser WhileLoop = new() { Name = "WhileLoop"}; + public SequenceParser ForEachLoop = new() { Name = "ForEachLoop"}; public SequenceParser ForLoop = new() { Name = "ForLoop"}; public void CreateLoopFlowStatements() @@ -16,14 +16,15 @@ public void CreateLoopFlowStatements() var ws1 = WhiteSpace.Repeat(1); var valueDeclare = new SequenceParser( - ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1), - "=", + ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1) + | UnaryExpression, + AssignOperators.Named("Operator"), PrimaryExpression ) - { Separator = ws }; + { Separator = ws, Name = "Initializer"}; var valueAssign = new SequenceParser( Identifier, - AssignOperators, + AssignOperators.Named("Operator"), PrimaryExpression ) { Separator = ws }; @@ -43,5 +44,23 @@ public void CreateLoopFlowStatements() ); ForLoop.Separator = ws; + WhileLoop.Add( + While, + LeftParen, + PrimaryExpression.Named("Condition"), + RightParen, + Statement + ); + WhileLoop.Separator = ws; + + ForEachLoop.Add( + Literal("foreach"), + LeftParen, + ((ValueTypes | Literal("var") | Identifier) & Identifier & In & PrimaryExpression).SeparatedBy(ws).Named("Declarator"), + RightParen, + Statement + ); + ForEachLoop.Separator = ws; + } } \ No newline at end of file From 57a03daecca0578fa66a4f89013a518ac40f3b69 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 6 Jun 2022 10:36:29 +0200 Subject: [PATCH 0108/1182] Update on code lowering --- src/SDSLParserExample/Program.cs | 79 ++++++++----- src/SDSLParserExample/SDSL/shader2.sdsl | 104 +----------------- src/Spv.Generator | 2 +- .../SpirvEmitter.Types.cs} | 10 +- .../Compiler/Emitter/SpirvEmitter.cs | 31 ++++++ src/Stride.Shaders/Compiler/Lowering.cs | 63 +++++++++++ src/Stride.Shaders/Compiler/ShaderCompiler.cs | 14 +++ .../Compiler/ThreeAddressElement.cs | 82 ++++++++------ src/Stride.Shaders/EntryPoints.cs | 11 ++ .../Parsers/AST/Shader/ControlFlow.cs | 4 +- .../Parsers/AST/Shader/Literals.cs | 39 +++---- .../Parsers/AST/Shader/Operations.cs | 54 ++------- .../Parsers/AST/Shader/OperatorToken.cs | 64 ----------- .../Parsers/AST/Shader/ShaderToken.cs | 19 ---- .../Parsers/AST/Shader/SpirvTypes.cs | 19 ++++ .../Parsers/AST/Shader/Statements.cs | 8 +- .../Parsers/AST/Shader/UnaryLiterals.cs | 7 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 4 +- src/Stride.Shaders/ShaderClassSource.cs | 18 +-- ...erSourceString.cs => ShaderClassString.cs} | 44 ++++---- src/Stride.Shaders/ShaderResult.cs | 22 ++++ 21 files changed, 333 insertions(+), 365 deletions(-) rename src/Stride.Shaders/Compiler/{SpirvEmitter.cs => Emitter/SpirvEmitter.Types.cs} (62%) create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs create mode 100644 src/Stride.Shaders/Compiler/Lowering.cs create mode 100644 src/Stride.Shaders/Compiler/ShaderCompiler.cs create mode 100644 src/Stride.Shaders/EntryPoints.cs create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs rename src/Stride.Shaders/{ShaderSourceString.cs => ShaderClassString.cs} (52%) create mode 100644 src/Stride.Shaders/ShaderResult.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index b5e5dd4122..3798cc2f6e 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -8,39 +8,68 @@ using Stride.Core.Shaders; using Stride.Core.Shaders.Parser; using Stride.Core.Shaders.Grammar.Stride; +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Compiling; -var shaderf = File.ReadAllText("./SDSL/shader.sdsl"); -var child = File.ReadAllText("./SDSL/InheritExample/Child.sdsl"); -var parent = File.ReadAllText("./SDSL/InheritExample/Parent.sdsl"); +var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); -// var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); +// ShaderCompiling(); +ThreeAddress(shaderf); -var sdsl = new Stride.Shaders.Parsing.ShaderMixinParser(); -//sdsl.Grammar.Using(sdsl.Grammar.CastExpression); -var s = new Stopwatch(); -var parser = new ExpressionParser(); -var match2 = sdsl.Parse(shaderf); -// sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", 5); +static void ThreeAddress(string code) +{ + + var parser = new ShaderMixinParser(); + ShaderProgram? ast = parser.Parse(code) as ShaderProgram; + var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; + var s = new Stopwatch(); + _ = Lowering.LowerToken(declare).ToList(); -s.Start(); -var match = sdsl.Parse(shaderf); -s.Stop(); + s.Start(); + var x = Lowering.LowerToken(declare).ToList(); + s.Stop(); + x.ForEach(Console.WriteLine); + Console.WriteLine(s.Elapsed); +} -// sdsl.PrintParserTree(); -Console.WriteLine(shaderf); -Console.WriteLine(new string('*', 64)); -Console.WriteLine(match); -Console.WriteLine($"parsing time : {s.Elapsed}"); -var grammar = ShaderParser.GetGrammar(); +static void ShaderCompiling(string shaderf){ + + var child = File.ReadAllText("./SDSL/InheritExample/Child.sdsl"); + var parent = File.ReadAllText("./SDSL/InheritExample/Parent.sdsl"); + + // var shaderf = File.ReadAllText("../../../SDSL/shader2.sdsl"); + + var sdsl = new Stride.Shaders.Parsing.ShaderMixinParser(); + //sdsl.Grammar.Using(sdsl.Grammar.CastExpression); + var s = new Stopwatch(); + var parser = new ExpressionParser(); + var match2 = sdsl.Parse(shaderf); + // sdsl.AddMacro("STRIDE_MULTISAMPLE_COUNT", 5); + + + s.Start(); + var match = sdsl.Parse(shaderf); + s.Stop(); + + // sdsl.PrintParserTree(); + + Console.WriteLine(shaderf); + Console.WriteLine(new string('*', 64)); + Console.WriteLine(match); + Console.WriteLine($"parsing time : {s.Elapsed}"); + + var grammar = ShaderParser.GetGrammar(); + + var p = ShaderParser.GetParser(); + p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); + s.Start(); + var result = p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); + s.Stop(); + Console.WriteLine($"irony parsing time : {s.Elapsed}"); +} -var p = ShaderParser.GetParser(); -p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); -s.Start(); -var result = p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); -s.Stop(); -Console.WriteLine($"irony parsing time : {s.Elapsed}"); diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 487c3da1db..3b6c0a218e 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,99 +1,7 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Simple { + float a = 0; -namespace Stride.Rendering.LightProbes -{ - /// - /// Defines a skybox environment light - /// - shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils - { - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { -#ifdef STRIDE_MULTISAMPLE_COUNT - #if STRIDE_MULTISAMPLE_COUNT > 1 - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #else - stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #endif -#else - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID -#endif - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } - - void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) - { - // Early exit - if (weight == 0.0f) - return; - - int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; - for (int i = 0; i < TOrder * TOrder; ++i) - { - // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly - sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; - } - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - var sampleDirection = streams.normalWS; - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - var shadingPosition = int3(streams.ShadingPosition.xy, 0); -#if STRIDE_MULTISAMPLE_COUNT == 1 - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); -#else - // TODO: Use SV_SampleIndex - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); -#endif - - uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); - float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); - - float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); - - // Protect ourselves against degenerate cases - // TODO: Investigate why those happen (almost coplanar tetrahedron?) - tetrahedronFactors3 = saturate(tetrahedronFactors3); - - float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); - - // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) - tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Renormalize barycentric coordinates - var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; - if (totalSum > 0.0f) - tetrahedronFactors4 /= totalSum; - - float3 sphericalColors[TOrder * TOrder]; - for (int i = 0; i < TOrder * TOrder; ++i) - sphericalColors[i] = 0.0f; - - FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); - FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); - FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); - FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - - streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - // TEST: - //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - //streams.envLightDiffuseColor = tetrahedronFactors3; - //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); - } - }; -} + void VSMain(){ + float b = (5+2)*3; + } +}; \ No newline at end of file diff --git a/src/Spv.Generator b/src/Spv.Generator index 07c29410e5..37797c7b04 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 07c29410e56358f71467c2ba264124505db064f3 +Subproject commit 37797c7b044d279d11d7cd134db19e2768cc5003 diff --git a/src/Stride.Shaders/Compiler/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs similarity index 62% rename from src/Stride.Shaders/Compiler/SpirvEmitter.cs rename to src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 1711b2cec5..34c54aba1b 100644 --- a/src/Stride.Shaders/Compiler/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -1,17 +1,15 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; namespace Stride.Shaders; -public class SpirvEmitter : Module +public partial class SpirvEmitter : Module { - public SpirvEmitter(uint version) : base(version) - { - - } + } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs new file mode 100644 index 0000000000..1c41eaf029 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; + +namespace Stride.Shaders; + +public partial class SpirvEmitter : Module +{ + public SpirvEmitter(uint version) : base(version) + { + + } + + public void Construct(ShaderClassString code, EntryPoints entry) + { + AddCapability(Capability.Shader); + SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); + + // Create all user defined types + + // Manage input output and stream + + // Generate methods + + } +} diff --git a/src/Stride.Shaders/Compiler/Lowering.cs b/src/Stride.Shaders/Compiler/Lowering.cs new file mode 100644 index 0000000000..45724a6a45 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Lowering.cs @@ -0,0 +1,63 @@ +using Stride.Shaders.Parsing.AST.Shader; + +namespace Stride.Shaders.Compiling; + +public static class Lowering +{ + public static IEnumerable LowerToken(ShaderToken token) + { + + return token switch + { + DeclareAssign t => Lower(t), + ConditionalExpression t => Lower(t), + Operation t => Lower(t), + ShaderLiteral t => Lower(t), + _ => throw new NotImplementedException() + }; + } + + static IEnumerable Lower(DeclareAssign s) + { + var v = LowerToken(s.Value); + return v.Append( + new AssignRegister{ + Name = s.VariableName, + Value = v.Last(), + Op = s.AssignOp + } + ); + } + + static IEnumerable Lower(ConditionalExpression cexp) + { + var result = new List(); + return result; + } + + static IEnumerable Lower(Operation o) + { + IEnumerable l = LowerToken(o.Left); + IEnumerable r = LowerToken(o.Right); + + return l.Concat(r).Append( + new OperationRegister + { + Op = o.Op, + Left = l.Last(), + Right = r.Last() + } + ); + } + + static IEnumerable Lower(ShaderLiteral lit) + { + return new List{ + lit switch { + NumberLiteral nl => new ValueRegister(nl), + _ => new ValueRegister(lit) + } + }; + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ShaderCompiler.cs b/src/Stride.Shaders/Compiler/ShaderCompiler.cs new file mode 100644 index 0000000000..4ffb0013bc --- /dev/null +++ b/src/Stride.Shaders/Compiler/ShaderCompiler.cs @@ -0,0 +1,14 @@ +using Stride.Shaders.Parsing; + +namespace Stride.Shaders.Compiling; + +public class ShaderCompiler +{ + public ShaderMixinParser Parser {get;set;} = new(); + public ShaderClassString Shader {get;set;} + + public void Compile(string shader, Dictionary macros) + { + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/ThreeAddressElement.cs index ad056f2cd8..5b31fabb5d 100644 --- a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/ThreeAddressElement.cs @@ -3,51 +3,71 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Stride.Shaders.Parsing.AST.Shader; -namespace Stride.Shaders.Parsing.Backend; +namespace Stride.Shaders.Compiling; -public enum Operators +public class Register { - Mul, - Div, - Mod, - Plus, - Minus, - LeftShift, - RightShift, - And, - Or, - Xor, - Less, - Greater, - LessEqual, - GreaterEqual, - Equals, - NotEquals, - LogicalAnd, - LogicalOr + private string name; + public string Name + { + get => name ?? "id_" + GetHashCode(); + set => name = value; + } } - -public interface Register { } - -public struct NamedRegister : Register +public class NamedRegister : Register { - public string Name { get; set; } + + public override string ToString() + { + return Name; + } } -public struct ValueRegister : Register +public class ValueRegister : Register { - public T Value { get; set; } + public ShaderLiteral Literal { get; set; } + public ValueRegister(ShaderLiteral v) + { + Literal = v; + Name = v.Value.ToString(); + } + public override string ToString() + { + return Literal.Value?.ToString() ?? "null"; + } } -public struct ThreeAddressOperation +public class OperationRegister : Register { - public string RegisterName { get; set; } public Register Left { get; set; } public Register Right { get; set; } - public Operators Op { get; set; } -} + public OperatorToken Op { get; set; } + public override string ToString() + { + return + new StringBuilder() + .Append(Name) + .Append(" = ") + .Append(Left.Name) + .Append(' ') + .Append(Op) + .Append(' ') + .Append(Right.Name) + .Append(';').ToString(); + } +} +public class AssignRegister : Register +{ + public AssignOpToken Op {get;set;} + public Register Value {get;set;} + public override string ToString() + { + return new StringBuilder().Append(Name).Append(' ').Append(Op).Append(' ').Append(Value.Name).ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/EntryPoints.cs b/src/Stride.Shaders/EntryPoints.cs new file mode 100644 index 0000000000..4b322631d5 --- /dev/null +++ b/src/Stride.Shaders/EntryPoints.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders; + +public enum EntryPoints +{ + PSMain, + VSMain, + GSMain, + CSMain, + DSMain, + HSMain +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs index f33db16a1b..f441bfa877 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs @@ -5,12 +5,14 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class ForLoop : ControlFlow { - public DeclareAssign Initializer {get;set;} + public List Attributes {get;set;} + public ShaderToken Initializer {get;set;} public ShaderToken Condition {get;set;} public ShaderToken Updater {get;set;} public ForLoop(Match m) { Match = m; + var forMatch = m["ForLoop"]; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 4d78546d95..0604c8de70 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -10,37 +10,32 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderLiteral : Projector { - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override ShaderToken ProjectConstant() - { - return this; - } + public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public object Value {get;set;} } public class NumberLiteral : ShaderLiteral { public bool Negative { get; set; } = false; - public object Value { get; set; } public string? Suffix { get; set; } - protected Type? inferredType; + protected string? inferredType; - public override Type InferredType + public override string InferredType { get { if (inferredType is not null) return inferredType; - if (Suffix is null) - return Value.GetType(); else { return Suffix switch { - "u" or "l" => typeof(long), - "f" or "d" => typeof(double), - _ => typeof(long) + "u" => "uint", + "l" => "long", + "f" => "float", + "d" => "double", + _ => "int" }; } } @@ -72,12 +67,11 @@ public NumberLiteral(Match match) } public class HexLiteral : NumberLiteral { - - public override Type InferredType + public override string InferredType { get { - return typeof(long); + return "long"; } set => inferredType = value; } @@ -93,8 +87,7 @@ public HexLiteral(Match match) } public class StringLiteral : ShaderLiteral { - public string? Value { get; set; } - public override Type InferredType { get => typeof(string); set { } } + public override string InferredType { get => "string"; set { } } public StringLiteral() { } @@ -107,8 +100,7 @@ public StringLiteral(Match match) public class BoolLiteral : ShaderLiteral { - public bool Value { get; set; } - public override Type InferredType { get => typeof(bool); set { } } + public override string InferredType { get => "bool"; set { } } public BoolLiteral() { } @@ -133,11 +125,10 @@ public TypeNameLiteral(Match m) public class VariableNameLiteral : ShaderLiteral { public string Name { get; set; } - public object Value { get; set; } - Type? inferredType; + string? inferredType; - public override Type InferredType { get => inferredType ?? typeof(void); set => inferredType = value; } + public override string InferredType { get => inferredType; set => inferredType = value; } public VariableNameLiteral(Match m) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 6ef9b9f864..d1056588ac 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -11,9 +11,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Projector : ShaderToken { - public virtual Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public abstract ShaderToken ProjectConstant(); + public virtual string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } public class Operation : Projector @@ -23,31 +21,12 @@ public class Operation : Projector public ShaderToken Left { get; set; } public ShaderToken Right { get; set; } - Type? inferredType; - public override Type InferredType + string? inferredType; + public override string InferredType { - get => inferredType ?? typeof(void); + get => inferredType ?? "int"; set => inferredType = value; - } - - public override ShaderToken ProjectConstant() - { - - if (Left is Projector) - Left = ((Projector)Left).ProjectConstant(); - if (Right is Projector) - Right = ((Projector)Right).ProjectConstant(); - - return (Left, Right) switch - { - (NumberLiteral ln, NumberLiteral rn) => ApplyOperation(Op, ln, rn), - (BoolLiteral ln, BoolLiteral rn) => ApplyOperation(Op, ln, rn), - (StringLiteral ln, StringLiteral rn) => ApplyOperation(Op, ln, rn), - _ => throw new Exception("Cannot process operation") - }; - } - - + } } @@ -325,11 +304,11 @@ public class ConditionalExpression : Projector public ShaderToken TrueOutput { get; set; } public ShaderToken FalseOutput { get; set; } - Type? inferredType; + string? inferredType; - public override Type InferredType + public override string InferredType { - get => inferredType ?? typeof(void); + get => inferredType; set => inferredType = value; } @@ -339,23 +318,6 @@ public ConditionalExpression(Match m) TrueOutput = GetToken(m.Matches[1]); FalseOutput = GetToken(m.Matches[2]); } - - public override ShaderToken ProjectConstant() - { - if (Condition is Projector) - Condition = ((Projector)Condition).ProjectConstant(); - - if (TrueOutput is Projector ) - TrueOutput= ((Projector)TrueOutput).ProjectConstant(); - - if (FalseOutput is Projector ) - FalseOutput= ((Projector)FalseOutput).ProjectConstant(); - - if (Condition is BoolLiteral c) - return c.Value ? TrueOutput : FalseOutput; - else - throw new Exception("Invalid condition"); - } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs index 6083ebe3df..33e1cd3292 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs @@ -88,68 +88,4 @@ public static AssignOpToken ToAssignOp(this string s) _ => throw new NotImplementedException() }; } - - private static double OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToDouble(a); - var r = Convert.ToDouble(b); - return f.Invoke(l, r); - } - private static double OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToInt32(a); - var r = Convert.ToInt32(b); - return f.Invoke(l, r); - } - - private static bool OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToDouble(a); - var r = Convert.ToDouble(b); - return f.Invoke(l, r); - } - - public static ShaderToken ApplyOperation(OperatorToken op, NumberLiteral l, NumberLiteral r) - { - return op switch - { - OperatorToken.Mul => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a*b) }, - OperatorToken.Div => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a / b) }, - OperatorToken.Mod => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a % b) }, - OperatorToken.Plus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a + b) }, - OperatorToken.Minus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a - b) }, - OperatorToken.LeftShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a,b) => a << b) }, - OperatorToken.RightShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a >> b) }, - OperatorToken.And => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a & b) }, - OperatorToken.Or => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a | b) }, - OperatorToken.Xor => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a ^ b) }, - OperatorToken.Less => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a < b) }, - OperatorToken.LessEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a <= b) }, - OperatorToken.Greater => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a > b) }, - OperatorToken.GreaterEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a >= b) }, - OperatorToken.Equals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a == b) }, - OperatorToken.NotEquals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a != b) }, - _ => throw new NotImplementedException() - }; - } - public static ShaderToken ApplyOperation(OperatorToken op, BoolLiteral l, BoolLiteral r) - { - return op switch - { - OperatorToken.LogicalAnd => new BoolLiteral { Value = l.Value && r.Value }, - OperatorToken.LogicalOr => new BoolLiteral { Value = l.Value || r.Value }, - OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, - OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, - _ => throw new NotImplementedException() - }; - } - public static ShaderToken ApplyOperation(OperatorToken op, StringLiteral l, StringLiteral r) - { - return op switch - { - OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, - OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, - _ => throw new NotImplementedException() - }; - } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 4ff70f608f..d33e08fa97 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -62,23 +62,4 @@ public static ShaderToken GetToken(Match match) _ => throw new NotImplementedException() }; } - - public static ShaderToken EvaluateExpression(ShaderToken expr, Dictionary macros) - { - return expr switch - { - ShaderLiteral l => l, - Operation o => EvaluateOperation(o,macros), - _ => throw new Exception("Couldn't evaluate expression") - }; - } - private static ShaderToken EvaluateOperation(Operation operation, Dictionary macros) - { - return operation.ProjectConstant() switch - { - Operation o => o, - ShaderLiteral t => t, - _ => throw new Exception("Couldn't evaluate operation") - }; - } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs b/src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs new file mode 100644 index 0000000000..7197c3bbe3 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs @@ -0,0 +1,19 @@ +using Spv.Generator; +using static Spv.Generator.Instruction; + + +namespace Stride.Shaders.Parsing.AST.Shader; + + + +public static class SpirvTypes +{ + public static Instruction GetSpirvType(string name) + { + return name switch + { + // "float" => TypeFloat() + _ => throw new NotImplementedException() + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 15ac387070..3bfa2acfab 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; using System; using System.Collections.Generic; @@ -9,9 +10,9 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class Statement : ShaderToken {} +public abstract class Statement : ShaderToken {} -public class EmptyStatement : Statement{} +public class EmptyStatement : Statement {} public class DeclareAssign : Statement { @@ -43,11 +44,12 @@ public AssignChain(Match m) AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); Value = GetToken(m["PrimaryExpression"]); } + } public class ReturnStatement : Statement { - public ShaderToken ReturnValue {get;set;} + public ShaderToken? ReturnValue {get;set;} public ReturnStatement(Match m) { Match = m; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index 129823dae5..8d176e8e53 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -10,12 +10,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class UnaryExpression : Projector { - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override ShaderToken ProjectConstant() - { - return this; - } + public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } public class ChainAccessor : UnaryExpression diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index 81c3381e86..d5cbe6d16b 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -16,8 +16,8 @@ public void CreateLoopFlowStatements() var ws1 = WhiteSpace.Repeat(1); var valueDeclare = new SequenceParser( - ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1) - | UnaryExpression, + ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1).Named("NewVariable") + | UnaryExpression.Named("ExistingVariable"), AssignOperators.Named("Operator"), PrimaryExpression ) diff --git a/src/Stride.Shaders/ShaderClassSource.cs b/src/Stride.Shaders/ShaderClassSource.cs index fd29de1a08..8e597e1688 100644 --- a/src/Stride.Shaders/ShaderClassSource.cs +++ b/src/Stride.Shaders/ShaderClassSource.cs @@ -4,28 +4,16 @@ namespace Stride.Shaders; public sealed class ShaderClassSource : ShaderClassCode, IEquatable { - - /// - /// Initializes a new instance of the class. - /// public ShaderClassSource() { } - /// - /// Initializes a new instance of the class. - /// - /// Name of the class. public ShaderClassSource(string className) : this(className, null) { } - /// - /// Initializes a new instance of the class. - /// - /// Name of the class. - /// The generic parameters. + public ShaderClassSource(string className, params string[] genericArguments) { ClassName = className; @@ -56,7 +44,7 @@ public ShaderClassSource(string className, params object[] genericArguments) public bool Equals(ShaderClassSource shaderClassSource) { - if (ReferenceEquals(null, shaderClassSource)) return false; + if (shaderClassSource is null) return false; if (ReferenceEquals(this, shaderClassSource)) return true; return string.Equals(ClassName, shaderClassSource.ClassName) && GenericArguments.OrderBy(x => x).SequenceEqual(shaderClassSource.GenericArguments.OrderBy(x => x)); @@ -65,7 +53,7 @@ public bool Equals(ShaderClassSource shaderClassSource) public override bool Equals(object obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; return Equals((ShaderClassSource)obj); diff --git a/src/Stride.Shaders/ShaderSourceString.cs b/src/Stride.Shaders/ShaderClassString.cs similarity index 52% rename from src/Stride.Shaders/ShaderSourceString.cs rename to src/Stride.Shaders/ShaderClassString.cs index 1d2b945312..24949b843a 100644 --- a/src/Stride.Shaders/ShaderSourceString.cs +++ b/src/Stride.Shaders/ShaderClassString.cs @@ -8,10 +8,10 @@ namespace Stride.Shaders; -public class ShaderSourceString +public class ShaderClassString { public string Code { get; set; } - public string ClassName { get => AST != null ? AST.Name : string.Empty; } + public string ClassName { get; set; } public ShaderProgram? AST { get; set; } string[] EntryPointNames = { "PSMain", @@ -24,7 +24,7 @@ public class ShaderSourceString ShaderMixinParser Parser { get; set; } - public ShaderSourceString(string code, ShaderMixinParser parser) + public ShaderClassString(string code, ShaderMixinParser parser) { Code = code; Parser = parser; @@ -37,36 +37,32 @@ public void Parse() public IEnumerable GetStreamValues() { - if (AST is not null) - return - from e in AST.Body - where e is ShaderValueDeclaration v - && v.IsStream - select e as ShaderValueDeclaration; - else - throw new Exception("AST is null"); + return + from e in AST?.Body + where e is ShaderValueDeclaration v + && v.IsStream + select e as ShaderValueDeclaration; + } + + public ShaderMethod GetEntryPoint(EntryPoints entry) + { + return AST?.Body.First(e => e is ShaderMethod m && m.Name == entry.ToString()) as ShaderMethod; } public IEnumerable GetEntryPoints() { - if (AST is not null) - return - from e in AST.Body + return + from e in AST?.Body where e is ShaderMethod method && EntryPointNames.Contains(method.Name) select e as ShaderMethod; - else - throw new Exception("AST is null"); } public IEnumerable GetMethods() { - if (AST is not null) - return - from e in AST.Body - where e is ShaderMethod method - && !EntryPointNames.Contains(method.Name) - select e as ShaderMethod; - else - throw new Exception("AST is null"); + return + from e in AST?.Body + where e is ShaderMethod method + && !EntryPointNames.Contains(method.Name) + select e as ShaderMethod; } diff --git a/src/Stride.Shaders/ShaderResult.cs b/src/Stride.Shaders/ShaderResult.cs new file mode 100644 index 0000000000..cb502bc031 --- /dev/null +++ b/src/Stride.Shaders/ShaderResult.cs @@ -0,0 +1,22 @@ +namespace Stride.Shaders; + +public struct ShaderResult +{ + private readonly T? value; + private readonly E? error; + + public bool isOk; + + public ShaderResult(T v) + { + value = v; + error = default; + isOk = true; + } + public ShaderResult(E e) + { + error = e; + value = default; + isOk = false; + } +} From 0f8c4bc20007a3471dd084102f938748b1b53ded Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 7 Jun 2022 08:09:00 +0200 Subject: [PATCH 0109/1182] Documentation --- src/Stride.Shaders/Compiler/Compilation.md | 8 ++++++++ src/Stride.Shaders/Compiler/{ReadMe.md => Composition.md} | 0 2 files changed, 8 insertions(+) create mode 100644 src/Stride.Shaders/Compiler/Compilation.md rename src/Stride.Shaders/Compiler/{ReadMe.md => Composition.md} (100%) diff --git a/src/Stride.Shaders/Compiler/Compilation.md b/src/Stride.Shaders/Compiler/Compilation.md new file mode 100644 index 0000000000..00d9dd97f1 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Compilation.md @@ -0,0 +1,8 @@ +# Compilation + +SDSL should first be lowered to a three address code that ressembles SPIRV. +The idea is to manage this intermediate code for optimization of code instead of using `spirv-tools` which are c++ libraries. + +## Lowering + +Lowering will be done by \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ReadMe.md b/src/Stride.Shaders/Compiler/Composition.md similarity index 100% rename from src/Stride.Shaders/Compiler/ReadMe.md rename to src/Stride.Shaders/Compiler/Composition.md From 6935b16db2111a49dd867f79908c7dc7ec39e8b3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 7 Jun 2022 18:38:00 +0200 Subject: [PATCH 0110/1182] re structure + statement containing registers --- src/Spv.Generator | 2 +- .../Parsers/AST/Shader/ShaderElements.cs | 91 +++++++++++++++++++ .../Parsers/AST/Shader/ShaderProgram.cs | 83 ----------------- .../Parsers/AST/Shader/Statements.cs | 5 +- 4 files changed, 96 insertions(+), 85 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs diff --git a/src/Spv.Generator b/src/Spv.Generator index 37797c7b04..07c29410e5 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 37797c7b044d279d11d7cd134db19e2768cc5003 +Subproject commit 07c29410e56358f71467c2ba264124505db064f3 diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs new file mode 100644 index 0000000000..8328c3a350 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -0,0 +1,91 @@ +using Eto.Parse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Parsing.AST.Shader; + +public class ResourceGroup : ShaderToken +{ + public IEnumerable Variables {get;set;} + + public ResourceGroup(Match m) + { + Match = m; + Variables = m["Variables"].Matches.Select(GetToken).ToList(); + + } +} +public class ConstantBuffer : ShaderToken +{ + public IEnumerable Variables {get;set;} + + public ConstantBuffer(Match m) + { + Match = m; + Variables = m["Variables"].Matches.Select(GetToken).ToList(); + + } +} +public class ShaderMethod : ShaderToken +{ + public bool IsStatic { get; set; } + public bool IsOverride { get; set; } + public bool IsStaged { get; set; } + + + public string Name { get; set; } + public string ReturnType { get; set; } + public IEnumerable ParameterList { get; set; } + public IEnumerable Statements { get; set; } + + public ShaderMethod(Match m) + { + Match = m; + IsStatic = m["Static"].Success; + IsOverride = m["Override"].Success; + IsStaged = m["Stage"].Success; + Name = m["MethodName"].StringValue; + ReturnType = m["ReturnType"].StringValue; + Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); + } +} + +public class ShaderValueDeclaration : ShaderToken +{ + public bool IsStream {get;set;} + public bool IsStaged {get;set;} + public string Name {get;set;} + public string Type {get;set;} + public string? Semantic { get; set; } + public ShaderToken Expression {get;set;} + + public ShaderValueDeclaration(Match m) + { + Match = m; + IsStream = m["Stream"].Success; + IsStaged = m["Stage"].Success; + Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; + Type = m["TypeName"].StringValue; + Name = m["VariableTerm"].StringValue; + } +} +public class Generics : ShaderToken +{ + public string Type { get; set; } + public string Name { get; set; } +} + +public class ShaderGenerics : ShaderToken +{ + public string Name { get; set; } + public IEnumerable Generics { get; set; } +} + +public class Mixin : ShaderToken +{ + public string Name { get; set; } + public IEnumerable GenericsValues { get; set; } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index 53b2970d0b..c2f759070e 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -7,89 +7,6 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class ResourceGroup : ShaderToken -{ - public IEnumerable Variables {get;set;} - - public ResourceGroup(Match m) - { - Match = m; - Variables = m["Variables"].Matches.Select(GetToken).ToList(); - - } -} -public class ConstantBuffer : ShaderToken -{ - public IEnumerable Variables {get;set;} - - public ConstantBuffer(Match m) - { - Match = m; - Variables = m["Variables"].Matches.Select(GetToken).ToList(); - - } -} -public class ShaderMethod : ShaderToken -{ - public bool IsStatic { get; set; } - public bool IsOverride { get; set; } - public bool IsStaged { get; set; } - - - public string Name { get; set; } - public string ReturnType { get; set; } - public IEnumerable ParameterList { get; set; } - public IEnumerable Statements { get; set; } - - public ShaderMethod(Match m) - { - Match = m; - IsStatic = m["Static"].Success; - IsOverride = m["Override"].Success; - IsStaged = m["Stage"].Success; - Name = m["MethodName"].StringValue; - ReturnType = m["ReturnType"].StringValue; - Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); - } -} - -public class ShaderValueDeclaration : ShaderToken -{ - public bool IsStream {get;set;} - public bool IsStaged {get;set;} - public string Name {get;set;} - public string Type {get;set;} - public string? Semantic { get; set; } - public ShaderToken Expression {get;set;} - - public ShaderValueDeclaration(Match m) - { - Match = m; - IsStream = m["Stream"].Success; - IsStaged = m["Stage"].Success; - Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; - Type = m["TypeName"].StringValue; - Name = m["VariableTerm"].StringValue; - } -} -public class Generics : ShaderToken -{ - public string Type { get; set; } - public string Name { get; set; } -} - -public class ShaderGenerics : ShaderToken -{ - public string Name { get; set; } - public IEnumerable Generics { get; set; } -} - -public class Mixin : ShaderToken -{ - public string Name { get; set; } - public IEnumerable GenericsValues { get; set; } -} - public class ShaderProgram : ShaderToken { public string Name {get;set;} diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 3bfa2acfab..446aa74561 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -10,7 +10,10 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public abstract class Statement : ShaderToken {} +public class Statement : ShaderToken +{ + public List LowCode {get;set;} = new(); +} public class EmptyStatement : Statement {} From 9d7fbc62e0315bcb571e5ce31782912f4c0295e6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Tue, 7 Jun 2022 19:01:05 +0200 Subject: [PATCH 0111/1182] restructure --- src/SDSLParserExample/Program.cs | 20 +++++++++---------- src/Spv.Generator | 2 +- .../{Lowering.cs => ShaderMixer.Lowering.cs} | 15 +++++++------- .../{ => Compiler}/ShaderMixer.cs | 6 ++++-- 4 files changed, 23 insertions(+), 20 deletions(-) rename src/Stride.Shaders/Compiler/{Lowering.cs => ShaderMixer.Lowering.cs} (76%) rename src/Stride.Shaders/{ => Compiler}/ShaderMixer.cs (85%) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3798cc2f6e..60a1b27568 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -21,16 +21,16 @@ static void ThreeAddress(string code) var parser = new ShaderMixinParser(); - ShaderProgram? ast = parser.Parse(code) as ShaderProgram; - var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; - var s = new Stopwatch(); - _ = Lowering.LowerToken(declare).ToList(); - - s.Start(); - var x = Lowering.LowerToken(declare).ToList(); - s.Stop(); - x.ForEach(Console.WriteLine); - Console.WriteLine(s.Elapsed); + // ShaderProgram? ast = parser.Parse(code) as ShaderProgram; + // var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; + // var s = new Stopwatch(); + // _ = Lowering.LowerToken(declare).ToList(); + + // s.Start(); + // var x = Lowering.LowerToken(declare).ToList(); + // s.Stop(); + // x.ForEach(Console.WriteLine); + // Console.WriteLine(s.Elapsed); } diff --git a/src/Spv.Generator b/src/Spv.Generator index 07c29410e5..37797c7b04 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 07c29410e56358f71467c2ba264124505db064f3 +Subproject commit 37797c7b044d279d11d7cd134db19e2768cc5003 diff --git a/src/Stride.Shaders/Compiler/Lowering.cs b/src/Stride.Shaders/Compiler/ShaderMixer.Lowering.cs similarity index 76% rename from src/Stride.Shaders/Compiler/Lowering.cs rename to src/Stride.Shaders/Compiler/ShaderMixer.Lowering.cs index 45724a6a45..e087af24f7 100644 --- a/src/Stride.Shaders/Compiler/Lowering.cs +++ b/src/Stride.Shaders/Compiler/ShaderMixer.Lowering.cs @@ -1,10 +1,11 @@ +using Stride.Shaders.Compiling; using Stride.Shaders.Parsing.AST.Shader; -namespace Stride.Shaders.Compiling; +namespace Stride.Shaders; -public static class Lowering +public partial class ShaderMixer { - public static IEnumerable LowerToken(ShaderToken token) + public IEnumerable LowerToken(ShaderToken token) { return token switch @@ -17,7 +18,7 @@ public static IEnumerable LowerToken(ShaderToken token) }; } - static IEnumerable Lower(DeclareAssign s) + IEnumerable Lower(DeclareAssign s) { var v = LowerToken(s.Value); return v.Append( @@ -29,13 +30,13 @@ static IEnumerable Lower(DeclareAssign s) ); } - static IEnumerable Lower(ConditionalExpression cexp) + IEnumerable Lower(ConditionalExpression cexp) { var result = new List(); return result; } - static IEnumerable Lower(Operation o) + IEnumerable Lower(Operation o) { IEnumerable l = LowerToken(o.Left); IEnumerable r = LowerToken(o.Right); @@ -50,7 +51,7 @@ static IEnumerable Lower(Operation o) ); } - static IEnumerable Lower(ShaderLiteral lit) + IEnumerable Lower(ShaderLiteral lit) { return new List{ lit switch { diff --git a/src/Stride.Shaders/ShaderMixer.cs b/src/Stride.Shaders/Compiler/ShaderMixer.cs similarity index 85% rename from src/Stride.Shaders/ShaderMixer.cs rename to src/Stride.Shaders/Compiler/ShaderMixer.cs index 64fd231239..971fbcdff5 100644 --- a/src/Stride.Shaders/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/ShaderMixer.cs @@ -6,13 +6,15 @@ using Spv.Generator; using Stride.Shaders.Parsing; -namespace Stride.Shaders; +namespace Stride.Shaders.Compiling; -public class ShaderMixer : ShaderSource +public partial class ShaderMixer : ShaderSource { public ShaderMixinParser Parser {get;set;} public List Mixins { get; set; } = new(); + public Dictionary Variables = new(); + public ShaderMixer() { Parser = new(); From 128dd221ebd9ba1de4867e8418440ccd1c37650d Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 10 Jun 2022 16:36:34 +0200 Subject: [PATCH 0112/1182] some ideas --- src/Spv.Generator | 2 +- .../Compiler/MixinVirtualTable.cs | 10 ++++++++ src/Stride.Shaders/Compiler/ShaderMixer.cs | 21 +++++++--------- .../Compiler/ThreeAddressElement.cs | 2 +- .../Parsers/AST/Shader/ShaderElements.cs | 4 ++-- .../Parsers/AST/Shader/ShaderToken.cs | 2 +- .../Parsers/ShaderMixinParser.cs | 5 ++++ src/Stride.Shaders/ShaderClassString.cs | 24 +++++++++---------- src/Stride.Shaders/ShaderMixin.cs | 6 ++--- 9 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 src/Stride.Shaders/Compiler/MixinVirtualTable.cs diff --git a/src/Spv.Generator b/src/Spv.Generator index 37797c7b04..72fd78e4a8 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 37797c7b044d279d11d7cd134db19e2768cc5003 +Subproject commit 72fd78e4a8417c970e3bda6474f88c274645d902 diff --git a/src/Stride.Shaders/Compiler/MixinVirtualTable.cs b/src/Stride.Shaders/Compiler/MixinVirtualTable.cs new file mode 100644 index 0000000000..19bda27c43 --- /dev/null +++ b/src/Stride.Shaders/Compiler/MixinVirtualTable.cs @@ -0,0 +1,10 @@ +using Stride.Shaders.Parsing.AST.Shader; + +namespace Stride.Shaders.Compiling; + + +public class MixinVirtualTable +{ + public List? Methods {get;set;} + public List? Variables {get;set;} +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ShaderMixer.cs b/src/Stride.Shaders/Compiler/ShaderMixer.cs index 971fbcdff5..23e94fea7a 100644 --- a/src/Stride.Shaders/Compiler/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/ShaderMixer.cs @@ -10,24 +10,21 @@ namespace Stride.Shaders.Compiling; public partial class ShaderMixer : ShaderSource { - public ShaderMixinParser Parser {get;set;} - public List Mixins { get; set; } = new(); + public ShaderSource Mixins { get; set; } + public MixinVirtualTable LocalVTable {get;set;} + + public MixinVirtualTable VirtualVTable {get;set;} public Dictionary Variables = new(); - public ShaderMixer() - { - Parser = new(); - } - public ShaderMixer(ShaderMixinParser parser) + public ShaderMixer(string code) { - Parser = parser; - } - public void Add(string mixin) - { - Mixins.Add(new ShaderMixin(mixin,Parser)); } + // public ShaderMixer(string code, Dictionary macros) + // { + + // } public override object Clone() { diff --git a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/ThreeAddressElement.cs index 5b31fabb5d..08a90375fd 100644 --- a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/ThreeAddressElement.cs @@ -10,7 +10,7 @@ namespace Stride.Shaders.Compiling; public class Register { - private string name; + private string? name; public string Name { get => name ?? "id_" + GetHashCode(); diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 8328c3a350..639307b65b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -53,7 +53,7 @@ public ShaderMethod(Match m) } } -public class ShaderValueDeclaration : ShaderToken +public class ShaderVariableDeclaration : ShaderToken { public bool IsStream {get;set;} public bool IsStaged {get;set;} @@ -62,7 +62,7 @@ public class ShaderValueDeclaration : ShaderToken public string? Semantic { get; set; } public ShaderToken Expression {get;set;} - public ShaderValueDeclaration(Match m) + public ShaderVariableDeclaration(Match m) { Match = m; IsStream = m["Stream"].Success; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index d33e08fa97..bdeb03d019 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -31,7 +31,7 @@ public static ShaderToken GetToken(Match match) "ShaderProgram" => new ShaderProgram(tmp), "ResourceGroup" => new ResourceGroup(tmp), "ConstantBuffer" => new ConstantBuffer(tmp), - "ShaderValueDeclaration" => new ShaderValueDeclaration(tmp), + "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp), "Method" => new ShaderMethod(tmp), "ControlFlow" => ControlFlow.Create(tmp), "Block" => new BlockStatement(tmp), diff --git a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs index 2e5eff4e10..56f71863c5 100644 --- a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs +++ b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs @@ -14,6 +14,11 @@ namespace Stride.Shaders.Parsing; public class ShaderMixinParser { + + private static readonly ShaderMixinParser instance = new(); + public static ShaderProgram ParseShader(string shader) => (ShaderProgram)instance.Parse(shader); + + public SDSLGrammar Grammar {get;set;} public DirectivePreprocessor DPreprocessor { get; set; } public Preprocessor Preprocessor { get; set; } diff --git a/src/Stride.Shaders/ShaderClassString.cs b/src/Stride.Shaders/ShaderClassString.cs index 24949b843a..226af0e0e0 100644 --- a/src/Stride.Shaders/ShaderClassString.cs +++ b/src/Stride.Shaders/ShaderClassString.cs @@ -10,10 +10,7 @@ namespace Stride.Shaders; public class ShaderClassString { - public string Code { get; set; } - public string ClassName { get; set; } - public ShaderProgram? AST { get; set; } - string[] EntryPointNames = { + static string[] EntryPointNames = { "PSMain", "VSMain", "GSMain", @@ -22,29 +19,32 @@ public class ShaderClassString "CSMain" }; - ShaderMixinParser Parser { get; set; } - public ShaderClassString(string code, ShaderMixinParser parser) + public string Code { get; set; } + public string ClassName => AST is null ? "" : AST.Name; + public ShaderProgram? AST { get; set; } + + public ShaderClassString(string code) { Code = code; - Parser = parser; + AST = ShaderMixinParser.ParseShader(code); } public void Parse() { - AST = (ShaderProgram)Parser.Parse(Code); + AST = ShaderMixinParser.ParseShader(Code); } - public IEnumerable GetStreamValues() + public IEnumerable GetStreamValues() { return from e in AST?.Body - where e is ShaderValueDeclaration v + where e is ShaderVariableDeclaration v && v.IsStream - select e as ShaderValueDeclaration; + select e as ShaderVariableDeclaration; } - public ShaderMethod GetEntryPoint(EntryPoints entry) + public ShaderMethod? GetEntryPoint(EntryPoints entry) { return AST?.Body.First(e => e is ShaderMethod m && m.Name == entry.ToString()) as ShaderMethod; } diff --git a/src/Stride.Shaders/ShaderMixin.cs b/src/Stride.Shaders/ShaderMixin.cs index 3be73ea421..0ce75de169 100644 --- a/src/Stride.Shaders/ShaderMixin.cs +++ b/src/Stride.Shaders/ShaderMixin.cs @@ -35,14 +35,14 @@ public void Parse() AST = (ShaderProgram)Parser.Parse(Code); } - public IEnumerable GetStreamValues() + public IEnumerable GetStreamValues() { if (AST is not null) return from e in AST.Body - where e is ShaderValueDeclaration v + where e is ShaderVariableDeclaration v && v.IsStream - select e as ShaderValueDeclaration; + select e as ShaderVariableDeclaration; else throw new Exception("AST is null"); } From 83e56170d64fbfb35696368054ef7c1c31a6de3e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 17 Jun 2022 18:21:56 +0200 Subject: [PATCH 0113/1182] restructure --- .../Compiler/Mixer/ShaderSource.cs | 13 ++++++ .../Compiler/Mixer/ShaderStringSource.cs | 45 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs new file mode 100644 index 0000000000..3719c61344 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs @@ -0,0 +1,13 @@ +namespace Stride.Shaders.Mixer; +public abstract class ShaderSource +{ + public bool Discard { get; set; } + + public abstract void EnumerateMixins(SortedSet shaderSources); + + public abstract object Clone(); + + public abstract override bool Equals(object against); + + public abstract override int GetHashCode(); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs new file mode 100644 index 0000000000..72febecd5f --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Mixer; + +public class ShaderStringSource : ShaderSource +{ + + public string Code { get; set; } + public string ClassName => AST is null ? "" : AST.Name; + public ShaderProgram? AST { get; set; } + + public ShaderStringSource(string code) + { + Code = code; + AST = ShaderMixinParser.ParseShader(code); + } + + public override object Clone() + { + return new ShaderStringSource(Code); + } + + public override bool Equals(object against) + { + return against is ShaderStringSource other + && this.Code == other.Code + && this.AST == other.AST; + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + + public override void EnumerateMixins(SortedSet shaderSources) + { + throw new NotImplementedException(); + } +} From 75217f3354b06d608133bf690e43d3a026078e61 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 17 Jun 2022 18:22:16 +0200 Subject: [PATCH 0114/1182] Compiler changes --- .../Compiler/Emitter/SpirvEmitter.Types.cs | 2 +- .../Compiler/Emitter/SpirvEmitter.cs | 4 +- .../{ => Emitter}/ThreeAddressElement.cs | 2 +- .../{ => Compiler/Mixer}/EntryPoints.cs | 2 +- .../Compiler/Mixer/ShaderArraySource.cs | 60 ++++++++++++++++ .../{ => Compiler/Mixer}/ShaderClassCode.cs | 2 +- .../{ => Compiler/Mixer}/ShaderClassSource.cs | 7 +- .../{ => Mixer}/ShaderMixer.Lowering.cs | 0 .../Compiler/{ => Mixer}/ShaderMixer.cs | 26 ++++--- .../{ => Compiler/Mixer}/ShaderMixin.cs | 2 +- .../{ => Compiler/Mixer}/ShaderResult.cs | 2 +- .../Compiler/Mixer/ShaderSourceCollection.cs | 48 +++++++++++++ .../Compiler/MixinVirtualTable.cs | 10 --- src/Stride.Shaders/Compiler/ShaderCompiler.cs | 14 ---- src/Stride.Shaders/ShaderClassString.cs | 69 ------------------- src/Stride.Shaders/ShaderSource.cs | 11 --- 16 files changed, 140 insertions(+), 121 deletions(-) rename src/Stride.Shaders/Compiler/{ => Emitter}/ThreeAddressElement.cs (97%) rename src/Stride.Shaders/{ => Compiler/Mixer}/EntryPoints.cs (75%) create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs rename src/Stride.Shaders/{ => Compiler/Mixer}/ShaderClassCode.cs (96%) rename src/Stride.Shaders/{ => Compiler/Mixer}/ShaderClassSource.cs (94%) rename src/Stride.Shaders/Compiler/{ => Mixer}/ShaderMixer.Lowering.cs (100%) rename src/Stride.Shaders/Compiler/{ => Mixer}/ShaderMixer.cs (58%) rename src/Stride.Shaders/{ => Compiler/Mixer}/ShaderMixin.cs (98%) rename src/Stride.Shaders/{ => Compiler/Mixer}/ShaderResult.cs (91%) create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs delete mode 100644 src/Stride.Shaders/Compiler/MixinVirtualTable.cs delete mode 100644 src/Stride.Shaders/Compiler/ShaderCompiler.cs delete mode 100644 src/Stride.Shaders/ShaderClassString.cs delete mode 100644 src/Stride.Shaders/ShaderSource.cs diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 34c54aba1b..4ba2f3c9f7 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -7,7 +7,7 @@ using Stride.Shaders.Parsing.AST.Shader; using static Spv.Specification; -namespace Stride.Shaders; +namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 1c41eaf029..e273bc6984 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -7,7 +7,7 @@ using Stride.Shaders.Parsing.AST.Shader; using static Spv.Specification; -namespace Stride.Shaders; +namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { @@ -16,7 +16,7 @@ public SpirvEmitter(uint version) : base(version) } - public void Construct(ShaderClassString code, EntryPoints entry) + public void Construct(ShaderStringSource code, EntryPoints entry) { AddCapability(Capability.Shader); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); diff --git a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs similarity index 97% rename from src/Stride.Shaders/Compiler/ThreeAddressElement.cs rename to src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index 08a90375fd..cba78c32c2 100644 --- a/src/Stride.Shaders/Compiler/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; using Stride.Shaders.Parsing.AST.Shader; -namespace Stride.Shaders.Compiling; +namespace Stride.Shaders.Spirv; public class Register diff --git a/src/Stride.Shaders/EntryPoints.cs b/src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs similarity index 75% rename from src/Stride.Shaders/EntryPoints.cs rename to src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs index 4b322631d5..f9c90526b4 100644 --- a/src/Stride.Shaders/EntryPoints.cs +++ b/src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders; +namespace Stride.Shaders.Mixer; public enum EntryPoints { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs new file mode 100644 index 0000000000..b57728d108 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs @@ -0,0 +1,60 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Mixer; + +public class ShaderArraySource : ShaderSource, IEnumerable, IEquatable +{ + + public ShaderArraySource() + { + Values = new(); + } + + ShaderSourceCollection Values {get;set;} + + public void Add(ShaderSource shader) + { + Values.Add(shader); + } + public void Add(string shader) + { + Values.Add(new ShaderStringSource(shader)); + } + + public override object Clone() + { + throw new NotImplementedException(); + } + + public override bool Equals(object against) + { + throw new NotImplementedException(); + } + + public bool Equals(ShaderArraySource? other) + { + throw new NotImplementedException(); + } + + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + throw new NotImplementedException(); + } +} diff --git a/src/Stride.Shaders/ShaderClassCode.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs similarity index 96% rename from src/Stride.Shaders/ShaderClassCode.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs index ba4d9a9cea..512c266125 100644 --- a/src/Stride.Shaders/ShaderClassCode.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs @@ -1,7 +1,7 @@ using System.Text; -namespace Stride.Shaders; +namespace Stride.Shaders.Mixer; public abstract class ShaderClassCode : ShaderSource { diff --git a/src/Stride.Shaders/ShaderClassSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs similarity index 94% rename from src/Stride.Shaders/ShaderClassSource.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs index 8e597e1688..a4fba961a8 100644 --- a/src/Stride.Shaders/ShaderClassSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace Stride.Shaders; +namespace Stride.Shaders.Mixer; public sealed class ShaderClassSource : ShaderClassCode, IEquatable { @@ -84,6 +84,11 @@ public override string ToString() return ToClassName(); } + public override void EnumerateMixins(SortedSet shaderSources) + { + throw new NotImplementedException(); + } + /// /// Performs an implicit conversion from to . /// diff --git a/src/Stride.Shaders/Compiler/ShaderMixer.Lowering.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs similarity index 100% rename from src/Stride.Shaders/Compiler/ShaderMixer.Lowering.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs diff --git a/src/Stride.Shaders/Compiler/ShaderMixer.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs similarity index 58% rename from src/Stride.Shaders/Compiler/ShaderMixer.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs index 23e94fea7a..c32a9ab432 100644 --- a/src/Stride.Shaders/Compiler/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs @@ -6,25 +6,35 @@ using Spv.Generator; using Stride.Shaders.Parsing; -namespace Stride.Shaders.Compiling; +namespace Stride.Shaders.Mixer; public partial class ShaderMixer : ShaderSource { public ShaderSource Mixins { get; set; } - public MixinVirtualTable LocalVTable {get;set;} - - public MixinVirtualTable VirtualVTable {get;set;} public Dictionary Variables = new(); public ShaderMixer(string code) { + Mixins = new ShaderStringSource(code); + } + public ShaderMixer(ShaderSource m) + { + Mixins = m; + } + public void AddMixin(ShaderSource mixin) + { + if(Mixins is ShaderStringSource sss) + { + var sas = new ShaderArraySource(); + sas.Add(Mixins); + sas.Add(mixin); + Mixins = sas; + } + else if(Mixins is ShaderArraySource sas) + sas.Add(mixin); } - // public ShaderMixer(string code, Dictionary macros) - // { - - // } public override object Clone() { diff --git a/src/Stride.Shaders/ShaderMixin.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs similarity index 98% rename from src/Stride.Shaders/ShaderMixin.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs index 0ce75de169..9afa6a177c 100644 --- a/src/Stride.Shaders/ShaderMixin.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs @@ -6,7 +6,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders; +namespace Stride.Shaders.Mixer; public class ShaderMixin { diff --git a/src/Stride.Shaders/ShaderResult.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs similarity index 91% rename from src/Stride.Shaders/ShaderResult.cs rename to src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs index cb502bc031..36d87d1af1 100644 --- a/src/Stride.Shaders/ShaderResult.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders; +namespace Stride.Shaders.Mixer; public struct ShaderResult { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs new file mode 100644 index 0000000000..c7309a6480 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs @@ -0,0 +1,48 @@ +namespace Stride.Shaders.Mixer; + +public sealed class ShaderSourceCollection : List +{ + public ShaderSourceCollection() + { + } + + public ShaderSourceCollection(IEnumerable collection) : base(collection) + { + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + foreach (var current in this) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + return hashCode; + } + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((ShaderSourceCollection)obj); + } + + public bool Equals(ShaderSourceCollection other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + if (Count != other.Count) + return false; + + for (int i = 0; i < Count; ++i) + { + if (!this[i].Equals(other[i])) + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/MixinVirtualTable.cs b/src/Stride.Shaders/Compiler/MixinVirtualTable.cs deleted file mode 100644 index 19bda27c43..0000000000 --- a/src/Stride.Shaders/Compiler/MixinVirtualTable.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Stride.Shaders.Parsing.AST.Shader; - -namespace Stride.Shaders.Compiling; - - -public class MixinVirtualTable -{ - public List? Methods {get;set;} - public List? Variables {get;set;} -} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ShaderCompiler.cs b/src/Stride.Shaders/Compiler/ShaderCompiler.cs deleted file mode 100644 index 4ffb0013bc..0000000000 --- a/src/Stride.Shaders/Compiler/ShaderCompiler.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stride.Shaders.Parsing; - -namespace Stride.Shaders.Compiling; - -public class ShaderCompiler -{ - public ShaderMixinParser Parser {get;set;} = new(); - public ShaderClassString Shader {get;set;} - - public void Compile(string shader, Dictionary macros) - { - - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderClassString.cs b/src/Stride.Shaders/ShaderClassString.cs deleted file mode 100644 index 226af0e0e0..0000000000 --- a/src/Stride.Shaders/ShaderClassString.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders; - -public class ShaderClassString -{ - static string[] EntryPointNames = { - "PSMain", - "VSMain", - "GSMain", - "HSMain", - "DSMain", - "CSMain" - }; - - - public string Code { get; set; } - public string ClassName => AST is null ? "" : AST.Name; - public ShaderProgram? AST { get; set; } - - public ShaderClassString(string code) - { - Code = code; - AST = ShaderMixinParser.ParseShader(code); - } - - public void Parse() - { - AST = ShaderMixinParser.ParseShader(Code); - } - - public IEnumerable GetStreamValues() - { - return - from e in AST?.Body - where e is ShaderVariableDeclaration v - && v.IsStream - select e as ShaderVariableDeclaration; - } - - public ShaderMethod? GetEntryPoint(EntryPoints entry) - { - return AST?.Body.First(e => e is ShaderMethod m && m.Name == entry.ToString()) as ShaderMethod; - } - public IEnumerable GetEntryPoints() - { - return - from e in AST?.Body - where e is ShaderMethod method - && EntryPointNames.Contains(method.Name) - select e as ShaderMethod; - } - public IEnumerable GetMethods() - { - return - from e in AST?.Body - where e is ShaderMethod method - && !EntryPointNames.Contains(method.Name) - select e as ShaderMethod; - } - - -} diff --git a/src/Stride.Shaders/ShaderSource.cs b/src/Stride.Shaders/ShaderSource.cs deleted file mode 100644 index 3c824cc60f..0000000000 --- a/src/Stride.Shaders/ShaderSource.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Stride.Shaders; -public abstract class ShaderSource -{ - public bool Discard { get; set; } - - public abstract object Clone(); - - public abstract override bool Equals(object against); - - public abstract override int GetHashCode(); -} \ No newline at end of file From 0cc7c1967f611686bc5dd649b67199f0edb2c487 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 29 Jun 2022 16:54:01 +0200 Subject: [PATCH 0115/1182] added mixin list and generics --- src/SDSLParserExample/Program.cs | 6 +++--- src/SDSLParserExample/SDSL/shader2.sdsl | 2 +- .../Compiler/Emitter/SpirvEmitter.cs | 1 + .../Compiler/Mixer/ShaderArraySource.cs | 11 ++++++++++- .../Compiler/Mixer/ShaderClassSource.cs | 4 ++++ .../Compiler/Mixer/ShaderMixer.Lowering.cs | 2 +- .../Compiler/Mixer/ShaderMixer.cs | 17 +---------------- .../Compiler/Mixer/ShaderSource.cs | 3 ++- .../Compiler/Mixer/ShaderStringSource.cs | 9 +++++++++ .../Parsers/AST/Shader/ShaderElements.cs | 11 +++++++++-- .../Parsers/AST/Shader/ShaderProgram.cs | 3 ++- .../Parsers/AST/Shader/Statements.cs | 3 ++- .../Grammars/SDSLGrammar/SDSLGrammar.Shader.cs | 7 ++++--- 13 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 60a1b27568..14744ecff0 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -9,12 +9,12 @@ using Stride.Core.Shaders.Parser; using Stride.Core.Shaders.Grammar.Stride; using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Compiling; +using Stride.Shaders.Mixer; var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); -// ShaderCompiling(); -ThreeAddress(shaderf); +ShaderCompiling(shaderf); +// ThreeAddress(shaderf); static void ThreeAddress(string code) { diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl index 3b6c0a218e..e4bda4e17a 100644 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ b/src/SDSLParserExample/SDSL/shader2.sdsl @@ -1,4 +1,4 @@ -shader Simple { +shader Simple : Parent<5, float, 12>, Parent2 { float a = 0; void VSMain(){ diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index e273bc6984..32fa8012f9 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -4,6 +4,7 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; +using Stride.Shaders.Mixer; using Stride.Shaders.Parsing.AST.Shader; using static Spv.Specification; diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs index b57728d108..200cea5244 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs @@ -16,7 +16,11 @@ public ShaderArraySource() { Values = new(); } - + + public override string ShaderName => throw new NotImplementedException(); + + public override IEnumerable Mixins => throw new NotImplementedException(); + ShaderSourceCollection Values {get;set;} public void Add(ShaderSource shader) @@ -33,6 +37,11 @@ public override object Clone() throw new NotImplementedException(); } + public override void EnumerateMixins(SortedSet shaderSources) + { + throw new NotImplementedException(); + } + public override bool Equals(object against) { throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs index a4fba961a8..593d8d6bab 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs @@ -4,6 +4,10 @@ namespace Stride.Shaders.Mixer; public sealed class ShaderClassSource : ShaderClassCode, IEquatable { + public override string ShaderName => throw new NotImplementedException(); + + public override IEnumerable Mixins => throw new NotImplementedException(); + public ShaderClassSource() { } diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs index e087af24f7..acba1c0e61 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs @@ -1,5 +1,5 @@ -using Stride.Shaders.Compiling; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Spirv; namespace Stride.Shaders; diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs index c32a9ab432..507e3253df 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs @@ -8,7 +8,7 @@ namespace Stride.Shaders.Mixer; -public partial class ShaderMixer : ShaderSource +public partial class ShaderMixer { public ShaderSource Mixins { get; set; } @@ -35,19 +35,4 @@ public void AddMixin(ShaderSource mixin) else if(Mixins is ShaderArraySource sas) sas.Add(mixin); } - - public override object Clone() - { - throw new NotImplementedException(); - } - - public override bool Equals(object against) - { - throw new NotImplementedException(); - } - - public override int GetHashCode() - { - throw new NotImplementedException(); - } } diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs index 3719c61344..20a06566a7 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs @@ -2,7 +2,8 @@ namespace Stride.Shaders.Mixer; public abstract class ShaderSource { public bool Discard { get; set; } - + public abstract string ShaderName {get;} + public abstract IEnumerable Mixins {get;} public abstract void EnumerateMixins(SortedSet shaderSources); public abstract object Clone(); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs index 72febecd5f..fe37bfa173 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs @@ -15,6 +15,10 @@ public class ShaderStringSource : ShaderSource public string ClassName => AST is null ? "" : AST.Name; public ShaderProgram? AST { get; set; } + public override string ShaderName => throw new NotImplementedException(); + + public override IEnumerable Mixins => throw new NotImplementedException(); + public ShaderStringSource(string code) { Code = code; @@ -42,4 +46,9 @@ public override void EnumerateMixins(SortedSet shaderSources) { throw new NotImplementedException(); } + + public override string? ToString() + { + return base.ToString(); + } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 639307b65b..088ddcdb57 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -84,8 +84,15 @@ public class ShaderGenerics : ShaderToken public IEnumerable Generics { get; set; } } -public class Mixin : ShaderToken +public class MixinToken : ShaderToken { public string Name { get; set; } - public IEnumerable GenericsValues { get; set; } + public List GenericsValues { get; set; } + + public MixinToken(Match m) + { + Match = m; + Name = m["Name"].StringValue; + GenericsValues = m["Generics"].Matches.Select(x => x.StringValue).ToList(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index c2f759070e..4dafa3a942 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -11,7 +11,7 @@ public class ShaderProgram : ShaderToken { public string Name {get;set;} public IEnumerable Generics { get; set; } - public IEnumerable Mixins { get; set; } + public IEnumerable Mixins { get; set; } public IEnumerable Body { get; set; } public ShaderProgram(Match m) @@ -19,5 +19,6 @@ public ShaderProgram(Match m) Match = m; Name = m["ShaderName"].StringValue; Body = m["Body"].Matches.Select(GetToken).ToList(); + Mixins = m["Mixins"].Matches.Select(x => new MixinToken(x)).ToList(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 446aa74561..b67a54158f 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -1,6 +1,7 @@ using Eto.Parse; using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Spirv; using System; using System.Collections.Generic; using System.Linq; @@ -12,7 +13,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class Statement : ShaderToken { - public List LowCode {get;set;} = new(); + public List LowCode {get;set;} = new(); } public class EmptyStatement : Statement {} diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 5af00eb23a..6a21b8fae8 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -72,7 +72,7 @@ public void CreateShader() "<", inheritGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), ">" - ){ Separator = ws, Name = "InheritanceGenerics"}; + ){ Separator = ws, Name = "Generics"}; var compositionDeclaration = new SequenceParser( Literal("compose"), @@ -106,10 +106,11 @@ public void CreateShader() var inheritances = Colon .Then( - Identifier.Then(inheritGenerics.Optional()).SeparatedBy(ws) + Identifier.Named("Name").Then(inheritGenerics.Optional()).SeparatedBy(ws).Named("Mixin") .Repeat(1).SeparatedBy(ws & Comma & ws) ) - .SeparatedBy(ws); + .SeparatedBy(ws) + .Named("Mixins"); From 07a32055da1537de73d3fd2bd2719ade16ba05ec Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 5 Jul 2022 14:35:42 +0200 Subject: [PATCH 0116/1182] use of dev branch --- src/Spv.Generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Spv.Generator b/src/Spv.Generator index 72fd78e4a8..6cd3ba989c 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 72fd78e4a8417c970e3bda6474f88c274645d902 +Subproject commit 6cd3ba989c09f1fd816dcdf7c89993e8a09e0ef8 From 2426259d1bbf3d6ad5c9f40c3fdf60aa738bb3c9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 6 Jul 2022 20:21:43 +0200 Subject: [PATCH 0117/1182] refactor + basic shader loading --- src/SDSLParserExample/Program.cs | 11 +++- .../Child.sdsl | 0 .../SDSL/MixinSamples/MyShader.sdsl | 8 +++ .../Parent.sdsl | 0 .../SDSL/MixinSamples/ShaderBase.sdsl | 8 +++ .../MixinSamples/ShaderBaseStream copy.sdsl | 32 ++++++++++ .../SDSL/MixinSamples/ShaderBaseStream.sdsl | 32 ++++++++++ src/Stride.Shaders/EffectCompiler.cs | 7 ++ .../Parsers/ShaderMixinParser.cs | 6 +- src/Stride.Shaders/ShaderLoader.cs | 6 ++ src/Stride.Shaders/ShaderSourceManager.cs | 64 +++++++++++++++++++ 11 files changed, 170 insertions(+), 4 deletions(-) rename src/SDSLParserExample/SDSL/{InheritExample => MixinSamples}/Child.sdsl (100%) create mode 100644 src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl rename src/SDSLParserExample/SDSL/{InheritExample => MixinSamples}/Parent.sdsl (100%) create mode 100644 src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl create mode 100644 src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl create mode 100644 src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl create mode 100644 src/Stride.Shaders/EffectCompiler.cs create mode 100644 src/Stride.Shaders/ShaderLoader.cs create mode 100644 src/Stride.Shaders/ShaderSourceManager.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 14744ecff0..3a1257f78f 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -10,11 +10,20 @@ using Stride.Core.Shaders.Grammar.Stride; using Stride.Shaders.Parsing.AST.Shader; using Stride.Shaders.Mixer; +using Stride.Shaders; var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); -ShaderCompiling(shaderf); +// ShaderCompiling(shaderf); // ThreeAddress(shaderf); +LoadShaders(); + +static void LoadShaders() +{ + var sources = new ShaderSourceManager(); + sources.AddDirectory("./SDSL/MixinSamples"); + var x = 0; +} static void ThreeAddress(string code) { diff --git a/src/SDSLParserExample/SDSL/InheritExample/Child.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/Child.sdsl similarity index 100% rename from src/SDSLParserExample/SDSL/InheritExample/Child.sdsl rename to src/SDSLParserExample/SDSL/MixinSamples/Child.sdsl diff --git a/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl new file mode 100644 index 0000000000..c0efe71131 --- /dev/null +++ b/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl @@ -0,0 +1,8 @@ +shader MyShader : ShaderBase +{ + + void VSMain() + { + + } +} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/Parent.sdsl similarity index 100% rename from src/SDSLParserExample/SDSL/InheritExample/Parent.sdsl rename to src/SDSLParserExample/SDSL/MixinSamples/Parent.sdsl diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl new file mode 100644 index 0000000000..9edca0ed3c --- /dev/null +++ b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl @@ -0,0 +1,8 @@ +shader ShaderBase : ShaderBaseStream +{ + // Declare Vertex shader main method + stage void VSMain() {} + + // Declare Pixel shader main method + stage void PSMain() {} +}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl new file mode 100644 index 0000000000..bf1fa67566 --- /dev/null +++ b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl @@ -0,0 +1,32 @@ +shader ShaderBaseStream +{ + // Default SV_POSITION output for VS/GS shaders + stage stream float4 ShadingPosition : SV_Position; + +/* +#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 + // Positive if this face is a front face, negative otherwise + stage stream float IsFrontFace : VFACE; +#else + // True if this face is a front face + stage stream bool IsFrontFace : SV_IsFrontFace; +#endif +*/ + // Default COLOR outputs for PS shader + stage stream float4 ColorTarget : SV_Target0; + stage stream float4 ColorTarget1 : SV_Target1; + stage stream float4 ColorTarget2 : SV_Target2; + stage stream float4 ColorTarget3 : SV_Target3; + stage stream float4 ColorTarget4 : SV_Target4; + stage stream float4 ColorTarget5 : SV_Target5; + stage stream float4 ColorTarget6 : SV_Target6; + stage stream float4 ColorTarget7 : SV_Target7; + + // Default DEPTH output for PS shader + stage stream float Depth : SV_Depth; + stage stream float DepthGreater : SV_DepthGreater; // Special output after PS + stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS + + // Default InstanceId for VS/GS shaders + stage stream uint InstanceID : SV_InstanceID; +}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl new file mode 100644 index 0000000000..bf1fa67566 --- /dev/null +++ b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl @@ -0,0 +1,32 @@ +shader ShaderBaseStream +{ + // Default SV_POSITION output for VS/GS shaders + stage stream float4 ShadingPosition : SV_Position; + +/* +#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 + // Positive if this face is a front face, negative otherwise + stage stream float IsFrontFace : VFACE; +#else + // True if this face is a front face + stage stream bool IsFrontFace : SV_IsFrontFace; +#endif +*/ + // Default COLOR outputs for PS shader + stage stream float4 ColorTarget : SV_Target0; + stage stream float4 ColorTarget1 : SV_Target1; + stage stream float4 ColorTarget2 : SV_Target2; + stage stream float4 ColorTarget3 : SV_Target3; + stage stream float4 ColorTarget4 : SV_Target4; + stage stream float4 ColorTarget5 : SV_Target5; + stage stream float4 ColorTarget6 : SV_Target6; + stage stream float4 ColorTarget7 : SV_Target7; + + // Default DEPTH output for PS shader + stage stream float Depth : SV_Depth; + stage stream float DepthGreater : SV_DepthGreater; // Special output after PS + stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS + + // Default InstanceId for VS/GS shaders + stage stream uint InstanceID : SV_InstanceID; +}; \ No newline at end of file diff --git a/src/Stride.Shaders/EffectCompiler.cs b/src/Stride.Shaders/EffectCompiler.cs new file mode 100644 index 0000000000..743be64846 --- /dev/null +++ b/src/Stride.Shaders/EffectCompiler.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders; + +public class EffectCompiler +{ + public ShaderLoader ShaderLoader {get;set;} + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs index 56f71863c5..d364d0a6b0 100644 --- a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs +++ b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs @@ -16,7 +16,7 @@ public class ShaderMixinParser { private static readonly ShaderMixinParser instance = new(); - public static ShaderProgram ParseShader(string shader) => (ShaderProgram)instance.Parse(shader); + public static ShaderProgram ParseShader(string shader) => instance.Parse(shader); public SDSLGrammar Grammar {get;set;} @@ -97,13 +97,13 @@ public string PreProcess(string code) return textBuilder.ToString(); } - public ShaderToken Parse(string shader) + public ShaderProgram Parse(string shader) { var code = PreProcess(shader); ParseTree = Grammar.Match(code); if (!ParseTree.Success) throw new Exception(ParseTree.ErrorMessage); - return ShaderToken.GetToken(ParseTree); + return (ShaderProgram)ShaderToken.GetToken(ParseTree); //return null; } diff --git a/src/Stride.Shaders/ShaderLoader.cs b/src/Stride.Shaders/ShaderLoader.cs new file mode 100644 index 0000000000..0c93b871e4 --- /dev/null +++ b/src/Stride.Shaders/ShaderLoader.cs @@ -0,0 +1,6 @@ +namespace Stride.Shaders; + +public class ShaderLoader +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderSourceManager.cs b/src/Stride.Shaders/ShaderSourceManager.cs new file mode 100644 index 0000000000..34f5025a98 --- /dev/null +++ b/src/Stride.Shaders/ShaderSourceManager.cs @@ -0,0 +1,64 @@ +using System.Diagnostics.CodeAnalysis; + +namespace Stride.Shaders; + +public class ShaderSourceManager +{ + + private readonly object locker = new object(); + private readonly Dictionary loadedShaderSources = new(); + private readonly Dictionary classNameToPath = new(); + private HashSet shaders = new(); + + private List lookups = new(); + + private const string DefaultEffectFileExtension = ".sdsl"; + + public ShaderSourceManager() { } + + + public void AddDirectory(string path) + { + lookups.Add(path); + foreach(var p in lookups) + { + Directory.EnumerateFiles(p,"*.sdsl",SearchOption.AllDirectories) + .Select(x => new ShaderSourceWithHash{ Path = x, Source = File.ReadAllText(x)}) + .ToList().ForEach(_ => shaders.Add(_)); + } + } + + + public void AddShaderSource(string className, string source, string path) + { + var shaderSource = new ShaderSourceWithHash { Path = path, Source = source }; + loadedShaderSources[className] = shaderSource; + classNameToPath[className] = path; + } + + public static ShaderSourceWithHash CreateShaderSourceWithHash(string type, string source) + { + return new ShaderSourceWithHash + { + Path = type, + Source = source + }; + } + + public struct ShaderSourceWithHash + { + public string Source; + public string Path; + public int Hash => GetHashCode(); + + public override bool Equals([NotNullWhen(true)] object? obj) + { + return obj is ShaderSourceWithHash other + && other.Hash == this.Hash; + } + public override int GetHashCode() + { + return HashCode.Combine(Source); + } + } +} \ No newline at end of file From fdb8640d793a96a48a6673574045010d402b7278 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 9 Jul 2022 23:35:06 +0200 Subject: [PATCH 0118/1182] reformatting some code --- src/SDSLParserExample/Program.cs | 8 +- .../MixinSamples/ShaderBaseStream copy.sdsl | 32 ------ .../Compiler/Emitter/SpirvEmitter.cs | 2 +- .../Compiler/Mixer/ShaderArraySource.cs | 2 +- .../Compiler/Mixer/ShaderClassString.cs | 47 ++++++++ .../Compiler/Mixer/ShaderMixer.cs | 4 +- .../Compiler/Mixer/ShaderMixin.cs | 26 ++--- .../Compiler/Mixer/ShaderStringSource.cs | 54 ---------- src/Stride.Shaders/EffectCompiler.cs | 15 ++- .../SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- .../Grammars/SDSLGrammar/SDSLGrammar.cs | 2 +- .../Parsers/Grammars/SDSLMixinReader.cs | 101 ++++++++++++++++++ .../Parsers/ShaderMixinParser.cs | 12 +++ src/Stride.Shaders/ShaderLoader.cs | 11 ++ src/Stride.Shaders/ShaderSourceManager.cs | 6 ++ 15 files changed, 208 insertions(+), 116 deletions(-) delete mode 100644 src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs delete mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs create mode 100644 src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3a1257f78f..b3b0df5521 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -16,12 +16,12 @@ // ShaderCompiling(shaderf); // ThreeAddress(shaderf); -LoadShaders(); +LoadShaders(shaderf); -static void LoadShaders() +static void LoadShaders(string shaderf) { - var sources = new ShaderSourceManager(); - sources.AddDirectory("./SDSL/MixinSamples"); + var compiler = new EffectCompiler("./SDSL/MixinSamples"); + var mixin = new ShaderMixinParser(); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl deleted file mode 100644 index bf1fa67566..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream copy.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -shader ShaderBaseStream -{ - // Default SV_POSITION output for VS/GS shaders - stage stream float4 ShadingPosition : SV_Position; - -/* -#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 - // Positive if this face is a front face, negative otherwise - stage stream float IsFrontFace : VFACE; -#else - // True if this face is a front face - stage stream bool IsFrontFace : SV_IsFrontFace; -#endif -*/ - // Default COLOR outputs for PS shader - stage stream float4 ColorTarget : SV_Target0; - stage stream float4 ColorTarget1 : SV_Target1; - stage stream float4 ColorTarget2 : SV_Target2; - stage stream float4 ColorTarget3 : SV_Target3; - stage stream float4 ColorTarget4 : SV_Target4; - stage stream float4 ColorTarget5 : SV_Target5; - stage stream float4 ColorTarget6 : SV_Target6; - stage stream float4 ColorTarget7 : SV_Target7; - - // Default DEPTH output for PS shader - stage stream float Depth : SV_Depth; - stage stream float DepthGreater : SV_DepthGreater; // Special output after PS - stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS - - // Default InstanceId for VS/GS shaders - stage stream uint InstanceID : SV_InstanceID; -}; \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 32fa8012f9..e7d7e4c951 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -17,7 +17,7 @@ public SpirvEmitter(uint version) : base(version) } - public void Construct(ShaderStringSource code, EntryPoints entry) + public void Construct(ShaderClassString code, EntryPoints entry) { AddCapability(Capability.Shader); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs index 200cea5244..0931540d1f 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs @@ -29,7 +29,7 @@ public void Add(ShaderSource shader) } public void Add(string shader) { - Values.Add(new ShaderStringSource(shader)); + Values.Add(new ShaderClassString(shader)); } public override object Clone() diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs new file mode 100644 index 0000000000..2d2aee2062 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs @@ -0,0 +1,47 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Mixer; + +public class ShaderClassString : ShaderMixin +{ + string source; + public override string Code => source; + public override string ShaderName => AST.Name; + + + public ShaderClassString(string code) + { + this.source = code; + } + + public void Parse() + { + AST = ShaderMixinParser.ParseShader(source); + } + + public override object Clone() + { + throw new NotImplementedException(); + } + + public override void EnumerateMixins(SortedSet shaderSources) + { + throw new NotImplementedException(); + } + + public override bool Equals(object against) + { + throw new NotImplementedException(); + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } +} diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs index 507e3253df..c92c84da59 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs @@ -16,7 +16,7 @@ public partial class ShaderMixer public ShaderMixer(string code) { - Mixins = new ShaderStringSource(code); + Mixins = new ShaderClassString(code); } public ShaderMixer(ShaderSource m) { @@ -25,7 +25,7 @@ public ShaderMixer(ShaderSource m) public void AddMixin(ShaderSource mixin) { - if(Mixins is ShaderStringSource sss) + if(Mixins is ShaderClassString sss) { var sas = new ShaderArraySource(); sas.Add(Mixins); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs index 9afa6a177c..6f31e5ee2c 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs @@ -8,11 +8,14 @@ namespace Stride.Shaders.Mixer; -public class ShaderMixin +public abstract class ShaderMixin : ShaderSource { - public string Code { get; set; } - public string MixinName { get => AST != null ? AST.Name : string.Empty; } - public ShaderProgram? AST { get; set; } + public abstract string Code { get; } + public string? ClassName => AST?.Name; + public override IEnumerable Mixins => AST.Mixins.Select(x => x.Name).ToList(); + + public ShaderProgram AST { get; set; } + string[] EntryPointNames = { "PSMain", "VSMain", @@ -22,19 +25,6 @@ public class ShaderMixin "CSMain" }; - ShaderMixinParser Parser { get; set; } - - public ShaderMixin(string code, ShaderMixinParser parser) - { - Code = code; - Parser = parser; - } - - public void Parse() - { - AST = (ShaderProgram)Parser.Parse(Code); - } - public IEnumerable GetStreamValues() { if (AST is not null) @@ -68,6 +58,4 @@ where e is ShaderMethod method else throw new Exception("AST is null"); } - - } diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs deleted file mode 100644 index fe37bfa173..0000000000 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderStringSource.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Mixer; - -public class ShaderStringSource : ShaderSource -{ - - public string Code { get; set; } - public string ClassName => AST is null ? "" : AST.Name; - public ShaderProgram? AST { get; set; } - - public override string ShaderName => throw new NotImplementedException(); - - public override IEnumerable Mixins => throw new NotImplementedException(); - - public ShaderStringSource(string code) - { - Code = code; - AST = ShaderMixinParser.ParseShader(code); - } - - public override object Clone() - { - return new ShaderStringSource(Code); - } - - public override bool Equals(object against) - { - return against is ShaderStringSource other - && this.Code == other.Code - && this.AST == other.AST; - } - - public override int GetHashCode() - { - throw new NotImplementedException(); - } - - public override void EnumerateMixins(SortedSet shaderSources) - { - throw new NotImplementedException(); - } - - public override string? ToString() - { - return base.ToString(); - } -} diff --git a/src/Stride.Shaders/EffectCompiler.cs b/src/Stride.Shaders/EffectCompiler.cs index 743be64846..b1e7961f3b 100644 --- a/src/Stride.Shaders/EffectCompiler.cs +++ b/src/Stride.Shaders/EffectCompiler.cs @@ -1,7 +1,20 @@ +using Stride.Shaders.Mixer; +using Stride.Shaders.Parsing; + namespace Stride.Shaders; public class EffectCompiler { - public ShaderLoader ShaderLoader {get;set;} + public ShaderLoader Loader {get;set;} + + public EffectCompiler(string path) + { + Loader = new ShaderLoader(path); + } + + public void Compile(ShaderMixin mixin) + { + var mixer = new ShaderMixer(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 6a21b8fae8..60a992a5a4 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -17,7 +17,7 @@ public SDSLGrammar UsingShader() Inner = ShaderExpression; return this; } - public void CreateShader() + public virtual void CreateShader() { var ws = WhiteSpace.Repeat(0); var ws1 = WhiteSpace.Repeat(1); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs index 67c251017f..83d5b48bcc 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -17,7 +17,7 @@ public SDSLGrammar Using(Parser p) return this; } - public void CreateAll() + public virtual void CreateAll() { CreateTokens(); CreateTokenGroups(); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs new file mode 100644 index 0000000000..0684fe78e5 --- /dev/null +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs @@ -0,0 +1,101 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + +namespace Stride.Shaders.Parsing.Grammars.SDSL; +public class SDSLMixinReader : SDSLGrammar +{ + public override void CreateAll() + { + CreateTokens(); + CreateTokenGroups(); + CreateLiterals(); + CreateExpressions(); + } + public override void CreateShader() + { + var ws = WhiteSpace.Repeat(0); + var ws1 = WhiteSpace.Repeat(1); + + + var shaderGenericValue = new AlternativeParser( + Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), + Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(ws1).Named("Semantic"), + ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), + ValueTypes + ){ Name = "ShaderGeneric" }; + + var shaderGenerics = new SequenceParser( + "<", + shaderGenericValue.Repeat(1).SeparatedBy(ws & Comma & ws), + ">" + ){ Name = "ShaderGenerics", Separator = ws }; + + var inheritGenericsValues = new AlternativeParser( + ValueTypes, + Identifier, + Literals + ); + + var inheritGenerics = new SequenceParser( + "<", + inheritGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), + ">" + ){ Separator = ws, Name = "Generics"}; + + var compositionDeclaration = new SequenceParser( + Literal("compose"), + ws1, + Identifier.Named("MixinName"), + ws1, + Identifier.Named("Name"), + ws, + Semi + ){ Name = "CompositionDeclaration"}; + + + var shaderBody = new SequenceParser( + LeftBrace, + AnyChar.Repeat(0).Until("}"), + RightBrace + ) + {Name = "Body", Separator = ws}; + + var inheritances = + Colon + .Then( + Identifier.Named("Name").Then(inheritGenerics.Optional()).SeparatedBy(ws).Named("Mixin") + .Repeat(1).SeparatedBy(ws & Comma & ws) + ) + .SeparatedBy(ws) + .Named("Mixins"); + + + + ShaderExpression.Add( + Literal("shader") & ws1 & Identifier.Named("ShaderName"), + shaderGenerics.Optional(), + inheritances.Optional(), + shaderBody, + Semi + ); + ShaderExpression.Separator = ws; + ShaderExpression.Name = "ShaderProgram"; + + NamespaceExpression.Add( + ws, + Literal("namespace") & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("Namespace"), + LeftBrace, + ShaderExpression, + RightBrace, + ws + ); + NamespaceExpression.Separator = ws; + + ShaderFile.Add( + NamespaceExpression, + ws & ShaderExpression & ws + ); + this.Inner = ShaderFile; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs index d364d0a6b0..3af5b1d6c7 100644 --- a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs +++ b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs @@ -17,17 +17,22 @@ public class ShaderMixinParser private static readonly ShaderMixinParser instance = new(); public static ShaderProgram ParseShader(string shader) => instance.Parse(shader); + public static List GetMixins(string shader) => instance.ParseMixins(shader); + public SDSLGrammar Grammar {get;set;} public DirectivePreprocessor DPreprocessor { get; set; } public Preprocessor Preprocessor { get; set; } + public SDSLMixinReader MixinParser {get;set;} + public GrammarMatch? ParseTree { get; set; } public ShaderMixinParser() { Grammar = new(); + MixinParser = new(); DPreprocessor = new(); @@ -106,6 +111,13 @@ public ShaderProgram Parse(string shader) return (ShaderProgram)ShaderToken.GetToken(ParseTree); //return null; } + List ParseMixins(string shader) + { + var match = MixinParser.Match(shader); + if (!match.Success) + throw new Exception(match.ErrorMessage); + return new(); + } private static void PrettyPrintMatches(Match match, int depth = 0) { diff --git a/src/Stride.Shaders/ShaderLoader.cs b/src/Stride.Shaders/ShaderLoader.cs index 0c93b871e4..299775f110 100644 --- a/src/Stride.Shaders/ShaderLoader.cs +++ b/src/Stride.Shaders/ShaderLoader.cs @@ -2,5 +2,16 @@ namespace Stride.Shaders; public class ShaderLoader { + ShaderSourceManager ShaderResource = new(); + + public ShaderLoader(string path) + { + ShaderResource.AddDirectory(path); + } + + public string Get(string name) + { + return ShaderResource.GetShaderSource(name); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/ShaderSourceManager.cs b/src/Stride.Shaders/ShaderSourceManager.cs index 34f5025a98..33ae273780 100644 --- a/src/Stride.Shaders/ShaderSourceManager.cs +++ b/src/Stride.Shaders/ShaderSourceManager.cs @@ -36,6 +36,12 @@ public void AddShaderSource(string className, string source, string path) classNameToPath[className] = path; } + public string GetShaderSource(string className) + { + return loadedShaderSources[className].Source; + } + + public static ShaderSourceWithHash CreateShaderSourceWithHash(string type, string source) { return new ShaderSourceWithHash From 8b0525fa69cd5c7cbdf950724dd4034b0b2ca14b Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 9 Jul 2022 23:44:14 +0200 Subject: [PATCH 0119/1182] simple note --- src/Stride.Shaders/Compiler/Composition.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Composition.md b/src/Stride.Shaders/Compiler/Composition.md index 5798330ee6..341f82864d 100644 --- a/src/Stride.Shaders/Compiler/Composition.md +++ b/src/Stride.Shaders/Compiler/Composition.md @@ -14,6 +14,10 @@ A single shader should be a full shader, defining all methods and variables in o An array of shader will contain multiple shader definition all linked by inheritances. It can be created from one shader requiring parent shaders to find in a shader dictionary/storage of some sort. +## Mixin graph + +The graph that the mixin system forms will have to be simplified to an array shader. + ### Spirv design #### RGroup and CBuffer @@ -30,5 +34,3 @@ Temporary IDs will be generated (maybe GuID?) and later converted to actual avai Needs a bit of research. Instead of generating full methods, we generate a list of statements for each methods then combine them depending the order. - -## Mixin shader \ No newline at end of file From 41289406a8c13a1c4da728fe04fdeacffac78f74 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 11 Jul 2022 22:32:04 +0200 Subject: [PATCH 0120/1182] lil code update --- .../Compiler/Mixer/ShaderArraySource.cs | 6 +++++- .../Compiler/Mixer/ShaderClassSource.cs | 2 +- .../Compiler/Mixer/ShaderClassString.cs | 4 ++-- .../Compiler/Mixer/ShaderMixer.cs | 21 ++++++++++--------- .../Compiler/Mixer/ShaderMixin.cs | 14 ++++++------- .../Compiler/Mixer/ShaderSource.cs | 3 ++- 6 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs index 0931540d1f..d392cbf97e 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs @@ -16,10 +16,14 @@ public ShaderArraySource() { Values = new(); } + public ShaderArraySource(IEnumerable values) + { + Values = new ShaderSourceCollection(values); + } public override string ShaderName => throw new NotImplementedException(); - public override IEnumerable Mixins => throw new NotImplementedException(); + public override IEnumerable MixinNames => throw new NotImplementedException(); ShaderSourceCollection Values {get;set;} diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs index 593d8d6bab..52683d3ee0 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs @@ -6,7 +6,7 @@ public sealed class ShaderClassSource : ShaderClassCode, IEquatable throw new NotImplementedException(); - public override IEnumerable Mixins => throw new NotImplementedException(); + public override IEnumerable MixinNames => throw new NotImplementedException(); public ShaderClassSource() { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs index 2d2aee2062..9d9247797a 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs @@ -10,14 +10,14 @@ namespace Stride.Shaders.Mixer; public class ShaderClassString : ShaderMixin { - string source; + readonly string source; public override string Code => source; public override string ShaderName => AST.Name; public ShaderClassString(string code) { - this.source = code; + source = code; } public void Parse() diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs index c92c84da59..0b69825aee 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs @@ -11,25 +11,26 @@ namespace Stride.Shaders.Mixer; public partial class ShaderMixer { public ShaderSource Mixins { get; set; } + public ShaderLoader Loader {get;set;} public Dictionary Variables = new(); - public ShaderMixer(string code) + public ShaderMixer(string code, ShaderLoader loader) { - Mixins = new ShaderClassString(code); - } - public ShaderMixer(ShaderSource m) - { - Mixins = m; + Loader = loader; + var mixin = new ShaderClassString(code); + Mixins = new ShaderArraySource(mixin.MixinNames.Select(loader.Get).Select(x => new ShaderClassString(x))); } public void AddMixin(ShaderSource mixin) { - if(Mixins is ShaderClassString sss) + if (Mixins is ShaderClassString) { - var sas = new ShaderArraySource(); - sas.Add(Mixins); - sas.Add(mixin); + var sas = new ShaderArraySource + { + Mixins, + mixin + }; Mixins = sas; } else if(Mixins is ShaderArraySource sas) diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs index 6f31e5ee2c..a3cd9598a5 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs @@ -10,13 +10,7 @@ namespace Stride.Shaders.Mixer; public abstract class ShaderMixin : ShaderSource { - public abstract string Code { get; } - public string? ClassName => AST?.Name; - public override IEnumerable Mixins => AST.Mixins.Select(x => x.Name).ToList(); - - public ShaderProgram AST { get; set; } - - string[] EntryPointNames = { + static readonly string[] EntryPointNames = { "PSMain", "VSMain", "GSMain", @@ -25,6 +19,12 @@ public abstract class ShaderMixin : ShaderSource "CSMain" }; + public abstract string Code { get; } + public string? ClassName => AST?.Name; + public override IEnumerable MixinNames => AST.Mixins.Select(x => x.Name).ToList(); + + public ShaderProgram AST { get; set; } + public IEnumerable GetStreamValues() { if (AST is not null) diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs index 20a06566a7..a6008a34ee 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs @@ -3,7 +3,8 @@ public abstract class ShaderSource { public bool Discard { get; set; } public abstract string ShaderName {get;} - public abstract IEnumerable Mixins {get;} + public abstract IEnumerable MixinNames {get;} + public abstract void EnumerateMixins(SortedSet shaderSources); public abstract object Clone(); From 00835e713ca93682dd9719734d59c5d37c754779 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Jul 2022 18:13:28 +0200 Subject: [PATCH 0121/1182] Update on code to get closer to Stride --- src/Stride.Shaders/IShaderMixinBuilder.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/Stride.Shaders/IShaderMixinBuilder.cs diff --git a/src/Stride.Shaders/IShaderMixinBuilder.cs b/src/Stride.Shaders/IShaderMixinBuilder.cs new file mode 100644 index 0000000000..e55c536abe --- /dev/null +++ b/src/Stride.Shaders/IShaderMixinBuilder.cs @@ -0,0 +1,13 @@ +using Stride.Shaders.Mixer; + +namespace Stride.Shaders; + +public interface IShaderMixinBuilder +{ + /// + /// Generates a mixin. + /// + /// The mixin tree. + /// The context. + void Generate(ShaderMixinSource mixinTree, ShaderMixinContext context); +} \ No newline at end of file From 86bd4e23c134d623c27f64c4f2f036f6c01d3fd8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 29 Jul 2022 18:16:11 +0200 Subject: [PATCH 0122/1182] More changes --- src/Stride.Shaders/Compiler/Composition.md | 2 +- .../Compiler/Mixer/ShaderArraySource.cs | 11 +- .../Compiler/Mixer/ShaderClassSource.cs | 10 - .../Compiler/Mixer/ShaderClassString.cs | 19 +- .../Compiler/Mixer/ShaderMixer.cs | 39 -- .../Compiler/Mixer/ShaderMixin.cs | 61 --- .../Compiler/Mixer/ShaderMixinContext.cs | 350 ++++++++++++++++++ .../Mixer/ShaderMixinDiscardException.cs | 23 ++ .../Mixer/ShaderMixinGeneratorSource.cs | 70 ++++ .../Compiler/Mixer/ShaderMixinManager.cs | 142 +++++++ .../Compiler/Mixer/ShaderMixinSource.cs | 217 +++++++++++ .../Compiler/Mixer/ShaderSource.cs | 4 - src/Stride.Shaders/EffectCompiler.cs | 5 - src/Stride.Shaders/Stride.Shaders.csproj | 5 + 14 files changed, 812 insertions(+), 146 deletions(-) delete mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs delete mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs diff --git a/src/Stride.Shaders/Compiler/Composition.md b/src/Stride.Shaders/Compiler/Composition.md index 341f82864d..d07d18fc0c 100644 --- a/src/Stride.Shaders/Compiler/Composition.md +++ b/src/Stride.Shaders/Compiler/Composition.md @@ -14,7 +14,7 @@ A single shader should be a full shader, defining all methods and variables in o An array of shader will contain multiple shader definition all linked by inheritances. It can be created from one shader requiring parent shaders to find in a shader dictionary/storage of some sort. -## Mixin graph +## Shader mixin The graph that the mixin system forms will have to be simplified to an array shader. diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs index d392cbf97e..8f6a36cfb4 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs @@ -21,11 +21,7 @@ public ShaderArraySource(IEnumerable values) Values = new ShaderSourceCollection(values); } - public override string ShaderName => throw new NotImplementedException(); - - public override IEnumerable MixinNames => throw new NotImplementedException(); - - ShaderSourceCollection Values {get;set;} + public ShaderSourceCollection Values {get;set;} public void Add(ShaderSource shader) { @@ -41,11 +37,6 @@ public override object Clone() throw new NotImplementedException(); } - public override void EnumerateMixins(SortedSet shaderSources) - { - throw new NotImplementedException(); - } - public override bool Equals(object against) { throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs index 52683d3ee0..1473bd9341 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs @@ -4,10 +4,6 @@ namespace Stride.Shaders.Mixer; public sealed class ShaderClassSource : ShaderClassCode, IEquatable { - public override string ShaderName => throw new NotImplementedException(); - - public override IEnumerable MixinNames => throw new NotImplementedException(); - public ShaderClassSource() { } @@ -87,12 +83,6 @@ public override string ToString() { return ToClassName(); } - - public override void EnumerateMixins(SortedSet shaderSources) - { - throw new NotImplementedException(); - } - /// /// Performs an implicit conversion from to . /// diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs index 9d9247797a..16fcb2d56d 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs @@ -8,21 +8,13 @@ namespace Stride.Shaders.Mixer; -public class ShaderClassString : ShaderMixin +public class ShaderClassString : ShaderSource { - readonly string source; - public override string Code => source; - public override string ShaderName => AST.Name; - + public string ShaderSourceCode {get;set;} public ShaderClassString(string code) { - source = code; - } - - public void Parse() - { - AST = ShaderMixinParser.ParseShader(source); + ShaderSourceCode = code; } public override object Clone() @@ -30,11 +22,6 @@ public override object Clone() throw new NotImplementedException(); } - public override void EnumerateMixins(SortedSet shaderSources) - { - throw new NotImplementedException(); - } - public override bool Equals(object against) { throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs deleted file mode 100644 index 0b69825aee..0000000000 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Spv.Generator; -using Stride.Shaders.Parsing; - -namespace Stride.Shaders.Mixer; - -public partial class ShaderMixer -{ - public ShaderSource Mixins { get; set; } - public ShaderLoader Loader {get;set;} - - public Dictionary Variables = new(); - - public ShaderMixer(string code, ShaderLoader loader) - { - Loader = loader; - var mixin = new ShaderClassString(code); - Mixins = new ShaderArraySource(mixin.MixinNames.Select(loader.Get).Select(x => new ShaderClassString(x))); - } - - public void AddMixin(ShaderSource mixin) - { - if (Mixins is ShaderClassString) - { - var sas = new ShaderArraySource - { - Mixins, - mixin - }; - Mixins = sas; - } - else if(Mixins is ShaderArraySource sas) - sas.Add(mixin); - } -} diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs deleted file mode 100644 index a3cd9598a5..0000000000 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixin.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Mixer; - -public abstract class ShaderMixin : ShaderSource -{ - static readonly string[] EntryPointNames = { - "PSMain", - "VSMain", - "GSMain", - "HSMain", - "DSMain", - "CSMain" - }; - - public abstract string Code { get; } - public string? ClassName => AST?.Name; - public override IEnumerable MixinNames => AST.Mixins.Select(x => x.Name).ToList(); - - public ShaderProgram AST { get; set; } - - public IEnumerable GetStreamValues() - { - if (AST is not null) - return - from e in AST.Body - where e is ShaderVariableDeclaration v - && v.IsStream - select e as ShaderVariableDeclaration; - else - throw new Exception("AST is null"); - } - public IEnumerable GetEntryPoints() - { - if (AST is not null) - return - from e in AST.Body - where e is ShaderMethod method - && EntryPointNames.Contains(method.Name) - select e as ShaderMethod; - else - throw new Exception("AST is null"); - } - public IEnumerable GetMethods() - { - if (AST is not null) - return - from e in AST.Body - where e is ShaderMethod method - && !EntryPointNames.Contains(method.Name) - select e as ShaderMethod; - else - throw new Exception("AST is null"); - } -} diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs new file mode 100644 index 0000000000..aa9a3f5f09 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs @@ -0,0 +1,350 @@ +namespace Stride.Shaders.Mixer; + + +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + + +public class ParameterCollection +{ + internal bool ContainsKey(PermutationParameterKey key) + { + throw new NotImplementedException(); + } + + internal void Set(PermutationParameterKey key, T? value) + { + throw new NotImplementedException(); + } + + internal T Get(PermutationParameterKey key) + { + throw new NotImplementedException(); + } +} + +/// +/// A context used when mixin . +/// +public class ShaderMixinContext +{ + private readonly ParameterCollection compilerParameters; + private readonly Stack parameterCollections = new Stack(); + private readonly Dictionary registeredBuilders; + private readonly Stack compositionIndices = new Stack(); + private readonly StringBuilder compositionStringBuilder = new StringBuilder(); + + private string compositionString = null; + + private readonly ShaderMixinSource currentMixinSourceTree; + + /// + /// Initializes a new instance of the class. + /// + /// The mixin tree. + /// The default property container. + /// The registered builders. + /// compilerParameters + /// or + /// registeredBuilders + public ShaderMixinContext(ShaderMixinSource mixinTree, ParameterCollection compilerParameters, Dictionary registeredBuilders) + { + if (mixinTree == null) throw new ArgumentNullException("mixinTree"); + if (compilerParameters == null) + throw new ArgumentNullException("compilerParameters"); + + if (registeredBuilders == null) + throw new ArgumentNullException("registeredBuilders"); + + // TODO: use a copy of the compilerParameters? + this.currentMixinSourceTree = mixinTree; + this.compilerParameters = compilerParameters; + this.registeredBuilders = registeredBuilders; + this.parameterCollections = new Stack(); + } + + /// + /// Gets or sets the child effect. + /// + /// The child effect. + public string ChildEffectName { get; set; } + + /// + /// Pushes the current parameters collection being used. + /// + /// Type of the parameter collection + /// The property container. + public void PushParameters(ParameterCollection parameterCollection) + { + parameterCollections.Push(parameterCollection); + } + + /// + /// Pops the parameters collection. + /// + public void PopParameters() + { + parameterCollections.Pop(); + } + + public ShaderMixinSource CurrentMixin + { + get + { + return currentMixinSourceTree; + } + } + + public void Discard() + { + throw new ShaderMixinDiscardException(); + } + + /// + /// Gets a parameter value for the specified key. + /// + /// Type of the parameter value + /// The parameter key. + /// The value or default value associated to this parameter key. + /// key + public T GetParam(PermutationParameterKey paramKey) + { + if (paramKey == null) + throw new ArgumentNullException("paramKey"); + + var globalKey = paramKey; + var composeKey = GetComposeKey(paramKey); + var selectedKey = globalKey; + ParameterCollection sourceParameters = null; + + // Try first if a composite key with a value is available for the key + if (composeKey != globalKey) + { + sourceParameters = FindKeyValue(composeKey, out selectedKey); + } + + // Else try using global key + if (sourceParameters == null) + { + sourceParameters = FindKeyValue(globalKey, out selectedKey); + } + + // If nothing found, use composeKey and global compiler parameters + if (sourceParameters == null) + { + selectedKey = composeKey; + sourceParameters = compilerParameters; + } + + // Gets the value from a source parameters + var value = Get(sourceParameters, selectedKey); + + return value; + } + + private ParameterCollection FindKeyValue(PermutationParameterKey key, out PermutationParameterKey selectedKey) + { + // Try to get a value from registered containers + selectedKey = null; + foreach (var parameterCollection in parameterCollections) + { + if (parameterCollection.ContainsKey(key)) + { + selectedKey = key; + return parameterCollection; + } + } + if (compilerParameters.ContainsKey(key)) + { + selectedKey = key; + return compilerParameters; + } + + return null; + } + + private PermutationParameterKey GetComposeKey(PermutationParameterKey key) + { + if (compositionString == null) + { + return key; + } + key = key.ComposeWith(compositionString); + return key; + } + + public void SetParam(PermutationParameterKey key, T value) + { + if (key == null) + throw new ArgumentNullException("key"); + + var propertyContainer = parameterCollections.Count > 0 ? parameterCollections.Peek() : compilerParameters; + Set(propertyContainer, key, value); + } + + /// + /// Removes the specified mixin from this instance. + /// + /// The mixin tree. + /// The name. + public void RemoveMixin(ShaderMixinSource mixinTree, string name) + { + var mixinParent = mixinTree; + for (int i = mixinParent.Mixins.Count - 1; i >= 0; i--) + { + var mixin = mixinParent.Mixins[i]; + if (mixin.ClassName == name) + { + mixinParent.Mixins.RemoveAt(i); + } + } + } + + /// + /// Mixins a into the specified mixin tree. + /// + /// The mixin tree. + /// The name. + public void Mixin(ShaderMixinSource mixinTree, string name) + { + if (name == null) + { + throw new ArgumentNullException("name", "Invalid null mixin name"); + } + + IShaderMixinBuilder builder; + if (!registeredBuilders.TryGetValue(name, out builder)) + { + // Else simply add the name of the shader + mixinTree.Mixins.Add(new ShaderClassSource(name)); + } + else if (builder != null) + { + builder.Generate(mixinTree, this); + } + } + + /// + /// Mixins a identified by its name/generic parameters into the specified mixin tree. + /// + /// The mixin tree. + /// The name. + /// The generic parameters. + /// If the class source doesn't support generic parameters + public void Mixin(ShaderMixinSource mixinTree, string name, params object[] genericParameters) + { + IShaderMixinBuilder builder; + if (!registeredBuilders.TryGetValue(name, out builder)) + { + // Else simply add the name of the shader + mixinTree.Mixins.Add(new ShaderClassSource(name, genericParameters)); + } + else if (builder != null) + { + if (genericParameters != null && genericParameters.Length != 0) + { + throw new InvalidOperationException(string.Format("Generic Parameters are not supported with [{0}]", builder.GetType().GetTypeInfo().Name)); + } + builder.Generate(mixinTree, this); + } + } + + public void PushComposition(ShaderMixinSource mixin, string compositionName, ShaderMixinSource composition) + { + mixin.AddComposition(compositionName, composition); + + compositionIndices.Push(compositionStringBuilder.Length); + if (compositionString != null) + { + compositionStringBuilder.Insert(0, '.'); + } + + compositionStringBuilder.Insert(0, compositionName); + + compositionString = compositionStringBuilder.ToString(); + } + + public void PushCompositionArray(ShaderMixinSource mixin, string compositionName, ShaderMixinSource composition) + { + int arrayIndex = mixin.AddCompositionToArray(compositionName, composition); + + compositionIndices.Push(compositionStringBuilder.Length); + if (compositionString != null) + { + compositionStringBuilder.Insert(0, '.'); + } + + compositionStringBuilder.Insert(0, ']'); + compositionStringBuilder.Insert(0, arrayIndex); + compositionStringBuilder.Insert(0, '['); + compositionStringBuilder.Insert(0, compositionName); + + compositionString = compositionStringBuilder.ToString(); + } + + public void PopComposition() + { + var compositionIndex = compositionIndices.Pop(); + compositionStringBuilder.Remove(0, compositionStringBuilder.Length - compositionIndex); + compositionString = compositionIndex == 0 ? null : compositionStringBuilder.ToString(); + } + + /// + /// Mixins a into the specified mixin tree. + /// + /// The mixin tree. + /// The shader source. + public void Mixin(ShaderMixinSource mixinTree, ShaderSource shaderSource) + { + if (shaderSource == null) + { + return; + } + + if (shaderSource is ShaderMixinSource shaderMixinSource) + { + mixinTree.CloneFrom(shaderMixinSource); + } + else if (shaderSource is ShaderClassCode shaderClassCode) + { + mixinTree.Mixins.Add(shaderClassCode); + } + else if (shaderSource is ShaderMixinGeneratorSource mixinGeneratorSource) + { + Mixin(mixinTree, mixinGeneratorSource.Name); + } + else + { + throw new InvalidOperationException($"ShaderSource [{shaderSource.GetType()}] is not supported (Only ShaderMixinSource and ShaderClassSource)"); + } + + // If we are mixin a shader source that has an attached discard, don't proceed further + if (shaderSource.Discard) + { + Discard(); + } + } + + // Helpers, until we get rid of ParameterCollection + private void Set(ParameterCollection parameterCollection, PermutationParameterKey key, T value) + { + parameterCollection.Set(key, value); + } + + private T Get(ParameterCollection parameterCollection, PermutationParameterKey key) + { + return parameterCollection.Get(key); + } +} + +public class PermutationParameterKey +{ + internal PermutationParameterKey ComposeWith(string compositionString) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs new file mode 100644 index 0000000000..978ddc7719 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs @@ -0,0 +1,23 @@ +using System.Runtime.Serialization; + +namespace Stride.Shaders.Mixer +{ + internal class ShaderMixinDiscardException : Exception + { + public ShaderMixinDiscardException() + { + } + + public ShaderMixinDiscardException(string? message) : base(message) + { + } + + public ShaderMixinDiscardException(string? message, Exception? innerException) : base(message, innerException) + { + } + + protected ShaderMixinDiscardException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs new file mode 100644 index 0000000000..8080e47d03 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs @@ -0,0 +1,70 @@ +namespace Stride.Shaders.Mixer; + +public sealed class ShaderMixinGeneratorSource : ShaderSource, IEquatable +{ + /// + /// Initializes a new instance of the class. + /// + public ShaderMixinGeneratorSource() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The name of the sdfx effect. + public ShaderMixinGeneratorSource(string name) + { + Name = name; + } + + /// + /// Gets or sets the name of the sdfx effect. + /// + /// The name of the sdfx effect. + public string Name { get; set; } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// An object to compare with this object. + /// true if the current object is equal to the parameter; otherwise, false. + public bool Equals(ShaderMixinGeneratorSource other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return string.Equals(Name, other.Name); + } + + public override object Clone() + { + return new ShaderMixinGeneratorSource(Name); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj is ShaderMixinGeneratorSource && Equals((ShaderMixinGeneratorSource)obj); + } + + public override int GetHashCode() + { + return (Name != null ? Name.GetHashCode() : 0); + } + + public static bool operator ==(ShaderMixinGeneratorSource left, ShaderMixinGeneratorSource right) + { + return Equals(left, right); + } + + public static bool operator !=(ShaderMixinGeneratorSource left, ShaderMixinGeneratorSource right) + { + return !Equals(left, right); + } + + public override string ToString() + { + return string.Format("sdfx {0}", Name); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs new file mode 100644 index 0000000000..ff1b1cef0d --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shaders.Parsing; + +namespace Stride.Shaders.Mixer; + +public class ShaderMixinManager +{ + private static readonly Dictionary RegisteredBuilders = new Dictionary(); + + /// + /// Registers a with the specified sdfx effect name. + /// + /// Name of the mixin. + /// The builder. + /// + /// sdfxEffectName + /// or + /// builder + /// + public static void Register(string sdfxEffectName, IShaderMixinBuilder builder) + { + if (sdfxEffectName == null) + throw new ArgumentNullException("sdfxEffectName"); + + if (builder == null) + throw new ArgumentNullException("builder"); + + lock (RegisteredBuilders) + { + RegisteredBuilders[sdfxEffectName] = builder; + } + } + + /// + /// Determines whether the specified PDXFX effect is registered. + /// + /// Name of the PDXFX effect. + /// true if the specified PDXFX effect is registered; otherwise, false. + /// sdfxEffectName + public static bool Contains(string sdfxEffectName) + { + if (sdfxEffectName == null) throw new ArgumentNullException("sdfxEffectName"); + + var effectName = GetEffectName(sdfxEffectName); + var rootEffectName = effectName.Key; + + lock (RegisteredBuilders) + { + return RegisteredBuilders.ContainsKey(rootEffectName); + } + } + + /// + /// Tries to get a by its name. + /// + /// Name of the mixin. + /// The builder instance found or null if not found. + /// true if the builder was found, false otherwise. + /// sdfxEffectName + public static bool TryGet(string sdfxEffectName, out IShaderMixinBuilder builder) + { + if (sdfxEffectName == null) + throw new ArgumentNullException("sdfxEffectName"); + + lock (RegisteredBuilders) + { + return RegisteredBuilders.TryGetValue(sdfxEffectName, out builder); + } + } + + /// + /// Generates a for the specified names and parameters. + /// + /// The name. + /// The properties. + /// The result of the mixin. + /// + /// sdfxEffectName + /// or + /// properties + /// + /// sdfxEffectName + public static ShaderMixinSource Generate(string sdfxEffectName, ParameterCollection properties) + { + if (sdfxEffectName == null) throw new ArgumentNullException("sdfxEffectName"); + + if (properties == null) + throw new ArgumentNullException("properties"); + + // Get the effect name and child effect name "RootEffectName.ChildEffectName" + var effectName = GetEffectName(sdfxEffectName); + var rootEffectName = effectName.Key; + var childEffectName = effectName.Value; + + IShaderMixinBuilder builder; + Dictionary builders; + lock (RegisteredBuilders) + { + if (!TryGet(rootEffectName, out builder)) + throw new ArgumentException(string.Format("sdfx effect [{0}] not found", rootEffectName), "sdfxEffectName"); + + builders = new Dictionary(RegisteredBuilders); + } + + // TODO cache mixin context and avoid to recreate one (check if if thread concurrency could occur here) + var mixinTree = new ShaderMixinSource() { Name = sdfxEffectName }; + var context = new ShaderMixinContext(mixinTree, properties, builders) { ChildEffectName = childEffectName }; + try + { + builder.Generate(mixinTree, context); + } + catch (ShaderMixinDiscardException) + { + // We don't rethrow as this exception is on purpose to early exit/escape from a shader mixin + } + return mixinTree; + } + + private static KeyValuePair GetEffectName(string sdfxEffectName) + { + var mainEffectNameEnd = sdfxEffectName.IndexOf('.'); + var rootEffectName = mainEffectNameEnd != -1 ? sdfxEffectName.Substring(0, mainEffectNameEnd) : sdfxEffectName; + var childEffectName = mainEffectNameEnd != -1 ? sdfxEffectName.Substring(mainEffectNameEnd + 1) : string.Empty; + return new KeyValuePair(rootEffectName, childEffectName); + } + + /// + /// Un-register all registered . + /// + public static void UnRegisterAll() + { + lock (RegisteredBuilders) + { + RegisteredBuilders.Clear(); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs new file mode 100644 index 0000000000..e55215d703 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs @@ -0,0 +1,217 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Mixer; + +public sealed class ShaderMixinSource : ShaderSource, IEquatable +{ + /// + /// Initializes a new instance of the class. + /// + public ShaderMixinSource() + { + Mixins = new List(); + Compositions = new SortedList(); + // Macros = new List(); + } + + /// + /// Gets or sets the name of the sdfx effect linked to this node. + /// + /// The name of the sdfx effect. + public string Name { get; set; } + public ShaderMixinSource Parent { get; set; } + + /// + /// Gets or sets the name of this mixin source (if this ShaderMixinSource was generated from a , + /// it contains the name of . + /// + /// The name. + //public string Name { get; set; } + + /// + /// Gets or sets the mixins. + /// + /// The mixins. + public List Mixins { get; set; } + + /// + /// Gets or sets the compositions. + /// + /// The compositions. + public SortedList Compositions { get; set; } + + /// + /// Gets or sets the macros. + /// + /// The macros. + // public List Macros { get; set; } + + /// + /// Adds a composition to this mixin. + /// + /// The name. + /// The shader source. + public void AddComposition(string name, ShaderSource shaderSource) + { + Compositions[name] = shaderSource; + } + + /// + /// Adds a composition to this mixin. + /// + /// The name. + /// The shader source element. + /// Returns the index of the composition in the array. + public int AddCompositionToArray(string name, ShaderSource shaderSourceElement) + { + ShaderSource shaderSource; + if (!Compositions.TryGetValue(name, out shaderSource)) + Compositions.Add(name, shaderSource = new ShaderArraySource()); + + var shaderArraySource = (ShaderArraySource)shaderSource; + shaderArraySource.Add(shaderSourceElement); + return shaderArraySource.Values.Count - 1; + } + + /// + /// Adds a macro to this mixin. + /// + /// The name. + /// The value. + public void AddMacro(string name, object value) + { + // Macros.Add(new ShaderMacro(name, value)); + } + + /// + /// Clones from the specified . + /// + /// The parent mixin to clone from. + /// parent + public void CloneFrom(ShaderMixinSource parent) + { + if (parent == null) + throw new ArgumentNullException("parent", $"Cannot clone mixin [{Name}] from a null parent"); + + Mixins.AddRange(parent.Mixins); + // Macros.AddRange(parent.Macros); + foreach (var shaderBasic in parent.Compositions) + { + Compositions[shaderBasic.Key] = shaderBasic.Value; + } + } + + /// + /// Clones from the specified . Clones members too. + /// + /// The parent mixin to clone from. + /// parent + public void DeepCloneFrom(ShaderMixinSource parent) + { + if (parent == null) + throw new ArgumentNullException("parent", $"Cannot deep clone mixin [{Name}] from a null parent"); + + foreach (var mixin in parent.Mixins) + Mixins.Add((ShaderClassCode)mixin.Clone()); + // Macros.AddRange(parent.Macros); + foreach (var shaderBasic in parent.Compositions) + { + Compositions[shaderBasic.Key] = (ShaderSource)shaderBasic.Value.Clone(); + } + } + + public override bool Equals(object against) + { + if (ReferenceEquals(null, against)) return false; + if (ReferenceEquals(this, against)) return true; + if (against.GetType() != this.GetType()) return false; + return Equals((ShaderMixinSource)against); + } + + + public override object Clone() + { + var newMixin = (ShaderMixinSource)MemberwiseClone(); + newMixin.Compositions = Compositions == null ? null : ToSortedList(Compositions.Select(x => new KeyValuePair(x.Key, (ShaderSource)x.Value.Clone()))); + newMixin.Mixins = Mixins == null ? null : Mixins.Select(x => (ShaderClassCode)x.Clone()).ToList(); + // newMixin.Macros = Macros == null ? null : new List(Macros.ToArray()); + return newMixin; + } + + private static SortedList ToSortedList(IEnumerable> list) where TKey : notnull + { + var values = new SortedList(); + foreach (var item in list) + values.Add(item.Key, item.Value); + return values; + } + + public override string ToString() + { + var result = new StringBuilder(); + + result.Append("mixin"); + + if (Mixins != null && Mixins.Count > 0) + { + result.Append(" "); + for (int i = 0; i < Mixins.Count; i++) + { + if (i > 0) + result.Append(", "); + result.Append(Mixins[i]); + } + } + + if (Compositions != null && Compositions.Count > 0) + { + result.Append(" ["); + var keys = Compositions.Keys.ToList(); + keys.Sort(); + for (int i = 0; i < keys.Count; i++) + { + var key = keys[i]; + if (i > 0) + result.Append(", "); + result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]); + } + result.Append("]"); + } + return result.ToString(); + } + + internal bool ShouldSerializeMacros() + { + // If collection is non-null and empty, skip serialization + // return Macros == null || Macros.Count != 0; + return false; + } + + internal bool ShouldSerializeMixins() + { + // If collection is non-null and empty, skip serialization + return Mixins == null || Mixins.Count != 0; + } + + internal bool ShouldSerializeCompositions() + { + // If collection is non-null and empty, skip serialization + return Compositions == null || Compositions.Count != 0; + } + + public bool Equals(ShaderMixinSource? other) + { + throw new NotImplementedException(); + } + + public override int GetHashCode() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs index a6008a34ee..ad43936788 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs +++ b/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs @@ -2,10 +2,6 @@ namespace Stride.Shaders.Mixer; public abstract class ShaderSource { public bool Discard { get; set; } - public abstract string ShaderName {get;} - public abstract IEnumerable MixinNames {get;} - - public abstract void EnumerateMixins(SortedSet shaderSources); public abstract object Clone(); diff --git a/src/Stride.Shaders/EffectCompiler.cs b/src/Stride.Shaders/EffectCompiler.cs index b1e7961f3b..9b37d1aaef 100644 --- a/src/Stride.Shaders/EffectCompiler.cs +++ b/src/Stride.Shaders/EffectCompiler.cs @@ -12,9 +12,4 @@ public EffectCompiler(string path) Loader = new ShaderLoader(path); } - public void Compile(ShaderMixin mixin) - { - var mixer = new ShaderMixer(); - } - } \ No newline at end of file diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index cb595e0572..7edb8b3176 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -6,9 +6,14 @@ + + + + net6.0 enable enable + true From aa65e55f5326c9c1fdf65460cd08120bf4ad2ecc Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 1 Aug 2022 01:01:30 +0200 Subject: [PATCH 0123/1182] Update parser + emitter --- src/SDSLParserExample/Program.cs | 10 +-- .../SDSL/MixinSamples/SingleShader.sdsl | 29 +++++++++ .../Compiler/Emitter/SpirvEmitter.Streams.cs | 22 +++++++ .../Compiler/Emitter/SpirvEmitter.Structs.cs | 18 ++++++ .../Compiler/Emitter/SpirvEmitter.Types.cs | 63 ++++++++++++++++++- .../Compiler/Emitter/SpirvEmitter.cs | 11 +++- .../Compiler/Mixer/SimpleMixer.cs | 19 ++++++ .../Parsers/AST/Shader/ShaderElements.cs | 24 +++++++ src/Stride.Shaders/ShaderSourceManager.cs | 8 ++- 9 files changed, 195 insertions(+), 9 deletions(-) create mode 100644 src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs create mode 100644 src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index b3b0df5521..7064d09c07 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -16,12 +16,14 @@ // ShaderCompiling(shaderf); // ThreeAddress(shaderf); -LoadShaders(shaderf); +LoadShaders(); -static void LoadShaders(string shaderf) +static void LoadShaders() { - var compiler = new EffectCompiler("./SDSL/MixinSamples"); - var mixin = new ShaderMixinParser(); + var manager = new ShaderSourceManager(); + manager.AddDirectory("./SDSL/MixinSamples"); + + var mixer = new SimpleMixer("SingleShader",manager); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl new file mode 100644 index 0000000000..4d5a33d8ea --- /dev/null +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -0,0 +1,29 @@ +shader SingleShader { + // Default SV_POSITION output for VS/GS shaders + stage stream float4 ShadingPosition : SV_Position; + + // front face + stage stream bool IsFrontFace : SV_IsFrontFace; + // Default COLOR outputs for PS shader + stage stream float4 ColorTarget : SV_Target0; + stage stream float4 ColorTarget1 : SV_Target1; + stage stream float4 ColorTarget2 : SV_Target2; + stage stream float4 ColorTarget3 : SV_Target3; + stage stream float4 ColorTarget4 : SV_Target4; + stage stream float4 ColorTarget5 : SV_Target5; + stage stream float4 ColorTarget6 : SV_Target6; + stage stream float4 ColorTarget7 : SV_Target7; + + // Default DEPTH output for PS shader + stage stream float Depth : SV_Depth; + stage stream float DepthGreater : SV_DepthGreater; // Special output after PS + stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS + + stage stream uint InstanceID : SV_InstanceID; + + + void VSMain() + { + streams.ShadingPosition = float4(1,1,1,1); + } +}; \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs new file mode 100644 index 0000000000..998daa4a5d --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -0,0 +1,22 @@ +using Stride.Shaders.Parsing.AST.Shader; + +namespace Stride.Shaders.Spirv; + +public partial class SpirvEmitter +{ + public void CreateStreamStructs(ShaderProgram program) + { + var variables = + program.Body + .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) + .Cast() + .Select(x => (x.Name, SpvType: ShaderTypes[x.Type])); + + var streams = TypeStruct(false, variables.Select(x => x.SpvType).ToArray()); + Name(streams,"VS_STREAMS"); + for (int i = 0; i < variables.Count(); i++) + { + MemberName(streams,i,variables.ElementAt(i).Name); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs new file mode 100644 index 0000000000..f115430199 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + +public partial class SpirvEmitter : Module +{ + void CreateStructs(ShaderProgram program) + { + // program.Body.Where(x => x is ShaderStr) + } +} diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 4ba2f3c9f7..0e9619a849 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -11,5 +11,66 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { - + static string[] nativeIntTypes = { + "sbyte", + "short", + "int", + "long" + }; + static string[] nativeUintTypes = { + "byte", + "ushort", + "uint", + "ulong" + }; + + static string[] nativeFloatTypes = { + "half", + "float", + "double", + }; + + public int Width(string v) => v switch { + "sbyte" or "byte"=> 8, + "short" or "half" => 16, + "int" or "float" => 32, + "long" or "double" => 64, + _ => throw new NotImplementedException() + }; + + + void CreateNativeTypes() + { + foreach(var t in nativeFloatTypes) + { + ShaderTypes[t] = TypeFloat(Width(t)); + } + foreach(var t in nativeIntTypes) + { + ShaderTypes[t] = TypeInt(Width(t), 1); + } + foreach(var t in nativeUintTypes) + { + ShaderTypes[t] = TypeInt(Width(t), 0); + } + // vectors + foreach(var t in nativeFloatTypes.Concat(nativeIntTypes).Concat(nativeUintTypes)) + { + for (int i = 1; i < 5; i++) + { + ShaderTypes[t + i] = TypeVector(ShaderTypes[t],i); + } + } + // Matrices + foreach(var t in nativeFloatTypes.Concat(nativeIntTypes).Concat(nativeUintTypes)) + { + for (int i = 1; i < 5; i++) + { + for (int j = 1; j < 5; j++) + { + ShaderTypes[t + i + "x" + j] = TypeMatrix(ShaderTypes[t+i], j); + } + } + } + } } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index e7d7e4c951..d014fd7258 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -12,18 +12,25 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { + public Dictionary ShaderTypes {get;set;} + public SpirvEmitter(uint version) : base(version) { - + ShaderTypes = new(); + CreateNativeTypes(); } - public void Construct(ShaderClassString code, EntryPoints entry) + public void Construct(ShaderProgram program, EntryPoints entry) { AddCapability(Capability.Shader); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); // Create all user defined types + // Create stream types + + CreateStreamStructs(program); + // Manage input output and stream // Generate methods diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs new file mode 100644 index 0000000000..8895aa9207 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -0,0 +1,19 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Spirv; + +namespace Stride.Shaders.Mixer; + +public class SimpleMixer +{ + ShaderClassString source; + ShaderProgram program; + List il; + + public SimpleMixer(string className, ShaderSourceManager manager) + { + source = new(manager.GetShaderSource(className)); + program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); + il = new(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 088ddcdb57..c380a263fc 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -7,6 +7,30 @@ namespace Stride.Shaders.Parsing.AST.Shader; +public class ShaderStructField : ShaderToken +{ + public string Type {get;set;} + public string Name {get;set;} + + + public ShaderStructField(Match m) + { + Match = m; + } +} + +public class ShaderStruct : ShaderToken +{ + public IEnumerable Fields {get;set;} + + public ShaderStruct(Match m) + { + Match = m; + Fields = m["Fields"].Matches.Select(GetToken).ToList(); + + } +} + public class ResourceGroup : ShaderToken { public IEnumerable Variables {get;set;} diff --git a/src/Stride.Shaders/ShaderSourceManager.cs b/src/Stride.Shaders/ShaderSourceManager.cs index 33ae273780..0e78a21b63 100644 --- a/src/Stride.Shaders/ShaderSourceManager.cs +++ b/src/Stride.Shaders/ShaderSourceManager.cs @@ -24,11 +24,15 @@ public void AddDirectory(string path) { Directory.EnumerateFiles(p,"*.sdsl",SearchOption.AllDirectories) .Select(x => new ShaderSourceWithHash{ Path = x, Source = File.ReadAllText(x)}) - .ToList().ForEach(_ => shaders.Add(_)); + .ToList().ForEach(AddShaderSource); } } - + public void AddShaderSource(ShaderSourceWithHash source) + { + loadedShaderSources[Path.GetFileNameWithoutExtension(source.Path)] = source; + classNameToPath[Path.GetFileNameWithoutExtension(source.Path)] = source.Path; + } public void AddShaderSource(string className, string source, string path) { var shaderSource = new ShaderSourceWithHash { Path = path, Source = source }; From 84801efe9ee14d3fad6bdf7cc4ddab6b099df8ce Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 1 Aug 2022 11:50:19 +0200 Subject: [PATCH 0124/1182] emitter func --- src/SDSLParserExample/Program.cs | 1 + src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 7064d09c07..f114adcb80 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -24,6 +24,7 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); + mixer.EmitSpirv(); var x = 0; } diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 8895aa9207..1def5de60d 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -16,4 +16,9 @@ public SimpleMixer(string className, ShaderSourceManager manager) program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); il = new(); } + public void EmitSpirv() + { + var spirv = new SpirvEmitter(455); + spirv.Construct(program,EntryPoints.PSMain); + } } \ No newline at end of file From 41b55c0dbfd5c100a0d69c06ecaf2ce26e959f6b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 1 Aug 2022 17:09:11 +0200 Subject: [PATCH 0125/1182] creation of in and out --- src/SDSLParserExample/Program.cs | 2 +- .../Compiler/Emitter/SpirvEmitter.Streams.cs | 33 ++++++- .../Compiler/Emitter/SpirvEmitter.Types.cs | 13 ++- .../Compiler/Emitter/SpirvEmitter.cs | 4 +- .../Compiler/Mixer/SimpleMixer.cs | 4 +- .../Parsers/AST/Shader/Operations.cs | 18 +++- .../Parsers/AST/Shader/ShaderElements.cs | 23 ----- .../Parsers/AST/Shader/ShaderMethods.cs | 99 +++++++++++++++++++ .../Parsers/AST/Shader/ShaderToken.cs | 2 +- .../Parsers/AST/Shader/Statements.cs | 30 +++++- 10 files changed, 185 insertions(+), 43 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index f114adcb80..261433f9f3 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -24,7 +24,7 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - mixer.EmitSpirv(); + mixer.EmitSpirv(EntryPoints.VSMain); var x = 0; } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index 998daa4a5d..12559b6065 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -1,11 +1,21 @@ +using Stride.Shaders.Mixer; using Stride.Shaders.Parsing.AST.Shader; namespace Stride.Shaders.Spirv; public partial class SpirvEmitter { - public void CreateStreamStructs(ShaderProgram program) + public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) { + var name = entry switch { + EntryPoints.VSMain => 'V', + EntryPoints.PSMain => 'P', + EntryPoints.GSMain => 'G', + EntryPoints.CSMain => 'C', + EntryPoints.DSMain => 'D', + EntryPoints.HSMain => 'H', + _ => throw new NotImplementedException() + }; var variables = program.Body .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) @@ -13,10 +23,29 @@ public void CreateStreamStructs(ShaderProgram program) .Select(x => (x.Name, SpvType: ShaderTypes[x.Type])); var streams = TypeStruct(false, variables.Select(x => x.SpvType).ToArray()); - Name(streams,"VS_STREAMS"); + Name(streams, name + "S_STREAMS"); for (int i = 0; i < variables.Count(); i++) { MemberName(streams,i,variables.ElementAt(i).Name); } + + MainMethod mainMethod = entry switch { + EntryPoints.VSMain => (MainMethod)program.Body.First(x => x is VSMainMethod), + EntryPoints.PSMain => (MainMethod)program.Body.First(x => x is PSMainMethod), + EntryPoints.GSMain => (MainMethod)program.Body.First(x => x is GSMainMethod), + EntryPoints.CSMain => (MainMethod)program.Body.First(x => x is CSMainMethod), + EntryPoints.DSMain => (MainMethod)program.Body.First(x => x is DSMainMethod), + EntryPoints.HSMain => (MainMethod)program.Body.First(x => x is HSMainMethod), + _ => throw new NotImplementedException() + }; + var likelyOutput = mainMethod.GetStreamValuesAssigned(); + var outVars = + variables.Where(x => likelyOutput.Contains(x.Name)); + var outStream = TypeStruct(true, outVars.Select(x => x.SpvType).ToArray()); + Name(outStream, name + "S_STREAMS_OUT"); + for (int i = 0; i < outVars.Count(); i++) + { + MemberName(outStream,i,variables.ElementAt(i).Name); + } } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 0e9619a849..47ad8faf7d 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -32,15 +32,22 @@ public partial class SpirvEmitter : Module public int Width(string v) => v switch { "sbyte" or "byte"=> 8, - "short" or "half" => 16, - "int" or "float" => 32, - "long" or "double" => 64, + "ushort" or "short" or "half" => 16, + "uint" or "int" or "float" => 32, + "ulong" or "long" or "double" => 64, _ => throw new NotImplementedException() }; void CreateNativeTypes() { + ShaderTypes["bool"] = TypeBool(); + for (int i = 1; i < 5; i++) + ShaderTypes["bool" + i] = TypeVector(ShaderTypes["bool"], i); + for (int i = 1; i < 5; i++) + for (int j = 1; j < 5; j++) + ShaderTypes["bool" + i + "x" + j] = TypeMatrix(ShaderTypes["bool"+i], j); + foreach(var t in nativeFloatTypes) { ShaderTypes[t] = TypeFloat(Width(t)); diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index d014fd7258..39aa124b5e 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -29,11 +29,11 @@ public void Construct(ShaderProgram program, EntryPoints entry) // Create stream types - CreateStreamStructs(program); + CreateStreamStructs(program, entry); // Manage input output and stream - // Generate methods + // Generate methods() } } diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 1def5de60d..3fd28c1485 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -16,9 +16,9 @@ public SimpleMixer(string className, ShaderSourceManager manager) program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); il = new(); } - public void EmitSpirv() + public void EmitSpirv(EntryPoints entry) { var spirv = new SpirvEmitter(455); - spirv.Construct(program,EntryPoints.PSMain); + spirv.Construct(program,entry); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index d1056588ac..76f925fbda 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -9,7 +9,17 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public abstract class Projector : ShaderToken + +public class Expression : ShaderToken +{ + public virtual IEnumerable GetVariableNamesUsed() + { + return Array.Empty(); + } +} + + +public abstract class Projector : Expression { public virtual string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } @@ -321,15 +331,15 @@ public ConditionalExpression(Match m) } -public class MethodCall : ShaderToken +public class MethodCall : Expression { public string MethodName { get; set; } - public IEnumerable Parameters { get; set; } + public IEnumerable Parameters { get; set; } public MethodCall(Match m) { Match = m; MethodName = m.Matches.First().StringValue; - Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).ToList(); + Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).Cast().ToList(); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index c380a263fc..01d7704d2f 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -53,29 +53,6 @@ public ConstantBuffer(Match m) } } -public class ShaderMethod : ShaderToken -{ - public bool IsStatic { get; set; } - public bool IsOverride { get; set; } - public bool IsStaged { get; set; } - - - public string Name { get; set; } - public string ReturnType { get; set; } - public IEnumerable ParameterList { get; set; } - public IEnumerable Statements { get; set; } - - public ShaderMethod(Match m) - { - Match = m; - IsStatic = m["Static"].Success; - IsOverride = m["Override"].Success; - IsStaged = m["Stage"].Success; - Name = m["MethodName"].StringValue; - ReturnType = m["ReturnType"].StringValue; - Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); - } -} public class ShaderVariableDeclaration : ShaderToken { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs new file mode 100644 index 0000000000..680d9e86ff --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -0,0 +1,99 @@ +using Eto.Parse; + +namespace Stride.Shaders.Parsing.AST.Shader; + + +public class ShaderMethod : ShaderToken +{ + public bool IsStatic { get; set; } + public bool IsOverride { get; set; } + public bool IsStaged { get; set; } + + + public string Name { get; set; } + public string ReturnType { get; set; } + public IEnumerable ParameterList { get; set; } + public IEnumerable Statements { get; set; } + + public ShaderMethod(Match m) + { + Match = m; + IsStatic = m["Static"].Success; + IsOverride = m["Override"].Success; + IsStaged = m["Stage"].Success; + Name = m["MethodName"].StringValue; + ReturnType = m["ReturnType"].StringValue; + Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); + } + + public static ShaderMethod Create(Match m) + { + return m["MethodName"].StringValue switch + { + "VSMain" => new VSMainMethod(m), + "PSMain" => new PSMainMethod(m), + "CSMain" => new CSMainMethod(m), + "GSMain" => new GSMainMethod(m), + "DSMain" => new DSMainMethod(m), + "HSMain" => new HSMainMethod(m), + _ => new ShaderMethod(m) + }; + } +} + +public abstract class MainMethod : ShaderMethod +{ + public MainMethod(Match m) : base(m){} + + public IEnumerable GetStreamValuesAssigned() + { + return Statements.SelectMany(x => x.GetStreamValuesAssigned()); + } + public IEnumerable GetStreamValuesUsed() + { + return Array.Empty(); + } + +} + + +public class VSMainMethod : MainMethod +{ + public VSMainMethod(Match m) : base(m) + { + } +} +public class PSMainMethod : MainMethod +{ + public PSMainMethod(Match m) : base(m) + { + } +} +public class GSMainMethod : MainMethod +{ + public GSMainMethod(Match m) : base(m) + { + + } +} +public class CSMainMethod : MainMethod +{ + public CSMainMethod(Match m) : base(m) + { + + } +} +public class DSMainMethod : MainMethod +{ + public DSMainMethod(Match m) : base(m) + { + + } +} +public class HSMainMethod : MainMethod +{ + public HSMainMethod(Match m) : base(m) + { + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index bdeb03d019..ea8294a6ed 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -32,7 +32,7 @@ public static ShaderToken GetToken(Match match) "ResourceGroup" => new ResourceGroup(tmp), "ConstantBuffer" => new ConstantBuffer(tmp), "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp), - "Method" => new ShaderMethod(tmp), + "Method" => ShaderMethod.Create(tmp), "ControlFlow" => ControlFlow.Create(tmp), "Block" => new BlockStatement(tmp), "Return" => new ReturnStatement(tmp), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index b67a54158f..45efb65aea 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -11,9 +11,18 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class Statement : ShaderToken +public abstract class Statement : ShaderToken { public List LowCode {get;set;} = new(); + + public virtual IEnumerable GetStreamValuesAssigned() + { + return Array.Empty(); + } + public virtual IEnumerable GetStreamValuesUsed() + { + return Array.Empty(); + } } public class EmptyStatement : Statement {} @@ -37,18 +46,25 @@ public DeclareAssign(Match m ) public class AssignChain : Statement { public AssignOpToken AssignOp { get; set; } - public bool StreamValue { get; set; } + public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; public IEnumerable AccessNames { get; set; } public ShaderToken Value { get; set; } public AssignChain(Match m) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - StreamValue = m.Matches.First().StringValue == "stream"; AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); Value = GetToken(m["PrimaryExpression"]); } + public override IEnumerable GetStreamValuesAssigned() + { + if(StreamValue) + return new List(){AccessNames.ElementAt(1)}; + else + return Array.Empty(); + } + } public class ReturnStatement : Statement @@ -64,10 +80,14 @@ public ReturnStatement(Match m) public class BlockStatement : Statement { - public IEnumerable Statements {get;set;} + public IEnumerable Statements {get;set;} public BlockStatement(Match m) { Match = m; - Statements = m.Matches.Select(GetToken).ToList(); + Statements = m.Matches.Select(GetToken).Cast().ToList(); + } + public override IEnumerable GetStreamValuesAssigned() + { + return Statements.SelectMany(x => x.GetStreamValuesAssigned()); } } From a0a3e8cac33720fba9eac65508f0a4d1d7e4c81c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 2 Aug 2022 18:30:39 +0200 Subject: [PATCH 0126/1182] Added type parser --- src/SDSLParserExample/Program.cs | 2 +- .../SDSL/MixinSamples/SingleShader.sdsl | 5 +- src/Spv.Generator | 2 +- .../Emitter/SpirvEmitter.MainMethod.cs | 52 ++++++++ .../Compiler/Emitter/SpirvEmitter.Streams.cs | 58 ++++----- .../Compiler/Emitter/SpirvEmitter.Types.cs | 119 +++++++++--------- .../Compiler/Emitter/SpirvEmitter.cs | 20 ++- .../Compiler/Emitter/SpvStruct.cs | 11 ++ .../Compiler/Emitter/StreamStructs.cs | 77 ++++++++++++ .../Compiler/Mixer/SimpleMixer.cs | 4 +- .../Parsers/AST/Shader/ShaderElements.cs | 2 +- .../Parsers/AST/Shader/ShaderMethods.cs | 4 +- .../Parsers/AST/Shader/ShaderToken.cs | 25 +++- .../Parsers/AST/Shader/Statements.cs | 22 ---- .../Parsers/Grammars/NativeTypeGrammar.cs | 72 +++++++++++ 15 files changed, 345 insertions(+), 130 deletions(-) create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs create mode 100644 src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs create mode 100644 src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 261433f9f3..28a43a3a2c 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -24,7 +24,7 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - mixer.EmitSpirv(EntryPoints.VSMain); + var module = mixer.EmitSpirv(EntryPoints.VSMain); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 4d5a33d8ea..2b237c504c 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -1,4 +1,7 @@ shader SingleShader { + + stage stream float4 triInput; + // Default SV_POSITION output for VS/GS shaders stage stream float4 ShadingPosition : SV_Position; @@ -24,6 +27,6 @@ shader SingleShader { void VSMain() { - streams.ShadingPosition = float4(1,1,1,1); + streams.ShadingPosition = streams.triInput; } }; \ No newline at end of file diff --git a/src/Spv.Generator b/src/Spv.Generator index 6cd3ba989c..0d17a5b461 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 6cd3ba989c09f1fd816dcdf7c89993e8a09e0ef8 +Subproject commit 0d17a5b46112541ed7345df0b9595b7b7f948071 diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs new file mode 100644 index 0000000000..d44984c3ea --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shaders.Mixer; +using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + +public partial class SpirvEmitter : Module +{ + public void MainMethod(EntryPoints entry, ShaderProgram p) + { + (entry switch + { + EntryPoints.VSMain => (Action)VSMethod, + EntryPoints.PSMain => (Action)PSMethod, + EntryPoints.CSMain => (Action)CSMethod, + EntryPoints.GSMain => (Action)GSMethod, + EntryPoints.HSMain => (Action)HSMethod, + EntryPoints.DSMain => (Action)DSMethod, + _ => throw new NotImplementedException() + })(p); + } + public void VSMethod(ShaderProgram p) + { + + } + public void PSMethod(ShaderProgram p) + { + + } + public void GSMethod(ShaderProgram p) + { + + } + public void CSMethod(ShaderProgram p) + { + + } + public void HSMethod(ShaderProgram p) + { + + } + public void DSMethod(ShaderProgram p) + { + + } +} diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index 12559b6065..a96d04c44c 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -1,35 +1,20 @@ +using Spv.Generator; using Stride.Shaders.Mixer; using Stride.Shaders.Parsing.AST.Shader; namespace Stride.Shaders.Spirv; public partial class SpirvEmitter -{ +{ + public Stream Stream { get; set; } + public StreamIn StreamIn { get; set; } + public StreamOut StreamOut { get; set; } + + public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) { - var name = entry switch { - EntryPoints.VSMain => 'V', - EntryPoints.PSMain => 'P', - EntryPoints.GSMain => 'G', - EntryPoints.CSMain => 'C', - EntryPoints.DSMain => 'D', - EntryPoints.HSMain => 'H', - _ => throw new NotImplementedException() - }; - var variables = - program.Body - .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) - .Cast() - .Select(x => (x.Name, SpvType: ShaderTypes[x.Type])); - - var streams = TypeStruct(false, variables.Select(x => x.SpvType).ToArray()); - Name(streams, name + "S_STREAMS"); - for (int i = 0; i < variables.Count(); i++) + MainMethod mainMethod = entry switch { - MemberName(streams,i,variables.ElementAt(i).Name); - } - - MainMethod mainMethod = entry switch { EntryPoints.VSMain => (MainMethod)program.Body.First(x => x is VSMainMethod), EntryPoints.PSMain => (MainMethod)program.Body.First(x => x is PSMainMethod), EntryPoints.GSMain => (MainMethod)program.Body.First(x => x is GSMainMethod), @@ -38,14 +23,23 @@ public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) EntryPoints.HSMain => (MainMethod)program.Body.First(x => x is HSMainMethod), _ => throw new NotImplementedException() }; - var likelyOutput = mainMethod.GetStreamValuesAssigned(); - var outVars = - variables.Where(x => likelyOutput.Contains(x.Name)); - var outStream = TypeStruct(true, outVars.Select(x => x.SpvType).ToArray()); - Name(outStream, name + "S_STREAMS_OUT"); - for (int i = 0; i < outVars.Count(); i++) - { - MemberName(outStream,i,variables.ElementAt(i).Name); - } + + var variables = + program.Body + .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) + .Cast() + .Select(x => (x.Name, SpvType: AsSpvType(x.Type))) + .ToList(); + + var likelyInputs = mainMethod.GetStreamValuesUsed(); + IEnumerable<(string,Instruction)> inVars = variables.Where(x => likelyInputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; + + var likelyOutputs = mainMethod.GetStreamValuesAssigned(); + IEnumerable<(string,Instruction)> outVars = variables.Where(x => likelyOutputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; + + Stream = new Stream(entry, this, variables as IEnumerable<(string,Instruction)>); + StreamIn = new(entry, this, inVars); + StreamOut = new StreamOut(entry, this, outVars); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 47ad8faf7d..d8e199605e 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -5,79 +5,72 @@ using System.Threading.Tasks; using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.Grammars.NativeType; using static Spv.Specification; namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { - static string[] nativeIntTypes = { - "sbyte", - "short", - "int", - "long" - }; - static string[] nativeUintTypes = { - "byte", - "ushort", - "uint", - "ulong" - }; - static string[] nativeFloatTypes = { - "half", - "float", - "double", - }; + public Instruction? AsSpvType(string n) + { + var match = NativeTypeGrammar.ParseNativeType(n); + if(!match.HasMatches) return TryGetUserDefined(n); + else return match.Matches[0] switch + { + { Name: "Bool" } => TypeBool(), + { Name: "Byte" } => TypeInt(8, 0), + { Name: "SByte" } => TypeInt(8, 1), + { Name: "UShort" } => TypeInt(16, 0), + { Name: "Short" } => TypeInt(16, 1), + { Name: "Half" } => TypeFloat(16), + { Name: "UInt" } => TypeInt(32, 0), + { Name: "Int" } => TypeInt(32, 1), + { Name: "Float" } => TypeFloat(32), + { Name: "ULong" } => TypeInt(64, 0), + { Name: "Long" } => TypeInt(64, 1), + { Name: "Double" } => TypeInt(32, 1), + - public int Width(string v) => v switch { - "sbyte" or "byte"=> 8, - "ushort" or "short" or "half" => 16, - "uint" or "int" or "float" => 32, - "ulong" or "long" or "double" => 64, - _ => throw new NotImplementedException() - }; + { Name: "BoolVector" } m => TypeVector(TypeBool(), (int)m["RowCount"].Value), + { Name: "ByteVector" } m => TypeVector(TypeInt(8, 0), (int)m["RowCount"].Value), + { Name: "SByteVector" } m => TypeVector(TypeInt(8, 1), (int)m["RowCount"].Value), + { Name: "UShortVector" } m => TypeVector(TypeInt(16, 0), (int)m["RowCount"].Value), + { Name: "ShortVector" } m => TypeVector(TypeInt(16, 1), (int)m["RowCount"].Value), + { Name: "HalfVector" } m => TypeVector(TypeFloat(16), (int)m["RowCount"].Value), + { Name: "UIntVector" } m => TypeVector(TypeInt(32, 0), (int)m["RowCount"].Value), + { Name: "IntVector" } m => TypeVector(TypeInt(32, 1), (int)m["RowCount"].Value), + { Name: "FloatVector" } m => TypeVector(TypeFloat(32), (int)m["RowCount"].Value), + { Name: "ULongVector" } m => TypeVector(TypeInt(64, 0), (int)m["RowCount"].Value), + { Name: "LongVector" } m => TypeVector(TypeInt(64, 1), (int)m["RowCount"].Value), + { Name: "DoubleVector" } m => TypeVector(TypeInt(32, 1), (int)m["RowCount"].Value), + { Name: "BoolMatrix" } m => TypeMatrix(TypeVector(TypeBool(), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "ByteMatrix" } m => TypeMatrix(TypeVector(TypeInt(8, 0), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "SByteMatrix" } m => TypeMatrix(TypeVector(TypeInt(8, 1), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "UShortMatrix" } m => TypeMatrix(TypeVector(TypeInt(16, 0), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "ShortMatrix" } m => TypeMatrix(TypeVector(TypeInt(16, 1), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "HalfMatrix" } m => TypeMatrix(TypeVector(TypeFloat(16), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "UIntMatrix" } m => TypeMatrix(TypeVector(TypeInt(32, 0), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "IntMatrix" } m => TypeMatrix(TypeVector(TypeInt(32, 1), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "FloatMatrix" } m => TypeMatrix(TypeVector(TypeFloat(32), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "ULongMatrix" } m => TypeMatrix(TypeVector(TypeInt(64, 0), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "LongMatrix" } m => TypeMatrix(TypeVector(TypeInt(64, 1), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + { Name: "DoubleMatrix" } m => TypeMatrix(TypeVector(TypeInt(32, 1), (int)m["RowCount"].Value), (int)m["ColCount"].Value), + _ => throw new NotImplementedException() + }; + } - void CreateNativeTypes() + public Instruction? TryGetUserDefined(string n) { - ShaderTypes["bool"] = TypeBool(); - for (int i = 1; i < 5; i++) - ShaderTypes["bool" + i] = TypeVector(ShaderTypes["bool"], i); - for (int i = 1; i < 5; i++) - for (int j = 1; j < 5; j++) - ShaderTypes["bool" + i + "x" + j] = TypeMatrix(ShaderTypes["bool"+i], j); - - foreach(var t in nativeFloatTypes) - { - ShaderTypes[t] = TypeFloat(Width(t)); - } - foreach(var t in nativeIntTypes) - { - ShaderTypes[t] = TypeInt(Width(t), 1); - } - foreach(var t in nativeUintTypes) - { - ShaderTypes[t] = TypeInt(Width(t), 0); - } - // vectors - foreach(var t in nativeFloatTypes.Concat(nativeIntTypes).Concat(nativeUintTypes)) - { - for (int i = 1; i < 5; i++) - { - ShaderTypes[t + i] = TypeVector(ShaderTypes[t],i); - } - } - // Matrices - foreach(var t in nativeFloatTypes.Concat(nativeIntTypes).Concat(nativeUintTypes)) - { - for (int i = 1; i < 5; i++) - { - for (int j = 1; j < 5; j++) - { - ShaderTypes[t + i + "x" + j] = TypeMatrix(ShaderTypes[t+i], j); - } - } - } + if(ShaderTypes.TryGetValue(n, out var i)) + return i.SpvType; + else return null; + } + + void CreateStructTypes() + { + } } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 39aa124b5e..13b58b77d1 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -12,19 +12,29 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { - public Dictionary ShaderTypes {get;set;} - + public Dictionary ShaderTypes {get;set;} + public Dictionary ShaderFunctionTypes {get;set;} public SpirvEmitter(uint version) : base(version) { ShaderTypes = new(); - CreateNativeTypes(); + CreateStructTypes(); } - public void Construct(ShaderProgram program, EntryPoints entry) + public void Initialize(EntryPoints entry) { - AddCapability(Capability.Shader); + var capability = entry switch + { + EntryPoints.GSMain => Capability.Geometry, + _ => Capability.Shader, + }; + AddCapability(capability); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); + } + + public void Construct(ShaderProgram program, EntryPoints entry) + { + Initialize(entry); // Create all user defined types // Create stream types diff --git a/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs b/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs new file mode 100644 index 0000000000..190d6f8a91 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs @@ -0,0 +1,11 @@ +using Spv.Generator; +using Stride.Shaders.Mixer; + +namespace Stride.Shaders.Spirv; + + +public abstract class SpvStruct +{ + public Instruction SpvType {get;set;} +} + diff --git a/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs b/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs new file mode 100644 index 0000000000..49522f1584 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs @@ -0,0 +1,77 @@ +using Spv.Generator; +using Stride.Shaders.Mixer; + +namespace Stride.Shaders.Spirv; + +public abstract class StreamStruct : SpvStruct +{ + public Dictionary NameToPosition {get;set;} = new(); + public StreamStruct(Module m, IEnumerable<(string,Instruction)> fields) + { + for (int i = 0; i < fields.Count(); i++) + { + NameToPosition[fields.ElementAt(i).Item1] = i; + } + SpvType = m.TypeStruct(false, fields.Select(x => x.Item2).ToArray()); + for (int i = 0; i < fields.Count(); i++) + { + m.MemberName(SpvType,i,fields.ElementAt(i).Item1); + } + } +} + +public class Stream : StreamStruct +{ + + public Stream(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) + { + var name = entry switch + { + EntryPoints.VSMain => "VS_STREAMS", + EntryPoints.PSMain => "PS_STREAMS", + EntryPoints.GSMain => "GS_STREAMS", + EntryPoints.CSMain => "CS_STREAMS", + EntryPoints.HSMain => "HS_STREAMS", + EntryPoints.DSMain => "DS_STREAMS", + _ => throw new NotImplementedException() + }; + m.Name(SpvType, name); + } +} + +public class StreamIn : StreamStruct +{ + + public StreamIn(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) + { + var name = entry switch + { + EntryPoints.VSMain => "VS_STREAMS_IN", + EntryPoints.PSMain => "PS_STREAMS_IN", + EntryPoints.GSMain => "GS_STREAMS_IN", + EntryPoints.CSMain => "CS_STREAMS_IN", + EntryPoints.HSMain => "HS_STREAMS_IN", + EntryPoints.DSMain => "DS_STREAMS_IN", + _ => throw new NotImplementedException() + }; + m.Name(SpvType, name); + } +} +public class StreamOut : StreamStruct +{ + + public StreamOut(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) + { + var name = entry switch + { + EntryPoints.VSMain => "VS_STREAMS_OUT", + EntryPoints.PSMain => "PS_STREAMS_OUT", + EntryPoints.GSMain => "GS_STREAMS_OUT", + EntryPoints.CSMain => "CS_STREAMS_OUT", + EntryPoints.HSMain => "HS_STREAMS_OUT", + EntryPoints.DSMain => "DS_STREAMS_OUT", + _ => throw new NotImplementedException() + }; + m.Name(SpvType, name); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 3fd28c1485..981cec179a 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -1,3 +1,4 @@ +using Spv.Generator; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.AST.Shader; using Stride.Shaders.Spirv; @@ -16,9 +17,10 @@ public SimpleMixer(string className, ShaderSourceManager manager) program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); il = new(); } - public void EmitSpirv(EntryPoints entry) + public Module EmitSpirv(EntryPoints entry) { var spirv = new SpirvEmitter(455); spirv.Construct(program,entry); + return spirv; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 01d7704d2f..e1d24323e0 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -70,7 +70,7 @@ public ShaderVariableDeclaration(Match m) IsStaged = m["Stage"].Success; Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; Type = m["TypeName"].StringValue; - Name = m["VariableTerm"].StringValue; + Name = m["Identifier"].StringValue; } } public class Generics : ShaderToken diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index 680d9e86ff..ecd6493a46 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -47,11 +47,11 @@ public MainMethod(Match m) : base(m){} public IEnumerable GetStreamValuesAssigned() { - return Statements.SelectMany(x => x.GetStreamValuesAssigned()); + return Statements.SelectMany(x => x.GetAssignedStream()); } public IEnumerable GetStreamValuesUsed() { - return Array.Empty(); + return Statements.SelectMany(x => x.GetUsedStream()); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index ea8294a6ed..84f99f930b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -54,7 +54,7 @@ public static ShaderToken GetToken(Match match) "MulExpression" => MulExpression.Create(tmp), "CastExpression" => new CastExpression(tmp), "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "ChainAccessor" => throw new NotImplementedException(), + "ChainAccessor" => new ChainAccessor(tmp), "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp), "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), @@ -62,4 +62,27 @@ public static ShaderToken GetToken(Match match) _ => throw new NotImplementedException() }; } + + + public IEnumerable GetUsedStream() + { + return this switch + { + AssignChain a => a.Value.GetUsedStream(), + ChainAccessor{Value: VariableNameLiteral{Name : "streams"}} => new string[1]{((VariableNameLiteral)((ChainAccessor)this).Field).Name}, + Operation {Left : ChainAccessor c} => c.GetUsedStream(), + Operation {Right : ChainAccessor c} => c.GetUsedStream(), + _ => Array.Empty() + }; + } + public IEnumerable GetAssignedStream() + { + return this switch + { + AssignChain{StreamValue: true} c => new string[1]{c.AccessNames.ElementAt(1)}, + BlockStatement b => b.Statements.SelectMany(x => x.GetAssignedStream()), + _ => Array.Empty() + }; + } + } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 45efb65aea..449f5023f3 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -14,15 +14,6 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Statement : ShaderToken { public List LowCode {get;set;} = new(); - - public virtual IEnumerable GetStreamValuesAssigned() - { - return Array.Empty(); - } - public virtual IEnumerable GetStreamValuesUsed() - { - return Array.Empty(); - } } public class EmptyStatement : Statement {} @@ -56,15 +47,6 @@ public AssignChain(Match m) AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); Value = GetToken(m["PrimaryExpression"]); } - - public override IEnumerable GetStreamValuesAssigned() - { - if(StreamValue) - return new List(){AccessNames.ElementAt(1)}; - else - return Array.Empty(); - } - } public class ReturnStatement : Statement @@ -86,8 +68,4 @@ public BlockStatement(Match m) Match = m; Statements = m.Matches.Select(GetToken).Cast().ToList(); } - public override IEnumerable GetStreamValuesAssigned() - { - return Statements.SelectMany(x => x.GetStreamValuesAssigned()); - } } diff --git a/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs new file mode 100644 index 0000000000..2e30ecae70 --- /dev/null +++ b/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs @@ -0,0 +1,72 @@ +using Eto.Parse; +using Eto.Parse.Parsers; +using static Eto.Parse.Terminals; + + +namespace Stride.Shaders.Parsing.Grammars.NativeType; + +public class NativeTypeGrammar : Grammar +{ + static NativeTypeGrammar global = new(); + + public static Match ParseNativeType(string s) => global.Match(s); + + public NativeTypeGrammar() : base("native-type-sdsl") + { + var numbers = new NumberParser(){AllowDecimal = false, AllowSign = false, AllowExponent = false, ValueType = typeof(int)}; + Inner = new AlternativeParser( + Terminals.Letter.Or("_").Then(Terminals.LetterOrDigit.Or("_").Repeat(0)), + Literal("bool").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("BoolMatrix"), + + Literal("ulong").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ULongMatrix"), + Literal("long").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("LongMatrix"), + Literal("double").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("DoubleMatrix"), + + Literal("uint").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("UIntMatrix"), + Literal("int").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("IntMatrix"), + Literal("float").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("FloatMatrix"), + + Literal("ushort").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("UShortMatrix"), + Literal("short").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ShortMatrix"), + Literal("half").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("HalfMatrix"), + + Literal("byte").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ByteMatrix"), + Literal("sbyte").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("SByteMatrix"), + + Literal("bool").Then(numbers.Named("RowCount")).Named("BoolVector"), + + Literal("ulong").Then(numbers.Named("RowCount")).Named("ULongVector"), + Literal("long").Then(numbers.Named("RowCount")).Named("LongVector"), + Literal("double").Then(numbers.Named("RowCount")).Named("DoubleVector"), + + Literal("uint").Then(numbers.Named("RowCount")).Named("UIntVector"), + Literal("int").Then(numbers.Named("RowCount")).Named("IntVector"), + Literal("float").Then(numbers.Named("RowCount")).Named("FloatVector"), + + Literal("ushort").Then(numbers.Named("RowCount")).Named("UShortVector"), + Literal("short").Then(numbers.Named("RowCount")).Named("ShortVector"), + Literal("half").Then(numbers.Named("RowCount")).Named("HalfVector"), + + Literal("byte").Then(numbers.Named("RowCount")).Named("ByteVector"), + Literal("sbyte").Then(numbers.Named("RowCount")).Named("SByteVector"), + + + Literal("bool").Named("Bool"), + + Literal("ulong").Named("ULong"), + Literal("long").Named("Long"), + Literal("double").Named("Double"), + + Literal("uint").Named("UInt"), + Literal("int").Named("Int"), + Literal("float").Named("Float"), + + Literal("ushort").Named("UShort"), + Literal("short").Named("Short"), + Literal("half").Named("Half"), + + Literal("byte").Named("Byte"), + Literal("sbyte").Named("SByte") + ); + } +} From 5f49e41b6ab6997e3bdff37b95da238788acb588 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 3 Aug 2022 12:20:04 +0200 Subject: [PATCH 0127/1182] Correction Stream generation --- src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs | 5 +++-- src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index d8e199605e..35caf8c043 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -16,8 +16,9 @@ public partial class SpirvEmitter : Module public Instruction? AsSpvType(string n) { var match = NativeTypeGrammar.ParseNativeType(n); - if(!match.HasMatches) return TryGetUserDefined(n); - else return match.Matches[0] switch + if(!match.HasMatches) return TryGetUserDefined(n); + if(!match["TypeParser"].HasMatches) return TryGetUserDefined(n); + else return match["TypeParser"].Matches[0] switch { { Name: "Bool" } => TypeBool(), { Name: "Byte" } => TypeInt(8, 0), diff --git a/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs b/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs index 2e30ecae70..3a47ea21ee 100644 --- a/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs +++ b/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs @@ -15,7 +15,6 @@ public NativeTypeGrammar() : base("native-type-sdsl") { var numbers = new NumberParser(){AllowDecimal = false, AllowSign = false, AllowExponent = false, ValueType = typeof(int)}; Inner = new AlternativeParser( - Terminals.Letter.Or("_").Then(Terminals.LetterOrDigit.Or("_").Repeat(0)), Literal("bool").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("BoolMatrix"), Literal("ulong").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ULongMatrix"), @@ -66,7 +65,8 @@ public NativeTypeGrammar() : base("native-type-sdsl") Literal("half").Named("Half"), Literal("byte").Named("Byte"), - Literal("sbyte").Named("SByte") - ); + Literal("sbyte").Named("SByte"), + Terminals.Letter.Or("_").Then(Terminals.LetterOrDigit.Or("_").Repeat(0)) + ).WithName("TypeParser"); } } From ca77c55e3ab6da8e073974f9bed631b9da35fedf Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 3 Aug 2022 13:10:41 +0200 Subject: [PATCH 0128/1182] update function --- .../Emitter/SpirvEmitter.MainMethod.cs | 8 ++++++- .../Emitter/SpirvEmitter.Statements.cs | 24 +++++++++++++++++++ .../Compiler/Emitter/SpirvEmitter.Streams.cs | 8 +++++++ .../Compiler/Emitter/SpirvEmitter.cs | 7 ++++-- .../Compiler/Emitter/StreamStructs.cs | 13 +++++----- 5 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs index d44984c3ea..4b51a382fc 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs @@ -27,7 +27,13 @@ public void MainMethod(EntryPoints entry, ShaderProgram p) } public void VSMethod(ShaderProgram p) { - + var typefunc = TypeFunction(TypeVoid()); + var func = Function(TypeVoid(), FunctionControlMask.MaskNone, typefunc); + Label(); + foreach(var s in ((VSMainMethod)p.Body.First(x => x is VSMainMethod)).Statements) + { + + } } public void PSMethod(ShaderProgram p) { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs new file mode 100644 index 0000000000..e67cac21d0 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Spv.Generator; +using Stride.Shaders.Mixer; +using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + +public partial class SpirvEmitter : Module +{ + public void EmitStatement(Statement s, params Dictionary[] ScopedVariables) + { + if(s is AssignChain ac) + { + // TODO : Generate 3 addr + + // Convert 3 addr + } + } +} diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index a96d04c44c..5b270ee9ca 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -1,6 +1,7 @@ using Spv.Generator; using Stride.Shaders.Mixer; using Stride.Shaders.Parsing.AST.Shader; +using static Spv.Specification; namespace Stride.Shaders.Spirv; @@ -40,6 +41,13 @@ public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) Stream = new Stream(entry, this, variables as IEnumerable<(string,Instruction)>); StreamIn = new(entry, this, inVars); StreamOut = new StreamOut(entry, this, outVars); + + // in-out + + var streamInPtr = TypePointer(StorageClass.Input , StreamIn.SpvType); + var streamOutPtr = TypePointer(StorageClass.Output , StreamOut.SpvType); + Variables[StreamIn.Name] = Variable(streamInPtr, StorageClass.Input); + Variables[StreamOut.Name] = Variable(streamOutPtr, StorageClass.Output); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 13b58b77d1..29637a13b2 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -14,6 +14,7 @@ public partial class SpirvEmitter : Module { public Dictionary ShaderTypes {get;set;} public Dictionary ShaderFunctionTypes {get;set;} + public Dictionary Variables {get;set;} public SpirvEmitter(uint version) : base(version) { ShaderTypes = new(); @@ -41,9 +42,11 @@ public void Construct(ShaderProgram program, EntryPoints entry) CreateStreamStructs(program, entry); - // Manage input output and stream - // Generate methods() + + // Generate main method + + MainMethod(entry,program); } } diff --git a/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs b/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs index 49522f1584..7bb542ded9 100644 --- a/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs +++ b/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs @@ -5,6 +5,7 @@ namespace Stride.Shaders.Spirv; public abstract class StreamStruct : SpvStruct { + public string Name {get; protected set;} public Dictionary NameToPosition {get;set;} = new(); public StreamStruct(Module m, IEnumerable<(string,Instruction)> fields) { @@ -25,7 +26,7 @@ public class Stream : StreamStruct public Stream(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) { - var name = entry switch + Name = entry switch { EntryPoints.VSMain => "VS_STREAMS", EntryPoints.PSMain => "PS_STREAMS", @@ -35,7 +36,7 @@ public Stream(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fie EntryPoints.DSMain => "DS_STREAMS", _ => throw new NotImplementedException() }; - m.Name(SpvType, name); + m.Name(SpvType, Name); } } @@ -44,7 +45,7 @@ public class StreamIn : StreamStruct public StreamIn(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) { - var name = entry switch + Name = entry switch { EntryPoints.VSMain => "VS_STREAMS_IN", EntryPoints.PSMain => "PS_STREAMS_IN", @@ -54,7 +55,7 @@ public StreamIn(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> f EntryPoints.DSMain => "DS_STREAMS_IN", _ => throw new NotImplementedException() }; - m.Name(SpvType, name); + m.Name(SpvType, Name); } } public class StreamOut : StreamStruct @@ -62,7 +63,7 @@ public class StreamOut : StreamStruct public StreamOut(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) { - var name = entry switch + Name = entry switch { EntryPoints.VSMain => "VS_STREAMS_OUT", EntryPoints.PSMain => "PS_STREAMS_OUT", @@ -72,6 +73,6 @@ public StreamOut(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> EntryPoints.DSMain => "DS_STREAMS_OUT", _ => throw new NotImplementedException() }; - m.Name(SpvType, name); + m.Name(SpvType, Name); } } \ No newline at end of file From db446a9d61fae5d6c690e6a2ea93d3399e2baa89 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 5 Aug 2022 17:07:34 +0200 Subject: [PATCH 0129/1182] Update lowering --- src/SDSLParserExample/Program.cs | 20 ++--- .../Emitter/SpirvEmitter.Statements.cs | 2 +- .../Compiler/Emitter/ThreeAddressElement.cs | 11 +++ .../Compiler/Mixer/ShaderMixer.Lowering.cs | 64 -------------- .../Parsers/AST/Lowering/Lowering.cs | 87 +++++++++++++++++++ .../Parsers/AST/Shader/ShaderMethods.cs | 20 +++-- .../Parsers/AST/Shader/Statements.cs | 2 +- 7 files changed, 125 insertions(+), 81 deletions(-) delete mode 100644 src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs create mode 100644 src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 28a43a3a2c..2ff73dff06 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -33,16 +33,16 @@ static void ThreeAddress(string code) var parser = new ShaderMixinParser(); - // ShaderProgram? ast = parser.Parse(code) as ShaderProgram; - // var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; - // var s = new Stopwatch(); - // _ = Lowering.LowerToken(declare).ToList(); - - // s.Start(); - // var x = Lowering.LowerToken(declare).ToList(); - // s.Stop(); - // x.ForEach(Console.WriteLine); - // Console.WriteLine(s.Elapsed); + ShaderProgram? ast = parser.Parse(code) as ShaderProgram; + var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; + var s = new Stopwatch(); + _ = Lowering.LowerToken(declare).ToList(); + + s.Start(); + var x = Lowering.LowerToken(declare).ToList(); + s.Stop(); + x.ForEach(Console.WriteLine); + Console.WriteLine(s.Elapsed); } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs index e67cac21d0..7e1dc0f5ac 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs @@ -18,7 +18,7 @@ public void EmitStatement(Statement s, params Dictionary[] S { // TODO : Generate 3 addr - // Convert 3 addr + // Convert 3 addr to spirv } } } diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index cba78c32c2..9e97ca4b81 100644 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -70,4 +70,15 @@ public override string ToString() { return new StringBuilder().Append(Name).Append(' ').Append(Op).Append(' ').Append(Value.Name).ToString(); } +} +public class AssignChainRegister : Register +{ + public IEnumerable Chain {get;set;} + public AssignOpToken Op {get;set;} + public Register Value {get;set;} + + public override string ToString() + { + return new StringBuilder().Append(string.Join(".",Chain)).Append(' ').Append(Op).Append(' ').Append(Value.Name).ToString(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs b/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs deleted file mode 100644 index acba1c0e61..0000000000 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixer.Lowering.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Spirv; - -namespace Stride.Shaders; - -public partial class ShaderMixer -{ - public IEnumerable LowerToken(ShaderToken token) - { - - return token switch - { - DeclareAssign t => Lower(t), - ConditionalExpression t => Lower(t), - Operation t => Lower(t), - ShaderLiteral t => Lower(t), - _ => throw new NotImplementedException() - }; - } - - IEnumerable Lower(DeclareAssign s) - { - var v = LowerToken(s.Value); - return v.Append( - new AssignRegister{ - Name = s.VariableName, - Value = v.Last(), - Op = s.AssignOp - } - ); - } - - IEnumerable Lower(ConditionalExpression cexp) - { - var result = new List(); - return result; - } - - IEnumerable Lower(Operation o) - { - IEnumerable l = LowerToken(o.Left); - IEnumerable r = LowerToken(o.Right); - - return l.Concat(r).Append( - new OperationRegister - { - Op = o.Op, - Left = l.Last(), - Right = r.Last() - } - ); - } - - IEnumerable Lower(ShaderLiteral lit) - { - return new List{ - lit switch { - NumberLiteral nl => new ValueRegister(nl), - _ => new ValueRegister(lit) - } - }; - } - -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs new file mode 100644 index 0000000000..2f2ab25242 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -0,0 +1,87 @@ +using Stride.Shaders.Spirv; + +namespace Stride.Shaders.Parsing.AST.Shader; + +public static class Lowering +{ + public static IEnumerable LowerToken(ShaderToken token) + { + + return token switch + { + BlockStatement t => Lower(t), + AssignChain t => Lower(t), + DeclareAssign t => Lower(t), + ConditionalExpression t => Lower(t), + Operation t => Lower(t), + ChainAccessor t => Lower(t), + ShaderLiteral t => Lower(t), + _ => throw new NotImplementedException() + }; + } + + static IEnumerable Lower(BlockStatement b) + { + b.LowCode = b.Statements.SelectMany(LowerToken); + return b.LowCode; + } + static IEnumerable Lower(AssignChain ac) + { + var v = LowerToken(ac.Value); + ac.LowCode = v.Append( + new AssignChainRegister{ + Chain = ac.AccessNames, + Value = v.Last(), + Op = ac.AssignOp + } + ); + return ac.LowCode; + } + static IEnumerable Lower(DeclareAssign s) + { + var v = LowerToken(s.Value); + s.LowCode = v.Append( + new AssignRegister{ + Name = s.VariableName, + Value = v.Last(), + Op = s.AssignOp + } + ); + return s.LowCode; + } + + static IEnumerable Lower(ConditionalExpression cexp) + { + var result = new List(); + return result; + } + + static IEnumerable Lower(Operation o) + { + IEnumerable l = LowerToken(o.Left); + IEnumerable r = LowerToken(o.Right); + + return l.Concat(r).Append( + new OperationRegister + { + Op = o.Op, + Left = l.Last(), + Right = r.Last() + } + ); + } + static IEnumerable Lower(ChainAccessor lit) + { + throw new NotImplementedException(); + } + static IEnumerable Lower(ShaderLiteral lit) + { + return new List{ + lit switch { + NumberLiteral nl => new ValueRegister(nl), + _ => new ValueRegister(lit) + } + }; + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index ecd6493a46..9a419abe05 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -26,6 +26,14 @@ public ShaderMethod(Match m) Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); } + public void Generate3Addr() + { + foreach (var s in Statements) + { + Lowering.LowerToken(s); + } + } + public static ShaderMethod Create(Match m) { return m["MethodName"].StringValue switch @@ -43,7 +51,7 @@ public static ShaderMethod Create(Match m) public abstract class MainMethod : ShaderMethod { - public MainMethod(Match m) : base(m){} + public MainMethod(Match m) : base(m) { } public IEnumerable GetStreamValuesAssigned() { @@ -61,39 +69,41 @@ public class VSMainMethod : MainMethod { public VSMainMethod(Match m) : base(m) { + Generate3Addr(); } } public class PSMainMethod : MainMethod { public PSMainMethod(Match m) : base(m) { + Generate3Addr(); } } public class GSMainMethod : MainMethod { public GSMainMethod(Match m) : base(m) { - + Generate3Addr(); } } public class CSMainMethod : MainMethod { public CSMainMethod(Match m) : base(m) { - + Generate3Addr(); } } public class DSMainMethod : MainMethod { public DSMainMethod(Match m) : base(m) { - + Generate3Addr(); } } public class HSMainMethod : MainMethod { public HSMainMethod(Match m) : base(m) { - + Generate3Addr(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 449f5023f3..92982feca7 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -13,7 +13,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Statement : ShaderToken { - public List LowCode {get;set;} = new(); + public IEnumerable LowCode {get;set;} } public class EmptyStatement : Statement {} From 5c9c9af76ef3b4ce39f069f1e3a44046900b768e Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 12 Aug 2022 15:11:56 +0200 Subject: [PATCH 0130/1182] update register types --- .../Compiler/Emitter/SpirvEmitter.Types.cs | 8 +- .../Compiler/Emitter/ThreeAddressElement.cs | 82 +++++++------------ .../Parsers/AST/Lowering/Lowering.cs | 13 +-- 3 files changed, 41 insertions(+), 62 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 35caf8c043..121b10098d 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -16,8 +16,8 @@ public partial class SpirvEmitter : Module public Instruction? AsSpvType(string n) { var match = NativeTypeGrammar.ParseNativeType(n); - if(!match.HasMatches) return TryGetUserDefined(n); - if(!match["TypeParser"].HasMatches) return TryGetUserDefined(n); + if (!match.HasMatches) return TryGetUserDefined(n); + if (!match["TypeParser"].HasMatches) return TryGetUserDefined(n); else return match["TypeParser"].Matches[0] switch { { Name: "Bool" } => TypeBool(), @@ -65,13 +65,13 @@ public partial class SpirvEmitter : Module public Instruction? TryGetUserDefined(string n) { - if(ShaderTypes.TryGetValue(n, out var i)) + if (ShaderTypes.TryGetValue(n, out var i)) return i.SpvType; else return null; } void CreateStructTypes() { - + } } diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index 9e97ca4b81..f30334dc14 100644 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -8,36 +8,26 @@ namespace Stride.Shaders.Spirv; -public class Register +public abstract class Register {} + +public class DeclareAssignRegister : Register { - private string? name; - public string Name - { - get => name ?? "id_" + GetHashCode(); - set => name = value; - } + public string Name {get;set;} + public AssignOpToken Op {get;set;} + public Register Value {get;set;} } -public class NamedRegister : Register +public class AssignRegister : Register { - - public override string ToString() - { - return Name; - } + public Register Left {get;set;} + public AssignOpToken Op {get;set;} + public Register Right {get;set;} } -public class ValueRegister : Register +public class AssignChainRegister : Register { - public ShaderLiteral Literal { get; set; } - public ValueRegister(ShaderLiteral v) - { - Literal = v; - Name = v.Value.ToString(); - } - public override string ToString() - { - return Literal.Value?.ToString() ?? "null"; - } + public IEnumerable NameChain {get;set;} + public AssignOpToken Op {get;set;} + public Register Value {get;set;} } public class OperationRegister : Register @@ -45,40 +35,26 @@ public class OperationRegister : Register public Register Left { get; set; } public Register Right { get; set; } public OperatorToken Op { get; set; } +} - public override string ToString() - { - return - new StringBuilder() - .Append(Name) - .Append(" = ") - .Append(Left.Name) - .Append(' ') - .Append(Op) - .Append(' ') - .Append(Right.Name) - .Append(';').ToString(); - } +public class ChainAccessorRegister : Register +{ + public IEnumerable Left { get; set; } + public IEnumerable Right { get; set; } } -public class AssignRegister : Register +public class ArrayAccessorRegister : Register { - public AssignOpToken Op {get;set;} - public Register Value {get;set;} + public Register Array { get; set; } + public Register Index { get; set; } +} + - public override string ToString() - { - return new StringBuilder().Append(Name).Append(' ').Append(Op).Append(' ').Append(Value.Name).ToString(); - } +public class VariableRegister : Register +{ + public string Name; } -public class AssignChainRegister : Register +public class LiteralRegister : Register { - public IEnumerable Chain {get;set;} - public AssignOpToken Op {get;set;} - public Register Value {get;set;} - - public override string ToString() - { - return new StringBuilder().Append(string.Join(".",Chain)).Append(' ').Append(Op).Append(' ').Append(Value.Name).ToString(); - } + public ShaderLiteral Value; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs index 2f2ab25242..8107d43850 100644 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -30,7 +30,7 @@ static IEnumerable Lower(AssignChain ac) var v = LowerToken(ac.Value); ac.LowCode = v.Append( new AssignChainRegister{ - Chain = ac.AccessNames, + NameChain = ac.AccessNames, Value = v.Last(), Op = ac.AssignOp } @@ -41,7 +41,7 @@ static IEnumerable Lower(DeclareAssign s) { var v = LowerToken(s.Value); s.LowCode = v.Append( - new AssignRegister{ + new DeclareAssignRegister{ Name = s.VariableName, Value = v.Last(), Op = s.AssignOp @@ -72,14 +72,17 @@ static IEnumerable Lower(Operation o) } static IEnumerable Lower(ChainAccessor lit) { - throw new NotImplementedException(); + return new Register[]{ + new ChainAccessorRegister{Left = LowerToken(lit.Value), Right = LowerToken(lit.Field)} + }; } static IEnumerable Lower(ShaderLiteral lit) { return new List{ lit switch { - NumberLiteral nl => new ValueRegister(nl), - _ => new ValueRegister(lit) + NumberLiteral nl => new LiteralRegister{Value = nl}, + VariableNameLiteral vn => new VariableRegister{Name = vn.Name}, + _ => throw new NotImplementedException() } }; } From b0d0301a9fc7613436dcb7fd0c23e1ef20053e85 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 12 Aug 2022 15:32:56 +0200 Subject: [PATCH 0131/1182] added array --- .../Compiler/Emitter/ThreeAddressElement.cs | 2 +- .../Parsers/AST/Lowering/Lowering.cs | 27 ++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index f30334dc14..7302e4d536 100644 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -46,7 +46,7 @@ public class ChainAccessorRegister : Register public class ArrayAccessorRegister : Register { public Register Array { get; set; } - public Register Index { get; set; } + public IEnumerable Indices { get; set; } } diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs index 8107d43850..bb30cd4f5f 100644 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -4,16 +4,17 @@ namespace Stride.Shaders.Parsing.AST.Shader; public static class Lowering { - public static IEnumerable LowerToken(ShaderToken token) + public static IEnumerable LowerToken(ShaderToken token) { - - return token switch + + return token switch { BlockStatement t => Lower(t), AssignChain t => Lower(t), DeclareAssign t => Lower(t), ConditionalExpression t => Lower(t), Operation t => Lower(t), + ArrayAccessor t => Lower(t), ChainAccessor t => Lower(t), ShaderLiteral t => Lower(t), _ => throw new NotImplementedException() @@ -29,7 +30,8 @@ static IEnumerable Lower(AssignChain ac) { var v = LowerToken(ac.Value); ac.LowCode = v.Append( - new AssignChainRegister{ + new AssignChainRegister + { NameChain = ac.AccessNames, Value = v.Last(), Op = ac.AssignOp @@ -41,7 +43,8 @@ static IEnumerable Lower(DeclareAssign s) { var v = LowerToken(s.Value); s.LowCode = v.Append( - new DeclareAssignRegister{ + new DeclareAssignRegister + { Name = s.VariableName, Value = v.Last(), Op = s.AssignOp @@ -76,6 +79,18 @@ static IEnumerable Lower(ChainAccessor lit) new ChainAccessorRegister{Left = LowerToken(lit.Value), Right = LowerToken(lit.Field)} }; } + static IEnumerable Lower(ArrayAccessor lit) + { + var array = LowerToken(lit.Value); + var accessors = lit.Accessors.SelectMany(LowerToken); + return + array + .Concat( + new Register[]{ + new ArrayAccessorRegister{Array = array.Last() , Indices = accessors} + } + ); + } static IEnumerable Lower(ShaderLiteral lit) { return new List{ @@ -86,5 +101,5 @@ static IEnumerable Lower(ShaderLiteral lit) } }; } - + } \ No newline at end of file From cf2ec60162a3fcd78c6b9005612519663e8d8421 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 18 Aug 2022 10:03:42 +0200 Subject: [PATCH 0132/1182] change of chain accessor --- .../Compiler/Emitter/ThreeAddressElement.cs | 17 +++++++++++------ .../Parsers/AST/Lowering/Lowering.cs | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index 7302e4d536..597c51be1c 100644 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -37,18 +37,23 @@ public class OperationRegister : Register public OperatorToken Op { get; set; } } -public class ChainAccessorRegister : Register +public class AccessorRegister : Register { - public IEnumerable Left { get; set; } - public IEnumerable Right { get; set; } + public Register Variable { get; set; } + public IEnumerable AccessorList { get; set; } } -public class ArrayAccessorRegister : Register +public abstract class AccessorTypes : Register{} + +public class FieldAccessor : AccessorTypes { - public Register Array { get; set; } - public IEnumerable Indices { get; set; } + public string Name { get; set; } } +public class IndexAccessor : AccessorTypes +{ + public Register Index { get; set; } +} public class VariableRegister : Register { diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs index bb30cd4f5f..46cf4a6017 100644 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -76,7 +76,7 @@ static IEnumerable Lower(Operation o) static IEnumerable Lower(ChainAccessor lit) { return new Register[]{ - new ChainAccessorRegister{Left = LowerToken(lit.Value), Right = LowerToken(lit.Field)} + new AccessorRegister{Variable = LowerToken(lit.Value), Right = LowerToken(lit.Field)} }; } static IEnumerable Lower(ArrayAccessor lit) From 303adaadc97d8aa9f854807abd51958a0adcfa72 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 18 Aug 2022 22:01:10 +0200 Subject: [PATCH 0133/1182] change accessor chain and array low code --- .../SDSL/MixinSamples/SingleShader.sdsl | 2 +- src/Spv.Generator | 2 +- .../Compiler/Emitter/ThreeAddressElement.cs | 12 +++- .../Parsers/AST/Lowering/Lowering.cs | 57 +++++++++++++------ .../Parsers/AST/Shader/ShaderToken.cs | 1 + .../Parsers/AST/Shader/UnaryLiterals.cs | 6 +- 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 2b237c504c..c9bfeefa78 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -27,6 +27,6 @@ shader SingleShader { void VSMain() { - streams.ShadingPosition = streams.triInput; + streams.ShadingPosition = a.dodo[5].machin[8][6]; } }; \ No newline at end of file diff --git a/src/Spv.Generator b/src/Spv.Generator index 0d17a5b461..a1473ad95f 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 0d17a5b46112541ed7345df0b9595b7b7f948071 +Subproject commit a1473ad95fbda4961e5eba2505f67a92f86ab51f diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs index 597c51be1c..cfedc32037 100644 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs @@ -43,7 +43,17 @@ public class AccessorRegister : Register public IEnumerable AccessorList { get; set; } } -public abstract class AccessorTypes : Register{} +public abstract class AccessorTypes : Register +{ + public static AccessorTypes From(Register r) + { + return r switch { + VariableRegister v => new FieldAccessor{Name = v.Name}, + LiteralRegister l => new IndexAccessor{Index = l}, + _ => throw new NotImplementedException() + }; + } +} public class FieldAccessor : AccessorTypes { diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs index 46cf4a6017..b2317d8b22 100644 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -4,7 +4,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public static class Lowering { - public static IEnumerable LowerToken(ShaderToken token) + public static IEnumerable LowerToken(ShaderToken token, bool isHead = true) { return token switch @@ -14,8 +14,8 @@ public static IEnumerable LowerToken(ShaderToken token) DeclareAssign t => Lower(t), ConditionalExpression t => Lower(t), Operation t => Lower(t), - ArrayAccessor t => Lower(t), - ChainAccessor t => Lower(t), + ArrayAccessor t => Lower(t, isHead), + ChainAccessor t => Lower(t, isHead), ShaderLiteral t => Lower(t), _ => throw new NotImplementedException() }; @@ -23,7 +23,7 @@ public static IEnumerable LowerToken(ShaderToken token) static IEnumerable Lower(BlockStatement b) { - b.LowCode = b.Statements.SelectMany(LowerToken); + b.LowCode = b.Statements.SelectMany(x => LowerToken(x)); return b.LowCode; } static IEnumerable Lower(AssignChain ac) @@ -73,23 +73,44 @@ static IEnumerable Lower(Operation o) } ); } - static IEnumerable Lower(ChainAccessor lit) + static IEnumerable Lower(ChainAccessor lit, bool isHead = true) { - return new Register[]{ - new AccessorRegister{Variable = LowerToken(lit.Value), Right = LowerToken(lit.Field)} - }; + // var a = streams.a.b.c[0][5] + if (!isHead) + { + var result = + LowerToken(lit.Value, false) + .Concat(lit.Field.SelectMany(x => LowerToken(x, false))); + return result; + } + else + { + var value = LowerToken(lit.Value, false); + var accessors = lit.Field.SelectMany(x => LowerToken(x, false)).Select(AccessorTypes.From); + return new Register[]{ + new AccessorRegister{Variable = value.Last(), AccessorList = accessors} + }; + } } - static IEnumerable Lower(ArrayAccessor lit) + static IEnumerable Lower(ArrayAccessor lit, bool isHead = true) { - var array = LowerToken(lit.Value); - var accessors = lit.Accessors.SelectMany(LowerToken); - return - array - .Concat( - new Register[]{ - new ArrayAccessorRegister{Array = array.Last() , Indices = accessors} - } - ); + if (!isHead) + { + var accessors = lit.Accessors.SelectMany(x => LowerToken(x, false)); + return LowerToken(lit.Value, false).Concat(accessors); + } + else + { + var array = LowerToken(lit.Value, false); + var accessors = lit.Accessors.SelectMany(x => LowerToken(x, false)).Select(AccessorTypes.From); + return + array + .Concat( + new Register[]{ + new AccessorRegister{Variable = array.Last() , AccessorList = accessors} + } + ); + } } static IEnumerable Lower(ShaderLiteral lit) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 84f99f930b..1a9210a80a 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -55,6 +55,7 @@ public static ShaderToken GetToken(Match match) "CastExpression" => new CastExpression(tmp), "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), "ChainAccessor" => new ChainAccessor(tmp), + "ArrayAccessor" => new ArrayAccessor(tmp), "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp), "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index 8d176e8e53..c1a98f24c2 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -16,13 +16,13 @@ public class UnaryExpression : Projector public class ChainAccessor : UnaryExpression { public ShaderToken Value { get; set; } - public ShaderToken Field { get; set; } + public IEnumerable Field { get; set; } public ChainAccessor(Match m) { Match = m; - Value = GetToken(m.Matches[0]); - Field = GetToken(m.Matches[1]); + Value = GetToken(m.Matches["Identifier"]); + Field = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); } } From cc171ba5b4b0f1c6c265d2230d2120e965aea421 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 25 Aug 2022 18:03:20 +0200 Subject: [PATCH 0134/1182] refactor --- src/SDSLParserExample/Program.cs | 1 + .../Compiler/Emitter/ThreeAddressElement.cs | 75 ----------- .../Compiler/ThreeAddress/Operators.cs | 38 ++++++ .../Compiler/ThreeAddress/Registers.cs | 60 +++++++++ .../Compiler/ThreeAddress/Snippet.cs | 15 +++ .../Parsers/AST/Lowering/Lowering.cs | 116 ++---------------- .../Parsers/AST/Shader/Statements.cs | 1 + 7 files changed, 126 insertions(+), 180 deletions(-) delete mode 100644 src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs create mode 100644 src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs create mode 100644 src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs create mode 100644 src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 2ff73dff06..a008708261 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -10,6 +10,7 @@ using Stride.Core.Shaders.Grammar.Stride; using Stride.Shaders.Parsing.AST.Shader; using Stride.Shaders.Mixer; +using Stride.Shaders.ThreeAddress; using Stride.Shaders; var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); diff --git a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs b/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs deleted file mode 100644 index cfedc32037..0000000000 --- a/src/Stride.Shaders/Compiler/Emitter/ThreeAddressElement.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Stride.Shaders.Parsing.AST.Shader; - -namespace Stride.Shaders.Spirv; - - -public abstract class Register {} - -public class DeclareAssignRegister : Register -{ - public string Name {get;set;} - public AssignOpToken Op {get;set;} - public Register Value {get;set;} -} - -public class AssignRegister : Register -{ - public Register Left {get;set;} - public AssignOpToken Op {get;set;} - public Register Right {get;set;} -} -public class AssignChainRegister : Register -{ - public IEnumerable NameChain {get;set;} - public AssignOpToken Op {get;set;} - public Register Value {get;set;} -} - -public class OperationRegister : Register -{ - public Register Left { get; set; } - public Register Right { get; set; } - public OperatorToken Op { get; set; } -} - -public class AccessorRegister : Register -{ - public Register Variable { get; set; } - public IEnumerable AccessorList { get; set; } -} - -public abstract class AccessorTypes : Register -{ - public static AccessorTypes From(Register r) - { - return r switch { - VariableRegister v => new FieldAccessor{Name = v.Name}, - LiteralRegister l => new IndexAccessor{Index = l}, - _ => throw new NotImplementedException() - }; - } -} - -public class FieldAccessor : AccessorTypes -{ - public string Name { get; set; } -} - -public class IndexAccessor : AccessorTypes -{ - public Register Index { get; set; } -} - -public class VariableRegister : Register -{ - public string Name; -} -public class LiteralRegister : Register -{ - public ShaderLiteral Value; -} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs b/src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs new file mode 100644 index 0000000000..4e99cc7918 --- /dev/null +++ b/src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs @@ -0,0 +1,38 @@ +namespace Stride.Shaders.ThreeAddress; + +public enum AssignOperator : byte +{ + Equal, + MulEqual, + DivEqual, + ModEqual, + PlusEqual, + MinusEqual, + LeftShiftEqual, + RightShiftEqual, + AndEqual, + OrEqual, + XorEqual +} + +public enum Operator : byte +{ + Mul, + Div, + Mod, + Plus, + Minus, + LeftShift, + RightShift, + And, + Or, + Xor, + Less, + Greater, + LessEqual, + GreaterEqual, + Equals, + NotEquals, + LogicalAnd, + LogicalOr +} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs b/src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs new file mode 100644 index 0000000000..54e92acc86 --- /dev/null +++ b/src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs @@ -0,0 +1,60 @@ +namespace Stride.Shaders.ThreeAddress; + + +public abstract class Register +{ + public string? Name {get;set;} +} + + +public class Copy : Register +{ + public string Value {get;set;} + + public Copy(string v) + { + Value = v; + } +} + +public class Assign : Register +{ + public string A {get;set;} + public string B {get;set;} + public Operator Op {get;set;} + + public Assign(string a, Operator op, string b) + { + A = a; + Op = op; + B = b; + } +} + +public abstract class Constant : Register {} +public class Constant : Constant +{ + public T Value; + + public Constant(T v) + { + Value = v; + } +} +public class CompositeConstant : Constant +{ + public IEnumerable Values; + + public CompositeConstant(IEnumerable v) + { + Values = v; + } +} + + +public class Accessor : Register{} + +public class AccessorChain : Register +{ + public List? Accessors {get;set;} +} diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs b/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs new file mode 100644 index 0000000000..e35368281f --- /dev/null +++ b/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs @@ -0,0 +1,15 @@ +namespace Stride.Shaders.ThreeAddress; +public class Snippet +{ + Dictionary LookUp {get;set;} = new(); + List IntermediateCode {get;set;} = new(); + + + public void Add(Register r) + { + IntermediateCode.Add(r); + if(r.Name is null) r.Name = $"Stride.T{IntermediateCode.Count}"; + LookUp[r.Name] = IntermediateCode.Count; + } + +} diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs index b2317d8b22..48d5201d16 100644 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Spirv; +using Stride.Shaders.ThreeAddress; namespace Stride.Shaders.Parsing.AST.Shader; @@ -9,118 +10,23 @@ public static IEnumerable LowerToken(ShaderToken token, bool isHead = return token switch { - BlockStatement t => Lower(t), - AssignChain t => Lower(t), - DeclareAssign t => Lower(t), - ConditionalExpression t => Lower(t), - Operation t => Lower(t), - ArrayAccessor t => Lower(t, isHead), - ChainAccessor t => Lower(t, isHead), + // BlockStatement t => Lower(t), + // AssignChain t => Lower(t), + // DeclareAssign t => Lower(t), + // ConditionalExpression t => Lower(t), + // Operation t => Lower(t), + // ArrayAccessor t => Lower(t, isHead), + // ChainAccessor t => Lower(t, isHead), ShaderLiteral t => Lower(t), _ => throw new NotImplementedException() }; } - static IEnumerable Lower(BlockStatement b) + public IEnumerable Lower(ShaderLiteral l) { - b.LowCode = b.Statements.SelectMany(x => LowerToken(x)); - return b.LowCode; - } - static IEnumerable Lower(AssignChain ac) - { - var v = LowerToken(ac.Value); - ac.LowCode = v.Append( - new AssignChainRegister - { - NameChain = ac.AccessNames, - Value = v.Last(), - Op = ac.AssignOp - } - ); - return ac.LowCode; - } - static IEnumerable Lower(DeclareAssign s) - { - var v = LowerToken(s.Value); - s.LowCode = v.Append( - new DeclareAssignRegister - { - Name = s.VariableName, - Value = v.Last(), - Op = s.AssignOp - } - ); - return s.LowCode; + } - static IEnumerable Lower(ConditionalExpression cexp) - { - var result = new List(); - return result; - } - - static IEnumerable Lower(Operation o) - { - IEnumerable l = LowerToken(o.Left); - IEnumerable r = LowerToken(o.Right); - - return l.Concat(r).Append( - new OperationRegister - { - Op = o.Op, - Left = l.Last(), - Right = r.Last() - } - ); - } - static IEnumerable Lower(ChainAccessor lit, bool isHead = true) - { - // var a = streams.a.b.c[0][5] - if (!isHead) - { - var result = - LowerToken(lit.Value, false) - .Concat(lit.Field.SelectMany(x => LowerToken(x, false))); - return result; - } - else - { - var value = LowerToken(lit.Value, false); - var accessors = lit.Field.SelectMany(x => LowerToken(x, false)).Select(AccessorTypes.From); - return new Register[]{ - new AccessorRegister{Variable = value.Last(), AccessorList = accessors} - }; - } - } - static IEnumerable Lower(ArrayAccessor lit, bool isHead = true) - { - if (!isHead) - { - var accessors = lit.Accessors.SelectMany(x => LowerToken(x, false)); - return LowerToken(lit.Value, false).Concat(accessors); - } - else - { - var array = LowerToken(lit.Value, false); - var accessors = lit.Accessors.SelectMany(x => LowerToken(x, false)).Select(AccessorTypes.From); - return - array - .Concat( - new Register[]{ - new AccessorRegister{Variable = array.Last() , AccessorList = accessors} - } - ); - } - } - static IEnumerable Lower(ShaderLiteral lit) - { - return new List{ - lit switch { - NumberLiteral nl => new LiteralRegister{Value = nl}, - VariableNameLiteral vn => new VariableRegister{Name = vn.Name}, - _ => throw new NotImplementedException() - } - }; - } + } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 92982feca7..a98c32725b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -2,6 +2,7 @@ using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; using Stride.Shaders.Spirv; +using Stride.Shaders.ThreeAddress; using System; using System.Collections.Generic; using System.Linq; From f1e9c5f32e43b6fa1cfd5323ee80fe51d42c92d9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 27 Aug 2022 17:05:42 +0200 Subject: [PATCH 0135/1182] some updates --- src/SDSLParserExample/Program.cs | 29 +++---- .../Compiler/Mixer/SimpleMixer.cs | 1 + .../Compiler/ThreeAddress/Snippet.cs | 15 ---- .../Parsers/AST/Lowering/Lowering.cs | 32 ------- .../Parsers/AST/Shader/Analysis/Analyzer.cs | 39 +++++++++ .../Parsers/AST/Shader/Literals.cs | 2 +- .../Parsers/AST/Shader/Operations.cs | 31 ++++--- .../Parsers/AST/Shader/ShaderMethods.cs | 20 ++--- .../Parsers/AST/Shader/ShaderToken.cs | 6 ++ .../Parsers/AST/Shader/Statements.cs | 23 ++++- .../Parsers/AST/Shader/UnaryLiterals.cs | 2 +- .../ThreeAddress/Operators.cs | 0 .../ThreeAddress/Registers.cs | 9 +- .../Parsers/ThreeAddress/Snippet.Lowering.cs | 87 +++++++++++++++++++ .../Parsers/ThreeAddress/Snippet.cs | 27 ++++++ 15 files changed, 219 insertions(+), 104 deletions(-) delete mode 100644 src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs delete mode 100644 src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs rename src/Stride.Shaders/{Compiler => Parsers}/ThreeAddress/Operators.cs (100%) rename src/Stride.Shaders/{Compiler => Parsers}/ThreeAddress/Registers.cs (86%) create mode 100644 src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs create mode 100644 src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index a008708261..dc1029d179 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -16,8 +16,8 @@ var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); // ShaderCompiling(shaderf); -// ThreeAddress(shaderf); -LoadShaders(); +ThreeAddress(); +// LoadShaders(); static void LoadShaders() { @@ -29,21 +29,20 @@ static void LoadShaders() var x = 0; } -static void ThreeAddress(string code) +static void ThreeAddress() { - var parser = new ShaderMixinParser(); - - ShaderProgram? ast = parser.Parse(code) as ShaderProgram; - var declare = ((ShaderMethod)ast.Body.First(x => x is ShaderMethod)).Statements.First(s => s is DeclareAssign) as DeclareAssign; - var s = new Stopwatch(); - _ = Lowering.LowerToken(declare).ToList(); - - s.Start(); - var x = Lowering.LowerToken(declare).ToList(); - s.Stop(); - x.ForEach(Console.WriteLine); - Console.WriteLine(s.Elapsed); + var o = + new Operation + { + Left = new NumberLiteral{Value = 5}, + Right = new NumberLiteral{Value = 6}, + Op = OperatorToken.Plus + }; + var s = new DeclareAssign(){VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + var snip = new Snippet(); + snip.Construct(s); + var x = 0; } diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 981cec179a..f103a517ac 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.AST.Shader; using Stride.Shaders.Spirv; +using Stride.Shaders.ThreeAddress; namespace Stride.Shaders.Mixer; diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs b/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs deleted file mode 100644 index e35368281f..0000000000 --- a/src/Stride.Shaders/Compiler/ThreeAddress/Snippet.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Stride.Shaders.ThreeAddress; -public class Snippet -{ - Dictionary LookUp {get;set;} = new(); - List IntermediateCode {get;set;} = new(); - - - public void Add(Register r) - { - IntermediateCode.Add(r); - if(r.Name is null) r.Name = $"Stride.T{IntermediateCode.Count}"; - LookUp[r.Name] = IntermediateCode.Count; - } - -} diff --git a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs b/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs deleted file mode 100644 index 48d5201d16..0000000000 --- a/src/Stride.Shaders/Parsers/AST/Lowering/Lowering.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Stride.Shaders.Spirv; -using Stride.Shaders.ThreeAddress; - -namespace Stride.Shaders.Parsing.AST.Shader; - -public static class Lowering -{ - public static IEnumerable LowerToken(ShaderToken token, bool isHead = true) - { - - return token switch - { - // BlockStatement t => Lower(t), - // AssignChain t => Lower(t), - // DeclareAssign t => Lower(t), - // ConditionalExpression t => Lower(t), - // Operation t => Lower(t), - // ArrayAccessor t => Lower(t, isHead), - // ChainAccessor t => Lower(t, isHead), - ShaderLiteral t => Lower(t), - _ => throw new NotImplementedException() - }; - } - - public IEnumerable Lower(ShaderLiteral l) - { - - } - - - -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs new file mode 100644 index 0000000000..d04aa27fea --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs @@ -0,0 +1,39 @@ +// namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +// public class Analyzer +// { +// public string? TypeChecking(ShaderToken t) +// { +// return t switch +// { +// Operation o => TypeCheck(o), +// NumberLiteral nl => TypeCheck(nl), +// VariableNameLiteral v => TypeCheck(v), +// _ => throw new NotImplementedException() +// }; +// } +// public string? TypeCheck(Operation o) +// { +// var left = TypeChecking(o.Left); +// var right = TypeChecking(o.Right); +// return Compare(left, right); +// } +// public string? TypeCheck(VariableNameLiteral v) +// { +// if(variables.TryGetValue(v.Name, out var saved)) +// { +// v.InferredType = saved.InferredType; +// return saved.InferredType; +// } +// else +// { +// variables[v.Name] = v; +// return null; +// } +// } +// public string? TypeCheck(NumberLiteral n) => n.InferredType; +// public string? Compare(string a, string b) +// { +// return a; +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 0604c8de70..0b9a8b2c6f 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -8,7 +8,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class ShaderLiteral : Projector +public class ShaderLiteral : Expression { public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public object Value {get;set;} diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 76f925fbda..d5f98f3b4d 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -10,33 +10,32 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class Expression : ShaderToken +public abstract class Expression : ShaderToken, ITyped { + string? inferredType; + public virtual string InferredType + { + get => inferredType ?? "int"; + set => inferredType = value; + } + + public string GetInferredType() + { + return InferredType; + } public virtual IEnumerable GetVariableNamesUsed() { return Array.Empty(); } } - -public abstract class Projector : Expression -{ - public virtual string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } -} - -public class Operation : Projector +public class Operation : Expression { public OperatorToken Op { get; set; } public ShaderToken Left { get; set; } public ShaderToken Right { get; set; } - string? inferredType; - public override string InferredType - { - get => inferredType ?? "int"; - set => inferredType = value; - } } @@ -308,7 +307,7 @@ public static LogicalOrExpression Create(Match m) } } -public class ConditionalExpression : Projector +public class ConditionalExpression : Expression { public ShaderToken Condition { get; set; } public ShaderToken TrueOutput { get; set; } @@ -316,7 +315,7 @@ public class ConditionalExpression : Projector string? inferredType; - public override string InferredType + public string InferredType { get => inferredType; set => inferredType = value; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index 9a419abe05..03a84488c3 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -26,14 +26,6 @@ public ShaderMethod(Match m) Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); } - public void Generate3Addr() - { - foreach (var s in Statements) - { - Lowering.LowerToken(s); - } - } - public static ShaderMethod Create(Match m) { return m["MethodName"].StringValue switch @@ -69,41 +61,41 @@ public class VSMainMethod : MainMethod { public VSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } public class PSMainMethod : MainMethod { public PSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } public class GSMainMethod : MainMethod { public GSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } public class CSMainMethod : MainMethod { public CSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } public class DSMainMethod : MainMethod { public DSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } public class HSMainMethod : MainMethod { public HSMainMethod(Match m) : base(m) { - Generate3Addr(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 1a9210a80a..41d2f88c01 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -8,6 +8,12 @@ namespace Stride.Shaders.Parsing.AST.Shader; +public interface ITyped +{ + public string GetInferredType(); +} + + public abstract class ShaderToken { public static string[] KeepValues = { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index a98c32725b..0250754838 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -12,19 +12,30 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public abstract class Statement : ShaderToken +public abstract class Statement : ShaderToken, ITyped { public IEnumerable LowCode {get;set;} + public virtual string InferredType{get => throw new NotImplementedException();set => throw new NotImplementedException();} + + public string GetInferredType() + { + return InferredType; + } } -public class EmptyStatement : Statement {} +public class EmptyStatement : Statement +{ + public override string InferredType => "void"; +} public class DeclareAssign : Statement { + public override string InferredType => "void"; public AssignOpToken AssignOp { get; set; } public string TypeName { get; set; } public string VariableName { get; set; } public ShaderToken Value { get; set; } + public DeclareAssign(){} public DeclareAssign(Match m ) { Match = m; @@ -37,6 +48,8 @@ public DeclareAssign(Match m ) public class AssignChain : Statement { + public override string InferredType => "void"; + public AssignOpToken AssignOp { get; set; } public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; public IEnumerable AccessNames { get; set; } @@ -52,12 +65,14 @@ public AssignChain(Match m) public class ReturnStatement : Statement { - public ShaderToken? ReturnValue {get;set;} + public override string InferredType => ReturnValue?.GetInferredType() ?? "void"; + + public ITyped? ReturnValue {get;set;} public ReturnStatement(Match m) { Match = m; if(m.HasMatches) - ReturnValue = GetToken(m["PrimaryExpression"]); + ReturnValue = (ITyped)GetToken(m["PrimaryExpression"]); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index c1a98f24c2..b46a422c82 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -8,7 +8,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class UnaryExpression : Projector +public class UnaryExpression : Expression { public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Operators.cs similarity index 100% rename from src/Stride.Shaders/Compiler/ThreeAddress/Operators.cs rename to src/Stride.Shaders/Parsers/ThreeAddress/Operators.cs diff --git a/src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs similarity index 86% rename from src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs rename to src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs index 54e92acc86..e615399d24 100644 --- a/src/Stride.Shaders/Compiler/ThreeAddress/Registers.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs @@ -51,10 +51,7 @@ public CompositeConstant(IEnumerable v) } } - -public class Accessor : Register{} - -public class AccessorChain : Register +public class ChainAccessorRegister : Register { - public List? Accessors {get;set;} -} + public IEnumerable? Accessors {get;set;} +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs new file mode 100644 index 0000000000..d09709509b --- /dev/null +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs @@ -0,0 +1,87 @@ +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Spirv; +using Stride.Shaders.ThreeAddress; + +namespace Stride.Shaders.ThreeAddress; + +public partial class Snippet +{ + + public IEnumerable LowerToken(ShaderToken token, bool isHead = true) + { + + return token switch + { + // BlockStatement t => Lower(t), + // AssignChain t => Lower(t), + DeclareAssign t => Lower(t), + // ConditionalExpression t => Lower(t), + Operation t => Lower(t), + ArrayAccessor t => Lower(t, isHead), + ChainAccessor t => Lower(t, isHead), + ShaderLiteral t => Lower(t), + _ => throw new NotImplementedException() + }; + } + + public IEnumerable Lower(DeclareAssign d) + { + var value = LowerToken(d.Value); + var r = new Copy(value.Last().Name){Name = d.VariableName}; + Add(r); + return value.Append(r); + } + + + public IEnumerable Lower(Operation o) + { + var left = LowerToken(o.Left); + var right = LowerToken(o.Right); + var r = new Assign(left.Last().Name, (Operator)o.Op, right.Last().Name); + Add(r); + return left.Concat(right).Append(r); + } + + public IEnumerable Lower(ChainAccessor ca, bool isHead = true) + { + if(!isHead) + { + return ca.Field.SelectMany(x => LowerToken(x,false)); + } + else + { + var accessors = ca.Field.SelectMany(x => LowerToken(x, false)); + var r = new ChainAccessorRegister(){Accessors = accessors.Select(x => x.Name)}; + Add(r); + return new List{r}; + } + } + public IEnumerable Lower(ArrayAccessor aa, bool isHead = true) + { + if(!isHead) + { + return aa.Accessors.SelectMany(x => LowerToken(x,false)); + } + else + { + var accessors = aa.Accessors.SelectMany(x => LowerToken(x, false)); + var r = new ChainAccessorRegister(){Accessors = accessors.Select(x => x.Name)}; + Add(r); + return new List{r}; + } + } + + public IEnumerable Lower(ShaderLiteral l) + { + var result = l switch { + NumberLiteral n => new List{new Constant(n)}, + VariableNameLiteral n => new List{new Constant(n){Name = n.Name}}, + _ => throw new NotImplementedException() + }; + foreach(var e in result) Add(e); + return result; + } + + + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs new file mode 100644 index 0000000000..50f0706aab --- /dev/null +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs @@ -0,0 +1,27 @@ +using Stride.Shaders.Parsing.AST.Shader; + +namespace Stride.Shaders.ThreeAddress; +public partial class Snippet +{ + Dictionary LookUp {get;set;} = new(); + List IntermediateCode {get;set;} = new(); + + + public void Add(Register r) + { + IntermediateCode.Add(r); + if(r.Name is null) r.Name = $"Stride.T{IntermediateCode.Count}"; + LookUp[r.Name] = IntermediateCode.Count; + } + public void Construct(params Statement[] statements) + { + Construct(statements.AsEnumerable()); + } + public void Construct(IEnumerable statements) + { + foreach(var s in statements) + { + LowerToken(s); + } + } +} From 01d1da1dfac317cde22c35353f899d76b2241c01 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 30 Aug 2022 10:15:49 +0200 Subject: [PATCH 0136/1182] update data --- src/Stride.Shaders/Compiler/Compilation.md | 8 -- .../Compiler/CompilationProcess.md | 93 +++++++++++++++++++ .../Parsers/AST/Shader/Analysis/Analyzer.cs | 75 ++++++++------- 3 files changed, 130 insertions(+), 46 deletions(-) delete mode 100644 src/Stride.Shaders/Compiler/Compilation.md create mode 100644 src/Stride.Shaders/Compiler/CompilationProcess.md diff --git a/src/Stride.Shaders/Compiler/Compilation.md b/src/Stride.Shaders/Compiler/Compilation.md deleted file mode 100644 index 00d9dd97f1..0000000000 --- a/src/Stride.Shaders/Compiler/Compilation.md +++ /dev/null @@ -1,8 +0,0 @@ -# Compilation - -SDSL should first be lowered to a three address code that ressembles SPIRV. -The idea is to manage this intermediate code for optimization of code instead of using `spirv-tools` which are c++ libraries. - -## Lowering - -Lowering will be done by \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/CompilationProcess.md b/src/Stride.Shaders/Compiler/CompilationProcess.md new file mode 100644 index 0000000000..084dc93539 --- /dev/null +++ b/src/Stride.Shaders/Compiler/CompilationProcess.md @@ -0,0 +1,93 @@ +# Compilation process + +## Parsing + + + + +```mermaid +flowchart TB + subgraph Parsing + StartParsing((start)) --> Load + Load[load shader] --> FirstParse[parse shader] + FirstParse --> HasMixins{has\n mixins ?} + HasMixins -->|yes|LoadOtherShaders[Load and parse other\n mixins recursively] + LoadOtherShaders --> ReorderMixins + ReorderMixins --> EndParsing((End)) + HasMixins -->|no|EndParsing((End)) + end + subgraph SemanticAnalysis + StartSemanticAnalysis((start)) --> VariableScope + VariableScope --> TypeChecking + TypeChecking --> MethodCall + MethodCall --> EndSemanticAnalysis((end)) + end + subgraph TACGen + StartTACGen((start)) --> Generation + Generation --> ExpressionOptimization + ExpressionOptimization --> ConditionalFlowOptimization + ConditionalFlowOptimization --> EndTACGen((end)) + end + subgraph SpirvGen + StartSpirvGen((start)) --> ConversionTAC2SpirvRepresentation + ConversionTAC2SpirvRepresentation --> SpirvRepresentation2bytecode + SpirvRepresentation2bytecode --> EndSpirvGen((end)) + end + Parsing --> SemanticAnalysis + SemanticAnalysis --> TACGen + TACGen --> SpirvGen +``` + + +## Shader caching + +```mermaid +flowchart TB + Start((start)) --> LoadStrideShaders + LoadStrideShaders --> LoadUserShader + LoadUserShader --> CacheShaders + CacheShaders --> ShaderDBEvent(Wait for shader event) + ShaderDBEvent --> IsShaderAdd{Is shader add ?} + IsShaderAdd -->|yes| LoadUserShader + IsShaderAdd -->|no| IsMixinUpdate{Is mixin update ?} + IsMixinUpdate --> QueryAndUpdate[Query and update shader] + QueryAndUpdate --> CacheShaders + +``` + + +```mermaid +classDiagram + class ShaderMixin + ShaderMixin: +String code + ShaderMixin: +ShaderProgram AST + ShaderMixin: +List~ShaderMixin~ mixins + ShaderMixin: +ShaderByteCode spirvByteCode + + class ShaderProgram + ShaderProgram: +List~ConstBufferValues~ cBuffer + ShaderProgram: +List~ShaderVariables~ variables + ShaderProgram: +List~ShaderMethod~ methods + + class ShaderMethod + ShaderMethod: +string Name + ShaderMethod: +bool IsStatic + ShaderMethod: +bool IsStream + ShaderMethod: +string returnType + ShaderMethod: +List~Variables~ params + ShaderMethod: +List~Statements~ statements + ShaderMethod: +List~TAC~ threeAddressCode + ShaderMethod: +... + + class ShaderByteCode + ShaderByteCode: +byte[] spirv + ShaderByteCode: +string glsl_code + ShaderByteCode: +string hlsl_code + ShaderByteCode: +string msl_code + + + + + + +``` \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs index d04aa27fea..9ebab37add 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs @@ -1,39 +1,38 @@ -// namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; -// public class Analyzer -// { -// public string? TypeChecking(ShaderToken t) -// { -// return t switch -// { -// Operation o => TypeCheck(o), -// NumberLiteral nl => TypeCheck(nl), -// VariableNameLiteral v => TypeCheck(v), -// _ => throw new NotImplementedException() -// }; -// } -// public string? TypeCheck(Operation o) -// { -// var left = TypeChecking(o.Left); -// var right = TypeChecking(o.Right); -// return Compare(left, right); -// } -// public string? TypeCheck(VariableNameLiteral v) -// { -// if(variables.TryGetValue(v.Name, out var saved)) -// { -// v.InferredType = saved.InferredType; -// return saved.InferredType; -// } -// else -// { -// variables[v.Name] = v; -// return null; -// } -// } -// public string? TypeCheck(NumberLiteral n) => n.InferredType; -// public string? Compare(string a, string b) -// { -// return a; -// } -// } \ No newline at end of file +public class SymbolTable +{ + Stack> Symbols; + + public SymbolTable() + { + Symbols = new(); + Symbols.Push(new()); + } + public SymbolTable(SymbolTable previous) + { + Symbols = new(); + foreach(var s in previous.Symbols) + Symbols.Push(s); + Symbols.Push(new()); + } + + public void AddVariable(VariableNameLiteral v) + { + foreach(var d in Symbols) + { + if(d.ContainsKey(v.Name)) + throw new Exception("Variable already declared at " + v.Match); + } + Symbols.Peek().Add(v.Name, v); + } + + public void SetType(string variableName, string type) + { + foreach(var d in Symbols) + { + if(d.TryGetValue(variableName, out var v)) + v.InferredType = type; + } + } +} \ No newline at end of file From f4cc15bff89d99b41c2854d8d2e70173734c3d7a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 30 Aug 2022 17:29:04 +0200 Subject: [PATCH 0137/1182] Basic type checking and variable duplication --- src/SDSLParserExample/Program.cs | 9 +- .../Parsers/AST/Shader/Analysis/Analyzer.cs | 38 -------- .../AST/Shader/Analysis/ShaderTokenTyped.cs | 7 ++ .../AST/Shader/Analysis/SymbolTable.cs | 46 +++++++++ .../Parsers/AST/Shader/Literals.cs | 27 ++++-- .../Parsers/AST/Shader/Operations.cs | 97 ++++++++++--------- .../Parsers/AST/Shader/ShaderToken.cs | 7 +- .../Parsers/AST/Shader/Statements.cs | 33 +++++-- 8 files changed, 155 insertions(+), 109 deletions(-) delete mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index dc1029d179..eab8833680 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -12,6 +12,7 @@ using Stride.Shaders.Mixer; using Stride.Shaders.ThreeAddress; using Stride.Shaders; +using Stride.Shaders.Parsing.AST.Shader.Analysis; var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); @@ -39,7 +40,13 @@ static void ThreeAddress() Right = new NumberLiteral{Value = 6}, Op = OperatorToken.Plus }; - var s = new DeclareAssign(){VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + + var symbols = new SymbolTable(); + var s = new DeclareAssign(){TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + symbols.PushVar(s); + var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = new VariableNameLiteral("dodo")}; + symbols.PushVar(s2); + var snip = new Snippet(); snip.Construct(s); var x = 0; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs deleted file mode 100644 index 9ebab37add..0000000000 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Analyzer.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; - -public class SymbolTable -{ - Stack> Symbols; - - public SymbolTable() - { - Symbols = new(); - Symbols.Push(new()); - } - public SymbolTable(SymbolTable previous) - { - Symbols = new(); - foreach(var s in previous.Symbols) - Symbols.Push(s); - Symbols.Push(new()); - } - - public void AddVariable(VariableNameLiteral v) - { - foreach(var d in Symbols) - { - if(d.ContainsKey(v.Name)) - throw new Exception("Variable already declared at " + v.Match); - } - Symbols.Peek().Add(v.Name, v); - } - - public void SetType(string variableName, string type) - { - foreach(var d in Symbols) - { - if(d.TryGetValue(variableName, out var v)) - v.InferredType = type; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs new file mode 100644 index 0000000000..c02cb616d9 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +public abstract class ShaderTokenTyped : ShaderToken +{ + public abstract string InferredType{get;set;} + public abstract void TypeCheck(SymbolTable symbols); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs new file mode 100644 index 0000000000..8f4ca621e7 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -0,0 +1,46 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +public class Symbol +{ + public string? Name {get;set;} + public string? Type {get;set;} + public DeclareAssign? Declaration {get;set;} +} + +public class SymbolTable : Stack> +{ + public Dictionary CurrentScope => Peek(); + public SymbolTable() + { + Push(new()); + } + + public void AddScope() => Push(new()); + + public void PushVar(Declaration a) + { + foreach(var d in this) + if(d.ContainsKey(a.VariableName)) + throw new Exception("Variable already declared at " + a.Match); + a.Value.TypeCheck(this); + CurrentScope.Add(a.VariableName, a); + } + + public void SetType(string variableName, string type) + { + foreach(var d in this) + if(d.TryGetValue(variableName, out var v)) + v.TypeName = type; + } + public bool TryGetType(string variableName, out string? type) + { + type = null; + foreach(var d in this) + if(d.TryGetValue(variableName, out var v)) + { + type = v.TypeName; + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 0b9a8b2c6f..788851b027 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; @@ -69,10 +70,7 @@ public class HexLiteral : NumberLiteral { public override string InferredType { - get - { - return "long"; - } + get => inferredType ?? "long"; set => inferredType = value; } @@ -87,7 +85,7 @@ public HexLiteral(Match match) } public class StringLiteral : ShaderLiteral { - public override string InferredType { get => "string"; set { } } + public override string InferredType { get => "string"; set => throw new NotImplementedException(); } public StringLiteral() { } @@ -100,7 +98,7 @@ public StringLiteral(Match match) public class BoolLiteral : ShaderLiteral { - public override string InferredType { get => "bool"; set { } } + public override string InferredType { get => "bool"; set => throw new NotImplementedException(); } public BoolLiteral() { } @@ -126,15 +124,26 @@ public class VariableNameLiteral : ShaderLiteral { public string Name { get; set; } - string? inferredType; - - public override string InferredType { get => inferredType; set => inferredType = value; } + public override string InferredType { get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; } + public VariableNameLiteral(string name) + { + Name = name; + } public VariableNameLiteral(Match m) { Name = m.StringValue; } + + public override void TypeCheck(SymbolTable symbols) + { + if(symbols.TryGetType(Name, out var type)) + { + this.inferredType = type; + } + else throw new NotImplementedException(); + } public override string ToString() { return $"{{ Variable : {Name} }}" ; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index d5f98f3b4d..07819360d1 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -1,5 +1,6 @@ using Eto.Parse; using Stride.Shaders.Parsing.AST.Directives; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; @@ -10,10 +11,10 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public abstract class Expression : ShaderToken, ITyped +public abstract class Expression : ShaderTokenTyped { - string? inferredType; - public virtual string InferredType + protected string? inferredType; + public override string InferredType { get => inferredType ?? "int"; set => inferredType = value; @@ -23,19 +24,25 @@ public string GetInferredType() { return InferredType; } - public virtual IEnumerable GetVariableNamesUsed() - { - return Array.Empty(); - } + public override void TypeCheck(SymbolTable symbols){} } public class Operation : Expression { public OperatorToken Op { get; set; } - public ShaderToken Left { get; set; } - public ShaderToken Right { get; set; } + public ShaderTokenTyped Left { get; set; } + public ShaderTokenTyped Right { get; set; } + public override void TypeCheck(SymbolTable symbols) + { + Left.TypeCheck(symbols); + Right.TypeCheck(symbols); + if(Left.InferredType == Right.InferredType) + InferredType = Left.InferredType; + else + throw new NotImplementedException(); + } } @@ -47,8 +54,8 @@ public static MulExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; MulExpression tmp = first; @@ -59,7 +66,7 @@ public static MulExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -74,8 +81,8 @@ public static SumExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; SumExpression tmp = first; @@ -86,7 +93,7 @@ public static SumExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -101,8 +108,8 @@ public static ShiftExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; ShiftExpression tmp = first; @@ -113,7 +120,7 @@ public static ShiftExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -128,8 +135,8 @@ public static AndExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; AndExpression tmp = first; @@ -140,7 +147,7 @@ public static AndExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -154,8 +161,8 @@ public static XorExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; XorExpression tmp = first; @@ -166,7 +173,7 @@ public static XorExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -180,8 +187,8 @@ public static OrExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; OrExpression tmp = first; @@ -192,7 +199,7 @@ public static OrExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -207,8 +214,8 @@ public static TestExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; TestExpression tmp = first; @@ -219,7 +226,7 @@ public static TestExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -234,8 +241,8 @@ public static EqualsExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; EqualsExpression tmp = first; @@ -246,7 +253,7 @@ public static EqualsExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -261,8 +268,8 @@ public static LogicalAndExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; LogicalAndExpression tmp = first; @@ -273,7 +280,7 @@ public static LogicalAndExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -288,8 +295,8 @@ public static LogicalOrExpression Create(Match m) { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0]), + Right = (ShaderTokenTyped)GetToken(m.Matches[2]) }; LogicalOrExpression tmp = first; @@ -300,7 +307,7 @@ public static LogicalOrExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) }; } return tmp; @@ -309,9 +316,9 @@ public static LogicalOrExpression Create(Match m) public class ConditionalExpression : Expression { - public ShaderToken Condition { get; set; } - public ShaderToken TrueOutput { get; set; } - public ShaderToken FalseOutput { get; set; } + public ShaderTokenTyped Condition { get; set; } + public ShaderTokenTyped TrueOutput { get; set; } + public ShaderTokenTyped FalseOutput { get; set; } string? inferredType; @@ -323,9 +330,9 @@ public string InferredType public ConditionalExpression(Match m) { - Condition = GetToken(m.Matches[0]); - TrueOutput = GetToken(m.Matches[1]); - FalseOutput = GetToken(m.Matches[2]); + Condition = (ShaderTokenTyped)GetToken(m.Matches[0]); + TrueOutput = (ShaderTokenTyped)GetToken(m.Matches[1]); + FalseOutput = (ShaderTokenTyped)GetToken(m.Matches[2]); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 41d2f88c01..df8d676c06 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -8,11 +8,6 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public interface ITyped -{ - public string GetInferredType(); -} - public abstract class ShaderToken { @@ -92,4 +87,4 @@ public IEnumerable GetAssignedStream() }; } -} +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 0250754838..87a7143003 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -1,6 +1,7 @@ using Eto.Parse; using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.ThreeAddress; using System; @@ -12,29 +13,41 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public abstract class Statement : ShaderToken, ITyped +public abstract class Statement : ShaderTokenTyped { public IEnumerable LowCode {get;set;} - public virtual string InferredType{get => throw new NotImplementedException();set => throw new NotImplementedException();} + public override string InferredType{get => throw new NotImplementedException();set => throw new NotImplementedException();} public string GetInferredType() { return InferredType; } + + public override void TypeCheck(SymbolTable symbols) + { + throw new NotImplementedException(); + } } public class EmptyStatement : Statement { public override string InferredType => "void"; + + public override void TypeCheck(SymbolTable symbols){} } -public class DeclareAssign : Statement +public abstract class Declaration : Statement { public override string InferredType => "void"; - public AssignOpToken AssignOp { get; set; } - public string TypeName { get; set; } + public string TypeName {get;set;} public string VariableName { get; set; } - public ShaderToken Value { get; set; } + public ShaderTokenTyped Value { get; set; } + +} + +public class DeclareAssign : Declaration +{ + public AssignOpToken AssignOp { get; set; } public DeclareAssign(){} public DeclareAssign(Match m ) { @@ -42,7 +55,7 @@ public DeclareAssign(Match m ) AssignOp = m["AssignOp"].StringValue.ToAssignOp(); TypeName = m["Type"].StringValue; VariableName = m["Variable"].StringValue; - Value = GetToken(m["Value"]); + Value = (ShaderTokenTyped)GetToken(m["Value"]); } } @@ -65,14 +78,14 @@ public AssignChain(Match m) public class ReturnStatement : Statement { - public override string InferredType => ReturnValue?.GetInferredType() ?? "void"; + public override string InferredType => ReturnValue?.InferredType ?? "void"; - public ITyped? ReturnValue {get;set;} + public ShaderTokenTyped? ReturnValue {get;set;} public ReturnStatement(Match m) { Match = m; if(m.HasMatches) - ReturnValue = (ITyped)GetToken(m["PrimaryExpression"]); + ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } } From 6f2523b776ca418362debe4c45efc1eeb6c8ed08 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 30 Aug 2022 18:33:37 +0200 Subject: [PATCH 0138/1182] number check, need check declaration --- src/SDSLParserExample/Program.cs | 9 +++++++- .../Parsers/AST/Shader/Operations.cs | 23 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index eab8833680..92d799cc57 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -44,7 +44,14 @@ static void ThreeAddress() var symbols = new SymbolTable(); var s = new DeclareAssign(){TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; symbols.PushVar(s); - var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = new VariableNameLiteral("dodo")}; + var o2 = + new Operation + { + Left = new VariableNameLiteral("dodo"), + Right = new NumberLiteral{Value = 6, InferredType = "float"}, + Op = OperatorToken.Plus + }; + var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2}; symbols.PushVar(s2); var snip = new Snippet(); diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 07819360d1..d484d60ef8 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -24,7 +24,7 @@ public string GetInferredType() { return InferredType; } - public override void TypeCheck(SymbolTable symbols){} + public override void TypeCheck(SymbolTable symbols) { } } public class Operation : Expression @@ -38,11 +38,30 @@ public override void TypeCheck(SymbolTable symbols) { Left.TypeCheck(symbols); Right.TypeCheck(symbols); - if(Left.InferredType == Right.InferredType) + if (Left.InferredType == Right.InferredType) InferredType = Left.InferredType; + else if (Left is NumberLiteral l && Right is NumberLiteral r) + CheckNumberComparison(l, r); else throw new NotImplementedException(); } + public void CheckNumberComparison(NumberLiteral l, NumberLiteral r) + { + if (l.Suffix is null && r.Suffix is null) + { + throw new NotImplementedException(); + } + else if (l.Suffix is not null && r.Suffix is null) + { + throw new NotImplementedException(); + } + else if (l.Suffix is null && r.Suffix is not null) + { + throw new NotImplementedException(); + } + else + throw new NotImplementedException("Wrong type"); + } } From 0e0b7b04301e947e6eeffb21ba831ad679f056a8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 1 Sep 2022 12:37:06 +0200 Subject: [PATCH 0139/1182] Simple type checker for expressions --- src/SDSLParserExample/Program.cs | 6 +- .../AST/Shader/Analysis/ShaderTokenTyped.cs | 2 +- .../AST/Shader/Analysis/SymbolTable.cs | 2 +- .../Parsers/AST/Shader/Literals.cs | 87 +++++++++++++------ .../Parsers/AST/Shader/Operations.cs | 37 +++++--- .../Parsers/AST/Shader/Statements.cs | 6 +- 6 files changed, 93 insertions(+), 47 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 92d799cc57..93ae6dbbfb 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -36,8 +36,8 @@ static void ThreeAddress() var o = new Operation { - Left = new NumberLiteral{Value = 5}, - Right = new NumberLiteral{Value = 6}, + Left = new NumberLiteral{Value = 5L}, + Right = new NumberLiteral{Value = 6L}, Op = OperatorToken.Plus }; @@ -48,7 +48,7 @@ static void ThreeAddress() new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral{Value = 6, InferredType = "float"}, + Right = new NumberLiteral{Value = 6L, InferredType = "float"}, Op = OperatorToken.Plus }; var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2}; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs index c02cb616d9..ca9cb5c6bb 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs @@ -3,5 +3,5 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; public abstract class ShaderTokenTyped : ShaderToken { public abstract string InferredType{get;set;} - public abstract void TypeCheck(SymbolTable symbols); + public abstract void TypeCheck(SymbolTable symbols, string expected = ""); } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 8f4ca621e7..59dddcccd3 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -22,7 +22,7 @@ public void PushVar(Declaration a) foreach(var d in this) if(d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); - a.Value.TypeCheck(this); + a.Value.TypeCheck(this, a.TypeName ?? ""); CurrentScope.Add(a.VariableName, a); } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 788851b027..15f865ba61 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -12,35 +12,17 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderLiteral : Expression { public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public object Value {get;set;} + public object Value { get; set; } } public class NumberLiteral : ShaderLiteral { public bool Negative { get; set; } = false; public string? Suffix { get; set; } - - protected string? inferredType; - - public override string InferredType + public override string InferredType { - get - { - if (inferredType is not null) - return inferredType; - else - { - return Suffix switch - { - "u" => "uint", - "l" => "long", - "f" => "float", - "d" => "double", - _ => "int" - }; - } - } - set => inferredType = value; + get => inferredType ?? throw new NotImplementedException(); + set => inferredType = value; } public NumberLiteral() { } @@ -65,10 +47,63 @@ public NumberLiteral(Match match) } } } + public override void TypeCheck(SymbolTable symbols, string expected) + { + if (Suffix is null) + { + if (expected != string.Empty) + { + inferredType = (Value, expected) switch + { + (_, "double") => "double", + (_, "float") => "float", + (_, "half") => "half", + (long l, "long") => "long", + (long l, "int") => "int", + (long l, "uint") => "uint", + (long l, "short") => "short", + (long l, "byte") => "byte", + (long l, "sbyte") => "sbyte", + _ => throw new NotImplementedException() + }; + } + else + { + inferredType = "int"; + } + } + else + { + if (expected != string.Empty) + { + inferredType = Suffix switch + { + "l" => "long", + "u" => "uint", + "f" => "float", + "d" => "double", + _ => throw new NotImplementedException() + }; + if (expected != inferredType) + throw new NotImplementedException(); + } + else + { + inferredType = Suffix switch + { + "l" => "long", + "u" => "uint", + "f" => "float", + "d" => "double", + _ => throw new NotImplementedException() + }; + } + } + } } public class HexLiteral : NumberLiteral { - public override string InferredType + public override string InferredType { get => inferredType ?? "long"; set => inferredType = value; @@ -136,9 +171,9 @@ public VariableNameLiteral(Match m) Name = m.StringValue; } - public override void TypeCheck(SymbolTable symbols) + public override void TypeCheck(SymbolTable symbols, string expected = "") { - if(symbols.TryGetType(Name, out var type)) + if (symbols.TryGetType(Name, out var type)) { this.inferredType = type; } @@ -146,6 +181,6 @@ public override void TypeCheck(SymbolTable symbols) } public override string ToString() { - return $"{{ Variable : {Name} }}" ; + return $"{{ Variable : {Name} }}"; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index d484d60ef8..a033c7ad83 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -16,7 +16,7 @@ public abstract class Expression : ShaderTokenTyped protected string? inferredType; public override string InferredType { - get => inferredType ?? "int"; + get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; } @@ -24,7 +24,7 @@ public string GetInferredType() { return InferredType; } - public override void TypeCheck(SymbolTable symbols) { } + public override void TypeCheck(SymbolTable symbols, string expected = "") { } } public class Operation : Expression @@ -34,22 +34,33 @@ public class Operation : Expression public ShaderTokenTyped Left { get; set; } public ShaderTokenTyped Right { get; set; } - public override void TypeCheck(SymbolTable symbols) + public override async void TypeCheck(SymbolTable symbols, string expected = "") { - Left.TypeCheck(symbols); - Right.TypeCheck(symbols); - if (Left.InferredType == Right.InferredType) - InferredType = Left.InferredType; - else if (Left is NumberLiteral l && Right is NumberLiteral r) - CheckNumberComparison(l, r); - else - throw new NotImplementedException(); + + if(expected != string.Empty) + { + Left.TypeCheck(symbols,expected); + Right.TypeCheck(symbols,expected); + if (Left.InferredType == Right.InferredType && Left.InferredType == expected) + InferredType = Left.InferredType; + else + throw new NotImplementedException(); + } + else + { + Left.TypeCheck(symbols); + Right.TypeCheck(symbols); + if(Left.InferredType != Right.InferredType) + throw new NotImplementedException(); + else + InferredType = Left.InferredType; + } } - public void CheckNumberComparison(NumberLiteral l, NumberLiteral r) + public void CheckNumberComparison(NumberLiteral l, NumberLiteral r, string expected) { if (l.Suffix is null && r.Suffix is null) { - throw new NotImplementedException(); + } else if (l.Suffix is not null && r.Suffix is null) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 87a7143003..522fc8cc16 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -23,7 +23,7 @@ public string GetInferredType() return InferredType; } - public override void TypeCheck(SymbolTable symbols) + public override void TypeCheck(SymbolTable symbols, string expected = "") { throw new NotImplementedException(); } @@ -33,13 +33,13 @@ public class EmptyStatement : Statement { public override string InferredType => "void"; - public override void TypeCheck(SymbolTable symbols){} + public override void TypeCheck(SymbolTable symbols, string expected = ""){} } public abstract class Declaration : Statement { public override string InferredType => "void"; - public string TypeName {get;set;} + public string? TypeName {get;set;} public string VariableName { get; set; } public ShaderTokenTyped Value { get; set; } From 21cbfd7b4c816369512414735b2e5c5ce115a1d3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 1 Sep 2022 20:10:50 +0200 Subject: [PATCH 0140/1182] interface for stream/static --- .../AST/Shader/Analysis/StaticCheck.cs | 15 ++++++++++++ .../Parsers/AST/Shader/ControlFlow.cs | 2 ++ .../Parsers/AST/Shader/Statements.cs | 23 +++++++++++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs new file mode 100644 index 0000000000..5a9d7268e9 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs @@ -0,0 +1,15 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + + +public interface IStaticCheck +{ + + public bool UsesShaderVar {get;set;} + public void CheckStatic(SymbolTable s); +} + +public interface IStreamCheck +{ + public bool UsesStream {get;set;} + public void CheckStream(SymbolTable s); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs index f441bfa877..2599e08899 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; namespace Stride.Shaders.Parsing.AST.Shader; @@ -92,5 +93,6 @@ public static ControlFlow Create(Match m) _ => throw new NotImplementedException() }; } + } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 522fc8cc16..710b713d80 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -15,6 +15,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Statement : ShaderTokenTyped { + public IEnumerable LowCode {get;set;} public override string InferredType{get => throw new NotImplementedException();set => throw new NotImplementedException();} @@ -32,7 +33,6 @@ public override void TypeCheck(SymbolTable symbols, string expected = "") public class EmptyStatement : Statement { public override string InferredType => "void"; - public override void TypeCheck(SymbolTable symbols, string expected = ""){} } @@ -45,9 +45,12 @@ public abstract class Declaration : Statement } -public class DeclareAssign : Declaration +public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck { public AssignOpToken AssignOp { get; set; } + public bool UsesStream { get; set;} + public bool UsesShaderVar {get;set;} + public DeclareAssign(){} public DeclareAssign(Match m ) { @@ -57,6 +60,18 @@ public DeclareAssign(Match m ) VariableName = m["Variable"].StringValue; Value = (ShaderTokenTyped)GetToken(m["Value"]); } + + public void CheckStatic(SymbolTable s) + { + if(Value is IStaticCheck sc) + sc.CheckStatic(s); + } + + public void CheckStream(SymbolTable s) + { + if(Value is IStreamCheck sc) + sc.CheckStream(s); + } } public class AssignChain : Statement @@ -66,13 +81,13 @@ public class AssignChain : Statement public AssignOpToken AssignOp { get; set; } public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; public IEnumerable AccessNames { get; set; } - public ShaderToken Value { get; set; } + public ShaderTokenTyped Value { get; set; } public AssignChain(Match m) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); - Value = GetToken(m["PrimaryExpression"]); + Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } } From 57258573e95481f4f09fe8c8dc36459b0d4e0a40 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 1 Sep 2022 22:32:46 +0200 Subject: [PATCH 0141/1182] change to interface --- .../AST/Shader/Analysis/StaticCheck.cs | 10 ++-- .../Parsers/AST/Shader/Operations.cs | 29 +++++------ .../Parsers/AST/Shader/ShaderToken.cs | 40 ++++++++-------- .../Parsers/AST/Shader/Statements.cs | 48 +++++++++++++++---- 4 files changed, 75 insertions(+), 52 deletions(-) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs index 5a9d7268e9..8884c7fec5 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs @@ -3,13 +3,13 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; public interface IStaticCheck { - - public bool UsesShaderVar {get;set;} - public void CheckStatic(SymbolTable s); + public bool CheckStatic(SymbolTable s); } public interface IStreamCheck { - public bool UsesStream {get;set;} - public void CheckStream(SymbolTable s); + public bool CheckStream(SymbolTable s); + public IEnumerable GetUsedStream(); + public IEnumerable GetAssignedStream(); + } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index a033c7ad83..42ac791a89 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -27,13 +27,13 @@ public string GetInferredType() public override void TypeCheck(SymbolTable symbols, string expected = "") { } } -public class Operation : Expression +public class Operation : Expression, IStreamCheck, IStaticCheck { public OperatorToken Op { get; set; } public ShaderTokenTyped Left { get; set; } public ShaderTokenTyped Right { get; set; } - + public override async void TypeCheck(SymbolTable symbols, string expected = "") { @@ -56,22 +56,17 @@ public override async void TypeCheck(SymbolTable symbols, string expected = "") InferredType = Left.InferredType; } } - public void CheckNumberComparison(NumberLiteral l, NumberLiteral r, string expected) + + public bool CheckStream(SymbolTable s) { - if (l.Suffix is null && r.Suffix is null) - { - - } - else if (l.Suffix is not null && r.Suffix is null) - { - throw new NotImplementedException(); - } - else if (l.Suffix is null && r.Suffix is not null) - { - throw new NotImplementedException(); - } - else - throw new NotImplementedException("Wrong type"); + return Left is IStreamCheck scl && scl.CheckStream(s) + || Right is IStreamCheck scr && scr.CheckStream(s); + } + + public bool CheckStatic(SymbolTable s) + { + return Left is IStaticCheck scl && scl.CheckStatic(s) + || Right is IStaticCheck scr && scr.CheckStatic(s); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index df8d676c06..59b81680ff 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -66,25 +66,25 @@ public static ShaderToken GetToken(Match match) } - public IEnumerable GetUsedStream() - { - return this switch - { - AssignChain a => a.Value.GetUsedStream(), - ChainAccessor{Value: VariableNameLiteral{Name : "streams"}} => new string[1]{((VariableNameLiteral)((ChainAccessor)this).Field).Name}, - Operation {Left : ChainAccessor c} => c.GetUsedStream(), - Operation {Right : ChainAccessor c} => c.GetUsedStream(), - _ => Array.Empty() - }; - } - public IEnumerable GetAssignedStream() - { - return this switch - { - AssignChain{StreamValue: true} c => new string[1]{c.AccessNames.ElementAt(1)}, - BlockStatement b => b.Statements.SelectMany(x => x.GetAssignedStream()), - _ => Array.Empty() - }; - } + // public IEnumerable GetUsedStream() + // { + // return this switch + // { + // AssignChain a => a.Value.GetUsedStream(), + // ChainAccessor{Value: VariableNameLiteral{Name : "streams"}} => new string[1]{((VariableNameLiteral)((ChainAccessor)this).Field).Name}, + // Operation {Left : ChainAccessor c} => c.GetUsedStream(), + // Operation {Right : ChainAccessor c} => c.GetUsedStream(), + // _ => Array.Empty() + // }; + // } + // public IEnumerable GetAssignedStream() + // { + // return this switch + // { + // AssignChain{StreamValue: true} c => new string[1]{c.AccessNames.ElementAt(1)}, + // BlockStatement b => b.Statements.SelectMany(x => x.GetAssignedStream()), + // _ => Array.Empty() + // }; + // } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 710b713d80..49f2282e85 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -48,9 +48,7 @@ public abstract class Declaration : Statement public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck { public AssignOpToken AssignOp { get; set; } - public bool UsesStream { get; set;} - public bool UsesShaderVar {get;set;} - + public DeclareAssign(){} public DeclareAssign(Match m ) { @@ -61,20 +59,20 @@ public DeclareAssign(Match m ) Value = (ShaderTokenTyped)GetToken(m["Value"]); } - public void CheckStatic(SymbolTable s) + public bool CheckStatic(SymbolTable s) { - if(Value is IStaticCheck sc) + return Value is IStaticCheck sc && sc.CheckStatic(s); } - public void CheckStream(SymbolTable s) + public bool CheckStream(SymbolTable s) { - if(Value is IStreamCheck sc) + return Value is IStreamCheck sc && sc.CheckStream(s); } } -public class AssignChain : Statement +public class AssignChain : Statement, IStreamCheck, IStaticCheck { public override string InferredType => "void"; @@ -89,9 +87,19 @@ public AssignChain(Match m) AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } + + public bool CheckStream(SymbolTable s) + { + return StreamValue || Value is IStreamCheck isc && isc.CheckStream(s); + } + + public bool CheckStatic(SymbolTable s) + { + return Value is IStaticCheck isc && isc.CheckStatic(s); + } } -public class ReturnStatement : Statement +public class ReturnStatement : Statement, IStreamCheck, IStaticCheck { public override string InferredType => ReturnValue?.InferredType ?? "void"; @@ -102,9 +110,19 @@ public ReturnStatement(Match m) if(m.HasMatches) ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } + + public bool CheckStream(SymbolTable s) + { + return ReturnValue is IStreamCheck sc && sc.CheckStream(s); + } + + public bool CheckStatic(SymbolTable s) + { + return ReturnValue is IStaticCheck sc && sc.CheckStatic(s); + } } -public class BlockStatement : Statement +public class BlockStatement : Statement, IStreamCheck, IStaticCheck { public IEnumerable Statements {get;set;} public BlockStatement(Match m) @@ -112,4 +130,14 @@ public BlockStatement(Match m) Match = m; Statements = m.Matches.Select(GetToken).Cast().ToList(); } + + public bool CheckStream(SymbolTable s) + { + return Statements.Any(x => x is IStreamCheck isc && isc.CheckStream(s)); + } + + public bool CheckStatic(SymbolTable s) + { + return Statements.Any(x => x is IStaticCheck isc && isc.CheckStatic(s)); + } } From 01209a96d6d3125099a2c61825660fca9abb57f2 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 12 Sep 2022 13:11:03 +0200 Subject: [PATCH 0142/1182] update operation --- src/SDSLParserExample/Program.cs | 2 +- src/Stride.Shaders.Test/ASTTypeChecking.cs | 91 +++++++++++++++++++ .../Parsers/AST/Shader/Operations.cs | 33 +++---- 3 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 src/Stride.Shaders.Test/ASTTypeChecking.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 93ae6dbbfb..2e29522dec 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -42,7 +42,7 @@ static void ThreeAddress() }; var symbols = new SymbolTable(); - var s = new DeclareAssign(){TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + var s = new DeclareAssign(){TypeName = "float", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; symbols.PushVar(s); var o2 = new Operation diff --git a/src/Stride.Shaders.Test/ASTTypeChecking.cs b/src/Stride.Shaders.Test/ASTTypeChecking.cs new file mode 100644 index 0000000000..eb6bd6cbec --- /dev/null +++ b/src/Stride.Shaders.Test/ASTTypeChecking.cs @@ -0,0 +1,91 @@ +using Xunit; +using System.Linq; +using Stride.Shaders.Parsing; +using System.Collections.Generic; +using Stride.Shaders.Parsing.AST.Shader.Analysis; +using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.ThreeAddress; + +namespace Stride.Shaders.Parsing.Test; + +public class ASTTypeChecking +{ + [Fact] + public void TypeCheckIntWithFloatCastedToInt() + { + var o = + new Operation + { + Left = new NumberLiteral { Value = 5L }, + Right = new NumberLiteral { Value = 6L }, + Op = OperatorToken.Plus + }; + + var symbols = new SymbolTable(); + var s = new DeclareAssign() { TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + symbols.PushVar(s); + var o2 = + new Operation + { + Left = new VariableNameLiteral("dodo"), + Right = new NumberLiteral { Value = 6L, InferredType = "float" }, + Op = OperatorToken.Plus + }; + var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; + symbols.PushVar(s2); + Assert.Equal("int", s2.InferredType); + + } + [Fact] + public void TypeCheckInt() + { + var o = + new Operation + { + Left = new NumberLiteral { Value = 5L }, + Right = new NumberLiteral { Value = 6L }, + Op = OperatorToken.Plus + }; + + var symbols = new SymbolTable(); + var s = new DeclareAssign() { TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + symbols.PushVar(s); + var o2 = + new Operation + { + Left = new VariableNameLiteral("dodo"), + Right = new NumberLiteral { Value = 6L, InferredType = "int" }, + Op = OperatorToken.Plus + }; + var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; + symbols.PushVar(s2); + Assert.Equal("int", s2.InferredType); + + } + [Fact] + public void TypeCheckFloat() + { + var o = + new Operation + { + Left = new NumberLiteral { Value = 5L }, + Right = new NumberLiteral { Value = 6L }, + Op = OperatorToken.Plus + }; + + var symbols = new SymbolTable(); + var s = new DeclareAssign() { TypeName = "float", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + symbols.PushVar(s); + var o2 = + new Operation + { + Left = new VariableNameLiteral("dodo"), + Right = new NumberLiteral { Value = 6L, InferredType = "int" }, + Op = OperatorToken.Plus + }; + var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; + symbols.PushVar(s2); + Assert.Equal("float", s2.InferredType); + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index a033c7ad83..5176325faf 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -36,42 +36,37 @@ public class Operation : Expression public override async void TypeCheck(SymbolTable symbols, string expected = "") { - - if(expected != string.Empty) + + if (expected != string.Empty) { - Left.TypeCheck(symbols,expected); - Right.TypeCheck(symbols,expected); + Left.TypeCheck(symbols, expected); + Right.TypeCheck(symbols, expected); if (Left.InferredType == Right.InferredType && Left.InferredType == expected) InferredType = Left.InferredType; else throw new NotImplementedException(); } - else + else { Left.TypeCheck(symbols); Right.TypeCheck(symbols); - if(Left.InferredType != Right.InferredType) - throw new NotImplementedException(); + if (Left.InferredType != Right.InferredType) + { + if(CheckImplicitCasting(Left,Right,expected)) + return; + else throw new NotImplementedException(); + } else InferredType = Left.InferredType; } } - public void CheckNumberComparison(NumberLiteral l, NumberLiteral r, string expected) + public bool CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string expected) { - if (l.Suffix is null && r.Suffix is null) + if (expected is not null) { } - else if (l.Suffix is not null && r.Suffix is null) - { - throw new NotImplementedException(); - } - else if (l.Suffix is null && r.Suffix is not null) - { - throw new NotImplementedException(); - } - else - throw new NotImplementedException("Wrong type"); + return true; } } From 81ccdf02b731c703688187f6086a8f4f6fb9779a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 12 Sep 2022 17:38:18 +0200 Subject: [PATCH 0143/1182] Simple type checking for variables --- .../AST/Shader/Analysis/NumberTypeCasting.cs | 17 +++++ .../Parsers/AST/Shader/Operations.cs | 37 +++++++--- .../Parsers/AST/Shader/ShaderMethods.cs | 6 +- .../Parsers/AST/Shader/Statements.cs | 68 +++++++++++++++---- 4 files changed, 105 insertions(+), 23 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs new file mode 100644 index 0000000000..11239dbb75 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs @@ -0,0 +1,17 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +public class NumberTypeCasting +{ + static Dictionary implicitCastingException = new Dictionary{ + {"byte", new string[0]}, + {"sbyte", new string[0]}, + {"short", new string[]{"byte","sbyte"}}, + {"ushort", new string[]{"byte","sbyte"}}, + {"half", new string[]{"byte","sbyte"}}, + {"int", new string[]{"sbyte", "ushort", "short"}}, + {"uint", new string[]{"sbyte", "ushort", "short"}}, + {"byte", new string[]{"sbyte", "ushort", "short"}}, + {"byte", new string[]{"sbyte", "ushort", "short"}}, + + }; +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index b13cb576c1..8f3391f472 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -33,7 +33,7 @@ public class Operation : Expression, IStreamCheck, IStaticCheck public ShaderTokenTyped Left { get; set; } public ShaderTokenTyped Right { get; set; } - + public override async void TypeCheck(SymbolTable symbols, string expected = "") { @@ -52,15 +52,27 @@ public override async void TypeCheck(SymbolTable symbols, string expected = "") Right.TypeCheck(symbols); if (Left.InferredType != Right.InferredType) { - if(CheckImplicitCasting(Left,Right,expected)) - return; - else throw new NotImplementedException(); + CheckImplicitCasting(Left, Right, expected); } else InferredType = Left.InferredType; } } + public IEnumerable GetUsedStream() + { + var result = Enumerable.Empty(); + if (Left is IStreamCheck lsc) + result.Concat(lsc.GetUsedStream()); + if (Right is IStreamCheck rsc) + result.Concat(rsc.GetUsedStream()); + return result; + } + public IEnumerable GetAssignedStream() + { + return Enumerable.Empty(); + } + public bool CheckStream(SymbolTable s) { return Left is IStreamCheck scl && scl.CheckStream(s) @@ -72,13 +84,20 @@ public bool CheckStatic(SymbolTable s) return Left is IStaticCheck scl && scl.CheckStatic(s) || Right is IStaticCheck scr && scr.CheckStatic(s); } - public bool CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string expected) + public void CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string expected) { - if (expected is not null) - { + - } - return true; + InferredType = (l.InferredType, r.InferredType, expected) switch + { + ("int","float", "int") => "int", + ("int","float", "float") => "float", + ("float","int", "int") => "int", + ("float","int", "float") => "float", + ("int","float", "") => "float", + ("float","int", "") => "float", + _ => throw new Exception($"Cannot cast types") + }; } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index 03a84488c3..90bc1819ff 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -1,8 +1,10 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; namespace Stride.Shaders.Parsing.AST.Shader; + public class ShaderMethod : ShaderToken { public bool IsStatic { get; set; } @@ -47,11 +49,11 @@ public MainMethod(Match m) : base(m) { } public IEnumerable GetStreamValuesAssigned() { - return Statements.SelectMany(x => x.GetAssignedStream()); + return Statements.OfType().SelectMany(x => x.GetAssignedStream()); } public IEnumerable GetStreamValuesUsed() { - return Statements.SelectMany(x => x.GetUsedStream()); + return Statements.OfType().SelectMany(x => x.GetUsedStream()); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 49f2282e85..b598511a6b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -15,9 +15,9 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Statement : ShaderTokenTyped { - - public IEnumerable LowCode {get;set;} - public override string InferredType{get => throw new NotImplementedException();set => throw new NotImplementedException();} + + public IEnumerable LowCode { get; set; } + public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public string GetInferredType() { @@ -33,13 +33,13 @@ public override void TypeCheck(SymbolTable symbols, string expected = "") public class EmptyStatement : Statement { public override string InferredType => "void"; - public override void TypeCheck(SymbolTable symbols, string expected = ""){} + public override void TypeCheck(SymbolTable symbols, string expected = "") { } } public abstract class Declaration : Statement { public override string InferredType => "void"; - public string? TypeName {get;set;} + public string? TypeName { get; set; } public string VariableName { get; set; } public ShaderTokenTyped Value { get; set; } @@ -48,9 +48,9 @@ public abstract class Declaration : Statement public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck { public AssignOpToken AssignOp { get; set; } - - public DeclareAssign(){} - public DeclareAssign(Match m ) + + public DeclareAssign() { } + public DeclareAssign(Match m) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); @@ -70,6 +70,16 @@ public bool CheckStream(SymbolTable s) return Value is IStreamCheck sc && sc.CheckStream(s); } + public IEnumerable GetUsedStream() + { + if (Value is IStreamCheck val) + return val.GetUsedStream(); + return Enumerable.Empty(); + } + public IEnumerable GetAssignedStream() + { + return Enumerable.Empty(); + } } public class AssignChain : Statement, IStreamCheck, IStaticCheck @@ -93,6 +103,21 @@ public bool CheckStream(SymbolTable s) return StreamValue || Value is IStreamCheck isc && isc.CheckStream(s); } + public IEnumerable GetAssignedStream() + { + if (StreamValue) + return new List() { AccessNames.ElementAt(1) }; + else + return Enumerable.Empty(); + } + public IEnumerable GetUsedStream() + { + if (Value is IStreamCheck v) + return v.GetUsedStream(); + else + return Enumerable.Empty(); + } + public bool CheckStatic(SymbolTable s) { return Value is IStaticCheck isc && isc.CheckStatic(s); @@ -102,12 +127,12 @@ public bool CheckStatic(SymbolTable s) public class ReturnStatement : Statement, IStreamCheck, IStaticCheck { public override string InferredType => ReturnValue?.InferredType ?? "void"; - - public ShaderTokenTyped? ReturnValue {get;set;} + + public ShaderTokenTyped? ReturnValue { get; set; } public ReturnStatement(Match m) { Match = m; - if(m.HasMatches) + if (m.HasMatches) ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } @@ -116,6 +141,17 @@ public bool CheckStream(SymbolTable s) return ReturnValue is IStreamCheck sc && sc.CheckStream(s); } + public IEnumerable GetUsedStream() + { + if (ReturnValue is IStreamCheck isc) + return isc.GetUsedStream(); + return Enumerable.Empty(); + } + public IEnumerable GetAssignedStream() + { + return Enumerable.Empty(); + } + public bool CheckStatic(SymbolTable s) { return ReturnValue is IStaticCheck sc && sc.CheckStatic(s); @@ -124,7 +160,7 @@ public bool CheckStatic(SymbolTable s) public class BlockStatement : Statement, IStreamCheck, IStaticCheck { - public IEnumerable Statements {get;set;} + public IEnumerable Statements { get; set; } public BlockStatement(Match m) { Match = m; @@ -135,6 +171,14 @@ public bool CheckStream(SymbolTable s) { return Statements.Any(x => x is IStreamCheck isc && isc.CheckStream(s)); } + public IEnumerable GetUsedStream() + { + return Statements.OfType().SelectMany(x => x.GetUsedStream()); + } + public IEnumerable GetAssignedStream() + { + return Statements.OfType().SelectMany(x => x.GetAssignedStream()); + } public bool CheckStatic(SymbolTable s) { From e43839f51a2281577a3752dd0ca497a7e4f05e7e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 13 Sep 2022 14:28:10 +0200 Subject: [PATCH 0144/1182] Implementation stream checking --- src/SDSLParserExample/Program.cs | 7 ++++--- .../SDSL/MixinSamples/SingleShader.sdsl | 1 + .../Compiler/Mixer/SimpleMixer.cs | 2 +- .../Parsers/AST/Shader/UnaryLiterals.cs | 18 +++++++++++++++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 2e29522dec..994959ffca 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -17,8 +17,8 @@ var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); // ShaderCompiling(shaderf); -ThreeAddress(); -// LoadShaders(); +// ThreeAddress(); +LoadShaders(); static void LoadShaders() { @@ -26,7 +26,8 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - var module = mixer.EmitSpirv(EntryPoints.VSMain); + // var module = mixer.EmitSpirv(EntryPoints.VSMain); + var used = mixer.program.Body.OfType().First().GetStreamValuesUsed().ToList(); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index c9bfeefa78..34b59e3342 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -28,5 +28,6 @@ shader SingleShader { void VSMain() { streams.ShadingPosition = a.dodo[5].machin[8][6]; + streams.Depth = streams.ShadingPosition; } }; \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index f103a517ac..18bec045f4 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Mixer; public class SimpleMixer { ShaderClassString source; - ShaderProgram program; + public ShaderProgram program; List il; public SimpleMixer(string className, ShaderSourceManager manager) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index b46a422c82..85c5359fbd 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; @@ -13,7 +14,7 @@ public class UnaryExpression : Expression public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } -public class ChainAccessor : UnaryExpression +public class ChainAccessor : UnaryExpression, IStreamCheck { public ShaderToken Value { get; set; } public IEnumerable Field { get; set; } @@ -24,6 +25,21 @@ public ChainAccessor(Match m) Value = GetToken(m.Matches["Identifier"]); Field = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); } + + public IEnumerable GetUsedStream() + { + if(Value is VariableNameLiteral vn && vn.Name == "streams") + return new List{((VariableNameLiteral)Field.First()).Name}; + return Enumerable.Empty(); + } + public IEnumerable GetAssignedStream() + { + return Enumerable.Empty(); + } + public bool CheckStream(SymbolTable symbols) + { + return GetUsedStream().Any(); + } } public class ArrayAccessor : UnaryExpression From c992376ba04d1d4265407c7c62a0b2902a0639de Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 13 Sep 2022 16:41:37 +0200 Subject: [PATCH 0145/1182] Simple variable checking --- src/SDSLParserExample/Program.cs | 4 +- .../SDSL/MixinSamples/SingleShader.sdsl | 3 +- .../Compiler/Emitter/SpirvEmitter.cs | 2 +- .../Compiler/Mixer/SimpleMixer.cs | 11 ++++++ .../AST/Shader/Analysis/StaticCheck.cs | 5 +++ .../AST/Shader/Analysis/SymbolTable.Check.cs | 11 ++++++ .../AST/Shader/Analysis/SymbolTable.cs | 37 ++++++++++++++----- .../Parsers/AST/Shader/Literals.cs | 8 +++- .../Parsers/AST/Shader/Operations.cs | 10 +++-- .../Parsers/AST/Shader/ShaderMethods.cs | 6 +++ .../Parsers/AST/Shader/Statements.cs | 9 ++++- .../Parsers/AST/Shader/UnaryLiterals.cs | 18 +++++++-- 12 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 994959ffca..3a60828227 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -26,7 +26,9 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - // var module = mixer.EmitSpirv(EntryPoints.VSMain); + mixer.SemanticChecks(); + + var module = mixer.EmitSpirv(EntryPoints.VSMain); var used = mixer.program.Body.OfType().First().GetStreamValuesUsed().ToList(); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 34b59e3342..213f1ec8c4 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -27,7 +27,8 @@ shader SingleShader { void VSMain() { - streams.ShadingPosition = a.dodo[5].machin[8][6]; + int a = 0; + streams.ShadingPosition = a; streams.Depth = streams.ShadingPosition; } }; \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 29637a13b2..3d01ad7765 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -14,7 +14,7 @@ public partial class SpirvEmitter : Module { public Dictionary ShaderTypes {get;set;} public Dictionary ShaderFunctionTypes {get;set;} - public Dictionary Variables {get;set;} + public Dictionary Variables {get;set;} = new(); public SpirvEmitter(uint version) : base(version) { ShaderTypes = new(); diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 18bec045f4..a7f4afa405 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -1,6 +1,7 @@ using Spv.Generator; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.ThreeAddress; @@ -18,6 +19,16 @@ public SimpleMixer(string className, ShaderSourceManager manager) program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); il = new(); } + public void SemanticChecks() + { + var sym = new SymbolTable(); + sym.PushStream(); + sym.AddScope(); + foreach(var method in program.Body.OfType()) + { + method.VariableChecking(sym); + } + } public Module EmitSpirv(EntryPoints entry) { var spirv = new SpirvEmitter(455); diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs index 8884c7fec5..df4437ae16 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs @@ -12,4 +12,9 @@ public interface IStreamCheck public IEnumerable GetUsedStream(); public IEnumerable GetAssignedStream(); +} + +public interface IVariableCheck +{ + public void CheckVariables(SymbolTable s); } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs new file mode 100644 index 0000000000..489a344387 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + + +public partial class SymbolTable +{ + public void CheckVar(Statement s) + { + if(s is IVariableCheck v) + v.CheckVariables(this); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 59dddcccd3..6873fad175 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -4,12 +4,12 @@ public class Symbol { public string? Name {get;set;} public string? Type {get;set;} - public DeclareAssign? Declaration {get;set;} + public Declaration? Declaration {get;set;} } -public class SymbolTable : Stack> +public partial class SymbolTable : Stack> { - public Dictionary CurrentScope => Peek(); + public Dictionary CurrentScope => Peek(); public SymbolTable() { Push(new()); @@ -23,24 +23,43 @@ public void PushVar(Declaration a) if(d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); a.Value.TypeCheck(this, a.TypeName ?? ""); - CurrentScope.Add(a.VariableName, a); + CurrentScope.Add(a.VariableName, new Symbol{Declaration = a}); + } + public void PushStream() + { + CurrentScope["streams"] = new Symbol{Name = "streams", Type = "STREAM"}; } public void SetType(string variableName, string type) { foreach(var d in this) if(d.TryGetValue(variableName, out var v)) - v.TypeName = type; + { + v.Type = type; + if(v.Declaration is not null) + v.Type = type; + } } public bool TryGetType(string variableName, out string? type) { type = null; foreach(var d in this) if(d.TryGetValue(variableName, out var v)) - { - type = v.TypeName; - return true; - } + type = v.Type; + return false; } + public void Analyse(Statement s) + { + if(s is Declaration d) + PushVar(d); + else if(s is BlockStatement b) + { + AddScope(); + foreach(var bs in b.Statements) + Analyse(bs); + Pop(); + } + else CheckVar(s); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 15f865ba61..bc7d2ede1c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -155,7 +155,7 @@ public TypeNameLiteral(Match m) } } -public class VariableNameLiteral : ShaderLiteral +public class VariableNameLiteral : ShaderLiteral, IVariableCheck { public string Name { get; set; } @@ -179,6 +179,12 @@ public override void TypeCheck(SymbolTable symbols, string expected = "") } else throw new NotImplementedException(); } + + public void CheckVariables(SymbolTable s) + { + if(!s.Any(x => x.ContainsKey(Name))) + throw new Exception("Not a variable"); + } public override string ToString() { return $"{{ Variable : {Name} }}"; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 8f3391f472..2a053d008d 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -27,7 +27,7 @@ public string GetInferredType() public override void TypeCheck(SymbolTable symbols, string expected = "") { } } -public class Operation : Expression, IStreamCheck, IStaticCheck +public class Operation : Expression, IStreamCheck, IStaticCheck, IVariableCheck { public OperatorToken Op { get; set; } @@ -84,10 +84,14 @@ public bool CheckStatic(SymbolTable s) return Left is IStaticCheck scl && scl.CheckStatic(s) || Right is IStaticCheck scr && scr.CheckStatic(s); } + + public void CheckVariables(SymbolTable s) + { + if(Left is IVariableCheck lvc) lvc.CheckVariables(s); + if(Right is IVariableCheck rvc) rvc.CheckVariables(s); + } public void CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string expected) { - - InferredType = (l.InferredType, r.InferredType, expected) switch { ("int","float", "int") => "int", diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index 90bc1819ff..939ffad077 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -56,6 +56,12 @@ public IEnumerable GetStreamValuesUsed() return Statements.OfType().SelectMany(x => x.GetUsedStream()); } + public void VariableChecking(SymbolTable sym) + { + foreach(var s in Statements) + sym.Analyse(s); + } + } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index b598511a6b..b013ffc674 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -82,7 +82,7 @@ public IEnumerable GetAssignedStream() } } -public class AssignChain : Statement, IStreamCheck, IStaticCheck +public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck { public override string InferredType => "void"; @@ -122,6 +122,13 @@ public bool CheckStatic(SymbolTable s) { return Value is IStaticCheck isc && isc.CheckStatic(s); } + + public void CheckVariables(SymbolTable s) + { + if(!s.Any(x => x.ContainsKey(this.AccessNames.First()))) + throw new Exception("Variable not exist"); + if(Value is IVariableCheck v) v.CheckVariables(s); + } } public class ReturnStatement : Statement, IStreamCheck, IStaticCheck diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index 85c5359fbd..81374ee768 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -14,7 +14,7 @@ public class UnaryExpression : Expression public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } -public class ChainAccessor : UnaryExpression, IStreamCheck +public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck { public ShaderToken Value { get; set; } public IEnumerable Field { get; set; } @@ -40,9 +40,13 @@ public bool CheckStream(SymbolTable symbols) { return GetUsedStream().Any(); } + public void CheckVariables(SymbolTable s) + { + if(Value is IVariableCheck n) n.CheckVariables(s); + } } -public class ArrayAccessor : UnaryExpression +public class ArrayAccessor : UnaryExpression, IVariableCheck { public ShaderToken Value { get; set; } public IEnumerable Accessors { get; set; } @@ -53,10 +57,14 @@ public ArrayAccessor(Match m) Value= GetToken(m.Matches[0]); Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); } + public void CheckVariables(SymbolTable s) + { + if(Value is IVariableCheck n) n.CheckVariables(s); + } } -public class PostfixIncrement : UnaryExpression +public class PostfixIncrement : UnaryExpression, IVariableCheck { public string Operator { get; set; } public ShaderToken Value { get; set; } @@ -71,6 +79,10 @@ public override string ToString() { return $"{{ PostfixIncrement : [\"{Value}\", \"{Operator}\"] }}"; } + public void CheckVariables(SymbolTable s) + { + if(Value is VariableNameLiteral n) n.CheckVariables(s); + } } public class PrefixIncrement : UnaryExpression From d15fef7829e26294638dd76221e71d298a32780e Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Wed, 14 Sep 2022 22:16:56 +0200 Subject: [PATCH 0146/1182] added symbol type for type checking --- .../AST/Shader/Analysis/SymbolTable.cs | 2 +- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 6873fad175..fa7c13c694 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -3,7 +3,7 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; public class Symbol { public string? Name {get;set;} - public string? Type {get;set;} + public ISymbolType? Type {get;set;} public Declaration? Declaration {get;set;} } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs new file mode 100644 index 0000000000..8fce330def --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -0,0 +1,92 @@ +using Eto.Parse; + +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +public interface ISymbolType +{ + public bool IsAccessorValid(string accessor); + public bool IsIndexingValid(string index); +} + +public class ArrayType : ISymbolType +{ + public ISymbolType TypeName {get;set;} + + public bool IsAccessorValid(string accessor) + { + return false; + } + + public bool IsIndexingValid(string index) + { + return true; + } +} + +public class CompositeType : ISymbolType +{ + public Dictionary Fields {get;set;} = new(); + + public bool IsAccessorValid(string accessor) + { + return Fields.ContainsKey(accessor); + } + + public bool IsIndexingValid(string index) + { + return false; + } +} + +public class VectorType : ISymbolType +{ + public int Size{get;set;} + public string TypeName {get;set;} + static string[] accessors = new string[]{"x","y","z","w"}; + public bool IsAccessorValid(string accessor) + { + return accessor.All(accessor[0..Size].Contains); + } + + public bool IsIndexingValid(string index) + { + return false; + } +} +public class MatrixType : ISymbolType +{ + public int SizeX{get;set;} + public int SizeY{get;set;} + public string TypeName {get;set;} + + static readonly Grammar accessorGrammar = new( + Terminals.Literal("_") + .Then("m" & Terminals.Set("0123") & Terminals.Set("0123")) + .Or(Terminals.Set("1234") & Terminals.Set("1234")) + .WithName("accessor") + ); + + public bool IsAccessorValid(string accessor) + { + return accessorGrammar.Match(accessor).Success; + } + + public bool IsIndexingValid(string index) + { + return false; + } +} +public class ScalarType : ISymbolType +{ + public string TypeName {get;set;} + + public bool IsAccessorValid(string accessor) + { + return false; + } + + public bool IsIndexingValid(string index) + { + return false; + } +} \ No newline at end of file From 1ebc8b3f7c905e85988d1191d3873ee8ee169ef0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 15 Sep 2022 22:31:50 +0200 Subject: [PATCH 0147/1182] Type checking with symbol table --- src/SDSLParserExample/Program.cs | 6 +- src/Stride.Shaders.Test/ASTTypeChecking.cs | 19 +-- .../Compiler/Emitter/SpirvEmitter.Streams.cs | 36 ++-- .../Compiler/Mixer/SimpleMixer.cs | 6 +- .../AST/Shader/Analysis/ShaderTokenTyped.cs | 4 +- .../AST/Shader/Analysis/SymbolTable.Check.cs | 41 +++++ .../AST/Shader/Analysis/SymbolTable.cs | 56 +++--- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 55 +++++- .../AST/Shader/Analysis/SymbolVariable.cs | 8 + .../Parsers/AST/Shader/ControlFlow.cs | 34 ++-- .../Parsers/AST/Shader/Literals.cs | 125 +++++++------- .../Parsers/AST/Shader/Operations.cs | 160 +++++++++--------- .../Parsers/AST/Shader/ShaderElements.cs | 23 ++- .../Parsers/AST/Shader/ShaderMethods.cs | 66 ++++---- .../Parsers/AST/Shader/ShaderProgram.cs | 7 +- .../Parsers/AST/Shader/ShaderToken.cs | 69 ++++---- .../Parsers/AST/Shader/Statements.cs | 43 +++-- .../Parsers/AST/Shader/UnaryLiterals.cs | 29 ++-- .../Parsers/ExpressionParser.cs | 4 +- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 4 +- .../SDSLGrammar.Directives.Expression.cs | 4 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 4 +- .../SDSLGrammar.MethodDeclaration.cs | 6 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 6 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 4 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 6 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 59 ++++--- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 52 +++--- .../Parsers/Grammars/SDSLMixinReader.cs | 6 +- .../Parsers/ShaderMixinParser.cs | 2 +- 30 files changed, 547 insertions(+), 397 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 3a60828227..cb636f58e7 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -29,7 +29,7 @@ static void LoadShaders() mixer.SemanticChecks(); var module = mixer.EmitSpirv(EntryPoints.VSMain); - var used = mixer.program.Body.OfType().First().GetStreamValuesUsed().ToList(); + var used = mixer.program.Body.OfType().First().GetUsedStream().ToList(); var x = 0; } @@ -45,13 +45,13 @@ static void ThreeAddress() }; var symbols = new SymbolTable(); - var s = new DeclareAssign(){TypeName = "float", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + var s = new DeclareAssign(){TypeName = new ScalarType("float"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; symbols.PushVar(s); var o2 = new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral{Value = 6L, InferredType = "float"}, + Right = new NumberLiteral{Value = 6L, InferredType = new ScalarType("float")}, Op = OperatorToken.Plus }; var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2}; diff --git a/src/Stride.Shaders.Test/ASTTypeChecking.cs b/src/Stride.Shaders.Test/ASTTypeChecking.cs index eb6bd6cbec..b908d3a5af 100644 --- a/src/Stride.Shaders.Test/ASTTypeChecking.cs +++ b/src/Stride.Shaders.Test/ASTTypeChecking.cs @@ -22,18 +22,18 @@ public void TypeCheckIntWithFloatCastedToInt() }; var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + var s = new DeclareAssign() { TypeName = new ScalarType("int"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; symbols.PushVar(s); var o2 = new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = "float" }, + Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("float") }, Op = OperatorToken.Plus }; var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; symbols.PushVar(s2); - Assert.Equal("int", s2.InferredType); + Assert.Equal(new ScalarType("int"), s2.InferredType); } [Fact] @@ -48,18 +48,18 @@ public void TypeCheckInt() }; var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = "int", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + var s = new DeclareAssign() { TypeName = new ScalarType("int"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; symbols.PushVar(s); var o2 = new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = "int" }, + Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("int") }, Op = OperatorToken.Plus }; var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; symbols.PushVar(s2); - Assert.Equal("int", s2.InferredType); + Assert.Equal(new ScalarType("int"), s2.InferredType); } [Fact] @@ -74,18 +74,17 @@ public void TypeCheckFloat() }; var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = "float", VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; + var s = new DeclareAssign() { TypeName = new ScalarType("float"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; symbols.PushVar(s); var o2 = new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = "int" }, + Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("int") }, Op = OperatorToken.Plus }; var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; symbols.PushVar(s2); - Assert.Equal("float", s2.InferredType); - + Assert.Equal(new ScalarType("float"), s2.InferredType); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index 5b270ee9ca..0fab49c6dc 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -25,29 +25,29 @@ public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) _ => throw new NotImplementedException() }; - var variables = - program.Body - .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) - .Cast() - .Select(x => (x.Name, SpvType: AsSpvType(x.Type))) - .ToList(); + // var variables = + // program.Body + // .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) + // .Cast() + // .Select(x => (x.Name, SpvType: AsSpvType(x.Type))) + // .ToList(); - var likelyInputs = mainMethod.GetStreamValuesUsed(); - IEnumerable<(string,Instruction)> inVars = variables.Where(x => likelyInputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; + // var likelyInputs = mainMethod.GetStreamValuesUsed(); + // IEnumerable<(string,Instruction)> inVars = variables.Where(x => likelyInputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; - var likelyOutputs = mainMethod.GetStreamValuesAssigned(); - IEnumerable<(string,Instruction)> outVars = variables.Where(x => likelyOutputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; + // var likelyOutputs = mainMethod.GetStreamValuesAssigned(); + // IEnumerable<(string,Instruction)> outVars = variables.Where(x => likelyOutputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; - Stream = new Stream(entry, this, variables as IEnumerable<(string,Instruction)>); - StreamIn = new(entry, this, inVars); - StreamOut = new StreamOut(entry, this, outVars); + // Stream = new Stream(entry, this, variables as IEnumerable<(string,Instruction)>); + // StreamIn = new(entry, this, inVars); + // StreamOut = new StreamOut(entry, this, outVars); - // in-out + // // in-out - var streamInPtr = TypePointer(StorageClass.Input , StreamIn.SpvType); - var streamOutPtr = TypePointer(StorageClass.Output , StreamOut.SpvType); - Variables[StreamIn.Name] = Variable(streamInPtr, StorageClass.Input); - Variables[StreamOut.Name] = Variable(streamOutPtr, StorageClass.Output); + // var streamInPtr = TypePointer(StorageClass.Input , StreamIn.SpvType); + // var streamOutPtr = TypePointer(StorageClass.Output , StreamOut.SpvType); + // Variables[StreamIn.Name] = Variable(streamInPtr, StorageClass.Input); + // Variables[StreamOut.Name] = Variable(streamOutPtr, StorageClass.Output); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index a7f4afa405..3add6b8dcd 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -22,11 +22,13 @@ public SimpleMixer(string className, ShaderSourceManager manager) public void SemanticChecks() { var sym = new SymbolTable(); - sym.PushStream(); - sym.AddScope(); + sym.PushStreamType(program.Body.OfType()); + foreach(var method in program.Body.OfType()) { + sym.AddScope(); method.VariableChecking(sym); + sym.Pop(); } } public Module EmitSpirv(EntryPoints entry) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs index ca9cb5c6bb..6693541ea1 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs @@ -2,6 +2,6 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; public abstract class ShaderTokenTyped : ShaderToken { - public abstract string InferredType{get;set;} - public abstract void TypeCheck(SymbolTable symbols, string expected = ""); + public abstract ISymbolType InferredType{get;set;} + public abstract void TypeCheck(SymbolTable symbols, ISymbolType expected); } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs index 489a344387..bc21db7c5c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs @@ -1,3 +1,5 @@ +using Eto.Parse; + namespace Stride.Shaders.Parsing.AST.Shader.Analysis; @@ -8,4 +10,43 @@ public void CheckVar(Statement s) if(s is IVariableCheck v) v.CheckVariables(this); } + public ISymbolType Tokenize(Match m) + { + return (m.Name, m.HasMatches) switch + { + ("ReturnType", _) => Tokenize(m.Matches[0]), + ("ValueTypes", true) => Tokenize(m.Matches[0]), + ("ArrayTypes", true) => Tokenize(m.Matches[0]), + ("ValueTypes", false) => new ScalarType(m.StringValue), + ("ScalarType", false) => new ScalarType(m.StringValue), + ("bool", _) => new ScalarType(m.StringValue), + ("sbyte", _) => new ScalarType(m.StringValue), + ("byte", _) => new ScalarType(m.StringValue), + ("short", _) => new ScalarType(m.StringValue), + ("int", _) => new ScalarType(m.StringValue), + ("uint", _) => new ScalarType(m.StringValue), + ("half", _) => new ScalarType(m.StringValue), + ("float", _) => new ScalarType(m.StringValue), + ("double", _) => new ScalarType(m.StringValue), + ("BoolScalar", _) => new ScalarType(m.StringValue), + ("SbyteScalar", _) => new ScalarType(m.StringValue), + ("ByteScalar", _) => new ScalarType(m.StringValue), + ("ShortScalar", _) => new ScalarType(m.StringValue), + ("IntScalar", _) => new ScalarType(m.StringValue), + ("UintScalar", _) => new ScalarType(m.StringValue), + ("HalfScalar", _) => new ScalarType(m.StringValue), + ("FloatScalar", _) => new ScalarType(m.StringValue), + ("DoubleScalar", _) => new ScalarType(m.StringValue), + ("BoolVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("SbyteVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("ByteVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("ShortVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("IntVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("UintVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("HalfVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("FloatVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + ("DoubleVec", _) => new VectorType(m["Size1"].StringValue, PushType(m["ScalarType"].StringValue,m["ScalarType"])), + _ => throw new NotImplementedException() + }; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index fa7c13c694..255a24545c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -1,15 +1,11 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; -public class Symbol -{ - public string? Name {get;set;} - public ISymbolType? Type {get;set;} - public Declaration? Declaration {get;set;} -} +public interface ISymbol{} + -public partial class SymbolTable : Stack> +public partial class SymbolTable : Stack> { - public Dictionary CurrentScope => Peek(); + public Dictionary CurrentScope => Peek(); public SymbolTable() { Push(new()); @@ -22,31 +18,49 @@ public void PushVar(Declaration a) foreach(var d in this) if(d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); - a.Value.TypeCheck(this, a.TypeName ?? ""); - CurrentScope.Add(a.VariableName, new Symbol{Declaration = a}); + a.Value.TypeCheck(this, a.TypeName); + CurrentScope.Add(a.VariableName, new SymbolVariable{Declaration = a}); + } + public void PushStreamType(IEnumerable variables) + { + CurrentScope["STREAM"] = new CompositeType("STREAM", variables.ToDictionary(v => v.Name, v => v.Type)); + } + public void PushStreamVar() + { + if(TryGetType("streams", out var type)) + CurrentScope["streams"] = new SymbolVariable(){Name = "streams", Type = type}; } - public void PushStream() + public ISymbolType PushType(string name, Eto.Parse.Match type) { - CurrentScope["streams"] = new Symbol{Name = "streams", Type = "STREAM"}; + if(!CurrentScope.ContainsKey(name)) + CurrentScope[name] = Tokenize(type); + return (ISymbolType)CurrentScope[name]; } - public void SetType(string variableName, string type) + public void SetType(string variableName, ISymbolType type) { foreach(var d in this) if(d.TryGetValue(variableName, out var v)) { - v.Type = type; - if(v.Declaration is not null) - v.Type = type; + if(v is SymbolVariable sv) + { + sv.Type = type; + if(sv.Declaration is not null) + sv.Type = type; + } } } - public bool TryGetType(string variableName, out string? type) + public bool TryGetType(string variableName, out ISymbolType type) { - type = null; + type = ScalarType.VoidType; foreach(var d in this) - if(d.TryGetValue(variableName, out var v)) - type = v.Type; - + { + if(d.TryGetValue(variableName, out var v) && v is ISymbolType sv) + { + type = sv; + return true; + } + } return false; } public void Analyse(Statement s) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index 8fce330def..d96aeb8b1b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -2,7 +2,7 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; -public interface ISymbolType +public interface ISymbolType : ISymbol, IEquatable { public bool IsAccessorValid(string accessor); public bool IsIndexingValid(string index); @@ -12,6 +12,12 @@ public class ArrayType : ISymbolType { public ISymbolType TypeName {get;set;} + + public bool Equals(ISymbolType? other) + { + return other is ArrayType a && a.TypeName.Equals(TypeName); + } + public bool IsAccessorValid(string accessor) { return false; @@ -25,8 +31,21 @@ public bool IsIndexingValid(string index) public class CompositeType : ISymbolType { + public string Name {get;set;} public Dictionary Fields {get;set;} = new(); + public CompositeType(string name, Dictionary fields) + { + Name = name; + Fields = fields; + } + + public bool Equals(ISymbolType? other) + { + return true; + // return other is CompositeType a && a.Fields.Keys.All(f => a.Fields[f].Equals()); + } + public bool IsAccessorValid(string accessor) { return Fields.ContainsKey(accessor); @@ -41,8 +60,19 @@ public bool IsIndexingValid(string index) public class VectorType : ISymbolType { public int Size{get;set;} - public string TypeName {get;set;} + public ISymbolType TypeName {get;set;} static string[] accessors = new string[]{"x","y","z","w"}; + + public VectorType(string size, ISymbolType type) + { + if(int.TryParse(size, out var s)) + { + Size = s; + TypeName = type; + } + else throw new NotImplementedException(); + } + public bool IsAccessorValid(string accessor) { return accessor.All(accessor[0..Size].Contains); @@ -52,6 +82,11 @@ public bool IsIndexingValid(string index) { return false; } + + public bool Equals(ISymbolType? other) + { + throw new NotImplementedException(); + } } public class MatrixType : ISymbolType { @@ -75,11 +110,22 @@ public bool IsIndexingValid(string index) { return false; } + + public bool Equals(ISymbolType? other) + { + throw new NotImplementedException(); + } } public class ScalarType : ISymbolType { + public static readonly ScalarType VoidType = new("void"); public string TypeName {get;set;} + public ScalarType(string type) + { + TypeName = type; + } + public bool IsAccessorValid(string accessor) { return false; @@ -89,4 +135,9 @@ public bool IsIndexingValid(string index) { return false; } + + public bool Equals(ISymbolType? other) + { + return other is ScalarType o && TypeName == o.TypeName; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs new file mode 100644 index 0000000000..e7417d7c65 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs @@ -0,0 +1,8 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +public class SymbolVariable : ISymbol +{ + public string? Name {get;set;} + public ISymbolType? Type {get;set;} + public Declaration? Declaration {get;set;} +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs index 2599e08899..92e2bbdf37 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs @@ -10,7 +10,7 @@ public class ForLoop : ControlFlow public ShaderToken Initializer {get;set;} public ShaderToken Condition {get;set;} public ShaderToken Updater {get;set;} - public ForLoop(Match m) + public ForLoop(Match m, SymbolTable s) { Match = m; var forMatch = m["ForLoop"]; @@ -25,13 +25,13 @@ public class IfStatement : ControlFlow public ShaderToken Attributes {get;set;} public ShaderToken Condition {get;set;} public ShaderToken Statements {get;set;} - public IfStatement(Match m) + public IfStatement(Match m, SymbolTable s) { Match = m; if(m["Attributes"].HasMatches) throw new NotImplementedException(); - Condition = GetToken(m["Condition"]); - Statements = GetToken(m["Statement"]); + Condition = GetToken(m["Condition"],s); + Statements = GetToken(m["Statement"],s); } } @@ -40,13 +40,13 @@ public class ElseIfStatement : ControlFlow public ShaderToken Attributes {get;set;} public ShaderToken Condition {get;set;} public ShaderToken Statements {get;set;} - public ElseIfStatement(Match m) + public ElseIfStatement(Match m, SymbolTable s) { Match = m; if(m["Attributes"].HasMatches) throw new NotImplementedException(); - Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); - Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + Condition = GetToken(m["Control"]["IfStatement"]["Condition"],s); + Statements = GetToken(m["Control"]["IfStatement"]["Statement"],s); } } @@ -55,13 +55,13 @@ public class ElseStatement : ControlFlow public ShaderToken Attributes {get;set;} public ShaderToken Condition {get;set;} public ShaderToken Statements {get;set;} - public ElseStatement(Match m) + public ElseStatement(Match m, SymbolTable s) { Match = m; if(m["Attributes"].HasMatches) throw new NotImplementedException(); - Condition = GetToken(m["Control"]["IfStatement"]["Condition"]); - Statements = GetToken(m["Control"]["IfStatement"]["Statement"]); + Condition = GetToken(m["Control"]["IfStatement"]["Condition"],s); + Statements = GetToken(m["Control"]["IfStatement"]["Statement"],s); } } @@ -70,26 +70,26 @@ public class ConditionalFlow : ControlFlow public IfStatement If {get;set;} public List ElseIfs {get;set;} public ElseStatement Else {get;set;} - public ConditionalFlow(Match m) + public ConditionalFlow(Match m, SymbolTable s) { Match = m["ConditionalFlow"]; - If = new IfStatement(Match["IfStatement"]); + If = new IfStatement(Match["IfStatement"],s); if(Match.Matches.Any(x => x.Name == "ElseIfStatement")) - ElseIfs = Match.Matches.Where(x => x.Name == "ElseIfStatement").Select(x => new ElseIfStatement(x)).ToList(); + ElseIfs = Match.Matches.Where(x => x.Name == "ElseIfStatement").Select(x => new ElseIfStatement(x,s)).ToList(); if(Match["ElseStatement"]) - Else = new ElseStatement(Match["ElseStatement"]); + Else = new ElseStatement(Match["ElseStatement"],s); } } public class ControlFlow : Statement { - public static ControlFlow Create(Match m) + public static ControlFlow Create(Match m, SymbolTable s) { return m.Matches[1].Name switch { - "ConditionalFlow" => new ConditionalFlow(m), - "ForLoop" => new ForLoop(m), + "ConditionalFlow" => new ConditionalFlow(m, s), + "ForLoop" => new ForLoop(m, s), _ => throw new NotImplementedException() }; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index bc7d2ede1c..55ad8fdef4 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderLiteral : Expression { - public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public override ISymbolType InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public object Value { get; set; } } @@ -19,7 +19,7 @@ public class NumberLiteral : ShaderLiteral { public bool Negative { get; set; } = false; public string? Suffix { get; set; } - public override string InferredType + public override ISymbolType InferredType { get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; @@ -27,7 +27,7 @@ public override string InferredType public NumberLiteral() { } - public NumberLiteral(Match match) + public NumberLiteral(Match match, SymbolTable s) { Match = match; if (!match.HasMatches) @@ -47,72 +47,73 @@ public NumberLiteral(Match match) } } } - public override void TypeCheck(SymbolTable symbols, string expected) + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { + throw new NotImplementedException(); if (Suffix is null) { - if (expected != string.Empty) - { - inferredType = (Value, expected) switch - { - (_, "double") => "double", - (_, "float") => "float", - (_, "half") => "half", - (long l, "long") => "long", - (long l, "int") => "int", - (long l, "uint") => "uint", - (long l, "short") => "short", - (long l, "byte") => "byte", - (long l, "sbyte") => "sbyte", - _ => throw new NotImplementedException() - }; - } - else - { - inferredType = "int"; - } - } - else - { - if (expected != string.Empty) - { - inferredType = Suffix switch - { - "l" => "long", - "u" => "uint", - "f" => "float", - "d" => "double", - _ => throw new NotImplementedException() - }; - if (expected != inferredType) - throw new NotImplementedException(); - } - else - { - inferredType = Suffix switch - { - "l" => "long", - "u" => "uint", - "f" => "float", - "d" => "double", - _ => throw new NotImplementedException() - }; - } + // if (expected != string.Empty) + // { + // inferredType = (Value, expected) switch + // { + // (_, "double") => "double", + // (_, "float") => "float", + // (_, "half") => "half", + // (long l, "long") => "long", + // (long l, "int") => "int", + // (long l, "uint") => "uint", + // (long l, "short") => "short", + // (long l, "byte") => "byte", + // (long l, "sbyte") => "sbyte", + // _ => throw new NotImplementedException() + // }; + // } + // else + // { + // inferredType = "int"; + // } + // } + // else + // { + // if (expected != string.Empty) + // { + // inferredType = Suffix switch + // { + // "l" => "long", + // "u" => "uint", + // "f" => "float", + // "d" => "double", + // _ => throw new NotImplementedException() + // }; + // if (expected != inferredType) + // throw new NotImplementedException(); + // } + // else + // { + // inferredType = Suffix switch + // { + // "l" => "long", + // "u" => "uint", + // "f" => "float", + // "d" => "double", + // _ => throw new NotImplementedException() + // }; + // } } } } public class HexLiteral : NumberLiteral { - public override string InferredType + public override ISymbolType InferredType { - get => inferredType ?? "long"; + get => inferredType; set => inferredType = value; } public HexLiteral() { } - public HexLiteral(Match match) + public HexLiteral(Match match, SymbolTable s) { Match = match; Value = Convert.ToUInt64(match.StringValue, 16); @@ -120,11 +121,11 @@ public HexLiteral(Match match) } public class StringLiteral : ShaderLiteral { - public override string InferredType { get => "string"; set => throw new NotImplementedException(); } + public override ISymbolType InferredType { get => new ScalarType("string"); set => throw new NotImplementedException(); } public StringLiteral() { } - public StringLiteral(Match match) + public StringLiteral(Match match, SymbolTable s) { Match = match; Value = match.StringValue; @@ -133,11 +134,11 @@ public StringLiteral(Match match) public class BoolLiteral : ShaderLiteral { - public override string InferredType { get => "bool"; set => throw new NotImplementedException(); } + public override ISymbolType InferredType { get => new ScalarType("bool"); set => throw new NotImplementedException(); } public BoolLiteral() { } - public BoolLiteral(Match match) + public BoolLiteral(Match match, SymbolTable s) { Match = match; Value = (bool)match.Value; @@ -149,7 +150,7 @@ public class TypeNameLiteral : ShaderLiteral { public string Name { get; set; } - public TypeNameLiteral(Match m) + public TypeNameLiteral(Match m, SymbolTable s) { Name = m.StringValue; } @@ -159,19 +160,19 @@ public class VariableNameLiteral : ShaderLiteral, IVariableCheck { public string Name { get; set; } - public override string InferredType { get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; } + public override ISymbolType InferredType { get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; } public VariableNameLiteral(string name) { Name = name; } - public VariableNameLiteral(Match m) + public VariableNameLiteral(Match m, SymbolTable s) { Name = m.StringValue; } - public override void TypeCheck(SymbolTable symbols, string expected = "") + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { if (symbols.TryGetType(Name, out var type)) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 2a053d008d..71b92893d6 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -13,18 +13,13 @@ namespace Stride.Shaders.Parsing.AST.Shader; public abstract class Expression : ShaderTokenTyped { - protected string? inferredType; - public override string InferredType + protected ISymbolType? inferredType; + public override ISymbolType InferredType { get => inferredType ?? throw new NotImplementedException(); set => inferredType = value; } - - public string GetInferredType() - { - return InferredType; - } - public override void TypeCheck(SymbolTable symbols, string expected = "") { } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { } } public class Operation : Expression, IStreamCheck, IStaticCheck, IVariableCheck @@ -34,38 +29,38 @@ public class Operation : Expression, IStreamCheck, IStaticCheck, IVariableCheck public ShaderTokenTyped Left { get; set; } public ShaderTokenTyped Right { get; set; } - public override async void TypeCheck(SymbolTable symbols, string expected = "") + public override async void TypeCheck(SymbolTable symbols, ISymbolType expected) { - if (expected != string.Empty) - { - Left.TypeCheck(symbols, expected); - Right.TypeCheck(symbols, expected); - if (Left.InferredType == Right.InferredType && Left.InferredType == expected) - InferredType = Left.InferredType; - else + // if (expected != string.Empty) + // { + // Left.TypeCheck(symbols, expected); + // Right.TypeCheck(symbols, expected); + // if (Left.InferredType == Right.InferredType && Left.InferredType == expected) + // InferredType = Left.InferredType; + // else throw new NotImplementedException(); - } - else - { - Left.TypeCheck(symbols); - Right.TypeCheck(symbols); - if (Left.InferredType != Right.InferredType) - { - CheckImplicitCasting(Left, Right, expected); - } - else - InferredType = Left.InferredType; - } + // } + // else + // { + // Left.TypeCheck(symbols); + // Right.TypeCheck(symbols); + // if (Left.InferredType != Right.InferredType) + // { + // CheckImplicitCasting(Left, Right, expected); + // } + // else + // InferredType = Left.InferredType; + // } } public IEnumerable GetUsedStream() { var result = Enumerable.Empty(); if (Left is IStreamCheck lsc) - result.Concat(lsc.GetUsedStream()); + result = result.Concat(lsc.GetUsedStream()); if (Right is IStreamCheck rsc) - result.Concat(rsc.GetUsedStream()); + result = result.Concat(rsc.GetUsedStream()); return result; } public IEnumerable GetAssignedStream() @@ -94,12 +89,12 @@ public void CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string { InferredType = (l.InferredType, r.InferredType, expected) switch { - ("int","float", "int") => "int", - ("int","float", "float") => "float", - ("float","int", "int") => "int", - ("float","int", "float") => "float", - ("int","float", "") => "float", - ("float","int", "") => "float", + // ("int","float", "int") => "int", + // ("int","float", "float") => "float", + // ("float","int", "int") => "int", + // ("float","int", "float") => "float", + // ("int","float", "") => "float", + // ("float","int", "") => "float", _ => throw new Exception($"Cannot cast types") }; } @@ -108,14 +103,14 @@ public void CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string public class MulExpression : Operation { - public static MulExpression Create(Match m) + public static MulExpression Create(Match m, SymbolTable s) { var first = new MulExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; MulExpression tmp = first; @@ -126,7 +121,7 @@ public static MulExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -135,14 +130,14 @@ public static MulExpression Create(Match m) public class SumExpression : Operation { - public static SumExpression Create(Match m) + public static SumExpression Create(Match m, SymbolTable s) { var first = new SumExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; SumExpression tmp = first; @@ -153,7 +148,7 @@ public static SumExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -162,14 +157,14 @@ public static SumExpression Create(Match m) public class ShiftExpression : Operation { - public static ShiftExpression Create(Match m) + public static ShiftExpression Create(Match m, SymbolTable s) { var first = new ShiftExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; ShiftExpression tmp = first; @@ -180,7 +175,7 @@ public static ShiftExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -189,14 +184,14 @@ public static ShiftExpression Create(Match m) public class AndExpression : Operation { - public static AndExpression Create(Match m) + public static AndExpression Create(Match m, SymbolTable s) { var first = new AndExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; AndExpression tmp = first; @@ -207,7 +202,7 @@ public static AndExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -215,14 +210,14 @@ public static AndExpression Create(Match m) } public class XorExpression : Operation { - public static XorExpression Create(Match m) + public static XorExpression Create(Match m, SymbolTable s) { var first = new XorExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; XorExpression tmp = first; @@ -233,7 +228,7 @@ public static XorExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -241,14 +236,14 @@ public static XorExpression Create(Match m) } public class OrExpression : Operation { - public static OrExpression Create(Match m) + public static OrExpression Create(Match m, SymbolTable s) { var first = new OrExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; OrExpression tmp = first; @@ -259,7 +254,7 @@ public static OrExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -268,14 +263,14 @@ public static OrExpression Create(Match m) public class TestExpression : Operation { - public static TestExpression Create(Match m) + public static TestExpression Create(Match m, SymbolTable s) { var first = new TestExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; TestExpression tmp = first; @@ -286,7 +281,7 @@ public static TestExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -295,14 +290,14 @@ public static TestExpression Create(Match m) public class EqualsExpression : Operation { - public static EqualsExpression Create(Match m) + public static EqualsExpression Create(Match m, SymbolTable s) { var first = new EqualsExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; EqualsExpression tmp = first; @@ -313,7 +308,7 @@ public static EqualsExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -322,14 +317,14 @@ public static EqualsExpression Create(Match m) public class LogicalAndExpression : Operation { - public static LogicalAndExpression Create(Match m) + public static LogicalAndExpression Create(Match m, SymbolTable s) { var first = new LogicalAndExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; LogicalAndExpression tmp = first; @@ -340,7 +335,7 @@ public static LogicalAndExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -349,14 +344,14 @@ public static LogicalAndExpression Create(Match m) } public class LogicalOrExpression : Operation { - public static LogicalOrExpression Create(Match m) + public static LogicalOrExpression Create(Match m, SymbolTable s) { var first = new LogicalOrExpression { Match = m, Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0]), - Right = (ShaderTokenTyped)GetToken(m.Matches[2]) + Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), + Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) }; LogicalOrExpression tmp = first; @@ -367,7 +362,7 @@ public static LogicalOrExpression Create(Match m) Match = m, Op = m.Matches[i].StringValue.ToOperatorToken(), Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1]) + Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) }; } return tmp; @@ -388,11 +383,11 @@ public string InferredType set => inferredType = value; } - public ConditionalExpression(Match m) + public ConditionalExpression(Match m, SymbolTable s) { - Condition = (ShaderTokenTyped)GetToken(m.Matches[0]); - TrueOutput = (ShaderTokenTyped)GetToken(m.Matches[1]); - FalseOutput = (ShaderTokenTyped)GetToken(m.Matches[2]); + Condition = (ShaderTokenTyped)GetToken(m.Matches[0], s); + TrueOutput = (ShaderTokenTyped)GetToken(m.Matches[1], s); + FalseOutput = (ShaderTokenTyped)GetToken(m.Matches[2], s); } } @@ -402,10 +397,11 @@ public class MethodCall : Expression public string MethodName { get; set; } public IEnumerable Parameters { get; set; } - public MethodCall(Match m) + public MethodCall(Match m, SymbolTable s) { Match = m; MethodName = m.Matches.First().StringValue; - Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).Cast().ToList(); + throw new NotImplementedException(); + // Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).Cast().ToList(); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index e1d24323e0..0889510b02 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; @@ -23,10 +24,12 @@ public class ShaderStruct : ShaderToken { public IEnumerable Fields {get;set;} - public ShaderStruct(Match m) + public ShaderStruct(Match m, SymbolTable s) { Match = m; - Fields = m["Fields"].Matches.Select(GetToken).ToList(); + throw new NotImplementedException(); + + // Fields = m["Fields"].Matches.Select(GetToken).ToList(); } } @@ -35,10 +38,11 @@ public class ResourceGroup : ShaderToken { public IEnumerable Variables {get;set;} - public ResourceGroup(Match m) + public ResourceGroup(Match m, SymbolTable s) { Match = m; - Variables = m["Variables"].Matches.Select(GetToken).ToList(); + throw new NotImplementedException(); + // Variables = m["Variables"].Matches.Select(GetToken).ToList(); } } @@ -46,10 +50,11 @@ public class ConstantBuffer : ShaderToken { public IEnumerable Variables {get;set;} - public ConstantBuffer(Match m) + public ConstantBuffer(Match m, SymbolTable s) { Match = m; - Variables = m["Variables"].Matches.Select(GetToken).ToList(); + throw new NotImplementedException(); + // Variables = m["Variables"].Matches.Select(GetToken).ToList(); } } @@ -59,17 +64,17 @@ public class ShaderVariableDeclaration : ShaderToken public bool IsStream {get;set;} public bool IsStaged {get;set;} public string Name {get;set;} - public string Type {get;set;} + public ISymbolType Type {get;set;} public string? Semantic { get; set; } public ShaderToken Expression {get;set;} - public ShaderVariableDeclaration(Match m) + public ShaderVariableDeclaration(Match m, SymbolTable s) { Match = m; IsStream = m["Stream"].Success; IsStaged = m["Stage"].Success; Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; - Type = m["TypeName"].StringValue; + Type = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); Name = m["Identifier"].StringValue; } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index 939ffad077..d027495eb8 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -13,52 +13,60 @@ public class ShaderMethod : ShaderToken public string Name { get; set; } - public string ReturnType { get; set; } + public ISymbolType ReturnType { get; set; } public IEnumerable ParameterList { get; set; } public IEnumerable Statements { get; set; } - public ShaderMethod(Match m) + public ShaderMethod(Match m, SymbolTable symbols) { Match = m; IsStatic = m["Static"].Success; IsOverride = m["Override"].Success; IsStaged = m["Stage"].Success; Name = m["MethodName"].StringValue; - ReturnType = m["ReturnType"].StringValue; - Statements = m["Statements"].Matches.Select(GetToken).Cast().ToList(); + ReturnType = symbols.PushType(m["ReturnType"].StringValue, m["ReturnType"]); + Statements = m["Statements"].Matches.Select(x => GetToken(x, symbols)).Cast().ToList(); } - public static ShaderMethod Create(Match m) + public static ShaderMethod Create(Match m, SymbolTable s) { return m["MethodName"].StringValue switch { - "VSMain" => new VSMainMethod(m), - "PSMain" => new PSMainMethod(m), - "CSMain" => new CSMainMethod(m), - "GSMain" => new GSMainMethod(m), - "DSMain" => new DSMainMethod(m), - "HSMain" => new HSMainMethod(m), - _ => new ShaderMethod(m) + "VSMain" => new VSMainMethod(m, s), + "PSMain" => new PSMainMethod(m, s), + "CSMain" => new CSMainMethod(m, s), + "GSMain" => new GSMainMethod(m, s), + "DSMain" => new DSMainMethod(m, s), + "HSMain" => new HSMainMethod(m, s), + _ => new ShaderMethod(m, s) }; } } -public abstract class MainMethod : ShaderMethod +public abstract class MainMethod : ShaderMethod, IStreamCheck { - public MainMethod(Match m) : base(m) { } + public MainMethod(Match m, SymbolTable s) : base(m, s) { } - public IEnumerable GetStreamValuesAssigned() + public bool CheckStream(SymbolTable s) + { + return Statements.OfType().Any(x => x.CheckStream(s)); + } + + public IEnumerable GetAssignedStream() { return Statements.OfType().SelectMany(x => x.GetAssignedStream()); } - public IEnumerable GetStreamValuesUsed() + + public IEnumerable GetUsedStream() { return Statements.OfType().SelectMany(x => x.GetUsedStream()); } public void VariableChecking(SymbolTable sym) { - foreach(var s in Statements) + if(CheckStream(sym)) + sym.PushStreamVar(); + foreach (var s in Statements) sym.Analyse(s); } @@ -67,43 +75,43 @@ public void VariableChecking(SymbolTable sym) public class VSMainMethod : MainMethod { - public VSMainMethod(Match m) : base(m) + public VSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } public class PSMainMethod : MainMethod { - public PSMainMethod(Match m) : base(m) + public PSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } public class GSMainMethod : MainMethod { - public GSMainMethod(Match m) : base(m) + public GSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } public class CSMainMethod : MainMethod { - public CSMainMethod(Match m) : base(m) + public CSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } public class DSMainMethod : MainMethod { - public DSMainMethod(Match m) : base(m) + public DSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } public class HSMainMethod : MainMethod { - public HSMainMethod(Match m) : base(m) + public HSMainMethod(Match m, SymbolTable s) : base(m, s) { - + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index 4dafa3a942..26d830039c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; @@ -9,16 +10,18 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class ShaderProgram : ShaderToken { + public SymbolTable Symbols {get;set;} public string Name {get;set;} public IEnumerable Generics { get; set; } public IEnumerable Mixins { get; set; } public IEnumerable Body { get; set; } - public ShaderProgram(Match m) + public ShaderProgram(Match m, SymbolTable symbols) { Match = m; + Symbols = symbols; Name = m["ShaderName"].StringValue; - Body = m["Body"].Matches.Select(GetToken).ToList(); + Body = m["Body"].Matches.Select(x => GetToken(x,symbols)).ToList(); Mixins = m["Mixins"].Matches.Select(x => new MixinToken(x)).ToList(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 59b81680ff..9dda72ae40 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -1,4 +1,5 @@ using Eto.Parse; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using Stride.Shaders.Parsing.Grammars.Expression; using System; using System.Collections.Generic; @@ -20,7 +21,11 @@ public abstract class ShaderToken }; public Match? Match { get; set; } - public static ShaderToken GetToken(Match match) + public static ShaderToken Tokenize(Match match) + { + return GetToken(match,new SymbolTable()); + } + public static ShaderToken GetToken(Match match, SymbolTable symbols) { var tmp = match; while (tmp.Matches.Count == 1 && !KeepValues.Contains(tmp.Name)) @@ -28,43 +33,45 @@ public static ShaderToken GetToken(Match match) return tmp.Name switch { - "Namespace" => GetToken(tmp.Matches.Last()), - "ShaderProgram" => new ShaderProgram(tmp), - "ResourceGroup" => new ResourceGroup(tmp), - "ConstantBuffer" => new ConstantBuffer(tmp), - "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp), - "Method" => ShaderMethod.Create(tmp), - "ControlFlow" => ControlFlow.Create(tmp), - "Block" => new BlockStatement(tmp), - "Return" => new ReturnStatement(tmp), - "AssignChain" => new AssignChain(tmp), - "DeclareAssign" => new DeclareAssign(tmp), + "Namespace" => GetToken(tmp.Matches.Last(),symbols), + "ShaderProgram" => new ShaderProgram(tmp,symbols), + "ResourceGroup" => new ResourceGroup(tmp,symbols), + "ConstantBuffer" => new ConstantBuffer(tmp,symbols), + "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp, symbols), + "Method" => ShaderMethod.Create(tmp, symbols), + "ControlFlow" => ControlFlow.Create(tmp, symbols), + "Block" => new BlockStatement(tmp, symbols), + "Return" => new ReturnStatement(tmp, symbols), + "AssignChain" => new AssignChain(tmp, symbols), + "DeclareAssign" => new DeclareAssign(tmp, symbols), "SimpleDeclare" => throw new NotImplementedException(), "EmptyStatement" => new EmptyStatement(), - "MethodCall" => new MethodCall(tmp), - "Ternary" => new ConditionalExpression(tmp), - "LogicalOrExpression" => LogicalOrExpression.Create(tmp), - "LogicalAndExpression" => LogicalAndExpression.Create(tmp), - "EqualsExpression" => EqualsExpression.Create(tmp), - "TestExpression" => TestExpression.Create(tmp), - "OrExpression" => OrExpression.Create(tmp), - "XorExpression" => XorExpression.Create(tmp), - "AndExpression" => AndExpression.Create(tmp), - "ShiftExpression" => ShiftExpression.Create(tmp), - "SumExpression" => SumExpression.Create(tmp), - "MulExpression" => MulExpression.Create(tmp), - "CastExpression" => new CastExpression(tmp), + "MethodCall" => new MethodCall(tmp, symbols), + "Ternary" => new ConditionalExpression(tmp, symbols), + "LogicalOrExpression" => LogicalOrExpression.Create(tmp, symbols), + "LogicalAndExpression" => LogicalAndExpression.Create(tmp, symbols), + "EqualsExpression" => EqualsExpression.Create(tmp, symbols), + "TestExpression" => TestExpression.Create(tmp, symbols), + "OrExpression" => OrExpression.Create(tmp, symbols), + "XorExpression" => XorExpression.Create(tmp, symbols), + "AndExpression" => AndExpression.Create(tmp, symbols), + "ShiftExpression" => ShiftExpression.Create(tmp, symbols), + "SumExpression" => SumExpression.Create(tmp, symbols), + "MulExpression" => MulExpression.Create(tmp, symbols), + "CastExpression" => new CastExpression(tmp, symbols), "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "ChainAccessor" => new ChainAccessor(tmp), - "ArrayAccessor" => new ArrayAccessor(tmp), - "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp), - "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), - "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), - "Boolean" => new BoolLiteral(tmp), + "ChainAccessor" => new ChainAccessor(tmp, symbols), + "ArrayAccessor" => new ArrayAccessor(tmp, symbols), + "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp, symbols), + "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp, symbols), + "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp, symbols), + "Boolean" => new BoolLiteral(tmp, symbols), _ => throw new NotImplementedException() }; } + + // public IEnumerable GetUsedStream() // { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index b013ffc674..3fe33136f6 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -17,14 +17,9 @@ public abstract class Statement : ShaderTokenTyped { public IEnumerable LowCode { get; set; } - public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public override ISymbolType InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public string GetInferredType() - { - return InferredType; - } - - public override void TypeCheck(SymbolTable symbols, string expected = "") + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { throw new NotImplementedException(); } @@ -32,14 +27,14 @@ public override void TypeCheck(SymbolTable symbols, string expected = "") public class EmptyStatement : Statement { - public override string InferredType => "void"; - public override void TypeCheck(SymbolTable symbols, string expected = "") { } + public override ISymbolType InferredType => ScalarType.VoidType; + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { } } public abstract class Declaration : Statement { - public override string InferredType => "void"; - public string? TypeName { get; set; } + public override ISymbolType InferredType => ScalarType.VoidType; + public ISymbolType? TypeName { get; set; } public string VariableName { get; set; } public ShaderTokenTyped Value { get; set; } @@ -50,13 +45,13 @@ public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck public AssignOpToken AssignOp { get; set; } public DeclareAssign() { } - public DeclareAssign(Match m) + public DeclareAssign(Match m, SymbolTable s) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - TypeName = m["Type"].StringValue; + TypeName = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); VariableName = m["Variable"].StringValue; - Value = (ShaderTokenTyped)GetToken(m["Value"]); + Value = (ShaderTokenTyped)GetToken(m["Value"],s); } public bool CheckStatic(SymbolTable s) @@ -84,18 +79,18 @@ public IEnumerable GetAssignedStream() public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck { - public override string InferredType => "void"; + public override ISymbolType InferredType => ScalarType.VoidType; public AssignOpToken AssignOp { get; set; } public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; public IEnumerable AccessNames { get; set; } public ShaderTokenTyped Value { get; set; } - public AssignChain(Match m) + public AssignChain(Match m, SymbolTable s) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); - Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); + Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"],s); } public bool CheckStream(SymbolTable s) @@ -133,14 +128,15 @@ public void CheckVariables(SymbolTable s) public class ReturnStatement : Statement, IStreamCheck, IStaticCheck { - public override string InferredType => ReturnValue?.InferredType ?? "void"; + public override ISymbolType InferredType => ReturnValue?.InferredType ?? ScalarType.VoidType; public ShaderTokenTyped? ReturnValue { get; set; } - public ReturnStatement(Match m) + public ReturnStatement(Match m, SymbolTable s) { Match = m; - if (m.HasMatches) - ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); + throw new NotImplementedException(); + // if (m.HasMatches) + // ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"]); } public bool CheckStream(SymbolTable s) @@ -168,10 +164,11 @@ public bool CheckStatic(SymbolTable s) public class BlockStatement : Statement, IStreamCheck, IStaticCheck { public IEnumerable Statements { get; set; } - public BlockStatement(Match m) + public BlockStatement(Match m, SymbolTable s) { Match = m; - Statements = m.Matches.Select(GetToken).Cast().ToList(); + throw new NotImplementedException(); + // Statements = m.Matches.Select(GetToken).Cast().ToList(); } public bool CheckStream(SymbolTable s) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index 81374ee768..81a5482373 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Parsing.AST.Shader; public class UnaryExpression : Expression { - public override string InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public override ISymbolType InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck @@ -19,11 +19,11 @@ public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck public ShaderToken Value { get; set; } public IEnumerable Field { get; set; } - public ChainAccessor(Match m) + public ChainAccessor(Match m, SymbolTable s) { Match = m; - Value = GetToken(m.Matches["Identifier"]); - Field = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); + Value = GetToken(m.Matches["Identifier"],s); + Field = m.Matches.GetRange(1,m.Matches.Count-1).Select(x => GetToken(x,s)); } public IEnumerable GetUsedStream() @@ -51,11 +51,12 @@ public class ArrayAccessor : UnaryExpression, IVariableCheck public ShaderToken Value { get; set; } public IEnumerable Accessors { get; set; } - public ArrayAccessor(Match m) + public ArrayAccessor(Match m, SymbolTable s) { Match = m; - Value= GetToken(m.Matches[0]); - Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); + Value= GetToken(m.Matches[0],s); + throw new NotImplementedException(); + // Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); } public void CheckVariables(SymbolTable s) { @@ -68,10 +69,10 @@ public class PostfixIncrement : UnaryExpression, IVariableCheck { public string Operator { get; set; } public ShaderToken Value { get; set; } - public PostfixIncrement(Match m) + public PostfixIncrement(Match m, SymbolTable s) { Match = m; - Value = GetToken(m.Matches[0]); + Value = GetToken(m.Matches[0],s); Operator = m.Matches[1].StringValue; } @@ -89,11 +90,11 @@ public class PrefixIncrement : UnaryExpression { public string Operator { get; set; } public ShaderToken Value { get; set; } - public PrefixIncrement(Match m) + public PrefixIncrement(Match m, SymbolTable s) { Match = m; Operator = m.Matches[0].StringValue; - Value = GetToken(m.Matches[1]); + Value = GetToken(m.Matches[1],s); } } @@ -101,9 +102,9 @@ public class CastExpression : UnaryExpression { public TypeNameLiteral Target { get; set; } public ShaderToken From { get; set; } - public CastExpression(Match m) + public CastExpression(Match m, SymbolTable s) { - Target = new TypeNameLiteral(m.Matches[0]); - From = GetToken(m.Matches[1]); + Target = new TypeNameLiteral(m.Matches[0],s); + From = GetToken(m.Matches[1],s); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ExpressionParser.cs b/src/Stride.Shaders/Parsers/ExpressionParser.cs index 4564ad610c..58f0b5b276 100644 --- a/src/Stride.Shaders/Parsers/ExpressionParser.cs +++ b/src/Stride.Shaders/Parsers/ExpressionParser.cs @@ -17,8 +17,8 @@ public ShaderToken Parse(string expr) { var match = Grammar.Match(expr); if (!match.Success) - throw new ArgumentOutOfRangeException("expr", string.Format("Invalid expr string: {0}", match.ErrorMessage)); - return ShaderToken.GetToken(match.Matches.First()); + throw new ArgumentOutOfRangeException(nameof(expr), string.Format("Invalid expr string: {0}", match.ErrorMessage)); + return ShaderToken.Tokenize(match.Matches.First()); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index 5f90ed3d33..4c4ffe5a91 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -23,7 +23,7 @@ public void CreateDeclarators() var declare = new SequenceParser(); declare.Add( - ValueTypes | Identifier, + SimpleTypes | Identifier, ws1, Identifier, ws, @@ -67,7 +67,7 @@ public void CreateDeclarators() valueDeclaration.Add( ~(staging & ws1), ~(StorageFlag & ws1), - (ValueTypes | Identifier).Named("TypeName"), + ValueTypes, ws1, Identifier ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index 2b43890046..da2f4529c1 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -50,7 +50,7 @@ public void CreateDirectiveExpressions() DirectiveTermExpression.Add( Literals, - ~(Plus | Minus & ws) & Identifier.Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen), + ~(Plus | Minus & ws) & Identifier.Except(Keywords | SimpleTypes).NotFollowedBy(ws & LeftParen), DirectivesMethodCall, Parenthesis(DirectiveExpression) ); @@ -102,7 +102,7 @@ public void CreateDirectiveExpressions() var cast = new SequenceParser(); cast.Add( LeftParen, - ValueTypes | Identifier, + SimpleTypes | Identifier, RightParen, DirectiveUnaryExpression ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 9fa3804a41..4086f3a343 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -64,7 +64,7 @@ public void CreateExpressions() TermExpression.Add( Literals, - Identifier.Named("VariableTerm").Except(Keywords | ValueTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + Identifier.Named("VariableTerm").Except(Keywords | SimpleTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), MethodCall, Parenthesis(PrimaryExpression) ); @@ -116,7 +116,7 @@ public void CreateExpressions() var cast = new SequenceParser( LeftParen, - ValueTypes | Identifier.Named("TypeName"), + SimpleTypes | Identifier.Named("TypeName"), RightParen, UnaryExpression ) diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 647991e7ce..592b20f316 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -24,7 +24,7 @@ public void CreateMethodDeclaration() var genericsList = new SequenceParser { Name = "ShaderGenerics", Separator = ws }; var parameterGenericsValues = new AlternativeParser( - ValueTypes, + SimpleTypes, Identifier.Then(genericsList.Optional()).SeparatedBy(ws) ) { Name = "ParameterGenericValue" }; @@ -36,7 +36,7 @@ public void CreateMethodDeclaration() ); ValueOrGeneric.Add( - ValueTypes | Identifier, + SimpleTypes | Identifier, genericsList.Optional() ); @@ -87,7 +87,7 @@ public void CreateMethodDeclaration() Attribute.Repeat(0).SeparatedBy(ws), ~(Stage.Named("Stage") & WhiteSpace), ~((Literal("override").Named("Override") | Literal("static").Named("Static")) & ws1), - Identifier.Named("ReturnType") & ws1 & Identifier.Named("MethodName"), + ValueTypes.Named("ReturnType") & ws1 & Identifier.Named("MethodName"), ParameterList, LeftBrace, Statement.Repeat(0).SeparatedBy(ws).Until("}").Named("Statements"), diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index 60a992a5a4..f8d8347411 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -52,8 +52,8 @@ public virtual void CreateShader() var shaderGenericValue = new AlternativeParser( Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(ws1).Named("Semantic"), - ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), - ValueTypes + SimpleTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), + SimpleTypes ){ Name = "ShaderGeneric" }; var shaderGenerics = new SequenceParser( @@ -63,7 +63,7 @@ public virtual void CreateShader() ){ Name = "ShaderGenerics", Separator = ws }; var inheritGenericsValues = new AlternativeParser( - ValueTypes, + SimpleTypes, Identifier, Literals ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index d5cbe6d16b..8ae998a1f4 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -16,7 +16,7 @@ public void CreateLoopFlowStatements() var ws1 = WhiteSpace.Repeat(1); var valueDeclare = new SequenceParser( - ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws1).Named("NewVariable") + ((SimpleTypes | Identifier) & Identifier).SeparatedBy(ws1).Named("NewVariable") | UnaryExpression.Named("ExistingVariable"), AssignOperators.Named("Operator"), PrimaryExpression @@ -56,7 +56,7 @@ public void CreateLoopFlowStatements() ForEachLoop.Add( Literal("foreach"), LeftParen, - ((ValueTypes | Literal("var") | Identifier) & Identifier & In & PrimaryExpression).SeparatedBy(ws).Named("Declarator"), + ((SimpleTypes | Literal("var") | Identifier) & Identifier & In & PrimaryExpression).SeparatedBy(ws).Named("Declarator"), RightParen, Statement ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index b6048afea4..0b0c97adef 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -64,13 +64,13 @@ public void CreateStatements() var declareAssign = - Identifier.Named("Type") + ValueTypes .Then(assignVar) .SeparatedBy(ws1); var simpleDeclare = - ((ValueTypes | Identifier) & Identifier & arraySpecifier).SeparatedBy(ws) - | ((ValueTypes | Identifier) & Identifier).SeparatedBy(ws); + ((SimpleTypes | Identifier) & Identifier & arraySpecifier).SeparatedBy(ws) + | ((SimpleTypes | Identifier) & Identifier).SeparatedBy(ws); Statement.Add( Block, diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index afe83e1aff..e98f6a6293 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -23,6 +23,8 @@ public partial class SDSLGrammar : Grammar public AlternativeParser UintTypes = new(); + public AlternativeParser SimpleTypes = new() { Name = "ValueTypes"}; + public SequenceParser ArrayTypes = new() { Name = "ArrayTypes"}; public AlternativeParser ValueTypes = new() { Name = "ValueTypes"}; public AlternativeParser StorageFlag = new(); @@ -72,42 +74,42 @@ public void CreateTokenGroups() ); BoolTypes.Add( - Bool.NotFollowedBy(Set("1234")), - BoolVec.NotFollowedBy("x"), - BoolMat + Bool.NotFollowedBy(Set("1234")).Named("BoolScalar"), + BoolVec.NotFollowedBy("x").Named("BoolVec"), + BoolMat.Named("BoolMatrix") ); HalfTypes.Add( - Half.NotFollowedBy(Set("1234")), - HalfVec.NotFollowedBy("x"), - HalfMat + Half.NotFollowedBy(Set("1234")).Named("HalfScalar"), + HalfVec.NotFollowedBy("x").Named("HalfVec"), + HalfMat.Named("HalfMatrix") ); FloatTypes.Add( - Float.NotFollowedBy(Set("1234")), - FloatVec.NotFollowedBy("x"), - FloatMat + Float.NotFollowedBy(Set("1234")).Named("FloatScalar"), + FloatVec.NotFollowedBy("x").Named("FloatVec"), + FloatMat.Named("FloatMatrix") ); DoubleTypes.Add( - Double.NotFollowedBy(Set("1234")), - DoubleVec.NotFollowedBy("x"), - DoubleMat + Double.NotFollowedBy(Set("1234")).Named("DoubleScalar"), + DoubleVec.NotFollowedBy("x").Named("DoubleVec"), + DoubleMat.Named("DoubleMatrix") ); IntTypes.Add( - Int.NotFollowedBy(Set("1234")), - IntVec.NotFollowedBy("x"), - IntMat + Int.NotFollowedBy(Set("1234")).Named("IntScalar"), + IntVec.NotFollowedBy("x").Named("IntVec"), + IntMat.Named("IntMatrix") ); UintTypes.Add( - Uint.NotFollowedBy(Set("1234")), - UintVec.NotFollowedBy("x"), - UintMat + Uint.NotFollowedBy(Set("1234")).Named("UintScalar"), + UintVec.NotFollowedBy("x").Named("UintVec"), + UintMat.Named("UintMatrix") ); - ValueTypes.Add( + SimpleTypes.Add( BoolTypes, HalfTypes, FloatTypes, @@ -115,8 +117,23 @@ public void CreateTokenGroups() IntTypes, UintTypes, BufferTypes, - TextureTypes + TextureTypes, + Void, + Identifier.Named("UserDefined") + ); + + ArrayTypes.Add( + SimpleTypes, + LeftBracket, + RightBracket ); + ArrayTypes.Separator = WhiteSpace.Repeat(0); + + ValueTypes.Add( + ArrayTypes, + SimpleTypes + ); + Keywords.Add( AppendStructuredBuffer, @@ -179,7 +196,7 @@ public void CreateTokenGroups() TriangleAdj, TriangleStream, Uniform, - ValueTypes, + SimpleTypes, Vector, Volatile, Void, diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index ee0a51ee97..20e9de2b4c 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -13,23 +13,23 @@ public partial class SDSLGrammar : Grammar protected LiteralTerminal AppendStructuredBuffer = new(); protected AlternativeParser ComponentNumber = new(); - protected LiteralTerminal Bool = new(); + protected SequenceParser Bool = new(){Name = "ScalarType"}; protected SequenceParser BoolVec = new(); protected SequenceParser BoolMat = new(); - protected AlternativeParser Uint = new(); + protected AlternativeParser Uint = new(){Name = "ScalarType"}; protected SequenceParser UintVec = new(); protected SequenceParser UintMat = new(); - protected LiteralTerminal Int = new(); + protected SequenceParser Int = new(){Name = "ScalarType"}; protected SequenceParser IntVec = new(); protected SequenceParser IntMat = new(); - protected LiteralTerminal Half = new(); + protected SequenceParser Half = new(){Name = "ScalarType"}; protected SequenceParser HalfVec = new(); protected SequenceParser HalfMat = new(); - protected LiteralTerminal Float = new(); + protected SequenceParser Float = new(){Name = "ScalarType"}; protected SequenceParser FloatVec = new(); protected SequenceParser FloatMat = new(); - protected LiteralTerminal Double = new(); + protected SequenceParser Double = new(){Name = "ScalarType"}; protected SequenceParser DoubleVec = new(); protected SequenceParser DoubleMat = new(); protected LiteralTerminal Buffer = new(); @@ -161,27 +161,27 @@ public void CreateTokens() Spaces = Space.Optional().Repeat(); SpacesWithLineBreak = WhiteSpace.Optional().Repeat().Then(Eol); AppendStructuredBuffer = Literal("AppendStructuredBuffer"); - ComponentNumber = Literal("1") | "2" | "3" | "4"; + ComponentNumber.Add("1" , "2" , "3" , "4"); - Bool = Literal("bool"); - BoolVec.Add(Bool,ComponentNumber); - BoolMat.Add(BoolVec,Literal("x"),ComponentNumber); + Bool.Add("bool"); + BoolVec.Add(Bool,ComponentNumber.Named("Size1")); + BoolMat.Add(BoolVec,Literal("x"),ComponentNumber.Named("Size2")); Uint.Add("uint","unsigned int", "dword"); - UintVec.Add(Uint,ComponentNumber); - UintMat.Add(UintVec,"x",ComponentNumber); - Int = Literal("int"); - IntVec.Add(Int,ComponentNumber); - IntMat.Add(IntVec,"x",ComponentNumber); + UintVec.Add(Uint,ComponentNumber.Named("Size1")); + UintMat.Add(UintVec,"x",ComponentNumber.Named("Size2")); + Int.Add("int"); + IntVec.Add(Int,ComponentNumber.Named("Size1")); + IntMat.Add(IntVec,"x",ComponentNumber.Named("Size2")); - Half = Literal("half"); - HalfVec.Add(Half, ComponentNumber); - HalfMat.Add(HalfVec, "x", ComponentNumber); - Float = Literal("float"); - FloatVec.Add(Float,ComponentNumber); - FloatMat.Add(FloatVec,"x",ComponentNumber); - Double = Literal("double"); - DoubleVec.Add(Double,ComponentNumber); - DoubleMat.Add(DoubleVec,"x",ComponentNumber); + Half.Add("half"); + HalfVec.Add(Half, ComponentNumber.Named("Size1")); + HalfMat.Add(HalfVec, "x", ComponentNumber.Named("Size1")); + Float.Add("float"); + FloatVec.Add(Float,ComponentNumber.Named("Size1")); + FloatMat.Add(FloatVec,"x",ComponentNumber.Named("Size2")); + Double.Add("double"); + DoubleVec.Add(Double,ComponentNumber.Named("Size1")); + DoubleMat.Add(DoubleVec,"x",ComponentNumber.Named("Size2")); Buffer = Literal("Buffer"); ByteAddressBuffer = Literal("ByteAddressBuffer"); Break = Literal("break"); @@ -241,11 +241,11 @@ public void CreateTokens() Literal("TextureCube").Then(Literal("Array").Optional()) ); TextureTypes.Add( - (TextureBase & "<" & ValueTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), + (TextureBase & "<" & SimpleTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), TextureBase ); BufferTypes.Add( - (Buffer & "<" & ValueTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), + (Buffer & "<" & SimpleTypes.Except(TextureTypes | BufferTypes) & ">").SeparatedBy(WhiteSpace.Repeat(0)), Buffer ); Triangle = Literal("triangle"); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs index 0684fe78e5..c13fedda24 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs @@ -21,8 +21,8 @@ public override void CreateShader() var shaderGenericValue = new AlternativeParser( Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(ws1).Named("Semantic"), - ValueTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), - ValueTypes + SimpleTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), + SimpleTypes ){ Name = "ShaderGeneric" }; var shaderGenerics = new SequenceParser( @@ -32,7 +32,7 @@ public override void CreateShader() ){ Name = "ShaderGenerics", Separator = ws }; var inheritGenericsValues = new AlternativeParser( - ValueTypes, + SimpleTypes, Identifier, Literals ); diff --git a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs index 3af5b1d6c7..6d54a7a261 100644 --- a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs +++ b/src/Stride.Shaders/Parsers/ShaderMixinParser.cs @@ -108,7 +108,7 @@ public ShaderProgram Parse(string shader) ParseTree = Grammar.Match(code); if (!ParseTree.Success) throw new Exception(ParseTree.ErrorMessage); - return (ShaderProgram)ShaderToken.GetToken(ParseTree); + return (ShaderProgram)ShaderToken.Tokenize(ParseTree); //return null; } List ParseMixins(string shader) From 612170170fe2b3f378c284b5ca59bb59d5e32013 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 15 Sep 2022 23:05:58 +0200 Subject: [PATCH 0148/1182] Number literal checker --- .../AST/Shader/Analysis/SymbolTable.Check.cs | 16 +++++++++ .../AST/Shader/Analysis/SymbolTable.cs | 13 +++++-- .../Parsers/AST/Shader/Literals.cs | 36 ++++++++++++++++--- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs index bc21db7c5c..6251e69f0e 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs @@ -10,6 +10,22 @@ public void CheckVar(Statement s) if(s is IVariableCheck v) v.CheckVariables(this); } + + public ISymbolType TokenizeScalar(string name) + { + return name switch + { + "byte" => new ScalarType("byte"), + "sbyte" => new ScalarType("byte"), + "short" => new ScalarType("short"), + "half" => new ScalarType("half"), + "int" => new ScalarType("int"), + "uint" => new ScalarType("uint"), + "float" => new ScalarType("float"), + "double" => new ScalarType("double"), + _ => throw new NotImplementedException() + }; + } public ISymbolType Tokenize(Match m) { return (m.Name, m.HasMatches) switch diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 255a24545c..f8d584d11a 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -6,6 +6,7 @@ public interface ISymbol{} public partial class SymbolTable : Stack> { public Dictionary CurrentScope => Peek(); + public Dictionary GlobalScope => this.First(); public SymbolTable() { Push(new()); @@ -32,9 +33,15 @@ public void PushStreamVar() } public ISymbolType PushType(string name, Eto.Parse.Match type) { - if(!CurrentScope.ContainsKey(name)) - CurrentScope[name] = Tokenize(type); - return (ISymbolType)CurrentScope[name]; + if(!GlobalScope.ContainsKey(name)) + GlobalScope[name] = Tokenize(type); + return (ISymbolType)GlobalScope[name]; + } + public ISymbolType PushScalarType(string name) + { + if(!GlobalScope.ContainsKey(name)) + GlobalScope[name] = TokenizeScalar(name); + return (ISymbolType)GlobalScope[name]; } public void SetType(string variableName, ISymbolType type) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 55ad8fdef4..7f096da1c2 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -33,6 +33,14 @@ public NumberLiteral(Match match, SymbolTable s) if (!match.HasMatches) { Value = match.Value; + InferredType = Value switch + { + int => s.PushScalarType("int"), + long => s.PushScalarType("int"), + float => s.PushScalarType("float"), + double => s.PushScalarType("float"), + _ => throw new NotImplementedException() + }; } else { @@ -44,14 +52,34 @@ public NumberLiteral(Match match, SymbolTable s) { Value = match.Matches[0].Value; Suffix = match["Suffix"].StringValue; + InferredType = Suffix switch + { + "l" => s.PushScalarType("long"), + "d" => s.PushScalarType("double"), + "f" => s.PushScalarType("float"), + "u" => s.PushScalarType("uint"), + "L" => s.PushScalarType("long"), + "D" => s.PushScalarType("double"), + "F" => s.PushScalarType("float"), + "U" => s.PushScalarType("uint"), + _ => throw new NotImplementedException(), + }; } } } public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { - throw new NotImplementedException(); - if (Suffix is null) + if (!expected.Equals(inferredType)) { + inferredType = (inferredType, expected) switch + { + (ScalarType{TypeName : "int"}, ScalarType{TypeName: "float"}) => expected, + (ScalarType{TypeName : "float"}, ScalarType{TypeName: "int"}) => expected, + _ => throw new NotImplementedException() + }; + } + // if (Suffix is null) + // { // if (expected != string.Empty) // { // inferredType = (Value, expected) switch @@ -99,7 +127,7 @@ public override void TypeCheck(SymbolTable symbols, ISymbolType expected) // _ => throw new NotImplementedException() // }; // } - } + // } } } public class HexLiteral : NumberLiteral @@ -183,7 +211,7 @@ public override void TypeCheck(SymbolTable symbols, ISymbolType expected) public void CheckVariables(SymbolTable s) { - if(!s.Any(x => x.ContainsKey(Name))) + if (!s.Any(x => x.ContainsKey(Name))) throw new Exception("Not a variable"); } public override string ToString() From 40085702240cfeb638685e42c8768d68d50f69d9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 15 Sep 2022 23:43:59 +0200 Subject: [PATCH 0149/1182] name for stream type --- src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index f8d584d11a..db82bd720d 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -28,7 +28,7 @@ public void PushStreamType(IEnumerable variables) } public void PushStreamVar() { - if(TryGetType("streams", out var type)) + if(TryGetType("STREAM", out var type)) CurrentScope["streams"] = new SymbolVariable(){Name = "streams", Type = type}; } public ISymbolType PushType(string name, Eto.Parse.Match type) From 26725997da8398ae42b02f88f8f042269db70296 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 16 Sep 2022 17:11:55 +0200 Subject: [PATCH 0150/1182] Type checking on assign chain --- .../AST/Shader/Analysis/SymbolTable.Check.cs | 3 + .../AST/Shader/Analysis/SymbolTable.cs | 15 +++- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 71 +++++++++++++++---- .../AST/Shader/Analysis/SymbolVariable.cs | 4 +- .../Parsers/AST/Shader/Literals.cs | 2 +- .../Parsers/AST/Shader/Statements.cs | 16 +++++ 6 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs index 6251e69f0e..d5b99e8528 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs @@ -8,7 +8,10 @@ public partial class SymbolTable public void CheckVar(Statement s) { if(s is IVariableCheck v) + { v.CheckVariables(this); + } + s.TypeCheck(this,ScalarType.VoidType); } public ISymbolType TokenizeScalar(string name) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index db82bd720d..9f086f57ef 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -20,7 +20,7 @@ public void PushVar(Declaration a) if(d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); a.Value.TypeCheck(this, a.TypeName); - CurrentScope.Add(a.VariableName, new SymbolVariable{Declaration = a}); + CurrentScope.Add(a.VariableName, new SymbolVariable{Declaration = a, Name = a.VariableName, Type = a.TypeName}); } public void PushStreamType(IEnumerable variables) { @@ -70,6 +70,19 @@ public bool TryGetType(string variableName, out ISymbolType type) } return false; } + public bool TryGetVarType(string variableName, out ISymbolType type) + { + foreach(var scope in this) + { + if(scope.TryGetValue(variableName, out var t)) + { + type = ((SymbolVariable)t).Type; + return true; + } + } + type = ScalarType.VoidType; + return false; + } public void Analyse(Statement s) { if(s is Declaration d) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index d96aeb8b1b..d87f90b283 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -6,11 +6,12 @@ public interface ISymbolType : ISymbol, IEquatable { public bool IsAccessorValid(string accessor); public bool IsIndexingValid(string index); + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed); } public class ArrayType : ISymbolType { - public ISymbolType TypeName {get;set;} + public ISymbolType TypeName { get; set; } public bool Equals(ISymbolType? other) @@ -27,19 +28,30 @@ public bool IsIndexingValid(string index) { return true; } + + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) + { + typeOfAccessed = ScalarType.VoidType; + if (int.TryParse(accessor, out var _)) + { + typeOfAccessed = TypeName; + return true; + } + return false; + } } public class CompositeType : ISymbolType { - public string Name {get;set;} - public Dictionary Fields {get;set;} = new(); + public string Name { get; set; } + public Dictionary Fields { get; set; } = new(); - public CompositeType(string name, Dictionary fields) + public CompositeType(string name, Dictionary fields) { Name = name; Fields = fields; } - + public bool Equals(ISymbolType? other) { return true; @@ -55,17 +67,23 @@ public bool IsIndexingValid(string index) { return false; } + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) + { + var result = Fields.TryGetValue(accessor, out var tmp ); + typeOfAccessed = tmp ?? ScalarType.VoidType; + return result; + } } public class VectorType : ISymbolType { - public int Size{get;set;} - public ISymbolType TypeName {get;set;} - static string[] accessors = new string[]{"x","y","z","w"}; + public int Size { get; set; } + public ISymbolType TypeName { get; set; } + static string[] accessors = new string[] { "x", "y", "z", "w" }; public VectorType(string size, ISymbolType type) { - if(int.TryParse(size, out var s)) + if (int.TryParse(size, out var s)) { Size = s; TypeName = type; @@ -87,16 +105,26 @@ public bool Equals(ISymbolType? other) { throw new NotImplementedException(); } + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) + { + if(IsAccessorValid(accessor)) + { + typeOfAccessed = TypeName; + return true; + } + typeOfAccessed = ScalarType.VoidType; + return false; + } } public class MatrixType : ISymbolType { - public int SizeX{get;set;} - public int SizeY{get;set;} - public string TypeName {get;set;} + public int SizeX { get; set; } + public int SizeY { get; set; } + public ISymbolType TypeName { get; set; } static readonly Grammar accessorGrammar = new( Terminals.Literal("_") - .Then("m" & Terminals.Set("0123") & Terminals.Set("0123")) + .Then("m" & Terminals.Set("0123") & Terminals.Set("0123")) .Or(Terminals.Set("1234") & Terminals.Set("1234")) .WithName("accessor") ); @@ -115,11 +143,21 @@ public bool Equals(ISymbolType? other) { throw new NotImplementedException(); } + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) + { + if(IsAccessorValid(accessor)) + { + typeOfAccessed = TypeName; + return true; + } + typeOfAccessed = ScalarType.VoidType; + return false; + } } public class ScalarType : ISymbolType { public static readonly ScalarType VoidType = new("void"); - public string TypeName {get;set;} + public string TypeName { get; set; } public ScalarType(string type) { @@ -140,4 +178,9 @@ public bool Equals(ISymbolType? other) { return other is ScalarType o && TypeName == o.TypeName; } + public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) + { + typeOfAccessed = ScalarType.VoidType; + return false; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs index e7417d7c65..ddab9ea853 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs @@ -2,7 +2,7 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; public class SymbolVariable : ISymbol { - public string? Name {get;set;} - public ISymbolType? Type {get;set;} + public string Name {get;set;} + public ISymbolType Type {get;set;} public Declaration? Declaration {get;set;} } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 7f096da1c2..d72a515475 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -202,7 +202,7 @@ public VariableNameLiteral(Match m, SymbolTable s) public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { - if (symbols.TryGetType(Name, out var type)) + if (symbols.TryGetVarType(Name, out var type)) { this.inferredType = type; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 3fe33136f6..87d442212d 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -124,6 +124,22 @@ public void CheckVariables(SymbolTable s) throw new Exception("Variable not exist"); if(Value is IVariableCheck v) v.CheckVariables(s); } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) + { + ISymbolType chainType = ScalarType.VoidType; + foreach(var a in AccessNames) + { + if(a == AccessNames.First()) + { + if(!symbols.TryGetVarType(a,out chainType)) + throw new Exception("wrong accessor"); + } + else + if(!chainType.TryAccessType(a,out chainType)) + throw new Exception("wrong accessor"); + } + Value.TypeCheck(symbols, chainType); + } } public class ReturnStatement : Statement, IStreamCheck, IStaticCheck From fed3ddfd757c1e2b1dd116948c751d80fc98b7e2 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Wed, 21 Sep 2022 01:31:05 +0200 Subject: [PATCH 0151/1182] added method value call --- .../SDSL/MixinSamples/SingleShader.sdsl | 2 +- .../Compiler/Emitter/SpirvEmitter.Streams.cs | 1 + .../Compiler/Emitter/SpirvEmitter.cs | 1 - .../AST/Shader/Analysis/SymbolTable.cs | 2 +- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 22 +++++++++++++++++++ .../Parsers/AST/Shader/Literals.cs | 2 +- .../Parsers/AST/Shader/Operations.cs | 14 ++++++++++++ .../Parsers/AST/Shader/ShaderToken.cs | 3 ++- .../Parsers/AST/Shader/Statements.cs | 20 ++++++++++++++++- .../SDSLGrammar/SDSLGrammar.Expression.cs | 11 +++++++++- .../SDSLGrammar/SDSLGrammar.Statements.cs | 7 +++--- 11 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 213f1ec8c4..d8802aecb4 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -27,7 +27,7 @@ shader SingleShader { void VSMain() { - int a = 0; + float4 a = float4(0); streams.ShadingPosition = a; streams.Depth = streams.ShadingPosition; } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index 0fab49c6dc..9ad73d31df 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -25,6 +25,7 @@ public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) _ => throw new NotImplementedException() }; + // var variables = // program.Body // .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 3d01ad7765..e792628b30 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -18,7 +18,6 @@ public partial class SpirvEmitter : Module public SpirvEmitter(uint version) : base(version) { ShaderTypes = new(); - CreateStructTypes(); } public void Initialize(EntryPoints entry) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 9f086f57ef..b1f4d5fb51 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -19,7 +19,7 @@ public void PushVar(Declaration a) foreach(var d in this) if(d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); - a.Value.TypeCheck(this, a.TypeName); + a.TypeCheck(this,ScalarType.VoidType); CurrentScope.Add(a.VariableName, new SymbolVariable{Declaration = a, Name = a.VariableName, Type = a.TypeName}); } public void PushStreamType(IEnumerable variables) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index d87f90b283..d99d79e03f 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -39,6 +39,11 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) } return false; } + + public override string ToString() + { + return $"{TypeName}[]"; + } } public class CompositeType : ISymbolType @@ -73,6 +78,10 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) typeOfAccessed = tmp ?? ScalarType.VoidType; return result; } + public override string ToString() + { + return $"{Name}"; + } } public class VectorType : ISymbolType @@ -115,6 +124,10 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) typeOfAccessed = ScalarType.VoidType; return false; } + public override string ToString() + { + return $"{TypeName}{Size}"; + } } public class MatrixType : ISymbolType { @@ -153,6 +166,11 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) typeOfAccessed = ScalarType.VoidType; return false; } + + public override string ToString() + { + return $"{TypeName}{SizeX}x{SizeY}"; + } } public class ScalarType : ISymbolType { @@ -183,4 +201,8 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) typeOfAccessed = ScalarType.VoidType; return false; } + public override string ToString() + { + return TypeName; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index d72a515475..a69ce969d3 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -75,7 +75,7 @@ public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { (ScalarType{TypeName : "int"}, ScalarType{TypeName: "float"}) => expected, (ScalarType{TypeName : "float"}, ScalarType{TypeName: "int"}) => expected, - _ => throw new NotImplementedException() + _ => throw new Exception($"cannot implictely cast {inferredType} to {expected}") }; } // if (Suffix is null) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index 71b92893d6..ea92e3a368 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -405,3 +405,17 @@ public MethodCall(Match m, SymbolTable s) // Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).Cast().ToList(); } } + +public class ValueMethodCall : Expression +{ + public string MethodName { get; set; } + public IEnumerable Parameters { get; set; } + + public ValueMethodCall(Match m, SymbolTable s) + { + Match = m; + MethodName = m.Matches.First().StringValue; + inferredType = s.Tokenize(m["ValueTypes"]); + Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(x => GetToken(x, s)).Cast().ToList(); + } +} diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 9dda72ae40..c39c032be2 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -44,9 +44,10 @@ public static ShaderToken GetToken(Match match, SymbolTable symbols) "Return" => new ReturnStatement(tmp, symbols), "AssignChain" => new AssignChain(tmp, symbols), "DeclareAssign" => new DeclareAssign(tmp, symbols), - "SimpleDeclare" => throw new NotImplementedException(), + "SimpleDeclare" => new SimpleDeclare(tmp, symbols), "EmptyStatement" => new EmptyStatement(), "MethodCall" => new MethodCall(tmp, symbols), + "ValueTypesMethods" => new ValueMethodCall(tmp, symbols), "Ternary" => new ConditionalExpression(tmp, symbols), "LogicalOrExpression" => LogicalOrExpression.Create(tmp, symbols), "LogicalAndExpression" => LogicalAndExpression.Create(tmp, symbols), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 87d442212d..4ac694a040 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -36,13 +36,14 @@ public abstract class Declaration : Statement public override ISymbolType InferredType => ScalarType.VoidType; public ISymbolType? TypeName { get; set; } public string VariableName { get; set; } - public ShaderTokenTyped Value { get; set; } } public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck { public AssignOpToken AssignOp { get; set; } + public ShaderTokenTyped Value { get; set; } + public DeclareAssign() { } public DeclareAssign(Match m, SymbolTable s) @@ -75,6 +76,23 @@ public IEnumerable GetAssignedStream() { return Enumerable.Empty(); } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) + { + Value.TypeCheck(symbols,TypeName); + } +} + +public class SimpleDeclare : Declaration +{ + public SimpleDeclare() { } + public SimpleDeclare(Match m, SymbolTable s) + { + Match = m; + VariableName = m["Variable"].StringValue; + TypeName = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); + + } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected){} } public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index 4086f3a343..d9aff5eb14 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -24,6 +24,7 @@ public partial class SDSLGrammar : Grammar public AlternativeParser IncrementExpression = new() { Name = "IncrementExpression" }; public AlternativeParser ParenExpression = new(){Name = "ParenExpression"}; public AlternativeParser EqualsExpression = new(){Name = "EqualsExpression"}; + public SequenceParser ValueTypesMethods = new(){Name = "ValueTypesMethods"}; public SequenceParser MethodCall = new(){Name = "MethodCall"}; public AlternativeParser PrimaryExpression = new(){Name = "PrimaryExpression"}; @@ -60,11 +61,19 @@ public void CreateExpressions() PlusPlus, MinusMinus ); - + + ValueTypesMethods.Add( + ValueTypes, + LeftParen, + PrimaryExpression.Repeat(0).SeparatedBy(ws & Comma & ws).Until(RightParen), + RightParen + ); + ValueTypesMethods.Separator = ws; TermExpression.Add( Literals, Identifier.Named("VariableTerm").Except(Keywords | SimpleTypes).NotFollowedBy(ws & LeftParen).Named("VariableTerm"), + ValueTypesMethods.Named("ValueTypesMethod"), MethodCall, Parenthesis(PrimaryExpression) ); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 0b0c97adef..8ca2c94250 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -43,8 +43,9 @@ public void CreateStatements() Attribute.Separator = ws; var arraySpecifier = - (LeftBracket & PrimaryExpression & RightBracket).SeparatedBy(ws); + (LeftBracket & PrimaryExpression.Named("Count") & RightBracket).SeparatedBy(ws); + arraySpecifier.Name = "ArraySpecifier"; var assignVar = @@ -69,8 +70,8 @@ public void CreateStatements() .SeparatedBy(ws1); var simpleDeclare = - ((SimpleTypes | Identifier) & Identifier & arraySpecifier).SeparatedBy(ws) - | ((SimpleTypes | Identifier) & Identifier).SeparatedBy(ws); + ((SimpleTypes | Identifier) & Identifier.Named("Variable") & arraySpecifier).SeparatedBy(ws) + | ((SimpleTypes | Identifier) & Identifier.Named("Variable")).SeparatedBy(ws); Statement.Add( Block, From a203834a8d1006c8feb165b4fb896b7602db2c95 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 29 Sep 2022 22:48:14 +0200 Subject: [PATCH 0152/1182] error checking --- src/SDSLParserExample/Program.cs | 2 +- .../SDSL/MixinSamples/SingleShader.sdsl | 4 +- .../Compiler/Mixer/SimpleMixer.cs | 3 +- .../Parsers/AST/Shader/Analysis/Errors.cs | 21 +++++++++ .../AST/Shader/Analysis/SymbolTable.cs | 3 ++ .../Parsers/AST/Shader/Analysis/SymbolType.cs | 4 +- .../Parsers/AST/Shader/Literals.cs | 2 +- .../Parsers/AST/Shader/Operations.cs | 5 ++ .../Parsers/AST/Shader/Statements.cs | 40 +++++++++------- .../Parsers/AST/Shader/UnaryLiterals.cs | 47 ++++++++++++++----- 10 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index cb636f58e7..874aa0fdb5 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -26,7 +26,7 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - mixer.SemanticChecks(); + var errors = mixer.SemanticChecks(); var module = mixer.EmitSpirv(EntryPoints.VSMain); var used = mixer.program.Body.OfType().First().GetUsedStream().ToList(); diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index d8802aecb4..b9724bd642 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -27,8 +27,8 @@ shader SingleShader { void VSMain() { - float4 a = float4(0); - streams.ShadingPosition = a; + float3 a = float3(0); + streams.ShadingPosition2 = a; streams.Depth = streams.ShadingPosition; } }; \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 3add6b8dcd..8b316cffdc 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -19,7 +19,7 @@ public SimpleMixer(string className, ShaderSourceManager manager) program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); il = new(); } - public void SemanticChecks() + public ErrorList SemanticChecks() { var sym = new SymbolTable(); sym.PushStreamType(program.Body.OfType()); @@ -30,6 +30,7 @@ public void SemanticChecks() method.VariableChecking(sym); sym.Pop(); } + return sym.Errors; } public Module EmitSpirv(EntryPoints entry) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs new file mode 100644 index 0000000000..c07c6c1ba4 --- /dev/null +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs @@ -0,0 +1,21 @@ +namespace Stride.Shaders.Parsing.AST.Shader.Analysis; + +using Eto.Parse; + + +public class ErrorInfo +{ + public Match Match {get;set;} + public string Message {get;set;} + + public ErrorInfo(Match mtc, string msg) + { + Match = mtc; + Message = msg; + } +} + +public class ErrorList : List +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index b1f4d5fb51..fb99aaa67e 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -5,6 +5,7 @@ public interface ISymbol{} public partial class SymbolTable : Stack> { + public ErrorList Errors {get;set;} = new(); public Dictionary CurrentScope => Peek(); public Dictionary GlobalScope => this.First(); public SymbolTable() @@ -13,6 +14,8 @@ public SymbolTable() } public void AddScope() => Push(new()); + public void AddError(Eto.Parse.Match match, string title) => Errors.Add(new(match, title)); + public void PushVar(Declaration a) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index d99d79e03f..331188420c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -112,7 +112,9 @@ public bool IsIndexingValid(string index) public bool Equals(ISymbolType? other) { - throw new NotImplementedException(); + return other is VectorType v + && v.TypeName.Equals(TypeName) + && v.Size == Size; } public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index a69ce969d3..1602501c35 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -204,7 +204,7 @@ public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { if (symbols.TryGetVarType(Name, out var type)) { - this.inferredType = type; + inferredType = type; } else throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs index ea92e3a368..4062f2bfee 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs @@ -418,4 +418,9 @@ public ValueMethodCall(Match m, SymbolTable s) inferredType = s.Tokenize(m["ValueTypes"]); Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(x => GetToken(x, s)).Cast().ToList(); } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) + { + if(!inferredType.Equals(expected)) + symbols.AddError(Match, $"cannot cast {inferredType} to {expected}"); + } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 4ac694a040..8e9380a127 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -50,9 +50,9 @@ public DeclareAssign(Match m, SymbolTable s) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - TypeName = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); + TypeName = s.PushType(m["ValueTypes"].StringValue, m["ValueTypes"]); VariableName = m["Variable"].StringValue; - Value = (ShaderTokenTyped)GetToken(m["Value"],s); + Value = (ShaderTokenTyped)GetToken(m["Value"], s); } public bool CheckStatic(SymbolTable s) @@ -78,7 +78,7 @@ public IEnumerable GetAssignedStream() } public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { - Value.TypeCheck(symbols,TypeName); + Value.TypeCheck(symbols, TypeName); } } @@ -89,10 +89,10 @@ public SimpleDeclare(Match m, SymbolTable s) { Match = m; VariableName = m["Variable"].StringValue; - TypeName = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); + TypeName = s.PushType(m["ValueTypes"].StringValue, m["ValueTypes"]); } - public override void TypeCheck(SymbolTable symbols, ISymbolType expected){} + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { } } public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck @@ -108,7 +108,7 @@ public AssignChain(Match m, SymbolTable s) Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); - Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"],s); + Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"], s); } public bool CheckStream(SymbolTable s) @@ -138,25 +138,33 @@ public bool CheckStatic(SymbolTable s) public void CheckVariables(SymbolTable s) { - if(!s.Any(x => x.ContainsKey(this.AccessNames.First()))) + if (!s.Any(x => x.ContainsKey(this.AccessNames.First()))) throw new Exception("Variable not exist"); - if(Value is IVariableCheck v) v.CheckVariables(s); + if (Value is IVariableCheck v) v.CheckVariables(s); } public override void TypeCheck(SymbolTable symbols, ISymbolType expected) { ISymbolType chainType = ScalarType.VoidType; - foreach(var a in AccessNames) + foreach (var a in AccessNames) { - if(a == AccessNames.First()) + var tmp = chainType; + if (a == AccessNames.First()) + { + if (!symbols.TryGetVarType(a, out chainType)) + { + symbols.AddError(Match, $"Field `{a}` doesn't exist in type `{tmp}`"); + return; + } + } + else if (!chainType.TryAccessType(a, out chainType)) { - if(!symbols.TryGetVarType(a,out chainType)) - throw new Exception("wrong accessor"); + symbols.AddError(Match, $"Field `{a}` doesn't exist in type `{tmp}`"); + return; } - else - if(!chainType.TryAccessType(a,out chainType)) - throw new Exception("wrong accessor"); } - Value.TypeCheck(symbols, chainType); + Value.TypeCheck(symbols, null); // Variable check ? + if (!chainType.Equals(Value.InferredType)) + symbols.AddError(Match, $"Cannot cast `{chainType}` to `{Value.InferredType}`"); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index 81a5482373..fe92553cdf 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -18,18 +18,19 @@ public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck { public ShaderToken Value { get; set; } public IEnumerable Field { get; set; } + public override ISymbolType InferredType { get => inferredType; set => inferredType = value; } public ChainAccessor(Match m, SymbolTable s) { Match = m; - Value = GetToken(m.Matches["Identifier"],s); - Field = m.Matches.GetRange(1,m.Matches.Count-1).Select(x => GetToken(x,s)); + Value = GetToken(m.Matches["Identifier"], s); + Field = m.Matches.GetRange(1, m.Matches.Count - 1).Select(x => GetToken(x, s)); } public IEnumerable GetUsedStream() { - if(Value is VariableNameLiteral vn && vn.Name == "streams") - return new List{((VariableNameLiteral)Field.First()).Name}; + if (Value is VariableNameLiteral vn && vn.Name == "streams") + return new List { ((VariableNameLiteral)Field.First()).Name }; return Enumerable.Empty(); } public IEnumerable GetAssignedStream() @@ -42,7 +43,27 @@ public bool CheckStream(SymbolTable symbols) } public void CheckVariables(SymbolTable s) { - if(Value is IVariableCheck n) n.CheckVariables(s); + if (Value is IVariableCheck n) n.CheckVariables(s); + } + public override void TypeCheck(SymbolTable symbols, ISymbolType expected) + { + if (Value is VariableNameLiteral vn && symbols.TryGetVarType(vn.Name, out var type)) + { + ISymbolType current = type; + + foreach (var a in Field) + { + var tmp = current; + if (a is VariableNameLiteral vna) + { + if(!current.TryAccessType(vna.Name, out current)) + { + symbols.AddError(Match, $"Accessor `{vna.Name}` does not exist for type `{tmp}`"); + } + } + } + inferredType = current; + } } } @@ -50,17 +71,17 @@ public class ArrayAccessor : UnaryExpression, IVariableCheck { public ShaderToken Value { get; set; } public IEnumerable Accessors { get; set; } - + public ArrayAccessor(Match m, SymbolTable s) { Match = m; - Value= GetToken(m.Matches[0],s); + Value = GetToken(m.Matches[0], s); throw new NotImplementedException(); // Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); } public void CheckVariables(SymbolTable s) { - if(Value is IVariableCheck n) n.CheckVariables(s); + if (Value is IVariableCheck n) n.CheckVariables(s); } } @@ -72,7 +93,7 @@ public class PostfixIncrement : UnaryExpression, IVariableCheck public PostfixIncrement(Match m, SymbolTable s) { Match = m; - Value = GetToken(m.Matches[0],s); + Value = GetToken(m.Matches[0], s); Operator = m.Matches[1].StringValue; } @@ -82,7 +103,7 @@ public override string ToString() } public void CheckVariables(SymbolTable s) { - if(Value is VariableNameLiteral n) n.CheckVariables(s); + if (Value is VariableNameLiteral n) n.CheckVariables(s); } } @@ -94,7 +115,7 @@ public PrefixIncrement(Match m, SymbolTable s) { Match = m; Operator = m.Matches[0].StringValue; - Value = GetToken(m.Matches[1],s); + Value = GetToken(m.Matches[1], s); } } @@ -104,7 +125,7 @@ public class CastExpression : UnaryExpression public ShaderToken From { get; set; } public CastExpression(Match m, SymbolTable s) { - Target = new TypeNameLiteral(m.Matches[0],s); - From = GetToken(m.Matches[1],s); + Target = new TypeNameLiteral(m.Matches[0], s); + From = GetToken(m.Matches[1], s); } } \ No newline at end of file From 6f0210c89da640c58e50f8e19335c77273622457 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 29 Sep 2022 23:01:23 +0200 Subject: [PATCH 0153/1182] error with accessor --- src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index b9724bd642..1b1a4ba775 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -28,7 +28,7 @@ shader SingleShader { void VSMain() { float3 a = float3(0); - streams.ShadingPosition2 = a; - streams.Depth = streams.ShadingPosition; + streams.ShadingPosition = a; + streams.Depth = streams.ShadingPosition.x; } }; \ No newline at end of file From 1739c39c72d3419498bfd15cc1b489d67ee7af66 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:42:33 +0200 Subject: [PATCH 0154/1182] swizzling testing --- .../SDSL/MixinSamples/SingleShader.sdsl | 2 +- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 1b1a4ba775..0c75669b04 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -27,7 +27,7 @@ shader SingleShader { void VSMain() { - float3 a = float3(0); + float4 a = float4(0); streams.ShadingPosition = a; streams.Depth = streams.ShadingPosition.x; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index 331188420c..271584f21a 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -88,7 +88,8 @@ public class VectorType : ISymbolType { public int Size { get; set; } public ISymbolType TypeName { get; set; } - static string[] accessors = new string[] { "x", "y", "z", "w" }; + static string swizzleX = "xyzw"; + static string swizzleR = "rgba"; public VectorType(string size, ISymbolType type) { @@ -99,10 +100,20 @@ public VectorType(string size, ISymbolType type) } else throw new NotImplementedException(); } + public VectorType(int size, ISymbolType type) + { + Size = size; + TypeName = type; + } public bool IsAccessorValid(string accessor) { - return accessor.All(accessor[0..Size].Contains); + return + accessor.Length < 5 + && ( + accessor.All(swizzleX.Contains) + || accessor.All(swizzleR.Contains) + ); } public bool IsIndexingValid(string index) @@ -120,7 +131,7 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) { if(IsAccessorValid(accessor)) { - typeOfAccessed = TypeName; + typeOfAccessed = accessor.Length > 1 ? new VectorType(accessor.Length,TypeName) : TypeName; return true; } typeOfAccessed = ScalarType.VoidType; From d7b5c23164a70c58a372a13274776dc9f3e6d63b Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 1 Oct 2022 22:43:17 +0200 Subject: [PATCH 0155/1182] added struct definition --- src/SDSLParserExample/Program.cs | 4 ++- .../SDSL/MixinSamples/SingleShader.sdsl | 6 +++++ src/Spv.Generator | 2 +- .../AST/Shader/Analysis/SymbolTable.cs | 4 +++ .../Parsers/AST/Shader/ShaderElements.cs | 22 ++++++++++----- .../Parsers/AST/Shader/ShaderToken.cs | 1 + .../SDSLGrammar/SDSLGrammar.Declaration.cs | 8 +++--- .../Parsers/ThreeAddress/Registers.cs | 15 +++++++---- .../Parsers/ThreeAddress/Snippet.Lowering.cs | 27 ++++++++++++++++--- 9 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 874aa0fdb5..ca626c886b 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -29,7 +29,9 @@ static void LoadShaders() var errors = mixer.SemanticChecks(); var module = mixer.EmitSpirv(EntryPoints.VSMain); - var used = mixer.program.Body.OfType().First().GetUsedStream().ToList(); + var main = mixer.program.Body.OfType().First(); + var snip = new Snippet(); + snip.Construct(main.Statements); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index 0c75669b04..aedeee7e01 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -1,5 +1,11 @@ shader SingleShader { + struct Position { + float x; + float y; + float z; + }; + stage stream float4 triInput; // Default SV_POSITION output for VS/GS shaders diff --git a/src/Spv.Generator b/src/Spv.Generator index a1473ad95f..9a3486864e 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit a1473ad95fbda4961e5eba2505f67a92f86ab51f +Subproject commit 9a3486864e970b1d26a8dd84ad1929c1a908cd79 diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index fb99aaa67e..4f6905f49b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -29,6 +29,10 @@ public void PushStreamType(IEnumerable variables) { CurrentScope["STREAM"] = new CompositeType("STREAM", variables.ToDictionary(v => v.Name, v => v.Type)); } + public void PushType(string name, StructDefinition structDef) + { + // CurrentScope[name] = new CompositeType(name, structDef.lds.); + } public void PushStreamVar() { if(TryGetType("STREAM", out var type)) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 0889510b02..f8f45e52a7 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -8,25 +8,33 @@ namespace Stride.Shaders.Parsing.AST.Shader; -public class ShaderStructField : ShaderToken +public class StructField : ShaderToken { - public string Type {get;set;} + public ISymbolType Type {get;set;} public string Name {get;set;} - public ShaderStructField(Match m) + public StructField(Match m, SymbolTable s) { - Match = m; + Match = m; + Type = s.Tokenize(m["ValueTypes"]); + Name = m["Name"].StringValue; } } -public class ShaderStruct : ShaderToken +public class StructDefinition : ShaderToken { - public IEnumerable Fields {get;set;} + public string StructName {get;set;} + public List Fields {get;set;} + + public CompositeType Type {get;set;} - public ShaderStruct(Match m, SymbolTable s) + public StructDefinition(Match m, SymbolTable s) { Match = m; + StructName = Match["StructName"].StringValue; + Fields = Match["Fields"].Matches.Select(x => new StructField(x,s)).ToList(); + Type = new CompositeType(StructName, Fields.ToDictionary(x => x.Name, x => s.Tokenize(x.Match["ValueTypes"]))); throw new NotImplementedException(); // Fields = m["Fields"].Matches.Select(GetToken).ToList(); diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index c39c032be2..8d2a8fae19 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -38,6 +38,7 @@ public static ShaderToken GetToken(Match match, SymbolTable symbols) "ResourceGroup" => new ResourceGroup(tmp,symbols), "ConstantBuffer" => new ConstantBuffer(tmp,symbols), "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp, symbols), + "StructDefinition" => new StructDefinition(tmp,symbols), "Method" => ShaderMethod.Create(tmp, symbols), "ControlFlow" => ControlFlow.Create(tmp, symbols), "Block" => new BlockStatement(tmp, symbols), diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index 4c4ffe5a91..645c6a2512 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -23,9 +23,9 @@ public void CreateDeclarators() var declare = new SequenceParser(); declare.Add( - SimpleTypes | Identifier, + ValueTypes, ws1, - Identifier, + Identifier.Named("Name"), ws, Semi ); @@ -94,9 +94,9 @@ public void CreateDeclarators() ConstantBufferValueDeclaration.Separator = ws; StructDefinition.Add( - Struct & ws1 & Identifier, + Struct & ws1 & Identifier.Named("StructName"), LeftBrace, - declare.Repeat(0).SeparatedBy(ws), + declare.Named("Declaration").Repeat(0).SeparatedBy(ws).Named("Fields"), RightBrace, Semi ); diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs index e615399d24..a85e53b684 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs @@ -41,17 +41,22 @@ public Constant(T v) Value = v; } } -public class CompositeConstant : Constant +public class CompositeConstant : Constant { - public IEnumerable Values; + public IEnumerable Values; - public CompositeConstant(IEnumerable v) + public CompositeConstant(IEnumerable v) { Values = v; } } -public class ChainAccessorRegister : Register +public class ChainRegister : Register { - public IEnumerable? Accessors {get;set;} + public IEnumerable Accessors {get;set;} + public ChainRegister(IEnumerable accessors) + { + Accessors = accessors; + } + } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs index d09709509b..2e495a3730 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs @@ -12,9 +12,10 @@ public IEnumerable LowerToken(ShaderToken token, bool isHead = true) return token switch { - // BlockStatement t => Lower(t), - // AssignChain t => Lower(t), + BlockStatement t => Lower(t), + AssignChain t => Lower(t), DeclareAssign t => Lower(t), + ValueMethodCall t => Lower(t), // ConditionalExpression t => Lower(t), Operation t => Lower(t), ArrayAccessor t => Lower(t, isHead), @@ -24,6 +25,17 @@ public IEnumerable LowerToken(ShaderToken token, bool isHead = true) }; } + public IEnumerable Lower(BlockStatement b) + { + return b.Statements.SelectMany(x => LowerToken(x)); + } + + public IEnumerable Lower(ValueMethodCall vm) + { + var values = vm.Parameters.SelectMany(x => LowerToken(x)); + return values.Append(new CompositeConstant(values.Select(x => x.Name ?? ""))); + } + public IEnumerable Lower(DeclareAssign d) { var value = LowerToken(d.Value); @@ -31,6 +43,13 @@ public IEnumerable Lower(DeclareAssign d) Add(r); return value.Append(r); } + public IEnumerable Lower(AssignChain a) + { + var value = LowerToken(a.Value); + var r = new ChainRegister(a.AccessNames); + Add(r); + return value.Append(r); + } public IEnumerable Lower(Operation o) @@ -51,7 +70,7 @@ public IEnumerable Lower(ChainAccessor ca, bool isHead = true) else { var accessors = ca.Field.SelectMany(x => LowerToken(x, false)); - var r = new ChainAccessorRegister(){Accessors = accessors.Select(x => x.Name)}; + var r = new ChainRegister(Enumerable.Empty()){Accessors = accessors.Select(x => x.Name)}; Add(r); return new List{r}; } @@ -65,7 +84,7 @@ public IEnumerable Lower(ArrayAccessor aa, bool isHead = true) else { var accessors = aa.Accessors.SelectMany(x => LowerToken(x, false)); - var r = new ChainAccessorRegister(){Accessors = accessors.Select(x => x.Name)}; + var r = new ChainRegister(Enumerable.Empty()){Accessors = accessors.Select(x => x.Name)}; Add(r); return new List{r}; } From d8a04f1e9673c5b73664a75795e4440d54a82d9c Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 2 Oct 2022 20:00:30 +0200 Subject: [PATCH 0156/1182] First IL working ? --- src/SDSLParserExample/Program.cs | 8 +- .../Compiler/Mixer/SimpleMixer.cs | 15 +-- .../AST/Shader/Analysis/SymbolTable.cs | 57 +++++----- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 13 ++- .../Parsers/AST/Shader/Literals.cs | 66 +++-------- .../Parsers/AST/Shader/ShaderElements.cs | 6 +- .../Parsers/AST/Shader/ShaderMethods.cs | 44 +++++-- .../Parsers/AST/Shader/ShaderProgram.cs | 25 +++- .../Parsers/AST/Shader/ShaderToken.cs | 4 +- .../Parsers/AST/Shader/UnaryLiterals.cs | 4 +- .../Parsers/ThreeAddress/Registers.cs | 69 ++++++++--- .../Parsers/ThreeAddress/Snippet.Lowering.cs | 107 +++++++++++++----- .../Parsers/ThreeAddress/Snippet.cs | 46 +++++++- 13 files changed, 297 insertions(+), 167 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index ca626c886b..340140f01d 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -14,6 +14,8 @@ using Stride.Shaders; using Stride.Shaders.Parsing.AST.Shader.Analysis; +Directory.SetCurrentDirectory("../../../"); + var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); // ShaderCompiling(shaderf); @@ -26,12 +28,10 @@ static void LoadShaders() manager.AddDirectory("./SDSL/MixinSamples"); var mixer = new SimpleMixer("SingleShader",manager); - var errors = mixer.SemanticChecks(); + var errors = mixer.SemanticChecks(); var module = mixer.EmitSpirv(EntryPoints.VSMain); var main = mixer.program.Body.OfType().First(); - var snip = new Snippet(); - snip.Construct(main.Statements); var x = 0; } @@ -59,7 +59,7 @@ static void ThreeAddress() var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2}; symbols.PushVar(s2); - var snip = new Snippet(); + var snip = new TAC(symbols); snip.Construct(s); var x = 0; } diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index 8b316cffdc..ba5a33f2f9 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -11,26 +11,17 @@ public class SimpleMixer { ShaderClassString source; public ShaderProgram program; - List il; public SimpleMixer(string className, ShaderSourceManager manager) { source = new(manager.GetShaderSource(className)); program = ShaderMixinParser.ParseShader(source.ShaderSourceCode); - il = new(); } - public ErrorList SemanticChecks() + public ErrorList SemanticChecks() where T : MainMethod { - var sym = new SymbolTable(); - sym.PushStreamType(program.Body.OfType()); + var errors = program.SemanticChecks(); - foreach(var method in program.Body.OfType()) - { - sym.AddScope(); - method.VariableChecking(sym); - sym.Pop(); - } - return sym.Errors; + return errors; } public Module EmitSpirv(EntryPoints entry) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 4f6905f49b..ac240c5d34 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -1,13 +1,16 @@ namespace Stride.Shaders.Parsing.AST.Shader.Analysis; -public interface ISymbol{} +public interface ISymbol { } public partial class SymbolTable : Stack> { - public ErrorList Errors {get;set;} = new(); - public Dictionary CurrentScope => Peek(); - public Dictionary GlobalScope => this.First(); + static readonly SymbolTable empty = new(); + public static SymbolTable Empty { get => empty; } + + public ErrorList Errors { get; set; } = new(); + public Dictionary CurrentScope => Peek(); + public Dictionary GlobalScope => this.First(); public SymbolTable() { Push(new()); @@ -19,47 +22,47 @@ public SymbolTable() public void PushVar(Declaration a) { - foreach(var d in this) - if(d.ContainsKey(a.VariableName)) + foreach (var d in this) + if (d.ContainsKey(a.VariableName)) throw new Exception("Variable already declared at " + a.Match); - a.TypeCheck(this,ScalarType.VoidType); - CurrentScope.Add(a.VariableName, new SymbolVariable{Declaration = a, Name = a.VariableName, Type = a.TypeName}); + a.TypeCheck(this, ScalarType.VoidType); + CurrentScope.Add(a.VariableName, new SymbolVariable { Declaration = a, Name = a.VariableName, Type = a.TypeName }); } public void PushStreamType(IEnumerable variables) { - CurrentScope["STREAM"] = new CompositeType("STREAM", variables.ToDictionary(v => v.Name, v => v.Type)); + CurrentScope["STREAM"] = new CompositeType("STREAM", new(variables.ToDictionary(v => v.Name, v => v.Type))); } - public void PushType(string name, StructDefinition structDef) + public void PushType(string name, CompositeType structDef) { - // CurrentScope[name] = new CompositeType(name, structDef.lds.); + CurrentScope[name] = structDef; } - public void PushStreamVar() + public void PushVar(string name, string type) { - if(TryGetType("STREAM", out var type)) - CurrentScope["streams"] = new SymbolVariable(){Name = "streams", Type = type}; + if (TryGetType(type, out var t)) + CurrentScope[name] = new SymbolVariable() { Name = name, Type = t }; } public ISymbolType PushType(string name, Eto.Parse.Match type) { - if(!GlobalScope.ContainsKey(name)) + if (!GlobalScope.ContainsKey(name)) GlobalScope[name] = Tokenize(type); return (ISymbolType)GlobalScope[name]; } public ISymbolType PushScalarType(string name) { - if(!GlobalScope.ContainsKey(name)) + if (!GlobalScope.ContainsKey(name)) GlobalScope[name] = TokenizeScalar(name); return (ISymbolType)GlobalScope[name]; } public void SetType(string variableName, ISymbolType type) { - foreach(var d in this) - if(d.TryGetValue(variableName, out var v)) + foreach (var d in this) + if (d.TryGetValue(variableName, out var v)) { - if(v is SymbolVariable sv) + if (v is SymbolVariable sv) { sv.Type = type; - if(sv.Declaration is not null) + if (sv.Declaration is not null) sv.Type = type; } } @@ -67,9 +70,9 @@ public void SetType(string variableName, ISymbolType type) public bool TryGetType(string variableName, out ISymbolType type) { type = ScalarType.VoidType; - foreach(var d in this) + foreach (var d in this) { - if(d.TryGetValue(variableName, out var v) && v is ISymbolType sv) + if (d.TryGetValue(variableName, out var v) && v is ISymbolType sv) { type = sv; return true; @@ -79,9 +82,9 @@ public bool TryGetType(string variableName, out ISymbolType type) } public bool TryGetVarType(string variableName, out ISymbolType type) { - foreach(var scope in this) + foreach (var scope in this) { - if(scope.TryGetValue(variableName, out var t)) + if (scope.TryGetValue(variableName, out var t)) { type = ((SymbolVariable)t).Type; return true; @@ -92,12 +95,12 @@ public bool TryGetVarType(string variableName, out ISymbolType type) } public void Analyse(Statement s) { - if(s is Declaration d) + if (s is Declaration d) PushVar(d); - else if(s is BlockStatement b) + else if (s is BlockStatement b) { AddScope(); - foreach(var bs in b.Statements) + foreach (var bs in b.Statements) Analyse(bs); Pop(); } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index 271584f21a..631127166e 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -49,9 +49,9 @@ public override string ToString() public class CompositeType : ISymbolType { public string Name { get; set; } - public Dictionary Fields { get; set; } = new(); + public SortedList Fields { get; set; } = new(); - public CompositeType(string name, Dictionary fields) + public CompositeType(string name, SortedList fields) { Name = name; Fields = fields; @@ -78,6 +78,15 @@ public bool TryAccessType(string accessor, out ISymbolType typeOfAccessed) typeOfAccessed = tmp ?? ScalarType.VoidType; return result; } + + public CompositeType SubType(string name, IEnumerable filter) + { + return new CompositeType( + name, + new(Fields.Where(x => filter.Contains(x.Key)).ToDictionary(x => x.Key, x=> x.Value)) + ); + } + public override string ToString() { return $"{Name}"; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs index 1602501c35..3cc93b24c5 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs @@ -78,56 +78,22 @@ public override void TypeCheck(SymbolTable symbols, ISymbolType expected) _ => throw new Exception($"cannot implictely cast {inferredType} to {expected}") }; } - // if (Suffix is null) - // { - // if (expected != string.Empty) - // { - // inferredType = (Value, expected) switch - // { - // (_, "double") => "double", - // (_, "float") => "float", - // (_, "half") => "half", - // (long l, "long") => "long", - // (long l, "int") => "int", - // (long l, "uint") => "uint", - // (long l, "short") => "short", - // (long l, "byte") => "byte", - // (long l, "sbyte") => "sbyte", - // _ => throw new NotImplementedException() - // }; - // } - // else - // { - // inferredType = "int"; - // } - // } - // else - // { - // if (expected != string.Empty) - // { - // inferredType = Suffix switch - // { - // "l" => "long", - // "u" => "uint", - // "f" => "float", - // "d" => "double", - // _ => throw new NotImplementedException() - // }; - // if (expected != inferredType) - // throw new NotImplementedException(); - // } - // else - // { - // inferredType = Suffix switch - // { - // "l" => "long", - // "u" => "uint", - // "f" => "float", - // "d" => "double", - // _ => throw new NotImplementedException() - // }; - // } - // } + } + public override string ToString() + { + return new StringBuilder().Append(InferredType.ToString()).Append('(').Append(Value.ToString()).Append(')').ToString(); + } + + public override bool Equals(object? obj) + { + return obj is NumberLiteral literal && + EqualityComparer.Default.Equals(inferredType, literal.inferredType) && + EqualityComparer.Default.Equals(Value, literal.Value); + } + + public override int GetHashCode() + { + return HashCode.Combine(inferredType, Value); } } public class HexLiteral : NumberLiteral diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index f8f45e52a7..36b7712fec 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -34,11 +34,7 @@ public StructDefinition(Match m, SymbolTable s) Match = m; StructName = Match["StructName"].StringValue; Fields = Match["Fields"].Matches.Select(x => new StructField(x,s)).ToList(); - Type = new CompositeType(StructName, Fields.ToDictionary(x => x.Name, x => s.Tokenize(x.Match["ValueTypes"]))); - throw new NotImplementedException(); - - // Fields = m["Fields"].Matches.Select(GetToken).ToList(); - + Type = new CompositeType(StructName, new(Fields.ToDictionary(x => x.Name, x => s.Tokenize(x.Match["ValueTypes"])))); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index d027495eb8..e10b3a049a 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -1,5 +1,6 @@ using Eto.Parse; using Stride.Shaders.Parsing.AST.Shader.Analysis; +using Stride.Shaders.ThreeAddress; namespace Stride.Shaders.Parsing.AST.Shader; @@ -45,7 +46,14 @@ public static ShaderMethod Create(Match m, SymbolTable s) public abstract class MainMethod : ShaderMethod, IStreamCheck { - public MainMethod(Match m, SymbolTable s) : base(m, s) { } + protected string prefix; + protected TAC snippet; + + public MainMethod(Match m, SymbolTable s) : base(m, s) + { + prefix = "NONE"; + snippet = new(s); + } public bool CheckStream(SymbolTable s) { @@ -65,11 +73,31 @@ public IEnumerable GetUsedStream() public void VariableChecking(SymbolTable sym) { if(CheckStream(sym)) - sym.PushStreamVar(); + sym.PushVar("streams","STREAM"); foreach (var s in Statements) sym.Analyse(s); } + public void CreateInOutStream(SymbolTable sym) + { + if(sym.TryGetType("STREAM", out var t)) + { + var used = GetUsedStream(); + var assigned = GetAssignedStream(); + var i = ((CompositeType)t).SubType(prefix + "_STREAM_IN",used); + var o = ((CompositeType)t).SubType(prefix + "_STREAM_OUT",assigned); + sym.PushType(i.Name, i); + sym.PushType(o.Name, o); + } + } + internal void GenerateIl(SymbolTable symbols) + { + CreateInOutStream(symbols); + symbols.PushVar("streams", "STREAM"); + symbols.PushVar("streams_in", prefix + "_STREAM_IN"); + symbols.PushVar("streams_out", prefix + "_STREAM_OUT"); + snippet.Construct(Statements); + } } @@ -77,41 +105,41 @@ public class VSMainMethod : MainMethod { public VSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "VS"; } } public class PSMainMethod : MainMethod { public PSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "PS"; } } public class GSMainMethod : MainMethod { public GSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "GS"; } } public class CSMainMethod : MainMethod { public CSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "CS"; } } public class DSMainMethod : MainMethod { public DSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "DS"; } } public class HSMainMethod : MainMethod { public HSMainMethod(Match m, SymbolTable s) : base(m, s) { - + prefix = "HS"; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index 26d830039c..dbc765a1d0 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -12,16 +12,33 @@ public class ShaderProgram : ShaderToken { public SymbolTable Symbols {get;set;} public string Name {get;set;} - public IEnumerable Generics { get; set; } + public IEnumerable? Generics { get; set; } public IEnumerable Mixins { get; set; } public IEnumerable Body { get; set; } - public ShaderProgram(Match m, SymbolTable symbols) + public ShaderProgram(Match m) { Match = m; - Symbols = symbols; + Symbols = new(); Name = m["ShaderName"].StringValue; - Body = m["Body"].Matches.Select(x => GetToken(x,symbols)).ToList(); + Body = m["Body"].Matches.Select(x => GetToken(x,Symbols)).ToList(); Mixins = m["Mixins"].Matches.Select(x => new MixinToken(x)).ToList(); } + + public ErrorList SemanticChecks() where T : MainMethod + { + var method = Body.OfType().First(); + Symbols.PushStreamType(Body.OfType()); + method.CreateInOutStream(Symbols); + foreach( var s in Body.OfType()) + Symbols.PushType(s.StructName, s.Type); + Symbols.AddScope(); + //method.VariableChecking(Symbols); + method.GenerateIl(Symbols); + Symbols.Pop(); + + + + return Symbols.Errors; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs index 8d2a8fae19..3343cced3b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs @@ -23,7 +23,7 @@ public abstract class ShaderToken public static ShaderToken Tokenize(Match match) { - return GetToken(match,new SymbolTable()); + return GetToken(match,SymbolTable.Empty); } public static ShaderToken GetToken(Match match, SymbolTable symbols) { @@ -34,7 +34,7 @@ public static ShaderToken GetToken(Match match, SymbolTable symbols) return tmp.Name switch { "Namespace" => GetToken(tmp.Matches.Last(),symbols), - "ShaderProgram" => new ShaderProgram(tmp,symbols), + "ShaderProgram" => new ShaderProgram(tmp), "ResourceGroup" => new ResourceGroup(tmp,symbols), "ConstantBuffer" => new ConstantBuffer(tmp,symbols), "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp, symbols), diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs index fe92553cdf..562ad15932 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs @@ -17,14 +17,14 @@ public class UnaryExpression : Expression public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck { public ShaderToken Value { get; set; } - public IEnumerable Field { get; set; } + public List Field { get; set; } public override ISymbolType InferredType { get => inferredType; set => inferredType = value; } public ChainAccessor(Match m, SymbolTable s) { Match = m; Value = GetToken(m.Matches["Identifier"], s); - Field = m.Matches.GetRange(1, m.Matches.Count - 1).Select(x => GetToken(x, s)); + Field = m.Matches.GetRange(1, m.Matches.Count - 1).Select(x => GetToken(x, s)).ToList(); } public IEnumerable GetUsedStream() diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs index a85e53b684..8c90571c47 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs @@ -1,38 +1,56 @@ +using System.Text; + namespace Stride.Shaders.ThreeAddress; -public abstract class Register +public abstract class Register { - public string? Name {get;set;} + public string? Name { get; set; } } public class Copy : Register { - public string Value {get;set;} + public string Value { get; set; } + public bool IsDeclare { get; set; } - public Copy(string v) + public Copy(string v, bool isDeclare = true) { Value = v; + IsDeclare = isDeclare; + } + public override string ToString() + { + return new StringBuilder().Append(Name).Append(' ').Append('=').Append(' ').Append(Value).ToString(); } } public class Assign : Register { - public string A {get;set;} - public string B {get;set;} - public Operator Op {get;set;} + public string A { get; set; } + public string B { get; set; } + public Operator Op { get; set; } public Assign(string a, Operator op, string b) { A = a; Op = op; B = b; - } + } + public override string ToString() + { + return + new StringBuilder() + .Append(Name).Append(' ') + .Append('=').Append(' ') + .Append(A).Append(' ') + .Append(Op).Append(' ') + .Append(B).ToString(); + } } -public abstract class Constant : Register {} -public class Constant : Constant +public abstract class Constant : Register { } +public class Constant : Constant { public T Value; @@ -40,8 +58,24 @@ public Constant(T v) { Value = v; } + + public override bool Equals(object? obj) + { + return obj is Constant constant && + EqualityComparer.Default.Equals(Value, constant.Value); + } + + public override int GetHashCode() + { + return HashCode.Combine(Value); + } + + public override string ToString() + { + return new StringBuilder().Append(Name).Append('=').Append(Value == null ? "" : Value.ToString() ?? string.Empty).ToString(); + } } -public class CompositeConstant : Constant +public class CompositeConstant : Constant { public IEnumerable Values; @@ -49,14 +83,21 @@ public CompositeConstant(IEnumerable v) { Values = v; } + public override string ToString() + { + return new StringBuilder().Append(Name).Append(' ').Append('=').Append(' ').Append(string.Join(",", Values)).ToString(); + } } public class ChainRegister : Register { - public IEnumerable Accessors {get;set;} - public ChainRegister(IEnumerable accessors) + public List Accessors { get; set; } + public ChainRegister(List accessors) { Accessors = accessors; } - + public override string ToString() + { + return new StringBuilder().Append(Name).Append('[').Append(string.Join("][", Accessors)).Append(']').ToString(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs index 2e495a3730..6a84e6e624 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs @@ -1,15 +1,20 @@ +using Stride.Core.Extensions; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.ThreeAddress; +using System.Reflection.Metadata.Ecma335; namespace Stride.Shaders.ThreeAddress; -public partial class Snippet +public partial class TAC { - public IEnumerable LowerToken(ShaderToken token, bool isHead = true) + public List LowerToken(ShaderToken token, bool isHead = true) { - + if (token is Declaration d) symbols.PushVar(d); + else if (token is BlockStatement) symbols.AddScope(); + else if (token is Statement s) symbols.CheckVar(s); return token switch { BlockStatement t => Lower(t), @@ -25,80 +30,120 @@ public IEnumerable LowerToken(ShaderToken token, bool isHead = true) }; } - public IEnumerable Lower(BlockStatement b) + public List Lower(BlockStatement b) { - return b.Statements.SelectMany(x => LowerToken(x)); + return b.Statements.SelectMany(x => LowerToken(x)).ToList(); } - public IEnumerable Lower(ValueMethodCall vm) + public List Lower(ValueMethodCall vm) { - var values = vm.Parameters.SelectMany(x => LowerToken(x)); - return values.Append(new CompositeConstant(values.Select(x => x.Name ?? ""))); + var values = vm.Parameters.SelectMany(x => LowerToken(x)).ToList(); + var r = new CompositeConstant(values.Select(x => x.Name ?? "")); + Add(r); + values.Add(r); + return values; } - public IEnumerable Lower(DeclareAssign d) + public List Lower(DeclareAssign d) { - var value = LowerToken(d.Value); + var value = LowerToken(d.Value).ToList(); var r = new Copy(value.Last().Name){Name = d.VariableName}; Add(r); - return value.Append(r); + value.Add(r); + return value; } - public IEnumerable Lower(AssignChain a) + public List Lower(AssignChain a) { var value = LowerToken(a.Value); - var r = new ChainRegister(a.AccessNames); + ISymbolType tmp = ScalarType.VoidType; + var accessors = new List(a.AccessNames.Count()); + for (int i = 0; i < a.AccessNames.Count(); i++) + { + var current = a.AccessNames.ElementAt(i); + if (i == 0) + symbols.TryGetVarType(current, out tmp); + else + { + if (tmp is CompositeType ct) + accessors.Add(ct.Fields.IndexOfKey(current)); + tmp.TryAccessType(current, out tmp); + } + } + var r = new ChainRegister(accessors); Add(r); - return value.Append(r); + var assign = new Copy(value.Last().Name, false) { Name = r.Name }; + Add(assign); + value.Add(r); + value.Add(assign); + return value; } - public IEnumerable Lower(Operation o) + public List Lower(Operation o) { var left = LowerToken(o.Left); var right = LowerToken(o.Right); var r = new Assign(left.Last().Name, (Operator)o.Op, right.Last().Name); Add(r); - return left.Concat(right).Append(r); + left.AddRange(right); + left.Add(r); + return left; } - public IEnumerable Lower(ChainAccessor ca, bool isHead = true) + public List Lower(ChainAccessor ca, bool isHead = true) { if(!isHead) { - return ca.Field.SelectMany(x => LowerToken(x,false)); + return ca.Field.SelectMany(x => LowerToken(x,false)).ToList(); } else { - var accessors = ca.Field.SelectMany(x => LowerToken(x, false)); - var r = new ChainRegister(Enumerable.Empty()){Accessors = accessors.Select(x => x.Name)}; + var accessors = new List(ca.Field.Count()); + symbols.TryGetVarType(((VariableNameLiteral)ca.Value).Name, out var tmp); + for (int i = 0; i < ca.Field.Count; i++) + { + if (ca.Field[i] is VariableNameLiteral fvn) + { + if (tmp is CompositeType ct) + accessors.Add(ct.Fields.IndexOfKey(fvn.Name)); + tmp.TryAccessType(fvn.Name, out tmp); + } + else throw new Exception(); + } + var r = new ChainRegister(accessors); Add(r); return new List{r}; } } - public IEnumerable Lower(ArrayAccessor aa, bool isHead = true) + public List Lower(ArrayAccessor aa, bool isHead = true) { if(!isHead) { - return aa.Accessors.SelectMany(x => LowerToken(x,false)); + return aa.Accessors.SelectMany(x => LowerToken(x,false)).ToList(); } else { var accessors = aa.Accessors.SelectMany(x => LowerToken(x, false)); - var r = new ChainRegister(Enumerable.Empty()){Accessors = accessors.Select(x => x.Name)}; + var r = new ChainRegister(new()){}; Add(r); return new List{r}; } } - public IEnumerable Lower(ShaderLiteral l) + public List Lower(ShaderLiteral l) { - var result = l switch { - NumberLiteral n => new List{new Constant(n)}, - VariableNameLiteral n => new List{new Constant(n){Name = n.Name}}, - _ => throw new NotImplementedException() - }; - foreach(var e in result) Add(e); - return result; + var result = new List(); + if (l is NumberLiteral n) + { + var c = AddConst(new Constant(n)); + return new List { c }; + } + else if (l is VariableNameLiteral vn) + { + return new List { IntermediateCode[LookUp[vn.Name]] }; + } + else + throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs index 50f0706aab..87219e1c4d 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs @@ -1,17 +1,51 @@ using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; namespace Stride.Shaders.ThreeAddress; -public partial class Snippet +public partial class TAC { + SymbolTable symbols; Dictionary LookUp {get;set;} = new(); List IntermediateCode {get;set;} = new(); - - + HashSet Constants {get;set;} = new(); + + public TAC(SymbolTable symbols) + { + this.symbols = symbols; + } + + public void Add(Register r) { - IntermediateCode.Add(r); - if(r.Name is null) r.Name = $"Stride.T{IntermediateCode.Count}"; + if (r is Copy c && !c.IsDeclare) + IntermediateCode.Add(r); + else + { + r.Name ??= $"%{IntermediateCode.Count}"; + LookUp[r.Name] = IntermediateCode.Count; + IntermediateCode.Add(r); + } + } + public void Add(Assign r) + { + if (r.Name is null) r.Name = $"%{IntermediateCode.Count}"; LookUp[r.Name] = IntermediateCode.Count; + IntermediateCode.Add(r); + } + public Constant AddConst(Constant c) + { + if (Constants.TryGetValue(c, out var result)) + { + return result; + } + else + { + c.Name ??= $"%{IntermediateCode.Count}"; + Constants.Add(c); + LookUp[c.Name] = IntermediateCode.Count; + IntermediateCode.Add(c); + return c; + } } public void Construct(params Statement[] statements) { @@ -19,7 +53,7 @@ public void Construct(params Statement[] statements) } public void Construct(IEnumerable statements) { - foreach(var s in statements) + foreach (var s in statements) { LowerToken(s); } From 2943d1563db8f05983f15cb5c49eba9223c2f47f Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 2 Oct 2022 23:30:12 +0200 Subject: [PATCH 0157/1182] Avoid duplicate of IL --- .../SDSL/MixinSamples/SingleShader.sdsl | 2 +- src/Stride.Shaders/Parsers/AST/Shader/Statements.cs | 4 ++-- src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs | 11 +++++++++++ .../Parsers/ThreeAddress/Snippet.Lowering.cs | 6 +++--- src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs | 8 ++++++-- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index aedeee7e01..c7cff8afe0 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -35,6 +35,6 @@ shader SingleShader { { float4 a = float4(0); streams.ShadingPosition = a; - streams.Depth = streams.ShadingPosition.x; + streams.ColorTarget = streams.ShadingPosition; } }; \ No newline at end of file diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs index 8e9380a127..587e39dee1 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs @@ -101,13 +101,13 @@ public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck public AssignOpToken AssignOp { get; set; } public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; - public IEnumerable AccessNames { get; set; } + public List AccessNames { get; set; } public ShaderTokenTyped Value { get; set; } public AssignChain(Match m, SymbolTable s) { Match = m; AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue); + AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue).ToList(); Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"], s); } diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs index 8c90571c47..3b8eab622b 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs @@ -8,6 +8,17 @@ public abstract class Register public string? Name { get; set; } } +public class Declare : Register +{ + + public Declare(){} + + public override string ToString() + { + return new StringBuilder().Append(Name).ToString(); + } +} + public class Copy : Register { diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs index 6a84e6e624..13643ab63a 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs @@ -69,9 +69,9 @@ public List Lower(AssignChain a) tmp.TryAccessType(current, out tmp); } } - var r = new ChainRegister(accessors); + var r = new ChainRegister(accessors) { Name = string.Join(".",a.AccessNames) }; Add(r); - var assign = new Copy(value.Last().Name, false) { Name = r.Name }; + var assign = new Copy(value[^1].Name, false) { Name = r.Name }; Add(assign); value.Add(r); value.Add(assign); @@ -110,7 +110,7 @@ public List Lower(ChainAccessor ca, bool isHead = true) } else throw new Exception(); } - var r = new ChainRegister(accessors); + var r = new ChainRegister(accessors) { Name = string.Join(".", Enumerable.Empty().Append(ca.Value).Concat(ca.Field).Cast().Select(x => x.Name)) }; Add(r); return new List{r}; } diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs index 87219e1c4d..8fefa4f61f 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs +++ b/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs @@ -22,8 +22,12 @@ public void Add(Register r) else { r.Name ??= $"%{IntermediateCode.Count}"; - LookUp[r.Name] = IntermediateCode.Count; - IntermediateCode.Add(r); + if (!LookUp.ContainsKey(r.Name)) + { + LookUp[r.Name] = IntermediateCode.Count; + IntermediateCode.Add(r); + } + } } public void Add(Assign r) From 9e50c2923a76547ff0a1f96d75324a493039614c Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 3 Oct 2022 19:06:03 +0200 Subject: [PATCH 0158/1182] different struct management --- src/SDSLParserExample/Program.cs | 4 +- src/SDSLParserExample/shader.spv | Bin 0 -> 1536 bytes .../Emitter/SpirvEmitter.MainMethod.cs | 25 +++--- .../Compiler/Emitter/SpirvEmitter.Streams.cs | 31 ++----- .../Compiler/Emitter/SpirvEmitter.Structs.cs | 33 +++++++- .../Compiler/Emitter/SpirvEmitter.Types.cs | 2 +- .../Compiler/Emitter/SpirvEmitter.cs | 35 ++++++-- .../Compiler/Emitter/SpvStruct.cs | 10 ++- .../Compiler/Emitter/StreamStructs.cs | 78 ------------------ .../Compiler/Emitter/spv-semantics.dis | 70 ++++++++++++++++ .../Compiler/Mixer/SimpleMixer.cs | 3 +- .../AST/Shader/Analysis/SymbolTable.cs | 3 + .../Parsers/AST/Shader/Analysis/SymbolType.cs | 8 +- .../Parsers/AST/Shader/ShaderMethods.cs | 6 +- .../Parsers/AST/Shader/ShaderProgram.cs | 6 +- 15 files changed, 180 insertions(+), 134 deletions(-) create mode 100644 src/SDSLParserExample/shader.spv delete mode 100644 src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs create mode 100644 src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 340140f01d..2ab3b52dfd 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -14,7 +14,7 @@ using Stride.Shaders; using Stride.Shaders.Parsing.AST.Shader.Analysis; -Directory.SetCurrentDirectory("../../../"); +// Directory.SetCurrentDirectory("../../../"); var shaderf = File.ReadAllText("./SDSL/shader2.sdsl"); @@ -31,7 +31,7 @@ static void LoadShaders() var errors = mixer.SemanticChecks(); var module = mixer.EmitSpirv(EntryPoints.VSMain); - var main = mixer.program.Body.OfType().First(); + File.WriteAllBytes("./shader.spv",module.Generate()); var x = 0; } diff --git a/src/SDSLParserExample/shader.spv b/src/SDSLParserExample/shader.spv new file mode 100644 index 0000000000000000000000000000000000000000..7805c372aa9de99770b0cbf38b4b3dcf6b885791 GIT binary patch literal 1536 zcmdT^+e*Vg5FJ}%y;rH1w^H#7ybC^wttFsFO!YN{8f_pXnry-P<-Q1>vuW(A#Rn0@ zgw5>CnVHOOw_Mt+h&3U6R`ge7SxQ35tW1l0dE>Pmr+wD)Zi8-;`YP};m4@*>@fj2E zMOozC_2aGzlh}_!HP{kal=9H4NL4C&zl`sVd+vv^$O86@SQg$A=w*_Hw8vJaWKzqx ze=>N+HZXYFJ!4tWp8|C|SFPi7+VjnylO#&gj-TEK3bKlp(~luXw6w`F`ZTa@6JtgO zwqs(GAF*8%vp!;bCdN1opZg}psu|cpj#)Z~X)w*;LG?h3*k=k^I}OmUG}q7bnk}%i zAj?{heLou2X%3hjXUdPef!!R*=PA!l(em8jk4}0hK{96ped)tbdv!@snJAUXZ zY|$G=$G&@cdp!Gsa!T{5`09%`%x`4lTz9lhE~mXw7wwDs?Ca;a+CV8UuVKa<*Y4Pk z{{K(p?Eg4F|3&^=b>OUzs{`kJocu59vxfVJ`8KfX!#jq2vDR^CFfQ`UXBA)41{R+c z+(68yj$4suROj#wE&LY#bS;MZby#!O>7$Ona8?U{4e&g-w4)Aro>k)1I~w9VbJQVE joac->HN;s3-2k@)%KbhfC*^(1hw>Nb)j(h2 x is VSMainMethod)).Statements) - { - - } + AddLabel(Label()); + // foreach(var s in ((VSMainMethod)p.Body.First(x => x is VSMainMethod)).Statements) + // { + + // } + Return(); + FunctionEnd(); + AddEntryPoint(ExecutionModel.Vertex, func, "VSMain", input,output); + + // AddExecutionMode(func, ExecutionMode.OriginLowerLeft); } public void PSMethod(ShaderProgram p) { - + } public void GSMethod(ShaderProgram p) { - + } public void CSMethod(ShaderProgram p) { - + } public void HSMethod(ShaderProgram p) { - + } public void DSMethod(ShaderProgram p) { - + } } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs index 9ad73d31df..2be753a800 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -1,6 +1,7 @@ using Spv.Generator; using Stride.Shaders.Mixer; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using static Spv.Specification; namespace Stride.Shaders.Spirv; @@ -8,8 +9,6 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter { public Stream Stream { get; set; } - public StreamIn StreamIn { get; set; } - public StreamOut StreamOut { get; set; } public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) @@ -24,31 +23,13 @@ public void CreateStreamStructs(ShaderProgram program, EntryPoints entry) EntryPoints.HSMain => (MainMethod)program.Body.First(x => x is HSMainMethod), _ => throw new NotImplementedException() }; + var structs = program.Symbols.GetAllStructTypes(); + program.Symbols.TryGetType("STREAM", out var streamType); + //var fields = ((CompositeType)streamType).Fields.Select(x => x.Field) + var x = 0; - // var variables = - // program.Body - // .Where(x => x is ShaderVariableDeclaration svd && svd.IsStream) - // .Cast() - // .Select(x => (x.Name, SpvType: AsSpvType(x.Type))) - // .ToList(); - - // var likelyInputs = mainMethod.GetStreamValuesUsed(); - // IEnumerable<(string,Instruction)> inVars = variables.Where(x => likelyInputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; - - // var likelyOutputs = mainMethod.GetStreamValuesAssigned(); - // IEnumerable<(string,Instruction)> outVars = variables.Where(x => likelyOutputs.Contains(x.Name)) as IEnumerable<(string,Instruction)>; - - // Stream = new Stream(entry, this, variables as IEnumerable<(string,Instruction)>); - // StreamIn = new(entry, this, inVars); - // StreamOut = new StreamOut(entry, this, outVars); - - // // in-out - - // var streamInPtr = TypePointer(StorageClass.Input , StreamIn.SpvType); - // var streamOutPtr = TypePointer(StorageClass.Output , StreamOut.SpvType); - // Variables[StreamIn.Name] = Variable(streamInPtr, StorageClass.Input); - // Variables[StreamOut.Name] = Variable(streamOutPtr, StorageClass.Output); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs index f115430199..e0ed13bb64 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs @@ -5,14 +5,45 @@ using System.Threading.Tasks; using Spv.Generator; using Stride.Shaders.Parsing.AST.Shader; +using Stride.Shaders.Parsing.AST.Shader.Analysis; using static Spv.Specification; namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { + + Instruction GetSpvType(ISymbolType t) + { + return t switch + { + ScalarType s => AsSpvType(s.ToString()), + VectorType s => AsSpvType(s.ToString()), + MatrixType s => AsSpvType(s.ToString()), + CompositeType c => ShaderTypes[c.Name].SpvType, + _ => throw new NotImplementedException() + }; + } void CreateStructs(ShaderProgram program) { - // program.Body.Where(x => x is ShaderStr) + foreach (var s in program.Symbols.GetAllStructTypes().Cast()) + { + var fields = s.Fields.Values.Select(x => GetSpvType(x)).ToArray(); + foreach(var f in fields) + Decorate(f,Decoration.HlslSemanticGOOGLE,new LiteralString("POSITION")); + ShaderTypes[s.Name] = + new SpvStruct( + TypeStruct( + true, + fields + ), + s + ); + Name(ShaderTypes[s.Name].SpvType,s.Name); + for (int i = 0; i < s.Fields.Count; i++) + { + MemberName(ShaderTypes[s.Name].SpvType,i,s.Fields.Keys[i]); + } + } } } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs index 121b10098d..01e5fed18b 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs @@ -13,7 +13,7 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { - public Instruction? AsSpvType(string n) + public Instruction AsSpvType(string n) { var match = NativeTypeGrammar.ParseNativeType(n); if (!match.HasMatches) return TryGetUserDefined(n); diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index e792628b30..2e06237b8d 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -12,6 +12,9 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { + private Instruction input; + private Instruction output; + public Dictionary ShaderTypes {get;set;} public Dictionary ShaderFunctionTypes {get;set;} public Dictionary Variables {get;set;} = new(); @@ -28,6 +31,8 @@ public void Initialize(EntryPoints entry) _ => Capability.Shader, }; AddCapability(capability); + AddExtension("SPV_GOOGLE_decorate_string"); + AddExtension("SPV_GOOGLE_hlsl_functionality1"); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); } @@ -36,11 +41,31 @@ public void Construct(ShaderProgram program, EntryPoints entry) Initialize(entry); // Create all user defined types - - // Create stream types - - CreateStreamStructs(program, entry); - + CreateStructs(program); + // Create stream in out + // foreach(var f in ShaderTypes["VS_STREAM_IN"].Definition.Fields) + // { + // var ptr = TypePointer(StorageClass.Input, GetSpvType(f.Value)); + // var v = Variable(ptr,StorageClass.Input); + // Name(v,f.Key); + // input.Add(v); + // AddGlobalVariable(v); + // Decorate(v,Decoration.HlslSemanticGOOGLE, new LiteralString("POSITION")); + // } + // foreach(var f in ShaderTypes["VS_STREAM_OUT"].Definition.Fields) + // { + // var ptr = TypePointer(StorageClass.Output, GetSpvType(f.Value)); + // var v = Variable(ptr,StorageClass.Output); + // Name(v,f.Key); + // input.Add(v); + // AddGlobalVariable(v); + // } + var pInput = TypePointer(StorageClass.Input,ShaderTypes["VS_STREAM_IN"].SpvType); + var pOutput = TypePointer(StorageClass.Output,ShaderTypes["VS_STREAM_OUT"].SpvType); + input = Variable(pInput,StorageClass.Input); + output = Variable(pOutput,StorageClass.Output); + AddGlobalVariable(input); + AddGlobalVariable(output); // Generate methods() diff --git a/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs b/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs index 190d6f8a91..7c670524ea 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs @@ -1,11 +1,19 @@ using Spv.Generator; using Stride.Shaders.Mixer; +using Stride.Shaders.Parsing.AST.Shader.Analysis; namespace Stride.Shaders.Spirv; -public abstract class SpvStruct +public class SpvStruct { public Instruction SpvType {get;set;} + public CompositeType Definition {get;set;} + + public SpvStruct(Instruction spvType, CompositeType definition) + { + SpvType = spvType; + Definition = definition; + } } diff --git a/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs b/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs deleted file mode 100644 index 7bb542ded9..0000000000 --- a/src/Stride.Shaders/Compiler/Emitter/StreamStructs.cs +++ /dev/null @@ -1,78 +0,0 @@ -using Spv.Generator; -using Stride.Shaders.Mixer; - -namespace Stride.Shaders.Spirv; - -public abstract class StreamStruct : SpvStruct -{ - public string Name {get; protected set;} - public Dictionary NameToPosition {get;set;} = new(); - public StreamStruct(Module m, IEnumerable<(string,Instruction)> fields) - { - for (int i = 0; i < fields.Count(); i++) - { - NameToPosition[fields.ElementAt(i).Item1] = i; - } - SpvType = m.TypeStruct(false, fields.Select(x => x.Item2).ToArray()); - for (int i = 0; i < fields.Count(); i++) - { - m.MemberName(SpvType,i,fields.ElementAt(i).Item1); - } - } -} - -public class Stream : StreamStruct -{ - - public Stream(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) - { - Name = entry switch - { - EntryPoints.VSMain => "VS_STREAMS", - EntryPoints.PSMain => "PS_STREAMS", - EntryPoints.GSMain => "GS_STREAMS", - EntryPoints.CSMain => "CS_STREAMS", - EntryPoints.HSMain => "HS_STREAMS", - EntryPoints.DSMain => "DS_STREAMS", - _ => throw new NotImplementedException() - }; - m.Name(SpvType, Name); - } -} - -public class StreamIn : StreamStruct -{ - - public StreamIn(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) - { - Name = entry switch - { - EntryPoints.VSMain => "VS_STREAMS_IN", - EntryPoints.PSMain => "PS_STREAMS_IN", - EntryPoints.GSMain => "GS_STREAMS_IN", - EntryPoints.CSMain => "CS_STREAMS_IN", - EntryPoints.HSMain => "HS_STREAMS_IN", - EntryPoints.DSMain => "DS_STREAMS_IN", - _ => throw new NotImplementedException() - }; - m.Name(SpvType, Name); - } -} -public class StreamOut : StreamStruct -{ - - public StreamOut(EntryPoints entry, Module m, IEnumerable<(string,Instruction)> fields) : base(m,fields) - { - Name = entry switch - { - EntryPoints.VSMain => "VS_STREAMS_OUT", - EntryPoints.PSMain => "PS_STREAMS_OUT", - EntryPoints.GSMain => "GS_STREAMS_OUT", - EntryPoints.CSMain => "CS_STREAMS_OUT", - EntryPoints.HSMain => "HS_STREAMS_OUT", - EntryPoints.DSMain => "DS_STREAMS_OUT", - _ => throw new NotImplementedException() - }; - m.Name(SpvType, Name); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis b/src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis new file mode 100644 index 0000000000..f107e74f90 --- /dev/null +++ b/src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis @@ -0,0 +1,70 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 10 +; Bound: 79 +; Schema: 0 + OpCapability Shader + OpExtension "SPV_GOOGLE_hlsl_functionality1" + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Vertex %VSMain "VSMain" %vPosition %_entryPointOutput_Pos %_entryPointOutput_Pshade + OpSource HLSL 500 + OpName %VSMain "VSMain" + OpName %_Global "$Global" + OpMemberName %_Global 0 "view_proj_matrix" + OpMemberName %_Global 1 "texture_matrix0" + OpName %_ "" + OpName %vPosition "vPosition" + OpName %_entryPointOutput_Pos "@entryPointOutput.Pos" + OpName %_entryPointOutput_Pshade "@entryPointOutput.Pshade" + OpMemberDecorate %_Global 0 RowMajor + OpMemberDecorate %_Global 0 Offset 0 + OpMemberDecorate %_Global 0 MatrixStride 16 + OpMemberDecorate %_Global 1 RowMajor + OpMemberDecorate %_Global 1 Offset 64 + OpMemberDecorate %_Global 1 MatrixStride 16 + OpDecorate %_Global Block + OpDecorate %_ DescriptorSet 0 + OpDecorate %_ Binding 0 + OpDecorate %vPosition Location 0 + OpDecorateString %vPosition UserSemantic "POSITION" + OpDecorate %_entryPointOutput_Pos Location 0 + OpDecorateString %_entryPointOutput_Pos UserSemantic "POSITION" + OpDecorate %_entryPointOutput_Pshade Location 1 + OpDecorateString %_entryPointOutput_Pshade UserSemantic "TEXCOORD0" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 + %v3float = OpTypeVector %float 3 + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%mat4v4float = OpTypeMatrix %v4float 4 + %_Global = OpTypeStruct %mat4v4float %mat4v4float +%_ptr_Uniform__Global = OpTypePointer Uniform %_Global + %_ = OpVariable %_ptr_Uniform__Global Uniform +%_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float + %int_1 = OpConstant %int 1 +%_ptr_Input_v4float = OpTypePointer Input %v4float + %vPosition = OpVariable %_ptr_Input_v4float Input +%_ptr_Output_v4float = OpTypePointer Output %v4float +%_entryPointOutput_Pos = OpVariable %_ptr_Output_v4float Output +%_ptr_Output_v3float = OpTypePointer Output %v3float +%_entryPointOutput_Pshade = OpVariable %_ptr_Output_v3float Output + %VSMain = OpFunction %void None %3 + %5 = OpLabel + %50 = OpLoad %v4float %vPosition + %67 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_0 + %68 = OpLoad %mat4v4float %67 + %69 = OpVectorTimesMatrix %v4float %50 %68 + %72 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_1 + %73 = OpLoad %mat4v4float %72 + %74 = OpVectorTimesMatrix %v4float %50 %73 + %75 = OpCompositeExtract %float %74 0 + %76 = OpCompositeExtract %float %74 1 + %77 = OpCompositeExtract %float %74 2 + %78 = OpCompositeConstruct %v3float %75 %76 %77 + OpStore %_entryPointOutput_Pos %69 + OpStore %_entryPointOutput_Pshade %78 + OpReturn + OpFunctionEnd \ No newline at end of file diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs index ba5a33f2f9..373c9a5cba 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs @@ -1,3 +1,4 @@ +using Spv; using Spv.Generator; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.AST.Shader; @@ -25,7 +26,7 @@ public ErrorList SemanticChecks() where T : MainMethod } public Module EmitSpirv(EntryPoints entry) { - var spirv = new SpirvEmitter(455); + var spirv = new SpirvEmitter(Specification.Version); spirv.Construct(program,entry); return spirv; } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index ac240c5d34..36f5e79ddc 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -20,6 +20,9 @@ public SymbolTable() public void AddError(Eto.Parse.Match match, string title) => Errors.Add(new(match, title)); + public IEnumerable GetAllStructTypes() => this.SelectMany(x => x.Select(y => y.Value).OfType()); + + public void PushVar(Declaration a) { foreach (var d in this) diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index 631127166e..ef2bd2ac53 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -96,7 +96,7 @@ public override string ToString() public class VectorType : ISymbolType { public int Size { get; set; } - public ISymbolType TypeName { get; set; } + public ScalarType TypeName { get; set; } static string swizzleX = "xyzw"; static string swizzleR = "rgba"; @@ -105,14 +105,14 @@ public VectorType(string size, ISymbolType type) if (int.TryParse(size, out var s)) { Size = s; - TypeName = type; + TypeName = (ScalarType)type; } else throw new NotImplementedException(); } public VectorType(int size, ISymbolType type) { Size = size; - TypeName = type; + TypeName = (ScalarType)type; } public bool IsAccessorValid(string accessor) @@ -155,7 +155,7 @@ public class MatrixType : ISymbolType { public int SizeX { get; set; } public int SizeY { get; set; } - public ISymbolType TypeName { get; set; } + public ScalarType TypeName { get; set; } static readonly Grammar accessorGrammar = new( Terminals.Literal("_") diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs index e10b3a049a..7cd4a0c4bf 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs @@ -47,12 +47,12 @@ public static ShaderMethod Create(Match m, SymbolTable s) public abstract class MainMethod : ShaderMethod, IStreamCheck { protected string prefix; - protected TAC snippet; + public TAC IL { get; set; } public MainMethod(Match m, SymbolTable s) : base(m, s) { prefix = "NONE"; - snippet = new(s); + IL = new(s); } public bool CheckStream(SymbolTable s) @@ -96,7 +96,7 @@ internal void GenerateIl(SymbolTable symbols) symbols.PushVar("streams", "STREAM"); symbols.PushVar("streams_in", prefix + "_STREAM_IN"); symbols.PushVar("streams_out", prefix + "_STREAM_OUT"); - snippet.Construct(Statements); + IL.Construct(Statements); } } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs index dbc765a1d0..0ec2ab76c1 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs @@ -28,10 +28,10 @@ public ShaderProgram(Match m) public ErrorList SemanticChecks() where T : MainMethod { var method = Body.OfType().First(); - Symbols.PushStreamType(Body.OfType()); - method.CreateInOutStream(Symbols); - foreach( var s in Body.OfType()) + foreach (var s in Body.OfType()) Symbols.PushType(s.StructName, s.Type); + Symbols.PushStreamType(Body.OfType()); + method.CreateInOutStream(Symbols); Symbols.AddScope(); //method.VariableChecking(Symbols); method.GenerateIl(Symbols); From 3b2d31caa9683fe1d2552374007f67b0f2b5056b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 4 Oct 2022 15:33:11 +0200 Subject: [PATCH 0159/1182] retest --- src/SDSLParserExample/Program.cs | 205 ++++++++++++++++-- .../SDSL/MixinSamples}/spv-semantics.dis | 0 .../SDSLParserExample.csproj | 2 + src/SDSLParserExample/TestModule.cs | 68 ++++++ src/SDSLParserExample/shader.spv | Bin 1536 -> 980 bytes .../Compiler/Emitter/SpirvEmitter.Structs.cs | 34 ++- .../Compiler/Emitter/SpirvEmitter.cs | 4 +- .../AST/Shader/Analysis/SymbolTable.cs | 2 +- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 10 +- .../Parsers/AST/Shader/ShaderElements.cs | 2 +- 10 files changed, 297 insertions(+), 30 deletions(-) rename src/{Stride.Shaders/Compiler/Emitter => SDSLParserExample/SDSL/MixinSamples}/spv-semantics.dis (100%) create mode 100644 src/SDSLParserExample/TestModule.cs diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 2ab3b52dfd..5f5d2f544d 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -13,6 +13,10 @@ using Stride.Shaders.ThreeAddress; using Stride.Shaders; using Stride.Shaders.Parsing.AST.Shader.Analysis; +using System.Text; +using SPIRVCross; +using static SPIRVCross.SPIRV; +using SDSLParserExample; // Directory.SetCurrentDirectory("../../../"); @@ -20,45 +24,211 @@ // ShaderCompiling(shaderf); // ThreeAddress(); -LoadShaders(); +// LoadShaders(); +TestModuleCreation(); + +static void TestModuleCreation() +{ + var module = new TestModule(); + module.Construct(); + var code = module.Generate(); + ToGlsl(code); + ToHlsl(code); +} static void LoadShaders() { var manager = new ShaderSourceManager(); manager.AddDirectory("./SDSL/MixinSamples"); - var mixer = new SimpleMixer("SingleShader",manager); + var mixer = new SimpleMixer("SingleShader", manager); var errors = mixer.SemanticChecks(); - + var module = mixer.EmitSpirv(EntryPoints.VSMain); - File.WriteAllBytes("./shader.spv",module.Generate()); + var bytes = module.Generate(); + File.WriteAllBytes("./shader.spv", bytes); + ToGlsl(bytes); var x = 0; } +static void ToGlsl(byte[] bytecode) +{ + unsafe + { + string GetString(byte* ptr) + { + int length = 0; + while (length < 4096 && ptr[length] != 0) + length++; + // Decode UTF-8 bytes to string. + return Encoding.UTF8.GetString(ptr, length); + } + + SpvId* spirv; + + fixed (byte* ptr = bytecode) + spirv = (SpvId*)ptr; + + uint word_count = (uint)bytecode.Length / 4; + + spvc_context context = default; + spvc_parsed_ir ir; + spvc_compiler compiler_glsl; + spvc_compiler_options options; + spvc_resources resources; + spvc_reflected_resource* list = default; + nuint count = default; + spvc_error_callback error_callback = default; + + // Create context. + if(spvc_context_create(&context) != spvc_result.SPVC_SUCCESS) throw new Exception(); + + // Set debug callback. + spvc_context_set_error_callback(context, error_callback, null); + + // Parse the SPIR-V. + if(spvc_context_parse_spirv(context, spirv, word_count, &ir) != spvc_result.SPVC_SUCCESS) + throw new Exception(); + + // Hand it off to a compiler instance and give it ownership of the IR. + + if(spvc_context_create_compiler(context, spvc_backend.Glsl, ir, spvc_capture_mode.TakeOwnership, &compiler_glsl) != spvc_result.SPVC_SUCCESS) + throw new Exception(); + // Do some basic reflection. + + if(spvc_compiler_create_shader_resources(compiler_glsl, &resources) != spvc_result.SPVC_SUCCESS) + throw new Exception(); + if(spvc_resources_get_resource_list_for_type(resources, spvc_resource_type.UniformBuffer, (spvc_reflected_resource*)&list, &count) != spvc_result.SPVC_SUCCESS) + throw new Exception(); + + for (uint i = 0; i < count; i++) + { + Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", list[i].id, list[i].base_type_id, list[i].type_id, GetString(list[i].name)); + + uint set = spvc_compiler_get_decoration(compiler_glsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationDescriptorSet); + Console.WriteLine($"Set: {set}"); + + uint binding = spvc_compiler_get_decoration(compiler_glsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationBinding); + Console.WriteLine($"Binding: {binding}"); + + Console.WriteLine("========="); + } + Console.WriteLine("\n \n"); + + // Modify options. + if(spvc_compiler_create_compiler_options(compiler_glsl, &options) !=spvc_result.SPVC_SUCCESS) throw new Exception(); + if(spvc_compiler_options_set_uint(options, spvc_compiler_option.GlslVersion, 450) !=spvc_result.SPVC_SUCCESS) throw new Exception(); + if(spvc_compiler_options_set_bool(options, spvc_compiler_option.GlslEs, false) !=spvc_result.SPVC_SUCCESS) throw new Exception(); + if(spvc_compiler_install_compiler_options(compiler_glsl, options) !=spvc_result.SPVC_SUCCESS) throw new Exception(); + + byte* result = default; + var res = spvc_compiler_compile(compiler_glsl, (byte*)&result); + if(res != spvc_result.SPVC_SUCCESS) throw new Exception(res.ToString()); + Console.WriteLine("Cross-compiled source: \n{0}", GetString(result)); + + // Frees all memory we allocated so far. + spvc_context_destroy(context); + } +} + + +static void ToHlsl(byte[] bytecode) +{ + unsafe + { + string GetString(byte* ptr) + { + int length = 0; + while (length < 4096 && ptr[length] != 0) + length++; + // Decode UTF-8 bytes to string. + return Encoding.UTF8.GetString(ptr, length); + } + + SpvId* spirv; + + fixed (byte* ptr = bytecode) + spirv = (SpvId*)ptr; + + uint word_count = (uint)bytecode.Length / 4; + + spvc_context context = default; + spvc_parsed_ir ir; + spvc_compiler compiler_hlsl; + spvc_compiler_options options; + spvc_resources resources; + spvc_reflected_resource* list = default; + nuint count = default; + spvc_error_callback error_callback = default; + + // Create context. + spvc_context_create(&context); + + // Set debug callback. + spvc_context_set_error_callback(context, error_callback, null); + + // Parse the SPIR-V. + spvc_context_parse_spirv(context, spirv, word_count, &ir); + + // Hand it off to a compiler instance and give it ownership of the IR. + spvc_context_create_compiler(context, spvc_backend.Hlsl, ir, spvc_capture_mode.TakeOwnership, &compiler_hlsl); + + // Do some basic reflection. + spvc_compiler_create_shader_resources(compiler_hlsl, &resources); + spvc_resources_get_resource_list_for_type(resources, spvc_resource_type.UniformBuffer, (spvc_reflected_resource*)&list, &count); + + for (uint i = 0; i < count; i++) + { + Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", list[i].id, list[i].base_type_id, list[i].type_id, GetString(list[i].name)); + + uint set = spvc_compiler_get_decoration(compiler_hlsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationDescriptorSet); + Console.WriteLine($"Set: {set}"); + + uint binding = spvc_compiler_get_decoration(compiler_hlsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationBinding); + Console.WriteLine($"Binding: {binding}"); + + Console.WriteLine("========="); + } + Console.WriteLine("\n \n"); + + // Modify options. + spvc_compiler_create_compiler_options(compiler_hlsl, &options); + spvc_compiler_options_set_uint(options, spvc_compiler_option.HlslShaderModel, 50); + spvc_compiler_install_compiler_options(compiler_hlsl, options); + + byte* result = default; + spvc_compiler_compile(compiler_hlsl, (byte*)&result); + Console.WriteLine("Cross-compiled source: \n{0}", GetString(result)); + + // Frees all memory we allocated so far. + spvc_context_destroy(context); + } +} + static void ThreeAddress() { - - var o = + + var o = new Operation { - Left = new NumberLiteral{Value = 5L}, - Right = new NumberLiteral{Value = 6L}, + Left = new NumberLiteral { Value = 5L }, + Right = new NumberLiteral { Value = 6L }, Op = OperatorToken.Plus }; - + var symbols = new SymbolTable(); - var s = new DeclareAssign(){TypeName = new ScalarType("float"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o}; + var s = new DeclareAssign() { TypeName = new ScalarType("float"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; symbols.PushVar(s); - var o2 = + var o2 = new Operation { Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral{Value = 6L, InferredType = new ScalarType("float")}, + Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("float") }, Op = OperatorToken.Plus }; - var s2 = new DeclareAssign(){VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2}; + var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; symbols.PushVar(s2); - + var snip = new TAC(symbols); snip.Construct(s); var x = 0; @@ -66,7 +236,8 @@ static void ThreeAddress() -static void ShaderCompiling(string shaderf){ +static void ShaderCompiling(string shaderf) +{ var child = File.ReadAllText("./SDSL/InheritExample/Child.sdsl"); var parent = File.ReadAllText("./SDSL/InheritExample/Parent.sdsl"); @@ -95,9 +266,9 @@ static void ShaderCompiling(string shaderf){ var grammar = ShaderParser.GetGrammar(); var p = ShaderParser.GetParser(); - p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); + p.PreProcessAndParse(shaderf, "./SDSL/shader2.sdsl"); s.Start(); - var result = p.PreProcessAndParse(shaderf,"./SDSL/shader2.sdsl"); + var result = p.PreProcessAndParse(shaderf, "./SDSL/shader2.sdsl"); s.Stop(); Console.WriteLine($"irony parsing time : {s.Elapsed}"); } diff --git a/src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis b/src/SDSLParserExample/SDSL/MixinSamples/spv-semantics.dis similarity index 100% rename from src/Stride.Shaders/Compiler/Emitter/spv-semantics.dis rename to src/SDSLParserExample/SDSL/MixinSamples/spv-semantics.dis diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj index b14a54141e..8fabdc3f4b 100644 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -6,6 +6,7 @@ + @@ -17,5 +18,6 @@ net6.0 enable enable + true diff --git a/src/SDSLParserExample/TestModule.cs b/src/SDSLParserExample/TestModule.cs new file mode 100644 index 0000000000..08d4afd845 --- /dev/null +++ b/src/SDSLParserExample/TestModule.cs @@ -0,0 +1,68 @@ +using Spv; +using Spv.Generator; +using static Spv.Specification; + +namespace SDSLParserExample; + +public class TestModule : Module +{ + public TestModule() : base(Specification.Version) { } + + public void Construct() + { + AddCapability(Capability.Shader); + SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); + + Instruction floatType = TypeFloat(32); + Instruction floatInputType = TypePointer(StorageClass.Input, floatType); + Instruction floatOutputType = TypePointer(StorageClass.Output, floatType); + Instruction vec3Type = TypeVector(floatType, 3); + Instruction vec4Type = TypeVector(floatType, 4); + Instruction vec4InputPtrType = TypePointer(StorageClass.Input, vec4Type); + Instruction vec3OutputPtrType = TypePointer(StorageClass.Output, vec3Type); + Instruction vec4OutputPtrType = TypePointer(StorageClass.Output, vec4Type); + Instruction vec4PositionPtrType = TypePointer(StorageClass.Output, vec4Type); + + Instruction inputPos = Variable(vec4InputPtrType, StorageClass.Input); + // Decorate(inputPos, Decoration.Aliased, (LiteralInteger)0); + // Instruction inputTest = Variable(floatInputType, StorageClass.Input); + Instruction sv_pos = Variable(vec4PositionPtrType, StorageClass.Output); + Decorate(sv_pos, Decoration.RelaxedPrecision); + Decorate(sv_pos, Decoration.BuiltIn, (LiteralInteger)0); + + Instruction outputColor = Variable(vec4OutputPtrType, StorageClass.Output); + + Name(inputPos, "pos"); + Name(sv_pos, "svpos"); + Name(outputColor, "outputColor"); + AddGlobalVariable(inputPos); + AddGlobalVariable(sv_pos); + AddGlobalVariable(outputColor); + + Instruction rColor = Constant(floatType, 0.5f); + Instruction gColor = Constant(floatType, 0.0f); + Instruction bColor = Constant(floatType, 0.0f); + Instruction aColor = Constant(floatType, 1.0f); + + Instruction compositeColor = ConstantComposite(vec4Type, rColor, gColor, bColor, aColor); + + Instruction voidType = TypeVoid(); + + Instruction mainFunctionType = TypeFunction(voidType, true); + Instruction mainFunction = Function(voidType, FunctionControlMask.MaskNone, mainFunctionType); + AddLabel(Label()); + + Instruction tempInput = Load(vec4Type, inputPos); + + Instruction resultSqrt = GlslSqrt(floatType, tempInput); + + Store(sv_pos, resultSqrt); + Store(outputColor, compositeColor); + + Return(); + FunctionEnd(); + + AddEntryPoint(ExecutionModel.Vertex, mainFunction, "main", inputPos, sv_pos, outputColor); + // AddExecutionMode(mainFunction, ExecutionMode.OriginLowerLeft); + } +} \ No newline at end of file diff --git a/src/SDSLParserExample/shader.spv b/src/SDSLParserExample/shader.spv index 7805c372aa9de99770b0cbf38b4b3dcf6b885791..6744c907c53da62a1bff49e14278170a46f76bb2 100644 GIT binary patch delta 27 hcmZqRxxzj{W@ADZ6E_P3BLf2iHxP?$zRRM_2moC#1)2Z= literal 1536 zcmdT^+e*Vg5FJ}%y;rH1w^H#7ybC^wttFsFO!YN{8f_pXnry-P<-Q1>vuW(A#Rn0@ zgw5>CnVHOOw_Mt+h&3U6R`ge7SxQ35tW1l0dE>Pmr+wD)Zi8-;`YP};m4@*>@fj2E zMOozC_2aGzlh}_!HP{kal=9H4NL4C&zl`sVd+vv^$O86@SQg$A=w*_Hw8vJaWKzqx ze=>N+HZXYFJ!4tWp8|C|SFPi7+VjnylO#&gj-TEK3bKlp(~luXw6w`F`ZTa@6JtgO zwqs(GAF*8%vp!;bCdN1opZg}psu|cpj#)Z~X)w*;LG?h3*k=k^I}OmUG}q7bnk}%i zAj?{heLou2X%3hjXUdPef!!R*=PA!l(em8jk4}0hK{96ped)tbdv!@snJAUXZ zY|$G=$G&@cdp!Gsa!T{5`09%`%x`4lTz9lhE~mXw7wwDs?Ca;a+CV8UuVKa<*Y4Pk z{{K(p?Eg4F|3&^=b>OUzs{`kJocu59vxfVJ`8KfX!#jq2vDR^CFfQ`UXBA)41{R+c z+(68yj$4suROj#wE&LY#bS;MZby#!O>7$Ona8?U{4e&g-w4)Aro>k)1I~w9VbJQVE joac->HN;s3-2k@)%KbhfC*^(1hw>Nb)j(h2 throw new NotImplementedException() }; } + int ConvertBuiltin(string? semantic) + { + return semantic?.ToUpper() switch + { + "POSITION" => (int)BuiltIn.Position, + "TEXCOORD" => (int)BuiltIn.FragCoord, + "SV_DEPTH" => (int)BuiltIn.FragDepth, + _ => -1 + }; + } void CreateStructs(ShaderProgram program) { foreach (var s in program.Symbols.GetAllStructTypes().Cast()) { - var fields = s.Fields.Values.Select(x => GetSpvType(x)).ToArray(); - foreach(var f in fields) - Decorate(f,Decoration.HlslSemanticGOOGLE,new LiteralString("POSITION")); - ShaderTypes[s.Name] = + var fields = new List(s.Fields.Count); + foreach (var f in s.Fields) + { + var spv = GetSpvType(f.Value); + if (s.HasSemantics && s.Semantics.TryGetValue(f.Key, out var semantic)) + { + var builtin = ConvertBuiltin(semantic); + if (builtin > -1) + Decorate(spv, Decoration.BuiltIn, (LiteralInteger)builtin); + } + fields.Add(spv); + + } + ShaderTypes[s.Name] = new SpvStruct( TypeStruct( true, - fields + fields.ToArray() ), s ); - Name(ShaderTypes[s.Name].SpvType,s.Name); + Name(ShaderTypes[s.Name].SpvType, s.Name); for (int i = 0; i < s.Fields.Count; i++) { - MemberName(ShaderTypes[s.Name].SpvType,i,s.Fields.Keys[i]); + MemberName(ShaderTypes[s.Name].SpvType, i, s.Fields.Keys[i]); } } } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 2e06237b8d..6f1826102f 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -31,8 +31,8 @@ public void Initialize(EntryPoints entry) _ => Capability.Shader, }; AddCapability(capability); - AddExtension("SPV_GOOGLE_decorate_string"); - AddExtension("SPV_GOOGLE_hlsl_functionality1"); + // AddExtension("SPV_GOOGLE_decorate_string"); + // AddExtension("SPV_GOOGLE_hlsl_functionality1"); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs index 36f5e79ddc..ed2130e19e 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -33,7 +33,7 @@ public void PushVar(Declaration a) } public void PushStreamType(IEnumerable variables) { - CurrentScope["STREAM"] = new CompositeType("STREAM", new(variables.ToDictionary(v => v.Name, v => v.Type))); + CurrentScope["STREAM"] = new CompositeType("STREAM", new(variables.ToDictionary(v => v.Name, v => v.Type)), new(variables.ToDictionary(v => v.Name, v => v.Semantic))); } public void PushType(string name, CompositeType structDef) { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs index ef2bd2ac53..77cae42527 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -51,10 +51,15 @@ public class CompositeType : ISymbolType public string Name { get; set; } public SortedList Fields { get; set; } = new(); - public CompositeType(string name, SortedList fields) + public bool HasSemantics {get;private set;} + public SortedList Semantics {get;private set;} + + public CompositeType(string name, SortedList fields, SortedList semantics) { Name = name; Fields = fields; + HasSemantics = semantics.Count > 0; + Semantics = semantics; } public bool Equals(ISymbolType? other) @@ -83,7 +88,8 @@ public CompositeType SubType(string name, IEnumerable filter) { return new CompositeType( name, - new(Fields.Where(x => filter.Contains(x.Key)).ToDictionary(x => x.Key, x=> x.Value)) + new(Fields.Where(x => filter.Contains(x.Key)).ToDictionary(x => x.Key, x=> x.Value)), + Semantics ); } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs index 36b7712fec..6bb07a6d05 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs @@ -34,7 +34,7 @@ public StructDefinition(Match m, SymbolTable s) Match = m; StructName = Match["StructName"].StringValue; Fields = Match["Fields"].Matches.Select(x => new StructField(x,s)).ToList(); - Type = new CompositeType(StructName, new(Fields.ToDictionary(x => x.Name, x => s.Tokenize(x.Match["ValueTypes"])))); + Type = new CompositeType(StructName, new(Fields.ToDictionary(x => x.Name, x => s.Tokenize(x.Match["ValueTypes"]))),new()); } } From 33f1972191b07bdfd9cdf8f994b29790665c0b34 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 4 Oct 2022 16:36:48 +0200 Subject: [PATCH 0160/1182] Added semantic index --- src/SDSLParserExample/Program.cs | 4 +- src/SDSLParserExample/TestModule.cs | 2 + .../Emitter/SpirvEmitter.MainMethod.cs | 2 +- .../Compiler/Emitter/SpirvEmitter.cs | 52 +++++++++---------- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 5f5d2f544d..1696531478 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -24,8 +24,8 @@ // ShaderCompiling(shaderf); // ThreeAddress(); -// LoadShaders(); -TestModuleCreation(); +LoadShaders(); +// TestModuleCreation(); static void TestModuleCreation() { diff --git a/src/SDSLParserExample/TestModule.cs b/src/SDSLParserExample/TestModule.cs index 08d4afd845..782557b4fb 100644 --- a/src/SDSLParserExample/TestModule.cs +++ b/src/SDSLParserExample/TestModule.cs @@ -31,6 +31,8 @@ public void Construct() Decorate(sv_pos, Decoration.BuiltIn, (LiteralInteger)0); Instruction outputColor = Variable(vec4OutputPtrType, StorageClass.Output); + // Decorate(outputColor, Decoration.); + Decorate(outputColor, Decoration.Location, (LiteralInteger)111); Name(inputPos, "pos"); Name(sv_pos, "svpos"); diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs index 82a191aad2..58249578ca 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs @@ -36,7 +36,7 @@ public void VSMethod(ShaderProgram p) // } Return(); FunctionEnd(); - AddEntryPoint(ExecutionModel.Vertex, func, "VSMain", input,output); + AddEntryPoint(ExecutionModel.Vertex, func, "VSMain", input.Concat(output).ToArray()); // AddExecutionMode(func, ExecutionMode.OriginLowerLeft); } diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index 6f1826102f..fe0a3109e9 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -12,12 +12,13 @@ namespace Stride.Shaders.Spirv; public partial class SpirvEmitter : Module { - private Instruction input; - private Instruction output; + private List input = new(); + private List output = new(); public Dictionary ShaderTypes {get;set;} public Dictionary ShaderFunctionTypes {get;set;} public Dictionary Variables {get;set;} = new(); + public SortedList Semantics {get;set;} public SpirvEmitter(uint version) : base(version) { ShaderTypes = new(); @@ -31,41 +32,36 @@ public void Initialize(EntryPoints entry) _ => Capability.Shader, }; AddCapability(capability); - // AddExtension("SPV_GOOGLE_decorate_string"); - // AddExtension("SPV_GOOGLE_hlsl_functionality1"); SetMemoryModel(AddressingModel.Logical, MemoryModel.Simple); } - + public void CreateSemantics(ShaderProgram program) + { + Semantics = new(program.Body.OfType().Where(x => x.Semantic!=null).Select((x,i) => (x,i)).ToDictionary(v=> v.x.Semantic ?? "", v => v.i)); + } public void Construct(ShaderProgram program, EntryPoints entry) { Initialize(entry); // Create all user defined types + CreateSemantics(program); CreateStructs(program); // Create stream in out - // foreach(var f in ShaderTypes["VS_STREAM_IN"].Definition.Fields) - // { - // var ptr = TypePointer(StorageClass.Input, GetSpvType(f.Value)); - // var v = Variable(ptr,StorageClass.Input); - // Name(v,f.Key); - // input.Add(v); - // AddGlobalVariable(v); - // Decorate(v,Decoration.HlslSemanticGOOGLE, new LiteralString("POSITION")); - // } - // foreach(var f in ShaderTypes["VS_STREAM_OUT"].Definition.Fields) - // { - // var ptr = TypePointer(StorageClass.Output, GetSpvType(f.Value)); - // var v = Variable(ptr,StorageClass.Output); - // Name(v,f.Key); - // input.Add(v); - // AddGlobalVariable(v); - // } - var pInput = TypePointer(StorageClass.Input,ShaderTypes["VS_STREAM_IN"].SpvType); - var pOutput = TypePointer(StorageClass.Output,ShaderTypes["VS_STREAM_OUT"].SpvType); - input = Variable(pInput,StorageClass.Input); - output = Variable(pOutput,StorageClass.Output); - AddGlobalVariable(input); - AddGlobalVariable(output); + foreach(var f in ShaderTypes["VS_STREAM_IN"].Definition.Fields) + { + var ptr = TypePointer(StorageClass.Input, GetSpvType(f.Value)); + var v = Variable(ptr,StorageClass.Input); + Name(v,f.Key); + input.Add(v); + AddGlobalVariable(v); + } + foreach(var f in ShaderTypes["VS_STREAM_OUT"].Definition.Fields) + { + var ptr = TypePointer(StorageClass.Output, GetSpvType(f.Value)); + var v = Variable(ptr,StorageClass.Output); + Name(v,f.Key); + input.Add(v); + AddGlobalVariable(v); + } // Generate methods() From 093b0e3c9e15c3eae03c4c1157952713a721d889 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 4 Oct 2022 16:56:25 +0200 Subject: [PATCH 0161/1182] update semantic --- src/SDSLParserExample/shader.spv | Bin 980 -> 1324 bytes .../Compiler/Emitter/SpirvEmitter.Structs.cs | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/SDSLParserExample/shader.spv b/src/SDSLParserExample/shader.spv index 6744c907c53da62a1bff49e14278170a46f76bb2..aadc98d4f516a7bf749942b77f8978eba90e764c 100644 GIT binary patch delta 490 zcmaKp&k6xi6vmG`?hG?V!-OOv?;vF*3o9$KpClTdl3hA8RA9bmC{;FajqBTH?`=G ze{$Fz!bK2n)<<|u@epmC4czEJ6l5xSNtim#`3&m}n;Et;%zo4F6~BBI&cp`nI3Zz< z!wU(QVrC=EcVlKFWagy{0RQrLVCOfnTqAWqaqbbyvOl)KXS-mQXDo@6x$QK2G5gqN b1$Gb7Dm3i@c23Pd#zX%Tc{S)4sth4-M=>1q delta 176 zcmZ3(b%mXmnMs+Qft8T~1VkqC%8IjtnSwwvEZ8?OGmn9R7s%$@=$g#L>(0Q!08+{g z#A1_wGH=fTsa61rasg>(Am#vKYapK!NQ3l&RD<{+c|ITpsS##iV&DhTia?$KkOr~M Z7+AqH$X*ZtiT?nq69&?Mfu>jhF#x<04X6MB diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs index 3879fb55f2..c9acad11ab 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs @@ -42,11 +42,9 @@ void CreateStructs(ShaderProgram program) foreach (var f in s.Fields) { var spv = GetSpvType(f.Value); - if (s.HasSemantics && s.Semantics.TryGetValue(f.Key, out var semantic)) + if (s.HasSemantics && s.Semantics.TryGetValue(f.Key, out var semantic) && semantic != null) { - var builtin = ConvertBuiltin(semantic); - if (builtin > -1) - Decorate(spv, Decoration.BuiltIn, (LiteralInteger)builtin); + Decorate(spv, Decoration.Location, (LiteralInteger)Semantics[semantic]); } fields.Add(spv); From 589a89f877d6cca3ebf316367c1121d566bc8fac Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 4 Oct 2022 18:12:32 +0200 Subject: [PATCH 0162/1182] builtin input --- src/SDSLParserExample/Program.cs | 1 + .../SDSL/MixinSamples/SingleShader.sdsl | 2 +- src/SDSLParserExample/shader.spv | Bin 1324 -> 1248 bytes .../Emitter/SpirvEmitter.MainMethod.cs | 1 + .../Compiler/Emitter/SpirvEmitter.Structs.cs | 10 ++++++--- .../Compiler/Emitter/SpirvEmitter.cs | 19 ++++++++++++++++++ 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 1696531478..0e1a3c1d5b 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -48,6 +48,7 @@ static void LoadShaders() var bytes = module.Generate(); File.WriteAllBytes("./shader.spv", bytes); ToGlsl(bytes); + ToHlsl(bytes); var x = 0; } diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl index c7cff8afe0..f2904bf9a9 100644 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl @@ -35,6 +35,6 @@ shader SingleShader { { float4 a = float4(0); streams.ShadingPosition = a; - streams.ColorTarget = streams.ShadingPosition; + streams.ColorTarget = float3(0); } }; \ No newline at end of file diff --git a/src/SDSLParserExample/shader.spv b/src/SDSLParserExample/shader.spv index aadc98d4f516a7bf749942b77f8978eba90e764c..ae30fc97f5b370c64e8b42803ab75b8923f80ffd 100644 GIT binary patch delta 236 zcmZ3(^?;L?nMs+Qft8T~1cWE@%8IjtnF2sEEZ8?OGmn9R8_4F}==z&+atxE7I4hX% zoS&0l6p~n!o?61d%D~3JJNYKlYj%)IAej7`Nm3EYW^iX<0qc+hN-zO2h|de8xhH>R zp32O`z&?2*i*y1rPy~dnfwG(+Su{RK2S{ERXa*mURs{0+fi#G126O?42DupoK;l1u P>V$ywUj{}73m^snuwogN delta 286 zcmaFBxrU3EnMs+Qft8T~1jHut%1U#9nZiIaEZ8?OGmn9R8_4DZVu6j0zZp5%7}$Xj z2qrIN5}s_scke3p5tGBemjuqaR#IgcX2%P9V)VxsgRU2jonU2oF>iq{14?2e}ZL sF978WGcYj-0@;c{Ss@?|Vw(Zo1)@Q|1Obrv51=|xApMttk--9p0f4I<5dZ)H diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs index 58249578ca..3436090219 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs @@ -30,6 +30,7 @@ public void VSMethod(ShaderProgram p) var typefunc = TypeFunction(TypeVoid()); var func = Function(TypeVoid(), FunctionControlMask.MaskNone, typefunc); AddLabel(Label()); + // foreach(var s in ((VSMainMethod)p.Body.First(x => x is VSMainMethod)).Statements) // { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs index c9acad11ab..7b6f326b6f 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs @@ -26,9 +26,9 @@ Instruction GetSpvType(ISymbolType t) } int ConvertBuiltin(string? semantic) { - return semantic?.ToUpper() switch + return semantic switch { - "POSITION" => (int)BuiltIn.Position, + "SV_Position" => (int)BuiltIn.Position, "TEXCOORD" => (int)BuiltIn.FragCoord, "SV_DEPTH" => (int)BuiltIn.FragDepth, _ => -1 @@ -44,7 +44,11 @@ void CreateStructs(ShaderProgram program) var spv = GetSpvType(f.Value); if (s.HasSemantics && s.Semantics.TryGetValue(f.Key, out var semantic) && semantic != null) { - Decorate(spv, Decoration.Location, (LiteralInteger)Semantics[semantic]); + var possible = ConvertBuiltin(semantic); + if(possible > -1) + Decorate(spv, Decoration.BuiltIn, (LiteralInteger)possible); + else + Decorate(spv, Decoration.Location, (LiteralInteger)Semantics[semantic]); } fields.Add(spv); diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs index fe0a3109e9..742edff48e 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs @@ -50,6 +50,16 @@ public void Construct(ShaderProgram program, EntryPoints entry) { var ptr = TypePointer(StorageClass.Input, GetSpvType(f.Value)); var v = Variable(ptr,StorageClass.Input); + + if(ShaderTypes["VS_STREAM_IN"].Definition.Semantics.TryGetValue(f.Key,out var semantic) && semantic !=null) + { + var possible = ConvertBuiltin(semantic); + if(possible > -1) + Decorate(v, Decoration.BuiltIn, (LiteralInteger)possible); + else + Decorate(v, Decoration.Location, (LiteralInteger)Semantics[semantic]); + } + Name(v,f.Key); input.Add(v); AddGlobalVariable(v); @@ -58,6 +68,15 @@ public void Construct(ShaderProgram program, EntryPoints entry) { var ptr = TypePointer(StorageClass.Output, GetSpvType(f.Value)); var v = Variable(ptr,StorageClass.Output); + + if(ShaderTypes["VS_STREAM_OUT"].Definition.Semantics.TryGetValue(f.Key,out var semantic) && semantic !=null) + { + var possible = ConvertBuiltin(semantic); + if(possible > -1) + Decorate(v, Decoration.BuiltIn, (LiteralInteger)possible); + else + Decorate(v, Decoration.Location, (LiteralInteger)Semantics[semantic]); + } Name(v,f.Key); input.Add(v); AddGlobalVariable(v); From a11adfe5afa5c1e724f1ecc9f3f51e3945737abf Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 24 Oct 2022 20:28:18 +0200 Subject: [PATCH 0163/1182] bump spv --- src/Spv.Generator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Spv.Generator b/src/Spv.Generator index 9a3486864e..3fb0e5b035 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 9a3486864e970b1d26a8dd84ad1929c1a908cd79 +Subproject commit 3fb0e5b0353495fc3a57874b5998f4d15d82d187 From 6d77f3d07d90655ef60e0e6574915f89d09719cc Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 7 Jan 2023 18:40:38 +0100 Subject: [PATCH 0164/1182] naming update --- SDSLParser.sln | 25 +++++++----- src/Eto.Parse | 2 +- ...SL.Benchmarks.ParserBench-report-github.md | 14 +++++++ .../SDSL.Benchmarks.ParserBench-report.csv | 3 ++ .../SDSL.Benchmarks.ParserBench-report.html | 31 +++++++++++++++ src/SDSL.Benchmarks/ParserBench.cs | 30 +++++++++++++++ src/SDSL.Benchmarks/Program.cs | 5 +++ src/SDSL.Benchmarks/SDSL.Benchmarks.csproj | 20 ++++++++++ src/SDSL.Benchmarks/shader.sdsl | 38 +++++++++++++++++++ .../ASTTypeChecking.cs | 10 ++--- .../BasicExpressionParsing.cs | 4 +- .../OperationExpressionParsing.cs | 4 +- .../SDSL.Test.csproj} | 4 +- .../Compiler/CompilationProcess.md | 0 .../Compiler/Composition.md | 0 .../Emitter/SpirvEmitter.MainMethod.cs | 6 +-- .../Emitter/SpirvEmitter.Statements.cs | 6 +-- .../Compiler/Emitter/SpirvEmitter.Streams.cs | 8 ++-- .../Compiler/Emitter/SpirvEmitter.Structs.cs | 6 +-- .../Compiler/Emitter/SpirvEmitter.Types.cs | 6 +-- .../Compiler/Emitter/SpirvEmitter.cs | 6 +-- .../Compiler/Emitter/SpvStruct.cs | 6 +-- .../Compiler/Mixer/EntryPoints.cs | 2 +- .../Compiler/Mixer/ShaderArraySource.cs | 6 +-- .../Compiler/Mixer/ShaderClassCode.cs | 2 +- .../Compiler/Mixer/ShaderClassSource.cs | 2 +- .../Compiler/Mixer/ShaderClassString.cs | 6 +-- .../Compiler/Mixer/ShaderMixinContext.cs | 2 +- .../Mixer/ShaderMixinDiscardException.cs | 2 +- .../Mixer/ShaderMixinGeneratorSource.cs | 2 +- .../Compiler/Mixer/ShaderMixinManager.cs | 4 +- .../Compiler/Mixer/ShaderMixinSource.cs | 6 +-- .../Compiler/Mixer/ShaderResult.cs | 2 +- .../Compiler/Mixer/ShaderSource.cs | 2 +- .../Compiler/Mixer/ShaderSourceCollection.cs | 2 +- .../Compiler/Mixer/SimpleMixer.cs | 12 +++--- .../EffectCompiler.cs | 6 +-- .../IShaderMixinBuilder.cs | 4 +- .../Parsers/AST/Directives/DirectiveToken.cs | 4 +- .../Parsers/AST/Directives/Directives.cs | 2 +- .../Parsers/AST/Directives/Literals.cs | 2 +- .../Parsers/AST/Directives/Operations.cs | 6 +-- .../Parsers/AST/Directives/OperatorToken.cs | 2 +- .../Parsers/AST/Directives/UnaryLiterals.cs | 2 +- .../Parsers/AST/Shader/Analysis/Errors.cs | 2 +- .../AST/Shader/Analysis/NumberTypeCasting.cs | 2 +- .../AST/Shader/Analysis/ShaderTokenTyped.cs | 2 +- .../AST/Shader/Analysis/StaticCheck.cs | 2 +- .../AST/Shader/Analysis/SymbolTable.Check.cs | 2 +- .../AST/Shader/Analysis/SymbolTable.cs | 2 +- .../Parsers/AST/Shader/Analysis/SymbolType.cs | 2 +- .../AST/Shader/Analysis/SymbolVariable.cs | 2 +- .../Parsers/AST/Shader/ControlFlow.cs | 4 +- .../Parsers/AST/Shader/Literals.cs | 4 +- .../Parsers/AST/Shader/Operations.cs | 8 ++-- .../Parsers/AST/Shader/OperatorToken.cs | 2 +- .../Parsers/AST/Shader/ShaderElements.cs | 4 +- .../Parsers/AST/Shader/ShaderMethods.cs | 6 +-- .../Parsers/AST/Shader/ShaderProgram.cs | 4 +- .../Parsers/AST/Shader/ShaderToken.cs | 6 +-- .../Parsers/AST/Shader/SpirvTypes.cs | 2 +- .../Parsers/AST/Shader/Statements.cs | 10 ++--- .../Parsers/AST/Shader/UnaryLiterals.cs | 4 +- .../Parsers/DirectivePreprocessor.cs | 10 ++--- .../Parsers/ExpressionParser.cs | 14 +++---- .../Parsers/Grammars/CommentGrammar.cs | 2 +- .../DirectiveGrammar.Directives.Expression.cs | 2 +- .../DirectiveGrammar.Directives.cs | 2 +- .../DirectiveGrammar.Tokens.cs | 2 +- .../DirectiveGrammar/DirectiveGrammar.cs | 2 +- .../DirectiveGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.TokenGroups.cs | 2 +- .../Parsers/Grammars/ExpressionGrammar.cs | 4 +- .../Parsers/Grammars/MacroGrammar.cs | 2 +- .../Parsers/Grammars/NativeTypeGrammar.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Declaration.cs | 2 +- .../SDSLGrammar.Directives.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Directives.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Expression.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Literals.cs | 2 +- .../SDSLGrammar.MethodDeclaration.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Shader.cs | 2 +- ...ar.Statements.ConditionalFlowStatements.cs | 2 +- ...SLGrammar.Statements.LoopFlowStatements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Statements.cs | 2 +- .../SDSLGrammar/SDSLGrammar.TokenGroups.cs | 2 +- .../SDSLGrammar/SDSLGrammar.Tokens.cs | 2 +- .../Grammars/SDSLGrammar/SDSLGrammar.cs | 2 +- .../Parsers/Grammars/SDSLMixinReader.cs | 2 +- .../Parsers/ShaderMixinParser.cs | 14 +++---- .../Parsers/ThreeAddress/Operators.cs | 2 +- .../Parsers/ThreeAddress/Registers.cs | 2 +- .../Parsers/ThreeAddress/Snippet.Lowering.cs | 10 ++--- .../Parsers/ThreeAddress/Snippet.cs | 6 +-- .../SDSL.csproj} | 2 +- src/{Stride.Shaders => SDSL}/ShaderLoader.cs | 2 +- .../ShaderSourceManager.cs | 2 +- src/SDSLParserExample/Program.cs | 12 +++--- .../SDSLParserExample.csproj | 2 +- 99 files changed, 330 insertions(+), 182 deletions(-) create mode 100644 src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md create mode 100644 src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv create mode 100644 src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html create mode 100644 src/SDSL.Benchmarks/ParserBench.cs create mode 100644 src/SDSL.Benchmarks/Program.cs create mode 100644 src/SDSL.Benchmarks/SDSL.Benchmarks.csproj create mode 100644 src/SDSL.Benchmarks/shader.sdsl rename src/{Stride.Shaders.Test => SDSL.Test}/ASTTypeChecking.cs (93%) rename src/{Stride.Shaders.Test => SDSL.Test}/BasicExpressionParsing.cs (97%) rename src/{Stride.Shaders.Test => SDSL.Test}/OperationExpressionParsing.cs (99%) rename src/{Stride.Shaders.Test/Stride.Shaders.Test.csproj => SDSL.Test/SDSL.Test.csproj} (88%) rename src/{Stride.Shaders => SDSL}/Compiler/CompilationProcess.md (100%) rename src/{Stride.Shaders => SDSL}/Compiler/Composition.md (100%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.MainMethod.cs (94%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.Statements.cs (81%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.Streams.cs (88%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.Structs.cs (94%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.Types.cs (97%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpirvEmitter.cs (96%) rename src/{Stride.Shaders => SDSL}/Compiler/Emitter/SpvStruct.cs (71%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/EntryPoints.cs (75%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderArraySource.cs (92%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderClassCode.cs (96%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderClassSource.cs (98%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderClassString.cs (85%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderMixinContext.cs (99%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderMixinDiscardException.cs (94%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderMixinGeneratorSource.cs (98%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderMixinManager.cs (98%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderMixinSource.cs (98%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderResult.cs (91%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderSource.cs (87%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/ShaderSourceCollection.cs (97%) rename src/{Stride.Shaders => SDSL}/Compiler/Mixer/SimpleMixer.cs (75%) rename src/{Stride.Shaders => SDSL}/EffectCompiler.cs (67%) rename src/{Stride.Shaders => SDSL}/IShaderMixinBuilder.cs (84%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/DirectiveToken.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/Directives.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/Literals.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/Operations.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/OperatorToken.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Directives/UnaryLiterals.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/Errors.cs (83%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs (91%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs (77%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/StaticCheck.cs (86%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/SymbolTable.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/SymbolType.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Analysis/SymbolVariable.cs (75%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/ControlFlow.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Literals.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Operations.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/OperatorToken.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/ShaderElements.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/ShaderMethods.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/ShaderProgram.cs (92%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/ShaderToken.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/SpirvTypes.cs (87%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/Statements.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/AST/Shader/UnaryLiterals.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/DirectivePreprocessor.cs (90%) rename src/{Stride.Shaders => SDSL}/Parsers/ExpressionParser.cs (60%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/CommentGrammar.cs (93%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs (87%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/ExpressionGrammar.cs (68%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/MacroGrammar.cs (91%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/NativeTypeGrammar.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs (97%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs (99%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs (93%) rename src/{Stride.Shaders => SDSL}/Parsers/Grammars/SDSLMixinReader.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/ShaderMixinParser.cs (93%) rename src/{Stride.Shaders => SDSL}/Parsers/ThreeAddress/Operators.cs (92%) rename src/{Stride.Shaders => SDSL}/Parsers/ThreeAddress/Registers.cs (98%) rename src/{Stride.Shaders => SDSL}/Parsers/ThreeAddress/Snippet.Lowering.cs (96%) rename src/{Stride.Shaders => SDSL}/Parsers/ThreeAddress/Snippet.cs (92%) rename src/{Stride.Shaders/Stride.Shaders.csproj => SDSL/SDSL.csproj} (92%) rename src/{Stride.Shaders => SDSL}/ShaderLoader.cs (91%) rename src/{Stride.Shaders => SDSL}/ShaderSourceManager.cs (98%) diff --git a/SDSLParser.sln b/SDSLParser.sln index 1265f607eb..5197fc742d 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -5,26 +5,24 @@ VisualStudioVersion = 17.2.32516.85 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5F88D871-B760-4857-BD74-296B07778B15}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDSL", "src\SDSL\SDSL.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "src\Stride.Shaders\Stride.Shaders.csproj", "{3A20C614-0B73-4592-B0A3-152FBA7C112C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Test", "src\Stride.Shaders.Test\Stride.Shaders.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDSL.Test", "src\SDSL.Test\SDSL.Test.csproj", "{6D885FCB-C043-4065-BA7E-E4937667B219}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "src\CppNet\CppNet.csproj", "{C2FD9262-69F8-4B75-9AB1-FF359C9143E9}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spv.Generator", "src\Spv.Generator\Spv.Generator\Spv.Generator.csproj", "{09D8574D-6452-40E2-9724-9C58F446D862}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSL.Benchmarks", "src\SDSL.Benchmarks\SDSL.Benchmarks.csproj", "{A2559EFF-A034-4B58-AF90-A525E32DF61C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Parse", "src\Eto.Parse\Eto.Parse\Eto.Parse.csproj", "{490CA54A-75FC-431F-A2C2-803F59576E88}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD}.Release|Any CPU.Build.0 = Release|Any CPU {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Debug|Any CPU.Build.0 = Debug|Any CPU {3A20C614-0B73-4592-B0A3-152FBA7C112C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -41,16 +39,25 @@ Global {09D8574D-6452-40E2-9724-9C58F446D862}.Debug|Any CPU.Build.0 = Debug|Any CPU {09D8574D-6452-40E2-9724-9C58F446D862}.Release|Any CPU.ActiveCfg = Release|Any CPU {09D8574D-6452-40E2-9724-9C58F446D862}.Release|Any CPU.Build.0 = Release|Any CPU + {A2559EFF-A034-4B58-AF90-A525E32DF61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2559EFF-A034-4B58-AF90-A525E32DF61C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2559EFF-A034-4B58-AF90-A525E32DF61C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2559EFF-A034-4B58-AF90-A525E32DF61C}.Release|Any CPU.Build.0 = Release|Any CPU + {490CA54A-75FC-431F-A2C2-803F59576E88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {490CA54A-75FC-431F-A2C2-803F59576E88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {490CA54A-75FC-431F-A2C2-803F59576E88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {490CA54A-75FC-431F-A2C2-803F59576E88}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {04B29CCB-301A-4B1B-8EE2-3866DDAA86CD} = {5F88D871-B760-4857-BD74-296B07778B15} {3A20C614-0B73-4592-B0A3-152FBA7C112C} = {5F88D871-B760-4857-BD74-296B07778B15} {6D885FCB-C043-4065-BA7E-E4937667B219} = {5F88D871-B760-4857-BD74-296B07778B15} {C2FD9262-69F8-4B75-9AB1-FF359C9143E9} = {5F88D871-B760-4857-BD74-296B07778B15} {09D8574D-6452-40E2-9724-9C58F446D862} = {5F88D871-B760-4857-BD74-296B07778B15} + {A2559EFF-A034-4B58-AF90-A525E32DF61C} = {5F88D871-B760-4857-BD74-296B07778B15} + {490CA54A-75FC-431F-A2C2-803F59576E88} = {5F88D871-B760-4857-BD74-296B07778B15} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4AF186D8-C065-4788-835B-3C253D65EAE0} diff --git a/src/Eto.Parse b/src/Eto.Parse index af87b77d8c..06eb73f953 160000 --- a/src/Eto.Parse +++ b/src/Eto.Parse @@ -1 +1 @@ -Subproject commit af87b77d8c63ef675e65815770bea71ca32e2ae7 +Subproject commit 06eb73f953d8e51ae6e85432dd06042cb2c99321 diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md new file mode 100644 index 0000000000..81c481c43a --- /dev/null +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md @@ -0,0 +1,14 @@ +``` ini + +BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) +AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx, 1 CPU, 8 logical and 4 physical cores +.NET SDK=7.0.101 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + + +``` +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | +|------------ |---------:|---------:|---------:|--------:|--------:|----------:| +| StrideParse | 416.2 μs | 13.24 μs | 38.19 μs | 88.8672 | 26.8555 | 246.9 KB | +| EtoParse | 418.3 μs | 11.48 μs | 33.13 μs | 79.5898 | - | 163.28 KB | diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv new file mode 100644 index 0000000000..34a5eec456 --- /dev/null +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv @@ -0,0 +1,3 @@ +Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Allocated +StrideParse,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,416.2 μs,13.24 μs,38.19 μs,88.8672,26.8555,246.9 KB +EtoParse,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,418.3 μs,11.48 μs,33.13 μs,79.5898,-,163.28 KB diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html new file mode 100644 index 0000000000..4d10d13030 --- /dev/null +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html @@ -0,0 +1,31 @@ + + + + +SDSL.Benchmarks.ParserBench-20230107-181725 + + + + +

+BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963)
+AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx, 1 CPU, 8 logical and 4 physical cores
+.NET SDK=7.0.101
+  [Host]     : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
+  DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
+
+
+ + + + + + +
MethodMeanErrorStdDevGen0Gen1Allocated
StrideParse416.2 μs13.24 μs38.19 μs88.867226.8555246.9 KB
EtoParse418.3 μs11.48 μs33.13 μs79.5898-163.28 KB
+ + diff --git a/src/SDSL.Benchmarks/ParserBench.cs b/src/SDSL.Benchmarks/ParserBench.cs new file mode 100644 index 0000000000..71095cb76c --- /dev/null +++ b/src/SDSL.Benchmarks/ParserBench.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BenchmarkDotNet; +using BenchmarkDotNet.Attributes; +using Stride.Core.Shaders.Grammar.Stride; +using Stride.Core.Shaders.Parser; + +namespace SDSL.Benchmarks; + +[MemoryDiagnoser] +public class ParserBench +{ + public string shaderText = File.ReadAllText(@"C:\Users\kafia\source\repos\SDSLParser\src\SDSL.Benchmarks\shader.sdsl"); + ShaderParser strideParser = ShaderParser.GetParser(); + Parsing.ShaderMixinParser etoParser = new(); + + [Benchmark] + public void StrideParse() + { + strideParser.Parse(shaderText, ""); + } + [Benchmark] + public void EtoParse() + { + etoParser.Parse(shaderText); + } +} diff --git a/src/SDSL.Benchmarks/Program.cs b/src/SDSL.Benchmarks/Program.cs new file mode 100644 index 0000000000..c6709bf5e7 --- /dev/null +++ b/src/SDSL.Benchmarks/Program.cs @@ -0,0 +1,5 @@ +// See https://aka.ms/new-console-template for more information +using BenchmarkDotNet.Running; +using SDSL.Benchmarks; + +BenchmarkRunner.Run(); diff --git a/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj b/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj new file mode 100644 index 0000000000..37c919b891 --- /dev/null +++ b/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj @@ -0,0 +1,20 @@ + + + + Exe + net7.0 + enable + enable + + + + + + + + + + + + + diff --git a/src/SDSL.Benchmarks/shader.sdsl b/src/SDSL.Benchmarks/shader.sdsl new file mode 100644 index 0000000000..060e745d1d --- /dev/null +++ b/src/SDSL.Benchmarks/shader.sdsl @@ -0,0 +1,38 @@ +shader SingleShader { + + struct Position { + float x; + float y; + float z; + }; + + stage stream float4 triInput; + + stage stream float4 ShadingPosition : SV_Position; + + stage stream bool IsFrontFace : SV_IsFrontFace; + + stage stream float4 ColorTarget : SV_Target0; + stage stream float4 ColorTarget1 : SV_Target1; + stage stream float4 ColorTarget2 : SV_Target2; + stage stream float4 ColorTarget3 : SV_Target3; + stage stream float4 ColorTarget4 : SV_Target4; + stage stream float4 ColorTarget5 : SV_Target5; + stage stream float4 ColorTarget6 : SV_Target6; + stage stream float4 ColorTarget7 : SV_Target7; + + // Default DEPTH output for PS shader + stage stream float Depth : SV_Depth; + stage stream float DepthGreater : SV_DepthGreater; // Special output after PS + stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS + + stage stream uint InstanceID : SV_InstanceID; + + + void VSMain() + { + float4 a = float4(0); + streams.ShadingPosition = a; + streams.ColorTarget = float3(0); + } +}; \ No newline at end of file diff --git a/src/Stride.Shaders.Test/ASTTypeChecking.cs b/src/SDSL.Test/ASTTypeChecking.cs similarity index 93% rename from src/Stride.Shaders.Test/ASTTypeChecking.cs rename to src/SDSL.Test/ASTTypeChecking.cs index b908d3a5af..e562ce96b0 100644 --- a/src/Stride.Shaders.Test/ASTTypeChecking.cs +++ b/src/SDSL.Test/ASTTypeChecking.cs @@ -1,12 +1,12 @@ using Xunit; using System.Linq; -using Stride.Shaders.Parsing; +using SDSL.Parsing; using System.Collections.Generic; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader; +using SDSL.ThreeAddress; -namespace Stride.Shaders.Parsing.Test; +namespace SDSL.Parsing.Test; public class ASTTypeChecking { diff --git a/src/Stride.Shaders.Test/BasicExpressionParsing.cs b/src/SDSL.Test/BasicExpressionParsing.cs similarity index 97% rename from src/Stride.Shaders.Test/BasicExpressionParsing.cs rename to src/SDSL.Test/BasicExpressionParsing.cs index 108cde0b52..d22d5c268b 100644 --- a/src/Stride.Shaders.Test/BasicExpressionParsing.cs +++ b/src/SDSL.Test/BasicExpressionParsing.cs @@ -1,11 +1,11 @@ using Xunit; using System.Linq; -using Stride.Shaders.Parsing; +using SDSL.Parsing; using Eto.Parse; using Eto.Parse.Parsers; using System.Collections.Generic; -namespace Stride.Shaders.Parsing.Test; +namespace SDSL.Parsing.Test; public class BasicExpressionParsing { diff --git a/src/Stride.Shaders.Test/OperationExpressionParsing.cs b/src/SDSL.Test/OperationExpressionParsing.cs similarity index 99% rename from src/Stride.Shaders.Test/OperationExpressionParsing.cs rename to src/SDSL.Test/OperationExpressionParsing.cs index 619f82f995..2b2270ed99 100644 --- a/src/Stride.Shaders.Test/OperationExpressionParsing.cs +++ b/src/SDSL.Test/OperationExpressionParsing.cs @@ -1,11 +1,11 @@ using Xunit; using System.Linq; -using Stride.Shaders.Parsing; +using SDSL.Parsing; using Eto.Parse; using Eto.Parse.Parsers; using System.Collections.Generic; -namespace Stride.Shaders.Parsing.Test; +namespace SDSL.Parsing.Test; public class OperationExpressionParsing { diff --git a/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj b/src/SDSL.Test/SDSL.Test.csproj similarity index 88% rename from src/Stride.Shaders.Test/Stride.Shaders.Test.csproj rename to src/SDSL.Test/SDSL.Test.csproj index 521754b0dd..56530de9c8 100644 --- a/src/Stride.Shaders.Test/Stride.Shaders.Test.csproj +++ b/src/SDSL.Test/SDSL.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable false @@ -21,7 +21,7 @@
- + diff --git a/src/Stride.Shaders/Compiler/CompilationProcess.md b/src/SDSL/Compiler/CompilationProcess.md similarity index 100% rename from src/Stride.Shaders/Compiler/CompilationProcess.md rename to src/SDSL/Compiler/CompilationProcess.md diff --git a/src/Stride.Shaders/Compiler/Composition.md b/src/SDSL/Compiler/Composition.md similarity index 100% rename from src/Stride.Shaders/Compiler/Composition.md rename to src/SDSL/Compiler/Composition.md diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.MainMethod.cs similarity index 94% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.MainMethod.cs index 3436090219..4f9401dbde 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.MainMethod.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.MainMethod.cs @@ -4,11 +4,11 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Mixer; +using SDSL.Parsing.AST.Shader; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.Statements.cs similarity index 81% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.Statements.cs index 7e1dc0f5ac..862379b8ed 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Statements.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.Statements.cs @@ -4,11 +4,11 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Mixer; +using SDSL.Parsing.AST.Shader; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.Streams.cs similarity index 88% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.Streams.cs index 2be753a800..7849960ee7 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Streams.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.Streams.cs @@ -1,10 +1,10 @@ using Spv.Generator; -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Mixer; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.Structs.cs similarity index 94% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.Structs.cs index 7b6f326b6f..8fe40e2f16 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Structs.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.Structs.cs @@ -4,11 +4,11 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.Types.cs similarity index 97% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.Types.cs index 01e5fed18b..c8948efd40 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.Types.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.Types.cs @@ -4,11 +4,11 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.Grammars.NativeType; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.Grammars.NativeType; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs b/src/SDSL/Compiler/Emitter/SpirvEmitter.cs similarity index 96% rename from src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs rename to src/SDSL/Compiler/Emitter/SpirvEmitter.cs index 742edff48e..9af98fc257 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpirvEmitter.cs +++ b/src/SDSL/Compiler/Emitter/SpirvEmitter.cs @@ -4,11 +4,11 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Mixer; +using SDSL.Parsing.AST.Shader; using static Spv.Specification; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public partial class SpirvEmitter : Module { diff --git a/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs b/src/SDSL/Compiler/Emitter/SpvStruct.cs similarity index 71% rename from src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs rename to src/SDSL/Compiler/Emitter/SpvStruct.cs index 7c670524ea..16b9bd0fc5 100644 --- a/src/Stride.Shaders/Compiler/Emitter/SpvStruct.cs +++ b/src/SDSL/Compiler/Emitter/SpvStruct.cs @@ -1,8 +1,8 @@ using Spv.Generator; -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Mixer; +using SDSL.Parsing.AST.Shader.Analysis; -namespace Stride.Shaders.Spirv; +namespace SDSL.Spirv; public class SpvStruct diff --git a/src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs b/src/SDSL/Compiler/Mixer/EntryPoints.cs similarity index 75% rename from src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs rename to src/SDSL/Compiler/Mixer/EntryPoints.cs index f9c90526b4..cc98d40d15 100644 --- a/src/Stride.Shaders/Compiler/Mixer/EntryPoints.cs +++ b/src/SDSL/Compiler/Mixer/EntryPoints.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public enum EntryPoints { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs b/src/SDSL/Compiler/Mixer/ShaderArraySource.cs similarity index 92% rename from src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs rename to src/SDSL/Compiler/Mixer/ShaderArraySource.cs index 8f6a36cfb4..5b8453f8f1 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderArraySource.cs +++ b/src/SDSL/Compiler/Mixer/ShaderArraySource.cs @@ -1,5 +1,5 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Parsing; +using SDSL.Parsing.AST.Shader; using System; using System.Collections; using System.Collections.Generic; @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public class ShaderArraySource : ShaderSource, IEnumerable, IEquatable { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs b/src/SDSL/Compiler/Mixer/ShaderClassCode.cs similarity index 96% rename from src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs rename to src/SDSL/Compiler/Mixer/ShaderClassCode.cs index 512c266125..7469240fea 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassCode.cs +++ b/src/SDSL/Compiler/Mixer/ShaderClassCode.cs @@ -1,7 +1,7 @@ using System.Text; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public abstract class ShaderClassCode : ShaderSource { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs b/src/SDSL/Compiler/Mixer/ShaderClassSource.cs similarity index 98% rename from src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs rename to src/SDSL/Compiler/Mixer/ShaderClassSource.cs index 1473bd9341..bc39360f3f 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassSource.cs +++ b/src/SDSL/Compiler/Mixer/ShaderClassSource.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public sealed class ShaderClassSource : ShaderClassCode, IEquatable { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs b/src/SDSL/Compiler/Mixer/ShaderClassString.cs similarity index 85% rename from src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs rename to src/SDSL/Compiler/Mixer/ShaderClassString.cs index 16fcb2d56d..353f4312ee 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderClassString.cs +++ b/src/SDSL/Compiler/Mixer/ShaderClassString.cs @@ -1,12 +1,12 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Parsing; +using SDSL.Parsing.AST.Shader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public class ShaderClassString : ShaderSource { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs b/src/SDSL/Compiler/Mixer/ShaderMixinContext.cs similarity index 99% rename from src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs rename to src/SDSL/Compiler/Mixer/ShaderMixinContext.cs index aa9a3f5f09..5369c2a7cf 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinContext.cs +++ b/src/SDSL/Compiler/Mixer/ShaderMixinContext.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs b/src/SDSL/Compiler/Mixer/ShaderMixinDiscardException.cs similarity index 94% rename from src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs rename to src/SDSL/Compiler/Mixer/ShaderMixinDiscardException.cs index 978ddc7719..5863da9ca5 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinDiscardException.cs +++ b/src/SDSL/Compiler/Mixer/ShaderMixinDiscardException.cs @@ -1,6 +1,6 @@ using System.Runtime.Serialization; -namespace Stride.Shaders.Mixer +namespace SDSL.Mixer { internal class ShaderMixinDiscardException : Exception { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs b/src/SDSL/Compiler/Mixer/ShaderMixinGeneratorSource.cs similarity index 98% rename from src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs rename to src/SDSL/Compiler/Mixer/ShaderMixinGeneratorSource.cs index 8080e47d03..cedf81288f 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinGeneratorSource.cs +++ b/src/SDSL/Compiler/Mixer/ShaderMixinGeneratorSource.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public sealed class ShaderMixinGeneratorSource : ShaderSource, IEquatable { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs b/src/SDSL/Compiler/Mixer/ShaderMixinManager.cs similarity index 98% rename from src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs rename to src/SDSL/Compiler/Mixer/ShaderMixinManager.cs index ff1b1cef0d..b71dc65c2c 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinManager.cs +++ b/src/SDSL/Compiler/Mixer/ShaderMixinManager.cs @@ -4,9 +4,9 @@ using System.Text; using System.Threading.Tasks; using Spv.Generator; -using Stride.Shaders.Parsing; +using SDSL.Parsing; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public class ShaderMixinManager { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs b/src/SDSL/Compiler/Mixer/ShaderMixinSource.cs similarity index 98% rename from src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs rename to src/SDSL/Compiler/Mixer/ShaderMixinSource.cs index e55215d703..643d74cb66 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderMixinSource.cs +++ b/src/SDSL/Compiler/Mixer/ShaderMixinSource.cs @@ -1,12 +1,12 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; +using SDSL.Parsing; +using SDSL.Parsing.AST.Shader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public sealed class ShaderMixinSource : ShaderSource, IEquatable { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs b/src/SDSL/Compiler/Mixer/ShaderResult.cs similarity index 91% rename from src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs rename to src/SDSL/Compiler/Mixer/ShaderResult.cs index 36d87d1af1..7bcace6f4b 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderResult.cs +++ b/src/SDSL/Compiler/Mixer/ShaderResult.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public struct ShaderResult { diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs b/src/SDSL/Compiler/Mixer/ShaderSource.cs similarity index 87% rename from src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs rename to src/SDSL/Compiler/Mixer/ShaderSource.cs index ad43936788..d2c07c9504 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderSource.cs +++ b/src/SDSL/Compiler/Mixer/ShaderSource.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public abstract class ShaderSource { public bool Discard { get; set; } diff --git a/src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs b/src/SDSL/Compiler/Mixer/ShaderSourceCollection.cs similarity index 97% rename from src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs rename to src/SDSL/Compiler/Mixer/ShaderSourceCollection.cs index c7309a6480..cf12389ac6 100644 --- a/src/Stride.Shaders/Compiler/Mixer/ShaderSourceCollection.cs +++ b/src/SDSL/Compiler/Mixer/ShaderSourceCollection.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public sealed class ShaderSourceCollection : List { diff --git a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs b/src/SDSL/Compiler/Mixer/SimpleMixer.cs similarity index 75% rename from src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs rename to src/SDSL/Compiler/Mixer/SimpleMixer.cs index 373c9a5cba..6fbd7e03b6 100644 --- a/src/Stride.Shaders/Compiler/Mixer/SimpleMixer.cs +++ b/src/SDSL/Compiler/Mixer/SimpleMixer.cs @@ -1,12 +1,12 @@ using Spv; using Spv.Generator; -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.Spirv; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.Spirv; +using SDSL.ThreeAddress; -namespace Stride.Shaders.Mixer; +namespace SDSL.Mixer; public class SimpleMixer { diff --git a/src/Stride.Shaders/EffectCompiler.cs b/src/SDSL/EffectCompiler.cs similarity index 67% rename from src/Stride.Shaders/EffectCompiler.cs rename to src/SDSL/EffectCompiler.cs index 9b37d1aaef..14a7d4aab9 100644 --- a/src/Stride.Shaders/EffectCompiler.cs +++ b/src/SDSL/EffectCompiler.cs @@ -1,7 +1,7 @@ -using Stride.Shaders.Mixer; -using Stride.Shaders.Parsing; +using SDSL.Mixer; +using SDSL.Parsing; -namespace Stride.Shaders; +namespace SDSL; public class EffectCompiler { diff --git a/src/Stride.Shaders/IShaderMixinBuilder.cs b/src/SDSL/IShaderMixinBuilder.cs similarity index 84% rename from src/Stride.Shaders/IShaderMixinBuilder.cs rename to src/SDSL/IShaderMixinBuilder.cs index e55c536abe..4a1157a6b7 100644 --- a/src/Stride.Shaders/IShaderMixinBuilder.cs +++ b/src/SDSL/IShaderMixinBuilder.cs @@ -1,6 +1,6 @@ -using Stride.Shaders.Mixer; +using SDSL.Mixer; -namespace Stride.Shaders; +namespace SDSL; public interface IShaderMixinBuilder { diff --git a/src/Stride.Shaders/Parsers/AST/Directives/DirectiveToken.cs b/src/SDSL/Parsers/AST/Directives/DirectiveToken.cs similarity index 97% rename from src/Stride.Shaders/Parsers/AST/Directives/DirectiveToken.cs rename to src/SDSL/Parsers/AST/Directives/DirectiveToken.cs index 31895472b4..0db753a49a 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/DirectiveToken.cs +++ b/src/SDSL/Parsers/AST/Directives/DirectiveToken.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shaders.Parsing.Grammars.Expression; +using SDSL.Parsing.Grammars.Expression; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public abstract class DirectiveToken diff --git a/src/Stride.Shaders/Parsers/AST/Directives/Directives.cs b/src/SDSL/Parsers/AST/Directives/Directives.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Directives/Directives.cs rename to src/SDSL/Parsers/AST/Directives/Directives.cs index c4d3087c3c..89b105d976 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/Directives.cs +++ b/src/SDSL/Parsers/AST/Directives/Directives.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public class DirectiveFlow : DirectiveToken { diff --git a/src/Stride.Shaders/Parsers/AST/Directives/Literals.cs b/src/SDSL/Parsers/AST/Directives/Literals.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Directives/Literals.cs rename to src/SDSL/Parsers/AST/Directives/Literals.cs index ebaa6bb12f..89c53cf520 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/Literals.cs +++ b/src/SDSL/Parsers/AST/Directives/Literals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public class DirectiveLiteral : DirectiveToken diff --git a/src/Stride.Shaders/Parsers/AST/Directives/Operations.cs b/src/SDSL/Parsers/AST/Directives/Operations.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Directives/Operations.cs rename to src/SDSL/Parsers/AST/Directives/Operations.cs index db69db3e3c..021e2090e2 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/Operations.cs +++ b/src/SDSL/Parsers/AST/Directives/Operations.cs @@ -1,13 +1,13 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Directives; +using SDSL.Parsing.AST.Directives; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shaders.Parsing.AST.Directives.OperatorTokenExtensions; +using static SDSL.Parsing.AST.Directives.OperatorTokenExtensions; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public abstract class Projector : DirectiveToken { diff --git a/src/Stride.Shaders/Parsers/AST/Directives/OperatorToken.cs b/src/SDSL/Parsers/AST/Directives/OperatorToken.cs similarity index 99% rename from src/Stride.Shaders/Parsers/AST/Directives/OperatorToken.cs rename to src/SDSL/Parsers/AST/Directives/OperatorToken.cs index def69e0ae0..8c02de1288 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/OperatorToken.cs +++ b/src/SDSL/Parsers/AST/Directives/OperatorToken.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public enum OperatorToken { diff --git a/src/Stride.Shaders/Parsers/AST/Directives/UnaryLiterals.cs b/src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs similarity index 97% rename from src/Stride.Shaders/Parsers/AST/Directives/UnaryLiterals.cs rename to src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs index 2a252337eb..e15173eda5 100644 --- a/src/Stride.Shaders/Parsers/AST/Directives/UnaryLiterals.cs +++ b/src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Directives; +namespace SDSL.Parsing.AST.Directives; public class UnaryExpression : DirectiveToken diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs b/src/SDSL/Parsers/AST/Shader/Analysis/Errors.cs similarity index 83% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/Errors.cs index c07c6c1ba4..b647261d16 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/Errors.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/Errors.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; using Eto.Parse; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs b/src/SDSL/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs similarity index 91% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs index 11239dbb75..76f2230290 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/NumberTypeCasting.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public class NumberTypeCasting { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs b/src/SDSL/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs similarity index 77% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs index 6693541ea1..4795aa397c 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/ShaderTokenTyped.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public abstract class ShaderTokenTyped : ShaderToken { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs b/src/SDSL/Parsers/AST/Shader/Analysis/StaticCheck.cs similarity index 86% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/StaticCheck.cs index df4437ae16..b93ca83ae1 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/StaticCheck.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/StaticCheck.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public interface IStaticCheck diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs index d5b99e8528..311031eccc 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.Check.cs @@ -1,6 +1,6 @@ using Eto.Parse; -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public partial class SymbolTable diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.cs index ed2130e19e..859ff6776d 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolTable.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolTable.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public interface ISymbol { } diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolType.cs similarity index 99% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/SymbolType.cs index 77cae42527..da345f7519 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolType.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolType.cs @@ -1,6 +1,6 @@ using Eto.Parse; -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public interface ISymbolType : ISymbol, IEquatable { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolVariable.cs similarity index 75% rename from src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs rename to src/SDSL/Parsers/AST/Shader/Analysis/SymbolVariable.cs index ddab9ea853..0d1913a9a9 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Analysis/SymbolVariable.cs +++ b/src/SDSL/Parsers/AST/Shader/Analysis/SymbolVariable.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.AST.Shader.Analysis; +namespace SDSL.Parsing.AST.Shader.Analysis; public class SymbolVariable : ISymbol { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs b/src/SDSL/Parsers/AST/Shader/ControlFlow.cs similarity index 96% rename from src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs rename to src/SDSL/Parsers/AST/Shader/ControlFlow.cs index 92e2bbdf37..29fd37989b 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ControlFlow.cs +++ b/src/SDSL/Parsers/AST/Shader/ControlFlow.cs @@ -1,7 +1,7 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public class ForLoop : ControlFlow diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs b/src/SDSL/Parsers/AST/Shader/Literals.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Shader/Literals.cs rename to src/SDSL/Parsers/AST/Shader/Literals.cs index 3cc93b24c5..27ffde9840 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Literals.cs +++ b/src/SDSL/Parsers/AST/Shader/Literals.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public class ShaderLiteral : Expression diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs b/src/SDSL/Parsers/AST/Shader/Operations.cs similarity index 98% rename from src/Stride.Shaders/Parsers/AST/Shader/Operations.cs rename to src/SDSL/Parsers/AST/Shader/Operations.cs index 4062f2bfee..1869af3b98 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Operations.cs +++ b/src/SDSL/Parsers/AST/Shader/Operations.cs @@ -1,14 +1,14 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Directives; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Directives; +using SDSL.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static Stride.Shaders.Parsing.AST.Shader.OperatorTokenExtensions; +using static SDSL.Parsing.AST.Shader.OperatorTokenExtensions; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public abstract class Expression : ShaderTokenTyped diff --git a/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs b/src/SDSL/Parsers/AST/Shader/OperatorToken.cs similarity index 97% rename from src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs rename to src/SDSL/Parsers/AST/Shader/OperatorToken.cs index 33e1cd3292..daf9bdd956 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/OperatorToken.cs +++ b/src/SDSL/Parsers/AST/Shader/OperatorToken.cs @@ -4,7 +4,7 @@ using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public enum AssignOpToken { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs b/src/SDSL/Parsers/AST/Shader/ShaderElements.cs similarity index 96% rename from src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs rename to src/SDSL/Parsers/AST/Shader/ShaderElements.cs index 6bb07a6d05..1f17b37df5 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderElements.cs +++ b/src/SDSL/Parsers/AST/Shader/ShaderElements.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public class StructField : ShaderToken { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs b/src/SDSL/Parsers/AST/Shader/ShaderMethods.cs similarity index 96% rename from src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs rename to src/SDSL/Parsers/AST/Shader/ShaderMethods.cs index 7cd4a0c4bf..e0d4fd8453 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderMethods.cs +++ b/src/SDSL/Parsers/AST/Shader/ShaderMethods.cs @@ -1,8 +1,8 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.ThreeAddress; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs b/src/SDSL/Parsers/AST/Shader/ShaderProgram.cs similarity index 92% rename from src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs rename to src/SDSL/Parsers/AST/Shader/ShaderProgram.cs index 0ec2ab76c1..8fd00dac55 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderProgram.cs +++ b/src/SDSL/Parsers/AST/Shader/ShaderProgram.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public class ShaderProgram : ShaderToken { diff --git a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs b/src/SDSL/Parsers/AST/Shader/ShaderToken.cs similarity index 96% rename from src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs rename to src/SDSL/Parsers/AST/Shader/ShaderToken.cs index 3343cced3b..d6631e78cc 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/ShaderToken.cs +++ b/src/SDSL/Parsers/AST/Shader/ShaderToken.cs @@ -1,13 +1,13 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.Parsing.Grammars.Expression; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.Grammars.Expression; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public abstract class ShaderToken diff --git a/src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs b/src/SDSL/Parsers/AST/Shader/SpirvTypes.cs similarity index 87% rename from src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs rename to src/SDSL/Parsers/AST/Shader/SpirvTypes.cs index 7197c3bbe3..6337870608 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/SpirvTypes.cs +++ b/src/SDSL/Parsers/AST/Shader/SpirvTypes.cs @@ -2,7 +2,7 @@ using static Spv.Generator.Instruction; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; diff --git a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs b/src/SDSL/Parsers/AST/Shader/Statements.cs similarity index 97% rename from src/Stride.Shaders/Parsers/AST/Shader/Statements.cs rename to src/SDSL/Parsers/AST/Shader/Statements.cs index 587e39dee1..feb73e23c9 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/Statements.cs +++ b/src/SDSL/Parsers/AST/Shader/Statements.cs @@ -1,16 +1,16 @@ using Eto.Parse; using Spv.Generator; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.Spirv; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.Spirv; +using SDSL.ThreeAddress; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public abstract class Statement : ShaderTokenTyped diff --git a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs b/src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs similarity index 97% rename from src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs rename to src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs index 562ad15932..73e52b5e02 100644 --- a/src/Stride.Shaders/Parsers/AST/Shader/UnaryLiterals.cs +++ b/src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs @@ -1,12 +1,12 @@ using Eto.Parse; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing.AST.Shader; +namespace SDSL.Parsing.AST.Shader; public class UnaryExpression : Expression diff --git a/src/Stride.Shaders/Parsers/DirectivePreprocessor.cs b/src/SDSL/Parsers/DirectivePreprocessor.cs similarity index 90% rename from src/Stride.Shaders/Parsers/DirectivePreprocessor.cs rename to src/SDSL/Parsers/DirectivePreprocessor.cs index af7eac1a78..ae249ad53f 100644 --- a/src/Stride.Shaders/Parsers/DirectivePreprocessor.cs +++ b/src/SDSL/Parsers/DirectivePreprocessor.cs @@ -1,14 +1,14 @@ -using Stride.Shaders.Parsing.AST.Directives; -using Stride.Shaders.Parsing.Grammars.Comments; -using Stride.Shaders.Parsing.Grammars.Directive; -using Stride.Shaders.Parsing.Grammars.Macros; +using SDSL.Parsing.AST.Directives; +using SDSL.Parsing.Grammars.Comments; +using SDSL.Parsing.Grammars.Directive; +using SDSL.Parsing.Grammars.Macros; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Stride.Shaders.Parsing; +namespace SDSL.Parsing; public class DirectivePreprocessor { diff --git a/src/Stride.Shaders/Parsers/ExpressionParser.cs b/src/SDSL/Parsers/ExpressionParser.cs similarity index 60% rename from src/Stride.Shaders/Parsers/ExpressionParser.cs rename to src/SDSL/Parsers/ExpressionParser.cs index 58f0b5b276..4261bead8c 100644 --- a/src/Stride.Shaders/Parsers/ExpressionParser.cs +++ b/src/SDSL/Parsers/ExpressionParser.cs @@ -1,13 +1,13 @@ -namespace Stride.Shaders.Parsing; +namespace SDSL.Parsing; using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.Grammars; -using Stride.Shaders.Parsing.Grammars.Comments; -using Stride.Shaders.Parsing.Grammars.Directive; -using Stride.Shaders.Parsing.Grammars.Expression; -using Stride.Shaders.Parsing.Grammars.SDSL; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.Grammars; +using SDSL.Parsing.Grammars.Comments; +using SDSL.Parsing.Grammars.Directive; +using SDSL.Parsing.Grammars.Expression; +using SDSL.Parsing.Grammars.SDSL; using System.Text; public class ExpressionParser { diff --git a/src/Stride.Shaders/Parsers/Grammars/CommentGrammar.cs b/src/SDSL/Parsers/Grammars/CommentGrammar.cs similarity index 93% rename from src/Stride.Shaders/Parsers/Grammars/CommentGrammar.cs rename to src/SDSL/Parsers/Grammars/CommentGrammar.cs index dc50dde5eb..b990a2f84b 100644 --- a/src/Stride.Shaders/Parsers/Grammars/CommentGrammar.cs +++ b/src/SDSL/Parsers/Grammars/CommentGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Comments; +namespace SDSL.Parsing.Grammars.Comments; public class CommentGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs index 6cb3b98a2d..5b3e02cbec 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs index 07916cf6b2..6b04544a1f 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public SequenceParser IfDirective = new(){Name = "IfDirective"}; diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs index 3298dec9e3..0d01b69db3 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs @@ -1,7 +1,7 @@ using Eto.Parse; using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs similarity index 87% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs index 904e5d1b08..4d09d19f0f 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs similarity index 97% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs index f851ca6ba1..94f31963da 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs @@ -4,7 +4,7 @@ using EtoParser = Eto.Parse.Parser; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { AlternativeParser IntegerSuffix = new(); diff --git a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs similarity index 96% rename from src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs rename to src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs index eee7e85528..a801098796 100644 --- a/src/Stride.Shaders/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Directive; +namespace SDSL.Parsing.Grammars.Directive; public partial class DirectiveGrammar : Grammar { public AlternativeParser IncOperators = new(); diff --git a/src/Stride.Shaders/Parsers/Grammars/ExpressionGrammar.cs b/src/SDSL/Parsers/Grammars/ExpressionGrammar.cs similarity index 68% rename from src/Stride.Shaders/Parsers/Grammars/ExpressionGrammar.cs rename to src/SDSL/Parsers/Grammars/ExpressionGrammar.cs index 8886514473..78a3b552d8 100644 --- a/src/Stride.Shaders/Parsers/Grammars/ExpressionGrammar.cs +++ b/src/SDSL/Parsers/Grammars/ExpressionGrammar.cs @@ -1,10 +1,10 @@ using Eto.Parse; using Eto.Parse.Parsers; -using Stride.Shaders.Parsing.Grammars.SDSL; +using SDSL.Parsing.Grammars.SDSL; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Expression; +namespace SDSL.Parsing.Grammars.Expression; public class ExpressionGrammar : SDSLGrammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/MacroGrammar.cs b/src/SDSL/Parsers/Grammars/MacroGrammar.cs similarity index 91% rename from src/Stride.Shaders/Parsers/Grammars/MacroGrammar.cs rename to src/SDSL/Parsers/Grammars/MacroGrammar.cs index cb17333f29..14d09ad3c7 100644 --- a/src/Stride.Shaders/Parsers/Grammars/MacroGrammar.cs +++ b/src/SDSL/Parsers/Grammars/MacroGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.Macros; +namespace SDSL.Parsing.Grammars.Macros; public class MacroGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs b/src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs rename to src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs index 3a47ea21ee..4b85df3c12 100644 --- a/src/Stride.Shaders/Parsers/Grammars/NativeTypeGrammar.cs +++ b/src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs @@ -3,7 +3,7 @@ using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.NativeType; +namespace SDSL.Parsing.Grammars.NativeType; public class NativeTypeGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs index 645c6a2512..e3140799b5 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ShaderValueDeclaration = new() { Name = "ShaderValueDeclaration" }; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs similarity index 99% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs index da2f4529c1..061bd8c65a 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs index 01c87bfa04..18691a6502 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser IfDirective = new(); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs similarity index 99% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs index d9aff5eb14..c01a390e0b 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser TermExpression = new(){Name = "TermExpression"}; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs similarity index 97% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs index 85fb1e132a..86fdbb7b79 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs @@ -3,7 +3,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { AlternativeParser IntegerSuffix = new() { Name = "Suffix"}; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs index 592b20f316..98fbfaff43 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ParameterList = new() {Name = "ParameterList"}; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs index f8d8347411..f27fb5a8ea 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public AlternativeParser Declarations = new(); diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs similarity index 96% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs index 70c4173f69..a0392c11d1 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser ControlFlow = new() { Name = "ControlFlow" }; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs similarity index 97% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs index 8ae998a1f4..bcfd8183b2 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs index 8ca2c94250..4fd3337cb8 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SequenceParser Attribute = new() { Name = "Attribute" }; diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs similarity index 99% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs index e98f6a6293..fffdb52465 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs similarity index 99% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs index 20e9de2b4c..f11639ea37 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs similarity index 93% rename from src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs rename to src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs index 83d5b48bcc..479b8b3164 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs +++ b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public partial class SDSLGrammar : Grammar { public SDSLGrammar() : base("sdsl") diff --git a/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs b/src/SDSL/Parsers/Grammars/SDSLMixinReader.cs similarity index 98% rename from src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs rename to src/SDSL/Parsers/Grammars/SDSLMixinReader.cs index c13fedda24..84f47a1e80 100644 --- a/src/Stride.Shaders/Parsers/Grammars/SDSLMixinReader.cs +++ b/src/SDSL/Parsers/Grammars/SDSLMixinReader.cs @@ -2,7 +2,7 @@ using Eto.Parse.Parsers; using static Eto.Parse.Terminals; -namespace Stride.Shaders.Parsing.Grammars.SDSL; +namespace SDSL.Parsing.Grammars.SDSL; public class SDSLMixinReader : SDSLGrammar { public override void CreateAll() diff --git a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs b/src/SDSL/Parsers/ShaderMixinParser.cs similarity index 93% rename from src/Stride.Shaders/Parsers/ShaderMixinParser.cs rename to src/SDSL/Parsers/ShaderMixinParser.cs index 6d54a7a261..175291a380 100644 --- a/src/Stride.Shaders/Parsers/ShaderMixinParser.cs +++ b/src/SDSL/Parsers/ShaderMixinParser.cs @@ -1,13 +1,13 @@ -namespace Stride.Shaders.Parsing; +namespace SDSL.Parsing; using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shaders.Parsing.AST.Directives; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.Grammars; -using Stride.Shaders.Parsing.Grammars.Comments; -using Stride.Shaders.Parsing.Grammars.Directive; -using Stride.Shaders.Parsing.Grammars.SDSL; +using SDSL.Parsing.AST.Directives; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.Grammars; +using SDSL.Parsing.Grammars.Comments; +using SDSL.Parsing.Grammars.Directive; +using SDSL.Parsing.Grammars.SDSL; using System.Text; using CppNet; diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Operators.cs b/src/SDSL/Parsers/ThreeAddress/Operators.cs similarity index 92% rename from src/Stride.Shaders/Parsers/ThreeAddress/Operators.cs rename to src/SDSL/Parsers/ThreeAddress/Operators.cs index 4e99cc7918..662f136ef0 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Operators.cs +++ b/src/SDSL/Parsers/ThreeAddress/Operators.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.ThreeAddress; +namespace SDSL.ThreeAddress; public enum AssignOperator : byte { diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs b/src/SDSL/Parsers/ThreeAddress/Registers.cs similarity index 98% rename from src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs rename to src/SDSL/Parsers/ThreeAddress/Registers.cs index 3b8eab622b..f0dd5a89e5 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Registers.cs +++ b/src/SDSL/Parsers/ThreeAddress/Registers.cs @@ -1,6 +1,6 @@ using System.Text; -namespace Stride.Shaders.ThreeAddress; +namespace SDSL.ThreeAddress; public abstract class Register diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs b/src/SDSL/Parsers/ThreeAddress/Snippet.Lowering.cs similarity index 96% rename from src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs rename to src/SDSL/Parsers/ThreeAddress/Snippet.Lowering.cs index 13643ab63a..c32b77c974 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.Lowering.cs +++ b/src/SDSL/Parsers/ThreeAddress/Snippet.Lowering.cs @@ -1,11 +1,11 @@ using Stride.Core.Extensions; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; -using Stride.Shaders.Spirv; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; +using SDSL.Spirv; +using SDSL.ThreeAddress; using System.Reflection.Metadata.Ecma335; -namespace Stride.Shaders.ThreeAddress; +namespace SDSL.ThreeAddress; public partial class TAC { diff --git a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs b/src/SDSL/Parsers/ThreeAddress/Snippet.cs similarity index 92% rename from src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs rename to src/SDSL/Parsers/ThreeAddress/Snippet.cs index 8fefa4f61f..6303e9ab30 100644 --- a/src/Stride.Shaders/Parsers/ThreeAddress/Snippet.cs +++ b/src/SDSL/Parsers/ThreeAddress/Snippet.cs @@ -1,7 +1,7 @@ -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader; +using SDSL.Parsing.AST.Shader.Analysis; -namespace Stride.Shaders.ThreeAddress; +namespace SDSL.ThreeAddress; public partial class TAC { SymbolTable symbols; diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/SDSL/SDSL.csproj similarity index 92% rename from src/Stride.Shaders/Stride.Shaders.csproj rename to src/SDSL/SDSL.csproj index 7edb8b3176..639ceddfe4 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/SDSL/SDSL.csproj @@ -11,7 +11,7 @@ - net6.0 + net7.0 enable enable true diff --git a/src/Stride.Shaders/ShaderLoader.cs b/src/SDSL/ShaderLoader.cs similarity index 91% rename from src/Stride.Shaders/ShaderLoader.cs rename to src/SDSL/ShaderLoader.cs index 299775f110..81ee23d256 100644 --- a/src/Stride.Shaders/ShaderLoader.cs +++ b/src/SDSL/ShaderLoader.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders; +namespace SDSL; public class ShaderLoader { diff --git a/src/Stride.Shaders/ShaderSourceManager.cs b/src/SDSL/ShaderSourceManager.cs similarity index 98% rename from src/Stride.Shaders/ShaderSourceManager.cs rename to src/SDSL/ShaderSourceManager.cs index 0e78a21b63..bbba7561ea 100644 --- a/src/Stride.Shaders/ShaderSourceManager.cs +++ b/src/SDSL/ShaderSourceManager.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; -namespace Stride.Shaders; +namespace SDSL; public class ShaderSourceManager { diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs index 0e1a3c1d5b..66a6c59944 100644 --- a/src/SDSLParserExample/Program.cs +++ b/src/SDSLParserExample/Program.cs @@ -1,18 +1,18 @@ using Eto.Parse; using Eto.Parse.Grammars; -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.Grammars.Expression; +using SDSL.Parsing; +using SDSL.Parsing.Grammars.Expression; using System.Diagnostics; using System.Linq; using Stride.Core.Shaders.Grammar; using Stride.Core.Shaders; using Stride.Core.Shaders.Parser; using Stride.Core.Shaders.Grammar.Stride; -using Stride.Shaders.Parsing.AST.Shader; -using Stride.Shaders.Mixer; -using Stride.Shaders.ThreeAddress; +using SDSL.Parsing.AST.Shader; +using SDSL.Mixer; +using SDSL.ThreeAddress; using Stride.Shaders; -using Stride.Shaders.Parsing.AST.Shader.Analysis; +using SDSL.Parsing.AST.Shader.Analysis; using System.Text; using SPIRVCross; using static SPIRVCross.SPIRV; diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj index 8fabdc3f4b..031e2cf1a1 100644 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ b/src/SDSLParserExample/SDSLParserExample.csproj @@ -15,7 +15,7 @@ Exe - net6.0 + net7.0 enable enable true From 367fee38479fe1c4c7fa5cdbce46afd4447d0d2b Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 7 Jan 2023 18:43:36 +0100 Subject: [PATCH 0165/1182] update deps --- src/Eto.Parse | 2 +- src/Spv.Generator | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Eto.Parse b/src/Eto.Parse index 06eb73f953..44e97733e6 160000 --- a/src/Eto.Parse +++ b/src/Eto.Parse @@ -1 +1 @@ -Subproject commit 06eb73f953d8e51ae6e85432dd06042cb2c99321 +Subproject commit 44e97733e688a3972ac97b4f6b1d12ef31c0ae43 diff --git a/src/Spv.Generator b/src/Spv.Generator index 3fb0e5b035..a5b84ae7ee 160000 --- a/src/Spv.Generator +++ b/src/Spv.Generator @@ -1 +1 @@ -Subproject commit 3fb0e5b0353495fc3a57874b5998f4d15d82d187 +Subproject commit a5b84ae7ee87c03a857acad5ef0350886fe0e5a5 From 736cdccd0eac8a937e035e85123c2f0984ec6b8b Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 7 Jan 2023 23:25:26 +0100 Subject: [PATCH 0166/1182] update benchmarks --- SDSLParser.sln | 7 + ...SL.Benchmarks.ParserBench-report-github.md | 13 +- .../SDSL.Benchmarks.ParserBench-report.csv | 4 +- .../SDSL.Benchmarks.ParserBench-report.html | 13 +- src/SDSL.Benchmarks/ParserBench.cs | 15 +- src/SDSLParserExample/Program.cs | 486 +++++++++--------- src/SDSLParserExample/SDSL/shader2.sdsl | 8 +- .../SDSLParserExample.csproj | 2 +- 8 files changed, 286 insertions(+), 262 deletions(-) diff --git a/SDSLParser.sln b/SDSLParser.sln index 5197fc742d..ee6be8d63d 100644 --- a/SDSLParser.sln +++ b/SDSLParser.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSL.Benchmarks", "src\SDSL EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Eto.Parse", "src\Eto.Parse\Eto.Parse\Eto.Parse.csproj", "{490CA54A-75FC-431F-A2C2-803F59576E88}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDSLParserExample", "src\SDSLParserExample\SDSLParserExample.csproj", "{6B241EE2-A96F-4FFC-B559-B0799F290E26}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -47,6 +49,10 @@ Global {490CA54A-75FC-431F-A2C2-803F59576E88}.Debug|Any CPU.Build.0 = Debug|Any CPU {490CA54A-75FC-431F-A2C2-803F59576E88}.Release|Any CPU.ActiveCfg = Release|Any CPU {490CA54A-75FC-431F-A2C2-803F59576E88}.Release|Any CPU.Build.0 = Release|Any CPU + {6B241EE2-A96F-4FFC-B559-B0799F290E26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B241EE2-A96F-4FFC-B559-B0799F290E26}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B241EE2-A96F-4FFC-B559-B0799F290E26}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B241EE2-A96F-4FFC-B559-B0799F290E26}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -58,6 +64,7 @@ Global {09D8574D-6452-40E2-9724-9C58F446D862} = {5F88D871-B760-4857-BD74-296B07778B15} {A2559EFF-A034-4B58-AF90-A525E32DF61C} = {5F88D871-B760-4857-BD74-296B07778B15} {490CA54A-75FC-431F-A2C2-803F59576E88} = {5F88D871-B760-4857-BD74-296B07778B15} + {6B241EE2-A96F-4FFC-B559-B0799F290E26} = {5F88D871-B760-4857-BD74-296B07778B15} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4AF186D8-C065-4788-835B-3C253D65EAE0} diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md index 81c481c43a..83aec92322 100644 --- a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report-github.md @@ -3,12 +3,13 @@ BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963) AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx, 1 CPU, 8 logical and 4 physical cores .NET SDK=7.0.101 - [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 + [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2 +Job=MediumRun Toolchain=InProcessNoEmitToolchain IterationCount=15 +LaunchCount=2 WarmupCount=10 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | -|------------ |---------:|---------:|---------:|--------:|--------:|----------:| -| StrideParse | 416.2 μs | 13.24 μs | 38.19 μs | 88.8672 | 26.8555 | 246.9 KB | -| EtoParse | 418.3 μs | 11.48 μs | 33.13 μs | 79.5898 | - | 163.28 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | +|------------ |---------:|---------:|---------:|---------:|--------:|----------:| +| StrideParse | 535.8 μs | 48.59 μs | 69.68 μs | 102.0508 | 33.6914 | 306.85 KB | +| EtoParse | 430.2 μs | 18.54 μs | 27.17 μs | 78.1250 | - | 161.17 KB | diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv index 34a5eec456..396303526a 100644 --- a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.csv @@ -1,3 +1,3 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Allocated -StrideParse,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,416.2 μs,13.24 μs,38.19 μs,88.8672,26.8555,246.9 KB -EtoParse,DefaultJob,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,Default,16,Default,418.3 μs,11.48 μs,33.13 μs,79.5898,-,163.28 KB +StrideParse,MediumRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,InProcessNoEmitToolchain,Default,Default,15,Default,2,Default,Default,Default,Default,Default,Default,16,10,535.8 μs,48.59 μs,69.68 μs,102.0508,33.6914,306.85 KB +EtoParse,MediumRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 7.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,InProcessNoEmitToolchain,Default,Default,15,Default,2,Default,Default,Default,Default,Default,Default,16,10,430.2 μs,18.54 μs,27.17 μs,78.1250,-,161.17 KB diff --git a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html index 4d10d13030..1edde705be 100644 --- a/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html +++ b/src/SDSL.Benchmarks/BenchmarkDotNet.Artifacts/results/SDSL.Benchmarks.ParserBench-report.html @@ -2,7 +2,7 @@ -SDSL.Benchmarks.ParserBench-20230107-181725 +SDSL.Benchmarks.ParserBench-20230107-232203 - - -

-BenchmarkDotNet=v0.13.3, OS=Windows 11 (10.0.22621.963)
-AMD Ryzen 5 3500U with Radeon Vega Mobile Gfx, 1 CPU, 8 logical and 4 physical cores
-.NET SDK=7.0.101
-  [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
-
-
Job=MediumRun  Toolchain=InProcessNoEmitToolchain  IterationCount=15  
-LaunchCount=2  WarmupCount=10  
-
- - - - - - -
MethodMeanErrorStdDevGen0Gen1Allocated
StrideParse535.8 μs48.59 μs69.68 μs102.050833.6914306.85 KB
EtoParse430.2 μs18.54 μs27.17 μs78.1250-161.17 KB
- - diff --git a/src/SDSL.Benchmarks/ParserBench.cs b/src/SDSL.Benchmarks/ParserBench.cs deleted file mode 100644 index 34b501cd82..0000000000 --- a/src/SDSL.Benchmarks/ParserBench.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using BenchmarkDotNet; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Toolchains.InProcess.NoEmit; -using Stride.Core.Shaders.Grammar.Stride; -using Stride.Core.Shaders.Parser; - -namespace SDSL.Benchmarks; - -public class AntiVirusFriendlyConfig : ManualConfig -{ - public AntiVirusFriendlyConfig() - { - AddJob(Job.MediumRun - .WithToolchain(InProcessNoEmitToolchain.Instance)); - } -} - -[Config(typeof(AntiVirusFriendlyConfig))] -[MemoryDiagnoser] -public class ParserBench -{ - public string shaderText = File.ReadAllText(@"C:\Users\kafia\source\repos\SDSLParser\src\SDSL.Benchmarks\shader.sdsl"); - ShaderParser strideParser = ShaderParser.GetParser(); - Parsing.ShaderMixinParser etoParser = new(); - - [Benchmark] - public void StrideParse() - { - strideParser.PreProcessAndParse(shaderText, ""); - } - [Benchmark] - public void EtoParse() - { - etoParser.Parse(shaderText); - } -} diff --git a/src/SDSL.Benchmarks/Program.cs b/src/SDSL.Benchmarks/Program.cs deleted file mode 100644 index c6709bf5e7..0000000000 --- a/src/SDSL.Benchmarks/Program.cs +++ /dev/null @@ -1,5 +0,0 @@ -// See https://aka.ms/new-console-template for more information -using BenchmarkDotNet.Running; -using SDSL.Benchmarks; - -BenchmarkRunner.Run(); diff --git a/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj b/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj deleted file mode 100644 index 1abd23946d..0000000000 --- a/src/SDSL.Benchmarks/SDSL.Benchmarks.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - - - - - - - - - - - diff --git a/src/SDSL.Benchmarks/shader.sdsl b/src/SDSL.Benchmarks/shader.sdsl deleted file mode 100644 index 060e745d1d..0000000000 --- a/src/SDSL.Benchmarks/shader.sdsl +++ /dev/null @@ -1,38 +0,0 @@ -shader SingleShader { - - struct Position { - float x; - float y; - float z; - }; - - stage stream float4 triInput; - - stage stream float4 ShadingPosition : SV_Position; - - stage stream bool IsFrontFace : SV_IsFrontFace; - - stage stream float4 ColorTarget : SV_Target0; - stage stream float4 ColorTarget1 : SV_Target1; - stage stream float4 ColorTarget2 : SV_Target2; - stage stream float4 ColorTarget3 : SV_Target3; - stage stream float4 ColorTarget4 : SV_Target4; - stage stream float4 ColorTarget5 : SV_Target5; - stage stream float4 ColorTarget6 : SV_Target6; - stage stream float4 ColorTarget7 : SV_Target7; - - // Default DEPTH output for PS shader - stage stream float Depth : SV_Depth; - stage stream float DepthGreater : SV_DepthGreater; // Special output after PS - stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS - - stage stream uint InstanceID : SV_InstanceID; - - - void VSMain() - { - float4 a = float4(0); - streams.ShadingPosition = a; - streams.ColorTarget = float3(0); - } -}; \ No newline at end of file diff --git a/src/SDSL.Test/ASTTypeChecking.cs b/src/SDSL.Test/ASTTypeChecking.cs deleted file mode 100644 index e562ce96b0..0000000000 --- a/src/SDSL.Test/ASTTypeChecking.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Xunit; -using System.Linq; -using SDSL.Parsing; -using System.Collections.Generic; -using SDSL.Parsing.AST.Shader.Analysis; -using SDSL.Parsing.AST.Shader; -using SDSL.ThreeAddress; - -namespace SDSL.Parsing.Test; - -public class ASTTypeChecking -{ - [Fact] - public void TypeCheckIntWithFloatCastedToInt() - { - var o = - new Operation - { - Left = new NumberLiteral { Value = 5L }, - Right = new NumberLiteral { Value = 6L }, - Op = OperatorToken.Plus - }; - - var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = new ScalarType("int"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; - symbols.PushVar(s); - var o2 = - new Operation - { - Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("float") }, - Op = OperatorToken.Plus - }; - var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; - symbols.PushVar(s2); - Assert.Equal(new ScalarType("int"), s2.InferredType); - - } - [Fact] - public void TypeCheckInt() - { - var o = - new Operation - { - Left = new NumberLiteral { Value = 5L }, - Right = new NumberLiteral { Value = 6L }, - Op = OperatorToken.Plus - }; - - var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = new ScalarType("int"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; - symbols.PushVar(s); - var o2 = - new Operation - { - Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("int") }, - Op = OperatorToken.Plus - }; - var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; - symbols.PushVar(s2); - Assert.Equal(new ScalarType("int"), s2.InferredType); - - } - [Fact] - public void TypeCheckFloat() - { - var o = - new Operation - { - Left = new NumberLiteral { Value = 5L }, - Right = new NumberLiteral { Value = 6L }, - Op = OperatorToken.Plus - }; - - var symbols = new SymbolTable(); - var s = new DeclareAssign() { TypeName = new ScalarType("float"), VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; - symbols.PushVar(s); - var o2 = - new Operation - { - Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = new ScalarType("int") }, - Op = OperatorToken.Plus - }; - var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; - symbols.PushVar(s2); - Assert.Equal(new ScalarType("float"), s2.InferredType); - } -} \ No newline at end of file diff --git a/src/SDSL.Test/BasicExpressionParsing.cs b/src/SDSL.Test/BasicExpressionParsing.cs deleted file mode 100644 index d22d5c268b..0000000000 --- a/src/SDSL.Test/BasicExpressionParsing.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Xunit; -using System.Linq; -using SDSL.Parsing; -using Eto.Parse; -using Eto.Parse.Parsers; -using System.Collections.Generic; - -namespace SDSL.Parsing.Test; - -public class BasicExpressionParsing -{ - ShaderMixinParser parser; - public BasicExpressionParsing() - { - parser = new(); - } - [Fact] - public void TestTerms() - { - parser.Grammar.Using(parser.Grammar.TermExpression); - List matches = new(){ - parser.TestParse("5"), - parser.TestParse("5l"), - parser.TestParse("5u"), - parser.TestParse("5f"), - parser.TestParse(".5"), - parser.TestParse("5f"), - parser.TestParse(".5d"), - parser.TestParse("my_var"), - parser.TestParse("\"Hello World\"") - }; - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - [Fact] - public void TestPostfix() - { - parser.Grammar.Using(parser.Grammar.PostfixExpression.Then(";")); - List matches = new(){ - parser.TestParse("my_var++;"), - parser.TestParse("my_var.a;"), - parser.TestParse("my_var[0];"), - parser.TestParse("my_var[a];"), - parser.TestParse("my_var.a[0];"), - parser.TestParse("my_var.a[b];"), - parser.TestParse("my_var.a[b]++;"), - parser.TestParse("my_var.a[0].c;"), - parser.TestParse("my_var.a[b].c;"), - parser.TestParse("my_var.a[b].c++;"), - parser.TestParse("my_var.a[b].c[5].b.e[7][5]++;"), - - }; - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - - [Fact] - public void TestUnary() - { - parser.Grammar.Using(parser.Grammar.UnaryExpression.Then(";")); - List matches = new() - { - parser.TestParse("++b;"), - parser.TestParse("++my_var.a;"), - parser.TestParse("++my_var[0];"), - parser.TestParse("++my_var[a];"), - parser.TestParse("++my_var.a[0];"), - parser.TestParse("++my_var.a[b];"), - parser.TestParse("++my_var.a[0].c;"), - parser.TestParse("++my_var.a[b].c;"), - parser.TestParse("++my_var.a[b].c[5].b.e[7][5];"), - }; - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - } - - [Fact] - public void TestCast() - { - parser.Grammar.Using(parser.Grammar.CastExpression.Then(";")); - List matches = new() - { - parser.TestParse("(float)++my_var;"), - parser.TestParse("(float)++my_var.a;"), - parser.TestParse("(float4)my_var[0]++;"), - parser.TestParse("(float4x4)++my_var[a];"), - parser.TestParse("(MyStruct)++my_var.a[0];"), - parser.TestParse("(MyStruct)my_var.a[b]++;"), - parser.TestParse("(MyStruct)++my_var.a[0].c;"), - parser.TestParse("(MyStruct)my_var.a[b].c++;"), - parser.TestParse("(MyStruct)++my_var.a[b].c[5].b.e[7][5];"), - }; - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - } -} \ No newline at end of file diff --git a/src/SDSL.Test/OperationExpressionParsing.cs b/src/SDSL.Test/OperationExpressionParsing.cs deleted file mode 100644 index 2b2270ed99..0000000000 --- a/src/SDSL.Test/OperationExpressionParsing.cs +++ /dev/null @@ -1,188 +0,0 @@ -using Xunit; -using System.Linq; -using SDSL.Parsing; -using Eto.Parse; -using Eto.Parse.Parsers; -using System.Collections.Generic; - -namespace SDSL.Parsing.Test; - -public class OperationExpressionParsing -{ - ShaderMixinParser parser; - public OperationExpressionParsing() - { - parser = new(); - } - [Fact] - public void TestMul() - { - parser.Grammar.Using(parser.Grammar.MulExpression.Then(";")); - List matches = new() - { - parser.TestParse("5*3;"), - parser.TestParse("5*3*4;"), - parser.TestParse("5 * (float)++my_var;"), - parser.TestParse("5* (float)++my_var.a;"), - parser.TestParse("(float4)my_var[0]++ * 2;"), - parser.TestParse("(float4x4)++my_var[a]* 2;"), - parser.TestParse("(MyStruct)++my_var.a[0] * 2;"), - parser.TestParse("2 * 3 * (MyStruct)my_var.a[b]++;"), - parser.TestParse("(MyStruct)++my_var.a[0].c *4* 5;"), - parser.TestParse("(float)my_value * (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.TestParse("(float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5];"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - [Fact] - public void TestSum() - { - parser.Grammar.Using(parser.Grammar.SumExpression.Then(";")); - List matches = new() - { - parser.TestParse("5+3;"), - parser.TestParse("a + b++ * 3 + 4;"), - parser.TestParse("5+3+4;"), - parser.TestParse("3 + 5 * (float)++my_var;"), - parser.TestParse("3 + 5* (float)++my_var.a;"), - parser.TestParse("a + (float4)my_var[0]++ * 2 + 4;"), - parser.TestParse("my_otherVar + (float4x4)++my_var[a]* 2 - 2;"), - parser.TestParse("(float)1 + (MyStruct)++my_var.a[0] * 2;"), - parser.TestParse("2 * 3 + (MyStruct)my_var.a[b]++;"), - parser.TestParse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5;"), - parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.TestParse("2 + (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] + ++b;"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - - [Fact] - public void TestShift() - { - parser.Grammar.Using(parser.Grammar.ShiftExpression.Then(";")); - List matches = new() - { - parser.TestParse("5 << 5+3;"), - parser.TestParse("a + b++ * 3 << 4;"), - parser.TestParse("5 << 3 >> 4;"), - parser.TestParse("3 + 5 * (float)++my_var;"), - parser.TestParse("3 + 5* (float)++my_var.a;"), - parser.TestParse("a >> (float4)my_var[0]++ * 2 + 4;"), - parser.TestParse("my_otherVar << (float4x4)++my_var[a]* 2 - 2;"), - parser.TestParse("(float)1 + (MyStruct)++my_var.a[0] << 2;"), - parser.TestParse("2 * 3 + (MyStruct)my_var.a[b]++;"), - parser.TestParse("(MyStruct)++my_var.a[0].c + 6 + 4 * 5 >> 2;"), - parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ *(float)my_value2;"), - parser.TestParse("2 + (float)my_value << (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - - [Fact] - public void TestTestExpr() - { - parser.Grammar.Using(parser.Grammar.TestExpression.Then(";")); - List matches = new() - { - parser.TestParse("5 < 5+3;"), - parser.TestParse("a > b++ * 3 < 4;"), - parser.TestParse("5 < 3 > 4;"), - parser.TestParse("3 + 5 * (float)++my_var;"), - parser.TestParse("3 + 5 > (float)++my_var.a*2;"), - parser.TestParse("a >> (float4)my_var[0]++ * 2 + 4;"), - parser.TestParse("my_otherVar > 2;"), - parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ >(float)my_value2;"), - parser.TestParse("2 + (float)my_value < (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - [Fact] - public void TestEqualsExpr() - { - parser.Grammar.Using(parser.Grammar.EqualsExpression.Then(";")); - List matches = new() - { - parser.TestParse("true == false;"), - parser.TestParse("true != false;"), - parser.TestParse("a > b++ == 3 < 4;"), - parser.TestParse("true == 3 != 4;"), - parser.TestParse("3 == 5 * (float)++my_var;"), - parser.TestParse("3 + 5 == (float)++my_var.a*2;"), - parser.TestParse("5 == a >> (float4)my_var[0]++ * 2 + 4;"), - parser.TestParse("my_otherVar > 2;"), - parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), - parser.TestParse("2 + (float)my_value == (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] > ++b;"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - - [Fact] - public void TestBinary() - { - parser.Grammar.Using(parser.Grammar.OrExpression.Then(";")); - List matches = new() - { - parser.TestParse("5 & 4;"), - parser.TestParse("1 ^ 6;"), - parser.TestParse("1 | 6;"), - parser.TestParse("a >> b++ | 3 << 4;"), - parser.TestParse("5 ^ 3 ^ 4;"), - parser.TestParse("3 & 5 * (float)++my_var;"), - parser.TestParse("3 + 5 | (float)++my_var.a*2;"), - parser.TestParse("5 & a >> (float4)my_var[0]++ * 2 & 4;"), - parser.TestParse("my_otherVar <> 2;"), - parser.TestParse("(float)my_value + (MyStruct)my_var.a[b].c+++(float)my_value2;"), - parser.TestParse("2 ^ (float)my_value | (float)my_value * (MyStruct)++my_var.a[b].c[5].b.e[7][5] >> ++b;"), - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - [Fact] - public void TestConditional() - { - parser.Grammar.Using(parser.Grammar.ConditionalExpression.Then(";")); - List matches = new() - { - parser.TestParse("true && true;"), - parser.TestParse("true || false;"), - parser.TestParse("1 || 6;"), - parser.TestParse("a > b++ && 3 < 4;"), - parser.TestParse("true == true || 3 != 4;"), - parser.TestParse("3 || 5 * (float)++my_var;"), - parser.TestParse("3 + 5 && (float)++my_var.a*2;"), - parser.TestParse("5 == a && (float4)my_var[0]++ * 2 & 4;"), - parser.TestParse("my_otherVar > 2 &&false;"), - parser.TestParse("(float)my_value && (MyStruct)my_var.a[b].c++ !=(float)my_value2;"), - parser.TestParse("2 ^ (float)my_value | (float)my_value | (MyStruct)++my_var.a[b].c[5].b.e[7][5] && 4 == ++b;"), - parser.TestParse("true ? 5 : 8;"), - - }; - - Assert.True(matches.TrueForAll(x => !x.Errors.Any())); - - } - -} \ No newline at end of file diff --git a/src/SDSL.Test/SDSL.Test.csproj b/src/SDSL.Test/SDSL.Test.csproj deleted file mode 100644 index 69a90c4c68..0000000000 --- a/src/SDSL.Test/SDSL.Test.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - net8.0 - enable - - false - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - diff --git a/src/SDSL/Analysis/Analyzer.cs b/src/SDSL/Analysis/Analyzer.cs deleted file mode 100644 index 513497e048..0000000000 --- a/src/SDSL/Analysis/Analyzer.cs +++ /dev/null @@ -1,71 +0,0 @@ -using CommunityToolkit.HighPerformance; -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using SDSL.TAC; -using SoftTouch.Spirv; - -namespace SDSL.Analysis; - -public class Analyzer -{ - SymbolTable Table; - ErrorList Errors; - List Mixins; - - - public Analyzer() - { - Table = new(); - Errors = []; - Mixins = []; - } - - public void Analyze(ShaderProgram program) - { - // Recover all mixins and add variables and types to the symbol table - foreach (var m in program.Body.OfType()) - Table.Methods.Add(m.Name, new(Table, m)); - TypeCheck(program); - foreach(var m in program.Body.OfType()) - m.IRCode = IR.Convert(m); - } - - public void TypeCheck(ShaderProgram program) - { - foreach (var func in program.Body.OfType()) - { - Table.Variables.PushScope(); - if(func is ModuleMethod m && m.ParameterList != null) - foreach(var p in m.ParameterList) - Table.Variables.Push(new(p.Name,p.Type)); - foreach (var statement in func.Statements) - { - TypeCheck(func, statement); - } - Table.Variables.PopScope(); - - } - } - public void TypeCheck(ShaderMethod method, Statement statement) - { - if (statement is BlockStatement block) - { - Table.Variables.PushScope(); - foreach (var s in block.Statements) - TypeCheck(method, s); - Table.Variables.PopScope(); - } - else - { - if(statement is ReturnStatement rs) - rs.TypeCheck(Table, method.ReturnType); - else - statement.TypeCheck(Table, null); - if (statement is Declaration da) - Table.Variables.Push(new VariableSymbol(da.VariableName, da.TypeName ?? SymbolType.Void)); - - } - } - -} \ No newline at end of file diff --git a/src/SDSL/Analysis/ControlFlowGraph.cs b/src/SDSL/Analysis/ControlFlowGraph.cs deleted file mode 100644 index 45b0f4abb4..0000000000 --- a/src/SDSL/Analysis/ControlFlowGraph.cs +++ /dev/null @@ -1,17 +0,0 @@ -using SDSL.Parsing.AST.Shader; -using SoftTouch.Spirv.Core.Buffers; - -namespace SDSL.Analysis; - - -public record struct CFEdge(Expression Condition, CFNode Destination); - -public class CFNode() -{ - public List Code = []; - public List Outputs = []; -} -public class ControlFlowGraph() -{ - public Dictionary Graphs = []; -} \ No newline at end of file diff --git a/src/SDSL/Analysis/Errors.cs b/src/SDSL/Analysis/Errors.cs deleted file mode 100644 index 3bc15784ef..0000000000 --- a/src/SDSL/Analysis/Errors.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace SDSL.Analysis; - -using Eto.Parse; - - -public struct ErrorInfo -{ - public Match Match { get; set; } - public string Message { get; set; } - - public ErrorInfo(Match mtc, string msg) - { - Match = mtc; - Message = msg; - } -} - -public class ErrorList : List -{ - -} \ No newline at end of file diff --git a/src/SDSL/Analysis/StaticCheck.cs b/src/SDSL/Analysis/StaticCheck.cs deleted file mode 100644 index 8a1cb0ad93..0000000000 --- a/src/SDSL/Analysis/StaticCheck.cs +++ /dev/null @@ -1,22 +0,0 @@ -using SDSL.Parsing.AST.Shader.Symbols; - -namespace SDSL.Analysis; - - -public interface IStaticCheck -{ - public bool CheckStatic(SymbolTable s); -} - -public interface IStreamCheck -{ - public bool CheckStream(SymbolTable s); - public IEnumerable? GetUsedStream(); - public IEnumerable? GetAssignedStream(); - -} - -public interface IVariableCheck -{ - public void CheckVariables(SymbolTable s); -} \ No newline at end of file diff --git a/src/SDSL/Mixing/ShaderMixer.cs b/src/SDSL/Mixing/ShaderMixer.cs deleted file mode 100644 index f975f9d73a..0000000000 --- a/src/SDSL/Mixing/ShaderMixer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using SDSL.Parsing.AST.Shader; -using SoftTouch.Spirv; -using static Spv.Specification; - -namespace SDSL.Mixing; - -public static class ShaderMixer -{ - public static void Compile(ShaderProgram program) - { - var mixer = new Mixer(program.Name); - - foreach(var method in program.Body.OfType()) - { - var function = mixer.WithFunction( - method.ReturnType.Name, - method.Name, - (builder) => { - if(method.ParameterList != null) - foreach(var p in method.ParameterList) - builder.With(p.Type.Name, p.Name); - return builder; - } - ); - function.FunctionEnd(); - } - foreach (var method in program.Body.OfType()) - { - if(method is VSMainMethod vs) - { - var func = mixer - .WithEntryPoint( - ExecutionModel.Vertex, - vs.Name - ) - .FunctionStart(); - - func.FunctionEnd(); - } - } - mixer.Build(); - } -} diff --git a/src/SDSL/Parsers/AST/Directives/DirectiveToken.cs b/src/SDSL/Parsers/AST/Directives/DirectiveToken.cs deleted file mode 100644 index 0db753a49a..0000000000 --- a/src/SDSL/Parsers/AST/Directives/DirectiveToken.cs +++ /dev/null @@ -1,141 +0,0 @@ -using Eto.Parse; -using SDSL.Parsing.Grammars.Expression; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Directives; - - -public abstract class DirectiveToken -{ - public Match Match { get; set; } - public abstract Type InferredType { get; set; } - - public abstract void EvaluateMacros(Dictionary macros); - - public static DirectiveToken GetToken(Match match) - { - var tmp = match; - while (tmp.Matches.Count == 1) - tmp = tmp.Matches.First(); - - return tmp.Name switch - { - "Directives" => new Directives(tmp), - "CodeSnippet" => new CodeSnippet(tmp), - "DefineDirective" => new DefineDirective(tmp), - "IfCode" => new IfCode(tmp), - "IfDefCode" or "IfNDefCode" => new IfDefCode(tmp), - "IfDefDirective" or "IfNDefDirective" => new IfDefineDirective(tmp), - "DirectiveTernary" => new ConditionalExpression(tmp), - "DirectiveLogicalOrExpression" => LogicalOrExpression.Create(tmp), - "DirectiveLogicalAndExpression" => LogicalAndExpression.Create(tmp), - "DirectiveEqualsExpression" => EqualsExpression.Create(tmp), - "DirectiveTestExpression" => TestExpression.Create(tmp), - "DirectiveOrExpression" => OrExpression.Create(tmp), - "DirectiveXorExpression" => XorExpression.Create(tmp), - "DirectiveAndExpression" => AndExpression.Create(tmp), - "DirectiveShiftExpression" => ShiftExpression.Create(tmp), - "DirectiveSumExpression" => SumExpression.Create(tmp), - "DirectiveMulExpression" => MulExpression.Create(tmp), - "DirectiveCastExpression" => new CastExpression(tmp), - "DirectivePrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "IntegerValue" or "FloatValue" => new NumberLiteral(tmp), - "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp), - "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp), - "Boolean" => new BoolLiteral(tmp), - _ => throw new NotImplementedException() - }; - } - - public static void Evaluate(DirectiveToken token, Dictionary macros, StringBuilder code) - { - switch(token) - { - case Directives d: - foreach(var c in d.DirectiveList) - Evaluate(c, macros, code); - break; - case CodeSnippet snippet: - code.Append(snippet.Content); - break; - - case DefineDirective def: - macros.Add(def.VariableName, def.Value); - break; - - case IfDefCode ifdefcode: - if(CheckCondition(ifdefcode.If,macros)) - foreach (var c in ifdefcode.Children) - Evaluate(c, macros, code); - else - foreach (var c in ifdefcode.Children) - Evaluate(c, macros, code); - break; - - case IfCode ifCode: - if (CheckCondition(ifCode.If, macros)) - foreach (var c in ifCode.Children) - Evaluate(c, macros, code); - else - { - bool passed = false; - if (ifCode.Elifs is not null) - { - foreach (var e in ifCode.Elifs) - { - if (CheckCondition(e.Elif, macros)) - { - foreach (var c in e.Children) - Evaluate(c, macros, code); - passed = true; - break; - } - } - if (passed) - foreach (var c in ifCode.Children) - Evaluate(c, macros, code); - } - else if(!passed && ifCode.Else is not null) - foreach(var c in ifCode.Else.Children) - Evaluate(c, macros, code); - } - break; - default: - throw new NotImplementedException(""); - } - } - - public static bool CheckCondition(DirectiveToken token, Dictionary macros) - { - return token switch - { - IfDefineDirective ifDefine => ifDefine.IsDefined && macros.ContainsKey(ifDefine.Name), - IfDirective ifd => EvaluateExpression(ifd.Condition,macros), - ElifDirective elifd => EvaluateExpression(elifd.Condition,macros), - _ => throw new NotImplementedException("") - }; - } - - public static bool EvaluateExpression(DirectiveToken expr, Dictionary macros) - { - return expr switch - { - BoolLiteral b => b.Value, - Operation o => EvaluateOperation(o,macros), - _ => throw new Exception("Couldn't evaluate expression") - }; - } - private static bool EvaluateOperation(Operation operation, Dictionary macros) - { - operation.EvaluateMacros(macros); - return operation.ProjectConstant() switch - { - BoolLiteral b => b.Value, - _ => throw new Exception("Couldn't evaluate operation") - }; - } -} diff --git a/src/SDSL/Parsers/AST/Directives/Directives.cs b/src/SDSL/Parsers/AST/Directives/Directives.cs deleted file mode 100644 index 89b105d976..0000000000 --- a/src/SDSL/Parsers/AST/Directives/Directives.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Directives; - -public class DirectiveFlow : DirectiveToken -{ - public override Type InferredType { get => typeof(void); set { } } - - public override void EvaluateMacros(Dictionary macros) - { - } -} - -public class Directives : DirectiveFlow -{ - public IEnumerable DirectiveList { get; set; } - public Directives(Match m) - { - Match = m; - DirectiveList = m.Matches.Select(GetToken); - } -} - -public class CodeSnippet: DirectiveFlow -{ - public string Content { get; set; } - - public CodeSnippet(Match m) - { - Match = m; - Content = m.StringValue; - } -} - -public class DefineDirective : DirectiveFlow -{ - public string VariableName { get; set; } - public DirectiveToken Value { get; set; } - - public DefineDirective(Match m) - { - Match = m; - VariableName = m.Matches[0].StringValue; - if(m.Matches.Count == 2) - Value = GetToken(m.Matches[1]); - } -} - -public class IfDefineDirective : DirectiveFlow -{ - public bool IsDefined { get; set; } - public string Name { get; set; } - - public IfDefineDirective(Match m) - { - Match = m; - IsDefined = m.Matches[0].StringValue == "ifdefine"; - Name = m.Matches[1].StringValue; - } -} - -public class IfDirective : DirectiveFlow -{ - public DirectiveToken Condition { get; set; } - - public IfDirective(Match m) - { - Match = m; - Condition = GetToken(m.Matches[1]); - } -} - -public class ElifDirective : DirectiveFlow -{ - public DirectiveToken Condition { get; set; } - - public ElifDirective(Match m) - { - Match = m; - Condition = GetToken(m.Matches[1]); - } -} - -public class ElseCode : DirectiveFlow -{ - public IEnumerable Children { get; set; } - public ElseCode(Match m) - { - Match = m; - Children = m["Children"].Matches.Select(GetToken); - } -} - -public class IfCode : DirectiveFlow -{ - public IfDirective If { get; set; } - public IEnumerable Children { get; set; } - public IEnumerable Elifs { get; set; } - public ElseCode Else { get; set; } - - - - public IfCode(Match m) - { - Match = m; - If = new IfDirective(m["IfDirective"]); - Children = m["Children"].Matches.Select(GetToken); - if(m.Matches.Any(x => x.Name == "ElifCode")) - Elifs = m.Matches.Where(x => x.Name == "ElifCode").Select(x => new ElifCode(x)); - if(m.Matches.Any(x => x.Name == "ElseCode")) - Else = new ElseCode(m["ElseCode"]); - } -} - -public class IfDefCode : DirectiveFlow -{ - public IfDefineDirective If { get; set; } - public IEnumerable Children { get; set; } - public ElseCode Else { get; set; } - - - - public IfDefCode(Match m) - { - Match = m; - If = new IfDefineDirective(m["IfDefDirective"]); - Children = m["Children"].Matches.Select(GetToken); - if (m.Matches.Any(x => x.Name == "ElseCode")) - Else = new ElseCode(m["ElseCode"]); - } -} - -public class ElifCode : DirectiveFlow -{ - public ElifDirective Elif { get; set; } - public IEnumerable Children { get; set; } - - - public ElifCode(Match m) - { - Match = m; - Children = m["Children"].Matches.Select(GetToken); - } -} diff --git a/src/SDSL/Parsers/AST/Directives/Literals.cs b/src/SDSL/Parsers/AST/Directives/Literals.cs deleted file mode 100644 index 89c53cf520..0000000000 --- a/src/SDSL/Parsers/AST/Directives/Literals.cs +++ /dev/null @@ -1,151 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Directives; - - -public class DirectiveLiteral : DirectiveToken -{ - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override void EvaluateMacros(Dictionary macros) - { - throw new NotImplementedException(); - } -} - -public class NumberLiteral : DirectiveLiteral -{ - public bool Negative { get; set; } = false; - public object Value { get; set; } - public string? Suffix { get; set; } - - protected Type? inferredType; - - public override Type InferredType - { - get - { - if (inferredType is not null) - return inferredType; - if (Suffix is null) - return Value.GetType(); - else - { - return Suffix switch - { - "u" or "l" => typeof(long), - "f" or "d" => typeof(double), - _ => typeof(long) - }; - } - } - set => inferredType = value; - } - - public NumberLiteral() { } - - public NumberLiteral(Match match) - { - Match = match; - if (!match.HasMatches) - { - Value = match.Value; - } - else - { - if (match.Name == "SignedTermExpression") - { - - } - else - { - Value = match.Matches[0].Value; - Suffix = match["Suffix"].StringValue; - } - } - } -} -public class HexLiteral : NumberLiteral -{ - - public override Type InferredType - { - get - { - return typeof(long); - } - set => inferredType = value; - } - - - public HexLiteral() { } - - public HexLiteral(Match match) - { - Match = match; - Value = Convert.ToUInt64(match.StringValue, 16); - } -} -public class StringLiteral : DirectiveLiteral -{ - public string? Value { get; set; } - public override Type InferredType { get => typeof(string); set { } } - - public StringLiteral() { } - - public StringLiteral(Match match) - { - Match = match; - Value = match.StringValue; - } -} - -public class BoolLiteral : DirectiveLiteral -{ - public bool Value { get; set; } - public override Type InferredType { get => typeof(bool); set { } } - - public BoolLiteral() { } - - public BoolLiteral(Match match) - { - Match = match; - Value = (bool)match.Value; - } -} - - -public class TypeNameLiteral : DirectiveLiteral -{ - public string Name { get; set; } - - public TypeNameLiteral(Match m) - { - Name = m.StringValue; - } -} - -public class VariableNameLiteral : DirectiveLiteral -{ - public string Name { get; set; } - public object Value { get; set; } - - Type? inferredType; - - public override Type InferredType { get => inferredType ?? typeof(void); set => inferredType = value; } - - - public VariableNameLiteral(Match m) - { - Name = m.StringValue; - } - public override string ToString() - { - return $"{{ Variable : {Name} }}" ; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Directives/Operations.cs b/src/SDSL/Parsers/AST/Directives/Operations.cs deleted file mode 100644 index 021e2090e2..0000000000 --- a/src/SDSL/Parsers/AST/Directives/Operations.cs +++ /dev/null @@ -1,454 +0,0 @@ -using Eto.Parse; -using SDSL.Parsing.AST.Directives; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static SDSL.Parsing.AST.Directives.OperatorTokenExtensions; - -namespace SDSL.Parsing.AST.Directives; - -public abstract class Projector : DirectiveToken -{ - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override void EvaluateMacros(Dictionary macros) - { - throw new NotImplementedException(); - } - - public abstract DirectiveToken ProjectConstant(); -} - -public class Operation : Projector -{ - public OperatorToken Op { get; set; } - - public DirectiveToken Left { get; set; } - public DirectiveToken Right { get; set; } - - Type? inferredType; - public override Type InferredType - { - get => inferredType ?? typeof(void); - set => inferredType = value; - } - public override void EvaluateMacros(Dictionary macros) - { - if(Left is Operation) - Left.EvaluateMacros(macros); - if (Right is Operation) - Right.EvaluateMacros(macros); - if (Left is VariableNameLiteral vl) - { - if (macros.TryGetValue(vl.Name, out object value)) - { - Left = value switch - { - float v => new NumberLiteral { Value = v }, - double v => new NumberLiteral { Value = v }, - byte v => new NumberLiteral { Value = v }, - ushort v => new NumberLiteral { Value = v }, - uint v => new NumberLiteral { Value = v }, - ulong v => new NumberLiteral { Value = v }, - int v => new NumberLiteral { Value = v }, - long v => new NumberLiteral { Value = v }, - short v => new NumberLiteral { Value = v }, - sbyte v => new NumberLiteral { Value = v }, - bool v => new BoolLiteral { Value = v }, - string v => new StringLiteral { Value = v }, - _ => throw new Exception("Unusable type") - }; - } - else - throw new Exception("Macro does not exist"); - } - if (Right is VariableNameLiteral vr) - { - if (macros.TryGetValue(vr.Name, out object value)) - { - Right = value switch - { - float v => new NumberLiteral { Value = v }, - double v => new NumberLiteral { Value = v }, - byte v => new NumberLiteral { Value = v }, - ushort v => new NumberLiteral { Value = v }, - uint v => new NumberLiteral { Value = v }, - ulong v => new NumberLiteral { Value = v }, - int v => new NumberLiteral { Value = v }, - long v => new NumberLiteral { Value = v }, - short v => new NumberLiteral { Value = v }, - sbyte v => new NumberLiteral { Value = v }, - bool v => new BoolLiteral { Value = v }, - string v => new StringLiteral { Value = v }, - _ => throw new Exception("Unusable type") - }; - } - else - throw new Exception("Macro does not exist"); - } - } - - public override DirectiveToken ProjectConstant() - { - - if (Left is Projector) - Left = ((Projector)Left).ProjectConstant(); - if (Right is Projector) - Right = ((Projector)Right).ProjectConstant(); - - return (Left, Right) switch - { - (NumberLiteral ln, NumberLiteral rn) => ApplyOperation(Op, ln, rn), - (BoolLiteral ln, BoolLiteral rn) => ApplyOperation(Op, ln, rn), - (StringLiteral ln, StringLiteral rn) => ApplyOperation(Op, ln, rn), - _ => throw new Exception("Cannot process operation") - }; - } - - -} - - -public class MulExpression : Operation -{ - public static MulExpression Create(Match m) - { - var first = new MulExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - MulExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new MulExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class SumExpression : Operation -{ - public static SumExpression Create(Match m) - { - var first = new SumExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - SumExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new SumExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class ShiftExpression : Operation -{ - public static ShiftExpression Create(Match m) - { - var first = new ShiftExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - ShiftExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new ShiftExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class AndExpression : Operation -{ - public static AndExpression Create(Match m) - { - var first = new AndExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - AndExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new AndExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} -public class XorExpression : Operation -{ - public static XorExpression Create(Match m) - { - var first = new XorExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - XorExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new XorExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} -public class OrExpression : Operation -{ - public static OrExpression Create(Match m) - { - var first = new OrExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - OrExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new OrExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class TestExpression : Operation -{ - public static TestExpression Create(Match m) - { - var first = new TestExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - TestExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new TestExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class EqualsExpression : Operation -{ - public static EqualsExpression Create(Match m) - { - var first = new EqualsExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - EqualsExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new EqualsExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class LogicalAndExpression : Operation -{ - public static LogicalAndExpression Create(Match m) - { - var first = new LogicalAndExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - LogicalAndExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new LogicalAndExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } - -} -public class LogicalOrExpression : Operation -{ - public static LogicalOrExpression Create(Match m) - { - var first = new LogicalOrExpression - { - Match = m, - Op = m.Matches[1].StringValue.AsOperatorToken(), - Left = GetToken(m.Matches[0]), - Right = GetToken(m.Matches[2]) - }; - - LogicalOrExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 2; i += 2) - { - tmp = new LogicalOrExpression - { - Match = m, - Op = m.Matches[i].StringValue.AsOperatorToken(), - Left = tmp, - Right = GetToken(m.Matches[i + 1]) - }; - } - return tmp; - } -} - -public class ConditionalExpression : Projector -{ - public DirectiveToken Condition { get; set; } - public DirectiveToken TrueOutput { get; set; } - public DirectiveToken FalseOutput { get; set; } - - Type? inferredType; - - public override Type InferredType - { - get => inferredType ?? typeof(void); - set => inferredType = value; - } - - public ConditionalExpression(Match m) - { - Condition = GetToken(m.Matches[0]); - TrueOutput = GetToken(m.Matches[1]); - FalseOutput = GetToken(m.Matches[2]); - } - - public override void EvaluateMacros(Dictionary macros) - { - if (Condition is VariableNameLiteral vcondition) - { - if (macros.TryGetValue(vcondition.Name, out object value)) - { - vcondition.Value = value; - vcondition.InferredType = value.GetType(); - } - else - throw new Exception("Macro does not exist"); - } - if (TrueOutput is VariableNameLiteral tout) - { - if (macros.TryGetValue(tout.Name, out object value)) - { - tout.Value = value; - tout.InferredType = value.GetType(); - } - else - throw new Exception("Macro does not exist"); - } - if (FalseOutput is VariableNameLiteral fout) - { - if (macros.TryGetValue(fout.Name, out object value)) - { - fout.Value = value; - fout.InferredType = value.GetType(); - } - else - throw new Exception("Macro does not exist"); - } - - } - - public override DirectiveToken ProjectConstant() - { - if (Condition is Projector) - Condition = ((Projector)Condition).ProjectConstant(); - - if (TrueOutput is Projector ) - TrueOutput= ((Projector)TrueOutput).ProjectConstant(); - - if (FalseOutput is Projector ) - FalseOutput= ((Projector)FalseOutput).ProjectConstant(); - - if (Condition is BoolLiteral c) - return c.Value ? TrueOutput : FalseOutput; - else - throw new Exception("Invalid condition"); - } -} diff --git a/src/SDSL/Parsers/AST/Directives/OperatorToken.cs b/src/SDSL/Parsers/AST/Directives/OperatorToken.cs deleted file mode 100644 index 8c02de1288..0000000000 --- a/src/SDSL/Parsers/AST/Directives/OperatorToken.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Directives; - -public enum OperatorToken -{ - Mul, - Div, - Mod, - Plus, - Minus, - LeftShift, - RightShift, - And, - Or, - Xor, - Less, - Greater, - LessEqual, - GreaterEqual, - Equals, - NotEquals, - LogicalAnd, - LogicalOr -} - -public static class OperatorTokenExtensions -{ - public static OperatorToken AsOperatorToken(this string s) - { - return s switch - { - "*" => OperatorToken.Mul, - "/" => OperatorToken.Div, - "%" => OperatorToken.Mod, - "+" => OperatorToken.Plus, - "-" => OperatorToken.Minus, - "<<" => OperatorToken.LeftShift, - ">>" => OperatorToken.RightShift, - "|" => OperatorToken.Or, - "&" => OperatorToken.And, - "^" => OperatorToken.Xor, - "<" => OperatorToken.Less, - "<=" => OperatorToken.LessEqual, - ">" => OperatorToken.Greater, - ">=" => OperatorToken.GreaterEqual, - "==" => OperatorToken.Equals, - "!=" => OperatorToken.NotEquals, - "&&" => OperatorToken.LogicalAnd, - "||" => OperatorToken.LogicalOr, - _ => throw new NotImplementedException() - }; - } - - private static double OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToDouble(a); - var r = Convert.ToDouble(b); - return f.Invoke(l, r); - } - private static double OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToInt32(a); - var r = Convert.ToInt32(b); - return f.Invoke(l, r); - } - - private static bool OperationWithCast(object a, object b, Func f) - { - var l = Convert.ToDouble(a); - var r = Convert.ToDouble(b); - return f.Invoke(l, r); - } - - public static DirectiveToken ApplyOperation(OperatorToken op, NumberLiteral l, NumberLiteral r) - { - return op switch - { - OperatorToken.Mul => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a*b) }, - OperatorToken.Div => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a / b) }, - OperatorToken.Mod => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a % b) }, - OperatorToken.Plus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a + b) }, - OperatorToken.Minus => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a - b) }, - OperatorToken.LeftShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a,b) => a << b) }, - OperatorToken.RightShift => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a >> b) }, - OperatorToken.And => new NumberLiteral { Value = OperationWithCast(l.Value, r.Value , (a, b) => a & b) }, - OperatorToken.Or => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a | b) }, - OperatorToken.Xor => new NumberLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a ^ b) }, - OperatorToken.Less => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a < b) }, - OperatorToken.LessEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a <= b) }, - OperatorToken.Greater => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a > b) }, - OperatorToken.GreaterEqual => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a >= b) }, - OperatorToken.Equals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a == b) }, - OperatorToken.NotEquals => new BoolLiteral { Value = OperationWithCast(l.Value,r.Value ,(a,b) => a != b) }, - _ => throw new NotImplementedException() - }; - } - public static DirectiveToken ApplyOperation(OperatorToken op, BoolLiteral l, BoolLiteral r) - { - return op switch - { - OperatorToken.LogicalAnd => new BoolLiteral { Value = l.Value && r.Value }, - OperatorToken.LogicalOr => new BoolLiteral { Value = l.Value || r.Value }, - OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, - OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, - _ => throw new NotImplementedException() - }; - } - public static DirectiveToken ApplyOperation(OperatorToken op, StringLiteral l, StringLiteral r) - { - return op switch - { - OperatorToken.Equals => new BoolLiteral { Value = l.Value == r.Value }, - OperatorToken.NotEquals => new BoolLiteral { Value = l.Value != r.Value }, - _ => throw new NotImplementedException() - }; - } -} diff --git a/src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs b/src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs deleted file mode 100644 index e15173eda5..0000000000 --- a/src/SDSL/Parsers/AST/Directives/UnaryLiterals.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Eto.Parse; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Directives; - - -public class UnaryExpression : DirectiveToken -{ - public override Type InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override void EvaluateMacros(Dictionary macros) - { - throw new NotImplementedException(); - } -} - -public class ChainAccessor : UnaryExpression -{ - public DirectiveToken Value { get; set; } - public DirectiveToken Field { get; set; } - - public ChainAccessor(Match m) - { - Match = m; - Value = GetToken(m.Matches[0]); - Field = GetToken(m.Matches[1]); - } -} - -public class ArrayAccessor : UnaryExpression -{ - public DirectiveToken Value { get; set; } - public IEnumerable Accessors { get; set; } - - public ArrayAccessor(Match m) - { - Match = m; - Value= GetToken(m.Matches[0]); - Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); - } -} - - -public class PostfixIncrement : UnaryExpression -{ - public string Operator { get; set; } - public DirectiveToken Value { get; set; } - public PostfixIncrement(Match m) - { - Match = m; - Value = GetToken(m.Matches[0]); - Operator = m.Matches[1].StringValue; - } - - public override string ToString() - { - return $"{{ PostfixIncrement : [\"{Value}\", \"{Operator}\"] }}"; - } -} - -public class PrefixIncrement : UnaryExpression -{ - public string Operator { get; set; } - public DirectiveToken Value { get; set; } - public PrefixIncrement(Match m) - { - Match = m; - Operator = m.Matches[0].StringValue; - Value = GetToken(m.Matches[1]); - } -} - -public class CastExpression : UnaryExpression -{ - public TypeNameLiteral Target { get; set; } - public DirectiveToken From { get; set; } - public CastExpression(Match m) - { - Target = new TypeNameLiteral(m.Matches[0]); - From = GetToken(m.Matches[1]); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/ControlFlow.cs b/src/SDSL/Parsers/AST/Shader/ControlFlow.cs deleted file mode 100644 index 7bace4ecb4..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ControlFlow.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; - -namespace SDSL.Parsing.AST.Shader; - - -public class ForLoop : ControlFlow -{ - public List Attributes {get;set;} - public ShaderToken Initializer {get;set;} - public ShaderToken Condition {get;set;} - public ShaderToken Updater {get;set;} - public ForLoop(Match m, SymbolTable s) - { - Match = m; - var forMatch = m["ForLoop"]; - } -} - - -public class IfStatement : ControlFlow -{ - public ShaderToken Attributes {get;set;} - public ShaderToken Condition {get;set;} - public ShaderToken Statements {get;set;} - public IfStatement(Match m, SymbolTable s) - { - Match = m; - if(m["Attributes"].HasMatches) - throw new NotImplementedException(); - Condition = GetToken(m["Condition"],s); - Statements = GetToken(m["Statement"],s); - } -} - -public class ElseIfStatement : ControlFlow -{ - public ShaderToken Attributes {get;set;} - public ShaderToken Condition {get;set;} - public ShaderToken Statements {get;set;} - public ElseIfStatement(Match m, SymbolTable s) - { - Match = m; - if(m["Attributes"].HasMatches) - throw new NotImplementedException(); - Condition = GetToken(m["Control"]["IfStatement"]["Condition"],s); - Statements = GetToken(m["Control"]["IfStatement"]["Statement"],s); - } -} - -public class ElseStatement : ControlFlow -{ - public ShaderToken Attributes {get;set;} - public ShaderToken Condition {get;set;} - public ShaderToken Statements {get;set;} - public ElseStatement(Match m, SymbolTable s) - { - Match = m; - if(m["Attributes"].HasMatches) - throw new NotImplementedException(); - Condition = GetToken(m["Control"]["IfStatement"]["Condition"],s); - Statements = GetToken(m["Control"]["IfStatement"]["Statement"],s); - } -} - -public class ConditionalFlow : ControlFlow -{ - public IfStatement If {get;set;} - public List ElseIfs {get;set;} - public ElseStatement Else {get;set;} - public ConditionalFlow(Match m, SymbolTable s) - { - Match = m["ConditionalFlow"]; - If = new IfStatement(Match["IfStatement"],s); - if(Match.Matches.Any(x => x.Name == "ElseIfStatement")) - ElseIfs = Match.Matches.Where(x => x.Name == "ElseIfStatement").Select(x => new ElseIfStatement(x,s)).ToList(); - if(Match["ElseStatement"]) - Else = new ElseStatement(Match["ElseStatement"],s); - } -} - - -public abstract class ControlFlow : Statement -{ - public static ControlFlow Create(Match m, SymbolTable s) - { - return m.Matches[1].Name switch - { - "ConditionalFlow" => new ConditionalFlow(m, s), - "ForLoop" => new ForLoop(m, s), - _ => throw new NotImplementedException() - }; - } -} - diff --git a/src/SDSL/Parsers/AST/Shader/Literals.cs b/src/SDSL/Parsers/AST/Shader/Literals.cs deleted file mode 100644 index 89a5e2cbad..0000000000 --- a/src/SDSL/Parsers/AST/Shader/Literals.cs +++ /dev/null @@ -1,201 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - - -public class ShaderLiteral : Expression -{ - public override SymbolType? InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - -} - -public class ShaderLiteral : ShaderLiteral -{ - public T Value { get; set; } -} - -public class NumberLiteral : ShaderLiteral -{ - public bool Negative { get; set; } = false; - public string? Suffix { get; set; } - public override SymbolType? InferredType - { - get => inferredType ?? throw new NotImplementedException(); - set => inferredType = value; - } - - public NumberLiteral() { } - - public NumberLiteral(Match match, SymbolTable s) - { - Match = match; - if (!match.HasMatches) - { - Value = match.Value switch - { - long l => Convert.ToDouble(l), - double d => d, - _ => throw new NotImplementedException() - }; - InferredType = Value % 1 == 0 ? s.Scalar("int") : s.Scalar("float"); - } - else - { - if (match.Name == "SignedTermExpression") - { - - } - else - { - Value = (double)match.Matches[0].Value; - Suffix = match["Suffix"].StringValue; - InferredType = Suffix switch - { - "l" => s.Scalar("long"), - "d" => s.Scalar("double"), - "f" => s.Scalar("float"), - "u" => s.Scalar("uint"), - "L" => s.Scalar("long"), - "D" => s.Scalar("double"), - "F" => s.Scalar("float"), - "U" => s.Scalar("uint"), - _ => throw new NotImplementedException(), - }; - } - } - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - if(Suffix == null) - { - inferredType = (InferredType, expected) switch - { - (Scalar s, null) => s, - (Scalar { Name: "float" }, Scalar { Name: "int" or "half" or "double" }) => expected, - (Scalar { Name: "int" }, Scalar { Name: "byte" or "sbyte" or "short" or "ushort" or "uint" or "int" or "long" or "ulong" or "float" or "double" }) => expected, - _ => throw new Exception($"cannot implictely cast {inferredType} to {expected}") - }; - } - else - { - if(InferredType != expected) - throw new Exception($"Cannot convert {InferredType} to {expected ?? SymbolType.Void}"); - } - } - public override string ToString() - { - return new StringBuilder().Append(InferredType.ToString()).Append('(').Append(Value.ToString()).Append(')').ToString(); - } - - public override bool Equals(object? obj) - { - return obj is NumberLiteral literal && - EqualityComparer.Default.Equals(inferredType, literal.inferredType) && - EqualityComparer.Default.Equals(Value, literal.Value); - } - - public override int GetHashCode() - { - return HashCode.Combine(inferredType, Value); - } -} -public class HexLiteral : NumberLiteral -{ - public override SymbolType? InferredType - { - get => inferredType; - set => inferredType = value; - } - - - public HexLiteral() { } - - public HexLiteral(Match match, SymbolTable s) - { - Match = match; - Value = Convert.ToUInt64(match.StringValue, 16); - } -} -public class StringLiteral : ShaderLiteral -{ - public override SymbolType? InferredType { get => SymbolType.String(); set => throw new NotImplementedException(); } - - public StringLiteral() { } - - public StringLiteral(Match match, SymbolTable s) - { - Match = match; - Value = match.StringValue; - } -} - -public class BoolLiteral : ShaderLiteral -{ - public override SymbolType? InferredType { get => SymbolType.Scalar("bool"); set => throw new NotImplementedException(); } - - public BoolLiteral() { } - - public BoolLiteral(Match match, SymbolTable s) - { - Match = match; - Value = (bool)match.Value; - } -} - - -public class TypeNameLiteral : ShaderLiteral -{ - public string Name { get; set; } - - public TypeNameLiteral(Match m, SymbolTable s) - { - Name = m.StringValue; - } -} - -public class VariableNameLiteral : ShaderLiteral, IVariableCheck -{ - public string Name { get; set; } - - public override SymbolType? InferredType { get => inferredType; set => inferredType = value; } - - public VariableNameLiteral(string name) - { - Name = name; - } - - public VariableNameLiteral(Match m, SymbolTable s) - { - Name = m.StringValue; - } - - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - if(symbols.Variables.TryGetVariable(Name, out var variable)) - { - if(variable.Type == expected) - inferredType = expected; - else - throw new Exception("Type is not matching"); - } - else throw new Exception($"Use of undeclared variable \"{Name}\""); - } - - public void CheckVariables(SymbolTable s) - { - if (!s.Variables.IsDeclared(Name)) - throw new Exception("Not a variable"); - } - public override string ToString() - { - return $"{{ Variable : {Name} }}"; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/Operations.cs b/src/SDSL/Parsers/AST/Shader/Operations.cs deleted file mode 100644 index 3120e68f85..0000000000 --- a/src/SDSL/Parsers/AST/Shader/Operations.cs +++ /dev/null @@ -1,420 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Directives; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static SDSL.Parsing.AST.Shader.OperatorTokenExtensions; - -namespace SDSL.Parsing.AST.Shader; - - -public abstract class Expression : ShaderTokenTyped -{ - protected SymbolType? inferredType; - public override SymbolType? InferredType - { - get => inferredType ?? throw new NotImplementedException(); - set => inferredType = value; - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) { } -} - -public class Operation : Expression, IStreamCheck, IStaticCheck, IVariableCheck -{ - public OperatorToken Op { get; set; } - - public ShaderTokenTyped Left { get; set; } - public ShaderTokenTyped Right { get; set; } - - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - SymbolType? ltype = SymbolType.Void; - SymbolType? rtype = SymbolType.Void; - - Left.TypeCheck(symbols, expected); - ltype = Left.InferredType; - Right.TypeCheck(symbols, expected); - rtype = Right.InferredType; - - - if(rtype == ltype && rtype == expected) - inferredType = rtype; - else - throw new Exception($"Cannot apply operation between types {Right.InferredType} and {Left.InferredType} when {expected} is expected"); - } - - public IEnumerable GetUsedStream() - { - var result = Enumerable.Empty(); - if (Left is IStreamCheck lsc) - result = result.Concat(lsc.GetUsedStream()); - if (Right is IStreamCheck rsc) - result = result.Concat(rsc.GetUsedStream()); - return result; - } - public IEnumerable GetAssignedStream() - { - return Enumerable.Empty(); - } - - public bool CheckStream(SymbolTable s) - { - return Left is IStreamCheck scl && scl.CheckStream(s) - || Right is IStreamCheck scr && scr.CheckStream(s); - } - - public bool CheckStatic(SymbolTable s) - { - return Left is IStaticCheck scl && scl.CheckStatic(s) - || Right is IStaticCheck scr && scr.CheckStatic(s); - } - - public void CheckVariables(SymbolTable s) - { - if (Left is IVariableCheck lvc) lvc.CheckVariables(s); - if (Right is IVariableCheck rvc) rvc.CheckVariables(s); - } - public void CheckImplicitCasting(ShaderTokenTyped l, ShaderTokenTyped r, string expected) - { - InferredType = (l.InferredType, r.InferredType, expected) switch - { - // ("int","float", "int") => "int", - // ("int","float", "float") => "float", - // ("float","int", "int") => "int", - // ("float","int", "float") => "float", - // ("int","float", "") => "float", - // ("float","int", "") => "float", - _ => throw new Exception($"Cannot cast types") - }; - } -} - - -public class MulExpression : Operation -{ - public static MulExpression Create(Match m, SymbolTable s) - { - var first = new MulExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - MulExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new MulExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class SumExpression : Operation -{ - public static SumExpression Create(Match m, SymbolTable s) - { - var first = new SumExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - SumExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new SumExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class ShiftExpression : Operation -{ - public static ShiftExpression Create(Match m, SymbolTable s) - { - var first = new ShiftExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - ShiftExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new ShiftExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class AndExpression : Operation -{ - public static AndExpression Create(Match m, SymbolTable s) - { - var first = new AndExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - AndExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new AndExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} -public class XorExpression : Operation -{ - public static XorExpression Create(Match m, SymbolTable s) - { - var first = new XorExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - XorExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new XorExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} -public class OrExpression : Operation -{ - public static OrExpression Create(Match m, SymbolTable s) - { - var first = new OrExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - OrExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new OrExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class TestExpression : Operation -{ - public static TestExpression Create(Match m, SymbolTable s) - { - var first = new TestExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - TestExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new TestExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class EqualsExpression : Operation -{ - public static EqualsExpression Create(Match m, SymbolTable s) - { - var first = new EqualsExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - EqualsExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new EqualsExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class LogicalAndExpression : Operation -{ - public static LogicalAndExpression Create(Match m, SymbolTable s) - { - var first = new LogicalAndExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - LogicalAndExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new LogicalAndExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } - -} -public class LogicalOrExpression : Operation -{ - public static LogicalOrExpression Create(Match m, SymbolTable s) - { - var first = new LogicalOrExpression - { - Match = m, - Op = m.Matches[1].StringValue.ToOperatorToken(), - Left = (ShaderTokenTyped)GetToken(m.Matches[0], s), - Right = (ShaderTokenTyped)GetToken(m.Matches[2], s) - }; - - LogicalOrExpression tmp = first; - for (int i = 3; i < m.Matches.Count - 1; i += 2) - { - tmp = new LogicalOrExpression - { - Match = m, - Op = m.Matches[i].StringValue.ToOperatorToken(), - Left = tmp, - Right = (ShaderTokenTyped)GetToken(m.Matches[i + 1], s) - }; - } - return tmp; - } -} - -public class ConditionalExpression : Expression -{ - public ShaderTokenTyped Condition { get; set; } - public ShaderTokenTyped TrueOutput { get; set; } - public ShaderTokenTyped FalseOutput { get; set; } - - string? inferredType; - - public string InferredType - { - get => inferredType; - set => inferredType = value; - } - - public ConditionalExpression(Match m, SymbolTable s) - { - Condition = (ShaderTokenTyped)GetToken(m.Matches[0], s); - TrueOutput = (ShaderTokenTyped)GetToken(m.Matches[1], s); - FalseOutput = (ShaderTokenTyped)GetToken(m.Matches[2], s); - } -} - - -public class MethodCall : Expression -{ - public string MethodName { get; set; } - public IEnumerable Parameters { get; set; } - - public MethodCall(Match m, SymbolTable s) - { - Match = m; - MethodName = m.Matches.First().StringValue; - throw new NotImplementedException(); - // Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(GetToken).Cast().ToList(); - } -} - -public class ValueMethodCall : Expression -{ - public string MethodName { get; set; } - public IEnumerable Parameters { get; set; } - - public ValueMethodCall(Match m, SymbolTable s) - { - Match = m; - MethodName = m.Matches.First().StringValue; - inferredType = s.Tokenize(m["ValueTypes"]); - Parameters = m.Matches.Where(x => x.Name == "PrimaryExpression").Select(x => GetToken(x, s)).Cast().ToList(); - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - // if(!inferredType.Equals(expected)) - // symbols.AddError(Match, $"cannot cast {inferredType} to {expected}"); - } -} diff --git a/src/SDSL/Parsers/AST/Shader/OperatorToken.cs b/src/SDSL/Parsers/AST/Shader/OperatorToken.cs deleted file mode 100644 index daf9bdd956..0000000000 --- a/src/SDSL/Parsers/AST/Shader/OperatorToken.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - -public enum AssignOpToken -{ - Equal, - MulEqual, - DivEqual, - ModEqual, - PlusEqual, - MinusEqual, - LeftShiftEqual, - RightShiftEqual, - AndEqual, - OrEqual, - XorEqual -} - -public enum OperatorToken -{ - Mul, - Div, - Mod, - Plus, - Minus, - LeftShift, - RightShift, - And, - Or, - Xor, - Less, - Greater, - LessEqual, - GreaterEqual, - Equals, - NotEquals, - LogicalAnd, - LogicalOr -} - -public static class OperatorTokenExtensions -{ - public static OperatorToken ToOperatorToken(this string s) - { - return s switch - { - "*" => OperatorToken.Mul, - "/" => OperatorToken.Div, - "%" => OperatorToken.Mod, - "+" => OperatorToken.Plus, - "-" => OperatorToken.Minus, - "<<" => OperatorToken.LeftShift, - ">>" => OperatorToken.RightShift, - "|" => OperatorToken.Or, - "&" => OperatorToken.And, - "^" => OperatorToken.Xor, - "<" => OperatorToken.Less, - "<=" => OperatorToken.LessEqual, - ">" => OperatorToken.Greater, - ">=" => OperatorToken.GreaterEqual, - "==" => OperatorToken.Equals, - "!=" => OperatorToken.NotEquals, - "&&" => OperatorToken.LogicalAnd, - "||" => OperatorToken.LogicalOr, - _ => throw new NotImplementedException() - }; - } - public static AssignOpToken ToAssignOp(this string s) - { - return s switch - { - "=" => AssignOpToken.Equal, - "*=" => AssignOpToken.MulEqual, - "/=" => AssignOpToken.DivEqual, - "%=" => AssignOpToken.ModEqual, - "+=" => AssignOpToken.PlusEqual, - "-=" => AssignOpToken.MinusEqual, - "<<=" => AssignOpToken.LeftShiftEqual, - ">>=" => AssignOpToken.RightShiftEqual, - "|=" => AssignOpToken.OrEqual, - "&=" => AssignOpToken.AndEqual, - "^=" => AssignOpToken.XorEqual, - _ => throw new NotImplementedException() - }; - } -} diff --git a/src/SDSL/Parsers/AST/Shader/ShaderElements.cs b/src/SDSL/Parsers/AST/Shader/ShaderElements.cs deleted file mode 100644 index ad23ece89a..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ShaderElements.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - -public class StructField : ShaderToken -{ - public SymbolType Type {get;set;} - public string Name {get;set;} - - - public StructField(Match m, SymbolTable s) - { - Match = m; - Type = s.Tokenize(m["ValueTypes"]); - Name = m["Name"].StringValue; - } -} - -public class StructDefinition : ShaderToken -{ - public string StructName {get;set;} - public List Fields {get;set;} - - public SymbolType Type {get;set;} - - public StructDefinition(Match m, SymbolTable s) - { - Match = m; - StructName = Match["StructName"].StringValue; - Fields = Match["Fields"].Matches.Select(x => new StructField(x,s)).ToList(); - Type = SymbolType.Struct(StructName, Fields.ToDictionary(x => x.Name, x => s.Tokenize(x?.Match["ValueTypes"]))); - } -} - -public class ResourceGroup : ShaderToken -{ - public IEnumerable Variables {get;set;} - - public ResourceGroup(Match m, SymbolTable s) - { - Match = m; - throw new NotImplementedException(); - // Variables = m["Variables"].Matches.Select(GetToken).ToList(); - - } -} -public class ConstantBuffer : ShaderToken -{ - public IEnumerable Variables {get;set;} - - public ConstantBuffer(Match m, SymbolTable s) - { - Match = m; - throw new NotImplementedException(); - // Variables = m["Variables"].Matches.Select(GetToken).ToList(); - - } -} - -public class ShaderVariableDeclaration : ShaderToken -{ - public bool IsStream {get;set;} - public bool IsStaged {get;set;} - public string Name {get;set;} - public SymbolType Type {get;set;} - public string? Semantic { get; set; } - public ShaderToken Expression {get;set;} - - public ShaderVariableDeclaration(Match m, SymbolTable s) - { - Match = m; - IsStream = m["Stream"].Success; - IsStaged = m["Stage"].Success; - Semantic = m["Semantic"].Success ? m["Semantic"].StringValue : null; - throw new NotImplementedException(); - // Type = s.PushType(m["ValueTypes"].StringValue,m["ValueTypes"]); - // Name = m["Identifier"].StringValue; - } -} -public class Generics : ShaderToken -{ - public string Type { get; set; } - public string Name { get; set; } -} - -public class ShaderGenerics : ShaderToken -{ - public string Name { get; set; } - public IEnumerable Generics { get; set; } -} - -public class MixinToken : ShaderToken -{ - public string Name { get; set; } - public List GenericsValues { get; set; } - - public MixinToken(Match m) - { - Match = m; - Name = m["Name"].StringValue; - GenericsValues = m["Generics"].Matches.Select(x => x.StringValue).ToList(); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/ShaderMethods.cs b/src/SDSL/Parsers/AST/Shader/ShaderMethods.cs deleted file mode 100644 index 07ac61aec6..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ShaderMethods.cs +++ /dev/null @@ -1,165 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using SDSL.TAC; - -namespace SDSL.Parsing.AST.Shader; - - - -public abstract class ShaderMethod : ShaderToken -{ - public bool IsStatic { get; set; } - public bool IsOverride { get; set; } - public bool IsStaged { get; set; } - public IR IRCode { get; set; } - public string Name { get; set; } - public SymbolType ReturnType { get; set; } - public List? ParameterList { get; set; } - public List Statements { get; set; } - - public ShaderMethod(Match m, SymbolTable symbols) - { - Match = m; - IsStatic = m["Static"].Success; - IsOverride = m["Override"].Success; - IsStaged = m["Stage"].Success; - Name = m["MethodName"].StringValue; - ReturnType = symbols.ParseType(m["ReturnType"].StringValue); - Statements = m["Statements"].Matches.Select(x => GetToken(x, symbols)).Cast().ToList(); - ParameterList = m["ParameterList"].Matches.Select(x => GetToken(x, symbols)).Cast().ToList(); - } - - public static ShaderMethod Create(Match m, SymbolTable s) - { - return m["MethodName"].StringValue switch - { - "VSMain" => new VSMainMethod(m, s), - "PSMain" => new PSMainMethod(m, s), - "CSMain" => new CSMainMethod(m, s), - "GSMain" => new GSMainMethod(m, s), - "DSMain" => new DSMainMethod(m, s), - "HSMain" => new HSMainMethod(m, s), - _ => new ModuleMethod(m, s) - }; - } -} - -public class MethodParameter : ShaderToken -{ - public SymbolType Type { get; set; } - public string Name { get; set; } - - public MethodParameter(Match m, SymbolTable s) - { - Match = m; - Name = m["Identifier"].StringValue; - Type = s.ParseType(m["ValueOrGeneric"].StringValue); - } -} -public class ModuleMethod(Match m, SymbolTable symbols) : ShaderMethod(m, symbols); - -public abstract class MainMethod : ShaderMethod, IStreamCheck -{ - protected string prefix; - // public TAC IL { get; set; } - - public MainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "NONE"; - // IL = new(s); - } - - public bool CheckStream(SymbolTable s) - { - if (Statements == null) return true; - return Statements.OfType().Any(x => x.CheckStream(s)); - } - - public IEnumerable? GetAssignedStream() - { - return Statements?.OfType().SelectMany(x => x.GetAssignedStream() ?? Enumerable.Empty()); - } - - public IEnumerable? GetUsedStream() - { - return Statements?.OfType().SelectMany(x => x.GetUsedStream() ?? Enumerable.Empty()); - } - - public void VariableChecking(SymbolTable sym) - { - // if(CheckStream(sym)) - // sym.PushVar("streams","STREAM"); - // foreach (var s in Statements) - // sym.Analyse(s); - throw new NotImplementedException(); - } - public void CreateInOutStream(SymbolTable sym) - { - // if(sym.TryGetType("STREAM", out var t)) - // { - // var used = GetUsedStream(); - // var assigned = GetAssignedStream(); - // var i = ((CompositeType)t).SubType(prefix + "_STREAM_IN",used); - // var o = ((CompositeType)t).SubType(prefix + "_STREAM_OUT",assigned); - // sym.PushType(i.Name, i); - // sym.PushType(o.Name, o); - // } - throw new NotImplementedException(); - } - - internal void GenerateIl(SymbolTable symbols) - { - CreateInOutStream(symbols); - throw new NotImplementedException(); - // symbols.PushVar("streams", "STREAM"); - // symbols.PushVar("streams_in", prefix + "_STREAM_IN"); - // symbols.PushVar("streams_out", prefix + "_STREAM_OUT"); - // IL.Construct(Statements); - } -} - - -public class VSMainMethod : MainMethod -{ - public VSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "VS"; - } -} -public class PSMainMethod : MainMethod -{ - public PSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "PS"; - } -} -public class GSMainMethod : MainMethod -{ - public GSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "GS"; - } -} -public class CSMainMethod : MainMethod -{ - public CSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "CS"; - } -} -public class DSMainMethod : MainMethod -{ - public DSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "DS"; - } -} -public class HSMainMethod : MainMethod -{ - public HSMainMethod(Match m, SymbolTable s) : base(m, s) - { - prefix = "HS"; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/ShaderProgram.cs b/src/SDSL/Parsers/AST/Shader/ShaderProgram.cs deleted file mode 100644 index 010febf5de..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ShaderProgram.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - -public class ShaderProgram : ShaderToken -{ - public SymbolTable Symbols {get;set;} - public string Name {get;set;} - public List? Generics { get; set; } - public List Mixins { get; set; } - public List Body { get; set; } - - public ShaderProgram(Match m) - { - Match = m; - Symbols = new(); - Name = m["ShaderName"].StringValue; - Body = m["Body"].Matches.Select(x => GetToken(x,Symbols)).ToList(); - Mixins = m["Mixins"].Matches.Select(x => new MixinToken(x)).ToList(); - } - - public ErrorList SemanticChecks() where T : MainMethod - { - var method = Body.OfType().First(); - // foreach (var s in Body.OfType()) - // Symbols.PushType(s.StructName, s.Type); - // Symbols.PushStreamType(Body.OfType()); - method.CreateInOutStream(Symbols); - // Symbols.AddScope(); - //method.VariableChecking(Symbols); - method.GenerateIl(Symbols); - // Symbols.Pop(); - - - - // return Symbols.Errors; - return null; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/ShaderToken.cs b/src/SDSL/Parsers/AST/Shader/ShaderToken.cs deleted file mode 100644 index 4d38810f3a..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ShaderToken.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Parsing.Grammars.Expression; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - - -public abstract class ShaderToken -{ - public static string[] KeepValues = { - "Block", - "Return", - "EmptyStatement", - "ConstantBuffer", - "ResourceGroup", - }; - public Match? Match { get; set; } - - public static ShaderToken Tokenize(Match match) - { - // return GetToken(match,SymbolTable.Empty); - return GetToken(match, null); - } - public static ShaderToken GetToken(Match match, SymbolTable symbols) - { - var tmp = match; - while (tmp.Matches.Count == 1 && !KeepValues.Contains(tmp.Name)) - tmp = tmp.Matches.First(); - - return tmp.Name switch - { - "Namespace" => GetToken(tmp.Matches.Last(),symbols), - "ShaderProgram" => new ShaderProgram(tmp), - "ResourceGroup" => new ResourceGroup(tmp,symbols), - "ConstantBuffer" => new ConstantBuffer(tmp,symbols), - "ShaderValueDeclaration" => new ShaderVariableDeclaration(tmp, symbols), - "StructDefinition" => new StructDefinition(tmp,symbols), - "Method" => ShaderMethod.Create(tmp, symbols), - "MethodParameter" => new MethodParameter(tmp, symbols), - "ControlFlow" => ControlFlow.Create(tmp, symbols), - "Block" => new BlockStatement(tmp, symbols), - "Return" => new ReturnStatement(tmp, symbols), - "AssignChain" => new AssignChain(tmp, symbols), - "DeclareAssign" => new DeclareAssign(tmp, symbols), - "SimpleDeclare" => new SimpleDeclare(tmp, symbols), - "EmptyStatement" => new EmptyStatement(), - "MethodCall" => new MethodCall(tmp, symbols), - "ValueTypesMethods" => new ValueMethodCall(tmp, symbols), - "Ternary" => new ConditionalExpression(tmp, symbols), - "LogicalOrExpression" => LogicalOrExpression.Create(tmp, symbols), - "LogicalAndExpression" => LogicalAndExpression.Create(tmp, symbols), - "EqualsExpression" => EqualsExpression.Create(tmp, symbols), - "TestExpression" => TestExpression.Create(tmp, symbols), - "OrExpression" => OrExpression.Create(tmp, symbols), - "XorExpression" => XorExpression.Create(tmp, symbols), - "AndExpression" => AndExpression.Create(tmp, symbols), - "ShiftExpression" => ShiftExpression.Create(tmp, symbols), - "SumExpression" => SumExpression.Create(tmp, symbols), - "MulExpression" => MulExpression.Create(tmp, symbols), - "CastExpression" => new CastExpression(tmp, symbols), - "PrefixIncrement" => throw new NotImplementedException("prefix implement not implemented"), - "ChainAccessor" => new ChainAccessor(tmp, symbols), - "ArrayAccessor" => new ArrayAccessor(tmp, symbols), - "IntegerValue" or "FloatValue" or "FloatLiteral" => new NumberLiteral(tmp, symbols), - "VariableTerm" or "Identifier" => new VariableNameLiteral(tmp, symbols), - "ValueTypes" or "TypeName" => new TypeNameLiteral(tmp, symbols), - "Boolean" => new BoolLiteral(tmp, symbols), - _ => throw new NotImplementedException() - }; - } - - - - - // public IEnumerable GetUsedStream() - // { - // return this switch - // { - // AssignChain a => a.Value.GetUsedStream(), - // ChainAccessor{Value: VariableNameLiteral{Name : "streams"}} => new string[1]{((VariableNameLiteral)((ChainAccessor)this).Field).Name}, - // Operation {Left : ChainAccessor c} => c.GetUsedStream(), - // Operation {Right : ChainAccessor c} => c.GetUsedStream(), - // _ => Array.Empty() - // }; - // } - // public IEnumerable GetAssignedStream() - // { - // return this switch - // { - // AssignChain{StreamValue: true} c => new string[1]{c.AccessNames.ElementAt(1)}, - // BlockStatement b => b.Statements.SelectMany(x => x.GetAssignedStream()), - // _ => Array.Empty() - // }; - // } - -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/ShaderTokenTyped.cs b/src/SDSL/Parsers/AST/Shader/ShaderTokenTyped.cs deleted file mode 100644 index 62db43b8f2..0000000000 --- a/src/SDSL/Parsers/AST/Shader/ShaderTokenTyped.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; - -namespace SDSL.Parsing.AST.Shader; - -public abstract class ShaderTokenTyped : ShaderToken -{ - public abstract SymbolType? InferredType { get; set; } - public abstract void TypeCheck(SymbolTable symbols, in SymbolType? expected); -} \ No newline at end of file diff --git a/src/SDSL/Parsers/AST/Shader/Statements.cs b/src/SDSL/Parsers/AST/Shader/Statements.cs deleted file mode 100644 index a686d45d6b..0000000000 --- a/src/SDSL/Parsers/AST/Shader/Statements.cs +++ /dev/null @@ -1,217 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - - -public abstract class Statement : ShaderTokenTyped -{ - public override SymbolType? InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - throw new NotImplementedException(); - } -} - -public class EmptyStatement : Statement -{ - public override SymbolType? InferredType => SymbolType.Void; - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) { } -} - -public abstract class Declaration : Statement -{ - public override SymbolType? InferredType => SymbolType.Void; - public SymbolType? TypeName { get; set; } - public string VariableName { get; set; } - -} - -public class DeclareAssign : Declaration, IStaticCheck, IStreamCheck -{ - public AssignOpToken AssignOp { get; set; } - public ShaderTokenTyped Value { get; set; } - - - public DeclareAssign() { } - public DeclareAssign(Match m, SymbolTable s) - { - Match = m; - AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - TypeName = s.ParseType(m["ValueTypes"].StringValue); - VariableName = m["Variable"].StringValue; - Value = (ShaderTokenTyped)GetToken(m["Value"], s); - } - - public bool CheckStatic(SymbolTable s) - { - return Value is IStaticCheck sc && - sc.CheckStatic(s); - } - - public bool CheckStream(SymbolTable s) - { - return Value is IStreamCheck sc && - sc.CheckStream(s); - } - public IEnumerable GetUsedStream() - { - if (Value is IStreamCheck val) - return val.GetUsedStream(); - return Enumerable.Empty(); - } - public IEnumerable GetAssignedStream() - { - return Enumerable.Empty(); - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? _) - { - Value.TypeCheck(symbols, TypeName); - } -} - -public class SimpleDeclare : Declaration -{ - public SimpleDeclare() { } - public SimpleDeclare(Match m, SymbolTable s) - { - Match = m; - VariableName = m["Variable"].StringValue; - TypeName = s.ParseType(m["ValueTypes"].StringValue); - - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) { } -} - -public class AssignChain : Statement, IStreamCheck, IStaticCheck, IVariableCheck -{ - public override SymbolType? InferredType => SymbolType.Void; - - public AssignOpToken AssignOp { get; set; } - public bool StreamValue => AccessNames.Any() && AccessNames.First() == "streams"; - public List AccessNames { get; set; } - public ShaderTokenTyped Value { get; set; } - public AssignChain(Match m, SymbolTable s) - { - Match = m; - AssignOp = m["AssignOp"].StringValue.ToAssignOp(); - AccessNames = m.Matches.Where(x => x.Name == "Identifier").Select(x => x.StringValue).ToList(); - Value = (ShaderTokenTyped)GetToken(m["PrimaryExpression"], s); - } - - public bool CheckStream(SymbolTable s) - { - return StreamValue || Value is IStreamCheck isc && isc.CheckStream(s); - } - - public IEnumerable GetAssignedStream() - { - if (StreamValue) - return new List() { AccessNames.ElementAt(1) }; - else - return Enumerable.Empty(); - } - public IEnumerable GetUsedStream() - { - if (Value is IStreamCheck v) - return v.GetUsedStream(); - else - return Enumerable.Empty(); - } - - public bool CheckStatic(SymbolTable s) - { - return Value is IStaticCheck isc && isc.CheckStatic(s); - } - - public void CheckVariables(SymbolTable s) - { - if (Value is IVariableCheck v) v.CheckVariables(s); - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - throw new NotImplementedException("TODO"); - } -} - -public class ReturnStatement : Statement, IStreamCheck, IStaticCheck -{ - public override SymbolType? InferredType => ReturnValue?.InferredType ?? SymbolType.Void; - - public ShaderTokenTyped? ReturnValue { get; set; } - public ReturnStatement(Match m, SymbolTable s) - { - Match = m; - if (m.HasMatches) - { - ReturnValue = (ShaderTokenTyped)GetToken(m["PrimaryExpression"], s); - } - } - - public bool CheckStream(SymbolTable s) - { - return ReturnValue is IStreamCheck sc && sc.CheckStream(s); - } - - public IEnumerable GetUsedStream() - { - if (ReturnValue is IStreamCheck isc) - return isc.GetUsedStream(); - return Enumerable.Empty(); - } - public IEnumerable GetAssignedStream() - { - return Enumerable.Empty(); - } - - public bool CheckStatic(SymbolTable s) - { - return ReturnValue is IStaticCheck sc && sc.CheckStatic(s); - } - - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - ReturnValue?.TypeCheck(symbols, expected); - if(ReturnValue?.InferredType != expected) - throw new Exception($"Type not matching, expected return type {expected?.ToString() ?? "void"}, and returned {ReturnValue?.InferredType}"); - - } -} - -public class BlockStatement : Statement, IStreamCheck, IStaticCheck -{ - public IEnumerable Statements { get; set; } - public BlockStatement(Match m, SymbolTable s) - { - Match = m; - throw new NotImplementedException(); - // Statements = m.Matches.Select(GetToken).Cast().ToList(); - } - - public bool CheckStream(SymbolTable s) - { - return Statements.Any(x => x is IStreamCheck isc && isc.CheckStream(s)); - } - public IEnumerable GetUsedStream() - { - return Statements.OfType().SelectMany(x => x.GetUsedStream()); - } - public IEnumerable GetAssignedStream() - { - return Statements.OfType().SelectMany(x => x.GetAssignedStream()); - } - - public bool CheckStatic(SymbolTable s) - { - return Statements.Any(x => x is IStaticCheck isc && isc.CheckStatic(s)); - } -} diff --git a/src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs b/src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs deleted file mode 100644 index 90dcacdac5..0000000000 --- a/src/SDSL/Parsers/AST/Shader/UnaryLiterals.cs +++ /dev/null @@ -1,134 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Symbols; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing.AST.Shader; - - -public class UnaryExpression : Expression -{ - public override SymbolType? InferredType { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } -} - -public class ChainAccessor : UnaryExpression, IStreamCheck, IVariableCheck -{ - public ShaderToken Value { get; set; } - public List Field { get; set; } - public override SymbolType? InferredType { get => inferredType; set => inferredType = value; } - - public ChainAccessor(Match m, SymbolTable s) - { - Match = m; - Value = GetToken(m.Matches["Identifier"], s); - Field = m.Matches.GetRange(1, m.Matches.Count - 1).Select(x => GetToken(x, s)).ToList(); - } - - public IEnumerable GetUsedStream() - { - if (Value is VariableNameLiteral vn && vn.Name == "streams") - return new List { ((VariableNameLiteral)Field.First()).Name }; - return Enumerable.Empty(); - } - public IEnumerable GetAssignedStream() - { - return Enumerable.Empty(); - } - public bool CheckStream(SymbolTable symbols) - { - return GetUsedStream().Any(); - } - public void CheckVariables(SymbolTable s) - { - if (Value is IVariableCheck n) n.CheckVariables(s); - } - public override void TypeCheck(SymbolTable symbols, in SymbolType? expected) - { - throw new NotImplementedException("TODO"); - // if (Value is VariableNameLiteral vn && symbols.TryGet(vn.Name, out var type)) - // { - // SymbolType current = type; - - // foreach (var a in Field) - // { - // var tmp = current; - // if (a is VariableNameLiteral vna) - // { - // if(!current.TryAccessType(vna.Name, out current)) - // { - // // symbols.AddError(Match, $"Accessor `{vna.Name}` does not exist for type `{tmp}`"); - // } - // } - // } - // inferredType = current; - // } - } -} - -public class ArrayAccessor : UnaryExpression, IVariableCheck -{ - public ShaderToken Value { get; set; } - public IEnumerable Accessors { get; set; } - - public ArrayAccessor(Match m, SymbolTable s) - { - Match = m; - Value = GetToken(m.Matches[0], s); - throw new NotImplementedException(); - // Accessors = m.Matches.GetRange(1,m.Matches.Count-1).Select(GetToken); - } - public void CheckVariables(SymbolTable s) - { - if (Value is IVariableCheck n) n.CheckVariables(s); - } -} - - -public class PostfixIncrement : UnaryExpression, IVariableCheck -{ - public string Operator { get; set; } - public ShaderToken Value { get; set; } - public PostfixIncrement(Match m, SymbolTable s) - { - Match = m; - Value = GetToken(m.Matches[0], s); - Operator = m.Matches[1].StringValue; - } - - public override string ToString() - { - return $"{{ PostfixIncrement : [\"{Value}\", \"{Operator}\"] }}"; - } - public void CheckVariables(SymbolTable s) - { - if (Value is VariableNameLiteral n) n.CheckVariables(s); - } -} - -public class PrefixIncrement : UnaryExpression -{ - public string Operator { get; set; } - public ShaderToken Value { get; set; } - public PrefixIncrement(Match m, SymbolTable s) - { - Match = m; - Operator = m.Matches[0].StringValue; - Value = GetToken(m.Matches[1], s); - } -} - -public class CastExpression : UnaryExpression -{ - public TypeNameLiteral Target { get; set; } - public ShaderToken From { get; set; } - public CastExpression(Match m, SymbolTable s) - { - Target = new TypeNameLiteral(m.Matches[0], s); - From = GetToken(m.Matches[1], s); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/DirectivePreprocessor.cs b/src/SDSL/Parsers/DirectivePreprocessor.cs deleted file mode 100644 index ae249ad53f..0000000000 --- a/src/SDSL/Parsers/DirectivePreprocessor.cs +++ /dev/null @@ -1,78 +0,0 @@ -using SDSL.Parsing.AST.Directives; -using SDSL.Parsing.Grammars.Comments; -using SDSL.Parsing.Grammars.Directive; -using SDSL.Parsing.Grammars.Macros; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace SDSL.Parsing; - -public class DirectivePreprocessor -{ - Dictionary macros; - public CommentGrammar CommentParser { get; set; } - public DirectiveGrammar DirectivesParser { get; set; } = new(); - public MacroGrammar MacrosParser { get; set; } - public Dictionary Macros - { - get => macros; - set { macros = value; MacrosParser = new(macros.Keys.ToArray()); } - } - - public DirectivePreprocessor() - { - DirectivesParser = new(); - CommentParser = new(); - MacrosParser = new(); - macros = new(); - } - - public string RemoveComments(string code) - { - var comments = CommentParser.Match(code); - var uncommentedCode = new StringBuilder(); - if (!comments.Matches.Any(x => x.Name == "Comment")) - { - return code; - } - else - { - foreach (var m in comments.Matches) - { - if (m.Name == "ActualCode") - { - uncommentedCode.AppendLine(m.StringValue); - } - } - return uncommentedCode.ToString(); - } - } - - public DirectiveToken ParseDirectives(in string code) - { - var parseTree = DirectivesParser.Match(code); - if (!parseTree.Success) - throw new Exception(parseTree.ErrorMessage); - return DirectiveToken.GetToken(parseTree["Directives"]); - } - - public string PreProcess(string shader) - { - var uncommentedCode = RemoveComments(shader); - var AST = ParseDirectives(uncommentedCode); - AST.EvaluateMacros(macros); - var afterDirectives = new StringBuilder(); - DirectiveToken.Evaluate(AST, macros, afterDirectives); - var matches = MacrosParser.Match(afterDirectives.ToString()); - if (!matches.Success) - throw new Exception(matches.ErrorMessage); - var replaceDefines = new StringBuilder(); - foreach(var m in matches.Matches) - replaceDefines.Append(m.Name == "ActualCode" ? m.StringValue : macros[m.StringValue]); - return replaceDefines.ToString(); - } - -} diff --git a/src/SDSL/Parsers/ExpressionParser.cs b/src/SDSL/Parsers/ExpressionParser.cs deleted file mode 100644 index 4261bead8c..0000000000 --- a/src/SDSL/Parsers/ExpressionParser.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace SDSL.Parsing; - -using Eto.Parse; -using Eto.Parse.Grammars; -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.Grammars; -using SDSL.Parsing.Grammars.Comments; -using SDSL.Parsing.Grammars.Directive; -using SDSL.Parsing.Grammars.Expression; -using SDSL.Parsing.Grammars.SDSL; -using System.Text; -public class ExpressionParser -{ - public ExpressionGrammar Grammar { get; set; } = new(); - - public ShaderToken Parse(string expr) - { - var match = Grammar.Match(expr); - if (!match.Success) - throw new ArgumentOutOfRangeException(nameof(expr), string.Format("Invalid expr string: {0}", match.ErrorMessage)); - return ShaderToken.Tokenize(match.Matches.First()); - } - -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/CommentGrammar.cs b/src/SDSL/Parsers/Grammars/CommentGrammar.cs deleted file mode 100644 index b990a2f84b..0000000000 --- a/src/SDSL/Parsers/Grammars/CommentGrammar.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace SDSL.Parsing.Grammars.Comments; - -public class CommentGrammar : Grammar -{ - public SequenceParser Comments = new(); - - public CommentGrammar() : base("comments-sdsl") - { - var commentStart = - Literal("//") - | Literal("/*"); - var singleLineComment = Literal("//").Then(AnyChar.Repeat(0).Until(Eol,false,true)).WithName("Comment"); - var blockComment = Literal("/*").Then(AnyChar.Repeat(0).Until("*/",false,true)).WithName("Comment"); - var anyComments = singleLineComment | blockComment; - var actualCode = AnyChar.Repeat(0).Until(End | "//" | "/*" ).Named("ActualCode"); - Comments.Add( - (anyComments | actualCode).Repeat(0).Until(End) - ); - Inner = Comments; - } -} diff --git a/src/SDSL/Parsers/Grammars/CommonParsers.Tokens.cs b/src/SDSL/Parsers/Grammars/CommonParsers.Tokens.cs deleted file mode 100644 index 0b2f608357..0000000000 --- a/src/SDSL/Parsers/Grammars/CommonParsers.Tokens.cs +++ /dev/null @@ -1,171 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; - -namespace SDSL.Parsing.Grammars; - -public static class CommonParsers -{ - - static CommonParsers() - { - TextureBase = - ( - Terminals.Literal("Texture2DMS") - | Terminals.Literal("TextureCube") - | Terminals.Literal("Texture") & Terminals.Set("123") & "D" - ) & ~Terminals.Literal("Array"); - TextureTypes = - (TextureBase & "<" & (BuiltinNumericTypes | Identifier) & ">").SeparatedBy(Spaces) - | TextureBase; - BufferTypes = - (Buffer & "<" & (BuiltinNumericTypes | Identifier) & ">").SeparatedBy(Spaces) - | Buffer; - - } - public static SequenceParser Identifier { get; } = (Terminals.Letter | "_") & (Terminals.Letter | Terminals.Digit | "_") * 0; - public static SequenceParser TextureBase { get; } - public static AlternativeParser TextureTypes { get; } - public static AlternativeParser BufferTypes { get; } - public static Parser Space => Terminals.WhiteSpace; - public static RepeatParser Spaces { get; } = Terminals.WhiteSpace * 0; - public static RepeatParser Spaces1 { get; } = Terminals.WhiteSpace * 1; - public static LiteralTerminal AppendStructuredBuffer { get; } = new(); - public static AlternativeParser ComponentNumber { get; } = new(); - - public static SequenceParser BuiltinNumericTypes { get; } = - (Terminals.Literal("void") | "void" | "byte" | "sbyte" | "short" | "ushort" | "half" | "int" | "uint" | "float" | "long" | "ulong" | "double") - & ( - (Terminals.Set("234") & "x" & Terminals.Set("234")) - | Terminals.Set("234") - ); - - public static CharTerminal IntegerSuffix { get; } = Terminals.Set("ulUL").WithName("IntegerSuffix"); - public static CharTerminal FloatSuffix { get; } = Terminals.Set("fdFD").WithName("FloatSuffix"); - public static LiteralTerminal Buffer { get; } = Terminals.Literal("buffer").WithName("Buffer"); - public static LiteralTerminal ByteAddressBuffer { get; } = Terminals.Literal("ByteAddressBuffer").WithName("ByteAddressBuffer"); - public static LiteralTerminal Break { get; } = Terminals.Literal("break").WithName("Break"); - public static LiteralTerminal Case { get; } = Terminals.Literal("case").WithName("Case"); - public static LiteralTerminal CBuffer { get; } = Terminals.Literal("cBuffer").WithName("CBuffer"); - public static LiteralTerminal Centroid { get; } = Terminals.Literal("centroid").WithName("Centroid"); - public static LiteralTerminal Class { get; } = Terminals.Literal("class").WithName("Class"); - public static LiteralTerminal ColumnMajor { get; } = Terminals.Literal("ColumnMajor").WithName("ColumnMajor"); - public static LiteralTerminal Const { get; } = Terminals.Literal("const").WithName("Const"); - public static LiteralTerminal ConsumeStructuredBuffer { get; } = Terminals.Literal("ConsumeStructuredBuffer").WithName("ConsumeStructuredBuffer"); - public static LiteralTerminal Continue { get; } = Terminals.Literal("continue").WithName("Continue"); - public static LiteralTerminal Default { get; } = Terminals.Literal("default").WithName("Default"); - public static LiteralTerminal Discard { get; } = Terminals.Literal("discard").WithName("Discard"); - public static LiteralTerminal Do { get; } = Terminals.Literal("do").WithName("Do"); - public static LiteralTerminal Else { get; } = Terminals.Literal("else").WithName("Else"); - public static LiteralTerminal Extern { get; } = Terminals.Literal("extern").WithName("Extern"); - public static LiteralTerminal For { get; } = Terminals.Literal("for").WithName("For"); - public static LiteralTerminal Groupshared { get; } = Terminals.Literal("groupshared").WithName("Groupshared"); - public static LiteralTerminal If { get; } = Terminals.Literal("if").WithName("If"); - public static LiteralTerminal In { get; } = Terminals.Literal("in").WithName("In"); - public static LiteralTerminal Inout { get; } = Terminals.Literal("inout").WithName("Inout"); - public static LiteralTerminal InputPatch { get; } = Terminals.Literal("inputpatch").WithName("InputPatch"); - public static LiteralTerminal Interface { get; } = Terminals.Literal("interface").WithName("Interface"); - - // public LiteralTerminal Line_ { get; set; } - - public static LiteralTerminal LineAdj { get; } = Terminals.Literal("lineAdj").WithName("LineAdj"); - public static LiteralTerminal Linear { get; } = Terminals.Literal("linear").WithName("Linear"); - public static LiteralTerminal LineStream { get; } = Terminals.Literal("LineStream").WithName("LineStream"); - public static LiteralTerminal Matrix { get; } = Terminals.Literal("matrix").WithName("Matrix"); - public static LiteralTerminal Nointerpolation { get; } = Terminals.Literal("nointerpolation").WithName("Nointerpolation"); - public static LiteralTerminal Noperspective { get; } = Terminals.Literal("noperspective").WithName("Noperspective"); - public static LiteralTerminal Out { get; } = Terminals.Literal("out").WithName("Out"); - public static LiteralTerminal OutputPatch { get; } = Terminals.Literal("OutputPatch").WithName("OutputPatch"); - public static LiteralTerminal Packoffset { get; } = Terminals.Literal("packoffset").WithName("Packoffset"); - public static LiteralTerminal Point { get; } = Terminals.Literal("point").WithName("Point"); - public static LiteralTerminal PointStream { get; } = Terminals.Literal("PointStream").WithName("PointStream"); - public static LiteralTerminal Precise { get; } = Terminals.Literal("precise").WithName("Precise"); - public static LiteralTerminal Register { get; } = Terminals.Literal("register").WithName("Register"); - public static LiteralTerminal Return { get; } = Terminals.Literal("return").WithName("Return"); - public static LiteralTerminal RowMajor { get; } = Terminals.Literal("rowMajor").WithName("RowMajor"); - public static LiteralTerminal RWBuffer { get; } = Terminals.Literal("RWBuffer").WithName("RWBuffer"); - public static LiteralTerminal RWByteAddressBuffer { get; } = Terminals.Literal("RWByteAddressBuffer").WithName("RWByteAddressBuffer"); - public static LiteralTerminal RWStructuredBuffer { get; } = Terminals.Literal("RWStructuredBuffer").WithName("RWStructuredBuffer"); - public static LiteralTerminal Sample { get; } = Terminals.Literal("sample").WithName("Sample"); - public static LiteralTerminal Sampler { get; } = Terminals.Literal("sampler").WithName("Sampler"); - public static LiteralTerminal SamplerComparisonState { get; } = Terminals.Literal("SamplerComparisonState").WithName("SamplerComparisonState"); - public static LiteralTerminal SamplerState { get; } = Terminals.Literal("SamplerState").WithName("SamplerState"); - public static LiteralTerminal Shared { get; } = Terminals.Literal("shared").WithName("Shared"); - public static LiteralTerminal StaticConst { get; } = Terminals.Literal("staticConst").WithName("StaticConst"); - public static LiteralTerminal Static { get; } = Terminals.Literal("static").WithName("Static"); - public static LiteralTerminal Struct { get; } = Terminals.Literal("struct").WithName("Struct"); - public static LiteralTerminal StructuredBuffer { get; } = Terminals.Literal("StructuredBuffer").WithName("StructuredBuffer"); - public static LiteralTerminal Switch { get; } = Terminals.Literal("switch").WithName("Switch"); - public static LiteralTerminal Triangle { get; } = Terminals.Literal("triangle").WithName("Triangle"); - public static LiteralTerminal TriangleAdj { get; } = Terminals.Literal("triangleadj").WithName("TriangleAdj"); - public static LiteralTerminal TriangleStream { get; } = Terminals.Literal("TriangleStream").WithName("TriangleStream"); - public static LiteralTerminal Uniform { get; } = Terminals.Literal("uniform").WithName("Uniform"); - public static LiteralTerminal Vector { get; } = Terminals.Literal("vector").WithName("Vector"); - public static LiteralTerminal Volatile { get; } = Terminals.Literal("volatile").WithName("Volatile"); - public static LiteralTerminal Void { get; } = Terminals.Literal("void").WithName("Void"); - public static LiteralTerminal While { get; } = Terminals.Literal("while").WithName("While"); - public static LiteralTerminal LeftParen { get; } = Terminals.Literal("(").WithName("LeftParen"); - public static LiteralTerminal RightParen { get; } = Terminals.Literal(")").WithName("RightParen"); - public static LiteralTerminal LeftBracket { get; } = Terminals.Literal("[").WithName("LeftBracket"); - public static LiteralTerminal RightBracket { get; } = Terminals.Literal("]").WithName("RightBracket"); - public static LiteralTerminal LeftBrace { get; } = Terminals.Literal("{").WithName("LeftBrace"); - public static LiteralTerminal RightBrace { get; } = Terminals.Literal("}").WithName("RightBrace"); - public static LiteralTerminal LeftShift { get; } = Terminals.Literal("<<").WithName("LeftShift"); - public static LiteralTerminal RightShift { get; } = Terminals.Literal(">>").WithName("RightShift"); - public static LiteralTerminal Plus { get; } = Terminals.Literal("+").WithName("Plus"); - public static LiteralTerminal PlusPlus { get; } = Terminals.Literal("++").WithName("PlusPlus"); - public static LiteralTerminal Minus { get; } = Terminals.Literal("-").WithName("Minus"); - public static LiteralTerminal MinusMinus { get; } = Terminals.Literal("--").WithName("MinusMinus"); - public static LiteralTerminal Star { get; } = Terminals.Literal("*").WithName("Star"); - public static LiteralTerminal Div { get; } = Terminals.Literal("/").WithName("Div"); - public static LiteralTerminal Mod { get; } = Terminals.Literal("%").WithName("Mod"); - public static LiteralTerminal And { get; } = Terminals.Literal("&").WithName("And"); - public static LiteralTerminal Or { get; } = Terminals.Literal("|").WithName("Or"); - public static LiteralTerminal AndAnd { get; } = Terminals.Literal("&&").WithName("AndAnd"); - public static LiteralTerminal OrOr { get; } = Terminals.Literal("||").WithName("OrOr"); - public static LiteralTerminal Caret { get; } = Terminals.Literal("^").WithName("Caret"); - public static LiteralTerminal Not { get; } = Terminals.Literal("!").WithName("Not"); - public static LiteralTerminal Tilde { get; } = Terminals.Literal("~").WithName("Tilde"); - public static LiteralTerminal Equal { get; } = Terminals.Literal("==").WithName("Equal"); - public static LiteralTerminal NotEqual { get; } = Terminals.Literal("!=").WithName("NotEqual"); - public static LiteralTerminal Less { get; } = Terminals.Literal("<").WithName("Less"); - public static LiteralTerminal LessEqual { get; } = Terminals.Literal("<=").WithName("LessEqual"); - public static LiteralTerminal Greater { get; } = Terminals.Literal(">").WithName("Greater"); - public static LiteralTerminal GreaterEqual { get; } = Terminals.Literal(">=").WithName("GreaterEqual"); - public static LiteralTerminal Question { get; } = Terminals.Literal("?").WithName("Question"); - public static LiteralTerminal Colon { get; } = Terminals.Literal(":").WithName("Colon"); - public static LiteralTerminal ColonColon { get; } = Terminals.Literal("::").WithName("ColonColon"); - public static LiteralTerminal Semi { get; } = Terminals.Literal(";").WithName("Semi"); - public static LiteralTerminal Comma { get; } = Terminals.Literal(",").WithName("Comma"); - public static LiteralTerminal Assign { get; } = Terminals.Literal("=").WithName("Assign"); - public static LiteralTerminal StarAssign { get; } = Terminals.Literal("*=").WithName("StarAssign"); - public static LiteralTerminal DivAssign { get; } = Terminals.Literal("/=").WithName("DivAssign"); - public static LiteralTerminal ModAssign { get; } = Terminals.Literal("%=").WithName("ModAssign"); - public static LiteralTerminal PlusAssign { get; } = Terminals.Literal("+=").WithName("PlusAssign"); - public static LiteralTerminal MinusAssign { get; } = Terminals.Literal("-=").WithName("MinusAssign"); - public static LiteralTerminal LeftShiftAssign { get; } = Terminals.Literal("<<=").WithName("LeftShiftAssign"); - public static LiteralTerminal RightShiftAssign { get; } = Terminals.Literal(">>=").WithName("RightShiftAssign"); - public static LiteralTerminal AndAssign { get; } = Terminals.Literal("&=").WithName("AndAssign"); - public static LiteralTerminal XorAssign { get; } = Terminals.Literal("^=").WithName("XorAssign"); - public static LiteralTerminal OrAssign { get; } = Terminals.Literal("|=").WithName("OrAssign"); - - public static LiteralTerminal Dot { get; } = Terminals.Literal(".").WithName("Dot"); - public static LiteralTerminal True { get; } = Terminals.Literal("true").WithName("True"); - public static LiteralTerminal False { get; } = Terminals.Literal("false").WithName("False"); - public static AlternativeParser PreprocessorDirectiveName { get; } = - (Terminals.Literal("define") - | "elif" - | "else" - | "endif" - | "error" - | "if" - | "ifdef" - | "ifndef" - | "include" - | "line" - | "pragma" - | "undef").WithName("PreprocessorDirectiveName"); - - public static LiteralTerminal Compose { get; } = Terminals.Literal("compose").WithName("Compose"); - public static LiteralTerminal Stream { get; } = Terminals.Literal("stream").WithName("Stream"); - public static LiteralTerminal Stage { get; } = Terminals.Literal("stage").WithName("Stage"); -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs deleted file mode 100644 index 5b3e02cbec..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.Expression.cs +++ /dev/null @@ -1,216 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace SDSL.Parsing.Grammars.Directive; -public partial class DirectiveGrammar : Grammar -{ - public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; - public AlternativeParser DirectivePostFixExpression = new() { Name = "DirectivePostFixExpression" }; - public AlternativeParser DirectiveUnaryExpression = new() { Name = "DirectiveUnaryExpression" }; - public AlternativeParser DirectiveCastExpression = new() { Name = "DirectiveCastExpression" }; - public AlternativeParser DirectiveMulExpression = new() { Name = "DirectiveMulExpression" }; - public AlternativeParser DirectiveSumExpression = new() { Name = "DirectiveSumExpression" }; - public AlternativeParser DirectiveShiftExpression = new() { Name = "DirectiveShiftExpression" }; - - public AlternativeParser DirectiveConditionalExpression = new() { Name = "DirectiveConditionalExpression" }; - public AlternativeParser DirectiveLogicalOrExpression = new() { Name = "DirectiveLogicalOrExpression" }; - public AlternativeParser DirectiveLogicalAndExpression = new() { Name = "DirectiveLogicalAndExpression" }; - public AlternativeParser DirectiveOrExpression = new() { Name = "DirectiveOrExpression" }; - public AlternativeParser DirectiveXorExpression = new() { Name = "DirectiveXorExpression" }; - public AlternativeParser DirectiveAndExpression = new() { Name = "DirectiveAndExpression" }; - public AlternativeParser DirectiveTestExpression = new() { Name = "DirectiveTestExpression" }; - - public AlternativeParser DirectiveIncrementExpression = new() { Name = "DirectiveIncrementExpression" }; - public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; - public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; - public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; - public DirectiveGrammar DirectiveUsingDirectiveExpression() - { - Inner = DirectiveExpression; - return this; - } - - public Parser Parenthesis(Parser p, bool notFollowedByUnary = true) - { - if (notFollowedByUnary) - return LeftParen.Then(p).Then(RightParen).SeparatedBy(SingleLineWhiteSpace.Repeat(0)).NotFollowedBy(DirectiveUnaryExpression); - else - return LeftParen.Then(p).Then(RightParen).SeparatedBy(SingleLineWhiteSpace.Repeat(0)); - } - public void CreateDirectiveExpressions() - { - var ws = SingleLineWhiteSpace.Repeat(0); - var ls1 = SingleLineWhiteSpace.Repeat(1); - - - - var incrementOp = new AlternativeParser(); - incrementOp.Add( - PlusPlus, - MinusMinus - ); - - var parameters = - DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws); - - var MethodCall = new AlternativeParser( - Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(ws).Named("DirectiveMethodCallExpression") - ); - - - DirectiveTermExpression.Add( - Literals, - ~(Plus | Minus & ws) & Identifier.Except(ValueTypes).NotFollowedBy(ws & LeftParen), - MethodCall, - Parenthesis(DirectiveExpression) - ); - - var arrayAccess = new SequenceParser(); - var chain = new SequenceParser(); - var postfixInc = new SequenceParser(); - - - arrayAccess.Add( - Identifier, - ws, - (LeftBracket & DirectiveExpression & RightBracket) - .SeparatedBy(ws) - .Repeat(1) - .SeparatedBy(ws) - ); - chain.Add( - (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(ws & Dot & ws) - ); - postfixInc.Add( - chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, - ws, - incrementOp.Named("Operator") - ); - - DirectivePostFixExpression.Add( - DirectiveTermExpression.NotFollowedBy(ws & (Dot | LeftBracket | incrementOp)), - postfixInc.Named("PostfixIncrement"), - chain.Named("AccessorChain"), - arrayAccess.Named("ArrayAccesor") - ); - - var prefixInc = new SequenceParser(); - prefixInc.Add( - incrementOp, - ws, - Identifier.NotFollowedBy(ws & (Dot | "[")) - | chain - | arrayAccess - ); - - DirectiveUnaryExpression.Add( - DirectivePostFixExpression, - prefixInc.Named("PrefixIncrement"), - Literal("sizeof").Then(LeftParen).Then(Identifier | DirectiveUnaryExpression).Then(RightParen).Named("SizeOf") - ); - - var cast = new SequenceParser(); - cast.Add( - LeftParen, - ValueTypes | Identifier, - RightParen, - DirectiveUnaryExpression - ); - - DirectiveCastExpression.Add( - DirectiveUnaryExpression, - cast.SeparatedBy(ws).Named("DirectiveCastExpression") - ); - - - var mulOp = Star | Div | Mod; - DirectiveMulExpression.Add( - DirectiveCastExpression.Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & mulOp.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - var sumOp = Plus | Minus; - - DirectiveSumExpression.Add( - DirectiveMulExpression.Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & sumOp.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - - var shiftOp = LeftShift | RightShift; - - DirectiveShiftExpression.Add( - DirectiveSumExpression.Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & shiftOp.Named("Operator") & ws).Until(ws & (Operators | Eol | End)) - ); - - - DirectiveAndExpression.Add( - DirectiveShiftExpression.Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & And.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - DirectiveXorExpression.Add( - DirectiveAndExpression.Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Literal("^").Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - - DirectiveOrExpression.Add( - DirectiveXorExpression.Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & Or.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - var testOp = LessEqual | Less | GreaterEqual | Greater; - - DirectiveTestExpression.Add( - DirectiveOrExpression.Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & testOp.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - var eqOp = - Literal("==") - | Literal("!="); - - DirectiveEqualsExpression.Add( - DirectiveTestExpression.Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & eqOp.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - DirectiveLogicalAndExpression.Add( - DirectiveEqualsExpression.Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & AndAnd.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - DirectiveLogicalOrExpression.Add( - DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws).Until(ws & (Eol | End)), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(ws & OrOr.Named("Operator") & ws).Until(ws & (Eol | End)) - ); - - DirectiveConditionalExpression.Add( - DirectiveLogicalOrExpression.NotFollowedBy(ws & "?"), - (Parenthesis(DirectiveLogicalOrExpression).NotFollowedBy(ws & OrOr) | DirectiveLogicalOrExpression) - .Then("?") - .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) - .Then(":") - .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) - .SeparatedBy(ws) - .Named("Ternary") - - ); - - DirectiveParenExpression.Add( - LeftParen.Then(DirectiveExpression).Then(RightParen).SeparatedBy(ws) - ); - - - var arrayDeclaration = - (LeftBrace & DirectiveExpression.Repeat(0).SeparatedBy(ws & Comma & ws) & RightBrace) - .SeparatedBy(ws); - - DirectiveExpression.Add( - BooleanTerm, - DirectiveConditionalExpression - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs deleted file mode 100644 index 6b04544a1f..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Directives.cs +++ /dev/null @@ -1,111 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace SDSL.Parsing.Grammars.Directive; -public partial class DirectiveGrammar : Grammar -{ - public SequenceParser IfDirective = new(){Name = "IfDirective"}; - public SequenceParser ElseDirective = new() { Name = "ElseDirective" }; - public SequenceParser ElifDirective = new(){Name = "ElifDirective"}; - public SequenceParser DefineDirective = new(){Name = "DefineDirective"}; - public SequenceParser EndIfDirective = new(){Name = "EndIfDirective"}; - - - public SequenceParser IfDefDirective = new() { Name = "IfDefDirective" }; - public SequenceParser IfNDefDirective = new(){Name = "IfNDefDirective"}; - - public SequenceParser IfDefCode = new() { Name = "IfDefCode" }; - public SequenceParser ElseCode = new() { Name = "ElseCode" }; - public SequenceParser IfCode = new() { Name = "IfCode" }; - public SequenceParser ElifCode = new() { Name = "ElifCode" }; - - - public SequenceParser ConditionalDirectives = new(){Name = "ConditionalDirectives"}; - public SequenceParser DefinitionDirectives = new(){Name = "DefineDirectives"}; - public AlternativeParser AnyDirectives = new(); - - public SequenceParser Directives = new(); - - public void CreateDirectives() - { - var ls = SingleLineWhiteSpace.Repeat(0); - var ls1 = SingleLineWhiteSpace.Repeat(1); - var ws = WhiteSpace.Repeat(0); - - var hash = Literal("#"); - var hashIfNDef = Literal("#ifndef").Named("ifndef"); - var hashIfDef = Literal("#ifdef").Named("ifdef"); - var hashIf = Literal("#if").Named("if"); - var hashEndIf = Literal("#endif").Named("endif"); - var hashElse = Literal("#else").Named("else"); - var hashElif = Literal("#elif").Named("elif"); - var hashDefine = Literal("#define").Named("define"); - - var startHash = - hashIfNDef - | hashIfDef - | hashIf - | hashDefine; - - var anyHash = - startHash - | hashElif - | hashElse - | hashEndIf; - - IfDirective.Add(hashIf, ls1, DirectiveExpression, ls.Until(Eol | End, true)); - ElseDirective.Add(hashElse, ls.Until(Eol | End, true)); - ElifDirective.Add(hashElif, ls1, DirectiveExpression, ls.Until(Eol | End, true)); - EndIfDirective.Add(hashEndIf, ls.Until(Eol | End, true)); - IfDefDirective.Add(hashIfDef, ls1, Identifier, ls.Until(Eol | End, true)); - IfNDefDirective.Add(hashIfNDef, ls1, Identifier, ls.Until(Eol | End, true)); - DefineDirective.Add(hashDefine, ls1, Identifier, ~(ls1 & DirectiveExpression), ls.Until(Eol | End)); - - - - var CodeOrDirective = - AnyDirectives - .Or(AnyChar.Repeat(0).Until(startHash | End).Named("CodeSnippet")) - .Repeat(1).Until(End); - - IfDefCode.Add( - IfDefDirective | IfNDefDirective, - AnyDirectives.Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) - .Repeat(0).Until(hashElse | hashEndIf).Named("Children"), - EndIfDirective | ElseCode & EndIfDirective - ); - - ElseCode.Add( - ElseDirective, - AnyDirectives - .Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) - .Repeat(0).Until(hashEndIf).Named("Children") - ); - - IfCode.Add( - IfDirective, - AnyDirectives.Or(AnyChar.Repeat(0).Until(anyHash).Named("CodeSnippet")) - .Repeat(0).Until(hashElif | hashElse | hashEndIf).Named("Children"), - ElifCode.Repeat(0), - EndIfDirective | ElseCode & EndIfDirective - ); - - ElifCode.Add( - ElifDirective, - AnyDirectives.Or(AnyChar.Repeat(0).Until(startHash).Named("CodeSnippet")) - .Repeat(0).Until(hashElse | hashEndIf).Named("Children") - ); - - AnyDirectives.Add( - DefineDirective, - IfDefCode, - IfCode - ); - - Directives.Add( - CodeOrDirective.Until(End).Named("Directives") - ); - Inner = Directives; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs deleted file mode 100644 index 0d01b69db3..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.Tokens.cs +++ /dev/null @@ -1,128 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -namespace SDSL.Parsing.Grammars.Directive; -public partial class DirectiveGrammar : Grammar -{ - - private LiteralTerminal Bool = new(); - private AlternativeParser Uint = new(); - private LiteralTerminal Int = new(); - private LiteralTerminal Long = new(); - - - private LiteralTerminal Half = new(); - private LiteralTerminal Float = new(); - private LiteralTerminal Double = new(); - - private LiteralTerminal LeftParen = new(); - private LiteralTerminal RightParen = new(); - private LiteralTerminal LeftBracket = new(); - private LiteralTerminal RightBracket = new(); - private LiteralTerminal LeftBrace = new(); - private LiteralTerminal RightBrace = new(); - - private LiteralTerminal LeftShift = new(); - private LiteralTerminal RightShift = new(); - private LiteralTerminal Plus = new(); - private LiteralTerminal PlusPlus = new(); - private LiteralTerminal Minus = new(); - private LiteralTerminal MinusMinus = new(); - private LiteralTerminal Star = new(); - private LiteralTerminal Div = new(); - private LiteralTerminal Mod = new(); - private LiteralTerminal And = new(); - private LiteralTerminal Or = new(); - private LiteralTerminal AndAnd = new(); - private LiteralTerminal OrOr = new(); - private LiteralTerminal Caret = new(); - private LiteralTerminal Not = new(); - private LiteralTerminal Tilde = new(); - private LiteralTerminal Equal = new(); - private LiteralTerminal NotEqual = new(); - private LiteralTerminal Less = new(); - private LiteralTerminal LessEqual = new(); - private LiteralTerminal Greater = new(); - private LiteralTerminal GreaterEqual = new(); - private LiteralTerminal Question = new(); - private LiteralTerminal Colon = new(); - private LiteralTerminal ColonColon = new(); - private LiteralTerminal Semi = new(); - private LiteralTerminal Comma = new(); - private LiteralTerminal Assign = new(); - private LiteralTerminal StarAssign = new(); - private LiteralTerminal DivAssign = new(); - private LiteralTerminal ModAssign = new(); - private LiteralTerminal PlusAssign = new(); - private LiteralTerminal MinusAssign = new(); - private LiteralTerminal LeftShiftAssign = new(); - private LiteralTerminal RightShiftAssign = new(); - private LiteralTerminal AndAssign = new(); - private LiteralTerminal XorAssign = new(); - private LiteralTerminal OrAssign = new(); - - private LiteralTerminal Dot = new(); - - - public void CreateTokens() - { - - Bool = Literal("bool"); - Uint.Add("uint","unsigned int", "dword"); - Int = Literal("int"); - Long = Literal("long"); - - Half = Literal("half"); - Float = Literal("float"); - Double = Literal("double"); - - LeftParen = Literal("("); - RightParen = Literal(")"); - LeftBracket = Literal("["); - RightBracket = Literal("]"); - LeftBrace = Literal("{"); - RightBrace = Literal("}"); - - LeftShift = Literal("<<"); - RightShift = Literal(">>"); - Plus = Literal("+"); - PlusPlus = Literal("++"); - Minus = Literal("-"); - MinusMinus = Literal("--"); - Star = Literal("*"); - Div = Literal("/"); - Mod = Literal("%"); - And = Literal("&"); - Or = Literal("|"); - AndAnd = Literal("&&"); - OrOr = Literal("||"); - Caret = Literal("^"); - Not = Literal("!"); - Tilde = Literal("~"); - Equal = Literal("=="); - NotEqual = Literal("!="); - Less = Literal("<"); - LessEqual = Literal("<="); - Greater = Literal(">"); - GreaterEqual = Literal(">="); - Question = Literal("?"); - Colon = Literal(":"); - ColonColon = Literal("::"); - Semi = Literal(";"); - Comma = Literal(","); - Assign = Literal("="); - StarAssign = Literal("*="); - DivAssign = Literal("/="); - ModAssign = Literal("%="); - PlusAssign = Literal("+="); - MinusAssign = Literal("-="); - LeftShiftAssign = Literal("<<="); - RightShiftAssign = Literal(">>="); - AndAssign = Literal("&="); - XorAssign = Literal("^="); - OrAssign = Literal("|="); - - Dot = Literal("."); - - } -} diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs deleted file mode 100644 index 4d09d19f0f..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/DirectiveGrammar.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace SDSL.Parsing.Grammars.Directive; - -public partial class DirectiveGrammar : Grammar -{ - public DirectiveGrammar() - { - CreateAll(); - } - - public void CreateAll() - { - CreateTokens(); - CreateTokenGroups(); - CreateLiterals(); - CreateDirectives(); - CreateDirectiveExpressions(); - } -} diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs deleted file mode 100644 index 94f31963da..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.Literals.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -using EtoParser = Eto.Parse.Parser; - -namespace SDSL.Parsing.Grammars.Directive; -public partial class DirectiveGrammar : Grammar -{ - AlternativeParser IntegerSuffix = new(); - AlternativeParser FloatSuffix = new(); - - public StringParser StringLiteral = new(); - public SequenceParser Identifier = new(); - - public NumberParser IntegerLiteral = new(); - public NumberParser FloatLiteral = new(); - public HexDigitTerminal HexDigits = new(); - public SequenceParser HexaDecimalLiteral = new(); - - public BooleanTerminal BooleanTerm = new(); - - public AlternativeParser Literals = new(); - - public void CreateLiterals() - { - Identifier.Add( - Letter.Or("_").Then(LetterOrDigit.Or("_").Repeat(0)).WithName("Identifier") - ); - - IntegerSuffix.Add( - "u", - "l", - "U", - "L" - ); - - FloatSuffix.Add( - "f", - "d", - "F", - "D" - ); - - - - StringLiteral = new StringParser().WithName("StringLiteral"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "float_value"}.WithName("IntegerValue"); - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Name = "int_value"}.WithName("FloatValue"); - HexDigits = new(); - HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); - - BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = new string[]{"true"},FalseValues = new string[]{"false"}, Name = "Boolean"}; - - Literals.Add( - IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Named("IntegerLiteral"), - FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix.Optional()).Named("FloatLiteral"), - HexaDecimalLiteral, - StringLiteral, - BooleanTerm - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs b/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs deleted file mode 100644 index a801098796..0000000000 --- a/src/SDSL/Parsers/Grammars/DirectiveGrammar/SDSLGrammar.TokenGroups.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace SDSL.Parsing.Grammars.Directive; -public partial class DirectiveGrammar : Grammar -{ - public AlternativeParser IncOperators = new(); - - public AlternativeParser Operators = new(); - public AlternativeParser AssignOperators = new(); - - public AlternativeParser ValueTypes = new(); - - public void CreateTokenGroups() - { - IncOperators.Add( - PlusPlus, - MinusMinus - ); - - Operators.Add( - PlusPlus, - Plus, - MinusMinus, - Minus, - Star, - Div, - Mod, - LeftShift, - RightShift, - AndAnd, - And, - OrOr, - Or, - "^", - Equal, - "==", - NotEqual, - Question - - ); - - AssignOperators.Add( - Assign, - StarAssign, - DivAssign, - ModAssign, - PlusAssign, - MinusAssign, - LeftShiftAssign, - RightShiftAssign, - AndAssign, - XorAssign, - OrAssign - ); - - - ValueTypes.Add( - Bool, - Half, - Float, - Double, - Int, - Uint, - Long - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/ExpressionGrammar.cs b/src/SDSL/Parsers/Grammars/ExpressionGrammar.cs deleted file mode 100644 index 78a3b552d8..0000000000 --- a/src/SDSL/Parsers/Grammars/ExpressionGrammar.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using SDSL.Parsing.Grammars.SDSL; -using static Eto.Parse.Terminals; - - -namespace SDSL.Parsing.Grammars.Expression; - -public class ExpressionGrammar : SDSLGrammar -{ - public ExpressionGrammar() : base() - { - Using(PrimaryExpression); - } -} diff --git a/src/SDSL/Parsers/Grammars/MacroGrammar.cs b/src/SDSL/Parsers/Grammars/MacroGrammar.cs deleted file mode 100644 index 14d09ad3c7..0000000000 --- a/src/SDSL/Parsers/Grammars/MacroGrammar.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace SDSL.Parsing.Grammars.Macros; - -public class MacroGrammar : Grammar -{ - - public MacroGrammar(params string[] variableNames) : base("variables-sdsl") - { - var altVars = new AlternativeParser(variableNames.Select(Literal)) - { - Name = "MacroVariable" - }; - var grammar = new AlternativeParser( - AnyChar.Repeat(0).Until(altVars).Named("ActualCode") & altVars - | AnyChar.Repeat(0).Until(End).Named("ActualCode") - ); - Inner = grammar.Repeat(0); - } -} diff --git a/src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs b/src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs deleted file mode 100644 index 4b85df3c12..0000000000 --- a/src/SDSL/Parsers/Grammars/NativeTypeGrammar.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - - -namespace SDSL.Parsing.Grammars.NativeType; - -public class NativeTypeGrammar : Grammar -{ - static NativeTypeGrammar global = new(); - - public static Match ParseNativeType(string s) => global.Match(s); - - public NativeTypeGrammar() : base("native-type-sdsl") - { - var numbers = new NumberParser(){AllowDecimal = false, AllowSign = false, AllowExponent = false, ValueType = typeof(int)}; - Inner = new AlternativeParser( - Literal("bool").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("BoolMatrix"), - - Literal("ulong").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ULongMatrix"), - Literal("long").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("LongMatrix"), - Literal("double").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("DoubleMatrix"), - - Literal("uint").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("UIntMatrix"), - Literal("int").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("IntMatrix"), - Literal("float").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("FloatMatrix"), - - Literal("ushort").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("UShortMatrix"), - Literal("short").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ShortMatrix"), - Literal("half").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("HalfMatrix"), - - Literal("byte").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("ByteMatrix"), - Literal("sbyte").Then(numbers.Named("RowCount")).Then("x").Then(numbers.Named("ColCount")).Named("SByteMatrix"), - - Literal("bool").Then(numbers.Named("RowCount")).Named("BoolVector"), - - Literal("ulong").Then(numbers.Named("RowCount")).Named("ULongVector"), - Literal("long").Then(numbers.Named("RowCount")).Named("LongVector"), - Literal("double").Then(numbers.Named("RowCount")).Named("DoubleVector"), - - Literal("uint").Then(numbers.Named("RowCount")).Named("UIntVector"), - Literal("int").Then(numbers.Named("RowCount")).Named("IntVector"), - Literal("float").Then(numbers.Named("RowCount")).Named("FloatVector"), - - Literal("ushort").Then(numbers.Named("RowCount")).Named("UShortVector"), - Literal("short").Then(numbers.Named("RowCount")).Named("ShortVector"), - Literal("half").Then(numbers.Named("RowCount")).Named("HalfVector"), - - Literal("byte").Then(numbers.Named("RowCount")).Named("ByteVector"), - Literal("sbyte").Then(numbers.Named("RowCount")).Named("SByteVector"), - - - Literal("bool").Named("Bool"), - - Literal("ulong").Named("ULong"), - Literal("long").Named("Long"), - Literal("double").Named("Double"), - - Literal("uint").Named("UInt"), - Literal("int").Named("Int"), - Literal("float").Named("Float"), - - Literal("ushort").Named("UShort"), - Literal("short").Named("Short"), - Literal("half").Named("Half"), - - Literal("byte").Named("Byte"), - Literal("sbyte").Named("SByte"), - Terminals.Letter.Or("_").Then(Terminals.LetterOrDigit.Or("_").Repeat(0)) - ).WithName("TypeParser"); - } -} diff --git a/src/SDSL/Parsers/Grammars/SDFXGrammar/SDFXGrammar.cs b/src/SDSL/Parsers/Grammars/SDFXGrammar/SDFXGrammar.cs deleted file mode 100644 index 9cf5d18862..0000000000 --- a/src/SDSL/Parsers/Grammars/SDFXGrammar/SDFXGrammar.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Eto.Parse; - -namespace SDSL.Parsing.Grammars.SDFX; - - -public class SDFXGrammar() : Grammar("sdfx") -{ - -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs deleted file mode 100644 index 8b9f58c74a..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Declaration.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SequenceParser ShaderCompositionDeclaration = new() { Name = "ShaderCompositionDeclaration" }; - public SequenceParser ShaderValueDeclaration = new() { Name = "ShaderValueDeclaration" }; - public SequenceParser ConstantBufferValueDeclaration = new(){Name = "ConstantBufferValueDeclaration"}; - public SequenceParser StructDefinition = new(){Name = "StructDefinition"}; - - public SDSLGrammar UsingDeclarators() - { - var ws = WhiteSpace.Repeat(0); - Inner = ShaderValueDeclaration & Semi; - // Inner = Identifier.Then(LeftBracket).Then(PrimaryExpression).Then(RightBracket).Then(";"); - return this; - } - public void CreateDeclarators() - { - var ws = WhiteSpace.Repeat(0); - var ws1 = WhiteSpace.Repeat(1); - - - ShaderCompositionDeclaration.Add( - Compose, - Identifier, - Identifier, - Literal("[]").Optional().WithName("Array"), - Semi - ); - ShaderCompositionDeclaration.SeparatedBy(ws); - - - var declare = new SequenceParser(); - declare.Add( - ValueTypes, - ws1, - Identifier.Named("Name"), - ws, - Semi - ); - - var packoffset = new SequenceParser(); - packoffset.Add( - Packoffset, - LeftParen, - Identifier, - (Dot & Identifier).Repeat(0), - RightParen - ); - packoffset.Separator = ws; - - var register = new SequenceParser(); - register.Add( - Register, - LeftParen, - Identifier.Repeat(0).SeparatedBy(ws & Comma & ws), - RightParen - ); - register.Separator = ws; - - var supplement = new SequenceParser(); - supplement.Add( - Colon, - ws, - packoffset.Named("PackOffset") - | register - | Identifier.Named("Semantic") - ); - - var staging = - Stage.NotFollowedBy(ws1 & CommonParsers.Stream).Named("Stage") - | Stage.Named("Stage") & ws1 & CommonParsers.Stream.Named("Stream") - | CommonParsers.Stream.Named("Stream"); - - var valueDeclaration = new SequenceParser(); - valueDeclaration.Add( - ~(staging & ws1), - ~(StorageFlag & ws1), - ValueTypes, - ws1, - Identifier - ); - - var assignOrSupplement = new AlternativeParser( - supplement, - (AssignOperators & PrimaryExpression).SeparatedBy(ws).NotFollowedBy(ws & supplement), - (AssignOperators & PrimaryExpression & supplement).SeparatedBy(ws) - ); - - ShaderValueDeclaration.Add( - valueDeclaration, - ~assignOrSupplement, - Semi - ); - ShaderValueDeclaration.Separator = ws; - - ConstantBufferValueDeclaration.Add( - valueDeclaration, - assignOrSupplement.Optional(), - Semi - ); - - ConstantBufferValueDeclaration.Separator = ws; - - StructDefinition.Add( - Struct & ws1 & Identifier.Named("StructName"), - LeftBrace, - declare.Named("Declaration").Repeat(0).SeparatedBy(ws).Named("Fields"), - RightBrace, - Semi - ); - StructDefinition.Separator = ws; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs deleted file mode 100644 index 459255da81..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.Expression.cs +++ /dev/null @@ -1,207 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public AlternativeParser DirectiveTermExpression = new() { Name = "DirectiveTermExpression" }; - public AlternativeParser DirectivePostFixExpression = new() { Name = "DirectivePostFixExpression" }; - public AlternativeParser DirectiveUnaryExpression = new() { Name = "DirectiveUnaryExpression" }; - public AlternativeParser DirectiveCastExpression = new() { Name = "DirectiveCastExpression" }; - public AlternativeParser DirectiveMulExpression = new() { Name = "DirectiveMulExpression" }; - public AlternativeParser DirectiveSumExpression = new() { Name = "DirectiveSumExpression" }; - public AlternativeParser DirectiveShiftExpression = new() { Name = "DirectiveShiftExpression" }; - - public AlternativeParser DirectiveConditionalExpression = new() { Name = "DirectiveConditionalExpression" }; - public AlternativeParser DirectiveLogicalOrExpression = new() { Name = "DirectiveLogicalOrExpression" }; - public AlternativeParser DirectiveLogicalAndExpression = new() { Name = "DirectiveLogicalAndExpression" }; - public AlternativeParser DirectiveOrExpression = new() { Name = "DirectiveOrExpression" }; - public AlternativeParser DirectiveXorExpression = new() { Name = "DirectiveXorExpression" }; - public AlternativeParser DirectiveAndExpression = new() { Name = "DirectiveAndExpression" }; - public AlternativeParser DirectiveTestExpression = new() { Name = "DirectiveTestExpression" }; - - public AlternativeParser DirectiveIncrementExpression = new() { Name = "DirectiveIncrementExpression" }; - public AlternativeParser DirectiveParenExpression = new() { Name = "DirectiveParenExpression" }; - public AlternativeParser DirectiveEqualsExpression = new() { Name = "DirectiveEqualsExpression" }; - public SequenceParser DirectivesMethodCall = new() { Name = "DirectivesMethodCall" }; - public AlternativeParser DirectiveExpression = new() { Name = "DirectiveExpression" }; - public SDSLGrammar DirectiveUsingDirectiveExpression() - { - Inner = DirectiveExpression; - return this; - } - public void CreateDirectiveExpressions() - { - - var incrementOp = new AlternativeParser(); - incrementOp.Add( - PlusPlus, - MinusMinus - ); - - // TODO : write tests for method calls - // TODO : Optimize method call - - - DirectiveTermExpression.Add( - Literals, - ~(Plus | Minus & Spaces) & Identifier.Except(Keywords | SimpleTypes).NotFollowedBy(Spaces & LeftParen), - DirectivesMethodCall, - Parenthesis(DirectiveExpression) - ); - - var arrayAccess = new SequenceParser(); - var chain = new SequenceParser(); - var postfixInc = new SequenceParser(); - - - arrayAccess.Add( - Identifier, - Spaces, - (LeftBracket & DirectiveExpression & RightBracket) - .SeparatedBy(Spaces) - .Repeat(1) - .SeparatedBy(Spaces) - ); - chain.Add( - (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(Spaces & Dot & Spaces) - ); - postfixInc.Add( - chain.Named("AccessorChain") | arrayAccess.Named("ArrayAccessor") | Identifier, - Spaces, - incrementOp.Named("Operator") - ); - - DirectivePostFixExpression.Add( - DirectiveTermExpression.NotFollowedBy(Spaces & (Dot | LeftBracket | incrementOp)), - postfixInc.Named("PostfixIncrement"), - chain.Named("AccessorChain"), - arrayAccess.Named("ArrayAccesor") - ); - - var prefixInc = new SequenceParser(); - prefixInc.Add( - incrementOp, - Spaces, - Identifier.NotFollowedBy(Spaces & (Dot | "[")) - | chain - | arrayAccess - ); - - DirectiveUnaryExpression.Add( - DirectivePostFixExpression, - prefixInc.Named("PrefixIncrement"), - Literal("sizeof").Then(LeftParen).Then(Identifier | DirectiveUnaryExpression).Then(RightParen).Named("SizeOf") - ); - - var cast = new SequenceParser(); - cast.Add( - LeftParen, - SimpleTypes | Identifier, - RightParen, - DirectiveUnaryExpression - ); - - DirectiveCastExpression.Add( - DirectiveUnaryExpression, - cast.SeparatedBy(Spaces).Named("DirectiveCastExpression") - ); - - - var mulOp = Star | Div | Mod; - DirectiveMulExpression.Add( - (Parenthesis(DirectiveExpression) | DirectiveCastExpression).Repeat(0).SeparatedBy(Spaces & mulOp.Named("Operator") & Spaces) - ); - - var sumOp = Plus | Minus; - - DirectiveSumExpression.Add( - DirectiveMulExpression.Repeat(0).SeparatedBy(Spaces & sumOp.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & sumOp.Named("Operator") & Spaces) - ); - - - var shiftOp = LeftShift | RightShift; - - DirectiveShiftExpression.Add( - DirectiveSumExpression.Repeat(0).SeparatedBy(Spaces & shiftOp.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & shiftOp.Named("Operator") & Spaces) - ); - - - DirectiveAndExpression.Add( - DirectiveShiftExpression.Repeat(0).SeparatedBy(Spaces & And.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & And.Named("Operator") & Spaces) - ); - - DirectiveXorExpression.Add( - DirectiveAndExpression.Repeat(0).SeparatedBy(Spaces & Literal("^").Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & Literal("^").Named("Operator") & Spaces) - ); - - - DirectiveOrExpression.Add( - DirectiveXorExpression.Repeat(0).SeparatedBy(Spaces & Or.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & Or.Named("Operator") & Spaces) - ); - - var testOp = LessEqual | Less | GreaterEqual | Greater; - - DirectiveTestExpression.Add( - DirectiveOrExpression.Repeat(0).SeparatedBy(Spaces & testOp.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & testOp.Named("Operator") & Spaces) - ); - - var eqOp = - Literal("==") - | Literal("!="); - - DirectiveEqualsExpression.Add( - DirectiveTestExpression.Repeat(0).SeparatedBy(Spaces & eqOp.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & eqOp.Named("Operator") & Spaces) - ); - - DirectiveLogicalAndExpression.Add( - DirectiveEqualsExpression.Repeat(0).SeparatedBy(Spaces & AndAnd.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & AndAnd.Named("Operator") & Spaces) - ); - DirectiveLogicalOrExpression.Add( - DirectiveLogicalAndExpression.Repeat(0).SeparatedBy(Spaces & OrOr.Named("Operator") & Spaces), - Parenthesis(DirectiveExpression).Repeat(0).SeparatedBy(Spaces & OrOr.Named("Operator") & Spaces) - ); - - DirectiveConditionalExpression.Add( - DirectiveLogicalOrExpression.NotFollowedBy(Spaces & "?"), - (Parenthesis(DirectiveLogicalOrExpression).NotFollowedBy(Spaces & OrOr) | DirectiveLogicalOrExpression) - .Then("?") - .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) - .Then(":") - .Then(DirectiveCastExpression | DirectiveParenExpression | DirectiveLogicalOrExpression) - .SeparatedBy(Spaces) - .Named("Ternary") - - ); - - DirectiveParenExpression.Add( - LeftParen.Then(DirectiveExpression).Then(RightParen).SeparatedBy(Spaces) - ); - - var parameters = - DirectiveExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces); - - DirectivesMethodCall.Add( - Identifier.Then(LeftParen).Then(parameters).Then(RightParen).SeparatedBy(Spaces).Named("DirectiveMethodCallExpression") - ); - - var arrayDeclaration = - (LeftBrace & DirectiveExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces) & RightBrace) - .SeparatedBy(Spaces); - - DirectiveExpression.Add( - arrayDeclaration, - DirectiveConditionalExpression - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs deleted file mode 100644 index e074cb54b5..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Directives.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SequenceParser IfDirective = new(); - public SequenceParser ESpaceseDirective = new(); - public SequenceParser ElifDirective = new(); - public SequenceParser DefineDirective = new(); - public SequenceParser EndIfDirective = new(); - - - public SequenceParser IfDefDirective = new(); - public SequenceParser IfNDefDirective = new(); - - public SequenceParser ConditionalDirectives = new(); - public SequenceParser DefineDirectives = new(); - - public SequenceParser Directives = new(); - - public SDSLGrammar UsingDirectives() - { - Inner = Directives; - return this; - } - public void CreateDirectives() - { - - var hash = Literal("#"); - var hashIfNDef = Literal("#ifndef").Named("hashifndef"); - var hashIfDef = Literal("#ifdef").Named("hashifdef"); - var hashIf = Literal("#if").Named("hashif"); - var hashEndIf = Literal("#endif").Named("HashEndIf"); - var hashESpacese = Literal("#eSpacese").Named("HashESpacese"); - var hashElif = Literal("#elif").Named("HashElif"); - var hashDefine = Literal("#define").Named("HashElif"); - - IfDirective.Add(hashIf, Spaces1, DirectiveExpression); - ESpaceseDirective.Add(hashESpacese, Spaces, Eol); - EndIfDirective.Add(hashEndIf, Spaces, Eol); - IfDefDirective.Add(hashIfDef, Spaces1, Identifier, Spaces, Eol); - IfNDefDirective.Add(hashIfNDef, Spaces1, Identifier, Spaces, Eol); - DefineDirective.Add(hashDefine, Spaces1, Identifier, Spaces1, DirectiveExpression, Spaces, Eol); - - var anyChars = AnyChar.Repeat(0); - - var eSpaceseList = new AlternativeParser( - (ElifDirective & anyChars.Until(hashElif | hashESpacese | hashEndIf).Named("ElifCode")).Repeat(), - ESpaceseDirective & anyChars.Until(hashEndIf).Named("ESpaceseCode") - ); - - ConditionalDirectives.Add( - IfDirective, - anyChars.Until(hashElif | hashESpacese | hashEndIf).Named("IfCode"), - ~eSpaceseList, - EndIfDirective - ); - DefineDirective.Add( - IfDefDirective | IfNDefDirective, - ConditionalDirectives | DefineDirective | anyChars.Repeat(0).Until(hashESpacese | hashEndIf), - ~(ESpaceseDirective & anyChars.Repeat().Until(EndIfDirective)), - EndIfDirective - ); - Directives.Add( - anyChars.Until(hashIf | hashIfDef | hashIfNDef).Named("UnchangedCode"), - ( - DefineDirective - | ConditionalDirectives - | anyChars.Until(hashIf | hashIfDef | hashIfNDef | End).Named("UnchangedCode") - ) - .Repeat(0) - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs deleted file mode 100644 index f9503351f6..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Expression.cs +++ /dev/null @@ -1,237 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public AlternativeParser TermExpression = new(){Name = "TermExpression"}; - public AlternativeParser PostfixExpression = new(){Name = "PostfixExpression"}; - public AlternativeParser UnaryExpression = new(){Name = "UnaryExpression"}; - public AlternativeParser CastExpression = new(){Name = "CastExpression"}; - public AlternativeParser MulExpression = new(){Name = "MulExpression"}; - public AlternativeParser SumExpression = new(){Name = "SumExpression"}; - public AlternativeParser ShiftExpression = new(){Name = "ShiftExpression"}; - - public AlternativeParser ConditionalExpression = new() { Name = "ConditionalExpression" }; - public AlternativeParser LogicalOrExpression = new(){Name = "LogicalOrExpression"}; - public AlternativeParser LogicalAndExpression = new(){Name = "LogicalAndExpression"}; - public AlternativeParser OrExpression = new(){Name = "OrExpression"}; - public AlternativeParser XorExpression = new(){Name = "XorExpression"}; - public AlternativeParser AndExpression = new(){Name = "AndExpression"}; - public AlternativeParser TestExpression = new(){Name = "TestExpression"}; - - public AlternativeParser IncrementExpression = new() { Name = "IncrementExpression" }; - public AlternativeParser ParenExpression = new(){Name = "ParenExpression"}; - public AlternativeParser EqualsExpression = new(){Name = "EqualsExpression"}; - public SequenceParser ValueTypesMethods = new(){Name = "ValueTypesMethods"}; - public SequenceParser MethodCall = new(){Name = "MethodCall"}; - public AlternativeParser PrimaryExpression = new(){Name = "PrimaryExpression"}; - - public SDSLGrammar UsingPrimaryExpression() - { - Inner = SumExpression.Then(";"); - return this; - } - - public Parser Parenthesis(Parser p, bool notFollowedByUnary = true) - { - if (notFollowedByUnary) - return LeftParen.Then(p).Then(RightParen).SeparatedBy(Spaces).NotFollowedBy(UnaryExpression); - else - return LeftParen.Then(p).Then(RightParen).SeparatedBy(Spaces); - } - public Parser Parenthesis(Parser p, Parser f, bool notFollowedByUnary = true) - { - if (notFollowedByUnary) - return LeftParen.Then(p).Then(RightParen).SeparatedBy(Spaces).NotFollowedBy(UnaryExpression).FollowedBy(Spaces & f); - else - return LeftParen.Then(p).Then(RightParen).SeparatedBy(Spaces).FollowedBy(Spaces & f); - } - - public void CreateExpressions() - { - - - var incrementOp = new AlternativeParser(); - incrementOp.Add( - PlusPlus, - MinusMinus - ); - - ValueTypesMethods.Add( - ValueTypes, - LeftParen, - PrimaryExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces).Until(RightParen), - RightParen - ); - ValueTypesMethods.Separator = Spaces; - - TermExpression.Add( - Literals, - Identifier.Named("VariableTerm").Except(Keywords | SimpleTypes).NotFollowedBy(Spaces & LeftParen).Named("VariableTerm"), - ValueTypesMethods.Named("ValueTypesMethod"), - MethodCall, - Parenthesis(PrimaryExpression) - ); - - var arrayAccess = new SequenceParser() { Name = "ArrayAccessor"}; - var chain = new SequenceParser() { Name = "ChainAccessor"}; - var postfixInc = new SequenceParser() { Name = "PostfixIncrement"}; - - - arrayAccess.Add( - Identifier, - Spaces, - (LeftBracket & PrimaryExpression & RightBracket) - .SeparatedBy(Spaces) - .Repeat(1) - .SeparatedBy(Spaces) - ); - chain.Add( - (arrayAccess | MethodCall | Identifier).Repeat(1).SeparatedBy(Spaces & Dot & Spaces) - ); - postfixInc.Add( - chain | arrayAccess | Identifier, - Spaces, - incrementOp.Named("Operator") - ); - - PostfixExpression.Add( - TermExpression.NotFollowedBy(Spaces & (Dot | LeftBracket | incrementOp)), - postfixInc, - chain, - arrayAccess - ); - - var prefixInc = new SequenceParser( - incrementOp.Named("Operator"), - Spaces, - Identifier.NotFollowedBy(Spaces & (Dot | "[")) - | chain - | arrayAccess - ) - { Name = "PrefixIncrement"}; - - UnaryExpression.Add( - PostfixExpression, - (Plus | Minus) & Spaces & PostfixExpression, - prefixInc, - Literal("sizeof").Then(LeftParen).Then(Identifier | UnaryExpression).Then(RightParen).Named("SizeOf") - ); - - var cast = new SequenceParser( - LeftParen, - SimpleTypes | Identifier.Named("TypeName"), - RightParen, - UnaryExpression - ) - { Name = "CastExpression", Separator = Spaces}; - - CastExpression.Add( - UnaryExpression, - cast - ); - - - var mulOp = Star | Div | Mod; - MulExpression.Add( - (Parenthesis(PrimaryExpression) | CastExpression).Repeat(0).SeparatedBy(Spaces & mulOp.Named("Operator") & Spaces) - ); - - var sumOp = Plus | Minus; - - SumExpression.Add( - MulExpression.Repeat(0).SeparatedBy(Spaces & sumOp.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & sumOp.Named("Operator") & Spaces) - ); - - - var shiftOp = LeftShift | RightShift; - - ShiftExpression.Add( - SumExpression.Repeat(0).SeparatedBy(Spaces & shiftOp.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & shiftOp.Named("Operator") & Spaces) - ); - - - AndExpression.Add( - ShiftExpression.Repeat(0).SeparatedBy(Spaces & And.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & And.Named("Operator") & Spaces) - ); - - XorExpression.Add( - AndExpression.Repeat(0).SeparatedBy(Spaces & Literal("^").Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & Literal("^").Named("Operator") & Spaces) - ); - - - OrExpression.Add( - XorExpression.Repeat(0).SeparatedBy(Spaces & Or.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & Or.Named("Operator") & Spaces) - ); - - var testOp = LessEqual | Less | GreaterEqual | Greater ; - - TestExpression.Add( - OrExpression.Repeat(0).SeparatedBy(Spaces & testOp.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & testOp.Named("Operator") & Spaces) - ); - - var eqOp = - Literal("==") - | Literal("!="); - - EqualsExpression.Add( - TestExpression.Repeat(0).SeparatedBy(Spaces & eqOp.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & eqOp.Named("Operator") & Spaces) - ); - - LogicalAndExpression.Add( - EqualsExpression.Repeat(0).SeparatedBy(Spaces & AndAnd.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & AndAnd.Named("Operator") & Spaces) - ); - LogicalOrExpression.Add( - LogicalAndExpression.Repeat(0).SeparatedBy(Spaces & OrOr.Named("Operator") & Spaces), - Parenthesis(PrimaryExpression).Repeat(0).SeparatedBy(Spaces & OrOr.Named("Operator") & Spaces) - ); - - var ternary = new SequenceParser( - Parenthesis(LogicalOrExpression) | LogicalOrExpression, - Question, - Parenthesis(LogicalOrExpression) | LogicalOrExpression, - Colon, - Parenthesis(LogicalOrExpression) | LogicalOrExpression - ){ Separator = Spaces, Name = "Ternary"}; - - - ConditionalExpression.Add( - LogicalOrExpression.NotFollowedBy(Spaces & "?"), - ternary - ); - - ParenExpression.Add( - LeftParen.Then(PrimaryExpression).Then(RightParen).SeparatedBy(Spaces) - ); - - - MethodCall.Add( - Identifier, - LeftParen, - PrimaryExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces).Until(RightParen), - RightParen - ); - MethodCall.Separator = Spaces; - - var arrayDeclaration = - (LeftBrace & PrimaryExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces) & RightBrace) - .SeparatedBy(Spaces); - - PrimaryExpression.Add( - arrayDeclaration, - // MethodCall, - ConditionalExpression - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs deleted file mode 100644 index f9a5242b2c..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Literals.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Globalization; -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public StringParser StringLiteral = new(); - public AlternativeParser UserDefinedId = new(); - - public NumberParser IntegerLiteral = new(); - public NumberParser FloatLiteral = new(); - public HexDigitTerminal HexDigits = new(); - public SequenceParser HexaDecimalLiteral = new(); - - public BooleanTerminal BooleanTerm = new() { Name = "BooleanTerm"}; - - public AlternativeParser Literals = new(); - - public SDSLGrammar UsingLiterals() - { - Inner = Literals; - return this; - } - public void CreateLiterals() - { - - - StringLiteral = new StringParser().WithName("StringLiteral"); - IntegerLiteral = new NumberParser() { AllowSign = true, AllowDecimal = false, AllowExponent = false, ValueType = typeof(long), Name = "IntegerValue" }; - FloatLiteral = new NumberParser() { AllowSign = true, AllowDecimal = true, AllowExponent = true, ValueType = typeof(double), Culture = new CultureInfo("en-US") , Name = "FloatValue" }; - - HexDigits = new(); - HexaDecimalLiteral = Literal("0x").Or(Literal("0X")).Then(HexDigit.Repeat(1)).WithName("HexaLiteral"); - - BooleanTerm = new BooleanTerminal{CaseSensitive = true, TrueValues = ["true"],FalseValues = ["false"], Name = "Boolean"}; - - Literals.Add( - IntegerLiteral.NotFollowedBy(Dot | IntegerSuffix | FloatSuffix | Set("xX")).Named("IntegerLiteral"), - IntegerLiteral.NotFollowedBy(Dot | FloatSuffix | Set("xX")).Then(IntegerSuffix).Named("IntegerLiteral"), - FloatLiteral.NotFollowedBy(Set("xX")).Then(FloatSuffix).Named("FloatLiteral"), - FloatLiteral.NotFollowedBy(Set("xX")).Named("FloatLiteral"), - HexaDecimalLiteral, - StringLiteral, - BooleanTerm - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs deleted file mode 100644 index 13a3aa6d6c..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.MethodDeclaration.cs +++ /dev/null @@ -1,103 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SequenceParser ParameterList = new() {Name = "ParameterList"}; - public SequenceParser ValueOrGeneric = new() {Name = "ValueOrGeneric"}; - - public AlternativeParser MethodDeclaration = new() { Name = "MethodDeclaration" }; - - - public SDSLGrammar UsingMethodDeclare() - { - Inner = MethodDeclaration; - return this; - } - public void CreateMethodDeclaration() - { - - - var genericsList = new SequenceParser { Name = "ShaderGenerics", Separator = Spaces }; - - var parameterGenericsValues = new AlternativeParser( - SimpleTypes, - Identifier.Then(genericsList.Optional()).SeparatedBy(Spaces) - ) - { Name = "ParameterGenericValue" }; - - genericsList.Add( - "<", - parameterGenericsValues.Repeat(1).SeparatedBy(Spaces & Comma & Spaces), - ">" - ); - - ValueOrGeneric.Add( - SimpleTypes | Identifier, - genericsList.Optional() - ); - - var declarePost = - LeftBracket.Then(PrimaryExpression).Then(RightBracket).SeparatedBy(Spaces) - | Colon.Then(Identifier).SeparatedBy(Spaces); - - var arraySpecifier = - (LeftBracket & PrimaryExpression & RightBracket) - .SeparatedBy(Spaces); - - var parameter = new SequenceParser( - ValueOrGeneric, - Spaces1, - (Identifier & Spaces & arraySpecifier) | Identifier, - (Equal & Spaces & PrimaryExpression).Optional() - ); - var parameterWithStorage = new AlternativeParser( - StorageFlag & Spaces1 & parameter, - parameter - ) - { Name = "MethodParameter" }; - - - ParameterList.Add( - LeftParen, - parameterWithStorage.Repeat(0).SeparatedBy(Spaces & Comma & Spaces), - RightParen - ); - ParameterList.Separator = Spaces; - - var abstractMethod = new SequenceParser( - Literal("abstract"), - Spaces1, - ~Literal("stage"), - Spaces1, - Identifier, - Spaces1, - Identifier, - Spaces, - ParameterList, - Spaces, - Semi - ) - { Name = "AbstractMethod"}; - - var method = new SequenceParser( - Attribute.Repeat(0).SeparatedBy(Spaces), - ~(Stage.Named("Stage") & WhiteSpace), - ~((Literal("override").Named("Override") | Literal("static").Named("Static")) & Spaces1), - ValueTypes.Named("ReturnType") & Spaces1 & Identifier.Named("MethodName"), - ParameterList, - LeftBrace, - Statement.Repeat(0).SeparatedBy(Spaces).Until("}").Named("Statements"), - RightBrace - ) - { Name = "Method", Separator = Spaces}; - - MethodDeclaration.Add( - abstractMethod, - method - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs deleted file mode 100644 index f06084cadf..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Shader.cs +++ /dev/null @@ -1,144 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - - - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public AlternativeParser Declarations = new(); - public SequenceParser ShaderExpression = new(); - public SequenceParser ResourceGroup = new() { Name = "ResourceGroup" }; - public SequenceParser ConstantBuffer = new() { Name = "ConstantBuffer" }; - public SequenceParser NamespaceExpression = new() {Name = "Namespace"}; - public AlternativeParser ShaderFile = new(){Name = "ShaderFile"}; - - public SDSLGrammar UsingShader() - { - Inner = ShaderExpression; - return this; - } - public virtual void CreateShader() - { - - - var typeDefinition = new SequenceParser( - Literal("typedef") & " ", - Identifier & " ", - ~("<" & (Identifier | PrimaryExpression).Repeat(1).SeparatedBy(Spaces & "," & Spaces).Until(">") & ">").Named("TypedefGenerics"), - Identifier, - Semi - ) - { Name = "TypeDef", Separator = Spaces}; - - - ConstantBuffer.Add( - "cbuffer" & Spaces1 & Identifier.Repeat(1).SeparatedBy(Spaces & Dot & Spaces).Named("GroupName"), - LeftBrace, - ShaderValueDeclaration.Repeat(0).SeparatedBy(Spaces).Named("Variables"), - RightBrace - ); - ConstantBuffer.Separator = Spaces; - ResourceGroup.Add( - "rgroup" & Spaces1 & Identifier.Repeat(1).SeparatedBy(Spaces & Dot & Spaces).Named("GroupName"), - LeftBrace, - ShaderValueDeclaration.Repeat(0).SeparatedBy(Spaces).Named("Variables"), - RightBrace - ); - ResourceGroup.Separator = Spaces; - - - var shaderGenericValue = new AlternativeParser( - Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(Spaces1).Named("GenericType"), - Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(Spaces1).Named("Semantic"), - SimpleTypes.Then(Identifier).SeparatedBy(Spaces1).Named("GenericValue"), - SimpleTypes - ){ Name = "ShaderGeneric" }; - - var shaderGenerics = new SequenceParser( - "<", - shaderGenericValue.Repeat(1).SeparatedBy(Spaces & Comma & Spaces), - ">" - ){ Name = "ShaderGenerics", Separator = Spaces }; - - var inheritGenericsValues = new AlternativeParser( - SimpleTypes, - Identifier, - Literals - ); - - var inheritGenerics = new SequenceParser( - "<", - inheritGenericsValues.Repeat(1).SeparatedBy(Spaces & Comma & Spaces), - ">" - ){ Separator = Spaces, Name = "Generics"}; - - var compositionDeclaration = new SequenceParser( - Literal("compose"), - Spaces1, - Identifier.Named("MixinName"), - Spaces1, - Identifier.Named("Name"), - Spaces, - Semi - ){ Name = "CompositionDeclaration"}; - - - var shaderContentTypes = new AlternativeParser( - typeDefinition, - StructDefinition, - ConstantBuffer, - ResourceGroup, - compositionDeclaration, - MethodDeclaration, - ShaderCompositionDeclaration, - ShaderValueDeclaration - - ); - - var shaderBody = new SequenceParser( - LeftBrace, - Spaces, - shaderContentTypes.Repeat(0).SeparatedBy(Spaces).Until(Spaces & "}"), - RightBrace - ) - {Name = "Body", Separator = Spaces}; - - var inheritances = - Colon - .Then( - Identifier.Named("Name").Then(inheritGenerics.Optional()).SeparatedBy(Spaces).Named("Mixin") - .Repeat(1).SeparatedBy(Spaces & Comma & Spaces) - ) - .SeparatedBy(Spaces) - .Named("Mixins"); - - - - ShaderExpression.Add( - Literal("shader") & Spaces1 & Identifier.Named("ShaderName"), - shaderGenerics.Optional(), - inheritances.Optional(), - shaderBody - ); - ShaderExpression.Separator = Spaces; - ShaderExpression.Name = "ShaderProgram"; - - NamespaceExpression.Add( - Spaces, - Literal("namespace") & Spaces1 & Identifier.Repeat(1).SeparatedBy(Spaces & Dot & Spaces).Named("Namespace"), - LeftBrace, - ShaderExpression.Repeat(0), - RightBrace, - Spaces - ); - NamespaceExpression.Separator = Spaces; - - ShaderFile.Add( - ShaderExpression.Repeat(1), - NamespaceExpression.Repeat(1) - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs deleted file mode 100644 index ee47e6b20f..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.ConditionalFlowStatements.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SequenceParser ControlFlow = new() { Name = "ControlFlow" }; - public void CreateConditionalFlowStatements() - { - - - var ifStatement = new SequenceParser( - If, - LeftParen, - PrimaryExpression.Named("Condition"), - RightParen, - Statement - ){Name = "IfStatement", Separator = Spaces}; - - var elseIfStatement = - Else.Then(ifStatement).SeparatedBy(Spaces1).Named("ElseIfStatement"); - - var elseStatement = - Else.Then(Statement).SeparatedBy(Spaces1).Named("ElseStatement"); - - var conditionalFlow = new AlternativeParser( - ifStatement & Spaces & elseIfStatement.Repeat(0).SeparatedBy(Spaces) & elseStatement, - ifStatement & Spaces & elseIfStatement.Repeat(0).SeparatedBy(Spaces), - ifStatement & Spaces & elseStatement, - ifStatement - ){Name = "ConditionalFlow"}; - - ControlFlow.Add( - Attribute.Repeat(0).Named("Attributes"), - Spaces, - conditionalFlow - | ForLoop - ); - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs deleted file mode 100644 index 64a89d9850..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.LoopFlowStatements.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; - -public partial class SDSLGrammar : Grammar -{ - public SequenceParser WhileLoop = new() { Name = "WhileLoop"}; - public SequenceParser ForEachLoop = new() { Name = "ForEachLoop"}; - public SequenceParser ForLoop = new() { Name = "ForLoop"}; - - public void CreateLoopFlowStatements() - { - var valueDeclare = new SequenceParser( - ((SimpleTypes | Identifier) & Identifier).SeparatedBy(Spaces1).Named("NewVariable") - | UnaryExpression.Named("ExistingVariable"), - AssignOperators.Named("Operator"), - PrimaryExpression - ) - { Separator = Spaces, Name = "Initializer"}; - var valueAssign = new SequenceParser( - Identifier, - AssignOperators.Named("Operator"), - PrimaryExpression - ) - { Separator = Spaces }; - - ForLoop.Add( - For, - LeftParen, - valueDeclare, - Semi, - PrimaryExpression, - Semi, - valueAssign | PrimaryExpression, - RightParen, - Semi - | Statement - - ); - ForLoop.Separator = Spaces; - - WhileLoop.Add( - While, - LeftParen, - PrimaryExpression.Named("Condition"), - RightParen, - Statement - ); - WhileLoop.Separator = Spaces; - - ForEachLoop.Add( - Literal("foreach"), - LeftParen, - ((SimpleTypes | Literal("var") | Identifier) & Identifier & In & PrimaryExpression).SeparatedBy(Spaces).Named("Declarator"), - RightParen, - Statement - ); - ForEachLoop.Separator = Spaces; - - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs deleted file mode 100644 index f3303c3592..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Statements.cs +++ /dev/null @@ -1,96 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SequenceParser Attribute = new() { Name = "Attribute" }; - public AlternativeParser Statement = new() { Name = "Statement"}; - public SequenceParser Block = new() { Name = "Block" }; - - - public SDSLGrammar UsingStatements() - { - Inner = Statement; - return this; - } - public void CreateStatements() - { - - var returnStatement = new SequenceParser( - Return, - (Spaces1 & PrimaryExpression & Spaces & Semi) - |(Spaces & Semi) - ); - - var attrParams = - ( - LeftParen & - PrimaryExpression.Repeat(0).SeparatedBy(Spaces & Comma & Spaces) & - RightParen - ).SeparatedBy(Spaces); - - Attribute.Add( - LeftBracket, - Identifier, - ~attrParams, - RightBracket - ); - Attribute.Separator = Spaces; - - var arraySpecifier = - (LeftBracket & PrimaryExpression.Named("Count") & RightBracket).SeparatedBy(Spaces); - - arraySpecifier.Name = "ArraySpecifier"; - - - var assignVar = - Identifier.Named("Variable") - .Then(arraySpecifier.Optional()) - .Then(AssignOperators.Named("AssignOp")) - .Then(PrimaryExpression.Named("Value")) - .Then(Semi) - .SeparatedBy(Spaces); - - var assignChain = - Identifier.Then(Dot.Then(Identifier).Repeat(0)) - .Then(AssignOperators.Named("AssignOp")) - .Then(PrimaryExpression) - .Then(Semi) - .SeparatedBy(Spaces); - - - var declareAssign = - ValueTypes - .Then(assignVar) - .SeparatedBy(Spaces1); - - var simpleDeclare = - ((SimpleTypes | Identifier) & Identifier.Named("Variable") & arraySpecifier).SeparatedBy(Spaces) - | ((SimpleTypes | Identifier) & Identifier.Named("Variable")).SeparatedBy(Spaces); - - Statement.Add( - Block, - ControlFlow, - ForLoop, - returnStatement.Named("Return"), - assignChain.Named("AssignChain"), - declareAssign.Named("DeclareAssign"), - simpleDeclare.Named("SimpleDeclare"), - assignVar.Named("Assign"), - PrimaryExpression.Then(Semi).SeparatedBy(Spaces).Named("EmptyStatement") - ); - - Block.Add( - LeftBrace, - Statement.Repeat(0).SeparatedBy(Spaces), - RightBrace - ); - Block.Separator = Spaces; - - - - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs deleted file mode 100644 index e504f2a409..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.TokenGroups.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; - -public partial class SDSLGrammar : Grammar -{ - public AlternativeParser IncOperators = new(); - - public AlternativeParser Operators = new(); - public AlternativeParser AssignOperators = new(); - - public AlternativeParser BoolTypes = new(); - - public AlternativeParser HalfTypes = new(); - - public AlternativeParser FloatTypes = new(); - - public AlternativeParser DoubleTypes = new(); - - public AlternativeParser IntTypes = new(); - - public AlternativeParser UintTypes = new(); - - public AlternativeParser SimpleTypes = new() { Name = "ValueTypes"}; - public SequenceParser ArrayTypes = new() { Name = "ArrayTypes"}; - public AlternativeParser ValueTypes = new() { Name = "ValueTypes"}; - public AlternativeParser StorageFlag = new(); - - public AlternativeParser Keywords = new(); - - public void CreateTokenGroups() - { - IncOperators.Add( - PlusPlus, - MinusMinus - ); - - Operators.Add( - PlusPlus, - Plus, - MinusMinus, - Minus, - Star, - Div, - Mod, - LeftShift, - RightShift, - AndAnd, - And, - OrOr, - Or, - Caret, - Equal, - "==", - NotEqual, - Question - - ); - - AssignOperators.Add( - Assign, - StarAssign, - DivAssign, - ModAssign, - PlusAssign, - MinusAssign, - LeftShiftAssign, - RightShiftAssign, - AndAssign, - XorAssign, - OrAssign - ); - - - SimpleTypes.Add( - BuiltinNumericTypes, - Identifier.Named("UserDefined") - ); - - ArrayTypes.Add( - SimpleTypes, - LeftBracket, - RightBracket - ); - ArrayTypes.Separator = WhiteSpace.Repeat(0); - - ValueTypes.Add( - ArrayTypes, - SimpleTypes - ); - - - Keywords.Add( - AppendStructuredBuffer, - CommonParsers.Buffer, - ByteAddressBuffer, - Break, - Case, - CBuffer, - Centroid, - Class, - ColumnMajor, - Const, - ConsumeStructuredBuffer, - Continue, - Default, - Discard, - Do, - Else, - Extern, - For, - Groupshared, - If, - In, - Inout, - InputPatch, - Interface, - LineAdj, - Linear, - LineStream, - Matrix, - Nointerpolation, - Noperspective, - Out, - OutputPatch, - Packoffset, - Point, - PointStream, - Precise, - Register, - Return, - RowMajor, - RWBuffer, - RWByteAddressBuffer, - RWStructuredBuffer, - Sample, - Sampler, - SamplerComparisonState, - SamplerState, - Shared, - Stage, - CommonParsers.Stream, - StaticConst, - Static, - Struct, - StructuredBuffer, - Switch, - TextureBase, - Triangle, - TriangleAdj, - TriangleStream, - Uniform, - SimpleTypes, - Vector, - CommonParsers.Volatile, - CommonParsers.Void, - While - ); - - StorageFlag.Add( - Literal("constant"), - RowMajor, - ColumnMajor, - Extern, - Precise, - Shared, - Groupshared, - StaticConst, - Static, - Uniform, - CommonParsers.Volatile, - Linear, - Centroid, - Nointerpolation, - Noperspective, - Sample, - Inout, - In.NotFollowedBy(WhiteSpace.Repeat(0) & Out), - Out, - Point, - Triangle, - LineAdj, - TriangleAdj - ); - - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs deleted file mode 100644 index 1d908ebea2..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.Tokens.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace SDSL.Parsing.Grammars.SDSL; - -public partial class SDSLGrammar : Grammar -{ -} diff --git a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs b/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs deleted file mode 100644 index 0f2223e669..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLGrammar/SDSLGrammar.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; - -namespace SDSL.Parsing.Grammars.SDSL; -public partial class SDSLGrammar : Grammar -{ - public SDSLGrammar() : base("sdsl") - { - CreateAll(); - Inner = ShaderFile; - } - - public SDSLGrammar Using(Parser p) - { - Inner = p; - return this; - } - - public virtual void CreateAll() - { - CreateTokenGroups(); - CreateLiterals(); - CreateDirectives(); - CreateDirectiveExpressions(); - CreateExpressions(); - CreateMethodDeclaration(); - CreateDeclarators(); - CreateConditionalFlowStatements(); - CreateLoopFlowStatements(); - CreateStatements(); - CreateShader(); - } -} diff --git a/src/SDSL/Parsers/Grammars/SDSLMixinReader.cs b/src/SDSL/Parsers/Grammars/SDSLMixinReader.cs deleted file mode 100644 index 1d229da3c9..0000000000 --- a/src/SDSL/Parsers/Grammars/SDSLMixinReader.cs +++ /dev/null @@ -1,101 +0,0 @@ -using Eto.Parse; -using Eto.Parse.Parsers; -using static Eto.Parse.Terminals; -using static SDSL.Parsing.Grammars.CommonParsers; - -namespace SDSL.Parsing.Grammars.SDSL; -public class SDSLMixinReader : SDSLGrammar -{ - public override void CreateAll() - { - CreateTokenGroups(); - CreateLiterals(); - CreateExpressions(); - } - public override void CreateShader() - { - var ws = WhiteSpace.Repeat(0); - var ws1 = WhiteSpace.Repeat(1); - - - var shaderGenericValue = new AlternativeParser( - Literal("TypeName").Named("TypeName").Then(Identifier).SeparatedBy(ws1).Named("GenericType"), - Literal("Semantic").Named("Semantic").Then(Identifier).SeparatedBy(ws1).Named("Semantic"), - SimpleTypes.Then(Identifier).SeparatedBy(ws1).Named("GenericValue"), - SimpleTypes - ){ Name = "ShaderGeneric" }; - - var shaderGenerics = new SequenceParser( - "<", - shaderGenericValue.Repeat(1).SeparatedBy(ws & Comma & ws), - ">" - ){ Name = "ShaderGenerics", Separator = ws }; - - var inheritGenericsValues = new AlternativeParser( - SimpleTypes, - Identifier, - Literals - ); - - var inheritGenerics = new SequenceParser( - "<", - inheritGenericsValues.Repeat(1).SeparatedBy(ws & Comma & ws), - ">" - ){ Separator = ws, Name = "Generics"}; - - var compositionDeclaration = new SequenceParser( - Literal("compose"), - ws1, - Identifier.Named("MixinName"), - ws1, - Identifier.Named("Name"), - ws, - Semi - ){ Name = "CompositionDeclaration"}; - - - var shaderBody = new SequenceParser( - LeftBrace, - AnyChar.Repeat(0).Until("}"), - RightBrace - ) - {Name = "Body", Separator = ws}; - - var inheritances = - Colon - .Then( - Identifier.Named("Name").Then(inheritGenerics.Optional()).SeparatedBy(ws).Named("Mixin") - .Repeat(1).SeparatedBy(ws & Comma & ws) - ) - .SeparatedBy(ws) - .Named("Mixins"); - - - - ShaderExpression.Add( - Literal("shader") & ws1 & Identifier.Named("ShaderName"), - shaderGenerics.Optional(), - inheritances.Optional(), - shaderBody, - Semi - ); - ShaderExpression.Separator = ws; - ShaderExpression.Name = "ShaderProgram"; - - NamespaceExpression.Add( - ws, - Literal("namespace") & ws1 & Identifier.Repeat(1).SeparatedBy(ws & Dot & ws).Named("Namespace"), - LeftBrace, - ShaderExpression, - RightBrace, - ws - ); - NamespaceExpression.Separator = ws; - - ShaderFile.Add( - NamespaceExpression, - ws & ShaderExpression & ws - ); - this.Inner = ShaderFile; - } -} \ No newline at end of file diff --git a/src/SDSL/Parsers/ShaderMixinParser.cs b/src/SDSL/Parsers/ShaderMixinParser.cs deleted file mode 100644 index 14387e9f87..0000000000 --- a/src/SDSL/Parsers/ShaderMixinParser.cs +++ /dev/null @@ -1,149 +0,0 @@ -namespace SDSL.Parsing; - -using Eto.Parse; -using Eto.Parse.Grammars; -using SDSL.Parsing.AST.Directives; -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.Grammars; -using SDSL.Parsing.Grammars.Comments; -using SDSL.Parsing.Grammars.Directive; -using SDSL.Parsing.Grammars.SDSL; -using System.Text; -using CppNet; - - -public class ShaderMixinParser -{ - - public static ShaderMixinParser Instance { get; } = new(); - public static ShaderProgram ParseShader(string shader) => Instance.Parse(shader); - public static List GetMixins(string shader) => Instance.ParseMixins(shader); - - - - public SDSLGrammar Grammar { get; set; } - public DirectivePreprocessor DPreprocessor { get; set; } - public Preprocessor Preprocessor { get; set; } - - public SDSLMixinReader MixinParser { get; set; } - - public GrammarMatch? ParseTree { get; set; } - - private ShaderMixinParser() - { - Grammar = new(); - MixinParser = new(); - DPreprocessor = new(); - - - Preprocessor = new(); - Preprocessor.addFeature(Feature.DIGRAPHS); - Preprocessor.addWarning(Warning.IMPORT); - Preprocessor.addFeature(Feature.INCLUDENEXT); - //Preprocessor.addFeature(Feature.LINEMARKERS); - // Preprocessor.setListener(new ErrorListener()); - } - - public ShaderMixinParser With(Parser p) - { - Grammar.Inner = p; - return this; - } - - public void PrintParserTree() - { - PrettyPrintMatches(ParseTree.Matches[0]); - } - - public GrammarMatch TestParse(string code) - { - return Grammar.Match(code); - } - - public string DPreProcess(string code) - { - return DPreprocessor.PreProcess(code); - } - - public string PreProcess(string code) - { - var inputSource = new StringLexerSource(code, true); - Preprocessor.addInput(inputSource); - var textBuilder = new StringBuilder(); - - var isEndOfStream = false; - while (!isEndOfStream) - { - Token tok = Preprocessor.token(); - switch (tok.getType()) - { - case Token.EOF: - isEndOfStream = true; - break; - case Token.CCOMMENT: - var strComment = tok.getText() ?? string.Empty; - foreach (var commentChar in strComment) - { - textBuilder.Append(commentChar == '\n' ? '\n' : ' '); - } - break; - case Token.CPPCOMMENT: - break; - default: - var tokenText = tok.getText(); - if (tokenText != null) - { - textBuilder.Append(tokenText); - } - break; - } - } - - return textBuilder.ToString(); - } - - public ShaderProgram Parse(string shader) - { - var code = PreProcess(shader); - ParseTree = Grammar.Match(code); - if (!ParseTree.Success) - throw new Exception(ParseTree.ErrorMessage[..500]); - return (ShaderProgram)ShaderToken.Tokenize(ParseTree); - //return null; - } - List ParseMixins(string shader) - { - var match = MixinParser.Match(shader); - if (!match.Success) - throw new Exception(match.ErrorMessage); - return new(); - } - - private static void PrettyPrintMatches(Match match, int depth = 0) - { - Console.ForegroundColor = ConsoleColor.Blue; - Console.Write(new string(' ', depth * 4) + match.Name); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(" : " + match.StringValue); - //Console.WriteLine(" : " + System.Text.RegularExpressions.Regex.Escape(match.StringValue)[..Math.Min(32,match.StringValue.Length)]); - foreach (var m in match.Matches) - { - if (m.Matches.Count == 1 && m.Name.Contains("Expression")) - { - var tmp = m.Matches[0]; - while (tmp.Matches.Count == 1) - { - tmp = tmp.Matches[0]; - } - PrettyPrintMatches(tmp, depth + 1); - } - else - PrettyPrintMatches(m, depth + 1); - } - } - - private class ErrorListener : DefaultPreprocessorListener - { - - } -} \ No newline at end of file diff --git a/src/SDSL/SDSL.csproj b/src/SDSL/SDSL.csproj deleted file mode 100644 index 14ece1beb3..0000000000 --- a/src/SDSL/SDSL.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - net8.0 - enable - enable - true - - diff --git a/src/SDSL/ShaderSourceProvider.cs b/src/SDSL/ShaderSourceProvider.cs deleted file mode 100644 index d0254a3287..0000000000 --- a/src/SDSL/ShaderSourceProvider.cs +++ /dev/null @@ -1,31 +0,0 @@ -using SDSL.Parsing; -using SDSL.Parsing.AST.Shader; - -namespace SDSL; - - -public class ShaderSourceProvider -{ - public static ShaderSourceProvider Instance { get; } = new(); - - public Dictionary Sources; - public Dictionary Trees; - private ShaderSourceProvider() - { - Sources = new(); - Trees = new(); - } - - - public static void Register(string shaderCode) - { - var shaderProgram = ShaderMixinParser.ParseShader(shaderCode); - var name = shaderProgram.Name; - - Instance.Sources[name] =shaderCode; - Instance.Trees[name] = shaderProgram; - } - - public static ShaderProgram GetTree(string name) => Instance.Trees[name]; - public static string GetSource(string name) => Instance.Sources[name]; -} \ No newline at end of file diff --git a/src/SDSL/Symbols/MethodSymbol.cs b/src/SDSL/Symbols/MethodSymbol.cs deleted file mode 100644 index 7a3d3552fc..0000000000 --- a/src/SDSL/Symbols/MethodSymbol.cs +++ /dev/null @@ -1,12 +0,0 @@ -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.AST.Shader.Symbols; - -namespace SDSL.Symbols; - -public record struct MethodSymbol(SymbolTable Table, ModuleMethod Method) -{ - public readonly string Name => Method.Name; - public readonly SymbolType Type => Method.ReturnType; - public readonly List? Parameters => Method.ParameterList; - -} diff --git a/src/SDSL/Symbols/SymbolQuantifier.cs b/src/SDSL/Symbols/SymbolQuantifier.cs deleted file mode 100644 index c1dee5160d..0000000000 --- a/src/SDSL/Symbols/SymbolQuantifier.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace SDSL.Symbols; - -public enum SymbolQuantifier -{ - Void, - Scalar, - Vector, - Matrix, - Struct, - Array, -} - diff --git a/src/SDSL/Symbols/SymbolTable.Check.cs b/src/SDSL/Symbols/SymbolTable.Check.cs deleted file mode 100644 index 3763561f85..0000000000 --- a/src/SDSL/Symbols/SymbolTable.Check.cs +++ /dev/null @@ -1,61 +0,0 @@ -using Eto.Parse; -using SDSL.Analysis; -using SDSL.Symbols; - -namespace SDSL.Parsing.AST.Shader.Symbols; - - -public partial class SymbolTable -{ - public void CheckVar(Statement s) - { - if (s is IVariableCheck v) - { - v.CheckVariables(this); - } - s.TypeCheck(this, SymbolType.Void); - } - - public SymbolType TokenizeScalar(string name) - => Scalar(name); - public SymbolType Tokenize(Match m) - { - return (m.Name, m.HasMatches) switch - { - ("ReturnType", _) => Tokenize(m.Matches[0]), - ("ValueTypes", true) => Tokenize(m.Matches[0]), - ("ArrayTypes", true) => Tokenize(m.Matches[0]), - ("ValueTypes", false) => Scalar(m.StringValue), - ("ScalarType", false) => Scalar(m.StringValue), - ("bool", _) => Scalar(m.StringValue), - ("sbyte", _) => Scalar(m.StringValue), - ("byte", _) => Scalar(m.StringValue), - ("short", _) => Scalar(m.StringValue), - ("int", _) => Scalar(m.StringValue), - ("uint", _) => Scalar(m.StringValue), - ("half", _) => Scalar(m.StringValue), - ("float", _) => Scalar(m.StringValue), - ("double", _) => Scalar(m.StringValue), - ("BoolScalar", _) => Scalar(m.StringValue), - ("SbyteScalar", _) => Scalar(m.StringValue), - ("ByteScalar", _) => Scalar(m.StringValue), - ("ShortScalar", _) => Scalar(m.StringValue), - ("IntScalar", _) => Scalar(m.StringValue), - ("UintScalar", _) => Scalar(m.StringValue), - ("HalfScalar", _) => Scalar(m.StringValue), - ("FloatScalar", _) => Scalar(m.StringValue), - ("DoubleScalar", _) => Scalar(m.StringValue), - ("BoolVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("SbyteVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("ByteVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("ShortVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("IntVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("UintVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("HalfVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("FloatVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - ("DoubleVec", _) => Vector(Scalar(m["ScalarType"].StringValue),(int)m["Size1"].Value), - _ => throw new NotImplementedException() - }; - } - -} \ No newline at end of file diff --git a/src/SDSL/Symbols/SymbolTable.cs b/src/SDSL/Symbols/SymbolTable.cs deleted file mode 100644 index 7f91d88a47..0000000000 --- a/src/SDSL/Symbols/SymbolTable.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Runtime.CompilerServices; -using Eto.Parse; -using SDSL.Symbols; - -namespace SDSL.Parsing.AST.Shader.Symbols; - -public partial class SymbolTable -{ - public Dictionary Types { get; } = []; - public VariableScope Variables; - public Dictionary Methods; - public SymbolTable() - { - Variables = new(this); - Methods = []; - } - - public SymbolType ParseType(string type, Dictionary? fields = null) - { - return type switch - { - string s when s.IsScalar() => Scalar(s), - string s when s.IsVector() => Vector(s), - string s when s.IsMatrix() => Matrix(s), - string s when s.IsArray() => Array(s), - string s when s.IsStruct() && fields != null => Struct(s, fields.ToDictionary(x => x.Key, x => ParseType(x.Value))), - string s when s.IsStruct() && fields == null => Struct(s), - _ => throw new NotImplementedException($"Type {type} cannot be parsed") - }; - } - - public Scalar Scalar(string name) - { - if (Types.TryGetValue(name, out var t)) - return (Scalar)t; - var symb = SymbolType.Scalar(name); - Types[name] = symb; - return symb; - } - public VectorSymbol Vector(string name) - { - if (Types.TryGetValue(name, out var t)) - return (VectorSymbol)t; - var symb = SymbolType.Vector(Scalar(name[..^1]), name[^1] - '0'); - Types[name] = symb; - return symb; - } - public VectorSymbol Vector(string baseType, int size) - { - if (Types.TryGetValue(baseType + size, out var t)) - return (VectorSymbol)t; - var symb = SymbolType.Vector(Scalar(baseType),size); - Types[baseType + size] = symb; - return symb; - } - public VectorSymbol Vector(Scalar scalar, int size) - { - if (Types.TryGetValue(scalar.Name + size, out var t)) - return (VectorSymbol)t; - var symb = SymbolType.Vector(scalar, size); - Types[scalar.Name + size] = symb; - return symb; - } - public MatrixSymbol Matrix(string name) - { - if (Types.TryGetValue(name, out var t)) - return (MatrixSymbol)t; - var symb = SymbolType.Matrix(Vector(name[..^2]), name[^1] - '0'); - Types[name] = symb; - return symb; - } - public ArraySymbol Array(string name) - { - if (Types.TryGetValue(name, out var t)) - return (ArraySymbol)t; - var symb = SymbolType.Array(Scalar(name[..^2]), null); - Types[name] = symb; - return symb; - } - public StructSymbol Struct(string name, Dictionary? fields = null) - { - if (Types.TryGetValue(name, out var t)) - return (StructSymbol)t; - var symb = SymbolType.Struct(name, fields ?? []); - Types[name] = symb; - return symb; - } -} - -file static class StringTypeExtensions -{ - public static bool IsScalar(this string t) - { - return t switch - { - "byte" or "sbyte" - or "short" or "ushort" or "half" - or "int" or "uint" or "float" - or "long" or "ulong" or "double" => true, - _ => false - }; - } - public static bool IsVector(this string t) - { - return t switch - { - string v when v[..^1].IsScalar() && char.IsDigit(v[^1]) => true, - _ => false - }; - } - public static bool IsMatrix(this string t) - { - return t switch - { - string v when v[..^2].IsVector() && v[^2] == 'x' && char.IsDigit(v[^1]) => true, - _ => false - }; - } - public static bool IsArray(this string t) - { - return t switch - { - string v when v[..^2].Any(x => !(char.IsLetterOrDigit(x) || x == '_')) && v[^2..] == "[]" => true, - _ => false - }; - } - public static bool IsStruct(this string t) - { - return t switch - { - string v when !v.IsArray() && !v.IsMatrix() && !v.IsVector() && !v.IsScalar() => true, - _ => false - }; - } - -} diff --git a/src/SDSL/Symbols/SymbolType.cs b/src/SDSL/Symbols/SymbolType.cs deleted file mode 100644 index a4079ae7bc..0000000000 --- a/src/SDSL/Symbols/SymbolType.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System.Numerics; - -namespace SDSL.Symbols; - -public abstract record SymbolType(string Name) -{ - static Dictionary Cache = new(); - public static SymbolType Void { get; } = new Scalar("void"); - - public static StringSymbol String() - { - if (Cache.TryGetValue("string", out var t)) - return (StringSymbol)t; - else - { - Cache["string"] = new StringSymbol(); - return (StringSymbol)Cache["string"]; - } - } - public static Scalar Scalar(string name) - { - if (Cache.TryGetValue(name, out var t)) - return (Scalar)t; - else - { - Cache[name] = new Scalar(name); - return (Scalar)Cache[name]; - } - } - public static VectorSymbol Vector(Scalar baseType, int size) - { - var newName = baseType.Name + size; - if (Cache.TryGetValue(newName, out var t)) - return (VectorSymbol)t; - else - { - Cache[newName] = new VectorSymbol(newName, baseType, size); - return (VectorSymbol)Cache[newName]; - } - } - public static MatrixSymbol Matrix(VectorSymbol baseType, int columns) - { - var newName = baseType.Name + "x" + columns; - if (Cache.TryGetValue(newName, out var t)) - return (MatrixSymbol)t; - else - { - Cache[newName] = new MatrixSymbol(newName, baseType, columns); - return (MatrixSymbol)Cache[newName]; - } - } - public static ArraySymbol Array(SymbolType baseType, int? size) - { - var newName = baseType.Name + "[]"; - if (Cache.TryGetValue(newName, out var t)) - return (ArraySymbol)t; - else - { - Cache[newName] = new ArraySymbol(newName, baseType, size); - return (ArraySymbol)Cache[newName]; - } - } - public static StructSymbol Struct(string typeName, Dictionary fields) - { - if (Cache.TryGetValue(typeName, out var t)) - return (StructSymbol)t; - else - { - Cache[typeName] = new StructSymbol(typeName, fields); - return (StructSymbol)Cache[typeName]; - } - } -}; - -public record StringSymbol() : SymbolType("string"); -public record Scalar(string Name) : SymbolType(Name); -public record VectorSymbol(string Name, Scalar BaseType, int Size) : SymbolType(Name); -public record MatrixSymbol(string Name, VectorSymbol BaseType, int Columns) : SymbolType(Name); -public record ArraySymbol(string Name, SymbolType BaseType, int? Size) : SymbolType(Name); -public record StructSymbol(string Name, Dictionary Fields) : SymbolType(Name); \ No newline at end of file diff --git a/src/SDSL/Symbols/VariableScope.cs b/src/SDSL/Symbols/VariableScope.cs deleted file mode 100644 index e06c03b08e..0000000000 --- a/src/SDSL/Symbols/VariableScope.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using SDSL.Parsing.AST.Shader.Symbols; - -namespace SDSL.Symbols; - - - -public class VariableScope -{ - SymbolTable Table; - Stack> Scopes; - - public VariableScope(SymbolTable table) - { - Table = table; - Scopes = new(); - } - - public void Push(VariableSymbol variable) - { - if (!IsDeclared(variable.Name)) - Scopes.Peek().Add(variable.Name, variable); - else - throw new Exception($"Variable {variable.Name} already declared"); - } - public void Remove(VariableSymbol variable) => Scopes.Peek().Remove(variable.Name); - public void PushScope() => Scopes.Push(new()); - public void PopScope() => Scopes.Pop(); - - public bool IsDeclared(string name) - { - foreach (var scope in Scopes) - if (scope.ContainsKey(name)) return true; - return false; - } - - public VariableSymbol? GetVariable(string name) - { - foreach (var scope in Scopes) - { - if (scope.TryGetValue(name, out var variable)) - return variable; - } - return null; - } - - public bool TryGetVariable(string name, out VariableSymbol variable) - { - variable = VariableSymbol.None; - foreach (var scope in Scopes) - { - if (scope.TryGetValue(name, out variable)) - return true; - } - return false; - } - - -} \ No newline at end of file diff --git a/src/SDSL/Symbols/VariableSymbol.cs b/src/SDSL/Symbols/VariableSymbol.cs deleted file mode 100644 index 157079e183..0000000000 --- a/src/SDSL/Symbols/VariableSymbol.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SDSL.Symbols; - -public record struct VariableSymbol(string Name, SymbolType Type) -{ - public static VariableSymbol None => new(null!, SymbolType.Void); -} - diff --git a/src/SDSL/TAC/IR.Convert.Expression.cs b/src/SDSL/TAC/IR.Convert.Expression.cs deleted file mode 100644 index e5178e7d07..0000000000 --- a/src/SDSL/TAC/IR.Convert.Expression.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Collections; -using System.Numerics; -using System.Runtime.InteropServices; -using CommunityToolkit.HighPerformance.Buffers; -using SDSL.Parsing.AST.Shader; -using SDSL.Symbols; -using shortid; - -namespace SDSL.TAC; - -public sealed partial class IR -{ - Operand? Convert(Expression expr) - { - if (expr is NumberLiteral nl) - { - return - new( - nl.Value.ToString(), - Kind.Constant, - nl.InferredType - ); - - } - else if (expr is BoolLiteral bl) - { - return - new( - bl.Value.ToString(), - Kind.Constant, - SymbolType.Scalar("bool") - ); - } - else if (expr is VariableNameLiteral vnl) - { - return - new( - vnl.Name, - Kind.Variable, - vnl.InferredType - ); - } - else if (expr is UnaryExpression ue) - return Convert(ue); - else if (expr is Operation op) - { - var resultL = Convert(op.Left as Expression ?? throw new NotImplementedException()); - var resultR = Convert(op.Right as Expression ?? throw new NotImplementedException()); - - Add( - new( - op.Op.Convert(), - resultL, - resultR, - new(ShortId.Generate(), Kind.Variable) - ) - ); - return this[Count - 1].Result; - } - else - throw new NotImplementedException(); - } - - Operand? Convert(UnaryExpression ue) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/src/SDSL/TAC/IR.Convert.cs b/src/SDSL/TAC/IR.Convert.cs deleted file mode 100644 index c8ad7ba0e6..0000000000 --- a/src/SDSL/TAC/IR.Convert.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Collections; -using System.Numerics; -using System.Runtime.InteropServices; -using CommunityToolkit.HighPerformance.Buffers; -using SDSL.Parsing.AST.Shader; -using SDSL.Parsing.AST.Shader.Symbols; - -namespace SDSL.TAC; - -public sealed partial class IR -{ - public static IR Convert(ShaderMethod method) - { - var ir = new IR(); - if(method is MainMethod m) - { - // TODO: Depending the main method generate variables - } - foreach (var statement in method.Statements) - if (statement is SimpleDeclare sd) - ir.Convert(sd); - else if (statement is DeclareAssign da) - ir.Convert(da); - return ir; - - } - void Convert(SimpleDeclare sd) - { - Add(new(Operator.Declare, Result: new(sd.VariableName, Kind.Variable, sd.TypeName))); - } - void Convert(DeclareAssign da) - { - var vId = Convert(da.Value as Expression ?? throw new NotImplementedException()); - Add(new(Operator.Declare, vId, Result: new(da.VariableName, Kind.Variable, da.TypeName))); - } -} \ No newline at end of file diff --git a/src/SDSL/TAC/IR.cs b/src/SDSL/TAC/IR.cs deleted file mode 100644 index 4c1f1a945b..0000000000 --- a/src/SDSL/TAC/IR.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections; -using System.Numerics; -using System.Runtime.InteropServices; -using CommunityToolkit.HighPerformance.Buffers; - -namespace SDSL.TAC; - -public sealed partial class IR -{ - MemoryOwner _values; - - public Span Span => _values.Span[..Count]; - public Memory Memory => _values.Memory[..Count]; - - public ref Quadruple this[int index] { get => ref Span[index]; } - - public int Count { get; private set; } - - public IR() - { - _values = MemoryOwner.Allocate(4, AllocationMode.Clear); - } - - void Expand(int size) - { - int nsize = Count + size; - if(nsize > _values.Length) - { - var tmp = MemoryOwner.Allocate( - (int)BitOperations.RoundUpToPowerOf2((uint)nsize), - AllocationMode.Clear - ); - Span.CopyTo(tmp.Span); - _values.Dispose(); - _values = tmp; - - } - } - - public Span.Enumerator GetEnumerator() => Span.GetEnumerator(); - - public void Add(Quadruple item) - { - Expand(1); - Count += 1; - Span[Count - 1] = item; - } - public void Clear() - { - Span.Clear(); - Count = 0; - } - public bool Contains(Quadruple item) => Span.Contains(item); - public int IndexOf(Quadruple item) => Span.IndexOf(item); - public void Insert(int index, Quadruple item) - { - Expand(1); - var data = Span[index..]; - Count += 1; - data.CopyTo(Span[(index+1)..]); - data[index] = item; - } -} \ No newline at end of file diff --git a/src/SDSL/TAC/Kind.cs b/src/SDSL/TAC/Kind.cs deleted file mode 100644 index f498a8639c..0000000000 --- a/src/SDSL/TAC/Kind.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace SDSL.TAC; - - -public enum Kind -{ - Undefined, - Label, - Constant, - Variable, - Literal -} \ No newline at end of file diff --git a/src/SDSL/TAC/Operand.cs b/src/SDSL/TAC/Operand.cs deleted file mode 100644 index 835d94b941..0000000000 --- a/src/SDSL/TAC/Operand.cs +++ /dev/null @@ -1,15 +0,0 @@ -using SDSL.Symbols; - -namespace SDSL.TAC; - -public record struct Operand(string Value, Kind Kind, SymbolType? Type = null) -{ - public readonly bool IsNone => Value == null && Kind == Kind.Undefined; - public static Operand None => new(null!, Kind.Undefined); - public static implicit operator Operand(in ValueTuple o) => new(o.Item1, o.Item2); - - public override string ToString() - { - return Value; - } -} \ No newline at end of file diff --git a/src/SDSL/TAC/Operator.cs b/src/SDSL/TAC/Operator.cs deleted file mode 100644 index 99b7c615ef..0000000000 --- a/src/SDSL/TAC/Operator.cs +++ /dev/null @@ -1,62 +0,0 @@ -using SDSL.Parsing.AST.Shader; -using static Spv.Specification; - -namespace SDSL.TAC; - - -public enum Operator -{ - Nop, - Declare, - Access, - If, - Goto, - Call, - Load, - PushParam, - Mul, - Div, - Mod, - Plus, - Minus, - LeftShift, - RightShift, - And, - Or, - Xor, - Less, - Greater, - LessEqual, - GreaterEqual, - Equals, - NotEquals, - LogicalAnd, - LogicalOr -} - -public static class OperatorExtensions -{ - public static Operator Convert(this OperatorToken token) => - token switch - { - OperatorToken.Mul => Operator.Mul, - OperatorToken.Div => Operator.Div, - OperatorToken.Mod => Operator.Mod, - OperatorToken.Plus => Operator.Plus, - OperatorToken.Minus => Operator.Minus, - OperatorToken.LeftShift => Operator.LeftShift, - OperatorToken.RightShift => Operator.RightShift, - OperatorToken.And => Operator.And, - OperatorToken.Or => Operator.Or, - OperatorToken.Xor => Operator.Xor, - OperatorToken.Less => Operator.Less, - OperatorToken.Greater => Operator.Greater, - OperatorToken.LessEqual => Operator.LessEqual, - OperatorToken.GreaterEqual => Operator.GreaterEqual, - OperatorToken.Equals => Operator.Equals, - OperatorToken.NotEquals => Operator.NotEquals, - OperatorToken.LogicalAnd => Operator.LogicalAnd, - OperatorToken.LogicalOr => Operator.LogicalOr, - _ => throw new NotImplementedException(), - }; -} \ No newline at end of file diff --git a/src/SDSL/TAC/Quadruple.cs b/src/SDSL/TAC/Quadruple.cs deleted file mode 100644 index 90fb16bd4f..0000000000 --- a/src/SDSL/TAC/Quadruple.cs +++ /dev/null @@ -1,27 +0,0 @@ -using SDSL.Parsing.AST.Shader; - -namespace SDSL.TAC; - - -public record struct Quadruple(Operator Operator, Operand? Operand1 = null, Operand? Operand2 = null, Operand? Result = null) -{ - public static Quadruple Nop => new(Operator.Nop); - - public static implicit operator Quadruple(in ValueTuple q) => new(q.Item1, q.Item2, q.Item3, q.Item4); - public override readonly string ToString() - { - - return Operator switch - { - Operator.Access => $"{Result} = {Operand1}[{Operand2}]", - Operator.Call => $"{Result} = Call {Operand1}", - Operator.Goto => $"Goto {Operand1}", - Operator.If => $"If {Operand1} Goto {Operand2}", - Operator.PushParam => $"PushParam {Operand1}", - Operator.Load => $"{Result} = Load {Operand1}", - Operator.Declare => $"{Operator} {Result} = {Operand1}{Operand2}", - Operator.Nop => "", - _ => $"{Result} = {Operand1} {Operator} {Operand2}" - }; - } -} \ No newline at end of file diff --git a/src/SDSLParserExample/Cross.cs b/src/SDSLParserExample/Cross.cs deleted file mode 100644 index dc6eb1e2f0..0000000000 --- a/src/SDSLParserExample/Cross.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System.Text; -using SPIRVCross; -using static SPIRVCross.SPIRV; - -namespace SDSLParserExample; - -public static class CrossExtensions -{ - - public static string ToGlsl(this Span byteCode) => ToGlsl(byteCode.ToArray()); - public static string ToHlsl(this Span byteCode) => ToHlsl(byteCode.ToArray()); - public static string ToGlsl(this byte[] bytecode) - { - unsafe - { - string GetString(byte* ptr) - { - int length = 0; - while (length < 4096 && ptr[length] != 0) - length++; - // Decode UTF-8 bytes to string. - return Encoding.UTF8.GetString(ptr, length); - } - - SpvId* spirv; - - fixed (byte* ptr = bytecode) - spirv = (SpvId*)ptr; - - uint word_count = (uint)bytecode.Length / 4; - - spvc_context context = default; - spvc_parsed_ir ir; - spvc_compiler compiler_glsl; - spvc_compiler_options options; - spvc_resources resources; - spvc_reflected_resource* list = default; - nuint count = default; - spvc_error_callback error_callback = default; - - // Create context. - if (spvc_context_create(&context) != spvc_result.SPVC_SUCCESS) throw new Exception(); - - // Set debug callback. - spvc_context_set_error_callback(context, error_callback, null); - - // Parse the SPIR-V. - Console.Write( - spvc_context_parse_spirv(context, spirv, word_count, &ir) switch - { - spvc_result.SPVC_SUCCESS => "", - spvc_result v => throw new Exception(v.ToString()) - } - ); - - // Hand it off to a compiler instance and give it ownership of the IR. - - if (spvc_context_create_compiler(context, spvc_backend.Glsl, ir, spvc_capture_mode.TakeOwnership, &compiler_glsl) != spvc_result.SPVC_SUCCESS) - throw new Exception(); - // Do some basic reflection. - - if (spvc_compiler_create_shader_resources(compiler_glsl, &resources) != spvc_result.SPVC_SUCCESS) - throw new Exception(); - if (spvc_resources_get_resource_list_for_type(resources, spvc_resource_type.UniformBuffer, (spvc_reflected_resource*)&list, &count) != spvc_result.SPVC_SUCCESS) - throw new Exception(); - - for (uint i = 0; i < count; i++) - { - Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", list[i].id, list[i].base_type_id, list[i].type_id, GetString(list[i].name)); - - uint set = spvc_compiler_get_decoration(compiler_glsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationDescriptorSet); - Console.WriteLine($"Set: {set}"); - - uint binding = spvc_compiler_get_decoration(compiler_glsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationBinding); - Console.WriteLine($"Binding: {binding}"); - - Console.WriteLine("========="); - } - Console.WriteLine("\n \n"); - - // Modify options. - if (spvc_compiler_create_compiler_options(compiler_glsl, &options) != spvc_result.SPVC_SUCCESS) throw new Exception(); - if (spvc_compiler_options_set_uint(options, spvc_compiler_option.GlslVersion, 450) != spvc_result.SPVC_SUCCESS) throw new Exception(); - if (spvc_compiler_options_set_bool(options, spvc_compiler_option.GlslEs, false) != spvc_result.SPVC_SUCCESS) throw new Exception(); - if (spvc_compiler_install_compiler_options(compiler_glsl, options) != spvc_result.SPVC_SUCCESS) throw new Exception(); - - byte* result = default; - var res = spvc_compiler_compile(compiler_glsl, (byte*)&result); - if (res != spvc_result.SPVC_SUCCESS) throw new Exception(res.ToString()); - var code = GetString(result); - - // Frees all memory we allocated so far. - spvc_context_destroy(context); - return code; - } - } - public static string ToHlsl(this byte[] bytecode) - { - unsafe - { - string GetString(byte* ptr) - { - int length = 0; - while (length < 4096 && ptr[length] != 0) - length++; - // Decode UTF-8 bytes to string. - return Encoding.UTF8.GetString(ptr, length); - } - - SpvId* spirv; - - fixed (byte* ptr = bytecode) - spirv = (SpvId*)ptr; - - uint word_count = (uint)bytecode.Length / 4; - - spvc_context context = default; - spvc_parsed_ir ir; - spvc_compiler compiler_hlsl; - spvc_compiler_options options; - spvc_resources resources; - spvc_reflected_resource* list = default; - nuint count = default; - spvc_error_callback error_callback = default; - - // Create context. - spvc_context_create(&context); - - // Set debug callback. - spvc_context_set_error_callback(context, error_callback, null); - - // Parse the SPIR-V. - spvc_context_parse_spirv(context, spirv, word_count, &ir); - - // Hand it off to a compiler instance and give it ownership of the IR. - spvc_context_create_compiler(context, spvc_backend.Hlsl, ir, spvc_capture_mode.TakeOwnership, &compiler_hlsl); - - // Do some basic reflection. - spvc_compiler_create_shader_resources(compiler_hlsl, &resources); - spvc_resources_get_resource_list_for_type(resources, spvc_resource_type.UniformBuffer, (spvc_reflected_resource*)&list, &count); - - for (uint i = 0; i < count; i++) - { - Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", list[i].id, list[i].base_type_id, list[i].type_id, GetString(list[i].name)); - - uint set = spvc_compiler_get_decoration(compiler_hlsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationDescriptorSet); - Console.WriteLine($"Set: {set}"); - - uint binding = spvc_compiler_get_decoration(compiler_hlsl, (SpvId)list[i].id, SpvDecoration.SpvDecorationBinding); - Console.WriteLine($"Binding: {binding}"); - - Console.WriteLine("========="); - } - Console.WriteLine("\n \n"); - - // Modify options. - spvc_compiler_create_compiler_options(compiler_hlsl, &options); - spvc_compiler_options_set_uint(options, spvc_compiler_option.HlslShaderModel, 50); - spvc_compiler_install_compiler_options(compiler_hlsl, options); - - byte* result = default; - spvc_compiler_compile(compiler_hlsl, (byte*)&result); - var code = GetString(result); - - // Frees all memory we allocated so far. - spvc_context_destroy(context); - return code; - } - } -} \ No newline at end of file diff --git a/src/SDSLParserExample/GLSL/a.spv b/src/SDSLParserExample/GLSL/a.spv deleted file mode 100644 index fdb5453cf03335741663a60d38e77f9db284c22d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1148 zcmY+CZA;ux5QRr~*KXDNQmaB=Y*uZ%tti^sH>8CkC0`c&;138(HbNk~3E8aBzt>;Y zFP5Gsxwou=;m(;kbMDOCv=$E@m@U|fJ+gP!e4DnYh$*&IpW)zoa5Ak%C+8neVXRrJ zCc;^_uC;Yy<6$}>@mRJe>&rI8C8tZ|wWMtJTZL^~wr~)IS6AWSXA~DjG_8JRNtC6N zBpRh<5?ASM0Tp3pCJQ)hUYfsc+ZwN;@xI{@J~JtKLO(SKIcL ztGVwRtpnj=Skh{(#m@4mQ45_myW|7oWAqP(@AF&QF8l4(o3`5Dk-wx^Alnt6cL1|9 zaMxj8bWfPw!66<9FFQ=UC%ob?@onLCoq>#gjvU^Q&qw{HPI72oIL!Y+jQkUqBM*M6 zlm565KA3$H^ZL)_`}!Bor(gJBzaR7hVQT$6Z{#zp?+4s>u}^vd_Q!7c;QdjgqZ4g< z<^6muJK+7m-<0Q$moo1Ep{hVTGxM5GueBu~EoNc|+cJ2(Gx}gS UKEEU1=e@?RV#NPS8=pS@0mDOD?EnA( diff --git a/src/SDSLParserExample/GLSL/main.frag b/src/SDSLParserExample/GLSL/main.frag deleted file mode 100644 index c2185aebf8..0000000000 --- a/src/SDSLParserExample/GLSL/main.frag +++ /dev/null @@ -1,29 +0,0 @@ -#version 450 - - -layout (location = 0) in vec4 color; -layout (location = 1) in vec3 pos; -layout (location = 0) out vec4 o_color; - - -struct Stream { - vec4 col; - vec3 pos; -}; - - -Stream streams; - - -vec4 ComputeColor(inout Stream streams) -{ - streams.col = color; - return streams.col; -} - -void main() -{ - streams.pos = pos; - vec4 color2 = ComputeColor(streams); - o_color = color; -} diff --git a/src/SDSLParserExample/Program.cs b/src/SDSLParserExample/Program.cs deleted file mode 100644 index 3704e7c398..0000000000 --- a/src/SDSLParserExample/Program.cs +++ /dev/null @@ -1,310 +0,0 @@ -using SDSL.Parsing; -using SDSL.Parsing.AST.Shader; -using SDSL.Analysis; -using SDSL.Parsing.AST.Shader.Symbols; -using SDSL.Parsing.Grammars.SDSL; -using SDSL.Symbols; -using SDSLParserExample; -using SoftTouch.Spirv; -using SoftTouch.Spirv.Core; -using SoftTouch.Spirv.Core.Buffers; -using SoftTouch.Spirv.Core.Parsing; -using SoftTouch.Spirv.PostProcessing; -using System.Diagnostics; -using System.Numerics; -using static Spv.Specification; -using Eto.Parse; -using SDSL.TAC; -using System.Reflection; -using SDSL.Mixing; - -static void ThreeAddress() -{ - var symb = new SymbolTable(); - var flt = SymbolType.Scalar("float"); - - var o = - new Operation - { - Left = new NumberLiteral { Value = 5f, InferredType = flt }, - Right = new NumberLiteral { Value = 6f, InferredType = flt }, - Op = OperatorToken.Plus - }; - - var s = new DeclareAssign() { TypeName = flt, VariableName = "dodo", AssignOp = AssignOpToken.Equal, Value = o }; - - var o2 = - new Operation - { - Left = new VariableNameLiteral("dodo"), - Right = new NumberLiteral { Value = 6L, InferredType = flt }, - Op = OperatorToken.Plus - }; - var s2 = new DeclareAssign() { VariableName = "dodo2", AssignOp = AssignOpToken.Equal, Value = o2 }; - - var x = 0; -} - - -void CrossShader() -{ - WordBuffer buffer = new(); - - buffer.AddOpCapability(Capability.Shader); - buffer.AddOpExtension("SPV_GOOGLE_decorate_string"); - buffer.AddOpExtension("SPV_GOOGLE_hlsl_functionality1"); - var extInstImport = buffer.AddOpExtInstImport("GLSL.std.450"); - buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.Vulkan); - - - // declarations - - Span c = stackalloc IdRef[10]; // This is for use in parameters - - - var t_void = buffer.AddOpTypeVoid(); - - var t_bool = buffer.AddOpTypeBool(); - - var t_func = buffer.AddOpTypeFunction(t_void, Span.Empty); - var t_float = buffer.AddOpTypeFloat(32); - var t_uint = buffer.AddOpTypeInt(32, 0); - var t_int = buffer.AddOpTypeInt(32, 1); - var t_float4 = buffer.AddOpTypeVector(t_float, 4); - var t_p_float4_func = buffer.AddOpTypePointer(StorageClass.Function, t_float4); - var constant1 = buffer.AddOpConstant(t_float, 5); - var constant2 = buffer.AddOpConstant(t_float, 2); - var constant3 = buffer.AddOpConstant(t_uint, 5); - var compositeType = buffer.AddOpConstantComposite( - t_float4, - stackalloc IdRef[] { constant1, constant1, constant2, constant1 } - ); - - var t_array = buffer.AddOpTypeArray(t_float4, constant3); - - var t_struct = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_uint, t_array, t_int }); - var t_struct2 = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_struct, t_uint }); - - var t_p_struct2 = buffer.AddOpTypePointer(StorageClass.Uniform, t_struct2); - - var v_struct2 = buffer.AddOpVariable(t_p_struct2, StorageClass.Uniform, null); - - var constant4 = buffer.AddOpConstant(t_int, 1); - - var t_p_uint = buffer.AddOpTypePointer(StorageClass.Uniform, t_uint); - var constant5 = buffer.AddOpConstant(t_uint, 0); - - var t_p_output = buffer.AddOpTypePointer(StorageClass.Output, t_float4); - var v_output = buffer.AddOpVariable(t_p_output, StorageClass.Output, null); - - var t_p_input = buffer.AddOpTypePointer(StorageClass.Input, t_float4); - var v_input = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - - var constant6 = buffer.AddOpConstant(t_int, 0); - var constant7 = buffer.AddOpConstant(t_int, 2); - var t_p_float4_unif = buffer.AddOpTypePointer(StorageClass.Uniform, t_float4); - - var v_input_2 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - var t_p_func = buffer.AddOpTypePointer(StorageClass.Function, t_int); - var constant8 = buffer.AddOpConstant(t_int, 4); - var v_input_3 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - - - - - buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); - buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); - buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); - buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); - buffer.AddOpDecorate(t_struct2, Decoration.Block); - buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); - buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); - buffer.AddOpDecorateStringGOOGLE(v_output, Decoration.HlslSemanticGOOGLE, null, null, "COLOR"); - - - - - buffer.AddOpName(t_p_func, "main"); - buffer.AddOpName(t_struct, "S"); - buffer.AddOpMemberName(t_struct, 0, "b"); - buffer.AddOpMemberName(t_struct, 1, "v"); - buffer.AddOpMemberName(t_struct, 2, "i"); - - - var main = buffer.AddOpFunction(t_void, FunctionControlMask.MaskNone, t_func); - buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "main", stackalloc IdRef[] { v_output, v_input, v_input_2, v_input_3 }); - buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); - - buffer.AddOpLabel(); - buffer.AddOpReturn(); - buffer.AddOpFunctionEnd(); - - buffer.GenerateSpirv().ToHlsl(); -} - - - -void CreateMixin() -{ - var mA = - Mixer.Create("MixinA") - .FinishInherit() - .WithType("float4") - .WithType("int*", StorageClass.Function) - .Build(); - var mB = - Mixer.Create("MixinB") - .Inherit("MixinA") - .FinishInherit() - .WithType("float4x4") - .Build(); - - var mC = - Mixer.Create("MixinC") - .Inherit("MixinA") - .FinishInherit() - .WithType("float4x2") - .Build(); - - - //CompositionSourceProvider.CompileAndRegister("MixinC"); - - var mD = - Mixer.Create("MixinD") - .Inherit("MixinB") - .Inherit("MixinC") - .FinishInherit(); - var mixin = - mD - .WithType("float4x3") - .WithConstant("a", 5f) - .WithInput("float3", "in_normal", "Normal", ExecutionModel.Vertex) - .WithInput("float3", "in_color", "Color", ExecutionModel.Vertex) - .WithOutput("float4", "out_position", "SV_Position", ExecutionModel.Vertex) - .WithOutput("float3", "out_color", "Color", ExecutionModel.Vertex) - .WithFunction("void", "DoNothing", static b => b.With("float", "myInt").With("float", "otherInt")) - .Return() - .FunctionEnd() - .WithFunction("float", "ReturnOne", static b => b) - .Return((m, f) => f.Constant(1f)) - .FunctionEnd() - .WithEntryPoint(ExecutionModel.Vertex, "VSMain") - .FunctionStart() - .DeclareAssign("a", 5f) - .Assign("out_position", (b,f) => f.Constant(new Vector4(1,2,3,0))) - .Declare("float", "b") - .AssignConstant("b", 6f) - .Declare("float", "c") - .Assign( - "c", - (m, f) => - f.Add( - "float", - f.Load("a"), - f.Mul( - "float", - f.Sin(f.Load("b")), - f.Call("ReturnOne", x => x) - ) - ) - ) - .CallFunction("DoNothing", (FunctionCallerParameters p) => p.With(p.Builder.Load("a")).With(p.Builder.Add("float" ,p.Builder.Constant(8f), p.Builder.Load("a")))) - .Return() - .FunctionEnd() - - .WithCapability(Capability.Shader) - .WithCapability(Capability.Float16) - .WithCapability(Capability.Int8) - .Build(); - - //Console.WriteLine(mA); - //Console.WriteLine(mB); - //Console.WriteLine(mD.Disassemble()); - - Console.WriteLine(mixin); - var processed = PostProcessor.Process("MixinD"); - processed = PostProcessor.Process("MixinD"); - processed.Dispose(); - Stopwatch stopwatch = Stopwatch.StartNew(); - processed = PostProcessor.Process("MixinD"); - stopwatch.Stop(); - - Console.WriteLine($"Process took : {stopwatch.Elapsed.TotalNanoseconds / 1000}µs"); - Console.WriteLine(Disassembler.Disassemble(processed)); - - - File.WriteAllBytes("./mixed.spv", processed.Bytes.ToArray()); - processed.Bytes.ToArray().ToGlsl(); - - stopwatch.Restart(); - var code = processed.Bytes.ToArray().ToGlsl(); - stopwatch.Stop(); - Console.WriteLine(code); - Console.WriteLine($"Cross compilation took : {stopwatch.Elapsed.TotalNanoseconds / 1000}µs"); - - var y = 0; -} - -static void ParseWorking() -{ - var buffer = new WordBuffer(); - var mixinName = buffer.AddOpSDSLMixinName("MyMixin"); - - buffer.AddOpExtInstImport("GLSL.std.450"); - - var t_flt = buffer.AddOpTypeFloat(32); - var t_vec4 = buffer.AddOpTypeVector(t_flt, 4); - var c_3f = buffer.AddOpConstant(t_flt,3f); - var c_4f = buffer.AddOpConstant(t_flt,4f); - var c_5f = buffer.AddOpConstant(t_flt,5f); - var c_6f = buffer.AddOpConstant(t_flt,6f); - - var c_vec4 = buffer.AddOpConstantComposite(t_vec4, stackalloc IdRef[]{c_3f,c_4f,c_5f,c_6f}); - - Console.WriteLine(Disassembler.Disassemble(buffer)); -} - -static void CheckOrderedEnumerator() -{ - var buffer = new WordBuffer(); - var t_int = buffer.AddOpTypeInt(32, 1); - var i_var = buffer.AddOpVariable(t_int, StorageClass.Private, null); - buffer.AddOpName(i_var, "My_var"); - buffer.AddOpTypeInt(64, 0); - buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); - buffer.AddOpCapability(Capability.Shader); - buffer.AddOpCapability(Capability.Geometry); - buffer.AddOpCapability(Capability.VectorComputeINTEL); - - foreach(var e in buffer) - { - Console.WriteLine(e.OpCode); - } -} - -static void ParseSDSL() -{ - - var shader = File.ReadAllText(@"C:\Users\youness_kafia\Documents\dotnetProjs\SDSLParser\src\SDSLParserExample\SDSL\MixinSamples\MyShader.sdsl"); - var program = ShaderMixinParser.ParseShader(shader); - new Analyzer().Analyze(program); - ShaderMixer.Compile(program); - - Console.WriteLine(MixinSourceProvider.Get("Something")); - - var x = 0; - -} - -//ParseWorking(); -//CheckOrderedEnumerator(); -Console.WriteLine("working on " + Directory.GetCurrentDirectory()); -ParseSDSL(); -var t = 0; - - -//CrossShader(); - -//ThreeAddress(); \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/Directive.sdsl b/src/SDSLParserExample/SDSL/Directive.sdsl deleted file mode 100644 index da788fd066..0000000000 --- a/src/SDSLParserExample/SDSL/Directive.sdsl +++ /dev/null @@ -1 +0,0 @@ -#else \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/Expressions.sdsl b/src/SDSLParserExample/SDSL/Expressions.sdsl deleted file mode 100644 index 5511d62eea..0000000000 --- a/src/SDSLParserExample/SDSL/Expressions.sdsl +++ /dev/null @@ -1 +0,0 @@ -float a[5]; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/Methods.sdsl b/src/SDSLParserExample/SDSL/Methods.sdsl deleted file mode 100644 index f65fb732e1..0000000000 --- a/src/SDSLParserExample/SDSL/Methods.sdsl +++ /dev/null @@ -1,8 +0,0 @@ - - - - -void foo(in MyStruct> a : SV_POSITION, out float b) -{ - -} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/Child.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/Child.sdsl deleted file mode 100644 index 95c9db4840..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/Child.sdsl +++ /dev/null @@ -1,4 +0,0 @@ -shader Child : Parent -{ - stream float a; -} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl deleted file mode 100644 index f0b1f820a7..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/MyShader.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -namespace MyNamespace -{ - shader Something - { - void VSMain() - { - int a = 5 + 8 + 3; - int b = a; - } - - void Add(int a, int b) - { - } - void Multiply(float3 a, float3 b) - { - } - } -} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/Parent.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/Parent.sdsl deleted file mode 100644 index 70b475b760..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/Parent.sdsl +++ /dev/null @@ -1,4 +0,0 @@ -shader Parent -{ - stream float a; -} \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl deleted file mode 100644 index 9edca0ed3c..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBase.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -shader ShaderBase : ShaderBaseStream -{ - // Declare Vertex shader main method - stage void VSMain() {} - - // Declare Pixel shader main method - stage void PSMain() {} -}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl deleted file mode 100644 index bf1fa67566..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/ShaderBaseStream.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -shader ShaderBaseStream -{ - // Default SV_POSITION output for VS/GS shaders - stage stream float4 ShadingPosition : SV_Position; - -/* -#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 - // Positive if this face is a front face, negative otherwise - stage stream float IsFrontFace : VFACE; -#else - // True if this face is a front face - stage stream bool IsFrontFace : SV_IsFrontFace; -#endif -*/ - // Default COLOR outputs for PS shader - stage stream float4 ColorTarget : SV_Target0; - stage stream float4 ColorTarget1 : SV_Target1; - stage stream float4 ColorTarget2 : SV_Target2; - stage stream float4 ColorTarget3 : SV_Target3; - stage stream float4 ColorTarget4 : SV_Target4; - stage stream float4 ColorTarget5 : SV_Target5; - stage stream float4 ColorTarget6 : SV_Target6; - stage stream float4 ColorTarget7 : SV_Target7; - - // Default DEPTH output for PS shader - stage stream float Depth : SV_Depth; - stage stream float DepthGreater : SV_DepthGreater; // Special output after PS - stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS - - // Default InstanceId for VS/GS shaders - stage stream uint InstanceID : SV_InstanceID; -}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl b/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl deleted file mode 100644 index f2904bf9a9..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/SingleShader.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -shader SingleShader { - - struct Position { - float x; - float y; - float z; - }; - - stage stream float4 triInput; - - // Default SV_POSITION output for VS/GS shaders - stage stream float4 ShadingPosition : SV_Position; - - // front face - stage stream bool IsFrontFace : SV_IsFrontFace; - // Default COLOR outputs for PS shader - stage stream float4 ColorTarget : SV_Target0; - stage stream float4 ColorTarget1 : SV_Target1; - stage stream float4 ColorTarget2 : SV_Target2; - stage stream float4 ColorTarget3 : SV_Target3; - stage stream float4 ColorTarget4 : SV_Target4; - stage stream float4 ColorTarget5 : SV_Target5; - stage stream float4 ColorTarget6 : SV_Target6; - stage stream float4 ColorTarget7 : SV_Target7; - - // Default DEPTH output for PS shader - stage stream float Depth : SV_Depth; - stage stream float DepthGreater : SV_DepthGreater; // Special output after PS - stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS - - stage stream uint InstanceID : SV_InstanceID; - - - void VSMain() - { - float4 a = float4(0); - streams.ShadingPosition = a; - streams.ColorTarget = float3(0); - } -}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/MixinSamples/spv-semantics.dis b/src/SDSLParserExample/SDSL/MixinSamples/spv-semantics.dis deleted file mode 100644 index f107e74f90..0000000000 --- a/src/SDSLParserExample/SDSL/MixinSamples/spv-semantics.dis +++ /dev/null @@ -1,70 +0,0 @@ -; SPIR-V -; Version: 1.0 -; Generator: Khronos Glslang Reference Front End; 10 -; Bound: 79 -; Schema: 0 - OpCapability Shader - OpExtension "SPV_GOOGLE_hlsl_functionality1" - %1 = OpExtInstImport "GLSL.std.450" - OpMemoryModel Logical GLSL450 - OpEntryPoint Vertex %VSMain "VSMain" %vPosition %_entryPointOutput_Pos %_entryPointOutput_Pshade - OpSource HLSL 500 - OpName %VSMain "VSMain" - OpName %_Global "$Global" - OpMemberName %_Global 0 "view_proj_matrix" - OpMemberName %_Global 1 "texture_matrix0" - OpName %_ "" - OpName %vPosition "vPosition" - OpName %_entryPointOutput_Pos "@entryPointOutput.Pos" - OpName %_entryPointOutput_Pshade "@entryPointOutput.Pshade" - OpMemberDecorate %_Global 0 RowMajor - OpMemberDecorate %_Global 0 Offset 0 - OpMemberDecorate %_Global 0 MatrixStride 16 - OpMemberDecorate %_Global 1 RowMajor - OpMemberDecorate %_Global 1 Offset 64 - OpMemberDecorate %_Global 1 MatrixStride 16 - OpDecorate %_Global Block - OpDecorate %_ DescriptorSet 0 - OpDecorate %_ Binding 0 - OpDecorate %vPosition Location 0 - OpDecorateString %vPosition UserSemantic "POSITION" - OpDecorate %_entryPointOutput_Pos Location 0 - OpDecorateString %_entryPointOutput_Pos UserSemantic "POSITION" - OpDecorate %_entryPointOutput_Pshade Location 1 - OpDecorateString %_entryPointOutput_Pshade UserSemantic "TEXCOORD0" - %void = OpTypeVoid - %3 = OpTypeFunction %void - %float = OpTypeFloat 32 - %v4float = OpTypeVector %float 4 - %v3float = OpTypeVector %float 3 - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 -%mat4v4float = OpTypeMatrix %v4float 4 - %_Global = OpTypeStruct %mat4v4float %mat4v4float -%_ptr_Uniform__Global = OpTypePointer Uniform %_Global - %_ = OpVariable %_ptr_Uniform__Global Uniform -%_ptr_Uniform_mat4v4float = OpTypePointer Uniform %mat4v4float - %int_1 = OpConstant %int 1 -%_ptr_Input_v4float = OpTypePointer Input %v4float - %vPosition = OpVariable %_ptr_Input_v4float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float -%_entryPointOutput_Pos = OpVariable %_ptr_Output_v4float Output -%_ptr_Output_v3float = OpTypePointer Output %v3float -%_entryPointOutput_Pshade = OpVariable %_ptr_Output_v3float Output - %VSMain = OpFunction %void None %3 - %5 = OpLabel - %50 = OpLoad %v4float %vPosition - %67 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_0 - %68 = OpLoad %mat4v4float %67 - %69 = OpVectorTimesMatrix %v4float %50 %68 - %72 = OpAccessChain %_ptr_Uniform_mat4v4float %_ %int_1 - %73 = OpLoad %mat4v4float %72 - %74 = OpVectorTimesMatrix %v4float %50 %73 - %75 = OpCompositeExtract %float %74 0 - %76 = OpCompositeExtract %float %74 1 - %77 = OpCompositeExtract %float %74 2 - %78 = OpCompositeConstruct %v3float %75 %76 %77 - OpStore %_entryPointOutput_Pos %69 - OpStore %_entryPointOutput_Pshade %78 - OpReturn - OpFunctionEnd \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/comments.sdsl b/src/SDSLParserExample/SDSL/comments.sdsl deleted file mode 100644 index 1f1a9ca932..0000000000 --- a/src/SDSLParserExample/SDSL/comments.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// my first line -// Hello second line -float a; -/* this is a block comment - And i can say a bit more on this line -*/ \ No newline at end of file diff --git a/src/SDSLParserExample/SDSL/shader.sdsl b/src/SDSLParserExample/SDSL/shader.sdsl deleted file mode 100644 index 487c3da1db..0000000000 --- a/src/SDSLParserExample/SDSL/shader.sdsl +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.LightProbes -{ - /// - /// Defines a skybox environment light - /// - shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils - { - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { -#ifdef STRIDE_MULTISAMPLE_COUNT - #if STRIDE_MULTISAMPLE_COUNT > 1 - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #else - stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #endif -#else - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID -#endif - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } - - void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) - { - // Early exit - if (weight == 0.0f) - return; - - int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; - for (int i = 0; i < TOrder * TOrder; ++i) - { - // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly - sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; - } - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - var sampleDirection = streams.normalWS; - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - var shadingPosition = int3(streams.ShadingPosition.xy, 0); -#if STRIDE_MULTISAMPLE_COUNT == 1 - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); -#else - // TODO: Use SV_SampleIndex - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); -#endif - - uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); - float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); - - float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); - - // Protect ourselves against degenerate cases - // TODO: Investigate why those happen (almost coplanar tetrahedron?) - tetrahedronFactors3 = saturate(tetrahedronFactors3); - - float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); - - // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) - tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Renormalize barycentric coordinates - var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; - if (totalSum > 0.0f) - tetrahedronFactors4 /= totalSum; - - float3 sphericalColors[TOrder * TOrder]; - for (int i = 0; i < TOrder * TOrder; ++i) - sphericalColors[i] = 0.0f; - - FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); - FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); - FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); - FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - - streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - // TEST: - //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - //streams.envLightDiffuseColor = tetrahedronFactors3; - //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); - } - }; -} diff --git a/src/SDSLParserExample/SDSL/shader2.sdsl b/src/SDSLParserExample/SDSL/shader2.sdsl deleted file mode 100644 index fc46448bd6..0000000000 --- a/src/SDSLParserExample/SDSL/shader2.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -shader Simple : Parent/*<5, float, 12>*/, Parent2 { - float a = 0; - - // void VSMain(){ - // float b = (5+2)*3; - // } -}; \ No newline at end of file diff --git a/src/SDSLParserExample/SDSLParserExample.csproj b/src/SDSLParserExample/SDSLParserExample.csproj deleted file mode 100644 index e03f037ad1..0000000000 --- a/src/SDSLParserExample/SDSLParserExample.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - Exe - net8.0 - enable - enable - true - true - - diff --git a/src/SDSLParserExample/mixed.spv b/src/SDSLParserExample/mixed.spv deleted file mode 100644 index 76390f1358f779589563f9152d0a7ee23ffa0c4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1296 zcmZvc*-jKu5QdBC24X;vfGn;vBH)693)?utG{l6EpeB%TO9q@sC(vz%=E6I?@I8DK zAIlq!|9AQvqQpaLs{Y#hKix!?>3)lP?1`CeN;o4{u^z9lc|9jRV12eKy|uHqQ$H&{ z))$wa3)+xHC|5IVRG7_5_V?bk(~N#*W0DEUElIEb?nuAQ-{-|~ntk%Vn)Gg`IPYd3 zvX1k`|Ma1bUTJoa<=xZviLax#d`J07-j%7WJ~t~rFAhHEXK9h<+M=AxeEcD~*J8UX z-|3g_tnfMa$SICH-O{Cgk>jWB;*q_SKJ@mI^pRvseb|j!4w${ba0%x52P7OYyM+94 z%^668Mk?LW_MmtdQe9$ab~}ezB>Drd}coq;*0-@ue-QyG!=(G z?wj4g@W*`z41e4=d=rO1?i;);-r#_5fCGmsicrhD7;N5+pL&X_^e;tMCDf8vlW^dg zoN4Lb(r_K}n8A0*fp_xeq?_si_k8nk0O#xoC%oJEz;M9(4PMuNJP&+glLudG%445p z3H<_IkxkB^zD42<3I98;ONcdm-D}xA%QydAO&2r6|JD26$fiFrX0sE%Fl$Zr-?LjD Xhx$aAyTjkmKJc<3fq!ZfN#OSnJz`Ok diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs new file mode 100644 index 0000000000..3f6b8026dc --- /dev/null +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -0,0 +1,6 @@ +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; + + +Console.WriteLine("Hello world"); +Console.WriteLine(Directory.GetCurrentDirectory()); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj new file mode 100644 index 0000000000..370311e009 --- /dev/null +++ b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrame.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrame.cs new file mode 100644 index 0000000000..3f96fcfa20 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrame.cs @@ -0,0 +1,24 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + + +public sealed class CodeFrame() : IDisposable +{ + public MemoryOwner Code { get; private set; } = MemoryOwner.Empty; + public List CodeSpans { get; } = []; + public int Length => Code.Length; + + public void Resize(int length) => Code = Code.Resize(length); + + public void Add(CodeFrame previousFrame, Range range) + { + var span = previousFrame.Code.Span[range]; + Resize(span.Length); + span.CopyTo(Code.Span[^span.Length..]); + CodeSpans.Add((previousFrame, range)); + } + + public void Dispose() => + Code.Dispose(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs new file mode 100644 index 0000000000..5f914bebfe --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs @@ -0,0 +1,25 @@ +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + +public record struct CodeFrameSnippets(CodeFrame Frame, Range Location) +{ + public readonly Span Span => Frame.Code.Span[Location]; + public readonly Memory Memory => Frame.Code.Memory[Location]; + + public readonly int Line + { + get + { + (int offset, int length) = Location.GetOffsetAndLength(Frame.Code.Length); + return Frame.Code.Span[..(offset + length)].Count('\n'); + } + } + public readonly int Column + { + get + { + (int offset, int length) = Location.GetOffsetAndLength(Frame.Code.Length); + return Frame.Code.Span[..(offset + length)].Length - Frame.Code.Span[..(offset + length)].LastIndexOf('\n'); + } + } + public static implicit operator CodeFrameSnippets((CodeFrame frame, Range range) tuple) => new(tuple.frame, tuple.range); +} diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeProcessor.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeProcessor.cs new file mode 100644 index 0000000000..446a225427 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeProcessor.cs @@ -0,0 +1,21 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + +public class SDSLPreProcessor() : IDisposable +{ + public List CodeFrames { get; set; } = []; + + public void Run() => + Apply(); + + public SDSLPreProcessor Apply() + where TPhase : struct, IPreProcessorPhase + => new TPhase().Apply(this); + + public void Dispose() + { + CodeFrames.ForEach(static x => x.Dispose()); + CodeFrames.Clear(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs new file mode 100644 index 0000000000..66085346af --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs @@ -0,0 +1,27 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + +public struct CommentPhase() : IPreProcessorPhase +{ + public readonly SDSLPreProcessor Apply(SDSLPreProcessor sdslpp) + { + var frame = new CodeFrame(); + var last = sdslpp.CodeFrames[^1]; + var scanner = new Scanner(last.Code.Memory); + var started = false; + while(!CommonParsers.Until(ref scanner, ["//", "/*"])) + { + if(!started) + started = true; + frame.Add(last, ..scanner.Position); + if (Terminals.Literal("//", ref scanner)) + CommonParsers.Until(ref scanner, '\n', advance: true); + else if (Terminals.Literal("/*", ref scanner)) + CommonParsers.Until(ref scanner, "*/", advance: true); + } + if (!started) + frame.Add(last, ..); + return sdslpp; + } +} diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs new file mode 100644 index 0000000000..caf282352f --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs @@ -0,0 +1,6 @@ +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + +public interface IPreProcessorPhase +{ + SDSLPreProcessor Apply(SDSLPreProcessor sdslpp); +} diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/LocationTranslator.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/LocationTranslator.cs new file mode 100644 index 0000000000..47a6e6fabf --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/LocationTranslator.cs @@ -0,0 +1,39 @@ +using System.Runtime.InteropServices; +using System.Security.Cryptography.X509Certificates; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing.Macros; + + +public class LocationTranslator(Memory origin, Memory processed) +{ + public List Links { get; set; } = []; + public Memory Origin { get; set; } = origin; + public Memory Processed { get; set; } = processed; + + + /// + /// Gets the list of text locations that translate the range chosen to the original file. + /// + /// + public List this[Range range] + { + get + { + + var result = new List(); + + foreach (var link in Links) + { + if (link.Processed.Intersect(range, Processed.Length)) + { + var (start, length) = link.Origin.GetOffsetAndLength(Origin.Length); + result.Add(new Range(start, length)); + } + } + + return result; + } + } +} diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs b/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs new file mode 100644 index 0000000000..ef7ddcf432 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs @@ -0,0 +1,102 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing; + +/// +/// Representation of the code where comments have been removed +/// +public struct CommentProcessedCode : IScannableCode +{ + public ReadOnlyMemory Original { get; init; } + public MemoryOwner Processed { get; private set; } = MemoryOwner.Empty; + public MemoryOwner Links { get; private set; } = MemoryOwner.Empty; + + public readonly ReadOnlySpan Span => Memory.Span; + + public readonly ReadOnlyMemory Memory => Processed.Memory; + + public CommentProcessedCode(string originalFile) + { + Original = originalFile.AsMemory(); + Process(); + } + public CommentProcessedCode(ReadOnlyMemory originalFile) + { + Original = originalFile; + Process(); + } + + internal void Process() + { + var scanner = new Scanner(new(Original)); + var started = false; + var lastPos = 0; + while (!scanner.IsEof) + { + CommonParsers.Until(ref scanner, ["//", "/*", "\""]); + if (!started) + started = true; + Add(lastPos..scanner.Position); + lastPos = scanner.Position; + if (Terminals.Literal("//", ref scanner)) + { + CommonParsers.Until(ref scanner, '\n', advance: true); + lastPos = scanner.Position; + Add([' ']); + } + else if (Terminals.Literal("/*", ref scanner)) + { + CommonParsers.Until(ref scanner, "*/", advance: true); + lastPos = scanner.Position; + Add([' ']); + } + else if (Terminals.Literal("\"", ref scanner)) + { + CommonParsers.Until(ref scanner, "\"", advance: true); + Add(lastPos..scanner.Position); + lastPos = scanner.Position; + } + } + } + + internal void Add(Range range) + { + (_, var length) = range.GetOffsetAndLength(Original.Length); + Processed = Processed.Add(Original.Span[range]); + Links = Links.Add([new(range, (Processed.Length - length)..Processed.Length)]); + + } + internal void Add(Span span) + { + Processed = Processed.Add(span); + } + + /// + /// Gets the list of text locations that translate the range chosen to the original file. + /// + /// + public readonly TextLocation GetOriginalLocation(Range range) + { + var (start, length) = range.GetOffsetAndLength(Processed.Length); + var end = start + length; + var outputStart = -1; + foreach (var link in Links.Span) + { + var (linkStart, linkLength) = link.Processed.GetOffsetAndLength(Processed.Length); + var linkEnd = linkStart + linkLength; + (var linkOriginalStart, var linkOriginalLength) = link.Origin.GetOffsetAndLength(Original.Length); + var linkOriginalEnd = linkOriginalStart + linkOriginalLength; + var realStart = linkOriginalStart + (start - linkStart); + if (outputStart == -1 && start >= linkStart && start < linkEnd) + { + outputStart = realStart; + } + if (end <= linkEnd) + { + var outputEnd = linkOriginalEnd - (linkEnd - end); + return new(Original, outputStart..outputEnd); + } + } + return new(Original, 0..0); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/PreProcessing/MemoryOwnerExtensions.cs b/src/Stride.Shaders.Parsing/PreProcessing/MemoryOwnerExtensions.cs new file mode 100644 index 0000000000..0616f78944 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/MemoryOwnerExtensions.cs @@ -0,0 +1,32 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.PreProcessing; + + +public static class MemoryOwnerExtensions +{ + public static MemoryOwner Resize(this MemoryOwner owner, int size) + { + var result = MemoryOwner.Allocate(owner.Length + size, AllocationMode.Clear); + owner.Span[..Math.Min(result.Length, owner.Length)].CopyTo(result.Span); + owner.Dispose(); + return result; + } + + public static MemoryOwner Add(this MemoryOwner owner, ReadOnlySpan span) + { + var result = owner.Resize(span.Length); + span.CopyTo(result.Span[^span.Length..]); + return result; + } + public static MemoryOwner Add(this MemoryOwner owner, Span span) + { + var result = owner.Resize(span.Length); + span.CopyTo(result.Span[^span.Length..]); + return result; + } + public static MemoryOwner Add(this MemoryOwner owner, Memory other, Range range) + { + return owner.Add(other.Span[range]); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/PreProcessing/TextLink.cs b/src/Stride.Shaders.Parsing/PreProcessing/TextLink.cs new file mode 100644 index 0000000000..fd895c7a66 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/TextLink.cs @@ -0,0 +1,3 @@ +namespace Stride.Shaders.Parsing.SDSL.PreProcessing; + +public record struct TextLink(Range Origin, Range Processed); diff --git a/src/Stride.Shaders.Parsing/PreProcessing/TextLinkExtensions.cs b/src/Stride.Shaders.Parsing/PreProcessing/TextLinkExtensions.cs new file mode 100644 index 0000000000..377b4fb63c --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/TextLinkExtensions.cs @@ -0,0 +1,31 @@ +namespace Stride.Shaders.Parsing.SDSL.PreProcessing; + + + +public static class TextLinkExtensions +{ + + public static bool Intersect(this Range range, Range other, int length) + { + var (start, l) = range.GetOffsetAndLength(length); + var end = start + l; + var (otherStart, ol) = other.GetOffsetAndLength(length); + var otherEnd = otherStart + ol; + + return start <= otherEnd && end >= otherStart; + } + + public static bool OriginIntersect(this TextLink link, Range range, int length, int originLength, out Range? result) + { + if (link.Processed.Intersect(range, length)) + { + var (start, l) = link.Origin.GetOffsetAndLength(originLength); + var end = start + l; + result = new Range(start, end); + return true; + } + + result = null; + return false; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs new file mode 100644 index 0000000000..0bc481588a --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs @@ -0,0 +1,31 @@ +using System.Text; + +namespace Stride.Shaders.Parsing.SDSL.AST; + +public abstract class Node(TextLocation info) +{ + public TextLocation Info { get; set; } = info; +} +public class ValueNode(TextLocation info) : Node(info) +{ + public string? Type { get; set; } = null; +} +public class NoNode() : Node(new()); + + +public class CodeSnippets() : Node(new()) +{ + public List Snippets { get; set; } = []; + + public string ToCode() + { + var builder = new StringBuilder(); + foreach (var s in Snippets) + builder.Append(s.Info.Text); + return builder.ToString(); + } +} + +public class CodeNode(TextLocation info) : Node(info); +public class Comment(TextLocation info) : CodeNode(info); +public class Code(TextLocation info) : CodeNode(info); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs b/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs new file mode 100644 index 0000000000..cd0befd088 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs @@ -0,0 +1,74 @@ +namespace Stride.Shaders.Parsing.SDSL; + +public enum AssignOperator +{ + NOp, + Simple, + Plus, + Minus, + Mul, + Div, + Mod, + RightShift, + LeftShift, + AND, + OR, + XOR +} + + +public static class StringAssignOperatorExtensions +{ + public static AssignOperator ToAssignOperator(this ReadOnlySpan s) + { + return s switch + { + "+=" => AssignOperator.Plus, + "-=" => AssignOperator.Minus, + "*=" => AssignOperator.Mul, + "/=" => AssignOperator.Div, + "%=" => AssignOperator.Mod, + ">>=" => AssignOperator.RightShift, + "<<=" => AssignOperator.LeftShift, + "&=" => AssignOperator.AND, + "|=" => AssignOperator.OR, + "^=" => AssignOperator.XOR, + _ => AssignOperator.NOp + }; + } + public static AssignOperator ToAssignOperator(this string s) + { + return s switch + { + "+=" => AssignOperator.Plus, + "-=" => AssignOperator.Minus, + "*=" => AssignOperator.Mul, + "/=" => AssignOperator.Div, + "%=" => AssignOperator.Mod, + ">>=" => AssignOperator.RightShift, + "<<=" => AssignOperator.LeftShift, + "&=" => AssignOperator.AND, + "|=" => AssignOperator.OR, + "^=" => AssignOperator.XOR, + _ => AssignOperator.NOp + }; + } + public static string ToAssignSymbol(this AssignOperator s) + { + return s switch + { + AssignOperator.Plus => "+=", + AssignOperator.Minus => "-=", + AssignOperator.Mul => "*=", + AssignOperator.Div => "/=", + AssignOperator.Mod => "%=", + AssignOperator.RightShift => ">>=", + AssignOperator.LeftShift => "<<=", + AssignOperator.AND => "&=", + AssignOperator.OR => "|=", + AssignOperator.XOR => "^=", + _ => "NOp" + }; + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs b/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs new file mode 100644 index 0000000000..8adcea1a6c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs @@ -0,0 +1,10 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + +public abstract record DataType(); +public record Scalar() : DataType(), IGenericValue; +public record Vector(int Size) : DataType(), IGenericValue; +public record Matrix(int Rows, int Columns) : DataType(), IGenericValue; +public record Array(int Size) : DataType(); +public record Struct(Dictionary Fields) : DataType(); +public record Buffer(DataType BaseType) : DataType(), IGenericValue; +public record Texture(DataType BaseType) : DataType(), IGenericValue; \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Directives.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Directives.cs new file mode 100644 index 0000000000..e784837327 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Directives.cs @@ -0,0 +1,157 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public class PreProcessableCode(TextLocation info) : Node(info) +{ + public List Snippets { get; set; } = []; + public override string ToString() + { + return string.Join("\n", Snippets); + } +} + +public abstract class DirectiveStatement(TextLocation info) : Node(info); +/// +/// Represents a directive code snippet +/// +/// +public class DirectiveCode(TextLocation info) : DirectiveStatement(info) +{ + public override string ToString() + { + return Info.Text.ToString(); + } +} +/// +/// Represents a directive macro +/// +/// +public abstract class Directive(TextLocation info) : DirectiveStatement(info); + +/// +/// Represents a directive flow control using conditionals (#if #ifdef #ifndef #elif #else #endif) +/// +/// +/// +public abstract class DirectiveFlow(Expression? expression, TextLocation info) : Node(info) +{ + public Expression? Expression { get; set; } = expression; + public PreProcessableCode? Code { get; set; } +} +/// +/// Represents a directive define macro +/// +/// +/// +/// +public class ObjectDefineDirective(Identifier identifier, Expression? expression, TextLocation info) : Directive(info) +{ + public Identifier Identifier { get; set; } = identifier; + public Expression? Expression { get; set; } = expression; +} + +/// +/// Represents a directive define function +/// +/// +/// +/// +public class FunctionDefineDirective(Identifier functionName, string pattern, TextLocation info) : Directive(info) +{ + public Identifier FunctionName { get; set; } = functionName; + public List Parameters { get; set; } = []; + public string Pattern { get; set; } = pattern; +} +/// +/// Represents a directive conditional flow control #if +/// +/// +/// +public class IfDirective(Expression expression, TextLocation info) : DirectiveFlow(expression, info) +{ + public override string ToString() + { + return $"#if {Expression}\n{Code}"; + } +} + +/// +/// Represents a directive conditional flow control #ifdef +/// +/// +/// +public class IfDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) +{ + public override string ToString() + { + return $"#ifdef {Expression}\n{Code}"; + } +} +/// +/// Represents a directive conditional flow control #ifndef +/// +/// +/// +public class IfNDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) +{ + public override string ToString() + { + return $"#ifndef {Expression}\n{Code}"; + } +} +/// +/// Represents a directive conditional flow control #elif +/// +/// +/// +public class ElifDirective(Expression expression, TextLocation info) : IfDirective(expression, info) +{ + public override string ToString() + { + return $"#elif {Expression}{Code}"; + } +} +/// +/// Represents a directive conditional flow control #else +/// +/// +public class ElseDirective(TextLocation info) : DirectiveFlow(null, info) +{ + public override string ToString() + { + return $"#else\n{Code}"; + } +} +public class EndIfDirective(TextLocation info) : DirectiveFlow(null, info) +{ + public override string ToString() + { + return "#endif"; + } +} + +/// +/// Represents a directive conditional flow control +/// +/// +/// +public class ConditionalDirectives(IfDirective ifExp, TextLocation info) : Directive(info) +{ + public IfDirective If { get; set; } = ifExp; + public List Elifs { get; set; } = []; + public ElseDirective? Else { get; set; } + + public override string ToString() + { + return (If, Elifs, Else) switch + { + (var i, [], null) => $"{i}", + (var i, var e, null) when e is not [] && e is not null => $"{i}\n{string.Join("\n", e)}", + (var i, var e, var el) when e is not [] && e is not null => $"{i}\n{string.Join("\n", e)}\n{el}", + (var i, [], var el) => $"{i}\n{el}", + _ => throw new NotImplementedException() + } + "#endif"; + } +} + + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs new file mode 100644 index 0000000000..9a04f7a371 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs @@ -0,0 +1,83 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + + + +public abstract class Expression(TextLocation info) : ValueNode(info); + +public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) +{ + public Identifier Name = name; + public ShaderExpressionList Parameters = parameters; + + public override string ToString() + { + return $"{Name}({string.Join(", ", Parameters)})"; + } +} + + +public abstract class UnaryExpression(Expression expression, Operator op, TextLocation info) : Expression(info) +{ + public Expression Expression { get; set; } = expression; + public Operator Operator { get; set; } = op; +} + +public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info); + +public class CastExpression(string typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) +{ + public string TypeName { get; set; } = typeName; +} + +public class PostfixExpression(Expression expression, Operator op, TextLocation info) : UnaryExpression(expression, op, info) +{ + public override string ToString() + { + return $"{Expression}{Operator.ToSymbol()}"; + } +} + +public class AccessorExpression(Expression expression, Expression accessed, TextLocation info) : PostfixExpression(expression, Operator.Accessor, info) +{ + public Expression Accessed { get; set; } = accessed; + + public override string ToString() + { + return $"{Expression}.{Accessed}"; + } +} + +public class IndexerExpression(Expression expression, Expression index, TextLocation info) : PostfixExpression(expression, Operator.Indexer, info) +{ + public Expression Index { get; set; } = index; + public override string ToString() + { + return $"{Expression}[{Index}]"; + } +} + + +public class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) +{ + public Operator Op { get; set; } = op; + public Expression Left { get; set; } = left; + public Expression Right { get; set; } = right; + + public override string ToString() + { + return $"( {Left} {Op.ToSymbol()} {Right} )"; + } +} + +public class TernaryExpression(Expression cond, Expression left, Expression right, TextLocation info) : Expression(info) +{ + public Expression Condition { get; set; } = cond; + public Expression Left { get; set; } = left; + public Expression Right { get; set; } = right; + + public override string ToString() + { + return $"({Condition} ? {Left} : {Right})"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs new file mode 100644 index 0000000000..2f2f7aef29 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -0,0 +1,103 @@ +using System.Drawing; +using System.Numerics; + +namespace Stride.Shaders.Parsing.SDSL.AST; + + + +public abstract class Literal(TextLocation info) : Expression(info); +public abstract class ValueLiteral(TextLocation info) : Literal(info); +public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); + +public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) +{ + public abstract double DoubleValue { get; } + public abstract int IntValue { get; } + public abstract long LongValue { get; } + +} +public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info) : NumberLiteral(info) + where T : struct, INumber +{ + public Suffix Suffix { get; set; } = suffix; + public T Value { get; set; } = value; + public override double DoubleValue => Convert.ToDouble(Value); + public override long LongValue => Convert.ToInt64(Value); + public override int IntValue => Convert.ToInt32(Value); + public override string ToString() + { + return $"{Value}{Suffix}"; + } + +} + +public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info); +public class UnsignedIntegerLiteral(Suffix suffix, ulong value, TextLocation info) : NumberLiteral(suffix, value, info); + +public sealed class FloatLiteral(Suffix suffix, double value, TextLocation info) : NumberLiteral(suffix, value, info) +{ + public static implicit operator FloatLiteral(double v) => new(new(), v, new()); +} + +public sealed class HexLiteral(ulong value, TextLocation info) : UnsignedIntegerLiteral(new(32, false, false), value, info); + + +public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) +{ + public bool Value { get; set; } = value; +} + +public abstract class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral(info) +{ + public TypeName TypeName { get; set; } = typeName; +} +public class VectorLiteral(TypeName typeName, TextLocation info) : VectorLiteral(typeName, info) + where TValueLiteral : ValueLiteral +{ + public List Values { get; set; } = []; + + public override string ToString() + { + return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + } +} + + +public abstract class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : ValueLiteral(info) +{ + public TypeName TypeName { get; set; } = typeName; + public int Rows { get; set; } = rows; + public int Cols { get; set; } = cols; +} +public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : MatrixLiteral(typeName, rows, cols, info) + where TValueLiteral : ValueLiteral +{ + public List Values { get; set; } = []; + + public override string ToString() + { + return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + } +} + + + +public class Identifier(string name, TextLocation info) : Literal(info) +{ + public string Name { get; set; } = name; + + public override string ToString() + { + return $"{Name}"; + } +} + +public class TypeName(string name, TextLocation info) : Literal(info) +{ + public string Name { get; set; } = name; + + public override string ToString() + { + return $"{Name}"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs new file mode 100644 index 0000000000..7753080fc1 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs @@ -0,0 +1,153 @@ +namespace Stride.Shaders.Parsing.SDSL; + +public enum Operator +{ + Nop, + Cast, + Positive, + Negative, + Not, + /// + /// Bitwise not + /// + BitwiseNot, + /// + /// Increment + /// + Inc, + /// + /// Decrement + /// + Dec, + Plus, + Minus, + Mul, + Div, + Mod, + RightShift, + LeftShift, + AND, + OR, + XOR, + Greater, + Lower, + GreaterOrEqual, + LowerOrEqual, + NotEquals, + Equals, + LogicalAND, + LogicalOR, + Accessor, + Indexer +} + +public static class StringOperatorExtensions +{ + public static Operator ToOperator(this ReadOnlySpan s) + { + return s switch + { + "!" => Operator.Not, + "~" => Operator.BitwiseNot, + "++" => Operator.Inc, + "--" => Operator.Dec, + "+" => Operator.Plus, + "-" => Operator.Minus, + "*" => Operator.Mul, + "/" => Operator.Div, + "%" => Operator.Mod, + ">>" => Operator.RightShift, + "<<" => Operator.LeftShift, + "&" => Operator.AND, + "|" => Operator.OR, + "^" => Operator.XOR, + ">" => Operator.Greater, + "<" => Operator.Lower, + ">=" => Operator.GreaterOrEqual, + "<=" => Operator.LowerOrEqual, + "==" => Operator.Equals, + "!=" => Operator.NotEquals, + "&&" => Operator.LogicalAND, + "||" => Operator.LogicalOR, + _ => Operator.Nop, + }; + } + public static Operator ToOperator(this string s) + { + return s switch + { + "!" => Operator.Not, + "~" => Operator.BitwiseNot, + "++" => Operator.Inc, + "--" => Operator.Dec, + "+" => Operator.Plus, + "-" => Operator.Minus, + "*" => Operator.Mul, + "/" => Operator.Div, + "%" => Operator.Mod, + ">>" => Operator.RightShift, + "<<" => Operator.LeftShift, + "&" => Operator.AND, + "|" => Operator.OR, + "^" => Operator.XOR, + ">" => Operator.Greater, + "<" => Operator.Lower, + ">=" => Operator.GreaterOrEqual, + "<=" => Operator.LowerOrEqual, + "==" => Operator.Equals, + "!=" => Operator.NotEquals, + "&&" => Operator.LogicalAND, + "||" => Operator.LogicalOR, + _ => Operator.Nop, + }; + } + public static string ToSymbol(this Operator s) + { + return s switch + { + Operator.Not => "!", + Operator.BitwiseNot => "~", + Operator.Inc => "++", + Operator.Dec => "--", + Operator.Plus => "+", + Operator.Minus => "-", + Operator.Mul => "*", + Operator.Div => "/", + Operator.Mod => "%", + Operator.RightShift => ">>", + Operator.LeftShift => "<<", + Operator.AND => "&", + Operator.OR => "|", + Operator.XOR => "^", + Operator.Greater => ">", + Operator.Lower => "<", + Operator.GreaterOrEqual => ">=", + Operator.LowerOrEqual => "<=", + Operator.Equals => "==", + Operator.NotEquals => "!=", + Operator.LogicalAND => "&&", + Operator.LogicalOR => "||", + _ => "NOp" + }; + } + + public static Operator ToOperator(this char c) + { + return c switch + { + '!' => Operator.Not, + '~' => Operator.BitwiseNot, + '+' => Operator.Plus, + '-' => Operator.Minus, + '*' => Operator.Mul, + '/' => Operator.Div, + '%' => Operator.Mod, + '&' => Operator.AND, + '|' => Operator.OR, + '^' => Operator.XOR, + '>' => Operator.Greater, + '<' => Operator.Lower, + _ => Operator.Nop, + }; + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs new file mode 100644 index 0000000000..fa616c22d2 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -0,0 +1,74 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + + +public class ShaderFile(TextLocation info) : Node(info) +{ + public List RootClasses { get; set; } = []; + public List Namespaces { get; set; } = []; + + public override string ToString() + { + return $"{string.Join("\n", RootClasses)}\n\n{string.Join("\n", Namespaces)}"; + } +} + +public class ShaderNamespace(TextLocation info) : Node(info) +{ + public List NamespacePath { get; set; } = []; + public string? Namespace { get; set; } + public List ShaderClasses { get; set; } = []; + + public override string ToString() + { + return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", ShaderClasses)}End\n"; + } +} + +public class ShaderClass(Identifier name, TextLocation info) : Node(info) +{ + public Identifier Name { get; set; } = name; + public List Elements { get; set; } = []; + public ShaderParameterDeclarations? Generics { get; set; } + public List Mixins { get; set; } = []; + + + public override string ToString() + { + return +$""" +Class : {Name} +Generics : {string.Join(", ", Generics)} +Inherits from : {string.Join(", ", Mixins)} +Body : +{string.Join("\n", Elements)} +"""; + } +} + + +public class ShaderGenerics(Identifier typename, Identifier name, TextLocation info) : Node(info) +{ + public Identifier Name { get; set; } = name; + public Identifier TypeName { get; set; } = typename; +} + +public class ShaderMixin(Identifier name, TextLocation info) : Node(info) +{ + public Identifier Name { get; set; } = name; + public ShaderExpressionList? Generics { get; set; } + public override string ToString() + { + return $"{Name}<{Generics}>"; + } +} + +public abstract class ShaderMixinValue(TextLocation info) : Node(info); +public class ShaderMixinExpression(Expression expression, TextLocation info) : ShaderMixinValue(info) +{ + public Expression Value { get; set; } = expression; +} +public class ShaderMixinIdentifier(Identifier identifier, TextLocation info) : ShaderMixinValue(info) +{ + public Identifier Value { get; set; } = identifier; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs new file mode 100644 index 0000000000..6abe7478dd --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs @@ -0,0 +1,20 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public abstract class ShaderAttribute(TextLocation info) : Node(info); + +public class ResourceBind(int location, int space, TextLocation info) : ShaderAttribute(info) +{ + public int Location { get; set; } = location; + public int Space { get; set; } = space; + + public override string ToString() + { + return $"Bind({Location}, {Space})"; + } +} + +public class ColorType(TextLocation info) : ShaderAttribute(info) +{ + public override string ToString() => "COLOR"; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs new file mode 100644 index 0000000000..f84479390a --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -0,0 +1,61 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : ShaderElement(info) +{ + public bool IsStaged { get; set; } = isStaged; +} + + +public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null) : MethodOrMember(location, isStaged) +{ + public TypeName Type { get; set; } = type; + public Identifier Name { get; set; } = name; + public Identifier? Semantic { get; set; } = semantic; + public bool IsStream { get; set; } = isStream; + public Expression? Value { get; set; } = initialValue; + + public override string ToString() + { + return $"{Type} {Name}"; + } +} + +public class ShaderMethod(TypeName returnType, Identifier name, TextLocation info, Identifier? visibility = null, Identifier? storage = null, bool isStaged = false, bool isAbstract = false, bool isVirtual = false, bool isOverride = false, bool isClone = false) : MethodOrMember(info, isStaged) +{ + public TypeName ReturnType { get; set; } = returnType; + public Identifier Name { get; set; } = name; + public Identifier? Visibility { get; set; } = visibility; + public Identifier? Storage { get; set; } = storage; + public bool? IsAbstract { get; set; } = isAbstract; + public bool? IsVirtual { get; set; } = isVirtual; + public bool? IsOverride { get; set; } = isOverride; + public bool? IsClone { get; set; } = isClone; + public ShaderParameterDeclarations? ParameterList { get; set; } + public BlockStatement? Body { get; set; } + + public override string ToString() + { + return $"{ReturnType} {Name}()\n{Body}\n"; + } +} + +public record struct ShaderParameter(TypeName TypeName, Identifier Name); + + +public abstract class ParameterListNode(TextLocation info) : Node(info); + +public class ShaderParameterDeclarations(TextLocation info) : ParameterListNode(info) +{ + public List Parameters { get; set; } = []; +} + +public class ShaderExpressionList(TextLocation info) : ParameterListNode(info) +{ + public List Values { get; set; } = []; + + public override string ToString() + { + return string.Join(", ", Values); + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs new file mode 100644 index 0000000000..8229f07a58 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -0,0 +1,40 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public abstract class ShaderElement(TextLocation info) : Node(info); + +public abstract class ShaderBuffer(Identifier name, TextLocation info) : ShaderElement(info) +{ + public Identifier Name { get; set; } = name; +} + +public class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) +{ + public TypeName TypeName { get; set; } = typename; + public Identifier Name { get; set; } = identifier; + + public override string ToString() + { + return $"{TypeName} {Name}"; + } +} + +public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElement(info) +{ + public Identifier TypeName { get; set; } = typename; + public List Members { get; set; } = []; + + public override string ToString() + { + return $"struct {TypeName} ({string.Join(", ", Members)})"; + } +} + +public sealed class CBuffer(Identifier name, TextLocation info) : ShaderBuffer(name, info) +{ + public List Members { get; set; } = []; +} +public sealed class TBuffer(Identifier name, TextLocation info) : ShaderBuffer(name, info) +{ + public List Members { get; set; } = []; +} diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs new file mode 100644 index 0000000000..eafe78348b --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs @@ -0,0 +1,20 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public interface IGenericValue; +public abstract class ShaderGenericsValue(TextLocation info) : Node(info); + + +public class ValueTypeGenerics(ValueLiteral value,TextLocation info) : ShaderGenericsValue(info) +{ + public ValueLiteral Value { get; set; } = value; +} + +public class IdentifierGenerics(Identifier identifier, TextLocation info) : ShaderGenericsValue(info) +{ + public Identifier Identifier { get; set; } = identifier; +} +public class AccessorExpressionGenerics(AccessorExpression accessor, TextLocation info) : ShaderGenericsValue(info) +{ + public AccessorExpression Accessor { get; set; } = accessor.Accessed is Identifier ? accessor : throw new ArgumentException($"Value accessed should be a shader class or a variable name"); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs new file mode 100644 index 0000000000..78f09b5fd2 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs @@ -0,0 +1,44 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public abstract class Control(TextLocation info) : Flow(info); + + +public class ConditionalFlow(If first, TextLocation info) : Flow(info) +{ + public If If { get; set; } = first; + public List ElseIfs { get; set; } = []; + public Else? Else { get; set; } + + public override string ToString() + { + return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; + } +} +public class If(Expression condition, Statement body, TextLocation info) : Flow(info) +{ + public Expression Condition { get; set; } = condition; + public Statement Body { get; set; } = body; + + public override string ToString() + { + return $"if({Condition})\n{Body}"; + } +} + +public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) +{ + public override string ToString() + { + return $"else if({Condition}){Body}"; + } +} + +public class Else(Statement body, TextLocation info) : Flow(info) +{ + public Statement Body { get; set; } = body; + public override string ToString() + { + return $"else {Body}"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs new file mode 100644 index 0000000000..3d79084e36 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs @@ -0,0 +1,56 @@ +namespace Stride.Shaders.Parsing.SDSL.AST; + +public abstract class Flow(TextLocation info) : Statement(info); + +public abstract class Loop(TextLocation info) : Flow(info); +public class Break(TextLocation info) : Statement(info); +public class Continue(TextLocation info) : Statement(info); + + +public class ForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : Loop(info) +{ + public TypeName Typename { get; set; } = typename; + public Identifier Variable { get; set; } = variable; + public Expression Collection { get; set; } = collection; + public Statement Body { get; set; } = body; + + public override string ToString() + { + return $"foreach({Typename} {Variable} in {Collection})\n{Body}"; + } +} + + +public class While(Expression condition, Statement body, TextLocation info) : Loop(info) +{ + public Expression Condition { get; set; } = condition; + public Statement Body { get; set; } = body; + public override string ToString() + { + return $"while({Condition})\n{Body}"; + } +} + +public enum ForAnnotationKind +{ + Unroll, + Loop, + Fastopt, + AllowUAVCondition +} +public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); + +public class For(Statement initializer, Statement cond, Statement update, Statement body, TextLocation info) : Loop(info) +{ + public Statement Initializer { get; set; } = initializer; + public Statement Condition { get; set; } = cond; + public Statement Update { get; set; } = update; + public Statement Body { get; set; } = body; + public List Annotations { get; set; } = []; + + public override string ToString() + { + return $"for({Initializer} {Condition} {Update})\n{Body}"; + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs new file mode 100644 index 0000000000..3fb272804b --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -0,0 +1,82 @@ +using System.Text; + +namespace Stride.Shaders.Parsing.SDSL.AST; + +public abstract class Statement(TextLocation info) : ValueNode(info); + +public class EmptyStatement(TextLocation info) : Statement(info) +{ + public override string ToString() => ";"; +} + +public class ExpressionStatement(Expression expression, TextLocation info) : Statement(info) +{ + public Expression Expression { get; set; } = expression; + public override string ToString() + { + return $"{Expression};"; + } +} + +public class Return(TextLocation info, Expression? expression = null) : Statement(info) +{ + public Expression? Value { get; set; } = expression; + + public override string ToString() + { + return $"return {Value};"; + } +} + +public abstract class Declaration(TypeName typename, TextLocation info) : Statement(info) +{ + public TypeName TypeName { get; set; } = typename; +} + +public class VariableAssign(Identifier name, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +{ + public Identifier Name { get; set; } = name; + public AssignOperator? Operator { get; set; } = op; + public Expression? Value { get; set; } = value; + + public override string ToString() + => Value switch + { + null => Name.Name, + Expression v => $"{Name} = {v}" + }; +} + +public class Declare(TypeName typename, TextLocation info) : Declaration(typename, info) +{ + public List Variables { get; set; } = []; + + public override string ToString() + { + return $"{TypeName} {string.Join(", ", Variables.Select(v => v.ToString()))}"; + } +} + +public class Assign(TextLocation info) : Statement(info) +{ + public List Variables { get; set; } = []; + public override string ToString() + { + return string.Join(", ", Variables.Select(x => x.ToString())) + ";"; + } +} + + + +public class BlockStatement(TextLocation info) : Statement(info) +{ + public List Statements { get; set; } = []; + + public override string ToString() + { + var builder = new StringBuilder().Append("Block : \n"); + foreach (var e in Statements) + builder.AppendLine(e.ToString()); + return builder.AppendLine("End").ToString(); + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Grammar.cs b/src/Stride.Shaders.Parsing/SDSL/Grammar.cs new file mode 100644 index 0000000000..3df059b5d1 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Grammar.cs @@ -0,0 +1,53 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public static class Grammar +{ + public static ParseResult Match(string code, TParser? parser = null) + where TValue : Node + where TParser : struct, IParser + { + var p = parser ?? new TParser(); + var scanner = new Scanner(code); + var result = new ParseResult(); + if (p.Match(ref scanner, result, out var fnum)) + result.AST = fnum; + if(!Terminals.EOF(ref scanner)) + result.Errors.Add(new("Expected end of file", scanner.CreateError(scanner.Position))); + return result; + } + + public static ParseResult Match(TScannable code, TParser? parser = null) + where TScannable : IScannableCode + where TValue : Node + where TParser : struct, IParser + { + var p = parser ?? new TParser(); + var scanner = new Scanner(code); + + var result = new ParseResult(); + if (p.Match(ref scanner, result, out var fnum)) + result.AST = fnum; + if(!Terminals.EOF(ref scanner)) + result.Errors.Add(new("Expected end of file", scanner.CreateError(scanner.Position))); + return result; + } + + + public static ParseResult MatchTyped(string code, TParser? parser = null) + where TValue : Node + where TParser : struct, IParser + { + var result = Match(code, parser); + if (result.AST is TValue r) + { + return new ParseResult() + { + AST = r, + Errors = result.Errors + }; + } + else return null!; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/IParser.cs b/src/Stride.Shaders.Parsing/SDSL/IParser.cs new file mode 100644 index 0000000000..3fe16c2a87 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/IParser.cs @@ -0,0 +1,12 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public interface IParser; + +public interface IParser + where TResult : Node +{ + public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/ParseResult.cs b/src/Stride.Shaders.Parsing/SDSL/ParseResult.cs new file mode 100644 index 0000000000..412dbbf749 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/ParseResult.cs @@ -0,0 +1,21 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct ParseError(string Message, ErrorLocation Location) +{ + public override readonly string ToString() + { + return $"{Message} at : {Location}"; + } +} + + +public class ParseResult + where T : Node +{ + public T? AST { get; set; } + public List Errors { get; internal set; } = []; +} +public class ParseResult : ParseResult; \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs new file mode 100644 index 0000000000..1d9baa7a13 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -0,0 +1,205 @@ +using System.Security.Cryptography; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + + +public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result) + where TScanner : struct, IScanner; +public delegate bool ParserValueDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, ParseError? orError = null) + where TScanner : struct, IScanner; +public delegate bool ParserOptionalValueDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, ParseError? orError = null) + where TScanner : struct, IScanner; + +public static class CommonParsers +{ + public static bool Exit(ref TScanner scanner, ParseResult result, out TNode parsed, int beginningPosition, in ParseError? orError = null) + where TScanner : struct, IScanner + where TNode : class + { + if (orError is not null) + { + result.Errors.Add(orError.Value); + scanner.Position = scanner.End; + parsed = null!; + return false; + } + if (result.Errors.Count == 0) + scanner.Position = beginningPosition; + parsed = null!; + return false; + } + + public static bool Spaces0(ref TScanner scanner, ParseResult result, out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) + where TScanner : struct, IScanner + => new Space0(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); + public static bool Spaces1(ref TScanner scanner, ParseResult result, out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) + where TScanner : struct, IScanner + => new Space1(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); + + + public static bool Optional(ref TScanner scanner, TTerminal terminal, bool advance = false) + where TScanner : struct, IScanner + where TTerminal : struct, ITerminal + { + terminal.Match(ref scanner, advance: advance); + return true; + } + public static bool Optional(ref TScanner scanner, IParser parser, ParseResult result, out TNode? node) + where TScanner : struct, IScanner + where TNode : Node + { + parser.Match(ref scanner, result, out node); + return true; + } + + public static bool FollowedBy(ref TScanner scanner, TTerminal terminal, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + where TTerminal : struct, ITerminal + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (terminal.Match(ref scanner, advance: advance)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } + public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (func.Invoke(ref scanner, result)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } + public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (func.Invoke(ref scanner, result, out parsed)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } + + public static bool Until(ref TScanner scanner, char value, bool advance = false) + where TScanner : struct, IScanner + { + while (!scanner.IsEof && !Terminals.Char(value, ref scanner, advance)) + scanner.Advance(1); + return scanner.IsEof; + } + public static bool Until(ref TScanner scanner, string value, bool advance = false) + where TScanner : struct, IScanner + { + while (!scanner.IsEof && !Terminals.Literal(value, ref scanner, advance)) + scanner.Advance(1); + return scanner.IsEof; + } + public static bool Until(ref TScanner scanner, ReadOnlySpan values, bool advance = false) + where TScanner : struct, IScanner + { + while (!scanner.IsEof) + { + foreach (var value in values) + if (Terminals.Literal(value, ref scanner, advance)) + return scanner.IsEof; + scanner.Advance(1); + } + return scanner.IsEof; + } + public static bool Until(ref Scanner scanner, bool advance = false) + where TScanner : struct, IScanner + where TTerminal : struct, ITerminal + { + var t = new TTerminal(); + while (!scanner.IsEof && !t.Match(ref scanner, advance)) + scanner.Advance(1); + return !scanner.IsEof; + } + public static bool Until(ref Scanner scanner, TTerminal1? terminal1 = null, TTerminal2? terminal2 = null, bool advance = false) + where TScanner : struct, IScanner + where TTerminal1 : struct, ITerminal + where TTerminal2 : struct, ITerminal + { + var t1 = terminal1 ?? new TTerminal1(); + var t2 = terminal2 ?? new TTerminal2(); + while (!scanner.IsEof && !(t1.Match(ref scanner, advance) || t2.Match(ref scanner, advance))) + scanner.Advance(1); + return !scanner.IsEof; + } + public static bool Until(ref Scanner scanner, TTerminal1? terminal1 = null, TTerminal2? terminal2 = null, TTerminal3? terminal3 = null, bool advance = false) + where TScanner : struct, IScanner + where TTerminal1 : struct, ITerminal + where TTerminal2 : struct, ITerminal + where TTerminal3 : struct, ITerminal + { + var t1 = terminal1 ?? new TTerminal1(); + var t2 = terminal2 ?? new TTerminal2(); + var t3 = terminal3 ?? new TTerminal3(); + while (!scanner.IsEof && !(t1.Match(ref scanner, advance) || t2.Match(ref scanner, advance) || t3.Match(ref scanner, advance))) + scanner.Advance(1); + return !scanner.IsEof; + } + + + public static bool Repeat(ref TScanner scanner, TParser parser, ParseResult result, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + where TScanner : struct, IScanner + where TParser : struct, IParser + where TNode : Node + { + return Repeat(ref scanner, (ref TScanner s, ParseResult r, out TNode node, ParseError? orError) => new TParser().Match(ref s, r, out node, orError), result, out nodes, minimum, withSpaces, separator, orError); + } + public static bool Repeat(ref TScanner scanner, ParserValueDelegate parser, ParseResult result, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + where TScanner : struct, IScanner + where TNode : Node + { + var position = scanner.Position; + nodes = []; + while (!scanner.IsEof) + { + if (parser.Invoke(ref scanner, result, out var node)) + { + nodes.Add(node); + if (withSpaces) + Spaces0(ref scanner, result, out _); + } + else break; + + if (separator is not null) + { + if (Terminals.Literal(separator, ref scanner, advance: true)) + { + if (withSpaces) + Spaces0(ref scanner, result, out _); + } + else if(nodes.Count >= minimum) + return true; + else Exit(ref scanner, result, out nodes, position, orError); + } + else Exit(ref scanner, result, out nodes, position, orError); + } + if (nodes.Count >= minimum) + return true; + else return Exit(ref scanner, result, out nodes, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Spaces.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Spaces.cs new file mode 100644 index 0000000000..68166be99c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Spaces.cs @@ -0,0 +1,60 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct Space0(bool OnlyWhiteSpace) : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out NoNode parsed, in ParseError? error = null!) + where TScanner : struct, IScanner + { + parsed = null!; + if (!OnlyWhiteSpace) + { + while (char.IsWhiteSpace((char)scanner.Peek())) + scanner.Advance(1); + return true; + } + else + { + while (scanner.Peek() == ' ') + scanner.Advance(1); + return true; + } + } +} + +public record struct Space1(bool OnlyWhiteSpace) : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out NoNode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + if (!OnlyWhiteSpace) + { + if (!char.IsWhiteSpace((char)scanner.Peek())) + { + if (orError != null) + result.Errors.Add(orError.Value); + return false; + + } + while (char.IsWhiteSpace((char)scanner.Peek())) + scanner.Advance(1); + return true; + } + else + { + if (!(scanner.Peek() == ' ')) + { + if (orError != null) + result.Errors.Add(orError.Value); + return false; + + } + while (scanner.Peek() == ' ') + scanner.Advance(1); + return true; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs new file mode 100644 index 0000000000..d8aa841b66 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -0,0 +1,613 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public struct DirectiveExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (Or(ref scanner, result, out parsed)) + return true; + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + return false; + } + } + + public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveExpressionParser().Match(ref scanner, result, out parsed, in orError); + public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveAdditionParser().Match(ref scanner, result, out parsed, in orError); + public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveMultiplicationParser().Match(ref scanner, result, out parsed, in orError); + public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveBitwiseShiftParser().Match(ref scanner, result, out parsed, in orError); + public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveRelationalParser().Match(ref scanner, result, out parsed, in orError); + public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveEqualityParser().Match(ref scanner, result, out parsed, in orError); + public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveBitwiseAndParser().Match(ref scanner, result, out parsed, in orError); + public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveBitwiseOrParser().Match(ref scanner, result, out parsed, in orError); + public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveBitwiseXOrParser().Match(ref scanner, result, out parsed, in orError); + public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveAndParser().Match(ref scanner, result, out parsed, in orError); + public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveOrParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct DirectiveTernaryParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (DirectiveExpressionParser.Or(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if ( + Terminals.Char('?', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(':', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.CreateError(scanner.Position))) + ) + { + parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveOrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.And(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Literal("||", ref scanner)) + { + var op = scanner.Slice(scanner.Position, 2).ToOperator(); + scanner.Advance(2); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Or(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.And(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveAndParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.BOr(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Literal("&&", ref scanner)) + { + var op = scanner.Slice(scanner.Position, 2).ToOperator(); + scanner.Advance(2); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.BAnd(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.BOr(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + + + +public record struct DirectiveBitwiseOrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.XOr(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (!Terminals.Literal("||", ref scanner) && Terminals.Char('|', ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.BOr(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.XOr(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} +public record struct DirectiveBitwiseXOrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.BAnd(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Char('^', ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.XOr(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.BAnd(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} +public record struct DirectiveBitwiseAndParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Equality(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (!Terminals.Literal("&&", ref scanner) && Terminals.Char('&', ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.BAnd(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Equality(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + + + +public record struct DirectiveEqualityParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Relation(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Literal("==", ref scanner) || Terminals.Literal("!=", ref scanner)) + { + var op = scanner.Slice(scanner.Position, 2).ToOperator(); + scanner.Advance(2); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Equality(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Relation(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveRelationalParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Shift(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + !Terminals.Literal(">=", ref scanner) && Terminals.Literal(">", ref scanner) + || !Terminals.Literal("<=", ref scanner) && Terminals.Literal("<", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Relation(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Shift(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else if (Terminals.Literal(">=", ref scanner) || Terminals.Literal("<=", ref scanner)) + { + var op = scanner.Slice(scanner.Position, 2).ToOperator(); + scanner.Advance(2); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Relation(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Shift(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveBitwiseShiftParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Add(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Literal(">>", ref scanner) || Terminals.Literal("<<", ref scanner)) + { + var op = scanner.Slice(scanner.Position, 2).ToOperator(); + scanner.Advance(2); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Shift(ref scanner, result, out var shift)) + { + parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Add(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveAdditionParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Mul(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Set("+-", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveExpressionParser.Add(ref scanner, result, out var add)) + { + parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveExpressionParser.Mul(ref scanner, result, out var mul)) + { + parsed = new BinaryExpression(left, op, mul, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveMultiplicationParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + parsed = null!; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var left)) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Terminals.Set("*/%", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + + if (DirectiveExpressionParser.Mul(ref scanner, result, out var expression)) + { + parsed = new BinaryExpression(left, op, expression, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var right)) + { + parsed = new BinaryExpression(left, op, right, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + scanner.Position = position; + return false; + } + else + { + parsed = left; + return true; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs new file mode 100644 index 0000000000..ac545c8985 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -0,0 +1,458 @@ +using Microsoft.VisualBasic; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public record struct PreprocessorParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out PreProcessableCode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + var p = new PreProcessableCode(new()); + while (!scanner.IsEof && DirectiveStatementParsers.Statement(ref scanner, result, out var statement)) + p.Snippets.Add(statement); + p.Info = scanner.GetLocation(position, scanner.Position - position); + parsed = p; + return true; + } + + public static bool PreCode(ref TScanner scanner, ParseResult result, out PreProcessableCode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PreprocessorParser().Match(ref scanner, result, out parsed, orError); +} + +public record struct DirectiveStatementParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out DirectiveStatement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + if (Conditional(ref scanner, result, out var conditional)) + { + parsed = conditional; + return true; + } + else if(Define(ref scanner, result, out var obj)) + { + parsed = obj; + return true; + } + else if (DefineFunc(ref scanner, result, out var func)) + { + parsed = func; + return true; + } + else if (Code(ref scanner, result, out var code)) + { + parsed = code; + return true; + } + else return false; + } + + public static bool AnyIf(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (If(ref scanner, result, out var ifDirective)) + { + parsed = ifDirective; + return true; + } + else if (IfDef(ref scanner, result, out var ifdefDirective)) + { + parsed = ifdefDirective; + return true; + } + else if (IfNDef(ref scanner, result, out var ifndefDirective)) + { + parsed = ifndefDirective; + return true; + } + parsed = null!; + return false; + } + public static bool Define(ref TScanner scanner, ParseResult result, out ObjectDefineDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ObjectDefineDirectiveParser().Match(ref scanner, result, out parsed, orError); + public static bool DefineFunc(ref TScanner scanner, ParseResult result, out FunctionDefineDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new FunctionDefineDirectiveParser().Match(ref scanner, result, out parsed, orError); + public static bool If(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalIfDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool IfDef(ref TScanner scanner, ParseResult result, out IfDefDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalIfDefDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool IfNDef(ref TScanner scanner, ParseResult result, out IfNDefDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalIfNDefDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool Elif(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalElifDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool Endif(ref TScanner scanner, ParseResult result, in ParseError? orError = null) + where TScanner : struct, IScanner + => new EndifDirectiveParser().Match(ref scanner, result, out _, orError); + public static bool Code(ref TScanner scanner, ParseResult result, out DirectiveCode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveCodeParser().Match(ref scanner, result, out parsed, orError); + public static bool Else(ref TScanner scanner, ParseResult result, out ElseDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalElseDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool Conditional(ref TScanner scanner, ParseResult result, out ConditionalDirectives parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ConditionalDirectivesParser().Match(ref scanner, result, out parsed, orError); + public static bool Statement(ref TScanner scanner, ParseResult result, out DirectiveStatement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveStatementParsers().Match(ref scanner, result, out parsed, orError); +} + +public struct ConditionalDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalDirectives parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + if (DirectiveStatementParsers.AnyIf(ref scanner, result, out var ifDirective, orError)) + { + if (PreprocessorParser.PreCode(ref scanner, result, out var c)) + ifDirective.Code = c; + + var elifDirectives = new List(); + while (DirectiveStatementParsers.Elif(ref scanner, result, out var elifDirective, orError)) + { + elifDirectives.Add((ElifDirective)elifDirective); + if (PreprocessorParser.PreCode(ref scanner, result, out c)) + elifDirective.Code = c; + } + + if (DirectiveStatementParsers.Else(ref scanner, result, out var elseDirective, orError)) + if (PreprocessorParser.PreCode(ref scanner, result, out c)) + elseDirective.Code = c; + + if (DirectiveStatementParsers.Endif(ref scanner, result, orError)) + { + parsed = new ConditionalDirectives(ifDirective, scanner.GetLocation(position, scanner.Position - position)) + { + Elifs = elifDirectives, + Else = elseDirective + }; + return true; + } + else + { + parsed = null!; + return false; + } + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + +public record struct DirectiveCodeParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out DirectiveCode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + var beginningOfLine = scanner.Position; + int lineCount = 0; + while ( + !( + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && ( + Terminals.Literal("#if", ref scanner) + || Terminals.Literal("#define", ref scanner) + || Terminals.Literal("#endif", ref scanner) + || Terminals.Literal("#elif", ref scanner) + ) + ) + && !scanner.IsEof + ) + { + CommonParsers.Until(ref scanner, '\n', advance: true); + beginningOfLine = scanner.Position; + lineCount += 1; + } + if (lineCount > 0) + { + scanner.Position = beginningOfLine; + parsed = new DirectiveCode(scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + +public record struct ConditionalIfDefDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDefDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + Terminals.Literal("#ifdef", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new("missing space", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var id, new("needs identifier", scanner.CreateError(scanner.Position))) + && Terminals.EOL(ref scanner, advance: true) + ) + { + var cond = new IfDefDirective(id, scanner.GetLocation(position, scanner.Position - position)); + parsed = cond; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} +public record struct ConditionalIfNDefDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out IfNDefDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + Terminals.Literal("#ifndef", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + && LiteralsParser.Identifier(ref scanner, result, out var id) + && Terminals.EOL(ref scanner, advance: true) + ) + { + var cond = new IfNDefDirective(id, scanner.GetLocation(position, scanner.Position - position)); + parsed = cond; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + +public record struct ConditionalIfDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + Terminals.Literal("#if", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + && DirectiveExpressionParser.Expression(ref scanner, result, out var expression) + && Terminals.EOL(ref scanner, advance: true) + ) + { + var cond = new IfDirective(expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = cond; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + + +public record struct ConditionalElifDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + Terminals.Literal("#elif", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + && DirectiveExpressionParser.Expression(ref scanner, result, out var expression) + && Terminals.EOL(ref scanner, advance: true) + ) + { + var cond = new ElifDirective(expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = cond; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} +public record struct ConditionalElseDirectivesParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if ( + Terminals.Literal("#else", ref scanner, advance: true) + && Terminals.EOL(ref scanner, advance: true) + ) + { + var cond = new ElseDirective(scanner.GetLocation(position, scanner.Position - position)); + parsed = cond; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + +public record struct EndifDirectiveParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out NoNode parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + + if ( + Terminals.Literal("#endif", ref scanner, advance: true) + && Terminals.EOL(ref scanner, advance: true) + ) + { + parsed = null!; + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + + +public record struct ObjectDefineDirectiveParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ObjectDefineDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + + if ( + Terminals.Literal("#define", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + ) + { + if ( + DirectiveExpressionParser.Expression(ref scanner, result, out var expression) + && Terminals.EOL(ref scanner, advance: true) + ) + { + parsed = new(identifier, expression, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if(Terminals.EOL(ref scanner, advance: true)) + { + parsed = new(identifier, null, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} + + +public record struct FunctionDefineDirectiveParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out FunctionDefineDirective parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + + if ( + Terminals.Literal("#define", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && Terminals.Char('(', ref scanner, advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + var func = new FunctionDefineDirective(identifier, "", new()); + + if ( + LiteralsParser.Identifier(ref scanner, result, out var param) + && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + ) + func.Parameters.Add(param); + while( + Terminals.Char(',', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && LiteralsParser.Identifier(ref scanner, result, out param) + && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + + ) + func.Parameters.Add(param); + if(!Terminals.Char(')', ref scanner, advance: true)) + { + result.Errors.Add(new("Parenthesis needs to be closed", scanner.CreateError(scanner.Position))); + scanner.Position = position; + parsed = null!; + return false; + } + else + { + var startPattern = scanner.Position; + while(!(scanner.IsEof || Terminals.Char('\n', ref scanner) || Terminals.Literal("\r\n", ref scanner))) + scanner.Advance(1); + func.Pattern = scanner.Memory[startPattern..scanner.Position].TrimEnd().TrimStart().ToString(); + if(!Terminals.Char('\n', ref scanner, advance: true)) + Terminals.Literal("\r\n", ref scanner, advance: true); + parsed = func; + return true; + } + } + else + { + scanner.Position = position; + parsed = null!; + return false; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs new file mode 100644 index 0000000000..5252553678 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -0,0 +1,92 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct DirectivePrimaryParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (Parenthesis(ref scanner, result, out parsed)) + return true; + else if (LiteralsParser.Identifier(ref scanner, result, out var lit)) + { + parsed = lit; + return true; + } + else if (LiteralsParser.Integer(ref scanner, result, out var integer)) + { + parsed = integer; + return true; + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + return false; + } + } + public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePrimaryParsers().Match(ref scanner, result, out parsed, in orError); + public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier parsed) + where TScanner : struct, IScanner + => new IdentifierParser().Match(ref scanner, result, out parsed); + public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveParenthesisExpressionParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct DirectiveParenthesisExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.CreateError(position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(')', ref scanner, advance: true) + ) + return true; + else + { + if (orError != null) + result.Errors.Add(orError.Value); + parsed = null!; + scanner.Position = position; + return false; + } + } +} + +public record struct DirectiveMethodCallParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + ParameterParsers.Values(ref scanner, result, out var parameters); + var pos2 = scanner.Position; + if (Terminals.Char(')', ref scanner, advance: true)) + { + parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + } + + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs new file mode 100644 index 0000000000..20bf7c9384 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs @@ -0,0 +1,196 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public record struct DirectivePostfixParser : IParser +{ + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + // If the following + if ( + Accessor(ref scanner, result, out parsed) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Set("[.", ref scanner) || Terminals.Literal("++", ref scanner) || Terminals.Literal("--", ref scanner)) + { + if (Terminals.Char('.', ref scanner, advance: true)) + { + if (Postfix(ref scanner, result, out var accessed)) + { + parsed = new AccessorExpression(parsed, accessed, scanner.GetLocation(position, scanner.Position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + } + else if (Terminals.Char('[', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if ( + ExpressionParser.Expression(ref scanner, result, out var index) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + { + parsed = new IndexerExpression(parsed, index, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = position; + return false; + } + } + else if (Terminals.Literal("++", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (Terminals.Literal("--", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + result.Errors.Add(new("Expected Postfix expression", scanner.CreateError(position))); + return false; + } + } + else return true; + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + return false; + } + } + public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePostfixParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePostfixIncrementParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePostfixAccessorParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePostfixIndexerParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct DirectivePostfixAccessorParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (PostfixParser.Indexer(ref scanner, result, out var expression)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if ( + Terminals.Char('.', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.CreateError(scanner.Position)))) + { + parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + parsed = expression; + return true; + } + } + if (orError is not null) + result.Errors.Add(orError.Value); + parsed = null!; + return false; + } +} + +public record struct DirectivePostfixIndexerParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + if (PrimaryParsers.Primary(ref scanner, result, out var expression)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('[', ref scanner, advance: true)) + { + if ( + CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + { + parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + result.Errors.Add(new("Expected accessor parser", scanner.CreateError(position))); + parsed = null!; + return false; + } + } + else + { + scanner.Position = pos2; + parsed = expression; + return true; + } + } + if (orError is not null) + result.Errors.Add(orError.Value); + parsed = null!; + return false; + } +} + +public record struct DirectivePostfixIncrementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if(PostfixParser.Accessor(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if(Terminals.Literal("++", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + return true; + } + } + if (orError is not null) + result.Errors.Add(orError.Value); + parsed = null!; + return false; + } +} + + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs new file mode 100644 index 0000000000..6ec1f723ed --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -0,0 +1,185 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct DirectivePrefixParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (DirectiveUnaryParsers.PrefixIncrement(ref scanner, result, out parsed)) + return true; + else if (DirectiveUnaryParsers.Signed(ref scanner, result, out parsed)) + return true; + // prefix not + else if (DirectiveUnaryParsers.Not(ref scanner, result, out parsed)) + return true; + // prefix cast + else if (DirectiveUnaryParsers.Cast(ref scanner, result, out parsed)) + return true; + else if (DirectiveUnaryParsers.Primary(ref scanner, result, out var p)) + { + parsed = p; + return true; + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + parsed = null!; + scanner.Position = position; + return false; + } + } +} + +public record struct DirectivePrefixIncrementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("++", ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + parsed = null!; + scanner.Position = position; + result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + return false; + } + } + // prefix decrememnt + else if (Terminals.Literal("--", ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + parsed = null!; + scanner.Position = position; + result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + return false; + } + } + else + { + if(orError is not null) + result.Errors.Add(orError.Value); + scanner.Position = position; + parsed = null!; + return false; + } + } +} + +public record struct DirectiveNotExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if (Terminals.Set("!~", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _); + if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + parsed = null!; + scanner.Position = position; + result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + return false; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + return false; + } + } +} + +public record struct DirectiveSignExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if (Terminals.Set("+-", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _); + if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + // TODO: check if error can be added here + if (orError is not null) + result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + parsed = null!; + scanner.Position = position; + return false; + } + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + return false; + } + } +} + +public record struct DirectiveCastExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(')', ref scanner, true) + && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) + ) + { + parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + parsed = null!; + scanner.Position = position; + return false; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs new file mode 100644 index 0000000000..aa5f4aa6e5 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs @@ -0,0 +1,26 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct DirectiveUnaryParsers +{ + internal static bool Not(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveNotExpressionParser().Match(ref scanner, result, out cast, in orError); + internal static bool Signed(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveSignExpressionParser().Match(ref scanner, result, out cast, in orError); + internal static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePrefixIncrementParser().Match(ref scanner, result, out cast, in orError); + internal static bool Cast(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectiveCastExpressionParser().Match(ref scanner, result, out cast, in orError); + public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePrefixParser().Match(ref scanner, result, out prefix, in orError); + public static bool Primary(ref TScanner scanner, ParseResult result, out Expression postfix, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DirectivePrimaryParsers().Match(ref scanner, result, out postfix, in orError); +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs new file mode 100644 index 0000000000..a71d252852 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -0,0 +1,401 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public struct ExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Ternary(ref scanner, result, out parsed)) + return true; + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ExpressionParser().Match(ref scanner, result, out parsed, in orError); + public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new AdditionParser().Match(ref scanner, result, out parsed, in orError); + public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new MultiplicationParser().Match(ref scanner, result, out parsed, in orError); + public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BitwiseShiftParser().Match(ref scanner, result, out parsed, in orError); + public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new RelationalParser().Match(ref scanner, result, out parsed, in orError); + public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new EqualityParser().Match(ref scanner, result, out parsed, in orError); + public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BitwiseAndParser().Match(ref scanner, result, out parsed, in orError); + public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BitwiseOrParser().Match(ref scanner, result, out parsed, in orError); + public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BitwiseXOrParser().Match(ref scanner, result, out parsed, in orError); + public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new AndParser().Match(ref scanner, result, out parsed, in orError); + public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new OrParser().Match(ref scanner, result, out parsed, in orError); + public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new TernaryParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct TernaryParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (ExpressionParser.Or(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('?', ref scanner, advance: true)) + { + + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.CreateError(scanner.Position)))) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(':', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.CreateError(scanner.Position)))) + { + parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + } + } + } + else + { + scanner.Position = pos2; + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct OrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.And(ref scanner, result, out var and)) + parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AndExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.And(ref scanner, result, out var and)) + parsed = and; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.AnyOf(["||"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct AndParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.BOr(ref scanner, result, out var bOr)) + parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseOrExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.BOr(ref scanner, result, out var bOr)) + parsed = bOr; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.AnyOf(["&&"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct BitwiseOrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.XOr(ref scanner, result, out var xor)) + parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting XorExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.XOr(ref scanner, result, out var xor)) + parsed = xor; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (!Terminals.Literal("||", ref scanner) && Terminals.AnyOf(["|"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} +public record struct BitwiseXOrParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) + parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseAndExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) + parsed = bAnd; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.AnyOf(["^"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} +public record struct BitwiseAndParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.Equality(ref scanner, result, out var eq)) + parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting EqualityExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.Equality(ref scanner, result, out var eq)) + parsed = eq; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (!Terminals.Literal("&&", ref scanner) && Terminals.AnyOf(["&"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + + +public record struct EqualityParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.Relation(ref scanner, result, out var rel)) + parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting RelationExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.Relation(ref scanner, result, out var rel)) + parsed = rel; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.AnyOf(["==", "!="], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct RelationalParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.Shift(ref scanner, result, out var shift)) + parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting ShiftExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.Shift(ref scanner, result, out var shift)) + parsed = shift; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (!Terminals.AnyOf(["<=", ">="], ref scanner, out _) && Terminals.AnyOf([">", "<"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct BitwiseShiftParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + string op = ""; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != "" && parsed is not null) + { + if (ExpressionParser.Add(ref scanner, result, out var add)) + parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AddExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == "") + { + if (ExpressionParser.Add(ref scanner, result, out var add)) + parsed = add; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.AnyOf([">>", "<<"], ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct AdditionParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + char op = '\0'; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != '\0' && parsed is not null) + { + if (ExpressionParser.Mul(ref scanner, result, out var mul)) + parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == '\0') + { + if (ExpressionParser.Mul(ref scanner, result, out var mul)) + parsed = mul; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.Set("+-", ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct MultiplicationParser() : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + char op = '\0'; + parsed = null!; + var position = scanner.Position; + do + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (op != '\0' && parsed is not null) + { + if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) + parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.CreateError(scanner.Position))); + } + else if (parsed is null && op == '\0') + { + if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) + parsed = prefix; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + while (Terminals.Set("*/%", ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs new file mode 100644 index 0000000000..743bf2856f --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -0,0 +1,83 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct PrimaryParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (Parenthesis(ref scanner, result, out parsed)) + return true; + else if (Method(ref scanner, result, out parsed)) + return true; + else if (LiteralsParser.Literal(ref scanner, result, out var lit)) + { + parsed = lit; + return true; + } + else + { + if (orError is not null) + result.Errors.Add(orError.Value); + return false; + } + } + public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PrimaryParsers().Match(ref scanner, result, out parsed, in orError); + public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier parsed) + where TScanner : struct, IScanner + => new IdentifierParser().Match(ref scanner, result, out parsed); + public static bool Method(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new MethodCallParser().Match(ref scanner, result, out parsed, in orError); + public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ParenthesisExpressionParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct ParenthesisExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.CreateError(position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(')', ref scanner, advance: true) + ) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct MethodCallParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + ) + { + ParameterParsers.Values(ref scanner, result, out var parameters); + CommonParsers.Spaces0(ref scanner, result, out _); + if(Terminals.Char(')', ref scanner, advance: true)) + { + parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs new file mode 100644 index 0000000000..05de4b8189 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -0,0 +1,165 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public record struct PostfixParser : IParser +{ + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + // If the following + if ( + Accessor(ref scanner, result, out parsed) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Set("[.", ref scanner) || Terminals.Literal("++", ref scanner) || Terminals.Literal("--", ref scanner)) + { + if (Terminals.Char('.', ref scanner, advance: true)) + { + if (Postfix(ref scanner, result, out var accessed)) + { + parsed = new AccessorExpression(parsed, accessed, scanner.GetLocation(position, scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + else if (Terminals.Char('[', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if ( + ExpressionParser.Expression(ref scanner, result, out var index) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + { + parsed = new IndexerExpression(parsed, index, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + } + else if (Terminals.Literal("++", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else if (Terminals.Literal("--", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Postfix expression", scanner.CreateError(position))); + + } + else return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixIncrementParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixAccessorParser().Match(ref scanner, result, out parsed, in orError); + internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixIndexerParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct PostfixAccessorParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (PostfixParser.Indexer(ref scanner, result, out var expression)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if ( + Terminals.Char('.', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.CreateError(scanner.Position)))) + { + parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + parsed = expression; + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct PostfixIndexerParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + if (PrimaryParsers.Primary(ref scanner, result, out var expression)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('[', ref scanner, advance: true)) + { + if ( + CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + { + parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected accessor parser", scanner.CreateError(position))); + + } + else + { + scanner.Position = pos2; + parsed = expression; + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct PostfixIncrementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (PostfixParser.Accessor(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Literal("++", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs new file mode 100644 index 0000000000..6aeca13661 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -0,0 +1,129 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct PrefixParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (UnaryParsers.PrefixIncrement(ref scanner, result, out parsed)) + return true; + else if (UnaryParsers.Signed(ref scanner, result, out parsed)) + return true; + // prefix not + else if (UnaryParsers.Not(ref scanner, result, out parsed)) + return true; + // prefix cast + else if (UnaryParsers.Cast(ref scanner, result, out parsed)) + return true; + else if (UnaryParsers.Postfix(ref scanner, result, out var p)) + { + parsed = p; + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct PrefixIncrementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("++", ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (UnaryParsers.Postfix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + } + // prefix decrememnt + else if (Terminals.Literal("--", ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (UnaryParsers.Postfix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct NotExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if (Terminals.Set("!~", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _); + if (UnaryParsers.Postfix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct SignExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Set("+-", ref scanner)) + { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); + CommonParsers.Spaces0(ref scanner, result, out _); + if (UnaryParsers.Prefix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct CastExpressionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(')', ref scanner, true) + && UnaryParsers.Postfix(ref scanner, result, out var lit) + ) + { + parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs new file mode 100644 index 0000000000..364edeb3bf --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs @@ -0,0 +1,26 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct UnaryParsers +{ + internal static bool Not(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new NotExpressionParser().Match(ref scanner, result, out cast, in orError); + internal static bool Signed(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new SignExpressionParser().Match(ref scanner, result, out cast, in orError); + internal static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PrefixIncrementParser().Match(ref scanner, result, out cast, in orError); + internal static bool Cast(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + where TScanner : struct, IScanner + => new CastExpressionParser().Match(ref scanner, result, out cast, in orError); + public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PrefixParser().Match(ref scanner, result, out prefix, in orError); + public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression postfix, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixParser().Match(ref scanner, result, out postfix, in orError); +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs new file mode 100644 index 0000000000..3fc229d36c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -0,0 +1,335 @@ +using System.Collections.Frozen; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public interface ILiteralParser +{ + public bool Match(ref TScanner scanner, ParseResult result, out TResult literal, in ParseError? error = null) + where TScanner : struct, IScanner; +} + +public record struct LiteralsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Vector(ref scanner, result, out var v, orError)) + { + literal = v; + return true; + } + else if (Matrix(ref scanner, result, out var m, orError)) + { + literal = m; + return true; + } + else if (Identifier(ref scanner, result, out var i, orError)) + { + literal = i; + return true; + } + else if (Number(ref scanner, result, out var n, orError)) + { + literal = n; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out literal, position, orError); + } + public static bool Literal(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) + where TScanner : struct, IScanner + => new LiteralsParser().Match(ref scanner, result, out literal, in orError); + public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier identifier, in ParseError? orError = null) + where TScanner : struct, IScanner + => new IdentifierParser().Match(ref scanner, result, out identifier, orError); + + public static bool TypeName(ref TScanner scanner, ParseResult result, out TypeName typeName, in ParseError? orError = null) + where TScanner : struct, IScanner + => new TypeNameParser().Match(ref scanner, result, out typeName); + + public static bool Number(ref TScanner scanner, ParseResult result, out NumberLiteral number, in ParseError? orError = null) + where TScanner : struct, IScanner + => new NumberParser().Match(ref scanner, result, out number, in orError); + public static bool Vector(ref TScanner scanner, ParseResult result, out VectorLiteral parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new VectorParser().Match(ref scanner, result, out parsed, in orError); + public static bool Matrix(ref TScanner scanner, ParseResult result, out MatrixLiteral parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new MatrixParser().Match(ref scanner, result, out parsed, in orError); + public static bool Integer(ref TScanner scanner, ParseResult result, out IntegerLiteral number, in ParseError? orError = null) + where TScanner : struct, IScanner + => new IntegerParser().Match(ref scanner, result, out number, in orError); + + public static bool AssignOperators(ref TScanner scanner, ParseResult result, out AssignOperator op, in ParseError? orError = null) + where TScanner : struct, IScanner + { + op = AssignOperator.NOp; + if( + Terminals.AnyOf( + ["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="], + ref scanner, + out var matched, + advance: true + ) + ) + { + op = matched.ToAssignOperator(); + return true; + } + else return false; + } + +} + + +public record struct Suffix(int Size, bool IsFloatingPoint, bool Signed) +{ + public readonly override string ToString() + { + return (IsFloatingPoint, Signed) switch + { + (true, _) => $"f{Size}", + (false, false) => $"u{Size}", + (false, true) => $"i{Size}", + }; + } +} + +public readonly record struct FloatSuffixParser() : ILiteralParser +{ + public static bool TryMatchAndAdvance(ref TScanner scanner, string match) + where TScanner : struct, IScanner + { + if (Terminals.Literal(match, ref scanner)) + { + scanner.Advance(match.Length); + return true; + } + return false; + } + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Suffix suffix, in ParseError? orError = null) + where TScanner : struct, IScanner + { + suffix = new(32, false, false); + if (Terminals.AnyOf(["f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true)) + { + suffix = matched switch + { + "f16" or "h" => new(16, true, true), + "f32" => new(32, true, true), + "f64" or "d" => new(64, true, true), + + _ => throw new NotImplementedException() + }; + return true; + } + else return false; + } +} + +public readonly record struct IntegerSuffixParser() : ILiteralParser +{ + public static bool TryMatchAndAdvance(ref TScanner scanner, string match) + where TScanner : struct, IScanner + { + if (Terminals.Literal(match, ref scanner)) + { + scanner.Advance(match.Length); + return true; + } + return false; + } + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Suffix suffix, in ParseError? orError = null) + where TScanner : struct, IScanner + { + suffix = new(32, false, false); + if (Terminals.AnyOf(["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "U", "L"], ref scanner, out var matched, advance: true)) + { + suffix = matched switch + { + "u8" => new(8, false, false), + "u16" => new(16, false, false), + "u32" => new(32, false, false), + "u64" => new(64, false, false), + "i8" => new(8, false, true), + "i16" => new(16, false, true), + "i32" => new(32, false, true), + "i64" => new(64, false, true), + "U" => new(32, false, false), + "L" => new(32, false, true), + _ => throw new NotImplementedException() + }; + return true; + } + else return false; + } +} + + +public record struct IdentifierParser() : ILiteralParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Identifier literal, in ParseError? orError = null) + where TScanner : struct, IScanner + { + literal = null!; + var position = scanner.Position; + if (Terminals.Char('_', ref scanner) || Terminals.Letter(ref scanner)) + { + scanner.Advance(1); + while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) + scanner.Advance(1); + var id = scanner.Memory[position..scanner.Position].ToString(); + if (Reserved.Keywords.Contains(id)) + return CommonParsers.Exit(ref scanner, result, out literal, position, orError); + literal = new(id, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return false; + } +} + +public record struct TypeNameParser() : ILiteralParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out TypeName name, in ParseError? orError = null) + where TScanner : struct, IScanner + { + name = null!; + var position = scanner.Position; + if (Terminals.Char('_', ref scanner) || Terminals.Letter(ref scanner)) + { + scanner.Advance(1); + while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) + scanner.Advance(1); + + var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position, scanner.Position - position)); + + var intermediate = scanner.Position; + if ( + CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('[', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out _) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + { + name = new TypeName(scanner.Memory[position..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position)); + return true; + } + else + { + scanner.Position = intermediate; + name = new(identifier.Name, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return false; + } +} + + + + +public record struct VectorParser : IParser +{ + + public readonly bool Match(ref TScanner scanner, ParseResult result, out VectorLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) + && Terminals.Digit(ref scanner, 2..4, advance: true) + ) + { + var tnPos = scanner.Position; + int size = scanner.Span[scanner.Position - 1] - '0'; + if (size < 2 || size > 4) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {size}", scanner.CreateError(scanner.Position - 1))); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('(', ref scanner, advance: true)) + { + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos)), scanner.GetLocation(..)) + { + TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1))) + }; + while (!scanner.IsEof) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Number(ref scanner, result, out var number)) + p.Values.Add(number); + else if (LiteralsParser.Vector(ref scanner, result, out var vec)) + p.Values.Add(vec); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(',', ref scanner, advance: true)) + CommonParsers.Spaces0(ref scanner, result, out _); + else if (Terminals.Char(')', ref scanner, advance: true)) + break; + } + if (scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.CreateError(scanner.Position))); + if (p.Values.Count != size && p.Values.Count > size) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {size}", scanner.CreateError(scanner.Position))); + parsed = p; + return true; + } + + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct MatrixParser : IParser +{ + + public readonly bool Match(ref TScanner scanner, ParseResult result, out MatrixLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) + && Terminals.Digit(ref scanner, 2..4, advance: true) + && Terminals.Char('x', ref scanner, advance: true) + && Terminals.Digit(ref scanner, 2..4, advance: true) + ) + { + var tnPos = scanner.Position; + int rows = scanner.Span[scanner.Position - 3] - '0'; + int cols = scanner.Span[scanner.Position - 1] - '0'; + if (cols < 2 || cols > 4 || rows < 2 || rows > 4) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {rows}x{cols}", scanner.CreateError(scanner.Position - 1))); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('(', ref scanner, advance: true)) + { + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos)), rows, cols, scanner.GetLocation(..)) + { + TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1))) + }; + while (!scanner.IsEof) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Number(ref scanner, result, out var number)) + p.Values.Add(number); + else if (LiteralsParser.Vector(ref scanner, result, out var vector, new("Expecting number or vector value", scanner.CreateError(scanner.Position)))) + p.Values.Add(vector); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(',', ref scanner, advance: true)) + CommonParsers.Spaces0(ref scanner, result, out _); + else if (Terminals.Char(')', ref scanner, advance: true)) + break; + } + if (scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.CreateError(scanner.Position))); + if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {rows}x{cols}", scanner.CreateError(scanner.Position))); + parsed = p; + return true; + } + + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs new file mode 100644 index 0000000000..321f1f4bd9 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -0,0 +1,156 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public struct NumberParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out NumberLiteral parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + var fp = new FloatParser(); + var ip = new IntegerParser(); + + if (fp.Match(ref scanner, result, out FloatLiteral pf)) + { + parsed = pf; + return true; + } + else if (ip.Match(ref scanner, result, out IntegerLiteral pi)) + { + parsed = pi; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public struct IntegerParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out IntegerLiteral node, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + IntegerSuffixParser suffix = new(); + if (Terminals.Digit(ref scanner, 1.., advance: true)) + { + while (Terminals.Digit(ref scanner, advance: true)) ; + + var numPos = scanner.Position; + if (suffix.Match(ref scanner, null!, out Suffix suf)) + { + node = new(suf, long.Parse(scanner.Span[position..numPos]), scanner.GetLocation(position, scanner.Position)); + return true; + } + else + { + var memory = scanner.Memory[position..scanner.Position]; + node = new(new(32, false, true), long.Parse(memory.Span), new(scanner.Memory, position..scanner.Position)); + return true; + } + } + else if (Terminals.Char('0', ref scanner, advance: true) && !Terminals.Digit(ref scanner, ..)) + { + node = new(new(32, false, true), 0, new(scanner.Memory, position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + } +} + +public struct FloatParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out FloatLiteral node, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + node = null!; + FloatSuffixParser suffix = new(); + if (Terminals.Char('.', ref scanner)) + { + scanner.Advance(1); + while (Terminals.Digit(ref scanner, advance: true)) ; + + if (suffix.Match(ref scanner, result, out Suffix s)) + node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); + return true; + } + else if (Terminals.Digit(ref scanner, 1.., advance: true)) + { + while (Terminals.Digit(ref scanner, advance: true)) ; + Suffix s = new(32, true, true); + if (Terminals.Char('.', ref scanner, advance: true)) + { + while (Terminals.Digit(ref scanner, advance: true)) ; + } + else if (!suffix.Match(ref scanner, result, out s)) + { + return CommonParsers.Exit(ref scanner, result, out node, position, orError); + } + var len = 0; + foreach (var e in scanner.Span[position..scanner.Position]) + if (!char.IsDigit(e)) + break; + else + len += 1; + node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position+len)]), new(scanner.Memory, position..scanner.Position)); + + return true; + } + else if (Terminals.Digit(ref scanner, 0)) + { + scanner.Advance(1); + Suffix s = new(32, true, true); + if (Terminals.Char('.', ref scanner, advance: true)) + { + while (Terminals.Digit(ref scanner, advance: true)) + if (!suffix.Match(ref scanner, result, out s)) + s = new(32, true, true); + } + node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + } +} +public struct HexParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out HexLiteral node, in ParseError? orError = null) + where TScanner : struct, IScanner + { + node = null!; + var position = scanner.Position; + if (Terminals.Literal("0x", ref scanner, advance: true)) + { + while (Terminals.Set("abcdefABCDEF", ref scanner, advance: true) || Terminals.Digit(ref scanner, advance: true)) ; + + ulong sum = 0; + + for (int i = 0; i < scanner.Position - position - 2; i += 1) + { + var v = Hex2int(scanner.Span[i]); + var add = v * Math.Pow(16, i); + if (ulong.MaxValue - sum < add) + { + result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.CreateError(position))); + return false; + } + } + node = new HexLiteral(sum, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + } + + static int Hex2int(char ch) + { + if (ch >= '0' && ch <= '9') + return ch - '0'; + if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + return -1; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs new file mode 100644 index 0000000000..07abfe318b --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs @@ -0,0 +1,188 @@ +using CommunityToolkit.HighPerformance; + +namespace Stride.Shaders.Parsing.SDSL; + +public class ReadOnlyMemoryCharComparer : IEqualityComparer> +{ + public static ReadOnlyMemoryCharComparer Instance { get; } = new(); + + public bool Equals(ReadOnlyMemory x, ReadOnlyMemory y) => + x.Span.Equals(y.Span, StringComparison.OrdinalIgnoreCase); + + public int GetHashCode(ReadOnlyMemory obj) => + string.GetHashCode(obj.Span, StringComparison.OrdinalIgnoreCase); +} + + +public static class Reserved +{ + internal static readonly HashSet TypeNames; + internal static readonly HashSet Keywords; + + static Reserved() + { + TypeNames = new(); + List types = [ + "float", + "half", + "byte", + "sbyte", + "short", + "ushort", + "int", + "uint", + "long", + "double", + "bool", + "min10float", + "min16float", + "min12int", + "min16int", + "min16uint" + ]; + + foreach(var t in types) + { + for(int i = 1; i < 5; i ++) + { + TypeNames.Add($"{t}{i}"); + for (int j = 1; j < 5; j++) + TypeNames.Add($"{t}{i}x{j}"); + } + } + + + Keywords = [ + ..TypeNames, + "AppendStructuredBuffer", + "asm", + "asm_fragment", + "BlendState", + "bool", + "break", + "Buffer", + "ByteAddressBuffer", + "case", + "cbuffer", + "centroid", + "class", + "column_major", + "compile", + "compile_fragment", + "CompileShader", + "const", + "continue", + "ComputeShader", + "ConsumeStructuredBuffer", + "default", + "DepthStencilState", + "DepthStencilView", + "discard", + "do", + "double", + "DomainShader", + "dword", + "else", + "export", + "extern", + "false", + "float", + "for", + "foreach", + "fxgroup", + "GeometryShader", + "groupshared", + "half", + "Hullshader", + "if", + "in", + "inline", + "inout", + "InputPatch", + "int", + "interface", + "line", + "lineadj", + "linear", + "LineStream", + "matrix", + "min16float", + "min10float", + "min16int", + "min12int", + "min16uint", + "namespace", + "nointerpolation", + "noperspective", + "NULL", + "out", + "OutputPatch", + "packoffset", + "pass", + "pixelfragment", + "PixelShader", + "point", + "PointStream", + "precise", + "RasterizerState", + "RenderTargetView", + "return", + "register", + "rgroup", + "row_major", + "RWBuffer", + "RWByteAddressBuffer", + "RWStructuredBuffer", + "RWTexture1D", + "RWTexture1DArray", + "RWTexture2D", + "RWTexture2DArray", + "RWTexture3D", + "sample", + "sampler", + "SamplerState", + "SamplerComparisonState", + "shader", + "shared", + "snorm", + "stateblock", + "stateblock_state", + "static", + "stream", + "string", + "struct", + "switch", + "StructuredBuffer", + "tbuffer", + "technique", + "technique10", + "technique11", + "texture", + "Texture1D", + "Texture1DArray", + "Texture2D", + "Texture2DArray", + "Texture2DMS", + "Texture2DMSArray", + "Texture3D", + "TextureCube", + "TextureCubeArray", + "true", + "typedef", + "triangle", + "triangleadj", + "TriangleStream", + "uint", + "uniform", + "unorm", + "unsigned", + "var", + "vector", + "vertexfragment", + "VertexShader", + "void", + "volatile", + "while" + ]; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs new file mode 100644 index 0000000000..c6522739e4 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -0,0 +1,159 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct BufferParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + parsed = null!; + if (CBuffer(ref scanner, result, out var cbuff, orError)) + { + parsed = cbuff; + return true; + } + else if (TBuffer(ref scanner, result, out var tbuff, orError)) + { + parsed = tbuff; + return true; + } + return false; + } + + public static bool Buffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BufferParsers().Match(ref scanner, result, out parsed, orError); + + public static bool TBuffer(ref TScanner scanner, ParseResult result, out TBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new TBufferParser().Match(ref scanner, result, out parsed, orError); + + public static bool CBuffer(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new CBufferParser().Match(ref scanner, result, out parsed, orError); + + public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new BufferMemberParser().Match(ref scanner, result, out parsed, orError); +} + + +public record struct CBufferParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("cbuffer ", ref scanner, advance: true)) + { + if ( + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char('{', ref scanner)) + { + List members = []; + CommonParsers.Spaces0(ref scanner, result, out _); + do + { + if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) + members.Add(member); + } + while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); + if (Terminals.Char('}', ref scanner, advance: true)) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + { + Members = members + }; + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } +} +public record struct TBufferParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out TBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("tbuffer ", ref scanner, advance: true)) + { + if ( + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char('{', ref scanner)) + { + List members = []; + CommonParsers.Spaces0(ref scanner, result, out _); + do + { + if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) + members.Add(member); + } + while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); + if (Terminals.Char('}', ref scanner, advance: true)) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + { + Members = members + }; + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); ; + + } +} + +public record struct BufferMemberParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + var isStage = false; + var isStream = false; + if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + isStage = true; + else + scanner.Position = position; + if (LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out Identifier name) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + ) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + { + CommonParsers.Until(ref scanner, ';', advance: true); + parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position), isStage, isStream); + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) + { + CommonParsers.Until(ref scanner, '=', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.CreateError(scanner.Position)))) + { + if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + { + parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), isStage, isStream); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs new file mode 100644 index 0000000000..0e06b368e6 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -0,0 +1,175 @@ +using System.Runtime.CompilerServices; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct ShaderClassParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (ComplexClass(ref scanner, result, out parsed, in orError)) + return true; + else + return false; + } + public static bool Class(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderClassParsers().Match(ref scanner, result, out parsed, in orError); + public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); + public static bool GenericsDefinition(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed) + where TScanner : struct, IScanner + => new ShaderGenericsDefinitionParser().Match(ref scanner, result, out parsed); + public static bool Mixin(ref TScanner scanner, ParseResult result, out ShaderMixin parsed) + where TScanner : struct, IScanner + => new ShaderMixinParser().Match(ref scanner, result, out parsed); +} + +public record struct SimpleShaderClassParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + if ( + Terminals.Literal("shader", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var className, new("Expected class name", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('{', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + + ) + { + var c = new ShaderClass(className, scanner.GetLocation(position, scanner.Position - position)); + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + { + if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) + { + c.Elements.Add(e); + } + else + break; + CommonParsers.Spaces0(ref scanner, result, out _); + } + parsed = c; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ShaderClassParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("shader ", ref scanner, advance: true)) + { + if ( + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + parsed = new ShaderClass(identifier, scanner.GetLocation(..)); + if (Terminals.Char('<', ref scanner, advance: true)) + { + ParameterParsers.Declarations(ref scanner, result, out var generics); + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char('>', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.CreateError(scanner.Position))); + parsed.Generics = generics; + CommonParsers.Spaces0(ref scanner, result, out _); + } + if (Terminals.Char(':', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + while (ShaderClassParsers.Mixin(ref scanner, result, out var mixin)) + { + parsed.Mixins.Add(mixin); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(',', ref scanner, advance: true)) + CommonParsers.Spaces0(ref scanner, result, out _); + else + break; + } + if (parsed.Mixins.Count == 0) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.CreateError(scanner.Position))); + CommonParsers.Spaces0(ref scanner, result, out _); + } + if (Terminals.Char('{', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + { + if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) + { + parsed.Elements.Add(e); + } + else + break; + CommonParsers.Spaces0(ref scanner, result, out _); + } + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.CreateError(position))); + + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + +public record struct ShaderMixinParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + parsed = new ShaderMixin(identifier, scanner.GetLocation(..)); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('<', ref scanner, advance: true)) + { + ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.CreateError(position))); + parsed.Generics = values; + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char('>', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.CreateError(scanner.Position))); + return true; + } + else + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + +public record struct ShaderGenericsDefinitionParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.Identifier(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + ) + { + parsed = new ShaderGenerics(typename, identifier, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs new file mode 100644 index 0000000000..9eaa0018b9 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -0,0 +1,106 @@ +using System.Runtime; +using System.Security.Cryptography.X509Certificates; +using System.Text.RegularExpressions; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + +public record struct ShaderMemberParser : IParser +{ + public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderMemberParser().Match(ref scanner, result, out parsed, in orError); + + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if (LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out Identifier name) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + ) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + { + CommonParsers.Until(ref scanner, ';', advance: true); + parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position)); + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) + { + CommonParsers.Until(ref scanner, '=', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.CreateError(scanner.Position)))) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) + { + CommonParsers.Until(ref scanner, ':', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new("Expected semantic here", scanner.CreateError(scanner.Position)))) + { + if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + { + parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.CreateError(scanner.Position))); + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} +public record struct ShaderStructParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("struct", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + parsed = new ShaderStruct(identifier, scanner.GetLocation(position..)); + CommonParsers.Repeat(ref scanner, new ShaderStructMemberParser(), result, out var members, 0, withSpaces: true, separator: ";"); + parsed.Members = members; + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing bracket", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} +public record struct ShaderStructMemberParser : IParser +{ + + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderStructMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + ) + { + parsed = new ShaderStructMember(typename, identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs new file mode 100644 index 0000000000..d9558b4ea4 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -0,0 +1,66 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct ShaderElementParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (BufferParsers.Buffer(ref scanner, result, out var buffer)) + { + parsed = buffer; + return true; + } + else if(Struct(ref scanner, result, out var structElement)) + { + parsed = structElement; + return true; + } + else + { + bool isStaged = false; + bool isStreamed = false; + var tmpPos = position; + if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + isStaged = true; + tmpPos = scanner.Position; + } + else + scanner.Position = tmpPos; + if (Terminals.Literal("stream", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + isStreamed = true; + else + scanner.Position = tmpPos; + if (ShaderMemberParser.Member(ref scanner, result, out var member)) + { + member.IsStream = isStreamed; + member.IsStaged = isStaged; + parsed = member; + return true; + } + else if (Method(ref scanner, result, out var method)) + { + method.IsStaged = isStaged; + parsed = method; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } + + } + + public static bool Struct(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderStructParser().Match(ref scanner, result, out parsed, in orError); + public static bool ShaderElement(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderElementParsers().Match(ref scanner, result, out parsed, in orError); + + public static bool Method(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs new file mode 100644 index 0000000000..8acee63dea --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -0,0 +1,96 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + + + +public record struct ShaderFileParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderFile parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + var file = new ShaderFile(new(scanner.Memory, ..)); + while (!scanner.IsEof) + { + if ( + Terminals.Literal("namespace", ref scanner) + && NamespaceParsers.Namespace(ref scanner, result, out var ns) + ) + { + file.Namespaces.Add(ns); + CommonParsers.Spaces0(ref scanner, result, out _); + } + else if(Terminals.Literal("shader", ref scanner) + && ShaderClassParsers.Class(ref scanner, result, out var shader) + ) + { + file.RootClasses.Add(shader); + CommonParsers.Spaces0(ref scanner, result, out _); + } + } + parsed = file; + return true; + } +} + + + + +public record struct NamespaceParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("namespace", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + ) + { + var ns = new ShaderNamespace(new()); + do + { + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + ns.NamespacePath.Add(identifier); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected identifier", scanner.CreateError(scanner.Position))); + + CommonParsers.Spaces0(ref scanner, result, out _); + } + while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true)); + if(ns.NamespacePath.Count > 0) + ns.Namespace = string.Join(".", ns.NamespacePath); + if (Terminals.Char(';', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + while (ShaderClassParsers.Class(ref scanner, result, out var shader)) + { + ns.ShaderClasses.Add(shader); + } + } + else if (Terminals.Char('{', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + { + if(ShaderClassParsers.Class(ref scanner, result, out var shader) && CommonParsers.Spaces0(ref scanner, result, out _)) + ns.ShaderClasses.Add(shader); + else + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class", scanner.CreateError(scanner.Position))); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + ns.Info = scanner.GetLocation(position, scanner.Position - position); + parsed = ns; + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool Namespace(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new NamespaceParsers().Match(ref scanner, result, out parsed, orError); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs new file mode 100644 index 0000000000..6c57b74a57 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -0,0 +1,139 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct ShaderMethodParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if (Method(ref scanner, result, out var method, in orError)) + { + parsed = method; + return true; + } + else + { + parsed = null!; + return false; + } + } + + public static bool Method(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new MethodParser().Match(ref scanner, result, out parsed, in orError); + public static bool Simple(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new SimpleMethodParser().Match(ref scanner, result, out parsed, in orError); + + public static bool Parameters(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ParameterDeclarationsParser().Match(ref scanner, result, out parsed, orError); +} + +public record struct SimpleMethodParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var methodName) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + && ShaderMethodParsers.Parameters(ref scanner, result, out var parameters) + && Terminals.Char(')', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && StatementParsers.Block(ref scanner, result, out var body, new("Expected Body declaration", scanner.CreateError(scanner.Position))) + ) + { + parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) + { + ParameterList = parameters, + Body = (BlockStatement)body + }; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + +public record struct MethodParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if (Terminals.Literal("abstract", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if ( + LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new("Expected type name here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new("Expected method name here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + ShaderMethodParsers.Parameters(ref scanner, result, out var parameters); + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char(')', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closed parenthesis", scanner.CreateError(scanner.Position))); + + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char(';', ref scanner, advance: true)) + { + if (orError != null) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + else + { + parsed = new(typename, methodName, scanner.GetLocation(position..scanner.Position), isAbstract: true) + { + ParameterList = parameters + }; + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + else + scanner.Position = position; + if (Terminals.AnyOf(["clone", "override"], ref scanner, out var matched, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + var isClone = false; + var isOverride = false; + var tmpPos = scanner.Position; + if (matched == "clone") + isClone = true; + else if (matched == "override") + isOverride = true; + + CommonParsers.Spaces0(ref scanner, result, out _); + if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) + { + parsed.IsClone = isClone; + parsed.IsOverride = isOverride; + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + } + else + scanner.Position = position; + if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) + { + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs new file mode 100644 index 0000000000..486878bde5 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -0,0 +1,128 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct ParameterParsers : IParser +{ + public bool Match(ref TScanner scanner, ParseResult result, out ParameterListNode parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + throw new NotImplementedException(); + } + public static bool Declarations(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ParameterDeclarationsParser().Match(ref scanner, result, out parsed, in orError); + public static bool Values(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ParameterListParser().Match(ref scanner, result, out parsed, in orError); + + public static bool GenericsList(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new GenericsListParser().Match(ref scanner, result, out parsed, in orError); + public static bool GenericsValue(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new GenericsValueParser().Match(ref scanner, result, out parsed, in orError); +} + + +public record struct ParameterDeclarationsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + List parameters = []; + while ( + LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var name) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + parameters.Add(new(typename, name)); + if (!Terminals.Char(',', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + break; + } + parsed = new(scanner.GetLocation(position..scanner.Position)) { Parameters = parameters }; + return true; + } +} +public record struct ParameterListParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + List values = []; + while (ExpressionParser.Expression(ref scanner, result, out var expr) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + values.Add(expr); + if (!Terminals.Char(',', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + break; + } + parsed = new(scanner.GetLocation(position..scanner.Position)) + { + Values = values + }; + return true; + } +} + +public record struct GenericsListParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.CreateError(scanner.Position)))) + { + parsed = new(scanner.GetLocation(position..scanner.Position)); + parsed.Values.Add(parameter); + CommonParsers.Spaces0(ref scanner, result, out _); + while (Terminals.Char(',', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.CreateError(scanner.Position)))) + { + parsed.Values.Add(other); + CommonParsers.Spaces0(ref scanner, result, out _); + } + } + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct GenericsValueParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (LiteralsParser.Number(ref scanner, result, out var number)) + { + parsed = number; + return true; + } + else if (LiteralsParser.Vector(ref scanner, result, out var vector)) + { + parsed = vector; + return true; + } + else if (PostfixParser.Accessor(ref scanner, result, out var accessor)) + { + if (accessor is AccessorExpression ae && ae.Accessed is Identifier) + { + parsed = accessor; + return true; + } + scanner.Position = position; + } + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + // previous parser might have matched somehow and advanced the scanner + + parsed = identifier; + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs new file mode 100644 index 0000000000..7039204788 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -0,0 +1,119 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + + +public record struct ControlsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if(If(ref scanner, result, out var ifstatement, orError)) + { + parsed = new(ifstatement, scanner.GetLocation(..)); + while(ElseIf(ref scanner, result, out var elseif, orError)) + parsed.ElseIfs.Add(elseif); + if (Else(ref scanner, result, out var elseStatement, orError)) + parsed.Else = elseStatement; + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else if(Terminals.Literal("else ", ref scanner)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new IfStatementParser().Match(ref scanner, result, out parsed, orError); + public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ElseIfStatementParser().Match(ref scanner, result, out parsed, orError); + public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ElseStatementParser().Match(ref scanner, result, out parsed, orError); +} + + + +public record struct IfStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out If parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("if", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position)))) + { + parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ElseIfStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseIf parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("else", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && Terminals.Literal("if", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position)))) + { + parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ElseStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Else parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("else", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position))) + ) + { + parsed = new(statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs new file mode 100644 index 0000000000..ba73f40230 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -0,0 +1,173 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + + +public record struct FlowParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (While(ref scanner, result, out var w, orError)) + { + parsed = w; + return true; + } + else if (ForEach(ref scanner, result, out var fe, orError)) + { + parsed = fe; + return true; + } + else if (For(ref scanner, result, out var f, orError)) + { + parsed = f; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new WhileParser().Match(ref scanner, result, out parsed, orError); + public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ForEachParser().Match(ref scanner, result, out parsed, orError); + public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ForParser().Match(ref scanner, result, out parsed, orError); +} + + + +public record struct ForParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out For parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + Terminals.Literal("for", ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + ) + { + Statement? init = null; + Statement? condition = null; + Statement? expression = null; + CommonParsers.Spaces0(ref scanner, result, out _); + + // Parsing the initialization + if(StatementParsers.Expression(ref scanner, result, out init)){} + else if(StatementParsers.Assignments(ref scanner, result, out init)){} + else if(StatementParsers.Declare(ref scanner, result, out init)){} + else if(StatementParsers.Empty(ref scanner, result, out init)){} + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected initializer", scanner.CreateError(scanner.Position))); + + CommonParsers.Spaces0(ref scanner, result, out _); + // Parsing the condition + + if (StatementParsers.Expression(ref scanner, result, out condition)){} + else if (StatementParsers.Empty(ref scanner, result, out condition)){} + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected condition expression", scanner.CreateError(scanner.Position))); + + CommonParsers.Spaces0(ref scanner, result, out _); + // parsing the final expression + + var tmpPos = scanner.Position; + if(CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) + expression = new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position)); + else if(ExpressionParser.Expression(ref scanner, result, out var exp) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) + { + expression = new ExpressionStatement(exp, exp.Info); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end expression", scanner.CreateError(scanner.Position))); + + CommonParsers.Spaces0(ref scanner, result, out _); + + // parsing the block or statement + + if(StatementParsers.Statement(ref scanner, result, out var body)) + { + parsed = new For(init, condition, expression, body, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ForEachParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ForEach parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("foreach", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if ( + LiteralsParser.TypeName(ref scanner, result, out var typeName, new("Expected type definition here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _) + ) + { + if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if ( + ExpressionParser.Expression(ref scanner, result, out var collection, new("Expected variable name or collection name here", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.CreateError(scanner.Position)))) + { + parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.CreateError(scanner.Position))); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected keyword in here", scanner.CreateError(scanner.Position))); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct WhileParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out While parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("while", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (ExpressionParser.Expression(ref scanner, result, out var expression, new("Expected expression here", scanner.CreateError(scanner.Position)))) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.CreateError(scanner.Position)))) + { + parsed = new(expression, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.CreateError(scanner.Position))); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.CreateError(scanner.Position))); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs new file mode 100644 index 0000000000..3944e5c4b8 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -0,0 +1,311 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct StatementParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Empty(ref scanner, result, out parsed)) + return true; + else if (Controls(ref scanner, result, out var cond)) + { + parsed = cond; + return true; + } + else if (Flow(ref scanner, result, out var flow)) + { + parsed = flow; + return true; + } + else if (Expression(ref scanner, result, out parsed)) + return true; + else if (Break(ref scanner, result, out parsed)) + return true; + else if (Return(ref scanner, result, out parsed)) + return true; + else if (Continue(ref scanner, result, out parsed)) + return true; + else if (Declare(ref scanner, result, out parsed)) + return true; + else if (Assignments(ref scanner, result, out parsed)) + return true; + else if (Block(ref scanner, result, out parsed)) + return true; + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + internal static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new StatementParsers().Match(ref scanner, result, out parsed, orError); + internal static bool Empty(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new EmptyStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new BlockStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Break(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new BreakParser().Match(ref scanner, result, out parsed, orError); + internal static bool Return(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ReturnStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Continue(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ContinueParser().Match(ref scanner, result, out parsed, orError); + internal static bool Expression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ExpressionStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Declare(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new DeclareStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Assignments(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new AssignmentsParser().Match(ref scanner, result, out parsed, orError); + internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new VariableAssignParser().Match(ref scanner, result, out parsed, orError); + internal static bool Controls(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ControlsParser().Match(ref scanner, result, out parsed, orError); + internal static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new FlowParsers().Match(ref scanner, result, out parsed, orError); +} + + + +public record struct EmptyStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + if(Terminals.Char(';', ref scanner, advance : true)) + { + parsed = new EmptyStatement(scanner.GetLocation(position..scanner.Position)); + return true; + } + return false; + } +} + + +public record struct ReturnStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("return;", ref scanner, advance: true)) + { + parsed = new Return(scanner.GetLocation(position..scanner.Position)); + return true; + } + else if ( + Terminals.Literal("return", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + ) + { + if (Terminals.Char(';', ref scanner, advance: true)) + { + parsed = new Return(scanner.GetLocation(position..scanner.Position)); + return true; + } + else if ( + ExpressionParser.Expression(ref scanner, result, out var val) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new Return(scanner.GetLocation(position, scanner.Position - position), val); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected value or \";\"", scanner.CreateError(scanner.Position))); + + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct BreakParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("break", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new Break(scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} +public record struct ContinueParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("continue", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new Break(scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ExpressionStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + ExpressionParser.Expression(ref scanner, result, out var expression) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new ExpressionStatement(expression, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + + + +public record struct BlockStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + var block = new BlockStatement(new()); + + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement)) + { + block.Statements.Add(statement); + CommonParsers.Spaces0(ref scanner, result, out _); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Statement", scanner.CreateError(scanner.Position))); + } + block.Info = scanner.GetLocation(position, scanner.Position - position); + parsed = block; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + + + +public record struct VariableAssignParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + if ( + CommonParsers.FollowedBy( + ref scanner, + result, + (ref TScanner s, ParseResult result, out AssignOperator op, ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), + out var op, + withSpaces: true, + advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression)) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position), op, expression); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected expression here", scanner.CreateError(position))); + } + else + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } +} + + + +public record struct DeclareStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + LiteralsParser.TypeName(ref scanner, result, out var typeName) + && CommonParsers.Spaces1(ref scanner, result, out _) + + ) + { + if (CommonParsers.Repeat(ref scanner, StatementParsers.VarAssign, result, out var assigns, 1, true, ",")) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(';', ref scanner, advance: true)) + { + parsed = new Declare(typeName, scanner.GetLocation(position..scanner.Position)) + { + Variables = assigns + }; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.CreateError(scanner.Position))); + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct AssignmentsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (CommonParsers.Repeat(ref scanner, StatementParsers.VarAssign, result, out var assigns, 1, true, ",")) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(';', ref scanner, advance: true)) + { + parsed = new Assign(scanner.GetLocation(position..scanner.Position)) + { + Variables = assigns + }; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.CreateError(scanner.Position))); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs new file mode 100644 index 0000000000..f5d1f85824 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -0,0 +1,224 @@ + +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace Stride.Shaders.Parsing.SDSL; + + +public static class Terminals +{ + public static bool AnyChar(ref TScanner scanner) + where TScanner : struct, IScanner + => !scanner.IsEof; + + public static CharTerminalParser Char(char c) => new(c); + public static bool Char(char c, ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new CharTerminalParser(c).Match(ref scanner, advance); + public static SetTerminalParser Set(string set) => new(set); + public static bool Set(string set, ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new SetTerminalParser(set).Match(ref scanner, advance); + + public static bool Set(string set, ref TScanner scanner, out char chosen, bool advance = false) + where TScanner : struct, IScanner + { + chosen = '\0'; + foreach(var c in set) + if(Char(c, ref scanner, advance: advance)) + { + chosen = c; + return true; + } + return false; + } + public static LiteralTerminalParser Literal(string literal) => new(literal); + public static bool Literal(string c, ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new LiteralTerminalParser(c).Match(ref scanner, advance); + public static bool AnyOf(ReadOnlySpan literals, ref TScanner scanner, out string matched, bool advance = false) + where TScanner : struct, IScanner + { + matched = null!; + foreach(var l in literals) + if(new LiteralTerminalParser(l).Match(ref scanner, advance)) + { + matched = l; + return true; + } + return false; + } + public static DigitTerminalParser Digit(DigitRange? mode = null) => new(mode ?? DigitRange.All); + public static bool Digit(ref TScanner scanner, DigitRange? mode = null, bool advance = false) + where TScanner : struct, IScanner + => new DigitTerminalParser(mode ?? DigitRange.All).Match(ref scanner, advance); + public static LetterTerminalParser Letter() => new(); + public static bool Letter(ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new LetterTerminalParser().Match(ref scanner, advance); + public static LetterOrDigitTerminalParser LetterOrDigit() => new(); + public static bool LetterOrDigit(ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new LetterOrDigitTerminalParser().Match(ref scanner, advance); + public static bool IdentifierFirstChar(ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => Letter(ref scanner, advance) || Char('_', ref scanner, advance); + public static bool EOL(ref TScanner scanner, bool advance = false) + where TScanner : struct, IScanner + => new EOLTerminalParser().Match(ref scanner, advance); + public static bool EOF(ref TScanner scanner) + where TScanner : struct, IScanner + => new EOFTerminalParser().Match(ref scanner, false); +} + +public interface ITerminal +{ + public bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner; +} + +public record struct CharTerminalParser(char Character) : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + if (scanner.Peek() == Character) + { + if(advance) + scanner.Advance(1); + return true; + } + return false; + } + public static implicit operator CharTerminalParser(char c) => new(c); +} + +public struct DigitRange +{ + static string allChars = "0123456789"; + public static DigitRange All { get; } = new(0..9); + public static DigitRange ExceptZero { get; } = new(1..9); + public static DigitRange OnlyZero { get; } = new(0); + public string Chars { get; set; } + public DigitRange(Range range) + { + var (o, l) = range.GetOffsetAndLength(allChars.Length); + Chars = allChars[o..Math.Min(allChars.Length,o+l+1)]; + } + public DigitRange(int digit) + { + Chars = $"{(char)(digit + '0')}"; + } + public DigitRange(string chars) + { + foreach(var e in chars) + if(!char.IsDigit(e)) + throw new ArgumentException($"Cannot use {chars} as a list of digit"); + Chars = chars; + } + + public static implicit operator DigitRange(Range range) => new(range); + public static implicit operator DigitRange(int number) => new(number); + public static implicit operator DigitRange(string numbers) => new(numbers); +} + +public record struct DigitTerminalParser(DigitRange Mode) : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + bool found = false; + if (Mode.Chars.Contains((char)scanner.Peek())) + found = true; + if (advance && found) + scanner.Advance(1); + return found; + } +} + +public record struct LetterTerminalParser() : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + if (scanner.Peek() > 0 && char.IsLetter((char)scanner.Peek())) + { + if (advance) + scanner.Advance(1); + return true; + } + return false; + } +} +public record struct LetterOrDigitTerminalParser() : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + if (scanner.Peek() > 0 && char.IsLetterOrDigit((char)scanner.Peek())) + { + if (advance) + scanner.Advance(1); + return true; + } + return false; + } +} + +public record struct LiteralTerminalParser(string Literal, bool CaseSensitive = true) : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + if (scanner.ReadString(Literal, CaseSensitive)) + { + if (advance) + scanner.Advance(Literal.Length); + return true; + } + return false; + } + public static implicit operator LiteralTerminalParser(string lit) => new(lit); +} + + +public record struct SetTerminalParser(string Set) : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + if (scanner.Peek() > 0 && Set.Contains((char)scanner.Peek())) + { + if (advance) + scanner.Advance(1); + return true; + } + return false; + } + + public static implicit operator SetTerminalParser(string set) => new(set); +} + +public record struct EOFTerminalParser() : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + return scanner.IsEof; + } +} +public record struct EOLTerminalParser() : ITerminal +{ + public readonly bool Match(ref TScanner scanner, bool advance) + where TScanner : struct, IScanner + { + var position = scanner.Position; + while (scanner.Peek() == ' ') + scanner.Advance(1); + var result = Terminals.Char('\n', ref scanner, advance) || Terminals.Literal("\r\n", ref scanner, advance); + if (!advance && result) + scanner.Position = position; + return result; + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs b/src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs new file mode 100644 index 0000000000..f0bab41f2c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs @@ -0,0 +1,14 @@ +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Parsing.SDSL.PreProcessing; + +namespace Stride.Shaders.Parsing.SDSL; + + +public static class SDSLParser +{ + public static ParseResult Parse(string code) + { + var c = new CommentProcessedCode(code); + return Grammar.Match(c); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs new file mode 100644 index 0000000000..e647c0b364 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs @@ -0,0 +1,56 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing; + +public struct ErrorLocation +{ + public ReadOnlyMemory Text { get; private set; } + public int Position { get; private set; } + private int leftOffset; + private int rightOffset; + private int line; + private int column; + public ErrorLocation(Scanner scanner, int position) + { + // Getting the line and column at the position given. + // TODO: Make this a function in scanner + var pos = scanner.Position; + scanner.Position = position; + line = scanner.Line; + column = scanner.Column; + scanner.Position = pos; + + // Setting other attributes + leftOffset = position - 5 > 0 ? 5 : position; + rightOffset = position + 5 < scanner.Span.Length ? 5 : scanner.Span.Length - position - 1; + Position = position; + + Text = scanner.Memory[(position - leftOffset)..(position + rightOffset)]; + } + + public static ErrorLocation Create(Scanner scanner, int position) + where TScannable : IScannableCode + { + var error = new ErrorLocation(); + var pos = scanner.Position; + scanner.Position = position; + error.line = scanner.Line; + error.column = scanner.Column; + scanner.Position = pos; + + // Setting other attributes + error.leftOffset = position - 5 > 0 ? 5 : position; + error.rightOffset = position + 5 < scanner.Span.Length ? 5 : scanner.Span.Length - position - 1; + error.Position = position; + + error.Text = scanner.Memory[(position - error.leftOffset)..(position + error.rightOffset)]; + return error; + } + + public readonly override string ToString() + { + return $"l{line}-c{column} : \n{Text[..5]}>>>{Text[5..]}"; + } +} + + diff --git a/src/Stride.Shaders.Parsing/Scanners/IScannableCode.cs b/src/Stride.Shaders.Parsing/Scanners/IScannableCode.cs new file mode 100644 index 0000000000..d1046675cc --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/IScannableCode.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Parsing; + +public interface IScannableCode +{ + ReadOnlySpan Span { get; } + ReadOnlyMemory Memory { get; } +} + + + + diff --git a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs new file mode 100644 index 0000000000..5bb6c8f965 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs @@ -0,0 +1,45 @@ +namespace Stride.Shaders.Parsing; + + +public interface IScanner : IScanner + where TScannable : IScannableCode +{ + TScannable Code { get; init; } +} + + +public interface IScanner +{ + public ReadOnlySpan Span { get; } + public ReadOnlyMemory Memory { get; } + public int Position { get; set; } + + public int Line { get; } + public int Column { get; } + + + + public int End { get; } + public bool IsEof { get; } + + public int ReadChar(); + + public int Peek(); + public ReadOnlySpan Peek(int size); + + public int Advance(int length); + + public bool ReadString(string matchString, bool caseSensitive); + + public ReadOnlySpan Slice(int index, int length); + + public int LineAtIndex(int index); + + public TextLocation GetLocation(int position, int length); + public TextLocation GetLocation(Range range); + public ErrorLocation CreateError(int position); +} + + + + diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannableString.cs b/src/Stride.Shaders.Parsing/Scanners/ScannableString.cs new file mode 100644 index 0000000000..ec19b5c78c --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/ScannableString.cs @@ -0,0 +1,32 @@ + +namespace Stride.Shaders.Parsing; + + +public readonly struct ScannableString(string code) : IScannableCode +{ + public string Code { get; } = code; + public readonly ReadOnlySpan Span => Code.AsSpan(); + public readonly ReadOnlyMemory Memory => Code.AsMemory(); + + public static implicit operator ScannableString(string s) => new (s); + public static implicit operator string(ScannableString s) => s.Code; +} + +public readonly struct ScannableMemory(Memory code) : IScannableCode +{ + public Memory Code { get; } = code; + public readonly ReadOnlySpan Span => Code.Span; + public readonly ReadOnlyMemory Memory => Code; + + public static implicit operator ScannableMemory(Memory s) => new(s); + public static implicit operator Memory(ScannableMemory s) => s.Code; +} +public readonly struct ScannableReadOnlyMemory(ReadOnlyMemory code) : IScannableCode +{ + public ReadOnlyMemory Code { get; } = code; + public readonly ReadOnlySpan Span => Code.Span; + public readonly ReadOnlyMemory Memory => Code; + + public static implicit operator ScannableReadOnlyMemory(Memory s) => new(s); + public static implicit operator ReadOnlyMemory(ScannableReadOnlyMemory s) => s.Code; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs new file mode 100644 index 0000000000..f1a9a8d8c8 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs @@ -0,0 +1,122 @@ +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Parsing.SDSL.PreProcessing; + +namespace Stride.Shaders.Parsing; + +public struct Scanner(string code) : IScanner +{ + readonly int start = 0; + // public string Code { get; } = code; + public readonly ReadOnlySpan Span => Code.AsSpan(); + public readonly ReadOnlyMemory Memory => Code.AsMemory(); + string Code { get; set; } = code; + public int Position { get; set; } = 0; + + public readonly int Line => Span[..Position].Count('\n') + 1; + public readonly int Column => Position - Span[..Position].LastIndexOf('\n') + 1; + + + + public readonly int End => Span.Length; + public readonly bool IsEof => Position >= End; + + public int ReadChar() + { + var pos = Position; + if (pos < End) + { + Position = pos + 1; + return Span[pos]; + } + return -1; + } + + public readonly int Peek() + { + var pos = Position; + return pos < End ? Span[pos] : -1; + } + public readonly ReadOnlySpan Peek(int size) + => Position < End ? Slice(Position, size) : []; + + public int Advance(int length) + { + var pos = Position; + var newPos = pos + length; + if (newPos <= End) + { + Position = newPos; + return pos; + } + return -1; + } + + public readonly bool ReadString(string matchString, bool caseSensitive) + { + var index = Position; + var Endstring = index + matchString.Length; + if (Endstring <= End) + { + if (caseSensitive) + { + for (int i = 0; i < matchString.Length; i++) + { + if (Span[index++] != matchString[i]) + return false; + } + return true; + } + else + { + for (int i = 0; i < matchString.Length; i++) + { + if (char.ToLowerInvariant(Span[index++]) != char.ToLowerInvariant(matchString[i])) + return false; + } + return true; + } + } + return false; + } + + public readonly ReadOnlySpan Slice(int index, int length) + { + if (index < End) + { + length = Math.Min(index + length, End) - index; + var slice = Span.Slice(index, length); + return slice; + } + return []; + } + + public readonly int LineAtIndex(int index) + { + int lineCount = 0; + var max = Math.Min(End, index); + for (int i = start; i < max; i++) + { + if (Span[i] == '\n') + lineCount++; + } + return lineCount + 1; + } + + public readonly TextLocation GetLocation(int position, int length) + { + return new(Memory, new(position, position + length)); + } + public readonly ErrorLocation CreateError(int position) + { + return new ErrorLocation(this, position); + } + + public readonly TextLocation GetLocation(Range range) + { + return new(Memory, range); + } +} + + + + diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs new file mode 100644 index 0000000000..37137c5997 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs @@ -0,0 +1,118 @@ +namespace Stride.Shaders.Parsing; + + + +public struct Scanner(T code) : IScanner + where T : IScannableCode +{ + readonly int start = 0; + public readonly ReadOnlySpan Span => Code.Span; + public readonly ReadOnlyMemory Memory => Code.Memory; + public T Code { get; set; } = code; + public int Position { get; set; } = 0; + + public readonly int Line => Span[..Position].Count('\n') + 1; + public readonly int Column => Position - Span[..Position].LastIndexOf('\n') + 1; + + + + public readonly int End => Span.Length; + public readonly bool IsEof => Position >= End; + + public int ReadChar() + { + var pos = Position; + if (pos < End) + { + Position = pos + 1; + return Span[pos]; + } + return -1; + } + + public readonly int Peek() + { + var pos = Position; + return pos < End ? Span[pos] : -1; + } + public readonly ReadOnlySpan Peek(int size) + => Position < End ? Slice(Position, size) : []; + + public int Advance(int length) + { + var pos = Position; + var newPos = pos + length; + if (newPos <= End) + { + Position = newPos; + return pos; + } + return -1; + } + + public readonly bool ReadString(string matchString, bool caseSensitive) + { + var index = Position; + var Endstring = index + matchString.Length; + if (Endstring <= End) + { + if (caseSensitive) + { + for (int i = 0; i < matchString.Length; i++) + { + if (Span[index++] != matchString[i]) + return false; + } + return true; + } + else + { + for (int i = 0; i < matchString.Length; i++) + { + if (char.ToLowerInvariant(Span[index++]) != char.ToLowerInvariant(matchString[i])) + return false; + } + return true; + } + } + return false; + } + + public readonly ReadOnlySpan Slice(int index, int length) + { + if (index < End) + { + length = Math.Min(index + length, End) - index; + var slice = Span.Slice(index, length); + return slice; + } + return []; + } + + public readonly int LineAtIndex(int index) + { + int lineCount = 0; + var max = Math.Min(End, index); + for (int i = start; i < max; i++) + { + if (Span[i] == '\n') + lineCount++; + } + return lineCount + 1; + } + + public readonly TextLocation GetLocation(int position, int length) + { + return new(Memory, new(position, position + length)); + } + + public readonly ErrorLocation CreateError(int position) + { + return ErrorLocation.Create(this, position); + } + + public readonly TextLocation GetLocation(Range range) + { + return new(Memory, range); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs new file mode 100644 index 0000000000..f7897c252b --- /dev/null +++ b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs @@ -0,0 +1,33 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Parsing; + +public record struct TextLocation(ReadOnlyMemory Original, Range Range) +{ + public ReadOnlyMemory Text { get; } = Original[Range]; + public readonly ReadOnlySpan TextSpan => Text.Span; + public readonly int Length => Range.GetOffsetAndLength(Original.Length).Length; + + public readonly int Line => Original.Span[..Range.StartsAt(Original.Length)].Count('\n') + 1; + public readonly int Column => Range.StartsAt(Original.Length) - Original.Span[..Range.StartsAt(Original.Length)].LastIndexOf('\n'); + public readonly override string ToString() + { + return $"[l{Line}-c{Column}]\n{Text.Span}"; + } +} + +public static class SpanCharExtensions +{ + public static int Sum(this (int offset, int length) ol) => ol.offset + ol.length; + + public static int EndsAt(this Range range, int originalLength) + { + var (o, l) =range.GetOffsetAndLength(originalLength); + return o + l; + } + public static int StartsAt(this Range range, int originalLength) + { + var (o, _) =range.GetOffsetAndLength(originalLength); + return o; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj new file mode 100644 index 0000000000..e7fe7008d7 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + From 16f737f45f3573a00e01d74bc4ad4d0e9fbf8f3b Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Sat, 6 Jul 2024 00:42:33 +0200 Subject: [PATCH 0295/1182] update Language server --- SDSL.sln | 7 + .../DidChangeWatchedFilesHandler.cs | 18 ++ src/Stride.Shaders.LSP/FoldingRangeHandler.cs | 39 +++ src/Stride.Shaders.LSP/Foo.cs | 20 ++ src/Stride.Shaders.LSP/Program.cs | 159 +++++++++++ .../SemanticTokensHandler.cs | 111 ++++++++ .../Stride.Shaders.LSP.csproj | 20 ++ src/Stride.Shaders.LSP/TextDocumentHandler.cs | 262 ++++++++++++++++++ 8 files changed, 636 insertions(+) create mode 100644 src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs create mode 100644 src/Stride.Shaders.LSP/FoldingRangeHandler.cs create mode 100644 src/Stride.Shaders.LSP/Foo.cs create mode 100644 src/Stride.Shaders.LSP/Program.cs create mode 100644 src/Stride.Shaders.LSP/SemanticTokensHandler.cs create mode 100644 src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj create mode 100644 src/Stride.Shaders.LSP/TextDocumentHandler.cs diff --git a/SDSL.sln b/SDSL.sln index 7089b075b7..5445c8ada3 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing", "s EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{92AE8C5F-4A4F-4A97-9561-86315D09F910}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{DA4DEF22-680A-4763-8016-5E62A7BEA975}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -26,9 +28,14 @@ Global {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Debug|Any CPU.Build.0 = Debug|Any CPU {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Release|Any CPU.ActiveCfg = Release|Any CPU {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Release|Any CPU.Build.0 = Release|Any CPU + {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {66A8722A-4CE8-422D-9467-7B2C8FCB4734} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {92AE8C5F-4A4F-4A97-9561-86315D09F910} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {DA4DEF22-680A-4763-8016-5E62A7BEA975} = {9967EA99-9716-43A9-B6BA-E5975F08250D} EndGlobalSection EndGlobal diff --git a/src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs b/src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs new file mode 100644 index 0000000000..ac6d667806 --- /dev/null +++ b/src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs @@ -0,0 +1,18 @@ +using System.Threading; +using System.Threading.Tasks; +using MediatR; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; + +namespace Stride.Shaders.Parsing.LSP; + + +internal class DidChangeWatchedFilesHandler : IDidChangeWatchedFilesHandler +{ + public DidChangeWatchedFilesRegistrationOptions GetRegistrationOptions() => new DidChangeWatchedFilesRegistrationOptions(); + + public Task Handle(DidChangeWatchedFilesParams request, CancellationToken cancellationToken) => Unit.Task; + + public DidChangeWatchedFilesRegistrationOptions GetRegistrationOptions(DidChangeWatchedFilesCapability capability, ClientCapabilities clientCapabilities) => new DidChangeWatchedFilesRegistrationOptions(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/FoldingRangeHandler.cs b/src/Stride.Shaders.LSP/FoldingRangeHandler.cs new file mode 100644 index 0000000000..7fa6e63b51 --- /dev/null +++ b/src/Stride.Shaders.LSP/FoldingRangeHandler.cs @@ -0,0 +1,39 @@ +using System.Threading; +using System.Threading.Tasks; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + + +namespace Stride.Shaders.Parsing.LSP; + +internal class FoldingRangeHandler : IFoldingRangeHandler +{ + public FoldingRangeRegistrationOptions GetRegistrationOptions() => + new FoldingRangeRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") + }; + + public Task?> Handle( + FoldingRangeRequestParam request, + CancellationToken cancellationToken + ) => + Task.FromResult?>( + new Container( + new FoldingRange + { + StartLine = 10, + EndLine = 20, + Kind = FoldingRangeKind.Region, + EndCharacter = 0, + StartCharacter = 0 + } + ) + ); + + public FoldingRangeRegistrationOptions GetRegistrationOptions(FoldingRangeCapability capability, ClientCapabilities clientCapabilities) => new FoldingRangeRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") + }; +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/Foo.cs b/src/Stride.Shaders.LSP/Foo.cs new file mode 100644 index 0000000000..15bce05436 --- /dev/null +++ b/src/Stride.Shaders.LSP/Foo.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Logging; + +namespace Stride.Shaders.Parsing.LSP; + + +internal class Foo +{ + private readonly ILogger _logger; + + public Foo(ILogger logger) + { + logger.LogInformation("inside ctor"); + _logger = logger; + } + + public void SayFoo() + { + _logger.LogInformation("Fooooo!"); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/Program.cs b/src/Stride.Shaders.LSP/Program.cs new file mode 100644 index 0000000000..44c88e315f --- /dev/null +++ b/src/Stride.Shaders.LSP/Program.cs @@ -0,0 +1,159 @@ +// See https://aka.ms/new-console-template for more information +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Server; +using Serilog; +using Stride.Shaders.Parsing.LSP; + +await MainAsync(); + +static async Task MainAsync() +{ + Log.Logger = new LoggerConfiguration() + .Enrich.FromLogContext() + .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day) + .MinimumLevel.Verbose() + .CreateLogger(); + + Log.Logger.Information("This only goes file..."); + + IObserver workDone = null!; + + var server = await LanguageServer.From( + options => + options + .WithInput(Console.OpenStandardInput()) + .WithOutput(Console.OpenStandardOutput()) + .ConfigureLogging( + x => x + .AddSerilog(Log.Logger) + .AddLanguageProtocolLogging() + .SetMinimumLevel(LogLevel.Debug) + ) + .WithHandler() + .WithHandler() + .WithHandler() + .WithHandler() + .WithHandler() + .WithHandler() + .WithServices(x => x.AddLogging(b => b.SetMinimumLevel(LogLevel.Trace))) + .WithServices( + services => + { + services.AddSingleton( + provider => + { + var loggerFactory = provider.GetService(); + var logger = loggerFactory.CreateLogger(); + + logger.LogInformation("Configuring"); + + return new Foo(logger); + } + ); + services.AddSingleton( + new ConfigurationItem + { + Section = "typescript", + } + ).AddSingleton( + new ConfigurationItem + { + Section = "terminal", + } + ); + } + ) + .OnInitialize( + async (server, request, token) => + { + var manager = server.WorkDoneManager.For( + request, new WorkDoneProgressBegin + { + Title = "Server is starting...", + Percentage = 10, + } + ); + workDone = manager; + + await Task.Delay(2000).ConfigureAwait(false); + + manager.OnNext( + new WorkDoneProgressReport + { + Percentage = 20, + Message = "loading in progress" + } + ); + } + ) + .OnInitialized( + async (server, request, response, token) => + { + workDone.OnNext( + new WorkDoneProgressReport + { + Percentage = 40, + Message = "loading almost done", + } + ); + + await Task.Delay(2000).ConfigureAwait(false); + + workDone.OnNext( + new WorkDoneProgressReport + { + Message = "loading done", + Percentage = 100, + } + ); + workDone.OnCompleted(); + } + ) + .OnStarted( + async (languageServer, token) => + { + using var manager = await languageServer.WorkDoneManager.Create(new WorkDoneProgressBegin { Title = "Doing some work..." }) + .ConfigureAwait(false); + + manager.OnNext(new WorkDoneProgressReport { Message = "doing things..." }); + await Task.Delay(10000).ConfigureAwait(false); + manager.OnNext(new WorkDoneProgressReport { Message = "doing things... 1234" }); + await Task.Delay(10000).ConfigureAwait(false); + manager.OnNext(new WorkDoneProgressReport { Message = "doing things... 56789" }); + + var logger = languageServer.Services.GetService>(); + var configuration = await languageServer.Configuration.GetConfiguration( + new ConfigurationItem + { + Section = "typescript", + }, new ConfigurationItem + { + Section = "terminal", + } + ).ConfigureAwait(false); + + var baseConfig = new JObject(); + foreach (var config in languageServer.Configuration.AsEnumerable()) + { + baseConfig.Add(config.Key, config.Value); + } + + logger.LogInformation("Base Config: {@Config}", baseConfig); + + var scopedConfig = new JObject(); + foreach (var config in configuration.AsEnumerable()) + { + scopedConfig.Add(config.Key, config.Value); + } + + logger.LogInformation("Scoped Config: {@Config}", scopedConfig); + } + ) + ).ConfigureAwait(false); + + await server.WaitForExit.ConfigureAwait(false); +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/SemanticTokensHandler.cs b/src/Stride.Shaders.LSP/SemanticTokensHandler.cs new file mode 100644 index 0000000000..6f0c3f0620 --- /dev/null +++ b/src/Stride.Shaders.LSP/SemanticTokensHandler.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + + +namespace Stride.Shaders.Parsing.LSP; + +public class SemanticTokensHandler : SemanticTokensHandlerBase +{ + private readonly ILogger _logger; + + public SemanticTokensHandler(ILogger logger) + { + _logger = logger; + } + + public override async Task Handle( + SemanticTokensParams request, CancellationToken cancellationToken + ) + { + var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); + return result; + } + + public override async Task Handle( + SemanticTokensRangeParams request, CancellationToken cancellationToken + ) + { + var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); + return result; + } + + public override async Task Handle( + SemanticTokensDeltaParams request, + CancellationToken cancellationToken + ) + { + var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); + return result; + } + + protected override async Task Tokenize( + SemanticTokensBuilder builder, ITextDocumentIdentifierParams identifier, + CancellationToken cancellationToken + ) + { + using var typesEnumerator = RotateEnum(SemanticTokenType.Defaults).GetEnumerator(); + using var modifiersEnumerator = RotateEnum(SemanticTokenModifier.Defaults).GetEnumerator(); + // you would normally get this from a common source that is managed by current open editor, current active editor, etc. + var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(identifier), cancellationToken).ConfigureAwait(false); + await Task.Yield(); + + foreach (var (line, text) in content.Split('\n').Select((text, line) => (line, text))) + { + var parts = text.TrimEnd().Split(';', ' ', '.', '"', '(', ')'); + var index = 0; + foreach (var part in parts) + { + typesEnumerator.MoveNext(); + modifiersEnumerator.MoveNext(); + if (string.IsNullOrWhiteSpace(part)) continue; + index = text.IndexOf(part, index, StringComparison.Ordinal); + builder.Push(line, index, part.Length, typesEnumerator.Current, modifiersEnumerator.Current); + } + } + } + + protected override Task + GetSemanticTokensDocument(ITextDocumentIdentifierParams @params, CancellationToken cancellationToken) + { + return Task.FromResult(new SemanticTokensDocument(RegistrationOptions.Legend)); + } + + + private IEnumerable RotateEnum(IEnumerable values) + { + while (true) + { + foreach (var item in values) + yield return item; + } + } + + protected override SemanticTokensRegistrationOptions CreateRegistrationOptions( + SemanticTokensCapability capability, ClientCapabilities clientCapabilities + ) + { + return new SemanticTokensRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForLanguage("csharp"), + Legend = new SemanticTokensLegend + { + TokenModifiers = capability.TokenModifiers, + TokenTypes = capability.TokenTypes + }, + Full = new SemanticTokensCapabilityRequestFull + { + Delta = true + }, + Range = true + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj new file mode 100644 index 0000000000..ac44e4e6aa --- /dev/null +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + diff --git a/src/Stride.Shaders.LSP/TextDocumentHandler.cs b/src/Stride.Shaders.LSP/TextDocumentHandler.cs new file mode 100644 index 0000000000..d8f06e2bb9 --- /dev/null +++ b/src/Stride.Shaders.LSP/TextDocumentHandler.cs @@ -0,0 +1,262 @@ +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using MediatR; +using Microsoft.Extensions.Logging; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using OmniSharp.Extensions.LanguageServer.Protocol.Progress; +using OmniSharp.Extensions.LanguageServer.Protocol.Server; +using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone; +using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; +using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range; + +namespace Stride.Shaders.Parsing.LSP; + +internal class TextDocumentHandler : TextDocumentSyncHandlerBase +{ + private readonly ILogger _logger; + private readonly ILanguageServerConfiguration _configuration; + + private readonly TextDocumentSelector _textDocumentSelector = new TextDocumentSelector( + new TextDocumentFilter + { + Pattern = "**/*.sdsl" + } + ); + + public TextDocumentHandler(ILogger logger, Foo foo, ILanguageServerConfiguration configuration) + { + _logger = logger; + _configuration = configuration; + foo.SayFoo(); + } + + public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Full; + + public override Task Handle(DidChangeTextDocumentParams notification, CancellationToken token) + { + _logger.LogCritical("Critical"); + _logger.LogDebug("Debug"); + _logger.LogTrace("Trace"); + _logger.LogInformation("Hello world!"); + return Unit.Task; + } + + public override async Task Handle(DidOpenTextDocumentParams notification, CancellationToken token) + { + await Task.Yield(); + _logger.LogInformation("Hello world!"); + await _configuration.GetScopedConfiguration(notification.TextDocument.Uri, token).ConfigureAwait(false); + return Unit.Value; + } + + public override Task Handle(DidCloseTextDocumentParams notification, CancellationToken token) + { + if (_configuration.TryGetScopedConfiguration(notification.TextDocument.Uri, out var disposable)) + { + disposable.Dispose(); + } + + return Unit.Task; + } + + public override Task Handle(DidSaveTextDocumentParams notification, CancellationToken token) => Unit.Task; + + protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(TextSynchronizationCapability capability, ClientCapabilities clientCapabilities) => new TextDocumentSyncRegistrationOptions() + { + DocumentSelector = _textDocumentSelector, + Change = Change, + Save = new SaveOptions() { IncludeText = true } + }; + + public override TextDocumentAttributes GetTextDocumentAttributes(DocumentUri uri) => new TextDocumentAttributes(uri, "csharp"); +} + +internal class MyDocumentSymbolHandler : IDocumentSymbolHandler +{ + public async Task Handle( + DocumentSymbolParams request, + CancellationToken cancellationToken + ) + { + // you would normally get this from a common source that is managed by current open editor, current active editor, etc. + var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(request), cancellationToken).ConfigureAwait(false); + var lines = content.Split('\n'); + var symbols = new List(); + for (var lineIndex = 0; lineIndex < lines.Length; lineIndex++) + { + var line = lines[lineIndex]; + var parts = line.Split(' ', '.', '(', ')', '{', '}', '[', ']', ';'); + var currentCharacter = 0; + foreach (var part in parts) + { + if (string.IsNullOrWhiteSpace(part)) + { + currentCharacter += part.Length + 1; + continue; + } + + symbols.Add( + new DocumentSymbol + { + Detail = part, + Deprecated = true, + Kind = SymbolKind.Field, + Tags = new[] { SymbolTag.Deprecated }, + Range = new Range( + new Position(lineIndex, currentCharacter), + new Position(lineIndex, currentCharacter + part.Length) + ), + SelectionRange = + new Range( + new Position(lineIndex, currentCharacter), + new Position(lineIndex, currentCharacter + part.Length) + ), + Name = part + } + ); + currentCharacter += part.Length + 1; + } + } + + // await Task.Delay(2000, cancellationToken); + return symbols; + } + + public DocumentSymbolRegistrationOptions GetRegistrationOptions(DocumentSymbolCapability capability, ClientCapabilities clientCapabilities) => new DocumentSymbolRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") + }; +} + +internal class MyWorkspaceSymbolsHandler : IWorkspaceSymbolsHandler +{ + private readonly IServerWorkDoneManager _serverWorkDoneManager; + private readonly IProgressManager _progressManager; + private readonly ILogger _logger; + + public MyWorkspaceSymbolsHandler(IServerWorkDoneManager serverWorkDoneManager, IProgressManager progressManager, ILogger logger) + { + _serverWorkDoneManager = serverWorkDoneManager; + _progressManager = progressManager; + _logger = logger; + } + + public async Task> Handle( + WorkspaceSymbolParams request, + CancellationToken cancellationToken + ) + { + using var reporter = _serverWorkDoneManager.For( + request, new WorkDoneProgressBegin + { + Cancellable = true, + Message = "This might take a while...", + Title = "Some long task....", + Percentage = 0 + } + ); + using var partialResults = _progressManager.For(request, cancellationToken); + if (partialResults != null) + { + await Task.Delay(2000, cancellationToken).ConfigureAwait(false); + + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 20 + } + ); + await Task.Delay(500, cancellationToken).ConfigureAwait(false); + + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 40 + } + ); + await Task.Delay(500, cancellationToken).ConfigureAwait(false); + + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 50 + } + ); + await Task.Delay(500, cancellationToken).ConfigureAwait(false); + + partialResults.OnNext( + [ + new WorkspaceSymbol { + ContainerName = "Partial Container", + Kind = SymbolKind.Constant, + Location = new Location { + Range = new Range( + new Position(2, 1), + new Position(2, 10) + ) + }, + Name = "Partial name" + } + ] + ); + + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 70 + } + ); + await Task.Delay(500, cancellationToken).ConfigureAwait(false); + + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 90 + } + ); + + partialResults.OnCompleted(); + return Array.Empty(); + } + + try + { + return new[] { + new WorkspaceSymbol { + ContainerName = "Container", + Kind = SymbolKind.Constant, + Location = new Location { + Range = new Range( + new Position(1, 1), + new Position(1, 10) + ) + }, + Name = "name" + } + }; + } + finally + { + reporter.OnNext( + new WorkDoneProgressReport + { + Cancellable = true, + Percentage = 100 + } + ); + } + } + + public WorkspaceSymbolRegistrationOptions GetRegistrationOptions(WorkspaceSymbolCapability capability, ClientCapabilities clientCapabilities) => new(); +} \ No newline at end of file From 5e37bf9df3ae2ac1010162010b25eb0fea2cfd97 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Mon, 8 Jul 2024 13:20:02 +0200 Subject: [PATCH 0296/1182] First example of coding HLSL using Silk.NET.D3DCompiler --- SDSL.sln | 7 +++ assets/HLSL/example.hlsl | 30 ++++++++++ src/Stride.Shaders.Compilers/Class1.cs | 6 ++ .../Stride.Shaders.Compilers.csproj | 19 +++++++ .../Program.cs | 56 ++++++++++++++++++- .../Stride.Shaders.Parsing.Experiments.csproj | 3 +- 6 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 assets/HLSL/example.hlsl create mode 100644 src/Stride.Shaders.Compilers/Class1.cs create mode 100644 src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj diff --git a/SDSL.sln b/SDSL.sln index 5445c8ada3..9e69321b4a 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Expe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{DA4DEF22-680A-4763-8016-5E62A7BEA975}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,10 +34,15 @@ Global {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Debug|Any CPU.Build.0 = Debug|Any CPU {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.ActiveCfg = Release|Any CPU {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.Build.0 = Release|Any CPU + {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {66A8722A-4CE8-422D-9467-7B2C8FCB4734} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {92AE8C5F-4A4F-4A97-9561-86315D09F910} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {DA4DEF22-680A-4763-8016-5E62A7BEA975} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D} = {9967EA99-9716-43A9-B6BA-E5975F08250D} EndGlobalSection EndGlobal diff --git a/assets/HLSL/example.hlsl b/assets/HLSL/example.hlsl new file mode 100644 index 0000000000..6c165d007c --- /dev/null +++ b/assets/HLSL/example.hlsl @@ -0,0 +1,30 @@ + +cbuffer cb : register(b0) +{ + float4x4 WorldViewProj; +}; + +struct VS_INPUT +{ + float4 Pos : POSITION; + float4 Color : COLOR; +}; + +struct PS_INPUT +{ + float4 Pos : SV_POSITION; + float4 Color : COLOR; +}; + +PS_INPUT VS(VS_INPUT input) +{ + PS_INPUT output = (PS_INPUT)0; + output.Pos = mul(input.Pos, WorldViewProj); + output.Color = input.Color; + return output; +} + +float4 PS(PS_INPUT input) : SV_Target +{ + return input.Color; +} diff --git a/src/Stride.Shaders.Compilers/Class1.cs b/src/Stride.Shaders.Compilers/Class1.cs new file mode 100644 index 0000000000..cb28f34d81 --- /dev/null +++ b/src/Stride.Shaders.Compilers/Class1.cs @@ -0,0 +1,6 @@ +namespace Stride.Shaders.Compilers; + +public class Class1 +{ + +} diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj new file mode 100644 index 0000000000..0f092c2b18 --- /dev/null +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + net8.0 + enable + enable + + + diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 3f6b8026dc..7a84cf24c0 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -1,6 +1,60 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Silk.NET.Direct3D.Compilers; +using Silk.NET.Core.Native; +using System.Text; Console.WriteLine("Hello world"); -Console.WriteLine(Directory.GetCurrentDirectory()); \ No newline at end of file +Console.WriteLine(Directory.GetCurrentDirectory()); + + +var d3d = D3DCompiler.GetApi(); +var utf_content = @" +struct PSInput +{ + float4 position : SV_POSITION; + float4 color; +}; + +PSInput VSMain(float4 position : POSITION, float4 color : COLOR) +{ + PSInput result; + + result.position = position; + result.color = color; + + return result; +} + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} + +"; + +var content = Encoding.ASCII.GetBytes(utf_content); +unsafe +{ + ID3D10Blob* shader; + ID3D10Blob* errorMsgs; + int res = 0; + fixed (byte* pContent = content) + { + res = d3d.Compile( + pSrcData: pContent, + SrcDataSize: (nuint)content.Length, + pSourceName: "triangle", + pDefines: null, + pInclude: null, + pEntrypoint: "VSMain", + pTarget: "vs_5_0", + Flags1: 0, + Flags2: 0, + ppCode: &shader, + ppErrorMsgs: &errorMsgs); + } + Console.WriteLine(Encoding.ASCII.GetString(errorMsgs->Buffer)); + SilkMarshal.ThrowHResult(res); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj index 370311e009..b54aab4b84 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj +++ b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj @@ -1,7 +1,7 @@  - + @@ -9,6 +9,7 @@ net8.0 enable enable + true From 383fc90985aa61b2ad724bc1ca97c5fa72f0df26 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Mon, 8 Jul 2024 17:02:37 +0200 Subject: [PATCH 0297/1182] Added code for spirv translator --- .../SpirvTranslator.cs | 36 ++++++ .../Stride.Shaders.Compilers.csproj | 2 + .../Program.cs | 108 +++++++++++++++++- 3 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SpirvTranslator.cs diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs new file mode 100644 index 0000000000..41685d59ef --- /dev/null +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -0,0 +1,36 @@ +using System.Linq.Expressions; +using System.Text; +using Silk.NET.Core.Native; +using Silk.NET.SPIRV.Cross; + +namespace Stride.Shaders.Compilers; + +public record struct SpirvTranslator(ReadOnlyMemory Words) +{ + static readonly Cross cross = Cross.GetApi(); + + public unsafe readonly string Translate(Backend backend = Backend.Hlsl) + { + var cross = Cross.GetApi(); + Context* context = null; + ParsedIr* ir = null; + Compiler* compiler = null; + Resources* resources = null; + byte* translated = null; + if (cross.ContextCreate(&context) != Result.Success) + throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); + + fixed(uint* w = Words.Span) + if(cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) + throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); + + if(cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) + throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + if(cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) + throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); + if (cross.CompilerCompile(compiler, &translated) != Result.Success) + throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); + var translatedCode = SilkMarshal.PtrToString((nint)translated); + return translatedCode ?? throw new Exception("Could not translate code"); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 0f092c2b18..5c87c0c3b0 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -7,6 +7,7 @@ + @@ -14,6 +15,7 @@ net8.0 enable enable + true diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 7a84cf24c0..0cbefde726 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -2,19 +2,115 @@ using Stride.Shaders.Parsing.SDSL.AST; using Silk.NET.Direct3D.Compilers; +using Silk.NET.SPIRV.Cross; using Silk.NET.Core.Native; using System.Text; +using Stride.Shaders.Compilers; Console.WriteLine("Hello world"); Console.WriteLine(Directory.GetCurrentDirectory()); +uint[] words = [ + // Offset 0x00000000 to 0x0000016F + 0x03022307, 0x00050100, 0x00000E00, + 0x0C000000, 0x00000000, 0x11000200, + 0x01000000, 0x0E000300, 0x00000000, + 0x01000000, 0x0F000700, 0x04000000, + 0x01000000, 0x50534D61, 0x696E0000, + 0x02000000, 0x03000000, 0x10000300, + 0x01000000, 0x07000000, 0x03000300, + 0x05000000, 0x58020000, 0x05000600, + 0x02000000, 0x696E2E76, 0x61722E43, + 0x4F4C4F52, 0x00000000, 0x05000700, + 0x03000000, 0x6F75742E, 0x7661722E, + 0x53565F54, 0x41524745, 0x54000000, + 0x05000400, 0x01000000, 0x50534D61, + 0x696E0000, 0x47000400, 0x02000000, + 0x1E000000, 0x00000000, 0x47000400, + 0x03000000, 0x1E000000, 0x00000000, + 0x16000300, 0x04000000, 0x20000000, + 0x17000400, 0x05000000, 0x04000000, + 0x04000000, 0x20000400, 0x06000000, + 0x01000000, 0x05000000, 0x20000400, + 0x07000000, 0x03000000, 0x05000000, + 0x13000200, 0x08000000, 0x21000300, + 0x09000000, 0x08000000, 0x3B000400, + 0x06000000, 0x02000000, 0x01000000, + 0x3B000400, 0x07000000, 0x03000000, + 0x03000000, 0x36000500, 0x08000000, + 0x01000000, 0x00000000, 0x09000000, + 0xF8000200, 0x0A000000, 0x3D000400, + 0x05000000, 0x0B000000, 0x02000000, + 0x3E000300, 0x03000000, 0x0B000000, + 0xFD000100, 0x38000100 +]; + +unsafe +{ + var code = new SpirvTranslator(words.AsMemory()); + Console.WriteLine(code.Translate(Backend.Glsl)); + // var cross = Cross.GetApi(); + // Context* context = null; + // cross.ContextCreate(&context); + // ParsedIr* ir = null; + // Result res = Result.Success; + // fixed (uint* w = words) + // res = cross.ContextParseSpirv(context, w, (nuint)words.Length, &ir); + + // Compiler* compiler = null; + // Resources* resources = null; + // ReflectedResource* resourceList = null; + // nuint size = 0; + // res = cross.ContextCreateCompiler(context, Backend.Glsl, ir, CaptureMode.Copy, &compiler); + // res = cross.CompilerCreateShaderResources(compiler, &resources); + // res = cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourceList, &size); + // for (int i = 0; i < (int)size; i++) + // { + // var name = new Span(resourceList[i].Name, (int)size); + // Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", resourceList[i].Id, resourceList[i].BaseTypeId, resourceList[i].TypeId, name.ToString()); + + // uint set = cross.CompilerGetDecoration(compiler, resourceList[i].Id, Silk.NET.SPIRV.Decoration.DescriptorSet); + // Console.WriteLine($"Set: {set}"); + + // uint binding = cross.CompilerGetDecoration(compiler, resourceList[i].Id, Silk.NET.SPIRV.Decoration.Binding); + // Console.WriteLine($"Binding: {binding}"); + + // Console.WriteLine("========="); + // } + // string GetString(byte* ptr) + // { + // int length = 0; + // while (length < 4096 && ptr[length] != 0) + // length++; + // // Decode UTF-8 bytes to string. + // return Encoding.UTF8.GetString(ptr, length); + // } + // byte* translated = null; + // cross.CompilerCompile(compiler, &translated); + // Console.WriteLine(GetString(translated)); + var x = 0; + +} + +// var d3d = D3DCompiler.GetApi(); + +// var dxc = DXC.GetApi(); +// unsafe +// { +// IDxcCompilerArgs* a = null; +// IDxcOperationResult* operationResult = null; +// var cid = IDxcCompiler.Guid; +// SilkMarshal.ThrowHResult( +// dxc.CreateInstance(ref cid, out ComPtr compiler) +// ); +// var x = 0; +// } -var d3d = D3DCompiler.GetApi(); var utf_content = @" struct PSInput { float4 position : SV_POSITION; - float4 color; + float4 color : COLOR; }; PSInput VSMain(float4 position : POSITION, float4 color : COLOR) @@ -34,9 +130,12 @@ float4 PSMain(PSInput input) : SV_TARGET "; + + var content = Encoding.ASCII.GetBytes(utf_content); unsafe { + D3DCompiler d3d = D3DCompiler.GetApi(); ID3D10Blob* shader; ID3D10Blob* errorMsgs; int res = 0; @@ -49,7 +148,7 @@ float4 PSMain(PSInput input) : SV_TARGET pDefines: null, pInclude: null, pEntrypoint: "VSMain", - pTarget: "vs_5_0", + pTarget: "vs_6_0", Flags1: 0, Flags2: 0, ppCode: &shader, @@ -57,4 +156,5 @@ float4 PSMain(PSInput input) : SV_TARGET } Console.WriteLine(Encoding.ASCII.GetString(errorMsgs->Buffer)); SilkMarshal.ThrowHResult(res); -} \ No newline at end of file +} + From f16a2d587a5b6da90495bfe98ef18af1c5e191b0 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Mon, 8 Jul 2024 17:36:57 +0200 Subject: [PATCH 0298/1182] trying to free memory from spirv --- .../SpirvTranslator.cs | 35 +++- .../Examples.cs | 132 ++++++++++++++++ .../Program.cs | 149 +----------------- 3 files changed, 168 insertions(+), 148 deletions(-) create mode 100644 src/Stride.Shaders.Parsing.Experiments/Examples.cs diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 41685d59ef..7e6ee58a45 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -1,4 +1,5 @@ using System.Linq.Expressions; +using System.Runtime.InteropServices; using System.Text; using Silk.NET.Core.Native; using Silk.NET.SPIRV.Cross; @@ -11,7 +12,6 @@ public record struct SpirvTranslator(ReadOnlyMemory Words) public unsafe readonly string Translate(Backend backend = Backend.Hlsl) { - var cross = Cross.GetApi(); Context* context = null; ParsedIr* ir = null; Compiler* compiler = null; @@ -31,6 +31,39 @@ public unsafe readonly string Translate(Backend backend = Backend.Hlsl) if (cross.CompilerCompile(compiler, &translated) != Result.Success) throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); var translatedCode = SilkMarshal.PtrToString((nint)translated); + return translatedCode ?? throw new Exception("Could not translate code"); } + public unsafe readonly void TranslateWithoutReturn(Backend backend = Backend.Hlsl) + { + Context* context = null; + ParsedIr* ir = null; + Compiler* compiler = null; + Resources* resources = null; + byte* translated = null; + if (cross.ContextCreate(&context) != Result.Success) + throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); + fixed(uint* w = Words.Span) + if(cross.ContextParseSpirv(context, w, (nuint)Words.Length, ref ir) != Result.Success) + throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, ref ir)} : Could not parse spirv"); + Marshal.FreeHGlobal((nint)context); + Marshal.FreeHGlobal(ir); + SilkMarshal.Free((nint)ir); + + // if(cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) + // throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + // if(cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) + // throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); + // if (cross.CompilerCompile(compiler, &translated) != Result.Success) + // throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); + + // Marshal.FreeHGlobal((nint)compiler); + // Marshal.FreeHGlobal((nint)resources); + // Marshal.FreeHGlobal((nint)ir); + // Marshal.FreeHGlobal((nint)context); + // Marshal.FreeHGlobal((nint)translated); + // var translatedCode = SilkMarshal.PtrToString((nint)translated); + + // return translatedCode ?? throw new Exception("Could not translate code"); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs new file mode 100644 index 0000000000..ee2f473747 --- /dev/null +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -0,0 +1,132 @@ +using System.Text; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; +using Silk.NET.SPIRV.Cross; +using Stride.Shaders.Compilers; + +namespace Stride.Shaders.Experiments; + +public static class Examples +{ + static uint[] words = [ + // Offset 0x00000000 to 0x0000016F + 0x03022307, 0x00050100, 0x00000E00, + 0x0C000000, 0x00000000, 0x11000200, + 0x01000000, 0x0E000300, 0x00000000, + 0x01000000, 0x0F000700, 0x04000000, + 0x01000000, 0x50534D61, 0x696E0000, + 0x02000000, 0x03000000, 0x10000300, + 0x01000000, 0x07000000, 0x03000300, + 0x05000000, 0x58020000, 0x05000600, + 0x02000000, 0x696E2E76, 0x61722E43, + 0x4F4C4F52, 0x00000000, 0x05000700, + 0x03000000, 0x6F75742E, 0x7661722E, + 0x53565F54, 0x41524745, 0x54000000, + 0x05000400, 0x01000000, 0x50534D61, + 0x696E0000, 0x47000400, 0x02000000, + 0x1E000000, 0x00000000, 0x47000400, + 0x03000000, 0x1E000000, 0x00000000, + 0x16000300, 0x04000000, 0x20000000, + 0x17000400, 0x05000000, 0x04000000, + 0x04000000, 0x20000400, 0x06000000, + 0x01000000, 0x05000000, 0x20000400, + 0x07000000, 0x03000000, 0x05000000, + 0x13000200, 0x08000000, 0x21000300, + 0x09000000, 0x08000000, 0x3B000400, + 0x06000000, 0x02000000, 0x01000000, + 0x3B000400, 0x07000000, 0x03000000, + 0x03000000, 0x36000500, 0x08000000, + 0x01000000, 0x00000000, 0x09000000, + 0xF8000200, 0x0A000000, 0x3D000400, + 0x05000000, 0x0B000000, 0x02000000, + 0x3E000300, 0x03000000, 0x0B000000, + 0xFD000100, 0x38000100 + ]; + public static void UseSpirvCross() + { + unsafe + { + var code = new SpirvTranslator(words.AsMemory()); + Console.WriteLine(code.Translate(Backend.Glsl)); + } + } + public static void UseSpirvCrossWhile() + { + unsafe + { + var code = new SpirvTranslator(words.AsMemory()); + while (true) + code.TranslateWithoutReturn(Backend.Glsl); + } + } + + public static void CompileHLSL() + { + + // var d3d = D3DCompiler.GetApi(); + + // var dxc = DXC.GetApi(); + // unsafe + // { + // IDxcCompilerArgs* a = null; + // IDxcOperationResult* operationResult = null; + // var cid = IDxcCompiler.Guid; + // SilkMarshal.ThrowHResult( + // dxc.CreateInstance(ref cid, out ComPtr compiler) + // ); + // var x = 0; + // } + + var utf_content = @" +struct PSInput +{ + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +PSInput VSMain(float4 position : POSITION, float4 color : COLOR) +{ + PSInput result; + + result.position = position; + result.color = color; + + return result; +} + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} + +"; + + + + var content = Encoding.ASCII.GetBytes(utf_content); + unsafe + { + D3DCompiler d3d = D3DCompiler.GetApi(); + ID3D10Blob* shader; + ID3D10Blob* errorMsgs; + int res = 0; + fixed (byte* pContent = content) + { + res = d3d.Compile( + pSrcData: pContent, + SrcDataSize: (nuint)content.Length, + pSourceName: "triangle", + pDefines: null, + pInclude: null, + pEntrypoint: "VSMain", + pTarget: "vs_6_0", + Flags1: 0, + Flags2: 0, + ppCode: &shader, + ppErrorMsgs: &errorMsgs); + } + Console.WriteLine(Encoding.ASCII.GetString(errorMsgs->Buffer)); + SilkMarshal.ThrowHResult(res); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 0cbefde726..67e8e2f93e 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -6,155 +6,10 @@ using Silk.NET.Core.Native; using System.Text; using Stride.Shaders.Compilers; +using Stride.Shaders.Experiments; Console.WriteLine("Hello world"); Console.WriteLine(Directory.GetCurrentDirectory()); -uint[] words = [ - // Offset 0x00000000 to 0x0000016F - 0x03022307, 0x00050100, 0x00000E00, - 0x0C000000, 0x00000000, 0x11000200, - 0x01000000, 0x0E000300, 0x00000000, - 0x01000000, 0x0F000700, 0x04000000, - 0x01000000, 0x50534D61, 0x696E0000, - 0x02000000, 0x03000000, 0x10000300, - 0x01000000, 0x07000000, 0x03000300, - 0x05000000, 0x58020000, 0x05000600, - 0x02000000, 0x696E2E76, 0x61722E43, - 0x4F4C4F52, 0x00000000, 0x05000700, - 0x03000000, 0x6F75742E, 0x7661722E, - 0x53565F54, 0x41524745, 0x54000000, - 0x05000400, 0x01000000, 0x50534D61, - 0x696E0000, 0x47000400, 0x02000000, - 0x1E000000, 0x00000000, 0x47000400, - 0x03000000, 0x1E000000, 0x00000000, - 0x16000300, 0x04000000, 0x20000000, - 0x17000400, 0x05000000, 0x04000000, - 0x04000000, 0x20000400, 0x06000000, - 0x01000000, 0x05000000, 0x20000400, - 0x07000000, 0x03000000, 0x05000000, - 0x13000200, 0x08000000, 0x21000300, - 0x09000000, 0x08000000, 0x3B000400, - 0x06000000, 0x02000000, 0x01000000, - 0x3B000400, 0x07000000, 0x03000000, - 0x03000000, 0x36000500, 0x08000000, - 0x01000000, 0x00000000, 0x09000000, - 0xF8000200, 0x0A000000, 0x3D000400, - 0x05000000, 0x0B000000, 0x02000000, - 0x3E000300, 0x03000000, 0x0B000000, - 0xFD000100, 0x38000100 -]; - -unsafe -{ - var code = new SpirvTranslator(words.AsMemory()); - Console.WriteLine(code.Translate(Backend.Glsl)); - // var cross = Cross.GetApi(); - // Context* context = null; - // cross.ContextCreate(&context); - // ParsedIr* ir = null; - // Result res = Result.Success; - // fixed (uint* w = words) - // res = cross.ContextParseSpirv(context, w, (nuint)words.Length, &ir); - - // Compiler* compiler = null; - // Resources* resources = null; - // ReflectedResource* resourceList = null; - // nuint size = 0; - // res = cross.ContextCreateCompiler(context, Backend.Glsl, ir, CaptureMode.Copy, &compiler); - // res = cross.CompilerCreateShaderResources(compiler, &resources); - // res = cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourceList, &size); - // for (int i = 0; i < (int)size; i++) - // { - // var name = new Span(resourceList[i].Name, (int)size); - // Console.WriteLine("ID: {0}, BaseTypeID: {1}, TypeID: {2}, Name: {3}", resourceList[i].Id, resourceList[i].BaseTypeId, resourceList[i].TypeId, name.ToString()); - - // uint set = cross.CompilerGetDecoration(compiler, resourceList[i].Id, Silk.NET.SPIRV.Decoration.DescriptorSet); - // Console.WriteLine($"Set: {set}"); - - // uint binding = cross.CompilerGetDecoration(compiler, resourceList[i].Id, Silk.NET.SPIRV.Decoration.Binding); - // Console.WriteLine($"Binding: {binding}"); - - // Console.WriteLine("========="); - // } - // string GetString(byte* ptr) - // { - // int length = 0; - // while (length < 4096 && ptr[length] != 0) - // length++; - // // Decode UTF-8 bytes to string. - // return Encoding.UTF8.GetString(ptr, length); - // } - // byte* translated = null; - // cross.CompilerCompile(compiler, &translated); - // Console.WriteLine(GetString(translated)); - var x = 0; - -} - -// var d3d = D3DCompiler.GetApi(); - -// var dxc = DXC.GetApi(); -// unsafe -// { -// IDxcCompilerArgs* a = null; -// IDxcOperationResult* operationResult = null; -// var cid = IDxcCompiler.Guid; -// SilkMarshal.ThrowHResult( -// dxc.CreateInstance(ref cid, out ComPtr compiler) -// ); -// var x = 0; -// } - -var utf_content = @" -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VSMain(float4 position : POSITION, float4 color : COLOR) -{ - PSInput result; - - result.position = position; - result.color = color; - - return result; -} - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} - -"; - - - -var content = Encoding.ASCII.GetBytes(utf_content); -unsafe -{ - D3DCompiler d3d = D3DCompiler.GetApi(); - ID3D10Blob* shader; - ID3D10Blob* errorMsgs; - int res = 0; - fixed (byte* pContent = content) - { - res = d3d.Compile( - pSrcData: pContent, - SrcDataSize: (nuint)content.Length, - pSourceName: "triangle", - pDefines: null, - pInclude: null, - pEntrypoint: "VSMain", - pTarget: "vs_6_0", - Flags1: 0, - Flags2: 0, - ppCode: &shader, - ppErrorMsgs: &errorMsgs); - } - Console.WriteLine(Encoding.ASCII.GetString(errorMsgs->Buffer)); - SilkMarshal.ThrowHResult(res); -} +Examples.UseSpirvCrossWhile(); \ No newline at end of file From bffe2497f7de237ae3c39e64a76b320564d80bd1 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Mon, 8 Jul 2024 18:46:40 +0200 Subject: [PATCH 0299/1182] working on FXC Compiler --- src/Stride.Shaders.Compilers/Class1.cs | 6 -- src/Stride.Shaders.Compilers/FXC.cs | 40 ++++++++++ src/Stride.Shaders.Compilers/MainMethod.cs | 10 +++ .../SpirvTranslator.cs | 76 ++++++------------- .../Examples.cs | 11 +-- .../Program.cs | 2 +- 6 files changed, 76 insertions(+), 69 deletions(-) delete mode 100644 src/Stride.Shaders.Compilers/Class1.cs create mode 100644 src/Stride.Shaders.Compilers/FXC.cs create mode 100644 src/Stride.Shaders.Compilers/MainMethod.cs diff --git a/src/Stride.Shaders.Compilers/Class1.cs b/src/Stride.Shaders.Compilers/Class1.cs deleted file mode 100644 index cb28f34d81..0000000000 --- a/src/Stride.Shaders.Compilers/Class1.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Stride.Shaders.Compilers; - -public class Class1 -{ - -} diff --git a/src/Stride.Shaders.Compilers/FXC.cs b/src/Stride.Shaders.Compilers/FXC.cs new file mode 100644 index 0000000000..d4addea8c6 --- /dev/null +++ b/src/Stride.Shaders.Compilers/FXC.cs @@ -0,0 +1,40 @@ +using System.Text; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; + +namespace Stride.Shaders.Compilers; + + + + +public record struct FXCompiler(string Code) +{ + static D3DCompiler d3d = D3DCompiler.GetApi(); + + public readonly void Compile() + { + var content = Encoding.ASCII.GetBytes(Code); + unsafe + { + // ComPtr shader; + // ComPtr errorMsgs; + // int res = 0; + // fixed(byte* pContent = content) + // res = d3d.Compile( + // pSrcData: pContent, + // SrcDataSize: (nuint)content.Length, + // // pSourceName: "triangle", + // pDefines: null, + // pInclude: null, + // pEntrypoint: "VSMain", + // pTarget: "vs_5_0", + // Flags1: 0, + // Flags2: 0, + // ppCode: &shader, + // ppErrorMsgs: &errorMsgs); + + // Console.WriteLine(Encoding.ASCII.GetString(errorMsgs.Get().Buffer)); + // SilkMarshal.ThrowHResult(res); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/MainMethod.cs b/src/Stride.Shaders.Compilers/MainMethod.cs new file mode 100644 index 0000000000..1ccc34ea78 --- /dev/null +++ b/src/Stride.Shaders.Compilers/MainMethod.cs @@ -0,0 +1,10 @@ +namespace Stride.Shaders.Compilers; + +public enum CompilerShaderStage +{ + Vertex, + Pixel, + Hull, + Domain, + Compute +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 7e6ee58a45..74dff26fdc 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -10,60 +10,32 @@ public record struct SpirvTranslator(ReadOnlyMemory Words) { static readonly Cross cross = Cross.GetApi(); - public unsafe readonly string Translate(Backend backend = Backend.Hlsl) + public readonly string Translate(Backend backend = Backend.Hlsl) { - Context* context = null; - ParsedIr* ir = null; - Compiler* compiler = null; - Resources* resources = null; - byte* translated = null; - if (cross.ContextCreate(&context) != Result.Success) - throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); - - fixed(uint* w = Words.Span) - if(cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) - throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); - - if(cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) - throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); - if(cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) - throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); - if (cross.CompilerCompile(compiler, &translated) != Result.Success) - throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); - var translatedCode = SilkMarshal.PtrToString((nint)translated); + string? translatedCode = null; + unsafe + { + Context* context = null; + ParsedIr* ir = null; + Compiler* compiler = null; + Resources* resources = null; + byte* translated = null; + if (cross.ContextCreate(&context) != Result.Success) + throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); + fixed (uint* w = Words.Span) + if (cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) + throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); + if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) + throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) + throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); + if (cross.CompilerCompile(compiler, &translated) != Result.Success) + throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); + translatedCode = SilkMarshal.PtrToString((nint)translated); + cross.ContextReleaseAllocations(context); + cross.ContextDestroy(context); + } return translatedCode ?? throw new Exception("Could not translate code"); } - public unsafe readonly void TranslateWithoutReturn(Backend backend = Backend.Hlsl) - { - Context* context = null; - ParsedIr* ir = null; - Compiler* compiler = null; - Resources* resources = null; - byte* translated = null; - if (cross.ContextCreate(&context) != Result.Success) - throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); - fixed(uint* w = Words.Span) - if(cross.ContextParseSpirv(context, w, (nuint)Words.Length, ref ir) != Result.Success) - throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, ref ir)} : Could not parse spirv"); - Marshal.FreeHGlobal((nint)context); - Marshal.FreeHGlobal(ir); - SilkMarshal.Free((nint)ir); - - // if(cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) - // throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); - // if(cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) - // throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); - // if (cross.CompilerCompile(compiler, &translated) != Result.Success) - // throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); - - // Marshal.FreeHGlobal((nint)compiler); - // Marshal.FreeHGlobal((nint)resources); - // Marshal.FreeHGlobal((nint)ir); - // Marshal.FreeHGlobal((nint)context); - // Marshal.FreeHGlobal((nint)translated); - // var translatedCode = SilkMarshal.PtrToString((nint)translated); - - // return translatedCode ?? throw new Exception("Could not translate code"); - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index ee2f473747..17bd54a8f0 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -47,16 +47,7 @@ public static void UseSpirvCross() unsafe { var code = new SpirvTranslator(words.AsMemory()); - Console.WriteLine(code.Translate(Backend.Glsl)); - } - } - public static void UseSpirvCrossWhile() - { - unsafe - { - var code = new SpirvTranslator(words.AsMemory()); - while (true) - code.TranslateWithoutReturn(Backend.Glsl); + Console.WriteLine(code.Translate(Backend.Hlsl)); } } diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 67e8e2f93e..f42fd517ca 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,4 @@ Console.WriteLine(Directory.GetCurrentDirectory()); -Examples.UseSpirvCrossWhile(); \ No newline at end of file +Examples.UseSpirvCross(); \ No newline at end of file From a1820cfc581e76ef59b86e3236758338e5d1b74e Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 9 Jul 2024 16:40:13 +0200 Subject: [PATCH 0300/1182] adding brower example perhaps --- src/Stride.Shaders.Compilers/DXC.cs | 57 ++++++++++++++++ .../SpirvTranslator.cs | 3 +- .../Stride.Shaders.Compilers.csproj | 1 + .../Examples.cs | 67 +------------------ .../Program.cs | 2 +- 5 files changed, 63 insertions(+), 67 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/DXC.cs diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs new file mode 100644 index 0000000000..a16c692b51 --- /dev/null +++ b/src/Stride.Shaders.Compilers/DXC.cs @@ -0,0 +1,57 @@ +using System.Text; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; + +namespace Stride.Shaders.Compilers; + + + + +public record struct DXCompiler(string Code) +{ + + static string sampleCode = @" +struct PSInput +{ + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +PSInput VSMain(float4 position : POSITION, float4 color : COLOR) +{ + PSInput result; + + result.position = position; + result.color = color; + + return result; +} + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} + +"; + static DXC dxc = DXC.GetApi(); + + public readonly void Compile() + { + // var content = Encoding.ASCII.GetBytes(Code); + unsafe + { + Guid id = IDxcCompiler.Guid; + Guid libId = IDxcCompiler3.Guid; + SilkMarshal.ThrowHResult(dxc.CreateInstance(&id, out ComPtr compiler)); + SilkMarshal.ThrowHResult(dxc.CreateInstance(&libId, out ComPtr library)); + Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); + IDxcBlobEncoding* sourceBlob = null; + fixed (char* ptr = Code.AsSpan()) + SilkMarshal.ThrowHResult(library.Get().CreateBlobWithEncodingFromPinned(ptr, (uint)Code.Length, 0, &sourceBlob)); + + // IDxcOperationResult* result = null; + // SilkMarshal.ThrowHResult(compiler.Get().Compile((IDxcBlob*)sourceBlob, (string)null!, (char*)SilkMarshal.StringToPtr("PSMain"), (char*)SilkMarshal.StringToPtr(""), (char**)SilkMarshal.StringArrayToPtr(["-spirv","-T", "ps_6_0"]), 3, null, 0, null, &result)); + // Console.WriteLine((nint)result); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 74dff26fdc..8b4bc7695b 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -38,4 +38,5 @@ public readonly string Translate(Backend backend = Backend.Hlsl) } return translatedCode ?? throw new Exception("Could not translate code"); } -} \ No newline at end of file +} + diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 5c87c0c3b0..7eb94c13ff 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -7,6 +7,7 @@ + diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 17bd54a8f0..8296656648 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -54,70 +54,7 @@ public static void UseSpirvCross() public static void CompileHLSL() { - // var d3d = D3DCompiler.GetApi(); - - // var dxc = DXC.GetApi(); - // unsafe - // { - // IDxcCompilerArgs* a = null; - // IDxcOperationResult* operationResult = null; - // var cid = IDxcCompiler.Guid; - // SilkMarshal.ThrowHResult( - // dxc.CreateInstance(ref cid, out ComPtr compiler) - // ); - // var x = 0; - // } - - var utf_content = @" -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VSMain(float4 position : POSITION, float4 color : COLOR) -{ - PSInput result; - - result.position = position; - result.color = color; - - return result; -} - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} - -"; - - - - var content = Encoding.ASCII.GetBytes(utf_content); - unsafe - { - D3DCompiler d3d = D3DCompiler.GetApi(); - ID3D10Blob* shader; - ID3D10Blob* errorMsgs; - int res = 0; - fixed (byte* pContent = content) - { - res = d3d.Compile( - pSrcData: pContent, - SrcDataSize: (nuint)content.Length, - pSourceName: "triangle", - pDefines: null, - pInclude: null, - pEntrypoint: "VSMain", - pTarget: "vs_6_0", - Flags1: 0, - Flags2: 0, - ppCode: &shader, - ppErrorMsgs: &errorMsgs); - } - Console.WriteLine(Encoding.ASCII.GetString(errorMsgs->Buffer)); - SilkMarshal.ThrowHResult(res); - } + var dxc = new DXCompiler(); + dxc.Compile(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index f42fd517ca..34bc5c00ba 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,4 @@ Console.WriteLine(Directory.GetCurrentDirectory()); -Examples.UseSpirvCross(); \ No newline at end of file +Examples.CompileHLSL(); \ No newline at end of file From 36e9d1a4356cd06042e7eb96f21ccee4c5808c1a Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 9 Jul 2024 17:51:20 +0200 Subject: [PATCH 0301/1182] Recreated the extension --- SDSL.sln | 7 +++++++ src/Stride.Shaders.Compilers/DXC.cs | 1 + src/Stride.Shaders.LSP.Test/Program.cs | 2 ++ .../Stride.Shaders.LSP.Test.csproj | 10 ++++++++++ src/Stride.Shaders.LSP/Program.cs | 6 +++--- src/Stride.Shaders.LSP/log20240709.txt | 4 ++++ 6 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 src/Stride.Shaders.LSP.Test/Program.cs create mode 100644 src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj create mode 100644 src/Stride.Shaders.LSP/log20240709.txt diff --git a/SDSL.sln b/SDSL.sln index 9e69321b4a..7da21d21ea 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -13,6 +13,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\S EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{55190824-293F-49AA-B068-95F69E949055}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,11 +40,16 @@ Global {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Debug|Any CPU.Build.0 = Debug|Any CPU {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.ActiveCfg = Release|Any CPU {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.Build.0 = Release|Any CPU + {55190824-293F-49AA-B068-95F69E949055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55190824-293F-49AA-B068-95F69E949055}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {66A8722A-4CE8-422D-9467-7B2C8FCB4734} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {92AE8C5F-4A4F-4A97-9561-86315D09F910} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {DA4DEF22-680A-4763-8016-5E62A7BEA975} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {55190824-293F-49AA-B068-95F69E949055} = {9967EA99-9716-43A9-B6BA-E5975F08250D} EndGlobalSection EndGlobal diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs index a16c692b51..2d8e43e1d1 100644 --- a/src/Stride.Shaders.Compilers/DXC.cs +++ b/src/Stride.Shaders.Compilers/DXC.cs @@ -40,6 +40,7 @@ public readonly void Compile() // var content = Encoding.ASCII.GetBytes(Code); unsafe { + Guid id = IDxcCompiler.Guid; Guid libId = IDxcCompiler3.Guid; SilkMarshal.ThrowHResult(dxc.CreateInstance(&id, out ComPtr compiler)); diff --git a/src/Stride.Shaders.LSP.Test/Program.cs b/src/Stride.Shaders.LSP.Test/Program.cs new file mode 100644 index 0000000000..3c8b8a82af --- /dev/null +++ b/src/Stride.Shaders.LSP.Test/Program.cs @@ -0,0 +1,2 @@ +// See https://aka.ms/new-console-template for more information +var client = \ No newline at end of file diff --git a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj new file mode 100644 index 0000000000..2150e3797b --- /dev/null +++ b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/src/Stride.Shaders.LSP/Program.cs b/src/Stride.Shaders.LSP/Program.cs index 44c88e315f..6867c0af25 100644 --- a/src/Stride.Shaders.LSP/Program.cs +++ b/src/Stride.Shaders.LSP/Program.cs @@ -47,7 +47,7 @@ static async Task MainAsync() provider => { var loggerFactory = provider.GetService(); - var logger = loggerFactory.CreateLogger(); + var logger = loggerFactory!.CreateLogger(); logger.LogInformation("Configuring"); @@ -142,7 +142,7 @@ static async Task MainAsync() baseConfig.Add(config.Key, config.Value); } - logger.LogInformation("Base Config: {@Config}", baseConfig); + logger!.LogInformation("Base Config: {@Config}", baseConfig); var scopedConfig = new JObject(); foreach (var config in configuration.AsEnumerable()) @@ -150,7 +150,7 @@ static async Task MainAsync() scopedConfig.Add(config.Key, config.Value); } - logger.LogInformation("Scoped Config: {@Config}", scopedConfig); + logger!.LogInformation("Scoped Config: {@Config}", scopedConfig); } ) ).ConfigureAwait(false); diff --git a/src/Stride.Shaders.LSP/log20240709.txt b/src/Stride.Shaders.LSP/log20240709.txt new file mode 100644 index 0000000000..58a4756da3 --- /dev/null +++ b/src/Stride.Shaders.LSP/log20240709.txt @@ -0,0 +1,4 @@ +2024-07-09 17:28:06.797 +02:00 [INF] This only goes file... +2024-07-09 17:28:07.048 +02:00 [INF] Configuring +2024-07-09 17:28:07.048 +02:00 [INF] inside ctor +2024-07-09 17:28:07.053 +02:00 [INF] Fooooo! From 283e9e339bdf76dd8a3f3bde41213aaaedc0564d Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 9 Jul 2024 18:09:56 +0200 Subject: [PATCH 0302/1182] update for language support --- src/Stride.Shaders.Parsing.Experiments/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 34bc5c00ba..29a71914e9 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,4 @@ Console.WriteLine(Directory.GetCurrentDirectory()); -Examples.CompileHLSL(); \ No newline at end of file +// Examples.CompileHLSL(); \ No newline at end of file From d1f5761cca491e6a81b9781e272bd4d855851da0 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 10 Jul 2024 12:01:40 +0200 Subject: [PATCH 0303/1182] simple update --- assets/HLSL/example.hlsl | 4 ++-- src/Stride.Shaders.Compilers/DXC.cs | 7 ++++--- .../Stride.Shaders.Compilers.csproj | 1 + src/Stride.Shaders.Parsing.Experiments/Examples.cs | 6 ++++++ src/Stride.Shaders.Parsing.Experiments/Program.cs | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/assets/HLSL/example.hlsl b/assets/HLSL/example.hlsl index 6c165d007c..84d98ff0e9 100644 --- a/assets/HLSL/example.hlsl +++ b/assets/HLSL/example.hlsl @@ -16,7 +16,7 @@ struct PS_INPUT float4 Color : COLOR; }; -PS_INPUT VS(VS_INPUT input) +PS_INPUT VSMain(VS_INPUT input) { PS_INPUT output = (PS_INPUT)0; output.Pos = mul(input.Pos, WorldViewProj); @@ -24,7 +24,7 @@ PS_INPUT VS(VS_INPUT input) return output; } -float4 PS(PS_INPUT input) : SV_Target +float4 main(PS_INPUT input) : SV_Target { return input.Color; } diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs index 2d8e43e1d1..66bc968801 100644 --- a/src/Stride.Shaders.Compilers/DXC.cs +++ b/src/Stride.Shaders.Compilers/DXC.cs @@ -42,10 +42,11 @@ public readonly void Compile() { Guid id = IDxcCompiler.Guid; - Guid libId = IDxcCompiler3.Guid; - SilkMarshal.ThrowHResult(dxc.CreateInstance(&id, out ComPtr compiler)); + Guid libId = IDxcUtils.Guid; + var guid = IDxcUtils.Guid; + var utils = dxc.CreateInstance(ref guid); SilkMarshal.ThrowHResult(dxc.CreateInstance(&libId, out ComPtr library)); - Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); + // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); IDxcBlobEncoding* sourceBlob = null; fixed (char* ptr = Code.AsSpan()) SilkMarshal.ThrowHResult(library.Get().CreateBlobWithEncodingFromPinned(ptr, (uint)Code.Length, 0, &sourceBlob)); diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 7eb94c13ff..8b0ab71838 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -6,6 +6,7 @@ + diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 8296656648..4d4cb12a0c 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -57,4 +57,10 @@ public static void CompileHLSL() var dxc = new DXCompiler(); dxc.Compile(); } + public static void CompileOldHLSL() + { + + var fxc = new FXCompiler(); + fxc.Compile(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 29a71914e9..82f1bfd515 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,4 @@ Console.WriteLine(Directory.GetCurrentDirectory()); -// Examples.CompileHLSL(); \ No newline at end of file +Examples.CompileOldHLSL(); \ No newline at end of file From f64cd9a5d8f05098bb5d0a3be0b929191dfd3e6f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 10 Jul 2024 12:14:56 +0200 Subject: [PATCH 0304/1182] update sln and experiments --- SDSL.sln | 34 +++++++++++++++---- src/Stride.Shaders.LSP.Test/Program.cs | 2 +- .../Program.cs | 2 +- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/SDSL.sln b/SDSL.sln index 7da21d21ea..cf17ff51c2 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -5,24 +5,29 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9967EA99-9716-43A9-B6BA-E5975F08250D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{66A8722A-4CE8-422D-9467-7B2C8FCB4734}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{66A8722A-4CE8-422D-9467-7B2C8FCB4734}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{92AE8C5F-4A4F-4A97-9561-86315D09F910}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{92AE8C5F-4A4F-4A97-9561-86315D09F910}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{DA4DEF22-680A-4763-8016-5E62A7BEA975}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{DA4DEF22-680A-4763-8016-5E62A7BEA975}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{55190824-293F-49AA-B068-95F69E949055}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SoftTouch.Spirv", "SoftTouch.Spirv", "{5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{54A7F69B-8687-4302-A545-77024C017E0B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv", "src\SoftTouch.Spirv\src\SoftTouch.Spirv\SoftTouch.Spirv.csproj", "{FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Core", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Core\SoftTouch.Spirv.Core.csproj", "{A23537C0-1B9E-45FB-B4E3-4B7B40443220}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -44,6 +49,17 @@ Global {55190824-293F-49AA-B068-95F69E949055}.Debug|Any CPU.Build.0 = Debug|Any CPU {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.ActiveCfg = Release|Any CPU {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.Build.0 = Release|Any CPU + {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Release|Any CPU.Build.0 = Release|Any CPU + {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {66A8722A-4CE8-422D-9467-7B2C8FCB4734} = {9967EA99-9716-43A9-B6BA-E5975F08250D} @@ -51,5 +67,9 @@ Global {DA4DEF22-680A-4763-8016-5E62A7BEA975} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {55190824-293F-49AA-B068-95F69E949055} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {54A7F69B-8687-4302-A545-77024C017E0B} = {5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9} + {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E} = {54A7F69B-8687-4302-A545-77024C017E0B} + {A23537C0-1B9E-45FB-B4E3-4B7B40443220} = {54A7F69B-8687-4302-A545-77024C017E0B} EndGlobalSection EndGlobal diff --git a/src/Stride.Shaders.LSP.Test/Program.cs b/src/Stride.Shaders.LSP.Test/Program.cs index 3c8b8a82af..906d748f35 100644 --- a/src/Stride.Shaders.LSP.Test/Program.cs +++ b/src/Stride.Shaders.LSP.Test/Program.cs @@ -1,2 +1,2 @@ // See https://aka.ms/new-console-template for more information -var client = \ No newline at end of file +Console.WriteLine("Hello world!"); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 82f1bfd515..34bc5c00ba 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,4 @@ Console.WriteLine(Directory.GetCurrentDirectory()); -Examples.CompileOldHLSL(); \ No newline at end of file +Examples.CompileHLSL(); \ No newline at end of file From ed281ec088defdf9dce9d1fcb722ff7f7bdff241 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 10 Jul 2024 16:37:28 +0200 Subject: [PATCH 0305/1182] Update with handwritten CLSID from the dxcapi.h --- src/Stride.Shaders.Compilers/DXC.cs | 31 ++++++++----- src/Stride.Shaders.Compilers/SpirvOpt.cs | 46 +++++++++++++++++++ .../Stride.Shaders.Compilers.csproj | 1 + .../Examples.cs | 8 +++- .../Program.cs | 1 + 5 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SpirvOpt.cs diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs index 66bc968801..b161bd9296 100644 --- a/src/Stride.Shaders.Compilers/DXC.cs +++ b/src/Stride.Shaders.Compilers/DXC.cs @@ -4,13 +4,15 @@ namespace Stride.Shaders.Compilers; +using DXCBuffer = Silk.NET.Direct3D.Compilers.Buffer; + public record struct DXCompiler(string Code) { - static string sampleCode = @" + public static string sampleCode = @" struct PSInput { float4 position : SV_POSITION; @@ -33,26 +35,33 @@ float4 PSMain(PSInput input) : SV_TARGET } "; - static DXC dxc = DXC.GetApi(); + static Guid blobGuid = Guid.Parse("3DA636C9-BA71-4024-A301-30CBF125305B"); + static Guid utilsGuid = Guid.Parse("6245D6AF-66E0-48FD-80B4-4D271796748C"); + static Guid compilerGuid = Guid.Parse("73e22d93-e6ce-47f3-b5bf-f0664f39c1b0"); + static Guid compilerArgsGuid = Guid.Parse("3e56ae82-224d-470f-a1a1-fe3016ee9f9d"); + static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); + static readonly DXC dxc = DXC.GetApi(); public readonly void Compile() { // var content = Encoding.ASCII.GetBytes(Code); unsafe { + var compiler = dxc.CreateInstance(ref compilerGuid); + var utils = dxc.CreateInstance(ref utilsGuid); + var args = dxc.CreateInstance(ref compilerArgsGuid); - Guid id = IDxcCompiler.Guid; - Guid libId = IDxcUtils.Guid; - var guid = IDxcUtils.Guid; - var utils = dxc.CreateInstance(ref guid); - SilkMarshal.ThrowHResult(dxc.CreateInstance(&libId, out ComPtr library)); // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); IDxcBlobEncoding* sourceBlob = null; fixed (char* ptr = Code.AsSpan()) - SilkMarshal.ThrowHResult(library.Get().CreateBlobWithEncodingFromPinned(ptr, (uint)Code.Length, 0, &sourceBlob)); - - // IDxcOperationResult* result = null; - // SilkMarshal.ThrowHResult(compiler.Get().Compile((IDxcBlob*)sourceBlob, (string)null!, (char*)SilkMarshal.StringToPtr("PSMain"), (char*)SilkMarshal.StringToPtr(""), (char**)SilkMarshal.StringArrayToPtr(["-spirv","-T", "ps_6_0"]), 3, null, 0, null, &result)); + { + // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); + var buff = new DXCBuffer(ptr, (nuint)Code.Length); + IDxcOperationResult* result = null; + SilkMarshal.ThrowHResult( + compiler.Get().Compile(&buff, ["-spirv", "-T", "ps_6_0"], 3, null, ref resultGuid,(void**)result) + ); + } // Console.WriteLine((nint)result); } } diff --git a/src/Stride.Shaders.Compilers/SpirvOpt.cs b/src/Stride.Shaders.Compilers/SpirvOpt.cs new file mode 100644 index 0000000000..a845bdfb6b --- /dev/null +++ b/src/Stride.Shaders.Compilers/SpirvOpt.cs @@ -0,0 +1,46 @@ +using System.Runtime.InteropServices; +using Silk.NET.Direct3D.Compilers; +using Silk.NET.Shaderc; + +namespace Stride.Shaders.Compilers; + +public static class SpirvOptimpizer +{ + static Shaderc shaderc = Shaderc.GetApi(); + + public static void Compile(string code, string entrypoint, SourceLanguage language, OptimizationLevel level, string filename = "source.shader") + { + unsafe + { + var compiler = shaderc.CompilerInitialize(); + var options = shaderc.CompileOptionsInitialize(); + shaderc.CompileOptionsSetSourceLanguage(options, language); + shaderc.CompileOptionsSetOptimizationLevel(options, level); + var compResult = shaderc.CompileIntoSpvAssembly(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); + var err = shaderc.ResultGetErrorMessageS(compResult); + if (string.IsNullOrEmpty(err)) + { + var res = shaderc.ResultGetBytesS(compResult); + Console.WriteLine(res); + } + } + } + + public static void Optimize(ReadOnlyMemory words) + { + unsafe + { + var bytes = MemoryMarshal.AsBytes(words.Span); + var compiler = shaderc.CompilerInitialize(); + var options = shaderc.CompileOptionsInitialize(); + shaderc.CompileOptionsSetOptimizationLevel(options, OptimizationLevel.Size); + var compResult = shaderc.CompileIntoSpvAssembly(compiler, DXCompiler.sampleCode, (nuint)DXCompiler.sampleCode.Length, ShaderKind.FragmentShader, "main.hlsl", "PSMain", options); + var err = shaderc.ResultGetErrorMessageS(compResult); + if (string.IsNullOrEmpty(err)) + { + var res = shaderc.ResultGetBytesS(compResult); + Console.WriteLine(res); + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 8b0ab71838..49d056901c 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 4d4cb12a0c..856e535f92 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -54,7 +54,7 @@ public static void UseSpirvCross() public static void CompileHLSL() { - var dxc = new DXCompiler(); + var dxc = new DXCompiler(DXCompiler.sampleCode); dxc.Compile(); } public static void CompileOldHLSL() @@ -63,4 +63,10 @@ public static void CompileOldHLSL() var fxc = new FXCompiler(); fxc.Compile(); } + public static void SpvOpt() + { + + // var spvopt = new SpirvOptimpizer(); + // spvopt.Optimize(words); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 34bc5c00ba..53ebc61cc3 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -12,4 +12,5 @@ Console.WriteLine(Directory.GetCurrentDirectory()); +// Examples.SpvOpt(); Examples.CompileHLSL(); \ No newline at end of file From 952efd8273cb736623ed0c5a111da144e0e585d9 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 10 Jul 2024 18:27:38 +0200 Subject: [PATCH 0306/1182] trying stuff with DXC --- src/Stride.Shaders.Compilers/DXC.cs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs index b161bd9296..a6c81c1f9b 100644 --- a/src/Stride.Shaders.Compilers/DXC.cs +++ b/src/Stride.Shaders.Compilers/DXC.cs @@ -1,4 +1,5 @@ using System.Text; +using Silk.NET.Core; using Silk.NET.Core.Native; using Silk.NET.Direct3D.Compilers; @@ -53,15 +54,18 @@ public readonly void Compile() // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); IDxcBlobEncoding* sourceBlob = null; - fixed (char* ptr = Code.AsSpan()) - { - // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); - var buff = new DXCBuffer(ptr, (nuint)Code.Length); - IDxcOperationResult* result = null; - SilkMarshal.ThrowHResult( - compiler.Get().Compile(&buff, ["-spirv", "-T", "ps_6_0"], 3, null, ref resultGuid,(void**)result) - ); - } + + SilkMarshal.ThrowHResult( + utils.Get().CreateBlobFromPinned((void*)SilkMarshal.StringToPtr(Code), (uint)Code.Length, 1200, ref sourceBlob) + ); + // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); + var buff = new DXCBuffer(sourceBlob, (nuint)Code.Length); + IDxcOperationResult* result = null; + string[] parms = ["-spirv", "-T", "ps_6_0", "-E", "PSMain"]; + SilkMarshal.ThrowHResult( + compiler.Get().Compile(&buff, parms, (uint)parms.Length, null, ref resultGuid,(void**)result) + ); + // Console.WriteLine((nint)result); } } From df31a09ff79ce35c0208bb99ac4a921d25d4e761 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 11 Jul 2024 19:46:48 +0200 Subject: [PATCH 0307/1182] Create LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..f52faac9e1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Stride + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From cf3a9fdb3d9c1b593c17379b27581c8908127dbb Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 14 Jul 2024 19:13:02 +0200 Subject: [PATCH 0308/1182] Changed web browser to avalonia edit --- SDSL.sln | 28 ++++++++++ src/SoftTouch.Spirv | 2 +- src/Stride.Shaders.AvaloniaViewer/App.axaml | 11 ++++ .../App.axaml.cs | 23 ++++++++ .../MainWindow.axaml | 31 +++++++++++ .../MainWindow.axaml.cs | 11 ++++ src/Stride.Shaders.AvaloniaViewer/Program.cs | 21 ++++++++ .../Stride.Shaders.AvaloniaViewer.csproj | 20 +++++++ .../app.manifest | 18 +++++++ src/Stride.Shaders.Compilers/SpirvOpt.cs | 54 +++++++++++++++++-- 10 files changed, 213 insertions(+), 6 deletions(-) create mode 100644 src/Stride.Shaders.AvaloniaViewer/App.axaml create mode 100644 src/Stride.Shaders.AvaloniaViewer/App.axaml.cs create mode 100644 src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml create mode 100644 src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs create mode 100644 src/Stride.Shaders.AvaloniaViewer/Program.cs create mode 100644 src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj create mode 100644 src/Stride.Shaders.AvaloniaViewer/app.manifest diff --git a/SDSL.sln b/SDSL.sln index cf17ff51c2..75e90fae3d 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -23,6 +23,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv", "src\Soft EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Core", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Core\SoftTouch.Spirv.Core.csproj", "{A23537C0-1B9E-45FB-B4E3-4B7B40443220}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Experiments", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Experiments\SoftTouch.Spirv.Experiments.csproj", "{56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Generators", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Generators\SoftTouch.Spirv.Generators.csproj", "{5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.BrowserView", "src\Stride.Shaders.BrowserView\Stride.Shaders.BrowserView.csproj", "{E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.AvaloniaViewer", "src\Stride.Shaders.AvaloniaViewer\Stride.Shaders.AvaloniaViewer.csproj", "{107AF929-CAC1-40DE-895D-71A61C9AED58}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +65,22 @@ Global {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Debug|Any CPU.Build.0 = Debug|Any CPU {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.ActiveCfg = Release|Any CPU {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.Build.0 = Release|Any CPU + {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Debug|Any CPU.Build.0 = Debug|Any CPU + {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Release|Any CPU.ActiveCfg = Release|Any CPU + {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Release|Any CPU.Build.0 = Release|Any CPU + {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.Build.0 = Release|Any CPU + {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Release|Any CPU.Build.0 = Release|Any CPU + {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {107AF929-CAC1-40DE-895D-71A61C9AED58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {107AF929-CAC1-40DE-895D-71A61C9AED58}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -71,5 +95,9 @@ Global {54A7F69B-8687-4302-A545-77024C017E0B} = {5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9} {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E} = {54A7F69B-8687-4302-A545-77024C017E0B} {A23537C0-1B9E-45FB-B4E3-4B7B40443220} = {54A7F69B-8687-4302-A545-77024C017E0B} + {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24} = {54A7F69B-8687-4302-A545-77024C017E0B} + {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0} = {54A7F69B-8687-4302-A545-77024C017E0B} + {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {107AF929-CAC1-40DE-895D-71A61C9AED58} = {9967EA99-9716-43A9-B6BA-E5975F08250D} EndGlobalSection EndGlobal diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index f940af5a3b..a44b20e685 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit f940af5a3be7bf79a596ed4397dc85dc6ee09962 +Subproject commit a44b20e685bbf8346c8b414640df679d5c8ade2e diff --git a/src/Stride.Shaders.AvaloniaViewer/App.axaml b/src/Stride.Shaders.AvaloniaViewer/App.axaml new file mode 100644 index 0000000000..d55859486d --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/App.axaml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs b/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs new file mode 100644 index 0000000000..772587a887 --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs @@ -0,0 +1,23 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace Stride.Shaders.AvaloniaViewer; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.MainWindow = new MainWindow(); + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml new file mode 100644 index 0000000000..7a82a78f43 --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml @@ -0,0 +1,31 @@ + + + + + + diff --git a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs new file mode 100644 index 0000000000..f11d07403c --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace Stride.Shaders.AvaloniaViewer; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/Program.cs b/src/Stride.Shaders.AvaloniaViewer/Program.cs new file mode 100644 index 0000000000..aef9dc2f27 --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/Program.cs @@ -0,0 +1,21 @@ +using Avalonia; +using System; + +namespace Stride.Shaders.AvaloniaViewer; + +class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} diff --git a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj new file mode 100644 index 0000000000..ba0b9c71e1 --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj @@ -0,0 +1,20 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + + diff --git a/src/Stride.Shaders.AvaloniaViewer/app.manifest b/src/Stride.Shaders.AvaloniaViewer/app.manifest new file mode 100644 index 0000000000..0b64ebc7a9 --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/Stride.Shaders.Compilers/SpirvOpt.cs b/src/Stride.Shaders.Compilers/SpirvOpt.cs index a845bdfb6b..8503519c13 100644 --- a/src/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/src/Stride.Shaders.Compilers/SpirvOpt.cs @@ -1,14 +1,16 @@ using System.Runtime.InteropServices; +using Silk.NET.Core.Native; using Silk.NET.Direct3D.Compilers; using Silk.NET.Shaderc; +using Silk.NET.SPIRV.Cross; namespace Stride.Shaders.Compilers; -public static class SpirvOptimpizer +public static class SpirvOptimizer { static Shaderc shaderc = Shaderc.GetApi(); - public static void Compile(string code, string entrypoint, SourceLanguage language, OptimizationLevel level, string filename = "source.shader") + public static string CompileAssembly(string code, string entrypoint, SourceLanguage language, OptimizationLevel level, string filename = "source.shader") { unsafe { @@ -18,14 +20,56 @@ public static void Compile(string code, string entrypoint, SourceLanguage langua shaderc.CompileOptionsSetOptimizationLevel(options, level); var compResult = shaderc.CompileIntoSpvAssembly(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); var err = shaderc.ResultGetErrorMessageS(compResult); + if (string.IsNullOrEmpty(err)) + return shaderc.ResultGetBytesS(compResult); + } + throw new Exception("Failed to compile shader"); + } + public static byte[] Compile(string code, string entrypoint, SourceLanguage language, OptimizationLevel level = OptimizationLevel.Size, string filename = "source.shader") + { + unsafe + { + var compiler = shaderc.CompilerInitialize(); + var options = shaderc.CompileOptionsInitialize(); + shaderc.CompileOptionsSetSourceLanguage(options, language); + shaderc.CompileOptionsSetOptimizationLevel(options, level); + var compResult = shaderc.CompileIntoSpv(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); + var err = shaderc.ResultGetErrorMessageS(compResult); if (string.IsNullOrEmpty(err)) { - var res = shaderc.ResultGetBytesS(compResult); - Console.WriteLine(res); + var bytes = shaderc.ResultGetBytes(compResult); + var length = shaderc.ResultGetLength(compResult); + var res = new byte[length]; + new Span(bytes, (int)length).CopyTo(res.AsSpan()); + SilkMarshal.Free((nint)bytes); + return res; } } + throw new Exception("Failed to compile shader"); } - + public static string Translate(string code, string entrypoint, SourceLanguage from, Backend to, OptimizationLevel level = OptimizationLevel.Zero, string filename = "source.shader") + { + unsafe + { + var compiler = shaderc.CompilerInitialize(); + var options = shaderc.CompileOptionsInitialize(); + shaderc.CompileOptionsSetSourceLanguage(options, from); + shaderc.CompileOptionsSetOptimizationLevel(options, level); + var compResult = shaderc.CompileIntoSpv(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); + var err = shaderc.ResultGetErrorMessageS(compResult); + if (string.IsNullOrEmpty(err)) + { + var bytes = shaderc.ResultGetBytes(compResult); + var length = shaderc.ResultGetLength(compResult); + var res = new uint[length]; + new Span((uint*)bytes, (int)length/4).CopyTo(res.AsSpan()); + SilkMarshal.Free((nint)bytes); + return new SpirvTranslator(res.AsMemory()).Translate(to); + } + } + throw new Exception("Failed to translate shader"); + } + public static void Optimize(ReadOnlyMemory words) { unsafe From 2a3b26b9f1278ca8576806452d217f944f299cdd Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 14 Jul 2024 19:58:45 +0200 Subject: [PATCH 0309/1182] Loading grammar --- .../MainWindow.axaml | 3 ++ .../MainWindow.axaml.cs | 13 ++++++ .../Stride.Shaders.AvaloniaViewer.csproj | 42 +++++++++++-------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml index 7a82a78f43..0ace4cf8a4 100644 --- a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml +++ b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml @@ -12,6 +12,7 @@ ColumnDefinitions="*,*" RowDefinitions="*"> diff --git a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs index f11d07403c..94a2c1ceec 100644 --- a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs +++ b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs @@ -1,4 +1,12 @@ +using System.Collections.Generic; using Avalonia.Controls; +using AvaloniaEdit; +using AvaloniaEdit.TextMate; +using TextMateSharp.Grammars; +using TextMateSharp.Internal.Grammars; +using TextMateSharp.Internal.Types; +using TextMateSharp.Registry; +using TextMateSharp.Themes; namespace Stride.Shaders.AvaloniaViewer; @@ -7,5 +15,10 @@ public partial class MainWindow : Window public MainWindow() { InitializeComponent(); + + var editor = this.FindControl("ShaderEditor"); + var registry = new Registry(new RegistryOptions(ThemeName.Dark)); + var grammar = registry.LoadGrammarFromPathSync("./sdsl.tmLanguage.json", 0, []); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj index ba0b9c71e1..06f9ec3c89 100644 --- a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj +++ b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj @@ -1,20 +1,28 @@  - - WinExe - net8.0 - enable - true - app.manifest - true - + + WinExe + net8.0 + enable + true + app.manifest + true + - - - - - - - - - + + + + + + + + + + + + + + + + + From 1448476bbec4dd636ee47ec9fed538b33414d916 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 14 Jul 2024 23:15:03 +0200 Subject: [PATCH 0310/1182] working on viewer --- .../MainWindow.axaml | 1 + .../MainWindow.axaml.cs | 69 +++++++++++++++++-- .../Stride.Shaders.AvaloniaViewer.csproj | 5 ++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml index 0ace4cf8a4..9f959733fe 100644 --- a/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml +++ b/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml @@ -19,6 +19,7 @@ Text="" ShowLineNumbers="True" FontFamily="Cascadia Code,Consolas,Menlo,Monospace" + TextChanged="Recompile" /> ("ShaderEditor") ?? throw new NotImplementedException(); + editor.Text = @"struct PSInput +{ + float4 color : COLOR; +}; + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} +"; + var options = new RegistryOptions(ThemeName.Dark); + //Initial setup of TextMate. + var textMateInstallation = editor.InstallTextMate(options); + + textMateInstallation.SetGrammar(options.GetScopeByLanguageId(options.GetLanguageByExtension(".hlsl").Id)); - var editor = this.FindControl("ShaderEditor"); - var registry = new Registry(new RegistryOptions(ThemeName.Dark)); - var grammar = registry.LoadGrammarFromPathSync("./sdsl.tmLanguage.json", 0, []); + } + + public void Recompile(object source, EventArgs args) + { + var editor = this.FindControl("ShaderEditor") ?? throw new NotImplementedException(); + var other = this.FindControl("OutputEditor") ?? throw new NotImplementedException(); + if(string.IsNullOrEmpty(editor.Text)) + editor.Text = @"struct PSInput +{ + float4 color : COLOR; +}; + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} +"; + try + { + other.Text = SpirvOptimizer.Translate(editor.Text, "PSMain", SourceLanguage.Hlsl, Backend.Glsl); + } + catch(Exception e) + { + other.Text = e.Message; + } + finally + { + other.Text = ""; + } + + } + + } \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj index 06f9ec3c89..1b10738ec1 100644 --- a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj +++ b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj @@ -17,11 +17,16 @@ + + + + + From 12dcc94de2f52a0bd66dc1fbe7ec55084e33c9cc Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 15 Jul 2024 01:28:16 +0200 Subject: [PATCH 0311/1182] translation working correctly --- src/Stride.Shaders.Compilers/SpirvOpt.cs | 6 ++++-- src/Stride.Shaders.Parsing.Experiments/Examples.cs | 8 +++++++- src/Stride.Shaders.Parsing.Experiments/Program.cs | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SpirvOpt.cs b/src/Stride.Shaders.Compilers/SpirvOpt.cs index 8503519c13..4e1a02d38e 100644 --- a/src/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/src/Stride.Shaders.Compilers/SpirvOpt.cs @@ -3,6 +3,8 @@ using Silk.NET.Direct3D.Compilers; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; +using SoftTouch.Spirv.Core; +using SoftTouch.Spirv.Core.Buffers; namespace Stride.Shaders.Compilers; @@ -61,8 +63,8 @@ public static string Translate(string code, string entrypoint, SourceLanguage fr { var bytes = shaderc.ResultGetBytes(compResult); var length = shaderc.ResultGetLength(compResult); - var res = new uint[length]; - new Span((uint*)bytes, (int)length/4).CopyTo(res.AsSpan()); + var byteArray = new Span(bytes, (int)length); + var res = MemoryMarshal.Cast(byteArray).ToArray(); SilkMarshal.Free((nint)bytes); return new SpirvTranslator(res.AsMemory()).Translate(to); } diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 856e535f92..18c1504945 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -1,6 +1,7 @@ using System.Text; using Silk.NET.Core.Native; using Silk.NET.Direct3D.Compilers; +using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; @@ -50,10 +51,15 @@ public static void UseSpirvCross() Console.WriteLine(code.Translate(Backend.Hlsl)); } } + public static void TranslateHLSL() + { + + Console.WriteLine(SpirvOptimizer.CompileAssembly(DXCompiler.sampleCode,"PSMain", SourceLanguage.Hlsl, OptimizationLevel.Zero)); + Console.WriteLine(SpirvOptimizer.Translate(DXCompiler.sampleCode,"PSMain", SourceLanguage.Hlsl, Backend.Hlsl)); + } public static void CompileHLSL() { - var dxc = new DXCompiler(DXCompiler.sampleCode); dxc.Compile(); } diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 53ebc61cc3..3df91b713b 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -13,4 +13,4 @@ // Examples.SpvOpt(); -Examples.CompileHLSL(); \ No newline at end of file +Examples.TranslateHLSL(); \ No newline at end of file From ff6e9524441caf0213e1128238fc8d8d3390f37b Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Mon, 15 Jul 2024 11:44:29 +0200 Subject: [PATCH 0312/1182] update solution --- SDSL.sln | 7 ------- 1 file changed, 7 deletions(-) diff --git a/SDSL.sln b/SDSL.sln index 75e90fae3d..ee29d6a6dc 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Experiments EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Generators", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Generators\SoftTouch.Spirv.Generators.csproj", "{5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.BrowserView", "src\Stride.Shaders.BrowserView\Stride.Shaders.BrowserView.csproj", "{E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.AvaloniaViewer", "src\Stride.Shaders.AvaloniaViewer\Stride.Shaders.AvaloniaViewer.csproj", "{107AF929-CAC1-40DE-895D-71A61C9AED58}" EndProject Global @@ -73,10 +71,6 @@ Global {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.Build.0 = Release|Any CPU - {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E}.Release|Any CPU.Build.0 = Release|Any CPU {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.Build.0 = Debug|Any CPU {107AF929-CAC1-40DE-895D-71A61C9AED58}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -97,7 +91,6 @@ Global {A23537C0-1B9E-45FB-B4E3-4B7B40443220} = {54A7F69B-8687-4302-A545-77024C017E0B} {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24} = {54A7F69B-8687-4302-A545-77024C017E0B} {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0} = {54A7F69B-8687-4302-A545-77024C017E0B} - {E9B67D9C-9D66-478F-8CB1-8EEFCD95334E} = {9967EA99-9716-43A9-B6BA-E5975F08250D} {107AF929-CAC1-40DE-895D-71A61C9AED58} = {9967EA99-9716-43A9-B6BA-E5975F08250D} EndGlobalSection EndGlobal From 6493bf547bc65257075a15d8ab7a49d34c9c6bd9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 11 Aug 2024 13:03:18 +0200 Subject: [PATCH 0313/1182] post build for unix too --- .../Stride.Shaders.AvaloniaViewer.csproj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj index 1b10738ec1..c2e5de7cb0 100644 --- a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj +++ b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj @@ -27,7 +27,11 @@ - + + + + + From 1170e6f9c4fa875101a07bf49cbdb39a2ea9a569 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 09:45:26 +0200 Subject: [PATCH 0314/1182] update spirv header --- src/SoftTouch.Spirv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index a44b20e685..7a0208992c 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit a44b20e685bbf8346c8b414640df679d5c8ade2e +Subproject commit 7a0208992cab61b7ea34c9d02229bd59626e5b5c From b5944c274fbce8d977e5b8750e6241a553c14fa0 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 13:34:58 +0200 Subject: [PATCH 0315/1182] made it work for netstandard2.0 --- src/Stride.Shaders.Parsing/ExternalInit.cs | 16 +++++ .../SDSL/AST/Literals.cs | 4 ++ .../Parsers/LiteralParsers/LiteralParsers.cs | 1 - .../Parsers/LiteralParsers/NumberParsers.cs | 22 ++++++- .../SDSL/Parsers/LiteralParsers/Reserved.cs | 11 ---- .../Scanners/TextLocation.cs | 4 ++ src/Stride.Shaders.Parsing/SpanExtensions.cs | 60 +++++++++++++++++++ .../Stride.Shaders.Parsing.csproj | 7 ++- 8 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/ExternalInit.cs create mode 100644 src/Stride.Shaders.Parsing/SpanExtensions.cs diff --git a/src/Stride.Shaders.Parsing/ExternalInit.cs b/src/Stride.Shaders.Parsing/ExternalInit.cs new file mode 100644 index 0000000000..d6df8f163c --- /dev/null +++ b/src/Stride.Shaders.Parsing/ExternalInit.cs @@ -0,0 +1,16 @@ +#if NETSTANDARD2_0 +using System.ComponentModel; + +namespace System.Runtime.CompilerServices +{ + /// + /// Reserved to be used by the compiler for tracking metadata. + /// This class should not be used by developers in source code. + /// This dummy class is required to compile records when targeting .NET Standard + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public static class IsExternalInit + { + } +} +#endif \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index 2f2f7aef29..eb0026ae58 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -17,7 +17,11 @@ public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) } public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info) : NumberLiteral(info) +#if NET8_0_OR_GREATER where T : struct, INumber +#else + where T : struct +#endif { public Suffix Suffix { get; set; } = suffix; public T Value { get; set; } = value; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 3fc229d36c..924d546379 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -1,4 +1,3 @@ -using System.Collections.Frozen; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 321f1f4bd9..c378bfd47a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -40,13 +40,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var numPos = scanner.Position; if (suffix.Match(ref scanner, null!, out Suffix suf)) { +#if NETSTANDARD2_0 + node = new(suf, long.Parse(scanner.Span[position..numPos].ToString()), scanner.GetLocation(position, scanner.Position)); +#else node = new(suf, long.Parse(scanner.Span[position..numPos]), scanner.GetLocation(position, scanner.Position)); +#endif return true; } else { var memory = scanner.Memory[position..scanner.Position]; +#if NETSTANDARD2_0 + node = new(new(32, false, true), long.Parse(memory.Span.ToString()), new(scanner.Memory, position..scanner.Position)); +#else node = new(new(32, false, true), long.Parse(memory.Span), new(scanner.Memory, position..scanner.Position)); +#endif return true; } } @@ -73,7 +81,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (Terminals.Digit(ref scanner, advance: true)) ; if (suffix.Match(ref scanner, result, out Suffix s)) +#if NETSTANDARD2_0 + node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position].ToString()), new(scanner.Memory, position..scanner.Position)); +#else node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); +#endif return true; } else if (Terminals.Digit(ref scanner, 1.., advance: true)) @@ -94,7 +106,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; else len += 1; - node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position+len)]), new(scanner.Memory, position..scanner.Position)); +#if NETSTANDARD2_0 + node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position+len)].ToString()), new(scanner.Memory, position..scanner.Position)); +#else + node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position + len)]), new(scanner.Memory, position..scanner.Position)); +#endif return true; } @@ -108,7 +124,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (!suffix.Match(ref scanner, result, out s)) s = new(32, true, true); } +#if NETSTANDARD2_0 + node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position].ToString()), new(scanner.Memory, position..scanner.Position)); +#else node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); +#endif return true; } else return CommonParsers.Exit(ref scanner, result, out node, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs index 07abfe318b..730d223624 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs @@ -2,17 +2,6 @@ namespace Stride.Shaders.Parsing.SDSL; -public class ReadOnlyMemoryCharComparer : IEqualityComparer> -{ - public static ReadOnlyMemoryCharComparer Instance { get; } = new(); - - public bool Equals(ReadOnlyMemory x, ReadOnlyMemory y) => - x.Span.Equals(y.Span, StringComparison.OrdinalIgnoreCase); - - public int GetHashCode(ReadOnlyMemory obj) => - string.GetHashCode(obj.Span, StringComparison.OrdinalIgnoreCase); -} - public static class Reserved { diff --git a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs index f7897c252b..c647b990c5 100644 --- a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs +++ b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs @@ -12,7 +12,11 @@ public record struct TextLocation(ReadOnlyMemory Original, Range Range) public readonly int Column => Range.StartsAt(Original.Length) - Original.Span[..Range.StartsAt(Original.Length)].LastIndexOf('\n'); public readonly override string ToString() { + #if NETSTANDARD2_0 + return $"[l{Line}-c{Column}]\n{Text.Span.ToString()}"; + #else return $"[l{Line}-c{Column}]\n{Text.Span}"; + #endif } } diff --git a/src/Stride.Shaders.Parsing/SpanExtensions.cs b/src/Stride.Shaders.Parsing/SpanExtensions.cs new file mode 100644 index 0000000000..d47c1f81c8 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SpanExtensions.cs @@ -0,0 +1,60 @@ +#if NETSTANDARD2_0 +public static class SpanExtensions +{ + public static int Count(this ReadOnlySpan span, char c) + { + int count = 0; + foreach(var item in span) + if(c == item) + count +=1; + return count; + } + public static int Count(this ReadOnlySpan span, int c) + { + int count = 0; + foreach(var item in span) + if(c == item) + count +=1; + return count; + } + public static int Count(this Span span, char c) + { + int count = 0; + foreach(var item in span) + if(c == item) + count +=1; + return count; + } + public static int Count(this Span span, int c) + { + int count = 0; + foreach(var item in span) + if(c == item) + count +=1; + return count; + } + public static ReadOnlySpan TrimEnd(this ReadOnlySpan span) + { + return span; + } + public static ReadOnlyMemory TrimEnd(this ReadOnlyMemory span) + { + return span; + } + public static ReadOnlySpan TrimStart(this ReadOnlySpan span) + { + for(int i = 0; i < span.Length; i++) + if(!char.IsWhiteSpace(span[i])) + return span[i..]; + return span; + } + public static ReadOnlyMemory TrimStart(this ReadOnlyMemory memory) + { + for(int i = 0; i < memory.Length; i++) + if(!char.IsWhiteSpace(memory.Span[i])) + return memory[i..]; + return memory; + } +} + +#endif \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index e7fe7008d7..87c67eaed8 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -1,13 +1,18 @@  - net8.0 + netstandard2.0;net8.0 enable enable + 12 + + + + From 55e59eafb40c02316b671bec9ade81517809dc85 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 13:36:37 +0200 Subject: [PATCH 0316/1182] added trim end extensions --- src/Stride.Shaders.Parsing/SpanExtensions.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SpanExtensions.cs b/src/Stride.Shaders.Parsing/SpanExtensions.cs index d47c1f81c8..46443d41fc 100644 --- a/src/Stride.Shaders.Parsing/SpanExtensions.cs +++ b/src/Stride.Shaders.Parsing/SpanExtensions.cs @@ -35,11 +35,17 @@ public static int Count(this Span span, int c) } public static ReadOnlySpan TrimEnd(this ReadOnlySpan span) { + for(int i = span.Length - 1; i >= 0; i++) + if(!char.IsWhiteSpace(span[i])) + return span[..i]; return span; } - public static ReadOnlyMemory TrimEnd(this ReadOnlyMemory span) + public static ReadOnlyMemory TrimEnd(this ReadOnlyMemory memory) { - return span; + for(int i = memory.Length - 1; i >= 0; i++) + if(!char.IsWhiteSpace(memory.Span[i])) + return memory[..i]; + return memory; } public static ReadOnlySpan TrimStart(this ReadOnlySpan span) { From 82005081ac17c1e720e728bd6421d5101da5d1a7 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 16:35:09 +0200 Subject: [PATCH 0317/1182] updated parser to parse code attributes --- assets/SDSL/Commented.sdsl | 1 + .../Examples.cs | 14 ++++ .../Program.cs | 3 +- .../SDSL/AST/ShaderAttributes.cs | 24 ++++++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 3 +- .../SDSL/Parsers/Common/CommonParsers.cs | 3 +- .../ShaderParsers/ShaderAttributeParsers.cs | 71 +++++++++++++++++++ .../ShaderParsers/ShaderElementParsers.cs | 8 ++- .../Stride.Shaders.Parsing.csproj | 4 +- 9 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs diff --git a/assets/SDSL/Commented.sdsl b/assets/SDSL/Commented.sdsl index adfccb0115..cc56833471 100644 --- a/assets/SDSL/Commented.sdsl +++ b/assets/SDSL/Commented.sdsl @@ -2,6 +2,7 @@ namespace MyNamespace.SoftTouch.Hello; shader Parent { + [Layout(1, 2)] stream int a; } diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 18c1504945..8e1fe03546 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -4,6 +4,7 @@ using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; +using Stride.Shaders.Parsing.SDSL; namespace Stride.Shaders.Experiments; @@ -75,4 +76,17 @@ public static void SpvOpt() // var spvopt = new SpirvOptimpizer(); // spvopt.Optimize(words); } + + public static void ParseSDSL() + { + var text = File.ReadAllText(@"C:\Users\youness_kafia\Documents\dotnetProjs\SDSL\assets\SDSL\Commented.sdsl"); + var parsed = SDSLParser.Parse(text); + Console.WriteLine(parsed.AST); + if(parsed.Errors.Count > 0) + { + Console.ForegroundColor = ConsoleColor.Red; + foreach (var e in parsed.Errors) + Console.WriteLine(e); + } + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 3df91b713b..65fb06dce7 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -13,4 +13,5 @@ // Examples.SpvOpt(); -Examples.TranslateHLSL(); \ No newline at end of file +// Examples.TranslateHLSL(); +Examples.ParseSDSL(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs index 6abe7478dd..72859bc8b7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs @@ -1,7 +1,29 @@ +using System.Security.Cryptography; + namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderAttribute(TextLocation info) : Node(info); +public sealed class ShaderAttributeList(List attributes, TextLocation info) : Node(info) +{ + public List Attributes { get; } = attributes; +} + +public class AnyShaderAttribute(Identifier name, TextLocation info, List parameters = null!) : ShaderAttribute(info) +{ + public Identifier Name { get; set; } = name; + public List Parameters { get; } = parameters ?? []; + + public override string ToString() + { + return Parameters switch + { + null => Name.Name, + _ => $"{Name}({string.Join(", ",Parameters.Select(x => x.ToString()))})" + }; + } +} + public class ResourceBind(int location, int space, TextLocation info) : ShaderAttribute(info) { @@ -17,4 +39,4 @@ public override string ToString() public class ColorType(TextLocation info) : ShaderAttribute(info) { public override string ToString() => "COLOR"; -} \ No newline at end of file +} diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f84479390a..4edaaa7cca 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -4,6 +4,7 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : ShaderElement(info) { public bool IsStaged { get; set; } = isStaged; + public List Attributes { get; set; } = []; } @@ -17,7 +18,7 @@ public sealed class ShaderMember(TypeName type, Identifier name, Expression? ini public override string ToString() { - return $"{Type} {Name}"; + return $"[{string.Join(" ", Attributes.Select(x => x.ToString()))}]\n{Type} {Name}"; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 1d9baa7a13..c34919edc1 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -194,9 +194,8 @@ public static bool Repeat(ref TScanner scanner, ParserValueDele } else if(nodes.Count >= minimum) return true; - else Exit(ref scanner, result, out nodes, position, orError); + else return Exit(ref scanner, result, out nodes, position, orError); } - else Exit(ref scanner, result, out nodes, position, orError); } if (nodes.Count >= minimum) return true; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs new file mode 100644 index 0000000000..ee0259ea81 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -0,0 +1,71 @@ +using Stride.Shaders.Parsing.SDSL.AST; + + +namespace Stride.Shaders.Parsing.SDSL; + + + +public record struct ShaderAttributeListParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + + if ( + CommonParsers.Repeat( + ref scanner, + new AttributeParser(), + result, + out var attributeList, + 1, + true + ) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + parsed = new ShaderAttributeList(attributeList, scanner.GetLocation(position..)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } + public static bool AttributeList(ref TScanner scanner, ParseResult result, out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new ShaderAttributeListParser().Match(ref scanner, result, out parsed, orError); + public static bool Attribute(ref TScanner scanner, ParseResult result, out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new AttributeParser().Match(ref scanner, result, out parsed, orError); +} + +public record struct AttributeParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Char('[', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('(', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + ParameterParsers.Values(ref scanner, result, out var values); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true)) + { + parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..), values.Values); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.CreateError(position))); + } + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char(']', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end attribute", scanner.CreateError(position))); + parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index d9558b4ea4..881db4c214 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -23,7 +23,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { bool isStaged = false; bool isStreamed = false; - var tmpPos = position; + bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); + var tmpPos = scanner.Position; + if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { isStaged = true; @@ -39,12 +41,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { member.IsStream = isStreamed; member.IsStaged = isStaged; + if(hasAttributes) + member.Attributes = attributes.Attributes; parsed = member; return true; } else if (Method(ref scanner, result, out var method)) { method.IsStaged = isStaged; + if(hasAttributes) + member.Attributes = attributes.Attributes; parsed = method; return true; } diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index 87c67eaed8..e0b374d689 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -1,10 +1,10 @@  - netstandard2.0;net8.0 + net8.0;netstandard2.0 enable enable - 12 + latest From b82b2865428c8a99905ed77608d523e4453ccfd2 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 17:07:15 +0200 Subject: [PATCH 0318/1182] updated spirv --- src/SoftTouch.Spirv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index 7a0208992c..bb8bd9d50f 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit 7a0208992cab61b7ea34c9d02229bd59626e5b5c +Subproject commit bb8bd9d50f649e21b6f58f32e51a03cbc08f4910 From ffe3196557ada00fc33e6b9655b2f6f4dc92d654 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 13 Aug 2024 18:09:42 +0200 Subject: [PATCH 0319/1182] updating spirv + starting to work on symbol table --- src/SoftTouch.Spirv | 2 +- src/Stride.Shaders.Compilers/SDSLC.cs | 4 ++++ src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs | 10 ---------- .../SDSL/Analysis/Symbol.cs | 15 +++++++++++++++ .../SDSL/Analysis/SymbolTable.cs | 8 ++++++++ .../SDSL/Analysis/SymbolTypes.cs | 12 ++++++++++++ 6 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSLC.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs create mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs create mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs create mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index bb8bd9d50f..ee22e93c8e 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit bb8bd9d50f649e21b6f58f32e51a03cbc08f4910 +Subproject commit ee22e93c8e72bcbfe74ce47908c8d7166b09d267 diff --git a/src/Stride.Shaders.Compilers/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSLC.cs new file mode 100644 index 0000000000..69bec54763 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSLC.cs @@ -0,0 +1,4 @@ +namespace Stride.Shaders.Compilers; + + +public record struct SDSLC; \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs b/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs deleted file mode 100644 index 8adcea1a6c..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/DataTypes.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Stride.Shaders.Parsing.SDSL.AST; - -public abstract record DataType(); -public record Scalar() : DataType(), IGenericValue; -public record Vector(int Size) : DataType(), IGenericValue; -public record Matrix(int Rows, int Columns) : DataType(), IGenericValue; -public record Array(int Size) : DataType(); -public record Struct(Dictionary Fields) : DataType(); -public record Buffer(DataType BaseType) : DataType(), IGenericValue; -public record Texture(DataType BaseType) : DataType(), IGenericValue; \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs new file mode 100644 index 0000000000..633c5c7eb4 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs @@ -0,0 +1,15 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL.Analysis; + + + + +public enum SymbolKind +{ + Variable, + Method +} + + +public record struct Symbol(Identifier Name, SymbolType Type, SymbolKind Kind); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs new file mode 100644 index 0000000000..3b83328655 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -0,0 +1,8 @@ +namespace Stride.Shaders.Parsing.SDSL.Analysis; + + + +public class SymbolTable +{ + Stack> Symbols = []; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs new file mode 100644 index 0000000000..6b5320ecfe --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs @@ -0,0 +1,12 @@ +namespace Stride.Shaders.Parsing.SDSL.Analysis; + + + +public abstract record SymbolType(); +public record Scalar() : SymbolType(); +public record Vector(int Size) : SymbolType(); +public record Matrix(int Rows, int Columns) : SymbolType(); +public record Array(int Size) : SymbolType(); +public record Struct(Dictionary Fields) : SymbolType(); +public record Buffer(SymbolType BaseType) : SymbolType(); +public record Texture(SymbolType BaseType) : SymbolType(); \ No newline at end of file From 3e743876d0ecd0f7c96b3d741e91efc1603f14d2 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 14 Aug 2024 12:15:37 +0200 Subject: [PATCH 0320/1182] Parsing compositions --- assets/SDSL/Commented.sdsl | 8 +++++ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 6 ++++ .../SDSL/AST/ShaderElements.cs | 1 + .../SDSL/Analysis/SymbolTable.cs | 20 ++++++++++++- .../SDSL/Analysis/SymbolTypes.cs | 20 ++++++++----- .../ShaderParsers/CompositionParsers.cs | 30 +++++++++++++++++++ .../ShaderParsers/ShaderClassParser.cs | 4 +++ .../ShaderParsers/ShaderElementParsers.cs | 12 +++++++- 8 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs diff --git a/assets/SDSL/Commented.sdsl b/assets/SDSL/Commented.sdsl index cc56833471..9ae3d3e6b6 100644 --- a/assets/SDSL/Commented.sdsl +++ b/assets/SDSL/Commented.sdsl @@ -6,8 +6,16 @@ shader Parent stream int a; } +shader Other +{ + stream int b; +} + shader MyShader : Parent { + + compose Other otherShader; + void MyMethod() { int a = 0; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4edaaa7cca..dc9f187005 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,6 +7,12 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : public List Attributes { get; set; } = []; } +public class ShaderCompose(Identifier name, ShaderMixin mixin, TextLocation info) : MethodOrMember(info) +{ + public Identifier Name { get; } = name; + public ShaderMixin Mixin { get; } = mixin; + public override string ToString() => $"compose {Name} {Mixin};"; +} public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null) : MethodOrMember(location, isStaged) { diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index 8229f07a58..e02e7b53ab 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -3,6 +3,7 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info); + public abstract class ShaderBuffer(Identifier name, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs index 3b83328655..81406bb604 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -1,8 +1,26 @@ +using Stride.Shaders.Parsing.SDSL.AST; + namespace Stride.Shaders.Parsing.SDSL.Analysis; public class SymbolTable { - Stack> Symbols = []; + public Dictionary DeclaredTypes { get; } = []; + public Stack> Symbols { get; } = []; + + public void Process(ShaderClass sclass) + { + DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass)); + foreach (var e in sclass.Elements) + { + if(e is ShaderMember member) + { + if (!DeclaredTypes.TryGetValue(member.Type.Name, out var mt)) + { + // mt = new SymbolType() + } + } + } + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs index 6b5320ecfe..e67e2b6c86 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs @@ -1,12 +1,18 @@ +using Stride.Shaders.Parsing.SDSL.AST; + namespace Stride.Shaders.Parsing.SDSL.Analysis; public abstract record SymbolType(); -public record Scalar() : SymbolType(); -public record Vector(int Size) : SymbolType(); -public record Matrix(int Rows, int Columns) : SymbolType(); -public record Array(int Size) : SymbolType(); -public record Struct(Dictionary Fields) : SymbolType(); -public record Buffer(SymbolType BaseType) : SymbolType(); -public record Texture(SymbolType BaseType) : SymbolType(); \ No newline at end of file +public sealed record MixinSymbol(ShaderClass Shader) : SymbolType(); +public sealed record Scalar() : SymbolType(); +public sealed record Vector(int Size) : SymbolType(); +public sealed record Matrix(int Rows, int Columns) : SymbolType(); +public sealed record Array(int Size) : SymbolType(); +public sealed record Struct(Dictionary Fields) : SymbolType(); +public sealed record Buffer(SymbolType BaseType, int Size) : SymbolType(); +public abstract record Texture(SymbolType BaseType) : SymbolType(); +public sealed record Texture1D(SymbolType BaseType, int Size) : SymbolType(); +public sealed record Texture2D(SymbolType BaseType, int Width, int Height) : SymbolType(); +public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : SymbolType(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs new file mode 100644 index 0000000000..3c4a6dab0f --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -0,0 +1,30 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + + +public record struct CompositionParser() : IParser +{ + public bool Match(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("compose", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if ( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.CreateError(scanner.Position))) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char(';', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(position))); + parsed = new(identifier, mixin, scanner.GetLocation(position..)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Mixin variable", scanner.CreateError(scanner.Position))); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 0e06b368e6..79b33520ba 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -137,6 +137,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { parsed = new ShaderMixin(identifier, scanner.GetLocation(..)); + var tmpPos = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) { @@ -148,7 +149,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else + { + scanner.Position = tmpPos; return true; + } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 881db4c214..64bcdedee6 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -54,11 +54,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = method; return true; } + else if(Compose(ref scanner, result, out var compose)) + { + compose.IsStaged = isStaged; + if(hasAttributes) + compose.Attributes = attributes.Attributes; + parsed = compose; + return true; + } else return CommonParsers.Exit(ref scanner, result, out parsed, position); } } - + public static bool Compose(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new CompositionParser().Match(ref scanner, result, out parsed, in orError); public static bool Struct(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderStructParser().Match(ref scanner, result, out parsed, in orError); From b215637cc649a818b4b4ffdb86f964ac7b2eb78a Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 14 Aug 2024 13:16:02 +0200 Subject: [PATCH 0321/1182] correction display --- src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs | 8 +++++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs index fa616c22d2..66987336a8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -58,9 +58,11 @@ public class ShaderMixin(Identifier name, TextLocation info) : Node(info) public Identifier Name { get; set; } = name; public ShaderExpressionList? Generics { get; set; } public override string ToString() - { - return $"{Name}<{Generics}>"; - } + => Generics switch + { + null => Name.Name, + _ => $"{Name}<{Generics}>" + }; } public abstract class ShaderMixinValue(TextLocation info) : Node(info); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index dc9f187005..83abc9d4f8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -11,7 +11,7 @@ public class ShaderCompose(Identifier name, ShaderMixin mixin, TextLocation info { public Identifier Name { get; } = name; public ShaderMixin Mixin { get; } = mixin; - public override string ToString() => $"compose {Name} {Mixin};"; + public override string ToString() => $"compose {Mixin} {Name};"; } public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null) : MethodOrMember(location, isStaged) From dfbe5c2104d370fe6c0d859509d5bf1d71daa063 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 14 Aug 2024 17:42:23 +0200 Subject: [PATCH 0322/1182] working on symbol table --- .../SDSL/Analysis/GlobalSymbolTypes.cs | 20 +++++++++ .../SDSL/Analysis/Symbol.cs | 7 ++- .../SDSL/Analysis/SymbolTable.cs | 43 ++++++++++++++++++- .../SDSL/Analysis/SymbolTypes.cs | 43 ++++++++++++++++--- 4 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs new file mode 100644 index 0000000000..64937b64dd --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs @@ -0,0 +1,20 @@ +using Stride.Shaders.Parsing.SDSL.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public static class GlobalShaderTypes +{ + static Dictionary mixins = []; + + + public static void Register(MixinSymbol symbol) + { + mixins[symbol.Name] = symbol; + } + public static MixinSymbol Get(string name) + { + return mixins[name]; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs index 633c5c7eb4..da627aae81 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs @@ -7,9 +7,12 @@ namespace Stride.Shaders.Parsing.SDSL.Analysis; public enum SymbolKind { + Constant, + ConstantGeneric, + Composition, + Method, Variable, - Method } -public record struct Symbol(Identifier Name, SymbolType Type, SymbolKind Kind); \ No newline at end of file +public record struct Symbol(string Name, SymbolType Type, SymbolKind Kind); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs index 81406bb604..64d41c08f3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -1,15 +1,17 @@ +using System.Security.Cryptography; +using System.Text.RegularExpressions; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL.Analysis; -public class SymbolTable +public partial class SymbolTable { public Dictionary DeclaredTypes { get; } = []; public Stack> Symbols { get; } = []; - public void Process(ShaderClass sclass) + public void Process(ShaderClass sclass, Dictionary? globalSymbols = null) { DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass)); foreach (var e in sclass.Elements) @@ -23,4 +25,41 @@ public void Process(ShaderClass sclass) } } } + + [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))$")] + private static partial Regex ScalarPattern(); + [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))([2-4])$")] + private static partial Regex VectorPattern(); + [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))([2-4])x([2-4])$")] + private static partial Regex MatrixPattern(); + [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))[\s\n]*\[[\s\n]*([0-9]+)?[\s\n]*\]$")] + private static partial Regex ArrayPattern(); + public SymbolType ParseType(string typename) + { + if (ScalarPattern().IsMatch(typename)) + return new Scalar(typename); + else if (VectorPattern().IsMatch(typename)) + { + var matches = VectorPattern().Match(typename); + var size = int.Parse(matches.Groups[6].ValueSpan); + var baseType = matches.Groups[1].Value; + return new Vector(new Scalar(baseType), size); + } + else if (MatrixPattern().IsMatch(typename)) + { + var matches = MatrixPattern().Match(typename); + var width = int.Parse(matches.Groups[6].ValueSpan); + var length = int.Parse(matches.Groups[7].ValueSpan); + var baseType = matches.Groups[1].Value; + return new Matrix(new Scalar(baseType), width, length); + } + else if (ArrayPattern().IsMatch(typename)) + { + var matches = ArrayPattern().Match(typename); + return new Array(ParseType(matches.Groups[1].Value), int.Parse(matches.Groups[6].ValueSpan)); + } + else throw new NotImplementedException(); + } + + } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs index e67e2b6c86..01a945abcd 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs @@ -1,3 +1,4 @@ +using System.Dynamic; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL.Analysis; @@ -5,14 +6,44 @@ namespace Stride.Shaders.Parsing.SDSL.Analysis; public abstract record SymbolType(); -public sealed record MixinSymbol(ShaderClass Shader) : SymbolType(); -public sealed record Scalar() : SymbolType(); -public sealed record Vector(int Size) : SymbolType(); -public sealed record Matrix(int Rows, int Columns) : SymbolType(); -public sealed record Array(int Size) : SymbolType(); + +public sealed record Scalar(string TypeName) : SymbolType(); +public sealed record Vector(Scalar BaseType, int Size) : SymbolType(); +public sealed record Matrix(Scalar BaseType, int Rows, int Columns) : SymbolType(); +public sealed record Array(SymbolType BaseType, int Size) : SymbolType(); public sealed record Struct(Dictionary Fields) : SymbolType(); public sealed record Buffer(SymbolType BaseType, int Size) : SymbolType(); + + public abstract record Texture(SymbolType BaseType) : SymbolType(); public sealed record Texture1D(SymbolType BaseType, int Size) : SymbolType(); public sealed record Texture2D(SymbolType BaseType, int Width, int Height) : SymbolType(); -public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : SymbolType(); \ No newline at end of file +public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : SymbolType(); + + +public sealed record MixinSymbol( + string Name, + List Components +) : SymbolType() +{ + public T Get(string name) + where T : SymbolType + { + foreach (var e in Components) + if (e is T r && e.Name == name) + return r; + throw new ArgumentException($"{name} not found in Mixin {Name}"); + } + public bool TryGet(string name, out T value) + where T : SymbolType + { + foreach (var e in Components) + if (e is T r && e.Name == name) + { + value = r; + return true; + } + value = null!; + return false; + } +} From 483a3f58241b071d6647d6c896bae0599fda2f16 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Fri, 16 Aug 2024 18:47:34 +0200 Subject: [PATCH 0323/1182] added functions --- .../SDSL/Analysis/GlobalSymbolTypes.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs index 64937b64dd..0ed9ebe543 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs @@ -11,10 +11,31 @@ public static class GlobalShaderTypes public static void Register(MixinSymbol symbol) { - mixins[symbol.Name] = symbol; + mixins.Add(symbol.Name, symbol); } + + public static bool TryRegister(MixinSymbol symbol) + { +#if NET8_0_OR_GREATER + return mixins.TryAdd(symbol.Name, symbol); +#else + if (mixins.ContainsKey(symbol.Name)) + return false; + else + { + Register(symbol); + return true; + } +#endif + } + public static MixinSymbol Get(string name) { return mixins[name]; } + + public static bool TryGet(string name, out MixinSymbol symbol) + { + return mixins.TryGetValue(name, out symbol); + } } \ No newline at end of file From 6eaf97d633aedc23f2797805594da964ccdd5313 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 9 Sep 2024 00:08:58 +0200 Subject: [PATCH 0324/1182] refactor and working on SDFX --- src/SoftTouch.Spirv | 2 +- src/Stride.Shaders.Parsing/ASTNode.cs | 13 ++++++ .../{SDSL => }/Grammar.cs | 0 .../{SDSL => }/IParser.cs | 0 .../{SDSL => }/ParseResult.cs | 0 .../SDFX/AST/Effect.Flow.cs | 42 +++++++++++++++++++ src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 32 ++++++++++++++ .../SDSL/AST/ASTNode.cs | 31 -------------- 8 files changed, 88 insertions(+), 32 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/ASTNode.cs rename src/Stride.Shaders.Parsing/{SDSL => }/Grammar.cs (100%) rename src/Stride.Shaders.Parsing/{SDSL => }/IParser.cs (100%) rename src/Stride.Shaders.Parsing/{SDSL => }/ParseResult.cs (100%) create mode 100644 src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs create mode 100644 src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index ee22e93c8e..e5834b5406 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit ee22e93c8e72bcbfe74ce47908c8d7166b09d267 +Subproject commit e5834b5406d21d37b1a545876d271254a98b3e29 diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders.Parsing/ASTNode.cs new file mode 100644 index 0000000000..d2bdd263e5 --- /dev/null +++ b/src/Stride.Shaders.Parsing/ASTNode.cs @@ -0,0 +1,13 @@ +using System.Text; + +namespace Stride.Shaders.Parsing; + +public abstract class Node(TextLocation info) +{ + public TextLocation Info { get; set; } = info; +} +public class ValueNode(TextLocation info) : Node(info) +{ + public string? Type { get; set; } = null; +} +public class NoNode() : Node(new()); diff --git a/src/Stride.Shaders.Parsing/SDSL/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Grammar.cs rename to src/Stride.Shaders.Parsing/Grammar.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/IParser.cs b/src/Stride.Shaders.Parsing/IParser.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/IParser.cs rename to src/Stride.Shaders.Parsing/IParser.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/ParseResult.cs b/src/Stride.Shaders.Parsing/ParseResult.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/ParseResult.cs rename to src/Stride.Shaders.Parsing/ParseResult.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs new file mode 100644 index 0000000000..119429b10c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs @@ -0,0 +1,42 @@ +namespace Stride.Shaders.Parsing.SDFX.AST; + +public class EffectFlow(TextLocation info) : EffectStatement(info); + +public class ConditionalFlow(If first, TextLocation info) : EffectFlow(info) +{ + public If If { get; set; } = first; + public List ElseIfs { get; set; } = []; + public Else? Else { get; set; } + + public override string ToString() + { + return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; + } +} +public class If(SDSL.AST.Expression condition, EffectStatement body, TextLocation info) : EffectFlow(info) +{ + public SDSL.AST.Expression Condition { get; set; } = condition; + public EffectStatement Body { get; set; } = body; + + public override string ToString() + { + return $"if({Condition})\n{Body}"; + } +} + +public class ElseIf(SDSL.AST.Expression condition, EffectStatement body, TextLocation info) : If(condition, body, info) +{ + public override string ToString() + { + return $"else if({Condition}){Body}"; + } +} + +public class Else(EffectStatement body, TextLocation info) : EffectFlow(info) +{ + public EffectStatement Body { get; set; } = body; + public override string ToString() + { + return $"else {Body}"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs new file mode 100644 index 0000000000..edfd85d7c7 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -0,0 +1,32 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDFX.AST; + + +public class Effect(TextLocation info) : Node(info) +{ + public List Members { get; set; } = []; +} + +public abstract class EffectStatement(TextLocation info) : Node(info); + +public class MixinCompose(Identifier name, TextLocation info) : EffectStatement(info) +{ + public Identifier MixinName { get; set; } = name; +} + +public class ComposeMixin(Identifier name, TextLocation info) : EffectStatement(info) +{ + public Identifier MixinName { get; set; } = name; +} +public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) +{ + public Identifier ParamsName { get; set; } = name; +} + +public class EffectBlock(TextLocation info) : EffectStatement(info) +{ + public List Statements { get; set; } = []; +} + + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs deleted file mode 100644 index 0bc481588a..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ASTNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Text; - -namespace Stride.Shaders.Parsing.SDSL.AST; - -public abstract class Node(TextLocation info) -{ - public TextLocation Info { get; set; } = info; -} -public class ValueNode(TextLocation info) : Node(info) -{ - public string? Type { get; set; } = null; -} -public class NoNode() : Node(new()); - - -public class CodeSnippets() : Node(new()) -{ - public List Snippets { get; set; } = []; - - public string ToCode() - { - var builder = new StringBuilder(); - foreach (var s in Snippets) - builder.Append(s.Info.Text); - return builder.ToString(); - } -} - -public class CodeNode(TextLocation info) : Node(info); -public class Comment(TextLocation info) : CodeNode(info); -public class Code(TextLocation info) : CodeNode(info); \ No newline at end of file From a98c56cd660e07efd191ae9afa632c5e5d354cd7 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 9 Sep 2024 15:35:05 +0200 Subject: [PATCH 0325/1182] added more AST types for SDFX --- .../SDFX/AST/Effect.Parameters.cs | 18 +++++++++ src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 39 ++++++++++++++----- 2 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs new file mode 100644 index 0000000000..cfd8a5cfa3 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs @@ -0,0 +1,18 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDFX.AST; + + +public class EffectParameters(Identifier name, TextLocation info) : Node(info) +{ + public Identifier Name { get; set; } = name; + public List Parameters { get; set; } = []; +} + + +public class EffectParameter(TypeName type, Identifier identifier, TextLocation info, Expression? value = null) : Node(info) +{ + public TypeName Type { get; set; } = type; + public Identifier Identifier { get; set;} = identifier; + public Expression? DefaultValue { get; set; } = value; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index edfd85d7c7..a5bf036369 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -1,27 +1,48 @@ -using Stride.Shaders.Parsing.SDSL.AST; - namespace Stride.Shaders.Parsing.SDFX.AST; -public class Effect(TextLocation info) : Node(info) +public class EffectFile(TextLocation info) : Node(info) +{ + public List RootClasses { get; set; } = []; + public List Namespaces { get; set; } = []; + + public override string ToString() + { + return $"{string.Join("\n", RootClasses)}\n\n{string.Join("\n", Namespaces)}"; + } +} + +public class EffectNamespace(TextLocation info) : Node(info) +{ + public List NamespacePath { get; set; } = []; + public string? Namespace { get; set; } + public List ShaderClasses { get; set; } = []; + + public override string ToString() + { + return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", ShaderClasses)}End\n"; + } +} + +public class EffectClass(TextLocation info) : Node(info) { public List Members { get; set; } = []; } public abstract class EffectStatement(TextLocation info) : Node(info); -public class MixinCompose(Identifier name, TextLocation info) : EffectStatement(info) +public class MixinCompose(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) { - public Identifier MixinName { get; set; } = name; + public SDSL.AST.Identifier MixinName { get; set; } = name; } -public class ComposeMixin(Identifier name, TextLocation info) : EffectStatement(info) +public class ComposeMixin(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) { - public Identifier MixinName { get; set; } = name; + public SDSL.AST.Identifier MixinName { get; set; } = name; } -public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) +public class UsingParams(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) { - public Identifier ParamsName { get; set; } = name; + public SDSL.AST.Identifier ParamsName { get; set; } = name; } public class EffectBlock(TextLocation info) : EffectStatement(info) From 3c892ea797e5d9b51648c376812b6004dca461bb Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 3 Oct 2024 13:23:40 +0200 Subject: [PATCH 0326/1182] updating spirv --- src/SoftTouch.Spirv | 2 +- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 15 +++-- .../SDFX/Parsers/EffectStatementParsers.cs | 67 +++++++++++++++++++ .../SDFX/Parsers/ParamsParsers.cs | 45 +++++++++++++ 4 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv index e5834b5406..1687e28513 160000 --- a/src/SoftTouch.Spirv +++ b/src/SoftTouch.Spirv @@ -1 +1 @@ -Subproject commit e5834b5406d21d37b1a545876d271254a98b3e29 +Subproject commit 1687e285131b752962901ec3bc5e4a9e67be344a diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index a5bf036369..f33f06c138 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -31,14 +31,21 @@ public class EffectClass(TextLocation info) : Node(info) public abstract class EffectStatement(TextLocation info) : Node(info); -public class MixinCompose(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) +public class MixinUse(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) { - public SDSL.AST.Identifier MixinName { get; set; } = name; + public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; } -public class ComposeMixin(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) +public abstract class Composable(); + +public class ComposeMixin(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) +{ + public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; +} + +public class ComposeParams(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) { - public SDSL.AST.Identifier MixinName { get; set; } = name; + public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; } public class UsingParams(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) { diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs new file mode 100644 index 0000000000..b93ce38db3 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -0,0 +1,67 @@ +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.SDFX.Parsers; + + +public record struct EffectStatementParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + throw new NotImplementedException(); + } + + +} + + +public record struct MixinComposeParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ComposeMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("mixin", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && Terminals.Literal("compose", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var name) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('=', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + + ) + { + if ( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct MixinParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("mixin", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs new file mode 100644 index 0000000000..c40d65f80f --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDFX.AST; + +namespace Stride.Shaders.Parsing.SDFX.Parsers; + + +public record struct ParamsParsers : IParser +{ + public bool Match(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("params", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if(LiteralsParser.TypeName(ref scanner, result, out var paramsName)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if(Terminals.Char('{', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + // while() + } + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ParameterParser : IParser +{ + public bool Match(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + + if(LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if(LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + + } + } + + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } +} \ No newline at end of file From f26399bc04354f7152dad8e01812cc8e22caece2 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 4 Oct 2024 16:03:38 +0200 Subject: [PATCH 0327/1182] update git modules and refactor everything --- .gitmodules | 6 +- SDSL.sln | 133 +++++++++--------- assets/SDSL/Commented.sdsl | 2 +- src/SoftTouch.Spirv | 1 - src/Stride.Shaders.Compilers/SpirvOpt.cs | 4 +- .../Stride.Shaders.Compilers.csproj | 2 +- src/Stride.Shaders.Parsing/ExternalInit.cs | 16 --- .../SDSL/AST/Literals.cs | 6 +- .../SDSL/Analysis/GlobalSymbolTypes.cs | 12 +- .../SDSL/Analysis/SymbolTable.cs | 2 +- .../Parsers/LiteralParsers/NumberParsers.cs | 21 --- .../Scanners/TextLocation.cs | 4 - src/Stride.Shaders.Parsing/SpanExtensions.cs | 66 --------- .../Stride.Shaders.Parsing.csproj | 2 +- submodules/SpirvHeaders | 1 + 15 files changed, 78 insertions(+), 200 deletions(-) delete mode 160000 src/SoftTouch.Spirv delete mode 100644 src/Stride.Shaders.Parsing/ExternalInit.cs delete mode 100644 src/Stride.Shaders.Parsing/SpanExtensions.cs create mode 160000 submodules/SpirvHeaders diff --git a/.gitmodules b/.gitmodules index f330f309db..622a474e74 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "src/SoftTouch.Spirv"] - path = src/SoftTouch.Spirv - url = https://github.com/ykafia/SoftTouch.Spirv +[submodule "submodules/SpirvHeaders"] + path = submodules/SpirvHeaders + url = https://github.com/KhronosGroup/SPIRV-Headers diff --git a/SDSL.sln b/SDSL.sln index ee29d6a6dc..199fbe3fdf 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -3,94 +3,91 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9967EA99-9716-43A9-B6BA-E5975F08250D}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F15E41A8-FD75-462B-9BB0-DCE18A6AD334}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{66A8722A-4CE8-422D-9467-7B2C8FCB4734}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{6641B2F9-0E20-43E5-BF88-44B02B32117B}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{92AE8C5F-4A4F-4A97-9561-86315D09F910}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{DA4DEF22-680A-4763-8016-5E62A7BEA975}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{06F65A22-F517-49B4-B4A5-F38D60555B2A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{E59CE683-4805-4FD3-98EB-4F704C253F1A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{55190824-293F-49AA-B068-95F69E949055}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SoftTouch.Spirv", "SoftTouch.Spirv", "{5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shaders.Spirv", "Stride.Shaders.Spirv", "{6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{54A7F69B-8687-4302-A545-77024C017E0B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv", "src\SoftTouch.Spirv\src\SoftTouch.Spirv\SoftTouch.Spirv.csproj", "{FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv\Stride.Shaders.Spirv.csproj", "{4EC134E1-5B64-497B-B129-4E1B4806E466}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Core", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Core\SoftTouch.Spirv.Core.csproj", "{A23537C0-1B9E-45FB-B4E3-4B7B40443220}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Experiments", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Experiments\Stride.Shaders.Spirv.Experiments.csproj", "{07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Experiments", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Experiments\SoftTouch.Spirv.Experiments.csproj", "{56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{1205976E-A945-4475-AD87-C63527D5A63A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SoftTouch.Spirv.Generators", "src\SoftTouch.Spirv\src\SoftTouch.Spirv.Generators\SoftTouch.Spirv.Generators.csproj", "{5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.AvaloniaViewer", "src\Stride.Shaders.AvaloniaViewer\Stride.Shaders.AvaloniaViewer.csproj", "{107AF929-CAC1-40DE-895D-71A61C9AED58}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core.Benchmarks", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core.Benchmarks\Stride.Shaders.Spirv.Core.Benchmarks.csproj", "{8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Debug|Any CPU.Build.0 = Debug|Any CPU - {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Release|Any CPU.ActiveCfg = Release|Any CPU - {66A8722A-4CE8-422D-9467-7B2C8FCB4734}.Release|Any CPU.Build.0 = Release|Any CPU - {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92AE8C5F-4A4F-4A97-9561-86315D09F910}.Release|Any CPU.Build.0 = Release|Any CPU - {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DA4DEF22-680A-4763-8016-5E62A7BEA975}.Release|Any CPU.Build.0 = Release|Any CPU - {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D}.Release|Any CPU.Build.0 = Release|Any CPU - {55190824-293F-49AA-B068-95F69E949055}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55190824-293F-49AA-B068-95F69E949055}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55190824-293F-49AA-B068-95F69E949055}.Release|Any CPU.Build.0 = Release|Any CPU - {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E}.Release|Any CPU.Build.0 = Release|Any CPU - {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A23537C0-1B9E-45FB-B4E3-4B7B40443220}.Release|Any CPU.Build.0 = Release|Any CPU - {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24}.Release|Any CPU.Build.0 = Release|Any CPU - {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0}.Release|Any CPU.Build.0 = Release|Any CPU - {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {107AF929-CAC1-40DE-895D-71A61C9AED58}.Debug|Any CPU.Build.0 = Debug|Any CPU - {107AF929-CAC1-40DE-895D-71A61C9AED58}.Release|Any CPU.ActiveCfg = Release|Any CPU - {107AF929-CAC1-40DE-895D-71A61C9AED58}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Release|Any CPU.Build.0 = Release|Any CPU + {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Release|Any CPU.Build.0 = Release|Any CPU + {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Release|Any CPU.Build.0 = Release|Any CPU + {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Release|Any CPU.Build.0 = Release|Any CPU + {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Release|Any CPU.Build.0 = Release|Any CPU + {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Release|Any CPU.Build.0 = Release|Any CPU + {4EC134E1-5B64-497B-B129-4E1B4806E466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EC134E1-5B64-497B-B129-4E1B4806E466}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EC134E1-5B64-497B-B129-4E1B4806E466}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EC134E1-5B64-497B-B129-4E1B4806E466}.Release|Any CPU.Build.0 = Release|Any CPU + {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Release|Any CPU.Build.0 = Release|Any CPU + {1205976E-A945-4475-AD87-C63527D5A63A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1205976E-A945-4475-AD87-C63527D5A63A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1205976E-A945-4475-AD87-C63527D5A63A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1205976E-A945-4475-AD87-C63527D5A63A}.Release|Any CPU.Build.0 = Release|Any CPU + {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection GlobalSection(NestedProjects) = preSolution - {66A8722A-4CE8-422D-9467-7B2C8FCB4734} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {92AE8C5F-4A4F-4A97-9561-86315D09F910} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {DA4DEF22-680A-4763-8016-5E62A7BEA975} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {EBDE1FC9-EDB9-417D-B0B7-B1DC1855404D} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {55190824-293F-49AA-B068-95F69E949055} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9} = {9967EA99-9716-43A9-B6BA-E5975F08250D} - {54A7F69B-8687-4302-A545-77024C017E0B} = {5BBFE662-7CE8-45F2-A0A9-F17F6D7758C9} - {FF203D61-F0DB-41A4-8AE8-2A0AC8AB0B0E} = {54A7F69B-8687-4302-A545-77024C017E0B} - {A23537C0-1B9E-45FB-B4E3-4B7B40443220} = {54A7F69B-8687-4302-A545-77024C017E0B} - {56F4CE74-6000-4ED5-BAE9-D6A22ABFBD24} = {54A7F69B-8687-4302-A545-77024C017E0B} - {5BC0A4F1-83C3-4F18-A37A-C4C9745EA3C0} = {54A7F69B-8687-4302-A545-77024C017E0B} - {107AF929-CAC1-40DE-895D-71A61C9AED58} = {9967EA99-9716-43A9-B6BA-E5975F08250D} + {6641B2F9-0E20-43E5-BF88-44B02B32117B} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {06F65A22-F517-49B4-B4A5-F38D60555B2A} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {E59CE683-4805-4FD3-98EB-4F704C253F1A} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} + {4EC134E1-5B64-497B-B129-4E1B4806E466} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} + {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} + {1205976E-A945-4475-AD87-C63527D5A63A} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} + {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} EndGlobalSection EndGlobal diff --git a/assets/SDSL/Commented.sdsl b/assets/SDSL/Commented.sdsl index 9ae3d3e6b6..748d2ae462 100644 --- a/assets/SDSL/Commented.sdsl +++ b/assets/SDSL/Commented.sdsl @@ -1,4 +1,4 @@ -namespace MyNamespace.SoftTouch.Hello; +namespace MyNamespace.Stride.Shaders.Hello; shader Parent { diff --git a/src/SoftTouch.Spirv b/src/SoftTouch.Spirv deleted file mode 160000 index 1687e28513..0000000000 --- a/src/SoftTouch.Spirv +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1687e285131b752962901ec3bc5e4a9e67be344a diff --git a/src/Stride.Shaders.Compilers/SpirvOpt.cs b/src/Stride.Shaders.Compilers/SpirvOpt.cs index 4e1a02d38e..f718caf553 100644 --- a/src/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/src/Stride.Shaders.Compilers/SpirvOpt.cs @@ -3,8 +3,8 @@ using Silk.NET.Direct3D.Compilers; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; -using SoftTouch.Spirv.Core; -using SoftTouch.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Compilers; diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 49d056901c..ab040063ff 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -2,7 +2,7 @@ - + diff --git a/src/Stride.Shaders.Parsing/ExternalInit.cs b/src/Stride.Shaders.Parsing/ExternalInit.cs deleted file mode 100644 index d6df8f163c..0000000000 --- a/src/Stride.Shaders.Parsing/ExternalInit.cs +++ /dev/null @@ -1,16 +0,0 @@ -#if NETSTANDARD2_0 -using System.ComponentModel; - -namespace System.Runtime.CompilerServices -{ - /// - /// Reserved to be used by the compiler for tracking metadata. - /// This class should not be used by developers in source code. - /// This dummy class is required to compile records when targeting .NET Standard - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public static class IsExternalInit - { - } -} -#endif \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index eb0026ae58..e8b4c20a52 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -17,11 +17,7 @@ public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) } public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info) : NumberLiteral(info) -#if NET8_0_OR_GREATER where T : struct, INumber -#else - where T : struct -#endif { public Suffix Suffix { get; set; } = suffix; public T Value { get; set; } = value; @@ -90,6 +86,8 @@ public class Identifier(string name, TextLocation info) : Literal(info) { public string Name { get; set; } = name; + public static implicit operator string(Identifier identifier) => identifier.Name; + public override string ToString() { return $"{Name}"; diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs index 0ed9ebe543..ac366aab63 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs @@ -16,17 +16,7 @@ public static void Register(MixinSymbol symbol) public static bool TryRegister(MixinSymbol symbol) { -#if NET8_0_OR_GREATER return mixins.TryAdd(symbol.Name, symbol); -#else - if (mixins.ContainsKey(symbol.Name)) - return false; - else - { - Register(symbol); - return true; - } -#endif } public static MixinSymbol Get(string name) @@ -34,7 +24,7 @@ public static MixinSymbol Get(string name) return mixins[name]; } - public static bool TryGet(string name, out MixinSymbol symbol) + public static bool TryGet(string name, out MixinSymbol? symbol) { return mixins.TryGetValue(name, out symbol); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs index 64d41c08f3..106a08db0d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -13,7 +13,7 @@ public partial class SymbolTable public void Process(ShaderClass sclass, Dictionary? globalSymbols = null) { - DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass)); + DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass.Name, [])); foreach (var e in sclass.Elements) { if(e is ShaderMember member) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index c378bfd47a..2c249de7db 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -40,21 +40,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var numPos = scanner.Position; if (suffix.Match(ref scanner, null!, out Suffix suf)) { -#if NETSTANDARD2_0 - node = new(suf, long.Parse(scanner.Span[position..numPos].ToString()), scanner.GetLocation(position, scanner.Position)); -#else node = new(suf, long.Parse(scanner.Span[position..numPos]), scanner.GetLocation(position, scanner.Position)); -#endif return true; } else { var memory = scanner.Memory[position..scanner.Position]; -#if NETSTANDARD2_0 - node = new(new(32, false, true), long.Parse(memory.Span.ToString()), new(scanner.Memory, position..scanner.Position)); -#else node = new(new(32, false, true), long.Parse(memory.Span), new(scanner.Memory, position..scanner.Position)); -#endif return true; } } @@ -81,11 +73,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (Terminals.Digit(ref scanner, advance: true)) ; if (suffix.Match(ref scanner, result, out Suffix s)) -#if NETSTANDARD2_0 - node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position].ToString()), new(scanner.Memory, position..scanner.Position)); -#else node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); -#endif return true; } else if (Terminals.Digit(ref scanner, 1.., advance: true)) @@ -106,12 +94,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; else len += 1; -#if NETSTANDARD2_0 - node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position+len)].ToString()), new(scanner.Memory, position..scanner.Position)); -#else node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position + len)]), new(scanner.Memory, position..scanner.Position)); -#endif - return true; } else if (Terminals.Digit(ref scanner, 0)) @@ -124,11 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (!suffix.Match(ref scanner, result, out s)) s = new(32, true, true); } -#if NETSTANDARD2_0 - node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position].ToString()), new(scanner.Memory, position..scanner.Position)); -#else node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); -#endif return true; } else return CommonParsers.Exit(ref scanner, result, out node, position, orError); diff --git a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs index c647b990c5..f7897c252b 100644 --- a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs +++ b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs @@ -12,11 +12,7 @@ public record struct TextLocation(ReadOnlyMemory Original, Range Range) public readonly int Column => Range.StartsAt(Original.Length) - Original.Span[..Range.StartsAt(Original.Length)].LastIndexOf('\n'); public readonly override string ToString() { - #if NETSTANDARD2_0 - return $"[l{Line}-c{Column}]\n{Text.Span.ToString()}"; - #else return $"[l{Line}-c{Column}]\n{Text.Span}"; - #endif } } diff --git a/src/Stride.Shaders.Parsing/SpanExtensions.cs b/src/Stride.Shaders.Parsing/SpanExtensions.cs deleted file mode 100644 index 46443d41fc..0000000000 --- a/src/Stride.Shaders.Parsing/SpanExtensions.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if NETSTANDARD2_0 -public static class SpanExtensions -{ - public static int Count(this ReadOnlySpan span, char c) - { - int count = 0; - foreach(var item in span) - if(c == item) - count +=1; - return count; - } - public static int Count(this ReadOnlySpan span, int c) - { - int count = 0; - foreach(var item in span) - if(c == item) - count +=1; - return count; - } - public static int Count(this Span span, char c) - { - int count = 0; - foreach(var item in span) - if(c == item) - count +=1; - return count; - } - public static int Count(this Span span, int c) - { - int count = 0; - foreach(var item in span) - if(c == item) - count +=1; - return count; - } - public static ReadOnlySpan TrimEnd(this ReadOnlySpan span) - { - for(int i = span.Length - 1; i >= 0; i++) - if(!char.IsWhiteSpace(span[i])) - return span[..i]; - return span; - } - public static ReadOnlyMemory TrimEnd(this ReadOnlyMemory memory) - { - for(int i = memory.Length - 1; i >= 0; i++) - if(!char.IsWhiteSpace(memory.Span[i])) - return memory[..i]; - return memory; - } - public static ReadOnlySpan TrimStart(this ReadOnlySpan span) - { - for(int i = 0; i < span.Length; i++) - if(!char.IsWhiteSpace(span[i])) - return span[i..]; - return span; - } - public static ReadOnlyMemory TrimStart(this ReadOnlyMemory memory) - { - for(int i = 0; i < memory.Length; i++) - if(!char.IsWhiteSpace(memory.Span[i])) - return memory[i..]; - return memory; - } -} - -#endif \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index e0b374d689..f2774bdd2d 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -1,7 +1,7 @@  - net8.0;netstandard2.0 + net8.0 enable enable latest diff --git a/submodules/SpirvHeaders b/submodules/SpirvHeaders new file mode 160000 index 0000000000..a62b032007 --- /dev/null +++ b/submodules/SpirvHeaders @@ -0,0 +1 @@ +Subproject commit a62b032007b2e7a69f24a195cbfbd0cf22d31bb0 From 6971a64d2a6d865350bdb9c58df372822e391943 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 7 Oct 2024 10:18:35 +0200 Subject: [PATCH 0328/1182] added back the spirv library --- .../Stride.Shaders.Parsing.csproj | 5 - ...re.Benchmarks.ParserBench-report-github.md | 16 + ...irv.Core.Benchmarks.ParserBench-report.csv | 5 + ...rv.Core.Benchmarks.ParserBench-report.html | 33 + .../ParserBench.cs | 55 ++ .../Program.cs | 10 + ...tride.Shaders.Spirv.Core.Benchmarks.csproj | 18 + .../Stride.Shaders.Spirv.Core/Bound.cs | 28 + .../Buffers/BufferBase.cs | 32 + .../Buffers/ExpandableBuffer.cs | 89 ++ .../Buffers/IMutSpirvBuffer.cs | 41 + .../Buffers/ISpirvBuffer.cs | 19 + .../Buffers/Multi/FunctionBufferCollection.cs | 116 +++ .../Multi/MultiBuffer.LocalVariables.cs | 58 ++ .../Buffers/Multi/MultiBuffer.Variables.cs | 45 ++ .../Buffers/Multi/MultiBuffer.cs | 214 +++++ .../Buffers/Single/UnsortedWordBuffer.cs | 56 ++ .../Buffers/Single/WordBuffer.Parse.cs | 25 + .../Buffers/Single/WordBuffer.cs | 211 +++++ .../Buffers/SortedFunctionBufferCollection.cs | 92 +++ .../Buffers/SortedWordBuffer.cs | 74 ++ .../Buffers/SpirvBuffer.cs | 111 +++ .../Buffers/SpirvMemory.cs | 32 + .../Buffers/SpirvSpan.cs | 60 ++ .../Disassembly/DisWriter.cs | 97 +++ .../Disassembly/Disassembler.cs | 237 ++++++ .../ISpirvElement.cs | 185 +++++ .../Information/InstructionInfo.Order.cs | 102 +++ .../Information/InstructionInfo.cs | 41 + .../Information/LogicalOperand.Size.cs | 75 ++ .../Information/LogicalOperand.cs | 32 + .../Information/LogicalOperandArray.cs | 101 +++ .../Literals/IFromSpirv.cs | 13 + .../Literals/ILiteralNumber.cs | 13 + .../Literals/IdMemorySemantics.cs | 15 + .../Literals/IdRef.cs | 26 + .../Literals/IdResult.cs | 36 + .../Literals/IdResultType.cs | 37 + .../Literals/IdScope.cs | 36 + .../Literals/LiteralFloat.cs | 132 +++ .../Literals/LiteralInteger.cs | 121 +++ .../Literals/LiteralString.cs | 125 +++ .../Literals/PairIdRefIdRef.cs | 35 + .../Literals/PairIdRefLiteralInteger.cs | 34 + .../Literals/PairLiteralIntegerIdRef.cs | 34 + .../Literals/SpvOp.cs | 19 + .../MemoryInstruction.cs | 52 ++ .../MutRefInstruction.cs | 77 ++ .../OperandQuantifier.cs | 8 + .../Parsing/FilteredEnumerator.cs | 144 ++++ .../Parsing/InstructionEnumerator.cs | 63 ++ .../Parsing/InstructionFinder.cs | 42 + .../Parsing/LambdaFilteredEnumerator.cs | 43 + .../Parsing/OperandEnumerator.cs | 250 ++++++ .../Parsing/OrderedEnumerator.cs | 136 ++++ .../Parsing/RefHeader.cs | 33 + .../Parsing/RefInstructions.cs | 66 ++ .../Parsing/SpirvHeader.cs | 92 +++ .../Parsing/SpirvReader.cs | 72 ++ .../Parsing/SpirvWriter.cs | 47 ++ .../RefInstruction.cs | 142 ++++ .../Stride.Shaders.Spirv.Core/SpvLiteral.cs | 79 ++ .../Stride.Shaders.Spirv.Core.csproj | 18 + .../Validation/ValidationPass.cs | 7 + .../Validation/Validator.cs | 12 + .../Program.cs | 174 ++++ .../Stride.Shaders.Spirv.Experiments.csproj | 14 + .../Extensions/spirv.sdsl.grammar-ext.json | 212 +++++ .../SPVGenerator.Extensions.cs | 23 + .../SPVGenerator.Info.cs | 162 ++++ .../SPVGenerator.Naming.cs | 193 +++++ .../SPVGenerator.SDSLOp.cs | 60 ++ .../SPVGenerator.cs | 237 ++++++ .../Stride.Shaders.Spirv.Generators.csproj | 42 + .../Stride.Shaders.Spirv/Composable.cs | 14 + .../CompositionSourceProvider.cs | 33 + .../MixinFilteredInstructionEnumerator.cs | 67 ++ .../Enumerators/MixinInstructionEnumerator.cs | 63 ++ .../SortedMixinInstructionEnumerator.cs | 73 ++ .../Mixer/Generating-CFG.md | 86 ++ .../Mixer/Mixer.BaseTypes.cs | 273 +++++++ .../Mixer/Mixer.Fluent.Compose.cs | 42 + .../Mixer/Mixer.Fluent.EntryPoint.cs | 44 + .../Mixer/Mixer.Fluent.Inherit.cs | 26 + .../Mixer.FunctionBuilder.CallFunction.cs | 757 ++++++++++++++++++ .../Mixer.FunctionBuilder.Conditionals.cs | 50 ++ .../Mixer/Mixer.FunctionBuilder.Glsl.cs | 447 +++++++++++ .../Mixer/Mixer.FunctionBuilder.Util.cs | 354 ++++++++ .../Mixer/Mixer.FunctionBuilder.cs | 194 +++++ .../Stride.Shaders.Spirv/Mixer/Mixer.IO.cs | 55 ++ .../Stride.Shaders.Spirv/Mixer/Mixer.cs | 249 ++++++ .../Stride.Shaders.Spirv/Mixer/MixerBase.cs | 35 + .../Mixin/FullMixinInstructions.cs | 55 ++ .../Stride.Shaders.Spirv/Mixin/Mixin.cs | 61 ++ .../Mixin/MixinInstruction.cs | 29 + .../Mixin/MixinInstructions.cs | 30 + .../Mixin/MixinParents.cs | 105 +++ .../Stride.Shaders.Spirv/MixinBuffer.cs | 119 +++ .../Stride.Shaders.Spirv/MixinCollection.cs | 93 +++ .../Stride.Shaders.Spirv/MixinGraph.cs | 92 +++ .../MixinSourceProvider.cs | 37 + .../Processing/BoundReducer.cs | 127 +++ .../Processing/CapabilitiesCompute.cs | 62 ++ .../Processing/CompressBuffer.cs | 30 + .../Processing/FunctionVariableOrderer.cs | 57 ++ .../Processing/INanoPass.cs | 17 + .../Processing/IOReplace.cs | 74 ++ .../Processing/IOVariableDecorator.cs | 505 ++++++++++++ .../Processing/IPostProcessorSubPass.cs | 14 + .../Processing/IdRefOffsetter.cs | 41 + .../MemoryModelDuplicatesRemover.cs | 42 + .../Processing/MixinMerger.cs | 36 + .../Processing/PostProcessor.cs | 48 ++ .../Processing/SDSLOpRemover.cs | 46 ++ .../Processing/TypeDuplicatesRemover.cs | 206 +++++ .../Stride.Shaders.Spirv.csproj | 17 + .../Stride.Shaders.Spirv/thinking.md | 35 + 117 files changed, 10326 insertions(+), 5 deletions(-) create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Composable.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index f2774bdd2d..9849751c5c 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -10,9 +10,4 @@ - - - - - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md new file mode 100644 index 0000000000..3d23457e29 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md @@ -0,0 +1,16 @@ +``` ini + +BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update) +Intel Core i5-8265U CPU 1.60GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores +.NET SDK=7.0.100 + [Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2 + DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2 + + +``` +| Method | Mean | Error | StdDev | Median | Allocated | +|------------ |---------------:|--------------:|--------------:|---------------:|----------:| +| MemorySlice | 0.6161 ns | 0.0977 ns | 0.2803 ns | 0.5250 ns | - | +| Count | 11.0984 ns | 0.4045 ns | 1.1606 ns | 10.9187 ns | - | +| Parse | 36,396.4577 ns | 1,022.9391 ns | 2,851.5453 ns | 35,373.0682 ns | - | +| ParseToList | 46,043.3036 ns | 732.9096 ns | 649.7052 ns | 45,818.8660 ns | - | diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv new file mode 100644 index 0000000000..7e0700c1f9 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv @@ -0,0 +1,5 @@ +Method;Job;AnalyzeLaunchVariance;EvaluateOverhead;MaxAbsoluteError;MaxRelativeError;MinInvokeCount;MinIterationTime;OutlierMode;Affinity;EnvironmentVariables;Jit;LargeAddressAware;Platform;PowerPlanMode;Runtime;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;HeapAffinitizeMask;HeapCount;NoAffinitize;RetainVm;Server;Arguments;BuildConfiguration;Clock;EngineFactory;NuGetReferences;Toolchain;IsMutator;InvocationCount;IterationCount;IterationTime;LaunchCount;MaxIterationCount;MaxWarmupIterationCount;MemoryRandomization;MinIterationCount;MinWarmupIterationCount;RunStrategy;UnrollFactor;WarmupCount;Mean;Error;StdDev;Median;Allocated +MemorySlice;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;0.6161 ns;0.0977 ns;0.2803 ns;0.5250 ns;0 B +Count;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;11.0984 ns;0.4045 ns;1.1606 ns;10.9187 ns;0 B +Parse;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;"36,396.4577 ns";"1,022.9391 ns";"2,851.5453 ns";"35,373.0682 ns";0 B +ParseToList;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;"46,043.3036 ns";732.9096 ns;649.7052 ns;"45,818.8660 ns";0 B diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html new file mode 100644 index 0000000000..59f2680c50 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html @@ -0,0 +1,33 @@ + + + + +Stride.Shaders.Spirv.Core.Benchmarks.ParserBench-20230502-153328 + + + + +

+BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
+Intel Core i5-8265U CPU 1.60GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores
+.NET SDK=7.0.100
+  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
+
+
+ + + + + + + + +
Method Mean Error StdDev MedianAllocated
MemorySlice0.6161 ns0.0977 ns0.2803 ns0.5250 ns-
Count11.0984 ns0.4045 ns1.1606 ns10.9187 ns-
Parse36,396.4577 ns1,022.9391 ns2,851.5453 ns35,373.0682 ns-
ParseToList46,043.3036 ns732.9096 ns649.7052 ns45,818.8660 ns-
+ + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs new file mode 100644 index 0000000000..cabd401f2c --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs @@ -0,0 +1,55 @@ +using BenchmarkDotNet.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.PortableExecutable; +using System.Text; +using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; +using CommunityToolkit.HighPerformance.Buffers; +using System.Runtime.InteropServices; + +namespace Stride.Shaders.Spirv.Core.Benchmarks; + +[MemoryDiagnoser] +public class ParserBench +{ + public MemoryOwner shader; + public List instructions; + + public ParserBench() + { + + + } + + + // [Benchmark] + // public void MemorySlice() + // { + // var slice = shader.Memory[5..]; + // } + // [Benchmark] + // public void Count() + // { + // var reader = new SpirvReader(shader); + // var count = reader.Count; + // } + + // [Benchmark] + // public void Parse() + // { + // var reader = new SpirvReader(shader); + // foreach (var i in reader) + // { + + // } + // } + // [Benchmark] + // public void ParseToList() + // { + // SpirvReader.ParseToList(shader, instructions); + // instructions.Clear(); + // } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs new file mode 100644 index 0000000000..e4d72d2900 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs @@ -0,0 +1,10 @@ +// See https://aka.ms/new-console-template for more information +using BenchmarkDotNet; +using BenchmarkDotNet.Running; +using Stride.Shaders.Spirv.Core.Benchmarks; + +BenchmarkRunner.Run(); + +Console.WriteLine("Hello, World!"); + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj new file mode 100644 index 0000000000..584b915ef5 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs new file mode 100644 index 0000000000..db91312f37 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core; + +/// +/// Represents the index bound for instructions in a spirv module +/// +public struct Bound +{ + public int Offset { get; set; } + public int Count { get; set; } + + public Bound() + { + Offset = 0; + Count = 0; + } + + public int Next() + { + Count += 1; + return Offset + Count; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs new file mode 100644 index 0000000000..0c5509acc3 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs @@ -0,0 +1,32 @@ +using System.Numerics; +using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A disposable buffer wrapper using the HighPerformance toolkit. +/// +/// +public abstract class BufferBase + where T : struct +{ + internal MemoryOwner _owner = MemoryOwner.Empty; + /// + /// Span accessor of the data represented by the buffer + /// + public virtual Span Span => _owner.Span[..Length]; + /// + /// Memory accessor of the data represented by the buffer + /// + public virtual Memory Memory => _owner.Memory[..Length]; + /// + /// Corresponding bytes + /// + public Span Bytes => MemoryMarshal.AsBytes(Span); + /// + /// Length of the buffer + /// + public int Length { get; protected set; } + public void Dispose() => _owner.Dispose(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs new file mode 100644 index 0000000000..073f40f249 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs @@ -0,0 +1,89 @@ +using System.Numerics; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A buffer that works similarly to List +/// +/// +public class ExpandableBuffer : BufferBase + where T : struct +{ + + public ExpandableBuffer() + { + _owner = MemoryOwner.Allocate(4, AllocationMode.Clear); + Length = 0; + } + + public ExpandableBuffer(int initialCapacity) + { + _owner = MemoryOwner.Allocate(initialCapacity, AllocationMode.Clear); + Length = 0; + } + /// + /// Expands the buffer by the size demanded. It allocates a new underlying array when needed. + /// + /// + private void Expand(int size) + { + if(Length + size > _owner.Length) + { + var n = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)(Length + size)), AllocationMode.Clear); + _owner.Span.CopyTo(n.Span); + var toDispose = _owner; + _owner = n; + toDispose.Dispose(); + } + } + /// + /// Adds an element to the buffer + /// + /// + public void Add(T item) + { + Expand(1); + _owner.Span[Length] = item; + Length += 1; + } + /// + /// Adds many elements to the buffer + /// + /// + public void Add(Span items) + { + Expand(items.Length); + items.CopyTo(_owner.Span[Length..]); + Length += items.Length; + } + /// + /// Inserts many elements at a specific place in the buffer + /// + /// + /// + public void Insert(int start, Span words) + { + Expand(words.Length); + var slice = _owner.Span[start..Length]; + slice.CopyTo(_owner.Span[(start + words.Length)..]); + words.CopyTo(_owner.Span.Slice(start, words.Length)); + Length += words.Length; + } + + /// + /// Remove an element from the buffer + /// + /// + /// + public bool RemoveAt(int index) + { + if(index < Length && index > 0) + { + Span[(index+1)..].CopyTo(Span[index..]); + Length -= 1; + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs new file mode 100644 index 0000000000..5ce2762bae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs @@ -0,0 +1,41 @@ +namespace Stride.Shaders.Spirv.Core; + + +public interface IMutSpirvBuffer +{ + public int GetNextId(); + public Instruction Add(MutRefInstruction instruction); +} + +public static class IMutSpirvBufferExtensions +{ + internal static int GetWordLength(this TBuffer _, Span values) + where TBuffer : IMutSpirvBuffer + where TValue : ISpirvElement + { + int length = 0; + foreach (var value in values) + length += value.WordCount; + return length; + } + internal static int GetWordLength(this TBuffer _, TValue? value) + where TBuffer : IMutSpirvBuffer + { + if (value is null) return 0; + + return value switch + { + LiteralInteger i => i.WordCount, + LiteralFloat i => i.WordCount, + int _ => 1, + IdRef _ => 1, + IdResultType _ => 1, + IdResult _ => 1, + string v => new LiteralString(v).WordCount, + LiteralString v => v.WordCount, + int[] a => a.Length, + Enum _ => 1, + _ => throw new NotImplementedException() + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs new file mode 100644 index 0000000000..1c5a0aa745 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs @@ -0,0 +1,19 @@ +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A spirv buffer object +/// +public interface ISpirvBuffer +{ + Span Span { get; } + Memory Memory { get; } + Span InstructionSpan { get; } + Memory InstructionMemory { get; } + + bool HasHeader { get; } + + public Instruction this[int index] {get;} + + public SpirvSpan AsSpan(); + public SpirvMemory AsMemory(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs new file mode 100644 index 0000000000..5fdcc5abae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs @@ -0,0 +1,116 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Collections; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A collection of function buffers, usable through the MultiBuffer class +/// +public class FunctionBufferCollection +{ + bool functionStarted; + public SortedList Buffers { get; } + public WordBuffer? Current => functionStarted ? Buffers.Values[^1] : null; + + public FunctionsInstructions Instructions => new(this); + + public int BuffersLength => Buffers.Sum(static (x) => x.Value.Length); + public int FunctionCount => Buffers.Count; + + public WordBuffer this[string name] => Buffers[name]; + + public FunctionBufferCollection() + { + functionStarted = false; + Buffers = new(); + } + + public IEnumerator> GetEnumerator() => Buffers.GetEnumerator(); + + + public Instruction Insert(MutRefInstruction instruction, string? functionName = null) + { + if(!functionStarted) + { + if (instruction.OpCode != SDSLOp.OpFunction || functionName == null) + throw new Exception("A function should be started with SDSLOp.OpFunction"); + Buffers.Add(functionName, new()); + functionStarted = true; + } + Instruction? result = Current?.Add(instruction); + if(instruction.OpCode == SDSLOp.OpFunctionEnd) + { + functionStarted = false; + } + return result ?? throw new Exception("The instruction was not inserted"); + } + + public void Add(string name, WordBuffer function) + { + Buffers.Add(name, function); + } + + public struct FunctionsInstructions + { + FunctionBufferCollection buffers; + public FunctionsInstructions(FunctionBufferCollection buffers) + { + this.buffers = buffers; + } + + + public Enumerator GetEnumerator() => new(buffers); + + public ref struct Enumerator + { + FunctionBufferCollection buffers; + IEnumerator> lastBuffer; + InstructionEnumerator lastEnumerator; + bool started; + public Enumerator(FunctionBufferCollection buffers) + { + this.buffers = buffers; + lastBuffer = buffers.GetEnumerator(); + started = false; + } + + public Instruction Current => lastEnumerator.Current; + + public bool MoveNext() + { + if (!started) + { + started = true; + if (!lastBuffer.MoveNext()) + return false; + lastEnumerator = new(lastBuffer.Current.Value); + while (!lastEnumerator.MoveNext()) + { + if (!lastBuffer.MoveNext()) + return false; + lastEnumerator = new(lastBuffer.Current.Value); + } + return true; + } + else + { + if (lastEnumerator.MoveNext()) + return true; + else + { + while (lastBuffer.MoveNext()) + { + lastEnumerator = new(lastBuffer.Current.Value); + if (lastEnumerator.MoveNext()) + return true; + } + } + return false; + } + } + } + } + + + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs new file mode 100644 index 0000000000..706a53d686 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs @@ -0,0 +1,58 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Transactions; + +namespace Stride.Shaders.Spirv.Core.Buffers; + + + +public sealed partial class MultiBuffer +{ + public MultiBufferLocalVariables LocalVariables => new(this); + + /// + /// Representation of local variables of the current function being written. + /// + public ref struct MultiBufferLocalVariables + { + MultiBuffer buffer; + public MultiBufferLocalVariables(MultiBuffer buffer) + { + this.buffer = buffer; + } + + public Instruction this[string name] + { + get + { + if(TryGet(name, out var instruction)) + return instruction; + throw new Exception($"Variable {name} not found"); + } + } + /// + /// Finds the last varibale with a specific name. + /// + /// + /// + /// + /// + public readonly bool TryGet(string name, out Instruction instruction) + { + var found = false; + instruction = Instruction.Empty; + if (buffer.Functions.Current == null) + throw new Exception("Not in function scope"); + var filtered = new LambdaFilteredEnumerator(buffer.Functions.Current, static (i) => i.OpCode == SDSLOp.OpSDSLVariable || i.OpCode == SDSLOp.OpSDSLFunctionParameter); + while (filtered.MoveNext()) + { + var vname = filtered.Current.GetOperand("name"); + if (vname?.Value == name) + { + instruction = filtered.Current; + found = true; + } + } + return found; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs new file mode 100644 index 0000000000..31f59ad7f4 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Transactions; + +namespace Stride.Shaders.Spirv.Core.Buffers; + + + +public sealed partial class MultiBuffer +{ + public MultiBufferGlobalVariables GlobalVariables => new(this); + + public ref struct MultiBufferGlobalVariables + { + MultiBuffer buffer; + public MultiBufferGlobalVariables(MultiBuffer buffer) + { + this.buffer = buffer; + } + + public Instruction this[string name] + { + get + { + if(TryGet(name, out var instruction)) + return instruction; + throw new Exception($"Variable {name} does not exist"); + } + } + + public readonly bool TryGet(string name, out Instruction instruction) + { + var filtered = new LambdaFilteredEnumerator(buffer.Declarations, static (i) => i.OpCode == SDSLOp.OpSDSLVariable || i.OpCode == SDSLOp.OpSDSLIOVariable); + while (filtered.MoveNext()) + { + if (filtered.Current.GetOperand("name")?.Value == name) + { + instruction = filtered.Current; + return true; + } + } + instruction = Instruction.Empty; + return false; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs new file mode 100644 index 0000000000..724ed3489f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs @@ -0,0 +1,214 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Text; +using System.Transactions; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Buffers; + + +/// +/// A spirv buffer composed of many different buffers for declarations and functions +/// +public sealed partial class MultiBuffer : IMutSpirvBuffer +{ + public int Bound { get; private set; } + public int Length => Declarations.Length + Functions.BuffersLength; + + public WordBuffer Declarations { get; init; } + public FunctionBufferCollection Functions { get; init; } + + public MultiBufferInstructions Instructions => new(this); + + public MultiBuffer() + { + Declarations = new(); + Functions = new(); + } + + public Instruction Add(MutRefInstruction instruction) + { + if (instruction.OpCode == SDSLOp.OpSDSLFunction) + { + var name = instruction.GetOperand("functionName"); + var id = instruction.GetOperand("resultId").Value; + Declarations.AddOpName(id, name); + Span words = stackalloc int[5]; + instruction.Words[..5].CopyTo(words); + var funcInstruction = new MutRefInstruction(words); + funcInstruction.OpCode = SDSLOp.OpFunction; + return Functions.Insert(funcInstruction, name.Value); + } + else if(instruction.OpCode == SDSLOp.OpFunction) + { + var n = ""; + foreach(var i in Declarations) + { + if (i.OpCode == SDSLOp.OpName && i.Words.Span[1] == instruction.Words[2]) + n = i.GetOperand("name")?.Value ?? ""; + } + return Functions.Insert(instruction, n); + } + else + { + return InstructionInfo.GetGroupOrder(instruction) switch + { + 13 => Functions.Insert(instruction), + _ => Declarations.Add(instruction) + }; + } + } + public Instruction Duplicate(RefInstruction instruction, int offset = 0) + { + var m = new MutRefInstruction(stackalloc int[instruction.WordCount]); + m.OpCode = instruction.OpCode; + m.WordCount = instruction.WordCount; + instruction.Operands.CopyTo(m.Words[1..]); + if (offset > 0) + { + foreach (var op in m) + { + if ( + op.Kind == OperandKind.IdResult + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.PairIdRefIdRef + || op.Kind == OperandKind.PairIdRefLiteralInteger + ) + op.Words[0] += offset; + if (op.Kind == OperandKind.PairIdRefIdRef || op.Kind == OperandKind.PairLiteralIntegerIdRef) + { + op.Words[1] += offset; + } + } + } + return Add(m); + } + + public int GetNextId() + { + Bound += 1; + return Bound; + } + + internal static int GetWordLength(T? value) + { + if (value is null) return 0; + + return value switch + { + LiteralInteger i => i.WordCount, + LiteralFloat i => i.WordCount, + int _ => 1, + IdRef _ => 1, + IdResultType _ => 1, + IdResult _ => 1, + string v => new LiteralString(v).WordCount, + LiteralString v => v.WordCount, + int[] a => a.Length, + Enum _ => 1, + _ => throw new NotImplementedException() + }; + } + + + public void Dispose() + { + Declarations.Dispose(); + foreach (var function in Functions) + function.Value.Dispose(); + } + + public struct MultiBufferInstructions + { + MultiBuffer buffers; + public MultiBufferInstructions(MultiBuffer buffers) + { + this.buffers = buffers; + } + + public Enumerator GetEnumerator() => new(buffers); + + public ref struct Enumerator + { + MultiBuffer buffers; + OrderedEnumerator declarationEnumerator; + FunctionBufferCollection.FunctionsInstructions.Enumerator functionsEnumerator; + bool started; + bool declarationsFinished; + public Enumerator(MultiBuffer buffers) + { + this.buffers = buffers; + declarationEnumerator = buffers.Declarations.GetEnumerator(); + functionsEnumerator = buffers.Functions.Instructions.GetEnumerator(); + started = false; + declarationsFinished = false; + } + + public Instruction Current => !declarationsFinished ? declarationEnumerator.Current : functionsEnumerator.Current; + + public bool MoveNext() + { + if(!started) + { + started = true; + if (declarationEnumerator.MoveNext()) + return true; + else + declarationsFinished = true; + if (functionsEnumerator.MoveNext()) + return true; + return false; + } + else + { + if(!declarationsFinished) + { + if (declarationEnumerator.MoveNext()) + return true; + else + declarationsFinished = true; + } + return functionsEnumerator.MoveNext(); + } + } + } + } + + public void RecomputeBound() + { + var b = 0; + foreach(var i in Declarations.UnorderedInstructions) + { + var id = i.ResultId; + if (id != null && id > b) + b = id ?? -1; + } + foreach(var (_,f) in Functions) + foreach (var i in f.UnorderedInstructions) + { + var id = i.ResultId; + if (id != null && id > b) + b = id ?? -1; + } + Bound = b + 1; + } + public override string ToString() + { + return + new StringBuilder() + .Append(Disassembler.Disassemble(Declarations)) + .Append(string.Join("\n", Functions.Buffers.Select(x => Disassembler.Disassemble(x.Value)))) + .ToString(); + } + +} + +// public static class MBExtensions +// { +// public static Instruction AddOpDecorate(this MultiBuffer mb, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) +// { +// var wordLength = 1 + MultiBuffer.GetWordLength(target) + MultiBuffer.GetWordLength(decoration) + MultiBuffer.GetWordLength(additional1) + MultiBuffer.GetWordLength(additional2) + MultiBuffer.GetWordLength(additionalString); +// var mri = new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpDecorate, target, (int)decoration, ..additional1.ToSpirvSpanOwner().Span, ..additional2.ToSpirvSpanOwner().Span, ..additionalString.ToSpirvSpanOwner().Span]); +// return mb.Add(mri); +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs new file mode 100644 index 0000000000..e97a1b1c36 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs @@ -0,0 +1,56 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A spirv buffer where instructions are not sorted +/// +public sealed class UnsortedWordBuffer : BufferBase, ISpirvBuffer +{ + public static readonly SortedWordBuffer Empty = new (); + + + public Span InstructionSpan => InstructionMemory.Span; + public Memory InstructionMemory => HasHeader ? Memory[5..] : Memory; + public bool HasHeader => Span[0] == Spv.Specification.MagicNumber; + + public int InstructionCount => new SpirvReader(Memory).Count; + public bool IsEmpty => Span.IsEmpty; + + + public Instruction this[int index] + { + get + { + var enumerator = GetEnumerator(); + int tmp = 0; + while(enumerator.MoveNext() && tmp < index) + tmp += 1; + return enumerator.Current; + } + } + + public InstructionEnumerator GetEnumerator() => new(this); + + public SpirvSpan AsSpan() => new(Span); + public SpirvMemory AsMemory() => new(this); + + + public UnsortedWordBuffer() + { + _owner = MemoryOwner.Empty; + } + + public UnsortedWordBuffer(WordBuffer buffer) + { + _owner = MemoryOwner.Allocate(buffer.Length); + buffer.Span.CopyTo(_owner.Span); + Length = buffer.Length; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs new file mode 100644 index 0000000000..e1f5e7c8eb --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs @@ -0,0 +1,25 @@ +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Runtime.InteropServices; +using System.Text; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +public partial class WordBuffer +{ + public static WordBuffer Parse(byte[] bytes) + { + WordBuffer buffer = new(bytes.Length / 4); + var ints = MemoryMarshal.Cast(bytes)[5..]; + ints.CopyTo(buffer.Span); + return buffer; + } + + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs new file mode 100644 index 0000000000..9e36f4a6e6 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs @@ -0,0 +1,211 @@ +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Runtime.InteropServices; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A buffer to assembler spirv byte code. +/// +public sealed partial class WordBuffer : ExpandableBuffer, ISpirvBuffer, IDisposable, IMutSpirvBuffer +{ + public Bound Bound { get; private set; } + public int InstructionCount => new SpirvReader(Memory).Count; + + public Span InstructionSpan => Span; + + public Memory InstructionMemory => Memory; + + public bool HasHeader => false; + + public Memory this[Range range] => Memory[range]; + + public WordBufferInstructions OrderedInstructions => new(this, true); + public WordBufferInstructions UnorderedInstructions => new(this, false); + + + public Instruction this[int index] + { + get + { + int id = 0; + int wid = 0; + while (id < index) + { + wid += Span[wid] >> 16; + id++; + } + return new Instruction(this, Memory[wid..(wid + Span[wid] >> 16)], index, wid); + } + } + public WordBuffer() + { + Bound = new(); + _owner = MemoryOwner.Allocate(32, AllocationMode.Clear); + } + + public WordBuffer(int initialCapacity = 32, int offset = 0) + { + Bound = new() { Offset = offset }; + _owner = MemoryOwner.Allocate(initialCapacity, AllocationMode.Clear); + } + + internal WordBuffer(Span words) + { + _owner = MemoryOwner.Allocate(words.Length, AllocationMode.Clear); + Length = words.Length; + words.CopyTo(Span); + Bound = new(); + } + + public OrderedEnumerator GetEnumerator() => new(this); + + + public int GetNextId() + { + Bound = Bound with { Count = Bound.Count + 1 }; + return Bound.Count + Bound.Offset; + } + public void SetBoundOffset(int offset) + { + Bound = Bound with { Offset = offset }; + } + + + + + public void Insert(Instruction instruction) + { + Insert(Length, instruction.Words.Span); + } + public void Insert(Span instructions, int? start = null) + { + Insert(start ?? Length, instructions); + } + + public Instruction Add(MutRefInstruction instruction) + { + Insert(instruction.Words); + return new(this, InstructionMemory.Slice(Length - instruction.WordCount, instruction.WordCount), InstructionCount - 1, Length - instruction.WordCount); + } + public Instruction Add(MutRefInstruction instruction, int start) + { + Insert(instruction.Words, start); + return new(this, InstructionMemory.Slice(Length - instruction.WordCount, instruction.WordCount), InstructionCount - 1, Length - instruction.WordCount); + } + + public Instruction Duplicate(RefInstruction instruction) + { + var m = new MutRefInstruction(stackalloc int[instruction.WordCount]); + m.OpCode = instruction.OpCode; + m.WordCount = instruction.WordCount; + instruction.Operands.CopyTo(m.Words[1..]); + Add(m); + return new(this, InstructionCount - 1); + } + + + public byte[] GenerateSpirv() + { + var output = new byte[Length * 4 + 5 * 4]; + var span = output.AsSpan(); + var ints = MemoryMarshal.Cast(span); + var instructionWords = ints[5..]; + + var header = new SpirvHeader(new SpirvVersion(1, 3), 0, Bound.Count + 1); + header.WriteTo(ints[0..5]); + var id = 0; + var enumerator = GetEnumerator(); + while (enumerator.MoveNext()) + { + var curr = enumerator.Current; + curr.Words.Span.CopyTo(instructionWords.Slice(id, curr.Words.Length)); + id += curr.Words.Length; + } + return output; + } + + + internal static int GetWordLength(T? value) + { + if (value is null) return 0; + + return value switch + { + LiteralInteger i => i.WordCount, + LiteralFloat i => i.WordCount, + int _ => 1, + IdRef _ => 1, + IdResultType _ => 1, + IdResult _ => 1, + string v => new LiteralString(v).WordCount, + LiteralString v => v.WordCount, + int[] a => a.Length, + Enum _ => 1, + _ => throw new NotImplementedException() + }; + } + + public void RecomputeLength() + { + var wid = 0; + while(wid < _owner.Length) + { + if (_owner.Span[wid] >> 16 == 0) + { + Length = wid; + return; + } + else + wid += _owner.Span[wid] >> 16; + } + } + + public SpirvSpan AsSpan() => new(Span); + public SpirvMemory AsMemory() => new(this); + + + + + public override string ToString() + { + return Disassembler.Disassemble(this); + } + + + public ref struct WordBufferInstructions + { + bool ordered; + WordBuffer buffer; + public WordBufferInstructions(WordBuffer buffer, bool ordered) + { + this.buffer = buffer; + this.ordered = ordered; + } + + public Enumerator GetEnumerator() => new(buffer, ordered); + + public ref struct Enumerator + { + bool ordered; + WordBuffer buffer; + + OrderedEnumerator orderedEnumerator; + InstructionEnumerator unorderedEnumerator; + + public Enumerator(WordBuffer buffer, bool ordered) + { + this.buffer = buffer; + this.ordered = ordered; + if (ordered) + orderedEnumerator = new(buffer); + else + unorderedEnumerator = new(buffer); + } + + public Instruction Current => ordered ? orderedEnumerator.Current : unorderedEnumerator.Current; + public bool MoveNext() => ordered ? orderedEnumerator.MoveNext() : unorderedEnumerator.MoveNext(); + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs new file mode 100644 index 0000000000..2caa23825e --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs @@ -0,0 +1,92 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Collections; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A collection of function buffers, usable through the MultiBuffer class +/// +public class SortedFunctionBufferCollection +{ + bool functionStarted; + public SortedList Buffers { get; } + public SortedWordBuffer? Current => functionStarted ? Buffers.Values[^1] : null; + + public FunctionsInstructions Instructions => new(this); + + public int BuffersLength => Buffers.Sum(static (x) => x.Value.Length); + + + public SortedFunctionBufferCollection(FunctionBufferCollection functions) + { + Buffers = new(functions.FunctionCount); + foreach(var func in functions.Buffers) + { + Buffers.Add(func.Key, new(func.Value)); + } + } + + public IEnumerator> GetEnumerator() => Buffers.GetEnumerator(); + + public struct FunctionsInstructions + { + SortedFunctionBufferCollection buffers; + public FunctionsInstructions(SortedFunctionBufferCollection buffers) + { + this.buffers = buffers; + } + + + public Enumerator GetEnumerator() => new(buffers); + + public ref struct Enumerator + { + IEnumerator> lastBuffer; + InstructionEnumerator lastEnumerator; + bool started; + public Enumerator(SortedFunctionBufferCollection buffers) + { + lastBuffer = buffers.GetEnumerator(); + started = false; + } + + public Instruction Current => lastEnumerator.Current; + + public bool MoveNext() + { + if (!started) + { + started = true; + if (!lastBuffer.MoveNext()) + return false; + lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); + while (!lastEnumerator.MoveNext()) + { + if (!lastBuffer.MoveNext()) + return false; + lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); + } + return true; + } + else + { + if (lastEnumerator.MoveNext()) + return true; + else + { + while (lastBuffer.MoveNext()) + { + lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); + if (lastEnumerator.MoveNext()) + return true; + } + } + return false; + } + } + } + } + + + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs new file mode 100644 index 0000000000..ecc4ccbf20 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs @@ -0,0 +1,74 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A buffer where all instructions have been sorted, no instructions can be added to it +/// +public sealed class SortedWordBuffer : BufferBase, ISpirvBuffer +{ + public static SortedWordBuffer Empty { get; } = new(); + public int InstructionCount => new SpirvReader(Memory).Count; + public bool IsEmpty => Span.IsEmpty; + + public Span InstructionSpan => InstructionMemory.Span; + + public Memory InstructionMemory => HasHeader ? Memory[5..] : Memory; + + public bool HasHeader => Span[0] == Spv.Specification.MagicNumber; + + public Instruction this[int index] + { + get + { + var enumerator = GetEnumerator(); + int tmp = 0; + while (enumerator.MoveNext() && tmp < index) + tmp += 1; + return enumerator.Current; + } + } + + public InstructionEnumerator GetEnumerator() => new(this); + + public SortedWordBuffer() + { + _owner = MemoryOwner.Empty; + } + + public SortedWordBuffer(WordBuffer buffer) + { + _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); + Length = 0; + foreach (var item in buffer) + { + item.Words.Span.CopyTo(_owner.Span[Length..(Length + item.WordCount)]); + Length += item.WordCount; + } + } + public SortedWordBuffer(MultiBuffer buffer) + { + _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); + Length = 0; + foreach (var item in buffer.Instructions) + { + item.Words.Span.CopyTo(_owner.Span[Length..(Length + item.WordCount)]); + Length += item.WordCount; + } + } + public SortedWordBuffer(SpirvBuffer buffer) + { + _owner = buffer._owner; + Length = buffer.Length; + buffer._owner = MemoryOwner.Empty; + } + public SpirvSpan AsSpan() => new(Span); + public SpirvMemory AsMemory() => new(this); + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs new file mode 100644 index 0000000000..e4e6a8ab70 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -0,0 +1,111 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A common spirv buffer containing a header. +/// +public class SpirvBuffer : ExpandableBuffer, ISpirvBuffer, IDisposable +{ + public Span InstructionSpan => _owner.Span[5..Length]; + public Memory InstructionMemory => _owner.Memory[5..Length]; + public RefHeader Header => new(_owner.Span[..5]); + public bool HasHeader => true; + + public Instruction this[int index] + { + get + { + int id = 0; + int wid = 5; + while (id < index) + { + wid += Span[wid] >> 16; + id++; + } + return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16),index,wid); + } + } + + public SpirvBuffer(int initialSize = 32) + { + _owner = MemoryOwner.Allocate(initialSize,AllocationMode.Clear); + var header = Header; + header.MagicNumber = Spv.Specification.MagicNumber; + header.VersionNumber = new(1,3); + header.GeneratorMagicNumber = 42; + Length = 5; + } + public SpirvBuffer(MultiBuffer buffer) + { + _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); + var header = Header; + header.MagicNumber = Spv.Specification.MagicNumber; + header.VersionNumber = new(1, 3); + header.GeneratorMagicNumber = 42; + header.Bound = buffer.Bound; + Length = 5; + foreach (var i in buffer.Declarations) + if (i.OpCode != SDSLOp.OpNop) + Add(i.Words.Span); + foreach(var (_,f) in buffer.Functions) + foreach (var i in f) + if (i.OpCode != SDSLOp.OpNop) + Add(i.Words.Span); + buffer.Dispose(); + } + + public InstructionEnumerator GetEnumerator() => new(this); + + public void Add(SortedWordBuffer buffer) => Add(buffer.Span); + + public void Replace(SpirvBuffer buffer, out bool dispose) + { + if(buffer.Length <= Length) + { + _owner.Span.Clear(); + buffer.Span.CopyTo(Span); + Length = buffer.Length; + dispose = true; + } + else + { + var disp = _owner; + _owner = buffer._owner; + Length = buffer.Length; + disp.Dispose(); + dispose = false; + } + } + + public void RecomputeBound() + { + int last = 0; + foreach(var i in this) + { + last = i.ResultId ?? last; + } + var header = Header; + header.Bound = last + 1; + } + + public SortedWordBuffer ToSorted() + { + return new(this); + } + public SpirvSpan AsSpan() => new(Span); + public SpirvMemory AsMemory() => new(this); + + + public override string ToString() + { + return Disassembler.Disassemble(this); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs new file mode 100644 index 0000000000..d3ae5b61e1 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs @@ -0,0 +1,32 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A buffer slice +/// +public ref struct SpirvMemory +{ + ISpirvBuffer buffer; + Span words => buffer.Span; + + public int Length => words.Length - (HasHeader ? 5 : 0); + public bool HasHeader => words[0] == Spv.Specification.MagicNumber; + + public Span Span => HasHeader ? words[5..] : words; + + + public int this[int index] { get => words[index]; set => words[index] = value; } + + public SpirvMemory(ISpirvBuffer buffer) + { + this.buffer = buffer; + } + + public InstructionEnumerator GetEnumerator() => new(buffer); +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs new file mode 100644 index 0000000000..ecc8f3706f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A buffer slice +/// +public ref struct SpirvSpan +{ + Span words; + + public int Length => words.Length - (HasHeader ? 5 : 0); + public bool HasHeader => words[0] == Spv.Specification.MagicNumber; + + public Span Span => HasHeader ? words[5..] : words; + + + public int this[int index] { get => words[index]; set => words[index] = value; } + + public SpirvSpan(Span words) + { + this.words = words; + } + + public Enumerator GetEnumerator() => new(words); + + public ref struct Enumerator + { + int wordIndex; + Span words; + + public RefInstruction Current => RefInstruction.ParseRef(words.Slice(wordIndex, words[wordIndex] >> 16)); + + public Enumerator(Span words) + { + wordIndex = -1; + this.words = words; + } + + public bool MoveNext() + { + if(wordIndex == -1) + { + wordIndex = 0; + return true; + } + else + { + if (wordIndex + (words[wordIndex] >> 16) >= words.Length) + return false; + wordIndex += words[wordIndex] >> 16; + return true; + } + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs new file mode 100644 index 0000000000..d77081009e --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs @@ -0,0 +1,97 @@ +using System.Text; + +namespace Stride.Shaders.Spirv.Core; + +public class DisWriter +{ + StringBuilder builder; + int idOffset; + + public DisWriter(int bound) //34 + { + builder = new(); + idOffset = 3; + while (bound > 0) + { + bound /= 10; + idOffset += 1; + } + } + public void Append(IdResult? result) + { + if (result != null) + { + var tmp = result.Value; + var size = 1; + while (tmp > 0) + { + tmp /= 10; + size += 1; + } + builder.Append('%').Append(result.Value).Append(' ', idOffset - 1 - size).Append('='); + } + else + builder.Append(' ', idOffset); + } + + public void Append(T value) where T : Enum + { + var name = Enum.GetName(typeof(T), value); + builder.Append(' ').Append(name); + } + public void Append(IdRef id) + { + builder.Append(' ').Append('%').Append(id.Value); + } + public void Append(IdResultType id) + { + builder.Append(' ').Append('%').Append(id.Value); + } + public void AppendInt(int v) + { + builder.Append(' ').Append(v); + } + public void AppendLiteral(LiteralInteger v) + { + builder.Append(' ').Append(v.Words); + } + + public void AppendLiteral(LiteralFloat v) + { + if(v.WordCount == 1) + builder.Append(' ').Append(Convert.ToSingle(v.Words & 0xFFFF)); + if(v.WordCount == 2) + builder.Append(' ').Append(Convert.ToDouble(v.Words)); + } + public void AppendLiteral(LiteralString v, bool quoted = false) + { + if(!quoted) + builder.Append(' ').Append(v.Value); + else + builder.Append(' ').Append('"').Append(v.Value).Append('"'); + } + public void Append(PairLiteralIntegerIdRef v) + { + (int,int) value = v; + AppendInt(value.Item1); + AppendInt(value.Item2); + } + public void Append(PairIdRefLiteralInteger v) + { + (int,int) value = v; + AppendInt(value.Item1); + AppendInt(value.Item2); + } + public void Append(PairIdRefIdRef v) + { + (int,int) value = v; + AppendInt(value.Item1); + AppendInt(value.Item2); + } + public void AppendLine() => builder.AppendLine(); + + public override string ToString() + { + return builder.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs new file mode 100644 index 0000000000..6f778d6f89 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs @@ -0,0 +1,237 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Runtime.InteropServices; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core; + + +public static class Disassembler +{ + + public static string Disassemble(Span memory) + { + var words = MagicNumber == memory[0] ? + memory[5..] : memory; + + var wbuff = new WordBuffer(words); + return Disassemble(wbuff); + } + + public static string Disassemble(Memory memory) + { + var words = MagicNumber == memory.Span[0] ? + memory.Span[5..] : memory.Span; + + var wbuff = new WordBuffer(words); + return Disassemble(wbuff); + } + public static string Disassemble(UnsortedWordBuffer wbuff) + { + var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); + + foreach (var e in wbuff) + { + dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); + dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); + foreach (var o in e) + { + Append(o, dis); + } + dis.AppendLine(); + } + return dis.ToString(); + } + + public static string Disassemble(SortedWordBuffer wbuff) + { + var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); + + foreach (var e in wbuff) + { + dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); + dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); + foreach (var o in e) + { + Append(o, dis); + } + dis.AppendLine(); + } + return dis.ToString(); + } + public static string Disassemble(SpirvBuffer wbuff) + { + var dis = new DisWriter(new SpirvReader(wbuff.InstructionMemory).ComputeBound()); + + foreach (var e in wbuff) + { + dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); + dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); + foreach (var o in e) + { + Append(o, dis); + } + dis.AppendLine(); + } + return dis.ToString(); + } + + public static string Disassemble(WordBuffer wbuff) + { + var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); + + foreach (var e in wbuff) + { + dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); + dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); + foreach (var o in e) + { + Append(o, dis); + } + dis.AppendLine(); + } + return dis.ToString(); + } + + public static void Append(in SpvOperand o, DisWriter dis) + { + + if (o.Kind == OperandKind.IdRef) + foreach (var e in o.Words) + dis.Append(new IdRef(e)); + else if (o.Kind == OperandKind.PackedVectorFormat) + foreach (var e in o.Words) + dis.Append((PackedVectorFormat)e); + else if (o.Kind == OperandKind.ImageOperands) + foreach (var e in o.Words) + dis.Append((ImageOperandsMask)e); + else if (o.Kind == OperandKind.FPFastMathMode) + foreach (var e in o.Words) + dis.Append((FPFastMathModeMask)e); + else if (o.Kind == OperandKind.SelectionControl) + foreach (var e in o.Words) + dis.Append((SelectionControlMask)e); + else if (o.Kind == OperandKind.LoopControl) + foreach (var e in o.Words) + dis.Append((LoopControlMask)e); + else if (o.Kind == OperandKind.FunctionControl) + foreach (var e in o.Words) + dis.Append((FunctionControlMask)e); + else if (o.Kind == OperandKind.MemorySemantics) + foreach (var e in o.Words) + dis.Append((MemorySemanticsMask)e); + else if (o.Kind == OperandKind.MemoryAccess) + foreach (var e in o.Words) + dis.Append((MemoryAccessMask)e); + else if (o.Kind == OperandKind.KernelProfilingInfo) + foreach (var e in o.Words) + dis.Append((KernelProfilingInfoMask)e); + else if (o.Kind == OperandKind.RayFlags) + foreach (var e in o.Words) + dis.Append((RayFlagsMask)e); + else if (o.Kind == OperandKind.FragmentShadingRate) + foreach (var e in o.Words) + dis.Append((FragmentShadingRateMask)e); + else if (o.Kind == OperandKind.SourceLanguage) + foreach (var e in o.Words) + dis.Append((SourceLanguage)e); + else if (o.Kind == OperandKind.ExecutionModel) + foreach (var e in o.Words) + dis.Append((ExecutionModel)e); + else if (o.Kind == OperandKind.AddressingModel) + foreach (var e in o.Words) + dis.Append((AddressingModel)e); + else if (o.Kind == OperandKind.MemoryModel) + foreach (var e in o.Words) + dis.Append((MemoryModel)e); + else if (o.Kind == OperandKind.ExecutionMode) + foreach (var e in o.Words) + dis.Append((ExecutionMode)e); + else if (o.Kind == OperandKind.StorageClass) + foreach (var e in o.Words) + dis.Append((StorageClass)e); + else if (o.Kind == OperandKind.Dim) + foreach (var e in o.Words) + dis.Append((Dim)e); + else if (o.Kind == OperandKind.SamplerAddressingMode) + foreach (var e in o.Words) + dis.Append((SamplerAddressingMode)e); + else if (o.Kind == OperandKind.SamplerFilterMode) + foreach (var e in o.Words) + dis.Append((SamplerFilterMode)e); + else if (o.Kind == OperandKind.ImageFormat) + foreach (var e in o.Words) + dis.Append((ImageFormat)e); + else if (o.Kind == OperandKind.ImageChannelOrder) + foreach (var e in o.Words) + dis.Append((ImageChannelOrder)e); + else if (o.Kind == OperandKind.ImageChannelDataType) + foreach (var e in o.Words) + dis.Append((ImageChannelDataType)e); + else if (o.Kind == OperandKind.FPRoundingMode) + foreach (var e in o.Words) + dis.Append((FPRoundingMode)e); + else if (o.Kind == OperandKind.LinkageType) + foreach (var e in o.Words) + dis.Append((LinkageType)e); + else if (o.Kind == OperandKind.AccessQualifier) + foreach (var e in o.Words) + dis.Append((AccessQualifier)e); + else if (o.Kind == OperandKind.FunctionParameterAttribute) + foreach (var e in o.Words) + dis.Append((FunctionParameterAttribute)e); + else if (o.Kind == OperandKind.Decoration) + foreach (var e in o.Words) + dis.Append((Decoration)e); + else if (o.Kind == OperandKind.BuiltIn) + foreach (var e in o.Words) + dis.Append((BuiltIn)e); + else if (o.Kind == OperandKind.Scope) + foreach (var e in o.Words) + dis.Append((Scope)e); + else if (o.Kind == OperandKind.GroupOperation) + foreach (var e in o.Words) + dis.Append((GroupOperation)e); + else if (o.Kind == OperandKind.KernelEnqueueFlags) + foreach (var e in o.Words) + dis.Append((KernelEnqueueFlags)e); + else if (o.Kind == OperandKind.Capability) + foreach (var e in o.Words) + dis.Append((Capability)e); + else if (o.Kind == OperandKind.RayQueryIntersection) + foreach (var e in o.Words) + dis.Append((RayQueryIntersection)e); + else if (o.Kind == OperandKind.RayQueryCommittedIntersectionType) + foreach (var e in o.Words) + dis.Append((RayQueryCommittedIntersectionType)e); + else if (o.Kind == OperandKind.RayQueryCandidateIntersectionType) + foreach (var e in o.Words) + dis.Append((RayQueryCandidateIntersectionType)e); + else if (o.Kind == OperandKind.IdResultType) + foreach (var e in o.Words) + dis.Append((IdResultType)e); + else if (o.Kind == OperandKind.IdMemorySemantics) + foreach (var e in o.Words) + dis.AppendInt((IdMemorySemantics)e); + else if (o.Kind == OperandKind.IdScope) + foreach (var e in o.Words) + dis.AppendInt((IdScope)e); + else if (o.Kind == OperandKind.IdRef) + foreach (var e in o.Words) + dis.Append((IdRef)e); + else if (o.Kind == OperandKind.LiteralInteger) + foreach (var e in o.Words) + dis.AppendInt(e); + else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) + for (int i = 0; i < o.Words.Length; i += 2) + dis.Append(new PairLiteralIntegerIdRef((o.Words[i], o.Words[i + 1]))); + else if (o.Kind == OperandKind.PairIdRefLiteralInteger) + for (int i = 0; i < o.Words.Length; i += 2) + dis.Append(new PairIdRefLiteralInteger((o.Words[i], o.Words[i + 1]))); + else if (o.Kind == OperandKind.PairIdRefIdRef) + for (int i = 0; i < o.Words.Length; i += 2) + dis.Append(new PairIdRefIdRef((o.Words[i], o.Words[i + 1]))); + else if (o.Kind == OperandKind.LiteralContextDependentNumber) + dis.AppendLiteral(o.To()); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs new file mode 100644 index 0000000000..2abd03c1af --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs @@ -0,0 +1,185 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace Stride.Shaders.Spirv.Core; + + +public interface ISpirvElement +{ + public int WordCount { get; } + public SpanOwner AsSpanOwner(); +} + +public interface IWritableSpirvElement : ISpirvElement +{ + public void Write(scoped ref SpirvWriter writer); +} + + +public static class ISpirvElementExtensions +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this string? value) + { + if (value is null) + return SpanOwner.Empty; + else + { + var lit = new LiteralString(value); + var span = SpanOwner.Allocate(lit.WordCount, AllocationMode.Clear); + lit.WriteTo(span.Span); + return span; + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this T value) + where T : struct + { + if (value is ISpirvElement element) + return element.AsSpanOwner(); + else + return value switch + { + byte v => new LiteralInteger(v).AsSpanOwner(), + sbyte v => new LiteralInteger(v).AsSpanOwner(), + ushort v => new LiteralInteger(v).AsSpanOwner(), + short v => new LiteralInteger(v).AsSpanOwner(), + uint v => new LiteralInteger(v).AsSpanOwner(), + int v => new LiteralInteger(v).AsSpanOwner(), + long v => new LiteralInteger(v).AsSpanOwner(), + ulong v => new LiteralInteger(v).AsSpanOwner(), + Half v => new LiteralFloat(v).AsSpanOwner(), + float v => new LiteralFloat(v).AsSpanOwner(), + double v => new LiteralFloat(v).AsSpanOwner(), + Enum e => new LiteralInteger(Convert.ToInt32(e)).AsSpanOwner(), + _ => throw new NotImplementedException() + }; + + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this T? value) + where T : struct + { + if (value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this Span values) + { + + int length = 0; + foreach (var value in values) + { + length += value switch + { + byte + or sbyte + or ushort + or short + or uint + or int + or Half + or float + or Enum => 1, + long + or ulong + or double => 2, + ISpirvElement element => element.WordCount, + _ => throw new NotImplementedException() + }; + } + var span = SpanOwner.Allocate(length); + length = 0; + for (int i = 0; i < values.Length; i++) + { + if(values[i] is ISpirvElement element) + { + element.AsSpanOwner().Span.CopyTo(span.Span[length..]); + length += element.WordCount; + } + else if(values[i] is byte vb) + { + span.Span[i] = vb; + length += 1; + } + else if(values[i] is sbyte vsb) + { + span.Span[i] = vsb; + length += 1; + } + else if(values[i] is short vsh) + { + span.Span[i] = vsh; + length += 1; + } + else if(values[i] is ushort vush) + { + span.Span[i] = vush; + length += 1; + } + else if(values[i] is Half vh) + { + span.Span[i] = (int)(new LiteralFloat(vh).Words & 0xFFFFFFFF); + length += 1; + } + else if(values[i] is float vf) + { + span.Span[i] = (int)(new LiteralFloat(vf).Words & 0xFFFFFFFF); + length += 1; + } + else if(values[i] is int vi) + { + span.Span[i] = vi; + length += 1; + } + else if(values[i] is Enum e) + { + span.Span[i] = Convert.ToInt32(e); + length += 1; + } + else if(values[i] is uint vui) + { + span.Span[i] = (int)vui; + length += 1; + } + else if(values[i] is double vd) + { + new LiteralFloat(vd).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); + length += 1; + } + else if(values[i] is long vl) + { + new LiteralInteger(vl).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); + length += 1; + } + else if(values[i] is ulong vul) + { + new LiteralInteger(vul).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); + length += 1; + } + else throw new NotImplementedException(); + } + return span; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this T? value) + where T : struct + => value.AsSpanOwner().Span; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this T value) + where T : struct + => value.AsSpanOwner().Span; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this string? value) + => value.AsSpanOwner().Span; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this Span values) + => values.AsSpanOwner().Span; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs new file mode 100644 index 0000000000..b637a44ae6 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core; + + + +public partial class InstructionInfo +{ + Dictionary<(SDSLOp, StorageClass?), int> OrderGroup = new(); + + public static ImmutableArray SDSLOperators { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().Contains("SDSL")).ToArray()); + public static ImmutableArray OpTypes { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().StartsWith("OpType")).ToArray()); + + void InitOrder() + { + OrderGroup[(SDSLOp.OpNop, null)] = 0; + OrderGroup[(SDSLOp.OpSDSLMixinName, null)] = 0; + OrderGroup[(SDSLOp.OpCapability, null)] = 0; + OrderGroup[(SDSLOp.OpSDSLMixinOffset, null)] = 0; + OrderGroup[(SDSLOp.OpSDSLMixinInherit, null)] = 0; + OrderGroup[(SDSLOp.OpSDSLCompose, null)] = 0; + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpSDSLImport"))) + OrderGroup[(e, null)] = 1; + OrderGroup[(SDSLOp.OpExtension, null)] = 1; + OrderGroup[(SDSLOp.OpExtInstImport, null)] = 2; + OrderGroup[(SDSLOp.OpMemoryModel, null)] = 3; + OrderGroup[(SDSLOp.OpEntryPoint, null)] = 4; + + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpExecutionMode"))) + OrderGroup[(e, null)] = 5; + + foreach (var e in new SDSLOp[] { SDSLOp.OpString, SDSLOp.OpSource, SDSLOp.OpSourceExtension, SDSLOp.OpSourceContinued }) + OrderGroup[(e, null)] = 6; + + OrderGroup[(SDSLOp.OpName, null)] = 7; + OrderGroup[(SDSLOp.OpSDSLMixinVariable, null)] = 7; + OrderGroup[(SDSLOp.OpMemberName, null)] = 7; + + OrderGroup[(SDSLOp.OpModuleProcessed, null)] = 8; + + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpDecorate"))) + OrderGroup[(e, null)] = 9; + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpMemberDecorate"))) + OrderGroup[(e, null)] = 9; + + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) + OrderGroup[(e, null)] = 10; + + foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) + OrderGroup[(SDSLOp.OpVariable, e)] = 10; + OrderGroup[(SDSLOp.OpSDSLIOVariable, null)] = 10; + + OrderGroup[(SDSLOp.OpUndef, null)] = 10; + OrderGroup[(SDSLOp.OpLine, null)] = 11; + OrderGroup[(SDSLOp.OpNoLine, null)] = 11; + + foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) + OrderGroup[(e, null)] = 13; + OrderGroup[(SDSLOp.OpVariable, StorageClass.Function)] = 13; + OrderGroup[(SDSLOp.OpSDSLMixinEnd, null)] = 14; + } + /// + /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. + /// + /// + /// + public static int GetGroupOrder(RefInstruction instruction) + { + return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); + } + /// + /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. + /// + /// + /// + public static int GetGroupOrder(MutRefInstruction instruction) + { + return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); + } + /// + /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. + /// + /// + /// + public static int GetGroupOrder(Instruction instruction) + { + return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words.Span[3] : null); + } + + public static int GetGroupOrder(SDSLOp op, StorageClass? sc = null) + { + return Instance.OrderGroup[(op, sc)]; + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs new file mode 100644 index 0000000000..d64b0a2daa --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core; + + +/// +/// Singleton object containing informations on every spirv instructions, used for spirv parsing. +/// +public partial class InstructionInfo +{ + public static InstructionInfo Instance { get; } = new(); + Dictionary Info = new(); + InstructionInfo(){} + + internal void Register(SDSLOp op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) + { + if(Info.TryGetValue(op, out var list)) + { + list.Add(new(kind, quantifier, name)); + } + else + { + Info.Add(op, new(spvClass) { new(kind, quantifier, name)}); + } + } + /// + /// Gets information for the instruction operation. + /// + /// + /// + public static LogicalOperandArray GetInfo(SDSLOp op) + { + return Instance.Info[op]; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs new file mode 100644 index 0000000000..53b629fef8 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core; + + +public enum OperandWordSize +{ + One, + Two, + Variable, + Rest +} +public readonly partial struct LogicalOperand +{ + public int GetWordSize() + { + return Kind switch + { + OperandKind.PackedVectorFormat + or OperandKind.ImageOperands + or OperandKind.FPFastMathMode + or OperandKind.SelectionControl + or OperandKind.LoopControl + or OperandKind.FunctionControl + or OperandKind.MemorySemantics + or OperandKind.MemoryAccess + or OperandKind.KernelProfilingInfo + or OperandKind.RayFlags + or OperandKind.FragmentShadingRate + or OperandKind.SourceLanguage + or OperandKind.ExecutionModel + or OperandKind.AddressingModel + or OperandKind.MemoryModel + or OperandKind.ExecutionMode + or OperandKind.StorageClass + or OperandKind.Dim + or OperandKind.SamplerAddressingMode + or OperandKind.SamplerFilterMode + or OperandKind.ImageFormat + or OperandKind.ImageChannelOrder + or OperandKind.ImageChannelDataType + or OperandKind.FPRoundingMode + or OperandKind.LinkageType + or OperandKind.AccessQualifier + or OperandKind.FunctionParameterAttribute + or OperandKind.Decoration + or OperandKind.BuiltIn + or OperandKind.Scope + or OperandKind.GroupOperation + or OperandKind.KernelEnqueueFlags + or OperandKind.Capability + or OperandKind.RayQueryIntersection + or OperandKind.RayQueryCommittedIntersectionType + or OperandKind.RayQueryCandidateIntersectionType + or OperandKind.IdResultType + or OperandKind.IdResult + or OperandKind.IdMemorySemantics + or OperandKind.IdScope + or OperandKind.IdRef + or OperandKind.LiteralInteger => 1, + OperandKind.LiteralString => -1, + OperandKind.LiteralContextDependentNumber => -1, + OperandKind.LiteralExtInstInteger => 1, + OperandKind.LiteralSpecConstantOpInteger => 1, + OperandKind.PairLiteralIntegerIdRef => 2, + OperandKind.PairIdRefLiteralInteger => 2, + OperandKind.PairIdRefIdRef => 2, + _ => throw new NotImplementedException("Operand kind not recognized") + }; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs new file mode 100644 index 0000000000..b70ad71f5f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core; + +public readonly partial struct LogicalOperand +{ + public string? Name { get; init; } + public string? SpvClass { get; init; } + public OperandKind? Kind { get; init; } + public OperandQuantifier? Quantifier { get; init; } + + public LogicalOperand() { } + + public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) + { + Name = name; + Kind = kind; + SpvClass = spvClass; + Quantifier = quantifier; + } + public LogicalOperand(string kind, string quantifier, string? name = null, string? spvClass = null) + { + Name = name; + Kind = Enum.Parse(kind); + SpvClass = spvClass; + Quantifier = Enum.Parse(quantifier); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs new file mode 100644 index 0000000000..7776b66d75 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Collections; + +namespace Stride.Shaders.Spirv.Core; + +public struct LogicalOperandArray : IList +{ + + public string ClassName { get; init; } + + List LogicalOperands { get; } + public bool HasResult => GetHasResult(); + public bool HasResultType => GetHasResultType(); + + public int Count => LogicalOperands.Count; + + public bool IsReadOnly => false; + + public LogicalOperand this[int index] + { + get => LogicalOperands[index]; + set => LogicalOperands[index] = value; + } + + public LogicalOperandArray(string? className) + { + ClassName = className ?? "Debug"; + LogicalOperands = new(); + } + + bool GetHasResult() + { + foreach (var o in LogicalOperands) + { + if (o.Kind == OperandKind.IdResult) + return true; + } + return false; + } + bool GetHasResultType() + { + foreach (var o in LogicalOperands) + { + if (o.Kind == OperandKind.IdResultType) + return true; + } + return false; + } + + + public int IndexOf(LogicalOperand item) + { + return LogicalOperands.IndexOf(item); + } + + public void Insert(int index, LogicalOperand item) + { + LogicalOperands.Insert(index, item); + } + + public void RemoveAt(int index) + { + LogicalOperands.RemoveAt(index); + } + + public void Add(LogicalOperand item) + { + LogicalOperands.Add(item); + } + + public void Clear() + { + LogicalOperands.Clear(); + } + + public bool Contains(LogicalOperand item) + { + return LogicalOperands.Contains(item); + } + + public void CopyTo(LogicalOperand[] array, int arrayIndex) + { + LogicalOperands.CopyTo(array, arrayIndex); + } + + public bool Remove(LogicalOperand item) + { + return LogicalOperands.Remove(item); + } + + public IEnumerator GetEnumerator() + { + return LogicalOperands.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs new file mode 100644 index 0000000000..404973bd7c --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core; + +public interface IFromSpirv +{ + static abstract T From(Span words); + static abstract T From(string value); +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs new file mode 100644 index 0000000000..3f5bc31d03 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + +public interface ILiteralNumber : ISpirvElement +{ + public long Words { get; init; } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs new file mode 100644 index 0000000000..07161fd69e --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs @@ -0,0 +1,15 @@ +namespace Stride.Shaders.Spirv.Core; + + +public record struct IdMemorySemantics(int Value) : IFromSpirv +{ + public static implicit operator int(IdMemorySemantics r) => r.Value; + public static implicit operator IdMemorySemantics(int v) => new(v); + public static implicit operator LiteralInteger(IdMemorySemantics v) => new(v.Value); + public static IdMemorySemantics From(Span words) => new() { Value = words[0] }; + + public static IdMemorySemantics From(string value) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs new file mode 100644 index 0000000000..7ba6ed7240 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs @@ -0,0 +1,26 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct IdRef(int Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 1; + + public static implicit operator int(IdRef r) => r.Value; + public static implicit operator IdRef(int v) => new(v); + public static implicit operator LiteralInteger(IdRef v) => new(v); + public static IdRef From(Span words) => new() { Value = words[0] }; + + public static IdRef From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + var owner = SpanOwner.Allocate(1); + owner.Span[0] = Value; + return owner; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs new file mode 100644 index 0000000000..a6ac465bb5 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs @@ -0,0 +1,36 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct IdResult(int Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 1; + + public static implicit operator int(IdResult r) => r.Value; + public static implicit operator IdResult(int v) => new(v); + public static implicit operator LiteralInteger(IdResult v) => new(v); + public static IdResult From(Span words) => new() { Value = words[0] }; + + public static IdResult From(string value) + { + throw new NotImplementedException(); + } + public readonly SpanOwner AsSpanOwner() + { + var owner = SpanOwner.Allocate(1); + owner.Span[0] = Value; + return owner; + } +} + +public static class IdResultExtensions +{ + public static SpanOwner AsSpanOwner(this IdResult? value) + { + if(value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs new file mode 100644 index 0000000000..b52d0b64ac --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs @@ -0,0 +1,37 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct IdResultType(int Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 1; + + public static implicit operator int(IdResultType r) => r.Value; + public static implicit operator IdResultType(int v) => new(v); + public static implicit operator LiteralInteger(IdResultType v) => new(v); + public static IdResultType From(Span words) => new() { Value = words[0] }; + + public static IdResultType From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + var owner = SpanOwner.Allocate(1); + owner.Span[0] = Value; + return owner; + } +} + +public static class IdResultTypeExtensions +{ + public static SpanOwner AsSpanOwner(this IdResultType? value) + { + if(value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs new file mode 100644 index 0000000000..e028926d41 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs @@ -0,0 +1,36 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct IdScope(int Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 1; + + public static implicit operator int(IdScope r) => r.Value; + public static implicit operator IdScope(int v) => new(v); + public static implicit operator LiteralInteger(IdScope v) => new(v); + public static IdScope From(Span words) => new() { Value = words[0] }; + + public static IdScope From(string value) + { + throw new NotImplementedException(); + } + public readonly SpanOwner AsSpanOwner() + { + var owner = SpanOwner.Allocate(1); + owner.Span[0] = Value; + return owner; + } +} + +public static class IdScopeExtensions +{ + public static SpanOwner AsSpanOwner(this IdScope? value) + { + if(value is null) + return SpanOwner.Empty; + else + return new LiteralInteger(value.Value.Value).AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs new file mode 100644 index 0000000000..dda177b8f0 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -0,0 +1,132 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Drawing; +using System.Numerics; + + +namespace Stride.Shaders.Spirv.Core; + + +public struct LiteralFloat : ILiteralNumber, IFromSpirv +{ + public long Words { get; init; } + int size; + + public readonly int WordCount => size / 32; + + public LiteralFloat(Half value) + { + Words = BitConverter.HalfToInt16Bits(value); + size = 16; + + } + public LiteralFloat(float value) + { + Words = BitConverter.SingleToInt32Bits(value); ; + size = sizeof(float) * 8; + } + public LiteralFloat(double value) + { + Words = BitConverter.DoubleToInt64Bits(value); + size = sizeof(double) * 8; + + } + public LiteralFloat(Span words) + { + if (words.Length == 2) + { + size = sizeof(long) * 8; + Words = words[0] << 32 | words[1]; + } + else if (words.Length == 1) + { + size = sizeof(int) * 8; + Words = words[0]; + } + + } + + + public static implicit operator LiteralFloat(Half value) => new(value); + public static implicit operator LiteralFloat(float value) => new(value); + public static implicit operator LiteralFloat(double value) => new(value); + public static implicit operator LiteralInteger(LiteralFloat value) => new(value.Words); + + + + public readonly bool TryCast(out Half value) + { + short bits = (short)(Words & 0X000000FF); + if (size == 32) + { + value = BitConverter.Int16BitsToHalf(bits); + return true; + } + else + { + value = Half.Zero; + return false; + } + } + public readonly bool TryCast(out float value) + { + Span span = stackalloc int[] + { + (int)(Words >> 32), + (int)(Words & 0X0000FFFF) + }; + if (size == 32) + { + value = BitConverter.Int32BitsToSingle(span[1]); + return true; + } + else + { + value = 0; + return false; + } + } + public readonly bool TryCast(out double value) + { + if (size == 64) + { + value = BitConverter.Int64BitsToDouble(Words); + return true; + } + else + { + value = 0; + return false; + } + } + + + + public readonly void Write(ref SpirvWriter writer) + { + Span span = + [ + (int)(Words >> 32), + (int)(Words & 0xFFFFFFFF) + ]; + if (size < 64) + writer.Write(span[1]); + else + writer.Write(span); + } + + public static LiteralFloat From(Span words) => new(words); + + public static LiteralFloat From(string value) + { + throw new NotImplementedException(); + } + public readonly SpanOwner AsSpanOwner() + { + Span span = WordCount == 1 ? [ (int)Words ] : [ (int)(Words >> 32), (int)(Words & 0xFFFFFFFF) ]; + var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); + span.CopyTo(owner.Span); + return owner; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs new file mode 100644 index 0000000000..2b5631007a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs @@ -0,0 +1,121 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core; + + +public struct LiteralInteger : ILiteralNumber, IFromSpirv +{ + public long Words { get; init; } + public int Size { get; init; } + public readonly int WordCount => Size / 32; + + public LiteralInteger(sbyte value) + { + Words = 0 | value; + Size = sizeof(sbyte) * 8; + } + public LiteralInteger(byte value) + { + Words = 0 | value; + Size = sizeof(byte) * 8; + } + + public LiteralInteger(short value) + { + Words = 0 | value; + Size = sizeof(short) * 8; + } + public LiteralInteger(ushort value) + { + Words = 0 | value; + Size = sizeof(ushort) * 8; + } + + public LiteralInteger(int value) + { + Words = 0 | value; + Size = sizeof(int) * 8; + } + public LiteralInteger(int? value) + { + Words = 0 | value ?? 0; + Size = sizeof(int) * 8; + } + public LiteralInteger(uint value) + { + Words = 0 | value; + Size = sizeof(uint) * 8; + + } + public LiteralInteger(long value) + { + Words = 0 | value; + Size = sizeof(long) * 8; + } + public LiteralInteger(ulong value) + { + Words = (long)value; + Size = sizeof(ulong) * 8; + + } + + public LiteralInteger(Span value) + { + if(value.Length == 2) + { + Size = sizeof(long) * 8; + Words = value[0] << 32 | value[1]; + } + else if (value.Length == 1) + { + Size = sizeof(int) * 8; + Words = value[0]; + } + } + + + public static implicit operator LiteralInteger(byte value) => new(value); + public static implicit operator LiteralInteger(sbyte value) => new(value); + public static implicit operator LiteralInteger(ushort value) => new(value); + public static implicit operator LiteralInteger(short value) => new(value); + public static implicit operator LiteralInteger(int value) => new(value); + public static implicit operator LiteralInteger(int? value) => new(value); + public static implicit operator LiteralInteger(uint value) => new(value); + public static implicit operator LiteralInteger(long value) => new(value); + public static implicit operator LiteralInteger(ulong value) => new(value); + + public readonly void Write(ref SpirvWriter writer) + { + Span span = + [ + (int)(Words >> 32), + (int)(Words & 0X000000FF) + ]; + if (Size < 64) + writer.Write(span[1]); + else + writer.Write(span); + } + + public static LiteralInteger From(Span words) + { + return new(words); + } + + public static LiteralInteger From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + Span span = WordCount == 1 ? [ (int)Words ] : [ (int)(Words >> 32), (int)(Words & 0xFFFFFFFF) ]; + var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); + span.CopyTo(owner.Span); + return owner; + } +} + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs new file mode 100644 index 0000000000..26f4ef8dfa --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -0,0 +1,125 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Runtime.InteropServices; +using System.Text; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core; + + +public readonly struct LiteralString : ISpirvElement, IFromSpirv +{ + readonly static StringPool pool = new(); + + public string Value { get; init; } + public readonly int Length => Value.Length + 1; + + public int WordCount => (Length / 4) + (HasRest ? 1 : 0); + internal bool HasRest => Length % 4 > 0; + internal int RestSize => Length % 4; + + internal LiteralString(string value) + { + Value = pool.GetOrAdd(value); + } + internal LiteralString(Span words) + { + Span chars = stackalloc char[words.Length * 4]; + for (int i = 0; i < words.Length; i++) + { + chars[i * 4] = (char)(words[i] & 0xFF); + chars[i * 4 + 1] = (char)(words[i] >> 8 & 0xFF); + chars[i * 4 + 2] = (char)(words[i] >> 16 & 0xFF); + chars[i * 4 + 3] = (char)(words[i] >> 24 & 0xFF); + }; + var real = chars[..chars.IndexOf('\0')]; + Value = pool.GetOrAdd(real); + } + public static implicit operator LiteralString(string s) => new(s); + + + public void WriteTo(Span slice) + { + for (int i = 0; i < Length; i++) + { + var pos = i / 4; + var shift = 8 * (i % 4); + var value = i < Value.Length ? Value[i] : '\0'; + slice[pos] |= value << shift; + } + } + + public void Write(ref SpirvWriter writer) + { + var wordLength = Value.Length / 4; + var rest = RestSize; + var span = Value.AsSpan(); + for (int i = 0; i < wordLength; i++) + { + if (rest == 0) + { + int word = + Convert.ToByte(span[4 * i]) << 24 + | Convert.ToByte(span[4 * i + 1]) << 16 + | Convert.ToByte(span[4 * i + 2]) << 8 + | Convert.ToByte(span[4 * i + 3]); + writer.Write(word); + } + else + { + if (i < wordLength - 1) + { + int word = + Convert.ToByte(span[4 * i]) << 24 + | Convert.ToByte(span[4 * i + 1]) << 16 + | Convert.ToByte(span[4 * i + 2]) << 8 + | Convert.ToByte(span[4 * i + 3]); + writer.Write(word); + + } + else + { + if (rest == 1) + writer.Write( + Convert.ToByte(span[4 * i]) << 24 + ); + else if (rest == 2) + writer.Write( + Convert.ToByte(span[4 * i]) << 24 + | Convert.ToByte(span[4 * i + 1]) << 16 + ); + else if (rest == 3) + writer.Write( + Convert.ToByte(span[4 * i]) << 24 + | Convert.ToByte(span[4 * i + 1]) << 16 + | Convert.ToByte(span[4 * i + 2]) << 8 + ); + } + } + } + } + + public static string Parse(Span input) + { + var lit = new LiteralString(input); + return lit.Value; + } + + public static LiteralString From(Span words) + { + return new(words); + } + + public static LiteralString From(string value) => value; + + public SpanOwner AsSpanOwner() + { + return Value.AsSpanOwner(); + } +} + +public static class SpirvStringExtensions +{ + public static LiteralString ToLiteralString(this string value) => value; + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs new file mode 100644 index 0000000000..799e4a197f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs @@ -0,0 +1,35 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct PairIdRefIdRef((int,int) Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 2; + + public static implicit operator (int,int)(PairIdRefIdRef r) => r.Value; + public static implicit operator PairIdRefIdRef((int,int) v) => new(v); + public static implicit operator LiteralInteger(PairIdRefIdRef v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); + public static PairIdRefIdRef From(Span words) => new() { Value = (words[0], words[1]) }; + + public static PairIdRefIdRef From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); + } +} + +public static class PairIdRefIdRefExtensions +{ + public static SpanOwner AsSpanOwner(this PairIdRefIdRef? value) + { + if(value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs new file mode 100644 index 0000000000..0fd5442c71 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs @@ -0,0 +1,34 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct PairIdRefLiteralInteger((int,int) Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 2; + + public static implicit operator (int,int)(PairIdRefLiteralInteger r) => r.Value; + public static implicit operator PairIdRefLiteralInteger((int,int) v) => new(v); + public static implicit operator LiteralInteger(PairIdRefLiteralInteger v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); + public static PairIdRefLiteralInteger From(Span words) => new() { Value = (words[0], words[1]) }; + + public static PairIdRefLiteralInteger From(string value) + { + throw new NotImplementedException(); + } + public readonly SpanOwner AsSpanOwner() + { + return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); + } +} + +public static class PairIdRefLiteralIntegerExtensions +{ + public static SpanOwner AsSpanOwner(this PairIdRefLiteralInteger? value) + { + if(value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs new file mode 100644 index 0000000000..a516780331 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs @@ -0,0 +1,34 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct PairLiteralIntegerIdRef((int, int) Value) : ISpirvElement, IFromSpirv +{ + public readonly int WordCount => 2; + + public static implicit operator (int, int)(PairLiteralIntegerIdRef r) => r.Value; + public static implicit operator PairLiteralIntegerIdRef((int, int) v) => new(v); + public static implicit operator LiteralInteger(PairLiteralIntegerIdRef v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); + public static PairLiteralIntegerIdRef From(Span words) => new() { Value = (words[0], words[1]) }; + + public static PairLiteralIntegerIdRef From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); + } +} +public static class PairLiteralIntegerIdRefExtensions +{ + public static SpanOwner AsSpanOwner(this PairLiteralIntegerIdRef? value) + { + if (value is null) + return SpanOwner.Empty; + else + return value.Value.AsSpanOwner(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs new file mode 100644 index 0000000000..2a2111f0c5 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs @@ -0,0 +1,19 @@ +using System.Runtime.CompilerServices; +using System; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core; + + +public record struct SpvEnum(T Value) : IFromSpirv> + where T : Enum +{ + public static implicit operator T(SpvEnum r) => r.Value; + public static implicit operator SpvEnum(T v) => new(v); + public static SpvEnum From(Span words) => new() { Value = Unsafe.As(ref words[0]) }; + + public static SpvEnum From(string value) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs new file mode 100644 index 0000000000..9fd1e3adcb --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -0,0 +1,52 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + + +namespace Stride.Shaders.Spirv.Core; + +/// +/// Representation of an instruction from a memory slice. +/// +/// +/// +/// +/// +public record struct Instruction(ISpirvBuffer Buffer, Memory Words, int Index, int WordIndex) +{ + public static Instruction Empty { get; } = new(null!, Memory.Empty, 0, 0); + + public static implicit operator IdRef(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); + public static implicit operator IdResultType(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); + + + public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Empty, index, 0) + { + Buffer = buffer; + Index = index; + var wid = 0; + for (int i = 0; i < index; i += 1) + wid += buffer.InstructionSpan[wid] >> 16; + Words = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); + WordIndex = wid; + } + + public SDSLOp OpCode => AsRef().OpCode; + public readonly int? ResultId { get => AsRef().ResultId; set => AsRef().SetResultId(value); } + public readonly int? ResultType { get => AsRef().ResultType; set => AsRef().SetResultType(value); } + public readonly int WordCount => Words.Length; + public readonly Memory Operands => Words[1..]; + + public bool IsEmpty => Words.IsEmpty; + + public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Words.Span); + + public T? GetOperand(string name) where T : struct, IFromSpirv + => AsRef().GetOperand(name); + + public readonly OperandEnumerator GetEnumerator() => AsRef().GetEnumerator(); + + public override string ToString() + { + return (ResultId == null ? "" : $"%{ResultId} = ") + $"{OpCode} {string.Join(" ", Operands.ToArray().Select(x => x.ToString()))}"; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs new file mode 100644 index 0000000000..883cae9254 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs @@ -0,0 +1,77 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System.Runtime.CompilerServices; + +namespace Stride.Shaders.Spirv.Core; + +/// +/// Helps create instruction through stack allocations instead of buffers +/// +public ref struct MutRefInstruction +{ + public Span Words { get; } + public Span Operands => Words [1..]; + public readonly SDSLOp OpCode + { + get => (SDSLOp)(Words[0] & 0xFFFF); + set { unchecked { Words[0] = (Words[0] & (int)0xFFFF0000) | (int)value;}} + } + public readonly int WordCount + { + get => Words[0] >> 16; + set => Words[0] = value << 16 | Words[0] & 0xFFFF; + } + + + private int _index; + + public MutRefInstruction(Span words) + { + Words = words; + WordCount = words.Length; + _index = 1; + } + public void Add(scoped Span values) + { + values.CopyTo(Words[_index..]); + _index += values.Length; + } + public void Add(Span values) + where T : ISpirvElement + { + foreach(var e in values) + Add(e.AsSpanOwner().Span); + } + + public void Add(T? value) + { + if (value != null) + { + if (value is int i) + Add([i]); + else if (value is ISpirvElement element) + Add(element.AsSpanOwner().Span); + else if (value is string s) + Add(s.AsSpanOwner().Span); + else if (value is Enum e) + Add([Convert.ToInt32(e)]); + } + } + + public readonly OperandEnumerator GetEnumerator() => new(RefInstruction.ParseRef(Words)); + public readonly T GetOperand(string name) + where T : struct, IFromSpirv + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + operandEnumerator.MoveNext(); + if (infoEnumerator.Current.Name == name) + { + return operandEnumerator.Current.To(); + } + } + throw new Exception($"Instruction {OpCode} has no operand named \"{name}\""); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs new file mode 100644 index 0000000000..2e080fe9f1 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs @@ -0,0 +1,8 @@ +namespace Stride.Shaders.Spirv.Core; + +public enum OperandQuantifier +{ + One, + ZeroOrOne, + ZeroOrMore +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs new file mode 100644 index 0000000000..d631384489 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs @@ -0,0 +1,144 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// A spirv buffer enumerator with filters on operations +/// +/// +public ref struct FilteredEnumerator + where T : ISpirvBuffer +{ + int wordIndex; + int index; + bool started; + T buffer; + readonly Span instructionWords => buffer.InstructionSpan; + + string? classFilter; + SDSLOp? filter1; + SDSLOp? filter2; + SDSLOp? filter3; + SDSLOp? filter4; + + FilterType filterType; + + + public FilteredEnumerator(T buff, string classFilt) + { + started = false; + wordIndex = 0; + buffer = buff; + classFilter = classFilt; + filterType = FilterType.ClassName; + } + public FilteredEnumerator(T buff, SDSLOp filt1) + { + started = false; + wordIndex = 0; + buffer = buff; + filter1 = filt1; + filterType = FilterType.Op1; + } + public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2) + { + started = false; + wordIndex = 0; + buffer = buff; + filter1 = filt1; + filter2 = filt2; + filterType = FilterType.Op2; + } + public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2, SDSLOp filt3) + { + started = false; + wordIndex = 0; + buffer = buff; + filter1 = filt1; + filter2 = filt2; + filter3 = filt3; + filterType = FilterType.Op3; + } + public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2, SDSLOp filt3, SDSLOp filt4) + { + started = false; + wordIndex = 0; + buffer = buff; + filter1 = filt1; + filter2 = filt2; + filter3 = filt3; + filter4 = filt4; + filterType = FilterType.Op4; + } + + public Instruction Current => ParseCurrentInstruction(); + + bool Matches(SDSLOp toCheck) + { + return filterType switch + { + FilterType.ClassName => InstructionInfo.GetInfo(toCheck).ClassName == classFilter, + FilterType.Op1 => toCheck == filter1, + FilterType.Op2 => toCheck == filter1 || toCheck == filter2, + FilterType.Op3 => toCheck == filter1 || toCheck == filter2 || toCheck == filter3, + FilterType.Op4 => toCheck == filter1 || toCheck == filter2 || toCheck == filter3 || toCheck == filter4, + _ => false + }; + } + public bool MoveNext() + { + if (!started) + { + started = true; + index = 0; + var sizeToStep = 0; + while (wordIndex + sizeToStep < instructionWords.Length && !Matches((SDSLOp)(instructionWords[wordIndex + sizeToStep] & 0xFFFF))) + { + sizeToStep += instructionWords[wordIndex + sizeToStep] >> 16; + index += 1; + } + wordIndex += sizeToStep; + if (wordIndex >= instructionWords.Length) + return false; + return true; + } + else + { + var sizeToStep = instructionWords[wordIndex] >> 16; + while(wordIndex + sizeToStep < instructionWords.Length && !Matches((SDSLOp)(instructionWords[wordIndex + sizeToStep] & 0xFFFF))) + { + sizeToStep += instructionWords[wordIndex + sizeToStep] >> 16; + index += 1; + } + wordIndex += sizeToStep; + if (wordIndex >= instructionWords.Length) + return false; + return true; + } + + } + + + public Instruction ParseCurrentInstruction() + { + var wordCount= instructionWords[wordIndex] >> 16; + return new(buffer, buffer.Memory.Slice(wordIndex, wordCount), index, wordIndex); + } + + internal enum FilterType + { + ClassName, + Op1, + Op2, + Op3, + Op4 + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs new file mode 100644 index 0000000000..6daed66302 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs @@ -0,0 +1,63 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// A simple spirv instruction enumerator without sorting +/// +public ref struct InstructionEnumerator +{ + int wordIndex; + int index; + bool started; + ISpirvBuffer buffer; + + public int ResultIdReplacement { get; set; } + + public InstructionEnumerator(ISpirvBuffer buffer) + { + started = false; + wordIndex = 0; + this.buffer = buffer; + ResultIdReplacement = 0; + } + + public Instruction Current => ParseCurrentInstruction(); + + public bool MoveNext() + { + if (!started) + { + started = true; + return true; + } + else + { + if (wordIndex >= buffer.InstructionSpan.Length) + return false; + var sizeToStep = buffer.InstructionSpan[wordIndex] >> 16; + wordIndex += sizeToStep; + index += 1; + if (wordIndex >= buffer.InstructionSpan.Length) + return false; + return true; + } + + } + + + public Instruction ParseCurrentInstruction() + { + var count = buffer.InstructionSpan[wordIndex] >> 16; + return new Instruction(buffer, buffer.InstructionMemory[wordIndex..(wordIndex + count)], index, wordIndex); + + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs new file mode 100644 index 0000000000..4e7ffe55c6 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs @@ -0,0 +1,42 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// A utility struct to find and look for specific instructions +/// +/// +public ref struct InstructionFinder where T : ISpirvBuffer +{ + T buffer; + //LambdaFilteredEnumerator enumerator; + + public InstructionFinder(T buffer) + { + this.buffer = buffer; + } + + public readonly Instruction First(Func filter) + { + var enumerator = new LambdaFilteredEnumerator(buffer, filter); + if (enumerator.MoveNext()) + return enumerator.Current; + else + throw new Exception("No matching instructions found"); + } + public readonly Instruction Last(Func filter) + { + var enumerator = new LambdaFilteredEnumerator(buffer, filter); + Instruction? result = null; + if (enumerator.MoveNext()) + result = enumerator.Current; + + return result != null ? result .Value: throw new Exception("No matching instructions found"); + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs new file mode 100644 index 0000000000..ec43176dc3 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs @@ -0,0 +1,43 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; +/// +/// An enumerator to filter instructions with a lambda +/// +/// +public ref struct LambdaFilteredEnumerator + where T : ISpirvBuffer +{ + T buffer; + + string? classFilter; + Func filter; + InstructionEnumerator enumerator; + + + public LambdaFilteredEnumerator(T buff, Func filter) + { + buffer = buff; + this.filter = filter; + enumerator = new(buffer); + } + public Instruction Current => enumerator.Current; + public bool MoveNext() + { + while(enumerator.MoveNext()) + { + if (filter.Invoke(Current) == true) + return true; + } + return false; + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs new file mode 100644 index 0000000000..5454c681ae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -0,0 +1,250 @@ +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// An instruction operands enumerator, useful for parsing instructions +/// +public ref struct OperandEnumerator +{ + static OperandKind[] pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); + RefInstruction instruction; + Span operands => instruction.Operands; + readonly LogicalOperandArray logicalOperands; + int wid; + int oid; + + public OperandEnumerator(RefInstruction instruction) + { + this.instruction = instruction; + logicalOperands = InstructionInfo.GetInfo(instruction.OpCode); + oid = -1; + wid = 0; + } + + public SpvOperand Current => ParseCurrent(); + + public bool MoveNext() + { + if (oid < 0) + { + oid = 0; + if (logicalOperands[0].Kind == OperandKind.None) + return false; + return true; + } + else + { + + var logOp = logicalOperands[oid]; + + if (instruction.OpCode == SDSLOp.OpDecorate) + { + if (oid == 0) + { + wid += 1; + oid += 1; + return true; + } + else if (oid > 0) + { + var builtin = (Decoration)operands[1]; + bool has2Extra = builtin == Decoration.LinkageAttributes; + bool has1Extra = + builtin == Decoration.BuiltIn + || builtin == Decoration.Location + || builtin == Decoration.SpecId + || builtin == Decoration.ArrayStride + || builtin == Decoration.MatrixStride + || builtin == Decoration.UniformId + || builtin == Decoration.Stream + || builtin == Decoration.Component + || builtin == Decoration.Index + || builtin == Decoration.Binding + || builtin == Decoration.DescriptorSet + || builtin == Decoration.Offset + || builtin == Decoration.XfbBuffer + || builtin == Decoration.XfbStride + || builtin == Decoration.FuncParamAttr + || builtin == Decoration.FPRoundingMode + || builtin == Decoration.FPFastMathMode + || builtin == Decoration.LinkageAttributes + || builtin == Decoration.InputAttachmentIndex + || builtin == Decoration.Alignment + || builtin == Decoration.MaxByteOffset + || builtin == Decoration.AlignmentId + || builtin == Decoration.MaxByteOffsetId + || builtin == Decoration.SecondaryViewportRelativeNV + || builtin == Decoration.CounterBuffer; + if (has1Extra && oid == 1 && !has2Extra) + { + wid += 1; + oid += 1; + } + else if (has2Extra) + { + throw new NotImplementedException(); + } + else + { + return false; + } + + } + + oid += 1; + if (oid > 2) + return false; + else + return wid < operands.Length; + } + else if (logOp.Quantifier == OperandQuantifier.One) + { + if (logOp.Kind == OperandKind.LiteralString) + { + while (!operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) + wid += 2; + else + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) + { + if ( + pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) + && wid < operands.Length - 1 + ) + { + wid += 2; + } + else if ( + logOp.Kind == OperandKind.LiteralString + && wid < operands.Length + ) + { + while (!operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (wid < operands.Length) + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + throw new NotImplementedException("params of strings is not yet implemented"); + else if ( + pairs.Contains(logOp.Kind ?? throw new Exception()) + && wid < operands.Length - 2 + ) + wid += 2; + else if (wid < operands.Length - 1) + wid += 1; + else + oid += 1; + + } + if (oid >= logicalOperands.Count) + return false; + return wid < operands.Length; + } + + } + + public SpvOperand ParseCurrent() + { + var logOp = logicalOperands[oid]; + if (instruction.OpCode == SDSLOp.OpDecorate) + { + SpvOperand result = new(); + if (oid == 0) + result = new(OperandKind.IdRef, OperandQuantifier.One, operands.Slice(wid, 1)); + else if (oid == 1) + result = new(OperandKind.Decoration, OperandQuantifier.One, operands.Slice(wid, 1)); + else if (oid == 2) + { + result = result with + { + Kind = (Decoration)operands[1] switch + { + Decoration.BuiltIn => OperandKind.BuiltIn, + Decoration.Location => OperandKind.LiteralInteger, + Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, + Decoration.ArrayStride => OperandKind.LiteralInteger, + Decoration.MatrixStride => OperandKind.LiteralInteger, + Decoration.UniformId => OperandKind.IdScope, + Decoration.Stream => OperandKind.LiteralInteger, + Decoration.Component => OperandKind.LiteralInteger, + Decoration.Index => OperandKind.LiteralInteger, + Decoration.Binding => OperandKind.LiteralInteger, + Decoration.DescriptorSet => OperandKind.LiteralInteger, + Decoration.Offset => OperandKind.LiteralInteger, + Decoration.XfbBuffer => OperandKind.LiteralInteger, + Decoration.XfbStride => OperandKind.LiteralInteger, + Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, + Decoration.FPRoundingMode => OperandKind.FPRoundingMode, + Decoration.FPFastMathMode => OperandKind.FPFastMathMode, + Decoration.LinkageAttributes => OperandKind.LiteralString, + Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, + Decoration.Alignment => OperandKind.LiteralInteger, + Decoration.MaxByteOffset => OperandKind.LiteralInteger, + Decoration.AlignmentId => OperandKind.IdRef, + Decoration.MaxByteOffsetId => OperandKind.IdRef, + Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, + Decoration.CounterBuffer => OperandKind.IdRef, + _ => OperandKind.None + } + }; + } + return result; + + } + else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + { + var length = 0; + while (!operands[wid + length].HasEndString()) + length += 1; + length += 1; + var result = new SpvOperand(OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, length)); + + return result; + } + else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) + { + var result = new SpvOperand(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + return result; + } + else + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + } + else + { + if (pairs.Contains(logOp.Kind ?? OperandKind.None)) + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + else + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + } + } + +} + +public static class IntExtensions +{ + public static bool HasEndString(this int i) + { + return + (char)(i >> 24) == '\0' + || (char)(i >> 16 & 0XFF) == '\0' + || (char)(i >> 8 & 0xFF) == '\0' + || (char)(i & 0xFF) == '\0'; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs new file mode 100644 index 0000000000..1841d6af9d --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -0,0 +1,136 @@ +using CommunityToolkit.HighPerformance.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Buffers; + +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + + +/// +/// An enumerator where each declartions instructions is sorted +/// +public ref struct OrderedEnumerator +{ + int index; + int wordIndex; + bool started; + + + ISpirvBuffer wbuff; + readonly Span instructionWords => wbuff.InstructionSpan; + Memory memorySlice => wbuff.InstructionMemory; + + public OrderedEnumerator(ISpirvBuffer buffer) + { + started = false; + wordIndex = 0; + index = 0; + wbuff = buffer; + } + + public readonly Instruction Current => new(wbuff, wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16), index, wordIndex); + + public bool MoveNext() + { + // The first time find the lowest group and index + if (!started) + { + (var firstGroup, var firstPos) = (int.MaxValue, int.MaxValue); + var wid = 0; + var idx = 0; + while(wid < instructionWords.Length) + { + var group = GetGroupOrder(wid); + if(group < firstGroup) + { + firstGroup = group; + firstPos = wid; + index = idx; + } + idx += 1; + wid += instructionWords[wid] >> 16; + } + wordIndex = firstPos; + started = true; + return true; + } + else + { + // We start from the current group since we've established there is no other below this one + var currentGroup = GetGroupOrder(wordIndex); + for (int group = currentGroup; group < 15; group += 1) + { + if(group == currentGroup) + { + var offset = instructionWords[wordIndex] >> 16; + var idx = index + 1; + while(wordIndex + offset < instructionWords.Length) + { + if(GetGroupOrder(wordIndex + offset) == group && idx > index) + { + wordIndex += offset; + index = idx; + return true; + } + offset += instructionWords[wordIndex + offset] >> 16; + idx += 1; + } + } + else + { + var wid = 0; + var idx = 0; + while (wid < instructionWords.Length) + { + var g = GetGroupOrder(wid); + if (g == group) + { + wordIndex = wid; + index = idx; + return true; + } + idx += 1; + wid += instructionWords[wid] >> 16; + } + } + } + return false; + + //var count = new SpirvReader(memorySlice).Count; + //var currentGroup = GetGroupOrder(wordIndex); + //for (int groupOffset = 0; groupOffset < 14; groupOffset++) + //{ + // var wid = 0; + // for (int i = 0; i < count; i++) + // { + // if (wid >= instructionWords.Length) + // break; + // var g = GetGroupOrder(wid); + // if (GetGroupOrder(wid) == currentGroup + groupOffset && i != index) + // { + // if (!(groupOffset == 0 && i < index)) + // { + // index = i; + // wordIndex = wid; + // return true; + // } + // } + // wid += instructionWords[wid] >> 16; + // } + //} + //return false; + } + + } + + int GetGroupOrder(int wid) + { + var op = (SDSLOp)(instructionWords[wid] & 0xFFFF); + return InstructionInfo.GetGroupOrder(op, op == SDSLOp.OpVariable ? (StorageClass)instructionWords[wid + 3] : null); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs new file mode 100644 index 0000000000..0ac1e94488 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// A spirv header parser +/// +public ref struct RefHeader +{ + Span Words { get; init; } + public uint MagicNumber { get => unchecked((uint)Words[0]); set => Words[0] = unchecked((int)value); } + public SpirvVersion VersionNumber { get => Words[1]; set => Words[1] = value; } + public int GeneratorMagicNumber { get => Words[2]; set => Words[2] = value; } + public int Bound { get => Words[3]; set => Words[3] = value; } + public int Schema { get => Words[4]; set => Words[4] = value; } + + public string Version => $"{VersionNumber >> 16}.{(VersionNumber >> 8) & 0x00FF}"; + + public RefHeader(Span words) + { + if (words.Length != 5) + throw new ArgumentException("There should be 5 words"); + Words = words; + } + + public bool IsValidMagic => MagicNumber == Spv.Specification.MagicNumber; + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs new file mode 100644 index 0000000000..cf57ca957c --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// An instruction utility parser. +/// +public ref struct RefInstructions +{ + Memory Words { get; init; } + + + public RefInstructions(Memory words) + { + Words = words; + } + + + public Enumerator GetEnumerator() => new(Words); + + public ref struct Enumerator + { + int wordIndex; + bool started; + Memory words; + + public Enumerator(Memory words) + { + started = false; + wordIndex = 0; + this.words = words; + } + + public RefInstruction Current => ParseCurrentInstruction(); + + public bool MoveNext() + { + if (!started) + { + started = true; + return true; + } + else + { + var sizeToStep = words.Span[wordIndex] >> 16; + wordIndex += sizeToStep; + if (wordIndex >= words.Length) + return false; + return true; + } + + } + + + public RefInstruction ParseCurrentInstruction() + { + var wordNumber = words.Span[wordIndex] >> 16; + return RefInstruction.Parse(words, wordIndex); + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs new file mode 100644 index 0000000000..c229c0896f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// Spirv version wrapper to interact through string/integers +/// +public struct SpirvVersion +{ + public int Version { get; } + + internal SpirvVersion(int word) + { + Version = word; + } + + public SpirvVersion(int major, int minor) + { + Version = major << 16 | minor << 8; + } + public SpirvVersion(string version) + { + if(version.Length == 3 && char.IsDigit(version[0]) && version[1] == '.' && char.IsDigit(version[2])) + { + Version = version[0] - '0' << 16 | version[1] - '0' << 8; + } + } + + public static implicit operator int(SpirvVersion v) => v.Version; + public static implicit operator SpirvVersion(int v) => new(v); + public static implicit operator SpirvVersion(string v) => new(v); +} + +/// +/// Spirv Header struct for spirv assembling +/// +public struct SpirvHeader +{ + public uint MagicNumber { get; init; } + public SpirvVersion VersionNumber { get; init; } + public int GeneratorMagicNumber { get; init; } + public int Bound { get; init; } + public int Schema { get; init; } + + public string Version => $"{VersionNumber >> 16}.{(VersionNumber >> 8) & 0x00FF}"; + + public SpirvHeader(string version, int generator, int bound, int schema = 0) + { + MagicNumber = Spv.Specification.MagicNumber; + VersionNumber = version; + GeneratorMagicNumber = generator; + Bound = bound; + Schema = schema; + } + public SpirvHeader(SpirvVersion version, int generator, int bound, int schema = 0) + { + MagicNumber = Spv.Specification.MagicNumber; + VersionNumber = version; + GeneratorMagicNumber = generator; + Bound = bound; + Schema = schema; + } + + public void WriteTo(Span words) + { + words[0] = unchecked((int)MagicNumber); + words[1] = VersionNumber.Version; + words[2] = GeneratorMagicNumber; + words[3] = Bound; + words[4] = Schema; + } + + public static SpirvHeader Read(Span words) + { + return new SpirvHeader + { + MagicNumber = (uint)words[0], + VersionNumber = words[1], + GeneratorMagicNumber = words[2], + Bound = words[3], + Schema = words[4] + }; + } + + public bool IsValidMagic => MagicNumber == Spv.Specification.MagicNumber; + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs new file mode 100644 index 0000000000..d1aea8809f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -0,0 +1,72 @@ +using CommunityToolkit.HighPerformance.Buffers; +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// Simple Spirv parser for external buffers +/// +public ref struct SpirvReader +{ + public static void ParseToList(byte[] byteCode, List instructions) + { + + var span = MemoryMarshal.Cast(byteCode.AsSpan()); + var data = new WordBuffer(span); + foreach (var instruction in data) + instructions.Add(instruction); + } + + + + + SpirvSpan buffer; + public int Count => GetInstructionCount(); + public int WordCount => buffer.Length; + public bool HasHeader { get; init; } + + public SpirvReader(byte[] byteCode, bool hasHeader = false) + { + buffer = new(MemoryMarshal.Cast(byteCode.AsSpan())); + HasHeader = hasHeader; + } + public SpirvReader(MemoryOwner slice, bool hasHeader = false) + { + buffer = new(slice.Span); + HasHeader = hasHeader; + } + public SpirvReader(Memory slice, bool hasHeader = false) + { + buffer = new(slice.Span[(hasHeader ? 5 : 0)..]); + } + public SpirvReader(Memory slice) + { + buffer = new(slice.Span); + //data = slice; + } + + + public SpirvSpan.Enumerator GetEnumerator() => new(buffer.Span); + + public int GetInstructionCount() + { + var count = 0; + var index = 0; + while(index < buffer.Length) + { + count += 1; + index += buffer[index] >> 16; + } + return count; + } + + public int ComputeBound() + { + var result = 0; + foreach(var e in this) + if(e.ResultId != null && e.ResultId > result) + result = e.ResultId.Value; + return result; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs new file mode 100644 index 0000000000..bf8aa77a0f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs @@ -0,0 +1,47 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core.Parsing; + + +public ref struct SpirvWriter +{ + public int Length { get; private set;} + MemoryOwner buffer; + + public Span SpirvCode => buffer.Span[..(Length-1)]; + + public SpirvWriter(int initialSize = 32) + { + buffer = MemoryOwner.Allocate(initialSize, AllocationMode.Clear); + Length = 0; + } + + void Expand(int size) + { + var futureLength = Length + size; + var realLength = buffer.Length; + if(Length > buffer.Length) + { + buffer.Dispose(); + buffer = MemoryOwner.Allocate(realLength*2, AllocationMode.Clear); + } + } + + public void Write(int word) + { + Expand(1); + buffer.Span[Length] = word; + Length += 1; + } + public void Write(scoped Span words) + { + Expand(words.Length); + words.CopyTo(buffer.Span[Length..]); + Length += Length; + } + + public void Dispose() + { + buffer.Dispose(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs new file mode 100644 index 0000000000..8e992b8909 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -0,0 +1,142 @@ +using System.Text; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + + +namespace Stride.Shaders.Spirv.Core; + +/// +/// A ref struct representation of an instruction in a buffer. +/// +public ref struct RefInstruction +{ + + public static RefInstruction Empty => new() { Words = Span.Empty, Operands = Span.Empty }; + + + /// + /// Word Count is the high-order 16 bits of word 0 of the instruction, holding its total WordCount. + ///
If the instruction takes a variable number of operands, Word Count also says "+ variable", after stating the minimum size of the instruction. + ///
+ public readonly int WordCount => Words[0] >> 16; + public readonly SDSLOp OpCode => (SDSLOp)(Words[0] & 0xFFFF); + public int? ResultId { get => GetResultId(); set => SetResultId(value); } + public int? ResultType { get => GetResultType(); set => SetResultType(value); } + public Span Operands { get; init; } + public Memory? Slice { get; init; } + public int OwnerIndex { get; set; } + public Span Words { get; init; } + + + + public bool IsEmpty => Words == Span.Empty; + + + + + public OperandEnumerator GetEnumerator() => new(this); + + + public T? GetOperand(string name) + where T : struct, IFromSpirv + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + return operandEnumerator.Current.To(); + } + } + } + return null; + } + + public static RefInstruction Parse(Memory owner, int ownerIndex) + { + var words = owner.Span.Slice(ownerIndex, owner.Span[ownerIndex] >> 16); + return new RefInstruction() + { + Operands = words[1..], + OwnerIndex = ownerIndex, + Slice = owner, + Words = words + }; + } + public static RefInstruction ParseRef(Span words) + { + return new RefInstruction() + { + Operands = words[1..], + Words = words, + }; + } + + + public int? GetResultId() + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResult) + return o.Words[0]; + return null; + } + public void SetResultId(int? value) + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResult) + o.Words[0] = value ?? -1; + } + public int? GetResultType() + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResultType) + return o.Words[0]; + return null; + } + public void SetResultType(int? value) + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResultType) + o.Words[0] = value ?? -1; + } + + public void OffsetIds(int offset) + { + foreach (var o in this) + { + if (o.Kind == OperandKind.IdRef) + o.Words[0] += offset; + else if (o.Kind == OperandKind.IdResult) + o.Words[0] += offset; + else if (o.Kind == OperandKind.IdResultType) + o.Words[0] += offset; + else if (o.Kind == OperandKind.PairIdRefLiteralInteger) + o.Words[0] += offset; + else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) + o.Words[1] += offset; + else if (o.Kind == OperandKind.PairIdRefIdRef) + { + o.Words[0] += offset; + o.Words[1] += offset; + } + } + } + + + + + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append(OpCode).Append(' '); + foreach (var o in this) + { + builder.Append(o.ToString()).Append(' '); + } + return builder.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs new file mode 100644 index 0000000000..b8f8e6d7f3 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -0,0 +1,79 @@ +using System.Runtime.CompilerServices; + +namespace Stride.Shaders.Spirv.Core; + +/// +/// Spirv operand representation, used for parsing spirv. +/// +public ref struct SpvOperand +{ + public OperandKind Kind { get; init; } + public OperandQuantifier Quantifier { get; init; } + public Span Words { get; init; } + public int Offset { get; init; } + + public SpvOperand(OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0) + { + Kind = kind; + Quantifier = quantifier; + Words = words; + Offset = idRefOffset; + } + + public void ReplaceIdResult(int replacement) + { + if(Kind == OperandKind.IdResult && replacement > 0) + Words[0] = replacement; + } + public T ToEnum() where T : Enum + { + return Unsafe.As(ref Words[0]); + } + public T To() where T : struct, IFromSpirv + { + if (Kind == OperandKind.IdRef && typeof(T) == typeof(IdRef)) + { + var id = new IdRef(Words[0] + Offset); + var result = Unsafe.As(ref id); + return result; + } + return T.From(Words); + } + + public override string ToString() + { + return Kind switch + { + OperandKind.LiteralString => To().Value, + OperandKind.IdRef => $"%{Words[0] + Offset}", + OperandKind.IdResultType => $"%{Words[0] + Offset}", + OperandKind.PairLiteralIntegerIdRef => $"{Words[0]} %{Words[0] + Offset}", + OperandKind.MemoryAccess => $"{ToEnum()}", + OperandKind.MemoryModel => $"{ToEnum()}", + OperandKind.MemorySemantics => $"{ToEnum()}", + OperandKind.AccessQualifier => $"{ToEnum()}", + OperandKind.AddressingModel => $"{ToEnum()}", + OperandKind.BuiltIn => $"{ToEnum()}", + OperandKind.Capability => $"{ToEnum()}", + OperandKind.Decoration => $"{ToEnum()}", + OperandKind.Dim => $"{ToEnum()}", + OperandKind.ExecutionMode => $"{ToEnum()}", + OperandKind.ExecutionModel => $"{ToEnum()}", + OperandKind.FPFastMathMode => $"{ToEnum()}", + OperandKind.FPRoundingMode => $"{ToEnum()}", + OperandKind.FragmentShadingRate => $"{ToEnum()}", + OperandKind.FunctionControl => $"{ToEnum()}", + OperandKind.FunctionParameterAttribute => $"{ToEnum()}", + OperandKind.GroupOperation => $"{ToEnum()}", + OperandKind.ImageChannelDataType => $"{ToEnum()}", + OperandKind.ImageChannelOrder => $"{ToEnum()}", + OperandKind.ImageFormat => $"{ToEnum()}", + OperandKind.ImageOperands => $"{ToEnum()}", + OperandKind.KernelEnqueueFlags => $"{ToEnum()}", + OperandKind.KernelProfilingInfo => $"{ToEnum()}", + OperandKind.LinkageType => $"{ToEnum()}", + OperandKind.None => "", + _ => Words[0].ToString() + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj new file mode 100644 index 0000000000..b8454dc409 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + true + Generated + + + + + + + + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs new file mode 100644 index 0000000000..b6e6ffa6dc --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders.Spirv.Core.Validation; + + +public abstract class ValidationPass +{ + public abstract bool Validate(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs new file mode 100644 index 0000000000..39f15b3260 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs @@ -0,0 +1,12 @@ +namespace Stride.Shaders.Spirv.Core.Validation; + + +public class Validation +{ + public List Passes; + + Validation() + { + Passes = new(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs new file mode 100644 index 0000000000..762b524afd --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs @@ -0,0 +1,174 @@ +// See https://aka.ms/new-console-template for more information +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using static Spv.Specification; + + +Console.WriteLine("Hello, world!"); + + +//var doc = JsonParser.Parse/*("{\"*/hello\" : \"world\"}"); +//Console.WriteLine(doc.RootElement.GetProperty("hello").GetString()); + +static void ParseShader() +{ + Console.WriteLine(Unsafe.SizeOf>()); + + InstructionInfo.GetInfo(SDSLOp.OpCapability); + + var shader = File.ReadAllBytes("../../shader.spv"); + + + SpirvReader.ParseToList(shader, new(8)); + + var x = 0; +} + + +static void CreateShader() +{ + LiteralString sname = "S"; + + var ssize = sname.WordCount; + var array = new byte[] {0,0,0,8}; + + var s = array.AsSpan(); + Span ints = MemoryMarshal.Cast(s); + + // var bound = new Bound(); + var buffer = new WordBuffer(); + // // Capabilities + + buffer.AddOpCapability(Capability.Shader); + var extInstImport = buffer.AddOpExtInstImport("GLSL.std.450"); + buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); + + + // declarations + + Span c = stackalloc IdRef[10]; // This is for use in parameters + + + var t_void = buffer.AddOpTypeVoid(); + + var t_bool = buffer.AddOpTypeBool(); + + var t_func = buffer.AddOpTypeFunction(t_void, Span.Empty); + var t_float = buffer.AddOpTypeFloat(32, null); + var t_uint = buffer.AddOpTypeInt(32, 0); + var t_int = buffer.AddOpTypeInt(32, 1); + var t_float4 = buffer.AddOpTypeVector(t_float, 4); + var t_p_float4_func = buffer.AddOpTypePointer(StorageClass.Function, t_float4); + var constant1 = buffer.AddOpConstant(t_float, 5); + var constant2 = buffer.AddOpConstant(t_float, 2); + var constant3 = buffer.AddOpConstant(t_uint, 5); + var compositeType = buffer.AddOpConstantComposite( + t_float4, + stackalloc IdRef[] { constant1, constant1, constant2, constant1 } + ); + + var t_array = buffer.AddOpTypeArray(t_float4, constant3); + + var t_struct = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_uint, t_array, t_int }); + var t_struct2 = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_struct, t_uint }); + + var t_p_struct2 = buffer.AddOpTypePointer(StorageClass.Uniform, t_struct2); + + var v_struct2 = buffer.AddOpVariable(t_p_struct2, StorageClass.Uniform, null); + + var constant4 = buffer.AddOpConstant(t_int, 1); + + var t_p_uint = buffer.AddOpTypePointer(StorageClass.Uniform, t_uint); + var constant5 = buffer.AddOpConstant(t_uint, 0); + + var t_p_output = buffer.AddOpTypePointer(StorageClass.Output, t_float4); + var v_output = buffer.AddOpVariable(t_p_output, StorageClass.Output, null); + + var t_p_input = buffer.AddOpTypePointer(StorageClass.Input, t_float4); + var v_input = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); + + var constant6 = buffer.AddOpConstant(t_int, 0); + var constant7 = buffer.AddOpConstant(t_int, 2); + var t_p_float4_unif = buffer.AddOpTypePointer(StorageClass.Uniform, t_float4); + + var v_input_2 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); + var t_p_func = buffer.AddOpTypePointer(StorageClass.Function, t_int); + var constant8 = buffer.AddOpConstant(t_int, 4); + var v_input_3 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); + + + + + buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); + buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); + buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); + buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); + buffer.AddOpDecorate(t_struct2, Decoration.Block); + buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); + buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); + + + + + buffer.AddOpName(t_p_func, "main"); + buffer.AddOpName(t_struct, "S"); + buffer.AddOpMemberName(t_struct, 0, "b"); + buffer.AddOpMemberName(t_struct, 1, "v"); + buffer.AddOpMemberName(t_struct, 2, "i"); + + + var main = buffer.AddOpFunction(t_void, FunctionControlMask.MaskNone, t_func); + buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", stackalloc IdRef[] { v_output, v_input, v_input_2, v_input_3 }); + buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); + + buffer.AddOpLabel(); + buffer.AddOpReturn(); + buffer.AddOpFunctionEnd(); + + var main2 = buffer.AddOpFunction(t_void, FunctionControlMask.MaskNone, t_func); + buffer.AddOpEntryPoint(ExecutionModel.Vertex, main, "VSMain", stackalloc IdRef[] { v_output, v_input, v_input_2, v_input_3 }); + + var sorted = new SortedWordBuffer(buffer); + + Console.WriteLine(Disassembler.Disassemble(sorted)); + + //var list = new List(buffer.Count); + //foreach(var e in buffer) + // list.Add(e); + + //var bytes = buffer.GenerateSpirv(); + + //File.WriteAllBytes("C:\\Users\\kafia\\source\\repos\\Stride.Shaders.Spirv\\shader.spv", bytes); ; + + var x = 0; +} + + +static void ParseWorking() +{ + // var path = @"C:\Users\youness_kafia\Documents\dotnetProjs\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; + var path = @"C:\Users\kafia\source\repos\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; + + var bytes = File.ReadAllBytes(path); + + var buffer = WordBuffer.Parse(bytes); + var extInst = buffer[1]; + foreach(var o in extInst) + { + if(o.Kind == OperandKind.LiteralString) + { + Console.WriteLine(o.To().Value); + } + } + var tmp = 0; +} + +CreateShader(); + +//ParseWorking(); diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj new file mode 100644 index 0000000000..ce4b9ceabc --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net8.0 + enable + enable + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json new file mode 100644 index 0000000000..4cba4b6793 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -0,0 +1,212 @@ +{ + "instructions": [ + { + "opname": "OpSDSLMixinName", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLMixinEnd", + "class": "Miscellaneous" + }, + { + "opname": "OpSDSLMixinOffset", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralInteger", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLMixinInherit", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLCompose", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixin" + }, + { + "kind": "LiteralString", + "name": "name" + } + ] + }, + { + "opname": "OpSDSLStage", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "stagedElement" + } + ] + }, + { + "opname": "OpSDSLImportFunction", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString", + "name": "functionName" + }, + { + "kind": "LiteralString", + "name": "mixinName" + }, + { + "kind": "LiteralInteger", + "name": "id" + }, + { + "kind": "LiteralInteger", + "name": "typeId" + } + ] + }, + { + "opname": "OpSDSLImportVariable", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString", + "name": "variableName" + }, + { + "kind": "LiteralString", + "name": "mixinName" + }, + { + "kind": "LiteralInteger", + "name": "id" + } + ] + }, + { + "opname": "OpSDSLImportIdRef", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString", + "name": "mixinName" + }, + { + "kind": "LiteralInteger", + "name": "id" + } + ] + }, + { + "opname": "OpSDSLMixinVariable", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "IdRef", + "name": "mixinId" + }, + { + "kind": "IdRef", + "name": "variableId" + } + ] + }, + { + "opname": "OpSDSLVariable", + "class": "Memory", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { "kind": "StorageClass" }, + { + "kind": "LiteralString", + "name": "name" + }, + { + "kind": "IdRef", + "quantifier": "?", + "name": "'Initializer'" + } + ] + }, + { + "opname": "OpSDSLFunctionParameter", + "class": "Function", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { + "kind": "LiteralString", + "name": "name" + } + ] + }, + { + "opname": "OpSDSLIOVariable", + "class": "Memory", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { "kind": "StorageClass" }, + { "kind": "ExecutionModel" }, + { + "kind": "LiteralString", + "name": "name" + }, + { + "kind": "LiteralString", + "name": "semantic" + }, + { + "kind": "IdRef", + "quantifier": "?", + "name": "'Initializer'" + } + ] + }, + { + "opname": "OpSDSLFunction", + "class": "Function", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { "kind": "FunctionControl" }, + { + "kind": "IdRef", + "name": "'Function Type'" + }, + { + "kind": "LiteralString", + "name": "functionName" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs new file mode 100644 index 0000000000..4396a19af2 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; + +namespace Stride.Shaders.Spirv.Generators; + + +public static class SpirvGeneratorExtensions +{ + public static SourceText ToSourceText(this StringBuilder builder) + { + return SourceText.From( + SyntaxFactory + .ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ); + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs new file mode 100644 index 0000000000..925bb3f46a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -0,0 +1,162 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; +using System.Runtime.InteropServices.ComTypes; + +namespace Stride.Shaders.Spirv.Generators +{ + public partial class SPVGenerator + { + + + public void CreateInfo(IncrementalGeneratorInitializationContext context) + { + + GenerateKinds(context); + + var code = new StringBuilder(); + + code + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public partial class InstructionInfo") + .AppendLine("{") + + .AppendLine("static InstructionInfo()") + .AppendLine("{") + ; + + + foreach (var instruction in spirvCore.RootElement.GetProperty("instructions").EnumerateArray()) + { + GenerateInfo(instruction, code); + } + foreach (var instruction in spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray()) + { + GenerateInfo(instruction, code); + } + code + .AppendLine("Instance.InitOrder();") + + .AppendLine("}") + + .AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); + } + + private void GenerateKinds(IncrementalGeneratorInitializationContext context) + { + var code = new StringBuilder() + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("\n\n") + .AppendLine("public enum OperandKind") + .AppendLine("{") + + .AppendLine("None = 0,"); + var kinds = spirvCore.RootElement.GetProperty("operand_kinds").EnumerateArray().Select(x => x.GetProperty("kind").GetString()); + foreach (var kind in kinds) + { + code.Append(kind).AppendLine(","); + } + code.AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); + + } + + public void GenerateInfo(JsonElement op, StringBuilder code) + { + var opname = op.GetProperty("opname").GetString(); + var spvClass = op.GetProperty("class").GetString(); + if (opname == "OpExtInst") + { + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); + } + else if (op.TryGetProperty("operands", out var operands)) + { + foreach (var operand in operands.EnumerateArray()) + { + var hasKind = operand.TryGetProperty("kind", out var kindJson); + var hasQuant = operand.TryGetProperty("quantifier", out var quantifierJson); + var hasName = operand.TryGetProperty("name", out var nameJson); + + if (hasKind) + { + var kind = kindJson.GetString(); + if (!hasQuant) + { + code + .Append("Instance.Register(SDSLOp.") + .Append(opname) + .Append(", OperandKind.") + .Append(kindJson.GetString()) + .Append(", OperandQuantifier.One, ") + .Append(!hasName ? $"\"{ConvertKindToName(kindJson.GetString())}\"" : $"\"{ConvertOperandName(nameJson.GetString())}\"") + .Append($", \"{spvClass}\"") + .AppendLine(");"); + } + else + { + var quant = quantifierJson.GetString(); + code + .Append("Instance.Register(SDSLOp.") + .Append(opname) + .Append(", OperandKind.") + .Append(kindJson.GetString()) + .Append(", OperandQuantifier.") + .Append(ConvertQuantifier(quantifierJson.GetString())) + .Append(", ") + .Append(!hasName ? $"\"{ConvertNameQuantToName(kind, quant)}\"" : $"\"{ConvertNameQuantToName(nameJson.GetString(), quant)}\"") + .Append($", \"{spvClass}\"") + .AppendLine(");"); + } + } + } + } + else + { + code.Append("Instance.Register(SDSLOp.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); + } + } + + public static string ConvertNameQuantToName(string name, string quant) + { + return (name, quant) switch + { + (_, "*") => "values", + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + _ => name.Replace("'", "").ToLowerInvariant() + }; + } + + public static string ConvertQuantifier(string quant) + { + if (quant == "*") + return "ZeroOrMore"; + else if (quant == "?") + return "ZeroOrOne"; + else return "One"; + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs new file mode 100644 index 0000000000..d3bf21a078 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs @@ -0,0 +1,193 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; + +namespace Stride.Shaders.Spirv.Generators +{ + + public static class ListExtensions + { + public static void AddUnique(this List list, string name) + { + if (list.Contains(name)) + list.Add(name + list.Where(x => x.StartsWith(name)).Count()); + else + list.Add(name); + } + } + + public partial class SPVGenerator + { + + + public static List ConvertOperandsToParameters(JsonElement op) + { + var opname = op.GetProperty("opname").GetString(); + var operands = op.GetProperty("operands").EnumerateArray(); + List parameters = new(); + foreach (var e in operands) + { + var kind = e.GetProperty("kind").GetString(); + var realKind = ConvertKind(kind); + if (e.TryGetProperty("quantifier", out var quant)) + { + if (e.TryGetProperty("name", out var name)) + { + if (quant.GetString() == "?") + parameters.AddUnique(realKind + "? " + ConvertOperandName(name.GetString())); + else if (quant.GetString() == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } + else + { + if (quant.GetString() == "?") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else if (quant.GetString() == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } + } + else + { + if (e.TryGetProperty("name", out var name)) + parameters.AddUnique(realKind + " " + ConvertOperandName(name.GetString())); + else if(kind == "IdResult" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else if (kind == "IdResultType" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else + parameters.AddUnique(realKind + " " + ConvertKindToName(kind)); + } + } + if(parameters.Any(x => x.Contains("resultType")) && parameters.Any(x => x.Contains("resultId"))) + { + var resultType = parameters[0]; + var resultId = parameters[1]; + parameters[0] = resultId; + parameters[1] = resultType; + } + return parameters; + } + + public static List ConvertOperandsToParameterNames(JsonElement op) + { + var opname = op.GetProperty("opname").GetString(); + var operands = op.GetProperty("operands").EnumerateArray(); + List parameters = new(op.GetProperty("operands").GetArrayLength()); + foreach (var e in operands) + { + var kind = e.GetProperty("kind").GetString(); + var realKind = ConvertKind(kind); + if (e.TryGetProperty("quantifier", out var quant)) + { + if (e.TryGetProperty("name", out var name)) + { + if (quant.GetString() == "?") + parameters.AddUnique(ConvertOperandName(name.GetString())); + else if (quant.GetString() == "*") + parameters.AddUnique("values"); + } + else + { + if (quant.GetString() == "?") + parameters.AddUnique(ConvertKindToName(kind)); + else if (quant.GetString() == "*") + parameters.AddUnique("values"); + } + } + else + { + if (e.TryGetProperty("name", out var name)) + parameters.AddUnique(ConvertOperandName(name.GetString())); + else + parameters.AddUnique(ConvertKindToName(kind)); + } + } + return parameters; + } + + public static string ConvertKind(string kind) + { + return kind switch + { + "LiteralInteger" => "LiteralInteger", + "LiteralFloat" => "LiteralFloat", + "LiteralString" => "LiteralString", + "ImageOperands" => "ImageOperandsMask", + "RawAccessChainOperands" => "RawAccessChainOperandsMask", + "FunctionControl" => "FunctionControlMask", + "MemoryAccess" => "MemoryAccessMask", + "LoopControl" => "LoopControlMask", + "SelectionControl" => "SelectionControlMask", + "LiteralExtInstInteger" => "LiteralInteger", + "LiteralSpecConstantOpInteger" => "Op", + "CooperativeMatrixOperands" => "CooperativeMatrixOperandsMask", + _ => kind + }; + } + + public static string ConvertKindToName(string kind) + { + return kind switch + { + "IdRef" => "id", + "IdResult" => "resultId", + "IdResultType" => "resultType", + _ => kind.ToLower() + }; + } + + public static string ConvertOperandName(string input, string quant = null) + { + if (string.IsNullOrEmpty(input)) + { + return string.Empty; + } + var result = ""; + bool firstLetterHit = false; + for (int i = 0; i < input.Length; i++) + { + + if (char.IsLetterOrDigit(input[i]) || input[i] == '_') + { + if (!firstLetterHit) + { + firstLetterHit = true; + result += char.ToLowerInvariant(input[i]); + } + else + result += input[i]; + } + + } + return (result, quant) switch + { + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + ("IdResult", _) => "resultId", + ("IdResultType", _) => "resultType", + ("IdRef", "*") => "id", + ("IdRef", "?") => "id", + ("IdRef", null) => "id", + ("LiteralInteger", _) => "", + ("LiteralFloat", _) => "", + ("LiteralString", _) => "", + ("Dim", _) => "", + ("ImageFormat", _) => "", + ("ExecutionMode", _) => "", + ("ExecutionModel", _) => "", + _ => result + }; + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs new file mode 100644 index 0000000000..b6a9e35bae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -0,0 +1,60 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp; + +namespace Stride.Shaders.Spirv.Generators +{ + public partial class SPVGenerator + { + public void CreateSDSLOp(IncrementalGeneratorInitializationContext context) + { + var code = new StringBuilder(); + var nsProvider = context + .SyntaxProvider + .CreateSyntaxProvider( + predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), + transform: (node, _) => (NamespaceDeclarationSyntax)node.Node + ); + context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => + { + var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); + var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue.Value.ToString())); + var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue.Value.ToString())).Max(); + + foreach (var e in spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray().Select(x => x.GetProperty("opname").GetString())) + members.Add(e, ++lastnum); + + code + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + foreach (var e in members) + code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); + code + .AppendLine("}"); + + + ctx.AddSource("SDSLOp.gen.cs", code.ToString()); + }); + + } + public static int ParseInteger(string text) + { + if (text.StartsWith("0x")) + return int.Parse(text.Substring(2), System.Globalization.NumberStyles.HexNumber); + else + return int.Parse(text); + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs new file mode 100644 index 0000000000..021a3def57 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -0,0 +1,237 @@ +using Microsoft.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices.ComTypes; +using System.Text; +using System.Text.Json; + +namespace Stride.Shaders.Spirv.Generators +{ + + [Generator] + public partial class SPVGenerator : IIncrementalGenerator + { + JsonDocument spirvCore; + JsonDocument spirvGlsl; + JsonDocument spirvSDSL; + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + // #if DEBUG + // if (!Debugger.IsAttached) + // Debugger.Launch(); + // #endif + var assembly = typeof(SPVGenerator).GetTypeInfo().Assembly; + string resourceCoreName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("spirv.core.grammar.json")); + + string resourceGlslName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("extinst.glsl.std.450.grammar.json")); + + string resourceSDSLName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("spirv.sdsl.grammar-ext.json")); + + spirvCore = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd()); + spirvGlsl = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd()); + spirvSDSL = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd()); + + CreateInfo(context); + CreateSDSLOp(context); + + var code = new StringBuilder(); + + code + .AppendLine("using static Spv.Specification;") + .AppendLine("namespace Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("") + .AppendLine("public static class WordBufferExtensions") + .AppendLine("{"); + + var instructions = spirvCore.RootElement.GetProperty("instructions").EnumerateArray().ToList(); + var sdslInstructions = spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray().ToList(); + var glslInstruction = spirvGlsl.RootElement.GetProperty("instructions").EnumerateArray().ToList(); + + instructions.ForEach(x => CreateOperation(x, code)); + sdslInstructions.ForEach(x => CreateOperation(x, code)); + glslInstruction.ForEach(x => CreateGlslOperation(x, code)); + + code.AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => { + ctx.AddSource( + "WordBufferExtensions.gen.cs", + code.ToSourceText()); + }); + } + + public void CreateOperation(JsonElement op, StringBuilder code) + { + var opname = op.GetProperty("opname").GetString(); + if (opname == "OpConstant") + { + code + .AppendLine("public static Instruction AddOpConstant(this TBuffer buffer, IdResultType? resultType, TValue value) where TBuffer : IMutSpirvBuffer where TValue : struct, ILiteralNumber") + .AppendLine("{") + + .AppendLine("var resultId = buffer.GetNextId();") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Add(new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]));") + + .AppendLine("}"); + + } + else if (opname == "OpSpecConstant") + { + code + .AppendLine("public static Instruction AddOpSpecConstant(this TBuffer buffer, IdResultType? resultType, TValue value) where TBuffer : IMutSpirvBuffer where TValue : ILiteralNumber") + .AppendLine("{") + + .AppendLine("var resultId = buffer.GetNextId();") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("var mutInstruction = new MutRefInstruction(stackalloc int[wordLength]);") + .AppendLine("mutInstruction.OpCode = SDSLOp.OpSpecConstant;") + .AppendLine("mutInstruction.Add(resultType);") + .AppendLine("mutInstruction.Add(resultId);") + .AppendLine("mutInstruction.Add(value);") + .AppendLine("return buffer.Add(mutInstruction);") + + .AppendLine("}"); + } + else if (opname.StartsWith("OpDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this TBuffer buffer, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) where TBuffer : IMutSpirvBuffer") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add(new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]));") + + .AppendLine("}"); + } + else if (opname.StartsWith("OpMemberDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this TBuffer buffer, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) where TBuffer : IMutSpirvBuffer") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add(new([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]));") + + .AppendLine("}"); + } + + else if (op.TryGetProperty("operands", out var operands)) + { + var parameters = ConvertOperandsToParameters(op); + var parameterNames = ConvertOperandsToParameterNames(op); + var hasResultId = parameterNames.Contains("resultId") && opname != "OpExtInst"; + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + var paramsParameters = parameters.Where(x => x.Contains("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); + + code + .Append("public static Instruction Add") + .Append(opname) + .Append("(this TBuffer buffer") + .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(") where TBuffer : IMutSpirvBuffer") + .AppendLine("{") + ; + if (hasResultId) + { + code.AppendLine("var resultId = buffer.GetNextId();"); + } + code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); + code + .AppendLine($"return buffer.Add(new([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]));") + .AppendLine("}"); + } + else + { + code + .Append("public static Instruction Add") + .Append(opname) + .AppendLine("(this TBuffer buffer) where TBuffer : IMutSpirvBuffer") + .AppendLine("{") + + .AppendLine($"return buffer.Add(new([1 << 16 | (int)SDSLOp.{opname}]));") + + .AppendLine("}"); + } + } + + public void CreateGlslOperation(JsonElement op, StringBuilder code) + { + var opname = op.GetProperty("opname").GetString(); + var opcode = op.GetProperty("opcode").GetInt32(); + + if (op.TryGetProperty("operands", out var operands)) + { + var parameters = ConvertOperandsToParameters(op); + parameters.Add("int set"); + + var parameterNames = ConvertOperandsToParameterNames(op); + parameterNames.Add("set"); + + var hasResultId = parameterNames.Contains("resultId"); + + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + + var paramsParameters = parameters.Where(x => x.Contains("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); + var other = parameterNames.Where(x => x != "resultType" && x != "resultId" && x != "set"); + + + code + .Append("public static Instruction AddGLSL") + .Append(opname) + .Append("(this TBuffer buffer, ") + .Append("IdResultType resultType, ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(") where TBuffer : IMutSpirvBuffer") + .AppendLine("{") + + .AppendLine("var resultId = buffer.GetNextId();") + .Append("Span refs = stackalloc IdRef[]{").Append(string.Join(", ", other)).AppendLine("};") + .AppendLine("if(buffer is MultiBuffer mb)") + + .Append("return mb.AddOpExtInst(") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + + .AppendLine("else if (buffer is WordBuffer wb)") + + .Append("return wb.AddOpExtInst(") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + + .AppendLine("else return Instruction.Empty;") + + .AppendLine("}"); + } + } + + + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj new file mode 100644 index 0000000000..8b313be946 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -0,0 +1,42 @@ + + + + netstandard2.0 + true + 12 + + + + + + + + + + + + + + + + + + + + + + + + + $(GetTargetPathDependsOn);GetDependencyTargetPaths + + + + + + + + + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Composable.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Composable.cs new file mode 100644 index 0000000000..d22213b9d7 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Composable.cs @@ -0,0 +1,14 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv; + +/// +/// A mixin that can be composed with others +/// +/// +/// +public record Composable(string Name, SortedWordBuffer Buffer) +{ + public InstructionEnumerator GetEnumerator() => new(Buffer); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs new file mode 100644 index 0000000000..ad320eb3a8 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs @@ -0,0 +1,33 @@ +using Stride.Shaders.Spirv.PostProcessing; + +namespace Stride.Shaders.Spirv; + +/// +/// Repository for compositable shaders +/// +public class CompositionSourceProvider +{ + internal static CompositionSourceProvider Instance { get; } = new(); + + readonly Dictionary Composables; + + private CompositionSourceProvider() + { + Composables = new(); + } + + public static void CompileAndRegister(string name) + { + var buffer = PostProcessor.Process(name).ToSorted(); + Register(new(name,buffer)); + } + + public static void Register(Composable composable) + { + Instance.Composables.Add(composable.Name, composable); + } + public static Composable Get(string name) + { + return Instance.Composables[name]; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs new file mode 100644 index 0000000000..cdf523b898 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs @@ -0,0 +1,67 @@ +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; + + +namespace Stride.Shaders.Spirv; + +/// +/// Instruction enumerator that goes through many mixins with filters. +/// +public ref struct MixinFilteredInstructionEnumerator +{ + MixinGraph Mixins { get; init; } + + MixinInstructionEnumerator enumerator; + + readonly SDSLOp? filter1; + readonly SDSLOp? filter2; + readonly SDSLOp? filter3; + readonly SDSLOp? filter4; + + public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1) + { + Mixins = mixins; + enumerator = mixins.Instructions.GetEnumerator(); + filter1 = f1; + } + public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2) + { + Mixins = mixins; + enumerator = mixins.Instructions.GetEnumerator(); + filter1 = f1; + filter2 = f2; + } + public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2, SDSLOp f3) + { + Mixins = mixins; + enumerator = mixins.Instructions.GetEnumerator(); + filter1 = f1; + filter2 = f2; + filter2 = f3; + } + public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2, SDSLOp f3, SDSLOp f4) + { + Mixins = mixins; + enumerator = mixins.Instructions.GetEnumerator(); + filter1 = f1; + filter2 = f2; + filter3 = f3; + filter4 = f4; + } + public MixinInstruction Current => enumerator.Current; + public bool MoveNext() + { + while(enumerator.MoveNext()) + { + if( + (filter2 == null && enumerator.Current.OpCode == filter1) + || (filter2 != null && filter3 == null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2) + || (filter3 != null && filter4 == null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2 || enumerator.Current.OpCode == filter3) + || (filter4 != null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2 || enumerator.Current.OpCode == filter3 || enumerator.Current.OpCode == filter4) + ) + return true; + } + return false; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs new file mode 100644 index 0000000000..a05cd47af7 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs @@ -0,0 +1,63 @@ +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; + + +namespace Stride.Shaders.Spirv; + +/// +/// Instruction enumerator that goes through many mixins. +/// +public ref struct MixinInstructionEnumerator +{ + MixinGraph Mixins { get; init; } + + MixinBuffer.InstructionsWrapper.Enumerator lastEnumerator; + int lastMixin; + public int MixinResultId { get; set; } + + bool offsetted; + + public MixinInstructionEnumerator(MixinGraph mixins, bool offsetted) + { + Mixins = mixins; + lastMixin = -1; + MixinResultId = -1; + this.offsetted = offsetted; + } + public MixinInstruction Current => new(Mixins[lastMixin].Name , lastEnumerator.Current); + + public bool MoveNext() + { + var count = Mixins.Count; + if (count == 0) + return false; + else if (lastMixin == -1) + { + lastMixin = 0; + MixinResultId = 1; + lastEnumerator = Mixins[lastMixin].Instructions.GetEnumerator(); + return lastEnumerator.MoveNext(); + } + else + { + while (lastMixin < count) + { + var hadId = lastEnumerator.Current.ResultId != null; + if (lastEnumerator.MoveNext()) + { + MixinResultId += hadId ? 1 : 0; + return true; + } + else + { + lastMixin += 1; + if (lastMixin < count) + lastEnumerator = Mixins[lastMixin].Instructions.GetEnumerator(); + } + } + return false; + } + + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs new file mode 100644 index 0000000000..2f875fadd9 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs @@ -0,0 +1,73 @@ +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv; + +/// +/// Instruction enumerator that goes through many mixins. Instructions are sorted. +/// +public ref struct SortedMixinInstructionEnumerator +{ + + MixinGraph Mixins { get; init; } + + int currentGroup; + int lastMixin; + int lastIndex; + int boundOffset; + + public SortedMixinInstructionEnumerator(MixinGraph mixins) + { + Mixins = mixins; + currentGroup = 0; + lastIndex = -1; + lastMixin = -1; + boundOffset = -1; + } + public readonly Instruction Current => Mixins[lastMixin].Instructions[lastIndex]; + public bool MoveNext() + { + if (Mixins.Count == 0) + return false; + if (lastMixin == -1) + { + lastMixin = 0; + lastIndex = 0; + boundOffset = 0; + return true; + } + else + { + var count = Mixins.Count; + // If the current mixin has no other + while (currentGroup < 14) + { + while (lastMixin < count) + { + var offset = 1; + var instruction = Mixins[lastMixin].Instructions[lastIndex + offset]; + while (lastIndex + offset < count && instruction.IsEmpty) + { + offset += 1; + } + if (!instruction.IsEmpty && InstructionInfo.GetGroupOrder(instruction.AsRef()) == currentGroup) + { + lastIndex += offset; + return true; + } + else + { + boundOffset += Mixins[lastMixin].Bound; + lastMixin += 1; + lastIndex = 0; + } + } + currentGroup += 1; + lastMixin = 0; + boundOffset = 0; + } + return false; + } + + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md new file mode 100644 index 0000000000..39e22d3855 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md @@ -0,0 +1,86 @@ +# Generating CFG in spirv + +given this : + +```glsl +for(int i = 0; i< 4; i++) +{ + + fragColor.x = i; +} +``` + +spirv-cross generates + +``` + +// Creating the variable i +%i = OpVariable %_ptr_Function_int Function +// initializing it with 0 + OpStore %i %int_0 +// We define an unconditional branch that always goes to a specific label. + OpBranch %10 +// Specific label to go back to +%10 = OpLabel +// Declares a structed loop, %12 is the merge block (exit), %13 is the continue + OpLoopMerge %12 %13 None +// An OpBranch should come right after an OpLoopMerge to start the branch + OpBranch %14 +%14 = OpLabel +// Load i and register if i is below 4 +%15 = OpLoad %int %i +%18 = OpSLessThan %bool %15 %int_4 +// This OpBranchConditional goes to either %11(code) or %12 (exit) depending %18 + OpBranchConditional %18 %11 %12 +%11 = OpLabel +// This is the code inside the block +%23 = OpLoad %int %i +%24 = OpConvertSToF %float %23 +%28 = OpAccessChain %_ptr_Output_float %fragColor %uint_0 + OpStore %28 %24 +// End of the code inside the block, now go back to %13 to add 1 to i + OpBranch %13 +%13 = OpLabel +%29 = OpLoad %int %i +%31 = OpIAdd %int %29 %int_1 + OpStore %i %31 +// Now go back to %10 to start the loop again + OpBranch %10 +%12 = OpLabel +``` + +While loops are surprisingly simpler. + +``` +int i = 0; +while(i < 4) +{ + fragColor.x = i; + i += 1; +} +``` + +``` +%i = OpVariable %_ptr_Function_int Function + OpStore %i %int_0 + OpBranch %10 +%10 = OpLabel + OpLoopMerge %12 %13 None + OpBranch %14 +%14 = OpLabel +%15 = OpLoad %int %i +%18 = OpSLessThan %bool %15 %int_4 + OpBranchConditional %18 %11 %12 +%11 = OpLabel +%23 = OpLoad %int %i +%24 = OpConvertSToF %float %23 +%28 = OpAccessChain %_ptr_Output_float %fragColor %uint_0 + OpStore %28 %24 +%30 = OpLoad %int %i +%31 = OpIAdd %int %30 %int_1 + OpStore %i %31 + OpBranch %13 +%13 = OpLabel + OpBranch %10 +%12 = OpLabel +``` \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs new file mode 100644 index 0000000000..467f93462b --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs @@ -0,0 +1,273 @@ +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Numerics; + +namespace Stride.Shaders.Spirv; + +public partial class Mixer +{ + + public MixinInstruction FindType(IdRef typeId) + { + foreach(var i in Buffer.Declarations) + { + if (i.OpCode == SDSLOp.OpTypePointer && i.ResultId == typeId) + { + IdRef toFind = i.Words.Span[1]; + foreach (var j in Buffer.Declarations) + { + if (j.ResultId == toFind) + { + var found = j.OpCode switch + { + var tmp when InstructionInfo.OpTypes.Contains(tmp) => true, + _ => false + }; + if (found) + return j; + } + } + } + else if (InstructionInfo.OpTypes.Contains(i.OpCode) && i.ResultId == typeId) + return i; + } + return Instruction.Empty; + } + + public MixinInstruction CreateTypePointer(ReadOnlyMemory type, Spv.Specification.StorageClass storage) + { + var t = GetOrCreateBaseType(type[..^1]); + return Buffer.AddOpTypePointer(storage, t.ResultId ?? -1); + } + public MixinInstruction GetOrCreateBaseType() + where T : struct + { + var v = default(T); + return v switch + { + sbyte t => GetOrCreateBaseType("sbyte".AsMemory()), + byte t => GetOrCreateBaseType("byte".AsMemory()), + short t => GetOrCreateBaseType("short".AsMemory()), + ushort t => GetOrCreateBaseType("ushort".AsMemory()), + int t => GetOrCreateBaseType("int".AsMemory()), + uint t => GetOrCreateBaseType("uint".AsMemory()), + long t => GetOrCreateBaseType("long".AsMemory()), + ulong t => GetOrCreateBaseType("ulong".AsMemory()), + System.Half t => GetOrCreateBaseType("half".AsMemory()), + float t => GetOrCreateBaseType("float".AsMemory()), + double t => GetOrCreateBaseType("double".AsMemory()), + Vector2 t => GetOrCreateBaseType("float2".AsMemory()), + Vector3 t => GetOrCreateBaseType("float3".AsMemory()), + Vector4 t => GetOrCreateBaseType("float4".AsMemory()), + Matrix4x4 t => GetOrCreateBaseType("float4x4".AsMemory()), + Matrix3x2 t => GetOrCreateBaseType("float3x2".AsMemory()), + _ => throw new NotImplementedException() + }; + } + public MixinInstruction GetOrCreateBaseType(ReadOnlyMemory type) + { + var matched = MatchesBaseType(type); + if (matched is null) return Instruction.Empty; + else + { + if (matched.Value.IsScalar) + { + var found = FindScalarType(type); + if (!found.IsEmpty) + return found; + else return matched.Value.BaseType.Span switch + { + "void" => Buffer.AddOpTypeVoid(), + "sbyte" => Buffer.AddOpTypeInt(8, 1), + "byte" => Buffer.AddOpTypeInt(8, 0), + "short" => Buffer.AddOpTypeInt(16, 1), + "ushort" => Buffer.AddOpTypeInt(16, 0), + "int" => Buffer.AddOpTypeInt(32, 1), + "uint" => Buffer.AddOpTypeInt(32, 0), + "long" => Buffer.AddOpTypeInt(64, 1), + "ulong" => Buffer.AddOpTypeInt(64, 0), + "half" => Buffer.AddOpTypeFloat(16, null), + "float" => Buffer.AddOpTypeFloat(32, null), + "double" => Buffer.AddOpTypeFloat(64, null), + _ => throw new NotImplementedException() + }; + } + else if (matched.Value.IsVector) + { + var found = FindVectorType(matched.Value); + if (!found.IsEmpty) + return found; + else + { + var b = GetOrCreateBaseType(matched.Value.BaseType); + if(b.MixinName == "") + return Buffer.AddOpTypeVector(b.ResultId ?? -1, new(matched?.Row)); + else + { + var imported = Buffer.AddOpSDSLImportIdRef(b.MixinName, b.ResultId ?? -1); + return Buffer.AddOpTypeVector(imported.ResultId ?? -1, new(matched?.Row)); + } + } + } + else if (matched.Value.IsMatrix) + { + var found = FindMatrixType(matched.Value); + if (!found.IsEmpty) + return found; + else + { + var b = GetOrCreateBaseType($"{matched.Value.BaseType.Span}{matched?.Row}".AsMemory()); + if (b.MixinName == "") + return Buffer.AddOpTypeMatrix(b.ResultId ?? -1, new(matched?.Row)); + else + { + var imported = Buffer.AddOpSDSLImportIdRef(b.MixinName, b.ResultId ?? -1); + return Buffer.AddOpTypeMatrix(imported.ResultId ?? -1, new(matched?.Row)); + } + } + } + else + throw new NotImplementedException(); + + } + } + + internal MixinInstruction FindMatrixType(in TypeMatch type) + { + var baseType = FindVectorType(type with {Col = null}); + if(baseType.IsEmpty) + return Instruction.Empty; + + // var enumerator = new MixinFilteredInstructionEnumerator(mixins, SDSLOp.OpTypeMatrix); + + // while (enumerator.MoveNext()) + // { + // if (enumerator.Current.Words[2] == baseType.Words[2] && enumerator.Current.Words[3] == type.Col) + // return enumerator.Current; + // } + + var self = new FilteredEnumerator(Buffer.Declarations, SDSLOp.OpTypeMatrix); + + while (self.MoveNext()) + { + if(self.Current.Words.Span[2] == baseType.Words[2] && self.Current.Words.Span[3] == type.Col) + return self.Current; + } + return Instruction.Empty; + } + internal MixinInstruction FindVectorType(in TypeMatch type) + { + var baseType = FindScalarType(type.BaseType); + if(baseType.IsEmpty) + return baseType; + + // var enumerator = new MixinFilteredInstructionEnumerator(mixins, SDSLOp.OpTypeVector); + + // while (enumerator.MoveNext()) + // { + // if (enumerator.Current.Words[2] == baseType.Words[2] && enumerator.Current.Words[3] == type.Row) + // return enumerator.Current; + // } + + var self = new FilteredEnumerator(Buffer.Declarations, SDSLOp.OpTypeVector); + + while (self.MoveNext()) + { + if (self.Current.Words.Span[2] == baseType.Words[2] && self.Current.Words.Span[3] == type.Row) + return self.Current; + } + return Instruction.Empty; + } + + internal MixinInstruction FindScalarType(ReadOnlyMemory type) + { + (SDSLOp Filter, int? Width, int? Sign) filterData = type.Span switch + { + "void" => (SDSLOp.OpTypeVoid, null, null), + "bool" => (SDSLOp.OpTypeBool, null, null), + "byte" => (SDSLOp.OpTypeInt, 8, 0), + "sbyte" => (SDSLOp.OpTypeInt, 8, 1), + "ushort" => (SDSLOp.OpTypeInt, 16, 0), + "short" => (SDSLOp.OpTypeInt, 16, 1), + "int" => (SDSLOp.OpTypeInt, 32, 1), + "uint" => (SDSLOp.OpTypeInt, 32, 0), + "ulong" => (SDSLOp.OpTypeInt, 64, 0), + "long" => (SDSLOp.OpTypeInt, 64, 1), + "half" => (SDSLOp.OpTypeFloat, 16, null), + "float" => (SDSLOp.OpTypeFloat, 32, null), + "double" => (SDSLOp.OpTypeFloat, 64, null), + _ => throw new Exception("Type not known") + }; + var enumerator = new MixinFilteredInstructionEnumerator(Mixins, filterData.Filter); + + // while (enumerator.MoveNext()) + // { + // if ( + // (filterData.Width is null) + // || (filterData.Width is not null && filterData.Sign is null && enumerator.Current.Words[2] == filterData.Width) + // || (filterData.Width is not null && filterData.Sign is not null && enumerator.Current.Words[2] == filterData.Width && enumerator.Current.Words[3] == filterData.Sign) + // ) + // return enumerator.Current; + // } + var self = new FilteredEnumerator(Buffer.Declarations, filterData.Filter); + + while (self.MoveNext()) + { + if ( + (filterData.Width is null) + || (filterData.Width is not null && filterData.Sign is null && self.Current.Words.Span[2] == filterData.Width) + || (filterData.Width is not null && filterData.Sign is not null && self.Current.Words.Span[2] == filterData.Width && self.Current.Words.Span[3] == filterData.Sign) + ) + return self.Current; + } + return Instruction.Empty; + } + + static string[] types = { "bool", "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "half", "float", "double" }; + + private static TypeMatch? MatchesBaseType(ReadOnlyMemory type) + { + if (type.Span.StartsWith("void") && type.Span.EndsWith("void")) + return new(type, null, null); + foreach (var t in types) + { + var span = type; + bool isPtr = false; + if (span.Span.EndsWith("*")) + { + span = type[..^1]; + isPtr = true; + } + if (span.Span.StartsWith(t) && span.Span.EndsWith(t)) + { + return new(span, null, null, isPtr); + } + else if (span.Span.StartsWith(t)) + { + if (span.Length - t.Length == 1 && char.IsDigit(span.Span[^1])) + { + var num = span.Span[^1] - '0'; + if (num > 1 && num < 5) + return new(t.AsMemory(), num, null); + } + else if (span.Length - t.Length == 3 && char.IsDigit(span.Span[^1]) && char.IsDigit(span.Span[^3]) && span.Span[^2] == 'x') + { + var num1 = span.Span[^3] - '0'; + var num2 = span.Span[^1] - '0'; + if (num1 > 1 && num1 < 5 && num2 > 1 && num2 < 5) + return new(t.AsMemory(), num1, num2, isPtr); + } + } + } + return null; + } +} +internal record struct TypeMatch(ReadOnlyMemory BaseType, int? Row, int? Col, bool IsPointer = false) +{ + public bool IsVoid => BaseType.Span.StartsWith("void") && BaseType.Span.EndsWith("void"); + public bool IsMatrix => Row != null && Col != null; + public bool IsVector => Row != null && Col == null; + public bool IsScalar => Row == null && Col == null; +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs new file mode 100644 index 0000000000..ad7ac2b05c --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs @@ -0,0 +1,42 @@ +using System.ComponentModel.Design.Serialization; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv; + +public partial class Mixer +{ + public Mixer ComposeWith(string mixinName, string variableName) + { + // Foreach instruction in mixin to compose + // Insert the instruction + // If the instruction is an OpName for variables, create a new OpName instruction with the same name prefixed by variableName + // Make sure to offset the Ids. + var composable = CompositionSourceProvider.Get(mixinName); + var offset = Buffer.Bound; + Span nameBuffer = stackalloc int[200]; + foreach (var i in composable) + { + if(i.OpCode == SDSLOp.OpName) + { + var name = i.GetOperand("name") ?? throw new Exception("Name is null"); + var newName = $"{variableName}_{name}"; + var buff = nameBuffer[0..(1 + 1 + name.WordCount)]; + buff.Clear(); + var newInstruction = new MutRefInstruction(buff); + newInstruction.Add(i.ResultId ?? -1); + newInstruction.Add(newName); + + Buffer.Add(newInstruction); + } + else + { + + } + } + throw new NotImplementedException(); + return this; + } + + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs new file mode 100644 index 0000000000..22080f7606 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs @@ -0,0 +1,44 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public partial class Mixer +{ + public struct EntryPoint + { + public Mixer mixer; + public ExecutionModel ExecutionModel { get; } + public string Name { get; } + + Instruction function; + public EntryPoint(Mixer mixer, ExecutionModel executionModel, string name) + { + this.mixer = mixer; + ExecutionModel = executionModel; + Name = name; + } + + + + public FunctionBuilder FunctionStart() + { + return new(mixer,this); + } + + public Mixer FinishEntryPoint() + { + mixer.Buffer.AddOpEntryPoint(ExecutionModel, function, Name, Span.Empty); + mixer.Buffer.AddOpExecutionMode( + function, + ExecutionMode.OriginLowerLeft + ); + mixer.Buffer.AddOpCapability(Capability.Shader); + mixer.Buffer.AddOpExtInstImport("GLSL.std.450"); + mixer.Buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); + return mixer; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs new file mode 100644 index 0000000000..05725a34f7 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs @@ -0,0 +1,26 @@ +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv; + + +public partial class Mixer +{ + public ref struct Inheritance + { + Mixer mixer; + public Inheritance(Mixer mixer) + { + this.mixer = mixer; + } + + public Inheritance Inherit(string name) + { + mixer.Inherit(name); + return this; + } + public Mixer FinishInherit() + { + return mixer; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs new file mode 100644 index 0000000000..5012f5512a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs @@ -0,0 +1,757 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Mixer; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + +public ref struct FunctionCallerParameters +{ + public FunctionBuilder Builder {get; private set;} + readonly Mixer mixer => Builder.mixer; + Span inner; + public Span ParameterVariables => inner[..Length]; + public int Length { get; private set; } + + public FunctionCallerParameters(FunctionBuilder builder, Span array) + { + if (array.Length != 16) + throw new ArgumentException("Length must be 16"); + Builder = builder; + inner = array; + Length = 0; + } + + public FunctionCallerParameters With(Instruction value) + { + //var p = mixer.Buffer.AddOpVariable(mixer.FindType(value.ResultType ?? -1), StorageClass.Function, null); + //mixer.Buffer.AddOpStore(p, value, null); + inner[Length] = value.ResultId ?? -1; + Length += 1; + return this; + } +} + +public delegate FunctionCallerParameters CreateCallFunctionParameter(FunctionCallerParameters p); + +public ref partial struct FunctionBuilder +{ + public Instruction Call(string functionName, CreateCallFunctionParameter fp) + { + var parameters = new FunctionCallerParameters(this, stackalloc IdRef[16]); + parameters = fp.Invoke(parameters); + var function = mixer.Buffer.Functions[functionName][0]; + return mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, parameters.ParameterVariables); + } + + public FunctionBuilder CallFunction(string functionName, CreateCallFunctionParameter fp) + { + var parameters = new FunctionCallerParameters(this, stackalloc IdRef[16]); + parameters = fp.Invoke(parameters); + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, parameters.ParameterVariables); + return this; + } + + + public FunctionBuilder CallFunction(string functionName) + { + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, Span.Empty); + return this; + } + public FunctionBuilder CallFunction(string functionName, Instruction param1) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[1] { var1 }); + return this; + } + public FunctionBuilder CallFunction(string functionName, Instruction param1, Instruction param2) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { var1, var2 }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11 + }); + return this; + } + + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11, + Instruction param12 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param12, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11, + var12 + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11, + Instruction param12, + Instruction param13 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param12, null); + var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param13, null); + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11, + var12, + var13, + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11, + Instruction param12, + Instruction param13, + Instruction param14 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param12, null); + var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param13, null); + var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param14, null); + + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11, + var12, + var13, + var14, + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11, + Instruction param12, + Instruction param13, + Instruction param14, + Instruction param15 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param12, null); + var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param13, null); + var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param14, null); + var var15 = mixer.Buffer.AddOpVariable(mixer.FindType(param15), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param15, null); + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11, + var12, + var13, + var14, + var15, + }); + return this; + } + public FunctionBuilder CallFunction( + string functionName, + Instruction param1, + Instruction param2, + Instruction param3, + Instruction param4, + Instruction param5, + Instruction param6, + Instruction param7, + Instruction param8, + Instruction param9, + Instruction param10, + Instruction param11, + Instruction param12, + Instruction param13, + Instruction param14, + Instruction param15, + Instruction param16 + ) + { + var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param1, null); + var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param2, null); + var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param3, null); + var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param4, null); + var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param5, null); + var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param6, null); + var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param7, null); + var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param8, null); + var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param9, null); + var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param10, null); + var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param11, null); + var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param12, null); + var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param13, null); + var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param14, null); + var var15 = mixer.Buffer.AddOpVariable(mixer.FindType(param15), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param15, null); + var var16 = mixer.Buffer.AddOpVariable(mixer.FindType(param16), StorageClass.Function, null); + mixer.Buffer.AddOpStore(var1, param16, null); + + + var function = mixer.Buffer.Functions[functionName][0]; + mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { + var1, + var2, + var3, + var4, + var5, + var6, + var7, + var8, + var9, + var10, + var11, + var12, + var13, + var14, + var15, + var16, + }); + return this; + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs new file mode 100644 index 0000000000..645521cb6b --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs @@ -0,0 +1,50 @@ +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; +using System.Runtime.Serialization.Formatters; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public delegate void ConditionBody(FunctionBuilder function); +public delegate Instruction ConditionCheck(FunctionBuilder function); + +public ref struct ConditionalBuilder +{ + Mixer mixer; + FunctionBuilder builder; + + public MutRefInstruction lastLabel; + + public void If(ConditionCheck condition, ConditionBody cf) + { + // TODO: prepare condition + cf.Invoke(builder); + } + public void ElseIf(ConditionCheck condition, ConditionBody cf) + { + // TODO: replace last + // TODO: prepare condition + cf.Invoke(builder); + } + public void Else(ConditionCheck condition, ConditionBody cf) + { + // TODO: replace last + // TODO: prepare condition + cf.Invoke(builder); + } + + public void Finish() + { + //TODO : Finish conditions + } +} + +public ref partial struct FunctionBuilder +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs new file mode 100644 index 0000000000..6fe09d53b0 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs @@ -0,0 +1,447 @@ +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; +using System.Runtime.Serialization.Formatters; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public ref partial struct FunctionBuilder +{ + + private IdRef? glslSet = null; + + public void EnsureGlslSet() + { + var exists = false; + if(glslSet != null && glslSet.Value > 0) + return; + else if(glslSet == null) + { + foreach (var i in mixer.Buffer.Declarations.UnorderedInstructions) + { + if (i.OpCode == SDSLOp.OpExtInstImport) + { + var name = i.GetOperand("name") ?? ""; + if (name.Value == "GLSL.std.450") + exists = true; + } + } + if (!exists) + { + glslSet = mixer.Buffer.AddOpExtInstImport("GLSL.std.450"); + } + } + } + + public Instruction Round(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLRound(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction RoundEven(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLRoundEven(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Trunc(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLTrunc(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FAbs(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFAbs(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction SAbs(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSAbs(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FSign(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFSign(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction SSign(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSSign(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Floor(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFloor(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Ceil(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLCeil(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Fract(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFract(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Radians(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLRadians(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Degrees(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLDegrees(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Sin(Instruction x) + { + EnsureGlslSet(); + var result = mixer.Buffer.AddGLSLSin(x.ResultType ?? -1, x, glslSet ?? -1); + return result; + } + public Instruction Cos(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLCos(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Tan(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLTan(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Asin(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAsin(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Acos(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAcos(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Atan(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAtan(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Sinh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSinh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Cosh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLCosh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Tanh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLTanh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Asinh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAsinh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Acosh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAcosh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Atanh(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAtanh(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Atan2(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLAtan2(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction Pow(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPow(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction Exp(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLExp(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Log(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLLog(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Exp2(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLExp2(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Log2(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLLog2(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Sqrt(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSqrt(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction InverseSqrt(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLInverseSqrt(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Determinant(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLDeterminant(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction MatrixInverse(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLMatrixInverse(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Modf(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLModf(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction ModfStruct(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLModfStruct(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FMin(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFMin(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction UMin(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUMin(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction SMin(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSMin(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction FMax(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFMax(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction UMax(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUMax(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction SMax(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSMax(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction FClamp(Instruction x, Instruction minVal, Instruction maxVal) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); + } + public Instruction UClamp(Instruction x, Instruction minVal, Instruction maxVal) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); + } + public Instruction SClamp(Instruction x, Instruction minVal, Instruction maxVal) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); + } + public Instruction FMix(Instruction x, Instruction y, Instruction a) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFMix(x.ResultType ?? -1, x, y, a, glslSet ?? -1); + } + public Instruction IMix(Instruction x, Instruction y, Instruction a) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLIMix(x.ResultType ?? -1, x, y, a, glslSet ?? -1); + } + public Instruction Step(Instruction edge, Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLStep(x.ResultType ?? -1, edge, x, glslSet ?? -1); + } + public Instruction SmoothStep(Instruction edge0, Instruction edge1, Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLSmoothStep(x.ResultType ?? -1, edge0, edge1, x, glslSet ?? -1); + } + public Instruction Fma(Instruction a, Instruction b, Instruction c) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFma(a.ResultType ?? -1, a, b, c, glslSet ?? -1); + } + public Instruction Frexp(Instruction x, Instruction exp) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFrexp(x.ResultType ?? -1, x, exp, glslSet ?? -1); + } + public Instruction FrexpStruct(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFrexpStruct(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Ldexp(Instruction x, Instruction exp) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLLdexp(x.ResultType ?? -1, x, exp, glslSet ?? -1); + } + public Instruction PackSnorm4x8(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackSnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction PackUnorm4x8(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackUnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction PackSnorm2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackSnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction PackUnorm2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackUnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction PackHalf2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackHalf2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction PackDouble2x32(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLPackDouble2x32(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackSnorm2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackSnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackUnorm2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackUnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackHalf2x16(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackHalf2x16(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackSnorm4x8(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackSnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackUnorm4x8(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackUnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction UnpackDouble2x32(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLUnpackDouble2x32(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Length(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLLength(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction Distance(Instruction p0, Instruction p1) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLDistance(p0.ResultType ?? -1, p0, p1, glslSet ?? -1); + } + public Instruction Cross(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLCross(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction Normalize(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLNormalize(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FaceForward(Instruction n, Instruction i, Instruction nref) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFaceForward(n.ResultType ?? -1, n, i, nref, glslSet ?? -1); + } + public Instruction Reflect(Instruction i, Instruction n) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLReflect(i.ResultType ?? -1, i, n, glslSet ?? -1); + } + public Instruction Refract(Instruction i, Instruction n, Instruction eta) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLRefract(i.ResultType ?? -1, i, n, eta, glslSet ?? -1); + } + public Instruction FindILsb(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFindILsb(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FindSMsb(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFindSMsb(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction FindUMsb(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLFindUMsb(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction InterpolateAtCentroid(Instruction x) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLInterpolateAtCentroid(x.ResultType ?? -1, x, glslSet ?? -1); + } + public Instruction InterpolateAtSample(Instruction interpolant, Instruction sample) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLInterpolateAtSample(interpolant.ResultType ?? -1, interpolant, sample, glslSet ?? -1); + } + public Instruction InterpolateAtOffset(Instruction interpolant, Instruction offset) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLInterpolateAtOffset(interpolant.ResultType ?? -1, interpolant, offset, glslSet ?? -1); + } + public Instruction NMin(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLNMin(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction NMax(Instruction x, Instruction y) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLNMax(x.ResultType ?? -1, x, y, glslSet ?? -1); + } + public Instruction NClamp(Instruction x, Instruction minVal, Instruction maxVal) + { + EnsureGlslSet(); + return mixer.Buffer.AddGLSLNClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs new file mode 100644 index 0000000000..4a73e266d8 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs @@ -0,0 +1,354 @@ +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using System.Runtime.InteropServices; +using System.Runtime.Serialization.Formatters; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public ref partial struct FunctionBuilder +{ + + public readonly Instruction FindVariable(string name) + { + if (mixer.LocalVariables.TryGet(name, out var local)) + return local; + else if (mixer.GlobalVariables.TryGet(name, out var global)) + return global; + else + throw new Exception($"Variable {name} was not found"); + } + + public readonly Instruction Constant(T value) + where T : struct + { + return mixer.CreateConstant(value).Instruction; + } + + public readonly Instruction Load(string name) + { + var variable = FindVariable(name); + var rtype = Instruction.Empty; + foreach (var i in mixer.Buffer.Declarations.UnorderedInstructions) + { + if (i.ResultId != null && i.ResultId == variable.ResultType && i.OpCode != SDSLOp.OpTypePointer) + { + rtype = i; + break; + } + else if (i.ResultId != null && i.ResultId == variable.ResultType && i.OpCode == SDSLOp.OpTypePointer) + { + var toFind = i.GetOperand("type"); + foreach (var j in mixer.Buffer.Declarations.UnorderedInstructions) + { + if (j.ResultId != null && j.ResultId == toFind && j.OpCode != SDSLOp.OpTypePointer) + { + rtype = j; + break; + } + } + break; + } + } + if (rtype.IsEmpty) + throw new Exception("type of variable was not found"); + + return mixer.Buffer.AddOpLoad(rtype, variable, null); + } + public readonly Instruction FindById(int id) + { + foreach (var i in mixer.Buffer.Instructions) + if (i.ResultId == id) + return i; + return Instruction.Empty; + } + + public readonly Instruction Add(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "byte" or "sbyte" + or "ushort" or "short" + or "uint" or "int" + or "long" or "ulong" => mixer.Buffer.AddOpIAdd(rtype, a, b), + "half" or "float" or "double" => mixer.Buffer.AddOpFAdd(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + public readonly Instruction Sub(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "byte" or "sbyte" + or "ushort" or "short" + or "uint" or "int" + or "long" or "ulong" => mixer.Buffer.AddOpISub(rtype, a, b), + "half" or "float" or "double" => mixer.Buffer.AddOpFSub(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + public readonly Instruction Div(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "sbyte" + or "short" + or "int" + or "long" => mixer.Buffer.AddOpSDiv(rtype, a, b), + "byte" + or "ushort" + or "uint" + or "ulong" => mixer.Buffer.AddOpUDiv(rtype, a, b), + "half" or "float" or "double" => mixer.Buffer.AddOpFDiv(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + public readonly Instruction Mul(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "byte" or "sbyte" + or "ushort" or "short" + or "uint" or "int" + or "long" or "ulong" => mixer.Buffer.AddOpIMul(rtype, a, b), + "half" or "float" or "double" => mixer.Buffer.AddOpFMul(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + + public readonly Instruction Mod(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "sbyte" + or "short" + or "int" + or "long" => mixer.Buffer.AddOpSMod(rtype, a, b), + "byte" + or "ushort" + or "uint" + or "ulong" => mixer.Buffer.AddOpUMod(rtype, a, b), + "half" or "float" or "double" => mixer.Buffer.AddOpFMod(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + public readonly Instruction Rem(string resultType, IdRef a, IdRef b) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return resultType switch + { + "sbyte" + or "short" + or "int" + or "long" => mixer.Buffer.AddOpSRem(rtype, a, b), + "byte" + or "ushort" + or "uint" + or "ulong" => throw new Exception("Cannot compute remainder of unsigned number"), + "half" or "float" or "double" => mixer.Buffer.AddOpFRem(rtype, a, b), + _ => throw new NotImplementedException($"{resultType} not yet implemented for this") + }; + } + public readonly Instruction VectorTimesScalar(string resultType, IdRef vector, IdRef scalar) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpVectorTimesScalar(rtype, vector, scalar); + } + public readonly Instruction VectorTimesMatrix(string resultType, IdRef vector, IdRef matrix) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpVectorTimesMatrix(rtype, vector, matrix); + } + public readonly Instruction MatrixTimesScalar(string resultType, IdRef matrix, IdRef scalar) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpMatrixTimesScalar(rtype, matrix, scalar); + } + public readonly Instruction MatrixTimesVector(string resultType, IdRef matrix, IdRef vector) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpMatrixTimesVector(rtype, matrix, vector); + } + public readonly Instruction MatrixTimesMatrix(string resultType, IdRef matrix, IdRef matrix2) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpMatrixTimesMatrix(rtype, matrix, matrix2); + } + + public readonly Instruction OuterProduct(string resultType, IdRef vector1, IdRef vector2) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpOuterProduct(rtype, vector1, vector2); + } + public readonly Instruction Dot(string resultType, IdRef vector1, IdRef vector2) + { + var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); + return mixer.Buffer.AddOpDot(rtype, vector1, vector2); + } + + + public readonly Instruction And(string resultType, IdRef operand1, IdRef operand2) + { + return mixer.Buffer.AddOpBitwiseAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); + } + + public readonly Instruction Or(string resultType, IdRef operand1, IdRef operand2) + { + return mixer.Buffer.AddOpBitwiseOr(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); + } + public readonly Instruction Xor(string resultType, IdRef operand1, IdRef operand2) + { + return mixer.Buffer.AddOpBitwiseXor(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); + } + + public readonly Instruction VectorShuffle(string resultType, IdRef vector1, IdRef vector2, Span values) + { + return mixer.Buffer.AddOpVectorShuffle(mixer.GetOrCreateBaseType(resultType.AsMemory()), vector1, vector2, MemoryMarshal.Cast(values)); + } + + + public readonly Instruction ShiftRightLogical(string resultType, IdRef baseId, IdRef shift) + { + return mixer.Buffer.AddOpShiftRightLogical(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); + } + public readonly Instruction ShiftRightArithmetic(string resultType, IdRef baseId, IdRef shift) + { + return mixer.Buffer.AddOpShiftRightArithmetic(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); + } + public readonly Instruction ShiftLeft(string resultType, IdRef baseId, IdRef shift) + { + return mixer.Buffer.AddOpShiftLeftLogical(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); + } + + public readonly Instruction GreaterThan(string resultType, IdRef value1, IdRef value2) + { + return resultType switch + { + + string f when + f.StartsWith("half") + || f.StartsWith("float") + || f.StartsWith("double") + => mixer.Buffer.AddOpFOrdGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("sbyte") + || f.StartsWith("short") + || f.StartsWith("int") + || f.StartsWith("long") + => mixer.Buffer.AddOpSGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("byte") + || f.StartsWith("ushort") + || f.StartsWith("uint") + || f.StartsWith("ulong") + => mixer.Buffer.AddOpUGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + _ => throw new NotImplementedException() + }; + } + public readonly Instruction LessThan(string resultType, IdRef value1, IdRef value2) + { + return resultType switch + { + + string f when + f.StartsWith("half") + || f.StartsWith("float") + || f.StartsWith("double") + => mixer.Buffer.AddOpFOrdLessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("sbyte") + || f.StartsWith("short") + || f.StartsWith("int") + || f.StartsWith("long") + => mixer.Buffer.AddOpSLessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("byte") + || f.StartsWith("ushort") + || f.StartsWith("uint") + || f.StartsWith("ulong") + => mixer.Buffer.AddOpULessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + _ => throw new NotImplementedException() + }; + } + public readonly Instruction GreaterThanEqual(string resultType, IdRef value1, IdRef value2) + { + return resultType switch + { + + string f when + f.StartsWith("half") + || f.StartsWith("float") + || f.StartsWith("double") + => mixer.Buffer.AddOpFOrdGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("sbyte") + || f.StartsWith("short") + || f.StartsWith("int") + || f.StartsWith("long") + => mixer.Buffer.AddOpSGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("byte") + || f.StartsWith("ushort") + || f.StartsWith("uint") + || f.StartsWith("ulong") + => mixer.Buffer.AddOpUGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + _ => throw new NotImplementedException() + }; + } + public readonly Instruction LessThanEqual(string resultType, IdRef value1, IdRef value2) + { + return resultType switch + { + + string f when + f.StartsWith("half") + || f.StartsWith("float") + || f.StartsWith("double") + => mixer.Buffer.AddOpFOrdLessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("sbyte") + || f.StartsWith("short") + || f.StartsWith("int") + || f.StartsWith("long") + => mixer.Buffer.AddOpSLessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + string f when + f.StartsWith("byte") + || f.StartsWith("ushort") + || f.StartsWith("uint") + || f.StartsWith("ulong") + => mixer.Buffer.AddOpULessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), + _ => throw new NotImplementedException() + }; + } + + public readonly Instruction LogicalEqual(string resultType, IdRef value1, IdRef value2) + { + return mixer.Buffer.AddOpLogicalEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); + } + public readonly Instruction LogicalNotEqual(string resultType, IdRef value1, IdRef value2) + { + return mixer.Buffer.AddOpLogicalNotEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); + } + public readonly Instruction LogicalAnd(string resultType, IdRef value1, IdRef value2) + { + return mixer.Buffer.AddOpLogicalAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); + } + public readonly Instruction LogicalOr(string resultType, IdRef value1, IdRef value2) + { + return mixer.Buffer.AddOpLogicalAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); + } + public readonly Instruction LogicalNot(string resultType, IdRef value) + { + return mixer.Buffer.AddOpLogicalNot(mixer.GetOrCreateBaseType(resultType.AsMemory()), value); + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs new file mode 100644 index 0000000000..54fa9bc683 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs @@ -0,0 +1,194 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Mixer; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public ref partial struct FunctionBuilder +{ + public record struct Variable(IdRef Id, bool IsVariable); + public record struct Value(IdRef Id, IdResultType Type, bool IsVariable = false) + { + public static implicit operator Value(Instruction i) => new(i, i.ResultType ?? -1, false); + }; + public delegate Variable InitializerDelegate(Mixer mixer, ref FunctionBuilder functionBuilder); + public delegate Value ValueDelegate(Mixer mixer, FunctionBuilder functionBuilder); + + internal Mixer mixer; + Instruction function; + EntryPoint? entryPoint; + + public FunctionBuilder(Mixer mixer, string returnType, string name, CreateFunctionParameters parameterTypesDelegate) + { + this.mixer = mixer; + + + var t = mixer.GetOrCreateBaseType(returnType.AsMemory()); + function = mixer.Buffer.AddOpSDSLFunction(t.ResultId ?? -1, FunctionControlMask.MaskNone, -1, name); + var p = new ParameterBuilder(mixer, stackalloc IdRef[16], stackalloc IdRef[16]); + p = parameterTypesDelegate.Invoke(p); + var t_func = mixer.Buffer.AddOpTypeFunction(t.ResultId ?? -1, p.Types); + function.Operands.Span[3] = t_func.ResultId ?? -1; + mixer.Buffer.AddOpLabel(); + } + public FunctionBuilder(Mixer mixer, EntryPoint entryPoint) + { + this.mixer = mixer; + this.entryPoint = entryPoint; + var t = mixer.GetOrCreateBaseType("void".AsMemory()); + var t_func = mixer.Buffer.AddOpTypeFunction(t.ResultId ?? -1, Span.Empty); + function = mixer.Buffer.AddOpSDSLFunction(t.ResultId ?? -1, FunctionControlMask.MaskNone, t_func, entryPoint.Name); + mixer.Buffer.AddOpLabel(); + + } + + + + public FunctionBuilder Declare(string type, string name) + { + var t = mixer.GetOrCreateBaseType(type.AsMemory()); + var p_t = mixer.Buffer.AddOpTypePointer(StorageClass.Function, t); + mixer.Buffer.AddOpSDSLVariable(p_t, StorageClass.Function, name, null); + return this; + } + /// + /// Declares a variable and assigns a value to it + /// + /// + /// + /// + /// + public FunctionBuilder DeclareAssign(string name, T constant) + where T : struct + { + var resultType = mixer.GetOrCreateBaseType(); + var ptr = mixer.Buffer.AddOpTypePointer(StorageClass.Function, resultType.ResultId ?? -1); + var value = mixer.CreateConstant(constant); + mixer.Buffer.AddOpSDSLVariable(ptr, StorageClass.Function, name, value.ResultId); + return this; + } + public FunctionBuilder Assign(string name, ValueDelegate initializer) + { + // TODO : If the value delegate is a constant no need to be loaded on a register + var result = initializer.Invoke(mixer, this); + if (mixer.LocalVariables.TryGet(name, out var local)) + { + var load = result.Id; + if(result.IsVariable) + load = mixer.Buffer.AddOpLoad(result.Type, result.Id, null).ResultId ?? -1; + mixer.Buffer.AddOpStore(local, load, null); + } + else if (mixer.GlobalVariables.TryGet(name, out var global)) + { + var load = result.Id; + if (result.IsVariable) + load = mixer.Buffer.AddOpLoad(result.Type, result.Id, null); + mixer.Buffer.AddOpStore(global, load, null); + } + return this; + + } + public FunctionBuilder Assign(string name, IdRef value) + { + if (mixer.LocalVariables.TryGet(name, out var local)) + mixer.Buffer.AddOpStore(local, value, null); + else if (mixer.GlobalVariables.TryGet(name, out var global)) + mixer.Buffer.AddOpStore(global, value, null); + return this; + } + public FunctionBuilder AssignConstant(string name, T constantValue) + where T : struct + { + var constant = mixer.CreateConstant(constantValue); + if (mixer.LocalVariables.TryGet(name, out var local)) + mixer.Buffer.AddOpStore(local, constant, null); + else if (mixer.GlobalVariables.TryGet(name, out var global)) + mixer.Buffer.AddOpStore(global, constant, null); + return this; + } + public FunctionBuilder AssignVariable(string destination, string source) + { + // TODO : If the value delegate is a constant no need to be loaded on a register + + Instruction src = Instruction.Empty; + if (mixer.LocalVariables.TryGet(source, out var ls)) + src = ls; + else if (mixer.GlobalVariables.TryGet(source, out var gs)) + src = gs; + + var srcType = mixer.FindType(src.Words.Span[1]); + + if (mixer.LocalVariables.TryGet(destination, out var local)) + { + var load = mixer.Buffer.AddOpLoad(srcType, src, null); + mixer.Buffer.AddOpStore(local, load, null); + } + else if (mixer.GlobalVariables.TryGet(destination, out var global)) + { + var load = mixer.Buffer.AddOpLoad(srcType, src, null); + mixer.Buffer.AddOpStore(global, load, null); + } + return this; + } + public FunctionBuilder Return(ValueDelegate vd) + { + Return(vd.Invoke(mixer, this).Id); + return this; + } + + public FunctionBuilder Return(IdRef? value = null) + { + if (value != null) + mixer.Buffer.AddOpReturnValue(value.Value); + else + mixer.Buffer.AddOpReturn(); + return this; + } + public Mixer FunctionEnd() + { + var count = mixer.IOVariables.Count; + Span idRefs = stackalloc IdRef[count]; + int index = 0; + foreach (var i in mixer.IOVariables) + { + idRefs[index] = i; + index += 1; + } + mixer.Buffer.AddOpFunctionEnd(); + if (entryPoint != null) + { + mixer.Buffer.AddOpEntryPoint(entryPoint.Value.ExecutionModel, function, entryPoint.Value.Name, idRefs); + } + return mixer; + } + + public delegate ParameterBuilder CreateFunctionParameters(ParameterBuilder typeIds); + public ref struct ParameterBuilder + { + Mixer mixer; + Span inner { get; } + Span innerTypes { get; } + public Span Parameters => inner[..count]; + public Span Types => innerTypes[..count]; + int count; + public ParameterBuilder(Mixer mixer, Span parameters, Span types) + { + this.mixer = mixer; + parameters.Clear(); + inner = parameters; + innerTypes = types; + count = 0; + } + + public ParameterBuilder With(string type, string name) + { + var i = mixer.Buffer.AddOpSDSLFunctionParameter(mixer.GetOrCreateBaseType(type.AsMemory()), name); + inner[count] = i.ResultId ?? -1; + innerTypes[count] = i.ResultType ?? -1; + count += 1; + return this; + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs new file mode 100644 index 0000000000..fe265233d1 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs @@ -0,0 +1,55 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + + +public partial class Mixer +{ + + public IOVariablesFinder IOVariables => new(this); + + public ref struct IOVariablesFinder + { + Mixer mixer; + + public readonly int Count + { + get + { + int result = 0; + foreach (var i in this) + result += 1; + return result; + } + } + public IOVariablesFinder(Mixer mixer) + { + this.mixer = mixer; + } + + public Enumerator GetEnumerator() => new(this); + + public ref struct Enumerator + { + InstructionEnumerator enumerator; + public Enumerator(IOVariablesFinder finder) + { + enumerator = new InstructionEnumerator(finder.mixer.Buffer.Declarations); + } + + public Instruction Current => enumerator.Current; + + public bool MoveNext() + { + while (enumerator.MoveNext()) + { + if (Current.OpCode == SDSLOp.OpSDSLIOVariable) + return true; + } + return false; + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs new file mode 100644 index 0000000000..58aebff05a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs @@ -0,0 +1,249 @@ +using System.Numerics; +using System.Security.Cryptography; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Core.Buffers.MultiBuffer; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv; + +/// +/// Spirv Mixer object mainly designed around SDSL +/// +public sealed partial class Mixer : MixerBase +{ + //public FunctionFinder Functions => new(this); + //FunctionBuffer functions; + + public MultiBufferLocalVariables LocalVariables => Buffer.LocalVariables; + public MultiBufferGlobalVariables GlobalVariables => Buffer.GlobalVariables; + + + + + public static Inheritance Create(string name) + { + return new(new(name)); + } + + public Mixer(string name) : base(name) + { + Buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); + //buffer.AddOpExtension("SPV_GOOGLE_decorate_string"); + } + + public Mixer WithCapability(Capability capability) + { + Buffer.AddOpCapability(capability); + return this; + } + + public EntryPoint WithEntryPoint(ExecutionModel model, string name) + { + return new EntryPoint(this, model, name); + } + public FunctionBuilder WithFunction(string type, string name, FunctionBuilder.CreateFunctionParameters parameterCreate) + { + return new FunctionBuilder(this, type, name, parameterCreate); + } + + public Mixer Inherit(string mixin) + { + Mixins.Add(mixin); + Buffer.AddOpSDSLMixinInherit(mixin); + return this; + } + + public Mixer WithType(string type, StorageClass? storage = null) + { + if (type.Contains('*')) + CreateTypePointer(type.AsMemory(), storage ?? throw new Exception("storage should not be null")); + else + GetOrCreateBaseType(type.AsMemory()); + return this; + } + + public Mixer WithInput(string type, string name, string semantic, ExecutionModel execution) + { + var t_variable = GetOrCreateBaseType(type.AsMemory()); + var p_t_variable = Buffer.AddOpTypePointer(StorageClass.Input, t_variable.ResultId ?? -1); + Buffer.AddOpSDSLIOVariable(p_t_variable.ResultId ?? -1, StorageClass.Input, execution, name, semantic, null); + return this; + } + public Mixer WithOutput(string type, string name, string semantic, ExecutionModel execution) + { + var t_variable = GetOrCreateBaseType(type.AsMemory()); + var p_t_variable = Buffer.AddOpTypePointer(StorageClass.Output, t_variable.ResultId ?? -1); + Buffer.AddOpSDSLIOVariable(p_t_variable.ResultId ?? -1, StorageClass.Output, execution, name, semantic, null); + return this; + } + + public Mixer WithConstant(string name, T value) + where T : struct + { + CreateConstant(name, value); + return this; + } + public MixinInstruction CreateConstant(T value) + where T : struct + { + return value switch + { + sbyte v => Buffer.AddOpConstant(GetOrCreateBaseType("sbyte".AsMemory()).ResultId ?? -1, v), + short v => Buffer.AddOpConstant(GetOrCreateBaseType("short".AsMemory()).ResultId ?? -1, v), + int v => Buffer.AddOpConstant(GetOrCreateBaseType("int".AsMemory()).ResultId ?? -1, v), + long v => Buffer.AddOpConstant(GetOrCreateBaseType("long".AsMemory()).ResultId ?? -1, v), + byte v => Buffer.AddOpConstant(GetOrCreateBaseType("byte".AsMemory()).ResultId ?? -1, v), + ushort v => Buffer.AddOpConstant(GetOrCreateBaseType("ushort".AsMemory()).ResultId ?? -1, v), + uint v => Buffer.AddOpConstant(GetOrCreateBaseType("uint".AsMemory()).ResultId ?? -1, v), + ulong v => Buffer.AddOpConstant(GetOrCreateBaseType("ulong".AsMemory()).ResultId ?? -1, v), + float v => Buffer.AddOpConstant(GetOrCreateBaseType("float".AsMemory()).ResultId ?? -1, v), + double v => Buffer.AddOpConstant(GetOrCreateBaseType("double".AsMemory()).ResultId ?? -1, v), + Vector2 v => CreateConstantVector(v), + Vector3 v => CreateConstantVector(v), + Vector4 v => CreateConstantVector(v), + _ => throw new NotImplementedException() + }; + } + public MixinInstruction CreateConstantVector(T value) + where T : struct + { + if (value is Vector2 vec2) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float2".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.Y); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1 }); + return cons; + } + else if (value is Vector3 vec3) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float3".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Y); + var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Z); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1 }); + return cons; + } + else if (value is Vector4 vec4) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float4".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Y); + var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Z); + var c4 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.W); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1, c4.ResultId ?? -1 }); + return cons; + } + throw new NotImplementedException(); + } + public MixinInstruction CreateConstant(string name, T value) + where T : struct + { + if (value is sbyte vi8) + { + var t_const = GetOrCreateBaseType("sbyte".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi8); + return cons; + } + else if (value is short vi16) + { + var t_const = GetOrCreateBaseType("short".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi16); + return cons; + } + else if (value is int vi32) + { + var t_const = GetOrCreateBaseType("int".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi32); + return cons; + } + else if (value is long vi64) + { + var t_const = GetOrCreateBaseType("long".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi64); + return cons; + } + else if (value is byte vu8) + { + var t_const = GetOrCreateBaseType("byte".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu8); + return cons; + } + else if (value is ushort vu16) + { + var t_const = GetOrCreateBaseType("ushort".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu16); + return cons; + } + else if (value is uint vu32) + { + var t_const = GetOrCreateBaseType("uint".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu32); + return cons; + } + else if (value is ulong vu64) + { + var t_const = GetOrCreateBaseType("ulong".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu64); + return cons; + } + else if (value is float vf32) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vf32); + return cons; + } + else if (value is double vf64) + { + var t_const = GetOrCreateBaseType("double".AsMemory()); + var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vf64); + return cons; + } + else if (value is Vector2 vec2) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float2".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.Y); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1 }); + return cons; + } + else if (value is Vector3 vec3) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float3".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Y); + var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Z); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1 }); + return cons; + } + else if (value is Vector4 vec4) + { + var t_const = GetOrCreateBaseType("float".AsMemory()); + var t_const2 = GetOrCreateBaseType("float4".AsMemory()); + + var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.X); + var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Y); + var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Z); + var c4 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.W); + var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1, c4.ResultId ?? -1 }); + return cons; + } + + throw new NotImplementedException(); + } + public override string ToString() + { + return Disassembler.Disassemble(new SortedWordBuffer(Buffer)); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs new file mode 100644 index 0000000000..376d2d5e06 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs @@ -0,0 +1,35 @@ +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv; + +/// +/// Mixer base class +/// +public abstract class MixerBase +{ + public MixinGraph Mixins {get; protected set;} + public MultiBuffer Buffer {get; protected set;} + + protected Action DisposeBuffers; + + public string Name { get; init; } + + + public MixerBase(string name) + { + Name = name; + Buffer = new(); + Buffer.AddOpSDSLMixinName(Name); + Mixins = new(); + DisposeBuffers = Buffer.Dispose; + } + + public virtual MixinBuffer Build() + { + Buffer.AddOpSDSLMixinEnd(); + // TODO : do some validation here + MixinSourceProvider.Register(new(Name, Buffer)); + DisposeBuffers.Invoke(); + return MixinSourceProvider.Get(Name); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs new file mode 100644 index 0000000000..fc9ffbfa75 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs @@ -0,0 +1,55 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv; + +/// +/// Helper to enumerate all instructions from many mixins +/// +public struct FullMixinInstructions +{ + Mixin mixin; + public FullMixinInstructions(Mixin mixin) + { + this.mixin = mixin; + } + + public Enumerator GetEnumerator() => new(mixin); + + public ref struct Enumerator + { + Mixin mixin; + MixinGraph graph; + bool graphFinished; + + MixinInstructionEnumerator enumerator; + InstructionEnumerator self; + + + public MixinInstruction Current => graphFinished ? new(mixin.Name, self.Current) : enumerator.Current; + + public Enumerator(Mixin mixin) + { + this.mixin = mixin; + graphFinished = false; + graph = MixinSourceProvider.GetMixinGraph(mixin.Name); + enumerator = graph.Instructions.GetEnumerator(); + self = mixin.Instructions.GetEnumerator(); + } + + public bool MoveNext() + { + if (enumerator.MoveNext()) + return true; + else + { + if (!graphFinished) + { + self.ResultIdReplacement = -1; + graphFinished = true; + } + return self.MoveNext(); + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs new file mode 100644 index 0000000000..3111729a3f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs @@ -0,0 +1,61 @@ +using System.Runtime.CompilerServices; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv; + + + + +/// +/// Mixin object +/// +public partial struct Mixin +{ + public static readonly Mixin Empty = new("", SortedWordBuffer.Empty); + + public string Name { get; init; } + public int Bound { get; init; } + public int ResultIdCount { get; init; } + + internal SortedWordBuffer Buffer { get; } + public MixinInstructions Instructions => new(this); + public FullMixinInstructions FullInstructions => new(this); + public MixinParents Parents => new(this); + + public bool IsEmpty => Buffer.IsEmpty; + + + public Mixin(string name, SortedWordBuffer wordBuffer) + { + Name = name; + Buffer = wordBuffer; + ResultIdCount = 0; + Bound = 0; + foreach (var i in Instructions) + { + if (i.ResultId != null) + { + ResultIdCount += 1; + if(i.ResultId > Bound) + Bound = i.ResultId.Value; + } + } + } + + public string Disassemble() + { + var words = new WordBuffer(); + foreach(var e in FullInstructions) + { + words.Insert(e.Instruction); + } + return Disassembler.Disassemble(new UnsortedWordBuffer(words)); + } + + + public override string ToString() + { + return Disassembler.Disassemble(Buffer.Memory); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs new file mode 100644 index 0000000000..dd60b4c944 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs @@ -0,0 +1,29 @@ +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv; + + +/// +/// Wrapper over Instruction for mixins +/// +public ref struct MixinInstruction +{ + public string MixinName { get; init; } + public Instruction Instruction { get; init; } + + public SDSLOp OpCode => Instruction.OpCode; + public int? ResultId => Instruction.ResultId; + public int? ResultType => Instruction.ResultType; + public Span Words => Instruction.Words.Span; + public bool IsEmpty => Instruction.IsEmpty; + + public static implicit operator MixinInstruction(Instruction instruction) => new("",instruction); + public static implicit operator IdRef(MixinInstruction mi) => mi.ResultId ?? throw new Exception("This instruction has no ResultId"); + public static implicit operator IdResultType(MixinInstruction mi) => mi.ResultId ?? throw new Exception("This instruction has no ResultId"); + + public MixinInstruction(string mixinName, Instruction instruction) + { + MixinName = mixinName; + Instruction = instruction; + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs new file mode 100644 index 0000000000..282f90d68e --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs @@ -0,0 +1,30 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv; + +/// +/// Helper to enumerate instructions from many mixins +/// +public ref struct MixinInstructions +{ + Mixin mixin; + public MixinInstructions(Mixin mixin) + { + this.mixin = mixin; + } + + public Instruction this[int index] + { + get + { + var count = mixin.Buffer.Length; + if(index >= count) return Instruction.Empty; + var enumerator = GetEnumerator(); + for(int i = 0; enumerator.MoveNext() && i < index; i++); + return enumerator.Current; + } + } + + public InstructionEnumerator GetEnumerator() => mixin.Buffer.GetEnumerator(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs new file mode 100644 index 0000000000..5cdaf4b0cb --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs @@ -0,0 +1,105 @@ +using System.Numerics; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv; + +/// +/// A list of parents built with MemoryOwner from the HighPerformance community toolkit +/// +public class ParentList +{ + MemoryOwner _owner; + public int Length { get; private set; } + + public string this[int index] => _owner.Span[index]; + + public ParentList() + { + _owner = MemoryOwner.Allocate(2); + } + + public ParentList(int size) + { + _owner = MemoryOwner.Allocate(size); + } + + public void Add(string name) + { + if(_owner.Length <= Length +1) + Expand(); + _owner.Span[Length] = name; + Length += 1; + } + + internal void Expand() + { + var r = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)Length + 1),AllocationMode.Clear); + _owner.Span.CopyTo(r.Span); + _owner.Dispose(); + _owner = r; + } + + public Enumerator GetEnumerator() => new(this); + + public ref struct Enumerator + { + readonly ParentList parentList; + int index; + public string Current => parentList[index]; + + public Enumerator(ParentList parentList) + { + this.parentList = parentList; + index = -1; + } + + public bool MoveNext() + { + return ++index < parentList.Length; + } + } + + public void Dispose() => _owner.Dispose(); +} + + +public ref struct MixinParents +{ + Mixin mixin; + public MixinParents(Mixin mixin) + { + this.mixin = mixin; + } + + public FilteredEnumerator GetEnumerator() => new(mixin.Buffer, SDSLOp.OpSDSLMixinInherit); + + public int GetCount() + { + var result = 0; + foreach (var p in this) + result += 1; + return result; + } + public ParentList ToList() + { + var count = GetCount(); + if (GetCount() == 0) + return new(); + var result = new ParentList(count); + foreach (var e in this) + { + foreach (var name in e) + { + result.Add(name.To().Value); + } + } + return result; + } + public MixinGraph ToGraph() + { + return new(ToList()); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs new file mode 100644 index 0000000000..70575cb1e1 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs @@ -0,0 +1,119 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv; + +public sealed class MixinBuffer +{ + public string Name { get; } + public SortedWordBuffer Declarations { get; } + public SortedFunctionBufferCollection Functions {get;} + public MixinGraph Parents { get; } + public InstructionsWrapper Instructions => new(this); + + public int Bound { + get + { + var bound = 0; + foreach(var i in Declarations) + { + if (i.ResultId > bound) + bound = i.ResultId ?? bound; + } + foreach(var (_,f) in Functions) + foreach (var i in f) + { + if (i.ResultId > bound) + bound = i.ResultId ?? bound; + } + return bound; + } + } + + public MixinBuffer(string name, MultiBuffer buffers) + { + Name = name; + Declarations = new(buffers.Declarations); + Functions = new(buffers.Functions); + Parents = new(); + + foreach(var i in Declarations) + { + if (i.OpCode == Core.SDSLOp.OpSDSLMixinInherit) + Parents.Add(i.GetOperand("mixinName")?.Value!); + } + } + + public ref struct InstructionsWrapper + { + MixinBuffer buffer; + public InstructionsWrapper(MixinBuffer buffer) + { + this.buffer = buffer; + } + + + public Instruction this[int index] + { + get + { + var e = GetEnumerator(); + for(int i = 0; i < index -1; i++) + { + e.MoveNext(); + } + return e.MoveNext() ? e.Current : throw new IndexOutOfRangeException(); + } + } + + public Enumerator GetEnumerator() => new(buffer); + + public ref struct Enumerator + { + MixinBuffer buffer; + + InstructionEnumerator declarations; + SortedFunctionBufferCollection.FunctionsInstructions.Enumerator functions; + bool finishedDecl; + + public Enumerator(MixinBuffer buffer) + { + this.buffer = buffer; + declarations = buffer.Declarations.GetEnumerator(); + functions = buffer.Functions.Instructions.GetEnumerator(); + } + + public Instruction Current => !finishedDecl ? declarations.Current : functions.Current; + + public bool MoveNext() + { + if (declarations.MoveNext()) + return true; + else if (functions.MoveNext()) + { + if(!finishedDecl) + finishedDecl = true; + return true; + } + else + return false; + } + } + } + + public override string ToString() + { + return + new StringBuilder() + .Append(Disassembler.Disassemble(Declarations)) + .Append(string.Join("\n", Functions.Buffers.Select(x => Disassembler.Disassemble(x.Value)))) + .ToString(); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs new file mode 100644 index 0000000000..a569a1ebbf --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs @@ -0,0 +1,93 @@ +using System.Collections; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv; + +/// +/// Collections of mixins +/// +internal struct MixinList : IList +{ + List mixins; + + public MixinList() + { + mixins = new(); + } + + public string this[int index] { get => mixins[index]; set => throw new Exception();} + + public int Count => mixins.Count; + + public bool IsReadOnly => false; + + public void Add(string mixin) + { + if (!mixins.Contains(mixin)) + mixins.Add(mixin); + } + + public void Clear() + { + mixins.Clear(); + } + + public bool Contains(string item) + { + return mixins.Contains(item); + } + + public void CopyTo(string[] array, int arrayIndex) + { + mixins.CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return mixins.GetEnumerator(); + } + + public int IndexOf(string item) + { + return mixins.IndexOf(item); + } + + public void Insert(int index, string item) + { + mixins.Insert(index,item); + } + + public bool Remove(string item) + { + return mixins.Remove(item); + } + + public void RemoveAt(int index) + { + mixins.RemoveAt(index); + } + + public List AsList() => mixins; + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} + +public ref struct MixinEnumerator +{ + List mixinNames; + List.Enumerator enumerator; + + public MixinEnumerator(List names) + { + mixinNames = names; + enumerator = mixinNames.GetEnumerator(); + } + + public MixinBuffer Current => MixinSourceProvider.Get(enumerator.Current); + + public bool MoveNext() => enumerator.MoveNext(); +} + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs new file mode 100644 index 0000000000..5e70d1b260 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs @@ -0,0 +1,92 @@ +namespace Stride.Shaders.Spirv; + + +public record struct MixinGraphInstructions(MixinGraph Graph, bool Offsetted = false) +{ + + public readonly int Count + { + get + { + int count = 0; + foreach (var e in this) + count += 1; + return count; + } + } + public readonly MixinInstructionEnumerator GetEnumerator() => new(Graph, Offsetted); +} + +/// +/// Representation of mixin parents to a graph. +/// +public class MixinGraph +{ + public ParentList Names { get; private set; } + internal MixinList DistinctNames { get; private set; } + + public MixinGraphInstructions OffsettedInstructions => new(this,true); + public MixinGraphInstructions Instructions => new(this); + + public int Count => GetCount(); + + public MixinBuffer this[int index] + { + get + { + if(index >= Count) + throw new IndexOutOfRangeException(); + var enumerator = GetEnumerator(); + for (int i = 0; enumerator.MoveNext() && i < index; i++){} + return enumerator.Current; + } + } + + public MixinGraph() + { + Names = new(); + DistinctNames = new(); + } + + public MixinGraph(ParentList names) + { + Names = names; + DistinctNames = new(); + RebuildGraph(); + } + + public MixinEnumerator GetEnumerator() => new(DistinctNames.AsList()); + + public void Add(string mixin) + { + Names.Add(mixin); + RebuildGraph(); + } + + public void RebuildGraph() + { + DistinctNames.Clear(); + foreach (var m in Names) + { + FillMixinHashSet(m); + } + } + + void FillMixinHashSet(string name) + { + if(MixinSourceProvider.TryGetMixinGraph(name, out var graph) && graph != null) + { + foreach (var m in graph) + FillMixinHashSet(m.Name); + DistinctNames.Add(name); + } + } + int GetCount() + { + int count = 0; + var e = GetEnumerator(); + while (e.MoveNext()) + count += 1; + return count; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs new file mode 100644 index 0000000000..ddac26ff5a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs @@ -0,0 +1,37 @@ +namespace Stride.Shaders.Spirv; + +/// +/// Mixin buffer repository +/// +public class MixinSourceProvider +{ + + internal static MixinSourceProvider Instance { get; } = new(); + + readonly Dictionary Mixins; + readonly Dictionary MixinGraph; + + private MixinSourceProvider() + { + Mixins = new(); + MixinGraph = new(); + } + + public static void Register(MixinBuffer mixin) + { + Instance.Mixins.Add(mixin.Name, mixin); + Instance.MixinGraph.Add(mixin.Name, mixin.Parents); + } + public static MixinBuffer Get(string name) + { + return Instance.Mixins[name]; + } + public static MixinGraph GetMixinGraph(string name) + { + return Instance.MixinGraph[name]; + } + public static bool TryGetMixinGraph(string name, out MixinGraph? graph) + { + return Instance.MixinGraph.TryGetValue(name, out graph); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs new file mode 100644 index 0000000000..f83fcf8a82 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs @@ -0,0 +1,127 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + + +/// +/// Makes sure indices used in spirv module are all continuous. +/// +public struct BoundReducer : INanoPass +{ + public BoundReducer() { } + + public void Apply(MultiBuffer buffer) + { + // First step is to find the next idResult + // If it's previous + 1 then it's okay, previous is now updated + // If it's above previous + 1, then it's not okay and we switch + + var finished = false; + var previousId = 0; + var next = Instruction.Empty; + var countIds = 0; + + foreach (var i in buffer.Instructions) + countIds += i.ResultId != null ? 1 : 0; + while (!finished && previousId < countIds) + { + var countAbove = 0; + foreach(var i in buffer.Instructions) + { + if(i.ResultId == previousId + 1) + { + countAbove += 1; + previousId += 1; + next = i; + break; + } + else if (next.IsEmpty && i.ResultId > previousId + 1) + { + countAbove += 1; + next = i; + } + else if(!next.IsEmpty && i.ResultId > previousId + 1 && i.ResultId < next.ResultId) + { + countAbove += 1; + next = i; + } + } + if (countAbove == 0) + finished = true; + else if(next.ResultId > previousId + 1) + { + next.AsRef().SetResultId(previousId + 1); + ReplaceRefs(next.ResultId ?? -1, previousId + 1, buffer); + } + } + + + buffer.RecomputeBound(); + } + static void ReplaceRefs(int from, int to, MultiBuffer buffer) + { + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + foreach (var (_, f) in buffer.Functions) + foreach (var i in f.UnorderedInstructions) + { + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + static void ReplaceRefs(int from, int to, WordBuffer func) + { + foreach (var i in func.UnorderedInstructions) + { + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs new file mode 100644 index 0000000000..4c96418b09 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs @@ -0,0 +1,62 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Processing; + +public struct CapabilitiesCompute : INanoPass +{ + public void Apply(MultiBuffer buffer) + { + throw new NotImplementedException("Needs to finish checking the spec"); + } + + public static void AddCapabilities(Instruction instruction) + { + if(instruction.OpCode == SDSLOp.OpEntryPoint) + { + if(instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.Geometry) + { + //Add capability geometry + } + else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationControl) + { + //Add capability tess + + } + else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationEvaluation) + { + //Add capability tess + } + } + else if(instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 16) + { + // Add capability Float16 + } + else if (instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 64) + { + // Add capability Float64 + } + else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 64) + { + // Add capability Float64 + } + else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 16) + { + // Add capability Float64 + } + else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 8) + { + // Add capability Float64 + } + + // TODO : Check if any atomic instructions operates on integers + // else if (instruction.OpCode == SDSLOp.OpAtomic && instruction.Words.Span[2] == 64) + // { + // // Add capability Float64 + // } + + + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs new file mode 100644 index 0000000000..89d4fd0acb --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs @@ -0,0 +1,30 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; + +namespace Stride.Shaders.Spirv.PostProcessing; + +public struct CompressBuffer : INanoPass +{ + public void Apply(MultiBuffer buffer) + { + using var tmp = new WordBuffer(); + foreach (var e in buffer.Declarations.UnorderedInstructions) + if (e.OpCode != SDSLOp.OpNop) + tmp.Insert(e); + buffer.Declarations.InstructionSpan.Clear(); + tmp.InstructionSpan.CopyTo(buffer.Declarations.InstructionSpan); + buffer.Declarations.RecomputeLength(); + foreach (var (_, f) in buffer.Functions) + { + tmp.InstructionSpan.Clear(); + tmp.RecomputeLength(); + foreach (var e in f.UnorderedInstructions) + if (e.OpCode != SDSLOp.OpNop) + tmp.Insert(e); + f.InstructionSpan.Clear(); + tmp.InstructionSpan.CopyTo(f.InstructionSpan); + f.RecomputeLength(); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs new file mode 100644 index 0000000000..84e8e6e74e --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs @@ -0,0 +1,57 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core; +namespace Stride.Shaders.Spirv.Processing; + +/// +/// Makes sure variables are created in the beginning of a function definition +/// +public struct FunctionVariableOrderer : INanoPass +{ + public void Apply(MultiBuffer buffer) + { + foreach(var (_,f) in buffer.Functions) + { + ProcessFunction(new(f.InstructionSpan)); + f.RecomputeLength(); + } + } + public static void ProcessFunction(SpirvSpan function) + { + using var tmp = new SpirvBuffer(function.Span.Length); + var enumerator = function.GetEnumerator(); + enumerator.MoveNext(); + var opf = enumerator.Current; + tmp.Insert(tmp.Length, opf.Words); + foreach(var i in function) + { + if(i.OpCode == SDSLOp.OpFunctionParameter) + tmp.Insert(tmp.Length, i.Words); + } + while(enumerator.Current.OpCode != SDSLOp.OpLabel) + enumerator.MoveNext(); + + tmp.Insert(tmp.Length, enumerator.Current.Words); + + foreach (var i in function) + { + if(i.OpCode == SDSLOp.OpVariable) + { + tmp.Insert(tmp.Length,i.Words); + } + } + while(enumerator.MoveNext()) + { + var i = enumerator.Current; + if (i.OpCode != SDSLOp.OpVariable && i.OpCode != SDSLOp.OpFunctionParameter) + { + tmp.Insert(tmp.Length, i.Words); + } + if (i.OpCode == SDSLOp.OpSDSLVariable) + { + var t = 0; + } + } + function.Span.Clear(); + tmp.InstructionSpan.CopyTo(function.Span); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs new file mode 100644 index 0000000000..95c12e6896 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs @@ -0,0 +1,17 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + +/// +/// Nano pass for the mixin compiler +/// +public interface INanoPass +{ + void Apply(MultiBuffer buffer); +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs new file mode 100644 index 0000000000..0fb6cfad62 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs @@ -0,0 +1,74 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.PostProcessing; + +public struct SDSLVariableReplace : INanoPass +{ + public void Apply(MultiBuffer buffer) + { + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + if (i.OpCode == SDSLOp.OpSDSLIOVariable) + { + + var sclassv = i.GetOperand("storageclass"); + var sclass = StorageClass.Private; + if (sclassv != null) + sclass = (StorageClass)sclassv.Value.Words; + var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); + variable.Operands.Span[1] = i.ResultId ?? -1; + buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); + SetOpNop(i.Words.Span); + } + else if (i.OpCode == SDSLOp.OpSDSLVariable) + { + var sclassv = i.GetOperand("storageclass"); + var sclass = StorageClass.Private; + if (sclassv != null) + sclass = (StorageClass)sclassv.Value.Words; + var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); + variable.Operands.Span[1] = i.ResultId ?? -1; + buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); + SetOpNop(i.Words.Span); + } + } + foreach (var (n, f) in buffer.Functions) + { + foreach (var i in f.UnorderedInstructions) + { + if(i.OpCode == SDSLOp.OpSDSLFunctionParameter) + { + var name = i.GetOperand("name"); + var resultType = i.ResultType ?? -1; + var variable = f.AddOpFunctionParameter(resultType); + variable.Operands.Span[1] = i.ResultId ?? -1; + buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); + SetOpNop(i.Words.Span); + } + else if (i.OpCode == SDSLOp.OpSDSLVariable) + { + + var sclassv = i.GetOperand("storageclass"); + var sclass = StorageClass.Private; + if (sclassv != null) + sclass = (StorageClass)sclassv.Value.Words; + var name = i.GetOperand("name"); + var resultType = i.ResultType ?? -1; + var initializer = i.GetOperand("initializer"); + var variable = f.AddOpVariable(resultType, sclass, initializer); + variable.Operands.Span[1] = i.ResultId ?? -1; + buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); + SetOpNop(i.Words.Span); + } + } + } + } + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs new file mode 100644 index 0000000000..ac515a402a --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs @@ -0,0 +1,505 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.PostProcessing; + +public struct IOVariableDecorator : INanoPass +{ + public void Apply(MultiBuffer buffer) + { + int inputLocation = -1; + int outputLocation = -1; + foreach (var i in buffer.Declarations) + { + if(i.OpCode == SDSLOp.OpSDSLIOVariable) + { + var execution = (ExecutionModel)(i.GetOperand("executionModel")?.Words ?? -1); + var storage = (StorageClass)(i.GetOperand("storageclass")?.Words ?? -1); + var semantic = i.GetOperand("semantic")?.Value ?? throw new NotImplementedException(); + if (semantic == "SV_Position") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage,execution) switch + { + (StorageClass.Input, ExecutionModel.Fragment) => (int)BuiltIn.FragCoord, + (StorageClass.Input or StorageClass.Output, _) + => (int)BuiltIn.Position, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_ClipDistance") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Input or StorageClass.Output, _) + => (int)BuiltIn.ClipDistance, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_CullDistance") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Input or StorageClass.Output, _) + => (int)BuiltIn.CullDistance, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_VertexID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Input, ExecutionModel.Vertex) + => (int)BuiltIn.VertexIndex, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_InstanceID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Input, ExecutionModel.Vertex) + => (int)BuiltIn.InstanceIndex, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_Depth" || semantic == "SV_DepthGreaterEqual" || semantic == "SV_DepthLessEqual") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Output,ExecutionModel.Fragment) + => (int)BuiltIn.FragDepth, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_IsFrontFace") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + (StorageClass.Input, ExecutionModel.Fragment) + => (int)BuiltIn.FrontFacing, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_DispatchThreadID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.GLCompute + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + or ExecutionModel.TaskEXT + or ExecutionModel.TaskNV + ) + => (int)BuiltIn.GlobalInvocationId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_GroupID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.GLCompute + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + or ExecutionModel.TaskEXT + or ExecutionModel.TaskNV + ) + => (int)BuiltIn.WorkgroupId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_GroupThreadID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.GLCompute + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + or ExecutionModel.TaskEXT + or ExecutionModel.TaskNV + ) + => (int)BuiltIn.LocalInvocationId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_GroupIndex") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.GLCompute + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + or ExecutionModel.TaskEXT + or ExecutionModel.TaskNV + ) + => (int)BuiltIn.LocalInvocationIndex, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_OutputControlPointID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.TessellationControl + ) + => (int)BuiltIn.InvocationId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_GSInstanceID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Geometry + ) + => (int)BuiltIn.InvocationId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_DomainLocation") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.TessellationEvaluation + ) + => (int)BuiltIn.TessCoord, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_PrimitiveID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.TessellationControl + or ExecutionModel.TessellationEvaluation + or ExecutionModel.Geometry + or ExecutionModel.Fragment + ) + or( + StorageClass.Output, + ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + or ExecutionModel.Geometry + ) + => (int)BuiltIn.TessCoord, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_TessFactor") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.TessellationControl + ) + => (int)BuiltIn.TessLevelOuter, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_InsideTessFactor") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.TessellationControl + ) + => (int)BuiltIn.TessLevelInner, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_SampleIndex") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + => (int)BuiltIn.SampleId, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_StencilRef") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Output, + ExecutionModel.Fragment + ) + => (int)BuiltIn.FragStencilRefEXT, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_Barycentrics") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + => (int)BuiltIn.BaryCoordKHR, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_RenderTargetArrayIndex") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + or + ( + StorageClass.Output, + ExecutionModel.Geometry + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + ) + => (int)BuiltIn.Layer, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_ViewportArrayIndex") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + or + ( + StorageClass.Output, + ExecutionModel.Geometry + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + ) + => (int)BuiltIn.ViewportIndex, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_Coverage") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input or StorageClass.Output, + ExecutionModel.Fragment + ) + => (int)BuiltIn.SampleMask, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_InnerCoverage") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + => (int)BuiltIn.FullyCoveredEXT, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_ViewID") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Input, + ExecutionModel.Vertex + or ExecutionModel.TessellationControl + or ExecutionModel.TessellationEvaluation + or ExecutionModel.Geometry + or ExecutionModel.Fragment + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + ) + => (int)BuiltIn.ViewIndex, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_ShadingRate") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Output, + ExecutionModel.Vertex + or ExecutionModel.Geometry + or ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + ) + => (int)BuiltIn.PrimitiveShadingRateKHR, + ( + StorageClass.Input, + ExecutionModel.Fragment + ) + => (int)BuiltIn.ShadingRateKHR, + _ => throw new NotImplementedException() + } + ); + } + else if (semantic == "SV_CullPrimitive") + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.BuiltIn, + (storage, execution) switch + { + ( + StorageClass.Output, + ExecutionModel.MeshEXT + or ExecutionModel.MeshNV + ) + => (int)BuiltIn.CullPrimitiveEXT, + _ => throw new NotImplementedException() + } + ); + } + else + { + buffer.AddOpDecorate( + i.ResultId ?? -1, + Decoration.Location, + (storage, execution) switch + { + (StorageClass.Input, _) + => ++inputLocation, + (StorageClass.Output, _) + => ++outputLocation, + _ => throw new NotImplementedException() + } + ); + } + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs new file mode 100644 index 0000000000..f02c9da405 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs @@ -0,0 +1,14 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + +public interface IPostProcessorSubPass +{ + void Apply(SpirvBuffer buffer, RefInstruction instruction); +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs new file mode 100644 index 0000000000..2423f0caae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs @@ -0,0 +1,41 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + + +/// +/// Offsets ids for each mixins inherited +/// +public struct IdRefOffsetter : INanoPass +{ + public IdRefOffsetter() { } + + public void Apply(MultiBuffer buffer) + { + //int offset = 0; + //int nextOffset = 0; + //foreach (var i in buffer) + //{ + // // if we hit a mixin name we reset stuff + // if (i.OpCode == SDSLOp.OpSDSLMixinName) + // { + // offset += nextOffset; + // nextOffset = 0; + // } + // else + // { + // if (i.ResultId != null) + // nextOffset = i.ResultId.Value; + // i.AsRef().OffsetIds(offset); + // } + //} + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs new file mode 100644 index 0000000000..2593e1d8ca --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs @@ -0,0 +1,42 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + +/// +/// Checks for duplicate memory models in case of multiple entry points +/// +public struct MemoryModelDuplicatesRemover : INanoPass +{ + + public void Apply(MultiBuffer buffer) + { + var found = false; + var wid = 0; + var span = buffer.Declarations.InstructionSpan; + while(wid < buffer.Declarations.Length) + { + if ((span[wid] & 0xFFFF) == (int)SDSLOp.OpMemoryModel) + { + if (!found) + found = true; + else + SetOpNop(span.Slice(wid, span[wid] >> 16)); + } + wid += span[wid] >> 16; + } + } + + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs new file mode 100644 index 0000000000..2c44736eae --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs @@ -0,0 +1,36 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + +public record struct OrderedSpvBuffer(SpirvBuffer Buffer) +{ + public readonly OrderedEnumerator GetEnumerator() => new(Buffer); +} + +/// +/// Merges mixins into one final spirv file +/// +public struct MixinMerger : INanoPass +{ + public readonly void Apply(MultiBuffer buffer) + { + //var temp = new SpirvBuffer(); + //var ordered = new OrderedSpvBuffer(buffer); + //foreach (var e in ordered) + // if(e.OpCode != SDSLOp.OpNop) + // temp.Add(e.Words.Span); + + //buffer.Replace(temp, out var dispose); + //if(dispose) + // temp.Dispose(); + //buffer.RecomputeBound(); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs new file mode 100644 index 0000000000..d75e8f140f --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs @@ -0,0 +1,48 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; + +namespace Stride.Shaders.Spirv.PostProcessing; + +/// +/// Nano pass merger/optimizer/compiler +/// +public static class PostProcessor +{ + public static SpirvBuffer Process(string mixinName) + { + var buffer = new MultiBuffer(); + var mixin = MixinSourceProvider.Get(mixinName); + var parents = MixinSourceProvider.GetMixinGraph(mixinName); + var bound = 0; + foreach(var p in parents) + { + foreach (var i in p.Instructions) + buffer.Duplicate(i.AsRef(), bound); + bound += p.Bound; + } + foreach(var i in mixin.Instructions) + buffer.Duplicate(i.AsRef(), bound); + Apply(buffer); + + return new(buffer); + } + + static void Apply(MultiBuffer buffer) + { + Apply(buffer); + Apply(buffer); + Apply(buffer); + Apply(buffer); + Apply(buffer); + Apply(buffer); + Apply(buffer); + } + + static void Apply(MultiBuffer buffer) + where T : struct, INanoPass + { + var p = new T(); + p.Apply(buffer); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs new file mode 100644 index 0000000000..8a1c6bcff2 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs @@ -0,0 +1,46 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + +/// +/// Removes SDSL specific instructions +/// +public struct SDSLOpRemover : INanoPass +{ + + public void Apply(MultiBuffer buffer) + { + var decl = new InstructionEnumerator(buffer.Declarations); + while(decl.MoveNext()) + { + var i = decl.Current; + if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) + SetOpNop(i.AsRef()); + } + foreach (var (_, f) in buffer.Functions) + { + var func = new InstructionEnumerator(f); + while(func.MoveNext()) + { + var i = func.Current; + if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) + SetOpNop(i.AsRef()); + } + } + } + + static void SetOpNop(RefInstruction i) + { + i.Words[0] = i.WordCount << 16; + i.Operands.Clear(); + } + +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs new file mode 100644 index 0000000000..c2f05efe99 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs @@ -0,0 +1,206 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Processing; + + + + +/// +/// Remove duplicate simple types. +/// Should be applied before the IdRefOffsetter. +/// +public struct TypeDuplicateRemover : INanoPass +{ + + public readonly void Apply(MultiBuffer buffer) + { + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) + { + foreach (var j in buffer.Declarations.UnorderedInstructions) + { + if ( + (j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words.Span); + } + } + } + } + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + if (i.OpCode == SDSLOp.OpTypeVector) + { + foreach (var j in buffer.Declarations.UnorderedInstructions) + { + if ( + j.OpCode == SDSLOp.OpTypeVector + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words.Span); + } + } + } + } + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + if (i.OpCode == SDSLOp.OpTypeMatrix) + { + foreach (var j in buffer.Declarations.UnorderedInstructions) + { + if ( + j.OpCode == SDSLOp.OpTypeMatrix + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words.Span); + } + } + } + } + //var idx1 = 0; + //// First base types + //foreach (var i in buffer.Declarations.UnorderedInstructions) + //{ + // if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) + // { + // var idx2 = 0; + // foreach (var j in buffer.Declarations) + // { + // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) + // { + // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + // SetOpNop(j.Words.Span); + // } + // idx2 += 1; + // } + // } + // else if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeBool) + // { + // var idx2 = 0; + // foreach (var j in buffer.Declarations) + // { + // if (j.OpCode == i.OpCode && idx1 != idx2) + // { + // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + // SetOpNop(j.Words.Span); + // } + // idx2 += 1; + // } + // } + // idx1 += 1; + //} + //idx1 = 0; + //// Then vectors + //foreach (var i in buffer.Declarations.UnorderedInstructions) + //{ + // if (i.OpCode == SDSLOp.OpTypeVector) + // { + // var idx2 = 0; + // foreach (var j in buffer.Declarations) + // { + // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) + // { + // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + // SetOpNop(j.Words.Span); + // } + // idx2 += 1; + // } + // } + // idx1 += 1; + //} + //idx1 = 0; + + //// Then matrices + //foreach (var i in buffer.Declarations.UnorderedInstructions) + //{ + // if (i.OpCode == SDSLOp.OpTypeMatrix) + // { + // var idx2 = 0; + // foreach (var j in buffer.Declarations) + // { + // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) + // { + // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + // SetOpNop(j.Words.Span); + // } + // idx2 += 1; + // } + // } + // idx1 += 1; + //} + + } + + static void ReplaceRefs(int from, int to, MultiBuffer buffer) + { + foreach (var i in buffer.Declarations.UnorderedInstructions) + { + var opcode = i.OpCode; + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + if (op.Words[0] == from || op.Words[1] == from) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + foreach (var (_, f) in buffer.Functions) + foreach (var i in f.UnorderedInstructions) + { + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + if (op.Words[0] == from || op.Words[1] == from) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + } + + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj new file mode 100644 index 0000000000..288f00d98c --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md new file mode 100644 index 0000000000..7976094404 --- /dev/null +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md @@ -0,0 +1,35 @@ +MixinName "MixinA" +%1 = OpTypeFloat 32 +%2 = OpTypeVector %1 2 +MixinEnd +MixinName "MixinB" +MixinInherit "MixinA" +%1 MixinImport "MixinA" 1 +%2 = OpTypeVector %1 3 +%3 = OpTypeMatrix %2 3 +MixinEnd +MixinName "MixinC" +MixinInherit "MixinA" +%1 MixinImport "MixinA" 1 +%2 = OpTypeVector %1 4 +%3 = OpTypeMatrix %2 4 +MixinEnd + + + +MixinName "MixinA" --> OpNop +%1 = OpTypeFloat 32 --> Keep +%2 = OpTypeVector %1 2 --> Keep +MixinEnd --> OpNop +MixinName "MixinB" --> OpNop +MixinInherit "MixinA" --> OpNop +%1 MixinImport "MixinA" 1 --> Keep + offset id +%2 = OpTypeVector %1 3 --> Keep + offset id +%3 = OpTypeMatrix %2 3 +MixinEnd +MixinName "MixinC" +MixinInherit "MixinA" +%1 MixinImport "MixinA" 1 +%2 = OpTypeVector %1 4 +%3 = OpTypeMatrix %2 4 +MixinEnd \ No newline at end of file From 6ca06f68c47f00c0ce29866c68eb3b3d4737993f Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 16 Oct 2024 16:57:30 +0200 Subject: [PATCH 0329/1182] working on parser + tests --- .gitignore | 1 + SDSL.sln | 7 +++ .../Stride.Shaders.LSP.Test.csproj | 4 ++ .../Examples.cs | 2 +- .../Stride.Shaders.Parsing.Experiments.csproj | 7 +++ .../ParsingTests.cs | 18 +++++++ .../Stride.Shaders.Parsing.Tests.csproj | 27 +++++++++++ .../SDFX/AST/Effect.Parameters.cs | 4 +- .../SDFX/Parsers/EffectFileParsers.cs | 0 .../SDFX/Parsers/EffectStatementParsers.cs | 21 +++++++- .../SDFX/Parsers/ParamsParsers.cs | 48 +++++++++++++++---- .../SDSL/AST/Literals.cs | 2 + .../ShaderParsers/CompositionParsers.cs | 2 +- 13 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 src/Stride.Shaders.Parsing.Tests/ParsingTests.cs create mode 100644 src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs diff --git a/.gitignore b/.gitignore index 64a1afc606..62f9f8f1a2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ obj/ .vs/ .antlr/ /src/SDSLParserExample/Properties/launchSettings.json +assets/Stride \ No newline at end of file diff --git a/SDSL.sln b/SDSL.sln index 199fbe3fdf..93758513aa 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Genera EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core.Benchmarks", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core.Benchmarks\Stride.Shaders.Spirv.Core.Benchmarks.csproj", "{8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Parsing.Tests\Stride.Shaders.Parsing.Tests.csproj", "{41050DB9-A819-4FC7-9D46-0ED054CAE7CB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -76,6 +78,10 @@ Global {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.Build.0 = Release|Any CPU + {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {6641B2F9-0E20-43E5-BF88-44B02B32117B} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} @@ -89,5 +95,6 @@ Global {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} {1205976E-A945-4475-AD87-C63527D5A63A} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} + {41050DB9-A819-4FC7-9D46-0ED054CAE7CB} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} EndGlobalSection EndGlobal diff --git a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj index 2150e3797b..370311e009 100644 --- a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj +++ b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj @@ -1,5 +1,9 @@  + + + + Exe net8.0 diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 8e1fe03546..025707bbc6 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -79,7 +79,7 @@ public static void SpvOpt() public static void ParseSDSL() { - var text = File.ReadAllText(@"C:\Users\youness_kafia\Documents\dotnetProjs\SDSL\assets\SDSL\Commented.sdsl"); + var text = File.ReadAllText("./assets/Stride/SDSL/B.sdsl"); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj index b54aab4b84..bae2639338 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj +++ b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj @@ -12,4 +12,11 @@ true + + + + diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs new file mode 100644 index 0000000000..d99abe63e4 --- /dev/null +++ b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs @@ -0,0 +1,18 @@ +namespace Stride.Shaders.Parsing.Tests; + +public class ParsingTests1 +{ + [Theory] + [InlineData("assets/SDSL/Commented.sdsl")] + public void Test1(string path) + { + var shader = File.ReadAllText(path); + Assert.True(shader.Length > 0); + } + + [Fact] + public void Test2() + { + Assert.True(true); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj new file mode 100644 index 0000000000..7348bce756 --- /dev/null +++ b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs index cfd8a5cfa3..fc8dd61e69 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs @@ -3,9 +3,9 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectParameters(Identifier name, TextLocation info) : Node(info) +public class EffectParameters(TypeName name, TextLocation info) : Node(info) { - public Identifier Name { get; set; } = name; + public TypeName Name { get; set; } = name; public List Parameters { get; set; } = []; } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index b93ce38db3..43fc6d2c82 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -1,5 +1,6 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX.Parsers; @@ -10,11 +11,29 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { throw new NotImplementedException(); } +} +public record struct UsingParamsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if(Terminals.Literal("using", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if(Terminals.Literal("params", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _, orError : new("Expected space here", scanner.CreateError(scanner.Position)))) + { + if(LiteralsParser.Identifier(ref scanner, result, out var identifier)) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } } - public record struct MixinComposeParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out ComposeMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index c40d65f80f..9bc5300083 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -6,39 +6,69 @@ namespace Stride.Shaders.Parsing.SDFX.Parsers; public record struct ParamsParsers : IParser { - public bool Match(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Terminals.Literal("params", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { - if(LiteralsParser.TypeName(ref scanner, result, out var paramsName)) + if (LiteralsParser.TypeName(ref scanner, result, out var paramsName)) { + parsed = new(paramsName, new()); CommonParsers.Spaces0(ref scanner, result, out _); - if(Terminals.Char('{', ref scanner, advance: true)) + if (Terminals.Char('{', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - // while() + while (!scanner.IsEof) + { + if (Parameter(ref scanner, result, out var p)) + parsed.Parameters.Add(p); + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else + CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected parameter definition or closing curly brace", scanner.CreateError(scanner.Position))); + CommonParsers.Spaces0(ref scanner, result, out _); + } } } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + public static bool Parameter(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new ParameterParser().Match(ref scanner, result, out parsed, orError); } public record struct ParameterParser : IParser { - public bool Match(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if(LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _)) { - if(LiteralsParser.Identifier(ref scanner, result, out var identifier)) + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (!Terminals.Char(';', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(scanner.Position))); + parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), expression); + return true; + } + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("expected assignment or semi colon", scanner.CreateError(scanner.Position))); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index e8b4c20a52..7fa8287cc0 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -102,4 +102,6 @@ public override string ToString() { return $"{Name}"; } + + public static implicit operator string(TypeName tn) => tn.Name; } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 3c4a6dab0f..66f5861a6a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -6,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct CompositionParser() : IParser { - public bool Match(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Terminals.Literal("compose", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) From 99f3fea6c8a3c41cd844e89d99aa141066ba94bc Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 16 Oct 2024 16:57:46 +0200 Subject: [PATCH 0330/1182] adding test files --- .gitignore | 3 +- .../SDFX/AmbientOcclusionBlurEffect.sdfx | 15 + .../SDFX/AmbientOcclusionRawAOEffect.sdfx | 15 + .../Stride/SDFX/BackgroundVelocityEffect.sdfx | 21 + assets/Stride/SDFX/CoCMapBlurEffect.sdfx | 15 + assets/Stride/SDFX/ColorCombinerEffect.sdfx | 12 + .../SDFX/ColorTransformGroupEffect.sdfx | 28 + assets/Stride/SDFX/CombineFrontCoCEffect.sdfx | 16 + .../SDFX/CombineLevelsFromCoCEffect.sdfx | 15 + assets/Stride/SDFX/ComputeEffectShader.sdfx | 23 + .../Stride/SDFX/ComputeShaderTestEffect.sdfx | 17 + assets/Stride/SDFX/CubemapEffect.sdfx | 50 + assets/Stride/SDFX/CustomEffect.sdfx | 27 + .../SDFX/DepthAwareDirectionalBlurEffect.sdfx | 16 + assets/Stride/SDFX/DepthMinMaxEffect.sdfx | 12 + assets/Stride/SDFX/FXAAShaderEffect.sdfx | 14 + assets/Stride/SDFX/FlareArtifactEffect.sdfx | 15 + assets/Stride/SDFX/GaussianBlurEffect.sdfx | 15 + assets/Stride/SDFX/ImageScalerEffect.sdfx | 18 + .../Stride/SDFX/LambertianPrefilteringSH.sdfx | 26 + ...mbertianPrefilteringSHNoComputeEffect.sdfx | 12 + assets/Stride/SDFX/LightShaftsEffect.sdfx | 14 + assets/Stride/SDFX/LightSkyboxEffect.sdfx | 26 + assets/Stride/SDFX/LightStreakEffect.sdfx | 15 + assets/Stride/SDFX/MSAAResolverEffect.sdfx | 28 + .../Stride/SDFX/McIntoshOptimizedEffect.sdfx | 18 + .../SDFX/ModelComponentPickingEffect.sdfx | 11 + .../SDFX/MultiTexturesSpriteEffect.sdfx | 9 + .../SDFX/MultipleRenderTargetsEffect.sdfx | 11 + assets/Stride/SDFX/ParticleBaseEffect.sdfx | 15 + assets/Stride/SDFX/ParticleCustomEffect.sdfx | 32 + assets/Stride/SDFX/ParticleEffect.sdfx | 18 + assets/Stride/SDFX/Picking.sdfx | 10 + assets/Stride/SDFX/PreviewTexture.sdfx | 25 + .../SDFX/RadiancePrefilteringGGXEffect.sdfx | 17 + ...adiancePrefilteringGGXNoComputeEffect.sdfx | 17 + assets/Stride/SDFX/SceneEditorParameters.sdfx | 16 + assets/Stride/SDFX/SelectedSprite.sdfx | 12 + assets/Stride/SDFX/ShadowMapCaster.sdfx | 26 + .../Stride/SDFX/ShadowMapCasterCubeMap.sdfx | 28 + .../SDFX/ShadowMapCasterParaboloid.sdfx | 28 + assets/Stride/SDFX/SimpleEffect.sdfx | 9 + assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx | 28 + .../SDFX/SphericalHarmonicsParameters.sdfx | 10 + .../SphericalHarmonicsRendererEffect.sdfx | 12 + assets/Stride/SDFX/SpriteBatch.sdfx | 13 + .../SDFX/StrideBakeLightProbeEffect.sdfx | 12 + .../StrideEditorForwardShadingEffect.sdfx | 54 + .../SDFX/StrideEditorHighlightingEffect.sdfx | 14 + .../StrideEditorMaterialPreviewEffect.sdfx | 14 + assets/Stride/SDFX/StrideEffectBase.sdfx | 181 ++ .../SDFX/StrideForwardShadingEffect.sdfx | 77 + .../SDFX/StrideWireframeShadingEffect.sdfx | 17 + .../SDFX/SubsurfaceScatteringBlurEffect.sdfx | 17 + assets/Stride/SDFX/ToGlslEffect.sdfx | 9 + assets/Stride/SDFX/ToneMapEffect.sdfx | 19 + assets/Stride/SDFX/UIEffect.sdfx | 13 + .../SDFX/test_mixin_complex_params.sdfx | 47 + .../Stride/SDFX/test_mixin_compose_keys.sdfx | 37 + assets/Stride/SDFX/test_mixin_simple.sdfx | 11 + .../Stride/SDFX/test_mixin_simple_child.sdfx | 18 + .../SDFX/test_mixin_simple_child_params.sdfx | 33 + .../Stride/SDFX/test_mixin_simple_clone.sdfx | 19 + .../SDFX/test_mixin_simple_compose.sdfx | 12 + .../Stride/SDFX/test_mixin_simple_params.sdfx | 38 + assets/Stride/SDSL/A.sdsl | 18 + assets/Stride/SDSL/AdditiveLightEffect.sdsl | 11 + assets/Stride/SDSL/AdditiveLightShader.sdsl | 22 + .../SDSL/AmbientOcclusionBlurShader.sdsl | 64 + .../SDSL/AmbientOcclusionRawAOShader.sdsl | 168 ++ .../SDSL/ApplyAmbientOcclusionShader.sdsl | 30 + assets/Stride/SDSL/B.sdsl | 5 + assets/Stride/SDSL/BRDFMicrofacet.sdsl | 227 ++ .../Stride/SDSL/BackgroundCubemapShader.sdsl | 14 + assets/Stride/SDSL/BackgroundShader.sdsl | 13 + assets/Stride/SDSL/BackgroundVelocity.sdsl | 28 + assets/Stride/SDSL/BakeLightProbeShader.sdsl | 29 + assets/Stride/SDSL/BaseTestChild.sdsl | 15 + assets/Stride/SDSL/BaseTestInter.sdsl | 10 + assets/Stride/SDSL/BaseTestParent.sdsl | 8 + assets/Stride/SDSL/BasicMixin.sdsl | 16 + assets/Stride/SDSL/BasicMixin2.sdsl | 8 + assets/Stride/SDSL/BlendUtils.sdsl | 63 + .../SDSL/BloomAfterimageCombineShader.sdsl | 24 + assets/Stride/SDSL/BloomAfterimageShader.sdsl | 32 + assets/Stride/SDSL/BrightFilterShader.sdsl | 40 + assets/Stride/SDSL/BufferToTexture.sdsl | 54 + .../Stride/SDSL/BufferToTextureColumns.sdsl | 83 + .../SDSL/BufferToTextureColumnsEffect.sdsl | 28 + assets/Stride/SDSL/BufferToTextureEffect.sdsl | 28 + assets/Stride/SDSL/C.sdsl | 5 + assets/Stride/SDSL/C1.sdsl | 5 + assets/Stride/SDSL/Camera.sdsl | 19 + assets/Stride/SDSL/CameraCube.sdsl | 33 + .../SDSL/CameraOrientationGizmoShader.sdsl | 11 + assets/Stride/SDSL/Child.sdsl | 15 + assets/Stride/SDSL/ChildError.sdsl | 9 + assets/Stride/SDSL/CircleOfConfusion.sdsl | 35 + assets/Stride/SDSL/ClearBuffer.sdsl | 14 + assets/Stride/SDSL/CloneTestBase.sdsl | 6 + assets/Stride/SDSL/CloneTestExtern.sdsl | 9 + assets/Stride/SDSL/CloneTestRoot.sdsl | 12 + assets/Stride/SDSL/CoCLinearDepthShader.sdsl | 29 + assets/Stride/SDSL/CoCMapBlurShader.sdsl | 70 + assets/Stride/SDSL/ColorBase.sdsl | 10 + assets/Stride/SDSL/ColorCombinerShader.sdsl | 43 + .../SDSL/ColorTransformGroupShader.sdsl | 20 + assets/Stride/SDSL/ColorTransformShader.sdsl | 16 + assets/Stride/SDSL/ColorUtility.sdsl | 82 + assets/Stride/SDSL/CombineFrontCoCShader.sdsl | 68 + .../SDSL/CombineLevelsFromCoCShader.sdsl | 123 + .../Stride/SDSL/CompilationErrorShader.sdsl | 15 + assets/Stride/SDSL/ComputeColor.sdsl | 12 + assets/Stride/SDSL/ComputeColor3.sdsl | 12 + assets/Stride/SDSL/ComputeColorAdd.sdsl | 15 + assets/Stride/SDSL/ComputeColorAdd3.sdsl | 15 + assets/Stride/SDSL/ComputeColorAdd3ds.sdsl | 27 + assets/Stride/SDSL/ComputeColorAddMaya.sdsl | 25 + assets/Stride/SDSL/ComputeColorAverage.sdsl | 27 + assets/Stride/SDSL/ComputeColorCave.sdsl | 20 + assets/Stride/SDSL/ComputeColorColor.sdsl | 35 + assets/Stride/SDSL/ComputeColorColorBurn.sdsl | 17 + .../Stride/SDSL/ComputeColorColorDodge.sdsl | 30 + .../SDSL/ComputeColorConstantColorLink.sdsl | 22 + .../SDSL/ComputeColorConstantFloatLink.sdsl | 21 + .../Stride/SDSL/ComputeColorConstantLink.sdsl | 18 + assets/Stride/SDSL/ComputeColorDarken3ds.sdsl | 24 + .../Stride/SDSL/ComputeColorDarkenMaya.sdsl | 27 + .../Stride/SDSL/ComputeColorDesaturate.sdsl | 24 + .../SDSL/ComputeColorDifference3ds.sdsl | 27 + .../SDSL/ComputeColorDifferenceMaya.sdsl | 26 + assets/Stride/SDSL/ComputeColorDivide.sdsl | 31 + assets/Stride/SDSL/ComputeColorExclusion.sdsl | 27 + assets/Stride/SDSL/ComputeColorFixed.sdsl | 15 + .../Stride/SDSL/ComputeColorFromStream.sdsl | 13 + assets/Stride/SDSL/ComputeColorHardLight.sdsl | 30 + assets/Stride/SDSL/ComputeColorHardMix.sdsl | 28 + assets/Stride/SDSL/ComputeColorHue.sdsl | 35 + .../Stride/SDSL/ComputeColorIlluminate.sdsl | 24 + assets/Stride/SDSL/ComputeColorIn.sdsl | 23 + assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl | 17 + .../Stride/SDSL/ComputeColorLighten3ds.sdsl | 24 + .../Stride/SDSL/ComputeColorLightenMaya.sdsl | 26 + .../Stride/SDSL/ComputeColorLinearBurn.sdsl | 32 + .../Stride/SDSL/ComputeColorLinearDodge.sdsl | 27 + assets/Stride/SDSL/ComputeColorMask.sdsl | 23 + assets/Stride/SDSL/ComputeColorMask3ds.sdsl | 23 + .../SDSL/ComputeColorMaterialAlphaBlend.sdsl | 15 + assets/Stride/SDSL/ComputeColorMultiply.sdsl | 17 + .../Stride/SDSL/ComputeColorMultiply3ds.sdsl | 27 + .../Stride/SDSL/ComputeColorMultiplyMaya.sdsl | 24 + assets/Stride/SDSL/ComputeColorOne.sdsl | 12 + assets/Stride/SDSL/ComputeColorOut.sdsl | 23 + assets/Stride/SDSL/ComputeColorOutdoor.sdsl | 21 + assets/Stride/SDSL/ComputeColorOver3ds.sdsl | 25 + assets/Stride/SDSL/ComputeColorOverMaya.sdsl | 25 + assets/Stride/SDSL/ComputeColorOverlay.sdsl | 20 + .../Stride/SDSL/ComputeColorOverlay3ds.sdsl | 30 + assets/Stride/SDSL/ComputeColorParameter.sdsl | 15 + assets/Stride/SDSL/ComputeColorPinLight.sdsl | 30 + assets/Stride/SDSL/ComputeColorRadial.sdsl | 24 + assets/Stride/SDSL/ComputeColorRed.sdsl | 13 + assets/Stride/SDSL/ComputeColorSaturate.sdsl | 24 + .../Stride/SDSL/ComputeColorSaturation.sdsl | 34 + assets/Stride/SDSL/ComputeColorScaler.sdsl | 12 + assets/Stride/SDSL/ComputeColorScreen.sdsl | 23 + assets/Stride/SDSL/ComputeColorSoftLight.sdsl | 37 + assets/Stride/SDSL/ComputeColorStream.sdsl | 11 + .../SDSL/ComputeColorSubstituteAlpha.sdsl | 15 + .../ComputeColorSubstituteAlphaWithColor.sdsl | 15 + assets/Stride/SDSL/ComputeColorSubtract.sdsl | 15 + .../Stride/SDSL/ComputeColorSubtract3ds.sdsl | 27 + .../Stride/SDSL/ComputeColorSubtractMaya.sdsl | 24 + assets/Stride/SDSL/ComputeColorSynthetic.sdsl | 9 + assets/Stride/SDSL/ComputeColorTexture.sdsl | 18 + ...omputeColorTextureDynamicScaledOffset.sdsl | 24 + .../SDSL/ComputeColorTextureLodSampler.sdsl | 24 + ...rTextureLodScaledOffsetDynamicSampler.sdsl | 36 + ...uteColorTextureLodScaledOffsetSampler.sdsl | 27 + .../ComputeColorTextureLodScaledSampler.sdsl | 26 + .../SDSL/ComputeColorTextureRepeat.sdsl | 19 + .../SDSL/ComputeColorTextureSampler.sdsl | 23 + .../SDSL/ComputeColorTextureScaled.sdsl | 18 + .../SDSL/ComputeColorTextureScaledOffset.sdsl | 19 + ...olorTextureScaledOffsetDynamicSampler.sdsl | 35 + ...ureScaledOffsetDynamicSamplerRandomUV.sdsl | 89 + ...omputeColorTextureScaledOffsetSampler.sdsl | 26 + .../ComputeColorTextureScaledSampler.sdsl | 25 + .../SDSL/ComputeColorTextureScroll.sdsl | 23 + assets/Stride/SDSL/ComputeColorThreshold.sdsl | 20 + assets/Stride/SDSL/ComputeColorValue.sdsl | 32 + assets/Stride/SDSL/ComputeColorWave.sdsl | 11 + .../Stride/SDSL/ComputeColorWaveNormal.sdsl | 26 + assets/Stride/SDSL/ComputeColorWhite.sdsl | 19 + assets/Stride/SDSL/ComputeShaderBase.sdsl | 69 + assets/Stride/SDSL/ComputeShaderTest.sdsl | 31 + .../SDSL/ComputeSphericalHarmonics.sdsl | 24 + assets/Stride/SDSL/ConstantBufferTest.sdsl | 22 + assets/Stride/SDSL/CubemapSprite.sdsl | 13 + assets/Stride/SDSL/CubemapUtils.sdsl | 97 + assets/Stride/SDSL/CustomFogEffect.sdsl | 40 + assets/Stride/SDSL/CustomShader.sdsl | 22 + assets/Stride/SDSL/CyclicTest.sdsl | 6 + assets/Stride/SDSL/DataPacking.sdsl | 98 + assets/Stride/SDSL/DeepExtern.sdsl | 6 + assets/Stride/SDSL/DeepExternTest.sdsl | 12 + .../SDSL/DepthAwareDirectionalBlurShader.sdsl | 20 + .../SDSL/DepthAwareDirectionalBlurUtil.sdsl | 96 + assets/Stride/SDSL/DepthBase.sdsl | 39 + assets/Stride/SDSL/DepthMinMaxShader.sdsl | 69 + assets/Stride/SDSL/DirectLightGroup.sdsl | 70 + assets/Stride/SDSL/DirectLightGroupArray.sdsl | 12 + assets/Stride/SDSL/DirectLightGroupFixed.sdsl | 18 + .../Stride/SDSL/DirectLightGroupPerDraw.sdsl | 23 + .../Stride/SDSL/DirectLightGroupPerView.sdsl | 23 + assets/Stride/SDSL/Dither.sdsl | 37 + assets/Stride/SDSL/DynamicSampler.sdsl | 16 + assets/Stride/SDSL/DynamicTexture.sdsl | 16 + assets/Stride/SDSL/DynamicTextureCube.sdsl | 16 + assets/Stride/SDSL/DynamicTextureStream.sdsl | 12 + assets/Stride/SDSL/Effect.sdsl | 38 + assets/Stride/SDSL/EffectCompiling.sdsl | 15 + assets/Stride/SDSL/EnvironmentLight.sdsl | 16 + assets/Stride/SDSL/EnvironmentLightArray.sdsl | 12 + assets/Stride/SDSL/ExternClone.sdsl | 8 + assets/Stride/SDSL/ExternCloneTest.sdsl | 15 + assets/Stride/SDSL/ExternMixin.sdsl | 11 + assets/Stride/SDSL/ExternTest.sdsl | 14 + assets/Stride/SDSL/FXAAShader.sdsl | 2067 +++++++++++++++++ assets/Stride/SDSL/FilmGrainShader.sdsl | 123 + assets/Stride/SDSL/FlareArtifactShader.sdsl | 72 + assets/Stride/SDSL/FlareReplicate.sdsl | 66 + assets/Stride/SDSL/FlattenLayers.sdsl | 21 + assets/Stride/SDSL/FogEffect.sdsl | 38 + assets/Stride/SDSL/ForEachTest.sdsl | 16 + assets/Stride/SDSL/GBuffer.sdsl | 17 + assets/Stride/SDSL/GBufferOutputNormals.sdsl | 16 + .../GBufferOutputSpecularColorRoughness.sdsl | 16 + ...tputSubsurfaceScatteringMaterialIndex.sdsl | 20 + assets/Stride/SDSL/GaussianBlurShader.sdsl | 32 + assets/Stride/SDSL/GenericCall.sdsl | 5 + assets/Stride/SDSL/GenericClass.sdsl | 25 + assets/Stride/SDSL/GenericClass2.sdsl | 23 + assets/Stride/SDSL/GenericExtern.sdsl | 6 + assets/Stride/SDSL/GenericTexcoord.sdsl | 6 + assets/Stride/SDSL/GeometryShaderTest.sdsl | 8 + assets/Stride/SDSL/Global.sdsl | 9 + assets/Stride/SDSL/GlobalVR.sdsl | 9 + assets/Stride/SDSL/HSVUtils.sdsl | 103 + assets/Stride/SDSL/Hammersley.sdsl | 26 + assets/Stride/SDSL/HammersleyTest.sdsl | 20 + assets/Stride/SDSL/HighlightShader.sdsl | 19 + .../Stride/SDSL/IComputeEnvironmentColor.sdsl | 16 + .../IMaterialCelShadingLightFunction.sdsl | 12 + .../SDSL/IMaterialHairDirectionFunction.sdsl | 10 + .../SDSL/IMaterialHairDiscardFunction.sdsl | 14 + ...IMaterialHairLightAttenuationFunction.sdsl | 10 + .../SDSL/IMaterialHairShadowingFunction.sdsl | 10 + ...SpecularMicrofacetEnvironmentFunction.sdsl | 15 + ...rialSpecularMicrofacetFresnelFunction.sdsl | 16 + ...rMicrofacetNormalDistributionFunction.sdsl | 15 + ...lSpecularMicrofacetVisibilityFunction.sdsl | 15 + assets/Stride/SDSL/IMaterialStreamBlend.sdsl | 14 + ...SubsurfaceScatteringScatteringProfile.sdsl | 14 + assets/Stride/SDSL/IMaterialSurface.sdsl | 14 + .../Stride/SDSL/IMaterialSurfaceDomain.sdsl | 11 + assets/Stride/SDSL/IMaterialSurfacePixel.sdsl | 11 + .../Stride/SDSL/IMaterialSurfaceShading.sdsl | 28 + .../Stride/SDSL/IMaterialSurfaceVertex.sdsl | 11 + assets/Stride/SDSL/IStreamInitializer.sdsl | 14 + assets/Stride/SDSL/IVoxelSampler.sdsl | 36 + assets/Stride/SDSL/ImageEffectShader.sdsl | 12 + assets/Stride/SDSL/ImageScalerShader.sdsl | 27 + assets/Stride/SDSL/ImportanceSamplingGGX.sdsl | 31 + assets/Stride/SDSL/InterfaceTest.sdsl | 9 + .../Stride/SDSL/InternalReferenceMixin.sdsl | 11 + ...ambertianPrefilteringSHNoComputePass1.sdsl | 77 + ...ambertianPrefilteringSHNoComputePass2.sdsl | 23 + .../SDSL/LambertianPrefilteringSHPass1.sdsl | 125 + .../SDSL/LambertianPrefilteringSHPass2.sdsl | 47 + .../SDSL/LevelCubeMapEnvironmentColor.sdsl | 19 + assets/Stride/SDSL/LightClustered.sdsl | 34 + .../Stride/SDSL/LightClusteredPointGroup.sdsl | 52 + .../Stride/SDSL/LightClusteredSpotGroup.sdsl | 54 + assets/Stride/SDSL/LightConstantWhite.sdsl | 18 + assets/Stride/SDSL/LightDirectional.sdsl | 17 + assets/Stride/SDSL/LightDirectionalGroup.sdsl | 30 + assets/Stride/SDSL/LightPoint.sdsl | 47 + assets/Stride/SDSL/LightPointGroup.sdsl | 45 + assets/Stride/SDSL/LightProbeShader.sdsl | 99 + assets/Stride/SDSL/LightShaftsShader.sdsl | 35 + assets/Stride/SDSL/LightSimpleAmbient.sdsl | 25 + assets/Stride/SDSL/LightSkyboxShader.sdsl | 49 + assets/Stride/SDSL/LightSpot.sdsl | 37 + .../SDSL/LightSpotAttenuationDefault.sdsl | 40 + .../SDSL/LightSpotAttenuationRectangular.sdsl | 40 + assets/Stride/SDSL/LightSpotGroup.sdsl | 54 + assets/Stride/SDSL/LightStreakShader.sdsl | 62 + assets/Stride/SDSL/LightStream.sdsl | 38 + assets/Stride/SDSL/LightTiling.sdsl | 71 + assets/Stride/SDSL/LightUtil.sdsl | 39 + assets/Stride/SDSL/LightVoxelEffect.sdsl | 34 + assets/Stride/SDSL/LightVoxelShader.sdsl | 45 + assets/Stride/SDSL/LocalSamples.sdsl | 6 + assets/Stride/SDSL/LuminanceLogShader.sdsl | 26 + .../Stride/SDSL/LuminanceToChannelShader.sdsl | 18 + assets/Stride/SDSL/LuminanceUtils.sdsl | 23 + .../Stride/SDSL/MSAADepthResolverShader.sdsl | 63 + assets/Stride/SDSL/MSAAResolverShader.sdsl | 224 ++ assets/Stride/SDSL/MacroTest.sdsl | 9 + assets/Stride/SDSL/MacroTestBase.sdsl | 9 + assets/Stride/SDSL/MacroTestChild.sdsl | 6 + assets/Stride/SDSL/MarchAttributes.sdsl | 6 + assets/Stride/SDSL/MarchAttributesEffect.sdsl | 18 + .../SDSL/MaterialCelShadingLightDefault.sdsl | 30 + .../SDSL/MaterialCelShadingLightRamp.sdsl | 20 + .../SDSL/MaterialDisplacementStream.sdsl | 19 + assets/Stride/SDSL/MaterialDomainStream.sdsl | 12 + .../SDSL/MaterialFrontBackBlendShader.sdsl | 33 + ...aterialHairDirectionFunctionBitangent.sdsl | 18 + .../MaterialHairDirectionFunctionTangent.sdsl | 15 + ...MaterialHairDiscardFunctionOpaquePass.sdsl | 25 + ...ialHairDiscardFunctionTransparentPass.sdsl | 25 + ...irLightAttenuationFunctionDirectional.sdsl | 48 + ...erialHairLightAttenuationFunctionNone.sdsl | 13 + ...terialHairShadowingFunctionScattering.sdsl | 46 + ...aterialHairShadowingFunctionShadowing.sdsl | 13 + assets/Stride/SDSL/MaterialHairShared.sdsl | 36 + .../SDSL/MaterialPixelShadingStream.sdsl | 43 + assets/Stride/SDSL/MaterialPixelStream.sdsl | 116 + ...alSpecularMicrofacetEnvironmentGGXLUT.sdsl | 27 + ...larMicrofacetEnvironmentGGXPolynomial.sdsl | 15 + ...pecularMicrofacetEnvironmentThinGlass.sdsl | 15 + ...MaterialSpecularMicrofacetFresnelNone.sdsl | 15 + ...erialSpecularMicrofacetFresnelSchlick.sdsl | 15 + ...ialSpecularMicrofacetFresnelThinGlass.sdsl | 15 + ...rMicrofacetNormalDistributionBeckmann.sdsl | 15 + ...icrofacetNormalDistributionBlinnPhong.sdsl | 15 + ...ecularMicrofacetNormalDistributionGGX.sdsl | 15 + ...cularMicrofacetVisibilityCookTorrance.sdsl | 15 + ...lSpecularMicrofacetVisibilityImplicit.sdsl | 15 + ...alSpecularMicrofacetVisibilityKelemen.sdsl | 15 + ...alSpecularMicrofacetVisibilityNeumann.sdsl | 15 + ...ularMicrofacetVisibilitySmithBeckmann.sdsl | 15 + ...icrofacetVisibilitySmithGGXCorrelated.sdsl | 15 + ...rofacetVisibilitySmithSchlickBeckmann.sdsl | 15 + ...arMicrofacetVisibilitySmithSchlickGGX.sdsl | 15 + assets/Stride/SDSL/MaterialStream.sdsl | 22 + .../SDSL/MaterialStreamAdditiveBlend.sdsl | 16 + .../SDSL/MaterialStreamLinearBlend.sdsl | 15 + .../SDSL/MaterialStreamNormalBlend.sdsl | 24 + ...tteringScatteringProfileCustomUniform.sdsl | 27 + ...tteringScatteringProfileCustomVarying.sdsl | 51 + ...urfaceScatteringScatteringProfileSkin.sdsl | 19 + assets/Stride/SDSL/MaterialSurfaceArray.sdsl | 17 + .../Stride/SDSL/MaterialSurfaceDiffuse.sdsl | 22 + .../MaterialSurfaceDiffuseMetalFlakes.sdsl | 31 + ...SurfaceDiffuseSpecularAlphaBlendColor.sdsl | 15 + .../SDSL/MaterialSurfaceDisplacement.sdsl | 22 + .../MaterialSurfaceDomainStageCompositor.sdsl | 22 + .../SDSL/MaterialSurfaceEmissiveShading.sdsl | 19 + .../SDSL/MaterialSurfaceGlossinessMap.sdsl | 23 + ...terialSurfaceGlossinessMapMetalFlakes.sdsl | 34 + .../MaterialSurfaceLightingAndShading.sdsl | 98 + .../Stride/SDSL/MaterialSurfaceMetalness.sdsl | 24 + .../Stride/SDSL/MaterialSurfaceNormalMap.sdsl | 33 + .../MaterialSurfaceNormalStreamShading.sdsl | 15 + .../MaterialSurfacePixelStageCompositor.sdsl | 28 + ...erialSurfaceSetStreamFromComputeColor.sdsl | 14 + .../SDSL/MaterialSurfaceShadingBlend.sdsl | 16 + ...terialSurfaceShadingDiffuseCelShading.sdsl | 51 + .../MaterialSurfaceShadingDiffuseHair.sdsl | 129 + .../MaterialSurfaceShadingDiffuseLambert.sdsl | 33 + ...erialSurfaceShadingSpecularBlinnPhong.sdsl | 21 + ...erialSurfaceShadingSpecularCelShading.sdsl | 42 + .../MaterialSurfaceShadingSpecularHair.sdsl | 374 +++ ...erialSurfaceShadingSpecularMicrofacet.sdsl | 40 + .../SDSL/MaterialSurfaceStreamShading.sdsl | 18 + .../SDSL/MaterialSurfaceStreamsBlend.sdsl | 25 + ...ialSurfaceSubsurfaceScatteringShading.sdsl | 74 + .../MaterialSurfaceTransmittanceShading.sdsl | 18 + ...aterialSurfaceTransparentAlphaDiscard.sdsl | 16 + .../MaterialSurfaceVertexDisplacement.sdsl | 23 + .../MaterialSurfaceVertexStageCompositor.sdsl | 23 + .../SDSL/MaterialTessellationStream.sdsl | 22 + ...aterialTransmittanceReflectanceStream.sdsl | 67 + assets/Stride/SDSL/MaterialVertexStream.sdsl | 12 + assets/Stride/SDSL/Math.sdsl | 123 + assets/Stride/SDSL/McIntoshCombineShader.sdsl | 22 + .../Stride/SDSL/McIntoshOptimizedShader.sdsl | 31 + assets/Stride/SDSL/MeshVelocity.sdsl | 37 + .../SDSL/MixinFunctionParamaterTest.sdsl | 8 + assets/Stride/SDSL/MixinNameClash.sdsl | 9 + assets/Stride/SDSL/MixinNoNameClash.sdsl | 9 + .../SDSL/ModelComponentPickingShader.sdsl | 26 + .../SDSL/MultiTexturesSpriteShader.sdsl | 9 + .../MultipleRenderTargetsEffectShader.sdsl | 16 + assets/Stride/SDSL/NonStageStreamTest.sdsl | 12 + assets/Stride/SDSL/NormalBase.sdsl | 24 + assets/Stride/SDSL/NormalFromMesh.sdsl | 27 + .../Stride/SDSL/NormalFromMeshInstanced.sdsl | 14 + .../Stride/SDSL/NormalFromNormalMapping.sdsl | 20 + .../NormalFromNormalMappingInstanced.sdsl | 20 + .../NormalFromNormalMappingTessellation.sdsl | 14 + ...romNormalMappingTessellationInstanced.sdsl | 14 + assets/Stride/SDSL/NormalMeshSkinning.sdsl | 13 + assets/Stride/SDSL/NormalPack.sdsl | 23 + assets/Stride/SDSL/NormalStream.sdsl | 22 + assets/Stride/SDSL/NormalUpdate.sdsl | 46 + assets/Stride/SDSL/NormalUtil.sdsl | 48 + .../Stride/SDSL/NormalVSSkinningFromMesh.sdsl | 13 + .../SDSL/NormalVSSkinningNormalMapping.sdsl | 13 + ...alVSSkinningNormalMappingTessellation.sdsl | 13 + assets/Stride/SDSL/OpaqueBase.sdsl | 21 + assets/Stride/SDSL/OutlineEffect.sdsl | 72 + assets/Stride/SDSL/Parent.sdsl | 14 + assets/Stride/SDSL/ParticleBase.sdsl | 132 ++ assets/Stride/SDSL/ParticleColor.sdsl | 20 + assets/Stride/SDSL/ParticleColorStream.sdsl | 25 + .../SDSL/ParticleComputeColorShader.sdsl | 26 + assets/Stride/SDSL/ParticleCustomShader.sdsl | 37 + assets/Stride/SDSL/ParticleUtilities.sdsl | 59 + assets/Stride/SDSL/PickingShader.sdsl | 23 + assets/Stride/SDSL/PointDepth.sdsl | 18 + assets/Stride/SDSL/PositionHStream4.sdsl | 9 + assets/Stride/SDSL/PositionStream.sdsl | 17 + assets/Stride/SDSL/PositionStream2.sdsl | 19 + assets/Stride/SDSL/PositionStream4.sdsl | 16 + .../Stride/SDSL/PositionVertexTransform.sdsl | 13 + assets/Stride/SDSL/PostEffectBoundingRay.sdsl | 98 + ...adiancePrefilteringGGXNoComputeShader.sdsl | 61 + .../SDSL/RadiancePrefilteringGGXShader.sdsl | 80 + assets/Stride/SDSL/RangeCompressorShader.sdsl | 31 + .../Stride/SDSL/RangeDecompressorShader.sdsl | 24 + .../RoughnessCubeMapEnvironmentColor.sdsl | 29 + assets/Stride/SDSL/SSLRBlurPass.sdsl | 87 + assets/Stride/SDSL/SSLRCombinePass.sdsl | 75 + assets/Stride/SDSL/SSLRCommon.sdsl | 103 + assets/Stride/SDSL/SSLRDepthPass.sdsl | 17 + assets/Stride/SDSL/SSLRRayTracePass.sdsl | 191 ++ assets/Stride/SDSL/SSLRResolvePass.sdsl | 108 + assets/Stride/SDSL/SSLRTemporalPass.sdsl | 87 + assets/Stride/SDSL/ScreenPositionBase.sdsl | 23 + assets/Stride/SDSL/SelectedSpriteShader.sdsl | 17 + assets/Stride/SDSL/SemanticTest.sdsl | 15 + assets/Stride/SDSL/ShaderBase.sdsl | 11 + assets/Stride/SDSL/ShaderBaseStream.sdsl | 35 + assets/Stride/SDSL/ShadingBase.sdsl | 73 + assets/Stride/SDSL/ShadingColor.sdsl | 15 + assets/Stride/SDSL/ShadowGroup.sdsl | 17 + .../SDSL/ShadowMapCasterAlphaDiscard.sdsl | 17 + .../SDSL/ShadowMapCasterAlphaDithered.sdsl | 39 + .../ShadowMapCasterCubeMapProjection.sdsl | 18 + .../SDSL/ShadowMapCasterNoPixelShader.sdsl | 15 + .../ShadowMapCasterParaboloidProjection.sdsl | 60 + assets/Stride/SDSL/ShadowMapCasterVsm.sdsl | 24 + assets/Stride/SDSL/ShadowMapCommon.sdsl | 26 + assets/Stride/SDSL/ShadowMapFilterBase.sdsl | 126 + .../Stride/SDSL/ShadowMapFilterDefault.sdsl | 45 + assets/Stride/SDSL/ShadowMapFilterPcf.sdsl | 285 +++ assets/Stride/SDSL/ShadowMapFilterVsm.sdsl | 30 + assets/Stride/SDSL/ShadowMapGroup.sdsl | 11 + assets/Stride/SDSL/ShadowMapReceiverBase.sdsl | 62 + .../SDSL/ShadowMapReceiverDirectional.sdsl | 118 + .../SDSL/ShadowMapReceiverPointCubeMap.sdsl | 113 + .../ShadowMapReceiverPointParaboloid.sdsl | 67 + assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl | 50 + assets/Stride/SDSL/ShadowStream.sdsl | 11 + .../Stride/SDSL/SharedTextureCoordinate.sdsl | 26 + .../Stride/SDSL/SignedDistanceFieldFont.sdsl | 48 + .../SDSL/SignedDistanceFieldFontShader.sdsl | 39 + assets/Stride/SDSL/Simple.sdsl | 6 + assets/Stride/SDSL/SimpleShader.sdsl | 20 + assets/Stride/SDSL/SkyboxShaderBase.sdsl | 23 + assets/Stride/SDSL/SkyboxShaderCubemap.sdsl | 17 + assets/Stride/SDSL/SkyboxShaderTexture.sdsl | 25 + assets/Stride/SDSL/SkyboxStream.sdsl | 10 + .../Stride/SDSL/SphericalHarmonicsBase.sdsl | 78 + .../SphericalHarmonicsEnvironmentColor.sdsl | 28 + .../SDSL/SphericalHarmonicsRenderer.sdsl | 36 + .../Stride/SDSL/SphericalHarmonicsUtils.sdsl | 70 + .../SDSL/SpotLightDataInternalShader.sdsl | 19 + assets/Stride/SDSL/Sprite3DBase.sdsl | 12 + assets/Stride/SDSL/SpriteAlphaCutoff.sdsl | 71 + assets/Stride/SDSL/SpriteBase.sdsl | 37 + assets/Stride/SDSL/SpriteBatchShader.sdsl | 55 + assets/Stride/SDSL/SpriteEffect.sdsl | 14 + .../Stride/SDSL/SpriteEffectExtTexture.sdsl | 102 + .../SDSL/SpriteEffectExtTextureRegular.sdsl | 27 + assets/Stride/SDSL/SpritePicking.sdsl | 18 + .../SpriteSignedDistanceFieldFontShader.sdsl | 12 + assets/Stride/SDSL/SpriteSuperSampler.sdsl | 40 + assets/Stride/SDSL/StageBase.sdsl | 7 + assets/Stride/SDSL/StageCallExtern.sdsl | 10 + assets/Stride/SDSL/StageDecl.sdsl | 6 + assets/Stride/SDSL/StageValueReference.sdsl | 12 + assets/Stride/SDSL/StageValueTest.sdsl | 11 + assets/Stride/SDSL/StaticCallMixin.sdsl | 10 + assets/Stride/SDSL/StaticMixin.sdsl | 10 + assets/Stride/SDSL/StaticStageCallTest.sdsl | 10 + assets/Stride/SDSL/StreamChild.sdsl | 9 + assets/Stride/SDSL/StreamError.sdsl | 16 + assets/Stride/SDSL/StreamParent0.sdsl | 6 + assets/Stride/SDSL/StreamParent1.sdsl | 6 + assets/Stride/SDSL/StreamParent2.sdsl | 7 + .../Stride/SDSL/StreamSolverExternTest.sdsl | 10 + assets/Stride/SDSL/StreamTest.sdsl | 70 + .../SDSL/StrideForwardShadingEffectVXGI.sdsl | 73 + assets/Stride/SDSL/StructuredBufferTest.sdsl | 14 + .../SDSL/SubsurfaceScatteringBlurShader.sdsl | 512 ++++ assets/Stride/SDSL/SwapUV.sdsl | 18 + assets/Stride/SDSL/TangentMeshSkinning.sdsl | 13 + .../Stride/SDSL/TemporalAntiAliasShader.sdsl | 275 +++ assets/Stride/SDSL/TessellationAE2.sdsl | 50 + assets/Stride/SDSL/TessellationAE3.sdsl | 50 + assets/Stride/SDSL/TessellationAE4.sdsl | 50 + assets/Stride/SDSL/TessellationBase.sdsl | 127 + assets/Stride/SDSL/TessellationFlat.sdsl | 49 + assets/Stride/SDSL/TessellationPN.sdsl | 171 ++ assets/Stride/SDSL/TessellationTest.sdsl | 22 + assets/Stride/SDSL/TestComputeColor.sdsl | 9 + assets/Stride/SDSL/TestComputeColor2.sdsl | 12 + .../Stride/SDSL/TestComputeColorRedirect.sdsl | 11 + assets/Stride/SDSL/TestComputeShader.sdsl | 56 + assets/Stride/SDSL/TestErrors.sdsl | 50 + assets/Stride/SDSL/TestExternArray.sdsl | 22 + assets/Stride/SDSL/TestGenerator.sdsl | 12 + assets/Stride/SDSL/TestGenericComplex.sdsl | 9 + assets/Stride/SDSL/TestGenericMacro.sdsl | 9 + assets/Stride/SDSL/TestGenerics.sdsl | 11 + assets/Stride/SDSL/TestMacros.sdsl | 15 + assets/Stride/SDSL/TestMacrosArray.sdsl | 13 + assets/Stride/SDSL/TestMultipleStatic.sdsl | 12 + assets/Stride/SDSL/TestPixelStream.sdsl | 11 + assets/Stride/SDSL/TestScreenPosition.sdsl | 6 + assets/Stride/SDSL/TestStream.sdsl | 26 + assets/Stride/SDSL/TestStreams.sdsl | 10 + assets/Stride/SDSL/TestStructInheritance.sdsl | 11 + assets/Stride/SDSL/TestStructure.sdsl | 14 + assets/Stride/SDSL/TestVertexStream.sdsl | 12 + .../Stride/SDSL/TextureProjectionCommon.sdsl | 25 + .../SDSL/TextureProjectionFilterDefault.sdsl | 21 + .../Stride/SDSL/TextureProjectionGroup.sdsl | 23 + .../SDSL/TextureProjectionReceiverBase.sdsl | 186 ++ .../SDSL/TextureProjectionReceiverSpot.sdsl | 26 + assets/Stride/SDSL/Texturing.sdsl | 124 + assets/Stride/SDSL/ThresholdAlphaCoC.sdsl | 65 + .../Stride/SDSL/ThresholdAlphaCoCFront.sdsl | 53 + assets/Stride/SDSL/ToGlslShader.sdsl | 20 + .../SDSL/ToneMapACESOperatorShader.sdsl | 31 + .../SDSL/ToneMapCommonOperatorShader.sdsl | 14 + .../SDSL/ToneMapDragoOperatorShader.sdsl | 22 + .../ToneMapExponentialOperatorShader.sdsl | 18 + .../SDSL/ToneMapHejl2OperatorShader.sdsl | 28 + .../SDSL/ToneMapHejlDawsonOperatorShader.sdsl | 24 + .../ToneMapLogarithmicOperatorShader.sdsl | 18 + .../SDSL/ToneMapMikeDayOperatorShader.sdsl | 30 + assets/Stride/SDSL/ToneMapOperatorShader.sdsl | 12 + .../SDSL/ToneMapReinhardOperatorShader.sdsl | 19 + assets/Stride/SDSL/ToneMapShader.sdsl | 91 + .../SDSL/ToneMapU2FilmicOperatorShader.sdsl | 40 + assets/Stride/SDSL/Transformation.sdsl | 42 + assets/Stride/SDSL/TransformationBase.sdsl | 36 + .../Stride/SDSL/TransformationBendWorld.sdsl | 23 + .../Stride/SDSL/TransformationInstancing.sdsl | 41 + assets/Stride/SDSL/TransformationMatrix.sdsl | 17 + .../Stride/SDSL/TransformationSkinning.sdsl | 43 + .../SDSL/TransformationSkinningInstanced.sdsl | 25 + .../Stride/SDSL/TransformationTextureUV.sdsl | 22 + assets/Stride/SDSL/TransformationWAndVP.sdsl | 26 + .../SDSL/TransformationWAndVPInstanced.sdsl | 12 + assets/Stride/SDSL/TransformationWVP.sdsl | 8 + assets/Stride/SDSL/TransformationZero.sdsl | 13 + .../SDSL/TripleRhombiCombineShader.sdsl | 42 + assets/Stride/SDSL/UIEffectShader.sdsl | 37 + assets/Stride/SDSL/Utilities.sdsl | 56 + assets/Stride/SDSL/VelocityOutput.sdsl | 11 + assets/Stride/SDSL/VelocityStream.sdsl | 14 + assets/Stride/SDSL/VideoShader.sdsl | 6 + assets/Stride/SDSL/VignettingShader.sdsl | 35 + assets/Stride/SDSL/VolumeMinMaxShader.sdsl | 20 + assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl | 34 + .../Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl | 15 + assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl | 12 + .../SDSL/Voxel2x2x2MipmapperHeuristic.sdsl | 27 + .../Voxel2x2x2MipmapperPhysicallyBased.sdsl | 23 + .../SDSL/Voxel2x2x2MipmapperSimple.sdsl | 12 + .../SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl | 16 + .../SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl | 16 + .../SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl | 16 + .../SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl | 16 + .../SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl | 16 + .../SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl | 16 + .../SDSL/VoxelAnisotropicPairedSampler.sdsl | 50 + .../VoxelAnisotropicPairedWriter_Float4.sdsl | 64 + .../Stride/SDSL/VoxelAnisotropicSampler.sdsl | 56 + .../SDSL/VoxelAnisotropicWriter_Float4.sdsl | 100 + assets/Stride/SDSL/VoxelAttribute.sdsl | 11 + ...elAttributeDirectionalCoverageSampler.sdsl | 43 + ...xelAttributeDirectionalCoverageShader.sdsl | 56 + .../VoxelAttributeEmissionOpacityShader.sdsl | 31 + .../SDSL/VoxelAttributeSoliditySampler.sdsl | 39 + .../SDSL/VoxelAttributeSolidityShader.sdsl | 108 + .../Stride/SDSL/VoxelBufferWriteAssign.sdsl | 15 + assets/Stride/SDSL/VoxelBufferWriteMax.sdsl | 16 + assets/Stride/SDSL/VoxelBufferWriter.sdsl | 29 + .../Stride/SDSL/VoxelFragmentPackFloat16.sdsl | 63 + .../Stride/SDSL/VoxelFragmentPackFloat32.sdsl | 61 + .../SDSL/VoxelFragmentPackFloatR11G11B10.sdsl | 66 + assets/Stride/SDSL/VoxelFragmentPacker.sdsl | 21 + assets/Stride/SDSL/VoxelIsotropicSampler.sdsl | 38 + .../SDSL/VoxelIsotropicWriter_Float4.sdsl | 44 + assets/Stride/SDSL/VoxelLayout_Float4.sdsl | 14 + assets/Stride/SDSL/VoxelMarchBeam.sdsl | 32 + assets/Stride/SDSL/VoxelMarchCone.sdsl | 36 + .../Stride/SDSL/VoxelMarchConeEditMode.sdsl | 47 + .../Stride/SDSL/VoxelMarchConePerMipmap.sdsl | 33 + assets/Stride/SDSL/VoxelMarchMethod.sdsl | 7 + assets/Stride/SDSL/VoxelMarchSet.sdsl | 6 + .../SDSL/VoxelMarchSetHemisphere12.sdsl | 55 + .../Stride/SDSL/VoxelMarchSetHemisphere6.sdsl | 47 + .../SDSL/VoxelMarchSetRandomHemisphere.sdsl | 46 + .../SDSL/VoxelModifierApplierAnisotropic.sdsl | 9 + ...VoxelModifierApplierAnisotropicPaired.sdsl | 9 + ...odifierApplierAntiAliasingAnisotropic.sdsl | 15 + ...rApplierAntiAliasingAnisotropicPaired.sdsl | 12 + ...lModifierApplierAntiAliasingIsotropic.sdsl | 10 + .../SDSL/VoxelModifierApplierIsotropic.sdsl | 9 + ...oxelModifierApplierOpacifyAnisotropic.sdsl | 17 + ...difierApplierOpacifyAnisotropicPaired.sdsl | 14 + .../VoxelModifierApplierOpacifyIsotropic.sdsl | 10 + ...xelModifierApplierSolidifyAnisotropic.sdsl | 15 + ...ifierApplierSolidifyAnisotropicPaired.sdsl | 12 + ...VoxelModifierApplierSolidifyIsotropic.sdsl | 10 + assets/Stride/SDSL/VoxelPositionStream.sdsl | 8 + .../Stride/SDSL/VoxelRadiusMarchMethod.sdsl | 7 + .../SDSL/VoxelStorageClipmapShader.sdsl | 107 + assets/Stride/SDSL/VoxelStorageShader.sdsl | 21 + .../VoxelStorageTextureClipmapShader.sdsl | 181 ++ .../SDSL/VoxelStorageTextureShader.sdsl | 10 + .../SDSL/VoxelVisualizationRawEffect.sdsl | 15 + .../SDSL/VoxelVisualizationRawShader.sdsl | 30 + .../SDSL/VoxelVisualizationViewEffect.sdsl | 23 + .../SDSL/VoxelVisualizationViewShader.sdsl | 30 + assets/Stride/SDSL/VoxelizationMethod.sdsl | 19 + .../SDSL/VoxelizationMethodDominantAxis.sdsl | 48 + .../SDSL/VoxelizationMethodSingleAxis.sdsl | 20 + assets/Stride/SDSL/VoxelizeToFragments.sdsl | 35 + .../SDSL/VoxelizeToFragmentsEffect.sdsl | 24 + 649 files changed, 23143 insertions(+), 2 deletions(-) create mode 100644 assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx create mode 100644 assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx create mode 100644 assets/Stride/SDFX/BackgroundVelocityEffect.sdfx create mode 100644 assets/Stride/SDFX/CoCMapBlurEffect.sdfx create mode 100644 assets/Stride/SDFX/ColorCombinerEffect.sdfx create mode 100644 assets/Stride/SDFX/ColorTransformGroupEffect.sdfx create mode 100644 assets/Stride/SDFX/CombineFrontCoCEffect.sdfx create mode 100644 assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx create mode 100644 assets/Stride/SDFX/ComputeEffectShader.sdfx create mode 100644 assets/Stride/SDFX/ComputeShaderTestEffect.sdfx create mode 100644 assets/Stride/SDFX/CubemapEffect.sdfx create mode 100644 assets/Stride/SDFX/CustomEffect.sdfx create mode 100644 assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx create mode 100644 assets/Stride/SDFX/DepthMinMaxEffect.sdfx create mode 100644 assets/Stride/SDFX/FXAAShaderEffect.sdfx create mode 100644 assets/Stride/SDFX/FlareArtifactEffect.sdfx create mode 100644 assets/Stride/SDFX/GaussianBlurEffect.sdfx create mode 100644 assets/Stride/SDFX/ImageScalerEffect.sdfx create mode 100644 assets/Stride/SDFX/LambertianPrefilteringSH.sdfx create mode 100644 assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx create mode 100644 assets/Stride/SDFX/LightShaftsEffect.sdfx create mode 100644 assets/Stride/SDFX/LightSkyboxEffect.sdfx create mode 100644 assets/Stride/SDFX/LightStreakEffect.sdfx create mode 100644 assets/Stride/SDFX/MSAAResolverEffect.sdfx create mode 100644 assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx create mode 100644 assets/Stride/SDFX/ModelComponentPickingEffect.sdfx create mode 100644 assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx create mode 100644 assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx create mode 100644 assets/Stride/SDFX/ParticleBaseEffect.sdfx create mode 100644 assets/Stride/SDFX/ParticleCustomEffect.sdfx create mode 100644 assets/Stride/SDFX/ParticleEffect.sdfx create mode 100644 assets/Stride/SDFX/Picking.sdfx create mode 100644 assets/Stride/SDFX/PreviewTexture.sdfx create mode 100644 assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx create mode 100644 assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx create mode 100644 assets/Stride/SDFX/SceneEditorParameters.sdfx create mode 100644 assets/Stride/SDFX/SelectedSprite.sdfx create mode 100644 assets/Stride/SDFX/ShadowMapCaster.sdfx create mode 100644 assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx create mode 100644 assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx create mode 100644 assets/Stride/SDFX/SimpleEffect.sdfx create mode 100644 assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx create mode 100644 assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx create mode 100644 assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx create mode 100644 assets/Stride/SDFX/SpriteBatch.sdfx create mode 100644 assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx create mode 100644 assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx create mode 100644 assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx create mode 100644 assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx create mode 100644 assets/Stride/SDFX/StrideEffectBase.sdfx create mode 100644 assets/Stride/SDFX/StrideForwardShadingEffect.sdfx create mode 100644 assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx create mode 100644 assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx create mode 100644 assets/Stride/SDFX/ToGlslEffect.sdfx create mode 100644 assets/Stride/SDFX/ToneMapEffect.sdfx create mode 100644 assets/Stride/SDFX/UIEffect.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_complex_params.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_compose_keys.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple_child.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple_child_params.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple_clone.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple_compose.sdfx create mode 100644 assets/Stride/SDFX/test_mixin_simple_params.sdfx create mode 100644 assets/Stride/SDSL/A.sdsl create mode 100644 assets/Stride/SDSL/AdditiveLightEffect.sdsl create mode 100644 assets/Stride/SDSL/AdditiveLightShader.sdsl create mode 100644 assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl create mode 100644 assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl create mode 100644 assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl create mode 100644 assets/Stride/SDSL/B.sdsl create mode 100644 assets/Stride/SDSL/BRDFMicrofacet.sdsl create mode 100644 assets/Stride/SDSL/BackgroundCubemapShader.sdsl create mode 100644 assets/Stride/SDSL/BackgroundShader.sdsl create mode 100644 assets/Stride/SDSL/BackgroundVelocity.sdsl create mode 100644 assets/Stride/SDSL/BakeLightProbeShader.sdsl create mode 100644 assets/Stride/SDSL/BaseTestChild.sdsl create mode 100644 assets/Stride/SDSL/BaseTestInter.sdsl create mode 100644 assets/Stride/SDSL/BaseTestParent.sdsl create mode 100644 assets/Stride/SDSL/BasicMixin.sdsl create mode 100644 assets/Stride/SDSL/BasicMixin2.sdsl create mode 100644 assets/Stride/SDSL/BlendUtils.sdsl create mode 100644 assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl create mode 100644 assets/Stride/SDSL/BloomAfterimageShader.sdsl create mode 100644 assets/Stride/SDSL/BrightFilterShader.sdsl create mode 100644 assets/Stride/SDSL/BufferToTexture.sdsl create mode 100644 assets/Stride/SDSL/BufferToTextureColumns.sdsl create mode 100644 assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl create mode 100644 assets/Stride/SDSL/BufferToTextureEffect.sdsl create mode 100644 assets/Stride/SDSL/C.sdsl create mode 100644 assets/Stride/SDSL/C1.sdsl create mode 100644 assets/Stride/SDSL/Camera.sdsl create mode 100644 assets/Stride/SDSL/CameraCube.sdsl create mode 100644 assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl create mode 100644 assets/Stride/SDSL/Child.sdsl create mode 100644 assets/Stride/SDSL/ChildError.sdsl create mode 100644 assets/Stride/SDSL/CircleOfConfusion.sdsl create mode 100644 assets/Stride/SDSL/ClearBuffer.sdsl create mode 100644 assets/Stride/SDSL/CloneTestBase.sdsl create mode 100644 assets/Stride/SDSL/CloneTestExtern.sdsl create mode 100644 assets/Stride/SDSL/CloneTestRoot.sdsl create mode 100644 assets/Stride/SDSL/CoCLinearDepthShader.sdsl create mode 100644 assets/Stride/SDSL/CoCMapBlurShader.sdsl create mode 100644 assets/Stride/SDSL/ColorBase.sdsl create mode 100644 assets/Stride/SDSL/ColorCombinerShader.sdsl create mode 100644 assets/Stride/SDSL/ColorTransformGroupShader.sdsl create mode 100644 assets/Stride/SDSL/ColorTransformShader.sdsl create mode 100644 assets/Stride/SDSL/ColorUtility.sdsl create mode 100644 assets/Stride/SDSL/CombineFrontCoCShader.sdsl create mode 100644 assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl create mode 100644 assets/Stride/SDSL/CompilationErrorShader.sdsl create mode 100644 assets/Stride/SDSL/ComputeColor.sdsl create mode 100644 assets/Stride/SDSL/ComputeColor3.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorAdd.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorAdd3.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorAdd3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorAddMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorAverage.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorCave.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorColor.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorColorBurn.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorColorDodge.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorConstantLink.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDarken3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDesaturate.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDifference3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorDivide.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorExclusion.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorFixed.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorFromStream.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorHardLight.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorHardMix.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorHue.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorIlluminate.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorIn.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorLighten3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorLightenMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorLinearBurn.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorLinearDodge.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMask.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMask3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMultiply.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOne.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOut.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOutdoor.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOver3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOverMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOverlay.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorParameter.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorPinLight.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorRadial.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorRed.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSaturate.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSaturation.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorScaler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorScreen.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSoftLight.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorStream.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSubtract.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorSynthetic.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTexture.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaled.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorTextureScroll.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorThreshold.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorValue.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorWave.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorWaveNormal.sdsl create mode 100644 assets/Stride/SDSL/ComputeColorWhite.sdsl create mode 100644 assets/Stride/SDSL/ComputeShaderBase.sdsl create mode 100644 assets/Stride/SDSL/ComputeShaderTest.sdsl create mode 100644 assets/Stride/SDSL/ComputeSphericalHarmonics.sdsl create mode 100644 assets/Stride/SDSL/ConstantBufferTest.sdsl create mode 100644 assets/Stride/SDSL/CubemapSprite.sdsl create mode 100644 assets/Stride/SDSL/CubemapUtils.sdsl create mode 100644 assets/Stride/SDSL/CustomFogEffect.sdsl create mode 100644 assets/Stride/SDSL/CustomShader.sdsl create mode 100644 assets/Stride/SDSL/CyclicTest.sdsl create mode 100644 assets/Stride/SDSL/DataPacking.sdsl create mode 100644 assets/Stride/SDSL/DeepExtern.sdsl create mode 100644 assets/Stride/SDSL/DeepExternTest.sdsl create mode 100644 assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl create mode 100644 assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl create mode 100644 assets/Stride/SDSL/DepthBase.sdsl create mode 100644 assets/Stride/SDSL/DepthMinMaxShader.sdsl create mode 100644 assets/Stride/SDSL/DirectLightGroup.sdsl create mode 100644 assets/Stride/SDSL/DirectLightGroupArray.sdsl create mode 100644 assets/Stride/SDSL/DirectLightGroupFixed.sdsl create mode 100644 assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl create mode 100644 assets/Stride/SDSL/DirectLightGroupPerView.sdsl create mode 100644 assets/Stride/SDSL/Dither.sdsl create mode 100644 assets/Stride/SDSL/DynamicSampler.sdsl create mode 100644 assets/Stride/SDSL/DynamicTexture.sdsl create mode 100644 assets/Stride/SDSL/DynamicTextureCube.sdsl create mode 100644 assets/Stride/SDSL/DynamicTextureStream.sdsl create mode 100644 assets/Stride/SDSL/Effect.sdsl create mode 100644 assets/Stride/SDSL/EffectCompiling.sdsl create mode 100644 assets/Stride/SDSL/EnvironmentLight.sdsl create mode 100644 assets/Stride/SDSL/EnvironmentLightArray.sdsl create mode 100644 assets/Stride/SDSL/ExternClone.sdsl create mode 100644 assets/Stride/SDSL/ExternCloneTest.sdsl create mode 100644 assets/Stride/SDSL/ExternMixin.sdsl create mode 100644 assets/Stride/SDSL/ExternTest.sdsl create mode 100644 assets/Stride/SDSL/FXAAShader.sdsl create mode 100644 assets/Stride/SDSL/FilmGrainShader.sdsl create mode 100644 assets/Stride/SDSL/FlareArtifactShader.sdsl create mode 100644 assets/Stride/SDSL/FlareReplicate.sdsl create mode 100644 assets/Stride/SDSL/FlattenLayers.sdsl create mode 100644 assets/Stride/SDSL/FogEffect.sdsl create mode 100644 assets/Stride/SDSL/ForEachTest.sdsl create mode 100644 assets/Stride/SDSL/GBuffer.sdsl create mode 100644 assets/Stride/SDSL/GBufferOutputNormals.sdsl create mode 100644 assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl create mode 100644 assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl create mode 100644 assets/Stride/SDSL/GaussianBlurShader.sdsl create mode 100644 assets/Stride/SDSL/GenericCall.sdsl create mode 100644 assets/Stride/SDSL/GenericClass.sdsl create mode 100644 assets/Stride/SDSL/GenericClass2.sdsl create mode 100644 assets/Stride/SDSL/GenericExtern.sdsl create mode 100644 assets/Stride/SDSL/GenericTexcoord.sdsl create mode 100644 assets/Stride/SDSL/GeometryShaderTest.sdsl create mode 100644 assets/Stride/SDSL/Global.sdsl create mode 100644 assets/Stride/SDSL/GlobalVR.sdsl create mode 100644 assets/Stride/SDSL/HSVUtils.sdsl create mode 100644 assets/Stride/SDSL/Hammersley.sdsl create mode 100644 assets/Stride/SDSL/HammersleyTest.sdsl create mode 100644 assets/Stride/SDSL/HighlightShader.sdsl create mode 100644 assets/Stride/SDSL/IComputeEnvironmentColor.sdsl create mode 100644 assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl create mode 100644 assets/Stride/SDSL/IMaterialStreamBlend.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSurface.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSurfacePixel.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSurfaceShading.sdsl create mode 100644 assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl create mode 100644 assets/Stride/SDSL/IStreamInitializer.sdsl create mode 100644 assets/Stride/SDSL/IVoxelSampler.sdsl create mode 100644 assets/Stride/SDSL/ImageEffectShader.sdsl create mode 100644 assets/Stride/SDSL/ImageScalerShader.sdsl create mode 100644 assets/Stride/SDSL/ImportanceSamplingGGX.sdsl create mode 100644 assets/Stride/SDSL/InterfaceTest.sdsl create mode 100644 assets/Stride/SDSL/InternalReferenceMixin.sdsl create mode 100644 assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl create mode 100644 assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl create mode 100644 assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl create mode 100644 assets/Stride/SDSL/LambertianPrefilteringSHPass2.sdsl create mode 100644 assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl create mode 100644 assets/Stride/SDSL/LightClustered.sdsl create mode 100644 assets/Stride/SDSL/LightClusteredPointGroup.sdsl create mode 100644 assets/Stride/SDSL/LightClusteredSpotGroup.sdsl create mode 100644 assets/Stride/SDSL/LightConstantWhite.sdsl create mode 100644 assets/Stride/SDSL/LightDirectional.sdsl create mode 100644 assets/Stride/SDSL/LightDirectionalGroup.sdsl create mode 100644 assets/Stride/SDSL/LightPoint.sdsl create mode 100644 assets/Stride/SDSL/LightPointGroup.sdsl create mode 100644 assets/Stride/SDSL/LightProbeShader.sdsl create mode 100644 assets/Stride/SDSL/LightShaftsShader.sdsl create mode 100644 assets/Stride/SDSL/LightSimpleAmbient.sdsl create mode 100644 assets/Stride/SDSL/LightSkyboxShader.sdsl create mode 100644 assets/Stride/SDSL/LightSpot.sdsl create mode 100644 assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl create mode 100644 assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl create mode 100644 assets/Stride/SDSL/LightSpotGroup.sdsl create mode 100644 assets/Stride/SDSL/LightStreakShader.sdsl create mode 100644 assets/Stride/SDSL/LightStream.sdsl create mode 100644 assets/Stride/SDSL/LightTiling.sdsl create mode 100644 assets/Stride/SDSL/LightUtil.sdsl create mode 100644 assets/Stride/SDSL/LightVoxelEffect.sdsl create mode 100644 assets/Stride/SDSL/LightVoxelShader.sdsl create mode 100644 assets/Stride/SDSL/LocalSamples.sdsl create mode 100644 assets/Stride/SDSL/LuminanceLogShader.sdsl create mode 100644 assets/Stride/SDSL/LuminanceToChannelShader.sdsl create mode 100644 assets/Stride/SDSL/LuminanceUtils.sdsl create mode 100644 assets/Stride/SDSL/MSAADepthResolverShader.sdsl create mode 100644 assets/Stride/SDSL/MSAAResolverShader.sdsl create mode 100644 assets/Stride/SDSL/MacroTest.sdsl create mode 100644 assets/Stride/SDSL/MacroTestBase.sdsl create mode 100644 assets/Stride/SDSL/MacroTestChild.sdsl create mode 100644 assets/Stride/SDSL/MarchAttributes.sdsl create mode 100644 assets/Stride/SDSL/MarchAttributesEffect.sdsl create mode 100644 assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl create mode 100644 assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl create mode 100644 assets/Stride/SDSL/MaterialDisplacementStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialDomainStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl create mode 100644 assets/Stride/SDSL/MaterialHairShared.sdsl create mode 100644 assets/Stride/SDSL/MaterialPixelShadingStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialPixelStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl create mode 100644 assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl create mode 100644 assets/Stride/SDSL/MaterialStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl create mode 100644 assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl create mode 100644 assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl create mode 100644 assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl create mode 100644 assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl create mode 100644 assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceArray.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl create mode 100644 assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl create mode 100644 assets/Stride/SDSL/MaterialTessellationStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl create mode 100644 assets/Stride/SDSL/MaterialVertexStream.sdsl create mode 100644 assets/Stride/SDSL/Math.sdsl create mode 100644 assets/Stride/SDSL/McIntoshCombineShader.sdsl create mode 100644 assets/Stride/SDSL/McIntoshOptimizedShader.sdsl create mode 100644 assets/Stride/SDSL/MeshVelocity.sdsl create mode 100644 assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl create mode 100644 assets/Stride/SDSL/MixinNameClash.sdsl create mode 100644 assets/Stride/SDSL/MixinNoNameClash.sdsl create mode 100644 assets/Stride/SDSL/ModelComponentPickingShader.sdsl create mode 100644 assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl create mode 100644 assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl create mode 100644 assets/Stride/SDSL/NonStageStreamTest.sdsl create mode 100644 assets/Stride/SDSL/NormalBase.sdsl create mode 100644 assets/Stride/SDSL/NormalFromMesh.sdsl create mode 100644 assets/Stride/SDSL/NormalFromMeshInstanced.sdsl create mode 100644 assets/Stride/SDSL/NormalFromNormalMapping.sdsl create mode 100644 assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl create mode 100644 assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl create mode 100644 assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl create mode 100644 assets/Stride/SDSL/NormalMeshSkinning.sdsl create mode 100644 assets/Stride/SDSL/NormalPack.sdsl create mode 100644 assets/Stride/SDSL/NormalStream.sdsl create mode 100644 assets/Stride/SDSL/NormalUpdate.sdsl create mode 100644 assets/Stride/SDSL/NormalUtil.sdsl create mode 100644 assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl create mode 100644 assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl create mode 100644 assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl create mode 100644 assets/Stride/SDSL/OpaqueBase.sdsl create mode 100644 assets/Stride/SDSL/OutlineEffect.sdsl create mode 100644 assets/Stride/SDSL/Parent.sdsl create mode 100644 assets/Stride/SDSL/ParticleBase.sdsl create mode 100644 assets/Stride/SDSL/ParticleColor.sdsl create mode 100644 assets/Stride/SDSL/ParticleColorStream.sdsl create mode 100644 assets/Stride/SDSL/ParticleComputeColorShader.sdsl create mode 100644 assets/Stride/SDSL/ParticleCustomShader.sdsl create mode 100644 assets/Stride/SDSL/ParticleUtilities.sdsl create mode 100644 assets/Stride/SDSL/PickingShader.sdsl create mode 100644 assets/Stride/SDSL/PointDepth.sdsl create mode 100644 assets/Stride/SDSL/PositionHStream4.sdsl create mode 100644 assets/Stride/SDSL/PositionStream.sdsl create mode 100644 assets/Stride/SDSL/PositionStream2.sdsl create mode 100644 assets/Stride/SDSL/PositionStream4.sdsl create mode 100644 assets/Stride/SDSL/PositionVertexTransform.sdsl create mode 100644 assets/Stride/SDSL/PostEffectBoundingRay.sdsl create mode 100644 assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl create mode 100644 assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl create mode 100644 assets/Stride/SDSL/RangeCompressorShader.sdsl create mode 100644 assets/Stride/SDSL/RangeDecompressorShader.sdsl create mode 100644 assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl create mode 100644 assets/Stride/SDSL/SSLRBlurPass.sdsl create mode 100644 assets/Stride/SDSL/SSLRCombinePass.sdsl create mode 100644 assets/Stride/SDSL/SSLRCommon.sdsl create mode 100644 assets/Stride/SDSL/SSLRDepthPass.sdsl create mode 100644 assets/Stride/SDSL/SSLRRayTracePass.sdsl create mode 100644 assets/Stride/SDSL/SSLRResolvePass.sdsl create mode 100644 assets/Stride/SDSL/SSLRTemporalPass.sdsl create mode 100644 assets/Stride/SDSL/ScreenPositionBase.sdsl create mode 100644 assets/Stride/SDSL/SelectedSpriteShader.sdsl create mode 100644 assets/Stride/SDSL/SemanticTest.sdsl create mode 100644 assets/Stride/SDSL/ShaderBase.sdsl create mode 100644 assets/Stride/SDSL/ShaderBaseStream.sdsl create mode 100644 assets/Stride/SDSL/ShadingBase.sdsl create mode 100644 assets/Stride/SDSL/ShadingColor.sdsl create mode 100644 assets/Stride/SDSL/ShadowGroup.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCasterVsm.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapCommon.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapFilterBase.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapFilterDefault.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapFilterPcf.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapFilterVsm.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapGroup.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapReceiverBase.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl create mode 100644 assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl create mode 100644 assets/Stride/SDSL/ShadowStream.sdsl create mode 100644 assets/Stride/SDSL/SharedTextureCoordinate.sdsl create mode 100644 assets/Stride/SDSL/SignedDistanceFieldFont.sdsl create mode 100644 assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl create mode 100644 assets/Stride/SDSL/Simple.sdsl create mode 100644 assets/Stride/SDSL/SimpleShader.sdsl create mode 100644 assets/Stride/SDSL/SkyboxShaderBase.sdsl create mode 100644 assets/Stride/SDSL/SkyboxShaderCubemap.sdsl create mode 100644 assets/Stride/SDSL/SkyboxShaderTexture.sdsl create mode 100644 assets/Stride/SDSL/SkyboxStream.sdsl create mode 100644 assets/Stride/SDSL/SphericalHarmonicsBase.sdsl create mode 100644 assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl create mode 100644 assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl create mode 100644 assets/Stride/SDSL/SphericalHarmonicsUtils.sdsl create mode 100644 assets/Stride/SDSL/SpotLightDataInternalShader.sdsl create mode 100644 assets/Stride/SDSL/Sprite3DBase.sdsl create mode 100644 assets/Stride/SDSL/SpriteAlphaCutoff.sdsl create mode 100644 assets/Stride/SDSL/SpriteBase.sdsl create mode 100644 assets/Stride/SDSL/SpriteBatchShader.sdsl create mode 100644 assets/Stride/SDSL/SpriteEffect.sdsl create mode 100644 assets/Stride/SDSL/SpriteEffectExtTexture.sdsl create mode 100644 assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl create mode 100644 assets/Stride/SDSL/SpritePicking.sdsl create mode 100644 assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl create mode 100644 assets/Stride/SDSL/SpriteSuperSampler.sdsl create mode 100644 assets/Stride/SDSL/StageBase.sdsl create mode 100644 assets/Stride/SDSL/StageCallExtern.sdsl create mode 100644 assets/Stride/SDSL/StageDecl.sdsl create mode 100644 assets/Stride/SDSL/StageValueReference.sdsl create mode 100644 assets/Stride/SDSL/StageValueTest.sdsl create mode 100644 assets/Stride/SDSL/StaticCallMixin.sdsl create mode 100644 assets/Stride/SDSL/StaticMixin.sdsl create mode 100644 assets/Stride/SDSL/StaticStageCallTest.sdsl create mode 100644 assets/Stride/SDSL/StreamChild.sdsl create mode 100644 assets/Stride/SDSL/StreamError.sdsl create mode 100644 assets/Stride/SDSL/StreamParent0.sdsl create mode 100644 assets/Stride/SDSL/StreamParent1.sdsl create mode 100644 assets/Stride/SDSL/StreamParent2.sdsl create mode 100644 assets/Stride/SDSL/StreamSolverExternTest.sdsl create mode 100644 assets/Stride/SDSL/StreamTest.sdsl create mode 100644 assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl create mode 100644 assets/Stride/SDSL/StructuredBufferTest.sdsl create mode 100644 assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl create mode 100644 assets/Stride/SDSL/SwapUV.sdsl create mode 100644 assets/Stride/SDSL/TangentMeshSkinning.sdsl create mode 100644 assets/Stride/SDSL/TemporalAntiAliasShader.sdsl create mode 100644 assets/Stride/SDSL/TessellationAE2.sdsl create mode 100644 assets/Stride/SDSL/TessellationAE3.sdsl create mode 100644 assets/Stride/SDSL/TessellationAE4.sdsl create mode 100644 assets/Stride/SDSL/TessellationBase.sdsl create mode 100644 assets/Stride/SDSL/TessellationFlat.sdsl create mode 100644 assets/Stride/SDSL/TessellationPN.sdsl create mode 100644 assets/Stride/SDSL/TessellationTest.sdsl create mode 100644 assets/Stride/SDSL/TestComputeColor.sdsl create mode 100644 assets/Stride/SDSL/TestComputeColor2.sdsl create mode 100644 assets/Stride/SDSL/TestComputeColorRedirect.sdsl create mode 100644 assets/Stride/SDSL/TestComputeShader.sdsl create mode 100644 assets/Stride/SDSL/TestErrors.sdsl create mode 100644 assets/Stride/SDSL/TestExternArray.sdsl create mode 100644 assets/Stride/SDSL/TestGenerator.sdsl create mode 100644 assets/Stride/SDSL/TestGenericComplex.sdsl create mode 100644 assets/Stride/SDSL/TestGenericMacro.sdsl create mode 100644 assets/Stride/SDSL/TestGenerics.sdsl create mode 100644 assets/Stride/SDSL/TestMacros.sdsl create mode 100644 assets/Stride/SDSL/TestMacrosArray.sdsl create mode 100644 assets/Stride/SDSL/TestMultipleStatic.sdsl create mode 100644 assets/Stride/SDSL/TestPixelStream.sdsl create mode 100644 assets/Stride/SDSL/TestScreenPosition.sdsl create mode 100644 assets/Stride/SDSL/TestStream.sdsl create mode 100644 assets/Stride/SDSL/TestStreams.sdsl create mode 100644 assets/Stride/SDSL/TestStructInheritance.sdsl create mode 100644 assets/Stride/SDSL/TestStructure.sdsl create mode 100644 assets/Stride/SDSL/TestVertexStream.sdsl create mode 100644 assets/Stride/SDSL/TextureProjectionCommon.sdsl create mode 100644 assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl create mode 100644 assets/Stride/SDSL/TextureProjectionGroup.sdsl create mode 100644 assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl create mode 100644 assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl create mode 100644 assets/Stride/SDSL/Texturing.sdsl create mode 100644 assets/Stride/SDSL/ThresholdAlphaCoC.sdsl create mode 100644 assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl create mode 100644 assets/Stride/SDSL/ToGlslShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapShader.sdsl create mode 100644 assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl create mode 100644 assets/Stride/SDSL/Transformation.sdsl create mode 100644 assets/Stride/SDSL/TransformationBase.sdsl create mode 100644 assets/Stride/SDSL/TransformationBendWorld.sdsl create mode 100644 assets/Stride/SDSL/TransformationInstancing.sdsl create mode 100644 assets/Stride/SDSL/TransformationMatrix.sdsl create mode 100644 assets/Stride/SDSL/TransformationSkinning.sdsl create mode 100644 assets/Stride/SDSL/TransformationSkinningInstanced.sdsl create mode 100644 assets/Stride/SDSL/TransformationTextureUV.sdsl create mode 100644 assets/Stride/SDSL/TransformationWAndVP.sdsl create mode 100644 assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl create mode 100644 assets/Stride/SDSL/TransformationWVP.sdsl create mode 100644 assets/Stride/SDSL/TransformationZero.sdsl create mode 100644 assets/Stride/SDSL/TripleRhombiCombineShader.sdsl create mode 100644 assets/Stride/SDSL/UIEffectShader.sdsl create mode 100644 assets/Stride/SDSL/Utilities.sdsl create mode 100644 assets/Stride/SDSL/VelocityOutput.sdsl create mode 100644 assets/Stride/SDSL/VelocityStream.sdsl create mode 100644 assets/Stride/SDSL/VideoShader.sdsl create mode 100644 assets/Stride/SDSL/VignettingShader.sdsl create mode 100644 assets/Stride/SDSL/VolumeMinMaxShader.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl create mode 100644 assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl create mode 100644 assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl create mode 100644 assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl create mode 100644 assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl create mode 100644 assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttribute.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl create mode 100644 assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelBufferWriteAssign.sdsl create mode 100644 assets/Stride/SDSL/VoxelBufferWriteMax.sdsl create mode 100644 assets/Stride/SDSL/VoxelBufferWriter.sdsl create mode 100644 assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl create mode 100644 assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl create mode 100644 assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl create mode 100644 assets/Stride/SDSL/VoxelFragmentPacker.sdsl create mode 100644 assets/Stride/SDSL/VoxelIsotropicSampler.sdsl create mode 100644 assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl create mode 100644 assets/Stride/SDSL/VoxelLayout_Float4.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchBeam.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchCone.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchMethod.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchSet.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl create mode 100644 assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl create mode 100644 assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl create mode 100644 assets/Stride/SDSL/VoxelPositionStream.sdsl create mode 100644 assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl create mode 100644 assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelStorageShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelStorageTextureShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl create mode 100644 assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl create mode 100644 assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl create mode 100644 assets/Stride/SDSL/VoxelizationMethod.sdsl create mode 100644 assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl create mode 100644 assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl create mode 100644 assets/Stride/SDSL/VoxelizeToFragments.sdsl create mode 100644 assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl diff --git a/.gitignore b/.gitignore index 62f9f8f1a2..981fdf3b42 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ obj/ .fake .vs/ .antlr/ -/src/SDSLParserExample/Properties/launchSettings.json -assets/Stride \ No newline at end of file +/src/SDSLParserExample/Properties/launchSettings.json \ No newline at end of file diff --git a/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx b/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx new file mode 100644 index 0000000000..13271d292a --- /dev/null +++ b/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A gaussian blur effect + /// + effect AmbientOcclusionBlurEffect + { + using params AmbientOcclusionBlurKeys; + + // Mixin + mixin AmbientOcclusionBlurShader; + }; +} diff --git a/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx b/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx new file mode 100644 index 0000000000..71be5b39a4 --- /dev/null +++ b/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A gaussian blur effect + /// + effect AmbientOcclusionRawAOEffect + { + using params AmbientOcclusionRawAOKeys; + + // Mixin + mixin AmbientOcclusionRawAOShader; + }; +} diff --git a/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx b/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx new file mode 100644 index 0000000000..d80fd5a495 --- /dev/null +++ b/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Computes screen space velocity for backgrounds +effect BackgroundVelocityEffect +{ + using params StrideEffectBaseKeys; + + mixin ShaderBase; + mixin ShadingBase; + mixin BackgroundVelocity; + + // ----------------------------------------------- + // MRT output definitions (color0 excluded) + // ----------------------------------------------- + var targetExtensions = StrideEffectBaseKeys.RenderTargetExtensions; + if (targetExtensions != null) + { + mixin (targetExtensions); + } +}; diff --git a/assets/Stride/SDFX/CoCMapBlurEffect.sdfx b/assets/Stride/SDFX/CoCMapBlurEffect.sdfx new file mode 100644 index 0000000000..7e1848424c --- /dev/null +++ b/assets/Stride/SDFX/CoCMapBlurEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A directional, depth-aware and weighted-blur for a CoC map. + /// + effect CoCMapBlurEffect + { + using params DepthAwareDirectionalBlurKeys; + + // Mixin + mixin CoCMapBlurShader; + }; +} diff --git a/assets/Stride/SDFX/ColorCombinerEffect.sdfx b/assets/Stride/SDFX/ColorCombinerEffect.sdfx new file mode 100644 index 0000000000..002d86bbca --- /dev/null +++ b/assets/Stride/SDFX/ColorCombinerEffect.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + effect ColorCombinerEffect + { + using params ColorCombiner; + + // Mixin + mixin ColorCombinerShader; + }; +} diff --git a/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx b/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx new file mode 100644 index 0000000000..a9971567bb --- /dev/null +++ b/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A Color transform group effect + /// + effect ColorTransformCompose + { + using params ColorTransformKeys; + + mixin ColorTransformKeys.Shader, ColorTransformKeys.GenericArguments; + }; + + effect ColorTransformGroupEffect + { + using params ColorTransformGroupKeys; + + // Mixin + mixin ColorTransformGroupShader; + foreach (var colorTransform in ColorTransformGroupKeys.Transforms) + { + context.PushParameters(colorTransform.Parameters); + mixin compose Transforms += ColorTransformCompose; + context.PopParameters(); + } + }; +} diff --git a/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx b/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx new file mode 100644 index 0000000000..ed7cf2d8c3 --- /dev/null +++ b/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// Combines the different blur levels depending on the pixel's CoC. + /// Specific for the front out-of-focus objects. + /// + effect CombineFrontCoCEffect + { + using params CombineLevelsFromCoCKeys; + + // Mixin + mixin CombineFrontCoCShader; + }; +} diff --git a/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx b/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx new file mode 100644 index 0000000000..48e68bd2c1 --- /dev/null +++ b/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// Combines the different blur levels depending on the pixel's CoC. (Back area only.) + /// + effect CombineLevelsFromCoCEffect + { + using params CombineLevelsFromCoCKeys; + + // Mixin + mixin CombineLevelsFromCoCShader; + }; +} diff --git a/assets/Stride/SDFX/ComputeEffectShader.sdfx b/assets/Stride/SDFX/ComputeEffectShader.sdfx new file mode 100644 index 0000000000..7a270ae1d1 --- /dev/null +++ b/assets/Stride/SDFX/ComputeEffectShader.sdfx @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.ComputeEffect +{ + /// + /// The effect for compute effect + /// + effect ComputeEffectShader + { + using params ComputeEffectShaderKeys; + + mixin macro ThreadNumberX = ComputeEffectShaderKeys.ThreadNumbers.X; + mixin macro ThreadNumberY = ComputeEffectShaderKeys.ThreadNumbers.Y; + mixin macro ThreadNumberZ = ComputeEffectShaderKeys.ThreadNumbers.Z; + + // base effect for computing + mixin ComputeShaderBase; + + // user computing effect + mixin ComputeEffectShaderKeys.ComputeShaderName; + }; +} diff --git a/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx b/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx new file mode 100644 index 0000000000..0d7d44b105 --- /dev/null +++ b/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Graphics.Tests +{ + params ComputeShaderTestParams + { + int NbOfIterations; + } + + effect ComputeShaderTestEffect + { + using params ComputeShaderTestParams; + + mixin ComputeShaderTest; + }; +} diff --git a/assets/Stride/SDFX/CubemapEffect.sdfx b/assets/Stride/SDFX/CubemapEffect.sdfx new file mode 100644 index 0000000000..d21fb15817 --- /dev/null +++ b/assets/Stride/SDFX/CubemapEffect.sdfx @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test +{ + effect CubemapDisplayEffect + { + using params MaterialParameters; + + mixin ShaderBase; + mixin TransformationWAndVP; + mixin AlbedoFlatShading; + mixin compose albedoDiffuse = ComputeColorTextureCubeBasic; + }; + + effect CubemapEffect + { + using params MaterialParameters; + + mixin ShaderBase; + mixin TransformationWAndVP; + mixin AlbedoFlatShading; + + if (MaterialParameters.AlbedoDiffuse != null) + mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; + else + mixin compose albedoDiffuse = ComputeColorTextureCubeReflect; + }; + + effect CubemapGeomEffect + { + using params MaterialParameters; + + mixin ShaderBase; + mixin TransformationWAndVP; + + mixin macro MAX_VERTEX_COUNT = 9; + mixin CameraCube; + + mixin AlbedoFlatShading; + + if (MaterialParameters.AlbedoDiffuse != null) + mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; + }; + + effect CubemapIBLEffect + { + mixin StrideBaseShader; + mixin child StrideGBufferShaderPass; + }; +} diff --git a/assets/Stride/SDFX/CustomEffect.sdfx b/assets/Stride/SDFX/CustomEffect.sdfx new file mode 100644 index 0000000000..e6b7acbdaa --- /dev/null +++ b/assets/Stride/SDFX/CustomEffect.sdfx @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Graphics.Tests +{ + partial effect CustomSubEffect + { + using params CustomShaderKeys; + + if (CustomShaderKeys.SwitchEffectLevel < 10) + { + mixin CustomShader; + } + else + { + mixin CustomShader2; + } + }; + + /// + /// A gaussian blur effect + /// + effect CustomEffect + { + mixin CustomShader; + mixin child CustomSubEffect; + }; +} diff --git a/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx b/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx new file mode 100644 index 0000000000..b5d1ec0ed8 --- /dev/null +++ b/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A directional, depth-aware, uniform-weight blur. + /// + effect DepthAwareDirectionalBlurEffect + { + using params DepthAwareDirectionalBlurKeys; + + // Mixin + mixin DepthAwareDirectionalBlurShader< DepthAwareDirectionalBlurKeys.Count, + DepthAwareDirectionalBlurKeys.TotalTap>; + }; +} diff --git a/assets/Stride/SDFX/DepthMinMaxEffect.sdfx b/assets/Stride/SDFX/DepthMinMaxEffect.sdfx new file mode 100644 index 0000000000..16b6fa420d --- /dev/null +++ b/assets/Stride/SDFX/DepthMinMaxEffect.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + effect DepthMinMaxEffect + { + using params DepthMinMax; + + mixin DepthMinMaxShader; + }; +} diff --git a/assets/Stride/SDFX/FXAAShaderEffect.sdfx b/assets/Stride/SDFX/FXAAShaderEffect.sdfx new file mode 100644 index 0000000000..7f1fa6d715 --- /dev/null +++ b/assets/Stride/SDFX/FXAAShaderEffect.sdfx @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + effect FXAAShaderEffect + { + using params FXAAEffect; + + // Mixin + mixin macro FXAA_GREEN_AS_LUMA = FXAAEffect.GreenAsLumaKey; + mixin macro FXAA_QUALITY__PRESET = FXAAEffect.QualityKey; + mixin FXAAShader; + }; +} diff --git a/assets/Stride/SDFX/FlareArtifactEffect.sdfx b/assets/Stride/SDFX/FlareArtifactEffect.sdfx new file mode 100644 index 0000000000..a72401b6bc --- /dev/null +++ b/assets/Stride/SDFX/FlareArtifactEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A flare artifact effect + /// + effect FlareArtifactEffect + { + using params FlareArtifactKeys; + + // Mixin + mixin FlareArtifactShader; + }; +} diff --git a/assets/Stride/SDFX/GaussianBlurEffect.sdfx b/assets/Stride/SDFX/GaussianBlurEffect.sdfx new file mode 100644 index 0000000000..0c95b95a36 --- /dev/null +++ b/assets/Stride/SDFX/GaussianBlurEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A gaussian blur effect + /// + effect GaussianBlurEffect + { + using params GaussianBlurKeys; + + // Mixin + mixin GaussianBlurShader; + }; +} diff --git a/assets/Stride/SDFX/ImageScalerEffect.sdfx b/assets/Stride/SDFX/ImageScalerEffect.sdfx new file mode 100644 index 0000000000..e0e0673f68 --- /dev/null +++ b/assets/Stride/SDFX/ImageScalerEffect.sdfx @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A copier effect + /// + effect ImageScalerEffect + { + mixin ImageScalerShader; + }; + + effect ImageSuperSamplerScalerEffect + { + mixin ImageScalerShader; + mixin SpriteSuperSampler; + }; +} diff --git a/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx b/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx new file mode 100644 index 0000000000..6018b180b4 --- /dev/null +++ b/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + params LambertianPrefilteringSHParameters + { + int BlockSize; + } + + effect LambertianPrefilteringSHEffectPass1 + { + using params SphericalHarmonicsParameters; + using params LambertianPrefilteringSHParameters; + + mixin LambertianPrefilteringSHPass1; + }; + + effect LambertianPrefilteringSHEffectPass2 + { + using params SphericalHarmonicsParameters; + using params LambertianPrefilteringSHParameters; + + mixin LambertianPrefilteringSHPass2; + }; +} diff --git a/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx b/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx new file mode 100644 index 0000000000..937d1cee91 --- /dev/null +++ b/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + effect LambertianPrefilteringSHNoComputeEffectPass1 + { + using params SphericalHarmonicsParameters; + + mixin LambertianPrefilteringSHNoComputePass1; + }; +} diff --git a/assets/Stride/SDFX/LightShaftsEffect.sdfx b/assets/Stride/SDFX/LightShaftsEffect.sdfx new file mode 100644 index 0000000000..d8f04ee853 --- /dev/null +++ b/assets/Stride/SDFX/LightShaftsEffect.sdfx @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + effect LightShaftsEffect + { + // Use code from the shadow receiver appropriate for the light this lightshaft is rendered for + using params LightShaftsEffectKeys; + mixin compose lightGroup = (LightShaftsEffectKeys.LightGroup); + + mixin LightShaftsShader; + }; +} diff --git a/assets/Stride/SDFX/LightSkyboxEffect.sdfx b/assets/Stride/SDFX/LightSkyboxEffect.sdfx new file mode 100644 index 0000000000..1295e11d55 --- /dev/null +++ b/assets/Stride/SDFX/LightSkyboxEffect.sdfx @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; + +namespace Stride.Rendering.Lights +{ + /// + /// Base effect + /// + effect LightSkyboxEffect + { + using params LightSkyboxShaderKeys; + + mixin LightSkyboxShader; + + if (LightSkyboxShaderKeys.LightDiffuseColor != null) + { + mixin compose lightDiffuseColor = LightSkyboxShaderKeys.LightDiffuseColor; + } + + if (LightSkyboxShaderKeys.LightSpecularColor != null) + { + mixin compose lightSpecularColor = LightSkyboxShaderKeys.LightSpecularColor; + } + }; +} diff --git a/assets/Stride/SDFX/LightStreakEffect.sdfx b/assets/Stride/SDFX/LightStreakEffect.sdfx new file mode 100644 index 0000000000..cf5ee265f7 --- /dev/null +++ b/assets/Stride/SDFX/LightStreakEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A light streak effect + /// + effect LightStreakEffect + { + using params LightStreakKeys; + + // Mixin + mixin LightStreakShader; + }; +} diff --git a/assets/Stride/SDFX/MSAAResolverEffect.sdfx b/assets/Stride/SDFX/MSAAResolverEffect.sdfx new file mode 100644 index 0000000000..b156fd5701 --- /dev/null +++ b/assets/Stride/SDFX/MSAAResolverEffect.sdfx @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Compositing +{ + params MSAAResolverParams + { + int MSAASamples; + int ResolveFilterType; + float ResolveFilterDiameter; + } + + effect MSAAResolverEffect + { + using params MSAAResolverParams; + + mixin macro INPUT_MSAA_SAMPLES = MSAAResolverParams.MSAASamples; + mixin MSAAResolverShader; + }; + + effect MSAADepthResolverEffect + { + using params MSAAResolverParams; + + mixin macro INPUT_MSAA_SAMPLES = MSAAResolverParams.MSAASamples; + mixin MSAADepthResolverShader; + }; +} diff --git a/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx b/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx new file mode 100644 index 0000000000..1482121421 --- /dev/null +++ b/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// Optimized version of the McIntosh blur. + /// Does the 2 final blur and keep the minimum in a single pass. + /// + partial effect McIntoshOptimizedEffect + { + using params DepthAwareDirectionalBlurKeys; + + // Mixin + mixin McIntoshOptimizedShader; + mixin compose directionalBlurA = DepthAwareDirectionalBlurUtil; + mixin compose directionalBlurB = DepthAwareDirectionalBlurUtil; + }; +} diff --git a/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx b/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx new file mode 100644 index 0000000000..83ea5f77af --- /dev/null +++ b/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; + +namespace Stride.Rendering.Utils +{ + effect ModelComponentPickingEffect + { + mixin ModelComponentPickingShader; + }; +} diff --git a/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx b/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx new file mode 100644 index 0000000000..bde2ba4838 --- /dev/null +++ b/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test +{ + effect MultiTexturesSpriteEffect + { + mixin MultiTexturesSpriteShader; + }; +} diff --git a/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx b/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx new file mode 100644 index 0000000000..481df35fde --- /dev/null +++ b/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Graphics.Tests +{ + effect MultipleRenderTargetsEffect + { + mixin StrideForwardShadingEffect; + mixin MultipleRenderTargetsEffectShader; + }; +} diff --git a/assets/Stride/SDFX/ParticleBaseEffect.sdfx b/assets/Stride/SDFX/ParticleBaseEffect.sdfx new file mode 100644 index 0000000000..1cc81875de --- /dev/null +++ b/assets/Stride/SDFX/ParticleBaseEffect.sdfx @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering +{ + partial effect ParticleBaseEffect + { + using params ParticleBaseKeys; + + using params ParticleUtilitiesKeys; + + mixin macro ParticleBaseKeys.UsesSoftEdge; + + mixin ParticleBase; + }; +} diff --git a/assets/Stride/SDFX/ParticleCustomEffect.sdfx b/assets/Stride/SDFX/ParticleCustomEffect.sdfx new file mode 100644 index 0000000000..51ba4060f3 --- /dev/null +++ b/assets/Stride/SDFX/ParticleCustomEffect.sdfx @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering +{ + partial effect ParticleCustomEffect + { + // Use the ParticleBaseKeys for constant attributes, defined in the game engine + using params ParticleBaseKeys; + + // Use the ParticleCustomShaderKeys for constant attributes, defined in this project + using params ParticleCustomShaderKeys; + + // Inherit from the ParticleBaseEffect.sdfx, defined in the game engine + mixin ParticleBaseEffect; + + // Use the ParticleCustomShader.sdsl, defined in this project + mixin ParticleCustomShader; + + // If the user-defined effect for the baseColor is not null use it + if (ParticleCustomShaderKeys.BaseColor != null) + { + mixin compose baseColor = ParticleCustomShaderKeys.BaseColor; + } + + // If the user-defined effect for the baseIntensity (alpha) is not null use it + if (ParticleCustomShaderKeys.BaseIntensity != null) + { + mixin compose baseIntensity = ParticleCustomShaderKeys.BaseIntensity; + } + }; +} diff --git a/assets/Stride/SDFX/ParticleEffect.sdfx b/assets/Stride/SDFX/ParticleEffect.sdfx new file mode 100644 index 0000000000..32308522d4 --- /dev/null +++ b/assets/Stride/SDFX/ParticleEffect.sdfx @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering +{ + partial effect ParticleEffect + { + using params ParticleBaseKeys; + + mixin ParticleBaseEffect; + + mixin ParticleComputeColorShader; + + if (ParticleBaseKeys.BaseColor != null) + { + mixin compose baseColor = ParticleBaseKeys.BaseColor; + } + }; +} diff --git a/assets/Stride/SDFX/Picking.sdfx b/assets/Stride/SDFX/Picking.sdfx new file mode 100644 index 0000000000..7e10001d58 --- /dev/null +++ b/assets/Stride/SDFX/Picking.sdfx @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering +{ + partial effect Picking + { + mixin PickingShader; + }; +} diff --git a/assets/Stride/SDFX/PreviewTexture.sdfx b/assets/Stride/SDFX/PreviewTexture.sdfx new file mode 100644 index 0000000000..66f32a74b6 --- /dev/null +++ b/assets/Stride/SDFX/PreviewTexture.sdfx @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace StrideEffects +{ + params PreviewTextureParameters + { + bool Is3D; + }; + + effect PreviewTexture + { + using params PreviewTextureParameters; + + if(PreviewTextureParameters.Is3D) + { + mixin Sprite3DBase; + } + + mixin SpriteBatch; + }; +} diff --git a/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx b/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx new file mode 100644 index 0000000000..c5fbbcb2cf --- /dev/null +++ b/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + params RadiancePrefilteringGGXParams + { + int NbOfSamplings; + } + + effect RadiancePrefilteringGGXEffect + { + using params RadiancePrefilteringGGXParams; + + mixin RadiancePrefilteringGGXShader; + }; +} diff --git a/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx b/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx new file mode 100644 index 0000000000..4a228d9b55 --- /dev/null +++ b/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + params RadiancePrefilteringGGXNoComputeParams + { + int NbOfSamplings; + } + + effect RadiancePrefilteringGGXNoComputeEffect + { + using params RadiancePrefilteringGGXNoComputeParams; + + mixin RadiancePrefilteringGGXNoComputeShader; + }; +} diff --git a/assets/Stride/SDFX/SceneEditorParameters.sdfx b/assets/Stride/SDFX/SceneEditorParameters.sdfx new file mode 100644 index 0000000000..f6218fed35 --- /dev/null +++ b/assets/Stride/SDFX/SceneEditorParameters.sdfx @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace StrideEffects +{ + params SceneEditorParameters + { + //bool IsSelected; + bool IsEffectCompiling; + bool IsEffectError; + //bool IsMetaEntity; + }; +} diff --git a/assets/Stride/SDFX/SelectedSprite.sdfx b/assets/Stride/SDFX/SelectedSprite.sdfx new file mode 100644 index 0000000000..995b2fce96 --- /dev/null +++ b/assets/Stride/SDFX/SelectedSprite.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace StrideEffects +{ + effect SelectedSprite + { + using params SpriteBaseKeys; + + mixin SpriteBatchShader; + mixin SelectedSpriteShader; + }; +} diff --git a/assets/Stride/SDFX/ShadowMapCaster.sdfx b/assets/Stride/SDFX/ShadowMapCaster.sdfx new file mode 100644 index 0000000000..daf419a64a --- /dev/null +++ b/assets/Stride/SDFX/ShadowMapCaster.sdfx @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Materials; + +namespace Stride.Rendering.Shadows +{ + // Spawn a sub-effect for the shadow map caster pass + partial effect ShadowMapCaster + { + using params MaterialKeys; + + // For cut off and blend materials we want to run pixel shader during rendering shadow maps + if(MaterialKeys.UseDitheredShadows) + { + mixin ShadowMapCasterAlphaDithered; + } + else if(MaterialKeys.UsePixelShaderWithDepthPass) + { + mixin ShadowMapCasterAlphaDiscard; + } + else + { + mixin ShadowMapCasterNoPixelShader; + } + }; +} diff --git a/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx b/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx new file mode 100644 index 0000000000..3801d3f241 --- /dev/null +++ b/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Materials; + +namespace Stride.Rendering.Shadows +{ + // Spawn a sub-effect for the shadow map caster pass + partial effect ShadowMapCasterCubeMap + { + using params MaterialKeys; + + // For cut off and blend materials we want to run pixel shader during rendering shadow maps + if(MaterialKeys.UseDitheredShadows) + { + mixin ShadowMapCasterAlphaDithered; + } + else if(MaterialKeys.UsePixelShaderWithDepthPass) + { + mixin ShadowMapCasterAlphaDiscard; + } + else + { + mixin ShadowMapCasterNoPixelShader; + } + + mixin ShadowMapCasterCubeMapProjection; + }; +} diff --git a/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx b/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx new file mode 100644 index 0000000000..c17fb3688e --- /dev/null +++ b/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Materials; + +namespace Stride.Rendering.Shadows +{ + // Spawn a sub-effect for the shadow map caster pass + partial effect ShadowMapCasterParaboloid + { + using params MaterialKeys; + + // For cut off and blend materials we want to run pixel shader during rendering shadow maps + if(MaterialKeys.UseDitheredShadows) + { + mixin ShadowMapCasterAlphaDithered; + } + else if(MaterialKeys.UsePixelShaderWithDepthPass) + { + mixin ShadowMapCasterAlphaDiscard; + } + else + { + mixin ShadowMapCasterNoPixelShader; + } + + mixin ShadowMapCasterParaboloidProjection; + }; +} diff --git a/assets/Stride/SDFX/SimpleEffect.sdfx b/assets/Stride/SDFX/SimpleEffect.sdfx new file mode 100644 index 0000000000..2d9b914c4f --- /dev/null +++ b/assets/Stride/SDFX/SimpleEffect.sdfx @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test +{ + effect SimpleEffect + { + mixin SimpleShader; + }; +} diff --git a/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx b/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx new file mode 100644 index 0000000000..cfc0540575 --- /dev/null +++ b/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace SpaceEscape.Effects +{ + params GameParameters + { + bool EnableFog = true; + bool EnableBend = true; + bool EnableOnflyTextureUVChange = false; + } + + effect SpaceEscapeEffectMain + { + using params GameParameters; + + mixin StrideForwardShadingEffect; + + if(GameParameters.EnableOnflyTextureUVChange) + mixin TransformationTextureUV; + + if(GameParameters.EnableBend) + mixin TransformationBendWorld; + + if(GameParameters.EnableFog) + mixin CustomFogEffect; + }; +} diff --git a/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx b/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx new file mode 100644 index 0000000000..969136062a --- /dev/null +++ b/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + params SphericalHarmonicsParameters + { + int HarmonicsOrder; + } +} diff --git a/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx b/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx new file mode 100644 index 0000000000..200b64c1c9 --- /dev/null +++ b/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + effect SphericalHarmonicsRendererEffect + { + using params SphericalHarmonicsParameters; + + mixin SphericalHarmonicsRenderer; + }; +} diff --git a/assets/Stride/SDFX/SpriteBatch.sdfx b/assets/Stride/SDFX/SpriteBatch.sdfx new file mode 100644 index 0000000000..c7434466cc --- /dev/null +++ b/assets/Stride/SDFX/SpriteBatch.sdfx @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering +{ + /// + /// SpriteBatch effect + /// + partial effect SpriteBatch + { + using params SpriteBaseKeys; + mixin SpriteBatchShader; + }; +} diff --git a/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx b/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx new file mode 100644 index 0000000000..9d45809246 --- /dev/null +++ b/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; +using Stride.Rendering.Materials; + +namespace Stride.Rendering.LightProbes +{ + partial shader StrideBakeLightProbeEffect + { + mixin BakeLightProbeShader; + } +} diff --git a/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx b/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx new file mode 100644 index 0000000000..1b7e509104 --- /dev/null +++ b/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace StrideEffects +{ + effect StrideEditorForwardShadingEffect + { + using params SceneEditorParameters; + + // TODO: This file is similar to StrideEditorWireframeShadingEffect. We should try to look if we can merge them into a single one. + + // Early failover in case there was an effect compilation error + // We later could do a two level error detection: + // - first time at the end of effect (that is ran with nearly empty CompilerParameters) + // - if this one fails too, use this early failover which should have only very few basic shaders + if (SceneEditorParameters.IsEffectError) + { + mixin ShaderBase; + mixin ShadingBase; + mixin TransformationBase; + mixin TransformationWAndVP; + mixin CompilationErrorShader; + discard; + } + + // Include the standard forward shading effect + mixin StrideForwardShadingEffect; + + mixin child Picking; + mixin child Wireframe; + mixin child Highlight; + + // Add an effect compiling if it is not ready + if (SceneEditorParameters.IsEffectCompiling) + { + mixin EffectCompiling; + } + }; + + effect Wireframe + { + using params MaterialFrontBackBlendShaderKeys; + + mixin MaterialFrontBackBlendShader; + } + + effect Highlight + { + mixin HighlightShader; + } +} diff --git a/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx b/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx new file mode 100644 index 0000000000..6d699fc1be --- /dev/null +++ b/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace StrideEffects +{ + effect StrideEditorHighlightingEffect + { + mixin StrideForwardShadingEffect; + //mixin MaterialHighlightingShader; + }; +} diff --git a/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx b/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx new file mode 100644 index 0000000000..812d2fc7e6 --- /dev/null +++ b/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace StrideEffects +{ + effect StrideEditorMaterialPreviewEffect + { + mixin StrideEditorForwardShadingEffect; + mixin SharedTextureCoordinate; + }; +} diff --git a/assets/Stride/SDFX/StrideEffectBase.sdfx b/assets/Stride/SDFX/StrideEffectBase.sdfx new file mode 100644 index 0000000000..e706737b01 --- /dev/null +++ b/assets/Stride/SDFX/StrideEffectBase.sdfx @@ -0,0 +1,181 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; +using Stride.Rendering.Materials; + +namespace Stride.Rendering +{ + /// + /// Base effect + /// + partial effect StrideEffectBase + { + using params MaterialKeys; + using params StrideEffectBaseKeys; + + // ----------------------------------------------- + // Base shaders + // ----------------------------------------------- + mixin ShaderBase; + mixin ShadingBase; + + // ----------------------------------------------- + // Mix material per Vertex Shader + // ----------------------------------------------- + var extensionPreVertexStageSurfaceShaders = MaterialKeys.VertexStageSurfaceShaders; + if (extensionPreVertexStageSurfaceShaders != null) + { + // Must come before TransformationBase as this is responsible to modify the vertex input stream + mixin MaterialSurfaceVertexStageCompositor; + mixin compose materialVertexStage = (extensionPreVertexStageSurfaceShaders); + mixin compose streamInitializerVertexStage = MaterialKeys.VertexStageStreamInitializer; + } + + // ----------------------------------------------- + // Transform vertex stream + // ----------------------------------------------- + // Come after material surface per vertex + mixin TransformationBase; + mixin NormalStream; + + var extensionTessellationShader = MaterialKeys.TessellationShader; + + if (StrideEffectBaseKeys.HasInstancing) + { + mixin macro StrideEffectBaseKeys.ModelTransformUsage; + mixin TransformationWAndVPInstanced; + + // ----------------------------------------------- + // Performs normal mapping (in case of no-skinning, otherwise it is overloaded below) + // ----------------------------------------------- + if (MaterialKeys.HasNormalMap) + { + if (extensionTessellationShader != null) + { + mixin NormalFromNormalMappingTessellationInstanced; + } + else + { + mixin NormalFromNormalMappingInstanced; + } + } + else + { + mixin NormalFromMeshInstanced; + } + } + else + { + mixin TransformationWAndVP; + + // ----------------------------------------------- + // Performs normal mapping (in case of no-skinning, otherwise it is overloaded below) + // ----------------------------------------------- + if (MaterialKeys.HasNormalMap) + { + if (extensionTessellationShader != null) + { + mixin NormalFromNormalMappingTessellation; + } + else + { + mixin NormalFromNormalMapping; + } + } + else + { + mixin NormalFromMesh; + } + } + + + // ----------------------------------------------- + // Performs animation skinning (position, normal and tangent) + // ----------------------------------------------- + if (MaterialKeys.HasSkinningPosition) + { + mixin macro MaterialKeys.SkinningMaxBones; + + if (StrideEffectBaseKeys.HasInstancing) + { + mixin TransformationSkinningInstanced; + } + else + { + mixin TransformationSkinning; + } + + if (MaterialKeys.HasSkinningNormal) + { + mixin NormalMeshSkinning; + } + + if (MaterialKeys.HasSkinningTangent) + { + mixin TangentMeshSkinning; + } + + if (MaterialKeys.HasSkinningNormal) + { + if (MaterialKeys.HasNormalMap) + { + if (extensionTessellationShader != null) + { + mixin NormalVSSkinningNormalMappingTessellation; + } + else + { + mixin NormalVSSkinningNormalMapping; + } + } + else + { + mixin NormalVSSkinningFromMesh; + } + } + } + + // -------------------------------------------- + // Mix material tessellation for Domain effect + //--------------------------------------------- + if(extensionTessellationShader != null) + { + mixin (extensionTessellationShader); + + var extensionDomainStageSurfaceShaders = MaterialKeys.DomainStageSurfaceShaders; + if(extensionDomainStageSurfaceShaders != null) + { + mixin MaterialSurfaceDomainStageCompositor; + mixin compose materialDomainStage = (extensionDomainStageSurfaceShaders); + mixin compose streamInitializerDomainStage = MaterialKeys.DomainStageStreamInitializer; + } + } + + // ----------------------------------------------- + // Screen space velocity calculation + // ----------------------------------------------- + var computeVelocityShader = StrideEffectBaseKeys.ComputeVelocityShader; + if(computeVelocityShader != null) + { + mixin (computeVelocityShader); + } + + // ----------------------------------------------- + // Mix Extension after vertex stage + // ----------------------------------------------- + var extensionPostVertexStage = StrideEffectBaseKeys.ExtensionPostVertexStageShader; + if (extensionPostVertexStage != null) + { + mixin (extensionPostVertexStage); + } + + // ----------------------------------------------- + // MRT output definitions (color0 excluded) + // ----------------------------------------------- + var targetExtensions = StrideEffectBaseKeys.RenderTargetExtensions; + if (targetExtensions != null) + { + mixin (targetExtensions); + } + }; +} diff --git a/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx b/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx new file mode 100644 index 0000000000..662ebee230 --- /dev/null +++ b/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx @@ -0,0 +1,77 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; +using Stride.Rendering.Materials; + +namespace Stride.Rendering +{ + partial effect StrideLighting + { + using params LightingKeys; + + // ----------------------------------------------- + // Add light groups + // ----------------------------------------------- + ShaderSourceCollection directLightGroups = LightingKeys.DirectLightGroups; + if (directLightGroups != null) + { + foreach(ShaderSource directLightGroup in directLightGroups) + { + // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" + mixin compose directLightGroups += (directLightGroup); + } + } + + // ----------------------------------------------- + // Add environment light groups + // ----------------------------------------------- + ShaderSourceCollection environmentLights = LightingKeys.EnvironmentLights; + if (environmentLights != null) + { + foreach(ShaderSource environmentLight in environmentLights) + { + // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" + mixin compose environmentLights += (environmentLight); + } + } + } + + /// + /// Forward shading effect + /// + effect StrideForwardShadingEffect + { + using params MaterialKeys; + + // Derive from StrideEffectBase + mixin StrideEffectBase; + + // ----------------------------------------------- + // Mix material and lighting shading for Pixel Shader + // ----------------------------------------------- + ShaderSource extensionPixelStageSurfaceShaders = MaterialKeys.PixelStageSurfaceShaders; + if (extensionPixelStageSurfaceShaders != null) + { + mixin MaterialSurfacePixelStageCompositor; + mixin compose materialPixelStage = (extensionPixelStageSurfaceShaders); + mixin compose streamInitializerPixelStage = MaterialKeys.PixelStageStreamInitializer; + + ShaderSource extensionPixelStageSurfaceFilter = MaterialKeys.PixelStageSurfaceFilter; + if (extensionPixelStageSurfaceFilter != null) + { + mixin (extensionPixelStageSurfaceFilter); + } + + mixin child GBuffer; + } + + // ----------------------------------------------- + // Add direct and environment light groups + // ----------------------------------------------- + mixin StrideLighting; + + mixin child ShadowMapCaster; + mixin child ShadowMapCasterParaboloid; + mixin child ShadowMapCasterCubeMap; + }; +} diff --git a/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx b/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx new file mode 100644 index 0000000000..da7ebfbf27 --- /dev/null +++ b/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Rendering.Data; +using Stride.Shaders.Compiler; + +namespace Stride.Rendering +{ + effect StrideWireframeShadingEffect + { + using params MaterialFrontBackBlendShaderKeys; + + mixin StrideEffectBase; + + mixin MaterialFrontBackBlendShader; + }; +} diff --git a/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx b/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx new file mode 100644 index 0000000000..c3cce2258a --- /dev/null +++ b/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx @@ -0,0 +1,17 @@ +namespace Stride.Rendering.SubsurfaceScattering +{ + effect SubsurfaceScatteringBlurEffect + { + using params SubsurfaceScatteringKeys; // TODO: What does this do? + + // Mixin: + mixin macro SSSS_FOLLOW_SURFACE = SubsurfaceScatteringKeys.FollowSurface; + + mixin SubsurfaceScatteringBlurShader; + }; +} diff --git a/assets/Stride/SDFX/ToGlslEffect.sdfx b/assets/Stride/SDFX/ToGlslEffect.sdfx new file mode 100644 index 0000000000..104a0887c4 --- /dev/null +++ b/assets/Stride/SDFX/ToGlslEffect.sdfx @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test +{ + effect ToGlslEffect + { + mixin ToGlslShader; + }; +} diff --git a/assets/Stride/SDFX/ToneMapEffect.sdfx b/assets/Stride/SDFX/ToneMapEffect.sdfx new file mode 100644 index 0000000000..3a4fb3ce3a --- /dev/null +++ b/assets/Stride/SDFX/ToneMapEffect.sdfx @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Images +{ + /// + /// A Tonemap effect + /// + effect ToneMapEffect + { + using params ColorTransformKeys; + using params ToneMapKeys; + + // Mixin + mixin ToneMapShader; + context.PushParameters(ToneMapKeys.Operator.Parameters); + mixin compose ToneMapOperator = ColorTransformKeys.Shader; + context.PopParameters(); + }; +} diff --git a/assets/Stride/SDFX/UIEffect.sdfx b/assets/Stride/SDFX/UIEffect.sdfx new file mode 100644 index 0000000000..41a956639d --- /dev/null +++ b/assets/Stride/SDFX/UIEffect.sdfx @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering +{ + /// + /// UIEffect effect + /// + partial effect UIEffect + { + using params SpriteBaseKeys; + mixin UIEffectShader; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_complex_params.sdfx b/assets/Stride/SDFX/test_mixin_complex_params.sdfx new file mode 100644 index 0000000000..fe2209c02e --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_complex_params.sdfx @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test1 +{ + params SubParameters + { + bool param1; + int param2 = 1; + string param3 = "ok"; + }; + + params TestParameters + { + SubParameters subParam1; + SubParameters subParameters[]; + }; + + effect DefaultComplexParams + { + using params TestParameters; + using params SubParameters; + + mixin A; + mixin B; + mixin C; + + int x = 1; + foreach (params TestParameters.subParameters) + { + if (SubParameters.param1) + { + mixin "C" + x; + } + + x++; + } + + using params TestParameters.subParam1 + { + + if (SubParameters.param2 == 1) + { + mixin D; + } + } + }; +} diff --git a/assets/Stride/SDFX/test_mixin_compose_keys.sdfx b/assets/Stride/SDFX/test_mixin_compose_keys.sdfx new file mode 100644 index 0000000000..3a39780d00 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_compose_keys.sdfx @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace TestABC +{ + params TestParameters + { + bool UseComputeColor2; + bool UseComputeColorRedirect; + }; + + partial effect ABCSubEffect + { + using params TestParameters; + + if (TestParameters.UseComputeColor2) + { + mixin TestComputeColor2; + } + else if (TestParameters.UseComputeColorRedirect) + { + mixin TestComputeColorRedirect; + mixin compose ColorRedirect = TestComputeColor2; + } + else + { + mixin TestComputeColor; + } + }; + + effect test_mixin_compose_keys + { + mixin A; + mixin compose SubCompute1 = ABCSubEffect; + mixin compose SubCompute2 = ABCSubEffect; + mixin compose SubComputes += ABCSubEffect; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple.sdfx b/assets/Stride/SDFX/test_mixin_simple.sdfx new file mode 100644 index 0000000000..30fb4c9eb3 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple.sdfx @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test2 +{ + effect DefaultSimple + { + mixin A; + mixin B; + mixin C; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple_child.sdfx b/assets/Stride/SDFX/test_mixin_simple_child.sdfx new file mode 100644 index 0000000000..28d5b83253 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple_child.sdfx @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test3 +{ + partial effect ChildMixin + { + mixin C1; + mixin C2; + }; + + effect DefaultSimpleChild + { + mixin A; + mixin B; + mixin C; + mixin ChildMixin; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx b/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx new file mode 100644 index 0000000000..a52d477a80 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test4 +{ + params TestParameters + { + int TestCount; + bool UseComputeColorEffect; + }; + + partial effect ChildParamsMixin + { + using params TestParameters; + + TestParameters.TestCount = 1; + if (TestParameters.TestCount == 1) + mixin C1; + }; + + effect DefaultSimpleChildParams + { + using params TestParameters; + + mixin A; + if (TestParameters.TestCount == 0) + mixin B; + + mixin child ChildParamsMixin; + + if (TestParameters.TestCount == 0) + mixin C; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple_clone.sdfx b/assets/Stride/SDFX/test_mixin_simple_clone.sdfx new file mode 100644 index 0000000000..69b66d7057 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple_clone.sdfx @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test5 +{ + effect ChildClone + { + mixin C1; + mixin C2; + }; + + effect DefaultSimpleClone + { + mixin A; + mixin B; + mixin C; + // Rename the sub child as Test + mixin child Test = ChildClone; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple_compose.sdfx b/assets/Stride/SDFX/test_mixin_simple_compose.sdfx new file mode 100644 index 0000000000..c740522705 --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple_compose.sdfx @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test6 +{ + effect DefaultSimpleCompose + { + mixin A; + mixin B; + mixin C; + mixin compose x = X; + }; +} diff --git a/assets/Stride/SDFX/test_mixin_simple_params.sdfx b/assets/Stride/SDFX/test_mixin_simple_params.sdfx new file mode 100644 index 0000000000..140291221c --- /dev/null +++ b/assets/Stride/SDFX/test_mixin_simple_params.sdfx @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Test7 +{ + params TestParameters + { + bool param1; + int param2 = 1; + string param3 = "ok"; + }; + + effect DefaultSimpleParams + { + using params TestParameters; + + mixin A; + mixin B; + + // Include a simple test of a boolean + if (TestParameters.param1) + { + // Conditional mixin + mixin C; + + // Simple test of macro + mixin macro TestParameters.param2; + + // Simple test of composition + mixin compose x = X; + } + else + { + mixin D; + mixin macro Test = TestParameters.param3; + mixin compose y = Y; + } + }; +} diff --git a/assets/Stride/SDSL/A.sdsl b/assets/Stride/SDSL/A.sdsl new file mode 100644 index 0000000000..5a64860ce0 --- /dev/null +++ b/assets/Stride/SDSL/A.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader A : ShaderBase +{ + compose ComputeColor SubCompute1; + compose ComputeColor SubCompute2; + compose ComputeColor SubComputes[]; + + override stage void PSMain() + { + streams.ColorTarget = SubCompute1.Compute(float4(1,1,1,1)) + SubCompute2.Compute(float4(1,1,1,1)); + + foreach(var subCompute in SubComputes) + { + streams.ColorTarget = subCompute.Compute(streams.ColorTarget); + } + } +}; diff --git a/assets/Stride/SDSL/AdditiveLightEffect.sdsl b/assets/Stride/SDSL/AdditiveLightEffect.sdsl new file mode 100644 index 0000000000..e0ef17704e --- /dev/null +++ b/assets/Stride/SDSL/AdditiveLightEffect.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + effect AdditiveLightEffect + { + using params AdditiveLightEffectKeys; + mixin AdditiveLightShader; + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/AdditiveLightShader.sdsl b/assets/Stride/SDSL/AdditiveLightShader.sdsl new file mode 100644 index 0000000000..a1376d29c9 --- /dev/null +++ b/assets/Stride/SDSL/AdditiveLightShader.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + shader AdditiveLightShader : ImageEffectShader, Texturing + { + cbuffer PerFrame + { + [Color] + stage float3 LightColor; + } + + stage override float4 Shading() + { + float4 color = Texture0.Sample(LinearSampler, streams.TexCoord); + if(TColor) + return float4(color.rgb * LightColor, 1); + return float4(color.rrr * LightColor, 1); + } + }; +} diff --git a/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl b/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl new file mode 100644 index 0000000000..eb9d9d7b50 --- /dev/null +++ b/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A gaussian blur shader + /// + internal shader AmbientOcclusionBlurShader : ImageEffectShader, Camera + { + stage float Weights[BlurCount]; + + stage float reconstructCSZ(float depth) + { + if (IsOrthographic) //near + z * (far - near) + return ZProjection.x + depth * ZProjection.y; + else + return ZProjection.y / (depth - ZProjection.x); + } + + stage override float4 Shading() + { + const float epsilon = 0.0001; + + // Direction in texel size: (float2(1,0) or float2(0,1)) * texel size + float2 direction = (IsVertical ? float2(0, 1) : float2(1, 0)) * Texture0TexelSize; + + // Add center + float totalWeight = Weights[0]; + float3 sum = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * totalWeight; + + float linearDepth = reconstructCSZ(Texture1.Sample(LinearSampler, streams.TexCoord).x); + if (linearDepth >= 300) + { + sum /= (totalWeight + epsilon); + return float4(sum, 1); + } + + // mirrored samples using bilinear filtering + [unroll] + for (int i = 1; i < BlurCount; i++) + { + // Handle both directions + [unroll] + for (int j = -1; j <= 1; j += 2) + { + float weight = 0.3 + Weights[i]; + + float value = Texture0.Sample(LinearSampler, streams.TexCoord + direction * j * i * BlurScale).rgb; + + float linearDepthOther = reconstructCSZ(Texture1.Sample(LinearSampler, streams.TexCoord + direction * j * i * BlurScale).x); + weight *= max(0.0, 1.0 - EdgeSharpness * abs(linearDepth - linearDepthOther)); + + sum += value * weight; + + totalWeight += weight; + } + } + + sum /= (totalWeight + epsilon); + return float4(sum, 1); + } + }; +} diff --git a/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl b/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl new file mode 100644 index 0000000000..b62d0910ea --- /dev/null +++ b/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl @@ -0,0 +1,168 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + shader AmbientOcclusionRawAOShader : ImageEffectShader, Camera + { + float4 ProjInfo; // .x = zN * zF, .y = zN - zF, .z = zF + float4 ScreenInfo; // .x = Width, .y = Height, .z = Aspect + + float ParamProjScale = 1; + float ParamIntensity = 1; + float ParamBias = 0.01f; + float ParamRadius = 1; + float ParamRadiusSquared = 1; + + stage float reconstructCSZ(float depth) + { + if (IsOrthographic) //near + z * (far - near) + return ZProjection.x + depth * ZProjection.y; + else + return ZProjection.y / (depth - ZProjection.x); + } + + stage float3 reconstructCSPosition(float2 S, float z) + { + if (IsOrthographic) + { + float2 uv = S.xy / ScreenInfo.xy; + uv = uv * 2 - 1; + return float3(uv * ProjInfo.xy, z); + } + else + { + return float3((S.xy * ProjInfo.xy + ProjInfo.zw) * z, z); + } + } + + stage float3 reconstructCSNormal(float3 position) + { + return normalize(cross(ddy(position), ddx(position))); + } + + stage float sampleAO(int2 screenPosition, float3 viewPosition, float3 viewNormal, float diskRadius, int i, float randomPatternRotationAngle) + { + //***************************** + // Sample Offset + float alpha = 1 * (i + 0.5) * 0.675f / SamplesCount; + float angle = 1 * 43.9822971503f * alpha + randomPatternRotationAngle; + + float2 offset = float2(cos(angle), sin(angle)); + float ssRadius = alpha * diskRadius; + + //***************************** + // Depth + float2 samplePos = streams.TexCoord + offset * ssRadius; + int2 samplePosInt = saturate(samplePos) * ScreenInfo.xy; + + float depth = Texture0.Load(int3(samplePosInt, 0)); + float linearDepth = reconstructCSZ(depth); + + //***************************** + // View Position + float3 position = reconstructCSPosition(samplePosInt + float2(0.5, 0.5), linearDepth); + position.x *= -1; + + //***************************** + // View Normal + float3 v = position - viewPosition; + v.z *= -1; + + //***************************** + // Ambient Occlusion + float distSq = dot(v, v); + float vn = dot(v, viewNormal); + + const float epsilon = 0.01; + + float f = max(ParamRadiusSquared - distSq, 0.0); + + return f * f * f * max((vn - ParamBias) / (epsilon + distSq), 0.0); + } + + stage override float4 Shading() + { + //***************************** + // Reconstruct View space linear depth Z from the depth buffer + float depth = Texture0.SampleLevel(Sampler, streams.TexCoord, 0).x; + float linearDepth = reconstructCSZ(depth); + + //***************************** + // Reconstruct View space position XYZ + int2 screenPosition = streams.TexCoord.xy * ScreenInfo.xy; + float3 viewPosition = reconstructCSPosition(screenPosition + float2(0.5, 0.5), linearDepth); + viewPosition.x *= -1; + + //***************************** + // Reconstruct View space normal NxNyNz + float3 viewNormal = reconstructCSNormal(viewPosition.xyz); + viewNormal.xy *= -1; + + //***************************** + // Hash function used in the HPG12 AlchemyAO paper + int linearDepthInt = (int)linearDepth; + //float randomPatternRotationAngle = (3 * screenPosition.x ^ screenPosition.y + screenPosition.x * screenPosition.y) * 10; + float randomPatternRotationAngle = ((15 * linearDepthInt + 3 * screenPosition.x ^ 2 * screenPosition.y + screenPosition.x * screenPosition.y) & 0x0000FFFF) * 10; + + //***************************** + // Choose a sample radius proportional to the projected area of the half-sphere + //float diskRadius = -projScale * radius / linearDepth; + float diskRadius; + if (IsOrthographic) + diskRadius = ParamProjScale / ProjInfo.z; + else + diskRadius = ParamProjScale / linearDepth; + + //***************************** + // Compute the ambient occlusion + float sum = 0.0; + for (int i = 0; i < SamplesCount; i++) + { + sum += sampleAO(screenPosition, viewPosition, viewNormal, diskRadius, i, randomPatternRotationAngle); + } + + float temp = ParamRadiusSquared * ParamRadius; + sum /= temp * temp; + float A = max(0.0, 1.0 - sum * 5 * ParamIntensity / SamplesCount); + + float nearPlaneFade = saturate(linearDepth * 2.0 - 0.5); + A = lerp(1, A, nearPlaneFade); + + //***************************** + // Bilateral box-filter over a quad for free, respecting depth edges + // (the difference that this makes is subtle) + if (abs(ddx(linearDepth)) < 0.02) + { + A -= ddx(A) * ((screenPosition.x & 1) - 0.5); + } + if (abs(ddy(linearDepth)) < 0.02) + { + A -= ddy(A) * ((screenPosition.y & 1) - 0.5); + } + + //************************ + // A now contains the light intensity factor (0 to 1) which can be applied to the ambient light illuminating the pixel + + + + //************************ + // Debug - visualize different + //************************ + + /************************ + // Visualize depth as color bands + //************************ + linearDepth = sum; + float4 color = Texture0.Sample(Sampler, streams.TexCoord); + color.r = ((float)(linearDepth % 4)) / 4.0; + color.g = ((float)((linearDepth / 4) % 4)) / 4.0; + color.b = ((float)((linearDepth / 16) % 4)) / 4.0; + return color; //*/ + + + + return float4(A, A, A, A); + } + }; +} diff --git a/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl b/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl new file mode 100644 index 0000000000..80cdf56753 --- /dev/null +++ b/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Stride.Rendering.Materials.ComputeColors; + +namespace Stride.Rendering.Images +{ + shader ApplyAmbientOcclusionShader : ImageEffectShader + { + stage override float4 Shading() + { + //***************************** + float4 color = Texture0.SampleLevel(Sampler, streams.TexCoord, 0); + float occlusion = Texture1.SampleLevel(Sampler, streams.TexCoord, 0).x; + + // TODO Enable debug output as a mixin + // color.rgba = occlusion; + + color.rgb *= occlusion; + + return color; + } + }; +} diff --git a/assets/Stride/SDSL/B.sdsl b/assets/Stride/SDSL/B.sdsl new file mode 100644 index 0000000000..86cd4a796d --- /dev/null +++ b/assets/Stride/SDSL/B.sdsl @@ -0,0 +1,5 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader B +{ +}; diff --git a/assets/Stride/SDSL/BRDFMicrofacet.sdsl b/assets/Stride/SDSL/BRDFMicrofacet.sdsl new file mode 100644 index 0000000000..3e1d16be54 --- /dev/null +++ b/assets/Stride/SDSL/BRDFMicrofacet.sdsl @@ -0,0 +1,227 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.BRDF +{ + /// + /// Utility shader for calculating the various variations of the functions + /// (Fresnel, NDF and Visibility) involved in a Microfacet shading model. + /// + shader BRDFMicrofacet : Math + { + // References: + // http://graphicrants.blogspot.jp/2013/08/specular-brdf-reference.html + // TODO: Add reference to original papers here + + // ------------------------------------------------- + // Normal Distribution Functions + // ------------------------------------------------- + // Expected parameters: + // alphaR = roughness^2 (Burley) + // nDotH = saturate(dot(n, h)) + // ------------------------------------------------- + // TODO Add GGX Anisotropic + + float ClampedPow(float x, float y) + { + return pow(max(x, 0.00001f), y); + } + + /// + /// Calculate the NDF Blinn-Phong + /// + float NormalDistributionBlinnPhong(float alphaR, float nDotH) + { + var alphaR2 = max(alphaR * alphaR, 0.1); // Cap the value to avoid high exponents. TODO: Find an acceptable limit with 16 bits floats targets + return ClampedPow(nDotH, 2 / alphaR2 - 2) / (PI * alphaR2); + } + + /// + /// Calculate the NDF Beckmann + /// + float NormalDistributionBeckmann(float alphaR, float nDotH) + { + var alphaR2 = max(alphaR * alphaR, 0.1); // Cap the value to avoid high exponents. TODO: Find an acceptable limit with 16 bits floats targets + var nDotH2 = max(nDotH * nDotH, 0.0001); + var nDotH4 = nDotH2 * nDotH2; + return exp((nDotH2 -1)/(alphaR2 * nDotH2))/(PI * alphaR2 * nDotH4); + } + + /// + /// Calculate the NDF GGX + /// + float NormalDistributionGGX(float alphaR, float nDotH) + { + var alphaR2 = alphaR * alphaR; + var d = max(nDotH * nDotH * (alphaR2 - 1) + 1, 0.0001); + return alphaR2 / (PI * d * d); + } + + // ------------------------------------------------- + // Fresnel Functions + // ------------------------------------------------- + // Expected parameters: + // f0 = fresnel specular color at angle 0 + // vDotH = saturate(dot(v, h)) + // ------------------------------------------------- + + /// + /// Calculate a nop Fresnel. + /// + float3 FresnelNone(float3 f0) + { + return f0; + } + + /// + /// Calculate a Schlick approximation to Fresnel + /// + float3 FresnelSchlick(float3 f0, float lOrVDotH) + { + return FresnelSchlick(f0, 1.0f, lOrVDotH); + } + + /// + /// Calculate a Schlick approximation to Fresnel with f0, f90 + /// + float3 FresnelSchlick(float3 f0, float3 f90, float lOrVDotH) + { + return f0 + (f90 - f0) * pow((1-lOrVDotH), 5); + } + + // ------------------------------------------------- + // Geometric Shadowing Functions + // ------------------------------------------------- + // We are using V (Visibility) instead of G (Geometric Shadowing function) + // The formula for V is given by: + // V = G / (nDotL * nDotV) + // + // Expected parameters: + // alphaR = roughness^2 (Burley) + // nDotV = max(dot(n, v), 1e-5f) + // nDotL = saturate(dot(n, l)) + // nDotH = saturate(dot(n, h)) + // ------------------------------------------------- + + /// + /// Calculate the Implicit Geometric Shadowing + /// + float VisibilityImplicit(float nDotL, float nDotV) + { + // G = nDotL * nDotV + return 1.0f; + } + + /// + /// Calculate the Neumann Geometric Shadowing + /// + float VisibilityNeumann(float nDotL, float nDotV) + { + // G = (nDotL * nDotV) / max(nDotL, nDotV) + return 1.0 / max(nDotL, nDotV); + } + + /// + /// Calculate the Cook-Torrance Geometric Shadowing + /// + float VisibilityCookTorrance(float nDotH, float vDotH, float nDotL, float nDotV) + { + // G = min(1, min(2 * nDotH * nDotV / vDotH, 2 * nDotH * nDotL / vDotH)); + return min(1, min(2 * nDotH * nDotV / vDotH, 2 * nDotH * nDotL / vDotH)) / (nDotL * nDotV); + } + + /// + /// Calculate the Kelemen Geometric Shadowing + /// + float VisibilityKelemen(float vDotH, float nDotL, float nDotV) + { + // G = nDotL * nDotV / (vDotH * vDotH); + return 1.0f / (vDotH * vDotH); + } + + float VisibilityBeckmann(float alphaR, float nDotX) + { + float c = nDotX / (alphaR * sqrt(1 - nDotX * nDotX)); + return c < 1.6f ? (3.535f * c + 2.181f * c * c) / ( 1 + 2.276f * c + 2577 * c * c) : 1.0f; + } + + /// + /// Calculate the Smith-Beckmann Geometric Shadowing (to use with their respective NDF) + /// + float VisibilitySmithBeckmann(float alphaR, float nDotL, float nDotV) + { + return (VisibilityBeckmann(alphaR, nDotL) * VisibilityBeckmann(alphaR, nDotV)) / (nDotL * nDotV); + } + + float VisibilityGGXCorrelated(float alphaR, float nDotX) + { + var alphaR2 = alphaR * alphaR; + var nDotX2 = nDotX * nDotX; + return sqrt(1 + alphaR2 * ( 1 - nDotX2) / nDotX2); + } + + /// + /// Calculate the Smith-GGX Correlated Geometric Shadowing + /// + /// See Moving Frostbite to PBR. SmithGGX Correlated + float VisibilitySmithGGXCorrelated(float alphaR, float nDotL, float nDotV) + { + // TODO: Expand (nDotL * nDotV) + return 2.0f / ( VisibilityGGXCorrelated(alphaR, nDotL) + VisibilityGGXCorrelated(alphaR, nDotV)) / (nDotL * nDotV); + } + + float VisibilityhSchlickBeckmann(float alphaR, float nDotX) + { + var k = alphaR * sqrt(2.0f / PI); + return nDotX / (nDotX * (1 - k) + k); + } + + /// + /// Calculate the Smith-Schlick-Beckmann Geometric Shadowing + /// + float VisibilitySmithSchlickBeckmann(float alphaR, float nDotL, float nDotV) + { + return VisibilityhSchlickBeckmann(alphaR, nDotL) * VisibilityhSchlickBeckmann(alphaR, nDotV) / (nDotL * nDotV); + } + + float VisibilityhSchlickGGX(float alphaR, float nDotX) + { + var k = alphaR * 0.5f; + return nDotX / (nDotX * (1.0f - k) + k); + } + + /// + /// Calculate the Smith-Schlick-GGX Geometric Shadowing + /// + float VisibilitySmithSchlickGGX(float alphaR, float nDotL, float nDotV) + { + return VisibilityhSchlickGGX(alphaR, nDotL) * VisibilityhSchlickGGX(alphaR, nDotV) / (nDotL * nDotV); + } + + float3 EnvironmentLightingDFG_GGX_Schlick_SmithSchlickGGX( float3 specularColor, float alphaR, float nDotV ) + { + float x = 1 - alphaR; + float y = nDotV; + + float b1 = -0.1688; + float b2 = 1.895; + float b3 = 0.9903; + float b4 = -4.853; + float b5 = 8.404; + float b6 = -5.069; + float bias = saturate( min( b1 * x + b2 * x * x, b3 + b4 * y + b5 * y * y + b6 * y * y * y ) ); + + float d0 = 0.6045; + float d1 = 1.699; + float d2 = -0.5228; + float d3 = -3.603; + float d4 = 1.404; + float d5 = 0.1939; + float d6 = 2.661; + float delta = saturate( d0 + d1 * x + d2 * y + d3 * x * x + d4 * x * y + d5 * y * y + d6 * x * x * x ); + float scale = delta - bias; + + bias *= saturate( 50.0 * specularColor.y ); + return specularColor * scale + bias; + } + }; +} diff --git a/assets/Stride/SDSL/BackgroundCubemapShader.sdsl b/assets/Stride/SDSL/BackgroundCubemapShader.sdsl new file mode 100644 index 0000000000..6bd53afbe4 --- /dev/null +++ b/assets/Stride/SDSL/BackgroundCubemapShader.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader BackgroundCubemapShader : BackgroundShader +{ + stage TextureCube Cubemap; + + // Shading of the sprite + stage override float4 Shading() + { + var directionVector = float3(1, 1-2*streams.TexCoord.y, 1-2*streams.TexCoord.x); + return Intensity * Cubemap.Sample(LinearSampler, normalize(directionVector)); + } +}; diff --git a/assets/Stride/SDSL/BackgroundShader.sdsl b/assets/Stride/SDSL/BackgroundShader.sdsl new file mode 100644 index 0000000000..d3b16762a3 --- /dev/null +++ b/assets/Stride/SDSL/BackgroundShader.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader BackgroundShader : SpriteBase +{ + stage float Intensity; + + // Shading of the sprite + stage override float4 Shading() + { + return Intensity * base.Shading(); + } +}; diff --git a/assets/Stride/SDSL/BackgroundVelocity.sdsl b/assets/Stride/SDSL/BackgroundVelocity.sdsl new file mode 100644 index 0000000000..c8e0763b80 --- /dev/null +++ b/assets/Stride/SDSL/BackgroundVelocity.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Computes screen space velocity for backgrounds +shader BackgroundVelocity : ShaderBase, VelocityStream, PositionStream4, ScreenPositionBase +{ + stage float4x4 DeltaMatrix; + + stage stream float4 currentShadingPosition; + stage stream float4 previousShadingPosition; + + stage override void VSMain() + { + streams.ShadingPosition = float4(streams.Position.xyz, 1); + streams.currentShadingPosition = streams.Position; + streams.previousShadingPosition = mul(streams.ShadingPosition, DeltaMatrix); + base.VSMain(); + } + + stage override void PSMain() + { + streams.currentShadingPosition /= streams.currentShadingPosition.w; + streams.previousShadingPosition /= streams.previousShadingPosition.w; + float2 delta = (streams.currentShadingPosition - streams.previousShadingPosition).xy; + streams.velocity = delta; + base.PSMain(); + } +}; diff --git a/assets/Stride/SDSL/BakeLightProbeShader.sdsl b/assets/Stride/SDSL/BakeLightProbeShader.sdsl new file mode 100644 index 0000000000..46407dc092 --- /dev/null +++ b/assets/Stride/SDSL/BakeLightProbeShader.sdsl @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.LightProbes +{ + // TODO: Inherit from SpriteBase; however we can't redefine SV_Target0 to have a different type due to ColorTarget being defined by ShaderBase => ShaderBaseStream + shader BakeLightProbeShader : PositionStream4, Texturing + { + // Default SV_POSITION output for VS/GS shaders + stage stream float4 ShadingPosition : SV_Position; + + stage stream uint LightProbeId : LIGHTPROBE_ID; + stage stream uint LightProbeIdOutput : SV_Target0; + + cbuffer PerDraw + { + stage float4x4 MatrixTransform; + } + + stage void VSMain() + { + streams.ShadingPosition = mul(streams.Position, MatrixTransform); + } + + stage void PSMain() + { + streams.LightProbeIdOutput = streams.LightProbeId; + } + }; +} diff --git a/assets/Stride/SDSL/BaseTestChild.sdsl b/assets/Stride/SDSL/BaseTestChild.sdsl new file mode 100644 index 0000000000..6989375ea0 --- /dev/null +++ b/assets/Stride/SDSL/BaseTestChild.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader BaseTestChild : BaseTestInter +{ + override void test1() + { + base.test1(); + } + + override void test2() + { + this.test1(); + base.test2(); + } +}; diff --git a/assets/Stride/SDSL/BaseTestInter.sdsl b/assets/Stride/SDSL/BaseTestInter.sdsl new file mode 100644 index 0000000000..3ca4eef00c --- /dev/null +++ b/assets/Stride/SDSL/BaseTestInter.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader BaseTestInter : BaseTestParent +{ + override void test1() + { + this.test2(); + base.test1(); + } +}; diff --git a/assets/Stride/SDSL/BaseTestParent.sdsl b/assets/Stride/SDSL/BaseTestParent.sdsl new file mode 100644 index 0000000000..b5bf42275b --- /dev/null +++ b/assets/Stride/SDSL/BaseTestParent.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader BaseTestParent +{ + void test1(){} + + void test2(){} +}; diff --git a/assets/Stride/SDSL/BasicMixin.sdsl b/assets/Stride/SDSL/BasicMixin.sdsl new file mode 100644 index 0000000000..06fd04207b --- /dev/null +++ b/assets/Stride/SDSL/BasicMixin.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader BasicMixin +{ + float myFloat = 0.2f; + stage float3 myPosition : register(b); + stream float2 screenPosition : register(vs, b); + + abstract void myFunc(); + float myFunc2() + { + var a = myFloat; + return a; + } + abstract stage void myFunc3(); +}; diff --git a/assets/Stride/SDSL/BasicMixin2.sdsl b/assets/Stride/SDSL/BasicMixin2.sdsl new file mode 100644 index 0000000000..6ebef4b2f8 --- /dev/null +++ b/assets/Stride/SDSL/BasicMixin2.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader BasicMixin2 +{ + float myFloat = 0.2f; + + void myFunc4() {} +}; diff --git a/assets/Stride/SDSL/BlendUtils.sdsl b/assets/Stride/SDSL/BlendUtils.sdsl new file mode 100644 index 0000000000..fdab8ccb49 --- /dev/null +++ b/assets/Stride/SDSL/BlendUtils.sdsl @@ -0,0 +1,63 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various helper functions to perform blending. +/// +shader BlendUtils +{ + // Performs an overlay operation between the two colors. + float4 Overlay(float4 col1, float4 col2) + { + // http://en.wikipedia.org/wiki/Blend_modes#Overlay + // if a < 0.5f: 2ab + // if a >= 0.5f: 1 - 2(1 - a)(1 - b) + return lerp(2.0f * col1 * col2, + 1.0f - 2.0f * (1.0f - col1) * (1.0f - col2), + step(col2, 0.5)); + } + + // Performs a blend operation between the three colors (RGB only). + float3 BasicColorBlend(float4 backColor, float4 frontColor, float3 interColor) + { + return frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb; + } + + // Performs a blend operation between the two alpha values. + float BasicAlphaBlend(float ba, float fa) + { + return lerp(fa, 1.0f, ba); + } + + // Performs a blend operation between the three colors. + float4 BasicBlend(float4 backColor, float4 frontColor, float3 interColor) + { + return float4(frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb, + lerp(frontColor.a, 1.0f, backColor.a)); + } + + // Performs a divide operation between the three colors (RGB only). + float3 ColorDivide(float3 t1, float3 t2) + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // Division + // "0/0" : 0 + // "t1/0" : 1 + // "t1/t2" : t1/t2 + + /*return lerp(t1 / t2, + 1.0 - Equals(t1, 0.0f), + Equals(t2, 0.0f));*/ + return lerp(t1 / t2, + 1.0 - step(t1, 0.0f), + step(t2, 0.0f)); + /*return lerp(t1 / t2, + 1.0 - step(abs(t1), 0.0f), + step(abs(t2), 0.0f));*/ + } + + // Compare each channel of the colors. + float3 Equals(float3 t1, float3 t2) + { + return step(abs(t1 - t2), 0); + } +}; diff --git a/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl b/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl new file mode 100644 index 0000000000..a0a556a60c --- /dev/null +++ b/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Combines persistence with current brightness. + /// Expects as input: + /// - Texture0: current brightness + /// - Texture1: persistence brightness + /// + internal shader BloomAfterimageCombineShader : ImageEffectShader + { + + stage override float4 Shading() + { + float3 currentColor = Texture0.Sample(PointSampler, streams.TexCoord).rgb; + float3 persistenceColor = Texture1.Sample(PointSampler, streams.TexCoord).rgb; + + float3 result = max(currentColor, persistenceColor); + return float4(result, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/BloomAfterimageShader.sdsl b/assets/Stride/SDSL/BloomAfterimageShader.sdsl new file mode 100644 index 0000000000..7a1ed8159f --- /dev/null +++ b/assets/Stride/SDSL/BloomAfterimageShader.sdsl @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Simulates retina persistence / afterimage with bright ghost slowly fading out. + /// + internal shader BloomAfterimageShader : ImageEffectShader + { + // Fade-out speed of the persistence image + stage float FadeOutSpeed; + + // How much sensitive we are to the bright light + stage float Sensitivity; + + stage override float4 Shading() + { + float3 currentColor = Texture0.Sample(LinearSampler, streams.TexCoord).rgb; + float3 persistenceColor = Texture1.Sample(LinearSampler, streams.TexCoord).rgb; + + persistenceColor *= FadeOutSpeed; + + var newPersistence = persistenceColor + currentColor * Sensitivity; + + // Never go brighter than the current brightness + if ( any(newPersistence > currentColor)) newPersistence = persistenceColor; + + return float4(newPersistence, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/BrightFilterShader.sdsl b/assets/Stride/SDSL/BrightFilterShader.sdsl new file mode 100644 index 0000000000..d45c30d67d --- /dev/null +++ b/assets/Stride/SDSL/BrightFilterShader.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A bright filter shader + /// + internal shader BrightFilterShader : ImageEffectShader + { + [Color] + stage float3 ColorModulator; + + stage float BrightPassSteepness = 2.0f; + stage float ThresholdOffset = 0.2f; + + stage override float4 Shading() + { + float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; + + // Calculate relative luminance + float luminance = LuminanceUtils.Luma(color); + + // method 1 + // Apply threshold + // float middle = luminance - ThresholdOffset; + // float range = 0.5f; + // float value = smoothstep(0, 1, saturate(middle * range)); + // color *= value; + + // method 2 + // color *= luminance < ThresholdOffset ? 0.0f : 1.0f; + + // method 3 + color *= smoothstep(0, 1, saturate(sqrt(luminance) / (BrightPassSteepness + 1) - ThresholdOffset)); + + return float4(color * ColorModulator, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/BufferToTexture.sdsl b/assets/Stride/SDSL/BufferToTexture.sdsl new file mode 100644 index 0000000000..3459d6dc2b --- /dev/null +++ b/assets/Stride/SDSL/BufferToTexture.sdsl @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader BufferToTexture : LocalSamples, ComputeShaderBase, VoxelPositionStream, DataPacking + { + stage RWBuffer VoxelFragments; + + stage float3 clipMapResolution; + + stage float storageUints; + + stage uint clipOffset; + + compose VoxelAttribute AttributesTemp[]; + compose VoxelAttribute AttributesIndirect[]; + + #ifndef IndirectStoreMacro + #define IndirectStoreMacro + #define IndirectReadAndStoreMacro + #endif + + override void Compute() + { + int3 clipMapResolutionI = (int3)clipMapResolution; + + uint3 pos = streams.DispatchThreadId.xyz; + pos.y = pos.y % clipMapResolutionI.y; + uint clipIndex = clipOffset + streams.DispatchThreadId.y/clipMapResolutionI.y; + + streams.PositionVXPS = pos; + streams.VoxelVolumeSize = clipMapResolutionI; + + uint wStride = clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z; + uint VoxelFragmentsIndex = clipIndex * wStride + pos.x + pos.y * clipMapResolutionI.x + pos.z * clipMapResolutionI.x * clipMapResolutionI.y; + VoxelFragmentsIndex *= (uint)storageUints; + + uint yStride = clipMapResolutionI.x * (uint)storageUints; + uint initialVoxelFragmentsIndex = VoxelFragmentsIndex; + + + + foreach (var attr in AttributesTemp) + attr.InitializeDummy(); + foreach (var attr in AttributesIndirect) + attr.InitializeDummy(); + + IndirectReadAndStoreMacro + + foreach (var attr in AttributesIndirect) + attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); + } + }; +} diff --git a/assets/Stride/SDSL/BufferToTextureColumns.sdsl b/assets/Stride/SDSL/BufferToTextureColumns.sdsl new file mode 100644 index 0000000000..dbbeb691e7 --- /dev/null +++ b/assets/Stride/SDSL/BufferToTextureColumns.sdsl @@ -0,0 +1,83 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader BufferToTextureColumns : LocalSamples, ComputeShaderBase, VoxelPositionStream, DataPacking + { + [Link("BufferToTexture.VoxelFragments")] + stage RWBuffer VoxelFragments; + + [Link("BufferToTexture.clipMapResolution")] + stage float3 clipMapResolution; + + [Link("BufferToTexture.storageUints")] + stage float storageUints; + + [Link("BufferToTexture.clipOffset")] + stage uint clipOffset; + + + compose VoxelAttribute AttributesTemp[]; + compose VoxelAttribute AttributesIndirect[]; + + #ifndef IndirectStoreMacro + #define IndirectStoreMacro + #define IndirectReadAndStoreMacro + #endif + + override void Compute() + { + int3 clipMapResolutionI = (int3)clipMapResolution; + + uint3 pos = streams.DispatchThreadId.xyz; + uint clipIndex = streams.DispatchThreadId.y + clipOffset; + + pos.y = 0; + streams.PositionVXPS = pos; + streams.VoxelVolumeSize = clipMapResolutionI; + + uint wStride = clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z; + uint VoxelFragmentsIndex = clipIndex * wStride + pos.x + pos.y * clipMapResolutionI.x + pos.z * clipMapResolutionI.x * clipMapResolutionI.y; + VoxelFragmentsIndex *= (uint)storageUints; + + uint yStride = clipMapResolutionI.x * (uint)storageUints; + uint initialVoxelFragmentsIndex = VoxelFragmentsIndex; + + foreach (var attr in AttributesTemp) + attr.InitializeDummy(); + foreach (var attr in AttributesIndirect) + attr.InitializeDummy(); + + IndirectStoreMacro + + VoxelFragmentsIndex += (uint)storageUints * clipMapResolutionI.x; + + foreach (var attr in AttributesIndirect) + attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); + + streams.PositionVXPS.y++; + for (int i = 0; streams.PositionVXPS.y < clipMapResolutionI.y-1 ; streams.PositionVXPS.y ++) + { + uint VoxelFragmentsIndexOld = VoxelFragmentsIndex; + + //See VoxelStorageClipmaps.cs Line #307 + IndirectReadAndStoreMacro + + foreach (var attr in AttributesIndirect) + attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); + + VoxelFragmentsIndex = VoxelFragmentsIndexOld + (uint)storageUints * clipMapResolutionI.x; + } + foreach (var attr in AttributesTemp) + attr.InitializeDummy(); + + foreach (var attr in AttributesIndirect) + attr.InitializeDummy(); + + IndirectStoreMacro + + foreach (var attr in AttributesIndirect) + attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); + } + }; +} diff --git a/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl b/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl new file mode 100644 index 0000000000..52721bd0c3 --- /dev/null +++ b/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + partial effect BufferToTextureColumnsEffect + { + using params BufferToTextureKeys; + + mixin BufferToTextureColumns; + if (BufferToTextureKeys.AttributesIndirect!=null) + { + foreach (var attr in BufferToTextureKeys.AttributesIndirect) + { + mixin compose AttributesIndirect += (attr); + } + } + if (BufferToTextureKeys.AttributesTemp!=null) + { + foreach (var attr in BufferToTextureKeys.AttributesTemp) + { + mixin compose AttributesTemp += (attr); + } + } + + mixin macro BufferToTextureKeys.IndirectReadAndStoreMacro; + mixin macro BufferToTextureKeys.IndirectStoreMacro; + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/BufferToTextureEffect.sdsl b/assets/Stride/SDSL/BufferToTextureEffect.sdsl new file mode 100644 index 0000000000..c0bacbe926 --- /dev/null +++ b/assets/Stride/SDSL/BufferToTextureEffect.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + partial effect BufferToTextureEffect + { + using params BufferToTextureKeys; + + mixin BufferToTexture; + if (BufferToTextureKeys.AttributesIndirect!=null) + { + foreach (var attr in BufferToTextureKeys.AttributesIndirect) + { + mixin compose AttributesIndirect += (attr); + } + } + if (BufferToTextureKeys.AttributesTemp!=null) + { + foreach (var attr in BufferToTextureKeys.AttributesTemp) + { + mixin compose AttributesTemp += (attr); + } + } + + mixin macro BufferToTextureKeys.IndirectReadAndStoreMacro; + mixin macro BufferToTextureKeys.IndirectStoreMacro; + }; +} diff --git a/assets/Stride/SDSL/C.sdsl b/assets/Stride/SDSL/C.sdsl new file mode 100644 index 0000000000..fb03f434ea --- /dev/null +++ b/assets/Stride/SDSL/C.sdsl @@ -0,0 +1,5 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader C +{ +}; diff --git a/assets/Stride/SDSL/C1.sdsl b/assets/Stride/SDSL/C1.sdsl new file mode 100644 index 0000000000..269864958f --- /dev/null +++ b/assets/Stride/SDSL/C1.sdsl @@ -0,0 +1,5 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader C1 +{ +}; diff --git a/assets/Stride/SDSL/Camera.sdsl b/assets/Stride/SDSL/Camera.sdsl new file mode 100644 index 0000000000..a5c1672adf --- /dev/null +++ b/assets/Stride/SDSL/Camera.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Camera +{ + cbuffer PerView { + // Camera Z NearClipPlane value. + stage float NearClipPlane = 1.0f; + // Camera Z FarClipPlane value. + stage float FarClipPlane = 100.0f; + // Z Retro projection factor used retro project a non-linear 1/z depth in the range [0.0 - 1.0] to a linear-depth in view space. + // Remarks: ZInViewSpace = ZProjection.y / (depth - ZProjection.x) + stage float2 ZProjection; + + // Camera View size + stage float2 ViewSize; + // Camera aspect ratio. + stage float AspectRatio; + }; +}; diff --git a/assets/Stride/SDSL/CameraCube.sdsl b/assets/Stride/SDSL/CameraCube.sdsl new file mode 100644 index 0000000000..0962ada297 --- /dev/null +++ b/assets/Stride/SDSL/CameraCube.sdsl @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Renders the geometry in the correct view for a cube map. +/// +shader CameraCube : PositionStream4, ShaderBase +{ + float3 CameraWorldPosition; + + float4x4 CameraViewProjectionMatrices[6]; + + stream uint RTAIndex : SV_RenderTargetArrayIndex; + + // flip render + [maxvertexcount(18)] + stage void GSMain(triangle Input input[3], inout TriangleStream triangleStream) + { + for (int i = 0; i < 6; ++i) + { + streams.RTAIndex = i; + + // TODO: verify that for OpenGL. This is likely to be wrong. Perhaps we don't have to change face winding. + for (int j = 0; j < 3; ++j) + { + streams = input[j]; + streams.ShadingPosition = mul(streams.PositionWS, CameraViewProjectionMatrices[i]); + triangleStream.Append(streams); + } + + triangleStream.RestartStrip(); + } + } +}; diff --git a/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl b/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl new file mode 100644 index 0000000000..461f20ab9b --- /dev/null +++ b/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader CameraOrientationGizmoShader : ComputeColor, PositionStream4 +{ + override float4 Compute() + { + float yPosRemapped = pow((streams.PositionWS.y + 1) / 2, 3.5f); + return float4(0.6f, 0.6f, 0.6f, 1.0f) * yPosRemapped; + } +}; diff --git a/assets/Stride/SDSL/Child.sdsl b/assets/Stride/SDSL/Child.sdsl new file mode 100644 index 0000000000..f3527309d1 --- /dev/null +++ b/assets/Stride/SDSL/Child.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Child : Parent +{ + SamplerState childSampler; + Texture2D childTexture; + + override float AddBaseValue(float inValue) + { + childTexture.Sample(childSampler, float2(0.0f, 0.0f)); + parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); + Parent.parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); + return inValue + baseValue + base.AddBaseValue(inValue); + } +}; diff --git a/assets/Stride/SDSL/ChildError.sdsl b/assets/Stride/SDSL/ChildError.sdsl new file mode 100644 index 0000000000..c7dc21c5e3 --- /dev/null +++ b/assets/Stride/SDSL/ChildError.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ChildError : Parent +{ + float AddBaseValue(float inValue) + { + return inValue + base.AddBaseValue(inValue); + } +}; diff --git a/assets/Stride/SDSL/CircleOfConfusion.sdsl b/assets/Stride/SDSL/CircleOfConfusion.sdsl new file mode 100644 index 0000000000..856d077158 --- /dev/null +++ b/assets/Stride/SDSL/CircleOfConfusion.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Computes the Circle of Confusion map. + /// + shader CircleOfConfusion + { + // TODO Might want to replace this with a real formula from camera lens parameters, + // but for now we'll keep these simple parameters for easy debugging. + // [Near Start, Near End, Far Start, Far End] + stage float4 depthAreas; + + //Gets the circle of confusion strength for a certain depth. + float getCoCFactor(float linearDepth) + { + //CoC factor for the front area + float nearLength = max(depthAreas.y - depthAreas.x, 0.01f); + float nearCoC = 1.0 - saturate( (linearDepth - depthAreas.x) / nearLength); + + //CoC factor for the back area + float farLength = max(depthAreas.w - depthAreas.z, 0.01f); + float farCoC = saturate( (linearDepth - depthAreas.z) / farLength); + + float result = saturate(nearCoC + farCoC); + + // We need to be able to distinguish the out-of-focus near area from the far area. + if (linearDepth < depthAreas.y) result = -result; + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/ClearBuffer.sdsl b/assets/Stride/SDSL/ClearBuffer.sdsl new file mode 100644 index 0000000000..2cc0e6b229 --- /dev/null +++ b/assets/Stride/SDSL/ClearBuffer.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader ClearBuffer : ComputeShaderBase + { + stage RWBuffer buffer; + int offset; + override void Compute() + { + buffer[streams.DispatchThreadId.x + offset] = 0; + } + }; +} diff --git a/assets/Stride/SDSL/CloneTestBase.sdsl b/assets/Stride/SDSL/CloneTestBase.sdsl new file mode 100644 index 0000000000..63775da982 --- /dev/null +++ b/assets/Stride/SDSL/CloneTestBase.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader CloneTestBase +{ + stage void testFunc() {} +}; diff --git a/assets/Stride/SDSL/CloneTestExtern.sdsl b/assets/Stride/SDSL/CloneTestExtern.sdsl new file mode 100644 index 0000000000..ec06d0ee40 --- /dev/null +++ b/assets/Stride/SDSL/CloneTestExtern.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader CloneTestExtern : CloneTestBase +{ + override stage clone void testFunc() + { + base.testFunc(); + } +}; diff --git a/assets/Stride/SDSL/CloneTestRoot.sdsl b/assets/Stride/SDSL/CloneTestRoot.sdsl new file mode 100644 index 0000000000..ab31eb2406 --- /dev/null +++ b/assets/Stride/SDSL/CloneTestRoot.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader CloneTestRoot : CloneTestBase +{ + compose CloneTestExtern extern0; + compose CloneTestExtern extern1; + + override stage void testFunc() + { + base.testFunc(); + } +}; diff --git a/assets/Stride/SDSL/CoCLinearDepthShader.sdsl b/assets/Stride/SDSL/CoCLinearDepthShader.sdsl new file mode 100644 index 0000000000..82b4dda9f2 --- /dev/null +++ b/assets/Stride/SDSL/CoCLinearDepthShader.sdsl @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Outputs CoC and linear depth. + /// Expects as input: + /// - Texture0: the raw depth-buffer used to render the original scene + /// + shader CoCLinearDepthShader : ImageEffectShader, Camera, CircleOfConfusion + { + + stage override float4 Shading() + { + // Linearizes the depth for view space + float depth = Texture0.Sample(Sampler, streams.TexCoord).x; + float linearDepth = ZProjection.y / (depth - ZProjection.x); + + // Debug: use this to visualize with a color in the [0, 1] range + // color = 1.0 - linearDepth / FarClipPlane; + + // Calculates the CoC based on the linearized depth + float CoC = getCoCFactor(linearDepth); + + return float4(CoC, linearDepth, 0.0, 0.0); + } + }; +} diff --git a/assets/Stride/SDSL/CoCMapBlurShader.sdsl b/assets/Stride/SDSL/CoCMapBlurShader.sdsl new file mode 100644 index 0000000000..a4fdc018d7 --- /dev/null +++ b/assets/Stride/SDSL/CoCMapBlurShader.sdsl @@ -0,0 +1,70 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Blurs a CoC map but keeps sharp border around CoC == 0. + /// It prevents out-of-focus silhouette outline appearing in front of another out-of-focus object, + /// due to abrupt changes in the CoC transitions. + /// + /// + /// Number of weights. (And number of taps along one direction from the center.) + + shader CoCMapBlurShader : ImageEffectShader + { + // Direction to apply the blur. (normalized vector) + float2 Direction; + + // The radius of the blur to apply around the considered fragment + float Radius; + + // Weights of each tap + float2 OffsetsWeights[TBlurCount]; + + stage override float4 Shading() + { + float2 direction = Direction * Texture0TexelSize; + + // Add center + float2 centerCoCDepth = Texture0.Sample(LinearSampler, streams.TexCoord).xy; + //float centerDepth = centerCoCDepth.y; + float value = centerCoCDepth.x * OffsetsWeights[0].y; + + float totalWeight = OffsetsWeights[0].y; + + // Mirrored samples + [unroll] + for(int i = 1; i < TBlurCount; i++) + { + + [unroll] + for (int j = -1.0; j <= 1.0; j += 2) // Backward(-1) and forward(+1) along the direction + { + float2 tapCoCDepth = Texture0.Sample(LinearSampler, streams.TexCoord + j * direction * OffsetsWeights[i].x).xy; + + float contribution = 1.0; + + if ( tapCoCDepth.y <= centerCoCDepth.y ) { + // Pixel in the back should not accept a sample in front with CoC null. + contribution *= sign(tapCoCDepth.x); + } + else + { + // Pixel with CoC null should not accept any sample, except if the sample is in front. + // if (sign(centerCoCDepth.x) == 0) contribution = 0.0; + contribution = centerCoCDepth.x; + } + + contribution = saturate(contribution); + float tapWeight = OffsetsWeights[i].y * contribution; + value += tapCoCDepth.x * tapWeight; + totalWeight += tapWeight; + } + + } + + return float4(value / totalWeight, centerCoCDepth.y, 0.0, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/ColorBase.sdsl b/assets/Stride/SDSL/ColorBase.sdsl new file mode 100644 index 0000000000..7792d17540 --- /dev/null +++ b/assets/Stride/SDSL/ColorBase.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a color stream. +/// +shader ColorBase +{ + // A color attribute + stage stream float4 Color : COLOR; +}; diff --git a/assets/Stride/SDSL/ColorCombinerShader.sdsl b/assets/Stride/SDSL/ColorCombinerShader.sdsl new file mode 100644 index 0000000000..e282e3e5d4 --- /dev/null +++ b/assets/Stride/SDSL/ColorCombinerShader.sdsl @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A shader combiner + /// + internal shader ColorCombinerShader : ImageEffectShader + { + float Factors[10]; + + [Color] + float3 ModulateRGB[10]; + + stage override float4 Shading() + { + float3 color = 0; + if (count > 0) + color += Texture0.Sample(Sampler, streams.TexCoord).rgb * Factors[0] * ModulateRGB[0]; + if (count > 1) + color += Texture1.Sample(Sampler, streams.TexCoord).rgb * Factors[1] * ModulateRGB[1]; + if (count > 2) + color += Texture2.Sample(Sampler, streams.TexCoord).rgb * Factors[2] * ModulateRGB[2]; + if (count > 3) + color += Texture3.Sample(Sampler, streams.TexCoord).rgb * Factors[3] * ModulateRGB[3]; + if (count > 4) + color += Texture4.Sample(Sampler, streams.TexCoord).rgb * Factors[4] * ModulateRGB[4]; + if (count > 5) + color += Texture5.Sample(Sampler, streams.TexCoord).rgb * Factors[5] * ModulateRGB[5]; + if (count > 6) + color += Texture6.Sample(Sampler, streams.TexCoord).rgb * Factors[6] * ModulateRGB[6]; + if (count > 7) + color += Texture7.Sample(Sampler, streams.TexCoord).rgb * Factors[7] * ModulateRGB[7]; + if (count > 8) + color += Texture8.Sample(Sampler, streams.TexCoord).rgb * Factors[8] * ModulateRGB[8]; + if (count > 9) + color += Texture9.Sample(Sampler, streams.TexCoord).rgb * Factors[9] * ModulateRGB[9]; + + return float4(color, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/ColorTransformGroupShader.sdsl b/assets/Stride/SDSL/ColorTransformGroupShader.sdsl new file mode 100644 index 0000000000..7f9b617453 --- /dev/null +++ b/assets/Stride/SDSL/ColorTransformGroupShader.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Computes shading for all the groups of lights. +/// +shader ColorTransformGroupShader : ImageEffectShader +{ + compose ColorTransformShader Transforms[]; + + override stage float4 Shading() + { + float4 color = base.Shading(); + + foreach (var transform in Transforms) + { + color = transform.Compute(color); + } + return color; + } +}; diff --git a/assets/Stride/SDSL/ColorTransformShader.sdsl b/assets/Stride/SDSL/ColorTransformShader.sdsl new file mode 100644 index 0000000000..cf53d814ae --- /dev/null +++ b/assets/Stride/SDSL/ColorTransformShader.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A generic interface for processing/filtering a color. + /// + shader ColorTransformShader + { + float4 Compute(float4 color) + { + return color; + } + }; +} diff --git a/assets/Stride/SDSL/ColorUtility.sdsl b/assets/Stride/SDSL/ColorUtility.sdsl new file mode 100644 index 0000000000..6d1f7af9bd --- /dev/null +++ b/assets/Stride/SDSL/ColorUtility.sdsl @@ -0,0 +1,82 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ColorUtility +{ + // Converts an srgb color to linear space + float ToLinear(float sRGB) + { + // http://chilliant.blogspot.jp/2012/08/srgb-approximations-for-hlsl.html + return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878); + } + + // Converts an srgb color to linear space + float3 ToLinear(float3 sRGB) + { + return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878); + } + + // Converts an srgb color to linear space + float4 ToLinear(float4 sRGBa) + { + float3 sRGB = sRGBa.rgb; + return float4(sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878), sRGBa.a); + } + + // simple screen gamma conversion + float4 GammaToLinear (float4 RGBa, float Gamma = 2.2) + { + RGBa.rgb = pow(RGBa.rgb, 1.0/Gamma); + return RGBa; + } + + float4 LinearToGamma (float4 RGBa, float Gamma = 2.2) + { + RGBa.rgb = pow(RGBa.rgb, Gamma); + return RGBa; + } + + //https://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html + // Converts an sRGB color to linear space + float4 SRgbToLinear(float4 sRGBa) + { + float3 sRGB = sRGBa.rgb; + return float4(sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878), sRGBa.a); + } + + // Converts an linear color to sRGB space + float4 LinearToSRgb(float4 RGBa) + { + float3 RGB = RGBa.rgb; + + float3 S1 = sqrt(RGB); + float3 S2 = sqrt(S1); + float3 S3 = sqrt(S2); + + return float4(0.662002687f * S1 + 0.684122060f * S2 - 0.323583601f * S3 - 0.0225411470f * RGB, RGBa.a); + } + + //https://github.com/vvvv/VL.Stride/pull/395#issuecomment-760253956 + // Converts a color from linear to sRGB + float4 LinearToSRgbPrecise(float4 RGBa) + { + float3 rgb = RGBa.rgb; + float3 higher = 1.055 * pow(rgb, 1.0/2.4) - 0.055; + float3 lower = rgb * 12.92f; + + float3 cutoff = step(rgb, 0.0031308); + RGBa.rgb = lerp(higher, lower, cutoff); + return RGBa; + } + + // Converts a color from sRGB to linear + float4 SRgbToLinearPrecise(float4 sRGBa) + { + float3 srgb = sRGBa.rgb; + float3 higher = pow((srgb + 0.055) / 1.055, 2.4); + float3 lower = srgb / 12.92; + + float3 cutoff = step(srgb, 0.04045); + sRGBa.rgb = lerp(higher, lower, cutoff); + return sRGBa; + } +}; diff --git a/assets/Stride/SDSL/CombineFrontCoCShader.sdsl b/assets/Stride/SDSL/CombineFrontCoCShader.sdsl new file mode 100644 index 0000000000..9510c3e829 --- /dev/null +++ b/assets/Stride/SDSL/CombineFrontCoCShader.sdsl @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + + +namespace Stride.Rendering.Images +{ + + /// + /// Combines the different blur levels depending on the pixel's CoC. (Front area only.) + /// + shader CombineFrontCoCShader : ImageEffectShader + { + + stage override float4 Shading() + { + + // Fetch all our levels + float4 colorLevels[8]; + + // Note: Manually unrolled until better HLSL2GLSL support + if (TLevelCount >= 1) + colorLevels[0] = Texture2.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 2) + colorLevels[1] = Texture3.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 3) + colorLevels[2] = Texture4.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 4) + colorLevels[3] = Texture5.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 5) + colorLevels[4] = Texture6.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 6) + colorLevels[5] = Texture7.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 7) + colorLevels[6] = Texture8.Sample(LinearSampler, streams.TexCoord).rgba; + if (TLevelCount >= 8) + colorLevels[7] = Texture9.Sample(LinearSampler, streams.TexCoord).rgba; + + + float4 result = float4(0.0, 0.0, 0.0, 0.0); + + // Gets the CoC of the current pixel + float CoC = Texture0.Sample(LinearSampler, streams.TexCoord).x; + + // A front object has by default its in-focus color. + if (CoC < 0) result = colorLevels[0]; + + // Alpha blend all the layers in the good order + // TODO we should be more selective and only blend the layer closest to the pixel CoC + [unroll] + for (int k = 1; k < TLevelCount; k++) + { + float4 layerColor = colorLevels[k]; + float newAlpha = layerColor.a + result.a * (1.0 - layerColor.a); + float3 newRGB = float4(0.0, 0.0, 0.0, 0.0); + if (newAlpha > 0) + { + newRGB = (layerColor.rgb * layerColor.a + result.rgb * result.a * (1.0 - layerColor.a)) / newAlpha; + } + result = float4(newRGB, newAlpha); + } + + // Need pre-multiply alpha for the blending with the render target. + result.rgb *= result.a; + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl b/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl new file mode 100644 index 0000000000..e87644859f --- /dev/null +++ b/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl @@ -0,0 +1,123 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Define to visualize debug colors for the different CoC levels. +#define DEBUG_COC_LEVEL_COLOR 0 + +namespace Stride.Rendering.Images +{ + /// + /// This takes in entry several blurred levels, and depending on the pixel CoC, + /// the final color will be an interpolation between 2 of these levels. + /// Level 0 is the original sharp image. The last level is the blurriest version. + /// Expects as input: + /// - Texture0: a [CoC, Linear Depth] buffer + /// - Texture1 ~ TextureX: the different blur levels. (0 == no blur) + /// + /// + /// Total number of layers used, including the original non-blurred image. + + shader CombineLevelsFromCoCShader : ImageEffectShader + { + // The CoC corresponding to each level of blur + stage float CoCLevelValues[TLevelCount]; + + stage override float4 Shading() + { + // Need to be able to access blur textures by index + //Texture2D dofTextureLevels[8] = + //{ + // Texture2, + // Texture3, + // Texture4, + // Texture5, + // Texture6, + // Texture7, + // Texture8, + // Texture9 + //}; + +#if DEBUG_COC_LEVEL_COLOR + // Some debug colors to visualize each layer + float3 debugColors[8] = + { + float3(1.0, 1.0, 1.0), + float3(0.5, 0.5, 1.0), + float3(0.5, 1.0, 0.5), + float3(1.0, 0.5, 0.5), + // Set more colors here + float3(1.0, 0.0, 0.0), + float3(1.0, 0.0, 0.0), + float3(1.0, 0.0, 0.0), + float3(1.0, 0.0, 0.0) + }; +#endif + + // Fetch all our levels + float3 colorLevels[8]; + + // Note: Manually unrolled until better HLSL2GLSL support + if (TLevelCount >= 1) + colorLevels[0] = Texture2.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 2) + colorLevels[1] = Texture3.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 3) + colorLevels[2] = Texture4.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 4) + colorLevels[3] = Texture5.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 5) + colorLevels[4] = Texture6.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 6) + colorLevels[5] = Texture7.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 7) + colorLevels[6] = Texture8.Sample(LinearSampler, streams.TexCoord).rgb; + if (TLevelCount >= 8) + colorLevels[7] = Texture9.Sample(LinearSampler, streams.TexCoord).rgb; + + [unroll] + for (int k = 0; k < TLevelCount; k++) + { + //colorLevels[k] = dofTextureLevels[k].Sample(LinearSampler, streams.TexCoord).rgb; +#if DEBUG_COC_LEVEL_COLOR + // Affects a debug color + colorLevels[k] *= debugColors[k]; +#endif + } + + // Gets the CoC of the current pixel + float CoC = abs(Texture0.Sample(LinearSampler, streams.TexCoord).x); + + // If the pixel is not in focus, use a blur version of the CoC to avoid sharp transitions + float blurredCoC = Texture1.Sample(LinearSampler, streams.TexCoord).x; + CoC = lerp(CoC, blurredCoC, sign(blurredCoC)); + + float3 result = float3(0.0, 0.0, 0.0); + + // We now find the 2 levels closest to the pixel CoC. + // We go down the levels, starting at the blurriest version. Once we find a level pair + // whose range contains our CoC, we keep the lerp between these 2 levels. + // (This part also supports a branch-less version.) + [unroll] + for (int i = TLevelCount - 2; i >= 0; i--) + { + // Current range we consider + float rangeMin = CoCLevelValues[i]; + float rangeMax = CoCLevelValues[i + 1]; + + // Does our CoC belong to this range? + float cocInRange = ((rangeMin < CoC && CoC <= rangeMax) || (rangeMin == CoC && rangeMin == 0))? 1.0 : 0.0; + // Here is the same test in a branch-less version for reference: + // float cocInRange = step(rangeMin, CoC) * step(CoC, rangeMax) * sign( abs(CoC - rangeMin)); + // cocInRange += (1.0 - sign(rangeMin)) * (1.0 - sign(CoC)); //Special edge-case for CoC 0 + + // We calculate the lerp factor between the 2 levels. + float lerpFactor = clamp( (CoC - rangeMin) / (rangeMax - rangeMin), 0.0, 1.0 ); // try smoothstep()? + + // We keep the lerp result only if the current level pair contains our CoC + result += cocInRange * lerp(colorLevels[i], colorLevels[i+1], lerpFactor); + } + + return float4( result, 1.0 ); + } + }; +} diff --git a/assets/Stride/SDSL/CompilationErrorShader.sdsl b/assets/Stride/SDSL/CompilationErrorShader.sdsl new file mode 100644 index 0000000000..688292ac4b --- /dev/null +++ b/assets/Stride/SDSL/CompilationErrorShader.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader CompilationErrorShader : ShadingBase +{ + // method computing color + stage override float4 Shading() + { + float factor = sin(Global.Time * 6.0f) * 0.25f + 0.25f; + float4 errorColor = float4(1.0f, 0.25f, 0.25f, 1.0f); + + // High frequency glow to let user know effect is reloading + return lerp(base.Shading(), errorColor, factor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColor.sdsl b/assets/Stride/SDSL/ComputeColor.sdsl new file mode 100644 index 0000000000..3aeba9aa7e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColor.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Base shader to compute a color (float4). +/// +shader ComputeColor +{ + float4 Compute() + { + return 0; + } +}; diff --git a/assets/Stride/SDSL/ComputeColor3.sdsl b/assets/Stride/SDSL/ComputeColor3.sdsl new file mode 100644 index 0000000000..697d709006 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColor3.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Base shader to compute a color (float3). +/// +shader ComputeColor3 +{ + float3 Compute() + { + return 0; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorAdd.sdsl b/assets/Stride/SDSL/ComputeColorAdd.sdsl new file mode 100644 index 0000000000..33c1befd38 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorAdd.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorAdd : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + return tex1.rgba + tex2.rgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorAdd3.sdsl b/assets/Stride/SDSL/ComputeColorAdd3.sdsl new file mode 100644 index 0000000000..5b32dba7e3 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorAdd3.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorAdd3 : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + return tex1.rgba + float4(tex2.rgb, 0.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl b/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl new file mode 100644 index 0000000000..41f66b22fe --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorAdd3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Add: + // r = fc + bc + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = frontColor.rgb + backColor.rgb; + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorAddMaya.sdsl b/assets/Stride/SDSL/ComputeColorAddMaya.sdsl new file mode 100644 index 0000000000..ef218b08ad --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorAddMaya.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorAddMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Add: + // color = bc + (fc * fa) + // alpha = ba + // + + return float4(backColor.rgb + (frontColor.rgb * frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorAverage.sdsl b/assets/Stride/SDSL/ComputeColorAverage.sdsl new file mode 100644 index 0000000000..9149b96a5c --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorAverage.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorAverage : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Average: + // r = (fc + bc) /2 + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 averageColor = (frontColor.rgb + backColor.rgb) * 0.5f; + + return BlendUtils.BasicBlend(backColor, frontColor, averageColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorCave.sdsl b/assets/Stride/SDSL/ComputeColorCave.sdsl new file mode 100644 index 0000000000..b6f39902c2 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorCave.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorCave : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + compose ComputeColor color3; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + float4 tex3 = color3.Compute(); + + float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); + float3 mix2 = mix1 * tex3.rgb; + + return float4(mix2, 1.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorColor.sdsl b/assets/Stride/SDSL/ComputeColorColor.sdsl new file mode 100644 index 0000000000..fe9336d0ce --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorColor.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorColor : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Color: + // if sat(fc) == 0 : color = val(bc), val(bc), val(bc) + // if sat(fc) != 0 : color = rgb(hue(fc), sat(fc), val(bc)) + // + // alpha = fa * (1-ba) + ba + + float3 color; + float frontSaturation = HSVUtils.GetSaturation(frontColor.rgb); + + if(frontSaturation == 0.0f) { + float valueResult = HSVUtils.GetValue(backColor.rgb); + color = float3(valueResult, valueResult, valueResult); + } else { + color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(frontColor.rgb), frontSaturation, HSVUtils.GetValue(backColor.rgb))); + } + + return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorColorBurn.sdsl b/assets/Stride/SDSL/ComputeColorColorBurn.sdsl new file mode 100644 index 0000000000..cfdfff98fb --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorColorBurn.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorColorBurn : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // http://en.wikipedia.org/wiki/Blend_modes#Dodge_and_burn + // The Color Burn mode divides the inverted bottom layer by the top layer, and then inverts the result + return float4(1.0f - BlendUtils.ColorDivide((1.0f - backColor.rgb), frontColor.rgb), 1.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorColorDodge.sdsl b/assets/Stride/SDSL/ComputeColorColorDodge.sdsl new file mode 100644 index 0000000000..dab222b6ac --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorColorDodge.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorColorDodge : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtain with the above formula + // + // ColorDodge: + // if (fc == 1) : r = ceiling(bc) + // if (fc != 1) : r = bc / (1 - fc) in[0,1] + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = lerp(saturate(backColor.rgb / (1.0f - frontColor.rgb)), + ceil(backColor.rgb), + BlendUtils.Equals(frontColor.rgb, 1.0f)); + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl b/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl new file mode 100644 index 0000000000..ff61960f00 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the color behind the key passed as generic. +/// +/// +/// LinkName: generic LinkType - the name of the key used to set the color. +/// +shader ComputeColorConstantColorLink : ComputeColor +{ + cbuffer PerMaterial + { + [Color] + [Link("LinkName")] + stage float4 constantColor; + } + + override float4 Compute() + { + return constantColor; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl b/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl new file mode 100644 index 0000000000..c7a13257a2 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the color from a float behind the key passed as generic. +/// +/// +/// LinkName: generic LinkType - the name of the key used to set the float value. +/// +shader ComputeColorConstantFloatLink : ComputeColor +{ + cbuffer PerMaterial + { + [Link("LinkName")] + stage float constantFloat; + } + + override float4 Compute() + { + return float4(constantFloat, constantFloat, constantFloat, constantFloat); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorConstantLink.sdsl b/assets/Stride/SDSL/ComputeColorConstantLink.sdsl new file mode 100644 index 0000000000..53294cf6ef --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorConstantLink.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the color from a float4 behind the key passed as generic. +/// +/// +/// LinkName: generic LinkType - the name of the key used to set the float4. +/// +shader ComputeColorConstantLink : ComputeColor +{ + [Link("LinkName")] + stage float4 constantColor; + + override float4 Compute() + { + return constantColor; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl b/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl new file mode 100644 index 0000000000..93e3499c1f --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDarken3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Darken: + // color = min((1 - fa) * ba * bc + (fa * fc), (1 - ba) * fa * fc + (ba * bc)) + // alpha = fa * (1-ba) + ba + + return float4(min(lerp(backColor.a * backColor.rgb, frontColor.rgb, frontColor.a), lerp(frontColor.a * frontColor.rgb, backColor.rgb, backColor.a)), + BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl b/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl new file mode 100644 index 0000000000..0a9e54e239 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDarkenMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Darken: + // color = min(fc, bc) * fa + bc * (1 - fa) + // alpha = ba + + float3 min = min(frontColor.rgb, backColor.rgb); + + //return float4(lerp(backColor.rgb, min, frontColor.a), frontColor.a); + return float4(lerp(backColor.rgb, min, frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDesaturate.sdsl b/assets/Stride/SDSL/ComputeColorDesaturate.sdsl new file mode 100644 index 0000000000..42a5659201 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDesaturate.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDesaturate : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Desaturate: + // color = bc * (1 - (fc * fa)) + // alpha = ba + + return float4(backColor.rgb * (1.0f - (frontColor.rgb * frontColor.a)), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl b/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl new file mode 100644 index 0000000000..5d01309282 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDifference3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // ColorDodge: + // r = abs(fc - bc) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = abs(frontColor.rgb - backColor.rgb); + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl b/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl new file mode 100644 index 0000000000..aae32624d6 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDifferenceMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Difference: + // color = abs(fc - bc) * fa + bc * (1 - fa) + // alpha = ba + + float3 diff = abs(frontColor.rgb - backColor.rgb); + + return float4(lerp(backColor.rgb, diff, frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorDivide.sdsl b/assets/Stride/SDSL/ComputeColorDivide.sdsl new file mode 100644 index 0000000000..7981fc646e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorDivide.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorDivide : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Divide: + // if (fc == 0 && bc == 0) : r = 0 + // if (fc == 0 && bc != 0) : r = 1 + // if (fc != 0) : r = bc / fc + // + // color = r + // alpha = fa * (1-ba) + ba + + float3 interColor = BlendUtils.ColorDivide(backColor.rgb, frontColor.rgb); + + return float4(interColor, + BlendUtils.BasicAlphaBlend(backColor.a,frontColor.a)); + } +}; + diff --git a/assets/Stride/SDSL/ComputeColorExclusion.sdsl b/assets/Stride/SDSL/ComputeColorExclusion.sdsl new file mode 100644 index 0000000000..7b61397816 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorExclusion.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorExclusion : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Exclusion: + // r = fc + bc - 2*(fc * bc) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = frontColor.rgb + backColor.rgb - 2.0f * frontColor.rgb * backColor.rgb ; + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorFixed.sdsl b/assets/Stride/SDSL/ComputeColorFixed.sdsl new file mode 100644 index 0000000000..7945f29521 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorFixed.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns a fixed color. +/// +/// +/// TVALUE: generic float4 - the color (as a float4). +/// +shader ComputeColorFixed : ComputeColor +{ + override float4 Compute() + { + return TVALUE; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorFromStream.sdsl b/assets/Stride/SDSL/ComputeColorFromStream.sdsl new file mode 100644 index 0000000000..6467552eca --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorFromStream.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Compute the color from a stream +/// +shader ComputeColorFromStream : ComputeColor +{ + stream float4 LocalColor : TStream; + + override float4 Compute() { + return saturate(streams.LocalColor.TRgba); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorHardLight.sdsl b/assets/Stride/SDSL/ComputeColorHardLight.sdsl new file mode 100644 index 0000000000..31433e1f2f --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorHardLight.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorHardLight : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // HardLight: + // if (fc < 0.5) : r = 2 * fc * bc + // if (fc >= 0.5) : r = 1 - 2*(1 - fc)*(1 - bc) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = lerp(2.0f * frontColor.rgb * backColor.rgb, + 1.0f - 2.0f * (1.0f - frontColor.rgb) * (1.0f - backColor.rgb), + step(0.5, frontColor.rgb)); + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorHardMix.sdsl b/assets/Stride/SDSL/ComputeColorHardMix.sdsl new file mode 100644 index 0000000000..fb8d585c2d --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorHardMix.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorHardMix : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // HardMix: + // if (bc + fc) <= 1 : r = 0 (in 3DsMax, the case (bc + fc == 1) always return 0) + // if (bc + fc) > 1 : r = 1 + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = 1.0f - step(backColor.rbg + frontColor.rgb, 1.0f); + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorHue.sdsl b/assets/Stride/SDSL/ComputeColorHue.sdsl new file mode 100644 index 0000000000..2ef9893ac8 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorHue.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorHue : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Hue: + // if sat(fc) == 0 : color = val(bc), val(bc), val(bc) + // if sat(fc) != 0 : color = rgb(hue(fc), sat(bc), val(bc)) + // + // alpha = fa * (1-ba) + ba + + float3 color; + + if(HSVUtils.GetSaturation(frontColor.rgb) == 0.0f) { + float colorValue = HSVUtils.GetValue(backColor.rgb); + color = float3(colorValue, colorValue, colorValue); + } else { + color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(frontColor.rgb), HSVUtils.GetSaturation(backColor.rgb), HSVUtils.GetValue(backColor.rgb))); + } + + return float4(color, + BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorIlluminate.sdsl b/assets/Stride/SDSL/ComputeColorIlluminate.sdsl new file mode 100644 index 0000000000..60917c1f4e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorIlluminate.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorIlluminate : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Illuminate: + // color = bc * (2 * fc * fa + 1 - fa) + // alpha = ba + + return float4(backColor.rgb * (2.0f * frontColor.rgb * frontColor.a + 1.0f - frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorIn.sdsl b/assets/Stride/SDSL/ComputeColorIn.sdsl new file mode 100644 index 0000000000..eafa39907e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorIn.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorIn : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // In: + // color = bc * fa + // alpha = ba * fa + + return backColor * frontColor.a; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl b/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl new file mode 100644 index 0000000000..d8233c19d5 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorLerpAlpha : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); + + return float4(mix1, 1.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl b/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl new file mode 100644 index 0000000000..0b56d9b25b --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorLighten3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Lighten: + // color = max((1 - fa) * ba * bc + (fa * fc), (1 - ba) * fa * fc + (ba * bc)) + // alpha = fa * (1-ba) + ba + + return float4(max(lerp(backColor.a * backColor.rgb, frontColor.rgb, frontColor.a), lerp(frontColor.a * frontColor.rgb, backColor.rgb, backColor.a)), + BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl b/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl new file mode 100644 index 0000000000..d637a2bda6 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorLightenMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Lighten: + // color = max(fc, bc) * fa + bc * (1 - fa) + // alpha = ba + + float3 maxColor = max(frontColor.rgb, backColor.rgb); + + return float4(lerp(backColor.rgb, maxColor, frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl b/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl new file mode 100644 index 0000000000..a1d8995fa5 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorLinearBurn : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // LinearBurn: + // if (bc + fc) <= 1 : r = 0 + // if (bc + fc) > 1 : r = fc + bc - 1 + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = lerp(frontColor.rgb + backColor.rgb - 1.0f, + 0.0f, + step(1.0f , (frontColor.rbg + backColor.rgb))); + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; + + diff --git a/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl b/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl new file mode 100644 index 0000000000..bd508fd77c --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorLinearDodge : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Linear Dodge: + // r = fc + bc in [0,1] + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = saturate(frontColor.rgb + backColor.rgb); + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMask.sdsl b/assets/Stride/SDSL/ComputeColorMask.sdsl new file mode 100644 index 0000000000..fc1e2a24a4 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMask.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +//shader ComputeColorDifference3ds : ComputeColor +shader ComputeColorMask : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 mask = color2.Compute(); + + // t = texture, m = mask, c = color, a = alpha + // + // Mask: + // color = tc + // alpha = ta * avg(mc) + + return float4(backColor.rgb, + backColor.a * (mask.r + mask.g + mask.b) / 3.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMask3ds.sdsl b/assets/Stride/SDSL/ComputeColorMask3ds.sdsl new file mode 100644 index 0000000000..ca606c7992 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMask3ds.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +//shader ComputeColorDifference3ds : ComputeColor +shader ComputeColorMask3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor maskColor; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 mask = maskColor.Compute(); + + // t = texture, m = mask, c = color, a = alpha + // + // Mask: + // color = tc + // alpha = ta * avg(mc) + + return float4(backColor.rgb, + backColor.a * (mask.r + mask.g + mask.b) / 3.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl b/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl new file mode 100644 index 0000000000..8bea684ed4 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader ComputeColorMaterialAlphaBlend : ComputeColor, MaterialPixelStream +{ + compose ComputeColor color; + + override float4 Compute() + { + var alpha = 2.0 * color.Compute().x; + float specularFactor = min(1, alpha); + float diffuseFactor = max(0, alpha - 1.0); + return float4(diffuseFactor, specularFactor, 0, 0); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMultiply.sdsl b/assets/Stride/SDSL/ComputeColorMultiply.sdsl new file mode 100644 index 0000000000..1ca85eb525 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMultiply.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorMultiply : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + float4 mix1 = tex1 * tex2; + + return mix1; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl b/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl new file mode 100644 index 0000000000..dc66cd54d8 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorMultiply3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Multiply: + // r = fc * bc + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 interColor = frontColor.rgb * backColor.rgb; + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl b/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl new file mode 100644 index 0000000000..b8c3f7b197 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorMultiplyMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Multiply: + // color = bc * (fc * fa + 1 - fa) + // alpha = ba + + return float4(backColor.rgb * (frontColor.rgb * frontColor.a + 1.0f - frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOne.sdsl b/assets/Stride/SDSL/ComputeColorOne.sdsl new file mode 100644 index 0000000000..0e7819dca3 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOne.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the white opaque color. +/// +shader ComputeColorOne : ComputeColor +{ + override float4 Compute() + { + return 1; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOut.sdsl b/assets/Stride/SDSL/ComputeColorOut.sdsl new file mode 100644 index 0000000000..617312f11b --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOut.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOut : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Out: + // color = bc * (1 - fa) + // alpha = ba * (1 - fa) + + return backColor * (1.0f - frontColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOutdoor.sdsl b/assets/Stride/SDSL/ComputeColorOutdoor.sdsl new file mode 100644 index 0000000000..5ad4861e0e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOutdoor.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOutdoor : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + compose ComputeColor color3; + compose ComputeColor color4; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + float4 tex3 = color3.Compute(); + + float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); + float3 mix2 = lerp(mix1.rgb, tex3.rgb, tex3.a); + + return float4(mix2, 1.0f); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOver3ds.sdsl b/assets/Stride/SDSL/ComputeColorOver3ds.sdsl new file mode 100644 index 0000000000..a4af3073df --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOver3ds.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOver3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Over: + // r = fc + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + return BlendUtils.BasicBlend(backColor, frontColor, frontColor.rgb); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOverMaya.sdsl b/assets/Stride/SDSL/ComputeColorOverMaya.sdsl new file mode 100644 index 0000000000..33da6e6d7e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOverMaya.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOverMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Over: + // color = bc + ((fc - bc) * fa) = (1 - fa) * bc + fa * fc + // alpha = ba + fa - (ba * fa) + // + + return float4(lerp(backColor.rgb, frontColor.rgb, frontColor.a), + BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOverlay.sdsl b/assets/Stride/SDSL/ComputeColorOverlay.sdsl new file mode 100644 index 0000000000..a8095b46eb --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOverlay.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOverlay : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + // http://en.wikipedia.org/wiki/Blend_modes#Overlay + // if a < 0.5f: 2ab + // if a >= 0.5f: 1 - 2(1 - a)(1 - b) + return lerp(2.0f * tex1 * tex2, + 1.0f - 2.0f * (1.0f - tex1) * (1.0f - tex2), + step(tex2, 0.5)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl b/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl new file mode 100644 index 0000000000..74346a94c8 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorOverlay3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Overlay: + // if bc < 0.5 : r = 2fc * bc + // if bc >= 0.5 : r = 1 - 2(1 - fc)(1 - bc) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = lerp(2.0f * frontColor.rgb * backColor.rgb, + 1.0f - 2.0f * (1.0f - frontColor.rgb) * (1.0f - backColor.rgb), + step(backColor.rgb, 0.5f)); + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorParameter.sdsl b/assets/Stride/SDSL/ComputeColorParameter.sdsl new file mode 100644 index 0000000000..1bd60ba73a --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorParameter.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the color from a parameter. +/// +shader ComputeColorParameter : ComputeColor +{ + [Color] + stage float4 ColorParameter; + + override float4 Compute() + { + return ColorParameter; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorPinLight.sdsl b/assets/Stride/SDSL/ComputeColorPinLight.sdsl new file mode 100644 index 0000000000..02e95946e1 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorPinLight.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorPinLight : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // PinLight: + // if fc <= 0.5 : r = min(bc, 2fc) + // if fc > 0.5 : r = max(bc, (2fc - 1)) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = lerp(max(backColor.rgb, (2.0f * frontColor.rgb - 1.0f)), + min(backColor.rgb, 2.0f * frontColor.rgb), + step(frontColor.rgb, 0.5f)); + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorRadial.sdsl b/assets/Stride/SDSL/ComputeColorRadial.sdsl new file mode 100644 index 0000000000..acfea5db73 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorRadial.sdsl @@ -0,0 +1,24 @@ +// This is a little more complex example which you can use +// Refer to the Radial Partical System in the Editor +// Under Material it uses a Shader for its Emissive color, and the shader's name is ComputeColorRadial +// In addition to ComputeColor this shader also inherits Texturing so it can use texture coordinates +// ColorCenter and ColorEdge are design time permutations and appear in the shader dictionary when you choose ComputeColorRadial from the proeprty grid + +shader ComputeColorRadial : ComputeColor, Texturing +{ + override float4 Compute() + { + float radialDistance = length(streams.TexCoord - float2(0.5, 0.5)) * 2; + + float4 unclamped = lerp(ColorCenter, ColorEdge, radialDistance); + + // We want to allow the intensity to grow a lot, but cap the alpha to 1 + float4 clamped = clamp(unclamped, float4(0, 0, 0, 0), float4(1000, 1000, 1000, 1)); + + // Remember that we use a premultiplied alpha pipeline so all color values should be premultiplied + clamped.rgb *= clamped.a; + + return clamped; + } +}; + diff --git a/assets/Stride/SDSL/ComputeColorRed.sdsl b/assets/Stride/SDSL/ComputeColorRed.sdsl new file mode 100644 index 0000000000..5435bcb468 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorRed.sdsl @@ -0,0 +1,13 @@ +// This is the simplest way of overriding particle shader behavior +// Refer to the Red Particle System in the Editor +// Under Material it uses a Shader for its Emissive color, and the shader's name is ComputeColorRed +// As long as your shader inherits ComputeColor and overrides float4 Compute() you can add any custom behavior to it + +shader ComputeColorRed : ComputeColor +{ + override float4 Compute() + { + return float4(1, 0, 0, 1); + } +}; + diff --git a/assets/Stride/SDSL/ComputeColorSaturate.sdsl b/assets/Stride/SDSL/ComputeColorSaturate.sdsl new file mode 100644 index 0000000000..32e01a3676 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSaturate.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSaturate : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Saturate: + // color = bc * (1 + (fc * fa)) + // alpha = ba + + return float4(backColor.rgb * (1.0f + (frontColor.rgb * frontColor.a)), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSaturation.sdsl b/assets/Stride/SDSL/ComputeColorSaturation.sdsl new file mode 100644 index 0000000000..d0777e1e06 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSaturation.sdsl @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSaturation : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Saturation: + // if sat(bc) == 0 : color = val(bc), val(bc), val(bc) + // if sat(bc) != 0 : color = rgb(hue(bc), sat(fc), val(bc)) + // + // alpha = fa * (1-ba) + ba + + float3 color; + float backSaturation = HSVUtils.GetSaturation(backColor.rgb); + if( backSaturation == 0.0f) { + float colorValue = HSVUtils.GetValue(backColor.rgb); + color = float3(colorValue, colorValue, colorValue); + } else { + color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(backColor.rgb), HSVUtils.GetSaturation(frontColor.rgb), HSVUtils.GetValue(backColor.rgb))); + } + + return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorScaler.sdsl b/assets/Stride/SDSL/ComputeColorScaler.sdsl new file mode 100644 index 0000000000..58f41d9ac2 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorScaler.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorScaler : ComputeColor +{ + override float4 Compute() + { + float4 baseColor = base.Compute(); + // TODO Check where to put gamma correction? => float tempScaleValue = pow(TScaleValue, 2.2) + // USe faster 2.0 instead of 2.2 + return float4(baseColor.xyz * TScaleValue * TScaleValue, baseColor.w); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorScreen.sdsl b/assets/Stride/SDSL/ComputeColorScreen.sdsl new file mode 100644 index 0000000000..79c4e36b1e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorScreen.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorScreen : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha + // + // Screen: + // color = fc * fa * (1 - bc * ba) + bc * ba + // alpha = fa * (1-ba) + ba + + return float4(frontColor.rgb * frontColor.a * (1.0f - backColor.rgb * backColor.a) + backColor.rgb * backColor.a, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSoftLight.sdsl b/assets/Stride/SDSL/ComputeColorSoftLight.sdsl new file mode 100644 index 0000000000..45157e6c49 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSoftLight.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSoftLight : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // SoftLight: + // if fc < 0.5 : r = bc(1 + (1 - bc)(2fc - 1)) + // else if bc < 9/64 : r = bc(bc(9 - 18fc) + 5.76fc - 1.88) + // else : r = bc + (sqrt(bc) - bc)(2fc - 1) + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r1 = backColor.rgb * (1.0f + (1.0f - backColor.rgb) * (2.0f * backColor.rgb -1.0f)); + float3 r2 = backColor.rgb * (backColor.rgb * (9.0f - 18.0f * frontColor.rgb) + 5.76f *frontColor.rgb -1.88f); + float3 r3 = backColor.rgb + (sqrt(backColor.rgb) - backColor.rgb) * (2.0f * frontColor.rgb - 1.0f); + + float interColor = lerp( r1, + lerp(r2, + r3, + step(9.0f / 64.0f, backColor.rgb)), + step(0.5f, frontColor.rgb)); + + return BlendUtils.BasicBlend(backColor, frontColor, interColor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorStream.sdsl b/assets/Stride/SDSL/ComputeColorStream.sdsl new file mode 100644 index 0000000000..75a3db6de4 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorStream.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Returns the color attribute of the mesh. +/// +shader ComputeColorStream : ComputeColor, ColorBase +{ + override float4 Compute() { + return streams.Color; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl b/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl new file mode 100644 index 0000000000..54bf3be179 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSubstituteAlpha : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + return float4(tex1.rgb, tex2.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl b/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl new file mode 100644 index 0000000000..1af92e63ee --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSubstituteAlphaWithColor : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 tex1 = color1.Compute(); + float4 tex2 = color2.Compute(); + + return float4(tex1.rgb, tex2.r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSubtract.sdsl b/assets/Stride/SDSL/ComputeColorSubtract.sdsl new file mode 100644 index 0000000000..af3e077af0 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSubtract.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSubtract : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + return backColor - frontColor; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl b/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl new file mode 100644 index 0000000000..088a73a9d2 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSubtract3ds : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Add: + // r = bc - fc + // + // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc + // alpha = fa * (1-ba) + ba + + float3 r = backColor.rgb - frontColor.rgb; + + return BlendUtils.BasicBlend(backColor, frontColor, r); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl b/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl new file mode 100644 index 0000000000..0a2c5e1322 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSubtractMaya : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From Maya API (LayeredTexture node) + // + // b = background, f = foreground, c = color, a = alpha + // + // Subtract: + // color = bc - (fc * fa) + // alpha = ba + + return float4(backColor.rgb - (frontColor.rgb * frontColor.a), + backColor.a); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorSynthetic.sdsl b/assets/Stride/SDSL/ComputeColorSynthetic.sdsl new file mode 100644 index 0000000000..fe4e3986d6 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorSynthetic.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorSynthetic : ComputeColor +{ + override float4 Compute() + { + return Material.SpecularColorValue; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTexture.sdsl b/assets/Stride/SDSL/ComputeColorTexture.sdsl new file mode 100644 index 0000000000..08b82a0651 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTexture.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with default sampler. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// +shader ComputeColorTexture : ComputeColor +{ + stage stream float2 TexCoord : TStream; + + override float4 Compute() + { + return TTexture.Sample(Texturing.Sampler, streams.TexCoord); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl b/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl new file mode 100644 index 0000000000..71f22298b2 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with default sampler wit a scale and an offset. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// +shader ComputeColorTextureDynamicScaledOffset : ComputeColor +{ + stage stream float2 TexCoord : TStream; + + // ------------------------------------- + // uniforms + // ------------------------------------- + stage float2 Offset = float2(0,0); + stage float2 Scale = float2(1,1); + + override float4 Compute() + { + return TTexture.Sample(Texturing.Sampler, streams.TexCoord * Scale + Offset); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl new file mode 100644 index 0000000000..6fd51fd12f --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TSampler: generic SamplerState - the sampler. +/// +shader ComputeColorTextureLodSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() + { + return Texture.SampleLevel(Sampler, streams.TexCoord, TLod).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl new file mode 100644 index 0000000000..e5e84675f9 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. +/// TOffset: generic LinkType - the float2 key for texture coordinates offset. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureLodScaledOffsetDynamicSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + cbuffer PerMaterial + { + [Link("TScale")] + stage float2 scale; + + [Link("TOffset")] + stage float2 offset; + } + + override float4 Compute() { + return Texture.SampleLevel(Sampler, streams.TexCoord * scale + offset, TLod).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl new file mode 100644 index 0000000000..780d3fdd90 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// TOffset: generic float2 - the texture coordinates offset. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureLodScaledOffsetSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() { + return Texture.SampleLevel(Sampler, streams.TexCoord * TScale + TOffset, TLod).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl new file mode 100644 index 0000000000..a6aeef0282 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureLodScaledSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() + { + return Texture.SampleLevel(Sampler, streams.TexCoord * TScale, TLod).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl b/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl new file mode 100644 index 0000000000..fbe8671779 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a repeated texture with default sampler. Default sampler should be on repeat for this shader to behave correctly. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TFactor: generic float - the repeat factor. +/// +shader ComputeColorTextureRepeat : ComputeColor +{ + stage stream float2 TexCoord : TStream; + + override float4 Compute() + { + return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TFactor); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl new file mode 100644 index 0000000000..621a08f55b --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TSampler: generic SamplerState - the sampler. +/// +shader ComputeColorTextureSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() + { + return Texture.Sample(Sampler, streams.TexCoord).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl new file mode 100644 index 0000000000..9ec08a6df8 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with the default sampler and fix texture coordinates scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// +shader ComputeColorTextureScaled : ComputeColor +{ + stream float2 TexCoord : TStream; + + override float4 Compute() { + return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TScale); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl new file mode 100644 index 0000000000..72c6de2899 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with the default sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// TOffset: generic float2 - the texture coordinates offset. +/// +shader ComputeColorTextureScaledOffset : ComputeColor +{ + stream float2 TexCoord : TStream; + + override float4 Compute() { + return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TScale + TOffset); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl new file mode 100644 index 0000000000..1b8063fb58 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. +/// TOffset: generic LinkType - the float2 key for texture coordinates offset. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureScaledOffsetDynamicSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + cbuffer PerMaterial + { + [Link("TScale")] + stage float2 scale; + + [Link("TOffset")] + stage float2 offset; + } + + override float4 Compute() { + return Texture.Sample(Sampler, streams.TexCoord * scale + offset).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl new file mode 100644 index 0000000000..888db62590 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl @@ -0,0 +1,89 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. +/// TOffset: generic LinkType - the float2 key for texture coordinates offset. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureScaledOffsetDynamicSamplerRandomUV : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + cbuffer PerMaterial + { + [Link("TScale")] + stage float2 scale; + + [Link("TOffset")] + stage float2 offset; + } + + //------------------------------------------------------------------------------ + // Gererate pseudorandom number + //------------------------------------------------------------------------------ + float Random(in float2 uv) + { + float2 noise = (frac(sin(dot(uv,float2(12.9898,78.233)*2.0)) * 43758.5453)); + return abs(noise.x + noise.y) * 0.5; + } + + //------------------------------------------------------------------------------ + // Gererate texture coordinates for random placement + //------------------------------------------------------------------------------ + float2 RandomUV(in float2 uv) + { + const uint NUM_PATTERNS = 2 * 2 * 4 * 4 * 4; + + uint pattern = (uint)(Random(floor(uv)) * (float)NUM_PATTERNS) % NUM_PATTERNS; + float2 result = frac(uv); + + // flip + if ((uint)(pattern % 2) != 0) + { + result.x = 1.0f - result.x; + } + pattern /= 2; + if ((uint)(pattern % 2) != 0) + { + result.y = 1.0f - result.y; + } + + // rotate + pattern /= 2; + if (pattern % 4 == 1) + { + result = float2(result.y, 1.0f - result.x); + } + else if (pattern % 4 == 2) + { + result = float2(1.0f - result.y, result.x); + } + else if (pattern % 4 == 3) + { + result = 1.0f - result; + } + + // offset + pattern /= 4; + result.x += (pattern % 4) * 0.25f; + pattern /= 4; + result.y += (pattern % 4) * 0.25f; + + return result; + } + + override float4 Compute() { + return Texture.Sample(Sampler, RandomUV(streams.TexCoord * scale + offset)).TRgba; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl new file mode 100644 index 0000000000..7a4544e901 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// TOffset: generic float2 - the texture coordinates offset. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureScaledOffsetSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() { + return Texture.Sample(Sampler, streams.TexCoord * TScale + TOffset).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl b/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl new file mode 100644 index 0000000000..e38a15f60a --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Samples a texture with a custom sampler and fix texture coordinates scale. +/// +/// +/// TTexture: generic Texture2D - the texture to sample. +/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. +/// TScale: generic float2 - the scaling factor of the texture coordinates. +/// TSampler: generic SamplerState - the custom sampler. +/// +shader ComputeColorTextureScaledSampler : ComputeColor, + DynamicTexture, + DynamicSampler, + DynamicTextureStream +{ + override float4 Compute() + { + return Texture.Sample(Sampler, streams.TexCoord * TScale).TRgba; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl b/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl new file mode 100644 index 0000000000..85e1147ac7 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Only works properly for ProceduralCylinder! +// You will have to customize it to handle other shapes if they are required. +shader ComputeColorTextureScroll : ComputeColor, Texturing +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Position : POSITION; + + // Only works properly for ProceduralCylinder! + // You will have to customize it to handle other shapes if they are required. + override float4 Compute() + { + streams.TexCoord.y += Global.Time * UvSpeed; + + float alpha = 1 - 10 * (abs(streams.Position.y) - 0.4f); + + return float4(alpha * colorIntensity, alpha * colorIntensity, alpha * colorIntensity, alpha); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorThreshold.sdsl b/assets/Stride/SDSL/ComputeColorThreshold.sdsl new file mode 100644 index 0000000000..1be707487e --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorThreshold.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorThreshold : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 baseColor = color1.Compute(); + float4 maskColor = color2.Compute(); + + return float4( + smoothstep(maskColor.r, maskColor.r, baseColor.r), + smoothstep(maskColor.g, maskColor.g, baseColor.g), + smoothstep(maskColor.b, maskColor.b, baseColor.b), + smoothstep(maskColor.a, maskColor.a, baseColor.a) + ); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorValue.sdsl b/assets/Stride/SDSL/ComputeColorValue.sdsl new file mode 100644 index 0000000000..a284b9e166 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorValue.sdsl @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorValue : ComputeColor +{ + compose ComputeColor color1; + compose ComputeColor color2; + + override float4 Compute() + { + float4 backColor = color1.Compute(); + float4 frontColor = color2.Compute(); + + // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx + // + // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula + // + // Value : + // if sat(bc) == 0 : color = val(bc), val(bc), val(bc) + // if sat(bc) != 0 : color = rgb(hue(bc), sat(bc), val(fc)) + // + // alpha = fa * (1-ba) + ba + + float3 color; + + if(HSVUtils.GetSaturation(backColor.rgb) == 0.0f) + color = float3(HSVUtils.GetValue(backColor.rgb)); + else + color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(backColor.rgb), HSVUtils.GetSaturation(backColor.rgb), HSVUtils.GetValue(frontColor.rgb))); + + return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorWave.sdsl b/assets/Stride/SDSL/ComputeColorWave.sdsl new file mode 100644 index 0000000000..457be899b7 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorWave.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader ComputeColorWave : ComputeColor, Texturing +{ + override float4 Compute() + { + float phase = length(streams.TexCoord - 0.5); + return sin((phase + Global.Time * Speed) * 2 * 3.14 * Frequency) * Amplitude; + } +}; diff --git a/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl b/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl new file mode 100644 index 0000000000..5d899f7df7 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader ComputeColorWaveNormal : ComputeColor, Texturing +{ + override float4 Compute() + { + float2 offset = streams.TexCoord - 0.5; + float phase = length(offset); + + float derivative = cos((phase + Global.Time * Speed) * 2 * 3.14 * Frequency) * Amplitude; + + float2 xz = SincosOfAtan(offset.y / offset.x); + float2 xy = SincosOfAtan(derivative); + + float3 normal; + normal.xy = (xz.yx * sign(offset.x) * -xy.x) * 0.5 + 0.5; + normal.z = xy.y; + return float4(normal, 1); + } + + float2 SincosOfAtan(float x) + { + return float2(x, 1) / sqrt(1 + x * x); + } +}; diff --git a/assets/Stride/SDSL/ComputeColorWhite.sdsl b/assets/Stride/SDSL/ComputeColorWhite.sdsl new file mode 100644 index 0000000000..f93b21ffd5 --- /dev/null +++ b/assets/Stride/SDSL/ComputeColorWhite.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Particles.Shaders +{ + shader ComputeColorWhite : ComputeColor + { + override float4 Compute() + { + return float4(1, 1, 1, 1); + } + }; +} diff --git a/assets/Stride/SDSL/ComputeShaderBase.sdsl b/assets/Stride/SDSL/ComputeShaderBase.sdsl new file mode 100644 index 0000000000..552b1162ea --- /dev/null +++ b/assets/Stride/SDSL/ComputeShaderBase.sdsl @@ -0,0 +1,69 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Base compute shader. +/// +/// +/// ThreadNumberX: Macro - number of threads on the X axis. +/// ThreadNumberY: Macro - number of threads on the Y axis. +/// ThreadNumberZ: Macro - number of threads on the Z axis. +/// +#ifndef ThreadNumberX +# define ThreadNumberX 1 +#endif +#ifndef ThreadNumberY +# define ThreadNumberY 1 +#endif +#ifndef ThreadNumberZ +# define ThreadNumberZ 1 +#endif +shader ComputeShaderBase +{ + stage stream uint3 GroupId : SV_GroupID; + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + stage stream uint3 GroupThreadId : SV_GroupThreadID; + stage stream uint GroupIndex : SV_GroupIndex; + + stage stream uint3 ThreadGroupCount; + stage stream uint ThreadCountPerGroup; + stage stream uint ThreadGroupIndex; + + stage stream int ThreadCountX; + stage stream int ThreadCountY; + stage stream int ThreadCountZ; + + cbuffer PerDispatch { + // This variable provides the ThreadGroupCount from the dispatch method + [Link("ComputeShaderBase.ThreadGroupCountGlobal")] + stage int3 ThreadGroupCountGlobal; + }; + + [numthreads(ThreadNumberX, ThreadNumberY, ThreadNumberZ)] + void CSMain() + { + // give access to ThreadCounts everywhere in the shader + streams.ThreadCountX = ThreadNumberX; + streams.ThreadCountY = ThreadNumberY; + streams.ThreadCountZ = ThreadNumberZ; + + // Predefined variable that gives the number of threads per group + streams.ThreadCountPerGroup = ThreadNumberX * ThreadNumberY * ThreadNumberZ; + + // Copy the global variable to the stream to make it consistent + streams.ThreadGroupCount = ThreadGroupCountGlobal; + + // Calculate a unique thread group index, an index that identifies a unique group of thread from a dispatch + streams.ThreadGroupIndex = (streams.GroupId.z * streams.ThreadGroupCount.y + streams.GroupId.y) * streams.ThreadGroupCount.x + streams.GroupId.x; + + Compute(); + } + + void Compute() + { + } + + bool IsFirstThreadOfGroup() + { + return streams.GroupThreadId.x == 0 && streams.GroupThreadId.y == 0 && streams.GroupThreadId.z == 0; + } +}; diff --git a/assets/Stride/SDSL/ComputeShaderTest.sdsl b/assets/Stride/SDSL/ComputeShaderTest.sdsl new file mode 100644 index 0000000000..e203546927 --- /dev/null +++ b/assets/Stride/SDSL/ComputeShaderTest.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Graphics.Tests +{ + /// + /// A shader performing Lambertian pre-filtering. + /// + internal shader ComputeShaderTest: ComputeShaderBase + { + stage Texture2D input; + stage RWTexture2D output; + + override void Compute() + { + float4 Sum = float4(0,0,0,0); + + [unroll] + for(int i=0; i + /// Base shader to sample an environment + /// + shader ComputeSphericalHarmonics : SphericalHarmonicsUtils, ComputeColor, NormalStream + { + cbuffer PerMaterial + { + [Color] + stage float3 SphericalColors[TOrder * TOrder]; + } + + override float4 Compute() + { + var direction = float3(streams.normalWS.xy, -streams.normalWS.z); + + return EvaluateSphericalHarmonics(SphericalColors, direction); + } + }; +} diff --git a/assets/Stride/SDSL/ConstantBufferTest.sdsl b/assets/Stride/SDSL/ConstantBufferTest.sdsl new file mode 100644 index 0000000000..fd0251196e --- /dev/null +++ b/assets/Stride/SDSL/ConstantBufferTest.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ConstantBufferTest +{ + cbuffer PerVertex + { + float a; + float c; + }; + + cbuffer PerVertex + { + float b; + }; + + cbuffer PerPixel + { + float d; + }; + + float e; +}; diff --git a/assets/Stride/SDSL/CubemapSprite.sdsl b/assets/Stride/SDSL/CubemapSprite.sdsl new file mode 100644 index 0000000000..1daa80a24a --- /dev/null +++ b/assets/Stride/SDSL/CubemapSprite.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader CubemapSprite : SpriteEffect, Texturing +{ + stage float ViewIndex; + + // Shading of the sprite + stage override float4 Shading() + { + return TextureCube0.Sample(Sampler, CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, ViewIndex)); + } +}; diff --git a/assets/Stride/SDSL/CubemapUtils.sdsl b/assets/Stride/SDSL/CubemapUtils.sdsl new file mode 100644 index 0000000000..a557c845d5 --- /dev/null +++ b/assets/Stride/SDSL/CubemapUtils.sdsl @@ -0,0 +1,97 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Cubemap +{ + /// + /// Utilities functions for cubemap sampling. + /// + shader CubemapUtils + { + // TODO: this might change on OpenGL + + // This is for indirect coordinate system cubemap sampling = Direct3D + // ________ ________ ________ ________ ________ ________ + // | y | y | ___x | z | y | y | + // | | | | | | | | | | | | | + // | z___| | |___z | | | |___x | |___x | x___| | + // | | | z | | | | + // |________|________|________|________|________|________| + // face X face -X face Y face -Y face Z face -Z + // + float3 ConvertTexcoordsNoFlip(float2 inputTexcoord, int viewIndex) + { + float2 position = 2 * inputTexcoord - 1; + + if (viewIndex == 0) + return float3(1, -position.y, -position.x); // face X + if (viewIndex == 1) + return float3(-1, -position.y, position.x); // face -X + if (viewIndex == 2) + return float3(position.x, 1, position.y); // face Y + if (viewIndex == 3) + return float3(position.x, -1, -position.y); // face -Y + if (viewIndex == 4) + return float3(position.x, -position.y, 1); // face Z + if (viewIndex == 5) + return float3(-position.x, -position.y, -1); // face -Z + + return 0; + } + + float3 ConvertTexcoordsFlip(float2 inputTexcoord, int viewIndex) + { + float2 position = float2(2, -2) * inputTexcoord + float2(-1, 1); + + if (viewIndex == 0) + return float3(1, position.y, position.x); // face X + if (viewIndex == 1) + return float3(-1, position.y, -position.x); // face -X + if (viewIndex == 2) + return float3(position.x, 1, -position.y); // face Y + if (viewIndex == 3) + return float3(-position.x, -1, position.y); // face -Y + if (viewIndex == 4) + return float3(-position.x, position.y, 1); // face Z + if (viewIndex == 5) + return float3(position.x, position.y, -1); // face -Z + + return 0; + } + + float3 ParallaxCorrectionCube(float3 samplingDir, float3 reflectionPoint, float3 cubemapCenter, float cubemapRange) + { + // TODO: evolve to a more generic transformation (rotation, scale of the BB) + reflectionPoint -= cubemapCenter; + float3 lambdaPos = (cubemapRange - reflectionPoint) / samplingDir; + float3 lambdaNeg = (-cubemapRange - reflectionPoint) / samplingDir; + + float3 maxLambda = max(lambdaPos, lambdaNeg); // only take strictly positive values + float minLambda = min(maxLambda.x, min(maxLambda.y, maxLambda.z)); // take the smallest one + + // no need to normalize + return reflectionPoint + minLambda * samplingDir; + } + + float3 ParallaxCorrectionSphere(float3 samplingDir, float3 reflectionPoint, float3 cubemapCenter, float cubemapRadius) + { + samplingDir = normalize(samplingDir); + float3 reflectionPointDir = reflectionPoint - cubemapCenter; + + float b = 2 * dot(reflectionPointDir, samplingDir); + float c = dot(reflectionPointDir, reflectionPointDir) - cubemapRadius * cubemapRadius; + float discr = b*b - 4*c; + + if (discr >= 0) + { + float sqrtDelta = sqrt(discr); + float lambda = 0.5 * (sqrtDelta - b); + // no need to normalize + return reflectionPointDir + lambda * samplingDir; + } + else + { + return samplingDir; + } + } + }; +} diff --git a/assets/Stride/SDSL/CustomFogEffect.sdsl b/assets/Stride/SDSL/CustomFogEffect.sdsl new file mode 100644 index 0000000000..fbb011ef62 --- /dev/null +++ b/assets/Stride/SDSL/CustomFogEffect.sdsl @@ -0,0 +1,40 @@ +// Simple fog emulating fixed pipeline as described in http://www.ozone3d.net/tutorials/glsl_fog/p03.php +shader CustomFogEffect : ShadingBase, TransformationBase, Camera +{ + cbuffer PerDraw + { + // Color of the fog + [Color] + stage float4 FogColor = float4(1,1,1,1); + + stage float fogNearPlaneZ = 80.0f;//35.0f; + stage float fogFarPlaneZ = 250.0f; + + stage float fogNearPlaneY = 0.0f; + stage float fogFarPlaneY = 120.0f; + } + + // Varying FogFactor calculated from VS and passed to PS + stage stream float FogFactor : FOG; + + stage override void PostTransformPosition() + { + base.PostTransformPosition(); + float depth; + const float LOG2 = 1.442695; + + float depthFactor = max ( (fogFarPlaneZ - streams.ShadingPosition.w ) / (fogFarPlaneZ - fogNearPlaneZ), 0.0); + float heightFactor = max ( (streams.ShadingPosition.y - fogFarPlaneY) / ( fogFarPlaneY - fogNearPlaneY), 0.0); + streams.FogFactor = saturate( depthFactor + heightFactor ); + } + + stage override float4 Shading() + { + float4 normalShade = base.Shading(); + + if(normalShade.w <= 0.005) + return normalShade; + + return lerp(FogColor, normalShade, streams.FogFactor); + } +}; diff --git a/assets/Stride/SDSL/CustomShader.sdsl b/assets/Stride/SDSL/CustomShader.sdsl new file mode 100644 index 0000000000..2c4fe84f4b --- /dev/null +++ b/assets/Stride/SDSL/CustomShader.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Graphics.Tests +{ + shader CustomShader : SpriteBase + { + // factor used by CustomEffect + stage float SwitchEffectLevel; + + cbuffer PerPass + { + [Link("MyCustomShader.ColorFactor2")] + stage float4 ColorFactor2; + }; + + // Shading of the sprite with dual texturing + stage override float4 Shading() + { + return base.Shading() * ColorFactor2; + } + }; +} diff --git a/assets/Stride/SDSL/CyclicTest.sdsl b/assets/Stride/SDSL/CyclicTest.sdsl new file mode 100644 index 0000000000..919664c10d --- /dev/null +++ b/assets/Stride/SDSL/CyclicTest.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader CyclicTest : CyclicTest +{ + +}; diff --git a/assets/Stride/SDSL/DataPacking.sdsl b/assets/Stride/SDSL/DataPacking.sdsl new file mode 100644 index 0000000000..a3c62b2f88 --- /dev/null +++ b/assets/Stride/SDSL/DataPacking.sdsl @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader DataPacking +{ + uint FloatToUnsignedFloatWExponent5(float num, int mantissa) + { + uint fltInt32 = asuint(num); + int offset = (23-mantissa); + int bitdepth = mantissa+5; + int bias = 15;//pow(2,5 - 1) - 1; + int biascounter = 0x38000000;//(127-bias)<<23; + + if (((fltInt32 & 0x7f800000) >> offset) <= (biascounter >> offset)) + return 0; + + uint fltInt16 = (((fltInt32 & 0x7fffffff) >> offset) - (biascounter >> offset)) & (0xFFFFFFFF >> (32-bitdepth)); + + return fltInt16; + } + float UnsignedFloatWExponent5ToFloat(uint num, int mantissa) + { + uint fltInt16 = num; + int offset = (23-mantissa); + int bitdepth = mantissa+5; + int bias = pow(2,5 - 1) - 1; + int biascounter = (127-bias)<<23; + + if (num==0) + return 0; + + uint fltInt32 = ((fltInt16) << offset) + 0x38000000; + + return asfloat(fltInt32); + } + uint Float3ToR11G11B10(float3 num) + { + return FloatToUnsignedFloatWExponent5(num.r, 6) | (FloatToUnsignedFloatWExponent5(num.g, 6)<<11) | (FloatToUnsignedFloatWExponent5(num.b, 5)<<22); + } + float3 R11G11B10ToFloat3(uint num) + { + float3 ret; + ret.r = UnsignedFloatWExponent5ToFloat(num & (0xFFFFFFFF>>(32-11)),6); + ret.g = UnsignedFloatWExponent5ToFloat((num>>11) & (0xFFFFFFFF>>(32-11)),6); + ret.b = UnsignedFloatWExponent5ToFloat((num>>22),5); + return ret; + } + uint FloatToHalfFloat(float num) + { + uint fltInt32 = asuint(num); + + if (((fltInt32 & 0x7f800000) >> 13) <= (0x38000000 >> 13)) + return 0; + + uint fltInt16 = (((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13)) & 0x00007fff; + fltInt16 |= ((fltInt32 & 0x80000000) >> 16); + + return fltInt16; + } + float HalfFloatToFloat(uint num) + { + if (num==0) + return 0; + + uint fltInt16 = num; + + uint fltInt32 = ((fltInt16 & 0x00008000) << 16); + fltInt32 |= ((fltInt16 & 0x00007fff) << 13) + 0x38000000; + + return asfloat(fltInt32); + } + uint PackFloat2ToHalfFloat2(float2 num) + { + return FloatToHalfFloat(num.r) | (FloatToHalfFloat(num.g)<<16); + } + float2 UnpackHalfFloat2ToFloat2(uint num) + { + return float2( HalfFloatToFloat(num & 0x0000ffff), + HalfFloatToFloat(num >> 16) ); + } + + uint3 UnpackByte3ToUint3(uint num) + { + return uint3( + num & 0x000000ff, + (num >> 8) & 0x000000ff, + (num >> 16) & 0x000000ff + ); + } + + uint FloatUnormToUint(float num) + { + return (uint)(num * 4294967295.0); + } + float UintToFloatUnorm(uint num) + { + return float(num) / 4294967295.0; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/DeepExtern.sdsl b/assets/Stride/SDSL/DeepExtern.sdsl new file mode 100644 index 0000000000..1b378d8113 --- /dev/null +++ b/assets/Stride/SDSL/DeepExtern.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader DeepExtern +{ + compose ExternMixin myExtern; +}; diff --git a/assets/Stride/SDSL/DeepExternTest.sdsl b/assets/Stride/SDSL/DeepExternTest.sdsl new file mode 100644 index 0000000000..8b2fca2f23 --- /dev/null +++ b/assets/Stride/SDSL/DeepExternTest.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader DeepExternTest +{ + compose DeepExtern myExtern; + + float externCall() + { + myExtern.myExtern.externFunc(); + return myExtern.myExtern.externMember; + } +}; diff --git a/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl b/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl new file mode 100644 index 0000000000..adf46d7bbb --- /dev/null +++ b/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + + /// + /// A blur with uniform weights applied along one direction. (depth-aware blur to avoid artifacts) + /// + + shader DepthAwareDirectionalBlurShader + : DepthAwareDirectionalBlurUtil, ImageEffectShader + { + stage override float4 Shading() + { + return Compute(); + } + + }; +} diff --git a/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl b/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl new file mode 100644 index 0000000000..597b68bff8 --- /dev/null +++ b/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl @@ -0,0 +1,96 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + + /// + /// A blur with weights applied along one direction. + /// Expects as input: + /// - Texture0: color buffer + /// + /// + /// The number of weights along a direction. + /// Total number of tpas. The value is always 2 * TWeightCount - 1. + + shader DepthAwareDirectionalBlurUtil : Texturing, ComputeColor + { + // Direction to apply the blur. (normalized vector) + float2 Direction; + + // The radius of the blur to apply around the considered fragment + float Radius; + + // Weights of each tap (weights values are symmetric along each direction) + float TapWeights[TWeightCount]; + + float CoCReference; + + // Gets the blur result for the current pixel. + override float4 Compute() + { + // Offset between 2 consecutive taps + float2 tapOffset = Radius / (TWeightCount - 1) * Texture0TexelSize; + + // Fills arrays with all the taps + float4 tapColor[TTotalNumber]; // All the taps colors + float tapOriginalWeight[TTotalNumber]; // With their respective weight + + // Center tap + int centerIndex = TWeightCount - 1; + tapColor[centerIndex] = Texture0.Sample(LinearSampler, streams.TexCoord).xyzw; + // Premultiply alpha + tapColor[centerIndex].rgb *= tapColor[centerIndex].a; + tapOriginalWeight[centerIndex] = TapWeights[0]; + + // Treats all the taps in the 2 directions from the center + [unroll] + for(int i = 1; i < TWeightCount; i++) + { + // Backwards + float2 tapUV = streams.TexCoord - i * Direction * tapOffset; + int tapIndex = centerIndex - i; + tapColor[tapIndex] = Texture0.Sample(LinearSampler, tapUV).xyzw; + // Premultiply alpha + tapColor[tapIndex].rgb *= tapColor[tapIndex].a; + tapOriginalWeight[tapIndex] = TapWeights[i]; + + // Forwards + tapUV = streams.TexCoord + i * Direction * tapOffset; + tapIndex = centerIndex + i; + tapColor[tapIndex] = Texture0.Sample(LinearSampler, tapUV).xyzw; + // Premultiply alpha + tapColor[tapIndex].rgb *= tapColor[tapIndex].a; + tapOriginalWeight[tapIndex] = TapWeights[i]; + } + + // Calculate the final average color + float4 resultColor = float4(0.0, 0.0, 0.0, 0.0); + float totalWeight = 0.0; + + [unroll] + for(int k = 0; k < TTotalNumber; k++) + { + float tapWeight = tapOriginalWeight[k]; + // You could change the weight on the fly here to discard some sample + resultColor += tapColor[k].xyzw * tapWeight; + totalWeight += tapWeight; + } + + if (totalWeight > 0) { + // Normalizes the final result + resultColor /= totalWeight; + } else { + resultColor = float4(0.0, 0.0, 0.0, 0.0); + } + + // Go back to non-premultiplied-alpha + if (resultColor.a > 0) + { + resultColor.rgb /= resultColor.a; + } + + return resultColor; + } + }; +} diff --git a/assets/Stride/SDSL/DepthBase.sdsl b/assets/Stride/SDSL/DepthBase.sdsl new file mode 100644 index 0000000000..1ecdc246dd --- /dev/null +++ b/assets/Stride/SDSL/DepthBase.sdsl @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a depth texture. +/// Various helper functions to extract information from a depth buffer. +/// +shader DepthBase : Camera, Texturing +{ + // ------------------------------------- + // Resources + // ------------------------------------- + rgroup PerView.Depth + { + //[Link("RenderTarget.DepthStencilSource")] + stage Texture2D DepthStencil; + } + + // Sample the depth from the texture + float GetZProjDepthFromUV(float2 uv) { + return DepthStencil.SampleLevel(PointSampler, uv, 0.0).x; + } + + float GetZProjDepthFromScreenPosition(int2 screenPosition) { + return DepthStencil.Load(int3(screenPosition,0), 0).x; + } + + float ComputeDepthFromZProj(float depth) { + // Retro project non linear 1/z depth to linear depth in view space + return ZProjection.y / (depth - ZProjection.x); + } + + float ComputeDepthFromUV(float2 uv) { + return ComputeDepthFromZProj(GetZProjDepthFromUV(uv)); + } + + float ComputeDepthFromScreenPosition(int2 screenPosition) { + return ComputeDepthFromZProj(GetZProjDepthFromScreenPosition(screenPosition)); + } +}; diff --git a/assets/Stride/SDSL/DepthMinMaxShader.sdsl b/assets/Stride/SDSL/DepthMinMaxShader.sdsl new file mode 100644 index 0000000000..63a1a1d4a0 --- /dev/null +++ b/assets/Stride/SDSL/DepthMinMaxShader.sdsl @@ -0,0 +1,69 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// STRIDE_GRAPHICS_PROFILE: Macro - graphics profile level. +/// + +namespace Stride.Rendering.Images +{ + /// + /// A reduction shader + /// + shader DepthMinMaxShader : ImageEffectShader + { + Texture2D TextureMap; + Texture2D TextureReduction; + + + float max_not_1(float left, float right) + { + if (left == 1.0f) return right; + if (right == 1.0f) return left; + return max(left, right); + } + + stage override float4 Shading() + { + if (TFirstPass) + { + float4 values; + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_1 + values = TextureMap.Gather(LinearSampler, streams.TexCoord); +#else + values.x = TextureMap.Sample(PointSampler, streams.TexCoord, int2(-1, 0)).r; + values.y = TextureMap.Sample(PointSampler, streams.TexCoord, int2(0, 0)).r; + values.z = TextureMap.Sample(PointSampler, streams.TexCoord, int2(0, -1)).r; + values.w = TextureMap.Sample(PointSampler, streams.TexCoord, int2(-1, -1)).r; +#endif + // TODO: do a simple sort for 4 values quicker than min/max + var minValue = min(min(values[0], values[1]), min(values[2], values[3])); + var maxValue = max_not_1(max_not_1(values[0], values[1]), max_not_1(values[2], values[3])); + + return float4(minValue, maxValue, 0, 0); + } + else + { + float4 minValues, maxValues; + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_11_0 + minValues = TextureReduction.GatherRed(LinearSampler, streams.TexCoord); + maxValues = TextureReduction.GatherGreen(LinearSampler, streams.TexCoord); +#else + float2 value0 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(-1, 0)).rg; + float2 value1 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(0, 0)).rg; + float2 value2 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(0, -1)).rg; + float2 value3 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(-1, -1)).rg; + minValues = float4(value0.r, value1.r, value2.r, value3.r); + maxValues = float4(value0.g, value1.g, value2.g, value3.g); +#endif + + // TODO: do a simple sort for 4 values quicker than min/max + var minValue = min(min(minValues[0], minValues[1]), min(minValues[2], minValues[3])); + var maxValue = max_not_1(max_not_1(maxValues[0], maxValues[1]), max_not_1(maxValues[2], maxValues[3])); + + return float4(minValue, maxValue, 0, 0); + } + } + }; +} diff --git a/assets/Stride/SDSL/DirectLightGroup.sdsl b/assets/Stride/SDSL/DirectLightGroup.sdsl new file mode 100644 index 0000000000..9b81711f7b --- /dev/null +++ b/assets/Stride/SDSL/DirectLightGroup.sdsl @@ -0,0 +1,70 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of similar lights (directional, spot...etc.) + /// + shader DirectLightGroup : + LightStream, + ShadowGroup, // Required for "ComputeShadow()". + TextureProjectionGroup, // Required for "ComputeTextureProjection()". + NormalStream, // Required for "streams.normalWS". + PositionStream4, // Required for "streams.PositionWS". + MaterialPixelStream // Required for "streams.viewWS" + { + int GetMaxLightCount() + { + return 0; + } + + /// + /// Gets the number of lights of this group + /// + int GetLightCount() + { + return 0; + } + + /// + /// One-time initialization before the light loop. + /// + void PrepareDirectLights() + { + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + void PrepareDirectLight(int lightIndex) + { + PrepareDirectLightCore(lightIndex); + + // Compute NdotL + streams.NdotL = max(dot(streams.normalWS, streams.lightDirectionWS), 0.0001f); + + // Computes the shadowColor + streams.shadowColor = ComputeShadow(streams.PositionWS.xyz, lightIndex); + + // Compute the final color with NdotL + streams.lightColorNdotL = streams.lightColor * streams.lightAttenuation * streams.shadowColor * streams.NdotL * streams.lightDirectAmbientOcclusion; + streams.lightSpecularColorNdotL = streams.lightColorNdotL; + + // Mask the light by the color of the projected texture: + streams.lightColorNdotL *= ComputeTextureProjection(streams.PositionWS.xyz, lightIndex); // TODO: Modify "streams.lightColor" instead? + + + float3 reflectionVectorWS = reflect(-streams.viewWS, streams.normalWS); + streams.lightSpecularColorNdotL *= ComputeSpecularTextureProjection(streams.PositionWS.xyz, reflectionVectorWS, lightIndex); + } + + void PrepareDirectLightCore(int lightIndex) + { + } + + float ComputeAttenuation(float3 position, int lightIndex) + { + return 1; + } + }; +} diff --git a/assets/Stride/SDSL/DirectLightGroupArray.sdsl b/assets/Stride/SDSL/DirectLightGroupArray.sdsl new file mode 100644 index 0000000000..4782cd84d8 --- /dev/null +++ b/assets/Stride/SDSL/DirectLightGroupArray.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// An array of light groups + /// + shader DirectLightGroupArray + { + stage compose DirectLightGroup directLightGroups[]; + }; +} diff --git a/assets/Stride/SDSL/DirectLightGroupFixed.sdsl b/assets/Stride/SDSL/DirectLightGroupFixed.sdsl new file mode 100644 index 0000000000..3358ca092b --- /dev/null +++ b/assets/Stride/SDSL/DirectLightGroupFixed.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Overrides the default behaviour of DirectLightGroup to only return a fixed number of lights + /// + shader DirectLightGroupFixed : DirectLightGroup + { + /// + /// Gets the number of lights of this group + /// + override int GetLightCount() + { + return TLightCount; + } + }; +} diff --git a/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl b/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl new file mode 100644 index 0000000000..219869ddb2 --- /dev/null +++ b/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of similar lights (directional, spot...etc.) + /// + shader DirectLightGroupPerDraw : DirectLightGroup + { + cbuffer PerDraw.Lighting + { + int LightCount; + } + + /// + /// Gets the number of lights of this group + /// + override int GetLightCount() + { + return LightCount; + } + }; +} diff --git a/assets/Stride/SDSL/DirectLightGroupPerView.sdsl b/assets/Stride/SDSL/DirectLightGroupPerView.sdsl new file mode 100644 index 0000000000..977874c86c --- /dev/null +++ b/assets/Stride/SDSL/DirectLightGroupPerView.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of similar lights (directional, spot...etc.) + /// + shader DirectLightGroupPerView : DirectLightGroup + { + cbuffer PerView.Lighting + { + int LightCount; + } + + /// + /// Gets the number of lights of this group + /// + override int GetLightCount() + { + return LightCount; + } + }; +} diff --git a/assets/Stride/SDSL/Dither.sdsl b/assets/Stride/SDSL/Dither.sdsl new file mode 100644 index 0000000000..5fee978311 --- /dev/null +++ b/assets/Stride/SDSL/Dither.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader Dither : ColorTransformShader, Texturing +{ + // Time changing at each frame for the animation + float Time; + + override float4 Compute(float4 color) + { + // Test cases that truncate to 8 bit and scale the result: + //return float4(Truncate(ScreenSpaceDither(color.rgb*0.1), 255), color.a) * 10; + //return float4(Truncate(color.rgb*0.1, 255), color.a) * 10; + + return float4(ScreenSpaceDither(color.rgb), color.a); + //return float4(color.rgb, color.a); + } + + float3 Truncate( float3 x, float n ) + { + return floor(x*n)/n; + } + + + float3 ScreenSpaceDither(float3 input) + { + float2 vScreenPos = streams.TexCoord; + vScreenPos /= Texture0TexelSize; + + // http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf + // lestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR + float3 vDither = dot(float2(131.0, 312.0), vScreenPos + Time); + vDither.rgb = frac(vDither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5); + float d = max(input.x, max(input.y, input.z)); + return input + (vDither.rgb / 255.0); + } +}; diff --git a/assets/Stride/SDSL/DynamicSampler.sdsl b/assets/Stride/SDSL/DynamicSampler.sdsl new file mode 100644 index 0000000000..a6fc09bcfb --- /dev/null +++ b/assets/Stride/SDSL/DynamicSampler.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a Texture2D. +/// +/// +/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. +/// +shader DynamicSampler +{ + rgroup LocalResourceGroup + { + [Link("TSampler")] + stage SamplerState Sampler; + } +}; diff --git a/assets/Stride/SDSL/DynamicTexture.sdsl b/assets/Stride/SDSL/DynamicTexture.sdsl new file mode 100644 index 0000000000..02f79c3a49 --- /dev/null +++ b/assets/Stride/SDSL/DynamicTexture.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a Texture2D. +/// +/// +/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. +/// +shader DynamicTexture +{ + rgroup LocalResourceGroup + { + [Link("TTexture")] + stage Texture2D Texture; + } +}; diff --git a/assets/Stride/SDSL/DynamicTextureCube.sdsl b/assets/Stride/SDSL/DynamicTextureCube.sdsl new file mode 100644 index 0000000000..5f47583d9d --- /dev/null +++ b/assets/Stride/SDSL/DynamicTextureCube.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a Texture2D. +/// +/// +/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. +/// +shader DynamicTextureCube +{ + rgroup LocalResourceGroup + { + [Link("TTexture")] + stage TextureCube CubeMap; + } +}; diff --git a/assets/Stride/SDSL/DynamicTextureStream.sdsl b/assets/Stride/SDSL/DynamicTextureStream.sdsl new file mode 100644 index 0000000000..6d87f6feb0 --- /dev/null +++ b/assets/Stride/SDSL/DynamicTextureStream.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a stream with custom attribute (usually texcoord). +/// +/// +/// NAME: generic Semantic - the name of the texcoord (e.g. TEXCOORD0). +/// +shader DynamicTextureStream +{ + stream float2 TexCoord : NAME; +}; diff --git a/assets/Stride/SDSL/Effect.sdsl b/assets/Stride/SDSL/Effect.sdsl new file mode 100644 index 0000000000..90c1706446 --- /dev/null +++ b/assets/Stride/SDSL/Effect.sdsl @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader Effect : SpriteBase +{ + stage float2 Center; + stage float Frequency; + stage float Phase; + stage float Spread; + stage float Amplitude; + stage float InvAspectRatio; + + stage override float4 Shading() + { + float2 wave; + + float2 toPixel = (streams.TexCoord.xy - Center) * float2(1, InvAspectRatio); + + float distance = length(toPixel); + float2 direction = normalize(toPixel); + + sincos(Frequency * distance + Phase, wave.x, wave.y); + + // Clamps the distance between 0 and 1 and squares the value. + float falloff = saturate(1 - distance); + falloff = pow(falloff, 1.0f / Spread); + + // Calculates new mapping coordinates based on the frequency, center, and amplitude. + float2 uv2 = streams.TexCoord.xy + (wave.x * falloff * Amplitude) * direction; + float lighting = lerp(1.0f, 1.0f + wave.x * falloff * 0.2f, saturate(Amplitude / 0.015f)); + + // Resamples the image based on the new coordinates. + float4 color = Texture0.Sample(Sampler, uv2); + color.rgb *= lighting; + + return color; + } +}; diff --git a/assets/Stride/SDSL/EffectCompiling.sdsl b/assets/Stride/SDSL/EffectCompiling.sdsl new file mode 100644 index 0000000000..004c4c70e2 --- /dev/null +++ b/assets/Stride/SDSL/EffectCompiling.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader EffectCompiling : ShadingBase +{ + // method computing color + stage override float4 Shading() + { + float factor = sin(Global.Time * 6.0f) * 0.25f + 0.25f; + float4 reloadColor = float4(0.66f, 1.0f, 0.25f, 1.0f); + + // High frequency glow to let user know effect is reloading + return lerp(base.Shading(), reloadColor, factor); + } +}; diff --git a/assets/Stride/SDSL/EnvironmentLight.sdsl b/assets/Stride/SDSL/EnvironmentLight.sdsl new file mode 100644 index 0000000000..fe9aecb246 --- /dev/null +++ b/assets/Stride/SDSL/EnvironmentLight.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines an environment light (ambient, IBL... etc.) + /// + shader EnvironmentLight : LightStream, ShadowGroup, NormalStream + { + void PrepareEnvironmentLight() + { + streams.envLightDiffuseColor = 0; + streams.envLightSpecularColor = 0; + } + }; +} diff --git a/assets/Stride/SDSL/EnvironmentLightArray.sdsl b/assets/Stride/SDSL/EnvironmentLightArray.sdsl new file mode 100644 index 0000000000..599b7c6c04 --- /dev/null +++ b/assets/Stride/SDSL/EnvironmentLightArray.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// An array of environment lights + /// + shader EnvironmentLightArray + { + stage compose EnvironmentLight environmentLights[]; + }; +} diff --git a/assets/Stride/SDSL/ExternClone.sdsl b/assets/Stride/SDSL/ExternClone.sdsl new file mode 100644 index 0000000000..f30dc65da8 --- /dev/null +++ b/assets/Stride/SDSL/ExternClone.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ExternClone +{ + clone void test() + { + } +}; diff --git a/assets/Stride/SDSL/ExternCloneTest.sdsl b/assets/Stride/SDSL/ExternCloneTest.sdsl new file mode 100644 index 0000000000..af0015bebf --- /dev/null +++ b/assets/Stride/SDSL/ExternCloneTest.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ExternCloneTest +{ + compose DeepExtern ext0; + compose DeepExtern ext1; + + void Test() + { + float fext0 = ext0.myExtern.externMember; + float fext1 = ext1.myExtern.externMember; + ext0.myExtern.externFunc(); + ext1.myExtern.externFunc(); + } +}; diff --git a/assets/Stride/SDSL/ExternMixin.sdsl b/assets/Stride/SDSL/ExternMixin.sdsl new file mode 100644 index 0000000000..56dcf2ea5a --- /dev/null +++ b/assets/Stride/SDSL/ExternMixin.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ExternMixin +{ + float externMember = 1.0f; + + void externFunc() + { + float a = 0.0f; + } +}; diff --git a/assets/Stride/SDSL/ExternTest.sdsl b/assets/Stride/SDSL/ExternTest.sdsl new file mode 100644 index 0000000000..f83715581a --- /dev/null +++ b/assets/Stride/SDSL/ExternTest.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ExternTest +{ + compose ExternMixin myExtern; + + void externFunc(){} + + float externCall() + { + myExtern.externFunc(); + return myExtern.externMember; + } +}; diff --git a/assets/Stride/SDSL/FXAAShader.sdsl b/assets/Stride/SDSL/FXAAShader.sdsl new file mode 100644 index 0000000000..fd748d9137 --- /dev/null +++ b/assets/Stride/SDSL/FXAAShader.sdsl @@ -0,0 +1,2067 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +#define FXAA_PC 1 +#define FXAA_HLSL_4 1 +#ifndef FXAA_QUALITY__PRESET +#define FXAA_QUALITY__PRESET 15 +#endif +shader FXAAShader : ImageEffectShader +{ + +/*============================================================================ + + + NVIDIA FXAA 3.11 by TIMOTHY LOTTES + + +------------------------------------------------------------------------------ +COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. +------------------------------------------------------------------------------ +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED +*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA +OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR +CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR +LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, +OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE +THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +------------------------------------------------------------------------------ + INTEGRATION CHECKLIST +------------------------------------------------------------------------------ +(1.) +In the shader source, setup defines for the desired configuration. +When providing multiple shaders (for different presets), +simply setup the defines differently in multiple files. +Example, + + #define FXAA_PC 1 + #define FXAA_HLSL_5 1 + #define FXAA_QUALITY__PRESET 12 + +Or, + + #define FXAA_360 1 + +Or, + + #define FXAA_PS3 1 + +Etc. + +(2.) +Then include this file, + + #include "Fxaa3_11.h" + +(3.) +Then call the FXAA pixel shader from within your desired shader. +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. +As for FXAA 3.11 all inputs for all shaders are the same +to enable easy porting between platforms. + + return FxaaPixelShader(...); + +(4.) +Insure pass prior to FXAA outputs RGBL (see next section). +Or use, + + #define FXAA_GREEN_AS_LUMA 1 + +(5.) +Setup engine to provide the following constants +which are used in the FxaaPixelShader() inputs, + + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir + +Look at the FXAA Quality FxaaPixelShader() for docs on inputs. + +(6.) +Have FXAA vertex shader run as a full screen triangle, +and output "pos" and "fxaaConsolePosPos" +such that inputs in the pixel shader provide, + + // {xy} = center of pixel + FxaaFloat2 pos, + + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + +(7.) +Insure the texture sampler(s) used by FXAA are set to bilinear filtering. + + +------------------------------------------------------------------------------ + INTEGRATION - RGBL AND COLORSPACE +------------------------------------------------------------------------------ +FXAA3 requires RGBL as input unless the following is set, + + #define FXAA_GREEN_AS_LUMA 1 + +In which case the engine uses green in place of luma, +and requires RGB input is in a non-linear colorspace. + +RGB should be LDR (low dynamic range). +Specifically do FXAA after tonemapping. + +RGB data as returned by a texture fetch can be non-linear, +or linear when FXAA_GREEN_AS_LUMA is not set. +Note an "sRGB format" texture counts as linear, +because the result of a texture fetch is linear data. +Regular "RGBA8" textures in the sRGB colorspace are non-linear. + +If FXAA_GREEN_AS_LUMA is not set, +luma must be stored in the alpha channel prior to running FXAA. +This luma should be in a perceptual space (could be gamma 2.0). +Example pass before FXAA where output is gamma 2.0 encoded, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.rgb = sqrt(color.rgb); // gamma 2.0 color output + color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma + return color; + +Another example where output is linear encoded, +say for instance writing to an sRGB formated render target, +where the render target does the conversion back to sRGB after blending, + + color.rgb = ToneMap(color.rgb); // linear color output + return color; + +To use FXAA, + + color.rgb = ToneMap(color.rgb); // linear color output + color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma + return color; + +Getting luma correct is required for the algorithm to work correctly. + + +------------------------------------------------------------------------------ + BEING LINEARLY CORRECT? +------------------------------------------------------------------------------ +Applying FXAA to a framebuffer with linear RGB color will look worse. +This is very counter intuitive, but happends to be true in this case. +The reason is because dithering artifacts will be more visiable +in a linear colorspace. + + +------------------------------------------------------------------------------ + COMPLEX INTEGRATION +------------------------------------------------------------------------------ +Q. What if the engine is blending into RGB before wanting to run FXAA? + +A. In the last opaque pass prior to FXAA, + have the pass write out luma into alpha. + Then blend into RGB only. + FXAA should be able to run ok + assuming the blending pass did not any add aliasing. + This should be the common case for particles and common blending passes. + +A. Or use FXAA_GREEN_AS_LUMA. + +============================================================================*/ + +/*============================================================================ + + INTEGRATION KNOBS + +============================================================================*/ +// +// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). +// FXAA_360_OPT is a prototype for the new optimized 360 version. +// +// 1 = Use API. +// 0 = Don't use API. +// +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PS3 + #define FXAA_PS3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360 + #define FXAA_360 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_360_OPT + #define FXAA_360_OPT 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_PC + // + // FXAA Quality + // The high quality PC algorithm. + // + #define FXAA_PC 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_PC_CONSOLE + // + // The console algorithm for PC is included + // for developers targeting really low spec machines. + // Likely better to just run FXAA_PC, and use a really low preset. + // + #define FXAA_PC_CONSOLE 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_120 + #define FXAA_GLSL_120 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GLSL_130 + #define FXAA_GLSL_130 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_3 + #define FXAA_HLSL_3 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_4 + #define FXAA_HLSL_4 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_HLSL_5 + #define FXAA_HLSL_5 0 +#endif +/*==========================================================================*/ +#ifndef FXAA_GREEN_AS_LUMA + // + // For those using non-linear color, + // and either not able to get luma in alpha, or not wanting to, + // this enables FXAA to run using green as a proxy for luma. + // So with this enabled, no need to pack luma in alpha. + // + // This will turn off AA on anything which lacks some amount of green. + // Pure red and blue or combination of only R and B, will get no AA. + // + // Might want to lower the settings for both, + // fxaaConsoleEdgeThresholdMin + // fxaaQualityEdgeThresholdMin + // In order to insure AA does not get turned off on colors + // which contain a minor amount of green. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_GREEN_AS_LUMA 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_EARLY_EXIT + // + // Controls algorithm's early exit path. + // On PS3 turning this ON adds 2 cycles to the shader. + // On 360 turning this OFF adds 10ths of a millisecond to the shader. + // Turning this off on console will result in a more blurry image. + // So this defaults to on. + // + // 1 = On. + // 0 = Off. + // + #define FXAA_EARLY_EXIT 1 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_DISCARD + // + // Only valid for PC OpenGL currently. + // Probably will not work when FXAA_GREEN_AS_LUMA = 1. + // + // 1 = Use discard on pixels which don't need AA. + // For APIs which enable concurrent TEX+ROP from same surface. + // 0 = Return unchanged color on pixels which don't need AA. + // + #define FXAA_DISCARD 0 +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_FAST_PIXEL_OFFSET + // + // Used for GLSL 120 only. + // + // 1 = GL API supports fast pixel offsets + // 0 = do not use fast pixel offsets + // + #ifdef GL_EXT_gpu_shader4 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_FAST_PIXEL_OFFSET 1 + #endif + #ifndef FXAA_FAST_PIXEL_OFFSET + #define FXAA_FAST_PIXEL_OFFSET 0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_GATHER4_ALPHA + // + // 1 = API supports gather4 on alpha channel. + // 0 = API does not support gather4 on alpha channel. + // + #if (FXAA_HLSL_5 == 1) + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_ARB_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifdef GL_NV_gpu_shader5 + #define FXAA_GATHER4_ALPHA 1 + #endif + #ifndef FXAA_GATHER4_ALPHA + #define FXAA_GATHER4_ALPHA 0 + #endif +#endif + +/*============================================================================ + FXAA CONSOLE PS3 - TUNING KNOBS +============================================================================*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS + // + // Consoles the sharpness of edges on PS3 only. + // Non-PS3 tuning is done with shader input. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 8.0 is sharper + // 4.0 is softer + // 2.0 is really soft (good for vector graphics inputs) + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 + #endif + #if 0 + #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 + #endif +#endif +/*--------------------------------------------------------------------------*/ +#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD + // + // Only effects PS3. + // Non-PS3 tuning is done with shader input. + // + // The minimum amount of local contrast required to apply algorithm. + // The console setting has a different mapping than the quality setting. + // + // This only applies when FXAA_EARLY_EXIT is 1. + // + // Due to the PS3 being ALU bound, + // there are only two safe values here: 0.25 and 0.125. + // These options use the shaders ability to a free *|/ by 2|4|8. + // + // 0.125 leaves less aliasing, but is softer + // 0.25 leaves more aliasing, and is sharper + // + #if 1 + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 + #else + #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 + #endif +#endif + +/*============================================================================ + FXAA QUALITY - TUNING KNOBS +------------------------------------------------------------------------------ +NOTE the other tuning knobs are now in the shader function inputs! +============================================================================*/ +#ifndef FXAA_QUALITY__PRESET + // + // Choose the quality preset. + // This needs to be compiled into the shader as it effects code. + // Best option to include multiple presets is to + // in each shader define the preset, then include this file. + // + // OPTIONS + // ----------------------------------------------------------------------- + // 10 to 15 - default medium dither (10=fastest, 15=highest quality) + // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) + // 39 - no dither, very expensive + // + // NOTES + // ----------------------------------------------------------------------- + // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) + // 13 = about same speed as FXAA 3.9 and better than 12 + // 23 = closest to FXAA 3.9 visually and performance wise + // _ = the lowest digit is directly related to performance + // _ = the highest digit is directly related to style + // + #define FXAA_QUALITY__PRESET 12 +#endif + + +/*============================================================================ + + FXAA QUALITY - PRESETS + +============================================================================*/ + +/*============================================================================ + FXAA QUALITY - MEDIUM DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 10) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 3.0 + #define FXAA_QUALITY__P2 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 11) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 3.0 + #define FXAA_QUALITY__P3 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 12) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 4.0 + #define FXAA_QUALITY__P4 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 13) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 4.0 + #define FXAA_QUALITY__P5 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 14) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 4.0 + #define FXAA_QUALITY__P6 12.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 15) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 12.0 +#endif + +/*============================================================================ + FXAA QUALITY - LOW DITHER PRESETS +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 20) + #define FXAA_QUALITY__PS 3 + #define FXAA_QUALITY__P0 1.5 + #define FXAA_QUALITY__P1 2.0 + #define FXAA_QUALITY__P2 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 21) + #define FXAA_QUALITY__PS 4 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 22) + #define FXAA_QUALITY__PS 5 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 23) + #define FXAA_QUALITY__PS 6 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 24) + #define FXAA_QUALITY__PS 7 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 3.0 + #define FXAA_QUALITY__P6 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 25) + #define FXAA_QUALITY__PS 8 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 4.0 + #define FXAA_QUALITY__P7 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 26) + #define FXAA_QUALITY__PS 9 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 4.0 + #define FXAA_QUALITY__P8 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 27) + #define FXAA_QUALITY__PS 10 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 4.0 + #define FXAA_QUALITY__P9 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 28) + #define FXAA_QUALITY__PS 11 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 4.0 + #define FXAA_QUALITY__P10 8.0 +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_QUALITY__PRESET == 29) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.5 + #define FXAA_QUALITY__P2 2.0 + #define FXAA_QUALITY__P3 2.0 + #define FXAA_QUALITY__P4 2.0 + #define FXAA_QUALITY__P5 2.0 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + +/*============================================================================ + FXAA QUALITY - EXTREME QUALITY +============================================================================*/ +#if (FXAA_QUALITY__PRESET == 39) + #define FXAA_QUALITY__PS 12 + #define FXAA_QUALITY__P0 1.0 + #define FXAA_QUALITY__P1 1.0 + #define FXAA_QUALITY__P2 1.0 + #define FXAA_QUALITY__P3 1.0 + #define FXAA_QUALITY__P4 1.0 + #define FXAA_QUALITY__P5 1.5 + #define FXAA_QUALITY__P6 2.0 + #define FXAA_QUALITY__P7 2.0 + #define FXAA_QUALITY__P8 2.0 + #define FXAA_QUALITY__P9 2.0 + #define FXAA_QUALITY__P10 4.0 + #define FXAA_QUALITY__P11 8.0 +#endif + + + +/*============================================================================ + + API PORTING + +============================================================================*/ +#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) + #define FxaaBool bool + #define FxaaDiscard discard + #define FxaaFloat float + #define FxaaFloat2 vec2 + #define FxaaFloat3 vec3 + #define FxaaFloat4 vec4 + #define FxaaHalf float + #define FxaaHalf2 vec2 + #define FxaaHalf3 vec3 + #define FxaaHalf4 vec4 + #define FxaaInt2 ivec2 + #define FxaaSat(x) clamp(x, 0.0, 1.0) + #define FxaaTex sampler2D +#else + #define FxaaBool bool + #define FxaaDiscard clip(-1) + #define FxaaFloat float + #define FxaaFloat2 float2 + #define FxaaFloat3 float3 + #define FxaaFloat4 float4 + #define FxaaHalf half + #define FxaaHalf2 half2 + #define FxaaHalf3 half3 + #define FxaaHalf4 half4 + #define FxaaSat(x) saturate(x) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_120 == 1) + // Requires, + // #version 120 + // And at least, + // #extension GL_EXT_gpu_shader4 : enable + // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) + #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) + #if (FXAA_FAST_PIXEL_OFFSET == 1) + #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) + #else + #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) + #endif + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_GLSL_130 == 1) + // Requires "#version 130" or better + #define FxaaTexTop(t, p) textureLod(t, p, 0.0) + #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) + #if (FXAA_GATHER4_ALPHA == 1) + // use #extension GL_ARB_gpu_shader5 : enable + #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) + #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) + #define FxaaTexGreen4(t, p) textureGather(t, p, 1) + #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) + #endif +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) + #define FxaaInt2 float2 + #define FxaaTex sampler2D + #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) + #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_4 == 1) + #define FxaaInt2 int2 + #define FxaaTex Texture2D + #define FxaaTexTop(t, p) t.SampleLevel(LinearSampler, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.SampleLevel(LinearSampler, p, 0.0, o) +#endif +/*--------------------------------------------------------------------------*/ +#if (FXAA_HLSL_5 == 1) + #define FxaaInt2 int2 + #define FxaaTex Texture2D + #define FxaaTexTop(t, p) t.SampleLevel(LinearSampler, p, 0.0) + #define FxaaTexOff(t, p, o, r) t.SampleLevel(LinearSampler, p, 0.0, o) + #define FxaaTexAlpha4(t, p) t.GatherAlpha(LinearSampler, p) + #define FxaaTexOffAlpha4(t, p, o) t.GatherAlpha(LinearSampler, p, o) + #define FxaaTexGreen4(t, p) t.GatherGreen(LinearSampler, p) + #define FxaaTexOffGreen4(t, p, o) t.GatherGreen(LinearSampler, p, o) +#endif + + +/*============================================================================ + GREEN AS LUMA OPTION SUPPORT FUNCTION +============================================================================*/ +#if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } +#else + FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } +#endif + + + + +/*============================================================================ + + FXAA3 QUALITY - PC + +============================================================================*/ +#if (FXAA_PC == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy} = center of pixel + FxaaFloat2 pos, + // + // Used only for FXAA Console, and not used on the 360 version. + // Use noperspective interpolation here (turn off perspective interpolation). + // {xy__} = upper left of pixel + // {__zw} = lower right of pixel + FxaaFloat4 fxaaConsolePosPos, + // + // Input color texture. + // {rgb_} = color in linear or perceptual color space + // if (FXAA_GREEN_AS_LUMA == 0) + // {___a} = luma in perceptual color space (not linear) + FxaaTex tex, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 2nd sampler. + // This sampler needs to have an exponent bias of -1. + FxaaTex fxaaConsole360TexExpBiasNegOne, + // + // Only used on the optimized 360 version of FXAA Console. + // For everything but 360, just use the same input here as for "tex". + // For 360, same texture, just alias with a 3nd sampler. + // This sampler needs to have an exponent bias of -2. + FxaaTex fxaaConsole360TexExpBiasNegTwo, + // + // Only used on FXAA Quality. + // This must be from a constant/uniform. + // {x_} = 1.0/screenWidthInPixels + // {_y} = 1.0/screenHeightInPixels + FxaaFloat2 fxaaQualityRcpFrame, + // + // Only used on FXAA Console. + // This must be from a constant/uniform. + // This effects sub-pixel AA quality and inversely sharpness. + // Where N ranges between, + // N = 0.50 (default) + // N = 0.33 (sharper) + // {x___} = -N/screenWidthInPixels + // {_y__} = -N/screenHeightInPixels + // {__z_} = N/screenWidthInPixels + // {___w} = N/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt, + // + // Only used on FXAA Console. + // Not used on 360, but used on PS3 and PC. + // This must be from a constant/uniform. + // {x___} = -2.0/screenWidthInPixels + // {_y__} = -2.0/screenHeightInPixels + // {__z_} = 2.0/screenWidthInPixels + // {___w} = 2.0/screenHeightInPixels + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + // + // Only used on FXAA Console. + // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. + // This must be from a constant/uniform. + // {x___} = 8.0/screenWidthInPixels + // {_y__} = 8.0/screenHeightInPixels + // {__z_} = -4.0/screenWidthInPixels + // {___w} = -4.0/screenHeightInPixels + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__SUBPIX define. + // It is here now to allow easier tuning. + // Choose the amount of sub-pixel aliasing removal. + // This can effect sharpness. + // 1.00 - upper limit (softer) + // 0.75 - default amount of filtering + // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) + // 0.25 - almost off + // 0.00 - completely off + FxaaFloat fxaaQualitySubpix, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // The minimum amount of local contrast required to apply algorithm. + // 0.333 - too little (faster) + // 0.250 - low quality + // 0.166 - default + // 0.125 - high quality + // 0.063 - overkill (slower) + FxaaFloat fxaaQualityEdgeThreshold, + // + // Only used on FXAA Quality. + // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // 0.0833 - upper limit (default, the start of visible unfiltered edges) + // 0.0625 - high quality (faster) + // 0.0312 - visible limit (slower) + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaQualityEdgeThresholdMin, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. + // Due to the PS3 being ALU bound, + // there are only three safe values here: 2 and 4 and 8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // For all other platforms can be a non-power of two. + // 8.0 is sharper (default!!!) + // 4.0 is softer + // 2.0 is really soft (good only for vector graphics inputs) + FxaaFloat fxaaConsoleEdgeSharpness, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. + // It is here now to allow easier tuning. + // This does not effect PS3, as this needs to be compiled in. + // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. + // Due to the PS3 being ALU bound, + // there are only two safe values here: 1/4 and 1/8. + // These options use the shaders ability to a free *|/ by 2|4|8. + // The console setting has a different mapping than the quality setting. + // Other platforms can use other values. + // 0.125 leaves less aliasing, but is softer (default!!!) + // 0.25 leaves more aliasing, and is sharper + FxaaFloat fxaaConsoleEdgeThreshold, + // + // Only used on FXAA Console. + // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. + // It is here now to allow easier tuning. + // Trims the algorithm from processing darks. + // The console setting has a different mapping than the quality setting. + // This only applies when FXAA_EARLY_EXIT is 1. + // This does not apply to PS3, + // PS3 was simplified to avoid more shader instructions. + // 0.06 - faster but more aliasing in darks + // 0.05 - default + // 0.04 - slower and less aliasing in darks + // Special notes when using FXAA_GREEN_AS_LUMA, + // Likely want to set this to zero. + // As colors that are mostly not-green + // will appear very dark in the green channel! + // Tune by looking at mostly non-green content, + // then start at zero and increase until aliasing is a problem. + FxaaFloat fxaaConsoleEdgeThresholdMin, + // + // Extra constants for 360 FXAA Console only. + // Use zeros or anything else for other platforms. + // These must be in physical constant registers and NOT immedates. + // Immedates will result in compiler un-optimizing. + // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posM; + posM.x = pos.x; + posM.y = pos.y; + #if (FXAA_GATHER4_ALPHA == 1) + #if (FXAA_DISCARD == 0) + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + #endif + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); + #else + FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); + FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); + #endif + #if (FXAA_DISCARD == 1) + #define lumaM luma4A.w + #endif + #define lumaE luma4A.z + #define lumaS luma4A.x + #define lumaSE luma4A.y + #define lumaNW luma4B.w + #define lumaN luma4B.z + #define lumaW luma4B.x + #else + FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); + #if (FXAA_GREEN_AS_LUMA == 0) + #define lumaM rgbyM.w + #else + #define lumaM rgbyM.y + #endif + FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat maxSM = max(lumaS, lumaM); + FxaaFloat minSM = min(lumaS, lumaM); + FxaaFloat maxESM = max(lumaE, maxSM); + FxaaFloat minESM = min(lumaE, minSM); + FxaaFloat maxWN = max(lumaN, lumaW); + FxaaFloat minWN = min(lumaN, lumaW); + FxaaFloat rangeMax = max(maxWN, maxESM); + FxaaFloat rangeMin = min(minWN, minESM); + FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; + FxaaFloat range = rangeMax - rangeMin; + FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); + FxaaBool earlyExit = range < rangeMaxClamped; +/*--------------------------------------------------------------------------*/ + if(earlyExit) + #if (FXAA_DISCARD == 1) + FxaaDiscard; + #else + return rgbyM; + #endif +/*--------------------------------------------------------------------------*/ + #if (FXAA_GATHER4_ALPHA == 0) + FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #else + FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); + FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNS = lumaN + lumaS; + FxaaFloat lumaWE = lumaW + lumaE; + FxaaFloat subpixRcpRange = 1.0/range; + FxaaFloat subpixNSWE = lumaNS + lumaWE; + FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; + FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNESE = lumaNE + lumaSE; + FxaaFloat lumaNWNE = lumaNW + lumaNE; + FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; + FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNWSW = lumaNW + lumaSW; + FxaaFloat lumaSWSE = lumaSW + lumaSE; + FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); + FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); + FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; + FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; + FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; + FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; +/*--------------------------------------------------------------------------*/ + FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; + FxaaFloat lengthSign = fxaaQualityRcpFrame.x; + FxaaBool horzSpan = edgeHorz >= edgeVert; + FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; +/*--------------------------------------------------------------------------*/ + if(!horzSpan) lumaN = lumaW; + if(!horzSpan) lumaS = lumaE; + if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; + FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; +/*--------------------------------------------------------------------------*/ + FxaaFloat gradientN = lumaN - lumaM; + FxaaFloat gradientS = lumaS - lumaM; + FxaaFloat lumaNN = lumaN + lumaM; + FxaaFloat lumaSS = lumaS + lumaM; + FxaaBool pairN = abs(gradientN) >= abs(gradientS); + FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); + if(pairN) lengthSign = -lengthSign; + FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posB; + posB.x = posM.x; + posB.y = posM.y; + FxaaFloat2 offNP; + offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; + offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; + if(!horzSpan) posB.x += lengthSign * 0.5; + if( horzSpan) posB.y += lengthSign * 0.5; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 posN; + posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; + posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; + FxaaFloat2 posP; + posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; + posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; + FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; + FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); + FxaaFloat subpixE = subpixC * subpixC; + FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); +/*--------------------------------------------------------------------------*/ + if(!pairN) lumaNN = lumaSS; + FxaaFloat gradientScaled = gradient * 1.0/4.0; + FxaaFloat lumaMM = lumaM - lumaNN * 0.5; + FxaaFloat subpixF = subpixD * subpixE; + FxaaBool lumaMLTZero = lumaMM < 0.0; +/*--------------------------------------------------------------------------*/ + lumaEndN -= lumaNN * 0.5; + lumaEndP -= lumaNN * 0.5; + FxaaBool doneN = abs(lumaEndN) >= gradientScaled; + FxaaBool doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; + FxaaBool doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; +/*--------------------------------------------------------------------------*/ + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 3) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 4) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 5) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 6) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 7) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 8) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 9) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 10) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 11) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; +/*--------------------------------------------------------------------------*/ + #if (FXAA_QUALITY__PS > 12) + if(doneNP) { + if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); + if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); + if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; + if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; + doneN = abs(lumaEndN) >= gradientScaled; + doneP = abs(lumaEndP) >= gradientScaled; + if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; + if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; + doneNP = (!doneN) || (!doneP); + if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; + if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } + #endif +/*--------------------------------------------------------------------------*/ + } +/*--------------------------------------------------------------------------*/ + FxaaFloat dstN = posM.x - posN.x; + FxaaFloat dstP = posP.x - posM.x; + if(!horzSpan) dstN = posM.y - posN.y; + if(!horzSpan) dstP = posP.y - posM.y; +/*--------------------------------------------------------------------------*/ + FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; + FxaaFloat spanLength = (dstP + dstN); + FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; + FxaaFloat spanLengthRcp = 1.0/spanLength; +/*--------------------------------------------------------------------------*/ + FxaaBool directionN = dstN < dstP; + FxaaFloat dst = min(dstN, dstP); + FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; + FxaaFloat subpixG = subpixF * subpixF; + FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; + FxaaFloat subpixH = subpixG * fxaaQualitySubpix; +/*--------------------------------------------------------------------------*/ + FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; + FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); + if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; + if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; + #if (FXAA_DISCARD == 1) + return FxaaTexTop(tex, posM); + #else + return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); + #endif +} +/*==========================================================================*/ +#endif + + + + +/*============================================================================ + + FXAA3 CONSOLE - PC VERSION + +------------------------------------------------------------------------------ +Instead of using this on PC, I'd suggest just using FXAA Quality with + #define FXAA_QUALITY__PRESET 10 +Or + #define FXAA_QUALITY__PRESET 20 +Either are higher qualilty and almost as fast as this on modern PC GPUs. +============================================================================*/ +#if (FXAA_PC_CONSOLE == 1) +/*--------------------------------------------------------------------------*/ +FxaaFloat4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); + FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); + FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); + FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaFloat lumaM = rgbyM.w; + #else + FxaaFloat lumaM = rgbyM.y; + #endif +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); + lumaNe += 1.0/384.0; + FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); + FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); + FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; +/*--------------------------------------------------------------------------*/ + FxaaFloat lumaMinM = min(lumaMin, lumaM); + FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); + FxaaFloat lumaMaxM = max(lumaMax, lumaM); + FxaaFloat dirSwMinusNe = lumaSw - lumaNe; + FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; + FxaaFloat dirSeMinusNw = lumaSe - lumaNw; + if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir; + dir.x = dirSwMinusNe + dirSeMinusNw; + dir.y = dirSwMinusNe - dirSeMinusNw; +/*--------------------------------------------------------------------------*/ + FxaaFloat2 dir1 = normalize(dir.xy); + FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); + FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; + FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); + FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); +/*--------------------------------------------------------------------------*/ + FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; + FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); +/*--------------------------------------------------------------------------*/ + #if (FXAA_GREEN_AS_LUMA == 0) + FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); + #else + FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); + #endif + if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; + return rgbyB; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - 360 PIXEL SHADER + +------------------------------------------------------------------------------ +This optimized version thanks to suggestions from Andy Luedke. +Should be fully tex bound in all cases. +As of the FXAA 3.11 release, I have still not tested this code, +however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. +And note this is replacing the old unoptimized version. +If it does not work, please let me know so I can fix it. +============================================================================*/ +#if (FXAA_360 == 1) +/*--------------------------------------------------------------------------*/ +[reduceTempRegUsage(4)] +float4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ + float4 lumaNwNeSwSe; + #if (FXAA_GREEN_AS_LUMA == 0) + asm { + tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #else + asm { + tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false + tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false + }; + #endif +/*--------------------------------------------------------------------------*/ + lumaNwNeSwSe.y += 1.0/384.0; + float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); + float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); + float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); +/*--------------------------------------------------------------------------*/ + float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + float lumaMinM = min(lumaMin, rgbyM.w); + float lumaMaxM = max(lumaMax, rgbyM.w); + #else + float lumaMinM = min(lumaMin, rgbyM.y); + float lumaMaxM = max(lumaMax, rgbyM.y); + #endif + if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; +/*--------------------------------------------------------------------------*/ + float2 dir; + dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); + dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); + dir = normalize(dir); +/*--------------------------------------------------------------------------*/ + float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; +/*--------------------------------------------------------------------------*/ + float4 dir2; + float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; + dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); + dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; +/*--------------------------------------------------------------------------*/ + float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); + float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); + float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); + float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ + float4 rgbyA = rgbyN1 + rgbyP1; + float4 rgbyB = rgbyN2 + rgbyP2 * 0.5 + rgbyA; +/*--------------------------------------------------------------------------*/ + float4 rgbyR = ((rgbyB.w - lumaMax) > 0.0) ? rgbyA : rgbyB; + rgbyR = ((rgbyB.w - lumaMin) > 0.0) ? rgbyR : rgbyA; + return rgbyR; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) + +============================================================================== +The code below does not exactly match the assembly. +I have a feeling that 12 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h0.w(TRUE), v5.xwxx, #0 + 6: addh h0.z(TRUE), -h2, h0.w + 7: texpkb h1.w(TRUE), v5, #0 + 9: addh h0.x(TRUE), h0.z, -h1.w + 10: addh h3.w(TRUE), h0.z, h1 + 11: texpkb h2.w(TRUE), v5.zwzz, #0 + 13: addh h0.z(TRUE), h3.w, -h2.w + 14: addh h0.x(TRUE), h2.w, h0 + 15: nrmh h1.xz(TRUE), h0_n + 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| + 17: maxh h4.w(TRUE), h0, h1 + 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n + 19: movr r1.zw(TRUE), v4.xxxy + 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww + 22: minh h5.w(TRUE), h0, h1 + 23: texpkb h0(TRUE), r2.xzxx, #0 + 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 + 27: maxh h4.x(TRUE), h2.z, h2.w + 28: texpkb h1(TRUE), r0.zwzz, #0 + 30: addh_d2 h1(TRUE), h0, h1 + 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 33: texpkb h0(TRUE), r0, #0 + 35: minh h4.z(TRUE), h2, h2.w + 36: fenct TRUE + 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 39: texpkb h2(TRUE), r1, #0 + 41: addh_d2 h0(TRUE), h0, h2 + 42: maxh h2.w(TRUE), h4, h4.x + 43: minh h2.x(TRUE), h5.w, h4.z + 44: addh_d2 h0(TRUE), h0, h1 + 45: slth h2.x(TRUE), h0.w, h2 + 46: sgth h2.w(TRUE), h0, h2 + 47: movh h0(TRUE), h0 + 48: addx.c0 rc(TRUE), h2, h2.w + 49: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; + | | | + 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; + | | | + 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; + | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; + | | | + 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; + | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; + | | | + 5 | SCT1 | mov | 15: NRMh h1.xz, h0; + | SRB | nrm | 15: NRMh h1.xz, h0; + | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; + | SCB1 | max | 17: MAXh h4.w, h0, h1; + | | | + 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; + | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; + | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; + | SCB1 | min | 22: MINh h5.w, h0, h1; + | | | + 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; + | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; + | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; + | | | + 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; + | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; + | | | + 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; + | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; + | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; + | | | + 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; + | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; + | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; + | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; + | | | + 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; + | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; + | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; + | | | + 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; + | SCT1 | set | 46: SGTh h2.w, h0, h2; + | SCB0/1 | mul | 47: MOVh h0, h0; + | | | + 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; + | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 0% 0% 50% + 6: 100% 0% 75% + 7: 0% 100% 75% + 8: 0% 100% 100% + 9: 0% 100% 25% + 10: 0% 100% 100% + 11: 50% 0% 100% + 12: 50% 0% 100% + 13: 25% 0% 100% + +MEAN: 17% 61% 67% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 0% 100% + 2: 0% 0% 100% 0% 100% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 0% 0% 0% 100% 100% + 6: 100% 100% 0% 100% 100% + 7: 0% 0% 100% 100% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 0% 100% + 10: 0% 0% 100% 100% 100% + 11: 100% 100% 0% 100% 100% + 12: 100% 100% 0% 100% 100% + 13: 100% 0% 0% 100% 100% + +MEAN: 30% 23% 61% 76% 100% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 13 cycles, 3 r regs, 923,076,923 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O3 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 dir; + half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + lumaNe.w += half(1.0/512.0); + dir.x = -lumaNe.w; + dir.z = -lumaNe.w; + #else + lumaNe.y += half(1.0/512.0); + dir.x = -lumaNe.y; + dir.z = -lumaNe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSw.w; + dir.z += lumaSw.w; + #else + dir.x += lumaSw.y; + dir.z += lumaSw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x -= lumaNw.w; + dir.z += lumaNw.w; + #else + dir.x -= lumaNw.y; + dir.z += lumaNw.y; + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x += lumaSe.w; + dir.z -= lumaSe.w; + #else + dir.x += lumaSe.y; + dir.z -= lumaSe.y; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half4 dir1_pos; + dir1_pos.xy = normalize(dir.xyz).xz; + half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (7) + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; +/*--------------------------------------------------------------------------*/ +// (8) + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (9) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (11) + // compilier moves these scalar ops up to other cycles + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); + half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); + #else + half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); + half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); + #endif + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (12) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif +/*--------------------------------------------------------------------------*/ +// (13) + if(twoTapLt || twoTapGt) rgby2 = rgby1; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + + +/*============================================================================ + + FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) + +============================================================================== +The code mostly matches the assembly. +I have a feeling that 14 cycles is possible, but was not able to get there. +Might have to increase register count to get full performance. +Note this shader does not use perspective interpolation. + +Use the following cgc options, + + --fenable-bx2 --fastmath --fastprecision --nofloatbindings + +Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). +Will look at fixing this for FXAA 3.12. +------------------------------------------------------------------------------ + NVSHADERPERF OUTPUT +------------------------------------------------------------------------------ +For reference and to aid in debug, output of NVShaderPerf should match this, + +Shader to schedule: + 0: texpkb h0.w(TRUE), v5.zyxx, #0 + 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x + 4: texpkb h1.w(TRUE), v5.xwxx, #0 + 6: addh h0.x(TRUE), h1.w, -h2.y + 7: texpkb h2.w(TRUE), v5.zwzz, #0 + 9: minh h4.w(TRUE), h2.y, h2 + 10: maxh h5.x(TRUE), h2.y, h2.w + 11: texpkb h0.w(TRUE), v5, #0 + 13: addh h3.w(TRUE), -h0, h0.x + 14: addh h0.x(TRUE), h0.w, h0 + 15: addh h0.z(TRUE), -h2.w, h0.x + 16: addh h0.x(TRUE), h2.w, h3.w + 17: minh h5.y(TRUE), h0.w, h1.w + 18: nrmh h2.xz(TRUE), h0_n + 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| + 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w + 21: movr r1.zw(TRUE), v4.xxxy + 22: maxh h2.w(TRUE), h0, h1 + 23: fenct TRUE + 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 26: texpkb h0(TRUE), r0, #0 + 28: maxh h5.x(TRUE), h2.w, h5 + 29: minh h5.w(TRUE), h5.y, h4 + 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz + 32: texpkb h2(TRUE), r1, #0 + 34: addh_d2 h2(TRUE), h0, h2 + 35: texpkb h1(TRUE), v4, #0 + 37: maxh h5.y(TRUE), h5.x, h1.w + 38: minh h4.w(TRUE), h1, h5 + 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 41: texpkb h0(TRUE), r0, #0 + 43: addh_m8 h5.z(TRUE), h5.y, -h4.w + 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz + 46: texpkb h3(TRUE), r2, #0 + 48: addh_d2 h0(TRUE), h0, h3 + 49: addh_d2 h3(TRUE), h0, h2 + 50: movh h0(TRUE), h3 + 51: slth h3.x(TRUE), h3.w, h5.w + 52: sgth h3.w(TRUE), h3, h5.x + 53: addx.c0 rc(TRUE), h3.x, h3 + 54: slth.c0 rc(TRUE), h5.z, h5 + 55: movh h0(c0.NE.w), h2 + 56: movh h0(c0.NE.x), h1 + +IPU0 ------ Simplified schedule: -------- +Pass | Unit | uOp | PC: Op +-----+--------+------+------------------------- + 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; + | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; + | | | + 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; + | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; + | | | + 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; + | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; + | SCB1 | min | 9: MINh h4.w, h2.---y, h2; + | | | + 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; + | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; + | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; + | | | + 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; + | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; + | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; + | | | + 6 | SCT1 | mov | 18: NRMh h2.xz, h0; + | SRB | nrm | 18: NRMh h2.xz, h0; + | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; + | | | + 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; + | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; + | SCB1 | max | 22: MAXh h2.w, h0, h1; + | | | + 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; + | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; + | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; + | SCB1 | min | 29: MINh h5.w, h5.---y, h4; + | | | + 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; + | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; + | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; + | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; + | | | + 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; + | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; + | SCB1 | min | 38: MINh h4.w, h1, h5; + | | | + 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; + | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; + | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; + | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; + | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; + | | | + 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; + | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; + | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; + | | | + 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; + | SCB0/1 | mul | 50: MOVh h0, h3; + | | | + 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; + | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; + | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; + | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; + | | | + 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; + | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; + +Pass SCT TEX SCB + 1: 0% 100% 25% + 2: 0% 100% 25% + 3: 0% 100% 50% + 4: 0% 100% 50% + 5: 50% 0% 25% + 6: 0% 0% 25% + 7: 100% 0% 25% + 8: 0% 100% 50% + 9: 0% 100% 100% + 10: 0% 100% 50% + 11: 0% 100% 75% + 12: 0% 100% 100% + 13: 100% 0% 100% + 14: 50% 0% 50% + 15: 100% 0% 100% + +MEAN: 26% 60% 56% + +Pass SCT0 SCT1 TEX SCB0 SCB1 + 1: 0% 0% 100% 100% 0% + 2: 0% 0% 100% 100% 0% + 3: 0% 0% 100% 100% 100% + 4: 0% 0% 100% 100% 100% + 5: 100% 100% 0% 100% 0% + 6: 0% 0% 0% 0% 100% + 7: 100% 100% 0% 0% 100% + 8: 0% 0% 100% 100% 100% + 9: 0% 0% 100% 100% 100% + 10: 0% 0% 100% 100% 100% + 11: 0% 0% 100% 100% 100% + 12: 0% 0% 100% 100% 100% + 13: 100% 100% 0% 100% 100% + 14: 100% 100% 0% 100% 100% + 15: 100% 100% 0% 100% 100% + +MEAN: 33% 33% 60% 86% 80% +Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 +Results 15 cycles, 3 r regs, 800,000,000 pixels/s +============================================================================*/ +#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) +/*--------------------------------------------------------------------------*/ +#pragma regcount 7 +#pragma disablepc all +#pragma option O2 +#pragma option OutColorPrec=fp16 +#pragma texformat default RGBA8 +/*==========================================================================*/ +half4 FxaaPixelShader( + // See FXAA Quality FxaaPixelShader() source for docs on Inputs! + FxaaFloat2 pos, + FxaaFloat4 fxaaConsolePosPos, + FxaaTex tex, + FxaaTex fxaaConsole360TexExpBiasNegOne, + FxaaTex fxaaConsole360TexExpBiasNegTwo, + FxaaFloat2 fxaaQualityRcpFrame, + FxaaFloat4 fxaaConsoleRcpFrameOpt, + FxaaFloat4 fxaaConsoleRcpFrameOpt2, + FxaaFloat4 fxaaConsole360RcpFrameOpt2, + FxaaFloat fxaaQualitySubpix, + FxaaFloat fxaaQualityEdgeThreshold, + FxaaFloat fxaaQualityEdgeThresholdMin, + FxaaFloat fxaaConsoleEdgeSharpness, + FxaaFloat fxaaConsoleEdgeThreshold, + FxaaFloat fxaaConsoleEdgeThresholdMin, + FxaaFloat4 fxaaConsole360ConstDir +) { +/*--------------------------------------------------------------------------*/ +// (1) + half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaNe = rgbyNe.w + half(1.0/512.0); + #else + half lumaNe = rgbyNe.y + half(1.0/512.0); + #endif +/*--------------------------------------------------------------------------*/ +// (2) + half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaSwNegNe = lumaSw.w - lumaNe; + #else + half lumaSwNegNe = lumaSw.y - lumaNe; + #endif +/*--------------------------------------------------------------------------*/ +// (3) + half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); + half lumaMinNwSw = min(lumaNw.w, lumaSw.w); + #else + half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); + half lumaMinNwSw = min(lumaNw.y, lumaSw.y); + #endif +/*--------------------------------------------------------------------------*/ +// (4) + half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half dirZ = lumaNw.w + lumaSwNegNe; + half dirX = -lumaNw.w + lumaSwNegNe; + #else + half dirZ = lumaNw.y + lumaSwNegNe; + half dirX = -lumaNw.y + lumaSwNegNe; + #endif +/*--------------------------------------------------------------------------*/ +// (5) + half3 dir; + dir.y = 0.0; + #if (FXAA_GREEN_AS_LUMA == 0) + dir.x = lumaSe.w + dirX; + dir.z = -lumaSe.w + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.w); + #else + dir.x = lumaSe.y + dirX; + dir.z = -lumaSe.y + dirZ; + half lumaMinNeSe = min(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (6) + half4 dir1_pos; + dir1_pos.xy = normalize(dir).xz; + half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); +/*--------------------------------------------------------------------------*/ +// (7) + half4 dir2_pos; + dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); + dir1_pos.zw = pos.xy; + dir2_pos.zw = pos.xy; + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxNeSe = max(lumaNe, lumaSe.w); + #else + half lumaMaxNeSe = max(lumaNe, lumaSe.y); + #endif +/*--------------------------------------------------------------------------*/ +// (8) + half4 temp1N; + temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); + half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); + half lumaMin = min(lumaMinNwSw, lumaMinNeSe); +/*--------------------------------------------------------------------------*/ +// (9) + half4 rgby1; + rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; + rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); + rgby1 = (temp1N + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (10) + half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); + #if (FXAA_GREEN_AS_LUMA == 0) + half lumaMaxM = max(lumaMax, rgbyM.w); + half lumaMinM = min(lumaMin, rgbyM.w); + #else + half lumaMaxM = max(lumaMax, rgbyM.y); + half lumaMinM = min(lumaMin, rgbyM.y); + #endif +/*--------------------------------------------------------------------------*/ +// (11) + half4 temp2N; + temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); + half4 rgby2; + rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; + half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; +/*--------------------------------------------------------------------------*/ +// (12) + rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); + rgby2 = (temp2N + rgby2) * 0.5; +/*--------------------------------------------------------------------------*/ +// (13) + rgby2 = (rgby2 + rgby1) * 0.5; +/*--------------------------------------------------------------------------*/ +// (14) + #if (FXAA_GREEN_AS_LUMA == 0) + bool twoTapLt = rgby2.w < lumaMin; + bool twoTapGt = rgby2.w > lumaMax; + #else + bool twoTapLt = rgby2.y < lumaMin; + bool twoTapGt = rgby2.y > lumaMax; + #endif + bool earlyExit = lumaRangeM < lumaMax; + bool twoTap = twoTapLt || twoTapGt; +/*--------------------------------------------------------------------------*/ +// (15) + if(twoTap) rgby2 = rgby1; + if(earlyExit) rgby2 = rgbyM; +/*--------------------------------------------------------------------------*/ + return rgby2; } +/*==========================================================================*/ +#endif + + stage override float4 Shading() + { + var texCoord = streams.TexCoord; + + float2 screenPixelRatio = Texture0TexelSize; + return FxaaPixelShader(texCoord, 0, Texture0, Texture0, Texture0, screenPixelRatio, 0, 0, 0, 0.75, 0.063, 0.0312, 8, 0.125, 0.05, 0); + } +}; diff --git a/assets/Stride/SDSL/FilmGrainShader.sdsl b/assets/Stride/SDSL/FilmGrainShader.sdsl new file mode 100644 index 0000000000..9453390c87 --- /dev/null +++ b/assets/Stride/SDSL/FilmGrainShader.sdsl @@ -0,0 +1,123 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Film-grain shader. + /// Adapted from the shader of Martins Upitis. + /// http://devlog-martinsh.blogspot.ca/2013/05/image-imperfections-and-film-grain-post.html + /// + internal shader FilmGrainShader : ColorTransformShader, Texturing + { + // Amount + float Amount; + + // Time changing at each frame for the animation + float Time; + + // Size of the grain + float GrainSize; + + // How the luminance influences the amount of grain. + float LuminanceFactor; + + override float4 Compute(float4 color) + { + float2 texCoord = streams.TexCoord; + + float2 rotCoordsR = coordRot(texCoord, Time); + float2 newCoord = rotCoordsR / Texture0TexelSize / GrainSize; + float n = pnoise3D(float3(newCoord, 0.0)); + float3 noiseFactor = float3(n, n, n); + + float3 col = color.rgb; + + // Noisiness response curve based on scene luminance + float luminance = lerp(0.0, LuminanceUtils.Luma(col), LuminanceFactor); + float lum = smoothstep(0.2, 0.0, luminance) + luminance; + + noiseFactor = saturate( lerp(noiseFactor, float3(0.0, 0.0, 0.0), pow(lum, 4.0))); + color.rgb += noiseFactor * Amount; + + return color; + } + + // Random texture generation + float4 rnm(float2 tc) + { + float noiseFactor = sin(dot(tc + float2(Time, Time), float2(12.9898, 78.233))) * 43758.5453; + + float4 result = float4( frac(noiseFactor), + frac(noiseFactor * 1.2154), + frac(noiseFactor * 1.3453), + frac(noiseFactor * 1.3647)); + return result * 2.0 - 1; + } + + float fade(float t) { + return Math.Quintic(t); + } + + float pnoise3D(float3 p) + { + float permTexUnit = 1.0 / 256.0; + float permTexUnitHalf = permTexUnit * 0.5; + + float3 pi = permTexUnit * floor(p) + permTexUnitHalf; // Integer part, scaled so +1 moves permTexUnit texel + // and offset 1/2 texel to sample texel centers + float3 pf = frac(p); // Fractional part for interpolation + + // Noise contributions from (x=0, y=0), z=0 and z=1 + float perm00 = rnm(pi.xy).a ; + float3 grad000 = rnm(float2(perm00, pi.z)).rgb * 4.0 - 1.0; + float n000 = dot(grad000, pf); + float3 grad001 = rnm(float2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0; + float n001 = dot(grad001, pf - float3(0.0, 0.0, 1.0)); + + // Noise contributions from (x=0, y=1), z=0 and z=1 + float perm01 = rnm(pi.xy + float2(0.0, permTexUnit)).a ; + float3 grad010 = rnm(float2(perm01, pi.z)).rgb * 4.0 - 1.0; + float n010 = dot(grad010, pf - float3(0.0, 1.0, 0.0)); + float3 grad011 = rnm(float2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0; + float n011 = dot(grad011, pf - float3(0.0, 1.0, 1.0)); + + // Noise contributions from (x=1, y=0), z=0 and z=1 + float perm10 = rnm(pi.xy + float2(permTexUnit, 0.0)).a ; + float3 grad100 = rnm(float2(perm10, pi.z)).rgb * 4.0 - 1.0; + float n100 = dot(grad100, pf - float3(1.0, 0.0, 0.0)); + float3 grad101 = rnm(float2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0; + float n101 = dot(grad101, pf - float3(1.0, 0.0, 1.0)); + + // Noise contributions from (x=1, y=1), z=0 and z=1 + float perm11 = rnm(pi.xy + float2(permTexUnit, permTexUnit)).a ; + float3 grad110 = rnm(float2(perm11, pi.z)).rgb * 4.0 - 1.0; + float n110 = dot(grad110, pf - float3(1.0, 1.0, 0.0)); + float3 grad111 = rnm(float2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0; + float n111 = dot(grad111, pf - float3(1.0, 1.0, 1.0)); + + // Blend contributions along x + float4 n_x = lerp(float4(n000, n001, n010, n011), float4(n100, n101, n110, n111), fade(pf.x)); + + // Blend contributions along y + float2 n_xy = lerp(n_x.xy, n_x.zw, fade(pf.y)); + + // Blend contributions along z + float n_xyz = lerp(n_xy.x, n_xy.y, fade(pf.z)); + + // We're done, return the final noise value. + return n_xyz; + } + + float2 coordRot(float2 tc, float angle) + { + float aspect = Texture0TexelSize.y / Texture0TexelSize.x; + float rotX = ((tc.x * 2.0 - 1.0) * aspect * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle)); + float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * aspect * sin(angle)); + rotX = ((rotX/aspect)*0.5+0.5); + rotY = rotY * 0.5 + 0.5; + return float2(rotX, rotY); + } + + }; +} diff --git a/assets/Stride/SDSL/FlareArtifactShader.sdsl b/assets/Stride/SDSL/FlareArtifactShader.sdsl new file mode 100644 index 0000000000..0b212a46a8 --- /dev/null +++ b/assets/Stride/SDSL/FlareArtifactShader.sdsl @@ -0,0 +1,72 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Lens flare artifact shader. + /// + internal shader FlareArtifactShader : ImageEffectShader + { + // Amount of blending + float Amount; + + // Offsets (zoom factor) and distortion of each tap + float2 ZoomOffsetsDistortions[TapCount]; + + // Modulate the color of each tap + float3 ColorAberrations[TapCount]; + + // Aberration strength + float AberrationStrength = 0; + + stage override float4 Shading() + { + float2 uv = streams.TexCoord; + + float2 fromCenterVector = uv - float2(0.5, 0.5); + float squareDistanceToCenter = dot(fromCenterVector, fromCenterVector); + float distanceToCenter = sqrt(squareDistanceToCenter); + + float2 originalUV = uv; + + float3 result = float3(0.0, 0.0, 0.0); + + [unroll] + for (int i = 0; i < TapCount; i++) + { + // Zoom effect + float2 zoomOffsetsDistortions = ZoomOffsetsDistortions[i]; + uv = ( originalUV - 0.5) * zoomOffsetsDistortions.x + 0.5; + + // Distort UV around the center + float distortion = sin(pow(distanceToCenter, zoomOffsetsDistortions.y)); // NOTE: Introducing the zoomOffsetsDistortions local variable prevents glLinkProgram from freezing on some android devices + float2 distortedUV = distortion * (uv - 0.5) + 0.5; + float3 tapColor = Texture0.Sample(LinearSampler, distortedUV).rgb; + + // Avoid hard cuts on the edge (vignetting-like) + float border = 0.1; + float2 borderNear = lerp( float2(0.0, 0.0), float2(1.0, 1.0), (0.5 - abs(distortedUV - 0.5)) / border); + float alpha = saturate(borderNear.x * borderNear.y); + tapColor *= alpha * alpha; + + // Avoid bleeding (could be clamp to border instead) + if (distortedUV.x < 0 || distortedUV.x > 1 || distortedUV.y < 0 || distortedUV.y > 1) tapColor = float3(0.0, 0.0, 0.0); + + /* + // Debug colors + if (i == 0 || i == 3) tapColor.r *= 10; + if (i == 1 || i == 4) tapColor.g *= 10; + if (i == 2 || i == 3 || i == 4) tapColor.b *= 10; + */ + + // Aberration + tapColor *= lerp( float3(1, 1, 1), ColorAberrations[i], AberrationStrength ); + + result += tapColor; + } + + return float4(result * Amount, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/FlareReplicate.sdsl b/assets/Stride/SDSL/FlareReplicate.sdsl new file mode 100644 index 0000000000..7df477b063 --- /dev/null +++ b/assets/Stride/SDSL/FlareReplicate.sdsl @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Replicates lens flare artifacts around. + /// + internal shader FlareReplicate : ImageEffectShader + { + + // Amount of blending + float Amount; + + // Halo factor + float HaloFactor; + + stage override float4 Shading() + { + float3 result = float3(0.0, 0.0, 0.0); + float2 originalUV = streams.TexCoord; + float2 uv = originalUV; + + // Initial flares + result += softBorderTap(uv); + + // Same flares downscaled + uv = (originalUV - 0.5) * 2.5 + 0.5; + result += softBorderTap(uv); + + uv = (originalUV - 0.5) * 4.0 + 0.5; + result += softBorderTap(uv); + + + // Symetry with scaling + uv = (originalUV - 0.5) * -4.5 + 0.5; + result += softBorderTap(uv); + + uv = (originalUV - 0.5) * -8.0 + 0.5; + result += softBorderTap(uv); + + + // Add some scale of the original bright pass + double-halo + uv = ( originalUV - 0.5) * -1.0 + 0.5; + result += Texture1.Sample(LinearSampler, uv).rgb * HaloFactor; + + uv = ( originalUV - 0.5) * -0.05 + 0.5; + result += Texture1.Sample(LinearSampler, uv).rgb * Amount; + + uv = ( originalUV - 0.5) * 0.1 + 0.5; + result += Texture1.Sample(LinearSampler, uv).rgb * HaloFactor * 0.5; + + return float4(result, 1.0); + } + + float3 softBorderTap(float2 uv) + { + float border = 0.18; + float2 borderNear = lerp( float2(0.0, 0.0), float2(1.0, 1.0), (0.5 - abs(uv - 0.5)) / border); + float alpha = saturate(borderNear.x * borderNear.y); + float3 result = Texture0.Sample(LinearSampler, uv).rgb * alpha; + if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) result = float3(0.0, 0.0, 0.0); + return result; + } + }; +} diff --git a/assets/Stride/SDSL/FlattenLayers.sdsl b/assets/Stride/SDSL/FlattenLayers.sdsl new file mode 100644 index 0000000000..51ecff4120 --- /dev/null +++ b/assets/Stride/SDSL/FlattenLayers.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Outputs the result of a compute color (useful to perform offline texture creation). +/// +shader FlattenLayers : ShaderBase, PositionStream4 +{ + compose ComputeColor outColor; + + stage override void VSMain() + { + base.VSMain(); + streams.ShadingPosition = streams.Position; + } + + stage override void PSMain() + { + base.PSMain(); + streams.ColorTarget = outColor.Compute(); + } +}; diff --git a/assets/Stride/SDSL/FogEffect.sdsl b/assets/Stride/SDSL/FogEffect.sdsl new file mode 100644 index 0000000000..927b5319f4 --- /dev/null +++ b/assets/Stride/SDSL/FogEffect.sdsl @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Simple fog + /// + internal shader FogEffect : ImageEffectShader + { + stage float FogStart; + stage float Density; + stage float zFar; + stage float zNear; + stage bool skipBG; + + stage float3 FogColor; + stage Texture2D DepthTexture; + + stage override float4 Shading() + { + float4 color = Texture0.Sample(PointSampler, streams.TexCoord); + float z_b = DepthTexture.SampleLevel(PointSampler, streams.TexCoord, 0.0).x; + + if (!skipBG || z_b < 1.0) { + float z_n = 2.0 * z_b - 1.0; + float dist = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); + dist -= FogStart; + + float fogAmount = clamp(exp(dist * -Density), 0.0, 1.0); + + color.xyz = lerp(FogColor, color.xyz, fogAmount); + } + + return color; + } + }; +} diff --git a/assets/Stride/SDSL/ForEachTest.sdsl b/assets/Stride/SDSL/ForEachTest.sdsl new file mode 100644 index 0000000000..3f9b08c2af --- /dev/null +++ b/assets/Stride/SDSL/ForEachTest.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ForEachTest +{ + float collec[5]; + + float test() + { + float res = 0.0; + foreach (var val in collec) + { + res += val; + } + return res; + } +}; diff --git a/assets/Stride/SDSL/GBuffer.sdsl b/assets/Stride/SDSL/GBuffer.sdsl new file mode 100644 index 0000000000..a560d7de83 --- /dev/null +++ b/assets/Stride/SDSL/GBuffer.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Deferred +{ + /// + /// An array of light groups + /// + shader GBuffer : ShaderBase, MaterialPixelStream + { + stage override void PSMain() + { + base.PSMain(); + + streams.ColorTarget = float4(streams.normalWS, 1.0f); + } + }; +} diff --git a/assets/Stride/SDSL/GBufferOutputNormals.sdsl b/assets/Stride/SDSL/GBufferOutputNormals.sdsl new file mode 100644 index 0000000000..7c1585c251 --- /dev/null +++ b/assets/Stride/SDSL/GBufferOutputNormals.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials.Shaders +{ + /// + /// Outputs material world space normal vectors (packed from [-1;-1] to [0;1] to fit smaller render targets) + /// + shader GBufferOutputNormals : ComputeColor, MaterialPixelShadingStream, NormalPack + { + override float4 Compute() + { + return float4(EncodeNormal(streams.normalWS), 1); + } + }; +} diff --git a/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl b/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl new file mode 100644 index 0000000000..0d5fca8567 --- /dev/null +++ b/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials.Shaders +{ + /// + /// Outputs material specular color (RGB) and roughness (A) + /// + shader GBufferOutputSpecularColorRoughness : ComputeColor, MaterialPixelShadingStream, Utilities + { + override float4 Compute() + { + return float4(streams.matSpecularVisible, sqrt(streams.alphaRoughness)); // alphaRoughness = roughness^2 + } + }; +} diff --git a/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl b/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl new file mode 100644 index 0000000000..1ba7541a6a --- /dev/null +++ b/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// + class GBufferOutputSubsurfaceScatteringMaterialIndex : ComputeColor + { + cbuffer PerDraw + { + // TODO: How to initialize this to 0 at all times for every material? + stage uint MaterialIndex; // This is only defined here so it can be overwritten by SubsurfaceScatteringRenderFeature in order to index the material inside the post process. + } + + override float4 Compute() + { + return MaterialIndex; + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/GaussianBlurShader.sdsl b/assets/Stride/SDSL/GaussianBlurShader.sdsl new file mode 100644 index 0000000000..c7335bcd14 --- /dev/null +++ b/assets/Stride/SDSL/GaussianBlurShader.sdsl @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A gaussian blur shader + /// + internal shader GaussianBlurShader : ImageEffectShader + { + stage float2 OffsetsWeights[BlurCount]; + + stage override float4 Shading() + { + // Direction in texel size: (float2(1,0) or float2(0,1)) * texel size + float2 direction = (IsVertical ? float2(0, 1) : float2(1, 0)) * Texture0TexelSize; + + // Add center + float3 value = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * OffsetsWeights[0].y; + + // mirrored samples using bilinear filtering + [unroll] + for(int i = 1; i < BlurCount; i++) + { + value += Texture0.Sample(LinearSampler, streams.TexCoord - direction * OffsetsWeights[i].x).rgb * OffsetsWeights[i].y; + value += Texture0.Sample(LinearSampler, streams.TexCoord + direction * OffsetsWeights[i].x).rgb * OffsetsWeights[i].y; + } + + return float4(value, 1); + } + }; +} diff --git a/assets/Stride/SDSL/GenericCall.sdsl b/assets/Stride/SDSL/GenericCall.sdsl new file mode 100644 index 0000000000..e08c997320 --- /dev/null +++ b/assets/Stride/SDSL/GenericCall.sdsl @@ -0,0 +1,5 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GenericCall : TestGenerics<1.000000> +{ +}; diff --git a/assets/Stride/SDSL/GenericClass.sdsl b/assets/Stride/SDSL/GenericClass.sdsl new file mode 100644 index 0000000000..938068ca99 --- /dev/null +++ b/assets/Stride/SDSL/GenericClass.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GenericClass< + Texture2D Texture,// = Texturing.Texture0, + SamplerState Sampler,// = Texturing.Sampler, + Semantic NAME, // = TEXCOORD0 + LinkType myLink, + unorm float constFloat, + int2 constInt2, + uint3 constUInt3, + float4 constUNormFloat4, + float linkVariable +> : TestBaseClass +{ + [Link("GenericLink.myLink")] + stage float3 uniformVariable; + + stage stream float2 texCoord : NAME; + + float genericCompute() + { + float4 value0 = TestBaseClass.Value; + return streams.texCoord.x * Texture.Sample(Sampler, streams.texCoord).x; + } +}; diff --git a/assets/Stride/SDSL/GenericClass2.sdsl b/assets/Stride/SDSL/GenericClass2.sdsl new file mode 100644 index 0000000000..6d724ee1dd --- /dev/null +++ b/assets/Stride/SDSL/GenericClass2.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GenericClass2 +< + Texture2D Texture, + Semantic TEXCOORD_INDEX, + float4 scale +> : ShaderBase, Texturing +{ + stage stream float2 texcoord0 : TEXCOORD_INDEX; + Texture2D TextureAll = Texturing.Texture3; + + stage override void VSMain() + { + streams.ShadingPosition = float4(1,1,1,1) * Texture.SampleLevel(Sampler, streams.texcoord0, 0); + } + + stage override void PSMain() + { + streams.ColorTarget = scale * float4(1,1,1,1) * streams.ShadingPosition * Texturing.Texture1.Sample(Sampler, streams.texcoord0); + streams.ColorTarget = streams.ColorTarget * GenericClass.genericCompute(); + } +}; diff --git a/assets/Stride/SDSL/GenericExtern.sdsl b/assets/Stride/SDSL/GenericExtern.sdsl new file mode 100644 index 0000000000..655f2afb72 --- /dev/null +++ b/assets/Stride/SDSL/GenericExtern.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GenericExtern +{ + compose GenericTexcoord myExtern; +}; diff --git a/assets/Stride/SDSL/GenericTexcoord.sdsl b/assets/Stride/SDSL/GenericTexcoord.sdsl new file mode 100644 index 0000000000..6ce943dc08 --- /dev/null +++ b/assets/Stride/SDSL/GenericTexcoord.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GenericTexcoord +{ + float2 coords : T; +}; diff --git a/assets/Stride/SDSL/GeometryShaderTest.sdsl b/assets/Stride/SDSL/GeometryShaderTest.sdsl new file mode 100644 index 0000000000..17f90de8ce --- /dev/null +++ b/assets/Stride/SDSL/GeometryShaderTest.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GeometryShaderTest : TestStructure +{ + void testGS0(point Input input[1], TriangleStream param){} + void testGS1(LineStream param){} + void testGS2(PointStream param){} +}; diff --git a/assets/Stride/SDSL/Global.sdsl b/assets/Stride/SDSL/Global.sdsl new file mode 100644 index 0000000000..87c3072068 --- /dev/null +++ b/assets/Stride/SDSL/Global.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Global +{ + cbuffer PerFrame { + stage float Time; + stage float TimeStep; + }; +}; diff --git a/assets/Stride/SDSL/GlobalVR.sdsl b/assets/Stride/SDSL/GlobalVR.sdsl new file mode 100644 index 0000000000..0d4e9af756 --- /dev/null +++ b/assets/Stride/SDSL/GlobalVR.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader GlobalVR +{ + cbuffer PerView.GlobalVR { + stage int EyeIndex; + stage int EyeCount; + }; +}; diff --git a/assets/Stride/SDSL/HSVUtils.sdsl b/assets/Stride/SDSL/HSVUtils.sdsl new file mode 100644 index 0000000000..70354af21d --- /dev/null +++ b/assets/Stride/SDSL/HSVUtils.sdsl @@ -0,0 +1,103 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various helper functions to convert color between RGB and HSV. +/// +shader HSVUtils +{ + float GetSaturation(float3 tex) + { + float e = 1.0e-10; + float maxChannel = max(max(tex.r, tex.g), tex.b); + if(maxChannel < e) + return 0.0f; + else + return 1.0f - min(min(tex.r, tex.g), tex.b) / maxChannel; + } + + float GetValue(float3 tex) + { + return max(max(tex.r, tex.g), tex.b); + } + + float GetHue(float3 tex) + { + float e = 1.0e-10; + float maxChannel = max(max(tex.r, tex.g), tex.b); + + float delta = maxChannel - min(min(tex.r, tex.g), tex.b); + if (delta < e) + return 0.0f; + if(maxChannel == tex.r) + { + return frac(1.0f + (tex.g - tex.b) / (6.0f * delta)); + } + else if(maxChannel == tex.g) + { + return 1.0f / 3.0f + (tex.b - tex.r) / (6.0f * delta); + } + else + { + return 2.0f / 3.0f + (tex.r - tex.g) / (6.0f * delta); + } + } + /* + float3 ToHSV(float3 tex) + { + return float3(GetHue(tex), GetSaturation(tex), GetValue(tex)); + } + + float3 ToRGB(float3 hsv) + { + + float s = hsl[1]; + float v = hsl[2]; + + if(s == 0) + return float3(v); + + float h = hsl[0]; + + int i = floor(h); + float f = h - i; + float p = v * (1.0f - s); + float q = v * (1.0f - s * f); + float t = v * (1.0f - s * (1.0f - f)); + + switch(i) + { + case 0 : + return float3(v, t, p); + case 1 : + return float3(q, v, p); + case 2 : + return float3(p, v, t); + case 3 : + return float3(p, q, v); + case 4 : + return float3(t, p, v); + default : + return float3(v, p, q); + } + } + */ + // From http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl + float3 ToHSV(float3 color) + { + float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + float4 p = lerp(float4(color.bg, K.wz), float4(color.gb, K.xy), step(color.b, color.g)); + float4 q = lerp(float4(p.xyw, color.r), float4(color.r, p.yzx), step(p.x, color.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + + float3 ToRGB(float3 color) + { + float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + float3 p = abs(frac(color.xxx + K.xyz) * 6.0 - K.www); + return color.z * lerp(K.xxx, saturate(p - K.xxx), color.y); + } + +}; diff --git a/assets/Stride/SDSL/Hammersley.sdsl b/assets/Stride/SDSL/Hammersley.sdsl new file mode 100644 index 0000000000..48c399d9f0 --- /dev/null +++ b/assets/Stride/SDSL/Hammersley.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Hammersley sampling on a Plane, Sphere, etc... + /// + shader Hammersley : Math + { + float2 GetSamplePlane(int k, int samplesCount) + { + var u = 0.0; + var p = 0.5; + for (int kk=k; kk; p*=0.5, kk>>=1) + { + if (kk & 1) // kk mod 2 == 1 + u += p; + } + + var v = (k + 0.5) / samplesCount; + + return float2(u,v); + } + }; +} diff --git a/assets/Stride/SDSL/HammersleyTest.sdsl b/assets/Stride/SDSL/HammersleyTest.sdsl new file mode 100644 index 0000000000..9338b60529 --- /dev/null +++ b/assets/Stride/SDSL/HammersleyTest.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader HammersleyTest : ComputeShaderBase +{ + stage int SamplesCount; + + RWTexture2D OutputTexture; + + // Shading of the sprite + override void Compute() + { + var xy = Hammersley.GetSamplePlane(streams.ThreadGroupIndex, SamplesCount); + + uint width, height; + OutputTexture.GetDimensions(width, height); + + OutputTexture[xy * float2(width, height)] = float4(1, 0, 0, 1); + } +}; diff --git a/assets/Stride/SDSL/HighlightShader.sdsl b/assets/Stride/SDSL/HighlightShader.sdsl new file mode 100644 index 0000000000..05e97f91d8 --- /dev/null +++ b/assets/Stride/SDSL/HighlightShader.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering +{ + // TODO GRAPHICS REFACTOR: Unify passthrough color shaders (picking, highlight, etc.) + shader HighlightShader : ShaderBase + { + cbuffer PerDraw + { + stage float4 HighlightColor; + } + + stage override void PSMain() + { + streams.ColorTarget = HighlightColor; + } + }; +} diff --git a/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl b/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl new file mode 100644 index 0000000000..f5a1431a24 --- /dev/null +++ b/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + /// + /// Base shader to sample an environment + /// + shader IComputeEnvironmentColor + { + float4 Compute(float3 direction) + { + return 0; + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl b/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl new file mode 100644 index 0000000000..f27432c8c4 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + class IMaterialCelShadingLightFunction : MaterialPixelShadingStream + { + float3 Compute(float lightIn) + { + return float3(lightIn, lightIn, lightIn); + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl b/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl new file mode 100644 index 0000000000..c953febd16 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class IMaterialHairDirectionFunction + { + abstract float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose); + }; +} diff --git a/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl b/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl new file mode 100644 index 0000000000..fc67a2eb75 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Common interface for discarding pixels for the hair shading model. + /// + class IMaterialHairDiscardFunction + { + // TODO: Can't we move the cbuffer with the HairAlphaThreshold here? + abstract void Discard(void); + }; +} diff --git a/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl b/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl new file mode 100644 index 0000000000..19f5d994f0 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class IMaterialHairLightAttenuationFunction + { + abstract float Compute(void); + }; +} diff --git a/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl b/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl new file mode 100644 index 0000000000..72b7f28abf --- /dev/null +++ b/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class IMaterialHairShadowingFunction + { + abstract float3 Compute(); + }; +} diff --git a/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl b/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl new file mode 100644 index 0000000000..a1bba7ba0a --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet IBL environment (DFG) function + /// + shader IMaterialSpecularMicrofacetEnvironmentFunction : MaterialPixelShadingStream, BRDFMicrofacet + { + float3 Compute(float3 specularColor, float alphaR, float nDotV) + { + return 0; + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl b/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl new file mode 100644 index 0000000000..80ee00b2df --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader IMaterialSpecularMicrofacetFresnelFunction : MaterialPixelShadingStream, BRDFMicrofacet + { + // TODO: We could provide f90 as well + float3 Compute(float3 f0) + { + return FresnelNone(f0); + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl b/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl new file mode 100644 index 0000000000..f035efadfa --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Normal Distribution function + /// + shader IMaterialSpecularMicrofacetNormalDistributionFunction : MaterialPixelShadingStream, BRDFMicrofacet + { + float Compute() + { + return NormalDistributionBlinnPhong(streams.alphaRoughness, streams.NdotH); + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl b/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl new file mode 100644 index 0000000000..2467ee9bbe --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader IMaterialSpecularMicrofacetVisibilityFunction : MaterialPixelShadingStream, BRDFMicrofacet + { + float Compute() + { + return VisibilityImplicit(streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialStreamBlend.sdsl b/assets/Stride/SDSL/IMaterialStreamBlend.sdsl new file mode 100644 index 0000000000..29281974b9 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialStreamBlend.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// An interface to blend a stream + /// + shader IMaterialStreamBlend : MaterialStream, MaterialVertexStream, MaterialPixelStream + { + void Compute(Streams fromStream) + { + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl b/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl new file mode 100644 index 0000000000..005ca3b78e --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class IMaterialSubsurfaceScatteringScatteringProfile + { + void Prepare(void) // Called once at the beginning of the shader. + { + } + + abstract float3 Compute(float dd); // Called once per light. + }; +} diff --git a/assets/Stride/SDSL/IMaterialSurface.sdsl b/assets/Stride/SDSL/IMaterialSurface.sdsl new file mode 100644 index 0000000000..c0cf2e91be --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSurface.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for a material layer + /// + shader IMaterialSurface : MaterialStream // TODO: provide a way to extend MaterialStream easily + { + void Compute() + { + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl b/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl new file mode 100644 index 0000000000..0aa099a035 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for a material layer (vertex stage) + /// + shader IMaterialSurfaceDomain : IMaterialSurface, MaterialDomainStream + { + }; +} diff --git a/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl b/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl new file mode 100644 index 0000000000..73c8e12f6e --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for a material layer + /// + shader IMaterialSurfacePixel : IMaterialSurface, MaterialPixelStream + { + }; +} diff --git a/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl b/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl new file mode 100644 index 0000000000..5909f82996 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for a material layer shading. + /// + shader IMaterialSurfaceShading : MaterialPixelStream, LightStream + { + void PrepareForLightingAndShading() + { + } + + float3 ComputeDirectLightContribution() + { + return 0; + } + + float3 ComputeEnvironmentLightContribution() + { + return 0; + } + + void AfterLightingAndShading() + { + } + }; +} diff --git a/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl b/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl new file mode 100644 index 0000000000..8506bb6759 --- /dev/null +++ b/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for a material layer (vertex stage) + /// + shader IMaterialSurfaceVertex : IMaterialSurface, MaterialVertexStream + { + }; +} diff --git a/assets/Stride/SDSL/IStreamInitializer.sdsl b/assets/Stride/SDSL/IStreamInitializer.sdsl new file mode 100644 index 0000000000..2c66a0d0e5 --- /dev/null +++ b/assets/Stride/SDSL/IStreamInitializer.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Base interface for initializing streams + /// + shader IStreamInitializer + { + void ResetStream() + { + } + }; +} diff --git a/assets/Stride/SDSL/IVoxelSampler.sdsl b/assets/Stride/SDSL/IVoxelSampler.sdsl new file mode 100644 index 0000000000..3861f40f16 --- /dev/null +++ b/assets/Stride/SDSL/IVoxelSampler.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader IVoxelSampler + { + float4 Sample(float3 position, float3 normal, float diameter) + { + return 0; + } + float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + return 0; + } + float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + return 0; + } + float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return float4(1, 0, 0, 0); + } + float VoxelSize() + { + return 1.0; + } + float4 Test() + { + return float4(1,0,0,1); + } + float4 ComputeLocal(float3 position) + { + return 0; + } + }; +} diff --git a/assets/Stride/SDSL/ImageEffectShader.sdsl b/assets/Stride/SDSL/ImageEffectShader.sdsl new file mode 100644 index 0000000000..14608ef8bd --- /dev/null +++ b/assets/Stride/SDSL/ImageEffectShader.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Base shader to perform post effects. Draws the input mesh without transformation. + /// + shader ImageEffectShader : SpriteBase + { + }; +} diff --git a/assets/Stride/SDSL/ImageScalerShader.sdsl b/assets/Stride/SDSL/ImageScalerShader.sdsl new file mode 100644 index 0000000000..6ba7d6c2f3 --- /dev/null +++ b/assets/Stride/SDSL/ImageScalerShader.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A copier shader + /// + internal shader ImageScalerShader : ImageEffectShader + { + // TODO: Color and IsOnlyChannelRed could be part of a color filter that we can pre-prend automatically + [Color] + stage float4 Color; + stage float IsOnlyChannelRed; + + // Shading of the sprite + stage override float4 Shading() + { + float4 color = base.Shading(); + if (IsOnlyChannelRed != 0) + { + color = float4(color.rrr, 1); + } + return color * Color; + } + }; +} diff --git a/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl b/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl new file mode 100644 index 0000000000..ac1895a3a2 --- /dev/null +++ b/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Importance sampling for the GGX function. + /// + shader ImportanceSamplingGGX : Math + { + float3 GetSample(float2 xi, float roughness, float3 N) + { + float a = roughness * roughness; + float phi = 2 * Math.PI * xi.x; + float CosTheta = sqrt( (1 - xi.y) / ( 1 + (a*a - 1) * xi.y ) ); + float SinTheta = sqrt( 1 - CosTheta * CosTheta ); + + float3 H; + H.x = SinTheta * cos( phi ); + H.y = SinTheta * sin( phi ); + H.z = CosTheta; + + float3 UpVector = abs(N.z) < 0.999 ? float3(0,0,1) : float3(1,0,0); + float3 TangentX = normalize( cross( UpVector, N ) ); + float3 TangentY = cross( N, TangentX ); + + // Tangent to world space + return TangentX * H.x + TangentY * H.y + N * H.z; + } + }; +} diff --git a/assets/Stride/SDSL/InterfaceTest.sdsl b/assets/Stride/SDSL/InterfaceTest.sdsl new file mode 100644 index 0000000000..f90b316241 --- /dev/null +++ b/assets/Stride/SDSL/InterfaceTest.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader InterfaceTest +{ + interface myInterface + { + abstract void test(); + }; +}; diff --git a/assets/Stride/SDSL/InternalReferenceMixin.sdsl b/assets/Stride/SDSL/InternalReferenceMixin.sdsl new file mode 100644 index 0000000000..c337ce8bbe --- /dev/null +++ b/assets/Stride/SDSL/InternalReferenceMixin.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader InternalReferenceMixin +{ + float myValue = 2.0f; + + float test() + { + return myValue; + } +}; diff --git a/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl b/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl new file mode 100644 index 0000000000..b51e719d9c --- /dev/null +++ b/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl @@ -0,0 +1,77 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The first pass of a shader performing Lambertian pre-filtering using Spherical Harmonics + /// + shader LambertianPrefilteringSHNoComputePass1 : SphericalHarmonicsBase, ImageEffectShader, Texturing + { + // the input texture containing the radiance + TextureCube RadianceMap; + + // Index of the spherical harmonics coefficient to compute + int CoefficientIndex; + + // The Cosine kernel factors + static const float A0 = 1.0; + static const float A1 = 2.0 / 3.0; + static const float A2 = 1.0 / 4.0; + static const float A3 = 0.0; + static const float A4 = -1.0 / 24.0; + static const float A[5 * 5] = + { + A0, + A1, A1, A1, + A2, A2, A2, A2, A2, + A3, A3, A3, A3, A3, A3, A3, + A4, A4, A4, A4, A4, A4, A4, A4, A4 + }; + + stage override float4 Shading() + { + float3 result = 0; + + float2 uv = streams.TexCoord * 2.0 - 1.0; + + // Calculate weight + float dist = 1.0f + dot(uv, uv); + float weight = 4.0f / (sqrt(dist) * dist); + + [unroll] + for (int faceIndex = 0; faceIndex < 6; faceIndex++) + { + // Extract direction from texel u, v + float3 dirVS = normalize(uvToDirectionVS(uv.x, uv.y, faceIndex)); + + // Calculates the values of the SH bases + EvaluateSHBases(dirVS); + + float3 radiance = RadianceMap.Sample(PointSampler, dirVS).xyz; + + result += A[CoefficientIndex] * streams.SHBaseValues[CoefficientIndex] * radiance * weight; + } + + return float4(result, weight * 6); + } + + float3 uvToDirectionVS(float u, float v, int viewIndex) + { + if (viewIndex == 0) + return float3(1, -v, -u); // face X + if (viewIndex == 1) + return float3(-1, -v, u); // face -X + if (viewIndex == 2) + return float3(u, 1, v); // face Y + if (viewIndex == 3) + return float3(u, -1, -v); // face -Y + if (viewIndex == 4) + return float3(u, -v, 1); // face Z + if (viewIndex == 5) + return float3(-u, -v, -1); // face -Z + + return 0; + } + }; +} diff --git a/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl b/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl new file mode 100644 index 0000000000..8961b52ef7 --- /dev/null +++ b/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The second pass of a shader performing Lambertian pre-filtering using Spherical Harmonics + /// + shader LambertianPrefilteringSHNoComputePass2 : ImageEffectShader, Texturing + { + stage override float4 Shading() + { + float4 result = 0; + + result += Texture0.Sample(PointSampler, streams.TexCoord, int2(-1, 0)); + result += Texture0.Sample(PointSampler, streams.TexCoord, int2(0, 0)); + result += Texture0.Sample(PointSampler, streams.TexCoord, int2(0, -1)); + result += Texture0.Sample(PointSampler, streams.TexCoord, int2(-1, -1)); + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl b/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl new file mode 100644 index 0000000000..290773888d --- /dev/null +++ b/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl @@ -0,0 +1,125 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The first pass of a shader performing Lambertian pre-filtering using Spherical Harmonics + /// + shader LambertianPrefilteringSHPass1 : SphericalHarmonicsBase, ComputeShaderBase, Texturing + { + // the input texture containing the radiance + TextureCube RadianceMap; + + // the output buffer containing SH coefficient partially summed. + RWBuffer OutputBuffer; + + // The Cosine kernel factors + static const float A0 = 1.0; + static const float A1 = 2.0/3.0; + static const float A2 = 1.0/4.0; + static const float A3 = 0.0; + static const float A4 = -1.0/24.0; + static const float A[5*5] = + { + A0, + A1, A1, A1, + A2, A2, A2, A2, A2, + A3, A3, A3, A3, A3, A3, A3, + A4, A4, A4, A4, A4, A4, A4, A4, A4 + }; + + // Shared memory for summing SH-Basis coefficients for a block + groupshared float4 PartialSHCoeffs[TBlockSize][TBlockSize][CoefficientsCount]; + + // Projects radiance on SH basis and sums results along rows. + override void Compute() + { + // Determine the indices of the texel to compute + const int3 location = int3(streams.GroupThreadId.xy + streams.GroupId.xy * TBlockSize, streams.GroupId.z); + + // Calculate the location in [-1, 1] texture space (center at the pixel center) + float inverseSize = 1 / float(TBlockSize * streams.ThreadGroupCount.x); + float u = ((location.x+0.5) * inverseSize) * 2.0f - 1.0f; + float v = ((location.y+0.5) * inverseSize) * 2.0f - 1.0f; + + // Extract direction from texel u,v + float3 dirVS = normalize(uvToDirectionVS(u, v, location.z)); + float3 radiance = RadianceMap.SampleLevel(Texturing.PointSampler, dirVS, 0).xyz; + + // Calculate weight + var dist = 1.0f + u * u + v * v; + var weight = 4.0f / (sqrt(dist) * dist); + radiance *= weight; + + // Calculates the values of the SH bases + EvaluateSHBases(dirVS); + + // Store the results in the shared memory + [unroll] + for(int c=0; c + /// The second pass of a shader performing Lambertian pre-filtering using Spherical Harmonics + /// + shader LambertianPrefilteringSHPass2 : SphericalHarmonicsBase, ComputeShaderBase, Texturing, Math + { + // the input buffer containing SH coefficients summed up along rows. + Buffer InputBuffer; + + // the output buffer containing the final SH coefficients. + RWBuffer OutputBuffer; + + // Shared memory for reducing SH-Basis coefficients + groupshared float4 PartialSHCoeffs[TSize]; + + // Reduce (sums) the SH coefficients along the columns + override void Compute() + { + int coeffId = streams.GroupId.z; + int threadId = streams.GroupThreadId.x; + int groupId = streams.GroupId.x + streams.ThreadGroupCount.x * streams.GroupId.y; + + // Store in shared memory + PartialSHCoeffs[threadId] = InputBuffer[coeffId + CoefficientsCount * (threadId + TSize * groupId)]; + GroupMemoryBarrierWithGroupSync(); + + // Sum the coefficients + for(int s = TSize / 2; s > 0; s >>= 1) + { + if(threadId < s) + PartialSHCoeffs[threadId] += PartialSHCoeffs[threadId + s]; + + GroupMemoryBarrierWithGroupSync(); + } + + // Have the first thread write out to the output buffer + if (IsFirstThreadOfGroup()) + { + OutputBuffer[coeffId + CoefficientsCount * groupId] = PartialSHCoeffs[0]; + } + } + }; +} diff --git a/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl b/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl new file mode 100644 index 0000000000..dbd5111753 --- /dev/null +++ b/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + /// + /// Sample a cubemap using the MaterialPixelShadingStream roughness parameter. + /// + shader LevelCubeMapEnvironmentColor : IComputeEnvironmentColor, Texturing + { + TextureCube CubeMap; + float MipLevel; + + override float4 Compute(float3 direction) + { + return CubeMap.SampleLevel(LinearSampler, direction, MipLevel); + } + }; +} diff --git a/assets/Stride/SDSL/LightClustered.sdsl b/assets/Stride/SDSL/LightClustered.sdsl new file mode 100644 index 0000000000..bed769dc8f --- /dev/null +++ b/assets/Stride/SDSL/LightClustered.sdsl @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + shader LightClustered : ScreenPositionBase, ShaderBaseStream, Camera + { + stage stream uint2 lightData; + stage stream int lightIndex; + + rgroup PerView.Lighting + { + stage Texture3D LightClusters; + stage Buffer LightIndices; + } + + cbuffer PerView.Lighting + { + stage float ClusterDepthScale; + stage float ClusterDepthBias; + stage float2 ClusterStride; + } + + void PrepareLightData() + { + float projectedDepth = streams.ShadingPosition.z; + float depth = ZProjection.y / (projectedDepth - ZProjection.x); + + float2 texCoord = float2(streams.ScreenPosition.x + 1, 1 - streams.ScreenPosition.y) * 0.5; + int slice = int(max(log2(depth * ClusterDepthScale + ClusterDepthBias), 0)); + streams.lightData = LightClusters.Load(int4(texCoord * ClusterStride, slice, 0)); + streams.lightIndex = streams.lightData.x; + } + }; +} diff --git a/assets/Stride/SDSL/LightClusteredPointGroup.sdsl b/assets/Stride/SDSL/LightClusteredPointGroup.sdsl new file mode 100644 index 0000000000..7a251ed15b --- /dev/null +++ b/assets/Stride/SDSL/LightClusteredPointGroup.sdsl @@ -0,0 +1,52 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of point lights in clustered shading. + /// + shader LightClusteredPointGroup : DirectLightGroup, LightClustered, LightPoint + { + rgroup PerView.Lighting + { + stage Buffer PointLights; + } + + override void PrepareDirectLights() + { + PrepareLightData(); + } + + override int GetMaxLightCount() + { + return streams.lightData.y & 0xFFFF; + } + + override int GetLightCount() + { + return streams.lightData.y & 0xFFFF; + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + override void PrepareDirectLightCore(int lightIndexIgnored) + { + // What we had so far was just a loop index + // Note: we have lightIndex as a parameter but we ignore it since we want to preserve it between point and spot lights + int realLightIndex = LightIndices.Load(streams.lightIndex); + streams.lightIndex++; + + // Build PointLightData + PointLightDataInternal pointLight; + float4 pointLight1 = PointLights.Load(realLightIndex * 2); + float4 pointLight2 = PointLights.Load(realLightIndex * 2 + 1); + pointLight.PositionWS = pointLight1.xyz; + pointLight.InvSquareRadius = pointLight1.w; + pointLight.Color = pointLight2.xyz; + + // Perform lighting + ProcessLight(pointLight); + } + }; +} diff --git a/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl b/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl new file mode 100644 index 0000000000..2a387ca574 --- /dev/null +++ b/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of spot lights in clustered shading. + /// + shader LightClusteredSpotGroup : + DirectLightGroup, + LightClustered, + LightSpot, // Required for "ProcessLight()". + SpotLightDataInternalShader // Required for "SpotLightDataInternal" + { + rgroup PerView.Lighting + { + stage Buffer SpotLights; + } + + override int GetMaxLightCount() + { + return streams.lightData.y >> 16; + } + + override int GetLightCount() + { + return streams.lightData.y >> 16; + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + override void PrepareDirectLightCore(int lightIndexIgnored) + { + // What we had so far was just a loop index + // Note: we have lightIndex as a parameter but we ignore it since we want to preserve it between point and spot lights + int realLightIndex = LightIndices.Load(streams.lightIndex); + streams.lightIndex++; + + // Build SpotLightData + SpotLightDataInternal spotLight; + float4 spotLight1 = SpotLights.Load(realLightIndex * 4); + float4 spotLight2 = SpotLights.Load(realLightIndex * 4 + 1); + float4 spotLight3 = SpotLights.Load(realLightIndex * 4 + 2); + float4 spotLight4 = SpotLights.Load(realLightIndex * 4 + 3); + spotLight.PositionWS = spotLight1.xyz; + spotLight.DirectionWS = spotLight2.xyz; + spotLight.AngleOffsetAndInvSquareRadius = spotLight3.xyz; + spotLight.Color = spotLight4.xyz; + + // Perform lighting + ProcessLight(spotLight); + } + }; +} diff --git a/assets/Stride/SDSL/LightConstantWhite.sdsl b/assets/Stride/SDSL/LightConstantWhite.sdsl new file mode 100644 index 0000000000..25b2ffba31 --- /dev/null +++ b/assets/Stride/SDSL/LightConstantWhite.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a white environment light + /// + shader LightConstantWhite : EnvironmentLight, LightStream + { + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + streams.envLightDiffuseColor = 1; + streams.envLightSpecularColor = 1; + } + }; +} diff --git a/assets/Stride/SDSL/LightDirectional.sdsl b/assets/Stride/SDSL/LightDirectional.sdsl new file mode 100644 index 0000000000..c404e52098 --- /dev/null +++ b/assets/Stride/SDSL/LightDirectional.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a directional light + /// + shader LightDirectional + { + struct DirectionalLightData + { + float3 DirectionWS; + [Color] + float3 Color; + }; + }; +} diff --git a/assets/Stride/SDSL/LightDirectionalGroup.sdsl b/assets/Stride/SDSL/LightDirectionalGroup.sdsl new file mode 100644 index 0000000000..36c1e6de65 --- /dev/null +++ b/assets/Stride/SDSL/LightDirectionalGroup.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of directional lights + /// + shader LightDirectionalGroup : DirectLightGroupPerView, LightDirectional + { + cbuffer PerView.Lighting + { + DirectionalLightData Lights[TMaxLightCount]; + } + + override int GetMaxLightCount() + { + return TMaxLightCount; + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + override void PrepareDirectLightCore(int lightIndex) + { + streams.lightColor = Lights[lightIndex].Color; + // TODO: Add support for disk based Directional light + streams.lightDirectionWS = -Lights[lightIndex].DirectionWS; + } + }; +} diff --git a/assets/Stride/SDSL/LightPoint.sdsl b/assets/Stride/SDSL/LightPoint.sdsl new file mode 100644 index 0000000000..96a4946e85 --- /dev/null +++ b/assets/Stride/SDSL/LightPoint.sdsl @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a point light + /// + shader LightPoint : LightUtil, LightStream, PositionStream4 + { + struct PointLightData + { + float3 PositionWS; + float InvSquareRadius; + [Color] + float3 Color; + }; + + struct PointLightDataInternal + { + float3 PositionWS; + float InvSquareRadius; + [Color] + float3 Color; + }; + + void ProcessLight(PointLightDataInternal light) + { + float3 lightVectorNorm; + float attenuation = ComputeAttenuation(light, streams.PositionWS.xyz, lightVectorNorm); + + streams.lightPositionWS = light.PositionWS; + streams.lightColor = light.Color; + streams.lightAttenuation = attenuation; + streams.lightDirectionWS = lightVectorNorm; + } + + float ComputeAttenuation(PointLightDataInternal light, float3 position, inout float3 lightVectorNorm) + { + float3 lightVector = light.PositionWS - position; + float lightVectorLength = length(lightVector); + lightVectorNorm = lightVector / lightVectorLength; + + float lightInvSquareRadius = light.InvSquareRadius; + return GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); + } + }; +} diff --git a/assets/Stride/SDSL/LightPointGroup.sdsl b/assets/Stride/SDSL/LightPointGroup.sdsl new file mode 100644 index 0000000000..27c2e20a16 --- /dev/null +++ b/assets/Stride/SDSL/LightPointGroup.sdsl @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of point lights + /// + shader LightPointGroup : DirectLightGroupPerDraw, LightPoint + { + cbuffer PerDraw.Lighting + { + PointLightData Lights[TMaxLightCount]; + } + + override int GetMaxLightCount() + { + return TMaxLightCount; + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + override void PrepareDirectLightCore(int lightIndex) + { + // TODO: Workaraound for SPIR-V compiler. Revert later + PointLightDataInternal data; + data.PositionWS = Lights[lightIndex].PositionWS; + data.InvSquareRadius = Lights[lightIndex].InvSquareRadius; + data.Color = Lights[lightIndex].Color; + + ProcessLight(data); + } + + override float ComputeAttenuation(float3 position, int lightIndex) + { + // TODO: Workaraound for SPIR-V compiler. Revert later + PointLightDataInternal data; + data.PositionWS = Lights[lightIndex].PositionWS; + data.InvSquareRadius = Lights[lightIndex].InvSquareRadius; + + float3 lightVectorNorm; + return ComputeAttenuation(data, position, lightVectorNorm); + } + }; +} diff --git a/assets/Stride/SDSL/LightProbeShader.sdsl b/assets/Stride/SDSL/LightProbeShader.sdsl new file mode 100644 index 0000000000..487c3da1db --- /dev/null +++ b/assets/Stride/SDSL/LightProbeShader.sdsl @@ -0,0 +1,99 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.LightProbes +{ + /// + /// Defines a skybox environment light + /// + shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils + { + cbuffer PerView.LightProbes + { + stage int IgnoredProbeStart; + } + rgroup PerView.LightProbes + { +#ifdef STRIDE_MULTISAMPLE_COUNT + #if STRIDE_MULTISAMPLE_COUNT > 1 + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #else + stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID + #endif +#else + stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID +#endif + stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs + stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix + stage Buffer LightProbeCoefficients; // probe ID => SH coefficients + } + + void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) + { + // Early exit + if (weight == 0.0f) + return; + + int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; + for (int i = 0; i < TOrder * TOrder; ++i) + { + // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly + sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; + } + } + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + var ambientAccessibility = streams.matAmbientOcclusion; + + var sampleDirection = streams.normalWS; + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + var shadingPosition = int3(streams.ShadingPosition.xy, 0); +#if STRIDE_MULTISAMPLE_COUNT == 1 + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); +#else + // TODO: Use SV_SampleIndex + uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); +#endif + + uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); + float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), + LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); + + float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); + + // Protect ourselves against degenerate cases + // TODO: Investigate why those happen (almost coplanar tetrahedron?) + tetrahedronFactors3 = saturate(tetrahedronFactors3); + + float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); + + // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) + tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); + + // Renormalize barycentric coordinates + var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; + if (totalSum > 0.0f) + tetrahedronFactors4 /= totalSum; + + float3 sphericalColors[TOrder * TOrder]; + for (int i = 0; i < TOrder * TOrder; ++i) + sphericalColors[i] = 0.0f; + + FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); + FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); + FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); + FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); + + streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + // TEST: + //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + //streams.envLightDiffuseColor = tetrahedronFactors3; + //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/LightShaftsShader.sdsl b/assets/Stride/SDSL/LightShaftsShader.sdsl new file mode 100644 index 0000000000..807010740c --- /dev/null +++ b/assets/Stride/SDSL/LightShaftsShader.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + shader LightShaftsShader : ImageEffectShader, PostEffectBoundingRay, LightStream, NormalStream + { + stage compose DirectLightGroup lightGroup; + + cbuffer PerFrame + { + stage float DensityFactor; + }; + + override float3 ComputeColorIn(float4 positionWS, float stepSize, int stepIndex) + { + // Most shadow groups use these for normal scaled bias + ResetLightStream(); + streams.NdotL = 1; + streams.normalWS = float3(0,1,0); + // Needed by thickness computation (TODO: need a way to disable ComputeTransmittance when computing light shafts) + streams.meshNormalWS = 0.0f; + streams.PositionWS = 0.0f; + + float atten = lightGroup.ComputeAttenuation(positionWS.xyz, 0); + float3 shadowColor = lightGroup.ComputeShadow(positionWS.xyz, 0); + + // Right now this doesn't support multi-colored shadows, since this shader only calculates the light shaft intensity, which is later multiplied by the light color + // So take the max here + float shadow = max(max(shadowColor.x, shadowColor.y), shadowColor.z); + + return DensityFactor * stepSize * shadow * atten; + } + }; +} diff --git a/assets/Stride/SDSL/LightSimpleAmbient.sdsl b/assets/Stride/SDSL/LightSimpleAmbient.sdsl new file mode 100644 index 0000000000..67308901cc --- /dev/null +++ b/assets/Stride/SDSL/LightSimpleAmbient.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a simple environment light + /// + shader LightSimpleAmbient : EnvironmentLight, MaterialPixelShadingStream + { + cbuffer PerView.Lighting + { + [Color] + float3 AmbientLight; + } + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + float3 lightColor = AmbientLight * streams.matAmbientOcclusion; + streams.envLightDiffuseColor = lightColor; + streams.envLightSpecularColor = lightColor; + } + }; +} diff --git a/assets/Stride/SDSL/LightSkyboxShader.sdsl b/assets/Stride/SDSL/LightSkyboxShader.sdsl new file mode 100644 index 0000000000..e7cc2d7317 --- /dev/null +++ b/assets/Stride/SDSL/LightSkyboxShader.sdsl @@ -0,0 +1,49 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a skybox environment light + /// + shader LightSkyboxShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation + { + cbuffer PerView.Lighting + { + float4x4 SkyMatrix; + float Intensity; + } + + compose IComputeEnvironmentColor lightDiffuseColor; + + compose IComputeEnvironmentColor lightSpecularColor; + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + + var ambientAccessibility = streams.matAmbientOcclusion; + + // ----------------------------------------- + // Diffuse lighting + // ----------------------------------------- + // TODO: This could be optimized by having a flag to allow rotation only if necessary + // Rotate the skybox + var sampleDirection = mul(streams.normalWS, (float3x3)SkyMatrix); + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + streams.envLightDiffuseColor = lightDiffuseColor.Compute(sampleDirection).rgb * Intensity * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; + + // ----------------------------------------- + // Specular lighting + // ----------------------------------------- + // TODO: This could be optimized by having a flag to allow rotation only if necessary + // Rotate the skybox + // TODO: Sample into "Importance Sampling" direction instead of the "reflect" direction + sampleDirection = reflect( -streams.viewWS, streams.normalWS ); + sampleDirection = mul(sampleDirection, (float3x3)SkyMatrix); + sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); + + streams.envLightSpecularColor = lightSpecularColor.Compute(sampleDirection).rgb * Intensity * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; + } + }; +} diff --git a/assets/Stride/SDSL/LightSpot.sdsl b/assets/Stride/SDSL/LightSpot.sdsl new file mode 100644 index 0000000000..cda55290f4 --- /dev/null +++ b/assets/Stride/SDSL/LightSpot.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a spot light + /// + shader LightSpot : + LightStream, // Required for "streams.lightColor" and "streams.lightDirectionWS". + PositionStream4, // Required for "streams.PositionWS". + SpotLightDataInternalShader, // Required for "SpotLightDataInternal" + LightSpotAttenuationDefault // Required for "ComputeAttenuation()" + { + struct SpotLightData + { + float3 PositionWS; + float3 DirectionWS; + float3 AngleOffsetAndInvSquareRadius; + [Color] + float3 Color; + }; + + void ProcessLight(SpotLightDataInternal light) + { + float3 lightVectorNorm; + //float attenuation = ComputeAttenuation(light, streams.PositionWS.xyz, lightVectorNorm); + float attenuation = ComputeAttenuation(light.PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. + light.AngleOffsetAndInvSquareRadius, + light.DirectionWS, + streams.PositionWS.xyz, lightVectorNorm); + + streams.lightColor = light.Color; + streams.lightAttenuation = attenuation; + streams.lightDirectionWS = lightVectorNorm; + } + }; +} diff --git a/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl b/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl new file mode 100644 index 0000000000..1c2967c6ae --- /dev/null +++ b/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Code for attenuating a group of spotlights using angular attenuation. + /// + shader LightSpotAttenuationDefault : + //SpotLightDataInternalShader, // Required for "SpotLightDataInternal" // TODO: Revert this line as soon as the shader compiler is fixed. + LightUtil // Required for "GetDistanceAttenuation()" and "GetAngularAttenuation()". + { + //override float ComputeAttenuation(SpotLightDataInternal light, float3 position, inout float3 lightVectorNorm) + float ComputeAttenuation(float3 PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. + float3 AngleOffsetAndInvSquareRadius, + float3 DirectionWS, + float3 position, + inout float3 lightVectorNorm) // This overload is a temporary fix for a compiler error rendering us unable to override "ComputeAttenution()". + { + // TODO: There's duplicate code here. See "LightSpotAttenuationRectangular". + + //float3 lightVector = light.PositionWS - position; + float3 lightVector = PositionWS - position; // TODO: Revert to the above line as soon as the shader compiler is fixed. + float lightVectorLength = length(lightVector); + lightVectorNorm = lightVector / lightVectorLength; + + //float3 lightAngleOffsetAndInvSquareRadius = light.AngleOffsetAndInvSquareRadius; + float3 lightAngleOffsetAndInvSquareRadius = AngleOffsetAndInvSquareRadius; // TODO: Revert to the above line as soon as the shader compiler is fixed. + float2 lightAngleAndOffset = lightAngleOffsetAndInvSquareRadius.xy; + float lightInvSquareRadius = lightAngleOffsetAndInvSquareRadius.z; + + // TODO: Add support for disk based Directional light + //float3 lightDirection = -light.DirectionWS; + float3 lightDirection = -DirectionWS; // TODO: Revert to the above line as soon as the shader compiler is fixed. + + float attenuation = GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); + attenuation *= GetAngularAttenuation(lightVectorNorm, lightDirection, lightAngleAndOffset.x, lightAngleAndOffset.y); + return attenuation; + } + }; +} diff --git a/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl b/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl new file mode 100644 index 0000000000..35a1c0ca5d --- /dev/null +++ b/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a function for attenuating a spot light. + /// Overrides the default implementation and replaces it + /// with a rectangular attenuation (hard cut off at spotlight + /// frustum edges) for use with textured spotlights. + /// + shader LightSpotAttenuationRectangular : + LightSpotAttenuationDefault // Defines the function "ComputeAttenuation()" that we are overriding here. + { + //override float ComputeAttenuation(SpotLightDataInternal light, float3 position, inout float3 lightVectorNorm) + override float ComputeAttenuation(float3 PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. + float3 AngleOffsetAndInvSquareRadius, + float3 DirectionWS, + float3 position, + inout float3 lightVectorNorm) // This overload is a temporary fix for a compiler error rendering us unable to override "ComputeAttenution()". + { + // TODO: There's duplicate code here. See "LightSpotAttenuationDefault". + + //float3 lightVector = light.PositionWS - position; + float3 lightVector = PositionWS - position; // TODO: Revert to the above line as soon as the shader compiler is fixed. + float lightVectorLength = length(lightVector); + lightVectorNorm = lightVector / lightVectorLength; + + //float3 lightAngleOffsetAndInvSquareRadius = light.AngleOffsetAndInvSquareRadius; + float3 lightAngleOffsetAndInvSquareRadius = AngleOffsetAndInvSquareRadius; // TODO: Revert to the above line as soon as the shader compiler is fixed. + float2 lightAngleAndOffset = lightAngleOffsetAndInvSquareRadius.xy; + float lightInvSquareRadius = lightAngleOffsetAndInvSquareRadius.z; + + // TODO: Add support for disk based Directional light + //float3 lightDirection = -light.DirectionWS; + float3 lightDirection = -DirectionWS; // TODO: Revert to the above line as soon as the shader compiler is fixed. + + return GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); + } + }; +} diff --git a/assets/Stride/SDSL/LightSpotGroup.sdsl b/assets/Stride/SDSL/LightSpotGroup.sdsl new file mode 100644 index 0000000000..fabe1d16ee --- /dev/null +++ b/assets/Stride/SDSL/LightSpotGroup.sdsl @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a group of spot lights + /// + shader LightSpotGroup : + DirectLightGroupPerDraw, // Required for "PrepareDirectLightCore()", "PrepareDirectLight()", "ComputeAttenuation()" and other stuff. + LightSpot, // Required for "SpotLightData". + LightSpotAttenuationDefault // Required for "ComputeAttenuation()" + { + cbuffer PerDraw.Lighting + { + SpotLightData Lights[TMaxLightCount]; + } + + override int GetMaxLightCount() + { + return TMaxLightCount; + } + + /// + /// Compute the light color/direction for the specified index within this group + /// + override void PrepareDirectLightCore(int lightIndex) + { + // TODO: Workaraound for SPIR-V compiler. Revert later + SpotLightDataInternal data; + data.PositionWS = Lights[lightIndex].PositionWS; + data.DirectionWS = Lights[lightIndex].DirectionWS; + data.AngleOffsetAndInvSquareRadius = Lights[lightIndex].AngleOffsetAndInvSquareRadius; + data.Color = Lights[lightIndex].Color; + + ProcessLight(data); + } + + override float ComputeAttenuation(float3 position, int lightIndex) + { + // TODO: Workaraound for SPIR-V compiler. Revert later + SpotLightDataInternal data; + data.PositionWS = Lights[lightIndex].PositionWS; + data.DirectionWS = Lights[lightIndex].DirectionWS; + data.AngleOffsetAndInvSquareRadius = Lights[lightIndex].AngleOffsetAndInvSquareRadius; + + float3 lightVectorNorm; + //return ComputeAttenuation(data, position, lightVectorNorm); + return ComputeAttenuation(data.PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. + data.AngleOffsetAndInvSquareRadius, + data.DirectionWS, + position, lightVectorNorm); + } + }; +} diff --git a/assets/Stride/SDSL/LightStreakShader.sdsl b/assets/Stride/SDSL/LightStreakShader.sdsl new file mode 100644 index 0000000000..aa975db334 --- /dev/null +++ b/assets/Stride/SDSL/LightStreakShader.sdsl @@ -0,0 +1,62 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// LightStreak shader. This extends colors along a direction, while applying an attenuation + /// factor along the way. + /// + internal shader LightStreakShader : ImageEffectShader + { + // Offset of the taps and their own weights + stage float2 TapOffsetsWeights[TapCount]; + + // Direction of the tap line + stage float2 Direction; + + // Light aberration coefficients along the streak + stage float3 ColorAberrationCoefficients; + + // Count of anamorphic sub-streaks with offsets and strength (including the main streak) + stage float3 AnamorphicOffsetsWeight[AnamorphicCount]; + + stage override float4 Shading() + { + // Direction in texel size + float2 direction = Direction * Texture0TexelSize; + float3 color = float3(0.0, 0.0, 0.0); + + [unroll] + for (int anamorphic = 0; anamorphic < AnamorphicCount; anamorphic++) { // All the anamorphic + + float2 textOffset = AnamorphicOffsetsWeight[anamorphic].xy * Texture0TexelSize; + + [unroll] + for(int i = 0; i < TapCount; i++) + { + float2 tapUV = streams.TexCoord + direction * TapOffsetsWeights[i].x + textOffset; + + float3 tapColor = Texture0.Sample(LinearSampler, tapUV).rgb; + + // TODO switch to vignetting-like lerp for nicer effect, + // or directly clamp to border instead + if (tapUV.x < 0 || tapUV.x > 1 || tapUV.y < 0 || tapUV.y > 1) { + tapColor = float3(0.0, 0.0, 0.0); + } + + // Some trick to apply chromatic aberration + if (i == 0) tapColor.r *= ColorAberrationCoefficients.r; + else if (i == 1) tapColor.g *= ColorAberrationCoefficients.g; + else if (i == 2) tapColor.b *= ColorAberrationCoefficients.b; + + tapColor *= AnamorphicOffsetsWeight[anamorphic].z; + + color += tapColor * TapOffsetsWeights[i].y; + } + } + + return float4(color, 1); + } + }; +} diff --git a/assets/Stride/SDSL/LightStream.sdsl b/assets/Stride/SDSL/LightStream.sdsl new file mode 100644 index 0000000000..a083bf9d2b --- /dev/null +++ b/assets/Stride/SDSL/LightStream.sdsl @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines light streams variable. + /// + shader LightStream + { + stage stream float3 lightPositionWS; + stage stream float3 lightDirectionWS; + stage stream float3 lightColor; + stage stream float3 lightColorNdotL; + stage stream float3 lightSpecularColorNdotL; + stage stream float lightAttenuation; + stage stream float3 envLightDiffuseColor; + stage stream float3 envLightSpecularColor; + + // normal dot light + stage stream float NdotL; + + stage stream float lightDirectAmbientOcclusion; + + void ResetLightStream() + { + streams.lightPositionWS = 0; + streams.lightDirectionWS = 0; + streams.lightColor = 0; + streams.lightColorNdotL = 0; + streams.lightSpecularColorNdotL = 0; + streams.lightAttenuation = 1.0f; + streams.envLightDiffuseColor = 0; + streams.envLightSpecularColor = 0; + streams.lightDirectAmbientOcclusion = 1.0f; + streams.NdotL = 0; + } + }; +} diff --git a/assets/Stride/SDSL/LightTiling.sdsl b/assets/Stride/SDSL/LightTiling.sdsl new file mode 100644 index 0000000000..aea96478c5 --- /dev/null +++ b/assets/Stride/SDSL/LightTiling.sdsl @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Lights +{ + shader LightTiling : ComputeShaderBase + { + struct PointLight + { + float3 Position; + float Radius; + }; + + + + // All point lights + int PointLightCount; + Buffer PointLights; + + // Light indices in this tile + RWBuffer FilteredLightIndicesBuffer; + + groupshared float4 FrustumPlanes[4]; + + groupshared uint FilteredLightIndicesCount; + groupshared uint FilteredLightIndices[1024]; + + override void Compute() + { + // Initialize variables and build frustum + if (ThreadGroupIndex == 0) + { + FilteredLightIndicesCount = 0; + //FrustumPlanes[0] = + } + + GroupMemoryBarrierWithGroupSync(); + + // Loop over lights + for (uint i = ThreadGroupIndex; i < PointLightCount; i += ThreadCountPerGroup) + { + PointLight pointLight = PointLights[i]; + + // Check our point against frustum planes + //if (dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) + // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) + // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) + // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f)) + { + uint lightIndex; + InterlockedAdd(FilteredLightIndicesCount, 1, lightIndex); + FilteredLightIndices[lightIndex] = i; + } + } + + GroupMemoryBarrierWithGroupSync(); + + // Copy results to buffer + for (uint i = ThreadGroupIndex; i < FilteredLightIndicesCount; i += ThreadCountPerGroup) + { + FilteredLightIndicesBuffer[i] = FilteredLightIndices[i]; + } + + // Put sentinel value to mark last point light + if (ThreadGroupIndex == 0) + { + FilteredLightIndicesBuffer[FilteredLightIndicesCount] = -1; + } + } + }; +} diff --git a/assets/Stride/SDSL/LightUtil.sdsl b/assets/Stride/SDSL/LightUtil.sdsl new file mode 100644 index 0000000000..6f94a098a5 --- /dev/null +++ b/assets/Stride/SDSL/LightUtil.sdsl @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Lights +{ + /// + /// Defines common function for direct lights + /// + shader LightUtil + { + // Code from "Moving Frostbite to Physically Based Rendering" Rousiers, Charles De Lagarde, Sébastien p32 + float SmoothDistanceAttenuation(float squaredDistance, float lightInvSquareRadius) + { + float factor = squaredDistance * lightInvSquareRadius; + float smoothFactor = saturate(1.0f - factor * factor); + return smoothFactor * smoothFactor; + } + + float GetDistanceAttenuation(float lightVectorLength, float lightInvSquareRadius) + { + float d2 = lightVectorLength * lightVectorLength; + float attenuation = 1.0 / (max(d2 , 0.01 * 0.01)); + attenuation *= SmoothDistanceAttenuation(d2, lightInvSquareRadius); + return attenuation; + } + + float GetAngularAttenuation(float3 lightVector, float3 lightDirection, float lightAngleScale, float lightAngleOffset) + { + // On the CPU + // float lightAngleScale = 1.0f / max (0.001f, (cosInner - cosOuter)); + // float lightAngleOffset = -cosOuter * angleScale; + float cd = dot(lightDirection, lightVector); + float attenuation = saturate(cd * lightAngleScale + lightAngleOffset); + // smooth the transition + attenuation *= attenuation; + return attenuation; + } + }; +} diff --git a/assets/Stride/SDSL/LightVoxelEffect.sdsl b/assets/Stride/SDSL/LightVoxelEffect.sdsl new file mode 100644 index 0000000000..8009fe7e49 --- /dev/null +++ b/assets/Stride/SDSL/LightVoxelEffect.sdsl @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; +using Stride.Rendering.Lights; + +namespace Stride.Rendering.Voxels.VoxelGI +{ + /// + /// Base effect + /// + effect LightVoxelEffect + { + using params LightVoxelShaderKeys; + using params MarchAttributesKeys; + + mixin LightVoxelShader; + + if (LightVoxelShaderKeys.diffuseMarcher != null) + { + mixin compose diffuseMarcher = LightVoxelShaderKeys.diffuseMarcher; + } + if (LightVoxelShaderKeys.specularMarcher != null) + { + mixin compose specularMarcher = LightVoxelShaderKeys.specularMarcher; + } + if (MarchAttributesKeys.AttributeSamplers!=null) + { + foreach (var attr in MarchAttributesKeys.AttributeSamplers) + { + mixin compose AttributeSamplers += (attr); + } + } + }; +} diff --git a/assets/Stride/SDSL/LightVoxelShader.sdsl b/assets/Stride/SDSL/LightVoxelShader.sdsl new file mode 100644 index 0000000000..0d679a9ece --- /dev/null +++ b/assets/Stride/SDSL/LightVoxelShader.sdsl @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Lights; +namespace Stride.Rendering.Voxels.VoxelGI +{ + /// + /// Defines a Voxel environment light + /// + shader LightVoxelShader : MarchAttributes, Camera, Texturing, EnvironmentLight, MaterialPixelShadingStream, NormalStream, PositionStream4, Transformation + { + cbuffer PerView.Lighting + { + float Intensity; + float SpecularIntensity; + } + + compose VoxelMarchSet diffuseMarcher; + compose VoxelRadiusMarchMethod specularMarcher; + + override void PrepareEnvironmentLight() + { + base.PrepareEnvironmentLight(); + if (Intensity > 0.0) + { + float3 worldPos = streams.PositionWS; + + float3 tan = normalize(cross(streams.normalWS.xyz, normalize(float3(1, 1, 1)))); + float3 bitan = cross(tan, streams.normalWS.xyz); + float3x3 tangentMatrix = float3x3(tan, bitan, streams.normalWS.xyz); + + float4 reflLighting = float4(0, 0, 0, 0); + + float3 startPos = worldPos + streams.normalWS.xyz * specularMarcher.StepSizeRadius(1.0); + + reflLighting = diffuseMarcher.March(worldPos, streams.normalWS.xyz); + + streams.envLightDiffuseColor = reflLighting.rgb * Intensity; + if (SpecularIntensity > 0.0) + streams.envLightSpecularColor = specularMarcher.MarchRadius(startPos, reflect(-streams.viewWS, streams.normalWS), sqrt(streams.alphaRoughness)).rgb * SpecularIntensity; + else + streams.envLightSpecularColor = float4(0,0,0,0); + } + } + }; +} diff --git a/assets/Stride/SDSL/LocalSamples.sdsl b/assets/Stride/SDSL/LocalSamples.sdsl new file mode 100644 index 0000000000..8805eafa54 --- /dev/null +++ b/assets/Stride/SDSL/LocalSamples.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader LocalSamples +{ + stage stream float4 LocalSample[10]; +}; diff --git a/assets/Stride/SDSL/LuminanceLogShader.sdsl b/assets/Stride/SDSL/LuminanceLogShader.sdsl new file mode 100644 index 0000000000..d784fcf92c --- /dev/null +++ b/assets/Stride/SDSL/LuminanceLogShader.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A log luminance shader (by default using luma/Perceptive luminance Y'601) + /// + shader LuminanceLogShader : ImageEffectShader + { + float GetLuminance(float3 color) + { + return LuminanceUtils.Luma(color); + } + + stage override float4 Shading() + { + float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; + + // TODO: Make the Luma configurable from the LuminanceLogEffect + // Make sure that we don't go beyond max half float (65504), so we cap values here + var lum = max(0.001, GetLuminance(color)); + return float4(log2(lum), 1.0, 1.0, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/LuminanceToChannelShader.sdsl b/assets/Stride/SDSL/LuminanceToChannelShader.sdsl new file mode 100644 index 0000000000..3d21f705e8 --- /dev/null +++ b/assets/Stride/SDSL/LuminanceToChannelShader.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A color transform for to output the luminance to the specified channel. + /// + internal shader LuminanceToChannelShader : ColorTransformShader + { + override float4 Compute(float4 color) + { + float4 outColor = color; + outColor.TChannel = LuminanceUtils.Luma(color.rgb); + return outColor; + } + }; +} diff --git a/assets/Stride/SDSL/LuminanceUtils.sdsl b/assets/Stride/SDSL/LuminanceUtils.sdsl new file mode 100644 index 0000000000..93031ca3c2 --- /dev/null +++ b/assets/Stride/SDSL/LuminanceUtils.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A utility shader for luminance. + /// + shader LuminanceUtils + { + /// + /// Calculate the perceptive luminance (601Y') + /// + /// + /// http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness + /// http://www.poynton.com/PDFs/YUV_and_luminance_harmful.pdf + /// + static float Luma(float3 color) + { + return max(dot(color, float3(0.299, 0.587, 0.114)), 0.0001); + } + }; +} diff --git a/assets/Stride/SDSL/MSAADepthResolverShader.sdsl b/assets/Stride/SDSL/MSAADepthResolverShader.sdsl new file mode 100644 index 0000000000..37a908d74c --- /dev/null +++ b/assets/Stride/SDSL/MSAADepthResolverShader.sdsl @@ -0,0 +1,63 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Compositing +{ + /// + /// A MSAA depth textures resolver shader + /// + internal shader MSAADepthResolverShader : ShaderBase, Texturing, Math + { + stage stream float4 Position : POSITION; + + stage float4 SvPosUnpack; + stage float2 TextureSizeLess1; + +#ifndef INPUT_MSAA_SAMPLES + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 1 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 2 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 4 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 8 + stage Texture2DMS InputTexture; +#else + #error "Unsupported amount of MSAA texture samples." +#endif + + // 1:-1 to 0:TextureSize + int2 ClipPosToUvPos(float2 clipPos) + { + return (int2)(clipPos * SvPosUnpack.xy + SvPosUnpack.zw); + } + + stage override void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + override stage void PSMain() + { + float4 output = 0; + int2 pixelPos = ClipPosToUvPos(streams.Position.xy); + + float resolvedDepth = InputTexture.Load(pixelPos, 0).r; + +#ifdef INPUT_MSAA_SAMPLES + + // Get the closest depth value + [unroll] + for (int sampleIndex = 1; sampleIndex < INPUT_MSAA_SAMPLES; sampleIndex++) + { + float sampleDepth = InputTexture.Load(pixelPos, sampleIndex).r; + resolvedDepth = min(resolvedDepth, sampleDepth); + } + +#endif + + streams.Depth = resolvedDepth; + } + }; +} diff --git a/assets/Stride/SDSL/MSAAResolverShader.sdsl b/assets/Stride/SDSL/MSAAResolverShader.sdsl new file mode 100644 index 0000000000..840bac1487 --- /dev/null +++ b/assets/Stride/SDSL/MSAAResolverShader.sdsl @@ -0,0 +1,224 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Compositing +{ + /// + /// A MSAA textures resolver shader + /// + internal shader MSAAResolverShader : ImageEffectShader, Math + { + // Reference: https://github.com/TheRealMJP/MSAAFilter + + stage float4 SvPosUnpack; + stage float2 TextureSizeLess1; +#ifndef INPUT_MSAA_SAMPLES + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 1 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 2 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 4 + stage Texture2DMS InputTexture; +#elif INPUT_MSAA_SAMPLES == 8 + stage Texture2DMS InputTexture; +#else + #error "Unsupported amount of MSAA texture samples." +#endif + + // Supported filter types (note: this must match C# source) + static const int FilterTypes_Box = 1; + static const int FilterTypes_Triangle = 2; + static const int FilterTypes_Gaussian = 3; + static const int FilterTypes_BlackmanHarris = 4; + static const int FilterTypes_Smoothstep = 5; + static const int FilterTypes_BSpline = 6; + static const int FilterTypes_CatmullRom = 7; + static const int FilterTypes_Mitchell = 8; + static const int FilterTypes_Sinc = 9; + + // These are the sub-sample locations for the 2x, 4x, and 8x standard multisample patterns. + // See the MSDN documentation for the D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS enumeration. + static const float2 SubSampleOffsets8[8] = { + float2( 0.0625f, -0.1875f), + float2(-0.0625f, 0.1875f), + float2( 0.3125f, 0.0625f), + float2(-0.1875f, -0.3125f), + float2(-0.3125f, 0.3125f), + float2(-0.4375f, -0.0625f), + float2( 0.1875f, 0.4375f), + float2( 0.4375f, -0.4375f), + }; + static const float2 SubSampleOffsets4[4] = { + float2(-0.125f, -0.375f), + float2( 0.375f, -0.125f), + float2(-0.375f, 0.125f), + float2( 0.125f, 0.375f), + }; + static const float2 SubSampleOffsets2[2] = { + float2( 0.25f, 0.25f), + float2(-0.25f, -0.25f), + }; + static const float2 SubSampleOffsets1[1] = { + float2(0.0f, 0.0f), + }; + + // All filtering functions assume that 'x' is normalized to [0, 1], where 1 == FilteRadius + + float FilterBox(in float x) + { + return x <= 1.0f; + } + + static float FilterTriangle(in float x) + { + return saturate(1.0f - x); + } + + static float FilterGaussian(in float x) + { + static const float sigma = 0.5f; + static const float g = 1.0f / sqrt(2.0f * 3.14159f * sigma * sigma); + return (g * exp(-(x * x) / (2 * sigma * sigma))); + } + + float FilterCubic(in float x, in float B, in float C) + { + float y = 0.0f; + float x2 = x * x; + float x3 = x * x * x; + if(x < 1) + y = (12 - 9 * B - 6 * C) * x3 + (-18 + 12 * B + 6 * C) * x2 + (6 - 2 * B); + else if (x <= 2) + y = (-B - 6 * C) * x3 + (6 * B + 30 * C) * x2 + (-12 * B - 48 * C) * x + (8 * B + 24 * C); + + return y / 6.0f; + } + + float FilterSinc(in float x) + { + float s; + + x *= ResolveFilterDiameter; + + if(x < 0.001f) + s = 1.0f; + else + s = sin(x * PI) / (x * PI); + + return s; + } + + float FilterBlackmanHarris(in float x) + { + x = 1.0f - x; + + static const float a0 = 0.35875f; + static const float a1 = 0.48829f; + static const float a2 = 0.14128f; + static const float a3 = 0.01168f; + return saturate(a0 - a1 * cos(PI * x) + a2 * cos(2 * PI * x) - a3 * cos(3 * PI * x)); + } + + float FilterSmoothstep(in float x) + { + return 1.0f - smoothstep(0.0f, 1.0f, x); + } + + float Filter(in float x) + { + // Cubic filters naturually work in a [-2, 2] domain. For the resolve case we + // want to rescale the filter so that it works in [-1, 1] instead + float cubicX = x * 2.0f; + + if(ResolveFilterType == FilterTypes_Box) + return FilterBox(x); + else if(ResolveFilterType == FilterTypes_Triangle) + return FilterTriangle(x); + else if(ResolveFilterType == FilterTypes_Gaussian) + return FilterGaussian(x); + else if(ResolveFilterType == FilterTypes_BlackmanHarris) + return FilterBlackmanHarris(x); + else if(ResolveFilterType == FilterTypes_Smoothstep) + return FilterSmoothstep(x); + else if(ResolveFilterType == FilterTypes_BSpline) + return FilterCubic(cubicX, 1.0, 0.0f); + else if(ResolveFilterType == FilterTypes_CatmullRom) + return FilterCubic(cubicX, 0, 0.5f); + else if(ResolveFilterType == FilterTypes_Mitchell) + return FilterCubic(cubicX, 1 / 3.0f, 1 / 3.0f); + else if(ResolveFilterType == FilterTypes_Sinc) + return FilterSinc(x); + else + return 1.0f; + } + + // 1:-1 to 0:TextureSize + int2 ClipPosToUvPos(float2 clipPos) + { + return (int2)(clipPos * SvPosUnpack.xy + SvPosUnpack.zw); + } + + override stage float4 Shading() + { + float4 output = 0; + int2 pixelPos = ClipPosToUvPos(streams.Position.xy); + + // Special case for single sample resolving + if(MSAASamples == 1) + { + output = InputTexture.Load(pixelPos, 0); + } + else + { + float4 sum = 0.0f; + float totalWeight = 0.0f; + + static const int SampleRadius = (int)((ResolveFilterDiameter / 2.0f) + 0.499f); + + for(int y = -SampleRadius; y <= SampleRadius; y++) + { + for(int x = -SampleRadius; x <= SampleRadius; x++) + { + float2 sampleOffset = float2(x, y); + float2 samplePos = pixelPos + sampleOffset; + samplePos = clamp(samplePos, 0, TextureSizeLess1); + + [unroll] + for(uint subSampleIdx = 0; subSampleIdx < MSAASamples; subSampleIdx++) + { + float2 subSampleOffset; + if(MSAASamples == 8) + subSampleOffset = SubSampleOffsets8[subSampleIdx].xy; + else if(MSAASamples == 4) + subSampleOffset = SubSampleOffsets4[subSampleIdx].xy; + else if(MSAASamples == 2) + subSampleOffset = SubSampleOffsets2[subSampleIdx].xy; + else + subSampleOffset = SubSampleOffsets1[subSampleIdx].xy; + float2 sampleDist = abs(sampleOffset + subSampleOffset) / (ResolveFilterDiameter / 2.0f); + + bool useSample = all(sampleDist <= 1.0f); + if(useSample) + { + float4 sampleValue = InputTexture.Load(samplePos, subSampleIdx); + float weight = Filter(sampleDist.x) * Filter(sampleDist.y); + float sampleLum = LuminanceUtils.Luma(sampleValue.rgb); + + // Use inverse luminance filtering (better quality on highlights) + weight *= 1.0f / (1.0f + sampleLum); + + sum += sampleValue * weight; + totalWeight += weight; + } + } + } + } + + output = sum / max(totalWeight, 0.00001f); + } + + return output; + } + }; +} diff --git a/assets/Stride/SDSL/MacroTest.sdsl b/assets/Stride/SDSL/MacroTest.sdsl new file mode 100644 index 0000000000..c23fcc2b58 --- /dev/null +++ b/assets/Stride/SDSL/MacroTest.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +#ifndef MACRO_TEST +# define MACRO_TEST float +#endif +shader MacroTest +{ + MACRO_TEST u; +}; diff --git a/assets/Stride/SDSL/MacroTestBase.sdsl b/assets/Stride/SDSL/MacroTestBase.sdsl new file mode 100644 index 0000000000..b8a411cac5 --- /dev/null +++ b/assets/Stride/SDSL/MacroTestBase.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MacroTestBase +{ + float4 GetValue() + { + return float4(0,0,0,0); + } +}; diff --git a/assets/Stride/SDSL/MacroTestChild.sdsl b/assets/Stride/SDSL/MacroTestChild.sdsl new file mode 100644 index 0000000000..1bf53ae07d --- /dev/null +++ b/assets/Stride/SDSL/MacroTestChild.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MacroTestChild : MacroTest +{ + +}; diff --git a/assets/Stride/SDSL/MarchAttributes.sdsl b/assets/Stride/SDSL/MarchAttributes.sdsl new file mode 100644 index 0000000000..d4d195721f --- /dev/null +++ b/assets/Stride/SDSL/MarchAttributes.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MarchAttributes +{ + stage compose IVoxelSampler AttributeSamplers[]; +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/MarchAttributesEffect.sdsl b/assets/Stride/SDSL/MarchAttributesEffect.sdsl new file mode 100644 index 0000000000..47a20343f0 --- /dev/null +++ b/assets/Stride/SDSL/MarchAttributesEffect.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + partial effect MarchAttributesEffect + { + using params MarchAttributesKeys; + + mixin MarchAttributes; + if (MarchAttributesKeys.AttributeSamplers!=null) + { + foreach (var attr in MarchAttributesKeys.AttributeSamplers) + { + mixin compose AttributeSamplers += (attr); + } + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl b/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl new file mode 100644 index 0000000000..9c188ede8d --- /dev/null +++ b/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialCelShadingLightDefault : IMaterialCelShadingLightFunction + { + override float3 Compute(float lightIn) + { + if (IsBlackAndWhite) + { + if (lightIn > 0.2) + return float3(1, 1, 1); + } + else + { + if (lightIn > 0.8) + return float3(1, 1, 1); + + if (lightIn > 0.5) + return float3(0.8f, 0.8f, 0.8f); + + if (lightIn > 0.2) + return float3(0.3f, 0.3f, 0.3f); + } + + return 0; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl b/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl new file mode 100644 index 0000000000..e82999cacc --- /dev/null +++ b/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialCelShadingLightRamp + : IMaterialCelShadingLightFunction, Texturing + { + rgroup PerMaterial + { + stage Texture2D CelShaderRamp; + } + + override float3 Compute(float lightIn) + { + float2 texCoord = float2(clamp(lightIn, 0, 1), 0.5); + return CelShaderRamp.SampleLevel(LinearSampler, texCoord, 0).rgb; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialDisplacementStream.sdsl b/assets/Stride/SDSL/MaterialDisplacementStream.sdsl new file mode 100644 index 0000000000..675bdbdd5b --- /dev/null +++ b/assets/Stride/SDSL/MaterialDisplacementStream.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + shader MaterialDisplacementStream : IStreamInitializer + { + // Displacement height attribute + stage stream float matDisplacement; + + override void ResetStream() + { + base.ResetStream(); + + streams.matDisplacement = 0.0f; + } + }; +} + diff --git a/assets/Stride/SDSL/MaterialDomainStream.sdsl b/assets/Stride/SDSL/MaterialDomainStream.sdsl new file mode 100644 index 0000000000..34f5ea4bfc --- /dev/null +++ b/assets/Stride/SDSL/MaterialDomainStream.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Contains all the default streams of the domain shader stage. + /// + shader MaterialDomainStream : MaterialStream, MaterialDisplacementStream, MaterialTessellationStream, NormalStream, PositionStream, Texturing + { + }; +} diff --git a/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl b/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl new file mode 100644 index 0000000000..1f94179874 --- /dev/null +++ b/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader MaterialFrontBackBlendShader : ShadingBase, Transformation, PositionStream, NormalStream +{ + cbuffer PerDraw + { + [Color] + stage float3 ColorFront; + + stage float ColorBlend; + + [Color] + stage float3 ColorBack; + + stage float AlphaBlend; + } + + // method computing color + stage override float4 Shading() + { + float3 color = ColorFront; + if (TUseNormalBackface) + { + float3 viewWS = normalize(Eye.xyz - streams.PositionWS.xyz); + // Allow smooth transition from front face to backface + float ndotV = saturate((dot(streams.normalWS, viewWS) + 0.25) / 0.25); + color = lerp(ColorBack, ColorFront, ndotV); + } + + return float4(color * ColorBlend, AlphaBlend); + } +}; diff --git a/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl b/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl new file mode 100644 index 0000000000..237f05e400 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairDirectionFunctionBitangent : IMaterialHairDirectionFunction + { + float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose) + { + normalOS = normalize(normalOS); // TODO: PERFORMANCE: Normalization required? + + tangentOS.xyz = normalize(tangentOS.xyz); // TODO: PERFORMANCE: Normalization required? + const float3 bitangentOS = normalize(tangentOS.w * cross(normalOS, tangentOS.xyz)); // TODO: PERFORMANCE: Normalization required? + const float3 bitangentWS = normalize(mul(bitangentOS, worldInverseTranspose)); // TODO: PERFORMANCE: Normalization required? + return bitangentWS; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl b/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl new file mode 100644 index 0000000000..431b4f4f38 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairDirectionFunctionTangent : IMaterialHairDirectionFunction + { + float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose) + { + tangentOS.xyz = normalize(tangentOS.xyz); // TODO: PERFORMANCE: Normalization required? + const float3 tangentWS = normalize(mul(tangentOS, worldInverseTranspose)); // TODO: PERFORMANCE: Is this normalization required? + return tangentWS; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl b/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl new file mode 100644 index 0000000000..ab888cd944 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Renders only the opaque parts for the opaque hair pass. + /// + class MaterialHairDiscardFunctionOpaquePass : IMaterialHairDiscardFunction, MaterialPixelStream + { + cbuffer PerMaterial + { + [Link("THairAlphaThreshold")] + stage float HairAlphaThreshold; // Any alpha value above this value is considered opaque. + } + + void Discard(void) + { + if(streams.matDiffuse.a < HairAlphaThreshold) + { + discard; + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl b/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl new file mode 100644 index 0000000000..16f618120d --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Renders only the transparent parts for the transparent hair pass. + /// + class MaterialHairDiscardFunctionTransparentPass : IMaterialHairDiscardFunction, MaterialPixelStream + { + cbuffer PerMaterial + { + [Link("THairAlphaThreshold")] + stage float HairAlphaThreshold; // Any alpha value above this value is considered opaque. + } + + void Discard(void) + { + if(streams.matDiffuse.a >= HairAlphaThreshold) + { + discard; + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl b/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl new file mode 100644 index 0000000000..16b12dde9f --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairLightAttenuationFunctionDirectional : IMaterialHairLightAttenuationFunction, + NormalStream, LightStream // These are required for accessing the normals and light direction. + { + cbuffer PerMaterial + { + [Link("THardnessReciprocal")] + stage float HardnessReciprocal; // == 1.0 / hardness + [Link("TBoundaryShift")] + stage float BoundaryShift; // Range: [0.0 ... 0.5] + } + + float CalculateNdotL(void) + { + const float3 meshNormalWorldSpaceShifted = normalize(lerp(streams.meshNormalWS, -streams.lightDirectionWS, BoundaryShift)); + const float3 normalMapNormalShifted = normalize(lerp(streams.normalWS, -streams.lightDirectionWS, BoundaryShift)); // If no normal map is present, this will be equal to the mesh normal. + + if(NormalMode == 0) // Mesh normals: + { + return dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS); + } + else if(NormalMode == 1) // Normal map normals: + { + return dot(normalMapNormalShifted, streams.lightDirectionWS); + } + else // Mesh & normal map normals: + { + // Alternate approach: + //return max(dot(normalMapNormalShifted, streams.lightDirectionWS), + // dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS)); + + // More conservative approach: + return min(dot(normalMapNormalShifted, streams.lightDirectionWS), + dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS)); + } + } + + float Compute(void) + { + float saturatedNdotL = saturate(CalculateNdotL()); + return pow(saturatedNdotL, HardnessReciprocal); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl b/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl new file mode 100644 index 0000000000..6efe8ed9c9 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairLightAttenuationFunctionNone : IMaterialHairLightAttenuationFunction + { + float Compute(void) + { + return(1.0); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl b/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl new file mode 100644 index 0000000000..917d4f97b1 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairShadowingFunctionScattering : IMaterialHairShadowingFunction, ShadowStream + { + cbuffer PerMaterial + { + [Link("TExtinctionStrength")] + stage float ExtinctionStrength; + } + + float3 Compute() + { + /* + // As an example, here is the SSSS code: + const float translucency = 0.5; + const float sssWidth = 0.1; + + // Calculate the scale of the effect: + const float scale = 8.25 * (1.0 - translucency) / sssWidth; + + // Armed with the thickness, we can now calculate the color by means of the + // precalculated transmittance profile. + // (It can be precomputed into a texture, for maximum performance): + const float d = scale * thickness; + + const float dd = -d * d; + float3 profile = float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + float3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + float3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + float3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + float3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + float3(0.078, 0.0, 0.0) * exp(dd / 7.41); // TODO: How can we generate this profile for arbitrary materials? + + // Using the profile, we finally approximate the transmitted lighting from + // the back of the object: + //return profile * saturate(0.3 + dot(lightDirectionWS, -meshNormalWS)) * attenuatedLightColor; + finalLighting *= profile; + */ + + return exp(-streams.thicknessWS * ExtinctionStrength); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl b/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl new file mode 100644 index 0000000000..41c29b1495 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialHairShadowingFunctionShadowing : IMaterialHairShadowingFunction, ShadowStream + { + float3 Compute() + { + return streams.shadowColor; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialHairShared.sdsl b/assets/Stride/SDSL/MaterialHairShared.sdsl new file mode 100644 index 0000000000..3003df01b5 --- /dev/null +++ b/assets/Stride/SDSL/MaterialHairShared.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialHairShared + { + static const int HAIR_SHADING_SCHEUERMANN_APPROXIMATION = 0; // These values must correspond to the ones defined in "MaterialHairShared.cs". + static const int HAIR_SHADING_SCHEUERMANN_IMPROVED = 1; + static const int HAIR_SHADING_KAJIYAKAY_SHIFTED = 2; + + static const int Opaque = 0; + static const int TransparentBack = 1; + static const int TransparentFront = 2; + + cbuffer PerMaterial // Changed to "PerMaterial" because otherwise PassID contains garbage, as we don't require nor execute the HairRenderFeature anymore. + { + stage int PassID; // 0 == Opaque, 1 == Transparent back, 2 = Transparent front + } + + float3 GetDebugColor(int passID) + { + if(passID == Opaque) + { + return float3(1.0, 0.0, 0.0); + } + else if(passID == TransparentBack) + { + return float3(0.0, 1.0, 0.0); + } + else + { + return float3(0.0, 0.0, 1.0); + } + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl b/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl new file mode 100644 index 0000000000..ccb9355595 --- /dev/null +++ b/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialPixelShadingStream : MaterialPixelStream, LightStream + { + // Output of shading a material surface + stage stream float3 shadingColor; + + // Output of the shading color alpha + stage stream float shadingColorAlpha; + + // Half vector (sum of normalWS + lightDirectionWS) + stage stream float3 H; + + // normal dot half vector + stage stream float NdotH; + + // light dot half vector + stage stream float LdotH; + + // view dot half vector + stage stream float VdotH; + + override void ResetStream() + { + base.ResetStream(); + streams.shadingColorAlpha = 1.0f; + } + + // Computes material attributes per light + stage void PrepareMaterialPerDirectLight() + { + // TODO: This is not plug-n-play + // Used by microfacet + streams.H = normalize(streams.viewWS + streams.lightDirectionWS); + streams.NdotH = saturate(dot(streams.normalWS, streams.H)); + streams.LdotH = saturate(dot(streams.lightDirectionWS, streams.H)); + streams.VdotH = streams.LdotH; + } + }; +} + diff --git a/assets/Stride/SDSL/MaterialPixelStream.sdsl b/assets/Stride/SDSL/MaterialPixelStream.sdsl new file mode 100644 index 0000000000..f761f2d6b7 --- /dev/null +++ b/assets/Stride/SDSL/MaterialPixelStream.sdsl @@ -0,0 +1,116 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialPixelStream : MaterialStream, NormalStream, LightStream + { + // -------------------------------------------------- + // Values defined by materials + // -------------------------------------------------- + + // Surface attributes + stage stream float3 matNormal; + + // The color base attributes + stage stream float4 matColorBase; + + // Diffuse attributes + stage stream float4 matDiffuse; + + // Microsurface attributes + stage stream float matGlossiness; + + // Specular attributes + stage stream float3 matSpecular; + + stage stream float matSpecularIntensity; + // Occlusion attributes + stage stream float matAmbientOcclusion; + stage stream float matAmbientOcclusionDirectLightingFactor; + stage stream float matCavity; + stage stream float matCavityDiffuse; + stage stream float matCavitySpecular; + + // Emissive attributes + stage stream float4 matEmissive; + stage stream float matEmissiveIntensity; + + // Scattering attributes + stage stream float matScatteringStrength; + + // Transparent attributes + stage stream float2 matDiffuseSpecularAlphaBlend; + stage stream float3 matAlphaBlendColor; + stage stream float matAlphaDiscard; + + // Inputs while shading a material surface + stage stream float3 viewWS; + + // -------------------------------------------------- + // Values Precomputed before lighting + // -------------------------------------------------- + + stage stream float3 matDiffuseVisible; + + stage stream float alphaRoughness; // disney-burley roughness + + stage stream float3 matSpecularVisible; + + stage stream float NdotV; // normal dot view + + override void ResetStream() + { + base.ResetStream(); + + // Reset all values for material stream to avoid pulling from a different stage (VS...etc.) + // TODO: It might be interesting to support pulling from VS, but this should be done from the IMaterialSurface and dedicated ComputerColors + streams.matNormal = float3(0, 0, 1); + + streams.matColorBase = 0.0f; + streams.matDiffuse = 0.0f; + streams.matDiffuseVisible = 0.0f; + + streams.matSpecular = 0.0f; + streams.matSpecularVisible = 0.0f; + streams.matSpecularIntensity = 1.0f; + + streams.matGlossiness = 0.0f; + streams.alphaRoughness = 1.0f; + + streams.matAmbientOcclusion = 1.0f; // 0.0: occluded, 1.0: not occluded + streams.matAmbientOcclusionDirectLightingFactor = 0.0f; + + streams.matCavity = 1.0f; + streams.matCavityDiffuse = 0.0f; + streams.matCavitySpecular = 0.0f; + + streams.matEmissive = 0.0f; + streams.matEmissiveIntensity = 0.0f; + + streams.matScatteringStrength = 1.0f; + + streams.matDiffuseSpecularAlphaBlend = 1.0f; + streams.matAlphaBlendColor = 1.0f; + streams.matAlphaDiscard = 0.1f; + } + + void PrepareMaterialForLightingAndShading() + { + // Direct lighting can be slightly influenced by AO map + streams.lightDirectAmbientOcclusion = lerp(1.0, streams.matAmbientOcclusion, streams.matAmbientOcclusionDirectLightingFactor); + + // Diffuse visible + streams.matDiffuseVisible = streams.matDiffuse.rgb * lerp(1.0f, streams.matCavity, streams.matCavityDiffuse) * streams.matDiffuseSpecularAlphaBlend.r * streams.matAlphaBlendColor; + streams.matSpecularVisible = streams.matSpecular.rgb * streams.matSpecularIntensity * lerp(1.0f, streams.matCavity, streams.matCavitySpecular) * streams.matDiffuseSpecularAlphaBlend.g * streams.matAlphaBlendColor; + + streams.NdotV = max(dot(streams.normalWS, streams.viewWS), 0.0001f); + + var roughness = 1.0f - streams.matGlossiness; + + // Make sure alphaRoughness is not going below a certain value as it can generate Infinity with some specular model + streams.alphaRoughness = max(roughness * roughness, 0.001); + // TODO: precalculate alphaRoughness^2 + } + }; +} + diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl new file mode 100644 index 0000000000..85b3ca5762 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader MaterialSpecularMicrofacetEnvironmentGGXLUT : IMaterialSpecularMicrofacetEnvironmentFunction, Texturing + { + rgroup PerMaterial + { + stage Texture2D EnvironmentLightingDFG_LUT; + } + + override float3 Compute(float3 specularColor, float alphaR, float nDotV) + { + float glossiness = 1.0f - sqrt(alphaR); +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 || STRIDE_GRAPHICS_API_OPENGL + // SampleLevel doesn't work on D3D feature level 9 + float4 environmentLightingDFG = EnvironmentLightingDFG_LUT.SampleLevel(LinearSampler, float2(glossiness, nDotV), 0); +#else + float4 environmentLightingDFG = EnvironmentLightingDFG_LUT.Sample(LinearSampler, float2(glossiness, nDotV)); +#endif + return specularColor * environmentLightingDFG.r + environmentLightingDFG.g; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl new file mode 100644 index 0000000000..7a954d2b2a --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader MaterialSpecularMicrofacetEnvironmentGGXPolynomial : IMaterialSpecularMicrofacetEnvironmentFunction + { + override float3 Compute(float3 specularColor, float alphaR, float nDotV) + { + return EnvironmentLightingDFG_GGX_Schlick_SmithSchlickGGX(specularColor, alphaR, nDotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl new file mode 100644 index 0000000000..0d7f0a3bd3 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader MaterialSpecularMicrofacetEnvironmentThinGlass : IMaterialSpecularMicrofacetEnvironmentFunction, MaterialTransmittanceReflectanceStream + { + override float3 Compute(float3 specularColor, float alphaR, float nDotV) + { + return streams.matReflectance; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl new file mode 100644 index 0000000000..9906e71c3e --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader MaterialSpecularMicrofacetFresnelNone : IMaterialSpecularMicrofacetFresnelFunction + { + override float3 Compute(float3 f0) + { + return FresnelNone(f0); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl new file mode 100644 index 0000000000..f092d6d09e --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Fresnel function + /// + shader MaterialSpecularMicrofacetFresnelSchlick : IMaterialSpecularMicrofacetFresnelFunction + { + override float3 Compute(float3 f0) + { + return FresnelSchlick(f0, streams.LdotH); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl new file mode 100644 index 0000000000..b78e190fff --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Microfacet fresnel function for Glass materials. + /// + shader MaterialSpecularMicrofacetFresnelThinGlass : IMaterialSpecularMicrofacetFresnelFunction, MaterialTransmittanceReflectanceStream + { + override float3 Compute(float3 f0) + { + return streams.matReflectance; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl new file mode 100644 index 0000000000..61b08d2ba3 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Normal Distribution function + /// + shader MaterialSpecularMicrofacetNormalDistributionBeckmann : IMaterialSpecularMicrofacetNormalDistributionFunction + { + override float Compute() + { + return NormalDistributionBeckmann(streams.alphaRoughness, streams.NdotH); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl new file mode 100644 index 0000000000..4245669e9a --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Normal Distribution function + /// + shader MaterialSpecularMicrofacetNormalDistributionBlinnPhong : IMaterialSpecularMicrofacetNormalDistributionFunction + { + override float Compute() + { + return NormalDistributionBlinnPhong(streams.alphaRoughness, streams.NdotH); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl new file mode 100644 index 0000000000..ae5a255067 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Normal Distribution function + /// + shader MaterialSpecularMicrofacetNormalDistributionGGX : IMaterialSpecularMicrofacetNormalDistributionFunction + { + override float Compute() + { + return NormalDistributionGGX(streams.alphaRoughness, streams.NdotH); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl new file mode 100644 index 0000000000..f32050ec03 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilityCookTorrance : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilityCookTorrance(streams.NdotH, streams.VdotH, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl new file mode 100644 index 0000000000..29dc1ef414 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilityImplicit : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilityImplicit(streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl new file mode 100644 index 0000000000..43842d4f8b --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilityKelemen : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilityKelemen(streams.VdotH, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl new file mode 100644 index 0000000000..4c2529f5a2 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilityNeumann : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilityNeumann(streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl new file mode 100644 index 0000000000..63db794b8b --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilitySmithBeckmann : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilitySmithBeckmann(streams.alphaRoughness, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl new file mode 100644 index 0000000000..d1898afde3 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilitySmithGGXCorrelated(streams.alphaRoughness, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl new file mode 100644 index 0000000000..66214bec56 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilitySmithSchlickBeckmann(streams.alphaRoughness, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl new file mode 100644 index 0000000000..f9cbc9a343 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Interface for a microfacet Geometric Shadowing function + /// + shader MaterialSpecularMicrofacetVisibilitySmithSchlickGGX : IMaterialSpecularMicrofacetVisibilityFunction + { + override float Compute() + { + return VisibilitySmithSchlickGGX(streams.alphaRoughness, streams.NdotL, streams.NdotV); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialStream.sdsl b/assets/Stride/SDSL/MaterialStream.sdsl new file mode 100644 index 0000000000..e68546945f --- /dev/null +++ b/assets/Stride/SDSL/MaterialStream.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialStream : IStreamInitializer + { + /// + /// The blending applied between the current and previous material attributes + /// + stage stream float matBlend; + + override void ResetStream() + { + base.ResetStream(); + + // Reset all values for material stream to avoid pulling from a different stage (VS...etc.) + // TODO: It might be interesting to support pulling from VS, but this should be done from the IMaterialSurface and dedicated ComputerColors + streams.matBlend = 0.0f; + } + }; +} + diff --git a/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl b/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl new file mode 100644 index 0000000000..72350d86c8 --- /dev/null +++ b/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Blend a stream linearly + /// + shader MaterialStreamAdditiveBlend : IMaterialStreamBlend + { + override void Compute(Streams fromStream) + { + streams.TMember = fromStream.TMember + streams.TMember; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl b/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl new file mode 100644 index 0000000000..4034194719 --- /dev/null +++ b/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Blend a stream linearly + /// + shader MaterialStreamLinearBlend : IMaterialStreamBlend + { + override void Compute(Streams fromStream) + { + streams.TMember = lerp(fromStream.TMember, streams.TMember, streams.matBlend); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl b/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl new file mode 100644 index 0000000000..d99113b45f --- /dev/null +++ b/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Blend a stream using RNM + /// + shader MaterialStreamNormalBlend : IMaterialStreamBlend + { + override void Compute(Streams fromStream) + { + // Linear interpolation (TODO: We could let the normal blending be configurable) + var middleNormal = NormalUtil.BlendRNM(fromStream.matNormal, streams.matNormal); + + // This is not correct, but try to have a good 0.5 and linear interpol from this + // ideally, we should have RNM support a blending based of matBlend + streams.matNormal = streams.matBlend < 0.5 ? + lerp(fromStream.matNormal, middleNormal, streams.matBlend / 0.5) + : lerp(middleNormal, streams.matNormal, (streams.matBlend - 0.5) * 2); + + //streams.matNormal = normalize(lerp(fromStream.matNormal, streams.matNormal, streams.matBlend)); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl new file mode 100644 index 0000000000..78fc015a7b --- /dev/null +++ b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialSubsurfaceScatteringScatteringProfileCustomUniform : IMaterialSubsurfaceScatteringScatteringProfile + { + cbuffer PerMaterial + { + stage float4 ScatteringProfile[6]; + } + + // TODO: This does not result in the exact same kind of profiles as the skin profile. But it's close. + // Improve it using the "Extending Separable Subsurface Scattering to Arbitrary Materials" paper. + float3 Compute(float dd) + { + float3 sum = 0.0; + + for(int i=0; i<6; ++i) + { + sum += exp(dd * ScatteringProfile[i].xyz) * ScatteringProfile[i].w; + } + + return sum; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl new file mode 100644 index 0000000000..70fec5180b --- /dev/null +++ b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialSubsurfaceScatteringScatteringProfileCustomVarying : IMaterialSubsurfaceScatteringScatteringProfile + { + compose ComputeColor FalloffMap; + + stage stream float3 falloff; + + override void Prepare(void) + { + // Calculate the falloff here and only once for all lights. + streams.falloff = FalloffMap.Compute().rgb; // TODO: Try supplying the texture using a streams variable instead? Might solve the issue with less code. + } + + float3 Gaussian(float variance, float dd, float3 falloff) + { + // We use a falloff to modulate the shape of the profile. Big falloffs + // spreads the shape making it wider, while small falloffs make it + // narrower. + const float3 adjustedFalloff = 0.001 + falloff; + const float3 adjustedFalloffSquared = adjustedFalloff * adjustedFalloff; + + const float twoVariance = 2.0 * variance; + const float twoPiVariance = 3.14 * twoVariance; + + const float3 adjustedFalloffSquaredTwoVariance = adjustedFalloffSquared * twoVariance; + + return exp(dd / adjustedFalloffSquaredTwoVariance) / twoPiVariance; + } + + float3 Compute(float dd) + { + // We used the red channel of the original skin profile defined in + // [d'Eon07] for all three channels. We noticed it can be used for green + // and blue channels (scaled using the falloff parameter) without + // introducing noticeable differences and allowing for total control over + // the profile. For example, it allows to create blue SSS gradients, which + // could be useful in case of rendering blue creatures. + + return 0.233 * Gaussian(0.0064, dd, streams.falloff) + // We consider this one to be directly bounced light, accounted by the strength parameter (see @STRENGTH) + 0.100 * Gaussian(0.0484, dd, streams.falloff) + + 0.118 * Gaussian(0.187, dd, streams.falloff) + + 0.113 * Gaussian(0.567, dd, streams.falloff) + + 0.358 * Gaussian(1.99, dd, streams.falloff) + + 0.078 * Gaussian(7.41, dd, streams.falloff); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl new file mode 100644 index 0000000000..264fba91ca --- /dev/null +++ b/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + class MaterialSubsurfaceScatteringScatteringProfileSkin : IMaterialSubsurfaceScatteringScatteringProfile + { + float3 Compute(float dd) + { + // Hardcoded skin profile from https://github.com/iryoku/separable-sss + return float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + + float3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + + float3(0.118, 0.198, 0.0) * exp(dd / 0.187) + + float3(0.113, 0.007, 0.007) * exp(dd / 0.567) + + float3(0.358, 0.004, 0.0) * exp(dd / 1.99) + + float3(0.078, 0.0, 0.0) * exp(dd / 7.41); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceArray.sdsl b/assets/Stride/SDSL/MaterialSurfaceArray.sdsl new file mode 100644 index 0000000000..9638626de5 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceArray.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialSurfaceArray : IMaterialSurface + { + compose IMaterialSurface layers[]; + + override void Compute() + { + foreach(var layer in layers) + { + layer.Compute(); + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl b/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl new file mode 100644 index 0000000000..46b30c63f7 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Converts diffuse color + /// + shader MaterialSurfaceDiffuse : IMaterialSurfacePixel + { + compose ComputeColor diffuseMap; + + override void Compute() + { + var colorBase = diffuseMap.Compute(); + streams.matDiffuse = colorBase; + + // Because matDiffuse can be modified when using a metalness, we are storing the colorBase into matColorBase + // so that we are able to query the original diffuse color without any modifications. + streams.matColorBase = colorBase; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl b/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl new file mode 100644 index 0000000000..4493318e23 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Converts diffuse color (for metal flakes layer) + /// + shader MaterialSurfaceDiffuseMetalFlakes : MaterialSurfaceDiffuse, + Transformation, + PositionStream4 + { + compose ComputeColor surfaceToEyeDistanceFactor; + + override void Compute() + { + var basePaintColor = streams.matDiffuse; + + base.Compute(); + + var distanceFactor = surfaceToEyeDistanceFactor.Compute().r; + + // Interpolate the factors using the surface to camera distance + float LOD = saturate(distance(Eye.xyz, streams.PositionWS.xyz) * distanceFactor); + streams.matDiffuse = lerp(streams.matDiffuse, basePaintColor, LOD); + + // Because matDiffuse can be modified when using a metalness, we are storing the colorBase into matColorBase + // so that we are able to query the original diffuse color without any modifications. + streams.matColorBase = lerp(streams.matDiffuse, basePaintColor, LOD); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl b/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl new file mode 100644 index 0000000000..6463f9529a --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha + /// + shader MaterialSurfaceDiffuseSpecularAlphaBlendColor : IMaterialSurfacePixel, MaterialPixelShadingStream + { + override void Compute() + { + streams.shadingColorAlpha = lerp(0, streams.shadingColorAlpha, streams.matDiffuseSpecularAlphaBlend.r); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl b/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl new file mode 100644 index 0000000000..df813a082c --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Material displacement map + /// + shader MaterialSurfaceDisplacement : IMaterialSurface, MaterialDisplacementStream, PositionStream, NormalStream, Transformation + { + override void Compute() + { + float3 scaledNormal = streams.TNormal; + if(TScaleNormal) + { + scaledNormal *= WorldScale; + } + + streams.TPosition = float4(streams.TPosition.xyz + streams.matDisplacement * scaledNormal, streams.TPosition.w); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl b/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl new file mode 100644 index 0000000000..6c0d3ad0e6 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + // Temporary code for testing IMaterialSurface + shader MaterialSurfaceDomainStageCompositor : TessellationBase + { + compose IMaterialSurface materialDomainStage; + compose IStreamInitializer streamInitializerDomainStage; + + stage override void TessellateDomain() + { + base.TessellateDomain(); + + // Reset material streams + streamInitializerDomainStage.ResetStream(); + + // Compute the shading of the surface + materialDomainStage.Compute(); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl new file mode 100644 index 0000000000..5d7f9561e3 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Emissive shading + /// + shader MaterialSurfaceEmissiveShading : IMaterialSurfacePixel, MaterialPixelShadingStream + { + override void Compute() + { + streams.shadingColor += streams.matEmissive.rgb * streams.matEmissiveIntensity; + if (TUseAlphaFromEmissive) + { + streams.shadingColorAlpha = streams.matEmissive.a; + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl b/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl new file mode 100644 index 0000000000..1066220f04 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Material glossiness map + /// + shader MaterialSurfaceGlossinessMap : IMaterialSurfacePixel + { + compose ComputeColor glossinessMap; + + override void Compute() + { + var glossiness = glossinessMap.Compute().r; + if (TInvert) + { + glossiness = 1.0 - glossiness; + } + + streams.matGlossiness = glossiness; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl b/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl new file mode 100644 index 0000000000..a082bde2f3 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Material glossiness map (for a metal flakes layer) + /// + shader MaterialSurfaceGlossinessMapMetalFlakes : MaterialSurfaceGlossinessMap, + Transformation, + PositionStream4 + { + compose ComputeColor surfaceToEyeDistanceFactor; + + override void Compute() + { + var metalFlakesGlossiness = streams.matGlossiness; + + // Compute base glossiness + base.Compute(); + + var distanceFactor = surfaceToEyeDistanceFactor.Compute().r; + + // Correct both glossiness factor (to avoid aliasing and unrealistic values) + float normalLength = length(streams.matNormal); + //streams.matGlossiness = normalLength * streams.matGlossiness / (normalLength + streams.matGlossiness * (1.0f - normalLength)); + metalFlakesGlossiness = normalLength * metalFlakesGlossiness / (normalLength + metalFlakesGlossiness * (1.0f - normalLength)); + + // Interpolate the factors using the surface to camera distance + float LOD = saturate(distance(Eye.xyz, streams.PositionWS.xyz) * distanceFactor); + + streams.matGlossiness = lerp(metalFlakesGlossiness, streams.matGlossiness, LOD); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl new file mode 100644 index 0000000000..04ee00301e --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs the shading of a material according to the lights + /// + shader MaterialSurfaceLightingAndShading : IMaterialSurfacePixel, DirectLightGroupArray, EnvironmentLightArray, MaterialPixelShadingStream, Math, Transformation, ShaderBaseStream, NormalUpdate + { + compose IMaterialSurfaceShading surfaces[]; + + override void Compute() + { + // Before performing the shading for all lights, update the NormalVS with the latest normal + // In case normal mapping is not used, this is a no-op + UpdateNormalFromTangentSpace(streams.matNormal); + + // Flip the normal so it is facing the right direction for back faces +#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 + //streams.normalWS = streams.normalWS * sign(streams.IsFrontFace);// FIXME: VFACE seems to not work in a proper way +#else + if(!streams.IsFrontFace) + streams.normalWS = -streams.normalWS; +#endif + + // Make sure that light stream is reset + ResetLightStream(); + + // Prepare the material for lighting (allows to pre-compute things which are reused during lighting computation) + PrepareMaterialForLightingAndShading(); + + // Prepare shading model + foreach (var surface in surfaces) + { + surface.PrepareForLightingAndShading(); + } + + // --------------------------------------------------------------------------- + // Compute Direct Lighting contribution + // --------------------------------------------------------------------------- + float3 directLightingContribution = 0; + foreach(var lightGroup in directLightGroups) + { + lightGroup.PrepareDirectLights(); + + const int maxLightCount = lightGroup.GetMaxLightCount(); + int count = lightGroup.GetLightCount(); + + // [unroll] Don't unroll and let the driver handle it + for(int i = 0; i < maxLightCount; i++) + { + if (i >= count) + { + break; + } + + // Compute the light color and direction + lightGroup.PrepareDirectLight(i); + + // Compute common material shading streams (TODO: This is temporary) + PrepareMaterialPerDirectLight(); + + // Iterate on shading models + foreach(var surface in surfaces) + { + directLightingContribution += surface.ComputeDirectLightContribution(); + } + } + } + + // --------------------------------------------------------------------------- + // Compute Environment Lighting contribution + // --------------------------------------------------------------------------- + float3 environmentLightingContribution = 0; + foreach(var environmentLight in environmentLights) + { + // Compute the environment light color (streams.lightColor) + environmentLight.PrepareEnvironmentLight(); + + // Iterate on shading models + foreach(var surface in surfaces) + { + environmentLightingContribution += surface.ComputeEnvironmentLightContribution(); + } + } + + // Add Direct (*PI over hemisphere) and Environment Lighting + streams.shadingColor += directLightingContribution * PI + environmentLightingContribution; + streams.shadingColorAlpha = streams.matDiffuse.a; + + // Do any computations after lighting and shading, like discarding pixels for example. + foreach (var surface in surfaces) + { + surface.AfterLightingAndShading(); + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl b/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl new file mode 100644 index 0000000000..97d9fba5af --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Converts Metalness to specular color + /// + shader MaterialSurfaceMetalness : IMaterialSurfacePixel + { + compose ComputeColor metalnessMap; + + override void Compute() + { + // Metallic workflow + // http://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf + float metalness = metalnessMap.Compute().r; + // Use a low 0.02 reflectance value for non-metal + streams.matSpecular = lerp(0.02, streams.matDiffuse.rgb, metalness); + + // Adjust diffuse + streams.matDiffuse.rgb = lerp(streams.matDiffuse.rgb, 0, metalness); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl b/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl new file mode 100644 index 0000000000..11066973e9 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Material normal map + /// + shader MaterialSurfaceNormalMap : IMaterialSurfacePixel + { + compose ComputeColor normalMap; + + override void Compute() + { + var normal = normalMap.Compute(); + + // For unsigned textures we need to convert (0, 1) to (-1, 1) range + if (TScaleAndBias) + { + normal = (2.0f * normal) - 1.0f; + } + + // If Z is calculated from XY do it here + if (TIsNormalXY1) + { + normal.z = sqrt(max(0, 1.0f - (normal.x * normal.x + normal.y * normal.y))); + } + + // Note! Don't normalize the streams.matNormal here, it's being normalize when streams.normalWS is calculated + streams.matNormal = normal.xyz; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl new file mode 100644 index 0000000000..51e0a07775 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + // Temporary code for testing IMaterialSurface + shader MaterialSurfaceNormalStreamShading : ShadingBase, NormalStream + { + stage override float4 Shading() + { + // Run surface shading but don't take the result + base.Shading(); + return float4(streams.normalWS * 0.5f + 0.5f, 1.0f); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl b/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl new file mode 100644 index 0000000000..c6b26c4ffb --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + // Temporary code for testing IMaterialSurface + shader MaterialSurfacePixelStageCompositor : ShadingBase, Transformation, PositionStream, MaterialPixelShadingStream, DirectLightGroupArray, EnvironmentLightArray + { + compose IMaterialSurface materialPixelStage; + compose IStreamInitializer streamInitializerPixelStage; + + stage override float4 Shading() + { + // Prepare global streams (temp) + streams.viewWS = normalize(Eye.xyz - streams.PositionWS.xyz); + streams.shadingColor = 0; + + // Reset material streams + streamInitializerPixelStage.ResetStream(); + + // Compute the shading of the surface + // TODO: separate between material attributes blending and material lighting/shadow shading + materialPixelStage.Compute(); + + // Return the actual shading color + return float4(streams.shadingColor, streams.shadingColorAlpha); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl b/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl new file mode 100644 index 0000000000..599951dadf --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialSurfaceSetStreamFromComputeColor : IMaterialSurfacePixel, IMaterialSurfaceVertex, IMaterialSurfaceDomain + { + compose ComputeColor computeColorSource; + + override void Compute() + { + streams.TStream = computeColorSource.Compute().TChannel; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl new file mode 100644 index 0000000000..a390e3a272 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialSurfaceShadingBlend : MaterialSurfaceArray, MaterialPixelShadingStream + { + override void Compute() + { + var backupShadingColor = streams.shadingColor; + var blending = streams.matBlend; + streams.shadingColor = 0; + base.Compute(); + streams.shadingColor = lerp(backupShadingColor, streams.shadingColor, blending); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl new file mode 100644 index 0000000000..7e974af3c6 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs a Cel shading + /// + class MaterialSurfaceShadingDiffuseCelShading : IMaterialSurfaceShading, Math, MaterialPixelShadingStream, LightStream, ShadowGroup + { + compose IMaterialCelShadingLightFunction celLightFunction; + + override float3 ComputeDirectLightContribution() + { + float3 celLight = streams.NdotL * streams.lightAttenuation; + + if (FakeNDotL > 0) + { + celLight = celLightFunction.Compute(celLight * FakeNDotL); + } + else + { + celLight = celLightFunction.Compute(celLight); + } + + float3 lighting = celLight * streams.lightColor * streams.shadowColor * streams.lightDirectAmbientOcclusion; + + var diffuseColor = streams.matDiffuseVisible; + if (TIsEnergyConservative) + { + // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf + diffuseColor *= (1 - streams.matSpecularVisible); + } + + float3 result = diffuseColor / PI * lighting * streams.matDiffuseSpecularAlphaBlend.x; + return result; + } + + override float3 ComputeEnvironmentLightContribution() + { + // TODO: Check how to factorize this with DirectLight + var diffuseColor = streams.matDiffuseVisible; + if (TIsEnergyConservative) + { + diffuseColor *= (1 - streams.matSpecularVisible); + } + + float3 celLight = celLightFunction.Compute(streams.envLightDiffuseColor); + return diffuseColor * celLight; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl new file mode 100644 index 0000000000..4c371808e2 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl @@ -0,0 +1,129 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Calculates the diffuse lighting for hair. + /// + shader MaterialSurfaceShadingDiffuseHair : + IMaterialSurfaceShading, // Required for "ComputeDirectLightContribution()" and the like. + MaterialPixelShadingStream, + Math, // Required for "PI". + LightStream, // Required for "streams.lightColor" and "streams.lightDirectionWS". + MaterialHairShared, + Transformation, // Required for "WorldInverseTranspose". + NormalStream // Required for "streams.normalWS", "streams.meshNormal", "streams.meshTangent". + { + compose IMaterialHairLightAttenuationFunction hairLightAttenuationFunction; + compose IMaterialHairDirectionFunction hairDirectionFunction; + compose IMaterialHairShadowingFunction hairShadowingFunction; + compose IMaterialHairDiscardFunction hairDiscardFunction; + + stream float3 hairDirection; + + override void PrepareForLightingAndShading() + { + streams.hairDirection = hairDirectionFunction.Compute(streams.meshNormal, streams.meshTangent, (float3x3)WorldInverseTranspose); + } + + float3 ComputeHairLightingDiffuse(float3 hairDirection, float3 toLightVec, float3 diffuseLighting) + { + float3 diffuse = diffuseLighting; + //float4 diffuse = LambertBRDF(surfaceData); // Mizuchi version // TODO: Can we delete this line? + + if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) + { + // in Kajiya's model: diffuse component: sin(t, l) + float cosTL = dot(hairDirection, toLightVec); + float sinTL = sqrt(1.0 - cosTL * cosTL); + diffuse *= sinTL; + } + + return diffuse; + } + + float HairDiffuseAttenuation(float dotNL) // "dotNL" must be unsaturated! + { + if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) + { + // No ad-hoc attenuation in Kajiya-Kay formula + // The coefficient for diffuse is applied during ComputeHairLightingDiffuse(), + // therefore we do not apply dotNL. + return 1.0; + } + else + { + //------------------------------------------------------------------------------ + // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.243 : + // "Kajiya-kay diffuse term is too bright" + // "standard dotNL diffuse is too dark in areas facing away from the light" + // "a good compromise is a tweaked dotNL term" + //------------------------------------------------------------------------------ + return saturate(0.75 * dotNL + 0.25); + } + } + + override float3 ComputeDirectLightContribution() + { + if(DebugRenderPasses) + { + return 0.0; // Return 0.0 because the indirect lighting function already returns the debug color. + } + + var diffuseColor = streams.matDiffuseVisible; // This already includes the multiplication by the cavity map. + if (TIsEnergyConservative) + { + // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf + diffuseColor *= (1 - streams.matSpecularVisible); + } + + float3 diffuseLighting = diffuseColor / PI; + diffuseLighting *= streams.lightColor * streams.lightAttenuation; //diffuseLighting *= streams.lightColorNdotL; // Distance- & normal-attenuated light color. + diffuseLighting *= streams.matDiffuseSpecularAlphaBlend.x; + diffuseLighting *= hairShadowingFunction.Compute(); // Apply shadowing/scattering. + diffuseLighting *= streams.lightDirectAmbientOcclusion; + + const float NdotLUnsaturated = dot(streams.normalWS, streams.lightDirectionWS); + + // TODO: Multiply by alpha or not? + float3 finalLighting = ComputeHairLightingDiffuse(streams.hairDirection, streams.lightDirectionWS, diffuseLighting); + finalLighting *= HairDiffuseAttenuation(NdotLUnsaturated); + finalLighting *= hairLightAttenuationFunction.Compute(); + + return finalLighting; + } + + override float3 ComputeEnvironmentLightContribution() + { + if(DebugRenderPasses) + { + return GetDebugColor(PassID); + } + + // TODO: The indirect diffuse hair lighting could be much better. + // For example by taking the hair structure into account just like for the specular lighting. + // But that's difficult because the diffuse environmental lighting is calculated somewhere else. + + // TODO: Check how to factorize this with DirectLight + var diffuseColor = streams.matDiffuseVisible; // This already includes the multiplication by the cavity map. + if (TIsEnergyConservative) + { + diffuseColor *= (1 - streams.matSpecularVisible); + } + + // TODO: Multiply by alpha or not? + return diffuseColor * streams.envLightDiffuseColor; + //return diffuseColor * streams.envLightDiffuseColor * streams.matAmbientOcclusion; // TODO: Does AO work without this? + } + + /* + // TODO: Enabling this allows the diffuse hair shading model to be used independently of the specular one. + // But this would mean if both the specular and the diffuse models are present, the shader will have two conditional discards, which will cause a shader compilation error. + // Need to find a way to fix that. + override void AfterLightingAndShading() + { + hairDiscardFunction.Discard(); + } + */ + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl new file mode 100644 index 0000000000..0532fde3c8 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs a Lambert shading + /// + shader MaterialSurfaceShadingDiffuseLambert : IMaterialSurfaceShading, Math + { + override float3 ComputeDirectLightContribution() + { + var diffuseColor = streams.matDiffuseVisible; + if (TIsEnergyConservative) + { + // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf + diffuseColor *= (1 - streams.matSpecularVisible); + } + return diffuseColor / PI * streams.lightColorNdotL * streams.matDiffuseSpecularAlphaBlend.x; + } + + override float3 ComputeEnvironmentLightContribution() + { + // TODO: Check how to factorize this with DirectLight + var diffuseColor = streams.matDiffuseVisible; + if (TIsEnergyConservative) + { + diffuseColor *= (1 - streams.matSpecularVisible); + } + + return diffuseColor * streams.envLightDiffuseColor; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl new file mode 100644 index 0000000000..b9884e40bf --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs a Lambert shading + /// + shader MaterialSurfaceShadingSpecularBlinnPhong : IMaterialSurfaceShading, NormalStream + { + override float3 ComputeDirectLightContribution() + { + float k = BRDFBlinnPhong.Compute(streams.lightDirectionWS, streams.normalWS, streams.viewWS, streams.matSpecularPower); + + var specularColor = streams.matSpecular * (streams.matCavity * streams.matCavitySpecular); + + // TODO: integrate AO/Cavity...etc. + // TODO: Check if we need to divide by PI + return specularColor * (k * streams.lightSpecularColorNdotL * streams.matDiffuseSpecularAlphaBlend.y); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl new file mode 100644 index 0000000000..9ce4e1a084 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs a Microfacet shading + /// + class MaterialSurfaceShadingSpecularCelShading : IMaterialSurfaceShading, MaterialPixelShadingStream, Math, BRDFMicrofacet, LightStream + { + compose IMaterialCelShadingLightFunction celLightFunction; + + compose IMaterialSpecularMicrofacetFresnelFunction fresnelFunction; + + compose IMaterialSpecularMicrofacetVisibilityFunction geometricShadowingFunction; + + compose IMaterialSpecularMicrofacetNormalDistributionFunction normalDistributionFunction; + + compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; + + override float3 ComputeDirectLightContribution() + { + var specularColor = streams.matSpecularVisible; + + var fresnel = fresnelFunction.Compute(specularColor); + var geometricShadowing = geometricShadowingFunction.Compute(); + var normalDistribution = normalDistributionFunction.Compute(); + + var reflected = fresnel * geometricShadowing * normalDistribution / 4; + + return celLightFunction.Compute(reflected) * streams.lightColorNdotL * streams.matDiffuseSpecularAlphaBlend.y; + } + + override float3 ComputeEnvironmentLightContribution() + { + var specularColor = streams.matSpecularVisible; + + // TODO: Allow plugability of this function (pb is that it is a combination of fresnel, visibility and NDF) + //return specularColor * streams.envLightSpecularColor; + return environmentFunction.Compute(specularColor, streams.alphaRoughness, streams.NdotV) * streams.envLightSpecularColor; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl new file mode 100644 index 0000000000..27008daae2 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl @@ -0,0 +1,374 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs hair shading. + /// + shader MaterialSurfaceShadingSpecularHair : + IMaterialSurfaceShading, // Required for "ComputeDirectLightContribution()" and the like. + MaterialPixelShadingStream, + MaterialHairShared, + NormalStream, // Required for "streams.normalWS", "streams.meshNormal", "streams.meshTangent". + Transformation, // Required for "WorldInverseTranspose". + MaterialPixelStream // Required for "streams.matDiffuse". + { + compose ComputeColor SpecularHighlightsShiftNoiseTexture; + compose ComputeColor SecondarySpecularGlintsNoiseTexture; + + compose IMaterialHairLightAttenuationFunction hairLightAttenuationFunction; + compose IMaterialHairDirectionFunction hairDirectionFunction; + compose IMaterialHairShadowingFunction hairShadowingFunction; + compose IMaterialHairDiscardFunction hairDiscardFunction; + compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; + + cbuffer PerMaterial + { + [Color] + stage float3 HairSpecularColor1; // The color of the primary specular reflection. + + [Color] + stage float3 HairSpecularColor2; // The color of the secondary specular reflection. + + stage float HairScalesAngle; + stage float HairSpecularShiftRatio; + stage float HairSpecularExponent1; + stage float HairSpecularExponent2; + stage float HairSpecularScale1; + stage float HairSpecularScale2; + stage float HairShiftNoiseScale; // Controls how much the noise should affect the specular highlight direction. + stage float HairGlintsNoiseStrength; // Controls how much the glints noise should affect the secondary reflections. + } + + /// + /// Holds all the required input data for hair shading. + /// + struct SurfaceData + { + float hairScalesAngle; + float hairSpecularShiftRatio; + float3 WBinormal; + float3 WViewDir; + float3 WNormal; + float hairSpecularExponent1; // TODO: This is ignored by the indirect lighting. + float hairSpecularExponent2; // TODO: This is ignored by the indirect lighting. + float3 hairSpecularColor1; + float3 hairSpecularColor2; + float cavity; + float hairSpecularScale1; + float hairSpecularScale2; + float hairSecondarySpecularGlintsNoise; + float hairSpecularHighlightsShiftNoise; + }; + + //stream SurfaceData surfaceData; + static SurfaceData surfaceData; // TODO: How to make the variable not get exposed in the CodeBehind? Sadly making this a streams variable causes a shader compilation error. + + SurfaceData GenerateSurfaceData(void) + { + SurfaceData result; + result.hairScalesAngle = HairScalesAngle; + result.hairSpecularShiftRatio = HairSpecularShiftRatio; + result.WViewDir = streams.viewWS; + result.WNormal = streams.normalWS; + + // TODO: Use mesh normal or normal map normal? + result.WBinormal = hairDirectionFunction.Compute(streams.meshNormal, streams.meshTangent, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Get rid of the float3x3 cast? + + result.hairSpecularExponent1 = HairSpecularExponent1; + result.hairSpecularExponent2 = HairSpecularExponent2; + + result.hairSpecularColor1 = HairSpecularColor1; + result.hairSpecularColor2 = HairSpecularColor2; + + result.hairSpecularScale1 = HairSpecularScale1; + result.hairSpecularScale2 = HairSpecularScale2; + + // We can't use "streams.matSpecularVisible" here because it is multiplied by the specular color. + result.cavity = lerp(1.0, streams.matCavity, streams.matCavitySpecular); + + result.hairSpecularHighlightsShiftNoise = (SpecularHighlightsShiftNoiseTexture.Compute().r - 0.5) * HairShiftNoiseScale; + //result.hairSpecularHighlightsShiftNoise = SpecularHighlightsShiftNoiseTexture.Compute().r * HairShiftNoiseScale; + result.hairSecondarySpecularGlintsNoise = lerp(1.0, SecondarySpecularGlintsNoiseTexture.Compute().r, HairGlintsNoiseStrength); + + return result; + } + + override void PrepareForLightingAndShading() // This gets executed only once for the entire shader. + { + surfaceData = GenerateSurfaceData(); + } + + void CalculateShiftAngles(SurfaceData surfaceData, out float shiftAngle1, out float shiftAngle2) + { + // The hair shift is being calculated differently from Mizuchi because the Mizuchi implementation is weird. + + float scalesAngle = surfaceData.hairScalesAngle; + shiftAngle1 = 2.0 * scalesAngle; + shiftAngle2 = -shiftAngle1 * surfaceData.hairSpecularShiftRatio; // hairSpecularShiftRatio is theoretically 1.5 + + shiftAngle1 += surfaceData.hairSpecularHighlightsShiftNoise; + shiftAngle2 += surfaceData.hairSpecularHighlightsShiftNoise; // I think Mizuchi subtracts the noise from the 2nd shift angle. That isn't correct according to my research, so I changed it. + + } + + float HairSingleSpecularTerm_Kajiya(float3 T, float3 toLightVec, float3 viewDir, float shiftAngle) + { + float cosTL = dot(T, toLightVec); + float sinTL = sqrt(1.0 - cosTL * cosTL); + + // in Kajiya's model: specular component: cos(t, rl) * cos(t, e) + sin(t, rl)sin(t, e) + float cosT_RL = -cosTL; + float sinT_RL = sinTL; + float cosTE = dot(T, viewDir); + float sinTE = sqrt(1.0 - cosTE * cosTE); + + // Kajiya-Kay highlight: reflected direction shifted + float cosT_RL_shifted = cosT_RL * cos(shiftAngle) - sinT_RL * sin(shiftAngle); + float sinT_RL_shifted = sqrt(1 - cosT_RL_shifted * cosT_RL_shifted); + return max(0.0, cosT_RL_shifted * cosTE + sinT_RL_shifted * sinTE); + } + + //------------------------------------------------------------------------------ + // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.244 : + // "sum the contribution of two separate specular terms per light" + // "each term has different specular colors, exponents, and is shifted in different directions + //------------------------------------------------------------------------------ + float HairSingleSpecularTerm_Scheuermann(float3 T, float3 H, float exponent) + { + float dotTH = dot(T, H); + //float sinTH = sqrt(1.0 - dotTH * dotTH); // Original version from Mizuchi. Causes artifacts with Scheuermann approximation because of the mathematically correct rotation. The original implementation doesn't suffer from that issue. + float sinTH = sqrt(max(1.0 - dotTH * dotTH, 0.0)); // We limit the value above 0.0 so it doesn't cause NaN errors with the Scheuermann approximation (because of the mathematically correct rotation). + return pow(sinTH, exponent); + } + + //============================================================================== + // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.244 : + // "specular highlights are shifted because the scales on the surface of a hair strand have tilted normals" + // "ideally we would tilt the tangent in the direction of the viewer" + // "in practice it is sufficient to tilt in the direction of the geometric normal" + //============================================================================== + //------------------------------------------------------------------------------ + // Original formula + //------------------------------------------------------------------------------ + //float3 ShiftTangent(float3 T, float3 N, float shiftAmount) + //{ + // return normalize(T + shiftAmount * N); + //} + // + //------------------------------------------------------------------------------ + // Alternative formula (mathematically correct rotation): + // Return vector X (= vector T rotated by angle shiftAngle towards direction N) + //------------------------------------------------------------------------------ + float3 ShiftTangent(float3 T, float3 N, float shiftAngle) + { + // While this function performs mathematically correct rotation, it's probably not desired + // (because the shift texture doesn't represent angles) and instead the original formula should be preferred. + // This is because it can cause the rotation to go beyond 90 degrees, causing the shading vector to point inside the surface, + // causing weird artifacts and issues in other parts of the shading code, which weren't modified to work with the mathematically + // correct rotation but still assume the original shift implemnetation. + + float cosTX = cos(shiftAngle); + float sinTX = sqrt(1.0 - cosTX * cosTX) * sign(shiftAngle); + + if(ShadingModel == HAIR_SHADING_SCHEUERMANN_APPROXIMATION) + { + //return normalize(N + T * shiftAngle); // Original formula + // Simplification (if T,N normal) - Use when T and N are normal + //float cosTN = 0.0; + //float sinTN = 1.0; + return cosTX * T + sinTX * N; + } + else + { + // Handling case when T and N are not really normal + float cosTN = dot(T, N); + float sinTN = sqrt(1.0 - cosTN * cosTN); + float3 X = (cosTX * sinTN - cosTN * sinTX) * T + sinTN * sinTX * N; + return normalize(X); + } + } + + float HairSpecularAttenuation(float dotNL) // "dotNL" must be unsaturated! + { + if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) + { + // No ad-hoc attenuation in Kajiya-Kay formula + // The coefficient for diffuse is applied during ComputeHairLightingSpecular(), + // therefore we do not apply dotNL. + return 1.0; + } + else + { + //------------------------------------------------------------------------------ + // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.246 : + // "specular attenuation for hair facing away from light" + //------------------------------------------------------------------------------ + return saturate(1.75 * dotNL + 0.25); + } + } + + float3 ComputeSpecularKajiya(SurfaceData surfaceData, float3 toLightVec, float shiftAngle, + float specularScale, float specularExponent, float3 specularColor) + { + //-------------------------------------------------------------------------- + // Shifted Kajiya-Kay formula (extension of Kajiya-Kay) + // Similar to what is used in AMD TressFX sample. + //-------------------------------------------------------------------------- + + float shiftedSpecular = HairSingleSpecularTerm_Kajiya(surfaceData.WBinormal, toLightVec, surfaceData.WViewDir, shiftAngle); + return(specularScale * specularColor * pow(shiftedSpecular, specularExponent)); + } + + float3 ComputeSpecularScheuermann(SurfaceData surfaceData, float3 halfVector, float shiftAngle, + float specularScale, float specularExponent, float3 specularColor) + { + //-------------------------------------------------------------------------- + // Scheuermann formula + //-------------------------------------------------------------------------- + // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.245 : + // "The lack of real self-shadowing will cause the specular highlights to be + // too bright on the hair facing away from the light" + // "To fade out the specular highlight on the shadowed side of the hair, we + // multiply by an attenuation term that is similar to the diffuse term." + //-------------------------------------------------------------------------- + + // shift tangents + float3 shiftDirection; + + if(ShadingModel == HAIR_SHADING_SCHEUERMANN_APPROXIMATION) + { + shiftDirection = surfaceData.WNormal; + } + else if(ShadingModel == HAIR_SHADING_SCHEUERMANN_IMPROVED) + { + shiftDirection = surfaceData.WViewDir; + } + + const float3 T = ShiftTangent(surfaceData.WBinormal, shiftDirection, shiftAngle); + + // specular term + return(specularScale * specularColor * HairSingleSpecularTerm_Scheuermann(T, halfVector, specularExponent)); + } + + //============================================================================== + // Specular term for hair (for Direct Lighting) + //============================================================================== + float3 ComputeHairLightingSpecular(SurfaceData surfaceData, float3 halfVector, float3 toLightVec) + { + // modulate specular shift by a texture + float shiftAngle1; + float shiftAngle2; + CalculateShiftAngles(surfaceData, shiftAngle1, shiftAngle2); + + float hairSpecularExponent1 = surfaceData.hairSpecularExponent1; // We already make sure on the CPU side that "surfaceData.hairSpecularExponent1" can't be "0.0". + float hairSpecularExponent2 = surfaceData.hairSpecularExponent2; // We already make sure on the CPU side that "surfaceData.hairSpecularExponent2" can't be "0.0". + + float3 specular1; + float3 specular2; + if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) + { + // primary highlight: reflected direction shift towards tip + specular1 = ComputeSpecularKajiya(surfaceData, toLightVec, shiftAngle1, surfaceData.hairSpecularScale1, hairSpecularExponent1, surfaceData.hairSpecularColor1); + // secondary highlight: reflected direction shifted toward root + specular2 = ComputeSpecularKajiya(surfaceData, toLightVec, shiftAngle2, surfaceData.hairSpecularScale2, hairSpecularExponent2, surfaceData.hairSpecularColor2); + } + else + { + // specular terms + specular1 = ComputeSpecularScheuermann(surfaceData, halfVector, shiftAngle1, surfaceData.hairSpecularScale1, hairSpecularExponent1, surfaceData.hairSpecularColor1); + specular2 = ComputeSpecularScheuermann(surfaceData, halfVector, shiftAngle2, surfaceData.hairSpecularScale2, hairSpecularExponent2, surfaceData.hairSpecularColor2); + } + + // modulate secondary specular term with noise + specular2 *= surfaceData.hairSecondarySpecularGlintsNoise; + + float3 specular = (specular1 + specular2) * hairShadowingFunction.Compute(); // Used to apply shadowing/scattering. + return specular * surfaceData.cavity; + } + + float3 ComputeSpecularIndirectLighting(SurfaceData surfaceData, float shiftAngle, float3 specularColor) + { + const float3 shiftedNormal = ShiftTangent(surfaceData.WBinormal, surfaceData.WNormal, shiftAngle); + + // specular term + const float shiftedNdotV = max(dot(shiftedNormal, surfaceData.WViewDir), 0.0); + + float3 specular = environmentFunction.Compute(specularColor, streams.alphaRoughness, shiftedNdotV) * streams.envLightSpecularColor; + + // Since "SpecularTerm_IBL()", which is replaced by "environmentFunction.Compute()", + // applies the cavity parameter internally, we do it too: + specular *= surfaceData.cavity; + + return specular; + } + + //============================================================================== + // Specular term for hair (for Indirect Lighting) + //------------------------------------------------------------------------------ + // Similarly to what is done for the direct lighting, we compute the specular component based on the shifted hair tangents. + // This is not physically realistic because: + // - the ambientBRDF map does not convolve the hair specular BRDF + // However, this is a satisfying approximation at first. + //============================================================================== + float3 ComputeHairImageBasedLightingSpecular(SurfaceData surfaceData) //, IBLTextureParameters IBL) + { + //return 1.0; + + // shift tangents + float shiftAngle1; + float shiftAngle2; + CalculateShiftAngles(surfaceData, shiftAngle1, shiftAngle2); + + float3 specular1 = ComputeSpecularIndirectLighting(surfaceData, shiftAngle1, surfaceData.hairSpecularColor1); + float3 specular2 = ComputeSpecularIndirectLighting(surfaceData, shiftAngle2, surfaceData.hairSpecularColor2); + + specular1 *= surfaceData.hairSpecularScale1; // TODO: This is a workaround to make the indirect lighting look better. Not sure if we should keep it as it basically scales the specular reflection like it does for the direct lighting. + specular2 *= surfaceData.hairSpecularScale2; // TODO: This is a workaround to make the indirect lighting look better. Not sure if we should keep it as it basically scales the specular reflection like it does for the direct lighting. + + // modulate secondary specular term with noise + specular2 *= surfaceData.hairSecondarySpecularGlintsNoise; + + return specular1 + specular2; + } + + override float3 ComputeDirectLightContribution() + { + if(DebugRenderPasses) + { + return 0.0; // Return 0.0 because the indirect lighting function already returns the debug color. + } + + float3 specular = ComputeHairLightingSpecular(surfaceData, + streams.H, // Half vector + streams.lightDirectionWS); // Vector pointing from the pixel towards the light. + + const float NdotLUnsaturated = dot(normalize(streams.normalWS), normalize(streams.lightDirectionWS)); // TODO: PERFORMANCE: Normalization necessary? + + //specular *= saturate(NdotLUnsaturated * 0.5 + 0.5); // This could be used in combination with hair SSS. + specular *= HairSpecularAttenuation(NdotLUnsaturated); + specular *= hairLightAttenuationFunction.Compute(); + specular *= streams.lightColor * streams.lightAttenuation * streams.matDiffuseSpecularAlphaBlend.y; + //specular *= streams.lightDirectAmbientOcclusion; + + // TODO: Multiply by alpha or not? + return specular * streams.matDiffuse.a; // TODO: Technically we should use "streams.shadingColorAlpha" but its value is assigned AFTER the shading, which makes it useless. + } + + override float3 ComputeEnvironmentLightContribution() + { + if(DebugRenderPasses) + { + return GetDebugColor(PassID); + } + + // TODO: Multiply by alpha or not? + return ComputeHairImageBasedLightingSpecular(surfaceData).rgb * streams.matDiffuse.a; // TODO: Technically we should use "streams.shadingColorAlpha" but its value is assigned AFTER the shading, which makes it useless. + } + + override void AfterLightingAndShading() + { + hairDiscardFunction.Discard(); + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl new file mode 100644 index 0000000000..850374956d --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs a Microfacet shading + /// + shader MaterialSurfaceShadingSpecularMicrofacet : IMaterialSurfaceShading, MaterialPixelShadingStream, Math, BRDFMicrofacet + { + compose IMaterialSpecularMicrofacetFresnelFunction fresnelFunction; + + compose IMaterialSpecularMicrofacetVisibilityFunction geometricShadowingFunction; + + compose IMaterialSpecularMicrofacetNormalDistributionFunction normalDistributionFunction; + + compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; + + override float3 ComputeDirectLightContribution() + { + var specularColor = streams.matSpecularVisible; + + var fresnel = fresnelFunction.Compute(specularColor); + var geometricShadowing = geometricShadowingFunction.Compute(); + var normalDistribution = normalDistributionFunction.Compute(); + + var reflected = fresnel * geometricShadowing * normalDistribution / 4; + + return reflected * streams.lightSpecularColorNdotL * streams.matDiffuseSpecularAlphaBlend.y; + } + + override float3 ComputeEnvironmentLightContribution() + { + var specularColor = streams.matSpecularVisible; + + // TODO: Allow plugability of this function (pb is that it is a combination of fresnel, visibility and NDF) + //return specularColor * streams.envLightSpecularColor; + return environmentFunction.Compute(specularColor, streams.alphaRoughness, streams.NdotV) * streams.envLightSpecularColor; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl new file mode 100644 index 0000000000..3509478b5b --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + // Temporary code for testing IMaterialSurface + shader MaterialSurfaceStreamShading : ShadingBase, MaterialPixelShadingStream + { + stage override float4 Shading() + { + // Run surface shading but don't take the result + base.Shading(); + var value = streams.TStreamName; + if (RemapSigned) + value = value * 0.5f + 0.5f; + return float4(value.TStreamRGB, 1.0f); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl b/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl new file mode 100644 index 0000000000..c87d7e44cf --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialSurfaceStreamsBlend : IMaterialSurface + { + compose IMaterialSurface layer; + + compose IMaterialStreamBlend blends[]; + + override void Compute() + { + var backup = streams; + + // Compute the layer + layer.Compute(); + + // Compute the blending of this layer + foreach(var blendStep in blends) + { + blendStep.Compute(backup); + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl new file mode 100644 index 0000000000..32668edf24 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl @@ -0,0 +1,74 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Performs subsurface scattering using shadow maps. + /// + class MaterialSurfaceSubsurfaceScatteringShading : + IMaterialSubsurfaceScatteringScatteringProfile, + IMaterialSurfaceShading, // Required for the "PrepareForLightingAndShading()", "ComputeDirectLightContribution()" and "AfterLightingAndShading()" functions. Already includes "MaterialPixelStream.sdsl". + MaterialPixelShadingStream, // Required for "streams.shadingColorAlpha". + ShadowStream, // Required for "streams.thicknessWS". + Math + { + cbuffer PerMaterial + { + stage float Translucency; + stage float ScatteringWidth; + } + + compose IMaterialSubsurfaceScatteringScatteringProfile scatteringProfileFunction; + + stream float scatteringStrength; // TODO: Do we need the stage keyword here? + + float3 CalculateTransmittance(float thickness, + float translucency, // This parameter allows to control the transmittance effect. Its range should be [0..1]. Higher values translate to a stronger effect. + float sssWidth, // This parameter should be the same as the one for the post-process. + float3 meshNormalWS, + float3 lightDirectionWS, + float3 attenuatedLightColor, + float3 surfaceAlbedo) + { + // Calculate the scale of the effect: + const float scale = 8.25 * (1.0 - translucency) / sssWidth; + + // Armed with the thickness, we can now calculate the color by means of the + // precalculated transmittance profile. + // (It can be precomputed into a texture, for maximum performance): + const float d = scale * thickness; + const float dd = -d * d; + + float3 profile = scatteringProfileFunction.Compute(dd); + + // Using the profile, we finally approximate the transmitted lighting from the back of the object: + return profile * saturate(0.3 + dot(lightDirectionWS, -meshNormalWS)) * attenuatedLightColor * surfaceAlbedo; + } + + override void PrepareForLightingAndShading() + { + scatteringProfileFunction.Prepare(); + streams.scatteringStrength = Translucency * streams.matScatteringStrength; + } + + override float3 ComputeDirectLightContribution() + { + float3 scatteredLighting = CalculateTransmittance(streams.thicknessWS, + streams.scatteringStrength, + ScatteringWidth, + streams.meshNormalWS, + streams.lightDirectionWS, + streams.lightColor * streams.lightAttenuation, + streams.matDiffuseVisible); + + return scatteredLighting; + //return scatteredLighting / PI; // TODO: Divide by Pi? + } + + override void AfterLightingAndShading() + { + // Store the scattering strength in the alpha channel, so the post-process can sample it: + streams.shadingColorAlpha = streams.scatteringStrength; // TODO: Is this the best way to write to the alpha channel of the render target? + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl b/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl new file mode 100644 index 0000000000..8b829e0c7f --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha + /// + shader MaterialSurfaceTransmittanceShading : IMaterialSurfacePixel, MaterialPixelShadingStream, MaterialTransmittanceReflectanceStream + { + override void Compute() + { + // Blend mode is SRC_COLOR, ZERO + // Transmittance == 0 => black + // Transmittance == 1 => preserve color + streams.shadingColor = lerp(1, streams.matTransmittance, streams.shadingColorAlpha); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl b/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl new file mode 100644 index 0000000000..26e8f51db8 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + shader MaterialSurfaceTransparentAlphaDiscard : IMaterialSurface, MaterialPixelShadingStream, ShaderBaseStream + { + override void Compute() + { + // Discard a pixel if the alpha from the material diffuse is less than the alpha discard limit + if (streams.shadingColorAlpha < streams.matAlphaDiscard) + { + discard; + } + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl b/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl new file mode 100644 index 0000000000..80773db836 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Material displacement map + /// + shader MaterialSurfaceVertexDisplacement : IMaterialSurfaceVertex + { + override void Compute() + { + var displacement = streams.matDisplacement; + if (TScaleAndBias) + { + displacement = displacement * 2 - 1; + } + + displacement *= streams.matDisplacementIntensity; + + streams.Position = float4(streams.Position.xyz + displacement * streams.meshNormal, streams.Position.w); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl b/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl new file mode 100644 index 0000000000..9185a3ef64 --- /dev/null +++ b/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + // Temporary code for testing IMaterialSurface + shader MaterialSurfaceVertexStageCompositor : ShaderBase + { + compose IMaterialSurface materialVertexStage; + compose IStreamInitializer streamInitializerVertexStage; + + stage override void VSMain() + { + base.VSMain(); + + // Reset material streams + streamInitializerVertexStage.ResetStream(); + + // Compute the shading of the surface + // TODO: separate between material attributes blending and material lighting/shadow shading + materialVertexStage.Compute(); + } + }; +} diff --git a/assets/Stride/SDSL/MaterialTessellationStream.sdsl b/assets/Stride/SDSL/MaterialTessellationStream.sdsl new file mode 100644 index 0000000000..94f9aaddb5 --- /dev/null +++ b/assets/Stride/SDSL/MaterialTessellationStream.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + shader MaterialTessellationStream : IStreamInitializer + { + // Displacement height attribute + stage stream float matSmoothingIntensity; + + // The level of details desired + stage stream float oppositeEdgeLOD; + + override void ResetStream() + { + base.ResetStream(); + + streams.oppositeEdgeLOD = 0.0f; + streams.matSmoothingIntensity = 0.0f; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl b/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl new file mode 100644 index 0000000000..ace6f7dcd0 --- /dev/null +++ b/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Materials +{ + /// + /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha + /// + shader MaterialTransmittanceReflectanceStream : MaterialPixelStream + { + cbuffer PerMaterial + { + stage float RefractiveIndex; + } + + stage stream float3 matTransmittance; + stage stream float3 matReflectance; + + override void ResetStream() + { + base.ResetStream(); + + streams.matTransmittance = 0.0f; + streams.matReflectance = 1.0f; + } + + override void PrepareMaterialForLightingAndShading() + { + base.PrepareMaterialForLightingAndShading(); + + // Angle between view vector and surface normal + const float cosTheta = streams.NdotV; + const float sinTheta2 = 1 - cosTheta * cosTheta; // Square of sinTheta + + float eta = max(RefractiveIndex, 1.0001); + + const float sinRefractedTheta2 = sinTheta2 / (eta * eta); // Square of sinRefractedTheta, We don't actually need sinRefractedTheta + const float cosRefractedTheta = sqrt(1 - sinRefractedTheta2); + + const float q0 = (eta * cosRefractedTheta - cosTheta); + const float q1 = (eta * cosRefractedTheta + cosTheta); + const float q2 = (eta * cosTheta - cosRefractedTheta); + const float q3 = (eta * cosTheta + cosRefractedTheta); + + const float r0 = q0 / q1; + const float r1 = q2 / q3; + + // Fresnel reflectance at the entering interface + const float R0 = 0.5 * saturate(r0 * r0 + r1 * r1); // TODO: Test if this command can be optimized by using float2(r0, r1).length() on target platforms + // Fresnel transmittance at the entering interface + const float T0 = 1 - R0; + + // intermediate float3 values + const float3 R = float3(R0, R0, R0); + const float3 T = float3(T0, T0, T0); + const float3 C = float3(cosRefractedTheta, cosRefractedTheta, cosRefractedTheta); + + // Coefficient to account for absorption + const float3 K = pow(max(streams.matColorBase.rgb, 0.001), 1 / C); + + const float3 RK = R*K; // intermediate value + + float3 transmittance = saturate(T*T * K / (1 - RK * RK)); + streams.matReflectance = saturate(RK * transmittance + R); + streams.matTransmittance = transmittance; + } + }; +} diff --git a/assets/Stride/SDSL/MaterialVertexStream.sdsl b/assets/Stride/SDSL/MaterialVertexStream.sdsl new file mode 100644 index 0000000000..8ffa0a9fbb --- /dev/null +++ b/assets/Stride/SDSL/MaterialVertexStream.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Materials +{ + /// + /// Contains all the default streams of the vertex shader stage. + /// + shader MaterialVertexStream : MaterialStream, MaterialDisplacementStream, NormalStream, PositionStream + { + }; +} diff --git a/assets/Stride/SDSL/Math.sdsl b/assets/Stride/SDSL/Math.sdsl new file mode 100644 index 0000000000..cba0235c22 --- /dev/null +++ b/assets/Stride/SDSL/Math.sdsl @@ -0,0 +1,123 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various math functions. +/// +shader Math +{ + // ------------------------------------- + // constant value + // ------------------------------------- + static const float PI = 3.14159265358979323846; + + // ------------------------------------- + // methods + // ------------------------------------- + // Tests intersection between a ray and a plane + static bool RayIntersectsPlane(float3 rayPosition, + float3 rayDirection, + float3 planeNormal, + float planeDirection, out float3 position) + { + float distance = (planeDirection - dot(planeNormal, rayPosition)) / dot(rayDirection, planeNormal); + position = rayPosition + rayDirection * distance; + return distance >= 0; + } + + // Tests intersection between a ray and a sphere + static bool RayIntersectsSphere(float3 rayPosition, float3 rayDirection, float3 spherePosition, float sphereRadius, out float distance) + { + //Source: Real-Time Collision Detection by Christer Ericson + //Reference: Page 177 + + float3 m = rayPosition - spherePosition; + + float b = dot(m, rayDirection); + float c = dot(m, m) - (sphereRadius * sphereRadius); + + if (c > 0 && b > 0) + { + distance = 0; + return false; + } + + float discriminant = b * b - c; + + if (discriminant < 0) + { + distance = 0; + return false; + } + + distance = -b - sqrt(discriminant); + + if (distance < 0) + distance = 0; + + return true; + } + + // Computes the luminance of a color + float Luminance(float3 color) { + return dot(color, float3(0.2126, 0.7152, 0.0722)); + } + + // ------------------------------------- + // Hermine interpolation + // ------------------------------------- + float Hermine(float x) { + return x * x * (3.0 - 2.0 * x); + } + float2 Hermine(float2 x) { + return x * x * (3.0 - 2.0 * x); + } + float3 Hermine(float3 x) { + return x * x * (3.0 - 2.0 * x); + } + float4 Hermine(float4 x) { + return x * x * (3.0 - 2.0 * x); + } + + // ------------------------------------- + // Quintic interpolation + // ------------------------------------- + float Quintic1(float x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float2 Quintic(float2 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float3 Quintic(float3 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + float4 Quintic(float4 x) { + return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); + } + + // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) + float FastRandom(uint n) + { + n = (n << 13) ^ n; + return float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0; + } + + // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) + float FastRandom(float2 x) + { + return FastRandom(uint(x.x * 37 + x.y * 6007)); + } + + // Transforms "vec" by "mat" and does a W-divide. + float4 Project(float4 vec, float4x4 mat) + { + float4 vecProjected = mul(vec, mat); + vecProjected.xyz /= vecProjected.w; + return vecProjected; + } + + //Exponential damping + float ExpDecay(float a, float b, float lambda, float dt) + { + return b + (a - b) * exp(-lambda * dt); + } +}; diff --git a/assets/Stride/SDSL/McIntoshCombineShader.sdsl b/assets/Stride/SDSL/McIntoshCombineShader.sdsl new file mode 100644 index 0000000000..d046e49844 --- /dev/null +++ b/assets/Stride/SDSL/McIntoshCombineShader.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Outputs the minium of 2 textures. (Final pass of the McIntosh bokeh effect.) + /// Expects as input: + /// - Texture0: a color buffer with diagonal blur + /// - Texture1: a color buffer with diagonal blur + /// + shader McIntoshCombineShader : ImageEffectShader + { + + stage override float4 Shading() + { + float4 minimum = min( Texture0.Sample(Sampler, streams.TexCoord), + Texture1.Sample(Sampler, streams.TexCoord) ); + return minimum; + } + }; +} diff --git a/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl b/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl new file mode 100644 index 0000000000..6b8c6c7b28 --- /dev/null +++ b/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + compose DepthAwareDirectionalBlurShader blurShader; + + /// + /// Optimized version of the McIntosh bokeh effect. + /// Based on a first blur pass, computes the 2 diagonal blurs and keeps the minimum. + /// Expects as input: + /// - Texture0: a color buffer with a first directional blur + /// - Texture1: the corresponding depth buffer + /// + shader McIntoshOptimizedShader : ImageEffectShader + { + compose ComputeColor directionalBlurA; + compose ComputeColor directionalBlurB; + + stage override float4 Shading() + { + // First diagonal blur + float4 blurColorA = directionalBlurA.Compute(); + + // Second diagonal blur + float4 blurColorB = directionalBlurB.Compute(); + + return min(blurColorA, blurColorB); + } + }; +} diff --git a/assets/Stride/SDSL/MeshVelocity.sdsl b/assets/Stride/SDSL/MeshVelocity.sdsl new file mode 100644 index 0000000000..52c10e5720 --- /dev/null +++ b/assets/Stride/SDSL/MeshVelocity.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Computes screen space velocity for meshes +shader MeshVelocity : PositionStream4, TransformationBase, ScreenPositionBase, VelocityStream +{ + cbuffer PerDraw + { + float4x4 PreviousWorldViewProjection; + } + + // The previous position in screen space + stage stream float4 PreviousPosition; + + stage override void VSMain() + { + base.VSMain(); + + // Calculate previous world position + streams.PreviousPosition = mul(streams.Position, PreviousWorldViewProjection); + } + + stage override void PSMain() + { + // Calculate screen space velocity + float2 position = streams.ScreenPosition.xy / streams.ScreenPosition.w; + float2 positionLast = streams.PreviousPosition.xy / streams.PreviousPosition.w; + streams.velocity = position - positionLast; + + base.PSMain(); + + //streams.ColorTarget = float4(abs(velocity.xy), 0.0f, 0.0f) * 1.0f; + + //float l = length(velocity.xy); + //streams.ColorTarget = float4(l.xxx, 0.0f) * 15.0f; + } +}; diff --git a/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl b/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl new file mode 100644 index 0000000000..041feeb5b8 --- /dev/null +++ b/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MixinFunctionParamaterTest +{ + abstract ExternMixin test0(); + + abstract void test1(ExternMixin ext); +}; diff --git a/assets/Stride/SDSL/MixinNameClash.sdsl b/assets/Stride/SDSL/MixinNameClash.sdsl new file mode 100644 index 0000000000..2b56f2ad0e --- /dev/null +++ b/assets/Stride/SDSL/MixinNameClash.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MixinNameClash : BasicMixin, BasicMixin2 +{ + void test() + { + float i = myFloat; + } +}; diff --git a/assets/Stride/SDSL/MixinNoNameClash.sdsl b/assets/Stride/SDSL/MixinNoNameClash.sdsl new file mode 100644 index 0000000000..4bc0d30555 --- /dev/null +++ b/assets/Stride/SDSL/MixinNoNameClash.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MixinNoNameClash : BasicMixin, BasicMixin2 +{ + void test() + { + float i = BasicMixin.myFloat + BasicMixin2.myFloat; + } +}; diff --git a/assets/Stride/SDSL/ModelComponentPickingShader.sdsl b/assets/Stride/SDSL/ModelComponentPickingShader.sdsl new file mode 100644 index 0000000000..0ff79ab897 --- /dev/null +++ b/assets/Stride/SDSL/ModelComponentPickingShader.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Utils +{ + /// + /// A shader used to output the id of the model component, mesh and material for a particular RenderMesh + /// + shader ModelComponentPickingShader : ShaderBase + { + [Color] + stage float4 ModelComponentId; + + [Color] + stage float4 MeshId; + + [Color] + stage float4 MaterialId; + + stage override void PSMain() + { + streams.ColorTarget = ModelComponentId; + streams.ColorTarget1 = MeshId; + streams.ColorTarget2 = MaterialId; + } + }; +} diff --git a/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl b/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl new file mode 100644 index 0000000000..85d407da20 --- /dev/null +++ b/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader MultiTexturesSpriteShader : SpriteBase +{ + stage override float4 Shading() + { + return base.Shading() + Texture1.Sample(Sampler, streams.TexCoord); + } +}; diff --git a/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl b/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl new file mode 100644 index 0000000000..f4ded98eb8 --- /dev/null +++ b/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Graphics.Tests +{ + shader MultipleRenderTargetsEffectShader: ShadingBase + { + stage override void PSMain() + { + base.PSMain(); + streams.ColorTarget = this.Shading(); + streams.ColorTarget1 = this.Shading() * float4(0, 0, 1, 1); + streams.ColorTarget2 = this.Shading() * float4(1, 1, 0, 1); + } + }; +} diff --git a/assets/Stride/SDSL/NonStageStreamTest.sdsl b/assets/Stride/SDSL/NonStageStreamTest.sdsl new file mode 100644 index 0000000000..8bf84f7428 --- /dev/null +++ b/assets/Stride/SDSL/NonStageStreamTest.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader NonStageStreamTest +{ + compose StreamParent2 ext0; + compose StreamParent2 ext1; + + float test() + { + return streams.ext0.parentStream + streams.ext1.parentStream + streams.ext0.stageStream + streams.ext1.stageStream; + } +}; diff --git a/assets/Stride/SDSL/NormalBase.sdsl b/assets/Stride/SDSL/NormalBase.sdsl new file mode 100644 index 0000000000..6fd4f17b60 --- /dev/null +++ b/assets/Stride/SDSL/NormalBase.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines the methods to get the normal in view space and inserts them in the pipeline. +/// +shader NormalBase : NormalUpdate, ShaderBase +{ + override stage void VSMain() + { + base.VSMain(); + + // Perform normal generation at the end in case vNormal is modified. + // TODO: Another mechanism (compute on first access?) + GenerateNormal_VS(); + } + + override stage void PSMain() + { + // Perform normal generation at beginning so that it is accessible during PS. + // TODO: Another mechanism (compute on first access?) + GenerateNormal_PS(); + base.PSMain(); + } +}; diff --git a/assets/Stride/SDSL/NormalFromMesh.sdsl b/assets/Stride/SDSL/NormalFromMesh.sdsl new file mode 100644 index 0000000000..7fc142c48d --- /dev/null +++ b/assets/Stride/SDSL/NormalFromMesh.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Computes normals in view space. +/// +shader NormalFromMesh : NormalBase, Transformation +{ + override stage void GenerateNormal_VS() + { + // Perform normal generation at the end in case meshNormal is modified + streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? + streams.normalWS = streams.meshNormalWS; + } + + override stage void GenerateNormal_PS() + { + // Normalize just once the normal coming from the vertex shader + if (dot(streams.normalWS, streams.normalWS) > 0) + streams.normalWS = normalize(streams.normalWS); + streams.meshNormalWS = streams.normalWS; + } + + stage override void UpdateNormalFromTangentSpace(float3 normalInTangentSpace) + { + // Override the default behavior, as we are not changing the NormalVS calculated at vertex stage when normal mapping is not used + } +}; diff --git a/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl b/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl new file mode 100644 index 0000000000..92fb617f76 --- /dev/null +++ b/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Computes normals in view space. +/// +shader NormalFromMeshInstanced : NormalFromMesh, TransformationInstancing +{ + override stage void GenerateNormal_VS() + { + // Perform normal generation at the end in case meshNormal is modified + streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? + streams.normalWS = streams.meshNormalWS; + } +}; diff --git a/assets/Stride/SDSL/NormalFromNormalMapping.sdsl b/assets/Stride/SDSL/NormalFromNormalMapping.sdsl new file mode 100644 index 0000000000..e92e0e9b2f --- /dev/null +++ b/assets/Stride/SDSL/NormalFromNormalMapping.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Calculates the normal the normals from a normal map. +/// +shader NormalFromNormalMapping : Transformation, NormalBase, NormalStream +{ + override stage void GenerateNormal_PS() + { + base.GenerateNormal_PS(); + UpdateTangentToWorld(); + // Transform meshNormal from object space to world space: + streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? + } + + override float3x3 GetTangentWorldTransform() + { + return (float3x3)WorldInverseTranspose; + } +}; diff --git a/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl b/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl new file mode 100644 index 0000000000..3c289ea545 --- /dev/null +++ b/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Calculates the normal the normals from a normal map. +/// +shader NormalFromNormalMappingInstanced : TransformationInstancing, NormalBase, NormalStream +{ + override stage void GenerateNormal_PS() + { + base.GenerateNormal_PS(); + UpdateTangentToWorld(); + // Transform meshNormal from object space to world space: + streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? + } + + override float3x3 GetTangentWorldTransform() + { + return transpose((float3x3)GetInstanceWorldInverse(streams.InstanceID)); + } +}; diff --git a/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl b/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl new file mode 100644 index 0000000000..cfcd65e7ab --- /dev/null +++ b/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Calculates the normal the normals from a normal map. +/// +shader NormalFromNormalMappingTessellation : NormalFromNormalMapping +{ + override stage void GenerateNormal_VS() + { + // Perform normal generation at the end in case meshNormal is modified + streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? + streams.normalWS = streams.meshNormalWS; + } +}; diff --git a/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl b/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl new file mode 100644 index 0000000000..e01db64831 --- /dev/null +++ b/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Calculates the normal the normals from a normal map. +/// +shader NormalFromNormalMappingTessellationInstanced : NormalFromNormalMappingInstanced, TransformationInstancing +{ + override stage void GenerateNormal_VS() + { + // Perform normal generation at the end in case meshNormal is modified + streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? + streams.normalWS = streams.meshNormalWS; + } +}; diff --git a/assets/Stride/SDSL/NormalMeshSkinning.sdsl b/assets/Stride/SDSL/NormalMeshSkinning.sdsl new file mode 100644 index 0000000000..84c1212c6d --- /dev/null +++ b/assets/Stride/SDSL/NormalMeshSkinning.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Performs skinning on the normals. +/// +shader NormalMeshSkinning : TransformationSkinning, NormalStream +{ + override stage void PreTransformPosition() + { + base.PreTransformPosition(); + streams.meshNormal = normalize(mul(streams.meshNormal, (float3x3)streams.skinningBlendMatrix)); // TODO: Does this result in an object or world space normal? If world space, write to meshNormalWS instead! + } +}; diff --git a/assets/Stride/SDSL/NormalPack.sdsl b/assets/Stride/SDSL/NormalPack.sdsl new file mode 100644 index 0000000000..debed9bd89 --- /dev/null +++ b/assets/Stride/SDSL/NormalPack.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Packs and stores the normals into the GBuffer. Expected texture output format: float3. +/// +shader NormalPack +{ + // Compact Normal Storage for Small G-Buffers + // [Aras Pranckevičius 2010, http://aras-p.info/texts/CompactNormalStorage.html] + float3 EncodeNormal(float3 n) + { + // Pack to [0;1] range + return n * 0.5 + 0.5; + } + + // Compact Normal Storage for Small G-Buffers + // [Aras Pranckevičius 2010, http://aras-p.info/texts/CompactNormalStorage.html] + float3 DecodeNormal(float3 enc) + { + // Unpack from [0;1] range + return normalize(enc * 2 - 1); + } +}; diff --git a/assets/Stride/SDSL/NormalStream.sdsl b/assets/Stride/SDSL/NormalStream.sdsl new file mode 100644 index 0000000000..737af23cfa --- /dev/null +++ b/assets/Stride/SDSL/NormalStream.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines the normal, view space normal and tangent streams. +/// +shader NormalStream +{ + // The normal attribute from the mesh + stage stream float3 meshNormal : NORMAL; + + // The above normal but in world space + stage stream float3 meshNormalWS; // This gets set in "NormalFromNormalMapping.sdsl" and "NormalFromMesh.sdsl". + + // The tangent attribute from the mesh + stage stream float4 meshTangent : TANGENT; + + // The normal in world space + stage stream float3 normalWS : NORMALWS; + + // The tangent to view matrix to transform a tangent normal vector to normal vector in viewspace + stage stream float3x3 tangentToWorld; +}; diff --git a/assets/Stride/SDSL/NormalUpdate.sdsl b/assets/Stride/SDSL/NormalUpdate.sdsl new file mode 100644 index 0000000000..19952503db --- /dev/null +++ b/assets/Stride/SDSL/NormalUpdate.sdsl @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines the methods to get the normal in world space. +/// +shader NormalUpdate : NormalStream +{ + stage void GenerateNormal_VS() + { + streams.normalWS = 0.0f; + } + + stage void GenerateNormal_PS() + { + } + + float3x3 GetTangentMatrix() + { + float3x3 tangentMatrix; + + streams.meshNormal = normalize(streams.meshNormal); + var tangent = normalize(streams.meshTangent.xyz); + float3 bitangent = streams.meshTangent.w * cross(streams.meshNormal, tangent); + tangentMatrix = float3x3(tangent, bitangent, streams.meshNormal); + + return tangentMatrix; + } + + stage void UpdateTangentToWorld() + { + var tangentMatrix = GetTangentMatrix(); + var tangentWorldTransform = GetTangentWorldTransform(); + streams.tangentToWorld = mul(tangentMatrix, tangentWorldTransform); + } + + float3x3 GetTangentWorldTransform() + { + return float3x3(1,0,0, 0,1,0, 0,0,1); + } + + // This method is called by the MaterialSurfaceLightingAndShading to calculate the effective normal + stage void UpdateNormalFromTangentSpace(float3 normalInTangentSpace) + { + streams.normalWS = normalize(mul(normalInTangentSpace, streams.tangentToWorld)); + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/NormalUtil.sdsl b/assets/Stride/SDSL/NormalUtil.sdsl new file mode 100644 index 0000000000..ec71999000 --- /dev/null +++ b/assets/Stride/SDSL/NormalUtil.sdsl @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various methods for manipulating normals +/// +shader NormalUtil +{ + // Blending Normal methods: http://blog.selfshadow.com/publications/blending-in-detail/ + + float3 BlendLinear(float3 n1, float3 n2) + { + return normalize(n1 + n2); + } + + float3 BlendPartialDerivative(float3 n1, float3 n2) + { + return normalize(float3(n1.xy*n2.z + n2.xy*n1.z, n1.z*n2.z)); + } + + float3 BlendPartialDerivative(float3 n1, float3 n2, float blend) + { + float2 pd = lerp(n1.xy/(n1.z + 0.00001), n2.xy/(n2.z + 0.00001), blend); + return normalize(float3(pd, 1)); + } + + float3 BlendWhiteout(float3 n1, float3 n2) + { + return float3(n1.xy + n2.xy, n1.z*n2.z); + } + + float3 BlendUDN(float3 n1, float3 n2) + { + return normalize(float3(n1.xy + n2.xy, n1.z)); + } + + float3 BlendRNM(float3 n1, float3 n2) + { + // TEMP try to keep length + var length_n1n2 = length(n1+n2); + n1 = normalize(n1); + n2 = normalize(n2); + + float3 t = n1 + float3(0, 0, 1); + float3 u = float3(-n2.x, -n2.y, n2.z); + float3 r = t*dot(t, u) - u*t.z; + return normalize(r) * length_n1n2; + } +}; diff --git a/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl b/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl new file mode 100644 index 0000000000..169d3ca5bc --- /dev/null +++ b/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Computes skinned normals in view space. +/// +shader NormalVSSkinningFromMesh : NormalFromMesh +{ + override stage void GenerateNormal_VS() + { + // Because meshNormal is already integrating World space, use it as-is for final normalWS + streams.normalWS = streams.meshNormal; + } +}; diff --git a/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl b/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl new file mode 100644 index 0000000000..09aed85e27 --- /dev/null +++ b/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Computes the transformation matrix from tangent to view space when skinning occured. +/// +shader NormalVSSkinningNormalMapping : NormalFromNormalMapping +{ + override float3x3 GetTangentWorldTransform() + { + // TangentMatrix is already in world space, so return an identity matrix here + return float3x3(1,0,0, 0,1,0, 0,0,1); + } +}; diff --git a/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl b/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl new file mode 100644 index 0000000000..12e6d9fbc1 --- /dev/null +++ b/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Calculates the normal the normals from a normal map. +/// +shader NormalVSSkinningNormalMappingTessellation : NormalVSSkinningNormalMapping +{ + override stage void GenerateNormal_VS() + { + // Because meshNormal is already integrating World space, use it as-is for final normalWS + streams.normalWS = streams.meshNormal; + } +}; diff --git a/assets/Stride/SDSL/OpaqueBase.sdsl b/assets/Stride/SDSL/OpaqueBase.sdsl new file mode 100644 index 0000000000..2c96caccfa --- /dev/null +++ b/assets/Stride/SDSL/OpaqueBase.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a texture for the output of the opaque render pass +/// and a helper function to extract the color of it. +/// +shader OpaqueBase : Texturing +{ + // ------------------------------------- + // Resources + // ------------------------------------- + rgroup PerView.Opaque + { + stage Texture2D OpaqueRenderTarget; + } + + float3 GetOpaqueColor(float2 uv) + { + return OpaqueRenderTarget.SampleLevel(PointSampler, uv, 0.0).xyz; + } +}; diff --git a/assets/Stride/SDSL/OutlineEffect.sdsl b/assets/Stride/SDSL/OutlineEffect.sdsl new file mode 100644 index 0000000000..36fbc41684 --- /dev/null +++ b/assets/Stride/SDSL/OutlineEffect.sdsl @@ -0,0 +1,72 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Simple fog + /// + internal shader OutlineEffect : ImageEffectShader + { + stage float2 ScreenDiffs; // .x = Width, .y = Height + + stage float zFar; + stage float zNear; + + stage float NormalWeight; + stage float DepthWeight; + stage float NormalNearCutoff; + + stage Texture2D DepthTexture; + + float3 normal_from_depth(float depth, float2 texcoords) { + const float2 offset1 = float2(0.0,ScreenDiffs.y); + const float2 offset2 = float2(ScreenDiffs.x,0.0); + + float depth1 = DepthTexture.SampleLevel(PointSampler, texcoords + offset1, 0.0).x; + float depth2 = DepthTexture.SampleLevel(PointSampler, texcoords + offset2, 0.0).x; + + float3 p1 = float3(offset1, depth1 - depth); + float3 p2 = float3(offset2, depth2 - depth); + + float3 normal = cross(p1, p2); + normal.z = -normal.z; + + return normalize(normal); + } + + float4 fetchNormalDepth(float2 tc){ + float4 nd; // return value + + // get depth + float z_b = DepthTexture.SampleLevel(PointSampler, tc, 0.0).x; + float z_n = 2.0 * z_b - 1.0; + float linearDepth = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); + + // linear depth + nd.w = DepthWeight * linearDepth; + + // normal, but skip stuff really close + nd.xyz = step(NormalNearCutoff, linearDepth) * normal_from_depth(z_b, tc) * NormalWeight; + + return nd; + } + + stage override float4 Shading() { + float4 color = Texture0.Sample(PointSampler, streams.TexCoord); + + float4 n1 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, -ScreenDiffs.y)); + float4 n2 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, ScreenDiffs.y)); + float4 n3 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, ScreenDiffs.y)); + float4 n4 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, -ScreenDiffs.y)); + + // Work out how much the normal and depth values are changing. + float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4); + + float normalDelta = dot(diagonalDelta.xyz, float3(1.0, 1.0, 1.0)); + float totalDelta = diagonalDelta.w + normalDelta * 0.4; + + return float4(color.xyz * (1.0 - clamp(totalDelta, 0.0, 1.0)), 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/Parent.sdsl b/assets/Stride/SDSL/Parent.sdsl new file mode 100644 index 0000000000..e58652e647 --- /dev/null +++ b/assets/Stride/SDSL/Parent.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Parent +{ + float baseValue = 2.0f; + Texture2D parentTexture; + + float AddBaseValue(float inValue) + { + float a0 = 0.0f, + a1 = 1.0f; + return inValue + baseValue + a0 + a1; + } +}; diff --git a/assets/Stride/SDSL/ParticleBase.sdsl b/assets/Stride/SDSL/ParticleBase.sdsl new file mode 100644 index 0000000000..617678c76f --- /dev/null +++ b/assets/Stride/SDSL/ParticleBase.sdsl @@ -0,0 +1,132 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +#ifndef UsesSoftEdge +# define UsesSoftEdge 0 +#endif + +shader ParticleBase : DepthBase, ShaderBase, Texturing, ParticleUtilities +{ + // ------------------------------------- + // streams + // ------------------------------------- + + // Shading position of the vertices/pixels + stage stream float4 Position : POSITION; + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 + // No extra streams are required +#else + stage stream float4 ScreenPosition : SCREEN_POSITION; +#endif + + // Linear depth of the position in view space in world units, used for soft edges + stage stream float ZDepth : Z_DEPTH_VALUE; + + // ------------------------------------- + // conditional streams - may or may not be present depending on existing particle fields + // ------------------------------------- + //stage stream float4 Color : COLOR; + nointerpolation stage stream float Lifetime : BATCH_LIFETIME; + nointerpolation stage stream float RandomSeed : BATCH_RANDOMSEED; // Ideally should be uint. Note! The sdsl doesn't support nointerpolation, so cast the float as int before using it + + cbuffer PerMaterial + { + stage float4 ColorScale; + + // When the value is 0 there is no occlusion (100% emissive), when it is 1 there is 100% occlusion (still limited by alpha) + stage float AlphaAdditive; + + // Z offset is how much the depth should be adjusted when rendering + stage float ZOffset; + + // 0 if disabled, equal to 1/Distance otherwise + stage float SoftEdgeInverseDistance; + } + + // ------------------------------------- + // VertexShader + // ------------------------------------- + + // Override Vertex shader main method from the ShaderBase shader + stage override void VSMain() + { + float4 worldPos = streams.Position; + + float4 viewPos = mul(worldPos, ViewMatrix); + + streams.ShadingPosition = mul(viewPos, ProjectionMatrix); + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 + // No extra code is required +#else + // TODO Check if we can optimize the code here. Possible that the .x/.w and .y/.w operations can't be optimized because of inproper interpolation. + streams.ScreenPosition = streams.ShadingPosition; +#endif + + // Z Offset + viewPos.w = 1; + viewPos.z += ZOffset; + + streams.ZDepth = viewPos.z; + + float4 viewProjPos = mul(viewPos, ProjectionMatrix); + + streams.ShadingPosition.z = (viewProjPos.z / viewProjPos.w) * streams.ShadingPosition.w; + } + + // ------------------------------------- + // PixelShader + // ------------------------------------- + + // Override Pixel shader main method from the ShaderBase shader + stage override void PSMain() + { + float4 colorTarget = Shading(); + + if (UsesSoftEdge > 0) + { + float screenWidth = ViewFrustum.x; + float screenHeight = ViewFrustum.y; + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 + var screenCoords = streams.ShadingPosition.xy; + screenCoords.x /= screenWidth; + screenCoords.y /= screenHeight; +#else + var screenCoords = (streams.ScreenPosition.xy / streams.ScreenPosition.ww) * float2(0.5, 0.5) + float2(0.5, 0.5); + screenCoords.y = 1 - screenCoords.y; +#endif + + // Account for Viewport offset and scaling + screenCoords.xy = Viewport.xy + screenCoords.xy * Viewport.zw; + + // Convert to linear depth for proper edge smoothing + float linearZOwn = -streams.ZDepth; + float linearZOpaque = GetLinearDepth(DepthStencil.Sample(Texturing.PointSampler, screenCoords).r); + + // Get the positive difference + var depthDistance = linearZOpaque - linearZOwn; + + // TODO Maybe set upper and lower bounds for more interesting effects + + // smoothstep(...) looks more natural than saturate(...): + var softEdge = smoothstep(0, 1, depthDistance * SoftEdgeInverseDistance); + colorTarget.rgba *= softEdge; + } + else + { + // Do nothing. The depth testing is enabled + } + + colorTarget.a *= AlphaAdditive; + + streams.ColorTarget = colorTarget; + } + + stage float4 Shading() + { + return ColorScale; + } + +}; diff --git a/assets/Stride/SDSL/ParticleColor.sdsl b/assets/Stride/SDSL/ParticleColor.sdsl new file mode 100644 index 0000000000..18226c4bb8 --- /dev/null +++ b/assets/Stride/SDSL/ParticleColor.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Rendering +{ + // This is a sample shader for plugging into the Shader input for ComputeColor computations + shader ParticleColor : ComputeColor + { + override float4 Compute() + { + return float4(1, 1, 1, 1); + } + }; +} diff --git a/assets/Stride/SDSL/ParticleColorStream.sdsl b/assets/Stride/SDSL/ParticleColorStream.sdsl new file mode 100644 index 0000000000..59ef3470fc --- /dev/null +++ b/assets/Stride/SDSL/ParticleColorStream.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Rendering +{ + // This is a sample shader for plugging into the Shader input for ComputeColor computations + shader ParticleColorStream : ParticleColor + { + // ------------------------------------- + // uniforms + // ------------------------------------- + stage stream float4 Color : COLOR; + + override float4 Compute() + { + return streams.Color; + } + }; +} diff --git a/assets/Stride/SDSL/ParticleComputeColorShader.sdsl b/assets/Stride/SDSL/ParticleComputeColorShader.sdsl new file mode 100644 index 0000000000..ef9562d873 --- /dev/null +++ b/assets/Stride/SDSL/ParticleComputeColorShader.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering +{ + +shader ParticleComputeColorShader : ParticleBase +{ + // ------------------------------------- + // streams + // ------------------------------------- + compose ComputeColor baseColor; + + // Shading of the sprite + stage override float4 Shading() + { + // ----------------------------------------------- + // Base particle color + // ----------------------------------------------- + float4 finalColor = base.Shading() * baseColor.Compute(); + + return finalColor; + } +}; + +} diff --git a/assets/Stride/SDSL/ParticleCustomShader.sdsl b/assets/Stride/SDSL/ParticleCustomShader.sdsl new file mode 100644 index 0000000000..306d4fbf64 --- /dev/null +++ b/assets/Stride/SDSL/ParticleCustomShader.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// By inheriting the ParticleBase we inherit Texturing and the VSMain/PSMain methods, enough to draw a uniformly colored quad + +shader ParticleCustomShader : ParticleBase +{ + // ------------------------------------- + // streams + // ------------------------------------- + + // This shader is settable by the user, and it's a binary tree made up from smaller shaders + compose ComputeColor baseColor; + + // This shader is settable by the user, and it's a binary tree made up from smaller shaders + compose ComputeColor baseIntensity; + + // Shading of the sprite - we override the base shader's Shading(), which only returns ColorScale + stage override float4 Shading() + { + // ----------------------------------------------- + // Base particle color RGB + // ----------------------------------------------- + float4 finalColor = base.Shading() * baseColor.Compute(); + + // ----------------------------------------------- + // Base particle alpha + // ----------------------------------------------- + finalColor.a = baseIntensity.Compute(); + + // Don't forget to premultiply the alpha + finalColor.rgb *= finalColor.aaa; + + return finalColor; + } +}; + diff --git a/assets/Stride/SDSL/ParticleUtilities.sdsl b/assets/Stride/SDSL/ParticleUtilities.sdsl new file mode 100644 index 0000000000..a4f3db83e9 --- /dev/null +++ b/assets/Stride/SDSL/ParticleUtilities.sdsl @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader ParticleUtilities +{ + + // ------------------------------------- + // uniforms + // ------------------------------------- + + // !When a bigger structure (float4) follow a smaller structure (float) the binding seems off + // Declare the uniforms in the order float4x4 > float4 > float > uint + cbuffer PerView + { + stage float4x4 ViewMatrix; + stage float4x4 ProjectionMatrix; + stage float4x4 ViewProjectionMatrix; + + // .x - Width, .y - Height, .z - Near, .w - Far + stage float4 ViewFrustum; + + stage float4 Viewport; + } + + stage float GetLinearDepth(float z) + { + float fastA = -ProjectionMatrix._33; // = zFar / (zFar - zNear); + float fastB = ProjectionMatrix._43; // = (-zFar * zNear) / (zFar - zNear); + return fastB / (z - fastA); + } + + // ------------------------------------- + // Randomness + // ------------------------------------- + + // Some notes on randomness + // The algorithm below is uses unsigned integer as input and generates deterministic random values with good distribution. + // Because we can't pass uint as vertex input, we use a float and cast it twice to prevent interpolation errors. + // Also, casting a huge uint value to float causes underflow, so we limit the input value to 0 .. 0xFFFF (the masking is done on the CPU side) + + static const float GelfondConst = 23.1406926327792690; // e to the power of Pi = (-1) to the power of -i + static const float GelfondSchneiderConst = 2.6651441426902251; // 2 to the power of sqrt(2) + static const float2 Gelfond = float2(GelfondConst, GelfondSchneiderConst); + static const float Numerator = 123456789; + + float GetRandom(float fSeed) + { + // Cast to int once to prevent interpolation errors + int uSeed = (int) (fSeed); + fSeed = (float) uSeed; + + float2 rand2 = float2(cos(fSeed), sin(fSeed)); + + float dotProduct = dot(rand2, Gelfond); + + return frac(fmod(Numerator, 1e-7 + 256.f * dotProduct)); + } +}; + diff --git a/assets/Stride/SDSL/PickingShader.sdsl b/assets/Stride/SDSL/PickingShader.sdsl new file mode 100644 index 0000000000..934e4b9c36 --- /dev/null +++ b/assets/Stride/SDSL/PickingShader.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering +{ + /// + /// A shader used to output the id of the model component, mesh and material for a particular RenderMesh + /// + shader PickingShader : ShaderBase + { + cbuffer PerDraw + { + stage float4 PickingData; + } + + stage override void PSMain() + { + float modelComponentId = PickingData.x + (min(streams.InstanceID, 1023.0) / 1024.0); + float meshMaterialIndex = PickingData.y; + streams.ColorTarget = float4(modelComponentId, meshMaterialIndex, 1, 1); + } + }; +} diff --git a/assets/Stride/SDSL/PointDepth.sdsl b/assets/Stride/SDSL/PointDepth.sdsl new file mode 100644 index 0000000000..482ab118e4 --- /dev/null +++ b/assets/Stride/SDSL/PointDepth.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Constantlty outputs the depth of a given point in the image. + /// + shader PointDepth: ImageEffectShader + { + float2 Coordinate; + + stage override float4 Shading() + { + return Texture0.Sample(Sampler, Coordinate).y; + } + }; +} diff --git a/assets/Stride/SDSL/PositionHStream4.sdsl b/assets/Stride/SDSL/PositionHStream4.sdsl new file mode 100644 index 0000000000..435b723332 --- /dev/null +++ b/assets/Stride/SDSL/PositionHStream4.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines a world space position stream. +/// +shader PositionHStream4 +{ + stream float4 PositionH : POSITIONH; +}; diff --git a/assets/Stride/SDSL/PositionStream.sdsl b/assets/Stride/SDSL/PositionStream.sdsl new file mode 100644 index 0000000000..a1523f093d --- /dev/null +++ b/assets/Stride/SDSL/PositionStream.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Gets the correct shader to have a position stream in a float4 (even if attribute is a float2). +/// +/// +/// PDX_USE_FLOAT_INPUT: Macro - Switch between float2 of float4 position attribute. +/// +#ifdef PDX_USE_FLOAT2_INPUT_INPUT +shader PositionStream : PositionStream2 +{ +}; +#else +shader PositionStream : PositionStream4 +{ +}; +#endif diff --git a/assets/Stride/SDSL/PositionStream2.sdsl b/assets/Stride/SDSL/PositionStream2.sdsl new file mode 100644 index 0000000000..150c3bc8bb --- /dev/null +++ b/assets/Stride/SDSL/PositionStream2.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines streams for object space position when the corresponding attribute is a float2. Sets its value in a float4. +/// +shader PositionStream2 : ShaderBase +{ + // The position attribute + stage stream float2 Position2 : POSITION; + + // The position as a float4 + stage stream float4 Position : ExpandedPosition4; + + override stage void VSMain() + { + streams.Position = float4(streams.Position2, 0.0f, 1.0f); + base.VSMain(); + } +}; diff --git a/assets/Stride/SDSL/PositionStream4.sdsl b/assets/Stride/SDSL/PositionStream4.sdsl new file mode 100644 index 0000000000..cde967ff1c --- /dev/null +++ b/assets/Stride/SDSL/PositionStream4.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines streams for object space and world space position. +/// +shader PositionStream4 +{ + // The position attribute + stage stream float4 Position : POSITION; + + // The position in world space + stage stream float4 PositionWS : POSITION_WS; + + // The depth in view space + stage stream float DepthVS : DEPTH_VS; +}; diff --git a/assets/Stride/SDSL/PositionVertexTransform.sdsl b/assets/Stride/SDSL/PositionVertexTransform.sdsl new file mode 100644 index 0000000000..454dacb2a2 --- /dev/null +++ b/assets/Stride/SDSL/PositionVertexTransform.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Provides a stream with the view space position (vertex or fragment) from the vertex attributes. +/// +shader PositionVertexTransform : ShaderBase, Transformation, PositionStream +{ + stage override void VSMain() + { + base.VSMain(); + streams.PositionWS = mul(streams.Position, World); + } +}; diff --git a/assets/Stride/SDSL/PostEffectBoundingRay.sdsl b/assets/Stride/SDSL/PostEffectBoundingRay.sdsl new file mode 100644 index 0000000000..230dd9b0be --- /dev/null +++ b/assets/Stride/SDSL/PostEffectBoundingRay.sdsl @@ -0,0 +1,98 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/// +/// TSampleCount: generic int - number of iterations. +/// +shader PostEffectBoundingRay : ImageEffectShader, DepthBase, Transformation, PositionStream4 +{ + float3 ComputeColorOut() + { + return 0; + } + + float3 ComputeColorIn(float4 positionWS, float stepSize, int stepIndex) + { + return 0; + } + + int HashXYZ(float3 input) + { + return int(input.z * 313 + input.x * 1039 + input.y * 638359); + } + + float RayStepJitter(float3 input, float stepSize) + { + return stepSize * Math.FastRandom(HashXYZ(input)); + } + + float4 ComputeFinalColor(float3 lightAcc) + { + return float4(lightAcc.xxx, 1.0f); + } + + stage override void PSMain() + { + // minmax.x = min + // minmax.y = max + float2 minmax = Texture0.Sample(PointSampler, streams.TexCoord).xy; + + float backsideMin = Texture1.Sample(PointSampler, 0.0f).x; + if(backsideMin < 1.0f) + minmax.x = 0.0f; + + // Need at least a maximum value for this pixel to be contained in the bounding box + if(minmax.y < 1.0f) + { + float currentZ = GetZProjDepthFromUV(streams.TexCoord); + float minZ = minmax.x; + float maxZ = min(minmax.y, currentZ); + + float minDistance = ComputeDepthFromZProj(minZ); + float maxDistance = ComputeDepthFromZProj(maxZ); + + // Compute world space direction and position of the ending position + float4 positionClipSpace = float4((1.0f - streams.TexCoord.xy * 2.0f) * float2(-1.0f, 1.0f), maxZ, 1.0f); + float4 positionVS = mul(positionClipSpace, ProjectionInverse); + positionVS.xyzw /= positionVS.w; + float4 endingPosition = mul(positionVS, ViewInverse); + float3 endingPositionDelta = endingPosition.xyz - Eye.xyz; + float4 directionWS = float4(endingPositionDelta, 0.0f); + directionWS = normalize(directionWS); + + // Compute depth slope and apply it to the world space direction so it can be multiplied by depth distances + float depthSlope = length(endingPositionDelta) / maxDistance; + directionWS *= depthSlope; + + float stepRange = (maxDistance - minDistance); + float stepSize = stepRange / (float)TSampleCount; + + float3 lightResult = 0.0f; + + // Expected by the directional shadow map to compute the cascades + streams.DepthVS = minDistance; + if(maxDistance > minDistance) + { + // Recalculate max distance by jittering the length of the ray to avoid banding artifacts + stepSize = (maxDistance - minDistance) / (float)TSampleCount; + + // Starting position + float4 positionWS = endingPosition + (RayStepJitter(positionVS.xyz, stepSize)-stepRange) * directionWS; + streams.DepthVS = minDistance; + + for(int i = 0; i < TSampleCount; i++) + { + lightResult += this.ComputeColorIn(positionWS, stepSize, i); + positionWS += stepSize * directionWS; + streams.DepthVS += stepSize; + } + } + + streams.ColorTarget = ComputeFinalColor(lightResult); + } + else // Outside the bounding box + { + streams.ColorTarget = ComputeFinalColor(this.ComputeColorOut()); + } + } +}; diff --git a/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl b/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl new file mode 100644 index 0000000000..3a20edde68 --- /dev/null +++ b/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl @@ -0,0 +1,61 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Shader performing radiance GGX pre-filtering + /// + shader RadiancePrefilteringGGXNoComputeShader : Math, ImageEffectShader + { + // the input texture containing the radiance + int RadianceMapSize; + + TextureCube RadianceMap; + + // The number of mipmap available + stage float MipmapCount; + + // The roughness of the GGX distribution + stage float Roughness; + + // The current face + stage int Face; + + // compute the pre-filtered environment map for input (group) direction + override stage float4 Shading() + { + // Calculate the direction of the texel in the cubemap + float3 R = normalize(CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, Face)); + + float4 prefilteredSample = 0; + + for (int sampleIndex = 0; sampleIndex < TNbOfSamples; sampleIndex++) + { + // Perform one sampling, calculate pre-filtered color and weight contribution + var xi = Hammersley.GetSamplePlane(sampleIndex, TNbOfSamples); + var H = ImportanceSamplingGGX.GetSample(xi, Roughness, R); + + float3 L = 2 * dot(R, H) * H - R; + float NoL = saturate(dot(R, L)); + float pdf = BRDFMicrofacet.NormalDistributionGGX(Roughness*Roughness, NoL) / 4; + float omegaS = 1.0 / (TNbOfSamples * pdf); + float omegaP = 4.0 * Math.PI / (6.0 * RadianceMapSize * RadianceMapSize) ; + float mipLevel = clamp(0.5 * log2(omegaS / omegaP) , 0, MipmapCount); + + float3 prefilteredColor = 0; + float weight = 0; + if (NoL > 0) + { + weight = NoL; + prefilteredColor = RadianceMap.SampleLevel(Texturing.LinearSampler, L, mipLevel).rgb * weight; + } + + // Stock the result in group-shared memory + prefilteredSample += float4(prefilteredColor, weight); + } + + return prefilteredSample / prefilteredSample.w; + } + }; +} diff --git a/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl b/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl new file mode 100644 index 0000000000..56e5d490a3 --- /dev/null +++ b/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl @@ -0,0 +1,80 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Shader performing radiance GGX pre-filtering + /// + shader RadiancePrefilteringGGXShader : Math, ComputeShaderBase + { + // the input texture containing the radiance + int RadianceMapSize; + TextureCube RadianceMap; + + // the output cube map containing the filtered radiance. + RWTexture2DArray FilteredRadiance; + + // Shared memory for summing SH-Basis coefficients for a block + groupshared float4 PrefilteredSamples[TNbOfSamples]; + + // The number of mipmap available + stage float MipmapCount; + + // The roughness of the GGX distribution + stage float Roughness; + + // compute the pre-filtered environment map for input (group) direction + override void Compute() + { + int2 pixel = streams.GroupId.xy; + int face = streams.GroupId.z; + int threadId = streams.GroupThreadId.x; + + // Calculate the uv of the pixel in [0, 1] + float u = (pixel.x + 0.5) / float(streams.ThreadGroupCount.x); + float v = (pixel.y + 0.5) / float(streams.ThreadGroupCount.y); + + // Calculate the direction of the texel in the cubemap + float3 R = normalize(CubemapUtils.ConvertTexcoordsNoFlip(float2(u, v), face)); + + // Perform one sampling, calculate pre-filtered color and weight contribution + var xi = Hammersley.GetSamplePlane(threadId, TNbOfSamples); + var H = ImportanceSamplingGGX.GetSample(xi, Roughness, R); + + float3 L = 2 * dot( R, H ) * H - R; + float NoL = saturate( dot( R, L ) ); + float pdf = BRDFMicrofacet.NormalDistributionGGX(Roughness*Roughness, NoL) / 4; + float omegaS = 1.0 / ( TNbOfSamples * pdf ); + float omegaP = 4.0 * Math.PI / (6.0 * RadianceMapSize * RadianceMapSize ) ; + float mipLevel = clamp (0.5 * log2 ( omegaS / omegaP ) , 0, MipmapCount ); + + float3 prefilteredColor = 0; + float weight = 0; + if( NoL > 0 ) + { + weight = NoL; + prefilteredColor = RadianceMap.SampleLevel(Texturing.LinearSampler, L, mipLevel).rgb * weight; + } + + // Stock the result in group-shared memory + PrefilteredSamples[threadId] = float4(prefilteredColor, weight); + GroupMemoryBarrierWithGroupSync(); + + // Perform the sums among the group + for(int s = TNbOfSamples / 2; s > 0; s >>= 1) + { + if(threadId < s) + PrefilteredSamples[threadId] += PrefilteredSamples[threadId + s]; + + GroupMemoryBarrierWithGroupSync(); + } + + // Let the first thread stock the final result in output texture + if(IsFirstThreadOfGroup()) + { + FilteredRadiance[float3(pixel.xy, face)] = PrefilteredSamples[0] / PrefilteredSamples[0].w; + } + } + }; +} diff --git a/assets/Stride/SDSL/RangeCompressorShader.sdsl b/assets/Stride/SDSL/RangeCompressorShader.sdsl new file mode 100644 index 0000000000..0a75198290 --- /dev/null +++ b/assets/Stride/SDSL/RangeCompressorShader.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + shader RangeCompressorShader : ImageEffectShader + { + stage override float4 Shading() + { + float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; + + // compute luma from HDR value: + float3 ntsc = float3(0.2126, 0.7152, 0.0722); + float relativeLuminance = dot(ntsc, color); + float perceptiveLuma = sqrt(relativeLuminance); + + // tone to "non-lossy" LDR: + float targetRange = 1.0; + float maxComponent = max(max(color.r, color.g), color.b); + // http://graphicrants.blogspot.jp/2013/12/tone-mapping.html + float3 brianKarisToned = color / (1 + maxComponent / targetRange); + + float3 mapped = brianKarisToned; + // and we don't apply gamma. because of big outlining artefact around [0-1] range objects in front of high [10-80] range emissive objects. + + // write output for FXAA: + return float4(mapped, perceptiveLuma); + } + }; +} + diff --git a/assets/Stride/SDSL/RangeDecompressorShader.sdsl b/assets/Stride/SDSL/RangeDecompressorShader.sdsl new file mode 100644 index 0000000000..44bc993275 --- /dev/null +++ b/assets/Stride/SDSL/RangeDecompressorShader.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + shader RangeDecompressorShader : ImageEffectShader + { + stage override float4 Shading() + { + float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; + + float3 linearColor = color; + + // reverse karis tone map: + float targetRange = 1.0; + float maxComponent = max(max(linearColor.r, linearColor.g), linearColor.b); + float3 reverseKaris = linearColor / (1 - maxComponent / targetRange); + + // write output for the rest of the post effects: + return float4(reverseKaris, 1.0); + } + }; +} + diff --git a/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl b/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl new file mode 100644 index 0000000000..51f48836cb --- /dev/null +++ b/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + /// + /// Sample a cubemap using the MaterialPixelShadingStream roughness parameter. + /// + shader RoughnessCubeMapEnvironmentColor : IComputeEnvironmentColor, Texturing, MaterialPixelShadingStream + { + cbuffer PerView.Lighting + { + float MipCount; + } + + rgroup PerView.Lighting + { + TextureCube CubeMap; + } + + override float4 Compute(float3 direction) + { + var alpha = streams.alphaRoughness; + var mipLevel = sqrt(alpha) * MipCount; + + return CubeMap.SampleLevel(LinearSampler, direction, mipLevel); + } + }; +} diff --git a/assets/Stride/SDSL/SSLRBlurPass.sdsl b/assets/Stride/SDSL/SSLRBlurPass.sdsl new file mode 100644 index 0000000000..fdac658863 --- /dev/null +++ b/assets/Stride/SDSL/SSLRBlurPass.sdsl @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Blur Pass + /// + shader SSLRBlurPass : ImageEffectShader + { + // Options: + // 3 - 5-tap blur + // 5 - 9-tap blur + #define SSR_BLUR_STEPS 3 + + override stage float4 Shading() + { + #if CONVOLVE_VERTICAL + const float2 offsets[SSR_BLUR_STEPS] = { + #if SSR_BLUR_STEPS == 3 + {0, 0}, + {1.3846153846, 0}, + {3.2307692308, 0} + #elif SSR_BLUR_STEPS == 5 + {0, 0}, + {1, 0}, + {2, 0}, + {3, 0}, + {4, 0} + #endif + }; + #else + const float2 offsets[SSR_BLUR_STEPS] = { + #if SSR_BLUR_STEPS == 3 + {0, 0}, + {0, 1.3846153846}, + {0, 3.2307692308} + #elif SSR_BLUR_STEPS == 5 + {0, 0}, + {0, 1}, + {0, 2}, + {0, 3}, + {0, 4} + #endif + }; + #endif + const float weights[SSR_BLUR_STEPS] = { + #if SSR_BLUR_STEPS == 3 + 0.2270270270, + 0.3162162162, + 0.0702702703 + #elif SSR_BLUR_STEPS == 5 + 0.2270270270, + 0.1945945946, + 0.1216216216, + 0.0540540541, + 0.0162162162 + #endif + }; + + float3 color = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * weights[0]; + + for (int i = 1; i < SSR_BLUR_STEPS; i++) + { + float2 texCoordOffset = offsets[i] * Texture0TexelSize; + + color += (Texture0.Sample(LinearSampler, streams.TexCoord + texCoordOffset).rgb + + Texture0.Sample(LinearSampler, streams.TexCoord - texCoordOffset).rgb) + * weights[i]; + } + + return float4(color, 1.0f); + } + }; + + effect SSLRBlurPassEffectH + { + mixin macro CONVOLVE_VERTICAL = 0; + mixin SSLRBlurPass; + }; + + effect SSLRBlurPassEffectV + { + mixin macro CONVOLVE_VERTICAL = 1; + mixin SSLRBlurPass; + }; +} diff --git a/assets/Stride/SDSL/SSLRCombinePass.sdsl b/assets/Stride/SDSL/SSLRCombinePass.sdsl new file mode 100644 index 0000000000..9cb48d6731 --- /dev/null +++ b/assets/Stride/SDSL/SSLRCombinePass.sdsl @@ -0,0 +1,75 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Combine Pass + /// + shader SSLRCombinePass : ImageEffectShader, SSLRCommon, Utilities + { + // Enable/disable blurring SSR during sampling results and mixing with reflections buffer + #define SSR_MIX_BLUR 1 + + float3 SampleSSR(float2 uv) + { + float4 ssr = Texture4.SampleLevel(LinearSampler, uv, 0); + + #if SSR_MIX_BLUR + ssr += Texture4.SampleLevel(LinearSampler, uv + float2(0, Texture4TexelSize.y), 0); + ssr += Texture4.SampleLevel(LinearSampler, uv - float2(0, Texture4TexelSize.y), 0); + ssr += Texture4.SampleLevel(LinearSampler, uv + float2(Texture4TexelSize.x, 0), 0); + ssr += Texture4.SampleLevel(LinearSampler, uv - float2(Texture4TexelSize.x, 0), 0); + ssr *= (1.0f / 5.0f); + #endif + + return ssr; + } + + // [Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II"] + float3 EnvBRDFApprox(float3 specularColor, float roughness, float NoV) + { + // Approximate version, base for pre integrated version + const half4 c0 = {-1, -0.0275, -0.572, 0.022}; + const half4 c1 = {1, 0.0425, 1.04, -0.04}; + half4 r = roughness * c0 + c1; + half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; + half2 AB = half2(-1.04, 1.04) * a004 + r.zw; + return specularColor * AB.x + saturate(50.0 * specularColor.g) * AB.y; + } + + override stage float4 Shading() + { + // Inputs Mapping: + // Texture0 - Scene Color + // Texture1 - Depth + // Texture2 - World Space Normals + // Texture3 - Specular Color + Roughness + // Texture4 - Reflections result + + float2 uv = streams.TexCoord; + + // Sample inputs + float4 sceneColor = Texture0.SampleLevel(PointSampler, uv, 0); + float3 ssr = SampleSSR(uv); + float3 positionWS = ComputeWorldPosition(uv); + + // Calculate view space normal vector + float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); + float3 normalWS = DecodeNormal(normalsBuffer.rgb); + float3 normalVS = mul(normalWS, (float3x3)V); + + // Sample material specular color and roughness + float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); + float3 specularColor = specularRoughnessBuffer.rgb; + float roughness = specularRoughnessBuffer.a; + + // Calculate reflection color + float3 viewVector = normalize(CameraPosWS.xyz - positionWS); + float NoV = saturate(dot(normalWS, viewVector)); + sceneColor.rgb += ssr * EnvBRDFApprox(specularColor, roughness, NoV); + + return sceneColor; + } + }; +} diff --git a/assets/Stride/SDSL/SSLRCommon.sdsl b/assets/Stride/SDSL/SSLRCommon.sdsl new file mode 100644 index 0000000000..5ea5442a4e --- /dev/null +++ b/assets/Stride/SDSL/SSLRCommon.sdsl @@ -0,0 +1,103 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader with common variables and functions + /// + shader SSLRCommon : ImageEffectShader, Utilities, NormalPack + { + cbuffer Data + { + stage float MaxColorMiplevel; + stage float TraceSizeMax; + stage float MaxTraceSamples; + //stage float Padding0; + + stage float RoughnessFade; + stage float TemporalTime; + stage float BRDFBias; + stage float ViewFarPlane; + + stage float4 ViewInfo; + + stage float3 CameraPosWS; + stage float WorldAntiSelfOcclusionBias; + + stage float4x4 V; + stage float4x4 IVP; + }; + + // Sample raw device depth buffer + float SampleZ(in float2 uv) + { + return Texture1.SampleLevel(PointSampler, uv, 0).r; + } + + // Linearize raw device depth + float LinearizeZ(in float depth) + { + return ViewInfo.w / (depth - ViewInfo.z); + } + + // Sample linear depth + float SampleDepth(in float2 uv) + { + float depth = SampleZ(uv); + return LinearizeZ(depth); + } + + // 1:-1 to 0:1 + float2 ClipToUv(float2 clipPos) + { + return clipPos * float2(0.5, -0.5) + float2(0.5, 0.5); + } + + // 0:1 to 1:-1 + float2 UvToClip(float2 uv) + { + return uv * float2(2, -2) + float2(-1, 1); + } + + float3 ComputeWorldPosition(float2 uv, float rawDepth) + { + float4 clipPos = float4(UvToClip(uv), rawDepth, 1); + float4 pos = mul(clipPos, IVP); + return pos.xyz / pos.w; + } + + float3 ComputeWorldPosition(float2 uv) + { + float rawDepth = SampleZ(uv); + return ComputeWorldPosition(uv, rawDepth); + } + + float3 ComputeViewPosition(float2 uv, float rawDepth) + { + float eyeZ = LinearizeZ(rawDepth) * ViewFarPlane; + return float3(UvToClip(uv) * ViewInfo.xy * eyeZ, eyeZ); + } + + float3 SampleViewPosition(float2 uv) + { + float rawDepth = SampleZ(uv); + return ComputeViewPosition(uv, rawDepth); + } + + float3 ScreenToView(float2 uv, float depth) + { + return float3(UvToClip(uv) * ViewInfo.xy, depth); + } + + float max2(float2 v) + { + return max(v.x, v.y); + } + + float2 RandN2(float2 pos, float2 random) + { + return frac(sin(dot(pos.xy + random, float2(12.9898, 78.233))) * float2(43758.5453, 28001.8384)); + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/SSLRDepthPass.sdsl b/assets/Stride/SDSL/SSLRDepthPass.sdsl new file mode 100644 index 0000000000..61437a16ee --- /dev/null +++ b/assets/Stride/SDSL/SSLRDepthPass.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Depth Pass + /// + shader SSLRDepthPass : ImageEffectShader + { + override stage float4 Shading() + { + float depth = Texture0.Sample(PointSampler, streams.TexCoord).r; + return depth.xxxx; + } + }; +} diff --git a/assets/Stride/SDSL/SSLRRayTracePass.sdsl b/assets/Stride/SDSL/SSLRRayTracePass.sdsl new file mode 100644 index 0000000000..3c9bb44b55 --- /dev/null +++ b/assets/Stride/SDSL/SSLRRayTracePass.sdsl @@ -0,0 +1,191 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Ray Trace Pass + /// + shader SSLRRayTracePass : ImageEffectShader, SSLRCommon, NormalPack, Math + { + cbuffer Data + { + stage float EdgeFadeFactor; + + stage float4x4 VP; + }; + + // go into clip space (-1:1 from bottom/left to up/right) + float3 ProjectWorldToClip(float3 wsPos) + { + float4 uv = mul(float4(wsPos, 1), VP); + uv /= uv.w; + return uv.xyz; + } + + // go into UV space. (0:1 from top/left to bottom/right) + float3 ProjectWorldToUv(float3 wsPos) + { + float3 pos = ProjectWorldToClip(wsPos); + return float3(ClipToUv(pos.xy), pos.z); + } + + float4 TangentToWorld(float3 N, float4 H) + { + float3 UpVector = abs(N.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 T = normalize( cross( UpVector, N ) ); + float3 B = cross( N, T ); + + return float4((T * H.x) + (B * H.y) + (N * H.z), H.w); + } + + // Brian Karis, Epic Games "Real Shading in Unreal Engine 4" + float4 ImportanceSampleGGX(float2 Xi, float Roughness) + { + float m = Roughness * Roughness; + float m2 = m * m; + + float Phi = 2 * PI * Xi.x; + + float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (m2 - 1.0) * Xi.y)); + float SinTheta = sqrt(max(1e-5, 1.0 - CosTheta * CosTheta)); + + float3 H; + H.x = SinTheta * cos(Phi); + H.y = SinTheta * sin(Phi); + H.z = CosTheta; + + float d = (CosTheta * m2 - CosTheta) * CosTheta + 1; + float D = m2 / (PI * d * d); + float pdf = D * CosTheta; + + return float4(H, pdf); + } + + float RayAttenBorder(float2 pos, float value) + { + float borderDist = min(1.0 - max(pos.x, pos.y), min(pos.x, pos.y)); + return saturate(borderDist > value ? 1.0 : borderDist / value); + } + + override stage float4 Shading() + { + // Inputs Mapping: + // Texture0 - Scene Color + // Texture1 - Depth + // Texture2 - World Space Normals + // Texture3 - Specular Color + Roughness + + float2 uv = streams.TexCoord; + + // Sample material roughness + float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); + float roughness = specularRoughnessBuffer.a; + + // Get view space position + float depth = SampleZ(uv); + float3 positionVS = ComputeViewPosition(uv, depth); + + // Reject invalid pixels + if(positionVS.z > 100.0f || roughness > RoughnessFade) + return 0; + + // Calculate view space normal vector + float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); + float3 normalWS = DecodeNormal(normalsBuffer.rgb); + float3 normalVS = mul(normalWS, (float3x3)V); + + // Randomize it a little + float2 jitter = RandN2(uv, TemporalTime); + float2 Xi = jitter; + Xi.y = lerp(Xi.y, 0.0, BRDFBias); + + float4 H = TangentToWorld(normalWS, ImportanceSampleGGX(Xi, roughness)); + + // Calculate normalized view space reflection vector + float3 reflectVS = normalize(reflect(positionVS, normalVS)); + + if(positionVS.z < 1.0 && reflectVS.z < 0.4) + return 0; + + float3 positionWS = ComputeWorldPosition(uv, depth); + float3 viewWS = normalize(positionWS - CameraPosWS.xyz); + float3 reflectWS = reflect(viewWS, H.xyz); + + float3 startWS = positionWS + normalWS * WorldAntiSelfOcclusionBias; + float3 startUV = ProjectWorldToUv(startWS); + float3 endUV = ProjectWorldToUv(startWS + reflectWS); + + float3 rayUV = endUV - startUV; + float screenStep = Texture1TexelSize.x; + rayUV *= screenStep / max2(abs(rayUV.xy)); + float3 startUv = startUV + rayUV * 2; + + float3 currOffset = startUv; + float3 rayStep = rayUV * 2; + + // Calculate number of samples + float3 samplesToEdge = ((sign(rayStep.xyz) * 0.5 + 0.5) - currOffset.xyz) / rayStep.xyz; + samplesToEdge.x = min(samplesToEdge.x, min(samplesToEdge.y, samplesToEdge.z)) * 1.05f; + float numSamples = min(MaxTraceSamples, samplesToEdge.x); + rayStep *= samplesToEdge.x / numSamples; + + // Calculate depth diffrence error + float depthDiffError = 1.3f * abs(rayStep.z); + + // Ray trace + float currSampleIndex = 0; + float currSample, depthDiff; + [loop] + while (currSampleIndex < numSamples) + { + // Sample depth buffer and calculate depth diffrence + currSample = SampleZ(currOffset.xy); + depthDiff = currOffset.z - currSample; + + // Check intersection + if(depthDiff >= 0) + { + if (depthDiff < depthDiffError) + { + break; + } + else + { + currOffset -= rayStep; + rayStep *= 0.5; + } + } + + // Move forward + currOffset += rayStep; + currSampleIndex++; + } + + // Check if has valid result after ray traycing + if(currSampleIndex >= numSamples || currOffset.z > 0.999) + { + // All samples done but no result + return 0; + } + + float2 hitUV = currOffset.xy; + + // Fade rays close to screen edge + const float fadeStart = 0.9f; + const float fadeEnd = 1.0f; + const float fadeDiffRcp = 1.0f / (fadeEnd - fadeStart); + float2 boundary = abs(hitUV - float2(0.5f, 0.5f)) * 2.0f; + float fadeOnBorder = 1.0f - saturate((boundary.x - fadeStart) * fadeDiffRcp); + fadeOnBorder *= 1.0f - saturate((boundary.y - fadeStart) * fadeDiffRcp); + fadeOnBorder = smoothstep(0.0f, 1.0f, fadeOnBorder); + fadeOnBorder *= RayAttenBorder(hitUV, EdgeFadeFactor); + + // Fade rays on high roughness + float roughnessFade = saturate((RoughnessFade - roughness) * 20); + + // Output: xy: hitUV, z: hitMask, w: unused + return float4(hitUV, fadeOnBorder * roughnessFade, 0); + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/SSLRResolvePass.sdsl b/assets/Stride/SDSL/SSLRResolvePass.sdsl new file mode 100644 index 0000000000..9218b2839e --- /dev/null +++ b/assets/Stride/SDSL/SSLRResolvePass.sdsl @@ -0,0 +1,108 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Resolve Pass + /// + shader SSLRResolvePass : ImageEffectShader, SSLRCommon, NormalPack, Math, BRDFMicrofacet + { + static const float2 Offsets[8] = + { + float2( 0, 0), + float2( 2, -2), + float2(-2, -2), + float2( 0, 2), + float2(-2, 0), + float2( 0, -2), + float2( 2, 0), + float2( 2, 2), + }; + + override stage float4 Shading() + { + // Inputs Mapping: + // Texture0 - Scene Color (with blurred mip maps chain or without) + // Texture1 - Depth + // Texture2 - World Space Normals + // Texture3 - Specular Color + Roughness + // Texture4 - Ray Trace result + + float2 uv = streams.TexCoord; + + // Early out for pixels with no hit result + if(Texture4.SampleLevel(LinearSampler, uv, 0).z <= 0.001) + return 0; + + // Sample material roughness + float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); + float roughness = specularRoughnessBuffer.a; + + // Get view space position + float depth = SampleZ(uv); + float3 positionVS = ComputeViewPosition(uv, depth); + + // Reject invalid pixels + if(positionVS.z > 100.0f || roughness > RoughnessFade) + return 0; + + // Calculate view space normal vector + float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); + float3 normalWS = DecodeNormal(normalsBuffer.rgb); + + // Calculate view vector + float3 positionWS = ComputeWorldPosition(uv, depth); + float3 viewVector = normalize(CameraPosWS.xyz - positionWS); + + // Randomize it a little + float2 random = RandN2(uv, TemporalTime); + float2 blueNoise = random.xy * 2.0 - 1.0; + float2x2 offsetRotationMatrix = float2x2(blueNoise.x, blueNoise.y, -blueNoise.y, blueNoise.x); + + float NdotV = saturate(dot(normalWS, viewVector)); + float coneTangent = lerp(0.0, roughness * 5 * (1.0 - BRDFBias), pow(NdotV, 1.5) * sqrt(roughness)); + + // Resolve samples + float4 result = 0.0; + for(int i = 0; i < ResolveSamples; i++) + { + float2 offsetUV = Offsets[i] * Texture4TexelSize; + offsetUV = mul(offsetRotationMatrix, offsetUV); + + // "uv" is the location of the current (or "local") pixel. We want to resolve the local pixel using + // intersections spawned from neighboring pixels. The neighboring pixel is this one: + float2 neighborUv = uv + offsetUV; + + // Now we fetch the intersection point + float4 hitPacked = Texture4.SampleLevel(LinearSampler, neighborUv, 0); + float2 hitUv = hitPacked.xy; + float hitMask = hitPacked.z; + + float intersectionCircleRadius = coneTangent * length(hitUv - uv); + float mip = clamp(log2(intersectionCircleRadius * TraceSizeMax), 0.0, MaxColorMiplevel); + + float4 sampleColor = float4(Texture0.SampleLevel(LinearSampler, hitUv, mip).rgb, 1); + if(ReduceHighlights) + sampleColor.rgb /= 1 + Luminance(sampleColor.rgb); + + result += sampleColor * hitMask; + } + + // Calculate final result value + result /= ResolveSamples; + if(ReduceHighlights) + result.rgb /= 1 - Luminance(result.rgb); + result.rgb *= result.a; + + return max(1e-5, result); + } + }; + + effect SSLRResolvePassEffect + { + using params SSLRKeys; + + mixin SSLRResolvePass; + } +} \ No newline at end of file diff --git a/assets/Stride/SDSL/SSLRTemporalPass.sdsl b/assets/Stride/SDSL/SSLRTemporalPass.sdsl new file mode 100644 index 0000000000..dc1f203315 --- /dev/null +++ b/assets/Stride/SDSL/SSLRTemporalPass.sdsl @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Screen Space Local Reflections shader for Temporal Pass + /// + shader SSLRTemporalPass : ImageEffectShader, Texturing + { + stage float TemporalResponse; + stage float TemporalScale; + stage float4x4 IVP; // Current frame inverse view*projection matrix + stage float4x4 prevVP; // Previous frame view*projection matrix + + // 1:-1 to 0:1 + float2 ClipToUv(float2 clipPos) + { + return clipPos * float2(0.5, -0.5) + float2(0.5, 0.5); + } + + // 0:1 to 1:-1 + float2 UvToClip(float2 uv) + { + return uv * float2(2, -2) + float2(-1, 1); + } + + float3 ComputeWorldPosition(float2 uv, float rawDepth) + { + float4 clipPos = float4(UvToClip(uv), rawDepth, 1); + float4 pos = mul(clipPos, IVP); + return pos.xyz / pos.w; + } + + float3 SampleWorldPosition(float2 uv) + { + float rawDepth = Texture2.SampleLevel(PointSampler, uv, 0).r; + return ComputeWorldPosition(uv, rawDepth); + } + + override stage float4 Shading() + { + // Inputs Mapping: + // Texture0 - Resolved reflections + // Texture1 - Previous frame resolved reflections + // Texture2 - Depth + + float2 uv = streams.TexCoord; + + // Reconstruct previous frame screen space position + float3 posWS = SampleWorldPosition(uv); + float4 prevSS = mul(float4(posWS, 1), prevVP); + prevSS.xy /= prevSS.w; + + float2 prevUV = ClipToUv(prevSS.xy); + + float4 current = Texture0.SampleLevel(LinearSampler, uv, 0); + float4 previous = Texture1.SampleLevel(LinearSampler, prevUV, 0); + + float2 du = float2(Texture0TexelSize.x, 0.0); + float2 dv = float2(0.0, Texture0TexelSize.y); + + float4 currentTopLeft = Texture0.SampleLevel(LinearSampler, uv.xy - dv - du, 0); + float4 currentTopCenter = Texture0.SampleLevel(LinearSampler, uv.xy - dv, 0); + float4 currentTopRight = Texture0.SampleLevel(LinearSampler, uv.xy - dv + du, 0); + float4 currentMiddleLeft = Texture0.SampleLevel(LinearSampler, uv.xy - du, 0); + float4 currentMiddleCenter = Texture0.SampleLevel(LinearSampler, uv.xy, 0); + float4 currentMiddleRight = Texture0.SampleLevel(LinearSampler, uv.xy + du, 0); + float4 currentBottomLeft = Texture0.SampleLevel(LinearSampler, uv.xy + dv - du, 0); + float4 currentBottomCenter = Texture0.SampleLevel(LinearSampler, uv.xy + dv, 0); + float4 currentBottomRight = Texture0.SampleLevel(LinearSampler, uv.xy + dv + du, 0); + + float4 currentMin = min(currentTopLeft, min(currentTopCenter, min(currentTopRight, min(currentMiddleLeft, min(currentMiddleCenter, min(currentMiddleRight, min(currentBottomLeft, min(currentBottomCenter, currentBottomRight)))))))); + float4 currentMax = max(currentTopLeft, max(currentTopCenter, max(currentTopRight, max(currentMiddleLeft, max(currentMiddleCenter, max(currentMiddleRight, max(currentBottomLeft, max(currentBottomCenter, currentBottomRight)))))))); + + float scale = TemporalScale; + + float4 center = (currentMin + currentMax) * 0.5f; + currentMin = (currentMin - center) * scale + center; + currentMax = (currentMax - center) * scale + center; + + previous = clamp(previous, currentMin, currentMax); + + return lerp(current, previous, TemporalResponse); + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/ScreenPositionBase.sdsl b/assets/Stride/SDSL/ScreenPositionBase.sdsl new file mode 100644 index 0000000000..a239e4b8d3 --- /dev/null +++ b/assets/Stride/SDSL/ScreenPositionBase.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Declares and sets the value of the screen position of the fragment ({x,y} in [-1,1], z in [0,1]). +/// Be careful when to include this shader because ShadingPosition should be correct at this point. Include this shader at the end of the mixin list. +/// +shader ScreenPositionBase : ShaderBase +{ + // The position in screen space + stage stream float4 ScreenPosition; + + stage override void VSMain() + { + base.VSMain(); + streams.ScreenPosition = streams.ShadingPosition; + } + + stage override void PSMain() + { + streams.ScreenPosition /= streams.ScreenPosition.w; + base.PSMain(); + } +}; diff --git a/assets/Stride/SDSL/SelectedSpriteShader.sdsl b/assets/Stride/SDSL/SelectedSpriteShader.sdsl new file mode 100644 index 0000000000..4db2057edb --- /dev/null +++ b/assets/Stride/SDSL/SelectedSpriteShader.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SelectedSpriteShader : SpriteBase +{ + float Blend; + + // method computing color + stage override float4 Shading() + { + float factor = fmod(streams.ShadingPosition.x, 2) * fmod(streams.ShadingPosition.y, 2); + float4 selectionColor = float4(0.0f, 0.5f, 1, 1); + float4 baseColor = base.Shading(); + + return lerp(baseColor, selectionColor, factor * Blend * Blend * baseColor.a); + } +}; diff --git a/assets/Stride/SDSL/SemanticTest.sdsl b/assets/Stride/SDSL/SemanticTest.sdsl new file mode 100644 index 0000000000..a6097376aa --- /dev/null +++ b/assets/Stride/SDSL/SemanticTest.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SemanticTest +{ + cbuffer PerFrame + { + float sem0 : POSITION; + float sem1 : POSITION; + } + + float test() + { + return sem0 + sem1; + } +}; diff --git a/assets/Stride/SDSL/ShaderBase.sdsl b/assets/Stride/SDSL/ShaderBase.sdsl new file mode 100644 index 0000000000..4ade27f5c5 --- /dev/null +++ b/assets/Stride/SDSL/ShaderBase.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// Base shader for all the graphics shaders +shader ShaderBase : ShaderBaseStream +{ + // Declare Vertex shader main method + stage void VSMain() {} + + // Declare Pixel shader main method + stage void PSMain() {} +}; diff --git a/assets/Stride/SDSL/ShaderBaseStream.sdsl b/assets/Stride/SDSL/ShaderBaseStream.sdsl new file mode 100644 index 0000000000..cce58432bf --- /dev/null +++ b/assets/Stride/SDSL/ShaderBaseStream.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// Base stream for a shader +shader ShaderBaseStream +{ + // Default SV_POSITION output for VS/GS shaders + stage stream float4 ShadingPosition : SV_Position; + +#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 + // Positive if this face is a front face, negative otherwise + stage stream float IsFrontFace : VFACE; +#else + // True if this face is a front face + stage stream bool IsFrontFace : SV_IsFrontFace; +#endif + + // Default COLOR outputs for PS shader + stage stream float4 ColorTarget : SV_Target0; + stage stream float4 ColorTarget1 : SV_Target1; + stage stream float4 ColorTarget2 : SV_Target2; + stage stream float4 ColorTarget3 : SV_Target3; + stage stream float4 ColorTarget4 : SV_Target4; + stage stream float4 ColorTarget5 : SV_Target5; + stage stream float4 ColorTarget6 : SV_Target6; + stage stream float4 ColorTarget7 : SV_Target7; + + // Default DEPTH output for PS shader + stage stream float Depth : SV_Depth; + stage stream float DepthGreater : SV_DepthGreater; // Special output after PS + stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS + + // Default InstanceId for VS/GS shaders + stage stream uint InstanceID : SV_InstanceID; +}; diff --git a/assets/Stride/SDSL/ShadingBase.sdsl b/assets/Stride/SDSL/ShadingBase.sdsl new file mode 100644 index 0000000000..58690f735b --- /dev/null +++ b/assets/Stride/SDSL/ShadingBase.sdsl @@ -0,0 +1,73 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Base shader to perfom shading. Defines the basic method and inserts it in the pipeline. +/// +/// +/// STRIDE_RENDER_TARGET_COUNT: Macro - Number of render targets. +/// + +#ifndef STRIDE_RENDER_TARGET_COUNT +# define STRIDE_RENDER_TARGET_COUNT 1 +#endif + +shader ShadingBase : ShaderBase +{ + compose ComputeColor ShadingColor0; + +#if STRIDE_RENDER_TARGET_COUNT > 1 + compose ComputeColor ShadingColor1; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 2 + compose ComputeColor ShadingColor2; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 3 + compose ComputeColor ShadingColor3; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 4 + compose ComputeColor ShadingColor4; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 5 + compose ComputeColor ShadingColor5; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 6 + compose ComputeColor ShadingColor6; +#endif +#if STRIDE_RENDER_TARGET_COUNT > 7 + compose ComputeColor ShadingColor7; +#endif + + // method computing color + stage float4 Shading() + { + return ShadingColor0.Compute(); + } + + stage override void PSMain() + { + base.PSMain(); + streams.ColorTarget = this.Shading(); + +#if STRIDE_RENDER_TARGET_COUNT > 1 + streams.ColorTarget1 = ShadingColor1.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 2 + streams.ColorTarget2 = ShadingColor2.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 3 + streams.ColorTarget3 = ShadingColor3.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 4 + streams.ColorTarget4 = ShadingColor4.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 5 + streams.ColorTarget5 = ShadingColor5.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 6 + streams.ColorTarget6 = ShadingColor6.Compute(); +#endif +#if STRIDE_RENDER_TARGET_COUNT > 7 + streams.ColorTarget7 = ShadingColor7.Compute(); +#endif + } +}; diff --git a/assets/Stride/SDSL/ShadingColor.sdsl b/assets/Stride/SDSL/ShadingColor.sdsl new file mode 100644 index 0000000000..42ca52d9c1 --- /dev/null +++ b/assets/Stride/SDSL/ShadingColor.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Class outputing color from a single ComputeColor and overriding any previous color computations. +/// +shader ShadingColor : ShaderBase +{ + compose ComputeColor Color; + + override void PSMain() + { + base.PSMain(); + streams.ColorTarget = Color.Compute(); + } +}; diff --git a/assets/Stride/SDSL/ShadowGroup.sdsl b/assets/Stride/SDSL/ShadowGroup.sdsl new file mode 100644 index 0000000000..0e47664834 --- /dev/null +++ b/assets/Stride/SDSL/ShadowGroup.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Defines the methods to compute shadowing and the sampler used on the shadow map. + /// + shader ShadowGroup : ShadowStream + { + // Computes the shadow for a given world position and light index + float3 ComputeShadow(float3 position, int lightIndex) + { + streams.thicknessWS = 0.0; // No thickness + return 1.0f; + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl b/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl new file mode 100644 index 0000000000..e9186ce9cd --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Shadow map caster with pixel shader performing alpha discard test. + /// + shader ShadowMapCasterAlphaDiscard : Transformation, ShaderBase, PositionStream, MaterialPixelStream + { + override stage void PSMain() + { + base.PSMain(); + + clip(streams.ColorTarget.a - streams.matAlphaDiscard); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl b/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl new file mode 100644 index 0000000000..f17f58ea6e --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Shadow map caster with pixel shader performing a dithered alpha discard test. + /// + shader ShadowMapCasterAlphaDithered : Transformation, ShaderBase, PositionStream, MaterialPixelStream + { + static const float BayerMatrix[16] = + { + 0, + 0.53333336, + 0.13333334, + 0.6666667, + 0.8, + 0.26666668, + 0.9333333, + 0.4, + 0.2, + 0.73333335, + 0.06666667, + 0.6, + 1, + 0.4666667, + 0.8666667, + 0.33333334, + }; + + override stage void PSMain() + { + base.PSMain(); + + int2 coord = int2(streams.ShadingPosition.xy % 4.0); + float bayer = BayerMatrix[coord.x+coord.y*4]; + clip( -1.01 + bayer + streams.ColorTarget.a * 1.01 ); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl b/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl new file mode 100644 index 0000000000..c83ccadeff --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Shadows +{ + shader ShadowMapCasterCubeMapProjection : TransformationBase, PositionStream4, Texturing + { + stage override void PostTransformPosition() + { + streams.ShadingPosition = ComputeShadingPosition(streams.PositionWS); + } + + stage override float4 ComputeShadingPosition(float4 world) + { + return mul(world, Transformation.ViewProjection); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl b/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl new file mode 100644 index 0000000000..05cd47a7ea --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Shadow map caster without pixel shader color outputs (only depth). + /// + shader ShadowMapCasterNoPixelShader : Transformation, ShaderBase, PositionStream + { + override stage void PSMain() + { + // no code = null pixel shader, as we are outputing depth only + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl b/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl new file mode 100644 index 0000000000..1519eacf6d --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl @@ -0,0 +1,60 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Shadows +{ + shader ShadowMapCasterParaboloidProjection : TransformationBase, PositionStream4, Texturing + { + static const float ClippingEpsilon = 0.03; + + cbuffer PerView.ShadowCaster + { + // x = Near; y = 1/(Far-Near) + float2 DepthParameters; + } + + // Used to write the distance from an object to the light to the depth buffer + stage stream float PixelDepth : SV_DEPTH; + + stage override void PostTransformPosition() + { + streams.ShadingPosition = ComputeParaboloidProjection(streams.PositionWS, streams.DepthVS); + } + + stage override float4 ComputeShadingPosition(float4 world) + { + float dummy; + return ComputeParaboloidProjection(world, dummy); + } + + float4 ComputeParaboloidProjection(float4 world, out float depth) + { + // Project into light view space + float4 lightSpace = mul(world, Transformation.View); + + // Store length and normalize + float distanceToLight = length(lightSpace.xyz); + float3 intermediate = lightSpace.xyz / distanceToLight; + + // Project x/y coordinates on parabola + intermediate.xy /= 1.0f+intermediate.z; + + // 2 different depth values + // The first one is the depth written to the depth buffer (always positive, since it is the distance to the point light) + // The second one is used for clipping (world space along the light's z-axis) + float2 depthValues = float2(distanceToLight, lightSpace.z + ClippingEpsilon) * DepthParameters.y; + + // Send projected depth to pixel shader + depth = depthValues.x; + + return float4(intermediate.xy, depthValues.y, 1); + } + + stage override void PSMain() + { + base.PSMain(); + + streams.PixelDepth = streams.DepthVS; + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl b/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl new file mode 100644 index 0000000000..356b71c7ce --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Creates shadow map for variance shadow mapping. + /// + shader ShadowMapCasterVsm : ShadowMapCasterBase + { + /// -------------------------------------------------------------------------------- + /// Pixel Shader + /// -------------------------------------------------------------------------------- + override stage void PSMain() + { + float depth = streams.ShadingPosition.z; + + // Compute partial derivatives of depth. + float dx = ddx(depth); + float dy = ddy(depth); + // Compute second moment over the pixel extents. + streams.ColorTarget = float4(depth, depth * depth + 0.25*(dx*dx + dy*dy), 0, 0); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapCommon.sdsl b/assets/Stride/SDSL/ShadowMapCommon.sdsl new file mode 100644 index 0000000000..e4e27d31b8 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapCommon.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Defines the textures used for shadow mapping. + /// + shader ShadowMapCommon + { + rgroup PerLighting + { + [Link("ShadowMap.ShadowMapTexture")] + Texture2D ShadowMapTexture; + } + + cbuffer PerLighting + { + [Link("ShadowMap.TextureSize")] + float2 ShadowMapTextureSize; + + [Link("ShadowMap.TextureTexelSize")] + float2 ShadowMapTextureTexelSize; + // TODO: We could have different types (Texture2DArray for optimized paths, TextureCube for omni...etc.) + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapFilterBase.sdsl b/assets/Stride/SDSL/ShadowMapFilterBase.sdsl new file mode 100644 index 0000000000..e407b7ab55 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapFilterBase.sdsl @@ -0,0 +1,126 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Defines shadow filtering method. + /// + shader ShadowMapFilterBase : ShadowMapCommon, Texturing, Math + { + /// + /// Calculate the shadow factor based on the position and shadow map distance. + /// + abstract float FilterShadow(float2 position, float positionDepth); + + /// + /// Used to calculate offsetted shadow map and world space pixel coordinates, + /// in order to mitigate shadow mapping artifacts for thickness calculation. + /// + void CalculateAdjustedShadowSpacePixelPosition(float filterRadiusInPixels, // The radius of the sampling kernel in texture space. + float3 pixelPositionWS, + float3 meshNormalWS, + float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. + float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. + out float3 adjustedPixelPositionWS, + out float3 adjustedPixelPositionShadowSpace) + { + // TODO: PERFORMANCE: The offset length can be calculated once for for each directional light on the CPU. For perspective shadows, this is a bit more complex. + // TODO: PERFORMANCE: Can we do the offset in shadow map space (by projecting the normal vector)? + + float4 bottomLeftTexelWS = Project(float4(0.0, 0.0, 0.0, 1.0), inverseWorldToShadowCascadeUV); + + // TODO: Does "ShadowMapTextureTexelSize" contain the texel size relative to the light's viewport or relative to the whole atlas? + const float4 topRightTexelWS = Project(float4(ShadowMapTextureTexelSize.xy * filterRadiusInPixels, 0.0, 1.0), inverseWorldToShadowCascadeUV); + + const float texelDiagonalLength = distance(topRightTexelWS.xyz, bottomLeftTexelWS.xyz); + + const float3 positionOffsetWS = meshNormalWS * texelDiagonalLength; // TODO: Do we even need an offset on faces that face the light? + adjustedPixelPositionWS = pixelPositionWS - positionOffsetWS; // Shrink the position into the surface to avoid SSS artifacts. + + // The pixel coordinate within shadow space (the light's post-projection space): + const float4 shadowMapCoordinate = Project(float4(adjustedPixelPositionWS, 1.0), worldToShadowCascadeUV); + + adjustedPixelPositionShadowSpace = shadowMapCoordinate.xyz; + } + + /// + /// Used to calculate offsetted shadow map and world space pixel coordinates, + /// in order to mitigate shadow mapping artifacts for thickness calculation. + /// + void CalculateAdjustedShadowSpacePixelPositionPerspective(float filterRadiusInPixels, // The radius of the sampling kernel in texture space. + float3 pixelPositionWS, + float3 meshNormalWS, + float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. + float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. + out float3 adjustedPixelPositionWS, + out float3 adjustedPixelPositionShadowSpace) + { + // TODO: PERFORMANCE: The offset length can be calculated once for for each directional light on the CPU. For perspective shadows, this is a bit more complex. + // TODO: PERFORMANCE: Can we do the offset in shadow map space (by projecting the normal vector)? + + const float4 shadowMapCoordinate = Project(float4(pixelPositionWS, 1.0), worldToShadowCascadeUV); + + + + // TODO: Does "ShadowMapTextureTexelSize" contain the texel size relative to the light's viewport or relative to the whole atlas? + const float4 topRightTexelWS = Project(float4(shadowMapCoordinate.xy + ShadowMapTextureTexelSize.xy * filterRadiusInPixels, shadowMapCoordinate.z, 1.0), inverseWorldToShadowCascadeUV); // TODO: Calculate two coordinates (that center shadowMapCoordinate)? + + const float texelDiagonalLength = distance(topRightTexelWS.xyz, pixelPositionWS); + + const float3 positionOffsetWS = meshNormalWS * texelDiagonalLength; // TODO: Do we even need an offset on faces that face the light? + adjustedPixelPositionWS = pixelPositionWS - positionOffsetWS; // Shrink the position into the surface to avoid SSS artifacts. + + // The pixel coordinate within shadow space (the light's post-projection space): + const float4 adjustedShadowMapCoordinate = Project(float4(adjustedPixelPositionWS, 1.0), worldToShadowCascadeUV); + + adjustedPixelPositionShadowSpace = adjustedShadowMapCoordinate.xyz; + } + + /// + /// Calculate the thickness of the object at this pixel using the shadow map. + /// + abstract float FilterThickness(float3 pixelPositionWS, + float3 meshNormalWS, + float2 depthRanges, + float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. + float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. + bool isOrthographic); + + // TODO: Maybe implement separate linear and a perspective functions? + float SampleThickness(float3 shadowSpaceCoordinate, + float3 pixelPositionWS, + float2 depthRanges, + float4x4 inverseWorldToShadowCascadeUV, + bool isOrthographic) + { + const float shadowMapDepth = ShadowMapTexture.SampleLevel(LinearBorderSampler, shadowSpaceCoordinate.xy, 0).r; + + float thickness; + + // Now we calculate the thickness from the light's point of view: + if(isOrthographic) + { + // Subtract the two linear depth values and multiply them by Z-far in order to get the thickness in world/view space. + // This works because for directional lightmaps, Z-near is 0.0. + thickness = abs(shadowMapDepth - shadowSpaceCoordinate.z) * depthRanges.y; // Same as the above, but faster. // TODO: Better use max(thickness, 0.0) instead of abs()? + } + else + { + //float znear = depthRanges.x; + //float zfar = depthRanges.y; + //float2 ZProjection = float2(zfar / (zfar - znear), (-zfar * znear) / (zfar - znear)); + //float d1 = CalculateViewSpaceDepthFromNonlinearDepth(shadowMapDepth, ZProjection); + //float d2 = CalculateViewSpaceDepthFromNonlinearDepth(positionDepth, ZProjection); + + //float d1 = ConvertToLinearDepth(shadowMapDepth, depthRanges.x, depthRanges.y); // TODO: Multiply by (far - near)? + //float d2 = ConvertToLinearDepth(shadowSpaceCoordinate.z, depthRanges.x, depthRanges.y); + + // TODO: PERFORMANCE: Instead of doing a matrix multiplication, just correctly linearize the depth and calculate the DISTANCE (not just the depth!)! + float4 shadowmapPositionWorldSpace = Project(float4(shadowSpaceCoordinate.xy, shadowMapDepth, 1.0), inverseWorldToShadowCascadeUV); + thickness = distance(shadowmapPositionWorldSpace.xyz, pixelPositionWS.xyz); + } + + return(thickness); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl b/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl new file mode 100644 index 0000000000..7bd7877374 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Performs default filtering: no filtering. + /// + shader ShadowMapFilterDefault : ShadowMapFilterBase + { + /// + /// Calculate the shadow factor based on the shadow map texture, the position, a sampler + /// + float FilterShadow(float2 position, float positionDepth) + { + return ShadowMapTexture.SampleCmpLevelZero(LinearClampCompareLessEqualSampler, position, positionDepth); + } + + float FilterThickness(float3 pixelPositionWS, + float3 meshNormalWS, + float2 depthRanges, + float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. + float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. + bool isOrthographic) + { + //const float filterRadiusInPixels = 1.0; // 1 pixel filter radius + const float filterRadiusInPixels = 1.5; // 1.5 pixel filter radius + + float3 adjustedPixelPositionWS; + float3 adjustedPixelPositionShadowSpace; + + if(isOrthographic) + { + CalculateAdjustedShadowSpacePixelPosition(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, + adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); + } + else + { + CalculateAdjustedShadowSpacePixelPositionPerspective(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, + adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); + } + + return SampleThickness(adjustedPixelPositionShadowSpace, adjustedPixelPositionWS, depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl b/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl new file mode 100644 index 0000000000..7f5469796a --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl @@ -0,0 +1,285 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Performs percentage closer filtering. + /// + shader ShadowMapFilterPcf : ShadowMapFilterBase + { + void CalculatePCFKernelParameters(float2 position, out float2 base_uv, out float2 st) // TODO: Make "st"! + { + float2 uv = position * ShadowMapTextureSize; // 1 unit - 1 texel + + base_uv = floor(uv + 0.5); + + st = uv + 0.5 - base_uv; + + base_uv -= 0.5; + base_uv *= ShadowMapTextureTexelSize; + } + + float Get3x3FilterKernel(float2 base_uv, float2 st, out float3 kernel[4]) + { + float2 uvW0 = (3 - 2 * st); + float2 uvW1 = (1 + 2 * st); + + float2 uv0 = (2 - st) / uvW0 - 1; + float2 uv1 = st / uvW1 + 1; + + // Each kernel element contains a texture coordinate (XY) and a weight (Z). + kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); + kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); + kernel[2] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); + kernel[3] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); + + return 16.0; + } + + float Get5x5FilterKernel(float2 base_uv, float2 st, out float3 kernel[9]) + { + float2 uvW0 = (4 - 3 * st); + float2 uvW1 = 7; + float2 uvW2 = (1 + 3 * st); + + float2 uv0 = (3 - 2 * st) / uvW0 - 2; + float2 uv1 = (3 + st) / uvW1; + float2 uv2 = st / uvW2 + 2; + + // Each kernel element contains a texture coordinate (XY) and a weight (Z). + kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); + kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); + kernel[2] = float3(base_uv + float2(uv2.x, uv0.y) * ShadowMapTextureTexelSize, uvW2.x * uvW0.y); + kernel[3] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); + kernel[4] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); + kernel[5] = float3(base_uv + float2(uv2.x, uv1.y) * ShadowMapTextureTexelSize, uvW2.x * uvW1.y); + kernel[6] = float3(base_uv + float2(uv0.x, uv2.y) * ShadowMapTextureTexelSize, uvW0.x * uvW2.y); + kernel[7] = float3(base_uv + float2(uv1.x, uv2.y) * ShadowMapTextureTexelSize, uvW1.x * uvW2.y); + kernel[8] = float3(base_uv + uv2 * ShadowMapTextureTexelSize, uvW2.x * uvW2.y); + + return 144.0; + } + + float Get7x7FilterKernel(float2 base_uv, float2 st, out float3 kernel[16]) + { + float2 uvW0 = (5 * st - 6); + float2 uvW1 = (11 * st - 28); + float2 uvW2 = -(11 * st + 17); + float2 uvW3 = -(5 * st + 1); + + float2 uv0 = (4 * st - 5) / uvW0 - 3; + float2 uv1 = (4 * st - 16) / uvW1 - 1; + float2 uv2 = -(7 * st + 5) / uvW2 + 1; + float2 uv3 = -st / uvW3 + 3; + + // Each kernel element contains a texture coordinate (XY) and a weight (Z). + kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); + kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); + kernel[2] = float3(base_uv + float2(uv2.x, uv0.y) * ShadowMapTextureTexelSize, uvW2.x * uvW0.y); + kernel[3] = float3(base_uv + float2(uv3.x, uv0.y) * ShadowMapTextureTexelSize, uvW3.x * uvW0.y); + kernel[4] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); + kernel[5] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); + kernel[6] = float3(base_uv + float2(uv2.x, uv1.y) * ShadowMapTextureTexelSize, uvW2.x * uvW1.y); + kernel[7] = float3(base_uv + float2(uv3.x, uv1.y) * ShadowMapTextureTexelSize, uvW3.x * uvW1.y); + kernel[8] = float3(base_uv + float2(uv0.x, uv2.y) * ShadowMapTextureTexelSize, uvW0.x * uvW2.y); + kernel[9] = float3(base_uv + float2(uv1.x, uv2.y) * ShadowMapTextureTexelSize, uvW1.x * uvW2.y); + kernel[10] = float3(base_uv + uv2 * ShadowMapTextureTexelSize, uvW2.x * uvW2.y); + kernel[11] = float3(base_uv + float2(uv3.x, uv2.y) * ShadowMapTextureTexelSize, uvW3.x * uvW2.y); + kernel[12] = float3(base_uv + float2(uv0.x, uv3.y) * ShadowMapTextureTexelSize, uvW0.x * uvW3.y); + kernel[13] = float3(base_uv + float2(uv1.x, uv3.y) * ShadowMapTextureTexelSize, uvW1.x * uvW3.y); + kernel[14] = float3(base_uv + float2(uv2.x, uv3.y) * ShadowMapTextureTexelSize, uvW2.x * uvW3.y); + kernel[15] = float3(base_uv + uv3 * ShadowMapTextureTexelSize, uvW3.x * uvW3.y); + + return 2704.0; + } + + float SampleTextureAndCompare(float2 position, float positionDepth) + { + return ShadowMapTexture.SampleCmpLevelZero(LinearClampCompareLessEqualSampler, position, positionDepth); + } + + float FilterShadow(float2 position, float positionDepth) + { + float shadow = 0.0f; + + // TODO: handle bias + + float2 base_uv; + float2 st; + CalculatePCFKernelParameters(position, base_uv, st); + + // TODO: Apply gradient for initial offset in this way once gradient mapping has been added + // Replacing the above 2 lines this this and using the float2 parameter depthGradient which contains the change in depth along the x and y axis over the size of the entire texture atlas + //base_uv -= float2(0.5, 0.5); + //float2 initialOffset = base_uv - uv; + //base_uv *= ShadowMapTextureTexelSize; + // + // Take offset to pixel center into account according to the depth gradient + //positionDepth += dot(initialOffset * ShadowMapTextureTexelSize, depthGradient); + + if (TFilterSize == 3) + { + float3 kernel[4]; + float normalizationFactor = Get3x3FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<4; ++i) + { + shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); + } + + shadow /= normalizationFactor; + } + else if (TFilterSize == 5) + { + float3 kernel[9]; + float normalizationFactor = Get5x5FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<9; ++i) + { + shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); + } + + shadow /= normalizationFactor; + } + else if (TFilterSize == 7) + { + float3 kernel[16]; + float normalizationFactor = Get7x7FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<16; ++i) + { + shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); + } + + shadow /= normalizationFactor; + } + + return shadow; + } + + /// + /// Returns the filter radius in texture space. + /// + float GetFilterRadiusInPixels(void) + { + // TODO: Some of these filters are so wide, that they cause artifacts on thin objects like ears for example. + + //return float(TFilterSize) / 2.0 + 1.0; + + if (TFilterSize == 3) + { + return 2.5; // 3 + } + else if (TFilterSize == 5) + { + return 3.5; // 5 + } + else + { + return 4.5; // 7 + } + } + + float SampleAndFilter(float3 adjustedPixelPositionWS, float3 adjustedPixelPositionShadowSpace, float2 depthRanges, float4x4 inverseWorldToShadowCascadeUV, bool isOrthographic, bool isDualParaboloid = false) + { + float2 uv = adjustedPixelPositionShadowSpace.xy * ShadowMapTextureSize; // 1 unit - 1 texel + + float2 base_uv = floor(uv + 0.5); + float2 st = uv + 0.5 - base_uv; + base_uv *= ShadowMapTextureTexelSize; + + float thickness = 0.0; + float normalizationFactor = 1.0; + + if (TFilterSize == 3) + { + float3 kernel[4]; + normalizationFactor = Get3x3FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<4; ++i) + { + thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, + depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); + } + } + else if (TFilterSize == 5) + { + float3 kernel[9]; + normalizationFactor = Get5x5FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<9; ++i) + { + thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, + depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); + } + } + else if (TFilterSize == 7) + { + float3 kernel[16]; + normalizationFactor = Get7x7FilterKernel(base_uv, st, kernel); + + [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... + for(int i=0; i<16; ++i) + { + thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, + depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); + } + } + + return(thickness / normalizationFactor); + } + + float FilterThickness(float3 pixelPositionWS, + float3 meshNormalWS, + float2 depthRanges, + float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. + float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. + bool isOrthographic) + { + // TODO: This filter is not great yet (quality wise), because we'd probably have to evaluate the scattering per sample to get smooth results. But that's too slow. + + float3 adjustedPixelPositionWS; + float3 adjustedPixelPositionShadowSpace; + + if(isOrthographic) // TODO: The offset calculation only works for directional lights for now. + { + // Calculate the adjusted world space coordinate and shadow map coordinate of the current pixel: + + + // TODO: PERFORMANCE: Ideally we'd like to move this to "ShadowMapReceiverDirectional.sdsl", + // because that way we can ensure that the adjusted pixel positions are calculated only once per pixel per light. + // Sadly this is not that easy because the offset depends on the filter width, which is only available inside of "ShadowMapFilterPcf.sdsl". + + CalculateAdjustedShadowSpacePixelPosition(GetFilterRadiusInPixels(), pixelPositionWS, meshNormalWS, + worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, + adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); + } + else + { + /* + float3 offset = -meshNormalWS * 0.01; // TODO: This is bad! + + // Calculate the regular shadow map coordinate: // TODO: Use the one calculated by the shadow mapping? + float4 shadowMapCoordinate = mul(float4(pixelPositionWS + offset, 1.0), worldToShadowCascadeUV); + shadowMapCoordinate.xyz /= shadowMapCoordinate.w; + + adjustedPixelPositionShadowSpace = shadowMapCoordinate.xyz; + adjustedPixelPositionWS = pixelPositionWS; + */ + + CalculateAdjustedShadowSpacePixelPositionPerspective(GetFilterRadiusInPixels(), pixelPositionWS, meshNormalWS, + worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, + adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); + } + + // Now perform the actual filtering: + return SampleAndFilter(adjustedPixelPositionWS, adjustedPixelPositionShadowSpace, depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); + } + + }; +} diff --git a/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl b/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl new file mode 100644 index 0000000000..ecbfc413d7 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Performs variance filtering. + /// + shader ShadowMapFilterVsm : ShadowMapFilterBase + { + cbuffer PerLighting + { + float BleedingFactor; + float MinVariance; + }; + + float FilterShadow(float2 position, float shadowMapDistance) + { + float2 moments = (float2)ShadowMapTexture.SampleLevel(LinearBorderSampler, position, 0.0); + float variance = moments.y - moments.x * moments.x; + // Clamp variance to min + variance = max(variance, MinVariance); + float dist = moments.x - shadowMapDistance; + float pMax = variance / (variance + dist * dist); + // Light bleeding reduction (See http://http.developer.nvidia.com/GPUGems3/gpugems3_ch08.html Light Bleeding 8.4.3) + pMax = saturate((pMax - BleedingFactor) / (1.0 - BleedingFactor)); + float p = shadowMapDistance <= moments.x; + return max(p, pMax); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapGroup.sdsl b/assets/Stride/SDSL/ShadowMapGroup.sdsl new file mode 100644 index 0000000000..7055dc7c79 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapGroup.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Defines the structures for shadow mapping. + /// + shader ShadowMapGroup : ShadowGroup, ShadowMapCommon + { + }; +} diff --git a/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl b/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl new file mode 100644 index 0000000000..ec5ffd9bf0 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl @@ -0,0 +1,62 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Selects the shadow map and computes the shadow factor. + /// + /// + /// TCascadeCountBase: Number of cascades. + /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). + /// + internal shader ShadowMapReceiverBase : + MaterialPixelShadingStream, + ShadowMapGroup, + ShadowMapFilterBase, + PositionStream4 + { + cbuffer PerLighting // TODO: Use a proper cbuffer for this? + { + float4x4 WorldToShadowCascadeUV[TCascadeCountBase * TLightCountBase]; + float4x4 InverseWorldToShadowCascadeUV[TCascadeCountBase * TLightCountBase]; // This is only required for SSS. + float4x4 ViewMatrices[TCascadeCountBase * TLightCountBase]; // This is only required for SSS. + float2 DepthRanges[TCascadeCountBase * TLightCountBase]; // x = z-near, y = z-far. This is only required for SSS. + float DepthBiases[TLightCountBase]; + float OffsetScales[TLightCountBase]; + }; + + float3 GetShadowPositionOffset(float offsetScale, float nDotL, float3 normal) + { + float normalOffsetScale = saturate(1.0f - nDotL); + return 2.0f * ShadowMapTextureTexelSize.x * offsetScale * normalOffsetScale * normal; + } + + float ComputeShadowFromCascade(float3 shadowPositionWS, int cascadeIndex, int lightIndex) + { + //float3 shadowPositionWSddx = ddx_fine(shadowPositionWS); + //float3 shadowPositionWSddy = ddy_fine(shadowPositionWS); + + float4 shadowPosition = mul(float4(shadowPositionWS, 1.0), WorldToShadowCascadeUV[cascadeIndex + lightIndex * TCascadeCountBase]); + shadowPosition.z -= DepthBiases[lightIndex]; + shadowPosition.xyz /= shadowPosition.w; + + return FilterShadow(shadowPosition.xy, shadowPosition.z); + } + + float ComputeThicknessFromCascade(float3 pixelPositionWS, // TODO: This is named "compute..." and the other function is named "calculate..."! + float3 meshNormalWS, + int cascadeIndex, + int lightIndex, + bool isOrthographic) + { + const int arrayIndex = cascadeIndex + lightIndex * TCascadeCountBase; + + return FilterThickness(pixelPositionWS, + meshNormalWS, + DepthRanges[arrayIndex], + WorldToShadowCascadeUV[arrayIndex], + InverseWorldToShadowCascadeUV[arrayIndex], + isOrthographic); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl b/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl new file mode 100644 index 0000000000..a4393aa152 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl @@ -0,0 +1,118 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Selects the shadow map and computes the shadow factor. + /// + /// + /// TCascadeCount: Number of cascades. + /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). + /// + internal shader ShadowMapReceiverDirectional : + ShadowMapReceiverBase, + Transformation // Required for "WorldInverseTranspose". + { + cbuffer PerView.Lighting // TODO: Use a proper cbuffer for this? + { + float CascadeDepthSplits[TCascadeCount * TLightCount]; + }; + + override float3 ComputeShadow(float3 position, int lightIndex) + { + int cascadeIndexBase = lightIndex * TCascadeCount; + + // Only support a single light per group + int cascadeIndex = 0; + [unroll] + for(int i = 0; i < TCascadeCount - 1; i++) + { + [flatten] + if (streams.DepthVS > CascadeDepthSplits[cascadeIndexBase + i]) + { + cascadeIndex = i + 1; + } + } + float3 shadow = 1.0; + float tempThickness = 999.0; + + // Offset the shadow position + float3 shadowPosition = position.xyz; + shadowPosition += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); + // If we are within the cascades + if (cascadeIndex < TCascadeCount) + { + shadow = ComputeShadowFromCascade(shadowPosition, cascadeIndex, lightIndex); + + if(TComputeTransmittance) + { + tempThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, + streams.meshNormalWS, // Use the vertex normal, not the normal map normal. + cascadeIndex, + lightIndex, + true); + } + + float nextSplit = CascadeDepthSplits[cascadeIndexBase + cascadeIndex]; + float splitSize = nextSplit; + if(cascadeIndex > 0) + { + splitSize = nextSplit - CascadeDepthSplits[cascadeIndexBase + cascadeIndex - 1]; + } + float splitDist = (nextSplit - streams.DepthVS) / splitSize; + + if (splitDist < 0.2) + { + float lerpAmt = smoothstep(0.0, 0.2, splitDist); + + if (cascadeIndex == TCascadeCount - 1) + { + if (!TDepthRangeAuto) + { + shadow = lerp(1.0f, shadow, lerpAmt); + + if(TComputeTransmittance) + { + tempThickness = lerp(0.0, tempThickness, lerpAmt); + } + } + } + else if (TBlendCascades) + { + float nextShadow = ComputeShadowFromCascade(shadowPosition, cascadeIndex + 1, lightIndex); + shadow = lerp(nextShadow, shadow, lerpAmt); + + if(TComputeTransmittance) + { + float nextThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, + streams.meshNormalWS, // Use the vertex normal, not the normal map normal. + cascadeIndex + 1, + lightIndex, + true); + + tempThickness = lerp(nextThickness, tempThickness, lerpAmt); + } + } + } + } + + streams.thicknessWS = tempThickness; + + // Output the shadow color + if (TCascadeDebug) + { + //// Display Cascade with colors in debug mode + //// GREEN BLUE PURPLE RED WHITE + static const float3 colors[5] = { float3(0,1,0), float3(0,0,1), float3(1,0,1), float3(1,0,0), float3(1,1,1)}; + return colors[cascadeIndex] * shadow; + } + + return shadow; + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl b/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl new file mode 100644 index 0000000000..442fb3b969 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl @@ -0,0 +1,113 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Shadows +{ + /// + /// Selects the shadow map and computes the shadow factor. + /// + internal shader ShadowMapReceiverPointCubeMap : ShadowMapGroup, ShadowMapFilterBase, PositionStream4, ShaderBaseStream, LightStream, Texturing, NormalStream + { + cbuffer PerDraw.Lighting + { + float4x4 WorldToShadow[TLightCount*6]; + float4x4 InverseWorldToShadow[TLightCount*6]; + float DepthBiases[TLightCount]; + float OffsetScales[TLightCount]; + float2 DepthParameters[TLightCount]; + }; + + // TODO: Deduplicate + float3 GetShadowPositionOffset(float offsetScale, float nDotL, float3 normal) + { + float normalOffsetScale = saturate(1.0f - nDotL); + return 2.0f * ShadowMapTextureTexelSize.x * offsetScale * normalOffsetScale * normal; + } + + float ComputeThickness(float3 positionWS, int cascadeIndex) + { + // Calculate thickness for SSS: + float tempThickness = 0.0; + + const bool ComputeThickness = true; // TODO: This should be a mixin parameter or something! + if(ComputeThickness) + { + // TODO: I don't know if the shadow map filtering can be done for cube maps in the same way as for directional lights or spot lights. + tempThickness = FilterThickness(positionWS, + streams.meshNormalWS, + float2(0.0f, 1.0f), //DepthRanges[lightIndex*6+faceIndex], // TODO: Currently not needed for perspective shadow maps. + WorldToShadow[cascadeIndex], + InverseWorldToShadow[cascadeIndex], + false); + } + + return tempThickness; + } + + override float3 ComputeShadow(float3 positionWS, int lightIndex) + { + // Calculate shadow: + float3 lightPosition = LightPointGroup.Lights[lightIndex].PositionWS.xyz; + float3 lightDelta = positionWS.xyz - lightPosition; + float distanceToLight = length(lightDelta); + float3 direction = lightDelta / distanceToLight; + float3 directionAbs = abs(direction); + + float longestAxis = max(directionAbs.x, max(directionAbs.y, directionAbs.z)); + + int faceIndex; + float lightSpaceZ; + + // Select the base face index for either X,Y or Z facing + [flatten] + if(directionAbs.x == longestAxis) + { + lightSpaceZ = lightDelta.x; + faceIndex = 2; + } + else if(directionAbs.y == longestAxis) + { + lightSpaceZ = lightDelta.y; + faceIndex = 4; + } + else // direction.z == longestAxis + { + lightSpaceZ = lightDelta.z; + faceIndex = 0; + } + + // Apply offset for the negative side of a direction (+1) + float lightSpaceZDirection = sign(lightSpaceZ); + faceIndex += int(-min(0.0, lightSpaceZDirection)); + + + int cascadeIndex = lightIndex * 6 + faceIndex; + + // Compute the thickness before modifying "positionWS": + streams.thicknessWS = ComputeThickness(positionWS, cascadeIndex); + + + // Apply normal scaled bias + positionWS += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); + + // Map to texture space + float4 projectedPosition = mul(float4(positionWS,1), WorldToShadow[cascadeIndex]); + projectedPosition /= projectedPosition.w; + + // Apply bias in view space + lightSpaceZ = abs(lightSpaceZ); + lightSpaceZ -= DepthBiases[lightIndex]; + + // Project view space depth into the same space as the shadow map + float depth = DepthParameters[lightIndex].x + (DepthParameters[lightIndex].y / lightSpaceZ); + + if(depth < 0 || depth > 1) + return 1; + + // Compare distance to light to value inside of the shadow map + float shadow = FilterShadow(projectedPosition.xy, depth); + + return(shadow); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl b/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl new file mode 100644 index 0000000000..c086acd565 --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl @@ -0,0 +1,67 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Shadows +{ + /// + /// Selects the shadow map and computes the shadow factor. + /// + internal shader ShadowMapReceiverPointParaboloid : ShadowMapGroup, ShadowMapFilterBase, PositionStream4, ShaderBaseStream + { + cbuffer PerDraw.Lighting + { + float4x4 View[TLightCount]; + float2 FaceOffsets[TLightCount]; + float2 BackfaceOffsets[TLightCount]; + float2 FaceSizes[TLightCount]; + float DepthBiases[TLightCount]; + float2 DepthParameters[TLightCount]; + }; + + override float3 ComputeShadow(float3 position, int lightIndex) + { + float4 lightSpace = mul(float4(position, 1), View[lightIndex]); + + // Store length and normalize + float distanceToLight = length(lightSpace.xyz); + float3 intermediate = lightSpace.xyz / distanceToLight; + + // Project x/y coordinates on parabola + intermediate.xy /= 1.0f + abs(intermediate.z); + + float2 depthParameters = DepthParameters[lightIndex]; + + // Apply bias + distanceToLight -= DepthBiases[lightIndex]; + + // Scale distance to light depth buffer range + distanceToLight *= depthParameters.y; + + // Map from (-1,1) to (0,1) + intermediate.xy = intermediate.xy * 0.5 + float2(0.5, 0.5); + intermediate.y = 1.0f-intermediate.y; + + // Apply offset into atlas and size of a single face in the atlas + float2 samplePosition = intermediate.xy * FaceSizes[lightIndex] + FaceOffsets[lightIndex]; + + // Apply offset for the back side face + [flatten] + if(lightSpace.z < 0) + { + samplePosition += BackfaceOffsets[lightIndex]; + } + + // Compare distance to light to value inside of the shadow map + float shadow = FilterShadow(samplePosition, distanceToLight); + + // Calculate thickness for SSS: + float tempThickness = 999.9; // No scattering for now. + + + + streams.thicknessWS = tempThickness; + + return(shadow); + } + }; +} diff --git a/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl b/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl new file mode 100644 index 0000000000..d617f548ad --- /dev/null +++ b/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Shadows +{ + /// + /// Selects the shadow map and computes the shadow factor. + /// + /// + /// TCascadeCount: Number of cascades. + /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). + /// + internal shader ShadowMapReceiverSpot : + ShadowMapReceiverBase, + Transformation // Required for "WorldInverseTranspose". + { + override float3 ComputeShadow(float3 position, int lightIndex) + { + // Offset the shadow position + float3 shadowPosition = position.xyz; + shadowPosition += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); + + float3 shadow = ComputeShadowFromCascade(shadowPosition, 0, lightIndex); + + float tempThickness = 0.0; + + // Note: transmittance is currently disabled for spot lights + //const bool ComputeTransmittance = true; // TODO: This should be a mixin parameter or something! + //if(ComputeTransmittance) + //{ + // tempThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, + // streams.meshNormalWS, + // 0, + // lightIndex, + // false); + //} + + streams.thicknessWS = tempThickness; + + // Output the shadow color + if (TCascadeDebug) + { + return float3(0, 1, 0) * shadow; + } + else + { + return shadow; + } + } + }; +} diff --git a/assets/Stride/SDSL/ShadowStream.sdsl b/assets/Stride/SDSL/ShadowStream.sdsl new file mode 100644 index 0000000000..f3c913735f --- /dev/null +++ b/assets/Stride/SDSL/ShadowStream.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/// +/// Defines shadow stream variables. +/// +shader ShadowStream +{ + stage stream float3 shadowColor; + stage stream float thicknessWS; +}; diff --git a/assets/Stride/SDSL/SharedTextureCoordinate.sdsl b/assets/Stride/SDSL/SharedTextureCoordinate.sdsl new file mode 100644 index 0000000000..f5b1bde11a --- /dev/null +++ b/assets/Stride/SDSL/SharedTextureCoordinate.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SharedTextureCoordinate : ShaderBase, Texturing +{ + override stage void PSMain() + { + // Remap all texture coords to TEXCOORD0 + streams.TexCoord1 = streams.TexCoord; + streams.TexCoord2 = streams.TexCoord; + streams.TexCoord3 = streams.TexCoord; + streams.TexCoord4 = streams.TexCoord; + streams.TexCoord5 = streams.TexCoord; + streams.TexCoord6 = streams.TexCoord; + streams.TexCoord7 = streams.TexCoord; + streams.TexCoord8 = streams.TexCoord; + streams.TexCoord9 = streams.TexCoord; + + base.PSMain(); + } + + override stage void VSMain() + { + base.VSMain(); + } +}; diff --git a/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl b/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl new file mode 100644 index 0000000000..491c9ea355 --- /dev/null +++ b/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SignedDistanceFieldFont : Texturing +{ + + // Gets the median of 3 values + float median(float r, float g, float b) + { + return max(min(r, g), min(max(r, g), b)); + } + + // Retrieves the pixel's color sampled from a signed distance field font texture, with font color, border and shadows + stage float4 FontColor(float4 sampledColor, float4 textColor, float4 borderColor, float borderThickness) + { + // -0.5 to +0.5 is the maximum distance msdfgen can produce, but it's blurry so cap the border at 0.25 + borderThickness = clamp(borderThickness, 0, 0.2); + + // Higher (more than 1) - sharper + // Lower (less than 1, more than 0) - blurry + float sharpnessMagnitude = 0.5f; + float axisDistance = 0.4 - borderThickness; + + // Get the median distance encoded in the signed distance field + float medianDistance = median(sampledColor.r, sampledColor.g, sampledColor.b); + + float sigDist = medianDistance - axisDistance; + + float transition = fwidth(sigDist) * 0.85; + float opacity = smoothstep(-transition, transition, sigDist); + opacity *= opacity; + + // Detect edge + if (borderThickness > 0) + { + float farDistance = axisDistance + borderThickness * 2; + float sigDistBorder = medianDistance - farDistance; + float borderLine = sharpnessMagnitude * sigDistBorder/fwidth(sigDistBorder) + farDistance; + float borderOpacity = smoothstep(0, 1, borderLine); + + textColor = lerp(borderColor, textColor, borderOpacity); + } + + sampledColor = lerp(float4(0,0,0,0), textColor, opacity); + + return sampledColor; + } +}; diff --git a/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl b/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl new file mode 100644 index 0000000000..c8e739a6d4 --- /dev/null +++ b/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SignedDistanceFieldFontShader : ShaderBase, SignedDistanceFieldFont +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Position : POSITION; + stage stream float4 Color : COLOR; + stage stream float Swizzle : BATCH_SWIZZLE; + + // ------------------------------------- + // VertexShader + // ------------------------------------- + stage override void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + // ------------------------------------- + // PixelShader + // ------------------------------------- + stage override void PSMain() + { + streams.ColorTarget = Shading(); + } + + stage float4 Shading() + { + // This should be a 3-channel signed distance field texture + float4 signedMultiDistance = Texture0.Sample(Sampler, streams.TexCoord); + + // These values can go into streams later + float4 borderColor = float4(0, 0, 0, 1); + float borderThickness = 0.f; + + return FontColor(signedMultiDistance, streams.Color, borderColor, borderThickness); + } +}; diff --git a/assets/Stride/SDSL/Simple.sdsl b/assets/Stride/SDSL/Simple.sdsl new file mode 100644 index 0000000000..65cf152d21 --- /dev/null +++ b/assets/Stride/SDSL/Simple.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Simple +{ + float test; +}; diff --git a/assets/Stride/SDSL/SimpleShader.sdsl b/assets/Stride/SDSL/SimpleShader.sdsl new file mode 100644 index 0000000000..221a8aff7e --- /dev/null +++ b/assets/Stride/SDSL/SimpleShader.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SimpleShader : ShaderBase, Texturing +{ + stage stream float2 Position : POSITION; + + float4 BaseColor; + + //stage float4 TestColor; + + stage override void VSMain() + { + streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); + } + + stage override void PSMain() + { + streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor + Texture0.Sample(PointRepeatSampler, streams.Position); // + TestColor; + } +}; diff --git a/assets/Stride/SDSL/SkyboxShaderBase.sdsl b/assets/Stride/SDSL/SkyboxShaderBase.sdsl new file mode 100644 index 0000000000..22fc687342 --- /dev/null +++ b/assets/Stride/SDSL/SkyboxShaderBase.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + shader SkyboxShaderBase : SpriteBase, SkyboxStream + { + stage float Intensity; + stage float4x4 ProjectionInverse; + stage float4x4 ViewInverse; + stage float4x4 SkyMatrix; + + override stage void VSMain() + { + base.VSMain(); + var screenPosition = streams.ShadingPosition / streams.ShadingPosition.w; + var position = float4(screenPosition.x, screenPosition.y, 1.0f, 1.0f); + var directionVS = mul(position, ProjectionInverse).xyz; + var directionWS = mul(float4(directionVS,0), ViewInverse).xyz; + streams.skyboxViewDirection = mul(directionWS, (float3x3)SkyMatrix); + } + }; +} diff --git a/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl b/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl new file mode 100644 index 0000000000..0ffcf1eeb8 --- /dev/null +++ b/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + shader SkyboxShaderCubemap : SkyboxShaderBase + { + stage TextureCube CubeMap; + + override stage float4 Shading() + { + var samplingDir = normalize(streams.skyboxViewDirection); + var color = CubeMap.Sample(LinearSampler, float3(samplingDir.x, samplingDir.y, -samplingDir.z)).rgb; + return float4(color * Intensity, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/SkyboxShaderTexture.sdsl b/assets/Stride/SDSL/SkyboxShaderTexture.sdsl new file mode 100644 index 0000000000..795273865d --- /dev/null +++ b/assets/Stride/SDSL/SkyboxShaderTexture.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + shader SkyboxShaderTexture : SkyboxShaderBase, Math + { + stage Texture2D Texture; + + override stage float4 Shading() + { + var samplingDir = normalize(streams.skyboxViewDirection); + var samplingDirSquare = float3(samplingDir.x*samplingDir.x, samplingDir.y*samplingDir.y, samplingDir.z*samplingDir.z); + var u = atan2(-samplingDir.z, -samplingDir.x)/(2*Math.PI) + 0.5; + var v = atan2(-samplingDir.y, length(samplingDir.xz))/Math.PI + 0.5; + +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 + var color = Texture.SampleLevel(LinearSampler, float2(u, v), 0).rgb; +#else + var color = Texture.Sample(LinearSampler, float2(u, v)).rgb; +#endif + return float4(color * Intensity, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/SkyboxStream.sdsl b/assets/Stride/SDSL/SkyboxStream.sdsl new file mode 100644 index 0000000000..c91f12856d --- /dev/null +++ b/assets/Stride/SDSL/SkyboxStream.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Skyboxes +{ + shader SkyboxStream + { + stage stream float3 skyboxViewDirection; + }; +} + diff --git a/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl b/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl new file mode 100644 index 0000000000..9f314bb389 --- /dev/null +++ b/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl @@ -0,0 +1,78 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A shader performing Lambertian pre-filtering. + /// + internal shader SphericalHarmonicsBase : Math + { + static const int CoefficientsCount = TOrder * TOrder; + + // Pi constants + static const float PI4 = 4 * PI; + static const float PI16 = 16 * PI; + static const float PI64 = 64 * PI; + static const float SQRT_PI = 1.77245385090551602729; + + // The values of the SH bases function after last evaluation + stream float SHBaseValues[CoefficientsCount]; + + void EvaluateSHBases(float3 direction) + { + var x = direction.x; + var y = direction.y; + var z = direction.z; + + var x2 = x*x; + var y2 = y*y; + var z2 = z*z; + + streams.SHBaseValues[0] = 1.0/(2.0*SQRT_PI); + +if(TOrder>1) +{ + streams.SHBaseValues[1] = -sqrt(3.0/PI4)*y; + streams.SHBaseValues[2] = sqrt(3.0/PI4)*z; + streams.SHBaseValues[3] = -sqrt(3.0/PI4)*x; + +if(TOrder>2) +{ + streams.SHBaseValues[4] = sqrt(15.0/PI4)*y*x; + streams.SHBaseValues[5] = -sqrt(15.0/PI4)*y*z; + streams.SHBaseValues[6] = sqrt(5.0/PI16)*(3.0*z2-1.0); + streams.SHBaseValues[7] = -sqrt(15.0/PI4)*x*z; + streams.SHBaseValues[8] = sqrt(15.0/PI16)*(x2-y2); + +if(TOrder>3) +{ + var z3 = pow(z, 3.0); + + var x4 = pow(x, 4.0); + var y4 = pow(y, 4.0); + var z4 = pow(z, 4.0); + + streams.SHBaseValues[ 9] = -sqrt( 70.0/PI64)*y*(3*x2-y2); + streams.SHBaseValues[10] = sqrt(105.0/ PI4)*y*x*z; + streams.SHBaseValues[11] = -sqrt( 21.0/PI16)*y*(-1.0+5.0*z2); + streams.SHBaseValues[12] = sqrt( 7.0/PI16)*(5.0*z3-3.0*z); + streams.SHBaseValues[13] = -sqrt( 42.0/PI64)*x*(-1.0+5.0*z2); + streams.SHBaseValues[14] = sqrt(105.0/PI16)*(x2-y2)*z; + streams.SHBaseValues[15] = -sqrt( 70.0/PI64)*x*(x2-3.0*y2); + +if(TOrder>4) +{ + streams.SHBaseValues[16] = 3.0*sqrt(35.0/PI16)*x*y*(x2-y2); + streams.SHBaseValues[17] = -3.0*sqrt(70.0/PI64)*y*z*(3.0*x2-y2); + streams.SHBaseValues[18] = 3.0*sqrt( 5.0/PI16)*y*x*(-1.0+7.0*z2); + streams.SHBaseValues[19] = -3.0*sqrt(10.0/PI64)*y*z*(-3.0+7.0*z2); + streams.SHBaseValues[20] = (105.0*z4-90.0*z2+9.0)/(16.0*SQRT_PI); + streams.SHBaseValues[21] = -3.0*sqrt(10.0/PI64)*x*z*(-3.0+7.0*z2); + streams.SHBaseValues[22] = 3.0*sqrt( 5.0/PI64)*(x2-y2)*(-1.0+7.0*z2); + streams.SHBaseValues[23] = -3.0*sqrt(70.0/PI64)*x*z*(x2-3.0*y2); + streams.SHBaseValues[24] = 3.0*sqrt(35.0/(4.0*PI64))*(x4-6.0*y2*x2+y4); +}}}} + } + }; +} diff --git a/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl b/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl new file mode 100644 index 0000000000..a13028600e --- /dev/null +++ b/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Skyboxes +{ + /// + /// Base shader to sample an environment + /// + shader SphericalHarmonicsEnvironmentColor : SphericalHarmonicsUtils, IComputeEnvironmentColor + { + cbuffer PerView.Lighting + { + [Color] + float3 SphericalColors[TOrder * TOrder]; + } + + override float4 Compute(float3 direction) + { + // Workaround for type mismatch during SPIR-V validation + //float3 test[TOrder * TOrder]; + //for (int i = 0; i < TOrder * TOrder; i++) + // test[i] = SphericalColors[i]; + //return EvaluateSphericalHarmonics(test, direction); + + return EvaluateSphericalHarmonics(SphericalColors, direction); + } + }; +} diff --git a/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl b/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl new file mode 100644 index 0000000000..592cbba076 --- /dev/null +++ b/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A shader performing Lambertian pre-filtering. + /// + internal shader SphericalHarmonicsRenderer: SphericalHarmonicsBase, ImageEffectShader, Texturing + { + [Color] stage float3 SHCoefficients[CoefficientsCount]; + + // Shading of the sprite + stage override void PSMain() + { + float3 ColorTargets[6]; + for( uint i=0; i<6; ++i) + { + var direction = normalize(CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, i)); // remarks: TexCoord points to the center of the pixel (what we want) + + EvaluateSHBases(direction); + + ColorTargets[i] = float3(0, 0, 0); + for(int k=0; k + /// A shader performing Lambertian pre-filtering. + /// + internal shader SphericalHarmonicsUtils : Math + { + static const int CoefficientsCount = TOrder * TOrder; + + float4 EvaluateSphericalHarmonics(float3 sphericalColors[TOrder * TOrder], float3 direction) + { + var x = direction.x; + var y = direction.y; + var z = direction.z; + + var x2 = x*x; + var y2 = y*y; + var z2 = z*z; + + float3 color = sphericalColors[0]; + +if(TOrder>1) +{ + color += sphericalColors[1]*y; + color += sphericalColors[2]*z; + color += sphericalColors[3]*x; + +if(TOrder>2) +{ + color += sphericalColors[4]*y*x; + color += sphericalColors[5]*y*z; + color += sphericalColors[6]*(3.0*z2-1.0); + color += sphericalColors[7]*x*z; + color += sphericalColors[8]*(x2-y2); + +if(TOrder>3) +{ + var z3 = z2 * z; + + var x4 = x2 * x2; + var y4 = y2 * y2; + var z4 = z2 * z2; + + color += sphericalColors[9]*y*(3*x2-y2); + color += sphericalColors[10]*y*x*z; + color += sphericalColors[11]*y*(-1.0+5.0*z2); + color += sphericalColors[12]*(5.0*z3-3.0*z); + color += sphericalColors[13]*x*(-1.0+5.0*z2); + color += sphericalColors[14]*(x2-y2)*z; + color += sphericalColors[15]*x*(x2-3.0*y2); + +if(TOrder>4) +{ + color += sphericalColors[16]*x*y*(x2-y2); + color += sphericalColors[17]*y*z*(3.0*x2-y2); + color += sphericalColors[18]*y*x*(-1.0+7.0*z2); + color += sphericalColors[19]*y*z*(-3.0+7.0*z2); + color += sphericalColors[20]*(105.0*z4-90.0*z2+9.0); + color += sphericalColors[21]*x*z*(-3.0+7.0*z2); + color += sphericalColors[22]*(x2-y2)*(-1.0+7.0*z2); + color += sphericalColors[23]*x*z*(x2-3.0*y2); + color += sphericalColors[24]*(x4-6.0*y2*x2+y4); +}}}} + return float4(color, 1); + } + }; +} diff --git a/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl b/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl new file mode 100644 index 0000000000..79bf42d82e --- /dev/null +++ b/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a structure that is used only within the spotlight shaders. + /// + shader SpotLightDataInternalShader // Named "SpotLightDataInternalShader" instead of "SpotLightDataInternal" because otherwise the name clashes with the name of the "SpotLightDataInternal" structure. + { + struct SpotLightDataInternal + { + float3 PositionWS; + float3 DirectionWS; + float3 AngleOffsetAndInvSquareRadius; + [Color] + float3 Color; + }; + }; +} diff --git a/assets/Stride/SDSL/Sprite3DBase.sdsl b/assets/Stride/SDSL/Sprite3DBase.sdsl new file mode 100644 index 0000000000..6cb51ecbdc --- /dev/null +++ b/assets/Stride/SDSL/Sprite3DBase.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader Sprite3DBase : SpriteBase +{ + stage float SliceCoordinate; + + override stage float4 Shading() + { + return Texture3D0.Sample(Sampler, float3(streams.TexCoord, SliceCoordinate)); + } +}; diff --git a/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl b/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl new file mode 100644 index 0000000000..ed38241453 --- /dev/null +++ b/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SpriteAlphaCutoff : SpriteBase +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Color : COLOR; + stage stream float4 ColorAdd : COLOR1; + stage stream float Swizzle : BATCH_SWIZZLE; + + // ------------------------------------- + // VertexShader + // ------------------------------------- + stage override void VSMain() + { + base.VSMain(); + if (TSRgb) + { + streams.Color = ColorUtility.ToLinear(streams.Color); + } + } + + // Shading of the sprite + stage override float4 Shading() + { + // Because we use float input values we should allow certain threshold - lets fix it at 0.1 + + // Alpha grayscale + float4 swizzleColor = (abs(streams.Swizzle - 1) <= 0.1) ? base.Shading().rrrr : base.Shading(); + + // Normal maps + if (abs(streams.Swizzle - 2) <= 0.1) + { + // TODO This should change if we move the flags (reconstruct Z, etc) to the texture + // For now just assume the formula below is correct (works for 90% of teh cases) + float nX = swizzleColor.r * 2 - 1; + float nY = swizzleColor.g * 2 - 1; + swizzleColor.a = 1; + float nZ = 1 - sqrt(saturate(nX * nX + nY * nY)); + swizzleColor.b = nZ * 0.5f + 0.5f; // Don't forget that the Z-component is also in the range (-1, 1) so all normal textures have Blue channel above 0.5 + } + + // Opaque grayscale + if (abs(streams.Swizzle - 3) <= 0.1) + { + swizzleColor.gb = swizzleColor.rr; + swizzleColor.a = 1; + } + + float4 finalColor = swizzleColor * streams.Color + streams.ColorAdd; + + // Discard low alpha pixels + clip(finalColor.a - 0.1); + + // Premultiply color and set alpha to 1 + //finalColor = float4(finalColor.rgb * finalColor.a, 1); + + return finalColor; + } +}; + +namespace Stride.Rendering +{ + partial effect SpriteAlphaCutoffEffect + { + using params SpriteBaseKeys; + mixin SpriteAlphaCutoff; + }; +} diff --git a/assets/Stride/SDSL/SpriteBase.sdsl b/assets/Stride/SDSL/SpriteBase.sdsl new file mode 100644 index 0000000000..c3c1694ec1 --- /dev/null +++ b/assets/Stride/SDSL/SpriteBase.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteBase : ShaderBase, Texturing +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Position : POSITION; + + cbuffer PerDraw + { + // ------------------------------------- + // uniforms + // ------------------------------------- + // A general transformation matrix + stage float4x4 MatrixTransform; + } + + // ------------------------------------- + // VertexShader + // ------------------------------------- + stage override void VSMain() + { + streams.ShadingPosition = mul(streams.Position, MatrixTransform); + } + + // Shading of the sprite + stage override void PSMain() + { + streams.ColorTarget = Shading(); + } + + stage float4 Shading() + { + return Texture0.Sample(Sampler, streams.TexCoord); + } +}; diff --git a/assets/Stride/SDSL/SpriteBatchShader.sdsl b/assets/Stride/SDSL/SpriteBatchShader.sdsl new file mode 100644 index 0000000000..d6ce2dfc08 --- /dev/null +++ b/assets/Stride/SDSL/SpriteBatchShader.sdsl @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteBatchShader : SpriteBase +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Color : COLOR; + stage stream float4 ColorAdd : COLOR1; + stage stream float Swizzle : BATCH_SWIZZLE; + + // ------------------------------------- + // VertexShader + // ------------------------------------- + stage override void VSMain() + { + base.VSMain(); + if (TSRgb) + { + streams.Color = ColorUtility.ToLinear(streams.Color); + } + } + + // Shading of the sprite + stage override float4 Shading() + { + // Because we use float input values we should allow certain threshold - lets fix it at 0.1 + + // Alpha grayscale + float4 swizzleColor = (abs(streams.Swizzle - 1) <= 0.1) ? base.Shading().rrrr : base.Shading(); + + // Normal maps + if (abs(streams.Swizzle - 2) <= 0.1) + { + // TODO This should change if we move the flags (reconstruct Z, etc) to the texture + // For now just assume the formula below is correct (works for 90% of teh cases) + float nX = swizzleColor.r * 2 - 1; + float nY = swizzleColor.g * 2 - 1; + swizzleColor.a = 1; + float nZ = 1 - sqrt(saturate(nX * nX + nY * nY)); + swizzleColor.b = nZ * 0.5f + 0.5f; // Don't forget that the Z-component is also in the range (-1, 1) so all normal textures have Blue channel above 0.5 + } + + // Opaque grayscale + if (abs(streams.Swizzle - 3) <= 0.1) + { + swizzleColor.gb = swizzleColor.rr; + swizzleColor.a = 1; + } + + + float4 finalColor = swizzleColor * streams.Color + streams.ColorAdd; + return finalColor; + } +}; diff --git a/assets/Stride/SDSL/SpriteEffect.sdsl b/assets/Stride/SDSL/SpriteEffect.sdsl new file mode 100644 index 0000000000..e1b0e4db56 --- /dev/null +++ b/assets/Stride/SDSL/SpriteEffect.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteEffect : SpriteBase +{ + // Color used to tint the sprite + [Color] + stage float4 Color = float4(1,1,1,1); + + // Shading of the sprite + stage override float4 Shading() + { + return base.Shading() * Color; + } +}; diff --git a/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl b/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl new file mode 100644 index 0000000000..f20005db50 --- /dev/null +++ b/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl @@ -0,0 +1,102 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteEffectExtTexture : ShaderBase +{ + // Color used to tint the sprite + //[Color] + //stage float4 Color = float4(1,1,1,1); + + //[ExternalOES] + stage Texture2D StrideInternal_TextureExt0; // DO NOT RENAME THIS VARIABLE! The ShaderCompiler specifically looks for "TextureExt0". + stage float MipLevel; + stage float Gamma; + //stage Texture2DExternalOES StrideInternal_TextureExt0; + + stage SamplerState Sampler; + + stage stream float2 TexCoord : TEXCOORD0; + stage stream float4 Position : POSITION; + + /*cbuffer PerDraw + { + stage float4x4 MatrixTransform; + }*/ + + stage override void VSMain() + { + //streams.ShadingPosition = mul(streams.Position, MatrixTransform); + streams.ShadingPosition = streams.Position; + } + + stage override void PSMain() + { + streams.ColorTarget = Shading(); + } + + float4 GetMipmapLevelDebugMask() + { + // These values depend on each other because the mip levels are + // copied down and therefore mask each other out. + // That's why no value is set to zero. + if(MipLevel < 0.5f) + { + return float4(1.0f, 1.0f, 1.0f, 1.0f); // White + } + else if(MipLevel < 1.5f) + { + return float4(1.0f, 0.5f, 0.5f, 1.0f); // Red + } + else if(MipLevel < 2.5f) + { + return float4(0.5f, 2.0f, 1.0f, 1.0f); // Green + } + else if(MipLevel < 3.5f) + { + return float4(1.0f, 0.5f, 2.0f, 1.0f); // Blue + } + else if(MipLevel < 4.5f) + { + return float4(2.0f, 2.0f, 0.5f, 1.0f); // Yellow + } + + // TODO: + else if(MipLevel < 5.5f) + { + return float4(1.0f, 2.0f, 2.0f, 1.0f); + } + else if(MipLevel < +.5f) + { + return float4(2.0f, 1.0f, 2.0f, 1.0f); + } + else if(MipLevel < 7.5f) + { + return float4(2.0f, 1.0f, 2.0f, 1.0f); + } + else if(MipLevel < 8.5f) + { + return float4(2.0f, 2.0f, 1.0f, 1.0f); + } + + return 2.0f; + } + + float3 ConvertToLinearSpace(float3 color) + { + return pow(color, Gamma); + } + + stage float4 Shading() + { + //return StrideInternal_TextureExt0.Sample(Sampler, streams.TexCoord) * Color; + + // Generate a "random" color based on the mip level, for debug purposes: + //float4 debugColor = GetMipmapLevelDebugMask(); + + //float4 debugColor = 1.0f; + //float4 textureColor = StrideInternal_TextureExt0.SampleLevel(Sampler, streams.TexCoord, MipLevel); //Failed to compile on GLSL + //return float4(ConvertToLinearSpace(textureColor.rgb), 1.0f) * debugColor; + + float4 textureColor = StrideInternal_TextureExt0.Sample(Sampler, streams.TexCoord); + return float4(ConvertToLinearSpace(textureColor.rgb), 1.0f); + } +}; diff --git a/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl b/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl new file mode 100644 index 0000000000..cfc3860fef --- /dev/null +++ b/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteEffectExtTextureRegular : ShaderBase +{ + stage Texture2D TextureRegular; + + stage SamplerState Sampler; + stage float MipLevel; + + stage stream float2 TexCoord : TEXCOORD0; + stage stream float4 Position : POSITION; + + stage override void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + stage override void PSMain() + { + streams.ColorTarget = Shading(); + } + + stage float4 Shading() + { + return TextureRegular.SampleLevel(Sampler, streams.TexCoord, MipLevel); + } +}; diff --git a/assets/Stride/SDSL/SpritePicking.sdsl b/assets/Stride/SDSL/SpritePicking.sdsl new file mode 100644 index 0000000000..653fcbdea7 --- /dev/null +++ b/assets/Stride/SDSL/SpritePicking.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SpritePicking : SpriteBase +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Color : COLOR; + + // method computing color + stage override float4 Shading() + { + base.Shading(); // discard pixel if needed. + + return streams.Color; + } +}; diff --git a/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl b/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl new file mode 100644 index 0000000000..17d75a3631 --- /dev/null +++ b/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader SpriteSignedDistanceFieldFontShader : SpriteBase, SignedDistanceFieldFont +{ + stage stream float4 Color : COLOR; + + // Shading of the sprite + stage override float4 Shading() + { + return FontColor(base.Shading(), streams.Color, float4(0,0,0,1), 0.f); + } +}; diff --git a/assets/Stride/SDSL/SpriteSuperSampler.sdsl b/assets/Stride/SDSL/SpriteSuperSampler.sdsl new file mode 100644 index 0000000000..c2d897abc9 --- /dev/null +++ b/assets/Stride/SDSL/SpriteSuperSampler.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader SpriteSuperSampler : SpriteBase +{ + stage override float4 Shading() + { + // "call of duty"-type of h4x4 checker box, but reduced to 9 picks instead of 13: + float2 jitters[] = { + float2(-2.0, 0.0), + float2(0.0, 0.0), + float2(2.0, 0.0), + float2(-1.0, 1.0), + float2(1.0, 1.0), + float2(-1.0, -1.0), + float2(1.0, -1.0), + float2(0.0, 2.0), + float2(0.0, -2.0) + }; + + float weightSum = 0; + float4 color = 0; + float2 texCoordBackup = streams.TexCoord; + + [unroll] + for (uint j = 0; j < 9; ++j) + { + float2 jitter = jitters[j]; + float dist = max(abs(jitter.x), abs(jitter.y)); + float weight = 3 - dist; + streams.TexCoord = texCoordBackup + jitter * Texture0TexelSize; + color += weight * base.Shading(); + weightSum += weight; + } + + streams.TexCoord = texCoordBackup; + + return color / weightSum; + } +}; diff --git a/assets/Stride/SDSL/StageBase.sdsl b/assets/Stride/SDSL/StageBase.sdsl new file mode 100644 index 0000000000..d4a4d22e00 --- /dev/null +++ b/assets/Stride/SDSL/StageBase.sdsl @@ -0,0 +1,7 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StageBase +{ + abstract stage void stageCall(); + stage float stageMember = 1.0f; +}; diff --git a/assets/Stride/SDSL/StageCallExtern.sdsl b/assets/Stride/SDSL/StageCallExtern.sdsl new file mode 100644 index 0000000000..a65e6bb714 --- /dev/null +++ b/assets/Stride/SDSL/StageCallExtern.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StageCallExtern : StageBase +{ + void test() + { + float u = stageMember; + stageCall(); + } +}; diff --git a/assets/Stride/SDSL/StageDecl.sdsl b/assets/Stride/SDSL/StageDecl.sdsl new file mode 100644 index 0000000000..b7186c6c75 --- /dev/null +++ b/assets/Stride/SDSL/StageDecl.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StageDecl +{ + stage int myStageVar = 1; +}; diff --git a/assets/Stride/SDSL/StageValueReference.sdsl b/assets/Stride/SDSL/StageValueReference.sdsl new file mode 100644 index 0000000000..f152267982 --- /dev/null +++ b/assets/Stride/SDSL/StageValueReference.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StageValueReference +{ + compose StageValueTest myStageVar = stage; + + void test() + { + myStageVar.test(); + float u = myStageVar.testFloat; + } +}; diff --git a/assets/Stride/SDSL/StageValueTest.sdsl b/assets/Stride/SDSL/StageValueTest.sdsl new file mode 100644 index 0000000000..8234eabb92 --- /dev/null +++ b/assets/Stride/SDSL/StageValueTest.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StageValueTest +{ + compose StageValueReference myExtern; + float testFloat; + + void test() + { + } +}; diff --git a/assets/Stride/SDSL/StaticCallMixin.sdsl b/assets/Stride/SDSL/StaticCallMixin.sdsl new file mode 100644 index 0000000000..664bed071d --- /dev/null +++ b/assets/Stride/SDSL/StaticCallMixin.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StaticCallMixin +{ + void call() + { + StaticMixin.staticCall(); + float a = -StaticMixin.staticMember; + } +}; diff --git a/assets/Stride/SDSL/StaticMixin.sdsl b/assets/Stride/SDSL/StaticMixin.sdsl new file mode 100644 index 0000000000..911790092d --- /dev/null +++ b/assets/Stride/SDSL/StaticMixin.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StaticMixin +{ + float staticMember; + + void staticCall() + { + } +}; diff --git a/assets/Stride/SDSL/StaticStageCallTest.sdsl b/assets/Stride/SDSL/StaticStageCallTest.sdsl new file mode 100644 index 0000000000..c2e581c111 --- /dev/null +++ b/assets/Stride/SDSL/StaticStageCallTest.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StaticStageCallTest : StageBase +{ + compose StageCallExtern myExtern; + + stage void stageCall() + { + } +}; diff --git a/assets/Stride/SDSL/StreamChild.sdsl b/assets/Stride/SDSL/StreamChild.sdsl new file mode 100644 index 0000000000..180e55db59 --- /dev/null +++ b/assets/Stride/SDSL/StreamChild.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamChild : StreamParent0, StreamParent1 +{ + float test() + { + return streams.StreamParent0.parentStream + streams.StreamParent1.parentStream; + } +}; diff --git a/assets/Stride/SDSL/StreamError.sdsl b/assets/Stride/SDSL/StreamError.sdsl new file mode 100644 index 0000000000..61577f7001 --- /dev/null +++ b/assets/Stride/SDSL/StreamError.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamError +{ + stream float myStream; + + void test0(inout float value) + { + value = 2.0*value; + } + + void test1() + { + test0(streams.myStream); + } +}; diff --git a/assets/Stride/SDSL/StreamParent0.sdsl b/assets/Stride/SDSL/StreamParent0.sdsl new file mode 100644 index 0000000000..8f2b752f80 --- /dev/null +++ b/assets/Stride/SDSL/StreamParent0.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamParent0 +{ + stream float parentStream = 0.0f; +}; diff --git a/assets/Stride/SDSL/StreamParent1.sdsl b/assets/Stride/SDSL/StreamParent1.sdsl new file mode 100644 index 0000000000..f97b938f0d --- /dev/null +++ b/assets/Stride/SDSL/StreamParent1.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamParent1 +{ + stream float parentStream = 0.0f; +}; diff --git a/assets/Stride/SDSL/StreamParent2.sdsl b/assets/Stride/SDSL/StreamParent2.sdsl new file mode 100644 index 0000000000..b55c0f6d3d --- /dev/null +++ b/assets/Stride/SDSL/StreamParent2.sdsl @@ -0,0 +1,7 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamParent2 +{ + stream float parentStream = 0.0f; + stage stream float stageStream = 0.0f; +}; diff --git a/assets/Stride/SDSL/StreamSolverExternTest.sdsl b/assets/Stride/SDSL/StreamSolverExternTest.sdsl new file mode 100644 index 0000000000..020d4a5d28 --- /dev/null +++ b/assets/Stride/SDSL/StreamSolverExternTest.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamSolverExternTest +{ + compose StreamChild myExtern; + float func() + { + return streams.myExtern.StreamParent0.parentStream + streams.myExtern.StreamParent1.parentStream; + } +}; diff --git a/assets/Stride/SDSL/StreamTest.sdsl b/assets/Stride/SDSL/StreamTest.sdsl new file mode 100644 index 0000000000..6918d24a02 --- /dev/null +++ b/assets/Stride/SDSL/StreamTest.sdsl @@ -0,0 +1,70 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StreamTest +{ + stream float2 PositionIn : Position; + stream float4 PositionOut; + stream float4 Color; + patchstream float3 patchstreamParam; + + void test() + { + streams.PositionOut = 2.0f*streams.PositionOut; + } + + void VSMain() + { + streams.PositionOut = float4(streams.PositionIn, 0.0f, 1.0f); + test(); + test(); + float4 a = streams.PositionOut; + } + + void PSMain() + { + streams.Color = streams.PositionOut; + //streams.Color = float4(0,0,0,0); + } + + void GSMain(point Input input[1], inout PointStream outStream) + { + streams = input[0]; + + streams.PositionOut = 0.5f * streams.PositionOut; + + outStream.Append(streams); + + for (int i = 0; i < 2; ++i) + { + outStream.Append(streams); + } + + outStream.RestartStrip(); + } + + void HSMain(InputPatch input, out Output output) + { + streams = input[0]; + //streams.PositionOut = 0.5f * streams.PositionOut; + output.PositionOut = 0.5f * input[0].PositionOut; + + output = streams; + + // TODO: using this syntax should be possible too + // TODO: add corresponding StreamUsage + //output.PositionOut = 0.5f * input[0].PositionOut; + } + + void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) + { + constants.patchstreamParam = 1.0f; + } + + void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) + { + streams = input[0]; + //streams.PositionOut = 0.5f * streams.PositionOut * constants.patchstreamParam.x; + streams = 0.5f * streams;// * constants.patchstreamParam.x; + output = streams; + } +}; diff --git a/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl b/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl new file mode 100644 index 0000000000..afcb07baa8 --- /dev/null +++ b/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl @@ -0,0 +1,73 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Data; +using Stride.Rendering.Materials; + +namespace Stride.Rendering.Voxels +{ + partial effect StrideLightingVXGI + { + using params LightingKeys; + + // ----------------------------------------------- + // Add light groups + // ----------------------------------------------- + ShaderSourceCollection directLightGroups = LightingKeys.DirectLightGroups; + if (directLightGroups != null) + { + foreach(ShaderSource directLightGroup in directLightGroups) + { + // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" + mixin compose directLightGroups += (directLightGroup); + } + } + + // ----------------------------------------------- + // Add environment light groups + // ----------------------------------------------- + ShaderSourceCollection environmentLights = LightingKeys.EnvironmentLights; + if (environmentLights != null) + { + foreach(ShaderSource environmentLight in environmentLights) + { + // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" + mixin compose environmentLights += (environmentLight); + } + } + } + + /// + /// Forward shading effect + /// + effect StrideForwardShadingEffectVXGI + { + using params MaterialKeys; + + // Derive from StrideEffectBase + mixin StrideEffectBase; + + // ----------------------------------------------- + // Mix material and lighting shading for Pixel Shader + // ----------------------------------------------- + ShaderSource extensionPixelStageSurfaceShaders = MaterialKeys.PixelStageSurfaceShaders; + if (extensionPixelStageSurfaceShaders != null) + { + mixin MaterialSurfacePixelStageCompositor; + mixin compose materialPixelStage = (extensionPixelStageSurfaceShaders); + mixin compose streamInitializerPixelStage = MaterialKeys.PixelStageStreamInitializer; + + ShaderSource extensionPixelStageSurfaceFilter = MaterialKeys.PixelStageSurfaceFilter; + if (extensionPixelStageSurfaceFilter != null) + { + mixin (extensionPixelStageSurfaceFilter); + } + } + + // ----------------------------------------------- + // Add direct and environment light groups + // ----------------------------------------------- + mixin StrideLightingVXGI; + + mixin child VoxelizeToFragmentsEffect; + }; +} diff --git a/assets/Stride/SDSL/StructuredBufferTest.sdsl b/assets/Stride/SDSL/StructuredBufferTest.sdsl new file mode 100644 index 0000000000..2479ccc773 --- /dev/null +++ b/assets/Stride/SDSL/StructuredBufferTest.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader StructuredBufferTest +{ + StructuredBuffer sbtest; + RWStructuredBuffer rwsbtest; + + void test() + { + uint numStructs; + uint stride; + sbtest.GetDimensions(numStructs, stride); + } +}; diff --git a/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl b/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl new file mode 100644 index 0000000000..ad87885410 --- /dev/null +++ b/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl @@ -0,0 +1,512 @@ + /* + * Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) + + * Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com) + * Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the following disclaimer + * in the documentation and/or other materials provided with the + * distribution: + * + * "Uses Separable SSS. Copyright (C) 2012 by Jorge Jimenez and Diego + * Gutierrez." + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS + * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of the copyright holders. + */ + +/** + * _______ _______ _______ _______ + * / | / | / | / | + * | (---- | (---- | (---- | (---- + * \ \ \ \ \ \ \ \ + * ----) | ----) | ----) | ----) | + * |_______/ |_______/ |_______/ |_______/ + * + * S E P A R A B L E S U B S U R F A C E S C A T T E R I N G + * + * http://www.iryoku.com/ + * + * Hi, thanks for your interest in Separable SSS! + * + * It's a simple shader composed of two components: + * + * 1) A transmittance function, 'SSSSTransmittance', which allows to calculate + * light transmission in thin slabs, useful for ears and nostrils. It should + * be applied during the main rendering pass as follows: + * + * float3 t = albedo.rgb * lights[i].color * attenuation * spot; + * color.rgb += t * SSSSTransmittance(...) + * + * (See 'Main.fx' for more details). + * + * 2) A simple two-pass reflectance post-processing shader, 'SSSSBlur*', which + * softens the skin appearance. It should be applied as a regular + * post-processing effect like bloom (the usual framebuffer ping-ponging): + * + * a) The first pass (horizontal) must be invoked by taking the final color + * framebuffer as input, and storing the results into a temporal + * framebuffer. + * b) The second pass (vertical) must be invoked by taking the temporal + * framebuffer as input, and storing the results into the original final + * color framebuffer. + * + * Note that This SSS filter should be applied *before* tonemapping. + * + * Before including SeparableSSS.h you'll have to setup the target. The + * following targets are available: + * SMAA_HLSL_3 + * SMAA_HLSL_4 + * SMAA_GLSL_3 + * + * For more information of what's under the hood, you can check the following + * URLs (but take into account that the shader has evolved a little bit since + * these publications): + * + * 1) Reflectance: http://www.iryoku.com/sssss/ + * 2) Transmittance: http://www.iryoku.com/translucency/ + * + * If you've got any doubts, just contact us! + */ + +namespace Stride.Rendering.SubsurfaceScattering +{ + /// + /// The Separable Subsurface Scattering shader based on https://github.com/iryoku/separable-sss. + /// + shader SubsurfaceScatteringBlurShader< + bool BlurHorizontally, + bool KernelSizeJittering, + bool OrthographicProjection, // If orthographic projection is used, this is true. If perspective projections are used, this is false. + int MaxMaterialCount, + int KernelLength, + int RenderMode + > : ImageEffectShader, Camera, Math + { + // Generated values: + stage float2 ProjectionSizeOnUnitPlaneInClipSpace; + stage float ScatteringWidths[MaxMaterialCount]; // TODO: Use Buffer instead? + stage float IterationNumber; + stage float4x4 ViewProjectionMatrix; // This is used for debugging only. + + cbuffer PerDraw + { + // Filter kernel layout is as follows: + // - Weights in the RGB channels. + // - Offsets in the A channel. + stage Buffer KernelBuffer; + } + + // These values correspond to the ones defined in SubsurfaceScatteringBlur.cs + #define SHOW_SCATTERING_OBJECTS 1 + #define SHOW_MATERIAL_INDEX 2 + #define SHOW_SCATTERING_WIDTH 3 + + //------------------------------------------------------------------------------ + // Configurable Defines + + // Light diffusion should occur on the surface of the object, not in a screen + // oriented plane. Setting SSSS_FOLLOW_SURFACE to 1 will ensure that diffusion + // is more accurately calculated, at the expense of more memory accesses. + #ifndef SSSS_FOLLOW_SURFACE + #define SSSS_FOLLOW_SURFACE 0 + #endif + + // This define allows to specify a different source for the SSS strength + // (instead of using the alpha channel of the color framebuffer). This is useful + // when the alpha channel of the mian color buffer is used for something else. + #ifndef SSSS_STRENGTH_SOURCE + #define SSSS_STRENGTH_SOURCE (colorM.a) + #endif + + //------------------------------------------------------------------------------ + // Porting Functions + //SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; + //SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; + #define SSSSTexture2D Texture2D + #define SSSSSampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) + #define SSSSSampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) + #define SSSSSample(tex, coord) SSSSSampleLevelZero(tex, coord) + #define SSSSSamplePoint(tex, coord) SSSSSampleLevelZeroPoint(tex, coord) + #define SSSSSampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) + #define SSSSSampleOffset(tex, coord, offset) SSSSSampleLevelZeroOffset(tex, coord, offset) + #define SSSSLerp(a, b, t) lerp(a, b, t) + #define SSSSSaturate(a) saturate(a) + #define SSSSMad(a, b, c) mad(a, b, c) + #define SSSSMul(v, m) mul(v, m) + #define SSSS_FLATTEN [flatten] + #define SSSS_BRANCH [branch] + #define SSSS_UNROLL [unroll] + + //------------------------------------------------------------------------------ + // Separable SSS Reflectance Pixel Shader + + float4 SSSSBlurPS( + // The usual quad texture coordinates. + float2 texcoord, + + // This is a SRGB or HDR color input buffer, which should be the final + // color frame, resolved in case of using multisampling. The desired + // SSS strength should be stored in the alpha channel (1 for full + // strength, 0 for disabling SSS). If this is not possible, you an + // customize the source of this value using SSSS_STRENGTH_SOURCE. + // + // When using non-SRGB buffers, you should convert to + // linear before processing, and back again to gamma space before + // storing the pixels (see Chapter 24 of GPU Gems 3 for more info) + // + // IMPORTANT: WORKING IN A NON-LINEAR SPACE WILL TOTALLY RUIN SSS! + SSSSTexture2D colorTex, + + // The linear depth buffer of the scene, resolved in case of using + // multisampling. The resolve should be a simple average to avoid + // artifacts in the silhouette of objects. + SSSSTexture2D depthTex, + + // This parameter specifies the global level of subsurface scattering + // or, in other words, the width of the filter. It's specified in + // world space units. + float sssWidth, + + // Direction of the blur: + // - First pass: float2(1.0, 0.0) + // - Second pass: float2(0.0, 1.0) + float2 dir, + + // This parameter indicates whether the stencil buffer should be + // initialized. Should be set to 'true' for the first pass if not + // previously initialized, to enable optimization of the second pass + bool initStencil, + + // Stride: The material index used to access the correct scattering kernel. + uint materialIndex) + { + // Fetch color of current pixel: + float4 colorM = SSSSSamplePoint(colorTex, texcoord); + + // This is disabled because we already discard using the material index. + /* + // Initialize the stencil buffer in case it was not already available: + if (initStencil) // (Checked in compile time, it's optimized away) + if (SSSS_STRENGTH_SOURCE == 0.0) discard; + */ + + // Fetch linear depth of current pixel: + float depthM = SSSSSamplePoint(depthTex, texcoord).r; + depthM = CalculateViewSpaceDepth(depthM); + + // Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window): + float2 scale = CalculateProjectionSize(depthM); // This is more accurate than the original approach, because it calculates the correct radius for non-square viewports. + + // Calculate the final step to fetch the surrounding pixels: + float2 finalStep = sssWidth * scale * dir; + finalStep *= SSSS_STRENGTH_SOURCE; // Modulate it using the alpha channel. + //finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. // This is disabled because we bake it into the kernel on the CPU instead. + + if(KernelSizeJittering) + { + // This reduces the banding artifacts by introducing a bit of noise. + // This might create a less mathematically correct falloff, since it messes with the sample offsets. + // But the difference is barely noticeable. + //finalStep *= 0.5 + GetRandomNumber(streams.ShadingPosition.xy + int(IterationNumber) * 10) * 0.5; // More noisy + finalStep *= 0.5 + GetRandomNumber8x8(streams.ShadingPosition.xy + 2 + int(IterationNumber) * 10) * 0.5; // More regular (shows a bit of a grid pattern) + //finalStep *= 0.5 + FastRandom(streams.ShadingPosition.xy + 2 + int(IterationNumber) * 10) * 0.5; // More noisy + } + + // Accumulate the center sample: + float4 colorBlurred = colorM; + colorBlurred.rgb *= GetKernelElement(materialIndex, 0).rgb; + + // Accumulate the other samples: + SSSS_UNROLL + for (int i = 1; i < KernelLength; i++) + { + // Fetch color and depth for current sample: + float2 offset = texcoord + GetKernelElement(materialIndex, i).a * finalStep; + float4 color = SSSSSample(colorTex, offset); + + #if SSSS_FOLLOW_SURFACE == 1 + // If the difference in depth is huge, we lerp color back to "colorM": + float depth = SSSSSample(depthTex, offset).r; + depth = CalculateViewSpaceDepth(depth); + + //float s = SSSSSaturate(300.0 * distanceToProjectionWindow * sssWidth * abs(depthM - depth)); // Original version + float s = SSSSSaturate(abs(depthM - depth) / sssWidth * 0.5); // TODO: Use a quadratic falloff or something? + color.rgb = SSSSLerp(color.rgb, colorM.rgb, s); + #endif + + // Accumulate: + colorBlurred.rgb += GetKernelElement(materialIndex, i).rgb * color.rgb; + } + + return colorBlurred; + } + + //------------------------------------------------------------------------------ + + float4 CalculateDebugView(float3 valueCenter, float3 valueTopLeft, float3 valueBottomLeft, float3 valueTopRight, float valueBottomRight, float centerImageMargin) + { + float3 output = float3(0.0, 0.0, 0.0); + + if(streams.TexCoord.x < 0.5) + { + if(streams.TexCoord.y < 0.5) + { + output = valueTopLeft; + } + else + { + output = valueBottomLeft; + } + } + else + { + if(streams.TexCoord.y < 0.5) + { + output = valueTopRight; + } + else + { + output = valueBottomRight; + } + } + + if((streams.TexCoord.x > centerImageMargin)&&(streams.TexCoord.x < 1.0 - centerImageMargin)&& + (streams.TexCoord.y > centerImageMargin)&&(streams.TexCoord.y < 1.0 - centerImageMargin)) + { + return(float4(valueCenter, 1.0)); + } + + return(float4(output, 1.0)); + } + + float4 GenerateColorFromID(int id) + { + return float4((23 + id * 109) % 256, + (67 + id * 67) % 256, + (109 + id * 23) % 256, + 255.0) / 255.0; + } + + float4 GetKernelElement(uint materialIndex, int sampleIndex) // TODO: Make both signed or unsigned? + { + return KernelBuffer.Load(materialIndex * KernelLength + sampleIndex); + } + /* + // Based on this article: https://briansharpe.wordpress.com/2011/11/15/a-fast-and-simple-32bit-floating-point-hash-function/ + float Hash(float2 p, float2 offset, float domainSize) // "p" is assumed to be an integer coordinate. + { + const float inverseLargeFloat = 1.0 / 951.135664; + + //p = p - floor(p / domain) * domain; // Truncate the domain + p = p % domainSize; // Truncate the domain (same as the above line). + p += offset; // Offset to the interesting part of the noise. + p *= p; // Square the vector. + + return(frac(p.x * p.y * inverseLargeFloat)); + } + */ + float GetRandomNumber4x4(int2 coordinate) + { + float randomNumbers[16] = + { + 0.3125, 0.625, 0.875, 0.25, + 0.1875, 0.4375, 0.0625, 0.75, + 1, 0.375, 0.6875, 0.9375, + 0.5, 0.5625, 0.8125, 0.125 + }; + + int2 wrappedCoordinate = coordinate % 4; + return randomNumbers[wrappedCoordinate.x * 4 + wrappedCoordinate.y]; + } + + float GetRandomNumber8x8(int2 coordinate) + { + float randomNumbers[64] = + { + 0.907692307692306, 0.153846153846154, 0.523076923076923, 0.769230769230768, + 0.215384615384615, 0.338461538461538, 0.030769230769230, 0.107692307692308, + 0.123076923076923, 0.492307692307692, 0.676923076923076, 0.861538461538460, + 0.692307692307692, 0.230769230769231, 0.892307692307691, 0.984615384615383, + 0.584615384615384, 0.461538461538462, 0.476923076923077, 0.015384615384615, + 0.815384615384614, 0.569230769230769, 0.092307692307692, 0.553846153846154, + 0.707692307692307, 0.307692307692308, 0.046153846153846, 0.830769230769230, + 0.384615384615385, 0.953846153846152, 0.261538461538462, 0.538461538461538, + 0.923076923076922, 0.369230769230769, 0.738461538461538, 0.753846153846153, + 0.200000000000000, 0.076923076923076, 0.415384615384615, 0.969230769230768, + 0.846153846153845, 0.169230769230769, 0.061538461538461, 0.876923076923076, + 0.600000000000000, 0.799999999999999, 0.784615384615384, 0.246153846153846, + 0.323076923076923, 0.430769230769231, 0.938461538461537, 0.138461538461538, + 0.446153846153846, 0.353846153846154, 0.292307692307692, 0.400000000000000, + 0.184615384615385, 0.723076923076922, 0.507692307692308, 0.615384615384615, + 0.276923076923077, 0.646153846153846, 0.630769230769230, 0.661538461538461 + }; + + int2 wrappedCoordinate = coordinate % 8; + return randomNumbers[wrappedCoordinate.x * 8 + wrappedCoordinate.y]; + } + /* + float GetRandomNumber(int2 coordinate) + { + return(frac(sin(dot(coordinate, float2(12.9898, 78.2332))) * 43758.5453)); + } + */ + float2 CalculateProjectionSize(float viewSpaceDepth) + { + if(OrthographicProjection) + { + return ProjectionSizeOnUnitPlaneInClipSpace; // Size stays the same regardless of distance. + } + + return ProjectionSizeOnUnitPlaneInClipSpace / viewSpaceDepth; + } + + float CalculateViewSpaceDepth(float nonlinearDepth) // TODO: Does this really convert to view space Z or just linearize the depth? + { + if(OrthographicProjection) + { + return(NearClipPlane + nonlinearDepth * (FarClipPlane - NearClipPlane)); // TODO: PERFORMANCE: Precompute "FarClipPlane - NearClipPlane" because it can't be inlined? // TODO: PERFORMANCE: And do we need the addition with "NearClipPlane"? I think it's redundant in this case because the orthographic projection matrix's near plane is at 0.0. + } + + return(ZProjection.y / (nonlinearDepth - ZProjection.x)); + } + + bool IntersectsProjectedSphere(float3 sphereWorldSpacePosition, float sphereRadiusWorldSpace, float2 clipSpaceCoordinate) + { + // Code for debugging the sampling radius calculation: + float4 projectedSphereCoordinate = mul(float4(sphereWorldSpacePosition, 1.0), ViewProjectionMatrix); + projectedSphereCoordinate.y = -projectedSphereCoordinate.y; // TODO: Why is this necessary? + projectedSphereCoordinate.xyz /= projectedSphereCoordinate.w; + + float projectedSphereViewSpaceDepth = CalculateViewSpaceDepth(projectedSphereCoordinate.z); + float2 projectedSphereScreenDimensions = CalculateProjectionSize(projectedSphereViewSpaceDepth); + + float2 SphereToPixelClipSpace = clipSpaceCoordinate.xy - projectedSphereCoordinate.xy; + + return length(SphereToPixelClipSpace / projectedSphereScreenDimensions) < sphereRadiusWorldSpace; + } + + stage override float4 Shading() + { + uint materialIndex = uint(Texture2.Load(int3(streams.ShadingPosition.xy, 0.0)).r + 0.5); // Version for material ID stored as a float. + + if(RenderMode == SHOW_SCATTERING_OBJECTS) + { + if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. + { + return 0.0; + } + + return 1.0; + } + else if(RenderMode == SHOW_MATERIAL_INDEX) + { + if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. + { + return 0.0; + } + + // Generate a "random" color using the material index: + return GenerateColorFromID(materialIndex); + } + else if(RenderMode == SHOW_SCATTERING_WIDTH) + { + return fmod(ScatteringWidths[materialIndex], 1.0); + } + + const float4 sceneColor = Texture0.Sample(LinearSampler, streams.TexCoord); + + if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. + { + return sceneColor; // Return the scene color because we are doing texture ping-ponging. + } + + float randomNumber = GetRandomNumber4x4(streams.ShadingPosition.xy + int(IterationNumber)); // More regular (shows a bit of a grid pattern) + //float randomNumber = FastRandom(streams.ShadingPosition.xy + int(IterationNumber)); // More noisy + + /* + float2 scale = CalculateProjectionSize(viewSpaceDepth); + if(scale.x < 1.0)// TODO: PEFORMANCE: Turn off rotation for small kernels (mentioned in the paper)? + { + randomNumber = 0.0; + } + */ + + float randomAngle = randomNumber * PI; // TODO: PERFORMANCE: Rotate only by 90 degrees? + randomAngle += IterationNumber; // TODO: Scale this vector somehow? Maybe from 0 to PI / 2 (depending on the number of passes). + + if(!BlurHorizontally) + { + randomAngle += PI / 2.0; + } + + float2 blurDirection = float2(cos(randomAngle), sin(randomAngle)); + float scatteringWidth = ScatteringWidths[materialIndex]; + + float4 blurredSSS = SSSSBlurPS(streams.TexCoord, + Texture0, + Texture1, // TODO: PERFORMANCE: Preconvert to view space/linearize? + scatteringWidth, + blurDirection, + false, + materialIndex); + return blurredSSS; + + // Code for debugging the sampling radius calculation: + /* + float2 clipSpaceCoordinate = streams.TexCoord.xy * 2.0 - 1.0; + if(IntersectsProjectedSphere(float3(0.0, 0.0, 0.0), 1.0, clipSpaceCoordinate)) + { + if(OrthographicProjection) + { + return sceneColor * float4(0.1, 1.0, 0.1, 1.0); + } + + return sceneColor * float4(1.0, 0.1, 0.1, 1.0); + } + */ + + // Code for debugging the SSSS in general, by visualizing the different buffers: + /* + if(BlurHorizontally) // If this is the 1st pass: + { + return blurredSSS; + } + else // If this is the 2nd pass: + { + const float nonlinearDepth = Texture1.Sample(Sampler, streams.TexCoord).r; + const float viewSpaceDepth = CalculateViewSpaceDepth(nonlinearDepth); + + const float centerImageMargin = 0.25; + + return CalculateDebugView(blurredSSS, + viewSpaceDepth, + sceneColor.rgb, //MaxMaterialCount / 500.0, + float(materialIndex) / 255.0, + ScatteringWidths[materialIndex] * 10.0, + centerImageMargin); + } + */ + } + }; +} diff --git a/assets/Stride/SDSL/SwapUV.sdsl b/assets/Stride/SDSL/SwapUV.sdsl new file mode 100644 index 0000000000..9d3b82b544 --- /dev/null +++ b/assets/Stride/SDSL/SwapUV.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Flips the V coordinate of the texcoord. +/// +/// +/// TStream: generic Semantic - Texcoord semantic. +/// +shader SwapUV : ShaderBase, Texturing +{ + stream float2 Texcoord : TStream; + + override void VSMain() + { + streams.Texcoord = float2(streams.Texcoord.x, 1.0f - streams.Texcoord.y); + base.VSMain(); + } +}; diff --git a/assets/Stride/SDSL/TangentMeshSkinning.sdsl b/assets/Stride/SDSL/TangentMeshSkinning.sdsl new file mode 100644 index 0000000000..3134d27db4 --- /dev/null +++ b/assets/Stride/SDSL/TangentMeshSkinning.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Performs skinning on the tangent. +/// +shader TangentMeshSkinning : TransformationSkinning, NormalStream +{ + override void PreTransformPosition() + { + base.PreTransformPosition(); + streams.meshTangent.xyz = mul(streams.meshTangent.xyz, (float3x3)streams.skinningBlendMatrix); + } +}; diff --git a/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl b/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl new file mode 100644 index 0000000000..01562f7281 --- /dev/null +++ b/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl @@ -0,0 +1,275 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TemporalAntiAliasShader : ImageEffectShader +{ + static const int OFFSET_LENGTH = 2; + + cbuffer PerDraw + { + float u_BlendWeightMin; // default = 1.0 / 8.0 + float u_BlendWeightMax; // default = 0.5 + float u_HistoryBlurAmp; // default = 2.0 + float u_LumaContrastFactor; // default = 128.0 + float u_VelocityDecay; // default = 0.5 + float u_WeightCenter; + float u_WeightLowCenter; + float4 u_Weight1; + float4 u_Weight2; + float4 u_WeightLow1; + float4 u_WeightLow2; + } + + // Texture0: color + // Texture1: depth + // Texture2: velocity + // Texture3: color previous frame (blurred) + stage override float4 Shading() + { + var texCoord = streams.TexCoord; + + // fetch position of current color + float centerDepth = Texture1.SampleLevel(PointSampler, streams.TexCoord, 0).r; + float3 currentUV = float3(streams.TexCoord, centerDepth); + + // fetch position of history color + float3 historyUV = currentUV; + + //-------------------------------------------------------------------------- + // Find the offset to the position with minimum depth in neighborhood + // for diolation of foreground velocity map + //-------------------------------------------------------------------------- + int2 offsets[] = + { + {-OFFSET_LENGTH, -OFFSET_LENGTH}, + { OFFSET_LENGTH, -OFFSET_LENGTH}, + {-OFFSET_LENGTH, OFFSET_LENGTH}, + { OFFSET_LENGTH, OFFSET_LENGTH} + }; + + float4 neighbor4Depths = Texture1.GatherRed(PointSampler, + streams.TexCoord, + offsets[0], + offsets[1], + offsets[2], + offsets[3]); + + float2 neighborDepthOffset = float2(OFFSET_LENGTH, OFFSET_LENGTH); + float neighborDepthOffsetX = OFFSET_LENGTH; + + if(neighbor4Depths.x < neighbor4Depths.y) + { + neighborDepthOffsetX = -OFFSET_LENGTH; + } + if(neighbor4Depths.z < neighbor4Depths.w) + { + neighborDepthOffset.x = -OFFSET_LENGTH; + } + float depthXY = min(neighbor4Depths.x, neighbor4Depths.y); + float depthZW = min(neighbor4Depths.z, neighbor4Depths.w); + if(depthXY < depthZW) + { + neighborDepthOffset.y = -OFFSET_LENGTH; + neighborDepthOffset.x = neighborDepthOffsetX; + } + + float depthXYZW = min(depthXY, depthZW); + if(centerDepth > depthXYZW) + { + historyUV.xy += neighborDepthOffset * Texture0TexelSize; + historyUV.z = depthXYZW; + } + + // neighbor 3x3 pixels + // 012 + // 345 + // 678 + float4 currentNeighborColor0 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, -1)); + float4 currentNeighborColor1 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, -1)); + float4 currentNeighborColor2 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, -1)); + float4 currentNeighborColor3 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, 0)); + float4 currentNeighborColor4 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, 0)); + float4 currentNeighborColor5 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, 0)); + float4 currentNeighborColor6 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, 1)); + float4 currentNeighborColor7 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, 1)); + float4 currentNeighborColor8 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, 1)); + + // Apply tonemapping + currentNeighborColor0.rgb *= SimpleTonemap(currentNeighborColor0.rgb); + currentNeighborColor1.rgb *= SimpleTonemap(currentNeighborColor1.rgb); + currentNeighborColor2.rgb *= SimpleTonemap(currentNeighborColor2.rgb); + currentNeighborColor3.rgb *= SimpleTonemap(currentNeighborColor3.rgb); + currentNeighborColor4.rgb *= SimpleTonemap(currentNeighborColor4.rgb); + currentNeighborColor5.rgb *= SimpleTonemap(currentNeighborColor5.rgb); + currentNeighborColor6.rgb *= SimpleTonemap(currentNeighborColor6.rgb); + currentNeighborColor7.rgb *= SimpleTonemap(currentNeighborColor7.rgb); + currentNeighborColor8.rgb *= SimpleTonemap(currentNeighborColor8.rgb); + + // Fetch velocity map with offset position by depth check + float2 velocityUV = Texture2.Sample(PointSampler, historyUV.xy).xy; // [-1, 1] + velocityUV.x = -velocityUV.x; + + float2 velocityPixels = velocityUV / Texture0TexelSize; // [-1, 1] * (RTWidth, RTHeight) + + // Fetch history color (bilinear filter) + float4 historyColor = Texture3.Sample(LinearSampler, currentUV.xy + velocityUV); + + // Apply tonemapping + historyColor.rgb *= SimpleTonemap(historyColor.rgb); + + //-------------------------------------------------------------------------- + // Find min/max luminance on current neighbor pixels + //-------------------------------------------------------------------------- + // Find minmax on cross shaped pixels (1) + // x1x + // 345 + // x7x + float4 neighborMin = min(min(min(currentNeighborColor1, currentNeighborColor3), min(currentNeighborColor4, currentNeighborColor5)), currentNeighborColor7); + float4 neighborMax = max(max(max(currentNeighborColor1, currentNeighborColor3), max(currentNeighborColor4, currentNeighborColor5)), currentNeighborColor7); + + // Find minmax on 3x3 pixels (2) + // 012 + // 345 + // 678 + float4 neighborMin2 = min(min(currentNeighborColor0, currentNeighborColor2), min(currentNeighborColor6, currentNeighborColor8)); + float4 neighborMax2 = max(max(currentNeighborColor0, currentNeighborColor2), max(currentNeighborColor6, currentNeighborColor8)); + neighborMin2 = min(neighborMin2, neighborMin); + neighborMax2 = max(neighborMax2, neighborMax); + + // Blend (1) and (2) + neighborMin = neighborMin * 0.5 + neighborMin2 * 0.5; + neighborMax = neighborMax * 0.5 + neighborMax2 * 0.5; + + // luminance range of current neighbor pixels + float currentLumaMin = Luma(neighborMin.rgb); + float currentLumaMax = Luma(neighborMax.rgb); + float currentLumaContrast = currentLumaMax - currentLumaMin; + + + // Apply LPF to current color + float4 currentLPFColor = + currentNeighborColor0 * u_WeightLow1.x + + currentNeighborColor1 * u_WeightLow1.y + + currentNeighborColor2 * u_WeightLow1.z + + currentNeighborColor3 * u_WeightLow1.w + + currentNeighborColor4 * u_WeightLowCenter + + currentNeighborColor5 * u_WeightLow2.x + + currentNeighborColor6 * u_WeightLow2.y + + currentNeighborColor7 * u_WeightLow2.z + + currentNeighborColor8 * u_WeightLow2.w; + + + //-------------------------------------------------------------------------- + // Blend history color and current LPF color + // + // Blend weight is computed from the intersect point between + // AABB(neighborMin-neighborMax) and line(historyColor-currentLPFColor). + //-------------------------------------------------------------------------- + historyColor.rgb = IntersectAABBWithLine(historyColor.rgb, + currentLPFColor.rgb, + neighborMin.rgb, + neighborMax.rgb); + + + //-------------------------------------------------------------------------- + // Apply reconstruction filter current color + // Use Blackman-Harris 3.3 + //-------------------------------------------------------------------------- + float4 currentColor = + currentNeighborColor0 * u_Weight1.x + + currentNeighborColor1 * u_Weight1.y + + currentNeighborColor2 * u_Weight1.z + + currentNeighborColor3 * u_Weight1.w + + currentNeighborColor4 * u_WeightCenter + + currentNeighborColor5 * u_Weight2.x + + currentNeighborColor6 * u_Weight2.y + + currentNeighborColor7 * u_Weight2.z + + currentNeighborColor8 * u_Weight2.w; + + // Sharpening of current filtered color + const float historyBlur = saturate((abs(velocityPixels.x) + abs(velocityPixels.y)) * u_HistoryBlurAmp); + const float sharpness = saturate(saturate(historyBlur) * 0.5 + rcp(1.0 + currentLumaContrast * u_LumaContrastFactor)); + currentColor.rgb = lerp(currentColor.rgb, currentNeighborColor4.rgb, sharpness); + + //-------------------------------------------------------------------------- + // Compute blend weight from luminance and velocity amounts + //-------------------------------------------------------------------------- + const float historyAmount = (1.0f + historyBlur) * u_BlendWeightMin; + float historyLuma = Luma(historyColor.rgb); + historyLuma = min(abs(currentLumaMin - historyLuma), abs(currentLumaMax - historyLuma)); + const float historyFactor = historyLuma * historyAmount * (1.0 + historyBlur * historyAmount * 8.0); + float blendWeight = saturate(historyFactor * rcp(max(0.001f, historyLuma + currentLumaContrast))); + + //-------------------------------------------------------------------------- + // Clamp blend weight by velocity amounts and blend weight of previous frame + //-------------------------------------------------------------------------- + const float velocityLength = sqrt(dot(velocityPixels, velocityPixels)); + const float prevBlendWeight = historyColor.a; + const float velocityDiff = abs(prevBlendWeight - velocityLength) / max(1.0, max(prevBlendWeight, velocityLength)); + blendWeight = clamp(blendWeight, velocityDiff * u_BlendWeightMin, u_BlendWeightMax); + + //-------------------------------------------------------------------------- + // Blend filtered current color and history color + //-------------------------------------------------------------------------- + float4 outputColor = float4(0.0f, 0.0f, 0.0f, 0.0f); + outputColor.rgb = lerp(historyColor.rgb, currentColor.rgb, blendWeight); + + // Save alpha channel for velocityUV weighting + outputColor.a = max(historyColor.a * u_VelocityDecay, velocityLength * rcp(u_VelocityDecay)); + + // Revert tonemapping + outputColor.rgb *= SimpleTonemapInv(outputColor.rgb); + + // Avoid NaN : transform to 0 + outputColor.rgb = -min(-outputColor.rgb, 0.0); + + return outputColor; + } + + //------------------------------------------------------------------------------ + // + // Utility functions + // + //------------------------------------------------------------------------------ + float nonzero(float a) + { + const float CLAMP_MIN= 0.001f; + return a > -CLAMP_MIN && a < CLAMP_MIN ? CLAMP_MIN : a; + } + float3 nonzero3(float3 a) + { + return float3( nonzero(a.x), nonzero(a.y), nonzero(a.z) ); + } + + float3 IntersectAABBWithLine(float3 startLine, float3 endLine, float3 minAABB, float3 maxAABB) + { + float3 minPos = min(endLine, min(minAABB, maxAABB)); + float3 maxPos = max(endLine, max(minAABB, maxAABB)); + float3 centerAABB = (maxPos + minPos) * 0.5; + float3 dir = nonzero3(endLine - startLine); + float3 invDir = rcp(dir); + float3 org = startLine - centerAABB; + float3 scaleAABB = maxPos - centerAABB; + + float3 pos0 = (scaleAABB - org) * invDir; + float3 pos1 = ((-scaleAABB) - org) * invDir; + float intersectPos = saturate(max(max(min(pos0.x, pos1.x), min(pos0.y, pos1.y)), min(pos0.z, pos1.z))); + return lerp(startLine, endLine, intersectPos); + } + + float Luma(float3 rgbColor) + { + return dot(rgbColor, float3(0.299, 0.587, 0.114)); + } + + + float3 SimpleTonemap(float3 linearColor) + { + return rcp(linearColor + 1.0f); + } + + + float3 SimpleTonemapInv(float3 tonemappedColor) + { + return rcp(1.0f - tonemappedColor); + } +}; diff --git a/assets/Stride/SDSL/TessellationAE2.sdsl b/assets/Stride/SDSL/TessellationAE2.sdsl new file mode 100644 index 0000000000..dc3a4e06d5 --- /dev/null +++ b/assets/Stride/SDSL/TessellationAE2.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/// +/// Performs Adjacent Edge tessellation on float3 stream. +/// +shader TessellationAE2 : TessellationBase, MaterialDomainStream +{ + stream float2 DomEdgeValue2[2]; + stream float2 DomVertValue2; + + stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) + { + base.TessellateHull(input, uCPID, NextCPID); + + const uint DominantEdge = uCPID * 2 + 3; + const uint DominantVertex = uCPID + 9; + + streams.DomEdgeValue2[0] = input[DominantEdge].TStream; + streams.DomEdgeValue2[1] = input[DominantEdge+1].TStream; + streams.DomVertValue2 = input[DominantVertex].TStream; + } + + stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) + { + base.InterpolateBarycentric(input, constants, f3BarycentricCoords); + + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + float + uCorner = (fU == 1 ? 1:0), + vCorner = (fV == 1 ? 1:0), + wCorner = (fW == 1 ? 1:0), + uEdge = (fU == 0 && fV * fW ? 1:0), + vEdge = (fV == 0 && fU * fW ? 1:0), + wEdge = (fW == 0 && fU * fV ? 1:0), + interior = (fU * fV * fW) ? 1 : 0; + + streams.TStream = + uCorner * input[0].DomVertValue2 + + vCorner * input[1].DomVertValue2 + + wCorner * input[2].DomVertValue2 + + uEdge * lerp(input[1].DomEdgeValue2[1], input[1].DomEdgeValue2[0], fV) + + vEdge * lerp(input[2].DomEdgeValue2[1], input[2].DomEdgeValue2[0], fW) + + wEdge * lerp(input[0].DomEdgeValue2[1], input[0].DomEdgeValue2[0], fU) + + interior * streams.TStream; + } +}; diff --git a/assets/Stride/SDSL/TessellationAE3.sdsl b/assets/Stride/SDSL/TessellationAE3.sdsl new file mode 100644 index 0000000000..9f955a4a98 --- /dev/null +++ b/assets/Stride/SDSL/TessellationAE3.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/// +/// Performs Adjacent Edge tessellation on float3 stream. +/// +shader TessellationAE3 : TessellationBase, MaterialDomainStream +{ + stream float3 DomEdgeValue3[2]; + stream float3 DomVertValue3; + + stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) + { + base.TessellateHull(input, uCPID, NextCPID); + + const uint DominantEdge = uCPID * 2 + 3; + const uint DominantVertex = uCPID + 9; + + streams.DomEdgeValue3[0] = input[DominantEdge].TStream; + streams.DomEdgeValue3[1] = input[DominantEdge+1].TStream; + streams.DomVertValue3 = input[DominantVertex].TStream; + } + + stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) + { + base.InterpolateBarycentric(input, constants, f3BarycentricCoords); + + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + float + uCorner = (fU == 1 ? 1:0), + vCorner = (fV == 1 ? 1:0), + wCorner = (fW == 1 ? 1:0), + uEdge = (fU == 0 && fV * fW ? 1:0), + vEdge = (fV == 0 && fU * fW ? 1:0), + wEdge = (fW == 0 && fU * fV ? 1:0), + interior = (fU * fV * fW) ? 1 : 0; + + streams.TStream = + uCorner * input[0].DomVertValue3 + + vCorner * input[1].DomVertValue3 + + wCorner * input[2].DomVertValue3 + + uEdge * lerp(input[1].DomEdgeValue3[1], input[1].DomEdgeValue3[0], fV) + + vEdge * lerp(input[2].DomEdgeValue3[1], input[2].DomEdgeValue3[0], fW) + + wEdge * lerp(input[0].DomEdgeValue3[1], input[0].DomEdgeValue3[0], fU) + + interior * streams.TStream; + } +}; diff --git a/assets/Stride/SDSL/TessellationAE4.sdsl b/assets/Stride/SDSL/TessellationAE4.sdsl new file mode 100644 index 0000000000..8cb8301cea --- /dev/null +++ b/assets/Stride/SDSL/TessellationAE4.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/// +/// Performs Adjacent Edge tessellation on float4 stream. +/// +shader TessellationAE4 : TessellationBase, MaterialDomainStream +{ + stream float4 DomEdgeValue4[2]; + stream float4 DomVertValue4; + + stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) + { + base.TessellateHull(input, uCPID, NextCPID); + + const uint DominantEdge = uCPID * 2 + 3; + const uint DominantVertex = uCPID + 9; + + streams.DomEdgeValue4[0] = input[DominantEdge].TStream; + streams.DomEdgeValue4[1] = input[DominantEdge+1].TStream; + streams.DomVertValue4 = input[DominantVertex].TStream; + } + + stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) + { + base.InterpolateBarycentric(input, constants, f3BarycentricCoords); + + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + float + uCorner = (fU == 1 ? 1:0), + vCorner = (fV == 1 ? 1:0), + wCorner = (fW == 1 ? 1:0), + uEdge = (fU == 0 && fV * fW ? 1:0), + vEdge = (fV == 0 && fU * fW ? 1:0), + wEdge = (fW == 0 && fU * fV ? 1:0), + interior = (fU * fV * fW) ? 1 : 0; + + streams.TStream = + uCorner * input[0].DomVertValue4 + + vCorner * input[1].DomVertValue4 + + wCorner * input[2].DomVertValue4 + + uEdge * lerp(input[1].DomEdgeValue4[1], input[1].DomEdgeValue4[0], fV) + + vEdge * lerp(input[2].DomEdgeValue4[1], input[2].DomEdgeValue4[0], fW) + + wEdge * lerp(input[0].DomEdgeValue4[1], input[0].DomEdgeValue4[0], fU) + + interior * streams.TStream; + } +}; diff --git a/assets/Stride/SDSL/TessellationBase.sdsl b/assets/Stride/SDSL/TessellationBase.sdsl new file mode 100644 index 0000000000..ebea982d65 --- /dev/null +++ b/assets/Stride/SDSL/TessellationBase.sdsl @@ -0,0 +1,127 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines the basic methods for tessellation. +/// +/// +/// InputControlPointCount: Macro - Input control points count. +/// OutputControlPointCount: Macro - Output control points count. +/// + +#ifndef InputControlPointCount +# define InputControlPointCount 3 +#endif + +#ifndef OutputControlPointCount +# define OutputControlPointCount 3 +#endif + +shader TessellationBase : ShaderBase, TransformationBase, MaterialDomainStream, Camera, Transformation, NormalBase +{ + cbuffer PerMaterial + { + [Link("Tessellation.DesiredTriangleSize")] + stage float DesiredTriangleSize = 12.0f; + } + + patchstream float tessFactor[3] : SV_TessFactor; + patchstream float insideTessFactor : SV_InsideTessFactor; + + override stage void GenerateNormal_VS() + { + base.GenerateNormal_VS(); + + // Ensure that normal is normalized at every steps of the tessellation. + streams.normalWS = normalize(streams.normalWS); + } + + [domain("tri")] + [partitioning("fractional_odd")] + [outputtopology("triangle_cw")] + [outputcontrolpoints(3)] + [patchconstantfunc("HSConstantMain")] + void HSMain(InputPatch input, out Output output, uint uCPID : SV_OutputControlPointID) + { + const uint NextCPID = uCPID < 2 ? uCPID + 1 : 0; + + streams = input[uCPID]; + + TessellateHull(input, uCPID, NextCPID); + + // Compute screen space position of current control point and next one + // TODO: Reuse ShadingPosition? + // However, not sure if we can do tessellation directly through ShadingPosition interpolation (in which case we wouldn't need to do it in domain shader either) + float2 screenPosition0 = GetScreenSpacePosition(input[uCPID].PositionWS, ViewSize.x, ViewSize.y); + float2 screenPosition1 = GetScreenSpacePosition(input[NextCPID].PositionWS, ViewSize.x, ViewSize.y); + + // Screen space tessellation based on desired triangle size + streams.oppositeEdgeLOD = distance(screenPosition0, screenPosition1) / DesiredTriangleSize; + + output = streams; + } + + void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) + { + constants.tessFactor[0] = output[1].oppositeEdgeLOD; + constants.tessFactor[1] = output[2].oppositeEdgeLOD; + constants.tessFactor[2] = output[0].oppositeEdgeLOD; + constants.insideTessFactor = 0.33f * (constants.tessFactor[0] + constants.tessFactor[1] + constants.tessFactor[2]); + + TessellateHullConstant(input, output, constants); + + if (ComputeClipping(input, output, constants)) + { + constants.tessFactor[0] = 0.0f; + constants.tessFactor[1] = 0.0f; + constants.tessFactor[2] = 0.0f; + constants.insideTessFactor = 0.0f; + } + } + + [domain("tri")] + void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) + { + InterpolateBarycentric(input, constants, f3BarycentricCoords); + + this.BaseTransformDS(); + + output = streams; + } + + stage override void BaseTransformVS() + { + this.PreTransformPosition(); + } + + stage void BaseTransformDS() + { + this.TransformPosition(); + this.PostTransformPosition(); + } + + stage override void TransformPosition() + { + base.TransformPosition(); + + // Apply tessellation map, etc... + TessellateDomain(); + } + + float2 GetScreenSpacePosition( + float4 f3Position, // View space position of patch control point + float fScreenWidth, // Screen width + float fScreenHeight // Screen height + ) + { + float4 f4ProjectedPosition = this.ComputeShadingPosition(f3Position); + float2 f2ScreenPosition = f4ProjectedPosition.xy / f4ProjectedPosition.w; + f2ScreenPosition = ( f2ScreenPosition + 1.0f ) * 0.5f * float2( fScreenWidth, -fScreenHeight ); + return f2ScreenPosition; + } + + stage void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) {} + stage void TessellateHullConstant(InputPatch input, const OutputPatch output, inout Constants constants) {} + stage float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) {} + stage void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) {} + stage void TessellateDomain() {} +}; diff --git a/assets/Stride/SDSL/TessellationFlat.sdsl b/assets/Stride/SDSL/TessellationFlat.sdsl new file mode 100644 index 0000000000..baaff3ea12 --- /dev/null +++ b/assets/Stride/SDSL/TessellationFlat.sdsl @@ -0,0 +1,49 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Tessellates without displacing. +/// +/// +/// InputControlPointCount: Macro - number of input control points. +/// + +#ifndef InputControlPointCount +#define InputControlPointCount 3 +#endif + +shader TessellationFlat : TessellationBase +{ + stage override float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) + { + return ComputeClippingGroup3(input[0].PositionWS, input[1].PositionWS, input[2].PositionWS); + } + + float ComputeClippingGroup3(float4 f3Position1, float4 f3Position2, float4 f3Position3) + { + float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); + float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); + float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); + + float3 clipPos1P = sign(clipPos1.xyz + clipPos1.www); + float3 clipPos1M = sign(clipPos1.xyz - clipPos1.www); + float3 clipPos2P = sign(clipPos2.xyz + clipPos2.www); + float3 clipPos2M = sign(clipPos2.xyz - clipPos2.www); + float3 clipPos3P = sign(clipPos3.xyz + clipPos3.www); + float3 clipPos3M = sign(clipPos3.xyz - clipPos3.www); + + float3 planeTests = abs(clipPos1P + clipPos1M + clipPos2P + clipPos2M + clipPos3P + clipPos3M); + + return all(planeTests != 6.0f) ? 0.0 : 1.0; + } + + stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) + { + //streams = input[0] * fU + input[1] * fV + input[2] * fW; + + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + streams = input[0] * fU + input[1] * fV + input[2] * fW; + } +}; diff --git a/assets/Stride/SDSL/TessellationPN.sdsl b/assets/Stride/SDSL/TessellationPN.sdsl new file mode 100644 index 0000000000..d8113fc024 --- /dev/null +++ b/assets/Stride/SDSL/TessellationPN.sdsl @@ -0,0 +1,171 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Performs PN tessellation (ensures edges preservation). +/// +/// +/// InputControlPointCount: Macro - number of input control points. +/// +#ifndef InputControlPointCount +# define InputControlPointCount 3 +#endif + +shader TessellationPN : TessellationFlat +{ + patchstream float3 f3ViewB111; + stream float3 nextPositionVS1; + stream float3 nextPositionVS2; + + float3 ComputeControlPoint(float3 pA, float3 pB, float3 nA) + { + return (2.0 * pA + pB - (dot((pB - pA), nA) * nA)) / 3.0f; + } + + float ComputeClippingGroup4(float3 f3Position1, float3 f3Position2, float3 f3Position3, float3 f3Position4) + { + float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); + float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); + float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); + float4 clipPos4 = this.ComputeShadingPosition(float4(f3Position4.xyz, 1.0f)); + + float3 planeTest; + + planeTest.x = ((-clipPos1.w <= clipPos1.x && clipPos1.x <= clipPos1.w) ? 1.0f : 0.0f) + + ((-clipPos2.w <= clipPos2.x && clipPos2.x <= clipPos2.w) ? 1.0f : 0.0f) + + ((-clipPos3.w <= clipPos3.x && clipPos3.x <= clipPos3.w) ? 1.0f : 0.0f) + + ((-clipPos4.w <= clipPos4.x && clipPos4.x <= clipPos4.w) ? 1.0f : 0.0f); + + planeTest.y = ((-clipPos1.w <= clipPos1.y && clipPos1.y <= clipPos1.w) ? 1.0f : 0.0f) + + ((-clipPos2.w <= clipPos2.y && clipPos2.y <= clipPos2.w) ? 1.0f : 0.0f) + + ((-clipPos3.w <= clipPos3.y && clipPos3.y <= clipPos3.w) ? 1.0f : 0.0f) + + ((-clipPos4.w <= clipPos4.y && clipPos4.y <= clipPos4.w) ? 1.0f : 0.0f); + + planeTest.z = ((-clipPos1.w <= clipPos1.z && clipPos1.z <= clipPos1.w) ? 1.0f : 0.0f) + + ((-clipPos2.w <= clipPos2.z && clipPos2.z <= clipPos2.w) ? 1.0f : 0.0f) + + ((-clipPos3.w <= clipPos3.z && clipPos3.z <= clipPos3.w) ? 1.0f : 0.0f) + + ((-clipPos4.w <= clipPos4.z && clipPos4.z <= clipPos4.w) ? 1.0f : 0.0f); + + return !all(planeTest != 0.0f) ? 1.0 : 0.0; + } + + float ComputeClippingGroup8(float3 f3Position1, float3 f3Position2, float3 f3Position3, float3 f3Position4, float3 f3Position5, float3 f3Position6, float3 f3Position7, float3 f3Position8) + { + float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); + float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); + float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); + float4 clipPos4 = this.ComputeShadingPosition(float4(f3Position4.xyz, 1.0f)); + float4 clipPos5 = this.ComputeShadingPosition(float4(f3Position5.xyz, 1.0f)); + float4 clipPos6 = this.ComputeShadingPosition(float4(f3Position6.xyz, 1.0f)); + float4 clipPos7 = this.ComputeShadingPosition(float4(f3Position7.xyz, 1.0f)); + float4 clipPos8 = this.ComputeShadingPosition(float4(f3Position8.xyz, 1.0f)); + + float3 planeTest; + + planeTest.x = ((-clipPos1.w <= clipPos1.x && clipPos1.x <= clipPos1.w) ? 1.0f : 0.0f) + + ((-clipPos2.w <= clipPos2.x && clipPos2.x <= clipPos2.w) ? 1.0f : 0.0f) + + ((-clipPos3.w <= clipPos3.x && clipPos3.x <= clipPos3.w) ? 1.0f : 0.0f) + + ((-clipPos4.w <= clipPos4.x && clipPos4.x <= clipPos4.w) ? 1.0f : 0.0f) + + ((-clipPos5.w <= clipPos5.x && clipPos5.x <= clipPos5.w) ? 1.0f : 0.0f) + + ((-clipPos6.w <= clipPos6.x && clipPos6.x <= clipPos6.w) ? 1.0f : 0.0f) + + ((-clipPos7.w <= clipPos7.x && clipPos7.x <= clipPos7.w) ? 1.0f : 0.0f) + + ((-clipPos8.w <= clipPos8.x && clipPos8.x <= clipPos8.w) ? 1.0f : 0.0f); + + planeTest.y = ((-clipPos1.w <= clipPos1.y && clipPos1.y <= clipPos1.w) ? 1.0f : 0.0f) + + ((-clipPos2.w <= clipPos2.y && clipPos2.y <= clipPos2.w) ? 1.0f : 0.0f) + + ((-clipPos3.w <= clipPos3.y && clipPos3.y <= clipPos3.w) ? 1.0f : 0.0f) + + ((-clipPos4.w <= clipPos4.y && clipPos4.y <= clipPos4.w) ? 1.0f : 0.0f) + + ((-clipPos5.w <= clipPos5.y && clipPos5.y <= clipPos5.w) ? 1.0f : 0.0f) + + ((-clipPos6.w <= clipPos6.y && clipPos6.y <= clipPos6.w) ? 1.0f : 0.0f) + + ((-clipPos7.w <= clipPos7.y && clipPos7.y <= clipPos7.w) ? 1.0f : 0.0f) + + ((-clipPos8.w <= clipPos8.y && clipPos8.y <= clipPos8.w) ? 1.0f : 0.0f); + + planeTest.z = ((0.0f <= clipPos1.z && clipPos1.z <= clipPos1.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos2.z && clipPos2.z <= clipPos2.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos3.z && clipPos3.z <= clipPos3.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos4.z && clipPos4.z <= clipPos4.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos5.z && clipPos5.z <= clipPos5.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos6.z && clipPos6.z <= clipPos6.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos7.z && clipPos7.z <= clipPos7.w) ? 1.0f : 0.0f) + + ((0.0f <= clipPos8.z && clipPos8.z <= clipPos8.w) ? 1.0f : 0.0f); + + return !all(planeTest != 0.0f) ? 1.0 : 0.0; + } + + stage override float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) + { + // For now, Displacement clipping is hardcoded here, need to be able to split that! (maybe not that easy, need array or something) + const float displacementSize = 75; + float3 f3Position5 = input[0].PositionWS.xyz + input[0].normalWS * displacementSize; + float3 f3Position6 = input[1].PositionWS.xyz + input[1].normalWS * displacementSize; + float3 f3Position7 = input[2].PositionWS.xyz + input[2].normalWS * displacementSize; + + float3 normalB111 = normalize((input[0].normalWS + input[1].normalWS + input[2].normalWS) / 3.0f); + float3 f3Position8 = constants.f3ViewB111 + normalB111 * displacementSize; + + return ComputeClippingGroup8(input[0].PositionWS.xyz, input[1].PositionWS.xyz, input[2].PositionWS.xyz, constants.f3ViewB111, + f3Position5, f3Position6, f3Position7, f3Position8); + //return ComputeClippingGroup4(input[0].PositionWS.xyz, input[1].PositionWS.xyz, input[2].PositionWS.xyz, constants.f3ViewB111, ViewProjection); + } + + stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) + { + streams.nextPositionVS1 = ComputeControlPoint((float3)input[uCPID].PositionWS, (float3)input[NextCPID].PositionWS, input[uCPID].normalWS); + streams.nextPositionVS2 = ComputeControlPoint((float3)input[NextCPID].PositionWS, (float3)input[uCPID].PositionWS, input[NextCPID].normalWS); + } + + stage override void TessellateHullConstant(InputPatch input, const OutputPatch output, inout Constants constants) + { + float3 f3B300 = output[0].PositionWS.xyz, + f3B210 = output[0].nextPositionVS1.xyz, + f3B120 = output[0].nextPositionVS2.xyz, + f3B030 = output[1].PositionWS.xyz, + f3B021 = output[1].nextPositionVS1.xyz, + f3B012 = output[1].nextPositionVS2.xyz, + f3B003 = output[2].PositionWS.xyz, + f3B102 = output[2].nextPositionVS1.xyz, + f3B201 = output[2].nextPositionVS2.xyz; + + float3 f3E = (f3B210 + f3B120 + f3B021 + f3B012 + f3B102 + f3B201) / 6.0f; + float3 f3V = (f3B003 + f3B030 + f3B300) / 3.0f; + constants.f3ViewB111 = f3E + ((f3E - f3V) / 2.0f); + + // TODO: Clipping test ? + //if (ComputeClipping(constants.f3ViewB111, ViewProjection)) + //{ + // constants.tessFactor[0] = 0.0f; + // constants.tessFactor[1] = 0.0f; + // constants.tessFactor[2] = 0.0f; + //} + + //float fB111Clipped = IsClipped( + // ApplyProjection(g_f4x4ViewProjection, O.f3ViewB111)); + } + + stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) + { + base.InterpolateBarycentric(input, constants, f3BarycentricCoords); + + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + float fUU = fU * fU; + float fVV = fV * fV; + float fWW = fW * fW; + float fUU3 = fUU * 3.0f; + float fVV3 = fVV * 3.0f; + float fWW3 = fWW * 3.0f; + + streams.PositionWS = + float4((float3)input[0].PositionWS * fUU * fU + + (float3)input[1].PositionWS * fVV * fV + + (float3)input[2].PositionWS * fWW * fW + + input[0].nextPositionVS1 * fUU3 * fV + + input[0].nextPositionVS2 * fVV3 * fU + + input[1].nextPositionVS1 * fVV3 * fW + + input[1].nextPositionVS2 * fWW3 * fV + + input[2].nextPositionVS1 * fWW3 * fU + + input[2].nextPositionVS2 * fUU3 * fW + + constants.f3ViewB111 * 6.0f * fW * fU * fV, 1.0f); + } +}; diff --git a/assets/Stride/SDSL/TessellationTest.sdsl b/assets/Stride/SDSL/TessellationTest.sdsl new file mode 100644 index 0000000000..161b4bc557 --- /dev/null +++ b/assets/Stride/SDSL/TessellationTest.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TessellationTest +{ + patchstream float tessFactor[3] : SV_TessFactor; + patchstream float insideTessFactor : SV_InsideTessFactor; + + float test(Constants constants) + { + return constants.tessFactor[0] + constants.insideTessFactor; + } + + float test2(InputPatch input, OutputPatch output, inout Constants constants) + { + return 0.0f; + } + + float test3(InputPatch input, OutputPatch output, inout Constants constants) + { + return test2(input, output, constants); + } +}; diff --git a/assets/Stride/SDSL/TestComputeColor.sdsl b/assets/Stride/SDSL/TestComputeColor.sdsl new file mode 100644 index 0000000000..79a70a2305 --- /dev/null +++ b/assets/Stride/SDSL/TestComputeColor.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColor +{ + float4 Compute(float4 color) + { + return color; + } +}; diff --git a/assets/Stride/SDSL/TestComputeColor2.sdsl b/assets/Stride/SDSL/TestComputeColor2.sdsl new file mode 100644 index 0000000000..4fe2cdd536 --- /dev/null +++ b/assets/Stride/SDSL/TestComputeColor2.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColor2 : ComputeColor +{ + [Color] + float4 Color; + + override float4 Compute(float4 color) + { + return Color + color * 1; + } +}; diff --git a/assets/Stride/SDSL/TestComputeColorRedirect.sdsl b/assets/Stride/SDSL/TestComputeColorRedirect.sdsl new file mode 100644 index 0000000000..6d3ff13808 --- /dev/null +++ b/assets/Stride/SDSL/TestComputeColorRedirect.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ComputeColorRedirect : ComputeColor +{ + compose TestComputeColor ColorRedirect; + + override float4 Compute(float4 color) + { + return ColorRedirect.Compute(color) + color * 1; + } +}; diff --git a/assets/Stride/SDSL/TestComputeShader.sdsl b/assets/Stride/SDSL/TestComputeShader.sdsl new file mode 100644 index 0000000000..4cfbb18e4b --- /dev/null +++ b/assets/Stride/SDSL/TestComputeShader.sdsl @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +#ifndef ThreadCountX +# define ThreadCountX 10 +#endif +#ifndef ThreadCountY +# define ThreadCountY 5 +#endif +#ifndef ThreadCountZ +# define ThreadCountZ 2 +#endif + +shader TestComputeShader +{ + stage stream uint3 GroupId : SV_GroupID; + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + stage stream uint3 GroupThreadId : SV_GroupThreadID; + stage stream uint GroupIndex : SV_GroupIndex; + + stage stream uint3 ThreadGroupCount; + stage stream uint ThreadCountPerGroup; + stage stream uint ThreadGroupIndex; + + cbuffer PerDispatch { + //[Link("Stride.Effects.ComputeShaderPluginKeys.ThreadGroupCount")] + stage uint3 ThreadGroupCountGlobal; + }; + + cbuffer ParticleCountBuffer { + uint ParticleCount; + uint ParticleStartIndex; + }; + + stage RWStructuredBuffer ParticleSortBuffer; + [Link("ParticleSortBuffer")] + stage StructuredBuffer ParticleSortBufferRO; + + [numthreads(ThreadCountX, ThreadCountY, ThreadCountZ)] + void CSMain() + { + streams.ThreadCountPerGroup = ThreadCountX * ThreadCountY * ThreadCountZ; + streams.ThreadGroupCount = ThreadGroupCountGlobal; + streams.ThreadGroupIndex = (streams.GroupId.z * streams.ThreadGroupCount.y + streams.GroupId.y) * streams.ThreadGroupCount.x + streams.GroupId.x; + Compute(); + } + + void Compute() + { + ParticleSortBuffer[0] = uint2(0,1); + uint numStructs; + uint stride; + ParticleSortBufferRO.GetDimensions(numStructs, stride); + ParticleSortBuffer.IncrementCounter(); + ParticleSortBuffer.DecrementCounter(); + } +}; diff --git a/assets/Stride/SDSL/TestErrors.sdsl b/assets/Stride/SDSL/TestErrors.sdsl new file mode 100644 index 0000000000..352ad88626 --- /dev/null +++ b/assets/Stride/SDSL/TestErrors.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestErrors +{ + abstract override void test0(); // 1 error + 1 error + override void test1(); // 2 errors + 1 error + abstract void test2(){} // 1 error + + stream float myStream; + float nonStream; + + extern int falseExtern = stage; // 2 errors + + extern ExternMixin myExtern; + + void test3() + { + test3(); // cyclic error + this.testNone(); // this error + 1 type inference + test1(); // 1 error call to declaration + + streams.myStream = myStream + 1.0f; // 1 error + streams.myStream = streams.nonStream; // 2 errors + streams.myStream = stage.noMember; // stage use error + stage name error + 2 types errors + + var varVar; // 1 error + + myExtern.falseCall(); // 1 no member error + 2 function not found errors + } + + void test4() + { + base.test4(); // no base mixin + base error + 1 type inferences + } + + float test5(float param) + { + return param; + } + int test5(int param) + { + return param; + } + + float test6() + { + var varIn; // 1 error + var varOut = test5(param); // 1 var error + 2 function error + } +}; diff --git a/assets/Stride/SDSL/TestExternArray.sdsl b/assets/Stride/SDSL/TestExternArray.sdsl new file mode 100644 index 0000000000..d1225b19c6 --- /dev/null +++ b/assets/Stride/SDSL/TestExternArray.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestExternArray +{ + compose ExternMixin externArray[]; + + float test() + { + externArray[0].externFunc(); + externArray[1].externFunc(); + + float a = externArray[0].externMember + externArray[1].externMember; + + foreach (var ext in externArray) + { + ext.externFunc(); + a += ext.externMember; + } + + return a; + } +}; diff --git a/assets/Stride/SDSL/TestGenerator.sdsl b/assets/Stride/SDSL/TestGenerator.sdsl new file mode 100644 index 0000000000..974dfaed88 --- /dev/null +++ b/assets/Stride/SDSL/TestGenerator.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader TestGenerator +{ + cbuffer ConstantBuffer + { + float TestFloat; + [Color] + float3 TestColor; + } +}; diff --git a/assets/Stride/SDSL/TestGenericComplex.sdsl b/assets/Stride/SDSL/TestGenericComplex.sdsl new file mode 100644 index 0000000000..2519535b95 --- /dev/null +++ b/assets/Stride/SDSL/TestGenericComplex.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestGenericComplex +{ + float test0() + { + return TestGenericMacro.test(); + } +}; diff --git a/assets/Stride/SDSL/TestGenericMacro.sdsl b/assets/Stride/SDSL/TestGenericMacro.sdsl new file mode 100644 index 0000000000..30d55dc807 --- /dev/null +++ b/assets/Stride/SDSL/TestGenericMacro.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestGenericMacro +{ + float test() + { + return MACRO; + } +}; diff --git a/assets/Stride/SDSL/TestGenerics.sdsl b/assets/Stride/SDSL/TestGenerics.sdsl new file mode 100644 index 0000000000..c96d51ee3a --- /dev/null +++ b/assets/Stride/SDSL/TestGenerics.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestGenerics +{ + float myMember = 2.0f; + + float test() + { + return myMember + myGen; + } +}; diff --git a/assets/Stride/SDSL/TestMacros.sdsl b/assets/Stride/SDSL/TestMacros.sdsl new file mode 100644 index 0000000000..ad4ff21633 --- /dev/null +++ b/assets/Stride/SDSL/TestMacros.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestMacros : PositionVertexTransform, ShadingBase +{ + compose MacroTest macros0; + compose MacroTest macros1; + compose MacroTest macros2; + + stage override void PSMain() + { + base.PSMain(); + float4 color = macros0.u * streams.ColorTarget + macros1.u * macros2.u; + streams.ColorTarget = color; + } +}; diff --git a/assets/Stride/SDSL/TestMacrosArray.sdsl b/assets/Stride/SDSL/TestMacrosArray.sdsl new file mode 100644 index 0000000000..fbf4bf4b1f --- /dev/null +++ b/assets/Stride/SDSL/TestMacrosArray.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestMacrosArray : PositionVertexTransform, ShadingBase +{ + compose MacroTest macrosArray[]; + + stage override void PSMain() + { + base.PSMain(); + float4 color = macrosArray[0].u * streams.ColorTarget + macrosArray[1].u * macrosArray[2].u; + streams.ColorTarget = color; + } +}; diff --git a/assets/Stride/SDSL/TestMultipleStatic.sdsl b/assets/Stride/SDSL/TestMultipleStatic.sdsl new file mode 100644 index 0000000000..a3bc389325 --- /dev/null +++ b/assets/Stride/SDSL/TestMultipleStatic.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestMultipleStatic +{ + compose StaticCallMixin staticExtern; + + void test() + { + StaticMixin.staticCall(); + float u = StaticMixin.staticMember; + } +}; diff --git a/assets/Stride/SDSL/TestPixelStream.sdsl b/assets/Stride/SDSL/TestPixelStream.sdsl new file mode 100644 index 0000000000..1934dae119 --- /dev/null +++ b/assets/Stride/SDSL/TestPixelStream.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestPixelStream : TestScreenPosition +{ + stream float4 OutputColor; + + void PSMain() + { + streams.OutputColor = streams.ScreenPosition; + } +}; diff --git a/assets/Stride/SDSL/TestScreenPosition.sdsl b/assets/Stride/SDSL/TestScreenPosition.sdsl new file mode 100644 index 0000000000..64bf3fc629 --- /dev/null +++ b/assets/Stride/SDSL/TestScreenPosition.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestScreenPosition +{ + stream float4 ScreenPosition; +}; diff --git a/assets/Stride/SDSL/TestStream.sdsl b/assets/Stride/SDSL/TestStream.sdsl new file mode 100644 index 0000000000..295f9f3e98 --- /dev/null +++ b/assets/Stride/SDSL/TestStream.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestStream : ShaderBase +{ + stage stream float2 Position : POSITION; + stage stream float blend; + + stage override void VSMain() + { + streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); + } + + stage override void PSMain() + { + var backup = streams; + Toto(backup); + + streams.ColorTarget = float4(streams.Position, 0, 1); + } + + + void Toto(Streams backup) + { + streams.Position = lerp(streams.Position, backup.Position, backup.blend); + } +}; diff --git a/assets/Stride/SDSL/TestStreams.sdsl b/assets/Stride/SDSL/TestStreams.sdsl new file mode 100644 index 0000000000..27b2b8ebc6 --- /dev/null +++ b/assets/Stride/SDSL/TestStreams.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestStreams : TestVertexStream, TestPixelStream +{ + void test0(Input input) + { + streams = input; + float4 a = streams.Position; + } +}; diff --git a/assets/Stride/SDSL/TestStructInheritance.sdsl b/assets/Stride/SDSL/TestStructInheritance.sdsl new file mode 100644 index 0000000000..e1e3303443 --- /dev/null +++ b/assets/Stride/SDSL/TestStructInheritance.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestStructInheritance : TestStructure +{ + myStruct member; + + float test2() + { + return member.structFloat; + } +}; diff --git a/assets/Stride/SDSL/TestStructure.sdsl b/assets/Stride/SDSL/TestStructure.sdsl new file mode 100644 index 0000000000..90a066bd71 --- /dev/null +++ b/assets/Stride/SDSL/TestStructure.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestStructure +{ + struct myStruct + { + float structFloat; + }; + + float test(myStruct param) + { + return param.structFloat; + } +}; diff --git a/assets/Stride/SDSL/TestVertexStream.sdsl b/assets/Stride/SDSL/TestVertexStream.sdsl new file mode 100644 index 0000000000..ca183348e1 --- /dev/null +++ b/assets/Stride/SDSL/TestVertexStream.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TestVertexStream : TestScreenPosition +{ + stream float4 Position; + + void VSMain() + { + // TODO: remove extra code for this type check (float * floatX) + streams.ScreenPosition = 2.0*streams.Position; + } +}; diff --git a/assets/Stride/SDSL/TextureProjectionCommon.sdsl b/assets/Stride/SDSL/TextureProjectionCommon.sdsl new file mode 100644 index 0000000000..949927b884 --- /dev/null +++ b/assets/Stride/SDSL/TextureProjectionCommon.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines the texture that is projected onto geometry. + /// + shader TextureProjectionCommon + { + cbuffer PerLightGroup + { + [Link("TextureProjection.UVScale")] // Defined in "TextureProjectionKeys". + float2 UVScale; + + [Link("TextureProjection.UVOffset")] // Defined in "TextureProjectionKeys". + float2 UVOffset; + } + + rgroup PerLightGroup + { + [Link("TextureProjection.ProjectionTexture")] // Defined in "TextureProjectionKeys". + Texture2D ProjectionTexture; + } + }; +} diff --git a/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl b/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl new file mode 100644 index 0000000000..9ac0e20ba1 --- /dev/null +++ b/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Filters the texture projected by a light using a linear sampler at the specified mip map level. + /// + /// + /// PerLightGroup: Parameter used to uniquely identify this group of lights. + /// + internal shader TextureProjectionFilterDefault : + TextureProjectionCommon, // Defines "ProjectionTexture". + Texturing // Defines "LinearSampler". + { + // Filters the projected texture using a linear sampler at the specified mip map level. + float3 FilterProjectedTexture(float2 textureCoordinate, float mipMapLevel) + { + return ProjectionTexture.SampleLevel(LinearSampler, textureCoordinate * UVScale + UVOffset, mipMapLevel).rgb; + } + }; +} diff --git a/assets/Stride/SDSL/TextureProjectionGroup.sdsl b/assets/Stride/SDSL/TextureProjectionGroup.sdsl new file mode 100644 index 0000000000..44d82daba8 --- /dev/null +++ b/assets/Stride/SDSL/TextureProjectionGroup.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Defines a base function for calculating the color of a texture projected by a light onto a world space position. + /// Based on whether or not the light has texture projection enabled, this function will be overridden by one that computes the projection. + /// + shader TextureProjectionGroup + { + // Computes the color of the projected texture for a given world position and light index + float3 ComputeTextureProjection(float3 positionWS, int lightIndex) + { + return 1.0f; + } + + // Computes a reflection of the texture projector + float3 ComputeSpecularTextureProjection(float3 positionWS, float3 reflectionWS, int lightIndex) + { + return 1.0f; + } + }; +} diff --git a/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl b/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl new file mode 100644 index 0000000000..f172e97466 --- /dev/null +++ b/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl @@ -0,0 +1,186 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Base class for computing texture projection for a light. Defines functions for computing the color of the projected texture at this world space position. + /// + /// + /// PerLightGroup: Parameter used to uniquely identify this group of lights. + /// TCascadeCountBase: The number of cascades of the current light. + /// TLightCountBase: The number of lights inside of this light group. + /// + internal shader TextureProjectionReceiverBase : // TODO: Rename to "TextureProjectionReceiver". + TextureProjectionCommon, // Required for accessing the texture that is projected. + TextureProjectionFilterDefault, // Defines "FilterProjectedTexture()". + Texturing // Required for the texture sampling. + { + // Enum values for the texture flip mode: + // These values have to match the ones defined in "LightSpot.cs". + const int FlipModeNone = 0; + const int FlipModeX = 1; + const int FlipModeY = 2; + const int FlipModeXY = 3; + ///////////////////////////////////////////////////////////////// + + cbuffer PerLightGroup + { + float4x4 WorldToProjectiveTextureUV[TCascadeCountBase * TLightCountBase]; + float4x4 ProjectorPlaneMatrices[TCascadeCountBase * TLightCountBase]; // Contains the world matrix of the projector plane. Required for ray-plane intersection testing. + float ProjectionTextureMipMapLevels[TLightCountBase]; // TODO: Not sure how to handle this in combination with cascades. + float TransitionAreas[TLightCountBase]; + }; + + /* + // Returns "1.0" if "point" is inside the box defined by "bottomLeft" and "topRight". Returns "0.0" otherwise. + // This function was taken from here: http://stackoverflow.com/questions/12751080/glsl-point-inside-box-test + float InsideOfRectangle(float2 p, float2 bottomLeft, float2 topRight) + { + float2 s = step(bottomLeft, p) - step(topRight, p); + return(s.x * s.y); + } + */ + + // The "transitionArea" parameter defines the size of the transition area between inside and outside the rectangle. + // The transition is faded inside the rectangle, not outside of it. + // NOTE: The "transitionArea" parameter must be smaller than the distance between "bottomLeft" and "topRight" (in each dimension). + // More information: http://stackoverflow.com/questions/12751080/glsl-point-inside-box-test + float insideOfRectangleSmooth(float2 p, float2 bottomLeft, float2 topRight, float transitionArea) + { + float2 s = smoothstep(bottomLeft, bottomLeft + transitionArea, p) - + smoothstep(topRight - transitionArea, topRight, p); + return(s.x * s.y); + } + + float CalculateRectangularMask(float2 projectedTextureCoordinate, float clipSpaceZ, float transitionArea) + { + // Mask the projection at the edges of the frustum: + //float mask = InsideOfRectangle(projectedTextureCoordinate, 0.0f, 1.0f); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. + float mask = insideOfRectangleSmooth(projectedTextureCoordinate, 0.0f, 1.0f, transitionArea); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. + + // Now mask the back projection, because we don't want any texture on the back of the light: + // TODO: PERFORMANCE: Profile performance difference between branching and masking the back projection. + //if(clipSpaceCoordinate.z < 0.0f) + //{ + // return float3(0.0f, 0.0f, 0.0f); + //} + + // Same as the above but branchless: + mask *= step(0.0f, clipSpaceZ); // If clipSpaceCoordinate.z >= 0.0f, return 1.0f. Otherwise return 0.0f. // TODO: Maybe we should move this to the light attenuation code. + + return mask; + } + + void ModifyTextureCoordinate(inout float2 textureCoordinate) + { + if(TFlipMode == FlipModeX || TFlipMode == FlipModeXY) + { + textureCoordinate.x = 1.0f - textureCoordinate.x; + } + + if(TFlipMode == FlipModeY || TFlipMode == FlipModeXY) + { + textureCoordinate.y = 1.0f - textureCoordinate.y; + } + } + + // Implemented according to "http://geomalgorithms.com/a06-_intersect-2.html". + bool IntersectPlane(float3 rayOrigin, float3 rayDirection, float3 planeNormal, float3 planeOrigin, out float3 pointOfIntersection) + { + const float epsilon = 0.001f; + + float planeDotRayOrigin = dot(planeNormal, planeOrigin - rayOrigin); + float planeDotRayDirection = dot(planeNormal, rayDirection); + + if((planeDotRayDirection > -epsilon)&&(planeDotRayDirection < epsilon)) // The ray is (almost) parallel to the plane. No intersection is possible: + { + return(false); + } + + /* + When the denominator n_dot_(P1-P0)=0, the line L is parallel to the plane P, + and thus either does not intersect it or else lies completely in the plane + (whenever either P0 or P1 is in P ). + Otherwise, when the denominator is nonzero and rI is a real number, + then the ray R intersects the plane P only when rI.ge.0. + A segment S intersects P only if rI.ge-0.le-1. + In all algorithms, the additional test rI.le.1 is the only difference for a segment instead of a ray. + */ + + float intersectionDistance = planeDotRayOrigin / planeDotRayDirection; + + if(intersectionDistance >= 0.0f) // TODO: Remove branch? + { + pointOfIntersection = rayOrigin + rayDirection * intersectionDistance; + return(true); + } + + return(false); + } + + // Computes a reflection fo the texture projector the world position "positionWS". + float3 ComputeSpecularTextureProjectionFromCascade(float3 positionWS, float3 reflectionWS, int cascadeIndex, int lightIndex) + { + int matrixIndex = cascadeIndex + lightIndex * TCascadeCountBase; + + float3 rayOrigin = positionWS; + float3 rayDirection = reflectionWS; + + float4x4 projectorPlaneMatrix = ProjectorPlaneMatrices[matrixIndex]; + float3 planeAxisX = float3(projectorPlaneMatrix._m00, projectorPlaneMatrix._m01, projectorPlaneMatrix._m02); + float3 planeAxisY = float3(projectorPlaneMatrix._m10, projectorPlaneMatrix._m11, projectorPlaneMatrix._m12); + float3 planeNormal = float3(projectorPlaneMatrix._m20, projectorPlaneMatrix._m21, projectorPlaneMatrix._m22); // Z axis + float3 planeOrigin = float3(projectorPlaneMatrix._m30, projectorPlaneMatrix._m31, projectorPlaneMatrix._m32); // Position/Origin + + float3 pointOfIntersection; + bool intersectionFound = IntersectPlane(rayOrigin, rayDirection, planeNormal, planeOrigin, pointOfIntersection); + + if(intersectionFound) // TODO: PERFORMANCE: Branch or just mask the result? + { + float mipMapLevel = ProjectionTextureMipMapLevels[lightIndex]; + float transitionArea = TransitionAreas[lightIndex]; + + float planeWidth = length(planeAxisX); + float planeHeight = length(planeAxisY); + + // Project the intersection point to plane space: + float3 planeOriginToPointOfIntersection = pointOfIntersection - planeOrigin; + float planeSpaceX = dot(planeOriginToPointOfIntersection, planeAxisX) / planeWidth; + float planeSpaceY = dot(planeOriginToPointOfIntersection, planeAxisY) / planeHeight; + + // Normalize the plane space coordinates: + float2 planeTextureCoordinate = float2(planeSpaceX, planeSpaceY) * 0.5f / float2(planeWidth, planeHeight) + 0.5f; + //planeTextureCoordinate = 1.0f - planeTextureCoordinate; + + //float planeReflectionMask = insideOfRectangleSmooth(planeTextureCoordinate, 0.0f, 1.0f, transitionArea); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. + float planeReflectionMask = CalculateRectangularMask(planeTextureCoordinate, + dot(planeNormal, rayDirection), // Pass dot product instead of clip space z, because all we need is a negative value to mask out he back side. + transitionArea); + + return FilterProjectedTexture(planeTextureCoordinate, mipMapLevel) * planeReflectionMask; + + } + + return 0.0f; + } + + // Computes the color of the projected texture at the world position "positionWS". + float3 ComputeTextureProjectionFromCascade(float3 positionWS, int cascadeIndex, int lightIndex) + { + int matrixIndex = cascadeIndex + lightIndex * TCascadeCountBase; + + float4 clipSpaceCoordinate = mul(float4(positionWS, 1.0), WorldToProjectiveTextureUV[matrixIndex]); + float2 projectedTextureCoordinate = clipSpaceCoordinate.xy / clipSpaceCoordinate.w; // W-divide because it's a projection matrix. + projectedTextureCoordinate.xy = projectedTextureCoordinate.xy * 0.5 + 0.5; // Offset the clip space coordinates from [-1.0 ... 1.0] to [0.0 ... 1.0]. + projectedTextureCoordinate.y = 1.0f - projectedTextureCoordinate.y; + + ModifyTextureCoordinate(projectedTextureCoordinate); + + // TODO: PERFORMANCE: Using a texture border and setting the wrapping mode to "clamp" would be faster. Not sure if that would be a possibility though. + float mipMapLevel = ProjectionTextureMipMapLevels[lightIndex]; + float transitionArea = TransitionAreas[lightIndex]; + float mask = CalculateRectangularMask(projectedTextureCoordinate, clipSpaceCoordinate.z, transitionArea); + return FilterProjectedTexture(projectedTextureCoordinate, mipMapLevel) * mask; + } + }; +} diff --git a/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl b/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl new file mode 100644 index 0000000000..4ab863d30f --- /dev/null +++ b/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Lights +{ + /// + /// Computes the texture projection of a spotlight. Returns the color of the projected texture at this world space position. + /// + /// + /// PerLightGroup: Parameter used to uniquely identify this group of lights. + /// TLightCount: The number of lights inside of this light group. + /// + internal shader TextureProjectionReceiverSpot : + TextureProjectionGroup, // Defines "ComputeTextureProjection()", which this shader overrides. + TextureProjectionReceiverBase // Defines "CalculateTextureProjectionFromCascade()". + { + override float3 ComputeTextureProjection(float3 positionWS, int lightIndex) + { + return ComputeTextureProjectionFromCascade(positionWS, 0, lightIndex); // Spotlights have only one cascade, so we hardcode the cascade index to zero. + } + + override float3 ComputeSpecularTextureProjection(float3 positionWS, float3 reflectionWS, int lightIndex) + { + return ComputeSpecularTextureProjectionFromCascade(positionWS, reflectionWS, 0, lightIndex); // Spotlights have only one cascade, so we hardcode the cascade index to zero. + } + }; +} diff --git a/assets/Stride/SDSL/Texturing.sdsl b/assets/Stride/SDSL/Texturing.sdsl new file mode 100644 index 0000000000..4f201a2c8f --- /dev/null +++ b/assets/Stride/SDSL/Texturing.sdsl @@ -0,0 +1,124 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Texturing +{ + // Default texture slots - might be automatically used by the material + stage Texture2D Texture0; + stage float2 Texture0TexelSize; + stage Texture2D Texture1; + stage float2 Texture1TexelSize; + stage Texture2D Texture2; + stage float2 Texture2TexelSize; + stage Texture2D Texture3; + stage float2 Texture3TexelSize; + stage Texture2D Texture4; + stage float2 Texture4TexelSize; + stage Texture2D Texture5; + stage float2 Texture5TexelSize; + stage Texture2D Texture6; + stage float2 Texture6TexelSize; + stage Texture2D Texture7; + stage float2 Texture7TexelSize; + stage Texture2D Texture8; + stage float2 Texture8TexelSize; + stage Texture2D Texture9; + stage float2 Texture9TexelSize; + + // Default texture cube slots + stage TextureCube TextureCube0; + stage TextureCube TextureCube1; + stage TextureCube TextureCube2; + stage TextureCube TextureCube3; + + // Default texture 3D slots + stage Texture3D Texture3D0; + stage Texture3D Texture3D1; + stage Texture3D Texture3D2; + stage Texture3D Texture3D3; + + // Default sampler + stage SamplerState Sampler; + + stage SamplerState PointSampler + { + Filter = MIN_MAG_MIP_POINT; + }; + + stage SamplerState LinearSampler + { + Filter = MIN_MAG_MIP_LINEAR; + }; + + stage SamplerState LinearBorderSampler + { + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Border; + AddressV = Border; + }; + + stage SamplerComparisonState LinearClampCompareLessEqualSampler + { + Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT; + AddressU = Clamp; + AddressV = Clamp; + ComparisonFunc = LessEqual; + + }; + + stage SamplerState AnisotropicSampler + { + Filter = ANISOTROPIC; + }; + + stage SamplerState AnisotropicRepeatSampler + { + Filter = ANISOTROPIC; + AddressU = Wrap; + AddressV = Wrap; + MaxAnisotropy = 16; + }; + + stage SamplerState PointRepeatSampler + { + Filter = MIN_MAG_MIP_POINT; + AddressU = Wrap; + AddressV = Wrap; + }; + + stage SamplerState LinearRepeatSampler + { + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; + }; + + stage SamplerState RepeatSampler + { + AddressU = Wrap; + AddressV = Wrap; + }; + + // Default custom samplers - might be automatically used by the materials + stage SamplerState Sampler0; + stage SamplerState Sampler1; + stage SamplerState Sampler2; + stage SamplerState Sampler3; + stage SamplerState Sampler4; + stage SamplerState Sampler5; + stage SamplerState Sampler6; + stage SamplerState Sampler7; + stage SamplerState Sampler8; + stage SamplerState Sampler9; + + // Texcoord attribute inputs + stage stream float2 TexCoord : TEXCOORD0; + stage stream float2 TexCoord1 : TEXCOORD1; + stage stream float2 TexCoord2 : TEXCOORD2; + stage stream float2 TexCoord3 : TEXCOORD3; + stage stream float2 TexCoord4 : TEXCOORD4; + stage stream float2 TexCoord5 : TEXCOORD5; + stage stream float2 TexCoord6 : TEXCOORD6; + stage stream float2 TexCoord7 : TEXCOORD7; + stage stream float2 TexCoord8 : TEXCOORD8; + stage stream float2 TexCoord9 : TEXCOORD9; +}; diff --git a/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl b/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl new file mode 100644 index 0000000000..cebf4b907b --- /dev/null +++ b/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl @@ -0,0 +1,65 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Makes front-objects transparent for the back out-of-focus area. + /// + shader ThresholdAlphaCoC: ImageEffectShader + { + // Previous CoC value (lower level) + float CoCReference; + + // Current CoC value + float CoCCurrent; + + // the epsilon is 0.5% of the -1;1 range of the CoC, which is enough to fix the problem of largely foreground objects getting selected as background. + static const float CoCCompareEpsilon = 0.01; + + stage override float4 Shading() + { + float4 color = Texture0.Sample(Sampler, streams.TexCoord).rgba; + + float4 result = color; + + float minCoC = Texture1.Sample(Sampler, streams.TexCoord).x; + + // To sample multiple neighbors + /* + float neighborCoC[5]; + + neighborCoC[0] = Texture1.Sample(Sampler, streams.TexCoord).x; + neighborCoC[1] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, 1)).x; + neighborCoC[2] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, -1)).x; + neighborCoC[3] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(1,0)).x; + neighborCoC[4] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(-1, 0)).x; + + float minCoC = 1; + [unroll] + for (int i = 0; i < 5; i++) + { + minCoC = min(minCoC, neighborCoC[i]); + } + */ + + // Front-objects are made transparent. & use an epsilon to give slack to the compare operator + if (minCoC < CoCReference + CoCCompareEpsilon) + { + + if (CoCReference > 0) + { + // Keep a "ghost" of the bleeding front object. + // The closest to our level, the more visible. + result.a = saturate ( lerp(0, 1, minCoC / CoCReference) ); + } + else + { + result.a = 0.0; + } + } + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl b/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl new file mode 100644 index 0000000000..c306650a9c --- /dev/null +++ b/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl @@ -0,0 +1,53 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Makes back-objects transparent for the front out-of-focus area. + /// + shader ThresholdAlphaCoCFront: ImageEffectShader + { + + // Previous CoC value (higher level in the negative values) + float CoCReference; + + // Current CoC value + float CoCCurrent; + + stage override float4 Shading() + { + float4 color = Texture0.Sample(Sampler, streams.TexCoord).rgba; + + float4 result = color; + + float minCoC = - Texture1.Sample(Sampler, streams.TexCoord).x; + + // To sample multiple neighbors + /* + float neighborCoC[5]; + + neighborCoC[0] = - Texture1.Sample(Sampler, streams.TexCoord).x; + neighborCoC[1] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, 1)).x; + neighborCoC[2] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, -1)).x; + neighborCoC[3] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(1,0)).x; + neighborCoC[4] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(-1, 0)).x; + + float minCoC = 1; + [unroll] + for (int i = 0; i < 1; i++) + { + minCoC = min(minCoC, neighborCoC[i]); + } + */ + + // Pixel higher than the current CoC level will be opaque. + // Under the CoC of the previous pass, completely transparent. + // Between the two CoC, lerp. + float range = CoCCurrent - CoCReference; + result.a = saturate( lerp(0, 1, (minCoC - CoCReference) / range ) ); + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/ToGlslShader.sdsl b/assets/Stride/SDSL/ToGlslShader.sdsl new file mode 100644 index 0000000000..7f63bf41fd --- /dev/null +++ b/assets/Stride/SDSL/ToGlslShader.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader ToGlslShader : ShaderBase, Texturing +{ + stage stream float2 Position : POSITION; + + float4 BaseColor; + + float TestArray[4]; + + stage override void VSMain() + { + streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); + } + + stage override void PSMain() + { + streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor*TestArray[0]*TestArray[1] + Texture0.Sample(PointRepeatSampler, streams.Position); + } +}; diff --git a/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl new file mode 100644 index 0000000000..44238e6259 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The ACES tonemap operator. + /// + internal shader ToneMapACESOperatorShader : ToneMapCommonOperatorShader + { + // ACES filmic tonemapper with highlight desaturation ("crosstalk"). + // Based on the curve fit by Krzysztof Narkowicz. + // https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ + + override float4 Compute(float4 color) + { + float pixelLuminance = LuminanceUtils.Luma(color); + + // ACES Tonemapper + const float a = 2.51f; + const float b = 0.03f; + const float c = 2.43f; + const float d = 0.59f; + const float e = 0.14f; + + float toneMappedLuminance = (pixelLuminance * (a * pixelLuminance + b)) / (pixelLuminance * (c * pixelLuminance + d) + e); + float whiteLuminance = (WhiteLevel * (a * WhiteLevel + b)) / (WhiteLevel * (c * WhiteLevel + d) + e); + return toneMappedLuminance / whiteLuminance * pow(color / pixelLuminance, LuminanceSaturation); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl new file mode 100644 index 0000000000..e17a49d894 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The common tonemap operator used by Reinhard, Drago, Exponential, Logarithmic. Just define common variables + /// + internal shader ToneMapCommonOperatorShader : ToneMapOperatorShader + { + float LuminanceSaturation = 1.0f; + float WhiteLevel = 5.0f; + }; +} diff --git a/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl new file mode 100644 index 0000000000..9a4c4bdce1 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The Drago tonemap operator. + /// + internal shader ToneMapDragoOperatorShader : ToneMapCommonOperatorShader + { + float DragoBias = 0.5f; + + override float4 Compute(float4 color) + { + float pixelLuminance = LuminanceUtils.Luma(color); + float toneMappedLuminance = log10(1 + pixelLuminance); + toneMappedLuminance /= log10(1 + WhiteLevel); + toneMappedLuminance /= log10(2 + 8 * ((pixelLuminance / WhiteLevel) * log10(DragoBias) / log10(0.5f))); + return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl new file mode 100644 index 0000000000..a52b444e1e --- /dev/null +++ b/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The logarithmic tonemap operator. + /// + internal shader ToneMapExponentialOperatorShader : ToneMapCommonOperatorShader + { + override float4 Compute(float4 color) + { + float pixelLuminance = LuminanceUtils.Luma(color); + float toneMappedLuminance = 1 - exp(-pixelLuminance / WhiteLevel); + return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl b/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl new file mode 100644 index 0000000000..2b5a89e145 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The tonemap operator by Jim Hejl version 2 that does not include the gamma correction and has a whitepoint parameter. + /// + /// + /// https://twitter.com/jimhejl/status/633777619998130176 + /// + internal shader ToneMapHejl2OperatorShader : ToneMapOperatorShader + { + float WhitePoint = 5.0f; + + override float4 Compute(float4 color) + { + // Workaround for Huawei Mate 9 Pro (Mali) GLSL bug + float w = (1.425 * WhitePoint) + 0.05f; + w = ((WhitePoint * w + 0.004f) / ((WhitePoint * (w + 0.55f) + 0.0491f))) - 0.0821f; + + float4 vh = float4(color.rgb, WhitePoint); + float4 va = (1.425 * vh) + 0.05f; // eval filmic curve + float4 vf = ((vh * va + 0.004f) / ((vh * (va + 0.55f) + 0.0491f))) - 0.0821f; + return float4(vf.rgb / w, 1.0); // white point correction + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl new file mode 100644 index 0000000000..a85de5124e --- /dev/null +++ b/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The tonemap operator by Jim Hejl and Richard Burgess-Dawson. + /// + /// + /// http://filmicgames.com/archives/75 + /// + internal shader ToneMapHejlDawsonOperatorShader : ToneMapOperatorShader + { + override float4 Compute(float4 color) + { + color = max(0,color-0.004); + color = (color*(6.2*color+.5))/(color*(6.2*color+1.7)+0.06); + // TODO: Reverts the gamma correction which was automatically applied by the formula + // TODO: Refit the curve without gamma correction + float3 linearColor = pow(color.rgb, 2.2); + return float4(linearColor, 1.0); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl new file mode 100644 index 0000000000..1c7a924954 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The logarithmic tonemap operator. + /// + internal shader ToneMapLogarithmicOperatorShader : ToneMapCommonOperatorShader + { + override float4 Compute(float4 color) + { + float pixelLuminance = LuminanceUtils.Luma(color); + float toneMappedLuminance = log10(1 + pixelLuminance) / log10(1 + WhiteLevel); + return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl new file mode 100644 index 0000000000..707d711eec --- /dev/null +++ b/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The tonemap operator from Mike Day, Insomniac Games. + /// + /// + /// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/09/an-efficient-and-user-friendly-tone-mapping-operator.pdf + /// + internal shader ToneMapMikeDayOperatorShader : ToneMapOperatorShader + { + float4 ToeCoeffs; + float4 ShoulderCoeffs; + float MiddleCrossOver; + + float Remap(float x) + { + float4 coeffs = (x < MiddleCrossOver) ? ToeCoeffs : ShoulderCoeffs; + float2 fraction = coeffs.xy * x + coeffs.zw; + return fraction.x / fraction.y; + } + + override float4 Compute(float4 color) + { + return float4(Remap(color.r), Remap(color.g), Remap(color.b), color.a); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapOperatorShader.sdsl new file mode 100644 index 0000000000..1b4c84f4fe --- /dev/null +++ b/assets/Stride/SDSL/ToneMapOperatorShader.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A generic interface for computing a tonemap operator. + /// + shader ToneMapOperatorShader : ColorTransformShader + { + }; +} diff --git a/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl new file mode 100644 index 0000000000..b857e6c795 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The Reinhard tonemap operator. + /// + internal shader ToneMapReinhardOperatorShader : ToneMapCommonOperatorShader + { + override float4 Compute(float4 color) + { + float pixelLuminance = LuminanceUtils.Luma(color); + // TODO add version: toneMappedLuminance = pixelLuminance / (1.0f + pixelLuminance); + float toneMappedLuminance = pixelLuminance * (1.0f + pixelLuminance / (WhiteLevel * WhiteLevel)) / (1.0f + pixelLuminance); + return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapShader.sdsl b/assets/Stride/SDSL/ToneMapShader.sdsl new file mode 100644 index 0000000000..59dc3e3668 --- /dev/null +++ b/assets/Stride/SDSL/ToneMapShader.sdsl @@ -0,0 +1,91 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// A tonemap shader + /// + internal shader ToneMapShader : ColorTransformShader, Texturing + { + // Luminance texture + Texture2D LuminanceTexture; + + // Exposure + float KeyValue = 0.18f; + float LuminanceLocalFactor = 0.0f; + float LuminanceAverageGlobal; + + // Color/Gamma correction + float Contrast = 0.0f; + float Brightness = 0.0f; + float Exposure = 1.0f; + + // ToneMap Operator + [Link("ToneMap.Operator")] + compose ToneMapOperatorShader ToneMapOperator; + + override float4 Compute(float4 inputColor) + { + // Get the input color to tonemap + float3 color = inputColor.rgb; + + // Code based on Matt Pettineo: https://mynameismjp.wordpress.com/2010/04/30/a-closer-look-at-tone-mapping/ + // Use local luminance slightly differently to allow mix between local and global + + // Gets the local luminance + float avgLuminance = LuminanceAverageGlobal; + if (TUseLocalLuminance) + { + float luminanceAverageLocal = LuminanceTexture.Sample(Texturing.LinearSampler, streams.TexCoord).r; + + // Calculate average geometric mean for luminance using local and global average luminances + avgLuminance = lerp(avgLuminance, luminanceAverageLocal, LuminanceLocalFactor); + } + avgLuminance = exp2(avgLuminance); + avgLuminance = max(avgLuminance, 0.0001f); + + // Apply brightness and contrast + float globalAverageLum = exp2(LuminanceAverageGlobal); + color = max(color + globalAverageLum.xxx * Brightness, 0.0001); + color = max(lerp(globalAverageLum.xxx, color, Contrast + 1.0f), 0.0001); + + // Apply ToneMapping + color = ToneMap(color, avgLuminance); + + return float4(color, inputColor.a); + } + + float CalculateExposure(float avgLuminance) + { + float exposure; + if (TAutoExposure) + { + float keyValue; + if (TAutoKeyValue) + { + keyValue = 1.03f - (2.0f / (2 + log10(avgLuminance + 1))); + } + else + { + keyValue = KeyValue; + } + float linearExposure = (keyValue / avgLuminance); + exposure = max(linearExposure, 0.0001f); + } + else + { + exposure = Exposure; + } + return exposure; + } + + float3 ToneMap(float3 color, float avgLuminance) + { + float exposure = CalculateExposure(avgLuminance); + color *= exposure; + color = ToneMapOperator.Compute(float4(color,1)).rgb; + return color; + } + }; +} diff --git a/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl b/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl new file mode 100644 index 0000000000..fe2d6c3f8d --- /dev/null +++ b/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl @@ -0,0 +1,40 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// The U2Filmic tonemap operator. + /// + internal shader ToneMapU2FilmicOperatorShader : ToneMapOperatorShader + { + float ShoulderStrength = 0.22f; + float LinearStrength = 0.25f; + float LinearAngle = 0.1f; + float ToeStrength = 0.2f; + float ToeNumerator = 0.01f; + float ToeDenominator = 0.3f; + float LinearWhite = 11.2f; + + // Function used by the Uncharted2 tone mapping curve + float3 U2Func(float3 x) + { + float A = ShoulderStrength; + float B = LinearStrength; + float C = LinearAngle; + float D = ToeStrength; + float E = ToeNumerator; + float F = ToeDenominator; + return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F)) - E/F; + } + + override float4 Compute(float4 color) + { + // Applies the Uncharted 2 filmic tone mapping curve + float3 numerator = U2Func(color.rgb); + float3 denominator = U2Func(LinearWhite); + + return float4(numerator / denominator, 1); + } + }; +} diff --git a/assets/Stride/SDSL/Transformation.sdsl b/assets/Stride/SDSL/Transformation.sdsl new file mode 100644 index 0000000000..e85458426f --- /dev/null +++ b/assets/Stride/SDSL/Transformation.sdsl @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader Transformation +{ + cbuffer PerView { + // View matrix. Default to Matrix.Identity. + stage float4x4 View; + // Inverse View matrix. Default to Matrix.Inverse(View) + stage float4x4 ViewInverse; + // Projection matrix. Default to Matrix.Identity. + stage float4x4 Projection; + // Projection matrix. Default to Matrix.Inverse(Projection). + stage float4x4 ProjectionInverse; + // ViewProjection matrix. Default to = View * Projection. + stage float4x4 ViewProjection; + // Screen projected ray vector. Default to = new Vector2(-1.0f / Projection.M11, 1.0f / Projection.M22); + stage float2 ProjScreenRay; + // Eye vector. Default to = View^-1[M41,M42,M43,1.0] + stage float4 Eye; + }; + + cbuffer PerDraw { + // World matrix. Default to Matrix.Identity. + stage float4x4 World; + } + cbuffer PerDraw { + // Inverse World matrix. Default to Matrix.Inverse(World). + stage float4x4 WorldInverse; + // Inverse Transpose World matrix. Default to Matrix.Transpose(Matrix.Inverse(World)). + stage float4x4 WorldInverseTranspose; + // WorldView matrix. Default to = World * View. + stage float4x4 WorldView; + // Inverse WorldView matrix. Default to Matrix.Inverse(WorldView) + stage float4x4 WorldViewInverse; + // WorldViewProjection matrix. Default to = World * ViewProjection. + stage float4x4 WorldViewProjection; + // The scale of the World. Default to Vector2.One. + stage float3 WorldScale; + // Eye vector in model space. Default to = (World*View)^-1[M41,M42,M43,1.0] + stage float4 EyeMS; + }; +}; diff --git a/assets/Stride/SDSL/TransformationBase.sdsl b/assets/Stride/SDSL/TransformationBase.sdsl new file mode 100644 index 0000000000..4e64b78b0a --- /dev/null +++ b/assets/Stride/SDSL/TransformationBase.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Defines the 3 transformations steps used in the pipeline. +/// The first is performed at the end of the VS. +/// The second is performed after the tessellation. +/// The third is performed at the end of the geometry pipeline. +/// +shader TransformationBase : ShaderBase +{ + // End of the VS (usually skinning) + stage void PreTransformPosition() {} + + // End of tessellation (usually displacement mapping in world space, etc...) + stage void TransformPosition() {} + + // At the end of the geometry pipeline (to generate ShadingPosition) + stage void PostTransformPosition() {} + + // Used in cases where a shading position needs to be calculated from a given world position + // for example: in tesselation, which needs to determine the triangle size on the screen + stage float4 ComputeShadingPosition(float4 world) { return 0; } + + stage void BaseTransformVS() + { + this.PreTransformPosition(); + this.TransformPosition(); + this.PostTransformPosition(); + } + + stage override void VSMain() + { + base.VSMain(); + this.BaseTransformVS(); + } +}; diff --git a/assets/Stride/SDSL/TransformationBendWorld.sdsl b/assets/Stride/SDSL/TransformationBendWorld.sdsl new file mode 100644 index 0000000000..5f77176a86 --- /dev/null +++ b/assets/Stride/SDSL/TransformationBendWorld.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader TransformationBendWorld : TransformationBase, PositionStream4 +{ + cbuffer PerDraw + { + // Adjusting Parameters + stage float DeformFactorX = -0.001f; + stage float DeformFactorY = -0.0006f; + } + + stage override void PreTransformPosition() + { + base.PreTransformPosition(); + + // Deform Y + streams.PositionWS.y += DeformFactorY * streams.PositionWS.z * streams.PositionWS.z; + // Deform X + streams.PositionWS.x += DeformFactorX * streams.PositionWS.z * streams.PositionWS.z; + } + +}; diff --git a/assets/Stride/SDSL/TransformationInstancing.sdsl b/assets/Stride/SDSL/TransformationInstancing.sdsl new file mode 100644 index 0000000000..11c75b3c5f --- /dev/null +++ b/assets/Stride/SDSL/TransformationInstancing.sdsl @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +#ifndef ModelTransformUsage +# define ModelTransformUsage 0 +#endif + +shader TransformationInstancing : TransformationBase, Transformation +{ + struct InstanceTransform + { + float4x4 Matrix; + }; + + rgroup PerDraw.Instancing + { + stage StructuredBuffer InstanceWorld; + stage StructuredBuffer InstanceWorldInverse; + } + + float4x4 GetInstanceWorld(uint instanceId) + { +#if ModelTransformUsage == 0 + return InstanceWorld[instanceId].Matrix; +#elif ModelTransformUsage == 1 + return mul(Transformation.World, InstanceWorld[instanceId].Matrix); +#else + return mul(InstanceWorld[instanceId].Matrix, Transformation.World); +#endif + } + + float4x4 GetInstanceWorldInverse(uint instanceId) + { +#if ModelTransformUsage == 0 + return InstanceWorldInverse[instanceId].Matrix; +#elif ModelTransformUsage == 1 + return mul(InstanceWorldInverse[instanceId].Matrix, Transformation.WorldInverse); +#else + return mul(Transformation.WorldInverse, InstanceWorldInverse[instanceId].Matrix); +#endif + } +}; diff --git a/assets/Stride/SDSL/TransformationMatrix.sdsl b/assets/Stride/SDSL/TransformationMatrix.sdsl new file mode 100644 index 0000000000..a9b3f9b4c3 --- /dev/null +++ b/assets/Stride/SDSL/TransformationMatrix.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Transform the position of the vertex with the given matrix. +/// +/// +/// TRANSFORMATION_MATRIX: generic float4x4 - The transformation matrix. +/// +shader TransformationMatrix : TransformationBase, PositionStream4, PositionHStream4 +{ + stage override void PostTransformPosition() + { + base.PostTransformPosition(); + streams.ShadingPosition = mul(streams.Position, TRANSFORMATION_MATRIX); + streams.PositionH = streams.ShadingPosition; + } +}; diff --git a/assets/Stride/SDSL/TransformationSkinning.sdsl b/assets/Stride/SDSL/TransformationSkinning.sdsl new file mode 100644 index 0000000000..fa8543914d --- /dev/null +++ b/assets/Stride/SDSL/TransformationSkinning.sdsl @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Performs skinning on the position. +/// +/// +/// SkinningMaxBones: Macro - number of threads on the X axis. +/// +#ifndef SkinningMaxBones +# define SkinningMaxBones 4 +#endif + +shader TransformationSkinning : TransformationBase, PositionStream4, Transformation +{ + cbuffer PerDraw + { + // TODO switch to float4x3 in a way compatible with ES 2.0 + stage float4x4 BlendMatrixArray[SkinningMaxBones]; + } + + stage stream float4 BlendWeights : BLENDWEIGHT; + stage stream uint4 BlendIndices : BLENDINDICES; + + stage stream float4x4 skinningBlendMatrix; + + float4x4 GetBlendMatrix(int index) + { + return BlendMatrixArray[index]; + } + + override stage void PreTransformPosition() + { + base.PreTransformPosition(); + + streams.skinningBlendMatrix = GetBlendMatrix(streams.BlendIndices[0]) * streams.BlendWeights[0] + + GetBlendMatrix(streams.BlendIndices[1]) * streams.BlendWeights[1] + + GetBlendMatrix(streams.BlendIndices[2]) * streams.BlendWeights[2] + + GetBlendMatrix(streams.BlendIndices[3]) * streams.BlendWeights[3]; + float4 blendPos = mul(float4(streams.Position.xyz, 1.0f), streams.skinningBlendMatrix); + blendPos /= blendPos.w; + streams.PositionWS = blendPos; + } +}; diff --git a/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl b/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl new file mode 100644 index 0000000000..3f46534d68 --- /dev/null +++ b/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader TransformationSkinningInstanced : TransformationSkinning, TransformationInstancing +{ + override stage void PreTransformPosition() + { + base.PreTransformPosition(); + + streams.skinningBlendMatrix = GetBlendMatrix(streams.BlendIndices[0]) * streams.BlendWeights[0] + + GetBlendMatrix(streams.BlendIndices[1]) * streams.BlendWeights[1] + + GetBlendMatrix(streams.BlendIndices[2]) * streams.BlendWeights[2] + + GetBlendMatrix(streams.BlendIndices[3]) * streams.BlendWeights[3]; + + // Put back to object space + streams.skinningBlendMatrix = mul(streams.skinningBlendMatrix, Transformation.WorldInverse); + + // Apply instance transformation + streams.skinningBlendMatrix = mul(streams.skinningBlendMatrix, GetInstanceWorld(streams.InstanceID)); + + // Transform position + float4 blendPos = mul(streams.Position, streams.skinningBlendMatrix); + + streams.PositionWS = blendPos; + } +}; diff --git a/assets/Stride/SDSL/TransformationTextureUV.sdsl b/assets/Stride/SDSL/TransformationTextureUV.sdsl new file mode 100644 index 0000000000..88be67a557 --- /dev/null +++ b/assets/Stride/SDSL/TransformationTextureUV.sdsl @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader TransformationTextureUV : ShaderBase, Texturing +{ + override void VSMain() + { + TransformUV_VS(); + + base.VSMain(); + } + + cbuffer PerDraw + { + stage float4 TextureRegion = float4(0,0,1,1); + } + + stage void TransformUV_VS() + { + streams.TexCoord = TextureRegion.xy + TextureRegion.zw * streams.TexCoord; + } +}; diff --git a/assets/Stride/SDSL/TransformationWAndVP.sdsl b/assets/Stride/SDSL/TransformationWAndVP.sdsl new file mode 100644 index 0000000000..f18b9b1512 --- /dev/null +++ b/assets/Stride/SDSL/TransformationWAndVP.sdsl @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Transforms the position of the vertex in world space first then in projection space +/// +shader TransformationWAndVP : TransformationBase, PositionStream4, PositionHStream4 +{ + stage override void PreTransformPosition() + { + base.PreTransformPosition(); + streams.PositionWS = mul(streams.Position, Transformation.World); + } + + stage override void PostTransformPosition() + { + base.PostTransformPosition(); + streams.ShadingPosition = ComputeShadingPosition(streams.PositionWS); + streams.PositionH = streams.ShadingPosition; + streams.DepthVS = streams.ShadingPosition.w; + } + + stage override float4 ComputeShadingPosition(float4 world) + { + return mul(world, Transformation.ViewProjection); + } +}; diff --git a/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl b/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl new file mode 100644 index 0000000000..f15b86663e --- /dev/null +++ b/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Transforms the position of the vertex in world space first then in projection space +/// +shader TransformationWAndVPInstanced : TransformationWAndVP, TransformationInstancing, PositionStream4, PositionHStream4 +{ + stage override void PreTransformPosition() + { + streams.PositionWS = mul(streams.Position, GetInstanceWorld(streams.InstanceID)); + } +}; diff --git a/assets/Stride/SDSL/TransformationWVP.sdsl b/assets/Stride/SDSL/TransformationWVP.sdsl new file mode 100644 index 0000000000..11b4f07bca --- /dev/null +++ b/assets/Stride/SDSL/TransformationWVP.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Transforms the local position of the vertex into the projection space. +/// +shader TransformationWVP : TransformationMatrix +{ +}; diff --git a/assets/Stride/SDSL/TransformationZero.sdsl b/assets/Stride/SDSL/TransformationZero.sdsl new file mode 100644 index 0000000000..5bea18abb3 --- /dev/null +++ b/assets/Stride/SDSL/TransformationZero.sdsl @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Resets the position to the origin. +/// +shader TransformationZero : TransformationBase +{ + stage override void BaseTransformVS() + { + streams.PositionStream4.Position = float4(0.0f, 0.0f, 0.0f, 1.0f); + base.BaseTransformVS(); + } +}; diff --git a/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl b/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl new file mode 100644 index 0000000000..ecc128b20e --- /dev/null +++ b/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Combines the 3 rhombi blurs into an hexagonal blur. (Final pass of the TripleRhombi bokeh effect.) + /// Expects as input: + /// - Texture0: a color buffer with the top-left rhombi blur + /// - Texture1: a color buffer with the top-right rhombi blur + /// - Texture2: a color buffer with the bottom rhombi blur + /// + shader TripleRhombiCombineShader : ImageEffectShader + { + // Offset to apply when reading a texture coordinate (for each of the 3 rhombis) + stage float2 RhombiTapOffsets[3]; + + stage override float4 Shading() + { + float4 tapColor[3]; + + tapColor[0] = Texture0.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[0] * Texture0TexelSize ); + tapColor[1] = Texture1.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[1] * Texture1TexelSize ); + tapColor[2] = Texture2.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[2] * Texture2TexelSize ); + + float4 result = float4(0.0, 0.0, 0.0, 0.0); + [unroll] + for (int i = 0; i < 3; i++) + { + float4 color = tapColor[i]; + color.rgb *= color.a; //Pre-multiply alpha + result += color; + } + + result /= 3.0; + + if (result.a > 0) result.rgb /= result.a; // Converts back to non-pre-multiplied alpha + + return result; + } + }; +} diff --git a/assets/Stride/SDSL/UIEffectShader.sdsl b/assets/Stride/SDSL/UIEffectShader.sdsl new file mode 100644 index 0000000000..605c75e9ff --- /dev/null +++ b/assets/Stride/SDSL/UIEffectShader.sdsl @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader UIEffectShader : ShaderBase, Texturing +{ + // ------------------------------------- + // streams + // ------------------------------------- + stage stream float4 Position : POSITION; + stage stream float4 Color : COLOR; + stage stream float Swizzle : BATCH_SWIZZLE; + + // ------------------------------------- + // VertexShader + // ------------------------------------- + stage override void VSMain() + { + streams.ShadingPosition = streams.Position; + if (TSRgb) + { + streams.Color = ColorUtility.ToLinear(streams.Color); + } + } + + // Shading of the sprite + stage override void PSMain() + { + streams.ColorTarget = Shading(); + } + + stage float4 Shading() + { + float4 sampledColor = Texture0.Sample(Sampler, streams.TexCoord); + float4 swizzledColor = streams.Swizzle == 0? sampledColor: sampledColor.rrrr; + + return swizzledColor * streams.Color; + } +}; diff --git a/assets/Stride/SDSL/Utilities.sdsl b/assets/Stride/SDSL/Utilities.sdsl new file mode 100644 index 0000000000..85e878c077 --- /dev/null +++ b/assets/Stride/SDSL/Utilities.sdsl @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +/// +/// Various helper functions. +/// +shader Utilities +{ + // ------------------------------------- + // type definition + // ------------------------------------- + typedef uint Half2; + typedef uint2 Half4; + + // Converts a Half2 to a float2 + float2 Half2ToFloat2(Half2 value) + { + return float2(f16tof32(value), f16tof32(value >> 16)); + } + + // Converts a float2 to a Half2 + Half2 Float2ToHalf2(float2 value) + { + return f32tof16(value.x) | (f32tof16(value.y) << 16); + } + + // Converts a Half4 to a float4 + float4 Half4ToFloat4(Half4 value) { + return float4(f16tof32(value.x), f16tof32(value.x>>16), f16tof32(value.y), f16tof32(value.y>>16)); + } + + // Converts a float4 to a Half4 + Half4 Float4ToHalf4(float4 value) { + return uint2(f32tof16(value.x) | (f32tof16(value.y) << 16), f32tof16(value.z) | (f32tof16(value.w) << 16)); + } + + // Commpute Schlick's approximation of Fresnel + float3 FresnelSchlick(float3 specularColor, float3 eye, float3 h, float factor) + { + return specularColor + (1.0f - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; + } + + // Commpute Schlick's approximation of Fresnel + float3 FresnelSchlickWithGloss(float3 specularColor, float3 eye, float3 h, float factor, float gloss) + { + return specularColor + (max(specularColor, gloss) - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; + } + + // flip the texture coordinate if on an opengl device. + static float2 ConvertTexCoord(float2 texcoord) { +#ifdef STRIDE_GRAPHICS_API_OPENGL + return float2(texcoord.x, 1.0f - texcoord.y); +#else + return texcoord; +#endif + } +}; diff --git a/assets/Stride/SDSL/VelocityOutput.sdsl b/assets/Stride/SDSL/VelocityOutput.sdsl new file mode 100644 index 0000000000..baf60694f0 --- /dev/null +++ b/assets/Stride/SDSL/VelocityOutput.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +// ComputeColor that just returns streams.velocity +shader VelocityOutput : ComputeColor, VelocityStream +{ + override float4 Compute() + { + return float4(streams.velocity.xy, 0.0f, 0.0f); + } +}; diff --git a/assets/Stride/SDSL/VelocityStream.sdsl b/assets/Stride/SDSL/VelocityStream.sdsl new file mode 100644 index 0000000000..77602e8b60 --- /dev/null +++ b/assets/Stride/SDSL/VelocityStream.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader VelocityStream : ShaderBase +{ + // Screen space velocity + stage stream float2 velocity; + + stage override void VSMain() + { + base.VSMain(); + streams.velocity = float2(0,0); + } +}; diff --git a/assets/Stride/SDSL/VideoShader.sdsl b/assets/Stride/SDSL/VideoShader.sdsl new file mode 100644 index 0000000000..a3392755ce --- /dev/null +++ b/assets/Stride/SDSL/VideoShader.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader VideoShader : SpriteBase +{ +}; diff --git a/assets/Stride/SDSL/VignettingShader.sdsl b/assets/Stride/SDSL/VignettingShader.sdsl new file mode 100644 index 0000000000..4b12a46146 --- /dev/null +++ b/assets/Stride/SDSL/VignettingShader.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Rendering.Images +{ + /// + /// Vignetting shader. + /// + internal shader VignettingShader : ColorTransformShader, Texturing + { + // Amount + float Amount; + + // At which radius from the center the vignetting begins, in [0, 1] + float RadiusBegin; + + // Color othe vignette + [Color] + float3 Color; + + override float4 Compute(float4 color) + { + float2 fromCenterVector = streams.TexCoord - float2(0.5, 0.5); + float squareDistanceToCenter = dot(fromCenterVector, fromCenterVector); + float distanceToCenter = sqrt(squareDistanceToCenter); + + float vignette = smoothstep(RadiusBegin, 1.0, distanceToCenter / 0.7071); // 0.7071 is sqrt(0.5), at the screen corner + vignette *= Amount; + color.rgb = color.rgb * (1.0 - vignette) + vignette * Color; + + return color; + + } + }; +} diff --git a/assets/Stride/SDSL/VolumeMinMaxShader.sdsl b/assets/Stride/SDSL/VolumeMinMaxShader.sdsl new file mode 100644 index 0000000000..ff56555e58 --- /dev/null +++ b/assets/Stride/SDSL/VolumeMinMaxShader.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +shader VolumeMinMaxShader : ShaderBase, PositionHStream4 +{ + stage matrix WorldViewProjection; + stage stream float4 Position : POSITION; + + stage override void VSMain() + { + streams.ShadingPosition = mul(streams.Position, WorldViewProjection); + streams.PositionH = streams.ShadingPosition; + } + + stage override void PSMain() + { + float depth = streams.PositionH.z / streams.PositionH.w; + streams.ColorTarget = float4(depth, depth, 0, 1); + } +}; diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl new file mode 100644 index 0000000000..0de543508e --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmap : Math, Texturing, ComputeShaderBase + { + stage float3 ReadOffset; + stage float3 WriteOffset; + stage Texture3D ReadTex; + stage RWTexture3D WriteTex; + + compose Voxel2x2x2Mipmapper mipmapper; + + override void Compute() + { + uint3 pos = streams.DispatchThreadId; + + uint3 posR = pos * 2 + (int3)ReadOffset; + + float4 fragmentSum = mipmapper.Mipmap( + ReadTex.Load(int4(posR, 0)), + ReadTex.Load(int4(posR + uint3(1, 0, 0), 0)), + ReadTex.Load(int4(posR + uint3(1, 1, 0), 0)), + ReadTex.Load(int4(posR + uint3(1, 0, 1), 0)), + ReadTex.Load(int4(posR + uint3(0, 1, 1), 0)), + ReadTex.Load(int4(posR + uint3(0, 1, 0), 0)), + ReadTex.Load(int4(posR + uint3(0, 0, 1), 0)), + ReadTex.Load(int4(posR + uint3(1, 1, 1), 0)) + ); + + WriteTex[pos + WriteOffset] = fragmentSum; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl b/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl new file mode 100644 index 0000000000..e84a8b65d0 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + partial effect Voxel2x2x2MipmapEffect + { + using params Voxel2x2x2MipmapKeys; + + mixin Voxel2x2x2Mipmap; + if (Voxel2x2x2MipmapKeys.mipmapper!=null) + { + mixin compose mipmapper = Voxel2x2x2MipmapKeys.mipmapper; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl new file mode 100644 index 0000000000..034a758332 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper : Math, Texturing, ComputeShaderBase + { + float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return float4(1,0,0,1); + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl b/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl new file mode 100644 index 0000000000..85cd028574 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2MipmapperHeuristic : Voxel2x2x2Mipmapper + { + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + float filledSum = ceil(s000.a) + ceil(s100.a) + ceil(s110.a) + ceil(s101.a) + ceil(s011.a) + ceil(s010.a) + ceil(s001.a) + ceil(s111.a); + float4 fragmentSum = (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111); + fragmentSum.rgb /= max(filledSum, 4); + fragmentSum.a /= 8; + return fragmentSum; + //Rather than divide by 8... + //I figure that since the visible surface of the + //emitter is a 2D projection, it should decrease + //by 2 dimensions rather than 3 (i.e divide by 4 rather than 8). + + //This makes the lighting fall-off much more realistic, + //but I find the opacity coverage too strong then. + //so keep that dividing by 8. + + //Of course, then the brightness in areas with clusters of voxels + //becomes too high, so instead divide by the number of filled voxels, minimum 4 + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl b/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl new file mode 100644 index 0000000000..08da325c53 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2MipmapperPhysicallyBased : Voxel2x2x2Mipmapper + { + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + float4 fragmentSum = (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111); + fragmentSum.rgb /= 4; + fragmentSum.a /= 8; + return fragmentSum; + //Rather than divide by 8... + //I figure that since the visible surface of the + //emitter is a 2D projection, it should decrease + //by 2 dimensions rather than 3 (i.e divide by 4 rather than 8). + + //This makes the lighting fall-off much more realistic, + //but I find the opacity coverage too strong then. + //so keep that dividing by 8. + } + }; +} \ No newline at end of file diff --git a/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl b/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl new file mode 100644 index 0000000000..37c4138c73 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2MipmapperSimple : Voxel2x2x2Mipmapper + { + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111)/8; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl new file mode 100644 index 0000000000..c8911d6765 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoXN : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s100,s000) + blend(s110,s010) + blend(s111,s011) + blend(s101,s001))/4; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl new file mode 100644 index 0000000000..87d50fc1f1 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoXP : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s000,s100) + blend(s010,s110) + blend(s011,s111) + blend(s001,s101))/4; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl new file mode 100644 index 0000000000..09425b6ac9 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoYN : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s010,s000) + blend(s110,s100) + blend(s111,s101) + blend(s011,s001))/4; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl new file mode 100644 index 0000000000..ef90d45c4f --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoYP : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s000,s010) + blend(s100,s110) + blend(s101,s111) + blend(s001,s011))/4; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl new file mode 100644 index 0000000000..554f527914 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoZN : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s001,s000) + blend(s101,s100) + blend(s111,s110) + blend(s011,s010))/4; + } + }; +} diff --git a/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl new file mode 100644 index 0000000000..0a0ea9d967 --- /dev/null +++ b/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader Voxel2x2x2Mipmapper_AnisoZP : Voxel2x2x2Mipmapper + { + float4 blend(float4 s0, float4 s1) + { + return s0*(1-s1.a) + s1; + } + override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) + { + return (blend(s000,s001) + blend(s100,s101) + blend(s110,s111) + blend(s010,s011))/4; + } + }; +} diff --git a/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl b/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl new file mode 100644 index 0000000000..d1a80cc183 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl @@ -0,0 +1,50 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader VoxelAnisotropicPairedSampler : IVoxelSampler, Texturing + { + compose VoxelStorageTextureShader storage; + cbuffer PerView.Lighting + { + float maxBrightness; + } + + float4 applyMaxBrightness(float4 col) + { + return float4(col.rgb * maxBrightness, col.a); + } + override float4 Sample(float3 position, float3 normal, float diameter) + { + return applyMaxBrightness( + storage.Sample(position, diameter, 0) * abs(normal.x) + + storage.Sample(position, diameter, 1) * abs(normal.y) + + storage.Sample(position, diameter, 2) * abs(normal.z) + ); + } + override float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + return applyMaxBrightness( + storage.SampleNearestMip(position, diameter, 0) * abs(normal.x) + + storage.SampleNearestMip(position, diameter, 1) * abs(normal.y) + + storage.SampleNearestMip(position, diameter, 2) * abs(normal.z) + ); + } + override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + return applyMaxBrightness( + storage.SampleByMipNearestMip(position, diameter, 0) * abs(normal.x) + + storage.SampleByMipNearestMip(position, diameter, 1) * abs(normal.y) + + storage.SampleByMipNearestMip(position, diameter, 2) * abs(normal.z) + ); + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return storage.SampleRaw(pos, mipmap, textureID, axis); + } + override float VoxelSize() + { + return storage.VoxelSize(); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl b/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl new file mode 100644 index 0000000000..18925b8ea5 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAnisotropicPairedWriter_Float4 : VoxelLayout_Float4, NormalStream +{ + stream float4 axisX; + stream float4 axisY; + stream float4 axisZ; + RWTexture3D DirectOutput; + compose VoxelFragmentPacker writer; + + float maxBrightnessInv; + + compose VoxelModifierApplierAnisotropicPaired Modifiers[]; + override void InitializeDummy() + { + streams.axisX = float4(0,0,0,0); + streams.axisY = float4(0,0,0,0); + streams.axisZ = float4(0,0,0,0); + } + override void InitializeFromStreams(float4 original) + { + streams.axisX = original * abs(streams.normalWS.x); + streams.axisY = original * abs(streams.normalWS.y); + streams.axisZ = original * abs(streams.normalWS.z); + } + float4 applyMaxBrightness(float4 col) + { + return float4(col.rgb * maxBrightnessInv, col.a); + } + override void DirectWrite(uint3 address, uint strideIndex, uint stride) + { + address.y += strideIndex * stride * 3; + float4 tempAxisX = streams.axisX; + float4 tempAxisY = streams.axisY; + float4 tempAxisZ = streams.axisZ; + foreach (var modifier in Modifiers) + { + modifier.Apply(tempAxisX, tempAxisY, tempAxisZ); + } + streams.axisX = tempAxisX; + streams.axisY = tempAxisY; + streams.axisZ = tempAxisZ; + + DirectOutput[address] = applyMaxBrightness(streams.axisX);address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisY);address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisZ); + } + override void IndirectWrite(RWBuffer buffer, uint address) + { + writer.Write(buffer, address, streams.axisX); + writer.Write(buffer, address, streams.axisY); + writer.Write(buffer, address, streams.axisZ); + } + override void InitializeFromBuffer(RWBuffer buffer, uint address) + { + writer.Read(buffer, address, streams.axisX); + writer.Read(buffer, address, streams.axisY); + writer.Read(buffer, address, streams.axisZ); + } + override float4 SampleLocal() + { + return streams.axisX; + } +}; diff --git a/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl b/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl new file mode 100644 index 0000000000..68a58069f8 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader VoxelAnisotropicSampler : IVoxelSampler, Texturing + { + compose VoxelStorageTextureShader storage; + cbuffer PerView.Lighting + { + float maxBrightness; + } + + float4 applyMaxBrightness(float4 col) + { + return float4(col.rgb * maxBrightness, col.a); + } + override float4 Sample(float3 position, float3 normal, float diameter) + { + float4 sum = float4(0,0,0,0); + + sum = storage.Sample(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); + sum += storage.Sample(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); + sum += storage.Sample(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); + + return applyMaxBrightness(sum); + } + override float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + float4 sum = float4(0, 0, 0, 0); + + sum = storage.SampleNearestMip(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); + sum += storage.SampleNearestMip(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); + sum += storage.SampleNearestMip(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); + + return applyMaxBrightness(sum); + } + override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + float4 sum = float4(0, 0, 0, 0); + + sum = storage.SampleByMipNearestMip(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); + sum += storage.SampleByMipNearestMip(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); + sum += storage.SampleByMipNearestMip(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); + + return applyMaxBrightness(sum); + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return storage.SampleRaw(pos, mipmap, textureID, axis); + } + override float VoxelSize() + { + return storage.VoxelSize(); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl b/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl new file mode 100644 index 0000000000..a0bdfe49e0 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl @@ -0,0 +1,100 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAnisotropicWriter_Float4 : VoxelLayout_Float4, NormalStream +{ + stream float4 axisXP; + stream float4 axisXN; + stream float4 axisYP; + stream float4 axisYN; + stream float4 axisZP; + stream float4 axisZN; + RWTexture3D DirectOutput; + compose VoxelFragmentPacker writer; + + float maxBrightnessInv; + + compose VoxelModifierApplierAnisotropic Modifiers[]; + override void InitializeDummy() + { + streams.axisXP = float4(0,0,0,0); + streams.axisYP = float4(0,0,0,0); + streams.axisZP = float4(0,0,0,0); + streams.axisXN = float4(0,0,0,0); + streams.axisYN = float4(0,0,0,0); + streams.axisZN = float4(0,0,0,0); + } + override void InitializeFromStreams(float4 original) + { + if (streams.normalWS.x > 0) + streams.axisXP = original * streams.normalWS.x; + else + streams.axisXN = original * -streams.normalWS.x; + + if (streams.normalWS.y > 0) + streams.axisYP = original * streams.normalWS.y; + else + streams.axisYN = original * -streams.normalWS.y; + + if (streams.normalWS.z > 0) + streams.axisZP = original * streams.normalWS.z; + else + streams.axisZN = original * -streams.normalWS.z; + } + float4 applyMaxBrightness(float4 col) + { + return float4(col.rgb * maxBrightnessInv, col.a); + } + override void DirectWrite(uint3 address, uint strideIndex, uint stride) + { + address.y += strideIndex * stride * 6; + float4 tempAxisXP = streams.axisXP; + float4 tempAxisXN = streams.axisXN; + float4 tempAxisYP = streams.axisYP; + float4 tempAxisYN = streams.axisYN; + float4 tempAxisZP = streams.axisZP; + float4 tempAxisZN = streams.axisZN; + foreach (var modifier in Modifiers) + { + modifier.Apply(tempAxisXP, tempAxisXN, tempAxisYP, tempAxisYN, tempAxisZP, tempAxisZN); + } + streams.axisXP = tempAxisXP; + streams.axisXN = tempAxisXN; + streams.axisYP = tempAxisYP; + streams.axisYN = tempAxisYN; + streams.axisZP = tempAxisZP; + streams.axisZN = tempAxisZN; + DirectOutput[address] = applyMaxBrightness(streams.axisXP); + address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisXN); + address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisYP); + address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisYN); + address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisZP); + address.y += stride; + DirectOutput[address] = applyMaxBrightness(streams.axisZN); + } + override void IndirectWrite(RWBuffer buffer, uint address) + { + writer.Write(buffer, address, streams.axisXP); + writer.Write(buffer, address, streams.axisXN); + writer.Write(buffer, address, streams.axisYP); + writer.Write(buffer, address, streams.axisYN); + writer.Write(buffer, address, streams.axisZP); + writer.Write(buffer, address, streams.axisZN); + } + override void InitializeFromBuffer(RWBuffer buffer, uint address) + { + writer.Read(buffer, address, streams.axisXP); + writer.Read(buffer, address, streams.axisXN); + writer.Read(buffer, address, streams.axisYP); + writer.Read(buffer, address, streams.axisYN); + writer.Read(buffer, address, streams.axisZP); + writer.Read(buffer, address, streams.axisZN); + } + override float4 SampleLocal() + { + return streams.axisXP; + } +}; diff --git a/assets/Stride/SDSL/VoxelAttribute.sdsl b/assets/Stride/SDSL/VoxelAttribute.sdsl new file mode 100644 index 0000000000..091060470e --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttribute.sdsl @@ -0,0 +1,11 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAttribute +{ + void InitializeDummy(){} + void InitializeFromStreams(){} + void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride){} + void IndirectWrite(RWBuffer buffer, uint address){} + void DirectWrite(uint3 address, uint strideIndex, uint stride){} + float4 SampleLocal(){return float4(0,0,0,1);}; +}; diff --git a/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl b/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl new file mode 100644 index 0000000000..5172a57787 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader VoxelAttributeDirectionalCoverageSampler : IVoxelSampler, Texturing + { + compose VoxelStorageTextureShader storage; + + override float4 ComputeLocal(float3 position) + { + return float4(0,0,0,1); + } + + float4 SetColor(float3 col) + { + return float4(col.r,col.g,col.b,max(col.r,max(col.g,col.b))); + } + override float4 Sample(float3 position, float3 normal, float diameter) + { + return SetColor(storage.Sample(position, diameter, 0).rgb); + } + override float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + return SetColor(storage.SampleNearestMip(position, diameter, 0).rgb); + } + override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + return SetColor(storage.SampleByMipNearestMip(position, diameter, 0).rgb); + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return storage.SampleRaw(pos,mipmap,textureID,axis); + } + override float VoxelSize() + { + return storage.VoxelSize(); + } + override float4 Test() + { + return float4(0,1,0,1); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl b/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl new file mode 100644 index 0000000000..1250bc6ecf --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl @@ -0,0 +1,56 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAttributeDirectionalCoverageShader : VoxelAttribute, ShaderBaseStream, NormalStream, DataPacking +{ + stream uint Voxel_Coverage; + stream float3 Voxel_CoverageResolved; + stream uint coverage : SV_Coverage; + + RWTexture3D DirectOutput; + + override void InitializeDummy() + { + streams.Voxel_Coverage = 0; + streams.Voxel_CoverageResolved = float3(0,0,0); + } + override void InitializeFromStreams() + { + uint shift = 0; + float xdot = abs(streams.normalWS.x); + float ydot = abs(streams.normalWS.y); + float zdot = abs(streams.normalWS.z); + if (xdot > ydot && xdot > zdot) + shift = 0; + if (ydot > xdot && ydot > zdot) + shift = 8; + if (zdot > ydot && zdot > xdot) + shift = 16; + streams.Voxel_Coverage = uint(streams.coverage)< buffer, uint address) + { + uint unusedOut; + InterlockedOr(buffer[address], streams.Voxel_Coverage, unusedOut); + address++; + } + override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) + { + streams.Voxel_Coverage = buffer[address]; + address++; + + uint3 coverage = UnpackByte3ToUint3(streams.Voxel_Coverage); + streams.Voxel_CoverageResolved = (float3(countbits(coverage.x),countbits(coverage.y),countbits(coverage.z)))/8.0; + } + float3 GetResolved(){ + return streams.Voxel_CoverageResolved; + } + override float4 SampleLocal() + { + return float4(streams.Voxel_CoverageResolved, 1.0); + } +}; diff --git a/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl b/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl new file mode 100644 index 0000000000..aa14c5df90 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAttributeEmissionOpacityShader : VoxelAttribute, ShaderBaseStream +{ + compose VoxelLayout_Float4 layout; + + override void InitializeDummy() + { + layout.InitializeDummy(); + } + override void InitializeFromStreams() + { + layout.InitializeFromStreams(streams.ColorTarget); + } + override void DirectWrite(uint3 address, uint strideIndex, uint stride) + { + layout.DirectWrite(address, strideIndex, stride); + } + override void IndirectWrite(RWBuffer buffer, uint address) + { + layout.IndirectWrite(buffer,address); + } + override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) + { + layout.InitializeFromBuffer(buffer, address); + } + override float4 SampleLocal() + { + return layout.SampleLocal(); + } +}; diff --git a/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl b/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl new file mode 100644 index 0000000000..59460049e6 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader VoxelAttributeSoliditySampler : IVoxelSampler, Texturing + { + compose VoxelStorageTextureShader storage; + + override float4 ComputeLocal(float3 position) + { + return float4(0,0,0,1); + } + + float4 SetColor(float4 col) + { + return float4(0,0,0,col.a); + } + override float4 Sample(float3 position, float3 normal, float diameter) + { + return SetColor(storage.Sample(position, diameter, 0).rrrr); + } + override float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + return SetColor(storage.SampleNearestMip(position, diameter, 0).rrrr); + } + override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + return SetColor(storage.SampleByMipNearestMip(position, diameter, 0).rrrr); + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return storage.SampleRaw(pos,mipmap,textureID,axis); + } + override float VoxelSize() + { + return storage.VoxelSize(); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl b/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl new file mode 100644 index 0000000000..4058ea5066 --- /dev/null +++ b/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl @@ -0,0 +1,108 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelAttributeSolidityShader : VoxelAttribute, VoxelPositionStream, ShaderBaseStream, NormalStream, DataPacking +{ + stream uint Voxel_SolidifyTop; + stream uint Voxel_SolidifyBottom; + stream float Voxel_Solidity; + stream int sendTo; + stream int ignoreTil; + + RWTexture3D DirectOutput; + + override void InitializeDummy() + { + streams.Voxel_SolidifyTop = 0; + streams.Voxel_SolidifyBottom = 0; + streams.Voxel_Solidity = 0; + streams.sendTo = 0; + streams.ignoreTil = 0; + } + override void InitializeFromStreams() + { + uint pos = FloatUnormToUint(streams.PositionVXS.y) & (0xFFFFFFFF << 2); + uint invpos = FloatUnormToUint(1.0 - streams.PositionVXS.y) & (0xFFFFFFFF << 2); + uint type = 0; + streams.normalWS = normalize(streams.normalWS); + if (streams.normalWS.y < -0.0) + type = 1; + if (streams.normalWS.y > 0.0) + type = 2; + + streams.Voxel_SolidifyTop = pos + type; + streams.Voxel_SolidifyBottom = invpos + type; + + streams.sendTo = 0; + streams.ignoreTil = 0; + } + override void DirectWrite(uint3 address, uint strideIndex, uint stride) + { + address.y += strideIndex * stride; + DirectOutput[address] = streams.Voxel_Solidity; + } + override void IndirectWrite(RWBuffer buffer, uint address) + { + InterlockedMax(buffer[address], streams.Voxel_SolidifyTop); + address++; + InterlockedMax(buffer[address], streams.Voxel_SolidifyBottom); + } + bool ResolvesSelf() + { + return (streams.Voxel_SolidifyTop & 3) == 2 && (streams.Voxel_SolidifyBottom & 3) == 1; + } + bool IsSender() + { + return (streams.Voxel_SolidifyTop & 3) == 1; + } + bool IsReceiver() + { + return (streams.Voxel_SolidifyBottom & 3) == 2; + } + override float4 SampleLocal() + { + return float4(IsReceiver()?1:0,IsSender()?1:0,ResolvesSelf()?1:0,streams.Voxel_Solidity); + } + override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) + { + int Y = streams.PositionVXPS.y; + int maxY = streams.VoxelVolumeSize.y; + + uint originalAddress = address; + + streams.Voxel_Solidity = 0; + + if (Y>streams.ignoreTil) + { + if (Y>=streams.sendTo) + { + streams.ignoreTil = maxY; + for(int y = Y ; y < maxY; y++) + { + uint tempAddress = base_stride.x + base_stride.y * y; + streams.Voxel_SolidifyTop = buffer[tempAddress]; + streams.Voxel_SolidifyBottom = buffer[tempAddress + 1]; + if (IsReceiver()) + { + if (streams.ignoreTil +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + shader VoxelBufferWriteAssign : VoxelBufferWriter + { + override void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data) + { + fragmentsBuffer[address] = data; + address++; + } + + override float4 Test() + { + return float4(0,1,0,1); + } + }; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl b/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl new file mode 100644 index 0000000000..e7d44d7ddb --- /dev/null +++ b/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + shader VoxelBufferWriteMax : VoxelBufferWriter + { + override void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data) + { + uint unusedOut = -1; + InterlockedMax(fragmentsBuffer[address], data, unusedOut); + address++; + } + + override float4 Test() + { + return float4(0,1,0,1); + } + }; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelBufferWriter.sdsl b/assets/Stride/SDSL/VoxelBufferWriter.sdsl new file mode 100644 index 0000000000..750d093c0e --- /dev/null +++ b/assets/Stride/SDSL/VoxelBufferWriter.sdsl @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + shader VoxelBufferWriter + { + void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data){} + void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint2 data) + { + Write_Internal(fragmentsBuffer, address,data.x); + Write_Internal(fragmentsBuffer, address,data.y); + } + void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint3 data) + { + Write_Internal(fragmentsBuffer, address,data.x); + Write_Internal(fragmentsBuffer, address,data.y); + Write_Internal(fragmentsBuffer, address,data.z); + } + void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint4 data) + { + Write_Internal(fragmentsBuffer, address,data.x); + Write_Internal(fragmentsBuffer, address,data.y); + Write_Internal(fragmentsBuffer, address,data.z); + Write_Internal(fragmentsBuffer, address,data.w); + } + + float4 Test() + { + return float4(1,0,0,1); + } + }; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl b/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl new file mode 100644 index 0000000000..ec1fe9efac --- /dev/null +++ b/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl @@ -0,0 +1,63 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelFragmentPackFloat16 : VoxelFragmentPacker, DataPacking +{ + override void Skip(inout uint address, float unpacked){address += 1;} + override void Skip(inout uint address, float2 unpacked){address += 1;} + override void Skip(inout uint address, float3 unpacked){address += 2;} + override void Skip(inout uint address, float4 unpacked){address += 2;} + override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, FloatToHalfFloat(unpacked.r)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, PackFloat2ToHalfFloat2(unpacked.rg)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, + uint2( + PackFloat2ToHalfFloat2(unpacked.rg), + FloatToHalfFloat(unpacked.b) + ) + ); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, + uint2( + PackFloat2ToHalfFloat2(unpacked.rg), + PackFloat2ToHalfFloat2(unpacked.ba) + ) + ); + } + + + + + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) + { + unpacked = HalfFloatToFloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) + { + unpacked = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) + { + unpacked.rg = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); + address++; + unpacked.b = HalfFloatToFloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) + { + unpacked.rg = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); + address++; + unpacked.ba = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); + address++; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl b/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl new file mode 100644 index 0000000000..4313d04aed --- /dev/null +++ b/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl @@ -0,0 +1,61 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelFragmentPackFloat32 : VoxelFragmentPacker +{ + override void Skip(inout uint address, float unpacked){address += 1;} + override void Skip(inout uint address, float2 unpacked){address += 2;} + override void Skip(inout uint address, float3 unpacked){address += 3;} + override void Skip(inout uint address, float4 unpacked){address += 4;} + override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); + } + + + + + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) + { + unpacked = asfloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) + { + unpacked.r = asfloat(fragmentsBuffer[address]); + address++; + unpacked.g = asfloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) + { + unpacked.r = asfloat(fragmentsBuffer[address]); + address++; + unpacked.g = asfloat(fragmentsBuffer[address]); + address++; + unpacked.b = asfloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) + { + unpacked.r = asfloat(fragmentsBuffer[address]); + address++; + unpacked.g = asfloat(fragmentsBuffer[address]); + address++; + unpacked.b = asfloat(fragmentsBuffer[address]); + address++; + unpacked.a = asfloat(fragmentsBuffer[address]); + address++; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl b/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl new file mode 100644 index 0000000000..d361704b63 --- /dev/null +++ b/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl @@ -0,0 +1,66 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelFragmentPackFloatR11G11B10 : VoxelFragmentPacker, DataPacking +{ + override void Skip(inout uint address, float unpacked){address += 1;} + override void Skip(inout uint address, float2 unpacked){address += 1;} + override void Skip(inout uint address, float3 unpacked){address += 1;} + override void Skip(inout uint address, float4 unpacked){address += 2;} + override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, Float3ToR11G11B10(unpacked)); + } + + + + + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) + { + unpacked.rgb = R11G11B10ToFloat3(fragmentsBuffer[address]); + address++; + } + + + + //Until partial packing is implemented (if ever), write some halfs when not writing exactly 3 values + //Otherwise many bits are wasted + //Keep layout consistent though (or things like InterlockedMax can give unexpected results) + override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, FloatToHalfFloat(unpacked.r)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, PackFloat2ToHalfFloat2(unpacked.rg)); + } + override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) + { + writer.Write_Internal(fragmentsBuffer, address, + uint2( + Float3ToR11G11B10(unpacked.rgb), + FloatToHalfFloat(unpacked.a) + ) + ); + } + + + + + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) + { + unpacked = HalfFloatToFloat(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) + { + unpacked = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); + address++; + } + override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) + { + unpacked.rgb = R11G11B10ToFloat3(fragmentsBuffer[address]); + address++; + unpacked.a = HalfFloatToFloat(fragmentsBuffer[address]); + address++; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelFragmentPacker.sdsl b/assets/Stride/SDSL/VoxelFragmentPacker.sdsl new file mode 100644 index 0000000000..731079e1cc --- /dev/null +++ b/assets/Stride/SDSL/VoxelFragmentPacker.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelFragmentPacker +{ + compose VoxelBufferWriter writer; + + void Skip(inout uint address, float unpacked){} + void Skip(inout uint address, float2 unpacked){} + void Skip(inout uint address, float3 unpacked){} + void Skip(inout uint address, float4 unpacked){} + + void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked){} + void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked){} + void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked){} + void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked){} + + void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked){unpacked = 0;} + void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked){unpacked = float2(0,0);} + void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked){unpacked = float3(0,0,0);} + void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked){unpacked = float4(0,0,0,0);} +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl b/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl new file mode 100644 index 0000000000..af69989e01 --- /dev/null +++ b/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + shader VoxelIsotropicSampler : IVoxelSampler, Texturing + { + compose VoxelStorageTextureShader storage; + cbuffer PerView.Lighting + { + float maxBrightness; + } + + override float4 ComputeLocal(float3 position) + { + return float4(0,0,0,1); + } + override float4 Sample(float3 position, float3 normal, float diameter) + { + return storage.Sample(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); + } + override float4 SampleNearestMip(float3 position, float3 normal, float diameter) + { + return storage.SampleNearestMip(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); + } + override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) + { + return storage.SampleByMipNearestMip(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + return storage.SampleRaw(pos,mipmap,textureID,axis); + } + override float VoxelSize() + { + return storage.VoxelSize(); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl b/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl new file mode 100644 index 0000000000..7505db6c0f --- /dev/null +++ b/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl @@ -0,0 +1,44 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelIsotropicWriter_Float4 : VoxelLayout_Float4 +{ + stream float4 center; + RWTexture3D DirectOutput; + compose VoxelFragmentPacker writer; + + float maxBrightnessInv; + + compose VoxelModifierApplierIsotropic Modifiers[]; + override void InitializeDummy() + { + streams.center = float4(0,0,0,0); + } + override void InitializeFromStreams(float4 original) + { + streams.center = original; + } + override void DirectWrite(uint3 address, uint strideIndex, uint stride) + { + address.y += strideIndex * stride; + float4 tempcenter = streams.center; + foreach (var modifier in Modifiers) + { + modifier.Apply(tempcenter); + } + streams.center = tempcenter; + + DirectOutput[address] = float4(streams.center.rgb * maxBrightnessInv, streams.center.a); + } + override void IndirectWrite(RWBuffer buffer, uint address) + { + writer.Write(buffer, address, streams.center); + } + override void InitializeFromBuffer(RWBuffer buffer, uint address) + { + writer.Read(buffer, address, streams.center); + } + override float4 SampleLocal() + { + return streams.center; + } +}; diff --git a/assets/Stride/SDSL/VoxelLayout_Float4.sdsl b/assets/Stride/SDSL/VoxelLayout_Float4.sdsl new file mode 100644 index 0000000000..d504cc51e8 --- /dev/null +++ b/assets/Stride/SDSL/VoxelLayout_Float4.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelLayout_Float4 : NormalStream +{ + void InitializeDummy(){} + void InitializeFromStreams(float4 original){} + void IndirectWrite(RWBuffer buffer, uint address){} + void InitializeFromBuffer(RWBuffer buffer, uint address){} + void DirectWrite(uint3 address, uint strideIndex, uint stride){} + float4 SampleLocal() + { + return float4(0,0,0,0); + } +}; diff --git a/assets/Stride/SDSL/VoxelMarchBeam.sdsl b/assets/Stride/SDSL/VoxelMarchBeam.sdsl new file mode 100644 index 0000000000..704c5ace1a --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchBeam.sdsl @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchBeam : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes +{ + #ifndef AttributeID + #define AttributeID 0 + #endif + override float4 March(float3 rayPos, float3 rayDir) + { + return MarchRadius(rayPos, rayDir, 1.0); + } + override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) + { + float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); + float dist = voxelSize; + float4 light = float4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < steps; i++) + { + float size = beamDiameter * radiusScale; + float3 pos = rayPos + rayDir * dist; + + light += AttributeSamplers[AttributeID].Sample(pos, -rayDir, AttributeSamplers[AttributeID].VoxelSize() * size) * saturate(1.0 - light.a); + + dist += AttributeSamplers[AttributeID].VoxelSize() * stepScale; + } + return light; + } + + override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } + override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchCone.sdsl b/assets/Stride/SDSL/VoxelMarchCone.sdsl new file mode 100644 index 0000000000..3dd3d7c411 --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchCone.sdsl @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchCone : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes +{ + #ifndef sampleFunction + #define sampleFunction Sample + #define AttributeID 0 + #endif + override float4 March(float3 rayPos, float3 rayDir) + { + return MarchRadius(rayPos, rayDir, 1.0); + } + override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) + { + float finalRatio = coneRatio.x * radiusScale; + float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); + + float dist = voxelSize / max(1,finalRatio); + + float4 light = float4(0.0, 0.0, 0.0, 0.0); + rayPos += offset * voxelSize * rayDir; + + for (int i = 0; i < steps; i ++) + { + float diameter = max(voxelSize, finalRatio * dist); + float3 pos = rayPos + rayDir * dist; + + light += AttributeSamplers[AttributeID].sampleFunction(pos, -rayDir, diameter) * saturate(1.0 - light.a); + + dist += diameter * stepScale; + } + return light; + } + override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } + override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } +}; diff --git a/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl b/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl new file mode 100644 index 0000000000..428f8ce219 --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchConeEditMode : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes +{ + #ifndef AttributeID + #define AttributeID 0 + #endif + cbuffer PerView.Lighting + { + int steps; + float stepScale; + float coneRatio; + int fast; + float offset; + } + override float4 March(float3 rayPos, float3 rayDir) + { + return MarchRadius(rayPos, rayDir, 1.0); + } + override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) + { + float finalRatio = coneRatio.x * radiusScale; + float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); + + float dist = voxelSize / max(1,finalRatio); + + float4 light = float4(0.0, 0.0, 0.0, 0.0); + rayPos += offset * voxelSize * rayDir; + + for (int i = 0; i < steps; i ++) + { + float diameter = max(voxelSize, finalRatio * dist); + float3 pos = rayPos + rayDir * dist; + + if (fast) + light += AttributeSamplers[AttributeID].SampleNearestMip(pos, -rayDir, diameter) * saturate(1.0 - light.a); + else + light += AttributeSamplers[AttributeID].Sample(pos, -rayDir, diameter) * saturate(1.0 - light.a); + + dist += diameter * stepScale; + } + return light; + } + + override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } + override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } +}; diff --git a/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl b/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl new file mode 100644 index 0000000000..b9847d3516 --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl @@ -0,0 +1,33 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchConePerMipmap : VoxelMarchMethod, MarchAttributes +{ + #ifndef AttributeID + #define AttributeID 0 + #endif + cbuffer PerView.Lighting + { + float offset; + float coneRatioInv; + } + override float4 March(float3 rayPos, float3 rayDir) + { + float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); + rayPos += rayDir * voxelSize * offset; + float dist = voxelSize * coneRatioInv; + float size = 0; + float4 light = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < steps; i++) + { + float3 pos = rayPos + rayDir * dist; + + light += AttributeSamplers[AttributeID].SampleByMipNearestMip(pos, -rayDir, size) * saturate(1.0 - light.a); + + dist *= 2; + size += 1; + } + return light; + } + + override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchMethod.sdsl b/assets/Stride/SDSL/VoxelMarchMethod.sdsl new file mode 100644 index 0000000000..86833761aa --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchMethod.sdsl @@ -0,0 +1,7 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchMethod +{ + float4 March(float3 rayPos, float3 rayDir){ return float4(0, 0, 0, 0); } + float StepSize(){ return 1.0; } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchSet.sdsl b/assets/Stride/SDSL/VoxelMarchSet.sdsl new file mode 100644 index 0000000000..0bb7aa8b38 --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchSet.sdsl @@ -0,0 +1,6 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchSet +{ + float4 March(float3 rayPos, float3 rayDir){ return float4(0, 0, 0, 0); } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl b/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl new file mode 100644 index 0000000000..cd3006e6ad --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchSetHemisphere12 : VoxelMarchSet +{ + cbuffer PerView.Lighting + { + float offset; + } + compose VoxelMarchMethod Marcher; + override float4 March(float3 rayPos, float3 rayDir) + { + float3 tan = normalize(cross(rayDir, normalize(float3(1, 1, 1)))); + float3 bitan = cross(tan, rayDir); + float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); + + float3 startPos = rayPos + rayDir * Marcher.StepSize() * offset; + + float4 reflLighting = float4(0, 0, 0, 0); + + //Dot products of rays + float central = 0.84; + float outer = 0.22; + float sum = (central*4+outer*8); + central /= sum; + outer /= sum; + + rayDir = mul(float3(-0.38, -0.37, 0.84), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * central; + rayDir = mul(float3(-0.31, 0.43, 0.84), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * central; + rayDir = mul(float3(0.36, 0.39, 0.84), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * central; + rayDir = mul(float3(0.36, -0.39, 0.84), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * central; + + rayDir = mul(float3(-0.87, 0.41, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(-0.35, 0.90, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(0.40, 0.88, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(0.92, 0.31, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(0.87, -0.43, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(0.30, -0.92, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(-0.43, -0.87, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + rayDir = mul(float3(-0.93, -0.28, 0.22), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + return reflLighting; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl b/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl new file mode 100644 index 0000000000..a2bcff2a6a --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchSetHemisphere6 : VoxelMarchSet, ShaderBase +{ + cbuffer PerView.Lighting + { + float offset; + } + compose VoxelMarchMethod Marcher; + override float4 March(float3 rayPos, float3 rayDir) + { + float3 tan = normalize(cross(rayDir, normalize(float3(1, 1, 1)))); + float3 bitan = cross(tan, rayDir); + float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); + + float3 startPos = rayPos + rayDir * Marcher.StepSize() * offset; + + float4 reflLighting = float4(0, 0, 0, 0); + + //Dot products of rays + float central = 1.0; + float outer = 0.445; + float sum = central + outer * 5; + central /= sum; + outer /= sum; + + rayDir = mul(float3(0, 0, 1), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * central; + + rayDir = mul(normalize(float3(0.85, 0.278, 0.445)), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + rayDir = mul(normalize(float3(0.527, -0.723, 0.445)), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + rayDir = mul(normalize(float3(-0.526, -0.724, 0.445)), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + rayDir = mul(normalize(float3(-0.851, 0.277, 0.445)), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + rayDir = mul(normalize(float3(0.895, 0.445, 0.445)), tangentMatrix); + reflLighting += Marcher.March(startPos, rayDir) * outer; + + return reflLighting; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl b/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl new file mode 100644 index 0000000000..48206a4146 --- /dev/null +++ b/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelMarchSetRandomHemisphere : VoxelMarchSet, ShaderBase +{ + cbuffer PerView.Lighting + { + int marchCount; + float time; + } + float Random(in float2 uv) + { + float2 noise = (frac(sin(dot(uv,float2(12.9898,78.233)*2.0)) * 43758.5453)); + return abs(noise.x + noise.y) * 0.5; + } + float3 CosineWeightedPointOnHemisphere(float2 uv) { + float u = Random(uv) * 6.28; + float v = Random(uv + 0.1); + + v = sqrt(v); + + float2 pos = float2(sin(u),cos(u)) * v; + + return float3(pos, sqrt(1-pos.x*pos.x-pos.y*pos.y)); + } + + compose VoxelMarchMethod Marcher; + override float4 March(float3 rayPos, float3 rayDir) + { + float3 tan = normalize(cross(rayDir, normalize(float3(1,1,1)))); + float3 bitan = cross(tan, rayDir); + float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); + + float3 startPos = rayPos + rayDir * Marcher.StepSize(); + + float4 reflLighting = float4(0, 0, 0, 0); + + for(int i = 0; i < marchCount; i ++) + { + float3 dir = CosineWeightedPointOnHemisphere(streams.ShadingPosition.xy + i*1.73 + time); + dir = mul(dir, tangentMatrix); + reflLighting += Marcher.March(startPos, dir); + } + + return reflLighting/(float)marchCount; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl new file mode 100644 index 0000000000..64d397ed0a --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierAnisotropic +{ + void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN){ } + void Apply(inout float3 XP, inout float3 XN, inout float3 YP, inout float3 YN, inout float3 ZP, inout float3 ZN){ } + void Apply(inout float2 XP, inout float2 XN, inout float2 YP, inout float2 YN, inout float2 ZP, inout float2 ZN){ } + void Apply(inout float XP, inout float XN, inout float YP, inout float YN, inout float ZP, inout float ZN){ } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl b/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl new file mode 100644 index 0000000000..e67093323d --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierAnisotropicPaired +{ + void Apply(inout float4 X, inout float4 Y, inout float4 Z){ } + void Apply(inout float3 X, inout float3 Y, inout float3 Z){ } + void Apply(inout float2 X, inout float2 Y, inout float2 Z){ } + void Apply(inout float X, inout float Y, inout float Z){ } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl new file mode 100644 index 0000000000..a5f09799f8 --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierAntiAliasingAnisotropic : VoxelModifierApplierAnisotropic, LocalSamples +{ + override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) + { + float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; + XP *= PlaneCoverage.x; + XN *= PlaneCoverage.x; + YP *= PlaneCoverage.y; + YN *= PlaneCoverage.y; + ZP *= PlaneCoverage.z; + ZN *= PlaneCoverage.z; + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl new file mode 100644 index 0000000000..62e9f2218f --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierAntiAliasingAnisotropicPaired : VoxelModifierApplierAnisotropicPaired, LocalSamples +{ + override void Apply(inout float4 X, inout float4 Y, inout float4 Z) + { + float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; + X *= PlaneCoverage.x; + Y *= PlaneCoverage.y; + Z *= PlaneCoverage.z; + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl new file mode 100644 index 0000000000..8185dbb518 --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierAntiAliasingIsotropic : VoxelModifierApplierIsotropic, LocalSamples +{ + override void Apply(inout float4 center) + { + float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; + center *= max(PlaneCoverage.x, max(PlaneCoverage.y, PlaneCoverage.z)); + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl new file mode 100644 index 0000000000..23d34d62bb --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierIsotropic +{ + void Apply(inout float4 center){} + void Apply(inout float3 center){} + void Apply(inout float2 center){} + void Apply(inout float center){} +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl new file mode 100644 index 0000000000..9006b8e50b --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierOpacifyAnisotropic : VoxelModifierApplierAnisotropic +{ + [Link("VoxelModifierApplierOpacifyIsotropic.Amount")] + float Amount; + + override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) + { + XP.a *= Amount; + XN.a *= Amount; + YP.a *= Amount; + YN.a *= Amount; + ZP.a *= Amount; + ZN.a *= Amount; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl b/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl new file mode 100644 index 0000000000..9b83671281 --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierOpacifyAnisotropicPaired : VoxelModifierApplierAnisotropicPaired +{ + [Link("VoxelModifierApplierOpacifyIsotropic.Amount")] + float Amount; + + override void Apply(inout float4 X, inout float4 Y, inout float4 Z) + { + X.a *= Amount; + Y.a *= Amount; + Z.a *= Amount; + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl new file mode 100644 index 0000000000..e0997dfd3b --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierOpacifyIsotropic : VoxelModifierApplierIsotropic +{ + float Amount; + override void Apply(inout float4 center) + { + center.a *= Amount; + } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl new file mode 100644 index 0000000000..19763d2e4d --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierSolidifyAnisotropic : VoxelModifierApplierAnisotropic, LocalSamples +{ + override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) + { + float Solidity = streams.LocalSample[SolidityAttributeID].a; + XP.a = max(Solidity, XP.a); + XN.a = max(Solidity, XN.a); + YP.a = max(Solidity, YP.a); + YN.a = max(Solidity, YN.a); + ZP.a = max(Solidity, ZP.a); + ZN.a = max(Solidity, ZN.a); + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl b/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl new file mode 100644 index 0000000000..1967d6b166 --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierSolidifyAnisotropicPaired : VoxelModifierApplierAnisotropicPaired, LocalSamples +{ + override void Apply(inout float4 X, inout float4 Y, inout float4 Z) + { + float Solidity = streams.LocalSample[SolidityAttributeID].a; + X.a = max(Solidity, X.a); + Y.a = max(Solidity, Y.a); + Z.a = max(Solidity, Z.a); + } +}; diff --git a/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl b/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl new file mode 100644 index 0000000000..5fc4ac4f1b --- /dev/null +++ b/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelModifierApplierSolidifyIsotropic : VoxelModifierApplierIsotropic, LocalSamples +{ + override void Apply(inout float4 center) + { + float Solidity = streams.LocalSample[SolidityAttributeID].a; + center.a = max(Solidity, center.a); + } +}; diff --git a/assets/Stride/SDSL/VoxelPositionStream.sdsl b/assets/Stride/SDSL/VoxelPositionStream.sdsl new file mode 100644 index 0000000000..245c59bebf --- /dev/null +++ b/assets/Stride/SDSL/VoxelPositionStream.sdsl @@ -0,0 +1,8 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelPositionStream +{ + stage stream float3 PositionVXS : POSITIONVXS; + stage stream int3 PositionVXPS : POSITIONVXPS; + stage stream float3 VoxelVolumeSize : VOXELVOLUMESIZE; +}; diff --git a/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl b/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl new file mode 100644 index 0000000000..a8d4ea59d9 --- /dev/null +++ b/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl @@ -0,0 +1,7 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelRadiusMarchMethod +{ + float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale){ return float4(0, 0, 0, 0); } + float StepSizeRadius(float radiusScale){ return radiusScale; } +}; \ No newline at end of file diff --git a/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl b/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl new file mode 100644 index 0000000000..6c92423e2e --- /dev/null +++ b/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl @@ -0,0 +1,107 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelStorageClipmapShader : VoxelStorageShader, Texturing, ShaderBaseStream, Transformation +{ + cbuffer PerView.VoxelizerStorer + { + float3 clipMapResolution; + //#ifdef singleClip + float clipPos; + float3 clipScale; + float3 clipOffset; + //#else + float clipMapCount; + float4 perClipMapOffsetScale[20]; + //#endif + float storageUints; + } + rgroup PerView.VoxelizerStorer + { + RWBuffer fragmentsBuffer; + } + compose VoxelAttribute AttributesTemp[]; + compose VoxelAttribute AttributesDirect[]; + compose VoxelAttribute AttributesIndirect[]; + + #ifdef singleClip + #define clipScaleIn clipScale + #define clipOffsetIn clipOffset + #define clipPosIn ((uint)clipPos) + #else + stage stream uint clipIndex; + #define clipScaleIn perClipMapOffsetScale[streams.clipIndex].w + #define clipOffsetIn perClipMapOffsetScale[streams.clipIndex].xyz + #define clipPosIn ((streams.clipIndex) * clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z) + #endif + + #ifndef IndirectStoreMacro + #define IndirectStoreMacro + #endif + + override bool MightStoreFragments() + { + float3 texPos = streams.PositionWS.xyz * clipScaleIn + clipOffsetIn; + return dot(texPos - saturate(texPos), float3(1, 1, 1)) == 0; + } + override void StoreFragments() + { + int3 clipMapResolutionI = (int3)clipMapResolution; + + float3 texPos = streams.PositionWS.xyz * clipScaleIn + clipOffsetIn; + + streams.PositionVXS = texPos; + streams.VoxelVolumeSize = clipMapResolution; + streams.PositionVXPS = int3(floor(saturate(texPos) * clipMapResolution)); + + int3 pixelPos = streams.PositionVXPS; + + uint index = clipPosIn + pixelPos.x + pixelPos.y * clipMapResolutionI.x + pixelPos.z * clipMapResolutionI.x * clipMapResolutionI.y; + + uint writeindex = index * (uint)storageUints; + + foreach (var attr in AttributesTemp) + { + attr.InitializeFromStreams(); + } + + foreach (var attr in AttributesDirect) + { + attr.InitializeFromStreams(); + } + + foreach (var attr in AttributesIndirect) + { + attr.InitializeFromStreams(); + } + + //See VoxelStorageClipmaps.cs Line #307 and Line #425 + IndirectStoreMacro + } + #ifndef singleClip + override void GenerateTriangles(triangle Input input[3], inout TriangleStream triangleStream) + { + method.InitializeFromTriangle(input); + int3 clipMapResolutionI = (int3)clipMapResolution; + + for (streams.clipIndex = 0; streams.clipIndex < clipMapCount; streams.clipIndex++) + { + [unroll] + for (int i = 0; i < 3 ; i ++) + { + streams = input[i]; + streams.ShadingPosition.xyz = mul(float4(streams.PositionWS.xyz * clipScaleIn + clipOffsetIn, 1),Transformation.View).xyz; + streams.ShadingPosition.xyz = streams.ShadingPosition.xyz * 2 - 1; + method.Append(triangleStream); + } + method.RestartStrip(triangleStream); + } + } + #else + override void PrepareVertex() + { + method.PrepareVertex(); + streams.ShadingPosition.xyz = mul(float4(streams.PositionWS.xyz * clipScaleIn + clipOffsetIn, 1),Transformation.View).xyz; + streams.ShadingPosition.xyz = streams.ShadingPosition.xyz * 2 - 1; + } + #endif +}; diff --git a/assets/Stride/SDSL/VoxelStorageShader.sdsl b/assets/Stride/SDSL/VoxelStorageShader.sdsl new file mode 100644 index 0000000000..ed92b8d972 --- /dev/null +++ b/assets/Stride/SDSL/VoxelStorageShader.sdsl @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelStorageShader : VoxelPositionStream, PositionStream4, ShaderBaseStream +{ + compose VoxelizationMethod method; + void PrepareFragments(){ method.PrepareFragment(); } + void StoreFragments(){ } + bool MightStoreFragments(){ return false; } + void PrepareVertex(){ method.PrepareVertex(); } + void GenerateTriangles(triangle Input input [3], inout TriangleStream triangleStream) + { + method.InitializeFromTriangle(input); + [unroll] + for (int i = 0; i < 3 ; i++) + { + streams = input[i]; + method.Append(triangleStream); + } + method.RestartStrip(triangleStream); + } +}; diff --git a/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl b/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl new file mode 100644 index 0000000000..67fe02142f --- /dev/null +++ b/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl @@ -0,0 +1,181 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelStorageTextureClipmapShader : VoxelStorageTextureShader, Texturing +{ + #define MapCount 20 + cbuffer PerView.Lighting + { + float4 perMapOffsetScale[MapCount]; + } + rgroup PerView.Lighting + { + Texture3D clipMaps; + Texture3D mipMaps; + } + + stage SamplerState LinearBorderSampler3D + { + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Border; + AddressV = Border; + AddressW = Border; + }; + stage SamplerState LinearBorderSampler3D_NearestMip + { + Filter = MIN_MAG_LINEAR_MIP_POINT; + AddressU = Border; + AddressV = Border; + AddressW = Border; + }; + override float VoxelSize() + { + return voxelSizeT; + } + override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) + { + if (textureID == 0) + { + return clipMaps.SampleLevel(Sampler, pos, 0); + } + else + { + return mipMaps.SampleLevel(Sampler, pos, mipmap); + } + return float4(0,0,0,0); + } + + override float4 SampleNearestMip(float3 pos, float diameter, int axis) + { + diameter *= 1.0 / voxelSizeT; + float mipmap = log2(max(1, diameter)); + return SampleByMipNearestMip(pos, mipmap, axis); + } + override float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis) + { + //Clipmaps + float3 clipMapSizeClip = float3(1, 1.0 / (clipCountT * axisCountT), 1); + float3 axisStrideClip = float3(0, 1.0 / (clipCountT * axisCountT), 0); + float3 clipSetStrideClip = float3(0, 1.0 / clipCountT, 0); + + //Mipmaps + float3 axisSizeMip = float3(1, 1.0 / (axisCountT), 1); + float3 axisStrideMip = float3(0, 1.0 / (axisCountT), 0); + + float mipBase = floor(mipmap); + + float4 offsetScale = perMapOffsetScale[mipBase]; + pos = pos * offsetScale.w + offsetScale.xyz; + + if (mipBase >= clipCountT) + { + //Seperate the different axis within the same texture + //by clamping to the usable texel range + //and fading out above and below + float boundaryFade = 1.0; + if (axisCountT > 1) + { + float height = mipHeightT / (pow(2, mipBase - clipCountT)); + + float texelY = pos.y * height; + float texelYClamped = clamp(texelY, 1, height - 1); + float boundaryFade = saturate(1.0 - abs(texelYClamped - texelY)); + + pos.y = texelYClamped / height; + + pos *= axisSizeMip; + pos += axisStrideMip * axis; + } + return mipMaps.SampleLevel(LinearBorderSampler3D_NearestMip, pos, mipBase - clipCountT) * boundaryFade; + } + else + { + pos.y = saturate(pos.y); + + pos *= clipMapSizeClip; + pos += axisStrideClip * axis + clipSetStrideClip * mipBase; + return clipMaps.SampleLevel(LinearBorderSampler3D_NearestMip, pos, 0); + } + } + override float4 Sample(float3 pos, float diameter, int axis) + { + //Clipmaps + float3 clipMapSizeClip = float3(1, 1.0 / (clipCountT * axisCountT), 1); + float3 axisStrideClip = float3(0, 1.0 / (clipCountT * axisCountT), 0); + float3 clipSetStrideClip = float3(0, 1.0 / clipCountT, 0); + + //Mipmaps + float3 axisSizeMip = float3(1, 1.0 / (axisCountT), 1); + float3 axisStrideMip = float3(0, 1.0 / (axisCountT), 0); + + + diameter *= 1.0 / voxelSizeT; + float mipmap = log2(max(1, diameter)); + + float mipBase = floor(mipmap); + + + float4 offsetScale = perMapOffsetScale[mipBase]; + float3 posFine = pos * offsetScale.w + offsetScale.xyz; + + offsetScale = perMapOffsetScale[mipBase + 1]; + float3 posCoarse = pos * offsetScale.w + offsetScale.xyz; + if (mipBase >= clipCountT) + { + //Seperate the different axis within the same texture + //by clamping to the usable texel range + //and fading out above and below + float boundaryFade = 1.0; + if (axisCountT > 1) + { + float height = mipHeightT / (pow(2, mipBase - clipCountT)); + + float texelY = posFine.y * height; + float texelYClamped = clamp(texelY, 1, height - 1); + float boundaryFade = saturate(1.0 - abs(texelYClamped - texelY)); + + posFine.y = texelYClamped / height; + + posFine *= axisSizeMip; + posFine += axisStrideMip * axis; + + posCoarse *= axisSizeMip; + posCoarse += axisStrideMip * axis; + } + return lerp ( + mipMaps.SampleLevel(LinearBorderSampler3D, posFine, mipBase - clipCountT), + mipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, mipBase - clipCountT + 1), + mipmap - mipBase) * boundaryFade; + } + else + { + posFine.y = saturate(posFine.y); + posCoarse.y = saturate(posCoarse.y); + if (mipBase == clipCountT-1) + { + posFine *= clipMapSizeClip; + posFine += axisStrideClip * axis + clipSetStrideClip * mipBase; + + posCoarse *= axisSizeMip; + posCoarse += axisStrideMip * axis; + return lerp( + clipMaps.SampleLevel(LinearBorderSampler3D, posFine, 0), + mipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, 0), + mipmap-mipBase + ); + } + else + { + posFine *= clipMapSizeClip; + posFine += axisStrideClip * axis + clipSetStrideClip * mipBase; + + posCoarse *= clipMapSizeClip; + posCoarse += axisStrideClip * axis + clipSetStrideClip * (mipBase+1); + return lerp( + clipMaps.SampleLevel(LinearBorderSampler3D, posFine, 0), + clipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, 0), + mipmap-mipBase + ); + } + } + } +}; diff --git a/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl b/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl new file mode 100644 index 0000000000..f5a2ee0801 --- /dev/null +++ b/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelStorageTextureShader +{ + float4 Sample(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } + float4 SampleNearestMip(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } + float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis){ return float4(0, 1, 0, 0); } + float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis){ return float4(1, 0, 0, 0); } + float VoxelSize(){ return 1.0; }; +}; diff --git a/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl b/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl new file mode 100644 index 0000000000..d63df75527 --- /dev/null +++ b/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels.Debug +{ + effect VoxelVisualizationRawEffect + { + using params VoxelVisualizationRawShaderKeys; + + mixin VoxelVisualizationRawShader; + if (VoxelVisualizationRawShaderKeys.Attribute != null) + { + mixin compose Attribute = VoxelVisualizationRawShaderKeys.Attribute; + } + } +} diff --git a/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl b/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl new file mode 100644 index 0000000000..200a24c716 --- /dev/null +++ b/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels.Debug +{ + shader VoxelVisualizationRawShader : ImageEffectShader + { + compose IVoxelSampler Attribute; + float2 range; + float rangeOffset; + float mip; + + stage override float4 Shading() + { + float2 offsetRange = range + float(abs(range.y-range.x) * rangeOffset).xx; + float2 screenPos = streams.TexCoord.xy; + screenPos.y = 1.0 - screenPos.y; + + float4 color = float4(0, 0, 0, 0); + for (int i = 0; i < 200; i++) + { + color += Attribute.SampleRaw(float3(streams.TexCoord.x, lerp(offsetRange.x, offsetRange.y, (float)i / 200.0), streams.TexCoord.y), mip-1, (mip>0)?1:0, 0) * (1.0 - color.a); + if (color.a > 0.99) + { + break; + } + } + return color.xyzz + float4(0.1, 0.1, 0.1, 1.0) * (1.0 - color.a); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl b/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl new file mode 100644 index 0000000000..f458e6f9a7 --- /dev/null +++ b/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels.Debug +{ + effect VoxelVisualizationViewEffect + { + using params VoxelVisualizationViewShaderKeys; + using params MarchAttributesKeys; + + mixin VoxelVisualizationViewShader; + if (VoxelVisualizationViewShaderKeys.marcher != null) + { + mixin compose marcher = VoxelVisualizationViewShaderKeys.marcher; + } + if (MarchAttributesKeys.AttributeSamplers != null) + { + foreach (var attr in MarchAttributesKeys.AttributeSamplers) + { + mixin compose AttributeSamplers += (attr); + } + } + } +} diff --git a/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl b/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl new file mode 100644 index 0000000000..09594aed14 --- /dev/null +++ b/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels.Debug +{ + shader VoxelVisualizationViewShader : MarchAttributes, ImageEffectShader + { + compose VoxelMarchMethod marcher; + + float4 background; + float4x4 view; + float4x4 viewInv; + + stage override float4 Shading() + { + float2 screenPos = streams.TexCoord.xy; + screenPos.y = 1.0 - screenPos.y; + + float4 p1 = mul(float4(screenPos*2.0-1.0,1,1), viewInv); + p1.xyz/=p1.w; + float4 p2 = mul(float4(0,0,0,1), viewInv); + p2.xyz/=p2.w; + + float3 rayDir = normalize( p1.xyz - p2.xyz); + float3 rayPos = p2.xyz; + + float4 color = marcher.March(rayPos, rayDir); + return color.xyzz + background * saturate(1.0-color.a); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelizationMethod.sdsl b/assets/Stride/SDSL/VoxelizationMethod.sdsl new file mode 100644 index 0000000000..0923c50d6f --- /dev/null +++ b/assets/Stride/SDSL/VoxelizationMethod.sdsl @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +shader VoxelizationMethod : VoxelPositionStream, PositionStream4, ShaderBaseStream +{ + void PrepareFragment(){ } + void PrepareVertex(){ } + + void InitializeFromTriangle(triangle Input input[3]) { } + + void Append(inout TriangleStream triangleStream) + { + streams.ShadingPosition.z = streams.ShadingPosition.z * 0.5 + 0.5; + triangleStream.Append(streams); + } + void RestartStrip(inout TriangleStream triangleStream) + { + triangleStream.RestartStrip(); + } +}; diff --git a/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl b/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl new file mode 100644 index 0000000000..23dda41cde --- /dev/null +++ b/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + /// + /// Voxelization, projects to axis of largest area and writes fragments to buffer + /// + shader VoxelizationMethodDominantAxis : VoxelizationMethod, Math, Transformation, ShaderBase, NormalStream, PositionStream4, VoxelPositionStream + { + centroid stream float3 centroidPositionWS; + centroid stream float3 centroidNormalWS; + override void PrepareFragment() + { + streams.PositionWS = float4(streams.centroidPositionWS,1); + streams.normalWS = streams.centroidNormalWS; + } + override void PrepareVertex() + { + streams.centroidPositionWS = streams.PositionWS.xyz; + streams.centroidNormalWS = streams.normalWS.xyz; + } + stream int dominantAxis; + override void InitializeFromTriangle(triangle Input input[3]) + { + float3 nor = abs(cross((input[1].ShadingPosition.xyz - input[0].ShadingPosition.xyz), (input[2].ShadingPosition.xyz - input[0].ShadingPosition.xyz))); + streams.dominantAxis = nor.x > nor.y ? 0 : 1; + streams.dominantAxis = nor.z > nor.y && nor.z > nor.x ? 2 : streams.dominantAxis; + } + void TransformPoint(inout float4 v1) + { + if (streams.dominantAxis == 0) + { + v1.xyz = float3(v1.yzx); + } + else if (streams.dominantAxis == 1) + { + v1.xyz = float3(v1.xzy); + } + v1.w = 1; + } + override void Append(inout TriangleStream triangleStream) + { + TransformPoint(streams.ShadingPosition); + streams.ShadingPosition.z = streams.ShadingPosition.z * 0.5 + 0.5; + triangleStream.Append(streams); + } + }; +} diff --git a/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl b/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl new file mode 100644 index 0000000000..1462f37243 --- /dev/null +++ b/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + /// + /// Voxelization, projects to axis of largest area and writes fragments to buffer + /// + shader VoxelizationMethodSingleAxis : VoxelizationMethod, Math, Transformation, ShaderBase, NormalStream, PositionStream4, VoxelPositionStream + { + centroid stream float3 centroidPositionWS; + override void PrepareFragment() + { + streams.PositionWS = float4(streams.centroidPositionWS,1); + } + override void PrepareVertex() + { + streams.centroidPositionWS = streams.PositionWS.xyz; + } + }; +} diff --git a/assets/Stride/SDSL/VoxelizeToFragments.sdsl b/assets/Stride/SDSL/VoxelizeToFragments.sdsl new file mode 100644 index 0000000000..e5ab198df6 --- /dev/null +++ b/assets/Stride/SDSL/VoxelizeToFragments.sdsl @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Rendering.Voxels +{ + /// + /// Voxelization, projects to axis of largest area and writes fragments to buffer + /// + shader VoxelizeToFragments : Math, Transformation, ShaderBase, Texturing, NormalStream, PositionStream4, VoxelPositionStream, MaterialPixelStream, MaterialPixelShadingStream + { + compose VoxelStorageShader Storage; + override stage void PSMain() + { + Storage.PrepareFragments(); + streams.IsFrontFace = true; + if (Storage.MightStoreFragments()) + { + base.PSMain(); + Storage.StoreFragments(); + streams.ColorTarget = float4(0,0,0,0); + } + } + override stage void VSMain() + { + base.VSMain(); + Storage.PrepareVertex(); + } + #ifdef RequireGeometryShader + [maxvertexcount(GeometryShaderMaxVertexCount)] + void GSMain(triangle Input input[3], inout TriangleStream triangleStream) + { + Storage.GenerateTriangles(input, triangleStream); + } + #endif + }; +} diff --git a/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl b/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl new file mode 100644 index 0000000000..3a876b4ec0 --- /dev/null +++ b/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Materials; +using Stride.Rendering.Voxels; + +namespace Stride.Rendering.Voxels +{ + partial effect VoxelizeToFragmentsEffect + { + using params MaterialKeys; + using params VoxelizeToFragmentsKeys; + + mixin VoxelizeToFragments; + if (VoxelizeToFragmentsKeys.Storage!=null) + { + mixin compose Storage = (VoxelizeToFragmentsKeys.Storage); + } + if (VoxelizeToFragmentsKeys.RequireGeometryShader == true) + { + mixin macro RequireGeometryShader = true; + mixin macro VoxelizeToFragmentsKeys.GeometryShaderMaxVertexCount; + } + }; +} From a2ae41a4837db2feb3763fa4d6d138eca1b975e1 Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Wed, 16 Oct 2024 17:44:20 +0200 Subject: [PATCH 0331/1182] working on effect --- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 7 ++- .../SDFX/Parsers/EffectFileParsers.cs | 36 +++++++++++++++ .../SDFX/Parsers/EffectParser.cs | 45 +++++++++++++++++++ .../SDFX/Parsers/EffectStatementParsers.cs | 35 +++++++++++++-- 4 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index f33f06c138..013b5b0acf 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -1,3 +1,5 @@ +using Stride.Shaders.Parsing.SDSL.AST; + namespace Stride.Shaders.Parsing.SDFX.AST; @@ -24,8 +26,9 @@ public override string ToString() } } -public class EffectClass(TextLocation info) : Node(info) +public class EffectClass(TypeName name, TextLocation info) : Node(info) { + public TypeName Name { get; set; } = name; public List Members { get; set; } = []; } @@ -38,7 +41,7 @@ public class MixinUse(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectSta public abstract class Composable(); -public class ComposeMixin(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinCompose(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) { public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs index e69de29bb2..8a1ef2980c 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs @@ -0,0 +1,36 @@ +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.SDFX.Parsers; + +public record struct EffectFileParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFile parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + CommonParsers.Spaces0(ref scanner, result, out _); + throw new NotImplementedException(); + } +} + + +public record struct EffectNamespaceParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + + if(Terminals.Literal("namespace", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + do + { + + } + while (!scanner.IsEof && !Terminals.Char(';', ref scanner) && Terminals.Char('.', ref scanner, advance: true)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs new file mode 100644 index 0000000000..869bd65215 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.SDFX.Parsers; + + +public record struct EffectParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("effect", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if (LiteralsParser.TypeName(ref scanner, result, out var effectName) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + parsed = new(effectName, new()); + if (Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + while( + !scanner.IsEof + && !Terminals.Char('}', ref scanner) + ) + { + if (EffectStatementParsers.Statement(ref scanner, result, out var s) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + parsed.Members.Add(s); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement here", scanner.CreateError(scanner.Position))); + } + if(scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement or end of block", scanner.CreateError(scanner.Position))); + else if(Terminals.Char('}', ref scanner, advance: true)) + { + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + } + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool EffectStatement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 43fc6d2c82..cf1b065f15 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -9,8 +9,35 @@ public record struct EffectStatementParsers : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - throw new NotImplementedException(); + var position = scanner.Position; + if(UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = p1; + return true; + } + else if(MixinCompose(ref scanner, result, out var p2, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = p2; + return true; + } + else if(MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = p3; + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + + public static bool Statement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); + + public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); + + public static bool MixinCompose(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new MixinComposeParser().Match(ref scanner, result, out parsed, orError); + public static bool MixinUse(ref TScanner scanner, ParseResult result, out AST.MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new MixinUseParser().Match(ref scanner, result, out parsed, orError); } @@ -34,9 +61,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct MixinComposeParser : IParser +public record struct MixinComposeParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ComposeMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( @@ -65,7 +92,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct MixinParser : IParser +public record struct MixinUseParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner { From c5c2da05d9603257fa78658e9a6ae5ff08ba59a9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 17 Oct 2024 22:05:24 +0200 Subject: [PATCH 0332/1182] more sdfx work --- .../Examples.cs | 3 +- src/Stride.Shaders.Parsing/ASTNode.cs | 26 ++++++++++ src/Stride.Shaders.Parsing/Grammar.cs | 3 +- src/Stride.Shaders.Parsing/IParser.cs | 2 +- src/Stride.Shaders.Parsing/ParseResult.cs | 2 +- .../SDFX/AST/Effect.Parameters.cs | 2 +- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 41 ++++----------- .../SDFX/Parsers/EffectFileParsers.cs | 50 +++++++++---------- .../SDFX/Parsers/EffectParser.cs | 6 ++- .../SDFX/Parsers/ParamsParsers.cs | 2 + src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs | 28 ++--------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../SDSL/Analysis/SymbolTable.cs | 2 +- .../ShaderParsers/ShaderClassParser.cs | 28 +++++------ .../ShaderParsers/ShaderFileParsers.cs | 21 ++++++-- .../{SDSL => }/SDSLParser.cs | 3 +- 16 files changed, 113 insertions(+), 110 deletions(-) rename src/Stride.Shaders.Parsing/{SDSL => }/SDSLParser.cs (82%) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 025707bbc6..757c3244fc 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -4,6 +4,7 @@ using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; +using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL; namespace Stride.Shaders.Experiments; @@ -79,7 +80,7 @@ public static void SpvOpt() public static void ParseSDSL() { - var text = File.ReadAllText("./assets/Stride/SDSL/B.sdsl"); + var text = File.ReadAllText("./assets/Stride/SDSL/AdditiveLightEffect.sdsl"); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders.Parsing/ASTNode.cs index d2bdd263e5..5919fdb32c 100644 --- a/src/Stride.Shaders.Parsing/ASTNode.cs +++ b/src/Stride.Shaders.Parsing/ASTNode.cs @@ -11,3 +11,29 @@ public class ValueNode(TextLocation info) : Node(info) public string? Type { get; set; } = null; } public class NoNode() : Node(new()); + +public abstract class ShaderDeclaration(TextLocation info) : Node(info); + + +public class ShaderFile(TextLocation info) : Node(info) +{ + public List RootDeclarations { get; set; } = []; + public List Namespaces { get; set; } = []; + + public override string ToString() + { + return $"{string.Join("\n", RootDeclarations)}\n\n{string.Join("\n", Namespaces)}"; + } +} + +public class ShaderNamespace(TextLocation info) : Node(info) +{ + public List NamespacePath { get; set; } = []; + public string? Namespace { get; set; } + public List Declarations { get; set; } = []; + + public override string ToString() + { + return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", Declarations)}End\n"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs index 3df059b5d1..483eec7a48 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders.Parsing/Grammar.cs @@ -1,6 +1,7 @@ +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Parsing; public static class Grammar { diff --git a/src/Stride.Shaders.Parsing/IParser.cs b/src/Stride.Shaders.Parsing/IParser.cs index 3fe16c2a87..81002a4b3c 100644 --- a/src/Stride.Shaders.Parsing/IParser.cs +++ b/src/Stride.Shaders.Parsing/IParser.cs @@ -1,6 +1,6 @@ using Stride.Shaders.Parsing.SDSL.AST; -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Parsing; public interface IParser; diff --git a/src/Stride.Shaders.Parsing/ParseResult.cs b/src/Stride.Shaders.Parsing/ParseResult.cs index 412dbbf749..967332acfa 100644 --- a/src/Stride.Shaders.Parsing/ParseResult.cs +++ b/src/Stride.Shaders.Parsing/ParseResult.cs @@ -1,6 +1,6 @@ using Stride.Shaders.Parsing.SDSL.AST; -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Parsing; public record struct ParseError(string Message, ErrorLocation Location) diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs index fc8dd61e69..fcc521013c 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs @@ -3,7 +3,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectParameters(TypeName name, TextLocation info) : Node(info) +public class EffectParameters(TypeName name, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; public List Parameters { get; set; } = []; diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 013b5b0acf..7bfcafc98d 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -3,30 +3,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectFile(TextLocation info) : Node(info) -{ - public List RootClasses { get; set; } = []; - public List Namespaces { get; set; } = []; - - public override string ToString() - { - return $"{string.Join("\n", RootClasses)}\n\n{string.Join("\n", Namespaces)}"; - } -} - -public class EffectNamespace(TextLocation info) : Node(info) -{ - public List NamespacePath { get; set; } = []; - public string? Namespace { get; set; } - public List ShaderClasses { get; set; } = []; - - public override string ToString() - { - return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", ShaderClasses)}End\n"; - } -} - -public class EffectClass(TypeName name, TextLocation info) : Node(info) +public class ShaderEffect(TypeName name, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; public List Members { get; set; } = []; @@ -34,25 +11,25 @@ public class EffectClass(TypeName name, TextLocation info) : Node(info) public abstract class EffectStatement(TextLocation info) : Node(info); -public class MixinUse(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinUse(InheritedMixin mixin, TextLocation info) : EffectStatement(info) { - public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; + public InheritedMixin MixinName { get; set; } = mixin; } public abstract class Composable(); -public class MixinCompose(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinCompose(InheritedMixin mixin, TextLocation info) : EffectStatement(info) { - public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; + public InheritedMixin MixinName { get; set; } = mixin; } -public class ComposeParams(SDSL.AST.ShaderMixin mixin, TextLocation info) : EffectStatement(info) +public class ComposeParams(InheritedMixin mixin, TextLocation info) : EffectStatement(info) { - public SDSL.AST.ShaderMixin MixinName { get; set; } = mixin; + public InheritedMixin MixinName { get; set; } = mixin; } -public class UsingParams(SDSL.AST.Identifier name, TextLocation info) : EffectStatement(info) +public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { - public SDSL.AST.Identifier ParamsName { get; set; } = name; + public Identifier ParamsName { get; set; } = name; } public class EffectBlock(TextLocation info) : EffectStatement(info) diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs index 8a1ef2980c..877ec4ceb3 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs @@ -3,34 +3,34 @@ namespace Stride.Shaders.Parsing.SDFX.Parsers; -public record struct EffectFileParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFile parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; +// public record struct EffectFileParser : IParser +// { +// public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFile parsed, in ParseError? orError = null) +// where TScanner : struct, IScanner +// { +// var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - throw new NotImplementedException(); - } -} +// CommonParsers.Spaces0(ref scanner, result, out _); +// throw new NotImplementedException(); +// } +// } -public record struct EffectNamespaceParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; +// public record struct EffectNamespaceParser : IParser +// { +// public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner +// { +// var position = scanner.Position; - if(Terminals.Literal("namespace", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) - { - do - { +// if(Terminals.Literal("namespace", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) +// { +// do +// { - } - while (!scanner.IsEof && !Terminals.Char(';', ref scanner) && Terminals.Char('.', ref scanner, advance: true)); - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); +// } +// while (!scanner.IsEof && !Terminals.Char(';', ref scanner) && Terminals.Char('.', ref scanner, advance: true)); +// } +// return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } -} \ No newline at end of file +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index 869bd65215..e30b5fb079 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -4,9 +4,9 @@ namespace Stride.Shaders.Parsing.SDFX.Parsers; -public record struct EffectParser : IParser +public record struct EffectParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Terminals.Literal("effect", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) @@ -40,6 +40,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + public static bool Effect(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new EffectParser().Match(ref scanner, result, out parsed, orError); public static bool EffectStatement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index 9bc5300083..96654c4631 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -36,6 +36,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + public static bool Params(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new ParamsParsers().Match(ref scanner, result, out parsed, orError); public static bool Parameter(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParameterParser().Match(ref scanner, result, out parsed, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs index 66987336a8..b390586b9c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -2,35 +2,13 @@ namespace Stride.Shaders.Parsing.SDSL.AST; -public class ShaderFile(TextLocation info) : Node(info) -{ - public List RootClasses { get; set; } = []; - public List Namespaces { get; set; } = []; - - public override string ToString() - { - return $"{string.Join("\n", RootClasses)}\n\n{string.Join("\n", Namespaces)}"; - } -} - -public class ShaderNamespace(TextLocation info) : Node(info) -{ - public List NamespacePath { get; set; } = []; - public string? Namespace { get; set; } - public List ShaderClasses { get; set; } = []; - - public override string ToString() - { - return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", ShaderClasses)}End\n"; - } -} -public class ShaderClass(Identifier name, TextLocation info) : Node(info) +public class ShaderMixin(Identifier name, TextLocation info) : ShaderDeclaration(info) { public Identifier Name { get; set; } = name; public List Elements { get; set; } = []; public ShaderParameterDeclarations? Generics { get; set; } - public List Mixins { get; set; } = []; + public List Mixins { get; set; } = []; public override string ToString() @@ -53,7 +31,7 @@ public class ShaderGenerics(Identifier typename, Identifier name, TextLocation i public Identifier TypeName { get; set; } = typename; } -public class ShaderMixin(Identifier name, TextLocation info) : Node(info) +public class InheritedMixin(Identifier name, TextLocation info) : Node(info) { public Identifier Name { get; set; } = name; public ShaderExpressionList? Generics { get; set; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 83abc9d4f8..4896e40b2c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,10 +7,10 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : public List Attributes { get; set; } = []; } -public class ShaderCompose(Identifier name, ShaderMixin mixin, TextLocation info) : MethodOrMember(info) +public class ShaderCompose(Identifier name, InheritedMixin mixin, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; } = name; - public ShaderMixin Mixin { get; } = mixin; + public InheritedMixin Mixin { get; } = mixin; public override string ToString() => $"compose {Mixin} {Name};"; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs index 106a08db0d..89fcbeba24 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -11,7 +11,7 @@ public partial class SymbolTable public Dictionary DeclaredTypes { get; } = []; public Stack> Symbols { get; } = []; - public void Process(ShaderClass sclass, Dictionary? globalSymbols = null) + public void Process(ShaderMixin sclass, Dictionary? globalSymbols = null) { DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass.Name, [])); foreach (var e in sclass.Elements) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 79b33520ba..96a2b4596d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -4,9 +4,9 @@ namespace Stride.Shaders.Parsing.SDSL; -public record struct ShaderClassParsers : IParser +public record struct ShaderClassParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (ComplexClass(ref scanner, result, out parsed, in orError)) @@ -14,23 +14,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return false; } - public static bool Class(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public static bool Class(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParsers().Match(ref scanner, result, out parsed, in orError); - public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); public static bool GenericsDefinition(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed) where TScanner : struct, IScanner => new ShaderGenericsDefinitionParser().Match(ref scanner, result, out parsed); - public static bool Mixin(ref TScanner scanner, ParseResult result, out ShaderMixin parsed) + public static bool Mixin(ref TScanner scanner, ParseResult result, out InheritedMixin parsed) where TScanner : struct, IScanner => new ShaderMixinParser().Match(ref scanner, result, out parsed); } -public record struct SimpleShaderClassParser : IParser +public record struct SimpleShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -45,7 +45,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { - var c = new ShaderClass(className, scanner.GetLocation(position, scanner.Position - position)); + var c = new ShaderMixin(className, scanner.GetLocation(position, scanner.Position - position)); while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) @@ -63,9 +63,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct ShaderClassParser : IParser +public record struct ShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -76,7 +76,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) ) { - parsed = new ShaderClass(identifier, scanner.GetLocation(..)); + parsed = new ShaderMixin(identifier, scanner.GetLocation(..)); if (Terminals.Char('<', ref scanner, advance: true)) { ParameterParsers.Declarations(ref scanner, result, out var generics); @@ -129,14 +129,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } -public record struct ShaderMixinParser : IParser +public record struct ShaderMixinParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out InheritedMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - parsed = new ShaderMixin(identifier, scanner.GetLocation(..)); + parsed = new InheritedMixin(identifier, scanner.GetLocation(..)); var tmpPos = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 8acee63dea..913bb1c8d7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Parsing.SDFX.Parsers; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -27,7 +28,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && ShaderClassParsers.Class(ref scanner, result, out var shader) ) { - file.RootClasses.Add(shader); + file.RootDeclarations.Add(shader); + CommonParsers.Spaces0(ref scanner, result, out _); + } + else if(Terminals.Literal("effect", ref scanner) + && EffectParser.Effect(ref scanner, result, out var effect) + ) + { + file.RootDeclarations.Add(effect); + CommonParsers.Spaces0(ref scanner, result, out _); + } + else if(Terminals.Literal("params", ref scanner) + && ParamsParsers.Params(ref scanner, result, out var p) + ) + { + file.RootDeclarations.Add(p); CommonParsers.Spaces0(ref scanner, result, out _); } } @@ -67,7 +82,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); while (ShaderClassParsers.Class(ref scanner, result, out var shader)) { - ns.ShaderClasses.Add(shader); + ns.Declarations.Add(shader); } } else if (Terminals.Char('{', ref scanner, advance: true)) @@ -76,7 +91,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if(ShaderClassParsers.Class(ref scanner, result, out var shader) && CommonParsers.Spaces0(ref scanner, result, out _)) - ns.ShaderClasses.Add(shader); + ns.Declarations.Add(shader); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class", scanner.CreateError(scanner.Position))); } diff --git a/src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs b/src/Stride.Shaders.Parsing/SDSLParser.cs similarity index 82% rename from src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs rename to src/Stride.Shaders.Parsing/SDSLParser.cs index f0bab41f2c..4546a466bc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/SDSLParser.cs +++ b/src/Stride.Shaders.Parsing/SDSLParser.cs @@ -1,7 +1,8 @@ +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Parsing.SDSL.PreProcessing; -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Parsing; public static class SDSLParser From e330f1cd4204e5bf85f75202319efd7bf52cb163 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 18 Oct 2024 12:57:15 +0200 Subject: [PATCH 0333/1182] Finishing some details about effect parsing --- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 21 ++++++++++++- .../SDFX/Parsers/EffectParser.cs | 1 + .../SDFX/Parsers/EffectStatementParsers.cs | 30 ++++++++----------- .../SDSL/Parsers/Common/CommonParsers.cs | 17 +++++++++++ .../ShaderParsers/ShaderFileParsers.cs | 12 +++++--- .../Scanners/ErrorLocation.cs | 15 +++++----- 6 files changed, 65 insertions(+), 31 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 7bfcafc98d..672027c454 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -7,6 +7,11 @@ public class ShaderEffect(TypeName name, TextLocation info) : ShaderDeclaration( { public TypeName Name { get; set; } = name; public List Members { get; set; } = []; + + public override string ToString() + { + return string.Join("", Members.Select(x => $"{x}\n")); + } } public abstract class EffectStatement(TextLocation info) : Node(info); @@ -14,13 +19,22 @@ public abstract class EffectStatement(TextLocation info) : Node(info); public class MixinUse(InheritedMixin mixin, TextLocation info) : EffectStatement(info) { public InheritedMixin MixinName { get; set; } = mixin; + public override string ToString() + { + return $"mixin {MixinName}"; + } } public abstract class Composable(); -public class MixinCompose(InheritedMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinCompose(Identifier identifier, InheritedMixin mixin, TextLocation info) : EffectStatement(info) { + public Identifier Identifier { get; set; } = identifier; public InheritedMixin MixinName { get; set; } = mixin; + public override string ToString() + { + return $"mixin compose {Identifier} = {MixinName}"; + } } public class ComposeParams(InheritedMixin mixin, TextLocation info) : EffectStatement(info) @@ -30,6 +44,11 @@ public class ComposeParams(InheritedMixin mixin, TextLocation info) : EffectStat public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { public Identifier ParamsName { get; set; } = name; + + public override string ToString() + { + return $"using params {ParamsName}"; + } } public class EffectBlock(TextLocation info) : EffectStatement(info) diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index e30b5fb079..472cae5fca 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -32,6 +32,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if(Terminals.Char('}', ref scanner, advance: true)) { parsed.Info = scanner.GetLocation(position..scanner.Position); + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); return true; } } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index cf1b065f15..f06df5ec25 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -10,17 +10,17 @@ public record struct EffectStatementParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if(UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + if (UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p1; return true; } - else if(MixinCompose(ref scanner, result, out var p2, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinCompose(ref scanner, result, out var p2, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p2; return true; } - else if(MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p3; return true; @@ -33,7 +33,7 @@ public static bool Statement(ref TScanner scanner, ParseResult result, public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); - + public static bool MixinCompose(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinComposeParser().Match(ref scanner, result, out parsed, orError); public static bool MixinUse(ref TScanner scanner, ParseResult result, out AST.MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -46,16 +46,14 @@ public record struct UsingParamsParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if(Terminals.Literal("using", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (CommonParsers.SequenceOf(ref scanner, ["using", "params"], advance: true)) { - if(Terminals.Literal("params", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _, orError : new("Expected space here", scanner.CreateError(scanner.Position)))) + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - if(LiteralsParser.Identifier(ref scanner, result, out var identifier)) - { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); - return true; - } + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + return true; } + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -67,15 +65,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("mixin", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) - && Terminals.Literal("compose", ref scanner, advance: true) + CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var name) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('=', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - + ) { if ( @@ -84,7 +80,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Terminals.Char(';', ref scanner, advance: true) ) { - parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new(name, mixin, scanner.GetLocation(position..scanner.Position)); return true; } } @@ -101,8 +97,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Terminals.Literal("mixin", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) && ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) ) { parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index c34919edc1..ee840c707b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -39,6 +39,22 @@ public static bool Spaces1(ref TScanner scanner, ParseResult result, o => new Space1(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); + public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan literals, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + foreach(var l in literals) + { + if (!(Terminals.Literal(l, ref scanner, advance: true) && Spaces1(ref scanner, null!, out _))) + { + scanner.Position = position; + return false; + } + } + scanner.Position = advance ? scanner.Position : position; + return true; + } + public static bool Optional(ref TScanner scanner, TTerminal terminal, bool advance = false) where TScanner : struct, IScanner where TTerminal : struct, ITerminal @@ -54,6 +70,7 @@ public static bool Optional(ref TScanner scanner, IParser(ref TScanner scanner, TTerminal terminal, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner where TTerminal : struct, ITerminal diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 913bb1c8d7..f1d223a209 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -31,7 +31,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o file.RootDeclarations.Add(shader); CommonParsers.Spaces0(ref scanner, result, out _); } - else if(Terminals.Literal("effect", ref scanner) + else if((Terminals.Literal("effect", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["partial", "effect"])) && EffectParser.Effect(ref scanner, result, out var effect) ) { @@ -68,6 +68,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var ns = new ShaderNamespace(new()); do { + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected identifier", scanner.CreateError(scanner.Position))); @@ -90,10 +92,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { - if(ShaderClassParsers.Class(ref scanner, result, out var shader) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (ShaderClassParsers.Class(ref scanner, result, out var shader) && CommonParsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(shader); - else - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class", scanner.CreateError(scanner.Position))); + else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) + ns.Declarations.Add(effect); + else + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class or effect", scanner.CreateError(scanner.Position))); } } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs index e647c0b364..ad17e371f0 100644 --- a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs +++ b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs @@ -21,11 +21,11 @@ public ErrorLocation(Scanner scanner, int position) scanner.Position = pos; // Setting other attributes - leftOffset = position - 5 > 0 ? 5 : position; - rightOffset = position + 5 < scanner.Span.Length ? 5 : scanner.Span.Length - position - 1; + leftOffset = Math.Max(0, position - 5); + rightOffset = Math.Min(scanner.Memory.Length, position); Position = position; - Text = scanner.Memory[(position - leftOffset)..(position + rightOffset)]; + Text = scanner.Memory; } public static ErrorLocation Create(Scanner scanner, int position) @@ -39,17 +39,16 @@ public static ErrorLocation Create(Scanner scanner, int scanner.Position = pos; // Setting other attributes - error.leftOffset = position - 5 > 0 ? 5 : position; - error.rightOffset = position + 5 < scanner.Span.Length ? 5 : scanner.Span.Length - position - 1; + error.leftOffset = Math.Max(0, position - 5); + error.rightOffset = Math.Min(scanner.Memory.Length, position); error.Position = position; - - error.Text = scanner.Memory[(position - error.leftOffset)..(position + error.rightOffset)]; + error.Text = scanner.Memory; return error; } public readonly override string ToString() { - return $"l{line}-c{column} : \n{Text[..5]}>>>{Text[5..]}"; + return $"l{line}-c{column} : \n{Text[leftOffset..Position]}>>>{Text[Position..]}"; } } From d14f283e73f48d45709064eccb98305599aff6d1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:55:12 +0200 Subject: [PATCH 0334/1182] Added submodule for preprocessing --- .gitmodules | 3 +++ submodules/CppNet8 | 1 + 2 files changed, 4 insertions(+) create mode 160000 submodules/CppNet8 diff --git a/.gitmodules b/.gitmodules index 622a474e74..d3cf9c426d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "submodules/SpirvHeaders"] path = submodules/SpirvHeaders url = https://github.com/KhronosGroup/SPIRV-Headers +[submodule "submodules/CppNet8"] + path = submodules/CppNet8 + url = https://github.com/ykafia/CppNet/ diff --git a/submodules/CppNet8 b/submodules/CppNet8 new file mode 160000 index 0000000000..a93fea69ee --- /dev/null +++ b/submodules/CppNet8 @@ -0,0 +1 @@ +Subproject commit a93fea69ee9bb51ee355ee2dc0c8d8eea7aaad50 From 1cec9eff85b7c083ecfd41eac1a9c0dd7eef5818 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 19 Oct 2024 16:55:22 +0200 Subject: [PATCH 0335/1182] Macro preprocessor testing --- assets/SDSL/Macroed.sdsl | 10 ++- .../Examples.cs | 22 +++++++ .../Program.cs | 17 ++--- .../Stride.Shaders.Parsing.Experiments.csproj | 14 ++--- .../ParsingTests.cs | 7 +++ .../Stride.Shaders.Parsing.Tests.csproj | 9 +-- .../PreProcessing/MacroPreProcessor.cs | 63 +++++++++++++++++++ .../Stride.Shaders.Parsing.csproj | 4 ++ 8 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs diff --git a/assets/SDSL/Macroed.sdsl b/assets/SDSL/Macroed.sdsl index 3c90513173..86bd9f65e2 100644 --- a/assets/SDSL/Macroed.sdsl +++ b/assets/SDSL/Macroed.sdsl @@ -1,4 +1,10 @@ #ifdef cond -machin +shader Machin +{ + +} #endif -machin2 \ No newline at end of file +shader Machin2 +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 757c3244fc..091daa1e34 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -90,4 +90,26 @@ public static void ParseSDSL() Console.WriteLine(e); } } + + public static void TryAllFiles() + { + foreach(var f in Directory.EnumerateFiles("./assets/Stride/SDSL")) + { + // var text = File.ReadAllText(f); + var preprocessed = MonoGamePreProcessor.Run(f, []); + Console.WriteLine(preprocessed); + var parsed = SDSLParser.Parse(preprocessed); + if(parsed.Errors.Count > 0) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(f); + } + else + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine(f); + } + } + Console.ForegroundColor = ConsoleColor.White; + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 65fb06dce7..6cd64c0ad0 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -1,17 +1,8 @@ -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; - -using Silk.NET.Direct3D.Compilers; -using Silk.NET.SPIRV.Cross; -using Silk.NET.Core.Native; -using System.Text; -using Stride.Shaders.Compilers; -using Stride.Shaders.Experiments; - -Console.WriteLine("Hello world"); -Console.WriteLine(Directory.GetCurrentDirectory()); +using Stride.Shaders.Experiments; // Examples.SpvOpt(); // Examples.TranslateHLSL(); -Examples.ParseSDSL(); \ No newline at end of file +// Examples.ParseSDSL(); + +Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj index bae2639338..28a67c6f41 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj +++ b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj @@ -1,8 +1,6 @@  - - - + Exe @@ -13,10 +11,12 @@ - + + + + + + diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs index d99abe63e4..8ba8e3fe4b 100644 --- a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs +++ b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs @@ -9,6 +9,13 @@ public void Test1(string path) var shader = File.ReadAllText(path); Assert.True(shader.Length > 0); } + [Theory] + [InlineData("assets/Stride/Commented.sdsl")] + public void TestMacro(string path) + { + var shader = File.ReadAllText(path); + Assert.True(shader.Length > 0); + } [Fact] public void Test2() diff --git a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj index 7348bce756..7e8e53618c 100644 --- a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -18,10 +18,11 @@ - + + + + +
diff --git a/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs b/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs new file mode 100644 index 0000000000..240ab28b11 --- /dev/null +++ b/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs @@ -0,0 +1,63 @@ +using System.Text; +using CppNet; + +namespace Stride.Shaders.Parsing; + +public static class MonoGamePreProcessor +{ public static string Run(string filepath, ReadOnlySpan<(string Name, string Definition)> defines) + { + var file = File.ReadAllText(filepath); + var filename = Path.GetFileName(filepath); + var cpp = new Preprocessor(); + cpp.addFeature(Feature.DIGRAPHS); + cpp.addWarning(Warning.IMPORT); + cpp.addFeature(Feature.INCLUDENEXT); + // cpp.addFeature(Feature.LINEMARKERS); + + // Pass defines + if (defines != null) + { + foreach (var (Name, Definition) in defines) + { + if (!string.IsNullOrWhiteSpace(Name)) + { + cpp.addMacro(Name, Definition ?? string.Empty); + } + } + } + var inputSource = new StringLexerSource(file, true, filename); + + cpp.addInput(inputSource); + + var textBuilder = new StringBuilder(); + + var isEndOfStream = false; + while (!isEndOfStream) + { + Token tok = cpp.token(); + switch (tok.getType()) + { + case Token.EOF: + isEndOfStream = true; + break; + case Token.CCOMMENT: + var strComment = tok.getText() ?? string.Empty; + foreach (var commentChar in strComment) + { + textBuilder.Append(commentChar == '\n' ? '\n' : ' '); + } + break; + case Token.CPPCOMMENT: + break; + default: + var tokenText = tok.getText(); + if (tokenText != null) + { + textBuilder.Append(tokenText); + } + break; + } + } + return textBuilder.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index 9849751c5c..0748def73b 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -10,4 +10,8 @@ + + + + From 7a4fc2f89bdc5cddc0930f48be5003c4261ac373 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 20 Oct 2024 12:43:39 +0200 Subject: [PATCH 0336/1182] working on error messaging --- src/Stride.Shaders.Parsing/Grammar.cs | 4 +-- src/Stride.Shaders.Parsing/ParseResult.cs | 29 +++++++++++++++++-- .../SDFX/Parsers/EffectParser.cs | 4 +-- .../SDFX/Parsers/ParamsParsers.cs | 6 ++-- .../DirectiveBinaryParsers.cs | 4 +-- .../DirectiveExpressions/DirectiveParsers.cs | 6 ++-- .../DirectivePrimaryExpressionParsers.cs | 4 +-- .../DirectiveUnaryParsers.Postfix.cs | 8 ++--- .../DirectiveUnaryParsers.Prefix.cs | 16 +++++----- .../ExpressionParsers/BinaryParsers.cs | 24 +++++++-------- .../PrimaryExpressionParsers.cs | 4 +-- .../ExpressionParsers/UnaryParsers.Postfix.cs | 8 ++--- .../ExpressionParsers/UnaryParsers.Prefix.cs | 8 ++--- .../Parsers/LiteralParsers/LiteralParsers.cs | 22 +++++++------- .../Parsers/LiteralParsers/NumberParsers.cs | 2 +- .../ShaderParsers/CompositionParsers.cs | 6 ++-- .../ShaderParsers/ShaderAttributeParsers.cs | 4 +-- .../ShaderParsers/ShaderBufferParsers.Cs | 6 ++-- .../ShaderParsers/ShaderClassParser.cs | 18 ++++++------ .../ShaderParsers/ShaderDataParsers.cs | 8 ++--- .../ShaderParsers/ShaderFileParsers.cs | 4 +-- .../ShaderParsers/ShaderMethodParsers.cs | 12 ++++---- .../Parsers/ShaderParsers/ShaderParameters.cs | 4 +-- .../StatementParsers.Control.cs | 16 +++++----- .../StatementParsers/StatementParsers.Flow.cs | 28 +++++++++--------- .../StatementParsers/StatementParsers.cs | 12 ++++---- src/Stride.Shaders.Parsing/SDSLERR.cs | 11 +++++++ .../Scanners/ErrorLocation.cs | 22 ++++++-------- .../Scanners/IScanner.cs | 2 +- .../Scanners/Scanner.cs | 2 +- .../Scanners/ScannerGeneric.cs | 2 +- 31 files changed, 169 insertions(+), 137 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSLERR.cs diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs index 483eec7a48..5c8269841e 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders.Parsing/Grammar.cs @@ -15,7 +15,7 @@ public static ParseResult Match(string code, TParser? parser = if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new("Expected end of file", scanner.CreateError(scanner.Position))); + result.Errors.Add(new("Expected end of file", scanner.GetErrorLocation(scanner.Position))); return result; } @@ -31,7 +31,7 @@ public static ParseResult Match(TScannable code, TP if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new("Expected end of file", scanner.CreateError(scanner.Position))); + result.Errors.Add(new("Expected end of file", scanner.GetErrorLocation(scanner.Position))); return result; } diff --git a/src/Stride.Shaders.Parsing/ParseResult.cs b/src/Stride.Shaders.Parsing/ParseResult.cs index 967332acfa..0e4d93792e 100644 --- a/src/Stride.Shaders.Parsing/ParseResult.cs +++ b/src/Stride.Shaders.Parsing/ParseResult.cs @@ -3,11 +3,36 @@ namespace Stride.Shaders.Parsing; -public record struct ParseError(string Message, ErrorLocation Location) +public record struct ParseError(string Message, ErrorLocation Location, ReadOnlyMemory Code) { + + readonly ReadOnlySpan GetNextToken() + { + ReadOnlySpan operators = ['+', '-', '*', '/', '%', '=', '!', '<', '>', '&', '|', '^', '~', '?', ':']; + var pos = Location.Position; + if(operators.Contains(Code.Span[pos])) + { + while(operators.Contains(Code.Span[pos])) + pos++; + return Code.Span[Location.Position..pos]; + } + else if(char.IsDigit(Code.Span[pos])) + { + while(char.IsDigit(Code.Span[pos])) + pos++; + return Code.Span[Location.Position..pos]; + } + else if(char.IsLetter(Code.Span[pos]) || Code.Span[pos] == '_' ) + { + while(char.IsLetterOrDigit(Code.Span[pos]) || Code.Span[pos] == '_') + pos++; + return Code.Span[Location.Position..pos]; + } + else return Code.Span[Location.Position..(Location.Position+1)]; + } public override readonly string ToString() { - return $"{Message} at : {Location}"; + return $"{Location} {Message} : {GetNextToken()}"; } } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index 472cae5fca..1e0844f520 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -25,10 +25,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed.Members.Add(s); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement here", scanner.GetErrorLocation(scanner.Position))); } if(scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement or end of block", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement or end of block", scanner.GetErrorLocation(scanner.Position))); else if(Terminals.Char('}', ref scanner, advance: true)) { parsed.Info = scanner.GetLocation(position..scanner.Position); diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index 96654c4631..c919b41d7d 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -28,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else - CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected parameter definition or closing curly brace", scanner.CreateError(scanner.Position))); + CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected parameter definition or closing curly brace", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); } } @@ -58,7 +58,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (ExpressionParser.Expression(ref scanner, result, out var expression) && CommonParsers.Spaces0(ref scanner, result, out _)) { if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(scanner.Position))); parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), expression); return true; } @@ -68,7 +68,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("expected assignment or semi colon", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("expected assignment or semi colon", scanner.GetErrorLocation(scanner.Position))); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index d8aa841b66..a103d30275 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -66,11 +66,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('?', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.CreateError(scanner.Position))) + && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(':', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.CreateError(scanner.Position))) + && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) ) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index ac545c8985..013dfb7f9e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -204,8 +204,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( Terminals.Literal("#ifdef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new("missing space", scanner.CreateError(scanner.Position))) - && LiteralsParser.Identifier(ref scanner, result, out var id, new("needs identifier", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new("missing space", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var id, new("needs identifier", scanner.GetErrorLocation(scanner.Position))) && Terminals.EOL(ref scanner, advance: true) ) { @@ -431,7 +431,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o func.Parameters.Add(param); if(!Terminals.Char(')', ref scanner, advance: true)) { - result.Errors.Add(new("Parenthesis needs to be closed", scanner.CreateError(scanner.Position))); + result.Errors.Add(new("Parenthesis needs to be closed", scanner.GetErrorLocation(scanner.Position))); scanner.Position = position; parsed = null!; return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index 5252553678..224089b793 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.CreateError(position))) + && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.GetErrorLocation(position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs index 20bf7c9384..268e7b035a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs @@ -60,7 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new("Expected Postfix expression", scanner.CreateError(position))); + result.Errors.Add(new("Expected Postfix expression", scanner.GetErrorLocation(position))); return false; } } @@ -102,7 +102,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.CreateError(scanner.Position)))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.GetErrorLocation(scanner.Position)))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.CreateError(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -146,7 +146,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new("Expected accessor parser", scanner.CreateError(position))); + result.Errors.Add(new("Expected accessor parser", scanner.GetErrorLocation(position))); parsed = null!; return false; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 6ec1f723ed..35ed9598bd 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); return false; } } @@ -70,7 +70,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); return false; } } @@ -106,14 +106,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.CreateError(position))); + result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); return false; } } else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); return false; } } @@ -140,7 +140,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { // TODO: check if error can be added here if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); parsed = null!; scanner.Position = position; return false; @@ -149,7 +149,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); return false; } } @@ -164,7 +164,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) @@ -176,7 +176,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.CreateError(position) }); + result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); parsed = null!; scanner.Position = position; return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index a71d252852..6d68eedf9c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -66,13 +66,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.CreateError(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.GetErrorLocation(scanner.Position)))) { CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(':', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.CreateError(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.GetErrorLocation(scanner.Position)))) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -105,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.And(ref scanner, result, out var and)) parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AndExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AndExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BOr(ref scanner, result, out var bOr)) parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseOrExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseOrExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.XOr(ref scanner, result, out var xor)) parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting XorExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting XorExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -197,7 +197,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseAndExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseAndExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -227,7 +227,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting EqualityExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting EqualityExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -260,7 +260,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Relation(ref scanner, result, out var rel)) parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting RelationExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting RelationExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -291,7 +291,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Shift(ref scanner, result, out var shift)) parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting ShiftExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting ShiftExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -322,7 +322,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Add(ref scanner, result, out var add)) parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AddExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AddExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == "") { @@ -353,7 +353,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Mul(ref scanner, result, out var mul)) parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == '\0') { @@ -384,7 +384,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.GetErrorLocation(scanner.Position))); } else if (parsed is null && op == '\0') { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 743bf2856f..3b7f13ee07 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.CreateError(position))) + && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.GetErrorLocation(position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -76,7 +76,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 05de4b8189..986209235a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -49,7 +49,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Postfix expression", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Postfix expression", scanner.GetErrorLocation(position))); } else return true; @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.CreateError(scanner.Position)))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.GetErrorLocation(scanner.Position)))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.CreateError(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -123,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected accessor parser", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected accessor parser", scanner.GetErrorLocation(position))); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 6aeca13661..eb7bc69817 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -42,7 +42,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); } // prefix decrememnt else if (Terminals.Literal("--", ref scanner, advance: true)) @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -77,7 +77,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && UnaryParsers.Postfix(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 924d546379..818e540e0d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -65,11 +65,11 @@ public static bool AssignOperators(ref TScanner scanner, ParseResult r where TScanner : struct, IScanner { op = AssignOperator.NOp; - if( + if ( Terminals.AnyOf( - ["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="], - ref scanner, - out var matched, + ["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="], + ref scanner, + out var matched, advance: true ) ) @@ -247,7 +247,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var tnPos = scanner.Position; int size = scanner.Span[scanner.Position - 1] - '0'; if (size < 2 || size > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {size}", scanner.CreateError(scanner.Position - 1))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { @@ -269,9 +269,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); if (p.Values.Count != size && p.Values.Count > size) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {size}", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = p; return true; } @@ -298,7 +298,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o int rows = scanner.Span[scanner.Position - 3] - '0'; int cols = scanner.Span[scanner.Position - 1] - '0'; if (cols < 2 || cols > 4 || rows < 2 || rows > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {rows}x{cols}", scanner.CreateError(scanner.Position - 1))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {rows}x{cols}", scanner.GetErrorLocation(scanner.Position - 1))); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { @@ -311,7 +311,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (LiteralsParser.Number(ref scanner, result, out var number)) p.Values.Add(number); - else if (LiteralsParser.Vector(ref scanner, result, out var vector, new("Expecting number or vector value", scanner.CreateError(scanner.Position)))) + else if (LiteralsParser.Vector(ref scanner, result, out var vector, new("Expecting number or vector value", scanner.GetErrorLocation(scanner.Position)))) p.Values.Add(vector); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); CommonParsers.Spaces0(ref scanner, result, out _); @@ -321,9 +321,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.GetErrorLocation(scanner.Position))); if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {rows}x{cols}", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {rows}x{cols}", scanner.GetErrorLocation(scanner.Position))); parsed = p; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 2c249de7db..864457d280 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -132,7 +132,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var add = v * Math.Pow(16, i); if (ulong.MaxValue - sum < add) { - result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.CreateError(position))); + result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.GetErrorLocation(position))); return false; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 66f5861a6a..64fd3e8076 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -14,16 +14,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.GetErrorLocation(scanner.Position))) ) { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(position))); parsed = new(identifier, mixin, scanner.GetLocation(position..)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Mixin variable", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Mixin variable", scanner.GetErrorLocation(scanner.Position))); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs index ee0259ea81..30fe709266 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -56,11 +56,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..), values.Values); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.GetErrorLocation(position))); } CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(']', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end attribute", scanner.CreateError(position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end attribute", scanner.GetErrorLocation(position))); parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..)); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index c6522739e4..bc75a4ca80 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -47,7 +47,7 @@ public record struct CBufferParser : IParser if (Terminals.Literal("cbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -85,7 +85,7 @@ public record struct TBufferParser : IParser if (Terminals.Literal("tbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -143,7 +143,7 @@ public record struct BufferMemberParser : IParser { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.CreateError(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 96a2b4596d..6b82e76584 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -37,8 +37,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("shader", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) - && LiteralsParser.Identifier(ref scanner, result, out var className, new("Expected class name", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var className, new("Expected class name", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) @@ -72,7 +72,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Literal("shader ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.CreateError(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -82,7 +82,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ParameterParsers.Declarations(ref scanner, result, out var generics); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.GetErrorLocation(scanner.Position))); parsed.Generics = generics; CommonParsers.Spaces0(ref scanner, result, out _); } @@ -99,7 +99,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (parsed.Mixins.Count == 0) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); } if (Terminals.Char('{', ref scanner, advance: true) @@ -120,7 +120,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.GetErrorLocation(position))); } } @@ -141,11 +141,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) { - ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.CreateError(position))); + ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.GetErrorLocation(position))); parsed.Generics = values; CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.GetErrorLocation(scanner.Position))); return true; } else @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 9eaa0018b9..0f31fb2f53 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -31,20 +31,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.CreateError(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) { if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) { CommonParsers.Until(ref scanner, ':', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new("Expected semantic here", scanner.CreateError(scanner.Position)))) + if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new("Expected semantic here", scanner.GetErrorLocation(scanner.Position)))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position))); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -79,7 +79,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing bracket", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing bracket", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index f1d223a209..ccd942d50e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -72,7 +72,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected identifier", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); } @@ -97,7 +97,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); else - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class or effect", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class or effect", scanner.GetErrorLocation(scanner.Position))); } } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 6c57b74a57..a59495a16d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -40,14 +40,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) && LiteralsParser.Identifier(ref scanner, result, out var methodName) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && ShaderMethodParsers.Parameters(ref scanner, result, out var parameters) && Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Block(ref scanner, result, out var body, new("Expected Body declaration", scanner.CreateError(scanner.Position))) + && StatementParsers.Block(ref scanner, result, out var body, new("Expected Body declaration", scanner.GetErrorLocation(scanner.Position))) ) { parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) @@ -72,9 +72,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Literal("abstract", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new("Expected type name here", scanner.CreateError(scanner.Position))) + LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new("Expected type name here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new("Expected method name here", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new("Expected method name here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -83,13 +83,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ShaderMethodParsers.Parameters(ref scanner, result, out var parameters); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(')', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closed parenthesis", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closed parenthesis", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) { if (orError != null) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(scanner.Position))); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 486878bde5..b95491c837 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -71,7 +71,7 @@ public record struct GenericsListParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.CreateError(scanner.Position)))) + if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position)))) { parsed = new(scanner.GetLocation(position..scanner.Position)); parsed.Values.Add(parameter); @@ -79,7 +79,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (Terminals.Char(',', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.CreateError(scanner.Position)))) + if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position)))) { parsed.Values.Add(other); CommonParsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 7039204788..f27a035fa8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -21,7 +21,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else if(Terminals.Literal("else ", ref scanner)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.CreateError(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position))); return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -49,19 +49,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.CreateError(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position)))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -80,19 +80,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.CreateError(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position)))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -107,7 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("else", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.CreateError(scanner.Position))) + && StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position))) ) { parsed = new(statement, scanner.GetLocation(position..scanner.Position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index ba73f40230..a9856185c8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -62,14 +62,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if(StatementParsers.Assignments(ref scanner, result, out init)){} else if(StatementParsers.Declare(ref scanner, result, out init)){} else if(StatementParsers.Empty(ref scanner, result, out init)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected initializer", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected initializer", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (StatementParsers.Expression(ref scanner, result, out condition)){} else if (StatementParsers.Empty(ref scanner, result, out condition)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected condition expression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected condition expression", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); // parsing the final expression @@ -81,7 +81,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { expression = new ExpressionStatement(exp, exp.Info); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end expression", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end expression", scanner.GetErrorLocation(scanner.Position))); CommonParsers.Spaces0(ref scanner, result, out _); @@ -109,34 +109,34 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new("Expected type definition here", scanner.CreateError(scanner.Position))) + LiteralsParser.TypeName(ref scanner, result, out var typeName, new("Expected type definition here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.CreateError(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces1(ref scanner, result, out _) ) { if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new("Expected variable name or collection name here", scanner.CreateError(scanner.Position))) + ExpressionParser.Expression(ref scanner, result, out var collection, new("Expected variable name or collection name here", scanner.GetErrorLocation(scanner.Position))) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.CreateError(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.GetErrorLocation(scanner.Position)))) { parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.GetErrorLocation(scanner.Position))); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected keyword in here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected keyword in here", scanner.GetErrorLocation(scanner.Position))); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -152,20 +152,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new("Expected expression here", scanner.CreateError(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.CreateError(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.GetErrorLocation(scanner.Position)))) { parsed = new(expression, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.GetErrorLocation(scanner.Position))); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.GetErrorLocation(scanner.Position))); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 3944e5c4b8..00ec435192 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -107,7 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if ( Terminals.Literal("return", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.CreateError(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) ) { if (Terminals.Char(';', ref scanner, advance: true)) @@ -124,7 +124,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new Return(scanner.GetLocation(position, scanner.Position - position), val); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected value or \";\"", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected value or \";\"", scanner.GetErrorLocation(scanner.Position))); } @@ -208,7 +208,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o block.Statements.Add(statement); CommonParsers.Spaces0(ref scanner, result, out _); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Statement", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Statement", scanner.GetErrorLocation(scanner.Position))); } block.Info = scanner.GetLocation(position, scanner.Position - position); parsed = block; @@ -243,7 +243,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(identifier, scanner.GetLocation(position..scanner.Position), op, expression); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected expression here", scanner.CreateError(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected expression here", scanner.GetErrorLocation(position))); } else { @@ -280,7 +280,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.GetErrorLocation(scanner.Position))); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -304,7 +304,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.CreateError(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.GetErrorLocation(scanner.Position))); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders.Parsing/SDSLERR.cs new file mode 100644 index 0000000000..e415e67341 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSLERR.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Parsing; + + +public static class SDSLErrors +{ + public const string SDSL0001 = "SDSL0001: Unexpected token"; + public const string SDSL0002 = "SDSL0002: vector size not supported"; + public const string SDSL0003 = "SDSL0003: matrix size not supported"; + public const string SDSL0004 = "Unfinished vector declaration"; + public const string SDSL0005 = "Too many values"; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs index ad17e371f0..0f75c11ce4 100644 --- a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs +++ b/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs @@ -4,51 +4,47 @@ namespace Stride.Shaders.Parsing; public struct ErrorLocation { - public ReadOnlyMemory Text { get; private set; } public int Position { get; private set; } private int leftOffset; private int rightOffset; - private int line; - private int column; + public int Line { get; private set;} + public int Column { get; private set;} public ErrorLocation(Scanner scanner, int position) { // Getting the line and column at the position given. // TODO: Make this a function in scanner var pos = scanner.Position; scanner.Position = position; - line = scanner.Line; - column = scanner.Column; + Line = scanner.Line; + Column = scanner.Column; scanner.Position = pos; // Setting other attributes leftOffset = Math.Max(0, position - 5); rightOffset = Math.Min(scanner.Memory.Length, position); Position = position; - - Text = scanner.Memory; } - + public static ErrorLocation Create(Scanner scanner, int position) where TScannable : IScannableCode { var error = new ErrorLocation(); var pos = scanner.Position; scanner.Position = position; - error.line = scanner.Line; - error.column = scanner.Column; + error.Line = scanner.Line; + error.Column = scanner.Column; scanner.Position = pos; // Setting other attributes error.leftOffset = Math.Max(0, position - 5); error.rightOffset = Math.Min(scanner.Memory.Length, position); error.Position = position; - error.Text = scanner.Memory; return error; } - public readonly override string ToString() + public override readonly string ToString() { - return $"l{line}-c{column} : \n{Text[leftOffset..Position]}>>>{Text[Position..]}"; + return $"[{Line}, {Column}]"; } } diff --git a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs index 5bb6c8f965..17ce4a6abe 100644 --- a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs +++ b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs @@ -37,7 +37,7 @@ public interface IScanner public TextLocation GetLocation(int position, int length); public TextLocation GetLocation(Range range); - public ErrorLocation CreateError(int position); + public ErrorLocation GetErrorLocation(int position); } diff --git a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs index f1a9a8d8c8..6992cb298c 100644 --- a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs +++ b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs @@ -106,7 +106,7 @@ public readonly TextLocation GetLocation(int position, int length) { return new(Memory, new(position, position + length)); } - public readonly ErrorLocation CreateError(int position) + public readonly ErrorLocation GetErrorLocation(int position) { return new ErrorLocation(this, position); } diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs index 37137c5997..e1c4f0681f 100644 --- a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs +++ b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs @@ -106,7 +106,7 @@ public readonly TextLocation GetLocation(int position, int length) return new(Memory, new(position, position + length)); } - public readonly ErrorLocation CreateError(int position) + public readonly ErrorLocation GetErrorLocation(int position) { return ErrorLocation.Create(this, position); } From 0b99c0d4af51c6a0bef5c465b22f17398a23bdd5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 21 Oct 2024 01:06:35 +0200 Subject: [PATCH 0337/1182] refactoring errors --- .../Examples.cs | 2 + src/Stride.Shaders.Parsing/Grammar.cs | 4 +- .../SDFX/Parsers/EffectParser.cs | 4 +- .../SDFX/Parsers/ParamsParsers.cs | 6 +-- .../DirectiveBinaryParsers.cs | 4 +- .../DirectiveExpressions/DirectiveParsers.cs | 6 +-- .../DirectivePrimaryExpressionParsers.cs | 4 +- .../DirectiveUnaryParsers.Postfix.cs | 8 ++-- .../DirectiveUnaryParsers.Prefix.cs | 8 ++-- .../ExpressionParsers/BinaryParsers.cs | 24 +++++------ .../PrimaryExpressionParsers.cs | 4 +- .../ExpressionParsers/UnaryParsers.Postfix.cs | 8 ++-- .../ExpressionParsers/UnaryParsers.Prefix.cs | 8 ++-- .../Parsers/LiteralParsers/LiteralParsers.cs | 8 ++-- .../Parsers/LiteralParsers/NumberParsers.cs | 2 +- .../ShaderParsers/CompositionParsers.cs | 6 +-- .../ShaderParsers/ShaderAttributeParsers.cs | 4 +- .../ShaderParsers/ShaderBufferParsers.Cs | 6 +-- .../ShaderParsers/ShaderClassParser.cs | 18 ++++---- .../ShaderParsers/ShaderDataParsers.cs | 8 ++-- .../ShaderParsers/ShaderFileParsers.cs | 4 +- .../ShaderParsers/ShaderMethodParsers.cs | 12 +++--- .../Parsers/ShaderParsers/ShaderParameters.cs | 4 +- .../StatementParsers.Control.cs | 16 +++---- .../StatementParsers/StatementParsers.Flow.cs | 28 ++++++------- .../StatementParsers/StatementParsers.cs | 12 +++--- src/Stride.Shaders.Parsing/SDSLERR.cs | 42 ++++++++++++++++++- 27 files changed, 150 insertions(+), 110 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 091daa1e34..308b42a58e 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -102,6 +102,7 @@ public static void TryAllFiles() if(parsed.Errors.Count > 0) { Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(string.Join("; ", parsed.Errors.Select(x => x.ToString()))); Console.WriteLine(f); } else @@ -109,6 +110,7 @@ public static void TryAllFiles() Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(f); } + break; } Console.ForegroundColor = ConsoleColor.White; } diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs index 5c8269841e..f0145784ec 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders.Parsing/Grammar.cs @@ -15,7 +15,7 @@ public static ParseResult Match(string code, TParser? parser = if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new("Expected end of file", scanner.GetErrorLocation(scanner.Position))); + result.Errors.Add(new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return result; } @@ -31,7 +31,7 @@ public static ParseResult Match(TScannable code, TP if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new("Expected end of file", scanner.GetErrorLocation(scanner.Position))); + result.Errors.Add(new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return result; } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index 1e0844f520..856d03c3ce 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -25,10 +25,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed.Members.Add(s); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } if(scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected statement or end of block", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0011, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); else if(Terminals.Char('}', ref scanner, advance: true)) { parsed.Info = scanner.GetLocation(position..scanner.Position); diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index c919b41d7d..9f95f72473 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -28,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else - CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected parameter definition or closing curly brace", scanner.GetErrorLocation(scanner.Position))); + CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0012, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); } } @@ -58,7 +58,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (ExpressionParser.Expression(ref scanner, result, out var expression) && CommonParsers.Spaces0(ref scanner, result, out _)) { if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), expression); return true; } @@ -68,7 +68,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("expected assignment or semi colon", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0014, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index a103d30275..ea28a35f6d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -66,11 +66,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('?', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) + && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(':', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) + && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index 013dfb7f9e..6e41f614a3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -204,8 +204,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( Terminals.Literal("#ifdef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new("missing space", scanner.GetErrorLocation(scanner.Position))) - && LiteralsParser.Identifier(ref scanner, result, out var id, new("needs identifier", scanner.GetErrorLocation(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var id, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && Terminals.EOL(ref scanner, advance: true) ) { @@ -431,7 +431,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o func.Parameters.Add(param); if(!Terminals.Char(')', ref scanner, advance: true)) { - result.Errors.Add(new("Parenthesis needs to be closed", scanner.GetErrorLocation(scanner.Position))); + result.Errors.Add(new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); scanner.Position = position; parsed = null!; return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index 224089b793..128f0ba5ab 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.GetErrorLocation(position))) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs index 268e7b035a..2827f5088a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs @@ -60,7 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new("Expected Postfix expression", scanner.GetErrorLocation(position))); + result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -102,7 +102,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.GetErrorLocation(scanner.Position)))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -146,7 +146,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new("Expected accessor parser", scanner.GetErrorLocation(position))); + result.Errors.Add(new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); parsed = null!; return false; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 35ed9598bd..0ea66ee45c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -70,7 +70,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -106,7 +106,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -164,7 +164,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 6d68eedf9c..a33681b676 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -66,13 +66,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var left, new("Expected expression", scanner.GetErrorLocation(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var left, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(':', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var right, new("Expected expression", scanner.GetErrorLocation(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var right, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -105,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.And(ref scanner, result, out var and)) parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AndExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0022, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BOr(ref scanner, result, out var bOr)) parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseOrExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.XOr(ref scanner, result, out var xor)) parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting XorExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0025, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -197,7 +197,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting BitwiseAndExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0026, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -227,7 +227,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting EqualityExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0027, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -260,7 +260,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Relation(ref scanner, result, out var rel)) parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting RelationExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0028, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -291,7 +291,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Shift(ref scanner, result, out var shift)) parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting ShiftExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0029, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -322,7 +322,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Add(ref scanner, result, out var add)) parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting AddExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0030, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -353,7 +353,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Mul(ref scanner, result, out var mul)) parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0031, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == '\0') { @@ -384,7 +384,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting MulExpression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0042, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == '\0') { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 3b7f13ee07..02ec4f6920 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new("Expected expression value", scanner.GetErrorLocation(position))) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -76,7 +76,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 986209235a..c07869061d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -49,7 +49,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Postfix expression", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return true; @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new("Expected accessor expression", scanner.GetErrorLocation(scanner.Position)))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLErrors.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new("Expected expression", scanner.GetErrorLocation(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -123,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected accessor parser", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index eb7bc69817..0f543cd215 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -42,7 +42,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } // prefix decrememnt else if (Terminals.Literal("--", ref scanner, advance: true)) @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -77,7 +77,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting Postfix expression", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && UnaryParsers.Postfix(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 818e540e0d..4317fb07ba 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -298,7 +298,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o int rows = scanner.Span[scanner.Position - 3] - '0'; int cols = scanner.Span[scanner.Position - 1] - '0'; if (cols < 2 || cols > 4 || rows < 2 || rows > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"A vector cannot be of size {rows}x{cols}", scanner.GetErrorLocation(scanner.Position - 1))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0006, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { @@ -311,7 +311,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (LiteralsParser.Number(ref scanner, result, out var number)) p.Values.Add(number); - else if (LiteralsParser.Vector(ref scanner, result, out var vector, new("Expecting number or vector value", scanner.GetErrorLocation(scanner.Position)))) + else if (LiteralsParser.Vector(ref scanner, result, out var vector, new(SDSLErrors.SDSL0007, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) p.Values.Add(vector); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); CommonParsers.Spaces0(ref scanner, result, out _); @@ -321,9 +321,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Unfinished vector declaration", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0008, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new($"Too many values for vector of size {rows}x{cols}", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0002, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = p; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 864457d280..b48f946a1f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -132,7 +132,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var add = v * Math.Pow(16, i); if (ulong.MaxValue - sum < add) { - result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.GetErrorLocation(position))); + result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.GetErrorLocation(position), scanner.Memory)); return false; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 64fd3e8076..cb2222d298 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -14,16 +14,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); parsed = new(identifier, mixin, scanner.GetLocation(position..)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Mixin variable", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs index 30fe709266..c2ed543a3f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -56,11 +56,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..), values.Values); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.GetErrorLocation(position), scanner.Memory)); } CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(']', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end attribute", scanner.GetErrorLocation(position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0019, scanner.GetErrorLocation(position), scanner.Memory)); parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..)); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index bc75a4ca80..fe2d671970 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -47,7 +47,7 @@ public record struct CBufferParser : IParser if (Terminals.Literal("cbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -85,7 +85,7 @@ public record struct TBufferParser : IParser if (Terminals.Literal("tbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -143,7 +143,7 @@ public record struct BufferMemberParser : IParser { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 6b82e76584..ba7cf76483 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -37,8 +37,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("shader", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) - && LiteralsParser.Identifier(ref scanner, result, out var className, new("Expected class name", scanner.GetErrorLocation(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var className, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) @@ -72,7 +72,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Literal("shader ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected identifier here", scanner.GetErrorLocation(scanner.Position))) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -82,7 +82,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ParameterParsers.Declarations(ref scanner, result, out var generics); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed.Generics = generics; CommonParsers.Spaces0(ref scanner, result, out _); } @@ -99,7 +99,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (parsed.Mixins.Count == 0) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); } if (Terminals.Char('{', ref scanner, advance: true) @@ -120,7 +120,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.GetErrorLocation(position), scanner.Memory)); } } @@ -141,11 +141,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) { - ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.GetErrorLocation(position))); + ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.GetErrorLocation(position), scanner.Memory)); parsed.Generics = values; CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing chevron", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return true; } else @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 0f31fb2f53..7975e56fc7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -31,20 +31,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) { CommonParsers.Until(ref scanner, ':', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new("Expected semantic here", scanner.GetErrorLocation(scanner.Position)))) + if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -79,7 +79,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing bracket", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index ccd942d50e..704a2b2e4e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -72,7 +72,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected identifier", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); } @@ -97,7 +97,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); else - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected shader class or effect", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0039, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index a59495a16d..ad499cb586 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -40,14 +40,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && ShaderMethodParsers.Parameters(ref scanner, result, out var parameters) && Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Block(ref scanner, result, out var body, new("Expected Body declaration", scanner.GetErrorLocation(scanner.Position))) + && StatementParsers.Block(ref scanner, result, out var body, new(SDSLErrors.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) @@ -72,9 +72,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Literal("abstract", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new("Expected type name here", scanner.GetErrorLocation(scanner.Position))) + LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new("Expected method name here", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -83,13 +83,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ShaderMethodParsers.Parameters(ref scanner, result, out var parameters); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(')', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closed parenthesis", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) { if (orError != null) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index b95491c837..8226fd370e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -71,7 +71,7 @@ public record struct GenericsListParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position)))) + if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(scanner.GetLocation(position..scanner.Position)); parsed.Values.Add(parameter); @@ -79,7 +79,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (Terminals.Char(',', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position)))) + if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed.Values.Add(other); CommonParsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index f27a035fa8..857ad8258d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -21,7 +21,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else if(Terminals.Literal("else ", ref scanner)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position))); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -49,19 +49,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.GetErrorLocation(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -80,19 +80,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new("Expected expression here", scanner.GetErrorLocation(scanner.Position))) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -107,7 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("else", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement here", scanner.GetErrorLocation(scanner.Position))) + && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new(statement, scanner.GetLocation(position..scanner.Position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index a9856185c8..8dd3c0ead5 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -62,14 +62,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if(StatementParsers.Assignments(ref scanner, result, out init)){} else if(StatementParsers.Declare(ref scanner, result, out init)){} else if(StatementParsers.Empty(ref scanner, result, out init)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected initializer", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0036, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (StatementParsers.Expression(ref scanner, result, out condition)){} else if (StatementParsers.Empty(ref scanner, result, out condition)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected condition expression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0037, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); // parsing the final expression @@ -81,7 +81,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { expression = new ExpressionStatement(exp, exp.Info); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected end expression", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0038, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); @@ -109,34 +109,34 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new("Expected type definition here", scanner.GetErrorLocation(scanner.Position))) + LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new("Expected variable name here", scanner.GetErrorLocation(scanner.Position))) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) ) { if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new("Expected variable name or collection name here", scanner.GetErrorLocation(scanner.Position))) + ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.GetErrorLocation(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected keyword in here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -152,20 +152,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new("Expected expression here", scanner.GetErrorLocation(scanner.Position)))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new("Expected statement to be here", scanner.GetErrorLocation(scanner.Position)))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(expression, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected closing parenthesis here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected opening parenthesis here", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 00ec435192..50e4360ff6 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -107,7 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if ( Terminals.Literal("return", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new("Expected at least one space", scanner.GetErrorLocation(scanner.Position))) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { if (Terminals.Char(';', ref scanner, advance: true)) @@ -124,7 +124,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new Return(scanner.GetLocation(position, scanner.Position - position), val); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected value or \";\"", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0041, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } @@ -208,7 +208,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o block.Statements.Add(statement); CommonParsers.Spaces0(ref scanner, result, out _); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected Statement", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } block.Info = scanner.GetLocation(position, scanner.Position - position); parsed = block; @@ -243,7 +243,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(identifier, scanner.GetLocation(position..scanner.Position), op, expression); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected expression here", scanner.GetErrorLocation(position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); } else { @@ -280,7 +280,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -304,7 +304,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expected semi colon to end statement", scanner.GetErrorLocation(scanner.Position))); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders.Parsing/SDSLERR.cs index e415e67341..93c5e9a0e8 100644 --- a/src/Stride.Shaders.Parsing/SDSLERR.cs +++ b/src/Stride.Shaders.Parsing/SDSLERR.cs @@ -6,6 +6,44 @@ public static class SDSLErrors public const string SDSL0001 = "SDSL0001: Unexpected token"; public const string SDSL0002 = "SDSL0002: vector size not supported"; public const string SDSL0003 = "SDSL0003: matrix size not supported"; - public const string SDSL0004 = "Unfinished vector declaration"; - public const string SDSL0005 = "Too many values"; + public const string SDSL0004 = "SDSL0004: Unfinished vector declaration"; + public const string SDSL0005 = "SDSL0005: Too many values"; + public const string SDSL0006 = "SDSL0006: wrong vector size"; + public const string SDSL0007 = "SDSL0007: Expecting number or vector value"; + public const string SDSL0008 = "SDSL0008: Unfinished vector declaration"; + public const string SDSL0009 = "SDSL0009: Expected "; + public const string SDSL0010 = "SDSL0010: Expected statement"; + public const string SDSL0011 = "SDSL0011: Expected statement or end of block"; + public const string SDSL0012 = "SDSL0012: Expected parameter or end of block"; + public const string SDSL0013 = "SDSL0013: Expected semi colon"; + public const string SDSL0014 = "SDSL0014: Expected assignment or semi colon"; + public const string SDSL0015 = "SDSL0015: Expected expression"; + public const string SDSL0016 = "SDSL0016: Expected at least one space"; + public const string SDSL0017 = "SDSL0017: Expected identifier"; + public const string SDSL0018 = "SDSL0018: Expected closing parenthesis"; + public const string SDSL0019 = "SDSL0019: Expected closing bracket"; + public const string SDSL0020 = "SDSL0020: Expected postfix expression"; + public const string SDSL0021 = "SDSL0021: Expected accessor expression"; + public const string SDSL0022 = "SDSL0022: Expected And expression"; + public const string SDSL0023 = "SDSL0023: Expected Or expression"; + public const string SDSL0024 = "SDSL0024: Expected BitWiseOr expression"; + public const string SDSL0025 = "SDSL0025: Expected BitWiseXor expression"; + public const string SDSL0026 = "SDSL0026: Expected BitWiseAnd expression"; + public const string SDSL0027 = "SDSL0027: Expected equality expression"; + public const string SDSL0028 = "SDSL0028: Expected relational expression"; + public const string SDSL0029 = "SDSL0029: Expected shift expression"; + public const string SDSL0030 = "SDSL0030: Expected additive expression"; + public const string SDSL0031 = "SDSL0031: Expected multiplicative expression"; + public const string SDSL0032 = "SDSL0032: Expected variable name"; + public const string SDSL0033 = "SDSL0033: Expected semi colon"; + public const string SDSL0034 = "SDSL0034: Expected closing chevron"; + public const string SDSL0035 = "SDSL0035: Expected open parenthesis"; + public const string SDSL0036 = "SDSL0036: Expected initializer expression"; + public const string SDSL0037 = "SDSL0037: Expected condition expression"; + public const string SDSL0038 = "SDSL0038: Expected increment expression"; + public const string SDSL0039 = "SDSL0039: Expected shader class or effect"; + public const string SDSL0040 = "SDSL0040: Expected body declaration"; + public const string SDSL0041 = "SDSL0041: Expected expression or semi colon"; + public const string SDSL0042 = "SDSL0042: Expected prefix expression"; + } \ No newline at end of file From d2600f50719d95d99316bc21dfd66390894538b4 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 21 Oct 2024 17:02:56 +0200 Subject: [PATCH 0338/1182] parsed array of mixin --- .../Examples.cs | 2 +- .../SDSL/AST/Literals.cs | 4 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 9 +- .../SDSL/AST/Statements.cs | 8 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 12 +-- .../ShaderParsers/CompositionParsers.cs | 23 ++++- .../ShaderParsers/ShaderDataParsers.cs | 95 ++++++++++++++----- .../ShaderParsers/ShaderElementParsers.cs | 10 +- .../StatementParsers/StatementParsers.cs | 2 +- 9 files changed, 123 insertions(+), 42 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 308b42a58e..0ae5aeb78e 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -104,13 +104,13 @@ public static void TryAllFiles() Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(string.Join("; ", parsed.Errors.Select(x => x.ToString()))); Console.WriteLine(f); + break; } else { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(f); } - break; } Console.ForegroundColor = ConsoleColor.White; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index 7fa8287cc0..f88db7c617 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -94,9 +94,11 @@ public override string ToString() } } -public class TypeName(string name, TextLocation info) : Literal(info) +public class TypeName(string name, TextLocation info, bool isArray) : Literal(info) { public string Name { get; set; } = name; + public bool IsArray { get; set; } = isArray; + public Expression? ArraySize { get; set; } public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4896e40b2c..374f965c0b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,11 +7,12 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : public List Attributes { get; set; } = []; } -public class ShaderCompose(Identifier name, InheritedMixin mixin, TextLocation info) : MethodOrMember(info) +public class ShaderCompose(Identifier name, InheritedMixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) { - public Identifier Name { get; } = name; - public InheritedMixin Mixin { get; } = mixin; - public override string ToString() => $"compose {Mixin} {Name};"; + public Identifier Name { get; set; } = name; + public InheritedMixin Mixin { get; set; } = mixin; + public bool IsArray { get; set; } = isArray; + public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null) : MethodOrMember(location, isStaged) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs index 3fb272804b..5d6c33d995 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -33,17 +33,17 @@ public abstract class Declaration(TypeName typename, TextLocation info) : Statem public TypeName TypeName { get; set; } = typename; } -public class VariableAssign(Identifier name, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +public class VariableAssign(Expression variable, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) { - public Identifier Name { get; set; } = name; + public Expression Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; public Expression? Value { get; set; } = value; public override string ToString() => Value switch { - null => Name.Name, - Expression v => $"{Name} = {v}" + null => Variable.ToString() ?? "", + Expression v => $"{Variable} = {v}" }; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 4317fb07ba..7d88ecb3e8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -216,13 +216,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Terminals.Char(']', ref scanner, advance: true) ) { - name = new TypeName(scanner.Memory[position..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position)); + name = new TypeName(scanner.Memory[position..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position), isArray: true); return true; } else { scanner.Position = intermediate; - name = new(identifier.Name, scanner.GetLocation(position..scanner.Position)); + name = new(identifier.Name, scanner.GetLocation(position..scanner.Position), isArray : false); return true; } } @@ -251,9 +251,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { - var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos)), scanner.GetLocation(..)) + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) { - TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1))) + TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) }; while (!scanner.IsEof) { @@ -302,9 +302,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { - var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos)), rows, cols, scanner.GetLocation(..)) + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), rows, cols, scanner.GetLocation(..)) { - TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1))) + TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) }; while (!scanner.IsEof) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index cb2222d298..7a4b0e389e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -11,16 +11,35 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (Terminals.Literal("compose", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { + var tmp = scanner.Position; if ( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin2) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier2) + && + ( + Terminals.Literal("[]", ref scanner, advance: true) + || CommonParsers.SequenceOf(ref scanner, ["[", "]"], advance: true) + ) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (!Terminals.Char(';', ref scanner, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); + parsed = new(identifier2, mixin2, true, scanner.GetLocation(position..)); + return true; + } + scanner.Position = tmp; + if( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new(identifier, mixin, scanner.GetLocation(position..)); + parsed = new(identifier, mixin, false, scanner.GetLocation(position..)); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 7975e56fc7..427be3d1d2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -17,42 +17,93 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out Identifier name) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + if ( + LiteralsParser.Identifier(ref scanner, result, out Identifier name) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + ) { - CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position)); - return true; + if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + { + CommonParsers.Until(ref scanner, ';', advance: true); + parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position)); + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) + { + CommonParsers.Until(ref scanner, '=', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) + { + CommonParsers.Until(ref scanner, ':', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + { + parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position)); + return true; + } + } } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) + else if ( + LiteralsParser.Identifier(ref scanner, result, out Identifier name2) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('[', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out var arraySize) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + ) { - CommonParsers.Until(ref scanner, '=', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + typename.IsArray = true; + typename.ArraySize = arraySize; + if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + { + CommonParsers.Until(ref scanner, ';', advance: true); + parsed = new ShaderMember(typename, name2, null, scanner.GetLocation(position..scanner.Position)); + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) + CommonParsers.Until(ref scanner, '=', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { - CommonParsers.Until(ref scanner, ':', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) { - if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + CommonParsers.Until(ref scanner, ':', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { - parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + { + parsed = new ShaderMember(typename, name2, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + parsed = new ShaderMember(typename, name2, expression, scanner.GetLocation(position..scanner.Position)); + return true; } - parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position)); - return true; } } + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 64bcdedee6..091ee3d78b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -21,11 +21,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { + bool isOverride = false; bool isStaged = false; bool isStreamed = false; bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); var tmpPos = scanner.Position; - + if (Terminals.Literal("override", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + isOverride = true; + tmpPos = scanner.Position; + } + else + scanner.Position = tmpPos; if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { isStaged = true; @@ -48,6 +55,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (Method(ref scanner, result, out var method)) { + method.IsOverride = isOverride; method.IsStaged = isStaged; if(hasAttributes) member.Attributes = attributes.Attributes; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 50e4360ff6..d11cece434 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -225,7 +225,7 @@ public record struct VariableAssignParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + if (PostfixParser.Postfix(ref scanner, result, out var identifier)) { if ( CommonParsers.FollowedBy( From db5b6935d47d717e71b4af0d823ab299746c9e32 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 21 Oct 2024 17:37:29 +0200 Subject: [PATCH 0339/1182] error parsing --- .../SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs | 3 +++ .../SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs | 1 + 2 files changed, 4 insertions(+) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index fe2d671970..460fcb38c5 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -120,6 +120,9 @@ public record struct BufferMemberParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { + #error this doesn't parse well + bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); + CommonParsers.Spaces0(ref scanner, result, out _); var position = scanner.Position; var isStage = false; var isStream = false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 091ee3d78b..91e2e7005f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -26,6 +26,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o bool isStreamed = false; bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); var tmpPos = scanner.Position; + #warning override keyword should always happen after stage and stream if (Terminals.Literal("override", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { isOverride = true; From 588b2846d35fb05f7a08971fc019d68afcd4f3cc Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 22 Oct 2024 00:08:42 +0200 Subject: [PATCH 0340/1182] fixed vector parsing --- .../SDSL/AST/Literals.cs | 8 +-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../SDSL/Parsers/Common/CommonParsers.cs | 22 +++++- .../Parsers/LiteralParsers/LiteralParsers.cs | 5 +- .../ShaderParsers/ShaderBufferParsers.Cs | 70 ++++++++++++++----- .../ShaderParsers/ShaderDataParsers.cs | 12 ++-- src/Stride.Shaders.Parsing/SDSLERR.cs | 1 + 7 files changed, 89 insertions(+), 33 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index f88db7c617..b1bca39e2b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -47,14 +47,10 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; } -public abstract class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral(info) +public class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral(info) { public TypeName TypeName { get; set; } = typeName; -} -public class VectorLiteral(TypeName typeName, TextLocation info) : VectorLiteral(typeName, info) - where TValueLiteral : ValueLiteral -{ - public List Values { get; set; } = []; + public List Values { get; set; } = []; public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 374f965c0b..5dddcf5d66 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -15,12 +15,14 @@ public class ShaderCompose(Identifier name, InheritedMixin mixin, bool isArray, public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null) : MethodOrMember(location, isStaged) +public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, Expression? arraySize = null) : MethodOrMember(location, isStaged) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; public bool IsStream { get; set; } = isStream; + public bool IsArray { get; set; } = isArray; + public Expression? ArraySize { get; set; } = arraySize; public Expression? Value { get; set; } = initialValue; public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index ee840c707b..e006cccdef 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -43,7 +43,7 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResu return false; } + public static bool FollowedBy(ref TScanner scanner, TParser parser, ParseResult result, out TResult parsed, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + where TParser : struct, IParser + where TResult : Node + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (parser.Match(ref scanner, result, out parsed)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } + public static bool Until(ref TScanner scanner, char value, bool advance = false) where TScanner : struct, IScanner { @@ -209,7 +227,7 @@ public static bool Repeat(ref TScanner scanner, ParserValueDele if (withSpaces) Spaces0(ref scanner, result, out _); } - else if(nodes.Count >= minimum) + else if (nodes.Count >= minimum) return true; else return Exit(ref scanner, result, out nodes, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 7d88ecb3e8..68ebba82f9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -251,7 +251,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { - var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) { TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) }; @@ -262,6 +262,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o p.Values.Add(number); else if (LiteralsParser.Vector(ref scanner, result, out var vec)) p.Values.Add(vec); + else if (ExpressionParser.Expression(ref scanner, result, out var exp)) + p.Values.Add(exp); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(',', ref scanner, advance: true)) CommonParsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 460fcb38c5..1c8457dddf 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -51,24 +51,24 @@ public record struct CBufferParser : IParser && CommonParsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner)) + if (Terminals.Char('{', ref scanner, advance: true)) { List members = []; CommonParsers.Spaces0(ref scanner, result, out _); - do + while(!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) members.Add(member); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); - if (Terminals.Char('}', ref scanner, advance: true)) + if(scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) - { - Members = members - }; - return true; - } + Members = members + }; + return true; + } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -120,26 +120,62 @@ public record struct BufferMemberParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - #error this doesn't parse well - bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); CommonParsers.Spaces0(ref scanner, result, out _); var position = scanner.Position; var isStage = false; var isStream = false; + bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); + var tmp = scanner.Position; if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { isStage = true; + tmp = scanner.Position; + } else - scanner.Position = position; - if (LiteralsParser.TypeName(ref scanner, result, out var typename) + scanner.Position = tmp; + if (LiteralsParser.TypeName(ref scanner, result, out var typename1) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out Identifier name) + && LiteralsParser.Identifier(ref scanner, result, out Identifier name1) + && Terminals.Char('[', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out var arraySize) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) ) { if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) { CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position), isStage, isStream); + parsed = new ShaderMember(typename1, name1, null, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySize: arraySize); + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) + { + CommonParsers.Until(ref scanner, '=', advance: true); + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + { + parsed = new ShaderMember(typename1, name1, expression, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySize: arraySize); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + } + scanner.Position = tmp; + if (LiteralsParser.TypeName(ref scanner, result, out var typename) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out Identifier name) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + ) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + { + CommonParsers.Until(ref scanner, ';', advance: true); + parsed = new ShaderMember(typename, name, null, false, scanner.GetLocation(position..scanner.Position), isStage, isStream); return true; } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) @@ -150,7 +186,7 @@ public record struct BufferMemberParser : IParser { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { - parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), isStage, isStream); + parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position), isStage, isStream); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 427be3d1d2..f1a83156a2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -27,7 +27,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) { CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name, null, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderMember(typename, name, null, false, scanner.GetLocation(position..scanner.Position)); return true; } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) @@ -44,7 +44,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { - parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); + parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position), semantic: semantic); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); @@ -52,7 +52,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - parsed = new ShaderMember(typename, name, expression, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position)); return true; } } @@ -73,7 +73,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) { CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name2, null, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderMember(typename, name2, null, true, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); return true; } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) @@ -90,7 +90,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { - parsed = new ShaderMember(typename, name2, expression, scanner.GetLocation(position..scanner.Position), semantic: semantic); + parsed = new ShaderMember(typename, name2, expression, true, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySize: arraySize); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); @@ -98,7 +98,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - parsed = new ShaderMember(typename, name2, expression, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderMember(typename, name2, expression, true, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); return true; } } diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders.Parsing/SDSLERR.cs index 93c5e9a0e8..ac01d57b1d 100644 --- a/src/Stride.Shaders.Parsing/SDSLERR.cs +++ b/src/Stride.Shaders.Parsing/SDSLERR.cs @@ -45,5 +45,6 @@ public static class SDSLErrors public const string SDSL0040 = "SDSL0040: Expected body declaration"; public const string SDSL0041 = "SDSL0041: Expected expression or semi colon"; public const string SDSL0042 = "SDSL0042: Expected prefix expression"; + public const string SDSL0043 = "SDSL0043: Unexpected "; } \ No newline at end of file From cfca100c84fe925898ee6aa80b76da83816b01fa Mon Sep 17 00:00:00 2001 From: KAFIA Youness Date: Tue, 22 Oct 2024 17:52:33 +0200 Subject: [PATCH 0341/1182] correction on many little issues --- .../Examples.cs | 3 +- .../Program.cs | 4 +- src/Stride.Shaders.Parsing/ASTNode.cs | 5 + src/Stride.Shaders.Parsing/Grammar.cs | 4 +- src/Stride.Shaders.Parsing/IParser.cs | 2 +- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 12 +- .../SDFX/Parsers/EffectParser.cs | 4 +- .../SDFX/Parsers/ParamsParsers.cs | 6 +- src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs | 6 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../SDSL/AST/Statements.cs | 4 +- .../SDSL/Analysis/SymbolTable.cs | 2 +- .../SDSL/Parsers/Common/CommonParsers.cs | 151 ++++++++++++++++++ .../SDSL/Parsers/Common/OptionalParser.cs | 12 ++ .../DirectiveBinaryParsers.cs | 4 +- .../DirectiveExpressions/DirectiveParsers.cs | 6 +- .../DirectivePrimaryExpressionParsers.cs | 4 +- .../DirectiveUnaryParsers.Postfix.cs | 8 +- .../DirectiveUnaryParsers.Prefix.cs | 8 +- .../ExpressionParsers/BinaryParsers.cs | 28 ++-- .../PrimaryExpressionParsers.cs | 4 +- .../ExpressionParsers/UnaryParsers.Postfix.cs | 8 +- .../ExpressionParsers/UnaryParsers.Prefix.cs | 8 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 17 +- .../SDSL/Parsers/LiteralParsers/Reserved.cs | 1 + .../ShaderParsers/CompositionParsers.cs | 6 +- .../ShaderParsers/ShaderAttributeParsers.cs | 2 +- .../ShaderParsers/ShaderBufferParsers.Cs | 12 +- .../ShaderParsers/ShaderClassParser.cs | 45 +++--- .../ShaderParsers/ShaderDataParsers.cs | 97 ++--------- .../ShaderParsers/ShaderElementParsers.cs | 22 +-- .../ShaderParsers/ShaderFileParsers.cs | 7 +- .../ShaderParsers/ShaderMethodParsers.cs | 12 +- .../Parsers/ShaderParsers/ShaderParameters.cs | 5 +- .../StatementParsers.Control.cs | 19 ++- .../StatementParsers/StatementParsers.Flow.cs | 28 ++-- .../StatementParsers/StatementParsers.cs | 22 ++- src/Stride.Shaders.Parsing/SDSLERR.cs | 4 +- 38 files changed, 359 insertions(+), 237 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 0ae5aeb78e..31fb794625 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -80,7 +80,8 @@ public static void SpvOpt() public static void ParseSDSL() { - var text = File.ReadAllText("./assets/Stride/SDSL/AdditiveLightEffect.sdsl"); + // var text = File.ReadAllText("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl"); + var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl", []); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 6cd64c0ad0..c679b629a6 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -3,6 +3,6 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -// Examples.ParseSDSL(); +Examples.ParseSDSL(); -Examples.TryAllFiles(); \ No newline at end of file +// Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders.Parsing/ASTNode.cs index 5919fdb32c..0443dedcb5 100644 --- a/src/Stride.Shaders.Parsing/ASTNode.cs +++ b/src/Stride.Shaders.Parsing/ASTNode.cs @@ -12,6 +12,11 @@ public class ValueNode(TextLocation info) : Node(info) } public class NoNode() : Node(new()); +public class ListNode(TextLocation info) : Node(info) +{ + public List Nodes { get; set; } = []; +} + public abstract class ShaderDeclaration(TextLocation info) : Node(info); diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs index f0145784ec..eadcf2f303 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders.Parsing/Grammar.cs @@ -15,7 +15,7 @@ public static ParseResult Match(string code, TParser? parser = if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return result; } @@ -31,7 +31,7 @@ public static ParseResult Match(TScannable code, TP if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return result; } diff --git a/src/Stride.Shaders.Parsing/IParser.cs b/src/Stride.Shaders.Parsing/IParser.cs index 81002a4b3c..8c9fba1fb1 100644 --- a/src/Stride.Shaders.Parsing/IParser.cs +++ b/src/Stride.Shaders.Parsing/IParser.cs @@ -4,7 +4,7 @@ namespace Stride.Shaders.Parsing; public interface IParser; -public interface IParser +public interface IParser : IParser where TResult : Node { public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 672027c454..530eac1698 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -16,9 +16,9 @@ public override string ToString() public abstract class EffectStatement(TextLocation info) : Node(info); -public class MixinUse(InheritedMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinUse(Mixin mixin, TextLocation info) : EffectStatement(info) { - public InheritedMixin MixinName { get; set; } = mixin; + public Mixin MixinName { get; set; } = mixin; public override string ToString() { return $"mixin {MixinName}"; @@ -27,19 +27,19 @@ public override string ToString() public abstract class Composable(); -public class MixinCompose(Identifier identifier, InheritedMixin mixin, TextLocation info) : EffectStatement(info) +public class MixinCompose(Identifier identifier, Mixin mixin, TextLocation info) : EffectStatement(info) { public Identifier Identifier { get; set; } = identifier; - public InheritedMixin MixinName { get; set; } = mixin; + public Mixin MixinName { get; set; } = mixin; public override string ToString() { return $"mixin compose {Identifier} = {MixinName}"; } } -public class ComposeParams(InheritedMixin mixin, TextLocation info) : EffectStatement(info) +public class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) { - public InheritedMixin MixinName { get; set; } = mixin; + public Mixin MixinName { get; set; } = mixin; } public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index 856d03c3ce..208942ef71 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -25,10 +25,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed.Members.Add(s); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } if(scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0011, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0011, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); else if(Terminals.Char('}', ref scanner, advance: true)) { parsed.Info = scanner.GetLocation(position..scanner.Position); diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index 9f95f72473..e36909e188 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -28,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else - CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0012, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0012, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); } } @@ -58,7 +58,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (ExpressionParser.Expression(ref scanner, result, out var expression) && CommonParsers.Spaces0(ref scanner, result, out _)) { if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), expression); return true; } @@ -68,7 +68,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0014, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0014, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs index b390586b9c..de04b5b99e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -3,12 +3,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; -public class ShaderMixin(Identifier name, TextLocation info) : ShaderDeclaration(info) +public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration(info) { public Identifier Name { get; set; } = name; public List Elements { get; set; } = []; public ShaderParameterDeclarations? Generics { get; set; } - public List Mixins { get; set; } = []; + public List Mixins { get; set; } = []; public override string ToString() @@ -31,7 +31,7 @@ public class ShaderGenerics(Identifier typename, Identifier name, TextLocation i public Identifier TypeName { get; set; } = typename; } -public class InheritedMixin(Identifier name, TextLocation info) : Node(info) +public class Mixin(Identifier name, TextLocation info) : Node(info) { public Identifier Name { get; set; } = name; public ShaderExpressionList? Generics { get; set; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 5dddcf5d66..ad17b28ce3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,10 +7,10 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : public List Attributes { get; set; } = []; } -public class ShaderCompose(Identifier name, InheritedMixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) +public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; - public InheritedMixin Mixin { get; set; } = mixin; + public Mixin Mixin { get; set; } = mixin; public bool IsArray { get; set; } = isArray; public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs index 5d6c33d995..5c1ff13584 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using System.Text; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -33,11 +34,12 @@ public abstract class Declaration(TypeName typename, TextLocation info) : Statem public TypeName TypeName { get; set; } = typename; } -public class VariableAssign(Expression variable, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +public class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) { public Expression Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; public Expression? Value { get; set; } = value; + public bool IsConst { get; set; } = isConst; public override string ToString() => Value switch diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs index 89fcbeba24..106a08db0d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs @@ -11,7 +11,7 @@ public partial class SymbolTable public Dictionary DeclaredTypes { get; } = []; public Stack> Symbols { get; } = []; - public void Process(ShaderMixin sclass, Dictionary? globalSymbols = null) + public void Process(ShaderClass sclass, Dictionary? globalSymbols = null) { DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass.Name, [])); foreach (var e in sclass.Elements) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index e006cccdef..3bee08ae53 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -55,6 +55,157 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + arraySize = null!; + value = null!; + if ( + LiteralsParser.TypeName(ref scanner, result, out typeName) + && Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out identifier)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('[', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out arraySize) + && Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + ) + { + scanner.Position = tmp; + } + tmp = scanner.Position; + if ( + !( + Terminals.Char('=', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out value) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + else + { + scanner.Position = position; + if ( + LiteralsParser.TypeName(ref scanner, result, out typeName) + && FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true) + && ExpressionParser.Expression(ref scanner, result, out arraySize) + && FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) + && Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out identifier)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('=', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out value) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + } + scanner.Position = position; + typeName = null!; + identifier = null!; + arraySize = null!; + return false; + } + + public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Mixin mixin, out Expression? arraySize, out Expression? value, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + arraySize = null!; + value = null!; + if ( + LiteralsParser.TypeName(ref scanner, result, out typeName) + && Spaces1(ref scanner, result, out _) + && ShaderClassParsers.Mixin(ref scanner, result, out mixin)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('[', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out arraySize) + && Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + ) + { + scanner.Position = tmp; + } + tmp = scanner.Position; + if( + !( + Terminals.Char('=', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out value) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + else + { + scanner.Position = position; + if ( + LiteralsParser.TypeName(ref scanner, result, out typeName) + && FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true) + && ExpressionParser.Expression(ref scanner, result, out arraySize) + && FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) + && Spaces1(ref scanner, result, out _) + && ShaderClassParsers.Mixin(ref scanner, result, out mixin)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('=', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out value) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + } + scanner.Position = position; + typeName = null!; + mixin = null!; + arraySize = null!; + return false; + } + public static bool Optional(ref TScanner scanner, TTerminal terminal, bool advance = false) where TScanner : struct, IScanner where TTerminal : struct, ITerminal diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs new file mode 100644 index 0000000000..7572169634 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs @@ -0,0 +1,12 @@ +namespace Stride.Shaders.Parsing.SDSL; + +public record struct OptionalParser(TParser Parser) : IParser + where TParser : IParser + where TResult : Node +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + Parser.Match(ref scanner, result, out parsed, orError); + return true; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index ea28a35f6d..602435aebd 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -66,11 +66,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('?', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(':', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index 6e41f614a3..a5b677f2d3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -204,8 +204,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( Terminals.Literal("#ifdef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && LiteralsParser.Identifier(ref scanner, result, out var id, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var id, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && Terminals.EOL(ref scanner, advance: true) ) { @@ -431,7 +431,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o func.Parameters.Add(param); if(!Terminals.Char(')', ref scanner, advance: true)) { - result.Errors.Add(new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); scanner.Position = position; parsed = null!; return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index 128f0ba5ab..bfd05dcab5 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs index 2827f5088a..df6ee9d512 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs @@ -60,7 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -102,7 +102,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -146,7 +146,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - result.Errors.Add(new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); parsed = null!; return false; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 0ea66ee45c..600ead6b2c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -70,7 +70,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -106,7 +106,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); return false; } } @@ -164,7 +164,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index a33681b676..d081352a80 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -66,13 +66,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var left, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(':', ref scanner, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var right, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -105,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.And(ref scanner, result, out var and)) parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0022, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0022, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BOr(ref scanner, result, out var bOr)) parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.XOr(ref scanner, result, out var xor)) parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0025, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0025, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -197,7 +197,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0026, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0026, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -227,7 +227,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0027, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0027, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -260,7 +260,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Relation(ref scanner, result, out var rel)) parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0028, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0028, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -291,7 +291,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Shift(ref scanner, result, out var shift)) parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0029, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0029, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -299,8 +299,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = shift; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + CommonParsers.Spaces0(ref scanner, result, out _); } - while (!Terminals.AnyOf(["<=", ">="], ref scanner, out _) && Terminals.AnyOf([">", "<"], ref scanner, out op, advance: true)); + while (Terminals.AnyOf(["<=", ">=", "<", ">"], ref scanner, out op, advance: true)); + if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -322,7 +324,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Add(ref scanner, result, out var add)) parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0030, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0030, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == "") { @@ -353,7 +355,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Mul(ref scanner, result, out var mul)) parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0031, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0031, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == '\0') { @@ -384,7 +386,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0042, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0042, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (parsed is null && op == '\0') { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 02ec4f6920..eaac3a1134 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -48,7 +48,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, advance: true) ) @@ -76,7 +76,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index c07869061d..3c893b2b1f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -49,7 +49,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return true; @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLErrors.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLParsingMessages.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) @@ -123,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 0f543cd215..88a2c683b7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -42,7 +42,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } // prefix decrememnt else if (Terminals.Literal("--", ref scanner, advance: true)) @@ -53,7 +53,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -77,7 +77,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && UnaryParsers.Postfix(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 68ebba82f9..bc2a5cdfe6 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -203,7 +203,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o scanner.Advance(1); while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) scanner.Advance(1); - var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position, scanner.Position - position)); var intermediate = scanner.Position; @@ -247,7 +246,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var tnPos = scanner.Position; int size = scanner.Span[scanner.Position - 1] - '0'; if (size < 2 || size > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { @@ -264,7 +263,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o p.Values.Add(vec); else if (ExpressionParser.Expression(ref scanner, result, out var exp)) p.Values.Add(exp); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(',', ref scanner, advance: true)) CommonParsers.Spaces0(ref scanner, result, out _); @@ -272,9 +271,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); if (p.Values.Count != size && p.Values.Count > size) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = p; return true; } @@ -301,7 +300,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o int rows = scanner.Span[scanner.Position - 3] - '0'; int cols = scanner.Span[scanner.Position - 1] - '0'; if (cols < 2 || cols > 4 || rows < 2 || rows > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0006, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0006, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { @@ -314,7 +313,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (LiteralsParser.Number(ref scanner, result, out var number)) p.Values.Add(number); - else if (LiteralsParser.Vector(ref scanner, result, out var vector, new(SDSLErrors.SDSL0007, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + else if (LiteralsParser.Vector(ref scanner, result, out var vector, new(SDSLParsingMessages.SDSL0007, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) p.Values.Add(vector); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); CommonParsers.Spaces0(ref scanner, result, out _); @@ -324,9 +323,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0008, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0008, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0002, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = p; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs index 730d223624..f473f7a803 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs @@ -59,6 +59,7 @@ static Reserved() "compile", "compile_fragment", "CompileShader", + "compose", "const", "continue", "ComputeShader", diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 7a4b0e389e..e81580e27d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -25,7 +25,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); parsed = new(identifier2, mixin2, true, scanner.GetLocation(position..)); return true; } @@ -38,11 +38,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); parsed = new(identifier, mixin, false, scanner.GetLocation(position..)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs index c2ed543a3f..3a3c00137e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -60,7 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(']', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0019, scanner.GetErrorLocation(position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(position), scanner.Memory)); parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..)); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 1c8457dddf..b6efa8f5be 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -47,7 +47,7 @@ public record struct CBufferParser : IParser if (Terminals.Literal("cbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -59,10 +59,10 @@ public record struct CBufferParser : IParser { if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) members.Add(member); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } if(scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) { Members = members @@ -85,7 +85,7 @@ public record struct TBufferParser : IParser if (Terminals.Literal("tbuffer ", ref scanner, advance: true)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -154,7 +154,7 @@ public record struct BufferMemberParser : IParser { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { @@ -182,7 +182,7 @@ public record struct BufferMemberParser : IParser { CommonParsers.Until(ref scanner, '=', advance: true); CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index ba7cf76483..febe1674fc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -4,9 +4,9 @@ namespace Stride.Shaders.Parsing.SDSL; -public record struct ShaderClassParsers : IParser +public record struct ShaderClassParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (ComplexClass(ref scanner, result, out parsed, in orError)) @@ -14,38 +14,38 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return false; } - public static bool Class(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) + public static bool Class(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParsers().Match(ref scanner, result, out parsed, in orError); - public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) + public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); public static bool GenericsDefinition(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed) where TScanner : struct, IScanner => new ShaderGenericsDefinitionParser().Match(ref scanner, result, out parsed); - public static bool Mixin(ref TScanner scanner, ParseResult result, out InheritedMixin parsed) + public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed) where TScanner : struct, IScanner => new ShaderMixinParser().Match(ref scanner, result, out parsed); } -public record struct SimpleShaderClassParser : IParser +public record struct SimpleShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( Terminals.Literal("shader", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && LiteralsParser.Identifier(ref scanner, result, out var className, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var className, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) ) { - var c = new ShaderMixin(className, scanner.GetLocation(position, scanner.Position - position)); + var c = new ShaderClass(className, scanner.GetLocation(position, scanner.Position - position)); while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) @@ -63,26 +63,29 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct ShaderClassParser : IParser +public record struct ShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMixin parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("shader ", ref scanner, advance: true)) + var tmp = position; + if (Terminals.Literal("internal", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + tmp = scanner.Position; + if (Terminals.Literal("shader", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result,out _)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { - parsed = new ShaderMixin(identifier, scanner.GetLocation(..)); + parsed = new ShaderClass(identifier, scanner.GetLocation(..)); if (Terminals.Char('<', ref scanner, advance: true)) { ParameterParsers.Declarations(ref scanner, result, out var generics); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); parsed.Generics = generics; CommonParsers.Spaces0(ref scanner, result, out _); } @@ -129,14 +132,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } -public record struct ShaderMixinParser : IParser +public record struct ShaderMixinParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out InheritedMixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - parsed = new InheritedMixin(identifier, scanner.GetLocation(..)); + parsed = new Mixin(identifier, scanner.GetLocation(..)); var tmpPos = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) @@ -145,7 +148,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Generics = values; CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); return true; } else @@ -167,7 +170,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index f1a83156a2..ab576079de 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -15,95 +15,32 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if (LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _) - ) + + TypeName? typeName = null!; + Expression? arraySize = null!; + Expression? value = null!; + + + if (!Terminals.Literal("compose", ref scanner) && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySize, out value)) { if ( - LiteralsParser.Identifier(ref scanner, result, out Identifier name) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) + && LiteralsParser.Identifier(ref scanner, result, out var semantic) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) && CommonParsers.Until(ref scanner, ')', advance: true)) { - CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name, null, false, scanner.GetLocation(position..scanner.Position)); + parsed = new(typeName, identifier, value, arraySize != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySize: arraySize); return true; } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) - { - CommonParsers.Until(ref scanner, '=', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) - { - CommonParsers.Until(ref scanner, ':', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) - { - parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position), semantic: semantic); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } - parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position)); - return true; - } - } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - else if ( - LiteralsParser.Identifier(ref scanner, result, out Identifier name2) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('[', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out var arraySize) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) - ) + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - typename.IsArray = true; - typename.ArraySize = arraySize; - if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) - { - CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name2, null, true, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); - return true; - } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) - { - CommonParsers.Until(ref scanner, '=', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'))) - { - CommonParsers.Until(ref scanner, ':', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Identifier(ref scanner, result, out var semantic, orError ?? new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) - { - parsed = new ShaderMember(typename, name2, expression, true, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySize: arraySize); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Missing semi colon here", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } - parsed = new ShaderMember(typename, name2, expression, true, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); - return true; - } - } + parsed = new(typeName, identifier, value, arraySize != null, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); + return true; } - + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -130,7 +67,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 91e2e7005f..3ef68267b8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -45,13 +45,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o isStreamed = true; else scanner.Position = tmpPos; - if (ShaderMemberParser.Member(ref scanner, result, out var member)) + if(Compose(ref scanner, result, out var compose)) { - member.IsStream = isStreamed; - member.IsStaged = isStaged; + compose.IsStaged = isStaged; if(hasAttributes) - member.Attributes = attributes.Attributes; - parsed = member; + compose.Attributes = attributes.Attributes; + parsed = compose; return true; } else if (Method(ref scanner, result, out var method)) @@ -59,18 +58,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o method.IsOverride = isOverride; method.IsStaged = isStaged; if(hasAttributes) - member.Attributes = attributes.Attributes; + method.Attributes = attributes.Attributes; parsed = method; return true; } - else if(Compose(ref scanner, result, out var compose)) + else if (ShaderMemberParser.Member(ref scanner, result, out var member)) { - compose.IsStaged = isStaged; + member.IsStream = isStreamed; + member.IsStaged = isStaged; if(hasAttributes) - compose.Attributes = attributes.Attributes; - parsed = compose; + member.Attributes = attributes.Attributes; + parsed = member; return true; } + + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 704a2b2e4e..eec5391991 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -24,7 +24,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o file.Namespaces.Add(ns); CommonParsers.Spaces0(ref scanner, result, out _); } - else if(Terminals.Literal("shader", ref scanner) + else if( + (Terminals.Literal("shader", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["internal", "shader"])) && ShaderClassParsers.Class(ref scanner, result, out var shader) ) { @@ -72,7 +73,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); } @@ -97,7 +98,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); else - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0039, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0039, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index ad499cb586..8f6064a848 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -40,14 +40,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && ShaderMethodParsers.Parameters(ref scanner, result, out var parameters) && Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Block(ref scanner, result, out var body, new(SDSLErrors.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && StatementParsers.Block(ref scanner, result, out var body, new(SDSLParsingMessages.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) @@ -72,9 +72,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Literal("abstract", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -83,13 +83,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ShaderMethodParsers.Parameters(ref scanner, result, out var parameters); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(')', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) { if (orError != null) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 8226fd370e..e7429e6ec1 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -39,8 +39,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { parameters.Add(new(typename, name)); - if (!Terminals.Char(',', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) - break; + if (Terminals.Char(',', ref scanner, advance: true)) + CommonParsers.Spaces0(ref scanner, result, out _); + else break; } parsed = new(scanner.GetLocation(position..scanner.Position)) { Parameters = parameters }; return true; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 857ad8258d..7dd30e35d3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -10,7 +10,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if(If(ref scanner, result, out var ifstatement, orError)) + if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) { parsed = new(ifstatement, scanner.GetLocation(..)); while(ElseIf(ref scanner, result, out var elseif, orError)) @@ -46,22 +46,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( Terminals.Literal("if", ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -80,19 +79,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -107,7 +106,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("else", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { parsed = new(statement, scanner.GetLocation(position..scanner.Position)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 8dd3c0ead5..7b08eebe3c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -62,14 +62,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if(StatementParsers.Assignments(ref scanner, result, out init)){} else if(StatementParsers.Declare(ref scanner, result, out init)){} else if(StatementParsers.Empty(ref scanner, result, out init)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0036, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0036, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (StatementParsers.Expression(ref scanner, result, out condition)){} else if (StatementParsers.Empty(ref scanner, result, out condition)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0037, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0037, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); // parsing the final expression @@ -81,7 +81,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { expression = new ExpressionStatement(exp, exp.Info); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0038, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0038, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); @@ -109,34 +109,34 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrors.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces1(ref scanner, result, out _) ) { if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrors.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -152,20 +152,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { parsed = new(expression, statement, scanner.GetLocation(position..scanner.Position)); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index d11cece434..7628ab7971 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -107,7 +107,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if ( Terminals.Literal("return", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLErrors.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { if (Terminals.Char(';', ref scanner, advance: true)) @@ -124,7 +124,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new Return(scanner.GetLocation(position, scanner.Position - position), val); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0041, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0041, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } @@ -208,7 +208,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o block.Statements.Add(statement); CommonParsers.Spaces0(ref scanner, result, out _); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } block.Info = scanner.GetLocation(position, scanner.Position - position); parsed = block; @@ -225,6 +225,7 @@ public record struct VariableAssignParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; + if (PostfixParser.Postfix(ref scanner, result, out var identifier)) { if ( @@ -240,14 +241,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position), op, expression); + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); } else { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)); return true; } } @@ -263,6 +264,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; + var isConst = Terminals.Literal("const", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + if (!isConst) + scanner.Position = position; if ( LiteralsParser.TypeName(ref scanner, result, out var typeName) && CommonParsers.Spaces1(ref scanner, result, out _) @@ -271,6 +275,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (CommonParsers.Repeat(ref scanner, StatementParsers.VarAssign, result, out var assigns, 1, true, ",")) { + foreach (var a in assigns) + a.IsConst = isConst; CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(';', ref scanner, advance: true)) { @@ -280,7 +286,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -304,7 +310,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrors.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders.Parsing/SDSLERR.cs index ac01d57b1d..71bec24fff 100644 --- a/src/Stride.Shaders.Parsing/SDSLERR.cs +++ b/src/Stride.Shaders.Parsing/SDSLERR.cs @@ -1,7 +1,7 @@ namespace Stride.Shaders.Parsing; -public static class SDSLErrors +public static class SDSLParsingMessages { public const string SDSL0001 = "SDSL0001: Unexpected token"; public const string SDSL0002 = "SDSL0002: vector size not supported"; @@ -46,5 +46,5 @@ public static class SDSLErrors public const string SDSL0041 = "SDSL0041: Expected expression or semi colon"; public const string SDSL0042 = "SDSL0042: Expected prefix expression"; public const string SDSL0043 = "SDSL0043: Unexpected "; - + public const string SDSL0044 = "SDSL0044: Use of register and packoffset keyword deprecated"; } \ No newline at end of file From e2ee4a373211181517d2ed884539ddfb3d67ae44 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 23 Oct 2024 22:00:37 +0200 Subject: [PATCH 0342/1182] corrections on some shader member parsing and for loops --- .../Examples.cs | 8 ++-- .../SDSL/AST/Statements.Flow.cs | 3 +- .../SDSL/AST/Statements.cs | 2 +- .../SDSL/Parsers/Common/CommonParsers.cs | 26 +++++++--- .../Parsers/LiteralParsers/LiteralParsers.cs | 4 +- .../StatementParsers/StatementParsers.Flow.cs | 48 +++++++++++++++---- .../StatementParsers/StatementParsers.cs | 31 +++++++++--- .../Scanners/Scanner.cs | 1 + 8 files changed, 93 insertions(+), 30 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 31fb794625..c7823fc71c 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -81,7 +81,7 @@ public static void SpvOpt() public static void ParseSDSL() { // var text = File.ReadAllText("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl"); - var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl", []); + var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl", []); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) @@ -98,19 +98,19 @@ public static void TryAllFiles() { // var text = File.ReadAllText(f); var preprocessed = MonoGamePreProcessor.Run(f, []); - Console.WriteLine(preprocessed); var parsed = SDSLParser.Parse(preprocessed); if(parsed.Errors.Count > 0) { + Console.WriteLine(preprocessed); Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(string.Join("; ", parsed.Errors.Select(x => x.ToString()))); Console.WriteLine(f); + Console.ForegroundColor = ConsoleColor.White; break; } else { - Console.ForegroundColor = ConsoleColor.Green; - Console.WriteLine(f); + // Console.WriteLine(f); } } Console.ForegroundColor = ConsoleColor.White; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs index 3d79084e36..484336f1bf 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs @@ -40,12 +40,13 @@ public enum ForAnnotationKind } public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); -public class For(Statement initializer, Statement cond, Statement update, Statement body, TextLocation info) : Loop(info) +public class For(Statement initializer, Statement cond, Statement update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Statement Initializer { get; set; } = initializer; public Statement Condition { get; set; } = cond; public Statement Update { get; set; } = update; public Statement Body { get; set; } = body; + public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs index 5c1ff13584..5518afdb7f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -45,7 +45,7 @@ public override string ToString() => Value switch { null => Variable.ToString() ?? "", - Expression v => $"{Variable} = {v}" + Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" }; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 3bee08ae53..42e3a12a89 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -7,9 +7,9 @@ namespace Stride.Shaders.Parsing.SDSL; public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result) where TScanner : struct, IScanner; -public delegate bool ParserValueDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, ParseError? orError = null) +public delegate bool ParserValueDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner; -public delegate bool ParserOptionalValueDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, ParseError? orError = null) +public delegate bool ParserOptionalValueDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, in ParseError? orError = null) where TScanner : struct, IScanner; public static class CommonParsers @@ -84,9 +84,8 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann tmp = scanner.Position; if ( !( - Terminals.Char('=', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out value) + FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) ) ) { @@ -253,6 +252,21 @@ public static bool FollowedByDel(ref TScanner scanner, ParseResult res scanner.Position = position; return false; } + public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (func.Invoke(ref scanner, result, out parsed)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { @@ -353,7 +367,7 @@ public static bool Repeat(ref TScanner scanner, TParse where TParser : struct, IParser where TNode : Node { - return Repeat(ref scanner, (ref TScanner s, ParseResult r, out TNode node, ParseError? orError) => new TParser().Match(ref s, r, out node, orError), result, out nodes, minimum, withSpaces, separator, orError); + return Repeat(ref scanner, (ref TScanner s, ParseResult r, out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), result, out nodes, minimum, withSpaces, separator, orError); } public static bool Repeat(ref TScanner scanner, ParserValueDelegate parser, ParseResult result, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) where TScanner : struct, IScanner diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index bc2a5cdfe6..ede5d48dcc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -113,12 +113,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { suffix = new(32, false, false); - if (Terminals.AnyOf(["f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true)) + if (Terminals.AnyOf(["f", "f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true)) { suffix = matched switch { "f16" or "h" => new(16, true, true), - "f32" => new(32, true, true), + "f32" or "f" => new(32, true, true), "f64" or "d" => new(64, true, true), _ => throw new NotImplementedException() diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 7b08eebe3c..3597042662 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -47,6 +47,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; + + var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && CommonParsers.Spaces0(ref scanner, result, out _); + if (!hasAttributes) + scanner.Position = position; if( Terminals.Literal("for", ref scanner, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) @@ -59,8 +63,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o // Parsing the initialization if(StatementParsers.Expression(ref scanner, result, out init)){} - else if(StatementParsers.Assignments(ref scanner, result, out init)){} - else if(StatementParsers.Declare(ref scanner, result, out init)){} + else if(StatementParsers.DeclareOrAssign(ref scanner, result, out init)){} else if(StatementParsers.Empty(ref scanner, result, out init)){} else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0036, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); @@ -75,27 +78,52 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o // parsing the final expression var tmpPos = scanner.Position; - if(CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) - expression = new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position)); - else if(ExpressionParser.Expression(ref scanner, result, out var exp) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) - { - expression = new ExpressionStatement(exp, exp.Info); - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0038, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + if (!AssignOrExpression(ref scanner, result, out expression)) + expression = new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position)); + if(!CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); // parsing the block or statement if(StatementParsers.Statement(ref scanner, result, out var body)) { - parsed = new For(init, condition, expression, body, scanner.GetLocation(position..scanner.Position)); + parsed = new For(init, condition, expression!, body, scanner.GetLocation(position..scanner.Position), attribute: attribute); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + PostfixParser.Postfix(ref scanner, result, out var variable) + && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + ) + { + parsed = new Assign(scanner.GetLocation(position..scanner.Position)) + { + Variables = [new(variable, false, scanner.GetLocation(position..scanner.Position), op, value)] + }; + return true; + } + scanner.Position = position; + if( + ExpressionParser.Expression(ref scanner, result, out var expression) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')')) + ) + { + parsed = new ExpressionStatement(expression, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } } public record struct ForEachParser : IParser diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 7628ab7971..bb36a2eaf1 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -21,8 +21,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = flow; return true; } - else if (Expression(ref scanner, result, out parsed)) - return true; else if (Break(ref scanner, result, out parsed)) return true; else if (Return(ref scanner, result, out parsed)) @@ -33,6 +31,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; else if (Assignments(ref scanner, result, out parsed)) return true; + else if (Expression(ref scanner, result, out parsed)) + return true; else if (Block(ref scanner, result, out parsed)) return true; return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -64,7 +64,27 @@ internal static bool Declare(ref TScanner scanner, ParseResult result, internal static bool Assignments(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new AssignmentsParser().Match(ref scanner, result, out parsed, orError); - internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, ParseError? orError = null) + internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Assignments(ref scanner, result, out parsed, orError)) + return true; + else if (Declare(ref scanner, result, out parsed, orError)) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Assignments(ref scanner, result, out parsed, orError)) + return true; + else if (Expression(ref scanner, result, out parsed, orError)) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new VariableAssignParser().Match(ref scanner, result, out parsed, orError); internal static bool Controls(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) @@ -177,8 +197,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( ExpressionParser.Expression(ref scanner, result, out var expression) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), advance: true) ) { parsed = new ExpressionStatement(expression, scanner.GetLocation(position, scanner.Position - position)); @@ -232,7 +251,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.FollowedBy( ref scanner, result, - (ref TScanner s, ParseResult result, out AssignOperator op, ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), + (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), out var op, withSpaces: true, advance: true) diff --git a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs index 6992cb298c..532c3b574a 100644 --- a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs +++ b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs @@ -9,6 +9,7 @@ public struct Scanner(string code) : IScanner // public string Code { get; } = code; public readonly ReadOnlySpan Span => Code.AsSpan(); public readonly ReadOnlyMemory Memory => Code.AsMemory(); + public readonly ReadOnlyMemory Rest => Memory[Position..]; string Code { get; set; } = code; public int Position { get; set; } = 0; From af8d33c37f7ed8c004ecd9adf3d897613d11a1f0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 24 Oct 2024 12:41:53 +0200 Subject: [PATCH 0343/1182] Correction unary and number parser --- .../ExpressionParsers/UnaryParsers.Prefix.cs | 2 +- .../Parsers/LiteralParsers/NumberParsers.cs | 61 +++++++++---------- .../SDSL/Parsers/Terminals/Terminals.cs | 36 +++++++++++ 3 files changed, 67 insertions(+), 32 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 88a2c683b7..b14457e947 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && LiteralsParser.TypeName(ref scanner, result, out var typeName) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(')', ref scanner, true) && UnaryParsers.Postfix(ref scanner, result, out var lit) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index b48f946a1f..6103d14cce 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -11,12 +11,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; var fp = new FloatParser(); var ip = new IntegerParser(); + var hx = new HexParser(); if (fp.Match(ref scanner, result, out FloatLiteral pf)) { parsed = pf; return true; } + else if (hx.Match(ref scanner, result, out HexLiteral hi)) + { + parsed = hi; + return true; + } else if (ip.Match(ref scanner, result, out IntegerLiteral pi)) { parsed = pi; @@ -65,52 +71,45 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - node = null!; - FloatSuffixParser suffix = new(); - if (Terminals.Char('.', ref scanner)) + if (Terminals.Char('.', ref scanner, advance: true)) { - scanner.Advance(1); + if (!Terminals.Digit(ref scanner)) + return CommonParsers.Exit(ref scanner, result, out node, position); while (Terminals.Digit(ref scanner, advance: true)) ; - - if (suffix.Match(ref scanner, result, out Suffix s)) - node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); - return true; } else if (Terminals.Digit(ref scanner, 1.., advance: true)) { while (Terminals.Digit(ref scanner, advance: true)) ; - Suffix s = new(32, true, true); - if (Terminals.Char('.', ref scanner, advance: true)) + if (Terminals.Char('.', ref scanner)) { + scanner.Advance(1); + if (!Terminals.Digit(ref scanner)) + return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); while (Terminals.Digit(ref scanner, advance: true)) ; } - else if (!suffix.Match(ref scanner, result, out s)) - { - return CommonParsers.Exit(ref scanner, result, out node, position, orError); - } - var len = 0; - foreach (var e in scanner.Span[position..scanner.Position]) - if (!char.IsDigit(e)) - break; - else - len += 1; - node = new FloatLiteral(s, double.Parse(scanner.Span[position..(position + len)]), new(scanner.Memory, position..scanner.Position)); - return true; + else if (!Terminals.FloatSuffix(ref scanner, out _)) + return CommonParsers.Exit(ref scanner, result, out node, position); + else return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - else if (Terminals.Digit(ref scanner, 0)) + else if (Terminals.Digit(ref scanner, 0, advance: true)) { - scanner.Advance(1); - Suffix s = new(32, true, true); if (Terminals.Char('.', ref scanner, advance: true)) { - while (Terminals.Digit(ref scanner, advance: true)) - if (!suffix.Match(ref scanner, result, out s)) - s = new(32, true, true); + if (!Terminals.Digit(ref scanner)) + return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + while (Terminals.Digit(ref scanner, advance: true)) ; } - node = new FloatLiteral(s, double.Parse(scanner.Span[position..scanner.Position]), new(scanner.Memory, position..scanner.Position)); - return true; + else return CommonParsers.Exit(ref scanner, result, out node, position); } - else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + else return CommonParsers.Exit(ref scanner, result, out node, position); + + + var value = double.Parse(scanner.Span[position..scanner.Position]); + if (Terminals.FloatSuffix(ref scanner, out var suffix, advance: true) && suffix is not null) + node = new(suffix.Value, value, scanner.GetLocation(position..scanner.Position)); + else + node = new(new(32, true, true), value, scanner.GetLocation(position..scanner.Position)); + return true; } } public struct HexParser : IParser diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs index f5d1f85824..03f38d88e7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; +using System.Security.Cryptography; namespace Stride.Shaders.Parsing.SDSL; @@ -69,6 +70,41 @@ public static bool EOL(ref TScanner scanner, bool advance = false) public static bool EOF(ref TScanner scanner) where TScanner : struct, IScanner => new EOFTerminalParser().Match(ref scanner, false); + + public static bool FloatSuffix(ref TScanner scanner, out Suffix? suffix, bool advance = false) + where TScanner : struct, IScanner + { + suffix = null; + if (AnyOf(["f16", "h", "f32", "f", "f64", "d"], ref scanner, out var matched, advance: advance)) + { + suffix = matched switch + { + "f16" or "h" => new(16, true, true), + "f32" or "f" => new(32, true, true), + "f64" or "d" => new(64, true, true), + _ => throw new NotImplementedException() + }; + return true; + } + else return false; + } + public static bool IntSuffix(ref TScanner scanner, out Suffix? suffix, bool advance = false) + where TScanner : struct, IScanner + { + suffix = null; + if (AnyOf(["u32", "u", "U", "i64", "l", "L", "u64", "ul", "UL"], ref scanner, out var matched, advance: advance)) + { + suffix = matched switch + { + "u32" or "u" or "U" => new(32, false, false), + "i64" or "l" or "L" => new(64, false, true), + "u64" or "ul" or "UL" => new(64, false, false), + _ => throw new NotImplementedException() + }; + return true; + } + else return false; + } } public interface ITerminal From 7cb5a1da98ef1f76265bec016bdf8fe9140580e6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 24 Oct 2024 14:19:38 +0200 Subject: [PATCH 0344/1182] correction on method and shader member parsing --- .../Examples.cs | 4 +- .../Program.cs | 4 +- src/Stride.Shaders.Parsing/ASTNode.cs | 5 ++ src/Stride.Shaders.Parsing/ParseResult.cs | 2 + .../Parsers/LiteralParsers/LiteralParsers.cs | 4 +- .../ShaderParsers/ShaderDataParsers.cs | 4 +- .../ShaderParsers/ShaderFileParsers.cs | 55 +++++++++++++++++-- .../ShaderParsers/ShaderMethodParsers.cs | 7 +-- 8 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index c7823fc71c..39586c09bf 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -81,7 +81,7 @@ public static void SpvOpt() public static void ParseSDSL() { // var text = File.ReadAllText("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl"); - var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl", []); + var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/BRDFMicrofacet.sdsl", []); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) @@ -97,6 +97,8 @@ public static void TryAllFiles() foreach(var f in Directory.EnumerateFiles("./assets/Stride/SDSL")) { // var text = File.ReadAllText(f); + if (f.Contains("BasicMixin.sdsl")) + continue; var preprocessed = MonoGamePreProcessor.Run(f, []); var parsed = SDSLParser.Parse(preprocessed); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index c679b629a6..6cd64c0ad0 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -3,6 +3,6 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -Examples.ParseSDSL(); +// Examples.ParseSDSL(); -// Examples.TryAllFiles(); \ No newline at end of file +Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders.Parsing/ASTNode.cs index 0443dedcb5..84414bb33a 100644 --- a/src/Stride.Shaders.Parsing/ASTNode.cs +++ b/src/Stride.Shaders.Parsing/ASTNode.cs @@ -31,6 +31,11 @@ public override string ToString() } } +public class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) +{ + public List NamespacePath { get; set; } = []; +} + public class ShaderNamespace(TextLocation info) : Node(info) { public List NamespacePath { get; set; } = []; diff --git a/src/Stride.Shaders.Parsing/ParseResult.cs b/src/Stride.Shaders.Parsing/ParseResult.cs index 0e4d93792e..99b0dcc8a2 100644 --- a/src/Stride.Shaders.Parsing/ParseResult.cs +++ b/src/Stride.Shaders.Parsing/ParseResult.cs @@ -10,6 +10,8 @@ readonly ReadOnlySpan GetNextToken() { ReadOnlySpan operators = ['+', '-', '*', '/', '%', '=', '!', '<', '>', '&', '|', '^', '~', '?', ':']; var pos = Location.Position; + if (pos >= Code.Span.Length) + return []; if(operators.Contains(Code.Span[pos])) { while(operators.Contains(Code.Span[pos])) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index ede5d48dcc..ea18a3a01c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -257,9 +257,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (!scanner.IsEof) { CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Number(ref scanner, result, out var number)) - p.Values.Add(number); - else if (LiteralsParser.Vector(ref scanner, result, out var vec)) + if (LiteralsParser.Vector(ref scanner, result, out var vec)) p.Values.Add(vec); else if (ExpressionParser.Expression(ref scanner, result, out var exp)) p.Values.Add(exp); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index ab576079de..94335644bc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -25,10 +25,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) - && LiteralsParser.Identifier(ref scanner, result, out var semantic) + && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) && CommonParsers.Until(ref scanner, ')', advance: true)) + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = new(typeName, identifier, value, arraySize != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySize: arraySize); return true; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index eec5391991..9bee697424 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -17,14 +17,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (!scanner.IsEof) { if ( - Terminals.Literal("namespace", ref scanner) + Terminals.Literal("namespace", ref scanner) && NamespaceParsers.Namespace(ref scanner, result, out var ns) ) { file.Namespaces.Add(ns); CommonParsers.Spaces0(ref scanner, result, out _); } - else if( + else if ( (Terminals.Literal("shader", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["internal", "shader"])) && ShaderClassParsers.Class(ref scanner, result, out var shader) ) @@ -32,28 +32,71 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o file.RootDeclarations.Add(shader); CommonParsers.Spaces0(ref scanner, result, out _); } - else if((Terminals.Literal("effect", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["partial", "effect"])) + else if ((Terminals.Literal("effect", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["partial", "effect"])) && EffectParser.Effect(ref scanner, result, out var effect) ) { file.RootDeclarations.Add(effect); CommonParsers.Spaces0(ref scanner, result, out _); } - else if(Terminals.Literal("params", ref scanner) + else if (Terminals.Literal("params", ref scanner) && ParamsParsers.Params(ref scanner, result, out var p) ) { file.RootDeclarations.Add(p); CommonParsers.Spaces0(ref scanner, result, out _); } + else if (Terminals.Literal("using ", ref scanner) + && UsingNamespace(ref scanner, result, out var uns) + ) + { + file.RootDeclarations.Add(uns); + CommonParsers.Spaces0(ref scanner, result, out _); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } parsed = file; return true; } + public static bool UsingNamespace(ref TScanner scanner, ParseResult result, out UsingShaderNamespace parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new UsingNamespaceParser().Match(ref scanner, result, out parsed, orError); } +public record struct UsingNamespaceParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingShaderNamespace parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("using", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + parsed = new(scanner.GetLocation(..)); + do + { + if (CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true)) + { + parsed.NamespacePath.Add(identifier); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true)); + + + + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + public record struct NamespaceParsers : IParser { @@ -74,11 +117,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - + CommonParsers.Spaces0(ref scanner, result, out _); } while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true)); - if(ns.NamespacePath.Count > 0) + if (ns.NamespacePath.Count > 0) ns.Namespace = string.Join(".", ns.NamespacePath); if (Terminals.Char(';', ref scanner, advance: true)) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 8f6064a848..4ed5811f56 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -42,10 +42,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) - && ShaderMethodParsers.Parameters(ref scanner, result, out var parameters) - && Terminals.Char(')', ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.Parameters, out ShaderParameterDeclarations parameters, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) && StatementParsers.Block(ref scanner, result, out var body, new(SDSLParsingMessages.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) From 6452514f9ad7f450cced8892ab295e9daee48e7f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 24 Oct 2024 23:48:19 +0200 Subject: [PATCH 0345/1182] Corrections on parameter parsing and adding conditional parsing for sdfx --- .../Examples.cs | 3 +- .../Program.cs | 4 +- .../SDFX/AST/Effect.Flow.cs | 2 +- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 3 +- .../SDFX/Parsers/EffectParser.cs | 7 +- .../EffectStatementParsers.Conditional.cs | 124 ++++++++++++++++++ .../SDFX/Parsers/EffectStatementParsers.cs | 5 + .../SDSL/AST/Literals.cs | 14 +- .../SDSL/Parsers/Common/CommonParsers.cs | 6 +- .../ExpressionParsers/UnaryParsers.Postfix.cs | 4 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 36 ++++- .../Parsers/ShaderParsers/ShaderParameters.cs | 15 ++- .../StatementParsers/StatementParsers.cs | 4 +- 13 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 39586c09bf..9e5345e094 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -80,8 +80,7 @@ public static void SpvOpt() public static void ParseSDSL() { - // var text = File.ReadAllText("./assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl"); - var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/BRDFMicrofacet.sdsl", []); + var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl", []); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 6cd64c0ad0..c679b629a6 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -3,6 +3,6 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -// Examples.ParseSDSL(); +Examples.ParseSDSL(); -Examples.TryAllFiles(); \ No newline at end of file +// Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs index 119429b10c..e247cdbcfe 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs @@ -2,7 +2,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info); -public class ConditionalFlow(If first, TextLocation info) : EffectFlow(info) +public class EffectControl(If first, TextLocation info) : EffectFlow(info) { public If If { get; set; } = first; public List ElseIfs { get; set; } = []; diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 530eac1698..0da2a47241 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -3,10 +3,11 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class ShaderEffect(TypeName name, TextLocation info) : ShaderDeclaration(info) +public class ShaderEffect(TypeName name, bool isPartial, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; public List Members { get; set; } = []; + public bool IsPartial { get; set; } = isPartial; public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index 208942ef71..e0244ed38c 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -9,11 +9,16 @@ public record struct EffectParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; + + var isPartial = Terminals.Literal("partial", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + if(!isPartial) + scanner.Position = position; + if (Terminals.Literal("effect", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if (LiteralsParser.TypeName(ref scanner, result, out var effectName) && CommonParsers.Spaces0(ref scanner, result, out _)) { - parsed = new(effectName, new()); + parsed = new(effectName, isPartial, new()); if (Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { while( diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs new file mode 100644 index 0000000000..34cbb5ab5c --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -0,0 +1,124 @@ +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDFX.Parsers; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.SDFX; + + + +public record struct EffectControlsParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectControl parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + parsed = new(ifstatement, scanner.GetLocation(..)); + while(ElseIf(ref scanner, result, out var elseif, orError)) + parsed.ElseIfs.Add(elseif); + if (Else(ref scanner, result, out var elseStatement, orError)) + parsed.Else = elseStatement; + parsed.Info = scanner.GetLocation(position..scanner.Position); + return true; + } + else if(Terminals.Literal("else ", ref scanner)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool Control(ref TScanner scanner, ParseResult result, out EffectControl parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new EffectControlsParser().Match(ref scanner, result, out parsed, orError); + + public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new IfStatementParser().Match(ref scanner, result, out parsed, orError); + public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ElseIfStatementParser().Match(ref scanner, result, out parsed, orError); + public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ElseStatementParser().Match(ref scanner, result, out parsed, orError); +} + + + +public record struct IfStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out If parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("if", ref scanner, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ElseIfStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseIf parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("else", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && Terminals.Literal("if", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ElseStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Else parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("else", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + ) + { + parsed = new(statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index f06df5ec25..c83c6e4c55 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -25,6 +25,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p3; return true; } + else if(EffectControlsParser.Control(ref scanner, result, out var control)) + { + parsed = control; + return true; + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index b1bca39e2b..c35e841abf 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -9,6 +9,17 @@ public abstract class Literal(TextLocation info) : Expression(info); public abstract class ValueLiteral(TextLocation info) : Literal(info); public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); + +public class StringLiteral(string value, TextLocation info) : Literal(info) +{ + public string Value { get; set; } = value; + + public override string ToString( ) + { + return $"\"{Value}\""; + } +} + public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) { public abstract double DoubleValue { get; } @@ -95,6 +106,7 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public string Name { get; set; } = name; public bool IsArray { get; set; } = isArray; public Expression? ArraySize { get; set; } + public List Generics { get; set; } = []; public override string ToString() { @@ -102,4 +114,4 @@ public override string ToString() } public static implicit operator string(TypeName tn) => tn.Name; -} \ No newline at end of file +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 42e3a12a89..7b78915eeb 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -156,7 +156,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P scanner.Position = tmp; } tmp = scanner.Position; - if( + if ( !( Terminals.Char('=', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) @@ -367,9 +367,9 @@ public static bool Repeat(ref TScanner scanner, TParse where TParser : struct, IParser where TNode : Node { - return Repeat(ref scanner, (ref TScanner s, ParseResult r, out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), result, out nodes, minimum, withSpaces, separator, orError); + return Repeat(ref scanner, result, (ref TScanner s, ParseResult r, out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), out nodes, minimum, withSpaces, separator, orError); } - public static bool Repeat(ref TScanner scanner, ParserValueDelegate parser, ParseResult result, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + public static bool Repeat(ref TScanner scanner, ParseResult result, ParserValueDelegate parser, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) where TScanner : struct, IScanner where TNode : Node { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 3c893b2b1f..9d32a48a71 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -84,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLParsingMessages.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + && PostfixParser.Accessor(ref scanner, result, out var accessed)) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -115,7 +115,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var index) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true) ) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index ea18a3a01c..ecd8755997 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -60,6 +60,21 @@ public static bool Matrix(ref TScanner scanner, ParseResult result, ou public static bool Integer(ref TScanner scanner, ParseResult result, out IntegerLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner => new IntegerParser().Match(ref scanner, result, out number, in orError); + + public static bool StringLiteral(ref TScanner scanner, ParseResult result, out StringLiteral parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if(Terminals.Char('\"', ref scanner, advance: true)) + { + CommonParsers.Until(ref scanner, '\"', advance: true); + if (scanner.Span[position..scanner.Position].Contains('\n')) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(position), scanner.Memory)); + parsed = new(scanner.Span[position..scanner.Position].ToString(), scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position); + } public static bool AssignOperators(ref TScanner scanner, ParseResult result, out AssignOperator op, in ParseError? orError = null) where TScanner : struct, IScanner @@ -200,12 +215,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (Terminals.Char('_', ref scanner) || Terminals.Letter(ref scanner)) { + name = new TypeName("", new(), false); scanner.Advance(1); while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) scanner.Advance(1); var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position, scanner.Position - position)); var intermediate = scanner.Position; + + if(CommonParsers.FollowedBy(ref scanner, Terminals.Char('<'), withSpaces: true, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + CommonParsers.Repeat(ref scanner, result, LiteralsParser.TypeName, out List generics, 1, withSpaces: true, separator: ","); + if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('>'), withSpaces: true, advance: true)) + return CommonParsers.Exit(ref scanner, result, out name, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + name.Generics = generics; + intermediate = scanner.Position; + } + + if ( CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char('[', ref scanner, advance: true) @@ -215,13 +243,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Terminals.Char(']', ref scanner, advance: true) ) { - name = new TypeName(scanner.Memory[position..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position), isArray: true); + name.Name = scanner.Memory[position..scanner.Position].ToString().Trim(); + name.Info = scanner.GetLocation(position..scanner.Position); + name.IsArray = true; return true; } else { scanner.Position = intermediate; - name = new(identifier.Name, scanner.GetLocation(position..scanner.Position), isArray : false); + name.Name = identifier.Name; + name.Info = scanner.GetLocation(position..scanner.Position); + name.IsArray = false; return true; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index e7429e6ec1..d082458077 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -53,12 +53,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; List values = []; - while (ExpressionParser.Expression(ref scanner, result, out var expr) && CommonParsers.Spaces0(ref scanner, result, out _)) + do { - values.Add(expr); - if (!Terminals.Char(',', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) - break; + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expr)) + values.Add(expr); + else if (LiteralsParser.StringLiteral(ref scanner, result, out var str)) + values.Add(str); + else if (values.Count == 0) + break; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } + while (!scanner.IsEof && CommonParsers.FollowedBy(ref scanner, Terminals.Char(','), advance: true)); + parsed = new(scanner.GetLocation(position..scanner.Position)) { Values = values diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index bb36a2eaf1..064e08fe79 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -292,7 +292,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { - if (CommonParsers.Repeat(ref scanner, StatementParsers.VarAssign, result, out var assigns, 1, true, ",")) + if (CommonParsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) { foreach (var a in assigns) a.IsConst = isConst; @@ -318,7 +318,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (CommonParsers.Repeat(ref scanner, StatementParsers.VarAssign, result, out var assigns, 1, true, ",")) + if (CommonParsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) { CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(';', ref scanner, advance: true)) From 44889382a69b80874f58ce8ae4b1bdb2637f1b64 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 26 Oct 2024 01:50:09 +0200 Subject: [PATCH 0346/1182] added new sdfx features --- .../Program.cs | 4 +- .../SDFX/AST/Effect.Flow.cs | 18 +++- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 24 +++++ .../Parsers/EffectStatementParsers.Flow.cs | 73 +++++++++++++ .../SDFX/Parsers/EffectStatementParsers.cs | 101 +++++++++++++++++- 5 files changed, 212 insertions(+), 8 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index c679b629a6..6cd64c0ad0 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -3,6 +3,6 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -Examples.ParseSDSL(); +// Examples.ParseSDSL(); -// Examples.TryAllFiles(); \ No newline at end of file +Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs index e247cdbcfe..6c12356fc1 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Parsing.SDSL; namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info); @@ -39,4 +40,19 @@ public override string ToString() { return $"else {Body}"; } -} \ No newline at end of file +} + + + +public class EffectForEach(SDSL.AST.TypeName typename, SDSL.AST.Identifier variable, SDSL.AST.Expression collection, EffectStatement body, TextLocation info) : EffectFlow(info) +{ + public SDSL.AST.TypeName Typename { get; set; } = typename; + public SDSL.AST.Identifier Variable { get; set; } = variable; + public SDSL.AST.Expression Collection { get; set; } = collection; + public EffectStatement Body { get; set; } = body; + + public override string ToString() + { + return $"foreach({Typename} {Variable} in {Collection})\n{Body}"; + } +} diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 0da2a47241..807e981f8c 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -17,6 +17,16 @@ public override string ToString() public abstract class EffectStatement(TextLocation info) : Node(info); +public class EffectStatementBlock(TextLocation info) : EffectStatement(info) +{ + public List Statements { get; set; } = []; + + public override string ToString() + { + return string.Join("\n", Statements); + } +} + public class MixinUse(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; @@ -26,6 +36,11 @@ public override string ToString() } } +public class MixinConst(string identifier, TextLocation info) : EffectStatement(info) +{ + public string Identifier { get; set; } = identifier; +} + public abstract class Composable(); public class MixinCompose(Identifier identifier, Mixin mixin, TextLocation info) : EffectStatement(info) @@ -37,6 +52,15 @@ public override string ToString() return $"mixin compose {Identifier} = {MixinName}"; } } +public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) +{ + public Identifier Identifier { get; set; } = identifier; + public Identifier Source { get; set; } = source; + public override string ToString() + { + return $"mixin compose {Identifier} += {Source}"; + } +} public class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) { diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs new file mode 100644 index 0000000000..5a9cce566b --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs @@ -0,0 +1,73 @@ +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDFX.Parsers; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.SDFX; + + + +public record struct FlowParsers : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (ForEach(ref scanner, result, out var fe, orError)) + { + parsed = fe; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool ForEach(ref TScanner scanner, ParseResult result, out EffectForEach parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new EffectForEachParser().Match(ref scanner, result, out parsed, orError); +} + + + + +public record struct EffectForEachParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectForEach parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("foreach", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if ( + LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces1(ref scanner, result, out _) + ) + { + if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if ( + ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + { + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index c83c6e4c55..1356c411a8 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -10,7 +10,12 @@ public record struct EffectStatementParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + if (EffectBlock(ref scanner, result, out var block, orError)) + { + parsed = block; + return true; + } + else if (UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p1; return true; @@ -20,29 +25,67 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p2; return true; } + else if (MixinComposeAdd(ref scanner, result, out var mca, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = mca; + return true; + } else if (MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p3; return true; } - else if(EffectControlsParser.Control(ref scanner, result, out var control)) + else if (MixinConst(ref scanner, result, out var mc, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = mc; + return true; + } + else if (EffectControlsParser.Control(ref scanner, result, out var control)) { parsed = control; return true; } + else if (Flow(ref scanner, result, out var flow)) + { + parsed = flow; + return true; + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Statement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); - public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinCompose(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinComposeParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinUse(ref TScanner scanner, ParseResult result, out AST.MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool MixinComposeAdd(ref TScanner scanner, ParseResult result, out MixinComposeAdd parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new MixinComposeAddParser().Match(ref scanner, result, out parsed, orError); + public static bool MixinUse(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinUseParser().Match(ref scanner, result, out parsed, orError); + public static bool MixinConst(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new MixinConstParser().Match(ref scanner, result, out parsed, orError); + public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new FlowParsers().Match(ref scanner, result, out parsed, orError); + + public static bool EffectBlock(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + + if (Terminals.Char('{', ref scanner, advance: true)) + { + List statements = []; + while (CommonParsers.FollowedByDel(ref scanner, result, Statement, out EffectStatement statement, withSpaces: true, advance: true)) + { + statements.Add(statement); + } + if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + parsed = new EffectBlock(scanner.GetLocation(position..scanner.Position)) { Statements = statements }; + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position); + } } @@ -64,6 +107,30 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } +public record struct MixinConstParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.SequenceOf(ref scanner, ["mixin", "macro"], advance: true) + || CommonParsers.SequenceOf(ref scanner, ["mixin", "const"], advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + var tmp = scanner.Position; + CommonParsers.Until(ref scanner, ';'); + if (Terminals.Char(';', ref scanner)) + { + parsed = new(scanner.Memory[tmp..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + public record struct MixinComposeParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -93,6 +160,29 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } +public record struct MixinComposeAddParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinComposeAdd parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) + && LiteralsParser.Identifier(ref scanner, result, out var name) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Literal("+=", ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + + ) + { + var start = scanner.Position; + CommonParsers.Until(ref scanner, ';'); + parsed = new MixinComposeAdd(name, new(scanner.Memory[start..scanner.Position].ToString().Trim(), scanner.GetLocation(start..scanner.Position)), scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + public record struct MixinUseParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -102,6 +192,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Terminals.Literal("mixin", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) && ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) ) { parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); From c29dfbcee61fcd0e6097ef62a5b80e3674c98b23 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 27 Oct 2024 01:11:20 +0200 Subject: [PATCH 0347/1182] advancing through test files --- .../Examples.cs | 2 +- .../Program.cs | 6 +- .../ParsingTests.cs | 47 ++++++++---- .../Stride.Shaders.Parsing.Tests.csproj | 1 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 15 +++- .../SDSL/Parsers/Common/CommonParsers.cs | 19 +++++ .../Parsers/LiteralParsers/LiteralParsers.cs | 76 +++++++++++-------- .../ShaderParsers/ShaderBufferParsers.Cs | 7 +- .../ShaderParsers/ShaderElementParsers.cs | 2 + .../ShaderParsers/ShaderMethodParsers.cs | 39 ++++++++-- .../Parsers/ShaderParsers/ShaderParameters.cs | 25 +++--- .../StatementParsers.Control.cs | 2 +- 12 files changed, 174 insertions(+), 67 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 9e5345e094..90b310cd46 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -80,7 +80,7 @@ public static void SpvOpt() public static void ParseSDSL() { - var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl", []); + var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl", []); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 6cd64c0ad0..e50642e62b 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -1,8 +1,12 @@ using Stride.Shaders.Experiments; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; // Examples.SpvOpt(); // Examples.TranslateHLSL(); -// Examples.ParseSDSL(); +Grammar.Match("float(num) / 4294967295.0"); +Examples.ParseSDSL(); Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs index 8ba8e3fe4b..8adf083ee9 100644 --- a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs +++ b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs @@ -1,25 +1,44 @@ + +using Stride.Shaders.Parsing; namespace Stride.Shaders.Parsing.Tests; public class ParsingTests1 { - [Theory] - [InlineData("assets/SDSL/Commented.sdsl")] - public void Test1(string path) + public static IEnumerable GetShaderFilePaths() { - var shader = File.ReadAllText(path); - Assert.True(shader.Length > 0); + var files = Directory.GetFiles("assets/Stride/SDSL", "*.sdsl"); + foreach (var file in files) + { + yield return new object[] { file }; + } } + [Theory] - [InlineData("assets/Stride/Commented.sdsl")] - public void TestMacro(string path) + [MemberData(nameof(GetShaderFilePaths))] + public void TestAllFiles(string path) { - var shader = File.ReadAllText(path); - Assert.True(shader.Length > 0); + var text = MonoGamePreProcessor.Run(path, []); + var result = SDSLParser.Parse(text); + Assert.True(result.Errors.Count == 0, path + string.Join("\n", result.Errors.Select(x => x.ToString()))); } + // [Theory] + // [InlineData("assets/SDSL/Commented.sdsl")] + // public void Test1(string path) + // { + // var shader = File.ReadAllText(path); + // Assert.True(shader.Length > 0); + // } + // [Theory] + // [InlineData("assets/Stride/Commented.sdsl")] + // public void TestMacro(string path) + // { + // var shader = File.ReadAllText(path); + // Assert.True(shader.Length > 0); + // } - [Fact] - public void Test2() - { - Assert.True(true); - } + // [Fact] + // public void Test2() + // { + // Assert.True(true); + // } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj index 7e8e53618c..1e4d2f62e0 100644 --- a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index ad17b28ce3..d39e2f449b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -31,6 +31,19 @@ public override string ToString() } } +public class MethodParameter(TypeName type, Identifier name, TextLocation info, string? storage = null, Expression? arraySize = null) : Node(info) +{ + public TypeName Type { get; set; } = type; + public Identifier Name { get; set; } = name; + public Expression? ArraySize { get; set; } = arraySize; + public string? Storage { get; set; } = storage; + + public override string ToString() + { + return $"{Type} {Name}"; + } +} + public class ShaderMethod(TypeName returnType, Identifier name, TextLocation info, Identifier? visibility = null, Identifier? storage = null, bool isStaged = false, bool isAbstract = false, bool isVirtual = false, bool isOverride = false, bool isClone = false) : MethodOrMember(info, isStaged) { public TypeName ReturnType { get; set; } = returnType; @@ -41,7 +54,7 @@ public class ShaderMethod(TypeName returnType, Identifier name, TextLocation inf public bool? IsVirtual { get; set; } = isVirtual; public bool? IsOverride { get; set; } = isOverride; public bool? IsClone { get; set; } = isClone; - public ShaderParameterDeclarations? ParameterList { get; set; } + public List Parameters { get; set; } = []; public BlockStatement? Body { get; set; } public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 7b78915eeb..f621b855cc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -9,6 +9,10 @@ public delegate bool ParserDelegate(ref TScanner scanner, ParseResult where TScanner : struct, IScanner; public delegate bool ParserValueDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner; + +public delegate bool ParserListValueDelegate(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; + public delegate bool ParserOptionalValueDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, in ParseError? orError = null) where TScanner : struct, IScanner; @@ -267,6 +271,21 @@ public static bool FollowedByDel(ref TScanner scanner, ParseR scanner.Position = position; return false; } + public static bool FollowedByDelList(ref TScanner scanner, ParseResult result, ParserListValueDelegate func, out List parsed, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + if (func.Invoke(ref scanner, result, out parsed)) + { + if (!advance) + scanner.Position = position; + return true; + } + scanner.Position = position; + return false; + } public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index ecd8755997..6ad96cc9d8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -60,12 +60,12 @@ public static bool Matrix(ref TScanner scanner, ParseResult result, ou public static bool Integer(ref TScanner scanner, ParseResult result, out IntegerLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner => new IntegerParser().Match(ref scanner, result, out number, in orError); - + public static bool StringLiteral(ref TScanner scanner, ParseResult result, out StringLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if(Terminals.Char('\"', ref scanner, advance: true)) + if (Terminals.Char('\"', ref scanner, advance: true)) { CommonParsers.Until(ref scanner, '\"', advance: true); if (scanner.Span[position..scanner.Position].Contains('\n')) @@ -223,12 +223,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var intermediate = scanner.Position; - if(CommonParsers.FollowedBy(ref scanner, Terminals.Char('<'), withSpaces: true, advance: true)) + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('<'), withSpaces: true, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); CommonParsers.Repeat(ref scanner, result, LiteralsParser.TypeName, out List generics, 1, withSpaces: true, separator: ","); if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('>'), withSpaces: true, advance: true)) - return CommonParsers.Exit(ref scanner, result, out name, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out name, position); name.Generics = generics; intermediate = scanner.Position; } @@ -272,41 +272,57 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( Terminals.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) - && Terminals.Digit(ref scanner, 2..4, advance: true) ) { var tnPos = scanner.Position; - int size = scanner.Span[scanner.Position - 1] - '0'; - if (size < 2 || size > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('(', ref scanner, advance: true)) + if (Terminals.Digit(ref scanner, 2..4, advance: true)) { - var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) - { - TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) - }; - while (!scanner.IsEof) + tnPos = scanner.Position; + int size = scanner.Span[scanner.Position - 1] - '0'; + if (size < 2 || size > 4) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char('(', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Vector(ref scanner, result, out var vec)) - p.Values.Add(vec); - else if (ExpressionParser.Expression(ref scanner, result, out var exp)) - p.Values.Add(exp); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(',', ref scanner, advance: true)) + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) + { + TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) + }; + while (!scanner.IsEof) + { CommonParsers.Spaces0(ref scanner, result, out _); - else if (Terminals.Char(')', ref scanner, advance: true)) - break; + if (LiteralsParser.Vector(ref scanner, result, out var vec)) + p.Values.Add(vec); + else if (ExpressionParser.Expression(ref scanner, result, out var exp)) + p.Values.Add(exp); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(',', ref scanner, advance: true)) + CommonParsers.Spaces0(ref scanner, result, out _); + else if (Terminals.Char(')', ref scanner, advance: true)) + break; + } + if (scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + if (p.Values.Count != size && p.Values.Count > size) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + parsed = p; + return true; } - if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - if (p.Values.Count != size && p.Values.Count > size) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = p; + } + else if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + ) + { + parsed = new VectorLiteral(new TypeName(baseType, scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(position..scanner.Position)) + { + Values = [value] + }; return true; } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index b6efa8f5be..9f82f51e64 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -57,7 +57,10 @@ public record struct CBufferParser : IParser CommonParsers.Spaces0(ref scanner, result, out _); while(!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { - if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) + if ( + BufferParsers.Member(ref scanner, result, out var member) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) members.Add(member); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } @@ -184,7 +187,7 @@ public record struct BufferMemberParser : IParser CommonParsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) { - if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position), isStage, isStream); return true; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 3ef68267b8..4419f6dff8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -11,11 +11,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (BufferParsers.Buffer(ref scanner, result, out var buffer)) { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed = buffer; return true; } else if(Struct(ref scanner, result, out var structElement)) { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed = structElement; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 4ed5811f56..e47b497751 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -27,9 +27,36 @@ public static bool Simple(ref TScanner scanner, ParseResult result, ou where TScanner : struct, IScanner => new SimpleMethodParser().Match(ref scanner, result, out parsed, in orError); - public static bool Parameters(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) + + + public static bool MethodParameters(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if(CommonParsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) + { + parsed = parameters; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + + } + public static bool MethodParameter(ref TScanner scanner, ParseResult result, out MethodParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new ParameterDeclarationsParser().Match(ref scanner, result, out parsed, orError); + { + var position = scanner.Position; + + if(Terminals.AnyOf(["inout", "in", "out", "triangle"], ref scanner, out var storage, advance: true)) + CommonParsers.Spaces1(ref scanner, result, out _); + if(CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) + ) + { + parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + + } } public record struct SimpleMethodParser : IParser @@ -43,7 +70,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.Parameters, out ShaderParameterDeclarations parameters, withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.MethodParameters, out List parameters, withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) && StatementParsers.Block(ref scanner, result, out var body, new(SDSLParsingMessages.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) @@ -51,7 +78,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) { - ParameterList = parameters, + Parameters = parameters, Body = (BlockStatement)body }; return true; @@ -79,7 +106,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) { - ShaderMethodParsers.Parameters(ref scanner, result, out var parameters); + ShaderMethodParsers.MethodParameters(ref scanner, result, out var parameters); CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(')', ref scanner, advance: true)) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); @@ -95,7 +122,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = new(typename, methodName, scanner.GetLocation(position..scanner.Position), isAbstract: true) { - ParameterList = parameters + Parameters = parameters }; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index d082458077..049c2fbff0 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -31,18 +31,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; List parameters = []; - while ( - LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) - ) + + do { - parameters.Add(new(typename, name)); - if (Terminals.Char(',', ref scanner, advance: true)) - CommonParsers.Spaces0(ref scanner, result, out _); - else break; + if ( + CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var name) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + parameters.Add(new(typename, name)); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } + while (!scanner.IsEof && Terminals.Char(',', ref scanner, advance: true)); parsed = new(scanner.GetLocation(position..scanner.Position)) { Parameters = parameters }; return true; } @@ -61,7 +64,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if (LiteralsParser.StringLiteral(ref scanner, result, out var str)) values.Add(str); else if (values.Count == 0) - break; + break; else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } while (!scanner.IsEof && CommonParsers.FollowedBy(ref scanner, Terminals.Char(','), advance: true)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 7dd30e35d3..9439c1ba2a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -13,7 +13,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) { parsed = new(ifstatement, scanner.GetLocation(..)); - while(ElseIf(ref scanner, result, out var elseif, orError)) + while(ElseIf(ref scanner, result, out var elseif, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; From 08fabb9a981efd50e6970a64fab5596f8a45c542 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:57:32 +0100 Subject: [PATCH 0348/1182] added rgroup parsing --- .../SDSL/AST/ShaderElements.cs | 12 ++- .../ShaderParsers/ShaderBufferParsers.Cs | 76 ++++++++++++++++--- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index e02e7b53ab..2564433283 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -4,9 +4,9 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info); -public abstract class ShaderBuffer(Identifier name, TextLocation info) : ShaderElement(info) +public abstract class ShaderBuffer(List name, TextLocation info) : ShaderElement(info) { - public Identifier Name { get; set; } = name; + public List Name { get; set; } = name; } public class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) @@ -31,11 +31,15 @@ public override string ToString() } } -public sealed class CBuffer(Identifier name, TextLocation info) : ShaderBuffer(name, info) +public sealed class CBuffer(List name, TextLocation info) : ShaderBuffer(name, info) { public List Members { get; set; } = []; } -public sealed class TBuffer(Identifier name, TextLocation info) : ShaderBuffer(name, info) +public sealed class RGroup(List name, TextLocation info) : ShaderBuffer(name, info) +{ + public List Members { get; set; } = []; +} +public sealed class TBuffer(List name, TextLocation info) : ShaderBuffer(name, info) { public List Members { get; set; } = []; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 9f82f51e64..c2b9f36a81 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -18,6 +18,11 @@ public record struct BufferParsers : IParser parsed = tbuff; return true; } + else if (RGroup(ref scanner, result, out var rgroup, orError)) + { + parsed = rgroup; + return true; + } return false; } @@ -32,10 +37,61 @@ public record struct BufferParsers : IParser public static bool CBuffer(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new CBufferParser().Match(ref scanner, result, out parsed, orError); + public static bool RGroup(ref TScanner scanner, ParseResult result, out RGroup parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new RGroupParser().Match(ref scanner, result, out parsed, orError); public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new BufferMemberParser().Match(ref scanner, result, out parsed, orError); + + public static bool BufferName(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + return CommonParsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); + } +} + +public record struct RGroupParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out RGroup parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Terminals.Literal("rgroup", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + { + if ( + BufferParsers.BufferName(ref scanner, result, out var identifiers) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + if (Terminals.Char('{', ref scanner, advance: true)) + { + List members = []; + CommonParsers.Spaces0(ref scanner, result, out _); + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + { + if ( + BufferParsers.Member(ref scanner, result, out var member) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + members.Add(member); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + if (scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) + { + Members = members + }; + return true; + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } } @@ -44,10 +100,10 @@ public record struct CBufferParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("cbuffer ", ref scanner, advance: true)) + if (Terminals.Literal("cbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + BufferParsers.BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -55,23 +111,23 @@ public record struct CBufferParser : IParser { List members = []; CommonParsers.Spaces0(ref scanner, result, out _); - while(!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if ( - BufferParsers.Member(ref scanner, result, out var member) + BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _) ) members.Add(member); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - if(scanner.IsEof) + if (scanner.IsEof) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) { Members = members }; return true; - + } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -85,10 +141,10 @@ public record struct TBufferParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out TBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("tbuffer ", ref scanner, advance: true)) + if (Terminals.Literal("tbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + BufferParsers.BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -104,7 +160,7 @@ public record struct TBufferParser : IParser while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); if (Terminals.Char('}', ref scanner, advance: true)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) { Members = members }; From 2880db156feda7e9ded1feb5b372f1f7db27526f Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Mon, 28 Oct 2024 00:32:31 +0100 Subject: [PATCH 0349/1182] small corrections --- assets/Stride/SDSL/VoxelAttribute.sdsl | 2 +- .../SDSL/VoxelStorageTextureShader.sdsl | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 ++- .../SDSL/AST/ShaderElements.cs | 10 +++++++ .../SDSL/Parsers/Common/CommonParsers.cs | 1 + .../Parsers/LiteralParsers/LiteralParsers.cs | 19 ++++++++++-- .../ShaderParsers/ShaderClassParser.cs | 7 ++++- .../ShaderParsers/ShaderElementParsers.cs | 30 ++++++++++++++++++- .../ShaderParsers/ShaderFileParsers.cs | 6 +++- .../ShaderParsers/ShaderMethodParsers.cs | 8 +++-- 10 files changed, 79 insertions(+), 10 deletions(-) diff --git a/assets/Stride/SDSL/VoxelAttribute.sdsl b/assets/Stride/SDSL/VoxelAttribute.sdsl index 091060470e..0464c4b1db 100644 --- a/assets/Stride/SDSL/VoxelAttribute.sdsl +++ b/assets/Stride/SDSL/VoxelAttribute.sdsl @@ -7,5 +7,5 @@ shader VoxelAttribute void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride){} void IndirectWrite(RWBuffer buffer, uint address){} void DirectWrite(uint3 address, uint strideIndex, uint stride){} - float4 SampleLocal(){return float4(0,0,0,1);}; + float4 SampleLocal(){return float4(0,0,0,1);} }; diff --git a/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl b/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl index f5a2ee0801..d1d86dd1dd 100644 --- a/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl +++ b/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl @@ -6,5 +6,5 @@ shader VoxelStorageTextureShader float4 SampleNearestMip(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis){ return float4(0, 1, 0, 0); } float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis){ return float4(1, 0, 0, 0); } - float VoxelSize(){ return 1.0; }; + float VoxelSize(){ return 1.0; } }; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index d39e2f449b..169b0d78ff 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -44,13 +44,15 @@ public override string ToString() } } -public class ShaderMethod(TypeName returnType, Identifier name, TextLocation info, Identifier? visibility = null, Identifier? storage = null, bool isStaged = false, bool isAbstract = false, bool isVirtual = false, bool isOverride = false, bool isClone = false) : MethodOrMember(info, isStaged) +public class ShaderMethod(TypeName returnType, Identifier name, TextLocation info, Identifier? visibility = null, Identifier? storage = null, bool isStaged = false, bool isAbstract = false, bool isVirtual = false, bool isStatic = false, bool isOverride = false, bool isClone = false) : MethodOrMember(info, isStaged) { + public TypeName ReturnType { get; set; } = returnType; public Identifier Name { get; set; } = name; public Identifier? Visibility { get; set; } = visibility; public Identifier? Storage { get; set; } = storage; public bool? IsAbstract { get; set; } = isAbstract; + public bool IsStatic { get; set; } = isStatic; public bool? IsVirtual { get; set; } = isVirtual; public bool? IsOverride { get; set; } = isOverride; public bool? IsClone { get; set; } = isClone; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index 2564433283..2f99a52822 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -3,6 +3,16 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info); +public class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) +{ + public Identifier Name { get; set; } = name; + public TypeName Type { get; set; } = type; + + public override string ToString() + { + return $"typedef {Type} {Name}"; + } +} public abstract class ShaderBuffer(List name, TextLocation info) : ShaderElement(info) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index f621b855cc..d4474e2eb2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -66,6 +66,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann var position = scanner.Position; arraySize = null!; value = null!; + if ( LiteralsParser.TypeName(ref scanner, result, out typeName) && Spaces1(ref scanner, result, out _) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 6ad96cc9d8..dadeac7ecc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -47,6 +47,21 @@ public static bool Identifier(ref TScanner scanner, ParseResult result public static bool TypeName(ref TScanner scanner, ParseResult result, out TypeName typeName, in ParseError? orError = null) where TScanner : struct, IScanner => new TypeNameParser().Match(ref scanner, result, out typeName); + + public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, out TypeName parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + if(TypeName(ref scanner, result, out parsed)) + { + return true; + } + else if(Number(ref scanner, result, out var number)) + { + parsed = new TypeName(number.ToString(), number.Info, isArray: false); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); + } public static bool Number(ref TScanner scanner, ParseResult result, out NumberLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner @@ -226,7 +241,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('<'), withSpaces: true, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); - CommonParsers.Repeat(ref scanner, result, LiteralsParser.TypeName, out List generics, 1, withSpaces: true, separator: ","); + CommonParsers.Repeat(ref scanner, result, LiteralsParser.TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('>'), withSpaces: true, advance: true)) return CommonParsers.Exit(ref scanner, result, out name, position); name.Generics = generics; @@ -257,7 +272,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } } - else return false; + else return CommonParsers.Exit(ref scanner, result, out name, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index febe1674fc..6ee789fa2f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -72,7 +72,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var tmp = position; if (Terminals.Literal("internal", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; - if (Terminals.Literal("shader", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result,out _)) + if ( + ( + Terminals.Literal("shader", ref scanner, advance: true) + || Terminals.Literal("class", ref scanner, advance: true) + ) + && CommonParsers.Spaces1(ref scanner, result,out _)) { if ( LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 4419f6dff8..87429cfe17 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -9,7 +9,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (BufferParsers.Buffer(ref scanner, result, out var buffer)) + if(TypeDef(ref scanner, result, out var typeDef)) + { + parsed = typeDef; + return true; + } + else if (BufferParsers.Buffer(ref scanner, result, out var buffer)) { CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed = buffer; @@ -92,4 +97,27 @@ public static bool ShaderElement(ref TScanner scanner, ParseResult res public static bool Method(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); + + public static bool TypeDef(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + + if ( + Terminals.Literal("typedef", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.TypeName(ref scanner, result, out var type) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var name) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new TypeDef(type, name, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } + } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 9bee697424..6bb6049461 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -25,7 +25,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); } else if ( - (Terminals.Literal("shader", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["internal", "shader"])) + ( + Terminals.Literal("class", ref scanner) + || Terminals.Literal("shader", ref scanner) + || CommonParsers.SequenceOf(ref scanner, ["internal", "shader"]) + ) && ShaderClassParsers.Class(ref scanner, result, out var shader) ) { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index e47b497751..2efd43d5e2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -46,7 +46,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if(Terminals.AnyOf(["inout", "in", "out", "triangle"], ref scanner, out var storage, advance: true)) + if(Terminals.AnyOf(["inout", "in", "out", "triangle", "const"], ref scanner, out var storage, advance: true)) CommonParsers.Spaces1(ref scanner, result, out _); if(CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) ) @@ -132,21 +132,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else scanner.Position = position; - if (Terminals.AnyOf(["clone", "override"], ref scanner, out var matched, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Terminals.AnyOf(["clone", "override", "static"], ref scanner, out var matched, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { var isClone = false; var isOverride = false; + var isStatic = false; var tmpPos = scanner.Position; if (matched == "clone") isClone = true; else if (matched == "override") isOverride = true; + else if (matched == "static") + isStatic = true; CommonParsers.Spaces0(ref scanner, result, out _); if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { parsed.IsClone = isClone; parsed.IsOverride = isOverride; + parsed.IsStatic = isStatic; parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } From 7d5638f2474594c1129372c34c7ba8e376c3de2a Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Fri, 1 Nov 2024 23:45:31 +0100 Subject: [PATCH 0350/1182] correcting things slowly --- .../Program.cs | 2 +- .../SDFX/AST/Effect.Flow.cs | 2 +- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 36 ++++++ .../SDFX/Parsers/EffectStatementParsers.cs | 105 +++++++++++++++--- .../SDSL/AST/Literals.cs | 25 +++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 24 ++++ .../SDSL/AST/ShaderElements.cs | 15 +++ .../SDSL/AST/Statements.Control.cs | 1 + .../SDSL/Parsers/Common/CommonParsers.cs | 45 ++++++++ .../PrimaryExpressionParsers.cs | 30 ++++- .../Parsers/LiteralParsers/LiteralParsers.cs | 26 ++++- .../Parsers/LiteralParsers/NumberParsers.cs | 22 +++- .../ShaderParsers/ShaderClassParser.cs | 2 +- .../ShaderParsers/ShaderDataParsers.cs | 54 ++++++++- .../ShaderParsers/ShaderElementParsers.cs | 62 +++++++++-- .../ShaderParsers/ShaderMethodParsers.cs | 15 +++ .../Parsers/ShaderParsers/ShaderParameters.cs | 4 +- .../StatementParsers.Control.cs | 7 +- .../StatementParsers/StatementParsers.cs | 54 +++++++-- .../SDSL/Parsers/Terminals/Terminals.cs | 2 + 20 files changed, 471 insertions(+), 62 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index e50642e62b..c6c5f72b56 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -6,7 +6,7 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -Grammar.Match("float(num) / 4294967295.0"); +Grammar.Match("{\nsamplePosition += BackfaceOffsets[lightIndex];}"); Examples.ParseSDSL(); Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs index 6c12356fc1..b51c1d9395 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info); @@ -8,7 +9,6 @@ public class EffectControl(If first, TextLocation info) : EffectFlow(info) public If If { get; set; } = first; public List ElseIfs { get; set; } = []; public Else? Else { get; set; } - public override string ToString() { return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 807e981f8c..cc1c4d54d3 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -17,6 +17,18 @@ public override string ToString() public abstract class EffectStatement(TextLocation info) : Node(info); + +public class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) +{ + public Identifier Name { get; set; } = name; + public Expression? Value { get; set; } = value; + public bool IsCollection => Name.Name.Contains("Collection"); + public override string ToString() + { + return $"ShaderSourceCollection {Name} = {Value}"; + } +} + public class EffectStatementBlock(TextLocation info) : EffectStatement(info) { public List Statements { get; set; } = []; @@ -35,6 +47,23 @@ public override string ToString() return $"mixin {MixinName}"; } } +public class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) +{ + public Mixin MixinName { get; set; } = mixin; + public override string ToString() + { + return $"mixin child {MixinName}"; + } +} + +public class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) +{ + public Mixin MixinName { get; set; } = mixin; + public override string ToString() + { + return $"mixin clone {MixinName}"; + } +} public class MixinConst(string identifier, TextLocation info) : EffectStatement(info) { @@ -47,6 +76,13 @@ public class MixinCompose(Identifier identifier, Mixin mixin, TextLocation info) { public Identifier Identifier { get; set; } = identifier; public Mixin MixinName { get; set; } = mixin; + + + public MixinCompose(Identifier identifier, Expression value, TextLocation info) : this(identifier, new Mixin(new(value.ToString(), value.Info), value.Info), info) + { + + } + public override string ToString() { return $"mixin compose {Identifier} = {MixinName}"; diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 1356c411a8..fcb2d509d9 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -20,7 +20,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p1; return true; } - else if (MixinCompose(ref scanner, result, out var p2, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinCompose(ref scanner, result, out var p2, orError)) { parsed = p2; return true; @@ -30,14 +30,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = mca; return true; } - else if (MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinChild(ref scanner, result, out var mc, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - parsed = p3; + parsed = mc; return true; } - else if (MixinConst(ref scanner, result, out var mc, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinClone(ref scanner, result, out var mcl, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - parsed = mc; + parsed = mcl; + return true; + } + else if (MixinConst(ref scanner, result, out var mconst, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = mconst; + return true; + } + else if (MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = p3; return true; } else if (EffectControlsParser.Control(ref scanner, result, out var control)) @@ -50,6 +60,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = flow; return true; } + else if (ShaderSourceDeclaration(ref scanner, result, out var ssd, orError)) + { + parsed = ssd; + return true; + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -63,6 +78,34 @@ public static bool MixinComposeAdd(ref TScanner scanner, ParseResult r => new MixinComposeAddParser().Match(ref scanner, result, out parsed, orError); public static bool MixinUse(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinUseParser().Match(ref scanner, result, out parsed, orError); + public static bool MixinChild(ref TScanner scanner, ParseResult result, out MixinChild parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.SequenceOf(ref scanner, ["mixin", "child"], advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + ) + { + parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + public static bool MixinClone(ref TScanner scanner, ParseResult result, out MixinClone parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.SequenceOf(ref scanner, ["mixin", "clone"], advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + ) + { + parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } public static bool MixinConst(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinConstParser().Match(ref scanner, result, out parsed, orError); public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -86,6 +129,21 @@ public static bool EffectBlock(ref TScanner scanner, ParseResult resul } return CommonParsers.Exit(ref scanner, result, out parsed, position); } + public static bool ShaderSourceDeclaration(ref TScanner scanner, ParseResult result, out ShaderSourceDeclaration parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.AnyOf(["ShaderSourceCollection ", "ShaderSource "], ref scanner, out _) + && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var arraySize, out var value) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new(name, scanner.GetLocation(position..scanner.Position), value); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position); + } + } @@ -138,23 +196,29 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('=', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) ) { + var paren = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); if ( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + && paren == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { parsed = new(name, mixin, scanner.GetLocation(position..scanner.Position)); return true; } + else if( + CommonParsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression postfix, withSpaces: true, advance: true) + && paren == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new(name, postfix, scanner.GetLocation(position..scanner.Position)); + return true; + } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -191,12 +255,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Terminals.Literal("mixin", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) - && ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) ) { - parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); - return true; + var betweenParenthesis = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); + if (ShaderClassParsers.Mixin(ref scanner, result, out var mixin)) + { + var checkParen = betweenParenthesis == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true); + var finished = CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true); + if (finished && checkParen) + { + parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + return finished; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index c35e841abf..e36605a92b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -14,7 +14,7 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override string ToString( ) + public override string ToString() { return $"\"{Value}\""; } @@ -45,9 +45,10 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info); public class UnsignedIntegerLiteral(Suffix suffix, ulong value, TextLocation info) : NumberLiteral(suffix, value, info); -public sealed class FloatLiteral(Suffix suffix, double value, TextLocation info) : NumberLiteral(suffix, value, info) +public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) { - public static implicit operator FloatLiteral(double v) => new(new(), v, new()); + public int? Exponent { get; set; } = exponent; + public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); } public sealed class HexLiteral(ulong value, TextLocation info) : UnsignedIntegerLiteral(new(32, false, false), value, info); @@ -70,25 +71,31 @@ public override string ToString() } -public abstract class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : ValueLiteral(info) +public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : ValueLiteral(info) { public TypeName TypeName { get; set; } = typeName; public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; + public List Values { get; set; } = []; + public override string ToString() + { + return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + } } -public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : MatrixLiteral(typeName, rows, cols, info) - where TValueLiteral : ValueLiteral -{ - public List Values { get; set; } = []; +public class ArrayLiteral(TextLocation info) : ValueLiteral(info) +{ + public List Values { get; set; } = []; public override string ToString() { - return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + return $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; } } + + public class Identifier(string name, TextLocation info) : Literal(info) { public string Name { get; set; } = name; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 169b0d78ff..9ad55d01ed 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,6 +7,30 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : public List Attributes { get; set; } = []; } + +public class SamplerStateAssign(Identifier name, Expression value, TextLocation info) : ShaderElement(info) +{ + public Identifier Name { get; set; } = name; + public Expression Value { get; set; } = value; + + public override string ToString() + { + return $"{Name} = {Value}"; + } +} + +public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMember(info) +{ + public Identifier Name { get; set; } = name; + public List Members { get; set; } = []; + + public override string ToString() + { + return $"SamplerState {Name} ({string.Join(", ", Members)})"; + } +} + + public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index 2f99a52822..f9f23b42ce 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -3,6 +3,19 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info); + +public class ShaderConstant(TypeName type, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) +{ + public TypeName Type { get; set; } = type; + public Identifier Name { get; set; } = name; + public Expression? Value { get; set; } = value; + + public override string ToString() + { + return $"{Type} {Name} = {Value}"; + } +} + public class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; @@ -23,6 +36,7 @@ public class ShaderStructMember(TypeName typename, Identifier identifier, TextLo { public TypeName TypeName { get; set; } = typename; public Identifier Name { get; set; } = identifier; + public List Attributes { get; set; } = []; public override string ToString() { @@ -41,6 +55,7 @@ public override string ToString() } } + public sealed class CBuffer(List name, TextLocation info) : ShaderBuffer(name, info) { public List Members { get; set; } = []; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs index 78f09b5fd2..980c17b6ee 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs @@ -9,6 +9,7 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public If If { get; set; } = first; public List ElseIfs { get; set; } = []; public Else? Else { get; set; } + public ShaderAttributeList? Attributes { get; set; } public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index d4474e2eb2..10e9b875e8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -60,6 +60,51 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult result, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + arraySize = null!; + value = null!; + + if (LiteralsParser.Identifier(ref scanner, result, out identifier)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('[', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && Optional(ref scanner, new ExpressionParser(), result, out arraySize) + && Spaces0(ref scanner, result, out _) + && Terminals.Char(']', ref scanner, advance: true) + ) + ) + { + scanner.Position = tmp; + } + tmp = scanner.Position; + if ( + !( + FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + else + { + scanner.Position = position; + identifier = null!; + arraySize = null!; + return false; + } + } public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index eaac3a1134..6a3c8c7ecc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -1,3 +1,4 @@ +using System.Security.AccessControl; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -10,6 +11,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Parenthesis(ref scanner, result, out parsed)) return true; + else if (ArrayLiteral(ref scanner, result, out parsed)) + return true; else if (Method(ref scanner, result, out parsed)) return true; else if (LiteralsParser.Literal(ref scanner, result, out var lit)) @@ -36,6 +39,9 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParenthesisExpressionParser().Match(ref scanner, result, out parsed, in orError); + public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ArrayLiteralParser().Match(ref scanner, result, out parsed, in orError); } @@ -71,7 +77,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { ParameterParsers.Values(ref scanner, result, out var parameters); CommonParsers.Spaces0(ref scanner, result, out _); - if(Terminals.Char(')', ref scanner, advance: true)) + if (Terminals.Char(')', ref scanner, advance: true)) { parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); return true; @@ -80,4 +86,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } +} + +public record struct ArrayLiteralParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('{', ref scanner, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ParameterParsers.Values, out ShaderExpressionList values, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) + ) + { + parsed = new ArrayLiteral(scanner.GetLocation(position..scanner.Position)) + { + Values = values.Values + }; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index dadeac7ecc..6148294648 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -35,6 +35,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o literal = n; return true; } + else if (Boolean(ref scanner, result, out var b, orError)) + { + literal = b; + return true; + } else return CommonParsers.Exit(ref scanner, result, out literal, position, orError); } public static bool Literal(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) @@ -63,9 +68,21 @@ public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult else return CommonParsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); } + public static bool Boolean(ref TScanner scanner, ParseResult result, out BoolLiteral number, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if(Terminals.AnyOf(["true", "false"], ref scanner, out var matched, advance: true)) + { + number = new(matched == "true", scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out number, scanner.Position, orError); + } public static bool Number(ref TScanner scanner, ParseResult result, out NumberLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner => new NumberParser().Match(ref scanner, result, out number, in orError); + public static bool Vector(ref TScanner scanner, ParseResult result, out VectorLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new VectorParser().Match(ref scanner, result, out parsed, in orError); @@ -365,17 +382,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('(', ref scanner, advance: true)) { - var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), rows, cols, scanner.GetLocation(..)) + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), rows, cols, scanner.GetLocation(..)) { TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) }; while (!scanner.IsEof) { CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Number(ref scanner, result, out var number)) - p.Values.Add(number); - else if (LiteralsParser.Vector(ref scanner, result, out var vector, new(SDSLParsingMessages.SDSL0007, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + + if (LiteralsParser.Vector(ref scanner, result, out var vector)) p.Values.Add(vector); + else if (ExpressionParser.Expression(ref scanner, result, out var expression)) + p.Values.Add(expression); else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(',', ref scanner, advance: true)) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 6103d14cce..789fe253bb 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -87,9 +87,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); while (Terminals.Digit(ref scanner, advance: true)) ; } - else if (!Terminals.FloatSuffix(ref scanner, out _)) - return CommonParsers.Exit(ref scanner, result, out node, position); - else return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else if (Terminals.FloatSuffix(ref scanner, out _) || Terminals.Char('e', ref scanner)){} + else return CommonParsers.Exit(ref scanner, result, out node, position); } else if (Terminals.Digit(ref scanner, 0, advance: true)) { @@ -105,13 +104,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var value = double.Parse(scanner.Span[position..scanner.Position]); + int? exponent = null; + if (Terminals.Char('e', ref scanner, advance: true)) + { + var signed = Terminals.AnyOf(["+", "-"], ref scanner, out var matched, advance: true); + if (LiteralsParser.Integer(ref scanner, result, out var exp)) + { + exponent = (int)exp.Value; + if(signed && matched == "-") + exponent = -exponent; + } + else return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } if (Terminals.FloatSuffix(ref scanner, out var suffix, advance: true) && suffix is not null) - node = new(suffix.Value, value, scanner.GetLocation(position..scanner.Position)); + node = new(suffix.Value, value, exponent, scanner.GetLocation(position..scanner.Position)); else - node = new(new(32, true, true), value, scanner.GetLocation(position..scanner.Position)); + node = new(new(32, true, true), value, exponent, scanner.GetLocation(position..scanner.Position)); return true; } } + public struct HexParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out HexLiteral node, in ParseError? orError = null) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 6ee789fa2f..b8fb75ea7e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -23,7 +23,7 @@ public static bool ComplexClass(ref TScanner scanner, ParseResult resu public static bool GenericsDefinition(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed) where TScanner : struct, IScanner => new ShaderGenericsDefinitionParser().Match(ref scanner, result, out parsed); - public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed) + public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderMixinParser().Match(ref scanner, result, out parsed); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 94335644bc..49717b6c75 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -60,6 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); parsed = new ShaderStruct(identifier, scanner.GetLocation(position..)); CommonParsers.Repeat(ref scanner, new ShaderStructMemberParser(), result, out var members, 0, withSpaces: true, separator: ";"); + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed.Members = members; if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) { @@ -72,20 +73,69 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } + +public record struct ShaderSamplerStateParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("SamplerState", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + ) + { + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + { + Members = assignments + }; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new SamplerStateAssign(identifier, expression, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} public record struct ShaderStructMemberParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderStructMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes); if ( - LiteralsParser.TypeName(ref scanner, result, out var typename) + CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier) + && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) ) { parsed = new ShaderStructMember(typename, identifier, scanner.GetLocation(position..scanner.Position)); + if (hasAttributes) + parsed.Attributes = attributes.Attributes; return true; } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 87429cfe17..8aa2b68e8c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -9,18 +9,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if(TypeDef(ref scanner, result, out var typeDef)) + if (TypeDef(ref scanner, result, out var typeDef)) { parsed = typeDef; return true; } + else if (Constant(ref scanner, result, out var cst)) + { + parsed = cst; + return true; + } else if (BufferParsers.Buffer(ref scanner, result, out var buffer)) { CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed = buffer; return true; } - else if(Struct(ref scanner, result, out var structElement)) + else if (Struct(ref scanner, result, out var structElement)) { CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed = structElement; @@ -33,7 +38,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o bool isStreamed = false; bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); var tmpPos = scanner.Position; - #warning override keyword should always happen after stage and stream +#warning override keyword should always happen after stage and stream if (Terminals.Literal("override", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { isOverride = true; @@ -52,10 +57,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o isStreamed = true; else scanner.Position = tmpPos; - if(Compose(ref scanner, result, out var compose)) + if (SamplerState(ref scanner, result, out var samplerState)) + { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed = samplerState; + return true; + } + else if (Compose(ref scanner, result, out var compose)) { compose.IsStaged = isStaged; - if(hasAttributes) + if (hasAttributes) compose.Attributes = attributes.Attributes; parsed = compose; return true; @@ -64,7 +75,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { method.IsOverride = isOverride; method.IsStaged = isStaged; - if(hasAttributes) + if (hasAttributes) method.Attributes = attributes.Attributes; parsed = method; return true; @@ -73,16 +84,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { member.IsStream = isStreamed; member.IsStaged = isStaged; - if(hasAttributes) + if (hasAttributes) member.Attributes = attributes.Attributes; parsed = member; return true; } - - + + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } - + } public static bool Compose(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -90,6 +101,9 @@ public static bool Compose(ref TScanner scanner, ParseResult result, o public static bool Struct(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderStructParser().Match(ref scanner, result, out parsed, in orError); + public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderSamplerStateParser().Match(ref scanner, result, out parsed, in orError); public static bool ShaderElement(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderElementParsers().Match(ref scanner, result, out parsed, in orError); @@ -98,6 +112,34 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou where TScanner : struct, IScanner => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); + public static bool Constant(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + ( + CommonParsers.SequenceOf(ref scanner, ["static", "const"], advance: true) + || Terminals.Literal("const", ref scanner, advance: true) + ) + && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new ShaderConstant(type, name, value, scanner.GetLocation(position..scanner.Position)); + return true; + } + else if( + CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out type, out name, out arraySize, out value) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new ShaderConstant(type, name, value, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + + } + public static bool TypeDef(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 2efd43d5e2..f9e43200e9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -33,6 +33,21 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult where TScanner : struct, IScanner { var position = scanner.Position; + #warning We should not allow void to be a parameter, this is legacy C code + if( + CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + || + ( + CommonParsers.FollowedBy(ref scanner, Terminals.Literal("void"), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + ) + ) + { + parsed = []; + return true; + } + else + if(CommonParsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) { parsed = parameters; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 049c2fbff0..223d83a659 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -63,9 +63,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o values.Add(expr); else if (LiteralsParser.StringLiteral(ref scanner, result, out var str)) values.Add(str); - else if (values.Count == 0) + else break; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } while (!scanner.IsEof && CommonParsers.FollowedBy(ref scanner, Terminals.Char(','), advance: true)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 9439c1ba2a..4846f10032 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -10,9 +10,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; + if(ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributeList)) + CommonParsers.Spaces0(ref scanner, result, out _); if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) { - parsed = new(ifstatement, scanner.GetLocation(..)); + parsed = new(ifstatement, scanner.GetLocation(..)) + { + Attributes = attributeList + }; while(ElseIf(ref scanner, result, out var elseif, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 064e08fe79..5f0e14063e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -29,9 +29,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; else if (Declare(ref scanner, result, out parsed)) return true; - else if (Assignments(ref scanner, result, out parsed)) + else if (!Terminals.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) return true; - else if (Expression(ref scanner, result, out parsed)) + else if (!Terminals.Char('{', ref scanner) && Expression(ref scanner, result, out parsed)) return true; else if (Block(ref scanner, result, out parsed)) return true; @@ -127,16 +127,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if ( Terminals.Literal("return", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) ) { - if (Terminals.Char(';', ref scanner, advance: true)) + + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = new Return(scanner.GetLocation(position..scanner.Position)); return true; } else if ( - ExpressionParser.Expression(ref scanner, result, out var val) + PrimaryParsers.Parenthesis(ref scanner, result, out var p) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(';', ref scanner, advance: true) + ) + { + parsed = new Return(scanner.GetLocation(position, scanner.Position - position), p); + return true; + } + else if ( + CommonParsers.Spaces1(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var val) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner, advance: true) ) @@ -145,8 +155,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0041, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - - } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -245,7 +253,33 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - if (PostfixParser.Postfix(ref scanner, result, out var identifier)) + if (CommonParsers.IdentifierArraySizeValue(ref scanner, result, out var identifier, out var arraySisze, out var value, advance: true)) + { + if ( + CommonParsers.FollowedBy( + ref scanner, + result, + (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), + out var op, + withSpaces: true, + advance: true) + ) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression)) + { + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); + } + else + { + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)); + return true; + } + } + else if(PostfixParser.Postfix(ref scanner, result, out var p)) { if ( CommonParsers.FollowedBy( @@ -283,7 +317,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - var isConst = Terminals.Literal("const", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + var isConst = + Terminals.Literal("const", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) + || CommonParsers.SequenceOf(ref scanner, ["static", "const"], advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); if (!isConst) scanner.Position = position; if ( diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs index 03f38d88e7..dfcc8c8144 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -71,6 +71,8 @@ public static bool EOF(ref TScanner scanner) where TScanner : struct, IScanner => new EOFTerminalParser().Match(ref scanner, false); + + public static bool FloatSuffix(ref TScanner scanner, out Suffix? suffix, bool advance = false) where TScanner : struct, IScanner { From 0299777c360b71e2d762959169ea5e0a1b6a77c3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 2 Nov 2024 00:09:05 +0100 Subject: [PATCH 0351/1182] added Sampler comparison state --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 10 +++ .../SDSL/Parsers/Common/CommonParsers.cs | 7 +- .../ShaderParsers/ShaderDataParsers.cs | 72 +++++++++++++++++-- .../ShaderParsers/ShaderElementParsers.cs | 9 +++ .../ShaderParsers/ShaderMethodParsers.cs | 2 +- .../StatementParsers/StatementParsers.cs | 2 +- 6 files changed, 93 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 9ad55d01ed..b6ca0d0c22 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -29,6 +29,16 @@ public override string ToString() return $"SamplerState {Name} ({string.Join(", ", Members)})"; } } +public class ShaderSamplerComparisonState(Identifier name, TextLocation info) : MethodOrMember(info) +{ + public Identifier Name { get; set; } = name; + public List Members { get; set; } = []; + + public override string ToString() + { + return $"SamplerState {Name} ({string.Join(", ", Members)})"; + } +} public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 10e9b875e8..32e369b148 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -60,14 +60,17 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult result, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) + public static bool IdentifierArraySizeOptionalValue(ref TScanner scanner, ParseResult result, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; arraySize = null!; value = null!; - if (LiteralsParser.Identifier(ref scanner, result, out identifier)) + if ( + LiteralsParser.Identifier(ref scanner, result, out identifier) + && !FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true, advance: true) + ) { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 49717b6c75..b74c5e9149 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -83,20 +83,82 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Terminals.Literal("SamplerState", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var identifier) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) + &&CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + { + Members = assignments + }; + return true; + } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new SamplerStateAssign(identifier, expression, scanner.GetLocation(position..scanner.Position)); + return true; + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ShaderSamplerComparisonStateParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderSamplerComparisonState parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Literal("SamplerComparisonState", ref scanner, advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier) + + ) + { + if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) + &&CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) { Members = assignments }; return true; } + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + { + parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + return true; + } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 8aa2b68e8c..a5906911b0 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -63,6 +63,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = samplerState; return true; } + else if (SamplerComparisonState(ref scanner, result, out var samplerCompState)) + { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed = samplerCompState; + return true; + } else if (Compose(ref scanner, result, out var compose)) { compose.IsStaged = isStaged; @@ -104,6 +110,9 @@ public static bool Struct(ref TScanner scanner, ParseResult result, ou public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderSamplerStateParser().Match(ref scanner, result, out parsed, in orError); + public static bool SamplerComparisonState(ref TScanner scanner, ParseResult result, out ShaderSamplerComparisonState parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ShaderSamplerComparisonStateParser().Match(ref scanner, result, out parsed, in orError); public static bool ShaderElement(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderElementParsers().Match(ref scanner, result, out parsed, in orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index f9e43200e9..d88fd8027e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -61,7 +61,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if(Terminals.AnyOf(["inout", "in", "out", "triangle", "const"], ref scanner, out var storage, advance: true)) + if(Terminals.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) CommonParsers.Spaces1(ref scanner, result, out _); if(CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) ) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 5f0e14063e..5807a99d4b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -253,7 +253,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - if (CommonParsers.IdentifierArraySizeValue(ref scanner, result, out var identifier, out var arraySisze, out var value, advance: true)) + if (CommonParsers.IdentifierArraySizeOptionalValue(ref scanner, result, out var identifier, out var arraySisze, out var value, advance: true)) { if ( CommonParsers.FollowedBy( From e0a5d83fb63fcafead194648e878b9addfe26c03 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 2 Nov 2024 14:33:05 +0100 Subject: [PATCH 0352/1182] Update parsers for type array parsing --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../SDSL/AST/ShaderElements.cs | 58 ++++++++++++++++++- .../SDSL/AST/Statements.Flow.cs | 1 + .../SDSL/Parsers/Common/CommonParsers.cs | 53 +++++++++-------- .../ShaderParsers/ShaderBufferParsers.Cs | 10 +--- .../ShaderParsers/ShaderDataParsers.cs | 8 +-- .../ShaderParsers/ShaderElementParsers.cs | 42 +++++++++----- .../StatementParsers/StatementParsers.cs | 20 ++++++- 8 files changed, 137 insertions(+), 59 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b6ca0d0c22..62ff2aee89 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -49,14 +49,14 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, Expression? arraySize = null) : MethodOrMember(location, isStaged) +public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, List? arraySizes = null) : MethodOrMember(location, isStaged) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; public bool IsStream { get; set; } = isStream; public bool IsArray { get; set; } = isArray; - public Expression? ArraySize { get; set; } = arraySize; + public List? ArraySizes { get; set; } = arraySizes; public Expression? Value { get; set; } = initialValue; public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index f9f23b42ce..11309c2c47 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -4,15 +4,67 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info); -public class ShaderConstant(TypeName type, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) +public enum StorageClass +{ + None, + Extern, + NoInterpolation, + Precise, + Shared, + GroupShared, + Static, + Uniform, + Volatile +} + +public enum TypeModifier +{ + None, + Const, + RowMajor, + ColumnMajor +} + +public static class ShaderVariableInformationExtensions +{ + public static StorageClass ToStorageClass(this string str) + { + return str switch + { + "extern" => StorageClass.Extern, + "nointerpolation" => StorageClass.NoInterpolation, + "precise" => StorageClass.Precise, + "shared" => StorageClass.Shared, + "groupshared" => StorageClass.GroupShared, + "static" => StorageClass.Static, + "uniform" => StorageClass.Uniform, + "volatile" => StorageClass.Volatile, + _ => StorageClass.None + }; + } + + public static TypeModifier ToTypeModifier(this string str) + { + return str switch + { + "const" => TypeModifier.Const, + "row_major" => TypeModifier.RowMajor, + "column_major" => TypeModifier.ColumnMajor, + _ => TypeModifier.None + }; + } +} + +public class ShaderVariable(TypeName type, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; public Expression? Value { get; set; } = value; - + public StorageClass StorageClass { get; set; } = StorageClass.None; + public TypeModifier TypeModifier { get; set; } = TypeModifier.None; public override string ToString() { - return $"{Type} {Name} = {Value}"; + return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " :"")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " :"")}{Type} {Name} = {Value}"; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs index 484336f1bf..3dfba8ffa0 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs @@ -4,6 +4,7 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info); +public class Discard(TextLocation info) : Statement(info); public class Continue(TextLocation info) : Statement(info); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 32e369b148..c83a4252ee 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -60,11 +60,11 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult result, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) + public static bool IdentifierArraySizeOptionalValue(ref TScanner scanner, ParseResult result, out Identifier identifier, out List arraySizes, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; - arraySize = null!; + arraySizes = null!; value = null!; if ( @@ -74,15 +74,7 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); - if ( - !( - Terminals.Char('[', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && Optional(ref scanner, new ExpressionParser(), result, out arraySize) - && Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - ) + if (!FollowedByDelList(ref scanner, result, ArraySizes, out arraySizes, withSpaces: true, advance: true)) { scanner.Position = tmp; } @@ -104,11 +96,11 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann { scanner.Position = position; identifier = null!; - arraySize = null!; + arraySizes = null!; return false; } } - public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out Expression? arraySize, out Expression? value, bool advance = true) + public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; @@ -122,15 +114,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); - if ( - !( - Terminals.Char('[', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out arraySize) - && Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - ) + if (!FollowedByDelList(ref scanner, result, ArraySizes, out arraySize, withSpaces: true, advance: true)) { scanner.Position = tmp; } @@ -153,9 +137,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann scanner.Position = position; if ( LiteralsParser.TypeName(ref scanner, result, out typeName) - && FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true) - && ExpressionParser.Expression(ref scanner, result, out arraySize) - && FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) + && FollowedByDelList(ref scanner, result, ArraySizes, out List sizes, withSpaces: true, advance: true) && Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out identifier)) { @@ -183,6 +165,27 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann return false; } + public static bool ArraySizes(ref TScanner scanner, ParseResult result, out List arraySizes, in ParseError? orError = null) + where TScanner : struct, IScanner + { + arraySizes = []; + while (!scanner.IsEof) + { + if (FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true)) + { + if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) + { + arraySizes.Add(arraySize); + if (!FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true)) + return Exit(ref scanner, result, out arraySizes, scanner.Position); + } + else return Exit(ref scanner, result, out arraySizes, scanner.Position); + } + else break; + } + return true; + } + public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Mixin mixin, out Expression? arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index c2b9f36a81..278ef48a0f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -195,18 +195,14 @@ public record struct BufferMemberParser : IParser if (LiteralsParser.TypeName(ref scanner, result, out var typename1) && CommonParsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out Identifier name1) - && Terminals.Char('[', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out var arraySize) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) + && CommonParsers.FollowedByDelList(ref scanner, result, CommonParsers.ArraySizes, out List arraySizes, withSpaces:true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) ) { if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) { CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename1, name1, null, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySize: arraySize); + parsed = new ShaderMember(typename1, name1, null, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySizes: arraySizes); return true; } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) @@ -217,7 +213,7 @@ public record struct BufferMemberParser : IParser { if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) { - parsed = new ShaderMember(typename1, name1, expression, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySize: arraySize); + parsed = new ShaderMember(typename1, name1, expression, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySizes: arraySizes); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index b74c5e9149..fc09367b74 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -17,11 +17,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; TypeName? typeName = null!; - Expression? arraySize = null!; + List arraySizes = null!; Expression? value = null!; - if (!Terminals.Literal("compose", ref scanner) && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySize, out value)) + if (!Terminals.Literal("compose", ref scanner) && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) { if ( CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) @@ -30,14 +30,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typeName, identifier, value, arraySize != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySize: arraySize); + parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySizes: arraySizes); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typeName, identifier, value, arraySize != null, scanner.GetLocation(position..scanner.Position), arraySize: arraySize); + parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), arraySizes: arraySizes); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index a5906911b0..f9e2bb311e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -14,7 +14,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = typeDef; return true; } - else if (Constant(ref scanner, result, out var cst)) + else if (ShaderVariable(ref scanner, result, out var cst)) { parsed = cst; return true; @@ -121,28 +121,38 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou where TScanner : struct, IScanner => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); - public static bool Constant(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + public static bool ShaderVariable(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; + + var hasStorageClass = + Terminals.AnyOf( + ["extern", "nointerpolation", "precise", "shared", "groupshared", "static", "uniform", "volatile"], + ref scanner, + out var storageClass, + advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + ; + var hasTypeModifier = + Terminals.AnyOf( + ["const", "row_major", "column_major"], + ref scanner, + out var typemodifier, + advance: true) + && CommonParsers.Spaces1(ref scanner, result, out _) + ; + if( - ( - CommonParsers.SequenceOf(ref scanner, ["static", "const"], advance: true) - || Terminals.Literal("const", ref scanner, advance: true) - ) - && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) + CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { - parsed = new ShaderConstant(type, name, value, scanner.GetLocation(position..scanner.Position)); - return true; - } - else if( - CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out type, out name, out arraySize, out value) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) - ) - { - parsed = new ShaderConstant(type, name, value, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderVariable(type, name, value, scanner.GetLocation(position..scanner.Position)) + { + StorageClass = storageClass.ToStorageClass(), + TypeModifier = typemodifier.ToTypeModifier() + }; return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 5807a99d4b..9d94b3a909 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -23,16 +23,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (Break(ref scanner, result, out parsed)) return true; + else if (Discard(ref scanner, result, out parsed)) + return true; else if (Return(ref scanner, result, out parsed)) return true; else if (Continue(ref scanner, result, out parsed)) return true; else if (Declare(ref scanner, result, out parsed)) return true; - else if (!Terminals.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) - return true; else if (!Terminals.Char('{', ref scanner) && Expression(ref scanner, result, out parsed)) return true; + else if (!Terminals.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) + return true; else if (Block(ref scanner, result, out parsed)) return true; return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -49,6 +51,20 @@ internal static bool Block(ref TScanner scanner, ParseResult result, o internal static bool Break(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new BreakParser().Match(ref scanner, result, out parsed, orError); + internal static bool Discard(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new Discard(scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } internal static bool Return(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ReturnStatementParser().Match(ref scanner, result, out parsed, orError); From f37a57b79f87bfc9e779a1d71c112f060a055beb Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 3 Nov 2024 00:00:49 +0100 Subject: [PATCH 0353/1182] Small corrections on parsing statements and primaries --- .../Program.cs | 10 +++- .../SDFX/Parsers/EffectStatementParsers.cs | 1 + .../SDSL/AST/Expression.cs | 9 +++ .../SDSL/AST/Literals.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 3 +- .../SDSL/AST/ShaderElements.cs | 21 +++++++ .../SDSL/AST/Statements.cs | 28 +++++++++- .../SDSL/Parsers/Common/CommonParsers.cs | 20 +++++++ .../ExpressionParsers/BinaryParsers.cs | 20 +++---- .../PrimaryExpressionParsers.cs | 24 ++++++-- .../ExpressionParsers/UnaryParsers.Postfix.cs | 56 ++++++++----------- .../ShaderParsers/ShaderClassParser.cs | 4 +- .../ShaderParsers/ShaderDataParsers.cs | 1 + .../ShaderParsers/ShaderElementParsers.cs | 37 +++++++----- .../ShaderParsers/ShaderMethodParsers.cs | 1 + .../Parsers/ShaderParsers/ShaderParameters.cs | 4 +- .../StatementParsers/StatementParsers.cs | 46 +++++++++++---- 17 files changed, 203 insertions(+), 84 deletions(-) diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index c6c5f72b56..647d95ff64 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -6,7 +6,11 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -Grammar.Match("{\nsamplePosition += BackfaceOffsets[lightIndex];}"); -Examples.ParseSDSL(); +var matched = Grammar.Match("if(depth < 0 || depth > 1)\n return 1;"); +foreach(var e in matched.Errors) + Console.WriteLine(e); +Console.WriteLine(matched.AST); -Examples.TryAllFiles(); \ No newline at end of file +// Examples.ParseSDSL(); + +// Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index fcb2d509d9..38171b7666 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -138,6 +138,7 @@ public static bool ShaderSourceDeclaration(ref TScanner scanner, Parse && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { + typename.ArraySize = arraySize; parsed = new(name, scanner.GetLocation(position..scanner.Position), value); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs index 9a04f7a371..f741c0d4b9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs @@ -16,6 +16,15 @@ public override string ToString() } } +public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) +{ + public Mixin Mixin { get; set; } = mixin; + public override string ToString() + { + return $"{Mixin}"; + } +} + public abstract class UnaryExpression(Expression expression, Operator op, TextLocation info) : Expression(info) { diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index e36605a92b..8c579f583b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -112,7 +112,7 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in { public string Name { get; set; } = name; public bool IsArray { get; set; } = isArray; - public Expression? ArraySize { get; set; } + public List? ArraySize { get; set; } public List Generics { get; set; } = []; public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 62ff2aee89..e7bdeef020 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -49,7 +49,7 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, List? arraySizes = null) : MethodOrMember(location, isStaged) +public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, List? arraySizes = null, InterpolationModifier interpolation = InterpolationModifier.None) : MethodOrMember(location, isStaged) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; @@ -58,6 +58,7 @@ public sealed class ShaderMember(TypeName type, Identifier name, Expression? ini public bool IsArray { get; set; } = isArray; public List? ArraySizes { get; set; } = arraySizes; public Expression? Value { get; set; } = initialValue; + public InterpolationModifier Interpolation { get; set; } = interpolation; public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index 11309c2c47..e3bea0148f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -24,9 +24,30 @@ public enum TypeModifier RowMajor, ColumnMajor } +public enum InterpolationModifier +{ + None, + Linear, + Centroid, + NoInterpolation, + NoPerspective, + Sample +} public static class ShaderVariableInformationExtensions { + public static InterpolationModifier ToInterpolationModifier(this string str) + { + return str switch + { + "linear" => InterpolationModifier.Linear, + "centroid" => InterpolationModifier.Centroid, + "nointerpolation" => InterpolationModifier.NoInterpolation, + "noperspective" => InterpolationModifier.NoPerspective, + "sample" => InterpolationModifier.Sample, + _ => InterpolationModifier.None + }; + } public static StorageClass ToStorageClass(this string str) { return str switch diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs index 5518afdb7f..e60b9283cb 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -48,10 +48,36 @@ public override string ToString() Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" }; } +public class DeclaredVariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +{ + public Expression Variable { get; set; } = variable; + public AssignOperator? Operator { get; set; } = op; + public Expression? Value { get; set; } = value; + public bool IsConst { get; set; } = isConst; + public TypeName TypeName { get; set; } = new("void", info, false); + public List? ArraySizes + { + get => TypeName.ArraySize; + set => TypeName.ArraySize = value; + } + + internal void ReplaceTypeName(TypeName typeName) + { + TypeName.Type = typeName.Type; + TypeName.Info = typeName.Info; + } + + public override string ToString() + => Value switch + { + null => Variable.ToString() ?? "", + Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" + }; +} public class Declare(TypeName typename, TextLocation info) : Declaration(typename, info) { - public List Variables { get; set; } = []; + public List Variables { get; set; } = []; public override string ToString() { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index c83a4252ee..473e5a058f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -293,6 +293,26 @@ public static bool FollowedBy(ref TScanner scanner, TTermin scanner.Position = position; return false; } + public static bool FollowedByAny(ref TScanner scanner, ReadOnlySpan literals, out string matched, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + foreach (var l in literals) + { + if (Terminals.Literal(l, ref scanner, advance: advance)) + { + if (!advance) + scanner.Position = position; + matched = l; + return true; + } + } + matched = null!; + scanner.Position = position; + return false; + } public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index d081352a80..97b177b42f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -105,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.And(ref scanner, result, out var and)) parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0022, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -136,7 +136,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BOr(ref scanner, result, out var bOr)) parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0024, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.XOr(ref scanner, result, out var xor)) parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0025, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -197,7 +197,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0026, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -227,7 +227,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0027, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -260,7 +260,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Relation(ref scanner, result, out var rel)) parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0028, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -291,7 +291,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Shift(ref scanner, result, out var shift)) parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0029, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -324,7 +324,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Add(ref scanner, result, out var add)) parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0030, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { @@ -355,7 +355,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (ExpressionParser.Mul(ref scanner, result, out var mul)) parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0031, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == '\0') { @@ -386,7 +386,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0042, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == '\0') { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 6a3c8c7ecc..f0375011f3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -9,23 +9,21 @@ public record struct PrimaryParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { + var position = scanner.Position; if (Parenthesis(ref scanner, result, out parsed)) return true; else if (ArrayLiteral(ref scanner, result, out parsed)) return true; else if (Method(ref scanner, result, out parsed)) return true; + else if (MixinAccess(ref scanner, result, out parsed)) + return true; else if (LiteralsParser.Literal(ref scanner, result, out var lit)) { parsed = lit; return true; } - else - { - if (orError is not null) - result.Errors.Add(orError.Value); - return false; - } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -42,6 +40,20 @@ public static bool Parenthesis(ref TScanner scanner, ParseResult resul public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ArrayLiteralParser().Match(ref scanner, result, out parsed, in orError); + public static bool MixinAccess(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) + ) + { + parsed = new MixinAccess(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 9d32a48a71..9c55aa88aa 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -9,50 +9,40 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - // If the following - if ( - Accessor(ref scanner, result, out parsed) - && CommonParsers.Spaces0(ref scanner, result, out _) - ) + if (PrimaryParsers.Primary(ref scanner, result, out parsed)) { - if (Terminals.Set("[.", ref scanner) || Terminals.Literal("++", ref scanner) || Terminals.Literal("--", ref scanner)) + while(!scanner.IsEof && CommonParsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out var matched, withSpaces: true, advance: true)) { - if (Terminals.Char('.', ref scanner, advance: true)) + if( + matched == "[" + && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression indexer, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) + ) { - if (Postfix(ref scanner, result, out var accessed)) - { - parsed = new AccessorExpression(parsed, accessed, scanner.GetLocation(position, scanner.Position)); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + parsed = new IndexerExpression(parsed, indexer, scanner.GetLocation(position..scanner.Position)); } - else if (Terminals.Char('[', ref scanner, advance: true)) + else if( + matched == "." + && CommonParsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression call, withSpaces: true, advance: true) + ) { - CommonParsers.Spaces0(ref scanner, result, out _); - if ( - ExpressionParser.Expression(ref scanner, result, out var index) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - { - parsed = new IndexerExpression(parsed, index, scanner.GetLocation(position, scanner.Position - position)); - return true; - } + parsed = new AccessorExpression(parsed, call, scanner.GetLocation(position..scanner.Position)); } - else if (Terminals.Literal("++", ref scanner, advance: true)) + else if( + matched == "." + && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Literal, out Literal accessor, withSpaces: true, advance: true) + ) { - parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); - return true; + parsed = new AccessorExpression(parsed, accessor, scanner.GetLocation(position..scanner.Position)); } - else if (Terminals.Literal("--", ref scanner, advance: true)) + else if(matched == "++" || matched == "--") { - parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); - return true; + parsed = new PostfixExpression(parsed, matched.ToOperator(), scanner.GetLocation(position..scanner.Position)); + break; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); - } - else return true; + CommonParsers.Spaces0(ref scanner, result, out _); + return true; } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index b8fb75ea7e..224cf06cf0 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -149,11 +149,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char('<', ref scanner, advance: true)) { - ParameterParsers.GenericsList(ref scanner, result, out var values, new("Expecting constant generics", scanner.GetErrorLocation(position), scanner.Memory)); + ParameterParsers.GenericsList(ref scanner, result, out var values); parsed.Generics = values; CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return CommonParsers.Exit(ref scanner, result, out parsed, position); return true; } else diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index fc09367b74..06728852bd 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -30,6 +30,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { + typeName.ArraySize = arraySizes; parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySizes: arraySizes); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index f9e2bb311e..194e794c55 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -9,6 +9,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; + + bool isOverride = false; + bool isStaged = false; + bool isStreamed = false; + bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); + var tmpPos = position; +#warning interpolation modifier should always be after stream/stage + var hasInterpolation = Terminals.AnyOf(["linear ", "centroid ", "nointerpolation", "noperspective", "sample"], ref scanner, out var interpolation, advance: true); + if (TypeDef(ref scanner, result, out var typeDef)) { parsed = typeDef; @@ -33,11 +42,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - bool isOverride = false; - bool isStaged = false; - bool isStreamed = false; - bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); - var tmpPos = scanner.Position; + + tmpPos = scanner.Position; #warning override keyword should always happen after stage and stream if (Terminals.Literal("override", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { @@ -57,6 +63,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o isStreamed = true; else scanner.Position = tmpPos; + if(!hasInterpolation) + hasInterpolation = Terminals.AnyOf(["linear ", "centroid ", "nointerpolation", "noperspective", "sample"], ref scanner, out interpolation, advance: true); if (SamplerState(ref scanner, result, out var samplerState)) { CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); @@ -90,6 +98,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { member.IsStream = isStreamed; member.IsStaged = isStaged; + if(hasInterpolation) + member.Interpolation = interpolation.ToInterpolationModifier(); if (hasAttributes) member.Attributes = attributes.Attributes; parsed = member; @@ -125,29 +135,30 @@ public static bool ShaderVariable(ref TScanner scanner, ParseResult re where TScanner : struct, IScanner { var position = scanner.Position; - - var hasStorageClass = + + var hasStorageClass = Terminals.AnyOf( - ["extern", "nointerpolation", "precise", "shared", "groupshared", "static", "uniform", "volatile"], - ref scanner, + ["extern", "nointerpolation", "precise", "shared", "groupshared", "static", "uniform", "volatile"], + ref scanner, out var storageClass, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) ; - var hasTypeModifier = + var hasTypeModifier = Terminals.AnyOf( ["const", "row_major", "column_major"], - ref scanner, + ref scanner, out var typemodifier, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) ; - if( + if ( CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { + type.ArraySize = arraySize; parsed = new ShaderVariable(type, name, value, scanner.GetLocation(position..scanner.Position)) { StorageClass = storageClass.ToStorageClass(), @@ -158,7 +169,7 @@ public static bool ShaderVariable(ref TScanner scanner, ParseResult re else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - + public static bool TypeDef(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index d88fd8027e..22f769a4c9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -66,6 +66,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r if(CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) ) { + typename.ArraySize = arraySize; parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 223d83a659..34e217281a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -43,7 +43,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parameters.Add(new(typename, name)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } while (!scanner.IsEof && Terminals.Char(',', ref scanner, advance: true)); parsed = new(scanner.GetLocation(position..scanner.Position)) { Parameters = parameters }; @@ -82,7 +82,7 @@ public record struct GenericsListParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter)) { parsed = new(scanner.GetLocation(position..scanner.Position)); parsed.Values.Add(parameter); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 9d94b3a909..28b696d9cf 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -56,7 +56,7 @@ internal static bool Discard(ref TScanner scanner, ParseResult result, { var position = scanner.Position; if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) + CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { @@ -103,6 +103,9 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new VariableAssignParser().Match(ref scanner, result, out parsed, orError); + internal static bool DeclaredVarAssign(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new DeclaredVariableAssignParser().Match(ref scanner, result, out parsed, orError); internal static bool Controls(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ControlsParser().Match(ref scanner, result, out parsed, orError); @@ -120,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if(Terminals.Char(';', ref scanner, advance : true)) + if (Terminals.Char(';', ref scanner, advance: true)) { parsed = new EmptyStatement(scanner.GetLocation(position..scanner.Position)); return true; @@ -145,7 +148,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Terminals.Literal("return", ref scanner, advance: true) ) { - + if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = new Return(scanner.GetLocation(position..scanner.Position)); @@ -268,8 +271,7 @@ public record struct VariableAssignParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - - if (CommonParsers.IdentifierArraySizeOptionalValue(ref scanner, result, out var identifier, out var arraySisze, out var value, advance: true)) + if (PostfixParser.Postfix(ref scanner, result, out var p)) { if ( CommonParsers.FollowedBy( @@ -284,18 +286,28 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression); + parsed = new(p, false, scanner.GetLocation(position..scanner.Position), op, expression); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); } else { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)); + parsed = new(p, false, scanner.GetLocation(position..scanner.Position)); return true; } } - else if(PostfixParser.Postfix(ref scanner, result, out var p)) + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } +} + +public record struct DeclaredVariableAssignParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + + if (CommonParsers.IdentifierArraySizeOptionalValue(ref scanner, result, out var identifier, out var arraySizes, out var value, advance: true)) { if ( CommonParsers.FollowedBy( @@ -310,14 +322,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression); + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression) + { + ArraySizes = arraySizes, + Value = value + }; return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); } else { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)); + parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)) + { + ArraySizes = arraySizes + }; return true; } } @@ -333,7 +352,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - var isConst = + var isConst = Terminals.Literal("const", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) || CommonParsers.SequenceOf(ref scanner, ["static", "const"], advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); if (!isConst) @@ -344,10 +363,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { - if (CommonParsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) + if (CommonParsers.Repeat(ref scanner, result, StatementParsers.DeclaredVarAssign, out List assigns, 1, true, ",")) { foreach (var a in assigns) + { a.IsConst = isConst; + a.ReplaceTypeName(typeName); + } CommonParsers.Spaces0(ref scanner, result, out _); if (Terminals.Char(';', ref scanner, advance: true)) { From 280ee10d0a3e185728c13d5336c97e539793a3ef Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:00:02 +0100 Subject: [PATCH 0354/1182] correction McIntosh shader + finalized SDSL parsing, onto SDFX parsing --- .../Stride/SDSL/McIntoshOptimizedShader.sdsl | 2 +- .../Program.cs | 2 +- .../ParsingTests.cs | 5 + .../SDFX/Parsers/EffectStatementParsers.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 9 +- .../SDSL/AST/ShaderElements.cs | 16 ++ .../SDSL/AST/Statements.Flow.cs | 8 +- .../SDSL/Parsers/Common/CommonParsers.cs | 197 +++++++++++++++++- .../ExpressionParsers/UnaryParsers.Prefix.cs | 12 +- .../Parsers/LiteralParsers/NumberParsers.cs | 4 +- .../ShaderParsers/CompositionParsers.cs | 34 +-- .../ShaderParsers/ShaderBufferParsers.Cs | 60 +----- .../ShaderParsers/ShaderDataParsers.cs | 37 +++- .../ShaderParsers/ShaderElementParsers.cs | 84 +++----- .../ShaderParsers/ShaderMethodParsers.cs | 58 +++--- .../StatementParsers/StatementParsers.Flow.cs | 21 +- 16 files changed, 351 insertions(+), 200 deletions(-) diff --git a/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl b/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl index 6b8c6c7b28..e8b5e8d252 100644 --- a/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl +++ b/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl @@ -3,7 +3,6 @@ namespace Stride.Rendering.Images { - compose DepthAwareDirectionalBlurShader blurShader; /// /// Optimized version of the McIntosh bokeh effect. @@ -14,6 +13,7 @@ namespace Stride.Rendering.Images /// shader McIntoshOptimizedShader : ImageEffectShader { + compose DepthAwareDirectionalBlurShader blurShader; compose ComputeColor directionalBlurA; compose ComputeColor directionalBlurB; diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 647d95ff64..1bbd295a06 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -6,7 +6,7 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -var matched = Grammar.Match("if(depth < 0 || depth > 1)\n return 1;"); +var matched = Grammar.Match("int uSeed = (int) (fSeed);"); foreach(var e in matched.Errors) Console.WriteLine(e); Console.WriteLine(matched.AST); diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs index 8adf083ee9..ba7ae85e71 100644 --- a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs +++ b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs @@ -11,6 +11,11 @@ public static IEnumerable GetShaderFilePaths() { yield return new object[] { file }; } + files = Directory.GetFiles("assets/Stride/SDFX", "*.sdfx"); + foreach (var file in files) + { + yield return new object[] { file }; + } } [Theory] diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 38171b7666..6266904500 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -203,7 +203,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var paren = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); if ( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + ExpressionParser.Expression(ref scanner, result, out var mixin) && paren == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e7bdeef020..c79c9a4d0a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -49,15 +49,17 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, bool isStream = false, Identifier? semantic = null, List? arraySizes = null, InterpolationModifier interpolation = InterpolationModifier.None) : MethodOrMember(location, isStaged) +public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, StreamKind streamKind = StreamKind.None, Identifier? semantic = null, List? arraySizes = null, InterpolationModifier interpolation = InterpolationModifier.None, StorageClass storageClass = StorageClass.None, TypeModifier typeModifier = TypeModifier.None) : MethodOrMember(location, isStaged) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; - public bool IsStream { get; set; } = isStream; + public StreamKind StreamKind { get; set; } = streamKind; public bool IsArray { get; set; } = isArray; public List? ArraySizes { get; set; } = arraySizes; public Expression? Value { get; set; } = initialValue; + public TypeModifier TypeModifier { get; set; } = typeModifier; + public StorageClass StorageClass { get; set; } = storageClass; public InterpolationModifier Interpolation { get; set; } = interpolation; public override string ToString() @@ -66,10 +68,11 @@ public override string ToString() } } -public class MethodParameter(TypeName type, Identifier name, TextLocation info, string? storage = null, Expression? arraySize = null) : Node(info) +public class MethodParameter(TypeName type, Identifier name, TextLocation info, string? storage = null, Expression? arraySize = null, Identifier? semantic = null) : Node(info) { public TypeName Type { get; set; } = type; public Identifier Name { get; set; } = name; + public Identifier? Semantic { get; set; } = semantic; public Expression? ArraySize { get; set; } = arraySize; public string? Storage { get; set; } = storage; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index e3bea0148f..b4987b3bcf 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -34,8 +34,24 @@ public enum InterpolationModifier Sample } +public enum StreamKind +{ + None, + Stream, + PatchStream +} + public static class ShaderVariableInformationExtensions { + public static StreamKind ToStreamKind(this string str) + { + return str switch + { + "stream" => StreamKind.Stream, + "patchstream" => StreamKind.PatchStream, + _ => StreamKind.None + }; + } public static InterpolationModifier ToInterpolationModifier(this string str) { return str switch diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs index 3dfba8ffa0..080dcb5689 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs @@ -22,10 +22,12 @@ public override string ToString() } -public class While(Expression condition, Statement body, TextLocation info) : Loop(info) +public class While(Expression condition, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; + public ShaderAttribute? Attribute { get; internal set; } = attribute; + public override string ToString() { return $"while({Condition})\n{Body}"; @@ -41,11 +43,11 @@ public enum ForAnnotationKind } public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); -public class For(Statement initializer, Statement cond, Statement update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +public class For(Statement initializer, Statement cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Statement Initializer { get; set; } = initializer; public Statement Condition { get; set; } = cond; - public Statement Update { get; set; } = update; + public List Update { get; set; } = update; public Statement Body { get; set; } = body; public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 473e5a058f..48affd54c8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -60,6 +60,135 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult result, out bool isStaged, out bool isStatic, out bool isClone, out bool isOverride, out bool isAbstract, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + isStaged = false; + isStatic = false; + isOverride = false; + isAbstract = false; + isClone = false; + bool matched = false; + // legacy + while ( + Terminals.AnyOf( + [ + "stage", + "override", + "clone", + "abstract", + "static" + ], + ref scanner, + out string match, + advance: true) + && Spaces1(ref scanner, result, out _)) + { + matched = true; + if(match == "stage") + isStaged = true; + else if(match == "override") + isOverride = true; + else if(match == "clone") + isClone = true; + else if(match == "abstract") + isAbstract = true; + else if(match == "static") + isStatic = true; + else break; + } + if(!advance) + scanner.Position = position; + return matched; + } + + public static bool VariableModifiers(ref TScanner scanner, ParseResult result, out bool isStaged, out StreamKind streamKind, out InterpolationModifier interpolation, out TypeModifier typeModifier, out StorageClass storageClass, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + isStaged = false; + streamKind = StreamKind.None; + interpolation = InterpolationModifier.None; + typeModifier = TypeModifier.None; + storageClass = StorageClass.None; + bool matched = false; + // legacy + while ( + Terminals.AnyOf( + [ + "stage", + "stream", + "patchstream", + "linear", + "centroid", + "nointerpolation", + "noperspective", + "sample", + "extern", + "nointerpolation", + "precise", + "shared", + "groupshared", + "static", + "uniform", + "volatile", + "const", + "rowmajor", + "columnmajor" + ], + ref scanner, + out string match, + advance: true) + && Spaces1(ref scanner, result, out _)) + { + matched = true; + if (match == "stage") + isStaged = true; + else if(match == "stream") + streamKind = StreamKind.Stream; + else if(match == "patchstream") + streamKind = StreamKind.PatchStream; + else if(match == "linear") + interpolation = InterpolationModifier.Linear; + else if(match == "centroid") + interpolation = InterpolationModifier.Centroid; + else if(match == "nointerpolation") + interpolation = InterpolationModifier.NoInterpolation; + else if(match == "noperspective") + interpolation = InterpolationModifier.NoPerspective; + else if(match == "sample") + interpolation = InterpolationModifier.Sample; + else if(match == "extern") + storageClass = StorageClass.Extern; + else if(match == "nointerpolation") + storageClass = StorageClass.NoInterpolation; + else if(match == "precise") + storageClass = StorageClass.Precise; + else if(match == "shared") + storageClass = StorageClass.Shared; + else if(match == "groupshared") + storageClass = StorageClass.GroupShared; + else if(match == "static") + storageClass = StorageClass.Static; + else if(match == "uniform") + storageClass = StorageClass.Uniform; + else if(match == "volatile") + storageClass = StorageClass.Volatile; + else if(match == "const") + typeModifier = TypeModifier.Const; + else if(match == "rowmajor") + typeModifier = TypeModifier.RowMajor; + else if(match == "columnmajor") + typeModifier = TypeModifier.ColumnMajor; + else break; + } + if(!advance) + scanner.Position = position; + return matched; + } + + public static bool IdentifierArraySizeOptionalValue(ref TScanner scanner, ParseResult result, out Identifier identifier, out List arraySizes, out Expression? value, bool advance = true) where TScanner : struct, IScanner { @@ -164,6 +293,70 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann arraySize = null!; return false; } + public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out Mixin mixin, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) + where TScanner : struct, IScanner + { + var position = scanner.Position; + arraySize = null!; + value = null!; + + if ( + ShaderClassParsers.Mixin(ref scanner, result, out mixin) + && Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out identifier)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if (!FollowedByDelList(ref scanner, result, ArraySizes, out arraySize, withSpaces: true, advance: true)) + { + scanner.Position = tmp; + } + tmp = scanner.Position; + if ( + !( + FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + else + { + scanner.Position = position; + if ( + ShaderClassParsers.Mixin(ref scanner, result, out mixin) + && FollowedByDelList(ref scanner, result, ArraySizes, out List sizes, withSpaces: true, advance: true) + && Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out identifier)) + { + var tmp = scanner.Position; + Spaces0(ref scanner, result, out _); + if ( + !( + Terminals.Char('=', ref scanner, advance: true) + && Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out value) + ) + ) + { + scanner.Position = tmp; + } + if (!advance) + scanner.Position = position; + return true; + } + } + scanner.Position = position; + mixin = null!; + identifier = null!; + arraySize = null!; + return false; + } public static bool ArraySizes(ref TScanner scanner, ParseResult result, out List arraySizes, in ParseError? orError = null) where TScanner : struct, IScanner @@ -173,7 +366,9 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result { if (FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true)) { - if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) + if(FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true)) + break; + else if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) { arraySizes.Add(arraySize); if (!FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true)) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index b14457e947..75a06101aa 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -113,15 +113,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.TypeName(ref scanner, result, out var typeName) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(')', ref scanner, true) - && UnaryParsers.Postfix(ref scanner, result, out var lit) + CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, result, UnaryParsers.Postfix, out Expression expression, withSpaces: true, advance: true) ) { - parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new CastExpression(typeName.Name, Operator.Cast, expression, scanner.GetLocation(position, scanner.Position - position)); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 789fe253bb..fbeadc8dc2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -83,7 +83,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Terminals.Char('.', ref scanner)) { scanner.Advance(1); - if (!Terminals.Digit(ref scanner)) + if (!Terminals.Digit(ref scanner) && !Terminals.FloatSuffix(ref scanner, out _)) return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); while (Terminals.Digit(ref scanner, advance: true)) ; } @@ -94,7 +94,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Terminals.Char('.', ref scanner, advance: true)) { - if (!Terminals.Digit(ref scanner)) + if (!Terminals.Digit(ref scanner) && !Terminals.FloatSuffix(ref scanner, out _)) return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); while (Terminals.Digit(ref scanner, advance: true)) ; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index e81580e27d..43047b74e8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -9,37 +9,23 @@ public record struct CompositionParser() : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; + + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); + var isStaged = Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + if (Terminals.Literal("compose", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { var tmp = scanner.Position; - if ( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin2) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier2) - && - ( - Terminals.Literal("[]", ref scanner, advance: true) - || CommonParsers.SequenceOf(ref scanner, ["[", "]"], advance: true) - ) - ) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new(identifier2, mixin2, true, scanner.GetLocation(position..)); - return true; - } - scanner.Position = tmp; - if( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier) - ) + if (CommonParsers.MixinIdentifierArraySizeValue(ref scanner, result, out var mixin, out var name, out var arraysize, out var value, advance: true)) { CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char(';', ref scanner, advance: true)) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new(identifier, mixin, false, scanner.GetLocation(position..)); + parsed = new(name, mixin, true, scanner.GetLocation(position..)) + { + Attributes = hasAttributes ? attributes.Attributes : null!, + IsStaged = isStaged + }; return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 278ef48a0f..2e80dcc8b3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -182,7 +182,7 @@ public record struct BufferMemberParser : IParser CommonParsers.Spaces0(ref scanner, result, out _); var position = scanner.Position; var isStage = false; - var isStream = false; + StreamKind streamKind = StreamKind.None; bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); var tmp = scanner.Position; if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) @@ -192,61 +192,13 @@ public record struct BufferMemberParser : IParser } else scanner.Position = tmp; - if (LiteralsParser.TypeName(ref scanner, result, out var typename1) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out Identifier name1) - && CommonParsers.FollowedByDelList(ref scanner, result, CommonParsers.ArraySizes, out List arraySizes, withSpaces:true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) + if ( + CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySizes, out var value, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true, advance: true) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) - { - CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename1, name1, null, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySizes: arraySizes); - return true; - } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) - { - CommonParsers.Until(ref scanner, '=', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(';', ref scanner)) - { - parsed = new ShaderMember(typename1, name1, expression, true, scanner.GetLocation(position..scanner.Position), isStage, isStream, arraySizes: arraySizes); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } - } - } - scanner.Position = tmp; - if (LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out Identifier name) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set("=;"), withSpaces: true) - ) - { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true)) - { - CommonParsers.Until(ref scanner, ';', advance: true); - parsed = new ShaderMember(typename, name, null, false, scanner.GetLocation(position..scanner.Position), isStage, isStream); - return true; - } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Set("="), withSpaces: true)) - { - CommonParsers.Until(ref scanner, '=', advance: true); - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression, orError: orError ?? new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) - { - parsed = new ShaderMember(typename, name, expression, false, scanner.GetLocation(position..scanner.Position), isStage, isStream); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } - } + parsed = new ShaderMember(typename, identifier, null, true, scanner.GetLocation(position..scanner.Position), isStage, streamKind, arraySizes: arraySizes); + return true; } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 06728852bd..681359b2da 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -20,8 +20,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o List arraySizes = null!; Expression? value = null!; + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Literal("compose", ref scanner) && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) + if (Terminals.Literal("compose", ref scanner)) + return CommonParsers.Exit(ref scanner, result, out parsed, position); + + + var hasModifier = + CommonParsers.VariableModifiers(ref scanner, result, out var isStaged, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _); + + if (CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) { if ( CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) @@ -31,14 +40,28 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { typeName.ArraySize = arraySizes; - parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySizes: arraySizes); + parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySizes: arraySizes) + { + Attributes = hasAttributes ? attributes.Attributes : null!, + IsStaged = isStaged, + Interpolation = interpolation, + StreamKind = streamKind, + TypeModifier = typeModifier, + }; return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), arraySizes: arraySizes); + parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), arraySizes: arraySizes) + { + Attributes = hasAttributes ? attributes.Attributes : null!, + IsStaged = isStaged, + Interpolation = interpolation, + StreamKind = streamKind, + TypeModifier = typeModifier, + }; return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); @@ -92,9 +115,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) - &&CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) - { + { parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) { Members = assignments @@ -146,9 +169,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && CommonParsers.Spaces0(ref scanner, result, out _) && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) - &&CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) - { + { parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) { Members = assignments diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 194e794c55..fb3acde187 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -9,25 +9,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - - bool isOverride = false; - bool isStaged = false; - bool isStreamed = false; - bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); - var tmpPos = position; -#warning interpolation modifier should always be after stream/stage - var hasInterpolation = Terminals.AnyOf(["linear ", "centroid ", "nointerpolation", "noperspective", "sample"], ref scanner, out var interpolation, advance: true); - if (TypeDef(ref scanner, result, out var typeDef)) { parsed = typeDef; return true; } - else if (ShaderVariable(ref scanner, result, out var cst)) - { - parsed = cst; - return true; - } else if (BufferParsers.Buffer(ref scanner, result, out var buffer)) { CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); @@ -43,65 +29,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { - tmpPos = scanner.Position; -#warning override keyword should always happen after stage and stream - if (Terminals.Literal("override", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) - { - isOverride = true; - tmpPos = scanner.Position; - } - else - scanner.Position = tmpPos; - if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) - { - isStaged = true; - tmpPos = scanner.Position; - } - else - scanner.Position = tmpPos; - if (Terminals.Literal("stream", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) - isStreamed = true; - else - scanner.Position = tmpPos; - if(!hasInterpolation) - hasInterpolation = Terminals.AnyOf(["linear ", "centroid ", "nointerpolation", "noperspective", "sample"], ref scanner, out interpolation, advance: true); - if (SamplerState(ref scanner, result, out var samplerState)) - { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); - parsed = samplerState; - return true; - } - else if (SamplerComparisonState(ref scanner, result, out var samplerCompState)) + + if(AnySamplers(ref scanner, result, out var sampler)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); - parsed = samplerCompState; + parsed = sampler; return true; } else if (Compose(ref scanner, result, out var compose)) { - compose.IsStaged = isStaged; - if (hasAttributes) - compose.Attributes = attributes.Attributes; parsed = compose; return true; } else if (Method(ref scanner, result, out var method)) { - method.IsOverride = isOverride; - method.IsStaged = isStaged; - if (hasAttributes) - method.Attributes = attributes.Attributes; parsed = method; return true; } else if (ShaderMemberParser.Member(ref scanner, result, out var member)) { - member.IsStream = isStreamed; - member.IsStaged = isStaged; - if(hasInterpolation) - member.Interpolation = interpolation.ToInterpolationModifier(); - if (hasAttributes) - member.Attributes = attributes.Attributes; parsed = member; return true; } @@ -117,6 +62,28 @@ public static bool Compose(ref TScanner scanner, ParseResult result, o public static bool Struct(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderStructParser().Match(ref scanner, result, out parsed, in orError); + + + public static bool AnySamplers(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + var isStaged = Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); + + if (SamplerState(ref scanner, result, out var samplerState)) + { + samplerState.IsStaged = isStaged; + parsed = samplerState; + return true; + } + else if (SamplerComparisonState(ref scanner, result, out var samplerCompState)) + { + samplerCompState.IsStaged = isStaged; + parsed = samplerCompState; + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); + } public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderSamplerStateParser().Match(ref scanner, result, out parsed, in orError); @@ -189,7 +156,6 @@ public static bool TypeDef(ref TScanner scanner, ParseResult result, o return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 22f769a4c9..f8726c7051 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -28,15 +28,15 @@ public static bool Simple(ref TScanner scanner, ParseResult result, ou => new SimpleMethodParser().Match(ref scanner, result, out parsed, in orError); - + public static bool MethodParameters(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - #warning We should not allow void to be a parameter, this is legacy C code - if( +#warning We should not allow void to be a parameter, this is legacy C code + if ( CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) - || + || ( CommonParsers.FollowedBy(ref scanner, Terminals.Literal("void"), withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) @@ -48,7 +48,7 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult } else - if(CommonParsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) + if (CommonParsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) { parsed = parameters; return true; @@ -61,14 +61,26 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if(Terminals.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) + if (Terminals.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) CommonParsers.Spaces1(ref scanner, result, out _); - if(CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) + if (CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) ) { typename.ArraySize = arraySize; - parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage); - return true; + if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) + { + parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage, semantic: semantic); + return true; + } + else + { + parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage); + return true; + } } else return CommonParsers.Exit(ref scanner, result, out parsed, position); @@ -111,7 +123,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if (Terminals.Literal("abstract", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); + var hasModifiers = CommonParsers.MethodModifiers(ref scanner, result, out var isStaged, out var isStatic, out var isClone, out var isOverride, out var isAbstract, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); + + if (isAbstract) { if ( LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) @@ -146,24 +162,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - else - scanner.Position = position; - if (Terminals.AnyOf(["clone", "override", "static"], ref scanner, out var matched, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + else if (isClone || isOverride || isStatic) { - var isClone = false; - var isOverride = false; - var isStatic = false; - var tmpPos = scanner.Position; - if (matched == "clone") - isClone = true; - else if (matched == "override") - isOverride = true; - else if (matched == "static") - isStatic = true; - - CommonParsers.Spaces0(ref scanner, result, out _); if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { + if (hasAttributes) + parsed.Attributes = attributes.Attributes; parsed.IsClone = isClone; parsed.IsOverride = isOverride; parsed.IsStatic = isStatic; @@ -171,9 +175,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } } - else - scanner.Position = position; - if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) + else if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { parsed.Info = scanner.GetLocation(position..scanner.Position); return true; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 3597042662..54e703e706 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -10,8 +10,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; + var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && CommonParsers.Spaces0(ref scanner, result, out _); + if (!hasAttributes) + scanner.Position = position; if (While(ref scanner, result, out var w, orError)) { + if(hasAttributes) + w.Attribute = attribute; parsed = w; return true; } @@ -22,6 +27,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (For(ref scanner, result, out var f, orError)) { + if(hasAttributes) + f.Attribute = attribute; parsed = f; return true; } @@ -47,10 +54,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - - var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && CommonParsers.Spaces0(ref scanner, result, out _); - if (!hasAttributes) - scanner.Position = position; if( Terminals.Literal("for", ref scanner, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) @@ -58,7 +61,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { Statement? init = null; Statement? condition = null; - Statement? expression = null; + List? expressions = null; CommonParsers.Spaces0(ref scanner, result, out _); // Parsing the initialization @@ -79,8 +82,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var tmpPos = scanner.Position; - if (!AssignOrExpression(ref scanner, result, out expression)) - expression = new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position)); + if (!CommonParsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) + expressions = [new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position))]; if(!CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); CommonParsers.Spaces0(ref scanner, result, out _); @@ -89,7 +92,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if(StatementParsers.Statement(ref scanner, result, out var body)) { - parsed = new For(init, condition, expression!, body, scanner.GetLocation(position..scanner.Position), attribute: attribute); + parsed = new For(init, condition, expressions!, body, scanner.GetLocation(position..scanner.Position)); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); @@ -97,7 +100,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; From 2823f26dc5c0ce464c0b88336d71f25f26fc4b1a Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:46:19 +0100 Subject: [PATCH 0355/1182] effect parsers corrections --- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 38 +++++-- .../SDFX/Parsers/EffectStatementParsers.cs | 98 +++++++++++++++---- .../SDFX/Parsers/ParamsParsers.cs | 3 +- src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs | 1 + .../ShaderParsers/ShaderClassParser.cs | 17 +++- .../ShaderParsers/ShaderFileParsers.cs | 4 +- 6 files changed, 129 insertions(+), 32 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index cc1c4d54d3..0e245a14f9 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX.AST; @@ -72,20 +73,35 @@ public class MixinConst(string identifier, TextLocation info) : EffectStatement( public abstract class Composable(); -public class MixinCompose(Identifier identifier, Mixin mixin, TextLocation info) : EffectStatement(info) -{ - public Identifier Identifier { get; set; } = identifier; - public Mixin MixinName { get; set; } = mixin; +public abstract class ComposeValue(TextLocation info) : Node(info); - public MixinCompose(Identifier identifier, Expression value, TextLocation info) : this(identifier, new Mixin(new(value.ToString(), value.Info), value.Info), info) +public class ComposePathValue(string path, TextLocation info) : ComposeValue(info) +{ + public string Path { get; set; } = path; + public override string ToString() { - + return Path.ToString(); + } +} +public class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(info) +{ + public Mixin Mixin { get; set; } = mixin; + public override string ToString() + { + return Mixin.ToString(); } +} + +public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue value, TextLocation info) : EffectStatement(info) +{ + public Identifier Identifier { get; set; } = identifier; + AssignOperator Operator { get; set; } = op; + public ComposeValue ComposeValue { get; set; } = value; public override string ToString() { - return $"mixin compose {Identifier} = {MixinName}"; + return $"mixin compose {Identifier} = {ComposeValue}"; } } public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) @@ -118,3 +134,11 @@ public class EffectBlock(TextLocation info) : EffectStatement(info) } +public class EffectExpressionStatement(Statement statement, TextLocation info) : EffectStatement(info) +{ + public Statement Statement { get; set; } = statement; +} + +public class EffectDiscardStatement(TextLocation info) : EffectStatement(info); + + diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 6266904500..6b4e78e1fb 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -10,42 +10,42 @@ public record struct EffectStatementParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (EffectBlock(ref scanner, result, out var block, orError)) + if (EffectBlock(ref scanner, result, out var block)) { parsed = block; return true; } - else if (UsingParams(ref scanner, result, out var p1, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (UsingParams(ref scanner, result, out var p1) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p1; return true; } - else if (MixinCompose(ref scanner, result, out var p2, orError)) + else if (MixinCompose(ref scanner, result, out var p2)) { parsed = p2; return true; } - else if (MixinComposeAdd(ref scanner, result, out var mca, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinComposeAdd(ref scanner, result, out var mca) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = mca; return true; } - else if (MixinChild(ref scanner, result, out var mc, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinChild(ref scanner, result, out var mc) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = mc; return true; } - else if (MixinClone(ref scanner, result, out var mcl, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinClone(ref scanner, result, out var mcl) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = mcl; return true; } - else if (MixinConst(ref scanner, result, out var mconst, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinConst(ref scanner, result, out var mconst) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = mconst; return true; } - else if (MixinUse(ref scanner, result, out var p3, orError) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinUse(ref scanner, result, out var p3) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) { parsed = p3; return true; @@ -60,11 +60,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = flow; return true; } - else if (ShaderSourceDeclaration(ref scanner, result, out var ssd, orError)) + else if (ShaderSourceDeclaration(ref scanner, result, out var ssd)) { parsed = ssd; return true; } + else if (StatementParsers.Expression(ref scanner, result, out var exp)) + { + parsed = new EffectExpressionStatement(exp, scanner.GetLocation(position..scanner.Position)); + return true; + } + else if ( + CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + ) + { + parsed = new EffectDiscardStatement(scanner.GetLocation(position..scanner.Position)); + return true; + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -133,7 +146,7 @@ public static bool ShaderSourceDeclaration(ref TScanner scanner, Parse { var position = scanner.Position; if ( - Terminals.AnyOf(["ShaderSourceCollection ", "ShaderSource "], ref scanner, out _) + Terminals.AnyOf(["ShaderSourceCollection ", "ShaderSource ", "var "], ref scanner, out _) && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var arraySize, out var value) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) @@ -198,31 +211,71 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.AnyOf(["=", "+="], ref scanner, out var op, advance: true) ) { - var paren = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); - if ( - ExpressionParser.Expression(ref scanner, result, out var mixin) - && paren == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + if( + CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ComposeValue(ref scanner, result, out var composeValue) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { - parsed = new(name, mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue, scanner.GetLocation(position..scanner.Position)); return true; } else if( - CommonParsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression postfix, withSpaces: true, advance: true) - && paren == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) + CommonParsers.Spaces0(ref scanner, result, out _) + && ComposeValue(ref scanner, result, out var composeValue2) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) ) { - parsed = new(name, postfix, scanner.GetLocation(position..scanner.Position)); + parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue2, scanner.GetLocation(position..scanner.Position)); return true; } + } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + + public static bool ComposeValue(ref TScanner scanner, ParseResult result, out ComposeValue value, in ParseError? orError = null) where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && ( + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + || CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + ) + ) + { + value = new ComposeMixinValue(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + else + { + scanner.Position = position; + if(Terminals.IdentifierFirstChar(ref scanner, advance: true)) + { + while( + Terminals.LetterOrDigit(ref scanner, advance: true) + || Terminals.Char('_', ref scanner, advance: true) + || Terminals.Char('.', ref scanner, advance: true) + ); + if( + CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + || CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + ) + { + value = new ComposePathValue(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position..scanner.Position)); + return true; + } + } + } + return CommonParsers.Exit(ref scanner, result, out value, position); + } } public record struct MixinComposeAddParser : IParser @@ -259,7 +312,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { var betweenParenthesis = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); - if (ShaderClassParsers.Mixin(ref scanner, result, out var mixin)) + if ( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && !CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) + ) { var checkParen = betweenParenthesis == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true); var finished = CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true); @@ -270,7 +326,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return CommonParsers.Exit(ref scanner, result, out parsed, position); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + return CommonParsers.Exit(ref scanner, result, out parsed, position); } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index e36909e188..0d380f0498 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -22,8 +22,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Parameter(ref scanner, result, out var p)) parsed.Parameters.Add(p); - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) { + CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); parsed.Info = scanner.GetLocation(position..scanner.Position); return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs index de04b5b99e..886599e407 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -33,6 +33,7 @@ public class ShaderGenerics(Identifier typename, Identifier name, TextLocation i public class Mixin(Identifier name, TextLocation info) : Node(info) { + public List Path { get; set; } = []; public Identifier Name { get; set; } = name; public ShaderExpressionList? Generics { get; set; } public override string ToString() diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 224cf06cf0..72758e0e10 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -142,15 +142,28 @@ public record struct ShaderMixinParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + List path = []; + do { + if(LiteralsParser.Identifier(ref scanner, result, out var id)) + path.Add(id); + } + while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)); + + if (path.Count > 0) + { + var identifier = path[^1]; parsed = new Mixin(identifier, scanner.GetLocation(..)); var tmpPos = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('<', ref scanner, advance: true)) + if ( + Terminals.Char('<', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) { ParameterParsers.GenericsList(ref scanner, result, out var values); parsed.Generics = values; + parsed.Path = path[..^1]; CommonParsers.Spaces0(ref scanner, result, out _); if (!Terminals.Char('>', ref scanner, advance: true)) return CommonParsers.Exit(ref scanner, result, out parsed, position); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 6bb6049461..21f6832d3f 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -43,7 +43,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o file.RootDeclarations.Add(effect); CommonParsers.Spaces0(ref scanner, result, out _); } - else if (Terminals.Literal("params", ref scanner) + else if (Terminals.Literal("params ", ref scanner) && ParamsParsers.Params(ref scanner, result, out var p) ) { @@ -144,6 +144,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ns.Declarations.Add(shader); else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); + else if (ParamsParsers.Params(ref scanner, result, out var p) && CommonParsers.Spaces0(ref scanner, result, out _)) + ns.Declarations.Add(p); else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0039, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } From 1f99d64a93dcf49fd043aa875a59585f1b29e773 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sun, 3 Nov 2024 20:58:06 +0100 Subject: [PATCH 0356/1182] some complex params test left to add --- src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs | 4 ++-- .../SDFX/Parsers/EffectStatementParsers.Conditional.cs | 2 +- .../SDFX/Parsers/EffectStatementParsers.cs | 7 ++----- .../SDSL/Parsers/ShaderParsers/ShaderClassParser.cs | 2 ++ 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs index 0e245a14f9..7c73f475bc 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs @@ -40,9 +40,9 @@ public override string ToString() } } -public class MixinUse(Mixin mixin, TextLocation info) : EffectStatement(info) +public class MixinUse(List mixin, TextLocation info) : EffectStatement(info) { - public Mixin MixinName { get; set; } = mixin; + public List MixinName { get; set; } = mixin; public override string ToString() { return $"mixin {MixinName}"; diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs index 34cbb5ab5c..5d72b2ffa8 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -15,7 +15,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) { parsed = new(ifstatement, scanner.GetLocation(..)); - while(ElseIf(ref scanner, result, out var elseif, orError)) + while(ElseIf(ref scanner, result, out var elseif, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 6b4e78e1fb..051706b206 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -312,16 +312,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { var betweenParenthesis = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); - if ( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && !CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) - ) + if (CommonParsers.Repeat(ref scanner, result, ShaderClassParsers.Mixin, out List mixins, 1, withSpaces: true, separator: ",")) { var checkParen = betweenParenthesis == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true); var finished = CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true); if (finished && checkParen) { - parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new(mixins, scanner.GetLocation(position..scanner.Position)); return finished; } else return CommonParsers.Exit(ref scanner, result, out parsed, position); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 72758e0e10..a8eef6788a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -72,6 +72,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var tmp = position; if (Terminals.Literal("internal", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; + if(CommonParsers.FollowedBy(ref scanner, Terminals.Literal("partial"), withSpaces: true, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + tmp = scanner.Position; if ( ( Terminals.Literal("shader", ref scanner, advance: true) From 12e1131a6cebf8b4b02da5b59887046177354d1f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 4 Nov 2024 10:23:00 +0100 Subject: [PATCH 0357/1182] correction for VS and invariant culture --- SDSL.sln | 34 +++++++++++-------- .../Parsers/LiteralParsers/NumberParsers.cs | 3 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/SDSL.sln b/SDSL.sln index 93758513aa..a6666991bd 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -5,38 +5,37 @@ VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F15E41A8-FD75-462B-9BB0-DCE18A6AD334}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{6641B2F9-0E20-43E5-BF88-44B02B32117B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{6641B2F9-0E20-43E5-BF88-44B02B32117B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{06F65A22-F517-49B4-B4A5-F38D60555B2A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{06F65A22-F517-49B4-B4A5-F38D60555B2A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{E59CE683-4805-4FD3-98EB-4F704C253F1A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{E59CE683-4805-4FD3-98EB-4F704C253F1A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shaders.Spirv", "Stride.Shaders.Spirv", "{6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv\Stride.Shaders.Spirv.csproj", "{4EC134E1-5B64-497B-B129-4E1B4806E466}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv\Stride.Shaders.Spirv.csproj", "{4EC134E1-5B64-497B-B129-4E1B4806E466}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Experiments", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Experiments\Stride.Shaders.Spirv.Experiments.csproj", "{07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Experiments", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Experiments\Stride.Shaders.Spirv.Experiments.csproj", "{07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{1205976E-A945-4475-AD87-C63527D5A63A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{1205976E-A945-4475-AD87-C63527D5A63A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core.Benchmarks", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core.Benchmarks\Stride.Shaders.Spirv.Core.Benchmarks.csproj", "{8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core.Benchmarks", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core.Benchmarks\Stride.Shaders.Spirv.Core.Benchmarks.csproj", "{8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Parsing.Tests\Stride.Shaders.Parsing.Tests.csproj", "{41050DB9-A819-4FC7-9D46-0ED054CAE7CB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Parsing.Tests\Stride.Shaders.Parsing.Tests.csproj", "{41050DB9-A819-4FC7-9D46-0ED054CAE7CB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.Build.0 = Debug|Any CPU @@ -82,6 +81,13 @@ Global {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Debug|Any CPU.Build.0 = Debug|Any CPU {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.ActiveCfg = Release|Any CPU {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.Build.0 = Release|Any CPU + {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {6641B2F9-0E20-43E5-BF88-44B02B32117B} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index fbeadc8dc2..79df6340a2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Parsing.SDSL.AST; +using System.Globalization; namespace Stride.Shaders.Parsing.SDSL; @@ -103,7 +104,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return CommonParsers.Exit(ref scanner, result, out node, position); - var value = double.Parse(scanner.Span[position..scanner.Position]); + var value = double.Parse(scanner.Span[position..scanner.Position], CultureInfo.InvariantCulture); int? exponent = null; if (Terminals.Char('e', ref scanner, advance: true)) { From 1d5198f58962e45f01160d04b8eb1cfe3c5bad53 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 4 Nov 2024 10:25:32 +0100 Subject: [PATCH 0358/1182] added folder in solution --- SDSL.sln | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SDSL.sln b/SDSL.sln index a6666991bd..6947481a58 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -31,6 +31,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "submodules", "submodules", "{5889489A-15EB-4324-ACBC-3A4C9F11A39C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -102,5 +104,9 @@ Global {1205976E-A945-4475-AD87-C63527D5A63A} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} {41050DB9-A819-4FC7-9D46-0ED054CAE7CB} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} + {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897} = {5889489A-15EB-4324-ACBC-3A4C9F11A39C} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A8CB18C1-53F2-4B53-B9FF-46BBBCA76534} EndGlobalSection EndGlobal From ebf4c794ead2510d6490e5b358e59f69ee857ffd Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 8 Nov 2024 17:46:52 +0100 Subject: [PATCH 0359/1182] little updates --- assets/SDSL/Test.sdsl | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 assets/SDSL/Test.sdsl diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl new file mode 100644 index 0000000000..79fe8f1427 --- /dev/null +++ b/assets/SDSL/Test.sdsl @@ -0,0 +1,6 @@ +struct Machin { + [Link("hello")] + stage something something; + [Link("hello2", 1 , 3)] + stage something[] something; +} \ No newline at end of file From de5eb0a2b71c651dd6950f509ba764c577b2ce7f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 8 Nov 2024 18:17:49 +0100 Subject: [PATCH 0360/1182] small update --- assets/SDSL/Test.sdsl | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 79fe8f1427..29ace9f603 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,6 +1,13 @@ -struct Machin { - [Link("hello")] - stage something something; - [Link("hello2", 1 , 3)] - stage something[] something; + +shader Main { + struct Machin { + [Link("hello")] + stage something something; + [Link("hello2", 1 , 3)] + stage something[machin, machin, 3, machin(22), obo.obo] something; + } + + struct Machin { + + } } \ No newline at end of file From 0442e07ef0596e1a5daf5c87a4bd9e1028243cdd Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 9 Nov 2024 01:25:38 +0100 Subject: [PATCH 0361/1182] testing --- assets/SDSL/Test.sdsl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 29ace9f603..81d3519a04 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,5 +1,12 @@ +namespace machin.other.chamqsdklj; -shader Main { +shader Parent +{ + [Layout(1, 2)] + stream int a; +} + +shader Main { struct Machin { [Link("hello")] stage something something; From 93a04814f87c6f32683346008e980652f3693688 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Sat, 9 Nov 2024 12:32:00 +0100 Subject: [PATCH 0362/1182] correction multiline shader --- assets/SDSL/Test.sdsl | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 81d3519a04..c4661b69a3 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,20 +1,20 @@ -namespace machin.other.chamqsdklj; - -shader Parent +shader + Parent : + hello { [Layout(1, 2)] stream int a; } -shader Main { - struct Machin { - [Link("hello")] - stage something something; - [Link("hello2", 1 , 3)] - stage something[machin, machin, 3, machin(22), obo.obo] something; - } +// shader Main { +// struct Machin { +// [Link("hello")] +// stage something something; +// [Link("hello2", 1 , 3)] +// stage something[machin, machin, 3, machin(22), obo.obo] something; +// } - struct Machin { +// struct Machin { - } -} \ No newline at end of file +// } +// } \ No newline at end of file From 2c8cf664e94fd2c65c864f39758af8820a7ffc6e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Nov 2024 22:15:05 +0100 Subject: [PATCH 0363/1182] namespace highlighting working --- assets/SDSL/Simple.sdsl | 9 +++++++++ assets/SDSL/Test.sdsl | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 assets/SDSL/Simple.sdsl diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl new file mode 100644 index 0000000000..cf48bb1409 --- /dev/null +++ b/assets/SDSL/Simple.sdsl @@ -0,0 +1,9 @@ +namespace machin { + namespace hello; + namespace other.thing + { + shader class { + + } + } +} \ No newline at end of file diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index c4661b69a3..7ef957060e 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,11 +1,20 @@ -shader - Parent : - hello -{ - [Layout(1, 2)] - stream int a; +shader machin { + } +namespace machin.something.Hello { + namespace machin; + + namespace hello.world + { + shader machin { + + } + } + +} + + // shader Main { // struct Machin { // [Link("hello")] From 758490a23f4d404018a720e4f6dfdafc0b838c1c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Nov 2024 23:06:22 +0100 Subject: [PATCH 0364/1182] added partial class and effects --- assets/SDSL/Simple.sdsl | 11 +++++++++-- assets/SDSL/Test.sdsl | 9 +++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl index cf48bb1409..d89a85e204 100644 --- a/assets/SDSL/Simple.sdsl +++ b/assets/SDSL/Simple.sdsl @@ -2,8 +2,15 @@ namespace machin { namespace hello; namespace other.thing { - shader class { - + shader class.heloo { + + } + + shader class : Hlelo { + } + + shader other; + } } \ No newline at end of file diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 7ef957060e..4199bd5670 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,4 +1,4 @@ -shader machin { +partial effect machin { } @@ -7,9 +7,14 @@ namespace machin.something.Hello { namespace hello.world { - shader machin { + shader machin + { } + + effect machin { + + } } } From de199b59ee2b28777690df0d938d9ab84b193495 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Nov 2024 23:15:14 +0100 Subject: [PATCH 0365/1182] little corrections, starting work on shader elements --- assets/SDSL/Simple.sdsl | 2 +- assets/SDSL/Test.sdsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl index d89a85e204..bdb5dc453e 100644 --- a/assets/SDSL/Simple.sdsl +++ b/assets/SDSL/Simple.sdsl @@ -2,7 +2,7 @@ namespace machin { namespace hello; namespace other.thing { - shader class.heloo { + internal partial effect class.heloo { } diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 4199bd5670..6b11768cec 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -7,7 +7,7 @@ namespace machin.something.Hello { namespace hello.world { - shader machin + partial shader machin { } From 05a6d4b578fb33c68287c5dd81e0590e16810966 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 21 Nov 2024 23:48:25 +0100 Subject: [PATCH 0366/1182] added simple declarations --- assets/SDSL/Simple.sdsl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl index bdb5dc453e..3c98d11ca7 100644 --- a/assets/SDSL/Simple.sdsl +++ b/assets/SDSL/Simple.sdsl @@ -7,7 +7,8 @@ namespace machin { } shader class : Hlelo { - + float a; + float3x3 b = 1.0f32 + 5; } shader other; From 381be9a8537cabd22124eb23970567bf9c61baf8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 23 Nov 2024 23:50:50 +0100 Subject: [PATCH 0367/1182] restart from scratch, tmLanguage not enough, need semantic --- assets/SDSL/Simple.sdsl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl index 3c98d11ca7..b5e252e2b9 100644 --- a/assets/SDSL/Simple.sdsl +++ b/assets/SDSL/Simple.sdsl @@ -7,8 +7,13 @@ namespace machin { } shader class : Hlelo { - float a; - float3x3 b = 1.0f32 + 5; + patchstream float a = 5; + float3x3 b; + + float Foo(int a, int b) + { + + } } shader other; From 7175e00fff337bd5dd637a1563a15edb881beb47 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Nov 2024 14:36:52 +0100 Subject: [PATCH 0368/1182] working on statements --- assets/SDSL/Simple.sdsl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/SDSL/Simple.sdsl b/assets/SDSL/Simple.sdsl index b5e252e2b9..7ee150f2b0 100644 --- a/assets/SDSL/Simple.sdsl +++ b/assets/SDSL/Simple.sdsl @@ -6,12 +6,19 @@ namespace machin { } - shader class : Hlelo { + shader MyCLass : Hello<1,2,3.0f32,"Hello"> { patchstream float a = 5; float3x3 b; float Foo(int a, int b) { + elif(a == b) + { + float a = Comm(); + } + const int a = 3; + machin = 5; + streams.a.machin.hello[1] = 9; } } From 4cbdbd906b4e2eef0f44244139bb14d8c704e831 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Nov 2024 16:07:07 +0100 Subject: [PATCH 0369/1182] refactored some functions and upgrade to .NET 9 --- .../Stride.Shaders.AvaloniaViewer.csproj | 2 +- .../Stride.Shaders.Compilers.csproj | 2 +- .../Stride.Shaders.LSP.Test.csproj | 2 +- .../Stride.Shaders.LSP.csproj | 2 +- .../Stride.Shaders.Parsing.Experiments.csproj | 2 +- .../Stride.Shaders.Parsing.Tests.csproj | 2 +- .../SDSL/Parsers/Common/CommonParsers.cs | 44 ++- .../SDSL/Parsers/Common/Delegates.cs | 11 + .../ExpressionParsers/BinaryParsers.cs | 275 +++++++----------- .../PrimaryExpressionParsers.cs | 115 ++++---- .../ExpressionParsers/UnaryParsers.Postfix.cs | 87 +++--- .../ExpressionParsers/UnaryParsers.Prefix.cs | 114 ++++---- .../Parsers/ExpressionParsers/UnaryParsers.cs | 26 -- .../ShaderParsers/ShaderBufferParsers.Cs | 151 ++++------ .../Stride.Shaders.Parsing.csproj | 2 +- ...tride.Shaders.Spirv.Core.Benchmarks.csproj | 2 +- .../Stride.Shaders.Spirv.Core.csproj | 2 +- .../Stride.Shaders.Spirv.Experiments.csproj | 2 +- .../Stride.Shaders.Spirv.csproj | 2 +- 19 files changed, 348 insertions(+), 497 deletions(-) create mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs diff --git a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj index c2e5de7cb0..c8059d76d5 100644 --- a/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj +++ b/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj @@ -1,7 +1,7 @@  WinExe - net8.0 + net9.0 enable true app.manifest diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index ab040063ff..4344add0d9 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -15,7 +15,7 @@ - net8.0 + net9.0 enable enable true diff --git a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj index 370311e009..d91bdeef5c 100644 --- a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj +++ b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj @@ -6,7 +6,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index ac44e4e6aa..e3228ce9ff 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj index 28a67c6f41..d57c2a62e4 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj +++ b/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj @@ -4,7 +4,7 @@ Exe - net8.0 + net9.0 enable enable true diff --git a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj index 1e4d2f62e0..a012f8f3f3 100644 --- a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 48affd54c8..61e52d3e04 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -5,16 +5,6 @@ namespace Stride.Shaders.Parsing.SDSL; -public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result) - where TScanner : struct, IScanner; -public delegate bool ParserValueDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) - where TScanner : struct, IScanner; - -public delegate bool ParserListValueDelegate(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) - where TScanner : struct, IScanner; - -public delegate bool ParserOptionalValueDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, in ParseError? orError = null) - where TScanner : struct, IScanner; public static class CommonParsers { @@ -43,6 +33,32 @@ public static bool Spaces1(ref TScanner scanner, ParseResult result, o => new Space1(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); + + + public static bool Alternatives(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null, params ReadOnlySpan> parsers) + where TScanner : struct, IScanner + where TResult : Node + { + var position = scanner.Position; + foreach(var p in parsers) + if(p.Invoke(ref scanner, result, out parsed)) + return true; + return Exit(ref scanner, result, out parsed, position, orError); + } + public static bool Sequences(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null, bool withSPaces = false, string? separator = null, params ReadOnlySpan> parsers) + where TScanner : struct, IScanner + where TResult : Node + { + parsed = []; + var position = scanner.Position; + foreach(var p in parsers) + if(p.Invoke(ref scanner, result, out var r)) + parsed.Add(r); + else + return Exit(ref scanner, result, out parsed, position, orError); + return true; + } + public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan literals, bool advance = false) where TScanner : struct, IScanner { @@ -523,7 +539,7 @@ public static bool FollowedByDel(ref TScanner scanner, ParseResult res scanner.Position = position; return false; } - public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -538,7 +554,7 @@ public static bool FollowedByDel(ref TScanner scanner, ParseR scanner.Position = position; return false; } - public static bool FollowedByDelList(ref TScanner scanner, ParseResult result, ParserListValueDelegate func, out List parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedByDelList(ref TScanner scanner, ParseResult result, ParserListDelegate func, out List parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -553,7 +569,7 @@ public static bool FollowedByDelList(ref TScanner scanner, Pa scanner.Position = position; return false; } - public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserValueDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -655,7 +671,7 @@ public static bool Repeat(ref TScanner scanner, TParse { return Repeat(ref scanner, result, (ref TScanner s, ParseResult r, out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), out nodes, minimum, withSpaces, separator, orError); } - public static bool Repeat(ref TScanner scanner, ParseResult result, ParserValueDelegate parser, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + public static bool Repeat(ref TScanner scanner, ParseResult result, ParserDelegate parser, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) where TScanner : struct, IScanner where TNode : Node { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs new file mode 100644 index 0000000000..00aa74e2c4 --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Parsing.SDSL; + + +public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result) + where TScanner : struct, IScanner; +public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; +public delegate bool ParserListDelegate(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; +public delegate bool ParserOptionalDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 97b177b42f..0b4d498fff 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -4,6 +4,10 @@ namespace Stride.Shaders.Parsing.SDSL; public struct ExpressionParser : IParser { + public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new ExpressionParser().Match(ref scanner, result, out parsed, in orError); + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -13,117 +17,63 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new ExpressionParser().Match(ref scanner, result, out parsed, in orError); public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new AdditionParser().Match(ref scanner, result, out parsed, in orError); - public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new MultiplicationParser().Match(ref scanner, result, out parsed, in orError); - public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new BitwiseShiftParser().Match(ref scanner, result, out parsed, in orError); - public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new RelationalParser().Match(ref scanner, result, out parsed, in orError); - public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new EqualityParser().Match(ref scanner, result, out parsed, in orError); - public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new BitwiseAndParser().Match(ref scanner, result, out parsed, in orError); - public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new BitwiseOrParser().Match(ref scanner, result, out parsed, in orError); - public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new BitwiseXOrParser().Match(ref scanner, result, out parsed, in orError); - public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new AndParser().Match(ref scanner, result, out parsed, in orError); - public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new OrParser().Match(ref scanner, result, out parsed, in orError); - public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new TernaryParser().Match(ref scanner, result, out parsed, in orError); -} - - -public record struct TernaryParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner { + char op = '\0'; + parsed = null!; var position = scanner.Position; - if (ExpressionParser.Or(ref scanner, result, out parsed)) + do { - var pos2 = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('?', ref scanner, advance: true)) + if (op != '\0' && parsed is not null) { - - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(':', ref scanner, advance: true)) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - } - } + if (Mul(ref scanner, result, out var mul)) + parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } - else + else if (parsed is null && op == '\0') { - scanner.Position = pos2; - return true; + if (Mul(ref scanner, result, out var mul)) + parsed = mul; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + while (Terminals.Set("+-", ref scanner, out op, advance: true)); + if (parsed is not null) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct OrParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + char op = '\0'; parsed = null!; var position = scanner.Position; do { CommonParsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op != '\0' && parsed is not null) { - if (ExpressionParser.And(ref scanner, result, out var and)) - parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); + if (PrefixParser.Prefix(ref scanner, result, out var prefix)) + parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op == '\0') { - if (ExpressionParser.And(ref scanner, result, out var and)) - parsed = and; + if (PrefixParser.Prefix(ref scanner, result, out var prefix)) + parsed = prefix; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["||"], ref scanner, out op, advance: true)); + while (Terminals.Set("*/%", ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct AndParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -134,27 +84,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.BOr(ref scanner, result, out var bOr)) - parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); + if (Add(ref scanner, result, out var add)) + parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.BOr(ref scanner, result, out var bOr)) - parsed = bOr; + if (Add(ref scanner, result, out var add)) + parsed = add; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["&&"], ref scanner, out op, advance: true)); + while (Terminals.AnyOf([">>", "<<"], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct BitwiseOrParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -165,26 +112,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.XOr(ref scanner, result, out var xor)) - parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); + if (Shift(ref scanner, result, out var shift)) + parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.XOr(ref scanner, result, out var xor)) - parsed = xor; + if (Shift(ref scanner, result, out var shift)) + parsed = shift; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } + CommonParsers.Spaces0(ref scanner, result, out _); } - while (!Terminals.Literal("||", ref scanner) && Terminals.AnyOf(["|"], ref scanner, out op, advance: true)); + while (Terminals.AnyOf(["<=", ">=", "<", ">"], ref scanner, out op, advance: true)); + if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct BitwiseXOrParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -195,26 +142,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) - parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); + if (Relation(ref scanner, result, out var rel)) + parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.BAnd(ref scanner, result, out var bAnd)) - parsed = bAnd; + if (Relation(ref scanner, result, out var rel)) + parsed = rel; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["^"], ref scanner, out op, advance: true)); + while (Terminals.AnyOf(["==", "!="], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct BitwiseAndParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -225,13 +170,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.Equality(ref scanner, result, out var eq)) + if (Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.Equality(ref scanner, result, out var eq)) + if (Equality(ref scanner, result, out var eq)) parsed = eq; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -241,13 +186,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} - - -public record struct EqualityParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -258,27 +198,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.Relation(ref scanner, result, out var rel)) - parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); + if (XOr(ref scanner, result, out var xor)) + parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.Relation(ref scanner, result, out var rel)) - parsed = rel; + if (XOr(ref scanner, result, out var xor)) + parsed = xor; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["==", "!="], ref scanner, out op, advance: true)); + while (!Terminals.Literal("||", ref scanner) && Terminals.AnyOf(["|"], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct RelationalParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -289,29 +226,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.Shift(ref scanner, result, out var shift)) - parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); + if (BAnd(ref scanner, result, out var bAnd)) + parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.Shift(ref scanner, result, out var shift)) - parsed = shift; + if (BAnd(ref scanner, result, out var bAnd)) + parsed = bAnd; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - CommonParsers.Spaces0(ref scanner, result, out _); } - while (Terminals.AnyOf(["<=", ">=", "<", ">"], ref scanner, out op, advance: true)); - + while (Terminals.AnyOf(["^"], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct BitwiseShiftParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { string op = ""; @@ -322,82 +254,83 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { - if (ExpressionParser.Add(ref scanner, result, out var add)) - parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); + if (BOr(ref scanner, result, out var bOr)) + parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { - if (ExpressionParser.Add(ref scanner, result, out var add)) - parsed = add; + if (BOr(ref scanner, result, out var bOr)) + parsed = bOr; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf([">>", "<<"], ref scanner, out op, advance: true)); + while (Terminals.AnyOf(["&&"], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct AdditionParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - char op = '\0'; + string op = ""; parsed = null!; var position = scanner.Position; do { CommonParsers.Spaces0(ref scanner, result, out _); - if (op != '\0' && parsed is not null) + if (op != "" && parsed is not null) { - if (ExpressionParser.Mul(ref scanner, result, out var mul)) - parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); + if (And(ref scanner, result, out var and)) + parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); else return CommonParsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == '\0') + else if (parsed is null && op == "") { - if (ExpressionParser.Mul(ref scanner, result, out var mul)) - parsed = mul; + if (And(ref scanner, result, out var and)) + parsed = and; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.Set("+-", ref scanner, out op, advance: true)); + while (Terminals.AnyOf(["||"], ref scanner, out op, advance: true)); if (parsed is not null) return true; else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct MultiplicationParser() : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - char op = '\0'; - parsed = null!; var position = scanner.Position; - do + if (Or(ref scanner, result, out parsed)) { + var pos2 = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); - if (op != '\0' && parsed is not null) + if (Terminals.Char('?', ref scanner, advance: true)) { - if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) - parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + + CommonParsers.Spaces0(ref scanner, result, out _); + if (Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Char(':', ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + { + parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + } + } } - else if (parsed is null && op == '\0') + else { - if (UnaryParsers.Prefix(ref scanner, result, out var prefix)) - parsed = prefix; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + scanner.Position = pos2; + return true; } } - while (Terminals.Set("*/%", ref scanner, out op, advance: true)); - if (parsed is not null) - return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index f0375011f3..cce621504c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -6,78 +6,38 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PrimaryParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Parenthesis(ref scanner, result, out parsed)) - return true; - else if (ArrayLiteral(ref scanner, result, out parsed)) - return true; - else if (Method(ref scanner, result, out parsed)) - return true; - else if (MixinAccess(ref scanner, result, out parsed)) - return true; - else if (LiteralsParser.Literal(ref scanner, result, out var lit)) - { - parsed = lit; - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new PrimaryParsers().Match(ref scanner, result, out parsed, in orError); - public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier parsed) - where TScanner : struct, IScanner - => new IdentifierParser().Match(ref scanner, result, out parsed); - public static bool Method(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new MethodCallParser().Match(ref scanner, result, out parsed, in orError); - public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new ParenthesisExpressionParser().Match(ref scanner, result, out parsed, in orError); - public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new ArrayLiteralParser().Match(ref scanner, result, out parsed, in orError); - public static bool MixinAccess(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - var position = scanner.Position; - if( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) - ) - { - parsed = new MixinAccess(mixin, scanner.GetLocation(position..scanner.Position)); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return CommonParsers.Alternatives( + ref scanner, result, out parsed, in orError, + Parenthesis, + ArrayLiteral, + Method, + MixinAccess, + Literal + ); } -} - -public record struct ParenthesisExpressionParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Literal(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if ( - Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(')', ref scanner, advance: true) - ) + if(LiteralsParser.Literal(ref scanner, result, out var lit)) + { + parsed = lit; return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position); } -} - -public record struct MethodCallParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + + public static bool Method(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -98,11 +58,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct ArrayLiteralParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Terminals.Char('(', ref scanner, advance: true) + && CommonParsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) + && CommonParsers.Spaces0(ref scanner, result, out _) + && Terminals.Char(')', ref scanner, advance: true) + ) + return true; + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -120,4 +92,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return CommonParsers.Exit(ref scanner, result, out parsed, position); } + + public static bool MixinAccess(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + && CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) + ) + { + parsed = new MixinAccess(mixin, scanner.GetLocation(position..scanner.Position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 9c55aa88aa..92e979e658 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -4,6 +4,9 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PostfixParser : IParser { + public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PostfixParser().Match(ref scanner, result, out parsed, in orError); public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -11,9 +14,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (PrimaryParsers.Primary(ref scanner, result, out parsed)) { - while(!scanner.IsEof && CommonParsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out var matched, withSpaces: true, advance: true)) + while (!scanner.IsEof && CommonParsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out var matched, withSpaces: true, advance: true)) { - if( + if ( matched == "[" && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression indexer, withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) @@ -21,21 +24,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = new IndexerExpression(parsed, indexer, scanner.GetLocation(position..scanner.Position)); } - else if( + else if ( matched == "." && CommonParsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression call, withSpaces: true, advance: true) ) { parsed = new AccessorExpression(parsed, call, scanner.GetLocation(position..scanner.Position)); } - else if( + else if ( matched == "." && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Literal, out Literal accessor, withSpaces: true, advance: true) ) { parsed = new AccessorExpression(parsed, accessor, scanner.GetLocation(position..scanner.Position)); } - else if(matched == "++" || matched == "--") + else if (matched == "++" || matched == "--") { parsed = new PostfixExpression(parsed, matched.ToOperator(), scanner.GetLocation(position..scanner.Position)); break; @@ -46,35 +49,41 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PostfixParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PostfixIncrementParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + public static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new PostfixAccessorParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PostfixIndexerParser().Match(ref scanner, result, out parsed, in orError); -} - + { + var position = scanner.Position; + if (Accessor(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + CommonParsers.Spaces0(ref scanner, result, out _); + if (Terminals.Literal("++", ref scanner, advance: true)) + { + parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else + { + scanner.Position = pos2; + return true; + } + } + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + } -public record struct PostfixAccessorParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (PostfixParser.Indexer(ref scanner, result, out var expression)) + if (Indexer(ref scanner, result, out var expression)) { var pos2 = scanner.Position; CommonParsers.Spaces0(ref scanner, result, out _); if ( Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed)) + && Accessor(ref scanner, result, out var accessed)) { parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); return true; @@ -88,11 +97,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct PostfixIndexerParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -114,37 +120,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); - - } - else - { - scanner.Position = pos2; - parsed = expression; - return true; - } - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } -} -public record struct PostfixIncrementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (PostfixParser.Accessor(ref scanner, result, out parsed)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Literal("++", ref scanner, advance: true)) - { - parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); - return true; } else { scanner.Position = pos2; + parsed = expression; return true; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 75a06101aa..a459d89f4b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -5,110 +5,96 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PrefixParser : IParser { + public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) + where TScanner : struct, IScanner + => new PrefixParser().Match(ref scanner, result, out prefix, in orError); + + public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - var position = scanner.Position; - if (UnaryParsers.PrefixIncrement(ref scanner, result, out parsed)) - return true; - else if (UnaryParsers.Signed(ref scanner, result, out parsed)) - return true; - // prefix not - else if (UnaryParsers.Not(ref scanner, result, out parsed)) - return true; - // prefix cast - else if (UnaryParsers.Cast(ref scanner, result, out parsed)) - return true; - else if (UnaryParsers.Postfix(ref scanner, result, out var p)) - { - parsed = p; - return true; - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return CommonParsers.Alternatives( + ref scanner, + result, + out parsed, + orError, + PrefixIncrement, + Signed, + Not, + Cast, + PostfixParser.Postfix + ); } -} -public record struct PrefixIncrementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Not(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("++", ref scanner, advance: true)) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if (UnaryParsers.Postfix(ref scanner, result, out var lit)) - { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); - } - // prefix decrememnt - else if (Terminals.Literal("--", ref scanner, advance: true)) + if (Terminals.Set("!~", ref scanner)) { + var op = ((char)scanner.Peek()).ToOperator(); + scanner.Advance(1); CommonParsers.Spaces0(ref scanner, result, out _); - if (UnaryParsers.Postfix(ref scanner, result, out var lit)) + if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); - + } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct NotExpressionParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Signed(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - parsed = null!; var position = scanner.Position; - if (Terminals.Set("!~", ref scanner)) + if (Terminals.Set("+-", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); CommonParsers.Spaces0(ref scanner, result, out _); - if (UnaryParsers.Postfix(ref scanner, result, out var lit)) + if (Prefix(ref scanner, result, out var lit)) { parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); - + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} - -public record struct SignExpressionParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + + public static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Set("+-", ref scanner)) + if (Terminals.Literal("++", ref scanner, advance: true)) { - var op = ((char)scanner.Peek()).ToOperator(); - scanner.Advance(1); CommonParsers.Spaces0(ref scanner, result, out _); - if (UnaryParsers.Prefix(ref scanner, result, out var lit)) + if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + // prefix decrememnt + else if (Terminals.Literal("--", ref scanner, advance: true)) + { + CommonParsers.Spaces0(ref scanner, result, out _); + if (PostfixParser.Postfix(ref scanner, result, out var lit)) + { + parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + return true; + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + + } + else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct CastExpressionParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Cast(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -116,7 +102,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, result, UnaryParsers.Postfix, out Expression expression, withSpaces: true, advance: true) + && CommonParsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true) ) { parsed = new CastExpression(typeName.Name, Operator.Cast, expression, scanner.GetLocation(position, scanner.Position - position)); @@ -124,4 +110,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs deleted file mode 100644 index 364edeb3bf..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL; - - -public record struct UnaryParsers -{ - internal static bool Not(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) - where TScanner : struct, IScanner - => new NotExpressionParser().Match(ref scanner, result, out cast, in orError); - internal static bool Signed(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) - where TScanner : struct, IScanner - => new SignExpressionParser().Match(ref scanner, result, out cast, in orError); - internal static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PrefixIncrementParser().Match(ref scanner, result, out cast, in orError); - internal static bool Cast(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) - where TScanner : struct, IScanner - => new CastExpressionParser().Match(ref scanner, result, out cast, in orError); - public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PrefixParser().Match(ref scanner, result, out prefix, in orError); - public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression postfix, in ParseError? orError = null) - where TScanner : struct, IScanner - => new PostfixParser().Match(ref scanner, result, out postfix, in orError); -} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 2e80dcc8b3..39e41b580e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -5,105 +5,64 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct BufferParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - parsed = null!; - if (CBuffer(ref scanner, result, out var cbuff, orError)) - { - parsed = cbuff; - return true; - } - else if (TBuffer(ref scanner, result, out var tbuff, orError)) - { - parsed = tbuff; - return true; - } - else if (RGroup(ref scanner, result, out var rgroup, orError)) - { - parsed = rgroup; - return true; - } - return false; - } - public static bool Buffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new BufferParsers().Match(ref scanner, result, out parsed, orError); - public static bool TBuffer(ref TScanner scanner, ParseResult result, out TBuffer parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new TBufferParser().Match(ref scanner, result, out parsed, orError); - - public static bool CBuffer(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new CBufferParser().Match(ref scanner, result, out parsed, orError); - public static bool RGroup(ref TScanner scanner, ParseResult result, out RGroup parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new RGroupParser().Match(ref scanner, result, out parsed, orError); - - public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new BufferMemberParser().Match(ref scanner, result, out parsed, orError); - - public static bool BufferName(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) - where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return CommonParsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); + return CommonParsers.Alternatives( + ref scanner, result, out parsed, in orError, + CBuffer, + TBuffer, + RGroup + ); } -} -public record struct RGroupParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out RGroup parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool TBuffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("rgroup", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Terminals.Literal("tbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - BufferParsers.BufferName(ref scanner, result, out var identifiers) + BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner, advance: true)) + if (Terminals.Char('{', ref scanner)) { List members = []; CommonParsers.Spaces0(ref scanner, result, out _); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + do { - if ( - BufferParsers.Member(ref scanner, result, out var member) - && CommonParsers.Spaces0(ref scanner, result, out _) - ) + if (Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) members.Add(member); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) + while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); + if (Terminals.Char('}', ref scanner, advance: true)) { - Members = members - }; - return true; - + parsed = new TBuffer(identifiers, scanner.GetLocation(position..scanner.Position)) + { + Members = members + }; + return true; + } } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); ; } -} - -public record struct CBufferParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out CBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool CBuffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; if (Terminals.Literal("cbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - BufferParsers.BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) && CommonParsers.Spaces0(ref scanner, result, out _) ) { @@ -114,7 +73,7 @@ public record struct CBufferParser : IParser while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { if ( - BufferParsers.Member(ref scanner, result, out var member) + Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _) ) members.Add(member); @@ -122,7 +81,7 @@ public record struct CBufferParser : IParser } if (scanner.IsEof) return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) + parsed = new CBuffer(identifiers, scanner.GetLocation(position..scanner.Position)) { Members = members }; @@ -133,51 +92,49 @@ public record struct CBufferParser : IParser } } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } -} -public record struct TBufferParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out TBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + + public static bool RGroup(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("tbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Terminals.Literal("rgroup", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) { if ( - BufferParsers.BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + BufferName(ref scanner, result, out var identifiers) && CommonParsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner)) + if (Terminals.Char('{', ref scanner, advance: true)) { List members = []; CommonParsers.Spaces0(ref scanner, result, out _); - do + while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) { - if (BufferParsers.Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) + if ( + Member(ref scanner, result, out var member) + && CommonParsers.Spaces0(ref scanner, result, out _) + ) members.Add(member); + else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); } - while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); - if (Terminals.Char('}', ref scanner, advance: true)) + if (scanner.IsEof) + return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + parsed = new RGroup(identifiers, scanner.GetLocation(position..scanner.Position)) { - parsed = new(identifiers, scanner.GetLocation(position..scanner.Position)) - { - Members = members - }; - return true; - } + Members = members + }; + return true; + } else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); ; - + return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct BufferMemberParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) + where TScanner : struct, IScanner { CommonParsers.Spaces0(ref scanner, result, out _); var position = scanner.Position; @@ -202,4 +159,10 @@ public record struct BufferMemberParser : IParser } return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); } -} + + public static bool BufferName(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + return CommonParsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index 0748def73b..b1241fa643 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -1,7 +1,7 @@  - net8.0 + net9.0 enable enable latest diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj index 584b915ef5..e49df807a6 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index b8454dc409..17dc13560f 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable true diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj index ce4b9ceabc..c748a98e28 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj @@ -6,7 +6,7 @@ Exe - net8.0 + net9.0 enable enable diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj index 288f00d98c..f87fca4119 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj +++ b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable From 27a71ad80ce2d4704c5713c581fb1f0c71ff2f65 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Nov 2024 20:23:35 +0100 Subject: [PATCH 0370/1182] correction in executable files --- src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj | 5 +++++ src/Stride.Shaders.LSP/log20240709.txt | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) delete mode 100644 src/Stride.Shaders.LSP/log20240709.txt diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index e3228ce9ff..4c8ac9a03f 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -7,6 +7,7 @@ enable + @@ -17,4 +18,8 @@ + + ..\sdsl-language-support\bin\ + + diff --git a/src/Stride.Shaders.LSP/log20240709.txt b/src/Stride.Shaders.LSP/log20240709.txt deleted file mode 100644 index 58a4756da3..0000000000 --- a/src/Stride.Shaders.LSP/log20240709.txt +++ /dev/null @@ -1,4 +0,0 @@ -2024-07-09 17:28:06.797 +02:00 [INF] This only goes file... -2024-07-09 17:28:07.048 +02:00 [INF] Configuring -2024-07-09 17:28:07.048 +02:00 [INF] inside ctor -2024-07-09 17:28:07.053 +02:00 [INF] Fooooo! From 368fdba383b0e22555edc159bff56940d7781456 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Nov 2024 21:15:50 +0100 Subject: [PATCH 0371/1182] solved all extensions issues --- .gitignore | 4 +++- src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj | 5 ----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 981fdf3b42..e597410b83 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ obj/ .fake .vs/ .antlr/ -/src/SDSLParserExample/Properties/launchSettings.json \ No newline at end of file +/src/SDSLParserExample/Properties/launchSettings.json +log*.txt +*.vsix \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index 4c8ac9a03f..13a3d7795e 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -17,9 +17,4 @@ - - - ..\sdsl-language-support\bin\ - - From 82189f9d32ad2d9945b9718b42228e7174d50a96 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 24 Nov 2024 21:19:33 +0100 Subject: [PATCH 0372/1182] publish lsp for extension --- src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index 13a3d7795e..b378010b9a 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -17,4 +17,10 @@ + + + ..\sdsl-language-support\bin\ + false + + From 9f57ab2d332095a772c0813ac9e942d2ecc71bf4 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Thu, 27 Feb 2025 11:24:59 +0100 Subject: [PATCH 0373/1182] Extension data (#18) Adding semantic data on the syntax tree. Refactor of the parser --- SDSL.sln | 7 + assets/SDSL/Test.sdsl | 39 +- .../Stride.Shaders.Core.csproj | 14 + src/Stride.Shaders.Core/Symbol.cs | 22 ++ src/Stride.Shaders.Core/SymbolFrame.cs | 29 ++ src/Stride.Shaders.Core/SymbolProvider.cs | 7 + .../SymbolTypes.Globals.cs | 72 ++++ src/Stride.Shaders.Core/SymbolTypes.cs | 144 ++++++++ src/Stride.Shaders.LSP/Foo.cs | 10 +- .../DidChangeWatchedFilesHandler.cs | 0 .../{ => Handlers}/FoldingRangeHandler.cs | 35 +- .../Handlers/HoverHandler.cs | 149 ++++++++ .../{ => Handlers}/SemanticTokensHandler.cs | 41 ++- .../{ => Handlers}/TextDocumentHandler.cs | 88 +++-- src/Stride.Shaders.LSP/Program.cs | 7 +- src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs | 21 ++ .../Stride.Shaders.LSP.csproj | 5 + .../Examples.cs | 100 +++++- .../Program.cs | 12 +- .../ParsingTests.cs | 28 +- src/Stride.Shaders.Parsing/ASTNode.cs | 26 +- .../Analysis/OperatorTable.cs | 79 ++++ src/Stride.Shaders.Parsing/Analysis/SDIR.cs | 24 ++ .../Analysis/SymbolTable.ConstExpr.cs | 73 ++++ .../Analysis/SymbolTable.cs | 45 +++ .../Analysis/TypeNameExtensions.cs | 16 + src/Stride.Shaders.Parsing/Grammar.cs | 8 +- .../PreProcessing/CMacros/CommentPhase.cs | 10 +- .../PreProcessing/CommentProcessedCode.cs | 14 +- .../PreProcessing/MacroPreProcessor.cs | 13 +- .../SDFX/Parsers/EffectParser.cs | 27 +- .../EffectStatementParsers.Conditional.cs | 70 ++-- .../Parsers/EffectStatementParsers.Flow.cs | 35 +- .../SDFX/Parsers/EffectStatementParsers.cs | 166 ++++----- .../SDFX/Parsers/ParamsParsers.cs | 42 +-- .../SDSL/AST/AssignOperator.cs | 2 + .../SDSL/AST/Expression.cs | 50 ++- .../SDSL/AST/Literals.cs | 132 ++++++- src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs | 33 ++ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 65 +++- .../SDSL/AST/ShaderElements.cs | 72 +++- .../SDSL/AST/ShaderGenericsValues.cs | 9 - .../SDSL/AST/Statements.Control.cs | 17 + .../SDSL/AST/Statements.cs | 98 ++++- .../SDSL/AST/SymbolTypeProcess.cs | 61 ++++ .../SDSL/Analysis/GlobalSymbolTypes.cs | 31 -- .../SDSL/Analysis/Symbol.cs | 18 - .../SDSL/Analysis/SymbolTable.cs | 65 ---- .../SDSL/Analysis/SymbolTypes.cs | 49 --- .../SDSL/Parsers/Common/CommonParsers.cs | 84 +++-- .../DirectiveBinaryParsers.cs | 148 ++++---- .../DirectiveExpressions/DirectiveParsers.cs | 118 +++--- .../DirectivePrimaryExpressionParsers.cs | 24 +- .../DirectiveUnaryParsers.Postfix.cs | 196 ---------- .../DirectiveUnaryParsers.Prefix.cs | 50 +-- .../ExpressionParsers/BinaryParsers.cs | 150 ++++---- .../PrimaryExpressionParsers.cs | 46 +-- .../ExpressionParsers/UnaryParsers.Postfix.cs | 217 +++++------ .../ExpressionParsers/UnaryParsers.Prefix.cs | 52 +-- .../Parsers/LiteralParsers/LiteralParsers.cs | 338 +++++++++--------- .../Parsers/LiteralParsers/NumberParsers.cs | 138 +++---- .../ShaderParsers/CompositionParsers.cs | 20 +- .../ShaderParsers/ShaderAttributeParsers.cs | 38 +- .../ShaderParsers/ShaderBufferParsers.Cs | 84 ++--- .../ShaderParsers/ShaderClassParser.cs | 100 +++--- .../ShaderParsers/ShaderDataParsers.cs | 138 +++---- .../ShaderParsers/ShaderElementParsers.cs | 40 +-- .../ShaderParsers/ShaderFileParsers.cs | 89 ++--- .../ShaderParsers/ShaderMethodParsers.cs | 82 ++--- .../Parsers/ShaderParsers/ShaderParameters.cs | 40 +-- .../StatementParsers.Control.cs | 72 ++-- .../StatementParsers/StatementParsers.Flow.cs | 98 ++--- .../StatementParsers/StatementParsers.cs | 152 ++++---- .../SDSL/Parsers/Terminals/Terminals.cs | 58 +-- src/Stride.Shaders.Parsing/SDSLERR.cs | 13 +- .../Scanners/IScanner.cs | 7 +- .../Scanners/Scanner.cs | 16 +- .../Scanners/ScannerGeneric.cs | 4 + .../Scanners/TextLocation.cs | 3 + .../Stride.Shaders.Parsing.csproj | 1 + .../Stride.Shaders.Spirv/CFG/BasicBlock.cs | Bin 0 -> 1076 bytes .../Stride.Shaders.Spirv.csproj | 1 + 82 files changed, 2844 insertions(+), 1953 deletions(-) create mode 100644 src/Stride.Shaders.Core/Stride.Shaders.Core.csproj create mode 100644 src/Stride.Shaders.Core/Symbol.cs create mode 100644 src/Stride.Shaders.Core/SymbolFrame.cs create mode 100644 src/Stride.Shaders.Core/SymbolProvider.cs create mode 100644 src/Stride.Shaders.Core/SymbolTypes.Globals.cs create mode 100644 src/Stride.Shaders.Core/SymbolTypes.cs rename src/Stride.Shaders.LSP/{ => Handlers}/DidChangeWatchedFilesHandler.cs (100%) rename src/Stride.Shaders.LSP/{ => Handlers}/FoldingRangeHandler.cs (54%) create mode 100644 src/Stride.Shaders.LSP/Handlers/HoverHandler.cs rename src/Stride.Shaders.LSP/{ => Handlers}/SemanticTokensHandler.cs (72%) rename src/Stride.Shaders.LSP/{ => Handlers}/TextDocumentHandler.cs (78%) create mode 100644 src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs create mode 100644 src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs create mode 100644 src/Stride.Shaders.Parsing/Analysis/SDIR.cs create mode 100644 src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs create mode 100644 src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs create mode 100644 src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs create mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs create mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs diff --git a/SDSL.sln b/SDSL.sln index 6947481a58..ce5a63e6e4 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -33,6 +33,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "submodules\CppNet EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "submodules", "submodules", "{5889489A-15EB-4324-ACBC-3A4C9F11A39C}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Core", "src\Stride.Shaders.Core\Stride.Shaders.Core.csproj", "{C2EE00B4-6CDA-498B-A54E-610E66EBD397}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,6 +89,10 @@ Global {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.Build.0 = Release|Any CPU + {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -105,6 +111,7 @@ Global {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} {41050DB9-A819-4FC7-9D46-0ED054CAE7CB} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897} = {5889489A-15EB-4324-ACBC-3A4C9F11A39C} + {C2EE00B4-6CDA-498B-A54E-610E66EBD397} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A8CB18C1-53F2-4B53-B9FF-46BBBCA76534} diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index 6b11768cec..ae85a572a7 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,34 +1,19 @@ -partial effect machin { - -} +namespace Machin +{ + shader Test + { + stream float4 Position; + stream float4 Color; -namespace machin.something.Hello { - namespace machin; - namespace hello.world - { - partial shader machin + void PSMain() { - + streams.Position.w = 1.0; } - - effect machin { + void VSMain() + { + streams.Color = float4(1.0,0.0,1.0,1u32); } } - -} - - -// shader Main { -// struct Machin { -// [Link("hello")] -// stage something something; -// [Link("hello2", 1 , 3)] -// stage something[machin, machin, 3, machin(22), obo.obo] something; -// } - -// struct Machin { - -// } -// } \ No newline at end of file +} \ No newline at end of file diff --git a/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj b/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj new file mode 100644 index 0000000000..f68e932c9a --- /dev/null +++ b/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj @@ -0,0 +1,14 @@ + + + + net9.0 + enable + enable + + + + + + + + diff --git a/src/Stride.Shaders.Core/Symbol.cs b/src/Stride.Shaders.Core/Symbol.cs new file mode 100644 index 0000000000..5f5d616c7e --- /dev/null +++ b/src/Stride.Shaders.Core/Symbol.cs @@ -0,0 +1,22 @@ +namespace Stride.Shaders.Core; + + + + +public enum SymbolKind +{ + MixinParent, + MixinChild, + Struct, + Method, + Variable, + Constant, + ConstantGeneric, + Composition, + CBuffer, + TBuffer, + RGroup +} + +public record struct SymbolID(string Name, SymbolKind Kind); +public record struct Symbol(SymbolID Id, SymbolType Type); \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolFrame.cs b/src/Stride.Shaders.Core/SymbolFrame.cs new file mode 100644 index 0000000000..3066c463fa --- /dev/null +++ b/src/Stride.Shaders.Core/SymbolFrame.cs @@ -0,0 +1,29 @@ +namespace Stride.Shaders.Core; + + +public readonly struct SymbolFrame +{ + readonly Dictionary symbols; + + public SymbolFrame() + { + symbols = []; + } + + public Symbol this[string name, SymbolKind kind] => symbols[new(name, kind)]; + + public void Add(SymbolID name, Symbol symbol) + => symbols.Add(name, symbol); + public void Add(string name, SymbolKind kind, SymbolType type) + => symbols.Add(new(name, kind), new(new(name, kind), type)); + public bool TryAdd(string name, SymbolKind kind, SymbolType type) + => symbols.TryAdd(new(name, kind), new(new(name, kind), type)); + public void Remove(string name, SymbolKind kind) + => symbols.Remove(new(name, kind)); + public bool ContainsKey(SymbolID name) => symbols.ContainsKey(name); + public bool ContainsValue(Symbol symbol) => symbols.ContainsValue(symbol); + public bool TryGetValue(string name, SymbolKind kind, out Symbol symbol) + => symbols.TryGetValue(new(name, kind), out symbol); + + public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolProvider.cs b/src/Stride.Shaders.Core/SymbolProvider.cs new file mode 100644 index 0000000000..9e07b770b5 --- /dev/null +++ b/src/Stride.Shaders.Core/SymbolProvider.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders.Core; + +public interface ISymbolProvider +{ + public Dictionary DeclaredTypes { get; } + public SymbolFrame RootSymbols { get; } +} diff --git a/src/Stride.Shaders.Core/SymbolTypes.Globals.cs b/src/Stride.Shaders.Core/SymbolTypes.Globals.cs new file mode 100644 index 0000000000..43f6a3cb54 --- /dev/null +++ b/src/Stride.Shaders.Core/SymbolTypes.Globals.cs @@ -0,0 +1,72 @@ +using System.Collections.Frozen; + +namespace Stride.Shaders.Core; + + +public partial record Scalar +{ + public static string[] names = [ + "bool", + "byte", + "sbyte", + "short", + "ushort", + "half", + "int", + "uint", + "float", + "long", + "ulong", + "double" + ]; + public static Scalar From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + + // static Scalar() + // { + // var arr = new KeyValuePair[names.Length + 1]; + // arr[0] = new("void", new("void")); + // for(int i = 1; i < names.Length; i++) + // arr[i] = new(names[i], new(names[i])); + // Types = FrozenDictionary.ToFrozenDictionary(arr); + // } + internal static FrozenDictionary Init() + { + var arr = new KeyValuePair[names.Length + 1]; + arr[0] = new("void", new("void")); + for(int i = 1; i < names.Length + 1; i++) + arr[i] = new(names[i - 1], new(names[i - 1])); + return arr.ToFrozenDictionary(); + } +} + +public partial record Vector +{ + public static Vector From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + + internal static FrozenDictionary Init() + { + var arr = new KeyValuePair[Scalar.names.Length * 4]; + for(int i = 0; i < Scalar.names.Length; i++) + for(int x = 1; x < 5; x++) + arr[i * 4 + (x - 1)] = new($"{Scalar.names[i]}{x}", new(Scalar.From(Scalar.names[i]),x)); + return arr.ToFrozenDictionary(); + } +} + + +public partial record Matrix +{ + public static Matrix From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + internal static FrozenDictionary Init() + { + var arr = new KeyValuePair[Scalar.names.Length * 4 * 4]; + for(int i = 0; i < Scalar.names.Length; i++) + for(int x = 1; x < 5; x++) + for(int y = 1; y < 5; y++) + arr[i * 16 + (x - 1) * 4 + (y - 1) * 4] = new($"{Scalar.names[i]}{x}x{y}", new(Scalar.From(Scalar.names[i]),x,y)); + return arr.ToFrozenDictionary(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolTypes.cs b/src/Stride.Shaders.Core/SymbolTypes.cs new file mode 100644 index 0000000000..7d3c221188 --- /dev/null +++ b/src/Stride.Shaders.Core/SymbolTypes.cs @@ -0,0 +1,144 @@ +using System.Security.Cryptography.X509Certificates; +using Microsoft.VisualBasic; + +namespace Stride.Shaders.Core; + + + +public abstract record SymbolType() +{ + public static bool TryGetNumeric(string name, out SymbolType? result) + { + if(Scalar.Types.TryGetValue(name, out var s)) + { + result = s; + return true; + } + else if(Vector.Types.TryGetValue(name, out var v)) + { + result = v; + return true; + } + else if(Matrix.Types.TryGetValue(name, out var m)) + { + result = m; + return true; + } + else if (name == "void") + { + result = Scalar.From("void"); + return true; + } + else + { + result = null; + return true; + } + } +} + +public sealed record Undefined(string TypeName) : SymbolType() +{ + public override string ToString() + { + return TypeName; + } +} +public sealed partial record Scalar(string TypeName) : SymbolType() +{ + public override string ToString() + { + return TypeName; + } +} +public sealed partial record Vector(Scalar BaseType, int Size) : SymbolType() +{ + public override string ToString() + { + return $"{BaseType}{Size}"; + } +} +public sealed partial record Matrix(Scalar BaseType, int Rows, int Columns) : SymbolType() +{ + public override string ToString() + { + return $"{BaseType}{Rows}x{Columns}"; + } +} +public sealed record Array(SymbolType BaseType, int Size) : SymbolType() +{ + public override string ToString() + { + return $"{BaseType}[{Size}]"; + } +} +public sealed record Struct(string Name, Dictionary Fields) : SymbolType() +{ + public override string ToString() + { + return $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Value} {x.Key}"))}}}"; + } +} +public sealed record Buffer(SymbolType BaseType, int Size) : SymbolType() +{ + public override string ToString() + { + return $"Buffer<{BaseType}, {Size}>"; + } +} + + +public abstract record Texture(SymbolType BaseType) : SymbolType() +{ + public override string ToString() + { + return $"Texture<{BaseType}>"; + } +} +public sealed record Texture1D(SymbolType BaseType, int Size) : Texture(BaseType) +{ + public override string ToString() + { + return $"Texture<{BaseType}, {Size}>"; + } +} +public sealed record Texture2D(SymbolType BaseType, int Width, int Height) : Texture(BaseType) +{ + public override string ToString() + { + return $"Texture<{BaseType}, {Width}, {Height}>"; + } +} +public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : Texture(BaseType) +{ + public override string ToString() + { + return $"Texture<{BaseType}, {Width}, {Height}, {Depth}>"; + } +} + + +public sealed record BufferSymbol(string Name, List Symbols) : SymbolType; +public sealed record ParamsSymbol(string Name, List Symbols) : SymbolType; +public sealed record EffectSymbol(string Name, List Symbols) : SymbolType; +public sealed record ShaderSymbol(string Name, List Components) : SymbolType +{ + public Symbol Get(string name, SymbolKind kind) + { + foreach (var e in Components) + if (e.Id.Kind == kind && e.Id.Name == name) + return e; + throw new ArgumentException($"{name} not found in Mixin {Name}"); + } + public bool TryGet(string name, SymbolKind kind, out Symbol? value) + { + foreach (var e in Components) + if (e.Id.Kind == kind && e.Id.Name == name) + { + value = e; + return true; + } + value = null!; + return false; + } +} diff --git a/src/Stride.Shaders.LSP/Foo.cs b/src/Stride.Shaders.LSP/Foo.cs index 15bce05436..0437c8ce57 100644 --- a/src/Stride.Shaders.LSP/Foo.cs +++ b/src/Stride.Shaders.LSP/Foo.cs @@ -3,15 +3,9 @@ namespace Stride.Shaders.Parsing.LSP; -internal class Foo +internal class Foo(ILogger logger) { - private readonly ILogger _logger; - - public Foo(ILogger logger) - { - logger.LogInformation("inside ctor"); - _logger = logger; - } + private readonly ILogger _logger = logger; public void SayFoo() { diff --git a/src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs b/src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs similarity index 100% rename from src/Stride.Shaders.LSP/DidChangeWatchedFilesHandler.cs rename to src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs diff --git a/src/Stride.Shaders.LSP/FoldingRangeHandler.cs b/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs similarity index 54% rename from src/Stride.Shaders.LSP/FoldingRangeHandler.cs rename to src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs index 7fa6e63b51..bb07ec0395 100644 --- a/src/Stride.Shaders.LSP/FoldingRangeHandler.cs +++ b/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs @@ -18,19 +18,28 @@ public FoldingRangeRegistrationOptions GetRegistrationOptions() => public Task?> Handle( FoldingRangeRequestParam request, CancellationToken cancellationToken - ) => - Task.FromResult?>( - new Container( - new FoldingRange - { - StartLine = 10, - EndLine = 20, - Kind = FoldingRangeKind.Region, - EndCharacter = 0, - StartCharacter = 0 - } - ) - ); + ) + { + var result = SDSLParser.Parse(File.ReadAllText(request.TextDocument.Uri.GetFileSystemPath())); + if (result.AST is ShaderFile sf && sf.Namespaces.Count > 0) + { + var ns = sf.Namespaces.First(); + return Task.FromResult?>( + new Container( + new FoldingRange + { + StartLine = ns.Info.Line, + EndLine = ns.Info.EndLine, + StartCharacter = ns.Info.Column, + EndCharacter = ns.Info.EndColumn, + Kind = FoldingRangeKind.Region + } + ) + ); + } + + return Task.FromResult?>(null); + } public FoldingRangeRegistrationOptions GetRegistrationOptions(FoldingRangeCapability capability, ClientCapabilities clientCapabilities) => new FoldingRangeRegistrationOptions { diff --git a/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs b/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs new file mode 100644 index 0000000000..6e0f621eeb --- /dev/null +++ b/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs @@ -0,0 +1,149 @@ +using Microsoft.Extensions.Logging; +using OmniSharp.Extensions.LanguageServer.Protocol; +using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; +using OmniSharp.Extensions.LanguageServer.Protocol.Document; +using OmniSharp.Extensions.LanguageServer.Protocol.Models; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.LSP; + + + +public class HoverHandler(ILogger logger) : HoverHandlerBase +{ + + ILogger _logger = logger; + public override async Task Handle(HoverParams request, CancellationToken cancellationToken) + { + var content = MonoGamePreProcessor.Run( + await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(request.TextDocument.Uri) ?? "", cancellationToken).ConfigureAwait(false), + Path.GetFileName(DocumentUri.GetFileSystemPath(request.TextDocument.Uri))! + ); + var result = SDSLParser.Parse(content); + if (result.AST is ShaderFile sf && sf.Namespaces.Count > 0) + { + if (ComputeIntersection(request.Position, sf, out var description)) + { + return new Hover + { + Contents = description + }; + } + else return new Hover + { + Contents = new($"Hovering at : {request.Position}") + }; + } + return null; + } + + protected override HoverRegistrationOptions CreateRegistrationOptions(HoverCapability capability, ClientCapabilities clientCapabilities) + { + return new HoverRegistrationOptions + { + DocumentSelector = TextDocumentSelector.ForLanguage("sdsl"), + WorkDoneProgress = true + }; + } + + bool ComputeIntersection(Position position, Node node, out MarkedStringsOrMarkupContent description) + { + description = null!; + if (node is ShaderFile sf) + { + foreach (var ns in sf.Namespaces) + if (ns.Intersects(position)) + return ComputeIntersection(position, ns, out description); + foreach (var e in sf.RootDeclarations) + if (e.Intersects(position)) + return ComputeIntersection(position, e, out description); + } + else if (node is ShaderNamespace sn) + { + if (sn.Namespace is not null && sn.Namespace.Intersects(position)) + { + description = new(sn.Namespace.ToString()); + return true; + } + foreach (var decl in sn.Declarations) + { + if (decl.Intersects(position)) + return ComputeIntersection(position, decl, out description); + } + } + else if (node is ShaderClass sc) + { + if (sc.Name.Intersects(position)) + { + description = new($"shader {sc.Name}"); + return true; + } + foreach (var parent in sc.Mixins) + if (parent.Intersects(position)) + { + description = new($"mixin {parent}"); + return true; + } + foreach (var e in sc.Elements) + if (e.Intersects(position)) + return ComputeIntersection(position, e, out description); + } + else if (node is ShaderMember member) + { + if (member.TypeName.Intersects(position)) + { + description = new($"{member.TypeName}"); + return true; + } + else + { + description = new( new MarkedString("SDSL", $"{member.Info.Text}")); + return true; + } + } + else if (node is ShaderMethod method) + { + if (method.Name.Intersects(position)) + { + description = new($"method {method.Name}"); + return true; + } + foreach (var arg in method.Parameters) + if (arg.Intersects(position)) + { + description = new($"argument {arg.Name}"); + return true; + } + if (method.Body is not null) + foreach (var s in method.Body.Statements) + if (s.Intersects(position)) + return ComputeIntersection(position, s, out description); + } + return false; + } + + //static bool ComputeIntersection(Position position, ShaderFile file, out string description) + //{ + // description = ""; + // foreach (var ns in file.Namespaces) + // { + // if (ns.Namespace is not null && ns.Namespace.Intersects(position)) + // { + // description = ns.Namespace.ToString(); + // return true; + // } + // else + // { + // foreach (var decl in ns.Declarations) + // { + // if (decl is ShaderClass sclass && sclass.Intersects(position)) + // { + // description = $"shader {sclass.Name}"; + // return true; + // } + // } + // } + // } + // return false; + //} +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/SemanticTokensHandler.cs b/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs similarity index 72% rename from src/Stride.Shaders.LSP/SemanticTokensHandler.cs rename to src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs index 6f0c3f0620..b3bd01f2fb 100644 --- a/src/Stride.Shaders.LSP/SemanticTokensHandler.cs +++ b/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs @@ -13,14 +13,9 @@ namespace Stride.Shaders.Parsing.LSP; -public class SemanticTokensHandler : SemanticTokensHandlerBase +public class SemanticTokensHandler(ILogger logger) : SemanticTokensHandlerBase { - private readonly ILogger _logger; - - public SemanticTokensHandler(ILogger logger) - { - _logger = logger; - } + private readonly ILogger _logger = logger; public override async Task Handle( SemanticTokensParams request, CancellationToken cancellationToken @@ -58,19 +53,27 @@ CancellationToken cancellationToken var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(identifier), cancellationToken).ConfigureAwait(false); await Task.Yield(); - foreach (var (line, text) in content.Split('\n').Select((text, line) => (line, text))) + var result = SDSLParser.Parse(content); + if(result.AST is ShaderFile sf && sf.Namespaces.Count > 0) { - var parts = text.TrimEnd().Split(';', ' ', '.', '"', '(', ')'); - var index = 0; - foreach (var part in parts) - { - typesEnumerator.MoveNext(); - modifiersEnumerator.MoveNext(); - if (string.IsNullOrWhiteSpace(part)) continue; - index = text.IndexOf(part, index, StringComparison.Ordinal); - builder.Push(line, index, part.Length, typesEnumerator.Current, modifiersEnumerator.Current); - } + var ns = sf.Namespaces[0]; + _logger.LogInformation($"Handling namespace : {ns.Namespace}"); + builder.Push(ns.Info.Line,ns.Info.Column, ns.Info.Length, SemanticTokenType.Namespace, SemanticTokenModifier.Declaration); } + + // foreach (var (line, text) in content.Split('\n').Select((text, line) => (line, text))) + // { + // var parts = text.TrimEnd().Split(';', ' ', '.', '"', '(', ')'); + // var index = 0; + // foreach (var part in parts) + // { + // typesEnumerator.MoveNext(); + // modifiersEnumerator.MoveNext(); + // if (string.IsNullOrWhiteSpace(part)) continue; + // index = text.IndexOf(part, index, StringComparison.Ordinal); + // builder.Push(line, index, part.Length, typesEnumerator.Current, modifiersEnumerator.Current); + // } + // } } protected override Task @@ -95,7 +98,7 @@ protected override SemanticTokensRegistrationOptions CreateRegistrationOptions( { return new SemanticTokensRegistrationOptions { - DocumentSelector = TextDocumentSelector.ForLanguage("csharp"), + DocumentSelector = TextDocumentSelector.ForLanguage("sdsl"), Legend = new SemanticTokensLegend { TokenModifiers = capability.TokenModifiers, diff --git a/src/Stride.Shaders.LSP/TextDocumentHandler.cs b/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs similarity index 78% rename from src/Stride.Shaders.LSP/TextDocumentHandler.cs rename to src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs index d8f06e2bb9..f12fe6669e 100644 --- a/src/Stride.Shaders.LSP/TextDocumentHandler.cs +++ b/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs @@ -13,6 +13,7 @@ using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; using OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone; using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; +using Serilog; using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range; namespace Stride.Shaders.Parsing.LSP; @@ -22,7 +23,7 @@ internal class TextDocumentHandler : TextDocumentSyncHandlerBase private readonly ILogger _logger; private readonly ILanguageServerConfiguration _configuration; - private readonly TextDocumentSelector _textDocumentSelector = new TextDocumentSelector( + private readonly TextDocumentSelector _textDocumentSelector = new( new TextDocumentFilter { Pattern = "**/*.sdsl" @@ -40,10 +41,10 @@ public TextDocumentHandler(ILogger logger, Foo foo, ILangua public override Task Handle(DidChangeTextDocumentParams notification, CancellationToken token) { - _logger.LogCritical("Critical"); - _logger.LogDebug("Debug"); - _logger.LogTrace("Trace"); - _logger.LogInformation("Hello world!"); + // _logger.LogCritical("Critical"); + // _logger.LogDebug("Debug"); + // _logger.LogTrace("Trace"); + // _logger.LogInformation("Hello world!"); return Unit.Task; } @@ -88,42 +89,57 @@ CancellationToken cancellationToken var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(request), cancellationToken).ConfigureAwait(false); var lines = content.Split('\n'); var symbols = new List(); - for (var lineIndex = 0; lineIndex < lines.Length; lineIndex++) + + var result = SDSLParser.Parse(content); + if (result.AST is ShaderNamespace nsp) { - var line = lines[lineIndex]; - var parts = line.Split(' ', '.', '(', ')', '{', '}', '[', ']', ';'); - var currentCharacter = 0; - foreach (var part in parts) - { - if (string.IsNullOrWhiteSpace(part)) + Log.Information($"{nsp.NamespacePath} is being treated"); + symbols.Add( + new DocumentSymbol() { - currentCharacter += part.Length + 1; - continue; + Kind = SymbolKind.Namespace, + Name = string.Join(".", nsp.NamespacePath.Select(x => x.Name)), + Range = new Range(nsp.Info.Line, nsp.Info.Column, nsp.Info.EndLine, nsp.Info.EndColumn) } - - symbols.Add( - new DocumentSymbol - { - Detail = part, - Deprecated = true, - Kind = SymbolKind.Field, - Tags = new[] { SymbolTag.Deprecated }, - Range = new Range( - new Position(lineIndex, currentCharacter), - new Position(lineIndex, currentCharacter + part.Length) - ), - SelectionRange = - new Range( - new Position(lineIndex, currentCharacter), - new Position(lineIndex, currentCharacter + part.Length) - ), - Name = part - } - ); - currentCharacter += part.Length + 1; - } + ); } + // for (var lineIndex = 0; lineIndex < lines.Length; lineIndex++) + // { + // var line = lines[lineIndex]; + // var parts = line.Split(' ', '.', '(', ')', '{', '}', '[', ']', ';'); + // var currentCharacter = 0; + // foreach (var part in parts) + // { + // if (string.IsNullOrWhiteSpace(part)) + // { + // currentCharacter += part.Length + 1; + // continue; + // } + + // symbols.Add( + // new DocumentSymbol + // { + // Detail = part, + // Deprecated = true, + // Kind = SymbolKind.Field, + // Tags = new[] { SymbolTag.Deprecated }, + // Range = new Range( + // new Position(lineIndex, currentCharacter), + // new Position(lineIndex, currentCharacter + part.Length) + // ), + // SelectionRange = + // new Range( + // new Position(lineIndex, currentCharacter), + // new Position(lineIndex, currentCharacter + part.Length) + // ), + // Name = part + // } + // ); + // currentCharacter += part.Length + 1; + // } + // } + // await Task.Delay(2000, cancellationToken); return symbols; } diff --git a/src/Stride.Shaders.LSP/Program.cs b/src/Stride.Shaders.LSP/Program.cs index 6867c0af25..41f51a2e19 100644 --- a/src/Stride.Shaders.LSP/Program.cs +++ b/src/Stride.Shaders.LSP/Program.cs @@ -14,12 +14,10 @@ static async Task MainAsync() { Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() - .WriteTo.File("log.txt", rollingInterval: RollingInterval.Day) + .WriteTo.File("log.txt", rollingInterval: RollingInterval.Minute) .MinimumLevel.Verbose() .CreateLogger(); - Log.Logger.Information("This only goes file..."); - IObserver workDone = null!; var server = await LanguageServer.From( @@ -35,7 +33,8 @@ static async Task MainAsync() ) .WithHandler() .WithHandler() - .WithHandler() + // .WithHandler() + .WithHandler() .WithHandler() .WithHandler() .WithHandler() diff --git a/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs b/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs new file mode 100644 index 0000000000..8b30ca6759 --- /dev/null +++ b/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs @@ -0,0 +1,21 @@ +using OmniSharp.Extensions.LanguageServer.Protocol.Models; + +namespace Stride.Shaders.Parsing.LSP; + +public static class ASTExtensions +{ + public static bool Intersects(this N node, Position position) + where N : Node + { + if ( + position.Line + 1 >= node.Info.Line + && position.Line + 1 <= node.Info.EndLine + && position.Character + 1 >= node.Info.Column + && position.Character + 1 < node.Info.Column + node.Info.Length + ) + { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index b378010b9a..dab5471a22 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -18,6 +18,11 @@ + + + + + ..\sdsl-language-support\bin\ false diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Parsing.Experiments/Examples.cs index 90b310cd46..8ff65814f7 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Examples.cs @@ -5,10 +5,35 @@ using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Experiments; +public record struct TextPosition(int Line, int Character) +{ + public static implicit operator TextPosition((int, int) pos) => new TextPosition(pos.Item1, pos.Item2); +} +public static class ASTExtensions +{ + public static bool Intersects(this N node, TextPosition position) + where N : Node + { + + if ( + position.Line + 1 >= node.Info.Line + && position.Line + 1 <= node.Info.EndLine + && position.Character + 1 >= node.Info.Column + && position.Character + 1 < node.Info.Column + node.Info.Length + ) + { + return true; + } + return false; + } +} + public static class Examples { static uint[] words = [ @@ -80,7 +105,7 @@ public static void SpvOpt() public static void ParseSDSL() { - var text = MonoGamePreProcessor.Run("./assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl", []); + var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/Test.sdsl"); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); if(parsed.Errors.Count > 0) @@ -89,6 +114,11 @@ public static void ParseSDSL() foreach (var e in parsed.Errors) Console.WriteLine(e); } + else + { + var table = new SymbolTable(); + parsed.AST?.ProcessSymbol(table); + } } public static void TryAllFiles() @@ -98,7 +128,7 @@ public static void TryAllFiles() // var text = File.ReadAllText(f); if (f.Contains("BasicMixin.sdsl")) continue; - var preprocessed = MonoGamePreProcessor.Run(f, []); + var preprocessed = MonoGamePreProcessor.OpenAndRun(f); var parsed = SDSLParser.Parse(preprocessed); if(parsed.Errors.Count > 0) { @@ -116,4 +146,68 @@ public static void TryAllFiles() } Console.ForegroundColor = ConsoleColor.White; } -} \ No newline at end of file + static bool ComputeIntersection(TextPosition position, Node node, out Node n) + { + n = null!; + if (node is ShaderFile sf) + { + foreach (var ns in sf.Namespaces) + if (ns.Intersects(position)) + return ComputeIntersection(position, ns, out n); + foreach (var e in sf.RootDeclarations) + if (e.Intersects(position)) + return ComputeIntersection(position, e, out n); + } + else if (node is ShaderNamespace sn) + { + if (sn.Namespace is not null && sn.Namespace.Intersects(position)) + { + n = sn.Namespace; + return true; + } + foreach (var decl in sn.Declarations) + { + if (decl.Intersects(position)) + return ComputeIntersection(position, decl, out n); + } + } + else if (node is ShaderClass sc) + { + if (sc.Name.Intersects(position)) + { + n = sc.Name; + return true; + } + foreach (var parent in sc.Mixins) + if (parent.Intersects(position)) + { + n = parent; + return true; + } + foreach (var e in sc.Elements) + if (e.Intersects(position)) + return ComputeIntersection(position, e, out n); + } + else if (node is ShaderMethod method) + { + if (method.Name.Intersects(position)) + { + n = method.Name; + return true; + } + foreach (var arg in method.Parameters) + if (arg.Intersects(position)) + { + n = arg; + return true; + } + if (method.Body is not null) + foreach (var s in method.Body.Statements) + if (s.Intersects(position)) + return ComputeIntersection(position, s, out n); + } + return false; + } +} + + diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs index 1bbd295a06..31ea71f403 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ b/src/Stride.Shaders.Parsing.Experiments/Program.cs @@ -6,11 +6,11 @@ // Examples.SpvOpt(); // Examples.TranslateHLSL(); -var matched = Grammar.Match("int uSeed = (int) (fSeed);"); -foreach(var e in matched.Errors) - Console.WriteLine(e); -Console.WriteLine(matched.AST); - -// Examples.ParseSDSL(); +// var matched = Grammar.Match("int uSeed = (int) (fSeed);"); +// foreach(var e in matched.Errors) +// Console.WriteLine(e); +// Console.WriteLine(matched.AST); +Examples.ParseSDSL(); +var x = 0; // Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs index ba7ae85e71..125acc8332 100644 --- a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs +++ b/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs @@ -1,5 +1,6 @@ using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; namespace Stride.Shaders.Parsing.Tests; public class ParsingTests1 @@ -20,30 +21,19 @@ public static IEnumerable GetShaderFilePaths() [Theory] [MemberData(nameof(GetShaderFilePaths))] - public void TestAllFiles(string path) + public void ParseFile(string path) { - var text = MonoGamePreProcessor.Run(path, []); + var text = MonoGamePreProcessor.OpenAndRun(path, []); var result = SDSLParser.Parse(text); Assert.True(result.Errors.Count == 0, path + string.Join("\n", result.Errors.Select(x => x.ToString()))); } - // [Theory] - // [InlineData("assets/SDSL/Commented.sdsl")] - // public void Test1(string path) - // { - // var shader = File.ReadAllText(path); - // Assert.True(shader.Length > 0); - // } - // [Theory] - // [InlineData("assets/Stride/Commented.sdsl")] - // public void TestMacro(string path) - // { - // var shader = File.ReadAllText(path); - // Assert.True(shader.Length > 0); - // } - // [Fact] - // public void Test2() + // [Theory] + // [MemberData(nameof(GetShaderFilePaths))] + // public void AnalyseFile(string path) // { - // Assert.True(true); + // var text = MonoGamePreProcessor.OpenAndRun(path, []); + // var result = SDSLParser.Parse(text); + // Assert.True(result.Errors.Count == 0, path + string.Join("\n", result.Errors.Select(x => x.ToString()))); // } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders.Parsing/ASTNode.cs index 84414bb33a..3c5ed0ec71 100644 --- a/src/Stride.Shaders.Parsing/ASTNode.cs +++ b/src/Stride.Shaders.Parsing/ASTNode.cs @@ -1,14 +1,18 @@ using System.Text; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing; public abstract class Node(TextLocation info) { public TextLocation Info { get; set; } = info; + public virtual void ProcessSymbol(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); } public class ValueNode(TextLocation info) : Node(info) { - public string? Type { get; set; } = null; + public virtual SymbolType? Type { get; set; } = null; } public class NoNode() : Node(new()); @@ -25,6 +29,14 @@ public class ShaderFile(TextLocation info) : Node(info) public List RootDeclarations { get; set; } = []; public List Namespaces { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + foreach (var e in RootDeclarations) + e.ProcessSymbol(table); + foreach (var ns in Namespaces) + ns.ProcessSymbol(table); + } + public override string ToString() { return $"{string.Join("\n", RootDeclarations)}\n\n{string.Join("\n", Namespaces)}"; @@ -33,15 +45,21 @@ public override string ToString() public class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) { - public List NamespacePath { get; set; } = []; + public List NamespacePath { get; set; } = []; } public class ShaderNamespace(TextLocation info) : Node(info) { - public List NamespacePath { get; set; } = []; - public string? Namespace { get; set; } + public List NamespacePath { get; set; } = []; + public Identifier? Namespace { get; set; } public List Declarations { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + foreach(var d in Declarations) + d.ProcessSymbol(table); + } + public override string ToString() { return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", Declarations)}End\n"; diff --git a/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs b/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs new file mode 100644 index 0000000000..ff0a66fb5a --- /dev/null +++ b/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs @@ -0,0 +1,79 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.Analysis; + +public static class OperatorTable +{ + + public static bool CheckBinaryOperation(SymbolType left, SymbolType right, Operator op) + { + int a = 0; + float b = 0; + var c = b * a; + return (left, right, op) switch + { + // Scalar operations + ( + Scalar { TypeName: "int" or "long" }, Scalar { TypeName: "int" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + or Operator.LeftShift or Operator.RightShift + or Operator.OR or Operator.XOR or Operator.AND + ) => true, + ( + Scalar { TypeName: "float" or "double" }, Scalar { TypeName: "double" or "float" or "int" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + ( + Scalar { TypeName: "float" } or Scalar { TypeName: "int" }, Scalar { TypeName: "float" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + + // Vector operations + ( + Vector { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, + Vector { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + // Matrix operations + ( + Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, + Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + ( + Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Vector { BaseType: Scalar { TypeName: "int" or "float" or "long" or "double" } }, + Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Vector { BaseType: Scalar { TypeName: "int" or "float" or "long" or "double" } }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + + _ => false, + }; + } + public static bool BinaryOperationResultingType(SymbolType left, SymbolType right, Operator op, out SymbolType? result) + { + long a = 0; + float b = 0; + float c = a * b; + // TODO : correct that part + result = ((int)op, left, right) switch + { + // Boolean operations + (>= 22 and < 26, Scalar{ TypeName : "bool"}, Scalar {TypeName: "bool"}) => left, + // Linear algebra + (>=8 and < 13, Scalar {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, Scalar r) when l.TypeName == r.TypeName => right, + (>=8 and < 13, Scalar { TypeName: "int" or "uint" or "long" or "ulong" }, Scalar { TypeName: "float" or "double"}) => right, + (>=8 and < 13, Scalar { TypeName: "float" }, Scalar { TypeName: "int" or "float" }) => left, + (>=8 and < 13, Vector l, Vector r) when l.BaseType == r.BaseType => right, + (>=8 and < 13, Vector, Scalar) => left, + (>=8 and < 13, Matrix l, Matrix r) when l.BaseType == r.BaseType => right, + (>=8 and < 13, Matrix l, Scalar r) => l, + (>=8 and < 13, Matrix l, Vector r) => l, + (>=8 and < 13, Matrix { BaseType: Scalar { TypeName: "int" } } l, Matrix { BaseType: Scalar { TypeName: "int" or "float" } } r) => l, + // Comparison + (>=18 and < 22, Scalar {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, Scalar r) when l.TypeName == r.TypeName => Scalar.From("bool"), + _ => null, + }; + return result != null; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SDIR.cs b/src/Stride.Shaders.Parsing/Analysis/SDIR.cs new file mode 100644 index 0000000000..59b2f6fc60 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Analysis/SDIR.cs @@ -0,0 +1,24 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Parsing.Analysis; + + +public enum IROp +{ + Nop, + Positive, Negative, BitwiseComplement, + Mul, Div, Mod, + Add, Sub, + LeftShift, RightShift, + Greater, GreaterThan, Lower, LowerThan, + Equals, NotEquals, + BitwiseAND, BitwiseXOR, BitwiseOR, + LogicalAND, LogicalOR, + +} + + +public record struct SDID( + string Name + +); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs new file mode 100644 index 0000000000..c957e95079 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs @@ -0,0 +1,73 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.Analysis; + +public partial class SymbolTable +{ + public bool IsConstantExpression(Expression expression) + { + if(expression is TernaryExpression tern) + return IsConstantExpression(tern.Condition) && IsConstantExpression(tern.Left) && IsConstantExpression(tern.Right); + else if(expression is BinaryExpression bin) + return IsConstantExpression(bin.Left) && IsConstantExpression(bin.Right); + else if(expression is Identifier identifier) + return TryFind(identifier, SymbolKind.Constant, out _); + else if(expression is NumberLiteral || expression is BoolLiteral) + return true; + else return false; + } + + // public bool TryFold(Expression expression, out Expression result) + // { + // if(expression is TernaryExpression tern) + // { + // if(TryFold(tern.Condition, out var cond)) + // tern.Condition = cond; + // if(TryFold(tern.Left, out var left)) + // tern.Left = left; + // if(TryFold(tern.Right, out var right)) + // tern.Right = right; + // result = tern; + // return true; + // } + // else if(expression is BinaryExpression bexp) + // { + // if(bexp.Left is not NumberLiteral || bexp.Left is not BoolLiteral) + // if(TryFold(bexp.Left, out var bleft)) + // bexp.Left = bleft; + // if(bexp.Right is not NumberLiteral || bexp.Right is not BoolLiteral) + // if(TryFold(bexp.Right, out var bright)) + // bexp.Right = bright; + // result = (bexp.Left, bexp.Op, bexp.Right) switch + // { + // (BoolLiteral l, Operator.LogicalAND, BoolLiteral r) => new BoolLiteral(false, bexp.Info), + // (BoolLiteral l, Operator.LogicalOR, BoolLiteral r) => new BoolLiteral(false, bexp.Info), + // (IntegerLiteral l, Operator.Plus, IntegerLiteral r) => new IntegerLiteral(l.Suffix, l.Value + r.Value, bexp.Info), + // (IntegerLiteral l, Operator.Plus, FloatLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), + // (FloatLiteral l, Operator.Plus, IntegerLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), + // (FloatLiteral l, Operator.Plus, FloatLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), + // _ => bexp + // }; + // return true; + // } + // else if(expression is Identifier identifier) + // { + // if(TryFind(identifier, SymbolKind.Constant, out var symbol)) + // { + // if(symbol.DefaultValue is null) + // throw new NotImplementedException(); + // result = null!; + // return true; + // } + // } + // else + // { + // result = expression; + // return false; + // } + // result = null!; + // return false; + // } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs new file mode 100644 index 0000000000..c3fec86f53 --- /dev/null +++ b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Parsing.Analysis; + + +public record struct SemanticErrors(TextLocation Location, string Message); + +// TODO : make sure that symbol checking is separated based on symbol kind +public partial class SymbolTable : ISymbolProvider +{ + public Dictionary DeclaredTypes { get; } = []; + public SymbolFrame CurrentTable => Symbols[^1]; + public SymbolFrame RootSymbols => Symbols[0]; + public List Symbols { get; } = [new()]; + + public List Errors { get; } = []; + + + public void Push() => Symbols.Add(new()); + public SymbolFrame Pop() + { + var scope = Symbols[^1]; + Symbols.Remove(scope); + return scope; + } + + public void Import(ISymbolProvider symbols) + { + foreach (var (name, type) in symbols.DeclaredTypes) + DeclaredTypes.TryAdd(name, type); + foreach (var (name, symbol) in symbols.RootSymbols) + RootSymbols.Add(name, symbol); + } + + public bool TryFind(string name, SymbolKind kind, out Symbol symbol) + { + for(int i = 0; i < Symbols.Count; i--) + if(Symbols[i].TryGetValue(name, kind, out symbol)) + return true; + symbol = default; + return false; + } + + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs b/src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs new file mode 100644 index 0000000000..5ad022d50d --- /dev/null +++ b/src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs @@ -0,0 +1,16 @@ +using System.Text.RegularExpressions; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Core.Analysis; + +public static partial class TypeNameExtensions +{ + public static SymbolType ToSymbol(this TypeName typeName) + { + if(!typeName.IsArray && typeName.Generics.Count == 0 && SymbolType.TryGetNumeric(typeName.Name, out var result)) + return result!; + else return new Undefined(typeName); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders.Parsing/Grammar.cs index eadcf2f303..27d9d878a8 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders.Parsing/Grammar.cs @@ -14,8 +14,8 @@ public static ParseResult Match(string code, TParser? parser = var result = new ParseResult(); if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; - if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + if(!Tokens.EOF(ref scanner)) + result.Errors.Add(new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); return result; } @@ -30,8 +30,8 @@ public static ParseResult Match(TScannable code, TP var result = new ParseResult(); if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; - if(!Terminals.EOF(ref scanner)) - result.Errors.Add(new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + if(!Tokens.EOF(ref scanner)) + result.Errors.Add(new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); return result; } diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs index 66085346af..29b917c803 100644 --- a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs +++ b/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs @@ -10,15 +10,15 @@ public readonly SDSLPreProcessor Apply(SDSLPreProcessor sdslpp) var last = sdslpp.CodeFrames[^1]; var scanner = new Scanner(last.Code.Memory); var started = false; - while(!CommonParsers.Until(ref scanner, ["//", "/*"])) + while(!Parsers.Until(ref scanner, ["//", "/*"])) { if(!started) started = true; frame.Add(last, ..scanner.Position); - if (Terminals.Literal("//", ref scanner)) - CommonParsers.Until(ref scanner, '\n', advance: true); - else if (Terminals.Literal("/*", ref scanner)) - CommonParsers.Until(ref scanner, "*/", advance: true); + if (Tokens.Literal("//", ref scanner)) + Parsers.Until(ref scanner, '\n', advance: true); + else if (Tokens.Literal("/*", ref scanner)) + Parsers.Until(ref scanner, "*/", advance: true); } if (!started) frame.Add(last, ..); diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs b/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs index ef7ddcf432..14d42c72ed 100644 --- a/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs +++ b/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs @@ -33,26 +33,26 @@ internal void Process() var lastPos = 0; while (!scanner.IsEof) { - CommonParsers.Until(ref scanner, ["//", "/*", "\""]); + Parsers.Until(ref scanner, ["//", "/*", "\""]); if (!started) started = true; Add(lastPos..scanner.Position); lastPos = scanner.Position; - if (Terminals.Literal("//", ref scanner)) + if (Tokens.Literal("//", ref scanner)) { - CommonParsers.Until(ref scanner, '\n', advance: true); + Parsers.Until(ref scanner, '\n', advance: true); lastPos = scanner.Position; Add([' ']); } - else if (Terminals.Literal("/*", ref scanner)) + else if (Tokens.Literal("/*", ref scanner)) { - CommonParsers.Until(ref scanner, "*/", advance: true); + Parsers.Until(ref scanner, "*/", advance: true); lastPos = scanner.Position; Add([' ']); } - else if (Terminals.Literal("\"", ref scanner)) + else if (Tokens.Literal("\"", ref scanner)) { - CommonParsers.Until(ref scanner, "\"", advance: true); + Parsers.Until(ref scanner, "\"", advance: true); Add(lastPos..scanner.Position); lastPos = scanner.Position; } diff --git a/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs b/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs index 240ab28b11..9dbc17e0b5 100644 --- a/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs +++ b/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs @@ -4,10 +4,13 @@ namespace Stride.Shaders.Parsing; public static class MonoGamePreProcessor -{ public static string Run(string filepath, ReadOnlySpan<(string Name, string Definition)> defines) +{ + public static string OpenAndRun(string filepath, params ReadOnlySpan<(string Name, string Definition)> defines) + { + return Run(File.ReadAllText(filepath), Path.GetFileName(filepath), defines); + } + public static string Run(string content, string filename, params ReadOnlySpan<(string Name, string Definition)> defines) { - var file = File.ReadAllText(filepath); - var filename = Path.GetFileName(filepath); var cpp = new Preprocessor(); cpp.addFeature(Feature.DIGRAPHS); cpp.addWarning(Warning.IMPORT); @@ -15,7 +18,7 @@ public static class MonoGamePreProcessor // cpp.addFeature(Feature.LINEMARKERS); // Pass defines - if (defines != null) + if (!defines.IsEmpty) { foreach (var (Name, Definition) in defines) { @@ -25,7 +28,7 @@ public static class MonoGamePreProcessor } } } - var inputSource = new StringLexerSource(file, true, filename); + var inputSource = new StringLexerSource(content, true, filename); cpp.addInput(inputSource); diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs index e0244ed38c..c5681b3cee 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs @@ -1,5 +1,6 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX.Parsers; @@ -10,40 +11,40 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - var isPartial = Terminals.Literal("partial", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + var isPartial = Tokens.Literal("partial", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _); if(!isPartial) scanner.Position = position; - if (Terminals.Literal("effect", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("effect", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { - if (LiteralsParser.TypeName(ref scanner, result, out var effectName) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (LiteralsParser.TypeName(ref scanner, result, out var effectName) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - parsed = new(effectName, isPartial, new()); - if (Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + parsed = new((TypeName)effectName, isPartial, new()); + if (Tokens.Char('{', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { while( !scanner.IsEof - && !Terminals.Char('}', ref scanner) + && !Tokens.Char('}', ref scanner) ) { - if (EffectStatementParsers.Statement(ref scanner, result, out var s) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (EffectStatementParsers.Statement(ref scanner, result, out var s) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { parsed.Members.Add(s); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0009, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); } if(scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0011, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - else if(Terminals.Char('}', ref scanner, advance: true)) + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0011, scanner[scanner.Position], scanner.Memory)); + else if(Tokens.Char('}', ref scanner, advance: true)) { - parsed.Info = scanner.GetLocation(position..scanner.Position); - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner[position..scanner.Position]; + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); return true; } } } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Effect(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs index 5d72b2ffa8..6e88cc1781 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -12,19 +12,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (If(ref scanner, result, out var ifstatement, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - parsed = new(ifstatement, scanner.GetLocation(..)); - while(ElseIf(ref scanner, result, out var elseif, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) + parsed = new(ifstatement, scanner[..]); + while(ElseIf(ref scanner, result, out var elseif, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; - parsed.Info = scanner.GetLocation(position..scanner.Position); + parsed.Info = scanner[position..scanner.Position]; return true; } - else if(Terminals.Literal("else ", ref scanner)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else if(Tokens.Literal("else ", ref scanner)) + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner[scanner.Position], scanner.Memory)); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Control(ref TScanner scanner, ParseResult result, out EffectControl parsed, ParseError? orError = null) @@ -51,24 +51,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("if", ref scanner, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Literal("if", ref scanner, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(condition, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -79,27 +79,27 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("else", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) - && Terminals.Literal("if", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Literal("else", ref scanner, advance: true) + && SDSL.Parsers.Spaces1(ref scanner, result, out _) + && Tokens.Literal("if", ref scanner, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('(', ref scanner, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(condition, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -110,15 +110,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("else", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + Tokens.Literal("else", ref scanner, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)) ) { - parsed = new(statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(statement, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs index 5a9cce566b..a56bd1f098 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDFX.Parsers; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX; @@ -17,7 +18,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = fe; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool ForEach(ref TScanner scanner, ParseResult result, out EffectForEach parsed, ParseError? orError = null) @@ -34,40 +35,40 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("foreach", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Literal("foreach", ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('(', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces1(ref scanner, result, out _) + LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && SDSL.Parsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) + && SDSL.Parsers.Spaces1(ref scanner, result, out _) ) { - if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("in", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new((TypeName)typeName, identifier, collection, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs index 051706b206..e089dbd213 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -15,7 +15,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = block; return true; } - else if (UsingParams(ref scanner, result, out var p1) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (UsingParams(ref scanner, result, out var p1) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = p1; return true; @@ -25,27 +25,27 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p2; return true; } - else if (MixinComposeAdd(ref scanner, result, out var mca) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinComposeAdd(ref scanner, result, out var mca) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = mca; return true; } - else if (MixinChild(ref scanner, result, out var mc) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinChild(ref scanner, result, out var mc) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = mc; return true; } - else if (MixinClone(ref scanner, result, out var mcl) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinClone(ref scanner, result, out var mcl) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = mcl; return true; } - else if (MixinConst(ref scanner, result, out var mconst) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinConst(ref scanner, result, out var mconst) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = mconst; return true; } - else if (MixinUse(ref scanner, result, out var p3) && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (MixinUse(ref scanner, result, out var p3) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = p3; return true; @@ -67,18 +67,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (StatementParsers.Expression(ref scanner, result, out var exp)) { - parsed = new EffectExpressionStatement(exp, scanner.GetLocation(position..scanner.Position)); + parsed = new EffectExpressionStatement(exp, scanner[position..scanner.Position]); return true; } else if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Literal("discard"), withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new EffectDiscardStatement(scanner.GetLocation(position..scanner.Position)); + parsed = new EffectDiscardStatement(scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Statement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -95,29 +95,29 @@ public static bool MixinChild(ref TScanner scanner, ParseResult result { var position = scanner.Position; if ( - CommonParsers.SequenceOf(ref scanner, ["mixin", "child"], advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "child"], advance: true) + && SDSL.Parsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) ) { - parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new(mixin, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool MixinClone(ref TScanner scanner, ParseResult result, out MixinClone parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - CommonParsers.SequenceOf(ref scanner, ["mixin", "clone"], advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "clone"], advance: true) + && SDSL.Parsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) ) { - parsed = new(mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new(mixin, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool MixinConst(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinConstParser().Match(ref scanner, result, out parsed, orError); @@ -128,34 +128,34 @@ public static bool EffectBlock(ref TScanner scanner, ParseResult resul { var position = scanner.Position; - if (Terminals.Char('{', ref scanner, advance: true)) + if (Tokens.Char('{', ref scanner, advance: true)) { List statements = []; - while (CommonParsers.FollowedByDel(ref scanner, result, Statement, out EffectStatement statement, withSpaces: true, advance: true)) + while (SDSL.Parsers.FollowedByDel(ref scanner, result, Statement, out EffectStatement statement, withSpaces: true, advance: true)) { statements.Add(statement); } - if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new EffectBlock(scanner.GetLocation(position..scanner.Position)) { Statements = statements }; + if (!SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + parsed = new EffectBlock(scanner[position..scanner.Position]) { Statements = statements }; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); } public static bool ShaderSourceDeclaration(ref TScanner scanner, ParseResult result, out ShaderSourceDeclaration parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - Terminals.AnyOf(["ShaderSourceCollection ", "ShaderSource ", "var "], ref scanner, out _) - && CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var arraySize, out var value) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Tokens.AnyOf(["ShaderSourceCollection ", "ShaderSource ", "var "], ref scanner, out _) + && SDSL.Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var arraySize, out var value) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { typename.ArraySize = arraySize; - parsed = new(name, scanner.GetLocation(position..scanner.Position), value); + parsed = new(name, scanner[position..scanner.Position], value); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); } } @@ -166,16 +166,16 @@ public record struct UsingParamsParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (CommonParsers.SequenceOf(ref scanner, ["using", "params"], advance: true)) + if (SDSL.Parsers.SequenceOf(ref scanner, ["using", "params"], advance: true)) { if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new(identifier, scanner[position..scanner.Position]); return true; } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -185,21 +185,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - CommonParsers.SequenceOf(ref scanner, ["mixin", "macro"], advance: true) - || CommonParsers.SequenceOf(ref scanner, ["mixin", "const"], advance: true) + SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "macro"], advance: true) + || SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "const"], advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _); + SDSL.Parsers.Spaces0(ref scanner, result, out _); var tmp = scanner.Position; - CommonParsers.Until(ref scanner, ';'); - if (Terminals.Char(';', ref scanner)) + SDSL.Parsers.Until(ref scanner, ';'); + if (Tokens.Char(';', ref scanner)) { - parsed = new(scanner.Memory[tmp..scanner.Position].ToString().Trim(), scanner.GetLocation(position..scanner.Position)); + parsed = new(scanner.Memory[tmp..scanner.Position].ToString().Trim(), scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -209,35 +209,35 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) + SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.AnyOf(["=", "+="], ref scanner, out var op, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && Tokens.AnyOf(["=", "+="], ref scanner, out var op, advance: true) ) { if( - CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) && ComposeValue(ref scanner, result, out var composeValue) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue, scanner.GetLocation(position..scanner.Position)); + parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue, scanner[position..scanner.Position]); return true; } else if( - CommonParsers.Spaces0(ref scanner, result, out _) + SDSL.Parsers.Spaces0(ref scanner, result, out _) && ComposeValue(ref scanner, result, out var composeValue2) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue2, scanner.GetLocation(position..scanner.Position)); + parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue2, scanner[position..scanner.Position]); return true; } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool ComposeValue(ref TScanner scanner, ParseResult result, out ComposeValue value, in ParseError? orError = null) where TScanner : struct, IScanner @@ -246,35 +246,35 @@ public static bool ComposeValue(ref TScanner scanner, ParseResult resu if( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) && ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) - || CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) + || SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) ) ) { - value = new ComposeMixinValue(mixin, scanner.GetLocation(position..scanner.Position)); + value = new ComposeMixinValue(mixin, scanner[position..scanner.Position]); return true; } else { scanner.Position = position; - if(Terminals.IdentifierFirstChar(ref scanner, advance: true)) + if(Tokens.IdentifierFirstChar(ref scanner, advance: true)) { while( - Terminals.LetterOrDigit(ref scanner, advance: true) - || Terminals.Char('_', ref scanner, advance: true) - || Terminals.Char('.', ref scanner, advance: true) + Tokens.LetterOrDigit(ref scanner, advance: true) + || Tokens.Char('_', ref scanner, advance: true) + || Tokens.Char('.', ref scanner, advance: true) ); if( - CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) - || CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) + || SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) ) { - value = new ComposePathValue(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position..scanner.Position)); + value = new ComposePathValue(scanner.Memory[position..scanner.Position].ToString(), scanner[position..scanner.Position]); return true; } } } - return CommonParsers.Exit(ref scanner, result, out value, position); + return SDSL.Parsers.Exit(ref scanner, result, out value, position); } } @@ -284,20 +284,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - CommonParsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) + SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Literal("+=", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Literal("+=", ref scanner, advance: true) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) ) { var start = scanner.Position; - CommonParsers.Until(ref scanner, ';'); - parsed = new MixinComposeAdd(name, new(scanner.Memory[start..scanner.Position].ToString().Trim(), scanner.GetLocation(start..scanner.Position)), scanner.GetLocation(position..scanner.Position)); + SDSL.Parsers.Until(ref scanner, ';'); + parsed = new MixinComposeAdd(name, new(scanner.Memory[start..scanner.Position].ToString().Trim(), scanner[start..scanner.Position]), scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -307,24 +307,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("mixin", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("mixin", ref scanner, advance: true) + && SDSL.Parsers.Spaces1(ref scanner, result, out _) ) { - var betweenParenthesis = CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true); - if (CommonParsers.Repeat(ref scanner, result, ShaderClassParsers.Mixin, out List mixins, 1, withSpaces: true, separator: ",")) + var betweenParenthesis = SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true); + if (SDSL.Parsers.Repeat(ref scanner, result, ShaderClassParsers.Mixin, out List mixins, 1, withSpaces: true, separator: ",")) { - var checkParen = betweenParenthesis == CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true); - var finished = CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true); + var checkParen = betweenParenthesis == SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true); + var finished = SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true); if (finished && checkParen) { - parsed = new(mixins, scanner.GetLocation(position..scanner.Position)); + parsed = new(mixins, scanner[position..scanner.Position]); return finished; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); } - return CommonParsers.Exit(ref scanner, result, out parsed, position); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs index 0d380f0498..0c03d26a5c 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs @@ -9,33 +9,33 @@ public record struct ParamsParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("params", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("params", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { if (LiteralsParser.TypeName(ref scanner, result, out var paramsName)) { parsed = new(paramsName, new()); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('{', ref scanner, advance: true)) + SDSL.Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char('{', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + SDSL.Parsers.Spaces0(ref scanner, result, out _); while (!scanner.IsEof) { if (Parameter(ref scanner, result, out var p)) parsed.Parameters.Add(p); - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + else if (SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); - parsed.Info = scanner.GetLocation(position..scanner.Position); + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner[position..scanner.Position]; return true; } else - CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0012, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0012, scanner[scanner.Position], scanner.Memory)); + SDSL.Parsers.Spaces0(ref scanner, result, out _); } } } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Params(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParamsParsers().Match(ref scanner, result, out parsed, orError); @@ -49,30 +49,30 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - if (LiteralsParser.TypeName(ref scanner, result, out var typename) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (LiteralsParser.TypeName(ref scanner, result, out var typename) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true)) + if (SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression) && CommonParsers.Spaces0(ref scanner, result, out _)) + SDSL.Parsers.Spaces0(ref scanner, result, out _); + if (ExpressionParser.Expression(ref scanner, result, out var expression) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), expression); + if (!Tokens.Char(';', ref scanner, advance: true)) + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0013, scanner[scanner.Position], scanner.Memory)); + parsed = new(typename, identifier, scanner[position..scanner.Position], expression); return true; } } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new(typename, identifier, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0014, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0014, scanner[scanner.Position], scanner.Memory)); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs b/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs index cd0befd088..2cd8dee1c2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs @@ -40,6 +40,7 @@ public static AssignOperator ToAssignOperator(this string s) { return s switch { + "=" => AssignOperator.Simple, "+=" => AssignOperator.Plus, "-=" => AssignOperator.Minus, "*=" => AssignOperator.Mul, @@ -57,6 +58,7 @@ public static string ToAssignSymbol(this AssignOperator s) { return s switch { + AssignOperator.Simple => "=", AssignOperator.Plus => "+=", AssignOperator.Minus => "-=", AssignOperator.Mul => "*=", diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs index f741c0d4b9..c4b2c785aa 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs @@ -1,3 +1,6 @@ +using System.Text; +using Stride.Shaders.Parsing.Analysis; + namespace Stride.Shaders.Parsing.SDSL.AST; @@ -39,40 +42,57 @@ public class CastExpression(string typeName, Operator op, Expression expression, public string TypeName { get; set; } = typeName; } -public class PostfixExpression(Expression expression, Operator op, TextLocation info) : UnaryExpression(expression, op, info) +public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { + public Operator Operator { get; set; } = op; public override string ToString() { - return $"{Expression}{Operator.ToSymbol()}"; + return $"{Operator.ToSymbol()}"; } } -public class AccessorExpression(Expression expression, Expression accessed, TextLocation info) : PostfixExpression(expression, Operator.Accessor, info) +public class AccessorChainExpression(Expression source, TextLocation info) : Expression(info) { - public Expression Accessed { get; set; } = accessed; - - public override string ToString() - { - return $"{Expression}.{Accessed}"; - } -} + public Expression Source { get; set; } = source; + public List Accessors { get; set; } = []; -public class IndexerExpression(Expression expression, Expression index, TextLocation info) : PostfixExpression(expression, Operator.Indexer, info) -{ - public Expression Index { get; set; } = index; public override string ToString() { - return $"{Expression}[{Index}]"; + var builder = new StringBuilder().Append(Source); + foreach(var a in Accessors) + if(a is NumberLiteral) + builder.Append('[').Append(a).Append(']'); + else if(a is PostfixIncrement) + builder.Append(a); + else + builder.Append('.').Append(a); + return builder.ToString(); } } - public class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) { public Operator Op { get; set; } = op; public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; + public override void ProcessSymbol(SymbolTable table) + { + Left.ProcessSymbol(table); + Right.ProcessSymbol(table); + if ( + OperatorTable.BinaryOperationResultingType( + Left.Type ?? throw new NotImplementedException("Missing type"), + Right.Type ?? throw new NotImplementedException("Missing type"), + Op, + out var t + ) + ) + Type = t; + else + table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); + } + public override string ToString() { return $"( {Left} {Op.ToSymbol()} {Right} )"; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs index 8c579f583b..3d585f02e4 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs @@ -1,5 +1,8 @@ -using System.Drawing; using System.Numerics; +using System.Text; +using Stride.Shaders.Core; +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -9,7 +12,6 @@ public abstract class Literal(TextLocation info) : Expression(info); public abstract class ValueLiteral(TextLocation info) : Literal(info); public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); - public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; @@ -35,6 +37,7 @@ public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info public override double DoubleValue => Convert.ToDouble(Value); public override long LongValue => Convert.ToInt64(Value); public override int IntValue => Convert.ToInt32(Value); + public override string ToString() { return $"{Value}{Suffix}"; @@ -42,21 +45,55 @@ public override string ToString() } -public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info); +public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) +{ + public override void ProcessSymbol(SymbolTable table) + { + Type = Suffix switch + { + { Signed: true, Size: 8 } => Scalar.From("sbyte"), + { Signed: true, Size: 16 } => Scalar.From("short"), + { Signed: true, Size: 32 } => Scalar.From("int"), + { Signed: true, Size: 64 } => Scalar.From("long"), + { Signed: false, Size: 8 } => Scalar.From("byte"), + { Signed: false, Size: 16 } => Scalar.From("ushort"), + { Signed: false, Size: 32 } => Scalar.From("uint"), + { Signed: false, Size: 64 } => Scalar.From("ulong"), + _ => throw new NotImplementedException("Unsupported integer suffix") + }; + } +} public class UnsignedIntegerLiteral(Suffix suffix, ulong value, TextLocation info) : NumberLiteral(suffix, value, info); public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) { public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); + + public override void ProcessSymbol(SymbolTable table) + { + Type = Suffix.Size switch + { + 16 => Scalar.From("half"), + 32 => Scalar.From("float"), + 64 => Scalar.From("double"), + _ => throw new NotImplementedException("Unsupported float") + }; + } } -public sealed class HexLiteral(ulong value, TextLocation info) : UnsignedIntegerLiteral(new(32, false, false), value, info); +public sealed class HexLiteral(ulong value, TextLocation info) : UnsignedIntegerLiteral(new(32, false, false), value, info) +{ + public override void ProcessSymbol(SymbolTable table) + => Type = Scalar.From("long"); +} public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; + public override void ProcessSymbol(SymbolTable table) + => Type = Scalar.From("bool"); } public class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral(info) @@ -64,9 +101,25 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral( public TypeName TypeName { get; set; } = typeName; public List Values { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + Type = TypeName.ToSymbol(); + var tmp = (Core.Vector)Type; + foreach(var v in Values) + { + v.ProcessSymbol(table); + if( + v.Type is Scalar st && tmp.BaseType != st + || (v.Type is Core.Vector vt && vt.BaseType != tmp.BaseType) + || (v.Type is Core.Vector vt2 && vt2.Size > tmp.Size) + ) + table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); + } + } + public override string ToString() { - return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + return $"{TypeName}({string.Join(", ", Values.Select(x => x.ToString()))})"; } } @@ -93,19 +146,66 @@ public override string ToString() } - - - public class Identifier(string name, TextLocation info) : Literal(info) { public string Name { get; set; } = name; public static implicit operator string(Identifier identifier) => identifier.Name; + public override void ProcessSymbol(SymbolTable table) + { + for (int i = table.Symbols.Count - 1; i >= 0; i -= 1) + { + if (table.Symbols[i].TryGetValue(Name, SymbolKind.Variable, out var symbol)) + { + if (symbol.Type is not Undefined and not null) + Type = symbol.Type; + else + Type = symbol.Type ?? new Undefined(Name); + return; + } + } + throw new NotImplementedException($"Cannot find symbol {Name}."); + } + public override string ToString() { return $"{Name}"; } + + public bool IsSwizzle() + { + if(Name.Length > 4) + return false; + + bool colorMode = false; + bool vectorMode = false; + + Span colorFields = ['r', 'g', 'b', 'a']; + Span vectorFields = ['x', 'y', 'z', 'w']; + + if(colorFields.Contains(Name[0])) + colorMode = true; + else if(vectorFields.Contains(Name[0])) + vectorMode = true; + + if(!colorMode && !vectorMode) + return false; + var fields = colorMode ? colorFields : vectorFields; + foreach(var c in Name) + if(!fields.Contains(c)) + return false; + return true; + } + + public bool IsMatrixField() + { + return + Name.Length == 3 + && Name[0] == '_' + && char.IsDigit(Name[1]) && Name[1] - '0' > 0 && Name[1] - '0' < 5 + && char.IsDigit(Name[2]) && Name[2] - '0' > 0 && Name[2] - '0' < 5; + } } public class TypeName(string name, TextLocation info, bool isArray) : Literal(info) @@ -117,7 +217,21 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public override string ToString() { - return $"{Name}"; + var builder = new StringBuilder(); + builder.Append(Name); + if(Generics.Count > 0) + { + builder.Append('<'); + foreach(var g in Generics) + builder.Append(g.ToString()).Append(", "); + builder.Append('>'); + } + if(ArraySize != null) + foreach(var s in ArraySize) + builder.Append('[').Append(s.ToString()).Append(']'); + + return builder.ToString(); + } public static implicit operator string(TypeName tn) => tn.Name; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs index 886599e407..24fb684123 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs @@ -1,3 +1,7 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; + namespace Stride.Shaders.Parsing.SDSL.AST; @@ -11,6 +15,35 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public List Mixins { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + foreach (var member in Elements) + { + if(member is ShaderMethod func) + { + func.Type = func.ReturnTypeName.ToSymbol(); + table.RootSymbols.Add(new(func.Name, SymbolKind.Method), new(new(func.Name, SymbolKind.Method), func.Type)); + table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); + } + else if(member is ShaderMember svar) + { + svar.Type = svar.TypeName.ToSymbol(); + table.RootSymbols.Add( + new( + svar.Name, + svar.TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable + ), + new(new(svar.Name, SymbolKind.Variable), svar.TypeName.ToSymbol()) + ); + table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + } + } + foreach (var member in Elements) + if(member is not MethodOrMember) + member.ProcessSymbol(table); + } + + public override string ToString() { return diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c79c9a4d0a..b4df7b1862 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -1,3 +1,7 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; + namespace Stride.Shaders.Parsing.SDSL.AST; @@ -49,9 +53,21 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, Identifier name, Expression? initialValue, bool isArray, TextLocation location, bool isStaged = false, StreamKind streamKind = StreamKind.None, Identifier? semantic = null, List? arraySizes = null, InterpolationModifier interpolation = InterpolationModifier.None, StorageClass storageClass = StorageClass.None, TypeModifier typeModifier = TypeModifier.None) : MethodOrMember(location, isStaged) +public sealed class ShaderMember(TypeName type, + Identifier name, + Expression? initialValue, + bool isArray, + TextLocation location, + bool isStaged = false, + StreamKind streamKind = StreamKind.None, + Identifier? semantic = null, + List? arraySizes = null, + InterpolationModifier interpolation = InterpolationModifier.None, + StorageClass storageClass = StorageClass.None, + TypeModifier typeModifier = TypeModifier.None + ) : MethodOrMember(location, isStaged) { - public TypeName Type { get; set; } = type; + public TypeName TypeName { get; set; } = type; public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; public StreamKind StreamKind { get; set; } = streamKind; @@ -64,13 +80,17 @@ public sealed class ShaderMember(TypeName type, Identifier name, Expression? ini public override string ToString() { - return $"[{string.Join(" ", Attributes.Select(x => x.ToString()))}]\n{Type} {Name}"; + if(Attributes != null) + return $"[{string.Join(" ", Attributes.Select(x => x.ToString()))}]\n{TypeName} {Name}"; + else + return $"{TypeName} {Name}"; } } public class MethodParameter(TypeName type, Identifier name, TextLocation info, string? storage = null, Expression? arraySize = null, Identifier? semantic = null) : Node(info) { - public TypeName Type { get; set; } = type; + public TypeName TypeName { get; set; } = type; + public SymbolType? Type { get; set; } public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; public Expression? ArraySize { get; set; } = arraySize; @@ -82,10 +102,23 @@ public override string ToString() } } -public class ShaderMethod(TypeName returnType, Identifier name, TextLocation info, Identifier? visibility = null, Identifier? storage = null, bool isStaged = false, bool isAbstract = false, bool isVirtual = false, bool isStatic = false, bool isOverride = false, bool isClone = false) : MethodOrMember(info, isStaged) +public class ShaderMethod( + TypeName returnType, + Identifier name, + TextLocation info, + Identifier? visibility = null, + Identifier? storage = null, + bool isStaged = false, + bool isAbstract = false, + bool isVirtual = false, + bool isStatic = false, + bool isOverride = false, + bool isClone = false + ) : MethodOrMember(info, isStaged) { - public TypeName ReturnType { get; set; } = returnType; + public SymbolType? ReturnType { get; set; } + public TypeName ReturnTypeName { get; set; } = returnType; public Identifier Name { get; set; } = name; public Identifier? Visibility { get; set; } = visibility; public Identifier? Storage { get; set; } = storage; @@ -97,9 +130,27 @@ public class ShaderMethod(TypeName returnType, Identifier name, TextLocation inf public List Parameters { get; set; } = []; public BlockStatement? Body { get; set; } + + public override void ProcessSymbol(SymbolTable table) + { + foreach (var arg in Parameters) + { + var argSym = arg.TypeName.ToSymbol(); + table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + arg.Type = argSym; + } + if (Body is not null) + { + table.Push(); + foreach (var s in Body.Statements) + s.ProcessSymbol(table); + table.Pop(); + } + } + public override string ToString() { - return $"{ReturnType} {Name}()\n{Body}\n"; + return $"{ReturnTypeName} {Name}()\n{Body}\n"; } } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs index b4987b3bcf..91dee86104 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs @@ -1,7 +1,14 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; + namespace Stride.Shaders.Parsing.SDSL.AST; -public abstract class ShaderElement(TextLocation info) : Node(info); +public abstract class ShaderElement(TextLocation info) : Node(info) +{ + public SymbolType? Type { get; set; } +} public enum StorageClass @@ -94,42 +101,67 @@ public static TypeModifier ToTypeModifier(this string str) public class ShaderVariable(TypeName type, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) { - public TypeName Type { get; set; } = type; + public TypeName TypeName { get; set; } = type; public Identifier Name { get; set; } = name; public Expression? Value { get; set; } = value; public StorageClass StorageClass { get; set; } = StorageClass.None; public TypeModifier TypeModifier { get; set; } = TypeModifier.None; public override string ToString() { - return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " :"")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " :"")}{Type} {Name} = {Value}"; + return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " :"")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " :"")}{TypeName} {Name} = {Value}"; } } public class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; - public TypeName Type { get; set; } = type; + public TypeName TypeName { get; set; } = type; public override string ToString() { - return $"typedef {Type} {Name}"; + return $"typedef {TypeName} {Name}"; } } public abstract class ShaderBuffer(List name, TextLocation info) : ShaderElement(info) { public List Name { get; set; } = name; + public List Members { get; set; } = []; + + public override void ProcessSymbol(SymbolTable table) + { + var sym = new Symbol(new(Name.ToString() ?? "", SymbolKind.CBuffer), new BufferSymbol(Name.ToString() ?? "", [])); + + table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); + var kind = this switch + { + CBuffer => SymbolKind.CBuffer, + TBuffer => SymbolKind.TBuffer, + RGroup => SymbolKind.RGroup, + _ => throw new NotSupportedException() + }; + table.RootSymbols.Add(new(Name.ToString() ?? "", kind), sym); + foreach (var cbmem in Members) + { + var msym = cbmem.TypeName.ToSymbol(); + table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); + cbmem.Type = msym; + } + } } public class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) { public TypeName TypeName { get; set; } = typename; + public SymbolType? Type { get; set; } public Identifier Name { get; set; } = identifier; public List Attributes { get; set; } = []; public override string ToString() { - return $"{TypeName} {Name}"; + if(Type is not null) + return $"{Type} {Name}"; + else return $"{TypeName} {Name}"; } } @@ -138,6 +170,19 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public Identifier TypeName { get; set; } = typename; public List Members { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new Struct(TypeName.ToString() ?? "", [])); + table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); + table.RootSymbols.Add(new(TypeName.ToString() ?? "", SymbolKind.Struct), sym); + foreach (var smem in Members) + { + var msym = smem.TypeName.ToSymbol(); + table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); + smem.Type = msym; + } + } + public override string ToString() { return $"struct {TypeName} ({string.Join(", ", Members)})"; @@ -145,15 +190,6 @@ public override string ToString() } -public sealed class CBuffer(List name, TextLocation info) : ShaderBuffer(name, info) -{ - public List Members { get; set; } = []; -} -public sealed class RGroup(List name, TextLocation info) : ShaderBuffer(name, info) -{ - public List Members { get; set; } = []; -} -public sealed class TBuffer(List name, TextLocation info) : ShaderBuffer(name, info) -{ - public List Members { get; set; } = []; -} +public sealed class CBuffer(List name, TextLocation info) : ShaderBuffer(name, info); +public sealed class RGroup(List name, TextLocation info) : ShaderBuffer(name, info); +public sealed class TBuffer(List name, TextLocation info) : ShaderBuffer(name, info); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs index eafe78348b..e4251c0346 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs @@ -8,13 +8,4 @@ public abstract class ShaderGenericsValue(TextLocation info) : Node(info); public class ValueTypeGenerics(ValueLiteral value,TextLocation info) : ShaderGenericsValue(info) { public ValueLiteral Value { get; set; } = value; -} - -public class IdentifierGenerics(Identifier identifier, TextLocation info) : ShaderGenericsValue(info) -{ - public Identifier Identifier { get; set; } = identifier; -} -public class AccessorExpressionGenerics(AccessorExpression accessor, TextLocation info) : ShaderGenericsValue(info) -{ - public AccessorExpression Accessor { get; set; } = accessor.Accessed is Identifier ? accessor : throw new ArgumentException($"Value accessed should be a shader class or a variable name"); } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs index 980c17b6ee..ed9ab1c014 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs @@ -1,3 +1,5 @@ +using Stride.Shaders.Parsing.Analysis; + namespace Stride.Shaders.Parsing.SDSL.AST; @@ -11,6 +13,21 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } + public override void ProcessSymbol(SymbolTable table) + { + If.Condition.ProcessSymbol(table); + If.Body.ProcessSymbol(table); + if (ElseIfs.Count > 0) + { + foreach (var ei in ElseIfs) + { + ei.Condition.ProcessSymbol(table); + ei.Body.ProcessSymbol(table); + } + } + Else?.Body.ProcessSymbol(table); + } + public override string ToString() { return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs index e60b9283cb..077456631b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs @@ -1,5 +1,7 @@ -using System.Runtime.CompilerServices; using System.Text; +using Stride.Shaders.Core; +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -7,11 +9,13 @@ public abstract class Statement(TextLocation info) : ValueNode(info); public class EmptyStatement(TextLocation info) : Statement(info) { + public override SymbolType? Type { get => Scalar.From("void"); set { } } public override string ToString() => ";"; } public class ExpressionStatement(Expression expression, TextLocation info) : Statement(info) { + public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; public override string ToString() { @@ -21,6 +25,7 @@ public override string ToString() public class Return(TextLocation info, Expression? expression = null) : Statement(info) { + public override SymbolType? Type { get => Value?.Type ?? Scalar.From("void"); set { } } public Expression? Value { get; set; } = expression; public override string ToString() @@ -48,9 +53,9 @@ public override string ToString() Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" }; } -public class DeclaredVariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +public class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) { - public Expression Variable { get; set; } = variable; + public Identifier Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; public Expression? Value { get; set; } = value; public bool IsConst { get; set; } = isConst; @@ -79,6 +84,30 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + if (TypeName == "var") + { + if (Variables.Count == 1 && Variables[0].Value is not null) + { + Variables[0].Value?.ProcessSymbol(table); + Type = Variables[0].Value!.Type; + } + else + table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); + } + else + { + Type = TypeName.ToSymbol(); + table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); + foreach (var d in Variables) + { + d.Value?.ProcessSymbol(table); + table.CurrentTable.Add(new(d.Variable, SymbolKind.Variable), new(new(d.Variable, SymbolKind.Variable), Type)); + } + } + } + public override string ToString() { return $"{TypeName} {string.Join(", ", Variables.Select(v => v.ToString()))}"; @@ -88,6 +117,63 @@ public override string ToString() public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; + + public override void ProcessSymbol(SymbolTable table) + { + foreach (var variable in Variables) + { + if (variable.Variable is Identifier id) + { + if (table.TryFind(id, SymbolKind.Variable, out var symbol)) + Type = symbol.Type; + else throw new NotImplementedException(); + } + else if (variable.Variable is AccessorChainExpression exp) + { + if (exp.Source is Identifier streams && streams == "streams") + { + if (exp.Accessors[0] is not Identifier) + throw new NotImplementedException(); + else + { + // Check type of first symbol + exp.Accessors[0].ProcessSymbol(table); + exp.Type = exp.Accessors[0].Type; + // If has more, dive into the type definition + // First case none + if (exp.Accessors.Count > 1) + { + foreach (var accessor in exp.Accessors[1..]) + { + if (exp.Type is not null && exp.Type.TryAccess(accessor, out var type)) + { + exp.Type = type; + accessor.Type = type; + } + else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {exp.Type}"); + } + } + + } + } + else + { + exp.Source.ProcessSymbol(table); + foreach (var accessor in exp.Accessors) + { + if (exp.Type is not null && exp.Type.TryAccess(accessor, out var type)) + { + exp.Type = type; + accessor.Type = type; + } + else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {exp.Type}"); + } + } + } + else throw new NotImplementedException(); + variable.Value?.ProcessSymbol(table); + } + } public override string ToString() { return string.Join(", ", Variables.Select(x => x.ToString())) + ";"; @@ -100,6 +186,12 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + foreach (var s in Statements) + s.ProcessSymbol(table); + } + public override string ToString() { var builder = new StringBuilder().Append("Block : \n"); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs b/src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs new file mode 100644 index 0000000000..bc457919ed --- /dev/null +++ b/src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs @@ -0,0 +1,61 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Parsing.SDSL.AST; + +public static class SymbolTypeProcessExtension +{ + public static bool TryAccess(this SymbolType symbol, Expression expression, out SymbolType? type) + { + type = null; + if( + symbol is Scalar or Vector + && expression is Identifier swizzle + && swizzle.IsSwizzle() + ) + { + if(symbol.TrySwizzle(swizzle, out type)) + { + swizzle.Type = type; + return true; + } + else throw new NotImplementedException(); + } + else if(symbol is Matrix matrix && expression is Identifier matrixField && matrixField.IsMatrixField()) + { + type = matrix.BaseType; + matrixField.Type = type; + return true; + } + else if(symbol is Struct s && expression is Identifier field) + { + if(s.Fields.TryGetValue(field, out var ft)) + { + type = ft; + field.Type = ft; + } + else throw new NotImplementedException($"field {field} not found in type {s}"); + } + return false; + } + public static bool TrySwizzle(this SymbolType symbol, string swizzle, out SymbolType? type) + { + type = null; + if(symbol is Scalar s) + { + foreach(var c in swizzle) + if(c != 'r' || c != 'x') + return false; + type = new Vector(s, swizzle.Length); + return true; + } + else if(symbol is Vector v) + { + if(swizzle.Length == 1) + type = v.BaseType; + else + type = new Vector(v.BaseType, swizzle.Length); + return true; + } + else return false; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs deleted file mode 100644 index ac366aab63..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/GlobalSymbolTypes.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Stride.Shaders.Parsing.SDSL.Analysis; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL; - - -public static class GlobalShaderTypes -{ - static Dictionary mixins = []; - - - public static void Register(MixinSymbol symbol) - { - mixins.Add(symbol.Name, symbol); - } - - public static bool TryRegister(MixinSymbol symbol) - { - return mixins.TryAdd(symbol.Name, symbol); - } - - public static MixinSymbol Get(string name) - { - return mixins[name]; - } - - public static bool TryGet(string name, out MixinSymbol? symbol) - { - return mixins.TryGetValue(name, out symbol); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs deleted file mode 100644 index da627aae81..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/Symbol.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL.Analysis; - - - - -public enum SymbolKind -{ - Constant, - ConstantGeneric, - Composition, - Method, - Variable, -} - - -public record struct Symbol(string Name, SymbolType Type, SymbolKind Kind); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs deleted file mode 100644 index 106a08db0d..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTable.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Security.Cryptography; -using System.Text.RegularExpressions; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL.Analysis; - - - -public partial class SymbolTable -{ - public Dictionary DeclaredTypes { get; } = []; - public Stack> Symbols { get; } = []; - - public void Process(ShaderClass sclass, Dictionary? globalSymbols = null) - { - DeclaredTypes.Add(sclass.Name.Name, new MixinSymbol(sclass.Name, [])); - foreach (var e in sclass.Elements) - { - if(e is ShaderMember member) - { - if (!DeclaredTypes.TryGetValue(member.Type.Name, out var mt)) - { - // mt = new SymbolType() - } - } - } - } - - [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))$")] - private static partial Regex ScalarPattern(); - [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))([2-4])$")] - private static partial Regex VectorPattern(); - [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))([2-4])x([2-4])$")] - private static partial Regex MatrixPattern(); - [GeneratedRegex(@"^((s?byte)|(u?(short|int|long))|(half|float|double))[\s\n]*\[[\s\n]*([0-9]+)?[\s\n]*\]$")] - private static partial Regex ArrayPattern(); - public SymbolType ParseType(string typename) - { - if (ScalarPattern().IsMatch(typename)) - return new Scalar(typename); - else if (VectorPattern().IsMatch(typename)) - { - var matches = VectorPattern().Match(typename); - var size = int.Parse(matches.Groups[6].ValueSpan); - var baseType = matches.Groups[1].Value; - return new Vector(new Scalar(baseType), size); - } - else if (MatrixPattern().IsMatch(typename)) - { - var matches = MatrixPattern().Match(typename); - var width = int.Parse(matches.Groups[6].ValueSpan); - var length = int.Parse(matches.Groups[7].ValueSpan); - var baseType = matches.Groups[1].Value; - return new Matrix(new Scalar(baseType), width, length); - } - else if (ArrayPattern().IsMatch(typename)) - { - var matches = ArrayPattern().Match(typename); - return new Array(ParseType(matches.Groups[1].Value), int.Parse(matches.Groups[6].ValueSpan)); - } - else throw new NotImplementedException(); - } - - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs b/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs deleted file mode 100644 index 01a945abcd..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Analysis/SymbolTypes.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Dynamic; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL.Analysis; - - - -public abstract record SymbolType(); - -public sealed record Scalar(string TypeName) : SymbolType(); -public sealed record Vector(Scalar BaseType, int Size) : SymbolType(); -public sealed record Matrix(Scalar BaseType, int Rows, int Columns) : SymbolType(); -public sealed record Array(SymbolType BaseType, int Size) : SymbolType(); -public sealed record Struct(Dictionary Fields) : SymbolType(); -public sealed record Buffer(SymbolType BaseType, int Size) : SymbolType(); - - -public abstract record Texture(SymbolType BaseType) : SymbolType(); -public sealed record Texture1D(SymbolType BaseType, int Size) : SymbolType(); -public sealed record Texture2D(SymbolType BaseType, int Width, int Height) : SymbolType(); -public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : SymbolType(); - - -public sealed record MixinSymbol( - string Name, - List Components -) : SymbolType() -{ - public T Get(string name) - where T : SymbolType - { - foreach (var e in Components) - if (e is T r && e.Name == name) - return r; - throw new ArgumentException($"{name} not found in Mixin {Name}"); - } - public bool TryGet(string name, out T value) - where T : SymbolType - { - foreach (var e in Components) - if (e is T r && e.Name == name) - { - value = r; - return true; - } - value = null!; - return false; - } -} diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs index 61e52d3e04..5f98a096c5 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -6,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; -public static class CommonParsers +public static class Parsers { public static bool Exit(ref TScanner scanner, ParseResult result, out TNode parsed, int beginningPosition, in ParseError? orError = null) where TScanner : struct, IScanner @@ -65,7 +65,7 @@ public static bool SequenceOf(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult r bool matched = false; // legacy while ( - Terminals.AnyOf( + Tokens.AnyOf( [ "stage", "override", @@ -131,7 +131,7 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult bool matched = false; // legacy while ( - Terminals.AnyOf( + Tokens.AnyOf( [ "stage", "stream", @@ -214,7 +214,7 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann if ( LiteralsParser.Identifier(ref scanner, result, out identifier) - && !FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true, advance: true) + && !FollowedBy(ref scanner, Tokens.Char('.'), withSpaces: true, advance: true) ) { var tmp = scanner.Position; @@ -226,7 +226,7 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann tmp = scanner.Position; if ( !( - FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) ) ) @@ -266,7 +266,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann tmp = scanner.Position; if ( !( - FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) ) ) @@ -290,7 +290,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann Spaces0(ref scanner, result, out _); if ( !( - Terminals.Char('=', ref scanner, advance: true) + Tokens.Char('=', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out value) ) @@ -330,7 +330,7 @@ public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, tmp = scanner.Position; if ( !( - FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) + FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) ) ) @@ -354,7 +354,7 @@ public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, Spaces0(ref scanner, result, out _); if ( !( - Terminals.Char('=', ref scanner, advance: true) + Tokens.Char('=', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out value) ) @@ -380,14 +380,14 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result arraySizes = []; while (!scanner.IsEof) { - if (FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true)) + if (FollowedBy(ref scanner, Tokens.Char('['), withSpaces: true, advance: true)) { - if(FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true)) + if(FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true)) break; else if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) { arraySizes.Add(arraySize); - if (!FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true)) + if (!FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true)) return Exit(ref scanner, result, out arraySizes, scanner.Position); } else return Exit(ref scanner, result, out arraySizes, scanner.Position); @@ -412,11 +412,11 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P Spaces0(ref scanner, result, out _); if ( !( - Terminals.Char('[', ref scanner, advance: true) + Tokens.Char('[', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out arraySize) && Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) + && Tokens.Char(']', ref scanner, advance: true) ) ) { @@ -425,7 +425,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P tmp = scanner.Position; if ( !( - Terminals.Char('=', ref scanner, advance: true) + Tokens.Char('=', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out value) ) @@ -442,9 +442,9 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P scanner.Position = position; if ( LiteralsParser.TypeName(ref scanner, result, out typeName) - && FollowedBy(ref scanner, Terminals.Char('['), withSpaces: true, advance: true) + && FollowedBy(ref scanner, Tokens.Char('['), withSpaces: true, advance: true) && ExpressionParser.Expression(ref scanner, result, out arraySize) - && FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) + && FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) && Spaces1(ref scanner, result, out _) && ShaderClassParsers.Mixin(ref scanner, result, out mixin)) { @@ -452,7 +452,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P Spaces0(ref scanner, result, out _); if ( !( - Terminals.Char('=', ref scanner, advance: true) + Tokens.Char('=', ref scanner, advance: true) && Spaces0(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out value) ) @@ -474,7 +474,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P public static bool Optional(ref TScanner scanner, TTerminal terminal, bool advance = false) where TScanner : struct, IScanner - where TTerminal : struct, ITerminal + where TTerminal : struct, IToken { terminal.Match(ref scanner, advance: advance); return true; @@ -490,7 +490,7 @@ public static bool Optional(ref TScanner scanner, IParser(ref TScanner scanner, TTerminal terminal, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner - where TTerminal : struct, ITerminal + where TTerminal : struct, IToken { var position = scanner.Position; if (withSpaces) @@ -512,7 +512,7 @@ public static bool FollowedByAny(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, string literals, out char matched, bool withSpaces = false, bool advance = false) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (withSpaces) + Spaces0(ref scanner, null!, out _); + foreach (var l in literals) + { + if (Tokens.Char(l, ref scanner, advance: advance)) + { + if (!advance) + scanner.Position = position; + matched = l; + return true; + } + } + matched = '0'; + scanner.Position = position; + return false; + } public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { @@ -606,14 +626,14 @@ public static bool FollowedBy(ref TScanner scanner, public static bool Until(ref TScanner scanner, char value, bool advance = false) where TScanner : struct, IScanner { - while (!scanner.IsEof && !Terminals.Char(value, ref scanner, advance)) + while (!scanner.IsEof && !Tokens.Char(value, ref scanner, advance)) scanner.Advance(1); return scanner.IsEof; } public static bool Until(ref TScanner scanner, string value, bool advance = false) where TScanner : struct, IScanner { - while (!scanner.IsEof && !Terminals.Literal(value, ref scanner, advance)) + while (!scanner.IsEof && !Tokens.Literal(value, ref scanner, advance)) scanner.Advance(1); return scanner.IsEof; } @@ -623,7 +643,7 @@ public static bool Until(ref TScanner scanner, ReadOnlySpan va while (!scanner.IsEof) { foreach (var value in values) - if (Terminals.Literal(value, ref scanner, advance)) + if (Tokens.Literal(value, ref scanner, advance)) return scanner.IsEof; scanner.Advance(1); } @@ -631,7 +651,7 @@ public static bool Until(ref TScanner scanner, ReadOnlySpan va } public static bool Until(ref Scanner scanner, bool advance = false) where TScanner : struct, IScanner - where TTerminal : struct, ITerminal + where TTerminal : struct, IToken { var t = new TTerminal(); while (!scanner.IsEof && !t.Match(ref scanner, advance)) @@ -640,8 +660,8 @@ public static bool Until(ref Scanner scanner, bool advance } public static bool Until(ref Scanner scanner, TTerminal1? terminal1 = null, TTerminal2? terminal2 = null, bool advance = false) where TScanner : struct, IScanner - where TTerminal1 : struct, ITerminal - where TTerminal2 : struct, ITerminal + where TTerminal1 : struct, IToken + where TTerminal2 : struct, IToken { var t1 = terminal1 ?? new TTerminal1(); var t2 = terminal2 ?? new TTerminal2(); @@ -651,9 +671,9 @@ public static bool Until(ref Scanner scanner, } public static bool Until(ref Scanner scanner, TTerminal1? terminal1 = null, TTerminal2? terminal2 = null, TTerminal3? terminal3 = null, bool advance = false) where TScanner : struct, IScanner - where TTerminal1 : struct, ITerminal - where TTerminal2 : struct, ITerminal - where TTerminal3 : struct, ITerminal + where TTerminal1 : struct, IToken + where TTerminal2 : struct, IToken + where TTerminal3 : struct, IToken { var t1 = terminal1 ?? new TTerminal1(); var t2 = terminal2 ?? new TTerminal2(); @@ -689,7 +709,7 @@ public static bool Repeat(ref TScanner scanner, ParseResult res if (separator is not null) { - if (Terminals.Literal(separator, ref scanner, advance: true)) + if (Tokens.Literal(separator, ref scanner, advance: true)) { if (withSpaces) Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index 602435aebd..8e891f3f7d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -62,18 +62,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (DirectiveExpressionParser.Or(ref scanner, result, out parsed)) { var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if ( - Terminals.Char('?', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(':', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + Tokens.Char('?', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && DirectiveExpressionParser.Expression(ref scanner, result, out var left, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(':', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && DirectiveExpressionParser.Expression(ref scanner, result, out var right, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) ) { - parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); + parsed = new TernaryExpression(parsed, left, right, scanner[position..scanner.Position]); return true; } else @@ -99,23 +99,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.And(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Literal("||", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Literal("||", ref scanner)) { var op = scanner.Slice(scanner.Position, 2).ToOperator(); scanner.Advance(2); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Or(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.And(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -148,23 +148,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BOr(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Literal("&&", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Literal("&&", ref scanner)) { var op = scanner.Slice(scanner.Position, 2).ToOperator(); scanner.Advance(2); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BAnd(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.BOr(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -200,23 +200,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.XOr(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (!Terminals.Literal("||", ref scanner) && Terminals.Char('|', ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (!Tokens.Literal("||", ref scanner) && Tokens.Char('|', ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BOr(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.XOr(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -249,23 +249,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BAnd(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Char('^', ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Char('^', ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.XOr(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.BAnd(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -298,23 +298,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Equality(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (!Terminals.Literal("&&", ref scanner) && Terminals.Char('&', ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (!Tokens.Literal("&&", ref scanner) && Tokens.Char('&', ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BAnd(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Equality(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -350,23 +350,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Relation(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Literal("==", ref scanner) || Terminals.Literal("!=", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Literal("==", ref scanner) || Tokens.Literal("!=", ref scanner)) { var op = scanner.Slice(scanner.Position, 2).ToOperator(); scanner.Advance(2); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Equality(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Relation(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -400,25 +400,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Shift(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - !Terminals.Literal(">=", ref scanner) && Terminals.Literal(">", ref scanner) - || !Terminals.Literal("<=", ref scanner) && Terminals.Literal("<", ref scanner)) + !Tokens.Literal(">=", ref scanner) && Tokens.Literal(">", ref scanner) + || !Tokens.Literal("<=", ref scanner) && Tokens.Literal("<", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Relation(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Shift(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -428,19 +428,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } - else if (Terminals.Literal(">=", ref scanner) || Terminals.Literal("<=", ref scanner)) + else if (Tokens.Literal(">=", ref scanner) || Tokens.Literal("<=", ref scanner)) { var op = scanner.Slice(scanner.Position, 2).ToOperator(); scanner.Advance(2); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Relation(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Shift(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -474,23 +474,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Add(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Literal(">>", ref scanner) || Terminals.Literal("<<", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Literal(">>", ref scanner) || Tokens.Literal("<<", ref scanner)) { var op = scanner.Slice(scanner.Position, 2).ToOperator(); scanner.Advance(2); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Shift(ref scanner, result, out var shift)) { - parsed = new BinaryExpression(left, op, shift, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, shift, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Add(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else @@ -524,23 +524,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Mul(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Set("+-", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Set("+-", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Add(ref scanner, result, out var add)) { - parsed = new BinaryExpression(left, op, add, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, add, scanner[position..scanner.Position]); return true; } else if (DirectiveExpressionParser.Mul(ref scanner, result, out var mul)) { - parsed = new BinaryExpression(left, op, mul, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, mul, scanner[position..scanner.Position]); return true; } else @@ -573,24 +573,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; parsed = null!; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var left)) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); - if (Terminals.Set("*/%", ref scanner)) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + if (Tokens.Set("*/%", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Mul(ref scanner, result, out var expression)) { - parsed = new BinaryExpression(left, op, expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, expression, scanner[position..scanner.Position]); return true; } else if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var right)) { - parsed = new BinaryExpression(left, op, right, scanner.GetLocation(position, scanner.Position - position)); + parsed = new BinaryExpression(left, op, right, scanner[position..scanner.Position]); return true; } scanner.Position = position; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index a5b677f2d3..1ecf478af4 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -12,7 +12,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var p = new PreProcessableCode(new()); while (!scanner.IsEof && DirectiveStatementParsers.Statement(ref scanner, result, out var statement)) p.Snippets.Add(statement); - p.Info = scanner.GetLocation(position, scanner.Position - position); + p.Info = scanner[position..scanner.Position]; parsed = p; return true; } @@ -133,7 +133,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (DirectiveStatementParsers.Endif(ref scanner, result, orError)) { - parsed = new ConditionalDirectives(ifDirective, scanner.GetLocation(position, scanner.Position - position)) + parsed = new ConditionalDirectives(ifDirective, scanner[position..scanner.Position]) { Elifs = elifDirectives, Else = elseDirective @@ -165,25 +165,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o int lineCount = 0; while ( !( - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) && ( - Terminals.Literal("#if", ref scanner) - || Terminals.Literal("#define", ref scanner) - || Terminals.Literal("#endif", ref scanner) - || Terminals.Literal("#elif", ref scanner) + Tokens.Literal("#if", ref scanner) + || Tokens.Literal("#define", ref scanner) + || Tokens.Literal("#endif", ref scanner) + || Tokens.Literal("#elif", ref scanner) ) ) && !scanner.IsEof ) { - CommonParsers.Until(ref scanner, '\n', advance: true); + Parsers.Until(ref scanner, '\n', advance: true); beginningOfLine = scanner.Position; lineCount += 1; } if (lineCount > 0) { scanner.Position = beginningOfLine; - parsed = new DirectiveCode(scanner.GetLocation(position, scanner.Position - position)); + parsed = new DirectiveCode(scanner[position..scanner.Position]); return true; } else @@ -201,15 +201,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#ifdef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && LiteralsParser.Identifier(ref scanner, result, out var id, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && Terminals.EOL(ref scanner, advance: true) + Tokens.Literal("#ifdef", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true, orError: new(SDSLErrorMessages.SDSL0016, scanner[scanner.Position], scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var id, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Tokens.EOL(ref scanner, advance: true) ) { - var cond = new IfDefDirective(id, scanner.GetLocation(position, scanner.Position - position)); + var cond = new IfDefDirective(id, scanner[position..scanner.Position]); parsed = cond; return true; } @@ -227,15 +227,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#ifndef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Literal("#ifndef", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) && LiteralsParser.Identifier(ref scanner, result, out var id) - && Terminals.EOL(ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { - var cond = new IfNDefDirective(id, scanner.GetLocation(position, scanner.Position - position)); + var cond = new IfNDefDirective(id, scanner[position..scanner.Position]); parsed = cond; return true; } @@ -254,15 +254,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#if", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Literal("#if", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) && DirectiveExpressionParser.Expression(ref scanner, result, out var expression) - && Terminals.EOL(ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { - var cond = new IfDirective(expression, scanner.GetLocation(position, scanner.Position - position)); + var cond = new IfDirective(expression, scanner[position..scanner.Position]); parsed = cond; return true; } @@ -282,15 +282,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#elif", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Literal("#elif", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) && DirectiveExpressionParser.Expression(ref scanner, result, out var expression) - && Terminals.EOL(ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { - var cond = new ElifDirective(expression, scanner.GetLocation(position, scanner.Position - position)); + var cond = new ElifDirective(expression, scanner[position..scanner.Position]); parsed = cond; return true; } @@ -308,13 +308,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#else", ref scanner, advance: true) - && Terminals.EOL(ref scanner, advance: true) + Tokens.Literal("#else", ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { - var cond = new ElseDirective(scanner.GetLocation(position, scanner.Position - position)); + var cond = new ElseDirective(scanner[position..scanner.Position]); parsed = cond; return true; } @@ -333,11 +333,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#endif", ref scanner, advance: true) - && Terminals.EOL(ref scanner, advance: true) + Tokens.Literal("#endif", ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { parsed = null!; @@ -359,25 +359,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#define", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Literal("#define", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { if ( DirectiveExpressionParser.Expression(ref scanner, result, out var expression) - && Terminals.EOL(ref scanner, advance: true) + && Tokens.EOL(ref scanner, advance: true) ) { - parsed = new(identifier, expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = new(identifier, expression, scanner[position..scanner.Position]); return true; } - else if(Terminals.EOL(ref scanner, advance: true)) + else if(Tokens.EOL(ref scanner, advance: true)) { - parsed = new(identifier, null, scanner.GetLocation(position, scanner.Position - position)); + parsed = new(identifier, null, scanner[position..scanner.Position]); return true; } else @@ -403,35 +403,35 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if ( - Terminals.Literal("#define", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Literal("#define", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, onlyWhiteSpace: true) && LiteralsParser.Identifier(ref scanner, result, out var identifier) - && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) - && Terminals.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && Tokens.Char('(', ref scanner, advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); + Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); var func = new FunctionDefineDirective(identifier, "", new()); if ( LiteralsParser.Identifier(ref scanner, result, out var param) - && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) ) func.Parameters.Add(param); while( - Terminals.Char(',', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + Tokens.Char(',', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) && LiteralsParser.Identifier(ref scanner, result, out param) - && CommonParsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) + && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) ) func.Parameters.Add(param); - if(!Terminals.Char(')', ref scanner, advance: true)) + if(!Tokens.Char(')', ref scanner, advance: true)) { - result.Errors.Add(new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + result.Errors.Add(new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); scanner.Position = position; parsed = null!; return false; @@ -439,11 +439,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { var startPattern = scanner.Position; - while(!(scanner.IsEof || Terminals.Char('\n', ref scanner) || Terminals.Literal("\r\n", ref scanner))) + while(!(scanner.IsEof || Tokens.Char('\n', ref scanner) || Tokens.Literal("\r\n", ref scanner))) scanner.Advance(1); func.Pattern = scanner.Memory[startPattern..scanner.Position].TrimEnd().TrimStart().ToString(); - if(!Terminals.Char('\n', ref scanner, advance: true)) - Terminals.Literal("\r\n", ref scanner, advance: true); + if(!Tokens.Char('\n', ref scanner, advance: true)) + Tokens.Literal("\r\n", ref scanner, advance: true); parsed = func; return true; } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index bfd05dcab5..f158d1b0d4 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -46,11 +46,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(')', ref scanner, advance: true) + Tokens.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(')', ref scanner, advance: true) ) return true; else @@ -72,21 +72,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var identifier) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('(', ref scanner, advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); ParameterParsers.Values(ref scanner, result, out var parameters); var pos2 = scanner.Position; - if (Terminals.Char(')', ref scanner, advance: true)) + if (Tokens.Char(')', ref scanner, advance: true)) { - parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position, scanner.Position - position)); + parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs deleted file mode 100644 index df6ee9d512..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Postfix.cs +++ /dev/null @@ -1,196 +0,0 @@ -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDSL; - -public record struct DirectivePostfixParser : IParser -{ - - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - // If the following - if ( - Accessor(ref scanner, result, out parsed) - && CommonParsers.Spaces0(ref scanner, result, out _) - ) - { - if (Terminals.Set("[.", ref scanner) || Terminals.Literal("++", ref scanner) || Terminals.Literal("--", ref scanner)) - { - if (Terminals.Char('.', ref scanner, advance: true)) - { - if (Postfix(ref scanner, result, out var accessed)) - { - parsed = new AccessorExpression(parsed, accessed, scanner.GetLocation(position, scanner.Position)); - return true; - } - else - { - scanner.Position = position; - return false; - } - } - else if (Terminals.Char('[', ref scanner, advance: true)) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if ( - ExpressionParser.Expression(ref scanner, result, out var index) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - { - parsed = new IndexerExpression(parsed, index, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - scanner.Position = position; - return false; - } - } - else if (Terminals.Literal("++", ref scanner, advance: true)) - { - parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else if (Terminals.Literal("--", ref scanner, advance: true)) - { - parsed = new PostfixExpression(parsed, Operator.Dec, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); - return false; - } - } - else return true; - } - else - { - if (orError is not null) - result.Errors.Add(orError.Value); - scanner.Position = position; - return false; - } - } - public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new DirectivePostfixParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new DirectivePostfixIncrementParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new DirectivePostfixAccessorParser().Match(ref scanner, result, out parsed, in orError); - internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new DirectivePostfixIndexerParser().Match(ref scanner, result, out parsed, in orError); -} - - -public record struct DirectivePostfixAccessorParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (PostfixParser.Indexer(ref scanner, result, out var expression)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if ( - Terminals.Char('.', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && PostfixParser.Accessor(ref scanner, result, out var accessed, new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) - { - parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - scanner.Position = pos2; - parsed = expression; - return true; - } - } - if (orError is not null) - result.Errors.Add(orError.Value); - parsed = null!; - return false; - } -} - -public record struct DirectivePostfixIndexerParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - - if (PrimaryParsers.Primary(ref scanner, result, out var expression)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('[', ref scanner, advance: true)) - { - if ( - CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - { - parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - result.Errors.Add(new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = null!; - return false; - } - } - else - { - scanner.Position = pos2; - parsed = expression; - return true; - } - } - if (orError is not null) - result.Errors.Add(orError.Value); - parsed = null!; - return false; - } -} - -public record struct DirectivePostfixIncrementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if(PostfixParser.Accessor(ref scanner, result, out parsed)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if(Terminals.Literal("++", ref scanner, advance: true)) - { - parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - scanner.Position = pos2; - return true; - } - } - if (orError is not null) - result.Errors.Add(orError.Value); - parsed = null!; - return false; - } -} - - diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 600ead6b2c..5c07d51790 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -41,36 +41,36 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("++", ref scanner, advance: true)) + if (Tokens.Literal("++", ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(Operator.Inc, lit, scanner[position..scanner.Position]); return true; } else { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); return false; } } // prefix decrememnt - else if (Terminals.Literal("--", ref scanner, advance: true)) + else if (Tokens.Literal("--", ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(Operator.Inc, lit, scanner[position..scanner.Position]); return true; } else { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); return false; } } @@ -92,28 +92,28 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if (Terminals.Set("!~", ref scanner)) + if (Tokens.Set("!~", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (DirectiveUnaryParsers.Primary(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(op, lit, scanner[position..scanner.Position]); return true; } else { parsed = null!; scanner.Position = position; - result.Errors.Add(new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); return false; } } else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); + result.Errors.Add(orError.Value with { Location = scanner[position] }); return false; } } @@ -126,21 +126,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if (Terminals.Set("+-", ref scanner)) + if (Tokens.Set("+-", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (DirectiveUnaryParsers.Prefix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(op, lit, scanner[position..scanner.Position]); return true; } else { // TODO: check if error can be added here if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); + result.Errors.Add(orError.Value with { Location = scanner[position] }); parsed = null!; scanner.Position = position; return false; @@ -149,7 +149,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); + result.Errors.Add(orError.Value with { Location = scanner[position] }); return false; } } @@ -162,21 +162,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(')', ref scanner, true) + Tokens.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var typeName, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(')', ref scanner, true) && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) ) { - parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner[position..scanner.Position]); return true; } else { if (orError is not null) - result.Errors.Add(orError.Value with { Location = scanner.GetErrorLocation(position) }); + result.Errors.Add(orError.Value with { Location = scanner[position] }); parsed = null!; scanner.Position = position; return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 0b4d498fff..05b5ded9df 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -14,7 +14,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (Ternary(ref scanner, result, out parsed)) return true; - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -25,24 +25,24 @@ public static bool Add(ref TScanner scanner, ParseResult result, out E var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != '\0' && parsed is not null) { if (Mul(ref scanner, result, out var mul)) - parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), mul, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == '\0') { if (Mul(ref scanner, result, out var mul)) parsed = mul; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.Set("+-", ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, "+-", out op, withSpaces: true, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -53,24 +53,24 @@ public static bool Mul(ref TScanner scanner, ParseResult result, out E var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != '\0' && parsed is not null) { if (PrefixParser.Prefix(ref scanner, result, out var prefix)) - parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), prefix, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == '\0') { if (PrefixParser.Prefix(ref scanner, result, out var prefix)) parsed = prefix; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.Set("*/%", ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, "*/%", out op, withSpaces: true, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -81,24 +81,24 @@ public static bool Shift(ref TScanner scanner, ParseResult result, out var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (Add(ref scanner, result, out var add)) - parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (Add(ref scanner, result, out var add)) parsed = add; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf([">>", "<<"], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, [">>", "<<"], out op, withSpaces: true, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -109,26 +109,26 @@ public static bool Relation(ref TScanner scanner, ParseResult result, var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (Shift(ref scanner, result, out var shift)) - parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (Shift(ref scanner, result, out var shift)) parsed = shift; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - while (Terminals.AnyOf(["<=", ">=", "<", ">"], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["<=", ">=", "<", ">"], out op, withSpaces: true, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -139,24 +139,24 @@ public static bool Equality(ref TScanner scanner, ParseResult result, var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (Relation(ref scanner, result, out var rel)) - parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (Relation(ref scanner, result, out var rel)) parsed = rel; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["==", "!="], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["==", "!="], out op, withSpaces: true, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -167,24 +167,27 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (Equality(ref scanner, result, out var eq)) - parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (Equality(ref scanner, result, out var eq)) parsed = eq; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (!Terminals.Literal("&&", ref scanner) && Terminals.AnyOf(["&"], ref scanner, out op, advance: true)); + while ( + !Parsers.FollowedBy(ref scanner, Tokens.Literal("&&"), withSpaces: true) + && Parsers.FollowedByAny(ref scanner, ["&"], out op, advance: true) + ); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -195,24 +198,27 @@ public static bool BOr(ref TScanner scanner, ParseResult result, out E var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (XOr(ref scanner, result, out var xor)) - parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (XOr(ref scanner, result, out var xor)) parsed = xor; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (!Terminals.Literal("||", ref scanner) && Terminals.AnyOf(["|"], ref scanner, out op, advance: true)); + while ( + !Parsers.FollowedBy(ref scanner, Tokens.Literal("||"), withSpaces: true) + && Parsers.FollowedByAny(ref scanner, ["|"], out op, advance: true) + ); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -223,24 +229,24 @@ public static bool XOr(ref TScanner scanner, ParseResult result, out E var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (BAnd(ref scanner, result, out var bAnd)) - parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (BAnd(ref scanner, result, out var bAnd)) parsed = bAnd; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["^"], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["^"], out op, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -251,24 +257,24 @@ public static bool And(ref TScanner scanner, ParseResult result, out E var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (BOr(ref scanner, result, out var bOr)) - parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (BOr(ref scanner, result, out var bOr)) parsed = bOr; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["&&"], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["&&"], out op, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -279,24 +285,24 @@ public static bool Or(ref TScanner scanner, ParseResult result, out Ex var position = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (op != "" && parsed is not null) { if (And(ref scanner, result, out var and)) - parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner.GetLocation(position..scanner.Position)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner[position..scanner.Position]); + else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (parsed is null && op == "") { if (And(ref scanner, result, out var and)) parsed = and; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Terminals.AnyOf(["||"], ref scanner, out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["||"], out op, advance: true)); if (parsed is not null) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -306,20 +312,20 @@ public static bool Ternary(ref TScanner scanner, ParseResult result, o if (Or(ref scanner, result, out parsed)) { var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('?', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char('?', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Expression(ref scanner, result, out var left, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + Parsers.Spaces0(ref scanner, result, out _); + if (Expression(ref scanner, result, out var left, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(':', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(':', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Expression(ref scanner, result, out var right, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + Parsers.Spaces0(ref scanner, result, out _); + if (Expression(ref scanner, result, out var right, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) { - parsed = new TernaryExpression(parsed, left, right, scanner.GetLocation(position, scanner.Position - position)); + parsed = new TernaryExpression(parsed, left, right, scanner[position..scanner.Position]); return true; } } @@ -331,6 +337,6 @@ public static bool Ternary(ref TScanner scanner, ParseResult result, o return true; } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index cce621504c..8dbcc0980d 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -14,7 +14,7 @@ public static bool Primary(ref TScanner scanner, ParseResult result, o public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return CommonParsers.Alternatives( + return Parsers.Alternatives( ref scanner, result, out parsed, in orError, Parenthesis, ArrayLiteral, @@ -33,7 +33,7 @@ public static bool Literal(ref TScanner scanner, ParseResult result, o parsed = lit; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } @@ -43,20 +43,20 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var identifier) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('(', ref scanner, advance: true) ) { ParameterParsers.Values(ref scanner, result, out var parameters); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(')', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(')', ref scanner, advance: true)) { - parsed = new MethodCall(identifier, parameters, scanner.GetLocation(position..scanner.Position)); + parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -64,14 +64,14 @@ public static bool Parenthesis(ref TScanner scanner, ParseResult resul { var position = scanner.Position; if ( - Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(')', ref scanner, advance: true) + Tokens.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(')', ref scanner, advance: true) ) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -79,18 +79,18 @@ public static bool ArrayLiteral(ref TScanner scanner, ParseResult resu { var position = scanner.Position; if ( - Terminals.Char('{', ref scanner, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ParameterParsers.Values, out ShaderExpressionList values, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) + Tokens.Char('{', ref scanner, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ParameterParsers.Values, out ShaderExpressionList values, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) ) { - parsed = new ArrayLiteral(scanner.GetLocation(position..scanner.Position)) + parsed = new ArrayLiteral(scanner[position..scanner.Position]) { Values = values.Values }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool MixinAccess(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -99,12 +99,12 @@ public static bool MixinAccess(ref TScanner scanner, ParseResult resul var position = scanner.Position; if ( ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('.'), withSpaces: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('.'), withSpaces: true) ) { - parsed = new MixinAccess(mixin, scanner.GetLocation(position..scanner.Position)); + parsed = new MixinAccess(mixin, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 92e979e658..8ae7be983c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -14,123 +14,128 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (PrimaryParsers.Primary(ref scanner, result, out parsed)) { - while (!scanner.IsEof && CommonParsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out var matched, withSpaces: true, advance: true)) + if (Parsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out _, withSpaces: true)) { - if ( - matched == "[" - && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression indexer, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(']'), withSpaces: true, advance: true) - ) + parsed = new AccessorChainExpression(parsed, parsed.Info); + while (!scanner.IsEof && Parsers.FollowedByAny(ref scanner, ["[", ".", "++", "--"], out var matched, withSpaces: true, advance: true)) { - parsed = new IndexerExpression(parsed, indexer, scanner.GetLocation(position..scanner.Position)); - } - else if ( - matched == "." - && CommonParsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression call, withSpaces: true, advance: true) - ) - { - parsed = new AccessorExpression(parsed, call, scanner.GetLocation(position..scanner.Position)); - } - else if ( - matched == "." - && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Literal, out Literal accessor, withSpaces: true, advance: true) - ) - { - parsed = new AccessorExpression(parsed, accessor, scanner.GetLocation(position..scanner.Position)); - } - else if (matched == "++" || matched == "--") - { - parsed = new PostfixExpression(parsed, matched.ToOperator(), scanner.GetLocation(position..scanner.Position)); - break; + if ( + matched == "[" + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression indexer, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) + ) + { + ((AccessorChainExpression)parsed).Accessors.Add(indexer); + } + else if ( + matched == "." + && Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression call, withSpaces: true, advance: true) + ) + { + ((AccessorChainExpression)parsed).Accessors.Add(call); + } + else if ( + matched == "." + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier accessor, withSpaces: true, advance: true) + ) + { + ((AccessorChainExpression)parsed).Accessors.Add(accessor); + } + else if (matched == "++" || matched == "--") + { + ((AccessorChainExpression)parsed).Accessors.Add(new PostfixIncrement(matched.ToOperator(), scanner[(scanner.Position - 2)..scanner.Position])); + break; + } } + Parsers.Spaces0(ref scanner, result, out _); } - CommonParsers.Spaces0(ref scanner, result, out _); + parsed.Info = scanner[position..scanner.Position]; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } - - public static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Accessor(ref scanner, result, out parsed)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Literal("++", ref scanner, advance: true)) - { - parsed = new PostfixExpression(parsed, Operator.Inc, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - scanner.Position = pos2; - return true; - } - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Indexer(ref scanner, result, out var expression)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if ( - Terminals.Char('.', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Accessor(ref scanner, result, out var accessed)) - { - parsed = new AccessorExpression(expression, accessed, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else - { - scanner.Position = pos2; - parsed = expression; - return true; - } - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } + // public static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + // where TScanner : struct, IScanner + // { + // var position = scanner.Position; + // if (Accessor(ref scanner, result, out parsed)) + // { + // var pos2 = scanner.Position; + // CommonParsers.Spaces0(ref scanner, result, out _); + // if (Tokens.Literal("++", ref scanner, advance: true)) + // { + // parsed = new PostfixExpression(parsed, Operator.Inc, scanner[position..scanner.Position]); + // return true; + // } + // else + // { + // scanner.Position = pos2; + // return true; + // } + // } + // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + // } - internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; + // public static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + // where TScanner : struct, IScanner + // { + // var position = scanner.Position; + // if (Indexer(ref scanner, result, out var expression)) + // { + // var pos2 = scanner.Position; + // CommonParsers.Spaces0(ref scanner, result, out _); + // if ( + // Tokens.Char('.', ref scanner, advance: true) + // && CommonParsers.Spaces0(ref scanner, result, out _) + // && Accessor(ref scanner, result, out var accessed)) + // { + // parsed = new AccessorExpression(expression, accessed, scanner[position..scanner.Position]); + // return true; + // } + // else + // { + // scanner.Position = pos2; + // parsed = expression; + // return true; + // } + // } + // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + // } - if (PrimaryParsers.Primary(ref scanner, result, out var expression)) - { - var pos2 = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('[', ref scanner, advance: true)) - { - if ( - CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var index) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - { - parsed = new IndexerExpression(expression, index, scanner.GetLocation(position, scanner.Position - position)); - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0021, scanner.GetErrorLocation(position), scanner.Memory)); + // internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + // where TScanner : struct, IScanner + // { + // var position = scanner.Position; - } - else - { - scanner.Position = pos2; - parsed = expression; - return true; - } - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } + // if (PrimaryParsers.Primary(ref scanner, result, out var expression)) + // { + // var pos2 = scanner.Position; + // CommonParsers.Spaces0(ref scanner, result, out _); + // if (Tokens.Char('[', ref scanner, advance: true)) + // { + // if ( + // CommonParsers.Spaces0(ref scanner, result, out _) + // && ExpressionParser.Expression(ref scanner, result, out var index) + // && CommonParsers.Spaces0(ref scanner, result, out _) + // && Tokens.Char(']', ref scanner, advance: true) + // ) + // { + // parsed = new IndexerExpression(expression, index, scanner[position..scanner.Position]); + // return true; + // } + // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0021, scanner[position], scanner.Memory)); + + // } + // else + // { + // scanner.Position = pos2; + // parsed = expression; + // return true; + // } + // } + // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + // } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index a459d89f4b..bd695dfcc9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -13,7 +13,7 @@ public static bool Prefix(ref TScanner scanner, ParseResult result, ou public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return CommonParsers.Alternatives( + return Parsers.Alternatives( ref scanner, result, out parsed, @@ -30,68 +30,68 @@ public static bool Not(ref TScanner scanner, ParseResult result, out E where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Set("!~", ref scanner)) + if (Tokens.Set("!~", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(op, lit, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Signed(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Set("+-", ref scanner)) + if (Tokens.Set("+-", ref scanner)) { var op = ((char)scanner.Peek()).ToOperator(); scanner.Advance(1); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (Prefix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(op, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(op, lit, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("++", ref scanner, advance: true)) + if (Tokens.Literal("++", ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(Operator.Inc, lit, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); } // prefix decrememnt - else if (Terminals.Literal("--", ref scanner, advance: true)) + else if (Tokens.Literal("--", ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner.GetLocation(position, scanner.Position - position)); + parsed = new PrefixExpression(Operator.Inc, lit, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0020, scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Cast(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) @@ -99,15 +99,15 @@ public static bool Cast(ref TScanner scanner, ParseResult result, out { var position = scanner.Position; if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true) ) { - parsed = new CastExpression(typeName.Name, Operator.Cast, expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = new CastExpression(typeName.Name, Operator.Cast, expression, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 6148294648..0e216ca412 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -40,7 +40,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o literal = b; return true; } - else return CommonParsers.Exit(ref scanner, result, out literal, position, orError); + else return Parsers.Exit(ref scanner, result, out literal, position, orError); } public static bool Literal(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) where TScanner : struct, IScanner @@ -49,63 +49,179 @@ public static bool Identifier(ref TScanner scanner, ParseResult result where TScanner : struct, IScanner => new IdentifierParser().Match(ref scanner, result, out identifier, orError); - public static bool TypeName(ref TScanner scanner, ParseResult result, out TypeName typeName, in ParseError? orError = null) + + public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + if(TypeNameLiteral(ref scanner, result, out var tn, orError)) + { + parsed = tn; + return true; + } + else return false; + } + public static bool TypeName(ref TScanner scanner, ParseResult result, out TypeName name, in ParseError? orError = null) where TScanner : struct, IScanner - => new TypeNameParser().Match(ref scanner, result, out typeName); - + { + name = null!; + var position = scanner.Position; + if (Tokens.Char('_', ref scanner) || Tokens.Letter(ref scanner)) + { + name = new TypeName("", new(), false); + scanner.Advance(1); + while (Tokens.LetterOrDigit(ref scanner) || Tokens.Char('_', ref scanner)) + scanner.Advance(1); + var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner[position..scanner.Position]); + + var intermediate = scanner.Position; + + if (Parsers.FollowedBy(ref scanner, Tokens.Char('<'), withSpaces: true, advance: true)) + { + Parsers.Spaces0(ref scanner, result, out _); + Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); + if (!Parsers.FollowedBy(ref scanner, Tokens.Char('>'), withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out name, position); + ((TypeName)name).Generics = generics; + intermediate = scanner.Position; + } + + + if ( + Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('[', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Parsers.Optional(ref scanner, new ExpressionParser(), result, out _) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(']', ref scanner, advance: true) + ) + { + ((TypeName)name).Name = scanner.Memory[position..scanner.Position].ToString().Trim(); + name.Info = scanner[position..scanner.Position]; + ((TypeName)name).IsArray = true; + return true; + } + else + { + scanner.Position = intermediate; + ((TypeName)name).Name = identifier.Name; + name.Info = scanner[position..scanner.Position]; + ((TypeName)name).IsArray = false; + return true; + } + } + else return Parsers.Exit(ref scanner, result, out name, position, orError); + } + public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, out TypeName parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - if(TypeName(ref scanner, result, out parsed)) + if (TypeName(ref scanner, result, out var typename)) { + parsed = (TypeName)typename; return true; } - else if(Number(ref scanner, result, out var number)) + else if (Number(ref scanner, result, out var number)) { - parsed = new TypeName(number.ToString(), number.Info, isArray: false); + parsed = new TypeName(number.ToString() ?? "", number.Info, isArray: false); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); } public static bool Boolean(ref TScanner scanner, ParseResult result, out BoolLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if(Terminals.AnyOf(["true", "false"], ref scanner, out var matched, advance: true)) + if (Tokens.AnyOf(["true", "false"], ref scanner, out var matched, advance: true)) { - number = new(matched == "true", scanner.GetLocation(position..scanner.Position)); + number = new(matched == "true", scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out number, scanner.Position, orError); + else return Parsers.Exit(ref scanner, result, out number, scanner.Position, orError); } - public static bool Number(ref TScanner scanner, ParseResult result, out NumberLiteral number, in ParseError? orError = null) + public static bool Number(ref TScanner scanner, ParseResult result, out Literal number, in ParseError? orError = null) where TScanner : struct, IScanner => new NumberParser().Match(ref scanner, result, out number, in orError); - - public static bool Vector(ref TScanner scanner, ParseResult result, out VectorLiteral parsed, in ParseError? orError = null) + + public static bool Vector(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new VectorParser().Match(ref scanner, result, out parsed, in orError); + { + var position = scanner.Position; + if ( + Tokens.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) + ) + { + var tnPos = scanner.Position; + if (Tokens.Digit(ref scanner, 2..4, advance: true)) + { + tnPos = scanner.Position; + int size = scanner.Span[scanner.Position - 1] - '0'; + if (size < 2 || size > 4) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0002, scanner[scanner.Position - 1], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char('(', ref scanner, advance: true)) + { + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), scanner[..]); + while (!scanner.IsEof) + { + Parsers.Spaces0(ref scanner, result, out _); + if (Vector(ref scanner, result, out var vec)) + p.Values.Add(vec); + else if (ExpressionParser.Expression(ref scanner, result, out var exp)) + p.Values.Add(exp); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(',', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + else if (Tokens.Char(')', ref scanner, advance: true)) + break; + } + if (scanner.IsEof) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0004, scanner[scanner.Position], scanner.Memory)); + if (p.Values.Count != size && p.Values.Count > size) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0005, scanner[scanner.Position], scanner.Memory)); + parsed = p; + return true; + } + } + else if ( + Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) + ) + { + parsed = new VectorLiteral(new TypeName(baseType, scanner[position..tnPos], isArray: false), scanner[position..scanner.Position]) + { + Values = [value] + }; + return true; + } + else return Parsers.Exit(ref scanner, result, out parsed, position); + + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } public static bool Matrix(ref TScanner scanner, ParseResult result, out MatrixLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MatrixParser().Match(ref scanner, result, out parsed, in orError); - public static bool Integer(ref TScanner scanner, ParseResult result, out IntegerLiteral number, in ParseError? orError = null) + public static bool Integer(ref TScanner scanner, ParseResult result, out Literal number, in ParseError? orError = null) where TScanner : struct, IScanner - => new IntegerParser().Match(ref scanner, result, out number, in orError); + => NumberParser.Integer(ref scanner, result, out number, in orError); public static bool StringLiteral(ref TScanner scanner, ParseResult result, out StringLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Char('\"', ref scanner, advance: true)) + if (Tokens.Char('\"', ref scanner, advance: true)) { - CommonParsers.Until(ref scanner, '\"', advance: true); + Parsers.Until(ref scanner, '\"', advance: true); if (scanner.Span[position..scanner.Position].Contains('\n')) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new(scanner.Span[position..scanner.Position].ToString(), scanner.GetLocation(position..scanner.Position)); + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[position], scanner.Memory)); + parsed = new(scanner.Span[position..scanner.Position].ToString(), scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position); + return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool AssignOperators(ref TScanner scanner, ParseResult result, out AssignOperator op, in ParseError? orError = null) @@ -113,7 +229,7 @@ public static bool AssignOperators(ref TScanner scanner, ParseResult r { op = AssignOperator.NOp; if ( - Terminals.AnyOf( + Tokens.AnyOf( ["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="], ref scanner, out var matched, @@ -148,7 +264,7 @@ public readonly record struct FloatSuffixParser() : ILiteralParser public static bool TryMatchAndAdvance(ref TScanner scanner, string match) where TScanner : struct, IScanner { - if (Terminals.Literal(match, ref scanner)) + if (Tokens.Literal(match, ref scanner)) { scanner.Advance(match.Length); return true; @@ -160,7 +276,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { suffix = new(32, false, false); - if (Terminals.AnyOf(["f", "f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true)) + if (Tokens.AnyOf(["f", "f16", "f32", "f64", "d", "h"], ref scanner, out var matched, advance: true)) { suffix = matched switch { @@ -181,7 +297,7 @@ public readonly record struct IntegerSuffixParser() : ILiteralParser public static bool TryMatchAndAdvance(ref TScanner scanner, string match) where TScanner : struct, IScanner { - if (Terminals.Literal(match, ref scanner)) + if (Tokens.Literal(match, ref scanner)) { scanner.Advance(match.Length); return true; @@ -193,7 +309,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { suffix = new(32, false, false); - if (Terminals.AnyOf(["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "U", "L"], ref scanner, out var matched, advance: true)) + if (Tokens.AnyOf(["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "U", "L"], ref scanner, out var matched, advance: true)) { suffix = matched switch { @@ -223,143 +339,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { literal = null!; var position = scanner.Position; - if (Terminals.Char('_', ref scanner) || Terminals.Letter(ref scanner)) + if (Tokens.Char('_', ref scanner) || Tokens.Letter(ref scanner)) { scanner.Advance(1); - while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) + while (Tokens.LetterOrDigit(ref scanner) || Tokens.Char('_', ref scanner)) scanner.Advance(1); var id = scanner.Memory[position..scanner.Position].ToString(); if (Reserved.Keywords.Contains(id)) - return CommonParsers.Exit(ref scanner, result, out literal, position, orError); - literal = new(id, scanner.GetLocation(position, scanner.Position - position)); + return Parsers.Exit(ref scanner, result, out literal, position, orError); + literal = new(id, scanner[position..scanner.Position]); return true; } else return false; } } -public record struct TypeNameParser() : ILiteralParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out TypeName name, in ParseError? orError = null) - where TScanner : struct, IScanner - { - name = null!; - var position = scanner.Position; - if (Terminals.Char('_', ref scanner) || Terminals.Letter(ref scanner)) - { - name = new TypeName("", new(), false); - scanner.Advance(1); - while (Terminals.LetterOrDigit(ref scanner) || Terminals.Char('_', ref scanner)) - scanner.Advance(1); - var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner.GetLocation(position, scanner.Position - position)); - - var intermediate = scanner.Position; - - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('<'), withSpaces: true, advance: true)) - { - CommonParsers.Spaces0(ref scanner, result, out _); - CommonParsers.Repeat(ref scanner, result, LiteralsParser.TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); - if (!CommonParsers.FollowedBy(ref scanner, Terminals.Char('>'), withSpaces: true, advance: true)) - return CommonParsers.Exit(ref scanner, result, out name, position); - name.Generics = generics; - intermediate = scanner.Position; - } - - - if ( - CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('[', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Optional(ref scanner, new ExpressionParser(), result, out _) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(']', ref scanner, advance: true) - ) - { - name.Name = scanner.Memory[position..scanner.Position].ToString().Trim(); - name.Info = scanner.GetLocation(position..scanner.Position); - name.IsArray = true; - return true; - } - else - { - scanner.Position = intermediate; - name.Name = identifier.Name; - name.Info = scanner.GetLocation(position..scanner.Position); - name.IsArray = false; - return true; - } - } - else return CommonParsers.Exit(ref scanner, result, out name, position, orError); - } -} - - - - -public record struct VectorParser : IParser -{ - - public readonly bool Match(ref TScanner scanner, ParseResult result, out VectorLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Terminals.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) - ) - { - var tnPos = scanner.Position; - if (Terminals.Digit(ref scanner, 2..4, advance: true)) - { - tnPos = scanner.Position; - int size = scanner.Span[scanner.Position - 1] - '0'; - if (size < 2 || size > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('(', ref scanner, advance: true)) - { - var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(..)) - { - TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) - }; - while (!scanner.IsEof) - { - CommonParsers.Spaces0(ref scanner, result, out _); - if (LiteralsParser.Vector(ref scanner, result, out var vec)) - p.Values.Add(vec); - else if (ExpressionParser.Expression(ref scanner, result, out var exp)) - p.Values.Add(exp); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(',', ref scanner, advance: true)) - CommonParsers.Spaces0(ref scanner, result, out _); - else if (Terminals.Char(')', ref scanner, advance: true)) - break; - } - if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0004, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - if (p.Values.Count != size && p.Values.Count > size) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0005, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = p; - return true; - } - } - else if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) - ) - { - parsed = new VectorLiteral(new TypeName(baseType, scanner.GetLocation(position..tnPos), isArray: false), scanner.GetLocation(position..scanner.Position)) - { - Values = [value] - }; - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); - - } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - } -} public record struct MatrixParser : IParser { @@ -368,48 +362,48 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) - && Terminals.Digit(ref scanner, 2..4, advance: true) - && Terminals.Char('x', ref scanner, advance: true) - && Terminals.Digit(ref scanner, 2..4, advance: true) + Tokens.AnyOf(["bool", "half", "float", "double", "short", "ushort", "int", "uint", "long", "ulong"], ref scanner, out var baseType, advance: true) + && Tokens.Digit(ref scanner, 2..4, advance: true) + && Tokens.Char('x', ref scanner, advance: true) + && Tokens.Digit(ref scanner, 2..4, advance: true) ) { var tnPos = scanner.Position; int rows = scanner.Span[scanner.Position - 3] - '0'; int cols = scanner.Span[scanner.Position - 1] - '0'; if (cols < 2 || cols > 4 || rows < 2 || rows > 4) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0006, scanner.GetErrorLocation(scanner.Position - 1), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('(', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0006, scanner[scanner.Position - 1], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char('(', ref scanner, advance: true)) { - var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner.GetLocation(position..tnPos), isArray: false), rows, cols, scanner.GetLocation(..)) + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), rows, cols, scanner[..]) { - TypeName = new(baseType, scanner.GetLocation((tnPos - baseType.Length)..(tnPos - 1)), isArray: false) + TypeName = new(baseType, scanner[(tnPos - baseType.Length)..(tnPos - 1)], isArray: false) }; while (!scanner.IsEof) { - CommonParsers.Spaces0(ref scanner, result, out _); - + Parsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.Vector(ref scanner, result, out var vector)) p.Values.Add(vector); else if (ExpressionParser.Expression(ref scanner, result, out var expression)) p.Values.Add(expression); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(',', ref scanner, advance: true)) - CommonParsers.Spaces0(ref scanner, result, out _); - else if (Terminals.Char(')', ref scanner, advance: true)) + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(',', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + else if (Tokens.Char(')', ref scanner, advance: true)) break; } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0008, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0008, scanner[scanner.Position], scanner.Memory)); if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0002, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0002, scanner[scanner.Position], scanner.Memory)); parsed = p; return true; } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 79df6340a2..32e147fa5a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -4,137 +4,115 @@ namespace Stride.Shaders.Parsing.SDSL; -public struct NumberParser : IParser +public struct NumberParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out NumberLiteral parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - var position = scanner.Position; - var fp = new FloatParser(); - var ip = new IntegerParser(); - var hx = new HexParser(); - - if (fp.Match(ref scanner, result, out FloatLiteral pf)) - { - parsed = pf; - return true; - } - else if (hx.Match(ref scanner, result, out HexLiteral hi)) - { - parsed = hi; - return true; - } - else if (ip.Match(ref scanner, result, out IntegerLiteral pi)) - { - parsed = pi; - return true; - } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Alternatives( + ref scanner, + result, + out parsed, + orError, + Hex, + Float, + Integer + + ); } -} -public struct IntegerParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out IntegerLiteral node, in ParseError? orError = null) + public static bool Integer(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; IntegerSuffixParser suffix = new(); - if (Terminals.Digit(ref scanner, 1.., advance: true)) + if (Tokens.Digit(ref scanner, 1.., advance: true)) { - while (Terminals.Digit(ref scanner, advance: true)) ; + while (Tokens.Digit(ref scanner, advance: true)) ; var numPos = scanner.Position; if (suffix.Match(ref scanner, null!, out Suffix suf)) { - node = new(suf, long.Parse(scanner.Span[position..numPos]), scanner.GetLocation(position, scanner.Position)); + parsed = new IntegerLiteral(suf, long.Parse(scanner.Span[position..numPos]), scanner[position..scanner.Position]); return true; } else { var memory = scanner.Memory[position..scanner.Position]; - node = new(new(32, false, true), long.Parse(memory.Span), new(scanner.Memory, position..scanner.Position)); + parsed = new IntegerLiteral(new(32, false, true), long.Parse(memory.Span), new(scanner.Memory, position..scanner.Position)); return true; } } - else if (Terminals.Char('0', ref scanner, advance: true) && !Terminals.Digit(ref scanner, ..)) + else if (Tokens.Char('0', ref scanner, advance: true) && !Tokens.Digit(ref scanner, ..)) { - node = new(new(32, false, true), 0, new(scanner.Memory, position..scanner.Position)); + parsed = new IntegerLiteral(new(32, false, true), 0, new(scanner.Memory, position..scanner.Position)); return true; } - else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} - -public struct FloatParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out FloatLiteral node, in ParseError? orError = null) + public static bool Float(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Char('.', ref scanner, advance: true)) + if (Tokens.Char('.', ref scanner, advance: true)) { - if (!Terminals.Digit(ref scanner)) - return CommonParsers.Exit(ref scanner, result, out node, position); - while (Terminals.Digit(ref scanner, advance: true)) ; + if (!Tokens.Digit(ref scanner)) + return Parsers.Exit(ref scanner, result, out parsed, position); + while (Tokens.Digit(ref scanner, advance: true)) ; } - else if (Terminals.Digit(ref scanner, 1.., advance: true)) + else if (Tokens.Digit(ref scanner, 1.., advance: true)) { - while (Terminals.Digit(ref scanner, advance: true)) ; - if (Terminals.Char('.', ref scanner)) + while (Tokens.Digit(ref scanner, advance: true)) ; + if (Tokens.Char('.', ref scanner)) { scanner.Advance(1); - if (!Terminals.Digit(ref scanner) && !Terminals.FloatSuffix(ref scanner, out _)) - return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - while (Terminals.Digit(ref scanner, advance: true)) ; + if (!Tokens.Digit(ref scanner) && !Tokens.FloatSuffix(ref scanner, out _)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + while (Tokens.Digit(ref scanner, advance: true)) ; } - else if (Terminals.FloatSuffix(ref scanner, out _) || Terminals.Char('e', ref scanner)){} - else return CommonParsers.Exit(ref scanner, result, out node, position); + else if (Tokens.FloatSuffix(ref scanner, out _) || Tokens.Char('e', ref scanner)) { } + else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (Terminals.Digit(ref scanner, 0, advance: true)) + else if (Tokens.Digit(ref scanner, 0, advance: true)) { - if (Terminals.Char('.', ref scanner, advance: true)) + if (Tokens.Char('.', ref scanner, advance: true)) { - if (!Terminals.Digit(ref scanner) && !Terminals.FloatSuffix(ref scanner, out _)) - return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - while (Terminals.Digit(ref scanner, advance: true)) ; + if (!Tokens.Digit(ref scanner) && !Tokens.FloatSuffix(ref scanner, out _)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + while (Tokens.Digit(ref scanner, advance: true)) ; } - else return CommonParsers.Exit(ref scanner, result, out node, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } - else return CommonParsers.Exit(ref scanner, result, out node, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); var value = double.Parse(scanner.Span[position..scanner.Position], CultureInfo.InvariantCulture); int? exponent = null; - if (Terminals.Char('e', ref scanner, advance: true)) + if (Tokens.Char('e', ref scanner, advance: true)) { - var signed = Terminals.AnyOf(["+", "-"], ref scanner, out var matched, advance: true); - if (LiteralsParser.Integer(ref scanner, result, out var exp)) + var signed = Tokens.AnyOf(["+", "-"], ref scanner, out var matched, advance: true); + if (Integer(ref scanner, result, out var exp)) { - exponent = (int)exp.Value; - if(signed && matched == "-") + exponent = (int)((IntegerLiteral)exp).Value; + if (signed && matched == "-") exponent = -exponent; } - else return CommonParsers.Exit(ref scanner, result, out node, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - if (Terminals.FloatSuffix(ref scanner, out var suffix, advance: true) && suffix is not null) - node = new(suffix.Value, value, exponent, scanner.GetLocation(position..scanner.Position)); + if (Tokens.FloatSuffix(ref scanner, out var suffix, advance: true) && suffix is not null) + parsed = new FloatLiteral(suffix.Value, value, exponent, scanner[position..scanner.Position]); else - node = new(new(32, true, true), value, exponent, scanner.GetLocation(position..scanner.Position)); + parsed = new FloatLiteral(new(32, true, true), value, exponent, scanner[position..scanner.Position]); return true; } -} - -public struct HexParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out HexLiteral node, in ParseError? orError = null) + public static bool Hex(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - node = null!; + parsed = null!; var position = scanner.Position; - if (Terminals.Literal("0x", ref scanner, advance: true)) + if (Tokens.Literal("0x", ref scanner, advance: true)) { - while (Terminals.Set("abcdefABCDEF", ref scanner, advance: true) || Terminals.Digit(ref scanner, advance: true)) ; + while (Tokens.Set("abcdefABCDEF", ref scanner, advance: true) || Tokens.Digit(ref scanner, advance: true)) ; ulong sum = 0; @@ -144,16 +122,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var add = v * Math.Pow(16, i); if (ulong.MaxValue - sum < add) { - result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner.GetErrorLocation(position), scanner.Memory)); + result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner[position], scanner.Memory)); return false; } } - node = new HexLiteral(sum, scanner.GetLocation(position, scanner.Position - position)); + parsed = new HexLiteral(sum, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out node, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - static int Hex2int(char ch) { if (ch >= '0' && ch <= '9') @@ -164,4 +141,5 @@ static int Hex2int(char ch) return ch - 'a' + 10; return -1; } -} \ No newline at end of file +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 43047b74e8..1712a5fd33 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -10,26 +10,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); - var isStaged = Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _); + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); + var isStaged = Tokens.Literal("stage", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _); - if (Terminals.Literal("compose", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("compose", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { var tmp = scanner.Position; - if (CommonParsers.MixinIdentifierArraySizeValue(ref scanner, result, out var mixin, out var name, out var arraysize, out var value, advance: true)) + if (Parsers.MixinIdentifierArraySizeValue(ref scanner, result, out var mixin, out var name, out var arraysize, out var value, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char(';', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new(name, mixin, true, scanner.GetLocation(position..)) + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char(';', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[position], scanner.Memory)); + parsed = new(name, mixin, true, scanner[position..]) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs index 3a3c00137e..f5b2a46b5c 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -12,7 +12,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( - CommonParsers.Repeat( + Parsers.Repeat( ref scanner, new AttributeParser(), result, @@ -20,13 +20,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o 1, true ) - && CommonParsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) { - parsed = new ShaderAttributeList(attributeList, scanner.GetLocation(position..)); + parsed = new ShaderAttributeList(attributeList, scanner[position..]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool AttributeList(ref TScanner scanner, ParseResult result, out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -40,32 +40,32 @@ public record struct AttributeParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Char('[', ref scanner, advance: true)) + if (Tokens.Char('[', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char('(', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char('(', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); ParameterParsers.Values(ref scanner, result, out var values); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _) && Terminals.Char(']', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _) && Tokens.Char(']', ref scanner, advance: true)) { - parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..), values.Values); + parsed = new AnyShaderAttribute(identifier, scanner[position..], values.Values); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new("Badly formatted attribute", scanner[position], scanner.Memory)); } - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char(']', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(position), scanner.Memory)); - parsed = new AnyShaderAttribute(identifier, scanner.GetLocation(position..)); + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char(']', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0019, scanner[position], scanner.Memory)); + parsed = new AnyShaderAttribute(identifier, scanner[position..]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 39e41b580e..0a4b291305 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -11,7 +11,7 @@ public record struct BufferParsers : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return CommonParsers.Alternatives( + return Parsers.Alternatives( ref scanner, result, out parsed, in orError, CBuffer, TBuffer, @@ -23,126 +23,126 @@ public record struct BufferParsers : IParser where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("tbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("tbuffer", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { if ( - BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + BufferName(ref scanner, result, out var identifiers, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner)) + if (Tokens.Char('{', ref scanner)) { List members = []; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); do { - if (Member(ref scanner, result, out var member) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Member(ref scanner, result, out var member) && Parsers.Spaces0(ref scanner, result, out _)) members.Add(member); } - while (!(Terminals.Letter(ref scanner) || Terminals.Char('_', ref scanner))); - if (Terminals.Char('}', ref scanner, advance: true)) + while (!(Tokens.Letter(ref scanner) || Tokens.Char('_', ref scanner))); + if (Tokens.Char('}', ref scanner, advance: true)) { - parsed = new TBuffer(identifiers, scanner.GetLocation(position..scanner.Position)) + parsed = new TBuffer(identifiers, scanner[position..scanner.Position]) { Members = members }; return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); ; + return Parsers.Exit(ref scanner, result, out parsed, position, orError); ; } public static bool CBuffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("cbuffer", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("cbuffer", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { if ( - BufferName(ref scanner, result, out var identifiers, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + BufferName(ref scanner, result, out var identifiers, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner, advance: true)) + if (Tokens.Char('{', ref scanner, advance: true)) { List members = []; - CommonParsers.Spaces0(ref scanner, result, out _); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { if ( Member(ref scanner, result, out var member) - && CommonParsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) members.Add(member); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new CBuffer(identifiers, scanner.GetLocation(position..scanner.Position)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0043, scanner[scanner.Position], scanner.Memory)); + parsed = new CBuffer(identifiers, scanner[position..scanner.Position]) { Members = members }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool RGroup(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("rgroup", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("rgroup", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { if ( BufferName(ref scanner, result, out var identifiers) - && CommonParsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('{', ref scanner, advance: true)) + if (Tokens.Char('{', ref scanner, advance: true)) { List members = []; - CommonParsers.Spaces0(ref scanner, result, out _); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { if ( Member(ref scanner, result, out var member) - && CommonParsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) members.Add(member); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } if (scanner.IsEof) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0043, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - parsed = new RGroup(identifiers, scanner.GetLocation(position..scanner.Position)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0043, scanner[scanner.Position], scanner.Memory)); + parsed = new RGroup(identifiers, scanner[position..scanner.Position]) { Members = members }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); var position = scanner.Position; var isStage = false; StreamKind streamKind = StreamKind.None; bool hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes, orError); var tmp = scanner.Position; - if (Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("stage", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { isStage = true; tmp = scanner.Position; @@ -150,19 +150,19 @@ public record struct BufferParsers : IParser else scanner.Position = tmp; if ( - CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySizes, out var value, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Set(";"), withSpaces: true, advance: true) + Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySizes, out var value, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Set(";"), withSpaces: true, advance: true) ) { - parsed = new ShaderMember(typename, identifier, null, true, scanner.GetLocation(position..scanner.Position), isStage, streamKind, arraySizes: arraySizes); + parsed = new ShaderMember(typename, identifier, null, true, scanner[position..scanner.Position], isStage, streamKind, arraySizes: arraySizes); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool BufferName(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return CommonParsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); + return Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index a8eef6788a..13145f9fb8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -36,17 +36,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( - Terminals.Literal("shader", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && LiteralsParser.Identifier(ref scanner, result, out var className, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('{', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Literal("shader", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _, new(SDSLErrorMessages.SDSL0016, scanner[scanner.Position], scanner.Memory)) + && LiteralsParser.Identifier(ref scanner, result, out var className, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('{', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) ) { - var c = new ShaderClass(className, scanner.GetLocation(position, scanner.Position - position)); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + var c = new ShaderClass(className, scanner[position..scanner.Position]); + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) { @@ -54,12 +54,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else break; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } parsed = c; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -70,53 +70,53 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; var tmp = position; - if (Terminals.Literal("internal", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("internal", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; - if(CommonParsers.FollowedBy(ref scanner, Terminals.Literal("partial"), withSpaces: true, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if(Parsers.FollowedBy(ref scanner, Tokens.Literal("partial"), withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; if ( ( - Terminals.Literal("shader", ref scanner, advance: true) - || Terminals.Literal("class", ref scanner, advance: true) + Tokens.Literal("shader", ref scanner, advance: true) + || Tokens.Literal("class", ref scanner, advance: true) ) - && CommonParsers.Spaces1(ref scanner, result,out _)) + && Parsers.Spaces1(ref scanner, result,out _)) { if ( - LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - parsed = new ShaderClass(identifier, scanner.GetLocation(..)); - if (Terminals.Char('<', ref scanner, advance: true)) + parsed = new ShaderClass(identifier, scanner[..]); + if (Tokens.Char('<', ref scanner, advance: true)) { ParameterParsers.Declarations(ref scanner, result, out var generics); - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0034, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char('>', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0034, scanner[scanner.Position], scanner.Memory)); parsed.Generics = generics; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - if (Terminals.Char(':', ref scanner, advance: true)) + if (Tokens.Char(':', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); while (ShaderClassParsers.Mixin(ref scanner, result, out var mixin)) { parsed.Mixins.Add(mixin); - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(',', ref scanner, advance: true)) - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(',', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); else break; } if (parsed.Mixins.Count == 0) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + return Parsers.Exit(ref scanner, result, out parsed, position, new("Expecting at least one mixin", scanner[scanner.Position], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); } - if (Terminals.Char('{', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + if (Tokens.Char('{', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) ) { - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { if (ShaderElementParsers.ShaderElement(ref scanner, result, out var e)) { @@ -124,17 +124,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else break; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); - parsed.Info = scanner.GetLocation(position..scanner.Position); + Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner[position..scanner.Position]; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new("Expecting shader body", scanner[position], scanner.Memory)); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -150,25 +150,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if(LiteralsParser.Identifier(ref scanner, result, out var id)) path.Add(id); } - while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)); + while (!scanner.IsEof && Tokens.Char('.', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)); if (path.Count > 0) { var identifier = path[^1]; - parsed = new Mixin(identifier, scanner.GetLocation(..)); + parsed = new Mixin(identifier, scanner[..]); var tmpPos = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if ( - Terminals.Char('<', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Char('<', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) ) { ParameterParsers.GenericsList(ref scanner, result, out var values); parsed.Generics = values; parsed.Path = path[..^1]; - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char('>', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position); + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char('>', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position); return true; } else @@ -177,7 +177,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -190,13 +190,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.Identifier(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && Parsers.Spaces1(ref scanner, result, out _, new(SDSLErrorMessages.SDSL0016, scanner[scanner.Position], scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { - parsed = new ShaderGenerics(typename, identifier, scanner.GetLocation(position, scanner.Position - position)); + parsed = new ShaderGenerics(typename, identifier, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 681359b2da..c289b91bed 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -20,27 +20,27 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o List arraySizes = null!; Expression? value = null!; - var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); - if (Terminals.Literal("compose", ref scanner)) - return CommonParsers.Exit(ref scanner, result, out parsed, position); + if (Tokens.Literal("compose", ref scanner)) + return Parsers.Exit(ref scanner, result, out parsed, position); var hasModifier = - CommonParsers.VariableModifiers(ref scanner, result, out var isStaged, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.VariableModifiers(ref scanner, result, out var isStaged, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) + && Parsers.Spaces0(ref scanner, result, out _); - if (CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) + if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) { if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { typeName.ArraySize = arraySizes; - parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), semantic: semantic, arraySizes: arraySizes) + parsed = new(typeName, identifier, value, arraySizes != null, scanner[position..scanner.Position], semantic: semantic, arraySizes: arraySizes) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, @@ -50,11 +50,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typeName, identifier, value, arraySizes != null, scanner.GetLocation(position..scanner.Position), arraySizes: arraySizes) + parsed = new(typeName, identifier, value, arraySizes != null, scanner[position..scanner.Position], arraySizes: arraySizes) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, @@ -64,9 +64,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0013, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } public record struct ShaderStructParser : IParser @@ -75,26 +75,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("struct", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("struct", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var identifier) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _); - parsed = new ShaderStruct(identifier, scanner.GetLocation(position..)); - CommonParsers.Repeat(ref scanner, new ShaderStructMemberParser(), result, out var members, 0, withSpaces: true, separator: ";"); - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + Parsers.Spaces0(ref scanner, result, out _); + parsed = new ShaderStruct(identifier, scanner[position..]); + Parsers.Repeat(ref scanner, new ShaderStructMemberParser(), result, out var members, 0, withSpaces: true, separator: ";"); + Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); parsed.Members = members; - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true)) + if (Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); - parsed.Info = scanner.GetLocation(position..scanner.Position); + Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); + parsed.Info = scanner[position..scanner.Position]; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0019, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -104,34 +104,34 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("SamplerState", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("SamplerState", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + parsed = new(identifier, scanner[position..scanner.Position]) { Members = assignments }; return true; } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new(identifier, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0019, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) @@ -139,16 +139,16 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P { var position = scanner.Position; if ( - CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateAssign(identifier, expression, scanner.GetLocation(position..scanner.Position)); + parsed = new SamplerStateAssign(identifier, expression, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -158,34 +158,34 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("SamplerComparisonState", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("SamplerComparisonState", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var identifier) ) { if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char('{'), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && CommonParsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('}'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)) + parsed = new(identifier, scanner[position..scanner.Position]) { Members = assignments }; return true; } - else if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + else if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new(identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new(identifier, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0019, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0019, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) @@ -193,16 +193,16 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P { var position = scanner.Position; if ( - CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('='), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateAssign(identifier, expression, scanner.GetLocation(position..scanner.Position)); + parsed = new SamplerStateAssign(identifier, expression, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } public record struct ShaderStructMemberParser : IParser @@ -213,18 +213,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes); if ( - CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) - && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) + && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) ) { - parsed = new ShaderStructMember(typename, identifier, scanner.GetLocation(position..scanner.Position)); + parsed = new ShaderStructMember(typename, identifier, scanner[position..scanner.Position]); if (hasAttributes) parsed.Attributes = attributes.Attributes; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index fb3acde187..66b480647b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -16,13 +16,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (BufferParsers.Buffer(ref scanner, result, out var buffer)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); parsed = buffer; return true; } else if (Struct(ref scanner, result, out var structElement)) { - CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true); + Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); parsed = structElement; return true; } @@ -52,7 +52,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } } @@ -68,7 +68,7 @@ public static bool AnySamplers(ref TScanner scanner, ParseResult resul where TScanner : struct, IScanner { var position = scanner.Position; - var isStaged = Terminals.Literal("stage", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); + var isStaged = Tokens.Literal("stage", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _); if (SamplerState(ref scanner, result, out var samplerState)) { @@ -82,7 +82,7 @@ public static bool AnySamplers(ref TScanner scanner, ParseResult resul parsed = samplerCompState; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -104,36 +104,36 @@ public static bool ShaderVariable(ref TScanner scanner, ParseResult re var position = scanner.Position; var hasStorageClass = - Terminals.AnyOf( + Tokens.AnyOf( ["extern", "nointerpolation", "precise", "shared", "groupshared", "static", "uniform", "volatile"], ref scanner, out var storageClass, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) ; var hasTypeModifier = - Terminals.AnyOf( + Tokens.AnyOf( ["const", "row_major", "column_major"], ref scanner, out var typemodifier, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) ; if ( - CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { type.ArraySize = arraySize; - parsed = new ShaderVariable(type, name, value, scanner.GetLocation(position..scanner.Position)) + parsed = new ShaderVariable(type, name, value, scanner[position..scanner.Position]) { StorageClass = storageClass.ToStorageClass(), TypeModifier = typemodifier.ToTypeModifier() }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -143,19 +143,19 @@ public static bool TypeDef(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( - Terminals.Literal("typedef", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("typedef", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.TypeName(ref scanner, result, out var type) - && CommonParsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(';', ref scanner, advance: true) ) { - parsed = new TypeDef(type, name, scanner.GetLocation(position..scanner.Position)); + parsed = new TypeDef(type, name, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 21f6832d3f..fdc0d3e8d7 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -12,52 +12,52 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); var file = new ShaderFile(new(scanner.Memory, ..)); while (!scanner.IsEof) { if ( - Terminals.Literal("namespace", ref scanner) + Tokens.Literal("namespace", ref scanner) && NamespaceParsers.Namespace(ref scanner, result, out var ns) ) { file.Namespaces.Add(ns); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } else if ( ( - Terminals.Literal("class", ref scanner) - || Terminals.Literal("shader", ref scanner) - || CommonParsers.SequenceOf(ref scanner, ["internal", "shader"]) + Tokens.Literal("class", ref scanner) + || Tokens.Literal("shader", ref scanner) + || Parsers.SequenceOf(ref scanner, ["internal", "shader"]) ) && ShaderClassParsers.Class(ref scanner, result, out var shader) ) { file.RootDeclarations.Add(shader); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - else if ((Terminals.Literal("effect", ref scanner) || CommonParsers.SequenceOf(ref scanner, ["partial", "effect"])) + else if ((Tokens.Literal("effect", ref scanner) || Parsers.SequenceOf(ref scanner, ["partial", "effect"])) && EffectParser.Effect(ref scanner, result, out var effect) ) { file.RootDeclarations.Add(effect); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - else if (Terminals.Literal("params ", ref scanner) + else if (Tokens.Literal("params ", ref scanner) && ParamsParsers.Params(ref scanner, result, out var p) ) { file.RootDeclarations.Add(p); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - else if (Terminals.Literal("using ", ref scanner) + else if (Tokens.Literal("using ", ref scanner) && UsingNamespace(ref scanner, result, out var uns) ) { file.RootDeclarations.Add(uns); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } parsed = file; return true; @@ -73,29 +73,29 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("using", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Literal("using", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - parsed = new(scanner.GetLocation(..)); + parsed = new(scanner[..]); do { - if (CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true)) + if (Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true)) { parsed.NamespacePath.Add(identifier); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true)); + while (!scanner.IsEof && Tokens.Char('.', ref scanner, advance: true)); - - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + + if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed.Info = scanner.GetLocation(position..scanner.Position); + parsed.Info = scanner[position..scanner.Position]; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0013, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0013, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -109,54 +109,55 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("namespace", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Tokens.Literal("namespace", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) ) { var ns = new ShaderNamespace(new()); + Parsers.Spaces0(ref scanner, result, out _); + var nsStart = scanner.Position; do { - CommonParsers.Spaces0(ref scanner, result, out _); - + Parsers.Spaces0(ref scanner, result, out _); if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) ns.NamespacePath.Add(identifier); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - while (!scanner.IsEof && Terminals.Char('.', ref scanner, advance: true)); + while (!scanner.IsEof && Tokens.Char('.', ref scanner, advance: true)); if (ns.NamespacePath.Count > 0) - ns.Namespace = string.Join(".", ns.NamespacePath); - if (Terminals.Char(';', ref scanner, advance: true)) + ns.Namespace = new(string.Join(".", ns.NamespacePath), scanner[nsStart..scanner.Position]); + if (Tokens.Char(';', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); while (ShaderClassParsers.Class(ref scanner, result, out var shader)) { ns.Declarations.Add(shader); } } - else if (Terminals.Char('{', ref scanner, advance: true)) + else if (Tokens.Char('{', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { - if (ShaderClassParsers.Class(ref scanner, result, out var shader) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (ShaderClassParsers.Class(ref scanner, result, out var shader) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(shader); - else if (EffectParser.Effect(ref scanner, result, out var effect) && CommonParsers.Spaces0(ref scanner, result, out _)) + else if (EffectParser.Effect(ref scanner, result, out var effect) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); - else if (ParamsParsers.Params(ref scanner, result, out var p) && CommonParsers.Spaces0(ref scanner, result, out _)) + else if (ParamsParsers.Params(ref scanner, result, out var p) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(p); else - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0039, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0039, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - ns.Info = scanner.GetLocation(position, scanner.Position - position); + ns.Info = scanner[position..scanner.Position]; parsed = ns; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool Namespace(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index f8726c7051..b066da368e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -35,11 +35,11 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult var position = scanner.Position; #warning We should not allow void to be a parameter, this is legacy C code if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) || ( - CommonParsers.FollowedBy(ref scanner, Terminals.Literal("void"), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true) + Parsers.FollowedBy(ref scanner, Tokens.Literal("void"), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) ) ) { @@ -48,12 +48,12 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult } else - if (CommonParsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) + if (Parsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) { parsed = parameters; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool MethodParameter(ref TScanner scanner, ParseResult result, out MethodParameter parsed, in ParseError? orError = null) @@ -61,28 +61,28 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if (Terminals.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) - CommonParsers.Spaces1(ref scanner, result, out _); - if (CommonParsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) + if (Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) + Parsers.Spaces1(ref scanner, result, out _); + if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) ) { typename.ArraySize = arraySize; if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Char(':'), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) + Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) ) { - parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage, semantic: semantic); + parsed = new(typename, identifier, scanner[position..scanner.Position], storage, semantic: semantic); return true; } else { - parsed = new(typename, identifier, scanner.GetLocation(position..scanner.Position), storage); + parsed = new(typename, identifier, scanner[position..scanner.Position], storage); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } } @@ -95,23 +95,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( LiteralsParser.TypeName(ref scanner, result, out var typename) - && CommonParsers.Spaces1(ref scanner, result, out _, new(SDSLParsingMessages.SDSL0016, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && Parsers.Spaces1(ref scanner, result, out _, new(SDSLErrorMessages.SDSL0016, scanner[scanner.Position], scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.MethodParameters, out List parameters, withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Block(ref scanner, result, out var body, new(SDSLParsingMessages.SDSL0040, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.MethodParameters, out List parameters, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && StatementParsers.Block(ref scanner, result, out var body, new(SDSLErrorMessages.SDSL0040, scanner[scanner.Position], scanner.Memory)) ) { - parsed = new ShaderMethod(typename, methodName, scanner.GetLocation(position, scanner.Position - position)) + parsed = new ShaderMethod(typename, methodName, scanner[position..scanner.Position]) { Parameters = parameters, Body = (BlockStatement)body }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -124,42 +124,42 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = null!; var position = scanner.Position; - var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && CommonParsers.Spaces0(ref scanner, result, out _); - var hasModifiers = CommonParsers.MethodModifiers(ref scanner, result, out var isStaged, out var isStatic, out var isClone, out var isOverride, out var isAbstract, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); + var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); + var hasModifiers = Parsers.MethodModifiers(ref scanner, result, out var isStaged, out var isStatic, out var isClone, out var isOverride, out var isAbstract, advance: true) && Parsers.Spaces0(ref scanner, result, out _); if (isAbstract) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + LiteralsParser.TypeName(ref scanner, result, out var typename, orError: new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var methodName, orError: new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { ShaderMethodParsers.MethodParameters(ref scanner, result, out var parameters); - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char(')', ref scanner, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char(')', ref scanner, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); - if (!Terminals.Char(';', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (!Tokens.Char(';', ref scanner, advance: true)) { if (orError != null) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[scanner.Position], scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } else { - parsed = new(typename, methodName, scanner.GetLocation(position..scanner.Position), isAbstract: true) + parsed = new(typename, methodName, scanner[position..scanner.Position], isAbstract: true) { Parameters = parameters }; return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } else if (isClone || isOverride || isStatic) @@ -171,16 +171,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed.IsClone = isClone; parsed.IsOverride = isOverride; parsed.IsStatic = isStatic; - parsed.Info = scanner.GetLocation(position..scanner.Position); + parsed.Info = scanner[position..scanner.Position]; return true; } } else if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { - parsed.Info = scanner.GetLocation(position..scanner.Position); + parsed.Info = scanner[position..scanner.Position]; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 34e217281a..ca4e5b0599 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -35,18 +35,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o do { if ( - CommonParsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var name) - && CommonParsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) { parameters.Add(new(typename, name)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } - while (!scanner.IsEof && Terminals.Char(',', ref scanner, advance: true)); - parsed = new(scanner.GetLocation(position..scanner.Position)) { Parameters = parameters }; + while (!scanner.IsEof && Tokens.Char(',', ref scanner, advance: true)); + parsed = new(scanner[position..scanner.Position]) { Parameters = parameters }; return true; } } @@ -58,18 +58,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o List values = []; do { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expr)) values.Add(expr); else if (LiteralsParser.StringLiteral(ref scanner, result, out var str)) values.Add(str); else break; - // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - while (!scanner.IsEof && CommonParsers.FollowedBy(ref scanner, Terminals.Char(','), advance: true)); + while (!scanner.IsEof && Parsers.FollowedBy(ref scanner, Tokens.Char(','), advance: true)); - parsed = new(scanner.GetLocation(position..scanner.Position)) + parsed = new(scanner[position..scanner.Position]) { Values = values }; @@ -84,21 +84,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter)) { - parsed = new(scanner.GetLocation(position..scanner.Position)); + parsed = new(scanner[position..scanner.Position]); parsed.Values.Add(parameter); - CommonParsers.Spaces0(ref scanner, result, out _); - while (Terminals.Char(',', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + while (Tokens.Char(',', ref scanner, advance: true)) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + Parsers.Spaces0(ref scanner, result, out _); + if (ParameterParsers.GenericsValue(ref scanner, result, out var other, new("Expecting at least one generics value", scanner[scanner.Position], scanner.Memory))) { parsed.Values.Add(other); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } } return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -117,9 +117,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = vector; return true; } - else if (PostfixParser.Accessor(ref scanner, result, out var accessor)) + else if (PostfixParser.Postfix(ref scanner, result, out var accessor)) { - if (accessor is AccessorExpression ae && ae.Accessed is Identifier) + if (accessor is AccessorChainExpression ae && ae.Source is Identifier) { parsed = accessor; return true; @@ -133,7 +133,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = identifier; return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 4846f10032..0a7cd6a421 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -11,23 +11,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if(ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributeList)) - CommonParsers.Spaces0(ref scanner, result, out _); - if (If(ref scanner, result, out var ifstatement, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) + Parsers.Spaces0(ref scanner, result, out _); + if (If(ref scanner, result, out var ifstatement, orError) && Parsers.Spaces0(ref scanner, result, out _)) { - parsed = new(ifstatement, scanner.GetLocation(..)) + parsed = new(ifstatement, scanner[..]) { Attributes = attributeList }; - while(ElseIf(ref scanner, result, out var elseif, orError) && CommonParsers.Spaces0(ref scanner, result, out _)) + while(ElseIf(ref scanner, result, out var elseif, orError) && Parsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; - parsed.Info = scanner.GetLocation(position..scanner.Position); + parsed.Info = scanner[position..scanner.Position]; return true; } - else if(Terminals.Literal("else ", ref scanner)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else if(Tokens.Literal("else ", ref scanner)) + return Parsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner[scanner.Position], scanner.Memory)); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) @@ -50,24 +50,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("if", ref scanner, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Literal("if", ref scanner, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(condition, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -78,27 +78,27 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("else", ref scanner, advance: true) - && CommonParsers.Spaces1(ref scanner, result, out _) - && Terminals.Literal("if", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char('(', ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + Tokens.Literal("else", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) + && Tokens.Literal("if", ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('(', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(condition, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(condition, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -109,15 +109,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("else", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) + Tokens.Literal("else", ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)) ) { - parsed = new(statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(statement, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 54e703e706..a38db15af6 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -10,7 +10,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && CommonParsers.Spaces0(ref scanner, result, out _); + var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && Parsers.Spaces0(ref scanner, result, out _); if (!hasAttributes) scanner.Position = position; if (While(ref scanner, result, out var w, orError)) @@ -32,7 +32,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = f; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) @@ -55,49 +55,49 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if( - Terminals.Literal("for", ref scanner, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char('('), withSpaces: true, advance: true) + Tokens.Literal("for", ref scanner, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) ) { Statement? init = null; Statement? condition = null; List? expressions = null; - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); // Parsing the initialization if(StatementParsers.Expression(ref scanner, result, out init)){} else if(StatementParsers.DeclareOrAssign(ref scanner, result, out init)){} else if(StatementParsers.Empty(ref scanner, result, out init)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0036, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0036, scanner[scanner.Position], scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (StatementParsers.Expression(ref scanner, result, out condition)){} else if (StatementParsers.Empty(ref scanner, result, out condition)){} - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0037, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); // parsing the final expression var tmpPos = scanner.Position; - if (!CommonParsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) - expressions = [new EmptyStatement(scanner.GetLocation(tmpPos..scanner.Position))]; - if(!CommonParsers.FollowedBy(ref scanner, Terminals.Char(')'), withSpaces: true, advance: true)) - return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); - CommonParsers.Spaces0(ref scanner, result, out _); + if (!Parsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) + expressions = [new EmptyStatement(scanner[tmpPos..scanner.Position])]; + if(!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); // parsing the block or statement if(StatementParsers.Statement(ref scanner, result, out var body)) { - parsed = new For(init, condition, expressions!, body, scanner.GetLocation(position..scanner.Position)); + parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) @@ -106,26 +106,26 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes var position = scanner.Position; if( PostfixParser.Postfix(ref scanner, result, out var variable) - && CommonParsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) - && CommonParsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) ) { - parsed = new Assign(scanner.GetLocation(position..scanner.Position)) + parsed = new Assign(scanner[position..scanner.Position]) { - Variables = [new(variable, false, scanner.GetLocation(position..scanner.Position), op, value)] + Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] }; return true; } scanner.Position = position; if( ExpressionParser.Expression(ref scanner, result, out var expression) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(')')) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')')) ) { - parsed = new ExpressionStatement(expression, scanner.GetLocation(position..scanner.Position)); + parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -135,41 +135,41 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("foreach", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Literal("foreach", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLParsingMessages.SDSL0017, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces1(ref scanner, result, out _) + LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces1(ref scanner, result, out _) + && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces1(ref scanner, result, out _) ) { - if (Terminals.Literal("in", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("in", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLParsingMessages.SDSL0032, scanner.GetErrorLocation(scanner.Position), scanner.Memory)) - && CommonParsers.Spaces0(ref scanner, result, out _) + ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(typeName, identifier, collection, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(typeName, identifier, collection, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -179,26 +179,26 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("while", ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Literal("while", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (Terminals.Char('(', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) { - if (Terminals.Char(')', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory))) + if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new(expression, statement, scanner.GetLocation(position..scanner.Position)); + parsed = new(expression, statement, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0018, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0035, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 28b696d9cf..c2650266bc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -31,13 +31,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; else if (Declare(ref scanner, result, out parsed)) return true; - else if (!Terminals.Char('{', ref scanner) && Expression(ref scanner, result, out parsed)) + else if (!Tokens.Char('{', ref scanner) && Expression(ref scanner, result, out parsed)) return true; - else if (!Terminals.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) + else if (!Tokens.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) return true; else if (Block(ref scanner, result, out parsed)) return true; - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } internal static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner @@ -56,14 +56,14 @@ internal static bool Discard(ref TScanner scanner, ParseResult result, { var position = scanner.Position; if ( - CommonParsers.FollowedBy(ref scanner, Terminals.Literal("discard"), withSpaces: true, advance: true) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, Tokens.Literal("discard"), withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new Discard(scanner.GetLocation(position..scanner.Position)); + parsed = new Discard(scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } internal static bool Return(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner @@ -88,7 +88,7 @@ internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult return true; else if (Declare(ref scanner, result, out parsed, orError)) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner @@ -98,7 +98,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; else if (Expression(ref scanner, result, out parsed, orError)) return true; - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -123,9 +123,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - if (Terminals.Char(';', ref scanner, advance: true)) + if (Tokens.Char(';', ref scanner, advance: true)) { - parsed = new EmptyStatement(scanner.GetLocation(position..scanner.Position)); + parsed = new EmptyStatement(scanner[position..scanner.Position]); return true; } return false; @@ -139,43 +139,42 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Literal("return;", ref scanner, advance: true)) + if (Tokens.Literal("return;", ref scanner, advance: true)) { - parsed = new Return(scanner.GetLocation(position..scanner.Position)); + parsed = new Return(scanner[position..scanner.Position]); return true; } else if ( - Terminals.Literal("return", ref scanner, advance: true) + Tokens.Literal("return", ref scanner, advance: true) ) { - if (CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), withSpaces: true, advance: true)) + if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new Return(scanner.GetLocation(position..scanner.Position)); + parsed = new Return(scanner[position..scanner.Position]); return true; } else if ( - PrimaryParsers.Parenthesis(ref scanner, result, out var p) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Parenthesis, out Expression p, advance : true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new Return(scanner.GetLocation(position, scanner.Position - position), p); + parsed = new Return(scanner[position..scanner.Position], p); return true; } else if ( - CommonParsers.Spaces1(ref scanner, result, out _) + Parsers.Spaces1(ref scanner, result, out _) && ExpressionParser.Expression(ref scanner, result, out var val) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(';', ref scanner, advance: true) ) { - parsed = new Return(scanner.GetLocation(position, scanner.Position - position), val); + parsed = new Return(scanner[position..scanner.Position], val); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0041, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0041, scanner[scanner.Position], scanner.Memory)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -186,15 +185,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("break", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + Tokens.Literal("break", ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(';', ref scanner, advance: true) ) { - parsed = new Break(scanner.GetLocation(position, scanner.Position - position)); + parsed = new Break(scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } public record struct ContinueParser : IParser @@ -204,15 +203,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; if ( - Terminals.Literal("continue", ref scanner, advance: true) - && CommonParsers.Spaces0(ref scanner, result, out _) - && Terminals.Char(';', ref scanner, advance: true) + Tokens.Literal("continue", ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(';', ref scanner, advance: true) ) { - parsed = new Break(scanner.GetLocation(position, scanner.Position - position)); + parsed = new Break(scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -224,13 +223,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( ExpressionParser.Expression(ref scanner, result, out var expression) - && CommonParsers.FollowedBy(ref scanner, Terminals.Char(';'), advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true) ) { - parsed = new ExpressionStatement(expression, scanner.GetLocation(position, scanner.Position - position)); + parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -243,24 +242,24 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Terminals.Char('{', ref scanner, advance: true) && CommonParsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('{', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { var block = new BlockStatement(new()); - while (!scanner.IsEof && !Terminals.Char('}', ref scanner, advance: true)) + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { if (StatementParsers.Statement(ref scanner, result, out var statement)) { block.Statements.Add(statement); - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0010, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)); } - block.Info = scanner.GetLocation(position, scanner.Position - position); + block.Info = scanner[position..scanner.Position]; parsed = block; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -274,30 +273,30 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (PostfixParser.Postfix(ref scanner, result, out var p)) { if ( - CommonParsers.FollowedBy( + Parsers.FollowedBy( ref scanner, result, - (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), + (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && Parsers.Spaces0(ref s, result, out _), out var op, withSpaces: true, advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(p, false, scanner.GetLocation(position..scanner.Position), op, expression); + parsed = new(p, false, scanner[position..scanner.Position], op, expression); return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)); } else { - parsed = new(p, false, scanner.GetLocation(position..scanner.Position)); + parsed = new(p, false, scanner[position..scanner.Position]); return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } } @@ -307,40 +306,41 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; - if (CommonParsers.IdentifierArraySizeOptionalValue(ref scanner, result, out var identifier, out var arraySizes, out var value, advance: true)) + if (Parsers.IdentifierArraySizeOptionalValue(ref scanner, result, out var identifier, out var arraySizes, out var value, advance: true)) { if ( - CommonParsers.FollowedBy( + Parsers.FollowedBy( ref scanner, result, - (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && CommonParsers.Spaces0(ref s, result, out _), + (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && Parsers.Spaces0(ref s, result, out _), out var op, withSpaces: true, advance: true) ) { - CommonParsers.Spaces0(ref scanner, result, out _); + Parsers.Spaces0(ref scanner, result, out _); if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position), op, expression) + parsed = new(identifier, false, scanner[position..scanner.Position], op, expression) { ArraySizes = arraySizes, Value = value }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0015, scanner.GetErrorLocation(position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)); } else { - parsed = new(identifier, false, scanner.GetLocation(position..scanner.Position)) + parsed = new(identifier, false, scanner[position..scanner.Position]) { - ArraySizes = arraySizes + ArraySizes = arraySizes, + Value = value }; return true; } } - else return CommonParsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } } @@ -353,36 +353,36 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; var isConst = - Terminals.Literal("const", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _) - || CommonParsers.SequenceOf(ref scanner, ["static", "const"], advance: true) && CommonParsers.Spaces0(ref scanner, result, out _); + Tokens.Literal("const", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _) + || Parsers.SequenceOf(ref scanner, ["static", "const"], advance: true) && Parsers.Spaces0(ref scanner, result, out _); if (!isConst) scanner.Position = position; if ( LiteralsParser.TypeName(ref scanner, result, out var typeName) - && CommonParsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) ) { - if (CommonParsers.Repeat(ref scanner, result, StatementParsers.DeclaredVarAssign, out List assigns, 1, true, ",")) + if (Parsers.Repeat(ref scanner, result, StatementParsers.DeclaredVarAssign, out List assigns, 1, true, ",")) { foreach (var a in assigns) { a.IsConst = isConst; a.ReplaceTypeName(typeName); } - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(';', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(';', ref scanner, advance: true)) { - parsed = new Declare(typeName, scanner.GetLocation(position..scanner.Position)) + parsed = new Declare(typeName, scanner[position..scanner.Position]) { Variables = assigns }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[scanner.Position], scanner.Memory)); } } - return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } @@ -392,19 +392,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (CommonParsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) + if (Parsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) { - CommonParsers.Spaces0(ref scanner, result, out _); - if (Terminals.Char(';', ref scanner, advance: true)) + Parsers.Spaces0(ref scanner, result, out _); + if (Tokens.Char(';', ref scanner, advance: true)) { - parsed = new Assign(scanner.GetLocation(position..scanner.Position)) + parsed = new Assign(scanner[position..scanner.Position]) { Variables = assigns }; return true; } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0033, scanner.GetErrorLocation(scanner.Position), scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[scanner.Position], scanner.Memory)); } - else return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs index dfcc8c8144..c5068fa940 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs +++ b/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -6,20 +6,20 @@ namespace Stride.Shaders.Parsing.SDSL; -public static class Terminals +public static class Tokens { public static bool AnyChar(ref TScanner scanner) where TScanner : struct, IScanner => !scanner.IsEof; - public static CharTerminalParser Char(char c) => new(c); + public static CharTokenParser Char(char c) => new(c); public static bool Char(char c, ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new CharTerminalParser(c).Match(ref scanner, advance); - public static SetTerminalParser Set(string set) => new(set); + => new CharTokenParser(c).Match(ref scanner, advance); + public static SetTokenParser Set(string set) => new(set); public static bool Set(string set, ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new SetTerminalParser(set).Match(ref scanner, advance); + => new SetTokenParser(set).Match(ref scanner, advance); public static bool Set(string set, ref TScanner scanner, out char chosen, bool advance = false) where TScanner : struct, IScanner @@ -33,43 +33,43 @@ public static bool Set(string set, ref TScanner scanner, out char chos } return false; } - public static LiteralTerminalParser Literal(string literal) => new(literal); + public static LiteralTokenParser Literal(string literal) => new(literal); public static bool Literal(string c, ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new LiteralTerminalParser(c).Match(ref scanner, advance); + => new LiteralTokenParser(c).Match(ref scanner, advance); public static bool AnyOf(ReadOnlySpan literals, ref TScanner scanner, out string matched, bool advance = false) where TScanner : struct, IScanner { matched = null!; foreach(var l in literals) - if(new LiteralTerminalParser(l).Match(ref scanner, advance)) + if(new LiteralTokenParser(l).Match(ref scanner, advance)) { matched = l; return true; } return false; } - public static DigitTerminalParser Digit(DigitRange? mode = null) => new(mode ?? DigitRange.All); + public static DigitTokenParser Digit(DigitRange? mode = null) => new(mode ?? DigitRange.All); public static bool Digit(ref TScanner scanner, DigitRange? mode = null, bool advance = false) where TScanner : struct, IScanner - => new DigitTerminalParser(mode ?? DigitRange.All).Match(ref scanner, advance); - public static LetterTerminalParser Letter() => new(); + => new DigitTokenParser(mode ?? DigitRange.All).Match(ref scanner, advance); + public static LetterTokenParser Letter() => new(); public static bool Letter(ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new LetterTerminalParser().Match(ref scanner, advance); - public static LetterOrDigitTerminalParser LetterOrDigit() => new(); + => new LetterTokenParser().Match(ref scanner, advance); + public static LetterOrDigitTokenParser LetterOrDigit() => new(); public static bool LetterOrDigit(ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new LetterOrDigitTerminalParser().Match(ref scanner, advance); + => new LetterOrDigitTokenParser().Match(ref scanner, advance); public static bool IdentifierFirstChar(ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner => Letter(ref scanner, advance) || Char('_', ref scanner, advance); public static bool EOL(ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner - => new EOLTerminalParser().Match(ref scanner, advance); + => new EOLTokenParser().Match(ref scanner, advance); public static bool EOF(ref TScanner scanner) where TScanner : struct, IScanner - => new EOFTerminalParser().Match(ref scanner, false); + => new EOFTokenParser().Match(ref scanner, false); @@ -109,13 +109,13 @@ public static bool IntSuffix(ref TScanner scanner, out Suffix? suffix, } } -public interface ITerminal +public interface IToken { public bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner; } -public record struct CharTerminalParser(char Character) : ITerminal +public record struct CharTokenParser(char Character) : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -128,7 +128,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) } return false; } - public static implicit operator CharTerminalParser(char c) => new(c); + public static implicit operator CharTokenParser(char c) => new(c); } public struct DigitRange @@ -160,7 +160,7 @@ public DigitRange(string chars) public static implicit operator DigitRange(string numbers) => new(numbers); } -public record struct DigitTerminalParser(DigitRange Mode) : ITerminal +public record struct DigitTokenParser(DigitRange Mode) : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -174,7 +174,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) } } -public record struct LetterTerminalParser() : ITerminal +public record struct LetterTokenParser() : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -188,7 +188,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) return false; } } -public record struct LetterOrDigitTerminalParser() : ITerminal +public record struct LetterOrDigitTokenParser() : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -203,7 +203,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) } } -public record struct LiteralTerminalParser(string Literal, bool CaseSensitive = true) : ITerminal +public record struct LiteralTokenParser(string Literal, bool CaseSensitive = true) : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -216,11 +216,11 @@ public readonly bool Match(ref TScanner scanner, bool advance) } return false; } - public static implicit operator LiteralTerminalParser(string lit) => new(lit); + public static implicit operator LiteralTokenParser(string lit) => new(lit); } -public record struct SetTerminalParser(string Set) : ITerminal +public record struct SetTokenParser(string Set) : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -234,10 +234,10 @@ public readonly bool Match(ref TScanner scanner, bool advance) return false; } - public static implicit operator SetTerminalParser(string set) => new(set); + public static implicit operator SetTokenParser(string set) => new(set); } -public record struct EOFTerminalParser() : ITerminal +public record struct EOFTokenParser() : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -245,7 +245,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) return scanner.IsEof; } } -public record struct EOLTerminalParser() : ITerminal +public record struct EOLTokenParser() : IToken { public readonly bool Match(ref TScanner scanner, bool advance) where TScanner : struct, IScanner @@ -253,7 +253,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) var position = scanner.Position; while (scanner.Peek() == ' ') scanner.Advance(1); - var result = Terminals.Char('\n', ref scanner, advance) || Terminals.Literal("\r\n", ref scanner, advance); + var result = Tokens.Char('\n', ref scanner, advance) || Tokens.Literal("\r\n", ref scanner, advance); if (!advance && result) scanner.Position = position; return result; diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders.Parsing/SDSLERR.cs index 71bec24fff..c7dd1e41b5 100644 --- a/src/Stride.Shaders.Parsing/SDSLERR.cs +++ b/src/Stride.Shaders.Parsing/SDSLERR.cs @@ -1,7 +1,7 @@ namespace Stride.Shaders.Parsing; -public static class SDSLParsingMessages +public static class SDSLErrorMessages { public const string SDSL0001 = "SDSL0001: Unexpected token"; public const string SDSL0002 = "SDSL0002: vector size not supported"; @@ -47,4 +47,15 @@ public static class SDSLParsingMessages public const string SDSL0042 = "SDSL0042: Expected prefix expression"; public const string SDSL0043 = "SDSL0043: Unexpected "; public const string SDSL0044 = "SDSL0044: Use of register and packoffset keyword deprecated"; + + + // Semantic errors + + public const string SDSL0100 = "SDSL0100: Variable is not declared"; + public const string SDSL0101 = "SDSL0101: Variable is already declared"; + public const string SDSL0102 = "SDSL0102: Variable is not a constant"; + public const string SDSL0103 = "SDSL0103: Variable cannot be assigned to"; + public const string SDSL0104 = "SDSL0104: Cannot infer type"; + public const string SDSL0105 = "SDSL0105: Unrecognized node"; + public const string SDSL0106 = "SDSL0106: Unsupported type"; } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs index 17ce4a6abe..c7e0ff95c5 100644 --- a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs +++ b/src/Stride.Shaders.Parsing/Scanners/IScanner.cs @@ -17,6 +17,9 @@ public interface IScanner public int Line { get; } public int Column { get; } + public TextLocation this[Range range] { get; } + public ErrorLocation this[int position] { get; } + public int End { get; } @@ -34,10 +37,6 @@ public interface IScanner public ReadOnlySpan Slice(int index, int length); public int LineAtIndex(int index); - - public TextLocation GetLocation(int position, int length); - public TextLocation GetLocation(Range range); - public ErrorLocation GetErrorLocation(int position); } diff --git a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs index 532c3b574a..1b51df4d36 100644 --- a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs +++ b/src/Stride.Shaders.Parsing/Scanners/Scanner.cs @@ -21,6 +21,9 @@ public struct Scanner(string code) : IScanner public readonly int End => Span.Length; public readonly bool IsEof => Position >= End; + public readonly TextLocation this[Range range] => new(Memory, range); + public readonly ErrorLocation this[int position] => new(this, position); + public int ReadChar() { var pos = Position; @@ -103,19 +106,6 @@ public readonly int LineAtIndex(int index) return lineCount + 1; } - public readonly TextLocation GetLocation(int position, int length) - { - return new(Memory, new(position, position + length)); - } - public readonly ErrorLocation GetErrorLocation(int position) - { - return new ErrorLocation(this, position); - } - - public readonly TextLocation GetLocation(Range range) - { - return new(Memory, range); - } } diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs index e1c4f0681f..066ee2eb85 100644 --- a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs +++ b/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs @@ -19,6 +19,10 @@ public struct Scanner(T code) : IScanner public readonly int End => Span.Length; public readonly bool IsEof => Position >= End; + public readonly TextLocation this[Range range] => new(Memory, range); + public readonly ErrorLocation this[int position] => new(new Scanner(Memory.ToString()), position); + + public int ReadChar() { var pos = Position; diff --git a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs index f7897c252b..3ecaab3f96 100644 --- a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs +++ b/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs @@ -10,6 +10,9 @@ public record struct TextLocation(ReadOnlyMemory Original, Range Range) public readonly int Line => Original.Span[..Range.StartsAt(Original.Length)].Count('\n') + 1; public readonly int Column => Range.StartsAt(Original.Length) - Original.Span[..Range.StartsAt(Original.Length)].LastIndexOf('\n'); + + public readonly int EndLine => Original.Span[..Range.EndsAt(Original.Length)].Count('\n') + 1; + public readonly int EndColumn => Range.EndsAt(Original.Length) - Original.Span[..Range.EndsAt(Original.Length)].LastIndexOf('\n'); public readonly override string ToString() { return $"[l{Line}-c{Column}]\n{Text.Span}"; diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj index b1241fa643..1d4a6a9e33 100644 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj @@ -13,5 +13,6 @@ + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs new file mode 100644 index 0000000000000000000000000000000000000000..94098c527fbe77165133a794291e795b325da829 GIT binary patch literal 1076 zcmb`GPfNrw5XIkF@H^zF7e9dFrGg-c7X{C;UDx8;F8!m(vR_^OWnyUywXTbVv@esH zHuzHd=T;UVeYxXL=f-h8pf>)wekBkNDT4y@cfz5*0 z7pyf=UMXmI{+?wG`-4{GO^Ns5+G-4p4VIKWkF5qLhJt5;wdDV7m2B+m@Cakf7}>h> z-@p)RcG@tPpoSAU*gLeH;kq|XvXLTAS7;lvv{rMDSFp_Ga5`tdAnTisbo{Mq%-!ib zKF3gp(3^t3 + From 0212da206d34c0d42e64ac6cfd6d41b05c190348 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Wed, 26 Mar 2025 14:21:33 +0100 Subject: [PATCH 0374/1182] Bridging the parser and the compiler together (#19) More semantic rules, more documentation, refactoring/streamlining of the project structure, LLVM inspired IR generator, first basic example working --- .devcontainer/devcontainer.json | 22 + .gitignore | 3 +- .gitmodules | 3 + Readme.md | 8 +- SDSL.sln | 136 +--- assets/SDSL/Test.sdsl | 32 +- assets/SDSL/TestBasic.sdsl | 9 + assets/SDSL/TestVertex.sdsl | 11 + .../.avalonia-build-tasks/id | 1 + src/Stride.Shaders.Compilers/DXC.cs | 72 -- src/Stride.Shaders.Compilers/Direct3D/DXC.cs | 75 ++ src/Stride.Shaders.Compilers/Direct3D/FXC.cs | 18 + src/Stride.Shaders.Compilers/FXC.cs | 40 - src/Stride.Shaders.Compilers/ICompiler.cs | 7 + src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 34 + src/Stride.Shaders.Compilers/SDSLC.cs | 4 - src/Stride.Shaders.Compilers/SpirvOpt.cs | 1 + .../Stride.Shaders.Compilers.csproj | 3 +- .../Stride.Shaders.Core.csproj | 14 - src/Stride.Shaders.Core/Symbol.cs | 22 - .../SymbolTypes.Globals.cs | 72 -- src/Stride.Shaders.Core/SymbolTypes.cs | 144 ---- .../Examples.Spirv.cs | 202 +++++ .../Examples.cs | 37 +- src/Stride.Shaders.Experiments/Program.cs | 9 + .../Stride.Shaders.Experiments.csproj} | 0 src/Stride.Shaders.LSP.Test/Program.cs | 2 - .../Stride.Shaders.LSP.Test.csproj | 14 - .../Stride.Shaders.LSP.csproj | 2 +- .../Program.cs | 16 - .../Analysis/OperatorTable.cs | 79 -- .../Analysis/SymbolTable.ConstExpr.cs | 73 -- .../Analysis/SymbolTable.cs | 45 -- src/Stride.Shaders.Parsing/IParser.cs | 12 - .../SDSL/AST/Expression.cs | 112 --- .../SDSL/AST/Literals.cs | 238 ------ .../SDSL/AST/Statements.Control.cs | 62 -- .../SDSL/AST/Statements.Flow.cs | 60 -- .../Stride.Shaders.Parsing.csproj | 18 - .../Buffers/IMutSpirvBuffer.cs | 11 +- .../Buffers/ISpirvBuffer.cs | 65 ++ .../Buffers/SpirvBuffer.cs | 166 ++++ .../Buffers/SpirvMemory.cs | 57 ++ .../Buffers/SpirvSpan.cs | 45 ++ .../ISpirvElement.cs | 25 +- .../Information/InstructionInfo.Order.cs | 100 ++- .../Information/InstructionInfo.cs | 11 +- .../Information/LogicalOperand.Size.cs | 0 .../Information/LogicalOperand.cs | 3 + .../Information/LogicalOperandArray.cs | 26 +- .../Literals/IFromSpirv.cs | 4 + .../Literals/ILiteralNumber.cs | 3 + .../Literals/IdMemorySemantics.cs | 0 .../Literals/IdRef.cs | 2 + .../Literals/IdResult.cs | 0 .../Literals/IdResultType.cs | 0 .../Literals/IdScope.cs | 0 .../Literals/LiteralFloat.cs | 6 +- .../Literals/LiteralInteger.cs | 0 .../Literals/LiteralString.cs | 4 +- .../Literals/PairIdRefIdRef.cs | 0 .../Literals/PairIdRefLiteralInteger.cs | 0 .../Literals/PairLiteralIntegerIdRef.cs | 0 .../Literals/SpvOp.cs | 0 .../MemoryInstruction.cs | 5 +- .../OperandQuantifier.cs | 0 .../Parsing/InstructionEnumerator.cs | 32 +- .../Parsing/OperandEnumerator.cs | 0 .../Parsing/OrderedEnumerator.cs | 67 +- .../Parsing/RefHeader.cs | 13 +- .../Parsing/RefInstructionEnumerator.cs | 44 + .../Parsing/SpirvHeader.cs | 4 +- .../Parsing/SpirvReader.cs | 24 +- .../Parsing/SpirvWriter.cs | 0 .../RefInstruction.cs | 58 +- .../Stride.Shaders.Spirv.Core/SpvLiteral.cs | 0 .../Stride.Shaders.Spirv.Core.csproj | 4 +- src/Stride.Shaders.Spirv.Generators/Data.cs | 55 ++ .../Extensions/spirv.sdsl.grammar-ext.json | 0 .../SPVGenerator.Extensions.cs | 0 .../SPVGenerator.Info.cs | 160 ++++ .../SPVGenerator.Naming.cs | 189 +++++ .../SPVGenerator.SDSLOp.cs | 58 ++ .../SPVGenerator.cs | 340 ++++++++ .../Stride.Shaders.Spirv.Generators.csproj | 54 ++ ...re.Benchmarks.ParserBench-report-github.md | 16 - ...irv.Core.Benchmarks.ParserBench-report.csv | 5 - ...rv.Core.Benchmarks.ParserBench-report.html | 33 - .../ParserBench.cs | 55 -- .../Program.cs | 10 - ...tride.Shaders.Spirv.Core.Benchmarks.csproj | 18 - .../Stride.Shaders.Spirv.Core/Bound.cs | 28 - .../Buffers/BufferBase.cs | 32 - .../Buffers/ExpandableBuffer.cs | 89 -- .../Buffers/ISpirvBuffer.cs | 19 - .../Buffers/Multi/FunctionBufferCollection.cs | 116 --- .../Multi/MultiBuffer.LocalVariables.cs | 58 -- .../Buffers/Multi/MultiBuffer.Variables.cs | 45 -- .../Buffers/Multi/MultiBuffer.cs | 214 ----- .../Buffers/Single/UnsortedWordBuffer.cs | 56 -- .../Buffers/Single/WordBuffer.Parse.cs | 25 - .../Buffers/Single/WordBuffer.cs | 211 ----- .../Buffers/SortedFunctionBufferCollection.cs | 92 --- .../Buffers/SortedWordBuffer.cs | 74 -- .../Buffers/SpirvBuffer.cs | 111 --- .../Buffers/SpirvMemory.cs | 32 - .../Buffers/SpirvSpan.cs | 60 -- .../Disassembly/DisWriter.cs | 97 --- .../Disassembly/Disassembler.cs | 237 ------ .../MutRefInstruction.cs | 77 -- .../Parsing/FilteredEnumerator.cs | 144 ---- .../Parsing/InstructionFinder.cs | 42 - .../Parsing/LambdaFilteredEnumerator.cs | 43 - .../Parsing/RefInstructions.cs | 66 -- .../Validation/ValidationPass.cs | 7 - .../Validation/Validator.cs | 12 - .../Program.cs | 174 ---- .../SPVGenerator.Info.cs | 162 ---- .../SPVGenerator.Naming.cs | 193 ----- .../SPVGenerator.SDSLOp.cs | 60 -- .../SPVGenerator.cs | 237 ------ .../Stride.Shaders.Spirv.Generators.csproj | 42 - .../Stride.Shaders.Spirv/CFG/BasicBlock.cs | Bin 1076 -> 0 bytes .../Stride.Shaders.Spirv/Composable.cs | 14 - .../CompositionSourceProvider.cs | 33 - .../MixinFilteredInstructionEnumerator.cs | 67 -- .../Enumerators/MixinInstructionEnumerator.cs | 63 -- .../SortedMixinInstructionEnumerator.cs | 73 -- .../Mixer/Generating-CFG.md | 86 -- .../Mixer/Mixer.BaseTypes.cs | 273 ------- .../Mixer/Mixer.Fluent.Compose.cs | 42 - .../Mixer/Mixer.Fluent.EntryPoint.cs | 44 - .../Mixer/Mixer.Fluent.Inherit.cs | 26 - .../Mixer.FunctionBuilder.CallFunction.cs | 757 ------------------ .../Mixer.FunctionBuilder.Conditionals.cs | 50 -- .../Mixer/Mixer.FunctionBuilder.Glsl.cs | 447 ----------- .../Mixer/Mixer.FunctionBuilder.Util.cs | 354 -------- .../Mixer/Mixer.FunctionBuilder.cs | 194 ----- .../Stride.Shaders.Spirv/Mixer/Mixer.IO.cs | 55 -- .../Stride.Shaders.Spirv/Mixer/Mixer.cs | 249 ------ .../Stride.Shaders.Spirv/Mixer/MixerBase.cs | 35 - .../Mixin/FullMixinInstructions.cs | 55 -- .../Stride.Shaders.Spirv/Mixin/Mixin.cs | 61 -- .../Mixin/MixinInstruction.cs | 29 - .../Mixin/MixinInstructions.cs | 30 - .../Mixin/MixinParents.cs | 105 --- .../Stride.Shaders.Spirv/MixinBuffer.cs | 119 --- .../Stride.Shaders.Spirv/MixinCollection.cs | 93 --- .../Stride.Shaders.Spirv/MixinGraph.cs | 92 --- .../MixinSourceProvider.cs | 37 - .../Processing/BoundReducer.cs | 127 --- .../Processing/CapabilitiesCompute.cs | 62 -- .../Processing/CompressBuffer.cs | 30 - .../Processing/FunctionVariableOrderer.cs | 57 -- .../Processing/IOReplace.cs | 74 -- .../Processing/IOVariableDecorator.cs | 505 ------------ .../Processing/IdRefOffsetter.cs | 41 - .../MemoryModelDuplicatesRemover.cs | 42 - .../Processing/MixinMerger.cs | 36 - .../Processing/PostProcessor.cs | 48 -- .../Processing/SDSLOpRemover.cs | 46 -- .../Processing/TypeDuplicatesRemover.cs | 206 ----- .../Stride.Shaders.Spirv.csproj | 18 - .../ParsingTests.cs | 0 .../Stride.Shaders.Parsing.Tests.csproj | 2 +- .../Core/AssignOperators.cs} | 2 +- src/Stride.Shaders/Core/EntryPoints.cs | 29 + .../Core/Operators.cs} | 2 +- src/Stride.Shaders/Core/StreamUsage.cs | 18 + src/Stride.Shaders/Core/Symbol.cs | 53 ++ .../Core}/SymbolFrame.cs | 24 +- .../Core}/SymbolProvider.cs | 2 +- .../Core/SymbolTypes.Globals.cs | 72 ++ src/Stride.Shaders/Core/SymbolTypes.cs | 157 ++++ .../Parsing}/ASTNode.cs | 27 +- src/Stride.Shaders/Parsing/Analysis/CFG.cs | 13 + .../Parsing/Analysis/IStreamChecker.cs | 8 + .../Parsing/Analysis/OperatorTable.cs | 72 ++ src/Stride.Shaders/Parsing/Analysis/ReadMe.md | 20 + .../Parsing}/Analysis/SDIR.cs | 12 +- .../Parsing/Analysis/SymbolTable.cs | 51 ++ .../Parsing}/Analysis/TypeNameExtensions.cs | 2 +- .../Parsing}/Grammar.cs | 3 + src/Stride.Shaders/Parsing/IParser.cs | 28 + .../Parsing}/ParseResult.cs | 15 +- .../PreProcessing/CMacros/CodeFrame.cs | 0 .../CMacros/CodeFrameSnippets.cs | 0 .../PreProcessing/CMacros/CodeProcessor.cs | 0 .../PreProcessing/CMacros/CommentPhase.cs | 0 .../CMacros/IPreProcessorPhase.cs | 0 .../CMacros/LocationTranslator.cs | 0 .../PreProcessing/CommentProcessedCode.cs | 0 .../PreProcessing/MacroPreProcessor.cs | 0 .../PreProcessing/MemoryOwnerExtensions.cs | 0 .../Parsing}/PreProcessing/TextLink.cs | 0 .../PreProcessing/TextLinkExtensions.cs | 0 .../Parsing}/SDFX/AST/Effect.Flow.cs | 0 .../Parsing}/SDFX/AST/Effect.Parameters.cs | 0 .../Parsing}/SDFX/AST/Effect.cs | 1 + .../SDFX/Parsers/EffectFileParsers.cs | 0 .../Parsing}/SDFX/Parsers/EffectParser.cs | 0 .../EffectStatementParsers.Conditional.cs | 0 .../Parsers/EffectStatementParsers.Flow.cs | 0 .../SDFX/Parsers/EffectStatementParsers.cs | 4 +- .../Parsing}/SDFX/Parsers/ParamsParsers.cs | 0 .../Parsing/SDSL/AST/AssignOperator.cs | 76 ++ .../Parsing}/SDSL/AST/Directives.cs | 0 .../Parsing/SDSL/AST/Expression.cs | 228 ++++++ .../Parsing/SDSL/AST/Literals.cs | 351 ++++++++ .../Parsing/SDSL/AST/Operator.cs | 153 ++++ .../Parsing}/SDSL/AST/Shader.cs | 56 +- .../Parsing}/SDSL/AST/ShaderAttributes.cs | 0 .../SDSL/AST/ShaderElements.MethodOrMember.cs | 61 +- .../Parsing}/SDSL/AST/ShaderElements.cs | 24 +- .../Parsing}/SDSL/AST/ShaderGenericsValues.cs | 0 .../Parsing/SDSL/AST/Statements.Control.cs | 96 +++ .../Parsing/SDSL/AST/Statements.Flow.cs | 119 +++ .../Parsing}/SDSL/AST/Statements.cs | 148 ++-- .../Parsing}/SDSL/AST/SymbolTypeProcess.cs | 14 +- .../SDSL/Parsers/Common/CommonParsers.cs | 11 +- .../Parsing}/SDSL/Parsers/Common/Delegates.cs | 0 .../SDSL/Parsers/Common/OptionalParser.cs | 0 .../Parsing}/SDSL/Parsers/Common/Spaces.cs | 0 .../DirectiveBinaryParsers.cs | 1 + .../DirectiveExpressions/DirectiveParsers.cs | 0 .../DirectivePrimaryExpressionParsers.cs | 0 .../DirectiveUnaryParsers.Prefix.cs | 1 + .../DirectiveUnaryParsers.cs | 0 .../ExpressionParsers/BinaryParsers.cs | 46 +- .../PrimaryExpressionParsers.cs | 0 .../ExpressionParsers/UnaryParsers.Postfix.cs | 1 + .../ExpressionParsers/UnaryParsers.Prefix.cs | 1 + .../Parsers/LiteralParsers/LiteralParsers.cs | 1 + .../Parsers/LiteralParsers/NumberParsers.cs | 0 .../SDSL/Parsers/LiteralParsers/Reserved.cs | 0 .../ShaderParsers/CompositionParsers.cs | 0 .../ShaderParsers/ShaderAttributeParsers.cs | 0 .../ShaderParsers/ShaderBufferParsers.Cs | 4 +- .../ShaderParsers/ShaderClassParser.cs | 0 .../ShaderParsers/ShaderDataParsers.cs | 10 +- .../ShaderParsers/ShaderElementParsers.cs | 5 +- .../ShaderParsers/ShaderFileParsers.cs | 0 .../ShaderParsers/ShaderMethodParsers.cs | 7 +- .../Parsers/ShaderParsers/ShaderParameters.cs | 0 .../StatementParsers.Control.cs | 0 .../StatementParsers/StatementParsers.Flow.cs | 1 + .../StatementParsers/StatementParsers.cs | 1 + .../SDSL/Parsers/Terminals/Terminals.cs | 0 .../Parsing}/SDSLERR.cs | 4 +- .../Parsing}/SDSLParser.cs | 4 +- .../Parsing}/Scanners/ErrorLocation.cs | 0 .../Parsing}/Scanners/IScannableCode.cs | 0 .../Parsing}/Scanners/IScanner.cs | 0 .../Parsing}/Scanners/ScannableString.cs | 0 .../Parsing}/Scanners/Scanner.cs | 0 .../Parsing}/Scanners/ScannerGeneric.cs | 0 .../Parsing}/Scanners/TextLocation.cs | 0 .../Spirv/Building/BasicBlocks.cs | Bin 0 -> 4490 bytes .../Spirv/Building/Builder.Expressions.cs | 234 ++++++ .../Spirv/Building/Builder.Flow.cs | 37 + .../Spirv/Building/Builder.Functions.cs | 45 ++ src/Stride.Shaders/Spirv/Building/Builder.cs | 66 ++ .../Spirv/Building/CompilerUnit.cs | 30 + src/Stride.Shaders/Spirv/Building/Context.cs | 166 ++++ .../Spirv/Building/DictionaryPool.cs | 0 src/Stride.Shaders/Spirv/Building/Module.cs | 8 + .../Spirv/Processing/BoundReducer.cs | 127 +++ .../Spirv/Processing/CapabilitiesCompute.cs | 62 ++ .../Spirv/Processing/CompressBuffer.cs | 30 + .../Processing/FunctionVariableOrderer.cs | 57 ++ .../Spirv}/Processing/INanoPass.cs | 2 +- .../Spirv/Processing/IOReplace.cs | 74 ++ .../Spirv/Processing/IOVariableDecorator.cs | 505 ++++++++++++ .../Processing/IPostProcessorSubPass.cs | 0 .../Spirv/Processing/IdRefOffsetter.cs | 41 + .../MemoryModelDuplicatesRemover.cs | 42 + .../Spirv/Processing/MixinMerger.cs | 36 + .../Spirv/Processing/PostProcessor.cs | 48 ++ .../Spirv/Processing/SDSLOpRemover.cs | 46 ++ .../Spirv/Processing/TypeDuplicatesRemover.cs | 206 +++++ .../Spirv/Storage/MixinStorage.cs | 39 + .../Spirv/Tools/SpirvDis.Appends.cs | 272 +++++++ .../Spirv/Tools/SpirvDis.Writer.cs | 58 ++ src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 147 ++++ src/Stride.Shaders/Spirv/Tools/Validator.cs | 8 + .../Spirv}/thinking.md | 0 .../Stride.Shaders.csproj} | 4 +- submodules/SpirvHeaders | 2 +- submodules/SpirvRegistry | 1 + 289 files changed, 6185 insertions(+), 9363 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 assets/SDSL/TestBasic.sdsl create mode 100644 assets/SDSL/TestVertex.sdsl create mode 100644 src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id delete mode 100644 src/Stride.Shaders.Compilers/DXC.cs create mode 100644 src/Stride.Shaders.Compilers/Direct3D/DXC.cs create mode 100644 src/Stride.Shaders.Compilers/Direct3D/FXC.cs delete mode 100644 src/Stride.Shaders.Compilers/FXC.cs create mode 100644 src/Stride.Shaders.Compilers/ICompiler.cs create mode 100644 src/Stride.Shaders.Compilers/SDSL/SDSLC.cs delete mode 100644 src/Stride.Shaders.Compilers/SDSLC.cs delete mode 100644 src/Stride.Shaders.Core/Stride.Shaders.Core.csproj delete mode 100644 src/Stride.Shaders.Core/Symbol.cs delete mode 100644 src/Stride.Shaders.Core/SymbolTypes.Globals.cs delete mode 100644 src/Stride.Shaders.Core/SymbolTypes.cs create mode 100644 src/Stride.Shaders.Experiments/Examples.Spirv.cs rename src/{Stride.Shaders.Parsing.Experiments => Stride.Shaders.Experiments}/Examples.cs (88%) create mode 100644 src/Stride.Shaders.Experiments/Program.cs rename src/{Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj => Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj} (100%) delete mode 100644 src/Stride.Shaders.LSP.Test/Program.cs delete mode 100644 src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj delete mode 100644 src/Stride.Shaders.Parsing.Experiments/Program.cs delete mode 100644 src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs delete mode 100644 src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs delete mode 100644 src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs delete mode 100644 src/Stride.Shaders.Parsing/IParser.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs delete mode 100644 src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs delete mode 100644 src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs (82%) create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/ISpirvElement.cs (89%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs (54%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs (75%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs (92%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs (76%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs (73%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs (80%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IdRef.cs (84%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IdResult.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/IdScope.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs (98%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs (97%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/MemoryInstruction.cs (89%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/OperandQuantifier.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs (55%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs (55%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs (75%) create mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs (97%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs (76%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/RefInstruction.cs (68%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/SpvLiteral.cs (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj (80%) create mode 100644 src/Stride.Shaders.Spirv.Generators/Data.cs rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json (100%) rename src/{Stride.Shaders.Spirv => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs (100%) create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Composable.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs delete mode 100644 src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj rename src/{Stride.Shaders.Parsing.Tests => Stride.Shaders.Tests}/ParsingTests.cs (100%) rename src/{Stride.Shaders.Parsing.Tests => Stride.Shaders.Tests}/Stride.Shaders.Parsing.Tests.csproj (90%) rename src/{Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs => Stride.Shaders/Core/AssignOperators.cs} (98%) create mode 100644 src/Stride.Shaders/Core/EntryPoints.cs rename src/{Stride.Shaders.Parsing/SDSL/AST/Operator.cs => Stride.Shaders/Core/Operators.cs} (99%) create mode 100644 src/Stride.Shaders/Core/StreamUsage.cs create mode 100644 src/Stride.Shaders/Core/Symbol.cs rename src/{Stride.Shaders.Core => Stride.Shaders/Core}/SymbolFrame.cs (58%) rename src/{Stride.Shaders.Core => Stride.Shaders/Core}/SymbolProvider.cs (74%) create mode 100644 src/Stride.Shaders/Core/SymbolTypes.Globals.cs create mode 100644 src/Stride.Shaders/Core/SymbolTypes.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/ASTNode.cs (80%) create mode 100644 src/Stride.Shaders/Parsing/Analysis/CFG.cs create mode 100644 src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs create mode 100644 src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs create mode 100644 src/Stride.Shaders/Parsing/Analysis/ReadMe.md rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Analysis/SDIR.cs (60%) create mode 100644 src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Analysis/TypeNameExtensions.cs (90%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Grammar.cs (96%) create mode 100644 src/Stride.Shaders/Parsing/IParser.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/ParseResult.cs (83%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/CodeFrame.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/CodeFrameSnippets.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/CodeProcessor.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/CommentPhase.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/IPreProcessorPhase.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CMacros/LocationTranslator.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/CommentProcessedCode.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/MacroPreProcessor.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/MemoryOwnerExtensions.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/TextLink.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/PreProcessing/TextLinkExtensions.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/AST/Effect.Flow.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/AST/Effect.Parameters.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/AST/Effect.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/EffectFileParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/EffectParser.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/EffectStatementParsers.Conditional.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/EffectStatementParsers.Flow.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/EffectStatementParsers.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDFX/Parsers/ParamsParsers.cs (100%) create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/Directives.cs (100%) create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/Shader.cs (58%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/ShaderAttributes.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/ShaderElements.MethodOrMember.cs (72%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/ShaderElements.cs (87%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/ShaderGenericsValues.cs (100%) create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/Statements.cs (52%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/AST/SymbolTypeProcess.cs (76%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/Common/CommonParsers.cs (98%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/Common/Delegates.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/Common/OptionalParser.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/Common/Spaces.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs (92%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/LiteralParsers/LiteralParsers.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/LiteralParsers/NumberParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/LiteralParsers/Reserved.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/CompositionParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs (96%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs (95%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs (96%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs (96%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/ShaderParsers/ShaderParameters.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/StatementParsers/StatementParsers.cs (99%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSL/Parsers/Terminals/Terminals.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSLERR.cs (98%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/SDSLParser.cs (81%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/ErrorLocation.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/IScannableCode.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/IScanner.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/ScannableString.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/Scanner.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/ScannerGeneric.cs (100%) rename src/{Stride.Shaders.Parsing => Stride.Shaders/Parsing}/Scanners/TextLocation.cs (100%) create mode 100644 src/Stride.Shaders/Spirv/Building/BasicBlocks.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.Flow.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.Functions.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.cs create mode 100644 src/Stride.Shaders/Spirv/Building/CompilerUnit.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Context.cs create mode 100644 src/Stride.Shaders/Spirv/Building/DictionaryPool.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Module.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/BoundReducer.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs rename src/{Stride.Shaders.Spirv/Stride.Shaders.Spirv => Stride.Shaders/Spirv}/Processing/INanoPass.cs (90%) create mode 100644 src/Stride.Shaders/Spirv/Processing/IOReplace.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs rename src/{Stride.Shaders.Spirv/Stride.Shaders.Spirv => Stride.Shaders/Spirv}/Processing/IPostProcessorSubPass.cs (100%) create mode 100644 src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/MixinMerger.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/PostProcessor.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs create mode 100644 src/Stride.Shaders/Spirv/Storage/MixinStorage.cs create mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs create mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs create mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.cs create mode 100644 src/Stride.Shaders/Spirv/Tools/Validator.cs rename src/{Stride.Shaders.Spirv/Stride.Shaders.Spirv => Stride.Shaders/Spirv}/thinking.md (100%) rename src/{Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj => Stride.Shaders/Stride.Shaders.csproj} (72%) create mode 160000 submodules/SpirvRegistry diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..a221530520 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +{ + "name": ".NET 9 dev container", + "image": "mcr.microsoft.com/dotnet/sdk:9.0", + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit", + "ms-dotnettools.vscodeintellicode-csharp", + "ms-vscode.vscode-node-azure-pack", + "Ionide.Ionide-fsharp" + ], + "settings": { + "terminal.integrated.shell.linux": "/usr/bin/pwsh" + } + } + }, + "features": { + "ghcr.io/devcontainers/features/powershell:1": {} + }, + "postStartCommand": "git submodule update --init" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index e597410b83..513eb1daa5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ obj/ .antlr/ /src/SDSLParserExample/Properties/launchSettings.json log*.txt -*.vsix \ No newline at end of file +*.vsix +*.fsx \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index d3cf9c426d..6b8d134039 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "submodules/CppNet8"] path = submodules/CppNet8 url = https://github.com/ykafia/CppNet/ +[submodule "submodules/SpirvRegistry"] + path = submodules/SpirvRegistry + url = https://github.com/KhronosGroup/Registry-Root-SPIR-V diff --git a/Readme.md b/Readme.md index 8a82c4fec8..211bd5e490 100644 --- a/Readme.md +++ b/Readme.md @@ -19,4 +19,10 @@ SDSL is a superset of the HLSL Shading language, bringing advanced and higher le ## Contribute -You can fork the repository, clone it with submodules and create PRs. \ No newline at end of file +To contribute to this project, start by cloning this repository and pulling submodules : + +```bash +git clone https://github.com/Stride3D/SDSL +cd ./SDSL +git submodule update --init +``` \ No newline at end of file diff --git a/SDSL.sln b/SDSL.sln index ce5a63e6e4..3ee7007f06 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -3,37 +3,21 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F15E41A8-FD75-462B-9BB0-DCE18A6AD334}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9B25B78A-8418-4161-99D6-5E84611BDA59}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing", "src\Stride.Shaders.Parsing\Stride.Shaders.Parsing.csproj", "{6641B2F9-0E20-43E5-BF88-44B02B32117B}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{C61EE276-91AA-4EDB-9E19-8BD8321FE13D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Experiments", "src\Stride.Shaders.Parsing.Experiments\Stride.Shaders.Parsing.Experiments.csproj", "{55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{C723E631-41D8-4797-86C3-9D52711CC849}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{06F65A22-F517-49B4-B4A5-F38D60555B2A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders", "src\Stride.Shaders\Stride.Shaders.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{E59CE683-4805-4FD3-98EB-4F704C253F1A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Tests\Stride.Shaders.Parsing.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.LSP.Test", "src\Stride.Shaders.LSP.Test\Stride.Shaders.LSP.Test.csproj", "{FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shaders.Spirv", "Stride.Shaders.Spirv", "{6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{32B1203D-8160-455A-9F00-8097119B7EB4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv\Stride.Shaders.Spirv.csproj", "{4EC134E1-5B64-497B-B129-4E1B4806E466}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Experiments", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Experiments\Stride.Shaders.Spirv.Experiments.csproj", "{07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{1205976E-A945-4475-AD87-C63527D5A63A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core.Benchmarks", "src\Stride.Shaders.Spirv\Stride.Shaders.Spirv.Core.Benchmarks\Stride.Shaders.Spirv.Core.Benchmarks.csproj", "{8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Parsing.Tests\Stride.Shaders.Parsing.Tests.csproj", "{41050DB9-A819-4FC7-9D46-0ED054CAE7CB}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "submodules", "submodules", "{5889489A-15EB-4324-ACBC-3A4C9F11A39C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Core", "src\Stride.Shaders.Core\Stride.Shaders.Core.csproj", "{C2EE00B4-6CDA-498B-A54E-610E66EBD397}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -41,79 +25,45 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6641B2F9-0E20-43E5-BF88-44B02B32117B}.Release|Any CPU.Build.0 = Release|Any CPU - {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD}.Release|Any CPU.Build.0 = Release|Any CPU - {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {06F65A22-F517-49B4-B4A5-F38D60555B2A}.Release|Any CPU.Build.0 = Release|Any CPU - {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E59CE683-4805-4FD3-98EB-4F704C253F1A}.Release|Any CPU.Build.0 = Release|Any CPU - {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C}.Release|Any CPU.Build.0 = Release|Any CPU - {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6}.Release|Any CPU.Build.0 = Release|Any CPU - {4EC134E1-5B64-497B-B129-4E1B4806E466}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4EC134E1-5B64-497B-B129-4E1B4806E466}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4EC134E1-5B64-497B-B129-4E1B4806E466}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4EC134E1-5B64-497B-B129-4E1B4806E466}.Release|Any CPU.Build.0 = Release|Any CPU - {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Debug|Any CPU.Build.0 = Debug|Any CPU - {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00}.Release|Any CPU.Build.0 = Release|Any CPU - {1205976E-A945-4475-AD87-C63527D5A63A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1205976E-A945-4475-AD87-C63527D5A63A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1205976E-A945-4475-AD87-C63527D5A63A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1205976E-A945-4475-AD87-C63527D5A63A}.Release|Any CPU.Build.0 = Release|Any CPU - {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C}.Release|Any CPU.Build.0 = Release|Any CPU - {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41050DB9-A819-4FC7-9D46-0ED054CAE7CB}.Release|Any CPU.Build.0 = Release|Any CPU - {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897}.Release|Any CPU.Build.0 = Release|Any CPU - {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C2EE00B4-6CDA-498B-A54E-610E66EBD397}.Release|Any CPU.Build.0 = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|Any CPU.Build.0 = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|Any CPU.Build.0 = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|Any CPU.Build.0 = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|Any CPU.Build.0 = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.Build.0 = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|Any CPU.Build.0 = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {6641B2F9-0E20-43E5-BF88-44B02B32117B} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {55F0B4B4-8BD5-4957-8D96-BF369E3CCCFD} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {06F65A22-F517-49B4-B4A5-F38D60555B2A} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {E59CE683-4805-4FD3-98EB-4F704C253F1A} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {FB96F2D7-6288-492A-8CB5-2FCE9DB1BA8C} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {DDCF65EC-1CF7-4098-B20B-DA6761F6B8E6} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} - {4EC134E1-5B64-497B-B129-4E1B4806E466} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} - {07ED0B5B-BB1A-4B7E-ACBD-C06FC106AF00} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} - {1205976E-A945-4475-AD87-C63527D5A63A} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} - {8A94649E-8A3B-4F7C-85A5-9D38212AAA3C} = {6F9ED3BC-F61F-4FFE-9AC4-F42FDECDFA92} - {41050DB9-A819-4FC7-9D46-0ED054CAE7CB} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - {8DE1B8C3-4276-4B6D-B4DE-1B9C0B41B897} = {5889489A-15EB-4324-ACBC-3A4C9F11A39C} - {C2EE00B4-6CDA-498B-A54E-610E66EBD397} = {F15E41A8-FD75-462B-9BB0-DCE18A6AD334} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A8CB18C1-53F2-4B53-B9FF-46BBBCA76534} + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {C723E631-41D8-4797-86C3-9D52711CC849} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/assets/SDSL/Test.sdsl b/assets/SDSL/Test.sdsl index ae85a572a7..9115b8c19a 100644 --- a/assets/SDSL/Test.sdsl +++ b/assets/SDSL/Test.sdsl @@ -1,19 +1,23 @@ -namespace Machin +namespace Machin; +shader Test { - shader Test - { - stream float4 Position; - stream float4 Color; - + stream float4 Position : SV_POSITION; + stream float4 Color : SV_TARGET; + bool machin = false; - void PSMain() - { - streams.Position.w = 1.0; - } + void PSMain() + { + streams.Position.w = 1.0; + } - void VSMain() - { - streams.Color = float4(1.0,0.0,1.0,1u32); - } + void VSMain() + { + int a = 0; + a = 3; + if(machin) + streams.Color *= 2; + if(a < 2) + a *= 3; + streams.Color = float4(1.0,0.0,1.0,1f32); } } \ No newline at end of file diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl new file mode 100644 index 0000000000..9cd6dd4033 --- /dev/null +++ b/assets/SDSL/TestBasic.sdsl @@ -0,0 +1,9 @@ +namespace Stride.Shaders.Tests; + +shader TestBasic +{ + int Add(int a, int b) + { + return a + b; + } +} \ No newline at end of file diff --git a/assets/SDSL/TestVertex.sdsl b/assets/SDSL/TestVertex.sdsl new file mode 100644 index 0000000000..8d8077ef71 --- /dev/null +++ b/assets/SDSL/TestVertex.sdsl @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Tests; + +shader TestVertex +{ + stream float4 Position : SV_POSITION; + + void VSMain() + { + streams.Position *= float4(1,1,1,0.5f); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id b/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id new file mode 100644 index 0000000000..343510a1ed --- /dev/null +++ b/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id @@ -0,0 +1 @@ +(q*KPE* \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/DXC.cs b/src/Stride.Shaders.Compilers/DXC.cs deleted file mode 100644 index a6c81c1f9b..0000000000 --- a/src/Stride.Shaders.Compilers/DXC.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Text; -using Silk.NET.Core; -using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; - -namespace Stride.Shaders.Compilers; - -using DXCBuffer = Silk.NET.Direct3D.Compilers.Buffer; - - - - -public record struct DXCompiler(string Code) -{ - - public static string sampleCode = @" -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VSMain(float4 position : POSITION, float4 color : COLOR) -{ - PSInput result; - - result.position = position; - result.color = color; - - return result; -} - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} - -"; - static Guid blobGuid = Guid.Parse("3DA636C9-BA71-4024-A301-30CBF125305B"); - static Guid utilsGuid = Guid.Parse("6245D6AF-66E0-48FD-80B4-4D271796748C"); - static Guid compilerGuid = Guid.Parse("73e22d93-e6ce-47f3-b5bf-f0664f39c1b0"); - static Guid compilerArgsGuid = Guid.Parse("3e56ae82-224d-470f-a1a1-fe3016ee9f9d"); - static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); - static readonly DXC dxc = DXC.GetApi(); - - public readonly void Compile() - { - // var content = Encoding.ASCII.GetBytes(Code); - unsafe - { - var compiler = dxc.CreateInstance(ref compilerGuid); - var utils = dxc.CreateInstance(ref utilsGuid); - var args = dxc.CreateInstance(ref compilerArgsGuid); - - // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); - IDxcBlobEncoding* sourceBlob = null; - - SilkMarshal.ThrowHResult( - utils.Get().CreateBlobFromPinned((void*)SilkMarshal.StringToPtr(Code), (uint)Code.Length, 1200, ref sourceBlob) - ); - // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); - var buff = new DXCBuffer(sourceBlob, (nuint)Code.Length); - IDxcOperationResult* result = null; - string[] parms = ["-spirv", "-T", "ps_6_0", "-E", "PSMain"]; - SilkMarshal.ThrowHResult( - compiler.Get().Compile(&buff, parms, (uint)parms.Length, null, ref resultGuid,(void**)result) - ); - - // Console.WriteLine((nint)result); - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/Direct3D/DXC.cs b/src/Stride.Shaders.Compilers/Direct3D/DXC.cs new file mode 100644 index 0000000000..d5e557ff46 --- /dev/null +++ b/src/Stride.Shaders.Compilers/Direct3D/DXC.cs @@ -0,0 +1,75 @@ +using System.Text; +using Silk.NET.Core; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; + +namespace Stride.Shaders.Compilers.Direct3D; + +using DXCBuffer = Silk.NET.Direct3D.Compilers.Buffer; + + + + +public record struct DXCompiler() : ICompiler +{ + + public static string sampleCode = @" +struct PSInput +{ + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +PSInput VSMain(float4 position : POSITION, float4 color : COLOR) +{ + PSInput result; + + result.position = position; + result.color = color; + + return result; +} + +float4 PSMain(PSInput input) : SV_TARGET +{ + return input.color; +} + +"; + static Guid blobGuid = Guid.Parse("3DA636C9-BA71-4024-A301-30CBF125305B"); + static Guid utilsGuid = Guid.Parse("6245D6AF-66E0-48FD-80B4-4D271796748C"); + static Guid compilerGuid = Guid.Parse("73e22d93-e6ce-47f3-b5bf-f0664f39c1b0"); + static Guid compilerArgsGuid = Guid.Parse("3e56ae82-224d-470f-a1a1-fe3016ee9f9d"); + static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); + static readonly DXC dxc = DXC.GetApi(); + + public bool Compile(string code, out Memory compiled) + { + throw new NotImplementedException(); + // var content = Encoding.ASCII.GetBytes(Code); + // unsafe + // { + // var compiler = dxc.CreateInstance(ref compilerGuid); + // var utils = dxc.CreateInstance(ref utilsGuid); + // var args = dxc.CreateInstance(ref compilerArgsGuid); + + // // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); + // IDxcBlobEncoding* sourceBlob = null; + + // SilkMarshal.ThrowHResult( + // utils.Get().CreateBlobFromPinned((void*)SilkMarshal.StringToPtr(Code), (uint)Code.Length, 1200, ref sourceBlob) + // ); + // // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); + // var buff = new DXCBuffer(sourceBlob, (nuint)Code.Length); + // IDxcOperationResult* result = null; + // string[] parms = ["-spirv", "-T", "ps_6_0", "-E", "PSMain"]; + // SilkMarshal.ThrowHResult( + // compiler.Get().Compile(&buff, parms, (uint)parms.Length, null, ref resultGuid,(void**)result) + // ); + + // // Console.WriteLine((nint)result); + // } + // compiled = Memory.Empty; + // return true; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/Direct3D/FXC.cs b/src/Stride.Shaders.Compilers/Direct3D/FXC.cs new file mode 100644 index 0000000000..151311f23b --- /dev/null +++ b/src/Stride.Shaders.Compilers/Direct3D/FXC.cs @@ -0,0 +1,18 @@ +using System.Text; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; + +namespace Stride.Shaders.Compilers.Direct3D; + + + + +public record struct FXCompiler() : ICompiler +{ + static D3DCompiler d3d = D3DCompiler.GetApi(); + + public bool Compile(string code, out Memory compiled) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/FXC.cs b/src/Stride.Shaders.Compilers/FXC.cs deleted file mode 100644 index d4addea8c6..0000000000 --- a/src/Stride.Shaders.Compilers/FXC.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Text; -using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; - -namespace Stride.Shaders.Compilers; - - - - -public record struct FXCompiler(string Code) -{ - static D3DCompiler d3d = D3DCompiler.GetApi(); - - public readonly void Compile() - { - var content = Encoding.ASCII.GetBytes(Code); - unsafe - { - // ComPtr shader; - // ComPtr errorMsgs; - // int res = 0; - // fixed(byte* pContent = content) - // res = d3d.Compile( - // pSrcData: pContent, - // SrcDataSize: (nuint)content.Length, - // // pSourceName: "triangle", - // pDefines: null, - // pInclude: null, - // pEntrypoint: "VSMain", - // pTarget: "vs_5_0", - // Flags1: 0, - // Flags2: 0, - // ppCode: &shader, - // ppErrorMsgs: &errorMsgs); - - // Console.WriteLine(Encoding.ASCII.GetString(errorMsgs.Get().Buffer)); - // SilkMarshal.ThrowHResult(res); - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/ICompiler.cs b/src/Stride.Shaders.Compilers/ICompiler.cs new file mode 100644 index 0000000000..7ff14fb6f2 --- /dev/null +++ b/src/Stride.Shaders.Compilers/ICompiler.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders.Compilers; + + +public interface ICompiler +{ + bool Compile(string code, out Memory compiled); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs new file mode 100644 index 0000000000..766a50e7df --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -0,0 +1,34 @@ +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Tools; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Compilers.SDSL; + +public record struct SDSLC() : ICompiler +{ + public readonly bool Compile(string code, out Memory compiled) + { + var parsed = SDSLParser.Parse(code); + if(parsed.AST is ShaderFile sf) + { + SymbolTable table = new(); + var shader = sf.Namespaces.First().Declarations.OfType().First(); + shader.ProcessSymbol(table); + + if(table.Errors.Count > 0) + throw new Exception("Some parse errors"); + var compiler = new CompilerUnit(); + shader.Compile(compiler, table); + + compiler.Context.Buffer.Sort(); + var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); + var dis = new SpirvDis(merged); + dis.Disassemble(true); + } + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSLC.cs deleted file mode 100644 index 69bec54763..0000000000 --- a/src/Stride.Shaders.Compilers/SDSLC.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Stride.Shaders.Compilers; - - -public record struct SDSLC; \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SpirvOpt.cs b/src/Stride.Shaders.Compilers/SpirvOpt.cs index f718caf553..a3732a7950 100644 --- a/src/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/src/Stride.Shaders.Compilers/SpirvOpt.cs @@ -5,6 +5,7 @@ using Silk.NET.SPIRV.Cross; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Compilers.Direct3D; namespace Stride.Shaders.Compilers; diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 4344add0d9..1a1c0a984d 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -1,8 +1,7 @@  - - + diff --git a/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj b/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj deleted file mode 100644 index f68e932c9a..0000000000 --- a/src/Stride.Shaders.Core/Stride.Shaders.Core.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - net9.0 - enable - enable - - - - - - - - diff --git a/src/Stride.Shaders.Core/Symbol.cs b/src/Stride.Shaders.Core/Symbol.cs deleted file mode 100644 index 5f5d616c7e..0000000000 --- a/src/Stride.Shaders.Core/Symbol.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Stride.Shaders.Core; - - - - -public enum SymbolKind -{ - MixinParent, - MixinChild, - Struct, - Method, - Variable, - Constant, - ConstantGeneric, - Composition, - CBuffer, - TBuffer, - RGroup -} - -public record struct SymbolID(string Name, SymbolKind Kind); -public record struct Symbol(SymbolID Id, SymbolType Type); \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolTypes.Globals.cs b/src/Stride.Shaders.Core/SymbolTypes.Globals.cs deleted file mode 100644 index 43f6a3cb54..0000000000 --- a/src/Stride.Shaders.Core/SymbolTypes.Globals.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.Collections.Frozen; - -namespace Stride.Shaders.Core; - - -public partial record Scalar -{ - public static string[] names = [ - "bool", - "byte", - "sbyte", - "short", - "ushort", - "half", - "int", - "uint", - "float", - "long", - "ulong", - "double" - ]; - public static Scalar From(string s) => Types[s]; - public static FrozenDictionary Types { get; } = Init(); - - // static Scalar() - // { - // var arr = new KeyValuePair[names.Length + 1]; - // arr[0] = new("void", new("void")); - // for(int i = 1; i < names.Length; i++) - // arr[i] = new(names[i], new(names[i])); - // Types = FrozenDictionary.ToFrozenDictionary(arr); - // } - internal static FrozenDictionary Init() - { - var arr = new KeyValuePair[names.Length + 1]; - arr[0] = new("void", new("void")); - for(int i = 1; i < names.Length + 1; i++) - arr[i] = new(names[i - 1], new(names[i - 1])); - return arr.ToFrozenDictionary(); - } -} - -public partial record Vector -{ - public static Vector From(string s) => Types[s]; - public static FrozenDictionary Types { get; } = Init(); - - internal static FrozenDictionary Init() - { - var arr = new KeyValuePair[Scalar.names.Length * 4]; - for(int i = 0; i < Scalar.names.Length; i++) - for(int x = 1; x < 5; x++) - arr[i * 4 + (x - 1)] = new($"{Scalar.names[i]}{x}", new(Scalar.From(Scalar.names[i]),x)); - return arr.ToFrozenDictionary(); - } -} - - -public partial record Matrix -{ - public static Matrix From(string s) => Types[s]; - public static FrozenDictionary Types { get; } = Init(); - internal static FrozenDictionary Init() - { - var arr = new KeyValuePair[Scalar.names.Length * 4 * 4]; - for(int i = 0; i < Scalar.names.Length; i++) - for(int x = 1; x < 5; x++) - for(int y = 1; y < 5; y++) - arr[i * 16 + (x - 1) * 4 + (y - 1) * 4] = new($"{Scalar.names[i]}{x}x{y}", new(Scalar.From(Scalar.names[i]),x,y)); - return arr.ToFrozenDictionary(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolTypes.cs b/src/Stride.Shaders.Core/SymbolTypes.cs deleted file mode 100644 index 7d3c221188..0000000000 --- a/src/Stride.Shaders.Core/SymbolTypes.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Security.Cryptography.X509Certificates; -using Microsoft.VisualBasic; - -namespace Stride.Shaders.Core; - - - -public abstract record SymbolType() -{ - public static bool TryGetNumeric(string name, out SymbolType? result) - { - if(Scalar.Types.TryGetValue(name, out var s)) - { - result = s; - return true; - } - else if(Vector.Types.TryGetValue(name, out var v)) - { - result = v; - return true; - } - else if(Matrix.Types.TryGetValue(name, out var m)) - { - result = m; - return true; - } - else if (name == "void") - { - result = Scalar.From("void"); - return true; - } - else - { - result = null; - return true; - } - } -} - -public sealed record Undefined(string TypeName) : SymbolType() -{ - public override string ToString() - { - return TypeName; - } -} -public sealed partial record Scalar(string TypeName) : SymbolType() -{ - public override string ToString() - { - return TypeName; - } -} -public sealed partial record Vector(Scalar BaseType, int Size) : SymbolType() -{ - public override string ToString() - { - return $"{BaseType}{Size}"; - } -} -public sealed partial record Matrix(Scalar BaseType, int Rows, int Columns) : SymbolType() -{ - public override string ToString() - { - return $"{BaseType}{Rows}x{Columns}"; - } -} -public sealed record Array(SymbolType BaseType, int Size) : SymbolType() -{ - public override string ToString() - { - return $"{BaseType}[{Size}]"; - } -} -public sealed record Struct(string Name, Dictionary Fields) : SymbolType() -{ - public override string ToString() - { - return $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Value} {x.Key}"))}}}"; - } -} -public sealed record Buffer(SymbolType BaseType, int Size) : SymbolType() -{ - public override string ToString() - { - return $"Buffer<{BaseType}, {Size}>"; - } -} - - -public abstract record Texture(SymbolType BaseType) : SymbolType() -{ - public override string ToString() - { - return $"Texture<{BaseType}>"; - } -} -public sealed record Texture1D(SymbolType BaseType, int Size) : Texture(BaseType) -{ - public override string ToString() - { - return $"Texture<{BaseType}, {Size}>"; - } -} -public sealed record Texture2D(SymbolType BaseType, int Width, int Height) : Texture(BaseType) -{ - public override string ToString() - { - return $"Texture<{BaseType}, {Width}, {Height}>"; - } -} -public sealed record Texture3D(SymbolType BaseType, int Width, int Height, int Depth) : Texture(BaseType) -{ - public override string ToString() - { - return $"Texture<{BaseType}, {Width}, {Height}, {Depth}>"; - } -} - - -public sealed record BufferSymbol(string Name, List Symbols) : SymbolType; -public sealed record ParamsSymbol(string Name, List Symbols) : SymbolType; -public sealed record EffectSymbol(string Name, List Symbols) : SymbolType; -public sealed record ShaderSymbol(string Name, List Components) : SymbolType -{ - public Symbol Get(string name, SymbolKind kind) - { - foreach (var e in Components) - if (e.Id.Kind == kind && e.Id.Name == name) - return e; - throw new ArgumentException($"{name} not found in Mixin {Name}"); - } - public bool TryGet(string name, SymbolKind kind, out Symbol? value) - { - foreach (var e in Components) - if (e.Id.Kind == kind && e.Id.Name == name) - { - value = e; - return true; - } - value = null!; - return false; - } -} diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs new file mode 100644 index 0000000000..58026c3411 --- /dev/null +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -0,0 +1,202 @@ +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using Stride.Shaders.Spirv.Tools; +using Stride.Shaders.Spirv.Building; +using static Spv.Specification; + +namespace Stride.Shaders.Experiments; + + +public static partial class Examples +{ + public static void GenerateSpirv() + { + var module = new SpirvModule(); + using var context = new SpirvContext(new()); + using var builder = new SpirvBuilder(); + + context.GetOrRegister(new MatrixType(ScalarType.From("float"), 4, 3)); + context.GetOrRegister(ScalarType.From("int")); + + + // context.AddGlobalVariable(new(new("color", SymbolKind.Variable, Storage.Stream), VectorType.From("float4"))); + + var function = builder.CreateFunction( + context, + "add", + new(ScalarType.From("int"), [ScalarType.From("int"), ScalarType.From("int")]) + ); + builder.AddFunctionParameter(context, "a", ScalarType.From("int")); + builder.AddFunctionParameter(context, "b", ScalarType.From("int")); + builder.SetPositionTo(function); + var block = builder.CreateBlock(context, "sourceBlock"); + builder.SetPositionTo(block); + var v = builder.BinaryOperation( + context, + function.Parameters["a"].TypeId, + function.Parameters["a"], Operator.Plus, function.Parameters["b"] + ); + builder.Return(v); + context.Buffer.Sort(); + var dis = new SpirvDis(SpirvBuffer.Merge(context.Buffer, builder.Buffer), useNames: true); + dis.Disassemble(true); + } + + public static void ParseShader() + { + Console.WriteLine(Unsafe.SizeOf>()); + + InstructionInfo.GetInfo(SDSLOp.OpCapability); + + var shader = File.ReadAllBytes("../../shader.spv"); + + + SpirvReader.ParseToList(shader, new(8)); + } + + + public static void CreateShader() + { + int id = 1; + + // var bound = new Bound(); + var buffer = new SpirvBuffer(); + // // Capabilities + + buffer.AddOpCapability(Capability.Shader); + var extInstImport = buffer.AddOpExtInstImport(id++, "GLSL.std.450"); + buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); + + + // declarations + + Span c = stackalloc IdRef[10]; // This is for use in parameters + + + var t_void = buffer.AddOpTypeVoid(id++); + + var t_bool = buffer.AddOpTypeBool(id++); + + var t_func = buffer.AddOpTypeFunction(id++, t_void, []); + var t_float = buffer.AddOpTypeFloat(id++, 32, null); + var t_uint = buffer.AddOpTypeInt(id++, 32, 0); + var t_int = buffer.AddOpTypeInt(id++, 32, 1); + var t_func_add = buffer.AddOpTypeFunction(id++, t_int, [t_int, t_int]); + var t_float4 = buffer.AddOpTypeVector(id++, t_float, 4); + var t_p_float4_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_float4); + var constant1 = buffer.AddOpConstant(id++, t_float, 5); + var constant2 = buffer.AddOpConstant(id++, t_float, 2.23f); + var constant3 = buffer.AddOpConstant(id++, t_uint, 5); + var compositeType = buffer.AddOpConstantComposite( + id++, + t_float4, + [constant1, constant1, constant2, constant1] + ); + + var t_array = buffer.AddOpTypeArray(id++, t_float4, constant3); + + var t_struct = buffer.AddOpTypeStruct(id++, [t_uint, t_array, t_int]); + var t_struct2 = buffer.AddOpTypeStruct(id++, [t_struct, t_uint]); + + var t_p_struct2 = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_struct2); + + var v_struct2 = buffer.AddOpVariable(id++, t_p_struct2, StorageClass.Uniform, null); + + var constant4 = buffer.AddOpConstant(id++, t_int, 1); + + var t_p_uint = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_uint); + var constant5 = buffer.AddOpConstant(id++, t_uint, 0); + + var t_p_output = buffer.AddOpTypePointer(id++, StorageClass.Output, t_float4); + var v_output = buffer.AddOpVariable(id++, t_p_output, StorageClass.Output, null); + + var t_p_input = buffer.AddOpTypePointer(id++, StorageClass.Input, t_float4); + var v_input = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + + var constant6 = buffer.AddOpConstant(id++, t_int, 0); + var constant7 = buffer.AddOpConstant(id++, t_int, 2); + var t_p_float4_unif = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_float4); + + var v_input_2 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + var t_p_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_int); + var constant8 = buffer.AddOpConstant(id++, t_int, 4); + var v_input_3 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + + + + + + buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); + buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); + buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); + buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); + buffer.AddOpDecorate(t_struct2, Decoration.Block); + buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); + buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); + + + + + buffer.AddOpName(t_p_func, "main"); + buffer.AddOpName(t_struct, "S"); + buffer.AddOpMemberName(t_struct, 0, "b"); + buffer.AddOpMemberName(t_struct, 1, "v"); + buffer.AddOpMemberName(t_struct, 2, "i"); + + var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.MaskNone, t_func_add); + var a = buffer.AddOpFunctionParameter(id++, t_int); + var b = buffer.AddOpFunctionParameter(id++, t_int); + buffer.AddOpLabel(id++); + var res = buffer.AddOpIAdd(id++, t_int, a, b); + buffer.AddOpReturnValue(res); + buffer.AddOpFunctionEnd(); + + var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.MaskNone, t_func); + buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); + buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); + + buffer.AddOpLabel(id++); + var resAdd = buffer.AddOpFunctionCall(id++, t_int, add, [constant7, constant7]); + buffer.AddOpReturn(); + buffer.AddOpFunctionEnd(); + + + + + + buffer.Sort(); + + var dis = new SpirvDis(buffer, useNames: true); + + dis.Disassemble(writeToConsole: true); + File.WriteAllBytes( + "test.spv", + MemoryMarshal.Cast(buffer.Span) + ); + } + + + public static void ParseWorking() + { + // var path = @"C:\Users\youness_kafia\Documents\dotnetProjs\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; + var path = @"C:\Users\kafia\source\repos\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; + + var bytes = File.ReadAllBytes(path); + + var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytes)); + var extInst = buffer[1]; + foreach (var o in extInst) + { + if (o.Kind == OperandKind.LiteralString) + { + Console.WriteLine(o.To().Value); + } + } + } +} diff --git a/src/Stride.Shaders.Parsing.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs similarity index 88% rename from src/Stride.Shaders.Parsing.Experiments/Examples.cs rename to src/Stride.Shaders.Experiments/Examples.cs index 8ff65814f7..68eb066dbc 100644 --- a/src/Stride.Shaders.Parsing.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -1,12 +1,11 @@ using System.Text; -using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; +using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; -using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Experiments; @@ -34,7 +33,7 @@ public static bool Intersects(this N node, TextPosition position) } } -public static class Examples +public static partial class Examples { static uint[] words = [ // Offset 0x00000000 to 0x0000016F @@ -71,7 +70,7 @@ public static class Examples 0xFD000100, 0x38000100 ]; public static void UseSpirvCross() - { + { unsafe { var code = new SpirvTranslator(words.AsMemory()); @@ -80,21 +79,21 @@ public static void UseSpirvCross() } public static void TranslateHLSL() { - - Console.WriteLine(SpirvOptimizer.CompileAssembly(DXCompiler.sampleCode,"PSMain", SourceLanguage.Hlsl, OptimizationLevel.Zero)); - Console.WriteLine(SpirvOptimizer.Translate(DXCompiler.sampleCode,"PSMain", SourceLanguage.Hlsl, Backend.Hlsl)); + + Console.WriteLine(SpirvOptimizer.CompileAssembly(DXCompiler.sampleCode, "PSMain", SourceLanguage.Hlsl, OptimizationLevel.Zero)); + Console.WriteLine(SpirvOptimizer.Translate(DXCompiler.sampleCode, "PSMain", SourceLanguage.Hlsl, Backend.Hlsl)); } public static void CompileHLSL() { - var dxc = new DXCompiler(DXCompiler.sampleCode); - dxc.Compile(); + var dxc = new DXCompiler(); + dxc.Compile(DXCompiler.sampleCode, out var compiled); } public static void CompileOldHLSL() { var fxc = new FXCompiler(); - fxc.Compile(); + fxc.Compile(DXCompiler.sampleCode, out var compiled); } public static void SpvOpt() { @@ -108,7 +107,7 @@ public static void ParseSDSL() var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/Test.sdsl"); var parsed = SDSLParser.Parse(text); Console.WriteLine(parsed.AST); - if(parsed.Errors.Count > 0) + if (parsed.Errors.Count > 0) { Console.ForegroundColor = ConsoleColor.Red; foreach (var e in parsed.Errors) @@ -118,19 +117,21 @@ public static void ParseSDSL() { var table = new SymbolTable(); parsed.AST?.ProcessSymbol(table); + foreach (var e in table.Errors) + Console.WriteLine(e); } } public static void TryAllFiles() { - foreach(var f in Directory.EnumerateFiles("./assets/Stride/SDSL")) + foreach (var f in Directory.EnumerateFiles("./assets/Stride/SDSL")) { // var text = File.ReadAllText(f); if (f.Contains("BasicMixin.sdsl")) continue; var preprocessed = MonoGamePreProcessor.OpenAndRun(f); var parsed = SDSLParser.Parse(preprocessed); - if(parsed.Errors.Count > 0) + if (parsed.Errors.Count > 0) { Console.WriteLine(preprocessed); Console.ForegroundColor = ConsoleColor.Red; @@ -208,6 +209,14 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) } return false; } + + public static void CompileSDSL() + { + var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestBasic.sdsl"); + + var sdslc = new SDSLC(); + sdslc.Compile(text, out var bytecode); + } } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs new file mode 100644 index 0000000000..693a03ff7d --- /dev/null +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -0,0 +1,9 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Experiments; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; + +Examples.CompileSDSL(); +// Examples.TryAllFiles(); +// Examples.CreateShader(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj similarity index 100% rename from src/Stride.Shaders.Parsing.Experiments/Stride.Shaders.Parsing.Experiments.csproj rename to src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj diff --git a/src/Stride.Shaders.LSP.Test/Program.cs b/src/Stride.Shaders.LSP.Test/Program.cs deleted file mode 100644 index 906d748f35..0000000000 --- a/src/Stride.Shaders.LSP.Test/Program.cs +++ /dev/null @@ -1,2 +0,0 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello world!"); \ No newline at end of file diff --git a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj b/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj deleted file mode 100644 index d91bdeef5c..0000000000 --- a/src/Stride.Shaders.LSP.Test/Stride.Shaders.LSP.Test.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - Exe - net9.0 - enable - enable - - - diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index dab5471a22..a1970af07f 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Stride.Shaders.Parsing.Experiments/Program.cs b/src/Stride.Shaders.Parsing.Experiments/Program.cs deleted file mode 100644 index 31ea71f403..0000000000 --- a/src/Stride.Shaders.Parsing.Experiments/Program.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Stride.Shaders.Experiments; -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; - - -// Examples.SpvOpt(); -// Examples.TranslateHLSL(); -// var matched = Grammar.Match("int uSeed = (int) (fSeed);"); -// foreach(var e in matched.Errors) -// Console.WriteLine(e); -// Console.WriteLine(matched.AST); - -Examples.ParseSDSL(); -var x = 0; -// Examples.TryAllFiles(); \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs b/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs deleted file mode 100644 index ff0a66fb5a..0000000000 --- a/src/Stride.Shaders.Parsing/Analysis/OperatorTable.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDSL; - -namespace Stride.Shaders.Parsing.Analysis; - -public static class OperatorTable -{ - - public static bool CheckBinaryOperation(SymbolType left, SymbolType right, Operator op) - { - int a = 0; - float b = 0; - var c = b * a; - return (left, right, op) switch - { - // Scalar operations - ( - Scalar { TypeName: "int" or "long" }, Scalar { TypeName: "int" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - or Operator.LeftShift or Operator.RightShift - or Operator.OR or Operator.XOR or Operator.AND - ) => true, - ( - Scalar { TypeName: "float" or "double" }, Scalar { TypeName: "double" or "float" or "int" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - ( - Scalar { TypeName: "float" } or Scalar { TypeName: "int" }, Scalar { TypeName: "float" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - - // Vector operations - ( - Vector { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, - Vector { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - // Matrix operations - ( - Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, - Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Scalar { TypeName: "int" or "float" or "long" or "double" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - ( - Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Vector { BaseType: Scalar { TypeName: "int" or "float" or "long" or "double" } }, - Matrix { BaseType: Scalar { TypeName: "int" or "long" or "float" } } or Vector { BaseType: Scalar { TypeName: "int" or "float" or "long" or "double" } }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - - _ => false, - }; - } - public static bool BinaryOperationResultingType(SymbolType left, SymbolType right, Operator op, out SymbolType? result) - { - long a = 0; - float b = 0; - float c = a * b; - // TODO : correct that part - result = ((int)op, left, right) switch - { - // Boolean operations - (>= 22 and < 26, Scalar{ TypeName : "bool"}, Scalar {TypeName: "bool"}) => left, - // Linear algebra - (>=8 and < 13, Scalar {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, Scalar r) when l.TypeName == r.TypeName => right, - (>=8 and < 13, Scalar { TypeName: "int" or "uint" or "long" or "ulong" }, Scalar { TypeName: "float" or "double"}) => right, - (>=8 and < 13, Scalar { TypeName: "float" }, Scalar { TypeName: "int" or "float" }) => left, - (>=8 and < 13, Vector l, Vector r) when l.BaseType == r.BaseType => right, - (>=8 and < 13, Vector, Scalar) => left, - (>=8 and < 13, Matrix l, Matrix r) when l.BaseType == r.BaseType => right, - (>=8 and < 13, Matrix l, Scalar r) => l, - (>=8 and < 13, Matrix l, Vector r) => l, - (>=8 and < 13, Matrix { BaseType: Scalar { TypeName: "int" } } l, Matrix { BaseType: Scalar { TypeName: "int" or "float" } } r) => l, - // Comparison - (>=18 and < 22, Scalar {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, Scalar r) when l.TypeName == r.TypeName => Scalar.From("bool"), - _ => null, - }; - return result != null; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs deleted file mode 100644 index c957e95079..0000000000 --- a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.ConstExpr.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.Analysis; - -public partial class SymbolTable -{ - public bool IsConstantExpression(Expression expression) - { - if(expression is TernaryExpression tern) - return IsConstantExpression(tern.Condition) && IsConstantExpression(tern.Left) && IsConstantExpression(tern.Right); - else if(expression is BinaryExpression bin) - return IsConstantExpression(bin.Left) && IsConstantExpression(bin.Right); - else if(expression is Identifier identifier) - return TryFind(identifier, SymbolKind.Constant, out _); - else if(expression is NumberLiteral || expression is BoolLiteral) - return true; - else return false; - } - - // public bool TryFold(Expression expression, out Expression result) - // { - // if(expression is TernaryExpression tern) - // { - // if(TryFold(tern.Condition, out var cond)) - // tern.Condition = cond; - // if(TryFold(tern.Left, out var left)) - // tern.Left = left; - // if(TryFold(tern.Right, out var right)) - // tern.Right = right; - // result = tern; - // return true; - // } - // else if(expression is BinaryExpression bexp) - // { - // if(bexp.Left is not NumberLiteral || bexp.Left is not BoolLiteral) - // if(TryFold(bexp.Left, out var bleft)) - // bexp.Left = bleft; - // if(bexp.Right is not NumberLiteral || bexp.Right is not BoolLiteral) - // if(TryFold(bexp.Right, out var bright)) - // bexp.Right = bright; - // result = (bexp.Left, bexp.Op, bexp.Right) switch - // { - // (BoolLiteral l, Operator.LogicalAND, BoolLiteral r) => new BoolLiteral(false, bexp.Info), - // (BoolLiteral l, Operator.LogicalOR, BoolLiteral r) => new BoolLiteral(false, bexp.Info), - // (IntegerLiteral l, Operator.Plus, IntegerLiteral r) => new IntegerLiteral(l.Suffix, l.Value + r.Value, bexp.Info), - // (IntegerLiteral l, Operator.Plus, FloatLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), - // (FloatLiteral l, Operator.Plus, IntegerLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), - // (FloatLiteral l, Operator.Plus, FloatLiteral r) => new IntegerLiteral(l.Suffix, (long)(l.Value + r.Value), bexp.Info), - // _ => bexp - // }; - // return true; - // } - // else if(expression is Identifier identifier) - // { - // if(TryFind(identifier, SymbolKind.Constant, out var symbol)) - // { - // if(symbol.DefaultValue is null) - // throw new NotImplementedException(); - // result = null!; - // return true; - // } - // } - // else - // { - // result = expression; - // return false; - // } - // result = null!; - // return false; - // } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs deleted file mode 100644 index c3fec86f53..0000000000 --- a/src/Stride.Shaders.Parsing/Analysis/SymbolTable.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Stride.Shaders.Core; - -namespace Stride.Shaders.Parsing.Analysis; - - -public record struct SemanticErrors(TextLocation Location, string Message); - -// TODO : make sure that symbol checking is separated based on symbol kind -public partial class SymbolTable : ISymbolProvider -{ - public Dictionary DeclaredTypes { get; } = []; - public SymbolFrame CurrentTable => Symbols[^1]; - public SymbolFrame RootSymbols => Symbols[0]; - public List Symbols { get; } = [new()]; - - public List Errors { get; } = []; - - - public void Push() => Symbols.Add(new()); - public SymbolFrame Pop() - { - var scope = Symbols[^1]; - Symbols.Remove(scope); - return scope; - } - - public void Import(ISymbolProvider symbols) - { - foreach (var (name, type) in symbols.DeclaredTypes) - DeclaredTypes.TryAdd(name, type); - foreach (var (name, symbol) in symbols.RootSymbols) - RootSymbols.Add(name, symbol); - } - - public bool TryFind(string name, SymbolKind kind, out Symbol symbol) - { - for(int i = 0; i < Symbols.Count; i--) - if(Symbols[i].TryGetValue(name, kind, out symbol)) - return true; - symbol = default; - return false; - } - - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/IParser.cs b/src/Stride.Shaders.Parsing/IParser.cs deleted file mode 100644 index 8c9fba1fb1..0000000000 --- a/src/Stride.Shaders.Parsing/IParser.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing; - -public interface IParser; - -public interface IParser : IParser - where TResult : Node -{ - public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) - where TScanner : struct, IScanner; -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs deleted file mode 100644 index c4b2c785aa..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Expression.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Text; -using Stride.Shaders.Parsing.Analysis; - -namespace Stride.Shaders.Parsing.SDSL.AST; - - - - -public abstract class Expression(TextLocation info) : ValueNode(info); - -public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) -{ - public Identifier Name = name; - public ShaderExpressionList Parameters = parameters; - - public override string ToString() - { - return $"{Name}({string.Join(", ", Parameters)})"; - } -} - -public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) -{ - public Mixin Mixin { get; set; } = mixin; - public override string ToString() - { - return $"{Mixin}"; - } -} - - -public abstract class UnaryExpression(Expression expression, Operator op, TextLocation info) : Expression(info) -{ - public Expression Expression { get; set; } = expression; - public Operator Operator { get; set; } = op; -} - -public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info); - -public class CastExpression(string typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) -{ - public string TypeName { get; set; } = typeName; -} - -public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) -{ - public Operator Operator { get; set; } = op; - public override string ToString() - { - return $"{Operator.ToSymbol()}"; - } -} - -public class AccessorChainExpression(Expression source, TextLocation info) : Expression(info) -{ - public Expression Source { get; set; } = source; - public List Accessors { get; set; } = []; - - public override string ToString() - { - var builder = new StringBuilder().Append(Source); - foreach(var a in Accessors) - if(a is NumberLiteral) - builder.Append('[').Append(a).Append(']'); - else if(a is PostfixIncrement) - builder.Append(a); - else - builder.Append('.').Append(a); - return builder.ToString(); - } -} - -public class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) -{ - public Operator Op { get; set; } = op; - public Expression Left { get; set; } = left; - public Expression Right { get; set; } = right; - - public override void ProcessSymbol(SymbolTable table) - { - Left.ProcessSymbol(table); - Right.ProcessSymbol(table); - if ( - OperatorTable.BinaryOperationResultingType( - Left.Type ?? throw new NotImplementedException("Missing type"), - Right.Type ?? throw new NotImplementedException("Missing type"), - Op, - out var t - ) - ) - Type = t; - else - table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); - } - - public override string ToString() - { - return $"( {Left} {Op.ToSymbol()} {Right} )"; - } -} - -public class TernaryExpression(Expression cond, Expression left, Expression right, TextLocation info) : Expression(info) -{ - public Expression Condition { get; set; } = cond; - public Expression Left { get; set; } = left; - public Expression Right { get; set; } = right; - - public override string ToString() - { - return $"({Condition} ? {Left} : {Right})"; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs deleted file mode 100644 index 3d585f02e4..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Literals.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System.Numerics; -using System.Text; -using Stride.Shaders.Core; -using Stride.Shaders.Core.Analysis; -using Stride.Shaders.Parsing.Analysis; - -namespace Stride.Shaders.Parsing.SDSL.AST; - - - -public abstract class Literal(TextLocation info) : Expression(info); -public abstract class ValueLiteral(TextLocation info) : Literal(info); -public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); - -public class StringLiteral(string value, TextLocation info) : Literal(info) -{ - public string Value { get; set; } = value; - - public override string ToString() - { - return $"\"{Value}\""; - } -} - -public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) -{ - public abstract double DoubleValue { get; } - public abstract int IntValue { get; } - public abstract long LongValue { get; } - -} -public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info) : NumberLiteral(info) - where T : struct, INumber -{ - public Suffix Suffix { get; set; } = suffix; - public T Value { get; set; } = value; - public override double DoubleValue => Convert.ToDouble(Value); - public override long LongValue => Convert.ToInt64(Value); - public override int IntValue => Convert.ToInt32(Value); - - public override string ToString() - { - return $"{Value}{Suffix}"; - } - -} - -public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) -{ - public override void ProcessSymbol(SymbolTable table) - { - Type = Suffix switch - { - { Signed: true, Size: 8 } => Scalar.From("sbyte"), - { Signed: true, Size: 16 } => Scalar.From("short"), - { Signed: true, Size: 32 } => Scalar.From("int"), - { Signed: true, Size: 64 } => Scalar.From("long"), - { Signed: false, Size: 8 } => Scalar.From("byte"), - { Signed: false, Size: 16 } => Scalar.From("ushort"), - { Signed: false, Size: 32 } => Scalar.From("uint"), - { Signed: false, Size: 64 } => Scalar.From("ulong"), - _ => throw new NotImplementedException("Unsupported integer suffix") - }; - } -} -public class UnsignedIntegerLiteral(Suffix suffix, ulong value, TextLocation info) : NumberLiteral(suffix, value, info); - -public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) -{ - public int? Exponent { get; set; } = exponent; - public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - - public override void ProcessSymbol(SymbolTable table) - { - Type = Suffix.Size switch - { - 16 => Scalar.From("half"), - 32 => Scalar.From("float"), - 64 => Scalar.From("double"), - _ => throw new NotImplementedException("Unsupported float") - }; - } -} - -public sealed class HexLiteral(ulong value, TextLocation info) : UnsignedIntegerLiteral(new(32, false, false), value, info) -{ - public override void ProcessSymbol(SymbolTable table) - => Type = Scalar.From("long"); -} - - -public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) -{ - public bool Value { get; set; } = value; - public override void ProcessSymbol(SymbolTable table) - => Type = Scalar.From("bool"); -} - -public class VectorLiteral(TypeName typeName, TextLocation info) : ValueLiteral(info) -{ - public TypeName TypeName { get; set; } = typeName; - public List Values { get; set; } = []; - - public override void ProcessSymbol(SymbolTable table) - { - Type = TypeName.ToSymbol(); - var tmp = (Core.Vector)Type; - foreach(var v in Values) - { - v.ProcessSymbol(table); - if( - v.Type is Scalar st && tmp.BaseType != st - || (v.Type is Core.Vector vt && vt.BaseType != tmp.BaseType) - || (v.Type is Core.Vector vt2 && vt2.Size > tmp.Size) - ) - table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); - } - } - - public override string ToString() - { - return $"{TypeName}({string.Join(", ", Values.Select(x => x.ToString()))})"; - } -} - - -public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : ValueLiteral(info) -{ - public TypeName TypeName { get; set; } = typeName; - public int Rows { get; set; } = rows; - public int Cols { get; set; } = cols; - public List Values { get; set; } = []; - public override string ToString() - { - return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; - } -} - -public class ArrayLiteral(TextLocation info) : ValueLiteral(info) -{ - public List Values { get; set; } = []; - public override string ToString() - { - return $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; - } -} - - -public class Identifier(string name, TextLocation info) : Literal(info) -{ - public string Name { get; set; } = name; - - public static implicit operator string(Identifier identifier) => identifier.Name; - - public override void ProcessSymbol(SymbolTable table) - { - for (int i = table.Symbols.Count - 1; i >= 0; i -= 1) - { - if (table.Symbols[i].TryGetValue(Name, SymbolKind.Variable, out var symbol)) - { - if (symbol.Type is not Undefined and not null) - Type = symbol.Type; - else - Type = symbol.Type ?? new Undefined(Name); - return; - } - } - throw new NotImplementedException($"Cannot find symbol {Name}."); - } - - public override string ToString() - { - return $"{Name}"; - } - - public bool IsSwizzle() - { - if(Name.Length > 4) - return false; - - bool colorMode = false; - bool vectorMode = false; - - Span colorFields = ['r', 'g', 'b', 'a']; - Span vectorFields = ['x', 'y', 'z', 'w']; - - if(colorFields.Contains(Name[0])) - colorMode = true; - else if(vectorFields.Contains(Name[0])) - vectorMode = true; - - if(!colorMode && !vectorMode) - return false; - var fields = colorMode ? colorFields : vectorFields; - foreach(var c in Name) - if(!fields.Contains(c)) - return false; - return true; - } - - public bool IsMatrixField() - { - return - Name.Length == 3 - && Name[0] == '_' - && char.IsDigit(Name[1]) && Name[1] - '0' > 0 && Name[1] - '0' < 5 - && char.IsDigit(Name[2]) && Name[2] - '0' > 0 && Name[2] - '0' < 5; - } -} - -public class TypeName(string name, TextLocation info, bool isArray) : Literal(info) -{ - public string Name { get; set; } = name; - public bool IsArray { get; set; } = isArray; - public List? ArraySize { get; set; } - public List Generics { get; set; } = []; - - public override string ToString() - { - var builder = new StringBuilder(); - builder.Append(Name); - if(Generics.Count > 0) - { - builder.Append('<'); - foreach(var g in Generics) - builder.Append(g.ToString()).Append(", "); - builder.Append('>'); - } - if(ArraySize != null) - foreach(var s in ArraySize) - builder.Append('[').Append(s.ToString()).Append(']'); - - return builder.ToString(); - - } - - public static implicit operator string(TypeName tn) => tn.Name; -} diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs deleted file mode 100644 index ed9ab1c014..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Control.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Stride.Shaders.Parsing.Analysis; - -namespace Stride.Shaders.Parsing.SDSL.AST; - - -public abstract class Control(TextLocation info) : Flow(info); - - -public class ConditionalFlow(If first, TextLocation info) : Flow(info) -{ - public If If { get; set; } = first; - public List ElseIfs { get; set; } = []; - public Else? Else { get; set; } - public ShaderAttributeList? Attributes { get; set; } - - public override void ProcessSymbol(SymbolTable table) - { - If.Condition.ProcessSymbol(table); - If.Body.ProcessSymbol(table); - if (ElseIfs.Count > 0) - { - foreach (var ei in ElseIfs) - { - ei.Condition.ProcessSymbol(table); - ei.Body.ProcessSymbol(table); - } - } - Else?.Body.ProcessSymbol(table); - } - - public override string ToString() - { - return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; - } -} -public class If(Expression condition, Statement body, TextLocation info) : Flow(info) -{ - public Expression Condition { get; set; } = condition; - public Statement Body { get; set; } = body; - - public override string ToString() - { - return $"if({Condition})\n{Body}"; - } -} - -public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) -{ - public override string ToString() - { - return $"else if({Condition}){Body}"; - } -} - -public class Else(Statement body, TextLocation info) : Flow(info) -{ - public Statement Body { get; set; } = body; - public override string ToString() - { - return $"else {Body}"; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs deleted file mode 100644 index 080dcb5689..0000000000 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.Flow.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace Stride.Shaders.Parsing.SDSL.AST; - -public abstract class Flow(TextLocation info) : Statement(info); - -public abstract class Loop(TextLocation info) : Flow(info); -public class Break(TextLocation info) : Statement(info); -public class Discard(TextLocation info) : Statement(info); -public class Continue(TextLocation info) : Statement(info); - - -public class ForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : Loop(info) -{ - public TypeName Typename { get; set; } = typename; - public Identifier Variable { get; set; } = variable; - public Expression Collection { get; set; } = collection; - public Statement Body { get; set; } = body; - - public override string ToString() - { - return $"foreach({Typename} {Variable} in {Collection})\n{Body}"; - } -} - - -public class While(Expression condition, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) -{ - public Expression Condition { get; set; } = condition; - public Statement Body { get; set; } = body; - public ShaderAttribute? Attribute { get; internal set; } = attribute; - - public override string ToString() - { - return $"while({Condition})\n{Body}"; - } -} - -public enum ForAnnotationKind -{ - Unroll, - Loop, - Fastopt, - AllowUAVCondition -} -public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); - -public class For(Statement initializer, Statement cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) -{ - public Statement Initializer { get; set; } = initializer; - public Statement Condition { get; set; } = cond; - public List Update { get; set; } = update; - public Statement Body { get; set; } = body; - public ShaderAttribute? Attribute = attribute; - public List Annotations { get; set; } = []; - - public override string ToString() - { - return $"for({Initializer} {Condition} {Update})\n{Body}"; - } -} - diff --git a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj b/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj deleted file mode 100644 index 1d4a6a9e33..0000000000 --- a/src/Stride.Shaders.Parsing/Stride.Shaders.Parsing.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net9.0 - enable - enable - latest - - - - - - - - - - - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs similarity index 82% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs rename to src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs index 5ce2762bae..14a6c8f98f 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs @@ -1,10 +1,13 @@ -namespace Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +namespace Stride.Shaders.Spirv.Core; -public interface IMutSpirvBuffer +/// +/// SPIR-V buffer that can add instructions to itself +/// +public interface IMutSpirvBuffer : ISpirvBuffer { - public int GetNextId(); - public Instruction Add(MutRefInstruction instruction); + public Instruction Add(Span instruction); } public static class IMutSpirvBufferExtensions diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs new file mode 100644 index 0000000000..4181e64e60 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs @@ -0,0 +1,65 @@ +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A SPIR-V buffer object +/// +public interface ISpirvBuffer +{ + /// + /// Span of the buffer + /// + Span Span { get; } + /// + /// Memory of the buffer + /// + Memory Memory { get; } + /// + /// Span of the buffer without the header + /// + Span InstructionSpan { get; } + /// + /// Memory of the buffer without the header + /// + Memory InstructionMemory { get; } + /// + /// Count of instructions + /// + public int InstructionCount { get; } + /// + /// Length of the buffer + /// + int Length { get; } + + /// + /// Wether the buffer has a header + /// + bool HasHeader { get; } + /// + /// Header of the buffer + /// + RefHeader Header { get; set; } + + /// + /// Get instruction from the instruction index + /// + public Instruction this[int index] { get; } + + /// + /// Convert to a SpirvSpan + /// + /// Buffer as a Span + public SpirvSpan AsSpan(); + /// + /// Convert to a SpirvMemory + /// + /// Buffer as a memory + public SpirvMemory AsMemory(); + + /// + /// Gets Instruction enumerator + /// + /// Instruction enumerator + public RefInstructionEnumerator GetEnumerator(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs new file mode 100644 index 0000000000..3bd3652841 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -0,0 +1,166 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using System.Numerics; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A common SPIR-V buffer containing a header. +/// +public class SpirvBuffer : IMutSpirvBuffer, IDisposable +{ + /// + /// Reusable buffer containing the SPIR-V code + /// + MemoryOwner _owner; + public int Length { get; protected set; } + public Span Span => _owner.Span[..Length]; + public Memory Memory => _owner.Memory[..Length]; + public bool HasHeader => true; + public RefHeader Header + { + get => new(_owner.Span[..5]); + set + { + value.Words.CopyTo(Header.Words); + } + } + public Span InstructionSpan => Span[5..]; + public Memory InstructionMemory => Memory[5..]; + + public int InstructionCount => new SpirvReader(Memory).Count; + + public Instruction this[int index] + { + get + { + int id = 0; + int wid = 5; + while (id < index) + { + wid += Span[wid] >> 16; + id++; + } + return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16), index, wid); + } + } + + public SpirvBuffer(int initialSize = 32) + { + _owner = MemoryOwner.Allocate(initialSize, AllocationMode.Clear); + Header = Header with + { + MagicNumber = Spv.Specification.MagicNumber, + VersionNumber = new(1, 3) + }; + Length = 5; + } + public SpirvBuffer(Memory memory) + { + _owner = MemoryOwner.Allocate(memory.Length, AllocationMode.Clear); + memory.CopyTo(_owner.Memory); + Header = Header with + { + MagicNumber = Spv.Specification.MagicNumber, + VersionNumber = new(1, 3) + }; + } + public SpirvBuffer(Span span) + { + _owner = MemoryOwner.Allocate(span.Length, AllocationMode.Clear); + span.CopyTo(_owner.Span); + Header = Header with + { + MagicNumber = Spv.Specification.MagicNumber, + VersionNumber = new(1, 3) + }; + } + + + public RefInstructionEnumerator GetEnumerator() => new(InstructionSpan, HasHeader); + + public void Sort() + { + var sorted = new OrderedEnumerator(this); + var other = MemoryOwner.Allocate(Length, AllocationMode.Clear); + var pos = 5; + while (sorted.MoveNext()) + { + sorted.Current.Words.CopyTo(other.Memory[pos..]); + pos += sorted.Current.WordCount; + } + _owner.Span[0..5].CopyTo(other.Span[0..5]); + _owner.Dispose(); + _owner = other; + } + public SpirvSpan AsSpan() => new(Span); + public SpirvMemory AsMemory() => new(Memory); + + public Instruction Add(Span instruction) + { + var result = Insert(Length, instruction); + if (RefInstruction.ParseRef(instruction).ResultId is int resultId && resultId >= Header.Bound) + Header = Header with { Bound = resultId + 1 }; + return result; + } + + public void Remove(int position) + { + if(position < 5 && position > Length) + throw new ArgumentOutOfRangeException($"Can't remove at position {position}"); + var size = Span[position] >> 16; + Span[(position + size)..].CopyTo(Span[position..]); + Length -= size; + } + public Instruction Insert(int start, ReadOnlySpan words) + { + Expand(words.Length); + if (start == Length) + words.CopyTo(_owner.Span[start..]); + else + { + var slice = _owner.Span[start..Length]; + slice.CopyTo(_owner.Span[(start + words.Length)..]); + words.CopyTo(_owner.Span.Slice(start, words.Length)); + } + Length += words.Length; + return new(this, Memory[start..(start + words.Length)], InstructionCount - 1, Length - words.Length); + } + + void Expand(int size) + { + if (Length + size > _owner.Length) + { + var n = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)(Length + size)), AllocationMode.Clear); + _owner.Span.CopyTo(n.Span); + var toDispose = _owner; + _owner = n; + toDispose.Dispose(); + } + } + + internal void Add(TBuff buffer) + where TBuff : ISpirvBuffer + { + Expand(buffer.InstructionSpan.Length); + buffer.InstructionSpan.CopyTo(_owner.Span[Length..]); + Length += buffer.InstructionSpan.Length; + } + + + public static SpirvBuffer Merge(T1 left, T2 right) + where T1 : ISpirvBuffer + where T2 : ISpirvBuffer + { + var buff = new SpirvBuffer(left.Length + right.Length + 5); + buff.Add(left); + buff.Add(right); + foreach (var e in buff) + if (e.ResultId is int r && buff.Header.Bound < r) + buff.Header = buff.Header with { Bound = r }; + return buff; + } + + public void Dispose() => _owner.Dispose(); + +} diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs new file mode 100644 index 0000000000..1c6fa3444f --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs @@ -0,0 +1,57 @@ +using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A SPIR-V buffer memory slice +/// +public readonly struct SpirvMemory(Memory memory) : ISpirvBuffer +{ + public readonly Instruction this[int index] + { + get + { + int id = 0; + int wid = 5; + while (id < index) + { + wid += Span[wid] >> 16; + id++; + } + return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16), index, wid); + } + } + public readonly Span Span => Memory.Span; + + public readonly Memory Memory { get; } = memory; + + public readonly Span InstructionSpan => Span[(HasHeader ? 5 : 0)..]; + + public readonly Memory InstructionMemory => Memory[(HasHeader ? 5 : 0)..]; + + public readonly int InstructionCount => new SpirvReader(Memory).Count; + + public readonly int Length => Memory.Length; + + public readonly bool HasHeader => Span[0] == Spv.Specification.MagicNumber; + + public readonly RefHeader Header + { + get => HasHeader ? new(Span[..5]) : throw new Exception("No header for this buffer"); + set + { + if (HasHeader) value.Words.CopyTo(Header.Words); + } + } + + public readonly SpirvMemory AsMemory() => this; + + public readonly SpirvSpan AsSpan() => new(Span); + + public RefInstructionEnumerator GetEnumerator() => new(InstructionSpan, HasHeader); +} diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs new file mode 100644 index 0000000000..faa06270b7 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +/// +/// A SPIR-V buffer span slice +/// +public readonly ref struct SpirvSpan(Span words) : ISpirvBuffer +{ + public readonly Instruction this[int index] => throw new NotImplementedException(); + + public readonly Span Span { get; } = words; + + public readonly Memory Memory => throw new Exception("Can't get Memory from Span"); + + public readonly Span InstructionSpan => Span[(HasHeader ? 5 : 0)..]; + + public readonly Memory InstructionMemory => throw new Exception("Can't get Memory from Span"); + + public readonly int InstructionCount => new SpirvReader(this).Count; + + public readonly int Length => Span.Length; + + public readonly bool HasHeader => Span[0] == Spv.Specification.MagicNumber; + + public readonly RefHeader Header + { + get => HasHeader ? new(Span[..5]) : throw new Exception("No header for this buffer"); + set + { + if (HasHeader) value.Words.CopyTo(Header.Words); + } + } + + public readonly SpirvMemory AsMemory() => throw new Exception("Can't get Memory from Span"); + + public readonly SpirvSpan AsSpan() => this; + + public RefInstructionEnumerator GetEnumerator() => new(Span, HasHeader); +} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs similarity index 89% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs rename to src/Stride.Shaders.Spirv.Core/ISpirvElement.cs index 2abd03c1af..0817375e33 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/ISpirvElement.cs +++ b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs @@ -1,7 +1,4 @@ using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System.Numerics; -using System.Runtime.CompilerServices; namespace Stride.Shaders.Spirv.Core; @@ -12,15 +9,9 @@ public interface ISpirvElement public SpanOwner AsSpanOwner(); } -public interface IWritableSpirvElement : ISpirvElement -{ - public void Write(scoped ref SpirvWriter writer); -} - - public static class ISpirvElementExtensions { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this string? value) { if (value is null) @@ -33,7 +24,7 @@ internal static SpanOwner AsSpanOwner(this string? value) return span; } } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this T value) where T : struct { @@ -58,7 +49,7 @@ internal static SpanOwner AsSpanOwner(this T value) }; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this T? value) where T : struct { @@ -68,7 +59,7 @@ internal static SpanOwner AsSpanOwner(this T? value) return value.Value.AsSpanOwner(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static SpanOwner AsSpanOwner(this Span values) { @@ -167,19 +158,19 @@ or ulong return span; } - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this T? value) where T : struct => value.AsSpanOwner().Span; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this T value) where T : struct => value.AsSpanOwner().Span; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this string? value) => value.AsSpanOwner().Span; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static Span AsSpirvSpan(this Span values) => values.AsSpanOwner().Span; } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs similarity index 54% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs rename to src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index b637a44ae6..5a682b5a63 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -10,7 +10,9 @@ namespace Stride.Shaders.Spirv.Core; - +/// +/// Object containing information about SPIR-V instructions based on the unified SPIR-V specification. +/// public partial class InstructionInfo { Dictionary<(SDSLOp, StorageClass?), int> OrderGroup = new(); @@ -20,51 +22,74 @@ public partial class InstructionInfo void InitOrder() { - OrderGroup[(SDSLOp.OpNop, null)] = 0; - OrderGroup[(SDSLOp.OpSDSLMixinName, null)] = 0; - OrderGroup[(SDSLOp.OpCapability, null)] = 0; - OrderGroup[(SDSLOp.OpSDSLMixinOffset, null)] = 0; - OrderGroup[(SDSLOp.OpSDSLMixinInherit, null)] = 0; - OrderGroup[(SDSLOp.OpSDSLCompose, null)] = 0; + int group = 0; + Span initSDSL = [ + SDSLOp.OpNop, + SDSLOp.OpSDSLMixinName, + SDSLOp.OpCapability, + SDSLOp.OpSDSLMixinOffset, + SDSLOp.OpSDSLMixinInherit, + SDSLOp.OpSDSLCompose + ]; + foreach(var e in initSDSL) + OrderGroup[(e, null)] = group; + + group++; foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpSDSLImport"))) - OrderGroup[(e, null)] = 1; - OrderGroup[(SDSLOp.OpExtension, null)] = 1; - OrderGroup[(SDSLOp.OpExtInstImport, null)] = 2; - OrderGroup[(SDSLOp.OpMemoryModel, null)] = 3; - OrderGroup[(SDSLOp.OpEntryPoint, null)] = 4; + OrderGroup[(e, null)] = group; + OrderGroup[(SDSLOp.OpExtension, null)] = group; + + group++; + OrderGroup[(SDSLOp.OpExtInstImport, null)] = group; + group++; + OrderGroup[(SDSLOp.OpMemoryModel, null)] = group; + group++; + OrderGroup[(SDSLOp.OpEntryPoint, null)] = group; + group++; foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpExecutionMode"))) - OrderGroup[(e, null)] = 5; + OrderGroup[(e, null)] = group; - foreach (var e in new SDSLOp[] { SDSLOp.OpString, SDSLOp.OpSource, SDSLOp.OpSourceExtension, SDSLOp.OpSourceContinued }) - OrderGroup[(e, null)] = 6; + group++; + Span opDebugSource = [SDSLOp.OpString, SDSLOp.OpSource, SDSLOp.OpSourceExtension, SDSLOp.OpSourceContinued]; + foreach (var e in opDebugSource) + OrderGroup[(e, null)] = group; - OrderGroup[(SDSLOp.OpName, null)] = 7; - OrderGroup[(SDSLOp.OpSDSLMixinVariable, null)] = 7; - OrderGroup[(SDSLOp.OpMemberName, null)] = 7; + group++; + OrderGroup[(SDSLOp.OpName, null)] = group; + OrderGroup[(SDSLOp.OpSDSLMixinVariable, null)] = group; + OrderGroup[(SDSLOp.OpMemberName, null)] = group; - OrderGroup[(SDSLOp.OpModuleProcessed, null)] = 8; + group++; + OrderGroup[(SDSLOp.OpModuleProcessed, null)] = group; + group++; foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpDecorate"))) - OrderGroup[(e, null)] = 9; + OrderGroup[(e, null)] = group; foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpMemberDecorate"))) - OrderGroup[(e, null)] = 9; + OrderGroup[(e, null)] = group; + group++; foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) - OrderGroup[(e, null)] = 10; + OrderGroup[(e, null)] = group; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) - OrderGroup[(SDSLOp.OpVariable, e)] = 10; - OrderGroup[(SDSLOp.OpSDSLIOVariable, null)] = 10; + OrderGroup[(SDSLOp.OpVariable, e)] = group; + OrderGroup[(SDSLOp.OpSDSLIOVariable, null)] = group; - OrderGroup[(SDSLOp.OpUndef, null)] = 10; - OrderGroup[(SDSLOp.OpLine, null)] = 11; - OrderGroup[(SDSLOp.OpNoLine, null)] = 11; + OrderGroup[(SDSLOp.OpUndef, null)] = group; + group++; + OrderGroup[(SDSLOp.OpLine, null)] = group; + OrderGroup[(SDSLOp.OpNoLine, null)] = group; + + group++; + group++; foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) - OrderGroup[(e, null)] = 13; - OrderGroup[(SDSLOp.OpVariable, StorageClass.Function)] = 13; - OrderGroup[(SDSLOp.OpSDSLMixinEnd, null)] = 14; + OrderGroup[(e, null)] = group; + OrderGroup[(SDSLOp.OpVariable, StorageClass.Function)] = group; + group++; + OrderGroup[(SDSLOp.OpSDSLMixinEnd, null)] = group; } /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. @@ -75,25 +100,22 @@ public static int GetGroupOrder(RefInstruction instruction) { return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); } + /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. /// /// /// - public static int GetGroupOrder(MutRefInstruction instruction) + public static int GetGroupOrder(Instruction instruction) { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); + return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words.Span[3] : null); } /// - /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. + /// Gets the order group for a given instruction and Storage class, useful for sorting instructions according to the specification. /// - /// + /// + /// /// - public static int GetGroupOrder(Instruction instruction) - { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words.Span[3] : null); - } - public static int GetGroupOrder(SDSLOp op, StorageClass? sc = null) { return Instance.OrderGroup[(op, sc)]; diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs similarity index 75% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs rename to src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index d64b0a2daa..e319faf3e6 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -17,7 +17,14 @@ public partial class InstructionInfo public static InstructionInfo Instance { get; } = new(); Dictionary Info = new(); InstructionInfo(){} - + /// + /// Register information about a SPIR-V instruction + /// + /// + /// + /// + /// + /// internal void Register(SDSLOp op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) { if(Info.TryGetValue(op, out var list)) @@ -26,7 +33,7 @@ internal void Register(SDSLOp op, OperandKind? kind, OperandQuantifier? quantifi } else { - Info.Add(op, new(spvClass) { new(kind, quantifier, name)}); + Info.Add(op, new(spvClass, [new(kind, quantifier, name)])); } } /// diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs rename to src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs similarity index 92% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs rename to src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs index b70ad71f5f..6c16aeebbb 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs @@ -6,6 +6,9 @@ namespace Stride.Shaders.Spirv.Core; +/// +/// Information on SPIR-V instruction operands +/// public readonly partial struct LogicalOperand { public string? Name { get; init; } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs similarity index 76% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs rename to src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs index 7776b66d75..c16dd8d08d 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs @@ -4,12 +4,14 @@ namespace Stride.Shaders.Spirv.Core; -public struct LogicalOperandArray : IList +/// +/// Wrapper for the operand list to contain a class name +/// +public readonly struct LogicalOperandArray(string? className, List? operands = null) { + public string ClassName { get; init; } = className ?? "Debug"; - public string ClassName { get; init; } - - List LogicalOperands { get; } + List LogicalOperands { get; } = operands ?? []; public bool HasResult => GetHasResult(); public bool HasResultType => GetHasResultType(); @@ -23,12 +25,6 @@ public LogicalOperand this[int index] set => LogicalOperands[index] = value; } - public LogicalOperandArray(string? className) - { - ClassName = className ?? "Debug"; - LogicalOperands = new(); - } - bool GetHasResult() { foreach (var o in LogicalOperands) @@ -89,13 +85,5 @@ public bool Remove(LogicalOperand item) return LogicalOperands.Remove(item); } - public IEnumerator GetEnumerator() - { - return LogicalOperands.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } + public List.Enumerator GetEnumerator() => LogicalOperands.GetEnumerator(); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs b/src/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs similarity index 73% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs index 404973bd7c..00c9eae6b3 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs @@ -6,6 +6,10 @@ namespace Stride.Shaders.Spirv.Core; +/// +/// Can be parsed from SPIR-V words +/// +/// public interface IFromSpirv { static abstract T From(Span words); diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs b/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs similarity index 80% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs rename to src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs index 3f5bc31d03..f3dc53e7de 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs @@ -7,6 +7,9 @@ namespace Stride.Shaders.Spirv.Core; +/// +/// Represents a number literal in SPIR-V +/// public interface ILiteralNumber : ISpirvElement { public long Words { get; init; } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs similarity index 84% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs index 7ba6ed7240..b0a600d99a 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdRef.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs @@ -10,6 +10,8 @@ public record struct IdRef(int Value) : ISpirvElement, IFromSpirv public static implicit operator int(IdRef r) => r.Value; public static implicit operator IdRef(int v) => new(v); public static implicit operator LiteralInteger(IdRef v) => new(v); + public static implicit operator IdResult(IdRef v) => new(v); + public static implicit operator IdResultType(IdRef v) => new(v); public static IdRef From(Span words) => new() { Value = words[0] }; public static IdRef From(string value) diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResult.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/IdScope.cs rename to src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs similarity index 98% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs rename to src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs index dda177b8f0..9e273b9f86 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -71,11 +71,11 @@ public readonly bool TryCast(out Half value) } public readonly bool TryCast(out float value) { - Span span = stackalloc int[] - { + Span span = + [ (int)(Words >> 32), (int)(Words & 0X0000FFFF) - }; + ]; if (size == 32) { value = BitConverter.Int32BitsToSingle(span[1]); diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs rename to src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs similarity index 97% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs rename to src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs index 26f4ef8dfa..40cb289ad1 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -18,11 +18,11 @@ namespace Stride.Shaders.Spirv.Core; internal bool HasRest => Length % 4 > 0; internal int RestSize => Length % 4; - internal LiteralString(string value) + public LiteralString(string value) { Value = pool.GetOrAdd(value); } - internal LiteralString(Span words) + public LiteralString(Span words) { Span chars = stackalloc char[words.Length * 4]; for (int i = 0; i < words.Length; i++) diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs rename to src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs rename to src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs rename to src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs rename to src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs similarity index 89% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs rename to src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index 9fd1e3adcb..aa80df328b 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -40,9 +40,12 @@ public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Em public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Words.Span); - public T? GetOperand(string name) where T : struct, IFromSpirv + public readonly T? GetOperand(string name) where T : struct, IFromSpirv => AsRef().GetOperand(name); + public readonly bool TryGetOperand(string name, out T? operand) where T : struct, IFromSpirv + => AsRef().TryGetOperand(name, out operand); + public readonly OperandEnumerator GetEnumerator() => AsRef().GetEnumerator(); public override string ToString() diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs b/src/Stride.Shaders.Spirv.Core/OperandQuantifier.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/OperandQuantifier.cs rename to src/Stride.Shaders.Spirv.Core/OperandQuantifier.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs similarity index 55% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs index 6daed66302..83d00822c8 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs @@ -1,34 +1,19 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Buffers; -using static Spv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; /// -/// A simple spirv instruction enumerator without sorting +/// A simple SPIR-V instruction enumerator without sorting /// -public ref struct InstructionEnumerator +public ref struct InstructionEnumerator(ISpirvBuffer buffer) { - int wordIndex; + int wordIndex = 0; int index; - bool started; - ISpirvBuffer buffer; + bool started = false; + readonly ISpirvBuffer buffer = buffer; - public int ResultIdReplacement { get; set; } - - public InstructionEnumerator(ISpirvBuffer buffer) - { - started = false; - wordIndex = 0; - this.buffer = buffer; - ResultIdReplacement = 0; - } + public int ResultIdReplacement { get; set; } = 0; public Instruction Current => ParseCurrentInstruction(); @@ -54,10 +39,9 @@ public bool MoveNext() } - public Instruction ParseCurrentInstruction() + public readonly Instruction ParseCurrentInstruction() { var count = buffer.InstructionSpan[wordIndex] >> 16; return new Instruction(buffer, buffer.InstructionMemory[wordIndex..(wordIndex + count)], index, wordIndex); - } } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs similarity index 55% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 1841d6af9d..257f0fc5b7 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -12,26 +12,17 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// -/// An enumerator where each declartions instructions is sorted +/// An enumerator where each instructions is sorted /// -public ref struct OrderedEnumerator +public ref struct OrderedEnumerator(ISpirvBuffer buffer) { - int index; - int wordIndex; - bool started; + int index = 0; + int wordIndex = 0; + bool started = false; - ISpirvBuffer wbuff; - readonly Span instructionWords => wbuff.InstructionSpan; - Memory memorySlice => wbuff.InstructionMemory; - - public OrderedEnumerator(ISpirvBuffer buffer) - { - started = false; - wordIndex = 0; - index = 0; - wbuff = buffer; - } + readonly ISpirvBuffer wbuff = buffer; + readonly Span InstructionWords => wbuff.InstructionSpan; public readonly Instruction Current => new(wbuff, wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16), index, wordIndex); @@ -43,7 +34,7 @@ public bool MoveNext() (var firstGroup, var firstPos) = (int.MaxValue, int.MaxValue); var wid = 0; var idx = 0; - while(wid < instructionWords.Length) + while(wid < InstructionWords.Length) { var group = GetGroupOrder(wid); if(group < firstGroup) @@ -53,7 +44,7 @@ public bool MoveNext() index = idx; } idx += 1; - wid += instructionWords[wid] >> 16; + wid += InstructionWords[wid] >> 16; } wordIndex = firstPos; started = true; @@ -67,9 +58,9 @@ public bool MoveNext() { if(group == currentGroup) { - var offset = instructionWords[wordIndex] >> 16; + var offset = InstructionWords[wordIndex] >> 16; var idx = index + 1; - while(wordIndex + offset < instructionWords.Length) + while(wordIndex + offset < InstructionWords.Length) { if(GetGroupOrder(wordIndex + offset) == group && idx > index) { @@ -77,7 +68,7 @@ public bool MoveNext() index = idx; return true; } - offset += instructionWords[wordIndex + offset] >> 16; + offset += InstructionWords[wordIndex + offset] >> 16; idx += 1; } } @@ -85,7 +76,7 @@ public bool MoveNext() { var wid = 0; var idx = 0; - while (wid < instructionWords.Length) + while (wid < InstructionWords.Length) { var g = GetGroupOrder(wid); if (g == group) @@ -95,42 +86,18 @@ public bool MoveNext() return true; } idx += 1; - wid += instructionWords[wid] >> 16; + wid += InstructionWords[wid] >> 16; } } } return false; - - //var count = new SpirvReader(memorySlice).Count; - //var currentGroup = GetGroupOrder(wordIndex); - //for (int groupOffset = 0; groupOffset < 14; groupOffset++) - //{ - // var wid = 0; - // for (int i = 0; i < count; i++) - // { - // if (wid >= instructionWords.Length) - // break; - // var g = GetGroupOrder(wid); - // if (GetGroupOrder(wid) == currentGroup + groupOffset && i != index) - // { - // if (!(groupOffset == 0 && i < index)) - // { - // index = i; - // wordIndex = wid; - // return true; - // } - // } - // wid += instructionWords[wid] >> 16; - // } - //} - //return false; } } - int GetGroupOrder(int wid) + readonly int GetGroupOrder(int wid) { - var op = (SDSLOp)(instructionWords[wid] & 0xFFFF); - return InstructionInfo.GetGroupOrder(op, op == SDSLOp.OpVariable ? (StorageClass)instructionWords[wid + 3] : null); + var op = (SDSLOp)(InstructionWords[wid] & 0xFFFF); + return InstructionInfo.GetGroupOrder(op, op == SDSLOp.OpVariable ? (StorageClass)InstructionWords[wid + 3] : null); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs similarity index 75% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs index 0ac1e94488..67f57f6fc2 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs @@ -1,18 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; +namespace Stride.Shaders.Spirv.Core.Parsing; /// /// A spirv header parser /// -public ref struct RefHeader +public readonly ref struct RefHeader { - Span Words { get; init; } + internal Span Words { get; init; } public uint MagicNumber { get => unchecked((uint)Words[0]); set => Words[0] = unchecked((int)value); } public SpirvVersion VersionNumber { get => Words[1]; set => Words[1] = value; } public int GeneratorMagicNumber { get => Words[2]; set => Words[2] = value; } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs new file mode 100644 index 0000000000..e0dc3b5a80 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs @@ -0,0 +1,44 @@ +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// Instruction enumerator returning RefInstruction +/// +public ref struct RefInstructionEnumerator +{ + int wordIndex; + int index; + readonly Span words; + readonly bool hasHeader; + + public readonly RefInstruction Current => + RefInstruction.ParseRef( + words.Slice(wordIndex, words[wordIndex] >> 16), + wordIndex + (hasHeader ? 5 : 0), + index + ); + + public RefInstructionEnumerator(Span words, bool hasHeader) + { + wordIndex = -1; + index = 0; + this.words = words; + this.hasHeader = hasHeader; + } + + public bool MoveNext() + { + if (wordIndex == -1) + { + wordIndex = 0; + return true; + } + else + { + if (wordIndex + (words[wordIndex] >> 16) >= words.Length) + return false; + wordIndex += words[wordIndex] >> 16; + index += 1; + return true; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs similarity index 97% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index c229c0896f..6d1855bfb0 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -10,7 +10,7 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// /// Spirv version wrapper to interact through string/integers /// -public struct SpirvVersion +public readonly struct SpirvVersion { public int Version { get; } @@ -39,7 +39,7 @@ public SpirvVersion(string version) /// /// Spirv Header struct for spirv assembling /// -public struct SpirvHeader +public readonly struct SpirvHeader { public uint MagicNumber { get; init; } public SpirvVersion VersionNumber { get; init; } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs similarity index 76% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index d1aea8809f..1e489e6316 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -13,9 +13,9 @@ public static void ParseToList(byte[] byteCode, List instructions) { var span = MemoryMarshal.Cast(byteCode.AsSpan()); - var data = new WordBuffer(span); + var data = new SpirvBuffer(span); foreach (var instruction in data) - instructions.Add(instruction); + instructions.Add(instruction.ToOwned(data)); } @@ -45,28 +45,24 @@ public SpirvReader(Memory slice) buffer = new(slice.Span); //data = slice; } + public SpirvReader(SpirvSpan span) + { + buffer = span; + //data = slice; + } - public SpirvSpan.Enumerator GetEnumerator() => new(buffer.Span); + public readonly RefInstructionEnumerator GetEnumerator() => new(buffer.Span, HasHeader); - public int GetInstructionCount() + public readonly int GetInstructionCount() { var count = 0; var index = 0; while(index < buffer.Length) { count += 1; - index += buffer[index] >> 16; + index += buffer.Span[index] >> 16; } return count; } - - public int ComputeBound() - { - var result = 0; - foreach(var e in this) - if(e.ResultId != null && e.ResultId > result) - result = e.ResultId.Value; - return result; - } } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs similarity index 68% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs rename to src/Stride.Shaders.Spirv.Core/RefInstruction.cs index 8e992b8909..711f5358fe 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -1,4 +1,6 @@ +using System.Security.Cryptography; using System.Text; +using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; using static Spv.Specification; @@ -11,7 +13,7 @@ namespace Stride.Shaders.Spirv.Core; public ref struct RefInstruction { - public static RefInstruction Empty => new() { Words = Span.Empty, Operands = Span.Empty }; + public static RefInstruction Empty => new() { Words = [], Operands = [] }; /// @@ -24,12 +26,11 @@ public ref struct RefInstruction public int? ResultType { get => GetResultType(); set => SetResultType(value); } public Span Operands { get; init; } public Memory? Slice { get; init; } - public int OwnerIndex { get; set; } + public int InstructionIndex { get; set; } + public int WordIndex { get; set; } public Span Words { get; init; } - - - public bool IsEmpty => Words == Span.Empty; + public readonly bool IsEmpty => Words.IsEmpty; @@ -56,23 +57,55 @@ public ref struct RefInstruction return null; } - public static RefInstruction Parse(Memory owner, int ownerIndex) + public bool TryGetOperand(string name, out T? operand) + where T : struct, IFromSpirv + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + operand = operandEnumerator.Current.To(); + return true; + } + } + } + operand = null; + return false; + } + + public static RefInstruction Parse(Memory owner, int ownerIndex, int index) { var words = owner.Span.Slice(ownerIndex, owner.Span[ownerIndex] >> 16); return new RefInstruction() { Operands = words[1..], - OwnerIndex = ownerIndex, + WordIndex = ownerIndex, + InstructionIndex = index, Slice = owner, Words = words }; } - public static RefInstruction ParseRef(Span words) + // public static RefInstruction ParseRef(ReadOnlySpan words) + // { + // return new RefInstruction() + // { + // Operands = words[1..], + // Words = words, + // }; + // } + public static RefInstruction ParseRef(Span words, int? wordIndex = null, int? index = null) { return new RefInstruction() { - Operands = words[1..], Words = words, + WordIndex = wordIndex ?? -1, + InstructionIndex = index ?? -1, + Operands = words[1..] }; } @@ -126,8 +159,11 @@ public void OffsetIds(int offset) } } - - + public readonly Instruction ToOwned(SpirvBuffer buffer) + { + if(InstructionIndex == -1) throw new Exception("Instruction not found"); + return new(buffer, buffer.Memory[WordIndex..(WordIndex + WordCount)], InstructionIndex, WordIndex); + } public override string ToString() { diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/SpvLiteral.cs rename to src/Stride.Shaders.Spirv.Core/SpvLiteral.cs diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj similarity index 80% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj rename to src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 17dc13560f..10f39ad242 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -9,10 +9,10 @@ - + - + diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs new file mode 100644 index 0000000000..a9dde24d44 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -0,0 +1,55 @@ +using System.Text.Json.Serialization; + +namespace Stride.Shaders.Spirv.Generators; + + +public struct OpKind +{ + [JsonPropertyName("kind")] + public string Kind { get; set; } + [JsonPropertyName("category")] + public string Category { get; set; } +} + + +public struct OperandData +{ + [JsonPropertyName("kind")] + public string Kind { get; set; } + [JsonPropertyName("name")] + public string? Name { get; set; } + [JsonPropertyName("quantifier")] + public string? Quantifier { get; set; } +} + +public struct InstructionData +{ + [JsonPropertyName("opname")] + public string OpName { get; set; } + [JsonPropertyName("class")] + public string Class { get; set; } + [JsonPropertyName("opcode")] + public int OpCode { get; set; } + [JsonPropertyName("operands")] + public List Operands { get; set; } + [JsonPropertyName("version")] + public string Version { get; set; } +} + +public class SpirvGrammar +{ + [JsonPropertyName("magic_number")] + public string MagicNumber { get; set; } = ""; + [JsonPropertyName("major_version")] + public int MajorVersion { get; set; } + [JsonPropertyName("minor_version")] + public int MinorVersion { get; set; } + [JsonPropertyName("revision")] + public int Revision { get; set; } + + [JsonPropertyName("instructions")] + public List Instructions { get; set; } = []; + + [JsonPropertyName("operand_kinds")] + public List OperandKinds { get; set; } = []; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json rename to src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs rename to src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs new file mode 100644 index 0000000000..a25e129a44 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -0,0 +1,160 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; +using System.Runtime.InteropServices.ComTypes; + +namespace Stride.Shaders.Spirv.Generators; +public partial class SPVGenerator +{ + + + public void CreateInfo(IncrementalGeneratorInitializationContext context) + { + + GenerateKinds(context); + + var code = new StringBuilder(); + + code + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public partial class InstructionInfo") + .AppendLine("{") + + .AppendLine("static InstructionInfo()") + .AppendLine("{") + ; + + + foreach (var instruction in spirvCore!.Instructions) + { + GenerateInfo(instruction, code); + } + foreach (var instruction in spirvSDSL!.Instructions) + { + GenerateInfo(instruction, code); + } + code + .AppendLine("Instance.InitOrder();") + + .AppendLine("}") + + .AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); + } + + private void GenerateKinds(IncrementalGeneratorInitializationContext context) + { + var code = new StringBuilder() + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("\n\n") + .AppendLine("public enum OperandKind") + .AppendLine("{") + + .AppendLine("None = 0,"); + var kinds = spirvCore!.OperandKinds.Select(x => x.Kind); + foreach (var kind in kinds) + { + code.Append(kind).AppendLine(","); + } + code.AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); + + } + + public void GenerateInfo(InstructionData op, StringBuilder code) + { + var opname = op.OpName; + var spvClass = op.Class; + if (opname == "OpExtInst") + { + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); + code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); + } + else if (op.Operands is List operands) + { + foreach (var operand in operands) + { + // var hasKind = operand.Kind; + // var hasQuant = operand.Quantifier; + // var hasName = operand.Name; + + if (operand.Kind is string kind) + { + if (operand.Quantifier is string quant) + { + code + .Append("Instance.Register(SDSLOp.") + .Append(opname) + .Append(", OperandKind.") + .Append(kind) + .Append(", OperandQuantifier.") + .Append(ConvertQuantifier(quant)) + .Append(", ") + .Append(operand.Name is null ? $"\"{ConvertNameQuantToName(kind, quant)}\"" : $"\"{ConvertNameQuantToName(operand.Name, quant)}\"") + .Append($", \"{spvClass}\"") + .AppendLine(");"); + } + else + { + code + .Append("Instance.Register(SDSLOp.") + .Append(opname) + .Append(", OperandKind.") + .Append(kind) + .Append(", OperandQuantifier.One, ") + .Append(operand.Name is null ? $"\"{ConvertKindToName(kind)}\"" : $"\"{ConvertOperandName(operand.Name)}\"") + .Append($", \"{spvClass}\"") + .AppendLine(");"); + } + + } + } + } + else + { + code.Append("Instance.Register(SDSLOp.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); + } + } + + public static string ConvertNameQuantToName(string name, string quant) + { + return (name, quant) switch + { + (_, "*") => "values", + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + _ => name.Replace("'", "").ToLowerInvariant() + }; + } + + public static string ConvertQuantifier(string quant) + { + if (quant == "*") + return "ZeroOrMore"; + else if (quant == "?") + return "ZeroOrOne"; + else return "One"; + } +} + diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs new file mode 100644 index 0000000000..14cc5072be --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs @@ -0,0 +1,189 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; + +namespace Stride.Shaders.Spirv.Generators; + + +public static class ListExtensions +{ + public static void AddUnique(this List list, string name) + { + if (list.Contains(name)) + list.Add(name + list.Where(x => x.StartsWith(name)).Count()); + else + list.Add(name); + } +} + +public partial class SPVGenerator +{ + + + public List ConvertOperandsToParameters(InstructionData op) + { + var opname = op.OpName; + var operands = op.Operands; + List parameters = []; + foreach (var e in operands) + { + var kind = e.Kind; + var realKind = ConvertKind(kind!); + if (e.Quantifier is not null) + { + if (e.Name is string name) + { + if (e.Quantifier == "?") + parameters.AddUnique(realKind + "? " + ConvertOperandName(name)); + else if (e.Quantifier == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } + else + { + if (e.Quantifier == "?") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind!)); + else if (e.Quantifier == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } + } + else + { + if (e.Name is not null) + parameters.AddUnique(realKind + " " + ConvertOperandName(e.Name)); + else if (kind == "IdResult" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else if (kind == "IdResultType" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else + parameters.AddUnique(realKind + " " + ConvertKindToName(kind!)); + } + } + if (parameters.Any(x => x.Contains("resultType")) && parameters.Any(x => x.Contains("resultId"))) + { + var resultType = parameters[0]; + var resultId = parameters[1]; + parameters[0] = resultId; + parameters[1] = resultType; + } + return parameters; + } + + public List ConvertOperandsToParameterNames(InstructionData op) + { + var opname = op.OpName; + var operands = op.Operands; + List parameters = new(op.Operands.Count); + foreach (var e in operands) + { + var kind = e.Kind; + var realKind = ConvertKind(kind!); + if (e.Quantifier is string quant) + { + if (e.Name is string name) + { + if (quant == "?") + parameters.AddUnique(ConvertOperandName(name)); + else if (quant == "*") + parameters.AddUnique("values"); + } + else + { + if (quant == "?") + parameters.AddUnique(ConvertKindToName(kind!)); + else if (quant == "*") + parameters.AddUnique("values"); + } + } + else + { + if (e.Name is string name) + parameters.AddUnique(ConvertOperandName(name)); + else + parameters.AddUnique(ConvertKindToName(kind)); + } + } + return parameters; + } + + public string ConvertKind(string kind) + { + var opKind = operandKinds[kind]; + + return (opKind.Kind, opKind.Category) switch + { + ("LiteralInteger", _) => "LiteralInteger", + ("LiteralFloat", _) => "LiteralFloat", + ("LiteralString", _) => "LiteralString", + ( _ , "BitEnum") => kind + "Mask", + ("LiteralExtInstInteger", _) => "LiteralInteger", + ("LiteralSpecConstantOpInteger", _) => "Op", + _ => kind + }; + } + + public static string ConvertKindToName(string kind) + { + return kind switch + { + "IdRef" => "id", + "IdResult" => "resultId", + "IdResultType" => "resultType", + _ => kind.ToLower() + }; + } + + public static string ConvertOperandName(string input, string? quant = null) + { + if (string.IsNullOrEmpty(input)) + { + return string.Empty; + } + var result = ""; + bool firstLetterHit = false; + for (int i = 0; i < input.Length; i++) + { + + if (char.IsLetterOrDigit(input[i]) || input[i] == '_') + { + if (!firstLetterHit) + { + firstLetterHit = true; + result += char.ToLowerInvariant(input[i]); + } + else + result += input[i]; + } + + } + return (result, quant) switch + { + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + ("IdResult", _) => "resultId", + ("IdResultType", _) => "resultType", + ("IdRef", "*") => "id", + ("IdRef", "?") => "id", + ("IdRef", null) => "id", + ("LiteralInteger", _) => "", + ("LiteralFloat", _) => "", + ("LiteralString", _) => "", + ("Dim", _) => "", + ("ImageFormat", _) => "", + ("ExecutionMode", _) => "", + ("ExecutionModel", _) => "", + _ => result + }; + } +} + diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs new file mode 100644 index 0000000000..f04e3bdc31 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -0,0 +1,58 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp; + +namespace Stride.Shaders.Spirv.Generators; +public partial class SPVGenerator +{ + public void CreateSDSLOp(IncrementalGeneratorInitializationContext context) + { + var code = new StringBuilder(); + var nsProvider = context + .SyntaxProvider + .CreateSyntaxProvider( + predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), + transform: (node, _) => (NamespaceDeclarationSyntax)node.Node + ); + context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => + { + var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); + var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue!.Value.ToString())); + var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue!.Value.ToString())).Max(); + + foreach (var e in spirvSDSL!.Instructions.Select(x => x.OpName)) + members.Add(e!, ++lastnum); + + code + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + foreach (var e in members) + code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); + code + .AppendLine("}"); + + + ctx.AddSource("SDSLOp.gen.cs", code.ToSourceText()); + }); + + } + public static int ParseInteger(string text) + { + if (text.StartsWith("0x")) + return int.Parse(text.Substring(2), System.Globalization.NumberStyles.HexNumber); + else + return int.Parse(text); + } +} diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs new file mode 100644 index 0000000000..99ccf16bf6 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -0,0 +1,340 @@ +using AngleSharp.Dom; +using Microsoft.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices.ComTypes; +using System.Text; +using System.Text.Json; +using AngleSharp; + +namespace Stride.Shaders.Spirv.Generators; + + +[Generator] +public partial class SPVGenerator : IIncrementalGenerator +{ + SpirvGrammar? spirvCore; + SpirvGrammar? spirvGlsl; + SpirvGrammar? spirvSDSL; + + IDocument? unifiedDoc; + IDocument? glslDoc; + + Dictionary operandKinds = []; + + public void Initialize(IncrementalGeneratorInitializationContext context) + { + // #if DEBUG + // if (!Debugger.IsAttached) + // Debugger.Launch(); + // #endif + var assembly = typeof(SPVGenerator).GetTypeInfo().Assembly; + string resourceCoreName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("spirv.core.grammar.json")); + + string resourceGlslName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("extinst.glsl.std.450.grammar.json")); + + string resourceSDSLName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("spirv.sdsl.grammar-ext.json")); + + string resourceUnifiedName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("SPIRV.html")); + string resourceGlslRegistryName = + assembly.GetManifestResourceNames() + .Single(str => str.EndsWith("GLSL.std.450.html")); + + + + + spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd()); + spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd()); + spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd()); + + var config = Configuration.Default.WithDefaultLoader(); + var htmlContext = BrowsingContext.New(config); + var documentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceUnifiedName)).ReadToEnd())); + documentTask.Wait(); + unifiedDoc = documentTask.Result; + var glslDocumentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceGlslRegistryName)).ReadToEnd())); + glslDocumentTask.Wait(); + glslDoc = glslDocumentTask.Result; + + foreach (var o in spirvCore!.OperandKinds) + operandKinds[o.Kind] = o; + + CreateInfo(context); + CreateSDSLOp(context); + + var code = new StringBuilder(); + + code + .AppendLine("using static Spv.Specification;") + .AppendLine("namespace Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("") + .AppendLine("public static class SpirvBufferExtensions") + .AppendLine("{"); + + var instructions = spirvCore!.Instructions; + var sdslInstructions = spirvSDSL!.Instructions; + var glslInstruction = spirvGlsl!.Instructions; + + instructions.ForEach(x => CreateOperation(x, code)); + sdslInstructions.ForEach(x => CreateOperation(x, code)); + glslInstruction.ForEach(x => CreateGlslOperation(x, code)); + + code.AppendLine("}"); + + context.RegisterPostInitializationOutput(ctx => + { + ctx.AddSource( + "SpirvBufferExtensions.gen.cs", + code.ToSourceText()); + }); + } + + public static string AddDocComment(IHtmlCollection? cells) + { + var code = new StringBuilder(); + if (cells.FirstOrDefault() is IElement element) + { + var split = element.TextContent.Split('\n'); + code.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); + foreach (var t in split.Skip(1)) + if(!string.IsNullOrEmpty(t)) + code.Append("/// ") + .Append(t.Replace("", "id")) + .AppendLine(""); + code.AppendLine("/// "); + } + return code.ToString(); + } + + public void CreateOperation(InstructionData op, StringBuilder code) + { + var opname = op.OpName; + var cells = unifiedDoc!.QuerySelectorAll($"p.tableblock:has(#{opname})"); + var comment = AddDocComment(cells); + code.AppendLine(comment); + if (opname == "OpConstant") + { + code + .AppendLine("public static Instruction AddOpConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + + .AppendLine("}"); + + + code.AppendLine(comment); + code + .AppendLine("public static Instruction InsertOpConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + + .AppendLine("}"); + + } + else if (opname == "OpSpecConstant") + { + code + .AppendLine("public static Instruction AddOpSpecConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("}"); + code.AppendLine(comment); + code + .AppendLine("public static Instruction InsertOpSpecConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("}"); + } + else if (opname!.StartsWith("OpDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + code.AppendLine(comment); + code + .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + } + else if (opname.StartsWith("OpMemberDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + code.AppendLine(comment); + code + .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + } + + else if (op.Operands is not null && op.Operands.Count > 0) + { + var parameters = ConvertOperandsToParameters(op); + var parameterNames = ConvertOperandsToParameterNames(op); + var hasResultId = parameterNames.Contains("resultId") && opname != "OpExtInst"; + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + var paramsParameters = parameters.Where(x => x.StartsWith("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.StartsWith("Span")); + + code + .Append("public static Instruction Add") + .Append(opname) + .Append("(this SpirvBuffer buffer") + .Append(hasResultId ? ", IdResult resultId" : "") + .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + ; + code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); + code + .AppendLine($"return buffer.Add([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine("}"); + + + + code.AppendLine(comment); + code + .Append("public static Instruction Insert") + .Append(opname) + .Append("(this SpirvBuffer buffer, int position") + .Append(hasResultId ? ", IdResult resultId" : "") + .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + ; + code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); + code + .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine("}"); + } + else + { + code + .Append("public static Instruction Add") + .Append(opname) + .AppendLine("(this SpirvBuffer buffer)") + .AppendLine("{") + + .AppendLine($"return buffer.Add([1 << 16 | (int)SDSLOp.{opname}]);") + + .AppendLine("}"); + code.AppendLine(comment); + code + .Append("public static Instruction Insert") + .Append(opname) + .AppendLine("(this SpirvBuffer buffer, int position)") + .AppendLine("{") + .AppendLine($"return buffer.Insert(position, [1 << 16 | (int)SDSLOp.{opname}]);") + .AppendLine("}"); + } + } + + public void CreateGlslOperation(InstructionData op, StringBuilder code) + { + var opname = op.OpName; + var opcode = op.OpCode; + + if (op.Operands is not null) + { + var parameters = ConvertOperandsToParameters(op); + parameters.Add("int set"); + + var parameterNames = ConvertOperandsToParameterNames(op); + parameterNames.Add("set"); + + var hasResultId = parameterNames.Contains("resultId"); + + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + + var paramsParameters = parameters.Where(x => x.Contains("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); + var other = parameterNames.Where(x => x != "resultType" && x != "resultId" && x != "set"); + + var cells = glslDoc!.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{opname}\"))"); + var comment = AddDocComment(cells); + code.AppendLine(comment); + code + .Append("public static Instruction AddGLSL") + .Append(opname) + .Append("(this SpirvBuffer buffer, IdResultType resultType, int resultId, ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") + .Append("return buffer.AddOpExtInst(") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + .AppendLine("}"); + + code.AppendLine(comment); + code + .Append("public static Instruction InsertGLSL") + .Append(opname) + .Append("(this SpirvBuffer buffer, int position, IdResultType resultType, int resultId, ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") + .Append("return buffer.InsertOpExtInst(position, ") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + .AppendLine("}"); + } + } +} diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj new file mode 100644 index 0000000000..05fefad5fa --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -0,0 +1,54 @@ + + + + netstandard2.0 + latest + enable + enable + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(GetTargetPathDependsOn);GetDependencyTargetPaths + + + + + + + + + + + + + + + diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md deleted file mode 100644 index 3d23457e29..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report-github.md +++ /dev/null @@ -1,16 +0,0 @@ -``` ini - -BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update) -Intel Core i5-8265U CPU 1.60GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores -.NET SDK=7.0.100 - [Host] : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2 - DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2 - - -``` -| Method | Mean | Error | StdDev | Median | Allocated | -|------------ |---------------:|--------------:|--------------:|---------------:|----------:| -| MemorySlice | 0.6161 ns | 0.0977 ns | 0.2803 ns | 0.5250 ns | - | -| Count | 11.0984 ns | 0.4045 ns | 1.1606 ns | 10.9187 ns | - | -| Parse | 36,396.4577 ns | 1,022.9391 ns | 2,851.5453 ns | 35,373.0682 ns | - | -| ParseToList | 46,043.3036 ns | 732.9096 ns | 649.7052 ns | 45,818.8660 ns | - | diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv deleted file mode 100644 index 7e0700c1f9..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.csv +++ /dev/null @@ -1,5 +0,0 @@ -Method;Job;AnalyzeLaunchVariance;EvaluateOverhead;MaxAbsoluteError;MaxRelativeError;MinInvokeCount;MinIterationTime;OutlierMode;Affinity;EnvironmentVariables;Jit;LargeAddressAware;Platform;PowerPlanMode;Runtime;AllowVeryLargeObjects;Concurrent;CpuGroups;Force;HeapAffinitizeMask;HeapCount;NoAffinitize;RetainVm;Server;Arguments;BuildConfiguration;Clock;EngineFactory;NuGetReferences;Toolchain;IsMutator;InvocationCount;IterationCount;IterationTime;LaunchCount;MaxIterationCount;MaxWarmupIterationCount;MemoryRandomization;MinIterationCount;MinWarmupIterationCount;RunStrategy;UnrollFactor;WarmupCount;Mean;Error;StdDev;Median;Allocated -MemorySlice;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;0.6161 ns;0.0977 ns;0.2803 ns;0.5250 ns;0 B -Count;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;11.0984 ns;0.4045 ns;1.1606 ns;10.9187 ns;0 B -Parse;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;"36,396.4577 ns";"1,022.9391 ns";"2,851.5453 ns";"35,373.0682 ns";0 B -ParseToList;DefaultJob;False;Default;Default;Default;Default;Default;Default;11111111;Empty;RyuJit;Default;X64;8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c;.NET 7.0;False;True;False;True;Default;Default;False;False;False;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;Default;16;Default;"46,043.3036 ns";732.9096 ns;649.7052 ns;"45,818.8660 ns";0 B diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html deleted file mode 100644 index 59f2680c50..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/BenchmarkDotNet.Artifacts/results/SoftTouch.Spirv.Core.Benchmarks.ParserBench-report.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Stride.Shaders.Spirv.Core.Benchmarks.ParserBench-20230502-153328 - - - - -

-BenchmarkDotNet=v0.13.5, OS=Windows 10 (10.0.19045.2846/22H2/2022Update)
-Intel Core i5-8265U CPU 1.60GHz (Whiskey Lake), 1 CPU, 8 logical and 4 physical cores
-.NET SDK=7.0.100
-  [Host]     : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
-  DefaultJob : .NET 7.0.0 (7.0.22.51805), X64 RyuJIT AVX2
-
-
- - - - - - - - -
Method Mean Error StdDev MedianAllocated
MemorySlice0.6161 ns0.0977 ns0.2803 ns0.5250 ns-
Count11.0984 ns0.4045 ns1.1606 ns10.9187 ns-
Parse36,396.4577 ns1,022.9391 ns2,851.5453 ns35,373.0682 ns-
ParseToList46,043.3036 ns732.9096 ns649.7052 ns45,818.8660 ns-
- - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs deleted file mode 100644 index cabd401f2c..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/ParserBench.cs +++ /dev/null @@ -1,55 +0,0 @@ -using BenchmarkDotNet.Attributes; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.PortableExecutable; -using System.Text; -using System.Threading.Tasks; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; -using CommunityToolkit.HighPerformance.Buffers; -using System.Runtime.InteropServices; - -namespace Stride.Shaders.Spirv.Core.Benchmarks; - -[MemoryDiagnoser] -public class ParserBench -{ - public MemoryOwner shader; - public List instructions; - - public ParserBench() - { - - - } - - - // [Benchmark] - // public void MemorySlice() - // { - // var slice = shader.Memory[5..]; - // } - // [Benchmark] - // public void Count() - // { - // var reader = new SpirvReader(shader); - // var count = reader.Count; - // } - - // [Benchmark] - // public void Parse() - // { - // var reader = new SpirvReader(shader); - // foreach (var i in reader) - // { - - // } - // } - // [Benchmark] - // public void ParseToList() - // { - // SpirvReader.ParseToList(shader, instructions); - // instructions.Clear(); - // } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs deleted file mode 100644 index e4d72d2900..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Program.cs +++ /dev/null @@ -1,10 +0,0 @@ -// See https://aka.ms/new-console-template for more information -using BenchmarkDotNet; -using BenchmarkDotNet.Running; -using Stride.Shaders.Spirv.Core.Benchmarks; - -BenchmarkRunner.Run(); - -Console.WriteLine("Hello, World!"); - - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj deleted file mode 100644 index e49df807a6..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core.Benchmarks/Stride.Shaders.Spirv.Core.Benchmarks.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - net9.0 - enable - enable - - - - - - - - - - - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs deleted file mode 100644 index db91312f37..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Bound.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core; - -/// -/// Represents the index bound for instructions in a spirv module -/// -public struct Bound -{ - public int Offset { get; set; } - public int Count { get; set; } - - public Bound() - { - Offset = 0; - Count = 0; - } - - public int Next() - { - Count += 1; - return Offset + Count; - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs deleted file mode 100644 index 0c5509acc3..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/BufferBase.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Numerics; -using System.Runtime.InteropServices; -using CommunityToolkit.HighPerformance.Buffers; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A disposable buffer wrapper using the HighPerformance toolkit. -/// -/// -public abstract class BufferBase - where T : struct -{ - internal MemoryOwner _owner = MemoryOwner.Empty; - /// - /// Span accessor of the data represented by the buffer - /// - public virtual Span Span => _owner.Span[..Length]; - /// - /// Memory accessor of the data represented by the buffer - /// - public virtual Memory Memory => _owner.Memory[..Length]; - /// - /// Corresponding bytes - /// - public Span Bytes => MemoryMarshal.AsBytes(Span); - /// - /// Length of the buffer - /// - public int Length { get; protected set; } - public void Dispose() => _owner.Dispose(); -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs deleted file mode 100644 index 073f40f249..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ExpandableBuffer.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System.Numerics; -using CommunityToolkit.HighPerformance.Buffers; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A buffer that works similarly to List -/// -/// -public class ExpandableBuffer : BufferBase - where T : struct -{ - - public ExpandableBuffer() - { - _owner = MemoryOwner.Allocate(4, AllocationMode.Clear); - Length = 0; - } - - public ExpandableBuffer(int initialCapacity) - { - _owner = MemoryOwner.Allocate(initialCapacity, AllocationMode.Clear); - Length = 0; - } - /// - /// Expands the buffer by the size demanded. It allocates a new underlying array when needed. - /// - /// - private void Expand(int size) - { - if(Length + size > _owner.Length) - { - var n = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)(Length + size)), AllocationMode.Clear); - _owner.Span.CopyTo(n.Span); - var toDispose = _owner; - _owner = n; - toDispose.Dispose(); - } - } - /// - /// Adds an element to the buffer - /// - /// - public void Add(T item) - { - Expand(1); - _owner.Span[Length] = item; - Length += 1; - } - /// - /// Adds many elements to the buffer - /// - /// - public void Add(Span items) - { - Expand(items.Length); - items.CopyTo(_owner.Span[Length..]); - Length += items.Length; - } - /// - /// Inserts many elements at a specific place in the buffer - /// - /// - /// - public void Insert(int start, Span words) - { - Expand(words.Length); - var slice = _owner.Span[start..Length]; - slice.CopyTo(_owner.Span[(start + words.Length)..]); - words.CopyTo(_owner.Span.Slice(start, words.Length)); - Length += words.Length; - } - - /// - /// Remove an element from the buffer - /// - /// - /// - public bool RemoveAt(int index) - { - if(index < Length && index > 0) - { - Span[(index+1)..].CopyTo(Span[index..]); - Length -= 1; - return true; - } - return false; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs deleted file mode 100644 index 1c5a0aa745..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A spirv buffer object -/// -public interface ISpirvBuffer -{ - Span Span { get; } - Memory Memory { get; } - Span InstructionSpan { get; } - Memory InstructionMemory { get; } - - bool HasHeader { get; } - - public Instruction this[int index] {get;} - - public SpirvSpan AsSpan(); - public SpirvMemory AsMemory(); -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs deleted file mode 100644 index 5fdcc5abae..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/FunctionBufferCollection.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Collections; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A collection of function buffers, usable through the MultiBuffer class -/// -public class FunctionBufferCollection -{ - bool functionStarted; - public SortedList Buffers { get; } - public WordBuffer? Current => functionStarted ? Buffers.Values[^1] : null; - - public FunctionsInstructions Instructions => new(this); - - public int BuffersLength => Buffers.Sum(static (x) => x.Value.Length); - public int FunctionCount => Buffers.Count; - - public WordBuffer this[string name] => Buffers[name]; - - public FunctionBufferCollection() - { - functionStarted = false; - Buffers = new(); - } - - public IEnumerator> GetEnumerator() => Buffers.GetEnumerator(); - - - public Instruction Insert(MutRefInstruction instruction, string? functionName = null) - { - if(!functionStarted) - { - if (instruction.OpCode != SDSLOp.OpFunction || functionName == null) - throw new Exception("A function should be started with SDSLOp.OpFunction"); - Buffers.Add(functionName, new()); - functionStarted = true; - } - Instruction? result = Current?.Add(instruction); - if(instruction.OpCode == SDSLOp.OpFunctionEnd) - { - functionStarted = false; - } - return result ?? throw new Exception("The instruction was not inserted"); - } - - public void Add(string name, WordBuffer function) - { - Buffers.Add(name, function); - } - - public struct FunctionsInstructions - { - FunctionBufferCollection buffers; - public FunctionsInstructions(FunctionBufferCollection buffers) - { - this.buffers = buffers; - } - - - public Enumerator GetEnumerator() => new(buffers); - - public ref struct Enumerator - { - FunctionBufferCollection buffers; - IEnumerator> lastBuffer; - InstructionEnumerator lastEnumerator; - bool started; - public Enumerator(FunctionBufferCollection buffers) - { - this.buffers = buffers; - lastBuffer = buffers.GetEnumerator(); - started = false; - } - - public Instruction Current => lastEnumerator.Current; - - public bool MoveNext() - { - if (!started) - { - started = true; - if (!lastBuffer.MoveNext()) - return false; - lastEnumerator = new(lastBuffer.Current.Value); - while (!lastEnumerator.MoveNext()) - { - if (!lastBuffer.MoveNext()) - return false; - lastEnumerator = new(lastBuffer.Current.Value); - } - return true; - } - else - { - if (lastEnumerator.MoveNext()) - return true; - else - { - while (lastBuffer.MoveNext()) - { - lastEnumerator = new(lastBuffer.Current.Value); - if (lastEnumerator.MoveNext()) - return true; - } - } - return false; - } - } - } - } - - - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs deleted file mode 100644 index 706a53d686..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.LocalVariables.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Transactions; - -namespace Stride.Shaders.Spirv.Core.Buffers; - - - -public sealed partial class MultiBuffer -{ - public MultiBufferLocalVariables LocalVariables => new(this); - - /// - /// Representation of local variables of the current function being written. - /// - public ref struct MultiBufferLocalVariables - { - MultiBuffer buffer; - public MultiBufferLocalVariables(MultiBuffer buffer) - { - this.buffer = buffer; - } - - public Instruction this[string name] - { - get - { - if(TryGet(name, out var instruction)) - return instruction; - throw new Exception($"Variable {name} not found"); - } - } - /// - /// Finds the last varibale with a specific name. - /// - /// - /// - /// - /// - public readonly bool TryGet(string name, out Instruction instruction) - { - var found = false; - instruction = Instruction.Empty; - if (buffer.Functions.Current == null) - throw new Exception("Not in function scope"); - var filtered = new LambdaFilteredEnumerator(buffer.Functions.Current, static (i) => i.OpCode == SDSLOp.OpSDSLVariable || i.OpCode == SDSLOp.OpSDSLFunctionParameter); - while (filtered.MoveNext()) - { - var vname = filtered.Current.GetOperand("name"); - if (vname?.Value == name) - { - instruction = filtered.Current; - found = true; - } - } - return found; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs deleted file mode 100644 index 31f59ad7f4..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.Variables.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Transactions; - -namespace Stride.Shaders.Spirv.Core.Buffers; - - - -public sealed partial class MultiBuffer -{ - public MultiBufferGlobalVariables GlobalVariables => new(this); - - public ref struct MultiBufferGlobalVariables - { - MultiBuffer buffer; - public MultiBufferGlobalVariables(MultiBuffer buffer) - { - this.buffer = buffer; - } - - public Instruction this[string name] - { - get - { - if(TryGet(name, out var instruction)) - return instruction; - throw new Exception($"Variable {name} does not exist"); - } - } - - public readonly bool TryGet(string name, out Instruction instruction) - { - var filtered = new LambdaFilteredEnumerator(buffer.Declarations, static (i) => i.OpCode == SDSLOp.OpSDSLVariable || i.OpCode == SDSLOp.OpSDSLIOVariable); - while (filtered.MoveNext()) - { - if (filtered.Current.GetOperand("name")?.Value == name) - { - instruction = filtered.Current; - return true; - } - } - instruction = Instruction.Empty; - return false; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs deleted file mode 100644 index 724ed3489f..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Multi/MultiBuffer.cs +++ /dev/null @@ -1,214 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Text; -using System.Transactions; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Buffers; - - -/// -/// A spirv buffer composed of many different buffers for declarations and functions -/// -public sealed partial class MultiBuffer : IMutSpirvBuffer -{ - public int Bound { get; private set; } - public int Length => Declarations.Length + Functions.BuffersLength; - - public WordBuffer Declarations { get; init; } - public FunctionBufferCollection Functions { get; init; } - - public MultiBufferInstructions Instructions => new(this); - - public MultiBuffer() - { - Declarations = new(); - Functions = new(); - } - - public Instruction Add(MutRefInstruction instruction) - { - if (instruction.OpCode == SDSLOp.OpSDSLFunction) - { - var name = instruction.GetOperand("functionName"); - var id = instruction.GetOperand("resultId").Value; - Declarations.AddOpName(id, name); - Span words = stackalloc int[5]; - instruction.Words[..5].CopyTo(words); - var funcInstruction = new MutRefInstruction(words); - funcInstruction.OpCode = SDSLOp.OpFunction; - return Functions.Insert(funcInstruction, name.Value); - } - else if(instruction.OpCode == SDSLOp.OpFunction) - { - var n = ""; - foreach(var i in Declarations) - { - if (i.OpCode == SDSLOp.OpName && i.Words.Span[1] == instruction.Words[2]) - n = i.GetOperand("name")?.Value ?? ""; - } - return Functions.Insert(instruction, n); - } - else - { - return InstructionInfo.GetGroupOrder(instruction) switch - { - 13 => Functions.Insert(instruction), - _ => Declarations.Add(instruction) - }; - } - } - public Instruction Duplicate(RefInstruction instruction, int offset = 0) - { - var m = new MutRefInstruction(stackalloc int[instruction.WordCount]); - m.OpCode = instruction.OpCode; - m.WordCount = instruction.WordCount; - instruction.Operands.CopyTo(m.Words[1..]); - if (offset > 0) - { - foreach (var op in m) - { - if ( - op.Kind == OperandKind.IdResult - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.PairIdRefIdRef - || op.Kind == OperandKind.PairIdRefLiteralInteger - ) - op.Words[0] += offset; - if (op.Kind == OperandKind.PairIdRefIdRef || op.Kind == OperandKind.PairLiteralIntegerIdRef) - { - op.Words[1] += offset; - } - } - } - return Add(m); - } - - public int GetNextId() - { - Bound += 1; - return Bound; - } - - internal static int GetWordLength(T? value) - { - if (value is null) return 0; - - return value switch - { - LiteralInteger i => i.WordCount, - LiteralFloat i => i.WordCount, - int _ => 1, - IdRef _ => 1, - IdResultType _ => 1, - IdResult _ => 1, - string v => new LiteralString(v).WordCount, - LiteralString v => v.WordCount, - int[] a => a.Length, - Enum _ => 1, - _ => throw new NotImplementedException() - }; - } - - - public void Dispose() - { - Declarations.Dispose(); - foreach (var function in Functions) - function.Value.Dispose(); - } - - public struct MultiBufferInstructions - { - MultiBuffer buffers; - public MultiBufferInstructions(MultiBuffer buffers) - { - this.buffers = buffers; - } - - public Enumerator GetEnumerator() => new(buffers); - - public ref struct Enumerator - { - MultiBuffer buffers; - OrderedEnumerator declarationEnumerator; - FunctionBufferCollection.FunctionsInstructions.Enumerator functionsEnumerator; - bool started; - bool declarationsFinished; - public Enumerator(MultiBuffer buffers) - { - this.buffers = buffers; - declarationEnumerator = buffers.Declarations.GetEnumerator(); - functionsEnumerator = buffers.Functions.Instructions.GetEnumerator(); - started = false; - declarationsFinished = false; - } - - public Instruction Current => !declarationsFinished ? declarationEnumerator.Current : functionsEnumerator.Current; - - public bool MoveNext() - { - if(!started) - { - started = true; - if (declarationEnumerator.MoveNext()) - return true; - else - declarationsFinished = true; - if (functionsEnumerator.MoveNext()) - return true; - return false; - } - else - { - if(!declarationsFinished) - { - if (declarationEnumerator.MoveNext()) - return true; - else - declarationsFinished = true; - } - return functionsEnumerator.MoveNext(); - } - } - } - } - - public void RecomputeBound() - { - var b = 0; - foreach(var i in Declarations.UnorderedInstructions) - { - var id = i.ResultId; - if (id != null && id > b) - b = id ?? -1; - } - foreach(var (_,f) in Functions) - foreach (var i in f.UnorderedInstructions) - { - var id = i.ResultId; - if (id != null && id > b) - b = id ?? -1; - } - Bound = b + 1; - } - public override string ToString() - { - return - new StringBuilder() - .Append(Disassembler.Disassemble(Declarations)) - .Append(string.Join("\n", Functions.Buffers.Select(x => Disassembler.Disassemble(x.Value)))) - .ToString(); - } - -} - -// public static class MBExtensions -// { -// public static Instruction AddOpDecorate(this MultiBuffer mb, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) -// { -// var wordLength = 1 + MultiBuffer.GetWordLength(target) + MultiBuffer.GetWordLength(decoration) + MultiBuffer.GetWordLength(additional1) + MultiBuffer.GetWordLength(additional2) + MultiBuffer.GetWordLength(additionalString); -// var mri = new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpDecorate, target, (int)decoration, ..additional1.ToSpirvSpanOwner().Span, ..additional2.ToSpirvSpanOwner().Span, ..additionalString.ToSpirvSpanOwner().Span]); -// return mb.Add(mri); -// } -// } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs deleted file mode 100644 index e97a1b1c36..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/UnsortedWordBuffer.cs +++ /dev/null @@ -1,56 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A spirv buffer where instructions are not sorted -/// -public sealed class UnsortedWordBuffer : BufferBase, ISpirvBuffer -{ - public static readonly SortedWordBuffer Empty = new (); - - - public Span InstructionSpan => InstructionMemory.Span; - public Memory InstructionMemory => HasHeader ? Memory[5..] : Memory; - public bool HasHeader => Span[0] == Spv.Specification.MagicNumber; - - public int InstructionCount => new SpirvReader(Memory).Count; - public bool IsEmpty => Span.IsEmpty; - - - public Instruction this[int index] - { - get - { - var enumerator = GetEnumerator(); - int tmp = 0; - while(enumerator.MoveNext() && tmp < index) - tmp += 1; - return enumerator.Current; - } - } - - public InstructionEnumerator GetEnumerator() => new(this); - - public SpirvSpan AsSpan() => new(Span); - public SpirvMemory AsMemory() => new(this); - - - public UnsortedWordBuffer() - { - _owner = MemoryOwner.Empty; - } - - public UnsortedWordBuffer(WordBuffer buffer) - { - _owner = MemoryOwner.Allocate(buffer.Length); - buffer.Span.CopyTo(_owner.Span); - Length = buffer.Length; - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs deleted file mode 100644 index e1f5e7c8eb..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.Parse.cs +++ /dev/null @@ -1,25 +0,0 @@ -using CommunityToolkit.HighPerformance; -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.InteropServices; -using System.Text; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -public partial class WordBuffer -{ - public static WordBuffer Parse(byte[] bytes) - { - WordBuffer buffer = new(bytes.Length / 4); - var ints = MemoryMarshal.Cast(bytes)[5..]; - ints.CopyTo(buffer.Span); - return buffer; - } - - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs deleted file mode 100644 index 9e36f4a6e6..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/Single/WordBuffer.cs +++ /dev/null @@ -1,211 +0,0 @@ -using CommunityToolkit.HighPerformance; -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System.Runtime.InteropServices; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A buffer to assembler spirv byte code. -/// -public sealed partial class WordBuffer : ExpandableBuffer, ISpirvBuffer, IDisposable, IMutSpirvBuffer -{ - public Bound Bound { get; private set; } - public int InstructionCount => new SpirvReader(Memory).Count; - - public Span InstructionSpan => Span; - - public Memory InstructionMemory => Memory; - - public bool HasHeader => false; - - public Memory this[Range range] => Memory[range]; - - public WordBufferInstructions OrderedInstructions => new(this, true); - public WordBufferInstructions UnorderedInstructions => new(this, false); - - - public Instruction this[int index] - { - get - { - int id = 0; - int wid = 0; - while (id < index) - { - wid += Span[wid] >> 16; - id++; - } - return new Instruction(this, Memory[wid..(wid + Span[wid] >> 16)], index, wid); - } - } - public WordBuffer() - { - Bound = new(); - _owner = MemoryOwner.Allocate(32, AllocationMode.Clear); - } - - public WordBuffer(int initialCapacity = 32, int offset = 0) - { - Bound = new() { Offset = offset }; - _owner = MemoryOwner.Allocate(initialCapacity, AllocationMode.Clear); - } - - internal WordBuffer(Span words) - { - _owner = MemoryOwner.Allocate(words.Length, AllocationMode.Clear); - Length = words.Length; - words.CopyTo(Span); - Bound = new(); - } - - public OrderedEnumerator GetEnumerator() => new(this); - - - public int GetNextId() - { - Bound = Bound with { Count = Bound.Count + 1 }; - return Bound.Count + Bound.Offset; - } - public void SetBoundOffset(int offset) - { - Bound = Bound with { Offset = offset }; - } - - - - - public void Insert(Instruction instruction) - { - Insert(Length, instruction.Words.Span); - } - public void Insert(Span instructions, int? start = null) - { - Insert(start ?? Length, instructions); - } - - public Instruction Add(MutRefInstruction instruction) - { - Insert(instruction.Words); - return new(this, InstructionMemory.Slice(Length - instruction.WordCount, instruction.WordCount), InstructionCount - 1, Length - instruction.WordCount); - } - public Instruction Add(MutRefInstruction instruction, int start) - { - Insert(instruction.Words, start); - return new(this, InstructionMemory.Slice(Length - instruction.WordCount, instruction.WordCount), InstructionCount - 1, Length - instruction.WordCount); - } - - public Instruction Duplicate(RefInstruction instruction) - { - var m = new MutRefInstruction(stackalloc int[instruction.WordCount]); - m.OpCode = instruction.OpCode; - m.WordCount = instruction.WordCount; - instruction.Operands.CopyTo(m.Words[1..]); - Add(m); - return new(this, InstructionCount - 1); - } - - - public byte[] GenerateSpirv() - { - var output = new byte[Length * 4 + 5 * 4]; - var span = output.AsSpan(); - var ints = MemoryMarshal.Cast(span); - var instructionWords = ints[5..]; - - var header = new SpirvHeader(new SpirvVersion(1, 3), 0, Bound.Count + 1); - header.WriteTo(ints[0..5]); - var id = 0; - var enumerator = GetEnumerator(); - while (enumerator.MoveNext()) - { - var curr = enumerator.Current; - curr.Words.Span.CopyTo(instructionWords.Slice(id, curr.Words.Length)); - id += curr.Words.Length; - } - return output; - } - - - internal static int GetWordLength(T? value) - { - if (value is null) return 0; - - return value switch - { - LiteralInteger i => i.WordCount, - LiteralFloat i => i.WordCount, - int _ => 1, - IdRef _ => 1, - IdResultType _ => 1, - IdResult _ => 1, - string v => new LiteralString(v).WordCount, - LiteralString v => v.WordCount, - int[] a => a.Length, - Enum _ => 1, - _ => throw new NotImplementedException() - }; - } - - public void RecomputeLength() - { - var wid = 0; - while(wid < _owner.Length) - { - if (_owner.Span[wid] >> 16 == 0) - { - Length = wid; - return; - } - else - wid += _owner.Span[wid] >> 16; - } - } - - public SpirvSpan AsSpan() => new(Span); - public SpirvMemory AsMemory() => new(this); - - - - - public override string ToString() - { - return Disassembler.Disassemble(this); - } - - - public ref struct WordBufferInstructions - { - bool ordered; - WordBuffer buffer; - public WordBufferInstructions(WordBuffer buffer, bool ordered) - { - this.buffer = buffer; - this.ordered = ordered; - } - - public Enumerator GetEnumerator() => new(buffer, ordered); - - public ref struct Enumerator - { - bool ordered; - WordBuffer buffer; - - OrderedEnumerator orderedEnumerator; - InstructionEnumerator unorderedEnumerator; - - public Enumerator(WordBuffer buffer, bool ordered) - { - this.buffer = buffer; - this.ordered = ordered; - if (ordered) - orderedEnumerator = new(buffer); - else - unorderedEnumerator = new(buffer); - } - - public Instruction Current => ordered ? orderedEnumerator.Current : unorderedEnumerator.Current; - public bool MoveNext() => ordered ? orderedEnumerator.MoveNext() : unorderedEnumerator.MoveNext(); - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs deleted file mode 100644 index 2caa23825e..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedFunctionBufferCollection.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Collections; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A collection of function buffers, usable through the MultiBuffer class -/// -public class SortedFunctionBufferCollection -{ - bool functionStarted; - public SortedList Buffers { get; } - public SortedWordBuffer? Current => functionStarted ? Buffers.Values[^1] : null; - - public FunctionsInstructions Instructions => new(this); - - public int BuffersLength => Buffers.Sum(static (x) => x.Value.Length); - - - public SortedFunctionBufferCollection(FunctionBufferCollection functions) - { - Buffers = new(functions.FunctionCount); - foreach(var func in functions.Buffers) - { - Buffers.Add(func.Key, new(func.Value)); - } - } - - public IEnumerator> GetEnumerator() => Buffers.GetEnumerator(); - - public struct FunctionsInstructions - { - SortedFunctionBufferCollection buffers; - public FunctionsInstructions(SortedFunctionBufferCollection buffers) - { - this.buffers = buffers; - } - - - public Enumerator GetEnumerator() => new(buffers); - - public ref struct Enumerator - { - IEnumerator> lastBuffer; - InstructionEnumerator lastEnumerator; - bool started; - public Enumerator(SortedFunctionBufferCollection buffers) - { - lastBuffer = buffers.GetEnumerator(); - started = false; - } - - public Instruction Current => lastEnumerator.Current; - - public bool MoveNext() - { - if (!started) - { - started = true; - if (!lastBuffer.MoveNext()) - return false; - lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); - while (!lastEnumerator.MoveNext()) - { - if (!lastBuffer.MoveNext()) - return false; - lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); - } - return true; - } - else - { - if (lastEnumerator.MoveNext()) - return true; - else - { - while (lastBuffer.MoveNext()) - { - lastEnumerator = lastBuffer.Current.Value.GetEnumerator(); - if (lastEnumerator.MoveNext()) - return true; - } - } - return false; - } - } - } - } - - - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs deleted file mode 100644 index ecc4ccbf20..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SortedWordBuffer.cs +++ /dev/null @@ -1,74 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A buffer where all instructions have been sorted, no instructions can be added to it -/// -public sealed class SortedWordBuffer : BufferBase, ISpirvBuffer -{ - public static SortedWordBuffer Empty { get; } = new(); - public int InstructionCount => new SpirvReader(Memory).Count; - public bool IsEmpty => Span.IsEmpty; - - public Span InstructionSpan => InstructionMemory.Span; - - public Memory InstructionMemory => HasHeader ? Memory[5..] : Memory; - - public bool HasHeader => Span[0] == Spv.Specification.MagicNumber; - - public Instruction this[int index] - { - get - { - var enumerator = GetEnumerator(); - int tmp = 0; - while (enumerator.MoveNext() && tmp < index) - tmp += 1; - return enumerator.Current; - } - } - - public InstructionEnumerator GetEnumerator() => new(this); - - public SortedWordBuffer() - { - _owner = MemoryOwner.Empty; - } - - public SortedWordBuffer(WordBuffer buffer) - { - _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); - Length = 0; - foreach (var item in buffer) - { - item.Words.Span.CopyTo(_owner.Span[Length..(Length + item.WordCount)]); - Length += item.WordCount; - } - } - public SortedWordBuffer(MultiBuffer buffer) - { - _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); - Length = 0; - foreach (var item in buffer.Instructions) - { - item.Words.Span.CopyTo(_owner.Span[Length..(Length + item.WordCount)]); - Length += item.WordCount; - } - } - public SortedWordBuffer(SpirvBuffer buffer) - { - _owner = buffer._owner; - Length = buffer.Length; - buffer._owner = MemoryOwner.Empty; - } - public SpirvSpan AsSpan() => new(Span); - public SpirvMemory AsMemory() => new(this); - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs deleted file mode 100644 index e4e6a8ab70..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ /dev/null @@ -1,111 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A common spirv buffer containing a header. -/// -public class SpirvBuffer : ExpandableBuffer, ISpirvBuffer, IDisposable -{ - public Span InstructionSpan => _owner.Span[5..Length]; - public Memory InstructionMemory => _owner.Memory[5..Length]; - public RefHeader Header => new(_owner.Span[..5]); - public bool HasHeader => true; - - public Instruction this[int index] - { - get - { - int id = 0; - int wid = 5; - while (id < index) - { - wid += Span[wid] >> 16; - id++; - } - return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16),index,wid); - } - } - - public SpirvBuffer(int initialSize = 32) - { - _owner = MemoryOwner.Allocate(initialSize,AllocationMode.Clear); - var header = Header; - header.MagicNumber = Spv.Specification.MagicNumber; - header.VersionNumber = new(1,3); - header.GeneratorMagicNumber = 42; - Length = 5; - } - public SpirvBuffer(MultiBuffer buffer) - { - _owner = MemoryOwner.Allocate(buffer.Length, AllocationMode.Clear); - var header = Header; - header.MagicNumber = Spv.Specification.MagicNumber; - header.VersionNumber = new(1, 3); - header.GeneratorMagicNumber = 42; - header.Bound = buffer.Bound; - Length = 5; - foreach (var i in buffer.Declarations) - if (i.OpCode != SDSLOp.OpNop) - Add(i.Words.Span); - foreach(var (_,f) in buffer.Functions) - foreach (var i in f) - if (i.OpCode != SDSLOp.OpNop) - Add(i.Words.Span); - buffer.Dispose(); - } - - public InstructionEnumerator GetEnumerator() => new(this); - - public void Add(SortedWordBuffer buffer) => Add(buffer.Span); - - public void Replace(SpirvBuffer buffer, out bool dispose) - { - if(buffer.Length <= Length) - { - _owner.Span.Clear(); - buffer.Span.CopyTo(Span); - Length = buffer.Length; - dispose = true; - } - else - { - var disp = _owner; - _owner = buffer._owner; - Length = buffer.Length; - disp.Dispose(); - dispose = false; - } - } - - public void RecomputeBound() - { - int last = 0; - foreach(var i in this) - { - last = i.ResultId ?? last; - } - var header = Header; - header.Bound = last + 1; - } - - public SortedWordBuffer ToSorted() - { - return new(this); - } - public SpirvSpan AsSpan() => new(Span); - public SpirvMemory AsMemory() => new(this); - - - public override string ToString() - { - return Disassembler.Disassemble(this); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs deleted file mode 100644 index d3ae5b61e1..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A buffer slice -/// -public ref struct SpirvMemory -{ - ISpirvBuffer buffer; - Span words => buffer.Span; - - public int Length => words.Length - (HasHeader ? 5 : 0); - public bool HasHeader => words[0] == Spv.Specification.MagicNumber; - - public Span Span => HasHeader ? words[5..] : words; - - - public int this[int index] { get => words[index]; set => words[index] = value; } - - public SpirvMemory(ISpirvBuffer buffer) - { - this.buffer = buffer; - } - - public InstructionEnumerator GetEnumerator() => new(buffer); -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs deleted file mode 100644 index ecc8f3706f..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A buffer slice -/// -public ref struct SpirvSpan -{ - Span words; - - public int Length => words.Length - (HasHeader ? 5 : 0); - public bool HasHeader => words[0] == Spv.Specification.MagicNumber; - - public Span Span => HasHeader ? words[5..] : words; - - - public int this[int index] { get => words[index]; set => words[index] = value; } - - public SpirvSpan(Span words) - { - this.words = words; - } - - public Enumerator GetEnumerator() => new(words); - - public ref struct Enumerator - { - int wordIndex; - Span words; - - public RefInstruction Current => RefInstruction.ParseRef(words.Slice(wordIndex, words[wordIndex] >> 16)); - - public Enumerator(Span words) - { - wordIndex = -1; - this.words = words; - } - - public bool MoveNext() - { - if(wordIndex == -1) - { - wordIndex = 0; - return true; - } - else - { - if (wordIndex + (words[wordIndex] >> 16) >= words.Length) - return false; - wordIndex += words[wordIndex] >> 16; - return true; - } - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs deleted file mode 100644 index d77081009e..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/DisWriter.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System.Text; - -namespace Stride.Shaders.Spirv.Core; - -public class DisWriter -{ - StringBuilder builder; - int idOffset; - - public DisWriter(int bound) //34 - { - builder = new(); - idOffset = 3; - while (bound > 0) - { - bound /= 10; - idOffset += 1; - } - } - public void Append(IdResult? result) - { - if (result != null) - { - var tmp = result.Value; - var size = 1; - while (tmp > 0) - { - tmp /= 10; - size += 1; - } - builder.Append('%').Append(result.Value).Append(' ', idOffset - 1 - size).Append('='); - } - else - builder.Append(' ', idOffset); - } - - public void Append(T value) where T : Enum - { - var name = Enum.GetName(typeof(T), value); - builder.Append(' ').Append(name); - } - public void Append(IdRef id) - { - builder.Append(' ').Append('%').Append(id.Value); - } - public void Append(IdResultType id) - { - builder.Append(' ').Append('%').Append(id.Value); - } - public void AppendInt(int v) - { - builder.Append(' ').Append(v); - } - public void AppendLiteral(LiteralInteger v) - { - builder.Append(' ').Append(v.Words); - } - - public void AppendLiteral(LiteralFloat v) - { - if(v.WordCount == 1) - builder.Append(' ').Append(Convert.ToSingle(v.Words & 0xFFFF)); - if(v.WordCount == 2) - builder.Append(' ').Append(Convert.ToDouble(v.Words)); - } - public void AppendLiteral(LiteralString v, bool quoted = false) - { - if(!quoted) - builder.Append(' ').Append(v.Value); - else - builder.Append(' ').Append('"').Append(v.Value).Append('"'); - } - public void Append(PairLiteralIntegerIdRef v) - { - (int,int) value = v; - AppendInt(value.Item1); - AppendInt(value.Item2); - } - public void Append(PairIdRefLiteralInteger v) - { - (int,int) value = v; - AppendInt(value.Item1); - AppendInt(value.Item2); - } - public void Append(PairIdRefIdRef v) - { - (int,int) value = v; - AppendInt(value.Item1); - AppendInt(value.Item2); - } - public void AppendLine() => builder.AppendLine(); - - public override string ToString() - { - return builder.ToString(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs deleted file mode 100644 index 6f778d6f89..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Disassembly/Disassembler.cs +++ /dev/null @@ -1,237 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System.Runtime.InteropServices; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core; - - -public static class Disassembler -{ - - public static string Disassemble(Span memory) - { - var words = MagicNumber == memory[0] ? - memory[5..] : memory; - - var wbuff = new WordBuffer(words); - return Disassemble(wbuff); - } - - public static string Disassemble(Memory memory) - { - var words = MagicNumber == memory.Span[0] ? - memory.Span[5..] : memory.Span; - - var wbuff = new WordBuffer(words); - return Disassemble(wbuff); - } - public static string Disassemble(UnsortedWordBuffer wbuff) - { - var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); - - foreach (var e in wbuff) - { - dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); - dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); - foreach (var o in e) - { - Append(o, dis); - } - dis.AppendLine(); - } - return dis.ToString(); - } - - public static string Disassemble(SortedWordBuffer wbuff) - { - var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); - - foreach (var e in wbuff) - { - dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); - dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); - foreach (var o in e) - { - Append(o, dis); - } - dis.AppendLine(); - } - return dis.ToString(); - } - public static string Disassemble(SpirvBuffer wbuff) - { - var dis = new DisWriter(new SpirvReader(wbuff.InstructionMemory).ComputeBound()); - - foreach (var e in wbuff) - { - dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); - dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); - foreach (var o in e) - { - Append(o, dis); - } - dis.AppendLine(); - } - return dis.ToString(); - } - - public static string Disassemble(WordBuffer wbuff) - { - var dis = new DisWriter(new SpirvReader(wbuff.Memory, wbuff.Span[0] == MagicNumber).ComputeBound()); - - foreach (var e in wbuff) - { - dis.Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); - dis.AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); - foreach (var o in e) - { - Append(o, dis); - } - dis.AppendLine(); - } - return dis.ToString(); - } - - public static void Append(in SpvOperand o, DisWriter dis) - { - - if (o.Kind == OperandKind.IdRef) - foreach (var e in o.Words) - dis.Append(new IdRef(e)); - else if (o.Kind == OperandKind.PackedVectorFormat) - foreach (var e in o.Words) - dis.Append((PackedVectorFormat)e); - else if (o.Kind == OperandKind.ImageOperands) - foreach (var e in o.Words) - dis.Append((ImageOperandsMask)e); - else if (o.Kind == OperandKind.FPFastMathMode) - foreach (var e in o.Words) - dis.Append((FPFastMathModeMask)e); - else if (o.Kind == OperandKind.SelectionControl) - foreach (var e in o.Words) - dis.Append((SelectionControlMask)e); - else if (o.Kind == OperandKind.LoopControl) - foreach (var e in o.Words) - dis.Append((LoopControlMask)e); - else if (o.Kind == OperandKind.FunctionControl) - foreach (var e in o.Words) - dis.Append((FunctionControlMask)e); - else if (o.Kind == OperandKind.MemorySemantics) - foreach (var e in o.Words) - dis.Append((MemorySemanticsMask)e); - else if (o.Kind == OperandKind.MemoryAccess) - foreach (var e in o.Words) - dis.Append((MemoryAccessMask)e); - else if (o.Kind == OperandKind.KernelProfilingInfo) - foreach (var e in o.Words) - dis.Append((KernelProfilingInfoMask)e); - else if (o.Kind == OperandKind.RayFlags) - foreach (var e in o.Words) - dis.Append((RayFlagsMask)e); - else if (o.Kind == OperandKind.FragmentShadingRate) - foreach (var e in o.Words) - dis.Append((FragmentShadingRateMask)e); - else if (o.Kind == OperandKind.SourceLanguage) - foreach (var e in o.Words) - dis.Append((SourceLanguage)e); - else if (o.Kind == OperandKind.ExecutionModel) - foreach (var e in o.Words) - dis.Append((ExecutionModel)e); - else if (o.Kind == OperandKind.AddressingModel) - foreach (var e in o.Words) - dis.Append((AddressingModel)e); - else if (o.Kind == OperandKind.MemoryModel) - foreach (var e in o.Words) - dis.Append((MemoryModel)e); - else if (o.Kind == OperandKind.ExecutionMode) - foreach (var e in o.Words) - dis.Append((ExecutionMode)e); - else if (o.Kind == OperandKind.StorageClass) - foreach (var e in o.Words) - dis.Append((StorageClass)e); - else if (o.Kind == OperandKind.Dim) - foreach (var e in o.Words) - dis.Append((Dim)e); - else if (o.Kind == OperandKind.SamplerAddressingMode) - foreach (var e in o.Words) - dis.Append((SamplerAddressingMode)e); - else if (o.Kind == OperandKind.SamplerFilterMode) - foreach (var e in o.Words) - dis.Append((SamplerFilterMode)e); - else if (o.Kind == OperandKind.ImageFormat) - foreach (var e in o.Words) - dis.Append((ImageFormat)e); - else if (o.Kind == OperandKind.ImageChannelOrder) - foreach (var e in o.Words) - dis.Append((ImageChannelOrder)e); - else if (o.Kind == OperandKind.ImageChannelDataType) - foreach (var e in o.Words) - dis.Append((ImageChannelDataType)e); - else if (o.Kind == OperandKind.FPRoundingMode) - foreach (var e in o.Words) - dis.Append((FPRoundingMode)e); - else if (o.Kind == OperandKind.LinkageType) - foreach (var e in o.Words) - dis.Append((LinkageType)e); - else if (o.Kind == OperandKind.AccessQualifier) - foreach (var e in o.Words) - dis.Append((AccessQualifier)e); - else if (o.Kind == OperandKind.FunctionParameterAttribute) - foreach (var e in o.Words) - dis.Append((FunctionParameterAttribute)e); - else if (o.Kind == OperandKind.Decoration) - foreach (var e in o.Words) - dis.Append((Decoration)e); - else if (o.Kind == OperandKind.BuiltIn) - foreach (var e in o.Words) - dis.Append((BuiltIn)e); - else if (o.Kind == OperandKind.Scope) - foreach (var e in o.Words) - dis.Append((Scope)e); - else if (o.Kind == OperandKind.GroupOperation) - foreach (var e in o.Words) - dis.Append((GroupOperation)e); - else if (o.Kind == OperandKind.KernelEnqueueFlags) - foreach (var e in o.Words) - dis.Append((KernelEnqueueFlags)e); - else if (o.Kind == OperandKind.Capability) - foreach (var e in o.Words) - dis.Append((Capability)e); - else if (o.Kind == OperandKind.RayQueryIntersection) - foreach (var e in o.Words) - dis.Append((RayQueryIntersection)e); - else if (o.Kind == OperandKind.RayQueryCommittedIntersectionType) - foreach (var e in o.Words) - dis.Append((RayQueryCommittedIntersectionType)e); - else if (o.Kind == OperandKind.RayQueryCandidateIntersectionType) - foreach (var e in o.Words) - dis.Append((RayQueryCandidateIntersectionType)e); - else if (o.Kind == OperandKind.IdResultType) - foreach (var e in o.Words) - dis.Append((IdResultType)e); - else if (o.Kind == OperandKind.IdMemorySemantics) - foreach (var e in o.Words) - dis.AppendInt((IdMemorySemantics)e); - else if (o.Kind == OperandKind.IdScope) - foreach (var e in o.Words) - dis.AppendInt((IdScope)e); - else if (o.Kind == OperandKind.IdRef) - foreach (var e in o.Words) - dis.Append((IdRef)e); - else if (o.Kind == OperandKind.LiteralInteger) - foreach (var e in o.Words) - dis.AppendInt(e); - else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) - for (int i = 0; i < o.Words.Length; i += 2) - dis.Append(new PairLiteralIntegerIdRef((o.Words[i], o.Words[i + 1]))); - else if (o.Kind == OperandKind.PairIdRefLiteralInteger) - for (int i = 0; i < o.Words.Length; i += 2) - dis.Append(new PairIdRefLiteralInteger((o.Words[i], o.Words[i + 1]))); - else if (o.Kind == OperandKind.PairIdRefIdRef) - for (int i = 0; i < o.Words.Length; i += 2) - dis.Append(new PairIdRefIdRef((o.Words[i], o.Words[i + 1]))); - else if (o.Kind == OperandKind.LiteralContextDependentNumber) - dis.AppendLiteral(o.To()); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs deleted file mode 100644 index 883cae9254..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/MutRefInstruction.cs +++ /dev/null @@ -1,77 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System.Runtime.CompilerServices; - -namespace Stride.Shaders.Spirv.Core; - -/// -/// Helps create instruction through stack allocations instead of buffers -/// -public ref struct MutRefInstruction -{ - public Span Words { get; } - public Span Operands => Words [1..]; - public readonly SDSLOp OpCode - { - get => (SDSLOp)(Words[0] & 0xFFFF); - set { unchecked { Words[0] = (Words[0] & (int)0xFFFF0000) | (int)value;}} - } - public readonly int WordCount - { - get => Words[0] >> 16; - set => Words[0] = value << 16 | Words[0] & 0xFFFF; - } - - - private int _index; - - public MutRefInstruction(Span words) - { - Words = words; - WordCount = words.Length; - _index = 1; - } - public void Add(scoped Span values) - { - values.CopyTo(Words[_index..]); - _index += values.Length; - } - public void Add(Span values) - where T : ISpirvElement - { - foreach(var e in values) - Add(e.AsSpanOwner().Span); - } - - public void Add(T? value) - { - if (value != null) - { - if (value is int i) - Add([i]); - else if (value is ISpirvElement element) - Add(element.AsSpanOwner().Span); - else if (value is string s) - Add(s.AsSpanOwner().Span); - else if (value is Enum e) - Add([Convert.ToInt32(e)]); - } - } - - public readonly OperandEnumerator GetEnumerator() => new(RefInstruction.ParseRef(Words)); - public readonly T GetOperand(string name) - where T : struct, IFromSpirv - { - var info = InstructionInfo.GetInfo(OpCode); - var infoEnumerator = info.GetEnumerator(); - var operandEnumerator = GetEnumerator(); - while (infoEnumerator.MoveNext()) - { - operandEnumerator.MoveNext(); - if (infoEnumerator.Current.Name == name) - { - return operandEnumerator.Current.To(); - } - } - throw new Exception($"Instruction {OpCode} has no operand named \"{name}\""); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs deleted file mode 100644 index d631384489..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/FilteredEnumerator.cs +++ /dev/null @@ -1,144 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// A spirv buffer enumerator with filters on operations -/// -/// -public ref struct FilteredEnumerator - where T : ISpirvBuffer -{ - int wordIndex; - int index; - bool started; - T buffer; - readonly Span instructionWords => buffer.InstructionSpan; - - string? classFilter; - SDSLOp? filter1; - SDSLOp? filter2; - SDSLOp? filter3; - SDSLOp? filter4; - - FilterType filterType; - - - public FilteredEnumerator(T buff, string classFilt) - { - started = false; - wordIndex = 0; - buffer = buff; - classFilter = classFilt; - filterType = FilterType.ClassName; - } - public FilteredEnumerator(T buff, SDSLOp filt1) - { - started = false; - wordIndex = 0; - buffer = buff; - filter1 = filt1; - filterType = FilterType.Op1; - } - public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2) - { - started = false; - wordIndex = 0; - buffer = buff; - filter1 = filt1; - filter2 = filt2; - filterType = FilterType.Op2; - } - public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2, SDSLOp filt3) - { - started = false; - wordIndex = 0; - buffer = buff; - filter1 = filt1; - filter2 = filt2; - filter3 = filt3; - filterType = FilterType.Op3; - } - public FilteredEnumerator(T buff, SDSLOp filt1, SDSLOp filt2, SDSLOp filt3, SDSLOp filt4) - { - started = false; - wordIndex = 0; - buffer = buff; - filter1 = filt1; - filter2 = filt2; - filter3 = filt3; - filter4 = filt4; - filterType = FilterType.Op4; - } - - public Instruction Current => ParseCurrentInstruction(); - - bool Matches(SDSLOp toCheck) - { - return filterType switch - { - FilterType.ClassName => InstructionInfo.GetInfo(toCheck).ClassName == classFilter, - FilterType.Op1 => toCheck == filter1, - FilterType.Op2 => toCheck == filter1 || toCheck == filter2, - FilterType.Op3 => toCheck == filter1 || toCheck == filter2 || toCheck == filter3, - FilterType.Op4 => toCheck == filter1 || toCheck == filter2 || toCheck == filter3 || toCheck == filter4, - _ => false - }; - } - public bool MoveNext() - { - if (!started) - { - started = true; - index = 0; - var sizeToStep = 0; - while (wordIndex + sizeToStep < instructionWords.Length && !Matches((SDSLOp)(instructionWords[wordIndex + sizeToStep] & 0xFFFF))) - { - sizeToStep += instructionWords[wordIndex + sizeToStep] >> 16; - index += 1; - } - wordIndex += sizeToStep; - if (wordIndex >= instructionWords.Length) - return false; - return true; - } - else - { - var sizeToStep = instructionWords[wordIndex] >> 16; - while(wordIndex + sizeToStep < instructionWords.Length && !Matches((SDSLOp)(instructionWords[wordIndex + sizeToStep] & 0xFFFF))) - { - sizeToStep += instructionWords[wordIndex + sizeToStep] >> 16; - index += 1; - } - wordIndex += sizeToStep; - if (wordIndex >= instructionWords.Length) - return false; - return true; - } - - } - - - public Instruction ParseCurrentInstruction() - { - var wordCount= instructionWords[wordIndex] >> 16; - return new(buffer, buffer.Memory.Slice(wordIndex, wordCount), index, wordIndex); - } - - internal enum FilterType - { - ClassName, - Op1, - Op2, - Op3, - Op4 - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs deleted file mode 100644 index 4e7ffe55c6..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/InstructionFinder.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// A utility struct to find and look for specific instructions -/// -/// -public ref struct InstructionFinder where T : ISpirvBuffer -{ - T buffer; - //LambdaFilteredEnumerator enumerator; - - public InstructionFinder(T buffer) - { - this.buffer = buffer; - } - - public readonly Instruction First(Func filter) - { - var enumerator = new LambdaFilteredEnumerator(buffer, filter); - if (enumerator.MoveNext()) - return enumerator.Current; - else - throw new Exception("No matching instructions found"); - } - public readonly Instruction Last(Func filter) - { - var enumerator = new LambdaFilteredEnumerator(buffer, filter); - Instruction? result = null; - if (enumerator.MoveNext()) - result = enumerator.Current; - - return result != null ? result .Value: throw new Exception("No matching instructions found"); - } - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs deleted file mode 100644 index ec43176dc3..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/LambdaFilteredEnumerator.cs +++ /dev/null @@ -1,43 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; -/// -/// An enumerator to filter instructions with a lambda -/// -/// -public ref struct LambdaFilteredEnumerator - where T : ISpirvBuffer -{ - T buffer; - - string? classFilter; - Func filter; - InstructionEnumerator enumerator; - - - public LambdaFilteredEnumerator(T buff, Func filter) - { - buffer = buff; - this.filter = filter; - enumerator = new(buffer); - } - public Instruction Current => enumerator.Current; - public bool MoveNext() - { - while(enumerator.MoveNext()) - { - if (filter.Invoke(Current) == true) - return true; - } - return false; - } - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs deleted file mode 100644 index cf57ca957c..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Parsing/RefInstructions.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// An instruction utility parser. -/// -public ref struct RefInstructions -{ - Memory Words { get; init; } - - - public RefInstructions(Memory words) - { - Words = words; - } - - - public Enumerator GetEnumerator() => new(Words); - - public ref struct Enumerator - { - int wordIndex; - bool started; - Memory words; - - public Enumerator(Memory words) - { - started = false; - wordIndex = 0; - this.words = words; - } - - public RefInstruction Current => ParseCurrentInstruction(); - - public bool MoveNext() - { - if (!started) - { - started = true; - return true; - } - else - { - var sizeToStep = words.Span[wordIndex] >> 16; - wordIndex += sizeToStep; - if (wordIndex >= words.Length) - return false; - return true; - } - - } - - - public RefInstruction ParseCurrentInstruction() - { - var wordNumber = words.Span[wordIndex] >> 16; - return RefInstruction.Parse(words, wordIndex); - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs deleted file mode 100644 index b6e6ffa6dc..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/ValidationPass.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Stride.Shaders.Spirv.Core.Validation; - - -public abstract class ValidationPass -{ - public abstract bool Validate(); -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs deleted file mode 100644 index 39f15b3260..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Core/Validation/Validator.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Stride.Shaders.Spirv.Core.Validation; - - -public class Validation -{ - public List Passes; - - Validation() - { - Passes = new(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs deleted file mode 100644 index 762b524afd..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Program.cs +++ /dev/null @@ -1,174 +0,0 @@ -// See https://aka.ms/new-console-template for more information -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; -using Stride.Shaders.Spirv.Core.Buffers; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using static Spv.Specification; - - -Console.WriteLine("Hello, world!"); - - -//var doc = JsonParser.Parse/*("{\"*/hello\" : \"world\"}"); -//Console.WriteLine(doc.RootElement.GetProperty("hello").GetString()); - -static void ParseShader() -{ - Console.WriteLine(Unsafe.SizeOf>()); - - InstructionInfo.GetInfo(SDSLOp.OpCapability); - - var shader = File.ReadAllBytes("../../shader.spv"); - - - SpirvReader.ParseToList(shader, new(8)); - - var x = 0; -} - - -static void CreateShader() -{ - LiteralString sname = "S"; - - var ssize = sname.WordCount; - var array = new byte[] {0,0,0,8}; - - var s = array.AsSpan(); - Span ints = MemoryMarshal.Cast(s); - - // var bound = new Bound(); - var buffer = new WordBuffer(); - // // Capabilities - - buffer.AddOpCapability(Capability.Shader); - var extInstImport = buffer.AddOpExtInstImport("GLSL.std.450"); - buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); - - - // declarations - - Span c = stackalloc IdRef[10]; // This is for use in parameters - - - var t_void = buffer.AddOpTypeVoid(); - - var t_bool = buffer.AddOpTypeBool(); - - var t_func = buffer.AddOpTypeFunction(t_void, Span.Empty); - var t_float = buffer.AddOpTypeFloat(32, null); - var t_uint = buffer.AddOpTypeInt(32, 0); - var t_int = buffer.AddOpTypeInt(32, 1); - var t_float4 = buffer.AddOpTypeVector(t_float, 4); - var t_p_float4_func = buffer.AddOpTypePointer(StorageClass.Function, t_float4); - var constant1 = buffer.AddOpConstant(t_float, 5); - var constant2 = buffer.AddOpConstant(t_float, 2); - var constant3 = buffer.AddOpConstant(t_uint, 5); - var compositeType = buffer.AddOpConstantComposite( - t_float4, - stackalloc IdRef[] { constant1, constant1, constant2, constant1 } - ); - - var t_array = buffer.AddOpTypeArray(t_float4, constant3); - - var t_struct = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_uint, t_array, t_int }); - var t_struct2 = buffer.AddOpTypeStruct(stackalloc IdRef[] { t_struct, t_uint }); - - var t_p_struct2 = buffer.AddOpTypePointer(StorageClass.Uniform, t_struct2); - - var v_struct2 = buffer.AddOpVariable(t_p_struct2, StorageClass.Uniform, null); - - var constant4 = buffer.AddOpConstant(t_int, 1); - - var t_p_uint = buffer.AddOpTypePointer(StorageClass.Uniform, t_uint); - var constant5 = buffer.AddOpConstant(t_uint, 0); - - var t_p_output = buffer.AddOpTypePointer(StorageClass.Output, t_float4); - var v_output = buffer.AddOpVariable(t_p_output, StorageClass.Output, null); - - var t_p_input = buffer.AddOpTypePointer(StorageClass.Input, t_float4); - var v_input = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - - var constant6 = buffer.AddOpConstant(t_int, 0); - var constant7 = buffer.AddOpConstant(t_int, 2); - var t_p_float4_unif = buffer.AddOpTypePointer(StorageClass.Uniform, t_float4); - - var v_input_2 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - var t_p_func = buffer.AddOpTypePointer(StorageClass.Function, t_int); - var constant8 = buffer.AddOpConstant(t_int, 4); - var v_input_3 = buffer.AddOpVariable(t_p_input, StorageClass.Input, null); - - - - - buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); - buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); - buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); - buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); - buffer.AddOpDecorate(t_struct2, Decoration.Block); - buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); - buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); - - - - - buffer.AddOpName(t_p_func, "main"); - buffer.AddOpName(t_struct, "S"); - buffer.AddOpMemberName(t_struct, 0, "b"); - buffer.AddOpMemberName(t_struct, 1, "v"); - buffer.AddOpMemberName(t_struct, 2, "i"); - - - var main = buffer.AddOpFunction(t_void, FunctionControlMask.MaskNone, t_func); - buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", stackalloc IdRef[] { v_output, v_input, v_input_2, v_input_3 }); - buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); - - buffer.AddOpLabel(); - buffer.AddOpReturn(); - buffer.AddOpFunctionEnd(); - - var main2 = buffer.AddOpFunction(t_void, FunctionControlMask.MaskNone, t_func); - buffer.AddOpEntryPoint(ExecutionModel.Vertex, main, "VSMain", stackalloc IdRef[] { v_output, v_input, v_input_2, v_input_3 }); - - var sorted = new SortedWordBuffer(buffer); - - Console.WriteLine(Disassembler.Disassemble(sorted)); - - //var list = new List(buffer.Count); - //foreach(var e in buffer) - // list.Add(e); - - //var bytes = buffer.GenerateSpirv(); - - //File.WriteAllBytes("C:\\Users\\kafia\\source\\repos\\Stride.Shaders.Spirv\\shader.spv", bytes); ; - - var x = 0; -} - - -static void ParseWorking() -{ - // var path = @"C:\Users\youness_kafia\Documents\dotnetProjs\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; - var path = @"C:\Users\kafia\source\repos\SDSLParser\src\Stride.Shaders.Spirv\working1-6.spv"; - - var bytes = File.ReadAllBytes(path); - - var buffer = WordBuffer.Parse(bytes); - var extInst = buffer[1]; - foreach(var o in extInst) - { - if(o.Kind == OperandKind.LiteralString) - { - Console.WriteLine(o.To().Value); - } - } - var tmp = 0; -} - -CreateShader(); - -//ParseWorking(); diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs deleted file mode 100644 index 925bb3f46a..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ /dev/null @@ -1,162 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Reflection; -using System.Text.Json; -using System.Security.Claims; -using System.Runtime.InteropServices.ComTypes; - -namespace Stride.Shaders.Spirv.Generators -{ - public partial class SPVGenerator - { - - - public void CreateInfo(IncrementalGeneratorInitializationContext context) - { - - GenerateKinds(context); - - var code = new StringBuilder(); - - code - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public partial class InstructionInfo") - .AppendLine("{") - - .AppendLine("static InstructionInfo()") - .AppendLine("{") - ; - - - foreach (var instruction in spirvCore.RootElement.GetProperty("instructions").EnumerateArray()) - { - GenerateInfo(instruction, code); - } - foreach (var instruction in spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray()) - { - GenerateInfo(instruction, code); - } - code - .AppendLine("Instance.InitOrder();") - - .AppendLine("}") - - .AppendLine("}"); - - context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); - } - - private void GenerateKinds(IncrementalGeneratorInitializationContext context) - { - var code = new StringBuilder() - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("\n\n") - .AppendLine("public enum OperandKind") - .AppendLine("{") - - .AppendLine("None = 0,"); - var kinds = spirvCore.RootElement.GetProperty("operand_kinds").EnumerateArray().Select(x => x.GetProperty("kind").GetString()); - foreach (var kind in kinds) - { - code.Append(kind).AppendLine(","); - } - code.AppendLine("}"); - - context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); - - } - - public void GenerateInfo(JsonElement op, StringBuilder code) - { - var opname = op.GetProperty("opname").GetString(); - var spvClass = op.GetProperty("class").GetString(); - if (opname == "OpExtInst") - { - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); - } - else if (op.TryGetProperty("operands", out var operands)) - { - foreach (var operand in operands.EnumerateArray()) - { - var hasKind = operand.TryGetProperty("kind", out var kindJson); - var hasQuant = operand.TryGetProperty("quantifier", out var quantifierJson); - var hasName = operand.TryGetProperty("name", out var nameJson); - - if (hasKind) - { - var kind = kindJson.GetString(); - if (!hasQuant) - { - code - .Append("Instance.Register(SDSLOp.") - .Append(opname) - .Append(", OperandKind.") - .Append(kindJson.GetString()) - .Append(", OperandQuantifier.One, ") - .Append(!hasName ? $"\"{ConvertKindToName(kindJson.GetString())}\"" : $"\"{ConvertOperandName(nameJson.GetString())}\"") - .Append($", \"{spvClass}\"") - .AppendLine(");"); - } - else - { - var quant = quantifierJson.GetString(); - code - .Append("Instance.Register(SDSLOp.") - .Append(opname) - .Append(", OperandKind.") - .Append(kindJson.GetString()) - .Append(", OperandQuantifier.") - .Append(ConvertQuantifier(quantifierJson.GetString())) - .Append(", ") - .Append(!hasName ? $"\"{ConvertNameQuantToName(kind, quant)}\"" : $"\"{ConvertNameQuantToName(nameJson.GetString(), quant)}\"") - .Append($", \"{spvClass}\"") - .AppendLine(");"); - } - } - } - } - else - { - code.Append("Instance.Register(SDSLOp.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); - } - } - - public static string ConvertNameQuantToName(string name, string quant) - { - return (name, quant) switch - { - (_, "*") => "values", - ("event", _) => "eventId", - ("string", _) => "value", - ("base", _) => "baseId", - ("object", _) => "objectId", - ("default", _) => "defaultId", - _ => name.Replace("'", "").ToLowerInvariant() - }; - } - - public static string ConvertQuantifier(string quant) - { - if (quant == "*") - return "ZeroOrMore"; - else if (quant == "?") - return "ZeroOrOne"; - else return "One"; - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs deleted file mode 100644 index d3bf21a078..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs +++ /dev/null @@ -1,193 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Reflection; -using System.Text.Json; -using System.Security.Claims; - -namespace Stride.Shaders.Spirv.Generators -{ - - public static class ListExtensions - { - public static void AddUnique(this List list, string name) - { - if (list.Contains(name)) - list.Add(name + list.Where(x => x.StartsWith(name)).Count()); - else - list.Add(name); - } - } - - public partial class SPVGenerator - { - - - public static List ConvertOperandsToParameters(JsonElement op) - { - var opname = op.GetProperty("opname").GetString(); - var operands = op.GetProperty("operands").EnumerateArray(); - List parameters = new(); - foreach (var e in operands) - { - var kind = e.GetProperty("kind").GetString(); - var realKind = ConvertKind(kind); - if (e.TryGetProperty("quantifier", out var quant)) - { - if (e.TryGetProperty("name", out var name)) - { - if (quant.GetString() == "?") - parameters.AddUnique(realKind + "? " + ConvertOperandName(name.GetString())); - else if (quant.GetString() == "*") - parameters.AddUnique("Span<" + realKind + "> values"); - } - else - { - if (quant.GetString() == "?") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); - else if (quant.GetString() == "*") - parameters.AddUnique("Span<" + realKind + "> values"); - } - } - else - { - if (e.TryGetProperty("name", out var name)) - parameters.AddUnique(realKind + " " + ConvertOperandName(name.GetString())); - else if(kind == "IdResult" && opname == "OpExtInst") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); - else if (kind == "IdResultType" && opname == "OpExtInst") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); - else - parameters.AddUnique(realKind + " " + ConvertKindToName(kind)); - } - } - if(parameters.Any(x => x.Contains("resultType")) && parameters.Any(x => x.Contains("resultId"))) - { - var resultType = parameters[0]; - var resultId = parameters[1]; - parameters[0] = resultId; - parameters[1] = resultType; - } - return parameters; - } - - public static List ConvertOperandsToParameterNames(JsonElement op) - { - var opname = op.GetProperty("opname").GetString(); - var operands = op.GetProperty("operands").EnumerateArray(); - List parameters = new(op.GetProperty("operands").GetArrayLength()); - foreach (var e in operands) - { - var kind = e.GetProperty("kind").GetString(); - var realKind = ConvertKind(kind); - if (e.TryGetProperty("quantifier", out var quant)) - { - if (e.TryGetProperty("name", out var name)) - { - if (quant.GetString() == "?") - parameters.AddUnique(ConvertOperandName(name.GetString())); - else if (quant.GetString() == "*") - parameters.AddUnique("values"); - } - else - { - if (quant.GetString() == "?") - parameters.AddUnique(ConvertKindToName(kind)); - else if (quant.GetString() == "*") - parameters.AddUnique("values"); - } - } - else - { - if (e.TryGetProperty("name", out var name)) - parameters.AddUnique(ConvertOperandName(name.GetString())); - else - parameters.AddUnique(ConvertKindToName(kind)); - } - } - return parameters; - } - - public static string ConvertKind(string kind) - { - return kind switch - { - "LiteralInteger" => "LiteralInteger", - "LiteralFloat" => "LiteralFloat", - "LiteralString" => "LiteralString", - "ImageOperands" => "ImageOperandsMask", - "RawAccessChainOperands" => "RawAccessChainOperandsMask", - "FunctionControl" => "FunctionControlMask", - "MemoryAccess" => "MemoryAccessMask", - "LoopControl" => "LoopControlMask", - "SelectionControl" => "SelectionControlMask", - "LiteralExtInstInteger" => "LiteralInteger", - "LiteralSpecConstantOpInteger" => "Op", - "CooperativeMatrixOperands" => "CooperativeMatrixOperandsMask", - _ => kind - }; - } - - public static string ConvertKindToName(string kind) - { - return kind switch - { - "IdRef" => "id", - "IdResult" => "resultId", - "IdResultType" => "resultType", - _ => kind.ToLower() - }; - } - - public static string ConvertOperandName(string input, string quant = null) - { - if (string.IsNullOrEmpty(input)) - { - return string.Empty; - } - var result = ""; - bool firstLetterHit = false; - for (int i = 0; i < input.Length; i++) - { - - if (char.IsLetterOrDigit(input[i]) || input[i] == '_') - { - if (!firstLetterHit) - { - firstLetterHit = true; - result += char.ToLowerInvariant(input[i]); - } - else - result += input[i]; - } - - } - return (result, quant) switch - { - ("event", _) => "eventId", - ("string", _) => "value", - ("base", _) => "baseId", - ("object", _) => "objectId", - ("default", _) => "defaultId", - ("IdResult", _) => "resultId", - ("IdResultType", _) => "resultType", - ("IdRef", "*") => "id", - ("IdRef", "?") => "id", - ("IdRef", null) => "id", - ("LiteralInteger", _) => "", - ("LiteralFloat", _) => "", - ("LiteralString", _) => "", - ("Dim", _) => "", - ("ImageFormat", _) => "", - ("ExecutionMode", _) => "", - ("ExecutionModel", _) => "", - _ => result - }; - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs deleted file mode 100644 index b6a9e35bae..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Reflection; -using System.Text.Json; -using System.Security.Claims; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.CSharp; - -namespace Stride.Shaders.Spirv.Generators -{ - public partial class SPVGenerator - { - public void CreateSDSLOp(IncrementalGeneratorInitializationContext context) - { - var code = new StringBuilder(); - var nsProvider = context - .SyntaxProvider - .CreateSyntaxProvider( - predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), - transform: (node, _) => (NamespaceDeclarationSyntax)node.Node - ); - context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => - { - var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); - var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue.Value.ToString())); - var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue.Value.ToString())).Max(); - - foreach (var e in spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray().Select(x => x.GetProperty("opname").GetString())) - members.Add(e, ++lastnum); - - code - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum SDSLOp : int") - .AppendLine("{"); - foreach (var e in members) - code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); - code - .AppendLine("}"); - - - ctx.AddSource("SDSLOp.gen.cs", code.ToString()); - }); - - } - public static int ParseInteger(string text) - { - if (text.StartsWith("0x")) - return int.Parse(text.Substring(2), System.Globalization.NumberStyles.HexNumber); - else - return int.Parse(text); - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs deleted file mode 100644 index 021a3def57..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ /dev/null @@ -1,237 +0,0 @@ -using Microsoft.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices.ComTypes; -using System.Text; -using System.Text.Json; - -namespace Stride.Shaders.Spirv.Generators -{ - - [Generator] - public partial class SPVGenerator : IIncrementalGenerator - { - JsonDocument spirvCore; - JsonDocument spirvGlsl; - JsonDocument spirvSDSL; - - public void Initialize(IncrementalGeneratorInitializationContext context) - { - // #if DEBUG - // if (!Debugger.IsAttached) - // Debugger.Launch(); - // #endif - var assembly = typeof(SPVGenerator).GetTypeInfo().Assembly; - string resourceCoreName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("spirv.core.grammar.json")); - - string resourceGlslName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("extinst.glsl.std.450.grammar.json")); - - string resourceSDSLName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("spirv.sdsl.grammar-ext.json")); - - spirvCore = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd()); - spirvGlsl = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd()); - spirvSDSL = JsonDocument.Parse(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd()); - - CreateInfo(context); - CreateSDSLOp(context); - - var code = new StringBuilder(); - - code - .AppendLine("using static Spv.Specification;") - .AppendLine("namespace Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("") - .AppendLine("public static class WordBufferExtensions") - .AppendLine("{"); - - var instructions = spirvCore.RootElement.GetProperty("instructions").EnumerateArray().ToList(); - var sdslInstructions = spirvSDSL.RootElement.GetProperty("instructions").EnumerateArray().ToList(); - var glslInstruction = spirvGlsl.RootElement.GetProperty("instructions").EnumerateArray().ToList(); - - instructions.ForEach(x => CreateOperation(x, code)); - sdslInstructions.ForEach(x => CreateOperation(x, code)); - glslInstruction.ForEach(x => CreateGlslOperation(x, code)); - - code.AppendLine("}"); - - context.RegisterPostInitializationOutput(ctx => { - ctx.AddSource( - "WordBufferExtensions.gen.cs", - code.ToSourceText()); - }); - } - - public void CreateOperation(JsonElement op, StringBuilder code) - { - var opname = op.GetProperty("opname").GetString(); - if (opname == "OpConstant") - { - code - .AppendLine("public static Instruction AddOpConstant(this TBuffer buffer, IdResultType? resultType, TValue value) where TBuffer : IMutSpirvBuffer where TValue : struct, ILiteralNumber") - .AppendLine("{") - - .AppendLine("var resultId = buffer.GetNextId();") - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add(new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]));") - - .AppendLine("}"); - - } - else if (opname == "OpSpecConstant") - { - code - .AppendLine("public static Instruction AddOpSpecConstant(this TBuffer buffer, IdResultType? resultType, TValue value) where TBuffer : IMutSpirvBuffer where TValue : ILiteralNumber") - .AppendLine("{") - - .AppendLine("var resultId = buffer.GetNextId();") - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("var mutInstruction = new MutRefInstruction(stackalloc int[wordLength]);") - .AppendLine("mutInstruction.OpCode = SDSLOp.OpSpecConstant;") - .AppendLine("mutInstruction.Add(resultType);") - .AppendLine("mutInstruction.Add(resultId);") - .AppendLine("mutInstruction.Add(value);") - .AppendLine("return buffer.Add(mutInstruction);") - - .AppendLine("}"); - } - else if (opname.StartsWith("OpDecorate")) - { - code - .Append("public static Instruction Add").Append(opname).Append("(this TBuffer buffer, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) where TBuffer : IMutSpirvBuffer") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add(new MutRefInstruction([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]));") - - .AppendLine("}"); - } - else if (opname.StartsWith("OpMemberDecorate")) - { - code - .Append("public static Instruction Add").Append(opname).Append("(this TBuffer buffer, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null) where TBuffer : IMutSpirvBuffer") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add(new([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]));") - - .AppendLine("}"); - } - - else if (op.TryGetProperty("operands", out var operands)) - { - var parameters = ConvertOperandsToParameters(op); - var parameterNames = ConvertOperandsToParameterNames(op); - var hasResultId = parameterNames.Contains("resultId") && opname != "OpExtInst"; - if (hasResultId) - { - parameters.Remove(parameters.First(x => x.Contains("resultId"))); - } - var paramsParameters = parameters.Where(x => x.Contains("Span")); - var nullableParameters = parameters.Where(x => x.Contains("?")); - var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); - - code - .Append("public static Instruction Add") - .Append(opname) - .Append("(this TBuffer buffer") - .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(") where TBuffer : IMutSpirvBuffer") - .AppendLine("{") - ; - if (hasResultId) - { - code.AppendLine("var resultId = buffer.GetNextId();"); - } - code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); - code - .AppendLine($"return buffer.Add(new([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]));") - .AppendLine("}"); - } - else - { - code - .Append("public static Instruction Add") - .Append(opname) - .AppendLine("(this TBuffer buffer) where TBuffer : IMutSpirvBuffer") - .AppendLine("{") - - .AppendLine($"return buffer.Add(new([1 << 16 | (int)SDSLOp.{opname}]));") - - .AppendLine("}"); - } - } - - public void CreateGlslOperation(JsonElement op, StringBuilder code) - { - var opname = op.GetProperty("opname").GetString(); - var opcode = op.GetProperty("opcode").GetInt32(); - - if (op.TryGetProperty("operands", out var operands)) - { - var parameters = ConvertOperandsToParameters(op); - parameters.Add("int set"); - - var parameterNames = ConvertOperandsToParameterNames(op); - parameterNames.Add("set"); - - var hasResultId = parameterNames.Contains("resultId"); - - if (hasResultId) - { - parameters.Remove(parameters.First(x => x.Contains("resultId"))); - } - - var paramsParameters = parameters.Where(x => x.Contains("Span")); - var nullableParameters = parameters.Where(x => x.Contains("?")); - var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); - var other = parameterNames.Where(x => x != "resultType" && x != "resultId" && x != "set"); - - - code - .Append("public static Instruction AddGLSL") - .Append(opname) - .Append("(this TBuffer buffer, ") - .Append("IdResultType resultType, ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(") where TBuffer : IMutSpirvBuffer") - .AppendLine("{") - - .AppendLine("var resultId = buffer.GetNextId();") - .Append("Span refs = stackalloc IdRef[]{").Append(string.Join(", ", other)).AppendLine("};") - .AppendLine("if(buffer is MultiBuffer mb)") - - .Append("return mb.AddOpExtInst(") - .Append("set, ") - .Append(opcode) - .Append(", resultId, resultType ") - .AppendLine(", refs);") - - .AppendLine("else if (buffer is WordBuffer wb)") - - .Append("return wb.AddOpExtInst(") - .Append("set, ") - .Append(opcode) - .Append(", resultId, resultType ") - .AppendLine(", refs);") - - .AppendLine("else return Instruction.Empty;") - - .AppendLine("}"); - } - } - - - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj deleted file mode 100644 index 8b313be946..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - netstandard2.0 - true - 12 - - - - - - - - - - - - - - - - - - - - - - - - - $(GetTargetPathDependsOn);GetDependencyTargetPaths - - - - - - - - - - - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CFG/BasicBlock.cs deleted file mode 100644 index 94098c527fbe77165133a794291e795b325da829..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1076 zcmb`GPfNrw5XIkF@H^zF7e9dFrGg-c7X{C;UDx8;F8!m(vR_^OWnyUywXTbVv@esH zHuzHd=T;UVeYxXL=f-h8pf>)wekBkNDT4y@cfz5*0 z7pyf=UMXmI{+?wG`-4{GO^Ns5+G-4p4VIKWkF5qLhJt5;wdDV7m2B+m@Cakf7}>h> z-@p)RcG@tPpoSAU*gLeH;kq|XvXLTAS7;lvv{rMDSFp_Ga5`tdAnTisbo{Mq%-!ib zKF3gp(3^t3 -/// A mixin that can be composed with others -///
-/// -/// -public record Composable(string Name, SortedWordBuffer Buffer) -{ - public InstructionEnumerator GetEnumerator() => new(Buffer); -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs deleted file mode 100644 index ad320eb3a8..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/CompositionSourceProvider.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Stride.Shaders.Spirv.PostProcessing; - -namespace Stride.Shaders.Spirv; - -/// -/// Repository for compositable shaders -/// -public class CompositionSourceProvider -{ - internal static CompositionSourceProvider Instance { get; } = new(); - - readonly Dictionary Composables; - - private CompositionSourceProvider() - { - Composables = new(); - } - - public static void CompileAndRegister(string name) - { - var buffer = PostProcessor.Process(name).ToSorted(); - Register(new(name,buffer)); - } - - public static void Register(Composable composable) - { - Instance.Composables.Add(composable.Name, composable); - } - public static Composable Get(string name) - { - return Instance.Composables[name]; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs deleted file mode 100644 index cdf523b898..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinFilteredInstructionEnumerator.cs +++ /dev/null @@ -1,67 +0,0 @@ -using CommunityToolkit.HighPerformance; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; - - -namespace Stride.Shaders.Spirv; - -/// -/// Instruction enumerator that goes through many mixins with filters. -/// -public ref struct MixinFilteredInstructionEnumerator -{ - MixinGraph Mixins { get; init; } - - MixinInstructionEnumerator enumerator; - - readonly SDSLOp? filter1; - readonly SDSLOp? filter2; - readonly SDSLOp? filter3; - readonly SDSLOp? filter4; - - public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1) - { - Mixins = mixins; - enumerator = mixins.Instructions.GetEnumerator(); - filter1 = f1; - } - public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2) - { - Mixins = mixins; - enumerator = mixins.Instructions.GetEnumerator(); - filter1 = f1; - filter2 = f2; - } - public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2, SDSLOp f3) - { - Mixins = mixins; - enumerator = mixins.Instructions.GetEnumerator(); - filter1 = f1; - filter2 = f2; - filter2 = f3; - } - public MixinFilteredInstructionEnumerator(MixinGraph mixins, SDSLOp f1, SDSLOp f2, SDSLOp f3, SDSLOp f4) - { - Mixins = mixins; - enumerator = mixins.Instructions.GetEnumerator(); - filter1 = f1; - filter2 = f2; - filter3 = f3; - filter4 = f4; - } - public MixinInstruction Current => enumerator.Current; - public bool MoveNext() - { - while(enumerator.MoveNext()) - { - if( - (filter2 == null && enumerator.Current.OpCode == filter1) - || (filter2 != null && filter3 == null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2) - || (filter3 != null && filter4 == null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2 || enumerator.Current.OpCode == filter3) - || (filter4 != null && enumerator.Current.OpCode == filter1 || enumerator.Current.OpCode == filter2 || enumerator.Current.OpCode == filter3 || enumerator.Current.OpCode == filter4) - ) - return true; - } - return false; - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs deleted file mode 100644 index a05cd47af7..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/MixinInstructionEnumerator.cs +++ /dev/null @@ -1,63 +0,0 @@ -using CommunityToolkit.HighPerformance; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; - - -namespace Stride.Shaders.Spirv; - -/// -/// Instruction enumerator that goes through many mixins. -/// -public ref struct MixinInstructionEnumerator -{ - MixinGraph Mixins { get; init; } - - MixinBuffer.InstructionsWrapper.Enumerator lastEnumerator; - int lastMixin; - public int MixinResultId { get; set; } - - bool offsetted; - - public MixinInstructionEnumerator(MixinGraph mixins, bool offsetted) - { - Mixins = mixins; - lastMixin = -1; - MixinResultId = -1; - this.offsetted = offsetted; - } - public MixinInstruction Current => new(Mixins[lastMixin].Name , lastEnumerator.Current); - - public bool MoveNext() - { - var count = Mixins.Count; - if (count == 0) - return false; - else if (lastMixin == -1) - { - lastMixin = 0; - MixinResultId = 1; - lastEnumerator = Mixins[lastMixin].Instructions.GetEnumerator(); - return lastEnumerator.MoveNext(); - } - else - { - while (lastMixin < count) - { - var hadId = lastEnumerator.Current.ResultId != null; - if (lastEnumerator.MoveNext()) - { - MixinResultId += hadId ? 1 : 0; - return true; - } - else - { - lastMixin += 1; - if (lastMixin < count) - lastEnumerator = Mixins[lastMixin].Instructions.GetEnumerator(); - } - } - return false; - } - - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs deleted file mode 100644 index 2f875fadd9..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Enumerators/SortedMixinInstructionEnumerator.cs +++ /dev/null @@ -1,73 +0,0 @@ -using CommunityToolkit.HighPerformance; -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Spirv; - -/// -/// Instruction enumerator that goes through many mixins. Instructions are sorted. -/// -public ref struct SortedMixinInstructionEnumerator -{ - - MixinGraph Mixins { get; init; } - - int currentGroup; - int lastMixin; - int lastIndex; - int boundOffset; - - public SortedMixinInstructionEnumerator(MixinGraph mixins) - { - Mixins = mixins; - currentGroup = 0; - lastIndex = -1; - lastMixin = -1; - boundOffset = -1; - } - public readonly Instruction Current => Mixins[lastMixin].Instructions[lastIndex]; - public bool MoveNext() - { - if (Mixins.Count == 0) - return false; - if (lastMixin == -1) - { - lastMixin = 0; - lastIndex = 0; - boundOffset = 0; - return true; - } - else - { - var count = Mixins.Count; - // If the current mixin has no other - while (currentGroup < 14) - { - while (lastMixin < count) - { - var offset = 1; - var instruction = Mixins[lastMixin].Instructions[lastIndex + offset]; - while (lastIndex + offset < count && instruction.IsEmpty) - { - offset += 1; - } - if (!instruction.IsEmpty && InstructionInfo.GetGroupOrder(instruction.AsRef()) == currentGroup) - { - lastIndex += offset; - return true; - } - else - { - boundOffset += Mixins[lastMixin].Bound; - lastMixin += 1; - lastIndex = 0; - } - } - currentGroup += 1; - lastMixin = 0; - boundOffset = 0; - } - return false; - } - - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md deleted file mode 100644 index 39e22d3855..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Generating-CFG.md +++ /dev/null @@ -1,86 +0,0 @@ -# Generating CFG in spirv - -given this : - -```glsl -for(int i = 0; i< 4; i++) -{ - - fragColor.x = i; -} -``` - -spirv-cross generates - -``` - -// Creating the variable i -%i = OpVariable %_ptr_Function_int Function -// initializing it with 0 - OpStore %i %int_0 -// We define an unconditional branch that always goes to a specific label. - OpBranch %10 -// Specific label to go back to -%10 = OpLabel -// Declares a structed loop, %12 is the merge block (exit), %13 is the continue - OpLoopMerge %12 %13 None -// An OpBranch should come right after an OpLoopMerge to start the branch - OpBranch %14 -%14 = OpLabel -// Load i and register if i is below 4 -%15 = OpLoad %int %i -%18 = OpSLessThan %bool %15 %int_4 -// This OpBranchConditional goes to either %11(code) or %12 (exit) depending %18 - OpBranchConditional %18 %11 %12 -%11 = OpLabel -// This is the code inside the block -%23 = OpLoad %int %i -%24 = OpConvertSToF %float %23 -%28 = OpAccessChain %_ptr_Output_float %fragColor %uint_0 - OpStore %28 %24 -// End of the code inside the block, now go back to %13 to add 1 to i - OpBranch %13 -%13 = OpLabel -%29 = OpLoad %int %i -%31 = OpIAdd %int %29 %int_1 - OpStore %i %31 -// Now go back to %10 to start the loop again - OpBranch %10 -%12 = OpLabel -``` - -While loops are surprisingly simpler. - -``` -int i = 0; -while(i < 4) -{ - fragColor.x = i; - i += 1; -} -``` - -``` -%i = OpVariable %_ptr_Function_int Function - OpStore %i %int_0 - OpBranch %10 -%10 = OpLabel - OpLoopMerge %12 %13 None - OpBranch %14 -%14 = OpLabel -%15 = OpLoad %int %i -%18 = OpSLessThan %bool %15 %int_4 - OpBranchConditional %18 %11 %12 -%11 = OpLabel -%23 = OpLoad %int %i -%24 = OpConvertSToF %float %23 -%28 = OpAccessChain %_ptr_Output_float %fragColor %uint_0 - OpStore %28 %24 -%30 = OpLoad %int %i -%31 = OpIAdd %int %30 %int_1 - OpStore %i %31 - OpBranch %13 -%13 = OpLabel - OpBranch %10 -%12 = OpLabel -``` \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs deleted file mode 100644 index 467f93462b..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.BaseTypes.cs +++ /dev/null @@ -1,273 +0,0 @@ -using CommunityToolkit.HighPerformance; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System.Numerics; - -namespace Stride.Shaders.Spirv; - -public partial class Mixer -{ - - public MixinInstruction FindType(IdRef typeId) - { - foreach(var i in Buffer.Declarations) - { - if (i.OpCode == SDSLOp.OpTypePointer && i.ResultId == typeId) - { - IdRef toFind = i.Words.Span[1]; - foreach (var j in Buffer.Declarations) - { - if (j.ResultId == toFind) - { - var found = j.OpCode switch - { - var tmp when InstructionInfo.OpTypes.Contains(tmp) => true, - _ => false - }; - if (found) - return j; - } - } - } - else if (InstructionInfo.OpTypes.Contains(i.OpCode) && i.ResultId == typeId) - return i; - } - return Instruction.Empty; - } - - public MixinInstruction CreateTypePointer(ReadOnlyMemory type, Spv.Specification.StorageClass storage) - { - var t = GetOrCreateBaseType(type[..^1]); - return Buffer.AddOpTypePointer(storage, t.ResultId ?? -1); - } - public MixinInstruction GetOrCreateBaseType() - where T : struct - { - var v = default(T); - return v switch - { - sbyte t => GetOrCreateBaseType("sbyte".AsMemory()), - byte t => GetOrCreateBaseType("byte".AsMemory()), - short t => GetOrCreateBaseType("short".AsMemory()), - ushort t => GetOrCreateBaseType("ushort".AsMemory()), - int t => GetOrCreateBaseType("int".AsMemory()), - uint t => GetOrCreateBaseType("uint".AsMemory()), - long t => GetOrCreateBaseType("long".AsMemory()), - ulong t => GetOrCreateBaseType("ulong".AsMemory()), - System.Half t => GetOrCreateBaseType("half".AsMemory()), - float t => GetOrCreateBaseType("float".AsMemory()), - double t => GetOrCreateBaseType("double".AsMemory()), - Vector2 t => GetOrCreateBaseType("float2".AsMemory()), - Vector3 t => GetOrCreateBaseType("float3".AsMemory()), - Vector4 t => GetOrCreateBaseType("float4".AsMemory()), - Matrix4x4 t => GetOrCreateBaseType("float4x4".AsMemory()), - Matrix3x2 t => GetOrCreateBaseType("float3x2".AsMemory()), - _ => throw new NotImplementedException() - }; - } - public MixinInstruction GetOrCreateBaseType(ReadOnlyMemory type) - { - var matched = MatchesBaseType(type); - if (matched is null) return Instruction.Empty; - else - { - if (matched.Value.IsScalar) - { - var found = FindScalarType(type); - if (!found.IsEmpty) - return found; - else return matched.Value.BaseType.Span switch - { - "void" => Buffer.AddOpTypeVoid(), - "sbyte" => Buffer.AddOpTypeInt(8, 1), - "byte" => Buffer.AddOpTypeInt(8, 0), - "short" => Buffer.AddOpTypeInt(16, 1), - "ushort" => Buffer.AddOpTypeInt(16, 0), - "int" => Buffer.AddOpTypeInt(32, 1), - "uint" => Buffer.AddOpTypeInt(32, 0), - "long" => Buffer.AddOpTypeInt(64, 1), - "ulong" => Buffer.AddOpTypeInt(64, 0), - "half" => Buffer.AddOpTypeFloat(16, null), - "float" => Buffer.AddOpTypeFloat(32, null), - "double" => Buffer.AddOpTypeFloat(64, null), - _ => throw new NotImplementedException() - }; - } - else if (matched.Value.IsVector) - { - var found = FindVectorType(matched.Value); - if (!found.IsEmpty) - return found; - else - { - var b = GetOrCreateBaseType(matched.Value.BaseType); - if(b.MixinName == "") - return Buffer.AddOpTypeVector(b.ResultId ?? -1, new(matched?.Row)); - else - { - var imported = Buffer.AddOpSDSLImportIdRef(b.MixinName, b.ResultId ?? -1); - return Buffer.AddOpTypeVector(imported.ResultId ?? -1, new(matched?.Row)); - } - } - } - else if (matched.Value.IsMatrix) - { - var found = FindMatrixType(matched.Value); - if (!found.IsEmpty) - return found; - else - { - var b = GetOrCreateBaseType($"{matched.Value.BaseType.Span}{matched?.Row}".AsMemory()); - if (b.MixinName == "") - return Buffer.AddOpTypeMatrix(b.ResultId ?? -1, new(matched?.Row)); - else - { - var imported = Buffer.AddOpSDSLImportIdRef(b.MixinName, b.ResultId ?? -1); - return Buffer.AddOpTypeMatrix(imported.ResultId ?? -1, new(matched?.Row)); - } - } - } - else - throw new NotImplementedException(); - - } - } - - internal MixinInstruction FindMatrixType(in TypeMatch type) - { - var baseType = FindVectorType(type with {Col = null}); - if(baseType.IsEmpty) - return Instruction.Empty; - - // var enumerator = new MixinFilteredInstructionEnumerator(mixins, SDSLOp.OpTypeMatrix); - - // while (enumerator.MoveNext()) - // { - // if (enumerator.Current.Words[2] == baseType.Words[2] && enumerator.Current.Words[3] == type.Col) - // return enumerator.Current; - // } - - var self = new FilteredEnumerator(Buffer.Declarations, SDSLOp.OpTypeMatrix); - - while (self.MoveNext()) - { - if(self.Current.Words.Span[2] == baseType.Words[2] && self.Current.Words.Span[3] == type.Col) - return self.Current; - } - return Instruction.Empty; - } - internal MixinInstruction FindVectorType(in TypeMatch type) - { - var baseType = FindScalarType(type.BaseType); - if(baseType.IsEmpty) - return baseType; - - // var enumerator = new MixinFilteredInstructionEnumerator(mixins, SDSLOp.OpTypeVector); - - // while (enumerator.MoveNext()) - // { - // if (enumerator.Current.Words[2] == baseType.Words[2] && enumerator.Current.Words[3] == type.Row) - // return enumerator.Current; - // } - - var self = new FilteredEnumerator(Buffer.Declarations, SDSLOp.OpTypeVector); - - while (self.MoveNext()) - { - if (self.Current.Words.Span[2] == baseType.Words[2] && self.Current.Words.Span[3] == type.Row) - return self.Current; - } - return Instruction.Empty; - } - - internal MixinInstruction FindScalarType(ReadOnlyMemory type) - { - (SDSLOp Filter, int? Width, int? Sign) filterData = type.Span switch - { - "void" => (SDSLOp.OpTypeVoid, null, null), - "bool" => (SDSLOp.OpTypeBool, null, null), - "byte" => (SDSLOp.OpTypeInt, 8, 0), - "sbyte" => (SDSLOp.OpTypeInt, 8, 1), - "ushort" => (SDSLOp.OpTypeInt, 16, 0), - "short" => (SDSLOp.OpTypeInt, 16, 1), - "int" => (SDSLOp.OpTypeInt, 32, 1), - "uint" => (SDSLOp.OpTypeInt, 32, 0), - "ulong" => (SDSLOp.OpTypeInt, 64, 0), - "long" => (SDSLOp.OpTypeInt, 64, 1), - "half" => (SDSLOp.OpTypeFloat, 16, null), - "float" => (SDSLOp.OpTypeFloat, 32, null), - "double" => (SDSLOp.OpTypeFloat, 64, null), - _ => throw new Exception("Type not known") - }; - var enumerator = new MixinFilteredInstructionEnumerator(Mixins, filterData.Filter); - - // while (enumerator.MoveNext()) - // { - // if ( - // (filterData.Width is null) - // || (filterData.Width is not null && filterData.Sign is null && enumerator.Current.Words[2] == filterData.Width) - // || (filterData.Width is not null && filterData.Sign is not null && enumerator.Current.Words[2] == filterData.Width && enumerator.Current.Words[3] == filterData.Sign) - // ) - // return enumerator.Current; - // } - var self = new FilteredEnumerator(Buffer.Declarations, filterData.Filter); - - while (self.MoveNext()) - { - if ( - (filterData.Width is null) - || (filterData.Width is not null && filterData.Sign is null && self.Current.Words.Span[2] == filterData.Width) - || (filterData.Width is not null && filterData.Sign is not null && self.Current.Words.Span[2] == filterData.Width && self.Current.Words.Span[3] == filterData.Sign) - ) - return self.Current; - } - return Instruction.Empty; - } - - static string[] types = { "bool", "sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "half", "float", "double" }; - - private static TypeMatch? MatchesBaseType(ReadOnlyMemory type) - { - if (type.Span.StartsWith("void") && type.Span.EndsWith("void")) - return new(type, null, null); - foreach (var t in types) - { - var span = type; - bool isPtr = false; - if (span.Span.EndsWith("*")) - { - span = type[..^1]; - isPtr = true; - } - if (span.Span.StartsWith(t) && span.Span.EndsWith(t)) - { - return new(span, null, null, isPtr); - } - else if (span.Span.StartsWith(t)) - { - if (span.Length - t.Length == 1 && char.IsDigit(span.Span[^1])) - { - var num = span.Span[^1] - '0'; - if (num > 1 && num < 5) - return new(t.AsMemory(), num, null); - } - else if (span.Length - t.Length == 3 && char.IsDigit(span.Span[^1]) && char.IsDigit(span.Span[^3]) && span.Span[^2] == 'x') - { - var num1 = span.Span[^3] - '0'; - var num2 = span.Span[^1] - '0'; - if (num1 > 1 && num1 < 5 && num2 > 1 && num2 < 5) - return new(t.AsMemory(), num1, num2, isPtr); - } - } - } - return null; - } -} -internal record struct TypeMatch(ReadOnlyMemory BaseType, int? Row, int? Col, bool IsPointer = false) -{ - public bool IsVoid => BaseType.Span.StartsWith("void") && BaseType.Span.EndsWith("void"); - public bool IsMatrix => Row != null && Col != null; - public bool IsVector => Row != null && Col == null; - public bool IsScalar => Row == null && Col == null; -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs deleted file mode 100644 index ad7ac2b05c..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Compose.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.ComponentModel.Design.Serialization; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; - -namespace Stride.Shaders.Spirv; - -public partial class Mixer -{ - public Mixer ComposeWith(string mixinName, string variableName) - { - // Foreach instruction in mixin to compose - // Insert the instruction - // If the instruction is an OpName for variables, create a new OpName instruction with the same name prefixed by variableName - // Make sure to offset the Ids. - var composable = CompositionSourceProvider.Get(mixinName); - var offset = Buffer.Bound; - Span nameBuffer = stackalloc int[200]; - foreach (var i in composable) - { - if(i.OpCode == SDSLOp.OpName) - { - var name = i.GetOperand("name") ?? throw new Exception("Name is null"); - var newName = $"{variableName}_{name}"; - var buff = nameBuffer[0..(1 + 1 + name.WordCount)]; - buff.Clear(); - var newInstruction = new MutRefInstruction(buff); - newInstruction.Add(i.ResultId ?? -1); - newInstruction.Add(newName); - - Buffer.Add(newInstruction); - } - else - { - - } - } - throw new NotImplementedException(); - return this; - } - - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs deleted file mode 100644 index 22080f7606..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.EntryPoint.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public partial class Mixer -{ - public struct EntryPoint - { - public Mixer mixer; - public ExecutionModel ExecutionModel { get; } - public string Name { get; } - - Instruction function; - public EntryPoint(Mixer mixer, ExecutionModel executionModel, string name) - { - this.mixer = mixer; - ExecutionModel = executionModel; - Name = name; - } - - - - public FunctionBuilder FunctionStart() - { - return new(mixer,this); - } - - public Mixer FinishEntryPoint() - { - mixer.Buffer.AddOpEntryPoint(ExecutionModel, function, Name, Span.Empty); - mixer.Buffer.AddOpExecutionMode( - function, - ExecutionMode.OriginLowerLeft - ); - mixer.Buffer.AddOpCapability(Capability.Shader); - mixer.Buffer.AddOpExtInstImport("GLSL.std.450"); - mixer.Buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); - return mixer; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs deleted file mode 100644 index 05725a34f7..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.Fluent.Inherit.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Spirv; - - -public partial class Mixer -{ - public ref struct Inheritance - { - Mixer mixer; - public Inheritance(Mixer mixer) - { - this.mixer = mixer; - } - - public Inheritance Inherit(string name) - { - mixer.Inherit(name); - return this; - } - public Mixer FinishInherit() - { - return mixer; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs deleted file mode 100644 index 5012f5512a..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.CallFunction.cs +++ /dev/null @@ -1,757 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using static Stride.Shaders.Spirv.Mixer; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - -public ref struct FunctionCallerParameters -{ - public FunctionBuilder Builder {get; private set;} - readonly Mixer mixer => Builder.mixer; - Span inner; - public Span ParameterVariables => inner[..Length]; - public int Length { get; private set; } - - public FunctionCallerParameters(FunctionBuilder builder, Span array) - { - if (array.Length != 16) - throw new ArgumentException("Length must be 16"); - Builder = builder; - inner = array; - Length = 0; - } - - public FunctionCallerParameters With(Instruction value) - { - //var p = mixer.Buffer.AddOpVariable(mixer.FindType(value.ResultType ?? -1), StorageClass.Function, null); - //mixer.Buffer.AddOpStore(p, value, null); - inner[Length] = value.ResultId ?? -1; - Length += 1; - return this; - } -} - -public delegate FunctionCallerParameters CreateCallFunctionParameter(FunctionCallerParameters p); - -public ref partial struct FunctionBuilder -{ - public Instruction Call(string functionName, CreateCallFunctionParameter fp) - { - var parameters = new FunctionCallerParameters(this, stackalloc IdRef[16]); - parameters = fp.Invoke(parameters); - var function = mixer.Buffer.Functions[functionName][0]; - return mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, parameters.ParameterVariables); - } - - public FunctionBuilder CallFunction(string functionName, CreateCallFunctionParameter fp) - { - var parameters = new FunctionCallerParameters(this, stackalloc IdRef[16]); - parameters = fp.Invoke(parameters); - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, parameters.ParameterVariables); - return this; - } - - - public FunctionBuilder CallFunction(string functionName) - { - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, Span.Empty); - return this; - } - public FunctionBuilder CallFunction(string functionName, Instruction param1) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[1] { var1 }); - return this; - } - public FunctionBuilder CallFunction(string functionName, Instruction param1, Instruction param2) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { var1, var2 }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11 - }); - return this; - } - - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11, - Instruction param12 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param12, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11, - var12 - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11, - Instruction param12, - Instruction param13 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param12, null); - var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param13, null); - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11, - var12, - var13, - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11, - Instruction param12, - Instruction param13, - Instruction param14 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param12, null); - var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param13, null); - var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param14, null); - - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11, - var12, - var13, - var14, - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11, - Instruction param12, - Instruction param13, - Instruction param14, - Instruction param15 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param12, null); - var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param13, null); - var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param14, null); - var var15 = mixer.Buffer.AddOpVariable(mixer.FindType(param15), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param15, null); - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11, - var12, - var13, - var14, - var15, - }); - return this; - } - public FunctionBuilder CallFunction( - string functionName, - Instruction param1, - Instruction param2, - Instruction param3, - Instruction param4, - Instruction param5, - Instruction param6, - Instruction param7, - Instruction param8, - Instruction param9, - Instruction param10, - Instruction param11, - Instruction param12, - Instruction param13, - Instruction param14, - Instruction param15, - Instruction param16 - ) - { - var var1 = mixer.Buffer.AddOpVariable(mixer.FindType(param1), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param1, null); - var var2 = mixer.Buffer.AddOpVariable(mixer.FindType(param2), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param2, null); - var var3 = mixer.Buffer.AddOpVariable(mixer.FindType(param3), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param3, null); - var var4 = mixer.Buffer.AddOpVariable(mixer.FindType(param4), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param4, null); - var var5 = mixer.Buffer.AddOpVariable(mixer.FindType(param5), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param5, null); - var var6 = mixer.Buffer.AddOpVariable(mixer.FindType(param6), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param6, null); - var var7 = mixer.Buffer.AddOpVariable(mixer.FindType(param7), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param7, null); - var var8 = mixer.Buffer.AddOpVariable(mixer.FindType(param8), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param8, null); - var var9 = mixer.Buffer.AddOpVariable(mixer.FindType(param9), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param9, null); - var var10 = mixer.Buffer.AddOpVariable(mixer.FindType(param10), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param10, null); - var var11 = mixer.Buffer.AddOpVariable(mixer.FindType(param11), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param11, null); - var var12 = mixer.Buffer.AddOpVariable(mixer.FindType(param12), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param12, null); - var var13 = mixer.Buffer.AddOpVariable(mixer.FindType(param13), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param13, null); - var var14 = mixer.Buffer.AddOpVariable(mixer.FindType(param14), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param14, null); - var var15 = mixer.Buffer.AddOpVariable(mixer.FindType(param15), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param15, null); - var var16 = mixer.Buffer.AddOpVariable(mixer.FindType(param16), StorageClass.Function, null); - mixer.Buffer.AddOpStore(var1, param16, null); - - - var function = mixer.Buffer.Functions[functionName][0]; - mixer.Buffer.AddOpFunctionCall(function.ResultType ?? -1, function.ResultId ?? -1, stackalloc IdRef[] { - var1, - var2, - var3, - var4, - var5, - var6, - var7, - var8, - var9, - var10, - var11, - var12, - var13, - var14, - var15, - var16, - }); - return this; - } - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs deleted file mode 100644 index 645521cb6b..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Conditionals.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.InteropServices; -using System.Runtime.Serialization.Formatters; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public delegate void ConditionBody(FunctionBuilder function); -public delegate Instruction ConditionCheck(FunctionBuilder function); - -public ref struct ConditionalBuilder -{ - Mixer mixer; - FunctionBuilder builder; - - public MutRefInstruction lastLabel; - - public void If(ConditionCheck condition, ConditionBody cf) - { - // TODO: prepare condition - cf.Invoke(builder); - } - public void ElseIf(ConditionCheck condition, ConditionBody cf) - { - // TODO: replace last - // TODO: prepare condition - cf.Invoke(builder); - } - public void Else(ConditionCheck condition, ConditionBody cf) - { - // TODO: replace last - // TODO: prepare condition - cf.Invoke(builder); - } - - public void Finish() - { - //TODO : Finish conditions - } -} - -public ref partial struct FunctionBuilder -{ - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs deleted file mode 100644 index 6fe09d53b0..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Glsl.cs +++ /dev/null @@ -1,447 +0,0 @@ -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.InteropServices; -using System.Runtime.Serialization.Formatters; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public ref partial struct FunctionBuilder -{ - - private IdRef? glslSet = null; - - public void EnsureGlslSet() - { - var exists = false; - if(glslSet != null && glslSet.Value > 0) - return; - else if(glslSet == null) - { - foreach (var i in mixer.Buffer.Declarations.UnorderedInstructions) - { - if (i.OpCode == SDSLOp.OpExtInstImport) - { - var name = i.GetOperand("name") ?? ""; - if (name.Value == "GLSL.std.450") - exists = true; - } - } - if (!exists) - { - glslSet = mixer.Buffer.AddOpExtInstImport("GLSL.std.450"); - } - } - } - - public Instruction Round(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLRound(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction RoundEven(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLRoundEven(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Trunc(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLTrunc(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FAbs(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFAbs(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction SAbs(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSAbs(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FSign(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFSign(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction SSign(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSSign(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Floor(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFloor(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Ceil(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLCeil(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Fract(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFract(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Radians(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLRadians(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Degrees(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLDegrees(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Sin(Instruction x) - { - EnsureGlslSet(); - var result = mixer.Buffer.AddGLSLSin(x.ResultType ?? -1, x, glslSet ?? -1); - return result; - } - public Instruction Cos(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLCos(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Tan(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLTan(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Asin(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAsin(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Acos(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAcos(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Atan(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAtan(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Sinh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSinh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Cosh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLCosh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Tanh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLTanh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Asinh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAsinh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Acosh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAcosh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Atanh(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAtanh(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Atan2(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLAtan2(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction Pow(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPow(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction Exp(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLExp(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Log(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLLog(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Exp2(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLExp2(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Log2(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLLog2(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Sqrt(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSqrt(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction InverseSqrt(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLInverseSqrt(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Determinant(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLDeterminant(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction MatrixInverse(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLMatrixInverse(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Modf(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLModf(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction ModfStruct(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLModfStruct(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FMin(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFMin(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction UMin(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUMin(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction SMin(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSMin(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction FMax(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFMax(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction UMax(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUMax(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction SMax(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSMax(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction FClamp(Instruction x, Instruction minVal, Instruction maxVal) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); - } - public Instruction UClamp(Instruction x, Instruction minVal, Instruction maxVal) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); - } - public Instruction SClamp(Instruction x, Instruction minVal, Instruction maxVal) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); - } - public Instruction FMix(Instruction x, Instruction y, Instruction a) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFMix(x.ResultType ?? -1, x, y, a, glslSet ?? -1); - } - public Instruction IMix(Instruction x, Instruction y, Instruction a) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLIMix(x.ResultType ?? -1, x, y, a, glslSet ?? -1); - } - public Instruction Step(Instruction edge, Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLStep(x.ResultType ?? -1, edge, x, glslSet ?? -1); - } - public Instruction SmoothStep(Instruction edge0, Instruction edge1, Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLSmoothStep(x.ResultType ?? -1, edge0, edge1, x, glslSet ?? -1); - } - public Instruction Fma(Instruction a, Instruction b, Instruction c) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFma(a.ResultType ?? -1, a, b, c, glslSet ?? -1); - } - public Instruction Frexp(Instruction x, Instruction exp) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFrexp(x.ResultType ?? -1, x, exp, glslSet ?? -1); - } - public Instruction FrexpStruct(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFrexpStruct(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Ldexp(Instruction x, Instruction exp) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLLdexp(x.ResultType ?? -1, x, exp, glslSet ?? -1); - } - public Instruction PackSnorm4x8(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackSnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction PackUnorm4x8(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackUnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction PackSnorm2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackSnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction PackUnorm2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackUnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction PackHalf2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackHalf2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction PackDouble2x32(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLPackDouble2x32(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackSnorm2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackSnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackUnorm2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackUnorm2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackHalf2x16(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackHalf2x16(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackSnorm4x8(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackSnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackUnorm4x8(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackUnorm4x8(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction UnpackDouble2x32(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLUnpackDouble2x32(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Length(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLLength(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction Distance(Instruction p0, Instruction p1) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLDistance(p0.ResultType ?? -1, p0, p1, glslSet ?? -1); - } - public Instruction Cross(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLCross(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction Normalize(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLNormalize(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FaceForward(Instruction n, Instruction i, Instruction nref) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFaceForward(n.ResultType ?? -1, n, i, nref, glslSet ?? -1); - } - public Instruction Reflect(Instruction i, Instruction n) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLReflect(i.ResultType ?? -1, i, n, glslSet ?? -1); - } - public Instruction Refract(Instruction i, Instruction n, Instruction eta) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLRefract(i.ResultType ?? -1, i, n, eta, glslSet ?? -1); - } - public Instruction FindILsb(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFindILsb(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FindSMsb(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFindSMsb(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction FindUMsb(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLFindUMsb(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction InterpolateAtCentroid(Instruction x) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLInterpolateAtCentroid(x.ResultType ?? -1, x, glslSet ?? -1); - } - public Instruction InterpolateAtSample(Instruction interpolant, Instruction sample) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLInterpolateAtSample(interpolant.ResultType ?? -1, interpolant, sample, glslSet ?? -1); - } - public Instruction InterpolateAtOffset(Instruction interpolant, Instruction offset) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLInterpolateAtOffset(interpolant.ResultType ?? -1, interpolant, offset, glslSet ?? -1); - } - public Instruction NMin(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLNMin(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction NMax(Instruction x, Instruction y) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLNMax(x.ResultType ?? -1, x, y, glslSet ?? -1); - } - public Instruction NClamp(Instruction x, Instruction minVal, Instruction maxVal) - { - EnsureGlslSet(); - return mixer.Buffer.AddGLSLNClamp(x.ResultType ?? -1, x, minVal, maxVal, glslSet ?? -1); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs deleted file mode 100644 index 4a73e266d8..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.Util.cs +++ /dev/null @@ -1,354 +0,0 @@ -using System.Reflection.Metadata; -using System.Reflection.Metadata.Ecma335; -using System.Runtime.InteropServices; -using System.Runtime.Serialization.Formatters; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public ref partial struct FunctionBuilder -{ - - public readonly Instruction FindVariable(string name) - { - if (mixer.LocalVariables.TryGet(name, out var local)) - return local; - else if (mixer.GlobalVariables.TryGet(name, out var global)) - return global; - else - throw new Exception($"Variable {name} was not found"); - } - - public readonly Instruction Constant(T value) - where T : struct - { - return mixer.CreateConstant(value).Instruction; - } - - public readonly Instruction Load(string name) - { - var variable = FindVariable(name); - var rtype = Instruction.Empty; - foreach (var i in mixer.Buffer.Declarations.UnorderedInstructions) - { - if (i.ResultId != null && i.ResultId == variable.ResultType && i.OpCode != SDSLOp.OpTypePointer) - { - rtype = i; - break; - } - else if (i.ResultId != null && i.ResultId == variable.ResultType && i.OpCode == SDSLOp.OpTypePointer) - { - var toFind = i.GetOperand("type"); - foreach (var j in mixer.Buffer.Declarations.UnorderedInstructions) - { - if (j.ResultId != null && j.ResultId == toFind && j.OpCode != SDSLOp.OpTypePointer) - { - rtype = j; - break; - } - } - break; - } - } - if (rtype.IsEmpty) - throw new Exception("type of variable was not found"); - - return mixer.Buffer.AddOpLoad(rtype, variable, null); - } - public readonly Instruction FindById(int id) - { - foreach (var i in mixer.Buffer.Instructions) - if (i.ResultId == id) - return i; - return Instruction.Empty; - } - - public readonly Instruction Add(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "byte" or "sbyte" - or "ushort" or "short" - or "uint" or "int" - or "long" or "ulong" => mixer.Buffer.AddOpIAdd(rtype, a, b), - "half" or "float" or "double" => mixer.Buffer.AddOpFAdd(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - public readonly Instruction Sub(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "byte" or "sbyte" - or "ushort" or "short" - or "uint" or "int" - or "long" or "ulong" => mixer.Buffer.AddOpISub(rtype, a, b), - "half" or "float" or "double" => mixer.Buffer.AddOpFSub(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - public readonly Instruction Div(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "sbyte" - or "short" - or "int" - or "long" => mixer.Buffer.AddOpSDiv(rtype, a, b), - "byte" - or "ushort" - or "uint" - or "ulong" => mixer.Buffer.AddOpUDiv(rtype, a, b), - "half" or "float" or "double" => mixer.Buffer.AddOpFDiv(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - public readonly Instruction Mul(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "byte" or "sbyte" - or "ushort" or "short" - or "uint" or "int" - or "long" or "ulong" => mixer.Buffer.AddOpIMul(rtype, a, b), - "half" or "float" or "double" => mixer.Buffer.AddOpFMul(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - - public readonly Instruction Mod(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "sbyte" - or "short" - or "int" - or "long" => mixer.Buffer.AddOpSMod(rtype, a, b), - "byte" - or "ushort" - or "uint" - or "ulong" => mixer.Buffer.AddOpUMod(rtype, a, b), - "half" or "float" or "double" => mixer.Buffer.AddOpFMod(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - public readonly Instruction Rem(string resultType, IdRef a, IdRef b) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return resultType switch - { - "sbyte" - or "short" - or "int" - or "long" => mixer.Buffer.AddOpSRem(rtype, a, b), - "byte" - or "ushort" - or "uint" - or "ulong" => throw new Exception("Cannot compute remainder of unsigned number"), - "half" or "float" or "double" => mixer.Buffer.AddOpFRem(rtype, a, b), - _ => throw new NotImplementedException($"{resultType} not yet implemented for this") - }; - } - public readonly Instruction VectorTimesScalar(string resultType, IdRef vector, IdRef scalar) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpVectorTimesScalar(rtype, vector, scalar); - } - public readonly Instruction VectorTimesMatrix(string resultType, IdRef vector, IdRef matrix) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpVectorTimesMatrix(rtype, vector, matrix); - } - public readonly Instruction MatrixTimesScalar(string resultType, IdRef matrix, IdRef scalar) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpMatrixTimesScalar(rtype, matrix, scalar); - } - public readonly Instruction MatrixTimesVector(string resultType, IdRef matrix, IdRef vector) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpMatrixTimesVector(rtype, matrix, vector); - } - public readonly Instruction MatrixTimesMatrix(string resultType, IdRef matrix, IdRef matrix2) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpMatrixTimesMatrix(rtype, matrix, matrix2); - } - - public readonly Instruction OuterProduct(string resultType, IdRef vector1, IdRef vector2) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpOuterProduct(rtype, vector1, vector2); - } - public readonly Instruction Dot(string resultType, IdRef vector1, IdRef vector2) - { - var rtype = mixer.GetOrCreateBaseType(resultType.AsMemory()); - return mixer.Buffer.AddOpDot(rtype, vector1, vector2); - } - - - public readonly Instruction And(string resultType, IdRef operand1, IdRef operand2) - { - return mixer.Buffer.AddOpBitwiseAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); - } - - public readonly Instruction Or(string resultType, IdRef operand1, IdRef operand2) - { - return mixer.Buffer.AddOpBitwiseOr(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); - } - public readonly Instruction Xor(string resultType, IdRef operand1, IdRef operand2) - { - return mixer.Buffer.AddOpBitwiseXor(mixer.GetOrCreateBaseType(resultType.AsMemory()), operand1, operand2); - } - - public readonly Instruction VectorShuffle(string resultType, IdRef vector1, IdRef vector2, Span values) - { - return mixer.Buffer.AddOpVectorShuffle(mixer.GetOrCreateBaseType(resultType.AsMemory()), vector1, vector2, MemoryMarshal.Cast(values)); - } - - - public readonly Instruction ShiftRightLogical(string resultType, IdRef baseId, IdRef shift) - { - return mixer.Buffer.AddOpShiftRightLogical(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); - } - public readonly Instruction ShiftRightArithmetic(string resultType, IdRef baseId, IdRef shift) - { - return mixer.Buffer.AddOpShiftRightArithmetic(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); - } - public readonly Instruction ShiftLeft(string resultType, IdRef baseId, IdRef shift) - { - return mixer.Buffer.AddOpShiftLeftLogical(mixer.GetOrCreateBaseType(resultType.AsMemory()), baseId, shift); - } - - public readonly Instruction GreaterThan(string resultType, IdRef value1, IdRef value2) - { - return resultType switch - { - - string f when - f.StartsWith("half") - || f.StartsWith("float") - || f.StartsWith("double") - => mixer.Buffer.AddOpFOrdGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("sbyte") - || f.StartsWith("short") - || f.StartsWith("int") - || f.StartsWith("long") - => mixer.Buffer.AddOpSGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("byte") - || f.StartsWith("ushort") - || f.StartsWith("uint") - || f.StartsWith("ulong") - => mixer.Buffer.AddOpUGreaterThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - _ => throw new NotImplementedException() - }; - } - public readonly Instruction LessThan(string resultType, IdRef value1, IdRef value2) - { - return resultType switch - { - - string f when - f.StartsWith("half") - || f.StartsWith("float") - || f.StartsWith("double") - => mixer.Buffer.AddOpFOrdLessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("sbyte") - || f.StartsWith("short") - || f.StartsWith("int") - || f.StartsWith("long") - => mixer.Buffer.AddOpSLessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("byte") - || f.StartsWith("ushort") - || f.StartsWith("uint") - || f.StartsWith("ulong") - => mixer.Buffer.AddOpULessThan(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - _ => throw new NotImplementedException() - }; - } - public readonly Instruction GreaterThanEqual(string resultType, IdRef value1, IdRef value2) - { - return resultType switch - { - - string f when - f.StartsWith("half") - || f.StartsWith("float") - || f.StartsWith("double") - => mixer.Buffer.AddOpFOrdGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("sbyte") - || f.StartsWith("short") - || f.StartsWith("int") - || f.StartsWith("long") - => mixer.Buffer.AddOpSGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("byte") - || f.StartsWith("ushort") - || f.StartsWith("uint") - || f.StartsWith("ulong") - => mixer.Buffer.AddOpUGreaterThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - _ => throw new NotImplementedException() - }; - } - public readonly Instruction LessThanEqual(string resultType, IdRef value1, IdRef value2) - { - return resultType switch - { - - string f when - f.StartsWith("half") - || f.StartsWith("float") - || f.StartsWith("double") - => mixer.Buffer.AddOpFOrdLessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("sbyte") - || f.StartsWith("short") - || f.StartsWith("int") - || f.StartsWith("long") - => mixer.Buffer.AddOpSLessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - string f when - f.StartsWith("byte") - || f.StartsWith("ushort") - || f.StartsWith("uint") - || f.StartsWith("ulong") - => mixer.Buffer.AddOpULessThanEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2), - _ => throw new NotImplementedException() - }; - } - - public readonly Instruction LogicalEqual(string resultType, IdRef value1, IdRef value2) - { - return mixer.Buffer.AddOpLogicalEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); - } - public readonly Instruction LogicalNotEqual(string resultType, IdRef value1, IdRef value2) - { - return mixer.Buffer.AddOpLogicalNotEqual(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); - } - public readonly Instruction LogicalAnd(string resultType, IdRef value1, IdRef value2) - { - return mixer.Buffer.AddOpLogicalAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); - } - public readonly Instruction LogicalOr(string resultType, IdRef value1, IdRef value2) - { - return mixer.Buffer.AddOpLogicalAnd(mixer.GetOrCreateBaseType(resultType.AsMemory()), value1, value2); - } - public readonly Instruction LogicalNot(string resultType, IdRef value) - { - return mixer.Buffer.AddOpLogicalNot(mixer.GetOrCreateBaseType(resultType.AsMemory()), value); - } - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs deleted file mode 100644 index 54fa9bc683..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.FunctionBuilder.cs +++ /dev/null @@ -1,194 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using static Stride.Shaders.Spirv.Mixer; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public ref partial struct FunctionBuilder -{ - public record struct Variable(IdRef Id, bool IsVariable); - public record struct Value(IdRef Id, IdResultType Type, bool IsVariable = false) - { - public static implicit operator Value(Instruction i) => new(i, i.ResultType ?? -1, false); - }; - public delegate Variable InitializerDelegate(Mixer mixer, ref FunctionBuilder functionBuilder); - public delegate Value ValueDelegate(Mixer mixer, FunctionBuilder functionBuilder); - - internal Mixer mixer; - Instruction function; - EntryPoint? entryPoint; - - public FunctionBuilder(Mixer mixer, string returnType, string name, CreateFunctionParameters parameterTypesDelegate) - { - this.mixer = mixer; - - - var t = mixer.GetOrCreateBaseType(returnType.AsMemory()); - function = mixer.Buffer.AddOpSDSLFunction(t.ResultId ?? -1, FunctionControlMask.MaskNone, -1, name); - var p = new ParameterBuilder(mixer, stackalloc IdRef[16], stackalloc IdRef[16]); - p = parameterTypesDelegate.Invoke(p); - var t_func = mixer.Buffer.AddOpTypeFunction(t.ResultId ?? -1, p.Types); - function.Operands.Span[3] = t_func.ResultId ?? -1; - mixer.Buffer.AddOpLabel(); - } - public FunctionBuilder(Mixer mixer, EntryPoint entryPoint) - { - this.mixer = mixer; - this.entryPoint = entryPoint; - var t = mixer.GetOrCreateBaseType("void".AsMemory()); - var t_func = mixer.Buffer.AddOpTypeFunction(t.ResultId ?? -1, Span.Empty); - function = mixer.Buffer.AddOpSDSLFunction(t.ResultId ?? -1, FunctionControlMask.MaskNone, t_func, entryPoint.Name); - mixer.Buffer.AddOpLabel(); - - } - - - - public FunctionBuilder Declare(string type, string name) - { - var t = mixer.GetOrCreateBaseType(type.AsMemory()); - var p_t = mixer.Buffer.AddOpTypePointer(StorageClass.Function, t); - mixer.Buffer.AddOpSDSLVariable(p_t, StorageClass.Function, name, null); - return this; - } - /// - /// Declares a variable and assigns a value to it - /// - /// - /// - /// - /// - public FunctionBuilder DeclareAssign(string name, T constant) - where T : struct - { - var resultType = mixer.GetOrCreateBaseType(); - var ptr = mixer.Buffer.AddOpTypePointer(StorageClass.Function, resultType.ResultId ?? -1); - var value = mixer.CreateConstant(constant); - mixer.Buffer.AddOpSDSLVariable(ptr, StorageClass.Function, name, value.ResultId); - return this; - } - public FunctionBuilder Assign(string name, ValueDelegate initializer) - { - // TODO : If the value delegate is a constant no need to be loaded on a register - var result = initializer.Invoke(mixer, this); - if (mixer.LocalVariables.TryGet(name, out var local)) - { - var load = result.Id; - if(result.IsVariable) - load = mixer.Buffer.AddOpLoad(result.Type, result.Id, null).ResultId ?? -1; - mixer.Buffer.AddOpStore(local, load, null); - } - else if (mixer.GlobalVariables.TryGet(name, out var global)) - { - var load = result.Id; - if (result.IsVariable) - load = mixer.Buffer.AddOpLoad(result.Type, result.Id, null); - mixer.Buffer.AddOpStore(global, load, null); - } - return this; - - } - public FunctionBuilder Assign(string name, IdRef value) - { - if (mixer.LocalVariables.TryGet(name, out var local)) - mixer.Buffer.AddOpStore(local, value, null); - else if (mixer.GlobalVariables.TryGet(name, out var global)) - mixer.Buffer.AddOpStore(global, value, null); - return this; - } - public FunctionBuilder AssignConstant(string name, T constantValue) - where T : struct - { - var constant = mixer.CreateConstant(constantValue); - if (mixer.LocalVariables.TryGet(name, out var local)) - mixer.Buffer.AddOpStore(local, constant, null); - else if (mixer.GlobalVariables.TryGet(name, out var global)) - mixer.Buffer.AddOpStore(global, constant, null); - return this; - } - public FunctionBuilder AssignVariable(string destination, string source) - { - // TODO : If the value delegate is a constant no need to be loaded on a register - - Instruction src = Instruction.Empty; - if (mixer.LocalVariables.TryGet(source, out var ls)) - src = ls; - else if (mixer.GlobalVariables.TryGet(source, out var gs)) - src = gs; - - var srcType = mixer.FindType(src.Words.Span[1]); - - if (mixer.LocalVariables.TryGet(destination, out var local)) - { - var load = mixer.Buffer.AddOpLoad(srcType, src, null); - mixer.Buffer.AddOpStore(local, load, null); - } - else if (mixer.GlobalVariables.TryGet(destination, out var global)) - { - var load = mixer.Buffer.AddOpLoad(srcType, src, null); - mixer.Buffer.AddOpStore(global, load, null); - } - return this; - } - public FunctionBuilder Return(ValueDelegate vd) - { - Return(vd.Invoke(mixer, this).Id); - return this; - } - - public FunctionBuilder Return(IdRef? value = null) - { - if (value != null) - mixer.Buffer.AddOpReturnValue(value.Value); - else - mixer.Buffer.AddOpReturn(); - return this; - } - public Mixer FunctionEnd() - { - var count = mixer.IOVariables.Count; - Span idRefs = stackalloc IdRef[count]; - int index = 0; - foreach (var i in mixer.IOVariables) - { - idRefs[index] = i; - index += 1; - } - mixer.Buffer.AddOpFunctionEnd(); - if (entryPoint != null) - { - mixer.Buffer.AddOpEntryPoint(entryPoint.Value.ExecutionModel, function, entryPoint.Value.Name, idRefs); - } - return mixer; - } - - public delegate ParameterBuilder CreateFunctionParameters(ParameterBuilder typeIds); - public ref struct ParameterBuilder - { - Mixer mixer; - Span inner { get; } - Span innerTypes { get; } - public Span Parameters => inner[..count]; - public Span Types => innerTypes[..count]; - int count; - public ParameterBuilder(Mixer mixer, Span parameters, Span types) - { - this.mixer = mixer; - parameters.Clear(); - inner = parameters; - innerTypes = types; - count = 0; - } - - public ParameterBuilder With(string type, string name) - { - var i = mixer.Buffer.AddOpSDSLFunctionParameter(mixer.GetOrCreateBaseType(type.AsMemory()), name); - inner[count] = i.ResultId ?? -1; - innerTypes[count] = i.ResultType ?? -1; - count += 1; - return this; - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs deleted file mode 100644 index fe265233d1..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.IO.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - - -public partial class Mixer -{ - - public IOVariablesFinder IOVariables => new(this); - - public ref struct IOVariablesFinder - { - Mixer mixer; - - public readonly int Count - { - get - { - int result = 0; - foreach (var i in this) - result += 1; - return result; - } - } - public IOVariablesFinder(Mixer mixer) - { - this.mixer = mixer; - } - - public Enumerator GetEnumerator() => new(this); - - public ref struct Enumerator - { - InstructionEnumerator enumerator; - public Enumerator(IOVariablesFinder finder) - { - enumerator = new InstructionEnumerator(finder.mixer.Buffer.Declarations); - } - - public Instruction Current => enumerator.Current; - - public bool MoveNext() - { - while (enumerator.MoveNext()) - { - if (Current.OpCode == SDSLOp.OpSDSLIOVariable) - return true; - } - return false; - } - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs deleted file mode 100644 index 58aebff05a..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/Mixer.cs +++ /dev/null @@ -1,249 +0,0 @@ -using System.Numerics; -using System.Security.Cryptography; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using static Stride.Shaders.Spirv.Core.Buffers.MultiBuffer; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv; - -/// -/// Spirv Mixer object mainly designed around SDSL -/// -public sealed partial class Mixer : MixerBase -{ - //public FunctionFinder Functions => new(this); - //FunctionBuffer functions; - - public MultiBufferLocalVariables LocalVariables => Buffer.LocalVariables; - public MultiBufferGlobalVariables GlobalVariables => Buffer.GlobalVariables; - - - - - public static Inheritance Create(string name) - { - return new(new(name)); - } - - public Mixer(string name) : base(name) - { - Buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); - //buffer.AddOpExtension("SPV_GOOGLE_decorate_string"); - } - - public Mixer WithCapability(Capability capability) - { - Buffer.AddOpCapability(capability); - return this; - } - - public EntryPoint WithEntryPoint(ExecutionModel model, string name) - { - return new EntryPoint(this, model, name); - } - public FunctionBuilder WithFunction(string type, string name, FunctionBuilder.CreateFunctionParameters parameterCreate) - { - return new FunctionBuilder(this, type, name, parameterCreate); - } - - public Mixer Inherit(string mixin) - { - Mixins.Add(mixin); - Buffer.AddOpSDSLMixinInherit(mixin); - return this; - } - - public Mixer WithType(string type, StorageClass? storage = null) - { - if (type.Contains('*')) - CreateTypePointer(type.AsMemory(), storage ?? throw new Exception("storage should not be null")); - else - GetOrCreateBaseType(type.AsMemory()); - return this; - } - - public Mixer WithInput(string type, string name, string semantic, ExecutionModel execution) - { - var t_variable = GetOrCreateBaseType(type.AsMemory()); - var p_t_variable = Buffer.AddOpTypePointer(StorageClass.Input, t_variable.ResultId ?? -1); - Buffer.AddOpSDSLIOVariable(p_t_variable.ResultId ?? -1, StorageClass.Input, execution, name, semantic, null); - return this; - } - public Mixer WithOutput(string type, string name, string semantic, ExecutionModel execution) - { - var t_variable = GetOrCreateBaseType(type.AsMemory()); - var p_t_variable = Buffer.AddOpTypePointer(StorageClass.Output, t_variable.ResultId ?? -1); - Buffer.AddOpSDSLIOVariable(p_t_variable.ResultId ?? -1, StorageClass.Output, execution, name, semantic, null); - return this; - } - - public Mixer WithConstant(string name, T value) - where T : struct - { - CreateConstant(name, value); - return this; - } - public MixinInstruction CreateConstant(T value) - where T : struct - { - return value switch - { - sbyte v => Buffer.AddOpConstant(GetOrCreateBaseType("sbyte".AsMemory()).ResultId ?? -1, v), - short v => Buffer.AddOpConstant(GetOrCreateBaseType("short".AsMemory()).ResultId ?? -1, v), - int v => Buffer.AddOpConstant(GetOrCreateBaseType("int".AsMemory()).ResultId ?? -1, v), - long v => Buffer.AddOpConstant(GetOrCreateBaseType("long".AsMemory()).ResultId ?? -1, v), - byte v => Buffer.AddOpConstant(GetOrCreateBaseType("byte".AsMemory()).ResultId ?? -1, v), - ushort v => Buffer.AddOpConstant(GetOrCreateBaseType("ushort".AsMemory()).ResultId ?? -1, v), - uint v => Buffer.AddOpConstant(GetOrCreateBaseType("uint".AsMemory()).ResultId ?? -1, v), - ulong v => Buffer.AddOpConstant(GetOrCreateBaseType("ulong".AsMemory()).ResultId ?? -1, v), - float v => Buffer.AddOpConstant(GetOrCreateBaseType("float".AsMemory()).ResultId ?? -1, v), - double v => Buffer.AddOpConstant(GetOrCreateBaseType("double".AsMemory()).ResultId ?? -1, v), - Vector2 v => CreateConstantVector(v), - Vector3 v => CreateConstantVector(v), - Vector4 v => CreateConstantVector(v), - _ => throw new NotImplementedException() - }; - } - public MixinInstruction CreateConstantVector(T value) - where T : struct - { - if (value is Vector2 vec2) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float2".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.Y); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1 }); - return cons; - } - else if (value is Vector3 vec3) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float3".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Y); - var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Z); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1 }); - return cons; - } - else if (value is Vector4 vec4) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float4".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Y); - var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Z); - var c4 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.W); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1, c4.ResultId ?? -1 }); - return cons; - } - throw new NotImplementedException(); - } - public MixinInstruction CreateConstant(string name, T value) - where T : struct - { - if (value is sbyte vi8) - { - var t_const = GetOrCreateBaseType("sbyte".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi8); - return cons; - } - else if (value is short vi16) - { - var t_const = GetOrCreateBaseType("short".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi16); - return cons; - } - else if (value is int vi32) - { - var t_const = GetOrCreateBaseType("int".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi32); - return cons; - } - else if (value is long vi64) - { - var t_const = GetOrCreateBaseType("long".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vi64); - return cons; - } - else if (value is byte vu8) - { - var t_const = GetOrCreateBaseType("byte".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu8); - return cons; - } - else if (value is ushort vu16) - { - var t_const = GetOrCreateBaseType("ushort".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu16); - return cons; - } - else if (value is uint vu32) - { - var t_const = GetOrCreateBaseType("uint".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu32); - return cons; - } - else if (value is ulong vu64) - { - var t_const = GetOrCreateBaseType("ulong".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vu64); - return cons; - } - else if (value is float vf32) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vf32); - return cons; - } - else if (value is double vf64) - { - var t_const = GetOrCreateBaseType("double".AsMemory()); - var cons = Buffer.AddOpConstant(t_const.ResultId ?? -1, vf64); - return cons; - } - else if (value is Vector2 vec2) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float2".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec2.Y); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1 }); - return cons; - } - else if (value is Vector3 vec3) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float3".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Y); - var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec3.Z); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1 }); - return cons; - } - else if (value is Vector4 vec4) - { - var t_const = GetOrCreateBaseType("float".AsMemory()); - var t_const2 = GetOrCreateBaseType("float4".AsMemory()); - - var c1 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.X); - var c2 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Y); - var c3 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.Z); - var c4 = Buffer.AddOpConstant(t_const.ResultId ?? -1, vec4.W); - var cons = Buffer.AddOpConstantComposite(t_const2.ResultId ?? -1, stackalloc IdRef[] { c1.ResultId ?? -1, c2.ResultId ?? -1, c3.ResultId ?? -1, c4.ResultId ?? -1 }); - return cons; - } - - throw new NotImplementedException(); - } - public override string ToString() - { - return Disassembler.Disassemble(new SortedWordBuffer(Buffer)); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs deleted file mode 100644 index 376d2d5e06..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixer/MixerBase.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; - -namespace Stride.Shaders.Spirv; - -/// -/// Mixer base class -/// -public abstract class MixerBase -{ - public MixinGraph Mixins {get; protected set;} - public MultiBuffer Buffer {get; protected set;} - - protected Action DisposeBuffers; - - public string Name { get; init; } - - - public MixerBase(string name) - { - Name = name; - Buffer = new(); - Buffer.AddOpSDSLMixinName(Name); - Mixins = new(); - DisposeBuffers = Buffer.Dispose; - } - - public virtual MixinBuffer Build() - { - Buffer.AddOpSDSLMixinEnd(); - // TODO : do some validation here - MixinSourceProvider.Register(new(Name, Buffer)); - DisposeBuffers.Invoke(); - return MixinSourceProvider.Get(Name); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs deleted file mode 100644 index fc9ffbfa75..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/FullMixinInstructions.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; - -namespace Stride.Shaders.Spirv; - -/// -/// Helper to enumerate all instructions from many mixins -/// -public struct FullMixinInstructions -{ - Mixin mixin; - public FullMixinInstructions(Mixin mixin) - { - this.mixin = mixin; - } - - public Enumerator GetEnumerator() => new(mixin); - - public ref struct Enumerator - { - Mixin mixin; - MixinGraph graph; - bool graphFinished; - - MixinInstructionEnumerator enumerator; - InstructionEnumerator self; - - - public MixinInstruction Current => graphFinished ? new(mixin.Name, self.Current) : enumerator.Current; - - public Enumerator(Mixin mixin) - { - this.mixin = mixin; - graphFinished = false; - graph = MixinSourceProvider.GetMixinGraph(mixin.Name); - enumerator = graph.Instructions.GetEnumerator(); - self = mixin.Instructions.GetEnumerator(); - } - - public bool MoveNext() - { - if (enumerator.MoveNext()) - return true; - else - { - if (!graphFinished) - { - self.ResultIdReplacement = -1; - graphFinished = true; - } - return self.MoveNext(); - } - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs deleted file mode 100644 index 3111729a3f..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/Mixin.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Runtime.CompilerServices; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; - -namespace Stride.Shaders.Spirv; - - - - -/// -/// Mixin object -/// -public partial struct Mixin -{ - public static readonly Mixin Empty = new("", SortedWordBuffer.Empty); - - public string Name { get; init; } - public int Bound { get; init; } - public int ResultIdCount { get; init; } - - internal SortedWordBuffer Buffer { get; } - public MixinInstructions Instructions => new(this); - public FullMixinInstructions FullInstructions => new(this); - public MixinParents Parents => new(this); - - public bool IsEmpty => Buffer.IsEmpty; - - - public Mixin(string name, SortedWordBuffer wordBuffer) - { - Name = name; - Buffer = wordBuffer; - ResultIdCount = 0; - Bound = 0; - foreach (var i in Instructions) - { - if (i.ResultId != null) - { - ResultIdCount += 1; - if(i.ResultId > Bound) - Bound = i.ResultId.Value; - } - } - } - - public string Disassemble() - { - var words = new WordBuffer(); - foreach(var e in FullInstructions) - { - words.Insert(e.Instruction); - } - return Disassembler.Disassemble(new UnsortedWordBuffer(words)); - } - - - public override string ToString() - { - return Disassembler.Disassemble(Buffer.Memory); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs deleted file mode 100644 index dd60b4c944..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstruction.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Spirv; - - -/// -/// Wrapper over Instruction for mixins -/// -public ref struct MixinInstruction -{ - public string MixinName { get; init; } - public Instruction Instruction { get; init; } - - public SDSLOp OpCode => Instruction.OpCode; - public int? ResultId => Instruction.ResultId; - public int? ResultType => Instruction.ResultType; - public Span Words => Instruction.Words.Span; - public bool IsEmpty => Instruction.IsEmpty; - - public static implicit operator MixinInstruction(Instruction instruction) => new("",instruction); - public static implicit operator IdRef(MixinInstruction mi) => mi.ResultId ?? throw new Exception("This instruction has no ResultId"); - public static implicit operator IdResultType(MixinInstruction mi) => mi.ResultId ?? throw new Exception("This instruction has no ResultId"); - - public MixinInstruction(string mixinName, Instruction instruction) - { - MixinName = mixinName; - Instruction = instruction; - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs deleted file mode 100644 index 282f90d68e..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinInstructions.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Parsing; - -namespace Stride.Shaders.Spirv; - -/// -/// Helper to enumerate instructions from many mixins -/// -public ref struct MixinInstructions -{ - Mixin mixin; - public MixinInstructions(Mixin mixin) - { - this.mixin = mixin; - } - - public Instruction this[int index] - { - get - { - var count = mixin.Buffer.Length; - if(index >= count) return Instruction.Empty; - var enumerator = GetEnumerator(); - for(int i = 0; enumerator.MoveNext() && i < index; i++); - return enumerator.Current; - } - } - - public InstructionEnumerator GetEnumerator() => mixin.Buffer.GetEnumerator(); -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs deleted file mode 100644 index 5cdaf4b0cb..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Mixin/MixinParents.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Numerics; -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; - -namespace Stride.Shaders.Spirv; - -/// -/// A list of parents built with MemoryOwner from the HighPerformance community toolkit -/// -public class ParentList -{ - MemoryOwner _owner; - public int Length { get; private set; } - - public string this[int index] => _owner.Span[index]; - - public ParentList() - { - _owner = MemoryOwner.Allocate(2); - } - - public ParentList(int size) - { - _owner = MemoryOwner.Allocate(size); - } - - public void Add(string name) - { - if(_owner.Length <= Length +1) - Expand(); - _owner.Span[Length] = name; - Length += 1; - } - - internal void Expand() - { - var r = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)Length + 1),AllocationMode.Clear); - _owner.Span.CopyTo(r.Span); - _owner.Dispose(); - _owner = r; - } - - public Enumerator GetEnumerator() => new(this); - - public ref struct Enumerator - { - readonly ParentList parentList; - int index; - public string Current => parentList[index]; - - public Enumerator(ParentList parentList) - { - this.parentList = parentList; - index = -1; - } - - public bool MoveNext() - { - return ++index < parentList.Length; - } - } - - public void Dispose() => _owner.Dispose(); -} - - -public ref struct MixinParents -{ - Mixin mixin; - public MixinParents(Mixin mixin) - { - this.mixin = mixin; - } - - public FilteredEnumerator GetEnumerator() => new(mixin.Buffer, SDSLOp.OpSDSLMixinInherit); - - public int GetCount() - { - var result = 0; - foreach (var p in this) - result += 1; - return result; - } - public ParentList ToList() - { - var count = GetCount(); - if (GetCount() == 0) - return new(); - var result = new ParentList(count); - foreach (var e in this) - { - foreach (var name in e) - { - result.Add(name.To().Value); - } - } - return result; - } - public MixinGraph ToGraph() - { - return new(ToList()); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs deleted file mode 100644 index 70575cb1e1..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinBuffer.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv; - -public sealed class MixinBuffer -{ - public string Name { get; } - public SortedWordBuffer Declarations { get; } - public SortedFunctionBufferCollection Functions {get;} - public MixinGraph Parents { get; } - public InstructionsWrapper Instructions => new(this); - - public int Bound { - get - { - var bound = 0; - foreach(var i in Declarations) - { - if (i.ResultId > bound) - bound = i.ResultId ?? bound; - } - foreach(var (_,f) in Functions) - foreach (var i in f) - { - if (i.ResultId > bound) - bound = i.ResultId ?? bound; - } - return bound; - } - } - - public MixinBuffer(string name, MultiBuffer buffers) - { - Name = name; - Declarations = new(buffers.Declarations); - Functions = new(buffers.Functions); - Parents = new(); - - foreach(var i in Declarations) - { - if (i.OpCode == Core.SDSLOp.OpSDSLMixinInherit) - Parents.Add(i.GetOperand("mixinName")?.Value!); - } - } - - public ref struct InstructionsWrapper - { - MixinBuffer buffer; - public InstructionsWrapper(MixinBuffer buffer) - { - this.buffer = buffer; - } - - - public Instruction this[int index] - { - get - { - var e = GetEnumerator(); - for(int i = 0; i < index -1; i++) - { - e.MoveNext(); - } - return e.MoveNext() ? e.Current : throw new IndexOutOfRangeException(); - } - } - - public Enumerator GetEnumerator() => new(buffer); - - public ref struct Enumerator - { - MixinBuffer buffer; - - InstructionEnumerator declarations; - SortedFunctionBufferCollection.FunctionsInstructions.Enumerator functions; - bool finishedDecl; - - public Enumerator(MixinBuffer buffer) - { - this.buffer = buffer; - declarations = buffer.Declarations.GetEnumerator(); - functions = buffer.Functions.Instructions.GetEnumerator(); - } - - public Instruction Current => !finishedDecl ? declarations.Current : functions.Current; - - public bool MoveNext() - { - if (declarations.MoveNext()) - return true; - else if (functions.MoveNext()) - { - if(!finishedDecl) - finishedDecl = true; - return true; - } - else - return false; - } - } - } - - public override string ToString() - { - return - new StringBuilder() - .Append(Disassembler.Disassemble(Declarations)) - .Append(string.Join("\n", Functions.Buffers.Select(x => Disassembler.Disassemble(x.Value)))) - .ToString(); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs deleted file mode 100644 index a569a1ebbf..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinCollection.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections; -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Spirv; - -/// -/// Collections of mixins -/// -internal struct MixinList : IList -{ - List mixins; - - public MixinList() - { - mixins = new(); - } - - public string this[int index] { get => mixins[index]; set => throw new Exception();} - - public int Count => mixins.Count; - - public bool IsReadOnly => false; - - public void Add(string mixin) - { - if (!mixins.Contains(mixin)) - mixins.Add(mixin); - } - - public void Clear() - { - mixins.Clear(); - } - - public bool Contains(string item) - { - return mixins.Contains(item); - } - - public void CopyTo(string[] array, int arrayIndex) - { - mixins.CopyTo(array, arrayIndex); - } - - public IEnumerator GetEnumerator() - { - return mixins.GetEnumerator(); - } - - public int IndexOf(string item) - { - return mixins.IndexOf(item); - } - - public void Insert(int index, string item) - { - mixins.Insert(index,item); - } - - public bool Remove(string item) - { - return mixins.Remove(item); - } - - public void RemoveAt(int index) - { - mixins.RemoveAt(index); - } - - public List AsList() => mixins; - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } -} - -public ref struct MixinEnumerator -{ - List mixinNames; - List.Enumerator enumerator; - - public MixinEnumerator(List names) - { - mixinNames = names; - enumerator = mixinNames.GetEnumerator(); - } - - public MixinBuffer Current => MixinSourceProvider.Get(enumerator.Current); - - public bool MoveNext() => enumerator.MoveNext(); -} - diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs deleted file mode 100644 index 5e70d1b260..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinGraph.cs +++ /dev/null @@ -1,92 +0,0 @@ -namespace Stride.Shaders.Spirv; - - -public record struct MixinGraphInstructions(MixinGraph Graph, bool Offsetted = false) -{ - - public readonly int Count - { - get - { - int count = 0; - foreach (var e in this) - count += 1; - return count; - } - } - public readonly MixinInstructionEnumerator GetEnumerator() => new(Graph, Offsetted); -} - -/// -/// Representation of mixin parents to a graph. -/// -public class MixinGraph -{ - public ParentList Names { get; private set; } - internal MixinList DistinctNames { get; private set; } - - public MixinGraphInstructions OffsettedInstructions => new(this,true); - public MixinGraphInstructions Instructions => new(this); - - public int Count => GetCount(); - - public MixinBuffer this[int index] - { - get - { - if(index >= Count) - throw new IndexOutOfRangeException(); - var enumerator = GetEnumerator(); - for (int i = 0; enumerator.MoveNext() && i < index; i++){} - return enumerator.Current; - } - } - - public MixinGraph() - { - Names = new(); - DistinctNames = new(); - } - - public MixinGraph(ParentList names) - { - Names = names; - DistinctNames = new(); - RebuildGraph(); - } - - public MixinEnumerator GetEnumerator() => new(DistinctNames.AsList()); - - public void Add(string mixin) - { - Names.Add(mixin); - RebuildGraph(); - } - - public void RebuildGraph() - { - DistinctNames.Clear(); - foreach (var m in Names) - { - FillMixinHashSet(m); - } - } - - void FillMixinHashSet(string name) - { - if(MixinSourceProvider.TryGetMixinGraph(name, out var graph) && graph != null) - { - foreach (var m in graph) - FillMixinHashSet(m.Name); - DistinctNames.Add(name); - } - } - int GetCount() - { - int count = 0; - var e = GetEnumerator(); - while (e.MoveNext()) - count += 1; - return count; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs deleted file mode 100644 index ddac26ff5a..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/MixinSourceProvider.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Stride.Shaders.Spirv; - -/// -/// Mixin buffer repository -/// -public class MixinSourceProvider -{ - - internal static MixinSourceProvider Instance { get; } = new(); - - readonly Dictionary Mixins; - readonly Dictionary MixinGraph; - - private MixinSourceProvider() - { - Mixins = new(); - MixinGraph = new(); - } - - public static void Register(MixinBuffer mixin) - { - Instance.Mixins.Add(mixin.Name, mixin); - Instance.MixinGraph.Add(mixin.Name, mixin.Parents); - } - public static MixinBuffer Get(string name) - { - return Instance.Mixins[name]; - } - public static MixinGraph GetMixinGraph(string name) - { - return Instance.MixinGraph[name]; - } - public static bool TryGetMixinGraph(string name, out MixinGraph? graph) - { - return Instance.MixinGraph.TryGetValue(name, out graph); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs deleted file mode 100644 index f83fcf8a82..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/BoundReducer.cs +++ /dev/null @@ -1,127 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - - -/// -/// Makes sure indices used in spirv module are all continuous. -/// -public struct BoundReducer : INanoPass -{ - public BoundReducer() { } - - public void Apply(MultiBuffer buffer) - { - // First step is to find the next idResult - // If it's previous + 1 then it's okay, previous is now updated - // If it's above previous + 1, then it's not okay and we switch - - var finished = false; - var previousId = 0; - var next = Instruction.Empty; - var countIds = 0; - - foreach (var i in buffer.Instructions) - countIds += i.ResultId != null ? 1 : 0; - while (!finished && previousId < countIds) - { - var countAbove = 0; - foreach(var i in buffer.Instructions) - { - if(i.ResultId == previousId + 1) - { - countAbove += 1; - previousId += 1; - next = i; - break; - } - else if (next.IsEmpty && i.ResultId > previousId + 1) - { - countAbove += 1; - next = i; - } - else if(!next.IsEmpty && i.ResultId > previousId + 1 && i.ResultId < next.ResultId) - { - countAbove += 1; - next = i; - } - } - if (countAbove == 0) - finished = true; - else if(next.ResultId > previousId + 1) - { - next.AsRef().SetResultId(previousId + 1); - ReplaceRefs(next.ResultId ?? -1, previousId + 1, buffer); - } - } - - - buffer.RecomputeBound(); - } - static void ReplaceRefs(int from, int to, MultiBuffer buffer) - { - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - foreach (var (_, f) in buffer.Functions) - foreach (var i in f.UnorderedInstructions) - { - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } - static void ReplaceRefs(int from, int to, WordBuffer func) - { - foreach (var i in func.UnorderedInstructions) - { - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs deleted file mode 100644 index 4c96418b09..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CapabilitiesCompute.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Processing; - -public struct CapabilitiesCompute : INanoPass -{ - public void Apply(MultiBuffer buffer) - { - throw new NotImplementedException("Needs to finish checking the spec"); - } - - public static void AddCapabilities(Instruction instruction) - { - if(instruction.OpCode == SDSLOp.OpEntryPoint) - { - if(instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.Geometry) - { - //Add capability geometry - } - else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationControl) - { - //Add capability tess - - } - else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationEvaluation) - { - //Add capability tess - } - } - else if(instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 16) - { - // Add capability Float16 - } - else if (instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 64) - { - // Add capability Float64 - } - else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 64) - { - // Add capability Float64 - } - else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 16) - { - // Add capability Float64 - } - else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 8) - { - // Add capability Float64 - } - - // TODO : Check if any atomic instructions operates on integers - // else if (instruction.OpCode == SDSLOp.OpAtomic && instruction.Words.Span[2] == 64) - // { - // // Add capability Float64 - // } - - - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs deleted file mode 100644 index 89d4fd0acb..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/CompressBuffer.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; - -namespace Stride.Shaders.Spirv.PostProcessing; - -public struct CompressBuffer : INanoPass -{ - public void Apply(MultiBuffer buffer) - { - using var tmp = new WordBuffer(); - foreach (var e in buffer.Declarations.UnorderedInstructions) - if (e.OpCode != SDSLOp.OpNop) - tmp.Insert(e); - buffer.Declarations.InstructionSpan.Clear(); - tmp.InstructionSpan.CopyTo(buffer.Declarations.InstructionSpan); - buffer.Declarations.RecomputeLength(); - foreach (var (_, f) in buffer.Functions) - { - tmp.InstructionSpan.Clear(); - tmp.RecomputeLength(); - foreach (var e in f.UnorderedInstructions) - if (e.OpCode != SDSLOp.OpNop) - tmp.Insert(e); - f.InstructionSpan.Clear(); - tmp.InstructionSpan.CopyTo(f.InstructionSpan); - f.RecomputeLength(); - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs deleted file mode 100644 index 84e8e6e74e..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/FunctionVariableOrderer.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core; -namespace Stride.Shaders.Spirv.Processing; - -/// -/// Makes sure variables are created in the beginning of a function definition -/// -public struct FunctionVariableOrderer : INanoPass -{ - public void Apply(MultiBuffer buffer) - { - foreach(var (_,f) in buffer.Functions) - { - ProcessFunction(new(f.InstructionSpan)); - f.RecomputeLength(); - } - } - public static void ProcessFunction(SpirvSpan function) - { - using var tmp = new SpirvBuffer(function.Span.Length); - var enumerator = function.GetEnumerator(); - enumerator.MoveNext(); - var opf = enumerator.Current; - tmp.Insert(tmp.Length, opf.Words); - foreach(var i in function) - { - if(i.OpCode == SDSLOp.OpFunctionParameter) - tmp.Insert(tmp.Length, i.Words); - } - while(enumerator.Current.OpCode != SDSLOp.OpLabel) - enumerator.MoveNext(); - - tmp.Insert(tmp.Length, enumerator.Current.Words); - - foreach (var i in function) - { - if(i.OpCode == SDSLOp.OpVariable) - { - tmp.Insert(tmp.Length,i.Words); - } - } - while(enumerator.MoveNext()) - { - var i = enumerator.Current; - if (i.OpCode != SDSLOp.OpVariable && i.OpCode != SDSLOp.OpFunctionParameter) - { - tmp.Insert(tmp.Length, i.Words); - } - if (i.OpCode == SDSLOp.OpSDSLVariable) - { - var t = 0; - } - } - function.Span.Clear(); - tmp.InstructionSpan.CopyTo(function.Span); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs deleted file mode 100644 index 0fb6cfad62..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOReplace.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.PostProcessing; - -public struct SDSLVariableReplace : INanoPass -{ - public void Apply(MultiBuffer buffer) - { - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - if (i.OpCode == SDSLOp.OpSDSLIOVariable) - { - - var sclassv = i.GetOperand("storageclass"); - var sclass = StorageClass.Private; - if (sclassv != null) - sclass = (StorageClass)sclassv.Value.Words; - var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); - variable.Operands.Span[1] = i.ResultId ?? -1; - buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); - SetOpNop(i.Words.Span); - } - else if (i.OpCode == SDSLOp.OpSDSLVariable) - { - var sclassv = i.GetOperand("storageclass"); - var sclass = StorageClass.Private; - if (sclassv != null) - sclass = (StorageClass)sclassv.Value.Words; - var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); - variable.Operands.Span[1] = i.ResultId ?? -1; - buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); - SetOpNop(i.Words.Span); - } - } - foreach (var (n, f) in buffer.Functions) - { - foreach (var i in f.UnorderedInstructions) - { - if(i.OpCode == SDSLOp.OpSDSLFunctionParameter) - { - var name = i.GetOperand("name"); - var resultType = i.ResultType ?? -1; - var variable = f.AddOpFunctionParameter(resultType); - variable.Operands.Span[1] = i.ResultId ?? -1; - buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); - SetOpNop(i.Words.Span); - } - else if (i.OpCode == SDSLOp.OpSDSLVariable) - { - - var sclassv = i.GetOperand("storageclass"); - var sclass = StorageClass.Private; - if (sclassv != null) - sclass = (StorageClass)sclassv.Value.Words; - var name = i.GetOperand("name"); - var resultType = i.ResultType ?? -1; - var initializer = i.GetOperand("initializer"); - var variable = f.AddOpVariable(resultType, sclass, initializer); - variable.Operands.Span[1] = i.ResultId ?? -1; - buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); - SetOpNop(i.Words.Span); - } - } - } - } - static void SetOpNop(Span words) - { - words[0] = words.Length << 16; - words[1..].Clear(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs deleted file mode 100644 index ac515a402a..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IOVariableDecorator.cs +++ /dev/null @@ -1,505 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.PostProcessing; - -public struct IOVariableDecorator : INanoPass -{ - public void Apply(MultiBuffer buffer) - { - int inputLocation = -1; - int outputLocation = -1; - foreach (var i in buffer.Declarations) - { - if(i.OpCode == SDSLOp.OpSDSLIOVariable) - { - var execution = (ExecutionModel)(i.GetOperand("executionModel")?.Words ?? -1); - var storage = (StorageClass)(i.GetOperand("storageclass")?.Words ?? -1); - var semantic = i.GetOperand("semantic")?.Value ?? throw new NotImplementedException(); - if (semantic == "SV_Position") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage,execution) switch - { - (StorageClass.Input, ExecutionModel.Fragment) => (int)BuiltIn.FragCoord, - (StorageClass.Input or StorageClass.Output, _) - => (int)BuiltIn.Position, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_ClipDistance") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Input or StorageClass.Output, _) - => (int)BuiltIn.ClipDistance, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_CullDistance") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Input or StorageClass.Output, _) - => (int)BuiltIn.CullDistance, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_VertexID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Input, ExecutionModel.Vertex) - => (int)BuiltIn.VertexIndex, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_InstanceID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Input, ExecutionModel.Vertex) - => (int)BuiltIn.InstanceIndex, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_Depth" || semantic == "SV_DepthGreaterEqual" || semantic == "SV_DepthLessEqual") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Output,ExecutionModel.Fragment) - => (int)BuiltIn.FragDepth, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_IsFrontFace") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - (StorageClass.Input, ExecutionModel.Fragment) - => (int)BuiltIn.FrontFacing, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_DispatchThreadID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.GLCompute - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - or ExecutionModel.TaskEXT - or ExecutionModel.TaskNV - ) - => (int)BuiltIn.GlobalInvocationId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_GroupID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.GLCompute - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - or ExecutionModel.TaskEXT - or ExecutionModel.TaskNV - ) - => (int)BuiltIn.WorkgroupId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_GroupThreadID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.GLCompute - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - or ExecutionModel.TaskEXT - or ExecutionModel.TaskNV - ) - => (int)BuiltIn.LocalInvocationId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_GroupIndex") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.GLCompute - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - or ExecutionModel.TaskEXT - or ExecutionModel.TaskNV - ) - => (int)BuiltIn.LocalInvocationIndex, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_OutputControlPointID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.TessellationControl - ) - => (int)BuiltIn.InvocationId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_GSInstanceID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Geometry - ) - => (int)BuiltIn.InvocationId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_DomainLocation") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.TessellationEvaluation - ) - => (int)BuiltIn.TessCoord, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_PrimitiveID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.TessellationControl - or ExecutionModel.TessellationEvaluation - or ExecutionModel.Geometry - or ExecutionModel.Fragment - ) - or( - StorageClass.Output, - ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - or ExecutionModel.Geometry - ) - => (int)BuiltIn.TessCoord, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_TessFactor") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.TessellationControl - ) - => (int)BuiltIn.TessLevelOuter, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_InsideTessFactor") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.TessellationControl - ) - => (int)BuiltIn.TessLevelInner, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_SampleIndex") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - => (int)BuiltIn.SampleId, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_StencilRef") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Output, - ExecutionModel.Fragment - ) - => (int)BuiltIn.FragStencilRefEXT, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_Barycentrics") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - => (int)BuiltIn.BaryCoordKHR, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_RenderTargetArrayIndex") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - or - ( - StorageClass.Output, - ExecutionModel.Geometry - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - ) - => (int)BuiltIn.Layer, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_ViewportArrayIndex") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - or - ( - StorageClass.Output, - ExecutionModel.Geometry - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - ) - => (int)BuiltIn.ViewportIndex, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_Coverage") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input or StorageClass.Output, - ExecutionModel.Fragment - ) - => (int)BuiltIn.SampleMask, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_InnerCoverage") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - => (int)BuiltIn.FullyCoveredEXT, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_ViewID") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Input, - ExecutionModel.Vertex - or ExecutionModel.TessellationControl - or ExecutionModel.TessellationEvaluation - or ExecutionModel.Geometry - or ExecutionModel.Fragment - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - ) - => (int)BuiltIn.ViewIndex, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_ShadingRate") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Output, - ExecutionModel.Vertex - or ExecutionModel.Geometry - or ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - ) - => (int)BuiltIn.PrimitiveShadingRateKHR, - ( - StorageClass.Input, - ExecutionModel.Fragment - ) - => (int)BuiltIn.ShadingRateKHR, - _ => throw new NotImplementedException() - } - ); - } - else if (semantic == "SV_CullPrimitive") - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.BuiltIn, - (storage, execution) switch - { - ( - StorageClass.Output, - ExecutionModel.MeshEXT - or ExecutionModel.MeshNV - ) - => (int)BuiltIn.CullPrimitiveEXT, - _ => throw new NotImplementedException() - } - ); - } - else - { - buffer.AddOpDecorate( - i.ResultId ?? -1, - Decoration.Location, - (storage, execution) switch - { - (StorageClass.Input, _) - => ++inputLocation, - (StorageClass.Output, _) - => ++outputLocation, - _ => throw new NotImplementedException() - } - ); - } - } - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs deleted file mode 100644 index 2423f0caae..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IdRefOffsetter.cs +++ /dev/null @@ -1,41 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - - -/// -/// Offsets ids for each mixins inherited -/// -public struct IdRefOffsetter : INanoPass -{ - public IdRefOffsetter() { } - - public void Apply(MultiBuffer buffer) - { - //int offset = 0; - //int nextOffset = 0; - //foreach (var i in buffer) - //{ - // // if we hit a mixin name we reset stuff - // if (i.OpCode == SDSLOp.OpSDSLMixinName) - // { - // offset += nextOffset; - // nextOffset = 0; - // } - // else - // { - // if (i.ResultId != null) - // nextOffset = i.ResultId.Value; - // i.AsRef().OffsetIds(offset); - // } - //} - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs deleted file mode 100644 index 2593e1d8ca..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MemoryModelDuplicatesRemover.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - -/// -/// Checks for duplicate memory models in case of multiple entry points -/// -public struct MemoryModelDuplicatesRemover : INanoPass -{ - - public void Apply(MultiBuffer buffer) - { - var found = false; - var wid = 0; - var span = buffer.Declarations.InstructionSpan; - while(wid < buffer.Declarations.Length) - { - if ((span[wid] & 0xFFFF) == (int)SDSLOp.OpMemoryModel) - { - if (!found) - found = true; - else - SetOpNop(span.Slice(wid, span[wid] >> 16)); - } - wid += span[wid] >> 16; - } - } - - static void SetOpNop(Span words) - { - words[0] = words.Length << 16; - words[1..].Clear(); - } - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs deleted file mode 100644 index 2c44736eae..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/MixinMerger.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - -public record struct OrderedSpvBuffer(SpirvBuffer Buffer) -{ - public readonly OrderedEnumerator GetEnumerator() => new(Buffer); -} - -/// -/// Merges mixins into one final spirv file -/// -public struct MixinMerger : INanoPass -{ - public readonly void Apply(MultiBuffer buffer) - { - //var temp = new SpirvBuffer(); - //var ordered = new OrderedSpvBuffer(buffer); - //foreach (var e in ordered) - // if(e.OpCode != SDSLOp.OpNop) - // temp.Add(e.Words.Span); - - //buffer.Replace(temp, out var dispose); - //if(dispose) - // temp.Dispose(); - //buffer.RecomputeBound(); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs deleted file mode 100644 index d75e8f140f..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/PostProcessor.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; - -namespace Stride.Shaders.Spirv.PostProcessing; - -/// -/// Nano pass merger/optimizer/compiler -/// -public static class PostProcessor -{ - public static SpirvBuffer Process(string mixinName) - { - var buffer = new MultiBuffer(); - var mixin = MixinSourceProvider.Get(mixinName); - var parents = MixinSourceProvider.GetMixinGraph(mixinName); - var bound = 0; - foreach(var p in parents) - { - foreach (var i in p.Instructions) - buffer.Duplicate(i.AsRef(), bound); - bound += p.Bound; - } - foreach(var i in mixin.Instructions) - buffer.Duplicate(i.AsRef(), bound); - Apply(buffer); - - return new(buffer); - } - - static void Apply(MultiBuffer buffer) - { - Apply(buffer); - Apply(buffer); - Apply(buffer); - Apply(buffer); - Apply(buffer); - Apply(buffer); - Apply(buffer); - } - - static void Apply(MultiBuffer buffer) - where T : struct, INanoPass - { - var p = new T(); - p.Apply(buffer); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs deleted file mode 100644 index 8a1c6bcff2..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/SDSLOpRemover.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - -/// -/// Removes SDSL specific instructions -/// -public struct SDSLOpRemover : INanoPass -{ - - public void Apply(MultiBuffer buffer) - { - var decl = new InstructionEnumerator(buffer.Declarations); - while(decl.MoveNext()) - { - var i = decl.Current; - if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) - SetOpNop(i.AsRef()); - } - foreach (var (_, f) in buffer.Functions) - { - var func = new InstructionEnumerator(f); - while(func.MoveNext()) - { - var i = func.Current; - if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) - SetOpNop(i.AsRef()); - } - } - } - - static void SetOpNop(RefInstruction i) - { - i.Words[0] = i.WordCount << 16; - i.Operands.Clear(); - } - -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs deleted file mode 100644 index c2f05efe99..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/TypeDuplicatesRemover.cs +++ /dev/null @@ -1,206 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - - - -/// -/// Remove duplicate simple types. -/// Should be applied before the IdRefOffsetter. -/// -public struct TypeDuplicateRemover : INanoPass -{ - - public readonly void Apply(MultiBuffer buffer) - { - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) - { - foreach (var j in buffer.Declarations.UnorderedInstructions) - { - if ( - (j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words.Span); - } - } - } - } - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - if (i.OpCode == SDSLOp.OpTypeVector) - { - foreach (var j in buffer.Declarations.UnorderedInstructions) - { - if ( - j.OpCode == SDSLOp.OpTypeVector - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words.Span); - } - } - } - } - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - if (i.OpCode == SDSLOp.OpTypeMatrix) - { - foreach (var j in buffer.Declarations.UnorderedInstructions) - { - if ( - j.OpCode == SDSLOp.OpTypeMatrix - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words.Span); - } - } - } - } - //var idx1 = 0; - //// First base types - //foreach (var i in buffer.Declarations.UnorderedInstructions) - //{ - // if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) - // { - // var idx2 = 0; - // foreach (var j in buffer.Declarations) - // { - // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) - // { - // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - // SetOpNop(j.Words.Span); - // } - // idx2 += 1; - // } - // } - // else if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeBool) - // { - // var idx2 = 0; - // foreach (var j in buffer.Declarations) - // { - // if (j.OpCode == i.OpCode && idx1 != idx2) - // { - // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - // SetOpNop(j.Words.Span); - // } - // idx2 += 1; - // } - // } - // idx1 += 1; - //} - //idx1 = 0; - //// Then vectors - //foreach (var i in buffer.Declarations.UnorderedInstructions) - //{ - // if (i.OpCode == SDSLOp.OpTypeVector) - // { - // var idx2 = 0; - // foreach (var j in buffer.Declarations) - // { - // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) - // { - // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - // SetOpNop(j.Words.Span); - // } - // idx2 += 1; - // } - // } - // idx1 += 1; - //} - //idx1 = 0; - - //// Then matrices - //foreach (var i in buffer.Declarations.UnorderedInstructions) - //{ - // if (i.OpCode == SDSLOp.OpTypeMatrix) - // { - // var idx2 = 0; - // foreach (var j in buffer.Declarations) - // { - // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) - // { - // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - // SetOpNop(j.Words.Span); - // } - // idx2 += 1; - // } - // } - // idx1 += 1; - //} - - } - - static void ReplaceRefs(int from, int to, MultiBuffer buffer) - { - foreach (var i in buffer.Declarations.UnorderedInstructions) - { - var opcode = i.OpCode; - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - if (op.Words[0] == from || op.Words[1] == from) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } - foreach (var (_, f) in buffer.Functions) - foreach (var i in f.UnorderedInstructions) - { - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - if (op.Words[0] == from || op.Words[1] == from) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } - } - - static void SetOpNop(Span words) - { - words[0] = words.Length << 16; - words[1..].Clear(); - } -} diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj b/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj deleted file mode 100644 index a352bb781f..0000000000 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - net9.0 - enable - enable - - - - - - - - - - - - diff --git a/src/Stride.Shaders.Parsing.Tests/ParsingTests.cs b/src/Stride.Shaders.Tests/ParsingTests.cs similarity index 100% rename from src/Stride.Shaders.Parsing.Tests/ParsingTests.cs rename to src/Stride.Shaders.Tests/ParsingTests.cs diff --git a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj similarity index 90% rename from src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj rename to src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index a012f8f3f3..f6346ae7e6 100644 --- a/src/Stride.Shaders.Parsing.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -23,7 +23,7 @@ - + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs b/src/Stride.Shaders/Core/AssignOperators.cs similarity index 98% rename from src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs rename to src/Stride.Shaders/Core/AssignOperators.cs index 2cd8dee1c2..ab76548969 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/AssignOperator.cs +++ b/src/Stride.Shaders/Core/AssignOperators.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Core; public enum AssignOperator { diff --git a/src/Stride.Shaders/Core/EntryPoints.cs b/src/Stride.Shaders/Core/EntryPoints.cs new file mode 100644 index 0000000000..793de82e25 --- /dev/null +++ b/src/Stride.Shaders/Core/EntryPoints.cs @@ -0,0 +1,29 @@ +namespace Stride.Shaders.Core; + + +public enum EntryPoint : uint +{ + None = 0, + VertexShader = 1, + PixelShader = 1 << 1, + ComputeShader = 1 << 2, + GeometryShader = 1 << 3, + /// + /// Tesselation control + /// + HullShader = 1 << 4, + /// + /// Tesselation evaluation + /// + DomainShader = 1 << 5, + TaskNV = 1 << 6, + MeshNV = 1 << 7, + RayGeneration = 1 << 8, + Intersection = 1 << 9, + AnyHit = 1 << 10, + ClosestHit = 1 << 11, + Miss = 1 << 12, + Callable = 1 << 13, + TaskEXT = 1 << 14, + MeshEXT = 1 << 15, +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs b/src/Stride.Shaders/Core/Operators.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs rename to src/Stride.Shaders/Core/Operators.cs index 7753080fc1..ceb29ef54a 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Operator.cs +++ b/src/Stride.Shaders/Core/Operators.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Parsing.SDSL; +namespace Stride.Shaders.Core; public enum Operator { diff --git a/src/Stride.Shaders/Core/StreamUsage.cs b/src/Stride.Shaders/Core/StreamUsage.cs new file mode 100644 index 0000000000..1be930f32c --- /dev/null +++ b/src/Stride.Shaders/Core/StreamUsage.cs @@ -0,0 +1,18 @@ +namespace Stride.Shaders.Core; + + +public record struct StreamData(EntryPoint EntryPoint, StreamIO IO); + +public class StreamUsage +{ + Dictionary> usages { get; } = []; + + public List this[SymbolID id] => usages[id]; + + public bool ContainsKey(SymbolID symbolID) => usages.ContainsKey(symbolID); + public void Add(SymbolID symbolID, StreamData streamData) + { + if(!usages.TryAdd(symbolID, [streamData])) + usages[symbolID].Add(streamData); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs new file mode 100644 index 0000000000..87691b123c --- /dev/null +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -0,0 +1,53 @@ +namespace Stride.Shaders.Core; + + + + +public enum SymbolKind +{ + MixinParent, + MixinChild, + Struct, + Method, + Variable, + Constant, + ConstantGeneric, + Composition, + CBuffer, + TBuffer, + RGroup +} + +public enum Storage : ushort +{ + None, + Uniform, + UniformConstant, + Stream, + Function, + Generic, +} + +public enum StreamIO : byte +{ + Input, + Output +} + +public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0); +public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); +public record struct Symbol(SymbolID Id, SymbolType Type, object? Data = null); + + + +public record struct MixinParentSymbol(); +public record struct MixinChildSymbol(); +public record struct StructSymbol(); +public record struct MethodSymbol(); +public record struct VariableSymbol(); +public record struct ConstantSymbol(); +public record struct ConstantGenericSymbol(); +public record struct CompositionSymbol(); +public record struct CBufferSymbol(); +public record struct TBufferSymbol(); +public record struct RGroupSymbol(); \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs similarity index 58% rename from src/Stride.Shaders.Core/SymbolFrame.cs rename to src/Stride.Shaders/Core/SymbolFrame.cs index 3066c463fa..242604afe8 100644 --- a/src/Stride.Shaders.Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -1,17 +1,20 @@ namespace Stride.Shaders.Core; - -public readonly struct SymbolFrame +public class SymbolFrame() { - readonly Dictionary symbols; + readonly Dictionary symbols = []; - public SymbolFrame() + public Symbol this[string name, SymbolKind kind] + { + get => symbols[new(name, kind)]; + set => symbols[new(name, kind)] = value; + } + public Symbol this[SymbolID symbolID] { - symbols = []; + get => symbols[symbolID]; + set => symbols[symbolID] = value; } - public Symbol this[string name, SymbolKind kind] => symbols[new(name, kind)]; - public void Add(SymbolID name, Symbol symbol) => symbols.Add(name, symbol); public void Add(string name, SymbolKind kind, SymbolType type) @@ -24,6 +27,13 @@ public void Remove(string name, SymbolKind kind) public bool ContainsValue(Symbol symbol) => symbols.ContainsValue(symbol); public bool TryGetValue(string name, SymbolKind kind, out Symbol symbol) => symbols.TryGetValue(new(name, kind), out symbol); + public bool TryGetValue(string name, SymbolKind kind, Storage storage, out Symbol symbol) + => symbols.TryGetValue(new(name, kind, storage), out symbol); public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); +} + +public sealed class RootSymbolFrame : SymbolFrame +{ + public StreamUsage StreamUsages { get; } = new(); } \ No newline at end of file diff --git a/src/Stride.Shaders.Core/SymbolProvider.cs b/src/Stride.Shaders/Core/SymbolProvider.cs similarity index 74% rename from src/Stride.Shaders.Core/SymbolProvider.cs rename to src/Stride.Shaders/Core/SymbolProvider.cs index 9e07b770b5..0efb39ccac 100644 --- a/src/Stride.Shaders.Core/SymbolProvider.cs +++ b/src/Stride.Shaders/Core/SymbolProvider.cs @@ -3,5 +3,5 @@ public interface ISymbolProvider { public Dictionary DeclaredTypes { get; } - public SymbolFrame RootSymbols { get; } + public RootSymbolFrame RootSymbols { get; } } diff --git a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs new file mode 100644 index 0000000000..aafa23f666 --- /dev/null +++ b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs @@ -0,0 +1,72 @@ +using System.Collections.Frozen; + +namespace Stride.Shaders.Core; + + +public partial record ScalarType +{ + public static string[] names = [ + "bool", + "byte", + "sbyte", + "short", + "ushort", + "half", + "int", + "uint", + "float", + "long", + "ulong", + "double" + ]; + public static ScalarType From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + + // static Scalar() + // { + // var arr = new KeyValuePair[names.Length + 1]; + // arr[0] = new("void", new("void")); + // for(int i = 1; i < names.Length; i++) + // arr[i] = new(names[i], new(names[i])); + // Types = FrozenDictionary.ToFrozenDictionary(arr); + // } + internal static FrozenDictionary Init() + { + var arr = new KeyValuePair[names.Length + 1]; + arr[0] = new("void", new("void")); + for(int i = 1; i < names.Length + 1; i++) + arr[i] = new(names[i - 1], new(names[i - 1])); + return arr.ToFrozenDictionary(); + } +} + +public partial record VectorType +{ + public static VectorType From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + + internal static FrozenDictionary Init() + { + var arr = new KeyValuePair[ScalarType.names.Length * 4]; + for(int i = 0; i < ScalarType.names.Length; i++) + for(int x = 1; x < 5; x++) + arr[i * 4 + (x - 1)] = new($"{ScalarType.names[i]}{x}", new(ScalarType.From(ScalarType.names[i]),x)); + return arr.ToFrozenDictionary(); + } +} + + +public partial record MatrixType +{ + public static MatrixType From(string s) => Types[s]; + public static FrozenDictionary Types { get; } = Init(); + internal static FrozenDictionary Init() + { + var arr = new List>(ScalarType.names.Length * 4 * 4); + for(int i = 0; i < ScalarType.names.Length; i++) + for(int x = 1; x < 5; x++) + for(int y = 1; y < 5; y++) + arr.Add(new($"{ScalarType.names[i]}{x}x{y}", new(ScalarType.From(ScalarType.names[i]),x,y))); + return arr.ToFrozenDictionary(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs new file mode 100644 index 0000000000..4ce3c28d49 --- /dev/null +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -0,0 +1,157 @@ +using System.Text; + +namespace Stride.Shaders.Core; + + + +public abstract record SymbolType() +{ + public static bool TryGetNumeric(string name, out SymbolType? result) + { + if(ScalarType.Types.TryGetValue(name, out var s)) + { + result = s; + return true; + } + else if(VectorType.Types.TryGetValue(name, out var v)) + { + result = v; + return true; + } + else if(MatrixType.Types.TryGetValue(name, out var m)) + { + result = m; + return true; + } + else if (name == "void") + { + result = ScalarType.From("void"); + return true; + } + else + { + result = null; + return true; + } + } +} + +public sealed record UndefinedType(string TypeName) : SymbolType() +{ + public override string ToString() + { + return TypeName; + } +} + +public sealed record PointerType(SymbolType BaseType) : SymbolType() +{ + public override string ToString() => $"*{BaseType}"; +} + +public sealed partial record ScalarType(string TypeName) : SymbolType() +{ + public override string ToString() => TypeName; +} +public sealed partial record VectorType(ScalarType BaseType, int Size) : SymbolType() +{ + public override string ToString() => $"{BaseType}{Size}"; +} +public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Columns) : SymbolType() +{ + public override string ToString() => $"{BaseType}{Rows}x{Columns}"; +} +public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() +{ + public override string ToString() => $"{BaseType}[{Size}]"; +} +public sealed record StructType(string Name, SortedList Fields) : SymbolType() +{ + public override string ToString() => $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Value} {x.Key}"))}}}"; +} +public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() +{ + public override string ToString() => $"Buffer<{BaseType}, {Size}>"; +} + + +public abstract record TextureType(SymbolType BaseType) : SymbolType() +{ + public override string ToString() => $"Texture<{BaseType}>"; +} +public sealed record Texture1DType(SymbolType BaseType, int Size) : TextureType(BaseType) +{ + public override string ToString() => $"Texture<{BaseType}, {Size}>"; +} +public sealed record Texture2DType(SymbolType BaseType, int Width, int Height) : TextureType(BaseType) +{ + public override string ToString() => $"Texture<{BaseType}, {Width}, {Height}>"; +} +public sealed record Texture3DType(SymbolType BaseType, int Width, int Height, int Depth) : TextureType(BaseType) +{ + public override string ToString() => $"Texture<{BaseType}, {Width}, {Height}, {Depth}>"; +} + + +public sealed record FunctionType(SymbolType ReturnType, List ParameterTypes) : SymbolType() +{ + public bool Equals(FunctionType? other) + { + if(other is null) + return false; + if (ReturnType == null || other.ReturnType == null) + return false; + if (ParameterTypes == null || other.ParameterTypes == null) + return false; + return ReturnType == other.ReturnType && ParameterTypes.SequenceEqual(other.ParameterTypes); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + ReturnType.GetHashCode(); + foreach (var item in ParameterTypes) + { + hash = hash * 31 + item.GetHashCode(); + } + return hash; + } + + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append($"fn("); + for(int i = 0; i < ParameterTypes.Count; i++) + { + builder.Append(ParameterTypes[i]); + if(i < ParameterTypes.Count - 1) + builder.Append('*'); + } + return builder.Append($")->{ReturnType}").ToString(); + } +} + +public sealed record ConstantBufferSymbol(string Name, List Symbols) : SymbolType; +public sealed record ParamsSymbol(string Name, List Symbols) : SymbolType; +public sealed record EffectSymbol(string Name, List Symbols) : SymbolType; +public sealed record ShaderSymbol(string Name, List Components) : SymbolType +{ + public Symbol Get(string name, SymbolKind kind) + { + foreach (var e in Components) + if (e.Id.Kind == kind && e.Id.Name == name) + return e; + throw new ArgumentException($"{name} not found in Mixin {Name}"); + } + public bool TryGet(string name, SymbolKind kind, out Symbol? value) + { + foreach (var e in Components) + if (e.Id.Kind == kind && e.Id.Name == name) + { + value = e; + return true; + } + value = null!; + return false; + } +} diff --git a/src/Stride.Shaders.Parsing/ASTNode.cs b/src/Stride.Shaders/Parsing/ASTNode.cs similarity index 80% rename from src/Stride.Shaders.Parsing/ASTNode.cs rename to src/Stride.Shaders/Parsing/ASTNode.cs index 3c5ed0ec71..f23600e3e1 100644 --- a/src/Stride.Shaders.Parsing/ASTNode.cs +++ b/src/Stride.Shaders/Parsing/ASTNode.cs @@ -5,25 +5,38 @@ namespace Stride.Shaders.Parsing; +/// +/// Base class for shader syntax tree elements +/// public abstract class Node(TextLocation info) { public TextLocation Info { get; set; } = info; public virtual void ProcessSymbol(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); } + +/// +/// AST Node with a type +/// public class ValueNode(TextLocation info) : Node(info) { public virtual SymbolType? Type { get; set; } = null; } + +/// +/// Empty node for empty result +/// public class NoNode() : Node(new()); -public class ListNode(TextLocation info) : Node(info) -{ - public List Nodes { get; set; } = []; -} +/// +/// A declaration in SDSL/SDFX +/// public abstract class ShaderDeclaration(TextLocation info) : Node(info); +/// +/// Shader file node containing usings, namespaces, shaders, effects or params +/// public class ShaderFile(TextLocation info) : Node(info) { public List RootDeclarations { get; set; } = []; @@ -43,11 +56,17 @@ public override string ToString() } } +/// +/// Using instructions +/// public class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) { public List NamespacePath { get; set; } = []; } +/// +/// Namespace declaration +/// public class ShaderNamespace(TextLocation info) : Node(info) { public List NamespacePath { get; set; } = []; diff --git a/src/Stride.Shaders/Parsing/Analysis/CFG.cs b/src/Stride.Shaders/Parsing/Analysis/CFG.cs new file mode 100644 index 0000000000..b09834c0a0 --- /dev/null +++ b/src/Stride.Shaders/Parsing/Analysis/CFG.cs @@ -0,0 +1,13 @@ +namespace Stride.Shaders.Parsing.Analysis; + + + +public class BasicBlock +{ + List Instructions { get; } = []; +} + +public class CFG +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs b/src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs new file mode 100644 index 0000000000..36ea74af96 --- /dev/null +++ b/src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs @@ -0,0 +1,8 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Parsing.Analysis; + +public interface IStreamChecker +{ + public void CheckIO(SymbolTable table, EntryPoint? entryPoint = null); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs b/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs new file mode 100644 index 0000000000..f97aa911aa --- /dev/null +++ b/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs @@ -0,0 +1,72 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL; + +namespace Stride.Shaders.Parsing.Analysis; + +public static class OperatorTable +{ + public static bool CheckBinaryOperation(SymbolType left, SymbolType right, Operator op) + { + return (left, right, op) switch + { + // Scalar operations + ( + ScalarType { TypeName: "int" or "long" }, ScalarType { TypeName: "int" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + or Operator.LeftShift or Operator.RightShift + or Operator.OR or Operator.XOR or Operator.AND + ) => true, + ( + ScalarType { TypeName: "float" or "double" }, ScalarType { TypeName: "double" or "float" or "int" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + ( + ScalarType { TypeName: "float" } or ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + + // Vector operations + ( + VectorType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, + VectorType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + // Matrix operations + ( + MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, + MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + ( + MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or VectorType { BaseType: ScalarType { TypeName: "int" or "float" or "long" or "double" } }, + MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or VectorType { BaseType: ScalarType { TypeName: "int" or "float" or "long" or "double" } }, + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod + ) => true, + + _ => false, + }; + } + public static bool BinaryOperationResultingType(SymbolType left, SymbolType right, Operator op, out SymbolType? result) + { + // TODO : correct that part + result = ((int)op, left, right) switch + { + // Boolean operations + (>= 22 and < 26, ScalarType{ TypeName : "bool"}, ScalarType {TypeName: "bool"}) => left, + // Linear algebra + (>=8 and < 13, ScalarType {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, ScalarType r) when l.TypeName == r.TypeName => right, + (>=8 and < 13, ScalarType { TypeName: "int" or "uint" or "long" or "ulong" }, ScalarType { TypeName: "float" or "double"}) => right, + (>=8 and < 13, ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" or "float" }) => left, + (>=8 and < 13, VectorType l, VectorType r) when l.BaseType == r.BaseType => right, + (>=8 and < 13, VectorType, ScalarType) => left, + (>=8 and < 13, MatrixType l, MatrixType r) when l.BaseType == r.BaseType => right, + (>=8 and < 13, MatrixType l, ScalarType r) => l, + (>=8 and < 13, MatrixType l, VectorType r) => l, + (>=8 and < 13, MatrixType { BaseType: ScalarType { TypeName: "int" } } l, MatrixType { BaseType: ScalarType { TypeName: "int" or "float" } } r) => l, + // Comparison + (>=18 and < 22, SymbolType l, SymbolType r) when l == r => ScalarType.From("bool"), + _ => null, + }; + return result != null; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/ReadMe.md b/src/Stride.Shaders/Parsing/Analysis/ReadMe.md new file mode 100644 index 0000000000..6ab01eb0aa --- /dev/null +++ b/src/Stride.Shaders/Parsing/Analysis/ReadMe.md @@ -0,0 +1,20 @@ +# Semantic analysis + + +## On AST + +- [ ] Type checking +- [ ] Scope resolution +- [ ] Name resolution +- [ ] Type inference + + +## On CFG + +- [ ] Control flow analysis +- [ ] Data flow analysis + + +## Optimisations + +- [ ] Constant folding \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/SDIR.cs b/src/Stride.Shaders/Parsing/Analysis/SDIR.cs similarity index 60% rename from src/Stride.Shaders.Parsing/Analysis/SDIR.cs rename to src/Stride.Shaders/Parsing/Analysis/SDIR.cs index 59b2f6fc60..2b32491a67 100644 --- a/src/Stride.Shaders.Parsing/Analysis/SDIR.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SDIR.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.Analysis; @@ -17,8 +18,15 @@ public enum IROp } +public record struct QuadrupleArg( + string Name, + Statement Statement +); -public record struct SDID( - string Name +public record struct Quadruple( + IROp Op, + QuadrupleArg Arg1, + QuadrupleArg Arg2, + QuadrupleArg Result ); \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs new file mode 100644 index 0000000000..b72989d335 --- /dev/null +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -0,0 +1,51 @@ +using System.Runtime.InteropServices; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.Analysis; + + +public record struct SemanticErrors(TextLocation Location, string Message); + +public partial class SymbolTable : ISymbolProvider +{ + public Dictionary DeclaredTypes { get; } = []; + public SymbolFrame CurrentFrame => CurrentFunctionSymbols[^1]; + public RootSymbolFrame RootSymbols => new(); + public SortedList> FunctionSymbols { get; } = []; + + public List Errors { get; } = []; + + public List? CurrentFunctionSymbols { get; internal set; } + + public void Push() => CurrentFunctionSymbols?.Add(new()); + + public SymbolFrame? Pop() + { + var scope = CurrentFunctionSymbols?[^1]; + CurrentFunctionSymbols?.Remove(scope!); + return scope; + } + + public void Import(ISymbolProvider symbols) + { + foreach (var (name, type) in symbols.DeclaredTypes) + DeclaredTypes.TryAdd(name, type); + foreach (var (name, symbol) in symbols.RootSymbols) + RootSymbols.Add(name, symbol); + } + + public bool TryFind(string name, SymbolKind kind, out Symbol symbol) + { + + if(CurrentFunctionSymbols is null) + return RootSymbols.TryGetValue(name, kind, out symbol); + + for (int i = CurrentFunctionSymbols.Count - 1; i >= 0; i--) + if (CurrentFunctionSymbols[i].TryGetValue(name, kind, out symbol)) + return true; + return RootSymbols.TryGetValue(name, kind, out symbol); + } + + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs b/src/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs similarity index 90% rename from src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs rename to src/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs index 5ad022d50d..e907ff01ac 100644 --- a/src/Stride.Shaders.Parsing/Analysis/TypeNameExtensions.cs +++ b/src/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs @@ -11,6 +11,6 @@ public static SymbolType ToSymbol(this TypeName typeName) { if(!typeName.IsArray && typeName.Generics.Count == 0 && SymbolType.TryGetNumeric(typeName.Name, out var result)) return result!; - else return new Undefined(typeName); + else return new UndefinedType(typeName); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/Grammar.cs b/src/Stride.Shaders/Parsing/Grammar.cs similarity index 96% rename from src/Stride.Shaders.Parsing/Grammar.cs rename to src/Stride.Shaders/Parsing/Grammar.cs index 27d9d878a8..f42ab1279c 100644 --- a/src/Stride.Shaders.Parsing/Grammar.cs +++ b/src/Stride.Shaders/Parsing/Grammar.cs @@ -3,6 +3,9 @@ namespace Stride.Shaders.Parsing; +/// +/// Wrapper for the SDSL grammar parsers +/// public static class Grammar { public static ParseResult Match(string code, TParser? parser = null) diff --git a/src/Stride.Shaders/Parsing/IParser.cs b/src/Stride.Shaders/Parsing/IParser.cs new file mode 100644 index 0000000000..6313f4a4e3 --- /dev/null +++ b/src/Stride.Shaders/Parsing/IParser.cs @@ -0,0 +1,28 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing; + +/// +/// Parser interface +/// +public interface IParser; + +/// +/// Parser with a Match method to parse a specific node. +/// +/// Output type of the parser +public interface IParser : IParser + where TResult : Node +{ + /// + /// Parsing method + /// + /// Scanner containing information on the position in the shader text + /// Result of the parser + /// Element parsed + /// The error to use in case of a parse error + /// Type of the scanner + /// + public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) + where TScanner : struct, IScanner; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/ParseResult.cs b/src/Stride.Shaders/Parsing/ParseResult.cs similarity index 83% rename from src/Stride.Shaders.Parsing/ParseResult.cs rename to src/Stride.Shaders/Parsing/ParseResult.cs index 99b0dcc8a2..4f5092b40a 100644 --- a/src/Stride.Shaders.Parsing/ParseResult.cs +++ b/src/Stride.Shaders/Parsing/ParseResult.cs @@ -2,13 +2,15 @@ namespace Stride.Shaders.Parsing; - +/// +/// Represents a parsing error +/// public record struct ParseError(string Message, ErrorLocation Location, ReadOnlyMemory Code) { readonly ReadOnlySpan GetNextToken() { - ReadOnlySpan operators = ['+', '-', '*', '/', '%', '=', '!', '<', '>', '&', '|', '^', '~', '?', ':']; + var operators = "'+-*/%=!<>&|^~?:".AsSpan(); var pos = Location.Position; if (pos >= Code.Span.Length) return []; @@ -38,11 +40,18 @@ public override readonly string ToString() } } - +/// +/// Represents the result of the parser +/// +/// public class ParseResult where T : Node { public T? AST { get; set; } public List Errors { get; internal set; } = []; } + +/// +/// Default parser result +/// public class ParseResult : ParseResult; \ No newline at end of file diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrame.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrame.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeProcessor.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/CodeProcessor.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/CommentPhase.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CMacros/LocationTranslator.cs b/src/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CMacros/LocationTranslator.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs b/src/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/CommentProcessedCode.cs rename to src/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs b/src/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/MacroPreProcessor.cs rename to src/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/MemoryOwnerExtensions.cs b/src/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/MemoryOwnerExtensions.cs rename to src/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/TextLink.cs b/src/Stride.Shaders/Parsing/PreProcessing/TextLink.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/TextLink.cs rename to src/Stride.Shaders/Parsing/PreProcessing/TextLink.cs diff --git a/src/Stride.Shaders.Parsing/PreProcessing/TextLinkExtensions.cs b/src/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs similarity index 100% rename from src/Stride.Shaders.Parsing/PreProcessing/TextLinkExtensions.cs rename to src/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/AST/Effect.Flow.cs rename to src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/AST/Effect.Parameters.cs rename to src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs rename to src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 7c73f475bc..245892842b 100644 --- a/src/Stride.Shaders.Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/EffectFileParsers.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/EffectParser.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs index e089dbd213..a84336a428 100644 --- a/src/Stride.Shaders.Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; @@ -147,11 +148,10 @@ public static bool ShaderSourceDeclaration(ref TScanner scanner, Parse var position = scanner.Position; if ( Tokens.AnyOf(["ShaderSourceCollection ", "ShaderSource ", "var "], ref scanner, out _) - && SDSL.Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var arraySize, out var value) + && SDSL.Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name,out var value) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - typename.ArraySize = arraySize; parsed = new(name, scanner[position..scanner.Position], value); return true; } diff --git a/src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDFX/Parsers/ParamsParsers.cs rename to src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs b/src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs new file mode 100644 index 0000000000..ea14973e3a --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs @@ -0,0 +1,76 @@ +// namespace Stride.Shaders.Parsing.SDSL; + +// public enum AssignOperator +// { +// NOp, +// Simple, +// Plus, +// Minus, +// Mul, +// Div, +// Mod, +// RightShift, +// LeftShift, +// AND, +// OR, +// XOR +// } + + +// public static class StringAssignOperatorExtensions +// { +// public static AssignOperator ToAssignOperator(this ReadOnlySpan s) +// { +// return s switch +// { +// "+=" => AssignOperator.Plus, +// "-=" => AssignOperator.Minus, +// "*=" => AssignOperator.Mul, +// "/=" => AssignOperator.Div, +// "%=" => AssignOperator.Mod, +// ">>=" => AssignOperator.RightShift, +// "<<=" => AssignOperator.LeftShift, +// "&=" => AssignOperator.AND, +// "|=" => AssignOperator.OR, +// "^=" => AssignOperator.XOR, +// _ => AssignOperator.NOp +// }; +// } +// public static AssignOperator ToAssignOperator(this string s) +// { +// return s switch +// { +// "=" => AssignOperator.Simple, +// "+=" => AssignOperator.Plus, +// "-=" => AssignOperator.Minus, +// "*=" => AssignOperator.Mul, +// "/=" => AssignOperator.Div, +// "%=" => AssignOperator.Mod, +// ">>=" => AssignOperator.RightShift, +// "<<=" => AssignOperator.LeftShift, +// "&=" => AssignOperator.AND, +// "|=" => AssignOperator.OR, +// "^=" => AssignOperator.XOR, +// _ => AssignOperator.NOp +// }; +// } +// public static string ToAssignSymbol(this AssignOperator s) +// { +// return s switch +// { +// AssignOperator.Simple => "=", +// AssignOperator.Plus => "+=", +// AssignOperator.Minus => "-=", +// AssignOperator.Mul => "*=", +// AssignOperator.Div => "/=", +// AssignOperator.Mod => "%=", +// AssignOperator.RightShift => ">>=", +// AssignOperator.LeftShift => "<<=", +// AssignOperator.AND => "&=", +// AssignOperator.OR => "|=", +// AssignOperator.XOR => "^=", +// _ => "NOp" +// }; +// } +// } + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Directives.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/AST/Directives.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs new file mode 100644 index 0000000000..9dcbcd1215 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -0,0 +1,228 @@ +using System.Text; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.AST; + + + +/// +/// Code expression, represents operations and literals +/// +public abstract class Expression(TextLocation info) : ValueNode(info) +{ + public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null, null); + public virtual void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); + public abstract SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); +} + +public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) +{ + public Identifier Name = name; + public ShaderExpressionList Parameters = parameters; + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, module) = compiler; + var list = parameters.Values; + Span compiledParams = stackalloc IdRef[list.Count]; + var tmp = 0; + foreach(var p in list) + compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; + return builder.CallFunction(context, Name, compiledParams); + } + public override string ToString() + { + return $"{Name}({string.Join(", ", Parameters)})"; + } +} + +/// +/// Represents an accessed mixin. +/// +public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) +{ + public Mixin Mixin { get; set; } = mixin; + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() + { + return $"{Mixin}"; + } +} + + +public abstract class UnaryExpression(Expression expression, Operator op, TextLocation info) : Expression(info) +{ + public Expression Expression { get; set; } = expression; + public Operator Operator { get; set; } = op; +} + +public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} + +public class CastExpression(string typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) +{ + public string TypeName { get; set; } = typeName; + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} + +public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) +{ + public Operator Operator { get; set; } = op; + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() + { + return $"{Operator.ToSymbol()}"; + } +} + +public class AccessorChainExpression(Expression source, TextLocation info) : Expression(info) +{ + public Expression Source { get; set; } = source; + public List Accessors { get; set; } = []; + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) + { + + if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar && entrypoint is not null) + { + streamVar.ProcessSymbol(table, entrypoint, io); + Type = streamVar.Type; + // If has more, dive into the type definition + // First case none + if (Accessors.Count > 1) + { + foreach (var accessor in Accessors[1..]) + { + if (Type is not null && Type.TryAccess(accessor, out var type)) + { + Type = type; + accessor.Type = type; + } + else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); + + if(accessor is not Identifier) + accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); + } + } + table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); + } + else + { + Source.ProcessSymbol(table, entrypoint, io ?? StreamIO.Output); + Type = Source.Type; + foreach (var accessor in Accessors[1..]) + { + if (Type is not null && Type.TryAccess(accessor, out var type)) + { + Type = type; + accessor.Type = type; + } + else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); + if(accessor is not Identifier) + accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); + } + } + } + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + var builder = new StringBuilder().Append(Source); + foreach (var a in Accessors) + if (a is NumberLiteral) + builder.Append('[').Append(a).Append(']'); + else if (a is PostfixIncrement) + builder.Append(a); + else + builder.Append('.').Append(a); + return builder.ToString(); + } +} + +public class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) +{ + public Operator Op { get; set; } = op; + public Expression Left { get; set; } = left; + public Expression Right { get; set; } = right; + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + { + Left.ProcessSymbol(table, entrypoint, io); + Right.ProcessSymbol(table, entrypoint, io); + if ( + OperatorTable.BinaryOperationResultingType( + Left.Type ?? throw new NotImplementedException("Missing type"), + Right.Type ?? throw new NotImplementedException("Missing type"), + Op, + out var t + ) + ) + Type = t; + else + table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); + } + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var left = Left.Compile(table, shader, compiler); + var right = Right.Compile(table, shader, compiler); + var (builder, context, _) = compiler; + return builder.BinaryOperation(context, context.GetOrRegister(Type), left, Op, right); + } + + public override string ToString() + { + return $"( {Left} {Op.ToSymbol()} {Right} )"; + } +} + +public class TernaryExpression(Expression cond, Expression left, Expression right, TextLocation info) : Expression(info) +{ + public Expression Condition { get; set; } = cond; + public Expression Left { get; set; } = left; + public Expression Right { get; set; } = right; + + public override void ProcessSymbol(SymbolTable table) + { + Condition.ProcessSymbol(table); + Left.ProcessSymbol(table); + Right.ProcessSymbol(table); + if (Condition.Type is not ScalarType { TypeName: "bool" }) + table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); + if (Left.Type != Right.Type) + table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); + } + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"({Condition} ? {Left} : {Right})"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs new file mode 100644 index 0000000000..3185b1f66f --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -0,0 +1,351 @@ +using System.Numerics; +using System.Text; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Parsing.SDSL.AST; + + + +public abstract class Literal(TextLocation info) : Expression(info); +public abstract class ValueLiteral(TextLocation info) : Literal(info); +public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); + +public class StringLiteral(string value, TextLocation info) : Literal(info) +{ + public string Value { get; set; } = value; + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"\"{Value}\""; + } +} + +public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) +{ + public abstract double DoubleValue { get; } + public abstract int IntValue { get; } + public abstract long LongValue { get; } + +} +public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info) : NumberLiteral(info) + where T : struct, INumber +{ + public Suffix Suffix { get; set; } = suffix; + public T Value { get; set; } = value; + public override double DoubleValue => Convert.ToDouble(Value); + public override long LongValue => Convert.ToInt64(Value); + public override int IntValue => Convert.ToInt32(Value); + + public override string ToString() + { + return $"{Value}{Suffix}"; + } + +} + +public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) +{ + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + { + Type = Suffix switch + { + { Signed: true, Size: 8 } => ScalarType.From("sbyte"), + { Signed: true, Size: 16 } => ScalarType.From("short"), + { Signed: true, Size: 32 } => ScalarType.From("int"), + { Signed: true, Size: 64 } => ScalarType.From("long"), + { Signed: false, Size: 8 } => ScalarType.From("byte"), + { Signed: false, Size: 16 } => ScalarType.From("ushort"), + { Signed: false, Size: 32 } => ScalarType.From("uint"), + { Signed: false, Size: 64 } => ScalarType.From("ulong"), + _ => throw new NotImplementedException("Unsupported integer suffix") + }; + } + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var i = (Type, Suffix) switch + { + (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), LongValue), + (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), IntValue), + _ => throw new NotImplementedException("") + }; + return new SpirvValue(i, i.ResultType!.Value, null); + } +} + +public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) +{ + public int? Exponent { get; set; } = exponent; + public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + { + Type = Suffix.Size switch + { + 16 => ScalarType.From("half"), + 32 => ScalarType.From("float"), + 64 => ScalarType.From("double"), + _ => throw new NotImplementedException("Unsupported float") + }; + } + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var i = (Type, Suffix) switch + { + (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), DoubleValue), + (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), (float)DoubleValue), + _ => throw new NotImplementedException("") + }; + return new SpirvValue(i, i.ResultType!.Value, null); + } +} + +public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(32, false, false), (long)value, info) +{ + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + => Type = ScalarType.From("long"); +} + + +public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) +{ + public bool Value { get; set; } = value; + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + => Type = ScalarType.From("bool"); + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var i = Value switch + { + true => compiler.Context.Buffer.AddOpConstantTrue(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)), + false => compiler.Context.Buffer.AddOpConstantFalse(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)) + }; + return new SpirvValue(i, i.ResultType!.Value, null); + } +} + +public abstract class CompositeLiteral(TextLocation info) : ValueLiteral(info) +{ + public List Values { get; set; } = []; + + public bool IsConstant() + { + foreach (var v in Values) + if (v is not NumberLiteral or BoolLiteral) + return false; + return true; + } + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, module) = compiler; + Span values = stackalloc IdRef[Values.Count]; + int tmp = 0; + foreach (var v in Values) + values[tmp++] = v.Compile(table, shader, compiler).Id; + return builder.CompositeConstruct(context, this, values); + } +} +public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) +{ + public TypeName TypeName { get; set; } = typeName; + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + { + TypeName.ProcessSymbol(table); + Type = TypeName.Type; + var tmp = (Core.VectorType)Type! ?? throw new NotImplementedException(); + foreach (var v in Values) + { + v.ProcessSymbol(table); + if ( + v.Type is ScalarType st && tmp.BaseType != st + || (v.Type is Core.VectorType vt && vt.BaseType != tmp.BaseType) + || (v.Type is Core.VectorType vt2 && vt2.Size > tmp.Size) + ) + table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); + } + } + public override string ToString() + { + return $"{TypeName}({string.Join(", ", Values.Select(x => x.ToString()))})"; + } +} + + +public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : CompositeLiteral(info) +{ + public TypeName TypeName { get; set; } = typeName; + public int Rows { get; set; } = rows; + public int Cols { get; set; } = cols; + + public override string ToString() + { + return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + } +} + +public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) +{ + public override string ToString() + => $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; +} + +public class Identifier(string name, TextLocation info) : Literal(info) +{ + public string Name { get; set; } = name; + + public static implicit operator string(Identifier identifier) => identifier.Name; + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + { + Span sOrder = [Storage.Function, Storage.Stream, Storage.Uniform, Storage.UniformConstant, Storage.Generic]; + foreach (var storage in sOrder) + { + if (table.CurrentFunctionSymbols is null) + { + if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) + Type = symbol.Type; + } + else + { + for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; i -= 1) + { + if (table.CurrentFunctionSymbols![i].TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) + { + if (symbol.Type is not UndefinedType and not null) + Type = symbol.Type; + else + Type = symbol.Type ?? new UndefinedType(Name); + return; + } + } + if (table.CurrentFunctionSymbols is null) + { + if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var rootSymbol)) + Type = rootSymbol.Type; + } + } + + } + throw new NotImplementedException($"Cannot find symbol {Name}."); + } + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, _, _) = compiler; + if(builder.CurrentFunction is SpirvFunction f) + { + if(f.Variables.TryGetValue(Name, out var resultVar)) + return resultVar; + else if(f.Parameters.TryGetValue(Name, out var paramVar)) + return paramVar; + } + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"{Name}"; + } + + public bool IsSwizzle() + { + if (Name.Length > 4) + return false; + + bool colorMode = false; + bool vectorMode = false; + + Span colorFields = ['r', 'g', 'b', 'a']; + Span vectorFields = ['x', 'y', 'z', 'w']; + + if (colorFields.Contains(Name[0])) + colorMode = true; + else if (vectorFields.Contains(Name[0])) + vectorMode = true; + + if (!colorMode && !vectorMode) + return false; + var fields = colorMode ? colorFields : vectorFields; + foreach (var c in Name) + if (!fields.Contains(c)) + return false; + return true; + } + + public bool IsMatrixField() + { + return + Name.Length == 3 + && Name[0] == '_' + && char.IsDigit(Name[1]) && Name[1] - '0' > 0 && Name[1] - '0' < 5 + && char.IsDigit(Name[2]) && Name[2] - '0' > 0 && Name[2] - '0' < 5; + } +} + +public class TypeName(string name, TextLocation info, bool isArray) : Literal(info) +{ + public string Name { get; set; } = name; + public bool IsArray { get; set; } = isArray; + public List? ArraySize { get; set; } + public List Generics { get; set; } = []; + + public override void ProcessSymbol(SymbolTable table, EntryPoint? entryPoint = null, StreamIO? io = null) + { + if (!IsArray && Generics.Count == 0) + { + if (table.DeclaredTypes.TryGetValue(Name, out var type)) + Type = type; + else if (SymbolType.TryGetNumeric(Name, out var numeric)) + { + Type = numeric; + table.DeclaredTypes.Add(Type!.ToString(), Type); + } + else throw new NotImplementedException(); + } + // else if (IsArray && Generics.Count == 0) + // { + // if (table.DeclaredTypes.TryGetValue(Name, out var type) && ) + // { + // Type = new Core.Array(type, ) + // } + // else table.Errors.Add(new(Info, "type not found")); + // } + else throw new NotImplementedException(); + } + + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append(Name); + if (Generics.Count > 0) + { + builder.Append('<'); + foreach (var g in Generics) + builder.Append(g.ToString()).Append(", "); + builder.Append('>'); + } + if (ArraySize != null) + foreach (var s in ArraySize) + builder.Append('[').Append(s.ToString()).Append(']'); + + return builder.ToString(); + + } + + public static implicit operator string(TypeName tn) => tn.Name; +} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs new file mode 100644 index 0000000000..e1623d0931 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs @@ -0,0 +1,153 @@ +// namespace Stride.Shaders.Parsing.SDSL; + +// public enum Operator +// { +// Nop, +// Cast, +// Positive, +// Negative, +// Not, +// /// +// /// Bitwise not +// /// +// BitwiseNot, +// /// +// /// Increment +// /// +// Inc, +// /// +// /// Decrement +// /// +// Dec, +// Plus, +// Minus, +// Mul, +// Div, +// Mod, +// RightShift, +// LeftShift, +// AND, +// OR, +// XOR, +// Greater, +// Lower, +// GreaterOrEqual, +// LowerOrEqual, +// NotEquals, +// Equals, +// LogicalAND, +// LogicalOR, +// Accessor, +// Indexer +// } + +// public static class StringOperatorExtensions +// { +// public static Operator ToOperator(this ReadOnlySpan s) +// { +// return s switch +// { +// "!" => Operator.Not, +// "~" => Operator.BitwiseNot, +// "++" => Operator.Inc, +// "--" => Operator.Dec, +// "+" => Operator.Plus, +// "-" => Operator.Minus, +// "*" => Operator.Mul, +// "/" => Operator.Div, +// "%" => Operator.Mod, +// ">>" => Operator.RightShift, +// "<<" => Operator.LeftShift, +// "&" => Operator.AND, +// "|" => Operator.OR, +// "^" => Operator.XOR, +// ">" => Operator.Greater, +// "<" => Operator.Lower, +// ">=" => Operator.GreaterOrEqual, +// "<=" => Operator.LowerOrEqual, +// "==" => Operator.Equals, +// "!=" => Operator.NotEquals, +// "&&" => Operator.LogicalAND, +// "||" => Operator.LogicalOR, +// _ => Operator.Nop, +// }; +// } +// public static Operator ToOperator(this string s) +// { +// return s switch +// { +// "!" => Operator.Not, +// "~" => Operator.BitwiseNot, +// "++" => Operator.Inc, +// "--" => Operator.Dec, +// "+" => Operator.Plus, +// "-" => Operator.Minus, +// "*" => Operator.Mul, +// "/" => Operator.Div, +// "%" => Operator.Mod, +// ">>" => Operator.RightShift, +// "<<" => Operator.LeftShift, +// "&" => Operator.AND, +// "|" => Operator.OR, +// "^" => Operator.XOR, +// ">" => Operator.Greater, +// "<" => Operator.Lower, +// ">=" => Operator.GreaterOrEqual, +// "<=" => Operator.LowerOrEqual, +// "==" => Operator.Equals, +// "!=" => Operator.NotEquals, +// "&&" => Operator.LogicalAND, +// "||" => Operator.LogicalOR, +// _ => Operator.Nop, +// }; +// } +// public static string ToSymbol(this Operator s) +// { +// return s switch +// { +// Operator.Not => "!", +// Operator.BitwiseNot => "~", +// Operator.Inc => "++", +// Operator.Dec => "--", +// Operator.Plus => "+", +// Operator.Minus => "-", +// Operator.Mul => "*", +// Operator.Div => "/", +// Operator.Mod => "%", +// Operator.RightShift => ">>", +// Operator.LeftShift => "<<", +// Operator.AND => "&", +// Operator.OR => "|", +// Operator.XOR => "^", +// Operator.Greater => ">", +// Operator.Lower => "<", +// Operator.GreaterOrEqual => ">=", +// Operator.LowerOrEqual => "<=", +// Operator.Equals => "==", +// Operator.NotEquals => "!=", +// Operator.LogicalAND => "&&", +// Operator.LogicalOR => "||", +// _ => "NOp" +// }; +// } + +// public static Operator ToOperator(this char c) +// { +// return c switch +// { +// '!' => Operator.Not, +// '~' => Operator.BitwiseNot, +// '+' => Operator.Plus, +// '-' => Operator.Minus, +// '*' => Operator.Mul, +// '/' => Operator.Div, +// '%' => Operator.Mod, +// '&' => Operator.AND, +// '|' => Operator.OR, +// '^' => Operator.XOR, +// '>' => Operator.Greater, +// '<' => Operator.Lower, +// _ => Operator.Nop, +// }; +// } +// } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs similarity index 58% rename from src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 24fb684123..4a67895c1e 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -19,28 +20,59 @@ public override void ProcessSymbol(SymbolTable table) { foreach (var member in Elements) { - if(member is ShaderMethod func) + if (member is ShaderMethod func) { - func.Type = func.ReturnTypeName.ToSymbol(); + func.ReturnTypeName.ProcessSymbol(table); + var ftype = new FunctionType(func.ReturnTypeName.Type, []); + foreach (var arg in func.Parameters) + { + arg.TypeName.ProcessSymbol(table); + var argSym = arg.TypeName.Type; + table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + arg.Type = argSym; + ftype.ParameterTypes.Add(arg.Type); + } + func.Type = ftype; + table.RootSymbols.Add(new(func.Name, SymbolKind.Method), new(new(func.Name, SymbolKind.Method), func.Type)); table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); } - else if(member is ShaderMember svar) + else if (member is ShaderMember svar) { - svar.Type = svar.TypeName.ToSymbol(); - table.RootSymbols.Add( - new( - svar.Name, - svar.TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable - ), - new(new(svar.Name, SymbolKind.Variable), svar.TypeName.ToSymbol()) - ); + svar.TypeName.ProcessSymbol(table); + svar.Type = svar.TypeName.Type; + var sid = + new SymbolID + ( + svar.Name, + svar.TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, + svar.StreamKind switch + { + StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, + _ => Storage.None + } + ); + table.RootSymbols.Add + ( + sid, + new(sid, svar.Type) + ); table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } } + foreach (var member in Elements) - if(member is not MethodOrMember) + { + if (member is not ShaderMember) member.ProcessSymbol(table); + } + } + + + public void Compile(CompilerUnit compiler, SymbolTable table) + { + foreach(var method in Elements.OfType()) + method.Compile(table, this, compiler); } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/AST/ShaderAttributes.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs similarity index 72% rename from src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b4df7b1862..da061f4d05 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -53,26 +54,24 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember(TypeName type, - Identifier name, +public sealed class ShaderMember( + TypeName typeName, + Identifier identifier, Expression? initialValue, - bool isArray, TextLocation location, bool isStaged = false, StreamKind streamKind = StreamKind.None, Identifier? semantic = null, - List? arraySizes = null, InterpolationModifier interpolation = InterpolationModifier.None, StorageClass storageClass = StorageClass.None, TypeModifier typeModifier = TypeModifier.None ) : MethodOrMember(location, isStaged) { - public TypeName TypeName { get; set; } = type; - public Identifier Name { get; set; } = name; + public Identifier Name { get; set; } = identifier; + public TypeName TypeName { get; set; } = typeName; public Identifier? Semantic { get; set; } = semantic; public StreamKind StreamKind { get; set; } = streamKind; - public bool IsArray { get; set; } = isArray; - public List? ArraySizes { get; set; } = arraySizes; + public bool IsArray => TypeName?.IsArray ?? false; public Expression? Value { get; set; } = initialValue; public TypeModifier TypeModifier { get; set; } = typeModifier; public StorageClass StorageClass { get; set; } = storageClass; @@ -80,10 +79,10 @@ public sealed class ShaderMember(TypeName type, public override string ToString() { - if(Attributes != null) + if (Attributes != null) return $"[{string.Join(" ", Attributes.Select(x => x.ToString()))}]\n{TypeName} {Name}"; else - return $"{TypeName} {Name}"; + return $"{StreamKind.ToString().ToLowerInvariant()} {StorageClass.ToString().ToLowerInvariant()} {TypeName} {Name}"; } } @@ -120,6 +119,17 @@ public class ShaderMethod( public SymbolType? ReturnType { get; set; } public TypeName ReturnTypeName { get; set; } = returnType; public Identifier Name { get; set; } = name; + public EntryPoint EntryPoint { get; } = + name.Name switch + { + "VSMain" => EntryPoint.VertexShader, + "PSMain" => EntryPoint.PixelShader, + "CSMain" => EntryPoint.ComputeShader, + "GSMain" => EntryPoint.GeometryShader, + "DSMain" => EntryPoint.DomainShader, + "HSMain" => EntryPoint.HullShader, + _ => 0 + }; public Identifier? Visibility { get; set; } = visibility; public Identifier? Storage { get; set; } = storage; public bool? IsAbstract { get; set; } = isAbstract; @@ -128,26 +138,49 @@ public class ShaderMethod( public bool? IsOverride { get; set; } = isOverride; public bool? IsClone { get; set; } = isClone; public List Parameters { get; set; } = []; - public BlockStatement? Body { get; set; } + public BlockStatement? Body { get; set; } public override void ProcessSymbol(SymbolTable table) { + table.FunctionSymbols[Name] = [new()]; + table.CurrentFunctionSymbols = table.FunctionSymbols[Name]; foreach (var arg in Parameters) { - var argSym = arg.TypeName.ToSymbol(); + arg.TypeName.ProcessSymbol(table); + var argSym = arg.TypeName.Type; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + table.CurrentFrame.Add(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); arg.Type = argSym; + } if (Body is not null) { table.Push(); foreach (var s in Body.Statements) - s.ProcessSymbol(table); + if (EntryPoint == 0) + s.ProcessSymbol(table); + else + s.ProcessSymbol(table, this, EntryPoint, null); table.Pop(); } } + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, _) = compiler; + if (Type is FunctionType ftype) + { + builder.CreateFunction(context, Name, ftype); + foreach (var p in Parameters) + builder.AddFunctionParameter(context, p.Name, p.Type); + if(Body is BlockStatement body) + foreach(var s in body) + s.Compile(table, shader, compiler); + } + else throw new NotImplementedException(); + } + public override string ToString() { return $"{ReturnTypeName} {Name}()\n{Body}\n"; @@ -168,6 +201,8 @@ public class ShaderExpressionList(TextLocation info) : ParameterListNode(info) { public List Values { get; set; } = []; + public List.Enumerator GetEnumerator() => Values.GetEnumerator(); + public override string ToString() { return string.Join(", ", Values); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs similarity index 87% rename from src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 91dee86104..57459ab2b5 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -99,16 +99,16 @@ public static TypeModifier ToTypeModifier(this string str) } } -public class ShaderVariable(TypeName type, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) +public class ShaderVariable(TypeName typeName, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) { - public TypeName TypeName { get; set; } = type; public Identifier Name { get; set; } = name; + public TypeName TypeName { get; set; } = typeName; public Expression? Value { get; set; } = value; public StorageClass StorageClass { get; set; } = StorageClass.None; public TypeModifier TypeModifier { get; set; } = TypeModifier.None; public override string ToString() { - return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " :"")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " :"")}{TypeName} {Name} = {Value}"; + return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " : "")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " : "")} {TypeName} {Name} = {Value}"; } } @@ -130,7 +130,7 @@ public abstract class ShaderBuffer(List name, TextLocation info) : S public override void ProcessSymbol(SymbolTable table) { - var sym = new Symbol(new(Name.ToString() ?? "", SymbolKind.CBuffer), new BufferSymbol(Name.ToString() ?? "", [])); + var sym = new Symbol(new(Name.ToString() ?? "", SymbolKind.CBuffer), new ConstantBufferSymbol(Name.ToString() ?? "", [])); table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); var kind = this switch @@ -143,9 +143,9 @@ public override void ProcessSymbol(SymbolTable table) table.RootSymbols.Add(new(Name.ToString() ?? "", kind), sym); foreach (var cbmem in Members) { - var msym = cbmem.TypeName.ToSymbol(); - table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); - cbmem.Type = msym; + cbmem.TypeName.ProcessSymbol(table); + cbmem.Type = cbmem.Type; + table.DeclaredTypes.TryAdd(cbmem.Type.ToString(), cbmem.Type); } } } @@ -159,7 +159,7 @@ public class ShaderStructMember(TypeName typename, Identifier identifier, TextLo public override string ToString() { - if(Type is not null) + if (Type is not null) return $"{Type} {Name}"; else return $"{TypeName} {Name}"; } @@ -172,14 +172,14 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public override void ProcessSymbol(SymbolTable table) { - var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new Struct(TypeName.ToString() ?? "", [])); + var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new StructType(TypeName.ToString() ?? "", [])); table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); table.RootSymbols.Add(new(TypeName.ToString() ?? "", SymbolKind.Struct), sym); foreach (var smem in Members) { - var msym = smem.TypeName.ToSymbol(); - table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); - smem.Type = msym; + smem.TypeName.ProcessSymbol(table); + smem.Type = smem.TypeName.Type; + table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); } } diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/AST/ShaderGenericsValues.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs new file mode 100644 index 0000000000..38994a3401 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -0,0 +1,96 @@ +using Stride.Shaders; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Parsing.Analysis; + +namespace Stride.Shaders.Parsing.SDSL.AST; + + +public abstract class Control(TextLocation info) : Flow(info); + + +public class ConditionalFlow(If first, TextLocation info) : Flow(info) +{ + public If If { get; set; } = first; + public List ElseIfs { get; set; } = []; + public Else? Else { get; set; } + public ShaderAttributeList? Attributes { get; set; } + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + If.ProcessSymbol(table, method, entrypoint, io); + foreach (var ei in ElseIfs) + ei.ProcessSymbol(table, method, entrypoint, io); + Else?.ProcessSymbol(table, method, entrypoint, io); + + } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; + } +} +public class If(Expression condition, Statement body, TextLocation info) : Flow(info) +{ + public Expression Condition { get; set; } = condition; + public Statement Body { get; set; } = body; + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + Condition.ProcessSymbol(table, entrypoint, io); + Body.ProcessSymbol(table, method, entrypoint, io); + if(Condition.Type != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); + } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"if({Condition})\n{Body}"; + } +} + +public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) +{ + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + Condition.ProcessSymbol(table, entrypoint, io); + Body.ProcessSymbol(table, method, entrypoint, io); + if(Condition.Type != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); + } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() + { + return $"else if({Condition}){Body}"; + } +} + +public class Else(Statement body, TextLocation info) : Flow(info) +{ + public Statement Body { get; set; } = body; + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + Body.ProcessSymbol(table, method, entrypoint, io); + } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() + { + return $"else {Body}"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs new file mode 100644 index 0000000000..b3a4ea5535 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -0,0 +1,119 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; + +namespace Stride.Shaders.Parsing.SDSL.AST; + +public abstract class Flow(TextLocation info) : Statement(info); + +public abstract class Loop(TextLocation info) : Flow(info); +public class Break(TextLocation info) : Statement(info) +{ + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class Discard(TextLocation info) : Statement(info) +{ + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class Continue(TextLocation info) : Statement(info) +{ + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} + + +public class ForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : Loop(info) +{ + public TypeName TypeName { get; set; } = typename; + public Identifier Variable { get; set; } = variable; + public Expression Collection { get; set; } = collection; + public Statement Body { get; set; } = body; + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + Collection.ProcessSymbol(table); + if(Collection.Type is ArrayType arrSym) + { + var btype = arrSym.BaseType; + TypeName.ProcessSymbol(table); + } + } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"foreach({TypeName} {Variable} in {Collection})\n{Body}"; + } +} + + +public class While(Expression condition, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +{ + public Expression Condition { get; set; } = condition; + public Statement Body { get; set; } = body; + public ShaderAttribute? Attribute { get; internal set; } = attribute; + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + { + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table); + } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"while({Condition})\n{Body}"; + } +} + +public enum ForAnnotationKind +{ + Unroll, + Loop, + Fastopt, + AllowUAVCondition +} +public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); + +public class For(Statement initializer, Statement cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +{ + public Statement Initializer { get; set; } = initializer; + public Statement Condition { get; set; } = cond; + public List Update { get; set; } = update; + public Statement Body { get; set; } = body; + public ShaderAttribute? Attribute = attribute; + public List Annotations { get; set; } = []; + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() + { + return $"for({Initializer} {Condition} {Update})\n{Body}"; + } +} + diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs similarity index 52% rename from src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 077456631b..02beb54451 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -1,15 +1,22 @@ using System.Text; using Stride.Shaders.Core; -using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Parsing.SDSL.AST; -public abstract class Statement(TextLocation info) : ValueNode(info); +public abstract class Statement(TextLocation info) : ValueNode(info) +{ + public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null!, null); + public virtual void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); + public abstract void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); +} public class EmptyStatement(TextLocation info) : Statement(info) { - public override SymbolType? Type { get => Scalar.From("void"); set { } } + public override SymbolType? Type { get => ScalarType.From("void"); set { } } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { } public override string ToString() => ";"; } @@ -17,6 +24,16 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta { public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; + + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + { + Expression.ProcessSymbol(table, entrypoint, io); + Type = ScalarType.From("void"); + } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + Expression.Compile(table, shader, compiler); + } public override string ToString() { return $"{Expression};"; @@ -25,9 +42,20 @@ public override string ToString() public class Return(TextLocation info, Expression? expression = null) : Statement(info) { - public override SymbolType? Type { get => Value?.Type ?? Scalar.From("void"); set { } } + public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + { + Value?.ProcessSymbol(table, entrypoint, io); + Type = Value?.Type ?? ScalarType.From("void"); + } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, _, _) = compiler; + builder.Return(Value?.Compile(table, shader, compiler)); + } public override string ToString() { return $"return {Value};"; @@ -39,13 +67,17 @@ public abstract class Declaration(TypeName typename, TextLocation info) : Statem public TypeName TypeName { get; set; } = typename; } -public class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +public class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) { public Expression Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; public Expression? Value { get; set; } = value; public bool IsConst { get; set; } = isConst; + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } public override string ToString() => Value switch { @@ -53,7 +85,7 @@ public override string ToString() Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" }; } -public class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Node(info) +public class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) { public Identifier Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; @@ -66,6 +98,20 @@ public List? ArraySizes set => TypeName.ArraySize = value; } + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + { + TypeName.ProcessSymbol(table, entrypoint, io); + Variable.Type = TypeName.Type; + Value?.ProcessSymbol(table, entrypoint, io); + if (Value is not null && Value.Type != Variable.Type) + table.Errors.Add(new(TypeName.Info, "wrong type")); + } + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + internal void ReplaceTypeName(TypeName typeName) { TypeName.Type = typeName.Type; @@ -84,13 +130,13 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) { if (TypeName == "var") { if (Variables.Count == 1 && Variables[0].Value is not null) { - Variables[0].Value?.ProcessSymbol(table); + Variables[0].Value?.ProcessSymbol(table, entrypoint, io); Type = Variables[0].Value!.Type; } else @@ -98,16 +144,20 @@ public override void ProcessSymbol(SymbolTable table) } else { - Type = TypeName.ToSymbol(); + TypeName.ProcessSymbol(table, entrypoint, io); + Type = TypeName.Type; table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); foreach (var d in Variables) { - d.Value?.ProcessSymbol(table); - table.CurrentTable.Add(new(d.Variable, SymbolKind.Variable), new(new(d.Variable, SymbolKind.Variable), Type)); + d.Value?.ProcessSymbol(table, entrypoint, io); + table.CurrentFrame.Add(new(d.Variable, SymbolKind.Variable), new(new(d.Variable, SymbolKind.Variable), Type)); } } } - + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } public override string ToString() { return $"{TypeName} {string.Join(", ", Variables.Select(v => v.ToString()))}"; @@ -118,61 +168,14 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) { foreach (var variable in Variables) - { - if (variable.Variable is Identifier id) - { - if (table.TryFind(id, SymbolKind.Variable, out var symbol)) - Type = symbol.Type; - else throw new NotImplementedException(); - } - else if (variable.Variable is AccessorChainExpression exp) - { - if (exp.Source is Identifier streams && streams == "streams") - { - if (exp.Accessors[0] is not Identifier) - throw new NotImplementedException(); - else - { - // Check type of first symbol - exp.Accessors[0].ProcessSymbol(table); - exp.Type = exp.Accessors[0].Type; - // If has more, dive into the type definition - // First case none - if (exp.Accessors.Count > 1) - { - foreach (var accessor in exp.Accessors[1..]) - { - if (exp.Type is not null && exp.Type.TryAccess(accessor, out var type)) - { - exp.Type = type; - accessor.Type = type; - } - else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {exp.Type}"); - } - } - - } - } - else - { - exp.Source.ProcessSymbol(table); - foreach (var accessor in exp.Accessors) - { - if (exp.Type is not null && exp.Type.TryAccess(accessor, out var type)) - { - exp.Type = type; - accessor.Type = type; - } - else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {exp.Type}"); - } - } - } - else throw new NotImplementedException(); - variable.Value?.ProcessSymbol(table); - } + variable.Variable.ProcessSymbol(table, entrypoint, io); + } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); } public override string ToString() { @@ -186,12 +189,23 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) { foreach (var s in Statements) - s.ProcessSymbol(table); + s.ProcessSymbol(table, method, entrypoint, io); } + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, _) = compiler; + builder.CreateBlock(context); + foreach (var s in Statements) + s.Compile(table, shader, compiler); + + } + + public List.Enumerator GetEnumerator() => Statements.GetEnumerator(); + public override string ToString() { var builder = new StringBuilder().Append("Block : \n"); diff --git a/src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs b/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs similarity index 76% rename from src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs rename to src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs index bc457919ed..d6ed8946b1 100644 --- a/src/Stride.Shaders.Parsing/SDSL/AST/SymbolTypeProcess.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs @@ -8,7 +8,7 @@ public static bool TryAccess(this SymbolType symbol, Expression expression, out { type = null; if( - symbol is Scalar or Vector + symbol is ScalarType or VectorType && expression is Identifier swizzle && swizzle.IsSwizzle() ) @@ -20,13 +20,13 @@ symbol is Scalar or Vector } else throw new NotImplementedException(); } - else if(symbol is Matrix matrix && expression is Identifier matrixField && matrixField.IsMatrixField()) + else if(symbol is MatrixType matrix && expression is Identifier matrixField && matrixField.IsMatrixField()) { type = matrix.BaseType; matrixField.Type = type; return true; } - else if(symbol is Struct s && expression is Identifier field) + else if(symbol is StructType s && expression is Identifier field) { if(s.Fields.TryGetValue(field, out var ft)) { @@ -40,20 +40,20 @@ symbol is Scalar or Vector public static bool TrySwizzle(this SymbolType symbol, string swizzle, out SymbolType? type) { type = null; - if(symbol is Scalar s) + if(symbol is ScalarType s) { foreach(var c in swizzle) if(c != 'r' || c != 'x') return false; - type = new Vector(s, swizzle.Length); + type = new VectorType(s, swizzle.Length); return true; } - else if(symbol is Vector v) + else if(symbol is VectorType v) { if(swizzle.Length == 1) type = v.BaseType; else - type = new Vector(v.BaseType, swizzle.Length); + type = new VectorType(v.BaseType, swizzle.Length); return true; } else return false; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs similarity index 98% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 5f98a096c5..e9989cfb57 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -245,11 +245,10 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann return false; } } - public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) + public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; - arraySize = null!; value = null!; if ( @@ -259,10 +258,10 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); - if (!FollowedByDelList(ref scanner, result, ArraySizes, out arraySize, withSpaces: true, advance: true)) - { + if (FollowedByDelList(ref scanner, result, ArraySizes, out List arraySize, withSpaces: true, advance: true)) + typeName.ArraySize = arraySize; + else scanner.Position = tmp; - } tmp = scanner.Position; if ( !( @@ -306,9 +305,9 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann scanner.Position = position; typeName = null!; identifier = null!; - arraySize = null!; return false; } + public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out Mixin mixin, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Delegates.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/Common/OptionalParser.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Spaces.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/Common/Spaces.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index 8e891f3f7d..39e1f7e153 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 5c07d51790..5cf2138277 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs similarity index 92% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 05b5ded9df..ef51adea9b 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -17,6 +18,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + /// + /// add ::= mul ( spaces '+' spaces add)* + /// public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -44,7 +48,9 @@ public static bool Add(ref TScanner scanner, ParseResult result, out E return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// mul ::= prefix ( spaces '*' spaces mul)* + /// public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -72,7 +78,9 @@ public static bool Mul(ref TScanner scanner, ParseResult result, out E return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// shift ::= add ( spaces ('<<' | '>>') spaces shift)* + /// public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -100,7 +108,9 @@ public static bool Shift(ref TScanner scanner, ParseResult result, out return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// relational ::= shift ( spaces ('<=' | '>=' | '<' | '>') spaces relational)* + /// public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -130,7 +140,9 @@ public static bool Relation(ref TScanner scanner, ParseResult result, return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// equality ::= relational ( spaces ('==' | '!=') spaces equality)* + /// public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -158,7 +170,9 @@ public static bool Equality(ref TScanner scanner, ParseResult result, return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// band ::= equality ( spaces '&' spaces band)* + /// public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -182,7 +196,7 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out } } while ( - !Parsers.FollowedBy(ref scanner, Tokens.Literal("&&"), withSpaces: true) + !Parsers.FollowedBy(ref scanner, Tokens.Literal("&&"), withSpaces: true) && Parsers.FollowedByAny(ref scanner, ["&"], out op, advance: true) ); if (parsed is not null) @@ -190,6 +204,10 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + /// + /// bor ::= band ( spaces '|' spaces bor)* + /// + public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -213,13 +231,16 @@ public static bool BOr(ref TScanner scanner, ParseResult result, out E } } while ( - !Parsers.FollowedBy(ref scanner, Tokens.Literal("||"), withSpaces: true) + !Parsers.FollowedBy(ref scanner, Tokens.Literal("||"), withSpaces: true) && Parsers.FollowedByAny(ref scanner, ["|"], out op, advance: true) ); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + /// + /// xor ::= bor ( spaces '^' spaces xor)* + /// public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -248,6 +269,9 @@ public static bool XOr(ref TScanner scanner, ParseResult result, out E return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + /// + /// and ::= xor ( spaces '&&' spaces and)* + /// public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -276,7 +300,9 @@ public static bool And(ref TScanner scanner, ParseResult result, out E return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// or ::= and ( spaces '&&' spaces or)* + /// public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -304,7 +330,9 @@ public static bool Or(ref TScanner scanner, ParseResult result, out Ex return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + /// + /// ternary ::= or ( spaces '?' spaces expression spaces ':' spaces expression)* + /// public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 8ae7be983c..2d207432fc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index bd695dfcc9..8193b602dc 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 0e216ca412..12a5d38eb3 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs similarity index 96% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index 0a4b291305..e9dba31ec8 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -150,11 +150,11 @@ public record struct BufferParsers : IParser else scanner.Position = tmp; if ( - Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySizes, out var value, advance: true) + Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out var value, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Set(";"), withSpaces: true, advance: true) ) { - parsed = new ShaderMember(typename, identifier, null, true, scanner[position..scanner.Position], isStage, streamKind, arraySizes: arraySizes); + parsed = new ShaderMember(typeName, identifier, value, scanner[position..scanner.Position], isStage, streamKind); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs similarity index 95% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index c289b91bed..ee5ffe99f9 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -15,9 +15,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = null!; var position = scanner.Position; - - TypeName? typeName = null!; - List arraySizes = null!; Expression? value = null!; var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); @@ -30,7 +27,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.VariableModifiers(ref scanner, result, out var isStaged, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) && Parsers.Spaces0(ref scanner, result, out _); - if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out typeName, out var identifier, out arraySizes, out value)) + if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out value)) { if ( Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) @@ -39,8 +36,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - typeName.ArraySize = arraySizes; - parsed = new(typeName, identifier, value, arraySizes != null, scanner[position..scanner.Position], semantic: semantic, arraySizes: arraySizes) + parsed = new(typeName, identifier, value, scanner[position..scanner.Position], semantic: semantic) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, @@ -54,7 +50,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new(typeName, identifier, value, arraySizes != null, scanner[position..scanner.Position], arraySizes: arraySizes) + parsed = new(typeName, identifier, value, scanner[position..scanner.Position]) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs similarity index 96% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 66b480647b..50ba2ba840 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -121,12 +121,11 @@ public static bool ShaderVariable(ref TScanner scanner, ParseResult re ; if ( - Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var type, out var name, out var arraySize, out var value) + Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out var value) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - type.ArraySize = arraySize; - parsed = new ShaderVariable(type, name, value, scanner[position..scanner.Position]) + parsed = new ShaderVariable(typeName, identifier, value, scanner[position..scanner.Position]) { StorageClass = storageClass.ToStorageClass(), TypeModifier = typemodifier.ToTypeModifier() diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs similarity index 96% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index b066da368e..48bd9b83dd 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -61,12 +61,11 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if (Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true)) - Parsers.Spaces1(ref scanner, result, out _); - if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var arraySize, out var value, advance: true) + if (!(Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true) && Parsers.Spaces1(ref scanner, result, out _))) + scanner.Position = position; + if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var value, advance: true) ) { - typename.ArraySize = arraySize; if ( Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index a38db15af6..70944035e2 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs similarity index 99% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index c2650266bc..56423f62e1 100644 --- a/src/Stride.Shaders.Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs similarity index 100% rename from src/Stride.Shaders.Parsing/SDSL/Parsers/Terminals/Terminals.cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs diff --git a/src/Stride.Shaders.Parsing/SDSLERR.cs b/src/Stride.Shaders/Parsing/SDSLERR.cs similarity index 98% rename from src/Stride.Shaders.Parsing/SDSLERR.cs rename to src/Stride.Shaders/Parsing/SDSLERR.cs index c7dd1e41b5..7b17567640 100644 --- a/src/Stride.Shaders.Parsing/SDSLERR.cs +++ b/src/Stride.Shaders/Parsing/SDSLERR.cs @@ -1,6 +1,8 @@ namespace Stride.Shaders.Parsing; - +/// +/// Error messages for SDSL +/// public static class SDSLErrorMessages { public const string SDSL0001 = "SDSL0001: Unexpected token"; diff --git a/src/Stride.Shaders.Parsing/SDSLParser.cs b/src/Stride.Shaders/Parsing/SDSLParser.cs similarity index 81% rename from src/Stride.Shaders.Parsing/SDSLParser.cs rename to src/Stride.Shaders/Parsing/SDSLParser.cs index 4546a466bc..b6c963168d 100644 --- a/src/Stride.Shaders.Parsing/SDSLParser.cs +++ b/src/Stride.Shaders/Parsing/SDSLParser.cs @@ -4,7 +4,9 @@ namespace Stride.Shaders.Parsing; - +/// +/// Wrapper class for both grammar and code preprocessor +/// public static class SDSLParser { public static ParseResult Parse(string code) diff --git a/src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs b/src/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/ErrorLocation.cs rename to src/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/IScannableCode.cs b/src/Stride.Shaders/Parsing/Scanners/IScannableCode.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/IScannableCode.cs rename to src/Stride.Shaders/Parsing/Scanners/IScannableCode.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/IScanner.cs b/src/Stride.Shaders/Parsing/Scanners/IScanner.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/IScanner.cs rename to src/Stride.Shaders/Parsing/Scanners/IScanner.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannableString.cs b/src/Stride.Shaders/Parsing/Scanners/ScannableString.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/ScannableString.cs rename to src/Stride.Shaders/Parsing/Scanners/ScannableString.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/Scanner.cs b/src/Stride.Shaders/Parsing/Scanners/Scanner.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/Scanner.cs rename to src/Stride.Shaders/Parsing/Scanners/Scanner.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs b/src/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/ScannerGeneric.cs rename to src/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs diff --git a/src/Stride.Shaders.Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs similarity index 100% rename from src/Stride.Shaders.Parsing/Scanners/TextLocation.cs rename to src/Stride.Shaders/Parsing/Scanners/TextLocation.cs diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs new file mode 100644 index 0000000000000000000000000000000000000000..6f839904abc6f1c49991f7e0a7df7b7abbd9114d GIT binary patch literal 4490 zcmc&%O-~d-5UsO`|6%k5iLQ59FrqObAxgw>As+TqH!i!I{eT$4UsvDj+M=dsdV2>1 z&4!_8x~J;(tLj%ZzkjV{AtRZ{H!0*)mNLg(Uk1{`-FNAP@f>Sf@=m6h9mt+Ml_%2t zy;GUN=3Fix*hWhZfntc?0M-|4T*Nj3?h8C!z;j1>7;W2I86&NZWQ?6FFS=jaE&sg| z{t9Ws%L?8u;At*D?K-~v!@)#p9 zbVOUnK)>W&EysLp_PGRiGx(yF|!z@KIWES zpI42V$2i5s3~Y8`afJ7ah(Bhjos~1#*F4#|jRT|4*u21hiw&QZx#OJ1M04p4?rmR% z?1wu>b1b_dTdr@jy1*QNF}_WRQjy=3m3P5Z$ZKFAlOyb72iKG*T1?NhqKvhyc?Ruq zM)|gJvWxMx+-zZizIX!3I@cG_%K@J3VZ^hmqZ{0jVa7;RBh9HsVtjHJWYcR-6DHiVE4QDKd`;+u3dSg?7IvZ3u7%XmI%1-HsLEkkOV##V z*IH?cJgnqYN|(2DU?-5C?Ce(SQ4>#b-j#XCodeZEsu1<1s;M3=&Quw9w6+K89+md7 zGrXB1mNly=MKM-d(^rdlP6anJuz4o-#?EXM`ZZ>DO6QHs9FF&};r*HRi0m1))23=M zUao##r4I1?1p26b6l;w3xm6uER?g*Xw(9&H65=8sozT0mC%i9?Q)tzEtro|yNG{s= z&k7rJ;VMfm4&j^MDm{!$@0y^vtG=@1jk|Js>EN$>i-2RpU<#1dG`?HcWbSkGdNR$7 zV||-o#QSkjRpO%3lYjOdtejU^MV*^MzVHDW=Yuv2rxL59&nZVwp2L?34edK-pTd7%f@H3!w zA^sw;3gNm^M_k?$^RcW+xvz$QQ8(`1Q&-V@ClIT8-LmCRPQ`OPszz&WR5h{gt<1W5 HRDJpb1TW_5 literal 0 HcmV?d00001 diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs new file mode 100644 index 0000000000..f632d04c25 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -0,0 +1,234 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Parsing.SDSL.AST; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Building; + + +public partial class SpirvBuilder +{ + public SpirvValue BinaryOperation(SpirvContext context, int resultType, in SpirvValue left, Operator op, in SpirvValue right, string? name = null) + { + + var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch + { + (Operator.Plus, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpIAdd(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Plus, ScalarType l, ScalarType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpFAdd(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Minus, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpISub(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Minus, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpFSub(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Mul, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpIMul(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Mul, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpFMul(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) + => Buffer.InsertOpUDiv(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpSDiv(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() + => Buffer.InsertOpFDiv(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() + => Buffer.InsertOpUMod(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertOpSMod(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsFloating() && r.IsNumber() + => Buffer.InsertOpFMod(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.RightShift, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertOpShiftRightLogical(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.LeftShift, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertOpShiftRightLogical(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.AND, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertOpBitwiseAnd(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.OR, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertOpBitwiseOr(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.XOR, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertOpBitwiseXor(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertOpLogicalAnd(Position, context.Bound++, resultType, left.Id, right.Id), + + (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertOpLogicalOr(Position, context.Bound++, resultType, left.Id, right.Id), + + _ => throw new NotImplementedException() + }; + Position += instruction.WordCount; + if (instruction.ResultId is int resultId) + { + if (name is not null) + context.AddName(instruction, name); + return new(instruction, name); + } + else throw new NotImplementedException("Instruction should have result id"); + } + + public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) + { + Span paramsIds = stackalloc IdRef[parameters.Length]; + var tmp = 0; + foreach (var p in parameters) + paramsIds[tmp++] = p.Id; + return CallFunction(context, name, paramsIds); + } + public SpirvValue CallFunction(SpirvContext context, string name, Span parameters) + { + var func = context.Module.Functions[name]; + var fcall = Buffer.InsertOpFunctionCall(Position, context.Bound++, func.Id, context.GetOrRegister(func.FunctionType.ReturnType), parameters); + Position += fcall.WordCount; + return new(fcall, func.Name); + } + + public SpirvValue CreateConstant(SpirvContext context, ShaderClass shader, Literal literal) + { + var instruction = literal switch + { + BoolLiteral lit => lit.Value switch + { + true => Buffer.InsertOpConstantTrue(Position, context.Bound++, context.GetOrRegister(lit.Type)), + false => Buffer.InsertOpConstantFalse(Position, context.Bound++, context.GetOrRegister(lit.Type)) + }, + IntegerLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.LongValue), + _ => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.IntValue), + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.DoubleValue), + _ => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), (float)lit.DoubleValue), + }, + _ => throw new NotImplementedException() + }; + Position += instruction.WordCount; + return new(instruction); + } + + public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) + { + var instruction = Buffer.InsertOpCompositeConstruct(Position, context.Bound++, context.GetOrRegister(literal.Type), values); + Position += instruction.WordCount; + return new(instruction); + } +} + + + + +internal static class SymbolExtensions +{ + + public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "sbyte" or "short" or "int" or "long" }; + public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "byte" or "ushort" or "uint" or "ulong" }; + public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { TypeName: "half" or "float" or "double" }; + public static bool IsInteger(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsUnsignedInteger(); + public static bool IsNumber(this SymbolType symbol) => symbol.IsInteger() || symbol.IsFloating(); + public static bool IsSigned(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsFloating(); + public static bool IsUnsigned(this SymbolType symbol) => symbol.IsUnsignedInteger(); + public static bool IsSignedIntegerVector(this SymbolType symbol) + => symbol.IsSignedInteger() || symbol is VectorType v && v.BaseType.IsSignedInteger(); + public static bool IsUnsignedIntegerVector(this SymbolType symbol) + => symbol.IsUnsignedInteger() || symbol is VectorType v && v.BaseType.IsUnsignedInteger(); + public static bool IsIntegerVector(this SymbolType symbol) + => symbol.IsInteger() || symbol is VectorType v && v.BaseType.IsInteger(); + public static bool IsFloatingVector(this SymbolType symbol) + => symbol.IsFloating() || symbol is VectorType v && v.BaseType.IsFloating(); + public static bool IsNumberVector(this SymbolType symbol) + => symbol.IsNumber() || symbol is VectorType v && v.BaseType.IsNumber(); + public static bool IsSignedVector(this SymbolType symbol) + => symbol.IsSignedIntegerVector() || symbol.IsFloatingVector(); + public static bool IsUnsignedVector(this SymbolType symbol) + => symbol.IsUnsignedIntegerVector(); + + public static bool SameComponentCount(SymbolType left, SymbolType right) + => (right, left) switch + { + (ScalarType l, ScalarType r) => true, + (VectorType l, ScalarType r) => l.Size == 1, + (ScalarType l, VectorType r) => r.Size == 1, + (VectorType l, VectorType r) => l.Size == r.Size, + (MatrixType l, VectorType r) => l.Columns == 1 && l.Rows == r.Size, + (VectorType l, MatrixType r) => r.Columns == 1 && r.Rows == l.Size, + (MatrixType l, MatrixType r) => r.Columns == l.Columns && r.Rows == l.Rows, + _ => false + }; + public static bool SameBaseTypeWidth(SymbolType left, SymbolType right) + => (right, left) switch + { + (ScalarType { TypeName: "byte" or "sbyte" }, ScalarType { TypeName: "byte" or "sbyte" }) => true, + (ScalarType { TypeName: "ushort" or "short" or "half" }, ScalarType { TypeName: "ushort" or "short" or "half" }) => true, + (ScalarType { TypeName: "uint" or "int" or "float" }, ScalarType { TypeName: "uint" or "int" or "float" }) => true, + (ScalarType { TypeName: "ulong" or "long" or "double" }, ScalarType { TypeName: "ulong" or "long" or "double" }) => true, + (VectorType l, ScalarType r) => SameBaseType(l.BaseType, r), + (ScalarType l, VectorType r) => SameBaseType(l, r.BaseType), + (VectorType l, VectorType r) => SameBaseType(l.BaseType, r.BaseType), + (MatrixType l, VectorType r) => SameBaseType(l.BaseType, r.BaseType), + (VectorType l, MatrixType r) => SameBaseType(l.BaseType, r.BaseType), + (MatrixType l, MatrixType r) => SameBaseType(l.BaseType, r.BaseType), + _ => false + }; + + public static bool SameComponentCountAndWidth(SymbolType left, SymbolType right) + => SameComponentCount(left, right) && SameBaseTypeWidth(left, right); + public static bool SameBaseType(SymbolType left, SymbolType right) + => (right, left) switch + { + (ScalarType l, ScalarType r) => l == r, + (VectorType l, ScalarType r) => l.BaseType == r, + (ScalarType l, VectorType r) => r.BaseType == l, + (VectorType l, VectorType r) => l.BaseType == r.BaseType, + (MatrixType l, VectorType r) => l.BaseType == r.BaseType, + (VectorType l, MatrixType r) => l.BaseType == r.BaseType, + (MatrixType l, MatrixType r) => l.BaseType == r.BaseType, + _ => false + }; + public static bool SameSignage(SymbolType left, SymbolType right) + => (right, left) switch + { + (ScalarType l, ScalarType r) => l.IsInteger() && l.IsInteger(), + (VectorType l, ScalarType r) => l.BaseType == r, + (ScalarType l, VectorType r) => r.BaseType == l, + (VectorType l, VectorType r) => l.BaseType == r.BaseType, + (MatrixType l, VectorType r) => l.BaseType == r.BaseType, + (VectorType l, MatrixType r) => l.BaseType == r.BaseType, + (MatrixType l, MatrixType r) => l.BaseType == r.BaseType, + _ => false + }; +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs new file mode 100644 index 0000000000..51cb90284a --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -0,0 +1,37 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Building; + + +public partial class SpirvBuilder +{ + public SpirvBlock CreateBlock(SpirvContext context, string? name = null) + { + var i = Buffer.InsertOpLabel(Position, context.Bound++); + Position += i.WordCount; + Position += Buffer.InsertOpUnreachable(Position).WordCount; + var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); + return result; + } + + public void Return(in SpirvValue? value = null) + { + Position += value switch + { + SpirvValue v => Buffer.InsertOpReturnValue(Position, v.Id).WordCount, + _ => Buffer.InsertOpReturn(Position).WordCount + }; + CleanBlock(); + } + + public void CleanBlock() + { + if ((Buffer.Span[Position] & 0xFFFF) == (int)SDSLOp.OpUnreachable) + { + var size = Buffer.Span[Position] >> 16; + Buffer.Remove(Position); + Position -= size; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs new file mode 100644 index 0000000000..b3e4e9b420 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -0,0 +1,45 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Building; + +public partial class SpirvBuilder +{ + public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.MaskNone) + { + foreach(var t in ftype.ParameterTypes) + context.GetOrRegister(t); + var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); + context.AddName(func, name); + var result = new SpirvFunction(func.ResultId!.Value, name, ftype); + Buffer.AddOpFunctionEnd(); + CurrentFunction = result; + return result; + } + + public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) + { + var p = Buffer.InsertOpFunctionParameter(Position, context.Bound++, context.GetOrRegister(type)); + Position += p.WordCount; + context.AddName(p, name); + CurrentFunction!.Value.Parameters.Add(name, new(p, name)); + return new(p, name); + } + public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.MaskNone) + { + var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(type.ReturnType), mask, context.GetOrRegister(type)); + context.AddName(func, name); + context.SetEntryPoint(execModel, func, name, variables); + var result = new SpirvFunction(func.ResultId!.Value, name, type); + if(!variables.IsEmpty) + foreach(var p in variables) + context.AddName(context.Variables[p.Id.Name], p.Id.Name); + Position += Buffer.InsertOpFunctionEnd(Position).WordCount; + CurrentFunction = result; + return result; + } + + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs new file mode 100644 index 0000000000..3b8a3305b2 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -0,0 +1,66 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Building; + + + +// Should have utility functions to add instruction to the buffer +public partial class SpirvBuilder() : IDisposable +{ + public SpirvBuffer Buffer { get; init; } = new(); + public SpirvFunction? CurrentFunction { get; private set; } + public SpirvBlock? CurrentBlock { get; private set; } + public int Position { get; private set; } + + public void SetPositionTo(TBlock block, bool beggining = false) + where TBlock : IInstructionBlock + { + if (block is SpirvBlock bb) + SetPositionTo(bb.Parent); + bool blockFound = false; + Span blockTermination = [ + (int)SDSLOp.OpBranch, + (int)SDSLOp.OpBranchConditional, + (int)SDSLOp.OpSwitch, + (int)SDSLOp.OpReturn, + (int)SDSLOp.OpReturnValue, + (int)SDSLOp.OpKill, + (int)SDSLOp.OpUnreachable, + (int)SDSLOp.OpTerminateInvocation + ]; + foreach (var e in Buffer) + { + if (e.ResultId is int id && id == block.Id) + { + blockFound = true; + // In case we want to top at the beginning of the block + if(beggining) + { + Position = e.WordIndex + e.WordCount; + return; + } + } + if (block is SpirvBlock && blockFound && blockTermination.Contains((int)e.OpCode)) + { + Position = e.WordIndex; + return; + } + else if (block is SpirvFunction && blockFound && e.OpCode == SDSLOp.OpFunctionEnd) + { + Position = e.WordIndex; + return; + } + } + Position = Buffer.Length; + } + + public SpirvBuffer Build(SpirvContext context) + { + context.Buffer.Sort(); + return SpirvBuffer.Merge(context.Buffer, Buffer); + } + + public void Dispose() => Buffer.Dispose(); +} diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs new file mode 100644 index 0000000000..6fb3ae2065 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -0,0 +1,30 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Spirv.Building; + + +public abstract class CompilerArgument; + + +public class CompilerUnit +{ + public SpirvModule Module { get; } + public SpirvContext Context { get; } + public SpirvBuilder Builder { get; } + public List Arguments { get; } + + public CompilerUnit() + { + Module = new SpirvModule(); + Context = new SpirvContext(Module); + Builder = new SpirvBuilder(); + Arguments = []; + } + + public void Deconstruct(out SpirvBuilder builder, out SpirvContext context, out SpirvModule module) + { + builder = Builder; + context = Context; + module = Module; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs new file mode 100644 index 0000000000..973d519e94 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -0,0 +1,166 @@ +using System.Numerics; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Building; + +// Should contain internal data not seen by the client but helpful for the generation like type symbols and other +// SPIR-V parameters +public class SpirvContext(SpirvModule module) : IDisposable +{ + public int Bound { get; internal set; } = 1; + public SpirvModule Module { get; } = module; + public SortedList Variables { get; } = []; + public Dictionary Types { get; } = []; + public Dictionary ReverseTypes { get; } = []; + public SpirvBuffer Buffer { get; set; } = new(); + + public void AddName(IdRef target, string name) + => Buffer.AddOpName(target, name); + + public void AddMemberName(IdRef target, int accessor, string name) + => Buffer.AddOpMemberName(target, accessor, name); + + public IdRef AddConstant(TScalar value) + where TScalar : INumber + { + return value switch + { + byte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v), + sbyte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v), + ushort v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v), + short v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v), + uint v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v), + int v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v), + ulong v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v), + long v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v), + Half v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v), + float v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v), + double v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v), + _ => throw new NotImplementedException() + }; + } + + public void AddGlobalVariable(Symbol variable) + { + throw new NotImplementedException(); + // var t = GetOrRegister(variable.Type); + // if (variable.Id.Storage == Storage.Stream) + // { + // foreach(var usage in SymbolProvider.RootSymbols.StreamUsages[variable.Id]) + // { + // var i = Buffer.AddOpVariable( + // Bound++, + // t, + // usage.IO switch + // { + // StreamIO.Input => StorageClass.Input, + // StreamIO.Output => StorageClass.Output, + // _ => throw new NotImplementedException() + // }, + // null + // ); + // Variables[variable.Id.Name] = i.ResultId!.Value; + // AddName(i, $"{usage.EntryPoint.ToString()}_{usage.IO.ToString()}_{variable.Id.Name}"); + // } + // } + // else + // { + // var storage = variable.Id.Storage switch + // { + // Storage.UniformConstant => StorageClass.UniformConstant, + // Storage.Uniform => StorageClass.Uniform, + // Storage.Function => StorageClass.Function, + // Storage.Generic => StorageClass.Generic, + // _ => throw new NotImplementedException("Variable has to have a storage class") + // }; + // var i = Buffer.AddOpVariable(Bound++, t, storage, null); + // Variables[variable.Id.Name] = i.ResultId!.Value; + // AddName(i, $"{variable.Id.Name}"); + // } + } + + + public void SetEntryPoint(ExecutionModel model, IdRef function, string name, ReadOnlySpan variables) + { + Span pvariables = stackalloc IdRef[variables.Length]; + int pos = 0; + foreach (var v in variables) + pvariables[pos++] = Variables[v.Id.Name]; + Buffer.AddOpEntryPoint(model, function, name, pvariables); + } + + public IdRef GetOrRegister(SymbolType? type) + { + if(type is null) + throw new ArgumentException($"Type is null"); + if (Types.TryGetValue(type, out var res)) + return res; + else + { + var instruction = type switch + { + ScalarType s => + s.TypeName switch + { + "void" => Buffer.AddOpTypeVoid(Bound++), + "bool" => Buffer.AddOpTypeBool(Bound++), + "sbyte" => Buffer.AddOpTypeInt(Bound++, 8, 1), + "byte" => Buffer.AddOpTypeInt(Bound++, 8, 0), + "ushort" => Buffer.AddOpTypeInt(Bound++, 16, 1), + "short" => Buffer.AddOpTypeInt(Bound++, 16, 0), + "int" => Buffer.AddOpTypeInt(Bound++, 32, 1), + "uint" => Buffer.AddOpTypeInt(Bound++, 32, 0), + "long" => Buffer.AddOpTypeInt(Bound++, 64, 1), + "ulong" => Buffer.AddOpTypeInt(Bound++, 64, 0), + "half" => Buffer.AddOpTypeFloat(Bound++, 16, null), + "float" => Buffer.AddOpTypeFloat(Bound++, 32, null), + "double" => Buffer.AddOpTypeFloat(Bound++, 64, null), + _ => throw new NotImplementedException($"Can't add type {type}") + + }, + VectorType v => Buffer.AddOpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size), + MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), + ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), + StructType st => RegisterStruct(st), + FunctionType f => RegisterFunctionType(f), + // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), + // StructSymbol st => RegisterStruct(st), + _ => throw new NotImplementedException($"Can't add type {type}") + }; + Types[type] = instruction; + ReverseTypes[instruction] = type; + return instruction; + } + } + + IdRef RegisterStruct(StructType structSymbol) + { + Span types = stackalloc IdRef[structSymbol.Fields.Count]; + int tmp = 0; + foreach (var f in structSymbol.Fields) + { + types[tmp] = GetOrRegister(f.Value); + AddMemberName(types[tmp], tmp, f.Key); + } + var result = Buffer.AddOpTypeStruct(Bound++, types); + AddName(result, structSymbol.Name); + return result; + } + + IdRef RegisterFunctionType(FunctionType functionType) + { + Span types = stackalloc IdRef[functionType.ParameterTypes.Count]; + int tmp = 0; + foreach (var f in functionType.ParameterTypes) + types[tmp] = GetOrRegister(f); + var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); + AddName(result, functionType.ToString()); + return result; + } + + public void Dispose() => Buffer.Dispose(); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/DictionaryPool.cs b/src/Stride.Shaders/Spirv/Building/DictionaryPool.cs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/Stride.Shaders/Spirv/Building/Module.cs b/src/Stride.Shaders/Spirv/Building/Module.cs new file mode 100644 index 0000000000..fd136f1cbd --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Module.cs @@ -0,0 +1,8 @@ +namespace Stride.Shaders.Spirv.Building; + + +// Should contain symbols for the SPIR-V module +public class SpirvModule() +{ + public SortedList Functions { get; init; } = []; +} diff --git a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs new file mode 100644 index 0000000000..666ce792d1 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs @@ -0,0 +1,127 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Runtime.CompilerServices; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + + +// /// +// /// Makes sure indices used in spirv module are all continuous. +// /// +// public struct BoundReducer : INanoPass +// { +// public BoundReducer() { } + +// public void Apply(SpirvBuffer buffer) +// { +// // First step is to find the next idResult +// // If it's previous + 1 then it's okay, previous is now updated +// // If it's above previous + 1, then it's not okay and we switch + +// var finished = false; +// var previousId = 0; +// var next = Instruction.Empty; +// var countIds = 0; + +// foreach (var i in buffer.Instructions) +// countIds += i.ResultId != null ? 1 : 0; +// while (!finished && previousId < countIds) +// { +// var countAbove = 0; +// foreach(var i in buffer.Instructions) +// { +// if(i.ResultId == previousId + 1) +// { +// countAbove += 1; +// previousId += 1; +// next = i; +// break; +// } +// else if (next.IsEmpty && i.ResultId > previousId + 1) +// { +// countAbove += 1; +// next = i; +// } +// else if(!next.IsEmpty && i.ResultId > previousId + 1 && i.ResultId < next.ResultId) +// { +// countAbove += 1; +// next = i; +// } +// } +// if (countAbove == 0) +// finished = true; +// else if(next.ResultId > previousId + 1) +// { +// next.AsRef().SetResultId(previousId + 1); +// ReplaceRefs(next.ResultId ?? -1, previousId + 1, buffer); +// } +// } + + +// buffer.RecomputeBound(); +// } +// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) +// { +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// foreach (var (_, f) in buffer.Functions) +// foreach (var i in f.UnorderedInstructions) +// { +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// } +// static void ReplaceRefs(int from, int to, SpirvBuffer func) +// { +// foreach (var i in func) +// { +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// } +// } diff --git a/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs new file mode 100644 index 0000000000..db3787d05b --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs @@ -0,0 +1,62 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Core.Parsing; +// using static Spv.Specification; + +// namespace Stride.Shaders.Spirv.Processing; + +// public struct CapabilitiesCompute : INanoPass +// { +// public void Apply(SpirvBuffer buffer) +// { +// throw new NotImplementedException("Needs to finish checking the spec"); +// } + +// public static void AddCapabilities(Instruction instruction) +// { +// if(instruction.OpCode == SDSLOp.OpEntryPoint) +// { +// if(instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.Geometry) +// { +// //Add capability geometry +// } +// else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationControl) +// { +// //Add capability tess + +// } +// else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationEvaluation) +// { +// //Add capability tess +// } +// } +// else if(instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 16) +// { +// // Add capability Float16 +// } +// else if (instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 64) +// { +// // Add capability Float64 +// } +// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 64) +// { +// // Add capability Float64 +// } +// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 16) +// { +// // Add capability Float64 +// } +// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 8) +// { +// // Add capability Float64 +// } + +// // TODO : Check if any atomic instructions operates on integers +// // else if (instruction.OpCode == SDSLOp.OpAtomic && instruction.Words.Span[2] == 64) +// // { +// // // Add capability Float64 +// // } + + +// } +// } diff --git a/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs b/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs new file mode 100644 index 0000000000..1095a4d5be --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs @@ -0,0 +1,30 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Processing; + +// namespace Stride.Shaders.Spirv.PostProcessing; + +// public struct CompressBuffer : INanoPass +// { +// public void Apply(SpirvBuffer buffer) +// { +// using var tmp = new WordBuffer(); +// foreach (var e in buffer.Declarations.UnorderedInstructions) +// if (e.OpCode != SDSLOp.OpNop) +// tmp.Insert(e); +// buffer.Declarations.InstructionSpan.Clear(); +// tmp.InstructionSpan.CopyTo(buffer.Declarations.InstructionSpan); +// buffer.Declarations.RecomputeLength(); +// foreach (var (_, f) in buffer.Functions) +// { +// tmp.InstructionSpan.Clear(); +// tmp.RecomputeLength(); +// foreach (var e in f.UnorderedInstructions) +// if (e.OpCode != SDSLOp.OpNop) +// tmp.Insert(e); +// f.InstructionSpan.Clear(); +// tmp.InstructionSpan.CopyTo(f.InstructionSpan); +// f.RecomputeLength(); +// } +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs b/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs new file mode 100644 index 0000000000..1159317ec5 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs @@ -0,0 +1,57 @@ +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Core; +// namespace Stride.Shaders.Spirv.Processing; + +// /// +// /// Makes sure variables are created in the beginning of a function definition +// /// +// public struct FunctionVariableOrderer : INanoPass +// { +// public void Apply(SpirvBuffer buffer) +// { +// foreach(var (_,f) in buffer.Functions) +// { +// ProcessFunction(new(f.InstructionSpan)); +// f.RecomputeLength(); +// } +// } +// public static void ProcessFunction(SpirvSpan function) +// { +// using var tmp = new SpirvBuffer(function.Span.Length); +// var enumerator = function.GetEnumerator(); +// enumerator.MoveNext(); +// var opf = enumerator.Current; +// tmp.Insert(tmp.Length, opf.Words); +// foreach(var i in function) +// { +// if(i.OpCode == SDSLOp.OpFunctionParameter) +// tmp.Insert(tmp.Length, i.Words); +// } +// while(enumerator.Current.OpCode != SDSLOp.OpLabel) +// enumerator.MoveNext(); + +// tmp.Insert(tmp.Length, enumerator.Current.Words); + +// foreach (var i in function) +// { +// if(i.OpCode == SDSLOp.OpVariable) +// { +// tmp.Insert(tmp.Length,i.Words); +// } +// } +// while(enumerator.MoveNext()) +// { +// var i = enumerator.Current; +// if (i.OpCode != SDSLOp.OpVariable && i.OpCode != SDSLOp.OpFunctionParameter) +// { +// tmp.Insert(tmp.Length, i.Words); +// } +// if (i.OpCode == SDSLOp.OpSDSLVariable) +// { +// var t = 0; +// } +// } +// function.Span.Clear(); +// tmp.InstructionSpan.CopyTo(function.Span); +// } +// } diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs similarity index 90% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs rename to src/Stride.Shaders/Spirv/Processing/INanoPass.cs index 95c12e6896..46a116e959 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/INanoPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs @@ -13,5 +13,5 @@ namespace Stride.Shaders.Spirv.Processing; ///
public interface INanoPass { - void Apply(MultiBuffer buffer); + void Apply(SpirvBuffer buffer); } diff --git a/src/Stride.Shaders/Spirv/Processing/IOReplace.cs b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs new file mode 100644 index 0000000000..2f7ac5f077 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs @@ -0,0 +1,74 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Processing; +// using static Spv.Specification; + +// namespace Stride.Shaders.Spirv.PostProcessing; + +// public struct SDSLVariableReplace : INanoPass +// { +// public void Apply(SpirvBuffer buffer) +// { +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// if (i.OpCode == SDSLOp.OpSDSLIOVariable) +// { + +// var sclassv = i.GetOperand("storageclass"); +// var sclass = StorageClass.Private; +// if (sclassv != null) +// sclass = (StorageClass)sclassv.Value.Words; +// var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); +// variable.Operands.Span[1] = i.ResultId ?? -1; +// buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); +// SetOpNop(i.Words.Span); +// } +// else if (i.OpCode == SDSLOp.OpSDSLVariable) +// { +// var sclassv = i.GetOperand("storageclass"); +// var sclass = StorageClass.Private; +// if (sclassv != null) +// sclass = (StorageClass)sclassv.Value.Words; +// var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); +// variable.Operands.Span[1] = i.ResultId ?? -1; +// buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); +// SetOpNop(i.Words.Span); +// } +// } +// foreach (var (n, f) in buffer.Functions) +// { +// foreach (var i in f.UnorderedInstructions) +// { +// if(i.OpCode == SDSLOp.OpSDSLFunctionParameter) +// { +// var name = i.GetOperand("name"); +// var resultType = i.ResultType ?? -1; +// var variable = f.AddOpFunctionParameter(resultType); +// variable.Operands.Span[1] = i.ResultId ?? -1; +// buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); +// SetOpNop(i.Words.Span); +// } +// else if (i.OpCode == SDSLOp.OpSDSLVariable) +// { + +// var sclassv = i.GetOperand("storageclass"); +// var sclass = StorageClass.Private; +// if (sclassv != null) +// sclass = (StorageClass)sclassv.Value.Words; +// var name = i.GetOperand("name"); +// var resultType = i.ResultType ?? -1; +// var initializer = i.GetOperand("initializer"); +// var variable = f.AddOpVariable(resultType, sclass, initializer); +// variable.Operands.Span[1] = i.ResultId ?? -1; +// buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); +// SetOpNop(i.Words.Span); +// } +// } +// } +// } +// static void SetOpNop(Span words) +// { +// words[0] = words.Length << 16; +// words[1..].Clear(); +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs new file mode 100644 index 0000000000..f3d3854a28 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs @@ -0,0 +1,505 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Processing; +// using static Spv.Specification; + +// namespace Stride.Shaders.Spirv.PostProcessing; + +// public struct IOVariableDecorator : INanoPass +// { +// public void Apply(SpirvBuffer buffer) +// { +// int inputLocation = -1; +// int outputLocation = -1; +// foreach (var i in buffer.Declarations) +// { +// if(i.OpCode == SDSLOp.OpSDSLIOVariable) +// { +// var execution = (ExecutionModel)(i.GetOperand("executionModel")?.Words ?? -1); +// var storage = (StorageClass)(i.GetOperand("storageclass")?.Words ?? -1); +// var semantic = i.GetOperand("semantic")?.Value ?? throw new NotImplementedException(); +// if (semantic == "SV_Position") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage,execution) switch +// { +// (StorageClass.Input, ExecutionModel.Fragment) => (int)BuiltIn.FragCoord, +// (StorageClass.Input or StorageClass.Output, _) +// => (int)BuiltIn.Position, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_ClipDistance") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Input or StorageClass.Output, _) +// => (int)BuiltIn.ClipDistance, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_CullDistance") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Input or StorageClass.Output, _) +// => (int)BuiltIn.CullDistance, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_VertexID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Input, ExecutionModel.Vertex) +// => (int)BuiltIn.VertexIndex, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_InstanceID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Input, ExecutionModel.Vertex) +// => (int)BuiltIn.InstanceIndex, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_Depth" || semantic == "SV_DepthGreaterEqual" || semantic == "SV_DepthLessEqual") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Output,ExecutionModel.Fragment) +// => (int)BuiltIn.FragDepth, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_IsFrontFace") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// (StorageClass.Input, ExecutionModel.Fragment) +// => (int)BuiltIn.FrontFacing, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_DispatchThreadID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.GLCompute +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// or ExecutionModel.TaskEXT +// or ExecutionModel.TaskNV +// ) +// => (int)BuiltIn.GlobalInvocationId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_GroupID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.GLCompute +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// or ExecutionModel.TaskEXT +// or ExecutionModel.TaskNV +// ) +// => (int)BuiltIn.WorkgroupId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_GroupThreadID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.GLCompute +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// or ExecutionModel.TaskEXT +// or ExecutionModel.TaskNV +// ) +// => (int)BuiltIn.LocalInvocationId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_GroupIndex") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.GLCompute +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// or ExecutionModel.TaskEXT +// or ExecutionModel.TaskNV +// ) +// => (int)BuiltIn.LocalInvocationIndex, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_OutputControlPointID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.TessellationControl +// ) +// => (int)BuiltIn.InvocationId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_GSInstanceID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Geometry +// ) +// => (int)BuiltIn.InvocationId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_DomainLocation") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.TessellationEvaluation +// ) +// => (int)BuiltIn.TessCoord, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_PrimitiveID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.TessellationControl +// or ExecutionModel.TessellationEvaluation +// or ExecutionModel.Geometry +// or ExecutionModel.Fragment +// ) +// or( +// StorageClass.Output, +// ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// or ExecutionModel.Geometry +// ) +// => (int)BuiltIn.TessCoord, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_TessFactor") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.TessellationControl +// ) +// => (int)BuiltIn.TessLevelOuter, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_InsideTessFactor") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.TessellationControl +// ) +// => (int)BuiltIn.TessLevelInner, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_SampleIndex") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.SampleId, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_StencilRef") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Output, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.FragStencilRefEXT, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_Barycentrics") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.BaryCoordKHR, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_RenderTargetArrayIndex") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// or +// ( +// StorageClass.Output, +// ExecutionModel.Geometry +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// ) +// => (int)BuiltIn.Layer, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_ViewportArrayIndex") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// or +// ( +// StorageClass.Output, +// ExecutionModel.Geometry +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// ) +// => (int)BuiltIn.ViewportIndex, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_Coverage") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input or StorageClass.Output, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.SampleMask, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_InnerCoverage") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.FullyCoveredEXT, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_ViewID") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Input, +// ExecutionModel.Vertex +// or ExecutionModel.TessellationControl +// or ExecutionModel.TessellationEvaluation +// or ExecutionModel.Geometry +// or ExecutionModel.Fragment +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// ) +// => (int)BuiltIn.ViewIndex, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_ShadingRate") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Output, +// ExecutionModel.Vertex +// or ExecutionModel.Geometry +// or ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// ) +// => (int)BuiltIn.PrimitiveShadingRateKHR, +// ( +// StorageClass.Input, +// ExecutionModel.Fragment +// ) +// => (int)BuiltIn.ShadingRateKHR, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else if (semantic == "SV_CullPrimitive") +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.BuiltIn, +// (storage, execution) switch +// { +// ( +// StorageClass.Output, +// ExecutionModel.MeshEXT +// or ExecutionModel.MeshNV +// ) +// => (int)BuiltIn.CullPrimitiveEXT, +// _ => throw new NotImplementedException() +// } +// ); +// } +// else +// { +// buffer.AddOpDecorate( +// i.ResultId ?? -1, +// Decoration.Location, +// (storage, execution) switch +// { +// (StorageClass.Input, _) +// => ++inputLocation, +// (StorageClass.Output, _) +// => ++outputLocation, +// _ => throw new NotImplementedException() +// } +// ); +// } +// } +// } +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/Processing/IPostProcessorSubPass.cs rename to src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs diff --git a/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs b/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs new file mode 100644 index 0000000000..1735425792 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs @@ -0,0 +1,41 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Runtime.CompilerServices; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + + +// /// +// /// Offsets ids for each mixins inherited +// /// +// public struct IdRefOffsetter : INanoPass +// { +// public IdRefOffsetter() { } + +// public void Apply(SpirvBuffer buffer) +// { +// //int offset = 0; +// //int nextOffset = 0; +// //foreach (var i in buffer) +// //{ +// // // if we hit a mixin name we reset stuff +// // if (i.OpCode == SDSLOp.OpSDSLMixinName) +// // { +// // offset += nextOffset; +// // nextOffset = 0; +// // } +// // else +// // { +// // if (i.ResultId != null) +// // nextOffset = i.ResultId.Value; +// // i.AsRef().OffsetIds(offset); +// // } +// //} +// } +// } diff --git a/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs new file mode 100644 index 0000000000..5260aada46 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs @@ -0,0 +1,42 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + +// /// +// /// Checks for duplicate memory models in case of multiple entry points +// /// +// public struct MemoryModelDuplicatesRemover : INanoPass +// { + +// public void Apply(SpirvBuffer buffer) +// { +// var found = false; +// var wid = 0; +// var span = buffer.Declarations.InstructionSpan; +// while(wid < buffer.Declarations.Length) +// { +// if ((span[wid] & 0xFFFF) == (int)SDSLOp.OpMemoryModel) +// { +// if (!found) +// found = true; +// else +// SetOpNop(span.Slice(wid, span[wid] >> 16)); +// } +// wid += span[wid] >> 16; +// } +// } + +// static void SetOpNop(Span words) +// { +// words[0] = words.Length << 16; +// words[1..].Clear(); +// } + +// } diff --git a/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs b/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs new file mode 100644 index 0000000000..03ed877c63 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs @@ -0,0 +1,36 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Core.Parsing; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + +// public record struct OrderedSpvBuffer(SpirvBuffer Buffer) +// { +// public readonly OrderedEnumerator GetEnumerator() => new(Buffer); +// } + +// /// +// /// Merges mixins into one final spirv file +// /// +// public struct MixinMerger : INanoPass +// { +// public readonly void Apply(SpirvBuffer buffer) +// { +// //var temp = new SpirvBuffer(); +// //var ordered = new OrderedSpvBuffer(buffer); +// //foreach (var e in ordered) +// // if(e.OpCode != SDSLOp.OpNop) +// // temp.Add(e.Words.Span); + +// //buffer.Replace(temp, out var dispose); +// //if(dispose) +// // temp.Dispose(); +// //buffer.RecomputeBound(); +// } +// } diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs new file mode 100644 index 0000000000..e03bacfdfd --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -0,0 +1,48 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Processing; + +// namespace Stride.Shaders.Spirv.PostProcessing; + +// /// +// /// Nano pass merger/optimizer/compiler +// /// +// public static class PostProcessor +// { +// public static SpirvBuffer Process(string mixinName) +// { +// var buffer = new SpirvBuffer(); +// var mixin = MixinSourceProvider.Get(mixinName); +// var parents = MixinSourceProvider.GetMixinGraph(mixinName); +// var bound = 0; +// foreach(var p in parents) +// { +// foreach (var i in p.Instructions) +// buffer.Duplicate(i.AsRef(), bound); +// bound += p.Bound; +// } +// foreach(var i in mixin.Instructions) +// buffer.Duplicate(i.AsRef(), bound); +// Apply(buffer); + +// return new(buffer); +// } + +// static void Apply(SpirvBuffer buffer) +// { +// Apply(buffer); +// Apply(buffer); +// Apply(buffer); +// Apply(buffer); +// Apply(buffer); +// Apply(buffer); +// Apply(buffer); +// } + +// static void Apply(SpirvBuffer buffer) +// where T : struct, INanoPass +// { +// var p = new T(); +// p.Apply(buffer); +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs new file mode 100644 index 0000000000..b3fd12d817 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs @@ -0,0 +1,46 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using Stride.Shaders.Spirv.Core.Parsing; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + +// /// +// /// Removes SDSL specific instructions +// /// +// public struct SDSLOpRemover : INanoPass +// { + +// public void Apply(SpirvBuffer buffer) +// { +// var decl = new InstructionEnumerator(buffer.Declarations); +// while(decl.MoveNext()) +// { +// var i = decl.Current; +// if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) +// SetOpNop(i.AsRef()); +// } +// foreach (var (_, f) in buffer.Functions) +// { +// var func = new InstructionEnumerator(f); +// while(func.MoveNext()) +// { +// var i = func.Current; +// if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) +// SetOpNop(i.AsRef()); +// } +// } +// } + +// static void SetOpNop(RefInstruction i) +// { +// i.Words[0] = i.WordCount << 16; +// i.Operands.Clear(); +// } + +// } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs new file mode 100644 index 0000000000..776fd5a83f --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -0,0 +1,206 @@ +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; + +// namespace Stride.Shaders.Spirv.Processing; + + + + +// /// +// /// Remove duplicate simple types. +// /// Should be applied before the IdRefOffsetter. +// /// +// public struct TypeDuplicateRemover : INanoPass +// { + +// public readonly void Apply(SpirvBuffer buffer) +// { +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) +// { +// foreach (var j in buffer.Declarations.UnorderedInstructions) +// { +// if ( +// (j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words.Span); +// } +// } +// } +// } +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// if (i.OpCode == SDSLOp.OpTypeVector) +// { +// foreach (var j in buffer.Declarations.UnorderedInstructions) +// { +// if ( +// j.OpCode == SDSLOp.OpTypeVector +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words.Span); +// } +// } +// } +// } +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// if (i.OpCode == SDSLOp.OpTypeMatrix) +// { +// foreach (var j in buffer.Declarations.UnorderedInstructions) +// { +// if ( +// j.OpCode == SDSLOp.OpTypeMatrix +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words.Span); +// } +// } +// } +// } +// //var idx1 = 0; +// //// First base types +// //foreach (var i in buffer.Declarations.UnorderedInstructions) +// //{ +// // if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) +// // { +// // var idx2 = 0; +// // foreach (var j in buffer.Declarations) +// // { +// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) +// // { +// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// // SetOpNop(j.Words.Span); +// // } +// // idx2 += 1; +// // } +// // } +// // else if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeBool) +// // { +// // var idx2 = 0; +// // foreach (var j in buffer.Declarations) +// // { +// // if (j.OpCode == i.OpCode && idx1 != idx2) +// // { +// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// // SetOpNop(j.Words.Span); +// // } +// // idx2 += 1; +// // } +// // } +// // idx1 += 1; +// //} +// //idx1 = 0; +// //// Then vectors +// //foreach (var i in buffer.Declarations.UnorderedInstructions) +// //{ +// // if (i.OpCode == SDSLOp.OpTypeVector) +// // { +// // var idx2 = 0; +// // foreach (var j in buffer.Declarations) +// // { +// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) +// // { +// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// // SetOpNop(j.Words.Span); +// // } +// // idx2 += 1; +// // } +// // } +// // idx1 += 1; +// //} +// //idx1 = 0; + +// //// Then matrices +// //foreach (var i in buffer.Declarations.UnorderedInstructions) +// //{ +// // if (i.OpCode == SDSLOp.OpTypeMatrix) +// // { +// // var idx2 = 0; +// // foreach (var j in buffer.Declarations) +// // { +// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) +// // { +// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// // SetOpNop(j.Words.Span); +// // } +// // idx2 += 1; +// // } +// // } +// // idx1 += 1; +// //} + +// } + +// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) +// { +// foreach (var i in buffer.Declarations.UnorderedInstructions) +// { +// var opcode = i.OpCode; +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// if (op.Words[0] == from || op.Words[1] == from) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// } +// foreach (var (_, f) in buffer.Functions) +// foreach (var i in f.UnorderedInstructions) +// { +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// if (op.Words[0] == from || op.Words[1] == from) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// } +// } + +// static void SetOpNop(Span words) +// { +// words[0] = words.Length << 16; +// words[1..].Clear(); +// } +// } diff --git a/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs b/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs new file mode 100644 index 0000000000..28f22f6d74 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs @@ -0,0 +1,39 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core.Buffers; + + +namespace Stride.Shaders.Spirv; + + + + +public record struct Mixin(string Name, SpirvBuffer Buffer); + + +public class MixinStorage +{ + public static MixinStorage Instance { get; } = new(); + Dictionary Storage { get; } = []; + + private MixinStorage(){} + + public static void RegisterOrUpdate(string name, SpirvBuffer buffer) + { + Instance.Storage[name] = new(name, buffer); + } + + public static bool TryRegister(string name, SpirvBuffer buffer) + { + return Instance.Storage.TryAdd(name, new(name, buffer)); + } + + public static Mixin Get(string name) + { + return Instance.Storage[name]; + } + + public static bool TryGet(string name, out Mixin mixin) + { + return Instance.Storage.TryGetValue(name, out mixin); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs new file mode 100644 index 0000000000..980f006721 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs @@ -0,0 +1,272 @@ +using static Spv.Specification; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv.Tools; + + +public partial struct SpirvDis +{ + public readonly void Append(IdResult? result) + { + + if (result != null) + { + var tmp = result.Value; + var size = 1; + while (tmp > 0) + { + tmp /= 10; + size += 1; + } + writer.Append(' ', IdOffset - 1 - size).Append('%', ConsoleColor.Blue).Append(result!.Value.Value, ConsoleColor.Blue); + } + else + writer.Append(' ', IdOffset); + + } + internal readonly void Append(NameId name) + { + writer.Append(' ', Math.Max(0, IdOffset - 2 - name.Name.Length)).Append('%', ConsoleColor.Blue).Append(name.Name, ConsoleColor.Blue); + } + + public readonly void Append(T value) where T : Enum + { + var name = Enum.GetName(typeof(T), value); + writer.Append(' ').Append(name); + } + public readonly void Append(IdRef id, bool ignoreName = false) + { + + if (UseNames && !ignoreName && nameTable.TryGetValue(id, out var name)) + writer.Append(" %", ConsoleColor.DarkYellow).Append(name.Name, ConsoleColor.DarkYellow); + else + writer.Append(" %", ConsoleColor.DarkYellow).Append(id.Value, ConsoleColor.DarkYellow); + } + public readonly void Append(IdResultType id) + { + if (UseNames && nameTable.TryGetValue(id, out var name)) + writer.Append(" %", ConsoleColor.DarkYellow).Append(name.Name, ConsoleColor.DarkYellow); + else + writer.Append(" %", ConsoleColor.DarkYellow).Append(id.Value, ConsoleColor.DarkYellow); + } + public readonly void AppendInt(int v) + { + writer.Append(' ').Append(v, ConsoleColor.Red); + } + public readonly void AppendConst(int typeId, Span words) + { + writer.Append(' '); + foreach (var e in buffer) + { + if (e.ResultId is int rid && rid == typeId) + { + if (e.OpCode == SDSLOp.OpTypeInt) + { + writer.Append(words.Length == 1 ? words[0] : words[0] << 32 | words[1], ConsoleColor.Red); + return; + } + else if (e.OpCode == SDSLOp.OpTypeFloat) + { + writer.Append( + words.Length == 1 ? + BitConverter.Int32BitsToSingle(words[0]) + : BitConverter.Int64BitsToDouble(words[0] << 32 | words[1]), + + ConsoleColor.Red + ); + return; + } + } + } + } + public readonly void AppendLiteral(LiteralInteger v) + { + writer.Append(' ').Append(v.Words, ConsoleColor.Red); + } + + public readonly void AppendLiteral(LiteralFloat v) + { + if (v.WordCount == 1) + writer.Append(' ').Append(Convert.ToSingle(v.Words & 0xFFFF), ConsoleColor.Red); + else if (v.WordCount == 2) + writer.Append(' ').Append(Convert.ToDouble(v.Words), ConsoleColor.Red); + } + public readonly void AppendLiteral(LiteralString v, bool quoted = false) + { + if (!quoted) + writer.Append(' ').Append(v.Value); + else + writer.Append(' ').Append('"').Append(v.Value, ConsoleColor.Green).Append('"'); + } + public readonly void Append(PairLiteralIntegerIdRef v) + { + (int, int) value = v; + AppendInt(value.Item1); + Append(new IdRef(value.Item2)); + } + public readonly void Append(PairIdRefLiteralInteger v) + { + (int, int) value = v; + Append(new IdRef(value.Item1)); + AppendInt(value.Item2); + } + public readonly void Append(PairIdRefIdRef v) + { + (int, int) value = v; + Append(new IdRef(value.Item1)); + Append(new IdRef(value.Item2)); + } + public readonly void AppendLine() => writer.AppendLine(); + + public readonly void Append(in SpvOperand o, in RefInstruction instruction) + { + if (o.Kind == OperandKind.IdRef) + foreach (var e in o.Words) + Append(new IdRef(e), instruction.OpCode == SDSLOp.OpName); + else if (o.Kind == OperandKind.IdResultType) + foreach (var e in o.Words) + Append((IdResultType)e); + else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) + for (int i = 0; i < o.Words.Length; i += 2) + Append(new PairLiteralIntegerIdRef((o.Words[i], o.Words[i + 1]))); + else if (o.Kind == OperandKind.PairIdRefLiteralInteger) + for (int i = 0; i < o.Words.Length; i += 2) + Append(new PairIdRefLiteralInteger((o.Words[i], o.Words[i + 1]))); + else if (o.Kind == OperandKind.PairIdRefIdRef) + for (int i = 0; i < o.Words.Length; i += 2) + Append(new PairIdRefIdRef((o.Words[i], o.Words[i + 1]))); + else if ( + o.Kind == OperandKind.LiteralContextDependentNumber + && (instruction.OpCode == SDSLOp.OpConstant || instruction.OpCode == SDSLOp.OpSpecConstant) + && instruction.ResultType is int rtype + ) + { + AppendConst(rtype, o.Words); + } + else if (o.Kind == OperandKind.LiteralContextDependentNumber) + AppendLiteral(o.To()); + else if (o.Kind == OperandKind.PackedVectorFormat) + foreach (var e in o.Words) + Append((PackedVectorFormat)e); + else if (o.Kind == OperandKind.ImageOperands) + foreach (var e in o.Words) + Append((ImageOperandsMask)e); + else if (o.Kind == OperandKind.FPFastMathMode) + foreach (var e in o.Words) + Append((FPFastMathModeMask)e); + else if (o.Kind == OperandKind.SelectionControl) + foreach (var e in o.Words) + Append((SelectionControlMask)e); + else if (o.Kind == OperandKind.LoopControl) + foreach (var e in o.Words) + Append((LoopControlMask)e); + else if (o.Kind == OperandKind.FunctionControl) + foreach (var e in o.Words) + Append((FunctionControlMask)e); + else if (o.Kind == OperandKind.MemorySemantics) + foreach (var e in o.Words) + Append((MemorySemanticsMask)e); + else if (o.Kind == OperandKind.MemoryAccess) + foreach (var e in o.Words) + Append((MemoryAccessMask)e); + else if (o.Kind == OperandKind.KernelProfilingInfo) + foreach (var e in o.Words) + Append((KernelProfilingInfoMask)e); + else if (o.Kind == OperandKind.RayFlags) + foreach (var e in o.Words) + Append((RayFlagsMask)e); + else if (o.Kind == OperandKind.FragmentShadingRate) + foreach (var e in o.Words) + Append((FragmentShadingRateMask)e); + else if (o.Kind == OperandKind.SourceLanguage) + foreach (var e in o.Words) + Append((SourceLanguage)e); + else if (o.Kind == OperandKind.ExecutionModel) + foreach (var e in o.Words) + Append((ExecutionModel)e); + else if (o.Kind == OperandKind.AddressingModel) + foreach (var e in o.Words) + Append((AddressingModel)e); + else if (o.Kind == OperandKind.MemoryModel) + foreach (var e in o.Words) + Append((MemoryModel)e); + else if (o.Kind == OperandKind.ExecutionMode) + foreach (var e in o.Words) + Append((ExecutionMode)e); + else if (o.Kind == OperandKind.StorageClass) + foreach (var e in o.Words) + Append((StorageClass)e); + else if (o.Kind == OperandKind.Dim) + foreach (var e in o.Words) + Append((Dim)e); + else if (o.Kind == OperandKind.SamplerAddressingMode) + foreach (var e in o.Words) + Append((SamplerAddressingMode)e); + else if (o.Kind == OperandKind.SamplerFilterMode) + foreach (var e in o.Words) + Append((SamplerFilterMode)e); + else if (o.Kind == OperandKind.ImageFormat) + foreach (var e in o.Words) + Append((ImageFormat)e); + else if (o.Kind == OperandKind.ImageChannelOrder) + foreach (var e in o.Words) + Append((ImageChannelOrder)e); + else if (o.Kind == OperandKind.ImageChannelDataType) + foreach (var e in o.Words) + Append((ImageChannelDataType)e); + else if (o.Kind == OperandKind.FPRoundingMode) + foreach (var e in o.Words) + Append((FPRoundingMode)e); + else if (o.Kind == OperandKind.LinkageType) + foreach (var e in o.Words) + Append((LinkageType)e); + else if (o.Kind == OperandKind.AccessQualifier) + foreach (var e in o.Words) + Append((AccessQualifier)e); + else if (o.Kind == OperandKind.FunctionParameterAttribute) + foreach (var e in o.Words) + Append((FunctionParameterAttribute)e); + else if (o.Kind == OperandKind.Decoration) + foreach (var e in o.Words) + Append((Decoration)e); + else if (o.Kind == OperandKind.BuiltIn) + foreach (var e in o.Words) + Append((BuiltIn)e); + else if (o.Kind == OperandKind.Scope) + foreach (var e in o.Words) + Append((Scope)e); + else if (o.Kind == OperandKind.GroupOperation) + foreach (var e in o.Words) + Append((GroupOperation)e); + else if (o.Kind == OperandKind.KernelEnqueueFlags) + foreach (var e in o.Words) + Append((KernelEnqueueFlags)e); + else if (o.Kind == OperandKind.Capability) + foreach (var e in o.Words) + Append((Capability)e); + else if (o.Kind == OperandKind.RayQueryIntersection) + foreach (var e in o.Words) + Append((RayQueryIntersection)e); + else if (o.Kind == OperandKind.RayQueryCommittedIntersectionType) + foreach (var e in o.Words) + Append((RayQueryCommittedIntersectionType)e); + else if (o.Kind == OperandKind.RayQueryCandidateIntersectionType) + foreach (var e in o.Words) + Append((RayQueryCandidateIntersectionType)e); + else if (o.Kind == OperandKind.IdMemorySemantics) + foreach (var e in o.Words) + AppendInt((IdMemorySemantics)e); + else if (o.Kind == OperandKind.IdScope) + foreach (var e in o.Words) + AppendInt((IdScope)e); + else if (o.Kind == OperandKind.IdRef) + foreach (var e in o.Words) + Append((IdRef)e); + else if (o.Kind == OperandKind.LiteralInteger) + foreach (var e in o.Words) + AppendInt(e); + else if (o.Kind == OperandKind.LiteralString) + AppendLiteral(new LiteralString(o.Words), quoted: true); + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs new file mode 100644 index 0000000000..b79854ced7 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs @@ -0,0 +1,58 @@ +using System.Text; + +namespace Stride.Shaders.Spirv.Tools; + + + +public struct DisWriter() +{ + public bool WriteToConsole { get; set; } + readonly StringBuilder builder = new(); + + public readonly DisWriter Append(char value, int repeatCount, ConsoleColor? color = null) + { + builder.Append(value, repeatCount); + if(WriteToConsole) + { + if(color is ConsoleColor c) + Console.ForegroundColor = c; + Console.Write(new string(value, repeatCount)); + Console.ResetColor(); + } + return this; + } + public readonly DisWriter Append(T value, ConsoleColor? color = null) + { + builder.Append(value); + if(WriteToConsole) + { + if(color is ConsoleColor c) + Console.ForegroundColor = c; + Console.Write(value); + Console.ResetColor(); + } + return this; + } + public readonly DisWriter AppendLine() + { + builder.AppendLine(); + if(WriteToConsole) + Console.WriteLine(); + return this; + } + public readonly DisWriter AppendLine(string machin, ConsoleColor? color = null) + { + builder.AppendLine(machin); + if(WriteToConsole) + { + if(color is ConsoleColor c) + Console.ForegroundColor = c; + Console.WriteLine(machin); + Console.ResetColor(); + } + return this; + } + + public readonly void Clear() => builder.Clear(); + public readonly override string ToString() => builder.ToString(); +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs new file mode 100644 index 0000000000..0345c346a2 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -0,0 +1,147 @@ +using System.Text; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core; +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Tools; + + +internal record struct NameId(string Name); + +public partial struct SpirvDis + where TBuffer : ISpirvBuffer + +{ + public readonly static int MAX_OFFSET = 16; + TBuffer buffer; + DisWriter writer = new(); + int IdOffset { get; init; } + bool UseNames { get; init; } + + SortedList nameTable = []; + + public SpirvDis(TBuffer buff, bool useNames = false) + { + buffer = buff; + writer = new(); + UseNames = useNames; + IdOffset = 9; + if (!useNames) + { + var bound = buff.Header.Bound; + IdOffset = 3; + while (bound > 0) + { + bound /= 10; + IdOffset += 1; + } + } + else + { + var maxName = 0; + foreach (var i in buffer) + { + if ( + (i.OpCode == SDSLOp.OpName || i.OpCode == SDSLOp.OpMemberName) + && i.TryGetOperand("name", out LiteralString? name) + && name is not null + ) + { + maxName = maxName > name.Value.Value.Length ? maxName : name.Value.Value.Length; + } + } + IdOffset += maxName; + } + IdOffset = Math.Min(IdOffset, MAX_OFFSET); + } + + + public string Disassemble(bool writeToConsole = false) + { + writer = writer with { WriteToConsole = writeToConsole }; + writer.Clear(); + + if (buffer.HasHeader) + { + var header = buffer.Header; + writer + .AppendLine("; SPIR-V") + .AppendLine($"; Version: {header.Version}") + .AppendLine($"; Generator: {header.GeneratorMagicNumber}") + .AppendLine($"; Bound: {header.Bound}") + .AppendLine($"; Schema: {header.Schema}"); + } + + foreach (var e in buffer) + { + CheckNameTable(e); + + if (UseNames && e.ResultId is int id && nameTable.TryGetValue(id, out var nid)) + Append(nid); + else + Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); + + writer.Append(' '); + if (e.ResultId is int) + writer.Append('='); + + AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); + foreach (var o in e) + Append(o, e); + + AppendLine(); + } + return writer.ToString(); + } + + // TODO : add other names + public readonly void CheckNameTable(RefInstruction instruction) + { + if ( + UseNames + && (instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) + && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t + && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n + ) + { + nameTable[t] = new(n.Value); + } + else if (instruction.OpCode == SDSLOp.OpTypeVoid) + nameTable[instruction.ResultId!.Value] = new("void"); + else if (instruction.OpCode == SDSLOp.OpTypeBool) + nameTable[instruction.ResultId!.Value] = new("bool"); + else if (instruction.OpCode == SDSLOp.OpTypeInt) + { + var type = instruction.Operands[1..] switch + { + [8, 0] => "byte", + [16, 0] => "ushort", + [32, 0] => "uint", + [64, 0] => "ulong", + [8, 1] => "sbyte", + [16, 1] => "short", + [32, 1] => "int", + [64, 1] => "long", + _ => "int" + }; + nameTable[instruction.ResultId!.Value] = new(type); + } + else if (instruction.OpCode == SDSLOp.OpTypeFloat) + { + var size = instruction.Operands[1]; + nameTable[instruction.ResultId!.Value] = new(size == 16 ? "half" : size == 64 ? "double" : "float"); + } + else if (instruction.OpCode == SDSLOp.OpTypeVector) + { + nameTable[instruction.ResultId!.Value] = new(nameTable[instruction.Operands[1]].Name + instruction.Operands[2]); + } + + + } + + + public readonly override string ToString() + { + return writer.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/Validator.cs b/src/Stride.Shaders/Spirv/Tools/Validator.cs new file mode 100644 index 0000000000..60ba34aafb --- /dev/null +++ b/src/Stride.Shaders/Spirv/Tools/Validator.cs @@ -0,0 +1,8 @@ +namespace Stride.Shaders.Spirv.Tools; + + + +public struct SpirvVal +{ + // public List Passes = []; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md b/src/Stride.Shaders/Spirv/thinking.md similarity index 100% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv/thinking.md rename to src/Stride.Shaders/Spirv/thinking.md diff --git a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj b/src/Stride.Shaders/Stride.Shaders.csproj similarity index 72% rename from src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj rename to src/Stride.Shaders/Stride.Shaders.csproj index c748a98e28..2cdce5bbd3 100644 --- a/src/Stride.Shaders.Spirv/Stride.Shaders.Spirv.Experiments/Stride.Shaders.Spirv.Experiments.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -1,11 +1,11 @@ - + + - Exe net9.0 enable enable diff --git a/submodules/SpirvHeaders b/submodules/SpirvHeaders index a62b032007..3f17b2af67 160000 --- a/submodules/SpirvHeaders +++ b/submodules/SpirvHeaders @@ -1 +1 @@ -Subproject commit a62b032007b2e7a69f24a195cbfbd0cf22d31bb0 +Subproject commit 3f17b2af6784bfa2c5aa5dbb8e0e74a607dd8b3b diff --git a/submodules/SpirvRegistry b/submodules/SpirvRegistry new file mode 160000 index 0000000000..a74197a3f0 --- /dev/null +++ b/submodules/SpirvRegistry @@ -0,0 +1 @@ +Subproject commit a74197a3f0d5400764ce3bec2880f06e27b7b5d3 From f9dd4abe6ea27b243032c405e403403874421040 Mon Sep 17 00:00:00 2001 From: Youness KAFIA <32330908+ykafia@users.noreply.github.com> Date: Wed, 26 Mar 2025 15:08:24 +0100 Subject: [PATCH 0375/1182] correction for compiler (#20) Co-authored-by: KAFIA Youness --- src/Stride.Shaders.Compilers/Direct3D/DXC.cs | 2 +- src/Stride.Shaders.Compilers/Direct3D/FXC.cs | 2 +- src/Stride.Shaders.Compilers/ICompiler.cs | 2 +- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 15 +++++++++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 1 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 3 +++ src/Stride.Shaders/Spirv/Building/Builder.Flow.cs | 2 +- .../Spirv/Building/Builder.Functions.cs | 3 ++- src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- src/Stride.Shaders/Spirv/Building/CompilerUnit.cs | 8 +++++++- src/Stride.Shaders/Spirv/Building/Context.cs | 15 +++++++++++++-- 11 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/Stride.Shaders.Compilers/Direct3D/DXC.cs b/src/Stride.Shaders.Compilers/Direct3D/DXC.cs index d5e557ff46..69faa30adc 100644 --- a/src/Stride.Shaders.Compilers/Direct3D/DXC.cs +++ b/src/Stride.Shaders.Compilers/Direct3D/DXC.cs @@ -43,7 +43,7 @@ float4 PSMain(PSInput input) : SV_TARGET static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); static readonly DXC dxc = DXC.GetApi(); - public bool Compile(string code, out Memory compiled) + public bool Compile(string code, out byte[] compiled) { throw new NotImplementedException(); // var content = Encoding.ASCII.GetBytes(Code); diff --git a/src/Stride.Shaders.Compilers/Direct3D/FXC.cs b/src/Stride.Shaders.Compilers/Direct3D/FXC.cs index 151311f23b..eeec9260a1 100644 --- a/src/Stride.Shaders.Compilers/Direct3D/FXC.cs +++ b/src/Stride.Shaders.Compilers/Direct3D/FXC.cs @@ -11,7 +11,7 @@ public record struct FXCompiler() : ICompiler { static D3DCompiler d3d = D3DCompiler.GetApi(); - public bool Compile(string code, out Memory compiled) + public bool Compile(string code, out byte[] compiled) { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders.Compilers/ICompiler.cs b/src/Stride.Shaders.Compilers/ICompiler.cs index 7ff14fb6f2..b5cc9710ba 100644 --- a/src/Stride.Shaders.Compilers/ICompiler.cs +++ b/src/Stride.Shaders.Compilers/ICompiler.cs @@ -3,5 +3,5 @@ namespace Stride.Shaders.Compilers; public interface ICompiler { - bool Compile(string code, out Memory compiled); + bool Compile(string code, out byte[] compiled); } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 766a50e7df..6219264c29 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -5,12 +5,13 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Core.Buffers; +using System.Runtime.InteropServices; namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC() : ICompiler { - public readonly bool Compile(string code, out Memory compiled) + public readonly bool Compile(string code, out byte[] compiled) { var parsed = SDSLParser.Parse(code); if(parsed.AST is ShaderFile sf) @@ -21,14 +22,20 @@ public readonly bool Compile(string code, out Memory compiled) if(table.Errors.Count > 0) throw new Exception("Some parse errors"); - var compiler = new CompilerUnit(); + using var compiler = new CompilerUnit(); shader.Compile(compiler, table); compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); - var dis = new SpirvDis(merged); + var dis = new SpirvDis(merged, true); dis.Disassemble(true); + compiled = MemoryMarshal.AsBytes(merged.Span).ToArray(); + return true; + } + else + { + compiled = []; + return false; } - throw new NotImplementedException(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4a67895c1e..688ff7af05 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -71,6 +71,7 @@ public override void ProcessSymbol(SymbolTable table) public void Compile(CompilerUnit compiler, SymbolTable table) { + compiler.Context.PutMixinName(Name); foreach(var method in Elements.OfType()) method.Compile(table, this, compiler); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index da061f4d05..40e33e98fa 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -175,8 +175,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler foreach (var p in Parameters) builder.AddFunctionParameter(context, p.Name, p.Type); if(Body is BlockStatement body) + { + builder.CreateBlock(context); foreach(var s in body) s.Compile(table, shader, compiler); + } } else throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 51cb90284a..d618835662 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -10,7 +10,7 @@ public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { var i = Buffer.InsertOpLabel(Position, context.Bound++); Position += i.WordCount; - Position += Buffer.InsertOpUnreachable(Position).WordCount; + Buffer.InsertOpUnreachable(Position); var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index b3e4e9b420..3287fb9493 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -12,9 +12,10 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT foreach(var t in ftype.ParameterTypes) context.GetOrRegister(t); var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); + Position += func.WordCount; context.AddName(func, name); var result = new SpirvFunction(func.ResultId!.Value, name, ftype); - Buffer.AddOpFunctionEnd(); + Buffer.InsertOpFunctionEnd(Position); CurrentFunction = result; return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 3b8a3305b2..477981d71e 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -12,7 +12,7 @@ public partial class SpirvBuilder() : IDisposable public SpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; private set; } public SpirvBlock? CurrentBlock { get; private set; } - public int Position { get; private set; } + public int Position { get; private set; } = 5; public void SetPositionTo(TBlock block, bool beggining = false) where TBlock : IInstructionBlock diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 6fb3ae2065..b3a439abeb 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -6,7 +6,7 @@ namespace Stride.Shaders.Spirv.Building; public abstract class CompilerArgument; -public class CompilerUnit +public class CompilerUnit : IDisposable { public SpirvModule Module { get; } public SpirvContext Context { get; } @@ -27,4 +27,10 @@ public void Deconstruct(out SpirvBuilder builder, out SpirvContext context, out context = Context; module = Module; } + + public void Dispose() + { + Builder.Dispose(); + Context.Dispose(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 973d519e94..5ef5a6bb52 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -12,12 +12,23 @@ namespace Stride.Shaders.Spirv.Building; public class SpirvContext(SpirvModule module) : IDisposable { public int Bound { get; internal set; } = 1; + public string? Name { get; private set; } public SpirvModule Module { get; } = module; public SortedList Variables { get; } = []; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public SpirvBuffer Buffer { get; set; } = new(); + public void PutMixinName(string name) + { + if (Name is null) + { + Name = name; + Buffer.InsertOpSDSLMixinName(5, name); + } + else throw new NotImplementedException(); + } + public void AddName(IdRef target, string name) => Buffer.AddOpName(target, name); @@ -43,7 +54,7 @@ public IdRef AddConstant(TScalar value) _ => throw new NotImplementedException() }; } - + public void AddGlobalVariable(Symbol variable) { throw new NotImplementedException(); @@ -95,7 +106,7 @@ public void SetEntryPoint(ExecutionModel model, IdRef function, string name, Rea public IdRef GetOrRegister(SymbolType? type) { - if(type is null) + if (type is null) throw new ArgumentException($"Type is null"); if (Types.TryGetValue(type, out var res)) return res; From 71342779a5aabab1b6233300b86202f7e28b8f6b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 09:33:56 +0900 Subject: [PATCH 0376/1182] Make sure RootSymbols is not being recreated every time. --- src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index b72989d335..e39b0bc340 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -11,7 +11,7 @@ public partial class SymbolTable : ISymbolProvider { public Dictionary DeclaredTypes { get; } = []; public SymbolFrame CurrentFrame => CurrentFunctionSymbols[^1]; - public RootSymbolFrame RootSymbols => new(); + public RootSymbolFrame RootSymbols { get; } = new(); public SortedList> FunctionSymbols { get; } = []; public List Errors { get; } = []; From 5631a1b4187cc6f26239f35ea8f4c9a0d11881a9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 15:06:35 +0900 Subject: [PATCH 0377/1182] Added OpSDSLDecorateSemantic --- .../Extensions/spirv.sdsl.grammar-ext.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json index 4cba4b6793..2f3b11e90e 100644 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -1,5 +1,19 @@ { "instructions": [ + { + "opname": "OpSDSLDecorateSemantic", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "'Target'" + }, + { + "kind": "LiteralString", + "name": "semantic" + } + ] + }, { "opname": "OpSDSLMixinName", "class": "Miscellaneous", From a2ccdba6eb4c664f18721459fa49d7959727b027 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 15:06:59 +0900 Subject: [PATCH 0378/1182] Added missing StringAssignOperatorExtensions.ToAssignOperator case for = --- src/Stride.Shaders/Core/AssignOperators.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Stride.Shaders/Core/AssignOperators.cs b/src/Stride.Shaders/Core/AssignOperators.cs index ab76548969..993a2647c8 100644 --- a/src/Stride.Shaders/Core/AssignOperators.cs +++ b/src/Stride.Shaders/Core/AssignOperators.cs @@ -23,6 +23,7 @@ public static AssignOperator ToAssignOperator(this ReadOnlySpan s) { return s switch { + "=" => AssignOperator.Simple, "+=" => AssignOperator.Plus, "-=" => AssignOperator.Minus, "*=" => AssignOperator.Mul, From 871aa829e2aa0102fd6e02522432d3d9108f780e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 15:07:32 +0900 Subject: [PATCH 0379/1182] SymbolTable.Pop: more efficient implementation --- src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index e39b0bc340..54640a95bd 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -23,7 +23,7 @@ public partial class SymbolTable : ISymbolProvider public SymbolFrame? Pop() { var scope = CurrentFunctionSymbols?[^1]; - CurrentFunctionSymbols?.Remove(scope!); + CurrentFunctionSymbols?.RemoveAt(CurrentFunctionSymbols.Count - 1); return scope; } From f14ff5535bb2594bf785b954f3ae55ff7e79e0e8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 15:08:28 +0900 Subject: [PATCH 0380/1182] Added CppNet project to sln --- SDSL.sln | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SDSL.sln b/SDSL.sln index 3ee7007f06..d7379616de 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{BFCBF799-91A7-93D7-A6A1-233537FD7E63}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,6 +55,10 @@ Global {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.Build.0 = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -65,5 +71,6 @@ Global {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {BFCBF799-91A7-93D7-A6A1-233537FD7E63} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal From 2e4398402848763a067424897d6b7ad0e962d120 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 27 May 2025 15:22:22 +0200 Subject: [PATCH 0381/1182] generates instructions for every op codes --- .gitignore | 3 +- src/Stride.Shaders.Experiments/Program.cs | 10 +- .../Literals/LiteralFloat.cs | 18 ++- .../Literals/LiteralInteger.cs | 6 +- .../MemoryInstruction.cs | 2 + .../RefInstruction.cs | 37 ++++- .../Stride.Shaders.Spirv.Core.csproj | 21 ++- src/Stride.Shaders.Spirv.Generators/Data.cs | 9 +- .../EquatableArray.cs | 138 +++++++++++++++++ .../SPVGenerator.Info.cs | 2 +- .../SPVGenerator.Instructions.cs | 140 ++++++++++++++++++ .../SPVGenerator.Naming.cs | 132 +++++++++-------- .../SPVGenerator.cs | 16 +- .../Stride.Shaders.Spirv.Generators.csproj | 2 + 14 files changed, 454 insertions(+), 82 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Generators/EquatableArray.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs diff --git a/.gitignore b/.gitignore index 513eb1daa5..413dc24dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ obj/ /src/SDSLParserExample/Properties/launchSettings.json log*.txt *.vsix -*.fsx \ No newline at end of file +*.fsx +src/Stride.Shaders.Spirv.Core/Generated/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.SPVGenerator/Op*.Instruction.g.cs \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 693a03ff7d..d012d56a1c 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -3,7 +3,15 @@ using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; Examples.CompileSDSL(); // Examples.TryAllFiles(); -// Examples.CreateShader(); \ No newline at end of file +// Examples.CreateShader(); + +var buffer = new SpirvBuffer(32); + +var i = buffer.AddOpTypeFloat(0, 32, null); +var fl = i.UnsafeAs(); +Console.WriteLine(fl.Width); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs index 9e273b9f86..124872a70c 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Core.Parsing; using System.Drawing; using System.Numerics; +using System.Runtime.InteropServices; namespace Stride.Shaders.Spirv.Core; @@ -69,7 +70,7 @@ public readonly bool TryCast(out Half value) return false; } } - public readonly bool TryCast(out float value) + public readonly bool TryCast(out float value) { Span span = [ @@ -87,7 +88,7 @@ public readonly bool TryCast(out float value) return false; } } - public readonly bool TryCast(out double value) + public readonly bool TryCast(out double value) { if (size == 64) { @@ -124,9 +125,20 @@ public static LiteralFloat From(string value) } public readonly SpanOwner AsSpanOwner() { - Span span = WordCount == 1 ? [ (int)Words ] : [ (int)(Words >> 32), (int)(Words & 0xFFFFFFFF) ]; + Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); span.CopyTo(owner.Span); return owner; } + + public override string ToString() + { + return size switch + { + 16 => $"{BitConverter.UInt16BitsToHalf((ushort)(Words & 0xFFFF))}", + 32 => $"{BitConverter.Int32BitsToSingle((int)(Words & 0xFFFFFFFF))}", + 64 => $"{BitConverter.Int64BitsToDouble(Words)}", + _ => throw new NotImplementedException() + }; + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs index 2b5631007a..754793ee2a 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs @@ -63,7 +63,7 @@ public LiteralInteger(ulong value) public LiteralInteger(Span value) { - if(value.Length == 2) + if (value.Length == 2) { Size = sizeof(long) * 8; Words = value[0] << 32 | value[1]; @@ -111,11 +111,13 @@ public static LiteralInteger From(string value) public readonly SpanOwner AsSpanOwner() { - Span span = WordCount == 1 ? [ (int)Words ] : [ (int)(Words >> 32), (int)(Words & 0xFFFFFFFF) ]; + Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); span.CopyTo(owner.Span); return owner; } + + public override readonly string ToString() => $"{Words}"; } diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index aa80df328b..ee92dc3e21 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -39,6 +39,8 @@ public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Em public bool IsEmpty => Words.IsEmpty; public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Words.Span); + public readonly TWrapper UnsafeAs() where TWrapper : struct, IWrapperInstruction, allows ref struct + => RefInstruction.ParseRef(Words.Span).UnsafeAs(); public readonly T? GetOperand(string name) where T : struct, IFromSpirv => AsRef().GetOperand(name); diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index 711f5358fe..104ee32f74 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -1,3 +1,4 @@ +using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using Stride.Shaders.Spirv.Core.Buffers; @@ -7,6 +8,12 @@ namespace Stride.Shaders.Spirv.Core; +public interface IWrapperInstruction +{ + RefInstruction Inner { get; set; } +} + + /// /// A ref struct representation of an instruction in a buffer. /// @@ -56,6 +63,25 @@ public ref struct RefInstruction } return null; } + internal T? GetEnumOperand(string name) + where T : Enum + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + var curr = operandEnumerator.Current; + return Unsafe.As(ref curr.Words[0]); + } + } + } + return default; + } public bool TryGetOperand(string name, out T? operand) where T : struct, IFromSpirv @@ -161,7 +187,7 @@ public void OffsetIds(int offset) public readonly Instruction ToOwned(SpirvBuffer buffer) { - if(InstructionIndex == -1) throw new Exception("Instruction not found"); + if (InstructionIndex == -1) throw new Exception("Instruction not found"); return new(buffer, buffer.Memory[WordIndex..(WordIndex + WordCount)], InstructionIndex, WordIndex); } @@ -175,4 +201,13 @@ public override string ToString() } return builder.ToString(); } + + public TWrapper UnsafeAs() + where TWrapper : struct, IWrapperInstruction, allows ref struct + { + return new TWrapper() + { + Inner = this + }; + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 10f39ad242..5a52639b6b 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -12,7 +12,24 @@ - + - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index a9dde24d44..24c44bfc61 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -3,7 +3,7 @@ namespace Stride.Shaders.Spirv.Generators; -public struct OpKind +public record struct OpKind { [JsonPropertyName("kind")] public string Kind { get; set; } @@ -12,7 +12,7 @@ public struct OpKind } -public struct OperandData +public record struct OperandData { [JsonPropertyName("kind")] public string Kind { get; set; } @@ -20,9 +20,10 @@ public struct OperandData public string? Name { get; set; } [JsonPropertyName("quantifier")] public string? Quantifier { get; set; } + public string? Class { get; set; } } -public struct InstructionData +public record struct InstructionData { [JsonPropertyName("opname")] public string OpName { get; set; } @@ -31,7 +32,7 @@ public struct InstructionData [JsonPropertyName("opcode")] public int OpCode { get; set; } [JsonPropertyName("operands")] - public List Operands { get; set; } + public EquatableArray? Operands { get; set; } [JsonPropertyName("version")] public string Version { get; set; } } diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs new file mode 100644 index 0000000000..28e1ca5192 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs @@ -0,0 +1,138 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +using System.Collections; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Stride.Shaders.Spirv.Generators; + + + +public class EquatableArrayJsonConverter : JsonConverter> + where T : IEquatable +{ + public override EquatableArray Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var array = JsonSerializer.Deserialize(ref reader, options) ?? []; + return new EquatableArray([..array]); + } + + public override void Write(Utf8JsonWriter writer, EquatableArray value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(value.AsArray(), options); + } +} + +/// +/// An immutable, equatable array. This is equivalent to but with value equality support. +/// +/// The type of values in the array. +public readonly struct EquatableArray : IEquatable>, IEnumerable + where T : IEquatable +{ + /// + /// The underlying array. + /// + private readonly T[]? _array; + + /// + /// Initializes a new instance of the struct. + /// + /// The input array to wrap. + public EquatableArray(T[] array) + { + _array = array; + } + + /// + /// Gets the length of the array, or 0 if the array is null + /// + public int Count => _array?.Length ?? 0; + + /// + /// Checks whether two values are the same. + /// + /// The first value. + /// The second value. + /// Whether and are equal. + public static bool operator ==(EquatableArray left, EquatableArray right) + { + return left.Equals(right); + } + + /// + /// Checks whether two values are not the same. + /// + /// The first value. + /// The second value. + /// Whether and are not equal. + public static bool operator !=(EquatableArray left, EquatableArray right) + { + return !left.Equals(right); + } + + /// + public bool Equals(EquatableArray array) + { + return AsSpan().SequenceEqual(array.AsSpan()); + } + + /// + public override bool Equals(object? obj) + { + return obj is EquatableArray array && Equals(this, array); + } + + /// + public override int GetHashCode() + { + if (_array is not T[] array) + { + return 0; + } + + HashCode hashCode = default; + + foreach (T item in array) + { + hashCode.Add(item); + } + + return hashCode.ToHashCode(); + } + + /// + /// Returns a wrapping the current items. + /// + /// A wrapping the current items. + public ReadOnlySpan AsSpan() + { + return _array.AsSpan(); + } + + /// + /// Returns the underlying wrapped array. + /// + /// Returns the underlying array. + public T[]? AsArray() + { + return _array; + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)(_array ?? [])).GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return ((IEnumerable)(_array ?? [])).GetEnumerator(); + } + + public static implicit operator EquatableArray(List list) => new([.. list]); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index a25e129a44..2944bc6be8 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -88,7 +88,7 @@ public void GenerateInfo(InstructionData op, StringBuilder code) code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); } - else if (op.Operands is List operands) + else if (op.Operands is EquatableArray operands) { foreach (var operand in operands) { diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs new file mode 100644 index 0000000000..64218b122d --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -0,0 +1,140 @@ +using AngleSharp.Common; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; +using System.Text; +using System.Text.Json; + +namespace Stride.Shaders.Spirv.Generators; + + +public record struct SpirvInstructionData +{ + public string Name { get; } + public string OpCode { get; } + public string Category { get; } + public string Description { get; } + public EquatableArray Operands { get; } + public EquatableArray Returns { get; } + + public SpirvInstructionData(string name, string opcode, string category, string description, string[] operands, string[] returns) + { + Name = name; + OpCode = opcode; + Category = category; + Description = description; + Operands = new(operands); + Returns = new(returns); + } +} + + +public partial class SPVGenerator : IIncrementalGenerator +{ + public void GenerateStructs(IncrementalGeneratorInitializationContext context) + { + IncrementalValuesProvider instructionsData = + context.AdditionalTextsProvider + .Where(file => Path.GetFileName(file.Path) == "spirv.core.grammar.json") + .Select((file, _) => file.GetText()?.ToString()) + .Where(text => text is not null) + .Select((text, _) => + { + var result = JsonSerializer.Deserialize(text!, options); + if (result is SpirvGrammar grammar) + { + var list = new List(24); + var dict = grammar.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); + if (grammar.Instructions is List instructions) + { + for (int i = 0; i < instructions.Count; i++) + { + list.Clear(); + if (instructions[i].Operands is EquatableArray operands) + { + foreach (var op in operands) + list.Add(op with { Class = dict[op.Kind] }); + instructions[i] = instructions[i] with { Operands = list }; + } + } + } + } + return result; + }) + .SelectMany((grammar, _) => grammar!.Instructions ?? []) + .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); + + + context.RegisterImplementationSourceOutput(instructionsData, + static (spc, source) => Execute(source, spc)); + + } + + public static void Execute(InstructionData instruction, SourceProductionContext spc) + { + StringBuilder builder = new(); + builder + .AppendLine("using static Spv.Specification;") + .AppendLine() + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine() + .AppendLine() + .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") + .AppendLine("{") + .AppendLine("public RefInstruction Inner { get; set; }"); + if (instruction.Operands != null) + { + foreach (var operand in instruction.Operands) + { + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else + { + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) + { + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } + + } + fieldName = nameBuilder.ToString(); + } + if (operand.Kind == "LiteralContextDependentNumber") + continue; + else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); + else if (operand.Class == "BitEnum") + builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); + else if (operand.Class == "ValueEnum") + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); + else + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); + } + } + + + builder + .AppendLine() + .AppendLine($"public Ref{instruction.OpName}(RefInstruction instruction) => Inner = instruction;") + .AppendLine($"public Ref{instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);"); + + + builder.AppendLine("}"); + spc.AddSource( + $"{instruction.OpName}.Instruction.g.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs index 14cc5072be..af49dfb962 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs @@ -31,40 +31,42 @@ public partial class SPVGenerator public List ConvertOperandsToParameters(InstructionData op) { var opname = op.OpName; - var operands = op.Operands; List parameters = []; - foreach (var e in operands) + if (op.Operands is EquatableArray operands) { - var kind = e.Kind; - var realKind = ConvertKind(kind!); - if (e.Quantifier is not null) + foreach (var e in operands) { - if (e.Name is string name) + var kind = e.Kind; + var realKind = ConvertKind(kind!); + if (e.Quantifier is not null) { - if (e.Quantifier == "?") - parameters.AddUnique(realKind + "? " + ConvertOperandName(name)); - else if (e.Quantifier == "*") - parameters.AddUnique("Span<" + realKind + "> values"); + if (e.Name is string name) + { + if (e.Quantifier == "?") + parameters.AddUnique(realKind + "? " + ConvertOperandName(name)); + else if (e.Quantifier == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } + else + { + if (e.Quantifier == "?") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind!)); + else if (e.Quantifier == "*") + parameters.AddUnique("Span<" + realKind + "> values"); + } } else { - if (e.Quantifier == "?") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind!)); - else if (e.Quantifier == "*") - parameters.AddUnique("Span<" + realKind + "> values"); + if (e.Name is not null) + parameters.AddUnique(realKind + " " + ConvertOperandName(e.Name)); + else if (kind == "IdResult" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else if (kind == "IdResultType" && opname == "OpExtInst") + parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); + else + parameters.AddUnique(realKind + " " + ConvertKindToName(kind!)); } } - else - { - if (e.Name is not null) - parameters.AddUnique(realKind + " " + ConvertOperandName(e.Name)); - else if (kind == "IdResult" && opname == "OpExtInst") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); - else if (kind == "IdResultType" && opname == "OpExtInst") - parameters.AddUnique(realKind + "? " + ConvertKindToName(kind)); - else - parameters.AddUnique(realKind + " " + ConvertKindToName(kind!)); - } } if (parameters.Any(x => x.Contains("resultType")) && parameters.Any(x => x.Contains("resultId"))) { @@ -80,36 +82,37 @@ public List ConvertOperandsToParameterNames(InstructionData op) { var opname = op.OpName; var operands = op.Operands; - List parameters = new(op.Operands.Count); - foreach (var e in operands) - { - var kind = e.Kind; - var realKind = ConvertKind(kind!); - if (e.Quantifier is string quant) + List parameters = new(op.Operands?.Count ?? 0); + if (operands is not null) + foreach (var e in operands) { - if (e.Name is string name) + var kind = e.Kind; + var realKind = ConvertKind(kind!); + if (e.Quantifier is string quant) { - if (quant == "?") - parameters.AddUnique(ConvertOperandName(name)); - else if (quant == "*") - parameters.AddUnique("values"); + if (e.Name is string name) + { + if (quant == "?") + parameters.AddUnique(ConvertOperandName(name)); + else if (quant == "*") + parameters.AddUnique("values"); + } + else + { + if (quant == "?") + parameters.AddUnique(ConvertKindToName(kind!)); + else if (quant == "*") + parameters.AddUnique("values"); + } } else { - if (quant == "?") - parameters.AddUnique(ConvertKindToName(kind!)); - else if (quant == "*") - parameters.AddUnique("values"); + if (e.Name is string name) + parameters.AddUnique(ConvertOperandName(name)); + else + parameters.AddUnique(ConvertKindToName(kind)); } } - else - { - if (e.Name is string name) - parameters.AddUnique(ConvertOperandName(name)); - else - parameters.AddUnique(ConvertKindToName(kind)); - } - } return parameters; } @@ -122,31 +125,35 @@ public string ConvertKind(string kind) ("LiteralInteger", _) => "LiteralInteger", ("LiteralFloat", _) => "LiteralFloat", ("LiteralString", _) => "LiteralString", - ( _ , "BitEnum") => kind + "Mask", + (_, "BitEnum") => kind + "Mask", ("LiteralExtInstInteger", _) => "LiteralInteger", ("LiteralSpecConstantOpInteger", _) => "Op", _ => kind }; } - public static string ConvertKindToName(string kind) + public static string ConvertKindToName(string kind, bool lower = true) { - return kind switch + return (kind, lower) switch { - "IdRef" => "id", - "IdResult" => "resultId", - "IdResultType" => "resultType", - _ => kind.ToLower() + ("IdRef", true) => "id", + ("IdResult", true) => "resultId", + ("IdResultType", true) => "resultType", + ("IdRef", false) => "Id", + ("IdResult", false) => "ResultId", + ("IdResultType", false) => "ResultType", + (_, true) => kind.ToLower(), + (_, false) => kind }; } - public static string ConvertOperandName(string input, string? quant = null) + public static string ConvertOperandName(string input, string? quant = null, bool lower = true) { if (string.IsNullOrEmpty(input)) { return string.Empty; } - var result = ""; + var result = new StringBuilder(); bool firstLetterHit = false; for (int i = 0; i < input.Length; i++) { @@ -156,14 +163,17 @@ public static string ConvertOperandName(string input, string? quant = null) if (!firstLetterHit) { firstLetterHit = true; - result += char.ToLowerInvariant(input[i]); + if (lower) + result.Append(char.ToLowerInvariant(input[i])); + else + result.Append(input[i]); } else - result += input[i]; + result.Append(input[i]); } } - return (result, quant) switch + return (result.ToString(), quant) switch { ("event", _) => "eventId", ("string", _) => "value", @@ -182,7 +192,7 @@ public static string ConvertOperandName(string input, string? quant = null) ("ImageFormat", _) => "", ("ExecutionMode", _) => "", ("ExecutionModel", _) => "", - _ => result + (string v, _) => v }; } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 99ccf16bf6..254c67b3b3 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -23,6 +23,8 @@ public partial class SPVGenerator : IIncrementalGenerator Dictionary operandKinds = []; + static readonly JsonSerializerOptions options = new(); + public void Initialize(IncrementalGeneratorInitializationContext context) { // #if DEBUG @@ -48,13 +50,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context) string resourceGlslRegistryName = assembly.GetManifestResourceNames() .Single(str => str.EndsWith("GLSL.std.450.html")); + + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) + options.Converters.Add(new EquatableArrayJsonConverter()); + spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd(), options); + spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd(), options); + spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd(), options); - - - spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd()); - spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd()); - spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd()); + GenerateStructs(context); var config = Configuration.Default.WithDefaultLoader(); var htmlContext = BrowsingContext.New(config); @@ -201,7 +205,7 @@ public void CreateOperation(InstructionData op, StringBuilder code) .AppendLine("}"); } - else if (op.Operands is not null && op.Operands.Count > 0) + else if (op.Operands is EquatableArray operands && operands.Count > 0) { var parameters = ConvertOperandsToParameters(op); var parameterNames = ConvertOperandsToParameterNames(op); diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 05fefad5fa..7759f47219 100644 --- a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -14,6 +14,7 @@ + @@ -42,6 +43,7 @@ + From 48d68b3002db9804b971e5c5487e38ab7667f271 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 17 Apr 2025 15:08:17 +0900 Subject: [PATCH 0382/1182] Variable declarations and streams (WIP) --- src/Stride.Shaders/Core/SymbolTypes.cs | 2 ++ .../Parsing/Analysis/SymbolTable.cs | 1 + .../Parsing/SDSL/AST/Expression.cs | 6 +++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 25 +++++++++++++++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 12 +++++++++ .../Parsing/SDSL/AST/Statements.cs | 7 ++++++ 6 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 4ce3c28d49..79cb6a558a 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -131,6 +131,8 @@ public override string ToString() } } +public sealed record StreamsSymbol : SymbolType; + public sealed record ConstantBufferSymbol(string Name, List Symbols) : SymbolType; public sealed record ParamsSymbol(string Name, List Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List Symbols) : SymbolType; diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 54640a95bd..fbadade3e1 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -12,6 +12,7 @@ public partial class SymbolTable : ISymbolProvider public Dictionary DeclaredTypes { get; } = []; public SymbolFrame CurrentFrame => CurrentFunctionSymbols[^1]; public RootSymbolFrame RootSymbols { get; } = new(); + public SymbolFrame Streams { get; } = new(); public SortedList> FunctionSymbols { get; } = []; public List Errors { get; } = []; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 9dcbcd1215..f6ca10dd8a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -102,9 +102,9 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) { - - if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar && entrypoint is not null) + if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { + table.CurrentFunctionSymbols.Add(table.Streams); streamVar.ProcessSymbol(table, entrypoint, io); Type = streamVar.Type; // If has more, dive into the type definition @@ -124,6 +124,8 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); } } + + table.Pop(); table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); } else diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 688ff7af05..bd2055ffe8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -52,15 +52,28 @@ public override void ProcessSymbol(SymbolTable table) _ => Storage.None } ); - table.RootSymbols.Add - ( - sid, - new(sid, svar.Type) - ); + var symbol = new Symbol(sid, svar.Type); + if (sid.Storage == Storage.Stream) + { + table.Streams.Add(sid, symbol); + } + else + { + table.RootSymbols.Add(sid, symbol); + } table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } } + var streams = + new SymbolID + ( + "streams", + SymbolKind.Variable, + Storage.None + ); + table.RootSymbols.Add(streams, new(streams, new StreamsSymbol())); + foreach (var member in Elements) { if (member is not ShaderMember) @@ -72,6 +85,8 @@ public override void ProcessSymbol(SymbolTable table) public void Compile(CompilerUnit compiler, SymbolTable table) { compiler.Context.PutMixinName(Name); + foreach(var member in Elements.OfType()) + member.Compile(table, this, compiler); foreach(var method in Elements.OfType()) method.Compile(table, this, compiler); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 40e33e98fa..b5dea6c89e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -77,6 +78,17 @@ public sealed class ShaderMember( public StorageClass StorageClass { get; set; } = storageClass; public InterpolationModifier Interpolation { get; set; } = interpolation; + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, _) = compiler; + var registeredType = context.GetOrRegister(Type); + var variable = context.Bound++; + context.Buffer.AddOpVariable(variable, registeredType, Spv.Specification.StorageClass.Function, null); + if (Semantic != null) + context.Buffer.AddOpSDSLDecorateSemantic(variable, Semantic.Name); + context.AddName(variable, Name); + } + public override string ToString() { if (Attributes != null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 02beb54451..d2bf648f29 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -175,6 +175,13 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method, Entry } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + var (builder, _, _) = compiler; + foreach (var variable in Variables) + { + var target = variable.Variable.Compile(table, shader, compiler); + var source = variable.Value.Compile(table, shader, compiler); + builder.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); + } throw new NotImplementedException(); } public override string ToString() From d0bf4bb63dc2e4cb58d768aacfbe5c09841e3dc8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 May 2025 13:04:02 +0900 Subject: [PATCH 0383/1182] Further progress on variable declaration, member accessor and variable assignment --- assets/SDSL/TestStruct.sdsl | 15 ++++++ src/Stride.Shaders.Experiments/Examples.cs | 4 +- src/Stride.Shaders/Core/SymbolTypes.cs | 32 ++++++++++- .../Parsing/SDSL/AST/Expression.cs | 53 ++++++++++++------- .../Parsing/SDSL/AST/ShaderElements.cs | 10 ++-- .../Parsing/SDSL/AST/Statements.cs | 26 ++++++--- .../Parsing/SDSL/AST/SymbolTypeProcess.cs | 3 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 13 ++++- 9 files changed, 122 insertions(+), 36 deletions(-) create mode 100644 assets/SDSL/TestStruct.sdsl diff --git a/assets/SDSL/TestStruct.sdsl b/assets/SDSL/TestStruct.sdsl new file mode 100644 index 0000000000..38c5445f4b --- /dev/null +++ b/assets/SDSL/TestStruct.sdsl @@ -0,0 +1,15 @@ +namespace Stride.Shaders.Tests; + +shader TestStruct +{ + struct A + { + int B; + }; + + void VSMain() + { + A a; + a.B = 3; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 68eb066dbc..b249cc4f6e 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -142,7 +142,7 @@ public static void TryAllFiles() } else { - // Console.WriteLine(f); + Console.WriteLine(f); } } Console.ForegroundColor = ConsoleColor.White; @@ -212,7 +212,7 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) public static void CompileSDSL() { - var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestBasic.sdsl"); + var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestStruct.sdsl"); var sdslc = new SDSLC(); sdslc.Compile(text, out var bytecode); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 79cb6a558a..bea68ab331 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Text; namespace Stride.Shaders.Core; @@ -65,9 +66,36 @@ public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"{BaseType}[{Size}]"; } -public sealed record StructType(string Name, SortedList Fields) : SymbolType() +public sealed record StructType(string Name, List<(string Name, SymbolType Type)> Fields) : SymbolType() { - public override string ToString() => $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Value} {x.Key}"))}}}"; + public override string ToString() => $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Type} {x.Name}"))}}}"; + + public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType type) + { + foreach (var field in Fields) + { + if (field.Name == name) + { + type = field.Type; + return true; + } + } + + type = null; + return false; + } + public int TryGetFieldIndex(string name) + { + for (var index = 0; index < Fields.Count; index++) + { + var field = Fields[index]; + if (field.Name == name) + return index; + } + + return -1; + } + } public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index f6ca10dd8a..ed18f3eb64 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -107,23 +107,8 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n table.CurrentFunctionSymbols.Add(table.Streams); streamVar.ProcessSymbol(table, entrypoint, io); Type = streamVar.Type; - // If has more, dive into the type definition - // First case none - if (Accessors.Count > 1) - { - foreach (var accessor in Accessors[1..]) - { - if (Type is not null && Type.TryAccess(accessor, out var type)) - { - Type = type; - accessor.Type = type; - } - else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); - - if(accessor is not Identifier) - accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); - } - } + + ProcessAccessors(); table.Pop(); table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); @@ -132,7 +117,12 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n { Source.ProcessSymbol(table, entrypoint, io ?? StreamIO.Output); Type = Source.Type; - foreach (var accessor in Accessors[1..]) + ProcessAccessors(); + } + + void ProcessAccessors() + { + foreach (var accessor in Accessors) { if (Type is not null && Type.TryAccess(accessor, out var type)) { @@ -147,7 +137,32 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, _) = compiler; + var source = Source.Compile(table, shader, compiler); + var variable = context.Bound++; + + if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) + throw new NotImplementedException(); + + var currentType = Source.Type; + Span indexes = stackalloc IdRef[Accessors.Count - 1]; + foreach (var accessor in Accessors) + { + if (currentType is StructType s && accessor is Identifier field) + { + var index = s.TryGetFieldIndex(field); + if (index == -1) + throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + } + else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + + currentType = accessor.Type; + } + + var resultType = context.GetOrRegister(Type); + var result = context.Buffer.InsertOpAccessChain(builder.Position, variable, resultType, source.Id, indexes); + builder.Position += result.WordCount; + return new(result, resultType); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 57459ab2b5..2becd50755 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -172,15 +172,19 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public override void ProcessSymbol(SymbolTable table) { - var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new StructType(TypeName.ToString() ?? "", [])); - table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); - table.RootSymbols.Add(new(TypeName.ToString() ?? "", SymbolKind.Struct), sym); + var fields = new List<(string Name, SymbolType Type)>(); foreach (var smem in Members) { smem.TypeName.ProcessSymbol(table); smem.Type = smem.TypeName.Type; table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); + + fields.Add((smem.Name, smem.Type)); } + + var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new StructType(TypeName.ToString() ?? "", fields)); + table.DeclaredTypes.TryAdd(TypeName.ToString(), sym.Type); + table.RootSymbols.Add(new(TypeName.ToString() ?? "", SymbolKind.Struct), sym); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index d2bf648f29..acc01cf897 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -150,13 +150,24 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method, Entry foreach (var d in Variables) { d.Value?.ProcessSymbol(table, entrypoint, io); - table.CurrentFrame.Add(new(d.Variable, SymbolKind.Variable), new(new(d.Variable, SymbolKind.Variable), Type)); + table.CurrentFrame.Add(new(d.Variable, SymbolKind.Variable, Storage.Function), new(new(d.Variable, SymbolKind.Variable), Type)); } } } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, _) = compiler; + var registeredType = context.GetOrRegister(new PointerType(Type!)); + foreach (var d in Variables) + { + var variable = context.Bound++; + var instruction = context.Buffer.InsertOpVariable(builder.Position, variable, registeredType, Spv.Specification.StorageClass.Function, null); + builder.Position += instruction.WordCount; + context.AddName(variable, d.Variable); + + if (builder.CurrentFunction is SpirvFunction f) + f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); + } } public override string ToString() { @@ -171,18 +182,21 @@ public class Assign(TextLocation info) : Statement(info) public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) { foreach (var variable in Variables) + { variable.Variable.ProcessSymbol(table, entrypoint, io); + variable.Value!.ProcessSymbol(table, entrypoint, io); + } } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, _, _) = compiler; + var (builder, context, _) = compiler; foreach (var variable in Variables) { var target = variable.Variable.Compile(table, shader, compiler); - var source = variable.Value.Compile(table, shader, compiler); - builder.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); + var source = variable.Value!.Compile(table, shader, compiler); + var instruction = context.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); + builder.Position += instruction.WordCount; } - throw new NotImplementedException(); } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs b/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs index d6ed8946b1..8650ccc92d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs @@ -28,10 +28,11 @@ symbol is ScalarType or VectorType } else if(symbol is StructType s && expression is Identifier field) { - if(s.Fields.TryGetValue(field, out var ft)) + if(s.TryGetFieldType(field, out var ft)) { type = ft; field.Type = ft; + return true; } else throw new NotImplementedException($"field {field} not found in type {s}"); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 477981d71e..f736cd79cb 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -12,7 +12,7 @@ public partial class SpirvBuilder() : IDisposable public SpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; private set; } public SpirvBlock? CurrentBlock { get; private set; } - public int Position { get; private set; } = 5; + public int Position { get; internal set; } = 5; public void SetPositionTo(TBlock block, bool beggining = false) where TBlock : IInstructionBlock diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 5ef5a6bb52..4ef800aa2e 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -138,6 +138,7 @@ public IdRef GetOrRegister(SymbolType? type) ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), StructType st => RegisterStruct(st), FunctionType f => RegisterFunctionType(f), + PointerType p => RegisterPointerType(p), // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") @@ -154,8 +155,8 @@ IdRef RegisterStruct(StructType structSymbol) int tmp = 0; foreach (var f in structSymbol.Fields) { - types[tmp] = GetOrRegister(f.Value); - AddMemberName(types[tmp], tmp, f.Key); + types[tmp] = GetOrRegister(f.Type); + AddMemberName(types[tmp], tmp, f.Name); } var result = Buffer.AddOpTypeStruct(Bound++, types); AddName(result, structSymbol.Name); @@ -173,5 +174,13 @@ IdRef RegisterFunctionType(FunctionType functionType) return result; } + IdRef RegisterPointerType(PointerType pointerType) + { + var baseType = GetOrRegister(pointerType.BaseType); + var result = Buffer.AddOpTypePointer(Bound++, Spv.Specification.StorageClass.Function, baseType); + AddName(result, pointerType.ToString()); + return result; + } + public void Dispose() => Buffer.Dispose(); } \ No newline at end of file From 4331a97bc27ca6654038c20848007afd0ff94d12 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 14 May 2025 11:21:33 +0200 Subject: [PATCH 0384/1182] Correction use of builder.Buffer.InsertX instead of context --- .../Parsing/OrderedEnumerator.cs | 3 ++- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 1 + src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs | 4 ++-- src/Stride.Shaders/Spirv/Building/Builder.cs | 5 +++++ src/Stride.Shaders/Spirv/Building/CompilerUnit.cs | 14 ++++++++++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 6 ++++++ src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 7 ++++++- 8 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 257f0fc5b7..8da66bfaeb 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -12,7 +12,8 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// -/// An enumerator where each instructions is sorted +/// An enumerator where each instructions is sorted +/// Instruction are grouped together in the InstructionInfo.Order file, and each groups are ordered based on the SPIR-V specification /// public ref struct OrderedEnumerator(ISpirvBuffer buffer) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index ed18f3eb64..049c075306 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -160,7 +160,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } var resultType = context.GetOrRegister(Type); - var result = context.Buffer.InsertOpAccessChain(builder.Position, variable, resultType, source.Id, indexes); + var result = builder.Buffer.InsertOpAccessChain(builder.Position, variable, resultType, source.Id, indexes); builder.Position += result.WordCount; return new(result, resultType); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b5dea6c89e..f29428148b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Parsing.SDSL.AST; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index acc01cf897..68b2e93b43 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -161,7 +161,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit foreach (var d in Variables) { var variable = context.Bound++; - var instruction = context.Buffer.InsertOpVariable(builder.Position, variable, registeredType, Spv.Specification.StorageClass.Function, null); + var instruction = builder.Buffer.InsertOpVariable(builder.Position, variable, registeredType, Spv.Specification.StorageClass.Function, null); builder.Position += instruction.WordCount; context.AddName(variable, d.Variable); @@ -194,7 +194,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { var target = variable.Variable.Compile(table, shader, compiler); var source = variable.Value!.Compile(table, shader, compiler); - var instruction = context.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); + var instruction = builder.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); builder.Position += instruction.WordCount; } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index f736cd79cb..1d93dc9ad1 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; namespace Stride.Shaders.Spirv.Building; @@ -63,4 +64,8 @@ public SpirvBuffer Build(SpirvContext context) } public void Dispose() => Buffer.Dispose(); + public override string ToString() + { + return new SpirvDis(Buffer).Disassemble(); + } } diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index b3a439abeb..839f39c30a 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -1,4 +1,7 @@ +using System.Text; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; namespace Stride.Shaders.Spirv.Building; @@ -33,4 +36,15 @@ public void Dispose() Builder.Dispose(); Context.Dispose(); } + + public override string ToString() + { + var builder = new StringBuilder(); + builder + .AppendLine("Context : ") + .AppendLine(new SpirvDis(Context.Buffer).Disassemble()) + .AppendLine("Functions : ") + .AppendLine(new SpirvDis(Builder.Buffer).Disassemble()); + return builder.ToString(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 4ef800aa2e..8070ed6849 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; using static Spv.Specification; namespace Stride.Shaders.Spirv.Building; @@ -183,4 +184,9 @@ IdRef RegisterPointerType(PointerType pointerType) } public void Dispose() => Buffer.Dispose(); + + public override string ToString() + { + return new SpirvDis(Buffer).Disassemble(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 0345c346a2..1e4243c681 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -23,6 +23,8 @@ public partial struct SpirvDis public SpirvDis(TBuffer buff, bool useNames = false) { buffer = buff; + if(buff.InstructionSpan.Length == 0) + return; writer = new(); UseNames = useNames; IdOffset = 9; @@ -71,6 +73,9 @@ public string Disassemble(bool writeToConsole = false) .AppendLine($"; Bound: {header.Bound}") .AppendLine($"; Schema: {header.Schema}"); } + + if(buffer.InstructionSpan.Length == 0) + return ""; foreach (var e in buffer) { @@ -129,7 +134,7 @@ public readonly void CheckNameTable(RefInstruction instruction) else if (instruction.OpCode == SDSLOp.OpTypeFloat) { var size = instruction.Operands[1]; - nameTable[instruction.ResultId!.Value] = new(size == 16 ? "half" : size == 64 ? "double" : "float"); + nameTable[instruction.ResultId!.Value] = new(size switch {16 => "half", 32 => "float", 64 => "double", _ => throw new NotImplementedException()}); } else if (instruction.OpCode == SDSLOp.OpTypeVector) { From 1e146a464a44918fcc468087070c89f58a22a36e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 16 May 2025 12:07:54 +0900 Subject: [PATCH 0385/1182] Fix buffer bounds (it was causing spirv-cross to crash) --- src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 3bd3652841..ebb045bb0c 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -156,8 +156,8 @@ public static SpirvBuffer Merge(T1 left, T2 right) buff.Add(left); buff.Add(right); foreach (var e in buff) - if (e.ResultId is int r && buff.Header.Bound < r) - buff.Header = buff.Header with { Bound = r }; + if (e.ResultId is int r && buff.Header.Bound < r + 1) + buff.Header = buff.Header with { Bound = r + 1 }; return buff; } From 13b4175abe5d793ad263d37bf8de1684aa598872 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 11:02:26 +0900 Subject: [PATCH 0386/1182] Further progress on struct types --- assets/SDSL/TestStruct.sdsl | 4 +- .../Parsing/SDSL/AST/Expression.cs | 18 +++-- .../Parsing/SDSL/AST/Statements.cs | 14 +++- .../Spirv/Building/Builder.Expressions.cs | 25 ------- src/Stride.Shaders/Spirv/Building/Context.cs | 70 ++++++++++++++++--- 5 files changed, 91 insertions(+), 40 deletions(-) diff --git a/assets/SDSL/TestStruct.sdsl b/assets/SDSL/TestStruct.sdsl index 38c5445f4b..7619208c75 100644 --- a/assets/SDSL/TestStruct.sdsl +++ b/assets/SDSL/TestStruct.sdsl @@ -5,11 +5,13 @@ shader TestStruct struct A { int B; + int C; }; void VSMain() { A a; - a.B = 3; + a.C = 3; + a.B = a.C; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 049c075306..0382a07db6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -130,9 +130,12 @@ void ProcessAccessors() accessor.Type = type; } else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); + if(accessor is not Identifier) accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); } + // AccessorChain always end up with a pointer type + Type = new PointerType(Type); } } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -144,19 +147,24 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) throw new NotImplementedException(); - var currentType = Source.Type; - Span indexes = stackalloc IdRef[Accessors.Count - 1]; - foreach (var accessor in Accessors) + var currentValueType = Source.Type; + Span indexes = stackalloc IdRef[Accessors.Count]; + for (var i = 0; i < Accessors.Count; i++) { - if (currentType is StructType s && accessor is Identifier field) + var accessor = Accessors[i]; + if (currentValueType is StructType s && accessor is Identifier field) { var index = s.TryGetFieldIndex(field); if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.ProcessSymbol(table); + indexes[i] = context.CreateConstant(shader, indexLiteral).Id; } else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); - currentType = accessor.Type; + currentValueType = accessor.Type; } var resultType = context.GetOrRegister(Type); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 68b2e93b43..464f2c1b38 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -1,4 +1,5 @@ using System.Text; +using Spv; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; @@ -185,8 +186,11 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method, Entry { variable.Variable.ProcessSymbol(table, entrypoint, io); variable.Value!.ProcessSymbol(table, entrypoint, io); + + if (variable.Variable.Type is not PointerType) + throw new InvalidOperationException("can only assign to pointer type"); } - } + } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, _) = compiler; @@ -194,6 +198,14 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { var target = variable.Variable.Compile(table, shader, compiler); var source = variable.Value!.Compile(table, shader, compiler); + if (variable.Value!.Type is PointerType p) + { + var sourceLoad = context.Bound++; + var underlyingType = context.GetOrRegister(p.BaseType); + builder.Position += builder.Buffer.InsertOpLoad(builder.Position, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.MaskNone).WordCount; + source = new(sourceLoad, underlyingType); + } + var instruction = builder.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); builder.Position += instruction.WordCount; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index f632d04c25..26530923d2 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -116,31 +116,6 @@ public SpirvValue CallFunction(SpirvContext context, string name, Span pa return new(fcall, func.Name); } - public SpirvValue CreateConstant(SpirvContext context, ShaderClass shader, Literal literal) - { - var instruction = literal switch - { - BoolLiteral lit => lit.Value switch - { - true => Buffer.InsertOpConstantTrue(Position, context.Bound++, context.GetOrRegister(lit.Type)), - false => Buffer.InsertOpConstantFalse(Position, context.Bound++, context.GetOrRegister(lit.Type)) - }, - IntegerLiteral lit => lit.Suffix.Size switch - { - > 32 => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.LongValue), - _ => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.IntValue), - }, - FloatLiteral lit => lit.Suffix.Size switch - { - > 32 => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), lit.DoubleValue), - _ => Buffer.InsertOpConstant(Position, context.Bound++, context.GetOrRegister(lit.Type), (float)lit.DoubleValue), - }, - _ => throw new NotImplementedException() - }; - Position += instruction.WordCount; - return new(instruction); - } - public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { var instruction = Buffer.InsertOpCompositeConstruct(Position, context.Bound++, context.GetOrRegister(literal.Type), values); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 8070ed6849..9e1e33af3b 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -18,6 +18,7 @@ public class SpirvContext(SpirvModule module) : IDisposable public SortedList Variables { get; } = []; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; + public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; public SpirvBuffer Buffer { get; set; } = new(); public void PutMixinName(string name) @@ -25,7 +26,8 @@ public void PutMixinName(string name) if (Name is null) { Name = name; - Buffer.InsertOpSDSLMixinName(5, name); + // temporary removed for testing SPIRV cross + //Buffer.InsertOpSDSLMixinName(5, name); } else throw new NotImplementedException(); } @@ -153,14 +155,14 @@ public IdRef GetOrRegister(SymbolType? type) IdRef RegisterStruct(StructType structSymbol) { Span types = stackalloc IdRef[structSymbol.Fields.Count]; - int tmp = 0; - foreach (var f in structSymbol.Fields) - { - types[tmp] = GetOrRegister(f.Type); - AddMemberName(types[tmp], tmp, f.Name); - } + for (var index = 0; index < structSymbol.Fields.Count; index++) + types[index] = GetOrRegister(structSymbol.Fields[index].Type); + var result = Buffer.AddOpTypeStruct(Bound++, types); AddName(result, structSymbol.Name); + for (var index = 0; index < structSymbol.Fields.Count; index++) + AddMemberName(result, index, structSymbol.Fields[index].Name); + return result; } @@ -171,7 +173,8 @@ IdRef RegisterFunctionType(FunctionType functionType) foreach (var f in functionType.ParameterTypes) types[tmp] = GetOrRegister(f); var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); - AddName(result, functionType.ToString()); + // disabled for now: currently it generates name with {}, not working with most SPIRV tools + //AddName(result, functionType.ToString()); return result; } @@ -183,6 +186,57 @@ IdRef RegisterPointerType(PointerType pointerType) return result; } + public SpirvValue CreateConstant(ShaderClass shader, Literal literal) + { + object literalValue = literal switch + { + BoolLiteral lit => lit.Value, + IntegerLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.LongValue, + _ => lit.IntValue, + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.DoubleValue, + _ => (float)lit.DoubleValue, + }, + }; + + if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) + return result; + + var instruction = literal switch + { + BoolLiteral lit => lit.Value switch + { + true => Buffer.AddOpConstantTrue(Bound++, GetOrRegister(lit.Type)), + false => Buffer.AddOpConstantFalse(Bound++, GetOrRegister(lit.Type)) + }, + IntegerLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.LongValue), + _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue), + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue), + _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue), + }, + _ => throw new NotImplementedException() + }; + + result = new(instruction); + LiteralConstants.Add((literal.Type, literalValue), result); + AddName(result.Id, literal switch + { + BoolLiteral lit => $"{lit.Type}_{lit.Value}", + IntegerLiteral lit => $"{lit.Type}_{lit.Value}", + FloatLiteral lit => $"{lit.Type}_{lit.Value}", + }); + return result; + } + public void Dispose() => Buffer.Dispose(); public override string ToString() From 3751ba351df9387c60b3949c3c8970261691cae5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 11:02:48 +0900 Subject: [PATCH 0387/1182] Display disassembler error (currently in console) --- src/Stride.Shaders.Compilers/SpirvTranslator.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 8b4bc7695b..b549f52c43 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -26,12 +26,19 @@ public readonly string Translate(Backend backend = Backend.Hlsl) if (cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); + cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => + { + var error = Marshal.PtrToStringAnsi((IntPtr)errorData); + Console.WriteLine(error); + }), null); + if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); if (cross.CompilerCompile(compiler, &translated) != Result.Success) throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); + translatedCode = SilkMarshal.PtrToString((nint)translated); cross.ContextReleaseAllocations(context); cross.ContextDestroy(context); From 61c6f8d39a71628a6de44f038c1f9526206ca21e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 11:03:17 +0900 Subject: [PATCH 0388/1182] Disassembler: check names in a first pass so that disassembly has all names --- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 1e4243c681..2757bd1f9e 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -77,10 +77,15 @@ public string Disassemble(bool writeToConsole = false) if(buffer.InstructionSpan.Length == 0) return ""; + // First pass: scan names foreach (var e in buffer) { CheckNameTable(e); + } + // Second pass: disassemble + foreach (var e in buffer) + { if (UseNames && e.ResultId is int id && nameTable.TryGetValue(id, out var nid)) Append(nid); else From 62e36f3c961c33e3eeb7a48c3270b8c66e66eba6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 13:03:16 +0900 Subject: [PATCH 0389/1182] Fix OpFunctionEnd position --- src/Stride.Shaders.Experiments/Examples.Spirv.cs | 1 + .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 1 + src/Stride.Shaders/Spirv/Building/Builder.Flow.cs | 1 - src/Stride.Shaders/Spirv/Building/Builder.Functions.cs | 7 +++++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 58026c3411..6c975debf7 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -41,6 +41,7 @@ public static void GenerateSpirv() function.Parameters["a"], Operator.Plus, function.Parameters["b"] ); builder.Return(v); + builder.EndFunction(context); context.Buffer.Sort(); var dis = new SpirvDis(SpirvBuffer.Merge(context.Buffer, builder.Buffer), useNames: true); dis.Disassemble(true); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f29428148b..f8c5469eba 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -193,6 +193,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler foreach(var s in body) s.Compile(table, shader, compiler); } + builder.EndFunction(context); } else throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index d618835662..12678e21ea 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -31,7 +31,6 @@ public void CleanBlock() { var size = Buffer.Span[Position] >> 16; Buffer.Remove(Position); - Position -= size; } } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 3287fb9493..41c456a400 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -15,11 +15,15 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT Position += func.WordCount; context.AddName(func, name); var result = new SpirvFunction(func.ResultId!.Value, name, ftype); - Buffer.InsertOpFunctionEnd(Position); CurrentFunction = result; return result; } + public void EndFunction(SpirvContext context) + { + Position += Buffer.InsertOpFunctionEnd(Position).WordCount; + } + public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) { var p = Buffer.InsertOpFunctionParameter(Position, context.Bound++, context.GetOrRegister(type)); @@ -37,7 +41,6 @@ public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execM if(!variables.IsEmpty) foreach(var p in variables) context.AddName(context.Variables[p.Id.Name], p.Id.Name); - Position += Buffer.InsertOpFunctionEnd(Position).WordCount; CurrentFunction = result; return result; } From b91a89610efa93e0f0397bbd3269d474bd43a0d5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 13:03:31 +0900 Subject: [PATCH 0390/1182] Added FunctionCall --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 6 ++++++ src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 4 ++-- src/Stride.Shaders/Spirv/Building/Builder.Functions.cs | 1 + src/Stride.Shaders/Spirv/Building/Module.cs | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 0382a07db6..6b3e8fd545 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -24,6 +24,12 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public Identifier Name = name; public ShaderExpressionList Parameters = parameters; + public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) + { + foreach (var p in parameters.Values) + p.ProcessSymbol(table, entrypoint, io); + } + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, module) = compiler; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 26530923d2..ecd6965546 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -110,8 +110,8 @@ public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - var func = context.Module.Functions[name]; - var fcall = Buffer.InsertOpFunctionCall(Position, context.Bound++, func.Id, context.GetOrRegister(func.FunctionType.ReturnType), parameters); + var func = context.Module.Functions.First(x => x.Name == name); + var fcall = Buffer.InsertOpFunctionCall(Position, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); Position += fcall.WordCount; return new(fcall, func.Name); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 41c456a400..59d5afb446 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -16,6 +16,7 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT context.AddName(func, name); var result = new SpirvFunction(func.ResultId!.Value, name, ftype); CurrentFunction = result; + context.Module.Functions.Add(result); return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Module.cs b/src/Stride.Shaders/Spirv/Building/Module.cs index fd136f1cbd..54684e8a01 100644 --- a/src/Stride.Shaders/Spirv/Building/Module.cs +++ b/src/Stride.Shaders/Spirv/Building/Module.cs @@ -4,5 +4,5 @@ namespace Stride.Shaders.Spirv.Building; // Should contain symbols for the SPIR-V module public class SpirvModule() { - public SortedList Functions { get; init; } = []; + public List Functions { get; init; } = []; } From 5222efa57aedba3e53c2ae973ad2c79441a5af95 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 13:05:49 +0900 Subject: [PATCH 0391/1182] Added SPIRV-cross after SDSLC --- assets/SDSL/TestStruct.sdsl | 11 ++++++++++- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 11 +++++++++++ src/Stride.Shaders.Experiments/Examples.cs | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/assets/SDSL/TestStruct.sdsl b/assets/SDSL/TestStruct.sdsl index 7619208c75..7b3f265e59 100644 --- a/assets/SDSL/TestStruct.sdsl +++ b/assets/SDSL/TestStruct.sdsl @@ -8,10 +8,19 @@ shader TestStruct int C; }; - void VSMain() + void Test1(int p1, int p2) + { + A a; + a.C = p1 + p2; + return; + } + + float4 VSMain() { A a; a.C = 3; a.B = a.C; + Test1(3, a.B); + return float4(1.0, 1.0, 1.0, 1.0); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 6219264c29..0a760e7db1 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -25,6 +25,17 @@ public readonly bool Compile(string code, out byte[] compiled) using var compiler = new CompilerUnit(); shader.Compile(compiler, table); + // temp hack to add entry point (last function) + var context = compiler.Context; + if (context.Module.Functions.Count > 0) + { + var lastFunction = context.Module.Functions[^1]; + context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); + context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); + context.SetEntryPoint(Spv.Specification.ExecutionModel.Vertex, lastFunction.Id, lastFunction.Name, []); + } + + compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); var dis = new SpirvDis(merged, true); diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index b249cc4f6e..c383a0a0e3 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -1,4 +1,5 @@ using System.Text; +using CommunityToolkit.HighPerformance; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; @@ -216,6 +217,8 @@ public static void CompileSDSL() var sdslc = new SDSLC(); sdslc.Compile(text, out var bytecode); + var code = new SpirvTranslator(bytecode.AsMemory().Cast()); + Console.WriteLine(code.Translate(Backend.Hlsl)); } } From 7f5510b4aae7cc15a79679b43d55843ec72a79a1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 13:06:17 +0900 Subject: [PATCH 0392/1182] Disasm: Always use opcode names --- src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs index 980f006721..13e3d81116 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs @@ -122,7 +122,7 @@ public readonly void Append(in SpvOperand o, in RefInstruction instruction) { if (o.Kind == OperandKind.IdRef) foreach (var e in o.Words) - Append(new IdRef(e), instruction.OpCode == SDSLOp.OpName); + Append(new IdRef(e), false); else if (o.Kind == OperandKind.IdResultType) foreach (var e in o.Words) Append((IdResultType)e); From a6417c5634d1d7ba501f2df84394d41bb8e4295b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 May 2025 13:32:21 +0900 Subject: [PATCH 0393/1182] Generate better SPIRV assembly (which can be fed in shader playground or other tools directly) --- src/Stride.Shaders/Core/SymbolTypes.cs | 20 +++++++++++++++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 6 +++--- .../Spirv/Tools/SpirvDis.Appends.cs | 2 ++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index bea68ab331..cd5ccd7993 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -7,6 +7,12 @@ namespace Stride.Shaders.Core; public abstract record SymbolType() { + /// + /// Converts to an identifier compatible with . + /// + /// + public virtual string ToId() => ToString(); + public static bool TryGetNumeric(string name, out SymbolType? result) { if(ScalarType.Types.TryGetValue(name, out var s)) @@ -47,6 +53,7 @@ public override string ToString() public sealed record PointerType(SymbolType BaseType) : SymbolType() { + public override string ToId() => $"ptr_{BaseType.ToId()}"; public override string ToString() => $"*{BaseType}"; } @@ -68,6 +75,7 @@ public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() } public sealed record StructType(string Name, List<(string Name, SymbolType Type)> Fields) : SymbolType() { + public override string ToId() => Name; public override string ToString() => $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Type} {x.Name}"))}}}"; public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType type) @@ -145,6 +153,18 @@ public override int GetHashCode() return hash; } + public override string ToId() + { + var builder = new StringBuilder(); + builder.Append($"fn_"); + for (int i = 0; i < ParameterTypes.Count; i++) + { + builder.Append(ParameterTypes[i].ToId()); + builder.Append('_'); + } + return builder.Append(ReturnType.ToId()).ToString(); + } + public override string ToString() { var builder = new StringBuilder(); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9e1e33af3b..00d4ba9e1c 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -159,7 +159,7 @@ IdRef RegisterStruct(StructType structSymbol) types[index] = GetOrRegister(structSymbol.Fields[index].Type); var result = Buffer.AddOpTypeStruct(Bound++, types); - AddName(result, structSymbol.Name); + AddName(result, structSymbol.ToId()); for (var index = 0; index < structSymbol.Fields.Count; index++) AddMemberName(result, index, structSymbol.Fields[index].Name); @@ -174,7 +174,7 @@ IdRef RegisterFunctionType(FunctionType functionType) types[tmp] = GetOrRegister(f); var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); // disabled for now: currently it generates name with {}, not working with most SPIRV tools - //AddName(result, functionType.ToString()); + AddName(result, functionType.ToId()); return result; } @@ -182,7 +182,7 @@ IdRef RegisterPointerType(PointerType pointerType) { var baseType = GetOrRegister(pointerType.BaseType); var result = Buffer.AddOpTypePointer(Bound++, Spv.Specification.StorageClass.Function, baseType); - AddName(result, pointerType.ToString()); + AddName(result, pointerType.ToId()); return result; } diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs index 13e3d81116..92f3a2c5ff 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs @@ -32,6 +32,8 @@ internal readonly void Append(NameId name) public readonly void Append(T value) where T : Enum { var name = Enum.GetName(typeof(T), value); + if (name == "MaskNone") + name = "None"; writer.Append(' ').Append(name); } public readonly void Append(IdRef id, bool ignoreName = false) From 8ce5bdd1c662ff93a0f73be8c9dde820a4fcfa6a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 May 2025 18:09:09 +0900 Subject: [PATCH 0394/1182] First test iteration for StreamAnalyzer --- assets/SDSL/TestBasic.sdsl | 24 +- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 9 +- .../Buffers/SpirvBuffer.cs | 12 + .../RefInstructionEnumerator - Copy.cs | 47 ++++ .../Parsing/SDSL/AST/Expression.cs | 41 ++- .../Parsing/SDSL/AST/Literals.cs | 26 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 14 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 7 +- .../Spirv/Building/Builder.Functions.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 6 +- .../Spirv/Processing/StreamAnalyzer.cs | 250 ++++++++++++++++++ 11 files changed, 394 insertions(+), 44 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index 9cd6dd4033..c5806f49eb 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -2,8 +2,28 @@ namespace Stride.Shaders.Tests; shader TestBasic { - int Add(int a, int b) + stream float4 InputPosition : POSITION; + stream float4 Position : SV_POSITION; + stream float4 ExtraColor : COLOR; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.Position = streams.InputPosition; + return; + } + + void Test() + { + streams.ColorTarget = streams.ExtraColor; + return; + } + + void PSMain() { - return a + b; + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + streams.ColorTarget = streams.ExtraColor; + //Test(); + return; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 0a760e7db1..871cd3c53c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -6,6 +6,8 @@ using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Core.Buffers; using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Processing; namespace Stride.Shaders.Compilers.SDSL; @@ -29,12 +31,13 @@ public readonly bool Compile(string code, out byte[] compiled) var context = compiler.Context; if (context.Module.Functions.Count > 0) { - var lastFunction = context.Module.Functions[^1]; + var entryPoint = context.Module.Functions[^1]; context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); - context.SetEntryPoint(Spv.Specification.ExecutionModel.Vertex, lastFunction.Id, lastFunction.Name, []); - } + context.SetEntryPoint(Spv.Specification.ExecutionModel.Vertex, entryPoint.Id, entryPoint.Name, []); + new StreamAnalyzer().Process(table, compiler, entryPoint); + } compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index ebb045bb0c..04c08eefd5 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -25,11 +25,23 @@ public RefHeader Header value.Words.CopyTo(Header.Words); } } + public Span InstructionSpan => Span[5..]; public Memory InstructionMemory => Memory[5..]; public int InstructionCount => new SpirvReader(Memory).Count; + public RefInstruction FindInstructionByResultId(int resultId) + { + foreach (var instruction in this) + { + if (instruction.ResultId == resultId) + return instruction; + } + + throw new InvalidOperationException(); + } + public Instruction this[int index] { get diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs new file mode 100644 index 0000000000..3365fe0618 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs @@ -0,0 +1,47 @@ +using System.Reflection.Emit; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// Instruction enumerator returning RefInstruction +/// +public ref struct RefMutableFunctionInstructionEnumerator +{ + int wordIndex; + int index; + readonly SpirvBuffer buffer; + + public readonly RefInstruction Current => + RefInstruction.ParseRef( + buffer.Span.Slice(wordIndex, buffer.Span[wordIndex] >> 16), + wordIndex, + index + ); + + public RefMutableFunctionInstructionEnumerator(SpirvBuffer buffer, int methodStart) + { + wordIndex = methodStart; + index = -1; + this.buffer = buffer; + } + + public bool MoveNext() + { + if (index == -1) + { + index = 0; + return true; + } + else + { + if (index >= 0 && buffer.Span[wordIndex] == (int)SDSLOp.OpFunctionEnd) + return false; + if (wordIndex + (buffer.Span[wordIndex] >> 16) >= buffer.Span.Length) + return false; + wordIndex += buffer.Span[wordIndex] >> 16; + index += 1; + return true; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 6b3e8fd545..d68bf22e38 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -110,25 +110,30 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n { if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { - table.CurrentFunctionSymbols.Add(table.Streams); + //table.CurrentFunctionSymbols.Add(table.Streams); streamVar.ProcessSymbol(table, entrypoint, io); Type = streamVar.Type; - ProcessAccessors(); + if (Accessors.Count > 1) + { + ProcessAccessors(1); - table.Pop(); - table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); + table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); + } } else { Source.ProcessSymbol(table, entrypoint, io ?? StreamIO.Output); Type = Source.Type; - ProcessAccessors(); + ProcessAccessors(0); } - void ProcessAccessors() + // AccessorChain always end up with a pointer type + Type = new PointerType(Type); + + void ProcessAccessors(int firstIndex) { - foreach (var accessor in Accessors) + foreach (var accessor in Accessors[firstIndex..]) { if (Type is not null && Type.TryAccess(accessor, out var type)) { @@ -140,22 +145,28 @@ void ProcessAccessors() if(accessor is not Identifier) accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); } - // AccessorChain always end up with a pointer type - Type = new PointerType(Type); } } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, _) = compiler; - var source = Source.Compile(table, shader, compiler); + SpirvValue source; var variable = context.Bound++; + int firstIndex = 0; if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) - throw new NotImplementedException(); + { + source = streamVar.Compile(table, shader, compiler); + firstIndex = 1; + } + else + { + source = Source.Compile(table, shader, compiler); + } var currentValueType = Source.Type; Span indexes = stackalloc IdRef[Accessors.Count]; - for (var i = 0; i < Accessors.Count; i++) + for (var i = firstIndex; i < Accessors.Count; i++) { var accessor = Accessors[i]; if (currentValueType is StructType s && accessor is Identifier field) @@ -166,13 +177,17 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); indexLiteral.ProcessSymbol(table); - indexes[i] = context.CreateConstant(shader, indexLiteral).Id; + indexes[i] = context.CreateConstant(indexLiteral).Id; } else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); currentValueType = accessor.Type; } + // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) + if (firstIndex == Accessors.Count) + return source; + var resultType = context.GetOrRegister(Type); var result = builder.Buffer.InsertOpAccessChain(builder.Position, variable, resultType, source.Id, indexes); builder.Position += result.WordCount; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 3185b1f66f..76eb204a67 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -210,16 +210,12 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, St Span sOrder = [Storage.Function, Storage.Stream, Storage.Uniform, Storage.UniformConstant, Storage.Generic]; foreach (var storage in sOrder) { - if (table.CurrentFunctionSymbols is null) + if (table.CurrentFunctionSymbols is not null) { - if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) - Type = symbol.Type; - } - else - { - for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; i -= 1) + for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; --i) { - if (table.CurrentFunctionSymbols![i].TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) + if (table.CurrentFunctionSymbols![i] + .TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) { if (symbol.Type is not UndefinedType and not null) Type = symbol.Type; @@ -228,11 +224,12 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, St return; } } - if (table.CurrentFunctionSymbols is null) - { - if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var rootSymbol)) - Type = rootSymbol.Type; - } + } + + if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var rootSymbol)) + { + Type = rootSymbol.Type; + return; } } @@ -249,6 +246,9 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil else if(f.Parameters.TryGetValue(Name, out var paramVar)) return paramVar; } + + if (compiler.Context.Variables.TryGetValue(Name, out var variable)) + return variable; throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index bd2055ffe8..4159029332 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -53,11 +53,11 @@ public override void ProcessSymbol(SymbolTable table) } ); var symbol = new Symbol(sid, svar.Type); - if (sid.Storage == Storage.Stream) - { - table.Streams.Add(sid, symbol); - } - else + //if (sid.Storage == Storage.Stream) + //{ + // table.Streams.Add(sid, symbol); + //} + //else { table.RootSymbols.Add(sid, symbol); } @@ -65,14 +65,14 @@ public override void ProcessSymbol(SymbolTable table) } } - var streams = + /*var streams = new SymbolID ( "streams", SymbolKind.Variable, Storage.None ); - table.RootSymbols.Add(streams, new(streams, new StreamsSymbol())); + table.RootSymbols.Add(streams, new(streams, new StreamsSymbol()));*/ foreach (var member in Elements) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f8c5469eba..8de1f9ed81 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -1,3 +1,4 @@ +using Spv; using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; @@ -84,7 +85,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var (builder, context, _) = compiler; var registeredType = context.GetOrRegister(Type); var variable = context.Bound++; - context.Buffer.AddOpVariable(variable, registeredType, Spv.Specification.StorageClass.Function, null); + // TODO: Add a StreamSDSL storage class? + context.Buffer.AddOpVariable(variable, registeredType, Spv.Specification.StorageClass.Private, null); + context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) context.Buffer.AddOpSDSLDecorateSemantic(variable, Semantic.Name); context.AddName(variable, Name); @@ -190,7 +193,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if(Body is BlockStatement body) { builder.CreateBlock(context); - foreach(var s in body) + foreach (var s in body) s.Compile(table, shader, compiler); } builder.EndFunction(context); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 59d5afb446..73c700a757 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -41,7 +41,7 @@ public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execM var result = new SpirvFunction(func.ResultId!.Value, name, type); if(!variables.IsEmpty) foreach(var p in variables) - context.AddName(context.Variables[p.Id.Name], p.Id.Name); + context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); CurrentFunction = result; return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 00d4ba9e1c..9d5436fb31 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -15,7 +15,7 @@ public class SpirvContext(SpirvModule module) : IDisposable public int Bound { get; internal set; } = 1; public string? Name { get; private set; } public SpirvModule Module { get; } = module; - public SortedList Variables { get; } = []; + public SortedList Variables { get; } = []; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; @@ -103,7 +103,7 @@ public void SetEntryPoint(ExecutionModel model, IdRef function, string name, Rea Span pvariables = stackalloc IdRef[variables.Length]; int pos = 0; foreach (var v in variables) - pvariables[pos++] = Variables[v.Id.Name]; + pvariables[pos++] = Variables[v.Id.Name].Id; Buffer.AddOpEntryPoint(model, function, name, pvariables); } @@ -186,7 +186,7 @@ IdRef RegisterPointerType(PointerType pointerType) return result; } - public SpirvValue CreateConstant(ShaderClass shader, Literal literal) + public SpirvValue CreateConstant(Literal literal) { object literalValue = literal switch { diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs new file mode 100644 index 0000000000..8f8446e3ed --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -0,0 +1,250 @@ +using Spv; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; +using Stride.Shaders.Spirv.Tools; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace Stride.Shaders.Spirv.Processing +{ + public class StreamAnalyzer + { + class StreamInfo(string name, SymbolType type) + { + public string Name { get; } = name; + public SymbolType Type { get; } = type; + + public int FieldIndex { get; set; } = -1; + public bool Read { get; set; } + public bool Write { get; set; } + + public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; + } + + public void Process(SymbolTable table, CompilerUnit compiler, SpirvFunction entryPoint) + { + var context = compiler.Context; + var streams = new Dictionary(); + + // Build name table + SortedList nameTable = []; + foreach (var instruction in compiler.Context.Buffer) + { + if ((instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) + && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t + && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n + ) + { + nameTable[t] = new(n.Value); + } + } + + + // Analyze streams + foreach (var instruction in compiler.Context.Buffer) + { + if (instruction.OpCode == SDSLOp.OpVariable + && (Specification.StorageClass)instruction.Operands[2] == Specification.StorageClass.Private) + { + var name = nameTable.TryGetValue(instruction.Operands[1], out var nameId) + ? nameId.Name + : $"unnamed_{instruction.Operands[1]}"; + var type = compiler.Context.ReverseTypes[instruction.Operands[0]]; + streams.Add(instruction.ResultId!.Value, new StreamInfo(name, type)); + } + } + + // Create streams struct + //var streamStructType = new StructType("STREAMS", streams); + //var streamStruct = compiler.Context.GetOrRegister(streamStructType); + + var streamStructId = context.Bound++; + var streamStructPtrId = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, streamStructId); + + //for (var index = 0; index < structSymbol.Fields.Count; index++) + // AddMemberName(result, index, structSymbol.Fields[index].Name); + + List structStreams = new(); + int totalActiveStreams = 0; + ProcessMethod(table, compiler, entryPoint.Id, true, streamStructPtrId.ResultId!.Value, streams, ref totalActiveStreams); + + Span fields = stackalloc IdRef[totalActiveStreams]; + foreach (var stream in streams) + { + if (stream.Value.FieldIndex == -1) + continue; + fields[stream.Value.FieldIndex] = context.Types[stream.Value.Type]; + context.Buffer.AddOpMemberName(streamStructId, stream.Value.FieldIndex, stream.Value.Name); + } + var result = context.Buffer.AddOpTypeStruct(streamStructId, fields); + context.AddName(result, "STREAMS"); + + var methodStart = FindMethodStart(compiler, entryPoint.Id); + var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); + } + + private bool ProcessMethod(SymbolTable table, CompilerUnit compiler, int functionId, bool isEntryPoint, int streamStructPtrId, Dictionary streams, ref int totalActiveStreams) + { + var methodStart = FindMethodStart(compiler, functionId); + int? streamsVariableId = null; + var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); + var context = compiler.Context; + + void MarkStreamsUsed() + { + if (streamsVariableId == null) + { + streamsVariableId = context.Bound++; + } + } + + while (enumerator.MoveNext()) + { + var instruction = enumerator.Current; + + if (instruction.OpCode == SDSLOp.OpLoad + || instruction.OpCode == SDSLOp.OpStore) + { + var operandIndex = instruction.OpCode == SDSLOp.OpLoad ? 2 : 0; + if (streams.TryGetValue(instruction.Operands[operandIndex], out var streamInfo)) + { + if (streamInfo.FieldIndex == -1) + { + streamInfo.FieldIndex = totalActiveStreams++; + // First time, let's register it + } + + if (instruction.OpCode == SDSLOp.OpLoad && !streamInfo.Write) + streamInfo.Read = true; + if (instruction.OpCode == SDSLOp.OpStore) + streamInfo.Write = true; + MarkStreamsUsed(); + + var typeId = compiler.Context.GetOrRegister(streamInfo.Type); + var typePtrId = compiler.Context.GetOrRegister(new PointerType(streamInfo.Type)); + var index = streamInfo.FieldIndex; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.ProcessSymbol(table); + IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; + var accessChain = compiler.Builder.Buffer.InsertOpAccessChain(instruction.WordIndex, compiler.Context.Bound++, typePtrId, streamsVariableId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); + + // Update OpLoad/OpStore to use the new OpAccessChain + enumerator.MoveNext(); + instruction = enumerator.Current; + instruction.Operands[operandIndex] = accessChain.ResultId!.Value; + } + } + else if (instruction.OpCode == SDSLOp.OpAccessChain) + { + if (streams.TryGetValue(instruction.Operands[2], out var streamInfo)) + { + // Map the pointer access as access to the underlying stream (if any) + // i.e., streams.A.B will share same streamInfo as streams.A + // TODO: need to store access chain, handle type info in OpStore/OpLoad, etc. + streams.Add(instruction.ResultId!.Value, streamInfo); + + // TODO: Add OpAccessChain entry + //throw new NotImplementedException(); + } + } + else if (instruction.OpCode == SDSLOp.OpFunctionCall) + { + // Process call + var calledFunctionId = instruction.Operands[2]; + if (ProcessMethod(table, compiler, calledFunctionId, false, streamStructPtrId, streams, ref totalActiveStreams)) + MarkStreamsUsed(); + } + } + + if (streamsVariableId != null) + { + enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); + + while (enumerator.MoveNext()) + { + var instruction = enumerator.Current; + + if (instruction.OpCode == SDSLOp.OpFunction) + { + // Entry point will add STREAMS as a variable + // For other functions, it will be passed through + if (isEntryPoint) + { + while ((instruction.OpCode == SDSLOp.OpFunction || instruction.OpCode == SDSLOp.OpFunctionParameter || instruction.OpCode == SDSLOp.OpLabel) && enumerator.MoveNext()) + instruction = enumerator.Current; + + var streamsVariable = compiler.Builder.Buffer.InsertOpVariable(instruction.WordIndex, streamsVariableId.Value, streamStructPtrId, Specification.StorageClass.Function, null); + enumerator.MoveNext(); + instruction = enumerator.Current; + + context.AddName(streamsVariable, "streams"); + + // Copy read variables from streams + foreach (var streamInfo in streams) + { + if (streamInfo.Value.Read) + { + var loadedValue = compiler.Builder.Buffer.InsertOpLoad(instruction.WordIndex, context.Bound++, context.Types[streamInfo.Value.Type], streamInfo.Key, null); + enumerator.MoveNext(); + instruction = enumerator.Current; + var typeId = compiler.Context.GetOrRegister(streamInfo.Value.Type); + var typePtrId = compiler.Context.GetOrRegister(new PointerType(streamInfo.Value.Type)); + var index = streamInfo.Value.FieldIndex; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.ProcessSymbol(table); + IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; + var accessChain = compiler.Builder.Buffer.InsertOpAccessChain(instruction.WordIndex, compiler.Context.Bound++, typeId, streamsVariableId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); + enumerator.MoveNext(); + instruction = enumerator.Current; + + compiler.Builder.Buffer.InsertOpStore(instruction.WordIndex, accessChain.ResultId!.Value, loadedValue.ResultId!.Value, null); + } + } + } + else + { + var functionType = context.Buffer.FindInstructionByResultId(instruction.Operands[3]); + Span parameterTypes = stackalloc IdRef[1 + functionType.Operands.Length - 2]; + parameterTypes[0] = streamStructPtrId; + for (int i = 0; i < functionType.Operands.Length - 2; ++i) + parameterTypes[i + 1] = instruction.Operands[2 + i]; + var newFunctionType = compiler.Context.Buffer.InsertOpTypeFunction(functionType.WordIndex + functionType.WordCount, context.Bound++, functionType.Operands[1], parameterTypes); + + // Update function type + instruction.Operands[3] = newFunctionType.ResultId!.Value; + + var streamsVariable = compiler.Builder.Buffer.InsertOpFunctionParameter(instruction.WordIndex + instruction.WordCount, streamsVariableId.Value, streamStructPtrId); + } + } + } + } + + return streamsVariableId != null; + } + + public int FindMethodStart(CompilerUnit compiler, int functionId) + { + int? start = null; + foreach (var instruction in compiler.Builder.Buffer) + { + if (instruction.OpCode == SDSLOp.OpFunction + && instruction.ResultId == functionId) + { + return instruction.WordIndex; + } + } + + throw new NotImplementedException(); + } + } +} From 973580c14d6afb57a5b866b820b65b389539b09b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 May 2025 11:03:02 +0900 Subject: [PATCH 0395/1182] Changed StreamAnalyzer to use static variables (much simpler) --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 12 +- .../Spirv/Processing/StreamAnalyzer.cs | 310 ++++++++++-------- 2 files changed, 176 insertions(+), 146 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 871cd3c53c..bca610df65 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -29,15 +29,9 @@ public readonly bool Compile(string code, out byte[] compiled) // temp hack to add entry point (last function) var context = compiler.Context; - if (context.Module.Functions.Count > 0) - { - var entryPoint = context.Module.Functions[^1]; - context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); - context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); - context.SetEntryPoint(Spv.Specification.ExecutionModel.Vertex, entryPoint.Id, entryPoint.Name, []); - - new StreamAnalyzer().Process(table, compiler, entryPoint); - } + context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); + context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); + new StreamAnalyzer().Process(table, compiler); compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 8f8446e3ed..ac6b7a6004 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -19,33 +19,82 @@ namespace Stride.Shaders.Spirv.Processing { public class StreamAnalyzer { - class StreamInfo(string name, SymbolType type) + class StreamInfo(string? semantic, string name, SymbolType type, int id) { + public string? Semantic { get; } = semantic; public string Name { get; } = name; public SymbolType Type { get; } = type; - public int FieldIndex { get; set; } = -1; + public int Id { get; } = id; + + /// + /// We automatically mark input: a variable read before it's written to, or an output without a write. + /// + public bool Input => Read || (Output && !Write); + public bool Output { get; set; } + public bool Read { get; set; } public bool Write { get; set; } public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - public void Process(SymbolTable table, CompilerUnit compiler, SpirvFunction entryPoint) + public void Process(SymbolTable table, CompilerUnit compiler) + { + var context = compiler.Context; + + var entryPointVS = context.Module.Functions.Find(x => x.Name == "VSMain"); + var entryPointPS = context.Module.Functions.Find(x => x.Name == "PSMain"); + + var streams = CreateStreams(compiler); + + foreach (var stream in streams) + { + if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) + stream.Value.Stream.Output = true; + } + ProcessMethod(table, compiler, entryPointPS.Id, streams); + + GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + foreach (var stream in streams) + { + stream.Value.Stream.Output = stream.Value.Stream.Read; + stream.Value.Stream.Read = false; + stream.Value.Stream.Write = false; + } + ProcessMethod(table, compiler, entryPointVS.Id, streams); + + GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + } + + private SortedList CreateStreams(CompilerUnit compiler) { var context = compiler.Context; - var streams = new Dictionary(); + var streams = new SortedList(); // Build name table SortedList nameTable = []; - foreach (var instruction in compiler.Context.Buffer) + SortedList semanticTable = []; + foreach (var instruction in context.Buffer) { - if ((instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) - && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n - ) { - nameTable[t] = new(n.Value); + if ((instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) + && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t + && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n + ) + { + nameTable[t] = new(n.Value); + } + } + + { + if (instruction.OpCode == SDSLOp.OpSDSLDecorateSemantic + && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t + && instruction.TryGetOperand("semantic", out LiteralString? name) && name is LiteralString n + ) + { + semanticTable[t] = n.Value; + } } } @@ -60,88 +109,144 @@ public void Process(SymbolTable table, CompilerUnit compiler, SpirvFunction entr ? nameId.Name : $"unnamed_{instruction.Operands[1]}"; var type = compiler.Context.ReverseTypes[instruction.Operands[0]]; - streams.Add(instruction.ResultId!.Value, new StreamInfo(name, type)); + semanticTable.TryGetValue(instruction.Operands[1], out var semantic); + streams.Add(instruction.ResultId!.Value, (new StreamInfo(semantic, name, type, instruction.ResultId!.Value), true)); } } - // Create streams struct - //var streamStructType = new StructType("STREAMS", streams); - //var streamStruct = compiler.Context.GetOrRegister(streamStructType); - - var streamStructId = context.Bound++; - var streamStructPtrId = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, streamStructId); - - //for (var index = 0; index < structSymbol.Fields.Count; index++) - // AddMemberName(result, index, structSymbol.Fields[index].Name); - - List structStreams = new(); - int totalActiveStreams = 0; - ProcessMethod(table, compiler, entryPoint.Id, true, streamStructPtrId.ResultId!.Value, streams, ref totalActiveStreams); + return streams; + } - Span fields = stackalloc IdRef[totalActiveStreams]; + private void GenerateStreamWrapper(SymbolTable table, CompilerUnit compiler, Specification.ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) + { + var stage = executionModel switch + { + Specification.ExecutionModel.Fragment => "PS", + Specification.ExecutionModel.Vertex => "VS", + }; + var context = compiler.Context; + List inputStreams = []; + List outputStreams = []; foreach (var stream in streams) { - if (stream.Value.FieldIndex == -1) + // Only direct access to global variables (not temporary variables created within function) + if (!stream.Value.IsDirect) continue; - fields[stream.Value.FieldIndex] = context.Types[stream.Value.Type]; - context.Buffer.AddOpMemberName(streamStructId, stream.Value.FieldIndex, stream.Value.Name); + + if (stream.Value.Stream.Input) + inputStreams.Add(stream.Value.Stream); + // TODO: filter with previous stage + if (stream.Value.Stream.Output) + outputStreams.Add(stream.Value.Stream); } - var result = context.Buffer.AddOpTypeStruct(streamStructId, fields); - context.AddName(result, "STREAMS"); - var methodStart = FindMethodStart(compiler, entryPoint.Id); - var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); - } + var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); - private bool ProcessMethod(SymbolTable table, CompilerUnit compiler, int functionId, bool isEntryPoint, int streamStructPtrId, Dictionary streams, ref int totalActiveStreams) - { - var methodStart = FindMethodStart(compiler, functionId); - int? streamsVariableId = null; - var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); - var context = compiler.Context; + Span inputFields = stackalloc IdRef[inputStreams.Count]; + int inputFieldIndex = 0; + var inputStructId = context.Bound++; + foreach (var stream in inputStreams) + { + inputFields[inputFieldIndex] = context.Types[stream.Type]; + context.Buffer.AddOpMemberName(inputStructId, inputFieldIndex++, stream.Name); + } + context.Buffer.AddOpTypeStruct(inputStructId, inputFields); + context.AddName(inputStructId, $"{stage}_INPUT"); + var inputStructPtrId = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, inputStructId); + + Span outputFields = stackalloc IdRef[outputStreams.Count]; + int outputFieldIndex = 0; + var outputStructId = context.Bound++; + foreach (var stream in outputStreams) + { + outputFields[outputFieldIndex] = context.Types[stream.Type]; + context.Buffer.AddOpMemberName(outputStructId, outputFieldIndex++, stream.Name); + } + context.Buffer.AddOpTypeStruct(outputStructId, outputFields); + context.AddName(outputStructId, $"{stage}_OUTPUT"); + var outputStructPtrId = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, outputStructId); + + // Add new entry point wrapper + var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, outputStructId, MemoryMarshal.CreateSpan(ref inputStructPtrId, 1)); + var newEntryPointFunction = compiler.Builder.Buffer.AddOpFunction(context.Bound++, outputStructId, Specification.FunctionControlMask.MaskNone, newEntryPointFunctionType); + context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); - void MarkStreamsUsed() { - if (streamsVariableId == null) + // Add INPUT (as a function parameter) + var inputParameter = compiler.Builder.Buffer.AddOpFunctionParameter(context.Bound++, inputStructPtrId); + context.AddName(inputParameter, "input"); + + compiler.Builder.Buffer.AddOpLabel(context.Bound++); + + // Add OUTPUT (as a local variable) + var outputParameter = compiler.Builder.Buffer.AddOpVariable(context.Bound++, outputStructPtrId.ResultId.Value, Specification.StorageClass.Function, null); + context.AddName(outputParameter, "output"); + + // Copy read variables from streams + inputFieldIndex = 0; + foreach (var stream in inputStreams) { - streamsVariableId = context.Bound++; + var typeId = compiler.Context.GetOrRegister(stream.Type); + var typePtrId = compiler.Context.GetOrRegister(new PointerType(stream.Type)); + var indexLiteral = new IntegerLiteral(new(32, false, true), inputFieldIndex++, new()); + indexLiteral.ProcessSymbol(table); + IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; + var accessChain = compiler.Builder.Buffer.AddOpAccessChain(compiler.Context.Bound++, typeId, inputParameter.ResultId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); + var loadedValue = compiler.Builder.Buffer.AddOpLoad(context.Bound++, context.Types[stream.Type], accessChain, null); + + compiler.Builder.Buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); } + + compiler.Builder.Buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); + + inputFieldIndex = 0; + foreach (var stream in outputStreams) + { + var loadedValue = compiler.Builder.Buffer.AddOpLoad(context.Bound++, context.Types[stream.Type], stream.Id, null); + var typeId = compiler.Context.GetOrRegister(stream.Type); + var typePtrId = compiler.Context.GetOrRegister(new PointerType(stream.Type)); + var indexLiteral = new IntegerLiteral(new(32, false, true), inputFieldIndex++, new()); + indexLiteral.ProcessSymbol(table); + IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; + var accessChain = compiler.Builder.Buffer.AddOpAccessChain(compiler.Context.Bound++, typeId, outputParameter.ResultId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); + + compiler.Builder.Buffer.AddOpStore(accessChain.ResultId!.Value, loadedValue.ResultId!.Value, null); + } + + var outputResult = compiler.Builder.Buffer.AddOpLoad(context.Bound++, outputStructId, outputParameter, null); + compiler.Builder.Buffer.AddOpReturnValue(outputResult); + compiler.Builder.Buffer.AddOpFunctionEnd(); } + context.SetEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", []); + } + + /// + /// Figure out (recursively) which streams are being read from and written to. + /// + private void ProcessMethod(SymbolTable table, CompilerUnit compiler, int functionId, SortedList streams) + { + var methodStart = FindMethodStart(compiler, functionId); + var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); + while (enumerator.MoveNext()) { var instruction = enumerator.Current; + if (instruction.OpCode == SDSLOp.OpFunctionEnd) + break; + if (instruction.OpCode == SDSLOp.OpLoad || instruction.OpCode == SDSLOp.OpStore) { var operandIndex = instruction.OpCode == SDSLOp.OpLoad ? 2 : 0; if (streams.TryGetValue(instruction.Operands[operandIndex], out var streamInfo)) { - if (streamInfo.FieldIndex == -1) - { - streamInfo.FieldIndex = totalActiveStreams++; - // First time, let's register it - } - - if (instruction.OpCode == SDSLOp.OpLoad && !streamInfo.Write) - streamInfo.Read = true; + // If read after a write (within same shader), we are not reading the variable from previous stage => not marking as Read + if (instruction.OpCode == SDSLOp.OpLoad && !streamInfo.Stream.Write) + streamInfo.Stream.Read = true; if (instruction.OpCode == SDSLOp.OpStore) - streamInfo.Write = true; - MarkStreamsUsed(); - - var typeId = compiler.Context.GetOrRegister(streamInfo.Type); - var typePtrId = compiler.Context.GetOrRegister(new PointerType(streamInfo.Type)); - var index = streamInfo.FieldIndex; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.ProcessSymbol(table); - IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; - var accessChain = compiler.Builder.Buffer.InsertOpAccessChain(instruction.WordIndex, compiler.Context.Bound++, typePtrId, streamsVariableId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); - - // Update OpLoad/OpStore to use the new OpAccessChain - enumerator.MoveNext(); - instruction = enumerator.Current; - instruction.Operands[operandIndex] = accessChain.ResultId!.Value; + streamInfo.Stream.Write = true; } } else if (instruction.OpCode == SDSLOp.OpAccessChain) @@ -150,86 +255,17 @@ void MarkStreamsUsed() { // Map the pointer access as access to the underlying stream (if any) // i.e., streams.A.B will share same streamInfo as streams.A - // TODO: need to store access chain, handle type info in OpStore/OpLoad, etc. - streams.Add(instruction.ResultId!.Value, streamInfo); - - // TODO: Add OpAccessChain entry - //throw new NotImplementedException(); + // TODO: what happens in case of partial write? + streams.Add(instruction.ResultId!.Value, (streamInfo.Stream, false)); } } else if (instruction.OpCode == SDSLOp.OpFunctionCall) { // Process call var calledFunctionId = instruction.Operands[2]; - if (ProcessMethod(table, compiler, calledFunctionId, false, streamStructPtrId, streams, ref totalActiveStreams)) - MarkStreamsUsed(); + ProcessMethod(table, compiler, calledFunctionId, streams); } } - - if (streamsVariableId != null) - { - enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); - - while (enumerator.MoveNext()) - { - var instruction = enumerator.Current; - - if (instruction.OpCode == SDSLOp.OpFunction) - { - // Entry point will add STREAMS as a variable - // For other functions, it will be passed through - if (isEntryPoint) - { - while ((instruction.OpCode == SDSLOp.OpFunction || instruction.OpCode == SDSLOp.OpFunctionParameter || instruction.OpCode == SDSLOp.OpLabel) && enumerator.MoveNext()) - instruction = enumerator.Current; - - var streamsVariable = compiler.Builder.Buffer.InsertOpVariable(instruction.WordIndex, streamsVariableId.Value, streamStructPtrId, Specification.StorageClass.Function, null); - enumerator.MoveNext(); - instruction = enumerator.Current; - - context.AddName(streamsVariable, "streams"); - - // Copy read variables from streams - foreach (var streamInfo in streams) - { - if (streamInfo.Value.Read) - { - var loadedValue = compiler.Builder.Buffer.InsertOpLoad(instruction.WordIndex, context.Bound++, context.Types[streamInfo.Value.Type], streamInfo.Key, null); - enumerator.MoveNext(); - instruction = enumerator.Current; - var typeId = compiler.Context.GetOrRegister(streamInfo.Value.Type); - var typePtrId = compiler.Context.GetOrRegister(new PointerType(streamInfo.Value.Type)); - var index = streamInfo.Value.FieldIndex; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.ProcessSymbol(table); - IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; - var accessChain = compiler.Builder.Buffer.InsertOpAccessChain(instruction.WordIndex, compiler.Context.Bound++, typeId, streamsVariableId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); - enumerator.MoveNext(); - instruction = enumerator.Current; - - compiler.Builder.Buffer.InsertOpStore(instruction.WordIndex, accessChain.ResultId!.Value, loadedValue.ResultId!.Value, null); - } - } - } - else - { - var functionType = context.Buffer.FindInstructionByResultId(instruction.Operands[3]); - Span parameterTypes = stackalloc IdRef[1 + functionType.Operands.Length - 2]; - parameterTypes[0] = streamStructPtrId; - for (int i = 0; i < functionType.Operands.Length - 2; ++i) - parameterTypes[i + 1] = instruction.Operands[2 + i]; - var newFunctionType = compiler.Context.Buffer.InsertOpTypeFunction(functionType.WordIndex + functionType.WordCount, context.Bound++, functionType.Operands[1], parameterTypes); - - // Update function type - instruction.Operands[3] = newFunctionType.ResultId!.Value; - - var streamsVariable = compiler.Builder.Buffer.InsertOpFunctionParameter(instruction.WordIndex + instruction.WordCount, streamsVariableId.Value, streamStructPtrId); - } - } - } - } - - return streamsVariableId != null; } public int FindMethodStart(CompilerUnit compiler, int functionId) From 26add6e6627bd62fa6ea0bcf5be222492ad5c6d4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 May 2025 12:58:35 +0900 Subject: [PATCH 0396/1182] Disassembler: avoid name clashes --- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 26 +++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 2757bd1f9e..8ff0981bcd 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -18,6 +18,8 @@ public partial struct SpirvDis int IdOffset { get; init; } bool UseNames { get; init; } + // avoid name collisions + private HashSet usedNames = []; SortedList nameTable = []; public SpirvDis(TBuffer buff, bool useNames = false) @@ -114,12 +116,12 @@ public readonly void CheckNameTable(RefInstruction instruction) && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n ) { - nameTable[t] = new(n.Value); + UpdateNameTable(t, n.Value); } else if (instruction.OpCode == SDSLOp.OpTypeVoid) - nameTable[instruction.ResultId!.Value] = new("void"); + UpdateNameTable(instruction.ResultId!.Value, "void"); else if (instruction.OpCode == SDSLOp.OpTypeBool) - nameTable[instruction.ResultId!.Value] = new("bool"); + UpdateNameTable(instruction.ResultId!.Value, "bool"); else if (instruction.OpCode == SDSLOp.OpTypeInt) { var type = instruction.Operands[1..] switch @@ -134,21 +136,33 @@ public readonly void CheckNameTable(RefInstruction instruction) [64, 1] => "long", _ => "int" }; - nameTable[instruction.ResultId!.Value] = new(type); + UpdateNameTable(instruction.ResultId!.Value, type); } else if (instruction.OpCode == SDSLOp.OpTypeFloat) { var size = instruction.Operands[1]; - nameTable[instruction.ResultId!.Value] = new(size switch {16 => "half", 32 => "float", 64 => "double", _ => throw new NotImplementedException()}); + UpdateNameTable(instruction.ResultId!.Value, size switch {16 => "half", 32 => "float", 64 => "double", _ => throw new NotImplementedException()}); } else if (instruction.OpCode == SDSLOp.OpTypeVector) { - nameTable[instruction.ResultId!.Value] = new(nameTable[instruction.Operands[1]].Name + instruction.Operands[2]); + UpdateNameTable(instruction.ResultId!.Value, nameTable[instruction.Operands[1]].Name + instruction.Operands[2]); } } + private readonly void UpdateNameTable(int id, string name) + { + if (!usedNames.Add(name)) + { + int extraId = 0; + var tentativeName = name; + while (!usedNames.Add(tentativeName)) + tentativeName = $"{name}_{extraId++}"; + name = tentativeName; + } + nameTable[id] = new(name); + } public readonly override string ToString() { From a317a9398d306adbd71f8383797141ae5806f56e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 May 2025 13:06:57 +0900 Subject: [PATCH 0397/1182] Better streams propagation --- .../Spirv/Processing/StreamAnalyzer.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index ac6b7a6004..9e036c9dab 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -48,23 +48,32 @@ public void Process(SymbolTable table, CompilerUnit compiler) var streams = CreateStreams(compiler); + // Expected at the end of pixel shader foreach (var stream in streams) { if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) stream.Value.Stream.Output = true; } - ProcessMethod(table, compiler, entryPointPS.Id, streams); - GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + + // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages + foreach (var stream in streams) + { + if (stream.Value.Stream.Semantic is { } semantic && (semantic == "SV_Coverage" || semantic == "SV_IsFrontFace" || semantic == "VFACE")) + stream.Value.Stream.Read = false; + } + PropagateStreamsFromPreviousStage(streams); + GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + } + + private static void PropagateStreamsFromPreviousStage(SortedList streams) + { foreach (var stream in streams) { stream.Value.Stream.Output = stream.Value.Stream.Read; stream.Value.Stream.Read = false; stream.Value.Stream.Write = false; } - ProcessMethod(table, compiler, entryPointVS.Id, streams); - - GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); } private SortedList CreateStreams(CompilerUnit compiler) @@ -119,6 +128,8 @@ public void Process(SymbolTable table, CompilerUnit compiler) private void GenerateStreamWrapper(SymbolTable table, CompilerUnit compiler, Specification.ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) { + ProcessMethod(table, compiler, entryPointId, streams); + var stage = executionModel switch { Specification.ExecutionModel.Fragment => "PS", From 1afe98010d214ddc25837a2d42369a06c18ef922 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 15:25:39 +0900 Subject: [PATCH 0398/1182] Removed StreamUsages --- src/Stride.Shaders/Core/StreamUsage.cs | 18 ------------------ src/Stride.Shaders/Core/SymbolFrame.cs | 1 - .../Parsing/SDSL/AST/Expression.cs | 2 -- 3 files changed, 21 deletions(-) delete mode 100644 src/Stride.Shaders/Core/StreamUsage.cs diff --git a/src/Stride.Shaders/Core/StreamUsage.cs b/src/Stride.Shaders/Core/StreamUsage.cs deleted file mode 100644 index 1be930f32c..0000000000 --- a/src/Stride.Shaders/Core/StreamUsage.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Stride.Shaders.Core; - - -public record struct StreamData(EntryPoint EntryPoint, StreamIO IO); - -public class StreamUsage -{ - Dictionary> usages { get; } = []; - - public List this[SymbolID id] => usages[id]; - - public bool ContainsKey(SymbolID symbolID) => usages.ContainsKey(symbolID); - public void Add(SymbolID symbolID, StreamData streamData) - { - if(!usages.TryAdd(symbolID, [streamData])) - usages[symbolID].Add(streamData); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 242604afe8..938471cd98 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -35,5 +35,4 @@ public bool TryGetValue(string name, SymbolKind kind, Storage storage, out Symbo public sealed class RootSymbolFrame : SymbolFrame { - public StreamUsage StreamUsages { get; } = new(); } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index d68bf22e38..a95a1a771f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -117,8 +117,6 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n if (Accessors.Count > 1) { ProcessAccessors(1); - - table.RootSymbols.StreamUsages.Add(new(streamVar, SymbolKind.Variable, Storage.Stream), new(entrypoint ?? EntryPoint.None, io ?? StreamIO.Output)); } } else From 5f0677d2a39b3d8addc05986dc2dbb785972a6cc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 16:20:32 +0900 Subject: [PATCH 0399/1182] Renamed RefMutableFunctionInstructionEnumerator.cs --- ...rator - Copy.cs => RefMutableFunctionInstructionEnumerator.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Stride.Shaders.Spirv.Core/Parsing/{RefInstructionEnumerator - Copy.cs => RefMutableFunctionInstructionEnumerator.cs} (100%) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs similarity index 100% rename from src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator - Copy.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs From 047eacc037e84f186fc97b4f71010adc34ae9d73 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 16:21:24 +0900 Subject: [PATCH 0400/1182] SpirvBuffer: properly set Length in ctor --- src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 04c08eefd5..9c929feebd 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -76,6 +76,7 @@ public SpirvBuffer(Memory memory) MagicNumber = Spv.Specification.MagicNumber, VersionNumber = new(1, 3) }; + Length = _owner.Length; } public SpirvBuffer(Span span) { @@ -86,6 +87,7 @@ public SpirvBuffer(Span span) MagicNumber = Spv.Specification.MagicNumber, VersionNumber = new(1, 3) }; + Length = _owner.Length; } From 91f43d3b28c8aa571e1171b89b87b09bd7ec5f06 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 16:22:43 +0900 Subject: [PATCH 0401/1182] External shaders (WIP) --- assets/SDSL/TestBase.sdsl | 11 +++ assets/SDSL/TestBasic.sdsl | 4 +- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 15 ++-- src/Stride.Shaders.Experiments/Examples.cs | 15 +++- .../Parsing/Analysis/SymbolTable.cs | 5 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 75 +++++++++++++++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 5 ++ 7 files changed, 119 insertions(+), 11 deletions(-) create mode 100644 assets/SDSL/TestBase.sdsl diff --git a/assets/SDSL/TestBase.sdsl b/assets/SDSL/TestBase.sdsl new file mode 100644 index 0000000000..3454dd7f10 --- /dev/null +++ b/assets/SDSL/TestBase.sdsl @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Tests; + +shader TestBase +{ + stream float4 ColorTarget : SV_Target0; + + void SetColor(float4 color) + { + streams.ColorTarget = color; + } +} \ No newline at end of file diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index c5806f49eb..babe7413cb 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -1,11 +1,10 @@ namespace Stride.Shaders.Tests; -shader TestBasic +shader TestBasic : TestBase { stream float4 InputPosition : POSITION; stream float4 Position : SV_POSITION; stream float4 ExtraColor : COLOR; - stream float4 ColorTarget : SV_Target0; void VSMain() { @@ -16,6 +15,7 @@ shader TestBasic void Test() { streams.ColorTarget = streams.ExtraColor; + SetColor(streams.ExtraColor); return; } diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index bca610df65..77079c6c0e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Compilers.SDSL; -public record struct SDSLC() : ICompiler +public record struct SDSLC(IExternalShaderLoader ShaderLoader) : ICompiler { public readonly bool Compile(string code, out byte[] compiled) { @@ -20,6 +20,7 @@ public readonly bool Compile(string code, out byte[] compiled) { SymbolTable table = new(); var shader = sf.Namespaces.First().Declarations.OfType().First(); + table.ShaderLoader = ShaderLoader; shader.ProcessSymbol(table); if(table.Errors.Count > 0) @@ -28,15 +29,15 @@ public readonly bool Compile(string code, out byte[] compiled) shader.Compile(compiler, table); // temp hack to add entry point (last function) - var context = compiler.Context; - context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); - context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); - new StreamAnalyzer().Process(table, compiler); + //var context = compiler.Context; + //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); + //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); + //new StreamAnalyzer().Process(table, compiler); compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); - var dis = new SpirvDis(merged, true); - dis.Disassemble(true); + //var dis = new SpirvDis(merged, true); + //dis.Disassemble(true); compiled = MemoryMarshal.AsBytes(merged.Span).ToArray(); return true; } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index c383a0a0e3..8dfeada024 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -8,6 +8,7 @@ using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Experiments; @@ -211,11 +212,23 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) return false; } + class ShaderLoader : IExternalShaderLoader + { + public bool LoadExternalReference(string name, out byte[] bytecode) + { + var text = MonoGamePreProcessor.OpenAndRun($"./assets/SDSL/{name}.sdsl"); + var sdslc = new SDSLC(); + sdslc.ShaderLoader = this; + return sdslc.Compile(text, out bytecode); + } + } + public static void CompileSDSL() { - var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestStruct.sdsl"); + var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestBasic.sdsl"); var sdslc = new SDSLC(); + sdslc.ShaderLoader = new ShaderLoader(); sdslc.Compile(text, out var bytecode); var code = new SpirvTranslator(bytecode.AsMemory().Cast()); Console.WriteLine(code.Translate(Backend.Hlsl)); diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index fbadade3e1..86b545603b 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -1,6 +1,7 @@ -using System.Runtime.InteropServices; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using System.Runtime.InteropServices; namespace Stride.Shaders.Parsing.Analysis; @@ -21,6 +22,8 @@ public partial class SymbolTable : ISymbolProvider public void Push() => CurrentFunctionSymbols?.Add(new()); + public IExternalShaderLoader ShaderLoader { get; set; } + public SymbolFrame? Pop() { var scope = CurrentFunctionSymbols?[^1]; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4159029332..d14d256228 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -2,6 +2,9 @@ using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -15,9 +18,81 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public ShaderParameterDeclarations? Generics { get; set; } public List Mixins { get; set; } = []; + public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out Dictionary names, out Dictionary types) + { + var memberNames = new Dictionary<(int, int), string>(); + names = new Dictionary(); + types = new Dictionary(); + foreach (var instruction in buffer) + { + if (instruction.OpCode == SDSLOp.OpName) + { + var nameInstruction = instruction.UnsafeAs(); + names.Add(nameInstruction.Target, nameInstruction.Name.Value); + } + else if (instruction.OpCode == SDSLOp.OpMemberName) + { + var nameInstruction = instruction.UnsafeAs(); + memberNames.Add((nameInstruction.Type, (int)nameInstruction.Member.Words), nameInstruction.Name.Value); + } + else if (instruction.OpCode == SDSLOp.OpTypeFloat) + { + var floatInstruction = instruction.UnsafeAs(); + if (floatInstruction.FloatingPointEncoding != 0) + throw new InvalidOperationException(); + + types.Add(floatInstruction.ResultId, floatInstruction.Width.Words switch + { + 16 => ScalarType.From("half"), + 32 => ScalarType.From("float"), + 64 => ScalarType.From("double"), + }); + } + else if (instruction.OpCode == SDSLOp.OpTypeVoid) + { + types.Add(instruction.ResultId!.Value, ScalarType.From("void")); + } + else if (instruction.OpCode == SDSLOp.OpTypeVector) + { + var vectorInstruction = instruction.UnsafeAs(); + var innerType = (ScalarType)types[vectorInstruction.ComponentType]; + types.Add(instruction.ResultId!.Value, new VectorType(innerType, (int)vectorInstruction.ComponentCount.Words)); + } + else if (instruction.OpCode == SDSLOp.OpTypeStruct) + { + var structInstruction = instruction.UnsafeAs(); + var structName = names[instruction.ResultId!.Value]; + var fields = new List<(string Name, SymbolType Type)>(); + throw new NotImplementedException(); + types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); + } + } + + return types; + } public override void ProcessSymbol(SymbolTable table) { + foreach (var mixin in Mixins) + { + table.ShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); + var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + + ProcessNameAndTypes(buffer, out var names, out var types); + foreach (var instruction in buffer) + { + if (instruction.OpCode == SDSLOp.OpVariable) + { + var variableInstruction = instruction.UnsafeAs(); + var variableName = names[variableInstruction.ResultId.Value]; + var variableType = types[variableInstruction.ResultType]; + + var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + table.RootSymbols.Add(sid, new(sid, variableType)); + } + } + } + foreach (var member in Elements) { if (member is ShaderMethod func) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9d5436fb31..333a525a85 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -8,6 +8,11 @@ namespace Stride.Shaders.Spirv.Building; +public interface IExternalShaderLoader +{ + public bool LoadExternalReference(string name, out byte[] bytecode); +} + // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters public class SpirvContext(SpirvModule module) : IDisposable From 3e628961f984486f8c4ad3fc6c8667caa858e3da Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 17:59:36 +0900 Subject: [PATCH 0402/1182] Removed ProcessSymbol unecessary parameters --- .../Parsing/SDSL/AST/Expression.cs | 20 +++++------ .../Parsing/SDSL/AST/Literals.cs | 14 ++++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Parsing/SDSL/AST/Statements.Control.cs | 24 ++++++------- .../Parsing/SDSL/AST/Statements.Flow.cs | 10 +++--- .../Parsing/SDSL/AST/Statements.cs | 36 +++++++++---------- 6 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index a95a1a771f..70b4c6bfac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -14,8 +14,6 @@ namespace Stride.Shaders.Parsing.SDSL.AST; ///
public abstract class Expression(TextLocation info) : ValueNode(info) { - public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null, null); - public virtual void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); public abstract SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); } @@ -24,10 +22,10 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public Identifier Name = name; public ShaderExpressionList Parameters = parameters; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table) { foreach (var p in parameters.Values) - p.ProcessSymbol(table, entrypoint, io); + p.ProcessSymbol(table); } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -106,12 +104,12 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table) { if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { //table.CurrentFunctionSymbols.Add(table.Streams); - streamVar.ProcessSymbol(table, entrypoint, io); + streamVar.ProcessSymbol(table); Type = streamVar.Type; if (Accessors.Count > 1) @@ -121,7 +119,7 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint = n } else { - Source.ProcessSymbol(table, entrypoint, io ?? StreamIO.Output); + Source.ProcessSymbol(table); Type = Source.Type; ProcessAccessors(0); } @@ -141,7 +139,7 @@ void ProcessAccessors(int firstIndex) else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); if(accessor is not Identifier) - accessor.ProcessSymbol(table, entrypoint, io ?? StreamIO.Input); + accessor.ProcessSymbol(table); } } } @@ -212,10 +210,10 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) { - Left.ProcessSymbol(table, entrypoint, io); - Right.ProcessSymbol(table, entrypoint, io); + Left.ProcessSymbol(table); + Right.ProcessSymbol(table); if ( OperatorTable.BinaryOperationResultingType( Left.Type ?? throw new NotImplementedException("Missing type"), diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 76eb204a67..26acae6947 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -54,7 +54,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) { Type = Suffix switch { @@ -86,7 +86,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) { Type = Suffix.Size switch { @@ -110,7 +110,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(32, false, false), (long)value, info) { - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) => Type = ScalarType.From("long"); } @@ -118,7 +118,7 @@ public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, St public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) => Type = ScalarType.From("bool"); public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -158,7 +158,7 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) { TypeName.ProcessSymbol(table); Type = TypeName.Type; @@ -205,7 +205,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table) { Span sOrder = [Storage.Function, Storage.Stream, Storage.Uniform, Storage.UniformConstant, Storage.Generic]; foreach (var storage in sOrder) @@ -299,7 +299,7 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public List? ArraySize { get; set; } public List Generics { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, EntryPoint? entryPoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table) { if (!IsArray && Generics.Count == 0) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 8de1f9ed81..50d7edc962 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -177,7 +177,7 @@ public override void ProcessSymbol(SymbolTable table) if (EntryPoint == 0) s.ProcessSymbol(table); else - s.ProcessSymbol(table, this, EntryPoint, null); + s.ProcessSymbol(table, this); table.Pop(); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 38994a3401..1a5968dfec 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -16,12 +16,12 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - If.ProcessSymbol(table, method, entrypoint, io); + If.ProcessSymbol(table, method); foreach (var ei in ElseIfs) - ei.ProcessSymbol(table, method, entrypoint, io); - Else?.ProcessSymbol(table, method, entrypoint, io); + ei.ProcessSymbol(table, method); + Else?.ProcessSymbol(table, method); } @@ -40,10 +40,10 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - Condition.ProcessSymbol(table, entrypoint, io); - Body.ProcessSymbol(table, method, entrypoint, io); + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table, method); if(Condition.Type != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); } @@ -60,10 +60,10 @@ public override string ToString() public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - Condition.ProcessSymbol(table, entrypoint, io); - Body.ProcessSymbol(table, method, entrypoint, io); + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table, method); if(Condition.Type != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); } @@ -81,9 +81,9 @@ public class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - Body.ProcessSymbol(table, method, entrypoint, io); + Body.ProcessSymbol(table, method); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index b3a4ea5535..23c9e1df67 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -9,7 +9,7 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -18,7 +18,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Discard(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -27,7 +27,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Continue(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) { } + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -43,7 +43,7 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public Expression Collection { get; set; } = collection; public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { Collection.ProcessSymbol(table); if(Collection.Type is ArrayType arrSym) @@ -71,7 +71,7 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public Statement Body { get; set; } = body; public ShaderAttribute? Attribute { get; internal set; } = attribute; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint, StreamIO? io) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { Condition.ProcessSymbol(table); Body.ProcessSymbol(table); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 464f2c1b38..ee61b79c1d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -9,8 +9,8 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Statement(TextLocation info) : ValueNode(info) { - public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null!, null); - public virtual void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); + public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null!); + public virtual void ProcessSymbol(SymbolTable table, ShaderMethod method) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); public abstract void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); } @@ -26,9 +26,9 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - Expression.ProcessSymbol(table, entrypoint, io); + Expression.ProcessSymbol(table); Type = ScalarType.From("void"); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -46,9 +46,9 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - Value?.ProcessSymbol(table, entrypoint, io); + Value?.ProcessSymbol(table); Type = Value?.Type ?? ScalarType.From("void"); } @@ -99,11 +99,11 @@ public List? ArraySizes set => TypeName.ArraySize = value; } - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { - TypeName.ProcessSymbol(table, entrypoint, io); + TypeName.ProcessSymbol(table); Variable.Type = TypeName.Type; - Value?.ProcessSymbol(table, entrypoint, io); + Value?.ProcessSymbol(table); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); } @@ -131,13 +131,13 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { if (TypeName == "var") { if (Variables.Count == 1 && Variables[0].Value is not null) { - Variables[0].Value?.ProcessSymbol(table, entrypoint, io); + Variables[0].Value?.ProcessSymbol(table); Type = Variables[0].Value!.Type; } else @@ -145,12 +145,12 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method, Entry } else { - TypeName.ProcessSymbol(table, entrypoint, io); + TypeName.ProcessSymbol(table); Type = TypeName.Type; table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); foreach (var d in Variables) { - d.Value?.ProcessSymbol(table, entrypoint, io); + d.Value?.ProcessSymbol(table); table.CurrentFrame.Add(new(d.Variable, SymbolKind.Variable, Storage.Function), new(new(d.Variable, SymbolKind.Variable), Type)); } } @@ -180,12 +180,12 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { foreach (var variable in Variables) { - variable.Variable.ProcessSymbol(table, entrypoint, io); - variable.Value!.ProcessSymbol(table, entrypoint, io); + variable.Variable.ProcessSymbol(table); + variable.Value!.ProcessSymbol(table); if (variable.Variable.Type is not PointerType) throw new InvalidOperationException("can only assign to pointer type"); @@ -222,10 +222,10 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method, EntryPoint? entrypoint = null, StreamIO? io = null) + public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { foreach (var s in Statements) - s.ProcessSymbol(table, method, entrypoint, io); + s.ProcessSymbol(table, method); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) From 2881d638cd0ea8c7d6c28effc11237e6f4097d39 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 May 2025 18:26:30 +0900 Subject: [PATCH 0403/1182] Simplified SymbolTable --- src/Stride.Shaders/Core/SymbolFrame.cs | 33 +++++++------------ .../Parsing/Analysis/SymbolTable.cs | 14 ++++---- .../Parsing/SDSL/AST/Literals.cs | 33 ++++++++----------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 6 ++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 ++- .../Parsing/SDSL/AST/ShaderElements.cs | 4 +-- .../Parsing/SDSL/AST/Statements.cs | 2 +- 7 files changed, 40 insertions(+), 56 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 938471cd98..4128e32554 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -2,35 +2,24 @@ namespace Stride.Shaders.Core; public class SymbolFrame() { - readonly Dictionary symbols = []; + readonly Dictionary symbols = []; - public Symbol this[string name, SymbolKind kind] + public Symbol this[string name] { - get => symbols[new(name, kind)]; - set => symbols[new(name, kind)] = value; - } - public Symbol this[SymbolID symbolID] - { - get => symbols[symbolID]; - set => symbols[symbolID] = value; + get => symbols[name]; + set => symbols[name] = value; } - public void Add(SymbolID name, Symbol symbol) + public void Add(string name, Symbol symbol) => symbols.Add(name, symbol); - public void Add(string name, SymbolKind kind, SymbolType type) - => symbols.Add(new(name, kind), new(new(name, kind), type)); - public bool TryAdd(string name, SymbolKind kind, SymbolType type) - => symbols.TryAdd(new(name, kind), new(new(name, kind), type)); - public void Remove(string name, SymbolKind kind) - => symbols.Remove(new(name, kind)); - public bool ContainsKey(SymbolID name) => symbols.ContainsKey(name); + public void Remove(string name) + => symbols.Remove(name); + public bool ContainsKey(string name) => symbols.ContainsKey(name); public bool ContainsValue(Symbol symbol) => symbols.ContainsValue(symbol); - public bool TryGetValue(string name, SymbolKind kind, out Symbol symbol) - => symbols.TryGetValue(new(name, kind), out symbol); - public bool TryGetValue(string name, SymbolKind kind, Storage storage, out Symbol symbol) - => symbols.TryGetValue(new(name, kind, storage), out symbol); + public bool TryGetValue(string name, out Symbol symbol) + => symbols.TryGetValue(name, out symbol); - public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); + public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); } public sealed class RootSymbolFrame : SymbolFrame diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 86b545603b..3f1cccc498 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -39,16 +39,14 @@ public void Import(ISymbolProvider symbols) RootSymbols.Add(name, symbol); } - public bool TryFind(string name, SymbolKind kind, out Symbol symbol) + public bool TryFind(string name, out Symbol symbol) { - if(CurrentFunctionSymbols is null) - return RootSymbols.TryGetValue(name, kind, out symbol); - - for (int i = CurrentFunctionSymbols.Count - 1; i >= 0; i--) - if (CurrentFunctionSymbols[i].TryGetValue(name, kind, out symbol)) - return true; - return RootSymbols.TryGetValue(name, kind, out symbol); + if (CurrentFunctionSymbols is not null) + for (int i = CurrentFunctionSymbols.Count - 1; i >= 0; i--) + if (CurrentFunctionSymbols[i].TryGetValue(name, out symbol)) + return true; + return RootSymbols.TryGetValue(name, out symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 26acae6947..81d7696db9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -207,31 +207,26 @@ public class Identifier(string name, TextLocation info) : Literal(info) public override void ProcessSymbol(SymbolTable table) { - Span sOrder = [Storage.Function, Storage.Stream, Storage.Uniform, Storage.UniformConstant, Storage.Generic]; - foreach (var storage in sOrder) + if (table.CurrentFunctionSymbols is not null) { - if (table.CurrentFunctionSymbols is not null) + for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; --i) { - for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; --i) + if (table.CurrentFunctionSymbols![i] + .TryGetValue(Name, out var symbol)) { - if (table.CurrentFunctionSymbols![i] - .TryGetValue(Name, SymbolKind.Variable, storage, out var symbol)) - { - if (symbol.Type is not UndefinedType and not null) - Type = symbol.Type; - else - Type = symbol.Type ?? new UndefinedType(Name); - return; - } + if (symbol.Type is not UndefinedType and not null) + Type = symbol.Type; + else + Type = symbol.Type ?? new UndefinedType(Name); + return; } } + } - if (table.RootSymbols.TryGetValue(Name, SymbolKind.Variable, storage, out var rootSymbol)) - { - Type = rootSymbol.Type; - return; - } - + if (table.RootSymbols.TryGetValue(Name, out var rootSymbol)) + { + Type = rootSymbol.Type; + return; } throw new NotImplementedException($"Cannot find symbol {Name}."); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index d14d256228..ea04d39a09 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -88,7 +88,7 @@ public override void ProcessSymbol(SymbolTable table) var variableType = types[variableInstruction.ResultType]; var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - table.RootSymbols.Add(sid, new(sid, variableType)); + table.RootSymbols.Add(sid.Name, new(sid, variableType)); } } } @@ -109,7 +109,7 @@ public override void ProcessSymbol(SymbolTable table) } func.Type = ftype; - table.RootSymbols.Add(new(func.Name, SymbolKind.Method), new(new(func.Name, SymbolKind.Method), func.Type)); + table.RootSymbols.Add(func.Name, new(new(func.Name, SymbolKind.Method), func.Type)); table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); } else if (member is ShaderMember svar) @@ -134,7 +134,7 @@ public override void ProcessSymbol(SymbolTable table) //} //else { - table.RootSymbols.Add(sid, symbol); + table.RootSymbols.Add(sid.Name, symbol); } table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 50d7edc962..e08d15535c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -90,6 +90,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) context.Buffer.AddOpSDSLDecorateSemantic(variable, Semantic.Name); + //if (Semantic != null) + // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); context.AddName(variable, Name); } @@ -166,7 +168,7 @@ public override void ProcessSymbol(SymbolTable table) arg.TypeName.ProcessSymbol(table); var argSym = arg.TypeName.Type; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - table.CurrentFrame.Add(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); + table.CurrentFrame.Add(arg.Name, new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); arg.Type = argSym; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 2becd50755..7f62768b35 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -140,7 +140,7 @@ public override void ProcessSymbol(SymbolTable table) RGroup => SymbolKind.RGroup, _ => throw new NotSupportedException() }; - table.RootSymbols.Add(new(Name.ToString() ?? "", kind), sym); + table.RootSymbols.Add(Name.ToString() ?? "", sym); foreach (var cbmem in Members) { cbmem.TypeName.ProcessSymbol(table); @@ -184,7 +184,7 @@ public override void ProcessSymbol(SymbolTable table) var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new StructType(TypeName.ToString() ?? "", fields)); table.DeclaredTypes.TryAdd(TypeName.ToString(), sym.Type); - table.RootSymbols.Add(new(TypeName.ToString() ?? "", SymbolKind.Struct), sym); + table.RootSymbols.Add(sym.Id.Name, sym); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index ee61b79c1d..f9be867717 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -151,7 +151,7 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method) foreach (var d in Variables) { d.Value?.ProcessSymbol(table); - table.CurrentFrame.Add(new(d.Variable, SymbolKind.Variable, Storage.Function), new(new(d.Variable, SymbolKind.Variable), Type)); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type)); } } } From 5fd04ada548057f1566f700080307d09ef8d6b38 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 31 May 2025 18:48:12 +0200 Subject: [PATCH 0404/1182] updating instruction info and structs --- .gitignore | 2 +- .../Information/InstructionInfo.cs | 37 ++++-- .../Stride.Shaders.Spirv.Core.csproj | 2 +- .../SPVGenerator.Instructions.cs | 123 ++++++++++++++---- .../SPVGenerator.cs | 7 +- 5 files changed, 133 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 413dc24dbf..b566b5b6bd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,4 @@ obj/ log*.txt *.vsix *.fsx -src/Stride.Shaders.Spirv.Core/Generated/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.SPVGenerator/Op*.Instruction.g.cs \ No newline at end of file +src/Stride.Shaders.Spirv.Core/Generated/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.SPVGenerator/*.Instruction.g.cs \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index e319faf3e6..038ce82f82 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -8,6 +8,11 @@ namespace Stride.Shaders.Spirv.Core; +public record struct OperandKey(SDSLOp Op, Decoration? Decoration = null) +{ + public static implicit operator OperandKey(SDSLOp op) => new(op); +} + /// /// Singleton object containing informations on every spirv instructions, used for spirv parsing. @@ -15,8 +20,26 @@ namespace Stride.Shaders.Spirv.Core; public partial class InstructionInfo { public static InstructionInfo Instance { get; } = new(); - Dictionary Info = new(); - InstructionInfo(){} + readonly Dictionary Info = []; + InstructionInfo() + { + Info.Add(new(SDSLOp.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Location), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Index), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); + #warning needs more information + } /// /// Register information about a SPIR-V instruction /// @@ -25,23 +48,19 @@ public partial class InstructionInfo /// /// /// - internal void Register(SDSLOp op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) + internal void Register(OperandKey op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) { - if(Info.TryGetValue(op, out var list)) - { + if (Info.TryGetValue(op, out var list)) list.Add(new(kind, quantifier, name)); - } else - { Info.Add(op, new(spvClass, [new(kind, quantifier, name)])); - } } /// /// Gets information for the instruction operation. /// /// /// - public static LogicalOperandArray GetInfo(SDSLOp op) + public static LogicalOperandArray GetInfo(OperandKey op) { return Instance.Info[op]; } diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 5a52639b6b..cab36fe85d 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 64218b122d..5a47cef62d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -64,9 +64,75 @@ public void GenerateStructs(IncrementalGeneratorInitializationContext context) .SelectMany((grammar, _) => grammar!.Instructions ?? []) .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); + IncrementalValuesProvider glslInstructionsData = + context.AdditionalTextsProvider + .Where(file => Path.GetFileName(file.Path) == "extinst.glsl.std.450.grammar.json" ) + .Select((file, _) => file.GetText()?.ToString()) + .Where(text => text is not null) + .Select((text, _) => + { + var result = JsonSerializer.Deserialize(text!, options); + if (result is SpirvGrammar grammar) + { + var list = new List(24); + var dict = spirvCore!.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); + if (grammar.Instructions is List instructions) + { + for (int i = 0; i < instructions.Count; i++) + { + list.Clear(); + if (instructions[i].Operands is EquatableArray operands) + { + foreach (var op in operands) + list.Add(op with { Class = dict[op.Kind] }); + instructions[i] = instructions[i] with { Operands = list }; + } + } + } + } + return result; + }) + .SelectMany((grammar, _) => grammar!.Instructions ?? []) + .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); + + IncrementalValuesProvider sdslInstructionsData = + context.AdditionalTextsProvider + .Where(file => Path.GetFileName(file.Path) == "spirv.sdsl.grammar-ext.json") + .Select((file, _) => file.GetText()?.ToString()) + .Where(text => text is not null) + .Select((text, _) => + { + var result = JsonSerializer.Deserialize(text!, options); + if (result is SpirvGrammar grammar) + { + var list = new List(24); + var dict = spirvCore!.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); + if (grammar.Instructions is List instructions) + { + for (int i = 0; i < instructions.Count; i++ ) + { + list.Clear(); + if (instructions[i].Operands is EquatableArray operands) + { + foreach (var op in operands) + list.Add(op with { Class = dict[op.Kind] }); + instructions[i] = instructions[i] with { Operands = list }; + } + } + } + } + return result; + }) + .SelectMany((grammar, _) => grammar!.Instructions ?? []) + .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); + context.RegisterImplementationSourceOutput(instructionsData, static (spc, source) => Execute(source, spc)); + context.RegisterImplementationSourceOutput(glslInstructionsData, + static (spc, source) => Execute(source, spc)); + context.RegisterImplementationSourceOutput(sdslInstructionsData, + static (spc, source) => Execute(source, spc)); } @@ -82,41 +148,48 @@ public static void Execute(InstructionData instruction, SourceProductionContext .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") .AppendLine("{") .AppendLine("public RefInstruction Inner { get; set; }"); - if (instruction.Operands != null) + try { - foreach (var operand in instruction.Operands) + if (instruction.Operands != null) { - string fieldName; - string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - if (operand.Name is null or "") - fieldName = ConvertKindToName(operand.Kind, false); - else + foreach (var operand in instruction.Operands) { - var nameBuilder = new StringBuilder(); - bool first = true; - foreach (var c in operand.Name) + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else { - if (char.IsLetterOrDigit(c) || c == '_') + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } + } + fieldName = nameBuilder.ToString(); } - fieldName = nameBuilder.ToString(); + if (operand.Kind == "LiteralContextDependentNumber") + continue; + else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); + else if (operand.Class == "BitEnum") + builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); + else if (operand.Class == "ValueEnum") + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); + else + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); } - if (operand.Kind == "LiteralContextDependentNumber") - continue; - else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); - else if (operand.Class == "BitEnum") - builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); - else if (operand.Class == "ValueEnum") - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); - else - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); } } + catch (Exception e) + { + builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); + } builder diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 254c67b3b3..821f563441 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -50,7 +50,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) string resourceGlslRegistryName = assembly.GetManifestResourceNames() .Single(str => str.EndsWith("GLSL.std.450.html")); - + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) options.Converters.Add(new EquatableArrayJsonConverter()); @@ -58,7 +58,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context) spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd(), options); spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd(), options); - GenerateStructs(context); var config = Configuration.Default.WithDefaultLoader(); var htmlContext = BrowsingContext.New(config); @@ -75,6 +74,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) CreateInfo(context); CreateSDSLOp(context); + var code = new StringBuilder(); code @@ -100,6 +100,9 @@ public void Initialize(IncrementalGeneratorInitializationContext context) "SpirvBufferExtensions.gen.cs", code.ToSourceText()); }); + + GenerateStructs(context); + } public static string AddDocComment(IHtmlCollection? cells) From 3fbd116b641dfd9341de091d9ba9dfabf0980ed1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 Jun 2025 15:20:15 +0200 Subject: [PATCH 0405/1182] Corrections on decoration disassembly --- src/Stride.Shaders.Experiments/Program.cs | 12 +- .../Information/InstructionInfo.cs | 68 +++++-- .../Parsing/OperandEnumerator.cs | 173 +++++++----------- .../RefInstruction.cs | 13 +- .../Extensions/spirv.sdsl.enum-ext.json | 13 ++ src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 3 +- test.spv | Bin 0 -> 996 bytes 7 files changed, 139 insertions(+), 143 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json create mode 100644 test.spv diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index d012d56a1c..089615cebc 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -5,13 +5,11 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; +using static Spv.Specification; -Examples.CompileSDSL(); +// Examples.CompileSDSL(); // Examples.TryAllFiles(); -// Examples.CreateShader(); +Examples.CreateShader(); -var buffer = new SpirvBuffer(32); - -var i = buffer.AddOpTypeFloat(0, 32, null); -var fl = i.UnsafeAs(); -Console.WriteLine(fl.Width); \ No newline at end of file +var buffer = new SpirvBuffer(32); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index 038ce82f82..c8cc7e6044 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -23,22 +23,56 @@ public partial class InstructionInfo readonly Dictionary Info = []; InstructionInfo() { - Info.Add(new(SDSLOp.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Location), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Index), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); - #warning needs more information + Info.Add(new(SDSLOp.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + } /// /// Register information about a SPIR-V instruction @@ -62,6 +96,8 @@ internal void Register(OperandKey op, OperandKind? kind, OperandQuantifier? quan /// public static LogicalOperandArray GetInfo(OperandKey op) { + if(op.Decoration is not null && !Instance.Info.ContainsKey(op)) + return Instance.Info[op with { Decoration = null }]; return Instance.Info[op]; } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index 5454c681ae..19b9a02a75 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -17,7 +17,18 @@ public ref struct OperandEnumerator public OperandEnumerator(RefInstruction instruction) { this.instruction = instruction; - logicalOperands = InstructionInfo.GetInfo(instruction.OpCode); + Decoration? decoration = instruction.OpCode switch + { + SDSLOp.OpDecorateString + or SDSLOp.OpDecorateStringGOOGLE + or SDSLOp.OpDecorate + or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], + SDSLOp.OpMemberDecorate + or SDSLOp.OpMemberDecorateString + or SDSLOp.OpMemberDecorateStringGOOGLE => (Decoration)instruction.Operands[2], + _ => null + }; + logicalOperands = InstructionInfo.GetInfo(new(instruction.OpCode, decoration)); oid = -1; wid = 0; } @@ -33,72 +44,13 @@ public bool MoveNext() return false; return true; } + else if(oid >= logicalOperands.Count - 1) + return false; else { - var logOp = logicalOperands[oid]; - if (instruction.OpCode == SDSLOp.OpDecorate) - { - if (oid == 0) - { - wid += 1; - oid += 1; - return true; - } - else if (oid > 0) - { - var builtin = (Decoration)operands[1]; - bool has2Extra = builtin == Decoration.LinkageAttributes; - bool has1Extra = - builtin == Decoration.BuiltIn - || builtin == Decoration.Location - || builtin == Decoration.SpecId - || builtin == Decoration.ArrayStride - || builtin == Decoration.MatrixStride - || builtin == Decoration.UniformId - || builtin == Decoration.Stream - || builtin == Decoration.Component - || builtin == Decoration.Index - || builtin == Decoration.Binding - || builtin == Decoration.DescriptorSet - || builtin == Decoration.Offset - || builtin == Decoration.XfbBuffer - || builtin == Decoration.XfbStride - || builtin == Decoration.FuncParamAttr - || builtin == Decoration.FPRoundingMode - || builtin == Decoration.FPFastMathMode - || builtin == Decoration.LinkageAttributes - || builtin == Decoration.InputAttachmentIndex - || builtin == Decoration.Alignment - || builtin == Decoration.MaxByteOffset - || builtin == Decoration.AlignmentId - || builtin == Decoration.MaxByteOffsetId - || builtin == Decoration.SecondaryViewportRelativeNV - || builtin == Decoration.CounterBuffer; - if (has1Extra && oid == 1 && !has2Extra) - { - wid += 1; - oid += 1; - } - else if (has2Extra) - { - throw new NotImplementedException(); - } - else - { - return false; - } - - } - - oid += 1; - if (oid > 2) - return false; - else - return wid < operands.Length; - } - else if (logOp.Quantifier == OperandQuantifier.One) + if (logOp.Quantifier == OperandQuantifier.One) { if (logOp.Kind == OperandKind.LiteralString) { @@ -151,8 +103,6 @@ public bool MoveNext() oid += 1; } - if (oid >= logicalOperands.Count) - return false; return wid < operands.Length; } @@ -161,52 +111,53 @@ public bool MoveNext() public SpvOperand ParseCurrent() { var logOp = logicalOperands[oid]; - if (instruction.OpCode == SDSLOp.OpDecorate) - { - SpvOperand result = new(); - if (oid == 0) - result = new(OperandKind.IdRef, OperandQuantifier.One, operands.Slice(wid, 1)); - else if (oid == 1) - result = new(OperandKind.Decoration, OperandQuantifier.One, operands.Slice(wid, 1)); - else if (oid == 2) - { - result = result with - { - Kind = (Decoration)operands[1] switch - { - Decoration.BuiltIn => OperandKind.BuiltIn, - Decoration.Location => OperandKind.LiteralInteger, - Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, - Decoration.ArrayStride => OperandKind.LiteralInteger, - Decoration.MatrixStride => OperandKind.LiteralInteger, - Decoration.UniformId => OperandKind.IdScope, - Decoration.Stream => OperandKind.LiteralInteger, - Decoration.Component => OperandKind.LiteralInteger, - Decoration.Index => OperandKind.LiteralInteger, - Decoration.Binding => OperandKind.LiteralInteger, - Decoration.DescriptorSet => OperandKind.LiteralInteger, - Decoration.Offset => OperandKind.LiteralInteger, - Decoration.XfbBuffer => OperandKind.LiteralInteger, - Decoration.XfbStride => OperandKind.LiteralInteger, - Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, - Decoration.FPRoundingMode => OperandKind.FPRoundingMode, - Decoration.FPFastMathMode => OperandKind.FPFastMathMode, - Decoration.LinkageAttributes => OperandKind.LiteralString, - Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, - Decoration.Alignment => OperandKind.LiteralInteger, - Decoration.MaxByteOffset => OperandKind.LiteralInteger, - Decoration.AlignmentId => OperandKind.IdRef, - Decoration.MaxByteOffsetId => OperandKind.IdRef, - Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, - Decoration.CounterBuffer => OperandKind.IdRef, - _ => OperandKind.None - } - }; - } - return result; - - } - else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) + // if (instruction.OpCode == SDSLOp.OpDecorate) + // { + // SpvOperand result = new(); + // if (oid == 0) + // result = new(OperandKind.IdRef, OperandQuantifier.One, operands.Slice(wid, 1)); + // else if (oid == 1) + // result = new(OperandKind.Decoration, OperandQuantifier.One, operands.Slice(wid, 1)); + // else if (oid == 2) + // { + // result = result with + // { + // Kind = (Decoration)operands[1] switch + // { + // Decoration.BuiltIn => OperandKind.BuiltIn, + // Decoration.Location => OperandKind.LiteralInteger, + // Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, + // Decoration.ArrayStride => OperandKind.LiteralInteger, + // Decoration.MatrixStride => OperandKind.LiteralInteger, + // Decoration.UniformId => OperandKind.IdScope, + // Decoration.Stream => OperandKind.LiteralInteger, + // Decoration.Component => OperandKind.LiteralInteger, + // Decoration.Index => OperandKind.LiteralInteger, + // Decoration.Binding => OperandKind.LiteralInteger, + // Decoration.DescriptorSet => OperandKind.LiteralInteger, + // Decoration.Offset => OperandKind.LiteralInteger, + // Decoration.XfbBuffer => OperandKind.LiteralInteger, + // Decoration.XfbStride => OperandKind.LiteralInteger, + // Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, + // Decoration.FPRoundingMode => OperandKind.FPRoundingMode, + // Decoration.FPFastMathMode => OperandKind.FPFastMathMode, + // Decoration.LinkageAttributes => OperandKind.LiteralString, + // Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, + // Decoration.Alignment => OperandKind.LiteralInteger, + // Decoration.MaxByteOffset => OperandKind.LiteralInteger, + // Decoration.AlignmentId => OperandKind.IdRef, + // Decoration.MaxByteOffsetId => OperandKind.IdRef, + // Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, + // Decoration.CounterBuffer => OperandKind.IdRef, + // _ => OperandKind.None + // } + // }; + // } + // return result; + + // } + // else + if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) { if (logOp.Kind == OperandKind.LiteralString) { diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index 104ee32f74..63fd719156 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -138,11 +138,10 @@ public static RefInstruction ParseRef(Span words, int? wordIndex = null, in public int? GetResultId() { - foreach (var o in this) - if (o.Kind == OperandKind.IdResult) - return o.Words[0]; - return null; + TryGetOperand("resultId", out var resultId); + return resultId; } + public void SetResultId(int? value) { foreach (var o in this) @@ -151,10 +150,8 @@ public void SetResultId(int? value) } public int? GetResultType() { - foreach (var o in this) - if (o.Kind == OperandKind.IdResultType) - return o.Words[0]; - return null; + TryGetOperand("resultType", out var resultId); + return resultId; } public void SetResultType(int? value) { diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json new file mode 100644 index 0000000000..ab8af2bbe4 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json @@ -0,0 +1,13 @@ +{ + "extensions": [ + { + "name": "ExecutionModel", + "values": [ + { + "name": "SDSL", + "description": "SDSL execution model" + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 0345c346a2..e869307626 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core; using static Spv.Specification; +using System.Runtime.CompilerServices; namespace Stride.Shaders.Spirv.Tools; @@ -12,7 +13,7 @@ public partial struct SpirvDis where TBuffer : ISpirvBuffer { - public readonly static int MAX_OFFSET = 16; + public readonly static int MAX_OFFSET = 16; TBuffer buffer; DisWriter writer = new(); int IdOffset { get; init; } diff --git a/test.spv b/test.spv new file mode 100644 index 0000000000000000000000000000000000000000..13083ba0bb816d7245b27b458f2e1b4518fc6829 GIT binary patch literal 996 zcmYk4NlF7@5Jt@H}-ujg@RL|oA=)vw_z zDP|92WuASE-2-{!Xr)|hEY-eZx7pX2wa%YJuL8xK?>q`7VaS={nW0-ey_2yS>^^i8 zOcSjZHY)e~3*WgdnBL7;!Ynm|`1Y`8ljl&8H@=5&ZWu&-T_%47@9w*n`_6PvdHZy> zt_G|Ta@9-p^2X-nH>mK2)*E-H1{`ma;_fqn@4FhmD12{a%zdnz0=}dCX|y@}npe*N z#r!PVJGzJc^!?9_nV(17E9Le52aTn9i`Yu?m$02_{c>TK>;0D2oA;kh_fPdrV&30< zoYw;KPq>lXRiOC&PTAC$|5mcsv47ZL1N~XlY!)1If8_Mf=xR@Q-2#ept=&eSb1i%C N0B8DM;+HyW{{hzfBkKSF literal 0 HcmV?d00001 From 581941e052ed75def0612429d65ed4653e7f7bfe Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Jun 2025 12:20:37 +0900 Subject: [PATCH 0406/1182] Work on module import --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 +- src/Stride.Shaders.Experiments/Examples.cs | 37 +++++- .../Information/InstructionInfo.Order.cs | 5 +- .../Extensions/spirv.sdsl.grammar-ext.json | 66 ++++------- src/Stride.Shaders/Core/Symbol.cs | 3 +- .../Parsing/Analysis/SymbolTable.cs | 24 ++-- .../Parsing/SDSL/AST/Expression.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 29 ++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 106 +++++++++++++++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Spirv/Building/Builder.Expressions.cs | 4 +- .../Spirv/Building/Builder.Functions.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 10 +- src/Stride.Shaders/Spirv/Building/Module.cs | 9 +- .../Spirv/Processing/StreamAnalyzer.cs | 10 +- 15 files changed, 198 insertions(+), 117 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 77079c6c0e..d53ca937b0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -36,8 +36,8 @@ public readonly bool Compile(string code, out byte[] compiled) compiler.Context.Buffer.Sort(); var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); - //var dis = new SpirvDis(merged, true); - //dis.Disassemble(true); + var dis = new SpirvDis(merged, true); + dis.Disassemble(true); compiled = MemoryMarshal.AsBytes(merged.Span).ToArray(); return true; } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 8dfeada024..2ac1f337a0 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -1,14 +1,18 @@ -using System.Text; using CommunityToolkit.HighPerformance; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Compilers; -using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Compilers.Direct3D; +using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using System.Text; +using Stride.Shaders.Spirv.Processing; namespace Stride.Shaders.Experiments; @@ -76,6 +80,7 @@ public static void UseSpirvCross() unsafe { var code = new SpirvTranslator(words.AsMemory()); + File.WriteAllBytes("shader.bin", words.SelectMany(x => BitConverter.GetBytes(x).Reverse()).ToArray()); Console.WriteLine(code.Translate(Backend.Hlsl)); } } @@ -214,8 +219,14 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) class ShaderLoader : IExternalShaderLoader { - public bool LoadExternalReference(string name, out byte[] bytecode) + public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode) { + var filename = $"./assets/SDSL/{name}.sdsl"; + if (!File.Exists(filename)) + { + bytecode = null; + return false; + } var text = MonoGamePreProcessor.OpenAndRun($"./assets/SDSL/{name}.sdsl"); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; @@ -230,8 +241,26 @@ public static void CompileSDSL() var sdslc = new SDSLC(); sdslc.ShaderLoader = new ShaderLoader(); sdslc.Compile(text, out var bytecode); + + File.WriteAllBytes("shader.bin", bytecode); + var test = bytecode.AsMemory().Cast().ToArray(); var code = new SpirvTranslator(bytecode.AsMemory().Cast()); - Console.WriteLine(code.Translate(Backend.Hlsl)); + //Console.WriteLine(code.Translate(Backend.Hlsl)); + + } + + public static void MergeSDSL() + { + CompileSDSL(); + + new ShaderLoader().LoadExternalReference("TestBasic", out var bytecode); + var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + + + //var context = compiler.Context; + //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); + //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); + //new StreamAnalyzer().Process(table, compiler); } } diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 5a682b5a63..b98b3f2012 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -25,9 +25,8 @@ void InitOrder() int group = 0; Span initSDSL = [ SDSLOp.OpNop, - SDSLOp.OpSDSLMixinName, + SDSLOp.OpSDSLShader, SDSLOp.OpCapability, - SDSLOp.OpSDSLMixinOffset, SDSLOp.OpSDSLMixinInherit, SDSLOp.OpSDSLCompose ]; @@ -89,7 +88,7 @@ void InitOrder() OrderGroup[(e, null)] = group; OrderGroup[(SDSLOp.OpVariable, StorageClass.Function)] = group; group++; - OrderGroup[(SDSLOp.OpSDSLMixinEnd, null)] = group; + OrderGroup[(SDSLOp.OpSDSLShaderEnd, null)] = group; } /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json index 2f3b11e90e..f63c930b3f 100644 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -15,36 +15,26 @@ ] }, { - "opname": "OpSDSLMixinName", + "opname": "OpSDSLShader", "class": "Miscellaneous", "operands": [ { "kind": "LiteralString", - "name": "mixinName" + "name": "shaderName" } ] }, { - "opname": "OpSDSLMixinEnd", + "opname": "OpSDSLShaderEnd", "class": "Miscellaneous" }, - { - "opname": "OpSDSLMixinOffset", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralInteger", - "name": "mixinName" - } - ] - }, { "opname": "OpSDSLMixinInherit", "class": "Miscellaneous", "operands": [ { - "kind": "LiteralString", - "name": "mixinName" + "kind": "IdRef", + "name": "shader" } ] }, @@ -73,7 +63,7 @@ ] }, { - "opname": "OpSDSLImportFunction", + "opname": "OpSDSLImportShader", "class": "Miscellaneous", "operands": [ { @@ -81,57 +71,39 @@ }, { "kind": "LiteralString", - "name": "functionName" - }, - { - "kind": "LiteralString", - "name": "mixinName" - }, - { - "kind": "LiteralInteger", - "name": "id" - }, - { - "kind": "LiteralInteger", - "name": "typeId" + "name": "shaderName" } ] }, { - "opname": "OpSDSLImportVariable", + "opname": "OpSDSLImportFunction", "class": "Miscellaneous", "operands": [ - { - "kind": "IdResult" - }, - { - "kind": "LiteralString", - "name": "variableName" - }, + { "kind": "IdResultType" }, + { "kind": "IdResult" }, { "kind": "LiteralString", - "name": "mixinName" + "name": "functionName" }, { - "kind": "LiteralInteger", - "name": "id" + "kind": "IdRef", + "name": "shader" } ] }, { - "opname": "OpSDSLImportIdRef", + "opname": "OpSDSLImportVariable", "class": "Miscellaneous", "operands": [ - { - "kind": "IdResult" - }, + { "kind": "IdResultType" }, + { "kind": "IdResult" }, { "kind": "LiteralString", - "name": "mixinName" + "name": "variableName" }, { - "kind": "LiteralInteger", - "name": "id" + "kind": "IdRef", + "name": "shader" } ] }, diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 87691b123c..d0cbc9fa37 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -5,8 +5,7 @@ namespace Stride.Shaders.Core; public enum SymbolKind { - MixinParent, - MixinChild, + Shader, Struct, Method, Variable, diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 3f1cccc498..585647ddaf 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -11,23 +11,29 @@ public record struct SemanticErrors(TextLocation Location, string Message); public partial class SymbolTable : ISymbolProvider { public Dictionary DeclaredTypes { get; } = []; - public SymbolFrame CurrentFrame => CurrentFunctionSymbols[^1]; + public SymbolFrame CurrentFrame => CurrentSymbols[^1]; public RootSymbolFrame RootSymbols { get; } = new(); public SymbolFrame Streams { get; } = new(); - public SortedList> FunctionSymbols { get; } = []; public List Errors { get; } = []; - public List? CurrentFunctionSymbols { get; internal set; } + public List CurrentSymbols { get; } = new(); - public void Push() => CurrentFunctionSymbols?.Add(new()); + public SymbolTable() + { + Push(RootSymbols); + } + + public void Push() => CurrentSymbols.Add(new()); + + public void Push(SymbolFrame symbolFrame) => CurrentSymbols.Add(symbolFrame); public IExternalShaderLoader ShaderLoader { get; set; } public SymbolFrame? Pop() { - var scope = CurrentFunctionSymbols?[^1]; - CurrentFunctionSymbols?.RemoveAt(CurrentFunctionSymbols.Count - 1); + var scope = CurrentSymbols?[^1]; + CurrentSymbols?.RemoveAt(CurrentSymbols.Count - 1); return scope; } @@ -42,9 +48,9 @@ public void Import(ISymbolProvider symbols) public bool TryFind(string name, out Symbol symbol) { - if (CurrentFunctionSymbols is not null) - for (int i = CurrentFunctionSymbols.Count - 1; i >= 0; i--) - if (CurrentFunctionSymbols[i].TryGetValue(name, out symbol)) + if (CurrentSymbols is not null) + for (int i = CurrentSymbols.Count - 1; i >= 0; i--) + if (CurrentSymbols[i].TryGetValue(name, out symbol)) return true; return RootSymbols.TryGetValue(name, out symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 70b4c6bfac..07a048b1d1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -108,7 +108,7 @@ public override void ProcessSymbol(SymbolTable table) { if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { - //table.CurrentFunctionSymbols.Add(table.Streams); + //table.CurrentSymbols.Add(table.Streams); streamVar.ProcessSymbol(table); Type = streamVar.Type; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 81d7696db9..5c2aaf5ef1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -207,39 +207,34 @@ public class Identifier(string name, TextLocation info) : Literal(info) public override void ProcessSymbol(SymbolTable table) { - if (table.CurrentFunctionSymbols is not null) + for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) { - for (int i = table.CurrentFunctionSymbols.Count - 1; i >= 0; --i) + if (table.CurrentSymbols![i] + .TryGetValue(Name, out var symbol)) { - if (table.CurrentFunctionSymbols![i] - .TryGetValue(Name, out var symbol)) - { - if (symbol.Type is not UndefinedType and not null) - Type = symbol.Type; - else - Type = symbol.Type ?? new UndefinedType(Name); - return; - } + if (symbol.Type is not UndefinedType and not null) + Type = symbol.Type; + else + Type = symbol.Type ?? new UndefinedType(Name); + return; } } - if (table.RootSymbols.TryGetValue(Name, out var rootSymbol)) - { - Type = rootSymbol.Type; - return; - } throw new NotImplementedException($"Cannot find symbol {Name}."); } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, _, _) = compiler; + var (builder, context, _) = compiler; if(builder.CurrentFunction is SpirvFunction f) { if(f.Variables.TryGetValue(Name, out var resultVar)) return resultVar; else if(f.Parameters.TryGetValue(Name, out var paramVar)) return paramVar; + + if (context.Module.InheritedVariables.TryGetValue(Name, out var externalVar)) + return externalVar; } if (compiler.Context.Variables.TryGetValue(Name, out var variable)) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index ea04d39a09..7610a7d663 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -60,39 +60,78 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D } else if (instruction.OpCode == SDSLOp.OpTypeStruct) { - var structInstruction = instruction.UnsafeAs(); + var typeStructInstruction = instruction.UnsafeAs(); var structName = names[instruction.ResultId!.Value]; var fields = new List<(string Name, SymbolType Type)>(); throw new NotImplementedException(); types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); } + else if (instruction.OpCode == SDSLOp.OpTypeFunction) + { + var typeFunctionInstruction = instruction.UnsafeAs(); + var returnType = types[typeFunctionInstruction.ReturnType]; + var parameterTypes = new List(); + foreach (var operand in instruction.Operands[2..]) + { + parameterTypes.Add(types[operand]); + } + types.Add(instruction.ResultId!.Value, new FunctionType(returnType, parameterTypes)); + } } return types; } - public override void ProcessSymbol(SymbolTable table) + private ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) { - foreach (var mixin in Mixins) + externalShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); + var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + + ProcessNameAndTypes(buffer, out var names, out var types); + + var symbols = new List(); + foreach (var instruction in buffer) { - table.ShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); - var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + if (instruction.OpCode == SDSLOp.OpVariable) + { + var variableInstruction = instruction.UnsafeAs(); + var variableName = names[variableInstruction.ResultId.Value]; + var variableType = types[variableInstruction.ResultType]; - ProcessNameAndTypes(buffer, out var names, out var types); - foreach (var instruction in buffer) + var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + symbols.Add(new(sid, variableType)); + } + + if (instruction.OpCode == SDSLOp.OpFunction) { - if (instruction.OpCode == SDSLOp.OpVariable) - { - var variableInstruction = instruction.UnsafeAs(); - var variableName = names[variableInstruction.ResultId.Value]; - var variableType = types[variableInstruction.ResultType]; + var functionInstruction = instruction.UnsafeAs(); + var functionName = names[functionInstruction.ResultId.Value]; + var functionType = types[functionInstruction.FunctionType]; - var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - table.RootSymbols.Add(sid.Name, new(sid, variableType)); - } + var sid = new SymbolID(functionName, SymbolKind.Method); + symbols.Add(new(sid, functionType)); } } + var shaderType = new ShaderSymbol(mixin.Name, symbols); + return shaderType; + } + + public override void ProcessSymbol(SymbolTable table) + { + table.Push(); + foreach (var mixin in Mixins) + { + var shaderType = LoadShader(table.ShaderLoader, mixin); + + var sid2 = new SymbolID(mixin.Name, SymbolKind.Shader); + table.RootSymbols.Add(mixin.Name, new(new SymbolID(mixin.Name, SymbolKind.Shader), shaderType)); + + // Register members + foreach (var symbol in shaderType.Components) + table.CurrentFrame.Add(symbol.Id.Name, symbol); + } + foreach (var member in Elements) { if (member is ShaderMethod func) @@ -154,13 +193,46 @@ public override void ProcessSymbol(SymbolTable table) if (member is not ShaderMember) member.ProcessSymbol(table); } + table.Pop(); } public void Compile(CompilerUnit compiler, SymbolTable table) { - compiler.Context.PutMixinName(Name); - foreach(var member in Elements.OfType()) + var (builder, context, _) = compiler; + context.PutShaderName(Name); + + foreach (var mixin in Mixins) + { + // Import types and variables/functions + var shader = context.Buffer.AddOpSDSLImportShader(context.Bound++, new(mixin.Name)); + + var shaderType = (ShaderSymbol)table.RootSymbols[mixin.Name].Type; + + foreach (var c in shaderType.Components) + { + if (c.Id.Kind == SymbolKind.Variable) + { + var variableTypeId = context.GetOrRegister(c.Type); + var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); + context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); + } + else if (c.Id.Kind == SymbolKind.Method) + { + var functionType = (FunctionType)c.Type; + + var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); + var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); + context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); + } + } + + // Mark inherit + context.Buffer.AddOpSDSLMixinInherit(shader); + context.Module.InheritedMixins.Add(shaderType); + } + + foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach(var method in Elements.OfType()) method.Compile(table, this, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e08d15535c..ed2c6d3e22 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -161,8 +161,7 @@ public class ShaderMethod( public override void ProcessSymbol(SymbolTable table) { - table.FunctionSymbols[Name] = [new()]; - table.CurrentFunctionSymbols = table.FunctionSymbols[Name]; + table.Push(); foreach (var arg in Parameters) { arg.TypeName.ProcessSymbol(table); @@ -182,6 +181,7 @@ public override void ProcessSymbol(SymbolTable table) s.ProcessSymbol(table, this); table.Pop(); } + table.Pop(); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index ecd6965546..c31b4356d3 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -110,7 +110,9 @@ public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - var func = context.Module.Functions.First(x => x.Name == name); + if (!context.Module.Functions.TryGetValue(name, out var func)) + context.Module.InheritedFunctions.TryGetValue(name, out func); + var fcall = Buffer.InsertOpFunctionCall(Position, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); Position += fcall.WordCount; return new(fcall, func.Name); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 73c700a757..47126e6484 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -16,7 +16,7 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT context.AddName(func, name); var result = new SpirvFunction(func.ResultId!.Value, name, ftype); CurrentFunction = result; - context.Module.Functions.Add(result); + context.Module.Functions.Add(name, result); return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 333a525a85..11813ae07a 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -1,16 +1,17 @@ -using System.Numerics; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System.Diagnostics.CodeAnalysis; +using System.Numerics; using static Spv.Specification; namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { - public bool LoadExternalReference(string name, out byte[] bytecode); + public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other @@ -26,13 +27,12 @@ public class SpirvContext(SpirvModule module) : IDisposable public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; public SpirvBuffer Buffer { get; set; } = new(); - public void PutMixinName(string name) + public void PutShaderName(string name) { if (Name is null) { Name = name; - // temporary removed for testing SPIRV cross - //Buffer.InsertOpSDSLMixinName(5, name); + Buffer.InsertOpSDSLShader(5, name); } else throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Spirv/Building/Module.cs b/src/Stride.Shaders/Spirv/Building/Module.cs index 54684e8a01..af4826702a 100644 --- a/src/Stride.Shaders/Spirv/Building/Module.cs +++ b/src/Stride.Shaders/Spirv/Building/Module.cs @@ -1,8 +1,15 @@ +using Stride.Shaders.Core; + namespace Stride.Shaders.Spirv.Building; // Should contain symbols for the SPIR-V module public class SpirvModule() { - public List Functions { get; init; } = []; + public Dictionary Functions { get; init; } = []; + + public List InheritedMixins { get; } = []; + + public Dictionary InheritedVariables { get; } = []; + public Dictionary InheritedFunctions { get; } = []; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 9e036c9dab..95dc849b41 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -43,8 +43,8 @@ public void Process(SymbolTable table, CompilerUnit compiler) { var context = compiler.Context; - var entryPointVS = context.Module.Functions.Find(x => x.Name == "VSMain"); - var entryPointPS = context.Module.Functions.Find(x => x.Name == "PSMain"); + var entryPointVS = context.Module.Functions["VSMain"]; + var entryPointPS = context.Module.Functions["PSMain"]; var streams = CreateStreams(compiler); @@ -128,7 +128,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) { - ProcessMethod(table, compiler, entryPointId, streams); + ProcessMethod(compiler, entryPointId, streams); var stage = executionModel switch { @@ -235,7 +235,7 @@ private void GenerateStreamWrapper(SymbolTable table, CompilerUnit compiler, Spe /// /// Figure out (recursively) which streams are being read from and written to. /// - private void ProcessMethod(SymbolTable table, CompilerUnit compiler, int functionId, SortedList streams) + private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList streams) { var methodStart = FindMethodStart(compiler, functionId); var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); @@ -274,7 +274,7 @@ private void ProcessMethod(SymbolTable table, CompilerUnit compiler, int functio { // Process call var calledFunctionId = instruction.Operands[2]; - ProcessMethod(table, compiler, calledFunctionId, streams); + ProcessMethod(compiler, calledFunctionId, streams); } } } From fd7f63335aa4f40229e26dfadd7c9e1692f01f75 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 10 Jun 2025 14:48:06 +0200 Subject: [PATCH 0407/1182] Improve generator --- .../Parsing/OperandEnumerator.cs | 4 +- src/Stride.Shaders.Spirv.Generators/Data.cs | 25 +- .../EquatableArray.cs | 5 +- .../SPVGenerator.Buffers.cs | 227 ++++++++ .../SPVGenerator.Helpers.cs | 81 +++ .../SPVGenerator.Info.cs | 172 ++++--- .../SPVGenerator.Instructions.cs | 132 +---- .../SPVGenerator.Naming.cs | 10 +- .../SPVGenerator.SDSLOp.cs | 120 +++-- .../SPVGenerator.cs | 487 +++++++----------- 10 files changed, 723 insertions(+), 540 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index 19b9a02a75..96a032acd9 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -20,12 +20,10 @@ public OperandEnumerator(RefInstruction instruction) Decoration? decoration = instruction.OpCode switch { SDSLOp.OpDecorateString - or SDSLOp.OpDecorateStringGOOGLE or SDSLOp.OpDecorate or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], SDSLOp.OpMemberDecorate - or SDSLOp.OpMemberDecorateString - or SDSLOp.OpMemberDecorateStringGOOGLE => (Decoration)instruction.Operands[2], + or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], _ => null }; logicalOperands = InstructionInfo.GetInfo(new(instruction.OpCode, decoration)); diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index 24c44bfc61..897ede2281 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -21,6 +21,7 @@ public record struct OperandData [JsonPropertyName("quantifier")] public string? Quantifier { get; set; } public string? Class { get; set; } + public string? TypeName { get; set; } } public record struct InstructionData @@ -35,12 +36,13 @@ public record struct InstructionData public EquatableArray? Operands { get; set; } [JsonPropertyName("version")] public string Version { get; set; } + public string Documentation { get; set; } } -public class SpirvGrammar +public record struct SpirvGrammar { [JsonPropertyName("magic_number")] - public string MagicNumber { get; set; } = ""; + public string MagicNumber { get; set; } [JsonPropertyName("major_version")] public int MajorVersion { get; set; } [JsonPropertyName("minor_version")] @@ -49,8 +51,23 @@ public class SpirvGrammar public int Revision { get; set; } [JsonPropertyName("instructions")] - public List Instructions { get; set; } = []; + public EquatableArray? Instructions { get; set; } [JsonPropertyName("operand_kinds")] - public List OperandKinds { get; set; } = []; + public EquatableArray? OperandKinds { get; set; } + public string CoreDoc { get; set; } + public string GLSLDoc { get; set; } + + public SpirvGrammar() + { + MagicNumber = ""; + MajorVersion = 0; + MinorVersion = 0; + Revision = 0; + Instructions = []; + OperandKinds = []; + CoreDoc = ""; + GLSLDoc = ""; + } + } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs index 28e1ca5192..98651a6a20 100644 --- a/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs +++ b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs @@ -36,13 +36,13 @@ public override void Write(Utf8JsonWriter writer, EquatableArray value, JsonS /// /// The underlying array. /// - private readonly T[]? _array; + private readonly T[]? _array = []; /// /// Initializes a new instance of the struct. /// /// The input array to wrap. - public EquatableArray(T[] array) + public EquatableArray(T[]? array) { _array = array; } @@ -134,5 +134,6 @@ IEnumerator IEnumerable.GetEnumerator() return ((IEnumerable)(_array ?? [])).GetEnumerator(); } + public static implicit operator EquatableArray(T[] arr) => new(arr); public static implicit operator EquatableArray(List list) => new([.. list]); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs new file mode 100644 index 0000000000..5e022a9437 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -0,0 +1,227 @@ +using System.Text; + +namespace Stride.Shaders.Spirv.Generators; + +public partial class SPVGenerator +{ + public static void CreateOperation(InstructionData op, StringBuilder code, Dictionary operandKinds) + { + var opname = op.OpName; + if (opname == "OpConstant") + { + code.AppendLine(op.Documentation); + code + .AppendLine("public static Instruction AddOpConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + + .AppendLine("}"); + + + code.AppendLine(op.Documentation); + code + .AppendLine("public static Instruction InsertOpConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + + .AppendLine("}"); + + } + else if (opname == "OpSpecConstant") + { + code + .AppendLine("public static Instruction AddOpSpecConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("}"); + code.AppendLine(op.Documentation); + code + .AppendLine("public static Instruction InsertOpSpecConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("}"); + } + else if (opname!.StartsWith("OpDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + code.AppendLine(op.Documentation); + code + .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + } + else if (opname.StartsWith("OpMemberDecorate")) + { + code + .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + code.AppendLine(op.Documentation); + code + .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") + .AppendLine("{") + + .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + + .AppendLine("}"); + } + + else if (op.Operands is EquatableArray operands && operands.Count > 0) + { + var parameters = ConvertOperandsToParameters(op, operandKinds); + var parameterNames = ConvertOperandsToParameterNames(op, operandKinds); + var hasResultId = parameterNames.Contains("resultId") && opname != "OpExtInst"; + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + var paramsParameters = parameters.Where(x => x.StartsWith("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.StartsWith("Span")); + + code + .Append("public static Instruction Add") + .Append(opname) + .Append("(this SpirvBuffer buffer") + .Append(hasResultId ? ", IdResult resultId" : "") + .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + ; + code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); + code + .AppendLine($"return buffer.Add([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine("}"); + + + + code.AppendLine(op.Documentation); + code + .Append("public static Instruction Insert") + .Append(opname) + .Append("(this SpirvBuffer buffer, int position") + .Append(hasResultId ? ", IdResult resultId" : "") + .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + ; + code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); + code + .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine("}"); + } + else + { + code + .Append("public static Instruction Add") + .Append(opname) + .AppendLine("(this SpirvBuffer buffer)") + .AppendLine("{") + + .AppendLine($"return buffer.Add([1 << 16 | (int)SDSLOp.{opname}]);") + + .AppendLine("}"); + code.AppendLine(op.Documentation); + code + .Append("public static Instruction Insert") + .Append(opname) + .AppendLine("(this SpirvBuffer buffer, int position)") + .AppendLine("{") + .AppendLine($"return buffer.Insert(position, [1 << 16 | (int)SDSLOp.{opname}]);") + .AppendLine("}"); + } + } + + public static void CreateGlslOperation(InstructionData op, StringBuilder code, Dictionary operandKinds) + { + var opname = op.OpName; + var opcode = op.OpCode; + + if (op.Operands is not null) + { + var parameters = ConvertOperandsToParameters(op, operandKinds); + parameters.Add("int set"); + + var parameterNames = ConvertOperandsToParameterNames(op, operandKinds); + parameterNames.Add("set"); + + var hasResultId = parameterNames.Contains("resultId"); + + if (hasResultId) + { + parameters.Remove(parameters.First(x => x.Contains("resultId"))); + } + + var paramsParameters = parameters.Where(x => x.Contains("Span")); + var nullableParameters = parameters.Where(x => x.Contains("?")); + var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); + var other = parameterNames.Where(x => x != "resultType" && x != "resultId" && x != "set"); + + // var cells = glslDoc!.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{opname}\"))"); + // var comment = AddDocComment(cells); + code.AppendLine(op.Documentation); + code + .Append("public static Instruction AddGLSL") + .Append(opname) + .Append("(this SpirvBuffer buffer, IdResultType resultType, int resultId, ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") + .Append("return buffer.AddOpExtInst(") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + .AppendLine("}"); + + code.AppendLine(op.Documentation); + code + .Append("public static Instruction InsertGLSL") + .Append(opname) + .Append("(this SpirvBuffer buffer, int position, IdResultType resultType, int resultId, ") + .Append(string.Join(", ", normalParameters)) + .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) + .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) + .AppendLine(")") + .AppendLine("{") + .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") + .Append("return buffer.InsertOpExtInst(position, ") + .Append("set, ") + .Append(opcode) + .Append(", resultId, resultType ") + .AppendLine(", refs);") + .AppendLine("}"); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs new file mode 100644 index 0000000000..c867ab004d --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs @@ -0,0 +1,81 @@ +using System.Text; + +namespace Stride.Shaders.Spirv.Generators; + +public partial class SPVGenerator +{ + public static string ConvertName(OperandData operand) + { + return operand switch + { + { Name: "name", Quantifier: "*" } => "values", + { Name: "event", Quantifier: _ } => "eventId", + { Name: "string", Quantifier: _ } => "value", + { Name: "base", Quantifier: _ } => "baseId", + { Name: "object", Quantifier: _ } => "objectId", + { Name: "default", Quantifier: _ } => "defaultId", + _ => operand.Name?.Replace("'", "").ToLowerInvariant() ?? "" + }; + } + + + public static string KindToVariableName(string kind) + { + return kind switch + { + "IdResult" => "result", + "IdResultType" => "resultType", + "IdRef" => "idRef", + _ => kind.Replace("'", "").Replace(" ", "").ToLowerInvariant() + }; + } + public static string GenerateTypeName(OperandData operand) + { + var type = operand.Kind; + if (operand.Class == "BitEnum") + type = $"{type}Mask"; + if (operand.Quantifier == "*") + type = $"Span<{type}>"; + else if (operand.Quantifier == "?") + type = $"{type}?"; + return type; + } + public static string GenerateVariableName(OperandData operand) + { + var nameBuilder = new StringBuilder(); + bool first = true; + operand.Name ??= ConvertKindToName(operand.Kind); + foreach (var c in operand.Name) + { + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } + + } + return nameBuilder.ToString(); + } + public static string ConvertNameQuantToName(string name, string quant) + { + return (name, quant) switch + { + (_, "*") => "values", + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + _ => name.Replace("'", "").ToLowerInvariant() + }; + } + + public static string ConvertQuantifier(string quant) + { + if (quant == "*") + return "ZeroOrMore"; + else if (quant == "?") + return "ZeroOrOne"; + else return "One"; + } +} diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 2944bc6be8..c987596814 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -10,73 +10,134 @@ using System.Text.Json; using System.Security.Claims; using System.Runtime.InteropServices.ComTypes; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.CSharp; namespace Stride.Shaders.Spirv.Generators; + public partial class SPVGenerator { - public void CreateInfo(IncrementalGeneratorInitializationContext context) + public void CreateInfo(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - GenerateKinds(context); - - var code = new StringBuilder(); + GenerateKinds(context, grammarProvider); - code - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public partial class InstructionInfo") - .AppendLine("{") + var infoProvider = grammarProvider + .Select(static (grammar, _) => grammar.Instructions!.Value); - .AppendLine("static InstructionInfo()") - .AppendLine("{") + context.RegisterImplementationSourceOutput(infoProvider, + static (spc, instructions) => + { + var code = new StringBuilder(); + code + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public partial class InstructionInfo") + .AppendLine("{") + .AppendLine("static InstructionInfo()") + .AppendLine("{"); + foreach (var instruction in instructions) + GenerateInfo(instruction, code); + + code + .AppendLine("Instance.InitOrder();") + .AppendLine("}") + .AppendLine("}"); + spc.AddSource( + "InstructionInfo.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + }) ; + // var code = new StringBuilder(); - foreach (var instruction in spirvCore!.Instructions) - { - GenerateInfo(instruction, code); - } - foreach (var instruction in spirvSDSL!.Instructions) - { - GenerateInfo(instruction, code); - } - code - .AppendLine("Instance.InitOrder();") + // code + // .AppendLine("using static Spv.Specification;") + // .AppendLine("") + // .AppendLine("namespace Stride.Shaders.Spirv.Core;") + // .AppendLine("") + // .AppendLine("public partial class InstructionInfo") + // .AppendLine("{") + + // .AppendLine("static InstructionInfo()") + // .AppendLine("{") + // ; + + + // foreach (var instruction in spirvCore!.Instructions) + // { + // GenerateInfo(instruction, code); + // } + // foreach (var instruction in spirvSDSL!.Instructions) + // { + // GenerateInfo(instruction, code); + // } + // code + // .AppendLine("Instance.InitOrder();") - .AppendLine("}") + // .AppendLine("}") - .AppendLine("}"); + // .AppendLine("}"); - context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); + // context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); } - private void GenerateKinds(IncrementalGeneratorInitializationContext context) + private void GenerateKinds(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - var code = new StringBuilder() - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("\n\n") - .AppendLine("public enum OperandKind") - .AppendLine("{") - - .AppendLine("None = 0,"); - var kinds = spirvCore!.OperandKinds.Select(x => x.Kind); - foreach (var kind in kinds) - { - code.Append(kind).AppendLine(","); - } - code.AppendLine("}"); + var kindsProvider = grammarProvider + .Select(static (grammar, _) => grammar.OperandKinds!.Value); - context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); + context.RegisterImplementationSourceOutput(kindsProvider, + static (spc, kinds) => + { + var builder = new StringBuilder(); + builder + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum OperandKind") + .AppendLine("{") + .AppendLine(" None,"); + foreach (var kind in kinds) + builder.AppendLine($" {kind.Kind},"); + builder + .AppendLine("}"); + spc.AddSource("OperandKind.gen.cs", builder.ToString()); + } + ); + // var code = new StringBuilder() + // .AppendLine("using static Spv.Specification;") + // .AppendLine("") + // .AppendLine("namespace Stride.Shaders.Spirv.Core;") + // .AppendLine("\n\n") + // .AppendLine("public enum OperandKind") + // .AppendLine("{") + + // .AppendLine("None = 0,"); + // var kinds = spirvCore!.OperandKinds.Select(x => x.Kind); + // foreach (var kind in kinds) + // { + // code.Append(kind).AppendLine(","); + // } + // code.AppendLine("}"); + + // context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); } - public void GenerateInfo(InstructionData op, StringBuilder code) + public static void GenerateInfo(InstructionData op, StringBuilder code) { var opname = op.OpName; var spvClass = op.Class; @@ -124,7 +185,7 @@ public void GenerateInfo(InstructionData op, StringBuilder code) .Append($", \"{spvClass}\"") .AppendLine(");"); } - + } } } @@ -134,27 +195,6 @@ public void GenerateInfo(InstructionData op, StringBuilder code) } } - public static string ConvertNameQuantToName(string name, string quant) - { - return (name, quant) switch - { - (_, "*") => "values", - ("event", _) => "eventId", - ("string", _) => "value", - ("base", _) => "baseId", - ("object", _) => "objectId", - ("default", _) => "defaultId", - _ => name.Replace("'", "").ToLowerInvariant() - }; - } - public static string ConvertQuantifier(string quant) - { - if (quant == "*") - return "ZeroOrMore"; - else if (quant == "?") - return "ZeroOrOne"; - else return "One"; - } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 5a47cef62d..4885d5e755 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -7,132 +7,22 @@ namespace Stride.Shaders.Spirv.Generators; - -public record struct SpirvInstructionData -{ - public string Name { get; } - public string OpCode { get; } - public string Category { get; } - public string Description { get; } - public EquatableArray Operands { get; } - public EquatableArray Returns { get; } - - public SpirvInstructionData(string name, string opcode, string category, string description, string[] operands, string[] returns) - { - Name = name; - OpCode = opcode; - Category = category; - Description = description; - Operands = new(operands); - Returns = new(returns); - } -} - - public partial class SPVGenerator : IIncrementalGenerator { - public void GenerateStructs(IncrementalGeneratorInitializationContext context) + public void GenerateStructs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - IncrementalValuesProvider instructionsData = - context.AdditionalTextsProvider - .Where(file => Path.GetFileName(file.Path) == "spirv.core.grammar.json") - .Select((file, _) => file.GetText()?.ToString()) - .Where(text => text is not null) - .Select((text, _) => - { - var result = JsonSerializer.Deserialize(text!, options); - if (result is SpirvGrammar grammar) - { - var list = new List(24); - var dict = grammar.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); - if (grammar.Instructions is List instructions) - { - for (int i = 0; i < instructions.Count; i++) - { - list.Clear(); - if (instructions[i].Operands is EquatableArray operands) - { - foreach (var op in operands) - list.Add(op with { Class = dict[op.Kind] }); - instructions[i] = instructions[i] with { Operands = list }; - } - } - } - } - return result; - }) - .SelectMany((grammar, _) => grammar!.Instructions ?? []) - .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); - - IncrementalValuesProvider glslInstructionsData = - context.AdditionalTextsProvider - .Where(file => Path.GetFileName(file.Path) == "extinst.glsl.std.450.grammar.json" ) - .Select((file, _) => file.GetText()?.ToString()) - .Where(text => text is not null) - .Select((text, _) => - { - var result = JsonSerializer.Deserialize(text!, options); - if (result is SpirvGrammar grammar) - { - var list = new List(24); - var dict = spirvCore!.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); - if (grammar.Instructions is List instructions) - { - for (int i = 0; i < instructions.Count; i++) - { - list.Clear(); - if (instructions[i].Operands is EquatableArray operands) - { - foreach (var op in operands) - list.Add(op with { Class = dict[op.Kind] }); - instructions[i] = instructions[i] with { Operands = list }; - } - } - } - } - return result; - }) - .SelectMany((grammar, _) => grammar!.Instructions ?? []) - .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); + var sdslInstructionsData = + grammarProvider + .Select(static (grammar, _) => grammar.Instructions); - IncrementalValuesProvider sdslInstructionsData = - context.AdditionalTextsProvider - .Where(file => Path.GetFileName(file.Path) == "spirv.sdsl.grammar-ext.json") - .Select((file, _) => file.GetText()?.ToString()) - .Where(text => text is not null) - .Select((text, _) => - { - var result = JsonSerializer.Deserialize(text!, options); - if (result is SpirvGrammar grammar) - { - var list = new List(24); - var dict = spirvCore!.OperandKinds.ToDictionary(x => x.Kind, x => x.Category); - if (grammar.Instructions is List instructions) - { - for (int i = 0; i < instructions.Count; i++ ) - { - list.Clear(); - if (instructions[i].Operands is EquatableArray operands) - { - foreach (var op in operands) - list.Add(op with { Class = dict[op.Kind] }); - instructions[i] = instructions[i] with { Operands = list }; - } - } - } - } - return result; - }) - .SelectMany((grammar, _) => grammar!.Instructions ?? []) - .Where(instruction => !instruction.OpName.StartsWith("OpCopyMemory")); - - - context.RegisterImplementationSourceOutput(instructionsData, - static (spc, source) => Execute(source, spc)); - context.RegisterImplementationSourceOutput(glslInstructionsData, - static (spc, source) => Execute(source, spc)); context.RegisterImplementationSourceOutput(sdslInstructionsData, - static (spc, source) => Execute(source, spc)); + static (spc, source) => + { + foreach (var instruction in source!) + if(!instruction.OpName.Contains("OpCopyMemory")) + Execute(instruction, spc); + } + ); } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs index af49dfb962..86b3cf6448 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs @@ -28,7 +28,7 @@ public partial class SPVGenerator { - public List ConvertOperandsToParameters(InstructionData op) + public static List ConvertOperandsToParameters(InstructionData op, Dictionary operandKinds) { var opname = op.OpName; List parameters = []; @@ -37,7 +37,7 @@ public List ConvertOperandsToParameters(InstructionData op) foreach (var e in operands) { var kind = e.Kind; - var realKind = ConvertKind(kind!); + var realKind = ConvertKind(kind!, operandKinds); if (e.Quantifier is not null) { if (e.Name is string name) @@ -78,7 +78,7 @@ public List ConvertOperandsToParameters(InstructionData op) return parameters; } - public List ConvertOperandsToParameterNames(InstructionData op) + public static List ConvertOperandsToParameterNames(InstructionData op, Dictionary operandKinds) { var opname = op.OpName; var operands = op.Operands; @@ -87,7 +87,7 @@ public List ConvertOperandsToParameterNames(InstructionData op) foreach (var e in operands) { var kind = e.Kind; - var realKind = ConvertKind(kind!); + var realKind = ConvertKind(kind!, operandKinds); if (e.Quantifier is string quant) { if (e.Name is string name) @@ -116,7 +116,7 @@ public List ConvertOperandsToParameterNames(InstructionData op) return parameters; } - public string ConvertKind(string kind) + public static string ConvertKind(string kind, Dictionary operandKinds) { var opKind = operandKinds[kind]; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index f04e3bdc31..bad6efa94a 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -11,41 +11,101 @@ using System.Security.Claims; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; +using AngleSharp.Common; +using Microsoft.CodeAnalysis.Text; +using System.Dynamic; namespace Stride.Shaders.Spirv.Generators; + public partial class SPVGenerator { - public void CreateSDSLOp(IncrementalGeneratorInitializationContext context) + public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - var code = new StringBuilder(); - var nsProvider = context - .SyntaxProvider - .CreateSyntaxProvider( - predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), - transform: (node, _) => (NamespaceDeclarationSyntax)node.Node - ); - context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => - { - var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); - var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue!.Value.ToString())); - var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue!.Value.ToString())).Max(); - - foreach (var e in spirvSDSL!.Instructions.Select(x => x.OpName)) - members.Add(e!, ++lastnum); - - code - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum SDSLOp : int") - .AppendLine("{"); - foreach (var e in members) - code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); - code - .AppendLine("}"); - - - ctx.AddSource("SDSLOp.gen.cs", code.ToSourceText()); - }); + + var instructionsProvider = + grammarProvider + .Select((x, _) => x!.Instructions!.Value); + context.RegisterImplementationSourceOutput( + instructionsProvider, + (ctx, instructionArray) => + { + var code = new StringBuilder(); + code + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + try + { + Dictionary members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode); + int lastnum = members.Values.Max(); + foreach (var instruction in instructionArray) + { + if (instruction.OpName is null) + continue; + if (members.TryGetValue(instruction.OpName, out var value)) + { + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); + } + else + { + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); + } + } + } + catch (Exception ex) + { + code.AppendLine($"/*{ex.Message}\n\n {ex.StackTrace} */"); + } + + code.AppendLine("}"); + ctx.AddSource("SDSLOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + + ); + + // var code = new StringBuilder(); + // var nsProvider = context + // .SyntaxProvider + // .CreateSyntaxProvider( + // predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), + // transform: (node, _) => (NamespaceDeclarationSyntax)node.Node + // ); + // context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => + // { + // var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); + // var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue!.Value.ToString())); + // var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue!.Value.ToString())).Max(); + + // foreach (var e in spirvSDSL!.Instructions.Select(x => x.OpName)) + // members.Add(e!, ++lastnum); + + // code + // .AppendLine("namespace Stride.Shaders.Spirv.Core;") + // .AppendLine("") + // .AppendLine("public enum SDSLOp : int") + // .AppendLine("{"); + // foreach (var e in members) + // code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); + // code + // .AppendLine("}"); + + + // ctx.AddSource("SDSLOp.gen.cs", code.ToSourceText()); + // }); } public static int ParseInteger(string text) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 821f563441..4357d9ac2c 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -7,6 +7,9 @@ using System.Text; using System.Text.Json; using AngleSharp; +using System.Net.Http.Headers; +using Microsoft.CodeAnalysis.Text; +using Microsoft.CodeAnalysis.CSharp; namespace Stride.Shaders.Spirv.Generators; @@ -14,14 +17,8 @@ namespace Stride.Shaders.Spirv.Generators; [Generator] public partial class SPVGenerator : IIncrementalGenerator { - SpirvGrammar? spirvCore; - SpirvGrammar? spirvGlsl; - SpirvGrammar? spirvSDSL; - IDocument? unifiedDoc; - IDocument? glslDoc; - - Dictionary operandKinds = []; + // Dictionary operandKinds = []; static readonly JsonSerializerOptions options = new(); @@ -31,317 +28,189 @@ public void Initialize(IncrementalGeneratorInitializationContext context) // if (!Debugger.IsAttached) // Debugger.Launch(); // #endif - var assembly = typeof(SPVGenerator).GetTypeInfo().Assembly; - string resourceCoreName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("spirv.core.grammar.json")); - - string resourceGlslName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("extinst.glsl.std.450.grammar.json")); - - string resourceSDSLName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("spirv.sdsl.grammar-ext.json")); - - string resourceUnifiedName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("SPIRV.html")); - string resourceGlslRegistryName = - assembly.GetManifestResourceNames() - .Single(str => str.EndsWith("GLSL.std.450.html")); - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) options.Converters.Add(new EquatableArrayJsonConverter()); - - spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd(), options); - spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd(), options); - spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd(), options); - - - var config = Configuration.Default.WithDefaultLoader(); - var htmlContext = BrowsingContext.New(config); - var documentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceUnifiedName)).ReadToEnd())); - documentTask.Wait(); - unifiedDoc = documentTask.Result; - var glslDocumentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceGlslRegistryName)).ReadToEnd())); - glslDocumentTask.Wait(); - glslDoc = glslDocumentTask.Result; - - foreach (var o in spirvCore!.OperandKinds) - operandKinds[o.Kind] = o; - - CreateInfo(context); - CreateSDSLOp(context); - - - var code = new StringBuilder(); - - code - .AppendLine("using static Spv.Specification;") - .AppendLine("namespace Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("") - .AppendLine("public static class SpirvBufferExtensions") - .AppendLine("{"); - - var instructions = spirvCore!.Instructions; - var sdslInstructions = spirvSDSL!.Instructions; - var glslInstruction = spirvGlsl!.Instructions; - - instructions.ForEach(x => CreateOperation(x, code)); - sdslInstructions.ForEach(x => CreateOperation(x, code)); - glslInstruction.ForEach(x => CreateGlslOperation(x, code)); - - code.AppendLine("}"); - - context.RegisterPostInitializationOutput(ctx => - { - ctx.AddSource( - "SpirvBufferExtensions.gen.cs", - code.ToSourceText()); - }); - - GenerateStructs(context); - - } - - public static string AddDocComment(IHtmlCollection? cells) - { - var code = new StringBuilder(); - if (cells.FirstOrDefault() is IElement element) - { - var split = element.TextContent.Split('\n'); - code.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); - foreach (var t in split.Skip(1)) - if(!string.IsNullOrEmpty(t)) - code.Append("/// ") - .Append(t.Replace("", "id")) - .AppendLine(""); - code.AppendLine("/// "); - } - return code.ToString(); - } - - public void CreateOperation(InstructionData op, StringBuilder code) - { - var opname = op.OpName; - var cells = unifiedDoc!.QuerySelectorAll($"p.tableblock:has(#{opname})"); - var comment = AddDocComment(cells); - code.AppendLine(comment); - if (opname == "OpConstant") - { - code - .AppendLine("public static Instruction AddOpConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") - .AppendLine("{") - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") - - .AppendLine("}"); - - - code.AppendLine(comment); - code - .AppendLine("public static Instruction InsertOpConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") - .AppendLine("{") - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") - - .AppendLine("}"); - - } - else if (opname == "OpSpecConstant") - { - code - .AppendLine("public static Instruction AddOpSpecConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") - .AppendLine("}"); - code.AppendLine(comment); - code - .AppendLine("public static Instruction InsertOpSpecConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") - .AppendLine("}"); - } - else if (opname!.StartsWith("OpDecorate")) - { - code - .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") - - .AppendLine("}"); - code.AppendLine(comment); - code - .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef target, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") - - .AppendLine("}"); - } - else if (opname.StartsWith("OpMemberDecorate")) - { - code - .Append("public static Instruction Add").Append(opname).Append("(this SpirvBuffer buffer, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") - - .AppendLine("}"); - code.AppendLine(comment); - code - .Append("public static Instruction Insert").Append(opname).Append("(this SpirvBuffer buffer, int position, IdRef structureType, LiteralInteger member, Decoration decoration, int? additional1 = null, int? additional2 = null, string? additionalString = null)") - .AppendLine("{") - - .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") - - .AppendLine("}"); - } - - else if (op.Operands is EquatableArray operands && operands.Count > 0) - { - var parameters = ConvertOperandsToParameters(op); - var parameterNames = ConvertOperandsToParameterNames(op); - var hasResultId = parameterNames.Contains("resultId") && opname != "OpExtInst"; - if (hasResultId) + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) + options.Converters.Add(new EquatableArrayJsonConverter()); + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) + options.Converters.Add(new EquatableArrayJsonConverter()); + + // spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd(), options); + // spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd(), options); + // spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd(), options); + + + // var config = Configuration.Default.WithDefaultLoader(); + // var htmlContext = BrowsingContext.New(config); + // var documentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceUnifiedName)).ReadToEnd())); + // documentTask.Wait(); + // unifiedDoc = documentTask.Result; + // var glslDocumentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceGlslRegistryName)).ReadToEnd())); + // glslDocumentTask.Wait(); + // glslDoc = glslDocumentTask.Result; + + // foreach (var o in spirvCore!.OperandKinds) + // operandKinds[o.Kind] = o; + + + + + var grammarData = + context + .AdditionalTextsProvider + .Where( + static file => + Path.GetFileName(file.Path) switch + { + "spirv.core.grammar.json" + or "spirv.sdsl.grammar-ext.json" + or "extinst.glsl.std.450.grammar.json" + or "SPIRV.html" + or "GLSL.std.450.html" => true, + _ => false + } + ) + .Collect() + .Select( + static (files, _) => + { + SpirvGrammar grammar = new(); + foreach (var file in files) + { + if (Path.GetFileName(file.Path) == "SPIRV.html") + grammar.CoreDoc = file.GetText()?.ToString() ?? ""; + else if (Path.GetFileName(file.Path) == "GLSL.std.450.html") + grammar.GLSLDoc = file.GetText()?.ToString() ?? ""; + else + { + var parsed = JsonSerializer.Deserialize(file.GetText()?.ToString() ?? "{}", options); + if (grammar.MagicNumber == "" && parsed.MagicNumber != "") + { + grammar.MagicNumber = parsed!.MagicNumber; + grammar.MajorVersion = parsed.MajorVersion; + grammar.MinorVersion = parsed.MinorVersion; + grammar.Revision = parsed.Revision; + } + if (parsed.Instructions is not null) + { + InstructionData[] instructions = [.. grammar.Instructions, .. parsed.Instructions]; + grammar.Instructions = instructions; + } + if (parsed.OperandKinds is not null) + { + OpKind[] operandKinds = [.. grammar.OperandKinds, .. parsed.OperandKinds]; + grammar.OperandKinds = operandKinds; + } + + } + } + return grammar; + } + ) + .Select(static (grammar, ct) => { - parameters.Remove(parameters.First(x => x.Contains("resultId"))); + var operandKinds = grammar.OperandKinds?.AsArray().ToDictionary(x => x.Kind, x => x.Category); + var config = Configuration.Default.WithDefaultLoader(); + var htmlContext = BrowsingContext.New(config); + var coreTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); + coreTask.Wait(); + var glslTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); + glslTask.Wait(); + var coreDoc = coreTask.Result; + var glslDoc = glslTask.Result; + + var builder = new StringBuilder(); + var buffer = new List(24); + for (int i = 0; i < grammar.Instructions?.AsArray()!.Length; i++) + // foreach (var instruction in grammar.Instructions) + { + var instruction = grammar.Instructions.Value.AsArray()![i]!; + // setup the documentation + var cells = instruction.OpName switch + { + string v when v.Contains("GLSL") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName}\"))"), + string v when v.Contains("SDSL") => null, // SDSL does not have documentation + string => coreDoc!.QuerySelectorAll($"p.tableblock:has(#{instruction.OpName})"), + }; + if (cells is not null) + { + if (cells.FirstOrDefault() is IElement element) + { + var split = element.TextContent.Split('\n'); + builder.Clear(); + builder.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); + foreach (var t in split.Skip(1)) + if (!string.IsNullOrEmpty(t)) + builder.Append("/// ") + .Append(t.Replace("", "id")) + .AppendLine(""); + builder.AppendLine("/// "); + } + instruction.Documentation = builder.ToString(); + } + + + // setup the operand class + buffer.Clear(); + if (instruction.Operands?.AsArray() is OperandData[] operands) + { + foreach (var op in operands) + { + var name = GenerateVariableName(op); + var type = GenerateTypeName(op); + buffer.Add(op with { Class = operandKinds[op.Kind], Name = name, TypeName = type }); + } + instruction.Operands = buffer; + } + + grammar.Instructions.Value.AsArray()![i] = instruction; + + } + return grammar; } - var paramsParameters = parameters.Where(x => x.StartsWith("Span")); - var nullableParameters = parameters.Where(x => x.Contains("?")); - var normalParameters = parameters.Where(x => !x.Contains("?") && !x.StartsWith("Span")); - - code - .Append("public static Instruction Add") - .Append(opname) - .Append("(this SpirvBuffer buffer") - .Append(hasResultId ? ", IdResult resultId" : "") - .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(")") - .AppendLine("{") - ; - code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); - code - .AppendLine($"return buffer.Add([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") - .AppendLine("}"); - - - - code.AppendLine(comment); - code - .Append("public static Instruction Insert") - .Append(opname) - .Append("(this SpirvBuffer buffer, int position") - .Append(hasResultId ? ", IdResult resultId" : "") - .Append(normalParameters.Count() + nullableParameters.Count() + paramsParameters.Count() == 0 ? "" : ", ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(")") - .AppendLine("{") - ; - code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); - code - .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") - .AppendLine("}"); - } - else - { - code - .Append("public static Instruction Add") - .Append(opname) - .AppendLine("(this SpirvBuffer buffer)") - .AppendLine("{") - - .AppendLine($"return buffer.Add([1 << 16 | (int)SDSLOp.{opname}]);") + ); - .AppendLine("}"); - code.AppendLine(comment); - code - .Append("public static Instruction Insert") - .Append(opname) - .AppendLine("(this SpirvBuffer buffer, int position)") - .AppendLine("{") - .AppendLine($"return buffer.Insert(position, [1 << 16 | (int)SDSLOp.{opname}]);") - .AppendLine("}"); - } - } - - public void CreateGlslOperation(InstructionData op, StringBuilder code) - { - var opname = op.OpName; - var opcode = op.OpCode; - - if (op.Operands is not null) - { - var parameters = ConvertOperandsToParameters(op); - parameters.Add("int set"); + CreateInfo(context, grammarData); + CreateSDSLOp(context, grammarData); + GenerateStructs(context, grammarData); - var parameterNames = ConvertOperandsToParameterNames(op); - parameterNames.Add("set"); - - var hasResultId = parameterNames.Contains("resultId"); - - if (hasResultId) + context.RegisterImplementationSourceOutput( + grammarData, + static (spc, source) => { - parameters.Remove(parameters.First(x => x.Contains("resultId"))); + var operandKinds = source.OperandKinds!.Value.AsArray().ToDictionary(x => x.Kind, x => x); + var code = new StringBuilder(); + code + .AppendLine("using static Spv.Specification;") + .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public static class SpirvBufferExtensions") + .AppendLine("{"); + foreach (var instruction in source.Instructions!.Value.AsArray()!) + { + if (instruction.OpName.StartsWith("Op")) + CreateOperation(instruction, code, operandKinds); + else + CreateGlslOperation(instruction, code, operandKinds); + } + code + .AppendLine("}"); + + spc.AddSource("SpirvBufferExtensions.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + ); - var paramsParameters = parameters.Where(x => x.Contains("Span")); - var nullableParameters = parameters.Where(x => x.Contains("?")); - var normalParameters = parameters.Where(x => !x.Contains("?") && !x.Contains("Span")); - var other = parameterNames.Where(x => x != "resultType" && x != "resultId" && x != "set"); - var cells = glslDoc!.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{opname}\"))"); - var comment = AddDocComment(cells); - code.AppendLine(comment); - code - .Append("public static Instruction AddGLSL") - .Append(opname) - .Append("(this SpirvBuffer buffer, IdResultType resultType, int resultId, ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(")") - .AppendLine("{") - .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") - .Append("return buffer.AddOpExtInst(") - .Append("set, ") - .Append(opcode) - .Append(", resultId, resultType ") - .AppendLine(", refs);") - .AppendLine("}"); - - code.AppendLine(comment); - code - .Append("public static Instruction InsertGLSL") - .Append(opname) - .Append("(this SpirvBuffer buffer, int position, IdResultType resultType, int resultId, ") - .Append(string.Join(", ", normalParameters)) - .Append(nullableParameters.Count() == 0 ? "" : (normalParameters.Count() > 0 ? ", " : "") + string.Join(", ", nullableParameters)) - .Append(paramsParameters.Count() == 0 ? "" : (normalParameters.Count() + nullableParameters.Count() > 0 ? ", " : "") + paramsParameters.First()) - .AppendLine(")") - .AppendLine("{") - .Append("Span refs = [").Append(string.Join(", ", other)).AppendLine("];") - .Append("return buffer.InsertOpExtInst(position, ") - .Append("set, ") - .Append(opcode) - .Append(", resultId, resultType ") - .AppendLine(", refs);") - .AppendLine("}"); - } } } From 786ee1357111ac8937a7aaa680838e9f0e6f98cf Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 Jun 2025 11:47:59 +0200 Subject: [PATCH 0408/1182] Improving generator + working on custom specification --- src/Stride.Shaders.Spirv.Generators/Data.cs | 46 ++++ .../SPVGenerator.Enums.cs | 61 +++++ .../SPVGenerator.Extensions.cs | 23 -- ...ming.cs => SPVGenerator.Helpers.Naming.cs} | 77 ++++++ .../SPVGenerator.Helpers.Preprocessing.cs | 130 +++++++++++ .../SPVGenerator.Helpers.cs | 81 ------- .../SPVGenerator.Info.cs | 98 +++----- .../SPVGenerator.Instructions.cs | 115 ++++----- .../SPVGenerator.SDSLOp.cs | 37 --- .../SPVGenerator.cs | 221 +++++------------- 10 files changed, 461 insertions(+), 428 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs delete mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs rename src/Stride.Shaders.Spirv.Generators/{SPVGenerator.Naming.cs => SPVGenerator.Helpers.Naming.cs} (68%) create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs delete mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index 897ede2281..b4125baf53 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -1,14 +1,58 @@ +using System.Text.Json; using System.Text.Json.Serialization; namespace Stride.Shaders.Spirv.Generators; +public class EnumerantValueConverter : JsonConverter +{ + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Number) + return reader.GetInt32(); + else if (reader.TokenType == JsonTokenType.String) + { + var value = reader.GetString(); + if (value != null && value.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) + { + return int.Parse(value.Substring(2), System.Globalization.NumberStyles.HexNumber); + } + else + { + return int.Parse(value); + } + } + else throw new Exception($"Unexpected token type {reader.TokenType} for Enumerant value."); + } + + public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options) + { + writer.WriteNumberValue(value); + } +} + + +public record struct Enumerant +{ + [JsonPropertyName("enumerant")] + public string Name { get; set; } + [JsonPropertyName("value")] + [JsonConverter(typeof(EnumerantValueConverter))] + public int Value { get; set; } + [JsonPropertyName("capabilities")] + public EquatableArray? Capabilities { get; set; } + [JsonPropertyName("version")] + public string Version { get; set; } +} public record struct OpKind { [JsonPropertyName("kind")] public string Kind { get; set; } [JsonPropertyName("category")] public string Category { get; set; } + + [JsonPropertyName("enumerants")] + public EquatableArray? Enumerants { get; set; } } @@ -39,6 +83,8 @@ public record struct InstructionData public string Documentation { get; set; } } +public record struct AdditionalEnum(string Original, string New); + public record struct SpirvGrammar { [JsonPropertyName("magic_number")] diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs new file mode 100644 index 0000000000..c02eaf96e1 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs @@ -0,0 +1,61 @@ +using System; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; + +namespace Stride.Shaders.Spirv.Generators; + + +public partial class SPVGenerator +{ + public void CreateSpecification(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) + { + var sdsloProvider = grammarProvider + .Select(static (grammar, _) => grammar.OperandKinds!.Value); + + context.RegisterImplementationSourceOutput( + sdsloProvider, + GenerateSDSLSpecification + ); + } + public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableArray operandKinds) + { + var code = new StringBuilder(); + code + .AppendLine("namespace Stride.Shaders.Spirv;") + .AppendLine("") + .AppendLine("public static class Specification") + .AppendLine("{"); + + foreach (var op in operandKinds) + { + if (op.Category == "BitEnum") + { + code + .AppendLine($"[Flags]"); + } + code + .AppendLine($"public enum {op.Kind}") + .AppendLine("{"); + foreach (var enumerant in op.Enumerants!.Value) + code.AppendLine($" {enumerant.Name} = {enumerant.Value},"); + code.AppendLine("}"); + code.AppendLine(); + } + + code + .AppendLine("}"); + + spc.AddSource( + "SDSLSpecification.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs deleted file mode 100644 index 4396a19af2..0000000000 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; - -namespace Stride.Shaders.Spirv.Generators; - - -public static class SpirvGeneratorExtensions -{ - public static SourceText ToSourceText(this StringBuilder builder) - { - return SourceText.From( - SyntaxFactory - .ParseCompilationUnit(builder.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ); - - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs similarity index 68% rename from src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs rename to src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 86b3cf6448..71694d94d8 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -22,12 +22,87 @@ public static void AddUnique(this List list, string name) else list.Add(name); } + public static void AddUnique(this List<(string Name, string Type)> list, string name, string type) + { + if (list.Any(x => x.Name == name)) + list.Add(($"{name}{list.Where(x => x.Name.StartsWith(name)).Count()}", type)); + else + list.Add((name, type)); + } } public partial class SPVGenerator { + public static string ConvertQuantifier(string quant) + { + if (quant == "*") + return "ZeroOrMore"; + else if (quant == "?") + return "ZeroOrOne"; + else return "One"; + } + public static string ConvertNameQuantToName(string name, string quant) + { + return (name, quant) switch + { + (_, "*") => "values", + ("event", _) => "eventId", + ("string", _) => "value", + ("base", _) => "baseId", + ("object", _) => "objectId", + ("default", _) => "defaultId", + _ => name.Replace("'", "").ToLowerInvariant() + }; + } + public static void PreProcessOperands(InstructionData op, Dictionary operandKinds, List<(string Name, string Type)> parameters) + { + var opname = op.OpName; + if (op.Operands?.AsArray() is OperandData[] operands) + { + for (int i = 0; i < operands.Length; i++) + { + var e = operands[i]; + var kind = e.Kind; + var realKind = ConvertKind(kind!, operandKinds); + if (e.Quantifier is not null) + { + if (e.Name is string name) + { + if (e.Quantifier == "?") + parameters.AddUnique(ConvertOperandName(name), $"{realKind}?"); + else if (e.Quantifier == "*") + parameters.AddUnique("values", $"Span<{realKind}>"); + } + else + { + if (e.Quantifier == "?") + parameters.AddUnique(ConvertKindToName(kind!), $"{realKind}?"); + else if (e.Quantifier == "*") + parameters.AddUnique("values", $"Span<{realKind}>"); + } + } + else + { + if (e.Name is not null) + parameters.AddUnique(ConvertOperandName(e.Name), realKind); + else if (kind == "IdResult" && opname == "OpExtInst") + parameters.AddUnique(ConvertKindToName(kind), $"{realKind}?"); + else if (kind == "IdResultType" && opname == "OpExtInst") + parameters.AddUnique(ConvertKindToName(kind), $"{realKind}?"); + else + parameters.AddUnique(ConvertKindToName(kind!), realKind); + } + e.TypeName = parameters.Last().Type; + e.Name = parameters.Last().Name; + e.Class = operandKinds[kind!].Category; + operands[i] = e; + } + } + } + + // TODO: Include this in the preprocessing of instructions public static List ConvertOperandsToParameters(InstructionData op, Dictionary operandKinds) { var opname = op.OpName; @@ -78,6 +153,7 @@ public static List ConvertOperandsToParameters(InstructionData op, Dicti return parameters; } + // TODO: Include this in the preprocessing of instructions public static List ConvertOperandsToParameterNames(InstructionData op, Dictionary operandKinds) { var opname = op.OpName; @@ -195,5 +271,6 @@ public static string ConvertOperandName(string input, string? quant = null, bool (string v, _) => v }; } + } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs new file mode 100644 index 0000000000..d5f3faa4bb --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -0,0 +1,130 @@ +using System.Collections.Immutable; +using System.Text; +using System.Text.Json; +using AngleSharp; +using AngleSharp.Dom; +using Microsoft.CodeAnalysis; + +namespace Stride.Shaders.Spirv.Generators; + +public partial class SPVGenerator +{ + public static bool IsSpirvSpecification(AdditionalText file) + => + Path.GetFileName(file.Path) switch + { + "spirv.core.grammar.json" + or "spirv.sdsl.grammar-ext.json" + or "extinst.glsl.std.450.grammar.json" + or "SPIRV.html" + or "GLSL.std.450.html" => true, + _ => false + }; + + public SpirvGrammar PreProcessGrammar(ImmutableArray files, CancellationToken _) + { + SpirvGrammar grammar = new(); + foreach (var file in files) + { + if (Path.GetFileName(file.Path) == "SPIRV.html") + grammar.CoreDoc = file.GetText()?.ToString() ?? ""; + else if (Path.GetFileName(file.Path) == "GLSL.std.450.html") + grammar.GLSLDoc = file.GetText()?.ToString() ?? ""; + else + { + var parsed = JsonSerializer.Deserialize(file.GetText()?.ToString() ?? "{}", options); + if (grammar.MagicNumber == "" && parsed.MagicNumber != "") + { + grammar.MagicNumber = parsed!.MagicNumber; + grammar.MajorVersion = parsed.MajorVersion; + grammar.MinorVersion = parsed.MinorVersion; + grammar.Revision = parsed.Revision; + } + if (parsed.Instructions is not null) + { + InstructionData[] instructions = [.. grammar.Instructions, .. parsed.Instructions]; + grammar.Instructions = instructions; + } + if (parsed.OperandKinds is not null) + { + OpKind[] operandKinds = [.. grammar.OperandKinds, .. parsed.OperandKinds]; + grammar.OperandKinds = operandKinds; + } + + } + } + return grammar; + } + + public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationToken _) + { + var operandKinds = grammar.OperandKinds?.AsArray().ToDictionary(x => x.Kind, x => x); + var config = Configuration.Default.WithDefaultLoader(); + var htmlContext = BrowsingContext.New(config); + var coreTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); + coreTask.Wait(); + var glslTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); + glslTask.Wait(); + var coreDoc = coreTask.Result; + var glslDoc = glslTask.Result; + + var builder = new StringBuilder(); + // var buffer = new List(24); + if (grammar.Instructions?.AsArray() is InstructionData[] instructions) + { + for (int i = 0; i < instructions.Length; i++) + // foreach (var instruction in grammar.Instructions) + { + var instruction = grammar.Instructions.Value.AsArray()![i]!; + if(!instruction.OpName.StartsWith("Op")) + instruction.OpName = $"Op{instruction.OpName}"; + // setup the documentation + var cells = instruction.OpName switch + { + string v when v.StartsWith("GLSL") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName}\"))"), + string v when v.Contains("SDSL") => null, // SDSL does not have documentation + string => coreDoc!.QuerySelectorAll($"p.tableblock:has(#{instruction.OpName})"), + }; + if (cells is not null) + { + if (cells.FirstOrDefault() is IElement element) + { + var split = element.TextContent.Split('\n'); + builder.Clear(); + builder.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); + foreach (var t in split.Skip(1)) + if (!string.IsNullOrEmpty(t)) + builder.Append("/// ") + .Append(t.Replace("", "id")) + .AppendLine(""); + builder.AppendLine("/// "); + } + instruction.Documentation = builder.ToString(); + } + + + // A reusable buffer + var buffer = new List<(string, string)>(24); + + if (instruction.Operands?.AsArray() is OperandData[] operands) + PreProcessOperands(instruction, operandKinds!, buffer); + + instructions[i] = instruction; + + } + } + return grammar; + + } + + public static string KindToVariableName(string kind) + { + return kind switch + { + "IdResult" => "result", + "IdResultType" => "resultType", + "IdRef" => "idRef", + _ => kind.Replace("'", "").Replace(" ", "").ToLowerInvariant() + }; + } +} diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs deleted file mode 100644 index c867ab004d..0000000000 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System.Text; - -namespace Stride.Shaders.Spirv.Generators; - -public partial class SPVGenerator -{ - public static string ConvertName(OperandData operand) - { - return operand switch - { - { Name: "name", Quantifier: "*" } => "values", - { Name: "event", Quantifier: _ } => "eventId", - { Name: "string", Quantifier: _ } => "value", - { Name: "base", Quantifier: _ } => "baseId", - { Name: "object", Quantifier: _ } => "objectId", - { Name: "default", Quantifier: _ } => "defaultId", - _ => operand.Name?.Replace("'", "").ToLowerInvariant() ?? "" - }; - } - - - public static string KindToVariableName(string kind) - { - return kind switch - { - "IdResult" => "result", - "IdResultType" => "resultType", - "IdRef" => "idRef", - _ => kind.Replace("'", "").Replace(" ", "").ToLowerInvariant() - }; - } - public static string GenerateTypeName(OperandData operand) - { - var type = operand.Kind; - if (operand.Class == "BitEnum") - type = $"{type}Mask"; - if (operand.Quantifier == "*") - type = $"Span<{type}>"; - else if (operand.Quantifier == "?") - type = $"{type}?"; - return type; - } - public static string GenerateVariableName(OperandData operand) - { - var nameBuilder = new StringBuilder(); - bool first = true; - operand.Name ??= ConvertKindToName(operand.Kind); - foreach (var c in operand.Name) - { - if (char.IsLetterOrDigit(c) || c == '_') - { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } - - } - return nameBuilder.ToString(); - } - public static string ConvertNameQuantToName(string name, string quant) - { - return (name, quant) switch - { - (_, "*") => "values", - ("event", _) => "eventId", - ("string", _) => "value", - ("base", _) => "baseId", - ("object", _) => "objectId", - ("default", _) => "defaultId", - _ => name.Replace("'", "").ToLowerInvariant() - }; - } - - public static string ConvertQuantifier(string quant) - { - if (quant == "*") - return "ZeroOrMore"; - else if (quant == "?") - return "ZeroOrOne"; - else return "One"; - } -} diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index c987596814..c8246eaac7 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -27,70 +27,40 @@ public void CreateInfo(IncrementalGeneratorInitializationContext context, Increm var infoProvider = grammarProvider .Select(static (grammar, _) => grammar.Instructions!.Value); - context.RegisterImplementationSourceOutput(infoProvider, - static (spc, instructions) => - { - var code = new StringBuilder(); - code - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public partial class InstructionInfo") - .AppendLine("{") - .AppendLine("static InstructionInfo()") - .AppendLine("{"); - foreach (var instruction in instructions) - GenerateInfo(instruction, code); - - code - .AppendLine("Instance.InitOrder();") - .AppendLine("}") - .AppendLine("}"); - spc.AddSource( - "InstructionInfo.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - }) - ; - - // var code = new StringBuilder(); - - // code - // .AppendLine("using static Spv.Specification;") - // .AppendLine("") - // .AppendLine("namespace Stride.Shaders.Spirv.Core;") - // .AppendLine("") - // .AppendLine("public partial class InstructionInfo") - // .AppendLine("{") - - // .AppendLine("static InstructionInfo()") - // .AppendLine("{") - // ; - - - // foreach (var instruction in spirvCore!.Instructions) - // { - // GenerateInfo(instruction, code); - // } - // foreach (var instruction in spirvSDSL!.Instructions) - // { - // GenerateInfo(instruction, code); - // } - // code - // .AppendLine("Instance.InitOrder();") - - // .AppendLine("}") - - // .AppendLine("}"); - - // context.RegisterPostInitializationOutput(ctx => ctx.AddSource("InstructionInfo.gen.cs", code.ToSourceText())); + context.RegisterImplementationSourceOutput( + infoProvider, + GenerateInstructionInformation + ); + } + static void GenerateInstructionInformation(SourceProductionContext spc, EquatableArray instructions) + { + var code = new StringBuilder(); + code + .AppendLine("using static Spv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public partial class InstructionInfo") + .AppendLine("{") + .AppendLine("static InstructionInfo()") + .AppendLine("{"); + foreach (var instruction in instructions) + GenerateInfo(instruction, code); + + code + .AppendLine("Instance.InitOrder();") + .AppendLine("}") + .AppendLine("}"); + spc.AddSource( + "InstructionInfo.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); } private void GenerateKinds(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 4885d5e755..4ceed5a901 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -15,82 +15,89 @@ public void GenerateStructs(IncrementalGeneratorInitializationContext context, I grammarProvider .Select(static (grammar, _) => grammar.Instructions); - context.RegisterImplementationSourceOutput(sdslInstructionsData, - static (spc, source) => - { - foreach (var instruction in source!) - if(!instruction.OpName.Contains("OpCopyMemory")) - Execute(instruction, spc); - } + context.RegisterImplementationSourceOutput( + sdslInstructionsData, + GenerateInstructionStructs ); } - public static void Execute(InstructionData instruction, SourceProductionContext spc) + public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableArray? instructions) { + StringBuilder builder = new(); builder - .AppendLine("using static Spv.Specification;") - .AppendLine() - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine() - .AppendLine() - .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") - .AppendLine("{") - .AppendLine("public RefInstruction Inner { get; set; }"); - try + .AppendLine("using static Spv.Specification;") + .AppendLine() + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine() + .AppendLine(); + if (instructions is not null) { - if (instruction.Operands != null) + foreach (var instruction in instructions) { - foreach (var operand in instruction.Operands) + + builder + .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") + .AppendLine("{") + .AppendLine("public RefInstruction Inner { get; set; }"); + try { - string fieldName; - string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - if (operand.Name is null or "") - fieldName = ConvertKindToName(operand.Kind, false); - else + if (instruction.Operands != null) { - var nameBuilder = new StringBuilder(); - bool first = true; - foreach (var c in operand.Name) + foreach (var operand in instruction.Operands) { - if (char.IsLetterOrDigit(c) || c == '_') + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) + { + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } + } + fieldName = nameBuilder.ToString(); + } + if (operand.Kind == "LiteralContextDependentNumber") + continue; + else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); + else if (operand.Class == "BitEnum") + builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); + else if (operand.Class == "ValueEnum") + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); + else + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); } - fieldName = nameBuilder.ToString(); } - if (operand.Kind == "LiteralContextDependentNumber") - continue; - else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); - else if (operand.Class == "BitEnum") - builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); - else if (operand.Class == "ValueEnum") - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); - else - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); } - } - } - catch (Exception e) - { - builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); - } + catch (Exception e) + { + builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); + } - builder - .AppendLine() - .AppendLine($"public Ref{instruction.OpName}(RefInstruction instruction) => Inner = instruction;") - .AppendLine($"public Ref{instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);"); + builder + .AppendLine() + .AppendLine($"public Ref{instruction.OpName}(RefInstruction instruction) => Inner = instruction;") + .AppendLine($"public Ref{instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);"); - builder.AppendLine("}"); + builder + .AppendLine("}") + .AppendLine(); + } + } spc.AddSource( - $"{instruction.OpName}.Instruction.g.cs", + $"InstructionStructs.gen.cs", SourceText.From( SyntaxFactory .ParseCompilationUnit(builder.ToString()) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index bad6efa94a..15ff066670 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -77,42 +77,5 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr ); - // var code = new StringBuilder(); - // var nsProvider = context - // .SyntaxProvider - // .CreateSyntaxProvider( - // predicate: (node, _) => node is NamespaceDeclarationSyntax ns && ns.Name.ToString().StartsWith("Spv"), - // transform: (node, _) => (NamespaceDeclarationSyntax)node.Node - // ); - // context.RegisterImplementationSourceOutput(nsProvider, (ctx, nds) => - // { - // var eds = nds.ChildNodes().OfType().First(x => x.Identifier.Text == "Specification").ChildNodes().OfType().First(x => x.Identifier.Text == "Op"); - // var members = eds.Members.Where(x => x.Identifier.Text != "Max").ToDictionary(x => x.Identifier.Text, y => ParseInteger(y.EqualsValue!.Value.ToString())); - // var lastnum = eds.Members.Where(x => x.Identifier.Text != "Max").Select(x => ParseInteger(x.EqualsValue!.Value.ToString())).Max(); - - // foreach (var e in spirvSDSL!.Instructions.Select(x => x.OpName)) - // members.Add(e!, ++lastnum); - - // code - // .AppendLine("namespace Stride.Shaders.Spirv.Core;") - // .AppendLine("") - // .AppendLine("public enum SDSLOp : int") - // .AppendLine("{"); - // foreach (var e in members) - // code.Append(e.Key).Append(" = ").Append(e.Value).AppendLine(","); - // code - // .AppendLine("}"); - - - // ctx.AddSource("SDSLOp.gen.cs", code.ToSourceText()); - // }); - - } - public static int ParseInteger(string text) - { - if (text.StartsWith("0x")) - return int.Parse(text.Substring(2), System.Globalization.NumberStyles.HexNumber); - else - return int.Parse(text); } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 4357d9ac2c..932844ece1 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -10,6 +10,7 @@ using System.Net.Http.Headers; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Stride.Shaders.Spirv.Generators; @@ -17,158 +18,36 @@ namespace Stride.Shaders.Spirv.Generators; [Generator] public partial class SPVGenerator : IIncrementalGenerator { - - // Dictionary operandKinds = []; - static readonly JsonSerializerOptions options = new(); public void Initialize(IncrementalGeneratorInitializationContext context) { - // #if DEBUG - // if (!Debugger.IsAttached) - // Debugger.Launch(); - // #endif if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) options.Converters.Add(new EquatableArrayJsonConverter()); if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) options.Converters.Add(new EquatableArrayJsonConverter()); if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) options.Converters.Add(new EquatableArrayJsonConverter()); + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) + options.Converters.Add(new EquatableArrayJsonConverter()); + if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) + options.Converters.Add(new EquatableArrayJsonConverter()); - // spirvCore = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceCoreName)).ReadToEnd(), options); - // spirvGlsl = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceGlslName)).ReadToEnd(), options); - // spirvSDSL = JsonSerializer.Deserialize(new StreamReader(assembly.GetManifestResourceStream(resourceSDSLName)).ReadToEnd(), options); - - - // var config = Configuration.Default.WithDefaultLoader(); - // var htmlContext = BrowsingContext.New(config); - // var documentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceUnifiedName)).ReadToEnd())); - // documentTask.Wait(); - // unifiedDoc = documentTask.Result; - // var glslDocumentTask = htmlContext.OpenAsync(req => req.Content(new StreamReader(assembly.GetManifestResourceStream(resourceGlslRegistryName)).ReadToEnd())); - // glslDocumentTask.Wait(); - // glslDoc = glslDocumentTask.Result; - - // foreach (var o in spirvCore!.OperandKinds) - // operandKinds[o.Kind] = o; - - - + + var grammarData = context .AdditionalTextsProvider - .Where( - static file => - Path.GetFileName(file.Path) switch - { - "spirv.core.grammar.json" - or "spirv.sdsl.grammar-ext.json" - or "extinst.glsl.std.450.grammar.json" - or "SPIRV.html" - or "GLSL.std.450.html" => true, - _ => false - } - ) + .Where(IsSpirvSpecification) .Collect() - .Select( - static (files, _) => - { - SpirvGrammar grammar = new(); - foreach (var file in files) - { - if (Path.GetFileName(file.Path) == "SPIRV.html") - grammar.CoreDoc = file.GetText()?.ToString() ?? ""; - else if (Path.GetFileName(file.Path) == "GLSL.std.450.html") - grammar.GLSLDoc = file.GetText()?.ToString() ?? ""; - else - { - var parsed = JsonSerializer.Deserialize(file.GetText()?.ToString() ?? "{}", options); - if (grammar.MagicNumber == "" && parsed.MagicNumber != "") - { - grammar.MagicNumber = parsed!.MagicNumber; - grammar.MajorVersion = parsed.MajorVersion; - grammar.MinorVersion = parsed.MinorVersion; - grammar.Revision = parsed.Revision; - } - if (parsed.Instructions is not null) - { - InstructionData[] instructions = [.. grammar.Instructions, .. parsed.Instructions]; - grammar.Instructions = instructions; - } - if (parsed.OperandKinds is not null) - { - OpKind[] operandKinds = [.. grammar.OperandKinds, .. parsed.OperandKinds]; - grammar.OperandKinds = operandKinds; - } - - } - } - return grammar; - } - ) - .Select(static (grammar, ct) => - { - var operandKinds = grammar.OperandKinds?.AsArray().ToDictionary(x => x.Kind, x => x.Category); - var config = Configuration.Default.WithDefaultLoader(); - var htmlContext = BrowsingContext.New(config); - var coreTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); - coreTask.Wait(); - var glslTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); - glslTask.Wait(); - var coreDoc = coreTask.Result; - var glslDoc = glslTask.Result; - - var builder = new StringBuilder(); - var buffer = new List(24); - for (int i = 0; i < grammar.Instructions?.AsArray()!.Length; i++) - // foreach (var instruction in grammar.Instructions) - { - var instruction = grammar.Instructions.Value.AsArray()![i]!; - // setup the documentation - var cells = instruction.OpName switch - { - string v when v.Contains("GLSL") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName}\"))"), - string v when v.Contains("SDSL") => null, // SDSL does not have documentation - string => coreDoc!.QuerySelectorAll($"p.tableblock:has(#{instruction.OpName})"), - }; - if (cells is not null) - { - if (cells.FirstOrDefault() is IElement element) - { - var split = element.TextContent.Split('\n'); - builder.Clear(); - builder.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); - foreach (var t in split.Skip(1)) - if (!string.IsNullOrEmpty(t)) - builder.Append("/// ") - .Append(t.Replace("", "id")) - .AppendLine(""); - builder.AppendLine("/// "); - } - instruction.Documentation = builder.ToString(); - } - - - // setup the operand class - buffer.Clear(); - if (instruction.Operands?.AsArray() is OperandData[] operands) - { - foreach (var op in operands) - { - var name = GenerateVariableName(op); - var type = GenerateTypeName(op); - buffer.Add(op with { Class = operandKinds[op.Kind], Name = name, TypeName = type }); - } - instruction.Operands = buffer; - } - - grammar.Instructions.Value.AsArray()![i] = instruction; - - } - return grammar; - } - ); + .Select(PreProcessGrammar) + .Select(PreProcessInstructions); + + context.SyntaxProvider.CreateSyntaxProvider( + predicate: (s, _) => s is ClassDeclarationSyntax or EnumDeclarationSyntax or StructDeclarationSyntax or MemberDeclarationSyntax, + transform: (ctx, _) => ctx + ).Combine(grammarData); CreateInfo(context, grammarData); CreateSDSLOp(context, grammarData); @@ -176,41 +55,45 @@ string v when v.Contains("SDSL") => null, // SDSL does not have documentation context.RegisterImplementationSourceOutput( grammarData, - static (spc, source) => - { - var operandKinds = source.OperandKinds!.Value.AsArray().ToDictionary(x => x.Kind, x => x); - var code = new StringBuilder(); - code - .AppendLine("using static Spv.Specification;") - .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public static class SpirvBufferExtensions") - .AppendLine("{"); - foreach (var instruction in source.Instructions!.Value.AsArray()!) - { - if (instruction.OpName.StartsWith("Op")) - CreateOperation(instruction, code, operandKinds); - else - CreateGlslOperation(instruction, code, operandKinds); - } - code - .AppendLine("}"); - - spc.AddSource("SpirvBufferExtensions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - - } + BufferGeneration ); } + + public static void BufferGeneration(SourceProductionContext spc, SpirvGrammar source) + { + var operandKinds = source.OperandKinds!.Value.AsArray().ToDictionary(x => x.Kind, x => x); + var code = new StringBuilder(); + code + .AppendLine("using static Spv.Specification;") + .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public static class SpirvBufferExtensions") + .AppendLine("{"); + foreach (var instruction in source.Instructions!.Value.AsArray()!) + { + if (instruction.OpName.StartsWith("Op")) + CreateOperation(instruction, code, operandKinds); + else + CreateGlslOperation(instruction, code, operandKinds); + } + code + .AppendLine("}"); + + spc.AddSource("SpirvBufferExtensions.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + + } + + } From a02e7e14eba7474e06e5645207dfa540c661ba78 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 Jun 2025 12:07:26 +0200 Subject: [PATCH 0409/1182] Change prefix from Op to GLSL for GLSL instructions --- .../SPVGenerator.Buffers.cs | 4 ++-- .../SPVGenerator.Helpers.Preprocessing.cs | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index 5e022a9437..e99d12ffe4 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -189,7 +189,7 @@ public static void CreateGlslOperation(InstructionData op, StringBuilder code, D // var comment = AddDocComment(cells); code.AppendLine(op.Documentation); code - .Append("public static Instruction AddGLSL") + .Append("public static Instruction Add") .Append(opname) .Append("(this SpirvBuffer buffer, IdResultType resultType, int resultId, ") .Append(string.Join(", ", normalParameters)) @@ -207,7 +207,7 @@ public static void CreateGlslOperation(InstructionData op, StringBuilder code, D code.AppendLine(op.Documentation); code - .Append("public static Instruction InsertGLSL") + .Append("public static Instruction Insert") .Append(opname) .Append("(this SpirvBuffer buffer, int position, IdResultType resultType, int resultId, ") .Append(string.Join(", ", normalParameters)) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index d5f3faa4bb..4fa34277d3 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -76,12 +76,11 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok // foreach (var instruction in grammar.Instructions) { var instruction = grammar.Instructions.Value.AsArray()![i]!; - if(!instruction.OpName.StartsWith("Op")) - instruction.OpName = $"Op{instruction.OpName}"; + // setup the documentation var cells = instruction.OpName switch { - string v when v.StartsWith("GLSL") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName}\"))"), + string v when !v.StartsWith("Op") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName.Replace("GLSL", "")}\"))"), string v when v.Contains("SDSL") => null, // SDSL does not have documentation string => coreDoc!.QuerySelectorAll($"p.tableblock:has(#{instruction.OpName})"), }; @@ -101,7 +100,9 @@ string v when v.Contains("SDSL") => null, // SDSL does not have documentation } instruction.Documentation = builder.ToString(); } - + + if (!instruction.OpName.StartsWith("Op")) + instruction.OpName = $"GLSL{instruction.OpName}"; // A reusable buffer var buffer = new List<(string, string)>(24); From 19949496199e8130496d9b5503709a38373e5e00 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 11 Jun 2025 14:31:22 +0200 Subject: [PATCH 0410/1182] Removed GLSL instructions from the generation --- src/Stride.Shaders.Spirv.Generators/EquatableArray.cs | 2 ++ src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs | 9 +++++++-- .../SPVGenerator.SDSLOp.cs | 8 +++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs index 98651a6a20..4fce6b4bd5 100644 --- a/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs +++ b/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs @@ -4,6 +4,7 @@ // using System.Collections; +using System.Collections.Immutable; using System.Text.Json; using System.Text.Json.Serialization; @@ -136,4 +137,5 @@ IEnumerator IEnumerable.GetEnumerator() public static implicit operator EquatableArray(T[] arr) => new(arr); public static implicit operator EquatableArray(List list) => new([.. list]); + public static implicit operator EquatableArray(ImmutableArray list) => new([.. list]); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index c8246eaac7..3dfe89056d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -24,8 +24,12 @@ public void CreateInfo(IncrementalGeneratorInitializationContext context, Increm GenerateKinds(context, grammarProvider); - var infoProvider = grammarProvider - .Select(static (grammar, _) => grammar.Instructions!.Value); + IncrementalValueProvider> infoProvider = + grammarProvider + .SelectMany(static (grammar, _) => grammar.Instructions!.Value) + .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + .Collect() + .Select(static (arr, _) => new EquatableArray([.. arr])); context.RegisterImplementationSourceOutput( infoProvider, @@ -109,6 +113,7 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In public static void GenerateInfo(InstructionData op, StringBuilder code) { + var opname = op.OpName; var spvClass = op.Class; if (opname == "OpExtInst") diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 15ff066670..e03faf5ecd 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -24,7 +24,11 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr var instructionsProvider = grammarProvider - .Select((x, _) => x!.Instructions!.Value); + .SelectMany(static (grammar, _) => grammar.Instructions!.Value) + .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + .Collect() + .Select(static (arr, _) => new EquatableArray([.. arr])); + context.RegisterImplementationSourceOutput( instructionsProvider, (ctx, instructionArray) => @@ -43,8 +47,6 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr int lastnum = members.Values.Max(); foreach (var instruction in instructionArray) { - if (instruction.OpName is null) - continue; if (members.TryGetValue(instruction.OpName, out var value)) { if (instruction.OpName.Contains("SDSL") && value <= 0) From 5a4d9fe0c0e7a52bca7467408ef3955b63ebe050 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 14:37:23 +0900 Subject: [PATCH 0411/1182] Mixer (WIP) --- assets/SDSL/TestVertex.sdsl | 13 ++- assets/Stride/SDSL/GenericClass.sdsl | 2 +- src/Stride.Shaders.Experiments/Examples.cs | 103 +++++++++++++++++- src/Stride.Shaders.Experiments/Program.cs | 3 +- .../Stride.Shaders.Spirv.Core.csproj | 9 +- 5 files changed, 120 insertions(+), 10 deletions(-) diff --git a/assets/SDSL/TestVertex.sdsl b/assets/SDSL/TestVertex.sdsl index 8d8077ef71..08faf744ab 100644 --- a/assets/SDSL/TestVertex.sdsl +++ b/assets/SDSL/TestVertex.sdsl @@ -2,10 +2,19 @@ namespace Stride.Shaders.Tests; shader TestVertex { - stream float4 Position : SV_POSITION; + float4 Pos2; + //stream float4 Position : SV_POSITION; + //stream float4 Test : INPUT1; + stream float4 ColorTarget : SV_Target0; void VSMain() { - streams.Position *= float4(1,1,1,0.5f); + Pos2 = Pos2; + streams.Position = streams.Test; + } + + void PSMain() + { + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); } } \ No newline at end of file diff --git a/assets/Stride/SDSL/GenericClass.sdsl b/assets/Stride/SDSL/GenericClass.sdsl index 938068ca99..cba53fa421 100644 --- a/assets/Stride/SDSL/GenericClass.sdsl +++ b/assets/Stride/SDSL/GenericClass.sdsl @@ -5,7 +5,7 @@ shader GenericClass< SamplerState Sampler,// = Texturing.Sampler, Semantic NAME, // = TEXCOORD0 LinkType myLink, - unorm float constFloat, + float constFloat, int2 constInt2, uint3 constUInt3, float4 constUNormFloat4, diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 2ac1f337a0..bb90fc49ee 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -10,9 +10,12 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Processing; +using Stride.Shaders.Spirv.Tools; namespace Stride.Shaders.Experiments; @@ -249,19 +252,115 @@ public static void CompileSDSL() } + public abstract class ShaderSource + { + } + + public struct ShaderMacro + { + public string Name; + public string Definition; + } + + public class ShaderMixinSource : ShaderSource + { + public List Mixins { get; } = []; + + public SortedList Compositions { get; } = []; + + public List Macros { get; } = []; + } + + public sealed class ShaderClassCode(string className) : ShaderSource + { + public string ClassName { get; } = className; + } + + static Dictionary loadedShaders = new(); + + static SpirvBuffer GetOrLoadShader(string name) + { + if (loadedShaders.TryGetValue(name, out var buffer)) + return buffer; + + new ShaderLoader().LoadExternalReference(name, out var bytecode); + buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + + loadedShaders.Add(name, buffer); + + return buffer; + } + public static void MergeSDSL() { CompileSDSL(); - new ShaderLoader().LoadExternalReference("TestBasic", out var bytecode); - var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; + + var buffer = GetOrLoadShader("TestBasic"); + // Step: expand "for" + // TODO + + // Step: build mixins: top level and (TODO) compose + var inheritanceList = new List(); + BuildInheritanceList(buffer, inheritanceList); + inheritanceList.Add("TestBasic"); + + var temp = new SpirvBuffer(); + var offset = 0; + var nextOffset = 0; + foreach (var shaderName in inheritanceList) + { + var shader = GetOrLoadShader(shaderName); + offset += nextOffset; + foreach (var i in shader) + { + temp.Add(i.Words); + + if (i.ResultId != null) + nextOffset = i.ResultId.Value; + i.OffsetIds(offset); + } + } + + var dis = new SpirvDis(temp, true); + dis.Disassemble(true); + + // Step: merge mixins + // start from most-derived class and import on demand + // Step: analyze streams and generate in/out variables //var context = compiler.Context; //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); //new StreamAnalyzer().Process(table, compiler); } + + private static void BuildInheritanceList(SpirvBuffer buffer, List inheritanceList) + { + // Build shader name mapping + var shaderMapping = new Dictionary(); + foreach (var i in buffer) + { + if (i.OpCode == SDSLOp.OpSDSLImportShader) + { + shaderMapping[i.ResultId!.Value] = i.GetOperand("shaderName")!.Value.Value; + } + } + + // Check inheritance + foreach (var i in buffer) + { + if (i.OpCode == SDSLOp.OpSDSLMixinInherit) + { + var shaderName = shaderMapping[i.Words[1]]; + var shader = GetOrLoadShader(shaderName); + BuildInheritanceList(shader, inheritanceList); + inheritanceList.Add(shaderName); + } + } + } } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 089615cebc..09a8bf7505 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -8,7 +8,8 @@ using Stride.Shaders.Spirv.Tools; using static Spv.Specification; -// Examples.CompileSDSL(); +//Examples.CompileSDSL(); +Examples.MergeSDSL(); // Examples.TryAllFiles(); Examples.CreateShader(); diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index cab36fe85d..4e8e6cfc8d 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -11,10 +11,11 @@ + + + - + From 7a894c857ba8333449607337ec81fda7f222340f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 14:47:59 +0900 Subject: [PATCH 0412/1182] Removed Instruction.Index, Instruction.WordIndex and RefInstruction.InstructionIndex --- src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs | 4 ++-- src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs | 2 +- src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs | 10 +++------- .../Parsing/InstructionEnumerator.cs | 2 +- .../Parsing/OrderedEnumerator.cs | 2 +- .../Parsing/RefInstructionEnumerator.cs | 3 +-- .../Parsing/RefMutableFunctionInstructionEnumerator.cs | 3 +-- src/Stride.Shaders.Spirv.Core/RefInstruction.cs | 10 +++------- 8 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 9c929feebd..2c01d0891d 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -53,7 +53,7 @@ public Instruction this[int index] wid += Span[wid] >> 16; id++; } - return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16), index, wid); + return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16)); } } @@ -138,7 +138,7 @@ public Instruction Insert(int start, ReadOnlySpan words) words.CopyTo(_owner.Span.Slice(start, words.Length)); } Length += words.Length; - return new(this, Memory[start..(start + words.Length)], InstructionCount - 1, Length - words.Length); + return new(this, Memory[start..(start + words.Length)]); } void Expand(int size) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs index 1c6fa3444f..ebb55cf076 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs @@ -23,7 +23,7 @@ public readonly Instruction this[int index] wid += Span[wid] >> 16; id++; } - return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16), index, wid); + return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16)); } } public readonly Span Span => Memory.Span; diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index ee92dc3e21..a3c71cfb83 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -9,25 +9,21 @@ namespace Stride.Shaders.Spirv.Core; /// /// /// -/// -/// -public record struct Instruction(ISpirvBuffer Buffer, Memory Words, int Index, int WordIndex) +public record struct Instruction(ISpirvBuffer Buffer, Memory Words) { - public static Instruction Empty { get; } = new(null!, Memory.Empty, 0, 0); + public static Instruction Empty { get; } = new(null!, Memory.Empty); public static implicit operator IdRef(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); public static implicit operator IdResultType(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); - public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Empty, index, 0) + public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Empty) { Buffer = buffer; - Index = index; var wid = 0; for (int i = 0; i < index; i += 1) wid += buffer.InstructionSpan[wid] >> 16; Words = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); - WordIndex = wid; } public SDSLOp OpCode => AsRef().OpCode; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs index 83d00822c8..35d702a76d 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs @@ -42,6 +42,6 @@ public bool MoveNext() public readonly Instruction ParseCurrentInstruction() { var count = buffer.InstructionSpan[wordIndex] >> 16; - return new Instruction(buffer, buffer.InstructionMemory[wordIndex..(wordIndex + count)], index, wordIndex); + return new Instruction(buffer, buffer.InstructionMemory[wordIndex..(wordIndex + count)]); } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 8da66bfaeb..b6f771e267 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -25,7 +25,7 @@ public ref struct OrderedEnumerator(ISpirvBuffer buffer) readonly ISpirvBuffer wbuff = buffer; readonly Span InstructionWords => wbuff.InstructionSpan; - public readonly Instruction Current => new(wbuff, wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16), index, wordIndex); + public readonly Instruction Current => new(wbuff, wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16)); public bool MoveNext() { diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs index e0dc3b5a80..041ff6ffd4 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs @@ -13,8 +13,7 @@ public ref struct RefInstructionEnumerator public readonly RefInstruction Current => RefInstruction.ParseRef( words.Slice(wordIndex, words[wordIndex] >> 16), - wordIndex + (hasHeader ? 5 : 0), - index + wordIndex + (hasHeader ? 5 : 0) ); public RefInstructionEnumerator(Span words, bool hasHeader) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs index 3365fe0618..5fcdf09e7a 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs @@ -15,8 +15,7 @@ public ref struct RefMutableFunctionInstructionEnumerator public readonly RefInstruction Current => RefInstruction.ParseRef( buffer.Span.Slice(wordIndex, buffer.Span[wordIndex] >> 16), - wordIndex, - index + wordIndex ); public RefMutableFunctionInstructionEnumerator(SpirvBuffer buffer, int methodStart) diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index 63fd719156..c47b011595 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -33,7 +33,6 @@ public ref struct RefInstruction public int? ResultType { get => GetResultType(); set => SetResultType(value); } public Span Operands { get; init; } public Memory? Slice { get; init; } - public int InstructionIndex { get; set; } public int WordIndex { get; set; } public Span Words { get; init; } @@ -104,14 +103,13 @@ public bool TryGetOperand(string name, out T? operand) return false; } - public static RefInstruction Parse(Memory owner, int ownerIndex, int index) + public static RefInstruction Parse(Memory owner, int ownerIndex) { var words = owner.Span.Slice(ownerIndex, owner.Span[ownerIndex] >> 16); return new RefInstruction() { Operands = words[1..], WordIndex = ownerIndex, - InstructionIndex = index, Slice = owner, Words = words }; @@ -124,13 +122,12 @@ public static RefInstruction Parse(Memory owner, int ownerIndex, int index) // Words = words, // }; // } - public static RefInstruction ParseRef(Span words, int? wordIndex = null, int? index = null) + public static RefInstruction ParseRef(Span words, int? wordIndex = null) { return new RefInstruction() { Words = words, WordIndex = wordIndex ?? -1, - InstructionIndex = index ?? -1, Operands = words[1..] }; } @@ -184,8 +181,7 @@ public void OffsetIds(int offset) public readonly Instruction ToOwned(SpirvBuffer buffer) { - if (InstructionIndex == -1) throw new Exception("Instruction not found"); - return new(buffer, buffer.Memory[WordIndex..(WordIndex + WordCount)], InstructionIndex, WordIndex); + return new(buffer, buffer.Memory[WordIndex..(WordIndex + WordCount)]); } public override string ToString() From 5f22d9ed7cf10b03a35531644f63c073e563d467 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 15:36:39 +0900 Subject: [PATCH 0413/1182] Simplify Instruction classes --- .../Buffers/SpirvBuffer.cs | 6 +++--- .../Buffers/SpirvMemory.cs | 2 +- .../Information/InstructionInfo.Order.cs | 2 +- .../MemoryInstruction.cs | 17 +++++++++-------- .../Parsing/InstructionEnumerator.cs | 2 +- .../Parsing/OrderedEnumerator.cs | 2 +- src/Stride.Shaders.Spirv.Core/RefInstruction.cs | 4 +--- 7 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 2c01d0891d..1c682a7bef 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -53,7 +53,7 @@ public Instruction this[int index] wid += Span[wid] >> 16; id++; } - return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16)); + return new Instruction(Memory.Slice(wid, Span[wid] >> 16)); } } @@ -100,7 +100,7 @@ public void Sort() var pos = 5; while (sorted.MoveNext()) { - sorted.Current.Words.CopyTo(other.Memory[pos..]); + sorted.Current.Memory.CopyTo(other.Memory[pos..]); pos += sorted.Current.WordCount; } _owner.Span[0..5].CopyTo(other.Span[0..5]); @@ -138,7 +138,7 @@ public Instruction Insert(int start, ReadOnlySpan words) words.CopyTo(_owner.Span.Slice(start, words.Length)); } Length += words.Length; - return new(this, Memory[start..(start + words.Length)]); + return new(Memory[start..(start + words.Length)]); } void Expand(int size) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs index ebb55cf076..15e67f0fa2 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs @@ -23,7 +23,7 @@ public readonly Instruction this[int index] wid += Span[wid] >> 16; id++; } - return new Instruction(this, Memory.Slice(wid, Span[wid] >> 16)); + return new Instruction(Memory.Slice(wid, Span[wid] >> 16)); } } public readonly Span Span => Memory.Span; diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index b98b3f2012..51bb6b1622 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -107,7 +107,7 @@ public static int GetGroupOrder(RefInstruction instruction) /// public static int GetGroupOrder(Instruction instruction) { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words.Span[3] : null); + return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); } /// /// Gets the order group for a given instruction and Storage class, useful for sorting instructions according to the specification. diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index a3c71cfb83..a81586975d 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -9,34 +9,35 @@ namespace Stride.Shaders.Spirv.Core; /// /// /// -public record struct Instruction(ISpirvBuffer Buffer, Memory Words) +public record struct Instruction(Memory Memory) { - public static Instruction Empty { get; } = new(null!, Memory.Empty); + public static Instruction Empty { get; } = new(Memory.Empty); public static implicit operator IdRef(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); public static implicit operator IdResultType(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); - public Instruction(ISpirvBuffer buffer, int index) : this(buffer, Memory.Empty) + public Instruction(ISpirvBuffer buffer, int index) : this(Memory.Empty) { - Buffer = buffer; var wid = 0; for (int i = 0; i < index; i += 1) wid += buffer.InstructionSpan[wid] >> 16; - Words = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); + Memory = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); } public SDSLOp OpCode => AsRef().OpCode; public readonly int? ResultId { get => AsRef().ResultId; set => AsRef().SetResultId(value); } public readonly int? ResultType { get => AsRef().ResultType; set => AsRef().SetResultType(value); } public readonly int WordCount => Words.Length; - public readonly Memory Operands => Words[1..]; + public readonly Memory Operands => Memory[1..]; + + public readonly Span Words => Memory.Span; public bool IsEmpty => Words.IsEmpty; - public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Words.Span); + public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Memory.Span); public readonly TWrapper UnsafeAs() where TWrapper : struct, IWrapperInstruction, allows ref struct - => RefInstruction.ParseRef(Words.Span).UnsafeAs(); + => RefInstruction.ParseRef(Memory.Span).UnsafeAs(); public readonly T? GetOperand(string name) where T : struct, IFromSpirv => AsRef().GetOperand(name); diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs index 35d702a76d..ec91ad7ed1 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs @@ -42,6 +42,6 @@ public bool MoveNext() public readonly Instruction ParseCurrentInstruction() { var count = buffer.InstructionSpan[wordIndex] >> 16; - return new Instruction(buffer, buffer.InstructionMemory[wordIndex..(wordIndex + count)]); + return new Instruction(buffer.InstructionMemory[wordIndex..(wordIndex + count)]); } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index b6f771e267..95c354b003 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -25,7 +25,7 @@ public ref struct OrderedEnumerator(ISpirvBuffer buffer) readonly ISpirvBuffer wbuff = buffer; readonly Span InstructionWords => wbuff.InstructionSpan; - public readonly Instruction Current => new(wbuff, wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16)); + public readonly Instruction Current => new(wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16)); public bool MoveNext() { diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index c47b011595..fef3b75223 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -32,7 +32,6 @@ public ref struct RefInstruction public int? ResultId { get => GetResultId(); set => SetResultId(value); } public int? ResultType { get => GetResultType(); set => SetResultType(value); } public Span Operands { get; init; } - public Memory? Slice { get; init; } public int WordIndex { get; set; } public Span Words { get; init; } @@ -110,7 +109,6 @@ public static RefInstruction Parse(Memory owner, int ownerIndex) { Operands = words[1..], WordIndex = ownerIndex, - Slice = owner, Words = words }; } @@ -181,7 +179,7 @@ public void OffsetIds(int offset) public readonly Instruction ToOwned(SpirvBuffer buffer) { - return new(buffer, buffer.Memory[WordIndex..(WordIndex + WordCount)]); + return new(buffer.Memory[WordIndex..(WordIndex + WordCount)]); } public override string ToString() From 152d37d65b5342517dd840965cf6e1c1ffe36814 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 15:58:26 +0900 Subject: [PATCH 0414/1182] Removed most usages of RefInstruction --- .../Buffers/ISpirvBuffer.cs | 2 +- .../Buffers/SpirvBuffer.cs | 4 +- .../Buffers/SpirvMemory.cs | 2 +- .../Buffers/SpirvSpan.cs | 2 +- .../IWrapperInstruction.cs | 6 + .../MemoryInstruction.cs | 131 ++++++++++-- .../Parsing/InstructionEnumerator.cs | 13 +- .../Parsing/IntExtensions.cs | 13 ++ ...> MutableFunctionInstructionEnumerator.cs} | 16 +- .../Parsing/OperandEnumerator.cs | 16 +- .../Parsing/RefOperandEnumerator.cs | 187 ++++++++++++++++++ .../Parsing/SpirvReader.cs | 2 +- .../RefInstruction.cs | 17 +- .../SPVGenerator.Instructions.cs | 5 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 10 +- .../Spirv/Processing/StreamAnalyzer.cs | 6 +- .../Spirv/Tools/SpirvDis.Appends.cs | 2 +- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 2 +- 18 files changed, 364 insertions(+), 72 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs rename src/Stride.Shaders.Spirv.Core/Parsing/{RefMutableFunctionInstructionEnumerator.cs => MutableFunctionInstructionEnumerator.cs} (66%) create mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs index 4181e64e60..b11ce0fdf6 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs @@ -61,5 +61,5 @@ public interface ISpirvBuffer /// Gets Instruction enumerator /// /// Instruction enumerator - public RefInstructionEnumerator GetEnumerator(); + public InstructionEnumerator GetEnumerator(); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 1c682a7bef..26ed0d1bd5 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -31,7 +31,7 @@ public RefHeader Header public int InstructionCount => new SpirvReader(Memory).Count; - public RefInstruction FindInstructionByResultId(int resultId) + public Instruction FindInstructionByResultId(int resultId) { foreach (var instruction in this) { @@ -91,7 +91,7 @@ public SpirvBuffer(Span span) } - public RefInstructionEnumerator GetEnumerator() => new(InstructionSpan, HasHeader); + public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); public void Sort() { diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs index 15e67f0fa2..0a962c4ec7 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs @@ -53,5 +53,5 @@ public readonly RefHeader Header public readonly SpirvSpan AsSpan() => new(Span); - public RefInstructionEnumerator GetEnumerator() => new(InstructionSpan, HasHeader); + public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs index faa06270b7..180eb8fe01 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs @@ -41,5 +41,5 @@ public readonly RefHeader Header public readonly SpirvSpan AsSpan() => this; - public RefInstructionEnumerator GetEnumerator() => new(Span, HasHeader); + public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); } diff --git a/src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs b/src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs new file mode 100644 index 0000000000..5204533784 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs @@ -0,0 +1,6 @@ +namespace Stride.Shaders.Spirv.Core; + +public interface IWrapperInstruction +{ + Instruction Inner { get; set; } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index a81586975d..c28fc1ea65 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Spirv.Core.Buffers; +using System.Runtime.CompilerServices; +using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; @@ -25,30 +26,136 @@ public Instruction(ISpirvBuffer buffer, int index) : this(Memory.Empty) Memory = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); } - public SDSLOp OpCode => AsRef().OpCode; - public readonly int? ResultId { get => AsRef().ResultId; set => AsRef().SetResultId(value); } - public readonly int? ResultType { get => AsRef().ResultType; set => AsRef().SetResultType(value); } + public readonly SDSLOp OpCode => (SDSLOp)(Words[0] & 0xFFFF); + public int? ResultId { get => GetResultId(); set => SetResultId(value); } + public int? ResultType { get => GetResultType(); set => SetResultType(value); } public readonly int WordCount => Words.Length; - public readonly Memory Operands => Memory[1..]; + public readonly Span Operands => Memory[1..].Span; public readonly Span Words => Memory.Span; public bool IsEmpty => Words.IsEmpty; public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Memory.Span); - public readonly TWrapper UnsafeAs() where TWrapper : struct, IWrapperInstruction, allows ref struct - => RefInstruction.ParseRef(Memory.Span).UnsafeAs(); + public TWrapper UnsafeAs() + where TWrapper : struct, IWrapperInstruction, allows ref struct + { + return new TWrapper() + { + Inner = this + }; + } - public readonly T? GetOperand(string name) where T : struct, IFromSpirv - => AsRef().GetOperand(name); + public T? GetOperand(string name) + where T : struct, IFromSpirv + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + return operandEnumerator.Current.To(); + } + } + } + return null; + } - public readonly bool TryGetOperand(string name, out T? operand) where T : struct, IFromSpirv - => AsRef().TryGetOperand(name, out operand); + internal T? GetEnumOperand(string name) + where T : Enum + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + var curr = operandEnumerator.Current; + return Unsafe.As(ref curr.Words[0]); + } + } + } + return default; + } - public readonly OperandEnumerator GetEnumerator() => AsRef().GetEnumerator(); + public readonly OperandEnumerator GetEnumerator() => new(this); public override string ToString() { return (ResultId == null ? "" : $"%{ResultId} = ") + $"{OpCode} {string.Join(" ", Operands.ToArray().Select(x => x.ToString()))}"; } + + public int? GetResultId() + { + TryGetOperand("resultId", out var resultId); + return resultId; + } + + public void SetResultId(int? value) + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResult) + o.Words[0] = value ?? -1; + } + public int? GetResultType() + { + TryGetOperand("resultType", out var resultId); + return resultId; + } + public void SetResultType(int? value) + { + foreach (var o in this) + if (o.Kind == OperandKind.IdResultType) + o.Words[0] = value ?? -1; + } + + public bool TryGetOperand(string name, out T? operand) + where T : struct, IFromSpirv + { + var info = InstructionInfo.GetInfo(OpCode); + var infoEnumerator = info.GetEnumerator(); + var operandEnumerator = GetEnumerator(); + while (infoEnumerator.MoveNext()) + { + if (operandEnumerator.MoveNext()) + { + if (infoEnumerator.Current.Name == name) + { + operand = operandEnumerator.Current.To(); + return true; + } + } + } + operand = null; + return false; + } + + public void OffsetIds(int offset) + { + foreach (var o in this) + { + if (o.Kind == OperandKind.IdRef) + o.Words[0] += offset; + else if (o.Kind == OperandKind.IdResult) + o.Words[0] += offset; + else if (o.Kind == OperandKind.IdResultType) + o.Words[0] += offset; + else if (o.Kind == OperandKind.PairIdRefLiteralInteger) + o.Words[0] += offset; + else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) + o.Words[1] += offset; + else if (o.Kind == OperandKind.PairIdRefIdRef) + { + o.Words[0] += offset; + o.Words[1] += offset; + } + } + } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs index ec91ad7ed1..57ef62531a 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs @@ -6,12 +6,11 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// /// A simple SPIR-V instruction enumerator without sorting /// -public ref struct InstructionEnumerator(ISpirvBuffer buffer) +public ref struct InstructionEnumerator(Memory InstructionMemory, bool HasHeader) { int wordIndex = 0; int index; bool started = false; - readonly ISpirvBuffer buffer = buffer; public int ResultIdReplacement { get; set; } = 0; @@ -26,12 +25,12 @@ public bool MoveNext() } else { - if (wordIndex >= buffer.InstructionSpan.Length) + if (wordIndex >= InstructionMemory.Span.Length) return false; - var sizeToStep = buffer.InstructionSpan[wordIndex] >> 16; + var sizeToStep = InstructionMemory.Span[wordIndex] >> 16; wordIndex += sizeToStep; index += 1; - if (wordIndex >= buffer.InstructionSpan.Length) + if (wordIndex >= InstructionMemory.Span.Length) return false; return true; } @@ -41,7 +40,7 @@ public bool MoveNext() public readonly Instruction ParseCurrentInstruction() { - var count = buffer.InstructionSpan[wordIndex] >> 16; - return new Instruction(buffer.InstructionMemory[wordIndex..(wordIndex + count)]); + var count = InstructionMemory.Span[wordIndex] >> 16; + return new Instruction(InstructionMemory[wordIndex..(wordIndex + count)]); } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs b/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs new file mode 100644 index 0000000000..a4724ec1ca --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs @@ -0,0 +1,13 @@ +namespace Stride.Shaders.Spirv.Core.Parsing; + +public static class IntExtensions +{ + public static bool HasEndString(this int i) + { + return + (char)(i >> 24) == '\0' + || (char)(i >> 16 & 0XFF) == '\0' + || (char)(i >> 8 & 0xFF) == '\0' + || (char)(i & 0xFF) == '\0'; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs similarity index 66% rename from src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs rename to src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs index 5fcdf09e7a..de4cf19e56 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefMutableFunctionInstructionEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs @@ -6,19 +6,15 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// /// Instruction enumerator returning RefInstruction /// -public ref struct RefMutableFunctionInstructionEnumerator +public ref struct MutableFunctionInstructionEnumerator { int wordIndex; int index; readonly SpirvBuffer buffer; - public readonly RefInstruction Current => - RefInstruction.ParseRef( - buffer.Span.Slice(wordIndex, buffer.Span[wordIndex] >> 16), - wordIndex - ); + public Instruction Current => ParseCurrentInstruction(); - public RefMutableFunctionInstructionEnumerator(SpirvBuffer buffer, int methodStart) + public MutableFunctionInstructionEnumerator(SpirvBuffer buffer, int methodStart) { wordIndex = methodStart; index = -1; @@ -43,4 +39,10 @@ public bool MoveNext() return true; } } + + public readonly Instruction ParseCurrentInstruction() + { + var count = buffer.InstructionMemory.Span[wordIndex] >> 16; + return new Instruction(buffer.InstructionMemory[wordIndex..(wordIndex + count)]); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index 96a032acd9..954ecbf70e 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -8,13 +8,13 @@ namespace Stride.Shaders.Spirv.Core.Parsing; public ref struct OperandEnumerator { static OperandKind[] pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); - RefInstruction instruction; + Instruction instruction; Span operands => instruction.Operands; readonly LogicalOperandArray logicalOperands; int wid; int oid; - public OperandEnumerator(RefInstruction instruction) + public OperandEnumerator(Instruction instruction) { this.instruction = instruction; Decoration? decoration = instruction.OpCode switch @@ -184,16 +184,4 @@ public SpvOperand ParseCurrent() } } -} - -public static class IntExtensions -{ - public static bool HasEndString(this int i) - { - return - (char)(i >> 24) == '\0' - || (char)(i >> 16 & 0XFF) == '\0' - || (char)(i >> 8 & 0xFF) == '\0' - || (char)(i & 0xFF) == '\0'; - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs new file mode 100644 index 0000000000..b463410c25 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs @@ -0,0 +1,187 @@ +using static Spv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// An instruction operands enumerator, useful for parsing instructions +/// +public ref struct RefOperandEnumerator +{ + static OperandKind[] pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); + RefInstruction instruction; + Span operands => instruction.Operands; + readonly LogicalOperandArray logicalOperands; + int wid; + int oid; + + public RefOperandEnumerator(RefInstruction instruction) + { + this.instruction = instruction; + Decoration? decoration = instruction.OpCode switch + { + SDSLOp.OpDecorateString + or SDSLOp.OpDecorate + or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], + SDSLOp.OpMemberDecorate + or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], + _ => null + }; + logicalOperands = InstructionInfo.GetInfo(new(instruction.OpCode, decoration)); + oid = -1; + wid = 0; + } + + public SpvOperand Current => ParseCurrent(); + + public bool MoveNext() + { + if (oid < 0) + { + oid = 0; + if (logicalOperands[0].Kind == OperandKind.None) + return false; + return true; + } + else if(oid >= logicalOperands.Count - 1) + return false; + else + { + var logOp = logicalOperands[oid]; + + if (logOp.Quantifier == OperandQuantifier.One) + { + if (logOp.Kind == OperandKind.LiteralString) + { + while (!operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) + wid += 2; + else + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) + { + if ( + pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) + && wid < operands.Length - 1 + ) + { + wid += 2; + } + else if ( + logOp.Kind == OperandKind.LiteralString + && wid < operands.Length + ) + { + while (!operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (wid < operands.Length) + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + throw new NotImplementedException("params of strings is not yet implemented"); + else if ( + pairs.Contains(logOp.Kind ?? throw new Exception()) + && wid < operands.Length - 2 + ) + wid += 2; + else if (wid < operands.Length - 1) + wid += 1; + else + oid += 1; + + } + return wid < operands.Length; + } + + } + + public SpvOperand ParseCurrent() + { + var logOp = logicalOperands[oid]; + // if (instruction.OpCode == SDSLOp.OpDecorate) + // { + // SpvOperand result = new(); + // if (oid == 0) + // result = new(OperandKind.IdRef, OperandQuantifier.One, operands.Slice(wid, 1)); + // else if (oid == 1) + // result = new(OperandKind.Decoration, OperandQuantifier.One, operands.Slice(wid, 1)); + // else if (oid == 2) + // { + // result = result with + // { + // Kind = (Decoration)operands[1] switch + // { + // Decoration.BuiltIn => OperandKind.BuiltIn, + // Decoration.Location => OperandKind.LiteralInteger, + // Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, + // Decoration.ArrayStride => OperandKind.LiteralInteger, + // Decoration.MatrixStride => OperandKind.LiteralInteger, + // Decoration.UniformId => OperandKind.IdScope, + // Decoration.Stream => OperandKind.LiteralInteger, + // Decoration.Component => OperandKind.LiteralInteger, + // Decoration.Index => OperandKind.LiteralInteger, + // Decoration.Binding => OperandKind.LiteralInteger, + // Decoration.DescriptorSet => OperandKind.LiteralInteger, + // Decoration.Offset => OperandKind.LiteralInteger, + // Decoration.XfbBuffer => OperandKind.LiteralInteger, + // Decoration.XfbStride => OperandKind.LiteralInteger, + // Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, + // Decoration.FPRoundingMode => OperandKind.FPRoundingMode, + // Decoration.FPFastMathMode => OperandKind.FPFastMathMode, + // Decoration.LinkageAttributes => OperandKind.LiteralString, + // Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, + // Decoration.Alignment => OperandKind.LiteralInteger, + // Decoration.MaxByteOffset => OperandKind.LiteralInteger, + // Decoration.AlignmentId => OperandKind.IdRef, + // Decoration.MaxByteOffsetId => OperandKind.IdRef, + // Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, + // Decoration.CounterBuffer => OperandKind.IdRef, + // _ => OperandKind.None + // } + // }; + // } + // return result; + + // } + // else + if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + { + var length = 0; + while (!operands[wid + length].HasEndString()) + length += 1; + length += 1; + var result = new SpvOperand(OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, length)); + + return result; + } + else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) + { + var result = new SpvOperand(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + return result; + } + else + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + } + else + { + if (pairs.Contains(logOp.Kind ?? OperandKind.None)) + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + else + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + } + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index 1e489e6316..d5575bbe0c 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -15,7 +15,7 @@ public static void ParseToList(byte[] byteCode, List instructions) var span = MemoryMarshal.Cast(byteCode.AsSpan()); var data = new SpirvBuffer(span); foreach (var instruction in data) - instructions.Add(instruction.ToOwned(data)); + instructions.Add(instruction); } diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index fef3b75223..5328c5f33c 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -8,12 +8,6 @@ namespace Stride.Shaders.Spirv.Core; -public interface IWrapperInstruction -{ - RefInstruction Inner { get; set; } -} - - /// /// A ref struct representation of an instruction in a buffer. /// @@ -40,7 +34,7 @@ public ref struct RefInstruction - public OperandEnumerator GetEnumerator() => new(this); + public RefOperandEnumerator GetEnumerator() => new(this); public T? GetOperand(string name) @@ -192,13 +186,4 @@ public override string ToString() } return builder.ToString(); } - - public TWrapper UnsafeAs() - where TWrapper : struct, IWrapperInstruction, allows ref struct - { - return new TWrapper() - { - Inner = this - }; - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 4ceed5a901..ab7182b027 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -40,7 +40,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat builder .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") .AppendLine("{") - .AppendLine("public RefInstruction Inner { get; set; }"); + .AppendLine("public Instruction Inner { get; set; }"); try { if (instruction.Operands != null) @@ -87,8 +87,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat builder .AppendLine() - .AppendLine($"public Ref{instruction.OpName}(RefInstruction instruction) => Inner = instruction;") - .AppendLine($"public Ref{instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);"); + .AppendLine($"public Ref{instruction.OpName}(Instruction instruction) => Inner = instruction;"); builder diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 1d93dc9ad1..c7617e8d81 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System; namespace Stride.Shaders.Spirv.Building; @@ -31,6 +32,7 @@ public void SetPositionTo(TBlock block, bool beggining = false) (int)SDSLOp.OpUnreachable, (int)SDSLOp.OpTerminateInvocation ]; + var wid = 0; foreach (var e in Buffer) { if (e.ResultId is int id && id == block.Id) @@ -39,20 +41,22 @@ public void SetPositionTo(TBlock block, bool beggining = false) // In case we want to top at the beginning of the block if(beggining) { - Position = e.WordIndex + e.WordCount; + Position = wid + e.WordCount; return; } } if (block is SpirvBlock && blockFound && blockTermination.Contains((int)e.OpCode)) { - Position = e.WordIndex; + Position = wid; return; } else if (block is SpirvFunction && blockFound && e.OpCode == SDSLOp.OpFunctionEnd) { - Position = e.WordIndex; + Position = wid; return; } + + wid += e.WordCount; } Position = Buffer.Length; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 95dc849b41..c2a7a19c82 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -238,7 +238,7 @@ private void GenerateStreamWrapper(SymbolTable table, CompilerUnit compiler, Spe private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList streams) { var methodStart = FindMethodStart(compiler, functionId); - var enumerator = new RefMutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); + var enumerator = new MutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); while (enumerator.MoveNext()) { @@ -282,13 +282,15 @@ private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList writer.AppendLine(); - public readonly void Append(in SpvOperand o, in RefInstruction instruction) + public readonly void Append(in SpvOperand o, in Instruction instruction) { if (o.Kind == OperandKind.IdRef) foreach (var e in o.Words) diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index ae387ecbcd..a58c4d781e 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -108,7 +108,7 @@ public string Disassemble(bool writeToConsole = false) } // TODO : add other names - public readonly void CheckNameTable(RefInstruction instruction) + public readonly void CheckNameTable(Instruction instruction) { if ( UseNames From 516ce7140d1fa196cefc61abf457a053d0e28fdd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 16:01:30 +0900 Subject: [PATCH 0415/1182] Removed RefInstruction --- .../Buffers/SpirvBuffer.cs | 2 +- .../Information/InstructionInfo.Order.cs | 11 +- .../MemoryInstruction.cs | 1 - .../Parsing/RefInstructionEnumerator.cs | 43 ---- .../Parsing/RefOperandEnumerator.cs | 187 ----------------- .../Parsing/SpirvReader.cs | 2 +- .../RefInstruction.cs | 189 ------------------ .../Spirv/Processing/IPostProcessorSubPass.cs | 2 +- 8 files changed, 4 insertions(+), 433 deletions(-) delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/RefInstruction.cs diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 26ed0d1bd5..90638f80a8 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -113,7 +113,7 @@ public void Sort() public Instruction Add(Span instruction) { var result = Insert(Length, instruction); - if (RefInstruction.ParseRef(instruction).ResultId is int resultId && resultId >= Header.Bound) + if (result.ResultId is int resultId && resultId >= Header.Bound) Header = Header with { Bound = resultId + 1 }; return result; } diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 51bb6b1622..2e49a83cf9 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -90,16 +90,6 @@ void InitOrder() group++; OrderGroup[(SDSLOp.OpSDSLShaderEnd, null)] = group; } - /// - /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. - /// - /// - /// - public static int GetGroupOrder(RefInstruction instruction) - { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); - } - /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. /// @@ -109,6 +99,7 @@ public static int GetGroupOrder(Instruction instruction) { return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); } + /// /// Gets the order group for a given instruction and Storage class, useful for sorting instructions according to the specification. /// diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index c28fc1ea65..38bf8b86f7 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -36,7 +36,6 @@ public Instruction(ISpirvBuffer buffer, int index) : this(Memory.Empty) public bool IsEmpty => Words.IsEmpty; - public readonly RefInstruction AsRef() => RefInstruction.ParseRef(Memory.Span); public TWrapper UnsafeAs() where TWrapper : struct, IWrapperInstruction, allows ref struct { diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs deleted file mode 100644 index 041ff6ffd4..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefInstructionEnumerator.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// Instruction enumerator returning RefInstruction -/// -public ref struct RefInstructionEnumerator -{ - int wordIndex; - int index; - readonly Span words; - readonly bool hasHeader; - - public readonly RefInstruction Current => - RefInstruction.ParseRef( - words.Slice(wordIndex, words[wordIndex] >> 16), - wordIndex + (hasHeader ? 5 : 0) - ); - - public RefInstructionEnumerator(Span words, bool hasHeader) - { - wordIndex = -1; - index = 0; - this.words = words; - this.hasHeader = hasHeader; - } - - public bool MoveNext() - { - if (wordIndex == -1) - { - wordIndex = 0; - return true; - } - else - { - if (wordIndex + (words[wordIndex] >> 16) >= words.Length) - return false; - wordIndex += words[wordIndex] >> 16; - index += 1; - return true; - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs deleted file mode 100644 index b463410c25..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefOperandEnumerator.cs +++ /dev/null @@ -1,187 +0,0 @@ -using static Spv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// An instruction operands enumerator, useful for parsing instructions -/// -public ref struct RefOperandEnumerator -{ - static OperandKind[] pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); - RefInstruction instruction; - Span operands => instruction.Operands; - readonly LogicalOperandArray logicalOperands; - int wid; - int oid; - - public RefOperandEnumerator(RefInstruction instruction) - { - this.instruction = instruction; - Decoration? decoration = instruction.OpCode switch - { - SDSLOp.OpDecorateString - or SDSLOp.OpDecorate - or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], - SDSLOp.OpMemberDecorate - or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], - _ => null - }; - logicalOperands = InstructionInfo.GetInfo(new(instruction.OpCode, decoration)); - oid = -1; - wid = 0; - } - - public SpvOperand Current => ParseCurrent(); - - public bool MoveNext() - { - if (oid < 0) - { - oid = 0; - if (logicalOperands[0].Kind == OperandKind.None) - return false; - return true; - } - else if(oid >= logicalOperands.Count - 1) - return false; - else - { - var logOp = logicalOperands[oid]; - - if (logOp.Quantifier == OperandQuantifier.One) - { - if (logOp.Kind == OperandKind.LiteralString) - { - while (!operands[wid].HasEndString()) - wid += 1; - wid += 1; - } - else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) - wid += 2; - else - wid += 1; - oid += 1; - - } - else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) - { - if ( - pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) - && wid < operands.Length - 1 - ) - { - wid += 2; - } - else if ( - logOp.Kind == OperandKind.LiteralString - && wid < operands.Length - ) - { - while (!operands[wid].HasEndString()) - wid += 1; - wid += 1; - } - else if (wid < operands.Length) - wid += 1; - oid += 1; - - } - else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) - { - if (logOp.Kind == OperandKind.LiteralString) - throw new NotImplementedException("params of strings is not yet implemented"); - else if ( - pairs.Contains(logOp.Kind ?? throw new Exception()) - && wid < operands.Length - 2 - ) - wid += 2; - else if (wid < operands.Length - 1) - wid += 1; - else - oid += 1; - - } - return wid < operands.Length; - } - - } - - public SpvOperand ParseCurrent() - { - var logOp = logicalOperands[oid]; - // if (instruction.OpCode == SDSLOp.OpDecorate) - // { - // SpvOperand result = new(); - // if (oid == 0) - // result = new(OperandKind.IdRef, OperandQuantifier.One, operands.Slice(wid, 1)); - // else if (oid == 1) - // result = new(OperandKind.Decoration, OperandQuantifier.One, operands.Slice(wid, 1)); - // else if (oid == 2) - // { - // result = result with - // { - // Kind = (Decoration)operands[1] switch - // { - // Decoration.BuiltIn => OperandKind.BuiltIn, - // Decoration.Location => OperandKind.LiteralInteger, - // Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, - // Decoration.ArrayStride => OperandKind.LiteralInteger, - // Decoration.MatrixStride => OperandKind.LiteralInteger, - // Decoration.UniformId => OperandKind.IdScope, - // Decoration.Stream => OperandKind.LiteralInteger, - // Decoration.Component => OperandKind.LiteralInteger, - // Decoration.Index => OperandKind.LiteralInteger, - // Decoration.Binding => OperandKind.LiteralInteger, - // Decoration.DescriptorSet => OperandKind.LiteralInteger, - // Decoration.Offset => OperandKind.LiteralInteger, - // Decoration.XfbBuffer => OperandKind.LiteralInteger, - // Decoration.XfbStride => OperandKind.LiteralInteger, - // Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, - // Decoration.FPRoundingMode => OperandKind.FPRoundingMode, - // Decoration.FPFastMathMode => OperandKind.FPFastMathMode, - // Decoration.LinkageAttributes => OperandKind.LiteralString, - // Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, - // Decoration.Alignment => OperandKind.LiteralInteger, - // Decoration.MaxByteOffset => OperandKind.LiteralInteger, - // Decoration.AlignmentId => OperandKind.IdRef, - // Decoration.MaxByteOffsetId => OperandKind.IdRef, - // Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, - // Decoration.CounterBuffer => OperandKind.IdRef, - // _ => OperandKind.None - // } - // }; - // } - // return result; - - // } - // else - if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) - { - if (logOp.Kind == OperandKind.LiteralString) - { - var length = 0; - while (!operands[wid + length].HasEndString()) - length += 1; - length += 1; - var result = new SpvOperand(OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, length)); - - return result; - } - else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) - { - var result = new SpvOperand(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); - return result; - } - else - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); - } - else - { - if (pairs.Contains(logOp.Kind ?? OperandKind.None)) - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); - else - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); - } - } - -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index d5575bbe0c..4e35f91967 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -52,7 +52,7 @@ public SpirvReader(SpirvSpan span) } - public readonly RefInstructionEnumerator GetEnumerator() => new(buffer.Span, HasHeader); + public readonly InstructionEnumerator GetEnumerator() => new(buffer.Memory, HasHeader); public readonly int GetInstructionCount() { diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs deleted file mode 100644 index 5328c5f33c..0000000000 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; - - -namespace Stride.Shaders.Spirv.Core; - -/// -/// A ref struct representation of an instruction in a buffer. -/// -public ref struct RefInstruction -{ - - public static RefInstruction Empty => new() { Words = [], Operands = [] }; - - - /// - /// Word Count is the high-order 16 bits of word 0 of the instruction, holding its total WordCount. - ///
If the instruction takes a variable number of operands, Word Count also says "+ variable", after stating the minimum size of the instruction. - ///
- public readonly int WordCount => Words[0] >> 16; - public readonly SDSLOp OpCode => (SDSLOp)(Words[0] & 0xFFFF); - public int? ResultId { get => GetResultId(); set => SetResultId(value); } - public int? ResultType { get => GetResultType(); set => SetResultType(value); } - public Span Operands { get; init; } - public int WordIndex { get; set; } - public Span Words { get; init; } - - public readonly bool IsEmpty => Words.IsEmpty; - - - - - public RefOperandEnumerator GetEnumerator() => new(this); - - - public T? GetOperand(string name) - where T : struct, IFromSpirv - { - var info = InstructionInfo.GetInfo(OpCode); - var infoEnumerator = info.GetEnumerator(); - var operandEnumerator = GetEnumerator(); - while (infoEnumerator.MoveNext()) - { - if (operandEnumerator.MoveNext()) - { - if (infoEnumerator.Current.Name == name) - { - return operandEnumerator.Current.To(); - } - } - } - return null; - } - internal T? GetEnumOperand(string name) - where T : Enum - { - var info = InstructionInfo.GetInfo(OpCode); - var infoEnumerator = info.GetEnumerator(); - var operandEnumerator = GetEnumerator(); - while (infoEnumerator.MoveNext()) - { - if (operandEnumerator.MoveNext()) - { - if (infoEnumerator.Current.Name == name) - { - var curr = operandEnumerator.Current; - return Unsafe.As(ref curr.Words[0]); - } - } - } - return default; - } - - public bool TryGetOperand(string name, out T? operand) - where T : struct, IFromSpirv - { - var info = InstructionInfo.GetInfo(OpCode); - var infoEnumerator = info.GetEnumerator(); - var operandEnumerator = GetEnumerator(); - while (infoEnumerator.MoveNext()) - { - if (operandEnumerator.MoveNext()) - { - if (infoEnumerator.Current.Name == name) - { - operand = operandEnumerator.Current.To(); - return true; - } - } - } - operand = null; - return false; - } - - public static RefInstruction Parse(Memory owner, int ownerIndex) - { - var words = owner.Span.Slice(ownerIndex, owner.Span[ownerIndex] >> 16); - return new RefInstruction() - { - Operands = words[1..], - WordIndex = ownerIndex, - Words = words - }; - } - // public static RefInstruction ParseRef(ReadOnlySpan words) - // { - // return new RefInstruction() - // { - // Operands = words[1..], - // Words = words, - // }; - // } - public static RefInstruction ParseRef(Span words, int? wordIndex = null) - { - return new RefInstruction() - { - Words = words, - WordIndex = wordIndex ?? -1, - Operands = words[1..] - }; - } - - - public int? GetResultId() - { - TryGetOperand("resultId", out var resultId); - return resultId; - } - - public void SetResultId(int? value) - { - foreach (var o in this) - if (o.Kind == OperandKind.IdResult) - o.Words[0] = value ?? -1; - } - public int? GetResultType() - { - TryGetOperand("resultType", out var resultId); - return resultId; - } - public void SetResultType(int? value) - { - foreach (var o in this) - if (o.Kind == OperandKind.IdResultType) - o.Words[0] = value ?? -1; - } - - public void OffsetIds(int offset) - { - foreach (var o in this) - { - if (o.Kind == OperandKind.IdRef) - o.Words[0] += offset; - else if (o.Kind == OperandKind.IdResult) - o.Words[0] += offset; - else if (o.Kind == OperandKind.IdResultType) - o.Words[0] += offset; - else if (o.Kind == OperandKind.PairIdRefLiteralInteger) - o.Words[0] += offset; - else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) - o.Words[1] += offset; - else if (o.Kind == OperandKind.PairIdRefIdRef) - { - o.Words[0] += offset; - o.Words[1] += offset; - } - } - } - - public readonly Instruction ToOwned(SpirvBuffer buffer) - { - return new(buffer.Memory[WordIndex..(WordIndex + WordCount)]); - } - - public override string ToString() - { - var builder = new StringBuilder(); - builder.Append(OpCode).Append(' '); - foreach (var o in this) - { - builder.Append(o.ToString()).Append(' '); - } - return builder.ToString(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs index f02c9da405..5abc9b895f 100644 --- a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs @@ -10,5 +10,5 @@ namespace Stride.Shaders.Spirv.Processing; public interface IPostProcessorSubPass { - void Apply(SpirvBuffer buffer, RefInstruction instruction); + void Apply(SpirvBuffer buffer, Instruction instruction); } From 8b01c879ec342118dfc57666a41dd45c3cdf0089 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Jun 2025 16:22:54 +0900 Subject: [PATCH 0416/1182] Renamed Ref to Inst --- .../SPVGenerator.Instructions.cs | 4 ++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index ab7182b027..ccb70c592d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -38,7 +38,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat { builder - .AppendLine($"public ref struct Ref{instruction.OpName} : IWrapperInstruction") + .AppendLine($"public ref struct Inst{instruction.OpName} : IWrapperInstruction") .AppendLine("{") .AppendLine("public Instruction Inner { get; set; }"); try @@ -87,7 +87,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat builder .AppendLine() - .AppendLine($"public Ref{instruction.OpName}(Instruction instruction) => Inner = instruction;"); + .AppendLine($"public Inst{instruction.OpName}(Instruction instruction) => Inner = instruction;"); builder diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 7610a7d663..2a82a0a7c0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -27,17 +27,17 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D { if (instruction.OpCode == SDSLOp.OpName) { - var nameInstruction = instruction.UnsafeAs(); + var nameInstruction = instruction.UnsafeAs(); names.Add(nameInstruction.Target, nameInstruction.Name.Value); } else if (instruction.OpCode == SDSLOp.OpMemberName) { - var nameInstruction = instruction.UnsafeAs(); + var nameInstruction = instruction.UnsafeAs(); memberNames.Add((nameInstruction.Type, (int)nameInstruction.Member.Words), nameInstruction.Name.Value); } else if (instruction.OpCode == SDSLOp.OpTypeFloat) { - var floatInstruction = instruction.UnsafeAs(); + var floatInstruction = instruction.UnsafeAs(); if (floatInstruction.FloatingPointEncoding != 0) throw new InvalidOperationException(); @@ -54,13 +54,13 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D } else if (instruction.OpCode == SDSLOp.OpTypeVector) { - var vectorInstruction = instruction.UnsafeAs(); + var vectorInstruction = instruction.UnsafeAs(); var innerType = (ScalarType)types[vectorInstruction.ComponentType]; types.Add(instruction.ResultId!.Value, new VectorType(innerType, (int)vectorInstruction.ComponentCount.Words)); } else if (instruction.OpCode == SDSLOp.OpTypeStruct) { - var typeStructInstruction = instruction.UnsafeAs(); + var typeStructInstruction = instruction.UnsafeAs(); var structName = names[instruction.ResultId!.Value]; var fields = new List<(string Name, SymbolType Type)>(); throw new NotImplementedException(); @@ -68,7 +68,7 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D } else if (instruction.OpCode == SDSLOp.OpTypeFunction) { - var typeFunctionInstruction = instruction.UnsafeAs(); + var typeFunctionInstruction = instruction.UnsafeAs(); var returnType = types[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); foreach (var operand in instruction.Operands[2..]) @@ -94,7 +94,7 @@ private ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixi { if (instruction.OpCode == SDSLOp.OpVariable) { - var variableInstruction = instruction.UnsafeAs(); + var variableInstruction = instruction.UnsafeAs(); var variableName = names[variableInstruction.ResultId.Value]; var variableType = types[variableInstruction.ResultType]; @@ -104,7 +104,7 @@ private ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixi if (instruction.OpCode == SDSLOp.OpFunction) { - var functionInstruction = instruction.UnsafeAs(); + var functionInstruction = instruction.UnsafeAs(); var functionName = names[functionInstruction.ResultId.Value]; var functionType = types[functionInstruction.FunctionType]; From e065eca8b1974ce548022e26f0d6703cf064e679 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 12 Jun 2025 10:08:30 +0200 Subject: [PATCH 0417/1182] generator working for enums --- src/Stride.Shaders.Spirv.Generators/Data.cs | 38 ++++- .../EquatableDictionary.cs | 126 ++++++++++++++++ .../EquatableList.cs | 134 ++++++++++++++++++ .../Extensions/spirv.sdsl.enum-ext.json | 13 -- .../Extensions/spirv.sdsl.grammar-ext.json | 59 ++++++-- .../SPVGenerator.Buffers.cs | 2 +- .../SPVGenerator.Enums.cs | 18 +-- .../SPVGenerator.Helpers.Naming.cs | 6 +- .../SPVGenerator.Helpers.Preprocessing.cs | 37 +++-- .../SPVGenerator.Info.cs | 9 +- .../SPVGenerator.Instructions.cs | 8 +- .../SPVGenerator.SDSLOp.cs | 124 ++++++++++------ .../SPVGenerator.cs | 101 +++++++------ 13 files changed, 521 insertions(+), 154 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/EquatableList.cs delete mode 100644 src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index b4125baf53..4960504647 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -31,6 +31,28 @@ public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptio } } +public class OperandKindConverter : JsonConverter> +{ + public override EquatableDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType != JsonTokenType.StartArray) + return []; + else + { + var array = JsonSerializer.Deserialize(ref reader, options) ?? []; + return array.ToDictionary( + x => x.Kind, + x => x + ); + } + } + + public override void Write(Utf8JsonWriter writer, EquatableDictionary value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value.AsDictionary()?.Values.ToArray() ?? [], options); + } +} + public record struct Enumerant { @@ -40,7 +62,7 @@ public record struct Enumerant [JsonConverter(typeof(EnumerantValueConverter))] public int Value { get; set; } [JsonPropertyName("capabilities")] - public EquatableArray? Capabilities { get; set; } + public EquatableList? Capabilities { get; set; } [JsonPropertyName("version")] public string Version { get; set; } } @@ -52,7 +74,7 @@ public record struct OpKind public string Category { get; set; } [JsonPropertyName("enumerants")] - public EquatableArray? Enumerants { get; set; } + public EquatableList? Enumerants { get; set; } } @@ -77,7 +99,7 @@ public record struct InstructionData [JsonPropertyName("opcode")] public int OpCode { get; set; } [JsonPropertyName("operands")] - public EquatableArray? Operands { get; set; } + public EquatableList? Operands { get; set; } [JsonPropertyName("version")] public string Version { get; set; } public string Documentation { get; set; } @@ -97,10 +119,12 @@ public record struct SpirvGrammar public int Revision { get; set; } [JsonPropertyName("instructions")] - public EquatableArray? Instructions { get; set; } + public EquatableList? Instructions { get; set; } + // public EquatableList? OperandKinds { get; set; } [JsonPropertyName("operand_kinds")] - public EquatableArray? OperandKinds { get; set; } + [JsonConverter(typeof(OperandKindConverter))] + public EquatableDictionary? OperandKinds { get; set; } public string CoreDoc { get; set; } public string GLSLDoc { get; set; } @@ -110,8 +134,8 @@ public SpirvGrammar() MajorVersion = 0; MinorVersion = 0; Revision = 0; - Instructions = []; - OperandKinds = []; + Instructions = new([]); + OperandKinds = new([]); CoreDoc = ""; GLSLDoc = ""; } diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs b/src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs new file mode 100644 index 0000000000..1c5dbd6f47 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs @@ -0,0 +1,126 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +using System.Collections; +using System.Collections.Immutable; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Stride.Shaders.Spirv.Generators; + + + +public class EquatableDictionaryJsonConverter : JsonConverter> + where TKey : IEquatable + where TValue : IEquatable +{ + public override EquatableDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var dict = JsonSerializer.Deserialize>(ref reader, options) ?? []; + return new EquatableDictionary(dict); + } + + public override void Write(Utf8JsonWriter writer, EquatableDictionary value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(value.AsDictionary(), options); + } +} + +/// +/// An immutable, equatable array. This is equivalent to but with value equality support. +/// +/// The type of values in the array. +/// +/// Initializes a new instance of the struct. +/// +/// The input array to wrap. +public readonly struct EquatableDictionary(Dictionary? dict) : IEquatable>, IEnumerable> + where TKey : IEquatable + where TValue : IEquatable +{ + /// + /// The underlying array. + /// + private readonly Dictionary? _dict = dict; + + /// + /// Gets the length of the array, or 0 if the array is null + /// + public int Count => _dict?.Count ?? 0; + + /// + /// Checks whether two values are the same. + /// + /// The first value. + /// The second value. + /// Whether and are equal. + public static bool operator ==(EquatableDictionary left, EquatableDictionary right) + { + return left.Equals(right); + } + + /// + /// Checks whether two values are not the same. + /// + /// The first value. + /// The second value. + /// Whether and are not equal. + public static bool operator !=(EquatableDictionary left, EquatableDictionary right) + { + return !left.Equals(right); + } + + /// + public bool Equals(EquatableDictionary other) + { + return _dict?.Count == other._dict?.Count && + _dict?.All(kv => other._dict?.TryGetValue(kv.Key, out var value) == true && kv.Value.Equals(value)) == true; + } + + /// + public override bool Equals(object? obj) + { + return obj is EquatableDictionary dict && Equals(this, dict); + } + + /// + public override int GetHashCode() + { + if (_dict is not Dictionary dict) + { + return 0; + } + + HashCode hashCode = default; + + foreach (var kv in dict) + { + hashCode.Add(kv); + } + + return hashCode.ToHashCode(); + } + + /// + /// Returns the underlying wrapped array. + /// + /// Returns the underlying array. + public Dictionary? AsDictionary() + { + return _dict; + } + + public IEnumerator> GetEnumerator() + { + return _dict?.GetEnumerator() ?? Enumerable.Empty>().GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public static implicit operator EquatableDictionary(Dictionary dict) => new(dict); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableList.cs b/src/Stride.Shaders.Spirv.Generators/EquatableList.cs new file mode 100644 index 0000000000..8c72099b2d --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/EquatableList.cs @@ -0,0 +1,134 @@ +// +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2017 Datadog, Inc. +// + +using System.Collections; +using System.Collections.Immutable; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Stride.Shaders.Spirv.Generators; + + + +public class EquatableListJsonConverter : JsonConverter> + where T : IEquatable +{ + public override EquatableList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + var list = JsonSerializer.Deserialize(ref reader, options) ?? []; + return new EquatableList([..list]); + } + + public override void Write(Utf8JsonWriter writer, EquatableList value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(value.AsList(), options); + } +} + +/// +/// An immutable, equatable list. This is equivalent to but with value equality support. +/// +/// The type of values in the list. +/// +/// Initializes a new instance of the struct. +/// +/// The input list to wrap. +public readonly struct EquatableList(List list) : IEquatable>, IEnumerable + where T : IEquatable +{ + /// + /// The underlying list. + /// + private readonly List _list = list; + + /// + /// Gets the length of the list, or 0 if the list is null + /// + public int Count => _list.Count; + + /// + /// Checks whether two values are the same. + /// + /// The first value. + /// The second value. + /// Whether and are equal. + public static bool operator ==(EquatableList left, EquatableList right) + { + return left.Equals(right); + } + + /// + /// Checks whether two values are not the same. + /// + /// The first value. + /// The second value. + /// Whether and are not equal. + public static bool operator !=(EquatableList left, EquatableList right) + { + return !left.Equals(right); + } + + /// + public bool Equals(EquatableList list) + { + if (Count != list.Count) + return false; + for (int i = 0; i < Count; i++) + { + if (!_list![i].Equals(list._list![i])) + return false; + } + return true; + } + + /// + public override bool Equals(object? obj) + { + return obj is EquatableList list && Equals(this, list); + } + + /// + public override int GetHashCode() + { + if (_list is not List list) + { + return 0; + } + + HashCode hashCode = default; + + foreach (T item in list) + { + hashCode.Add(item); + } + + return hashCode.ToHashCode(); + } + + + /// + /// Returns the underlying wrapped list. + /// + /// Returns the underlying list. + public List AsList() + { + return _list; + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + /// + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + public static implicit operator EquatableList(List list) => new([.. list]); + public static implicit operator EquatableList(ImmutableList list) => new([.. list]); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json deleted file mode 100644 index ab8af2bbe4..0000000000 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.enum-ext.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "extensions": [ - { - "name": "ExecutionModel", - "values": [ - { - "name": "SDSL", - "description": "SDSL execution model" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json index 2f3b11e90e..74291ba759 100644 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -156,9 +156,15 @@ "opname": "OpSDSLVariable", "class": "Memory", "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { "kind": "StorageClass" }, + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "StorageClass" + }, { "kind": "LiteralString", "name": "name" @@ -174,8 +180,12 @@ "opname": "OpSDSLFunctionParameter", "class": "Function", "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, { "kind": "LiteralString", "name": "name" @@ -186,10 +196,18 @@ "opname": "OpSDSLIOVariable", "class": "Memory", "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { "kind": "StorageClass" }, - { "kind": "ExecutionModel" }, + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "StorageClass" + }, + { + "kind": "ExecutionModel" + }, { "kind": "LiteralString", "name": "name" @@ -209,9 +227,15 @@ "opname": "OpSDSLFunction", "class": "Function", "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { "kind": "FunctionControl" }, + { + "kind": "IdResultType" + }, + { + "kind": "IdResult" + }, + { + "kind": "FunctionControl" + }, { "kind": "IdRef", "name": "'Function Type'" @@ -222,5 +246,16 @@ } ] } + ], + "operand_kinds": [ + { + "kind": "ExecutionModel", + "enumerants": [ + { + "enumerant": "Mixin", + "value": 5367 + } + ] + } ] } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index e99d12ffe4..b901345e9b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -88,7 +88,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("}"); } - else if (op.Operands is EquatableArray operands && operands.Count > 0) + else if (op.Operands is EquatableList operands && operands.Count > 0) { var parameters = ConvertOperandsToParameters(op, operandKinds); var parameterNames = ConvertOperandsToParameterNames(op, operandKinds); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs index c02eaf96e1..298e5c794a 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs @@ -6,29 +6,28 @@ namespace Stride.Shaders.Spirv.Generators; - public partial class SPVGenerator { public void CreateSpecification(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { var sdsloProvider = grammarProvider - .Select(static (grammar, _) => grammar.OperandKinds!.Value); + .Select(static (grammar, _) => grammar.OperandKinds ?? new([])); context.RegisterImplementationSourceOutput( sdsloProvider, GenerateSDSLSpecification ); } - public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableArray operandKinds) + public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableDictionary operandKinds) { var code = new StringBuilder(); code .AppendLine("namespace Stride.Shaders.Spirv;") .AppendLine("") - .AppendLine("public static class Specification") + .AppendLine("public static partial class Specification") .AppendLine("{"); - foreach (var op in operandKinds) + foreach (var op in operandKinds.AsDictionary()!.Values) { if (op.Category == "BitEnum") { @@ -36,10 +35,13 @@ public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableArra .AppendLine($"[Flags]"); } code - .AppendLine($"public enum {op.Kind}") + .AppendLine($"public enum {op.Kind}{(op.Category == "BitEnum" ? "Mask" : "")}") .AppendLine("{"); - foreach (var enumerant in op.Enumerants!.Value) - code.AppendLine($" {enumerant.Name} = {enumerant.Value},"); + if (op.Enumerants?.AsList() is List enumerants) + { + foreach (var enumerant in enumerants) + code.AppendLine($" {(char.IsDigit(enumerant.Name[0]) ? op.Kind : "")}{enumerant.Name} = {enumerant.Value},"); + } code.AppendLine("}"); code.AppendLine(); } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 71694d94d8..6cf91c9c61 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -58,9 +58,9 @@ public static string ConvertNameQuantToName(string name, string quant) public static void PreProcessOperands(InstructionData op, Dictionary operandKinds, List<(string Name, string Type)> parameters) { var opname = op.OpName; - if (op.Operands?.AsArray() is OperandData[] operands) + if (op.Operands?.AsList() is List operands) { - for (int i = 0; i < operands.Length; i++) + for (int i = 0; i < operands.Count; i++) { var e = operands[i]; var kind = e.Kind; @@ -107,7 +107,7 @@ public static List ConvertOperandsToParameters(InstructionData op, Dicti { var opname = op.OpName; List parameters = []; - if (op.Operands is EquatableArray operands) + if (op.Operands is EquatableList operands) { foreach (var e in operands) { diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 4fa34277d3..2eb0a2eadd 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -2,6 +2,7 @@ using System.Text; using System.Text.Json; using AngleSharp; +using AngleSharp.Common; using AngleSharp.Dom; using Microsoft.CodeAnalysis; @@ -42,13 +43,22 @@ public SpirvGrammar PreProcessGrammar(ImmutableArray files, Canc } if (parsed.Instructions is not null) { - InstructionData[] instructions = [.. grammar.Instructions, .. parsed.Instructions]; - grammar.Instructions = instructions; + + grammar.Instructions?.AsList()?.AddRange(parsed.Instructions?.AsList() ?? []); } - if (parsed.OperandKinds is not null) + if (parsed.OperandKinds?.AsDictionary() is Dictionary parsedKinds && grammar.OperandKinds?.AsDictionary() is Dictionary grammarKinds) { - OpKind[] operandKinds = [.. grammar.OperandKinds, .. parsed.OperandKinds]; - grammar.OperandKinds = operandKinds; + foreach (var pk in parsedKinds) + { + if (grammarKinds.ContainsKey(pk.Key)) + { + grammarKinds[pk.Key].Enumerants?.AsList()?.AddRange(pk.Value.Enumerants?.AsList() ?? []); + if (grammarKinds[pk.Key].Category is null || grammarKinds[pk.Key].Category.Length == 0) + grammarKinds[pk.Key] = grammarKinds[pk.Key] with { Category = pk.Value.Category}; + } + else + grammarKinds[pk.Key] = pk.Value; + } } } @@ -58,7 +68,6 @@ public SpirvGrammar PreProcessGrammar(ImmutableArray files, Canc public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationToken _) { - var operandKinds = grammar.OperandKinds?.AsArray().ToDictionary(x => x.Kind, x => x); var config = Configuration.Default.WithDefaultLoader(); var htmlContext = BrowsingContext.New(config); var coreTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); @@ -70,15 +79,15 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok var builder = new StringBuilder(); // var buffer = new List(24); - if (grammar.Instructions?.AsArray() is InstructionData[] instructions) + if (grammar.Instructions?.AsList() is List instructions) { - for (int i = 0; i < instructions.Length; i++) + for (int i = 0; i < instructions.Count; i++) // foreach (var instruction in grammar.Instructions) { - var instruction = grammar.Instructions.Value.AsArray()![i]!; - + var instruction = grammar.Instructions.Value.AsList()![i]!; + // setup the documentation - var cells = instruction.OpName switch + var cells = instruction.OpName switch { string v when !v.StartsWith("Op") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName.Replace("GLSL", "")}\"))"), string v when v.Contains("SDSL") => null, // SDSL does not have documentation @@ -100,15 +109,15 @@ string v when v.Contains("SDSL") => null, // SDSL does not have documentation } instruction.Documentation = builder.ToString(); } - + if (!instruction.OpName.StartsWith("Op")) instruction.OpName = $"GLSL{instruction.OpName}"; // A reusable buffer var buffer = new List<(string, string)>(24); - if (instruction.Operands?.AsArray() is OperandData[] operands) - PreProcessOperands(instruction, operandKinds!, buffer); + if (instruction.Operands?.AsList() is List operands) + PreProcessOperands(instruction, grammar.OperandKinds?.AsDictionary()!, buffer); instructions[i] = instruction; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 3dfe89056d..6890456e7b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -40,7 +40,7 @@ static void GenerateInstructionInformation(SourceProductionContext spc, Equatabl { var code = new StringBuilder(); code - .AppendLine("using static Spv.Specification;") + .AppendLine("using static Stride.Shaders.Spirv.Specification;") .AppendLine("") .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine("") @@ -77,14 +77,15 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In { var builder = new StringBuilder(); builder - .AppendLine("using static Spv.Specification;") + .AppendLine("using static Stride.Shaders.Spirv.Specification;") .AppendLine("") .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine("") .AppendLine("public enum OperandKind") .AppendLine("{") .AppendLine(" None,"); - foreach (var kind in kinds) + if(kinds.AsDictionary() is Dictionary dict) + foreach (var kind in dict.Values) builder.AppendLine($" {kind.Kind},"); builder .AppendLine("}"); @@ -124,7 +125,7 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); } - else if (op.Operands is EquatableArray operands) + else if (op.Operands is EquatableList operands) { foreach (var operand in operands) { diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 4ceed5a901..844b63602d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -17,17 +17,17 @@ public void GenerateStructs(IncrementalGeneratorInitializationContext context, I context.RegisterImplementationSourceOutput( sdslInstructionsData, - GenerateInstructionStructs + (source, instructions) => GenerateInstructionStructs(source, instructions) ); } - public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableArray? instructions) + public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableList? instructions) { StringBuilder builder = new(); builder - .AppendLine("using static Spv.Specification;") + .AppendLine("using static Stride.Shaders.Spirv.Specification;") .AppendLine() .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine() @@ -75,7 +75,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat else if (operand.Class == "ValueEnum") builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); else - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}/*{operand.Class}*/>(\"{operandName}\") ?? default;"); } } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index e03faf5ecd..3d96146164 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -24,60 +24,98 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr var instructionsProvider = grammarProvider - .SelectMany(static (grammar, _) => grammar.Instructions!.Value) - .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) - .Collect() - .Select(static (arr, _) => new EquatableArray([.. arr])); + .Select(static (grammar, _) => grammar.Instructions); + // .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + // .Collect() + // .Select(static (arr, _) => new EquatableList([.. arr])); context.RegisterImplementationSourceOutput( instructionsProvider, - (ctx, instructionArray) => + ExecuteSDSLOpCreation + + + ); + + } + public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList? instructionArray) + { + if (instructionArray is not null) + { + var code = new StringBuilder(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + + Dictionary members = instructionArray?.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; + int lastnum = members.Values.Max(); + foreach (var instruction in instructionArray!) { - var code = new StringBuilder(); - code - .AppendLine("using static Spv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum SDSLOp : int") - .AppendLine("{"); - try + if (members.TryGetValue(instruction.OpName, out var value)) { - Dictionary members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode); - int lastnum = members.Values.Max(); - foreach (var instruction in instructionArray) - { - if (members.TryGetValue(instruction.OpName, out var value)) - { - if (instruction.OpName.Contains("SDSL") && value <= 0) - value = ++lastnum; - code.AppendLine($" {instruction.OpName} = {value},"); - } - else - { - members.Add(instruction.OpName, ++lastnum); - code.AppendLine($" {instruction.OpName} = {lastnum},"); - } - } + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); } - catch (Exception ex) + else { - code.AppendLine($"/*{ex.Message}\n\n {ex.StackTrace} */"); + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); } + } + - code.AppendLine("}"); - ctx.AddSource("SDSLOp.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); + code.AppendLine("}"); + ctx.AddSource("SDSLOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + code.Clear(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv;") + .AppendLine("") + .AppendLine("public static partial class Specification") + .AppendLine("{") + .AppendLine("public enum Op : int") + .AppendLine("{"); + + foreach (var instruction in instructionArray!) + { + if (members.TryGetValue(instruction.OpName, out var value)) + { + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); + } + else + { + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); + } } + code.AppendLine("}}"); - ); + ctx.AddSource("SpecificationOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + + } } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 932844ece1..c523f30d5d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -22,19 +22,19 @@ public partial class SPVGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) - options.Converters.Add(new EquatableArrayJsonConverter()); - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) - options.Converters.Add(new EquatableArrayJsonConverter()); - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) - options.Converters.Add(new EquatableArrayJsonConverter()); - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) - options.Converters.Add(new EquatableArrayJsonConverter()); - if (!options.Converters.Any(x => x is EquatableArrayJsonConverter)) - options.Converters.Add(new EquatableArrayJsonConverter()); - - - + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); + + + var grammarData = context @@ -44,14 +44,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .Select(PreProcessGrammar) .Select(PreProcessInstructions); - context.SyntaxProvider.CreateSyntaxProvider( - predicate: (s, _) => s is ClassDeclarationSyntax or EnumDeclarationSyntax or StructDeclarationSyntax or MemberDeclarationSyntax, - transform: (ctx, _) => ctx - ).Combine(grammarData); - CreateInfo(context, grammarData); CreateSDSLOp(context, grammarData); GenerateStructs(context, grammarData); + CreateSpecification(context, grammarData); context.RegisterImplementationSourceOutput( grammarData, @@ -63,35 +59,50 @@ public void Initialize(IncrementalGeneratorInitializationContext context) public static void BufferGeneration(SourceProductionContext spc, SpirvGrammar source) { - var operandKinds = source.OperandKinds!.Value.AsArray().ToDictionary(x => x.Kind, x => x); - var code = new StringBuilder(); - code - .AppendLine("using static Spv.Specification;") - .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public static class SpirvBufferExtensions") - .AppendLine("{"); - foreach (var instruction in source.Instructions!.Value.AsArray()!) + + try { - if (instruction.OpName.StartsWith("Op")) - CreateOperation(instruction, code, operandKinds); - else - CreateGlslOperation(instruction, code, operandKinds); + var code = new StringBuilder(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public static class SpirvBufferExtensions") + .AppendLine("{"); + foreach (var instruction in source.Instructions?.AsList() ?? []) + { + if (instruction.OpName.StartsWith("Op")) + CreateOperation(instruction, code, source.OperandKinds?.AsDictionary() ?? []); + else + CreateGlslOperation(instruction, code, source.OperandKinds?.AsDictionary() ?? []); + } + code + .AppendLine("}"); + + spc.AddSource("SpirvBufferExtensions.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + catch (Exception ex) + { + spc.AddSource("SpirvBufferExtensions.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit($"/* Error generating SpirvBufferExtensions: {ex.Message} */") + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); } - code - .AppendLine("}"); - - spc.AddSource("SpirvBufferExtensions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); } From 6e046397131385deab895c0bec02a7d65fd3f8a1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Thu, 12 Jun 2025 10:30:42 +0200 Subject: [PATCH 0418/1182] changed imports --- src/Stride.Shaders.Experiments/Examples.Spirv.cs | 6 +++--- src/Stride.Shaders.Experiments/Program.cs | 2 +- .../Information/InstructionInfo.Order.cs | 2 +- .../Information/InstructionInfo.cs | 6 +++--- src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs | 2 +- src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs | 2 +- src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs | 2 +- src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs | 2 +- src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs | 2 +- src/Stride.Shaders.Spirv.Core/RefInstruction.cs | 2 +- src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs | 2 ++ src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.Functions.cs | 6 +++--- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs | 2 +- src/Stride.Shaders/Spirv/Processing/IOReplace.cs | 2 +- src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs | 2 +- src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs | 2 +- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 2 +- 20 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 58026c3411..0b5afc1c0f 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -6,7 +6,7 @@ using Stride.Shaders.Spirv.Core.Parsing; using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Building; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Experiments; @@ -149,7 +149,7 @@ public static void CreateShader() buffer.AddOpMemberName(t_struct, 1, "v"); buffer.AddOpMemberName(t_struct, 2, "i"); - var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.MaskNone, t_func_add); + var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.None, t_func_add); var a = buffer.AddOpFunctionParameter(id++, t_int); var b = buffer.AddOpFunctionParameter(id++, t_int); buffer.AddOpLabel(id++); @@ -157,7 +157,7 @@ public static void CreateShader() buffer.AddOpReturnValue(res); buffer.AddOpFunctionEnd(); - var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.MaskNone, t_func); + var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.None, t_func); buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 089615cebc..6725fd574f 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -6,7 +6,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; // Examples.CompileSDSL(); // Examples.TryAllFiles(); diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 5a682b5a63..333feecc3b 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index c8cc7e6044..1246ec1fd5 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; @@ -46,7 +46,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + // Info.Add(new(SDSLOp.OpDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); @@ -71,7 +71,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + // Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); } /// diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs index 40cb289ad1..b27ddd70cc 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -2,7 +2,7 @@ using Stride.Shaders.Spirv.Core.Parsing; using System.Runtime.InteropServices; using System.Text; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; diff --git a/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs index 2a2111f0c5..e7a272bc29 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs @@ -1,6 +1,6 @@ using System.Runtime.CompilerServices; using System; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index 96a032acd9..1ef310d9bc 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -1,4 +1,4 @@ -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 257f0fc5b7..c64b4c3df0 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Stride.Shaders.Spirv.Core.Buffers; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index 6d1855bfb0..bee3c49566 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; diff --git a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs index 63fd719156..268d318e25 100644 --- a/src/Stride.Shaders.Spirv.Core/RefInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/RefInstruction.cs @@ -3,7 +3,7 @@ using System.Text; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs index 298e5c794a..70d331f2d5 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Enums.cs @@ -29,6 +29,8 @@ public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableDict foreach (var op in operandKinds.AsDictionary()!.Values) { + if (op.Category == "Literal" || op.Category == "Id" || op.Category == "Composite") + continue; if (op.Category == "BitEnum") { code diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 6890456e7b..c8a2be1d91 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -93,7 +93,7 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In } ); // var code = new StringBuilder() - // .AppendLine("using static Spv.Specification;") + // .AppendLine("using static Stride.Shaders.Spirv.Specification;") // .AppendLine("") // .AppendLine("namespace Stride.Shaders.Spirv.Core;") // .AppendLine("\n\n") diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index f632d04c25..89223eb2e7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -2,7 +2,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Parsing.SDSL.AST; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 3287fb9493..461574fb16 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -1,13 +1,13 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { - public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.MaskNone) + public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.None) { foreach(var t in ftype.ParameterTypes) context.GetOrRegister(t); @@ -28,7 +28,7 @@ public SpirvValue AddFunctionParameter(SpirvContext context, string name, Symbol CurrentFunction!.Value.Parameters.Add(name, new(p, name)); return new(p, name); } - public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.MaskNone) + public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.None) { var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(type.ReturnType), mask, context.GetOrRegister(type)); context.AddName(func, name); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 5ef5a6bb52..3b2c6f5337 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -3,7 +3,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; diff --git a/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs index db3787d05b..3bf158e6bd 100644 --- a/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs +++ b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs @@ -1,7 +1,7 @@ // using Stride.Shaders.Spirv.Core; // using Stride.Shaders.Spirv.Core.Buffers; // using Stride.Shaders.Spirv.Core.Parsing; -// using static Spv.Specification; +// using static Stride.Shaders.Spirv.Specification; // namespace Stride.Shaders.Spirv.Processing; diff --git a/src/Stride.Shaders/Spirv/Processing/IOReplace.cs b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs index 2f7ac5f077..b7553792e6 100644 --- a/src/Stride.Shaders/Spirv/Processing/IOReplace.cs +++ b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs @@ -1,7 +1,7 @@ // using Stride.Shaders.Spirv.Core; // using Stride.Shaders.Spirv.Core.Buffers; // using Stride.Shaders.Spirv.Processing; -// using static Spv.Specification; +// using static Stride.Shaders.Spirv.Specification; // namespace Stride.Shaders.Spirv.PostProcessing; diff --git a/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs index f3d3854a28..c9b0b3c362 100644 --- a/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs +++ b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs @@ -1,7 +1,7 @@ // using Stride.Shaders.Spirv.Core; // using Stride.Shaders.Spirv.Core.Buffers; // using Stride.Shaders.Spirv.Processing; -// using static Spv.Specification; +// using static Stride.Shaders.Spirv.Specification; // namespace Stride.Shaders.Spirv.PostProcessing; diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs index 980f006721..d497ca8d14 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs @@ -1,4 +1,4 @@ -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Spirv.Tools; diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index e869307626..fb7a3f0d04 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -1,7 +1,7 @@ using System.Text; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core; -using static Spv.Specification; +using static Stride.Shaders.Spirv.Specification; using System.Runtime.CompilerServices; namespace Stride.Shaders.Spirv.Tools; From b2072686584c51313fa73b0a57f42f2d0ef52ed8 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 13 Jun 2025 09:04:21 +0200 Subject: [PATCH 0419/1182] correction removal of GLSL again --- .../SPVGenerator.SDSLOp.cs | 156 ++++++++---------- 1 file changed, 69 insertions(+), 87 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 3d96146164..39f7a127d2 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -1,20 +1,8 @@ using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Reflection; -using System.Text.Json; -using System.Security.Claims; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; using AngleSharp.Common; using Microsoft.CodeAnalysis.Text; -using System.Dynamic; - namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator @@ -24,98 +12,92 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr var instructionsProvider = grammarProvider - .Select(static (grammar, _) => grammar.Instructions); - // .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) - // .Collect() - // .Select(static (arr, _) => new EquatableList([.. arr])); + .SelectMany(static (grammar, b) => grammar.Instructions?.AsList() ?? []) + .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + .Collect() + .Select(static (arr, _) => new EquatableList([.. arr])); context.RegisterImplementationSourceOutput( instructionsProvider, ExecuteSDSLOpCreation - - ); } - public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList? instructionArray) + public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList instructionArray) { - if (instructionArray is not null) - { - var code = new StringBuilder(); - code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum SDSLOp : int") - .AppendLine("{"); - Dictionary members = instructionArray?.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; - int lastnum = members.Values.Max(); - foreach (var instruction in instructionArray!) + var code = new StringBuilder(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + + Dictionary members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; + int lastnum = members.Values.Max(); + foreach (var instruction in instructionArray!) + { + if (members.TryGetValue(instruction.OpName, out var value)) + { + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); + } + else { - if (members.TryGetValue(instruction.OpName, out var value)) - { - if (instruction.OpName.Contains("SDSL") && value <= 0) - value = ++lastnum; - code.AppendLine($" {instruction.OpName} = {value},"); - } - else - { - members.Add(instruction.OpName, ++lastnum); - code.AppendLine($" {instruction.OpName} = {lastnum},"); - } + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); } + } - code.AppendLine("}"); - ctx.AddSource("SDSLOp.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - code.Clear(); - code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv;") - .AppendLine("") - .AppendLine("public static partial class Specification") - .AppendLine("{") - .AppendLine("public enum Op : int") - .AppendLine("{"); + code.AppendLine("}"); + ctx.AddSource("SDSLOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + code.Clear(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv;") + .AppendLine("") + .AppendLine("public static partial class Specification") + .AppendLine("{") + .AppendLine("public enum Op : int") + .AppendLine("{"); - foreach (var instruction in instructionArray!) + foreach (var instruction in instructionArray!) + { + if (members.TryGetValue(instruction.OpName, out var value)) { - if (members.TryGetValue(instruction.OpName, out var value)) - { - if (instruction.OpName.Contains("SDSL") && value <= 0) - value = ++lastnum; - code.AppendLine($" {instruction.OpName} = {value},"); - } - else - { - members.Add(instruction.OpName, ++lastnum); - code.AppendLine($" {instruction.OpName} = {lastnum},"); - } + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); + } + else + { + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); } - code.AppendLine("}}"); - - ctx.AddSource("SpecificationOp.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - } + code.AppendLine("}}"); + ctx.AddSource("SpecificationOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); } } From 15ba85cb0411ec8d959914abdb11ff6336ea19d8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Jun 2025 18:26:03 +0900 Subject: [PATCH 0420/1182] SpirvBuffer is now a list of instructions --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 +- .../Examples.Spirv.cs | 6 +- src/Stride.Shaders.Experiments/Examples.cs | 6 +- .../Buffers/ISpirvBuffer.cs | 52 +---- .../Buffers/SpirvBuffer.cs | 188 ++++++++---------- .../Buffers/SpirvMemory.cs | 57 ------ .../Buffers/SpirvSpan.cs | 45 ----- .../MemoryInstruction.cs | 8 - .../MutableFunctionInstructionEnumerator.cs | 48 ----- .../Parsing/OrderedEnumerator.cs | 62 ++---- .../Parsing/SpirvReader.cs | 21 +- .../Parsing/SDSL/AST/Expression.cs | 3 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../Parsing/SDSL/AST/Statements.cs | 8 +- .../Spirv/Building/Builder.Expressions.cs | 45 ++--- .../Spirv/Building/Builder.Flow.cs | 14 +- .../Spirv/Building/Builder.Functions.cs | 7 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 9 +- .../Spirv/Building/CompilerUnit.cs | 8 +- src/Stride.Shaders/Spirv/Building/Context.cs | 6 +- .../Spirv/Processing/StreamAnalyzer.cs | 18 +- .../Spirv/Tools/SpirvDis.Appends.cs | 2 +- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 10 +- 23 files changed, 172 insertions(+), 459 deletions(-) delete mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index d53ca937b0..2781a49a03 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -25,7 +25,7 @@ public readonly bool Compile(string code, out byte[] compiled) if(table.Errors.Count > 0) throw new Exception("Some parse errors"); - using var compiler = new CompilerUnit(); + var compiler = new CompilerUnit(); shader.Compile(compiler, table); // temp hack to add entry point (last function) @@ -38,7 +38,7 @@ public readonly bool Compile(string code, out byte[] compiled) var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); var dis = new SpirvDis(merged, true); dis.Disassemble(true); - compiled = MemoryMarshal.AsBytes(merged.Span).ToArray(); + compiled = MemoryMarshal.AsBytes(merged.ToBuffer().AsSpan()).ToArray(); return true; } else diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 1a0d9b2092..3e3d6d3bfd 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -16,8 +16,8 @@ public static partial class Examples public static void GenerateSpirv() { var module = new SpirvModule(); - using var context = new SpirvContext(new()); - using var builder = new SpirvBuilder(); + var context = new SpirvContext(new()); + var builder = new SpirvBuilder(); context.GetOrRegister(new MatrixType(ScalarType.From("float"), 4, 3)); context.GetOrRegister(ScalarType.From("int")); @@ -178,7 +178,7 @@ public static void CreateShader() dis.Disassemble(writeToConsole: true); File.WriteAllBytes( "test.spv", - MemoryMarshal.Cast(buffer.Span) + MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) ); } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index bb90fc49ee..036dc1d1ad 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -314,7 +314,7 @@ public static void MergeSDSL() { var shader = GetOrLoadShader(shaderName); offset += nextOffset; - foreach (var i in shader) + foreach (var i in shader.Instructions) { temp.Add(i.Words); @@ -341,7 +341,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri { // Build shader name mapping var shaderMapping = new Dictionary(); - foreach (var i in buffer) + foreach (var i in buffer.Instructions) { if (i.OpCode == SDSLOp.OpSDSLImportShader) { @@ -350,7 +350,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri } // Check inheritance - foreach (var i in buffer) + foreach (var i in buffer.Instructions) { if (i.OpCode == SDSLOp.OpSDSLMixinInherit) { diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs index b11ce0fdf6..ba21486094 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs @@ -7,59 +7,13 @@ namespace Stride.Shaders.Spirv.Core.Buffers; /// public interface ISpirvBuffer { - /// - /// Span of the buffer - /// - Span Span { get; } - /// - /// Memory of the buffer - /// - Memory Memory { get; } - /// - /// Span of the buffer without the header - /// - Span InstructionSpan { get; } - /// - /// Memory of the buffer without the header - /// - Memory InstructionMemory { get; } - /// - /// Count of instructions - /// - public int InstructionCount { get; } - /// - /// Length of the buffer - /// - int Length { get; } + public bool HasHeader { get; } + public ref SpirvHeader Header { get; } - /// - /// Wether the buffer has a header - /// - bool HasHeader { get; } - /// - /// Header of the buffer - /// - RefHeader Header { get; set; } + public Span InstructionsSpan { get; } /// /// Get instruction from the instruction index /// public Instruction this[int index] { get; } - - /// - /// Convert to a SpirvSpan - /// - /// Buffer as a Span - public SpirvSpan AsSpan(); - /// - /// Convert to a SpirvMemory - /// - /// Buffer as a memory - public SpirvMemory AsMemory(); - - /// - /// Gets Instruction enumerator - /// - /// Instruction enumerator - public InstructionEnumerator GetEnumerator(); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 90638f80a8..ff43e69bfc 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -1,5 +1,8 @@ -using CommunityToolkit.HighPerformance.Buffers; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Spirv.Core.Parsing; +using System; +using System.Buffers; using System.Numerics; namespace Stride.Shaders.Spirv.Core.Buffers; @@ -7,33 +10,25 @@ namespace Stride.Shaders.Spirv.Core.Buffers; /// /// A common SPIR-V buffer containing a header. /// -public class SpirvBuffer : IMutSpirvBuffer, IDisposable +public class SpirvBuffer : IMutSpirvBuffer { - /// - /// Reusable buffer containing the SPIR-V code - /// - MemoryOwner _owner; - public int Length { get; protected set; } - public Span Span => _owner.Span[..Length]; - public Memory Memory => _owner.Memory[..Length]; - public bool HasHeader => true; - public RefHeader Header + private SpirvHeader header = new SpirvHeader { - get => new(_owner.Span[..5]); - set - { - value.Words.CopyTo(Header.Words); - } - } + VersionNumber = new(1, 3), + MagicNumber = Spv.Specification.MagicNumber, + }; + private ArrayPool pool = ArrayPool.Shared; + + public List Instructions { get; } = new(); - public Span InstructionSpan => Span[5..]; - public Memory InstructionMemory => Memory[5..]; + public Span InstructionsSpan => Instructions.AsSpan(); - public int InstructionCount => new SpirvReader(Memory).Count; + public bool HasHeader => true; + public ref SpirvHeader Header => ref header; public Instruction FindInstructionByResultId(int resultId) { - foreach (var instruction in this) + foreach (var instruction in Instructions) { if (instruction.ResultId == resultId) return instruction; @@ -42,139 +37,114 @@ public Instruction FindInstructionByResultId(int resultId) throw new InvalidOperationException(); } - public Instruction this[int index] - { - get - { - int id = 0; - int wid = 5; - while (id < index) - { - wid += Span[wid] >> 16; - id++; - } - return new Instruction(Memory.Slice(wid, Span[wid] >> 16)); - } - } + public Instruction this[int index] => Instructions[index]; public SpirvBuffer(int initialSize = 32) { - _owner = MemoryOwner.Allocate(initialSize, AllocationMode.Clear); - Header = Header with - { - MagicNumber = Spv.Specification.MagicNumber, - VersionNumber = new(1, 3) - }; - Length = 5; } public SpirvBuffer(Memory memory) { - _owner = MemoryOwner.Allocate(memory.Length, AllocationMode.Clear); - memory.CopyTo(_owner.Memory); - Header = Header with + Header = SpirvHeader.Read(memory.Span); + var instructions = memory[5..]; + + int wid = 0; + while (wid < instructions.Length) { - MagicNumber = Spv.Specification.MagicNumber, - VersionNumber = new(1, 3) - }; - Length = _owner.Length; + Instructions.Add(new Instruction(instructions.Slice(wid, instructions.Span[wid] >> 16))); + wid += instructions.Span[wid] >> 16; + } } + public SpirvBuffer(Span span) { - _owner = MemoryOwner.Allocate(span.Length, AllocationMode.Clear); - span.CopyTo(_owner.Span); - Header = Header with + Header = SpirvHeader.Read(span); + var instructions = span[5..]; + + int wid = 0; + while (wid < instructions.Length) { - MagicNumber = Spv.Specification.MagicNumber, - VersionNumber = new(1, 3) - }; - Length = _owner.Length; + Add(instructions.Slice(wid, instructions[wid] >> 16)); + wid += instructions[wid] >> 16; + } } + public int[] ToBuffer() + { + var offset = 5; + foreach (var instruction in Instructions) + offset += instruction.WordCount; + var buffer = new int[offset]; + + Header.WriteTo(buffer); + offset = 5; + foreach (var instruction in Instructions) + { + instruction.Words.CopyTo(buffer.AsSpan()[offset..]); + offset += instruction.WordCount; + } + + return buffer; + } - public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); public void Sort() { var sorted = new OrderedEnumerator(this); - var other = MemoryOwner.Allocate(Length, AllocationMode.Clear); - var pos = 5; + var newInstructions = new List(); while (sorted.MoveNext()) { - sorted.Current.Memory.CopyTo(other.Memory[pos..]); - pos += sorted.Current.WordCount; + newInstructions.Add(sorted.Current); } - _owner.Span[0..5].CopyTo(other.Span[0..5]); - _owner.Dispose(); - _owner = other; - } - public SpirvSpan AsSpan() => new(Span); - public SpirvMemory AsMemory() => new(Memory); - public Instruction Add(Span instruction) - { - var result = Insert(Length, instruction); - if (result.ResultId is int resultId && resultId >= Header.Bound) - Header = Header with { Bound = resultId + 1 }; - return result; + Instructions.Clear(); + Instructions.AddRange(newInstructions); } - public void Remove(int position) + private Instruction CreateInstruction(Span instructionData) { - if(position < 5 && position > Length) - throw new ArgumentOutOfRangeException($"Can't remove at position {position}"); - var size = Span[position] >> 16; - Span[(position + size)..].CopyTo(Span[position..]); - Length -= size; + var instructionBuffer = pool.Rent(instructionData.Length).AsMemory(0, instructionData.Length); + instructionData.CopyTo(instructionBuffer.Span); + return new Instruction(instructionBuffer); } - public Instruction Insert(int start, ReadOnlySpan words) + + public Instruction Add(Span instructionData) { - Expand(words.Length); - if (start == Length) - words.CopyTo(_owner.Span[start..]); - else - { - var slice = _owner.Span[start..Length]; - slice.CopyTo(_owner.Span[(start + words.Length)..]); - words.CopyTo(_owner.Span.Slice(start, words.Length)); - } - Length += words.Length; - return new(Memory[start..(start + words.Length)]); + var instruction = CreateInstruction(instructionData); + + Instructions.Add(instruction); + if (instruction.ResultId is int resultId && resultId >= Header.Bound) + Header = Header with { Bound = resultId + 1 }; + + return instruction; } - void Expand(int size) + public Instruction Insert(int position, Span instructionData) { - if (Length + size > _owner.Length) - { - var n = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)(Length + size)), AllocationMode.Clear); - _owner.Span.CopyTo(n.Span); - var toDispose = _owner; - _owner = n; - toDispose.Dispose(); - } + var instruction = CreateInstruction(instructionData); + + Instructions.Insert(position, instruction); + if (instruction.ResultId is int resultId && resultId >= Header.Bound) + Header = Header with { Bound = resultId + 1 }; + + return instruction; } internal void Add(TBuff buffer) where TBuff : ISpirvBuffer { - Expand(buffer.InstructionSpan.Length); - buffer.InstructionSpan.CopyTo(_owner.Span[Length..]); - Length += buffer.InstructionSpan.Length; + Instructions.AddRange(buffer.InstructionsSpan); } - public static SpirvBuffer Merge(T1 left, T2 right) where T1 : ISpirvBuffer where T2 : ISpirvBuffer { - var buff = new SpirvBuffer(left.Length + right.Length + 5); + var buff = new SpirvBuffer(); buff.Add(left); buff.Add(right); - foreach (var e in buff) + foreach (var e in buff.Instructions) if (e.ResultId is int r && buff.Header.Bound < r + 1) buff.Header = buff.Header with { Bound = r + 1 }; return buff; } - - public void Dispose() => _owner.Dispose(); - } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs deleted file mode 100644 index 0a962c4ec7..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvMemory.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A SPIR-V buffer memory slice -/// -public readonly struct SpirvMemory(Memory memory) : ISpirvBuffer -{ - public readonly Instruction this[int index] - { - get - { - int id = 0; - int wid = 5; - while (id < index) - { - wid += Span[wid] >> 16; - id++; - } - return new Instruction(Memory.Slice(wid, Span[wid] >> 16)); - } - } - public readonly Span Span => Memory.Span; - - public readonly Memory Memory { get; } = memory; - - public readonly Span InstructionSpan => Span[(HasHeader ? 5 : 0)..]; - - public readonly Memory InstructionMemory => Memory[(HasHeader ? 5 : 0)..]; - - public readonly int InstructionCount => new SpirvReader(Memory).Count; - - public readonly int Length => Memory.Length; - - public readonly bool HasHeader => Span[0] == Spv.Specification.MagicNumber; - - public readonly RefHeader Header - { - get => HasHeader ? new(Span[..5]) : throw new Exception("No header for this buffer"); - set - { - if (HasHeader) value.Words.CopyTo(Header.Words); - } - } - - public readonly SpirvMemory AsMemory() => this; - - public readonly SpirvSpan AsSpan() => new(Span); - - public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); -} diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs deleted file mode 100644 index 180eb8fe01..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvSpan.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Stride.Shaders.Spirv.Core.Parsing; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A SPIR-V buffer span slice -/// -public readonly ref struct SpirvSpan(Span words) : ISpirvBuffer -{ - public readonly Instruction this[int index] => throw new NotImplementedException(); - - public readonly Span Span { get; } = words; - - public readonly Memory Memory => throw new Exception("Can't get Memory from Span"); - - public readonly Span InstructionSpan => Span[(HasHeader ? 5 : 0)..]; - - public readonly Memory InstructionMemory => throw new Exception("Can't get Memory from Span"); - - public readonly int InstructionCount => new SpirvReader(this).Count; - - public readonly int Length => Span.Length; - - public readonly bool HasHeader => Span[0] == Spv.Specification.MagicNumber; - - public readonly RefHeader Header - { - get => HasHeader ? new(Span[..5]) : throw new Exception("No header for this buffer"); - set - { - if (HasHeader) value.Words.CopyTo(Header.Words); - } - } - - public readonly SpirvMemory AsMemory() => throw new Exception("Can't get Memory from Span"); - - public readonly SpirvSpan AsSpan() => this; - - public InstructionEnumerator GetEnumerator() => new(InstructionMemory, HasHeader); -} diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index 38bf8b86f7..dbb7e9a660 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -18,14 +18,6 @@ public record struct Instruction(Memory Memory) public static implicit operator IdResultType(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); - public Instruction(ISpirvBuffer buffer, int index) : this(Memory.Empty) - { - var wid = 0; - for (int i = 0; i < index; i += 1) - wid += buffer.InstructionSpan[wid] >> 16; - Memory = buffer.InstructionMemory.Slice(wid, buffer.InstructionSpan[wid] >> 16); - } - public readonly SDSLOp OpCode => (SDSLOp)(Words[0] & 0xFFFF); public int? ResultId { get => GetResultId(); set => SetResultId(value); } public int? ResultType { get => GetResultType(); set => SetResultType(value); } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs deleted file mode 100644 index de4cf19e56..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/MutableFunctionInstructionEnumerator.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Reflection.Emit; -using Stride.Shaders.Spirv.Core.Buffers; - -namespace Stride.Shaders.Spirv.Core.Parsing; - -/// -/// Instruction enumerator returning RefInstruction -/// -public ref struct MutableFunctionInstructionEnumerator -{ - int wordIndex; - int index; - readonly SpirvBuffer buffer; - - public Instruction Current => ParseCurrentInstruction(); - - public MutableFunctionInstructionEnumerator(SpirvBuffer buffer, int methodStart) - { - wordIndex = methodStart; - index = -1; - this.buffer = buffer; - } - - public bool MoveNext() - { - if (index == -1) - { - index = 0; - return true; - } - else - { - if (index >= 0 && buffer.Span[wordIndex] == (int)SDSLOp.OpFunctionEnd) - return false; - if (wordIndex + (buffer.Span[wordIndex] >> 16) >= buffer.Span.Length) - return false; - wordIndex += buffer.Span[wordIndex] >> 16; - index += 1; - return true; - } - } - - public readonly Instruction ParseCurrentInstruction() - { - var count = buffer.InstructionMemory.Span[wordIndex] >> 16; - return new Instruction(buffer.InstructionMemory[wordIndex..(wordIndex + count)]); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 96879d3ec2..8d22f7d488 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -1,11 +1,11 @@ using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; -using Stride.Shaders.Spirv.Core.Buffers; - using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; @@ -17,77 +17,60 @@ namespace Stride.Shaders.Spirv.Core.Parsing; ///
public ref struct OrderedEnumerator(ISpirvBuffer buffer) { - int index = 0; - int wordIndex = 0; + int currentPosition = 0; bool started = false; - readonly ISpirvBuffer wbuff = buffer; - readonly Span InstructionWords => wbuff.InstructionSpan; - - public readonly Instruction Current => new(wbuff.InstructionMemory.Slice(wordIndex, wbuff.InstructionSpan[wordIndex] >> 16)); + public readonly Instruction Current => buffer.InstructionsSpan[currentPosition]; public bool MoveNext() { // The first time find the lowest group and index if (!started) { - (var firstGroup, var firstPos) = (int.MaxValue, int.MaxValue); - var wid = 0; - var idx = 0; - while(wid < InstructionWords.Length) + var firstGroup = int.MaxValue; + var firstPos = int.MaxValue; + for (var index = 0; index < buffer.InstructionsSpan.Length; index++) { - var group = GetGroupOrder(wid); - if(group < firstGroup) + var instruction = buffer.InstructionsSpan[index]; + var group = GetGroupOrder(instruction); + if (group < firstGroup) { firstGroup = group; - firstPos = wid; - index = idx; + firstPos = index; } - idx += 1; - wid += InstructionWords[wid] >> 16; } - wordIndex = firstPos; + + currentPosition = firstPos; started = true; return true; } else { // We start from the current group since we've established there is no other below this one - var currentGroup = GetGroupOrder(wordIndex); + var currentGroup = GetGroupOrder(buffer.InstructionsSpan[currentPosition]); for (int group = currentGroup; group < 15; group += 1) { if(group == currentGroup) { - var offset = InstructionWords[wordIndex] >> 16; - var idx = index + 1; - while(wordIndex + offset < InstructionWords.Length) + for (int i = currentPosition + 1; i < buffer.InstructionsSpan.Length; ++i) { - if(GetGroupOrder(wordIndex + offset) == group && idx > index) + if (GetGroupOrder(buffer.InstructionsSpan[i]) == group) { - wordIndex += offset; - index = idx; + currentPosition = i; return true; } - offset += InstructionWords[wordIndex + offset] >> 16; - idx += 1; } } else { - var wid = 0; - var idx = 0; - while (wid < InstructionWords.Length) + for (int i = 0; i < buffer.InstructionsSpan.Length; ++i) { - var g = GetGroupOrder(wid); - if (g == group) + if (GetGroupOrder(buffer.InstructionsSpan[i]) == group) { - wordIndex = wid; - index = idx; + currentPosition = i; return true; } - idx += 1; - wid += InstructionWords[wid] >> 16; } } } @@ -96,9 +79,8 @@ public bool MoveNext() } - readonly int GetGroupOrder(int wid) + readonly int GetGroupOrder(Instruction instruction) { - var op = (SDSLOp)(InstructionWords[wid] & 0xFFFF); - return InstructionInfo.GetGroupOrder(op, op == SDSLOp.OpVariable ? (StorageClass)InstructionWords[wid + 3] : null); + return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index 4e35f91967..f9bb6f3acd 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -14,16 +14,15 @@ public static void ParseToList(byte[] byteCode, List instructions) var span = MemoryMarshal.Cast(byteCode.AsSpan()); var data = new SpirvBuffer(span); - foreach (var instruction in data) + foreach (var instruction in data.Instructions) instructions.Add(instruction); } - SpirvSpan buffer; + SpirvBuffer buffer; public int Count => GetInstructionCount(); - public int WordCount => buffer.Length; public bool HasHeader { get; init; } public SpirvReader(byte[] byteCode, bool hasHeader = false) @@ -45,24 +44,12 @@ public SpirvReader(Memory slice) buffer = new(slice.Span); //data = slice; } - public SpirvReader(SpirvSpan span) + public SpirvReader(SpirvBuffer span) { buffer = span; //data = slice; } - public readonly InstructionEnumerator GetEnumerator() => new(buffer.Memory, HasHeader); - - public readonly int GetInstructionCount() - { - var count = 0; - var index = 0; - while(index < buffer.Length) - { - count += 1; - index += buffer.Span[index] >> 16; - } - return count; - } + public readonly int GetInstructionCount() => buffer.Instructions.Count; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 07a048b1d1..0dfb50c36f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -185,8 +185,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return source; var resultType = context.GetOrRegister(Type); - var result = builder.Buffer.InsertOpAccessChain(builder.Position, variable, resultType, source.Id, indexes); - builder.Position += result.WordCount; + var result = builder.Buffer.InsertOpAccessChain(builder.Position++, variable, resultType, source.Id, indexes); return new(result, resultType); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 2a82a0a7c0..9eb34c7a90 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -23,7 +23,7 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D var memberNames = new Dictionary<(int, int), string>(); names = new Dictionary(); types = new Dictionary(); - foreach (var instruction in buffer) + foreach (var instruction in buffer.Instructions) { if (instruction.OpCode == SDSLOp.OpName) { @@ -90,7 +90,7 @@ private ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixi ProcessNameAndTypes(buffer, out var names, out var types); var symbols = new List(); - foreach (var instruction in buffer) + foreach (var instruction in buffer.Instructions) { if (instruction.OpCode == SDSLOp.OpVariable) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 187b42a0ad..fc3e1d297f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -163,8 +163,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit foreach (var d in Variables) { var variable = context.Bound++; - var instruction = builder.Buffer.InsertOpVariable(builder.Position, variable, registeredType, Specification.StorageClass.Function, null); - builder.Position += instruction.WordCount; + var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); context.AddName(variable, d.Variable); if (builder.CurrentFunction is SpirvFunction f) @@ -203,12 +202,11 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { var sourceLoad = context.Bound++; var underlyingType = context.GetOrRegister(p.BaseType); - builder.Position += builder.Buffer.InsertOpLoad(builder.Position, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.None).WordCount; + builder.Buffer.InsertOpLoad(builder.Position++, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.None); source = new(sourceLoad, underlyingType); } - var instruction = builder.Buffer.InsertOpStore(builder.Position, target.Id, source.Id, null); - builder.Position += instruction.WordCount; + var instruction = builder.Buffer.InsertOpStore(builder.Position++, target.Id, source.Id, null); } } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index fc14a9a752..e55b0fbf9e 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -16,81 +16,80 @@ public SpirvValue BinaryOperation(SpirvContext context, int resultType, in Spirv { (Operator.Plus, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpIAdd(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpIAdd(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Plus, ScalarType l, ScalarType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFAdd(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpFAdd(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Minus, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpISub(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpISub(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Minus, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFSub(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpFSub(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Mul, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpIMul(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpIMul(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Mul, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFMul(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpFMul(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Div, SymbolType l, SymbolType r) when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) - => Buffer.InsertOpUDiv(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpUDiv(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Div, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpSDiv(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpSDiv(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Div, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() - => Buffer.InsertOpFDiv(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpFDiv(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Mod, SymbolType l, SymbolType r) when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() - => Buffer.InsertOpUMod(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpUMod(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Mod, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpSMod(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpSMod(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.Mod, SymbolType l, SymbolType r) when l.IsFloating() && r.IsNumber() - => Buffer.InsertOpFMod(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpFMod(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.RightShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpShiftRightLogical(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.LeftShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpShiftRightLogical(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.AND, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseAnd(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpBitwiseAnd(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.OR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseOr(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpBitwiseOr(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.XOR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseXor(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpBitwiseXor(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertOpLogicalAnd(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpLogicalAnd(Position++, context.Bound++, resultType, left.Id, right.Id), (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertOpLogicalOr(Position, context.Bound++, resultType, left.Id, right.Id), + => Buffer.InsertOpLogicalOr(Position++, context.Bound++, resultType, left.Id, right.Id), _ => throw new NotImplementedException() }; - Position += instruction.WordCount; if (instruction.ResultId is int resultId) { if (name is not null) @@ -113,15 +112,13 @@ public SpirvValue CallFunction(SpirvContext context, string name, Span pa if (!context.Module.Functions.TryGetValue(name, out var func)) context.Module.InheritedFunctions.TryGetValue(name, out func); - var fcall = Buffer.InsertOpFunctionCall(Position, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); - Position += fcall.WordCount; + var fcall = Buffer.InsertOpFunctionCall(Position++, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); return new(fcall, func.Name); } public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { - var instruction = Buffer.InsertOpCompositeConstruct(Position, context.Bound++, context.GetOrRegister(literal.Type), values); - Position += instruction.WordCount; + var instruction = Buffer.InsertOpCompositeConstruct(Position++, context.Bound++, context.GetOrRegister(literal.Type), values); return new(instruction); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 12678e21ea..e6a2161c2f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -8,8 +8,7 @@ public partial class SpirvBuilder { public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { - var i = Buffer.InsertOpLabel(Position, context.Bound++); - Position += i.WordCount; + var i = Buffer.InsertOpLabel(Position++, context.Bound++); Buffer.InsertOpUnreachable(Position); var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); return result; @@ -17,20 +16,19 @@ public SpirvBlock CreateBlock(SpirvContext context, string? name = null) public void Return(in SpirvValue? value = null) { - Position += value switch + _ = value switch { - SpirvValue v => Buffer.InsertOpReturnValue(Position, v.Id).WordCount, - _ => Buffer.InsertOpReturn(Position).WordCount + SpirvValue v => Buffer.InsertOpReturnValue(Position++, v.Id).WordCount, + _ => Buffer.InsertOpReturn(Position++).WordCount }; CleanBlock(); } public void CleanBlock() { - if ((Buffer.Span[Position] & 0xFFFF) == (int)SDSLOp.OpUnreachable) + if (Buffer.Instructions[Position].OpCode == SDSLOp.OpUnreachable) { - var size = Buffer.Span[Position] >> 16; - Buffer.Remove(Position); + Buffer.Instructions.RemoveAt(Position); } } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 7933dae3aa..c070fc2a00 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -12,7 +12,7 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT foreach(var t in ftype.ParameterTypes) context.GetOrRegister(t); var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); - Position += func.WordCount; + Position = Buffer.Instructions.Count; context.AddName(func, name); var result = new SpirvFunction(func.ResultId!.Value, name, ftype); CurrentFunction = result; @@ -22,13 +22,12 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT public void EndFunction(SpirvContext context) { - Position += Buffer.InsertOpFunctionEnd(Position).WordCount; + Buffer.InsertOpFunctionEnd(Position++); } public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) { - var p = Buffer.InsertOpFunctionParameter(Position, context.Bound++, context.GetOrRegister(type)); - Position += p.WordCount; + var p = Buffer.InsertOpFunctionParameter(Position++, context.Bound++, context.GetOrRegister(type)); context.AddName(p, name); CurrentFunction!.Value.Parameters.Add(name, new(p, name)); return new(p, name); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index c7617e8d81..a07d280451 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -9,12 +9,12 @@ namespace Stride.Shaders.Spirv.Building; // Should have utility functions to add instruction to the buffer -public partial class SpirvBuilder() : IDisposable +public partial class SpirvBuilder() { public SpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; private set; } public SpirvBlock? CurrentBlock { get; private set; } - public int Position { get; internal set; } = 5; + public int Position { get; internal set; } = 0; public void SetPositionTo(TBlock block, bool beggining = false) where TBlock : IInstructionBlock @@ -33,7 +33,7 @@ public void SetPositionTo(TBlock block, bool beggining = false) (int)SDSLOp.OpTerminateInvocation ]; var wid = 0; - foreach (var e in Buffer) + foreach (var e in Buffer.Instructions) { if (e.ResultId is int id && id == block.Id) { @@ -58,7 +58,7 @@ public void SetPositionTo(TBlock block, bool beggining = false) wid += e.WordCount; } - Position = Buffer.Length; + Position = Buffer.Instructions.Count; } public SpirvBuffer Build(SpirvContext context) @@ -67,7 +67,6 @@ public SpirvBuffer Build(SpirvContext context) return SpirvBuffer.Merge(context.Buffer, Buffer); } - public void Dispose() => Buffer.Dispose(); public override string ToString() { return new SpirvDis(Buffer).Disassemble(); diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 839f39c30a..1820ad16b3 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Spirv.Building; public abstract class CompilerArgument; -public class CompilerUnit : IDisposable +public class CompilerUnit { public SpirvModule Module { get; } public SpirvContext Context { get; } @@ -31,12 +31,6 @@ public void Deconstruct(out SpirvBuilder builder, out SpirvContext context, out module = Module; } - public void Dispose() - { - Builder.Dispose(); - Context.Dispose(); - } - public override string ToString() { var builder = new StringBuilder(); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 47b0013816..cfa2391242 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -16,7 +16,7 @@ public interface IExternalShaderLoader // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters -public class SpirvContext(SpirvModule module) : IDisposable +public class SpirvContext(SpirvModule module) { public int Bound { get; internal set; } = 1; public string? Name { get; private set; } @@ -32,7 +32,7 @@ public void PutShaderName(string name) if (Name is null) { Name = name; - Buffer.InsertOpSDSLShader(5, name); + Buffer.InsertOpSDSLShader(0, name); } else throw new NotImplementedException(); } @@ -242,8 +242,6 @@ public SpirvValue CreateConstant(Literal literal) return result; } - public void Dispose() => Buffer.Dispose(); - public override string ToString() { return new SpirvDis(Buffer).Disassemble(); diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 184eb2638e..e1c684bf9a 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -84,7 +84,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList nameTable = []; SortedList semanticTable = []; - foreach (var instruction in context.Buffer) + foreach (var instruction in context.Buffer.Instructions) { { if ((instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) @@ -109,7 +109,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) { var methodStart = FindMethodStart(compiler, functionId); - var enumerator = new MutableFunctionInstructionEnumerator(compiler.Builder.Buffer, methodStart); - - while (enumerator.MoveNext()) + for (var index = methodStart; index < compiler.Builder.Buffer.Instructions.Count; index++) { - var instruction = enumerator.Current; - + var instruction = compiler.Builder.Buffer.Instructions[index]; if (instruction.OpCode == SDSLOp.OpFunctionEnd) break; @@ -282,15 +279,14 @@ private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList words) { writer.Append(' '); - foreach (var e in buffer) + foreach (var e in buffer.InstructionsSpan) { if (e.ResultId is int rid && rid == typeId) { diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 19bbf19ea2..35499e3c15 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -26,7 +26,7 @@ public partial struct SpirvDis public SpirvDis(TBuffer buff, bool useNames = false) { buffer = buff; - if(buff.InstructionSpan.Length == 0) + if(buff.InstructionsSpan.Length == 0) return; writer = new(); UseNames = useNames; @@ -44,7 +44,7 @@ public SpirvDis(TBuffer buff, bool useNames = false) else { var maxName = 0; - foreach (var i in buffer) + foreach (var i in buffer.InstructionsSpan) { if ( (i.OpCode == SDSLOp.OpName || i.OpCode == SDSLOp.OpMemberName) @@ -77,17 +77,17 @@ public string Disassemble(bool writeToConsole = false) .AppendLine($"; Schema: {header.Schema}"); } - if(buffer.InstructionSpan.Length == 0) + if(buffer.InstructionsSpan.Length == 0) return ""; // First pass: scan names - foreach (var e in buffer) + foreach (var e in buffer.InstructionsSpan) { CheckNameTable(e); } // Second pass: disassemble - foreach (var e in buffer) + foreach (var e in buffer.InstructionsSpan) { if (UseNames && e.ResultId is int id && nameTable.TryGetValue(id, out var nid)) Append(nid); From b3d12df5268388cce446e4a9eb34091d2b6b2554 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 14 Jun 2025 10:30:36 +0900 Subject: [PATCH 0421/1182] Added proper support for UserSemantic disassembly --- .../Information/InstructionInfo.cs | 4 ++-- .../Extensions/spirv.sdsl.grammar-ext.json | 14 -------------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +--- .../Spirv/Processing/StreamAnalyzer.cs | 5 +++-- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index 1246ec1fd5..d24358f39b 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -46,7 +46,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - // Info.Add(new(SDSLOp.OpDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(SDSLOp.OpDecorate, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); @@ -71,7 +71,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - // Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.HlslSemanticGOOGLE), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); } /// diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json index 41e3febc3e..70b9402402 100644 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -1,19 +1,5 @@ { "instructions": [ - { - "opname": "OpSDSLDecorateSemantic", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdRef", - "name": "'Target'" - }, - { - "kind": "LiteralString", - "name": "semantic" - } - ] - }, { "opname": "OpSDSLShader", "class": "Miscellaneous", diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 469719a587..0ad0836345 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -90,9 +90,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Buffer.AddOpVariable(variable, registeredType, Specification.StorageClass.Private, null); context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) - context.Buffer.AddOpSDSLDecorateSemantic(variable, Semantic.Name); - //if (Semantic != null) - // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); + context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); context.AddName(variable, Name); } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index e1c684bf9a..eee98be49b 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -97,9 +97,10 @@ private static void PropagateStreamsFromPreviousStage(SortedList().Decoration == Specification.Decoration.UserSemantic && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - && instruction.TryGetOperand("semantic", out LiteralString? name) && name is LiteralString n + && instruction.TryGetOperand("semanticName", out LiteralString? name) && name is LiteralString n ) { semanticTable[t] = n.Value; From 9beac57e61f6d032ba31690955b61a18c16307b4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 14 Jun 2025 18:01:44 +0900 Subject: [PATCH 0422/1182] Switch from OpDecorate to OpDecorateString for user semantic --- .../Information/InstructionInfo.cs | 17 +++++++++++++++-- .../MemoryInstruction.cs | 6 +++--- .../Parsing/OperandEnumerator.cs | 11 +---------- .../SPVGenerator.Buffers.cs | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index d24358f39b..0001a59b04 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -46,7 +46,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(SDSLOp.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); @@ -71,7 +71,7 @@ public partial class InstructionInfo Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(SDSLOp.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); } /// @@ -100,4 +100,17 @@ public static LogicalOperandArray GetInfo(OperandKey op) return Instance.Info[op with { Decoration = null }]; return Instance.Info[op]; } + public static LogicalOperandArray GetInfo(Instruction instruction) + { + Decoration? decoration = instruction.OpCode switch + { + SDSLOp.OpDecorateString + or SDSLOp.OpDecorate + or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], + SDSLOp.OpMemberDecorate + or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], + _ => null + }; + return GetInfo(new OperandKey(instruction.OpCode, decoration)); + } } diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index dbb7e9a660..d46f28617d 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -40,7 +40,7 @@ public TWrapper UnsafeAs() public T? GetOperand(string name) where T : struct, IFromSpirv { - var info = InstructionInfo.GetInfo(OpCode); + var info = InstructionInfo.GetInfo(this); var infoEnumerator = info.GetEnumerator(); var operandEnumerator = GetEnumerator(); while (infoEnumerator.MoveNext()) @@ -59,7 +59,7 @@ public TWrapper UnsafeAs() internal T? GetEnumOperand(string name) where T : Enum { - var info = InstructionInfo.GetInfo(OpCode); + var info = InstructionInfo.GetInfo(this); var infoEnumerator = info.GetEnumerator(); var operandEnumerator = GetEnumerator(); while (infoEnumerator.MoveNext()) @@ -110,7 +110,7 @@ public void SetResultType(int? value) public bool TryGetOperand(string name, out T? operand) where T : struct, IFromSpirv { - var info = InstructionInfo.GetInfo(OpCode); + var info = InstructionInfo.GetInfo(this); var infoEnumerator = info.GetEnumerator(); var operandEnumerator = GetEnumerator(); while (infoEnumerator.MoveNext()) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index c191704395..835567bdfb 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -17,16 +17,7 @@ public ref struct OperandEnumerator public OperandEnumerator(Instruction instruction) { this.instruction = instruction; - Decoration? decoration = instruction.OpCode switch - { - SDSLOp.OpDecorateString - or SDSLOp.OpDecorate - or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], - SDSLOp.OpMemberDecorate - or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], - _ => null - }; - logicalOperands = InstructionInfo.GetInfo(new(instruction.OpCode, decoration)); + logicalOperands = InstructionInfo.GetInfo(instruction); oid = -1; wid = 0; } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index b901345e9b..5e1d60a379 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -54,7 +54,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorateString, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -63,7 +63,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorateString, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); } From 4884afc421dd01d1989ca4d98e048d615885fbf3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 14 Jun 2025 11:28:05 +0200 Subject: [PATCH 0423/1182] correction on glsl instructions --- .../SPVGenerator.Instructions.cs | 2 +- .../SPVGenerator.SDSLOp.cs | 142 +++++++++--------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 7daf69d585..f791ad463e 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -75,7 +75,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat else if (operand.Class == "ValueEnum") builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); else - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}/*{operand.Class}*/>(\"{operandName}\") ?? default;"); + builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); } } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 3d96146164..f946d5bb86 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -24,10 +24,10 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr var instructionsProvider = grammarProvider - .Select(static (grammar, _) => grammar.Instructions); - // .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) - // .Collect() - // .Select(static (arr, _) => new EquatableList([.. arr])); + .SelectMany(static (grammar, b) => grammar.Instructions?.AsList() ?? []) + .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + .Collect() + .Select(static (arr, _) => new EquatableList([.. arr])); context.RegisterImplementationSourceOutput( instructionsProvider, @@ -37,85 +37,81 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr ); } - public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList? instructionArray) + public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList instructionArray) { - if (instructionArray is not null) - { - var code = new StringBuilder(); - code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum SDSLOp : int") - .AppendLine("{"); - Dictionary members = instructionArray?.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; - int lastnum = members.Values.Max(); - foreach (var instruction in instructionArray!) + var code = new StringBuilder(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum SDSLOp : int") + .AppendLine("{"); + + Dictionary members = instructionArray?.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; + int lastnum = members.Values.Max(); + foreach (var instruction in instructionArray!) + { + if (members.TryGetValue(instruction.OpName, out var value)) { - if (members.TryGetValue(instruction.OpName, out var value)) - { - if (instruction.OpName.Contains("SDSL") && value <= 0) - value = ++lastnum; - code.AppendLine($" {instruction.OpName} = {value},"); - } - else - { - members.Add(instruction.OpName, ++lastnum); - code.AppendLine($" {instruction.OpName} = {lastnum},"); - } + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); } + else + { + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); + } + } - code.AppendLine("}"); - ctx.AddSource("SDSLOp.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - code.Clear(); - code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv;") - .AppendLine("") - .AppendLine("public static partial class Specification") - .AppendLine("{") - .AppendLine("public enum Op : int") - .AppendLine("{"); + code.AppendLine("}"); + ctx.AddSource("SDSLOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + code.Clear(); + code + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv;") + .AppendLine("") + .AppendLine("public static partial class Specification") + .AppendLine("{") + .AppendLine("public enum Op : int") + .AppendLine("{"); - foreach (var instruction in instructionArray!) + foreach (var instruction in instructionArray!) + { + if (members.TryGetValue(instruction.OpName, out var value)) { - if (members.TryGetValue(instruction.OpName, out var value)) - { - if (instruction.OpName.Contains("SDSL") && value <= 0) - value = ++lastnum; - code.AppendLine($" {instruction.OpName} = {value},"); - } - else - { - members.Add(instruction.OpName, ++lastnum); - code.AppendLine($" {instruction.OpName} = {lastnum},"); - } + if (instruction.OpName.Contains("SDSL") && value <= 0) + value = ++lastnum; + code.AppendLine($" {instruction.OpName} = {value},"); + } + else + { + members.Add(instruction.OpName, ++lastnum); + code.AppendLine($" {instruction.OpName} = {lastnum},"); } - code.AppendLine("}}"); - - ctx.AddSource("SpecificationOp.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - } + code.AppendLine("}}"); + ctx.AddSource("SpecificationOp.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); } } From 16807908f3eeb7a0ea2b737a584b282ad2319571 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 14 Jun 2025 11:51:15 +0200 Subject: [PATCH 0424/1182] fixed opstruct --- src/Stride.Shaders.Experiments/Program.cs | 6 +++++- src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs | 2 +- src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index a30d6f730a..c98e77ceef 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -13,4 +13,8 @@ // Examples.TryAllFiles(); Examples.CreateShader(); -var buffer = new SpirvBuffer(32); \ No newline at end of file +var buffer = new SpirvBuffer(32); +var t_int = buffer.AddOpTypeInt(1, 32, 0); +buffer.AddOpTypeStruct(2, [t_int, t_int]); + +new SpirvDis(buffer).Disassemble(true); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index c191704395..7448b44dea 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -180,7 +180,7 @@ public SpvOperand ParseCurrent() if (pairs.Contains(logOp.Kind ?? OperandKind.None)) return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); else - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands[wid..]); } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index f946d5bb86..4fee357d7f 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -49,7 +49,7 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList members = instructionArray?.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; + Dictionary members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; int lastnum = members.Values.Max(); foreach (var instruction in instructionArray!) { From 20744f9dfebd7f2cfe4d2dbd89689a99840f2b6a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 16 Jun 2025 01:11:10 +0200 Subject: [PATCH 0425/1182] implicit operators + some fields are editable --- src/Stride.Shaders.Experiments/Program.cs | 11 +- src/Stride.Shaders.Spirv.Generators/Data.cs | 1 + .../SPVGenerator.Helpers.Naming.cs | 8 ++ .../SPVGenerator.Instructions.cs | 106 +++++++++++------- 4 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index c98e77ceef..8cf29e7f4a 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -9,12 +9,13 @@ using static Stride.Shaders.Spirv.Specification; //Examples.CompileSDSL(); -Examples.MergeSDSL(); +// Examples.MergeSDSL(); // Examples.TryAllFiles(); -Examples.CreateShader(); +// Examples.CreateShader(); var buffer = new SpirvBuffer(32); var t_int = buffer.AddOpTypeInt(1, 32, 0); -buffer.AddOpTypeStruct(2, [t_int, t_int]); - -new SpirvDis(buffer).Disassemble(true); \ No newline at end of file +InstOpTypeStruct tstr = buffer.AddOpTypeStruct(3, [t_int, t_int]); +InstOpExecutionMode tmode = buffer.AddOpExecutionMode(4, ExecutionMode.LocalSize); +tmode.Mode = ExecutionMode.Invocations; +Console.WriteLine(tmode.Mode); diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index 4960504647..5f615e29db 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -88,6 +88,7 @@ public record struct OperandData public string? Quantifier { get; set; } public string? Class { get; set; } public string? TypeName { get; set; } + public bool IsIndexKnown { get; set; } } public record struct InstructionData diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 6cf91c9c61..aa7a3e28f4 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -60,9 +60,17 @@ public static void PreProcessOperands(InstructionData op, Dictionary operands) { + bool computable = true; for (int i = 0; i < operands.Count; i++) { var e = operands[i]; + e.IsIndexKnown = computable; + computable = (computable, e.Kind, e.Quantifier) switch + { + (true, _, "*" or "+") => false, + (true, "LiteralString", _) => false, + _ => computable + }; var kind = e.Kind; var realKind = ConvertKind(kind!, operandKinds); if (e.Quantifier is not null) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index f791ad463e..72fc703700 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -13,16 +13,16 @@ public void GenerateStructs(IncrementalGeneratorInitializationContext context, I { var sdslInstructionsData = grammarProvider - .Select(static (grammar, _) => grammar.Instructions); + .Select(static (grammar, _) => grammar.Instructions ?? new([])); context.RegisterImplementationSourceOutput( sdslInstructionsData, - (source, instructions) => GenerateInstructionStructs(source, instructions) + GenerateInstructionStructs ); } - public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableList? instructions) + public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableList instructions) { StringBuilder builder = new(); @@ -32,40 +32,66 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine() .AppendLine(); - if (instructions is not null) + + foreach (var instruction in instructions) { - foreach (var instruction in instructions) - { - builder - .AppendLine($"public ref struct Inst{instruction.OpName} : IWrapperInstruction") - .AppendLine("{") - .AppendLine("public Instruction Inner { get; set; }"); - try + builder + .AppendLine($"public ref struct Inst{instruction.OpName} : IWrapperInstruction") + .AppendLine("{") + .AppendLine("public Instruction Inner { get; set; }"); + try + { + if (instruction.Operands?.AsList() is List operands && operands.Count > 0) { - if (instruction.Operands != null) + var tmp = 1; + foreach (var operand in operands) { - foreach (var operand in instruction.Operands) + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else { - string fieldName; - string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - if (operand.Name is null or "") - fieldName = ConvertKindToName(operand.Kind, false); - else + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) { - var nameBuilder = new StringBuilder(); - bool first = true; - foreach (var c in operand.Name) + if (char.IsLetterOrDigit(c) || c == '_') { - if (char.IsLetterOrDigit(c) || c == '_') - { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } - + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; } - fieldName = nameBuilder.ToString(); + + } + fieldName = nameBuilder.ToString(); + } + + if (operand.IsIndexKnown && operand.Class == "Id" || operand.Class == "BitEnum" || operand.Class == "ValueEnum" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + { + if (operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + { + builder.AppendLine($"public int {fieldName} {{get => Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = value;}}"); + tmp += 1; + } + else if (operand.Class == "BitEnum") + { + builder.AppendLine($"public {operand.Kind}Mask {fieldName} {{get => ({operand.Kind}Mask)Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = (int)value;}}"); + tmp += 1; + } + else if (operand.Class == "ValueEnum") + { + builder.AppendLine($"public {operand.Kind} {fieldName} {{get => ({operand.Kind})Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = (int)value;}}"); + tmp += 1; + } + else if (operand.Class == "Id") + { + builder.AppendLine($"public {operand.Kind} {fieldName} {{get => new {operand.Kind}(Inner.Memory.Span[{tmp}]); set => Inner.Memory.Span[{tmp}] = value;}}"); + tmp += 1; } + } + else + { if (operand.Kind == "LiteralContextDependentNumber") continue; else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") @@ -79,22 +105,24 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat } } } - catch (Exception e) - { - builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); - } + } + catch (Exception e) + { + builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); + } - builder - .AppendLine() - .AppendLine($"public Inst{instruction.OpName}(Instruction instruction) => Inner = instruction;"); + builder + .AppendLine() + .AppendLine($"public Inst{instruction.OpName}(Instruction instruction) => Inner = instruction;") + .AppendLine($"public static implicit operator Inst{instruction.OpName}(Instruction instruction) => new(instruction);"); - builder - .AppendLine("}") - .AppendLine(); - } + builder + .AppendLine("}") + .AppendLine(); } + spc.AddSource( $"InstructionStructs.gen.cs", SourceText.From( From 4a8b46476e5d49c29af5d813900be6ba7a99fb3e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Jun 2025 14:42:06 +0900 Subject: [PATCH 0426/1182] Fix operand enumeration when there is more than one entry --- .../MemoryInstruction.cs | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index d46f28617d..02adf50169 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -132,20 +132,24 @@ public void OffsetIds(int offset) { foreach (var o in this) { - if (o.Kind == OperandKind.IdRef) - o.Words[0] += offset; - else if (o.Kind == OperandKind.IdResult) - o.Words[0] += offset; - else if (o.Kind == OperandKind.IdResultType) - o.Words[0] += offset; - else if (o.Kind == OperandKind.PairIdRefLiteralInteger) - o.Words[0] += offset; - else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) - o.Words[1] += offset; - else if (o.Kind == OperandKind.PairIdRefIdRef) + if (o.Kind == OperandKind.IdRef + || o.Kind == OperandKind.IdResult + || o.Kind == OperandKind.IdResultType) { - o.Words[0] += offset; - o.Words[1] += offset; + for (int i = 0; i < o.Words.Length; ++i) + o.Words[i] += offset; + } + else if (o.Kind == OperandKind.PairIdRefLiteralInteger + || o.Kind == OperandKind.PairLiteralIntegerIdRef + || o.Kind == OperandKind.PairIdRefIdRef) + { + for (int i = 0; i < o.Words.Length; i += 2) + { + if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 0] += offset; + if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 1] += offset; + } } } } From a1c53ad72481b523fdb5f4f5e85c98b41547c138 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Jun 2025 14:44:50 +0900 Subject: [PATCH 0427/1182] Improvement to Stream analyzer --- assets/SDSL/TestBase.sdsl | 1 + src/Stride.Shaders.Experiments/Examples.cs | 184 ++++++++++- src/Stride.Shaders.Experiments/Program.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- .../Spirv/Processing/StreamAnalyzer.cs | 160 ++++------ .../Spirv/Processing/TypeDuplicatesRemover.cs | 301 ++++++------------ 7 files changed, 339 insertions(+), 315 deletions(-) diff --git a/assets/SDSL/TestBase.sdsl b/assets/SDSL/TestBase.sdsl index 3454dd7f10..2e87052268 100644 --- a/assets/SDSL/TestBase.sdsl +++ b/assets/SDSL/TestBase.sdsl @@ -7,5 +7,6 @@ shader TestBase void SetColor(float4 color) { streams.ColorTarget = color; + return; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 036dc1d1ad..5f89cf5a90 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -4,18 +4,21 @@ using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; +using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Processing; -using Stride.Shaders.Spirv.Tools; +using static Silk.NET.Core.Native.WinString; namespace Stride.Shaders.Experiments; @@ -291,6 +294,12 @@ static SpirvBuffer GetOrLoadShader(string name) return buffer; } + class ShaderInfo + { + public Dictionary Functions { get; } = new(); + public Dictionary Variables { get; } = new(); + } + public static void MergeSDSL() { CompileSDSL(); @@ -310,31 +319,182 @@ public static void MergeSDSL() var temp = new SpirvBuffer(); var offset = 0; var nextOffset = 0; + foreach (var shaderName in inheritanceList) { var shader = GetOrLoadShader(shaderName); offset += nextOffset; + nextOffset = 0; foreach (var i in shader.Instructions) { - temp.Add(i.Words); + var i2 = temp.Add(i.Words); - if (i.ResultId != null) + if (i.ResultId != null && i.ResultId.Value > nextOffset) nextOffset = i.ResultId.Value; - i.OffsetIds(offset); + i2.OffsetIds(offset); } } - var dis = new SpirvDis(temp, true); - dis.Disassemble(true); + var shaders = new Dictionary(); + ShaderInfo? currentShader = null; + + var names = new Dictionary(); + var importedShaders = new Dictionary(); + var idRemapping = new Dictionary(); + foreach (var i in temp.Instructions) + { + if (i.OpCode == SDSLOp.OpName) + { + var nameInstruction = i.UnsafeAs(); + names.Add(nameInstruction.Target, nameInstruction.Name.Value); + } + else if (i.OpCode == SDSLOp.OpSDSLShader) + { + currentShader = new ShaderInfo(); + var shaderName = i.UnsafeAs().ShaderName.Value; + shaders.Add(shaderName, currentShader); + SetOpNop(i.Words); + } + else if (i.OpCode == SDSLOp.OpSDSLShaderEnd) + { + currentShader = null; + importedShaders.Clear(); + SetOpNop(i.Words); + } + else if (i.OpCode == SDSLOp.OpSDSLMixinInherit) + { + SetOpNop(i.Words); + } + + if (i.OpCode == SDSLOp.OpFunction) + { + var function = i.UnsafeAs(); + var functionName = names[function.ResultId.Value]; + currentShader!.Functions.Add(functionName, i.ResultId!.Value); + + //temp.Remove(i.Position); + //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.Functioncontrol, function.FunctionType); + } + + if (i.OpCode == SDSLOp.OpVariable) + { + var variable = i.UnsafeAs(); + var variableName = names[variable.ResultId.Value]; + currentShader!.Variables.Add(variableName, i.ResultId!.Value); + } + + if (i.OpCode == SDSLOp.OpSDSLImportShader) + { + var importShader = i.UnsafeAs(); + + importedShaders.Add(importShader.ResultId.Value, shaders[importShader.ShaderName.Value]); + + SetOpNop(i.Words); + } + else if (i.OpCode == SDSLOp.OpSDSLImportVariable) + { + var importVariable = i.UnsafeAs(); + var importedShader = importedShaders[importVariable.Shader]; + + var importedVariable = importedShader.Variables[importVariable.VariableName.Value]; + + idRemapping.Add(importVariable.ResultId.Value, importedVariable); + + SetOpNop(i.Words); + } + else if (i.OpCode == SDSLOp.OpSDSLImportFunction) + { + var importFunction = i.UnsafeAs(); + + var importedShader = importedShaders[importFunction.Shader]; + var importedFunction = importedShader.Functions[importFunction.FunctionName.Value]; + idRemapping.Add(importFunction.ResultId.Value, importedFunction); + + SetOpNop(i.Words); + } + + foreach (var op in i) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[0], out var to1)) + op.Words[0] = to1; + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + op.Words[1] = to2; + } + } // Step: merge mixins // start from most-derived class and import on demand // Step: analyze streams and generate in/out variables - //var context = compiler.Context; - //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); - //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); - //new StreamAnalyzer().Process(table, compiler); + new TypeDuplicateRemover().Apply(temp); + + var context = new SpirvContext(new()); + context.Bound = offset + nextOffset + 1; + ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); + foreach (var i in temp.Instructions) + { + if (i.OpCode == SDSLOp.OpFunction) + { + var function = i.UnsafeAs(); + var functionName = names2[i.ResultId.Value]; + context.Module.Functions.Add(functionName, new SpirvFunction(i.ResultId.Value, functionName, (FunctionType)types[function.FunctionType])); + } + } + + foreach (var type in types) + { + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); + } + + context.Buffer.AddOpCapability(Specification.Capability.Shader); + context.Buffer.AddOpMemoryModel(Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); + new StreamAnalyzer().Process(temp, context); + + temp.Instructions.AddRange(context.Buffer.Instructions); + + new TypeDuplicateRemover().Apply(temp); + + var dis = new SpirvDis(temp, true); + var source = dis.Disassemble(true); + + File.WriteAllText("test.spvdis", source); + } + + static void ReplaceRefs(int from, int to, Instruction i) + { + var opcode = i.OpCode; + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + if (op.Words[0] == from || op.Words[1] == from) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); } private static void BuildInheritanceList(SpirvBuffer buffer, List inheritanceList) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 8cf29e7f4a..6589219800 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -9,7 +9,7 @@ using static Stride.Shaders.Spirv.Specification; //Examples.CompileSDSL(); -// Examples.MergeSDSL(); +Examples.MergeSDSL(); // Examples.TryAllFiles(); // Examples.CreateShader(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 76e81e826a..77fbe6caac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -18,7 +18,7 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public ShaderParameterDeclarations? Generics { get; set; } public List Mixins { get; set; } = []; - public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out Dictionary names, out Dictionary types) + public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out Dictionary names, out Dictionary types) { var memberNames = new Dictionary<(int, int), string>(); names = new Dictionary(); @@ -82,7 +82,7 @@ public Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out D return types; } - private ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) + private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) { externalShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index cfa2391242..dbe310a60e 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -18,7 +18,7 @@ public interface IExternalShaderLoader // SPIR-V parameters public class SpirvContext(SpirvModule module) { - public int Bound { get; internal set; } = 1; + public int Bound { get; set; } = 1; public string? Name { get; private set; } public SpirvModule Module { get; } = module; public SortedList Variables { get; } = []; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index eee98be49b..f83768a9d2 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -1,19 +1,8 @@ -using Spv; -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.Analysis; -using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; using Stride.Shaders.Spirv.Tools; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Spirv.Processing { @@ -39,14 +28,12 @@ class StreamInfo(string? semantic, string name, SymbolType type, int id) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - public void Process(SymbolTable table, CompilerUnit compiler) + public void Process(SpirvBuffer buffer, SpirvContext context) { - var context = compiler.Context; - var entryPointVS = context.Module.Functions["VSMain"]; var entryPointPS = context.Module.Functions["PSMain"]; - var streams = CreateStreams(compiler); + var streams = CreateStreams(buffer, context); // Expected at the end of pixel shader foreach (var stream in streams) @@ -54,7 +41,7 @@ public void Process(SymbolTable table, CompilerUnit compiler) if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) stream.Value.Stream.Output = true; } - GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + GenerateStreamWrapper(buffer, context, Specification.ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -63,7 +50,7 @@ public void Process(SymbolTable table, CompilerUnit compiler) stream.Value.Stream.Read = false; } PropagateStreamsFromPreviousStage(streams); - GenerateStreamWrapper(table, compiler, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + GenerateStreamWrapper(buffer, context, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); } private static void PropagateStreamsFromPreviousStage(SortedList streams) @@ -76,15 +63,14 @@ private static void PropagateStreamsFromPreviousStage(SortedList CreateStreams(CompilerUnit compiler) + private SortedList CreateStreams(SpirvBuffer buffer, SpirvContext context) { - var context = compiler.Context; var streams = new SortedList(); // Build name table SortedList nameTable = []; SortedList semanticTable = []; - foreach (var instruction in context.Buffer.Instructions) + foreach (var instruction in buffer.Instructions) { { if ((instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) @@ -110,7 +96,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) + private void GenerateStreamWrapper(SpirvBuffer buffer, SpirvContext context, Specification.ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) { - ProcessMethod(compiler, entryPointId, streams); + ProcessMethod(buffer, entryPointId, streams); var stage = executionModel switch { Specification.ExecutionModel.Fragment => "PS", Specification.ExecutionModel.Vertex => "VS", }; - var context = compiler.Context; - List inputStreams = []; - List outputStreams = []; + List<(StreamInfo Info, int Id)> inputStreams = []; + List<(StreamInfo Info, int Id)> outputStreams = []; foreach (var stream in streams) { // Only direct access to global variables (not temporary variables created within function) @@ -146,102 +131,75 @@ private void GenerateStreamWrapper(SymbolTable table, CompilerUnit compiler, Spe continue; if (stream.Value.Stream.Input) - inputStreams.Add(stream.Value.Stream); - // TODO: filter with previous stage + { + var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Input, context.Types[stream.Value.Stream.Type]); + var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Input, null); + context.AddName(variable, $"in_{stream.Value.Stream.Name}"); + + if (stream.Value.Stream.Semantic != null) + context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); + + inputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); + } + if (stream.Value.Stream.Output) - outputStreams.Add(stream.Value.Stream); - } + { + var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Output, context.Types[stream.Value.Stream.Type]); + var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Output, null); + context.AddName(variable, $"out_{stream.Value.Stream.Name}"); - var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); + if (stream.Value.Stream.Semantic != null) + context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); - Span inputFields = stackalloc IdRef[inputStreams.Count]; - int inputFieldIndex = 0; - var inputStructId = context.Bound++; - foreach (var stream in inputStreams) - { - inputFields[inputFieldIndex] = context.Types[stream.Type]; - context.Buffer.AddOpMemberName(inputStructId, inputFieldIndex++, stream.Name); - } - context.Buffer.AddOpTypeStruct(inputStructId, inputFields); - context.AddName(inputStructId, $"{stage}_INPUT"); - var inputStructPtrId = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, inputStructId); - - Span outputFields = stackalloc IdRef[outputStreams.Count]; - int outputFieldIndex = 0; - var outputStructId = context.Bound++; - foreach (var stream in outputStreams) - { - outputFields[outputFieldIndex] = context.Types[stream.Type]; - context.Buffer.AddOpMemberName(outputStructId, outputFieldIndex++, stream.Name); + outputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); + } } - context.Buffer.AddOpTypeStruct(outputStructId, outputFields); - context.AddName(outputStructId, $"{stage}_OUTPUT"); - var outputStructPtrId = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Function, outputStructId); + + var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); // Add new entry point wrapper - var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, outputStructId, MemoryMarshal.CreateSpan(ref inputStructPtrId, 1)); - var newEntryPointFunction = compiler.Builder.Buffer.AddOpFunction(context.Bound++, outputStructId, Specification.FunctionControlMask.None, newEntryPointFunctionType); + var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, voidTypeId, []); + var newEntryPointFunction = buffer.AddOpFunction(context.Bound++, voidTypeId, Specification.FunctionControlMask.None, newEntryPointFunctionType); + buffer.AddOpLabel(context.Bound++); context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); { - // Add INPUT (as a function parameter) - var inputParameter = compiler.Builder.Buffer.AddOpFunctionParameter(context.Bound++, inputStructPtrId); - context.AddName(inputParameter, "input"); - - compiler.Builder.Buffer.AddOpLabel(context.Bound++); - - // Add OUTPUT (as a local variable) - var outputParameter = compiler.Builder.Buffer.AddOpVariable(context.Bound++, outputStructPtrId.ResultId.Value, Specification.StorageClass.Function, null); - context.AddName(outputParameter, "output"); - // Copy read variables from streams - inputFieldIndex = 0; foreach (var stream in inputStreams) { - var typeId = compiler.Context.GetOrRegister(stream.Type); - var typePtrId = compiler.Context.GetOrRegister(new PointerType(stream.Type)); - var indexLiteral = new IntegerLiteral(new(32, false, true), inputFieldIndex++, new()); - indexLiteral.ProcessSymbol(table); - IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; - var accessChain = compiler.Builder.Buffer.AddOpAccessChain(compiler.Context.Bound++, typeId, inputParameter.ResultId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); - var loadedValue = compiler.Builder.Buffer.AddOpLoad(context.Bound++, context.Types[stream.Type], accessChain, null); - - compiler.Builder.Buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); + var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[stream.Info.Type], stream.Id, null); + buffer.AddOpStore(stream.Info.Id, loadedValue.ResultId!.Value, null); } - compiler.Builder.Buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); + buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); - inputFieldIndex = 0; foreach (var stream in outputStreams) { - var loadedValue = compiler.Builder.Buffer.AddOpLoad(context.Bound++, context.Types[stream.Type], stream.Id, null); - var typeId = compiler.Context.GetOrRegister(stream.Type); - var typePtrId = compiler.Context.GetOrRegister(new PointerType(stream.Type)); - var indexLiteral = new IntegerLiteral(new(32, false, true), inputFieldIndex++, new()); - indexLiteral.ProcessSymbol(table); - IdRef indexIdRef = compiler.Context.CreateConstant(indexLiteral).Id; - var accessChain = compiler.Builder.Buffer.AddOpAccessChain(compiler.Context.Bound++, typeId, outputParameter.ResultId!.Value, MemoryMarshal.CreateSpan(ref indexIdRef, 1)); - - compiler.Builder.Buffer.AddOpStore(accessChain.ResultId!.Value, loadedValue.ResultId!.Value, null); + var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[stream.Info.Type], stream.Info.Id, null); + buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); } - var outputResult = compiler.Builder.Buffer.AddOpLoad(context.Bound++, outputStructId, outputParameter, null); - compiler.Builder.Buffer.AddOpReturnValue(outputResult); - compiler.Builder.Buffer.AddOpFunctionEnd(); - } + buffer.AddOpReturn(); + buffer.AddOpFunctionEnd(); - context.SetEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", []); + Span pvariables = stackalloc IdRef[inputStreams.Count + outputStreams.Count]; + for (int i = 0; i < inputStreams.Count; i++) + pvariables[i] = inputStreams[i].Id; + for (int i = 0; i < outputStreams.Count; i++) + pvariables[inputStreams.Count + i] = outputStreams[i].Id; + context.Buffer.AddOpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", pvariables); + } } /// /// Figure out (recursively) which streams are being read from and written to. /// - private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList streams) + private void ProcessMethod(SpirvBuffer buffer, int functionId, SortedList streams) { - var methodStart = FindMethodStart(compiler, functionId); - for (var index = methodStart; index < compiler.Builder.Buffer.Instructions.Count; index++) + var methodStart = FindMethodStart(buffer, functionId); + for (var index = methodStart; index < buffer.Instructions.Count; index++) { - var instruction = compiler.Builder.Buffer.Instructions[index]; + var instruction = buffer.Instructions[index]; if (instruction.OpCode == SDSLOp.OpFunctionEnd) break; @@ -272,17 +230,17 @@ private void ProcessMethod(CompilerUnit compiler, int functionId, SortedList -// /// Remove duplicate simple types. -// /// Should be applied before the IdRefOffsetter. -// /// -// public struct TypeDuplicateRemover : INanoPass -// { +/// +/// Remove duplicate simple types. +/// Should be applied before the IdRefOffsetter. +/// +public struct TypeDuplicateRemover : INanoPass +{ -// public readonly void Apply(SpirvBuffer buffer) -// { -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) -// { -// foreach (var j in buffer.Declarations.UnorderedInstructions) -// { -// if ( -// (j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words.Span); -// } -// } -// } -// } -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// if (i.OpCode == SDSLOp.OpTypeVector) -// { -// foreach (var j in buffer.Declarations.UnorderedInstructions) -// { -// if ( -// j.OpCode == SDSLOp.OpTypeVector -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words.Span); -// } -// } -// } -// } -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// if (i.OpCode == SDSLOp.OpTypeMatrix) -// { -// foreach (var j in buffer.Declarations.UnorderedInstructions) -// { -// if ( -// j.OpCode == SDSLOp.OpTypeMatrix -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands.Span[1..], j.Operands.Span[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words.Span); -// } -// } -// } -// } -// //var idx1 = 0; -// //// First base types -// //foreach (var i in buffer.Declarations.UnorderedInstructions) -// //{ -// // if (i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) -// // { -// // var idx2 = 0; -// // foreach (var j in buffer.Declarations) -// // { -// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) -// // { -// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// // SetOpNop(j.Words.Span); -// // } -// // idx2 += 1; -// // } -// // } -// // else if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeBool) -// // { -// // var idx2 = 0; -// // foreach (var j in buffer.Declarations) -// // { -// // if (j.OpCode == i.OpCode && idx1 != idx2) -// // { -// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// // SetOpNop(j.Words.Span); -// // } -// // idx2 += 1; -// // } -// // } -// // idx1 += 1; -// //} -// //idx1 = 0; -// //// Then vectors -// //foreach (var i in buffer.Declarations.UnorderedInstructions) -// //{ -// // if (i.OpCode == SDSLOp.OpTypeVector) -// // { -// // var idx2 = 0; -// // foreach (var j in buffer.Declarations) -// // { -// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) -// // { -// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// // SetOpNop(j.Words.Span); -// // } -// // idx2 += 1; -// // } -// // } -// // idx1 += 1; -// //} -// //idx1 = 0; + public readonly void Apply(SpirvBuffer buffer) + { + foreach (var i in buffer.Instructions) + { + if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) + { + foreach (var j in buffer.Instructions) + { + if ( + (j.OpCode == SDSLOp.OpTypeVoid || j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words); + } + } + } + } + foreach (var i in buffer.Instructions) + { + if (i.OpCode == SDSLOp.OpTypeVector) + { + foreach (var j in buffer.Instructions) + { + if ( + j.OpCode == SDSLOp.OpTypeVector + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words); + } + } + } + } + foreach (var i in buffer.Instructions) + { + if (i.OpCode == SDSLOp.OpTypeMatrix) + { + foreach (var j in buffer.Instructions) + { + if ( + j.OpCode == SDSLOp.OpTypeMatrix + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words); + } + } + } + } + } -// //// Then matrices -// //foreach (var i in buffer.Declarations.UnorderedInstructions) -// //{ -// // if (i.OpCode == SDSLOp.OpTypeMatrix) -// // { -// // var idx2 = 0; -// // foreach (var j in buffer.Declarations) -// // { -// // if (j.OpCode == i.OpCode && idx1 != idx2 && i.Operands.Span[1..].SequenceEqual(j.Operands.Span[1..])) -// // { -// // ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// // SetOpNop(j.Words.Span); -// // } -// // idx2 += 1; -// // } -// // } -// // idx1 += 1; -// //} + static void ReplaceRefs(int from, int to, SpirvBuffer buffer) + { + foreach (var i in buffer.Instructions) + { + var opcode = i.OpCode; + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + if (op.Words[0] == from || op.Words[1] == from) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + } -// } - -// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) -// { -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// var opcode = i.OpCode; -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// if (op.Words[0] == from || op.Words[1] == from) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// } -// foreach (var (_, f) in buffer.Functions) -// foreach (var i in f.UnorderedInstructions) -// { -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// if (op.Words[0] == from || op.Words[1] == from) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// } -// } - -// static void SetOpNop(Span words) -// { -// words[0] = words.Length << 16; -// words[1..].Clear(); -// } -// } + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } +} From 397d7ce12dbd2f8f4f7450d55336b1ffeeaf532f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Jun 2025 13:17:57 +0900 Subject: [PATCH 0428/1182] Remove unecessary SDSL opcodes --- .../Information/InstructionInfo.Order.cs | 2 - .../Extensions/spirv.sdsl.grammar-ext.json | 111 ------------------ 2 files changed, 113 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 270e34acb8..0464503874 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -56,7 +56,6 @@ void InitOrder() group++; OrderGroup[(SDSLOp.OpName, null)] = group; - OrderGroup[(SDSLOp.OpSDSLMixinVariable, null)] = group; OrderGroup[(SDSLOp.OpMemberName, null)] = group; group++; @@ -74,7 +73,6 @@ void InitOrder() foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) OrderGroup[(SDSLOp.OpVariable, e)] = group; - OrderGroup[(SDSLOp.OpSDSLIOVariable, null)] = group; OrderGroup[(SDSLOp.OpUndef, null)] = group; diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json index 70b9402402..38d12b30f6 100644 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json @@ -92,117 +92,6 @@ "name": "shader" } ] - }, - { - "opname": "OpSDSLMixinVariable", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdResult" - }, - { - "kind": "IdRef", - "name": "mixinId" - }, - { - "kind": "IdRef", - "name": "variableId" - } - ] - }, - { - "opname": "OpSDSLVariable", - "class": "Memory", - "operands": [ - { - "kind": "IdResultType" - }, - { - "kind": "IdResult" - }, - { - "kind": "StorageClass" - }, - { - "kind": "LiteralString", - "name": "name" - }, - { - "kind": "IdRef", - "quantifier": "?", - "name": "'Initializer'" - } - ] - }, - { - "opname": "OpSDSLFunctionParameter", - "class": "Function", - "operands": [ - { - "kind": "IdResultType" - }, - { - "kind": "IdResult" - }, - { - "kind": "LiteralString", - "name": "name" - } - ] - }, - { - "opname": "OpSDSLIOVariable", - "class": "Memory", - "operands": [ - { - "kind": "IdResultType" - }, - { - "kind": "IdResult" - }, - { - "kind": "StorageClass" - }, - { - "kind": "ExecutionModel" - }, - { - "kind": "LiteralString", - "name": "name" - }, - { - "kind": "LiteralString", - "name": "semantic" - }, - { - "kind": "IdRef", - "quantifier": "?", - "name": "'Initializer'" - } - ] - }, - { - "opname": "OpSDSLFunction", - "class": "Function", - "operands": [ - { - "kind": "IdResultType" - }, - { - "kind": "IdResult" - }, - { - "kind": "FunctionControl" - }, - { - "kind": "IdRef", - "name": "'Function Type'" - }, - { - "kind": "LiteralString", - "name": "functionName" - } - ] } ], "operand_kinds": [ From ae3c29279f40283252fa0ca74966173dace7f9b8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Jun 2025 15:45:55 +0900 Subject: [PATCH 0429/1182] Improved symbol registration --- .../Parsing/Analysis/SymbolTable.cs | 2 + .../Parsing/SDSL/AST/Expression.cs | 10 +++- .../Parsing/SDSL/AST/Literals.cs | 5 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 55 ++++++++++--------- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 585647ddaf..4916f11a6b 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -19,6 +19,8 @@ public partial class SymbolTable : ISymbolProvider public List CurrentSymbols { get; } = new(); + public ShaderSymbol? CurrentShader { get; set; } + public SymbolTable() { Push(RootSymbols); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 0dfb50c36f..df52a63f67 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -113,9 +113,15 @@ public override void ProcessSymbol(SymbolTable table) Type = streamVar.Type; if (Accessors.Count > 1) - { ProcessAccessors(1); - } + } + else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) + { + methodCall.ProcessSymbol(table); + Type = methodCall.Type; + + if (Accessors.Count > 1) + ProcessAccessors(1); } else { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 5c2aaf5ef1..670c45b571 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -232,11 +232,10 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return resultVar; else if(f.Parameters.TryGetValue(Name, out var paramVar)) return paramVar; - - if (context.Module.InheritedVariables.TryGetValue(Name, out var externalVar)) - return externalVar; } + if (context.Module.InheritedVariables.TryGetValue(Name, out var externalVar)) + return externalVar; if (compiler.Context.Variables.TryGetValue(Name, out var variable)) return variable; throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 77fbe6caac..9bee77b743 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -1,10 +1,11 @@ using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System.Runtime.InteropServices; -using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -124,14 +125,10 @@ public override void ProcessSymbol(SymbolTable table) { var shaderType = LoadShader(table.ShaderLoader, mixin); - var sid2 = new SymbolID(mixin.Name, SymbolKind.Shader); - table.RootSymbols.Add(mixin.Name, new(new SymbolID(mixin.Name, SymbolKind.Shader), shaderType)); - - // Register members - foreach (var symbol in shaderType.Components) - table.CurrentFrame.Add(symbol.Id.Name, symbol); + RegisterShaderType(table, shaderType); } + var symbols = new List(); foreach (var member in Elements) { if (member is ShaderMethod func) @@ -148,8 +145,10 @@ public override void ProcessSymbol(SymbolTable table) } func.Type = ftype; - table.RootSymbols.Add(func.Name, new(new(func.Name, SymbolKind.Method), func.Type)); table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); + + var symbol = new Symbol(new(func.Name, SymbolKind.Method), func.Type); + symbols.Add(symbol); } else if (member is ShaderMember svar) { @@ -166,36 +165,37 @@ public override void ProcessSymbol(SymbolTable table) _ => Storage.None } ); - var symbol = new Symbol(sid, svar.Type); - //if (sid.Storage == Storage.Stream) - //{ - // table.Streams.Add(sid, symbol); - //} - //else - { - table.RootSymbols.Add(sid.Name, symbol); - } + table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + + var symbol = new Symbol(sid, svar.Type); + symbols.Add(symbol); } } - /*var streams = - new SymbolID - ( - "streams", - SymbolKind.Variable, - Storage.None - ); - table.RootSymbols.Add(streams, new(streams, new StreamsSymbol()));*/ + var currentShader = new ShaderSymbol(Name, symbols); + RegisterShaderType(table, currentShader); + table.CurrentShader = currentShader; foreach (var member in Elements) { if (member is not ShaderMember) member.ProcessSymbol(table); } + table.CurrentShader = null; table.Pop(); } + private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) + { + var sid = new SymbolID(shaderType.Name, SymbolKind.Shader); + table.RootSymbols.Add(shaderType.Name, new(sid, shaderType)); + + // Register members + foreach (var symbol in shaderType.Components) + table.CurrentFrame.Add(symbol.Id.Name, symbol); + } + public void Compile(CompilerUnit compiler, SymbolTable table) { @@ -232,10 +232,15 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.Module.InheritedMixins.Add(shaderType); } + var currentShader = (ShaderSymbol)table.RootSymbols[Name].Type; + table.CurrentShader = currentShader; + foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach(var method in Elements.OfType()) method.Compile(table, this, compiler); + + table.CurrentShader = null; } From ab2a23fdb8192959d4b14a95dee1b6f76c597085 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Jun 2025 16:34:40 +0900 Subject: [PATCH 0430/1182] Unifying ProcessSymbol and Compile (first step) --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 6 +-- src/Stride.Shaders.Experiments/Examples.cs | 7 --- src/Stride.Shaders/Parsing/ASTNode.cs | 17 +------ .../Parsing/SDSL/AST/Expression.cs | 32 +++++++------- .../Parsing/SDSL/AST/Literals.cs | 18 ++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 44 ++++++++----------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 27 ++++-------- .../Parsing/SDSL/AST/ShaderElements.cs | 8 +++- .../Parsing/SDSL/AST/Statements.Control.cs | 24 +++++----- .../Parsing/SDSL/AST/Statements.Flow.cs | 18 ++++---- .../Parsing/SDSL/AST/Statements.cs | 34 +++++++------- .../Spirv/Building/Builder.Expressions.cs | 10 ++++- 12 files changed, 108 insertions(+), 137 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 2781a49a03..c494ba8591 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -21,13 +21,13 @@ public readonly bool Compile(string code, out byte[] compiled) SymbolTable table = new(); var shader = sf.Namespaces.First().Declarations.OfType().First(); table.ShaderLoader = ShaderLoader; - shader.ProcessSymbol(table); - if(table.Errors.Count > 0) - throw new Exception("Some parse errors"); var compiler = new CompilerUnit(); shader.Compile(compiler, table); + if (table.Errors.Count > 0) + throw new Exception("Some parse errors"); + // temp hack to add entry point (last function) //var context = compiler.Context; //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 5f89cf5a90..d3c9e22820 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -126,13 +126,6 @@ public static void ParseSDSL() foreach (var e in parsed.Errors) Console.WriteLine(e); } - else - { - var table = new SymbolTable(); - parsed.AST?.ProcessSymbol(table); - foreach (var e in table.Errors) - Console.WriteLine(e); - } } public static void TryAllFiles() diff --git a/src/Stride.Shaders/Parsing/ASTNode.cs b/src/Stride.Shaders/Parsing/ASTNode.cs index f23600e3e1..c809c8f961 100644 --- a/src/Stride.Shaders/Parsing/ASTNode.cs +++ b/src/Stride.Shaders/Parsing/ASTNode.cs @@ -11,7 +11,6 @@ namespace Stride.Shaders.Parsing; public abstract class Node(TextLocation info) { public TextLocation Info { get; set; } = info; - public virtual void ProcessSymbol(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); } /// @@ -20,6 +19,8 @@ public abstract class Node(TextLocation info) public class ValueNode(TextLocation info) : Node(info) { public virtual SymbolType? Type { get; set; } = null; + + public virtual void ProcessType(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); } /// @@ -42,14 +43,6 @@ public class ShaderFile(TextLocation info) : Node(info) public List RootDeclarations { get; set; } = []; public List Namespaces { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) - { - foreach (var e in RootDeclarations) - e.ProcessSymbol(table); - foreach (var ns in Namespaces) - ns.ProcessSymbol(table); - } - public override string ToString() { return $"{string.Join("\n", RootDeclarations)}\n\n{string.Join("\n", Namespaces)}"; @@ -73,12 +66,6 @@ public class ShaderNamespace(TextLocation info) : Node(info) public Identifier? Namespace { get; set; } public List Declarations { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) - { - foreach(var d in Declarations) - d.ProcessSymbol(table); - } - public override string ToString() { return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", Declarations)}End\n"; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index df52a63f67..a46f790a77 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -22,10 +22,10 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public Identifier Name = name; public ShaderExpressionList Parameters = parameters; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { - foreach (var p in parameters.Values) - p.ProcessSymbol(table); + Name.ProcessType(table); + Type = ((FunctionType)Name.Type).ReturnType; } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -104,12 +104,12 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { //table.CurrentSymbols.Add(table.Streams); - streamVar.ProcessSymbol(table); + streamVar.ProcessType(table); Type = streamVar.Type; if (Accessors.Count > 1) @@ -117,7 +117,7 @@ public override void ProcessSymbol(SymbolTable table) } else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) { - methodCall.ProcessSymbol(table); + methodCall.ProcessType(table); Type = methodCall.Type; if (Accessors.Count > 1) @@ -125,7 +125,7 @@ public override void ProcessSymbol(SymbolTable table) } else { - Source.ProcessSymbol(table); + Source.ProcessType(table); Type = Source.Type; ProcessAccessors(0); } @@ -145,7 +145,7 @@ void ProcessAccessors(int firstIndex) else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); if(accessor is not Identifier) - accessor.ProcessSymbol(table); + accessor.ProcessType(table); } } } @@ -178,7 +178,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.ProcessSymbol(table); + indexLiteral.ProcessType(table); indexes[i] = context.CreateConstant(indexLiteral).Id; } else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); @@ -215,10 +215,10 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { - Left.ProcessSymbol(table); - Right.ProcessSymbol(table); + Left.ProcessType(table); + Right.ProcessType(table); if ( OperatorTable.BinaryOperationResultingType( Left.Type ?? throw new NotImplementedException("Missing type"), @@ -252,11 +252,11 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { - Condition.ProcessSymbol(table); - Left.ProcessSymbol(table); - Right.ProcessSymbol(table); + Condition.ProcessType(table); + Left.ProcessType(table); + Right.ProcessType(table); if (Condition.Type is not ScalarType { TypeName: "bool" }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); if (Left.Type != Right.Type) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 670c45b571..3765d62443 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -54,7 +54,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { Type = Suffix switch { @@ -86,7 +86,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { Type = Suffix.Size switch { @@ -110,7 +110,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(32, false, false), (long)value, info) { - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) => Type = ScalarType.From("long"); } @@ -118,7 +118,7 @@ public override void ProcessSymbol(SymbolTable table) public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) => Type = ScalarType.From("bool"); public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -158,14 +158,14 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { - TypeName.ProcessSymbol(table); + TypeName.ProcessType(table); Type = TypeName.Type; var tmp = (Core.VectorType)Type! ?? throw new NotImplementedException(); foreach (var v in Values) { - v.ProcessSymbol(table); + v.ProcessType(table); if ( v.Type is ScalarType st && tmp.BaseType != st || (v.Type is Core.VectorType vt && vt.BaseType != tmp.BaseType) @@ -205,7 +205,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) { @@ -288,7 +288,7 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public List? ArraySize { get; set; } public List Generics { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessType(SymbolTable table) { if (!IsArray && Generics.Count == 0) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 9bee77b743..4ba4e1af21 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -118,7 +118,18 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade return shaderType; } - public override void ProcessSymbol(SymbolTable table) + private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) + { + var sid = new SymbolID(shaderType.Name, SymbolKind.Shader); + table.RootSymbols.Add(shaderType.Name, new(sid, shaderType)); + + // Register members + foreach (var symbol in shaderType.Components) + table.CurrentFrame.Add(symbol.Id.Name, symbol); + } + + + public void Compile(CompilerUnit compiler, SymbolTable table) { table.Push(); foreach (var mixin in Mixins) @@ -133,11 +144,11 @@ public override void ProcessSymbol(SymbolTable table) { if (member is ShaderMethod func) { - func.ReturnTypeName.ProcessSymbol(table); + func.ReturnTypeName.ProcessType(table); var ftype = new FunctionType(func.ReturnTypeName.Type, []); foreach (var arg in func.Parameters) { - arg.TypeName.ProcessSymbol(table); + arg.TypeName.ProcessType(table); var argSym = arg.TypeName.Type; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = argSym; @@ -152,9 +163,9 @@ public override void ProcessSymbol(SymbolTable table) } else if (member is ShaderMember svar) { - svar.TypeName.ProcessSymbol(table); + svar.TypeName.ProcessType(table); svar.Type = svar.TypeName.Type; - var sid = + var sid = new SymbolID ( svar.Name, @@ -179,26 +190,9 @@ public override void ProcessSymbol(SymbolTable table) table.CurrentShader = currentShader; foreach (var member in Elements) { - if (member is not ShaderMember) - member.ProcessSymbol(table); + member.ProcessSymbol(table); } - table.CurrentShader = null; - table.Pop(); - } - private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) - { - var sid = new SymbolID(shaderType.Name, SymbolKind.Shader); - table.RootSymbols.Add(shaderType.Name, new(sid, shaderType)); - - // Register members - foreach (var symbol in shaderType.Components) - table.CurrentFrame.Add(symbol.Id.Name, symbol); - } - - - public void Compile(CompilerUnit compiler, SymbolTable table) - { var (builder, context, _) = compiler; context.PutShaderName(Name); @@ -232,15 +226,13 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.Module.InheritedMixins.Add(shaderType); } - var currentShader = (ShaderSymbol)table.RootSymbols[Name].Type; - table.CurrentShader = currentShader; - foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach(var method in Elements.OfType()) method.Compile(table, this, compiler); table.CurrentShader = null; + table.Pop(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 0ad0836345..ac4ab8da5a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -158,33 +158,18 @@ public class ShaderMethod( public BlockStatement? Body { get; set; } - public override void ProcessSymbol(SymbolTable table) + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { table.Push(); foreach (var arg in Parameters) { - arg.TypeName.ProcessSymbol(table); + arg.TypeName.ProcessType(table); var argSym = arg.TypeName.Type; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); table.CurrentFrame.Add(arg.Name, new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); arg.Type = argSym; - - } - if (Body is not null) - { - table.Push(); - foreach (var s in Body.Statements) - if (EntryPoint == 0) - s.ProcessSymbol(table); - else - s.ProcessSymbol(table, this); - table.Pop(); } - table.Pop(); - } - - public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { + var (builder, context, _) = compiler; if (Type is FunctionType ftype) { @@ -193,13 +178,19 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler builder.AddFunctionParameter(context, p.Name, p.Type); if(Body is BlockStatement body) { + table.Push(); builder.CreateBlock(context); + foreach (var s in Body.Statements) + s.ProcessType(table); foreach (var s in body) s.Compile(table, shader, compiler); + table.Pop(); } builder.EndFunction(context); } else throw new NotImplementedException(); + + table.Pop(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 7f62768b35..80bbc9b302 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -8,6 +8,10 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderElement(TextLocation info) : Node(info) { public SymbolType? Type { get; set; } + + public virtual void ProcessSymbol(SymbolTable table) + { + } } @@ -143,7 +147,7 @@ public override void ProcessSymbol(SymbolTable table) table.RootSymbols.Add(Name.ToString() ?? "", sym); foreach (var cbmem in Members) { - cbmem.TypeName.ProcessSymbol(table); + cbmem.TypeName.ProcessType(table); cbmem.Type = cbmem.Type; table.DeclaredTypes.TryAdd(cbmem.Type.ToString(), cbmem.Type); } @@ -175,7 +179,7 @@ public override void ProcessSymbol(SymbolTable table) var fields = new List<(string Name, SymbolType Type)>(); foreach (var smem in Members) { - smem.TypeName.ProcessSymbol(table); + smem.TypeName.ProcessType(table); smem.Type = smem.TypeName.Type; table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 1a5968dfec..3c388a67eb 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -16,12 +16,12 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - If.ProcessSymbol(table, method); + If.ProcessType(table); foreach (var ei in ElseIfs) - ei.ProcessSymbol(table, method); - Else?.ProcessSymbol(table, method); + ei.ProcessType(table); + Else?.ProcessType(table); } @@ -40,10 +40,10 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Condition.ProcessSymbol(table); - Body.ProcessSymbol(table, method); + Condition.ProcessType(table); + Body.ProcessType(table); if(Condition.Type != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); } @@ -60,10 +60,10 @@ public override string ToString() public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Condition.ProcessSymbol(table); - Body.ProcessSymbol(table, method); + Condition.ProcessType(table); + Body.ProcessType(table); if(Condition.Type != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); } @@ -81,9 +81,9 @@ public class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Body.ProcessSymbol(table, method); + Body.ProcessType(table); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 23c9e1df67..801b376f0c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -9,7 +9,7 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } + public override void ProcessType(SymbolTable table) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -18,7 +18,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Discard(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } + public override void ProcessType(SymbolTable table) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -27,7 +27,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Continue(TextLocation info) : Statement(info) { - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) { } + public override void ProcessType(SymbolTable table) { } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -43,13 +43,13 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public Expression Collection { get; set; } = collection; public Statement Body { get; set; } = body; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Collection.ProcessSymbol(table); + Collection.ProcessType(table); if(Collection.Type is ArrayType arrSym) { var btype = arrSym.BaseType; - TypeName.ProcessSymbol(table); + TypeName.ProcessType(table); } } @@ -71,10 +71,10 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public Statement Body { get; set; } = body; public ShaderAttribute? Attribute { get; internal set; } = attribute; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Condition.ProcessSymbol(table); - Body.ProcessSymbol(table); + Condition.ProcessType(table); + Body.ProcessType(table); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index fc3e1d297f..b8e292aebf 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -10,8 +10,6 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Statement(TextLocation info) : ValueNode(info) { - public override void ProcessSymbol(SymbolTable table) => ProcessSymbol(table, null!); - public virtual void ProcessSymbol(SymbolTable table, ShaderMethod method) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); public abstract void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); } @@ -27,9 +25,9 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Expression.ProcessSymbol(table); + Expression.ProcessType(table); Type = ScalarType.From("void"); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -47,9 +45,9 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - Value?.ProcessSymbol(table); + Value?.ProcessType(table); Type = Value?.Type ?? ScalarType.From("void"); } @@ -100,11 +98,11 @@ public List? ArraySizes set => TypeName.ArraySize = value; } - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { - TypeName.ProcessSymbol(table); + TypeName.ProcessType(table); Variable.Type = TypeName.Type; - Value?.ProcessSymbol(table); + Value?.ProcessType(table); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); } @@ -132,13 +130,13 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { if (TypeName == "var") { if (Variables.Count == 1 && Variables[0].Value is not null) { - Variables[0].Value?.ProcessSymbol(table); + Variables[0].Value?.ProcessType(table); Type = Variables[0].Value!.Type; } else @@ -146,12 +144,12 @@ public override void ProcessSymbol(SymbolTable table, ShaderMethod method) } else { - TypeName.ProcessSymbol(table); + TypeName.ProcessType(table); Type = TypeName.Type; table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); foreach (var d in Variables) { - d.Value?.ProcessSymbol(table); + d.Value?.ProcessType(table); table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type)); } } @@ -180,12 +178,12 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { foreach (var variable in Variables) { - variable.Variable.ProcessSymbol(table); - variable.Value!.ProcessSymbol(table); + variable.Variable.ProcessType(table); + variable.Value!.ProcessType(table); if (variable.Variable.Type is not PointerType) throw new InvalidOperationException("can only assign to pointer type"); @@ -221,10 +219,10 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void ProcessSymbol(SymbolTable table, ShaderMethod method) + public override void ProcessType(SymbolTable table) { foreach (var s in Statements) - s.ProcessSymbol(table, method); + s.ProcessType(table); } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index e55b0fbf9e..64121f0a28 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -109,13 +109,19 @@ public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - if (!context.Module.Functions.TryGetValue(name, out var func)) - context.Module.InheritedFunctions.TryGetValue(name, out func); + var func = FindFunction(context, name); var fcall = Buffer.InsertOpFunctionCall(Position++, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); return new(fcall, func.Name); } + private static SpirvFunction FindFunction(SpirvContext context, string name) + { + if (!context.Module.Functions.TryGetValue(name, out var func)) + context.Module.InheritedFunctions.TryGetValue(name, out func); + return func; + } + public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { var instruction = Buffer.InsertOpCompositeConstruct(Position++, context.Bound++, context.GetOrRegister(literal.Type), values); From 2e789c8c538b009ba5eba47a86a5cf14d9d80ba4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Jun 2025 11:47:47 +0900 Subject: [PATCH 0431/1182] Removed ProcessType --- src/Stride.Shaders/Core/SymbolTypes.cs | 4 +- src/Stride.Shaders/Parsing/ASTNode.cs | 2 - .../Parsing/SDSL/AST/Expression.cs | 90 +++++-------------- .../Parsing/SDSL/AST/Literals.cs | 60 +++++++------ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 9 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 +- .../Parsing/SDSL/AST/ShaderElements.cs | 6 +- .../Parsing/SDSL/AST/Statements.Control.cs | 41 +++------ .../Parsing/SDSL/AST/Statements.Flow.cs | 27 ++---- .../Parsing/SDSL/AST/Statements.cs | 61 ++++--------- 10 files changed, 102 insertions(+), 203 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index cd5ccd7993..1bf5c8a0ae 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -13,7 +13,7 @@ public abstract record SymbolType() /// public virtual string ToId() => ToString(); - public static bool TryGetNumeric(string name, out SymbolType? result) + public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolType result) { if(ScalarType.Types.TryGetValue(name, out var s)) { @@ -38,7 +38,7 @@ public static bool TryGetNumeric(string name, out SymbolType? result) else { result = null; - return true; + return false; } } } diff --git a/src/Stride.Shaders/Parsing/ASTNode.cs b/src/Stride.Shaders/Parsing/ASTNode.cs index c809c8f961..257c7ea631 100644 --- a/src/Stride.Shaders/Parsing/ASTNode.cs +++ b/src/Stride.Shaders/Parsing/ASTNode.cs @@ -19,8 +19,6 @@ public abstract class Node(TextLocation info) public class ValueNode(TextLocation info) : Node(info) { public virtual SymbolType? Type { get; set; } = null; - - public virtual void ProcessType(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); } /// diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index a46f790a77..bca5c38ec9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -22,14 +22,11 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public Identifier Name = name; public ShaderExpressionList Parameters = parameters; - public override void ProcessType(SymbolTable table) - { - Name.ProcessType(table); - Type = ((FunctionType)Name.Type).ReturnType; - } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + var functionType = (FunctionType)Name.ResolveType(table); + Type = functionType.ReturnType; + var (builder, context, module) = compiler; var list = parameters.Values; Span compiledParams = stackalloc IdRef[list.Count]; @@ -104,51 +101,6 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override void ProcessType(SymbolTable table) - { - if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) - { - //table.CurrentSymbols.Add(table.Streams); - streamVar.ProcessType(table); - Type = streamVar.Type; - - if (Accessors.Count > 1) - ProcessAccessors(1); - } - else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) - { - methodCall.ProcessType(table); - Type = methodCall.Type; - - if (Accessors.Count > 1) - ProcessAccessors(1); - } - else - { - Source.ProcessType(table); - Type = Source.Type; - ProcessAccessors(0); - } - - // AccessorChain always end up with a pointer type - Type = new PointerType(Type); - - void ProcessAccessors(int firstIndex) - { - foreach (var accessor in Accessors[firstIndex..]) - { - if (Type is not null && Type.TryAccess(accessor, out var type)) - { - Type = type; - accessor.Type = type; - } - else throw new NotImplementedException($"Cannot access {accessor.GetType().Name} from {Type}"); - - if(accessor is not Identifier) - accessor.ProcessType(table); - } - } - } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, _) = compiler; @@ -156,17 +108,25 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var variable = context.Bound++; int firstIndex = 0; + SymbolType currentValueType; if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { source = streamVar.Compile(table, shader, compiler); + currentValueType = streamVar.Type; + firstIndex = 1; + } + else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) + { + source = methodCall.Compile(table, shader, compiler); + currentValueType = methodCall.Type; firstIndex = 1; } else { source = Source.Compile(table, shader, compiler); + currentValueType = Source.Type; } - var currentValueType = Source.Type; Span indexes = stackalloc IdRef[Accessors.Count]; for (var i = firstIndex; i < Accessors.Count; i++) { @@ -178,7 +138,6 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.ProcessType(table); indexes[i] = context.CreateConstant(indexLiteral).Id; } else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); @@ -186,6 +145,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = accessor.Type; } + Type = new PointerType(currentValueType); + // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) if (firstIndex == Accessors.Count) return source; @@ -215,10 +176,10 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override void ProcessType(SymbolTable table) + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Left.ProcessType(table); - Right.ProcessType(table); + var left = Left.Compile(table, shader, compiler); + var right = Right.Compile(table, shader, compiler); if ( OperatorTable.BinaryOperationResultingType( Left.Type ?? throw new NotImplementedException("Missing type"), @@ -230,12 +191,7 @@ out var t Type = t; else table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); - } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var left = Left.Compile(table, shader, compiler); - var right = Right.Compile(table, shader, compiler); var (builder, context, _) = compiler; return builder.BinaryOperation(context, context.GetOrRegister(Type), left, Op, right); } @@ -252,19 +208,15 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override void ProcessType(SymbolTable table) + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.ProcessType(table); - Left.ProcessType(table); - Right.ProcessType(table); + Condition.Compile(table, shader, compiler); + Left.Compile(table, shader, compiler); + Right.Compile(table, shader, compiler); if (Condition.Type is not ScalarType { TypeName: "bool" }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); if (Left.Type != Right.Type) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - } - - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 3765d62443..08ccb637ba 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -54,7 +54,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override void ProcessType(SymbolTable table) + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { Type = Suffix switch { @@ -68,9 +68,7 @@ public override void ProcessType(SymbolTable table) { Signed: false, Size: 64 } => ScalarType.From("ulong"), _ => throw new NotImplementedException("Unsupported integer suffix") }; - } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { + var i = (Type, Suffix) switch { (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), LongValue), @@ -86,7 +84,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override void ProcessType(SymbolTable table) + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { Type = Suffix.Size switch { @@ -95,9 +93,6 @@ public override void ProcessType(SymbolTable table) 64 => ScalarType.From("double"), _ => throw new NotImplementedException("Unsupported float") }; - } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { var i = (Type, Suffix) switch { (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), DoubleValue), @@ -110,16 +105,14 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(32, false, false), (long)value, info) { - public override void ProcessType(SymbolTable table) - => Type = ScalarType.From("long"); + public override SymbolType? Type => ScalarType.From("long"); } public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; - public override void ProcessType(SymbolTable table) - => Type = ScalarType.From("bool"); + public override SymbolType? Type => ScalarType.From("bool"); public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -144,6 +137,8 @@ public bool IsConstant() return true; } + public abstract SymbolType GenerateType(SymbolTable table); + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, module) = compiler; @@ -151,6 +146,9 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil int tmp = 0; foreach (var v in Values) values[tmp++] = v.Compile(table, shader, compiler).Id; + + Type = GenerateType(table); + return builder.CompositeConstruct(context, this, values); } } @@ -158,14 +156,13 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override void ProcessType(SymbolTable table) + public override SymbolType GenerateType(SymbolTable table) { - TypeName.ProcessType(table); - Type = TypeName.Type; - var tmp = (Core.VectorType)Type! ?? throw new NotImplementedException(); + var result = TypeName.ResolveType(table); + + var tmp = (Core.VectorType)result ?? throw new NotImplementedException(); foreach (var v in Values) { - v.ProcessType(table); if ( v.Type is ScalarType st && tmp.BaseType != st || (v.Type is Core.VectorType vt && vt.BaseType != tmp.BaseType) @@ -173,7 +170,10 @@ public override void ProcessType(SymbolTable table) ) table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); } + + return result; } + public override string ToString() { return $"{TypeName}({string.Join(", ", Values.Select(x => x.ToString()))})"; @@ -187,6 +187,11 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; + public override SymbolType GenerateType(SymbolTable table) + { + throw new NotImplementedException(); + } + public override string ToString() { return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; @@ -195,6 +200,11 @@ public override string ToString() public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { + public override SymbolType GenerateType(SymbolTable table) + { + throw new NotImplementedException(); + } + public override string ToString() => $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; } @@ -205,7 +215,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override void ProcessType(SymbolTable table) + public SymbolType ResolveType(SymbolTable table) { for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) { @@ -213,10 +223,9 @@ public override void ProcessType(SymbolTable table) .TryGetValue(Name, out var symbol)) { if (symbol.Type is not UndefinedType and not null) - Type = symbol.Type; + return symbol.Type; else - Type = symbol.Type ?? new UndefinedType(Name); - return; + return symbol.Type ?? new UndefinedType(Name); } } @@ -225,6 +234,7 @@ public override void ProcessType(SymbolTable table) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + Type = ResolveType(table); var (builder, context, _) = compiler; if(builder.CurrentFunction is SpirvFunction f) { @@ -288,16 +298,16 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public List? ArraySize { get; set; } public List Generics { get; set; } = []; - public override void ProcessType(SymbolTable table) + public SymbolType ResolveType(SymbolTable table) { if (!IsArray && Generics.Count == 0) { if (table.DeclaredTypes.TryGetValue(Name, out var type)) - Type = type; + return type; else if (SymbolType.TryGetNumeric(Name, out var numeric)) { - Type = numeric; - table.DeclaredTypes.Add(Type!.ToString(), Type); + table.DeclaredTypes.Add(numeric.ToString(), numeric); + return numeric; } else throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4ba4e1af21..a93c3ed86e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -144,12 +144,10 @@ public void Compile(CompilerUnit compiler, SymbolTable table) { if (member is ShaderMethod func) { - func.ReturnTypeName.ProcessType(table); - var ftype = new FunctionType(func.ReturnTypeName.Type, []); + var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); foreach (var arg in func.Parameters) { - arg.TypeName.ProcessType(table); - var argSym = arg.TypeName.Type; + var argSym = arg.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = argSym; ftype.ParameterTypes.Add(arg.Type); @@ -163,8 +161,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } else if (member is ShaderMember svar) { - svar.TypeName.ProcessType(table); - svar.Type = svar.TypeName.Type; + svar.Type = svar.TypeName.ResolveType(table); var sid = new SymbolID ( diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index ac4ab8da5a..b5f6363ada 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -163,8 +163,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.Push(); foreach (var arg in Parameters) { - arg.TypeName.ProcessType(table); - var argSym = arg.TypeName.Type; + var argSym = arg.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); table.CurrentFrame.Add(arg.Name, new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); arg.Type = argSym; @@ -180,8 +179,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { table.Push(); builder.CreateBlock(context); - foreach (var s in Body.Statements) - s.ProcessType(table); foreach (var s in body) s.Compile(table, shader, compiler); table.Pop(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 80bbc9b302..fa70b185dc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -147,8 +147,7 @@ public override void ProcessSymbol(SymbolTable table) table.RootSymbols.Add(Name.ToString() ?? "", sym); foreach (var cbmem in Members) { - cbmem.TypeName.ProcessType(table); - cbmem.Type = cbmem.Type; + cbmem.Type = cbmem.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(cbmem.Type.ToString(), cbmem.Type); } } @@ -179,8 +178,7 @@ public override void ProcessSymbol(SymbolTable table) var fields = new List<(string Name, SymbolType Type)>(); foreach (var smem in Members) { - smem.TypeName.ProcessType(table); - smem.Type = smem.TypeName.Type; + smem.Type = smem.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add((smem.Name, smem.Type)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 3c388a67eb..f7254204c0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -16,17 +16,12 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - public override void ProcessType(SymbolTable table) - { - If.ProcessType(table); - foreach (var ei in ElseIfs) - ei.ProcessType(table); - Else?.ProcessType(table); - - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + If.Compile(table, shader, compiler); + foreach (var ei in ElseIfs) + ei.Compile(table, shader, compiler); + Else?.Compile(table, shader, compiler); throw new NotImplementedException(); } @@ -40,15 +35,12 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; - public override void ProcessType(SymbolTable table) - { - Condition.ProcessType(table); - Body.ProcessType(table); - if(Condition.Type != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); - } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + Condition.Compile(table, shader, compiler); + Body.Compile(table, shader, compiler); + if (Condition.Type != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } @@ -60,15 +52,12 @@ public override string ToString() public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { - public override void ProcessType(SymbolTable table) - { - Condition.ProcessType(table); - Body.ProcessType(table); - if(Condition.Type != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); - } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + Condition.Compile(table, shader, compiler); + Body.Compile(table, shader, compiler); + if (Condition.Type != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } public override string ToString() @@ -81,13 +70,9 @@ public class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; - public override void ProcessType(SymbolTable table) - { - Body.ProcessType(table); - } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + Body.Compile(table, shader, compiler); } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 801b376f0c..224c10b8ca 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -9,8 +9,6 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info) { - public override void ProcessType(SymbolTable table) { } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); @@ -18,8 +16,6 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Discard(TextLocation info) : Statement(info) { - public override void ProcessType(SymbolTable table) { } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); @@ -27,8 +23,6 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Continue(TextLocation info) : Statement(info) { - public override void ProcessType(SymbolTable table) { } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); @@ -43,18 +37,15 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public Expression Collection { get; set; } = collection; public Statement Body { get; set; } = body; - public override void ProcessType(SymbolTable table) + + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Collection.ProcessType(table); - if(Collection.Type is ArrayType arrSym) + Collection.Compile(table, shader, compiler); + if (Collection.Type is ArrayType arrSym) { var btype = arrSym.BaseType; - TypeName.ProcessType(table); + TypeName.Compile(table, shader, compiler); } - } - - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { throw new NotImplementedException(); } @@ -71,14 +62,10 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public Statement Body { get; set; } = body; public ShaderAttribute? Attribute { get; internal set; } = attribute; - public override void ProcessType(SymbolTable table) - { - Condition.ProcessType(table); - Body.ProcessType(table); - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + Condition.Compile(table, shader, compiler); + Body.Compile(table, shader, compiler); throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index b8e292aebf..893fd03d9c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -25,14 +25,10 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; - public override void ProcessType(SymbolTable table) - { - Expression.ProcessType(table); - Type = ScalarType.From("void"); - } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { Expression.Compile(table, shader, compiler); + Type = ScalarType.From("void"); } public override string ToString() { @@ -45,16 +41,11 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; - public override void ProcessType(SymbolTable table) - { - Value?.ProcessType(table); - Type = Value?.Type ?? ScalarType.From("void"); - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, _, _) = compiler; builder.Return(Value?.Compile(table, shader, compiler)); + Type = Value?.Type ?? ScalarType.From("void"); } public override string ToString() { @@ -98,17 +89,13 @@ public List? ArraySizes set => TypeName.ArraySize = value; } - public override void ProcessType(SymbolTable table) + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - TypeName.ProcessType(table); - Variable.Type = TypeName.Type; - Value?.ProcessType(table); + Variable.Type = TypeName.ResolveType(table); + var initialValue = Value?.Compile(table, shader, compiler); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { throw new NotImplementedException(); } @@ -130,13 +117,20 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void ProcessType(SymbolTable table) + public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + var compiledValues = new SpirvValue[Variables.Count]; + for (var index = 0; index < Variables.Count; index++) + { + if (Variables[index].Value != null) + compiledValues[index] = Variables[index].Value!.Compile(table, shader, compiler); + } + + // Compute type if (TypeName == "var") { if (Variables.Count == 1 && Variables[0].Value is not null) { - Variables[0].Value?.ProcessType(table); Type = Variables[0].Value!.Type; } else @@ -144,18 +138,14 @@ public override void ProcessType(SymbolTable table) } else { - TypeName.ProcessType(table); - Type = TypeName.Type; + Type = TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); foreach (var d in Variables) { - d.Value?.ProcessType(table); table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type)); } } - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { + var (builder, context, _) = compiler; var registeredType = context.GetOrRegister(new PointerType(Type!)); foreach (var d in Variables) @@ -178,17 +168,6 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; - public override void ProcessType(SymbolTable table) - { - foreach (var variable in Variables) - { - variable.Variable.ProcessType(table); - variable.Value!.ProcessType(table); - - if (variable.Variable.Type is not PointerType) - throw new InvalidOperationException("can only assign to pointer type"); - } - } public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, _) = compiler; @@ -196,6 +175,8 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { var target = variable.Variable.Compile(table, shader, compiler); var source = variable.Value!.Compile(table, shader, compiler); + if (variable.Variable.Type is not PointerType) + throw new InvalidOperationException("can only assign to pointer type"); if (variable.Value!.Type is PointerType p) { var sourceLoad = context.Bound++; @@ -219,12 +200,6 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void ProcessType(SymbolTable table) - { - foreach (var s in Statements) - s.ProcessType(table); - } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context, _) = compiler; From 778b4393059fb453bbff254150f93e9f6466b9cf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Jun 2025 18:24:23 +0900 Subject: [PATCH 0432/1182] Add a new symbol table context for each block --- src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 893fd03d9c..9ed161bf01 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -202,11 +202,12 @@ public class BlockStatement(TextLocation info) : Statement(info) public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + table.Push(); var (builder, context, _) = compiler; builder.CreateBlock(context); foreach (var s in Statements) s.Compile(table, shader, compiler); - + table.Pop(); } public List.Enumerator GetEnumerator() => Statements.GetEnumerator(); From ddd599e2cb199f38f452a16c8402ca8d474670b9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Jun 2025 17:18:11 +0900 Subject: [PATCH 0433/1182] Added cbuffer type --- src/Stride.Shaders/Core/SymbolTypes.cs | 18 ++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 11 +++++ .../Parsing/SDSL/AST/ShaderElements.cs | 46 ++++++++++++++----- .../ShaderParsers/ShaderBufferParsers.Cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 18 ++++---- 5 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 1bf5c8a0ae..36b043630b 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -73,14 +73,14 @@ public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"{BaseType}[{Size}]"; } -public sealed record StructType(string Name, List<(string Name, SymbolType Type)> Fields) : SymbolType() +public record StructuredType(string Name, List<(string Name, SymbolType Type)> Members) : SymbolType() { public override string ToId() => Name; - public override string ToString() => $"{Name}{{{string.Join(", ", Fields.Select(x => $"{x.Type} {x.Name}"))}}}"; + public override string ToString() => $"{Name}{{{string.Join(", ", Members.Select(x => $"{x.Type} {x.Name}"))}}}"; public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType type) { - foreach (var field in Fields) + foreach (var field in Members) { if (field.Name == name) { @@ -94,9 +94,9 @@ public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType t } public int TryGetFieldIndex(string name) { - for (var index = 0; index < Fields.Count; index++) + for (var index = 0; index < Members.Count; index++) { - var field = Fields[index]; + var field = Members[index]; if (field.Name == name) return index; } @@ -105,6 +105,8 @@ public int TryGetFieldIndex(string name) } } + +public sealed record StructType(string Name, List<(string Name, SymbolType Type)> Members) : StructuredType(Name, Members); public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"Buffer<{BaseType}, {Size}>"; @@ -181,9 +183,9 @@ public override string ToString() public sealed record StreamsSymbol : SymbolType; -public sealed record ConstantBufferSymbol(string Name, List Symbols) : SymbolType; -public sealed record ParamsSymbol(string Name, List Symbols) : SymbolType; -public sealed record EffectSymbol(string Name, List Symbols) : SymbolType; +public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type)> Members) : StructuredType(Name, Members); +public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; +public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record ShaderSymbol(string Name, List Components) : SymbolType { public Symbol Get(string name, SymbolKind kind) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a93c3ed86e..0d05e57dd4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -179,6 +179,15 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var symbol = new Symbol(sid, svar.Type); symbols.Add(symbol); } + else if (member is CBuffer cb) + { + foreach (var cbMember in cb.Members) + { + cbMember.Type = cbMember.TypeName.ResolveType(table); + var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); + symbols.Add(symbol); + } + } } var currentShader = new ShaderSymbol(Name, symbols); @@ -223,6 +232,8 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.Module.InheritedMixins.Add(shaderType); } + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach(var method in Elements.OfType()) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index fa70b185dc..9c08baa422 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -1,6 +1,9 @@ using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -127,14 +130,24 @@ public override string ToString() } } -public abstract class ShaderBuffer(List name, TextLocation info) : ShaderElement(info) +public abstract class ShaderBuffer(string name, TextLocation info) : ShaderElement(info) { - public List Name { get; set; } = name; + public string Name { get; set; } = name; public List Members { get; set; } = []; public override void ProcessSymbol(SymbolTable table) { - var sym = new Symbol(new(Name.ToString() ?? "", SymbolKind.CBuffer), new ConstantBufferSymbol(Name.ToString() ?? "", [])); + var fields = new List<(string Name, SymbolType Type)>(); + foreach (var smem in Members) + { + smem.Type = smem.TypeName.ResolveType(table); + table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); + + fields.Add((smem.Name, smem.Type)); + } + + Type = new ConstantBufferSymbol(Name, fields); + var sym = new Symbol(new(Name, SymbolKind.CBuffer), Type); table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); var kind = this switch @@ -144,12 +157,7 @@ public override void ProcessSymbol(SymbolTable table) RGroup => SymbolKind.RGroup, _ => throw new NotSupportedException() }; - table.RootSymbols.Add(Name.ToString() ?? "", sym); - foreach (var cbmem in Members) - { - cbmem.Type = cbmem.TypeName.ResolveType(table); - table.DeclaredTypes.TryAdd(cbmem.Type.ToString(), cbmem.Type); - } + table.RootSymbols.Add(Name, sym); } } @@ -196,6 +204,20 @@ public override string ToString() } -public sealed class CBuffer(List name, TextLocation info) : ShaderBuffer(name, info); -public sealed class RGroup(List name, TextLocation info) : ShaderBuffer(name, info); -public sealed class TBuffer(List name, TextLocation info) : ShaderBuffer(name, info); +public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) +{ + public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + var (builder, context, _) = compiler; + var registeredType = context.GetOrRegister(Type); + var variable = context.Bound++; + // TODO: Add a StreamSDSL storage class? + var pointerType = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Uniform, registeredType.Value); + context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); + //context.Variables.Add(Name, new(variable, registeredType, Name)); + context.AddName(variable, Name); + } +} + +public sealed class RGroup(string name, TextLocation info) : ShaderBuffer(name, info); +public sealed class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs index e9dba31ec8..942ddcbe0c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs @@ -160,9 +160,9 @@ public record struct BufferParsers : IParser return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool BufferName(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + public static bool BufferName(ref TScanner scanner, ParseResult result, out Identifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out parsed, 1, withSpaces: true, separator: "."); + return LiteralsParser.Identifier(ref scanner, result, out parsed, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index dbe310a60e..5e4cfde4c5 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -144,7 +144,8 @@ public IdRef GetOrRegister(SymbolType? type) VectorType v => Buffer.AddOpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size), MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), - StructType st => RegisterStruct(st), + StructType st => RegisterStructuredType(st.ToId(), st), + ConstantBufferSymbol cb => RegisterStructuredType($"type.{cb.ToId()}", cb), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), @@ -157,20 +158,21 @@ public IdRef GetOrRegister(SymbolType? type) } } - IdRef RegisterStruct(StructType structSymbol) + IdRef RegisterStructuredType(string name, StructuredType structSymbol) { - Span types = stackalloc IdRef[structSymbol.Fields.Count]; - for (var index = 0; index < structSymbol.Fields.Count; index++) - types[index] = GetOrRegister(structSymbol.Fields[index].Type); + Span types = stackalloc IdRef[structSymbol.Members.Count]; + for (var index = 0; index < structSymbol.Members.Count; index++) + types[index] = GetOrRegister(structSymbol.Members[index].Type); var result = Buffer.AddOpTypeStruct(Bound++, types); - AddName(result, structSymbol.ToId()); - for (var index = 0; index < structSymbol.Fields.Count; index++) - AddMemberName(result, index, structSymbol.Fields[index].Name); + AddName(result, name); + for (var index = 0; index < structSymbol.Members.Count; index++) + AddMemberName(result, index, structSymbol.Members[index].Name); return result; } + IdRef RegisterFunctionType(FunctionType functionType) { Span types = stackalloc IdRef[functionType.ParameterTypes.Count]; From 2907088e9b9638ca391648927bbee10df2c67adb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Jun 2025 17:18:31 +0900 Subject: [PATCH 0434/1182] Add shader as a type rather than a symbol --- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 0d05e57dd4..01ece448d0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -120,8 +120,7 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) { - var sid = new SymbolID(shaderType.Name, SymbolKind.Shader); - table.RootSymbols.Add(shaderType.Name, new(sid, shaderType)); + table.DeclaredTypes.Add(shaderType.Name, shaderType); // Register members foreach (var symbol in shaderType.Components) @@ -207,7 +206,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) // Import types and variables/functions var shader = context.Buffer.AddOpSDSLImportShader(context.Bound++, new(mixin.Name)); - var shaderType = (ShaderSymbol)table.RootSymbols[mixin.Name].Type; + var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; foreach (var c in shaderType.Components) { From 6327f562b81b624e55277e2ecd93045095ff500b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Jun 2025 18:37:25 +0900 Subject: [PATCH 0435/1182] Store IdRef in SymbolID --- src/Stride.Shaders/Core/Symbol.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 34 +++++++++++-------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 32 ++++------------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 34 ++++++++++++++++--- .../Parsing/SDSL/AST/ShaderElements.cs | 10 ++---- .../Parsing/SDSL/AST/Statements.cs | 6 ++-- 6 files changed, 61 insertions(+), 57 deletions(-) diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index d0cbc9fa37..fd10523502 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -33,7 +33,7 @@ public enum StreamIO : byte Output } -public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0); +public record struct SymbolID(string Name, int IdRef, SymbolKind Kind, Storage Storage = 0); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); public record struct Symbol(SymbolID Id, SymbolType Type, object? Data = null); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 08ccb637ba..d28d3399da 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -215,8 +215,23 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; + public Symbol ResolveSymbol(SymbolTable table) + { + for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) + { + if (table.CurrentSymbols![i] + .TryGetValue(Name, out var symbol)) + { + return symbol; + } + } + + throw new NotImplementedException($"Cannot find symbol {Name}."); + } + public SymbolType ResolveType(SymbolTable table) { + return ResolveSymbol(table).Type; for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) { if (table.CurrentSymbols![i] @@ -234,21 +249,12 @@ public SymbolType ResolveType(SymbolTable table) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Type = ResolveType(table); - var (builder, context, _) = compiler; - if(builder.CurrentFunction is SpirvFunction f) - { - if(f.Variables.TryGetValue(Name, out var resultVar)) - return resultVar; - else if(f.Parameters.TryGetValue(Name, out var paramVar)) - return paramVar; - } + var symbol = ResolveSymbol(table); + Type = symbol.Type; - if (context.Module.InheritedVariables.TryGetValue(Name, out var externalVar)) - return externalVar; - if (compiler.Context.Variables.TryGetValue(Name, out var variable)) - return variable; - throw new NotImplementedException(); + var (builder, context, _) = compiler; + var resultType = context.GetOrRegister(Type); + return new SpirvValue(symbol.Id.IdRef, resultType, Name); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 01ece448d0..dd0f86346c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -99,7 +99,7 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var variableName = names[variableInstruction.ResultId.Value]; var variableType = types[variableInstruction.ResultType]; - var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + var sid = new SymbolID(variableName, variableInstruction.ResultId, SymbolKind.Variable, Storage.Stream); symbols.Add(new(sid, variableType)); } @@ -109,7 +109,7 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var functionName = names[functionInstruction.ResultId.Value]; var functionType = types[functionInstruction.FunctionType]; - var sid = new SymbolID(functionName, SymbolKind.Method); + var sid = new SymbolID(functionName, functionInstruction.ResultId, SymbolKind.Method); symbols.Add(new(sid, functionType)); } } @@ -121,10 +121,6 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) { table.DeclaredTypes.Add(shaderType.Name, shaderType); - - // Register members - foreach (var symbol in shaderType.Components) - table.CurrentFrame.Add(symbol.Id.Name, symbol); } @@ -154,37 +150,19 @@ public void Compile(CompilerUnit compiler, SymbolTable table) func.Type = ftype; table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); - - var symbol = new Symbol(new(func.Name, SymbolKind.Method), func.Type); - symbols.Add(symbol); } else if (member is ShaderMember svar) { svar.Type = svar.TypeName.ResolveType(table); - var sid = - new SymbolID - ( - svar.Name, - svar.TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, - svar.StreamKind switch - { - StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, - _ => Storage.None - } - ); - table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); - - var symbol = new Symbol(sid, svar.Type); - symbols.Add(symbol); } else if (member is CBuffer cb) { foreach (var cbMember in cb.Members) { cbMember.Type = cbMember.TypeName.ResolveType(table); - var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); - symbols.Add(symbol); + //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); + //symbols.Add(symbol); } } } @@ -215,6 +193,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var variableTypeId = context.GetOrRegister(c.Type); var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); + table.CurrentFrame.Add(c.Id.Name, c with { Id = c.Id with { IdRef = variable.ResultId.Value } }); } else if (c.Id.Kind == SymbolKind.Method) { @@ -223,6 +202,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); + table.CurrentFrame.Add(c.Id.Name, c with { Id = c.Id with { IdRef = function.ResultId.Value } }); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b5f6363ada..4cbbb47761 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -4,8 +4,8 @@ using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -92,6 +92,22 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Semantic != null) context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); context.AddName(variable, Name); + + var sid = + new SymbolID + ( + Name, + variable, + TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, + StreamKind switch + { + StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, + _ => Storage.None + } + ); + var symbol = new Symbol(sid, Type); + table.CurrentShader.Components.Add(symbol); + table.CurrentFrame.Add(Name, symbol); } public override string ToString() @@ -165,17 +181,21 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var argSym = arg.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - table.CurrentFrame.Add(arg.Name, new(new(arg.Name, SymbolKind.Variable, Core.Storage.Function), arg.Type)); arg.Type = argSym; } var (builder, context, _) = compiler; + SpirvFunction function; if (Type is FunctionType ftype) { - builder.CreateFunction(context, Name, ftype); + function = builder.CreateFunction(context, Name, ftype); foreach (var p in Parameters) - builder.AddFunctionParameter(context, p.Name, p.Type); - if(Body is BlockStatement body) + { + var paramValue = builder.AddFunctionParameter(context, p.Name, p.Type); + table.CurrentFrame.Add(p.Name, new(new(p.Name, paramValue.Id, SymbolKind.Variable), p.Type)); + } + + if (Body is BlockStatement body) { table.Push(); builder.CreateBlock(context); @@ -188,6 +208,10 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler else throw new NotImplementedException(); table.Pop(); + + var symbol = new Symbol(new(Name, function.Id, SymbolKind.Method), Type); + table.CurrentShader.Components.Add(symbol); + table.CurrentFrame.Add(Name, symbol); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 9c08baa422..b21cc68fac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -147,9 +147,7 @@ public override void ProcessSymbol(SymbolTable table) } Type = new ConstantBufferSymbol(Name, fields); - var sym = new Symbol(new(Name, SymbolKind.CBuffer), Type); - - table.DeclaredTypes.TryAdd(sym.ToString(), sym.Type); + table.DeclaredTypes.TryAdd(Name, Type); var kind = this switch { CBuffer => SymbolKind.CBuffer, @@ -157,7 +155,6 @@ public override void ProcessSymbol(SymbolTable table) RGroup => SymbolKind.RGroup, _ => throw new NotSupportedException() }; - table.RootSymbols.Add(Name, sym); } } @@ -192,9 +189,8 @@ public override void ProcessSymbol(SymbolTable table) fields.Add((smem.Name, smem.Type)); } - var sym = new Symbol(new(TypeName.ToString() ?? "", SymbolKind.Struct), new StructType(TypeName.ToString() ?? "", fields)); - table.DeclaredTypes.TryAdd(TypeName.ToString(), sym.Type); - table.RootSymbols.Add(sym.Id.Name, sym); + Type = new StructType(TypeName.ToString() ?? "", fields); + table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 9ed161bf01..213c116dde 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -140,10 +140,6 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { Type = TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); - foreach (var d in Variables) - { - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type)); - } } var (builder, context, _) = compiler; @@ -154,6 +150,8 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); context.AddName(variable, d.Variable); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, variable, SymbolKind.Variable), Type)); + if (builder.CurrentFunction is SpirvFunction f) f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); } From 8185755301a83d729058ab738c6a0a4c71b71b3e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Jun 2025 11:34:51 +0900 Subject: [PATCH 0436/1182] Switch Variable and Parameter to use PointerType (which now include StorageClass) --- src/Stride.Shaders/Core/SymbolTypes.cs | 5 +- .../Parsing/SDSL/AST/Expression.cs | 6 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 +- .../Parsing/SDSL/AST/ShaderElements.cs | 3 +- .../Parsing/SDSL/AST/Statements.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 64 ++++++++++++++++--- 8 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 36b043630b..32bb932741 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Text; +using Stride.Shaders.Spirv; namespace Stride.Shaders.Core; @@ -51,9 +52,9 @@ public override string ToString() } } -public sealed record PointerType(SymbolType BaseType) : SymbolType() +public sealed record PointerType(SymbolType BaseType, Specification.StorageClass StorageClass) : SymbolType() { - public override string ToId() => $"ptr_{BaseType.ToId()}"; + public override string ToId() => $"ptr_{StorageClass}_{BaseType.ToId()}"; public override string ToString() => $"*{BaseType}"; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index bca5c38ec9..239ab98f8c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1,6 +1,7 @@ using System.Text; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -145,7 +146,10 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = accessor.Type; } - Type = new PointerType(currentValueType); + if (currentValueType is not PointerType) + throw new InvalidOperationException(); + + Type = new PointerType(currentValueType, Specification.StorageClass.Uniform); // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) if (firstIndex == Accessors.Count) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index dd0f86346c..34ec0d39c2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -49,6 +49,12 @@ public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer 64 => ScalarType.From("double"), }); } + else if (instruction.OpCode == SDSLOp.OpTypePointer) + { + var pointerInstruction = instruction.UnsafeAs(); + var innerType = types[pointerInstruction.Type]; + types.Add(instruction.ResultId!.Value, new PointerType(innerType, pointerInstruction.Storageclass)); + } else if (instruction.OpCode == SDSLOp.OpTypeVoid) { types.Add(instruction.ResultId!.Value, ScalarType.From("void")); @@ -153,7 +159,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } else if (member is ShaderMember svar) { - svar.Type = svar.TypeName.ResolveType(table); + svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } else if (member is CBuffer cb) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4cbbb47761..d38c0d6cf0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -191,8 +191,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler function = builder.CreateFunction(context, Name, ftype); foreach (var p in Parameters) { - var paramValue = builder.AddFunctionParameter(context, p.Name, p.Type); - table.CurrentFrame.Add(p.Name, new(new(p.Name, paramValue.Id, SymbolKind.Variable), p.Type)); + var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); + var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); + table.CurrentFrame.Add(p.Name, new(new(p.Name, paramValue.Id, SymbolKind.Variable), parameterType)); } if (Body is BlockStatement body) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index b21cc68fac..6cb25e263c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -205,10 +205,9 @@ public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context, _) = compiler; - var registeredType = context.GetOrRegister(Type); + var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? - var pointerType = context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Uniform, registeredType.Value); context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); //context.Variables.Add(Name, new(variable, registeredType, Name)); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 213c116dde..4c789cb908 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -143,7 +143,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } var (builder, context, _) = compiler; - var registeredType = context.GetOrRegister(new PointerType(Type!)); + var registeredType = context.GetOrRegister(new PointerType(Type!, Specification.StorageClass.Function)); foreach (var d in Variables) { var variable = context.Bound++; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 5e4cfde4c5..36244982b1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -188,7 +188,7 @@ IdRef RegisterFunctionType(FunctionType functionType) IdRef RegisterPointerType(PointerType pointerType) { var baseType = GetOrRegister(pointerType.BaseType); - var result = Buffer.AddOpTypePointer(Bound++, Specification.StorageClass.Function, baseType); + var result = Buffer.AddOpTypePointer(Bound++, pointerType.StorageClass, baseType); AddName(result, pointerType.ToId()); return result; } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index aa9a25bfb0..eb0a66421a 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -20,17 +20,20 @@ public struct TypeDuplicateRemover : INanoPass public readonly void Apply(SpirvBuffer buffer) { - foreach (var i in buffer.Instructions) + for (var index = 0; index < buffer.Instructions.Count; index++) { + var i = buffer.Instructions[index]; if (i.OpCode == SDSLOp.OpTypeVoid || i.OpCode == SDSLOp.OpTypeInt || i.OpCode == SDSLOp.OpTypeFloat) { - foreach (var j in buffer.Instructions) + for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) { + var j = buffer.Instructions[index2]; if ( - (j.OpCode == SDSLOp.OpTypeVoid || j.OpCode == SDSLOp.OpTypeInt || j.OpCode == SDSLOp.OpTypeFloat) + (j.OpCode == SDSLOp.OpTypeVoid || j.OpCode == SDSLOp.OpTypeInt || + j.OpCode == SDSLOp.OpTypeFloat) && i.ResultId != j.ResultId && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) + ) { ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); SetOpNop(j.Words); @@ -38,12 +41,15 @@ public readonly void Apply(SpirvBuffer buffer) } } } - foreach (var i in buffer.Instructions) + + for (var index = 0; index < buffer.Instructions.Count; index++) { + var i = buffer.Instructions[index]; if (i.OpCode == SDSLOp.OpTypeVector) { - foreach (var j in buffer.Instructions) + for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) { + var j = buffer.Instructions[index2]; if ( j.OpCode == SDSLOp.OpTypeVector && i.ResultId != j.ResultId @@ -56,12 +62,14 @@ public readonly void Apply(SpirvBuffer buffer) } } } - foreach (var i in buffer.Instructions) + for (var index = 0; index < buffer.Instructions.Count; index++) { + var i = buffer.Instructions[index]; if (i.OpCode == SDSLOp.OpTypeMatrix) { - foreach (var j in buffer.Instructions) + for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) { + var j = buffer.Instructions[index2]; if ( j.OpCode == SDSLOp.OpTypeMatrix && i.ResultId != j.ResultId @@ -74,6 +82,46 @@ public readonly void Apply(SpirvBuffer buffer) } } } + for (var index = 0; index < buffer.Instructions.Count; index++) + { + var i = buffer.Instructions[index]; + if (i.OpCode == SDSLOp.OpTypePointer) + { + for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) + { + var j = buffer.Instructions[index2]; + if ( + j.OpCode == SDSLOp.OpTypePointer + && i.ResultId != j.ResultId + && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words); + } + } + } + } + for (var index = 0; index < buffer.Instructions.Count; index++) + { + var i = buffer.Instructions[index]; + if (i.OpCode == SDSLOp.OpName) + { + for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) + { + var j = buffer.Instructions[index2]; + if ( + j.OpCode == SDSLOp.OpName + && i.Operands[0] == j.Operands[0] + && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) + ) + { + ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); + SetOpNop(j.Words); + } + } + } + } } static void ReplaceRefs(int from, int to, SpirvBuffer buffer) From 2b73eb73ef06fd21805f156cc85780233710182c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Jun 2025 13:32:52 +0900 Subject: [PATCH 0437/1182] cbuffer support --- assets/SDSL/TestBasic.sdsl | 7 +++- src/Stride.Shaders.Experiments/Examples.cs | 6 ++- src/Stride.Shaders/Core/Symbol.cs | 4 +- .../Parsing/SDSL/AST/Expression.cs | 39 +++++++++++++------ .../Parsing/SDSL/AST/Literals.cs | 18 +++++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 21 ++++++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 7 ++-- .../Parsing/SDSL/AST/ShaderElements.cs | 8 ++++ .../Parsing/SDSL/AST/Statements.Control.cs | 8 ++-- .../Parsing/SDSL/AST/Statements.Flow.cs | 4 +- .../Parsing/SDSL/AST/Statements.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 20 +++++++++- .../Spirv/Processing/StreamAnalyzer.cs | 6 ++- 13 files changed, 110 insertions(+), 40 deletions(-) diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index babe7413cb..5daca984cb 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -6,6 +6,11 @@ shader TestBasic : TestBase stream float4 Position : SV_POSITION; stream float4 ExtraColor : COLOR; + cbuffer Test123 + { + float4 CBufferValue1; + } + void VSMain() { streams.Position = streams.InputPosition; @@ -22,7 +27,7 @@ shader TestBasic : TestBase void PSMain() { streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); - streams.ColorTarget = streams.ExtraColor; + streams.ColorTarget = streams.ExtraColor * CBufferValue1; //Test(); return; } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index d3c9e22820..ba97842798 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -446,13 +446,15 @@ public static void MergeSDSL() context.ReverseTypes.Add(type.Key, type.Value); } - context.Buffer.AddOpCapability(Specification.Capability.Shader); - context.Buffer.AddOpMemoryModel(Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); + context.Buffer.InsertOpCapability(0, Specification.Capability.Shader); + context.Buffer.InsertOpMemoryModel(1, Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); + context.Buffer.InsertOpExtension(2, "SPV_GOOGLE_hlsl_functionality1"); new StreamAnalyzer().Process(temp, context); temp.Instructions.AddRange(context.Buffer.Instructions); new TypeDuplicateRemover().Apply(temp); + temp.Instructions.RemoveAll(x => x.OpCode == SDSLOp.OpNop); var dis = new SpirvDis(temp, true); var source = dis.Disassemble(true); diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index fd10523502..2a39a90683 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -33,9 +33,9 @@ public enum StreamIO : byte Output } -public record struct SymbolID(string Name, int IdRef, SymbolKind Kind, Storage Storage = 0); +public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); -public record struct Symbol(SymbolID Id, SymbolType Type, object? Data = null); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 239ab98f8c..bb9e8c62dc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -16,6 +16,22 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Expression(TextLocation info) : ValueNode(info) { public abstract SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); + + public SymbolType? ValueType => Type is PointerType pointerType ? pointerType.BaseType : Type; + + public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var result = Compile(table, shader, compiler); + var type = compiler.Context.ReverseTypes[result.TypeId]; + if (type is PointerType pointerType) + { + type = pointerType.BaseType; + var inst = compiler.Builder.Buffer.InsertOpLoad(compiler.Builder.Position++, compiler.Context.Bound++, compiler.Context.Types[type], result.Id, null); + result = new(inst.ResultId.Value, inst.ResultType.Value); + } + + return result; + } } public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) @@ -132,13 +148,14 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil for (var i = firstIndex; i < Accessors.Count; i++) { var accessor = Accessors[i]; - if (currentValueType is StructType s && accessor is Identifier field) + if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) { var index = s.TryGetFieldIndex(field); if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.Compile(table, shader, compiler); indexes[i] = context.CreateConstant(indexLiteral).Id; } else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); @@ -149,7 +166,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil if (currentValueType is not PointerType) throw new InvalidOperationException(); - Type = new PointerType(currentValueType, Specification.StorageClass.Uniform); + Type = currentValueType; // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) if (firstIndex == Accessors.Count) @@ -182,12 +199,12 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var left = Left.Compile(table, shader, compiler); - var right = Right.Compile(table, shader, compiler); + var left = Left.CompileAsValue(table, shader, compiler); + var right = Right.CompileAsValue(table, shader, compiler); if ( OperatorTable.BinaryOperationResultingType( - Left.Type ?? throw new NotImplementedException("Missing type"), - Right.Type ?? throw new NotImplementedException("Missing type"), + Left.ValueType ?? throw new NotImplementedException("Missing type"), + Right.ValueType ?? throw new NotImplementedException("Missing type"), Op, out var t ) @@ -214,12 +231,12 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.Compile(table, shader, compiler); - Left.Compile(table, shader, compiler); - Right.Compile(table, shader, compiler); - if (Condition.Type is not ScalarType { TypeName: "bool" }) + Condition.CompileAsValue(table, shader, compiler); + Left.CompileAsValue(table, shader, compiler); + Right.CompileAsValue(table, shader, compiler); + if (Condition.ValueType is not ScalarType { TypeName: "bool" }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - if (Left.Type != Right.Type) + if (Left.ValueType != Right.ValueType) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index d28d3399da..4b7b302c7b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -1,10 +1,11 @@ -using System.Numerics; -using System.Text; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Numerics; +using System.Text; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -254,7 +255,18 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var (builder, context, _) = compiler; var resultType = context.GetOrRegister(Type); - return new SpirvValue(symbol.Id.IdRef, resultType, Name); + var result = new SpirvValue(symbol.IdRef, resultType, Name); + + if (symbol.AccessChain is int accessChainIndex) + { + Span indexes = stackalloc IdRef[1]; + var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); + indexLiteral.Compile(table, shader, compiler); + indexes[0] = context.CreateConstant(indexLiteral).Id; + result.Id = compiler.Builder.Buffer.InsertOpAccessChain(compiler.Builder.Position++, compiler.Context.Bound++, resultType, symbol.IdRef, indexes).ResultId.Value; + } + + return result; } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 34ec0d39c2..33ddf97a53 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -69,8 +69,15 @@ public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer { var typeStructInstruction = instruction.UnsafeAs(); var structName = names[instruction.ResultId!.Value]; + var fieldsData = instruction.Memory.Span[2..]; var fields = new List<(string Name, SymbolType Type)>(); - throw new NotImplementedException(); + for (var index = 0; index < fieldsData.Length; index++) + { + var fieldData = fieldsData[index]; + var type = types[fieldData]; + var name = memberNames[(typeStructInstruction.ResultId.Value, index)]; + fields.Add((name, type)); + } types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); } else if (instruction.OpCode == SDSLOp.OpTypeFunction) @@ -105,8 +112,8 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var variableName = names[variableInstruction.ResultId.Value]; var variableType = types[variableInstruction.ResultType]; - var sid = new SymbolID(variableName, variableInstruction.ResultId, SymbolKind.Variable, Storage.Stream); - symbols.Add(new(sid, variableType)); + var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + symbols.Add(new(sid, variableType, variableInstruction.ResultId)); } if (instruction.OpCode == SDSLOp.OpFunction) @@ -115,8 +122,8 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var functionName = names[functionInstruction.ResultId.Value]; var functionType = types[functionInstruction.FunctionType]; - var sid = new SymbolID(functionName, functionInstruction.ResultId, SymbolKind.Method); - symbols.Add(new(sid, functionType)); + var sid = new SymbolID(functionName, SymbolKind.Method); + symbols.Add(new(sid, functionType, functionInstruction.ResultId)); } } @@ -199,7 +206,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var variableTypeId = context.GetOrRegister(c.Type); var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); - table.CurrentFrame.Add(c.Id.Name, c with { Id = c.Id with { IdRef = variable.ResultId.Value } }); + table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId.Value }); } else if (c.Id.Kind == SymbolKind.Method) { @@ -208,7 +215,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); - table.CurrentFrame.Add(c.Id.Name, c with { Id = c.Id with { IdRef = function.ResultId.Value } }); + table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId.Value }); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index d38c0d6cf0..124111a94a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -97,7 +97,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler new SymbolID ( Name, - variable, TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, StreamKind switch { @@ -105,7 +104,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler _ => Storage.None } ); - var symbol = new Symbol(sid, Type); + var symbol = new Symbol(sid, Type, variable); table.CurrentShader.Components.Add(symbol); table.CurrentFrame.Add(Name, symbol); } @@ -193,7 +192,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); - table.CurrentFrame.Add(p.Name, new(new(p.Name, paramValue.Id, SymbolKind.Variable), parameterType)); + table.CurrentFrame.Add(p.Name, new(new(p.Name, SymbolKind.Variable), parameterType, paramValue.Id)); } if (Body is BlockStatement body) @@ -210,7 +209,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.Pop(); - var symbol = new Symbol(new(Name, function.Id, SymbolKind.Method), Type); + var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); table.CurrentShader.Components.Add(symbol); table.CurrentFrame.Add(Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 6cb25e263c..40ef74c1b3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -211,6 +211,14 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); //context.Variables.Add(Name, new(variable, registeredType, Name)); context.AddName(variable, Name); + + for (var index = 0; index < Members.Count; index++) + { + var member = Members[index]; + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); + var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, index); + table.CurrentFrame.Add(member.Name, symbol); + } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index f7254204c0..ca7d0a2ab8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -37,9 +37,9 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.Compile(table, shader, compiler); + Condition.CompileAsValue(table, shader, compiler); Body.Compile(table, shader, compiler); - if (Condition.Type != ScalarType.From("bool")) + if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } @@ -54,9 +54,9 @@ public class ElseIf(Expression condition, Statement body, TextLocation info) : I { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.Compile(table, shader, compiler); + Condition.CompileAsValue(table, shader, compiler); Body.Compile(table, shader, compiler); - if (Condition.Type != ScalarType.From("bool")) + if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 224c10b8ca..2ce12ce593 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -64,8 +64,10 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.Compile(table, shader, compiler); + Condition.CompileAsValue(table, shader, compiler); Body.Compile(table, shader, compiler); + if (Condition.ValueType != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 4c789cb908..46b882a3f7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -150,7 +150,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); context.AddName(variable, d.Variable); - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, variable, SymbolKind.Variable), Type)); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); if (builder.CurrentFunction is SpirvFunction f) f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 36244982b1..077d358128 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -38,7 +38,7 @@ public void PutShaderName(string name) } public void AddName(IdRef target, string name) - => Buffer.AddOpName(target, name); + => Buffer.AddOpName(target, name.Replace('.', '_')); public void AddMemberName(IdRef target, int accessor, string name) => Buffer.AddOpMemberName(target, accessor, name); @@ -145,7 +145,7 @@ public IdRef GetOrRegister(SymbolType? type) MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), StructType st => RegisterStructuredType(st.ToId(), st), - ConstantBufferSymbol cb => RegisterStructuredType($"type.{cb.ToId()}", cb), + ConstantBufferSymbol cb => RegisterCBuffer(cb), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), @@ -158,6 +158,22 @@ public IdRef GetOrRegister(SymbolType? type) } } + private IdRef RegisterCBuffer(ConstantBufferSymbol cb) + { + var result = RegisterStructuredType($"type.{cb.ToId()}", cb); + + Buffer.AddOpDecorate(result, Decoration.Block); + for (var index = 0; index < cb.Members.Count; index++) + { + var member = cb.Members[index]; + if (index > 0) + throw new NotImplementedException("Offset"); + Buffer.AddOpMemberDecorate(result, index, Decoration.Offset, 0); + } + + return result; + } + IdRef RegisterStructuredType(string name, StructuredType structSymbol) { Span types = stackalloc IdRef[structSymbol.Members.Count]; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index f83768a9d2..4209f90a5a 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -167,7 +167,8 @@ private void GenerateStreamWrapper(SpirvBuffer buffer, SpirvContext context, Spe // Copy read variables from streams foreach (var stream in inputStreams) { - var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[stream.Info.Type], stream.Id, null); + var baseType = ((PointerType)stream.Info.Type).BaseType; + var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Id, null); buffer.AddOpStore(stream.Info.Id, loadedValue.ResultId!.Value, null); } @@ -175,7 +176,8 @@ private void GenerateStreamWrapper(SpirvBuffer buffer, SpirvContext context, Spe foreach (var stream in outputStreams) { - var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[stream.Info.Type], stream.Info.Id, null); + var baseType = ((PointerType)stream.Info.Type).BaseType; + var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null); buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); } From a33049862dcb33bd3010d1189ecf7fdd81bc5580 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 27 Aug 2025 19:51:08 +0200 Subject: [PATCH 0438/1182] adding new buffer and instruction types --- .../Buffers/NewSpirvBuffer.cs | 127 +++++++ .../Extensions/spirv.sdsl.grammar-ext.json | 108 ++++++ .../Parsing/OpDataEnumerator.cs | 239 ++++++++++++++ src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 16 +- .../Stride.Shaders.Spirv.Core.csproj | 11 +- .../EquatableList.cs | 73 ++-- .../SPVGenerator.Buffers.cs | 4 +- .../SPVGenerator.Extensions.cs | 23 ++ .../SPVGenerator.Helpers.Naming.cs | 3 +- .../SPVGenerator.Helpers.Preprocessing.cs | 2 +- .../SPVGenerator.Info.cs | 9 +- .../SPVGenerator.Instructions.cs | 311 +++++++++++++----- .../SPVGenerator.SDSLOp.cs | 14 +- ...Enums.cs => SPVGenerator.Specification.cs} | 9 +- .../SPVGenerator.cs | 15 +- .../Stride.Shaders.Spirv.Generators.csproj | 17 +- 16 files changed, 797 insertions(+), 184 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json create mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs rename src/Stride.Shaders.Spirv.Generators/{SPVGenerator.Enums.cs => SPVGenerator.Specification.cs} (79%) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs new file mode 100644 index 0000000000..526861e824 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -0,0 +1,127 @@ +#pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. + +using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core.Buffers; + + +public interface IMemoryInstruction +{ + OpDataIndex? DataIndex { get; set; } + MemoryOwner Memory { get; } + public void UpdateMemory(); +} + +public struct OpData : IDisposable +{ + public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } + public readonly SDSLOp Op => (SDSLOp)(Memory.Span[0] & 0xFFFF); + + public OpData() + { + Memory = MemoryOwner.Empty; + } + + public OpData(MemoryOwner memory) + { + Memory = memory; + } + + public readonly void Dispose() => Memory.Dispose(); + + public readonly T Get(string name) + where T : struct, IFromSpirv + { + foreach (var o in this) + { + if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) + return o.To(); + } + throw new Exception($"No operand '{name}' in op {Op}"); + } + public readonly T GetEnum(string name) + where T : Enum + { + foreach (var o in this) + { + if (name == o.Name && !o.Kind.ToString().Contains("Literal") && !o.Kind.ToString().Contains("Id")) + return o.ToEnum(); + } + throw new Exception($"No enum operand '{name}' in op {Op}"); + } + + public readonly OpDataEnumerator GetEnumerator() => new(Memory.Span); +} + + +public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) +{ + public readonly ref OpData Data => ref Buffer[Index]; +} + +public class NewSpirvBuffer +{ + List Memory { get; set; } = []; + + internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Memory)[index]; + // internal OpDataIndex this[int index] => new(index, this); + + public void Add(OpData data) + => Memory.Add(data); + + public void Add(ref T instruction) where T : IMemoryInstruction + { + if (instruction.DataIndex is OpDataIndex odi) + { + if (odi.Buffer == this) + return; + else + Memory.Add(new(instruction.Memory)); + } + else Memory.Add(new(instruction.Memory)); + instruction.DataIndex = new(Memory.Count - 1, this); + + } + + public void Insert(int index, OpData data) + => Memory.Insert(index, data); + + /// + /// Removes an instruction at a certain index. + ///
Be careful when using this method, as it will invalidate any references to the removed instruction. + ///
+ /// + /// true if the instruction was successfully removed + public bool RemoveAt(int index) + { + if (index < 0 || index >= Memory.Count) + return false; + Memory[index].Dispose(); + Memory.RemoveAt(index); + return true; + } + + public Enumerator GetEnumerator() => new(this); + + public ref struct Enumerator(NewSpirvBuffer buffer) + { + readonly NewSpirvBuffer buffer = buffer; + private readonly List list = buffer.Memory; + private int index = -1; + + public readonly OpDataIndex Current => new(index, buffer); + + public bool MoveNext() + { + if (index < list.Count - 1) + { + index++; + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json new file mode 100644 index 0000000000..38d12b30f6 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -0,0 +1,108 @@ +{ + "instructions": [ + { + "opname": "OpSDSLShader", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "shaderName" + } + ] + }, + { + "opname": "OpSDSLShaderEnd", + "class": "Miscellaneous" + }, + { + "opname": "OpSDSLMixinInherit", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "shader" + } + ] + }, + { + "opname": "OpSDSLCompose", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixin" + }, + { + "kind": "LiteralString", + "name": "name" + } + ] + }, + { + "opname": "OpSDSLStage", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "stagedElement" + } + ] + }, + { + "opname": "OpSDSLImportShader", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdResult" + }, + { + "kind": "LiteralString", + "name": "shaderName" + } + ] + }, + { + "opname": "OpSDSLImportFunction", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { + "kind": "LiteralString", + "name": "functionName" + }, + { + "kind": "IdRef", + "name": "shader" + } + ] + }, + { + "opname": "OpSDSLImportVariable", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { + "kind": "LiteralString", + "name": "variableName" + }, + { + "kind": "IdRef", + "name": "shader" + } + ] + } + ], + "operand_kinds": [ + { + "kind": "ExecutionModel", + "enumerants": [ + { + "enumerant": "Mixin", + "value": 5367 + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs new file mode 100644 index 0000000000..c3707930c6 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -0,0 +1,239 @@ +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Core.Parsing; + +/// +/// An instruction operands enumerator, useful for parsing instructions +/// +public ref struct OpDataEnumerator +{ + static readonly OperandKind[] pairs = [.. Enum.GetValues().Where(x => x.ToString().StartsWith("Pair"))]; + readonly Span instruction; + readonly Span Operands => instruction[1..]; + readonly SDSLOp OpCode => (SDSLOp)(instruction[0] & 0xFFFF); + readonly LogicalOperandArray logicalOperands; + int wid; + int oid; + + public OpDataEnumerator(Span instruction) + { + this.instruction = instruction; + logicalOperands = InstructionInfo.GetInfo(OpCode); + oid = -1; + wid = 0; + } + + public SpvOperand Current => ParseCurrent(); + + public bool MoveNext() + { + if (oid < 0) + { + oid = 0; + if (logicalOperands[0].Kind == OperandKind.None) + return false; + return true; + } + else + { + + var logOp = logicalOperands[oid]; + + if (OpCode == SDSLOp.OpDecorate) + { + if (oid == 0) + { + wid += 1; + oid += 1; + return true; + } + else if (oid > 0) + { + var builtin = (Decoration)Operands[1]; + bool has2Extra = builtin == Decoration.LinkageAttributes; + bool has1Extra = + builtin == Decoration.BuiltIn + || builtin == Decoration.Location + || builtin == Decoration.SpecId + || builtin == Decoration.ArrayStride + || builtin == Decoration.MatrixStride + || builtin == Decoration.UniformId + || builtin == Decoration.Stream + || builtin == Decoration.Component + || builtin == Decoration.Index + || builtin == Decoration.Binding + || builtin == Decoration.DescriptorSet + || builtin == Decoration.Offset + || builtin == Decoration.XfbBuffer + || builtin == Decoration.XfbStride + || builtin == Decoration.FuncParamAttr + || builtin == Decoration.FPRoundingMode + || builtin == Decoration.FPFastMathMode + || builtin == Decoration.LinkageAttributes + || builtin == Decoration.InputAttachmentIndex + || builtin == Decoration.Alignment + || builtin == Decoration.MaxByteOffset + || builtin == Decoration.AlignmentId + || builtin == Decoration.MaxByteOffsetId + || builtin == Decoration.SecondaryViewportRelativeNV + || builtin == Decoration.CounterBuffer; + if (has1Extra && oid == 1 && !has2Extra) + { + wid += 1; + oid += 1; + } + else if (has2Extra) + { + throw new NotImplementedException(); + } + else + { + return false; + } + + } + + oid += 1; + if (oid > 2) + return false; + else + return wid < Operands.Length; + } + else if (logOp.Quantifier == OperandQuantifier.One) + { + if (logOp.Kind == OperandKind.LiteralString) + { + while (!Operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) + wid += 2; + else + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) + { + if ( + pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) + && wid < Operands.Length - 1 + ) + { + wid += 2; + } + else if ( + logOp.Kind == OperandKind.LiteralString + && wid < Operands.Length + ) + { + while (!Operands[wid].HasEndString()) + wid += 1; + wid += 1; + } + else if (wid < Operands.Length) + wid += 1; + oid += 1; + + } + else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + throw new NotImplementedException("params of strings is not yet implemented"); + else if ( + pairs.Contains(logOp.Kind ?? throw new Exception()) + && wid < Operands.Length - 2 + ) + wid += 2; + else if (wid < Operands.Length - 1) + wid += 1; + else + oid += 1; + + } + if (oid >= logicalOperands.Count) + return false; + return wid < Operands.Length; + } + + } + + public SpvOperand ParseCurrent() + { + var logOp = logicalOperands[oid]; + if (OpCode == SDSLOp.OpDecorate) + { + SpvOperand result = new(); + if (oid == 0) + result = new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)); + else if (oid == 1) + result = new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)); + else if (oid == 2) + { + result = result with + { + Kind = (Decoration)Operands[1] switch + { + Decoration.BuiltIn => OperandKind.BuiltIn, + Decoration.Location => OperandKind.LiteralInteger, + Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, + Decoration.ArrayStride => OperandKind.LiteralInteger, + Decoration.MatrixStride => OperandKind.LiteralInteger, + Decoration.UniformId => OperandKind.IdScope, + Decoration.Stream => OperandKind.LiteralInteger, + Decoration.Component => OperandKind.LiteralInteger, + Decoration.Index => OperandKind.LiteralInteger, + Decoration.Binding => OperandKind.LiteralInteger, + Decoration.DescriptorSet => OperandKind.LiteralInteger, + Decoration.Offset => OperandKind.LiteralInteger, + Decoration.XfbBuffer => OperandKind.LiteralInteger, + Decoration.XfbStride => OperandKind.LiteralInteger, + Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, + Decoration.FPRoundingMode => OperandKind.FPRoundingMode, + Decoration.FPFastMathMode => OperandKind.FPFastMathMode, + Decoration.LinkageAttributes => OperandKind.LiteralString, + Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, + Decoration.Alignment => OperandKind.LiteralInteger, + Decoration.MaxByteOffset => OperandKind.LiteralInteger, + Decoration.AlignmentId => OperandKind.IdRef, + Decoration.MaxByteOffsetId => OperandKind.IdRef, + Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, + Decoration.CounterBuffer => OperandKind.IdRef, + _ => OperandKind.None + } + }; + } + return result; + + } + else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) + { + if (logOp.Kind == OperandKind.LiteralString) + { + var length = 0; + while (!Operands[wid + length].HasEndString()) + length += 1; + length += 1; + var result = new SpvOperand(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, length)); + + return result; + } + else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) + { + var result = new SpvOperand(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); + return result; + } + else + return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); + } + else + { + if (pairs.Contains(logOp.Kind ?? OperandKind.None)) + return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); + else + return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); + } + } + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index b8f8e6d7f3..bc024e5d46 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -7,6 +7,7 @@ namespace Stride.Shaders.Spirv.Core; ///
public ref struct SpvOperand { + public string? Name { get; init; } public OperandKind Kind { get; init; } public OperandQuantifier Quantifier { get; init; } public Span Words { get; init; } @@ -20,14 +21,23 @@ public SpvOperand(OperandKind kind, OperandQuantifier quantifier, Span word Offset = idRefOffset; } + public SpvOperand(string? name, OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0) + { + Name = name; + Kind = kind; + Quantifier = quantifier; + Words = words; + Offset = idRefOffset; + } + public void ReplaceIdResult(int replacement) { - if(Kind == OperandKind.IdResult && replacement > 0) + if (Kind == OperandKind.IdResult && replacement > 0) Words[0] = replacement; } public T ToEnum() where T : Enum { - return Unsafe.As(ref Words[0]); + return Unsafe.As(ref Words[0]); } public T To() where T : struct, IFromSpirv { @@ -42,7 +52,7 @@ public T To() where T : struct, IFromSpirv public override string ToString() { - return Kind switch + return Kind switch { OperandKind.LiteralString => To().Value, OperandKind.IdRef => $"%{Words[0] + Offset}", diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 4e8e6cfc8d..367e09462c 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -6,21 +6,19 @@ enable true Generated + preview - - - - - + + @@ -32,5 +30,4 @@ - \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/EquatableList.cs b/src/Stride.Shaders.Spirv.Generators/EquatableList.cs index 8c72099b2d..d6ca68b626 100644 --- a/src/Stride.Shaders.Spirv.Generators/EquatableList.cs +++ b/src/Stride.Shaders.Spirv.Generators/EquatableList.cs @@ -4,7 +4,6 @@ // using System.Collections; -using System.Collections.Immutable; using System.Text.Json; using System.Text.Json.Serialization; @@ -17,8 +16,8 @@ public class EquatableListJsonConverter : JsonConverter> { public override EquatableList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - var list = JsonSerializer.Deserialize(ref reader, options) ?? []; - return new EquatableList([..list]); + var array = JsonSerializer.Deserialize(ref reader, options) ?? []; + return new EquatableList([..array]); } public override void Write(Utf8JsonWriter writer, EquatableList value, JsonSerializerOptions options) @@ -28,25 +27,30 @@ public override void Write(Utf8JsonWriter writer, EquatableList value, JsonSe } /// -/// An immutable, equatable list. This is equivalent to but with value equality support. +/// An immutable, equatable array. This is equivalent to but with value equality support. /// -/// The type of values in the list. -/// -/// Initializes a new instance of the struct. -/// -/// The input list to wrap. -public readonly struct EquatableList(List list) : IEquatable>, IEnumerable +/// The type of values in the array. +public readonly struct EquatableList : IEquatable>, IEnumerable where T : IEquatable { /// - /// The underlying list. + /// The underlying array. /// - private readonly List _list = list; + private readonly List? _list; /// - /// Gets the length of the list, or 0 if the list is null + /// Initializes a new instance of the struct. /// - public int Count => _list.Count; + /// The input array to wrap. + public EquatableList(List array) + { + _list = array; + } + + /// + /// Gets the length of the array, or 0 if the array is null + /// + public int Count => _list?.Count ?? 0; /// /// Checks whether two values are the same. @@ -71,48 +75,36 @@ public readonly struct EquatableList(List list) : IEquatable - public bool Equals(EquatableList list) + public bool Equals(EquatableList array) { - if (Count != list.Count) - return false; - for (int i = 0; i < Count; i++) - { - if (!_list![i].Equals(list._list![i])) - return false; - } - return true; + return AsList().SequenceEqual(array.AsList()); } /// public override bool Equals(object? obj) { - return obj is EquatableList list && Equals(this, list); + return obj is EquatableList array && Equals(this, array); } /// public override int GetHashCode() { - if (_list is not List list) - { + if (_list is not List array) return 0; - } - - HashCode hashCode = default; - foreach (T item in list) + int hash = 17; + foreach (T item in array) { - hashCode.Add(item); + hash = hash * 31 + item.GetHashCode(); } - - return hashCode.ToHashCode(); + return hash; } - /// - /// Returns the underlying wrapped list. + /// Returns the underlying wrapped array. /// - /// Returns the underlying list. - public List AsList() + /// Returns the underlying array. + public List? AsList() { return _list; } @@ -120,15 +112,14 @@ public List AsList() /// IEnumerator IEnumerable.GetEnumerator() { - return _list.GetEnumerator(); + return ((IEnumerable)(_list ?? [])).GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() { - return _list.GetEnumerator(); + return ((IEnumerable)(_list ?? [])).GetEnumerator(); } - + public static implicit operator EquatableList(List list) => new([.. list]); - public static implicit operator EquatableList(ImmutableList list) => new([.. list]); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index 5e1d60a379..b901345e9b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -54,7 +54,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorateString, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -63,7 +63,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorateString, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs new file mode 100644 index 0000000000..4396a19af2 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs @@ -0,0 +1,23 @@ +using System; +using System.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; + +namespace Stride.Shaders.Spirv.Generators; + + +public static class SpirvGeneratorExtensions +{ + public static SourceText ToSourceText(this StringBuilder builder) + { + return SourceText.From( + SyntaxFactory + .ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ); + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index aa7a3e28f4..bdd835c82e 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using System; using System.Collections.Generic; using System.Diagnostics; @@ -281,4 +281,3 @@ public static string ConvertOperandName(string input, string? quant = null, bool } } - diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 2eb0a2eadd..b5e294497f 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -137,4 +137,4 @@ public static string KindToVariableName(string kind) _ => kind.Replace("'", "").Replace(" ", "").ToLowerInvariant() }; } -} +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index c8a2be1d91..e8b5555f45 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -24,19 +24,19 @@ public void CreateInfo(IncrementalGeneratorInitializationContext context, Increm GenerateKinds(context, grammarProvider); - IncrementalValueProvider> infoProvider = + IncrementalValueProvider> infoProvider = grammarProvider .SelectMany(static (grammar, _) => grammar.Instructions!.Value) .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) .Collect() - .Select(static (arr, _) => new EquatableArray([.. arr])); + .Select(static (arr, _) => new EquatableList([.. arr])); context.RegisterImplementationSourceOutput( infoProvider, GenerateInstructionInformation ); } - static void GenerateInstructionInformation(SourceProductionContext spc, EquatableArray instructions) + static void GenerateInstructionInformation(SourceProductionContext spc, EquatableList instructions) { var code = new StringBuilder(); code @@ -170,7 +170,4 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) code.Append("Instance.Register(SDSLOp.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); } } - - } - diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 72fc703700..bf7f72a0c2 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -11,120 +11,198 @@ public partial class SPVGenerator : IIncrementalGenerator { public void GenerateStructs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - var sdslInstructionsData = - grammarProvider - .Select(static (grammar, _) => grammar.Instructions ?? new([])); + // var sdslInstructionsData = + // grammarProvider + // .Select(static (grammar, _) => grammar.Instructions ?? new([])); context.RegisterImplementationSourceOutput( - sdslInstructionsData, + grammarProvider, GenerateInstructionStructs ); } - - public static void GenerateInstructionStructs(SourceProductionContext spc, EquatableList instructions) + public static void GenerateInstructionStructs(SourceProductionContext spc, SpirvGrammar grammar) { - StringBuilder builder = new(); builder - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine() - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine() - .AppendLine(); + .AppendLine("using static Spv.Specification;") + .AppendLine("using CommunityToolkit.HighPerformance;") + .AppendLine("using CommunityToolkit.HighPerformance.Buffers;") + .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine() + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine() + .AppendLine(); - foreach (var instruction in instructions) + StringBuilder body1 = new(); + StringBuilder body2 = new(); + StringBuilder body3 = new(); + StringBuilder body4 = new(); + if (grammar.Instructions?.AsList() is List instructions) { - - builder - .AppendLine($"public ref struct Inst{instruction.OpName} : IWrapperInstruction") - .AppendLine("{") - .AppendLine("public Instruction Inner { get; set; }"); - try + foreach (var instruction in instructions) { - if (instruction.Operands?.AsList() is List operands && operands.Count > 0) + + + + if (instruction.OpName.StartsWith("OpCopyMemory") || !instruction.OpName.StartsWith("OpType")) + continue; + body1.Clear(); + body2.Clear(); + body3.Clear(); + body4.Clear(); + + if (instruction.Operands?.AsList() is List operands) { - var tmp = 1; + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;") + .AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{x.Kind} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 foreach (var operand in operands) { - string fieldName; - string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - if (operand.Name is null or "") - fieldName = ConvertKindToName(operand.Kind, false); - else - { - var nameBuilder = new StringBuilder(); - bool first = true; - foreach (var c in operand.Name) - { - if (char.IsLetterOrDigit(c) || c == '_') - { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } - - } - fieldName = nameBuilder.ToString(); - } - - if (operand.IsIndexKnown && operand.Class == "Id" || operand.Class == "BitEnum" || operand.Class == "ValueEnum" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - { - if (operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - { - builder.AppendLine($"public int {fieldName} {{get => Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = value;}}"); - tmp += 1; - } - else if (operand.Class == "BitEnum") - { - builder.AppendLine($"public {operand.Kind}Mask {fieldName} {{get => ({operand.Kind}Mask)Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = (int)value;}}"); - tmp += 1; - } - else if (operand.Class == "ValueEnum") - { - builder.AppendLine($"public {operand.Kind} {fieldName} {{get => ({operand.Kind})Inner.Memory.Span[{tmp}]; set => Inner.Memory.Span[{tmp}] = (int)value;}}"); - tmp += 1; - } - else if (operand.Class == "Id") - { - builder.AppendLine($"public {operand.Kind} {fieldName} {{get => new {operand.Kind}(Inner.Memory.Span[{tmp}]); set => Inner.Memory.Span[{tmp}] = value;}}"); - tmp += 1; - } - } - else - { - if (operand.Kind == "LiteralContextDependentNumber") - continue; - else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); - else if (operand.Class == "BitEnum") - builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); - else if (operand.Class == "ValueEnum") - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); - else - builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); - } + + (string type, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + + body1.Append($"public {operand.Kind} {fieldName} {{ get; set {{ field = value; UpdateMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")") + .AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}>();"); + // Body 3 + body3.AppendLine($"{fieldName} = {operandName};"); } + body2.AppendLine("}\n}"); + + body3.AppendLine("UpdateMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateMemory()") + .AppendLine("{") + .Append($"Span instruction = [(int)SDSLOp.{instruction.OpName}, ") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $".. {fieldName}.AsSpirvSpan()"; + }))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + Memory?.Dispose(); + Memory = tmp;" + ) + .AppendLine("}"); + } - } - catch (Exception e) - { - builder.Append("/*").Append(e.Message).Append(" ").Append(e.StackTrace).AppendLine("*/"); - } - builder - .AppendLine() - .AppendLine($"public Inst{instruction.OpName}(Instruction instruction) => Inner = instruction;") - .AppendLine($"public static implicit operator Inst{instruction.OpName}(Instruction instruction) => new(instruction);"); + builder.AppendLine($@" +public struct {instruction.OpName} : IMemoryInstruction +{{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner Memory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} - builder - .AppendLine("}") - .AppendLine(); - } + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); +}} + + +"); + // builder.AppendLine($"public ref struct {instruction.OpName} : IWrapperInstruction") + // .AppendLine("{") + // .AppendLine("public RefInstruction Inner { get; set; }") + // .AppendLine("public int WordCount => Inner.WordCount;"); + // if (instruction.Operands.AsList() is List operands && operands.Count > 0) + // { + // foreach (var operand in operands) + // { + // string fieldName; + // string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + // if (operand.Name is null or "") + // fieldName = ConvertKindToName(operand.Kind, false); + // else + // { + // var nameBuilder = new StringBuilder(); + // bool first = true; + // foreach (var c in operand.Name) + // { + // if (char.IsLetterOrDigit(c) || c == '_') + // { + // nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + // first &= false; + // } + + // } + // fieldName = nameBuilder.ToString(); + // } + // if (operand.Kind == "LiteralContextDependentNumber") + // continue; + // else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") + // builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); + // else if (operand.Class == "BitEnum") + // builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); + // else if (operand.Class == "ValueEnum") + // builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); + // else + // builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); + // } + // } + + + // builder + // .AppendLine() + // .AppendLine($"public {instruction.OpName}(RefInstruction instruction) => Inner = instruction;") + // .AppendLine($"public {instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);") + // .AppendLine($"public static implicit operator IdRef({instruction.OpName} instruction) => new(instruction.Inner.ResultId ?? throw new Exception(\"Instruction has no result id\"));") + // .AppendLine($"public static implicit operator IdResultType({instruction.OpName} instruction) => new(instruction.Inner.ResultId ?? throw new Exception(\"Instruction has no result id\"));") + // .AppendLine($"public static implicit operator {instruction.OpName}(Span buffer) => new {instruction.OpName}(buffer);") + // .AppendLine($"public static implicit operator {instruction.OpName}(Instruction instruction) => new {instruction.OpName}(instruction.AsRef());") + // .AppendLine($"public static implicit operator {instruction.OpName}(RefInstruction instruction) => new {instruction.OpName}(instruction);"); + // builder.AppendLine("}"); + } + } spc.AddSource( - $"InstructionStructs.gen.cs", + $"Instructions.g.cs", SourceText.From( SyntaxFactory .ParseCompilationUnit(builder.ToString()) @@ -134,4 +212,55 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Equat ) ); } + + public static (string TypeName, string FieldName, string OperandName) ToTypeFieldAndOperandName(OperandData operand) + { + string typename = (operand.Kind, operand.Quantifier) switch + { + // ("PairIdRefIdRef", null or "") => "(IdRef, IdRef)", + // ("PairIdRefLiteralInteger", null or "") => "(IdRef, LiteralInteger)", + // ("PairLiteralIntegerIdRef", null or "") => "(LiteralInteger, IdRef)", + + + (string s, null or "") when s.StartsWith("Id") => "int", + ("LiteralInteger", null or "") => "int", + ("LiteralFloat", null or "") => "float", + ("LiteralString", null or "") => "string", + (string s, null or "") when s.StartsWith("Pair") => "(int, int)", + (string s, null or "") when !s.StartsWith("Literal") => s, + (string s, "?") when s.StartsWith("Id") => "int?", + ("LiteralInteger", "?") => "int?", + ("LiteralFloat", "?") => "float?", + ("LiteralString", "?") => "string?", + (string s, "?") when !s.StartsWith("Literal") => $"{s}?", + (string s, "*") when s.StartsWith("Id") => "int?", + ("LiteralInteger", "*") => "int[]", + ("LiteralFloat", "*") => "float[]", + ("LiteralString", "*") => "string[]", + (string s, "*") when !s.StartsWith("Literal") => $"{s}?", + _ => throw new NotImplementedException($"Could not generate C# type for {operand.Kind}-{operand.Quantifier}") + }; + + + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else + { + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) + { + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } + + } + fieldName = nameBuilder.ToString(); + } + return (typename, fieldName, operandName); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 39f7a127d2..619c85550a 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -1,8 +1,20 @@ using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; using System.Text; +using System.Threading.Tasks; +using System.IO; +using System.Reflection; +using System.Text.Json; +using System.Security.Claims; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; using AngleSharp.Common; using Microsoft.CodeAnalysis.Text; +using System.Dynamic; + namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator @@ -100,4 +112,4 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList grammarProvider) { var sdsloProvider = grammarProvider - .Select(static (grammar, _) => grammar.OperandKinds ?? new([])); + .Select(static (grammar, _) => grammar); context.RegisterImplementationSourceOutput( sdsloProvider, GenerateSDSLSpecification ); } - public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableDictionary operandKinds) + public void GenerateSDSLSpecification(SourceProductionContext spc, SpirvGrammar grammar) { var code = new StringBuilder(); code @@ -27,6 +27,11 @@ public void GenerateSDSLSpecification(SourceProductionContext spc, EquatableDict .AppendLine("public static partial class Specification") .AppendLine("{"); + code.AppendLine($"public static uint MagicNumber {{ get; }} = {grammar.MagicNumber};"); + code.AppendLine($"public static uint MajorVersion {{ get; }} = {grammar.MajorVersion};"); + code.AppendLine($"public static uint MinorVersion {{ get; }} = {grammar.MinorVersion};"); + code.AppendLine($"public static uint Revision {{ get; }} = {grammar.Revision};"); + var operandKinds = grammar.OperandKinds ?? new([]); foreach (var op in operandKinds.AsDictionary()!.Values) { if (op.Category == "Literal" || op.Category == "Id" || op.Category == "Composite") diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index c523f30d5d..4ff25f4064 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -1,16 +1,8 @@ -using AngleSharp.Dom; -using Microsoft.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices.ComTypes; +using Microsoft.CodeAnalysis; using System.Text; using System.Text.Json; -using AngleSharp; -using System.Net.Http.Headers; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Stride.Shaders.Spirv.Generators; @@ -33,9 +25,6 @@ public void Initialize(IncrementalGeneratorInitializationContext context) if (!options.Converters.Any(x => x is EquatableListJsonConverter)) options.Converters.Add(new EquatableListJsonConverter()); - - - var grammarData = context .AdditionalTextsProvider @@ -107,4 +96,4 @@ public static void BufferGeneration(SourceProductionContext spc, SpirvGrammar so } -} +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 7759f47219..58f3e67c96 100644 --- a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -14,7 +14,7 @@ - + @@ -23,19 +23,6 @@ - - - - - - - - - - - - - $(GetTargetPathDependsOn);GetDependencyTargetPaths @@ -53,4 +40,4 @@ - + \ No newline at end of file From 6e3bcb1339ee430c7eab6a41193105e52b752fd1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sat, 30 Aug 2025 13:16:27 +0200 Subject: [PATCH 0439/1182] improving spirv literal for better generation of code --- .../Examples.Spirv.cs | 126 +++++- src/Stride.Shaders.Experiments/Examples.cs | 26 +- .../Buffers/NewSpirvBuffer.cs | 40 +- .../Buffers/SpirvBuffer.cs | 6 +- .../ISpirvElement.cs | 170 +------- .../Information/InstructionInfo.Order.cs | 72 ++-- .../Information/InstructionInfo.cs | 110 ++--- .../Literals/LiteralArray.cs | 108 +++++ .../Literals/LiteralFloat.cs | 2 + .../Literals/LiteralInteger.cs | 118 +++++- .../Literals/LiteralValue.cs | 104 +++++ .../MemoryInstruction.cs | 3 +- .../Parsing/OpDataEnumerator.cs | 6 +- .../Parsing/OrderedEnumerator.cs | 2 +- .../Parsing/RefHeader.cs | 2 +- .../Parsing/SpirvHeader.cs | 6 +- src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 48 +-- .../Stride.Shaders.Spirv.Core.csproj | 2 +- .../SPVGenerator.Buffers.cs | 24 +- .../SPVGenerator.Info.cs | 16 +- .../SPVGenerator.Instructions.cs | 383 ++++++++++-------- src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 181 +++++---- .../Spirv/Building/Builder.Flow.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 19 +- .../Spirv/Processing/CapabilitiesCompute.cs | 14 +- .../Spirv/Processing/CompressBuffer.cs | 4 +- .../Processing/FunctionVariableOrderer.cs | 10 +- .../Spirv/Processing/IOReplace.cs | 8 +- .../Spirv/Processing/IOVariableDecorator.cs | 2 +- .../Spirv/Processing/IdRefOffsetter.cs | 2 +- .../MemoryModelDuplicatesRemover.cs | 2 +- .../Spirv/Processing/MixinMerger.cs | 2 +- .../Spirv/Processing/PostProcessor.cs | 2 +- .../Spirv/Processing/SDSLOpRemover.cs | 6 +- .../Spirv/Processing/StreamAnalyzer.cs | 40 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 23 +- .../Spirv/Tools/SpirvDis.Appends.cs | 6 +- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 14 +- 39 files changed, 1049 insertions(+), 664 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 3e3d6d3bfd..c229258970 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -51,13 +51,135 @@ public static void ParseShader() { Console.WriteLine(Unsafe.SizeOf>()); - InstructionInfo.GetInfo(SDSLOp.OpCapability); + InstructionInfo.GetInfo(Op.OpCapability); var shader = File.ReadAllBytes("../../shader.spv"); SpirvReader.ParseToList(shader, new(8)); } + + public static void CreateNewShader() + { + int id = 1; + + // var bound = new Bound(); + var buffer = new NewSpirvBuffer(); + // // Capabilities + + buffer.Add(new OpCapability(Capability.Shader)); + var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); + buffer.AddRef(ref extInstImport); + buffer.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + + + // declarations + + var t_void = new OpTypeVoid(id++); + buffer.AddRef(ref t_void); + + var t_bool = new OpTypeBool(id++); + buffer.AddRef(ref t_bool); + + var t_func = new OpTypeFunction(id++, t_void, []); + var t_float = new OpTypeFloat(id++, 32, null); + var t_uint = new OpTypeInt(id++, 32, 0); + var t_int = new OpTypeInt(id++, 32, 1); + var t_func_add = new OpTypeFunction(id++, t_int, [t_int, t_int]); + var t_float4 = new OpTypeVector(id++, t_float, 4); + var t_p_float4_func = new OpTypePointer(id++, StorageClass.Function, t_float4); + var constant1 = new OpConstant(id++, t_float, 5); + var constant2 = new OpConstant(id++, t_float, 2.23f); + var constant3 = new OpConstant(id++, t_uint, 5); + var compositeType = buffer.AddOpConstantComposite( + id++, + t_float4, + [constant1, constant1, constant2, constant1] + ); + + var t_array = buffer.AddOpTypeArray(id++, t_float4, constant3); + + var t_struct = buffer.AddOpTypeStruct(id++, [t_uint, t_array, t_int]); + var t_struct2 = buffer.AddOpTypeStruct(id++, [t_struct, t_uint]); + + var t_p_struct2 = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_struct2); + + var v_struct2 = buffer.AddOpVariable(id++, t_p_struct2, StorageClass.Uniform, null); + + var constant4 = buffer.AddOpConstant(id++, t_int, 1); + + var t_p_uint = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_uint); + var constant5 = buffer.AddOpConstant(id++, t_uint, 0); + + var t_p_output = buffer.AddOpTypePointer(id++, StorageClass.Output, t_float4); + var v_output = buffer.AddOpVariable(id++, t_p_output, StorageClass.Output, null); + + var t_p_input = buffer.AddOpTypePointer(id++, StorageClass.Input, t_float4); + var v_input = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + + var constant6 = buffer.AddOpConstant(id++, t_int, 0); + var constant7 = buffer.AddOpConstant(id++, t_int, 2); + var t_p_float4_unif = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_float4); + + var v_input_2 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + var t_p_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_int); + var constant8 = buffer.AddOpConstant(id++, t_int, 4); + var v_input_3 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + + + + + + buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); + buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); + buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); + buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); + buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); + buffer.AddOpDecorate(t_struct2, Decoration.Block); + buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); + buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); + + + + + buffer.AddOpName(t_p_func, "main"); + buffer.AddOpName(t_struct, "S"); + buffer.AddOpMemberName(t_struct, 0, "b"); + buffer.AddOpMemberName(t_struct, 1, "v"); + buffer.AddOpMemberName(t_struct, 2, "i"); + + var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.None, t_func_add); + var a = buffer.AddOpFunctionParameter(id++, t_int); + var b = buffer.AddOpFunctionParameter(id++, t_int); + buffer.AddOpLabel(id++); + var res = buffer.AddOpIAdd(id++, t_int, a, b); + buffer.AddOpReturnValue(res); + buffer.AddOpFunctionEnd(); + + var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.None, t_func); + buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); + buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); + + buffer.AddOpLabel(id++); + var resAdd = buffer.AddOpFunctionCall(id++, t_int, add, [constant7, constant7]); + buffer.AddOpReturn(); + buffer.AddOpFunctionEnd(); + + + + + + buffer.Sort(); + + var dis = new SpirvDis(buffer, useNames: true); + + dis.Disassemble(writeToConsole: true); + File.WriteAllBytes( + "test.spv", + MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) + ); + } public static void CreateShader() @@ -168,7 +290,7 @@ public static void CreateShader() buffer.AddOpFunctionEnd(); - + buffer.Sort(); diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index ba97842798..0167253330 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -336,30 +336,30 @@ public static void MergeSDSL() var idRemapping = new Dictionary(); foreach (var i in temp.Instructions) { - if (i.OpCode == SDSLOp.OpName) + if (i.OpCode == Op.OpName) { var nameInstruction = i.UnsafeAs(); names.Add(nameInstruction.Target, nameInstruction.Name.Value); } - else if (i.OpCode == SDSLOp.OpSDSLShader) + else if (i.OpCode == Op.OpSDSLShader) { currentShader = new ShaderInfo(); var shaderName = i.UnsafeAs().ShaderName.Value; shaders.Add(shaderName, currentShader); SetOpNop(i.Words); } - else if (i.OpCode == SDSLOp.OpSDSLShaderEnd) + else if (i.OpCode == Op.OpSDSLShaderEnd) { currentShader = null; importedShaders.Clear(); SetOpNop(i.Words); } - else if (i.OpCode == SDSLOp.OpSDSLMixinInherit) + else if (i.OpCode == Op.OpSDSLMixinInherit) { SetOpNop(i.Words); } - if (i.OpCode == SDSLOp.OpFunction) + if (i.OpCode == Op.OpFunction) { var function = i.UnsafeAs(); var functionName = names[function.ResultId.Value]; @@ -369,14 +369,14 @@ public static void MergeSDSL() //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.Functioncontrol, function.FunctionType); } - if (i.OpCode == SDSLOp.OpVariable) + if (i.OpCode == Op.OpVariable) { var variable = i.UnsafeAs(); var variableName = names[variable.ResultId.Value]; currentShader!.Variables.Add(variableName, i.ResultId!.Value); } - if (i.OpCode == SDSLOp.OpSDSLImportShader) + if (i.OpCode == Op.OpSDSLImportShader) { var importShader = i.UnsafeAs(); @@ -384,7 +384,7 @@ public static void MergeSDSL() SetOpNop(i.Words); } - else if (i.OpCode == SDSLOp.OpSDSLImportVariable) + else if (i.OpCode == Op.OpSDSLImportVariable) { var importVariable = i.UnsafeAs(); var importedShader = importedShaders[importVariable.Shader]; @@ -395,7 +395,7 @@ public static void MergeSDSL() SetOpNop(i.Words); } - else if (i.OpCode == SDSLOp.OpSDSLImportFunction) + else if (i.OpCode == Op.OpSDSLImportFunction) { var importFunction = i.UnsafeAs(); @@ -432,7 +432,7 @@ public static void MergeSDSL() ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); foreach (var i in temp.Instructions) { - if (i.OpCode == SDSLOp.OpFunction) + if (i.OpCode == Op.OpFunction) { var function = i.UnsafeAs(); var functionName = names2[i.ResultId.Value]; @@ -454,7 +454,7 @@ public static void MergeSDSL() temp.Instructions.AddRange(context.Buffer.Instructions); new TypeDuplicateRemover().Apply(temp); - temp.Instructions.RemoveAll(x => x.OpCode == SDSLOp.OpNop); + temp.Instructions.RemoveAll(x => x.OpCode == Op.OpNop); var dis = new SpirvDis(temp, true); var source = dis.Disassemble(true); @@ -498,7 +498,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri var shaderMapping = new Dictionary(); foreach (var i in buffer.Instructions) { - if (i.OpCode == SDSLOp.OpSDSLImportShader) + if (i.OpCode == Op.OpSDSLImportShader) { shaderMapping[i.ResultId!.Value] = i.GetOperand("shaderName")!.Value.Value; } @@ -507,7 +507,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri // Check inheritance foreach (var i in buffer.Instructions) { - if (i.OpCode == SDSLOp.OpSDSLMixinInherit) + if (i.OpCode == Op.OpSDSLMixinInherit) { var shaderName = shaderMapping[i.Words[1]]; var shader = GetOrLoadShader(shaderName); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 526861e824..39dff536dd 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -4,6 +4,7 @@ using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Spirv.Core.Parsing; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Buffers; @@ -11,14 +12,14 @@ namespace Stride.Shaders.Spirv.Core.Buffers; public interface IMemoryInstruction { OpDataIndex? DataIndex { get; set; } - MemoryOwner Memory { get; } - public void UpdateMemory(); + MemoryOwner InstructionMemory { get; } + public void UpdateInstructionMemory(); } -public struct OpData : IDisposable +public struct OpData : IDisposable, IComparable { public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } - public readonly SDSLOp Op => (SDSLOp)(Memory.Span[0] & 0xFFFF); + public readonly Op Op => (Op)(Memory.Span[0] & 0xFFFF); public OpData() { @@ -54,6 +55,13 @@ public readonly T GetEnum(string name) } public readonly OpDataEnumerator GetEnumerator() => new(Memory.Span); + + public readonly int CompareTo(OpData other) + { + var group = InstructionInfo.GetGroupOrder(this); + var otherGroup = InstructionInfo.GetGroupOrder(other); + return group.CompareTo(otherGroup); + } } @@ -72,18 +80,29 @@ public class NewSpirvBuffer public void Add(OpData data) => Memory.Add(data); - public void Add(ref T instruction) where T : IMemoryInstruction + public void AddRef(ref T instruction) where T : IMemoryInstruction { if (instruction.DataIndex is OpDataIndex odi) { if (odi.Buffer == this) return; else - Memory.Add(new(instruction.Memory)); + Memory.Add(new(instruction.InstructionMemory)); } - else Memory.Add(new(instruction.Memory)); + else Memory.Add(new(instruction.InstructionMemory)); instruction.DataIndex = new(Memory.Count - 1, this); - + + } + public void Add(in T instruction) where T : IMemoryInstruction + { + if (instruction.DataIndex is OpDataIndex odi) + { + if (odi.Buffer == this) + return; + else + Memory.Add(new(instruction.InstructionMemory)); + } + else Memory.Add(new(instruction.InstructionMemory)); } public void Insert(int index, OpData data) @@ -124,4 +143,9 @@ public bool MoveNext() return false; } } + + public void Sort() + { + Memory.Sort(static (a, b) => a.CompareTo(b)); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index ff43e69bfc..6ca6a89a95 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -12,14 +12,14 @@ namespace Stride.Shaders.Spirv.Core.Buffers; /// public class SpirvBuffer : IMutSpirvBuffer { - private SpirvHeader header = new SpirvHeader + private SpirvHeader header = new() { VersionNumber = new(1, 3), - MagicNumber = Spv.Specification.MagicNumber, + MagicNumber = Specification.MagicNumber, }; private ArrayPool pool = ArrayPool.Shared; - public List Instructions { get; } = new(); + public List Instructions { get; } = []; public Span InstructionsSpan => Instructions.AsSpan(); diff --git a/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs index 0817375e33..04a948d31e 100644 --- a/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs +++ b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs @@ -3,174 +3,8 @@ namespace Stride.Shaders.Spirv.Core; -public interface ISpirvElement +public interface ISpirvElement : IDisposable { + MemoryOwner Words { get; } public int WordCount { get; } - public SpanOwner AsSpanOwner(); -} - -public static class ISpirvElementExtensions -{ - - internal static SpanOwner AsSpanOwner(this string? value) - { - if (value is null) - return SpanOwner.Empty; - else - { - var lit = new LiteralString(value); - var span = SpanOwner.Allocate(lit.WordCount, AllocationMode.Clear); - lit.WriteTo(span.Span); - return span; - } - } - - internal static SpanOwner AsSpanOwner(this T value) - where T : struct - { - if (value is ISpirvElement element) - return element.AsSpanOwner(); - else - return value switch - { - byte v => new LiteralInteger(v).AsSpanOwner(), - sbyte v => new LiteralInteger(v).AsSpanOwner(), - ushort v => new LiteralInteger(v).AsSpanOwner(), - short v => new LiteralInteger(v).AsSpanOwner(), - uint v => new LiteralInteger(v).AsSpanOwner(), - int v => new LiteralInteger(v).AsSpanOwner(), - long v => new LiteralInteger(v).AsSpanOwner(), - ulong v => new LiteralInteger(v).AsSpanOwner(), - Half v => new LiteralFloat(v).AsSpanOwner(), - float v => new LiteralFloat(v).AsSpanOwner(), - double v => new LiteralFloat(v).AsSpanOwner(), - Enum e => new LiteralInteger(Convert.ToInt32(e)).AsSpanOwner(), - _ => throw new NotImplementedException() - }; - - } - - internal static SpanOwner AsSpanOwner(this T? value) - where T : struct - { - if (value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); - - } - - internal static SpanOwner AsSpanOwner(this Span values) - { - - int length = 0; - foreach (var value in values) - { - length += value switch - { - byte - or sbyte - or ushort - or short - or uint - or int - or Half - or float - or Enum => 1, - long - or ulong - or double => 2, - ISpirvElement element => element.WordCount, - _ => throw new NotImplementedException() - }; - } - var span = SpanOwner.Allocate(length); - length = 0; - for (int i = 0; i < values.Length; i++) - { - if(values[i] is ISpirvElement element) - { - element.AsSpanOwner().Span.CopyTo(span.Span[length..]); - length += element.WordCount; - } - else if(values[i] is byte vb) - { - span.Span[i] = vb; - length += 1; - } - else if(values[i] is sbyte vsb) - { - span.Span[i] = vsb; - length += 1; - } - else if(values[i] is short vsh) - { - span.Span[i] = vsh; - length += 1; - } - else if(values[i] is ushort vush) - { - span.Span[i] = vush; - length += 1; - } - else if(values[i] is Half vh) - { - span.Span[i] = (int)(new LiteralFloat(vh).Words & 0xFFFFFFFF); - length += 1; - } - else if(values[i] is float vf) - { - span.Span[i] = (int)(new LiteralFloat(vf).Words & 0xFFFFFFFF); - length += 1; - } - else if(values[i] is int vi) - { - span.Span[i] = vi; - length += 1; - } - else if(values[i] is Enum e) - { - span.Span[i] = Convert.ToInt32(e); - length += 1; - } - else if(values[i] is uint vui) - { - span.Span[i] = (int)vui; - length += 1; - } - else if(values[i] is double vd) - { - new LiteralFloat(vd).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); - length += 1; - } - else if(values[i] is long vl) - { - new LiteralInteger(vl).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); - length += 1; - } - else if(values[i] is ulong vul) - { - new LiteralInteger(vul).AsSpanOwner().Span.CopyTo(span.Span[i..(i+1)]); - length += 1; - } - else throw new NotImplementedException(); - } - return span; - } - - - internal static Span AsSpirvSpan(this T? value) - where T : struct - => value.AsSpanOwner().Span; - - internal static Span AsSpirvSpan(this T value) - where T : struct - => value.AsSpanOwner().Span; - - internal static Span AsSpirvSpan(this string? value) - => value.AsSpanOwner().Span; - - - internal static Span AsSpirvSpan(this Span values) - => values.AsSpanOwner().Span; } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 0464503874..9c4c660484 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -15,78 +15,78 @@ namespace Stride.Shaders.Spirv.Core; ///
public partial class InstructionInfo { - Dictionary<(SDSLOp, StorageClass?), int> OrderGroup = new(); + Dictionary<(Op, StorageClass?), int> OrderGroup = new(); - public static ImmutableArray SDSLOperators { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().Contains("SDSL")).ToArray()); - public static ImmutableArray OpTypes { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().StartsWith("OpType")).ToArray()); + public static ImmutableArray SDSLOperators { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().Contains("SDSL")).ToArray()); + public static ImmutableArray OpTypes { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().StartsWith("OpType")).ToArray()); void InitOrder() { int group = 0; - Span initSDSL = [ - SDSLOp.OpNop, - SDSLOp.OpSDSLShader, - SDSLOp.OpCapability, - SDSLOp.OpSDSLMixinInherit, - SDSLOp.OpSDSLCompose + Span initSDSL = [ + Op.OpNop, + Op.OpSDSLShader, + Op.OpCapability, + Op.OpSDSLMixinInherit, + Op.OpSDSLCompose ]; - foreach(var e in initSDSL) + foreach (var e in initSDSL) OrderGroup[(e, null)] = group; - + group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpSDSLImport"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpSDSLImport"))) OrderGroup[(e, null)] = group; - OrderGroup[(SDSLOp.OpExtension, null)] = group; + OrderGroup[(Op.OpExtension, null)] = group; group++; - OrderGroup[(SDSLOp.OpExtInstImport, null)] = group; + OrderGroup[(Op.OpExtInstImport, null)] = group; group++; - OrderGroup[(SDSLOp.OpMemoryModel, null)] = group; + OrderGroup[(Op.OpMemoryModel, null)] = group; group++; - OrderGroup[(SDSLOp.OpEntryPoint, null)] = group; + OrderGroup[(Op.OpEntryPoint, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpExecutionMode"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpExecutionMode"))) OrderGroup[(e, null)] = group; group++; - Span opDebugSource = [SDSLOp.OpString, SDSLOp.OpSource, SDSLOp.OpSourceExtension, SDSLOp.OpSourceContinued]; + Span opDebugSource = [Op.OpString, Op.OpSource, Op.OpSourceExtension, Op.OpSourceContinued]; foreach (var e in opDebugSource) OrderGroup[(e, null)] = group; group++; - OrderGroup[(SDSLOp.OpName, null)] = group; - OrderGroup[(SDSLOp.OpMemberName, null)] = group; + OrderGroup[(Op.OpName, null)] = group; + OrderGroup[(Op.OpMemberName, null)] = group; group++; - OrderGroup[(SDSLOp.OpModuleProcessed, null)] = group; + OrderGroup[(Op.OpModuleProcessed, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpDecorate"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpDecorate"))) OrderGroup[(e, null)] = group; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpMemberDecorate"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpMemberDecorate"))) OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) OrderGroup[(e, null)] = group; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) - OrderGroup[(SDSLOp.OpVariable, e)] = group; + OrderGroup[(Op.OpVariable, e)] = group; - OrderGroup[(SDSLOp.OpUndef, null)] = group; + OrderGroup[(Op.OpUndef, null)] = group; group++; - OrderGroup[(SDSLOp.OpLine, null)] = group; - OrderGroup[(SDSLOp.OpNoLine, null)] = group; + OrderGroup[(Op.OpLine, null)] = group; + OrderGroup[(Op.OpNoLine, null)] = group; group++; group++; - foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) + foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) OrderGroup[(e, null)] = group; - OrderGroup[(SDSLOp.OpVariable, StorageClass.Function)] = group; + OrderGroup[(Op.OpVariable, StorageClass.Function)] = group; group++; - OrderGroup[(SDSLOp.OpSDSLShaderEnd, null)] = group; + OrderGroup[(Op.OpSDSLShaderEnd, null)] = group; } /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. @@ -95,16 +95,20 @@ void InitOrder() /// public static int GetGroupOrder(Instruction instruction) { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); + return GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable ? (StorageClass)instruction.Words[3] : null); + } + public static int GetGroupOrder(Buffers.OpData instruction) + { + return GetGroupOrder(instruction.Op, instruction.Op == Op.OpVariable ? (StorageClass)instruction.Memory.Span[3] : null); } - + /// /// Gets the order group for a given instruction and Storage class, useful for sorting instructions according to the specification. /// /// /// /// - public static int GetGroupOrder(SDSLOp op, StorageClass? sc = null) + public static int GetGroupOrder(Op op, StorageClass? sc = null) { return Instance.OrderGroup[(op, sc)]; } diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index 0001a59b04..1eb8887aa0 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -8,9 +8,9 @@ namespace Stride.Shaders.Spirv.Core; -public record struct OperandKey(SDSLOp Op, Decoration? Decoration = null) +public record struct OperandKey(Op Op, Decoration? Decoration = null) { - public static implicit operator OperandKey(SDSLOp op) => new(op); + public static implicit operator OperandKey(Op op) => new(op); } @@ -23,55 +23,55 @@ public partial class InstructionInfo readonly Dictionary Info = []; InstructionInfo() { - Info.Add(new(SDSLOp.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); - Info.Add(new(SDSLOp.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(Op.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); + Info.Add(new(Op.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); + Info.Add(new(Op.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); + Info.Add(new(Op.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); + Info.Add(new(Op.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); + Info.Add(new(Op.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); + Info.Add(new(Op.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); + Info.Add(new(Op.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); + Info.Add(new(Op.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); + Info.Add(new(Op.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); + Info.Add(new(Op.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); + Info.Add(new(Op.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); + Info.Add(new(Op.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); + Info.Add(new(Op.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); + Info.Add(new(Op.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); + Info.Add(new(Op.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); + Info.Add(new(Op.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); + Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); + Info.Add(new(Op.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); + Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); + Info.Add(new(Op.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); + Info.Add(new(Op.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); + Info.Add(new(Op.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); + Info.Add(new(Op.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); - Info.Add(new(SDSLOp.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(SDSLOp.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); + Info.Add(new(Op.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); } /// @@ -104,11 +104,11 @@ public static LogicalOperandArray GetInfo(Instruction instruction) { Decoration? decoration = instruction.OpCode switch { - SDSLOp.OpDecorateString - or SDSLOp.OpDecorate - or SDSLOp.OpDecorateId => (Decoration)instruction.Operands[1], - SDSLOp.OpMemberDecorate - or SDSLOp.OpMemberDecorateString => (Decoration)instruction.Operands[2], + Op.OpDecorateString + or Op.OpDecorate + or Op.OpDecorateId => (Decoration)instruction.Operands[1], + Op.OpMemberDecorate + or Op.OpMemberDecorateString => (Decoration)instruction.Operands[2], _ => null }; return GetInfo(new OperandKey(instruction.OpCode, decoration)); diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs new file mode 100644 index 0000000000..9cc34152bb --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -0,0 +1,108 @@ +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + + +public static class LiteralArrayHelper +{ + public static LiteralArray Create(ReadOnlySpan elements) + where T : struct, ISpirvElement, IFromSpirv + { + return new LiteralArray(elements); + } +} + +[CollectionBuilder(typeof(LiteralArrayHelper), "Create")] +public struct LiteralArray : ISpirvElement, IFromSpirv>, IDisposable + where T : struct, ISpirvElement, IFromSpirv +{ + + MemoryOwner Words { get; set { field.Dispose(); field = value; } } + public readonly int WordCount => Words.Length; + + public LiteralArray(ReadOnlySpan words) + { + Words = MemoryOwner.Allocate(words.Length); + words.CopyTo(Words.Span); + } + + public void Assign(LiteralArray owner) + { + Words.Dispose(); + Words = owner.Words; + } + public void Assign(MemoryOwner owner) + { + Words.Dispose(); + Words = owner; + } + + public void Assign(Memory span) + { + Words.Dispose(); + Words = MemoryOwner.Allocate(span.Length); + span.CopyTo(Words.Memory); + } + + public void Assign(Span span) + { + Words.Dispose(); + Words = MemoryOwner.Allocate(span.Length); + span.CopyTo(Words.Span); + } + + public static LiteralArray From(Span words) + { + T tmp = default; + if (tmp is IdRef or IdResult or IdResultType or IdScope or LiteralInteger) + { + using var owner = SpanOwner.Allocate(words.Length, AllocationMode.Clear); + for (int i = 0; i < words.Length; i++) + owner.Span[i] = T.From([words[i]]); + return new LiteralArray(owner.Span); + } + else if (tmp is PairIdRefIdRef or PairIdRefLiteralInteger or PairLiteralIntegerIdRef) + { + using var owner = SpanOwner.Allocate(words.Length / 2, AllocationMode.Clear); + for (int i = 0; i < words.Length; i += 2) + owner.Span[i / 2] = T.From([words[i], words[i + 1]]); + return new LiteralArray(owner.Span); + } + else throw new NotImplementedException($"Can't process type {typeof(T).FullName}"); + } + + public static LiteralArray From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + T tmp = default; + if (tmp is IdRef or IdResult or IdResultType or IdScope or LiteralInteger) + { + var owner = SpanOwner.Allocate(Words.Length, AllocationMode.Clear); + for (int i = 0; i < Words.Length; i++) + owner.Span[i] = Words.Span[i].AsSpirvSpan()[0]; + return owner; + } + else if (tmp is PairIdRefIdRef or PairIdRefLiteralInteger or PairLiteralIntegerIdRef) + { + using var owner = SpanOwner.Allocate(Words.Length * 2, AllocationMode.Clear); + for (int i = 0; i < Words.Length; i += 2) + { + owner.Span[i] = Words.Span[i].AsSpirvSpan()[0]; + owner.Span[i + 1] = Words.Span[i].AsSpirvSpan()[1]; + } + return owner; + } + else throw new NotImplementedException($"Can't process type {typeof(T).FullName}"); + } + public readonly void Dispose() => Words.Dispose(); + + public readonly Span.Enumerator GetEnumerator() => Words.Span.GetEnumerator(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs index 124872a70c..4b6422b134 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -53,6 +53,8 @@ public LiteralFloat(Span words) public static implicit operator LiteralFloat(float value) => new(value); public static implicit operator LiteralFloat(double value) => new(value); public static implicit operator LiteralInteger(LiteralFloat value) => new(value.Words); + public static implicit operator float(LiteralFloat value) => BitConverter.Int32BitsToSingle((int)value.Words); + public static implicit operator double(LiteralFloat value) => BitConverter.Int64BitsToDouble(value.Words); diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs index 754793ee2a..3850cae8ce 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs @@ -4,7 +4,6 @@ namespace Stride.Shaders.Spirv.Core; - public struct LiteralInteger : ILiteralNumber, IFromSpirv { public long Words { get; init; } @@ -85,6 +84,7 @@ public LiteralInteger(Span value) public static implicit operator LiteralInteger(uint value) => new(value); public static implicit operator LiteralInteger(long value) => new(value); public static implicit operator LiteralInteger(ulong value) => new(value); + public static implicit operator int(LiteralInteger value) => (int)value.Words; public readonly void Write(ref SpirvWriter writer) { @@ -121,3 +121,119 @@ public readonly SpanOwner AsSpanOwner() } + +public struct LiteralExtInstInteger : ILiteralNumber, IFromSpirv +{ + public long Words { get; init; } + public int Size { get; init; } + public readonly int WordCount => Size / 32; + + public LiteralExtInstInteger(sbyte value) + { + Words = 0 | value; + Size = sizeof(sbyte) * 8; + } + public LiteralExtInstInteger(byte value) + { + Words = 0 | value; + Size = sizeof(byte) * 8; + } + + public LiteralExtInstInteger(short value) + { + Words = 0 | value; + Size = sizeof(short) * 8; + } + public LiteralExtInstInteger(ushort value) + { + Words = 0 | value; + Size = sizeof(ushort) * 8; + } + + public LiteralExtInstInteger(int value) + { + Words = 0 | value; + Size = sizeof(int) * 8; + } + public LiteralExtInstInteger(int? value) + { + Words = 0 | value ?? 0; + Size = sizeof(int) * 8; + } + public LiteralExtInstInteger(uint value) + { + Words = 0 | value; + Size = sizeof(uint) * 8; + + } + public LiteralExtInstInteger(long value) + { + Words = 0 | value; + Size = sizeof(long) * 8; + } + public LiteralExtInstInteger(ulong value) + { + Words = (long)value; + Size = sizeof(ulong) * 8; + + } + + public LiteralExtInstInteger(Span value) + { + if (value.Length == 2) + { + Size = sizeof(long) * 8; + Words = value[0] << 32 | value[1]; + } + else if (value.Length == 1) + { + Size = sizeof(int) * 8; + Words = value[0]; + } + } + + + public static implicit operator LiteralExtInstInteger(byte value) => new(value); + public static implicit operator LiteralExtInstInteger(sbyte value) => new(value); + public static implicit operator LiteralExtInstInteger(ushort value) => new(value); + public static implicit operator LiteralExtInstInteger(short value) => new(value); + public static implicit operator LiteralExtInstInteger(int value) => new(value); + public static implicit operator LiteralExtInstInteger(int? value) => new(value); + public static implicit operator LiteralExtInstInteger(uint value) => new(value); + public static implicit operator LiteralExtInstInteger(long value) => new(value); + public static implicit operator LiteralExtInstInteger(ulong value) => new(value); + public static implicit operator int(LiteralExtInstInteger value) => (int)value.Words; + + public readonly void Write(ref SpirvWriter writer) + { + Span span = + [ + (int)(Words >> 32), + (int)(Words & 0X000000FF) + ]; + if (Size < 64) + writer.Write(span[1]); + else + writer.Write(span); + } + + public static LiteralExtInstInteger From(Span words) + { + return new(words); + } + + public static LiteralExtInstInteger From(string value) + { + throw new NotImplementedException(); + } + + public readonly SpanOwner AsSpanOwner() + { + Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; + var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); + span.CopyTo(owner.Span); + return owner; + } + + public override readonly string ToString() => $"{Words}"; +} diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs new file mode 100644 index 0000000000..4694f9c56d --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -0,0 +1,104 @@ +using System.Numerics; +using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + + +public struct LiteralValue : ISpirvElement, IFromSpirv> +{ + static LiteralValue() + { + LiteralValue v = default; + _ = v switch + { + LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue + or LiteralValue => true, + + _ => throw new Exception("Type not supported in SPIR-V") + }; + } + public MemoryOwner Words { get; private set; } + public T Value { get; set { field = value; UpdateMemory(); } } + public readonly int WordCount => Words.Length; + + public LiteralValue(T value) + { + Value = value; + Words = MemoryOwner.Empty; + } + + void UpdateMemory() + { + int wordCount = Value switch + { + bool or byte or sbyte or short or ushort or Half or int or uint or float => 1, + long or ulong or double => 2, + string => throw new NotImplementedException("Can't compute string literal value yet"), + _ => throw new NotImplementedException() + }; + Words.Dispose(); + Words = MemoryOwner.Allocate(wordCount, AllocationMode.Clear); + if (Value is bool or byte or sbyte or short or ushort or Half or int or uint or float) + { + Words.Span[0] = Value switch + { + bool b => b ? 1 : 0, + byte b => b, + sbyte b => b, + short s => s, + ushort s => s, + // Half h => h, + int i => i, + uint i => (int)i, + float f => BitConverter.SingleToInt32Bits(f), + _ => throw new NotImplementedException() + }; + } + else if (Value is long or double) + { + Words.Span[0] = Value switch + { + long l => (int)(l >> 16), + double d => (int)BitConverter.DoubleToInt64Bits(d) >> 16, + _ => throw new NotImplementedException() + }; + Words.Span[1] = Value switch + { + long l => (int)(l & 0xFFFFFFFF), + double d => (int)(BitConverter.DoubleToInt64Bits(d) & 0xFFFFFFFF), + _ => throw new NotImplementedException() + }; + } + else if (Value is string) + { + throw new NotImplementedException("Can't process strings yet"); + } + } + + public static LiteralValue From(Span words) + { + throw new NotImplementedException(); + } + + public static LiteralValue From(string value) + { + throw new NotImplementedException(); + } + + public readonly void Dispose() => Words.Dispose(); + + public static implicit operator LiteralValue(T s) => new(s); + public static implicit operator T(LiteralValue lv) => lv.Value; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index 02adf50169..bb39798e0f 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -1,6 +1,7 @@ using System.Runtime.CompilerServices; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; @@ -18,7 +19,7 @@ public record struct Instruction(Memory Memory) public static implicit operator IdResultType(Instruction i) => new(i.ResultId ?? throw new Exception("Instruction has no result id")); - public readonly SDSLOp OpCode => (SDSLOp)(Words[0] & 0xFFFF); + public readonly Op OpCode => (Op)(Words[0] & 0xFFFF); public int? ResultId { get => GetResultId(); set => SetResultId(value); } public int? ResultType { get => GetResultType(); set => SetResultType(value); } public readonly int WordCount => Words.Length; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index c3707930c6..fe8e29f8cc 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -10,7 +10,7 @@ public ref struct OpDataEnumerator static readonly OperandKind[] pairs = [.. Enum.GetValues().Where(x => x.ToString().StartsWith("Pair"))]; readonly Span instruction; readonly Span Operands => instruction[1..]; - readonly SDSLOp OpCode => (SDSLOp)(instruction[0] & 0xFFFF); + readonly Op OpCode => (Op)(instruction[0] & 0xFFFF); readonly LogicalOperandArray logicalOperands; int wid; int oid; @@ -39,7 +39,7 @@ public bool MoveNext() var logOp = logicalOperands[oid]; - if (OpCode == SDSLOp.OpDecorate) + if (OpCode == Op.OpDecorate) { if (oid == 0) { @@ -162,7 +162,7 @@ public bool MoveNext() public SpvOperand ParseCurrent() { var logOp = logicalOperands[oid]; - if (OpCode == SDSLOp.OpDecorate) + if (OpCode == Op.OpDecorate) { SpvOperand result = new(); if (oid == 0) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 8d22f7d488..48ce306aad 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -81,6 +81,6 @@ public bool MoveNext() readonly int GetGroupOrder(Instruction instruction) { - return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == SDSLOp.OpVariable ? (StorageClass)instruction.Words[3] : null); + return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable ? (StorageClass)instruction.Words[3] : null); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs index 67f57f6fc2..b81c0e60d4 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs @@ -21,6 +21,6 @@ public RefHeader(Span words) Words = words; } - public bool IsValidMagic => MagicNumber == Spv.Specification.MagicNumber; + public bool IsValidMagic => MagicNumber == Stride.Shaders.Spirv.Specification.MagicNumber; } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index bee3c49566..ced050a6cb 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -51,7 +51,7 @@ public readonly struct SpirvHeader public SpirvHeader(string version, int generator, int bound, int schema = 0) { - MagicNumber = Spv.Specification.MagicNumber; + MagicNumber = Specification.MagicNumber; VersionNumber = version; GeneratorMagicNumber = generator; Bound = bound; @@ -59,7 +59,7 @@ public SpirvHeader(string version, int generator, int bound, int schema = 0) } public SpirvHeader(SpirvVersion version, int generator, int bound, int schema = 0) { - MagicNumber = Spv.Specification.MagicNumber; + MagicNumber = Specification.MagicNumber; VersionNumber = version; GeneratorMagicNumber = generator; Bound = bound; @@ -87,6 +87,6 @@ public static SpirvHeader Read(Span words) }; } - public bool IsValidMagic => MagicNumber == Spv.Specification.MagicNumber; + public bool IsValidMagic => MagicNumber == Specification.MagicNumber; } diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index bc024e5d46..04fd7e9c0a 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -58,30 +58,30 @@ public override string ToString() OperandKind.IdRef => $"%{Words[0] + Offset}", OperandKind.IdResultType => $"%{Words[0] + Offset}", OperandKind.PairLiteralIntegerIdRef => $"{Words[0]} %{Words[0] + Offset}", - OperandKind.MemoryAccess => $"{ToEnum()}", - OperandKind.MemoryModel => $"{ToEnum()}", - OperandKind.MemorySemantics => $"{ToEnum()}", - OperandKind.AccessQualifier => $"{ToEnum()}", - OperandKind.AddressingModel => $"{ToEnum()}", - OperandKind.BuiltIn => $"{ToEnum()}", - OperandKind.Capability => $"{ToEnum()}", - OperandKind.Decoration => $"{ToEnum()}", - OperandKind.Dim => $"{ToEnum()}", - OperandKind.ExecutionMode => $"{ToEnum()}", - OperandKind.ExecutionModel => $"{ToEnum()}", - OperandKind.FPFastMathMode => $"{ToEnum()}", - OperandKind.FPRoundingMode => $"{ToEnum()}", - OperandKind.FragmentShadingRate => $"{ToEnum()}", - OperandKind.FunctionControl => $"{ToEnum()}", - OperandKind.FunctionParameterAttribute => $"{ToEnum()}", - OperandKind.GroupOperation => $"{ToEnum()}", - OperandKind.ImageChannelDataType => $"{ToEnum()}", - OperandKind.ImageChannelOrder => $"{ToEnum()}", - OperandKind.ImageFormat => $"{ToEnum()}", - OperandKind.ImageOperands => $"{ToEnum()}", - OperandKind.KernelEnqueueFlags => $"{ToEnum()}", - OperandKind.KernelProfilingInfo => $"{ToEnum()}", - OperandKind.LinkageType => $"{ToEnum()}", + OperandKind.MemoryAccess => $"{ToEnum()}", + OperandKind.MemoryModel => $"{ToEnum()}", + OperandKind.MemorySemantics => $"{ToEnum()}", + OperandKind.AccessQualifier => $"{ToEnum()}", + OperandKind.AddressingModel => $"{ToEnum()}", + OperandKind.BuiltIn => $"{ToEnum()}", + OperandKind.Capability => $"{ToEnum()}", + OperandKind.Decoration => $"{ToEnum()}", + OperandKind.Dim => $"{ToEnum()}", + OperandKind.ExecutionMode => $"{ToEnum()}", + OperandKind.ExecutionModel => $"{ToEnum()}", + OperandKind.FPFastMathMode => $"{ToEnum()}", + OperandKind.FPRoundingMode => $"{ToEnum()}", + OperandKind.FragmentShadingRate => $"{ToEnum()}", + OperandKind.FunctionControl => $"{ToEnum()}", + OperandKind.FunctionParameterAttribute => $"{ToEnum()}", + OperandKind.GroupOperation => $"{ToEnum()}", + OperandKind.ImageChannelDataType => $"{ToEnum()}", + OperandKind.ImageChannelOrder => $"{ToEnum()}", + OperandKind.ImageFormat => $"{ToEnum()}", + OperandKind.ImageOperands => $"{ToEnum()}", + OperandKind.KernelEnqueueFlags => $"{ToEnum()}", + OperandKind.KernelProfilingInfo => $"{ToEnum()}", + OperandKind.LinkageType => $"{ToEnum()}", OperandKind.None => "", _ => Words[0].ToString() }; diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 367e09462c..61e31fa4fb 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index b901345e9b..1bd685e3b0 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -14,7 +14,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("public static Instruction AddOpConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") .AppendLine("}"); @@ -24,7 +24,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("public static Instruction InsertOpConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") .AppendLine("}"); @@ -36,7 +36,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") .AppendLine("}"); code.AppendLine(op.Documentation); code @@ -44,7 +44,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") .AppendLine("}"); } else if (opname!.StartsWith("OpDecorate")) @@ -54,7 +54,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -63,7 +63,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); } @@ -74,7 +74,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -83,7 +83,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") .AppendLine("}"); } @@ -115,7 +115,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti ; code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); code - .AppendLine($"return buffer.Add([wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine($"return buffer.Add([wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") .AppendLine("}"); @@ -135,7 +135,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti ; code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); code - .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)SDSLOp.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") .AppendLine("}"); } else @@ -146,7 +146,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("(this SpirvBuffer buffer)") .AppendLine("{") - .AppendLine($"return buffer.Add([1 << 16 | (int)SDSLOp.{opname}]);") + .AppendLine($"return buffer.Add([1 << 16 | (int)Op.{opname}]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -155,7 +155,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .Append(opname) .AppendLine("(this SpirvBuffer buffer, int position)") .AppendLine("{") - .AppendLine($"return buffer.Insert(position, [1 << 16 | (int)SDSLOp.{opname}]);") + .AppendLine($"return buffer.Insert(position, [1 << 16 | (int)Op.{opname}]);") .AppendLine("}"); } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index e8b5555f45..462d78b2e9 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -119,11 +119,11 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) var spvClass = op.Class; if (opname == "OpExtInst") { - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); - code.AppendLine("Instance.Register(SDSLOp.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); + code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); + code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); + code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); + code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); + code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); } else if (op.Operands is EquatableList operands) { @@ -138,7 +138,7 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) if (operand.Quantifier is string quant) { code - .Append("Instance.Register(SDSLOp.") + .Append("Instance.Register(Op.") .Append(opname) .Append(", OperandKind.") .Append(kind) @@ -152,7 +152,7 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) else { code - .Append("Instance.Register(SDSLOp.") + .Append("Instance.Register(Op.") .Append(opname) .Append(", OperandKind.") .Append(kind) @@ -167,7 +167,7 @@ public static void GenerateInfo(InstructionData op, StringBuilder code) } else { - code.Append("Instance.Register(SDSLOp.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); + code.Append("Instance.Register(Op.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); } } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index bf7f72a0c2..7d684e3b59 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -25,7 +25,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv { StringBuilder builder = new(); builder - .AppendLine("using static Spv.Specification;") + .AppendLine("using static Stride.Shaders.Spirv.Specification;") .AppendLine("using CommunityToolkit.HighPerformance;") .AppendLine("using CommunityToolkit.HighPerformance.Buffers;") .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") @@ -33,7 +33,6 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine() .AppendLine(); - StringBuilder body1 = new(); StringBuilder body2 = new(); StringBuilder body3 = new(); @@ -43,162 +42,220 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv foreach (var instruction in instructions) { - - - if (instruction.OpName.StartsWith("OpCopyMemory") || !instruction.OpName.StartsWith("OpType")) + if (instruction.OpName.StartsWith("OpCopyMemory")) continue; body1.Clear(); body2.Clear(); body3.Clear(); body4.Clear(); - - if (instruction.Operands?.AsList() is List operands) + if (instruction.OpName.Contains("Constant")) { - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;") - .AppendLine("foreach (var o in index.Buffer[index.Index])") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{x.Kind} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); + // foreach(var types in ["LiteralInteger", "LiteralFloat", "LiteralBool"]) + // builder.AppendLine($@" + // public struct {instruction.OpName}<{}> - // Body 1 - foreach (var operand in operands) - { - - (string type, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - body1.Append($"public {operand.Kind} {fieldName} {{ get; set {{ field = value; UpdateMemory(); }} }}"); + // "); + continue; + } + else if (instruction.OpName.Contains("GLSL")) + { + var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); + + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) + { + var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", allOperands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + if (allOperands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator IdRef({instruction.OpName} inst) => new IdRef(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + body1.AppendLine($"public int Instruction => {instruction.OpCode};"); + foreach (var operand in allOperands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray")) + body2.AppendLine($"{fieldName} = o.To>();"); + else body2.AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + body2.AppendLine("}"); + + body3.AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .Append($"Span instruction = [(int)SDSLOp.{extinst.OpName}, ") + .Append(string.Join(", ", extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" }).Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $".. {fieldName}.AsSpirvSpan()"; + }))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + body2.AppendLine("}"); - // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")") - .AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}>();"); - // Body 3 - body3.AppendLine($"{fieldName} = {operandName};"); } - body2.AppendLine("}\n}"); - - body3.AppendLine("UpdateMemory();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateMemory()") - .AppendLine("{") - .Append($"Span instruction = [(int)SDSLOp.{instruction.OpName}, ") - .Append(string.Join(", ", operands.Select(x => + else { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $".. {fieldName}.AsSpirvSpan()"; - }))) - .Append("];") - .AppendLine(@" + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + + if (instruction.Operands?.AsList() is List operands) + { + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + + if (operands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator IdRef({instruction.OpName} inst) => new IdRef(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + foreach (var operand in operands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray")) + body2.AppendLine($"{fieldName} = o.To>();"); + else body2.AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + body2.AppendLine("}"); + + body3.AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .Append($"Span instruction = [(int)SDSLOp.{instruction.OpName}, ") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $".. {fieldName}.AsSpirvSpan()"; + }))) + .Append("];") + .AppendLine(@" instruction[0] |= instruction.Length << 16; - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - Memory?.Dispose(); - Memory = tmp;" - ) - .AppendLine("}"); - - } + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + else + body4.AppendLine("public void UpdateInstructionMemory(){}"); + body2.AppendLine("}"); + } builder.AppendLine($@" -public struct {instruction.OpName} : IMemoryInstruction -{{ - public OpDataIndex? DataIndex {{ get; set; }} - public MemoryOwner Memory - {{ - readonly get - {{ - if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; - else return field; - }} - - private set - {{ - if (DataIndex is OpDataIndex odi) - {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; - }} - else field = value; - }} - }} - - {body1} - {body2} - {body3} - {body4} - - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); -}} - - -"); - // builder.AppendLine($"public ref struct {instruction.OpName} : IWrapperInstruction") - // .AppendLine("{") - // .AppendLine("public RefInstruction Inner { get; set; }") - // .AppendLine("public int WordCount => Inner.WordCount;"); - // if (instruction.Operands.AsList() is List operands && operands.Count > 0) - // { - // foreach (var operand in operands) - // { - // string fieldName; - // string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - // if (operand.Name is null or "") - // fieldName = ConvertKindToName(operand.Kind, false); - // else - // { - // var nameBuilder = new StringBuilder(); - // bool first = true; - // foreach (var c in operand.Name) - // { - // if (char.IsLetterOrDigit(c) || c == '_') - // { - // nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - // first &= false; - // } - - // } - // fieldName = nameBuilder.ToString(); - // } - // if (operand.Kind == "LiteralContextDependentNumber") - // continue; - // else if (operand.Kind == "LiteralInteger" || operand.Kind == "LiteralExtInstInteger" || operand.Kind == "LiteralSpecConstantOpInteger") - // builder.AppendLine($"public LiteralInteger {fieldName} => Inner.GetOperand(\"{operandName}\") ?? default;"); - // else if (operand.Class == "BitEnum") - // builder.AppendLine($"public {operand.Kind}Mask {fieldName} => Inner.GetEnumOperand<{operand.Kind}Mask>(\"{operandName}\");"); - // else if (operand.Class == "ValueEnum") - // builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetEnumOperand<{operand.Kind}>(\"{operandName}\");"); - // else - // builder.AppendLine($"public {operand.Kind} {fieldName} => Inner.GetOperand<{operand.Kind}>(\"{operandName}\") ?? default;"); - // } - // } - - - // builder - // .AppendLine() - // .AppendLine($"public {instruction.OpName}(RefInstruction instruction) => Inner = instruction;") - // .AppendLine($"public {instruction.OpName}(Span buffer) => Inner = RefInstruction.ParseRef(buffer);") - // .AppendLine($"public static implicit operator IdRef({instruction.OpName} instruction) => new(instruction.Inner.ResultId ?? throw new Exception(\"Instruction has no result id\"));") - // .AppendLine($"public static implicit operator IdResultType({instruction.OpName} instruction) => new(instruction.Inner.ResultId ?? throw new Exception(\"Instruction has no result id\"));") - // .AppendLine($"public static implicit operator {instruction.OpName}(Span buffer) => new {instruction.OpName}(buffer);") - // .AppendLine($"public static implicit operator {instruction.OpName}(Instruction instruction) => new {instruction.OpName}(instruction.AsRef());") - // .AppendLine($"public static implicit operator {instruction.OpName}(RefInstruction instruction) => new {instruction.OpName}(instruction);"); - // builder.AppendLine("}"); - + public struct {instruction.OpName} : IMemoryInstruction + {{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner InstructionMemory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} + + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + }} + "); } } spc.AddSource( @@ -215,30 +272,36 @@ private set public static (string TypeName, string FieldName, string OperandName) ToTypeFieldAndOperandName(OperandData operand) { - string typename = (operand.Kind, operand.Quantifier) switch + string typename = (operand.Kind, operand.Quantifier, operand.Class) switch { // ("PairIdRefIdRef", null or "") => "(IdRef, IdRef)", // ("PairIdRefLiteralInteger", null or "") => "(IdRef, LiteralInteger)", // ("PairLiteralIntegerIdRef", null or "") => "(LiteralInteger, IdRef)", - (string s, null or "") when s.StartsWith("Id") => "int", - ("LiteralInteger", null or "") => "int", - ("LiteralFloat", null or "") => "float", - ("LiteralString", null or "") => "string", - (string s, null or "") when s.StartsWith("Pair") => "(int, int)", - (string s, null or "") when !s.StartsWith("Literal") => s, - (string s, "?") when s.StartsWith("Id") => "int?", - ("LiteralInteger", "?") => "int?", - ("LiteralFloat", "?") => "float?", - ("LiteralString", "?") => "string?", - (string s, "?") when !s.StartsWith("Literal") => $"{s}?", - (string s, "*") when s.StartsWith("Id") => "int?", - ("LiteralInteger", "*") => "int[]", - ("LiteralFloat", "*") => "float[]", - ("LiteralString", "*") => "string[]", - (string s, "*") when !s.StartsWith("Literal") => $"{s}?", - _ => throw new NotImplementedException($"Could not generate C# type for {operand.Kind}-{operand.Quantifier}") + (string s, null or "", _) when s.StartsWith("Id") => "int", + ("LiteralInteger", null or "", _) => "int", + ("LiteralExtInstInteger", null or "", _) => "int", + ("LiteralFloat", null or "", _) => "float", + ("LiteralString", null or "", _) => "LiteralString", + (string s, null or "", _) when s.StartsWith("Pair") => "(int, int)", + (string s, null or "", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask", + (string s, null or "", "ValueEnum") when !s.StartsWith("Literal") => s, + (string s, "?", _) when s.StartsWith("Id") => "int?", + ("LiteralInteger", "?", _) => "int?", + ("LiteralExtInstInteger", "?", _) => "int?", + ("LiteralFloat", "?", _) => "float?", + ("LiteralString", "?", _) => "LiteralString?", + (string s, "?", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask?", + (string s, "?", "ValueEnum") when !s.StartsWith("Literal") => $"{s}?", + (string s, "*", _) when s.StartsWith("Id") => $"LiteralArray<{s}>", + ("LiteralInteger", "*", _) => "LiteralArray", + ("LiteralExtInstInteger", "*", _) => "LiteralArray", + ("LiteralFloat", "*", _) => "LiteralArray", + ("LiteralString", "*", _) => "LiteralArray", + // (string s, "*") when !s.StartsWith("Literal") => $"LiteralArray<{s}>", + (string s, "*", _) when s.StartsWith("Pair") => $"LiteralArray<{s}>", + _ => throw new NotImplementedException($"Could not generate C# type for '{operand.Kind}{operand.Quantifier}'") }; diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 32bb932741..d3e378fe27 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Core; public abstract record SymbolType() { /// - /// Converts to an identifier compatible with . + /// Converts to an identifier compatible with . /// /// public virtual string ToId() => ToString(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 33ddf97a53..4a071f5d5e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System.Runtime.InteropServices; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -22,76 +23,77 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out Dictionary names, out Dictionary types) { var memberNames = new Dictionary<(int, int), string>(); - names = new Dictionary(); - types = new Dictionary(); - foreach (var instruction in buffer.Instructions) - { - if (instruction.OpCode == SDSLOp.OpName) - { - var nameInstruction = instruction.UnsafeAs(); - names.Add(nameInstruction.Target, nameInstruction.Name.Value); - } - else if (instruction.OpCode == SDSLOp.OpMemberName) - { - var nameInstruction = instruction.UnsafeAs(); - memberNames.Add((nameInstruction.Type, (int)nameInstruction.Member.Words), nameInstruction.Name.Value); - } - else if (instruction.OpCode == SDSLOp.OpTypeFloat) - { - var floatInstruction = instruction.UnsafeAs(); - //if (floatInstruction.FloatingPointEncoding != 0) - // throw new InvalidOperationException(); - - types.Add(floatInstruction.ResultId, floatInstruction.Width.Words switch - { - 16 => ScalarType.From("half"), - 32 => ScalarType.From("float"), - 64 => ScalarType.From("double"), - }); - } - else if (instruction.OpCode == SDSLOp.OpTypePointer) - { - var pointerInstruction = instruction.UnsafeAs(); - var innerType = types[pointerInstruction.Type]; - types.Add(instruction.ResultId!.Value, new PointerType(innerType, pointerInstruction.Storageclass)); - } - else if (instruction.OpCode == SDSLOp.OpTypeVoid) - { - types.Add(instruction.ResultId!.Value, ScalarType.From("void")); - } - else if (instruction.OpCode == SDSLOp.OpTypeVector) - { - var vectorInstruction = instruction.UnsafeAs(); - var innerType = (ScalarType)types[vectorInstruction.ComponentType]; - types.Add(instruction.ResultId!.Value, new VectorType(innerType, (int)vectorInstruction.ComponentCount.Words)); - } - else if (instruction.OpCode == SDSLOp.OpTypeStruct) - { - var typeStructInstruction = instruction.UnsafeAs(); - var structName = names[instruction.ResultId!.Value]; - var fieldsData = instruction.Memory.Span[2..]; - var fields = new List<(string Name, SymbolType Type)>(); - for (var index = 0; index < fieldsData.Length; index++) - { - var fieldData = fieldsData[index]; - var type = types[fieldData]; - var name = memberNames[(typeStructInstruction.ResultId.Value, index)]; - fields.Add((name, type)); - } - types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); - } - else if (instruction.OpCode == SDSLOp.OpTypeFunction) - { - var typeFunctionInstruction = instruction.UnsafeAs(); - var returnType = types[typeFunctionInstruction.ReturnType]; - var parameterTypes = new List(); - foreach (var operand in instruction.Operands[2..]) - { - parameterTypes.Add(types[operand]); - } - types.Add(instruction.ResultId!.Value, new FunctionType(returnType, parameterTypes)); - } - } + names = []; + types = []; + #warning uncomment + // foreach (var instruction in buffer.Instructions) + // { + // if (instruction.OpCode == Op.OpName) + // { + // var nameInstruction = instruction.UnsafeAs(); + // names.Add(nameInstruction.Target, nameInstruction.Name.Value); + // } + // else if (instruction.OpCode == Op.OpMemberName) + // { + // var nameInstruction = instruction.UnsafeAs(); + // memberNames.Add((nameInstruction.Type, (int)nameInstruction.Member.Words), nameInstruction.Name.Value); + // } + // else if (instruction.OpCode == Op.OpTypeFloat) + // { + // var floatInstruction = instruction.UnsafeAs(); + // //if (floatInstruction.FloatingPointEncoding != 0) + // // throw new InvalidOperationException(); + + // types.Add(floatInstruction.ResultId, floatInstruction.Width.Words switch + // { + // 16 => ScalarType.From("half"), + // 32 => ScalarType.From("float"), + // 64 => ScalarType.From("double"), + // }); + // } + // else if (instruction.OpCode == Op.OpTypePointer) + // { + // var pointerInstruction = instruction.UnsafeAs(); + // var innerType = types[pointerInstruction.Type]; + // types.Add(instruction.ResultId!.Value, new PointerType(innerType, pointerInstruction.Storageclass)); + // } + // else if (instruction.OpCode == Op.OpTypeVoid) + // { + // types.Add(instruction.ResultId!.Value, ScalarType.From("void")); + // } + // else if (instruction.OpCode == Op.OpTypeVector) + // { + // var vectorInstruction = instruction.UnsafeAs(); + // var innerType = (ScalarType)types[vectorInstruction.ComponentType]; + // types.Add(instruction.ResultId!.Value, new VectorType(innerType, (int)vectorInstruction.ComponentCount.Words)); + // } + // else if (instruction.OpCode == Op.OpTypeStruct) + // { + // var typeStructInstruction = instruction.UnsafeAs(); + // var structName = names[instruction.ResultId!.Value]; + // var fieldsData = instruction.Memory.Span[2..]; + // var fields = new List<(string Name, SymbolType Type)>(); + // for (var index = 0; index < fieldsData.Length; index++) + // { + // var fieldData = fieldsData[index]; + // var type = types[fieldData]; + // var name = memberNames[(typeStructInstruction.ResultId.Value, index)]; + // fields.Add((name, type)); + // } + // types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); + // } + // else if (instruction.OpCode == Op.OpTypeFunction) + // { + // var typeFunctionInstruction = instruction.UnsafeAs(); + // var returnType = types[typeFunctionInstruction.ReturnType]; + // var parameterTypes = new List(); + // foreach (var operand in instruction.Operands[2..]) + // { + // parameterTypes.Add(types[operand]); + // } + // types.Add(instruction.ResultId!.Value, new FunctionType(returnType, parameterTypes)); + // } + // } return types; } @@ -106,25 +108,26 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var symbols = new List(); foreach (var instruction in buffer.Instructions) { - if (instruction.OpCode == SDSLOp.OpVariable) - { - var variableInstruction = instruction.UnsafeAs(); - var variableName = names[variableInstruction.ResultId.Value]; - var variableType = types[variableInstruction.ResultType]; - - var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - symbols.Add(new(sid, variableType, variableInstruction.ResultId)); - } - - if (instruction.OpCode == SDSLOp.OpFunction) - { - var functionInstruction = instruction.UnsafeAs(); - var functionName = names[functionInstruction.ResultId.Value]; - var functionType = types[functionInstruction.FunctionType]; - - var sid = new SymbolID(functionName, SymbolKind.Method); - symbols.Add(new(sid, functionType, functionInstruction.ResultId)); - } + #warning uncomment + // if (instruction.OpCode == Op.OpVariable) + // { + // var variableInstruction = instruction.UnsafeAs(); + // var variableName = names[variableInstruction.ResultId.Value]; + // var variableType = types[variableInstruction.ResultType]; + + // var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + // symbols.Add(new(sid, variableType, variableInstruction.ResultId)); + // } + + // if (instruction.OpCode == Op.OpFunction) + // { + // var functionInstruction = instruction.UnsafeAs(); + // var functionName = names[functionInstruction.ResultId.Value]; + // var functionType = types[functionInstruction.FunctionType]; + + // var sid = new SymbolID(functionName, SymbolKind.Method); + // symbols.Add(new(sid, functionType, functionInstruction.ResultId)); + // } } var shaderType = new ShaderSymbol(mixin.Name, symbols); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index e6a2161c2f..d058d245e7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -26,7 +26,7 @@ public void Return(in SpirvValue? value = null) public void CleanBlock() { - if (Buffer.Instructions[Position].OpCode == SDSLOp.OpUnreachable) + if (Buffer.Instructions[Position].OpCode == Op.OpUnreachable) { Buffer.Instructions.RemoveAt(Position); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index a07d280451..4edb527a00 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; using System; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; @@ -23,14 +24,14 @@ public void SetPositionTo(TBlock block, bool beggining = false) SetPositionTo(bb.Parent); bool blockFound = false; Span blockTermination = [ - (int)SDSLOp.OpBranch, - (int)SDSLOp.OpBranchConditional, - (int)SDSLOp.OpSwitch, - (int)SDSLOp.OpReturn, - (int)SDSLOp.OpReturnValue, - (int)SDSLOp.OpKill, - (int)SDSLOp.OpUnreachable, - (int)SDSLOp.OpTerminateInvocation + (int)Op.OpBranch, + (int)Op.OpBranchConditional, + (int)Op.OpSwitch, + (int)Op.OpReturn, + (int)Op.OpReturnValue, + (int)Op.OpKill, + (int)Op.OpUnreachable, + (int)Op.OpTerminateInvocation ]; var wid = 0; foreach (var e in Buffer.Instructions) @@ -50,7 +51,7 @@ public void SetPositionTo(TBlock block, bool beggining = false) Position = wid; return; } - else if (block is SpirvFunction && blockFound && e.OpCode == SDSLOp.OpFunctionEnd) + else if (block is SpirvFunction && blockFound && e.OpCode == Op.OpFunctionEnd) { Position = wid; return; diff --git a/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs index 3bf158e6bd..9ba158373a 100644 --- a/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs +++ b/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs @@ -14,7 +14,7 @@ // public static void AddCapabilities(Instruction instruction) // { -// if(instruction.OpCode == SDSLOp.OpEntryPoint) +// if(instruction.OpCode == Op.OpEntryPoint) // { // if(instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.Geometry) // { @@ -30,29 +30,29 @@ // //Add capability tess // } // } -// else if(instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 16) +// else if(instruction.OpCode == Op.OpTypeFloat && instruction.Words.Span[2] == 16) // { // // Add capability Float16 // } -// else if (instruction.OpCode == SDSLOp.OpTypeFloat && instruction.Words.Span[2] == 64) +// else if (instruction.OpCode == Op.OpTypeFloat && instruction.Words.Span[2] == 64) // { // // Add capability Float64 // } -// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 64) +// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 64) // { // // Add capability Float64 // } -// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 16) +// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 16) // { // // Add capability Float64 // } -// else if (instruction.OpCode == SDSLOp.OpTypeInt && instruction.Words.Span[2] == 8) +// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 8) // { // // Add capability Float64 // } // // TODO : Check if any atomic instructions operates on integers -// // else if (instruction.OpCode == SDSLOp.OpAtomic && instruction.Words.Span[2] == 64) +// // else if (instruction.OpCode == Op.OpAtomic && instruction.Words.Span[2] == 64) // // { // // // Add capability Float64 // // } diff --git a/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs b/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs index 1095a4d5be..b15cd2229b 100644 --- a/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs +++ b/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs @@ -10,7 +10,7 @@ // { // using var tmp = new WordBuffer(); // foreach (var e in buffer.Declarations.UnorderedInstructions) -// if (e.OpCode != SDSLOp.OpNop) +// if (e.OpCode != Op.OpNop) // tmp.Insert(e); // buffer.Declarations.InstructionSpan.Clear(); // tmp.InstructionSpan.CopyTo(buffer.Declarations.InstructionSpan); @@ -20,7 +20,7 @@ // tmp.InstructionSpan.Clear(); // tmp.RecomputeLength(); // foreach (var e in f.UnorderedInstructions) -// if (e.OpCode != SDSLOp.OpNop) +// if (e.OpCode != Op.OpNop) // tmp.Insert(e); // f.InstructionSpan.Clear(); // tmp.InstructionSpan.CopyTo(f.InstructionSpan); diff --git a/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs b/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs index 1159317ec5..d714fad84d 100644 --- a/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs +++ b/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs @@ -24,17 +24,17 @@ // tmp.Insert(tmp.Length, opf.Words); // foreach(var i in function) // { -// if(i.OpCode == SDSLOp.OpFunctionParameter) +// if(i.OpCode == Op.OpFunctionParameter) // tmp.Insert(tmp.Length, i.Words); // } -// while(enumerator.Current.OpCode != SDSLOp.OpLabel) +// while(enumerator.Current.OpCode != Op.OpLabel) // enumerator.MoveNext(); // tmp.Insert(tmp.Length, enumerator.Current.Words); // foreach (var i in function) // { -// if(i.OpCode == SDSLOp.OpVariable) +// if(i.OpCode == Op.OpVariable) // { // tmp.Insert(tmp.Length,i.Words); // } @@ -42,11 +42,11 @@ // while(enumerator.MoveNext()) // { // var i = enumerator.Current; -// if (i.OpCode != SDSLOp.OpVariable && i.OpCode != SDSLOp.OpFunctionParameter) +// if (i.OpCode != Op.OpVariable && i.OpCode != Op.OpFunctionParameter) // { // tmp.Insert(tmp.Length, i.Words); // } -// if (i.OpCode == SDSLOp.OpSDSLVariable) +// if (i.OpCode == Op.OpSDSLVariable) // { // var t = 0; // } diff --git a/src/Stride.Shaders/Spirv/Processing/IOReplace.cs b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs index b7553792e6..2c2f156af0 100644 --- a/src/Stride.Shaders/Spirv/Processing/IOReplace.cs +++ b/src/Stride.Shaders/Spirv/Processing/IOReplace.cs @@ -11,7 +11,7 @@ // { // foreach (var i in buffer.Declarations.UnorderedInstructions) // { -// if (i.OpCode == SDSLOp.OpSDSLIOVariable) +// if (i.OpCode == Op.OpSDSLIOVariable) // { // var sclassv = i.GetOperand("storageclass"); @@ -23,7 +23,7 @@ // buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); // SetOpNop(i.Words.Span); // } -// else if (i.OpCode == SDSLOp.OpSDSLVariable) +// else if (i.OpCode == Op.OpSDSLVariable) // { // var sclassv = i.GetOperand("storageclass"); // var sclass = StorageClass.Private; @@ -39,7 +39,7 @@ // { // foreach (var i in f.UnorderedInstructions) // { -// if(i.OpCode == SDSLOp.OpSDSLFunctionParameter) +// if(i.OpCode == Op.OpSDSLFunctionParameter) // { // var name = i.GetOperand("name"); // var resultType = i.ResultType ?? -1; @@ -48,7 +48,7 @@ // buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); // SetOpNop(i.Words.Span); // } -// else if (i.OpCode == SDSLOp.OpSDSLVariable) +// else if (i.OpCode == Op.OpSDSLVariable) // { // var sclassv = i.GetOperand("storageclass"); diff --git a/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs index c9b0b3c362..d0cccf0503 100644 --- a/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs +++ b/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs @@ -13,7 +13,7 @@ // int outputLocation = -1; // foreach (var i in buffer.Declarations) // { -// if(i.OpCode == SDSLOp.OpSDSLIOVariable) +// if(i.OpCode == Op.OpSDSLIOVariable) // { // var execution = (ExecutionModel)(i.GetOperand("executionModel")?.Words ?? -1); // var storage = (StorageClass)(i.GetOperand("storageclass")?.Words ?? -1); diff --git a/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs b/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs index 1735425792..28ae10d966 100644 --- a/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs +++ b/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs @@ -25,7 +25,7 @@ // //foreach (var i in buffer) // //{ // // // if we hit a mixin name we reset stuff -// // if (i.OpCode == SDSLOp.OpSDSLMixinName) +// // if (i.OpCode == Op.OpSDSLMixinName) // // { // // offset += nextOffset; // // nextOffset = 0; diff --git a/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs index 5260aada46..d96e218134 100644 --- a/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs @@ -22,7 +22,7 @@ // var span = buffer.Declarations.InstructionSpan; // while(wid < buffer.Declarations.Length) // { -// if ((span[wid] & 0xFFFF) == (int)SDSLOp.OpMemoryModel) +// if ((span[wid] & 0xFFFF) == (int)Op.OpMemoryModel) // { // if (!found) // found = true; diff --git a/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs b/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs index 03ed877c63..292c96885c 100644 --- a/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs +++ b/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs @@ -25,7 +25,7 @@ // //var temp = new SpirvBuffer(); // //var ordered = new OrderedSpvBuffer(buffer); // //foreach (var e in ordered) -// // if(e.OpCode != SDSLOp.OpNop) +// // if(e.OpCode != Op.OpNop) // // temp.Add(e.Words.Span); // //buffer.Replace(temp, out var dispose); diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs index e03bacfdfd..8f7368bd46 100644 --- a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -36,7 +36,7 @@ // Apply(buffer); // Apply(buffer); // Apply(buffer); -// Apply(buffer); +// Apply(buffer); // } // static void Apply(SpirvBuffer buffer) diff --git a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs index b3fd12d817..bb39462fcd 100644 --- a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs @@ -13,7 +13,7 @@ // /// // /// Removes SDSL specific instructions // /// -// public struct SDSLOpRemover : INanoPass +// public struct OpRemover : INanoPass // { // public void Apply(SpirvBuffer buffer) @@ -22,7 +22,7 @@ // while(decl.MoveNext()) // { // var i = decl.Current; -// if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) +// if (InstructionInfo.Operators.Contains(i.OpCode)) // SetOpNop(i.AsRef()); // } // foreach (var (_, f) in buffer.Functions) @@ -31,7 +31,7 @@ // while(func.MoveNext()) // { // var i = func.Current; -// if (InstructionInfo.SDSLOperators.Contains(i.OpCode)) +// if (InstructionInfo.Operators.Contains(i.OpCode)) // SetOpNop(i.AsRef()); // } // } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 4209f90a5a..13e1deacf2 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Processing { @@ -73,7 +74,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList().Decoration == Specification.Decoration.UserSemantic - && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - && instruction.TryGetOperand("semanticName", out LiteralString? name) && name is LiteralString n - ) - { - semanticTable[t] = n.Value; - } + #warning uncomment + // if (instruction.OpCode == Op.OpDecorateString + // && instruction.UnsafeAs().Decoration == Specification.Decoration.UserSemantic + // && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t + // && instruction.TryGetOperand("semanticName", out LiteralString? name) && name is LiteralString n + // ) + // { + // semanticTable[t] = n.Value; + // } } } @@ -98,7 +100,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList not marking as Read - if (instruction.OpCode == SDSLOp.OpLoad && !streamInfo.Stream.Write) + if (instruction.OpCode == Op.OpLoad && !streamInfo.Stream.Write) streamInfo.Stream.Read = true; - if (instruction.OpCode == SDSLOp.OpStore) + if (instruction.OpCode == Op.OpStore) streamInfo.Stream.Write = true; } } - else if (instruction.OpCode == SDSLOp.OpAccessChain) + else if (instruction.OpCode == Op.OpAccessChain) { if (streams.TryGetValue(instruction.Operands[2], out var streamInfo)) { @@ -228,7 +230,7 @@ private void ProcessMethod(SpirvBuffer buffer, int functionId, SortedList words) { if (e.ResultId is int rid && rid == typeId) { - if (e.OpCode == SDSLOp.OpTypeInt) + if (e.OpCode == Op.OpTypeInt) { writer.Append(words.Length == 1 ? words[0] : words[0] << 32 | words[1], ConsoleColor.Red); return; } - else if (e.OpCode == SDSLOp.OpTypeFloat) + else if (e.OpCode == Op.OpTypeFloat) { writer.Append( words.Length == 1 ? @@ -139,7 +139,7 @@ public readonly void Append(in SpvOperand o, in Instruction instruction) Append(new PairIdRefIdRef((o.Words[i], o.Words[i + 1]))); else if ( o.Kind == OperandKind.LiteralContextDependentNumber - && (instruction.OpCode == SDSLOp.OpConstant || instruction.OpCode == SDSLOp.OpSpecConstant) + && (instruction.OpCode == Op.OpConstant || instruction.OpCode == Op.OpSpecConstant) && instruction.ResultType is int rtype ) { diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index 35499e3c15..f459230393 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -47,7 +47,7 @@ public SpirvDis(TBuffer buff, bool useNames = false) foreach (var i in buffer.InstructionsSpan) { if ( - (i.OpCode == SDSLOp.OpName || i.OpCode == SDSLOp.OpMemberName) + (i.OpCode == Op.OpName || i.OpCode == Op.OpMemberName) && i.TryGetOperand("name", out LiteralString? name) && name is not null ) @@ -112,18 +112,18 @@ public readonly void CheckNameTable(Instruction instruction) { if ( UseNames - && (instruction.OpCode == SDSLOp.OpName || instruction.OpCode == SDSLOp.OpMemberName) + && (instruction.OpCode == Op.OpName || instruction.OpCode == Op.OpMemberName) && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n ) { UpdateNameTable(t, n.Value); } - else if (instruction.OpCode == SDSLOp.OpTypeVoid) + else if (instruction.OpCode == Op.OpTypeVoid) UpdateNameTable(instruction.ResultId!.Value, "void"); - else if (instruction.OpCode == SDSLOp.OpTypeBool) + else if (instruction.OpCode == Op.OpTypeBool) UpdateNameTable(instruction.ResultId!.Value, "bool"); - else if (instruction.OpCode == SDSLOp.OpTypeInt) + else if (instruction.OpCode == Op.OpTypeInt) { var type = instruction.Operands[1..] switch { @@ -139,12 +139,12 @@ public readonly void CheckNameTable(Instruction instruction) }; UpdateNameTable(instruction.ResultId!.Value, type); } - else if (instruction.OpCode == SDSLOp.OpTypeFloat) + else if (instruction.OpCode == Op.OpTypeFloat) { var size = instruction.Operands[1]; UpdateNameTable(instruction.ResultId!.Value, size switch {16 => "half", 32 => "float", 64 => "double", _ => throw new NotImplementedException()}); } - else if (instruction.OpCode == SDSLOp.OpTypeVector) + else if (instruction.OpCode == Op.OpTypeVector) { //UpdateNameTable(instruction.ResultId!.Value, nameTable[instruction.Operands[1]].Name + instruction.Operands[2]); } From e7eca3631e32709ffe7ca0644caa47e3ab4312a5 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 7 Sep 2025 09:30:46 +0000 Subject: [PATCH 0440/1182] slowly improving new structs --- .../Examples.Spirv.cs | 326 ++++---- src/Stride.Shaders.Experiments/Examples.cs | 326 ++++---- src/Stride.Shaders.Experiments/Program.cs | 10 +- .../Buffers/NewSpirvBuffer.cs | 89 ++- .../ISpirvElement.cs | 2 +- .../Information/InstructionInfo.cs | 23 +- .../Information/LogicalOperandArray.cs | 20 +- .../Literals/ILiteralNumber.cs | 2 +- .../Literals/IdRef.cs | 19 +- .../Literals/IdResult.cs | 29 +- .../Literals/IdResultType.cs | 28 +- .../Literals/IdScope.cs | 29 +- .../Literals/LiteralArray.cs | 212 +++-- .../Literals/LiteralFloat.cs | 155 ++-- .../Literals/LiteralInteger.cs | 143 ++-- .../Literals/LiteralString.cs | 17 +- .../Literals/LiteralValue.cs | 204 ++++- .../Literals/PairIdRefIdRef.cs | 40 +- .../Literals/PairIdRefLiteralInteger.cs | 40 +- .../Literals/PairLiteralIntegerIdRef.cs | 37 +- .../Literals/SpvOp.cs | 22 +- src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 96 ++- .../SPVGenerator.Buffers.cs | 20 +- .../SPVGenerator.Instructions.cs | 734 ++++++++++++------ .../SPVGenerator.cs | 8 +- .../Parsing/SDSL/AST/Expression.cs | 81 +- .../Parsing/SDSL/AST/Literals.cs | 94 ++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 180 ++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 49 +- .../Parsing/SDSL/AST/ShaderElements.cs | 3 +- .../Parsing/SDSL/AST/Statements.cs | 50 +- .../Spirv/Building/Builder.Expressions.cs | 199 ++--- .../Spirv/Building/Builder.Flow.cs | 26 +- .../Spirv/Building/Builder.Functions.cs | 54 +- src/Stride.Shaders/Spirv/Building/Context.cs | 283 +++---- .../Spirv/Processing/StreamAnalyzer.cs | 153 ++-- src/Stride.Shaders/Spirv/Tools/Dis.cs | 58 ++ .../Spirv/Tools/SpirvDis.Appends.cs | 6 +- src/Stride.Shaders/Stride.Shaders.csproj | 1 + 39 files changed, 2377 insertions(+), 1491 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Tools/Dis.cs diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index c229258970..ecc533bdb1 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -58,250 +58,226 @@ public static void ParseShader() SpirvReader.ParseToList(shader, new(8)); } - + public static void CreateNewShader() { int id = 1; // var bound = new Bound(); var buffer = new NewSpirvBuffer(); - // // Capabilities + // Capabilities buffer.Add(new OpCapability(Capability.Shader)); var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); buffer.AddRef(ref extInstImport); buffer.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - + // declarations var t_void = new OpTypeVoid(id++); buffer.AddRef(ref t_void); - var t_bool = new OpTypeBool(id++); - buffer.AddRef(ref t_bool); - - var t_func = new OpTypeFunction(id++, t_void, []); - var t_float = new OpTypeFloat(id++, 32, null); - var t_uint = new OpTypeInt(id++, 32, 0); - var t_int = new OpTypeInt(id++, 32, 1); - var t_func_add = new OpTypeFunction(id++, t_int, [t_int, t_int]); - var t_float4 = new OpTypeVector(id++, t_float, 4); - var t_p_float4_func = new OpTypePointer(id++, StorageClass.Function, t_float4); - var constant1 = new OpConstant(id++, t_float, 5); - var constant2 = new OpConstant(id++, t_float, 2.23f); - var constant3 = new OpConstant(id++, t_uint, 5); - var compositeType = buffer.AddOpConstantComposite( + buffer + .Add(new OpTypeBool(id++), out var t_bool) + .Add(new OpTypeFunction(id++, t_void, []), out var t_func) + .Add(new OpTypeFloat(id++, 32, null), out var t_float) + .Add(new OpTypeInt(id++, 32, 0), out var t_uint) + .Add(new OpTypeInt(id++, 32, 1), out var t_int) + .Add(new OpTypeFunction(id++, t_int, [t_int, t_int]), out var t_func_add) + .Add(new OpTypeVector(id++, t_float, 4), out var t_float4) + .Add(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func) + .Add(new OpConstant(id++, t_float, 5f), out var constant1) + .Add(new OpConstant(id++, t_float, 2.23f), out var constant2) + .Add(new OpConstant(id++, t_uint, 5), out var constant3) + .Add(new OpConstantComposite( id++, t_float4, [constant1, constant1, constant2, constant1] - ); - - var t_array = buffer.AddOpTypeArray(id++, t_float4, constant3); - - var t_struct = buffer.AddOpTypeStruct(id++, [t_uint, t_array, t_int]); - var t_struct2 = buffer.AddOpTypeStruct(id++, [t_struct, t_uint]); - - var t_p_struct2 = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_struct2); - - var v_struct2 = buffer.AddOpVariable(id++, t_p_struct2, StorageClass.Uniform, null); - - var constant4 = buffer.AddOpConstant(id++, t_int, 1); - - var t_p_uint = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_uint); - var constant5 = buffer.AddOpConstant(id++, t_uint, 0); - - var t_p_output = buffer.AddOpTypePointer(id++, StorageClass.Output, t_float4); - var v_output = buffer.AddOpVariable(id++, t_p_output, StorageClass.Output, null); - - var t_p_input = buffer.AddOpTypePointer(id++, StorageClass.Input, t_float4); - var v_input = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - - var constant6 = buffer.AddOpConstant(id++, t_int, 0); - var constant7 = buffer.AddOpConstant(id++, t_int, 2); - var t_p_float4_unif = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_float4); - - var v_input_2 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - var t_p_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_int); - var constant8 = buffer.AddOpConstant(id++, t_int, 4); - var v_input_3 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - - - - - - buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); - buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); - buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); - buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); - buffer.AddOpDecorate(t_struct2, Decoration.Block); - buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); - buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); - - - - - buffer.AddOpName(t_p_func, "main"); - buffer.AddOpName(t_struct, "S"); - buffer.AddOpMemberName(t_struct, 0, "b"); - buffer.AddOpMemberName(t_struct, 1, "v"); - buffer.AddOpMemberName(t_struct, 2, "i"); - - var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.None, t_func_add); - var a = buffer.AddOpFunctionParameter(id++, t_int); - var b = buffer.AddOpFunctionParameter(id++, t_int); - buffer.AddOpLabel(id++); - var res = buffer.AddOpIAdd(id++, t_int, a, b); - buffer.AddOpReturnValue(res); - buffer.AddOpFunctionEnd(); - - var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.None, t_func); - buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); - buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); - - buffer.AddOpLabel(id++); - var resAdd = buffer.AddOpFunctionCall(id++, t_int, add, [constant7, constant7]); - buffer.AddOpReturn(); - buffer.AddOpFunctionEnd(); - - - - + ), out var compositeType) + .Add(new OpTypeArray(id++, t_float4, constant3), out var t_array) + .Add(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct) + .Add(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2) + .Add(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2) + .Add(new OpVariable(id++, t_p_struct2, StorageClass.Uniform, null), out var v_struct2) + .Add(new OpConstant(id++, t_int, 1), out var constant4) + .Add(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint) + .Add(new OpConstant(id++, t_uint, 0), out var constant5) + .Add(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output) + .Add(new OpVariable(id++, t_p_output, StorageClass.Output, null), out var v_output) + .Add(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input) + .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input) + .Add(new OpConstant(id++, t_int, 0), out var constant6) + .Add(new OpConstant(id++, t_int, 2), out var constant7) + .Add(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif) + .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_2) + .Add(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func) + .Add(new OpConstant(id++, t_int, 4), out var constant8) + .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_3) + .Add(new OpDecorate(t_array, Decoration.ArrayStride, 16)) + .Add(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)) + .Add(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)) + .Add(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)) + .Add(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)) + .Add(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)) + .Add(new OpDecorate(t_struct2, Decoration.Block)) + .Add(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)) + .Add(new OpDecorate(v_input_2, Decoration.NoPerspective)) + .Add(new OpName(t_p_func, "main")) + .Add(new OpName(t_struct, "S")) + .Add(new OpMemberName(t_struct, 0, "b")) + .Add(new OpMemberName(t_struct, 1, "v")) + .Add(new OpMemberName(t_struct, 2, "i")) + .Add(new OpFunction(id++, t_int, FunctionControlMask.None, t_func_add), out var add) + + + .Add(new OpFunctionParameter(id++, t_int), out var a) + .Add(new OpFunctionParameter(id++, t_int), out var b) + .Add(new OpLabel(id++), out var label) + .Add(new OpIAdd(id++, t_int, a, b), out var res) + .Add(new OpReturnValue(res)) + .Add(new OpFunctionEnd()) + .Add(new OpFunction(id++, t_void, FunctionControlMask.None, t_func), out var main) + .Add(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])) + .Add(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)) + .Add(new OpLabel(id++), out var label2) + .Add(new OpFunctionCall(id++, t_int, add, [constant7, constant7]), out var resAdd) + .Add(new OpReturn()) + .Add(new OpFunctionEnd()); buffer.Sort(); + var span = buffer.ToBuffer(); - var dis = new SpirvDis(buffer, useNames: true); - - dis.Disassemble(writeToConsole: true); + Spv.Dis(buffer); File.WriteAllBytes( "test.spv", - MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) + MemoryMarshal.Cast(span.Span) ); } public static void CreateShader() { - int id = 1; + // int id = 1; - // var bound = new Bound(); - var buffer = new SpirvBuffer(); - // // Capabilities + // // var bound = new Bound(); + // var buffer = new SpirvBuffer(); + // // // Capabilities - buffer.AddOpCapability(Capability.Shader); - var extInstImport = buffer.AddOpExtInstImport(id++, "GLSL.std.450"); - buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); + // buffer.AddOpCapability(Capability.Shader); + // var extInstImport = buffer.AddOpExtInstImport(id++, "GLSL.std.450"); + // buffer.AddOpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450); - // declarations + // // declarations - Span c = stackalloc IdRef[10]; // This is for use in parameters + // Span c = stackalloc IdRef[10]; // This is for use in parameters - var t_void = buffer.AddOpTypeVoid(id++); + // var t_void = buffer.AddOpTypeVoid(id++); - var t_bool = buffer.AddOpTypeBool(id++); + // var t_bool = buffer.AddOpTypeBool(id++); - var t_func = buffer.AddOpTypeFunction(id++, t_void, []); - var t_float = buffer.AddOpTypeFloat(id++, 32, null); - var t_uint = buffer.AddOpTypeInt(id++, 32, 0); - var t_int = buffer.AddOpTypeInt(id++, 32, 1); - var t_func_add = buffer.AddOpTypeFunction(id++, t_int, [t_int, t_int]); - var t_float4 = buffer.AddOpTypeVector(id++, t_float, 4); - var t_p_float4_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_float4); - var constant1 = buffer.AddOpConstant(id++, t_float, 5); - var constant2 = buffer.AddOpConstant(id++, t_float, 2.23f); - var constant3 = buffer.AddOpConstant(id++, t_uint, 5); - var compositeType = buffer.AddOpConstantComposite( - id++, - t_float4, - [constant1, constant1, constant2, constant1] - ); + // var t_func = buffer.AddOpTypeFunction(id++, t_void, []); + // var t_float = buffer.AddOpTypeFloat(id++, 32, null); + // var t_uint = buffer.AddOpTypeInt(id++, 32, 0); + // var t_int = buffer.AddOpTypeInt(id++, 32, 1); + // var t_func_add = buffer.AddOpTypeFunction(id++, t_int, [t_int, t_int]); + // var t_float4 = buffer.AddOpTypeVector(id++, t_float, 4); + // var t_p_float4_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_float4); + // var constant1 = buffer.AddOpConstant(id++, t_float, 5); + // var constant2 = buffer.AddOpConstant(id++, t_float, 2.23f); + // var constant3 = buffer.AddOpConstant(id++, t_uint, 5); + // var compositeType = buffer.AddOpConstantComposite( + // id++, + // t_float4, + // [constant1, constant1, constant2, constant1] + // ); - var t_array = buffer.AddOpTypeArray(id++, t_float4, constant3); + // var t_array = buffer.AddOpTypeArray(id++, t_float4, constant3); - var t_struct = buffer.AddOpTypeStruct(id++, [t_uint, t_array, t_int]); - var t_struct2 = buffer.AddOpTypeStruct(id++, [t_struct, t_uint]); + // var t_struct = buffer.AddOpTypeStruct(id++, [t_uint, t_array, t_int]); + // var t_struct2 = buffer.AddOpTypeStruct(id++, [t_struct, t_uint]); - var t_p_struct2 = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_struct2); + // var t_p_struct2 = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_struct2); - var v_struct2 = buffer.AddOpVariable(id++, t_p_struct2, StorageClass.Uniform, null); + // var v_struct2 = buffer.AddOpVariable(id++, t_p_struct2, StorageClass.Uniform, null); - var constant4 = buffer.AddOpConstant(id++, t_int, 1); + // var constant4 = buffer.AddOpConstant(id++, t_int, 1); - var t_p_uint = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_uint); - var constant5 = buffer.AddOpConstant(id++, t_uint, 0); + // var t_p_uint = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_uint); + // var constant5 = buffer.AddOpConstant(id++, t_uint, 0); - var t_p_output = buffer.AddOpTypePointer(id++, StorageClass.Output, t_float4); - var v_output = buffer.AddOpVariable(id++, t_p_output, StorageClass.Output, null); + // var t_p_output = buffer.AddOpTypePointer(id++, StorageClass.Output, t_float4); + // var v_output = buffer.AddOpVariable(id++, t_p_output, StorageClass.Output, null); - var t_p_input = buffer.AddOpTypePointer(id++, StorageClass.Input, t_float4); - var v_input = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + // var t_p_input = buffer.AddOpTypePointer(id++, StorageClass.Input, t_float4); + // var v_input = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - var constant6 = buffer.AddOpConstant(id++, t_int, 0); - var constant7 = buffer.AddOpConstant(id++, t_int, 2); - var t_p_float4_unif = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_float4); + // var constant6 = buffer.AddOpConstant(id++, t_int, 0); + // var constant7 = buffer.AddOpConstant(id++, t_int, 2); + // var t_p_float4_unif = buffer.AddOpTypePointer(id++, StorageClass.Uniform, t_float4); - var v_input_2 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - var t_p_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_int); - var constant8 = buffer.AddOpConstant(id++, t_int, 4); - var v_input_3 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + // var v_input_2 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); + // var t_p_func = buffer.AddOpTypePointer(id++, StorageClass.Function, t_int); + // var constant8 = buffer.AddOpConstant(id++, t_int, 4); + // var v_input_3 = buffer.AddOpVariable(id++, t_p_input, StorageClass.Input, null); - buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); - buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); - buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); - buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); - buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); - buffer.AddOpDecorate(t_struct2, Decoration.Block); - buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); - buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); + // buffer.AddOpDecorate(t_array, Decoration.ArrayStride, 16); + // buffer.AddOpMemberDecorate(t_struct, 0, Decoration.Offset, 0); + // buffer.AddOpMemberDecorate(t_struct, 1, Decoration.Offset, 16); + // buffer.AddOpMemberDecorate(t_struct, 2, Decoration.Offset, 96); + // buffer.AddOpMemberDecorate(t_struct2, 0, Decoration.Offset, 0); + // buffer.AddOpMemberDecorate(t_struct2, 1, Decoration.Offset, 112); + // buffer.AddOpDecorate(t_struct2, Decoration.Block); + // buffer.AddOpDecorate(v_struct2, Decoration.DescriptorSet, 0); + // buffer.AddOpDecorate(v_input_2, Decoration.NoPerspective); - buffer.AddOpName(t_p_func, "main"); - buffer.AddOpName(t_struct, "S"); - buffer.AddOpMemberName(t_struct, 0, "b"); - buffer.AddOpMemberName(t_struct, 1, "v"); - buffer.AddOpMemberName(t_struct, 2, "i"); + // buffer.AddOpName(t_p_func, "main"); + // buffer.AddOpName(t_struct, "S"); + // buffer.AddOpMemberName(t_struct, 0, "b"); + // buffer.AddOpMemberName(t_struct, 1, "v"); + // buffer.AddOpMemberName(t_struct, 2, "i"); - var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.None, t_func_add); - var a = buffer.AddOpFunctionParameter(id++, t_int); - var b = buffer.AddOpFunctionParameter(id++, t_int); - buffer.AddOpLabel(id++); - var res = buffer.AddOpIAdd(id++, t_int, a, b); - buffer.AddOpReturnValue(res); - buffer.AddOpFunctionEnd(); + // var add = buffer.AddOpFunction(id++, t_int, FunctionControlMask.None, t_func_add); + // var a = buffer.AddOpFunctionParameter(id++, t_int); + // var b = buffer.AddOpFunctionParameter(id++, t_int); + // buffer.AddOpLabel(id++); + // var res = buffer.AddOpIAdd(id++, t_int, a, b); + // buffer.AddOpReturnValue(res); + // buffer.AddOpFunctionEnd(); - var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.None, t_func); - buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); - buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); + // var main = buffer.AddOpFunction(id++, t_void, FunctionControlMask.None, t_func); + // buffer.AddOpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3]); + // buffer.AddOpExecutionMode(main, ExecutionMode.OriginLowerLeft); - buffer.AddOpLabel(id++); - var resAdd = buffer.AddOpFunctionCall(id++, t_int, add, [constant7, constant7]); - buffer.AddOpReturn(); - buffer.AddOpFunctionEnd(); + // buffer.AddOpLabel(id++); + // var resAdd = buffer.AddOpFunctionCall(id++, t_int, add, [constant7, constant7]); + // buffer.AddOpReturn(); + // buffer.AddOpFunctionEnd(); - buffer.Sort(); + // buffer.Sort(); - var dis = new SpirvDis(buffer, useNames: true); + // var dis = new SpirvDis(buffer, useNames: true); - dis.Disassemble(writeToConsole: true); - File.WriteAllBytes( - "test.spv", - MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) - ); + // dis.Disassemble(writeToConsole: true); + // File.WriteAllBytes( + // "test.spv", + // MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) + // ); + #warning replace + throw new NotImplementedException(); } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 0167253330..1520ee9e6b 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -295,171 +295,173 @@ class ShaderInfo public static void MergeSDSL() { - CompileSDSL(); - - var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; - - var buffer = GetOrLoadShader("TestBasic"); - - // Step: expand "for" - // TODO - - // Step: build mixins: top level and (TODO) compose - var inheritanceList = new List(); - BuildInheritanceList(buffer, inheritanceList); - inheritanceList.Add("TestBasic"); - - var temp = new SpirvBuffer(); - var offset = 0; - var nextOffset = 0; - - foreach (var shaderName in inheritanceList) - { - var shader = GetOrLoadShader(shaderName); - offset += nextOffset; - nextOffset = 0; - foreach (var i in shader.Instructions) - { - var i2 = temp.Add(i.Words); - - if (i.ResultId != null && i.ResultId.Value > nextOffset) - nextOffset = i.ResultId.Value; - i2.OffsetIds(offset); - } - } - - var shaders = new Dictionary(); - ShaderInfo? currentShader = null; - - var names = new Dictionary(); - var importedShaders = new Dictionary(); - var idRemapping = new Dictionary(); - foreach (var i in temp.Instructions) - { - if (i.OpCode == Op.OpName) - { - var nameInstruction = i.UnsafeAs(); - names.Add(nameInstruction.Target, nameInstruction.Name.Value); - } - else if (i.OpCode == Op.OpSDSLShader) - { - currentShader = new ShaderInfo(); - var shaderName = i.UnsafeAs().ShaderName.Value; - shaders.Add(shaderName, currentShader); - SetOpNop(i.Words); - } - else if (i.OpCode == Op.OpSDSLShaderEnd) - { - currentShader = null; - importedShaders.Clear(); - SetOpNop(i.Words); - } - else if (i.OpCode == Op.OpSDSLMixinInherit) - { - SetOpNop(i.Words); - } - - if (i.OpCode == Op.OpFunction) - { - var function = i.UnsafeAs(); - var functionName = names[function.ResultId.Value]; - currentShader!.Functions.Add(functionName, i.ResultId!.Value); - - //temp.Remove(i.Position); - //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.Functioncontrol, function.FunctionType); - } - - if (i.OpCode == Op.OpVariable) - { - var variable = i.UnsafeAs(); - var variableName = names[variable.ResultId.Value]; - currentShader!.Variables.Add(variableName, i.ResultId!.Value); - } - - if (i.OpCode == Op.OpSDSLImportShader) - { - var importShader = i.UnsafeAs(); - - importedShaders.Add(importShader.ResultId.Value, shaders[importShader.ShaderName.Value]); - - SetOpNop(i.Words); - } - else if (i.OpCode == Op.OpSDSLImportVariable) - { - var importVariable = i.UnsafeAs(); - var importedShader = importedShaders[importVariable.Shader]; - - var importedVariable = importedShader.Variables[importVariable.VariableName.Value]; - - idRemapping.Add(importVariable.ResultId.Value, importedVariable); - - SetOpNop(i.Words); - } - else if (i.OpCode == Op.OpSDSLImportFunction) - { - var importFunction = i.UnsafeAs(); - - var importedShader = importedShaders[importFunction.Shader]; - var importedFunction = importedShader.Functions[importFunction.FunctionName.Value]; - idRemapping.Add(importFunction.ResultId.Value, importedFunction); - - SetOpNop(i.Words); - } - - foreach (var op in i) - { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[0], out var to1)) - op.Words[0] = to1; - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - op.Words[1] = to2; - } - } + // CompileSDSL(); + + // var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; + + // var buffer = GetOrLoadShader("TestBasic"); + + // // Step: expand "for" + // // TODO + + // // Step: build mixins: top level and (TODO) compose + // var inheritanceList = new List(); + // BuildInheritanceList(buffer, inheritanceList); + // inheritanceList.Add("TestBasic"); + + // var temp = new SpirvBuffer(); + // var offset = 0; + // var nextOffset = 0; + + // foreach (var shaderName in inheritanceList) + // { + // var shader = GetOrLoadShader(shaderName); + // offset += nextOffset; + // nextOffset = 0; + // foreach (var i in shader.Instructions) + // { + // var i2 = temp.Add(i.Words); + + // if (i.ResultId != null && i.ResultId.Value > nextOffset) + // nextOffset = i.ResultId.Value; + // i2.OffsetIds(offset); + // } + // } + + // var shaders = new Dictionary(); + // ShaderInfo? currentShader = null; + + // var names = new Dictionary(); + // var importedShaders = new Dictionary(); + // var idRemapping = new Dictionary(); + // foreach (var i in temp.Instructions) + // { + // if (i.OpCode == Op.OpName) + // { + // var nameInstruction = i.UnsafeAs(); + // names.Add(nameInstruction.Target, nameInstruction.Name.Value); + // } + // else if (i.OpCode == Op.OpSDSLShader) + // { + // currentShader = new ShaderInfo(); + // var shaderName = i.UnsafeAs().ShaderName.Value; + // shaders.Add(shaderName, currentShader); + // SetOpNop(i.Words); + // } + // else if (i.OpCode == Op.OpSDSLShaderEnd) + // { + // currentShader = null; + // importedShaders.Clear(); + // SetOpNop(i.Words); + // } + // else if (i.OpCode == Op.OpSDSLMixinInherit) + // { + // SetOpNop(i.Words); + // } + + // if (i.OpCode == Op.OpFunction) + // { + // var function = i.UnsafeAs(); + // var functionName = names[function.ResultId.Value]; + // currentShader!.Functions.Add(functionName, i.ResultId!.Value); + + // //temp.Remove(i.Position); + // //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.Functioncontrol, function.FunctionType); + // } + + // if (i.OpCode == Op.OpVariable) + // { + // var variable = i.UnsafeAs(); + // var variableName = names[variable.ResultId.Value]; + // currentShader!.Variables.Add(variableName, i.ResultId!.Value); + // } + + // if (i.OpCode == Op.OpSDSLImportShader) + // { + // var importShader = i.UnsafeAs(); + + // importedShaders.Add(importShader.ResultId.Value, shaders[importShader.ShaderName.Value]); + + // SetOpNop(i.Words); + // } + // else if (i.OpCode == Specification.Op.OpSDSLImportVariable) + // { + // var importVariable = i.UnsafeAs(); + // var importedShader = importedShaders[importVariable.Shader]; + + // var importedVariable = importedShader.Variables[importVariable.VariableName.Value]; + + // idRemapping.Add(importVariable.ResultId.Value, importedVariable); + + // SetOpNop(i.Words); + // } + // else if (i.OpCode == Op.OpSDSLImportFunction) + // { + // var importFunction = i.UnsafeAs(); + + // var importedShader = importedShaders[importFunction.Shader]; + // var importedFunction = importedShader.Functions[importFunction.FunctionName.Value]; + // idRemapping.Add(importFunction.ResultId.Value, importedFunction); + + // SetOpNop(i.Words); + // } + + // foreach (var op in i) + // { + // if ((op.Kind == OperandKind.IdRef + // || op.Kind == OperandKind.IdResultType + // || op.Kind == OperandKind.PairIdRefLiteralInteger + // || op.Kind == OperandKind.PairIdRefIdRef) + // && idRemapping.TryGetValue(op.Words[0], out var to1)) + // op.Words[0] = to1; + // if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + // || op.Kind == OperandKind.PairIdRefIdRef) + // && idRemapping.TryGetValue(op.Words[1], out var to2)) + // op.Words[1] = to2; + // } + // } // Step: merge mixins // start from most-derived class and import on demand // Step: analyze streams and generate in/out variables - new TypeDuplicateRemover().Apply(temp); - - var context = new SpirvContext(new()); - context.Bound = offset + nextOffset + 1; - ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); - foreach (var i in temp.Instructions) - { - if (i.OpCode == Op.OpFunction) - { - var function = i.UnsafeAs(); - var functionName = names2[i.ResultId.Value]; - context.Module.Functions.Add(functionName, new SpirvFunction(i.ResultId.Value, functionName, (FunctionType)types[function.FunctionType])); - } - } - - foreach (var type in types) - { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); - } - - context.Buffer.InsertOpCapability(0, Specification.Capability.Shader); - context.Buffer.InsertOpMemoryModel(1, Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); - context.Buffer.InsertOpExtension(2, "SPV_GOOGLE_hlsl_functionality1"); - new StreamAnalyzer().Process(temp, context); - - temp.Instructions.AddRange(context.Buffer.Instructions); - - new TypeDuplicateRemover().Apply(temp); - temp.Instructions.RemoveAll(x => x.OpCode == Op.OpNop); - - var dis = new SpirvDis(temp, true); - var source = dis.Disassemble(true); - - File.WriteAllText("test.spvdis", source); + // new TypeDuplicateRemover().Apply(temp); + + // var context = new SpirvContext(new()); + // context.Bound = offset + nextOffset + 1; + // ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); + // foreach (var i in temp.Instructions) + // { + // if (i.OpCode == Op.OpFunction) + // { + // var function = i.UnsafeAs(); + // var functionName = names2[i.ResultId.Value]; + // context.Module.Functions.Add(functionName, new SpirvFunction(i.ResultId.Value, functionName, (FunctionType)types[function.FunctionType])); + // } + // } + + // foreach (var type in types) + // { + // context.Types.Add(type.Value, type.Key); + // context.ReverseTypes.Add(type.Key, type.Value); + // } + + // context.Buffer.InsertOpCapability(0, Specification.Capability.Shader); + // context.Buffer.InsertOpMemoryModel(1, Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); + // context.Buffer.InsertOpExtension(2, "SPV_GOOGLE_hlsl_functionality1"); + // new StreamAnalyzer().Process(temp, context); + + // temp.Instructions.AddRange(context.Buffer.Instructions); + + // new TypeDuplicateRemover().Apply(temp); + // temp.Instructions.RemoveAll(x => x.OpCode == Op.OpNop); + + // var dis = new SpirvDis(temp, true); + // var source = dis.Disassemble(true); + + // File.WriteAllText("test.spvdis", source); + #warning replace + throw new NotImplementedException(); } static void ReplaceRefs(int from, int to, Instruction i) @@ -498,7 +500,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri var shaderMapping = new Dictionary(); foreach (var i in buffer.Instructions) { - if (i.OpCode == Op.OpSDSLImportShader) + if (i.OpCode == Specification.Op.OpSDSLImportShader) { shaderMapping[i.ResultId!.Value] = i.GetOperand("shaderName")!.Value.Value; } @@ -507,7 +509,7 @@ private static void BuildInheritanceList(SpirvBuffer buffer, List inheri // Check inheritance foreach (var i in buffer.Instructions) { - if (i.OpCode == Op.OpSDSLMixinInherit) + if (i.OpCode == Specification.Op.OpSDSLMixinInherit) { var shaderName = shaderMapping[i.Words[1]]; var shader = GetOrLoadShader(shaderName); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 6589219800..762edc8ef1 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -9,13 +9,9 @@ using static Stride.Shaders.Spirv.Specification; //Examples.CompileSDSL(); -Examples.MergeSDSL(); +// Examples.MergeSDSL(); // Examples.TryAllFiles(); // Examples.CreateShader(); -var buffer = new SpirvBuffer(32); -var t_int = buffer.AddOpTypeInt(1, 32, 0); -InstOpTypeStruct tstr = buffer.AddOpTypeStruct(3, [t_int, t_int]); -InstOpExecutionMode tmode = buffer.AddOpExecutionMode(4, ExecutionMode.LocalSize); -tmode.Mode = ExecutionMode.Invocations; -Console.WriteLine(tmode.Mode); +// Examples.GenerateSpirv(); +Examples.CreateNewShader(); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 39dff536dd..e6ffaf1e27 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -1,5 +1,6 @@ #pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; @@ -33,8 +34,22 @@ public OpData(MemoryOwner memory) public readonly void Dispose() => Memory.Dispose(); + + public readonly bool TryGetOperand(string name, out T operand) + { + foreach (var o in this) + { + if (name == o.Name) + { + operand = o.To(); + return true; + } + } + operand = default!; + return false; + } + public readonly T Get(string name) - where T : struct, IFromSpirv { foreach (var o in this) { @@ -67,20 +82,26 @@ public readonly int CompareTo(OpData other) public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) { + public readonly Op Op => Buffer[Index].Op; public readonly ref OpData Data => ref Buffer[Index]; } public class NewSpirvBuffer { + public SpirvHeader Header { get; set; } List Memory { get; set; } = []; internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Memory)[index]; // internal OpDataIndex this[int index] => new(index, this); public void Add(OpData data) - => Memory.Add(data); + { + if (InstructionInfo.GetInfo(data).GetResultIndex(out int index) && index >= Header.Bound) + Header = Header with { Bound = data.Memory.Span[index] + 1 }; + Memory.Add(data); + } - public void AddRef(ref T instruction) where T : IMemoryInstruction + public void AddRef(ref T instruction) where T : struct, IMemoryInstruction { if (instruction.DataIndex is OpDataIndex odi) { @@ -92,17 +113,39 @@ public void AddRef(ref T instruction) where T : IMemoryInstruction else Memory.Add(new(instruction.InstructionMemory)); instruction.DataIndex = new(Memory.Count - 1, this); + if (instruction.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) + Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; } - public void Add(in T instruction) where T : IMemoryInstruction + public NewSpirvBuffer Add(in T instruction) where T : struct, IMemoryInstruction { if (instruction.DataIndex is OpDataIndex odi) { if (odi.Buffer == this) - return; + return this; else Memory.Add(new(instruction.InstructionMemory)); } else Memory.Add(new(instruction.InstructionMemory)); + var tmp = instruction; + if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) + Header = Header with { Bound = tmp.InstructionMemory.Span[index] + 1 }; + return this; + } + public NewSpirvBuffer Add(in T instruction, out T result) where T : struct, IMemoryInstruction + { + result = instruction; + if (instruction.DataIndex is OpDataIndex odi) + { + if (odi.Buffer == this) + return this; + else + Memory.Add(new(instruction.InstructionMemory)); + } + else Memory.Add(new(instruction.InstructionMemory)); + var tmp = instruction; + if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) + Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; + return this; } public void Insert(int index, OpData data) @@ -148,4 +191,40 @@ public void Sort() { Memory.Sort(static (a, b) => a.CompareTo(b)); } + + public SpanOwner ToBuffer() + { + var result = SpanOwner.Allocate(5 + Memory.Sum(i => i.Memory.Length)); + var span = result.Span; + Header.WriteTo(span); + var offset = 5; + foreach (var instruction in Memory) + { + instruction.Memory.Span.CopyTo(span[offset..]); + offset += instruction.Memory.Length; + } + return result; + } +} + + +public static class IMemoryInstructionExtensions +{ + /// + /// Gets information for the instruction operation. + /// + /// + /// + public static LogicalOperandArray GetInfo(this ref T op) + where T : struct, IMemoryInstruction + { + Decoration? decoration = op switch + { + OpDecorate opd => opd.Decoration, + OpMemberDecorate opd => opd.Decoration, + _ => null + }; + + return InstructionInfo.GetInfo((Op)(op.InstructionMemory.Span[0] & 0xFFFF), decoration); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs index 04a948d31e..9854e141f4 100644 --- a/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs +++ b/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs @@ -5,6 +5,6 @@ namespace Stride.Shaders.Spirv.Core; public interface ISpirvElement : IDisposable { - MemoryOwner Words { get; } + ReadOnlySpan Words { get; } public int WordCount { get; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index 1eb8887aa0..fe796f6911 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; @@ -89,6 +90,12 @@ internal void Register(OperandKey op, OperandKind? kind, OperandQuantifier? quan else Info.Add(op, new(spvClass, [new(kind, quantifier, name)])); } + + + + public static LogicalOperandArray GetInfo(Op op, Decoration? decoration = null) + => GetInfo(new OperandKey(op, decoration)); + /// /// Gets information for the instruction operation. /// @@ -96,10 +103,11 @@ internal void Register(OperandKey op, OperandKind? kind, OperandQuantifier? quan /// public static LogicalOperandArray GetInfo(OperandKey op) { - if(op.Decoration is not null && !Instance.Info.ContainsKey(op)) + if (op.Decoration is not null && !Instance.Info.ContainsKey(op)) return Instance.Info[op with { Decoration = null }]; return Instance.Info[op]; } + public static LogicalOperandArray GetInfo(Instruction instruction) { Decoration? decoration = instruction.OpCode switch @@ -113,4 +121,17 @@ or Op.OpDecorate }; return GetInfo(new OperandKey(instruction.OpCode, decoration)); } + public static LogicalOperandArray GetInfo(OpData instruction) + { + Decoration? decoration = instruction.Op switch + { + Op.OpDecorateString + or Op.OpDecorate + or Op.OpDecorateId => (Decoration)instruction.Memory.Span[1], + Op.OpMemberDecorate + or Op.OpMemberDecorateString => (Decoration)instruction.Memory.Span[2], + _ => null + }; + return GetInfo(new OperandKey(instruction.Op, decoration)); + } } diff --git a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs index c16dd8d08d..66210296b5 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs @@ -12,8 +12,6 @@ public readonly struct LogicalOperandArray(string? className, List LogicalOperands { get; } = operands ?? []; - public bool HasResult => GetHasResult(); - public bool HasResultType => GetHasResultType(); public int Count => LogicalOperands.Count; @@ -25,22 +23,32 @@ public LogicalOperand this[int index] set => LogicalOperands[index] = value; } - bool GetHasResult() + public bool GetResultIndex(out int index) { - foreach (var o in LogicalOperands) + for(int i = 0; i < LogicalOperands.Count; i++) { + var o = LogicalOperands[i]; if (o.Kind == OperandKind.IdResult) + { + index = i; return true; + } } + index = -1; return false; } - bool GetHasResultType() + public bool GetResultTypeIndex(out int index) { - foreach (var o in LogicalOperands) + for (int i = 0; i < LogicalOperands.Count; i++) { + var o = LogicalOperands[i]; if (o.Kind == OperandKind.IdResultType) + { + index = i; return true; + } } + index = -1; return false; } diff --git a/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs b/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs index f3dc53e7de..373314ee8f 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs @@ -12,5 +12,5 @@ namespace Stride.Shaders.Spirv.Core; /// public interface ILiteralNumber : ISpirvElement { - public long Words { get; init; } + public MemoryOwner Data { get; init; } } diff --git a/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs index b0a600d99a..2c3d378def 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs @@ -3,16 +3,26 @@ namespace Stride.Shaders.Spirv.Core; -public record struct IdRef(int Value) : ISpirvElement, IFromSpirv +public record struct IdRef : ISpirvElement, IFromSpirv { public readonly int WordCount => 1; + public readonly int Value => Word.Span[0]; + public MemoryOwner Word { get; set; } + public readonly ReadOnlySpan Words => Word.Span; + + public IdRef(int value) + { + Word = MemoryOwner.Allocate(1); + Word.Span[0] = value; + } + public static implicit operator int(IdRef r) => r.Value; public static implicit operator IdRef(int v) => new(v); public static implicit operator LiteralInteger(IdRef v) => new(v); public static implicit operator IdResult(IdRef v) => new(v); public static implicit operator IdResultType(IdRef v) => new(v); - public static IdRef From(Span words) => new() { Value = words[0] }; + public static IdRef From(Span words) => new(words[0]); public static IdRef From(string value) { @@ -25,4 +35,9 @@ public readonly SpanOwner AsSpanOwner() owner.Span[0] = Value; return owner; } + + public void Dispose() + { + Word.Dispose(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs index a6ac465bb5..df3522002e 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs @@ -3,34 +3,43 @@ namespace Stride.Shaders.Spirv.Core; -public record struct IdResult(int Value) : ISpirvElement, IFromSpirv + + +public record struct IdResult : ISpirvElement, IFromSpirv { public readonly int WordCount => 1; + public readonly int Value => Word.Span[0]; + public MemoryOwner Word { get; set; } + public readonly ReadOnlySpan Words => Word.Span; + + public IdResult(int value) + { + Word = MemoryOwner.Allocate(1); + Word.Span[0] = value; + } + public static implicit operator int(IdResult r) => r.Value; public static implicit operator IdResult(int v) => new(v); public static implicit operator LiteralInteger(IdResult v) => new(v); - public static IdResult From(Span words) => new() { Value = words[0] }; + public static implicit operator IdRef(IdResult v) => new(v); + public static implicit operator IdResultType(IdResult v) => new(v); + public static IdResult From(Span words) => new(words[0]); public static IdResult From(string value) { throw new NotImplementedException(); } + public readonly SpanOwner AsSpanOwner() { var owner = SpanOwner.Allocate(1); owner.Span[0] = Value; return owner; } -} -public static class IdResultExtensions -{ - public static SpanOwner AsSpanOwner(this IdResult? value) + public void Dispose() { - if(value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); + Word.Dispose(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs index b52d0b64ac..58090d7c39 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs @@ -3,14 +3,28 @@ namespace Stride.Shaders.Spirv.Core; -public record struct IdResultType(int Value) : ISpirvElement, IFromSpirv + + +public record struct IdResultType : ISpirvElement, IFromSpirv { public readonly int WordCount => 1; + public readonly int Value => Word.Span[0]; + public MemoryOwner Word { get; set; } + public readonly ReadOnlySpan Words => Word.Span; + + public IdResultType(int value) + { + Word = MemoryOwner.Allocate(1); + Word.Span[0] = value; + } + public static implicit operator int(IdResultType r) => r.Value; public static implicit operator IdResultType(int v) => new(v); public static implicit operator LiteralInteger(IdResultType v) => new(v); - public static IdResultType From(Span words) => new() { Value = words[0] }; + public static implicit operator IdResult(IdResultType v) => new(v); + public static implicit operator IdRef(IdResultType v) => new(v); + public static IdResultType From(Span words) => new(words[0]); public static IdResultType From(string value) { @@ -23,15 +37,9 @@ public readonly SpanOwner AsSpanOwner() owner.Span[0] = Value; return owner; } -} -public static class IdResultTypeExtensions -{ - public static SpanOwner AsSpanOwner(this IdResultType? value) + public void Dispose() { - if(value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); + Word.Dispose(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs b/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs index e028926d41..854855814a 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs @@ -3,34 +3,43 @@ namespace Stride.Shaders.Spirv.Core; -public record struct IdScope(int Value) : ISpirvElement, IFromSpirv + + +public record struct IdScope : ISpirvElement, IFromSpirv { public readonly int WordCount => 1; + public readonly int Value => Word.Span[0]; + public MemoryOwner Word { get; set; } + public readonly ReadOnlySpan Words => Word.Span; + + public IdScope(int value) + { + Word = MemoryOwner.Allocate(1); + Word.Span[0] = value; + } + public static implicit operator int(IdScope r) => r.Value; public static implicit operator IdScope(int v) => new(v); public static implicit operator LiteralInteger(IdScope v) => new(v); - public static IdScope From(Span words) => new() { Value = words[0] }; + public static implicit operator IdResult(IdScope v) => new(v); + public static implicit operator IdResultType(IdScope v) => new(v); + public static IdScope From(Span words) => new(words[0]); public static IdScope From(string value) { throw new NotImplementedException(); } + public readonly SpanOwner AsSpanOwner() { var owner = SpanOwner.Allocate(1); owner.Span[0] = Value; return owner; } -} -public static class IdScopeExtensions -{ - public static SpanOwner AsSpanOwner(this IdScope? value) + public void Dispose() { - if(value is null) - return SpanOwner.Empty; - else - return new LiteralInteger(value.Value.Value).AsSpanOwner(); + Word.Dispose(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 9cc34152bb..a8da9051b1 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -10,7 +10,6 @@ namespace Stride.Shaders.Spirv.Core; public static class LiteralArrayHelper { public static LiteralArray Create(ReadOnlySpan elements) - where T : struct, ISpirvElement, IFromSpirv { return new LiteralArray(elements); } @@ -18,91 +17,200 @@ public static LiteralArray Create(ReadOnlySpan elements) [CollectionBuilder(typeof(LiteralArrayHelper), "Create")] public struct LiteralArray : ISpirvElement, IFromSpirv>, IDisposable - where T : struct, ISpirvElement, IFromSpirv { + static LiteralArray() + { + LiteralArray v = default; + _ = v switch + { + LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray + or LiteralArray<(int, int)> => true, + _ => throw new Exception("Type not supported in SPIR-V") + }; + } + + MemoryOwner Memory { get; set { field?.Dispose(); field = value; } } + public readonly ReadOnlySpan Words => Memory is not null ? Memory.Span : []; + MemoryOwner Elements { get; set { field?.Dispose(); field = value; } } + public readonly int WordCount => Elements.Length; - MemoryOwner Words { get; set { field.Dispose(); field = value; } } - public readonly int WordCount => Words.Length; - public LiteralArray(ReadOnlySpan words) + public LiteralArray(MemoryOwner elements) { - Words = MemoryOwner.Allocate(words.Length); - words.CopyTo(Words.Span); + Elements = elements; + Memory = MemoryOwner.Empty; + UpdateWords(); + } + public LiteralArray(ReadOnlySpan elements) + { + Elements = MemoryOwner.Allocate(elements.Length); + elements.CopyTo(Elements.Span); + Memory = MemoryOwner.Empty; + UpdateWords(); } public void Assign(LiteralArray owner) { - Words.Dispose(); - Words = owner.Words; + Elements?.Dispose(); + Elements = owner.Elements; + UpdateWords(); } public void Assign(MemoryOwner owner) { - Words.Dispose(); - Words = owner; + Elements.Dispose(); + Elements = owner; } public void Assign(Memory span) { - Words.Dispose(); - Words = MemoryOwner.Allocate(span.Length); - span.CopyTo(Words.Memory); + Elements.Dispose(); + Elements = MemoryOwner.Allocate(span.Length); + span.CopyTo(Elements.Memory); } public void Assign(Span span) { - Words.Dispose(); - Words = MemoryOwner.Allocate(span.Length); - span.CopyTo(Words.Span); + Elements.Dispose(); + Elements = MemoryOwner.Allocate(span.Length); + span.CopyTo(Elements.Span); } - public static LiteralArray From(Span words) + public readonly void Dispose() => Elements.Dispose(); + + void UpdateWords() { - T tmp = default; - if (tmp is IdRef or IdResult or IdResultType or IdScope or LiteralInteger) + Memory?.Dispose(); + Memory = MemoryOwner.Allocate(Elements.Length * 2, AllocationMode.Clear); + var pos = 0; + foreach (var element in Elements.Span) { - using var owner = SpanOwner.Allocate(words.Length, AllocationMode.Clear); - for (int i = 0; i < words.Length; i++) - owner.Span[i] = T.From([words[i]]); - return new LiteralArray(owner.Span); - } - else if (tmp is PairIdRefIdRef or PairIdRefLiteralInteger or PairLiteralIntegerIdRef) - { - using var owner = SpanOwner.Allocate(words.Length / 2, AllocationMode.Clear); - for (int i = 0; i < words.Length; i += 2) - owner.Span[i / 2] = T.From([words[i], words[i + 1]]); - return new LiteralArray(owner.Span); + if (element is bool or byte or sbyte or short or ushort or int or uint or float) + { + Memory.Span[pos++] = element switch + { + bool b => b ? 1 : 0, + byte b => b, + sbyte sb => sb, + short s => s, + ushort us => us, + int i => i, + uint ui => (int)ui, + float f => BitConverter.SingleToInt32Bits(f), + _ => throw new NotImplementedException() + }; + } + else if (element is long or ulong or double or ValueTuple) + { + Memory.Span[pos++] = element switch + { + long l => (int)(l >> 32), + ulong ul => (int)(ul >> 32), + double d => (int)(BitConverter.DoubleToInt64Bits(d) >> 32), + ValueTuple vt => vt.Item1, + _ => throw new NotImplementedException() + }; + Memory.Span[pos++] = element switch + { + long l => (int)(l & 0xFFFFFFFF), + ulong ul => (int)(ul & 0xFFFFFFFF), + double d => (int)(BitConverter.DoubleToInt64Bits(d) & 0xFFFFFFFF), + ValueTuple vt => vt.Item2, + _ => throw new NotImplementedException() + }; + } + else throw new NotImplementedException(); } - else throw new NotImplementedException($"Can't process type {typeof(T).FullName}"); + } - public static LiteralArray From(string value) - { - throw new NotImplementedException(); - } + public readonly Span.Enumerator GetEnumerator() => Elements.Span.GetEnumerator(); - public readonly SpanOwner AsSpanOwner() + public static LiteralArray From(Span words) { - T tmp = default; - if (tmp is IdRef or IdResult or IdResultType or IdScope or LiteralInteger) + T value = default!; + if (value is bool or byte or sbyte or short or ushort or int or uint or float) { - var owner = SpanOwner.Allocate(Words.Length, AllocationMode.Clear); - for (int i = 0; i < Words.Length; i++) - owner.Span[i] = Words.Span[i].AsSpirvSpan()[0]; - return owner; + var owner = MemoryOwner.Allocate(words.Length); + for (int i = 0; i < words.Length; i++) + { + if (value is bool) + { + bool b = words[i] != 0; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is byte) + { + byte b = (byte)words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is sbyte) + { + sbyte b = (sbyte)words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is short) + { + short b = (short)words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is ushort) + { + ushort b = (ushort)words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is int) + { + int b = words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is uint) + { + uint b = (uint)words[i]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is float) + { + float b = BitConverter.Int32BitsToSingle(words[i]); + owner.Span[i] = Unsafe.As(ref b); + } + } + return new(owner); } - else if (tmp is PairIdRefIdRef or PairIdRefLiteralInteger or PairLiteralIntegerIdRef) + else if (value is long or double && words.Length % 2 == 0) { - using var owner = SpanOwner.Allocate(Words.Length * 2, AllocationMode.Clear); - for (int i = 0; i < Words.Length; i += 2) + var owner = MemoryOwner.Allocate(words.Length / 2); + for (int i = 0; i < words.Length; i += 2) { - owner.Span[i] = Words.Span[i].AsSpirvSpan()[0]; - owner.Span[i + 1] = Words.Span[i].AsSpirvSpan()[1]; + if (value is long) + { + long b = words[i] << 32 | words[i + 1]; + owner.Span[i] = Unsafe.As(ref b); + } + else if (value is double) + { + double b = BitConverter.Int64BitsToDouble(words[i] << 32 | words[i + 1]); + owner.Span[i] = Unsafe.As(ref b); + } } - return owner; + return new(owner); } - else throw new NotImplementedException($"Can't process type {typeof(T).FullName}"); + else throw new NotImplementedException(); } - public readonly void Dispose() => Words.Dispose(); - public readonly Span.Enumerator GetEnumerator() => Words.Span.GetEnumerator(); + public static LiteralArray From(string value) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs index 4b6422b134..6df38cf9e4 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -11,39 +11,49 @@ namespace Stride.Shaders.Spirv.Core; public struct LiteralFloat : ILiteralNumber, IFromSpirv { - public long Words { get; init; } + public MemoryOwner Data { get; init; } int size; public readonly int WordCount => size / 32; + public readonly ReadOnlySpan Words => Data.Span; + public LiteralFloat(Half value) { - Words = BitConverter.HalfToInt16Bits(value); + Data = MemoryOwner.Allocate(1); + Data.Span[0] = BitConverter.HalfToInt16Bits(value); size = 16; } public LiteralFloat(float value) { - Words = BitConverter.SingleToInt32Bits(value); ; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = BitConverter.SingleToInt32Bits(value); size = sizeof(float) * 8; } public LiteralFloat(double value) { - Words = BitConverter.DoubleToInt64Bits(value); + Data = MemoryOwner.Allocate(2); + Data.Span[0] = (int)(BitConverter.DoubleToInt64Bits(value) >> 32); + Data.Span[1] = (int)(BitConverter.DoubleToInt64Bits(value) & 0xFFFFFFFF); + size = sizeof(double) * 8; size = sizeof(double) * 8; } public LiteralFloat(Span words) { + Data = MemoryOwner.Allocate(words.Length); if (words.Length == 2) { size = sizeof(long) * 8; - Words = words[0] << 32 | words[1]; + Data = MemoryOwner.Allocate(2); + Data.Span[0] = words[0] << 32 | words[1]; } else if (words.Length == 1) { size = sizeof(int) * 8; - Words = words[0]; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = words[0]; } } @@ -52,72 +62,61 @@ public LiteralFloat(Span words) public static implicit operator LiteralFloat(Half value) => new(value); public static implicit operator LiteralFloat(float value) => new(value); public static implicit operator LiteralFloat(double value) => new(value); - public static implicit operator LiteralInteger(LiteralFloat value) => new(value.Words); - public static implicit operator float(LiteralFloat value) => BitConverter.Int32BitsToSingle((int)value.Words); - public static implicit operator double(LiteralFloat value) => BitConverter.Int64BitsToDouble(value.Words); - - + // public static implicit operator LiteralInteger(LiteralFloat value) => new(value.Data); + public static implicit operator float(LiteralFloat value) => BitConverter.Int32BitsToSingle((int)value.Data.Span[0]); + public static implicit operator double(LiteralFloat value) => BitConverter.Int64BitsToDouble(value.Data.Span[0]); + + + + // public readonly bool TryCast(out Half value) + // { + // short bits = (short)(Data & 0X000000FF); + // if (size == 32) + // { + // value = BitConverter.Int16BitsToHalf(bits); + // return true; + // } + // else + // { + // value = Half.Zero; + // return false; + // } + // } + // public readonly bool TryCast(out float value) + // { + // Span span = + // [ + // (int)(Data >> 32), + // (int)(Data & 0X0000FFFF) + // ]; + // if (size == 32) + // { + // value = BitConverter.Int32BitsToSingle(span[1]); + // return true; + // } + // else + // { + // value = 0; + // return false; + // } + // } + // public readonly bool TryCast(out double value) + // { + // if (size == 64) + // { + // value = BitConverter.Int64BitsToDouble(Data); + // return true; + // } + // else + // { + // value = 0; + // return false; + // } + // } - public readonly bool TryCast(out Half value) - { - short bits = (short)(Words & 0X000000FF); - if (size == 32) - { - value = BitConverter.Int16BitsToHalf(bits); - return true; - } - else - { - value = Half.Zero; - return false; - } - } - public readonly bool TryCast(out float value) - { - Span span = - [ - (int)(Words >> 32), - (int)(Words & 0X0000FFFF) - ]; - if (size == 32) - { - value = BitConverter.Int32BitsToSingle(span[1]); - return true; - } - else - { - value = 0; - return false; - } - } - public readonly bool TryCast(out double value) - { - if (size == 64) - { - value = BitConverter.Int64BitsToDouble(Words); - return true; - } - else - { - value = 0; - return false; - } - } - public readonly void Write(ref SpirvWriter writer) - { - Span span = - [ - (int)(Words >> 32), - (int)(Words & 0xFFFFFFFF) - ]; - if (size < 64) - writer.Write(span[1]); - else - writer.Write(span); - } public static LiteralFloat From(Span words) => new(words); @@ -125,22 +124,20 @@ public static LiteralFloat From(string value) { throw new NotImplementedException(); } - public readonly SpanOwner AsSpanOwner() - { - Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; - var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); - span.CopyTo(owner.Span); - return owner; - } - public override string ToString() + public readonly override string ToString() { return size switch { - 16 => $"{BitConverter.UInt16BitsToHalf((ushort)(Words & 0xFFFF))}", - 32 => $"{BitConverter.Int32BitsToSingle((int)(Words & 0xFFFFFFFF))}", - 64 => $"{BitConverter.Int64BitsToDouble(Words)}", + 16 => $"{BitConverter.UInt16BitsToHalf((ushort)(Data.Span[0] & 0xFFFF))}", + 32 => $"{BitConverter.Int32BitsToSingle(Data.Span[0])}", + 64 => $"{BitConverter.Int64BitsToDouble(Data.Span[0] << 32 | Data.Span[1])}", _ => throw new NotImplementedException() }; } + + public void Dispose() + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs index 3850cae8ce..d942be11d9 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs @@ -6,72 +6,77 @@ namespace Stride.Shaders.Spirv.Core; public struct LiteralInteger : ILiteralNumber, IFromSpirv { - public long Words { get; init; } + public MemoryOwner Data { get; init; } public int Size { get; init; } public readonly int WordCount => Size / 32; + public readonly ReadOnlySpan Words => Data.Span; + public LiteralInteger(sbyte value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(sbyte) * 8; } public LiteralInteger(byte value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(byte) * 8; } public LiteralInteger(short value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(short) * 8; } public LiteralInteger(ushort value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(ushort) * 8; } public LiteralInteger(int value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = 0 | value; Size = sizeof(int) * 8; } public LiteralInteger(int? value) { - Words = 0 | value ?? 0; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value ?? 0; Size = sizeof(int) * 8; } public LiteralInteger(uint value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = (int)value; Size = sizeof(uint) * 8; } public LiteralInteger(long value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(2); + Data.Span[0] = (int)(value >> 32); + Data.Span[1] = (int)(value & 0xFFFFFFFF); Size = sizeof(long) * 8; } public LiteralInteger(ulong value) { - Words = (long)value; + Data = MemoryOwner.Allocate(2); + Data.Span[0] = (int)(value >> 32); + Data.Span[1] = (int)(value & 0xFFFFFFFF); Size = sizeof(ulong) * 8; } public LiteralInteger(Span value) { - if (value.Length == 2) - { - Size = sizeof(long) * 8; - Words = value[0] << 32 | value[1]; - } - else if (value.Length == 1) - { - Size = sizeof(int) * 8; - Words = value[0]; - } + Data = MemoryOwner.Allocate(value.Length); + value.CopyTo(Data.Span); } @@ -84,20 +89,7 @@ public LiteralInteger(Span value) public static implicit operator LiteralInteger(uint value) => new(value); public static implicit operator LiteralInteger(long value) => new(value); public static implicit operator LiteralInteger(ulong value) => new(value); - public static implicit operator int(LiteralInteger value) => (int)value.Words; - - public readonly void Write(ref SpirvWriter writer) - { - Span span = - [ - (int)(Words >> 32), - (int)(Words & 0X000000FF) - ]; - if (Size < 64) - writer.Write(span[1]); - else - writer.Write(span); - } + public static implicit operator int(LiteralInteger value) => value.Data.Span[0]; public static LiteralInteger From(Span words) { @@ -109,87 +101,90 @@ public static LiteralInteger From(string value) throw new NotImplementedException(); } - public readonly SpanOwner AsSpanOwner() + public override readonly string ToString() => $"{Data}"; + + public void Dispose() { - Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; - var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); - span.CopyTo(owner.Span); - return owner; + throw new NotImplementedException(); } - - public override readonly string ToString() => $"{Words}"; } + public struct LiteralExtInstInteger : ILiteralNumber, IFromSpirv { - public long Words { get; init; } + public MemoryOwner Data { get; init; } public int Size { get; init; } public readonly int WordCount => Size / 32; + public readonly ReadOnlySpan Words => Data.Span; + public LiteralExtInstInteger(sbyte value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(sbyte) * 8; } public LiteralExtInstInteger(byte value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(byte) * 8; } public LiteralExtInstInteger(short value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(short) * 8; } public LiteralExtInstInteger(ushort value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value; Size = sizeof(ushort) * 8; } public LiteralExtInstInteger(int value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = 0 | value; Size = sizeof(int) * 8; } public LiteralExtInstInteger(int? value) { - Words = 0 | value ?? 0; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = value ?? 0; Size = sizeof(int) * 8; } public LiteralExtInstInteger(uint value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(1); + Data.Span[0] = (int)value; Size = sizeof(uint) * 8; } public LiteralExtInstInteger(long value) { - Words = 0 | value; + Data = MemoryOwner.Allocate(2); + Data.Span[0] = (int)(value >> 32); + Data.Span[1] = (int)(value & 0xFFFFFFFF); Size = sizeof(long) * 8; } public LiteralExtInstInteger(ulong value) { - Words = (long)value; + Data = MemoryOwner.Allocate(2); + Data.Span[0] = (int)(value >> 32); + Data.Span[1] = (int)(value & 0xFFFFFFFF); Size = sizeof(ulong) * 8; } public LiteralExtInstInteger(Span value) { - if (value.Length == 2) - { - Size = sizeof(long) * 8; - Words = value[0] << 32 | value[1]; - } - else if (value.Length == 1) - { - Size = sizeof(int) * 8; - Words = value[0]; - } + Data = MemoryOwner.Allocate(value.Length); + value.CopyTo(Data.Span); } @@ -202,20 +197,7 @@ public LiteralExtInstInteger(Span value) public static implicit operator LiteralExtInstInteger(uint value) => new(value); public static implicit operator LiteralExtInstInteger(long value) => new(value); public static implicit operator LiteralExtInstInteger(ulong value) => new(value); - public static implicit operator int(LiteralExtInstInteger value) => (int)value.Words; - - public readonly void Write(ref SpirvWriter writer) - { - Span span = - [ - (int)(Words >> 32), - (int)(Words & 0X000000FF) - ]; - if (Size < 64) - writer.Write(span[1]); - else - writer.Write(span); - } + public static implicit operator int(LiteralExtInstInteger value) => value.Data.Span[0]; public static LiteralExtInstInteger From(Span words) { @@ -227,13 +209,10 @@ public static LiteralExtInstInteger From(string value) throw new NotImplementedException(); } - public readonly SpanOwner AsSpanOwner() + public override readonly string ToString() => $"{Data}"; + + public void Dispose() { - Span span = WordCount == 1 ? [(int)Words] : [(int)(Words >> 32), (int)(Words & 0xFFFFFFFF)]; - var owner = SpanOwner.Allocate(span.Length, AllocationMode.Clear); - span.CopyTo(owner.Span); - return owner; + throw new NotImplementedException(); } - - public override readonly string ToString() => $"{Words}"; } diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs index b27ddd70cc..7dad0706af 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -11,6 +11,7 @@ namespace Stride.Shaders.Spirv.Core; { readonly static StringPool pool = new(); + public MemoryOwner Memory { get; init; } public string Value { get; init; } public readonly int Length => Value.Length + 1; @@ -18,12 +19,18 @@ namespace Stride.Shaders.Spirv.Core; internal bool HasRest => Length % 4 > 0; internal int RestSize => Length % 4; + public ReadOnlySpan Words => Memory.Span; + public LiteralString(string value) { Value = pool.GetOrAdd(value); + Memory = MemoryOwner.Allocate(WordCount); + } public LiteralString(Span words) { + Memory = MemoryOwner.Allocate(WordCount); + words.CopyTo(Memory.Span); Span chars = stackalloc char[words.Length * 4]; for (int i = 0; i < words.Length; i++) { @@ -112,14 +119,8 @@ public static LiteralString From(Span words) public static LiteralString From(string value) => value; - public SpanOwner AsSpanOwner() + public void Dispose() { - return Value.AsSpanOwner(); + Memory.Dispose(); } -} - -public static class SpirvStringExtensions -{ - public static LiteralString ToLiteralString(this string value) => value; - } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index 4694f9c56d..f929a6e1b7 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -1,9 +1,17 @@ using System.Numerics; -using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Text; using CommunityToolkit.HighPerformance.Buffers; namespace Stride.Shaders.Spirv.Core; +public struct Id(int id) +{ + public int Value { get; set; } = id; + + public static implicit operator Id(int v) => new(v); + public static implicit operator int(Id id) => id.Value; +} public struct LiteralValue : ISpirvElement, IFromSpirv> { @@ -24,19 +32,58 @@ or LiteralValue or LiteralValue or LiteralValue or LiteralValue - or LiteralValue => true, - + or LiteralValue + or LiteralValue<(int, int)> => true, _ => throw new Exception("Type not supported in SPIR-V") }; } - public MemoryOwner Words { get; private set; } + public bool dispose; + public MemoryOwner MemoryOwner { get; private set; } + public readonly ReadOnlySpan Words => MemoryOwner.Span; public T Value { get; set { field = value; UpdateMemory(); } } public readonly int WordCount => Words.Length; - public LiteralValue(T value) + public LiteralValue(Span words, bool dispose = false) + { + this.dispose = dispose; + T value = default!; + if (value is bool) + Unsafe.As(ref value) = words[0] != 0; + else if (value is byte) + Unsafe.As(ref value) = (byte)words[0]; + else if (value is sbyte) + Unsafe.As(ref value) = (sbyte)words[0]; + else if (value is short) + Unsafe.As(ref value) = (short)words[0]; + else if (value is ushort) + Unsafe.As(ref value) = (ushort)words[0]; + else if (value is uint) + Unsafe.As(ref value) = (uint)words[0]; + else if (value is int) + Unsafe.As(ref value) = words[0]; + else if (value is float) + Unsafe.As(ref value) = BitConverter.Int32BitsToSingle(words[0]); + else if (value is long) + Unsafe.As(ref value) = ((long)words[0] << 32) | (uint)words[1]; + else if (value is ulong) + Unsafe.As(ref value) = ((ulong)words[0] << 32) | (uint)words[1]; + else if (value is double) + Unsafe.As(ref value) = BitConverter.Int64BitsToDouble(((long)words[0] << 32) | (uint)words[1]); + else if (value is ValueTuple) + Unsafe.As(ref value) = (words[0], words[1]); + + Value = value; + + MemoryOwner = MemoryOwner.Allocate(words.Length, AllocationMode.Clear); + words.CopyTo(MemoryOwner.Span); + UpdateMemory(); + } + public LiteralValue(T value, bool dispose = false) { + this.dispose = dispose; Value = value; - Words = MemoryOwner.Empty; + MemoryOwner = MemoryOwner.Empty; + UpdateMemory(); } void UpdateMemory() @@ -44,15 +91,19 @@ void UpdateMemory() int wordCount = Value switch { bool or byte or sbyte or short or ushort or Half or int or uint or float => 1, - long or ulong or double => 2, - string => throw new NotImplementedException("Can't compute string literal value yet"), - _ => throw new NotImplementedException() + long or ulong or double or ValueTuple => 2, + Enum => 1, + string s => (s.Length / 4) + (s.Length % 4 > 0 ? 1 : 0), + null => 0, + _ => throw new NotImplementedException("Can't compute literal value for type " + typeof(T)) }; - Words.Dispose(); - Words = MemoryOwner.Allocate(wordCount, AllocationMode.Clear); + if(MemoryOwner == null) + MemoryOwner = MemoryOwner.Empty; + else MemoryOwner.Dispose(); + MemoryOwner = MemoryOwner.Allocate(wordCount, AllocationMode.Clear); if (Value is bool or byte or sbyte or short or ushort or Half or int or uint or float) { - Words.Span[0] = Value switch + MemoryOwner.Span[0] = Value switch { bool b => b ? 1 : 0, byte b => b, @@ -66,30 +117,45 @@ void UpdateMemory() _ => throw new NotImplementedException() }; } - else if (Value is long or double) + else if (Value is long or double or ValueTuple) { - Words.Span[0] = Value switch + MemoryOwner.Span[0] = Value switch { long l => (int)(l >> 16), double d => (int)BitConverter.DoubleToInt64Bits(d) >> 16, + ValueTuple vt => vt.Item1, _ => throw new NotImplementedException() }; - Words.Span[1] = Value switch + MemoryOwner.Span[1] = Value switch { long l => (int)(l & 0xFFFFFFFF), double d => (int)(BitConverter.DoubleToInt64Bits(d) & 0xFFFFFFFF), + ValueTuple vt => vt.Item2, _ => throw new NotImplementedException() }; } - else if (Value is string) + else if (Value is string s) { - throw new NotImplementedException("Can't process strings yet"); + for (int i = 0; i < s.Length; i++) + { + var pos = i / 4; + var shift = 8 * (i % 4); + var value = i < s.Length ? s[i] : '\0'; + MemoryOwner.Span[pos] |= value << shift; + } } } public static LiteralValue From(Span words) { - throw new NotImplementedException(); + T value = default!; + return (value, words.Length) switch + { + (bool or byte or sbyte or short or ushort or Half or int or uint or float, 1) => new LiteralValue(words), + (long or ulong or double or ValueTuple, 2) => new LiteralValue(words), + (string, > 0) => new LiteralValue(words), + _ => throw new NotImplementedException("Cannot create LiteralValue from the provided words") + }; } public static LiteralValue From(string value) @@ -97,8 +163,108 @@ public static LiteralValue From(string value) throw new NotImplementedException(); } - public readonly void Dispose() => Words.Dispose(); + public readonly void Dispose() => MemoryOwner.Dispose(); public static implicit operator LiteralValue(T s) => new(s); public static implicit operator T(LiteralValue lv) => lv.Value; + + + public readonly Enumerator GetEnumerator() => new(MemoryOwner, dispose); + + public ref struct Enumerator(MemoryOwner memory, bool dispose) + { + Span.Enumerator enumerator = memory.Span.GetEnumerator(); + + public int Current => enumerator.Current; + public bool MoveNext() + { + if (!enumerator.MoveNext()) + { + if (dispose) + memory.Dispose(); + return false; + } + else return true; + } + } +} + + + +public static class LiteralValueExtensions +{ + public static LiteralValue AsLiteralValue(this T value) where T : struct, INumber => new(value); + public static LiteralValue AsLiteralValue(this T? value) where T : struct, INumber => new(value ?? default); + public static LiteralValue AsLiteralValue(this bool value) => new(value); + public static LiteralValue<(int, int)> AsLiteralValue(this (int, int) value) => new(value); + public static LiteralValue AsLiteralValue(this string value) => new(value); + + public static LiteralValue AsDisposableLiteralValue(this T value) where T : struct, INumber => new(value, true); + public static LiteralValue AsDisposableLiteralValue(this T? value) where T : struct, INumber => new(value ?? default, true); + public static LiteralValue AsDisposableLiteralValue(this bool value) => new(value, true); + public static LiteralValue<(int, int)> AsDisposableLiteralValue(this (int, int) value) => new(value, true); + public static LiteralValue AsDisposableLiteralValue(this string value) => new(value, true); +} + + +static class TemporaryArrayBuilder +{ + public static TemporaryArray Create(ReadOnlySpan values) => new(values); + + + static void Something() + { + var x = "hello".AsLiteralValue(); + TemporaryArray tmp = [.. x]; + } +} + + +[CollectionBuilder(typeof(TemporaryArrayBuilder), "Create")] +struct TemporaryArray : IDisposable +{ + MemoryOwner Memory { get; set; } + + int Length { get; set; } + + public TemporaryArray(ReadOnlySpan initialValues) + { + Memory = MemoryOwner.Allocate((int)BitOperations.RoundUpToPowerOf2((uint)initialValues.Length), AllocationMode.Clear); + initialValues.CopyTo(Memory.Span); + Length = initialValues.Length; + } + + + void Expand(int size) + { + if (Length + size > Memory.Length) + { + MemoryOwner newMemory = MemoryOwner.Allocate(Memory.Length * 2, AllocationMode.Clear); + Memory.Span.CopyTo(newMemory.Span); + Memory.Dispose(); + Memory = newMemory; + } + } + + public void Add(LiteralValue item) + { + Expand(item.WordCount); + item.Words.CopyTo(Memory.Span[Length..]); + Length += item.WordCount; + } + public void Add(LiteralArray item) + { + Expand(item.WordCount); + item.Words.CopyTo(Memory.Span[Length..]); + Length += item.WordCount; + } + public void Add(int value) + { + Expand(1); + Memory.Span[Length] = value; + Length += 1; + } + + public readonly Span.Enumerator GetEnumerator() => Memory.Span[..Length].GetEnumerator(); + public readonly void Dispose() => Memory.Dispose(); } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs index 799e4a197f..bdebe600f9 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs @@ -3,33 +3,37 @@ namespace Stride.Shaders.Spirv.Core; -public record struct PairIdRefIdRef((int,int) Value) : ISpirvElement, IFromSpirv +public struct PairIdRefIdRef : ISpirvElement, IFromSpirv { + public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; + MemoryOwner Memory { get; set; } + public readonly ReadOnlySpan Words => Memory.Span; - public static implicit operator (int,int)(PairIdRefIdRef r) => r.Value; - public static implicit operator PairIdRefIdRef((int,int) v) => new(v); - public static implicit operator LiteralInteger(PairIdRefIdRef v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); - public static PairIdRefIdRef From(Span words) => new() { Value = (words[0], words[1]) }; - - public static PairIdRefIdRef From(string value) + public PairIdRefIdRef() { - throw new NotImplementedException(); + Memory = MemoryOwner.Allocate(2, AllocationMode.Clear); + } + public PairIdRefIdRef((int, int) value) + { + Memory = MemoryOwner.Allocate(2); + Memory.Span[0] = value.Item1; + Memory.Span[1] = value.Item2; } - public readonly SpanOwner AsSpanOwner() + public static implicit operator (int, int)(PairIdRefIdRef r) => (r.Item1, r.Item2); + public static implicit operator PairIdRefIdRef((int, int) v) => new(v); + public static implicit operator LiteralInteger(PairIdRefIdRef v) => new((ulong)(v.Item1 << 16 | v.Item2)); + public static PairIdRefIdRef From(Span words) => new() { Item1 = words[0], Item2 = words[1] }; + + public static PairIdRefIdRef From(string value) { - return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); + throw new NotImplementedException(); } -} -public static class PairIdRefIdRefExtensions -{ - public static SpanOwner AsSpanOwner(this PairIdRefIdRef? value) + public void Dispose() { - if(value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); + throw new NotImplementedException(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs index 0fd5442c71..fcf6307cf9 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs @@ -2,33 +2,37 @@ namespace Stride.Shaders.Spirv.Core; - -public record struct PairIdRefLiteralInteger((int,int) Value) : ISpirvElement, IFromSpirv +public struct PairIdRefLiteralInteger : ISpirvElement, IFromSpirv { + public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; + MemoryOwner Memory { get; set; } + public readonly ReadOnlySpan Words => Memory.Span; + + public PairIdRefLiteralInteger() + { + Memory = MemoryOwner.Allocate(2, AllocationMode.Clear); + } + public PairIdRefLiteralInteger((int, int) value) + { + Memory = MemoryOwner.Allocate(2); + Memory.Span[0] = value.Item1; + Memory.Span[1] = value.Item2; + } - public static implicit operator (int,int)(PairIdRefLiteralInteger r) => r.Value; - public static implicit operator PairIdRefLiteralInteger((int,int) v) => new(v); - public static implicit operator LiteralInteger(PairIdRefLiteralInteger v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); - public static PairIdRefLiteralInteger From(Span words) => new() { Value = (words[0], words[1]) }; + public static implicit operator (int, int)(PairIdRefLiteralInteger r) => (r.Item1, r.Item2); + public static implicit operator PairIdRefLiteralInteger((int, int) v) => new(v); + public static implicit operator LiteralInteger(PairIdRefLiteralInteger v) => new((ulong)(v.Item1 << 16 | v.Item2)); + public static PairIdRefLiteralInteger From(Span words) => new() { Item1 = words[0], Item2 = words[1] }; public static PairIdRefLiteralInteger From(string value) { throw new NotImplementedException(); } - public readonly SpanOwner AsSpanOwner() - { - return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); - } -} -public static class PairIdRefLiteralIntegerExtensions -{ - public static SpanOwner AsSpanOwner(this PairIdRefLiteralInteger? value) + public void Dispose() { - if(value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); + throw new NotImplementedException(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs b/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs index a516780331..e3ef1824a5 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs @@ -3,32 +3,37 @@ namespace Stride.Shaders.Spirv.Core; -public record struct PairLiteralIntegerIdRef((int, int) Value) : ISpirvElement, IFromSpirv +public struct PairLiteralIntegerIdRef : ISpirvElement, IFromSpirv { + public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; + MemoryOwner Memory { get; set; } + public readonly ReadOnlySpan Words => Memory.Span; - public static implicit operator (int, int)(PairLiteralIntegerIdRef r) => r.Value; + public PairLiteralIntegerIdRef() + { + Memory = MemoryOwner.Allocate(2, AllocationMode.Clear); + } + public PairLiteralIntegerIdRef((int, int) value) + { + Memory = MemoryOwner.Allocate(2); + Memory.Span[0] = value.Item1; + Memory.Span[1] = value.Item2; + } + + public static implicit operator (int, int)(PairLiteralIntegerIdRef r) => (r.Item1, r.Item2); public static implicit operator PairLiteralIntegerIdRef((int, int) v) => new(v); - public static implicit operator LiteralInteger(PairLiteralIntegerIdRef v) => new((ulong)(v.Value.Item1 << 16 | v.Value.Item2)); - public static PairLiteralIntegerIdRef From(Span words) => new() { Value = (words[0], words[1]) }; + public static implicit operator LiteralInteger(PairLiteralIntegerIdRef v) => new((ulong)(v.Item1 << 16 | v.Item2)); + public static PairLiteralIntegerIdRef From(Span words) => new() { Item1 = words[0], Item2 = words[1] }; public static PairLiteralIntegerIdRef From(string value) { throw new NotImplementedException(); } - public readonly SpanOwner AsSpanOwner() + public void Dispose() { - return new LiteralInteger(Value.Item1 << 32 | Value.Item2).AsSpanOwner(); - } -} -public static class PairLiteralIntegerIdRefExtensions -{ - public static SpanOwner AsSpanOwner(this PairLiteralIntegerIdRef? value) - { - if (value is null) - return SpanOwner.Empty; - else - return value.Value.AsSpanOwner(); + throw new NotImplementedException(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs index e7a272bc29..e51e5a3237 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs @@ -5,15 +5,15 @@ namespace Stride.Shaders.Spirv.Core; -public record struct SpvEnum(T Value) : IFromSpirv> - where T : Enum -{ - public static implicit operator T(SpvEnum r) => r.Value; - public static implicit operator SpvEnum(T v) => new(v); - public static SpvEnum From(Span words) => new() { Value = Unsafe.As(ref words[0]) }; +// public record struct SpvEnum(T Value) : IFromSpirv> +// where T : Enum +// { +// public static implicit operator T(SpvEnum r) => r.Value; +// public static implicit operator SpvEnum(T v) => new(v); +// public static SpvEnum From(Span words) => new() { Value = Unsafe.As(ref words[0]) }; - public static SpvEnum From(string value) - { - throw new NotImplementedException(); - } -} \ No newline at end of file +// public static SpvEnum From(string value) +// { +// throw new NotImplementedException(); +// } +// } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index 04fd7e9c0a..5b0bf8259b 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -1,3 +1,4 @@ +using System.Data.SqlTypes; using System.Runtime.CompilerServices; namespace Stride.Shaders.Spirv.Core; @@ -39,15 +40,98 @@ public T ToEnum() where T : Enum { return Unsafe.As(ref Words[0]); } - public T To() where T : struct, IFromSpirv + + public readonly T To() { - if (Kind == OperandKind.IdRef && typeof(T) == typeof(IdRef)) + T tmp = default!; + if (tmp is bool or byte or sbyte or short or ushort or int or uint or float) + tmp = Unsafe.As(ref Words[0]); + else if (tmp is long or double or ValueTuple) + { + var value = Words[0] << 16 | Words[1]; + tmp = Unsafe.As(ref value); + } + else if (tmp is null && typeof(T) == typeof(string)) + { + using var lit = new LiteralValue(Words); + var result = lit.Value; + Unsafe.As(ref tmp) = result; + } + else if (tmp is Enum) + { + tmp = Unsafe.As(ref Words[0]); + } + else if (typeof(T).Name.Contains("LiteralArray")) { - var id = new IdRef(Words[0] + Offset); - var result = Unsafe.As(ref id); - return result; + if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray) + { + var result = LiteralArray.From(Words); + return Unsafe.As, T>(ref result); + } + else if (tmp is LiteralArray<(int, int)>) + { + var result = LiteralArray<(int, int)>.From(Words); + return Unsafe.As, T>(ref result); + } + else throw new NotImplementedException("Can't convert operand to type " + typeof(T)); } - return T.From(Words); + else throw new NotImplementedException($"Can't convert operand to type {typeof(T)}"); + return tmp; } public override string ToString() diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index 1bd685e3b0..644f7780fa 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -14,7 +14,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("public static Instruction AddOpConstant(this SpirvBuffer buffer, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpConstant, ..resultType.Words, resultId, ..value.Words]);") .AppendLine("}"); @@ -24,7 +24,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("public static Instruction InsertOpConstant(this SpirvBuffer buffer, int position, IdResult resultId, IdResultType? resultType, TValue value) where TValue : struct, ILiteralNumber") .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpConstant, ..resultType.Words, resultId, ..value.Words]);") .AppendLine("}"); @@ -36,7 +36,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.Words, resultId, ..value.Words]);") .AppendLine("}"); code.AppendLine(op.Documentation); code @@ -44,7 +44,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(resultType) + buffer.GetWordLength(resultId) + value.WordCount;") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.AsSpirvSpan(), resultId, ..value.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpSpecConstant, ..resultType.Words, resultId, ..value.Words]);") .AppendLine("}"); } else if (opname!.StartsWith("OpDecorate")) @@ -54,7 +54,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.Words, ..additional1.Words, ..additional2.Words, ..additionalString.Words]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -63,7 +63,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(target) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpDecorate, target, ..decoration.Words, ..additional1.Words, ..additional2.Words, ..additionalString.Words]);") .AppendLine("}"); } @@ -74,7 +74,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Add([wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.Words, ..member.Words, ..decoration.Words, ..additional1.Words, ..additional2.Words, ..additionalString.Words]);") .AppendLine("}"); code.AppendLine(op.Documentation); @@ -83,7 +83,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti .AppendLine("{") .AppendLine("var wordLength = 1 + buffer.GetWordLength(structureType) + buffer.GetWordLength(member) + buffer.GetWordLength(decoration) + buffer.GetWordLength(additional1) + buffer.GetWordLength(additional2) + buffer.GetWordLength(additionalString);") - .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.AsSpirvSpan(), ..member.AsSpirvSpan(), ..decoration.AsSpirvSpan(), ..additional1.AsSpirvSpan(), ..additional2.AsSpirvSpan(), ..additionalString.AsSpirvSpan()]);") + .AppendLine("return buffer.Insert(position, [wordLength << 16 | (int)Op.OpMemberDecorate, ..structureType.Words, ..member.Words, ..decoration.Words, ..additional1.Words, ..additional2.Words, ..additionalString.Words]);") .AppendLine("}"); } @@ -115,7 +115,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti ; code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); code - .AppendLine($"return buffer.Add([wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine($"return buffer.Add([wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.Words"))}]);") .AppendLine("}"); @@ -135,7 +135,7 @@ public static void CreateOperation(InstructionData op, StringBuilder code, Dicti ; code.Append("var wordLength = 1").Append(parameterNames.Any() ? " + " : "").Append(string.Join(" + ", parameterNames.Select(x => $"buffer.GetWordLength({x})"))).AppendLine(";"); code - .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.AsSpirvSpan()"))}]);") + .AppendLine($"return buffer.Insert(position, [wordLength << 16 | (int)Op.{opname}, {string.Join(", ", parameterNames.Select(x => $"..{x}.Words"))}]);") .AppendLine("}"); } else diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 7d684e3b59..1fda32c571 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -29,6 +29,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv .AppendLine("using CommunityToolkit.HighPerformance;") .AppendLine("using CommunityToolkit.HighPerformance.Buffers;") .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") + .AppendLine("using System.Numerics;") .AppendLine() .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine() @@ -42,220 +43,21 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv foreach (var instruction in instructions) { - if (instruction.OpName.StartsWith("OpCopyMemory")) - continue; body1.Clear(); body2.Clear(); body3.Clear(); body4.Clear(); - if (instruction.OpName.Contains("Constant")) - { - // foreach(var types in ["LiteralInteger", "LiteralFloat", "LiteralBool"]) - // builder.AppendLine($@" - // public struct {instruction.OpName}<{}> - - // "); - continue; - } + if (instruction.OpName.EndsWith("Constant")) + WriteConstantInstructions(grammar, instruction, builder, body1, body2, body3, body4); + else if (instruction.OpName.EndsWith("Decorate")) + WriteDecorateInstructions(grammar, instruction, builder, body1, body2, body3, body4); + else if (instruction.OpName.StartsWith("OpCopyMemory")) + WriteCopyMemoryInstructions(grammar, instruction, body1, body2, body3, body4); else if (instruction.OpName.Contains("GLSL")) - { - var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); - - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); - if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) - { - var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", allOperands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - - // Body 1 - if (allOperands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator IdRef({instruction.OpName} inst) => new IdRef(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - body1.AppendLine($"public int Instruction => {instruction.OpCode};"); - foreach (var operand in allOperands) - { - - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); - else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); - - // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To>();"); - else body2.AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); - } - body2.AppendLine("}"); - - body3.AppendLine("UpdateInstructionMemory();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .Append($"Span instruction = [(int)SDSLOp.{extinst.OpName}, ") - .Append(string.Join(", ", extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" }).Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $".. {fieldName}.AsSpirvSpan()"; - }))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); - - } - body2.AppendLine("}"); - - } - else - { - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); - - if (instruction.Operands?.AsList() is List operands) - { - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - - // Body 1 - - if (operands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator IdRef({instruction.OpName} inst) => new IdRef(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - foreach (var operand in operands) - { - - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); - else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); - - // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To>();"); - else body2.AppendLine($"{fieldName} = o.To{(operand.Class?.ToString().Contains("Enum") ?? false ? "Enum" : "")}<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); - } - body2.AppendLine("}"); - - body3.AppendLine("UpdateInstructionMemory();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .Append($"Span instruction = [(int)SDSLOp.{instruction.OpName}, ") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $".. {fieldName}.AsSpirvSpan()"; - }))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); - - } - else - body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); - - - } - builder.AppendLine($@" - public struct {instruction.OpName} : IMemoryInstruction - {{ - public OpDataIndex? DataIndex {{ get; set; }} - public MemoryOwner InstructionMemory - {{ - readonly get - {{ - if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; - else return field; - }} - - private set - {{ - if (DataIndex is OpDataIndex odi) - {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; - }} - else field = value; - }} - }} - - {body1} - {body2} - {body3} - {body4} - - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - }} - "); + WriteGLSLCode(grammar, instruction, builder, body1, body2, body3, body4); + else WriteOtherInstructions(grammar, instruction, builder, body1, body2, body3, body4); } } spc.AddSource( @@ -274,33 +76,27 @@ public static (string TypeName, string FieldName, string OperandName) ToTypeFiel { string typename = (operand.Kind, operand.Quantifier, operand.Class) switch { - // ("PairIdRefIdRef", null or "") => "(IdRef, IdRef)", - // ("PairIdRefLiteralInteger", null or "") => "(IdRef, LiteralInteger)", - // ("PairLiteralIntegerIdRef", null or "") => "(LiteralInteger, IdRef)", - - (string s, null or "", _) when s.StartsWith("Id") => "int", - ("LiteralInteger", null or "", _) => "int", - ("LiteralExtInstInteger", null or "", _) => "int", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", null or "", _) => "int", ("LiteralFloat", null or "", _) => "float", - ("LiteralString", null or "", _) => "LiteralString", + ("LiteralString", null or "", _) => "string", (string s, null or "", _) when s.StartsWith("Pair") => "(int, int)", (string s, null or "", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask", (string s, null or "", "ValueEnum") when !s.StartsWith("Literal") => s, (string s, "?", _) when s.StartsWith("Id") => "int?", - ("LiteralInteger", "?", _) => "int?", - ("LiteralExtInstInteger", "?", _) => "int?", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "?", _) => "int?", ("LiteralFloat", "?", _) => "float?", - ("LiteralString", "?", _) => "LiteralString?", + ("LiteralString", "?", _) => "string?", (string s, "?", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask?", (string s, "?", "ValueEnum") when !s.StartsWith("Literal") => $"{s}?", - (string s, "*", _) when s.StartsWith("Id") => $"LiteralArray<{s}>", - ("LiteralInteger", "*", _) => "LiteralArray", - ("LiteralExtInstInteger", "*", _) => "LiteralArray", - ("LiteralFloat", "*", _) => "LiteralArray", - ("LiteralString", "*", _) => "LiteralArray", - // (string s, "*") when !s.StartsWith("Literal") => $"LiteralArray<{s}>", - (string s, "*", _) when s.StartsWith("Pair") => $"LiteralArray<{s}>", + (string s, "*", _) when s.StartsWith("Id") => $"LiteralArray", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "*", _) => "LiteralArray", + ("LiteralFloat", "*", _) => "LiteralArray", + // ("LiteralString", "*", _) => "LiteralArray", + (string s, "*", _) when s.StartsWith("Pair") => $"LiteralArray<(int, int)>", + (string s, "*", "BitEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}Mask>", + (string s, "*", "ValueEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}>", + ("LiteralContextDependentNumber", null or "", _) => "LiteralValue", _ => throw new NotImplementedException($"Could not generate C# type for '{operand.Kind}{operand.Quantifier}'") }; @@ -326,4 +122,492 @@ public static (string TypeName, string FieldName, string OperandName) ToTypeFiel } return (typename, fieldName, operandName); } + + + static string ToSpreadOperator(OperandData operand) + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + return (operand.Class, operand.Quantifier) switch + { + (string s, null or "") when s.Contains("Id") => $"{fieldName}", + (string s, "?") when s.Contains("Id") => $".. {fieldName} is null ? (Span)[] : [{fieldName}.Value]", + (string s, null or "") when s.Contains("Enum") => $"(int){fieldName}", + (string s, "?") when s.Contains("Enum") => $".. {fieldName} is null ? (Span)[] : [(int){fieldName}.Value]", + (string, "*") => $".. {fieldName}.Words", + (string, "?") => $".. {fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words", + _ => $".. {fieldName}.AsDisposableLiteralValue().Words" + }; + } + + + static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + { + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + + if (instruction.Operands?.AsList() is List operands) + { + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + + if (operands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + foreach (var operand in operands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray")) + body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + else if (operand.Class is string s && s.Contains("Enum")) + body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + else body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + body2.AppendLine("}"); + + body3 + .AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") + .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") + .Append(string.Join(", ", operands.Select(ToSpreadOperator))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + else + body4.AppendLine("public void UpdateInstructionMemory(){}"); + body2.AppendLine("}"); + + builder.AppendLine($@" + public struct {instruction.OpName} : IMemoryInstruction + {{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner InstructionMemory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} + + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + }} + "); + } + static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + { + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + + if (instruction.Operands?.AsList() is List operands) + { + operands.Add(new(){Name = "additional1", Kind = "LiteralInteger", Quantifier = "?"}); + operands.Add(new(){Name = "additional2", Kind = "LiteralInteger", Quantifier = "?"}); + operands.Add(new(){Name = "additionalString", Kind = "LiteralString", Quantifier = "?"}); + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName} {(typename.EndsWith("?") ? "= null" : "")}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + + if (operands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + foreach (var operand in operands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray")) + body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + else if (operand.Class is string s && s.Contains("Enum")) + body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + else body2.AppendLine($"{fieldName} = o.To>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + body2.AppendLine("}"); + + body3 + .AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") + .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") + .Append(string.Join(", ", operands.Select(ToSpreadOperator))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + else + body4.AppendLine("public void UpdateInstructionMemory(){}"); + body2.AppendLine("}"); + + builder.AppendLine($@" + public struct {instruction.OpName} : IMemoryInstruction + {{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner InstructionMemory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} + + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + }} + "); + } + + static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + { + var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); + + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) + { + var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", allOperands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + if (allOperands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + body1.AppendLine($"public int Instruction => {instruction.OpCode};"); + foreach (var operand in allOperands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray")) + { + body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + } + else if (operand.Class is string s && s.Contains("Enum")) + body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + else body2.AppendLine($"{fieldName} = o.To>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + body2.AppendLine("}"); + + body3.AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") + .Append($"Span instruction = [(int)Op.{extinst.OpName}, ") + .Append(string.Join(", ", extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" }).Select(ToSpreadOperator))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + body2.AppendLine("}"); + builder.AppendLine($@" + public struct {instruction.OpName} : IMemoryInstruction + {{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner InstructionMemory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} + + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + }} + "); + + } + + static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + { + body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") + .AppendLine("{") + .AppendLine("DataIndex = index;"); + + if (instruction.Operands?.AsList() is List operands) + { + body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + .AppendLine("{"); + + body3.Append($"public {instruction.OpName}(") + .Append(string.Join(", ", operands.Select(x => + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); + return $"{typename} {operandName}"; + }))) + .AppendLine(")") + .AppendLine("{"); + + + // Body 1 + + + foreach (var operand in operands) + { + + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + + if (typename.StartsWith("LiteralArray")) + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + else if(typename.StartsWith("LiteralValue")) + body1.Append($"public T {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + else + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + + // Body 2 + body2.AppendLine($"if(o.Name == \"{operandName}\")"); + if (typename.StartsWith("LiteralArray") || typename.StartsWith("LiteralValue")) + body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + else if (operand.Class is string s && s.Contains("Enum")) + body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); + else body2.AppendLine($"{fieldName} = o.To>();"); + // Body 3 + if (typename.StartsWith("LiteralArray")) + body3.AppendLine($"{fieldName}.Assign({operandName});"); + else body3.AppendLine($"{fieldName} = {operandName};"); + } + + if (operands.Any(x => x is { Kind: "IdResult" })) + body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") + .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + body2.AppendLine("}"); + + body3.AppendLine("UpdateInstructionMemory();") + .AppendLine("}"); + + // Body 4 + + body4.AppendLine("public void UpdateInstructionMemory()") + .AppendLine("{") + .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") + .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") + .Append(string.Join(", ", operands.Select(ToSpreadOperator))) + .Append("];") + .AppendLine(@" + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + }" + ) + .AppendLine("}"); + + } + else + body4.AppendLine("public void UpdateInstructionMemory(){}"); + body2.AppendLine("}"); + builder.AppendLine($@" + // {string.Join(", ", instruction.Operands?.AsList().Select(x => $"{x.Name}:{x.Kind}"))} + public struct {instruction.OpName} : IMemoryInstruction + where T : struct, INumber + {{ + public OpDataIndex? DataIndex {{ get; set; }} + public MemoryOwner InstructionMemory + {{ + readonly get + {{ + if (DataIndex is OpDataIndex odi) + return odi.Buffer[odi.Index].Memory; + else return field; + }} + + private set + {{ + if (DataIndex is OpDataIndex odi) + {{ + odi.Buffer[odi.Index].Memory.Dispose(); + odi.Buffer[odi.Index].Memory = value; + }} + else field = value; + }} + }} + + {body1} + {body2} + {body3} + {body4} + + public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + }} + "); + } + static void WriteCopyMemoryInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + { + + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 4ff25f4064..7e228325d4 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -38,10 +38,10 @@ public void Initialize(IncrementalGeneratorInitializationContext context) GenerateStructs(context, grammarData); CreateSpecification(context, grammarData); - context.RegisterImplementationSourceOutput( - grammarData, - BufferGeneration - ); + // context.RegisterImplementationSourceOutput( + // grammarData, + // BufferGeneration + // ); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index bb9e8c62dc..231f80a8bc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -25,9 +25,10 @@ public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, Compiler var type = compiler.Context.ReverseTypes[result.TypeId]; if (type is PointerType pointerType) { - type = pointerType.BaseType; - var inst = compiler.Builder.Buffer.InsertOpLoad(compiler.Builder.Position++, compiler.Context.Bound++, compiler.Context.Types[type], result.Id, null); - result = new(inst.ResultId.Value, inst.ResultType.Value); + #warning replace + // type = pointerType.BaseType; + // var inst = compiler.Builder.Buffer.InsertOpLoad(compiler.Builder.Position++, compiler.Context.Bound++, compiler.Context.Types[type], result.Id, null); + // result = new(inst.ResultId.Value, inst.ResultType.Value); } return result; @@ -41,16 +42,18 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var functionType = (FunctionType)Name.ResolveType(table); - Type = functionType.ReturnType; - - var (builder, context, module) = compiler; - var list = parameters.Values; - Span compiledParams = stackalloc IdRef[list.Count]; - var tmp = 0; - foreach(var p in list) - compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; - return builder.CallFunction(context, Name, compiledParams); + // var functionType = (FunctionType)Name.ResolveType(table); + // Type = functionType.ReturnType; + + // var (builder, context, module) = compiler; + // var list = parameters.Values; + // Span compiledParams = stackalloc IdRef[list.Count]; + // var tmp = 0; + // foreach(var p in list) + // compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; + // return builder.CallFunction(context, Name, compiledParams); + #warning replace + throw new NotImplementedException(); } public override string ToString() { @@ -144,37 +147,39 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = Source.Type; } - Span indexes = stackalloc IdRef[Accessors.Count]; - for (var i = firstIndex; i < Accessors.Count; i++) - { - var accessor = Accessors[i]; - if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) - { - var index = s.TryGetFieldIndex(field); - if (index == -1) - throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); - //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.Compile(table, shader, compiler); - indexes[i] = context.CreateConstant(indexLiteral).Id; - } - else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); - - currentValueType = accessor.Type; - } - - if (currentValueType is not PointerType) - throw new InvalidOperationException(); - - Type = currentValueType; + // Span indexes = stackalloc IdRef[Accessors.Count]; + // for (var i = firstIndex; i < Accessors.Count; i++) + // { + // var accessor = Accessors[i]; + // if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) + // { + // var index = s.TryGetFieldIndex(field); + // if (index == -1) + // throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + // //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + // var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + // indexLiteral.Compile(table, shader, compiler); + // indexes[i] = context.CreateConstant(indexLiteral).Id; + // } + // else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + + // currentValueType = accessor.Type; + // } + + // if (currentValueType is not PointerType) + // throw new InvalidOperationException(); + + // Type = currentValueType; // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) if (firstIndex == Accessors.Count) return source; var resultType = context.GetOrRegister(Type); - var result = builder.Buffer.InsertOpAccessChain(builder.Position++, variable, resultType, source.Id, indexes); - return new(result, resultType); + // var result = builder.Buffer.InsertOpAccessChain(builder.Position++, variable, resultType, source.Id, indexes); + // return new(result, resultType); + #warning replace + throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 4b7b302c7b..e1d1f5c9cc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -70,13 +70,17 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil _ => throw new NotImplementedException("Unsupported integer suffix") }; - var i = (Type, Suffix) switch - { - (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), LongValue), - (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), IntValue), - _ => throw new NotImplementedException("") - }; - return new SpirvValue(i, i.ResultType!.Value, null); +#warning replace + + throw new NotImplementedException(); + + // var i = (Type, Suffix) switch + // { + // (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), LongValue), + // (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), IntValue), + // _ => throw new NotImplementedException("") + // }; + // return new SpirvValue(i, i.ResultType!.Value, null); } } @@ -94,13 +98,15 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil 64 => ScalarType.From("double"), _ => throw new NotImplementedException("Unsupported float") }; - var i = (Type, Suffix) switch - { - (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), DoubleValue), - (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), (float)DoubleValue), - _ => throw new NotImplementedException("") - }; - return new SpirvValue(i, i.ResultType!.Value, null); +#warning replace + throw new NotImplementedException(); + // var i = (Type, Suffix) switch + // { + // (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), DoubleValue), + // (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), (float)DoubleValue), + // _ => throw new NotImplementedException("") + // }; + // return new SpirvValue(i, i.ResultType!.Value, null); } } @@ -117,12 +123,14 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var i = Value switch - { - true => compiler.Context.Buffer.AddOpConstantTrue(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)), - false => compiler.Context.Buffer.AddOpConstantFalse(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)) - }; - return new SpirvValue(i, i.ResultType!.Value, null); +#warning replace + // var i = Value switch + // { + // true => compiler.Context.Buffer.AddOpConstantTrue(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)), + // false => compiler.Context.Buffer.AddOpConstantFalse(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)) + // }; + // return new SpirvValue(i, i.ResultType!.Value, null); + throw new NotImplementedException(); } } @@ -142,15 +150,17 @@ public bool IsConstant() public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; - Span values = stackalloc IdRef[Values.Count]; - int tmp = 0; - foreach (var v in Values) - values[tmp++] = v.Compile(table, shader, compiler).Id; + #warning replace + throw new NotImplementedException(); + // var (builder, context, module) = compiler; + // Span values = stackalloc IdRef[Values.Count]; + // int tmp = 0; + // foreach (var v in Values) + // values[tmp++] = v.Compile(table, shader, compiler).Id; - Type = GenerateType(table); + // Type = GenerateType(table); - return builder.CompositeConstruct(context, this, values); + // return builder.CompositeConstruct(context, this, values); } } public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) @@ -250,23 +260,25 @@ public SymbolType ResolveType(SymbolTable table) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var symbol = ResolveSymbol(table); - Type = symbol.Type; +#warning replace + // var symbol = ResolveSymbol(table); + // Type = symbol.Type; - var (builder, context, _) = compiler; - var resultType = context.GetOrRegister(Type); - var result = new SpirvValue(symbol.IdRef, resultType, Name); + // var (builder, context, _) = compiler; + // var resultType = context.GetOrRegister(Type); + // var result = new SpirvValue(symbol.IdRef, resultType, Name); - if (symbol.AccessChain is int accessChainIndex) - { - Span indexes = stackalloc IdRef[1]; - var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); - indexLiteral.Compile(table, shader, compiler); - indexes[0] = context.CreateConstant(indexLiteral).Id; - result.Id = compiler.Builder.Buffer.InsertOpAccessChain(compiler.Builder.Position++, compiler.Context.Bound++, resultType, symbol.IdRef, indexes).ResultId.Value; - } + // if (symbol.AccessChain is int accessChainIndex) + // { + // Span indexes = stackalloc IdRef[1]; + // var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); + // indexLiteral.Compile(table, shader, compiler); + // indexes[0] = context.CreateConstant(indexLiteral).Id; + // result.Id = compiler.Builder.Buffer.InsertOpAccessChain(compiler.Builder.Position++, compiler.Context.Bound++, resultType, symbol.IdRef, indexes).ResultId.Value; + // } - return result; + // return result; + throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4a071f5d5e..3c2fdc5b3d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; @@ -101,7 +102,11 @@ public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) { externalShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); - var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + if(bytecode is null) + throw new InvalidOperationException($"Could not load shader '{mixin.Name}'"); + using var mem = MemoryOwner.Allocate(bytecode.Length / 4); + MemoryMarshal.Cast(bytecode).CopyTo(mem.Span); + var buffer = new SpirvBuffer(mem.Span); ProcessNameAndTypes(buffer, out var names, out var types); @@ -142,100 +147,101 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp public void Compile(CompilerUnit compiler, SymbolTable table) { - table.Push(); - foreach (var mixin in Mixins) - { - var shaderType = LoadShader(table.ShaderLoader, mixin); + #warning replace + // table.Push(); + // foreach (var mixin in Mixins) + // { + // var shaderType = LoadShader(table.ShaderLoader, mixin); - RegisterShaderType(table, shaderType); - } + // RegisterShaderType(table, shaderType); + // } - var symbols = new List(); - foreach (var member in Elements) - { - if (member is ShaderMethod func) - { - var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); - foreach (var arg in func.Parameters) - { - var argSym = arg.TypeName.ResolveType(table); - table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = argSym; - ftype.ParameterTypes.Add(arg.Type); - } - func.Type = ftype; - - table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); - } - else if (member is ShaderMember svar) - { - svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); - table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); - } - else if (member is CBuffer cb) - { - foreach (var cbMember in cb.Members) - { - cbMember.Type = cbMember.TypeName.ResolveType(table); - //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); - //symbols.Add(symbol); - } - } - } + // var symbols = new List(); + // foreach (var member in Elements) + // { + // if (member is ShaderMethod func) + // { + // var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); + // foreach (var arg in func.Parameters) + // { + // var argSym = arg.TypeName.ResolveType(table); + // table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + // arg.Type = argSym; + // ftype.ParameterTypes.Add(arg.Type); + // } + // func.Type = ftype; + + // table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); + // } + // else if (member is ShaderMember svar) + // { + // svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); + // table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + // } + // else if (member is CBuffer cb) + // { + // foreach (var cbMember in cb.Members) + // { + // cbMember.Type = cbMember.TypeName.ResolveType(table); + // //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); + // //symbols.Add(symbol); + // } + // } + // } - var currentShader = new ShaderSymbol(Name, symbols); - RegisterShaderType(table, currentShader); + // var currentShader = new ShaderSymbol(Name, symbols); + // RegisterShaderType(table, currentShader); - table.CurrentShader = currentShader; - foreach (var member in Elements) - { - member.ProcessSymbol(table); - } + // table.CurrentShader = currentShader; + // foreach (var member in Elements) + // { + // member.ProcessSymbol(table); + // } - var (builder, context, _) = compiler; - context.PutShaderName(Name); + // var (builder, context, _) = compiler; + // context.PutShaderName(Name); - foreach (var mixin in Mixins) - { - // Import types and variables/functions - var shader = context.Buffer.AddOpSDSLImportShader(context.Bound++, new(mixin.Name)); - - var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; - - foreach (var c in shaderType.Components) - { - if (c.Id.Kind == SymbolKind.Variable) - { - var variableTypeId = context.GetOrRegister(c.Type); - var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); - context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); - table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId.Value }); - } - else if (c.Id.Kind == SymbolKind.Method) - { - var functionType = (FunctionType)c.Type; - - var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); - context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); - table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId.Value }); - } - } - - // Mark inherit - context.Buffer.AddOpSDSLMixinInherit(shader); - context.Module.InheritedMixins.Add(shaderType); - } + // foreach (var mixin in Mixins) + // { + // // Import types and variables/functions + // var shader = context.Buffer.AddOpSDSLImportShader(context.Bound++, new(mixin.Name)); + + // var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; + + // foreach (var c in shaderType.Components) + // { + // if (c.Id.Kind == SymbolKind.Variable) + // { + // var variableTypeId = context.GetOrRegister(c.Type); + // var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); + // context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); + // table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId.Value }); + // } + // else if (c.Id.Kind == SymbolKind.Method) + // { + // var functionType = (FunctionType)c.Type; + + // var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); + // var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); + // context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); + // table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId.Value }); + // } + // } + + // // Mark inherit + // context.Buffer.AddOpSDSLMixinInherit(shader); + // context.Module.InheritedMixins.Add(shaderType); + // } - foreach (var member in Elements.OfType()) - member.Compile(table, this, compiler); - foreach (var member in Elements.OfType()) - member.Compile(table, this, compiler); - foreach(var method in Elements.OfType()) - method.Compile(table, this, compiler); + // foreach (var member in Elements.OfType()) + // member.Compile(table, this, compiler); + // foreach (var member in Elements.OfType()) + // member.Compile(table, this, compiler); + // foreach(var method in Elements.OfType()) + // method.Compile(table, this, compiler); - table.CurrentShader = null; - table.Pop(); + // table.CurrentShader = null; + // table.Pop(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 124111a94a..fef771a979 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -83,30 +83,31 @@ public sealed class ShaderMember( public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; - var registeredType = context.GetOrRegister(Type); - var variable = context.Bound++; - // TODO: Add a StreamSDSL storage class? - context.Buffer.AddOpVariable(variable, registeredType, Specification.StorageClass.Private, null); - context.Variables.Add(Name, new(variable, registeredType, Name)); - if (Semantic != null) - context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); - context.AddName(variable, Name); - - var sid = - new SymbolID - ( - Name, - TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, - StreamKind switch - { - StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, - _ => Storage.None - } - ); - var symbol = new Symbol(sid, Type, variable); - table.CurrentShader.Components.Add(symbol); - table.CurrentFrame.Add(Name, symbol); + #warning replace + // var (builder, context, _) = compiler; + // var registeredType = context.GetOrRegister(Type); + // var variable = context.Bound++; + // // TODO: Add a StreamSDSL storage class? + // context.Buffer.AddOpVariable(variable, registeredType, Specification.StorageClass.Private, null); + // context.Variables.Add(Name, new(variable, registeredType, Name)); + // if (Semantic != null) + // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); + // context.AddName(variable, Name); + + // var sid = + // new SymbolID + // ( + // Name, + // TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, + // StreamKind switch + // { + // StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, + // _ => Storage.None + // } + // ); + // var symbol = new Symbol(sid, Type, variable); + // table.CurrentShader.Components.Add(symbol); + // table.CurrentFrame.Add(Name, symbol); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 40ef74c1b3..3710e92433 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -208,7 +208,8 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? - context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); + #warning replace + // context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); //context.Variables.Add(Name, new(variable, registeredType, Name)); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 46b882a3f7..a194976b75 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -146,14 +146,16 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var registeredType = context.GetOrRegister(new PointerType(Type!, Specification.StorageClass.Function)); foreach (var d in Variables) { - var variable = context.Bound++; - var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); - context.AddName(variable, d.Variable); + // var variable = context.Bound++; + // var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); + // context.AddName(variable, d.Variable); - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); + // table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); - if (builder.CurrentFunction is SpirvFunction f) - f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); + // if (builder.CurrentFunction is SpirvFunction f) + // f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); +#warning replace + throw new NotImplementedException(); } } public override string ToString() @@ -168,23 +170,25 @@ public class Assign(TextLocation info) : Statement(info) public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; - foreach (var variable in Variables) - { - var target = variable.Variable.Compile(table, shader, compiler); - var source = variable.Value!.Compile(table, shader, compiler); - if (variable.Variable.Type is not PointerType) - throw new InvalidOperationException("can only assign to pointer type"); - if (variable.Value!.Type is PointerType p) - { - var sourceLoad = context.Bound++; - var underlyingType = context.GetOrRegister(p.BaseType); - builder.Buffer.InsertOpLoad(builder.Position++, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.None); - source = new(sourceLoad, underlyingType); - } - - var instruction = builder.Buffer.InsertOpStore(builder.Position++, target.Id, source.Id, null); - } + // var (builder, context, _) = compiler; + // foreach (var variable in Variables) + // { + // var target = variable.Variable.Compile(table, shader, compiler); + // var source = variable.Value!.Compile(table, shader, compiler); + // if (variable.Variable.Type is not PointerType) + // throw new InvalidOperationException("can only assign to pointer type"); + // if (variable.Value!.Type is PointerType p) + // { + // var sourceLoad = context.Bound++; + // var underlyingType = context.GetOrRegister(p.BaseType); + // builder.Buffer.InsertOpLoad(builder.Position++, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.None); + // source = new(sourceLoad, underlyingType); + // } + + // var instruction = builder.Buffer.InsertOpStore(builder.Position++, target.Id, source.Id, null); + // } +#warning replace + throw new NotImplementedException(); } public override string ToString() { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 64121f0a28..6267679a28 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -12,107 +12,113 @@ public partial class SpirvBuilder public SpirvValue BinaryOperation(SpirvContext context, int resultType, in SpirvValue left, Operator op, in SpirvValue right, string? name = null) { - var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch - { - (Operator.Plus, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpIAdd(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Plus, ScalarType l, ScalarType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFAdd(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Minus, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpISub(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Minus, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFSub(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Mul, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpIMul(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Mul, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpFMul(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) - => Buffer.InsertOpUDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpSDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() - => Buffer.InsertOpFDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() - => Buffer.InsertOpUMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertOpSMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsNumber() - => Buffer.InsertOpFMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.RightShift, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.LeftShift, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.AND, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseAnd(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.OR, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseOr(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.XOR, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertOpBitwiseXor(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertOpLogicalAnd(Position++, context.Bound++, resultType, left.Id, right.Id), - - (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertOpLogicalOr(Position++, context.Bound++, resultType, left.Id, right.Id), - - _ => throw new NotImplementedException() - }; - if (instruction.ResultId is int resultId) - { - if (name is not null) - context.AddName(instruction, name); - return new(instruction, name); - } - else throw new NotImplementedException("Instruction should have result id"); + // var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch + // { + // (Operator.Plus, SymbolType l, SymbolType r) + // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpIAdd(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Plus, ScalarType l, ScalarType r) + // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpFAdd(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Minus, SymbolType l, SymbolType r) + // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpISub(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Minus, SymbolType l, SymbolType r) + // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpFSub(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Mul, SymbolType l, SymbolType r) + // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpIMul(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Mul, SymbolType l, SymbolType r) + // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpFMul(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Div, SymbolType l, SymbolType r) + // when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) + // => Buffer.InsertOpUDiv(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Div, SymbolType l, SymbolType r) + // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpSDiv(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Div, SymbolType l, SymbolType r) + // when l.IsFloatingVector() && r.IsFloatingVector() + // => Buffer.InsertOpFDiv(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Mod, SymbolType l, SymbolType r) + // when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() + // => Buffer.InsertOpUMod(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Mod, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) + // => Buffer.InsertOpSMod(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.Mod, SymbolType l, SymbolType r) + // when l.IsFloating() && r.IsNumber() + // => Buffer.InsertOpFMod(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.RightShift, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() + // => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.LeftShift, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() + // => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.AND, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() + // => Buffer.InsertOpBitwiseAnd(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.OR, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() + // => Buffer.InsertOpBitwiseOr(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.XOR, SymbolType l, SymbolType r) + // when l.IsInteger() && r.IsInteger() + // => Buffer.InsertOpBitwiseXor(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + // => Buffer.InsertOpLogicalAnd(Position++, context.Bound++, resultType, left.Id, right.Id), + + // (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + // => Buffer.InsertOpLogicalOr(Position++, context.Bound++, resultType, left.Id, right.Id), + + // _ => throw new NotImplementedException() + // }; + // if (instruction.ResultId is int resultId) + // { + // if (name is not null) + // context.AddName(instruction, name); + // return new(instruction, name); + // } + // else throw new NotImplementedException("Instruction should have result id"); +#warning replace + throw new NotImplementedException(); } public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - Span paramsIds = stackalloc IdRef[parameters.Length]; - var tmp = 0; - foreach (var p in parameters) - paramsIds[tmp++] = p.Id; - return CallFunction(context, name, paramsIds); + // Span paramsIds = stackalloc IdRef[parameters.Length]; + // var tmp = 0; + // foreach (var p in parameters) + // paramsIds[tmp++] = p.Id; + // return CallFunction(context, name, paramsIds); + #warning replace + throw new NotImplementedException(); } public SpirvValue CallFunction(SpirvContext context, string name, Span parameters) { - var func = FindFunction(context, name); + // var func = FindFunction(context, name); - var fcall = Buffer.InsertOpFunctionCall(Position++, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); - return new(fcall, func.Name); + // var fcall = Buffer.InsertOpFunctionCall(Position++, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); + // return new(fcall, func.Name); + #warning replace + throw new NotImplementedException(); } private static SpirvFunction FindFunction(SpirvContext context, string name) @@ -124,8 +130,11 @@ private static SpirvFunction FindFunction(SpirvContext context, string name) public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { - var instruction = Buffer.InsertOpCompositeConstruct(Position++, context.Bound++, context.GetOrRegister(literal.Type), values); - return new(instruction); + // var instruction = Buffer.InsertOpCompositeConstruct(Position++, context.Bound++, context.GetOrRegister(literal.Type), values); + // return new(instruction); + + #warning replace + throw new NotImplementedException(); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index d058d245e7..2a7ae65c6a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -8,25 +8,29 @@ public partial class SpirvBuilder { public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { - var i = Buffer.InsertOpLabel(Position++, context.Bound++); - Buffer.InsertOpUnreachable(Position); - var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); - return result; + // var i = Buffer.InsertOpLabel(Position++, context.Bound++); + // Buffer.InsertOpUnreachable(Position); + // var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); + // return result; + #warning replace + throw new NotImplementedException(); } public void Return(in SpirvValue? value = null) { - _ = value switch - { - SpirvValue v => Buffer.InsertOpReturnValue(Position++, v.Id).WordCount, - _ => Buffer.InsertOpReturn(Position++).WordCount - }; - CleanBlock(); + // _ = value switch + // { + // SpirvValue v => Buffer.InsertOpReturnValue(Position++, v.Id).WordCount, + // _ => Buffer.InsertOpReturn(Position++).WordCount + // }; + // CleanBlock(); + #warning replace + throw new NotImplementedException(); } public void CleanBlock() { - if (Buffer.Instructions[Position].OpCode == Op.OpUnreachable) + if (Buffer.Instructions[Position].OpCode == Specification.Op.OpUnreachable) { Buffer.Instructions.RemoveAt(Position); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index c070fc2a00..b41770a24d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -9,40 +9,48 @@ public partial class SpirvBuilder { public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.None) { - foreach(var t in ftype.ParameterTypes) - context.GetOrRegister(t); - var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); - Position = Buffer.Instructions.Count; - context.AddName(func, name); - var result = new SpirvFunction(func.ResultId!.Value, name, ftype); - CurrentFunction = result; - context.Module.Functions.Add(name, result); - return result; + // foreach(var t in ftype.ParameterTypes) + // context.GetOrRegister(t); + // var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); + // Position = Buffer.Instructions.Count; + // context.AddName(func, name); + // var result = new SpirvFunction(func.ResultId!.Value, name, ftype); + // CurrentFunction = result; + // context.Module.Functions.Add(name, result); + // return result; + #warning replace + throw new NotImplementedException(); } public void EndFunction(SpirvContext context) { - Buffer.InsertOpFunctionEnd(Position++); + // Buffer.InsertOpFunctionEnd(Position++); + #warning replace + throw new NotImplementedException(); } public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) { - var p = Buffer.InsertOpFunctionParameter(Position++, context.Bound++, context.GetOrRegister(type)); - context.AddName(p, name); - CurrentFunction!.Value.Parameters.Add(name, new(p, name)); - return new(p, name); + // var p = Buffer.InsertOpFunctionParameter(Position++, context.Bound++, context.GetOrRegister(type)); + // context.AddName(p, name); + // CurrentFunction!.Value.Parameters.Add(name, new(p, name)); + // return new(p, name); + #warning replace + throw new NotImplementedException(); } public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.None) { - var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(type.ReturnType), mask, context.GetOrRegister(type)); - context.AddName(func, name); - context.SetEntryPoint(execModel, func, name, variables); - var result = new SpirvFunction(func.ResultId!.Value, name, type); - if(!variables.IsEmpty) - foreach(var p in variables) - context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); - CurrentFunction = result; - return result; + // var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(type.ReturnType), mask, context.GetOrRegister(type)); + // context.AddName(func, name); + // context.SetEntryPoint(execModel, func, name, variables); + // var result = new SpirvFunction(func.ResultId!.Value, name, type); + // if(!variables.IsEmpty) + // foreach(var p in variables) + // context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); + // CurrentFunction = result; + // return result; + #warning replace + throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 077d358128..8594b255c8 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -31,36 +31,43 @@ public void PutShaderName(string name) { if (Name is null) { - Name = name; - Buffer.InsertOpSDSLShader(0, name); +#warning replace + // Name = name; + // Buffer.InsertOpSDSLShader(0, name); } else throw new NotImplementedException(); } public void AddName(IdRef target, string name) - => Buffer.AddOpName(target, name.Replace('.', '_')); +#warning replace + => throw new NotImplementedException(); + // => Buffer.AddOpName(target, name.Replace('.', '_')); public void AddMemberName(IdRef target, int accessor, string name) - => Buffer.AddOpMemberName(target, accessor, name); +#warning replace + => throw new NotImplementedException(); + // => Buffer.AddOpMemberName(target, accessor, name); public IdRef AddConstant(TScalar value) where TScalar : INumber { - return value switch - { - byte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v), - sbyte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v), - ushort v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v), - short v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v), - uint v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v), - int v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v), - ulong v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v), - long v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v), - Half v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v), - float v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v), - double v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v), - _ => throw new NotImplementedException() - }; + // return value switch + // { + // byte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v), + // sbyte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v), + // ushort v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v), + // short v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v), + // uint v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v), + // int v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v), + // ulong v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v), + // long v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v), + // Half v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v), + // float v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v), + // double v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v), + // _ => throw new NotImplementedException() + // }; +#warning replace + throw new NotImplementedException(); } public void AddGlobalVariable(Symbol variable) @@ -105,11 +112,13 @@ public void AddGlobalVariable(Symbol variable) public void SetEntryPoint(ExecutionModel model, IdRef function, string name, ReadOnlySpan variables) { - Span pvariables = stackalloc IdRef[variables.Length]; - int pos = 0; - foreach (var v in variables) - pvariables[pos++] = Variables[v.Id.Name].Id; - Buffer.AddOpEntryPoint(model, function, name, pvariables); + // Span pvariables = stackalloc IdRef[variables.Length]; + // int pos = 0; + // foreach (var v in variables) + // pvariables[pos++] = Variables[v.Id.Name].Id; + // Buffer.AddOpEntryPoint(model, function, name, pvariables); +#warning replace + throw new NotImplementedException(); } public IdRef GetOrRegister(SymbolType? type) @@ -120,144 +129,156 @@ public IdRef GetOrRegister(SymbolType? type) return res; else { - var instruction = type switch - { - ScalarType s => - s.TypeName switch - { - "void" => Buffer.AddOpTypeVoid(Bound++), - "bool" => Buffer.AddOpTypeBool(Bound++), - "sbyte" => Buffer.AddOpTypeInt(Bound++, 8, 1), - "byte" => Buffer.AddOpTypeInt(Bound++, 8, 0), - "ushort" => Buffer.AddOpTypeInt(Bound++, 16, 1), - "short" => Buffer.AddOpTypeInt(Bound++, 16, 0), - "int" => Buffer.AddOpTypeInt(Bound++, 32, 1), - "uint" => Buffer.AddOpTypeInt(Bound++, 32, 0), - "long" => Buffer.AddOpTypeInt(Bound++, 64, 1), - "ulong" => Buffer.AddOpTypeInt(Bound++, 64, 0), - "half" => Buffer.AddOpTypeFloat(Bound++, 16, null), - "float" => Buffer.AddOpTypeFloat(Bound++, 32, null), - "double" => Buffer.AddOpTypeFloat(Bound++, 64, null), - _ => throw new NotImplementedException($"Can't add type {type}") + // var instruction = type switch + // { + // ScalarType s => + // s.TypeName switch + // { + // "void" => Buffer.AddOpTypeVoid(Bound++), + // "bool" => Buffer.AddOpTypeBool(Bound++), + // "sbyte" => Buffer.AddOpTypeInt(Bound++, 8, 1), + // "byte" => Buffer.AddOpTypeInt(Bound++, 8, 0), + // "ushort" => Buffer.AddOpTypeInt(Bound++, 16, 1), + // "short" => Buffer.AddOpTypeInt(Bound++, 16, 0), + // "int" => Buffer.AddOpTypeInt(Bound++, 32, 1), + // "uint" => Buffer.AddOpTypeInt(Bound++, 32, 0), + // "long" => Buffer.AddOpTypeInt(Bound++, 64, 1), + // "ulong" => Buffer.AddOpTypeInt(Bound++, 64, 0), + // "half" => Buffer.AddOpTypeFloat(Bound++, 16, null), + // "float" => Buffer.AddOpTypeFloat(Bound++, 32, null), + // "double" => Buffer.AddOpTypeFloat(Bound++, 64, null), + // _ => throw new NotImplementedException($"Can't add type {type}") - }, - VectorType v => Buffer.AddOpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size), - MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), - ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), - StructType st => RegisterStructuredType(st.ToId(), st), - ConstantBufferSymbol cb => RegisterCBuffer(cb), - FunctionType f => RegisterFunctionType(f), - PointerType p => RegisterPointerType(p), - // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), - // StructSymbol st => RegisterStruct(st), - _ => throw new NotImplementedException($"Can't add type {type}") - }; - Types[type] = instruction; - ReverseTypes[instruction] = type; - return instruction; + // }, + // VectorType v => Buffer.AddOpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size), + // MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), + // ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), + // StructType st => RegisterStructuredType(st.ToId(), st), + // ConstantBufferSymbol cb => RegisterCBuffer(cb), + // FunctionType f => RegisterFunctionType(f), + // PointerType p => RegisterPointerType(p), + // // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), + // // StructSymbol st => RegisterStruct(st), + // _ => throw new NotImplementedException($"Can't add type {type}") + // }; + // Types[type] = instruction; + // ReverseTypes[instruction] = type; + // return instruction; +#warning replace + throw new NotImplementedException(); } } private IdRef RegisterCBuffer(ConstantBufferSymbol cb) { - var result = RegisterStructuredType($"type.{cb.ToId()}", cb); + // var result = RegisterStructuredType($"type.{cb.ToId()}", cb); - Buffer.AddOpDecorate(result, Decoration.Block); - for (var index = 0; index < cb.Members.Count; index++) - { - var member = cb.Members[index]; - if (index > 0) - throw new NotImplementedException("Offset"); - Buffer.AddOpMemberDecorate(result, index, Decoration.Offset, 0); - } + // Buffer.AddOpDecorate(result, Decoration.Block); + // for (var index = 0; index < cb.Members.Count; index++) + // { + // var member = cb.Members[index]; + // if (index > 0) + // throw new NotImplementedException("Offset"); + // Buffer.AddOpMemberDecorate(result, index, Decoration.Offset, 0); + // } - return result; + // return result; + #warning replace + throw new NotImplementedException(); } IdRef RegisterStructuredType(string name, StructuredType structSymbol) { - Span types = stackalloc IdRef[structSymbol.Members.Count]; - for (var index = 0; index < structSymbol.Members.Count; index++) - types[index] = GetOrRegister(structSymbol.Members[index].Type); + // Span types = stackalloc IdRef[structSymbol.Members.Count]; + // for (var index = 0; index < structSymbol.Members.Count; index++) + // types[index] = GetOrRegister(structSymbol.Members[index].Type); - var result = Buffer.AddOpTypeStruct(Bound++, types); - AddName(result, name); - for (var index = 0; index < structSymbol.Members.Count; index++) - AddMemberName(result, index, structSymbol.Members[index].Name); + // var result = Buffer.AddOpTypeStruct(Bound++, types); + // AddName(result, name); + // for (var index = 0; index < structSymbol.Members.Count; index++) + // AddMemberName(result, index, structSymbol.Members[index].Name); - return result; + // return result; +#warning replace + throw new NotImplementedException(); } IdRef RegisterFunctionType(FunctionType functionType) { - Span types = stackalloc IdRef[functionType.ParameterTypes.Count]; - int tmp = 0; - foreach (var f in functionType.ParameterTypes) - types[tmp] = GetOrRegister(f); - var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); + // Span types = stackalloc IdRef[functionType.ParameterTypes.Count]; + // int tmp = 0; + // foreach (var f in functionType.ParameterTypes) + // types[tmp] = GetOrRegister(f); + // var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); // disabled for now: currently it generates name with {}, not working with most SPIRV tools - AddName(result, functionType.ToId()); - return result; + // AddName(result, functionType.ToId()); + // return result; + #warning replace + throw new NotImplementedException(); } IdRef RegisterPointerType(PointerType pointerType) { - var baseType = GetOrRegister(pointerType.BaseType); - var result = Buffer.AddOpTypePointer(Bound++, pointerType.StorageClass, baseType); - AddName(result, pointerType.ToId()); - return result; + // var baseType = GetOrRegister(pointerType.BaseType); + // var result = Buffer.AddOpTypePointer(Bound++, pointerType.StorageClass, baseType); + // AddName(result, pointerType.ToId()); + // return result; +#warning replace + throw new NotImplementedException(); } public SpirvValue CreateConstant(Literal literal) { - object literalValue = literal switch - { - BoolLiteral lit => lit.Value, - IntegerLiteral lit => lit.Suffix.Size switch - { - > 32 => lit.LongValue, - _ => lit.IntValue, - }, - FloatLiteral lit => lit.Suffix.Size switch - { - > 32 => lit.DoubleValue, - _ => (float)lit.DoubleValue, - }, - }; + // object literalValue = literal switch + // { + // BoolLiteral lit => lit.Value, + // IntegerLiteral lit => lit.Suffix.Size switch + // { + // > 32 => lit.LongValue, + // _ => lit.IntValue, + // }, + // FloatLiteral lit => lit.Suffix.Size switch + // { + // > 32 => lit.DoubleValue, + // _ => (float)lit.DoubleValue, + // }, + // }; - if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) - return result; + // if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) + // return result; - var instruction = literal switch - { - BoolLiteral lit => lit.Value switch - { - true => Buffer.AddOpConstantTrue(Bound++, GetOrRegister(lit.Type)), - false => Buffer.AddOpConstantFalse(Bound++, GetOrRegister(lit.Type)) - }, - IntegerLiteral lit => lit.Suffix.Size switch - { - > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.LongValue), - _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue), - }, - FloatLiteral lit => lit.Suffix.Size switch - { - > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue), - _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue), - }, - _ => throw new NotImplementedException() - }; + // var instruction = literal switch + // { + // BoolLiteral lit => lit.Value switch + // { + // true => Buffer.AddOpConstantTrue(Bound++, GetOrRegister(lit.Type)), + // false => Buffer.AddOpConstantFalse(Bound++, GetOrRegister(lit.Type)) + // }, + // IntegerLiteral lit => lit.Suffix.Size switch + // { + // > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.LongValue), + // _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue), + // }, + // FloatLiteral lit => lit.Suffix.Size switch + // { + // > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue), + // _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue), + // }, + // _ => throw new NotImplementedException() + // }; - result = new(instruction); - LiteralConstants.Add((literal.Type, literalValue), result); - AddName(result.Id, literal switch - { - BoolLiteral lit => $"{lit.Type}_{lit.Value}", - IntegerLiteral lit => $"{lit.Type}_{lit.Value}", - FloatLiteral lit => $"{lit.Type}_{lit.Value}", - }); - return result; + // result = new(instruction); + // LiteralConstants.Add((literal.Type, literalValue), result); + // AddName(result.Id, literal switch + // { + // BoolLiteral lit => $"{lit.Type}_{lit.Value}", + // IntegerLiteral lit => $"{lit.Type}_{lit.Value}", + // FloatLiteral lit => $"{lit.Type}_{lit.Value}", + // }); + // return result; +#warning replace + throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 13e1deacf2..d52ae6f346 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -117,82 +117,83 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) { - ProcessMethod(buffer, entryPointId, streams); - - var stage = executionModel switch - { - Specification.ExecutionModel.Fragment => "PS", - Specification.ExecutionModel.Vertex => "VS", - }; - List<(StreamInfo Info, int Id)> inputStreams = []; - List<(StreamInfo Info, int Id)> outputStreams = []; - foreach (var stream in streams) - { - // Only direct access to global variables (not temporary variables created within function) - if (!stream.Value.IsDirect) - continue; - - if (stream.Value.Stream.Input) - { - var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Input, context.Types[stream.Value.Stream.Type]); - var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Input, null); - context.AddName(variable, $"in_{stream.Value.Stream.Name}"); - - if (stream.Value.Stream.Semantic != null) - context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); - - inputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); - } - - if (stream.Value.Stream.Output) - { - var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Output, context.Types[stream.Value.Stream.Type]); - var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Output, null); - context.AddName(variable, $"out_{stream.Value.Stream.Name}"); - - if (stream.Value.Stream.Semantic != null) - context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); - - outputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); - } - } - - var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); - - // Add new entry point wrapper - var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, voidTypeId, []); - var newEntryPointFunction = buffer.AddOpFunction(context.Bound++, voidTypeId, Specification.FunctionControlMask.None, newEntryPointFunctionType); - buffer.AddOpLabel(context.Bound++); - context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); - - { - // Copy read variables from streams - foreach (var stream in inputStreams) - { - var baseType = ((PointerType)stream.Info.Type).BaseType; - var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Id, null); - buffer.AddOpStore(stream.Info.Id, loadedValue.ResultId!.Value, null); - } - - buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); - - foreach (var stream in outputStreams) - { - var baseType = ((PointerType)stream.Info.Type).BaseType; - var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null); - buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); - } - - buffer.AddOpReturn(); - buffer.AddOpFunctionEnd(); - - Span pvariables = stackalloc IdRef[inputStreams.Count + outputStreams.Count]; - for (int i = 0; i < inputStreams.Count; i++) - pvariables[i] = inputStreams[i].Id; - for (int i = 0; i < outputStreams.Count; i++) - pvariables[inputStreams.Count + i] = outputStreams[i].Id; - context.Buffer.AddOpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", pvariables); - } + #warning replace + // ProcessMethod(buffer, entryPointId, streams); + + // var stage = executionModel switch + // { + // Specification.ExecutionModel.Fragment => "PS", + // Specification.ExecutionModel.Vertex => "VS", + // }; + // List<(StreamInfo Info, int Id)> inputStreams = []; + // List<(StreamInfo Info, int Id)> outputStreams = []; + // foreach (var stream in streams) + // { + // // Only direct access to global variables (not temporary variables created within function) + // if (!stream.Value.IsDirect) + // continue; + + // if (stream.Value.Stream.Input) + // { + // var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Input, context.Types[stream.Value.Stream.Type]); + // var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Input, null); + // context.AddName(variable, $"in_{stream.Value.Stream.Name}"); + + // if (stream.Value.Stream.Semantic != null) + // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); + + // inputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); + // } + + // if (stream.Value.Stream.Output) + // { + // var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Output, context.Types[stream.Value.Stream.Type]); + // var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Output, null); + // context.AddName(variable, $"out_{stream.Value.Stream.Name}"); + + // if (stream.Value.Stream.Semantic != null) + // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); + + // outputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); + // } + // } + + // var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); + + // // Add new entry point wrapper + // var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, voidTypeId, []); + // var newEntryPointFunction = buffer.AddOpFunction(context.Bound++, voidTypeId, Specification.FunctionControlMask.None, newEntryPointFunctionType); + // buffer.AddOpLabel(context.Bound++); + // context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); + + // { + // // Copy read variables from streams + // foreach (var stream in inputStreams) + // { + // var baseType = ((PointerType)stream.Info.Type).BaseType; + // var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Id, null); + // buffer.AddOpStore(stream.Info.Id, loadedValue.ResultId!.Value, null); + // } + + // buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); + + // foreach (var stream in outputStreams) + // { + // var baseType = ((PointerType)stream.Info.Type).BaseType; + // var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null); + // buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); + // } + + // buffer.AddOpReturn(); + // buffer.AddOpFunctionEnd(); + + // Span pvariables = stackalloc IdRef[inputStreams.Count + outputStreams.Count]; + // for (int i = 0; i < inputStreams.Count; i++) + // pvariables[i] = inputStreams[i].Id; + // for (int i = 0; i < outputStreams.Count; i++) + // pvariables[inputStreams.Count + i] = outputStreams[i].Id; + // context.Buffer.AddOpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", pvariables); + // } } /// diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs new file mode 100644 index 0000000000..28e8201ff5 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -0,0 +1,58 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Tools; + +public static partial class Spv +{ + struct DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) + { + static int MAX_OFFSET = 16; + SortedList nameTable = []; + NewSpirvBuffer buffer = buffer; + int idOffset; + bool useNames = useNames; + bool writeToConsole = writeToConsole; + + void ComputeIdOffset() + { + idOffset = 9; + if (!useNames) + { + var bound = buffer.Header.Bound; + idOffset = 3; + while (bound > 0) + { + bound /= 10; + idOffset += 1; + } + } + else + { + var maxName = 0; + foreach (var i in buffer) + { + maxName = i.Op switch + { + Op.OpName => maxName > ((OpName)i).Name.Length ? maxName : ((OpName)i).Name.Length, + Op.OpMemberName => maxName > ((OpMemberName)i).Name.Length ? maxName : ((OpMemberName)i).Name.Length, + _ => maxName + }; + } + idOffset += maxName; + } + idOffset = Math.Min(idOffset, MAX_OFFSET); + } + } + + + public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) + { + // this.buffer = buffer; + // ComputeIdOffset(); + // Assembly code generation logic goes here + var data = new DisData(buffer, useNames, writeToConsole); + return ""; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs index 9140146252..6d0e9f20df 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs @@ -83,15 +83,15 @@ public readonly void AppendConst(int typeId, Span words) } public readonly void AppendLiteral(LiteralInteger v) { - writer.Append(' ').Append(v.Words, ConsoleColor.Red); + writer.Append(' ').Append(v.Data, ConsoleColor.Red); } public readonly void AppendLiteral(LiteralFloat v) { if (v.WordCount == 1) - writer.Append(' ').Append(Convert.ToSingle(v.Words & 0xFFFF), ConsoleColor.Red); + writer.Append(' ').Append(Convert.ToSingle(v.Data.Span[0] & 0xFFFF), ConsoleColor.Red); else if (v.WordCount == 2) - writer.Append(' ').Append(Convert.ToDouble(v.Words), ConsoleColor.Red); + writer.Append(' ').Append(Convert.ToDouble(v.Data), ConsoleColor.Red); } public readonly void AppendLiteral(LiteralString v, bool quoted = false) { diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 2cdce5bbd3..12e58adbc8 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -9,6 +9,7 @@ net9.0 enable enable + preview From aac4610c41721216da16052e55c2d8036756b2f9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 8 Sep 2025 17:22:19 +0200 Subject: [PATCH 0441/1182] changes in generator to avoid memory leaks --- .../Parsing/SpirvHeader.cs | 10 +- src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 86 +++-- .../SPVGenerator.Instructions.cs | 30 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 294 ++++++++++++++++-- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 2 +- 5 files changed, 354 insertions(+), 68 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index ced050a6cb..93ab6d361b 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -43,7 +43,7 @@ public readonly struct SpirvHeader { public uint MagicNumber { get; init; } public SpirvVersion VersionNumber { get; init; } - public int GeneratorMagicNumber { get; init; } + public int Generator { get; init; } public int Bound { get; init; } public int Schema { get; init; } @@ -53,7 +53,7 @@ public SpirvHeader(string version, int generator, int bound, int schema = 0) { MagicNumber = Specification.MagicNumber; VersionNumber = version; - GeneratorMagicNumber = generator; + Generator = generator; Bound = bound; Schema = schema; } @@ -61,7 +61,7 @@ public SpirvHeader(SpirvVersion version, int generator, int bound, int schema = { MagicNumber = Specification.MagicNumber; VersionNumber = version; - GeneratorMagicNumber = generator; + Generator = generator; Bound = bound; Schema = schema; } @@ -70,7 +70,7 @@ public void WriteTo(Span words) { words[0] = unchecked((int)MagicNumber); words[1] = VersionNumber.Version; - words[2] = GeneratorMagicNumber; + words[2] = Generator; words[3] = Bound; words[4] = Schema; } @@ -81,7 +81,7 @@ public static SpirvHeader Read(Span words) { MagicNumber = (uint)words[0], VersionNumber = words[1], - GeneratorMagicNumber = words[2], + Generator = words[2], Bound = words[3], Schema = words[4] }; diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index 5b0bf8259b..5d509b5450 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -36,9 +36,43 @@ public void ReplaceIdResult(int replacement) if (Kind == OperandKind.IdResult && replacement > 0) Words[0] = replacement; } - public T ToEnum() where T : Enum + public readonly T ToEnum() where T : Enum + => Unsafe.As(ref Words[0]); + + internal readonly T ToLiteral() + { + using var lit = new LiteralValue(Words); + return lit.Value; + } + internal readonly LiteralArray ToLiteralArray() + => LiteralArray.From(Words); + + public readonly bool TryToLiteral(out LiteralValue literal) + { + literal = default; + (bool r, literal) = (literal, Kind) switch + { + (LiteralValue<(int, int)>, OperandKind kind) when kind.ToString().StartsWith("Pair") => (true, LiteralValue.From(Words)), + (LiteralValue, OperandKind kind) when kind.ToString().StartsWith("Id") => (true, LiteralValue.From(Words)), + (LiteralValue, OperandKind.LiteralInteger or OperandKind.LiteralExtInstInteger or OperandKind.LiteralSpecConstantOpInteger) + => (true, LiteralValue.From(Words)), + (LiteralValue or LiteralValue or LiteralValue, OperandKind.LiteralFloat) => (true, LiteralValue.From(Words)), + (LiteralValue, OperandKind.LiteralString) => (true, LiteralValue.From(Words)), + _ => (false, default) + }; + return true; + } + public readonly bool TryToArray(out LiteralArray literal) { - return Unsafe.As(ref Words[0]); + literal = default; + (bool r, literal) = (literal, Kind) switch + { + (LiteralArray<(int, int)>, OperandKind kind) when kind.ToString().StartsWith("Pair") => (true, LiteralArray.From(Words)), + (LiteralArray, OperandKind.IdRef or OperandKind.LiteralInteger) + => (true, LiteralArray.From(Words)), + _ => (false, default) // No other types supported yet + }; + return r; } public readonly T To() @@ -142,30 +176,30 @@ public override string ToString() OperandKind.IdRef => $"%{Words[0] + Offset}", OperandKind.IdResultType => $"%{Words[0] + Offset}", OperandKind.PairLiteralIntegerIdRef => $"{Words[0]} %{Words[0] + Offset}", - OperandKind.MemoryAccess => $"{ToEnum()}", - OperandKind.MemoryModel => $"{ToEnum()}", - OperandKind.MemorySemantics => $"{ToEnum()}", - OperandKind.AccessQualifier => $"{ToEnum()}", - OperandKind.AddressingModel => $"{ToEnum()}", - OperandKind.BuiltIn => $"{ToEnum()}", - OperandKind.Capability => $"{ToEnum()}", - OperandKind.Decoration => $"{ToEnum()}", - OperandKind.Dim => $"{ToEnum()}", - OperandKind.ExecutionMode => $"{ToEnum()}", - OperandKind.ExecutionModel => $"{ToEnum()}", - OperandKind.FPFastMathMode => $"{ToEnum()}", - OperandKind.FPRoundingMode => $"{ToEnum()}", - OperandKind.FragmentShadingRate => $"{ToEnum()}", - OperandKind.FunctionControl => $"{ToEnum()}", - OperandKind.FunctionParameterAttribute => $"{ToEnum()}", - OperandKind.GroupOperation => $"{ToEnum()}", - OperandKind.ImageChannelDataType => $"{ToEnum()}", - OperandKind.ImageChannelOrder => $"{ToEnum()}", - OperandKind.ImageFormat => $"{ToEnum()}", - OperandKind.ImageOperands => $"{ToEnum()}", - OperandKind.KernelEnqueueFlags => $"{ToEnum()}", - OperandKind.KernelProfilingInfo => $"{ToEnum()}", - OperandKind.LinkageType => $"{ToEnum()}", + OperandKind.MemoryAccess => $"{ToEnum()}", + OperandKind.MemoryModel => $"{ToEnum()}", + OperandKind.MemorySemantics => $"{ToEnum()}", + OperandKind.AccessQualifier => $"{ToEnum()}", + OperandKind.AddressingModel => $"{ToEnum()}", + OperandKind.BuiltIn => $"{ToEnum()}", + OperandKind.Capability => $"{ToEnum()}", + OperandKind.Decoration => $"{ToEnum()}", + OperandKind.Dim => $"{ToEnum()}", + OperandKind.ExecutionMode => $"{ToEnum()}", + OperandKind.ExecutionModel => $"{ToEnum()}", + OperandKind.FPFastMathMode => $"{ToEnum()}", + OperandKind.FPRoundingMode => $"{ToEnum()}", + OperandKind.FragmentShadingRate => $"{ToEnum()}", + OperandKind.FunctionControl => $"{ToEnum()}", + OperandKind.FunctionParameterAttribute => $"{ToEnum()}", + OperandKind.GroupOperation => $"{ToEnum()}", + OperandKind.ImageChannelDataType => $"{ToEnum()}", + OperandKind.ImageChannelOrder => $"{ToEnum()}", + OperandKind.ImageFormat => $"{ToEnum()}", + OperandKind.ImageOperands => $"{ToEnum()}", + OperandKind.KernelEnqueueFlags => $"{ToEnum()}", + OperandKind.KernelProfilingInfo => $"{ToEnum()}", + OperandKind.LinkageType => $"{ToEnum()}", OperandKind.None => "", _ => Words[0].ToString() }; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 1fda32c571..d86fea28e5 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -179,10 +179,10 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst // Body 2 body2.AppendLine($"if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); @@ -262,9 +262,9 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i if (instruction.Operands?.AsList() is List operands) { - operands.Add(new(){Name = "additional1", Kind = "LiteralInteger", Quantifier = "?"}); - operands.Add(new(){Name = "additional2", Kind = "LiteralInteger", Quantifier = "?"}); - operands.Add(new(){Name = "additionalString", Kind = "LiteralString", Quantifier = "?"}); + operands.Add(new() { Name = "additional1", Kind = "LiteralInteger", Quantifier = "?" }); + operands.Add(new() { Name = "additional2", Kind = "LiteralInteger", Quantifier = "?" }); + operands.Add(new() { Name = "additionalString", Kind = "LiteralString", Quantifier = "?" }); body2.AppendLine("foreach (var o in index.Buffer[index.Index])") .AppendLine("{"); @@ -296,10 +296,10 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i // Body 2 body2.AppendLine($"if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.To>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); @@ -414,11 +414,11 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, body2.AppendLine($"if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) { - body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + body2.AppendLine($"{fieldName} = o.To{typename}();"); } else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.To>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); @@ -511,7 +511,7 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i // Body 1 - + foreach (var operand in operands) { @@ -519,18 +519,20 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i if (typename.StartsWith("LiteralArray")) body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); - else if(typename.StartsWith("LiteralValue")) + else if (typename.StartsWith("LiteralValue")) body1.Append($"public T {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); else body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); // Body 2 body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray") || typename.StartsWith("LiteralValue")) - body2.AppendLine($"{fieldName} = o.To<{typename}>();"); + if (typename.StartsWith("LiteralArray")) + body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.To>();"); + else if (typename.StartsWith("LiteralValue")) + body2.AppendLine($"{fieldName} = o.ToLiteral();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 28e8201ff5..d448f71c45 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -1,3 +1,9 @@ +using System.Numerics; +using System.Text; +using System.Text.Json; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; @@ -6,32 +12,275 @@ namespace Stride.Shaders.Spirv.Tools; public static partial class Spv { - struct DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) + public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) + { + // this.buffer = buffer; + // ComputeIdOffset(); + // Assembly code generation logic goes here + var writer = new DisWriter(buffer, useNames, writeToConsole); + writer.Disassemble(); + foreach (var instruction in data) + { + // Disassemble each instruction + } + return ""; + } + + + + struct DisWriter(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) + { + DisData data = new(buffer, useNames, writeToConsole); + readonly StringBuilder builder = new(); + + DisWriter AppendLine(string text, ConsoleColor? color = null) + { + if (color is not null) + { + var previousColor = Console.ForegroundColor; + Console.ForegroundColor = color.Value; + Console.WriteLine(text); + Console.ForegroundColor = previousColor; + } + else + Console.WriteLine(text); + builder.AppendLine(text); + return this; + } + DisWriter Append(T text, ConsoleColor? color = null) + { + if (color is not null) + { + var previousColor = Console.ForegroundColor; + Console.ForegroundColor = color.Value; + Console.Write(text); + Console.ForegroundColor = previousColor; + } + else + Console.Write(text); + builder.Append(text); + return this; + } + DisWriter AppendRepeatChar(char c, int count) + { + if (data.WriteToConsole) + while (count-- > 0) + Console.Write(c); + builder.Append(c, count); + return this; + } + DisWriter AppendLiteralNumber(T value) + where T : struct, INumber + { + Append(value, ConsoleColor.Red).Append(' '); + return this; + } + + DisWriter AppendLiteralNumber(LiteralValue value, bool dispose = true) + where T : struct, INumber + { + Append(value.Value, ConsoleColor.Red).Append(' '); + if (dispose) + value.Dispose(); + return this; + } + + DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) + { + Append('"', ConsoleColor.Green).Append(value.Value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); + if (dispose) + value.Dispose(); + return this; + } + DisWriter AppendLiteralString(string value) + { + Append('"', ConsoleColor.Green).Append(value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); + return this; + } + + DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = true) + where T : struct, INumber + { + T tmp = default; + var size = tmp switch + { + byte or sbyte or short or ushort or int or uint or float => 1, + long or ulong or double => 2, + _ => throw new NotImplementedException("Cannot create LiteralValue from the provided words") + }; + for(int i = 0; i < value.WordCount; i += size) + { + if (size == 1) + { + using var lit = LiteralValue.From([value.Words[i]]); + Append(lit.Value, ConsoleColor.Red); + } + else + { + using var v = LiteralValue.From([(value.Words[i] << 32 | value.Words[i + 1])]); + Append(v.Value, ConsoleColor.Red); + } + } + if (dispose) + value.Dispose(); + return this; + } + DisWriter AppendResultId(int? id = null) + { + if (id is int i) + { + if (data.UseNames && data.NameTable.TryGetValue(i, out var name)) + { + AppendRepeatChar(' ', data.IdOffset - name.Length - 1); + Append('%', ConsoleColor.Cyan); + Append(name, ConsoleColor.Cyan); + } + else + { + var size = 0; + var tmp = i; + do + { + size += 1; + tmp /= 10; + } while (tmp > 0); + AppendRepeatChar(' ', data.IdOffset - size - 1 - 3); + Append($"%{i}", ConsoleColor.Cyan); + } + Append(" = "); + } + else + AppendRepeatChar(' ', data.IdOffset - 1); + return this; + + } + + public void Disassemble() + { + DisHeader(); + foreach (var instruction in data) + { + DisInstruction(instruction, this); + } + } + + public void DisHeader() + { + var header = data.Buffer.Header; + AppendLine($"; SPIR-V"); + AppendLine($"; Version: {header.Version}"); + AppendLine($"; Generator: {header.Generator}"); + AppendLine($"; Bound: {header.Bound}"); + AppendLine($"; Schema: {header.Schema}"); + AppendLine(""); + } + + public void DisInstruction(in OpDataIndex instruction, in DisWriter writer) + { + if (instruction.Op == Op.OpName) + { + var nameInst = (OpName)instruction; + data.NameTable[nameInst.Target] = nameInst.Name; + AppendResultId(); + Append("OpName ").AppendLiteralNumber(nameInst.Target).AppendLiteralString(nameInst.Name); + } + else if (instruction.Op == Op.OpMemberName) + { + var memberInst = (OpMemberName)instruction; + data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; + AppendResultId(); + Append("OpMemberName ").AppendLiteralNumber(memberInst.Type).AppendLiteralNumber(memberInst.Member).AppendLiteralString(memberInst.Name); + } + else + { + ref var data = ref instruction.Data; + var info = InstructionInfo.GetInfo(data); + if (info.GetResultIndex(out int resultIndex)) + AppendResultId(data.Memory.Span[resultIndex]); + else + AppendResultId(); + Append(instruction.Op.ToString()).Append(' '); + JsonElement e; + e.TryGetProperty() + foreach (var operand in data) + { + _ = operand.Kind switch + { + OperandKind.LiteralString => AppendLiteralString(operand.To>().Value), + _ => this + }; + } + } + } + + public override string ToString() => builder.ToString(); + } + + + struct MemberIndex : IEquatable, IDisposable + { + public int Ref; + public MemoryOwner Accessors; + public MemberIndex(int @ref, ReadOnlySpan accessors) + { + Ref = @ref; + if (accessors.IsEmpty) + Accessors = MemoryOwner.Empty; + else + { + Accessors = MemoryOwner.Allocate(accessors.Length); + accessors.CopyTo(Accessors.Span); + } + } + + public static implicit operator MemberIndex(int @ref) => new(@ref, []); + public static implicit operator MemberIndex(ReadOnlySpan refAndAccessors) => new(refAndAccessors[0], refAndAccessors[1..]); + + public readonly bool Equals(MemberIndex other) + => other.Ref == Ref && other.Accessors.Span.SequenceEqual(Accessors.Span); + public override readonly bool Equals(object? obj) + => obj is MemberIndex index && Equals(index); + public override int GetHashCode() + => HashCode.Combine(Ref, Accessors.Span.GetDjb2HashCode()); + public readonly void Dispose() => Accessors.Dispose(); + } + + + struct DisData : IDisposable { static int MAX_OFFSET = 16; - SortedList nameTable = []; - NewSpirvBuffer buffer = buffer; - int idOffset; - bool useNames = useNames; - bool writeToConsole = writeToConsole; + public Dictionary NameTable { get; } + public NewSpirvBuffer Buffer { get; } + public int IdOffset { get; private set; } + public bool UseNames { get; private set; } + public bool WriteToConsole { get; private set; } + + public DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) + { + Buffer = buffer; + NameTable = []; + this.UseNames = useNames; + this.WriteToConsole = writeToConsole; + ComputeIdOffset(); + } void ComputeIdOffset() { - idOffset = 9; - if (!useNames) + IdOffset = 9; + if (!UseNames) { - var bound = buffer.Header.Bound; - idOffset = 3; + var bound = Buffer.Header.Bound; + IdOffset = 3; while (bound > 0) { bound /= 10; - idOffset += 1; + IdOffset += 1; } } else { var maxName = 0; - foreach (var i in buffer) + foreach (var i in Buffer) { maxName = i.Op switch { @@ -40,19 +289,20 @@ void ComputeIdOffset() _ => maxName }; } - idOffset += maxName; + IdOffset += maxName; } - idOffset = Math.Min(idOffset, MAX_OFFSET); + IdOffset = Math.Min(IdOffset, MAX_OFFSET); + } + public readonly NewSpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); + + public readonly void Dispose() + { + foreach (var key in NameTable.Keys) + key.Dispose(); } } - public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) - { - // this.buffer = buffer; - // ComputeIdOffset(); - // Assembly code generation logic goes here - var data = new DisData(buffer, useNames, writeToConsole); - return ""; - } + + } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs index f459230393..858d192efc 100644 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs @@ -72,7 +72,7 @@ public string Disassemble(bool writeToConsole = false) writer .AppendLine("; SPIR-V") .AppendLine($"; Version: {header.Version}") - .AppendLine($"; Generator: {header.GeneratorMagicNumber}") + .AppendLine($"; Generator: {header.Generator}") .AppendLine($"; Bound: {header.Bound}") .AppendLine($"; Schema: {header.Schema}"); } From 50a076b346a807b57575b024d05d7d3bb922b87f Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 10 Sep 2025 17:30:40 +0200 Subject: [PATCH 0442/1182] Disassembler slowly getting better --- .../Examples.Spirv.cs | 127 ++--- .../Buffers/NewSpirvBuffer.cs | 4 +- .../Literals/LiteralValue.cs | 30 +- .../Parsing/IntExtensions.cs | 13 - .../Parsing/OpDataEnumerator.cs | 467 ++++++++++++------ src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 4 +- .../WordsExtensions.cs | 23 + .../SPVGenerator.Instructions.cs | 34 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 121 ++++- 9 files changed, 548 insertions(+), 275 deletions(-) delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs create mode 100644 src/Stride.Shaders.Spirv.Core/WordsExtensions.cs diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index ecc533bdb1..cd6656f617 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -67,6 +67,8 @@ public static void CreateNewShader() var buffer = new NewSpirvBuffer(); // Capabilities + var litS = new LiteralValue("main"); + buffer.Add(new OpCapability(Capability.Shader)); var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); buffer.AddRef(ref extInstImport); @@ -78,72 +80,71 @@ public static void CreateNewShader() var t_void = new OpTypeVoid(id++); buffer.AddRef(ref t_void); - buffer - .Add(new OpTypeBool(id++), out var t_bool) - .Add(new OpTypeFunction(id++, t_void, []), out var t_func) - .Add(new OpTypeFloat(id++, 32, null), out var t_float) - .Add(new OpTypeInt(id++, 32, 0), out var t_uint) - .Add(new OpTypeInt(id++, 32, 1), out var t_int) - .Add(new OpTypeFunction(id++, t_int, [t_int, t_int]), out var t_func_add) - .Add(new OpTypeVector(id++, t_float, 4), out var t_float4) - .Add(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func) - .Add(new OpConstant(id++, t_float, 5f), out var constant1) - .Add(new OpConstant(id++, t_float, 2.23f), out var constant2) - .Add(new OpConstant(id++, t_uint, 5), out var constant3) - .Add(new OpConstantComposite( + buffer.Add(new OpTypeBool(id++), out var t_bool); + buffer.Add(new OpTypeFunction(id++, t_void, []), out var t_func); + buffer.Add(new OpTypeFloat(id++, 32, null), out var t_float); + buffer.Add(new OpTypeInt(id++, 32, 0), out var t_uint); + buffer.Add(new OpTypeInt(id++, 32, 1), out var t_int); + buffer.Add(new OpTypeFunction(id++, t_int, [t_int, t_int]), out var t_func_add); + buffer.Add(new OpTypeVector(id++, t_float, 4), out var t_float4); + buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func); + buffer.Add(new OpConstant(id++, t_float, 5f), out var constant1); + buffer.Add(new OpConstant(id++, t_float, 2.23f), out var constant2); + buffer.Add(new OpConstant(id++, t_uint, 5), out var constant3); + buffer.Add(new OpConstantComposite( id++, t_float4, [constant1, constant1, constant2, constant1] - ), out var compositeType) - .Add(new OpTypeArray(id++, t_float4, constant3), out var t_array) - .Add(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct) - .Add(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2) - .Add(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2) - .Add(new OpVariable(id++, t_p_struct2, StorageClass.Uniform, null), out var v_struct2) - .Add(new OpConstant(id++, t_int, 1), out var constant4) - .Add(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint) - .Add(new OpConstant(id++, t_uint, 0), out var constant5) - .Add(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output) - .Add(new OpVariable(id++, t_p_output, StorageClass.Output, null), out var v_output) - .Add(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input) - .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input) - .Add(new OpConstant(id++, t_int, 0), out var constant6) - .Add(new OpConstant(id++, t_int, 2), out var constant7) - .Add(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif) - .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_2) - .Add(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func) - .Add(new OpConstant(id++, t_int, 4), out var constant8) - .Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_3) - .Add(new OpDecorate(t_array, Decoration.ArrayStride, 16)) - .Add(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)) - .Add(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)) - .Add(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)) - .Add(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)) - .Add(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)) - .Add(new OpDecorate(t_struct2, Decoration.Block)) - .Add(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)) - .Add(new OpDecorate(v_input_2, Decoration.NoPerspective)) - .Add(new OpName(t_p_func, "main")) - .Add(new OpName(t_struct, "S")) - .Add(new OpMemberName(t_struct, 0, "b")) - .Add(new OpMemberName(t_struct, 1, "v")) - .Add(new OpMemberName(t_struct, 2, "i")) - .Add(new OpFunction(id++, t_int, FunctionControlMask.None, t_func_add), out var add) - - - .Add(new OpFunctionParameter(id++, t_int), out var a) - .Add(new OpFunctionParameter(id++, t_int), out var b) - .Add(new OpLabel(id++), out var label) - .Add(new OpIAdd(id++, t_int, a, b), out var res) - .Add(new OpReturnValue(res)) - .Add(new OpFunctionEnd()) - .Add(new OpFunction(id++, t_void, FunctionControlMask.None, t_func), out var main) - .Add(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])) - .Add(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)) - .Add(new OpLabel(id++), out var label2) - .Add(new OpFunctionCall(id++, t_int, add, [constant7, constant7]), out var resAdd) - .Add(new OpReturn()) - .Add(new OpFunctionEnd()); + ), out var compositeType); + buffer.Add(new OpTypeArray(id++, t_float4, constant3), out var t_array); + buffer.Add(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct); + buffer.Add(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2); + buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2); + buffer.Add(new OpVariable(id++, t_p_struct2, StorageClass.Uniform, null), out var v_struct2); + buffer.Add(new OpConstant(id++, t_int, 1), out var constant4); + buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint); + buffer.Add(new OpConstant(id++, t_uint, 0), out var constant5); + buffer.Add(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output); + buffer.Add(new OpVariable(id++, t_p_output, StorageClass.Output, null), out var v_output); + buffer.Add(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input); + buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input); + buffer.Add(new OpConstant(id++, t_int, 0), out var constant6); + buffer.Add(new OpConstant(id++, t_int, 2), out var constant7); + buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif); + buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_2); + buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); + buffer.Add(new OpConstant(id++, t_int, 4), out var constant8); + buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_3); + buffer.Add(new OpDecorate(t_array, Decoration.ArrayStride, 16)); + buffer.Add(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)); + buffer.Add(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)); + buffer.Add(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)); + buffer.Add(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)); + buffer.Add(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)); + buffer.Add(new OpDecorate(t_struct2, Decoration.Block)); + buffer.Add(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)); + buffer.Add(new OpDecorate(v_input_2, Decoration.NoPerspective)); + buffer.Add(new OpName(t_p_func, "main")); + buffer.Add(new OpName(t_struct, "S")); + buffer.Add(new OpMemberName(t_struct, 0, "b")); + buffer.Add(new OpMemberName(t_struct, 1, "v")); + buffer.Add(new OpMemberName(t_struct, 2, "i")); + buffer.Add(new OpFunction(id++, t_int, FunctionControlMask.None, t_func_add), out var add); + + + buffer.Add(new OpFunctionParameter(id++, t_int), out var a); + buffer.Add(new OpFunctionParameter(id++, t_int), out var b); + buffer.Add(new OpLabel(id++), out var label); + buffer.Add(new OpIAdd(id++, t_int, a, b), out var res); + buffer.Add(new OpReturnValue(res)); + buffer.Add(new OpFunctionEnd()); + buffer.Add(new OpFunction(id++, t_void, FunctionControlMask.None, t_func), out var main); + buffer.Add(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])); + buffer.Add(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)); + buffer.Add(new OpLabel(id++), out var label2); + buffer.Add(new OpFunctionCall(id++, t_int, add, [constant7, constant7]), out var resAdd); + buffer.Add(new OpReturn()); + buffer.Add(new OpFunctionEnd());; buffer.Sort(); var span = buffer.ToBuffer(); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index e6ffaf1e27..f6e56c9aa9 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -86,9 +86,9 @@ public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) public readonly ref OpData Data => ref Buffer[Index]; } -public class NewSpirvBuffer +public class NewSpirvBuffer() { - public SpirvHeader Header { get; set; } + public SpirvHeader Header { get; set; } = new("1.4", 0, 1); List Memory { get; set; } = []; internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Memory)[index]; diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index f929a6e1b7..dd3a8d7a74 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -12,6 +12,11 @@ public struct Id(int id) public static implicit operator Id(int v) => new(v); public static implicit operator int(Id id) => id.Value; } +internal static class SPool +{ + internal static StringPool Instance { get; } = new(); + public static string GetOrAdd(ReadOnlySpan value) => Instance.GetOrAdd(value); +} public struct LiteralValue : ISpirvElement, IFromSpirv> { @@ -40,7 +45,7 @@ or LiteralValue public bool dispose; public MemoryOwner MemoryOwner { get; private set; } public readonly ReadOnlySpan Words => MemoryOwner.Span; - public T Value { get; set { field = value; UpdateMemory(); } } + public T Value { get; set { field = value; if(MemoryOwner is not null) UpdateMemory(); } } public readonly int WordCount => Words.Length; public LiteralValue(Span words, bool dispose = false) @@ -71,6 +76,27 @@ public LiteralValue(Span words, bool dispose = false) Unsafe.As(ref value) = BitConverter.Int64BitsToDouble(((long)words[0] << 32) | (uint)words[1]); else if (value is ValueTuple) Unsafe.As(ref value) = (words[0], words[1]); + else if(value is null && typeof(T) == typeof(string)) + { + Span sb = stackalloc char[words.Length * 4]; + for (int i = 0; i < words.Length; i++) + { + for (int j = 0; j < 4; j++) + { + var c = (char)((words[i] >> (8 * j)) & 0xFF); + if (c == 0) + break; + sb[i * 4 + j] = c; + } + } + Unsafe.As(ref value) = SPool.GetOrAdd(sb.Contains('\0') ? sb[0..sb.IndexOf('\0')] : sb); + } + else if (value is Enum) + Unsafe.As(ref value) = words[0]; + else if (typeof(T).Name.Contains("LiteralArray")) + throw new NotImplementedException("Use LiteralArray.From instead"); + else + throw new NotImplementedException("Cannot create LiteralValue from the provided words"); Value = value; @@ -93,7 +119,7 @@ void UpdateMemory() bool or byte or sbyte or short or ushort or Half or int or uint or float => 1, long or ulong or double or ValueTuple => 2, Enum => 1, - string s => (s.Length / 4) + (s.Length % 4 > 0 ? 1 : 0), + string s => s.GetWordCount(), null => 0, _ => throw new NotImplementedException("Can't compute literal value for type " + typeof(T)) }; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs b/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs deleted file mode 100644 index a4724ec1ca..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/IntExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Stride.Shaders.Spirv.Core.Parsing; - -public static class IntExtensions -{ - public static bool HasEndString(this int i) - { - return - (char)(i >> 24) == '\0' - || (char)(i >> 16 & 0XFF) == '\0' - || (char)(i >> 8 & 0xFF) == '\0' - || (char)(i & 0xFF) == '\0'; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index fe8e29f8cc..3fb0ef8143 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -36,142 +36,76 @@ public bool MoveNext() } else { - var logOp = logicalOperands[oid]; - - if (OpCode == Op.OpDecorate) + (bool result, int newWid, int newOid) = OpCode switch { - if (oid == 0) - { - wid += 1; - oid += 1; - return true; - } - else if (oid > 0) + Op.OpDecorate => oid switch { - var builtin = (Decoration)Operands[1]; - bool has2Extra = builtin == Decoration.LinkageAttributes; - bool has1Extra = - builtin == Decoration.BuiltIn - || builtin == Decoration.Location - || builtin == Decoration.SpecId - || builtin == Decoration.ArrayStride - || builtin == Decoration.MatrixStride - || builtin == Decoration.UniformId - || builtin == Decoration.Stream - || builtin == Decoration.Component - || builtin == Decoration.Index - || builtin == Decoration.Binding - || builtin == Decoration.DescriptorSet - || builtin == Decoration.Offset - || builtin == Decoration.XfbBuffer - || builtin == Decoration.XfbStride - || builtin == Decoration.FuncParamAttr - || builtin == Decoration.FPRoundingMode - || builtin == Decoration.FPFastMathMode - || builtin == Decoration.LinkageAttributes - || builtin == Decoration.InputAttachmentIndex - || builtin == Decoration.Alignment - || builtin == Decoration.MaxByteOffset - || builtin == Decoration.AlignmentId - || builtin == Decoration.MaxByteOffsetId - || builtin == Decoration.SecondaryViewportRelativeNV - || builtin == Decoration.CounterBuffer; - if (has1Extra && oid == 1 && !has2Extra) - { - wid += 1; - oid += 1; - } - else if (has2Extra) - { - throw new NotImplementedException(); - } - else + 0 => (true, wid + 1, oid + 1), + _ => (Decoration)Operands[wid] switch { - return false; + Decoration.BuiltIn + or Decoration.Location + or Decoration.SpecId + or Decoration.ArrayStride + or Decoration.MatrixStride + or Decoration.UniformId + or Decoration.Stream + or Decoration.Component + or Decoration.Index + or Decoration.Binding + or Decoration.DescriptorSet + or Decoration.Offset + or Decoration.XfbBuffer + or Decoration.XfbStride + or Decoration.FuncParamAttr + or Decoration.FPRoundingMode + or Decoration.FPFastMathMode + or Decoration.InputAttachmentIndex + or Decoration.Alignment + or Decoration.MaxByteOffset + or Decoration.AlignmentId + or Decoration.MaxByteOffsetId + or Decoration.SecondaryViewportRelativeNV + or Decoration.CounterBuffer => (true, wid + 1, oid + 1), + Decoration.LinkageAttributes => throw new NotImplementedException(), + _ => (false, wid, oid) } - - } - - oid += 1; - if (oid > 2) - return false; - else - return wid < Operands.Length; - } - else if (logOp.Quantifier == OperandQuantifier.One) - { - if (logOp.Kind == OperandKind.LiteralString) + }, + _ => logOp switch { - while (!Operands[wid].HasEndString()) - wid += 1; - wid += 1; + { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => (true, wid + 2, oid + 1), + { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => (true, wid + Operands[wid..].LengthOfString(), oid + 1), + { Quantifier: OperandQuantifier.One, Kind: _ } => (true, wid + 1, oid + 1), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => (wid < Operands.Length - 2, wid + (wid < Operands.Length - 2 ? 2 : 0), oid + wid < Operands.Length - 2 ? 1 : 0), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } + => (wid < Operands.Length - 1, wid + (wid < Operands.Length - 1 ? Operands[wid..].LengthOfString() : 0), oid + wid < Operands.Length ? 1 : 0), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } + => (wid < Operands.Length - 1, wid + (wid < Operands.Length ? 1 : 0), oid + wid < Operands.Length ? 1 : 0), + { Quantifier: OperandQuantifier.ZeroOrMore } + => (wid < Operands.Length - 1, wid < Operands.Length - 1 ? Operands.Length : wid, oid + (wid < Operands.Length - 1 ? 0 : 1)), + _ => (false, wid, oid) } - else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) - wid += 2; - else - wid += 1; - oid += 1; - - } - else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) - { - if ( - pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) - && wid < Operands.Length - 1 - ) - { - wid += 2; - } - else if ( - logOp.Kind == OperandKind.LiteralString - && wid < Operands.Length - ) - { - while (!Operands[wid].HasEndString()) - wid += 1; - wid += 1; - } - else if (wid < Operands.Length) - wid += 1; - oid += 1; - - } - else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) - { - if (logOp.Kind == OperandKind.LiteralString) - throw new NotImplementedException("params of strings is not yet implemented"); - else if ( - pairs.Contains(logOp.Kind ?? throw new Exception()) - && wid < Operands.Length - 2 - ) - wid += 2; - else if (wid < Operands.Length - 1) - wid += 1; - else - oid += 1; - - } - if (oid >= logicalOperands.Count) - return false; - return wid < Operands.Length; + }; + wid = newWid; + oid = newOid; + return result && wid <= Operands.Length && oid < logicalOperands.Count; } - } public SpvOperand ParseCurrent() { var logOp = logicalOperands[oid]; - if (OpCode == Op.OpDecorate) + + return OpCode switch { - SpvOperand result = new(); - if (oid == 0) - result = new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)); - else if (oid == 1) - result = new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)); - else if (oid == 2) + Op.OpDecorate => oid switch { - result = result with + 0 => new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)), + 1 => new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)), + 2 => new SpvOperand() with { Kind = (Decoration)Operands[1] switch { @@ -201,39 +135,266 @@ public SpvOperand ParseCurrent() Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, Decoration.CounterBuffer => OperandKind.IdRef, _ => OperandKind.None - } - }; - } - return result; - - } - else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) - { - if (logOp.Kind == OperandKind.LiteralString) + }, + Quantifier = OperandQuantifier.One, + Words = Operands.Slice(wid, 1) + }, + _ => throw new NotImplementedException() + }, + _ => logOp switch { - var length = 0; - while (!Operands[wid + length].HasEndString()) - length += 1; - length += 1; - var result = new SpvOperand(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, length)); - - return result; - } - else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) - { - var result = new SpvOperand(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); - return result; + { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } l + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + { Quantifier: OperandQuantifier.One, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } + => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Quantifier: OperandQuantifier.ZeroOrMore } + => pairs.Contains(logOp.Kind ?? OperandKind.None) + ? new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)) + : new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + _ => throw new NotImplementedException() } - else - return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); - } - else - { - if (pairs.Contains(logOp.Kind ?? OperandKind.None)) - return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); - else - return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); - } + }; } -} \ No newline at end of file +} + + + +// public ref struct OpDataEnumerator +// { +// static readonly OperandKind[] pairs = [.. Enum.GetValues().Where(x => x.ToString().StartsWith("Pair"))]; +// readonly Span instruction; +// readonly Span Operands => instruction[1..]; +// readonly Op OpCode => (Op)(instruction[0] & 0xFFFF); +// readonly LogicalOperandArray logicalOperands; +// int wid; +// int oid; + +// public OpDataEnumerator(Span instruction) +// { +// this.instruction = instruction; +// logicalOperands = InstructionInfo.GetInfo(OpCode); +// oid = -1; +// wid = 0; +// } + +// public SpvOperand Current => ParseCurrent(); + +// public bool MoveNext() +// { +// if (oid < 0) +// { +// oid = 0; +// if (logicalOperands[0].Kind == OperandKind.None) +// return false; +// return true; +// } +// else +// { + +// var logOp = logicalOperands[oid]; + +// if (OpCode == Op.OpDecorate) +// { +// if (oid == 0) +// { +// wid += 1; +// oid += 1; +// return true; +// } +// else if (oid > 0) +// { +// var builtin = (Decoration)Operands[1]; +// bool has2Extra = builtin == Decoration.LinkageAttributes; +// bool has1Extra = +// builtin == Decoration.BuiltIn +// || builtin == Decoration.Location +// || builtin == Decoration.SpecId +// || builtin == Decoration.ArrayStride +// || builtin == Decoration.MatrixStride +// || builtin == Decoration.UniformId +// || builtin == Decoration.Stream +// || builtin == Decoration.Component +// || builtin == Decoration.Index +// || builtin == Decoration.Binding +// || builtin == Decoration.DescriptorSet +// || builtin == Decoration.Offset +// || builtin == Decoration.XfbBuffer +// || builtin == Decoration.XfbStride +// || builtin == Decoration.FuncParamAttr +// || builtin == Decoration.FPRoundingMode +// || builtin == Decoration.FPFastMathMode +// || builtin == Decoration.LinkageAttributes +// || builtin == Decoration.InputAttachmentIndex +// || builtin == Decoration.Alignment +// || builtin == Decoration.MaxByteOffset +// || builtin == Decoration.AlignmentId +// || builtin == Decoration.MaxByteOffsetId +// || builtin == Decoration.SecondaryViewportRelativeNV +// || builtin == Decoration.CounterBuffer; +// if (has1Extra && oid == 1 && !has2Extra) +// { +// wid += 1; +// oid += 1; +// } +// else if (has2Extra) +// { +// throw new NotImplementedException(); +// } +// else +// { +// return false; +// } + +// } + +// oid += 1; +// if (oid > 2) +// return false; +// else +// return wid < Operands.Length; +// } +// else if (logOp.Quantifier == OperandQuantifier.One) +// { +// if (logOp.Kind == OperandKind.LiteralString) +// { +// while (!Operands[wid].HasEndString()) +// wid += 1; +// wid += 1; +// } +// else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) +// wid += 2; +// else +// wid += 1; +// oid += 1; + +// } +// else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) +// { +// if ( +// pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) +// && wid < Operands.Length - 1 +// ) +// { +// wid += 2; +// } +// else if ( +// logOp.Kind == OperandKind.LiteralString +// && wid < Operands.Length +// ) +// { +// while (!Operands[wid].HasEndString()) +// wid += 1; +// wid += 1; +// } +// else if (wid < Operands.Length) +// wid += 1; +// oid += 1; + +// } +// else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) +// { +// if (logOp.Kind == OperandKind.LiteralString) +// throw new NotImplementedException("params of strings is not yet implemented"); +// else if ( +// pairs.Contains(logOp.Kind ?? throw new Exception()) +// && wid < Operands.Length - 2 +// ) +// wid += 2; +// else if (wid < Operands.Length - 1) +// wid += 1; +// else +// oid += 1; + +// } +// if (oid >= logicalOperands.Count) +// return false; +// return wid < Operands.Length; +// } + +// } + +// public SpvOperand ParseCurrent() +// { +// var logOp = logicalOperands[oid]; +// if (OpCode == Op.OpDecorate) +// { +// SpvOperand result = new(); +// if (oid == 0) +// result = new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)); +// else if (oid == 1) +// result = new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)); +// else if (oid == 2) +// { +// result = result with +// { +// Kind = (Decoration)Operands[1] switch +// { +// Decoration.BuiltIn => OperandKind.BuiltIn, +// Decoration.Location => OperandKind.LiteralInteger, +// Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, +// Decoration.ArrayStride => OperandKind.LiteralInteger, +// Decoration.MatrixStride => OperandKind.LiteralInteger, +// Decoration.UniformId => OperandKind.IdScope, +// Decoration.Stream => OperandKind.LiteralInteger, +// Decoration.Component => OperandKind.LiteralInteger, +// Decoration.Index => OperandKind.LiteralInteger, +// Decoration.Binding => OperandKind.LiteralInteger, +// Decoration.DescriptorSet => OperandKind.LiteralInteger, +// Decoration.Offset => OperandKind.LiteralInteger, +// Decoration.XfbBuffer => OperandKind.LiteralInteger, +// Decoration.XfbStride => OperandKind.LiteralInteger, +// Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, +// Decoration.FPRoundingMode => OperandKind.FPRoundingMode, +// Decoration.FPFastMathMode => OperandKind.FPFastMathMode, +// Decoration.LinkageAttributes => OperandKind.LiteralString, +// Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, +// Decoration.Alignment => OperandKind.LiteralInteger, +// Decoration.MaxByteOffset => OperandKind.LiteralInteger, +// Decoration.AlignmentId => OperandKind.IdRef, +// Decoration.MaxByteOffsetId => OperandKind.IdRef, +// Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, +// Decoration.CounterBuffer => OperandKind.IdRef, +// _ => OperandKind.None +// } +// }; +// } +// return result; + +// } +// else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) +// { +// if (logOp.Kind == OperandKind.LiteralString) +// { +// var length = 0; +// while (!Operands[wid + length].HasEndString()) +// length += 1; +// length += 1; +// var result = new SpvOperand(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, length)); + +// return result; +// } +// else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) +// { +// var result = new SpvOperand(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); +// return result; +// } +// else +// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); +// } +// else +// { +// if (pairs.Contains(logOp.Kind ?? OperandKind.None)) +// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); +// else +// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); +// } +// } + +// } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index 5d509b5450..5f7516b53c 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -39,12 +39,12 @@ public void ReplaceIdResult(int replacement) public readonly T ToEnum() where T : Enum => Unsafe.As(ref Words[0]); - internal readonly T ToLiteral() + public readonly T ToLiteral() { using var lit = new LiteralValue(Words); return lit.Value; } - internal readonly LiteralArray ToLiteralArray() + public readonly LiteralArray ToLiteralArray() => LiteralArray.From(Words); public readonly bool TryToLiteral(out LiteralValue literal) diff --git a/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs b/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs new file mode 100644 index 0000000000..169335f628 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs @@ -0,0 +1,23 @@ +namespace Stride.Shaders.Spirv.Core; + +public static class IntExtensions +{ + public static bool HasEndString(this int i) + { + return + (char)(i >> 24) == '\0' + || (char)(i >> 16 & 0XFF) == '\0' + || (char)(i >> 8 & 0xFF) == '\0' + || (char)(i & 0xFF) == '\0'; + } + public static int LengthOfString(this Span ints) + { + for (int i = 0; i < ints.Length; i++) + { + if (ints[i].HasEndString()) + return i + 1; + } + return ints.Length; + } + public static int GetWordCount(this string s) => s.Length < 4 ? 1 : (s.Length / 4) + (s.Length % 4 > 0 ? 1 : 0); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index d86fea28e5..f116b89b19 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -166,18 +166,19 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst if (operands.Any(x => x is { Kind: "IdResult" })) body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + var tmp = -1; foreach (var operand in operands) { - + tmp += 1; (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); + body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) @@ -245,6 +246,12 @@ private set }} }} + public {instruction.OpName}() + {{ + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.{instruction.OpName} | (1 << 16); + }} + {body1} {body2} {body3} @@ -283,18 +290,19 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i if (operands.Any(x => x is { Kind: "IdResult" })) body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); + var tmp = -1; foreach (var operand in operands) { - + tmp += 1; (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); + body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) @@ -406,9 +414,9 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); // Body 2 body2.AppendLine($"if(o.Name == \"{operandName}\")"); @@ -518,11 +526,11 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else if (typename.StartsWith("LiteralValue")) - body1.Append($"public T {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + body1.Append($"public T {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; UpdateInstructionMemory(); }} }}"); + body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); // Body 2 body2.AppendLine($"if(o.Name == \"{operandName}\")"); diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index d448f71c45..5d33fa94a0 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -19,10 +19,6 @@ public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool write // Assembly code generation logic goes here var writer = new DisWriter(buffer, useNames, writeToConsole); writer.Disassemble(); - foreach (var instruction in data) - { - // Disassemble each instruction - } return ""; } @@ -33,7 +29,7 @@ struct DisWriter(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsol DisData data = new(buffer, useNames, writeToConsole); readonly StringBuilder builder = new(); - DisWriter AppendLine(string text, ConsoleColor? color = null) + readonly DisWriter AppendLine(string text, ConsoleColor? color = null) { if (color is not null) { @@ -47,7 +43,7 @@ DisWriter AppendLine(string text, ConsoleColor? color = null) builder.AppendLine(text); return this; } - DisWriter Append(T text, ConsoleColor? color = null) + readonly DisWriter Append(T text, ConsoleColor? color = null) { if (color is not null) { @@ -61,22 +57,22 @@ DisWriter Append(T text, ConsoleColor? color = null) builder.Append(text); return this; } - DisWriter AppendRepeatChar(char c, int count) + readonly DisWriter AppendRepeatChar(char c, int count) { if (data.WriteToConsole) - while (count-- > 0) + for(int i = 0; i < count; i++) Console.Write(c); builder.Append(c, count); return this; } - DisWriter AppendLiteralNumber(T value) + readonly DisWriter AppendLiteralNumber(T value) where T : struct, INumber { Append(value, ConsoleColor.Red).Append(' '); return this; } - DisWriter AppendLiteralNumber(LiteralValue value, bool dispose = true) + readonly DisWriter AppendLiteralNumber(LiteralValue value, bool dispose = true) where T : struct, INumber { Append(value.Value, ConsoleColor.Red).Append(' '); @@ -85,20 +81,20 @@ DisWriter AppendLiteralNumber(LiteralValue value, bool dispose = true) return this; } - DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) + readonly DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) { Append('"', ConsoleColor.Green).Append(value.Value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); if (dispose) value.Dispose(); return this; } - DisWriter AppendLiteralString(string value) + readonly DisWriter AppendLiteralString(string value) { Append('"', ConsoleColor.Green).Append(value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); return this; } - DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = true) + readonly DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = true) where T : struct, INumber { T tmp = default; @@ -125,7 +121,7 @@ DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = true) value.Dispose(); return this; } - DisWriter AppendResultId(int? id = null) + readonly DisWriter AppendResultId(int? id = null) { if (id is int i) { @@ -150,7 +146,7 @@ DisWriter AppendResultId(int? id = null) Append(" = "); } else - AppendRepeatChar(' ', data.IdOffset - 1); + AppendRepeatChar(' ', data.IdOffset); return this; } @@ -168,7 +164,7 @@ public void DisHeader() { var header = data.Buffer.Header; AppendLine($"; SPIR-V"); - AppendLine($"; Version: {header.Version}"); + AppendLine($"; Version: {header.VersionNumber >> 16}.{header.VersionNumber & 0xFF}"); AppendLine($"; Generator: {header.Generator}"); AppendLine($"; Bound: {header.Bound}"); AppendLine($"; Schema: {header.Schema}"); @@ -196,20 +192,81 @@ public void DisInstruction(in OpDataIndex instruction, in DisWriter writer) ref var data = ref instruction.Data; var info = InstructionInfo.GetInfo(data); if (info.GetResultIndex(out int resultIndex)) - AppendResultId(data.Memory.Span[resultIndex]); + AppendResultId(data.Memory.Span[1 + resultIndex]); else AppendResultId(); Append(instruction.Op.ToString()).Append(' '); - JsonElement e; - e.TryGetProperty() foreach (var operand in data) { - _ = operand.Kind switch + _ = (operand.Kind, operand.Quantifier) switch { - OperandKind.LiteralString => AppendLiteralString(operand.To>().Value), - _ => this + (OperandKind.IdResult, _) => Append(""), + ( + OperandKind.LiteralInteger + or OperandKind.LiteralExtInstInteger + or OperandKind.LiteralSpecConstantOpInteger, + OperandQuantifier.One + ) => AppendLiteralNumber(operand.ToLiteral()), + (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => Append('%', ConsoleColor.Green).Append(operand.ToLiteral(), ConsoleColor.Green).Append(' '), + (OperandKind.LiteralFloat, OperandQuantifier.One) => AppendLiteralNumber(operand.ToLiteral()), + (OperandKind.LiteralString, OperandQuantifier.One) => AppendLiteralString(operand.ToLiteral()), + (OperandKind.ImageOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FPFastMathMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.SelectionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.LoopControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FunctionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.MemorySemantics, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.MemoryAccess, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.KernelProfilingInfo, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.RayFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FragmentShadingRate, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.RawAccessChainOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.SourceLanguage, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.ExecutionModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.AddressingModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.MemoryModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.ExecutionMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.StorageClass, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.Dim, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.SamplerAddressingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.SamplerFilterMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.ImageFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.ImageChannelOrder, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.ImageChannelDataType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FPRoundingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FPDenormMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.QuantizationModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FPOperationMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.OverflowModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.LinkageType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.AccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.HostAccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FunctionParameterAttribute, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.Decoration, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.BuiltIn, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.Scope, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.GroupOperation, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.KernelEnqueueFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.Capability, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.RayQueryIntersection, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.RayQueryCommittedIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.RayQueryCandidateIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.PackedVectorFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.CooperativeMatrixOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.CooperativeMatrixLayout, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.CooperativeMatrixUse, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.CooperativeMatrixReduce, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.TensorClampMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.TensorAddressingOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.InitializationModeQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.LoadCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.StoreCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.NamedMaximumNumberOfRegisters, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandKind.FPEncoding, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), }; } + AppendLine(""); } } @@ -282,12 +339,22 @@ void ComputeIdOffset() var maxName = 0; foreach (var i in Buffer) { - maxName = i.Op switch + if (i.Op == Op.OpName) { - Op.OpName => maxName > ((OpName)i).Name.Length ? maxName : ((OpName)i).Name.Length, - Op.OpMemberName => maxName > ((OpMemberName)i).Name.Length ? maxName : ((OpMemberName)i).Name.Length, - _ => maxName - }; + var nameInst = (OpName)i; + maxName = maxName > nameInst.Name.Length ? maxName : nameInst.Name.Length; + } + else if (i.Op == Op.OpMemberName) + { + var memberInst = (OpMemberName)i; + maxName = maxName > memberInst.Name.Length ? maxName : memberInst.Name.Length; + } + // maxName = i.Op switch + // { + // Op.OpName => maxName > ((OpName)i).Name.Length ? maxName : ((OpName)i).Name.Length, + // Op.OpMemberName => maxName > ((OpMemberName)i).Name.Length ? maxName : ((OpMemberName)i).Name.Length, + // _ => maxName + // }; } IdOffset += maxName; } From af49848e93a4577657a7d52ec30aac45047f77bd Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 12 Sep 2025 05:54:49 +0200 Subject: [PATCH 0443/1182] Corrected disassembly --- .../Examples.Spirv.cs | 59 +++++++------- src/Stride.Shaders.Experiments/test.spv | Bin 0 -> 964 bytes .../Buffers/NewSpirvBuffer.cs | 21 ++++- .../Parsing/OpDataEnumerator.cs | 12 +-- .../Parsing/SpirvHeader.cs | 2 +- .../WordsExtensions.cs | 8 +- .../SPVGenerator.Info.cs | 22 +++--- .../SPVGenerator.Instructions.cs | 18 ++--- src/Stride.Shaders/Spirv/Tools/Dis.cs | 73 ++++++++++++++++-- 9 files changed, 145 insertions(+), 70 deletions(-) create mode 100644 src/Stride.Shaders.Experiments/test.spv diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index cd6656f617..06ce0cb44a 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; +using System.Reflection.Metadata.Ecma335; namespace Stride.Shaders.Experiments; @@ -67,54 +68,52 @@ public static void CreateNewShader() var buffer = new NewSpirvBuffer(); // Capabilities - var litS = new LiteralValue("main"); buffer.Add(new OpCapability(Capability.Shader)); var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); buffer.AddRef(ref extInstImport); buffer.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - + // declarations - var t_void = new OpTypeVoid(id++); - buffer.AddRef(ref t_void); + buffer.Add(new OpTypeVoid(id++), out var t_void); buffer.Add(new OpTypeBool(id++), out var t_bool); - buffer.Add(new OpTypeFunction(id++, t_void, []), out var t_func); + buffer.Add(new OpTypeFunction(t_void, id++, []), out var t_func); buffer.Add(new OpTypeFloat(id++, 32, null), out var t_float); buffer.Add(new OpTypeInt(id++, 32, 0), out var t_uint); buffer.Add(new OpTypeInt(id++, 32, 1), out var t_int); - buffer.Add(new OpTypeFunction(id++, t_int, [t_int, t_int]), out var t_func_add); - buffer.Add(new OpTypeVector(id++, t_float, 4), out var t_float4); + buffer.Add(new OpTypeFunction(id++, returnType: t_int, [t_int, t_int]), out var t_func_add); + buffer.Add(new OpTypeVector(id++, componentType: t_float, 4), out var t_float4); buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func); - buffer.Add(new OpConstant(id++, t_float, 5f), out var constant1); - buffer.Add(new OpConstant(id++, t_float, 2.23f), out var constant2); - buffer.Add(new OpConstant(id++, t_uint, 5), out var constant3); + buffer.Add(new OpConstant(t_float, id++, 5f), out var constant1); + buffer.Add(new OpConstant(t_float, id++, 2.23f), out var constant2); + buffer.Add(new OpConstant(t_uint, id++, 5), out var constant3); buffer.Add(new OpConstantComposite( - id++, t_float4, + id++, [constant1, constant1, constant2, constant1] ), out var compositeType); - buffer.Add(new OpTypeArray(id++, t_float4, constant3), out var t_array); + buffer.Add(new OpTypeArray(t_float4, id++, constant3), out var t_array); buffer.Add(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct); buffer.Add(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2); buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2); - buffer.Add(new OpVariable(id++, t_p_struct2, StorageClass.Uniform, null), out var v_struct2); - buffer.Add(new OpConstant(id++, t_int, 1), out var constant4); + buffer.Add(new OpVariable(t_p_struct2, id++, StorageClass.Uniform, null), out var v_struct2); + buffer.Add(new OpConstant(t_int, id++, 1), out var constant4); buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint); - buffer.Add(new OpConstant(id++, t_uint, 0), out var constant5); + buffer.Add(new OpConstant(t_uint, id++, 0), out var constant5); buffer.Add(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output); - buffer.Add(new OpVariable(id++, t_p_output, StorageClass.Output, null), out var v_output); + buffer.Add(new OpVariable(t_p_output, id++, StorageClass.Output, null), out var v_output); buffer.Add(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input); - buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input); - buffer.Add(new OpConstant(id++, t_int, 0), out var constant6); - buffer.Add(new OpConstant(id++, t_int, 2), out var constant7); + buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input); + buffer.Add(new OpConstant(t_int, id++, 0), out var constant6); + buffer.Add(new OpConstant(t_int, id++, 2), out var constant7); buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif); - buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_2); + buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_2); buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); - buffer.Add(new OpConstant(id++, t_int, 4), out var constant8); - buffer.Add(new OpVariable(id++, t_p_input, StorageClass.Input, null), out var v_input_3); + buffer.Add(new OpConstant(t_int, id++, 4), out var constant8); + buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_3); buffer.Add(new OpDecorate(t_array, Decoration.ArrayStride, 16)); buffer.Add(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)); buffer.Add(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)); @@ -129,22 +128,22 @@ public static void CreateNewShader() buffer.Add(new OpMemberName(t_struct, 0, "b")); buffer.Add(new OpMemberName(t_struct, 1, "v")); buffer.Add(new OpMemberName(t_struct, 2, "i")); - buffer.Add(new OpFunction(id++, t_int, FunctionControlMask.None, t_func_add), out var add); + buffer.Add(new OpFunction(t_int, id++, FunctionControlMask.None, t_func_add), out var add); - buffer.Add(new OpFunctionParameter(id++, t_int), out var a); - buffer.Add(new OpFunctionParameter(id++, t_int), out var b); + buffer.Add(new OpFunctionParameter(t_int, id++), out var a); + buffer.Add(new OpFunctionParameter(t_int, id++), out var b); buffer.Add(new OpLabel(id++), out var label); - buffer.Add(new OpIAdd(id++, t_int, a, b), out var res); + buffer.Add(new OpIAdd(t_int, id++, a, b), out var res); buffer.Add(new OpReturnValue(res)); buffer.Add(new OpFunctionEnd()); - buffer.Add(new OpFunction(id++, t_void, FunctionControlMask.None, t_func), out var main); + buffer.Add(new OpFunction(t_void, id++, FunctionControlMask.None, t_func), out var main); buffer.Add(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])); buffer.Add(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)); buffer.Add(new OpLabel(id++), out var label2); - buffer.Add(new OpFunctionCall(id++, t_int, add, [constant7, constant7]), out var resAdd); + buffer.Add(new OpFunctionCall(t_int, id++, add, [constant7, constant7]), out var resAdd); buffer.Add(new OpReturn()); - buffer.Add(new OpFunctionEnd());; + buffer.Add(new OpFunctionEnd()); buffer.Sort(); var span = buffer.ToBuffer(); @@ -277,7 +276,7 @@ public static void CreateShader() // "test.spv", // MemoryMarshal.Cast(buffer.ToBuffer().AsSpan()) // ); - #warning replace +#warning replace throw new NotImplementedException(); } diff --git a/src/Stride.Shaders.Experiments/test.spv b/src/Stride.Shaders.Experiments/test.spv new file mode 100644 index 0000000000000000000000000000000000000000..bd84918c6b81debddc73ad8df228b1b549128b4a GIT binary patch literal 964 zcmY+C$u2}u5QdK)%v#ghJhV16Asq{2Z0uN&h<*XY#)3$QwMX$79?gdMzP`7TR>^;= z{+dpmy0=(Z8%U+Tr1W>slqOOk=^07ou0Fr)T()1|9@_f{dzDn|W*HwRUP8CPb?55t z@j0a`arq$VCt5`pz+(@$_PvK=rh8DP*8EOxub`jkdQM~r+xd(u7qGC`GS@%9cj%9t z$afa~w?MJ?1X_QHx%#5VOCB({hTV)rw7zBZSdTC2b@k4+!#)P^E#$eU@Hy;N;9U`K zV7u1_r#rAl$d}O0>OLZWG51BkdAR+8J74e_>{(C*H9FaAic`MIDfjMa>@vCm>Ui9} zwj$5w$@)5%@9+-int`jWk9Q1XTN85|8v!YOp7{>>D7g8moH>X8kNLaU)>Ob^-gg|^ zeJ?Yu-&gJTa*j!~Z;<}v|!S%X3usLbL#gl=d)fu4U`kOGj4+> z_~w=^^dZ^a*8+<6F*hFZ7W3D^2RYiCz<)%a^&9BO({C^H?60_&AA0?gYps3%0KzOH Aq5uE@ literal 0 HcmV?d00001 diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index f6e56c9aa9..ba9a8c38bc 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -187,10 +187,7 @@ public bool MoveNext() } } - public void Sort() - { - Memory.Sort(static (a, b) => a.CompareTo(b)); - } + public void Sort() => Memory.Sort(static (a, b) => a.CompareTo(b)); public SpanOwner ToBuffer() { @@ -205,6 +202,22 @@ public SpanOwner ToBuffer() } return result; } + + public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) + { + foreach (var op in this) + { + var info = InstructionInfo.GetInfo(op.Op); + var mem = op.Data.Memory; + if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == typeId) + { + instruction = op; + return true; + } + } + instruction = default; + return false; + } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 3fb0ef8143..16e9eb03b7 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -91,7 +91,7 @@ or Decoration.SecondaryViewportRelativeNV }; wid = newWid; oid = newOid; - return result && wid <= Operands.Length && oid < logicalOperands.Count; + return result && wid < Operands.Length && oid < logicalOperands.Count; } } @@ -153,10 +153,12 @@ public SpvOperand ParseCurrent() => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), - { Quantifier: OperandQuantifier.ZeroOrMore } - => pairs.Contains(logOp.Kind ?? OperandKind.None) - ? new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)) - : new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length - 1 ? Operands[wid..] : []), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } + => throw new Exception("params of strings is not yet implemented"), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: _ } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length - 1 ? Operands[wid..] : []), _ => throw new NotImplementedException() } }; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index 93ab6d361b..ec8e055035 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -27,7 +27,7 @@ public SpirvVersion(string version) { if(version.Length == 3 && char.IsDigit(version[0]) && version[1] == '.' && char.IsDigit(version[2])) { - Version = version[0] - '0' << 16 | version[1] - '0' << 8; + Version = version[0] - '0' << 16 | version[2] - '0' << 8; } } diff --git a/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs b/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs index 169335f628..b67520088c 100644 --- a/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs +++ b/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs @@ -19,5 +19,11 @@ public static int LengthOfString(this Span ints) } return ints.Length; } - public static int GetWordCount(this string s) => s.Length < 4 ? 1 : (s.Length / 4) + (s.Length % 4 > 0 ? 1 : 0); + public static int GetWordCount(this string s) + { + var length = s.Length + 1; // +1 for the null terminator + if(length % 4 == 0) + return length / 4; + return (length / 4) + 1; + } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 462d78b2e9..157075ebc9 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -40,21 +40,19 @@ static void GenerateInstructionInformation(SourceProductionContext spc, Equatabl { var code = new StringBuilder(); code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public partial class InstructionInfo") - .AppendLine("{") - .AppendLine("static InstructionInfo()") - .AppendLine("{"); + .AppendLine(@" + using static Stride.Shaders.Spirv.Specification; + namespace Stride.Shaders.Spirv.Core; + + public partial class InstructionInfo + { + static InstructionInfo() + {" + ); foreach (var instruction in instructions) GenerateInfo(instruction, code); - code - .AppendLine("Instance.InitOrder();") - .AppendLine("}") - .AppendLine("}"); + code.AppendLine("Instance.InitOrder();}}"); spc.AddSource( "InstructionInfo.gen.cs", SourceText.From( diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index f116b89b19..a604dc0772 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -143,8 +143,7 @@ static string ToSpreadOperator(OperandData operand) static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { @@ -220,7 +219,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); + body2.AppendLine("DataIndex = index;").AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction @@ -264,8 +263,7 @@ private set static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { @@ -344,7 +342,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); + body2.AppendLine("DataIndex = index;").AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction @@ -385,8 +383,7 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) { var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); @@ -460,7 +457,7 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, .AppendLine("}"); } - body2.AppendLine("}"); + body2.AppendLine("DataIndex = index;").AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction {{ @@ -580,7 +577,8 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); + body2.AppendLine("DataIndex = index;").AppendLine("}"); + builder.AppendLine($@" // {string.Join(", ", instruction.Operands?.AsList().Select(x => $"{x.Name}:{x.Kind}"))} public struct {instruction.OpName} : IMemoryInstruction diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 5d33fa94a0..6c59979728 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -57,10 +57,23 @@ readonly DisWriter Append(T text, ConsoleColor? color = null) builder.Append(text); return this; } + + readonly DisWriter AppendIdRef(int id) + { + if (data.UseNames && data.NameTable.TryGetValue(id, out var name)) + return Append($"%{name} ", ConsoleColor.Green); + else return Append($"%{id} ", ConsoleColor.Green); + } + readonly DisWriter AppendIdRefs(Span ids) + { + foreach (var id in ids) + AppendIdRef(id); + return this; + } readonly DisWriter AppendRepeatChar(char c, int count) { if (data.WriteToConsole) - for(int i = 0; i < count; i++) + for (int i = 0; i < count; i++) Console.Write(c); builder.Append(c, count); return this; @@ -104,7 +117,7 @@ readonly DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = long or ulong or double => 2, _ => throw new NotImplementedException("Cannot create LiteralValue from the provided words") }; - for(int i = 0; i < value.WordCount; i += size) + for (int i = 0; i < value.WordCount; i += size) { if (size == 1) { @@ -121,13 +134,55 @@ readonly DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = value.Dispose(); return this; } + + DisWriter AppendContextDependentNumber(SpvOperand operand, OpData data, NewSpirvBuffer buffer) + { + int typeId = data.Op switch + { + Op.OpConstant or Op.OpSpecConstant => data.Memory.Span[1], + _ => throw new Exception("Unsupported context dependent number in instruction " + data.Op) + }; + if (buffer.TryGetInstructionById(typeId, out var typeInst)) + { + if (typeInst.Op == Op.OpTypeInt) + { + var type = (OpTypeInt)typeInst; + _ = type switch + { + { Width: <= 32, Signedness: 0 } => AppendLiteralNumber(operand.ToLiteral()), + { Width: <= 32, Signedness: 1 } => AppendLiteralNumber(operand.ToLiteral()), + { Width: 64, Signedness: 0 } => AppendLiteralNumber(operand.ToLiteral()), + { Width: 64, Signedness: 1 } => AppendLiteralNumber(operand.ToLiteral()), + _ => throw new NotImplementedException("Unsupported int width " + type.Width), + }; + } + else if (typeInst.Op == Op.OpTypeFloat) + { + var type = new OpTypeFloat(typeInst); + _ = type switch + { + { Width: 16 } => AppendLiteralNumber(operand.ToLiteral()), + { Width: 32 } => AppendLiteralNumber(operand.ToLiteral()), + { Width: 64 } => AppendLiteralNumber(operand.ToLiteral()), + _ => throw new NotImplementedException("Unsupported float width " + type.Width), + }; + } + else + throw new NotImplementedException("Unsupported context dependent number with type " + typeInst.Op); + return this; + } + else + throw new Exception("Cannot find type instruction for id " + typeId); + + } + readonly DisWriter AppendResultId(int? id = null) { if (id is int i) { if (data.UseNames && data.NameTable.TryGetValue(i, out var name)) { - AppendRepeatChar(' ', data.IdOffset - name.Length - 1); + AppendRepeatChar(' ', data.IdOffset - name.Length - 1 - 3); Append('%', ConsoleColor.Cyan); Append(name, ConsoleColor.Cyan); } @@ -178,14 +233,14 @@ public void DisInstruction(in OpDataIndex instruction, in DisWriter writer) var nameInst = (OpName)instruction; data.NameTable[nameInst.Target] = nameInst.Name; AppendResultId(); - Append("OpName ").AppendLiteralNumber(nameInst.Target).AppendLiteralString(nameInst.Name); + Append("OpName ", ConsoleColor.Blue).AppendLiteralNumber(nameInst.Target).AppendLiteralString(nameInst.Name).AppendLine(""); } else if (instruction.Op == Op.OpMemberName) { var memberInst = (OpMemberName)instruction; data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; AppendResultId(); - Append("OpMemberName ").AppendLiteralNumber(memberInst.Type).AppendLiteralNumber(memberInst.Member).AppendLiteralString(memberInst.Name); + Append("OpMemberName ", ConsoleColor.Blue).AppendLiteralNumber(memberInst.Type).AppendLiteralNumber(memberInst.Member).AppendLiteralString(memberInst.Name).AppendLine(""); } else { @@ -195,7 +250,7 @@ public void DisInstruction(in OpDataIndex instruction, in DisWriter writer) AppendResultId(data.Memory.Span[1 + resultIndex]); else AppendResultId(); - Append(instruction.Op.ToString()).Append(' '); + Append(instruction.Op.ToString(), ConsoleColor.Blue).Append(' '); foreach (var operand in data) { _ = (operand.Kind, operand.Quantifier) switch @@ -207,7 +262,9 @@ or OperandKind.LiteralExtInstInteger or OperandKind.LiteralSpecConstantOpInteger, OperandQuantifier.One ) => AppendLiteralNumber(operand.ToLiteral()), - (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => Append('%', ConsoleColor.Green).Append(operand.ToLiteral(), ConsoleColor.Green).Append(' '), + (OperandKind.LiteralContextDependentNumber, OperandQuantifier.One) => AppendContextDependentNumber(operand, data, buffer), + (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => AppendIdRef(operand.ToLiteral()), + (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.ZeroOrMore) => AppendIdRefs(operand.Words), (OperandKind.LiteralFloat, OperandQuantifier.One) => AppendLiteralNumber(operand.ToLiteral()), (OperandKind.LiteralString, OperandQuantifier.One) => AppendLiteralString(operand.ToLiteral()), (OperandKind.ImageOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), @@ -270,6 +327,8 @@ or OperandKind.LiteralExtInstInteger } } + + public override string ToString() => builder.ToString(); } From 23dc772d39a4029ecec62d6cce58b6126457646a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 14 Sep 2025 14:51:54 +0200 Subject: [PATCH 0444/1182] finicking little details with SpirvReader --- .../Examples.Spirv.cs | 134 +++++----- .../Buffers/NewSpirvBuffer.cs | 98 ++++++-- .../Buffers/SpirvBuffer.cs | 6 +- .../Parsing/OpDataEnumerator.cs | 238 +----------------- .../Parsing/OperandEnumerator.cs | 60 ++--- .../Parsing/OrderedEnumerator.cs | 9 +- .../Parsing/RefHeader.cs | 2 +- .../Parsing/SpirvReader.cs | 67 ++--- .../Parsing/SpirvWriter.cs | 47 ---- src/Stride.Shaders/Spirv/Tools/Dis.cs | 69 ++--- 10 files changed, 213 insertions(+), 517 deletions(-) delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 06ce0cb44a..bd1b1efd43 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -7,7 +7,6 @@ using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; -using System.Reflection.Metadata.Ecma335; namespace Stride.Shaders.Experiments; @@ -55,9 +54,6 @@ public static void ParseShader() InstructionInfo.GetInfo(Op.OpCapability); var shader = File.ReadAllBytes("../../shader.spv"); - - - SpirvReader.ParseToList(shader, new(8)); } public static void CreateNewShader() @@ -69,81 +65,81 @@ public static void CreateNewShader() // Capabilities - buffer.Add(new OpCapability(Capability.Shader)); + buffer.FluentAdd(new OpCapability(Capability.Shader)); var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); buffer.AddRef(ref extInstImport); - buffer.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + buffer.FluentAdd(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); // declarations - buffer.Add(new OpTypeVoid(id++), out var t_void); - - buffer.Add(new OpTypeBool(id++), out var t_bool); - buffer.Add(new OpTypeFunction(t_void, id++, []), out var t_func); - buffer.Add(new OpTypeFloat(id++, 32, null), out var t_float); - buffer.Add(new OpTypeInt(id++, 32, 0), out var t_uint); - buffer.Add(new OpTypeInt(id++, 32, 1), out var t_int); - buffer.Add(new OpTypeFunction(id++, returnType: t_int, [t_int, t_int]), out var t_func_add); - buffer.Add(new OpTypeVector(id++, componentType: t_float, 4), out var t_float4); - buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func); - buffer.Add(new OpConstant(t_float, id++, 5f), out var constant1); - buffer.Add(new OpConstant(t_float, id++, 2.23f), out var constant2); - buffer.Add(new OpConstant(t_uint, id++, 5), out var constant3); - buffer.Add(new OpConstantComposite( + buffer.FluentAdd(new OpTypeVoid(id++), out var t_void); + + buffer.FluentAdd(new OpTypeBool(id++), out var t_bool); + buffer.FluentAdd(new OpTypeFunction(t_void, id++, []), out var t_func); + buffer.FluentAdd(new OpTypeFloat(id++, 32, null), out var t_float); + buffer.FluentAdd(new OpTypeInt(id++, 32, 0), out var t_uint); + buffer.FluentAdd(new OpTypeInt(id++, 32, 1), out var t_int); + buffer.FluentAdd(new OpTypeFunction(id++, returnType: t_int, [t_int, t_int]), out var t_func_add); + buffer.FluentAdd(new OpTypeVector(id++, componentType: t_float, 4), out var t_float4); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Function, t_float4), out var t_p_float4_func); + buffer.FluentAdd(new OpConstant(t_float, id++, 5f), out var constant1); + buffer.FluentAdd(new OpConstant(t_float, id++, 2.23f), out var constant2); + buffer.FluentAdd(new OpConstant(t_uint, id++, 5), out var constant3); + buffer.FluentAdd(new OpConstantComposite( t_float4, id++, [constant1, constant1, constant2, constant1] ), out var compositeType); - buffer.Add(new OpTypeArray(t_float4, id++, constant3), out var t_array); - buffer.Add(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct); - buffer.Add(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2); - buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2); - buffer.Add(new OpVariable(t_p_struct2, id++, StorageClass.Uniform, null), out var v_struct2); - buffer.Add(new OpConstant(t_int, id++, 1), out var constant4); - buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint); - buffer.Add(new OpConstant(t_uint, id++, 0), out var constant5); - buffer.Add(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output); - buffer.Add(new OpVariable(t_p_output, id++, StorageClass.Output, null), out var v_output); - buffer.Add(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input); - buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input); - buffer.Add(new OpConstant(t_int, id++, 0), out var constant6); - buffer.Add(new OpConstant(t_int, id++, 2), out var constant7); - buffer.Add(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif); - buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_2); - buffer.Add(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); - buffer.Add(new OpConstant(t_int, id++, 4), out var constant8); - buffer.Add(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_3); - buffer.Add(new OpDecorate(t_array, Decoration.ArrayStride, 16)); - buffer.Add(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)); - buffer.Add(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)); - buffer.Add(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)); - buffer.Add(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)); - buffer.Add(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)); - buffer.Add(new OpDecorate(t_struct2, Decoration.Block)); - buffer.Add(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)); - buffer.Add(new OpDecorate(v_input_2, Decoration.NoPerspective)); - buffer.Add(new OpName(t_p_func, "main")); - buffer.Add(new OpName(t_struct, "S")); - buffer.Add(new OpMemberName(t_struct, 0, "b")); - buffer.Add(new OpMemberName(t_struct, 1, "v")); - buffer.Add(new OpMemberName(t_struct, 2, "i")); - buffer.Add(new OpFunction(t_int, id++, FunctionControlMask.None, t_func_add), out var add); - - - buffer.Add(new OpFunctionParameter(t_int, id++), out var a); - buffer.Add(new OpFunctionParameter(t_int, id++), out var b); - buffer.Add(new OpLabel(id++), out var label); - buffer.Add(new OpIAdd(t_int, id++, a, b), out var res); - buffer.Add(new OpReturnValue(res)); - buffer.Add(new OpFunctionEnd()); - buffer.Add(new OpFunction(t_void, id++, FunctionControlMask.None, t_func), out var main); - buffer.Add(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])); - buffer.Add(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)); - buffer.Add(new OpLabel(id++), out var label2); - buffer.Add(new OpFunctionCall(t_int, id++, add, [constant7, constant7]), out var resAdd); - buffer.Add(new OpReturn()); - buffer.Add(new OpFunctionEnd()); + buffer.FluentAdd(new OpTypeArray(t_float4, id++, constant3), out var t_array); + buffer.FluentAdd(new OpTypeStruct(id++, [t_uint, t_array, t_int]), out var t_struct); + buffer.FluentAdd(new OpTypeStruct(id++, [t_struct, t_uint]), out var t_struct2); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Uniform, t_struct2), out var t_p_struct2); + buffer.FluentAdd(new OpVariable(t_p_struct2, id++, StorageClass.Uniform, null), out var v_struct2); + buffer.FluentAdd(new OpConstant(t_int, id++, 1), out var constant4); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Uniform, t_uint), out var t_p_uint); + buffer.FluentAdd(new OpConstant(t_uint, id++, 0), out var constant5); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Output, t_float4), out var t_p_output); + buffer.FluentAdd(new OpVariable(t_p_output, id++, StorageClass.Output, null), out var v_output); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Input, t_float4), out var t_p_input); + buffer.FluentAdd(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input); + buffer.FluentAdd(new OpConstant(t_int, id++, 0), out var constant6); + buffer.FluentAdd(new OpConstant(t_int, id++, 2), out var constant7); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Uniform, t_float4), out var t_p_float4_unif); + buffer.FluentAdd(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_2); + buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); + buffer.FluentAdd(new OpConstant(t_int, id++, 4), out var constant8); + buffer.FluentAdd(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_3); + buffer.FluentAdd(new OpDecorate(t_array, Decoration.ArrayStride, 16)); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)); + buffer.FluentAdd(new OpDecorate(t_struct2, Decoration.Block)); + buffer.FluentAdd(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)); + buffer.FluentAdd(new OpDecorate(v_input_2, Decoration.NoPerspective)); + buffer.FluentAdd(new OpName(t_p_func, "main")); + buffer.FluentAdd(new OpName(t_struct, "S")); + buffer.FluentAdd(new OpMemberName(t_struct, 0, "b")); + buffer.FluentAdd(new OpMemberName(t_struct, 1, "v")); + buffer.FluentAdd(new OpMemberName(t_struct, 2, "i")); + buffer.FluentAdd(new OpFunction(t_int, id++, FunctionControlMask.None, t_func_add), out var add); + + + buffer.FluentAdd(new OpFunctionParameter(t_int, id++), out var a); + buffer.FluentAdd(new OpFunctionParameter(t_int, id++), out var b); + buffer.FluentAdd(new OpLabel(id++), out var label); + buffer.FluentAdd(new OpIAdd(t_int, id++, a, b), out var res); + buffer.FluentAdd(new OpReturnValue(res)); + buffer.FluentAdd(new OpFunctionEnd()); + buffer.FluentAdd(new OpFunction(t_void, id++, FunctionControlMask.None, t_func), out var main); + buffer.FluentAdd(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])); + buffer.FluentAdd(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)); + buffer.FluentAdd(new OpLabel(id++), out var label2); + buffer.FluentAdd(new OpFunctionCall(t_int, id++, add, [constant7, constant7]), out var resAdd); + buffer.FluentAdd(new OpReturn()); + buffer.FluentAdd(new OpFunctionEnd()); buffer.Sort(); var span = buffer.ToBuffer(); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index ba9a8c38bc..a78145c01b 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -22,6 +22,9 @@ public struct OpData : IDisposable, IComparable public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } public readonly Op Op => (Op)(Memory.Span[0] & 0xFFFF); + public readonly int IdResult => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : throw new Exception("No IdResult for this instruction"); + public readonly int IdResultType => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : throw new Exception("No IdResult for this instruction"); + public OpData() { Memory = MemoryOwner.Empty; @@ -31,6 +34,11 @@ public OpData(MemoryOwner memory) { Memory = memory; } + public OpData(Span memory) + { + Memory = MemoryOwner.Allocate(memory.Length); + memory.CopyTo(Memory.Span); + } public readonly void Dispose() => Memory.Dispose(); @@ -86,19 +94,48 @@ public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) public readonly ref OpData Data => ref Buffer[Index]; } -public class NewSpirvBuffer() +public sealed class NewSpirvBuffer() : IDisposable { public SpirvHeader Header { get; set; } = new("1.4", 0, 1); - List Memory { get; set; } = []; + List Instructions { get; set; } = []; + public int Count => Instructions.Count; + + internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; + + + public NewSpirvBuffer(Span span) : this() + { + if(span[0] == MagicNumber) + Header = SpirvHeader.Read(span); + var instructions = span[5..]; + + int wid = 0; + while (wid < instructions.Length) + { + Add(new(instructions.Slice(wid, instructions[wid] >> 16))); + wid += instructions[wid] >> 16; + } + } - internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Memory)[index]; - // internal OpDataIndex this[int index] => new(index, this); public void Add(OpData data) { if (InstructionInfo.GetInfo(data).GetResultIndex(out int index) && index >= Header.Bound) Header = Header with { Bound = data.Memory.Span[index] + 1 }; - Memory.Add(data); + Instructions.Add(data); + } + + public OpData Add(in T instruction) where T : struct, IMemoryInstruction + { + if (instruction.DataIndex is OpDataIndex odi) + { + if (odi.Buffer == this) + return odi.Data; + else + Instructions.Add(new(instruction.InstructionMemory)); + } + else Instructions.Add(new(instruction.InstructionMemory)); + return Instructions[^1]; } public void AddRef(ref T instruction) where T : struct, IMemoryInstruction @@ -108,30 +145,30 @@ public void AddRef(ref T instruction) where T : struct, IMemoryInstruction if (odi.Buffer == this) return; else - Memory.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); } - else Memory.Add(new(instruction.InstructionMemory)); - instruction.DataIndex = new(Memory.Count - 1, this); + else Instructions.Add(new(instruction.InstructionMemory)); + instruction.DataIndex = new(Instructions.Count - 1, this); if (instruction.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; } - public NewSpirvBuffer Add(in T instruction) where T : struct, IMemoryInstruction + public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction { if (instruction.DataIndex is OpDataIndex odi) { if (odi.Buffer == this) return this; else - Memory.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); } - else Memory.Add(new(instruction.InstructionMemory)); + else Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) Header = Header with { Bound = tmp.InstructionMemory.Span[index] + 1 }; return this; } - public NewSpirvBuffer Add(in T instruction, out T result) where T : struct, IMemoryInstruction + public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction { result = instruction; if (instruction.DataIndex is OpDataIndex odi) @@ -139,9 +176,9 @@ public NewSpirvBuffer Add(in T instruction, out T result) where T : struct, I if (odi.Buffer == this) return this; else - Memory.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); } - else Memory.Add(new(instruction.InstructionMemory)); + else Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; @@ -149,7 +186,16 @@ public NewSpirvBuffer Add(in T instruction, out T result) where T : struct, I } public void Insert(int index, OpData data) - => Memory.Insert(index, data); + => Instructions.Insert(index, data); + public T Insert(int index, in T data) + where T : struct, IMemoryInstruction + { + Instructions.Insert(index, new(data.InstructionMemory)); + var tmp = data; + if (tmp.GetInfo().GetResultIndex(out int rid) && rid >= Header.Bound) + Header = Header with { Bound = tmp.InstructionMemory.Span[rid] + 1 }; + return data; + } /// /// Removes an instruction at a certain index. @@ -159,10 +205,10 @@ public void Insert(int index, OpData data) /// true if the instruction was successfully removed public bool RemoveAt(int index) { - if (index < 0 || index >= Memory.Count) + if (index < 0 || index >= Instructions.Count) return false; - Memory[index].Dispose(); - Memory.RemoveAt(index); + Instructions[index].Dispose(); + Instructions.RemoveAt(index); return true; } @@ -171,7 +217,7 @@ public bool RemoveAt(int index) public ref struct Enumerator(NewSpirvBuffer buffer) { readonly NewSpirvBuffer buffer = buffer; - private readonly List list = buffer.Memory; + private readonly List list = buffer.Instructions; private int index = -1; public readonly OpDataIndex Current => new(index, buffer); @@ -187,15 +233,15 @@ public bool MoveNext() } } - public void Sort() => Memory.Sort(static (a, b) => a.CompareTo(b)); + public void Sort() => Instructions.Sort(static (a, b) => a.CompareTo(b)); public SpanOwner ToBuffer() { - var result = SpanOwner.Allocate(5 + Memory.Sum(i => i.Memory.Length)); + var result = SpanOwner.Allocate(5 + Instructions.Sum(i => i.Memory.Length)); var span = result.Span; Header.WriteTo(span); var offset = 5; - foreach (var instruction in Memory) + foreach (var instruction in Instructions) { instruction.Memory.Span.CopyTo(span[offset..]); offset += instruction.Memory.Length; @@ -208,7 +254,6 @@ public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) foreach (var op in this) { var info = InstructionInfo.GetInfo(op.Op); - var mem = op.Data.Memory; if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == typeId) { instruction = op; @@ -218,6 +263,13 @@ public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) instruction = default; return false; } + + public void Dispose() + { + foreach (var instruction in Instructions) + instruction.Dispose(); + Instructions.Clear(); + } } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 6ca6a89a95..bea995f19a 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -12,11 +12,7 @@ namespace Stride.Shaders.Spirv.Core.Buffers; /// public class SpirvBuffer : IMutSpirvBuffer { - private SpirvHeader header = new() - { - VersionNumber = new(1, 3), - MagicNumber = Specification.MagicNumber, - }; + private SpirvHeader header = new("1.3", 0, 0); private ArrayPool pool = ArrayPool.Shared; public List Instructions { get; } = []; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 16e9eb03b7..99191fdb7e 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -7,7 +7,6 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// public ref struct OpDataEnumerator { - static readonly OperandKind[] pairs = [.. Enum.GetValues().Where(x => x.ToString().StartsWith("Pair"))]; readonly Span instruction; readonly Span Operands => instruction[1..]; readonly Op OpCode => (Op)(instruction[0] & 0xFFFF); @@ -164,239 +163,4 @@ public SpvOperand ParseCurrent() }; } -} - - - -// public ref struct OpDataEnumerator -// { -// static readonly OperandKind[] pairs = [.. Enum.GetValues().Where(x => x.ToString().StartsWith("Pair"))]; -// readonly Span instruction; -// readonly Span Operands => instruction[1..]; -// readonly Op OpCode => (Op)(instruction[0] & 0xFFFF); -// readonly LogicalOperandArray logicalOperands; -// int wid; -// int oid; - -// public OpDataEnumerator(Span instruction) -// { -// this.instruction = instruction; -// logicalOperands = InstructionInfo.GetInfo(OpCode); -// oid = -1; -// wid = 0; -// } - -// public SpvOperand Current => ParseCurrent(); - -// public bool MoveNext() -// { -// if (oid < 0) -// { -// oid = 0; -// if (logicalOperands[0].Kind == OperandKind.None) -// return false; -// return true; -// } -// else -// { - -// var logOp = logicalOperands[oid]; - -// if (OpCode == Op.OpDecorate) -// { -// if (oid == 0) -// { -// wid += 1; -// oid += 1; -// return true; -// } -// else if (oid > 0) -// { -// var builtin = (Decoration)Operands[1]; -// bool has2Extra = builtin == Decoration.LinkageAttributes; -// bool has1Extra = -// builtin == Decoration.BuiltIn -// || builtin == Decoration.Location -// || builtin == Decoration.SpecId -// || builtin == Decoration.ArrayStride -// || builtin == Decoration.MatrixStride -// || builtin == Decoration.UniformId -// || builtin == Decoration.Stream -// || builtin == Decoration.Component -// || builtin == Decoration.Index -// || builtin == Decoration.Binding -// || builtin == Decoration.DescriptorSet -// || builtin == Decoration.Offset -// || builtin == Decoration.XfbBuffer -// || builtin == Decoration.XfbStride -// || builtin == Decoration.FuncParamAttr -// || builtin == Decoration.FPRoundingMode -// || builtin == Decoration.FPFastMathMode -// || builtin == Decoration.LinkageAttributes -// || builtin == Decoration.InputAttachmentIndex -// || builtin == Decoration.Alignment -// || builtin == Decoration.MaxByteOffset -// || builtin == Decoration.AlignmentId -// || builtin == Decoration.MaxByteOffsetId -// || builtin == Decoration.SecondaryViewportRelativeNV -// || builtin == Decoration.CounterBuffer; -// if (has1Extra && oid == 1 && !has2Extra) -// { -// wid += 1; -// oid += 1; -// } -// else if (has2Extra) -// { -// throw new NotImplementedException(); -// } -// else -// { -// return false; -// } - -// } - -// oid += 1; -// if (oid > 2) -// return false; -// else -// return wid < Operands.Length; -// } -// else if (logOp.Quantifier == OperandQuantifier.One) -// { -// if (logOp.Kind == OperandKind.LiteralString) -// { -// while (!Operands[wid].HasEndString()) -// wid += 1; -// wid += 1; -// } -// else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) -// wid += 2; -// else -// wid += 1; -// oid += 1; - -// } -// else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) -// { -// if ( -// pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) -// && wid < Operands.Length - 1 -// ) -// { -// wid += 2; -// } -// else if ( -// logOp.Kind == OperandKind.LiteralString -// && wid < Operands.Length -// ) -// { -// while (!Operands[wid].HasEndString()) -// wid += 1; -// wid += 1; -// } -// else if (wid < Operands.Length) -// wid += 1; -// oid += 1; - -// } -// else if (logOp.Quantifier == OperandQuantifier.ZeroOrMore) -// { -// if (logOp.Kind == OperandKind.LiteralString) -// throw new NotImplementedException("params of strings is not yet implemented"); -// else if ( -// pairs.Contains(logOp.Kind ?? throw new Exception()) -// && wid < Operands.Length - 2 -// ) -// wid += 2; -// else if (wid < Operands.Length - 1) -// wid += 1; -// else -// oid += 1; - -// } -// if (oid >= logicalOperands.Count) -// return false; -// return wid < Operands.Length; -// } - -// } - -// public SpvOperand ParseCurrent() -// { -// var logOp = logicalOperands[oid]; -// if (OpCode == Op.OpDecorate) -// { -// SpvOperand result = new(); -// if (oid == 0) -// result = new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)); -// else if (oid == 1) -// result = new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)); -// else if (oid == 2) -// { -// result = result with -// { -// Kind = (Decoration)Operands[1] switch -// { -// Decoration.BuiltIn => OperandKind.BuiltIn, -// Decoration.Location => OperandKind.LiteralInteger, -// Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, -// Decoration.ArrayStride => OperandKind.LiteralInteger, -// Decoration.MatrixStride => OperandKind.LiteralInteger, -// Decoration.UniformId => OperandKind.IdScope, -// Decoration.Stream => OperandKind.LiteralInteger, -// Decoration.Component => OperandKind.LiteralInteger, -// Decoration.Index => OperandKind.LiteralInteger, -// Decoration.Binding => OperandKind.LiteralInteger, -// Decoration.DescriptorSet => OperandKind.LiteralInteger, -// Decoration.Offset => OperandKind.LiteralInteger, -// Decoration.XfbBuffer => OperandKind.LiteralInteger, -// Decoration.XfbStride => OperandKind.LiteralInteger, -// Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, -// Decoration.FPRoundingMode => OperandKind.FPRoundingMode, -// Decoration.FPFastMathMode => OperandKind.FPFastMathMode, -// Decoration.LinkageAttributes => OperandKind.LiteralString, -// Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, -// Decoration.Alignment => OperandKind.LiteralInteger, -// Decoration.MaxByteOffset => OperandKind.LiteralInteger, -// Decoration.AlignmentId => OperandKind.IdRef, -// Decoration.MaxByteOffsetId => OperandKind.IdRef, -// Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, -// Decoration.CounterBuffer => OperandKind.IdRef, -// _ => OperandKind.None -// } -// }; -// } -// return result; - -// } -// else if (logOp.Quantifier != OperandQuantifier.ZeroOrMore) -// { -// if (logOp.Kind == OperandKind.LiteralString) -// { -// var length = 0; -// while (!Operands[wid + length].HasEndString()) -// length += 1; -// length += 1; -// var result = new SpvOperand(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, length)); - -// return result; -// } -// else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) -// { -// var result = new SpvOperand(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); -// return result; -// } -// else -// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); -// } -// else -// { -// if (pairs.Contains(logOp.Kind ?? OperandKind.None)) -// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); -// else -// return new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); -// } -// } - -// } \ No newline at end of file +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index c9dcf2c92b..ef5dbfb0dd 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -5,22 +5,14 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// /// An instruction operands enumerator, useful for parsing instructions /// -public ref struct OperandEnumerator +public ref struct OperandEnumerator(Instruction instruction) { - static OperandKind[] pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); - Instruction instruction; - Span operands => instruction.Operands; - readonly LogicalOperandArray logicalOperands; - int wid; - int oid; - - public OperandEnumerator(Instruction instruction) - { - this.instruction = instruction; - logicalOperands = InstructionInfo.GetInfo(instruction); - oid = -1; - wid = 0; - } + static OperandKind[] Pairs { get; } = Enum.GetValues().Where(x => x.ToString().StartsWith("Pair")).ToArray(); + Instruction instruction = instruction; + readonly Span Operands => instruction.Operands; + readonly LogicalOperandArray logicalOperands = InstructionInfo.GetInfo(instruction); + int wid = 0; + int oid = -1; public SpvOperand Current => ParseCurrent(); @@ -43,11 +35,11 @@ public bool MoveNext() { if (logOp.Kind == OperandKind.LiteralString) { - while (!operands[wid].HasEndString()) + while (!Operands[wid].HasEndString()) wid += 1; wid += 1; } - else if (pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) + else if (Pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent"))) wid += 2; else wid += 1; @@ -57,22 +49,22 @@ public bool MoveNext() else if (logOp.Quantifier == OperandQuantifier.ZeroOrOne) { if ( - pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) - && wid < operands.Length - 1 + Pairs.Contains(logOp.Kind ?? throw new Exception("kind is inexistent")) + && wid < Operands.Length - 1 ) { wid += 2; } else if ( logOp.Kind == OperandKind.LiteralString - && wid < operands.Length + && wid < Operands.Length ) { - while (!operands[wid].HasEndString()) + while (!Operands[wid].HasEndString()) wid += 1; wid += 1; } - else if (wid < operands.Length) + else if (wid < Operands.Length) wid += 1; oid += 1; @@ -82,17 +74,17 @@ public bool MoveNext() if (logOp.Kind == OperandKind.LiteralString) throw new NotImplementedException("params of strings is not yet implemented"); else if ( - pairs.Contains(logOp.Kind ?? throw new Exception()) - && wid < operands.Length - 2 + Pairs.Contains(logOp.Kind ?? throw new Exception()) + && wid < Operands.Length - 2 ) wid += 2; - else if (wid < operands.Length - 1) + else if (wid < Operands.Length - 1) wid += 1; else oid += 1; } - return wid < operands.Length; + return wid < Operands.Length; } } @@ -151,27 +143,27 @@ public SpvOperand ParseCurrent() if (logOp.Kind == OperandKind.LiteralString) { var length = 0; - while (!operands[wid + length].HasEndString()) + while (!Operands[wid + length].HasEndString()) length += 1; length += 1; - var result = new SpvOperand(OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, length)); + var result = new SpvOperand(OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, length)); return result; } - else if (pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) + else if (Pairs.Contains(logOp.Kind ?? throw new NotImplementedException(""))) { - var result = new SpvOperand(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + var result = new SpvOperand(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); return result; } else - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 1)); + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)); } else { - if (pairs.Contains(logOp.Kind ?? OperandKind.None)) - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands.Slice(wid, 2)); + if (Pairs.Contains(logOp.Kind ?? OperandKind.None)) + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)); else - return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, operands[wid..]); + return new(logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands[wid..]); } } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 48ce306aad..5062068be1 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -1,11 +1,4 @@ -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs index b81c0e60d4..c6b374825e 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs @@ -21,6 +21,6 @@ public RefHeader(Span words) Words = words; } - public bool IsValidMagic => MagicNumber == Stride.Shaders.Spirv.Specification.MagicNumber; + public bool IsValidMagic => MagicNumber == Specification.MagicNumber; } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index f9bb6f3acd..ddf137b6d6 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -7,49 +7,36 @@ namespace Stride.Shaders.Spirv.Core.Parsing; /// /// Simple Spirv parser for external buffers /// -public ref struct SpirvReader +public readonly ref struct SpirvReader(Span words) { - public static void ParseToList(byte[] byteCode, List instructions) - { - - var span = MemoryMarshal.Cast(byteCode.AsSpan()); - var data = new SpirvBuffer(span); - foreach (var instruction in data.Instructions) - instructions.Add(instruction); - } - - + public Span Words { get; init; } = words; + public SpirvReader(Span bytes) : this(MemoryMarshal.Cast(bytes)) { } + public readonly Enumerator GetEnumerator() => new(Words); - SpirvBuffer buffer; - public int Count => GetInstructionCount(); - public bool HasHeader { get; init; } - - public SpirvReader(byte[] byteCode, bool hasHeader = false) - { - buffer = new(MemoryMarshal.Cast(byteCode.AsSpan())); - HasHeader = hasHeader; - } - public SpirvReader(MemoryOwner slice, bool hasHeader = false) + public ref struct Enumerator(Span words) { - buffer = new(slice.Span); - HasHeader = hasHeader; + int wid = 0; + readonly Span words = words; + + public readonly Span Current => words[wid..(wid + (words[wid] >> 16))]; + + public bool MoveNext() + { + if(wid == 0 && words[0] == Specification.MagicNumber) + { + wid = 5; + return true; + } + else if (wid >= words.Length) + return false; + else + { + wid += words[wid] >> 16; + if (wid >= words.Length) + return false; + return true; + } + } } - public SpirvReader(Memory slice, bool hasHeader = false) - { - buffer = new(slice.Span[(hasHeader ? 5 : 0)..]); - } - public SpirvReader(Memory slice) - { - buffer = new(slice.Span); - //data = slice; - } - public SpirvReader(SpirvBuffer span) - { - buffer = span; - //data = slice; - } - - - public readonly int GetInstructionCount() => buffer.Instructions.Count; } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs deleted file mode 100644 index bf8aa77a0f..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvWriter.cs +++ /dev/null @@ -1,47 +0,0 @@ -using CommunityToolkit.HighPerformance.Buffers; - -namespace Stride.Shaders.Spirv.Core.Parsing; - - -public ref struct SpirvWriter -{ - public int Length { get; private set;} - MemoryOwner buffer; - - public Span SpirvCode => buffer.Span[..(Length-1)]; - - public SpirvWriter(int initialSize = 32) - { - buffer = MemoryOwner.Allocate(initialSize, AllocationMode.Clear); - Length = 0; - } - - void Expand(int size) - { - var futureLength = Length + size; - var realLength = buffer.Length; - if(Length > buffer.Length) - { - buffer.Dispose(); - buffer = MemoryOwner.Allocate(realLength*2, AllocationMode.Clear); - } - } - - public void Write(int word) - { - Expand(1); - buffer.Span[Length] = word; - Length += 1; - } - public void Write(scoped Span words) - { - Expand(words.Length); - words.CopyTo(buffer.Span[Length..]); - Length += Length; - } - - public void Dispose() - { - buffer.Dispose(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 6c59979728..99c4b2fffc 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Tools; @@ -14,15 +15,19 @@ public static partial class Spv { public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) { - // this.buffer = buffer; - // ComputeIdOffset(); - // Assembly code generation logic goes here var writer = new DisWriter(buffer, useNames, writeToConsole); writer.Disassemble(); - return ""; + writer.ToString(); + return writer.ToString(); } - + public static string Dis(SpirvReader reader, bool useNames = true, bool writeToConsole = true) + { + using var buffer = new NewSpirvBuffer(reader.Words); + var writer = new DisWriter(buffer, useNames, writeToConsole); + writer.Disassemble(); + return writer.ToString(); + } struct DisWriter(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) { @@ -85,15 +90,6 @@ readonly DisWriter AppendLiteralNumber(T value) return this; } - readonly DisWriter AppendLiteralNumber(LiteralValue value, bool dispose = true) - where T : struct, INumber - { - Append(value.Value, ConsoleColor.Red).Append(' '); - if (dispose) - value.Dispose(); - return this; - } - readonly DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) { Append('"', ConsoleColor.Green).Append(value.Value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); @@ -107,35 +103,8 @@ readonly DisWriter AppendLiteralString(string value) return this; } - readonly DisWriter AppendLiteralNumbers(LiteralArray value, bool dispose = true) - where T : struct, INumber - { - T tmp = default; - var size = tmp switch - { - byte or sbyte or short or ushort or int or uint or float => 1, - long or ulong or double => 2, - _ => throw new NotImplementedException("Cannot create LiteralValue from the provided words") - }; - for (int i = 0; i < value.WordCount; i += size) - { - if (size == 1) - { - using var lit = LiteralValue.From([value.Words[i]]); - Append(lit.Value, ConsoleColor.Red); - } - else - { - using var v = LiteralValue.From([(value.Words[i] << 32 | value.Words[i + 1])]); - Append(v.Value, ConsoleColor.Red); - } - } - if (dispose) - value.Dispose(); - return this; - } - DisWriter AppendContextDependentNumber(SpvOperand operand, OpData data, NewSpirvBuffer buffer) + readonly DisWriter AppendContextDependentNumber(SpvOperand operand, OpData data, NewSpirvBuffer buffer) { int typeId = data.Op switch { @@ -215,7 +184,7 @@ public void Disassemble() } } - public void DisHeader() + public readonly void DisHeader() { var header = data.Buffer.Header; AppendLine($"; SPIR-V"); @@ -226,7 +195,7 @@ public void DisHeader() AppendLine(""); } - public void DisInstruction(in OpDataIndex instruction, in DisWriter writer) + public readonly void DisInstruction(in OpDataIndex instruction, in DisWriter writer) { if (instruction.Op == Op.OpName) { @@ -329,7 +298,7 @@ or OperandKind.LiteralExtInstInteger - public override string ToString() => builder.ToString(); + public readonly override string ToString() => builder.ToString(); } @@ -375,8 +344,8 @@ public DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) { Buffer = buffer; NameTable = []; - this.UseNames = useNames; - this.WriteToConsole = writeToConsole; + UseNames = useNames; + WriteToConsole = writeToConsole; ComputeIdOffset(); } @@ -408,12 +377,6 @@ void ComputeIdOffset() var memberInst = (OpMemberName)i; maxName = maxName > memberInst.Name.Length ? maxName : memberInst.Name.Length; } - // maxName = i.Op switch - // { - // Op.OpName => maxName > ((OpName)i).Name.Length ? maxName : ((OpName)i).Name.Length, - // Op.OpMemberName => maxName > ((OpMemberName)i).Name.Length ? maxName : ((OpMemberName)i).Name.Length, - // _ => maxName - // }; } IdOffset += maxName; } From 5f76f23b6b4896511f5629028cf8d5f98c6e17ce Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 14 Sep 2025 16:52:52 +0200 Subject: [PATCH 0445/1182] rewriting changed code --- .../Parsing/SDSL/AST/Expression.cs | 84 ++-- .../Parsing/SDSL/AST/Literals.cs | 93 ++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 374 +++++++++--------- .../Parsing/SDSL/AST/ShaderElements.cs | 5 +- .../Spirv/Building/BasicBlocks.cs | Bin 4490 -> 5182 bytes src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- .../Spirv/Building/CompilerUnit.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 278 ++++++------- 8 files changed, 402 insertions(+), 438 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 231f80a8bc..7a9de3e958 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -25,12 +25,10 @@ public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, Compiler var type = compiler.Context.ReverseTypes[result.TypeId]; if (type is PointerType pointerType) { - #warning replace - // type = pointerType.BaseType; - // var inst = compiler.Builder.Buffer.InsertOpLoad(compiler.Builder.Position++, compiler.Context.Bound++, compiler.Context.Types[type], result.Id, null); - // result = new(inst.ResultId.Value, inst.ResultType.Value); + type = pointerType.BaseType; + var inst = compiler.Builder.Buffer.Insert(compiler.Builder.Position++, new OpLoad(compiler.Context.Types[type], compiler.Context.Bound++, result.Id, null)); + result = new(inst.ResultId, inst.ResultType); } - return result; } } @@ -42,18 +40,16 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - // var functionType = (FunctionType)Name.ResolveType(table); - // Type = functionType.ReturnType; - - // var (builder, context, module) = compiler; - // var list = parameters.Values; - // Span compiledParams = stackalloc IdRef[list.Count]; - // var tmp = 0; - // foreach(var p in list) - // compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; - // return builder.CallFunction(context, Name, compiledParams); - #warning replace - throw new NotImplementedException(); + var functionType = (FunctionType)Name.ResolveType(table); + Type = functionType.ReturnType; + + var (builder, context, module) = compiler; + var list = parameters.Values; + Span compiledParams = stackalloc int[list.Count]; + var tmp = 0; + foreach (var p in list) + compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; + return builder.CallFunction(context, Name, [.. compiledParams]); } public override string ToString() { @@ -147,39 +143,37 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = Source.Type; } - // Span indexes = stackalloc IdRef[Accessors.Count]; - // for (var i = firstIndex; i < Accessors.Count; i++) - // { - // var accessor = Accessors[i]; - // if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) - // { - // var index = s.TryGetFieldIndex(field); - // if (index == -1) - // throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); - // //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - // var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - // indexLiteral.Compile(table, shader, compiler); - // indexes[i] = context.CreateConstant(indexLiteral).Id; - // } - // else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); - - // currentValueType = accessor.Type; - // } - - // if (currentValueType is not PointerType) - // throw new InvalidOperationException(); - - // Type = currentValueType; + Span indexes = stackalloc int[Accessors.Count]; + for (var i = firstIndex; i < Accessors.Count; i++) + { + var accessor = Accessors[i]; + if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) + { + var index = s.TryGetFieldIndex(field); + if (index == -1) + throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.Compile(table, shader, compiler); + indexes[i] = context.CreateConstant(indexLiteral).Id; + } + else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + + currentValueType = accessor.Type; + } + + if (currentValueType is not PointerType) + throw new InvalidOperationException(); + + Type = currentValueType; // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) if (firstIndex == Accessors.Count) return source; var resultType = context.GetOrRegister(Type); - // var result = builder.Buffer.InsertOpAccessChain(builder.Position++, variable, resultType, source.Id, indexes); - // return new(result, resultType); - #warning replace - throw new NotImplementedException(); + var result = builder.Buffer.Insert(builder.Position++, new OpAccessChain(variable, resultType, source.Id, [.. indexes])); + return new(result.ResultId, resultType); } public override string ToString() @@ -243,7 +237,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); if (Left.ValueType != Right.ValueType) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - throw new NotImplementedException(); + throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index e1d1f5c9cc..37fc7969da 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -70,17 +70,14 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil _ => throw new NotImplementedException("Unsupported integer suffix") }; -#warning replace - throw new NotImplementedException(); - - // var i = (Type, Suffix) switch - // { - // (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), LongValue), - // (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), IntValue), - // _ => throw new NotImplementedException("") - // }; - // return new SpirvValue(i, i.ResultType!.Value, null); + var i = (Type, Suffix) switch + { + (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), + (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), + _ => throw new NotImplementedException("") + }; + return new SpirvValue(i.IdResult, i.IdResultType, null); } } @@ -98,15 +95,13 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil 64 => ScalarType.From("double"), _ => throw new NotImplementedException("Unsupported float") }; -#warning replace - throw new NotImplementedException(); - // var i = (Type, Suffix) switch - // { - // (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), DoubleValue), - // (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.AddOpConstant(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type), (float)DoubleValue), - // _ => throw new NotImplementedException("") - // }; - // return new SpirvValue(i, i.ResultType!.Value, null); + var i = (Type, Suffix) switch + { + (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, DoubleValue)), + (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, (float)DoubleValue)), + _ => throw new NotImplementedException("") + }; + return new SpirvValue(i.IdResult, i.IdResultType, null); } } @@ -123,14 +118,12 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { -#warning replace - // var i = Value switch - // { - // true => compiler.Context.Buffer.AddOpConstantTrue(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)), - // false => compiler.Context.Buffer.AddOpConstantFalse(compiler.Context.Bound++, compiler.Context.GetOrRegister(Type)) - // }; - // return new SpirvValue(i, i.ResultType!.Value, null); - throw new NotImplementedException(); + var i = Value switch + { + true => compiler.Context.Buffer.Add(new OpConstantTrue(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)), + false => compiler.Context.Buffer.Add(new OpConstantFalse(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)) + }; + return new SpirvValue(i.IdResult, i.IdResultType, null); } } @@ -150,17 +143,15 @@ public bool IsConstant() public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - #warning replace - throw new NotImplementedException(); - // var (builder, context, module) = compiler; - // Span values = stackalloc IdRef[Values.Count]; - // int tmp = 0; - // foreach (var v in Values) - // values[tmp++] = v.Compile(table, shader, compiler).Id; + var (builder, context, module) = compiler; + Span values = stackalloc int[Values.Count]; + int tmp = 0; + foreach (var v in Values) + values[tmp++] = v.Compile(table, shader, compiler).Id; - // Type = GenerateType(table); + Type = GenerateType(table); - // return builder.CompositeConstruct(context, this, values); + return builder.CompositeConstruct(context, this, [.. values]); } } public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) @@ -260,25 +251,23 @@ public SymbolType ResolveType(SymbolTable table) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { -#warning replace - // var symbol = ResolveSymbol(table); - // Type = symbol.Type; + var symbol = ResolveSymbol(table); + Type = symbol.Type; - // var (builder, context, _) = compiler; - // var resultType = context.GetOrRegister(Type); - // var result = new SpirvValue(symbol.IdRef, resultType, Name); + var (builder, context, _) = compiler; + var resultType = context.GetOrRegister(Type); + var result = new SpirvValue(symbol.IdRef, resultType, Name); - // if (symbol.AccessChain is int accessChainIndex) - // { - // Span indexes = stackalloc IdRef[1]; - // var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); - // indexLiteral.Compile(table, shader, compiler); - // indexes[0] = context.CreateConstant(indexLiteral).Id; - // result.Id = compiler.Builder.Buffer.InsertOpAccessChain(compiler.Builder.Position++, compiler.Context.Bound++, resultType, symbol.IdRef, indexes).ResultId.Value; - // } + if (symbol.AccessChain is int accessChainIndex) + { + var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); + indexLiteral.Compile(table, shader, compiler); + var index = context.CreateConstant(indexLiteral).Id; + result.Id = compiler.Builder.Buffer.Insert(compiler.Builder.Position++, new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); + } - // return result; - throw new NotImplementedException(); + return result; + // throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 3c2fdc5b3d..adeaa10c40 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -21,80 +21,80 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public ShaderParameterDeclarations? Generics { get; set; } public List Mixins { get; set; } = []; - public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer, out Dictionary names, out Dictionary types) + public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buffer, out Dictionary names, out Dictionary types) { var memberNames = new Dictionary<(int, int), string>(); names = []; types = []; - #warning uncomment - // foreach (var instruction in buffer.Instructions) - // { - // if (instruction.OpCode == Op.OpName) - // { - // var nameInstruction = instruction.UnsafeAs(); - // names.Add(nameInstruction.Target, nameInstruction.Name.Value); - // } - // else if (instruction.OpCode == Op.OpMemberName) - // { - // var nameInstruction = instruction.UnsafeAs(); - // memberNames.Add((nameInstruction.Type, (int)nameInstruction.Member.Words), nameInstruction.Name.Value); - // } - // else if (instruction.OpCode == Op.OpTypeFloat) - // { - // var floatInstruction = instruction.UnsafeAs(); - // //if (floatInstruction.FloatingPointEncoding != 0) - // // throw new InvalidOperationException(); - - // types.Add(floatInstruction.ResultId, floatInstruction.Width.Words switch - // { - // 16 => ScalarType.From("half"), - // 32 => ScalarType.From("float"), - // 64 => ScalarType.From("double"), - // }); - // } - // else if (instruction.OpCode == Op.OpTypePointer) - // { - // var pointerInstruction = instruction.UnsafeAs(); - // var innerType = types[pointerInstruction.Type]; - // types.Add(instruction.ResultId!.Value, new PointerType(innerType, pointerInstruction.Storageclass)); - // } - // else if (instruction.OpCode == Op.OpTypeVoid) - // { - // types.Add(instruction.ResultId!.Value, ScalarType.From("void")); - // } - // else if (instruction.OpCode == Op.OpTypeVector) - // { - // var vectorInstruction = instruction.UnsafeAs(); - // var innerType = (ScalarType)types[vectorInstruction.ComponentType]; - // types.Add(instruction.ResultId!.Value, new VectorType(innerType, (int)vectorInstruction.ComponentCount.Words)); - // } - // else if (instruction.OpCode == Op.OpTypeStruct) - // { - // var typeStructInstruction = instruction.UnsafeAs(); - // var structName = names[instruction.ResultId!.Value]; - // var fieldsData = instruction.Memory.Span[2..]; - // var fields = new List<(string Name, SymbolType Type)>(); - // for (var index = 0; index < fieldsData.Length; index++) - // { - // var fieldData = fieldsData[index]; - // var type = types[fieldData]; - // var name = memberNames[(typeStructInstruction.ResultId.Value, index)]; - // fields.Add((name, type)); - // } - // types.Add(instruction.ResultId!.Value, new StructType(structName, fields)); - // } - // else if (instruction.OpCode == Op.OpTypeFunction) - // { - // var typeFunctionInstruction = instruction.UnsafeAs(); - // var returnType = types[typeFunctionInstruction.ReturnType]; - // var parameterTypes = new List(); - // foreach (var operand in instruction.Operands[2..]) - // { - // parameterTypes.Add(types[operand]); - // } - // types.Add(instruction.ResultId!.Value, new FunctionType(returnType, parameterTypes)); - // } - // } + foreach (var instruction in buffer) + { + if (instruction.Op == Op.OpName) + { + OpName nameInstruction = instruction; + names.Add(nameInstruction.Target, nameInstruction.Name); + } + else if (instruction.Op == Op.OpMemberName) + { + OpMemberName nameInstruction = instruction; + memberNames.Add((nameInstruction.Type, nameInstruction.Member), nameInstruction.Name); + } + else if (instruction.Op == Op.OpTypeFloat) + { + OpTypeFloat floatInstruction = instruction; + //if (floatInstruction.FloatingPointEncoding != 0) + // throw new InvalidOperationException(); + + types.Add(floatInstruction.ResultId, floatInstruction.Width switch + { + 16 => ScalarType.From("half"), + 32 => ScalarType.From("float"), + 64 => ScalarType.From("double"), + _ => throw new InvalidOperationException(), + }); + } + else if (instruction.Op == Op.OpTypePointer) + { + OpTypePointer pointerInstruction = instruction; + var innerType = types[pointerInstruction.Type]; + types.Add(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); + } + else if (instruction.Op == Op.OpTypeVoid) + { + types.Add(((OpTypeVoid)instruction).ResultId, ScalarType.From("void")); + } + else if (instruction.Op == Op.OpTypeVector) + { + OpTypeVector vectorInstruction = instruction; + var innerType = (ScalarType)types[vectorInstruction.ComponentType]; + types.Add(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); + } + else if (instruction.Op == Op.OpTypeStruct) + { + OpTypeStruct typeStructInstruction = instruction; + var structName = names[typeStructInstruction.ResultId]; + var fieldsData = typeStructInstruction.Values; + var fields = new List<(string Name, SymbolType Type)>(); + for (var index = 0; index < fieldsData.WordCount; index++) + { + var fieldData = fieldsData.Words[index]; + var type = types[fieldData]; + var name = memberNames[(typeStructInstruction.ResultId, index)]; + fields.Add((name, type)); + } + types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); + } + else if (instruction.Op == Op.OpTypeFunction) + { + OpTypeFunction typeFunctionInstruction = instruction; + var returnType = types[typeFunctionInstruction.ReturnType]; + var parameterTypes = new List(); + foreach (var operand in typeFunctionInstruction.Values) + { + parameterTypes.Add(types[operand]); + } + types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); + } + } return types; } @@ -102,37 +102,36 @@ public static Dictionary ProcessNameAndTypes(SpirvBuffer buffer private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) { externalShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); - if(bytecode is null) + if (bytecode is null) throw new InvalidOperationException($"Could not load shader '{mixin.Name}'"); using var mem = MemoryOwner.Allocate(bytecode.Length / 4); MemoryMarshal.Cast(bytecode).CopyTo(mem.Span); - var buffer = new SpirvBuffer(mem.Span); + var buffer = new NewSpirvBuffer(mem.Span); ProcessNameAndTypes(buffer, out var names, out var types); var symbols = new List(); - foreach (var instruction in buffer.Instructions) + foreach (var instruction in buffer) { - #warning uncomment - // if (instruction.OpCode == Op.OpVariable) - // { - // var variableInstruction = instruction.UnsafeAs(); - // var variableName = names[variableInstruction.ResultId.Value]; - // var variableType = types[variableInstruction.ResultType]; - - // var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - // symbols.Add(new(sid, variableType, variableInstruction.ResultId)); - // } - - // if (instruction.OpCode == Op.OpFunction) - // { - // var functionInstruction = instruction.UnsafeAs(); - // var functionName = names[functionInstruction.ResultId.Value]; - // var functionType = types[functionInstruction.FunctionType]; - - // var sid = new SymbolID(functionName, SymbolKind.Method); - // symbols.Add(new(sid, functionType, functionInstruction.ResultId)); - // } + if (instruction.Op == Op.OpVariable) + { + OpVariable variableInstruction = instruction; + var variableName = names[variableInstruction.ResultId]; + var variableType = types[variableInstruction.ResultType]; + + var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); + symbols.Add(new(sid, variableType, variableInstruction.ResultId)); + } + + if (instruction.Op == Op.OpFunction) + { + OpFunction functionInstruction = instruction; + var functionName = names[functionInstruction.ResultId]; + var functionType = types[functionInstruction.FunctionType]; + + var sid = new SymbolID(functionName, SymbolKind.Method); + symbols.Add(new(sid, functionType, functionInstruction.ResultId)); + } } var shaderType = new ShaderSymbol(mixin.Name, symbols); @@ -147,101 +146,100 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp public void Compile(CompilerUnit compiler, SymbolTable table) { - #warning replace - // table.Push(); - // foreach (var mixin in Mixins) - // { - // var shaderType = LoadShader(table.ShaderLoader, mixin); - - // RegisterShaderType(table, shaderType); - // } - - // var symbols = new List(); - // foreach (var member in Elements) - // { - // if (member is ShaderMethod func) - // { - // var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); - // foreach (var arg in func.Parameters) - // { - // var argSym = arg.TypeName.ResolveType(table); - // table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - // arg.Type = argSym; - // ftype.ParameterTypes.Add(arg.Type); - // } - // func.Type = ftype; - - // table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); - // } - // else if (member is ShaderMember svar) - // { - // svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); - // table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); - // } - // else if (member is CBuffer cb) - // { - // foreach (var cbMember in cb.Members) - // { - // cbMember.Type = cbMember.TypeName.ResolveType(table); - // //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); - // //symbols.Add(symbol); - // } - // } - // } - - // var currentShader = new ShaderSymbol(Name, symbols); - // RegisterShaderType(table, currentShader); - - // table.CurrentShader = currentShader; - // foreach (var member in Elements) - // { - // member.ProcessSymbol(table); - // } - - // var (builder, context, _) = compiler; - // context.PutShaderName(Name); - - // foreach (var mixin in Mixins) - // { - // // Import types and variables/functions - // var shader = context.Buffer.AddOpSDSLImportShader(context.Bound++, new(mixin.Name)); - - // var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; - - // foreach (var c in shaderType.Components) - // { - // if (c.Id.Kind == SymbolKind.Variable) - // { - // var variableTypeId = context.GetOrRegister(c.Type); - // var variable = context.Buffer.AddOpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader); - // context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); - // table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId.Value }); - // } - // else if (c.Id.Kind == SymbolKind.Method) - // { - // var functionType = (FunctionType)c.Type; - - // var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - // var function = context.Buffer.AddOpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader); - // context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId.Value, c.Id.Name, functionType)); - // table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId.Value }); - // } - // } - - // // Mark inherit - // context.Buffer.AddOpSDSLMixinInherit(shader); - // context.Module.InheritedMixins.Add(shaderType); - // } - - // foreach (var member in Elements.OfType()) - // member.Compile(table, this, compiler); - // foreach (var member in Elements.OfType()) - // member.Compile(table, this, compiler); - // foreach(var method in Elements.OfType()) - // method.Compile(table, this, compiler); - - // table.CurrentShader = null; - // table.Pop(); + table.Push(); + foreach (var mixin in Mixins) + { + var shaderType = LoadShader(table.ShaderLoader, mixin); + + RegisterShaderType(table, shaderType); + } + + var symbols = new List(); + foreach (var member in Elements) + { + if (member is ShaderMethod func) + { + var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); + foreach (var arg in func.Parameters) + { + var argSym = arg.TypeName.ResolveType(table); + table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + arg.Type = argSym; + ftype.ParameterTypes.Add(arg.Type); + } + func.Type = ftype; + + table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); + } + else if (member is ShaderMember svar) + { + svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); + table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + } + else if (member is CBuffer cb) + { + foreach (var cbMember in cb.Members) + { + cbMember.Type = cbMember.TypeName.ResolveType(table); + //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); + //symbols.Add(symbol); + } + } + } + + var currentShader = new ShaderSymbol(Name, symbols); + RegisterShaderType(table, currentShader); + + table.CurrentShader = currentShader; + foreach (var member in Elements) + { + member.ProcessSymbol(table); + } + + var (builder, context, _) = compiler; + context.PutShaderName(Name); + + foreach (var mixin in Mixins) + { + // Import types and variables/functions + context.Buffer.FluentAdd(new OpSDSLImportShader(context.Bound++, new(mixin.Name)), out var shader); + + var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; + + foreach (var c in shaderType.Components) + { + if (c.Id.Kind == SymbolKind.Variable) + { + var variableTypeId = context.GetOrRegister(c.Type); + var variable = context.Buffer.Add(new OpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader.ResultId)); + context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); + table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.IdResult }); + } + else if (c.Id.Kind == SymbolKind.Method) + { + var functionType = (FunctionType)c.Type; + + var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); + context.Buffer.FluentAdd(new OpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader.ResultId), out var function); + context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId, c.Id.Name, functionType)); + table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); + } + } + + // Mark inherit + context.Buffer.Add(new OpSDSLMixinInherit(shader.ResultId)); + context.Module.InheritedMixins.Add(shaderType); + } + + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); + foreach (var method in Elements.OfType()) + method.Compile(table, this, compiler); + + table.CurrentShader = null; + table.Pop(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 3710e92433..a19d43e4c7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -208,9 +208,8 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? - #warning replace - // context.Buffer.AddOpVariable(variable, pointerType, Specification.StorageClass.Uniform, null); - //context.Variables.Add(Name, new(variable, registeredType, Name)); + context.Buffer.Add(new OpVariable(variable, pointerType, Specification.StorageClass.Uniform, null)); + context.Variables.Add(Name, new(variable, pointerType, Name)); context.AddName(variable, Name); for (var index = 0; index < Members.Count; index++) diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index 6f839904abc6f1c49991f7e0a7df7b7abbd9114d..70678867f1521cb64ac516a7fc19581fb8b572af 100644 GIT binary patch delta 734 zcmeBD-lwtQ3*+Q}YKvDdwoj*SN(dE3rsSUcnrt2vyHe&A`jR1<{K{dNQO;PUMmlhN%i+sAMQ$NM!(t zFJ)Eahl%?!Br@bOq)uMXCCge1GHLQfZfT$$V!Zx9^)5i!5+GKXypTnDau$n*CbC`F zZO&v!1G+%8&z9lLF*d zFlYdEmI6f-7|MWdC<4-%K>ZLoO$JS@{)YJr=ue<}+sXTxB)#<*e1YcW0!=FdhJqeL zFwkd-K$D`8%u`^{2C6q?h-I+GYA(^fs>kjtMEJvefa$vucpSmh5b`C$RIqPBAvF0g tlV~t*A7k1<$md8Ygt2yVqJZ<{Bmt$#b*vhbFL6svJ|$qXS%R&I8vv4^fBOIc delta 194 zcmdm|(WSiM3*+PjE{@6P1WYEcV`Q6L!DKY~0JqlUJ4{hPT4{0ubJ}Dr9<|9*Ok9&c zFvqc0Gw?ESO+LtMJh_QUWU>~w#AGK{9exD{D+UFI5{3+hOon0xjmh;);*2_z9oeKU zgBVhQBBcyDK-mz6N`?X;Uy(tNA&emrC{_yO=>T=+0eQJVwkD8W%}@)r<0HHCWCann f$#KF8lMRG9CWmoofccA9q$U>#hi$&Vk;e@HMussy diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 4edb527a00..2281307831 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Spirv.Building; // Should have utility functions to add instruction to the buffer public partial class SpirvBuilder() { - public SpirvBuffer Buffer { get; init; } = new(); + public NewSpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; private set; } public SpirvBlock? CurrentBlock { get; private set; } public int Position { get; internal set; } = 0; diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 1820ad16b3..6a966e4644 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -36,9 +36,9 @@ public override string ToString() var builder = new StringBuilder(); builder .AppendLine("Context : ") - .AppendLine(new SpirvDis(Context.Buffer).Disassemble()) + .AppendLine(Spv.Dis(Context.Buffer)) .AppendLine("Functions : ") - .AppendLine(new SpirvDis(Builder.Buffer).Disassemble()); + .AppendLine(Spv.Dis(Builder.Buffer)); return builder.ToString(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 8594b255c8..9e52bb8363 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -25,49 +25,45 @@ public class SpirvContext(SpirvModule module) public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; - public SpirvBuffer Buffer { get; set; } = new(); + public NewSpirvBuffer Buffer { get; set; } = new(); public void PutShaderName(string name) { if (Name is null) { -#warning replace - // Name = name; - // Buffer.InsertOpSDSLShader(0, name); + Name = name; + Buffer.Insert(0, new OpSDSLShader(name)); } else throw new NotImplementedException(); } - public void AddName(IdRef target, string name) -#warning replace - => throw new NotImplementedException(); - // => Buffer.AddOpName(target, name.Replace('.', '_')); + public void AddName(int target, string name) + => Buffer.Add(new OpName(target, name.Replace('.', '_'))); - public void AddMemberName(IdRef target, int accessor, string name) -#warning replace - => throw new NotImplementedException(); - // => Buffer.AddOpMemberName(target, accessor, name); + public void AddMemberName(int target, int accessor, string name) + => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); - public IdRef AddConstant(TScalar value) + public int AddConstant(TScalar value) where TScalar : INumber { - // return value switch - // { - // byte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v), - // sbyte v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v), - // ushort v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v), - // short v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v), - // uint v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v), - // int v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v), - // ulong v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v), - // long v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v), - // Half v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v), - // float v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v), - // double v => Buffer.AddOpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v), - // _ => throw new NotImplementedException() - // }; -#warning replace - throw new NotImplementedException(); + var data = value switch + { + byte v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v)), + sbyte v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v)), + ushort v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v)), + short v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v)), + uint v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v)), + int v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v)), + ulong v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v)), + long v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v)), + Half v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v)), + float v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v)), + double v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v)), + _ => throw new NotImplementedException() + }; + if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) + return data.Memory.Span[index + 1]; + throw new Exception("Constant has no result id"); } public void AddGlobalVariable(Symbol variable) @@ -110,18 +106,16 @@ public void AddGlobalVariable(Symbol variable) } - public void SetEntryPoint(ExecutionModel model, IdRef function, string name, ReadOnlySpan variables) + public void SetEntryPoint(ExecutionModel model, int function, string name, ReadOnlySpan variables) { - // Span pvariables = stackalloc IdRef[variables.Length]; - // int pos = 0; - // foreach (var v in variables) - // pvariables[pos++] = Variables[v.Id.Name].Id; - // Buffer.AddOpEntryPoint(model, function, name, pvariables); -#warning replace - throw new NotImplementedException(); + Span pvariables = stackalloc int[variables.Length]; + int pos = 0; + foreach (var v in variables) + pvariables[pos++] = Variables[v.Id.Name].Id; + Buffer.Add(new OpEntryPoint(model, function, name, [.. pvariables])); } - public IdRef GetOrRegister(SymbolType? type) + public int GetOrRegister(SymbolType? type) { if (type is null) throw new ArgumentException($"Type is null"); @@ -129,103 +123,93 @@ public IdRef GetOrRegister(SymbolType? type) return res; else { - // var instruction = type switch - // { - // ScalarType s => - // s.TypeName switch - // { - // "void" => Buffer.AddOpTypeVoid(Bound++), - // "bool" => Buffer.AddOpTypeBool(Bound++), - // "sbyte" => Buffer.AddOpTypeInt(Bound++, 8, 1), - // "byte" => Buffer.AddOpTypeInt(Bound++, 8, 0), - // "ushort" => Buffer.AddOpTypeInt(Bound++, 16, 1), - // "short" => Buffer.AddOpTypeInt(Bound++, 16, 0), - // "int" => Buffer.AddOpTypeInt(Bound++, 32, 1), - // "uint" => Buffer.AddOpTypeInt(Bound++, 32, 0), - // "long" => Buffer.AddOpTypeInt(Bound++, 64, 1), - // "ulong" => Buffer.AddOpTypeInt(Bound++, 64, 0), - // "half" => Buffer.AddOpTypeFloat(Bound++, 16, null), - // "float" => Buffer.AddOpTypeFloat(Bound++, 32, null), - // "double" => Buffer.AddOpTypeFloat(Bound++, 64, null), - // _ => throw new NotImplementedException($"Can't add type {type}") + var instruction = type switch + { + ScalarType s => + s.TypeName switch + { + "void" => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, + "bool" => Buffer.Add(new OpTypeBool(Bound++)).IdResult, + "sbyte" => Buffer.Add(new OpTypeInt(Bound++, 8, 1)).IdResult, + "byte" => Buffer.Add(new OpTypeInt(Bound++, 8, 0)).IdResult, + "ushort" => Buffer.Add(new OpTypeInt(Bound++, 16, 1)).IdResult, + "short" => Buffer.Add(new OpTypeInt(Bound++, 16, 0)).IdResult, + "int" => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, + "uint" => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, + "long" => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, + "ulong" => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, + "half" => Buffer.Add(new OpTypeFloat(Bound++, 16, null)).IdResult, + "float" => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, + "double" => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, + _ => throw new NotImplementedException($"Can't add type {type}") - // }, - // VectorType v => Buffer.AddOpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size), - // MatrixType m => Buffer.AddOpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns), - // ArrayType a => Buffer.AddOpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size), - // StructType st => RegisterStructuredType(st.ToId(), st), - // ConstantBufferSymbol cb => RegisterCBuffer(cb), - // FunctionType f => RegisterFunctionType(f), - // PointerType p => RegisterPointerType(p), - // // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), - // // StructSymbol st => RegisterStruct(st), - // _ => throw new NotImplementedException($"Can't add type {type}") - // }; - // Types[type] = instruction; - // ReverseTypes[instruction] = type; - // return instruction; -#warning replace - throw new NotImplementedException(); + }, + VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, + MatrixType m => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, + ArrayType a => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, + StructType st => RegisterStructuredType(st.ToId(), st), + ConstantBufferSymbol cb => RegisterCBuffer(cb), + FunctionType f => RegisterFunctionType(f), + PointerType p => RegisterPointerType(p), + // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), + // StructSymbol st => RegisterStruct(st), + _ => throw new NotImplementedException($"Can't add type {type}") + }; + Types[type] = instruction; + ReverseTypes[instruction] = type; + return instruction; } } - private IdRef RegisterCBuffer(ConstantBufferSymbol cb) + private int RegisterCBuffer(ConstantBufferSymbol cb) { - // var result = RegisterStructuredType($"type.{cb.ToId()}", cb); + var result = RegisterStructuredType($"type.{cb.ToId()}", cb); - // Buffer.AddOpDecorate(result, Decoration.Block); - // for (var index = 0; index < cb.Members.Count; index++) - // { - // var member = cb.Members[index]; - // if (index > 0) - // throw new NotImplementedException("Offset"); - // Buffer.AddOpMemberDecorate(result, index, Decoration.Offset, 0); - // } + Buffer.Add(new OpDecorate(result, Decoration.Block)); + for (var index = 0; index < cb.Members.Count; index++) + { + if (index > 0) + throw new NotImplementedException("Offset"); + Buffer.Add(new OpMemberDecorate(result, index, Decoration.Offset, 0)); + } - // return result; - #warning replace - throw new NotImplementedException(); + return result; } - IdRef RegisterStructuredType(string name, StructuredType structSymbol) + int RegisterStructuredType(string name, StructuredType structSymbol) { - // Span types = stackalloc IdRef[structSymbol.Members.Count]; - // for (var index = 0; index < structSymbol.Members.Count; index++) - // types[index] = GetOrRegister(structSymbol.Members[index].Type); + Span types = stackalloc int[structSymbol.Members.Count]; + for (var index = 0; index < structSymbol.Members.Count; index++) + types[index] = GetOrRegister(structSymbol.Members[index].Type); - // var result = Buffer.AddOpTypeStruct(Bound++, types); - // AddName(result, name); - // for (var index = 0; index < structSymbol.Members.Count; index++) - // AddMemberName(result, index, structSymbol.Members[index].Name); - - // return result; -#warning replace - throw new NotImplementedException(); + var result = Buffer.Add(new OpTypeStruct(Bound++, [.. types])); + var id = result.IdResult; + AddName(id, name); + for (var index = 0; index < structSymbol.Members.Count; index++) + AddMemberName(id, index, structSymbol.Members[index].Name); + return id; } - IdRef RegisterFunctionType(FunctionType functionType) + int RegisterFunctionType(FunctionType functionType) { - // Span types = stackalloc IdRef[functionType.ParameterTypes.Count]; - // int tmp = 0; - // foreach (var f in functionType.ParameterTypes) - // types[tmp] = GetOrRegister(f); - // var result = Buffer.AddOpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), types); + Span types = stackalloc int[functionType.ParameterTypes.Count]; + int tmp = 0; + foreach (var f in functionType.ParameterTypes) + types[tmp] = GetOrRegister(f); + var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); - // return result; - #warning replace - throw new NotImplementedException(); + return result.IdResult; } - IdRef RegisterPointerType(PointerType pointerType) + int RegisterPointerType(PointerType pointerType) { - // var baseType = GetOrRegister(pointerType.BaseType); - // var result = Buffer.AddOpTypePointer(Bound++, pointerType.StorageClass, baseType); - // AddName(result, pointerType.ToId()); - // return result; -#warning replace - throw new NotImplementedException(); + var baseType = GetOrRegister(pointerType.BaseType); + var result = Buffer.Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); + var id = result.IdResult; + AddName(id, pointerType.ToId()); + return id; } public SpirvValue CreateConstant(Literal literal) @@ -247,42 +231,42 @@ public SpirvValue CreateConstant(Literal literal) // if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) // return result; + var instruction = literal switch + { + BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(Bound++, GetOrRegister(lit.Type))), + BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(Bound++, GetOrRegister(lit.Type))), + IntegerLiteral lit => lit.Suffix switch + { + { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (byte)lit.IntValue)), + { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (sbyte)lit.IntValue)), + { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (ushort)lit.IntValue)), + { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (short)lit.IntValue)), + { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), unchecked((uint)lit.IntValue))), + { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue)), + _ => throw new NotImplementedException() + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue)), + _ => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue)), + }, + _ => throw new NotImplementedException() + }; - // var instruction = literal switch - // { - // BoolLiteral lit => lit.Value switch - // { - // true => Buffer.AddOpConstantTrue(Bound++, GetOrRegister(lit.Type)), - // false => Buffer.AddOpConstantFalse(Bound++, GetOrRegister(lit.Type)) - // }, - // IntegerLiteral lit => lit.Suffix.Size switch - // { - // > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.LongValue), - // _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue), - // }, - // FloatLiteral lit => lit.Suffix.Size switch - // { - // > 32 => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue), - // _ => Buffer.AddOpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue), - // }, - // _ => throw new NotImplementedException() - // }; - - // result = new(instruction); + SpirvValue result = new(instruction); // LiteralConstants.Add((literal.Type, literalValue), result); - // AddName(result.Id, literal switch - // { - // BoolLiteral lit => $"{lit.Type}_{lit.Value}", - // IntegerLiteral lit => $"{lit.Type}_{lit.Value}", - // FloatLiteral lit => $"{lit.Type}_{lit.Value}", - // }); - // return result; -#warning replace - throw new NotImplementedException(); + AddName(result.Id, literal switch + { + BoolLiteral lit => $"{lit.Type}_{lit.Value}", + IntegerLiteral lit => $"{lit.Type}_{lit.Value}", + FloatLiteral lit => $"{lit.Type}_{lit.Value}", + _ => throw new NotImplementedException() + }); + return result; } public override string ToString() { - return new SpirvDis(Buffer).Disassemble(); + return Spv.Dis(Buffer); } } \ No newline at end of file From 8e108ab57e06d3a3cfab033ac7c1df7e74626dd1 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 17 Sep 2025 22:31:52 +0200 Subject: [PATCH 0446/1182] improvements done and tested --- .gitignore | 3 +- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 8 +- .../Examples.Spirv.cs | 24 +- src/Stride.Shaders.Experiments/Examples.cs | 34 +- src/Stride.Shaders.Experiments/Program.cs | 14 +- .../Buffers/NewSpirvBuffer.cs | 33 +- .../Buffers/SpirvBuffer.cs | 292 +++++----- .../Literals/LiteralArray.cs | 4 +- .../Literals/LiteralString.cs | 50 -- .../Literals/LiteralValue.cs | 12 +- .../Parsing/OpDataEnumerator.cs | 10 +- .../SPVGenerator.Instructions.cs | 32 +- .../Parsing/SDSL/AST/Expression.cs | 4 +- .../Parsing/SDSL/AST/Literals.cs | 27 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 31 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 51 +- .../Parsing/SDSL/AST/ShaderElements.cs | 2 +- .../Parsing/SDSL/AST/Statements.cs | 50 +- .../Spirv/Building/Builder.Expressions.cs | 200 +++---- .../Spirv/Building/Builder.Flow.cs | 30 +- .../Spirv/Building/Builder.Functions.cs | 59 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 39 +- .../Spirv/Building/CompilerUnit.cs | 11 +- src/Stride.Shaders/Spirv/Building/Context.cs | 81 ++- .../Spirv/Processing/INanoPass.cs | 2 +- .../Spirv/Processing/IPostProcessorSubPass.cs | 2 +- .../Spirv/Processing/StreamAnalyzer.cs | 281 ++++----- .../Spirv/Processing/TypeDuplicatesRemover.cs | 302 +++++----- .../Spirv/Storage/MixinStorage.cs | 6 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 549 +++++++++++++++--- 30 files changed, 1316 insertions(+), 927 deletions(-) diff --git a/.gitignore b/.gitignore index b566b5b6bd..9fb2e37e51 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ obj/ log*.txt *.vsix *.fsx -src/Stride.Shaders.Spirv.Core/Generated/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.SPVGenerator/*.Instruction.g.cs \ No newline at end of file +src/Stride.Shaders.Spirv.Core/Generated/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.SPVGenerator/*.Instruction.g.cs +*.sdspv \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index c494ba8591..f5960b4021 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -34,11 +34,9 @@ public readonly bool Compile(string code, out byte[] compiled) //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); //new StreamAnalyzer().Process(table, compiler); - compiler.Context.Buffer.Sort(); - var merged = SpirvBuffer.Merge(compiler.Context.Buffer, compiler.Builder.Buffer); - var dis = new SpirvDis(merged, true); - dis.Disassemble(true); - compiled = MemoryMarshal.AsBytes(merged.ToBuffer().AsSpan()).ToArray(); + var merged = compiler.ToBuffer(); + var dis = Spv.Dis(merged, true); + compiled = MemoryMarshal.AsBytes(merged.ToBuffer().Span).ToArray(); return true; } else diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index bd1b1efd43..b3bdf298b2 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -15,9 +15,8 @@ public static partial class Examples { public static void GenerateSpirv() { - var module = new SpirvModule(); - var context = new SpirvContext(new()); - var builder = new SpirvBuilder(); + var compiler = new CompilerUnit(); + var (builder, context, module) = compiler; context.GetOrRegister(new MatrixType(ScalarType.From("float"), 4, 3)); context.GetOrRegister(ScalarType.From("int")); @@ -41,10 +40,9 @@ public static void GenerateSpirv() function.Parameters["a"], Operator.Plus, function.Parameters["b"] ); builder.Return(v); - builder.EndFunction(context); - context.Buffer.Sort(); - var dis = new SpirvDis(SpirvBuffer.Merge(context.Buffer, builder.Buffer), useNames: true); - dis.Disassemble(true); + builder.EndFunction(); + context.Sort(); + Spv.Dis(compiler.ToBuffer()); } public static void ParseShader() @@ -284,14 +282,8 @@ public static void ParseWorking() var bytes = File.ReadAllBytes(path); - var buffer = new SpirvBuffer(MemoryMarshal.Cast(bytes)); - var extInst = buffer[1]; - foreach (var o in extInst) - { - if (o.Kind == OperandKind.LiteralString) - { - Console.WriteLine(o.To().Value); - } - } + var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytes)); + var extInst = (OpExtInstImport)buffer[1] ; + Console.WriteLine(extInst.Name); } } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 1520ee9e6b..ed6c894199 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -237,14 +237,16 @@ public static void CompileSDSL() { var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestBasic.sdsl"); - var sdslc = new SDSLC(); - sdslc.ShaderLoader = new ShaderLoader(); + var sdslc = new SDSLC + { + ShaderLoader = new ShaderLoader() + }; sdslc.Compile(text, out var bytecode); - File.WriteAllBytes("shader.bin", bytecode); + File.WriteAllBytes("TestBasic.sdspv", bytecode); var test = bytecode.AsMemory().Cast().ToArray(); var code = new SpirvTranslator(bytecode.AsMemory().Cast()); - //Console.WriteLine(code.Translate(Backend.Hlsl)); + // Console.WriteLine(code.Translate(Backend.Hlsl)); } @@ -272,15 +274,15 @@ public sealed class ShaderClassCode(string className) : ShaderSource public string ClassName { get; } = className; } - static Dictionary loadedShaders = new(); + static Dictionary loadedShaders = new(); - static SpirvBuffer GetOrLoadShader(string name) + static NewSpirvBuffer GetOrLoadShader(string name) { if (loadedShaders.TryGetValue(name, out var buffer)) return buffer; new ShaderLoader().LoadExternalReference(name, out var bytecode); - buffer = new SpirvBuffer(MemoryMarshal.Cast(bytecode)); + buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); loadedShaders.Add(name, buffer); @@ -494,24 +496,20 @@ static void SetOpNop(Span words) words[1..].Clear(); } - private static void BuildInheritanceList(SpirvBuffer buffer, List inheritanceList) + private static void BuildInheritanceList(NewSpirvBuffer buffer, List inheritanceList) { // Build shader name mapping var shaderMapping = new Dictionary(); - foreach (var i in buffer.Instructions) - { - if (i.OpCode == Specification.Op.OpSDSLImportShader) - { - shaderMapping[i.ResultId!.Value] = i.GetOperand("shaderName")!.Value.Value; - } - } + foreach (var i in buffer) + if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader) i is {} importShader) + shaderMapping[importShader.ResultId] = importShader.ShaderName; // Check inheritance - foreach (var i in buffer.Instructions) + foreach (var i in buffer) { - if (i.OpCode == Specification.Op.OpSDSLMixinInherit) + if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is {} inherit) { - var shaderName = shaderMapping[i.Words[1]]; + var shaderName = shaderMapping[inherit.Shader]; var shader = GetOrLoadShader(shaderName); BuildInheritanceList(shader, inheritanceList); inheritanceList.Add(shaderName); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 762edc8ef1..bd49c27617 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -1,17 +1,9 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Experiments; -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Tools; -using static Stride.Shaders.Spirv.Specification; +using Stride.Shaders.Experiments; -//Examples.CompileSDSL(); +Examples.CompileSDSL(); // Examples.MergeSDSL(); // Examples.TryAllFiles(); // Examples.CreateShader(); // Examples.GenerateSpirv(); -Examples.CreateNewShader(); \ No newline at end of file +// Examples.CreateNewShader(); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index a78145c01b..8d59573fad 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -22,8 +22,8 @@ public struct OpData : IDisposable, IComparable public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } public readonly Op Op => (Op)(Memory.Span[0] & 0xFFFF); - public readonly int IdResult => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : throw new Exception("No IdResult for this instruction"); - public readonly int IdResultType => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : throw new Exception("No IdResult for this instruction"); + public readonly int? IdResult => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : null; + public readonly int? IdResultType => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; public OpData() { @@ -90,8 +90,8 @@ public readonly int CompareTo(OpData other) public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) { - public readonly Op Op => Buffer[Index].Op; - public readonly ref OpData Data => ref Buffer[Index]; + public readonly Op Op => Data.Op; + public readonly ref OpData Data => ref Buffer.GetRef(Index); } public sealed class NewSpirvBuffer() : IDisposable @@ -100,12 +100,15 @@ public sealed class NewSpirvBuffer() : IDisposable List Instructions { get; set; } = []; public int Count => Instructions.Count; - internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; + // internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; + public OpDataIndex this[int index] => new(index, this); + public ref OpData GetRef(int index) => ref CollectionsMarshal.AsSpan(Instructions)[index]; + public NewSpirvBuffer(Span span) : this() { - if(span[0] == MagicNumber) + if (span[0] == MagicNumber) Header = SpirvHeader.Read(span); var instructions = span[5..]; @@ -196,6 +199,13 @@ public T Insert(int index, in T data) Header = Header with { Bound = tmp.InstructionMemory.Span[rid] + 1 }; return data; } + public OpData InsertData(int index, in T data) + where T : struct, IMemoryInstruction + { + var result = new OpData(data.InstructionMemory); + Instructions.Insert(index, result); + return result; + } /// /// Removes an instruction at a certain index. @@ -270,6 +280,17 @@ public void Dispose() instruction.Dispose(); Instructions.Clear(); } + + public static NewSpirvBuffer Merge(NewSpirvBuffer buffer1, NewSpirvBuffer buffer2) + { + var result = new NewSpirvBuffer + { + Header = new SpirvHeader("1.4", Math.Max(buffer1.Header.Generator, buffer2.Header.Generator), Math.Max(buffer1.Header.Bound, buffer2.Header.Bound)) + }; + result.Instructions.AddRange(buffer1.Instructions); + result.Instructions.AddRange(buffer2.Instructions); + return result; + } } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index bea995f19a..5cd3998ba8 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -1,146 +1,146 @@ -using CommunityToolkit.HighPerformance; -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using System; -using System.Buffers; -using System.Numerics; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A common SPIR-V buffer containing a header. -/// -public class SpirvBuffer : IMutSpirvBuffer -{ - private SpirvHeader header = new("1.3", 0, 0); - private ArrayPool pool = ArrayPool.Shared; - - public List Instructions { get; } = []; - - public Span InstructionsSpan => Instructions.AsSpan(); - - public bool HasHeader => true; - public ref SpirvHeader Header => ref header; - - public Instruction FindInstructionByResultId(int resultId) - { - foreach (var instruction in Instructions) - { - if (instruction.ResultId == resultId) - return instruction; - } - - throw new InvalidOperationException(); - } - - public Instruction this[int index] => Instructions[index]; - - public SpirvBuffer(int initialSize = 32) - { - } - public SpirvBuffer(Memory memory) - { - Header = SpirvHeader.Read(memory.Span); - var instructions = memory[5..]; - - int wid = 0; - while (wid < instructions.Length) - { - Instructions.Add(new Instruction(instructions.Slice(wid, instructions.Span[wid] >> 16))); - wid += instructions.Span[wid] >> 16; - } - } - - public SpirvBuffer(Span span) - { - Header = SpirvHeader.Read(span); - var instructions = span[5..]; - - int wid = 0; - while (wid < instructions.Length) - { - Add(instructions.Slice(wid, instructions[wid] >> 16)); - wid += instructions[wid] >> 16; - } - } - - public int[] ToBuffer() - { - var offset = 5; - foreach (var instruction in Instructions) - offset += instruction.WordCount; - var buffer = new int[offset]; - - Header.WriteTo(buffer); - offset = 5; - foreach (var instruction in Instructions) - { - instruction.Words.CopyTo(buffer.AsSpan()[offset..]); - offset += instruction.WordCount; - } - - return buffer; - } - - - public void Sort() - { - var sorted = new OrderedEnumerator(this); - var newInstructions = new List(); - while (sorted.MoveNext()) - { - newInstructions.Add(sorted.Current); - } - - Instructions.Clear(); - Instructions.AddRange(newInstructions); - } - - private Instruction CreateInstruction(Span instructionData) - { - var instructionBuffer = pool.Rent(instructionData.Length).AsMemory(0, instructionData.Length); - instructionData.CopyTo(instructionBuffer.Span); - return new Instruction(instructionBuffer); - } - - public Instruction Add(Span instructionData) - { - var instruction = CreateInstruction(instructionData); - - Instructions.Add(instruction); - if (instruction.ResultId is int resultId && resultId >= Header.Bound) - Header = Header with { Bound = resultId + 1 }; - - return instruction; - } - - public Instruction Insert(int position, Span instructionData) - { - var instruction = CreateInstruction(instructionData); - - Instructions.Insert(position, instruction); - if (instruction.ResultId is int resultId && resultId >= Header.Bound) - Header = Header with { Bound = resultId + 1 }; - - return instruction; - } - - internal void Add(TBuff buffer) - where TBuff : ISpirvBuffer - { - Instructions.AddRange(buffer.InstructionsSpan); - } - - public static SpirvBuffer Merge(T1 left, T2 right) - where T1 : ISpirvBuffer - where T2 : ISpirvBuffer - { - var buff = new SpirvBuffer(); - buff.Add(left); - buff.Add(right); - foreach (var e in buff.Instructions) - if (e.ResultId is int r && buff.Header.Bound < r + 1) - buff.Header = buff.Header with { Bound = r + 1 }; - return buff; - } -} +// using CommunityToolkit.HighPerformance; +// using CommunityToolkit.HighPerformance.Buffers; +// using Stride.Shaders.Spirv.Core.Parsing; +// using System; +// using System.Buffers; +// using System.Numerics; + +// namespace Stride.Shaders.Spirv.Core.Buffers; + +// /// +// /// A common SPIR-V buffer containing a header. +// /// +// public class SpirvBuffer : IMutSpirvBuffer +// { +// private SpirvHeader header = new("1.3", 0, 0); +// private ArrayPool pool = ArrayPool.Shared; + +// public List Instructions { get; } = []; + +// public Span InstructionsSpan => Instructions.AsSpan(); + +// public bool HasHeader => true; +// public ref SpirvHeader Header => ref header; + +// public Instruction FindInstructionByResultId(int resultId) +// { +// foreach (var instruction in Instructions) +// { +// if (instruction.ResultId == resultId) +// return instruction; +// } + +// throw new InvalidOperationException(); +// } + +// public Instruction this[int index] => Instructions[index]; + +// public SpirvBuffer(int initialSize = 32) +// { +// } +// public SpirvBuffer(Memory memory) +// { +// Header = SpirvHeader.Read(memory.Span); +// var instructions = memory[5..]; + +// int wid = 0; +// while (wid < instructions.Length) +// { +// Instructions.Add(new Instruction(instructions.Slice(wid, instructions.Span[wid] >> 16))); +// wid += instructions.Span[wid] >> 16; +// } +// } + +// public SpirvBuffer(Span span) +// { +// Header = SpirvHeader.Read(span); +// var instructions = span[5..]; + +// int wid = 0; +// while (wid < instructions.Length) +// { +// Add(instructions.Slice(wid, instructions[wid] >> 16)); +// wid += instructions[wid] >> 16; +// } +// } + +// public int[] ToBuffer() +// { +// var offset = 5; +// foreach (var instruction in Instructions) +// offset += instruction.WordCount; +// var buffer = new int[offset]; + +// Header.WriteTo(buffer); +// offset = 5; +// foreach (var instruction in Instructions) +// { +// instruction.Words.CopyTo(buffer.AsSpan()[offset..]); +// offset += instruction.WordCount; +// } + +// return buffer; +// } + + +// public void Sort() +// { +// var sorted = new OrderedEnumerator(this); +// var newInstructions = new List(); +// while (sorted.MoveNext()) +// { +// newInstructions.Add(sorted.Current); +// } + +// Instructions.Clear(); +// Instructions.AddRange(newInstructions); +// } + +// private Instruction CreateInstruction(Span instructionData) +// { +// var instructionBuffer = pool.Rent(instructionData.Length).AsMemory(0, instructionData.Length); +// instructionData.CopyTo(instructionBuffer.Span); +// return new Instruction(instructionBuffer); +// } + +// public Instruction Add(Span instructionData) +// { +// var instruction = CreateInstruction(instructionData); + +// Instructions.Add(instruction); +// if (instruction.ResultId is int resultId && resultId >= Header.Bound) +// Header = Header with { Bound = resultId + 1 }; + +// return instruction; +// } + +// public Instruction Insert(int position, Span instructionData) +// { +// var instruction = CreateInstruction(instructionData); + +// Instructions.Insert(position, instruction); +// if (instruction.ResultId is int resultId && resultId >= Header.Bound) +// Header = Header with { Bound = resultId + 1 }; + +// return instruction; +// } + +// internal void Add(TBuff buffer) +// where TBuff : ISpirvBuffer +// { +// Instructions.AddRange(buffer.InstructionsSpan); +// } + +// public static SpirvBuffer Merge(T1 left, T2 right) +// where T1 : ISpirvBuffer +// where T2 : ISpirvBuffer +// { +// var buff = new SpirvBuffer(); +// buff.Add(left); +// buff.Add(right); +// foreach (var e in buff.Instructions) +// if (e.ResultId is int r && buff.Header.Bound < r + 1) +// buff.Header = buff.Header with { Bound = r + 1 }; +// return buff; +// } +// } diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index a8da9051b1..543961f373 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -76,14 +76,14 @@ public void Assign(MemoryOwner owner) public void Assign(Memory span) { Elements.Dispose(); - Elements = MemoryOwner.Allocate(span.Length); + Elements = span.Length == 0 ? MemoryOwner.Empty : MemoryOwner.Allocate(span.Length); span.CopyTo(Elements.Memory); } public void Assign(Span span) { Elements.Dispose(); - Elements = MemoryOwner.Allocate(span.Length); + Elements = span.Length == 0 ? MemoryOwner.Empty : MemoryOwner.Allocate(span.Length); span.CopyTo(Elements.Span); } diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs index 7dad0706af..f6b289646c 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -56,56 +56,6 @@ public void WriteTo(Span slice) } } - public void Write(ref SpirvWriter writer) - { - var wordLength = Value.Length / 4; - var rest = RestSize; - var span = Value.AsSpan(); - for (int i = 0; i < wordLength; i++) - { - if (rest == 0) - { - int word = - Convert.ToByte(span[4 * i]) << 24 - | Convert.ToByte(span[4 * i + 1]) << 16 - | Convert.ToByte(span[4 * i + 2]) << 8 - | Convert.ToByte(span[4 * i + 3]); - writer.Write(word); - } - else - { - if (i < wordLength - 1) - { - int word = - Convert.ToByte(span[4 * i]) << 24 - | Convert.ToByte(span[4 * i + 1]) << 16 - | Convert.ToByte(span[4 * i + 2]) << 8 - | Convert.ToByte(span[4 * i + 3]); - writer.Write(word); - - } - else - { - if (rest == 1) - writer.Write( - Convert.ToByte(span[4 * i]) << 24 - ); - else if (rest == 2) - writer.Write( - Convert.ToByte(span[4 * i]) << 24 - | Convert.ToByte(span[4 * i + 1]) << 16 - ); - else if (rest == 3) - writer.Write( - Convert.ToByte(span[4 * i]) << 24 - | Convert.ToByte(span[4 * i + 1]) << 16 - | Convert.ToByte(span[4 * i + 2]) << 8 - ); - } - } - } - } - public static string Parse(Span input) { var lit = new LiteralString(input); diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index dd3a8d7a74..6b6022a452 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -28,6 +28,7 @@ static LiteralValue() LiteralValue or LiteralValue or LiteralValue + or LiteralValue or LiteralValue or LiteralValue or LiteralValue @@ -45,7 +46,7 @@ or LiteralValue public bool dispose; public MemoryOwner MemoryOwner { get; private set; } public readonly ReadOnlySpan Words => MemoryOwner.Span; - public T Value { get; set { field = value; if(MemoryOwner is not null) UpdateMemory(); } } + public T Value { get; set { field = value; if (MemoryOwner is not null) UpdateMemory(); } } public readonly int WordCount => Words.Length; public LiteralValue(Span words, bool dispose = false) @@ -76,7 +77,9 @@ public LiteralValue(Span words, bool dispose = false) Unsafe.As(ref value) = BitConverter.Int64BitsToDouble(((long)words[0] << 32) | (uint)words[1]); else if (value is ValueTuple) Unsafe.As(ref value) = (words[0], words[1]); - else if(value is null && typeof(T) == typeof(string)) + else if (value is null && typeof(T) != typeof(string)) + value = default!; + else if (value is null && typeof(T) == typeof(string)) { Span sb = stackalloc char[words.Length * 4]; for (int i = 0; i < words.Length; i++) @@ -123,8 +126,11 @@ void UpdateMemory() null => 0, _ => throw new NotImplementedException("Can't compute literal value for type " + typeof(T)) }; - if(MemoryOwner == null) + if (MemoryOwner == null) + { MemoryOwner = MemoryOwner.Empty; + return; + } else MemoryOwner.Dispose(); MemoryOwner = MemoryOwner.Allocate(wordCount, AllocationMode.Clear); if (Value is bool or byte or sbyte or short or ushort or Half or int or uint or float) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 99191fdb7e..0880f1d501 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -90,7 +90,13 @@ or Decoration.SecondaryViewportRelativeNV }; wid = newWid; oid = newOid; - return result && wid < Operands.Length && oid < logicalOperands.Count; + if (oid < logicalOperands.Count) + return logicalOperands[oid].Quantifier switch + { + OperandQuantifier.One => result && wid < Operands.Length && oid < logicalOperands.Count, + _ => result && oid < logicalOperands.Count + }; + else return false; } } @@ -151,7 +157,7 @@ public SpvOperand ParseCurrent() { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length -1 ? Operands.Slice(wid, 1) : []), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length - 1 ? Operands[wid..] : []), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index a604dc0772..2932a17015 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -147,7 +147,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst if (instruction.Operands?.AsList() is List operands) { - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -230,7 +230,7 @@ public MemoryOwner InstructionMemory readonly get {{ if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; + return odi.Data.Memory; else return field; }} @@ -238,8 +238,8 @@ private set {{ if (DataIndex is OpDataIndex odi) {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; + odi.Data.Memory.Dispose(); + odi.Data.Memory = value; }} else field = value; }} @@ -270,7 +270,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i operands.Add(new() { Name = "additional1", Kind = "LiteralInteger", Quantifier = "?" }); operands.Add(new() { Name = "additional2", Kind = "LiteralInteger", Quantifier = "?" }); operands.Add(new() { Name = "additionalString", Kind = "LiteralString", Quantifier = "?" }); - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -353,7 +353,7 @@ public MemoryOwner InstructionMemory readonly get {{ if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; + return odi.Data.Memory; else return field; }} @@ -361,8 +361,8 @@ private set {{ if (DataIndex is OpDataIndex odi) {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; + odi.Data.Memory.Dispose(); + odi.Data.Memory = value; }} else field = value; }} @@ -387,7 +387,7 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) { var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -467,7 +467,7 @@ public MemoryOwner InstructionMemory readonly get {{ if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; + return odi.Data.Memory; else return field; }} @@ -475,8 +475,8 @@ private set {{ if (DataIndex is OpDataIndex odi) {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; + odi.Data.Memory.Dispose(); + odi.Data.Memory = value; }} else field = value; }} @@ -501,7 +501,7 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i if (instruction.Operands?.AsList() is List operands) { - body2.AppendLine("foreach (var o in index.Buffer[index.Index])") + body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -590,7 +590,7 @@ public MemoryOwner InstructionMemory readonly get {{ if (DataIndex is OpDataIndex odi) - return odi.Buffer[odi.Index].Memory; + return odi.Data.Memory; else return field; }} @@ -598,8 +598,8 @@ private set {{ if (DataIndex is OpDataIndex odi) {{ - odi.Buffer[odi.Index].Memory.Dispose(); - odi.Buffer[odi.Index].Memory = value; + odi.Data.Memory.Dispose(); + odi.Data.Memory = value; }} else field = value; }} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 7a9de3e958..7ece8f0c82 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -26,7 +26,7 @@ public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, Compiler if (type is PointerType pointerType) { type = pointerType.BaseType; - var inst = compiler.Builder.Buffer.Insert(compiler.Builder.Position++, new OpLoad(compiler.Context.Types[type], compiler.Context.Bound++, result.Id, null)); + var inst = compiler.Builder.Insert(new OpLoad(compiler.Context.Types[type], compiler.Context.Bound++, result.Id, null)); result = new(inst.ResultId, inst.ResultType); } return result; @@ -172,7 +172,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return source; var resultType = context.GetOrRegister(Type); - var result = builder.Buffer.Insert(builder.Position++, new OpAccessChain(variable, resultType, source.Id, [.. indexes])); + var result = builder.Insert(new OpAccessChain(variable, resultType, source.Id, [.. indexes])); return new(result.ResultId, resultType); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 37fc7969da..7d80309f00 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -71,13 +71,20 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil }; + // _ = (Type, Suffix) switch + // { + // (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), + // (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), + // _ => throw new NotImplementedException("") + // }; + var i = (Type, Suffix) switch { - (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), - (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), + (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), + (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), _ => throw new NotImplementedException("") }; - return new SpirvValue(i.IdResult, i.IdResultType, null); + return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); } } @@ -97,11 +104,11 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil }; var i = (Type, Suffix) switch { - (ScalarType, { Size: > 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, DoubleValue)), - (ScalarType, { Size: <= 32 }) => compiler.Context.Buffer.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, (float)DoubleValue)), + (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, DoubleValue)), + (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, (float)DoubleValue)), _ => throw new NotImplementedException("") }; - return new SpirvValue(i.IdResult, i.IdResultType, null); + return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); } } @@ -120,10 +127,10 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { var i = Value switch { - true => compiler.Context.Buffer.Add(new OpConstantTrue(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)), - false => compiler.Context.Buffer.Add(new OpConstantFalse(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)) + true => compiler.Context.Add(new OpConstantTrue(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)), + false => compiler.Context.Add(new OpConstantFalse(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)) }; - return new SpirvValue(i.IdResult, i.IdResultType, null); + return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); } } @@ -263,7 +270,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); indexLiteral.Compile(table, shader, compiler); var index = context.CreateConstant(indexLiteral).Id; - result.Id = compiler.Builder.Buffer.Insert(compiler.Builder.Position++, new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); + result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); } return result; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index adeaa10c40..266a4a09a3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -52,25 +52,22 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf _ => throw new InvalidOperationException(), }); } - else if (instruction.Op == Op.OpTypePointer) + else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is {} pointerInstruction) { - OpTypePointer pointerInstruction = instruction; var innerType = types[pointerInstruction.Type]; types.Add(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); } - else if (instruction.Op == Op.OpTypeVoid) + else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is {} voidInstruction) { - types.Add(((OpTypeVoid)instruction).ResultId, ScalarType.From("void")); + types.Add(voidInstruction.ResultId, ScalarType.From("void")); } - else if (instruction.Op == Op.OpTypeVector) + else if (instruction.Op == Op.OpTypeVector && (OpTypeVector)instruction is {} vectorInstruction) { - OpTypeVector vectorInstruction = instruction; var innerType = (ScalarType)types[vectorInstruction.ComponentType]; types.Add(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); } - else if (instruction.Op == Op.OpTypeStruct) + else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is {} typeStructInstruction) { - OpTypeStruct typeStructInstruction = instruction; var structName = names[typeStructInstruction.ResultId]; var fieldsData = typeStructInstruction.Values; var fields = new List<(string Name, SymbolType Type)>(); @@ -83,9 +80,8 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf } types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); } - else if (instruction.Op == Op.OpTypeFunction) + else if (instruction.Op == Op.OpTypeFunction && (OpTypeFunction)instruction is {} typeFunctionInstruction) { - OpTypeFunction typeFunctionInstruction = instruction; var returnType = types[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); foreach (var operand in typeFunctionInstruction.Values) @@ -113,9 +109,8 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade var symbols = new List(); foreach (var instruction in buffer) { - if (instruction.Op == Op.OpVariable) + if (instruction.Op == Op.OpVariable && (OpVariable)instruction is {} variableInstruction) { - OpVariable variableInstruction = instruction; var variableName = names[variableInstruction.ResultId]; var variableType = types[variableInstruction.ResultType]; @@ -202,7 +197,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) foreach (var mixin in Mixins) { // Import types and variables/functions - context.Buffer.FluentAdd(new OpSDSLImportShader(context.Bound++, new(mixin.Name)), out var shader); + context.FluentAdd(new OpSDSLImportShader(context.Bound++, new(mixin.Name)), out var shader); var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; @@ -211,23 +206,23 @@ public void Compile(CompilerUnit compiler, SymbolTable table) if (c.Id.Kind == SymbolKind.Variable) { var variableTypeId = context.GetOrRegister(c.Type); - var variable = context.Buffer.Add(new OpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader.ResultId)); - context.Module.InheritedVariables.Add(c.Id.Name, new(variable, c.Id.Name)); - table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.IdResult }); + context.FluentAdd(new OpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader.ResultId), out var variable); + context.Module.InheritedVariables.Add(c.Id.Name, new(variable.ResultId, variable.ResultType, variable.VariableName)); + table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId }); } else if (c.Id.Kind == SymbolKind.Method) { var functionType = (FunctionType)c.Type; var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.Buffer.FluentAdd(new OpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader.ResultId), out var function); + context.FluentAdd(new OpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader.ResultId), out var function); context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId, c.Id.Name, functionType)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); } } // Mark inherit - context.Buffer.Add(new OpSDSLMixinInherit(shader.ResultId)); + context.Add(new OpSDSLMixinInherit(shader.ResultId)); context.Module.InheritedMixins.Add(shaderType); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index fef771a979..9894c7fcce 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -83,31 +83,30 @@ public sealed class ShaderMember( public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - #warning replace - // var (builder, context, _) = compiler; - // var registeredType = context.GetOrRegister(Type); - // var variable = context.Bound++; - // // TODO: Add a StreamSDSL storage class? - // context.Buffer.AddOpVariable(variable, registeredType, Specification.StorageClass.Private, null); - // context.Variables.Add(Name, new(variable, registeredType, Name)); - // if (Semantic != null) - // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name); - // context.AddName(variable, Name); - - // var sid = - // new SymbolID - // ( - // Name, - // TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, - // StreamKind switch - // { - // StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, - // _ => Storage.None - // } - // ); - // var symbol = new Symbol(sid, Type, variable); - // table.CurrentShader.Components.Add(symbol); - // table.CurrentFrame.Add(Name, symbol); + var (builder, context, _) = compiler; + var registeredType = context.GetOrRegister(Type); + var variable = context.Bound++; + // TODO: Add a StreamSDSL storage class? + context.Add(new OpVariable(registeredType, variable, Specification.StorageClass.Private, null)); + context.Variables.Add(Name, new(variable, registeredType, Name)); + if (Semantic != null) + context.Add(new OpDecorate(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name)); + context.AddName(variable, Name); + + var sid = + new SymbolID + ( + Name, + TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, + StreamKind switch + { + StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, + _ => Storage.None + } + ); + var symbol = new Symbol(sid, Type, variable); + table.CurrentShader.Components.Add(symbol); + table.CurrentFrame.Add(Name, symbol); } public override string ToString() @@ -204,7 +203,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler s.Compile(table, shader, compiler); table.Pop(); } - builder.EndFunction(context); + builder.EndFunction(); } else throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index a19d43e4c7..6077fd4020 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -208,7 +208,7 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? - context.Buffer.Add(new OpVariable(variable, pointerType, Specification.StorageClass.Uniform, null)); + context.Add(new OpVariable(pointerType, variable, Specification.StorageClass.Uniform, null)); context.Variables.Add(Name, new(variable, pointerType, Name)); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index a194976b75..557733f5d3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -146,16 +146,14 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var registeredType = context.GetOrRegister(new PointerType(Type!, Specification.StorageClass.Function)); foreach (var d in Variables) { - // var variable = context.Bound++; - // var instruction = builder.Buffer.InsertOpVariable(builder.Position++, variable, registeredType, Specification.StorageClass.Function, null); - // context.AddName(variable, d.Variable); + var variable = context.Bound++; + builder.Insert(new OpVariable(registeredType, variable, Specification.StorageClass.Function, null)); + context.AddName(variable, d.Variable); - // table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); - // if (builder.CurrentFunction is SpirvFunction f) - // f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); -#warning replace - throw new NotImplementedException(); + if (builder.CurrentFunction is SpirvFunction f) + f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); } } public override string ToString() @@ -170,25 +168,23 @@ public class Assign(TextLocation info) : Statement(info) public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - // var (builder, context, _) = compiler; - // foreach (var variable in Variables) - // { - // var target = variable.Variable.Compile(table, shader, compiler); - // var source = variable.Value!.Compile(table, shader, compiler); - // if (variable.Variable.Type is not PointerType) - // throw new InvalidOperationException("can only assign to pointer type"); - // if (variable.Value!.Type is PointerType p) - // { - // var sourceLoad = context.Bound++; - // var underlyingType = context.GetOrRegister(p.BaseType); - // builder.Buffer.InsertOpLoad(builder.Position++, sourceLoad, underlyingType, source.Id, Specification.MemoryAccessMask.None); - // source = new(sourceLoad, underlyingType); - // } - - // var instruction = builder.Buffer.InsertOpStore(builder.Position++, target.Id, source.Id, null); - // } -#warning replace - throw new NotImplementedException(); + var (builder, context, _) = compiler; + foreach (var variable in Variables) + { + var target = variable.Variable.Compile(table, shader, compiler); + var source = variable.Value!.Compile(table, shader, compiler); + if (variable.Variable.Type is not PointerType) + throw new InvalidOperationException("can only assign to pointer type"); + if (variable.Value!.Type is PointerType p) + { + var sourceLoad = context.Bound++; + var underlyingType = context.GetOrRegister(p.BaseType); + builder.Insert(new OpLoad(underlyingType, sourceLoad, source.Id, Specification.MemoryAccessMask.None)); + source = new(sourceLoad, underlyingType); + } + + builder.Insert(new OpStore(target.Id, source.Id, null)); + } } public override string ToString() { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 6267679a28..217f9e24ba 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -12,113 +12,104 @@ public partial class SpirvBuilder public SpirvValue BinaryOperation(SpirvContext context, int resultType, in SpirvValue left, Operator op, in SpirvValue right, string? name = null) { - // var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch - // { - // (Operator.Plus, SymbolType l, SymbolType r) - // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpIAdd(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Plus, ScalarType l, ScalarType r) - // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpFAdd(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Minus, SymbolType l, SymbolType r) - // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpISub(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Minus, SymbolType l, SymbolType r) - // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpFSub(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Mul, SymbolType l, SymbolType r) - // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpIMul(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Mul, SymbolType l, SymbolType r) - // when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpFMul(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Div, SymbolType l, SymbolType r) - // when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) - // => Buffer.InsertOpUDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Div, SymbolType l, SymbolType r) - // when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpSDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Div, SymbolType l, SymbolType r) - // when l.IsFloatingVector() && r.IsFloatingVector() - // => Buffer.InsertOpFDiv(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Mod, SymbolType l, SymbolType r) - // when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() - // => Buffer.InsertOpUMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Mod, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) - // => Buffer.InsertOpSMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.Mod, SymbolType l, SymbolType r) - // when l.IsFloating() && r.IsNumber() - // => Buffer.InsertOpFMod(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.RightShift, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() - // => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.LeftShift, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() - // => Buffer.InsertOpShiftRightLogical(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.AND, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() - // => Buffer.InsertOpBitwiseAnd(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.OR, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() - // => Buffer.InsertOpBitwiseOr(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.XOR, SymbolType l, SymbolType r) - // when l.IsInteger() && r.IsInteger() - // => Buffer.InsertOpBitwiseXor(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - // => Buffer.InsertOpLogicalAnd(Position++, context.Bound++, resultType, left.Id, right.Id), - - // (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - // => Buffer.InsertOpLogicalOr(Position++, context.Bound++, resultType, left.Id, right.Id), - - // _ => throw new NotImplementedException() - // }; - // if (instruction.ResultId is int resultId) - // { - // if (name is not null) - // context.AddName(instruction, name); - // return new(instruction, name); - // } - // else throw new NotImplementedException("Instruction should have result id"); -#warning replace - throw new NotImplementedException(); + var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch + { + (Operator.Plus, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpIAdd(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Plus, ScalarType l, ScalarType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpFAdd(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Minus, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpISub(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Minus, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpFSub(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Mul, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpIMul(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Mul, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpFMul(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) + => Buffer.InsertData(Position++, new OpUDiv(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpSDiv(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Div, SymbolType l, SymbolType r) + when l.IsFloatingVector() && r.IsFloatingVector() + => Buffer.InsertData(Position++, new OpFDiv(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() + => Buffer.InsertData(Position++, new OpUMod(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) + => Buffer.InsertData(Position++, new OpSMod(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Mod, SymbolType l, SymbolType r) + when l.IsFloating() && r.IsNumber() + => Buffer.InsertData(Position++, new OpFMod(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.RightShift, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.LeftShift, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.AND, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertData(Position++, new OpBitwiseAnd(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.OR, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertData(Position++, new OpBitwiseOr(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.XOR, SymbolType l, SymbolType r) + when l.IsInteger() && r.IsInteger() + => Buffer.InsertData(Position++, new OpBitwiseXor(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertData(Position++, new OpLogicalAnd(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertData(Position++, new OpLogicalOr(resultType, context.Bound++, left.Id, right.Id)), + + _ => throw new NotImplementedException() + }; + + if (name is not null) + context.AddName(instruction.IdResult ?? -1, name); + return new(instruction, name); } public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - // Span paramsIds = stackalloc IdRef[parameters.Length]; - // var tmp = 0; - // foreach (var p in parameters) - // paramsIds[tmp++] = p.Id; - // return CallFunction(context, name, paramsIds); - #warning replace - throw new NotImplementedException(); + Span paramsIds = stackalloc int[parameters.Length]; + var tmp = 0; + foreach (var p in parameters) + paramsIds[tmp++] = p.Id; + return CallFunction(context, name, [.. paramsIds]); } - public SpirvValue CallFunction(SpirvContext context, string name, Span parameters) + public SpirvValue CallFunction(SpirvContext context, string name, Span parameters) { - // var func = FindFunction(context, name); + var func = FindFunction(context, name); - // var fcall = Buffer.InsertOpFunctionCall(Position++, context.Bound++, context.GetOrRegister(func.FunctionType.ReturnType), func.Id, parameters); - // return new(fcall, func.Name); - #warning replace - throw new NotImplementedException(); + var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(func.FunctionType.ReturnType), context.Bound++, func.Id, [.. parameters])); + return new(fcall, func.Name); } private static SpirvFunction FindFunction(SpirvContext context, string name) @@ -128,13 +119,10 @@ private static SpirvFunction FindFunction(SpirvContext context, string name) return func; } - public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) + public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { - // var instruction = Buffer.InsertOpCompositeConstruct(Position++, context.Bound++, context.GetOrRegister(literal.Type), values); - // return new(instruction); - - #warning replace - throw new NotImplementedException(); + var instruction = Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(literal.Type), context.Bound++, [.. values])); + return new(instruction.ResultId, instruction.ResultType); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 2a7ae65c6a..9de9ceaae3 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -8,31 +8,25 @@ public partial class SpirvBuilder { public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { - // var i = Buffer.InsertOpLabel(Position++, context.Bound++); - // Buffer.InsertOpUnreachable(Position); - // var result = new SpirvBlock(i, CurrentFunction ?? throw new NotImplementedException(), name); - // return result; - #warning replace - throw new NotImplementedException(); + var i = Buffer.Insert(Position++, new OpLabel(context.Bound++)); + Buffer.Insert(Position, new OpUnreachable()); + var result = new SpirvBlock(i.ResultId, CurrentFunction ?? throw new NotImplementedException(), name); + return result; } public void Return(in SpirvValue? value = null) { - // _ = value switch - // { - // SpirvValue v => Buffer.InsertOpReturnValue(Position++, v.Id).WordCount, - // _ => Buffer.InsertOpReturn(Position++).WordCount - // }; - // CleanBlock(); - #warning replace - throw new NotImplementedException(); + _ = value switch + { + SpirvValue v => Buffer.InsertData(Position++, new OpReturnValue(v.Id)), + _ => Buffer.InsertData(Position++, new OpReturn()) + }; + CleanBlock(); } public void CleanBlock() { - if (Buffer.Instructions[Position].OpCode == Specification.Op.OpUnreachable) - { - Buffer.Instructions.RemoveAt(Position); - } + if (Buffer[Position].Op == Specification.Op.OpUnreachable) + Buffer.RemoveAt(Position); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index b41770a24d..9ab8b27628 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; @@ -9,48 +10,38 @@ public partial class SpirvBuilder { public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.None) { - // foreach(var t in ftype.ParameterTypes) - // context.GetOrRegister(t); - // var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(ftype.ReturnType), mask, context.GetOrRegister(ftype)); - // Position = Buffer.Instructions.Count; - // context.AddName(func, name); - // var result = new SpirvFunction(func.ResultId!.Value, name, ftype); - // CurrentFunction = result; - // context.Module.Functions.Add(name, result); - // return result; - #warning replace - throw new NotImplementedException(); + foreach(var t in ftype.ParameterTypes) + context.GetOrRegister(t); + Buffer.FluentAdd(new OpFunction(context.GetOrRegister(ftype.ReturnType), context.Bound++, mask, context.GetOrRegister(ftype)), out var func); + Position = Buffer.Count; + context.AddName(func, name); + var result = new SpirvFunction(func.ResultId, name, ftype); + CurrentFunction = result; + context.Module.Functions.Add(name, result); + return result; } - public void EndFunction(SpirvContext context) - { - // Buffer.InsertOpFunctionEnd(Position++); - #warning replace - throw new NotImplementedException(); - } + public void EndFunction() => Buffer.Insert(Position++, new OpFunctionEnd()); public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) { - // var p = Buffer.InsertOpFunctionParameter(Position++, context.Bound++, context.GetOrRegister(type)); - // context.AddName(p, name); - // CurrentFunction!.Value.Parameters.Add(name, new(p, name)); - // return new(p, name); - #warning replace - throw new NotImplementedException(); + var p = Buffer.Insert(Position++, new OpFunctionParameter(context.GetOrRegister(type), context.Bound++)); + context.AddName(p, name); + var value = new SpirvValue(p.ResultId, p.ResultType, name); + CurrentFunction!.Value.Parameters.Add(name, value); + return value; } public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.None) { - // var func = Buffer.AddOpFunction(context.Bound++, context.GetOrRegister(type.ReturnType), mask, context.GetOrRegister(type)); - // context.AddName(func, name); - // context.SetEntryPoint(execModel, func, name, variables); - // var result = new SpirvFunction(func.ResultId!.Value, name, type); - // if(!variables.IsEmpty) - // foreach(var p in variables) - // context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); - // CurrentFunction = result; - // return result; - #warning replace - throw new NotImplementedException(); + Buffer.FluentAdd(new OpFunction(context.GetOrRegister(type.ReturnType), context.Bound++, mask, context.GetOrRegister(type)), out var func); + context.AddName(func, name); + context.SetEntryPoint(execModel, func, name, variables); + var result = new SpirvFunction(func.ResultId, name, type); + if(!variables.IsEmpty) + foreach(var p in variables) + context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); + CurrentFunction = result; + return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 2281307831..6893a172d7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Spirv.Building; // Should have utility functions to add instruction to the buffer public partial class SpirvBuilder() { - public NewSpirvBuffer Buffer { get; init; } = new(); + NewSpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; private set; } public SpirvBlock? CurrentBlock { get; private set; } public int Position { get; internal set; } = 0; @@ -33,43 +33,44 @@ public void SetPositionTo(TBlock block, bool beggining = false) (int)Op.OpUnreachable, (int)Op.OpTerminateInvocation ]; - var wid = 0; - foreach (var e in Buffer.Instructions) + var pos = -1; + foreach (var e in Buffer) { - if (e.ResultId is int id && id == block.Id) + pos += 1; + if (e.Data.IdResult is int id && id == block.Id) { blockFound = true; // In case we want to top at the beginning of the block - if(beggining) + if (beggining) { - Position = wid + e.WordCount; + Position = pos; return; } } - if (block is SpirvBlock && blockFound && blockTermination.Contains((int)e.OpCode)) + if (block is SpirvBlock && blockFound && blockTermination.Contains((int)e.Op)) { - Position = wid; + Position = pos; return; } - else if (block is SpirvFunction && blockFound && e.OpCode == Op.OpFunctionEnd) + else if (block is SpirvFunction && blockFound && e.Op == Op.OpFunctionEnd) { - Position = wid; + Position = pos; return; } - - wid += e.WordCount; } - Position = Buffer.Instructions.Count; + Position = Buffer.Count; } - public SpirvBuffer Build(SpirvContext context) - { - context.Buffer.Sort(); - return SpirvBuffer.Merge(context.Buffer, Buffer); - } + + public T Insert(in T value) + where T : struct, IMemoryInstruction + => Buffer.Insert(Position++, value); + + [Obsolete("Use the insert method instead")] + public NewSpirvBuffer GetBuffer() => Buffer; public override string ToString() { - return new SpirvDis(Buffer).Disassemble(); + return Spv.Dis(Buffer); } } diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 6a966e4644..3b16d54614 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -31,14 +31,21 @@ public void Deconstruct(out SpirvBuilder builder, out SpirvContext context, out module = Module; } +#pragma warning disable CS0618 // Type or member is obsolete + public NewSpirvBuffer ToBuffer() + { + Context.Sort(); + return NewSpirvBuffer.Merge(Context.GetBuffer(), Builder.GetBuffer()); + } public override string ToString() { var builder = new StringBuilder(); builder .AppendLine("Context : ") - .AppendLine(Spv.Dis(Context.Buffer)) + .AppendLine(Spv.Dis(Context.GetBuffer())) .AppendLine("Functions : ") - .AppendLine(Spv.Dis(Builder.Buffer)); + .AppendLine(Spv.Dis(Builder.GetBuffer())); return builder.ToString(); } +#pragma warning restore CS0618 // Type or member is obsolete } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9e52bb8363..d18dc7415b 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -25,7 +25,7 @@ public class SpirvContext(SpirvModule module) public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; - public NewSpirvBuffer Buffer { get; set; } = new(); + NewSpirvBuffer Buffer { get; set; } = new(); public void PutShaderName(string name) { @@ -48,17 +48,17 @@ public int AddConstant(TScalar value) { var data = value switch { - byte v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("byte")), v)), - sbyte v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("sbyte")), v)), - ushort v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("ushort")), v)), - short v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("short")), v)), - uint v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("uint")), v)), - int v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("int")), v)), - ulong v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("ulong")), v)), - long v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("long")), v)), - Half v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("half")), v)), - float v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("float")), v)), - double v => Buffer.Add(new OpConstant(Bound++, GetOrRegister(ScalarType.From("bdouble")), v)), + byte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("byte")), Bound++, v)), + sbyte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("sbyte")), Bound++, v)), + ushort v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ushort")), Bound++, v)), + short v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("short")), Bound++, v)), + uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("uint")), Bound++, v)), + int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("int")), Bound++, v)), + ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ulong")), Bound++, v)), + long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("long")), Bound++, v)), + Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), + float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("float")), Bound++, v)), + double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("bdouble")), Bound++, v)), _ => throw new NotImplementedException() }; if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) @@ -155,9 +155,9 @@ public int GetOrRegister(SymbolType? type) // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; - Types[type] = instruction; - ReverseTypes[instruction] = type; - return instruction; + Types[type] = instruction ?? -1; + ReverseTypes[instruction ?? -1] = type; + return instruction ?? -1; } } @@ -184,10 +184,10 @@ int RegisterStructuredType(string name, StructuredType structSymbol) var result = Buffer.Add(new OpTypeStruct(Bound++, [.. types])); var id = result.IdResult; - AddName(id, name); + AddName(id ?? -1, name); for (var index = 0; index < structSymbol.Members.Count; index++) - AddMemberName(id, index, structSymbol.Members[index].Name); - return id; + AddMemberName(id ?? -1, index, structSymbol.Members[index].Name); + return id ?? -1; } @@ -200,16 +200,16 @@ int RegisterFunctionType(FunctionType functionType) var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); - return result.IdResult; + return result.IdResult ?? -1; } int RegisterPointerType(PointerType pointerType) { var baseType = GetOrRegister(pointerType.BaseType); - var result = Buffer.Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); + var result = Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); var id = result.IdResult; - AddName(id, pointerType.ToId()); - return id; + AddName(id ?? -1, pointerType.ToId()); + return id ?? -1; } public SpirvValue CreateConstant(Literal literal) @@ -233,22 +233,22 @@ public SpirvValue CreateConstant(Literal literal) // return result; var instruction = literal switch { - BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(Bound++, GetOrRegister(lit.Type))), - BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(Bound++, GetOrRegister(lit.Type))), + BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), + BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(GetOrRegister(lit.Type), Bound++)), IntegerLiteral lit => lit.Suffix switch { - { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (byte)lit.IntValue)), - { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (sbyte)lit.IntValue)), - { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (ushort)lit.IntValue)), - { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (short)lit.IntValue)), - { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), unchecked((uint)lit.IntValue))), - { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), lit.IntValue)), + { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (byte)lit.IntValue)), + { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), + { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), + { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), + { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), + { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), _ => throw new NotImplementedException() }, FloatLiteral lit => lit.Suffix.Size switch { - > 32 => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), lit.DoubleValue)), - _ => Buffer.Add(new OpConstant(Bound++, GetOrRegister(lit.Type), (float)lit.DoubleValue)), + > 32 => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.DoubleValue)), + _ => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (float)lit.DoubleValue)), }, _ => throw new NotImplementedException() }; @@ -265,6 +265,23 @@ public SpirvValue CreateConstant(Literal literal) return result; } + public OpData Add(in T value) + where T : struct, IMemoryInstruction + => Buffer.Add(value); + + + public SpirvContext FluentAdd(in T value, out T result) + where T : struct, IMemoryInstruction + { + Buffer.FluentAdd(value, out result); + return this; + } + + public void Sort() => Buffer.Sort(); + + [Obsolete("Use the insert method instead")] + public NewSpirvBuffer GetBuffer() => Buffer; + public override string ToString() { return Spv.Dis(Buffer); diff --git a/src/Stride.Shaders/Spirv/Processing/INanoPass.cs b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs index 46a116e959..21847d3d68 100644 --- a/src/Stride.Shaders/Spirv/Processing/INanoPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs @@ -13,5 +13,5 @@ namespace Stride.Shaders.Spirv.Processing; /// public interface INanoPass { - void Apply(SpirvBuffer buffer); + void Apply(NewSpirvBuffer buffer); } diff --git a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs index 5abc9b895f..57ed81b258 100644 --- a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs @@ -10,5 +10,5 @@ namespace Stride.Shaders.Spirv.Processing; public interface IPostProcessorSubPass { - void Apply(SpirvBuffer buffer, Instruction instruction); + void Apply(NewSpirvBuffer buffer, Instruction instruction); } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index d52ae6f346..b53517384c 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -29,7 +29,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int id) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - public void Process(SpirvBuffer buffer, SpirvContext context) + public void Process(NewSpirvBuffer buffer, SpirvContext context) { var entryPointVS = context.Module.Functions["VSMain"]; var entryPointPS = context.Module.Functions["PSMain"]; @@ -42,7 +42,7 @@ public void Process(SpirvBuffer buffer, SpirvContext context) if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) stream.Value.Stream.Output = true; } - GenerateStreamWrapper(buffer, context, Specification.ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -64,195 +64,210 @@ private static void PropagateStreamsFromPreviousStage(SortedList CreateStreams(SpirvBuffer buffer, SpirvContext context) + private SortedList CreateStreams(NewSpirvBuffer buffer, SpirvContext context) { var streams = new SortedList(); // Build name table SortedList nameTable = []; SortedList semanticTable = []; - foreach (var instruction in buffer.Instructions) + foreach (var instruction in buffer) { { - if ((instruction.OpCode == Op.OpName || instruction.OpCode == Op.OpMemberName) - && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n + if (instruction.Op == Op.OpName + && ((OpName)instruction) is + { + Target: int t, + Name: string n + } ) { - nameTable[t] = new(n.Value); + nameTable[t] = new(n); + } + else if (instruction.Op == Op.OpMemberName + && ((OpMemberName)instruction) is + { + Type: int t2, + Member: int m, + Name: string n2 + } + ) + { + throw new NotImplementedException("Member names not supported yet"); + // if (nameTable.TryGetValue(t2, out var nameId)) + // nameId.MemberNames[m] = n2; + // else + // nameTable[t2] = new($"unnamed_{t2}") { MemberNames = { [m] = n2 } }; } } { - #warning uncomment - // if (instruction.OpCode == Op.OpDecorateString - // && instruction.UnsafeAs().Decoration == Specification.Decoration.UserSemantic - // && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - // && instruction.TryGetOperand("semanticName", out LiteralString? name) && name is LiteralString n - // ) - // { - // semanticTable[t] = n.Value; - // } + if (instruction.Op == Op.OpDecorateString + && ((OpDecorate)instruction) is + { + Decoration: Decoration.UserSemantic, + Target: int t, + AdditionalString: string n + } + ) + { + semanticTable[t] = n; + } } } // Analyze streams - foreach (var instruction in buffer.Instructions) + foreach (var instruction in buffer) { - if (instruction.OpCode == Op.OpVariable - && (Specification.StorageClass)instruction.Operands[2] == Specification.StorageClass.Private) + if (instruction.Op == Op.OpVariable && ((OpVariable)instruction) is + { + Storageclass: StorageClass.Private, + ResultId: int + } variable + ) { - var name = nameTable.TryGetValue(instruction.Operands[1], out var nameId) + var name = nameTable.TryGetValue(variable.ResultId, out var nameId) ? nameId.Name - : $"unnamed_{instruction.Operands[1]}"; - var type = context.ReverseTypes[instruction.Operands[0]]; - semanticTable.TryGetValue(instruction.Operands[1], out var semantic); - streams.Add(instruction.ResultId!.Value, (new StreamInfo(semantic, name, type, instruction.ResultId!.Value), true)); + : $"unnamed_{variable.ResultId}"; + var type = context.ReverseTypes[variable.ResultType]; + semanticTable.TryGetValue(variable.ResultId, out var semantic); + streams.Add(variable.ResultId, (new StreamInfo(semantic, name, type, variable.ResultId), true)); } } return streams; } - private void GenerateStreamWrapper(SpirvBuffer buffer, SpirvContext context, Specification.ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) + private void GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) { - #warning replace - // ProcessMethod(buffer, entryPointId, streams); - - // var stage = executionModel switch - // { - // Specification.ExecutionModel.Fragment => "PS", - // Specification.ExecutionModel.Vertex => "VS", - // }; - // List<(StreamInfo Info, int Id)> inputStreams = []; - // List<(StreamInfo Info, int Id)> outputStreams = []; - // foreach (var stream in streams) - // { - // // Only direct access to global variables (not temporary variables created within function) - // if (!stream.Value.IsDirect) - // continue; - - // if (stream.Value.Stream.Input) - // { - // var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Input, context.Types[stream.Value.Stream.Type]); - // var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Input, null); - // context.AddName(variable, $"in_{stream.Value.Stream.Name}"); - - // if (stream.Value.Stream.Semantic != null) - // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); - - // inputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); - // } - - // if (stream.Value.Stream.Output) - // { - // var pointerType = (IdRef)context.Buffer.AddOpTypePointer(context.Bound++, Specification.StorageClass.Output, context.Types[stream.Value.Stream.Type]); - // var variable = context.Buffer.AddOpVariable(context.Bound++, pointerType, Specification.StorageClass.Output, null); - // context.AddName(variable, $"out_{stream.Value.Stream.Name}"); - - // if (stream.Value.Stream.Semantic != null) - // context.Buffer.AddOpDecorateString(variable, Specification.Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic); - - // outputStreams.Add((stream.Value.Stream, variable.ResultId.Value)); - // } - // } - - // var voidTypeId = context.Buffer.AddOpTypeVoid(context.Bound++); - - // // Add new entry point wrapper - // var newEntryPointFunctionType = context.Buffer.AddOpTypeFunction(context.Bound++, voidTypeId, []); - // var newEntryPointFunction = buffer.AddOpFunction(context.Bound++, voidTypeId, Specification.FunctionControlMask.None, newEntryPointFunctionType); - // buffer.AddOpLabel(context.Bound++); - // context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); - - // { - // // Copy read variables from streams - // foreach (var stream in inputStreams) - // { - // var baseType = ((PointerType)stream.Info.Type).BaseType; - // var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Id, null); - // buffer.AddOpStore(stream.Info.Id, loadedValue.ResultId!.Value, null); - // } - - // buffer.AddOpFunctionCall(context.Bound++, voidTypeId, entryPointId, Span.Empty); - - // foreach (var stream in outputStreams) - // { - // var baseType = ((PointerType)stream.Info.Type).BaseType; - // var loadedValue = buffer.AddOpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null); - // buffer.AddOpStore(stream.Id, loadedValue.ResultId!.Value, null); - // } - - // buffer.AddOpReturn(); - // buffer.AddOpFunctionEnd(); - - // Span pvariables = stackalloc IdRef[inputStreams.Count + outputStreams.Count]; - // for (int i = 0; i < inputStreams.Count; i++) - // pvariables[i] = inputStreams[i].Id; - // for (int i = 0; i < outputStreams.Count; i++) - // pvariables[inputStreams.Count + i] = outputStreams[i].Id; - // context.Buffer.AddOpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", pvariables); - // } + ProcessMethod(buffer, entryPointId, streams); + + var stage = executionModel switch + { + ExecutionModel.Fragment => "PS", + ExecutionModel.Vertex => "VS", + _ => throw new NotImplementedException() + }; + List<(StreamInfo Info, int Id)> inputStreams = []; + List<(StreamInfo Info, int Id)> outputStreams = []; + foreach (var stream in streams) + { + // Only direct access to global variables (not temporary variables created within function) + if (!stream.Value.IsDirect) + continue; + + if (stream.Value.Stream.Input) + { + context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[stream.Value.Stream.Type]), out var pointerType); + context.FluentAdd(new OpVariable(pointerType.ResultId, context.Bound++, StorageClass.Input, null), out var variable); + context.AddName(variable, $"in_{stream.Value.Stream.Name}"); + + if (stream.Value.Stream.Semantic != null) + context.Add(new OpDecorate(variable, Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic)); + + inputStreams.Add((stream.Value.Stream, variable.ResultId)); + } + + if (stream.Value.Stream.Output) + { + context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Output, context.Types[stream.Value.Stream.Type]), out var pointerType) + .FluentAdd(new OpVariable(context.Bound++, pointerType, StorageClass.Output, null), out var variable); + context.AddName(variable, $"out_{stream.Value.Stream.Name}"); + + if (stream.Value.Stream.Semantic != null) + context.Add(new OpDecorate(variable, Decoration.UserSemantic, null, null, stream.Value.Stream.Semantic)); + + outputStreams.Add((stream.Value.Stream, variable.ResultId)); + } + } + + context.FluentAdd(new OpTypeVoid(context.Bound++), out var voidType); + + // Add new entry point wrapper + context.FluentAdd(new OpTypeFunction(context.Bound++, voidType, []), out var newEntryPointFunctionType); + buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType) , out var newEntryPointFunction); + buffer.Add(new OpLabel(context.Bound++)); + context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); + + { + // Copy read variables from streams + foreach (var stream in inputStreams) + { + var baseType = ((PointerType)stream.Info.Type).BaseType; + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null), out var loadedValue); + buffer.Add(new OpStore(stream.Info.Id, loadedValue.ResultId, null)); + } + + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPointId, [])); + + foreach (var stream in outputStreams) + { + var baseType = ((PointerType)stream.Info.Type).BaseType; + buffer.FluentAdd(new OpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null), out var loadedValue); + buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); + } + + buffer.Add(new OpReturn()); + buffer.Add(new OpFunctionEnd()); + + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count]; + for (int i = 0; i < inputStreams.Count; i++) + pvariables[i] = inputStreams[i].Id; + for (int i = 0; i < outputStreams.Count; i++) + pvariables[inputStreams.Count + i] = outputStreams[i].Id; + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); + } } /// /// Figure out (recursively) which streams are being read from and written to. /// - private void ProcessMethod(SpirvBuffer buffer, int functionId, SortedList streams) + private void ProcessMethod(NewSpirvBuffer buffer, int functionId, SortedList streams) { var methodStart = FindMethodStart(buffer, functionId); - for (var index = methodStart; index < buffer.Instructions.Count; index++) + for (var index = methodStart; index < buffer.Count; index++) { - var instruction = buffer.Instructions[index]; - if (instruction.OpCode == Op.OpFunctionEnd) + var instruction = buffer[index]; + if (instruction.Op == Op.OpFunctionEnd) break; - if (instruction.OpCode == Op.OpLoad - || instruction.OpCode == Op.OpStore) + if (instruction.Op is Op.OpLoad && (OpLoad)instruction is { } load) { - var operandIndex = instruction.OpCode == Op.OpLoad ? 2 : 0; - if (streams.TryGetValue(instruction.Operands[operandIndex], out var streamInfo)) - { - // If read after a write (within same shader), we are not reading the variable from previous stage => not marking as Read - if (instruction.OpCode == Op.OpLoad && !streamInfo.Stream.Write) - streamInfo.Stream.Read = true; - if (instruction.OpCode == Op.OpStore) - streamInfo.Stream.Write = true; - } + if (streams.TryGetValue(load.Pointer, out var streamInfo) && !streamInfo.Stream.Write) + streamInfo.Stream.Read = true; } - else if (instruction.OpCode == Op.OpAccessChain) + else if(instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { - if (streams.TryGetValue(instruction.Operands[2], out var streamInfo)) + if (streams.TryGetValue(store.Pointer, out var streamInfo)) + streamInfo.Stream.Write = true; + } + else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) + { + if (streams.TryGetValue(accessChain.BaseId, out var streamInfo)) { // Map the pointer access as access to the underlying stream (if any) // i.e., streams.A.B will share same streamInfo as streams.A // TODO: what happens in case of partial write? - streams.Add(instruction.ResultId!.Value, (streamInfo.Stream, false)); + streams.Add(accessChain.ResultId, (streamInfo.Stream, false)); } } - else if (instruction.OpCode == Op.OpFunctionCall) + else if (instruction.Op == Op.OpFunctionCall && (OpFunctionCall)instruction is { } call) { // Process call - var calledFunctionId = instruction.Operands[2]; - ProcessMethod(buffer, calledFunctionId, streams); + ProcessMethod(buffer, call.Function, streams); } } } - public int FindMethodStart(SpirvBuffer buffer, int functionId) + public int FindMethodStart(NewSpirvBuffer buffer, int functionId) { - int? start = null; - for (var index = 0; index < buffer.Instructions.Count; index++) + for (var index = 0; index < buffer.Count; index++) { - var instruction = buffer.Instructions[index]; - if (instruction.OpCode == Op.OpFunction - && instruction.ResultId == functionId) - { + var instruction = buffer[index]; + if (instruction.Op is Op.OpFunction) return index; - } } - throw new NotImplementedException(); } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 41d3eded1e..445a8b49a5 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -1,160 +1,160 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using static Stride.Shaders.Spirv.Specification; +// using Stride.Shaders.Spirv.Core; +// using Stride.Shaders.Spirv.Core.Buffers; +// using System; +// using System.Collections.Generic; +// using System.Linq; +// using System.Text; +// using System.Threading.Tasks; +// using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing; +// namespace Stride.Shaders.Spirv.Processing; -/// -/// Remove duplicate simple types. -/// Should be applied before the IdRefOffsetter. -/// -public struct TypeDuplicateRemover : INanoPass -{ +// /// +// /// Remove duplicate simple types. +// /// Should be applied before the IdRefOffsetter. +// /// +// public struct TypeDuplicateRemover : INanoPass +// { - public readonly void Apply(SpirvBuffer buffer) - { - for (var index = 0; index < buffer.Instructions.Count; index++) - { - var i = buffer.Instructions[index]; - if (i.OpCode == Op.OpTypeVoid || i.OpCode == Op.OpTypeInt || i.OpCode == Op.OpTypeFloat) - { - for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) - { - var j = buffer.Instructions[index2]; - if ( - (j.OpCode == Op.OpTypeVoid || j.OpCode == Op.OpTypeInt || - j.OpCode == Op.OpTypeFloat) - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words); - } - } - } - } +// public readonly void Apply(NewSpirvBuffer buffer) +// { +// for (var index = 0; index < buffer.Instructions.Count; index++) +// { +// var i = buffer.Instructions[index]; +// if (i.OpCode == Op.OpTypeVoid || i.OpCode == Op.OpTypeInt || i.OpCode == Op.OpTypeFloat) +// { +// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) +// { +// var j = buffer.Instructions[index2]; +// if ( +// (j.OpCode == Op.OpTypeVoid || j.OpCode == Op.OpTypeInt || +// j.OpCode == Op.OpTypeFloat) +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words); +// } +// } +// } +// } - for (var index = 0; index < buffer.Instructions.Count; index++) - { - var i = buffer.Instructions[index]; - if (i.OpCode == Op.OpTypeVector) - { - for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) - { - var j = buffer.Instructions[index2]; - if ( - j.OpCode == Op.OpTypeVector - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words); - } - } - } - } - for (var index = 0; index < buffer.Instructions.Count; index++) - { - var i = buffer.Instructions[index]; - if (i.OpCode == Op.OpTypeMatrix) - { - for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) - { - var j = buffer.Instructions[index2]; - if ( - j.OpCode == Op.OpTypeMatrix - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words); - } - } - } - } - for (var index = 0; index < buffer.Instructions.Count; index++) - { - var i = buffer.Instructions[index]; - if (i.OpCode == Op.OpTypePointer) - { - for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) - { - var j = buffer.Instructions[index2]; - if ( - j.OpCode == Op.OpTypePointer - && i.ResultId != j.ResultId - && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words); - } - } - } - } - for (var index = 0; index < buffer.Instructions.Count; index++) - { - var i = buffer.Instructions[index]; - if (i.OpCode == Op.OpName) - { - for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) - { - var j = buffer.Instructions[index2]; - if ( - j.OpCode == Op.OpName - && i.Operands[0] == j.Operands[0] - && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) - ) - { - ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); - SetOpNop(j.Words); - } - } - } - } - } +// for (var index = 0; index < buffer.Instructions.Count; index++) +// { +// var i = buffer.Instructions[index]; +// if (i.OpCode == Op.OpTypeVector) +// { +// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) +// { +// var j = buffer.Instructions[index2]; +// if ( +// j.OpCode == Op.OpTypeVector +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words); +// } +// } +// } +// } +// for (var index = 0; index < buffer.Instructions.Count; index++) +// { +// var i = buffer.Instructions[index]; +// if (i.OpCode == Op.OpTypeMatrix) +// { +// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) +// { +// var j = buffer.Instructions[index2]; +// if ( +// j.OpCode == Op.OpTypeMatrix +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words); +// } +// } +// } +// } +// for (var index = 0; index < buffer.Instructions.Count; index++) +// { +// var i = buffer.Instructions[index]; +// if (i.OpCode == Op.OpTypePointer) +// { +// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) +// { +// var j = buffer.Instructions[index2]; +// if ( +// j.OpCode == Op.OpTypePointer +// && i.ResultId != j.ResultId +// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words); +// } +// } +// } +// } +// for (var index = 0; index < buffer.Instructions.Count; index++) +// { +// var i = buffer.Instructions[index]; +// if (i.OpCode == Op.OpName) +// { +// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) +// { +// var j = buffer.Instructions[index2]; +// if ( +// j.OpCode == Op.OpName +// && i.Operands[0] == j.Operands[0] +// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) +// ) +// { +// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); +// SetOpNop(j.Words); +// } +// } +// } +// } +// } - static void ReplaceRefs(int from, int to, SpirvBuffer buffer) - { - foreach (var i in buffer.Instructions) - { - var opcode = i.OpCode; - foreach (var op in i) - { - if (op.Kind == OperandKind.IdRef && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - if (op.Words[0] == from || op.Words[1] == from) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } - } +// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) +// { +// foreach (var i in buffer.Instructions) +// { +// var opcode = i.OpCode; +// foreach (var op in i) +// { +// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) +// op.Words[0] = to; +// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// else if (op.Kind == OperandKind.PairIdRefIdRef) +// { +// if (op.Words[0] == from || op.Words[1] == from) +// { +// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; +// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; +// } +// } +// } +// } +// } - static void SetOpNop(Span words) - { - words[0] = words.Length << 16; - words[1..].Clear(); - } -} +// static void SetOpNop(Span words) +// { +// words[0] = words.Length << 16; +// words[1..].Clear(); +// } +// } diff --git a/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs b/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs index 28f22f6d74..635a875ff6 100644 --- a/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs +++ b/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs @@ -7,7 +7,7 @@ namespace Stride.Shaders.Spirv; -public record struct Mixin(string Name, SpirvBuffer Buffer); +public record struct Mixin(string Name, NewSpirvBuffer Buffer); public class MixinStorage @@ -17,12 +17,12 @@ public class MixinStorage private MixinStorage(){} - public static void RegisterOrUpdate(string name, SpirvBuffer buffer) + public static void RegisterOrUpdate(string name, NewSpirvBuffer buffer) { Instance.Storage[name] = new(name, buffer); } - public static bool TryRegister(string name, SpirvBuffer buffer) + public static bool TryRegister(string name, NewSpirvBuffer buffer) { return Instance.Storage.TryAdd(name, new(name, buffer)); } diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 99c4b2fffc..c142313525 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -1,4 +1,5 @@ using System.Numerics; +using System.Runtime.CompilerServices; using System.Text; using System.Text.Json; using CommunityToolkit.HighPerformance; @@ -80,7 +81,8 @@ readonly DisWriter AppendRepeatChar(char c, int count) if (data.WriteToConsole) for (int i = 0; i < count; i++) Console.Write(c); - builder.Append(c, count); + if (count > 0) + builder.Append(c, count); return this; } readonly DisWriter AppendLiteralNumber(T value) @@ -89,6 +91,21 @@ readonly DisWriter AppendLiteralNumber(T value) Append(value, ConsoleColor.Red).Append(' '); return this; } + readonly DisWriter AppendLiteralNumbers(Span words) + where T : struct, INumber + { + using var tmp = LiteralArray.From(words); + foreach (var value in tmp) + Append(value, ConsoleColor.Red).Append(' '); + return this; + } + readonly DisWriter AppendEnums(SpvOperand operand) + where T : Enum + { + foreach (ref var value in operand.Words) + Append(Unsafe.As(ref value).ToString(), ConsoleColor.Yellow).Append(' '); + return this; + } readonly DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) { @@ -222,75 +239,473 @@ public readonly void DisInstruction(in OpDataIndex instruction, in DisWriter wri Append(instruction.Op.ToString(), ConsoleColor.Blue).Append(' '); foreach (var operand in data) { - _ = (operand.Kind, operand.Quantifier) switch + + _ = operand.Kind switch { - (OperandKind.IdResult, _) => Append(""), - ( - OperandKind.LiteralInteger - or OperandKind.LiteralExtInstInteger - or OperandKind.LiteralSpecConstantOpInteger, - OperandQuantifier.One - ) => AppendLiteralNumber(operand.ToLiteral()), - (OperandKind.LiteralContextDependentNumber, OperandQuantifier.One) => AppendContextDependentNumber(operand, data, buffer), - (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => AppendIdRef(operand.ToLiteral()), - (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.ZeroOrMore) => AppendIdRefs(operand.Words), - (OperandKind.LiteralFloat, OperandQuantifier.One) => AppendLiteralNumber(operand.ToLiteral()), - (OperandKind.LiteralString, OperandQuantifier.One) => AppendLiteralString(operand.ToLiteral()), - (OperandKind.ImageOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FPFastMathMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.SelectionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.LoopControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FunctionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.MemorySemantics, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.MemoryAccess, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.KernelProfilingInfo, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.RayFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FragmentShadingRate, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.RawAccessChainOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.SourceLanguage, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.ExecutionModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.AddressingModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.MemoryModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.ExecutionMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.StorageClass, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.Dim, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.SamplerAddressingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.SamplerFilterMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.ImageFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.ImageChannelOrder, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.ImageChannelDataType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FPRoundingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FPDenormMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.QuantizationModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FPOperationMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.OverflowModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.LinkageType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.AccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.HostAccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FunctionParameterAttribute, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.Decoration, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.BuiltIn, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.Scope, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.GroupOperation, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.KernelEnqueueFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.Capability, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.RayQueryIntersection, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.RayQueryCommittedIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.RayQueryCandidateIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.PackedVectorFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.CooperativeMatrixOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.CooperativeMatrixLayout, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.CooperativeMatrixUse, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.CooperativeMatrixReduce, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.TensorClampMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.TensorAddressingOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.InitializationModeQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.LoadCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.StoreCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.NamedMaximumNumberOfRegisters, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandKind.FPEncoding, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + OperandKind.IdResult => Append(""), + OperandKind.LiteralInteger + or OperandKind.LiteralExtInstInteger + or OperandKind.LiteralSpecConstantOpInteger + => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => AppendLiteralNumber(operand.ToLiteral()), + (OperandQuantifier.ZeroOrMore, > 0) => AppendLiteralNumbers(operand.Words), + _ => throw new NotImplementedException("Unsupported literal integer quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.LiteralContextDependentNumber => AppendContextDependentNumber(operand, data, buffer), + OperandKind.IdRef or OperandKind.IdResultType => + (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => AppendIdRef(operand.ToLiteral()), + (OperandQuantifier.ZeroOrMore, > 0) => AppendIdRefs(operand.Words), + (OperandQuantifier.ZeroOrMore or OperandQuantifier.ZeroOrOne, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported id ref quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.LiteralFloat => AppendLiteralNumber(operand.ToLiteral()), + OperandKind.LiteralString => AppendLiteralString(operand.ToLiteral()), + OperandKind.ImageOperands => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FPFastMathMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.SelectionControl => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.LoopControl => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FunctionControl => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.MemorySemantics => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.MemoryAccess => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.KernelProfilingInfo => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.RayFlags => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FragmentShadingRate => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.RawAccessChainOperands => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.SourceLanguage => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.ExecutionModel => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.AddressingModel => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.MemoryModel => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.ExecutionMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.StorageClass => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.Dim => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.SamplerAddressingMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.SamplerFilterMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.ImageFormat => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.ImageChannelOrder => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.ImageChannelDataType => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FPRoundingMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FPDenormMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.QuantizationModes => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FPOperationMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.OverflowModes => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.LinkageType => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.AccessQualifier => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.HostAccessQualifier => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FunctionParameterAttribute => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.Decoration => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.BuiltIn => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.Scope => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.GroupOperation => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.KernelEnqueueFlags => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.Capability => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.RayQueryIntersection => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.RayQueryCommittedIntersectionType => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.RayQueryCandidateIntersectionType => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.PackedVectorFormat => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.CooperativeMatrixOperands => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.CooperativeMatrixLayout => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.CooperativeMatrixUse => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.CooperativeMatrixReduce => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.TensorClampMode => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.TensorAddressingOperands => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.InitializationModeQualifier => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.LoadCacheControl => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.StoreCacheControl => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.NamedMaximumNumberOfRegisters => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, + OperandKind.FPEncoding => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), }; + // _ = (operand.Kind, operand.Quantifier) switch + // { + // (OperandKind.IdResult, _) => Append(""), + // ( + // OperandKind.LiteralInteger + // or OperandKind.LiteralExtInstInteger + // or OperandKind.LiteralSpecConstantOpInteger, + // OperandQuantifier.One + // ) => AppendLiteralNumber(operand.ToLiteral()), + // (OperandKind.LiteralContextDependentNumber, OperandQuantifier.One) => AppendContextDependentNumber(operand, data, buffer), + // (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => AppendIdRef(operand.ToLiteral()), + // (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.ZeroOrMore) => AppendIdRefs(operand.Words), + // (OperandKind.LiteralFloat, OperandQuantifier.One) => AppendLiteralNumber(operand.ToLiteral()), + // (OperandKind.LiteralString, OperandQuantifier.One) => AppendLiteralString(operand.ToLiteral()), + // (OperandKind.ImageOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPFastMathMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.SelectionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.LoopControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FunctionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.MemorySemantics, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.MemoryAccess, OperandQuantifier.One or OperandQuantifier.ZeroOrOne) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.KernelProfilingInfo, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.RayFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FragmentShadingRate, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.RawAccessChainOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.SourceLanguage, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.ExecutionModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.AddressingModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.MemoryModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.ExecutionMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.StorageClass, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.Dim, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.SamplerAddressingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.SamplerFilterMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.ImageFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.ImageChannelOrder, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.ImageChannelDataType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPRoundingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPDenormMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.QuantizationModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPOperationMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.OverflowModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.LinkageType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.AccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.HostAccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FunctionParameterAttribute, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.Decoration, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.BuiltIn, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.Scope, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.GroupOperation, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.KernelEnqueueFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.Capability, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.RayQueryIntersection, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.RayQueryCommittedIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.RayQueryCandidateIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.PackedVectorFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.CooperativeMatrixOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.CooperativeMatrixLayout, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.CooperativeMatrixUse, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.CooperativeMatrixReduce, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.TensorClampMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.TensorAddressingOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.InitializationModeQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.LoadCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.StoreCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.NamedMaximumNumberOfRegisters, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPEncoding, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // (OperandKind.FPEncoding, OperandQuantifier.ZeroOrOne) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + // _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), + // }; } AppendLine(""); } From 9b8297c8402be0cde2c6e021dfcfea2cd3ac6422 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Sep 2025 17:56:59 +0900 Subject: [PATCH 0447/1182] Added support for optional operands --- .../SPVGenerator.Instructions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 2932a17015..9e81d7327d 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -178,6 +178,9 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst // Body 2 body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); + // Optional operands + if (operand.Quantifier == "?") + body2.AppendLine("if (o.Words.Length > 0)"); if (typename.StartsWith("LiteralArray")) body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) From 64b784ed04dbacbeb25ea08687b91dca5c4f9176 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Sep 2025 17:58:09 +0900 Subject: [PATCH 0448/1182] Readded the SDSL prototype --- src/Stride.Shaders.Experiments/Examples.cs | 368 +++++++++--------- src/Stride.Shaders.Experiments/Program.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 4 + .../Spirv/Processing/StreamAnalyzer.cs | 6 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 328 +++++++++------- 6 files changed, 376 insertions(+), 338 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index ed6c894199..a5bd338f2e 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -18,7 +18,8 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using static Silk.NET.Core.Native.WinString; +using static Stride.Shaders.Spirv.Specification; +using SourceLanguage = Silk.NET.Shaderc.SourceLanguage; namespace Stride.Shaders.Experiments; @@ -297,194 +298,205 @@ class ShaderInfo public static void MergeSDSL() { - // CompileSDSL(); - - // var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; - - // var buffer = GetOrLoadShader("TestBasic"); - - // // Step: expand "for" - // // TODO - - // // Step: build mixins: top level and (TODO) compose - // var inheritanceList = new List(); - // BuildInheritanceList(buffer, inheritanceList); - // inheritanceList.Add("TestBasic"); - - // var temp = new SpirvBuffer(); - // var offset = 0; - // var nextOffset = 0; - - // foreach (var shaderName in inheritanceList) - // { - // var shader = GetOrLoadShader(shaderName); - // offset += nextOffset; - // nextOffset = 0; - // foreach (var i in shader.Instructions) - // { - // var i2 = temp.Add(i.Words); - - // if (i.ResultId != null && i.ResultId.Value > nextOffset) - // nextOffset = i.ResultId.Value; - // i2.OffsetIds(offset); - // } - // } - - // var shaders = new Dictionary(); - // ShaderInfo? currentShader = null; - - // var names = new Dictionary(); - // var importedShaders = new Dictionary(); - // var idRemapping = new Dictionary(); - // foreach (var i in temp.Instructions) - // { - // if (i.OpCode == Op.OpName) - // { - // var nameInstruction = i.UnsafeAs(); - // names.Add(nameInstruction.Target, nameInstruction.Name.Value); - // } - // else if (i.OpCode == Op.OpSDSLShader) - // { - // currentShader = new ShaderInfo(); - // var shaderName = i.UnsafeAs().ShaderName.Value; - // shaders.Add(shaderName, currentShader); - // SetOpNop(i.Words); - // } - // else if (i.OpCode == Op.OpSDSLShaderEnd) - // { - // currentShader = null; - // importedShaders.Clear(); - // SetOpNop(i.Words); - // } - // else if (i.OpCode == Op.OpSDSLMixinInherit) - // { - // SetOpNop(i.Words); - // } - - // if (i.OpCode == Op.OpFunction) - // { - // var function = i.UnsafeAs(); - // var functionName = names[function.ResultId.Value]; - // currentShader!.Functions.Add(functionName, i.ResultId!.Value); - - // //temp.Remove(i.Position); - // //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.Functioncontrol, function.FunctionType); - // } - - // if (i.OpCode == Op.OpVariable) - // { - // var variable = i.UnsafeAs(); - // var variableName = names[variable.ResultId.Value]; - // currentShader!.Variables.Add(variableName, i.ResultId!.Value); - // } - - // if (i.OpCode == Op.OpSDSLImportShader) - // { - // var importShader = i.UnsafeAs(); - - // importedShaders.Add(importShader.ResultId.Value, shaders[importShader.ShaderName.Value]); - - // SetOpNop(i.Words); - // } - // else if (i.OpCode == Specification.Op.OpSDSLImportVariable) - // { - // var importVariable = i.UnsafeAs(); - // var importedShader = importedShaders[importVariable.Shader]; - - // var importedVariable = importedShader.Variables[importVariable.VariableName.Value]; - - // idRemapping.Add(importVariable.ResultId.Value, importedVariable); - - // SetOpNop(i.Words); - // } - // else if (i.OpCode == Op.OpSDSLImportFunction) - // { - // var importFunction = i.UnsafeAs(); - - // var importedShader = importedShaders[importFunction.Shader]; - // var importedFunction = importedShader.Functions[importFunction.FunctionName.Value]; - // idRemapping.Add(importFunction.ResultId.Value, importedFunction); - - // SetOpNop(i.Words); - // } - - // foreach (var op in i) - // { - // if ((op.Kind == OperandKind.IdRef - // || op.Kind == OperandKind.IdResultType - // || op.Kind == OperandKind.PairIdRefLiteralInteger - // || op.Kind == OperandKind.PairIdRefIdRef) - // && idRemapping.TryGetValue(op.Words[0], out var to1)) - // op.Words[0] = to1; - // if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - // || op.Kind == OperandKind.PairIdRefIdRef) - // && idRemapping.TryGetValue(op.Words[1], out var to2)) - // op.Words[1] = to2; - // } - // } + CompileSDSL(); + + var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; + + var buffer = GetOrLoadShader("TestBasic"); + + // Step: expand "for" + // TODO + + // Step: build mixins: top level and (TODO) compose + var inheritanceList = new List(); + BuildInheritanceList(buffer, inheritanceList); + inheritanceList.Add("TestBasic"); + + var temp = new NewSpirvBuffer(); + var offset = 0; + var nextOffset = 0; + + foreach (var shaderName in inheritanceList) + { + var shader = GetOrLoadShader(shaderName); + offset += nextOffset; + nextOffset = 0; + Spv.Dis(shader, true); + foreach (var i in shader) + { + var i2 = new OpData(i.Data.Memory.Span); + temp.Add(i2); + + if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) + nextOffset = i.Data.IdResult.Value; + + if (offset > 0) + OffsetIds(i2, offset); + } + Spv.Dis(temp, true); + } + + var shaders = new Dictionary(); + ShaderInfo? currentShader = null; + + var names = new Dictionary(); + var importedShaders = new Dictionary(); + var idRemapping = new Dictionary(); + foreach (var i in temp) + { + if (i.Data.Op == Op.OpName && (OpName)i is {} nameInstruction) + { + if (idRemapping.ContainsKey(nameInstruction.Target)) + SetOpNop(i.Data.Memory.Span); + else + names.Add(nameInstruction.Target, nameInstruction.Name); + } + else if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is {} shaderInstruction) + { + currentShader = new ShaderInfo(); + var shaderName = shaderInstruction.ShaderName; + shaders.Add(shaderName, currentShader); + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLShaderEnd) + { + currentShader = null; + importedShaders.Clear(); + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLMixinInherit) + { + SetOpNop(i.Data.Memory.Span); + } + + if (i.Data.Op == Op.OpFunction && (OpFunction)i is {} function) + { + var functionName = names[function.ResultId]; + currentShader!.Functions.Add(functionName, function.ResultId); + + //temp.Remove(i.Position); + //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.FunctionControl, function.FunctionType); + } + + if (i.Data.Op == Op.OpVariable && (OpVariable)i is {} variable) + { + var variableName = names[variable.ResultId]; + currentShader!.Variables.Add(variableName, variable.ResultId); + } + + if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is {} importShader) + { + importedShaders.Add(importShader.ResultId, shaders[importShader.ShaderName]); + + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is {} importVariable) + { + var importedShader = importedShaders[importVariable.Shader]; + + var importedVariable = importedShader.Variables[importVariable.VariableName]; + + idRemapping.Add(importVariable.ResultId, importedVariable); + + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is {} importFunction) + { + var importedShader = importedShaders[importFunction.Shader]; + var importedFunction = importedShader.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + + SetOpNop(i.Data.Memory.Span); + } + + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) + op.Words[0] = to1; + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + op.Words[1] = to2; + } + } + + Console.WriteLine("Done SDSL importing"); + Spv.Dis(temp, true); // Step: merge mixins // start from most-derived class and import on demand // Step: analyze streams and generate in/out variables - // new TypeDuplicateRemover().Apply(temp); - - // var context = new SpirvContext(new()); - // context.Bound = offset + nextOffset + 1; - // ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); - // foreach (var i in temp.Instructions) - // { - // if (i.OpCode == Op.OpFunction) - // { - // var function = i.UnsafeAs(); - // var functionName = names2[i.ResultId.Value]; - // context.Module.Functions.Add(functionName, new SpirvFunction(i.ResultId.Value, functionName, (FunctionType)types[function.FunctionType])); - // } - // } - - // foreach (var type in types) - // { - // context.Types.Add(type.Value, type.Key); - // context.ReverseTypes.Add(type.Key, type.Value); - // } - - // context.Buffer.InsertOpCapability(0, Specification.Capability.Shader); - // context.Buffer.InsertOpMemoryModel(1, Specification.AddressingModel.Logical, Specification.MemoryModel.GLSL450); - // context.Buffer.InsertOpExtension(2, "SPV_GOOGLE_hlsl_functionality1"); - // new StreamAnalyzer().Process(temp, context); - - // temp.Instructions.AddRange(context.Buffer.Instructions); - - // new TypeDuplicateRemover().Apply(temp); - // temp.Instructions.RemoveAll(x => x.OpCode == Op.OpNop); - - // var dis = new SpirvDis(temp, true); - // var source = dis.Disassemble(true); - - // File.WriteAllText("test.spvdis", source); - #warning replace - throw new NotImplementedException(); + new TypeDuplicateRemover().Apply(temp); + + Console.WriteLine("Done type remapping"); + Spv.Dis(temp, true); + + var context = new SpirvContext(new()); + context.Bound = offset + nextOffset + 1; + Spv.Dis(temp, true); + ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); + foreach (var i in temp) + { + if (i.Data.Op == Op.OpFunction && (OpFunction)i is {} function) + { + var functionName = names2[function.ResultId]; + context.Module.Functions.Add(functionName, new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); + } + } + + foreach (var type in types) + { + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); + } + + context.Insert(0, new OpCapability(Capability.Shader)); + context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); + new StreamAnalyzer().Process(temp, context); + + foreach (var inst in context.GetBuffer()) + temp.Add(inst.Data); + + new TypeDuplicateRemover().Apply(temp); + for (int i = 0; i < temp.Count; i++) + { + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + } + + var source = Spv.Dis(temp, true); + + File.WriteAllText("test.spvdis", source); } - static void ReplaceRefs(int from, int to, Instruction i) + public static void OffsetIds(OpData inst, int offset) { - var opcode = i.OpCode; - foreach (var op in i) + foreach (var o in inst) { - if (op.Kind == OperandKind.IdRef && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) - op.Words[0] = to; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) + if (o.Kind == OperandKind.IdRef + || o.Kind == OperandKind.IdResult + || o.Kind == OperandKind.IdResultType) + { + for (int i = 0; i < o.Words.Length; ++i) + o.Words[i] += offset; + } + else if (o.Kind == OperandKind.PairIdRefLiteralInteger + || o.Kind == OperandKind.PairLiteralIntegerIdRef + || o.Kind == OperandKind.PairIdRefIdRef) { - if (op.Words[0] == from || op.Words[1] == from) + for (int i = 0; i < o.Words.Length; i += 2) { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 0] += offset; + if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 1] += offset; } } } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index bd49c27617..1c38010f04 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -1,7 +1,7 @@ using Stride.Shaders.Experiments; -Examples.CompileSDSL(); -// Examples.MergeSDSL(); +//Examples.CompileSDSL(); +Examples.MergeSDSL(); // Examples.TryAllFiles(); // Examples.CreateShader(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 266a4a09a3..a28e754c4a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -206,7 +206,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) if (c.Id.Kind == SymbolKind.Variable) { var variableTypeId = context.GetOrRegister(c.Type); - context.FluentAdd(new OpSDSLImportVariable(context.Bound++, variableTypeId, c.Id.Name, shader.ResultId), out var variable); + context.FluentAdd(new OpSDSLImportVariable(variableTypeId, context.Bound++, c.Id.Name, shader.ResultId), out var variable); context.Module.InheritedVariables.Add(c.Id.Name, new(variable.ResultId, variable.ResultType, variable.VariableName)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId }); } @@ -215,7 +215,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var functionType = (FunctionType)c.Type; var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.FluentAdd(new OpSDSLImportFunction(context.Bound++, functionReturnTypeId, c.Id.Name, shader.ResultId), out var function); + context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound++, c.Id.Name, shader.ResultId), out var function); context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId, c.Id.Name, functionType)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index d18dc7415b..67ba847fb1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -265,6 +265,10 @@ public SpirvValue CreateConstant(Literal literal) return result; } + public OpData Insert(int index, in T value) + where T : struct, IMemoryInstruction + => Buffer.InsertData(index, value); + public OpData Add(in T value) where T : struct, IMemoryInstruction => Buffer.Add(value); diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index b53517384c..c60bd9fa5d 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -93,11 +93,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList -// /// Remove duplicate simple types. -// /// Should be applied before the IdRefOffsetter. -// /// -// public struct TypeDuplicateRemover : INanoPass -// { +/// +/// Remove duplicate simple types. +/// Should be applied before the IdRefOffsetter. +/// +public struct TypeDuplicateRemover : INanoPass +{ -// public readonly void Apply(NewSpirvBuffer buffer) -// { -// for (var index = 0; index < buffer.Instructions.Count; index++) -// { -// var i = buffer.Instructions[index]; -// if (i.OpCode == Op.OpTypeVoid || i.OpCode == Op.OpTypeInt || i.OpCode == Op.OpTypeFloat) -// { -// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) -// { -// var j = buffer.Instructions[index2]; -// if ( -// (j.OpCode == Op.OpTypeVoid || j.OpCode == Op.OpTypeInt || -// j.OpCode == Op.OpTypeFloat) -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words); -// } -// } -// } -// } + public readonly void Apply(NewSpirvBuffer buffer) + { + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpTypeVoid || i.Op == Op.OpTypeInt || i.Op == Op.OpTypeFloat) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + (j.Op == Op.OpTypeVoid || j.Op == Op.OpTypeInt || + j.Op == Op.OpTypeFloat) + && i.IdResult != j.IdResult + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } -// for (var index = 0; index < buffer.Instructions.Count; index++) -// { -// var i = buffer.Instructions[index]; -// if (i.OpCode == Op.OpTypeVector) -// { -// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) -// { -// var j = buffer.Instructions[index2]; -// if ( -// j.OpCode == Op.OpTypeVector -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words); -// } -// } -// } -// } -// for (var index = 0; index < buffer.Instructions.Count; index++) -// { -// var i = buffer.Instructions[index]; -// if (i.OpCode == Op.OpTypeMatrix) -// { -// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) -// { -// var j = buffer.Instructions[index2]; -// if ( -// j.OpCode == Op.OpTypeMatrix -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words); -// } -// } -// } -// } -// for (var index = 0; index < buffer.Instructions.Count; index++) -// { -// var i = buffer.Instructions[index]; -// if (i.OpCode == Op.OpTypePointer) -// { -// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) -// { -// var j = buffer.Instructions[index2]; -// if ( -// j.OpCode == Op.OpTypePointer -// && i.ResultId != j.ResultId -// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words); -// } -// } -// } -// } -// for (var index = 0; index < buffer.Instructions.Count; index++) -// { -// var i = buffer.Instructions[index]; -// if (i.OpCode == Op.OpName) -// { -// for (var index2 = index + 1; index2 < buffer.Instructions.Count; index2++) -// { -// var j = buffer.Instructions[index2]; -// if ( -// j.OpCode == Op.OpName -// && i.Operands[0] == j.Operands[0] -// && MemoryExtensions.SequenceEqual(i.Operands[1..], j.Operands[1..]) -// ) -// { -// ReplaceRefs(j.ResultId ?? -1, i.ResultId ?? -1, buffer); -// SetOpNop(j.Words); -// } -// } -// } -// } -// } + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpTypeVector) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + j.Op == Op.OpTypeVector + && i.IdResult != j.IdResult + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpTypeMatrix) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + j.Op == Op.OpTypeMatrix + && i.IdResult != j.IdResult + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpTypePointer) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + j.Op == Op.OpTypePointer + && i.IdResult != j.IdResult + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpTypeFunction) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + j.Op == Op.OpTypeFunction + && i.IdResult != j.IdResult + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index].Data; + if (i.Op == Op.OpName) + { + for (var index2 = index + 1; index2 < buffer.Count; index2++) + { + var j = buffer[index2].Data; + if ( + j.Op == Op.OpName + && i.Memory.Span[1] == j.Memory.Span[1] + && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) + ) + { + ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); + SetOpNop(j.Memory.Span); + } + } + } + } + } -// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) -// { -// foreach (var i in buffer.Instructions) -// { -// var opcode = i.OpCode; -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) -// op.Words[0] = to; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// if (op.Words[0] == from || op.Words[1] == from) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// } -// } + static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) + { + foreach (var i in buffer) + { + var opcode = i.Op; + foreach (var op in i.Data) + { + if (op.Kind == OperandKind.IdRef) + { + foreach (ref var w in op.Words) + { + if (w == from) + w = to; + } + } + else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + if (op.Words[0] == from || op.Words[1] == from) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } + } -// static void SetOpNop(Span words) -// { -// words[0] = words.Length << 16; -// words[1..].Clear(); -// } -// } + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } +} From 6afab0fa8febc18a3f1a6f62d2725421037cc922 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Sep 2025 17:59:24 +0900 Subject: [PATCH 0449/1182] Made Buffer.Sort() stable, so that instructions are kept in order (esp. important for type depending on another type) --- .../Buffers/NewSpirvBuffer.cs | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 8d59573fad..04441b9c1e 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using System.Text; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Spirv.Core.Parsing; @@ -85,6 +86,46 @@ public readonly int CompareTo(OpData other) var otherGroup = InstructionInfo.GetGroupOrder(other); return group.CompareTo(otherGroup); } + + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append(Op); + foreach (var op in this) + { + sb.Append(" "); + switch (op.Kind) + { + case OperandKind.IdResult: + case OperandKind.IdRef: + for (var index = 0; index < op.Words.Length; index++) + { + if (index > 0) + sb.Append(" "); + var x = op.Words[index]; + sb.Append("%"); + sb.Append(op.Words[0]); + } + + break; + case OperandKind.LiteralInteger when op.Words.Length == 1: + foreach (var e in op.Words) + sb.Append(e); + break; + case OperandKind.LiteralString: + sb.Append('"'); + sb.Append(op.ToLiteral()); + sb.Append('"'); + break; + default: + sb.Append($"unknown_{op.Kind}"); + if (op.Words.Length != 1) + sb.Append($"_{op.Words.Length}"); + break; + } + } + return sb.ToString(); + } } @@ -243,7 +284,14 @@ public bool MoveNext() } } - public void Sort() => Instructions.Sort(static (a, b) => a.CompareTo(b)); + public void Sort() + { + // Note: We don't use List.Sort because it's not stable. + // This is especially important for type depending on another type. + var sortedInstructions = Instructions.OrderBy(InstructionInfo.GetGroupOrder).ToList(); + Instructions.Clear(); + Instructions.AddRange(sortedInstructions); + } public SpanOwner ToBuffer() { From b4fe6987bb2e9d3fea74a2ce1783e3575176161c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Sep 2025 18:50:14 +0900 Subject: [PATCH 0450/1182] Improve disassembly (missing %) --- src/Stride.Shaders/Spirv/Tools/Dis.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index c142313525..c629458a55 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -64,9 +64,9 @@ readonly DisWriter Append(T text, ConsoleColor? color = null) return this; } - readonly DisWriter AppendIdRef(int id) + readonly DisWriter AppendIdRef(int id, bool useNames = true) { - if (data.UseNames && data.NameTable.TryGetValue(id, out var name)) + if (data.UseNames && useNames && data.NameTable.TryGetValue(id, out var name)) return Append($"%{name} ", ConsoleColor.Green); else return Append($"%{id} ", ConsoleColor.Green); } @@ -219,7 +219,7 @@ public readonly void DisInstruction(in OpDataIndex instruction, in DisWriter wri var nameInst = (OpName)instruction; data.NameTable[nameInst.Target] = nameInst.Name; AppendResultId(); - Append("OpName ", ConsoleColor.Blue).AppendLiteralNumber(nameInst.Target).AppendLiteralString(nameInst.Name).AppendLine(""); + Append("OpName ", ConsoleColor.Blue).AppendIdRef(nameInst.Target, false).AppendLiteralString(nameInst.Name).AppendLine(""); } else if (instruction.Op == Op.OpMemberName) { From fd97c8502d9c5a6688c514aa4929b544d071f00a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 14:24:13 +0900 Subject: [PATCH 0451/1182] Improved OpDecorate instructions and their disassembly --- .../Buffers/NewSpirvBuffer.cs | 3 +++ .../Parsing/OpDataEnumerator.cs | 17 ++++++++++++++++- .../SPVGenerator.Instructions.cs | 11 +++++++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Spirv/Processing/StreamAnalyzer.cs | 6 +++--- src/Stride.Shaders/Spirv/Tools/Dis.cs | 2 +- 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 04441b9c1e..34ed9cf840 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -355,7 +355,10 @@ public static LogicalOperandArray GetInfo(this ref T op) Decoration? decoration = op switch { OpDecorate opd => opd.Decoration, + OpDecorateId opd => opd.Decoration, + OpDecorateString opd => opd.Decoration, OpMemberDecorate opd => opd.Decoration, + OpMemberDecorateString opd => opd.Decoration, _ => null }; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 0880f1d501..428fc3afdd 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -17,7 +17,22 @@ public ref struct OpDataEnumerator public OpDataEnumerator(Span instruction) { this.instruction = instruction; - logicalOperands = InstructionInfo.GetInfo(OpCode); + + Decoration? decoration = null; + switch (OpCode) + { + case Op.OpDecorate: + case Op.OpDecorateId: + case Op.OpDecorateString: + decoration = (Decoration)instruction[2]; + break; + case Op.OpMemberDecorate: + case Op.OpMemberDecorateString: + decoration = (Decoration)instruction[3]; + break; + } + + logicalOperands = InstructionInfo.GetInfo(new OperandKey(OpCode, decoration)); oid = -1; wid = 0; } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 9e81d7327d..a05707508c 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -51,7 +51,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv if (instruction.OpName.EndsWith("Constant")) WriteConstantInstructions(grammar, instruction, builder, body1, body2, body3, body4); - else if (instruction.OpName.EndsWith("Decorate")) + else if (instruction.OpName.Contains("Decorate")) WriteDecorateInstructions(grammar, instruction, builder, body1, body2, body3, body4); else if (instruction.OpName.StartsWith("OpCopyMemory")) WriteCopyMemoryInstructions(grammar, instruction, body1, body2, body3, body4); @@ -270,9 +270,12 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i if (instruction.Operands?.AsList() is List operands) { - operands.Add(new() { Name = "additional1", Kind = "LiteralInteger", Quantifier = "?" }); - operands.Add(new() { Name = "additional2", Kind = "LiteralInteger", Quantifier = "?" }); - operands.Add(new() { Name = "additionalString", Kind = "LiteralString", Quantifier = "?" }); + if (instruction.OpName.EndsWith("Id")) + operands.Add(new() { Name = "additionalId", Kind = "IdRef" }); + else if (instruction.OpName.EndsWith("String")) + operands.Add(new() { Name = "additionalString", Kind = "LiteralString" }); + else + operands.Add(new() { Name = "additionalInteger", Kind = "LiteralInteger", Quantifier = "?" }); body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 9894c7fcce..a7a39c3ab9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -90,7 +90,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpVariable(registeredType, variable, Specification.StorageClass.Private, null)); context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) - context.Add(new OpDecorate(variable, Specification.Decoration.UserSemantic, null, null, Semantic.Name)); + context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); var sid = diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index c60bd9fa5d..229f261620 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -99,7 +99,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList Date: Wed, 24 Sep 2025 15:41:33 +0900 Subject: [PATCH 0452/1182] Array: set value instead of Assign (otherwise it modifies a copy) --- .../SPVGenerator.Instructions.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index a05707508c..2e6a19a110 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -187,9 +187,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); + body3.AppendLine($"{fieldName} = {operandName};"); } body2.AppendLine("}"); From d32eede5d011bd429ac026806a65701e9bed3ef8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 15:41:41 +0900 Subject: [PATCH 0453/1182] Array: fix allocation --- src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 543961f373..187de8ce1a 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -92,7 +92,8 @@ public void Assign(Span span) void UpdateWords() { Memory?.Dispose(); - Memory = MemoryOwner.Allocate(Elements.Length * 2, AllocationMode.Clear); + var memorySize = Elements.Length > 0 && Elements.Span[0] is long or ulong or double or ValueTuple ? Elements.Length * 2 : Elements.Length; + Memory = MemoryOwner.Allocate(memorySize, AllocationMode.Clear); var pos = 0; foreach (var element in Elements.Span) { From 9349bd3eefc9f681d866a81d91c82f9d56dcb34c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 15:42:07 +0900 Subject: [PATCH 0454/1182] SDSL: fix StreamAnalyzer (mixup type and id) --- .../Spirv/Processing/StreamAnalyzer.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 229f261620..71547759d8 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -42,7 +42,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) stream.Value.Stream.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -51,7 +51,9 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Read = false; } PropagateStreamsFromPreviousStage(streams); - GenerateStreamWrapper(buffer, context, Specification.ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + + buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } private static void PropagateStreamsFromPreviousStage(SortedList streams) @@ -135,7 +137,7 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) + private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, SortedList streams) { ProcessMethod(buffer, entryPointId, streams); @@ -153,11 +155,12 @@ private void GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, if (!stream.Value.IsDirect) continue; + var baseType = ((PointerType)stream.Value.Stream.Type).BaseType; if (stream.Value.Stream.Input) { - context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[stream.Value.Stream.Type]), out var pointerType); - context.FluentAdd(new OpVariable(pointerType.ResultId, context.Bound++, StorageClass.Input, null), out var variable); - context.AddName(variable, $"in_{stream.Value.Stream.Name}"); + context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); + context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); + context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); if (stream.Value.Stream.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); @@ -167,9 +170,9 @@ private void GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, if (stream.Value.Stream.Output) { - context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Output, context.Types[stream.Value.Stream.Type]), out var pointerType) - .FluentAdd(new OpVariable(context.Bound++, pointerType, StorageClass.Output, null), out var variable); - context.AddName(variable, $"out_{stream.Value.Stream.Name}"); + context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Output, context.Types[baseType]), out var pointerType); + context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); + context.AddName(variable, $"out_{stage}_{stream.Value.Stream.Name}"); if (stream.Value.Stream.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); @@ -200,7 +203,7 @@ private void GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, foreach (var stream in outputStreams) { var baseType = ((PointerType)stream.Info.Type).BaseType; - buffer.FluentAdd(new OpLoad(context.Bound++, context.Types[baseType], stream.Info.Id, null), out var loadedValue); + buffer.FluentAdd(new OpLoad( context.Types[baseType], context.Bound++, stream.Info.Id, null), out var loadedValue); buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); } @@ -214,6 +217,8 @@ private void GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, pvariables[inputStreams.Count + i] = outputStreams[i].Id; context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); } + + return newEntryPointFunction; } /// @@ -261,7 +266,7 @@ public int FindMethodStart(NewSpirvBuffer buffer, int functionId) for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; - if (instruction.Op is Op.OpFunction) + if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId) return index; } throw new NotImplementedException(); From 7c28a4cbaba24fbf50d25c1973477d4820de682a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 16:55:39 +0900 Subject: [PATCH 0455/1182] Optional operands were not properly enumerated --- .../Parsing/OpDataEnumerator.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 428fc3afdd..9445d53b0e 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -93,11 +93,11 @@ or Decoration.SecondaryViewportRelativeNV { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => (true, wid + Operands[wid..].LengthOfString(), oid + 1), { Quantifier: OperandQuantifier.One, Kind: _ } => (true, wid + 1, oid + 1), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => (wid < Operands.Length - 2, wid + (wid < Operands.Length - 2 ? 2 : 0), oid + wid < Operands.Length - 2 ? 1 : 0), + => (wid < Operands.Length - 2, wid + (wid < Operands.Length - 2 ? 2 : 0), oid + (wid < Operands.Length - 2 ? 1 : 0)), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } - => (wid < Operands.Length - 1, wid + (wid < Operands.Length - 1 ? Operands[wid..].LengthOfString() : 0), oid + wid < Operands.Length ? 1 : 0), + => (wid < Operands.Length - 1, wid + (wid < Operands.Length - 1 ? Operands[wid..].LengthOfString() : 0), oid + (wid < Operands.Length ? 1 : 0)), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } - => (wid < Operands.Length - 1, wid + (wid < Operands.Length ? 1 : 0), oid + wid < Operands.Length ? 1 : 0), + => (wid < Operands.Length - 1, wid + (wid < Operands.Length ? 1 : 0), oid + (wid < Operands.Length ? 1 : 0)), { Quantifier: OperandQuantifier.ZeroOrMore } => (wid < Operands.Length - 1, wid < Operands.Length - 1 ? Operands.Length : wid, oid + (wid < Operands.Length - 1 ? 0 : 1)), _ => (false, wid, oid) @@ -172,13 +172,13 @@ public SpvOperand ParseCurrent() { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length -1 ? Operands.Slice(wid, 1) : []), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands.Slice(wid, 1) : []), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length - 1 ? Operands[wid..] : []), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } => throw new Exception("params of strings is not yet implemented"), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length - 1 ? Operands[wid..] : []), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), _ => throw new NotImplementedException() } }; From 83a95c40e15c6f8088a700544ef93992dde83d58 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 17:03:55 +0900 Subject: [PATCH 0456/1182] Improved OpDecorate --- .../Information/InstructionInfo.cs | 96 +++++++++---------- .../Information/LogicalOperand.cs | 10 +- .../SPVGenerator.Instructions.cs | 12 ++- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index fe796f6911..80765d2f81 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -24,55 +24,55 @@ public partial class InstructionInfo readonly Dictionary Info = []; InstructionInfo() { - Info.Add(new(Op.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); - Info.Add(new(Op.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); - Info.Add(new(Op.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); - Info.Add(new(Op.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); - Info.Add(new(Op.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); - Info.Add(new(Op.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); - Info.Add(new(Op.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); - Info.Add(new(Op.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); - Info.Add(new(Op.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); - Info.Add(new(Op.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); - Info.Add(new(Op.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); - Info.Add(new(Op.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); - Info.Add(new(Op.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); - Info.Add(new(Op.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); - Info.Add(new(Op.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); - Info.Add(new(Op.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); - Info.Add(new(Op.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); - Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); - Info.Add(new(Op.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); - Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); - Info.Add(new(Op.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); - Info.Add(new(Op.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); - Info.Add(new(Op.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(Op.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(Op.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "specId")])); + Info.Add(new(Op.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "arrayStride")])); + Info.Add(new(Op.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "matrixStride")])); + Info.Add(new(Op.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "additionalInteger", "builtin")])); + Info.Add(new(Op.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "scopeId")])); + Info.Add(new(Op.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "streamNumber")])); + Info.Add(new(Op.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "location")])); + Info.Add(new(Op.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "index")])); + Info.Add(new(Op.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "descriptorSet")])); + Info.Add(new(Op.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "offset")])); + Info.Add(new(Op.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "bufferNumber")])); + Info.Add(new(Op.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "stride")])); + Info.Add(new(Op.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "additionalInteger", "roundingMode")])); + Info.Add(new(Op.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "additionalInteger", "fastMathMode")])); + Info.Add(new(Op.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalInteger", "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "additionalInteger2", "linkageType")])); + Info.Add(new(Op.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "inputAttachmentIndex")])); + Info.Add(new(Op.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "alignment")])); + Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "maxByteOffset")])); + Info.Add(new(Op.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "alignmentId")])); + Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "maxByteOffsetId")])); + Info.Add(new(Op.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "viewportIndex")])); + Info.Add(new(Op.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "counterBufferId")])); + Info.Add(new(Op.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "additionalInteger", "functionParameterAttribute")])); + Info.Add(new(Op.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalString", "semanticName")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "specId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "arrayStride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "matrixStride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "builtin")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "scopeId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "streamNumber")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "location")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "index")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "descriptorSet")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "offset")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "bufferNumber")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "stride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "roundingMode")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "fastMathMode")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "linkageType")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "inputAttachmentIndex")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "alignment")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "maxByteOffset")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "alignmentId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "maxByteOffsetId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "viewportIndex")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "counterBufferId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "functionParameterAttribute")])); - Info.Add(new(Op.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "semanticName")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "specId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "arrayStride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "matrixStride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "additionalInteger", "builtin")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "scopeId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "streamNumber")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "location")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "index")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "descriptorSet")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "offset")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "bufferNumber")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "stride")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "additionalInteger", "roundingMode")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "additionalInteger", "fastMathMode")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalInteger", "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "additionalInteger2", "linkageType")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "inputAttachmentIndex")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "alignment")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "maxByteOffset")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "alignmentId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "maxByteOffsetId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "viewportIndex")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "counterBufferId")])); + Info.Add(new(Op.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "additionalInteger", "functionParameterAttribute")])); + Info.Add(new(Op.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalString", "semanticName")])); } /// diff --git a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs index 6c16aeebbb..7d2d45bf52 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs @@ -12,24 +12,24 @@ namespace Stride.Shaders.Spirv.Core; public readonly partial struct LogicalOperand { public string? Name { get; init; } - public string? SpvClass { get; init; } + public string? DecorationName { get; init; } public OperandKind? Kind { get; init; } public OperandQuantifier? Quantifier { get; init; } public LogicalOperand() { } - public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) + public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? decorationName = null) { Name = name; Kind = kind; - SpvClass = spvClass; + DecorationName = decorationName; Quantifier = quantifier; } - public LogicalOperand(string kind, string quantifier, string? name = null, string? spvClass = null) + public LogicalOperand(string kind, string quantifier, string? name = null, string? decorationName = null) { Name = name; Kind = Enum.Parse(kind); - SpvClass = spvClass; + DecorationName = decorationName; Quantifier = Enum.Parse(quantifier); } } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 2e6a19a110..8680bdeccd 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -269,11 +269,17 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i if (instruction.Operands?.AsList() is List operands) { if (instruction.OpName.EndsWith("Id")) + // Note: not sure if this is correct, it might need to be an array (quantifier *) which we don't support nicely yet operands.Add(new() { Name = "additionalId", Kind = "IdRef" }); else if (instruction.OpName.EndsWith("String")) - operands.Add(new() { Name = "additionalString", Kind = "LiteralString" }); + operands.Add(new() { Name = "additionalString", Kind = "LiteralString", Quantifier = "?" }); else + { + // Note: not sure if this is correct, it might need to be an array (quantifier *) which we don't support nicely yet operands.Add(new() { Name = "additionalInteger", Kind = "LiteralInteger", Quantifier = "?" }); + operands.Add(new() { Name = "additionalInteger2", Kind = "LiteralInteger", Quantifier = "?" }); + } + body2.AppendLine("foreach (var o in index.Data)") .AppendLine("{"); @@ -304,7 +310,9 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); // Body 2 - body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); + if (tmp != 0) + body2.Append($"else "); + body2.AppendLine($"if(o.Name == \"{operandName}\")"); if (typename.StartsWith("LiteralArray")) body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) From d1f54937b67bd044f3a42ad170b5caeab53e38bc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 19:22:30 +0900 Subject: [PATCH 0457/1182] Improve disassembly names --- src/Stride.Shaders/Spirv/Tools/Dis.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 951862250f..d0dc935a58 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -196,6 +196,19 @@ public void Disassemble() { DisHeader(); foreach (var instruction in data) + { + if (instruction.Op == Op.OpName) + { + var nameInst = (OpName)instruction; + data.NameTable[nameInst.Target] = nameInst.Name; + } + else if (instruction.Op == Op.OpMemberName) + { + var memberInst = (OpMemberName)instruction; + data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; + } + } + foreach (var instruction in data) { DisInstruction(instruction, this); } @@ -217,16 +230,14 @@ public readonly void DisInstruction(in OpDataIndex instruction, in DisWriter wri if (instruction.Op == Op.OpName) { var nameInst = (OpName)instruction; - data.NameTable[nameInst.Target] = nameInst.Name; AppendResultId(); - Append("OpName ", ConsoleColor.Blue).AppendIdRef(nameInst.Target, false).AppendLiteralString(nameInst.Name).AppendLine(""); + Append("OpName ", ConsoleColor.Blue).AppendIdRef(nameInst.Target).AppendLiteralString(nameInst.Name).AppendLine(""); } else if (instruction.Op == Op.OpMemberName) { var memberInst = (OpMemberName)instruction; - data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; AppendResultId(); - Append("OpMemberName ", ConsoleColor.Blue).AppendIdRef(memberInst.Type, false).AppendLiteralNumber(memberInst.Member).AppendLiteralString(memberInst.Name).AppendLine(""); + Append("OpMemberName ", ConsoleColor.Blue).AppendIdRef(memberInst.Type).AppendLiteralNumber(memberInst.Member).AppendLiteralString(memberInst.Name).AppendLine(""); } else { From adad1f1a7297e65c355647660edce6933a5b7598 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 19:23:11 +0900 Subject: [PATCH 0458/1182] Perform a final buffer sort --- src/Stride.Shaders.Experiments/Examples.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index a5bd338f2e..f8ccd3c785 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -471,6 +471,8 @@ public static void MergeSDSL() temp.RemoveAt(i--); } + temp.Sort(); + var source = Spv.Dis(temp, true); File.WriteAllText("test.spvdis", source); From 29644c6ac4f2af91c040af7e77c3712ee3e09d87 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Sep 2025 19:23:44 +0900 Subject: [PATCH 0459/1182] Use local function variables for calling functions --- src/Stride.Shaders.Experiments/Examples.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 27 ++++++++++++++++++- .../Spirv/Building/Builder.Flow.cs | 3 +++ src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index f8ccd3c785..d350f7827c 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -378,7 +378,7 @@ public static void MergeSDSL() //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.FunctionControl, function.FunctionType); } - if (i.Data.Op == Op.OpVariable && (OpVariable)i is {} variable) + if (i.Data.Op == Op.OpVariable && (OpVariable)i is {} variable && variable.Storageclass != Specification.StorageClass.Function) { var variableName = names[variable.ResultId]; currentShader!.Variables.Add(variableName, variable.ResultId); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 7ece8f0c82..1af45daa14 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -47,8 +47,33 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var list = parameters.Values; Span compiledParams = stackalloc int[list.Count]; var tmp = 0; + foreach (var p in list) - compiledParams[tmp++] = p.Compile(table, shader, compiler).Id; + { + var paramSource = p.Compile(table, shader, compiler).Id; + var paramType = context.GetOrRegister(functionType.ParameterTypes[tmp]); + + // Wrap param in proper pointer type (function) + var paramVariable = context.Bound++; + + if (builder.CurrentFunction is SpirvFunction f) + { + var currentPosition = builder.Position; + builder.SetPositionTo(f.BasicBlocks.First().Value, true); + // Go after label + builder.Position++; + builder.Insert(new OpVariable(paramType, paramVariable, Specification.StorageClass.Function, null)); + + builder.Position = currentPosition + 1; + } + + var loadedParam = context.Bound++; + builder.Insert(new OpLoad(compiler.Context.Types[p.ValueType], loadedParam, paramSource, null)); + builder.Insert(new OpStore(paramVariable, loadedParam, null)); + + compiledParams[tmp++] = paramVariable; + } + return builder.CallFunction(context, Name, [.. compiledParams]); } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 9de9ceaae3..596d608e14 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -11,6 +11,9 @@ public SpirvBlock CreateBlock(SpirvContext context, string? name = null) var i = Buffer.Insert(Position++, new OpLabel(context.Bound++)); Buffer.Insert(Position, new OpUnreachable()); var result = new SpirvBlock(i.ResultId, CurrentFunction ?? throw new NotImplementedException(), name); + + CurrentFunction.Value.BasicBlocks.Add(result.Id, result); + return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 67ba847fb1..dd5ec27503 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -196,7 +196,7 @@ int RegisterFunctionType(FunctionType functionType) Span types = stackalloc int[functionType.ParameterTypes.Count]; int tmp = 0; foreach (var f in functionType.ParameterTypes) - types[tmp] = GetOrRegister(f); + types[tmp] = GetOrRegister(new PointerType(f, Specification.StorageClass.Function)); var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); From 8a113fa55b2050b3f1f8a03f97f5bcc66b14a5b0 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 23 Sep 2025 22:40:53 +0200 Subject: [PATCH 0460/1182] example of testing a frame with opengl --- SDSL.sln | 83 ++++++++ .../FrameRenderer.OpenGL.cs | 183 ++++++++++++++++++ src/Stride.Graphics.RHI/FrameRenderer.cs | 10 + .../Stride.Graphics.RHI.csproj | 18 ++ src/Stride.Shaders.Tests/RenderingTests.cs | 30 +++ .../Stride.Shaders.Parsing.Tests.csproj | 3 + 6 files changed, 327 insertions(+) create mode 100644 src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs create mode 100644 src/Stride.Graphics.RHI/FrameRenderer.cs create mode 100644 src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj create mode 100644 src/Stride.Shaders.Tests/RenderingTests.cs diff --git a/SDSL.sln b/SDSL.sln index d7379616de..81e6424c55 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -21,44 +21,126 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{BFCBF799-91A7-93D7-A6A1-233537FD7E63}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Graphics.RHI", "src\Stride.Graphics.RHI\Stride.Graphics.RHI.csproj", "{050ED94E-2A9D-4145-BCD1-7B97E5D58365}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|x64.ActiveCfg = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|x64.Build.0 = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|x86.ActiveCfg = Debug|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Debug|x86.Build.0 = Debug|Any CPU {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|Any CPU.ActiveCfg = Release|Any CPU {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|Any CPU.Build.0 = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|x64.ActiveCfg = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|x64.Build.0 = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|x86.ActiveCfg = Release|Any CPU + {C61EE276-91AA-4EDB-9E19-8BD8321FE13D}.Release|x86.Build.0 = Release|Any CPU {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|x64.ActiveCfg = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|x64.Build.0 = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|x86.ActiveCfg = Debug|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Debug|x86.Build.0 = Debug|Any CPU {C723E631-41D8-4797-86C3-9D52711CC849}.Release|Any CPU.ActiveCfg = Release|Any CPU {C723E631-41D8-4797-86C3-9D52711CC849}.Release|Any CPU.Build.0 = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|x64.ActiveCfg = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|x64.Build.0 = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|x86.ActiveCfg = Release|Any CPU + {C723E631-41D8-4797-86C3-9D52711CC849}.Release|x86.Build.0 = Release|Any CPU {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|x64.ActiveCfg = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|x64.Build.0 = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Debug|x86.Build.0 = Debug|Any CPU {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|Any CPU.ActiveCfg = Release|Any CPU {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|Any CPU.Build.0 = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|x64.ActiveCfg = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|x64.Build.0 = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|x86.ActiveCfg = Release|Any CPU + {595979CB-8447-4EA0-9A9F-0CBD8B9442BB}.Release|x86.Build.0 = Release|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|x64.ActiveCfg = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|x64.Build.0 = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|x86.ActiveCfg = Debug|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Debug|x86.Build.0 = Debug|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|Any CPU.ActiveCfg = Release|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|Any CPU.Build.0 = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x64.ActiveCfg = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x64.Build.0 = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x86.ActiveCfg = Release|Any CPU + {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x86.Build.0 = Release|Any CPU {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x64.Build.0 = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x86.Build.0 = Debug|Any CPU {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.ActiveCfg = Release|Any CPU {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.Build.0 = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x64.ActiveCfg = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x64.Build.0 = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x86.ActiveCfg = Release|Any CPU + {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x86.Build.0 = Release|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|x64.ActiveCfg = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|x64.Build.0 = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|x86.ActiveCfg = Debug|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|x86.Build.0 = Debug|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|Any CPU.ActiveCfg = Release|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|Any CPU.Build.0 = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|x64.ActiveCfg = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|x64.Build.0 = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|x86.ActiveCfg = Release|Any CPU + {32B1203D-8160-455A-9F00-8097119B7EB4}.Release|x86.Build.0 = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|x64.ActiveCfg = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|x64.Build.0 = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|x86.ActiveCfg = Debug|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Debug|x86.Build.0 = Debug|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.ActiveCfg = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|Any CPU.Build.0 = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x64.ActiveCfg = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x64.Build.0 = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.ActiveCfg = Release|Any CPU + {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.Build.0 = Release|Any CPU {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x64.ActiveCfg = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x64.Build.0 = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x86.ActiveCfg = Debug|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x86.Build.0 = Debug|Any CPU {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.ActiveCfg = Release|Any CPU {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.Build.0 = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x64.ActiveCfg = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x64.Build.0 = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x86.ActiveCfg = Release|Any CPU + {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x86.Build.0 = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.Build.0 = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x64.ActiveCfg = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x64.Build.0 = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x86.ActiveCfg = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x86.Build.0 = Debug|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|Any CPU.ActiveCfg = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|Any CPU.Build.0 = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x64.ActiveCfg = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x64.Build.0 = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x86.ActiveCfg = Release|Any CPU + {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -72,5 +154,6 @@ Global {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {BFCBF799-91A7-93D7-A6A1-233537FD7E63} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {050ED94E-2A9D-4145-BCD1-7B97E5D58365} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs new file mode 100644 index 0000000000..78c47be271 --- /dev/null +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -0,0 +1,183 @@ +using Silk.NET.Maths; +using Silk.NET.OpenGL; +using Silk.NET.Windowing; + +namespace Stride.Graphics.RHI; + + + +public class OpenGLFrameRenderer(uint width = 800, uint height = 600, byte[]? fragmentSpirv = null, byte[]? vertexSpirv = null) : FrameRenderer(width, height, vertexSpirv, fragmentSpirv) +{ + static IWindow? window; + static GL? Gl; + + uint width = width; + uint height = height; + + uint Fbo; + uint FboTex; + uint Vbo; + uint Ebo; + uint Vao; + uint Shader; + + byte[]? fragmentSpirv = fragmentSpirv; + + //Vertex shaders are run on each vertex. + private static readonly string VertexShaderSource = @" + #version 330 core //Using version GLSL version 3.3 + layout (location = 0) in vec4 vPos; + + void main() + { + gl_Position = vec4(vPos.x, vPos.y, vPos.z, 1.0); + } + "; + + //Fragment shaders are run on each fragment/pixel of the geometry. + private static readonly string FragmentShaderSource = @" + #version 330 core + out vec4 FragColor; + + void main() + { + FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); + } + "; + + //Vertex data, uploaded to the VBO. + private static readonly float[] Vertices = + [ + //X Y Z + 1f, 1f, 0f, + 1f, -1f, 0f, + -1f,-1f, 0f, + -1f, 1f, 1f + ]; + + //Index data, uploaded to the EBO. + private static readonly uint[] Indices = + [ + 0, 1, 3, + 1, 2, 3 + ]; + + + public override unsafe void RenderFrame(Span result) + { + var options = WindowOptions.Default; + options.Size = new Vector2D((int)width, (int)height); + options.IsVisible = false; + options.ShouldSwapAutomatically = false; + window = Window.Create(options); + window.Initialize(); + //Getting the opengl api for drawing to the screen. + Gl = GL.GetApi(window); + + // Generate a FBO + + + Gl.GenFramebuffers(1, out Fbo); + Gl.BindFramebuffer(FramebufferTarget.Framebuffer, Fbo); + + Gl.GenTextures(1, out FboTex); + Gl.BindTexture(TextureTarget.Texture2D, FboTex); + Gl.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, null); + Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, FboTex, 0); + + + + //Creating a vertex array. + Vao = Gl.GenVertexArray(); + Gl.BindVertexArray(Vao); + + //Initializing a vertex buffer that holds the vertex data. + Vbo = Gl.GenBuffer(); //Creating the buffer. + Gl.BindBuffer(BufferTargetARB.ArrayBuffer, Vbo); //Binding the buffer. + fixed (void* v = &Vertices[0]) + { + Gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(Vertices.Length * sizeof(uint)), v, BufferUsageARB.StaticDraw); //Setting buffer data. + } + + //Initializing a element buffer that holds the index data. + Ebo = Gl.GenBuffer(); //Creating the buffer. + Gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, Ebo); //Binding the buffer. + fixed (void* i = &Indices[0]) + { + Gl.BufferData(BufferTargetARB.ElementArrayBuffer, (nuint)(Indices.Length * sizeof(uint)), i, BufferUsageARB.StaticDraw); //Setting buffer data. + } + + //Creating a vertex shader. + uint vertexShader = Gl.CreateShader(ShaderType.VertexShader); + Gl.ShaderSource(vertexShader, VertexShaderSource); + Gl.CompileShader(vertexShader); + + //Checking the shader for compilation errors. + string infoLog = Gl.GetShaderInfoLog(vertexShader); + if (!string.IsNullOrWhiteSpace(infoLog)) + { + Console.WriteLine($"Error compiling vertex shader {infoLog}"); + } + + //Creating a fragment shader. + uint fragmentShader = Gl.CreateShader(ShaderType.FragmentShader); + if (fragmentSpirv is not null) + { + unsafe + { + fixed (byte* spirv = fragmentSpirv) + Gl.ShaderBinary([fragmentShader], GLEnum.SpirVBinary, (void*)spirv, (uint)fragmentSpirv.Length); + } + } + else + { + Gl.ShaderSource(fragmentShader, FragmentShaderSource); + Gl.CompileShader(fragmentShader); + } + + //Checking the shader for compilation errors. + infoLog = Gl.GetShaderInfoLog(fragmentShader); + if (!string.IsNullOrWhiteSpace(infoLog)) + { + Console.WriteLine($"Error compiling fragment shader {infoLog}"); + } + + //Combining the shaders under one shader program. + Shader = Gl.CreateProgram(); + Gl.AttachShader(Shader, vertexShader); + Gl.AttachShader(Shader, fragmentShader); + Gl.LinkProgram(Shader); + + //Checking the linking for errors. + Gl.GetProgram(Shader, GLEnum.LinkStatus, out var status); + if (status == 0) + { + Console.WriteLine($"Error linking shader {Gl.GetProgramInfoLog(Shader)}"); + } + + //Delete the no longer useful individual shaders; + Gl.DetachShader(Shader, vertexShader); + Gl.DetachShader(Shader, fragmentShader); + Gl.DeleteShader(vertexShader); + Gl.DeleteShader(fragmentShader); + + //Tell opengl how to give the data to the shaders. + Gl.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); + Gl.EnableVertexAttribArray(0); + + // Just render once + Gl.Clear((uint)ClearBufferMask.ColorBufferBit); + + //Bind the geometry and shader. + Gl.BindVertexArray(Vao); + Gl.UseProgram(Shader); + + //Draw the geometry. + Gl.DrawElements(PrimitiveType.Triangles, (uint)Indices.Length, DrawElementsType.UnsignedInt, null); + + Gl.ReadPixels(0, 0, width, height, GLEnum.Rgba, GLEnum.UnsignedByte, result); + window?.Close(); + window?.Dispose(); + + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.cs b/src/Stride.Graphics.RHI/FrameRenderer.cs new file mode 100644 index 0000000000..228e00abaa --- /dev/null +++ b/src/Stride.Graphics.RHI/FrameRenderer.cs @@ -0,0 +1,10 @@ +namespace Stride.Graphics.RHI; + +public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? vertexSpirv = null, byte[]? fragmentSpirv = null) +{ + uint width = width; + uint height = height; + byte[]? vertexSpirv = vertexSpirv; + byte[]? fragmentSpirv = fragmentSpirv; + public abstract void RenderFrame(Span bytes); +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj new file mode 100644 index 0000000000..944825764d --- /dev/null +++ b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj @@ -0,0 +1,18 @@ + + + + net9.0 + enable + enable + true + latest + + + + + + + + + + diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs new file mode 100644 index 0000000000..556b22e11b --- /dev/null +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -0,0 +1,30 @@ + +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; +using Silk.NET.OpenGL; +using Stride.Graphics.RHI; +using CommunityToolkit.HighPerformance.Buffers; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; + +namespace Stride.Shaders.Parsing.Tests; + +public class RenderingTests +{ + static int width = 800; + static int height = 600; + + + [Theory] + [InlineData("test.spv")] + public void RenderTest1(string path) + { + // var shader = File.ReadAllBytes(path); + var renderer = new OpenGLFrameRenderer(); + using var frameBuffer = MemoryOwner.Allocate(width * height * 4); + renderer.RenderFrame(frameBuffer.Span); + var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); + Assert.Equal(width, pixels.Width); + Assert.Equal(height, pixels.Height); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index f6346ae7e6..9d0d7a2622 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -10,8 +10,10 @@ + + @@ -24,6 +26,7 @@ + From 691a87b078f4a70cdb1e13b0a28f68acb4a309fe Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Sep 2025 13:04:49 +0900 Subject: [PATCH 0461/1182] Added implicit return at end of function --- .../Spirv/Building/Builder.Functions.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 9ab8b27628..7d5edb00ab 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -21,7 +21,20 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT return result; } - public void EndFunction() => Buffer.Insert(Position++, new OpFunctionEnd()); + public void EndFunction() + { + // If there was no explicit return, add one + var lastInstruction = Buffer[Position]; + if (lastInstruction.Op == Op.OpUnreachable) + { + if (CurrentFunction.Value.FunctionType.ReturnType != ScalarType.From("void")) + throw new InvalidOperationException("No function termination, but a return value is expected"); + + Return(null); + } + + Buffer.Insert(Position++, new OpFunctionEnd()); + } public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) { From 07c86b2fdcd0f47263114febfd7f0cb7e160030e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 09:10:23 +0900 Subject: [PATCH 0462/1182] Added support for integer equality expressions --- src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs | 2 ++ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 12 +++++++++++- .../Spirv/Building/Builder.Expressions.cs | 3 +++ src/Stride.Shaders/Spirv/Tools/Dis.cs | 2 +- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs b/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs index f97aa911aa..3ba4093a48 100644 --- a/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs @@ -53,6 +53,8 @@ public static bool BinaryOperationResultingType(SymbolType left, SymbolType righ { // Boolean operations (>= 22 and < 26, ScalarType{ TypeName : "bool"}, ScalarType {TypeName: "bool"}) => left, + // Equalities + (>= 22 and < 26, ScalarType l, ScalarType r) when l == r => ScalarType.From("bool"), // Linear algebra (>=8 and < 13, ScalarType {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, ScalarType r) when l.TypeName == r.TypeName => right, (>=8 and < 13, ScalarType { TypeName: "int" or "uint" or "long" or "ulong" }, ScalarType { TypeName: "float" or "double"}) => right, diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a28e754c4a..74b4f14f3c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -52,7 +52,17 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf _ => throw new InvalidOperationException(), }); } - else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is {} pointerInstruction) + else if (instruction.Op == Op.OpTypeInt) + { + OpTypeInt intInstruction = instruction; + types.Add(intInstruction.ResultId, ScalarType.From("int")); + } + else if (instruction.Op == Op.OpTypeBool) + { + OpTypeBool boolInstruction = instruction; + types.Add(boolInstruction.ResultId, ScalarType.From("bool")); + } + else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is { } pointerInstruction) { var innerType = types[pointerInstruction.Type]; types.Add(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 217f9e24ba..2597a12521 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -88,6 +88,9 @@ when l.IsInteger() && r.IsInteger() (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) => Buffer.InsertData(Position++, new OpLogicalOr(resultType, context.Bound++, left.Id, right.Id)), + (Operator.Equals, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + => Buffer.InsertData(Position++, new OpIEqual(resultType, context.Bound++, left.Id, right.Id)), + _ => throw new NotImplementedException() }; diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index d0dc935a58..3027124721 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -260,7 +260,7 @@ or OperandKind.LiteralSpecConstantOpInteger => (operand.Quantifier, operand.Words.Length) switch { (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => AppendLiteralNumber(operand.ToLiteral()), - (OperandQuantifier.ZeroOrMore, > 0) => AppendLiteralNumbers(operand.Words), + (OperandQuantifier.ZeroOrMore, _) => AppendLiteralNumbers(operand.Words), _ => throw new NotImplementedException("Unsupported literal integer quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, OperandKind.LiteralContextDependentNumber => AppendContextDependentNumber(operand, data, buffer), From 7b3be33b63dd07a7223c1e2ebf112aadd07f1d45 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 15:43:38 +0900 Subject: [PATCH 0463/1182] Added basic control flow (if/else) --- assets/SDSL/TestBase.sdsl | 1 - assets/SDSL/TestBasic.sdsl | 15 ++-- .../Parsing/SDSL/AST/Statements.Control.cs | 85 ++++++++++++++++--- .../Spirv/Building/Builder.Flow.cs | 11 +-- .../Spirv/Building/Builder.Functions.cs | 4 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 42 ++++++++- src/Stride.Shaders/Spirv/Building/Context.cs | 36 ++++---- src/Stride.Shaders/Stride.Shaders.csproj | 1 + 8 files changed, 147 insertions(+), 48 deletions(-) diff --git a/assets/SDSL/TestBase.sdsl b/assets/SDSL/TestBase.sdsl index 2e87052268..3454dd7f10 100644 --- a/assets/SDSL/TestBase.sdsl +++ b/assets/SDSL/TestBase.sdsl @@ -7,6 +7,5 @@ shader TestBase void SetColor(float4 color) { streams.ColorTarget = color; - return; } } \ No newline at end of file diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index 5daca984cb..87940d3131 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -11,24 +11,29 @@ shader TestBasic : TestBase float4 CBufferValue1; } + cbuffer Test456 + { + int CBufferValue2; + } + void VSMain() { streams.Position = streams.InputPosition; - return; } void Test() { streams.ColorTarget = streams.ExtraColor; SetColor(streams.ExtraColor); - return; } void PSMain() { - streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); - streams.ColorTarget = streams.ExtraColor * CBufferValue1; + if (CBufferValue2 == 12) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else + streams.ColorTarget = streams.ExtraColor * CBufferValue1; + Test(); //Test(); - return; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index ca7d0a2ab8..2a96490be9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -2,6 +2,8 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -16,13 +18,77 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override unsafe void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - If.Compile(table, shader, compiler); - foreach (var ei in ElseIfs) - ei.Compile(table, shader, compiler); - Else?.Compile(table, shader, compiler); - throw new NotImplementedException(); + var (builder, context, module) = compiler; + + var blockTrueBranchPositions = stackalloc int[ElseIfs.Count + 1]; + var selectionMergePositions = stackalloc int[ElseIfs.Count + 1]; + var ifTestConditions = stackalloc int[ElseIfs.Count + 1]; + + // Create and connect true/false blocks + for (int i = 0; i < ElseIfs.Count + 1; ++i) + { + var currentIf = i == 0 ? If : ElseIfs[i - 1]; + + var conditionValue = currentIf.Condition.CompileAsValue(table, shader, compiler); + if (currentIf.Condition.ValueType != ScalarType.From("bool")) + table.Errors.Add(new(currentIf.Condition.Info, "not a boolean")); + + // OpSelectionMerge and OpBranchConditional (will be filled later) + selectionMergePositions[i] = builder.Position; + var ifTestMerge = new OpSelectionMerge(0, Specification.SelectionControlMask.None); + builder.Insert(ifTestMerge); + ifTestConditions[i] = builder.Position; + var ifTestCondition = new OpBranchConditional(conditionValue.Id, 0, 0, []); + builder.Insert(ifTestCondition); + + var blockTrue = builder.CreateBlock(context, $"if_true_{builder.IfBlockCount + i}"); + ifTestCondition.TrueLabel = blockTrue.Id; + currentIf.Body.Compile(table, shader, compiler); + + // Do we have a specific false block? + if (i + 1 < ElseIfs.Count + 1 || Else != null) + { + var blockTrueBranch = new OpBranch(0); + blockTrueBranchPositions[i] = builder.Position; + builder.Insert(blockTrueBranch); + + var blockFalse = builder.CreateBlock(context, $"if_false_{builder.IfBlockCount + i}"); + ifTestCondition.FalseLabel = blockFalse.Id; + + // If there's an else without condition and we are at the last iteration, add the code now (otherwise it will happen next loop) + if (i + 1 == ElseIfs.Count + 1) + Else!.Compile(table, shader, compiler); + } + } + + // Create and connect merge branches + for (int i = ElseIfs.Count; i >= 0; --i) + { + var mergeBranch = new OpBranch(0); + builder.Insert(mergeBranch); + + var blockMerge = builder.CreateBlock(context, $"if_merge_{builder.IfBlockCount + i}"); + mergeBranch.TargetLabel = blockMerge.Id; + + if (i + 1 < ElseIfs.Count + 1 || Else != null) + { + var blockTrueBranch = (OpBranch)builder.GetBuffer()[blockTrueBranchPositions[i]]; + blockTrueBranch.TargetLabel = blockMerge.Id; + } + else + { + // If there is no false block, we adjust the OpConditionlBranch false to directly point to the merge block + var ifTestCondition = (OpBranchConditional)builder.GetBuffer()[ifTestConditions[i]]; + ifTestCondition.FalseLabel = blockMerge.Id; + } + + var selectionMerge = (OpSelectionMerge)builder.GetBuffer()[selectionMergePositions[i]]; + selectionMerge.MergeBlock = blockMerge.Id; + } + + builder.IfBlockCount += ElseIfs.Count + 1; } public override string ToString() @@ -37,11 +103,7 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Condition.CompileAsValue(table, shader, compiler); - Body.Compile(table, shader, compiler); - if (Condition.ValueType != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); - throw new NotImplementedException(); + throw new InvalidOperationException("Handled by ConditionalFlow"); } public override string ToString() @@ -54,6 +116,7 @@ public class ElseIf(Expression condition, Statement body, TextLocation info) : I { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + throw new InvalidOperationException("Handled by ConditionalFlow"); Condition.CompileAsValue(table, shader, compiler); Body.Compile(table, shader, compiler); if (Condition.ValueType != ScalarType.From("bool")) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 596d608e14..9b63c05036 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -9,10 +9,12 @@ public partial class SpirvBuilder public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { var i = Buffer.Insert(Position++, new OpLabel(context.Bound++)); - Buffer.Insert(Position, new OpUnreachable()); + if (name != null) + context.AddName(i.ResultId, name); var result = new SpirvBlock(i.ResultId, CurrentFunction ?? throw new NotImplementedException(), name); CurrentFunction.Value.BasicBlocks.Add(result.Id, result); + CurrentBlock = result; return result; } @@ -24,12 +26,5 @@ public void Return(in SpirvValue? value = null) SpirvValue v => Buffer.InsertData(Position++, new OpReturnValue(v.Id)), _ => Buffer.InsertData(Position++, new OpReturn()) }; - CleanBlock(); - } - - public void CleanBlock() - { - if (Buffer[Position].Op == Specification.Op.OpUnreachable) - Buffer.RemoveAt(Position); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 7d5edb00ab..c28bb5b9e7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -24,8 +24,8 @@ public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionT public void EndFunction() { // If there was no explicit return, add one - var lastInstruction = Buffer[Position]; - if (lastInstruction.Op == Op.OpUnreachable) + var lastInstruction = Buffer[Position - 1]; + if (!IsBlockTermination(lastInstruction.Op)) { if (CurrentFunction.Value.FunctionType.ReturnType != ScalarType.From("void")) throw new InvalidOperationException("No function termination, but a return value is expected"); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 6893a172d7..dc457f962e 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -13,10 +13,45 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder() { NewSpirvBuffer Buffer { get; init; } = new(); - public SpirvFunction? CurrentFunction { get; private set; } - public SpirvBlock? CurrentBlock { get; private set; } + public SpirvFunction? CurrentFunction { get; internal set; } + public SpirvBlock? CurrentBlock { get; internal set; } public int Position { get; internal set; } = 0; + public int IfBlockCount { get; internal set; } = 0; + + public static bool IsFunctionTermination(Op op) + { + switch (op) + { + case Op.OpReturn: + case Op.OpReturnValue: + case Op.OpKill: + case Op.OpUnreachable: + case Op.OpTerminateInvocation: + return true; + default: + return false; + } + } + + public static bool IsBlockTermination(Op op) + { + switch (op) + { + case Op.OpReturn: + case Op.OpReturnValue: + case Op.OpKill: + case Op.OpUnreachable: + case Op.OpTerminateInvocation: + case Op.OpBranch: + case Op.OpBranchConditional: + case Op.OpSwitch: + return true; + default: + return false; + } + } + public void SetPositionTo(TBlock block, bool beggining = false) where TBlock : IInstructionBlock { @@ -47,8 +82,9 @@ public void SetPositionTo(TBlock block, bool beggining = false) return; } } - if (block is SpirvBlock && blockFound && blockTermination.Contains((int)e.Op)) + if (block is SpirvBlock block2 && blockFound && IsBlockTermination(e.Op)) { + CurrentBlock = block2; Position = pos; return; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index dd5ec27503..9c6c1cd9d0 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -214,23 +214,23 @@ int RegisterPointerType(PointerType pointerType) public SpirvValue CreateConstant(Literal literal) { - // object literalValue = literal switch - // { - // BoolLiteral lit => lit.Value, - // IntegerLiteral lit => lit.Suffix.Size switch - // { - // > 32 => lit.LongValue, - // _ => lit.IntValue, - // }, - // FloatLiteral lit => lit.Suffix.Size switch - // { - // > 32 => lit.DoubleValue, - // _ => (float)lit.DoubleValue, - // }, - // }; + object literalValue = literal switch + { + BoolLiteral lit => lit.Value, + IntegerLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.LongValue, + _ => lit.IntValue, + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.DoubleValue, + _ => (float)lit.DoubleValue, + }, + }; - // if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) - // return result; + if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) + return result; var instruction = literal switch { BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), @@ -253,8 +253,8 @@ public SpirvValue CreateConstant(Literal literal) _ => throw new NotImplementedException() }; - SpirvValue result = new(instruction); - // LiteralConstants.Add((literal.Type, literalValue), result); + result = new(instruction); + LiteralConstants.Add((literal.Type, literalValue), result); AddName(result.Id, literal switch { BoolLiteral lit => $"{lit.Type}_{lit.Value}", diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 12e58adbc8..89987e6e88 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -10,6 +10,7 @@ enable enable preview + True From 0607fa24cd734db9aed2b8b74a7cea8fcacfef85 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 17:42:55 +0900 Subject: [PATCH 0464/1182] Added support for basic "for" loops (no continue/break yet) --- .../Parsing/SDSL/AST/Expression.cs | 36 +++++++++----- .../Parsing/SDSL/AST/Statements.Flow.cs | 48 +++++++++++++++++-- .../Parsing/SDSL/AST/Statements.cs | 28 +++++++++-- .../StatementParsers/StatementParsers.Flow.cs | 6 +-- .../Spirv/Building/Builder.Expressions.cs | 12 +++++ src/Stride.Shaders/Spirv/Building/Builder.cs | 22 +++++++++ 6 files changed, 131 insertions(+), 21 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 1af45daa14..64facef26e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1,10 +1,11 @@ -using System.Text; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Text; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -56,16 +57,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil // Wrap param in proper pointer type (function) var paramVariable = context.Bound++; - if (builder.CurrentFunction is SpirvFunction f) - { - var currentPosition = builder.Position; - builder.SetPositionTo(f.BasicBlocks.First().Value, true); - // Go after label - builder.Position++; - builder.Insert(new OpVariable(paramType, paramVariable, Specification.StorageClass.Function, null)); - - builder.Position = currentPosition + 1; - } + builder.AddFunctionVariable(paramType, paramVariable); var loadedParam = context.Bound++; builder.Insert(new OpLoad(compiler.Context.Types[p.ValueType], loadedParam, paramSource, null)); @@ -76,6 +68,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return builder.CallFunction(context, Name, [.. compiledParams]); } + public override string ToString() { return $"{Name}({string.Join(", ", Parameters)})"; @@ -110,7 +103,26 @@ public class PrefixExpression(Operator op, Expression expression, TextLocation i { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, _) = compiler; + var expression = Expression.CompileAsValue(table, shader, compiler); + Type = Expression.Type; + if (Expression.Type is PointerType pointerType && pointerType.BaseType is ScalarType { TypeName: "int" or "long" }) + { + var indexLiteral = new IntegerLiteral(new(32, false, true), 1, new()); + indexLiteral.Compile(table, shader, compiler); + var constant1 = context.CreateConstant(indexLiteral); + var result = builder.BinaryOperation(context, context.GetOrRegister(pointerType.BaseType), expression, Operator.Plus, constant1); + + builder.Insert(new OpStore(expression.Id, result.Id, null)); + + // Note: should we fetch the value again? (new OpLoad) + // return Expression.Compile(table, shader, compiler); + return result; + } + else + { + throw new NotImplementedException(); + } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 2ce12ce593..ab515071de 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -1,6 +1,8 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -86,10 +88,10 @@ public enum ForAnnotationKind } public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); -public class For(Statement initializer, Statement cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +public class For(Statement initializer, Expression cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Statement Initializer { get; set; } = initializer; - public Statement Condition { get; set; } = cond; + public Expression Condition { get; set; } = cond; public List Update { get; set; } = update; public Statement Body { get; set; } = body; public ShaderAttribute? Attribute = attribute; @@ -97,7 +99,47 @@ public class For(Statement initializer, Statement cond, List update, public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, module) = compiler; + + Initializer.Compile(table, shader, compiler); + + var startBranch = new OpBranch(0); + builder.Insert(startBranch); + + var forCheckBlock = builder.CreateBlock(context, $"for_check_{builder.ForBlockCount}"); + startBranch.TargetLabel = forCheckBlock.Id; + + var conditionValue = Condition.CompileAsValue(table, shader, compiler); + if (Condition.ValueType != ScalarType.From("bool")) + table.Errors.Add(new(Condition.Info, "not a boolean")); + + var loopMerge = new OpLoopMerge(0, 0, Specification.LoopControlMask.None); + builder.Insert(loopMerge); + + var branchConditional = new OpBranchConditional(conditionValue.Id, 0, 0, []); + builder.Insert(branchConditional); + + // Body block + var forBodyBlock = builder.CreateBlock(context, $"for_body_{builder.ForBlockCount}"); + branchConditional.TrueLabel = forBodyBlock.Id; + Body.Compile(table, shader, compiler); + var forBodyBranch = new OpBranch(0); + builder.Insert(forBodyBranch); + + // Continue block + var forContinueBlock = builder.CreateBlock(context, $"for_continue_{builder.ForBlockCount}"); + loopMerge.ContinueTarget = forContinueBlock.Id; + forBodyBranch.TargetLabel = forContinueBlock.Id; + foreach (var update in Update) + update.Compile(table, shader, compiler); + builder.Insert(new OpBranch(forCheckBlock.Id)); + + // Merge block + var forMergeBlock = builder.CreateBlock(context, $"for_merge_{builder.ForBlockCount}"); + branchConditional.FalseLabel = forMergeBlock.Id; + loopMerge.MergeBlock = forMergeBlock.Id; + + builder.ForBlockCount++; } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 557733f5d3..08cb0eca75 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -119,6 +119,8 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + var (builder, context, _) = compiler; + var compiledValues = new SpirvValue[Variables.Count]; for (var index = 0; index < Variables.Count; index++) { @@ -134,7 +136,10 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit Type = Variables[0].Value!.Type; } else + { table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); + return; + } } else { @@ -142,18 +147,35 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); } - var (builder, context, _) = compiler; - var registeredType = context.GetOrRegister(new PointerType(Type!, Specification.StorageClass.Function)); - foreach (var d in Variables) + var underlyingType = context.GetOrRegister(Type); + Type = new PointerType(Type, Specification.StorageClass.Function); + + var registeredType = context.GetOrRegister(Type); + for (var index = 0; index < Variables.Count; index++) { + var d = Variables[index]; + var variable = context.Bound++; builder.Insert(new OpVariable(registeredType, variable, Specification.StorageClass.Function, null)); + + builder.AddFunctionVariable(registeredType, variable); context.AddName(variable, d.Variable); table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); if (builder.CurrentFunction is SpirvFunction f) f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); + + if (d.Value != null) + { + var source = compiledValues[index]; + + var sourceLoad = context.Bound++; + builder.Insert(new OpLoad(underlyingType, sourceLoad, source.Id, Specification.MemoryAccessMask.None)); + source = new(sourceLoad, underlyingType); + + builder.Insert(new OpStore(variable, source.Id, null)); + } } } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 70944035e2..626b97230c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -61,7 +61,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { Statement? init = null; - Statement? condition = null; + Expression? condition = null; List? expressions = null; Parsers.Spaces0(ref scanner, result, out _); @@ -74,8 +74,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); // Parsing the condition - if (StatementParsers.Expression(ref scanner, result, out condition)){} - else if (StatementParsers.Empty(ref scanner, result, out condition)){} + if (ExpressionParser.Expression(ref scanner, result, out condition) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) {} else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 2597a12521..c092dac035 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -91,6 +91,18 @@ when l.IsInteger() && r.IsInteger() (Operator.Equals, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpIEqual(resultType, context.Bound++, left.Id, right.Id)), + (Operator.Lower, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + => Buffer.InsertData(Position++, new OpSLessThan(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.LowerOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + => Buffer.InsertData(Position++, new OpSLessThanEqual(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.Greater, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + => Buffer.InsertData(Position++, new OpSGreaterThan(resultType, context.Bound++, left.Id, right.Id)), + + (Operator.GreaterOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultType, context.Bound++, left.Id, right.Id)), + _ => throw new NotImplementedException() }; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index dc457f962e..bde543217f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -19,6 +19,8 @@ public partial class SpirvBuilder() public int IfBlockCount { get; internal set; } = 0; + public int ForBlockCount { get; internal set; } = 0; + public static bool IsFunctionTermination(Op op) { switch (op) @@ -52,6 +54,26 @@ public static bool IsBlockTermination(Op op) } } + public void AddFunctionVariable(int paramType, int paramVariable) + { + if (CurrentFunction is not SpirvFunction f) + throw new InvalidOperationException(); + + var currentPosition = Position; + var currentBlock = CurrentBlock; + + SetPositionTo(f.BasicBlocks.First().Value, true); + // Go after label and the last OpVariable + Position++; + while (Buffer[Position].Op == Op.OpVariable) + Position++; + Insert(new OpVariable(paramType, paramVariable, StorageClass.Function, null)); + + Position = currentPosition + 1; + CurrentBlock = currentBlock; + } + + public void SetPositionTo(TBlock block, bool beggining = false) where TBlock : IInstructionBlock { From 006d08e255ff4c079cbc8ddcfb1c5aec6ed201c4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 18:29:34 +0900 Subject: [PATCH 0465/1182] Pre-generate block ids, so no need to patch instructions later --- assets/SDSL/TestBasic.sdsl | 9 ++- .../Parsing/SDSL/AST/Statements.Control.cs | 55 ++++++------------ .../Parsing/SDSL/AST/Statements.Flow.cs | 40 +++++++------ .../Spirv/Building/Builder.Flow.cs | 57 +++++++++++++++++++ src/Stride.Shaders/Spirv/Building/Builder.cs | 37 ------------ 5 files changed, 102 insertions(+), 96 deletions(-) diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index 87940d3131..e550277468 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -29,9 +29,16 @@ shader TestBasic : TestBase void PSMain() { + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + + for (int i = 0; i < 4; ++i) + streams.ColorTarget = streams.ColorTarget * CBufferValue1; + if (CBufferValue2 == 12) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); - else + else if (CBufferValue2 == 13) + streams.ColorTarget = streams.ExtraColor * CBufferValue1; + else //if (CBufferValue2 == 14) streams.ColorTarget = streams.ExtraColor * CBufferValue1; Test(); //Test(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 2a96490be9..1dd28390c5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -22,40 +22,39 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi { var (builder, context, module) = compiler; - var blockTrueBranchPositions = stackalloc int[ElseIfs.Count + 1]; - var selectionMergePositions = stackalloc int[ElseIfs.Count + 1]; - var ifTestConditions = stackalloc int[ElseIfs.Count + 1]; + var blockTrueIds = stackalloc int[ElseIfs.Count + 1]; + var blockMergeIds = stackalloc int[ElseIfs.Count + 1]; // Create and connect true/false blocks for (int i = 0; i < ElseIfs.Count + 1; ++i) { var currentIf = i == 0 ? If : ElseIfs[i - 1]; + blockTrueIds[i] = context.Bound++; + blockMergeIds[i] = context.Bound++; + var conditionValue = currentIf.Condition.CompileAsValue(table, shader, compiler); if (currentIf.Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(currentIf.Condition.Info, "not a boolean")); + int? falseBlock = (i + 1 < ElseIfs.Count + 1 || Else != null) + ? context.Bound++ + : null; + // OpSelectionMerge and OpBranchConditional (will be filled later) - selectionMergePositions[i] = builder.Position; - var ifTestMerge = new OpSelectionMerge(0, Specification.SelectionControlMask.None); - builder.Insert(ifTestMerge); - ifTestConditions[i] = builder.Position; - var ifTestCondition = new OpBranchConditional(conditionValue.Id, 0, 0, []); - builder.Insert(ifTestCondition); - - var blockTrue = builder.CreateBlock(context, $"if_true_{builder.IfBlockCount + i}"); - ifTestCondition.TrueLabel = blockTrue.Id; + builder.Insert(new OpSelectionMerge(blockMergeIds[i], Specification.SelectionControlMask.None)); + builder.Insert(new OpBranchConditional(conditionValue.Id, blockTrueIds[i], falseBlock ?? blockMergeIds[i], [])); + + builder.CreateBlock(context, blockTrueIds[i], $"if_true_{builder.IfBlockCount + i}"); currentIf.Body.Compile(table, shader, compiler); // Do we have a specific false block? - if (i + 1 < ElseIfs.Count + 1 || Else != null) + if (falseBlock != null) { - var blockTrueBranch = new OpBranch(0); - blockTrueBranchPositions[i] = builder.Position; + var blockTrueBranch = new OpBranch(blockMergeIds[i]); builder.Insert(blockTrueBranch); - var blockFalse = builder.CreateBlock(context, $"if_false_{builder.IfBlockCount + i}"); - ifTestCondition.FalseLabel = blockFalse.Id; + builder.CreateBlock(context, falseBlock.Value, $"if_false_{builder.IfBlockCount + i}"); // If there's an else without condition and we are at the last iteration, add the code now (otherwise it will happen next loop) if (i + 1 == ElseIfs.Count + 1) @@ -66,26 +65,8 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi // Create and connect merge branches for (int i = ElseIfs.Count; i >= 0; --i) { - var mergeBranch = new OpBranch(0); - builder.Insert(mergeBranch); - - var blockMerge = builder.CreateBlock(context, $"if_merge_{builder.IfBlockCount + i}"); - mergeBranch.TargetLabel = blockMerge.Id; - - if (i + 1 < ElseIfs.Count + 1 || Else != null) - { - var blockTrueBranch = (OpBranch)builder.GetBuffer()[blockTrueBranchPositions[i]]; - blockTrueBranch.TargetLabel = blockMerge.Id; - } - else - { - // If there is no false block, we adjust the OpConditionlBranch false to directly point to the merge block - var ifTestCondition = (OpBranchConditional)builder.GetBuffer()[ifTestConditions[i]]; - ifTestCondition.FalseLabel = blockMerge.Id; - } - - var selectionMerge = (OpSelectionMerge)builder.GetBuffer()[selectionMergePositions[i]]; - selectionMerge.MergeBlock = blockMerge.Id; + builder.Insert(new OpBranch(blockMergeIds[i])); + builder.CreateBlock(context, blockMergeIds[i], $"if_merge_{builder.IfBlockCount + i}"); } builder.IfBlockCount += ElseIfs.Count + 1; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index ab515071de..8bfeb1d1d3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -103,43 +103,41 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit Initializer.Compile(table, shader, compiler); - var startBranch = new OpBranch(0); - builder.Insert(startBranch); + // Prepare blocks ids + var forCheckBlock = context.Bound++; + var forBodyBlock = context.Bound++; + var previousEscapeBlocks = builder.CurrentEscapeBlocks; + var currentEscapeBlocks = new SpirvBuilder.EscapeBlocks(context.Bound++, context.Bound++); + builder.CurrentEscapeBlocks = currentEscapeBlocks; - var forCheckBlock = builder.CreateBlock(context, $"for_check_{builder.ForBlockCount}"); - startBranch.TargetLabel = forCheckBlock.Id; + builder.Insert(new OpBranch(forCheckBlock)); + + // Check block + builder.CreateBlock(context, forCheckBlock, $"for_check_{builder.ForBlockCount}"); var conditionValue = Condition.CompileAsValue(table, shader, compiler); if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); - var loopMerge = new OpLoopMerge(0, 0, Specification.LoopControlMask.None); - builder.Insert(loopMerge); - - var branchConditional = new OpBranchConditional(conditionValue.Id, 0, 0, []); - builder.Insert(branchConditional); + builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None)); + builder.Insert(new OpBranchConditional(conditionValue.Id, forBodyBlock, currentEscapeBlocks.MergeBlock, [])); // Body block - var forBodyBlock = builder.CreateBlock(context, $"for_body_{builder.ForBlockCount}"); - branchConditional.TrueLabel = forBodyBlock.Id; + builder.CreateBlock(context, forBodyBlock, $"for_body_{builder.ForBlockCount}"); Body.Compile(table, shader, compiler); - var forBodyBranch = new OpBranch(0); - builder.Insert(forBodyBranch); + builder.Insert(new OpBranch(currentEscapeBlocks.ContinueBlock)); // Continue block - var forContinueBlock = builder.CreateBlock(context, $"for_continue_{builder.ForBlockCount}"); - loopMerge.ContinueTarget = forContinueBlock.Id; - forBodyBranch.TargetLabel = forContinueBlock.Id; + builder.CreateBlock(context, currentEscapeBlocks.ContinueBlock, $"for_continue_{builder.ForBlockCount}"); foreach (var update in Update) update.Compile(table, shader, compiler); - builder.Insert(new OpBranch(forCheckBlock.Id)); + builder.Insert(new OpBranch(forCheckBlock)); // Merge block - var forMergeBlock = builder.CreateBlock(context, $"for_merge_{builder.ForBlockCount}"); - branchConditional.FalseLabel = forMergeBlock.Id; - loopMerge.MergeBlock = forMergeBlock.Id; + builder.CreateBlock(context, currentEscapeBlocks.MergeBlock, $"for_merge_{builder.ForBlockCount}"); - builder.ForBlockCount++; + builder.ForBlockCount++; + builder.CurrentEscapeBlocks = previousEscapeBlocks; } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index 9b63c05036..aca53f8dc2 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -1,11 +1,68 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { + public record struct EscapeBlocks(int ContinueBlock, int MergeBlock); + + public int IfBlockCount { get; internal set; } = 0; + + public int ForBlockCount { get; internal set; } = 0; + + public int CurrentForExit { get; internal set; } + + public EscapeBlocks? CurrentEscapeBlocks { get; internal set; } + + public static bool IsFunctionTermination(Op op) + { + switch (op) + { + case Op.OpReturn: + case Op.OpReturnValue: + case Op.OpKill: + case Op.OpUnreachable: + case Op.OpTerminateInvocation: + return true; + default: + return false; + } + } + + public static bool IsBlockTermination(Op op) + { + switch (op) + { + case Op.OpReturn: + case Op.OpReturnValue: + case Op.OpKill: + case Op.OpUnreachable: + case Op.OpTerminateInvocation: + case Op.OpBranch: + case Op.OpBranchConditional: + case Op.OpSwitch: + return true; + default: + return false; + } + } + + public SpirvBlock CreateBlock(SpirvContext context, int blockId, string? name = null) + { + var i = Buffer.Insert(Position++, new OpLabel(blockId)); + if (name != null) + context.AddName(i.ResultId, name); + var result = new SpirvBlock(i.ResultId, CurrentFunction ?? throw new NotImplementedException(), name); + + CurrentFunction.Value.BasicBlocks.Add(result.Id, result); + CurrentBlock = result; + + return result; + } + public SpirvBlock CreateBlock(SpirvContext context, string? name = null) { var i = Buffer.Insert(Position++, new OpLabel(context.Bound++)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index bde543217f..ad135e9f34 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -17,43 +17,6 @@ public partial class SpirvBuilder() public SpirvBlock? CurrentBlock { get; internal set; } public int Position { get; internal set; } = 0; - public int IfBlockCount { get; internal set; } = 0; - - public int ForBlockCount { get; internal set; } = 0; - - public static bool IsFunctionTermination(Op op) - { - switch (op) - { - case Op.OpReturn: - case Op.OpReturnValue: - case Op.OpKill: - case Op.OpUnreachable: - case Op.OpTerminateInvocation: - return true; - default: - return false; - } - } - - public static bool IsBlockTermination(Op op) - { - switch (op) - { - case Op.OpReturn: - case Op.OpReturnValue: - case Op.OpKill: - case Op.OpUnreachable: - case Op.OpTerminateInvocation: - case Op.OpBranch: - case Op.OpBranchConditional: - case Op.OpSwitch: - return true; - default: - return false; - } - } - public void AddFunctionVariable(int paramType, int paramVariable) { if (CurrentFunction is not SpirvFunction f) From 03e8425544521008fc809b0ff8dd82a0e574c058 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 18:32:06 +0900 Subject: [PATCH 0466/1182] Added support for break/continue --- .../Parsing/SDSL/AST/Statements.Flow.cs | 14 ++++++++++++-- src/Stride.Shaders/Spirv/Building/Builder.Flow.cs | 2 -- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 8bfeb1d1d3..12c613df99 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -13,7 +13,12 @@ public class Break(TextLocation info) : Statement(info) { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, module) = compiler; + + if (builder.CurrentEscapeBlocks is not { } escapeBlocks) + throw new InvalidOperationException("Can't process break statement (no context)"); + + builder.Insert(new OpBranch(escapeBlocks.MergeBlock)); } } public class Discard(TextLocation info) : Statement(info) @@ -27,7 +32,12 @@ public class Continue(TextLocation info) : Statement(info) { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context, module) = compiler; + + if (builder.CurrentEscapeBlocks is not { } escapeBlocks) + throw new InvalidOperationException("Can't process continue statement (no context)"); + + builder.Insert(new OpBranch(escapeBlocks.ContinueBlock)); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs index aca53f8dc2..ffb7c17342 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs @@ -13,8 +13,6 @@ public record struct EscapeBlocks(int ContinueBlock, int MergeBlock); public int ForBlockCount { get; internal set; } = 0; - public int CurrentForExit { get; internal set; } - public EscapeBlocks? CurrentEscapeBlocks { get; internal set; } public static bool IsFunctionTermination(Op op) From e50598d15b2b6e2512d33b18508939d10f377443 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 18:32:48 +0900 Subject: [PATCH 0467/1182] Fix parser for continue statements --- .../Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 56423f62e1..16835d0d99 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -209,7 +209,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Tokens.Char(';', ref scanner, advance: true) ) { - parsed = new Break(scanner[position..scanner.Position]); + parsed = new Continue(scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); From 9c4e02f5396830f4a3e4e2fa30367b50d86f4536 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 19:04:33 +0900 Subject: [PATCH 0468/1182] Don't create a SPIRV block when there is a BlockStatement --- src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 08cb0eca75..f23f830f39 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -224,7 +224,6 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { table.Push(); var (builder, context, _) = compiler; - builder.CreateBlock(context); foreach (var s in Statements) s.Compile(table, shader, compiler); table.Pop(); From 94fefdabc4fc26113c2a03b904f7136eea6c2b83 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Sep 2025 19:05:26 +0900 Subject: [PATCH 0469/1182] Stop issuing command if there is an early break/continue/return --- assets/SDSL/TestBasic.sdsl | 18 +++++++++++++++++- .../Parsing/SDSL/AST/Statements.Control.cs | 7 ++++--- .../Parsing/SDSL/AST/Statements.Flow.cs | 6 ++++-- .../Parsing/SDSL/AST/Statements.cs | 5 +++++ src/Stride.Shaders/Spirv/Building/Builder.cs | 5 +++++ 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/assets/SDSL/TestBasic.sdsl b/assets/SDSL/TestBasic.sdsl index e550277468..c5e7fc4868 100644 --- a/assets/SDSL/TestBasic.sdsl +++ b/assets/SDSL/TestBasic.sdsl @@ -32,14 +32,30 @@ shader TestBasic : TestBase streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); for (int i = 0; i < 4; ++i) + { + if (i == 1) + break; + if (i == 2) + continue; + if (i == 3) + return; streams.ColorTarget = streams.ColorTarget * CBufferValue1; + } + // if with an ending else if (CBufferValue2 == 12) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else if (CBufferValue2 == 13) streams.ColorTarget = streams.ExtraColor * CBufferValue1; - else //if (CBufferValue2 == 14) + else streams.ColorTarget = streams.ExtraColor * CBufferValue1; + + // if without an ending else + if (CBufferValue2 == 12) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else if (CBufferValue2 == 13) + streams.ColorTarget = streams.ExtraColor * CBufferValue1; + Test(); //Test(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 1dd28390c5..c690f786a3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -51,8 +51,8 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi // Do we have a specific false block? if (falseBlock != null) { - var blockTrueBranch = new OpBranch(blockMergeIds[i]); - builder.Insert(blockTrueBranch); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(blockMergeIds[i])); builder.CreateBlock(context, falseBlock.Value, $"if_false_{builder.IfBlockCount + i}"); @@ -65,7 +65,8 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi // Create and connect merge branches for (int i = ElseIfs.Count; i >= 0; --i) { - builder.Insert(new OpBranch(blockMergeIds[i])); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(blockMergeIds[i])); builder.CreateBlock(context, blockMergeIds[i], $"if_merge_{builder.IfBlockCount + i}"); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 12c613df99..02bdf5d50b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -135,13 +135,15 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit // Body block builder.CreateBlock(context, forBodyBlock, $"for_body_{builder.ForBlockCount}"); Body.Compile(table, shader, compiler); - builder.Insert(new OpBranch(currentEscapeBlocks.ContinueBlock)); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(currentEscapeBlocks.ContinueBlock)); // Continue block builder.CreateBlock(context, currentEscapeBlocks.ContinueBlock, $"for_continue_{builder.ForBlockCount}"); foreach (var update in Update) update.Compile(table, shader, compiler); - builder.Insert(new OpBranch(forCheckBlock)); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(forCheckBlock)); // Merge block builder.CreateBlock(context, currentEscapeBlocks.MergeBlock, $"for_merge_{builder.ForBlockCount}"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index f23f830f39..0e34a2a520 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -225,7 +225,12 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit table.Push(); var (builder, context, _) = compiler; foreach (var s in Statements) + { s.Compile(table, shader, compiler); + if (SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + break; + } + table.Pop(); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index ad135e9f34..c60c7fc879 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -90,6 +90,11 @@ public T Insert(in T value) [Obsolete("Use the insert method instead")] public NewSpirvBuffer GetBuffer() => Buffer; + public Op GetLastInstructionType() + { + return Buffer[Position - 1].Op; + } + public override string ToString() { return Spv.Dis(Buffer); From 1331c56d3a9ce2136e361ab6d51e949e936305e3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Sep 2025 13:07:12 +0900 Subject: [PATCH 0470/1182] StreamAnalyzer: also add private global variables (needed since SPIRV 1.4) --- src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 71547759d8..3f0c19ab90 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -22,6 +22,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int id) /// public bool Input => Read || (Output && !Write); public bool Output { get; set; } + public bool Private => Read || Write; public bool Read { get; set; } public bool Write { get; set; } @@ -149,6 +150,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con }; List<(StreamInfo Info, int Id)> inputStreams = []; List<(StreamInfo Info, int Id)> outputStreams = []; + List privateStreams = []; foreach (var stream in streams) { // Only direct access to global variables (not temporary variables created within function) @@ -156,6 +158,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con continue; var baseType = ((PointerType)stream.Value.Stream.Type).BaseType; + if (stream.Value.Stream.Private) + privateStreams.Add(stream.Value.Stream); + if (stream.Value.Stream.Input) { context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); @@ -210,11 +215,13 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count]; + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count]; for (int i = 0; i < inputStreams.Count; i++) pvariables[i] = inputStreams[i].Id; for (int i = 0; i < outputStreams.Count; i++) pvariables[inputStreams.Count + i] = outputStreams[i].Id; + for (int i = 0; i < privateStreams.Count; i++) + pvariables[inputStreams.Count + outputStreams.Count + i] = privateStreams[i].Id; context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); } From dbd65cab85aab2c306bcd777ffd38e00873bdf0d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Sep 2025 13:07:52 +0900 Subject: [PATCH 0471/1182] NewSpirvBuffer: fix code to update Bounds --- .../Buffers/NewSpirvBuffer.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 34ed9cf840..5570ecbc36 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -164,8 +164,8 @@ public NewSpirvBuffer(Span span) : this() public void Add(OpData data) { - if (InstructionInfo.GetInfo(data).GetResultIndex(out int index) && index >= Header.Bound) - Header = Header with { Bound = data.Memory.Span[index] + 1 }; + if (data.IdResult is int index && index >= Header.Bound) + Header = Header with { Bound = index + 1 }; Instructions.Add(data); } @@ -194,8 +194,8 @@ public void AddRef(ref T instruction) where T : struct, IMemoryInstruction else Instructions.Add(new(instruction.InstructionMemory)); instruction.DataIndex = new(Instructions.Count - 1, this); - if (instruction.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) - Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; + if (instruction.GetInfo().GetResultIndex(out int rid) && instruction.InstructionMemory.Span[rid + 1] >= Header.Bound) + Header = Header with { Bound = instruction.InstructionMemory.Span[rid + 1] + 1 }; } public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction { @@ -208,8 +208,8 @@ public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryIn } else Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; - if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) - Header = Header with { Bound = tmp.InstructionMemory.Span[index] + 1 }; + if (tmp.GetInfo().GetResultIndex(out int rid) && tmp.InstructionMemory.Span[rid + 1] >= Header.Bound) + Header = Header with { Bound = tmp.InstructionMemory.Span[rid + 1] + 1 }; return this; } public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction @@ -224,8 +224,8 @@ public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : str } else Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; - if (tmp.GetInfo().GetResultIndex(out int index) && index >= Header.Bound) - Header = Header with { Bound = instruction.InstructionMemory.Span[index] + 1 }; + if (tmp.GetInfo().GetResultIndex(out int rid) && instruction.InstructionMemory.Span[rid + 1] >= Header.Bound) + Header = Header with { Bound = instruction.InstructionMemory.Span[rid + 1] + 1 }; return this; } @@ -236,8 +236,8 @@ public T Insert(int index, in T data) { Instructions.Insert(index, new(data.InstructionMemory)); var tmp = data; - if (tmp.GetInfo().GetResultIndex(out int rid) && rid >= Header.Bound) - Header = Header with { Bound = tmp.InstructionMemory.Span[rid] + 1 }; + if (tmp.GetInfo().GetResultIndex(out int rid) && tmp.InstructionMemory.Span[rid + 1] >= Header.Bound) + Header = Header with { Bound = tmp.InstructionMemory.Span[rid + 1] + 1 }; return data; } public OpData InsertData(int index, in T data) From f98706cef95f878e1b346cf1f636abfe9aaa3a8d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Sep 2025 15:02:54 +0900 Subject: [PATCH 0472/1182] Added some basic unit tests --- .../RenderTests/ConstantFloat4Return.sdsl | 13 + assets/SDSL/RenderTests/If.sdsl | 21 ++ assets/SDSL/RenderTests/IfElse.sdsl | 18 ++ assets/SDSL/RenderTests/IfElseif.sdsl | 24 ++ .../FrameRenderer.OpenGL.cs | 27 +- src/Stride.Graphics.RHI/FrameRenderer.cs | 3 + .../Stride.Graphics.RHI.csproj | 1 + .../SDSL/ShaderMixer.cs | 274 +++++++++++++++++ src/Stride.Shaders.Experiments/Examples.cs | 275 +----------------- src/Stride.Shaders.Experiments/Program.cs | 16 +- src/Stride.Shaders.Tests/RenderingTests.cs | 238 ++++++++++++++- .../Stride.Shaders.Parsing.Tests.csproj | 3 +- .../Spirv/Processing/StreamAnalyzer.cs | 9 +- 13 files changed, 628 insertions(+), 294 deletions(-) create mode 100644 assets/SDSL/RenderTests/ConstantFloat4Return.sdsl create mode 100644 assets/SDSL/RenderTests/If.sdsl create mode 100644 assets/SDSL/RenderTests/IfElse.sdsl create mode 100644 assets/SDSL/RenderTests/IfElseif.sdsl create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs diff --git a/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl b/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl new file mode 100644 index 0000000000..c934c4779a --- /dev/null +++ b/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl @@ -0,0 +1,13 @@ +// PSMain(ExpectedResult=#FF007FFF) + +namespace Stride.Shaders.Tests; + +shader ConstantFloat4Return +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(1.0, 0.0, 0.5, 1.0); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/If.sdsl b/assets/SDSL/RenderTests/If.sdsl new file mode 100644 index 0000000000..825e563101 --- /dev/null +++ b/assets/SDSL/RenderTests/If.sdsl @@ -0,0 +1,21 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test1=1) +// PSMain(ExpectedResult=#00000000, Test1=0) + +namespace Stride.Shaders.Tests; + +shader IfTrue +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (Test1) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElse.sdsl b/assets/SDSL/RenderTests/IfElse.sdsl new file mode 100644 index 0000000000..e2572ec95c --- /dev/null +++ b/assets/SDSL/RenderTests/IfElse.sdsl @@ -0,0 +1,18 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test1=1) +// PSMain(ExpectedResult=#7F7F7F7F, Test1=0) + +namespace Stride.Shaders.Tests; + +shader IfElseTrue +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (true) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElseif.sdsl b/assets/SDSL/RenderTests/IfElseif.sdsl new file mode 100644 index 0000000000..6dde8d44e0 --- /dev/null +++ b/assets/SDSL/RenderTests/IfElseif.sdsl @@ -0,0 +1,24 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, Test=2) +// PSMain(ExpectedResult=#00000000, Test=0) + +namespace Stride.Shaders.Tests; + +shader IfElseifFalseFalse +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (Test1 == 1) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else if (Test1 == 2) + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index 78c47be271..c77e9bc0a0 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -1,6 +1,7 @@ using Silk.NET.Maths; using Silk.NET.OpenGL; using Silk.NET.Windowing; +using System.Text; namespace Stride.Graphics.RHI; @@ -24,7 +25,7 @@ public class OpenGLFrameRenderer(uint width = 800, uint height = 600, byte[]? fr byte[]? fragmentSpirv = fragmentSpirv; //Vertex shaders are run on each vertex. - private static readonly string VertexShaderSource = @" + public string VertexShaderSource = @" #version 330 core //Using version GLSL version 3.3 layout (location = 0) in vec4 vPos; @@ -35,7 +36,7 @@ void main() "; //Fragment shaders are run on each fragment/pixel of the geometry. - private static readonly string FragmentShaderSource = @" + public string FragmentShaderSource = @" #version 330 core out vec4 FragColor; @@ -75,8 +76,6 @@ public override unsafe void RenderFrame(Span result) Gl = GL.GetApi(window); // Generate a FBO - - Gl.GenFramebuffers(1, out Fbo); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, Fbo); @@ -126,7 +125,9 @@ public override unsafe void RenderFrame(Span result) unsafe { fixed (byte* spirv = fragmentSpirv) - Gl.ShaderBinary([fragmentShader], GLEnum.SpirVBinary, (void*)spirv, (uint)fragmentSpirv.Length); + Gl.ShaderBinary([fragmentShader], GLEnum.ShaderBinaryFormatSpirV, (void*)spirv, (uint)fragmentSpirv.Length); + + Gl.SpecializeShader(fragmentShader, "PSMain_wrapper", 0, null, null); } } else @@ -172,6 +173,22 @@ public override unsafe void RenderFrame(Span result) Gl.BindVertexArray(Vao); Gl.UseProgram(Shader); + foreach (var param in Parameters) + { + var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{param.Key}"); + if ((GLEnum)blockIndex == GLEnum.InvalidIndex) + continue; + Gl.UniformBlockBinding(Shader, blockIndex, 0); + + int data = param.Value; + Gl.GenBuffers(1, out uint ubo); + Gl.BindBuffer(GLEnum.UniformBuffer, ubo); + Gl.BufferData(GLEnum.UniformBuffer, sizeof(uint), &data, GLEnum.DynamicDraw); + Gl.BindBuffer(GLEnum.UniformBuffer, 0); // Unbind + + Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); + } + //Draw the geometry. Gl.DrawElements(PrimitiveType.Triangles, (uint)Indices.Length, DrawElementsType.UnsignedInt, null); diff --git a/src/Stride.Graphics.RHI/FrameRenderer.cs b/src/Stride.Graphics.RHI/FrameRenderer.cs index 228e00abaa..5b77743c9c 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.cs @@ -6,5 +6,8 @@ public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? uint height = height; byte[]? vertexSpirv = vertexSpirv; byte[]? fragmentSpirv = fragmentSpirv; + + public Dictionary Parameters { get; } = new(); + public abstract void RenderFrame(Span bytes); } \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj index 944825764d..8e2b1f0510 100644 --- a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj +++ b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs new file mode 100644 index 0000000000..4cef39cb03 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -0,0 +1,274 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Tools; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Compilers.SDSL; + +public class ShaderMixer(IExternalShaderLoader ShaderLoader) +{ + public void MergeSDSL(string entryShaderName, out byte[] bytecode) + { + // TODO: support proper shader mixin source + //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; + + var buffer = GetOrLoadShader(entryShaderName); + + // Step: expand "for" + // TODO + + // Step: build mixins: top level and (TODO) compose + var inheritanceList = new List(); + BuildInheritanceList(buffer, inheritanceList); + inheritanceList.Add(entryShaderName); + + var temp = new NewSpirvBuffer(); + var offset = 0; + var nextOffset = 0; + + foreach (var shaderName in inheritanceList) + { + var shader = GetOrLoadShader(shaderName); + offset += nextOffset; + nextOffset = 0; + shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; + foreach (var i in shader) + { + var i2 = new OpData(i.Data.Memory.Span); + temp.Add(i2); + + if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) + nextOffset = i.Data.IdResult.Value; + + if (offset > 0) + OffsetIds(i2, offset); + } + } + + var shaders = new Dictionary(); + ShaderInfo? currentShader = null; + + var names = new Dictionary(); + var importedShaders = new Dictionary(); + var idRemapping = new Dictionary(); + foreach (var i in temp) + { + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + if (idRemapping.ContainsKey(nameInstruction.Target)) + SetOpNop(i.Data.Memory.Span); + else + names.Add(nameInstruction.Target, nameInstruction.Name); + } + else if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) + { + currentShader = new ShaderInfo(); + var shaderName = shaderInstruction.ShaderName; + shaders.Add(shaderName, currentShader); + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLShaderEnd) + { + currentShader = null; + importedShaders.Clear(); + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLMixinInherit) + { + SetOpNop(i.Data.Memory.Span); + } + + if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + var functionName = names[function.ResultId]; + currentShader!.Functions.Add(functionName, function.ResultId); + + //temp.Remove(i.Position); + //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.FunctionControl, function.FunctionType); + } + + if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + { + var variableName = names[variable.ResultId]; + currentShader!.Variables.Add(variableName, variable.ResultId); + } + + if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + { + importedShaders.Add(importShader.ResultId, shaders[importShader.ShaderName]); + + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + { + var importedShader = importedShaders[importVariable.Shader]; + + var importedVariable = importedShader.Variables[importVariable.VariableName]; + + idRemapping.Add(importVariable.ResultId, importedVariable); + + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + { + var importedShader = importedShaders[importFunction.Shader]; + var importedFunction = importedShader.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + + SetOpNop(i.Data.Memory.Span); + } + + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) + op.Words[0] = to1; + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + op.Words[1] = to2; + } + } + + //Console.WriteLine("Done SDSL importing"); + //Spv.Dis(temp, true); + + // Step: merge mixins + // start from most-derived class and import on demand + // Step: analyze streams and generate in/out variables + + new TypeDuplicateRemover().Apply(temp); + + //Console.WriteLine("Done type remapping"); + //Spv.Dis(temp, true); + + var context = new SpirvContext(new()); + context.Bound = offset + nextOffset + 1; + //Spv.Dis(temp, true); + ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); + foreach (var i in temp) + { + if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + var functionName = names2[function.ResultId]; + context.Module.Functions.Add(functionName, new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); + } + } + + foreach (var type in types) + { + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); + } + + context.Insert(0, new OpCapability(Capability.Shader)); + context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); + new StreamAnalyzer().Process(temp, context); + + foreach (var inst in context.GetBuffer()) + temp.Add(inst.Data); + + new TypeDuplicateRemover().Apply(temp); + for (int i = 0; i < temp.Count; i++) + { + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + } + + temp.Sort(); + + bytecode = MemoryMarshal.AsBytes(temp.ToBuffer().Span).ToArray(); + + //File.WriteAllBytes("test.spv", bytecode); + + Spv.Dis(temp, true); + //File.WriteAllText("test.spvdis", source); + } + + Dictionary loadedShaders = new(); + + class ShaderInfo + { + public Dictionary Functions { get; } = new(); + public Dictionary Variables { get; } = new(); + } + + NewSpirvBuffer GetOrLoadShader(string name) + { + if (loadedShaders.TryGetValue(name, out var buffer)) + return buffer; + + ShaderLoader.LoadExternalReference(name, out var bytecode); + buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); + + loadedShaders.Add(name, buffer); + + return buffer; + } + + static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } + + private void BuildInheritanceList(NewSpirvBuffer buffer, List inheritanceList) + { + // Build shader name mapping + var shaderMapping = new Dictionary(); + foreach (var i in buffer) + if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + shaderMapping[importShader.ResultId] = importShader.ShaderName; + + // Check inheritance + foreach (var i in buffer) + { + if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) + { + var shaderName = shaderMapping[inherit.Shader]; + var shader = GetOrLoadShader(shaderName); + BuildInheritanceList(shader, inheritanceList); + inheritanceList.Add(shaderName); + } + } + } + + public static void OffsetIds(OpData inst, int offset) + { + foreach (var o in inst) + { + if (o.Kind == OperandKind.IdRef + || o.Kind == OperandKind.IdResult + || o.Kind == OperandKind.IdResultType) + { + for (int i = 0; i < o.Words.Length; ++i) + o.Words[i] += offset; + } + else if (o.Kind == OperandKind.PairIdRefLiteralInteger + || o.Kind == OperandKind.PairLiteralIntegerIdRef + || o.Kind == OperandKind.PairIdRefIdRef) + { + for (int i = 0; i < o.Words.Length; i += 2) + { + if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 0] += offset; + if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) + o.Words[i * 2 + 1] += offset; + } + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index d350f7827c..4b119267e1 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -4,21 +4,10 @@ using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Compilers.SDSL; -using Stride.Shaders.Core; using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; -using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using static Stride.Shaders.Spirv.Specification; using SourceLanguage = Silk.NET.Shaderc.SourceLanguage; namespace Stride.Shaders.Experiments; @@ -217,7 +206,7 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) return false; } - class ShaderLoader : IExternalShaderLoader + public class ShaderLoader : IExternalShaderLoader { public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode) { @@ -227,7 +216,7 @@ public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode = null; return false; } - var text = MonoGamePreProcessor.OpenAndRun($"./assets/SDSL/{name}.sdsl"); + var text = MonoGamePreProcessor.OpenAndRun(filename); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; return sdslc.Compile(text, out bytecode); @@ -274,262 +263,4 @@ public sealed class ShaderClassCode(string className) : ShaderSource { public string ClassName { get; } = className; } - - static Dictionary loadedShaders = new(); - - static NewSpirvBuffer GetOrLoadShader(string name) - { - if (loadedShaders.TryGetValue(name, out var buffer)) - return buffer; - - new ShaderLoader().LoadExternalReference(name, out var bytecode); - buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); - - loadedShaders.Add(name, buffer); - - return buffer; - } - - class ShaderInfo - { - public Dictionary Functions { get; } = new(); - public Dictionary Variables { get; } = new(); - } - - public static void MergeSDSL() - { - CompileSDSL(); - - var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode("TestBasic") } }; - - var buffer = GetOrLoadShader("TestBasic"); - - // Step: expand "for" - // TODO - - // Step: build mixins: top level and (TODO) compose - var inheritanceList = new List(); - BuildInheritanceList(buffer, inheritanceList); - inheritanceList.Add("TestBasic"); - - var temp = new NewSpirvBuffer(); - var offset = 0; - var nextOffset = 0; - - foreach (var shaderName in inheritanceList) - { - var shader = GetOrLoadShader(shaderName); - offset += nextOffset; - nextOffset = 0; - Spv.Dis(shader, true); - foreach (var i in shader) - { - var i2 = new OpData(i.Data.Memory.Span); - temp.Add(i2); - - if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) - nextOffset = i.Data.IdResult.Value; - - if (offset > 0) - OffsetIds(i2, offset); - } - Spv.Dis(temp, true); - } - - var shaders = new Dictionary(); - ShaderInfo? currentShader = null; - - var names = new Dictionary(); - var importedShaders = new Dictionary(); - var idRemapping = new Dictionary(); - foreach (var i in temp) - { - if (i.Data.Op == Op.OpName && (OpName)i is {} nameInstruction) - { - if (idRemapping.ContainsKey(nameInstruction.Target)) - SetOpNop(i.Data.Memory.Span); - else - names.Add(nameInstruction.Target, nameInstruction.Name); - } - else if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is {} shaderInstruction) - { - currentShader = new ShaderInfo(); - var shaderName = shaderInstruction.ShaderName; - shaders.Add(shaderName, currentShader); - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLShaderEnd) - { - currentShader = null; - importedShaders.Clear(); - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLMixinInherit) - { - SetOpNop(i.Data.Memory.Span); - } - - if (i.Data.Op == Op.OpFunction && (OpFunction)i is {} function) - { - var functionName = names[function.ResultId]; - currentShader!.Functions.Add(functionName, function.ResultId); - - //temp.Remove(i.Position); - //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.FunctionControl, function.FunctionType); - } - - if (i.Data.Op == Op.OpVariable && (OpVariable)i is {} variable && variable.Storageclass != Specification.StorageClass.Function) - { - var variableName = names[variable.ResultId]; - currentShader!.Variables.Add(variableName, variable.ResultId); - } - - if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is {} importShader) - { - importedShaders.Add(importShader.ResultId, shaders[importShader.ShaderName]); - - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is {} importVariable) - { - var importedShader = importedShaders[importVariable.Shader]; - - var importedVariable = importedShader.Variables[importVariable.VariableName]; - - idRemapping.Add(importVariable.ResultId, importedVariable); - - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is {} importFunction) - { - var importedShader = importedShaders[importFunction.Shader]; - var importedFunction = importedShader.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - - SetOpNop(i.Data.Memory.Span); - } - - foreach (var op in i.Data) - { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) - op.Words[0] = to1; - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - op.Words[1] = to2; - } - } - - Console.WriteLine("Done SDSL importing"); - Spv.Dis(temp, true); - - // Step: merge mixins - // start from most-derived class and import on demand - // Step: analyze streams and generate in/out variables - - new TypeDuplicateRemover().Apply(temp); - - Console.WriteLine("Done type remapping"); - Spv.Dis(temp, true); - - var context = new SpirvContext(new()); - context.Bound = offset + nextOffset + 1; - Spv.Dis(temp, true); - ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); - foreach (var i in temp) - { - if (i.Data.Op == Op.OpFunction && (OpFunction)i is {} function) - { - var functionName = names2[function.ResultId]; - context.Module.Functions.Add(functionName, new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); - } - } - - foreach (var type in types) - { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); - } - - context.Insert(0, new OpCapability(Capability.Shader)); - context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - new StreamAnalyzer().Process(temp, context); - - foreach (var inst in context.GetBuffer()) - temp.Add(inst.Data); - - new TypeDuplicateRemover().Apply(temp); - for (int i = 0; i < temp.Count; i++) - { - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); - } - - temp.Sort(); - - var source = Spv.Dis(temp, true); - - File.WriteAllText("test.spvdis", source); - } - - public static void OffsetIds(OpData inst, int offset) - { - foreach (var o in inst) - { - if (o.Kind == OperandKind.IdRef - || o.Kind == OperandKind.IdResult - || o.Kind == OperandKind.IdResultType) - { - for (int i = 0; i < o.Words.Length; ++i) - o.Words[i] += offset; - } - else if (o.Kind == OperandKind.PairIdRefLiteralInteger - || o.Kind == OperandKind.PairLiteralIntegerIdRef - || o.Kind == OperandKind.PairIdRefIdRef) - { - for (int i = 0; i < o.Words.Length; i += 2) - { - if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 0] += offset; - if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 1] += offset; - } - } - } - } - - static void SetOpNop(Span words) - { - words[0] = words.Length << 16; - words[1..].Clear(); - } - - private static void BuildInheritanceList(NewSpirvBuffer buffer, List inheritanceList) - { - // Build shader name mapping - var shaderMapping = new Dictionary(); - foreach (var i in buffer) - if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader) i is {} importShader) - shaderMapping[importShader.ResultId] = importShader.ShaderName; - - // Check inheritance - foreach (var i in buffer) - { - if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is {} inherit) - { - var shaderName = shaderMapping[inherit.Shader]; - var shader = GetOrLoadShader(shaderName); - BuildInheritanceList(shader, inheritanceList); - inheritanceList.Add(shaderName); - } - } - } -} - - +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 1c38010f04..e2a970e7da 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -1,7 +1,19 @@ -using Stride.Shaders.Experiments; +using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Experiments; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Tools; + +Examples.TranslateHLSL(); //Examples.CompileSDSL(); -Examples.MergeSDSL(); +var shaderMixer = new ShaderMixer(new Examples.ShaderLoader()); +shaderMixer.MergeSDSL("TestBasic", out var bytecode); +var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); +var source = Spv.Dis(buffer, true); +File.WriteAllText("test.spvdis", source); + + // Examples.TryAllFiles(); // Examples.CreateShader(); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 556b22e11b..98159f7c5c 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -1,30 +1,246 @@ -using Stride.Shaders.Parsing; -using Stride.Shaders.Parsing.Analysis; -using Silk.NET.OpenGL; -using Stride.Graphics.RHI; +using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; +using Silk.NET.OpenGL; +using Silk.NET.SPIRV.Cross; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; +using Stride.Graphics.RHI; +using Stride.Shaders.Compilers; +using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Diagnostics.CodeAnalysis; +using System.Globalization; +using System.IO; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using Xunit.Abstractions; namespace Stride.Shaders.Parsing.Tests; -public class RenderingTests +public class RenderingTests(ITestOutputHelper Output) { - static int width = 800; - static int height = 600; + static int width = 1; + static int height = 1; + + class ShaderLoader : IExternalShaderLoader + { + public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode) + { + var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; + if (!File.Exists(filename)) + { + bytecode = null; + return false; + } + var text = MonoGamePreProcessor.OpenAndRun(filename); + var sdslc = new SDSLC(); + sdslc.ShaderLoader = this; + return sdslc.Compile(text, out bytecode); + } + } [Theory] - [InlineData("test.spv")] - public void RenderTest1(string path) + [MemberData(nameof(GetTestFiles))] + public void RenderTest1(string shaderName, string methodName, Dictionary parameters) { - // var shader = File.ReadAllBytes(path); - var renderer = new OpenGLFrameRenderer(); + // Compiler shader + var shaderMixer = new ShaderMixer(new ShaderLoader()); + shaderMixer.MergeSDSL(shaderName, out var bytecode); + File.WriteAllBytes($"{shaderName}.spv", bytecode); + + // Convert to GLSL + var translator = new SpirvTranslator(bytecode.AsMemory().Cast()); + var code = translator.Translate(Backend.Glsl); + + Output.WriteLine(code); + + // Execute test + var renderer = new OpenGLFrameRenderer((uint)width, (uint)height); + + // Setup parameters + foreach (var param in parameters) + { + // Note: Name is cbuffer name (not variable) + // For now, value is only a single integer, but we might support more later. + if (int.TryParse(param.Value, out var value)) + renderer.Parameters.Add(param.Key, value); + } + + renderer.FragmentShaderSource = code; using var frameBuffer = MemoryOwner.Allocate(width * height * 4); renderer.RenderFrame(frameBuffer.Span); var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); Assert.Equal(width, pixels.Width); Assert.Equal(height, pixels.Height); + + // Check output color value against expected result + var expectedColor = StringToRgba(parameters["ExpectedResult"]); + var pixel = pixels[0, 0].PackedValue; + Assert.Equal(expectedColor, pixel); + } + + public static IEnumerable GetTestFiles() + { + foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/RenderTests")) + { + // Parse header + var code = File.ReadAllLines(filename); + + foreach (var test in TestHeaderParser.ParseHeaders(code)) + { + var shadername = Path.GetFileNameWithoutExtension(filename); + if (shadername == "IfElseif") + yield return [shadername, test.Name, test.Parameters]; + } + } + + yield break; + } + + public static uint StringToRgba(string? stringColor) + { + var intValue = 0xFF000000; + if (stringColor?.StartsWith('#') == true) + { + if (stringColor.Length == "#00000000".Length && uint.TryParse(stringColor.AsSpan(1, 8), NumberStyles.HexNumber, null, out intValue)) + { + intValue = ((intValue & 0x000000FF) << 24) + | (intValue & 0x0000FF00) << 8 + | ((intValue & 0x00FF0000) >> 8) + | (intValue & 0xFF000000) >> 24; + } + } + return intValue; + } + +} + +// Note: generated with ChatGPT +public sealed class TestHeader +{ + public string Name { get; } + public Dictionary Parameters { get; } + + public TestHeader(string name, Dictionary parameters) + { + Name = name; + Parameters = parameters; + } + + public override string ToString() => + $"{Name}: {string.Join(", ", Parameters)}"; +} + +public static class TestHeaderParser +{ + // Matches: // TestName (Param1=..., Param2=..., ...) + // name = "Test" in your example + // args = "Param1=1, Param2=1, ExpectedResult=0x7F7F7F7F" + private static readonly Regex HeaderRegex = + new Regex(@"^\s*//\s*(?[^(]+?)\s*\((?.*)\)\s*$", + RegexOptions.Compiled); + + /// + /// Parse all headers from the provided lines. + /// + public static IEnumerable ParseHeaders(IEnumerable lines) + { + foreach (var line in lines) + { + var m = HeaderRegex.Match(line); + if (!m.Success) continue; + + var name = m.Groups["name"].Value.Trim(); + var args = m.Groups["args"].Value; + + var parameters = ParseParameters(args); + yield return new TestHeader(name, parameters); + } + } + + /// + /// Splits "A=1, B=foo, ExpectedResult=0xFF" into a dictionary. + /// Supports quoted values with commas: A="hello, world". + /// + private static Dictionary ParseParameters(string args) + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var piece in SplitArgs(args)) + { + if (string.IsNullOrWhiteSpace(piece)) continue; + + var eqIndex = piece.IndexOf('='); + if (eqIndex < 0) + { + // Parameter without value; store empty string + var keyOnly = piece.Trim(); + if (!result.ContainsKey(keyOnly)) + result[keyOnly] = string.Empty; + continue; + } + + var key = piece.Substring(0, eqIndex).Trim(); + var value = piece.Substring(eqIndex + 1).Trim(); + + // Strip matching quotes if present + if (value.Length >= 2 && + ((value[0] == '"' && value[^1] == '"') || (value[0] == '\'' && value[^1] == '\''))) + { + value = value.Substring(1, value.Length - 2); + } + + // Last-in wins on duplicate keys + result[key] = value; + } + return result; + } + + /// + /// Splits by commas but ignores commas inside quotes. + /// Accepts both single- and double-quoted values. + /// + private static IEnumerable SplitArgs(string args) + { + if (string.IsNullOrEmpty(args)) + yield break; + + var current = new List(args.Length); + bool inSingle = false, inDouble = false; + + for (int i = 0; i < args.Length; i++) + { + char c = args[i]; + + if (c == '\'' && !inDouble) + { + inSingle = !inSingle; + current.Add(c); + continue; + } + + if (c == '"' && !inSingle) + { + inDouble = !inDouble; + current.Add(c); + continue; + } + + if (c == ',' && !inSingle && !inDouble) + { + yield return new string(current.ToArray()).Trim(); + current.Clear(); + continue; + } + + current.Add(c); + } + + if (current.Count > 0) + yield return new string(current.ToArray()).Trim(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 9d0d7a2622..38c0472654 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -1,4 +1,4 @@ - + net9.0 @@ -25,6 +25,7 @@ + diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 3f0c19ab90..4071307189 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -32,8 +32,10 @@ class StreamInfo(string? semantic, string name, SymbolType type, int id) public void Process(NewSpirvBuffer buffer, SpirvContext context) { - var entryPointVS = context.Module.Functions["VSMain"]; - var entryPointPS = context.Module.Functions["PSMain"]; + context.Module.Functions.TryGetValue("VSMain", out var entryPointVS); + context.Module.Functions.TryGetValue("PSMain", out var entryPointPS); + if (entryPointPS.Id == 0) + throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); var streams = CreateStreams(buffer, context); @@ -52,7 +54,8 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Read = false; } PropagateStreamsFromPreviousStage(streams); - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + if (entryPointVS.Id != 0) + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } From ccf4a7caea7363d22f1cab8a02178b0e69af6783 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Sep 2025 17:21:40 +0900 Subject: [PATCH 0473/1182] Added better support for cbuffer --- .../Parsing/OpDataEnumerator.cs | 4 +- .../SPVGenerator.Instructions.cs | 1 + .../Spirv/Processing/StreamAnalyzer.cs | 54 ++++++++++++++++--- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 9445d53b0e..525f9fceda 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -123,8 +123,8 @@ public SpvOperand ParseCurrent() { Op.OpDecorate => oid switch { - 0 => new(OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)), - 1 => new(OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)), + 0 => new(logOp.Name, OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)), + 1 => new(logOp.Name, OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)), 2 => new SpvOperand() with { Kind = (Decoration)Operands[1] switch diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 8680bdeccd..572e4b577f 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -135,6 +135,7 @@ static string ToSpreadOperator(OperandData operand) (string s, "?") when s.Contains("Enum") => $".. {fieldName} is null ? (Span)[] : [(int){fieldName}.Value]", (string, "*") => $".. {fieldName}.Words", (string, "?") => $".. {fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words", + (_, "?") => $".. {fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words", _ => $".. {fieldName}.AsDisposableLiteralValue().Words" }; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 4071307189..abd7c96214 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -30,6 +30,10 @@ class StreamInfo(string? semantic, string name, SymbolType type, int id) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } + record struct AnalysisResult(SortedList Streams, List Blocks) + { + } + public void Process(NewSpirvBuffer buffer, SpirvContext context) { context.Module.Functions.TryGetValue("VSMain", out var entryPointVS); @@ -37,7 +41,8 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) if (entryPointPS.Id == 0) throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); - var streams = CreateStreams(buffer, context); + var analysisResult = Analyze(buffer, context); + var streams = analysisResult.Streams; // Expected at the end of pixel shader foreach (var stream in streams) @@ -45,7 +50,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) stream.Value.Stream.Output = true; } - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, streams); + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -55,7 +60,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) } PropagateStreamsFromPreviousStage(streams); if (entryPointVS.Id != 0) - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, streams); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult); buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } @@ -70,15 +75,20 @@ private static void PropagateStreamsFromPreviousStage(SortedList CreateStreams(NewSpirvBuffer buffer, SpirvContext context) + private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { var streams = new SortedList(); + HashSet blockTypes = new(); + Dictionary blockPointerTypes = new(); + List blockIds = new(); + // Build name table SortedList nameTable = []; SortedList semanticTable = []; foreach (var instruction in buffer) { + // Names { if (instruction.Op == Op.OpName && ((OpName)instruction) is @@ -103,6 +113,32 @@ private static void PropagateStreamsFromPreviousStage(SortedList streams) + private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult) { + var streams = analysisResult.Streams; + ProcessMethod(buffer, entryPointId, streams); var stage = executionModel switch @@ -218,13 +256,15 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count]; + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Streams.Count]; for (int i = 0; i < inputStreams.Count; i++) pvariables[i] = inputStreams[i].Id; for (int i = 0; i < outputStreams.Count; i++) pvariables[inputStreams.Count + i] = outputStreams[i].Id; for (int i = 0; i < privateStreams.Count; i++) pvariables[inputStreams.Count + outputStreams.Count + i] = privateStreams[i].Id; + for (int i = 0; i < analysisResult.Blocks.Count; i++) + pvariables[inputStreams.Count + outputStreams.Count + privateStreams.Count + i] = analysisResult.Blocks[i]; context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); } From df712068aa8aec2790d284fa1febc4d1f3ca8239 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Sep 2025 17:44:45 +0900 Subject: [PATCH 0474/1182] Rearranged unit tests --- assets/SDSL/RenderTests/If.sdsl | 8 +++--- assets/SDSL/RenderTests/IfElse.sdsl | 13 +++++++--- assets/SDSL/RenderTests/IfElseifElse.sdsl | 26 ++++++++++++++++++++ assets/SDSL/RenderTests/IfElseifElseif.sdsl | 27 +++++++++++++++++++++ src/Stride.Shaders.Tests/RenderingTests.cs | 14 +++++------ 5 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 assets/SDSL/RenderTests/IfElseifElse.sdsl create mode 100644 assets/SDSL/RenderTests/IfElseifElseif.sdsl diff --git a/assets/SDSL/RenderTests/If.sdsl b/assets/SDSL/RenderTests/If.sdsl index 825e563101..fa669ecdac 100644 --- a/assets/SDSL/RenderTests/If.sdsl +++ b/assets/SDSL/RenderTests/If.sdsl @@ -1,9 +1,9 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test1=1) -// PSMain(ExpectedResult=#00000000, Test1=0) +// PSMain(ExpectedResult=#FFFFFFFF, Test=1) +// PSMain(ExpectedResult=#00000000, Test=0) namespace Stride.Shaders.Tests; -shader IfTrue +shader If { stream float4 ColorTarget : SV_Target0; @@ -15,7 +15,7 @@ shader IfTrue void PSMain() { streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); - if (Test1) + if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElse.sdsl b/assets/SDSL/RenderTests/IfElse.sdsl index e2572ec95c..713c501037 100644 --- a/assets/SDSL/RenderTests/IfElse.sdsl +++ b/assets/SDSL/RenderTests/IfElse.sdsl @@ -1,16 +1,21 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test1=1) -// PSMain(ExpectedResult=#7F7F7F7F, Test1=0) +// PSMain(ExpectedResult=#FFFFFFFF, Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, Test=0) namespace Stride.Shaders.Tests; -shader IfElseTrue +shader IfElse { stream float4 ColorTarget : SV_Target0; + cbuffer Test + { + int Test1; + } + void PSMain() { streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); - if (true) + if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); diff --git a/assets/SDSL/RenderTests/IfElseifElse.sdsl b/assets/SDSL/RenderTests/IfElseifElse.sdsl new file mode 100644 index 0000000000..57ba15ca2f --- /dev/null +++ b/assets/SDSL/RenderTests/IfElseifElse.sdsl @@ -0,0 +1,26 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, Test=2) +// PSMain(ExpectedResult=#FF7F7F7F, Test=0) + +namespace Stride.Shaders.Tests; + +shader IfElseifFalseFalse +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (Test1 == 1) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else if (Test1 == 2) + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + else + streams.ColorTarget = float4(1.0, 0.5, 0.5, 0.5); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElseifElseif.sdsl b/assets/SDSL/RenderTests/IfElseifElseif.sdsl new file mode 100644 index 0000000000..defc4b8bbb --- /dev/null +++ b/assets/SDSL/RenderTests/IfElseifElseif.sdsl @@ -0,0 +1,27 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, Test=2) +// PSMain(ExpectedResult=#FF7F7F7F, Test=3) +// PSMain(ExpectedResult=#00000000, Test=0) + +namespace Stride.Shaders.Tests; + +shader IfElseifFalseFalse +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (Test1 == 1) + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + else if (Test1 == 2) + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + else if (Test1 == 3) + streams.ColorTarget = float4(1.0, 0.5, 0.5, 0.5); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 98159f7c5c..82ab39dbd1 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -46,7 +46,7 @@ public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] [Theory] [MemberData(nameof(GetTestFiles))] - public void RenderTest1(string shaderName, string methodName, Dictionary parameters) + public void RenderTest1(string shaderName, string methodName, string args) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader()); @@ -63,6 +63,7 @@ public void RenderTest1(string shaderName, string methodName, Dictionary GetTestFiles() foreach (var test in TestHeaderParser.ParseHeaders(code)) { var shadername = Path.GetFileNameWithoutExtension(filename); - if (shadername == "IfElseif") - yield return [shadername, test.Name, test.Parameters]; + yield return [shadername, test.Name, test.Parameters]; } } @@ -124,9 +124,9 @@ public static uint StringToRgba(string? stringColor) public sealed class TestHeader { public string Name { get; } - public Dictionary Parameters { get; } + public string Parameters { get; } - public TestHeader(string name, Dictionary parameters) + public TestHeader(string name, string parameters) { Name = name; Parameters = parameters; @@ -159,7 +159,7 @@ public static IEnumerable ParseHeaders(IEnumerable lines) var args = m.Groups["args"].Value; var parameters = ParseParameters(args); - yield return new TestHeader(name, parameters); + yield return new TestHeader(name, args); } } @@ -167,7 +167,7 @@ public static IEnumerable ParseHeaders(IEnumerable lines) /// Splits "A=1, B=foo, ExpectedResult=0xFF" into a dictionary. /// Supports quoted values with commas: A="hello, world". /// - private static Dictionary ParseParameters(string args) + public static Dictionary ParseParameters(string args) { var result = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var piece in SplitArgs(args)) From cd737124dcb40bdf19c3a6014caaac607993402a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 30 Sep 2025 11:18:51 +0900 Subject: [PATCH 0475/1182] Added tests for continue/break --- assets/SDSL/RenderTests/For.sdsl | 17 +++++++++ assets/SDSL/RenderTests/ForBreak.sdsl | 26 ++++++++++++++ assets/SDSL/RenderTests/ForContinue.sdsl | 30 ++++++++++++++++ .../Parsing/SDSL/AST/Expression.cs | 9 +---- .../Parsing/SDSL/AST/Statements.cs | 35 +++++++++++++++++++ .../Spirv/Building/Builder.Expressions.cs | 14 +++++++- 6 files changed, 122 insertions(+), 9 deletions(-) create mode 100644 assets/SDSL/RenderTests/For.sdsl create mode 100644 assets/SDSL/RenderTests/ForBreak.sdsl create mode 100644 assets/SDSL/RenderTests/ForContinue.sdsl diff --git a/assets/SDSL/RenderTests/For.sdsl b/assets/SDSL/RenderTests/For.sdsl new file mode 100644 index 0000000000..4cbdd90453 --- /dev/null +++ b/assets/SDSL/RenderTests/For.sdsl @@ -0,0 +1,17 @@ +// PSMain(ExpectedResult=#7F7F7F7F) + +namespace Stride.Shaders.Tests; + +shader For +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < 5; ++i) + { + streams.ColorTarget += float4(0.1, 0.1, 0.1, 0.1); + } + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/ForBreak.sdsl b/assets/SDSL/RenderTests/ForBreak.sdsl new file mode 100644 index 0000000000..5fec3f2265 --- /dev/null +++ b/assets/SDSL/RenderTests/ForBreak.sdsl @@ -0,0 +1,26 @@ +// PSMain(ExpectedResult=#FFFFFFFF, Test=10) +// PSMain(ExpectedResult=#7F7F7F7F, Test=5) +// PSMain(ExpectedResult=#00000000, Test=0) + +namespace Stride.Shaders.Tests; + +shader ForBreak +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < 20; ++i) + { + if (i == Test1) + break; + streams.ColorTarget += float4(0.1, 0.1, 0.1, 0.1); + } + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/ForContinue.sdsl b/assets/SDSL/RenderTests/ForContinue.sdsl new file mode 100644 index 0000000000..9f690552b4 --- /dev/null +++ b/assets/SDSL/RenderTests/ForContinue.sdsl @@ -0,0 +1,30 @@ +// PSMain(ExpectedResult=#7F7F0000) + +namespace Stride.Shaders.Tests; + +shader ForContinue +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + for (int i = 0; i < 10; ++i) + { + if (i % 2 == 0) + continue; + streams.ColorTarget += float4(0.1, 0.0, 0.0, 0.0); + } + for (i = 0; i < 10; ++i) + { + if (i % 2 == 1) + continue; + streams.ColorTarget += float4(0.0, 0.1, 0.0, 0.0); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 64facef26e..ce61ccb7a0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -23,14 +23,7 @@ public abstract class Expression(TextLocation info) : ValueNode(info) public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var result = Compile(table, shader, compiler); - var type = compiler.Context.ReverseTypes[result.TypeId]; - if (type is PointerType pointerType) - { - type = pointerType.BaseType; - var inst = compiler.Builder.Insert(new OpLoad(compiler.Context.Types[type], compiler.Context.Bound++, result.Id, null)); - result = new(inst.ResultId, inst.ResultType); - } - return result; + return compiler.Builder.AsValue(compiler.Context, result); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 0e34a2a520..a3190957b5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -205,6 +205,41 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit source = new(sourceLoad, underlyingType); } + if (variable.Operator != AssignOperator.Simple) + { + var binaryOperator = (variable.Operator) switch + { + AssignOperator.Plus => Operator.Plus, + AssignOperator.Minus => Operator.Minus, + AssignOperator.Mul => Operator.Mul, + AssignOperator.Div => Operator.Div, + AssignOperator.Mod => Operator.Mod, + AssignOperator.RightShift => Operator.RightShift, + AssignOperator.LeftShift => Operator.LeftShift, + AssignOperator.AND => Operator.AND, + AssignOperator.OR => Operator.OR, + AssignOperator.XOR => Operator.XOR, + }; + + var left = builder.AsValue(context, target); + var right = builder.AsValue(context, source); + + if ( + OperatorTable.BinaryOperationResultingType( + variable.Variable.ValueType ?? throw new NotImplementedException("Missing type"), + variable.Value.ValueType ?? throw new NotImplementedException("Missing type"), + binaryOperator, + out var t + ) + ) + Type = t; + else + table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); + + source = builder.BinaryOperation(context, context.GetOrRegister(Type), left, binaryOperator, right); + } + + builder.Insert(new OpStore(target.Id, source.Id, null)); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index c092dac035..844de604b7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -9,6 +9,18 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { + public SpirvValue AsValue(SpirvContext context, SpirvValue result) + { + var type = context.ReverseTypes[result.TypeId]; + if (type is PointerType pointerType) + { + type = pointerType.BaseType; + var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null)); + result = new(inst.ResultId, inst.ResultType); + } + return result; + } + public SpirvValue BinaryOperation(SpirvContext context, int resultType, in SpirvValue left, Operator op, in SpirvValue right, string? name = null) { @@ -18,7 +30,7 @@ public SpirvValue BinaryOperation(SpirvContext context, int resultType, in Spirv when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) => Buffer.InsertData(Position++, new OpIAdd(resultType, context.Bound++, left.Id, right.Id)), - (Operator.Plus, ScalarType l, ScalarType r) + (Operator.Plus, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) => Buffer.InsertData(Position++, new OpFAdd(resultType, context.Bound++, left.Id, right.Id)), From 53636f2c8ead3c88893ccd44114b3206c4951248 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 1 Oct 2025 08:45:49 +0900 Subject: [PATCH 0476/1182] Made more clear that test parameters uploads a cbuffer rather than a member inside a cbuffer for now --- assets/SDSL/RenderTests/ForBreak.sdsl | 6 ++-- assets/SDSL/RenderTests/If.sdsl | 4 +-- assets/SDSL/RenderTests/IfElse.sdsl | 4 +-- assets/SDSL/RenderTests/IfElseif.sdsl | 6 ++-- assets/SDSL/RenderTests/IfElseifElse.sdsl | 6 ++-- assets/SDSL/RenderTests/IfElseifElseif.sdsl | 8 ++--- .../FrameRenderer.OpenGL.cs | 31 ++++++++++++------- src/Stride.Graphics.RHI/FrameRenderer.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 7 +---- 9 files changed, 38 insertions(+), 36 deletions(-) diff --git a/assets/SDSL/RenderTests/ForBreak.sdsl b/assets/SDSL/RenderTests/ForBreak.sdsl index 5fec3f2265..c348ea039e 100644 --- a/assets/SDSL/RenderTests/ForBreak.sdsl +++ b/assets/SDSL/RenderTests/ForBreak.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=10) -// PSMain(ExpectedResult=#7F7F7F7F, Test=5) -// PSMain(ExpectedResult=#00000000, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=10) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=5) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/If.sdsl b/assets/SDSL/RenderTests/If.sdsl index fa669ecdac..191af2641e 100644 --- a/assets/SDSL/RenderTests/If.sdsl +++ b/assets/SDSL/RenderTests/If.sdsl @@ -1,5 +1,5 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=1) -// PSMain(ExpectedResult=#00000000, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElse.sdsl b/assets/SDSL/RenderTests/IfElse.sdsl index 713c501037..9760baa68d 100644 --- a/assets/SDSL/RenderTests/IfElse.sdsl +++ b/assets/SDSL/RenderTests/IfElse.sdsl @@ -1,5 +1,5 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseif.sdsl b/assets/SDSL/RenderTests/IfElseif.sdsl index 6dde8d44e0..47c14cae4c 100644 --- a/assets/SDSL/RenderTests/IfElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseif.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, Test=2) -// PSMain(ExpectedResult=#00000000, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseifElse.sdsl b/assets/SDSL/RenderTests/IfElseifElse.sdsl index 57ba15ca2f..54376200cb 100644 --- a/assets/SDSL/RenderTests/IfElseifElse.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElse.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, Test=2) -// PSMain(ExpectedResult=#FF7F7F7F, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) +// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseifElseif.sdsl b/assets/SDSL/RenderTests/IfElseifElseif.sdsl index defc4b8bbb..ac19946473 100644 --- a/assets/SDSL/RenderTests/IfElseifElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElseif.sdsl @@ -1,7 +1,7 @@ -// PSMain(ExpectedResult=#FFFFFFFF, Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, Test=2) -// PSMain(ExpectedResult=#FF7F7F7F, Test=3) -// PSMain(ExpectedResult=#00000000, Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) +// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=3) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) namespace Stride.Shaders.Tests; diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index c77e9bc0a0..1ca284d207 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -175,18 +175,25 @@ public override unsafe void RenderFrame(Span result) foreach (var param in Parameters) { - var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{param.Key}"); - if ((GLEnum)blockIndex == GLEnum.InvalidIndex) - continue; - Gl.UniformBlockBinding(Shader, blockIndex, 0); - - int data = param.Value; - Gl.GenBuffers(1, out uint ubo); - Gl.BindBuffer(GLEnum.UniformBuffer, ubo); - Gl.BufferData(GLEnum.UniformBuffer, sizeof(uint), &data, GLEnum.DynamicDraw); - Gl.BindBuffer(GLEnum.UniformBuffer, 0); // Unbind - - Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); + if (param.Key.StartsWith("cbuffer.")) + { + var cbufferName = param.Key.Substring("cbuffer.".Length); + var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{cbufferName}"); + if ((GLEnum)blockIndex == GLEnum.InvalidIndex) + continue; + Gl.UniformBlockBinding(Shader, blockIndex, 0); + + // Note: we only support a single int value for now + if (!int.TryParse(param.Value, out var data)) + throw new NotImplementedException("Tests only support a single integer in cbuffer"); + + Gl.GenBuffers(1, out uint ubo); + Gl.BindBuffer(GLEnum.UniformBuffer, ubo); + Gl.BufferData(GLEnum.UniformBuffer, sizeof(uint), &data, GLEnum.DynamicDraw); + Gl.BindBuffer(GLEnum.UniformBuffer, 0); // Unbind + + Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); + } } //Draw the geometry. diff --git a/src/Stride.Graphics.RHI/FrameRenderer.cs b/src/Stride.Graphics.RHI/FrameRenderer.cs index 5b77743c9c..d172a34d5e 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.cs @@ -7,7 +7,7 @@ public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? byte[]? vertexSpirv = vertexSpirv; byte[]? fragmentSpirv = fragmentSpirv; - public Dictionary Parameters { get; } = new(); + public Dictionary Parameters { get; } = new(); public abstract void RenderFrame(Span bytes); } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 82ab39dbd1..e2d2df0ae4 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -65,12 +65,7 @@ public void RenderTest1(string shaderName, string methodName, string args) // Setup parameters var parameters = TestHeaderParser.ParseParameters(args); foreach (var param in parameters) - { - // Note: Name is cbuffer name (not variable) - // For now, value is only a single integer, but we might support more later. - if (int.TryParse(param.Value, out var value)) - renderer.Parameters.Add(param.Key, value); - } + renderer.Parameters.Add(param.Key, param.Value); renderer.FragmentShaderSource = code; using var frameBuffer = MemoryOwner.Allocate(width * height * 4); From 73e208eb0910ea30f3115d50a2eb24b735b0f01d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 1 Oct 2025 21:42:28 +0900 Subject: [PATCH 0477/1182] Added unit test for simple inheritance and stream (VS+PS) --- .../SDSL/RenderTests/SimpleInheritance.sdsl | 26 +++++ .../RenderTests/SimpleInheritanceBase.sdsl | 11 ++ .../FrameRenderer.OpenGL.cs | 62 ++++++++-- .../SpirvTranslator.cs | 110 ++++++++++++------ src/Stride.Shaders.Tests/RenderingTests.cs | 15 ++- .../Spirv/Processing/StreamAnalyzer.cs | 53 ++++++--- 6 files changed, 216 insertions(+), 61 deletions(-) create mode 100644 assets/SDSL/RenderTests/SimpleInheritance.sdsl create mode 100644 assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl diff --git a/assets/SDSL/RenderTests/SimpleInheritance.sdsl b/assets/SDSL/RenderTests/SimpleInheritance.sdsl new file mode 100644 index 0000000000..bb558aa862 --- /dev/null +++ b/assets/SDSL/RenderTests/SimpleInheritance.sdsl @@ -0,0 +1,26 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) + +namespace Stride.Shaders.Tests; + +shader SimpleInheritance : SimpleInheritanceBase +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ExtraColor : COLOR; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void Test() + { + streams.ColorTarget = streams.ExtraColor; + SetColor(streams.ExtraColor); + } + + void PSMain() + { + Test(); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl new file mode 100644 index 0000000000..87e572851a --- /dev/null +++ b/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl @@ -0,0 +1,11 @@ +namespace Stride.Shaders.Tests; + +shader SimpleInheritanceBase +{ + stream float4 ColorTarget : SV_Target0; + + void SetColor(float4 color) + { + streams.ColorTarget = color; + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index 1ca284d207..91b3372a50 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -1,6 +1,7 @@ using Silk.NET.Maths; using Silk.NET.OpenGL; using Silk.NET.Windowing; +using System; using System.Text; namespace Stride.Graphics.RHI; @@ -112,10 +113,10 @@ public override unsafe void RenderFrame(Span result) Gl.CompileShader(vertexShader); //Checking the shader for compilation errors. - string infoLog = Gl.GetShaderInfoLog(vertexShader); - if (!string.IsNullOrWhiteSpace(infoLog)) + string shaderLog = Gl.GetShaderInfoLog(vertexShader); + if (!string.IsNullOrWhiteSpace(shaderLog)) { - Console.WriteLine($"Error compiling vertex shader {infoLog}"); + Console.WriteLine($"Error compiling vertex shader {shaderLog}"); } //Creating a fragment shader. @@ -137,10 +138,10 @@ public override unsafe void RenderFrame(Span result) } //Checking the shader for compilation errors. - infoLog = Gl.GetShaderInfoLog(fragmentShader); - if (!string.IsNullOrWhiteSpace(infoLog)) + shaderLog = Gl.GetShaderInfoLog(fragmentShader); + if (!string.IsNullOrWhiteSpace(shaderLog)) { - Console.WriteLine($"Error compiling fragment shader {infoLog}"); + Console.WriteLine($"Error compiling fragment shader {shaderLog}"); } //Combining the shaders under one shader program. @@ -151,9 +152,10 @@ public override unsafe void RenderFrame(Span result) //Checking the linking for errors. Gl.GetProgram(Shader, GLEnum.LinkStatus, out var status); + var programLog = Gl.GetProgramInfoLog(Shader); if (status == 0) { - Console.WriteLine($"Error linking shader {Gl.GetProgramInfoLog(Shader)}"); + Console.WriteLine($"Error linking shader {programLog}"); } //Delete the no longer useful individual shaders; @@ -162,9 +164,43 @@ public override unsafe void RenderFrame(Span result) Gl.DeleteShader(vertexShader); Gl.DeleteShader(fragmentShader); - //Tell opengl how to give the data to the shaders. - Gl.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); - Gl.EnableVertexAttribArray(0); + + Gl.GetProgram(Shader, GLEnum.ActiveAttributes, out var attributeCount); + for (uint i = 0; i < attributeCount; ++i) + { + Gl.GetActiveAttrib(Shader, i, 256, out _, out var attribSize, out AttributeType attribType, out string attribName); + + if (attribName == "in_VS_Position" || attribName == "vPos") + { + //Tell opengl how to give the data to the shaders. + Gl.VertexAttribPointer(i, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); + Gl.EnableVertexAttribArray(i); + } + else + { + foreach (var param in Parameters) + { + if (!param.Key.StartsWith("stream.") || !attribName.StartsWith("in_VS_")) + continue; + + var paramName = param.Key.Substring("stream.".Length); + attribName = attribName.Substring("in_VS_".Length); + + if (paramName == attribName) + { + if (attribType == AttributeType.Float) + Gl.VertexAttrib1(i, float.Parse(param.Value)); + else if (attribType == AttributeType.Int) + Gl.VertexAttrib1(i, int.Parse(param.Value)); + else if (attribType == AttributeType.FloatVec4) + { + var values = param.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries); + Gl.VertexAttrib4(i, float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3])); + } + } + } + } + } // Just render once Gl.Clear((uint)ClearBufferMask.ColorBufferBit); @@ -200,8 +236,10 @@ public override unsafe void RenderFrame(Span result) Gl.DrawElements(PrimitiveType.Triangles, (uint)Indices.Length, DrawElementsType.UnsignedInt, null); Gl.ReadPixels(0, 0, width, height, GLEnum.Rgba, GLEnum.UnsignedByte, result); - window?.Close(); - window?.Dispose(); + // Useful with RenderDoc + window.SwapBuffers(); + window.Close(); + window.Dispose(); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index b549f52c43..3b73cc8191 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -1,48 +1,92 @@ +using Silk.NET.Core.Native; +using Silk.NET.SPIRV; +using Silk.NET.SPIRV.Cross; using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Text; -using Silk.NET.Core.Native; -using Silk.NET.SPIRV.Cross; namespace Stride.Shaders.Compilers; -public record struct SpirvTranslator(ReadOnlyMemory Words) +public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { static readonly Cross cross = Cross.GetApi(); - - public readonly string Translate(Backend backend = Backend.Hlsl) + + public List<(string Name, ExecutionModel ExecutionModel)> GetEntryPoints(Backend backend = Backend.Hlsl) + { + Context* context = null; + ParsedIr* ir = null; + Compiler* compiler = null; + if (cross.ContextCreate(&context) != Result.Success) + throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); + fixed (uint* w = Words.Span) + if (cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) + throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); + + cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => + { + var error = Marshal.PtrToStringAnsi((IntPtr)errorData); + Console.WriteLine(error); + }), null); + + if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) + throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + + var result = new List<(string Name, ExecutionModel ExecutionModel)>(); + EntryPoint * entry_points = null; + nuint num_entry_points = 0; + bool entryPointFound = false; + cross.CompilerGetEntryPoints(compiler, &entry_points, &num_entry_points); + for (int i = 0; i < (int)num_entry_points; ++i) + { + var entryPointModel = entry_points[i].ExecutionModel; + var entryPointName = Marshal.PtrToStringAnsi((IntPtr)entry_points[i].Name)!; + result.Add((entryPointName, entryPointModel)); + } + + + cross.ContextReleaseAllocations(context); + cross.ContextDestroy(context); + + return result; + } + + public readonly string Translate(Backend backend = Backend.Hlsl, (string Name, ExecutionModel ExecutionModel)? entryPoint = null) { string? translatedCode = null; - unsafe + Context* context = null; + ParsedIr* ir = null; + Compiler* compiler = null; + Resources* resources = null; + byte* translated = null; + if (cross.ContextCreate(&context) != Result.Success) + throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); + fixed (uint* w = Words.Span) + if (cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) + throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); + + cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => { - Context* context = null; - ParsedIr* ir = null; - Compiler* compiler = null; - Resources* resources = null; - byte* translated = null; - if (cross.ContextCreate(&context) != Result.Success) - throw new Exception($"{cross.ContextCreate(&context)} : Could not create spirv context"); - fixed (uint* w = Words.Span) - if (cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir) != Result.Success) - throw new Exception($"{cross.ContextParseSpirv(context, w, (nuint)Words.Length, &ir)} : Could not parse spirv"); - - cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => - { - var error = Marshal.PtrToStringAnsi((IntPtr)errorData); - Console.WriteLine(error); - }), null); - - if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) - throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); - if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) - throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); - if (cross.CompilerCompile(compiler, &translated) != Result.Success) - throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); - - translatedCode = SilkMarshal.PtrToString((nint)translated); - cross.ContextReleaseAllocations(context); - cross.ContextDestroy(context); + var error = Marshal.PtrToStringAnsi((IntPtr)errorData); + Console.WriteLine(error); + }), null); + + if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) + throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + + if (entryPoint != null) + { + if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.Name, entryPoint.Value.ExecutionModel) != Result.Success) + throw new Exception($"{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.Name, entryPoint.Value.ExecutionModel)} : could not set entry point"); } + + if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) + throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); + if (cross.CompilerCompile(compiler, &translated) != Result.Success) + throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); + + translatedCode = SilkMarshal.PtrToString((nint)translated); + cross.ContextReleaseAllocations(context); + cross.ContextDestroy(context); return translatedCode ?? throw new Exception("Could not translate code"); } } diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index e2d2df0ae4..18c3506589 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -17,6 +17,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Text.RegularExpressions; +using Silk.NET.SPIRV; using Xunit.Abstractions; namespace Stride.Shaders.Parsing.Tests; @@ -55,9 +56,15 @@ public void RenderTest1(string shaderName, string methodName, string args) // Convert to GLSL var translator = new SpirvTranslator(bytecode.AsMemory().Cast()); - var code = translator.Translate(Backend.Glsl); + var entryPoints = translator.GetEntryPoints(); + var codePS = translator.Translate(Backend.Glsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); + var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) + ? translator.Translate(Backend.Glsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + : null; - Output.WriteLine(code); + if (codeVS != null) + Output.WriteLine(codeVS); + Output.WriteLine(codePS); // Execute test var renderer = new OpenGLFrameRenderer((uint)width, (uint)height); @@ -67,7 +74,9 @@ public void RenderTest1(string shaderName, string methodName, string args) foreach (var param in parameters) renderer.Parameters.Add(param.Key, param.Value); - renderer.FragmentShaderSource = code; + renderer.FragmentShaderSource = codePS; + if (codeVS != null) + renderer.VertexShaderSource = codeVS; using var frameBuffer = MemoryOwner.Allocate(width * height * 4); renderer.RenderFrame(frameBuffer.Span); var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index abd7c96214..74cf859593 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -9,20 +9,22 @@ namespace Stride.Shaders.Spirv.Processing { public class StreamAnalyzer { - class StreamInfo(string? semantic, string name, SymbolType type, int id) + class StreamInfo(string? semantic, string name, SymbolType type, int variableId) { public string? Semantic { get; } = semantic; public string Name { get; } = name; public SymbolType Type { get; } = type; - public int Id { get; } = id; + public int VariableId { get; } = variableId; + + public int? LayoutLocation { get; set; } /// /// We automatically mark input: a variable read before it's written to, or an output without a write. /// public bool Input => Read || (Output && !Write); public bool Output { get; set; } - public bool Private => Read || Write; + public bool Private => Input || Output || Read || Write; public bool Read { get; set; } public bool Write { get; set; } @@ -47,20 +49,31 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) // Expected at the end of pixel shader foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic.StartsWith("SV_Target") || semantic == "SV_Depth")) + if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH")) stream.Value.Stream.Output = true; } - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult); + + int layoutLocationCount = 0; + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult, ref layoutLocationCount); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic == "SV_Coverage" || semantic == "SV_IsFrontFace" || semantic == "VFACE")) + if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) stream.Value.Stream.Read = false; } PropagateStreamsFromPreviousStage(streams); if (entryPointVS.Id != 0) - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult); + { + // Expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION"))) + stream.Value.Stream.Output = true; + } + + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult, ref layoutLocationCount); + } buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } @@ -177,7 +190,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(streams, blockIds); } - private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult) + private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, ref int layoutLocationCount) { var streams = analysisResult.Streams; @@ -207,6 +220,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); + if (stream.Value.Stream.LayoutLocation == null) + stream.Value.Stream.LayoutLocation = layoutLocationCount++; + context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.LayoutLocation)); if (stream.Value.Stream.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); @@ -220,10 +236,21 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); context.AddName(variable, $"out_{stage}_{stream.Value.Stream.Name}"); - if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); + if (stream.Value.Stream.Semantic?.ToUpperInvariant() == "SV_POSITION") + { + context.Add(new OpDecorate(variable, Decoration.BuiltIn, (int)BuiltIn.Position)); + } + else + { + context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.LayoutLocation)); + if (stream.Value.Stream.Semantic != null) + context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); + } outputStreams.Add((stream.Value.Stream, variable.ResultId)); + + // We reset this layout location (only in_ will be read in next step) + stream.Value.Stream.LayoutLocation = null; } } @@ -241,7 +268,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con { var baseType = ((PointerType)stream.Info.Type).BaseType; buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null), out var loadedValue); - buffer.Add(new OpStore(stream.Info.Id, loadedValue.ResultId, null)); + buffer.Add(new OpStore(stream.Info.VariableId, loadedValue.ResultId, null)); } buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPointId, [])); @@ -249,7 +276,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var stream in outputStreams) { var baseType = ((PointerType)stream.Info.Type).BaseType; - buffer.FluentAdd(new OpLoad( context.Types[baseType], context.Bound++, stream.Info.Id, null), out var loadedValue); + buffer.FluentAdd(new OpLoad( context.Types[baseType], context.Bound++, stream.Info.VariableId, null), out var loadedValue); buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); } @@ -262,7 +289,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con for (int i = 0; i < outputStreams.Count; i++) pvariables[inputStreams.Count + i] = outputStreams[i].Id; for (int i = 0; i < privateStreams.Count; i++) - pvariables[inputStreams.Count + outputStreams.Count + i] = privateStreams[i].Id; + pvariables[inputStreams.Count + outputStreams.Count + i] = privateStreams[i].VariableId; for (int i = 0; i < analysisResult.Blocks.Count; i++) pvariables[inputStreams.Count + outputStreams.Count + privateStreams.Count + i] = analysisResult.Blocks[i]; context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); From e2a0a9d9a459aff38d5ae89570566fcc0ed9290e Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 30 Sep 2025 21:43:46 +0200 Subject: [PATCH 0478/1182] fix parsing of file namespace declaration --- .../Parsers/ShaderParsers/ShaderFileParsers.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index fdc0d3e8d7..62e9c6f3aa 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -131,9 +131,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Tokens.Char(';', ref scanner, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - while (ShaderClassParsers.Class(ref scanner, result, out var shader)) + while (!scanner.IsEof && ( + Tokens.AnyOf(["effect", "shader", "params"], ref scanner, out _) + || Parsers.SequenceOf(ref scanner, ["internal", "shader"]) + )) { - ns.Declarations.Add(shader); + if(ShaderClassParsers.Class(ref scanner, result, out var shader) && Parsers.Spaces0(ref scanner, result, out _)) + ns.Declarations.Add(shader); + else if( EffectParser.Effect(ref scanner, result, out var effect) && Parsers.Spaces0(ref scanner, result, out _)) + ns.Declarations.Add(effect); + else if( ParamsParsers.Params(ref scanner, result, out var p) && Parsers.Spaces0(ref scanner, result, out _)) + ns.Declarations.Add(p); + else + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); } } else if (Tokens.Char('{', ref scanner, advance: true)) From 72874662c03c8046bb4969cf0df55d7b8aeb87ef Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 30 Sep 2025 21:45:14 +0200 Subject: [PATCH 0479/1182] remove unecessary condition --- .../Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 62e9c6f3aa..18d6db46d1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -131,10 +131,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Tokens.Char(';', ref scanner, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - while (!scanner.IsEof && ( - Tokens.AnyOf(["effect", "shader", "params"], ref scanner, out _) - || Parsers.SequenceOf(ref scanner, ["internal", "shader"]) - )) + while (!scanner.IsEof) { if(ShaderClassParsers.Class(ref scanner, result, out var shader) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(shader); From 3e44b45ebd0693f74925134bce68b88e1b4c82e2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 11:05:11 +0900 Subject: [PATCH 0480/1182] Allow multiple shaders to be in the same test file --- assets/SDSL/RenderTests/IfElseif.sdsl | 2 +- assets/SDSL/RenderTests/IfElseifElse.sdsl | 2 +- assets/SDSL/RenderTests/IfElseifElseif.sdsl | 2 +- .../SDSL/RenderTests/SimpleInheritance.sdsl | 10 ++++ .../RenderTests/SimpleInheritanceBase.sdsl | 11 ---- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 55 +++++++++++-------- .../SDSL/ShaderMixer.cs | 13 +---- src/Stride.Shaders.Experiments/Examples.cs | 13 +++-- .../Buffers/NewSpirvBuffer.cs | 5 ++ src/Stride.Shaders.Tests/RenderingTests.cs | 9 ++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 +-- src/Stride.Shaders/Spirv/Building/Context.cs | 26 ++++++++- 12 files changed, 91 insertions(+), 65 deletions(-) delete mode 100644 assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl diff --git a/assets/SDSL/RenderTests/IfElseif.sdsl b/assets/SDSL/RenderTests/IfElseif.sdsl index 47c14cae4c..fa75f4d288 100644 --- a/assets/SDSL/RenderTests/IfElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseif.sdsl @@ -4,7 +4,7 @@ namespace Stride.Shaders.Tests; -shader IfElseifFalseFalse +shader IfElseif { stream float4 ColorTarget : SV_Target0; diff --git a/assets/SDSL/RenderTests/IfElseifElse.sdsl b/assets/SDSL/RenderTests/IfElseifElse.sdsl index 54376200cb..108345c5c6 100644 --- a/assets/SDSL/RenderTests/IfElseifElse.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElse.sdsl @@ -4,7 +4,7 @@ namespace Stride.Shaders.Tests; -shader IfElseifFalseFalse +shader IfElseifElse { stream float4 ColorTarget : SV_Target0; diff --git a/assets/SDSL/RenderTests/IfElseifElseif.sdsl b/assets/SDSL/RenderTests/IfElseifElseif.sdsl index ac19946473..8d84db5d06 100644 --- a/assets/SDSL/RenderTests/IfElseifElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElseif.sdsl @@ -5,7 +5,7 @@ namespace Stride.Shaders.Tests; -shader IfElseifFalseFalse +shader IfElseifElseif { stream float4 ColorTarget : SV_Target0; diff --git a/assets/SDSL/RenderTests/SimpleInheritance.sdsl b/assets/SDSL/RenderTests/SimpleInheritance.sdsl index bb558aa862..afcfbe12dd 100644 --- a/assets/SDSL/RenderTests/SimpleInheritance.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritance.sdsl @@ -2,6 +2,16 @@ namespace Stride.Shaders.Tests; +shader SimpleInheritanceBase +{ + stream float4 ColorTarget : SV_Target0; + + void SetColor(float4 color) + { + streams.ColorTarget = color; + } +} + shader SimpleInheritance : SimpleInheritanceBase { stream float4 Position : POSITION; diff --git a/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl deleted file mode 100644 index 87e572851a..0000000000 --- a/assets/SDSL/RenderTests/SimpleInheritanceBase.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -namespace Stride.Shaders.Tests; - -shader SimpleInheritanceBase -{ - stream float4 ColorTarget : SV_Target0; - - void SetColor(float4 color) - { - streams.ColorTarget = color; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index f5960b4021..3f65883c49 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -1,47 +1,56 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Core; -using Stride.Shaders.Spirv.Tools; -using Stride.Shaders.Spirv.Core.Buffers; -using System.Runtime.InteropServices; using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Processing; +using Stride.Shaders.Spirv.Tools; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; namespace Stride.Shaders.Compilers.SDSL; -public record struct SDSLC(IExternalShaderLoader ShaderLoader) : ICompiler +public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, out byte[] compiled) + public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuffer lastBuffer) { var parsed = SDSLParser.Parse(code); if(parsed.AST is ShaderFile sf) { - SymbolTable table = new(); - var shader = sf.Namespaces.First().Declarations.OfType().First(); - table.ShaderLoader = ShaderLoader; + lastBuffer = null; + foreach (var declaration in sf.Namespaces.First().Declarations) + { + if (declaration is ShaderClass shader) + { + SymbolTable table = new() + { + ShaderLoader = ShaderLoader + }; + var compiler = new CompilerUnit(); + shader.Compile(compiler, table); - var compiler = new CompilerUnit(); - shader.Compile(compiler, table); + if (table.Errors.Count > 0) + throw new Exception("Some parse errors"); - if (table.Errors.Count > 0) - throw new Exception("Some parse errors"); + var merged = compiler.ToBuffer(); + var dis = Spv.Dis(merged, true); + lastBuffer = merged; - // temp hack to add entry point (last function) - //var context = compiler.Context; - //context.Buffer.AddOpCapability(Spv.Specification.Capability.Shader); - //context.Buffer.AddOpMemoryModel(Spv.Specification.AddressingModel.Logical, Spv.Specification.MemoryModel.GLSL450); - //new StreamAnalyzer().Process(table, compiler); + ShaderLoader.RegisterShader(shader.Name, merged); + } + else + { + throw new NotImplementedException($"Compiling declaration [{declaration.GetType()}] is not implemented"); + } + } - var merged = compiler.ToBuffer(); - var dis = Spv.Dis(merged, true); - compiled = MemoryMarshal.AsBytes(merged.ToBuffer().Span).ToArray(); - return true; + return lastBuffer != null; } else { - compiled = []; + lastBuffer = null; return false; } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 4cef39cb03..525f1d3a39 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -190,7 +190,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) temp.Sort(); - bytecode = MemoryMarshal.AsBytes(temp.ToBuffer().Span).ToArray(); + bytecode = temp.ToBytecode(); //File.WriteAllBytes("test.spv", bytecode); @@ -198,8 +198,6 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //File.WriteAllText("test.spvdis", source); } - Dictionary loadedShaders = new(); - class ShaderInfo { public Dictionary Functions { get; } = new(); @@ -208,13 +206,8 @@ class ShaderInfo NewSpirvBuffer GetOrLoadShader(string name) { - if (loadedShaders.TryGetValue(name, out var buffer)) - return buffer; - - ShaderLoader.LoadExternalReference(name, out var bytecode); - buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); - - loadedShaders.Add(name, buffer); + if (!ShaderLoader.LoadExternalBuffer(name, out var buffer)) + throw new InvalidOperationException($"Could not load shader [{name}]"); return buffer; } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 4b119267e1..df2329d1b9 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -8,6 +8,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; using System.Diagnostics.CodeAnalysis; +using Stride.Shaders.Spirv.Core.Buffers; using SourceLanguage = Silk.NET.Shaderc.SourceLanguage; namespace Stride.Shaders.Experiments; @@ -206,20 +207,20 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) return false; } - public class ShaderLoader : IExternalShaderLoader + public class ShaderLoader : ShaderLoaderBase { - public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode) + public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/{name}.sdsl"; if (!File.Exists(filename)) { - bytecode = null; + buffer = null; return false; } var text = MonoGamePreProcessor.OpenAndRun(filename); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; - return sdslc.Compile(text, out bytecode); + return sdslc.Compile(text, out buffer); } } @@ -231,10 +232,10 @@ public static void CompileSDSL() { ShaderLoader = new ShaderLoader() }; - sdslc.Compile(text, out var bytecode); + sdslc.Compile(text, out var buffer); + var bytecode = buffer.ToBytecode(); File.WriteAllBytes("TestBasic.sdspv", bytecode); - var test = bytecode.AsMemory().Cast().ToArray(); var code = new SpirvTranslator(bytecode.AsMemory().Cast()); // Console.WriteLine(code.Translate(Backend.Hlsl)); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 5570ecbc36..342a82056e 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -293,6 +293,11 @@ public void Sort() Instructions.AddRange(sortedInstructions); } + public byte[] ToBytecode() + { + return MemoryMarshal.AsBytes(ToBuffer().Span).ToArray(); + } + public SpanOwner ToBuffer() { var result = SpanOwner.Allocate(5 + Instructions.Sum(i => i.Memory.Length)); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 18c3506589..16c1df2631 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -27,21 +27,20 @@ public class RenderingTests(ITestOutputHelper Output) static int width = 1; static int height = 1; - class ShaderLoader : IExternalShaderLoader + class ShaderLoader : ShaderLoaderBase { - public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode) + public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; if (!File.Exists(filename)) { - bytecode = null; + buffer = null; return false; } - var text = MonoGamePreProcessor.OpenAndRun(filename); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; - return sdslc.Compile(text, out bytecode); + return sdslc.Compile(text, out buffer); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 74b4f14f3c..1e4257ae15 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -107,12 +107,7 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) { - externalShaderLoader.LoadExternalReference(mixin.Name, out var bytecode); - if (bytecode is null) - throw new InvalidOperationException($"Could not load shader '{mixin.Name}'"); - using var mem = MemoryOwner.Allocate(bytecode.Length / 4); - MemoryMarshal.Cast(bytecode).CopyTo(mem.Span); - var buffer = new NewSpirvBuffer(mem.Span); + externalShaderLoader.LoadExternalBuffer(mixin.Name, out var buffer); ProcessNameAndTypes(buffer, out var names, out var types); @@ -154,6 +149,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Push(); foreach (var mixin in Mixins) { + // Check if shader isn't already loaded as part of current bytecode var shaderType = LoadShader(table.ShaderLoader, mixin); RegisterShaderType(table, shaderType); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9c6c1cd9d0..9e686c6fd3 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -11,7 +11,31 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { - public bool LoadExternalReference(string name, [MaybeNullWhen(false)] out byte[] bytecode); + public void RegisterShader(string name, NewSpirvBuffer buffer); + public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode); +} + +public abstract class ShaderLoaderBase : IExternalShaderLoader +{ + private Dictionary loadedShaders = new(); + + public void RegisterShader(string name, NewSpirvBuffer buffer) + { + loadedShaders.Add(name, buffer); + } + + public abstract bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); + + public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + { + if (!loadedShaders.ContainsKey(name) && !LoadExternalFile(name, out buffer)) + { + throw new InvalidOperationException($"Shader {name} could not be found"); + } + + buffer = loadedShaders[name]; + return true; + } } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other From fde7ab2e46ce10485a81729ae17376906c052a13 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 11:07:42 +0900 Subject: [PATCH 0481/1182] Added a specific test for position streams --- assets/SDSL/RenderTests/PositionStreams.sdsl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 assets/SDSL/RenderTests/PositionStreams.sdsl diff --git a/assets/SDSL/RenderTests/PositionStreams.sdsl b/assets/SDSL/RenderTests/PositionStreams.sdsl new file mode 100644 index 0000000000..ca59cb86fa --- /dev/null +++ b/assets/SDSL/RenderTests/PositionStreams.sdsl @@ -0,0 +1,20 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) + +namespace Stride.Shaders.Tests; + +shader PositionStreams +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + } +} \ No newline at end of file From 1d7b803a9ee6ce3268a8e76bf2256a55325a4aea Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 13:22:13 +0900 Subject: [PATCH 0482/1182] Separated tests for streams and inheritance --- assets/SDSL/RenderTests/PositionStreams.sdsl | 2 +- .../SDSL/RenderTests/SimpleInheritance.sdsl | 4 ++-- .../SDSL/RenderTests/StreamPassthroughPS.sdsl | 21 +++++++++++++++++ assets/SDSL/RenderTests/StreamVSToPS.sdsl | 23 +++++++++++++++++++ .../FrameRenderer.OpenGL.cs | 11 +++++---- 5 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 assets/SDSL/RenderTests/StreamPassthroughPS.sdsl create mode 100644 assets/SDSL/RenderTests/StreamVSToPS.sdsl diff --git a/assets/SDSL/RenderTests/PositionStreams.sdsl b/assets/SDSL/RenderTests/PositionStreams.sdsl index ca59cb86fa..cb89bc0dfe 100644 --- a/assets/SDSL/RenderTests/PositionStreams.sdsl +++ b/assets/SDSL/RenderTests/PositionStreams.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) +// PSMain(ExpectedResult=#7F7F7F7F) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/SimpleInheritance.sdsl b/assets/SDSL/RenderTests/SimpleInheritance.sdsl index afcfbe12dd..934ca3b915 100644 --- a/assets/SDSL/RenderTests/SimpleInheritance.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritance.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) +// PSMain(ExpectedResult=#7F7F7F7F) namespace Stride.Shaders.Tests; @@ -26,7 +26,7 @@ shader SimpleInheritance : SimpleInheritanceBase void Test() { streams.ColorTarget = streams.ExtraColor; - SetColor(streams.ExtraColor); + SetColor(float4(0.5, 0.5, 0.5, 0.5)); } void PSMain() diff --git a/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl new file mode 100644 index 0000000000..eac936a4b5 --- /dev/null +++ b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl @@ -0,0 +1,21 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) + +namespace Stride.Shaders.Tests; + +shader StreamPassthroughPS +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + stream float4 ExtraColor; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = streams.ExtraColor; + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/StreamVSToPS.sdsl b/assets/SDSL/RenderTests/StreamVSToPS.sdsl new file mode 100644 index 0000000000..a59cf9693c --- /dev/null +++ b/assets/SDSL/RenderTests/StreamVSToPS.sdsl @@ -0,0 +1,23 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) + +namespace Stride.Shaders.Tests; + +shader StreamVSToPS +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + stream float4 ExtraColor; + stream float4 ExtraColor2; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + streams.ExtraColor2 = streams.ExtraColor; + } + + void PSMain() + { + streams.ColorTarget = streams.ExtraColor2; + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index 91b3372a50..92eff1e63e 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -169,12 +169,13 @@ public override unsafe void RenderFrame(Span result) for (uint i = 0; i < attributeCount; ++i) { Gl.GetActiveAttrib(Shader, i, 256, out _, out var attribSize, out AttributeType attribType, out string attribName); + var attribIndex = (uint)Gl.GetAttribLocation(Shader, attribName); if (attribName == "in_VS_Position" || attribName == "vPos") { //Tell opengl how to give the data to the shaders. - Gl.VertexAttribPointer(i, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); - Gl.EnableVertexAttribArray(i); + Gl.VertexAttribPointer(attribIndex, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); + Gl.EnableVertexAttribArray(attribIndex); } else { @@ -189,13 +190,13 @@ public override unsafe void RenderFrame(Span result) if (paramName == attribName) { if (attribType == AttributeType.Float) - Gl.VertexAttrib1(i, float.Parse(param.Value)); + Gl.VertexAttrib1(attribIndex, float.Parse(param.Value)); else if (attribType == AttributeType.Int) - Gl.VertexAttrib1(i, int.Parse(param.Value)); + Gl.VertexAttrib1(attribIndex, int.Parse(param.Value)); else if (attribType == AttributeType.FloatVec4) { var values = param.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries); - Gl.VertexAttrib4(i, float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3])); + Gl.VertexAttrib4(attribIndex, float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3])); } } } From bd2e34c0095ee8aac12e922ef68447f6bedb816b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 14:11:54 +0900 Subject: [PATCH 0483/1182] Added support for method forward call --- .../SDSL/RenderTests/MethodForwardCall.sdsl | 25 +++++++++++++++++++ .../SDSL/RenderTests/SimpleInheritance.sdsl | 3 +-- .../Examples.Spirv.cs | 3 ++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 5 ++++ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 20 ++++++++++----- .../Spirv/Building/Builder.Functions.cs | 18 ++++++++----- 6 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 assets/SDSL/RenderTests/MethodForwardCall.sdsl diff --git a/assets/SDSL/RenderTests/MethodForwardCall.sdsl b/assets/SDSL/RenderTests/MethodForwardCall.sdsl new file mode 100644 index 0000000000..ab49b51f50 --- /dev/null +++ b/assets/SDSL/RenderTests/MethodForwardCall.sdsl @@ -0,0 +1,25 @@ +// PSMain(ExpectedResult=#7F7F7F7F) + +namespace Stride.Shaders.Tests; + +shader MethodForwardCall +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + Test(); + } + + void Test() + { + streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/SimpleInheritance.sdsl b/assets/SDSL/RenderTests/SimpleInheritance.sdsl index 934ca3b915..8a61ade03b 100644 --- a/assets/SDSL/RenderTests/SimpleInheritance.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritance.sdsl @@ -16,7 +16,6 @@ shader SimpleInheritance : SimpleInheritanceBase { stream float4 Position : POSITION; stream float4 ShadingPosition : SV_Position; - stream float4 ExtraColor : COLOR; void VSMain() { @@ -25,7 +24,7 @@ shader SimpleInheritance : SimpleInheritanceBase void Test() { - streams.ColorTarget = streams.ExtraColor; + streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); SetColor(float4(0.5, 0.5, 0.5, 0.5)); } diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index b3bdf298b2..21d418fb03 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -24,11 +24,12 @@ public static void GenerateSpirv() // context.AddGlobalVariable(new(new("color", SymbolKind.Variable, Storage.Stream), VectorType.From("float4"))); - var function = builder.CreateFunction( + var function = builder.DeclareFunction( context, "add", new(ScalarType.From("int"), [ScalarType.From("int"), ScalarType.From("int")]) ); + builder.BeginFunction(context, function); builder.AddFunctionParameter(context, "a", ScalarType.From("int")); builder.AddFunctionParameter(context, "b", ScalarType.From("int")); builder.SetPositionTo(function); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 1e4257ae15..e76e47c1ed 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -236,6 +236,11 @@ public void Compile(CompilerUnit compiler, SymbolTable table) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); + + // In case calling a method not yet processed, we first register method types + // (SPIR-V allow forward calling) + foreach (var method in Elements.OfType()) + method.Declare(table, this, compiler); foreach (var method in Elements.OfType()) method.Compile(table, this, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index a7a39c3ab9..c82f371de5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -147,6 +148,8 @@ public class ShaderMethod( bool isClone = false ) : MethodOrMember(info, isStaged) { + // Saved between Declare and Compile pass + private SpirvFunction function; public SymbolType? ReturnType { get; set; } public TypeName ReturnTypeName { get; set; } = returnType; @@ -173,6 +176,16 @@ public class ShaderMethod( public BlockStatement? Body { get; set; } + public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context, _) = compiler; + + function = builder.DeclareFunction(context, Name, (FunctionType)Type); + var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); + table.CurrentShader.Components.Add(symbol); + table.CurrentFrame.Add(Name, symbol); + } + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { table.Push(); @@ -184,10 +197,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler } var (builder, context, _) = compiler; - SpirvFunction function; if (Type is FunctionType ftype) { - function = builder.CreateFunction(context, Name, ftype); + builder.BeginFunction(context, function); foreach (var p in Parameters) { var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); @@ -208,10 +220,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler else throw new NotImplementedException(); table.Pop(); - - var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); - table.CurrentShader.Components.Add(symbol); - table.CurrentFrame.Add(Name, symbol); } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index c28bb5b9e7..31f90622d5 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -2,25 +2,31 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { - public SpirvFunction CreateFunction(SpirvContext context, string name, FunctionType ftype, FunctionControlMask mask = FunctionControlMask.None) + public SpirvFunction DeclareFunction(SpirvContext context, string name, FunctionType ftype) { - foreach(var t in ftype.ParameterTypes) + var func = context.Bound++; + foreach (var t in ftype.ParameterTypes) context.GetOrRegister(t); - Buffer.FluentAdd(new OpFunction(context.GetOrRegister(ftype.ReturnType), context.Bound++, mask, context.GetOrRegister(ftype)), out var func); - Position = Buffer.Count; context.AddName(func, name); - var result = new SpirvFunction(func.ResultId, name, ftype); - CurrentFunction = result; + var result = new SpirvFunction(func, name, ftype); context.Module.Functions.Add(name, result); return result; } + public void BeginFunction(SpirvContext context, SpirvFunction function, FunctionControlMask mask = FunctionControlMask.None) + { + Buffer.FluentAdd(new OpFunction(context.GetOrRegister(function.FunctionType.ReturnType), function.Id, mask, context.GetOrRegister(function.FunctionType)), out var func); + Position = Buffer.Count; + CurrentFunction = function; + } + public void EndFunction() { // If there was no explicit return, add one From 9a58d2a87679342671190d0d8290d543900095c0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 14:59:47 +0900 Subject: [PATCH 0484/1182] [Disassembler] Avoid name clash --- src/Stride.Shaders/Spirv/Tools/Dis.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 3027124721..a83c7ebc15 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -1,13 +1,11 @@ -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Text; -using System.Text.Json; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Text; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Tools; @@ -200,7 +198,14 @@ public void Disassemble() if (instruction.Op == Op.OpName) { var nameInst = (OpName)instruction; - data.NameTable[nameInst.Target] = nameInst.Name; + var name = nameInst.Name; + // Try to find an available name (in case there is a duplicate) + int tryCount = 0; + while (!data.UsedNames.Add(name)) + { + name = $"{nameInst.Name}_{++tryCount}"; + } + data.NameTable[nameInst.Target] = name; } else if (instruction.Op == Op.OpMemberName) { @@ -761,6 +766,7 @@ struct DisData : IDisposable { static int MAX_OFFSET = 16; public Dictionary NameTable { get; } + public HashSet UsedNames { get; } = new(); public NewSpirvBuffer Buffer { get; } public int IdOffset { get; private set; } public bool UseNames { get; private set; } From 4b9bd698f9e1a90d5f0d4b480a61ec4b1b785326 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 20:51:19 +0900 Subject: [PATCH 0485/1182] Progress on function abstract/override --- .../SimpleInheritanceAbstract.sdsl | 47 +++++++++++ .../FrameRenderer.OpenGL.cs | 2 + .../SDSL/ShaderMixer.cs | 83 ++++++++++--------- .../Extensions/spirv.sdsl.grammar-ext.json | 40 +++++++++ src/Stride.Shaders/Core/Symbol.cs | 10 ++- src/Stride.Shaders/Core/SymbolTypes.cs | 1 + src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 46 ++++++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 40 ++++++++- .../Spirv/Building/Builder.Class.cs | 49 +++++++++++ .../Spirv/Building/Builder.Expressions.cs | 11 +-- .../Spirv/Building/Builder.Functions.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 14 +++- src/Stride.Shaders/Spirv/Building/Module.cs | 4 +- .../Spirv/Processing/StreamAnalyzer.cs | 76 ++++++++++++----- src/Stride.Shaders/Spirv/Tools/Dis.cs | 9 +- 15 files changed, 344 insertions(+), 92 deletions(-) create mode 100644 assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.Class.cs diff --git a/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl new file mode 100644 index 0000000000..ceeb4c335e --- /dev/null +++ b/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl @@ -0,0 +1,47 @@ +// PSMain(ExpectedResult=#7F7F7F7F) + +namespace Stride.Shaders.Tests; + +shader SimpleInheritanceBase +{ + abstract void SetColor(float4 color); +} + +shader SimpleInheritanceBase2 : SimpleInheritanceBase +{ +} + +shader SimpleInheritanceBase3 : SimpleInheritanceBase2 +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void Test() + { + streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); + SetColor(float4(0.5, 0.5, 0.5, 0.5)); + } + + void PSMain() + { + Test(); + } +} + +shader SimpleInheritanceBase4 : SimpleInheritanceBase3 +{ +} + +shader SimpleInheritanceAbstract : SimpleInheritanceBase4 +{ + override void SetColor(float4 color) + { + streams.ColorTarget = color; + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index 92eff1e63e..58505c6a06 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -117,6 +117,7 @@ public override unsafe void RenderFrame(Span result) if (!string.IsNullOrWhiteSpace(shaderLog)) { Console.WriteLine($"Error compiling vertex shader {shaderLog}"); + throw new InvalidOperationException(shaderLog); } //Creating a fragment shader. @@ -142,6 +143,7 @@ public override unsafe void RenderFrame(Span result) if (!string.IsNullOrWhiteSpace(shaderLog)) { Console.WriteLine($"Error compiling fragment shader {shaderLog}"); + throw new InvalidOperationException(shaderLog); } //Combining the shaders under one shader program. diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 525f1d3a39..ceac0ed6dc 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -6,9 +6,9 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Processing; +using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; -using Stride.Shaders.Spirv.Tools; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Compilers.SDSL; @@ -20,14 +20,14 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) // TODO: support proper shader mixin source //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; - var buffer = GetOrLoadShader(entryShaderName); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, entryShaderName); // Step: expand "for" // TODO // Step: build mixins: top level and (TODO) compose var inheritanceList = new List(); - BuildInheritanceList(buffer, inheritanceList); + SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); inheritanceList.Add(entryShaderName); var temp = new NewSpirvBuffer(); @@ -36,7 +36,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) foreach (var shaderName in inheritanceList) { - var shader = GetOrLoadShader(shaderName); + var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName); offset += nextOffset; nextOffset = 0; shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; @@ -90,9 +90,6 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) { var functionName = names[function.ResultId]; currentShader!.Functions.Add(functionName, function.ResultId); - - //temp.Remove(i.Position); - //temp.InsertOpFunction(i.Position, i.ResultId.Value, i.ResultType!.Value, function.FunctionControl, function.FunctionType); } if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) @@ -158,12 +155,39 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) context.Bound = offset + nextOffset + 1; //Spv.Dis(temp, true); ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); - foreach (var i in temp) + + Dictionary methodOverrides = new Dictionary(); + for (var index = 0; index < temp.Count; index++) { + var i = temp[index]; if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { var functionName = names2[function.ResultId]; - context.Module.Functions.Add(functionName, new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); + if (!context.Module.Functions.TryGetValue(functionName, out var functions)) + context.Module.Functions.Add(functionName, functions = new()); + functions.Add(new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); + + if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is {} functionInfo) + { + if (functionInfo.ParentFunction != 0) + { + // TODO: better structure for more direct lookup by id? + // TODO: iterate to find real parent? or find it directly when computing shader? + methodOverrides[functionInfo.ParentFunction] = function.ResultId; + } + + if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) + { + while (temp[index].Op != Op.OpFunctionEnd) + { + SetOpNop(temp[index++].Data.Memory.Span); + } + SetOpNop(temp[index].Data.Memory.Span); + // Let's go to next instruction since we erased current function + continue; + } + } + SetOpNop(temp[index + 1].Data.Memory.Span); } } @@ -173,6 +197,18 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) context.ReverseTypes.Add(type.Key, type.Value); } + // Patch virtual method calls + foreach (var i in temp) + { + if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) + { + if (methodOverrides.TryGetValue(functionCall.Function, out var functionOverride)) + { + functionCall.Function = functionOverride; + } + } + } + context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); @@ -204,41 +240,12 @@ class ShaderInfo public Dictionary Variables { get; } = new(); } - NewSpirvBuffer GetOrLoadShader(string name) - { - if (!ShaderLoader.LoadExternalBuffer(name, out var buffer)) - throw new InvalidOperationException($"Could not load shader [{name}]"); - - return buffer; - } - static void SetOpNop(Span words) { words[0] = words.Length << 16; words[1..].Clear(); } - private void BuildInheritanceList(NewSpirvBuffer buffer, List inheritanceList) - { - // Build shader name mapping - var shaderMapping = new Dictionary(); - foreach (var i in buffer) - if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) - shaderMapping[importShader.ResultId] = importShader.ShaderName; - - // Check inheritance - foreach (var i in buffer) - { - if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) - { - var shaderName = shaderMapping[inherit.Shader]; - var shader = GetOrLoadShader(shaderName); - BuildInheritanceList(shader, inheritanceList); - inheritanceList.Add(shaderName); - } - } - } - public static void OffsetIds(OpData inst, int offset) { foreach (var o in inst) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 38d12b30f6..3bf8965a04 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -92,9 +92,49 @@ "name": "shader" } ] + }, + { + "opname": "OpSDSLFunctionInfo", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "parentFunction" + }, + { + "kind": "FunctionFlags", + "name": "flags" + } + ] } ], "operand_kinds": [ + { + "category": "BitEnum", + "kind": "FunctionFlags", + "enumerants": [ + { + "enumerant": "None", + "value": "0x0000" + }, + { + "enumerant": "Abstract", + "value": "0x0001" + }, + { + "enumerant": "Virtual", + "value": "0x0002" + }, + { + "enumerant": "Override", + "value": "0x0004" + }, + { + "enumerant": "Static", + "value": "0x0010" + } + ] + }, { "kind": "ExecutionModel", "enumerants": [ diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 2a39a90683..1a435ce685 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -1,3 +1,5 @@ +using System.Collections.Immutable; + namespace Stride.Shaders.Core; @@ -8,6 +10,7 @@ public enum SymbolKind Shader, Struct, Method, + MethodGroup, Variable, Constant, ConstantGeneric, @@ -35,7 +38,12 @@ public enum StreamIO : byte public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null); + +/// +/// Defines a symbol. +/// +/// Only used for specific such as +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, ImmutableArray GroupMembers = default); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index d3e378fe27..d85d60ee85 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -131,6 +131,7 @@ public sealed record Texture3DType(SymbolType BaseType, int Width, int Height, i public override string ToString() => $"Texture<{BaseType}, {Width}, {Height}, {Depth}>"; } +public sealed record FunctionGroupType() : SymbolType(); public sealed record FunctionType(SymbolType ReturnType, List ParameterTypes) : SymbolType() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index e76e47c1ed..5da5e248b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using System; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -105,22 +106,23 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf return types; } - private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, Mixin mixin) + private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, string mixin) { - externalShaderLoader.LoadExternalBuffer(mixin.Name, out var buffer); + externalShaderLoader.LoadExternalBuffer(mixin, out var buffer); ProcessNameAndTypes(buffer, out var names, out var types); var symbols = new List(); foreach (var instruction in buffer) { - if (instruction.Op == Op.OpVariable && (OpVariable)instruction is {} variableInstruction) + if (instruction.Op == Op.OpVariable && (OpVariable)instruction is {} variable && variable.Storageclass != Specification.StorageClass.Function) { - var variableName = names[variableInstruction.ResultId]; - var variableType = types[variableInstruction.ResultType]; + if (!names.TryGetValue(variable.ResultId, out var variableName)) + variableName = $"_{variable.ResultId}"; + var variableType = types[variable.ResultType]; var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - symbols.Add(new(sid, variableType, variableInstruction.ResultId)); + symbols.Add(new(sid, variableType, variable.ResultId)); } if (instruction.Op == Op.OpFunction) @@ -134,7 +136,7 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade } } - var shaderType = new ShaderSymbol(mixin.Name, symbols); + var shaderType = new ShaderSymbol(mixin, symbols); return shaderType; } @@ -143,11 +145,17 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp table.DeclaredTypes.Add(shaderType.Name, shaderType); } - public void Compile(CompilerUnit compiler, SymbolTable table) { table.Push(); + + var inheritanceList = new List(); foreach (var mixin in Mixins) + { + SpirvBuilder.BuildInheritanceList(table.ShaderLoader, mixin.Name, inheritanceList); + } + + foreach (var mixin in inheritanceList) { // Check if shader isn't already loaded as part of current bytecode var shaderType = LoadShader(table.ShaderLoader, mixin); @@ -165,7 +173,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) { var argSym = arg.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = argSym; + arg.Type = new PointerType(argSym, Specification.StorageClass.Function); ftype.ParameterTypes.Add(arg.Type); } func.Type = ftype; @@ -200,19 +208,23 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var (builder, context, _) = compiler; context.PutShaderName(Name); - foreach (var mixin in Mixins) + foreach (var mixin in inheritanceList) { // Import types and variables/functions - context.FluentAdd(new OpSDSLImportShader(context.Bound++, new(mixin.Name)), out var shader); + context.FluentAdd(new OpSDSLImportShader(context.Bound, new(mixin)), out var shader); + context.AddName(context.Bound, mixin); + context.Bound++; - var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.Name]; + var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin]; foreach (var c in shaderType.Components) { if (c.Id.Kind == SymbolKind.Variable) { var variableTypeId = context.GetOrRegister(c.Type); - context.FluentAdd(new OpSDSLImportVariable(variableTypeId, context.Bound++, c.Id.Name, shader.ResultId), out var variable); + context.FluentAdd(new OpSDSLImportVariable(variableTypeId, context.Bound, c.Id.Name, shader.ResultId), out var variable); + context.AddName(context.Bound, c.Id.Name); + context.Bound++; context.Module.InheritedVariables.Add(c.Id.Name, new(variable.ResultId, variable.ResultType, variable.VariableName)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId }); } @@ -221,8 +233,12 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var functionType = (FunctionType)c.Type; var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound++, c.Id.Name, shader.ResultId), out var function); - context.Module.InheritedFunctions.Add(c.Id.Name, new(function.ResultId, c.Id.Name, functionType)); + context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound, c.Id.Name, shader.ResultId), out var function); + context.AddName(context.Bound, c.Id.Name); + context.Bound++; + if (!context.Module.InheritedFunctions.TryGetValue(c.Id.Name, out var inheritedFunctions)) + context.Module.InheritedFunctions.Add(c.Id.Name, inheritedFunctions = new()); + inheritedFunctions.Add(new(function.ResultId, c.Id.Name, functionType)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c82f371de5..860d6ef33c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; @@ -181,9 +182,24 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler var (builder, context, _) = compiler; function = builder.DeclareFunction(context, Name, (FunctionType)Type); + var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); table.CurrentShader.Components.Add(symbol); - table.CurrentFrame.Add(Name, symbol); + + if (table.CurrentFrame.TryGetValue(Name, out var existingSymbol)) + { + // If there is already a function symbol with same name, let's create or add to a group. + if (existingSymbol.Type is FunctionType) + existingSymbol = new Symbol(new(Name, SymbolKind.MethodGroup), new FunctionGroupType(), 0, GroupMembers: ImmutableArray.Create(existingSymbol)); + + existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); + + table.CurrentFrame[Name] = existingSymbol; + } + else + { + table.CurrentFrame.Add(Name, symbol); + } } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -200,6 +216,28 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Type is FunctionType ftype) { builder.BeginFunction(context, function); + + var functionInfo = new OpSDSLFunctionInfo(0, Specification.FunctionFlagsMask.None); + + if (IsOverride == true) + { + // Find parent function + var inheritedFunctions = context.Module.InheritedFunctions[function.Name]; + var parentFunction = inheritedFunctions.Last(x => x.FunctionType == function.FunctionType); + + functionInfo.ParentFunction = parentFunction.Id; + functionInfo.Flags |= Specification.FunctionFlagsMask.Override; + } + + if (IsAbstract == true) + functionInfo.Flags |= Specification.FunctionFlagsMask.Abstract; + if (IsVirtual == true) + functionInfo.Flags |= Specification.FunctionFlagsMask.Virtual; + if (IsStatic) + functionInfo.Flags |= Specification.FunctionFlagsMask.Static; + + builder.Insert(functionInfo); + foreach (var p in Parameters) { var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs new file mode 100644 index 0000000000..da4a20f7ce --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -0,0 +1,49 @@ +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Building; +public partial class SpirvBuilder +{ + public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, NewSpirvBuffer buffer, List inheritanceList) + { + // Build shader name mapping + var shaderMapping = new Dictionary(); + foreach (var i in buffer) + if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + shaderMapping[importShader.ResultId] = importShader.ShaderName; + + // Check inheritance + foreach (var i in buffer) + { + if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) + { + var shaderName = shaderMapping[inherit.Shader]; + BuildInheritanceList(shaderLoader, shaderName, inheritanceList); + } + } + } + + public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, string shaderName, List inheritanceList) + { + if (!inheritanceList.Contains(shaderName)) + { + var shader = GetOrLoadShader(shaderLoader, shaderName); + BuildInheritanceList(shaderLoader, shader, inheritanceList); + inheritanceList.Add(shaderName); + } + } + + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string name) + { + if (!shaderLoader.LoadExternalBuffer(name, out var buffer)) + throw new InvalidOperationException($"Could not load shader [{name}]"); + + return buffer; + } +} diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 844de604b7..82df859f39 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -133,19 +133,14 @@ public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) { - var func = FindFunction(context, name); + var funcGroup = context.FindFunctions(name); + // TODO: find proper overload + var func = funcGroup.First(); var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(func.FunctionType.ReturnType), context.Bound++, func.Id, [.. parameters])); return new(fcall, func.Name); } - private static SpirvFunction FindFunction(SpirvContext context, string name) - { - if (!context.Module.Functions.TryGetValue(name, out var func)) - context.Module.InheritedFunctions.TryGetValue(name, out func); - return func; - } - public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) { var instruction = Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(literal.Type), context.Bound++, [.. values])); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 31f90622d5..23ff3f5099 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -16,7 +16,9 @@ public SpirvFunction DeclareFunction(SpirvContext context, string name, Function context.GetOrRegister(t); context.AddName(func, name); var result = new SpirvFunction(func, name, ftype); - context.Module.Functions.Add(name, result); + if (!context.Module.Functions.TryGetValue(name, out var functions)) + context.Module.Functions.Add(name, functions = new()); + functions.Add(result); return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9e686c6fd3..ce5a3dfeee 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -62,7 +62,7 @@ public void PutShaderName(string name) } public void AddName(int target, string name) - => Buffer.Add(new OpName(target, name.Replace('.', '_'))); + => Buffer.Add(new OpName(target, name)); public void AddMemberName(int target, int accessor, string name) => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); @@ -220,7 +220,7 @@ int RegisterFunctionType(FunctionType functionType) Span types = stackalloc int[functionType.ParameterTypes.Count]; int tmp = 0; foreach (var f in functionType.ParameterTypes) - types[tmp] = GetOrRegister(new PointerType(f, Specification.StorageClass.Function)); + types[tmp] = GetOrRegister(f); var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); @@ -314,4 +314,14 @@ public override string ToString() { return Spv.Dis(Buffer); } + + public List FindFunctions(string name) + { + var result = new List(); + if (Module.Functions.TryGetValue(name, out var funcGroup)) + result.AddRange(funcGroup); + if (Module.InheritedFunctions.TryGetValue(name, out funcGroup)) + result.AddRange(funcGroup); + return result; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Module.cs b/src/Stride.Shaders/Spirv/Building/Module.cs index af4826702a..96322f0b7d 100644 --- a/src/Stride.Shaders/Spirv/Building/Module.cs +++ b/src/Stride.Shaders/Spirv/Building/Module.cs @@ -6,10 +6,10 @@ namespace Stride.Shaders.Spirv.Building; // Should contain symbols for the SPIR-V module public class SpirvModule() { - public Dictionary Functions { get; init; } = []; + public Dictionary> Functions { get; init; } = []; public List InheritedMixins { get; } = []; public Dictionary InheritedVariables { get; } = []; - public Dictionary InheritedFunctions { get; } = []; + public Dictionary> InheritedFunctions { get; } = []; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 74cf859593..173f7e31ae 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System.IO; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Processing @@ -17,7 +18,8 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public int VariableId { get; } = variableId; - public int? LayoutLocation { get; set; } + public int? InputLayoutLocation { get; set; } + public int? OutputLayoutLocation { get; set; } /// /// We automatically mark input: a variable read before it's written to, or an output without a write. @@ -38,8 +40,8 @@ record struct AnalysisResult(SortedList public void Process(NewSpirvBuffer buffer, SpirvContext context) { - context.Module.Functions.TryGetValue("VSMain", out var entryPointVS); - context.Module.Functions.TryGetValue("PSMain", out var entryPointPS); + var entryPointVS = context.FindFunctions("VSMain").FirstOrDefault(); + var entryPointPS = context.FindFunctions("PSMain").First(); if (entryPointPS.Id == 0) throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); @@ -53,8 +55,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Output = true; } - int layoutLocationCount = 0; - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult, ref layoutLocationCount); + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -72,7 +73,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult, ref layoutLocationCount); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult); } buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); @@ -82,6 +83,8 @@ private static void PropagateStreamsFromPreviousStage(SortedList inputStreams = []; List<(StreamInfo Info, int Id)> outputStreams = []; List privateStreams = []; + + int inputLayoutLocationCount = 0; + int outputLayoutLocationCount = 0; + + foreach (var stream in streams) + { + // Only direct access to global variables (not temporary variables created within function) + if (!stream.Value.IsDirect) + continue; + + if (stream.Value.Stream.Output) + { + if (stream.Value.Stream.OutputLayoutLocation is {} outputLayoutLocation) + { + outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); + } + } + } + foreach (var stream in streams) { // Only direct access to global variables (not temporary variables created within function) @@ -220,9 +242,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); - if (stream.Value.Stream.LayoutLocation == null) - stream.Value.Stream.LayoutLocation = layoutLocationCount++; - context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.LayoutLocation)); + if (stream.Value.Stream.InputLayoutLocation == null) + stream.Value.Stream.InputLayoutLocation = inputLayoutLocationCount++; + context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.InputLayoutLocation.Value)); if (stream.Value.Stream.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); @@ -242,15 +264,21 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con } else { - context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.LayoutLocation)); + // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic + if (stream.Value.Stream.OutputLayoutLocation == null) + { + if (stream.Value.Stream.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) + stream.Value.Stream.OutputLayoutLocation = outputLayoutLocationCount++; + else + throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Stream.Name}]"); + } + + context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.OutputLayoutLocation.Value)); if (stream.Value.Stream.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); } outputStreams.Add((stream.Value.Stream, variable.ResultId)); - - // We reset this layout location (only in_ will be read in next step) - stream.Value.Stream.LayoutLocation = null; } } @@ -283,15 +311,17 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Streams.Count]; - for (int i = 0; i < inputStreams.Count; i++) - pvariables[i] = inputStreams[i].Id; - for (int i = 0; i < outputStreams.Count; i++) - pvariables[inputStreams.Count + i] = outputStreams[i].Id; - for (int i = 0; i < privateStreams.Count; i++) - pvariables[inputStreams.Count + outputStreams.Count + i] = privateStreams[i].VariableId; - for (int i = 0; i < analysisResult.Blocks.Count; i++) - pvariables[inputStreams.Count + outputStreams.Count + privateStreams.Count + i] = analysisResult.Blocks[i]; + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Blocks.Count]; + int pvariableIndex = 0; + foreach (var inputStream in inputStreams) + pvariables[pvariableIndex++] = inputStream.Id; + foreach (var outputStream in outputStreams) + pvariables[pvariableIndex++] = outputStream.Id; + foreach (var privateStream in privateStreams) + pvariables[pvariableIndex++] = privateStream.VariableId; + foreach (var block in analysisResult.Blocks) + pvariables[pvariableIndex++] = block; + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); } diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index a83c7ebc15..db33cd5596 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -198,7 +198,7 @@ public void Disassemble() if (instruction.Op == Op.OpName) { var nameInst = (OpName)instruction; - var name = nameInst.Name; + var name = nameInst.Name.Replace(".", "_"); // Try to find an available name (in case there is a duplicate) int tryCount = 0; while (!data.UsedNames.Add(name)) @@ -650,6 +650,13 @@ or OperandKind.LiteralSpecConstantOpInteger (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, + OperandKind.FunctionFlags => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), }; // _ = (operand.Kind, operand.Quantifier) switch From 9141ea538328a60766b92bbddba1d228aa814116 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 2 Oct 2025 21:51:40 +0900 Subject: [PATCH 0486/1182] Unified Module and SymbolTable --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 6 ++- .../SDSL/ShaderMixer.cs | 12 +++--- .../Examples.Spirv.cs | 2 +- src/Stride.Shaders/Core/SymbolFrame.cs | 22 ++++++++++- .../Parsing/Analysis/SymbolTable.cs | 33 +++++++++++----- .../Parsing/SDSL/AST/Expression.cs | 19 +++++---- .../Parsing/SDSL/AST/Literals.cs | 39 ++----------------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 7 +--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 30 +++++--------- .../Parsing/SDSL/AST/ShaderElements.cs | 2 +- .../Parsing/SDSL/AST/Statements.Control.cs | 2 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 6 +-- .../Parsing/SDSL/AST/Statements.cs | 8 ++-- .../Spirv/Building/Builder.Expressions.cs | 20 ++++++---- .../Spirv/Building/Builder.Functions.cs | 3 -- .../Spirv/Building/CompilerUnit.cs | 7 +--- src/Stride.Shaders/Spirv/Building/Context.cs | 13 +------ src/Stride.Shaders/Spirv/Building/Module.cs | 14 +++++-- .../Spirv/Processing/StreamAnalyzer.cs | 15 +++---- 19 files changed, 126 insertions(+), 134 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 3f65883c49..1533bc64ba 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -17,9 +17,13 @@ public record struct SDSLC(IExternalShaderLoader ShaderLoader) public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuffer lastBuffer) { var parsed = SDSLParser.Parse(code); + lastBuffer = null; + if (parsed.Errors.Count > 0) + { + throw new Exception("Some parse errors"); + } if(parsed.AST is ShaderFile sf) { - lastBuffer = null; foreach (var declaration in sf.Namespaces.First().Declarations) { if (declaration is ShaderClass shader) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index ceac0ed6dc..f3b7b66879 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,5 +1,6 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; @@ -34,6 +35,8 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var offset = 0; var nextOffset = 0; + var table = new SymbolTable(); + foreach (var shaderName in inheritanceList) { var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName); @@ -151,7 +154,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //Console.WriteLine("Done type remapping"); //Spv.Dis(temp, true); - var context = new SpirvContext(new()); + var context = new SpirvContext(); context.Bound = offset + nextOffset + 1; //Spv.Dis(temp, true); ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); @@ -163,9 +166,8 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { var functionName = names2[function.ResultId]; - if (!context.Module.Functions.TryGetValue(functionName, out var functions)) - context.Module.Functions.Add(functionName, functions = new()); - functions.Add(new SpirvFunction(function.ResultId, functionName, (FunctionType)types[function.FunctionType])); + var symbol = new Symbol(new(functionName, SymbolKind.Method), types[function.FunctionType], function.ResultId); + table.CurrentFrame.Add(functionName, symbol); if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is {} functionInfo) { @@ -212,7 +214,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - new StreamAnalyzer().Process(temp, context); + new StreamAnalyzer().Process(table, temp, context); foreach (var inst in context.GetBuffer()) temp.Add(inst.Data); diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 21d418fb03..09baa98dfc 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -16,7 +16,7 @@ public static partial class Examples public static void GenerateSpirv() { var compiler = new CompilerUnit(); - var (builder, context, module) = compiler; + var (builder, context) = compiler; context.GetOrRegister(new MatrixType(ScalarType.From("float"), 4, 3)); context.GetOrRegister(ScalarType.From("int")); diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 4128e32554..688d3d3ee5 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -1,3 +1,7 @@ +using Stride.Shaders.Parsing.Analysis; +using System.Collections.Immutable; +using System.Xml.Linq; + namespace Stride.Shaders.Core; public class SymbolFrame() @@ -11,7 +15,23 @@ public Symbol this[string name] } public void Add(string name, Symbol symbol) - => symbols.Add(name, symbol); + { + if (symbol.Type is FunctionType && TryGetValue(name, out var existingSymbol)) + { + // If there is already a function symbol with same name, let's create or add to a group. + if (existingSymbol.Type is FunctionType) + existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); + + existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); + + symbols[name] = existingSymbol; + } + else + { + symbols.Add(name, symbol); + } + } + public void Remove(string name) => symbols.Remove(name); public bool ContainsKey(string name) => symbols.ContainsKey(name); diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 4916f11a6b..4d24af2532 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; using System.Runtime.InteropServices; +using System.Xml.Linq; namespace Stride.Shaders.Parsing.Analysis; @@ -11,12 +12,13 @@ public record struct SemanticErrors(TextLocation Location, string Message); public partial class SymbolTable : ISymbolProvider { public Dictionary DeclaredTypes { get; } = []; - public SymbolFrame CurrentFrame => CurrentSymbols[^1]; - public RootSymbolFrame RootSymbols { get; } = new(); - public SymbolFrame Streams { get; } = new(); + public RootSymbolFrame RootSymbols { get; } = new(); public List Errors { get; } = []; + // Used by Identifier.ResolveSymbol + public SymbolFrame CurrentFrame => CurrentSymbols[^1]; + // Used by Identifier.ResolveSymbol public List CurrentSymbols { get; } = new(); public ShaderSymbol? CurrentShader { get; set; } @@ -47,15 +49,26 @@ public void Import(ISymbolProvider symbols) RootSymbols.Add(name, symbol); } - public bool TryFind(string name, out Symbol symbol) + public bool TryResolveSymbol(string name, out Symbol symbol) { - if (CurrentSymbols is not null) - for (int i = CurrentSymbols.Count - 1; i >= 0; i--) - if (CurrentSymbols[i].TryGetValue(name, out symbol)) - return true; - return RootSymbols.TryGetValue(name, out symbol); + for (int i = CurrentSymbols.Count - 1; i >= 0; i--) + if (CurrentSymbols[i].TryGetValue(name, out symbol)) + return true; + symbol = default; + return false; } - + public Symbol ResolveSymbol(string name) + { + for (int i = CurrentSymbols.Count - 1; i >= 0; --i) + { + if (CurrentSymbols[i].TryGetValue(name, out var symbol)) + { + return symbol; + } + } + + throw new NotImplementedException($"Cannot find symbol {name}."); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index ce61ccb7a0..76403ff1a4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -34,10 +34,15 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var functionType = (FunctionType)Name.ResolveType(table); + var functionSymbol = table.ResolveSymbol(Name); + // TODO: find proper overload + if (functionSymbol.Type is FunctionGroupType) + functionSymbol = functionSymbol.GroupMembers.First(); + var functionType = (FunctionType)functionSymbol.Type; + Type = functionType.ReturnType; - var (builder, context, module) = compiler; + var (builder, context) = compiler; var list = parameters.Values; Span compiledParams = stackalloc int[list.Count]; var tmp = 0; @@ -59,7 +64,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil compiledParams[tmp++] = paramVariable; } - return builder.CallFunction(context, Name, [.. compiledParams]); + return builder.CallFunction(table, context, Name, [.. compiledParams]); } public override string ToString() @@ -96,7 +101,7 @@ public class PrefixExpression(Operator op, Expression expression, TextLocation i { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; var expression = Expression.CompileAsValue(table, shader, compiler); Type = Expression.Type; if (Expression.Type is PointerType pointerType && pointerType.BaseType is ScalarType { TypeName: "int" or "long" }) @@ -149,7 +154,7 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; SpirvValue source; var variable = context.Bound++; @@ -192,7 +197,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = accessor.Type; } - if (currentValueType is not PointerType) + if (currentValueType is not PointerType && currentValueType != ScalarType.From("void")) throw new InvalidOperationException(); Type = currentValueType; @@ -242,7 +247,7 @@ out var t else table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); - var (builder, context, _) = compiler; + var (builder, context) = compiler; return builder.BinaryOperation(context, context.GetOrRegister(Type), left, Op, right); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 7d80309f00..564502d51c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -150,7 +150,7 @@ public bool IsConstant() public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; + var (builder, context) = compiler; Span values = stackalloc int[Values.Count]; int tmp = 0; foreach (var v in Values) @@ -224,44 +224,12 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public Symbol ResolveSymbol(SymbolTable table) - { - for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) - { - if (table.CurrentSymbols![i] - .TryGetValue(Name, out var symbol)) - { - return symbol; - } - } - - throw new NotImplementedException($"Cannot find symbol {Name}."); - } - - public SymbolType ResolveType(SymbolTable table) - { - return ResolveSymbol(table).Type; - for (int i = table.CurrentSymbols.Count - 1; i >= 0; --i) - { - if (table.CurrentSymbols![i] - .TryGetValue(Name, out var symbol)) - { - if (symbol.Type is not UndefinedType and not null) - return symbol.Type; - else - return symbol.Type ?? new UndefinedType(Name); - } - } - - throw new NotImplementedException($"Cannot find symbol {Name}."); - } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var symbol = ResolveSymbol(table); + var symbol = table.ResolveSymbol(Name); Type = symbol.Type; - var (builder, context, _) = compiler; + var (builder, context) = compiler; var resultType = context.GetOrRegister(Type); var result = new SpirvValue(symbol.IdRef, resultType, Name); @@ -274,7 +242,6 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } return result; - // throw new NotImplementedException(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 5da5e248b9..16ef979b67 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -205,7 +205,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) member.ProcessSymbol(table); } - var (builder, context, _) = compiler; + var (builder, context) = compiler; context.PutShaderName(Name); foreach (var mixin in inheritanceList) @@ -225,7 +225,6 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.FluentAdd(new OpSDSLImportVariable(variableTypeId, context.Bound, c.Id.Name, shader.ResultId), out var variable); context.AddName(context.Bound, c.Id.Name); context.Bound++; - context.Module.InheritedVariables.Add(c.Id.Name, new(variable.ResultId, variable.ResultType, variable.VariableName)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId }); } else if (c.Id.Kind == SymbolKind.Method) @@ -236,16 +235,12 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound, c.Id.Name, shader.ResultId), out var function); context.AddName(context.Bound, c.Id.Name); context.Bound++; - if (!context.Module.InheritedFunctions.TryGetValue(c.Id.Name, out var inheritedFunctions)) - context.Module.InheritedFunctions.Add(c.Id.Name, inheritedFunctions = new()); - inheritedFunctions.Add(new(function.ResultId, c.Id.Name, functionType)); table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); } } // Mark inherit context.Add(new OpSDSLMixinInherit(shader.ResultId)); - context.Module.InheritedMixins.Add(shaderType); } foreach (var member in Elements.OfType()) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 860d6ef33c..5d939c173b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -85,7 +85,7 @@ public sealed class ShaderMember( public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; var registeredType = context.GetOrRegister(Type); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? @@ -179,27 +179,13 @@ public class ShaderMethod( public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; function = builder.DeclareFunction(context, Name, (FunctionType)Type); var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); table.CurrentShader.Components.Add(symbol); - - if (table.CurrentFrame.TryGetValue(Name, out var existingSymbol)) - { - // If there is already a function symbol with same name, let's create or add to a group. - if (existingSymbol.Type is FunctionType) - existingSymbol = new Symbol(new(Name, SymbolKind.MethodGroup), new FunctionGroupType(), 0, GroupMembers: ImmutableArray.Create(existingSymbol)); - - existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); - - table.CurrentFrame[Name] = existingSymbol; - } - else - { - table.CurrentFrame.Add(Name, symbol); - } + table.CurrentFrame.Add(Name, symbol); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -212,7 +198,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler arg.Type = argSym; } - var (builder, context, _) = compiler; + var (builder, context) = compiler; if (Type is FunctionType ftype) { builder.BeginFunction(context, function); @@ -222,10 +208,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (IsOverride == true) { // Find parent function - var inheritedFunctions = context.Module.InheritedFunctions[function.Name]; - var parentFunction = inheritedFunctions.Last(x => x.FunctionType == function.FunctionType); + var parentSymbol = table.ResolveSymbol(function.Name); + // TODO: find proper overload + if (parentSymbol.Type is FunctionGroupType) + parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); - functionInfo.ParentFunction = parentFunction.Id; + functionInfo.ParentFunction = parentSymbol.IdRef; functionInfo.Flags |= Specification.FunctionFlagsMask.Override; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 6077fd4020..e78525fdae 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -204,7 +204,7 @@ public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, { public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index c690f786a3..0ce3ec46d1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -20,7 +20,7 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public override unsafe void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; + var (builder, context) = compiler; var blockTrueIds = stackalloc int[ElseIfs.Count + 1]; var blockMergeIds = stackalloc int[ElseIfs.Count + 1]; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 02bdf5d50b..4184a08273 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -13,7 +13,7 @@ public class Break(TextLocation info) : Statement(info) { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; + var (builder, context) = compiler; if (builder.CurrentEscapeBlocks is not { } escapeBlocks) throw new InvalidOperationException("Can't process break statement (no context)"); @@ -32,7 +32,7 @@ public class Continue(TextLocation info) : Statement(info) { public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; + var (builder, context) = compiler; if (builder.CurrentEscapeBlocks is not { } escapeBlocks) throw new InvalidOperationException("Can't process continue statement (no context)"); @@ -109,7 +109,7 @@ public class For(Statement initializer, Expression cond, List update, public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, module) = compiler; + var (builder, context) = compiler; Initializer.Compile(table, shader, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index a3190957b5..71ba58887f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -43,7 +43,7 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, _, _) = compiler; + var (builder, _) = compiler; builder.Return(Value?.Compile(table, shader, compiler)); Type = Value?.Type ?? ScalarType.From("void"); } @@ -119,7 +119,7 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; var compiledValues = new SpirvValue[Variables.Count]; for (var index = 0; index < Variables.Count; index++) @@ -190,7 +190,7 @@ public class Assign(TextLocation info) : Statement(info) public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var (builder, context, _) = compiler; + var (builder, context) = compiler; foreach (var variable in Variables) { var target = variable.Variable.Compile(table, shader, compiler); @@ -258,7 +258,7 @@ public class BlockStatement(TextLocation info) : Statement(info) public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { table.Push(); - var (builder, context, _) = compiler; + var (builder, context) = compiler; foreach (var s in Statements) { s.Compile(table, shader, compiler); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 82df859f39..dc742520f3 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Parsing.SDSL.AST; @@ -123,22 +124,27 @@ when l.IsInteger() && r.IsInteger() return new(instruction, name); } - public SpirvValue CallFunction(SpirvContext context, string name, ReadOnlySpan parameters) + public SpirvValue CallFunction(SymbolTable table, SpirvContext context, string name, ReadOnlySpan parameters) { Span paramsIds = stackalloc int[parameters.Length]; var tmp = 0; foreach (var p in parameters) paramsIds[tmp++] = p.Id; - return CallFunction(context, name, [.. paramsIds]); + return CallFunction(table, context, name, [.. paramsIds]); } - public SpirvValue CallFunction(SpirvContext context, string name, Span parameters) + public SpirvValue CallFunction(SymbolTable table, SpirvContext context, string name, Span parameters) { - var funcGroup = context.FindFunctions(name); + //var funcGroup = context.FindFunctions(name); + var functionSymbol = table.ResolveSymbol(name); + // TODO: find proper overload + if (functionSymbol.Type is FunctionGroupType) + functionSymbol = functionSymbol.GroupMembers.First(); // TODO: find proper overload - var func = funcGroup.First(); - var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(func.FunctionType.ReturnType), context.Bound++, func.Id, [.. parameters])); - return new(fcall, func.Name); + //var func = funcGroup.First(); + var functionType = (FunctionType)functionSymbol.Type; + var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(functionType.ReturnType), context.Bound++, functionSymbol.IdRef, [.. parameters])); + return new(fcall, functionSymbol.Id.Name); } public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 23ff3f5099..1aa4d2213c 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -16,9 +16,6 @@ public SpirvFunction DeclareFunction(SpirvContext context, string name, Function context.GetOrRegister(t); context.AddName(func, name); var result = new SpirvFunction(func, name, ftype); - if (!context.Module.Functions.TryGetValue(name, out var functions)) - context.Module.Functions.Add(name, functions = new()); - functions.Add(result); return result; } diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 3b16d54614..fd5ee0442c 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -11,24 +11,21 @@ public abstract class CompilerArgument; public class CompilerUnit { - public SpirvModule Module { get; } public SpirvContext Context { get; } public SpirvBuilder Builder { get; } public List Arguments { get; } public CompilerUnit() { - Module = new SpirvModule(); - Context = new SpirvContext(Module); + Context = new SpirvContext(); Builder = new SpirvBuilder(); Arguments = []; } - public void Deconstruct(out SpirvBuilder builder, out SpirvContext context, out SpirvModule module) + public void Deconstruct(out SpirvBuilder builder, out SpirvContext context) { builder = Builder; context = Context; - module = Module; } #pragma warning disable CS0618 // Type or member is obsolete diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index ce5a3dfeee..dee37a24ec 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -40,11 +40,10 @@ public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvB // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters -public class SpirvContext(SpirvModule module) +public class SpirvContext { public int Bound { get; set; } = 1; public string? Name { get; private set; } - public SpirvModule Module { get; } = module; public SortedList Variables { get; } = []; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; @@ -314,14 +313,4 @@ public override string ToString() { return Spv.Dis(Buffer); } - - public List FindFunctions(string name) - { - var result = new List(); - if (Module.Functions.TryGetValue(name, out var funcGroup)) - result.AddRange(funcGroup); - if (Module.InheritedFunctions.TryGetValue(name, out funcGroup)) - result.AddRange(funcGroup); - return result; - } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Module.cs b/src/Stride.Shaders/Spirv/Building/Module.cs index 96322f0b7d..b2456672ff 100644 --- a/src/Stride.Shaders/Spirv/Building/Module.cs +++ b/src/Stride.Shaders/Spirv/Building/Module.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using System.Reflection; namespace Stride.Shaders.Spirv.Building; @@ -8,8 +9,15 @@ public class SpirvModule() { public Dictionary> Functions { get; init; } = []; - public List InheritedMixins { get; } = []; - - public Dictionary InheritedVariables { get; } = []; public Dictionary> InheritedFunctions { get; } = []; + + public List FindFunctions(string name) + { + var result = new List(); + if (Functions.TryGetValue(name, out var funcGroup)) + result.AddRange(funcGroup); + if (InheritedFunctions.TryGetValue(name, out funcGroup)) + result.AddRange(funcGroup); + return result; + } } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 173f7e31ae..1c1edb2abf 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; using System.IO; +using Stride.Shaders.Parsing.Analysis; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Processing @@ -38,11 +39,11 @@ record struct AnalysisResult(SortedList { } - public void Process(NewSpirvBuffer buffer, SpirvContext context) + public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { - var entryPointVS = context.FindFunctions("VSMain").FirstOrDefault(); - var entryPointPS = context.FindFunctions("PSMain").First(); - if (entryPointPS.Id == 0) + table.TryResolveSymbol("VSMain", out var entryPointVS); + var entryPointPS = table.ResolveSymbol("PSMain"); + if (entryPointPS.IdRef == 0) throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); var analysisResult = Analyze(buffer, context); @@ -55,7 +56,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Output = true; } - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.Id, entryPointPS.Name, analysisResult); + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult); // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -64,7 +65,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Read = false; } PropagateStreamsFromPreviousStage(streams); - if (entryPointVS.Id != 0) + if (entryPointVS.IdRef != 0) { // Expected at the end of vertex shader foreach (var stream in streams) @@ -73,7 +74,7 @@ public void Process(NewSpirvBuffer buffer, SpirvContext context) stream.Value.Stream.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.Id, entryPointVS.Name, analysisResult); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); } buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); From d8661a390fb2527e40753890b794b27a159f394c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 3 Oct 2025 11:29:51 +0900 Subject: [PATCH 0487/1182] Moved to xunit 3 (to easily capture output) --- src/Stride.Shaders.Tests/Program.cs | 5 +++++ src/Stride.Shaders.Tests/RenderingTests.cs | 7 +++---- .../Stride.Shaders.Parsing.Tests.csproj | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 src/Stride.Shaders.Tests/Program.cs diff --git a/src/Stride.Shaders.Tests/Program.cs b/src/Stride.Shaders.Tests/Program.cs new file mode 100644 index 0000000000..43e330bab8 --- /dev/null +++ b/src/Stride.Shaders.Tests/Program.cs @@ -0,0 +1,5 @@ +using Stride.Shaders.Parsing.Tests; + +[assembly: CaptureConsole] + +//new RenderingTests().RenderTest1("SimpleInheritanceBaseThis", "PSMain", "ExpectedResult=#FFFFFFFF"); \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 16c1df2631..983e9cc692 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -18,11 +18,10 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using Silk.NET.SPIRV; -using Xunit.Abstractions; namespace Stride.Shaders.Parsing.Tests; -public class RenderingTests(ITestOutputHelper Output) +public class RenderingTests { static int width = 1; static int height = 1; @@ -62,8 +61,8 @@ public void RenderTest1(string shaderName, string methodName, string args) : null; if (codeVS != null) - Output.WriteLine(codeVS); - Output.WriteLine(codePS); + Console.WriteLine(codeVS); + Console.WriteLine(codePS); // Execute test var renderer = new OpenGLFrameRenderer((uint)width, (uint)height); diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 38c0472654..e398cbba8f 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -14,8 +14,8 @@ - - + + From 1b6382e5a63881422328659ec15902c810fd98bc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 3 Oct 2025 15:52:42 +0900 Subject: [PATCH 0488/1182] Improvements virtcall and added base calls --- .../SimpleInheritanceBaseThis.sdsl | 49 ++++++ .../SDSL/ShaderMixer.cs | 153 ++++++++++++++---- .../Extensions/spirv.sdsl.grammar-ext.json | 12 +- .../Parsing/SDSL/AST/Expression.cs | 5 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Spirv/Building/Builder.Expressions.cs | 2 - src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- 7 files changed, 186 insertions(+), 41 deletions(-) create mode 100644 assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl diff --git a/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl new file mode 100644 index 0000000000..dd10166c5c --- /dev/null +++ b/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl @@ -0,0 +1,49 @@ +// PSMain(ExpectedResult=#FFFFFFFF) + +namespace Stride.Shaders.Tests; + +shader SimpleInheritanceBase +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void Test() + { + streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); + this.SetColor(float4(0.5, 0.5, 0.5, 0.5)); + } + + void PSMain() + { + Test(); + } + + abstract void SetColor(float4 color); +} + +shader SimpleInheritanceBaseOverride1 : SimpleInheritanceBase +{ + override void SetColor(float4 color) + { + streams.ColorTarget = color; + } +} + +shader SimpleInheritanceBaseOverride2 : SimpleInheritanceBase +{ + override void SetColor(float4 color) + { + base.SetColor(color); + streams.ColorTarget += color; + } +} + +shader SimpleInheritanceBaseThis : SimpleInheritanceBaseOverride1, SimpleInheritanceBaseOverride2 +{ +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index f3b7b66879..8bce52b222 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -8,6 +8,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; +using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -16,6 +17,11 @@ namespace Stride.Shaders.Compilers.SDSL; public class ShaderMixer(IExternalShaderLoader ShaderLoader) { + class MethodGroup + { + public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); + } + public void MergeSDSL(string entryShaderName, out byte[] bytecode) { // TODO: support proper shader mixin source @@ -56,14 +62,18 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) } } - var shaders = new Dictionary(); + var shadersByName = new Dictionary(); + var shaders = new List(); ShaderInfo? currentShader = null; var names = new Dictionary(); var importedShaders = new Dictionary(); var idRemapping = new Dictionary(); - foreach (var i in temp) + + Dictionary methodGroups = new(); + for (var index = 0; index < temp.Count; index++) { + var i = temp[index]; if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) { if (idRemapping.ContainsKey(nameInstruction.Target)) @@ -73,16 +83,15 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) } else if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) { - currentShader = new ShaderInfo(); + currentShader = new ShaderInfo(shaders.Count); var shaderName = shaderInstruction.ShaderName; - shaders.Add(shaderName, currentShader); - SetOpNop(i.Data.Memory.Span); + shadersByName.Add(shaderName, currentShader); + shaders.Add(currentShader); } else if (i.Data.Op == Op.OpSDSLShaderEnd) { currentShader = null; importedShaders.Clear(); - SetOpNop(i.Data.Memory.Span); } else if (i.Data.Op == Op.OpSDSLMixinInherit) { @@ -103,7 +112,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - importedShaders.Add(importShader.ResultId, shaders[importShader.ShaderName]); + importedShaders.Add(importShader.ResultId, shadersByName[importShader.ShaderName]); SetOpNop(i.Data.Memory.Span); } @@ -159,7 +168,6 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //Spv.Dis(temp, true); ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); - Dictionary methodOverrides = new Dictionary(); for (var index = 0; index < temp.Count; index++) { var i = temp[index]; @@ -168,45 +176,103 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var functionName = names2[function.ResultId]; var symbol = new Symbol(new(functionName, SymbolKind.Method), types[function.FunctionType], function.ResultId); table.CurrentFrame.Add(functionName, symbol); + } + } - if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is {} functionInfo) + foreach (var type in types) + { + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); + } + + // Build method group info (override, etc.) + for (var index = 0; index < temp.Count; index++) + { + var i = temp[index]; + if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) + { + currentShader = shadersByName[shaderInstruction.ShaderName]; + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLShaderEnd) + { + currentShader = null; + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && + (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { - if (functionInfo.ParentFunction != 0) - { - // TODO: better structure for more direct lookup by id? - // TODO: iterate to find real parent? or find it directly when computing shader? - methodOverrides[functionInfo.ParentFunction] = function.ResultId; - } + // Check if it has a parent (and if yes, share the MethodGroup) + if (!methodGroups.TryGetValue(functionInfo.Parent, out var methodGroupEntry)) + methodGroupEntry = (currentShader, 0, new()); + + methodGroupEntry.Shader = currentShader; + methodGroupEntry.MethodIndexInGroup = methodGroupEntry.Group.Methods.Count; + methodGroupEntry.Group.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); + methodGroups[function.ResultId] = methodGroupEntry; + + // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) { while (temp[index].Op != Op.OpFunctionEnd) { SetOpNop(temp[index++].Data.Memory.Span); } + SetOpNop(temp[index].Data.Memory.Span); - // Let's go to next instruction since we erased current function - continue; + } + else + { + // Remove the OpSDSLFunctionInfo + SetOpNop(temp[index + 1].Data.Memory.Span); } } - SetOpNop(temp[index + 1].Data.Memory.Span); } } - foreach (var type in types) + // Patch method calls (virtual calls & base calls) + for (var index = 0; index < temp.Count; index++) { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); - } + var i = temp[index]; + if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + if (!methodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {names2[function.ResultId]}"); - // Patch virtual method calls - foreach (var i in temp) - { - if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) + currentShader = methodGroupEntry.Shader; + } + else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) { - if (methodOverrides.TryGetValue(functionCall.Function, out var functionOverride)) + if (!methodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {names2[functionCall.Function]}"); + + if (temp[index - 1].Op == Op.OpSDSLBase) + { + // Is it a base call? if yes, find the direct parent + SetOpNop(temp[index - 1].Data.Memory.Span); + + // Let's find the method in same group just before ours + bool baseMethodFound = false; + for (int j = methodGroupEntry.Group.Methods.Count - 1; j >= 0; --j) + { + if (methodGroupEntry.Group.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) + { + functionCall.Function = methodGroupEntry.Group.Methods[j].MethodId; + baseMethodFound = true; + break; + } + } + + if (!baseMethodFound) + throw new InvalidOperationException($"Can't find a base method for {names2[functionCall.Function]}"); + } + else { - functionCall.Function = functionOverride; + // If not, get the most derived implementation + functionCall.Function = methodGroupEntry.Group.Methods[^1].MethodId; } } } @@ -214,6 +280,17 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); + + { + for (int i = 0; i < temp.Count; i++) + { + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + } + temp.Sort(); + Spv.Dis(temp, true); + } + new StreamAnalyzer().Process(table, temp, context); foreach (var inst in context.GetBuffer()) @@ -236,8 +313,10 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //File.WriteAllText("test.spvdis", source); } - class ShaderInfo + class ShaderInfo(int shaderIndex) { + public int ShaderIndex { get; } = shaderIndex; + public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); } @@ -257,7 +336,10 @@ public static void OffsetIds(OpData inst, int offset) || o.Kind == OperandKind.IdResultType) { for (int i = 0; i < o.Words.Length; ++i) - o.Words[i] += offset; + { + if (o.Words[i] != 0) + o.Words[i] += offset; + } } else if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairLiteralIntegerIdRef @@ -266,9 +348,16 @@ public static void OffsetIds(OpData inst, int offset) for (int i = 0; i < o.Words.Length; i += 2) { if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 0] += offset; + { + if (o.Words[i * 2 + 0] != 0) + o.Words[i * 2 + 0] += offset; + } + if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 1] += offset; + { + if (o.Words[i * 2 + 1] != 0) + o.Words[i * 2 + 1] += offset; + } } } } diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 3bf8965a04..56ecb7038e 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -97,15 +97,19 @@ "opname": "OpSDSLFunctionInfo", "class": "Miscellaneous", "operands": [ - { - "kind": "IdRef", - "name": "parentFunction" - }, { "kind": "FunctionFlags", "name": "flags" + }, + { + "kind": "IdRef", + "name": "parent" } ] + }, + { + "opname": "OpSDSLBase", + "class": "Miscellaneous" } ], "operand_kinds": [ diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 76403ff1a4..c5966ea2bc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -31,6 +31,7 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo { public Identifier Name = name; public ShaderExpressionList Parameters = parameters; + public bool IsBaseCall { get; set; } = false; public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -64,6 +65,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil compiledParams[tmp++] = paramVariable; } + if (IsBaseCall) + builder.Insert(new OpSDSLBase()); return builder.CallFunction(table, context, Name, [.. compiledParams]); } @@ -168,6 +171,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) { + if (Source is Identifier { Name: "base" }) + methodCall.IsBaseCall = true; source = methodCall.Compile(table, shader, compiler); currentValueType = methodCall.Type; firstIndex = 1; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 5d939c173b..da0649c8de 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -203,7 +203,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { builder.BeginFunction(context, function); - var functionInfo = new OpSDSLFunctionInfo(0, Specification.FunctionFlagsMask.None); + var functionInfo = new OpSDSLFunctionInfo(Specification.FunctionFlagsMask.None, 0); if (IsOverride == true) { @@ -213,7 +213,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (parentSymbol.Type is FunctionGroupType) parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); - functionInfo.ParentFunction = parentSymbol.IdRef; + functionInfo.Parent = parentSymbol.IdRef; functionInfo.Flags |= Specification.FunctionFlagsMask.Override; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index dc742520f3..b5d587f7ab 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -140,8 +140,6 @@ public SpirvValue CallFunction(SymbolTable table, SpirvContext context, string n if (functionSymbol.Type is FunctionGroupType) functionSymbol = functionSymbol.GroupMembers.First(); - // TODO: find proper overload - //var func = funcGroup.First(); var functionType = (FunctionType)functionSymbol.Type; var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(functionType.ReturnType), context.Bound++, functionSymbol.IdRef, [.. parameters])); return new(fcall, functionSymbol.Id.Name); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index c60c7fc879..e1d894c778 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -28,7 +28,7 @@ public void AddFunctionVariable(int paramType, int paramVariable) SetPositionTo(f.BasicBlocks.First().Value, true); // Go after label and the last OpVariable Position++; - while (Buffer[Position].Op == Op.OpVariable) + while (Position + 1 < Buffer.Count && Buffer[Position].Op == Op.OpVariable) Position++; Insert(new OpVariable(paramType, paramVariable, StorageClass.Function, null)); From 1155109a2ae4a1647928e8b41f9a767dc2dc7e20 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Oct 2025 14:43:49 +0900 Subject: [PATCH 0489/1182] Progress on composition --- assets/SDSL/RenderTests/CompositionTest1.sdsl | 47 ++ .../SDSL/ShaderMixer.cs | 431 ++++++++++++------ .../Extensions/spirv.sdsl.grammar-ext.json | 32 +- .../Parsing/SDSL/AST/Expression.cs | 95 ++-- .../Parsing/SDSL/AST/Literals.cs | 23 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 77 +++- .../Spirv/Building/Builder.Expressions.cs | 16 +- src/Stride.Shaders/Spirv/Building/Context.cs | 23 + .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 7 + 10 files changed, 543 insertions(+), 210 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionTest1.sdsl diff --git a/assets/SDSL/RenderTests/CompositionTest1.sdsl b/assets/SDSL/RenderTests/CompositionTest1.sdsl new file mode 100644 index 0000000000..371aa3f21f --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionTest1.sdsl @@ -0,0 +1,47 @@ +// PSMain(ExpectedResult=#7F7F7F7F) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float4 Compute() + { + return float4(0.0, 0.0, 0.0, 0.0); + } +}; + +shader CompositionShaderA : CompositionBase +{ + override float4 Compute() + { + return float4(0.3, 0.3, 0.3, 0.3); + } +}; + +shader CompositionShaderB : CompositionBase +{ + override float4 Compute() + { + return float4(0.2, 0.2, 0.2, 0.2); + } +}; + +shader CompositionTest +{ + stream float4 ColorTarget : SV_Target0; + + CompositionBase Comp0; + CompositionBase Comp1; + + void PSMain() + { + streams.ColorTarget = Comp0.Compute() + Comp1.Compute(); + } +}; + +effect CompositionTest1 +{ + mixin CompositionTest; + mixin compose Comp0 = CompositionShaderA; + mixin compose Comp1 = CompositionShaderB; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 8bce52b222..bea6f42b37 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Core; +using Silk.NET.SPIRV.Cross; +using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; @@ -10,6 +11,7 @@ using Stride.Shaders.Spirv.Tools; using System; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -17,13 +19,80 @@ namespace Stride.Shaders.Compilers.SDSL; public class ShaderMixer(IExternalShaderLoader ShaderLoader) { + class MixinGroup + { + public List InheritanceList { get; } = new(); + } + + public void MergeSDSL(string entryShaderName, out byte[] bytecode) + { + var temp = new NewSpirvBuffer(); + + var context = new SpirvContext(); + var table = new SymbolTable(); + + // Root shader + MergeSDSLMixin(context, table, temp, entryShaderName); + + context.Insert(0, new OpCapability(Capability.Shader)); + context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); + + { + for (int i = 0; i < temp.Count; i++) + { + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + } + temp.Sort(); + Spv.Dis(temp, true); + } + + new StreamAnalyzer().Process(table, temp, context); + + foreach (var inst in context.GetBuffer()) + temp.Add(inst.Data); + + new TypeDuplicateRemover().Apply(temp); + for (int i = 0; i < temp.Count; i++) + { + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + } + + + temp.Sort(); + + bytecode = temp.ToBytecode(); + + //File.WriteAllBytes("test.spv", bytecode); + + Spv.Dis(temp, true); + //File.WriteAllText("test.spvdis", source); + } + class MethodGroup { + public string Name; + public int MethodIndexInGroup; + public ShaderInfo Shader; public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); } - public void MergeSDSL(string entryShaderName, out byte[] bytecode) + + class MixinResult { + public Dictionary MethodGroupsByName { get; } = new(); + + public Dictionary MethodGroups { get; } = new(); + + public Dictionary Compositions { get; } = new(); + } + + MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuffer temp, string entryShaderName) + { + var mixinResult = new MixinResult(); + // TODO: support proper shader mixin source //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; @@ -37,21 +106,28 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); inheritanceList.Add(entryShaderName); - var temp = new NewSpirvBuffer(); - var offset = 0; + var offset = context.Bound; var nextOffset = 0; - var table = new SymbolTable(); + var shaders = new List(); + var shadersByName = new Dictionary(); + var mixinStart = temp.Count; foreach (var shaderName in inheritanceList) { var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName); offset += nextOffset; nextOffset = 0; shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; + + var shaderStart = temp.Count; + + // Copy instructions to single buffer foreach (var i in shader) { var i2 = new OpData(i.Data.Memory.Span); + + // Ignore mixin inherit (already computed with inheritance list) temp.Add(i2); if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) @@ -60,115 +136,31 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) if (offset > 0) OffsetIds(i2, offset); } - } - var shadersByName = new Dictionary(); - var shaders = new List(); - ShaderInfo? currentShader = null; + var shaderInfo = new ShaderInfo(shaders.Count); + PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo); + shadersByName.Add(shaderName, shaderInfo); + shaders.Add(shaderInfo); - var names = new Dictionary(); - var importedShaders = new Dictionary(); - var idRemapping = new Dictionary(); - - Dictionary methodGroups = new(); - for (var index = 0; index < temp.Count; index++) - { - var i = temp[index]; - if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) - { - if (idRemapping.ContainsKey(nameInstruction.Target)) - SetOpNop(i.Data.Memory.Span); - else - names.Add(nameInstruction.Target, nameInstruction.Name); - } - else if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) - { - currentShader = new ShaderInfo(shaders.Count); - var shaderName = shaderInstruction.ShaderName; - shadersByName.Add(shaderName, currentShader); - shaders.Add(currentShader); - } - else if (i.Data.Op == Op.OpSDSLShaderEnd) - { - currentShader = null; - importedShaders.Clear(); - } - else if (i.Data.Op == Op.OpSDSLMixinInherit) - { - SetOpNop(i.Data.Memory.Span); - } - - if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) - { - var functionName = names[function.ResultId]; - currentShader!.Functions.Add(functionName, function.ResultId); - } - - if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) - { - var variableName = names[variable.ResultId]; - currentShader!.Variables.Add(variableName, variable.ResultId); - } - - if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) - { - importedShaders.Add(importShader.ResultId, shadersByName[importShader.ShaderName]); - - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) - { - var importedShader = importedShaders[importVariable.Shader]; - - var importedVariable = importedShader.Variables[importVariable.VariableName]; - - idRemapping.Add(importVariable.ResultId, importedVariable); - - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) - { - var importedShader = importedShaders[importFunction.Shader]; - var importedFunction = importedShader.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - - SetOpNop(i.Data.Memory.Span); - } - - foreach (var op in i.Data) - { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) - op.Words[0] = to1; - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - op.Words[1] = to2; - } + RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, shadersByName); } + var mixinEnd = temp.Count; + //Console.WriteLine("Done SDSL importing"); //Spv.Dis(temp, true); - // Step: merge mixins - // start from most-derived class and import on demand - // Step: analyze streams and generate in/out variables - new TypeDuplicateRemover().Apply(temp); //Console.WriteLine("Done type remapping"); //Spv.Dis(temp, true); - var context = new SpirvContext(); context.Bound = offset + nextOffset + 1; //Spv.Dis(temp, true); - ShaderClass.ProcessNameAndTypes(temp, out var names2, out var types); + ShaderClass.ProcessNameAndTypes(temp, 0, temp.Count, out var names2, out var types); - for (var index = 0; index < temp.Count; index++) + // Add symbol for each method in current type (equivalent to implicit this pointer) + for (var index = mixinStart; index < mixinEnd; index++) { var i = temp[index]; if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) @@ -179,14 +171,19 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) } } + // Build type mappings foreach (var type in types) { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); + if (!context.ReverseTypes.ContainsKey(type.Key)) + { + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); + } } // Build method group info (override, etc.) - for (var index = 0; index < temp.Count; index++) + ShaderInfo? currentShader = null; + for (var index = mixinStart; index < mixinEnd; index++) { var i = temp[index]; if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) @@ -204,15 +201,22 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { + var functionName = names2[function.ResultId]; + // Check if it has a parent (and if yes, share the MethodGroup) - if (!methodGroups.TryGetValue(functionInfo.Parent, out var methodGroupEntry)) - methodGroupEntry = (currentShader, 0, new()); + if (!mixinResult.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) + methodGroup = new MethodGroup { Name = functionName }; + + methodGroup.Shader = currentShader; + methodGroup.MethodIndexInGroup = methodGroup.Methods.Count; + methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); + + mixinResult.MethodGroups[function.ResultId] = methodGroup; - methodGroupEntry.Shader = currentShader; - methodGroupEntry.MethodIndexInGroup = methodGroupEntry.Group.Methods.Count; - methodGroupEntry.Group.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); + // Also add lookup by name + if (!mixinResult.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) + mixinResult.MethodGroupsByName.Add(functionName, function.ResultId); - methodGroups[function.ResultId] = methodGroupEntry; // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) @@ -233,34 +237,102 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) } } + // Compositions + foreach (var shader in shaders) + { + foreach (var variable in shader.Variables) + { + if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol) + { + + MixinResult compositionResult; + if (variable.Key == "Comp0") + compositionResult = MergeSDSLMixin(context, table, temp, "CompositionShaderA"); + else if (variable.Key == "Comp1") + compositionResult = MergeSDSLMixin(context, table, temp, "CompositionShaderB"); + else + throw new NotImplementedException(); + + mixinResult.Compositions.Add(variable.Value.Id, compositionResult); + } + } + } + + // Patch method calls (virtual calls & base calls) - for (var index = 0; index < temp.Count; index++) + var externalShaders = new HashSet(); + var externalFunctions = new Dictionary(); + for (var index = mixinStart; index < mixinEnd; index++) { var i = temp[index]; - if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + // Only import shaders should be left + if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + { + // Only external should be left + if (importShader.Type == ImportType.External) + { + externalShaders.Add(importShader.ResultId); + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) { - if (!methodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) + if (externalShaders.Contains(importFunction.Shader)) + { + externalFunctions.Add(importFunction.ResultId, importFunction.FunctionName); + SetOpNop(i.Data.Memory.Span); + } + } + // Removing OpName for OpSDSLImportShader and OpSDSLImportFunction (they are always located after, so no problem to do it in a single pass) + else if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + if (externalShaders.Contains(nameInstruction.Target) || externalFunctions.ContainsKey(nameInstruction.Target)) + { + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + if (!mixinResult.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) throw new InvalidOperationException($"Can't find method group info for {names2[function.ResultId]}"); currentShader = methodGroupEntry.Shader; } else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) { + var methodGroups = mixinResult.MethodGroups; + + // Process member call (composition) + if (temp[index - 1].Op == Op.OpSDSLCallTarget) + { + var callTarget = (OpSDSLCallTarget)temp[index - 1]; + var composition = mixinResult.Compositions[callTarget.Target]; + methodGroups = composition.MethodGroups; + + Spv.Dis(temp, false); + + var functionName = externalFunctions[functionCall.Function]; + var functionId = composition.MethodGroupsByName[functionName]; + + functionCall.Function = functionId; + + SetOpNop(temp[index - 1].Data.Memory.Span); + } + if (!methodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) throw new InvalidOperationException($"Can't find method group info for {names2[functionCall.Function]}"); - if (temp[index - 1].Op == Op.OpSDSLBase) + // Process base call + if (temp[index - 1].Op == Op.OpSDSLCallBase) { // Is it a base call? if yes, find the direct parent - SetOpNop(temp[index - 1].Data.Memory.Span); - // Let's find the method in same group just before ours bool baseMethodFound = false; - for (int j = methodGroupEntry.Group.Methods.Count - 1; j >= 0; --j) + for (int j = methodGroupEntry.Methods.Count - 1; j >= 0; --j) { - if (methodGroupEntry.Group.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) + if (methodGroupEntry.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) { - functionCall.Function = methodGroupEntry.Group.Methods[j].MethodId; + functionCall.Function = methodGroupEntry.Methods[j].MethodId; baseMethodFound = true; break; } @@ -268,57 +340,136 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) if (!baseMethodFound) throw new InvalidOperationException($"Can't find a base method for {names2[functionCall.Function]}"); + + SetOpNop(temp[index - 1].Data.Memory.Span); } else { // If not, get the most derived implementation - functionCall.Function = methodGroupEntry.Group.Methods[^1].MethodId; + functionCall.Function = methodGroupEntry.Methods[^1].MethodId; } } } - context.Insert(0, new OpCapability(Capability.Shader)); - context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - + for (var index = mixinStart; index < mixinEnd; index++) { - for (int i = 0; i < temp.Count; i++) + var i = temp[index]; + if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction) { - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); + SetOpNop(i.Data.Memory.Span); + } + + if (i.Op == Op.OpTypePointer) + { + } - temp.Sort(); - Spv.Dis(temp, true); } - new StreamAnalyzer().Process(table, temp, context); + return mixinResult; + } - foreach (var inst in context.GetBuffer()) - temp.Add(inst.Data); + private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo) + { + ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); - new TypeDuplicateRemover().Apply(temp); - for (int i = 0; i < temp.Count; i++) + for (var index = shaderStart; index < shaderEnd; index++) { - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); + var i = temp[index]; + + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + shaderInfo.Names.Add(nameInstruction.Target, nameInstruction.Name); + } + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + var functionName = shaderInfo.Names[function.ResultId]; + shaderInfo!.Functions.Add(functionName, function.ResultId); + } + else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + { + var variableName = shaderInfo.Names[variable.ResultId]; + shaderInfo!.Variables.Add(variableName, (variable.ResultId, types[variable.ResultType])); + } } + } - temp.Sort(); + private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, Dictionary shadersByName) + { + var importedShaders = new Dictionary(); + var idRemapping = new Dictionary(); + for (var index = shaderStart; index < temp.Count; index++) + { + var i = temp[index]; - bytecode = temp.ToBytecode(); + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + if (idRemapping.ContainsKey(nameInstruction.Target)) + { + SetOpNop(i.Data.Memory.Span); + shaderInfo.Names.Remove(nameInstruction.Target); + } + } + else if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) + { + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + { + if (importShader.Type == ImportType.Inherit) + { + importedShaders.Add(importShader.ResultId, shadersByName[importShader.ShaderName]); - //File.WriteAllBytes("test.spv", bytecode); + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + { + if (importedShaders.TryGetValue(importVariable.Shader, out var importedShader)) + { + var importedVariable = importedShader.Variables[importVariable.VariableName]; - Spv.Dis(temp, true); - //File.WriteAllText("test.spvdis", source); + idRemapping.Add(importVariable.ResultId, importedVariable.Id); + + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + { + if (importedShaders.TryGetValue(importFunction.Shader, out var importedShader)) + { + var importedFunction = importedShader.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + + SetOpNop(i.Data.Memory.Span); + } + } + + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) + op.Words[0] = to1; + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + op.Words[1] = to2; + } + } } class ShaderInfo(int shaderIndex) { public int ShaderIndex { get; } = shaderIndex; + public Dictionary Names { get; } = new(); + + public Dictionary Functions { get; } = new(); - public Dictionary Variables { get; } = new(); + public Dictionary Variables { get; } = new(); } static void SetOpNop(Span words) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 56ecb7038e..1cf4e6807a 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -58,7 +58,11 @@ { "kind": "LiteralString", "name": "shaderName" - } + }, + { + "kind": "ImportType", + "name": "type" + } ] }, { @@ -108,7 +112,17 @@ ] }, { - "opname": "OpSDSLBase", + "opname": "OpSDSLCallTarget", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "target" + } + ] + }, + { + "opname": "OpSDSLCallBase", "class": "Miscellaneous" } ], @@ -139,6 +153,20 @@ } ] }, + { + "category": "ValueEnum", + "kind": "ImportType", + "enumerants": [ + { + "enumerant": "External", + "value": 0 + }, + { + "enumerant": "Inherit", + "value": 1 + } + ] + }, { "kind": "ExecutionModel", "enumerants": [ diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index c5966ea2bc..c726a2bda9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -31,11 +31,25 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo { public Identifier Name = name; public ShaderExpressionList Parameters = parameters; + + public SpirvValue? MemberCall { get; set; } public bool IsBaseCall { get; set; } = false; public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var functionSymbol = table.ResolveSymbol(Name); + var (builder, context) = compiler; + + Symbol functionSymbol; + if (MemberCall != null) + { + var type = (ShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; + functionSymbol = type.Components.Single(x => x.Id.Name == Name); + } + else + { + functionSymbol = table.ResolveSymbol(Name); + } + // TODO: find proper overload if (functionSymbol.Type is FunctionGroupType) functionSymbol = functionSymbol.GroupMembers.First(); @@ -43,8 +57,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil Type = functionType.ReturnType; - var (builder, context) = compiler; var list = parameters.Values; + Span compiledParams = stackalloc int[list.Count]; var tmp = 0; @@ -65,9 +79,16 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil compiledParams[tmp++] = paramVariable; } - if (IsBaseCall) - builder.Insert(new OpSDSLBase()); - return builder.CallFunction(table, context, Name, [.. compiledParams]); + if (MemberCall != null) + { + builder.Insert(new OpSDSLCallTarget(MemberCall.Value.Id)); + } + else if (IsBaseCall) + { + builder.Insert(new OpSDSLCallBase()); + } + + return builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); } public override string ToString() @@ -158,14 +179,14 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - SpirvValue source; + SpirvValue result; var variable = context.Bound++; int firstIndex = 0; SymbolType currentValueType; if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { - source = streamVar.Compile(table, shader, compiler); + result = streamVar.Compile(table, shader, compiler); currentValueType = streamVar.Type; firstIndex = 1; } @@ -173,47 +194,63 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; - source = methodCall.Compile(table, shader, compiler); + result = methodCall.Compile(table, shader, compiler); currentValueType = methodCall.Type; firstIndex = 1; } else { - source = Source.Compile(table, shader, compiler); + result = Source.Compile(table, shader, compiler); currentValueType = Source.Type; } Span indexes = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i < Accessors.Count; i++) + for (var i = firstIndex; i <= Accessors.Count; i++) { + // Last accessor (or method call next) + if (i == Accessors.Count || Accessors[i] is MethodCall) + { + // Do we need to issue an OpAccessChain? + if (i > firstIndex) + { + var resultType = context.GetOrRegister(Type); + var accessChain = builder.Insert(new OpAccessChain(variable, resultType, result.Id, [.. indexes.Slice(firstIndex, i - firstIndex)])); + result = new SpirvValue(accessChain.ResultId, resultType); + } + + if (i == Accessors.Count) + break; + + firstIndex = i + 1; + } + var accessor = Accessors[i]; - if (currentValueType is PointerType p && p.BaseType is StructType s && accessor is Identifier field) + switch (currentValueType, accessor) { - var index = s.TryGetFieldIndex(field); - if (index == -1) - throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); - //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.Compile(table, shader, compiler); - indexes[i] = context.CreateConstant(indexLiteral).Id; + case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + methodCall2.MemberCall = result; + result = methodCall2.Compile(table, shader, compiler); + break; + case (PointerType { BaseType: StructType s }, Identifier field): + var index = s.TryGetFieldIndex(field); + if (index == -1) + throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.Compile(table, shader, compiler); + indexes[i] = context.CreateConstant(indexLiteral).Id; + break; + // TODO: Swizzle, etc. + default: + throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); } - else throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); currentValueType = accessor.Type; } - if (currentValueType is not PointerType && currentValueType != ScalarType.From("void")) - throw new InvalidOperationException(); - Type = currentValueType; - // Do we need the OpAccessChain? (if we have streams.StreamVar, we can return StreamVar as is) - if (firstIndex == Accessors.Count) - return source; - - var resultType = context.GetOrRegister(Type); - var result = builder.Insert(new OpAccessChain(variable, resultType, source.Id, [.. indexes])); - return new(result.ResultId, resultType); + return result; } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 564502d51c..c87dbdd245 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Text; @@ -291,18 +292,20 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public List? ArraySize { get; set; } public List Generics { get; set; } = []; - public SymbolType ResolveType(SymbolTable table) + public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolType symbolType) { if (!IsArray && Generics.Count == 0) { - if (table.DeclaredTypes.TryGetValue(Name, out var type)) - return type; + if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) + return true; else if (SymbolType.TryGetNumeric(Name, out var numeric)) { table.DeclaredTypes.Add(numeric.ToString(), numeric); - return numeric; + symbolType = numeric; + return true; } - else throw new NotImplementedException(); + + return false; } // else if (IsArray && Generics.Count == 0) // { @@ -312,7 +315,15 @@ public SymbolType ResolveType(SymbolTable table) // } // else table.Errors.Add(new(Info, "type not found")); // } - else throw new NotImplementedException(); + symbolType = null; + return false; + } + + public SymbolType ResolveType(SymbolTable table) + { + if (!TryResolveType(table, out var result)) + throw new InvalidOperationException($"Could not resolve type [{Name}]"); + return result; } public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 16ef979b67..eac1c4a845 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Reflection; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -22,13 +23,16 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public ShaderParameterDeclarations? Generics { get; set; } public List Mixins { get; set; } = []; - public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buffer, out Dictionary names, out Dictionary types) + // Note: We should make this method incremental (called many times in ShaderMixer) + // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) + public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) { var memberNames = new Dictionary<(int, int), string>(); names = []; types = []; - foreach (var instruction in buffer) + for (var i = start; i < end; i++) { + var instruction = buffer[i]; if (instruction.Op == Op.OpName) { OpName nameInstruction = instruction; @@ -101,16 +105,35 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf } types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); } + else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) + { + if (importShader.Type == ImportType.External) + { + types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, [])); + } + } + } + foreach (var instruction in buffer) + { + if (instruction.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)instruction is { } importFunction) + { + if (types.TryGetValue(importFunction.Shader, out var type) && type is ShaderSymbol shaderSymbol) + { + var returnType = types[importFunction.ResultType]; + var symbol = new Symbol(new(importFunction.FunctionName, SymbolKind.Method), returnType, importFunction.ResultId); + // TODO: review if really necessary? + // (external functions are resolved differently) + shaderSymbol.Components.Add(symbol); + } + } } return types; } - private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoader, string mixin) + private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string className) { - externalShaderLoader.LoadExternalBuffer(mixin, out var buffer); - - ProcessNameAndTypes(buffer, out var names, out var types); + ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); var symbols = new List(); foreach (var instruction in buffer) @@ -136,7 +159,7 @@ private static ShaderSymbol LoadShader(IExternalShaderLoader externalShaderLoade } } - var shaderType = new ShaderSymbol(mixin, symbols); + var shaderType = new ShaderSymbol(className, symbols); return shaderType; } @@ -147,6 +170,9 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp public void Compile(CompilerUnit compiler, SymbolTable table) { + var (builder, context) = compiler; + context.PutShaderName(Name); + table.Push(); var inheritanceList = new List(); @@ -157,10 +183,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) foreach (var mixin in inheritanceList) { - // Check if shader isn't already loaded as part of current bytecode - var shaderType = LoadShader(table.ShaderLoader, mixin); - - RegisterShaderType(table, shaderType); + LoadExternalShaderType(table, mixin); } var symbols = new List(); @@ -182,7 +205,14 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } else if (member is ShaderMember svar) { - svar.Type = new PointerType(svar.TypeName.ResolveType(table), Specification.StorageClass.Private); + if (!svar.TypeName.TryResolveType(table, out var memberType)) + { + memberType = LoadExternalShaderType(table, svar.TypeName.Name); + + table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); + } + + svar.Type = new PointerType(memberType, Specification.StorageClass.Private); table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } else if (member is CBuffer cb) @@ -205,18 +235,15 @@ public void Compile(CompilerUnit compiler, SymbolTable table) member.ProcessSymbol(table); } - var (builder, context) = compiler; - context.PutShaderName(Name); - foreach (var mixin in inheritanceList) { + var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin]; + // Import types and variables/functions - context.FluentAdd(new OpSDSLImportShader(context.Bound, new(mixin)), out var shader); - context.AddName(context.Bound, mixin); + context.FluentAdd(new OpSDSLImportShader(context.Bound, new(shaderType.Name), ImportType.Inherit), out var shader); + context.AddName(context.Bound, shaderType.Name); context.Bound++; - var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin]; - foreach (var c in shaderType.Components) { if (c.Id.Kind == SymbolKind.Variable) @@ -259,6 +286,18 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Pop(); } + private static ShaderSymbol LoadExternalShaderType(SymbolTable table, string className) + { + if (!table.ShaderLoader.LoadExternalBuffer(className, out var shaderBuffer)) + throw new InvalidOperationException($"Type [{className}] not found"); + + var shaderType = CreateShaderType(shaderBuffer, className); + + RegisterShaderType(table, shaderType); + + return shaderType; + } + public override string ToString() { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index b5d587f7ab..4014034c31 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -124,21 +124,11 @@ when l.IsInteger() && r.IsInteger() return new(instruction, name); } - public SpirvValue CallFunction(SymbolTable table, SpirvContext context, string name, ReadOnlySpan parameters) + public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol functionSymbol, Span parameters) { - Span paramsIds = stackalloc int[parameters.Length]; - var tmp = 0; - foreach (var p in parameters) - paramsIds[tmp++] = p.Id; - return CallFunction(table, context, name, [.. paramsIds]); - } - public SpirvValue CallFunction(SymbolTable table, SpirvContext context, string name, Span parameters) - { - //var funcGroup = context.FindFunctions(name); - var functionSymbol = table.ResolveSymbol(name); - // TODO: find proper overload + // Note: Overload should have been chosen before if (functionSymbol.Type is FunctionGroupType) - functionSymbol = functionSymbol.GroupMembers.First(); + throw new InvalidOperationException(); var functionType = (FunctionType)functionSymbol.Type; var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(functionType.ReturnType), context.Bound++, functionSymbol.IdRef, [.. parameters])); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index dee37a24ec..e80d34fc4c 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -174,6 +174,7 @@ public int GetOrRegister(SymbolType? type) ConstantBufferSymbol cb => RegisterCBuffer(cb), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), + ShaderSymbol s => RegisterShaderType(s), // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") @@ -184,6 +185,28 @@ public int GetOrRegister(SymbolType? type) } } + private int RegisterShaderType(ShaderSymbol shaderSymbol) + { + FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), ImportType.External), out var shader); + AddName(shader.ResultId, shaderSymbol.Name); + for (var index = 0; index < shaderSymbol.Components.Count; index++) + { + var c = shaderSymbol.Components[index]; + if (c.Id.Kind == SymbolKind.Method) + { + var functionType = (FunctionType)c.Type; + var functionReturnTypeId = GetOrRegister(functionType.ReturnType); + + c.IdRef = Bound++; + Add(new OpSDSLImportFunction(functionReturnTypeId, c.IdRef, c.Id.Name, shader.ResultId)); + AddName(c.IdRef, c.Id.Name); + } + shaderSymbol.Components[index] = c; + } + + return shader.ResultId; + } + private int RegisterCBuffer(ConstantBufferSymbol cb) { var result = RegisterStructuredType($"type.{cb.ToId()}", cb); diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index f0861d480b..7b9777f3e4 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -14,7 +14,7 @@ namespace Stride.Shaders.Spirv.Processing; /// /// Remove duplicate simple types. -/// Should be applied before the IdRefOffsetter. +/// Should be applied after the IdRefOffsetter. /// public struct TypeDuplicateRemover : INanoPass { diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index db33cd5596..9cc0756a69 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -657,6 +657,13 @@ or OperandKind.LiteralSpecConstantOpInteger (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, + OperandKind.ImportType => (operand.Quantifier, operand.Words.Length) switch + { + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), + _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) + }, _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), }; // _ = (operand.Kind, operand.Quantifier) switch From 16b6a5f54991c6cfd9cb05b0783a036cd8bfb34d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Oct 2025 18:55:35 +0900 Subject: [PATCH 0490/1182] Added basic effect parser, and composition first test is working! --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 12 ++ .../SDSL/ShaderMixer.cs | 131 ++++++++++++++++-- .../SDSL/ShaderSource.cs | 86 ++++++++++++ src/Stride.Shaders.Experiments/Examples.cs | 24 ---- .../Extensions/spirv.sdsl.grammar-ext.json | 42 +++++- src/Stride.Shaders.Tests/RenderingTests.cs | 3 +- .../Parsing/SDFX/AST/Effect.Flow.cs | 9 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 126 ++++++++++++++++- 8 files changed, 388 insertions(+), 45 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 1533bc64ba..0983f5b644 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -9,6 +9,7 @@ using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using Stride.Shaders.Parsing.SDFX.AST; namespace Stride.Shaders.Compilers.SDSL; @@ -44,6 +45,17 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf ShaderLoader.RegisterShader(shader.Name, merged); } + else if (declaration is ShaderEffect effect) + { + var compiler = new CompilerUnit(); + effect.Compile(compiler); + + var merged = compiler.ToBuffer(); + var dis = Spv.Dis(merged, true); + lastBuffer = merged; + + ShaderLoader.RegisterShader(effect.Name, merged); + } else { throw new NotImplementedException($"Compiling declaration [{declaration.GetType()}] is not implemented"); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index bea6f42b37..9089baf0cb 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -31,8 +31,10 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var context = new SpirvContext(); var table = new SymbolTable(); + var shaderSource = EvaluateEffects(new ShaderClassSource { ClassName = entryShaderName }); + // Root shader - MergeSDSLMixin(context, table, temp, entryShaderName); + MergeSDSLMixin(context, table, temp, shaderSource); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); @@ -71,6 +73,92 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //File.WriteAllText("test.spvdis", source); } + private void Merge(ShaderMixinSource mixinTree, ShaderSource source) + { + switch (source) + { + case ShaderClassSource classSource: + mixinTree.Mixins.Add(classSource); + break; + case ShaderMixinSource mixinSource: + foreach (var mixin in mixinSource.Mixins) + { + mixinTree.Mixins.Add(mixin); + } + + foreach (var composition in mixinSource.Compositions) + { + if (mixinTree.Compositions.TryGetValue(composition.Key, out var mixinTreeComposition)) + mixinTree.Compositions.Add(composition.Key, mixinTreeComposition = new ShaderMixinSource()); + Merge(mixinTreeComposition, composition.Value); + } + + break; + } + } + + private ShaderSource EvaluateEffects(ShaderSource source) + { + switch (source) + { + case ShaderClassSource classSource: + if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) + throw new NotImplementedException(); + + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); + if (buffer[0].Op == Op.OpSDSLEffect) + { + var mixinTree = new ShaderMixinSource(); + foreach (var instruction in buffer) + { + if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) + { + var instSource = new ShaderClassSource { ClassName = mixinInstruction.Mixin }; + var evaluatedSource = EvaluateEffects(instSource); + + Merge(mixinTree, evaluatedSource); + } + else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) + { + var instSource = new ShaderClassSource { ClassName = mixinComposeInstruction.Mixin }; + var evaluatedSource = EvaluateEffects(instSource); + + MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); + } + } + + return mixinTree; + } + + return classSource; + case ShaderMixinSource mixinSource: + var result = new ShaderMixinSource(); + foreach (var mixin in mixinSource.Mixins) + { + var evaluatedMixin = EvaluateEffects(mixin); + Merge(result, evaluatedMixin); + } + + foreach (var composition in mixinSource.Compositions) + { + var evaluatedMixin = EvaluateEffects(composition.Value); + MergeComposition(result, composition.Key, evaluatedMixin); + } + + return result; + default: + throw new NotImplementedException(); + } + } + + private void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) + { + if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) + mixinTree.Compositions.Add(compositionName, composition = new()); + + Merge(composition, evaluatedSource); + } + class MethodGroup { public string Name; @@ -89,22 +177,40 @@ class MixinResult public Dictionary Compositions { get; } = new(); } - MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuffer temp, string entryShaderName) + MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderSource entryShaderName) { var mixinResult = new MixinResult(); // TODO: support proper shader mixin source //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, entryShaderName); - // Step: expand "for" // TODO + var mixinsToMerge = new List(); + if (entryShaderName is ShaderClassSource classSource) + { + mixinsToMerge.Add(classSource); + } + else if (entryShaderName is ShaderMixinSource mixinSource) + { + foreach (var mixin in mixinSource.Mixins) + { + mixinsToMerge.Add(mixin); + } + } // Step: build mixins: top level and (TODO) compose var inheritanceList = new List(); - SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); - inheritanceList.Add(entryShaderName); + foreach (var mixinToMerge in mixinsToMerge) + { + if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) + throw new NotImplementedException(); + + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); + SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); + if (!inheritanceList.Contains(mixinToMerge.ClassName)) + inheritanceList.Add(mixinToMerge.ClassName); + } var offset = context.Bound; var nextOffset = 0; @@ -244,15 +350,14 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff { if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol) { - - MixinResult compositionResult; - if (variable.Key == "Comp0") - compositionResult = MergeSDSLMixin(context, table, temp, "CompositionShaderA"); - else if (variable.Key == "Comp1") - compositionResult = MergeSDSLMixin(context, table, temp, "CompositionShaderB"); - else + if (entryShaderName is not ShaderMixinSource mixinSource || !mixinSource.Compositions.TryGetValue(variable.Key, out var compositionMixin)) + { + compositionMixin = new ShaderMixinSource { Mixins = { } }; throw new NotImplementedException(); + } + var compositionResult = MergeSDSLMixin(context, table, temp, compositionMixin); + mixinResult.Compositions.Add(variable.Value.Id, compositionResult); } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs new file mode 100644 index 0000000000..b7ebf273a5 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs @@ -0,0 +1,86 @@ +using System.Text; + +namespace Stride.Shaders.Compilers.SDSL; + +public abstract class ShaderSource +{ + +} + +public sealed class ShaderClassSource : ShaderSource +{ + /// + /// Gets the name of the class. + /// + /// The name of the class. + public string ClassName { get; set; } + + /// + /// Gets the generic parameters. + /// + /// The generic parameters. + public string[] GenericArguments { get; set; } + + public string ToClassName() + { + if (GenericArguments == null) + return ClassName; + + var result = new StringBuilder(); + result.Append(ClassName); + if (GenericArguments != null && GenericArguments.Length > 0) + { + result.Append('<'); + result.Append(string.Join(",", GenericArguments)); + result.Append('>'); + } + + return result.ToString(); + } + + public override string ToString() + { + return ToClassName(); + } +} + +public sealed class ShaderMixinSource : ShaderSource +{ + public List Mixins { get; } = new(); + + public Dictionary Compositions { get; } = new(); + + public override string ToString() + { + var result = new StringBuilder(); + + result.Append("mixin"); + + if (Mixins != null && Mixins.Count > 0) + { + result.Append(" "); + for (int i = 0; i < Mixins.Count; i++) + { + if (i > 0) + result.Append(", "); + result.Append(Mixins[i]); + } + } + + if (Compositions != null && Compositions.Count > 0) + { + result.Append(" ["); + var keys = Compositions.Keys.ToList(); + keys.Sort(); + for (int i = 0; i < keys.Count; i++) + { + var key = keys[i]; + if (i > 0) + result.Append(", "); + result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]); + } + result.Append("]"); + } + return result.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index df2329d1b9..1c10789788 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -240,28 +240,4 @@ public static void CompileSDSL() // Console.WriteLine(code.Translate(Backend.Hlsl)); } - - public abstract class ShaderSource - { - } - - public struct ShaderMacro - { - public string Name; - public string Definition; - } - - public class ShaderMixinSource : ShaderSource - { - public List Mixins { get; } = []; - - public SortedList Compositions { get; } = []; - - public List Macros { get; } = []; - } - - public sealed class ShaderClassCode(string className) : ShaderSource - { - public string ClassName { get; } = className; - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 1cf4e6807a..c03c713a1a 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -14,6 +14,20 @@ "opname": "OpSDSLShaderEnd", "class": "Miscellaneous" }, + { + "opname": "OpSDSLEffect", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "effectName" + } + ] + }, + { + "opname": "OpSDSLEffectEnd", + "class": "Miscellaneous" + }, { "opname": "OpSDSLMixinInherit", "class": "Miscellaneous", @@ -61,8 +75,8 @@ }, { "kind": "ImportType", - "name": "type" - } + "name": "type" + } ] }, { @@ -124,6 +138,30 @@ { "opname": "OpSDSLCallBase", "class": "Miscellaneous" + }, + { + "opname": "OpSDSLMixin", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixin" + } + ] + }, + { + "opname": "OpSDSLMixinCompose", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "identifier" + }, + { + "kind": "LiteralString", + "name": "mixin" + } + ] } ], "operand_kinds": [ diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 983e9cc692..67f6643374 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -2,6 +2,7 @@ using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Silk.NET.OpenGL; +using Silk.NET.SPIRV; using Silk.NET.SPIRV.Cross; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; @@ -16,8 +17,8 @@ using System.Globalization; using System.IO; using System.Runtime.InteropServices; +using System.Text; using System.Text.RegularExpressions; -using Silk.NET.SPIRV; namespace Stride.Shaders.Parsing.Tests; diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs index b51c1d9395..26bae8b66c 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs @@ -1,8 +1,15 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectFlow(TextLocation info) : EffectStatement(info); +public class EffectFlow(TextLocation info) : EffectStatement(info) +{ + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} public class EffectControl(If first, TextLocation info) : EffectFlow(info) { diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 245892842b..ffa1540b8d 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -1,6 +1,8 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDFX.AST; @@ -15,16 +17,36 @@ public override string ToString() { return string.Join("", Members.Select(x => $"{x}\n")); } -} -public abstract class EffectStatement(TextLocation info) : Node(info); + public void Compile(CompilerUnit compiler) + { + compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); + + foreach (var statement in Members) + { + statement.Compile(compiler); + } + compiler.Builder.Insert(new OpSDSLEffectEnd()); + } +} + +public abstract class EffectStatement(TextLocation info) : Node(info) +{ + public abstract void Compile(CompilerUnit compiler); +} public class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) { public Identifier Name { get; set; } = name; public Expression? Value { get; set; } = value; public bool IsCollection => Name.Name.Contains("Collection"); + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() { return $"ShaderSourceCollection {Name} = {Value}"; @@ -35,6 +57,11 @@ public class EffectStatementBlock(TextLocation info) : EffectStatement(info) { public List Statements { get; set; } = []; + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() { return string.Join("\n", Statements); @@ -44,6 +71,18 @@ public override string ToString() public class MixinUse(List mixin, TextLocation info) : EffectStatement(info) { public List MixinName { get; set; } = mixin; + + public override void Compile(CompilerUnit compiler) + { + foreach (var mixinName in MixinName) + { + if (mixinName.Generics != null || mixinName.Path.Count > 0) + throw new NotImplementedException(); + + compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name)); + } + } + public override string ToString() { return $"mixin {MixinName}"; @@ -52,6 +91,12 @@ public override string ToString() public class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() { return $"mixin child {MixinName}"; @@ -61,6 +106,12 @@ public override string ToString() public class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() { return $"mixin clone {MixinName}"; @@ -70,16 +121,31 @@ public override string ToString() public class MixinConst(string identifier, TextLocation info) : EffectStatement(info) { public string Identifier { get; set; } = identifier; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + } public abstract class Composable(); -public abstract class ComposeValue(TextLocation info) : Node(info); +public abstract class ComposeValue(TextLocation info) : Node(info) +{ + public abstract void Compile(CompilerUnit compiler, Identifier identifier); +} public class ComposePathValue(string path, TextLocation info) : ComposeValue(info) { public string Path { get; set; } = path; + + public override void Compile(CompilerUnit compiler, Identifier identifier) + { + throw new NotImplementedException(); + } + public override string ToString() { return Path.ToString(); @@ -88,6 +154,17 @@ public override string ToString() public class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(info) { public Mixin Mixin { get; set; } = mixin; + + public override void Compile(CompilerUnit compiler, Identifier identifier) + { + if (Mixin.Generics != null || Mixin.Path.Count > 0) + throw new NotImplementedException(); + + + compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name)); + } + + public override string ToString() { return Mixin.ToString(); @@ -100,6 +177,12 @@ public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue AssignOperator Operator { get; set; } = op; public ComposeValue ComposeValue { get; set; } = value; + public override void Compile(CompilerUnit compiler) + { + ComposeValue.Compile(compiler, Identifier); + } + + public override string ToString() { return $"mixin compose {Identifier} = {ComposeValue}"; @@ -109,6 +192,12 @@ public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocat { public Identifier Identifier { get; set; } = identifier; public Identifier Source { get; set; } = source; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() { return $"mixin compose {Identifier} += {Source}"; @@ -118,11 +207,23 @@ public override string ToString() public class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + } public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { public Identifier ParamsName { get; set; } = name; + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() { return $"using params {ParamsName}"; @@ -132,14 +233,31 @@ public override string ToString() public class EffectBlock(TextLocation info) : EffectStatement(info) { public List Statements { get; set; } = []; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } + } public class EffectExpressionStatement(Statement statement, TextLocation info) : EffectStatement(info) { public Statement Statement { get; set; } = statement; + + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } } -public class EffectDiscardStatement(TextLocation info) : EffectStatement(info); +public class EffectDiscardStatement(TextLocation info) : EffectStatement(info) +{ + public override void Compile(CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} From cd35c97a3d4291e51ed208a2563c766b9dd6c26b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 10 Oct 2025 12:10:11 +0900 Subject: [PATCH 0491/1182] Use default base class implementation if composition details are not specified --- assets/SDSL/RenderTests/CompositionTest1.sdsl | 10 ++++++---- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 5 ++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionTest1.sdsl b/assets/SDSL/RenderTests/CompositionTest1.sdsl index 371aa3f21f..ecb36503e4 100644 --- a/assets/SDSL/RenderTests/CompositionTest1.sdsl +++ b/assets/SDSL/RenderTests/CompositionTest1.sdsl @@ -6,7 +6,7 @@ shader CompositionBase { float4 Compute() { - return float4(0.0, 0.0, 0.0, 0.0); + return float4(0.1, 0.1, 0.1, 0.1); } }; @@ -14,7 +14,7 @@ shader CompositionShaderA : CompositionBase { override float4 Compute() { - return float4(0.3, 0.3, 0.3, 0.3); + return float4(0.2, 0.2, 0.2, 0.2); } }; @@ -22,7 +22,7 @@ shader CompositionShaderB : CompositionBase { override float4 Compute() { - return float4(0.2, 0.2, 0.2, 0.2); + return base.Compute() + float4(0.1, 0.1, 0.1, 0.1); } }; @@ -32,10 +32,11 @@ shader CompositionTest CompositionBase Comp0; CompositionBase Comp1; + CompositionBase Comp2; void PSMain() { - streams.ColorTarget = Comp0.Compute() + Comp1.Compute(); + streams.ColorTarget = Comp0.Compute() + Comp1.Compute() + Comp2.Compute(); } }; @@ -44,4 +45,5 @@ effect CompositionTest1 mixin CompositionTest; mixin compose Comp0 = CompositionShaderA; mixin compose Comp1 = CompositionShaderB; + // Comp2 will have default value } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9089baf0cb..5e34643af7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -348,12 +348,11 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff { foreach (var variable in shader.Variables) { - if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol) + if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) { if (entryShaderName is not ShaderMixinSource mixinSource || !mixinSource.Compositions.TryGetValue(variable.Key, out var compositionMixin)) { - compositionMixin = new ShaderMixinSource { Mixins = { } }; - throw new NotImplementedException(); + compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource { ClassName = shaderSymbol.Name } } }; } var compositionResult = MergeSDSLMixin(context, table, temp, compositionMixin); From 67025ae5bd713675b6ca07758140111e797d5831 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Oct 2025 12:18:34 +0900 Subject: [PATCH 0492/1182] Process inheritance and compositions in a first pass --- .../SDSL/ShaderMixer.cs | 149 ++++++++++++------ .../Extensions/spirv.sdsl.grammar-ext.json | 14 +- src/Stride.Shaders.Tests/RenderingTests.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 21 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Parsing}/SDSL/ShaderSource.cs | 40 ++++- .../Spirv/Building/Builder.Class.cs | 24 +-- 7 files changed, 173 insertions(+), 81 deletions(-) rename src/{Stride.Shaders.Compilers => Stride.Shaders/Parsing}/SDSL/ShaderSource.cs (60%) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5e34643af7..1c6d1d38bf 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -13,6 +13,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; +using Stride.Shaders.Parsing.SDSL; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Compilers.SDSL; @@ -31,10 +32,12 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var context = new SpirvContext(); var table = new SymbolTable(); - var shaderSource = EvaluateEffects(new ShaderClassSource { ClassName = entryShaderName }); + var shaderSource = EvaluateEffects(new ShaderClassSource(entryShaderName)); + + var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); // Root shader - MergeSDSLMixin(context, table, temp, shaderSource); + MergeSDSLMixin(new MixinResultGlobal(), null, context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); @@ -113,14 +116,14 @@ private ShaderSource EvaluateEffects(ShaderSource source) { if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) { - var instSource = new ShaderClassSource { ClassName = mixinInstruction.Mixin }; + var instSource = new ShaderClassSource(mixinInstruction.Mixin); var evaluatedSource = EvaluateEffects(instSource); Merge(mixinTree, evaluatedSource); } else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) { - var instSource = new ShaderClassSource { ClassName = mixinComposeInstruction.Mixin }; + var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin); var evaluatedSource = EvaluateEffects(instSource); MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); @@ -167,9 +170,17 @@ class MethodGroup public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); } + class MixinResultGlobal + { + public Dictionary Names { get; } = new(); + public Dictionary Types { get; } = new(); + } - class MixinResult + + class MixinResult(MixinResult? parent) { + public MixinResult? Parent { get; } = parent; + public Dictionary MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); @@ -177,41 +188,71 @@ class MixinResult public Dictionary Compositions { get; } = new(); } - MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderSource entryShaderName) + private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource) { - var mixinResult = new MixinResult(); + var mixinsToMerge = new List(); - // TODO: support proper shader mixin source - //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; + var inheritanceList = new List(); - // Step: expand "for" - // TODO - var mixinsToMerge = new List(); - if (entryShaderName is ShaderClassSource classSource) - { - mixinsToMerge.Add(classSource); - } - else if (entryShaderName is ShaderMixinSource mixinSource) + var shaderMixinSource = shaderSource switch { - foreach (var mixin in mixinSource.Mixins) - { - mixinsToMerge.Add(mixin); - } - } + ShaderMixinSource mixinSource2 => mixinSource2, + ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, + }; - // Step: build mixins: top level and (TODO) compose - var inheritanceList = new List(); - foreach (var mixinToMerge in mixinsToMerge) + foreach (var mixinToMerge in shaderMixinSource.Mixins) { if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) throw new NotImplementedException(); var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); - if (!inheritanceList.Contains(mixinToMerge.ClassName)) - inheritanceList.Add(mixinToMerge.ClassName); + if (!inheritanceList.Contains(mixinToMerge)) + inheritanceList.Add(mixinToMerge); } + shaderMixinSource.Mixins.Clear(); + shaderMixinSource.Mixins.AddRange(inheritanceList); + + foreach (var shaderName in shaderMixinSource.Mixins) + { + var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName.ClassName); + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + + foreach (var i in shader) + { + if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + { + var variableType = types[variable.ResultType]; + if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + { + var variableName = names[variable.ResultId]; + // Make sure we have a ShaderMixinSource + // If composition is not specified, use default class + if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) + { + compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; + } + compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin); + shaderMixinSource.Compositions[variableName] = compositionMixin; + } + } + } + } + + return shaderMixinSource; + } + + MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderMixinSource mixinSource) + { + var mixinResult = new MixinResult(parent); + + // TODO: support proper shader mixin source + //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; + + // Step: expand "for" + // TODO + var offset = context.Bound; var nextOffset = 0; @@ -219,9 +260,9 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff var shadersByName = new Dictionary(); var mixinStart = temp.Count; - foreach (var shaderName in inheritanceList) + foreach (var shaderClass in mixinSource.Mixins) { - var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName); + var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderClass.ClassName); offset += nextOffset; nextOffset = 0; shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; @@ -232,8 +273,6 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff foreach (var i in shader) { var i2 = new OpData(i.Data.Memory.Span); - - // Ignore mixin inherit (already computed with inheritance list) temp.Add(i2); if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) @@ -245,7 +284,7 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff var shaderInfo = new ShaderInfo(shaders.Count); PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo); - shadersByName.Add(shaderName, shaderInfo); + shadersByName.Add(shaderClass.ClassName, shaderInfo); shaders.Add(shaderInfo); RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, shadersByName); @@ -263,7 +302,9 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff context.Bound = offset + nextOffset + 1; //Spv.Dis(temp, true); - ShaderClass.ProcessNameAndTypes(temp, 0, temp.Count, out var names2, out var types); + var names = global.Names; + var types = global.Types; + ShaderClass.ProcessNameAndTypes(temp, mixinStart, mixinEnd, names, types); // Add symbol for each method in current type (equivalent to implicit this pointer) for (var index = mixinStart; index < mixinEnd; index++) @@ -271,7 +312,7 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff var i = temp[index]; if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - var functionName = names2[function.ResultId]; + var functionName = names[function.ResultId]; var symbol = new Symbol(new(functionName, SymbolKind.Method), types[function.FunctionType], function.ResultId); table.CurrentFrame.Add(functionName, symbol); } @@ -307,22 +348,29 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { - var functionName = names2[function.ResultId]; + var functionName = names[function.ResultId]; + + // If it's a stage method, register at the root level + var methodMixinResult = mixinResult; + if ((functionInfo.Flags & FunctionFlagsMask.Stage) != 0) + { + while (methodMixinResult.Parent != null) + methodMixinResult = methodMixinResult.Parent; + } // Check if it has a parent (and if yes, share the MethodGroup) - if (!mixinResult.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) + if (!methodMixinResult.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) methodGroup = new MethodGroup { Name = functionName }; methodGroup.Shader = currentShader; methodGroup.MethodIndexInGroup = methodGroup.Methods.Count; methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); - mixinResult.MethodGroups[function.ResultId] = methodGroup; + methodMixinResult.MethodGroups[function.ResultId] = methodGroup; // Also add lookup by name - if (!mixinResult.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) - mixinResult.MethodGroupsByName.Add(functionName, function.ResultId); - + if (!methodMixinResult.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) + methodMixinResult.MethodGroupsByName.Add(functionName, function.ResultId); // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) @@ -350,12 +398,8 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff { if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) { - if (entryShaderName is not ShaderMixinSource mixinSource || !mixinSource.Compositions.TryGetValue(variable.Key, out var compositionMixin)) - { - compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource { ClassName = shaderSymbol.Name } } }; - } - - var compositionResult = MergeSDSLMixin(context, table, temp, compositionMixin); + var compositionMixin = mixinSource.Compositions[variable.Key]; + var compositionResult = MergeSDSLMixin(global, mixinResult, context, table, temp, compositionMixin); mixinResult.Compositions.Add(variable.Value.Id, compositionResult); } @@ -398,12 +442,19 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { if (!mixinResult.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {names2[function.ResultId]}"); + throw new InvalidOperationException($"Can't find method group info for {names[function.ResultId]}"); currentShader = methodGroupEntry.Shader; } else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) { + /*var methodMixinResult = mixinResult; + if ((functionInfo.Flags & FunctionFlagsMask.Stage) != 0) + { + while (methodMixinResult.Parent != null) + methodMixinResult = methodMixinResult.Parent; + }*/ + var methodGroups = mixinResult.MethodGroups; // Process member call (composition) @@ -424,7 +475,7 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff } if (!methodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {names2[functionCall.Function]}"); + throw new InvalidOperationException($"Can't find method group info for {names[functionCall.Function]}"); // Process base call if (temp[index - 1].Op == Op.OpSDSLCallBase) @@ -443,7 +494,7 @@ MixinResult MergeSDSLMixin(SpirvContext context, SymbolTable table, NewSpirvBuff } if (!baseMethodFound) - throw new InvalidOperationException($"Can't find a base method for {names2[functionCall.Function]}"); + throw new InvalidOperationException($"Can't find a base method for {names[functionCall.Function]}"); SetOpNop(temp[index - 1].Data.Memory.Span); } diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index c03c713a1a..62ba72cf8e 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -174,20 +174,20 @@ "value": "0x0000" }, { - "enumerant": "Abstract", + "enumerant": "Stage", "value": "0x0001" }, { - "enumerant": "Virtual", - "value": "0x0002" + "enumerant": "Abstract", + "value": "0x0010" }, { - "enumerant": "Override", - "value": "0x0004" + "enumerant": "Virtual", + "value": "0x0020" }, { - "enumerant": "Static", - "value": "0x0010" + "enumerant": "Override", + "value": "0x0040" } ] }, diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 67f6643374..aa35fd1b44 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -85,7 +85,7 @@ public void RenderTest1(string shaderName, string methodName, string args) // Check output color value against expected result var expectedColor = StringToRgba(parameters["ExpectedResult"]); var pixel = pixels[0, 0].PackedValue; - Assert.Equal(expectedColor, pixel); + Assert.Equal(expectedColor.ToString("X8"), pixel.ToString("X8")); } public static IEnumerable GetTestFiles() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index eac1c4a845..5bcabc1018 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -25,11 +25,18 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) - public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) + + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) { - var memberNames = new Dictionary<(int, int), string>(); names = []; types = []; + + ProcessNameAndTypes(buffer, start, end, names, types); + } + + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types) + { + var memberNames = new Dictionary<(int, int), string>(); for (var i = start; i < end; i++) { var instruction = buffer[i]; @@ -127,8 +134,6 @@ public static Dictionary ProcessNameAndTypes(NewSpirvBuffer buf } } } - - return types; } private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string className) @@ -175,15 +180,15 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Push(); - var inheritanceList = new List(); + var inheritanceList = new List(); foreach (var mixin in Mixins) { - SpirvBuilder.BuildInheritanceList(table.ShaderLoader, mixin.Name, inheritanceList); + SpirvBuilder.BuildInheritanceList(table.ShaderLoader, new ShaderClassSource(mixin.Name), inheritanceList); } foreach (var mixin in inheritanceList) { - LoadExternalShaderType(table, mixin); + LoadExternalShaderType(table, mixin.ClassName); } var symbols = new List(); @@ -237,7 +242,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) foreach (var mixin in inheritanceList) { - var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin]; + var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.ClassName]; // Import types and variables/functions context.FluentAdd(new OpSDSLImportShader(context.Bound, new(shaderType.Name), ImportType.Inherit), out var shader); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index da0649c8de..9948fec953 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -221,8 +221,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler functionInfo.Flags |= Specification.FunctionFlagsMask.Abstract; if (IsVirtual == true) functionInfo.Flags |= Specification.FunctionFlagsMask.Virtual; - if (IsStatic) - functionInfo.Flags |= Specification.FunctionFlagsMask.Static; + if (IsStaged) + functionInfo.Flags |= Specification.FunctionFlagsMask.Stage; builder.Insert(functionInfo); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs similarity index 60% rename from src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs rename to src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs index b7ebf273a5..1a6f405d05 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderSource.cs +++ b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs @@ -1,25 +1,25 @@ using System.Text; -namespace Stride.Shaders.Compilers.SDSL; +namespace Stride.Shaders.Parsing.SDSL; public abstract class ShaderSource { } -public sealed class ShaderClassSource : ShaderSource +public sealed class ShaderClassSource(string className) : ShaderSource, IEquatable { /// /// Gets the name of the class. /// /// The name of the class. - public string ClassName { get; set; } + public string ClassName { get; set; } = className; /// /// Gets the generic parameters. /// /// The generic parameters. - public string[] GenericArguments { get; set; } + public string[] GenericArguments { get; set; } = []; public string ToClassName() { @@ -38,6 +38,38 @@ public string ToClassName() return result.ToString(); } + public bool Equals(ShaderClassSource shaderClassSource) + { + if (ReferenceEquals(null, shaderClassSource)) return false; + if (ReferenceEquals(this, shaderClassSource)) return true; + return + string.Equals(ClassName, shaderClassSource.ClassName) && + GenericArguments.SequenceEqual(shaderClassSource.GenericArguments); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((ShaderClassSource)obj); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = ClassName?.GetHashCode() ?? 0; + if (GenericArguments != null) + { + foreach (var current in GenericArguments) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + + return hashCode; + } + } + public override string ToString() { return ToClassName(); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index da4a20f7ce..ae3db1447a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -4,19 +4,20 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Core; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { - public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, NewSpirvBuffer buffer, List inheritanceList) + public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, NewSpirvBuffer buffer, List inheritanceList) { // Build shader name mapping - var shaderMapping = new Dictionary(); + var shaderMapping = new Dictionary(); foreach (var i in buffer) if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) - shaderMapping[importShader.ResultId] = importShader.ShaderName; + shaderMapping[importShader.ResultId] = new ShaderClassSource(importShader.ShaderName); // Check inheritance foreach (var i in buffer) @@ -29,20 +30,23 @@ public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, NewS } } - public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, string shaderName, List inheritanceList) + public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassSource classSource, List inheritanceList) { - if (!inheritanceList.Contains(shaderName)) + if (!inheritanceList.Contains(classSource)) { - var shader = GetOrLoadShader(shaderLoader, shaderName); + if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) + throw new NotImplementedException(); + + var shader = GetOrLoadShader(shaderLoader, classSource.ClassName); BuildInheritanceList(shaderLoader, shader, inheritanceList); - inheritanceList.Add(shaderName); + inheritanceList.Add(classSource); } } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string name) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) { - if (!shaderLoader.LoadExternalBuffer(name, out var buffer)) - throw new InvalidOperationException($"Could not load shader [{name}]"); + if (!shaderLoader.LoadExternalBuffer(className, out var buffer)) + throw new InvalidOperationException($"Could not load shader [{className}]"); return buffer; } From 289c2f434108a8f7f9394df13bc7b33e16aff99f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Oct 2025 09:46:18 +0900 Subject: [PATCH 0493/1182] First implementation of "stage" methods --- .../RenderTests/CompositionTestStage1.sdsl | 82 ++++++ .../RenderTests/CompositionTestStage2.sdsl | 67 +++++ src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 +- .../SDSL/ShaderMixer.cs | 238 ++++++++++++++---- src/Stride.Shaders.Experiments/Program.cs | 2 +- .../Extensions/spirv.sdsl.grammar-ext.json | 4 + src/Stride.Shaders/Core/Symbol.cs | 3 +- src/Stride.Shaders/Core/SymbolFrame.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 22 +- .../ShaderParsers/ShaderMethodParsers.cs | 3 +- .../Parsing/SDSL/ShaderSource.cs | 6 +- .../Spirv/Building/BasicBlocks.cs | Bin 5182 -> 5260 bytes .../Spirv/Building/Builder.Functions.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- .../Spirv/Processing/StreamAnalyzer.cs | 10 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 57 ++++- 17 files changed, 436 insertions(+), 86 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionTestStage1.sdsl create mode 100644 assets/SDSL/RenderTests/CompositionTestStage2.sdsl diff --git a/assets/SDSL/RenderTests/CompositionTestStage1.sdsl b/assets/SDSL/RenderTests/CompositionTestStage1.sdsl new file mode 100644 index 0000000000..2dc1d6fe8a --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionTestStage1.sdsl @@ -0,0 +1,82 @@ +// PSMain(ExpectedResult=#BF407FFF) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + stage float BaseStageMethod1() + { + return 0.125; + } + + stage float BaseStageMethod2() + { + return 0.125; + } + + stage float BaseStageMethod3() + { + return 0.125; + } + + stage float BaseStageMethod4() + { + return 0.25; + } +}; + +shader CompositionShaderA : CompositionBase +{ + stage override float BaseStageMethod2() + { + return base.BaseStageMethod2() + 0.125; + } + + stage override float BaseStageMethod4() + { + return base.BaseStageMethod4() + 0.25; + } +}; + +shader CompositionShaderB : CompositionBase +{ + stage override float BaseStageMethod3() + { + return base.BaseStageMethod3() + 0.375; + } + + stage override float BaseStageMethod4() + { + return base.BaseStageMethod4() + 0.25; + } +}; + +shader CompositionTest : CompositionBase +{ + stream float4 ColorTarget : SV_Target0; + + CompositionBase Comp0; + CompositionBase Comp1; + + stage override float BaseStageMethod1() + { + return base.BaseStageMethod1() + 0.625; + } + + stage override float BaseStageMethod4() + { + return base.BaseStageMethod4() + 0.25; + } + + void PSMain() + { + streams.ColorTarget = float4(BaseStageMethod1(), BaseStageMethod2(), BaseStageMethod3(), BaseStageMethod4()); + } +}; + +effect CompositionTestStage1 +{ + mixin CompositionTest; + mixin compose Comp0 = CompositionShaderA; + mixin compose Comp1 = CompositionShaderB; +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/CompositionTestStage2.sdsl b/assets/SDSL/RenderTests/CompositionTestStage2.sdsl new file mode 100644 index 0000000000..7cfedeca57 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionTestStage2.sdsl @@ -0,0 +1,67 @@ +// PSMain(ExpectedResult=#BFBFFFFF) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + stage float BaseStageMethod1() + { + return 0.25; + } + + float ComputeBase() + { + return 0.1; + } + + float ComputeThis() + { + return 0.1; + } +}; + +shader CompositionShaderA : CompositionBase +{ + stage override float BaseStageMethod1() + { + return base.BaseStageMethod1() + 0.25; + } + + override float ComputeThis() + { + return this.BaseStageMethod1(); + } +}; + +shader CompositionShaderB : CompositionBase +{ + stage override float BaseStageMethod1() + { + return base.BaseStageMethod1() + 0.25; + } + + override float ComputeThis() + { + return this.BaseStageMethod1(); + } +}; + +shader CompositionTest +{ + stream float4 ColorTarget : SV_Target0; + + CompositionBase Comp0; + CompositionBase Comp1; + + void PSMain() + { + streams.ColorTarget = float4(Comp0.ComputeThis(), Comp1.ComputeThis(), 1.0, 1.0); + } +}; + +effect CompositionTestStage2 +{ + mixin CompositionTest; + mixin compose Comp0 = CompositionShaderA; + mixin compose Comp1 = CompositionShaderB; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 0983f5b644..eb1925b43e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -40,7 +40,7 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf throw new Exception("Some parse errors"); var merged = compiler.ToBuffer(); - var dis = Spv.Dis(merged, true); + var dis = Spv.Dis(merged); lastBuffer = merged; ShaderLoader.RegisterShader(shader.Name, merged); @@ -51,7 +51,7 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf effect.Compile(compiler); var merged = compiler.ToBuffer(); - var dis = Spv.Dis(merged, true); + var dis = Spv.Dis(merged); lastBuffer = merged; ShaderLoader.RegisterShader(effect.Name, merged); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 1c6d1d38bf..19edd89a3e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -37,7 +37,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); // Root shader - MergeSDSLMixin(new MixinResultGlobal(), null, context, table, temp, shaderSource2); + MergeSDSLMixin(new MixinResultGlobal(), context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); @@ -46,11 +46,15 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) { for (int i = 0; i < temp.Count; i++) { + // Remove Nop if (temp[i].Op == Op.OpNop) temp.RemoveAt(i--); + // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) + else if (temp[i].Op == Op.OpSDSLShader || temp[i].Op == Op.OpSDSLShaderEnd || temp[i].Op == Op.OpSDSLEffect || temp[i].Op == Op.OpSDSLEffectEnd) + temp.RemoveAt(i--); } temp.Sort(); - Spv.Dis(temp, true); + Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); } new StreamAnalyzer().Process(table, temp, context); @@ -72,7 +76,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //File.WriteAllBytes("test.spv", bytecode); - Spv.Dis(temp, true); + Spv.Dis(temp); //File.WriteAllText("test.spvdis", source); } @@ -168,6 +172,8 @@ class MethodGroup public int MethodIndexInGroup; public ShaderInfo Shader; public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); + + public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; } class MixinResultGlobal @@ -177,9 +183,12 @@ class MixinResultGlobal } - class MixinResult(MixinResult? parent) + class MixinResult(MixinResult? stage) { - public MixinResult? Parent { get; } = parent; + public MixinResult? Stage { get; } = stage; + + public List Shaders { get; } = new(); + public Dictionary ShadersByName { get; } = new(); public Dictionary MethodGroupsByName { get; } = new(); @@ -188,37 +197,36 @@ class MixinResult(MixinResult? parent) public Dictionary Compositions { get; } = new(); } - private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource) + private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinSource? root = null) { - var mixinsToMerge = new List(); - - var inheritanceList = new List(); + bool isRoot = root == null; + var mixinList = new List(); var shaderMixinSource = shaderSource switch { ShaderMixinSource mixinSource2 => mixinSource2, ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, }; - foreach (var mixinToMerge in shaderMixinSource.Mixins) { if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) throw new NotImplementedException(); var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); - SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, inheritanceList); - if (!inheritanceList.Contains(mixinToMerge)) - inheritanceList.Add(mixinToMerge); + SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList); + if (!mixinList.Contains(mixinToMerge)) + mixinList.Add(mixinToMerge); } shaderMixinSource.Mixins.Clear(); - shaderMixinSource.Mixins.AddRange(inheritanceList); + shaderMixinSource.Mixins.AddRange(mixinList); - foreach (var shaderName in shaderMixinSource.Mixins) + foreach (var shaderName in mixinList) { var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName.ClassName); ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + bool hasStage = false; foreach (var i in shader) { if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) @@ -233,19 +241,39 @@ private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shader { compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; } - compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin); + compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin, root ?? shaderMixinSource); shaderMixinSource.Compositions[variableName] = compositionMixin; } } + + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is {} functionInfo) + { + hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + } + } + + // If there are any stage variables, add class to root + if (!isRoot && hasStage) + { + var shaderNameStageOnly = new ShaderClassSource(shaderName.ClassName) { GenericArguments = shaderName.GenericArguments, ImportStageOnly = true }; + // Make sure it's not already added yet (either standard or stage only) + if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) + root!.Mixins.Add(shaderNameStageOnly); } } return shaderMixinSource; } - MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderMixinSource mixinSource) + MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderMixinSource mixinSource, MixinResult? stage = null, string? currentCompositionPath = null) { - var mixinResult = new MixinResult(parent); + if (currentCompositionPath != null) + temp.Add(new OpSDSLEffect(currentCompositionPath)); + + var isRoot = stage == null; + var mixinResult = new MixinResult(stage); + if (isRoot) + stage = mixinResult; // TODO: support proper shader mixin source //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; @@ -256,8 +284,8 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC var offset = context.Bound; var nextOffset = 0; - var shaders = new List(); - var shadersByName = new Dictionary(); + var shaders = mixinResult.Shaders; + var shadersByName = mixinResult.ShadersByName; var mixinStart = temp.Count; foreach (var shaderClass in mixinSource.Mixins) @@ -269,9 +297,61 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC var shaderStart = temp.Count; + bool skipFunction = false; + // Copy instructions to single buffer - foreach (var i in shader) + for (var index = 0; index < shader.Count; index++) { + var i = shader[index]; + // Do we need to skip variable/functions? (depending on stage/non-stage) + + { + var include = true; + if (i.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + { + var isStage = (importFunction.Flags & FunctionFlagsMask.Stage) != 0; + /*include = isStage switch + { + // Import stage members only if root level + true => isRoot || shaderClass.ImportStageOnly, + // Import non-stage members only if import stage only is not specified + false => !shaderClass.ImportStageOnly, + };*/ + } + if (i.Op == Op.OpFunction && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) + { + var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + include = isStage switch + { + // Import stage members only if root level + true => isRoot || shaderClass.ImportStageOnly, + // Import non-stage members only if import stage only is not specified + false => !shaderClass.ImportStageOnly, + }; + } + if (i.Op == Op.OpVariable) + { + // TODO + } + + + if (!include) + { + // Special case for function: skip until function end + // (for other cases such as variable, skipping only current instruction is enough) + if (i.Op == Op.OpFunction) + { + // Skip until end of function + while (shader[++index].Op != Op.OpFunctionEnd) + { + } + } + + // Go to next instruction + continue; + } + } + var i2 = new OpData(i.Data.Memory.Span); temp.Add(i2); @@ -282,12 +362,18 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC OffsetIds(i2, offset); } - var shaderInfo = new ShaderInfo(shaders.Count); - PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo); + var shaderInfo = new ShaderInfo(shaders.Count, shaderClass.ClassName, shaderStart, temp.Count); + shaderInfo.CompositionPath = currentCompositionPath; + if (mixinResult.Stage != null && mixinResult.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) + shaderInfo.Stage = stageShaderInfo; + + PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo, mixinResult); shadersByName.Add(shaderClass.ClassName, shaderInfo); shaders.Add(shaderInfo); - RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, shadersByName); + Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); + RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, mixinResult); + Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); } var mixinEnd = temp.Count; @@ -336,12 +422,10 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) { currentShader = shadersByName[shaderInstruction.ShaderName]; - SetOpNop(i.Data.Memory.Span); } else if (i.Data.Op == Op.OpSDSLShaderEnd) { currentShader = null; - SetOpNop(i.Data.Memory.Span); } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { @@ -350,27 +434,23 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC { var functionName = names[function.ResultId]; - // If it's a stage method, register at the root level - var methodMixinResult = mixinResult; - if ((functionInfo.Flags & FunctionFlagsMask.Stage) != 0) - { - while (methodMixinResult.Parent != null) - methodMixinResult = methodMixinResult.Parent; - } + var methodMixinGroup = mixinResult; + if (!isRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) + methodMixinGroup = methodMixinGroup.Stage; // Check if it has a parent (and if yes, share the MethodGroup) - if (!methodMixinResult.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) + if (!methodMixinGroup.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) methodGroup = new MethodGroup { Name = functionName }; methodGroup.Shader = currentShader; methodGroup.MethodIndexInGroup = methodGroup.Methods.Count; methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); - methodMixinResult.MethodGroups[function.ResultId] = methodGroup; + methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; // Also add lookup by name - if (!methodMixinResult.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) - methodMixinResult.MethodGroupsByName.Add(functionName, function.ResultId); + if (!methodMixinGroup.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) + methodMixinGroup.MethodGroupsByName.Add(functionName, function.ResultId); // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) @@ -399,7 +479,8 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) { var compositionMixin = mixinSource.Compositions[variable.Key]; - var compositionResult = MergeSDSLMixin(global, mixinResult, context, table, temp, compositionMixin); + var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; + var compositionResult = MergeSDSLMixin(global, context, table, temp, compositionMixin, stage, compositionPath); mixinResult.Compositions.Add(variable.Value.Id, compositionResult); } @@ -444,7 +525,7 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC if (!mixinResult.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) throw new InvalidOperationException($"Can't find method group info for {names[function.ResultId]}"); - currentShader = methodGroupEntry.Shader; + currentShader = shaders.Last(x => index >= x.StartInstruction); } else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) { @@ -455,16 +536,17 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC methodMixinResult = methodMixinResult.Parent; }*/ - var methodGroups = mixinResult.MethodGroups; + var methodMixinGroup = mixinResult; + var isBaseCall = temp[index - 1].Op == Op.OpSDSLCallBase; // Process member call (composition) if (temp[index - 1].Op == Op.OpSDSLCallTarget) { var callTarget = (OpSDSLCallTarget)temp[index - 1]; var composition = mixinResult.Compositions[callTarget.Target]; - methodGroups = composition.MethodGroups; + methodMixinGroup = composition; - Spv.Dis(temp, false); + Spv.Dis(temp, Spv.DisassemblerFlags.Id); var functionName = externalFunctions[functionCall.Function]; var functionId = composition.MethodGroupsByName[functionName]; @@ -474,12 +556,24 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC SetOpNop(temp[index - 1].Data.Memory.Span); } - if (!methodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {names[functionCall.Function]}"); + Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); + + bool foundInStage = false; + if (!methodMixinGroup.MethodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) + { + // Try again as a stage method (only if not a base call) + if (methodMixinGroup.Stage == null || !methodMixinGroup.Stage.MethodGroups.TryGetValue(functionCall.Function, out methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {names[functionCall.Function]}"); + foundInStage = true; + } // Process base call - if (temp[index - 1].Op == Op.OpSDSLCallBase) + if (isBaseCall) { + // We currently do not allow calling base stage method from a non-stage method + if (foundInStage) + throw new InvalidOperationException($"Method {names[functionCall.Function]} was found but a base call can't be performed on a stage method from a non-stage method"); + // Is it a base call? if yes, find the direct parent // Let's find the method in same group just before ours bool baseMethodFound = false; @@ -520,13 +614,15 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, MixinResult? parent, SpirvC } } + if (currentCompositionPath != null) + temp.Add(new OpSDSLEffectEnd()); + return mixinResult; } - private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo) + private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinResult mixinResult) { ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); - for (var index = shaderStart; index < shaderEnd; index++) { var i = temp[index]; @@ -548,7 +644,7 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader } } - private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, Dictionary shadersByName) + private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinResult mixinResult) { var importedShaders = new Dictionary(); var idRemapping = new Dictionary(); @@ -572,7 +668,7 @@ private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderE { if (importShader.Type == ImportType.Inherit) { - importedShaders.Add(importShader.ResultId, shadersByName[importShader.ShaderName]); + importedShaders.Add(importShader.ResultId, mixinResult.ShadersByName[importShader.ShaderName]); SetOpNop(i.Data.Memory.Span); } @@ -592,8 +688,20 @@ private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderE { if (importedShaders.TryGetValue(importFunction.Shader, out var importedShader)) { - var importedFunction = importedShader.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); + if (importedShader.Functions.ContainsKey(importFunction.FunctionName)) + { + var importedFunction = importedShader.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + } + else if (importedShader.Stage != null && importedShader.Stage.Functions.ContainsKey(importFunction.FunctionName)) + { + var importedFunction = importedShader.Stage.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + } + else + { + idRemapping.Add(importFunction.ResultId, 0); + } SetOpNop(i.Data.Memory.Span); } @@ -607,24 +715,50 @@ private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderE || op.Kind == OperandKind.PairIdRefIdRef) && op.Words.Length > 0 && idRemapping.TryGetValue(op.Words[0], out var to1)) + { + if (to1 == 0) + throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[0]} at instruction {index}"); op.Words[0] = to1; + } + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef || op.Kind == OperandKind.PairIdRefIdRef) && idRemapping.TryGetValue(op.Words[1], out var to2)) + { + if (to2 == 0) + throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[1]} at instruction {index}"); op.Words[1] = to2; + } } } } - class ShaderInfo(int shaderIndex) + class ShaderInfo(int shaderIndex, string shaderName, int startInstruction, int endInstruction) { public int ShaderIndex { get; } = shaderIndex; + public string ShaderName { get; } = shaderName; + + /// + /// The for the same shader at the top-level (for all the stage members, if any). + /// + public ShaderInfo? Stage { get; set; } + + /// + /// Kept for debug purpose. + /// + public string? CompositionPath { get; set; } + + public int StartInstruction { get; } = startInstruction; + public int EndInstruction { get; } = endInstruction; + public Dictionary Names { get; } = new(); public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); + + public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } static void SetOpNop(Span words) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index e2a970e7da..e9b3267f41 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -10,7 +10,7 @@ var shaderMixer = new ShaderMixer(new Examples.ShaderLoader()); shaderMixer.MergeSDSL("TestBasic", out var bytecode); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); -var source = Spv.Dis(buffer, true); +var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 62ba72cf8e..9e7c03bc75 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -92,6 +92,10 @@ { "kind": "IdRef", "name": "shader" + }, + { + "kind": "FunctionFlags", + "name": "flags" } ] }, diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 1a435ce685..88164d45a4 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -1,4 +1,5 @@ using System.Collections.Immutable; +using Stride.Shaders.Spirv; namespace Stride.Shaders.Core; @@ -36,7 +37,7 @@ public enum StreamIO : byte Output } -public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0); +public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0, Specification.FunctionFlagsMask FunctionFlags = Specification.FunctionFlagsMask.None); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); /// diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 688d3d3ee5..d9942a8421 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -20,7 +20,7 @@ public void Add(string name, Symbol symbol) { // If there is already a function symbol with same name, let's create or add to a group. if (existingSymbol.Type is FunctionType) - existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); + existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup, FunctionFlags: existingSymbol.Id.FunctionFlags), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 5bcabc1018..e6a46c4422 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -127,7 +127,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end if (types.TryGetValue(importFunction.Shader, out var type) && type is ShaderSymbol shaderSymbol) { var returnType = types[importFunction.ResultType]; - var symbol = new Symbol(new(importFunction.FunctionName, SymbolKind.Method), returnType, importFunction.ResultId); + var symbol = new Symbol(new(importFunction.FunctionName, SymbolKind.Method, FunctionFlags: importFunction.Flags), returnType, importFunction.ResultId); // TODO: review if really necessary? // (external functions are resolved differently) shaderSymbol.Components.Add(symbol); @@ -141,9 +141,11 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string class ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); var symbols = new List(); - foreach (var instruction in buffer) + for (var index = 0; index < buffer.Count; index++) { - if (instruction.Op == Op.OpVariable && (OpVariable)instruction is {} variable && variable.Storageclass != Specification.StorageClass.Function) + var instruction = buffer[index]; + if (instruction.Op == Op.OpVariable && (OpVariable)instruction is { } variable && + variable.Storageclass != Specification.StorageClass.Function) { if (!names.TryGetValue(variable.ResultId, out var variableName)) variableName = $"_{variable.ResultId}"; @@ -155,11 +157,15 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string class if (instruction.Op == Op.OpFunction) { + var functionFlags = FunctionFlagsMask.None; + if (buffer[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)buffer[index + 1] is { } functionInfo) + functionFlags = functionInfo.Flags; + OpFunction functionInstruction = instruction; var functionName = names[functionInstruction.ResultId]; var functionType = types[functionInstruction.FunctionType]; - var sid = new SymbolID(functionName, SymbolKind.Method); + var sid = new SymbolID(functionName, SymbolKind.Method, FunctionFlags: functionFlags); symbols.Add(new(sid, functionType, functionInstruction.ResultId)); } } @@ -264,7 +270,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var functionType = (FunctionType)c.Type; var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound, c.Id.Name, shader.ResultId), out var function); + context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound, c.Id.Name, shader.ResultId, c.Id.FunctionFlags), out var function); context.AddName(context.Bound, c.Id.Name); context.Bound++; table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 9948fec953..911c3d6b4b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -168,11 +168,11 @@ public class ShaderMethod( }; public Identifier? Visibility { get; set; } = visibility; public Identifier? Storage { get; set; } = storage; - public bool? IsAbstract { get; set; } = isAbstract; + public bool IsAbstract { get; set; } = isAbstract; public bool IsStatic { get; set; } = isStatic; - public bool? IsVirtual { get; set; } = isVirtual; - public bool? IsOverride { get; set; } = isOverride; - public bool? IsClone { get; set; } = isClone; + public bool IsVirtual { get; set; } = isVirtual; + public bool IsOverride { get; set; } = isOverride; + public bool IsClone { get; set; } = isClone; public List Parameters { get; set; } = []; public BlockStatement? Body { get; set; } @@ -181,9 +181,19 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var (builder, context) = compiler; - function = builder.DeclareFunction(context, Name, (FunctionType)Type); + function = builder.DeclareFunction(context, Name, (FunctionType)Type, IsStaged); - var symbol = new Symbol(new(Name, SymbolKind.Method), Type, function.Id); + var functionFlags = Specification.FunctionFlagsMask.None; + if (IsAbstract) + functionFlags |= Specification.FunctionFlagsMask.Abstract; + if (IsOverride) + functionFlags |= Specification.FunctionFlagsMask.Override; + if (IsVirtual) + functionFlags |= Specification.FunctionFlagsMask.Virtual; + if (IsStaged) + functionFlags |= Specification.FunctionFlagsMask.Stage; + + var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id); table.CurrentShader.Components.Add(symbol); table.CurrentFrame.Add(Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 48bd9b83dd..88489aa3e5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -161,12 +161,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - else if (isClone || isOverride || isStatic) + else if (isClone || isOverride || isStatic || isStaged) { if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { if (hasAttributes) parsed.Attributes = attributes.Attributes; + parsed.IsStaged = isStaged; parsed.IsClone = isClone; parsed.IsOverride = isOverride; parsed.IsStatic = isStatic; diff --git a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs index 1a6f405d05..537bff5aa6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs +++ b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs @@ -15,6 +15,8 @@ public sealed class ShaderClassSource(string className) : ShaderSource, IEquatab /// The name of the class. public string ClassName { get; set; } = className; + public bool ImportStageOnly { get; set; } = false; + /// /// Gets the generic parameters. /// @@ -23,10 +25,12 @@ public sealed class ShaderClassSource(string className) : ShaderSource, IEquatab public string ToClassName() { - if (GenericArguments == null) + if ((GenericArguments == null || GenericArguments.Length == 0) && !ImportStageOnly) return ClassName; var result = new StringBuilder(); + if (ImportStageOnly) + result.Append("stage "); result.Append(ClassName); if (GenericArguments != null && GenericArguments.Length > 0) { diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index 70678867f1521cb64ac516a7fc19581fb8b572af..d63151ed4f0a8bec40b2b3f514900272e34c63fa 100644 GIT binary patch delta 40 ucmdm|(WAMck5@d2As+~H7!(*h8HyQ#8A=!u8PXY2Cns{4Z|>vWzy<)`Lkh6~ delta 12 TcmeCt+^4ajk9YGO-VJO3BVPqM diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 1aa4d2213c..40cfe31fe9 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -9,13 +9,13 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { - public SpirvFunction DeclareFunction(SpirvContext context, string name, FunctionType ftype) + public SpirvFunction DeclareFunction(SpirvContext context, string name, FunctionType ftype, bool isStage = false) { var func = context.Bound++; foreach (var t in ftype.ParameterTypes) context.GetOrRegister(t); context.AddName(func, name); - var result = new SpirvFunction(func, name, ftype); + var result = new SpirvFunction(func, name, ftype) { IsStage = isStage }; return result; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index e80d34fc4c..b1be4b92f4 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -198,7 +198,7 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) var functionReturnTypeId = GetOrRegister(functionType.ReturnType); c.IdRef = Bound++; - Add(new OpSDSLImportFunction(functionReturnTypeId, c.IdRef, c.Id.Name, shader.ResultId)); + Add(new OpSDSLImportFunction(functionReturnTypeId, c.IdRef, c.Id.Name, shader.ResultId, c.Id.FunctionFlags)); AddName(c.IdRef, c.Id.Name); } shaderSymbol.Components[index] = c; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 1c1edb2abf..4db2f92a50 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -198,7 +198,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con { var streams = analysisResult.Streams; - ProcessMethod(buffer, entryPointId, streams); + ProcessMethod(buffer, [], entryPointId, streams); var stage = executionModel switch { @@ -332,7 +332,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con /// /// Figure out (recursively) which streams are being read from and written to. /// - private void ProcessMethod(NewSpirvBuffer buffer, int functionId, SortedList streams) + private void ProcessMethod(NewSpirvBuffer buffer, List callStack, int functionId, SortedList streams) { var methodStart = FindMethodStart(buffer, functionId); for (var index = methodStart; index < buffer.Count; index++) @@ -364,7 +364,11 @@ private void ProcessMethod(NewSpirvBuffer buffer, int functionId, SortedList(T text, ConsoleColor? color = null) readonly DisWriter AppendIdRef(int id, bool useNames = true) { if (data.UseNames && useNames && data.NameTable.TryGetValue(id, out var name)) - return Append($"%{name} ", ConsoleColor.Green); + { + Append($"%{name}", ConsoleColor.Green); + if (data.UseIds) + { + Append("["); + Append($"{id}", ConsoleColor.Green); + Append("]"); + } + Append(" "); + return this; + } else return Append($"%{id} ", ConsoleColor.Green); } readonly DisWriter AppendIdRefs(Span ids) @@ -169,6 +188,13 @@ readonly DisWriter AppendResultId(int? id = null) AppendRepeatChar(' ', data.IdOffset - name.Length - 1 - 3); Append('%', ConsoleColor.Cyan); Append(name, ConsoleColor.Cyan); + if (data.UseIds) + { + Append("["); + Append($"{id}", ConsoleColor.Cyan); + Append("]"); + + } } else { @@ -213,8 +239,15 @@ public void Disassemble() data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; } } + + int index = 0; foreach (var instruction in data) { + if (data.UseInstructionIndex) + { + Append($"SPV_{index:0000}: "); + index++; + } DisInstruction(instruction, this); } } @@ -783,14 +816,18 @@ struct DisData : IDisposable public HashSet UsedNames { get; } = new(); public NewSpirvBuffer Buffer { get; } public int IdOffset { get; private set; } - public bool UseNames { get; private set; } + public DisassemblerFlags Flags { get; private set; } public bool WriteToConsole { get; private set; } - public DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) + public bool UseNames => (Flags & DisassemblerFlags.Name) != 0; + public bool UseIds => (Flags & DisassemblerFlags.Id) != 0; + public bool UseInstructionIndex => (Flags & DisassemblerFlags.InstructionIndex) != 0; + + public DisData(NewSpirvBuffer buffer, DisassemblerFlags flags, bool writeToConsole) { Buffer = buffer; NameTable = []; - UseNames = useNames; + Flags = flags; WriteToConsole = writeToConsole; ComputeIdOffset(); } From f2f82a1460aebf07b87bf42f37c4ca2ba12c5089 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Oct 2025 10:40:06 +0900 Subject: [PATCH 0494/1182] Rearranged code in multiple methods/files and added some comments --- .../SDSL/EffectEvaluator.cs | 101 ++++ .../SDSL/ShaderMixer.MixinNode.cs | 52 ++ .../SDSL/ShaderMixer.ShaderInfo.cs | 154 +++++ .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 87 +++ .../SDSL/ShaderMixer.cs | 553 ++++-------------- 5 files changed, 507 insertions(+), 440 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs new file mode 100644 index 0000000000..2a02aad15d --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -0,0 +1,101 @@ +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Spirv.Building; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Compilers.SDSL +{ + internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) + { + public ShaderSource EvaluateEffects(ShaderSource source) + { + switch (source) + { + case ShaderClassSource classSource: + if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) + throw new NotImplementedException(); + + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); + if (buffer[0].Op == Op.OpSDSLEffect) + { + var mixinTree = new ShaderMixinSource(); + foreach (var instruction in buffer) + { + if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) + { + var instSource = new ShaderClassSource(mixinInstruction.Mixin); + var evaluatedSource = EvaluateEffects(instSource); + + Merge(mixinTree, evaluatedSource); + } + else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) + { + var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin); + var evaluatedSource = EvaluateEffects(instSource); + + MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); + } + } + + return mixinTree; + } + + return classSource; + case ShaderMixinSource mixinSource: + var result = new ShaderMixinSource(); + foreach (var mixin in mixinSource.Mixins) + { + var evaluatedMixin = EvaluateEffects(mixin); + Merge(result, evaluatedMixin); + } + + foreach (var composition in mixinSource.Compositions) + { + var evaluatedMixin = EvaluateEffects(composition.Value); + MergeComposition(result, composition.Key, evaluatedMixin); + } + + return result; + default: + throw new NotImplementedException(); + } + } + + public void Merge(ShaderMixinSource mixinTree, ShaderSource source) + { + switch (source) + { + case ShaderClassSource classSource: + mixinTree.Mixins.Add(classSource); + break; + case ShaderMixinSource mixinSource: + foreach (var mixin in mixinSource.Mixins) + { + mixinTree.Mixins.Add(mixin); + } + + foreach (var composition in mixinSource.Compositions) + { + if (mixinTree.Compositions.TryGetValue(composition.Key, out var mixinTreeComposition)) + mixinTree.Compositions.Add(composition.Key, mixinTreeComposition = new ShaderMixinSource()); + Merge(mixinTreeComposition, composition.Value); + } + + break; + } + } + + public void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) + { + if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) + mixinTree.Compositions.Add(compositionName, composition = new()); + + Merge(composition, evaluatedSource); + } + } +} diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs new file mode 100644 index 0000000000..5c843c1568 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -0,0 +1,52 @@ +namespace Stride.Shaders.Compilers.SDSL; + +public partial class ShaderMixer +{ + /// + /// Represents a mixin node which will merge multiple shaders. + /// + /// + /// The following shader would have 3 : top-level stage one (with MyShader and MyBase) and 2 compositions nodes (Comp0 and Comp1). + /// + /// shader MyShader : MyBase + /// { + /// ComputeColor Comp0; + /// ComputeColor Comp1; + /// } + /// + /// + /// + private partial class MixinNode(MixinNode? stage, string? compositionPath) + { + /// + /// If we are inside a composition node, this provides access to the stage (top-level) . + /// + public MixinNode? Stage { get; } = stage; + + public bool IsRoot => Stage == null; + + public string? CompositionPath { get; } = compositionPath; + + public int StartInstruction { get; internal set; } + public int EndInstruction { get; internal set; } + + /// + /// List of shaders mixed in this node. + /// + public List Shaders { get; } = new(); + + public Dictionary ShadersByName { get; } = new(); + public Dictionary MethodGroupsByName { get; } = new(); + public Dictionary MethodGroups { get; } = new(); + public Dictionary Compositions { get; } = new(); + } + + class MethodGroup + { + public string Name; + public ShaderInfo Shader; + public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); + + public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs new file mode 100644 index 0000000000..418dd5e7c3 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -0,0 +1,154 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Compilers.SDSL; + +public partial class ShaderMixer +{ + private class ShaderInfo(int shaderIndex, string shaderName, int startInstruction, int endInstruction) + { + /// + /// Index of this within this . + /// + public int ShaderIndex { get; } = shaderIndex; + + public string ShaderName { get; } = shaderName; + + /// + /// The for the same shader at the top-level (for all the stage members, if any). + /// + public ShaderInfo? Stage { get; set; } + + /// + /// Kept for debug purpose. + /// + public string? CompositionPath { get; set; } + + public int StartInstruction { get; } = startInstruction; + public int EndInstruction { get; } = endInstruction; + public Dictionary Names { get; } = new(); + public Dictionary Functions { get; } = new(); + public Dictionary Variables { get; } = new(); + + public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; + } + + private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + { + ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); + for (var index = shaderStart; index < shaderEnd; index++) + { + var i = temp[index]; + + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + shaderInfo.Names.Add(nameInstruction.Target, nameInstruction.Name); + } + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + var functionName = shaderInfo.Names[function.ResultId]; + shaderInfo!.Functions.Add(functionName, function.ResultId); + } + else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + { + var variableName = shaderInfo.Names[variable.ResultId]; + shaderInfo!.Variables.Add(variableName, (variable.ResultId, types[variable.ResultType])); + } + } + } + + private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + { + var importedShaders = new Dictionary(); + var idRemapping = new Dictionary(); + for (var index = shaderStart; index < temp.Count; index++) + { + var i = temp[index]; + + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + if (idRemapping.ContainsKey(nameInstruction.Target)) + { + SetOpNop(i.Data.Memory.Span); + shaderInfo.Names.Remove(nameInstruction.Target); + } + } + else if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) + { + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + { + if (importShader.Type == Specification.ImportType.Inherit) + { + importedShaders.Add(importShader.ResultId, mixinNode.ShadersByName[importShader.ShaderName]); + + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + { + if (importedShaders.TryGetValue(importVariable.Shader, out var importedShader)) + { + var importedVariable = importedShader.Variables[importVariable.VariableName]; + + idRemapping.Add(importVariable.ResultId, importedVariable.Id); + + SetOpNop(i.Data.Memory.Span); + } + } + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + { + if (importedShaders.TryGetValue(importFunction.Shader, out var importedShader)) + { + if (importedShader.Functions.ContainsKey(importFunction.FunctionName)) + { + var importedFunction = importedShader.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + } + else if (importedShader.Stage != null && importedShader.Stage.Functions.ContainsKey(importFunction.FunctionName)) + { + var importedFunction = importedShader.Stage.Functions[importFunction.FunctionName]; + idRemapping.Add(importFunction.ResultId, importedFunction); + } + else + { + // We have some cases when function is removed (i.e. stage/non-stage depending on mixin node), but import is still there. + // In this case, we map to 0 and make sure it's not referenced during next step. + idRemapping.Add(importFunction.ResultId, 0); + } + + SetOpNop(i.Data.Memory.Span); + } + } + + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) + { + if (to1 == 0) + throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[0]} at instruction {index}"); + op.Words[0] = to1; + } + + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + { + if (to2 == 0) + throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[1]} at instruction {index}"); + op.Words[1] = to2; + } + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs new file mode 100644 index 0000000000..31fdd1aa42 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -0,0 +1,87 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Compilers.SDSL; +using static Stride.Shaders.Spirv.Specification; + +public partial class ShaderMixer +{ + /// + /// Expands inheritance (including implicit and transitive ones) and composition (including shaders that should be merged at stage level). + /// + /// + /// + /// + /// + private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinSource? root = null) + { + bool isRoot = root == null; + var mixinList = new List(); + + var shaderMixinSource = shaderSource switch + { + ShaderMixinSource mixinSource2 => mixinSource2, + ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, + }; + foreach (var mixinToMerge in shaderMixinSource.Mixins) + { + if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) + throw new NotImplementedException(); + + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); + SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList); + if (!mixinList.Contains(mixinToMerge)) + mixinList.Add(mixinToMerge); + } + + shaderMixinSource.Mixins.Clear(); + shaderMixinSource.Mixins.AddRange(mixinList); + + foreach (var shaderName in mixinList) + { + var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName.ClassName); + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + + bool hasStage = false; + foreach (var i in shader) + { + if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + { + var variableType = types[variable.ResultType]; + if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + { + var variableName = names[variable.ResultId]; + // Make sure we have a ShaderMixinSource + // If composition is not specified, use default class + if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) + { + compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; + } + compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin, root ?? shaderMixinSource); + shaderMixinSource.Compositions[variableName] = compositionMixin; + } + } + + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is {} functionInfo) + { + hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + } + } + + // If there are any stage variables, add class to root + if (!isRoot && hasStage) + { + var shaderNameStageOnly = new ShaderClassSource(shaderName.ClassName) { GenericArguments = shaderName.GenericArguments, ImportStageOnly = true }; + // Make sure it's not already added yet (either standard or stage only) + if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) + root!.Mixins.Add(shaderNameStageOnly); + } + } + + return shaderMixinSource; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 19edd89a3e..5bbfd7a36a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -18,13 +18,8 @@ namespace Stride.Shaders.Compilers.SDSL; -public class ShaderMixer(IExternalShaderLoader ShaderLoader) +public partial class ShaderMixer(IExternalShaderLoader ShaderLoader) { - class MixinGroup - { - public List InheritanceList { get; } = new(); - } - public void MergeSDSL(string entryShaderName, out byte[] bytecode) { var temp = new NewSpirvBuffer(); @@ -32,30 +27,22 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var context = new SpirvContext(); var table = new SymbolTable(); - var shaderSource = EvaluateEffects(new ShaderClassSource(entryShaderName)); + var effectEvaluator = new EffectEvaluator(ShaderLoader); + var shaderSource = effectEvaluator.EvaluateEffects(new ShaderClassSource(entryShaderName)); var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); // Root shader - MergeSDSLMixin(new MixinResultGlobal(), context, table, temp, shaderSource2); + MergeMixinNode(new MixinGlobalContext(), context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - { - for (int i = 0; i < temp.Count; i++) - { - // Remove Nop - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); - // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) - else if (temp[i].Op == Op.OpSDSLShader || temp[i].Op == Op.OpSDSLShaderEnd || temp[i].Op == Op.OpSDSLEffect || temp[i].Op == Op.OpSDSLEffectEnd) - temp.RemoveAt(i--); - } - temp.Sort(); - Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); - } + CleanupUnnecessaryInstructions(temp); + temp.Sort(); + + Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); new StreamAnalyzer().Process(table, temp, context); @@ -69,7 +56,6 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) temp.RemoveAt(i--); } - temp.Sort(); bytecode = temp.ToBytecode(); @@ -80,214 +66,88 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) //File.WriteAllText("test.spvdis", source); } - private void Merge(ShaderMixinSource mixinTree, ShaderSource source) + class MixinGlobalContext { - switch (source) - { - case ShaderClassSource classSource: - mixinTree.Mixins.Add(classSource); - break; - case ShaderMixinSource mixinSource: - foreach (var mixin in mixinSource.Mixins) - { - mixinTree.Mixins.Add(mixin); - } - - foreach (var composition in mixinSource.Compositions) - { - if (mixinTree.Compositions.TryGetValue(composition.Key, out var mixinTreeComposition)) - mixinTree.Compositions.Add(composition.Key, mixinTreeComposition = new ShaderMixinSource()); - Merge(mixinTreeComposition, composition.Value); - } - - break; - } - } - - private ShaderSource EvaluateEffects(ShaderSource source) - { - switch (source) - { - case ShaderClassSource classSource: - if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) - throw new NotImplementedException(); - - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); - if (buffer[0].Op == Op.OpSDSLEffect) - { - var mixinTree = new ShaderMixinSource(); - foreach (var instruction in buffer) - { - if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) - { - var instSource = new ShaderClassSource(mixinInstruction.Mixin); - var evaluatedSource = EvaluateEffects(instSource); - - Merge(mixinTree, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) - { - var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin); - var evaluatedSource = EvaluateEffects(instSource); - - MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); - } - } - - return mixinTree; - } - - return classSource; - case ShaderMixinSource mixinSource: - var result = new ShaderMixinSource(); - foreach (var mixin in mixinSource.Mixins) - { - var evaluatedMixin = EvaluateEffects(mixin); - Merge(result, evaluatedMixin); - } - - foreach (var composition in mixinSource.Compositions) - { - var evaluatedMixin = EvaluateEffects(composition.Value); - MergeComposition(result, composition.Key, evaluatedMixin); - } - - return result; - default: - throw new NotImplementedException(); - } - } - - private void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) - { - if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) - mixinTree.Compositions.Add(compositionName, composition = new()); - - Merge(composition, evaluatedSource); - } - - class MethodGroup - { - public string Name; - public int MethodIndexInGroup; - public ShaderInfo Shader; - public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); - - public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; + public Dictionary Names { get; } = new(); + public Dictionary Types { get; } = new(); } - class MixinResultGlobal + class MixinNodeContext { - public Dictionary Names { get; } = new(); - public Dictionary Types { get; } = new(); + public MixinNode Result { get; } } - class MixinResult(MixinResult? stage) + MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinSource mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { - public MixinResult? Stage { get; } = stage; + if (currentCompositionPath != null) + buffer.Add(new OpSDSLEffect(currentCompositionPath)); - public List Shaders { get; } = new(); - public Dictionary ShadersByName { get; } = new(); + var mixinNode = new MixinNode(stage, currentCompositionPath); - public Dictionary MethodGroupsByName { get; } = new(); + // Step: expand "for" + // TODO - public Dictionary MethodGroups { get; } = new(); + // Merge all classes from mixinSource.Mixins in main buffer + ProcessMixinClasses(context, buffer, mixinSource, mixinNode); - public Dictionary Compositions { get; } = new(); - } + //Console.WriteLine("Done SDSL importing"); + //Spv.Dis(buffer, true); - private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinSource? root = null) - { - bool isRoot = root == null; - var mixinList = new List(); + new TypeDuplicateRemover().Apply(buffer); - var shaderMixinSource = shaderSource switch - { - ShaderMixinSource mixinSource2 => mixinSource2, - ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, - }; - foreach (var mixinToMerge in shaderMixinSource.Mixins) - { - if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) - throw new NotImplementedException(); + //Console.WriteLine("Done type remapping"); + //Spv.Dis(buffer, true); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); - SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList); - if (!mixinList.Contains(mixinToMerge)) - mixinList.Add(mixinToMerge); - } + // Build names and types mappings + ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); - shaderMixinSource.Mixins.Clear(); - shaderMixinSource.Mixins.AddRange(mixinList); + BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); - foreach (var shaderName in mixinList) + // Compositions (recursive) + foreach (var shader in mixinNode.Shaders) { - var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName.ClassName); - ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); - - bool hasStage = false; - foreach (var i in shader) + foreach (var variable in shader.Variables) { - if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) - { - var variableType = types[variable.ResultType]; - if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) - { - var variableName = names[variable.ResultId]; - // Make sure we have a ShaderMixinSource - // If composition is not specified, use default class - if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) - { - compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; - } - compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin, root ?? shaderMixinSource); - shaderMixinSource.Compositions[variableName] = compositionMixin; - } - } - - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is {} functionInfo) + if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) { - hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + var compositionMixin = mixinSource.Compositions[variable.Key]; + var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; + var compositionResult = MergeMixinNode(globalContext, context, table, buffer, compositionMixin, mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); + + mixinNode.Compositions.Add(variable.Value.Id, compositionResult); } } + } + + // Patch method calls (virtual calls & base calls) + PatchMethodCalls(globalContext, buffer, mixinNode); - // If there are any stage variables, add class to root - if (!isRoot && hasStage) + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction) { - var shaderNameStageOnly = new ShaderClassSource(shaderName.ClassName) { GenericArguments = shaderName.GenericArguments, ImportStageOnly = true }; - // Make sure it's not already added yet (either standard or stage only) - if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) - root!.Mixins.Add(shaderNameStageOnly); + SetOpNop(i.Data.Memory.Span); } } - return shaderMixinSource; - } - - MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, ShaderMixinSource mixinSource, MixinResult? stage = null, string? currentCompositionPath = null) - { if (currentCompositionPath != null) - temp.Add(new OpSDSLEffect(currentCompositionPath)); - - var isRoot = stage == null; - var mixinResult = new MixinResult(stage); - if (isRoot) - stage = mixinResult; + buffer.Add(new OpSDSLEffectEnd()); - // TODO: support proper shader mixin source - //var shaderMixin = new ShaderMixinSource { Mixins = { new ShaderClassCode(entryShaderName) } }; - - // Step: expand "for" - // TODO + return mixinNode; + } + private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, ShaderMixinSource mixinSource, MixinNode mixinNode) + { + var isRoot = mixinNode.Stage == null; var offset = context.Bound; var nextOffset = 0; - var shaders = mixinResult.Shaders; - var shadersByName = mixinResult.ShadersByName; + var shaders = mixinNode.Shaders; + var shadersByName = mixinNode.ShadersByName; - var mixinStart = temp.Count; + mixinNode.StartInstruction = temp.Count; foreach (var shaderClass in mixinSource.Mixins) { var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderClass.ClassName); @@ -299,25 +159,14 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo bool skipFunction = false; - // Copy instructions to single buffer + // Copy instructions to main buffer for (var index = 0; index < shader.Count; index++) { var i = shader[index]; + // Do we need to skip variable/functions? (depending on stage/non-stage) - { var include = true; - if (i.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) - { - var isStage = (importFunction.Flags & FunctionFlagsMask.Stage) != 0; - /*include = isStage switch - { - // Import stage members only if root level - true => isRoot || shaderClass.ImportStageOnly, - // Import non-stage members only if import stage only is not specified - false => !shaderClass.ImportStageOnly, - };*/ - } if (i.Op == Op.OpFunction && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; @@ -362,66 +211,57 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo OffsetIds(i2, offset); } + // Build ShaderInfo var shaderInfo = new ShaderInfo(shaders.Count, shaderClass.ClassName, shaderStart, temp.Count); - shaderInfo.CompositionPath = currentCompositionPath; - if (mixinResult.Stage != null && mixinResult.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) + shaderInfo.CompositionPath = mixinNode.CompositionPath; + if (mixinNode.Stage != null && mixinNode.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) shaderInfo.Stage = stageShaderInfo; - PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo, mixinResult); + PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo, mixinNode); + shadersByName.Add(shaderClass.ClassName, shaderInfo); shaders.Add(shaderInfo); - Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); - RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, mixinResult); - Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); + // Remap ids from inherited class (OpSDSLImport*) + RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, mixinNode); } - var mixinEnd = temp.Count; - - //Console.WriteLine("Done SDSL importing"); - //Spv.Dis(temp, true); - - new TypeDuplicateRemover().Apply(temp); - - //Console.WriteLine("Done type remapping"); - //Spv.Dis(temp, true); - + mixinNode.EndInstruction = temp.Count; context.Bound = offset + nextOffset + 1; - //Spv.Dis(temp, true); - var names = global.Names; - var types = global.Types; - ShaderClass.ProcessNameAndTypes(temp, mixinStart, mixinEnd, names, types); + } - // Add symbol for each method in current type (equivalent to implicit this pointer) - for (var index = mixinStart; index < mixinEnd; index++) + private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, MixinNode mixinNode) + { + // Setup types in context + foreach (var type in globalContext.Types) { - var i = temp[index]; - if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + if (!context.ReverseTypes.ContainsKey(type.Key)) { - var functionName = names[function.ResultId]; - var symbol = new Symbol(new(functionName, SymbolKind.Method), types[function.FunctionType], function.ResultId); - table.CurrentFrame.Add(functionName, symbol); + context.Types.Add(type.Value, type.Key); + context.ReverseTypes.Add(type.Key, type.Value); } } - // Build type mappings - foreach (var type in types) + // Add symbol for each method in current type (equivalent to implicit this pointer) + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { - if (!context.ReverseTypes.ContainsKey(type.Key)) + var i = temp[index]; + if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); + var functionName = globalContext.Names[function.ResultId]; + var symbol = new Symbol(new(functionName, SymbolKind.Method), globalContext.Types[function.FunctionType], function.ResultId); + table.CurrentFrame.Add(functionName, symbol); } } // Build method group info (override, etc.) ShaderInfo? currentShader = null; - for (var index = mixinStart; index < mixinEnd; index++) + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = temp[index]; if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) { - currentShader = shadersByName[shaderInstruction.ShaderName]; + currentShader = mixinNode.ShadersByName[shaderInstruction.ShaderName]; } else if (i.Data.Op == Op.OpSDSLShaderEnd) { @@ -432,10 +272,10 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { - var functionName = names[function.ResultId]; + var functionName = globalContext.Names[function.ResultId]; - var methodMixinGroup = mixinResult; - if (!isRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) + var methodMixinGroup = mixinNode; + if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) methodMixinGroup = methodMixinGroup.Stage; // Check if it has a parent (and if yes, share the MethodGroup) @@ -443,7 +283,6 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo methodGroup = new MethodGroup { Name = functionName }; methodGroup.Shader = currentShader; - methodGroup.MethodIndexInGroup = methodGroup.Methods.Count; methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; @@ -470,28 +309,14 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo } } } + } - // Compositions - foreach (var shader in shaders) - { - foreach (var variable in shader.Variables) - { - if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) - { - var compositionMixin = mixinSource.Compositions[variable.Key]; - var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; - var compositionResult = MergeSDSLMixin(global, context, table, temp, compositionMixin, stage, compositionPath); - - mixinResult.Compositions.Add(variable.Value.Id, compositionResult); - } - } - } - - - // Patch method calls (virtual calls & base calls) + private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvBuffer temp, MixinNode mixinNode) + { var externalShaders = new HashSet(); var externalFunctions = new Dictionary(); - for (var index = mixinStart; index < mixinEnd; index++) + ShaderInfo? currentShader = null; + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = temp[index]; // Only import shaders should be left @@ -522,28 +347,21 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - if (!mixinResult.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {names[function.ResultId]}"); + if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[function.ResultId]}"); - currentShader = shaders.Last(x => index >= x.StartInstruction); + currentShader = mixinNode.Shaders.Last(x => index >= x.StartInstruction); } else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) { - /*var methodMixinResult = mixinResult; - if ((functionInfo.Flags & FunctionFlagsMask.Stage) != 0) - { - while (methodMixinResult.Parent != null) - methodMixinResult = methodMixinResult.Parent; - }*/ - - var methodMixinGroup = mixinResult; + var methodMixinGroup = mixinNode; var isBaseCall = temp[index - 1].Op == Op.OpSDSLCallBase; // Process member call (composition) if (temp[index - 1].Op == Op.OpSDSLCallTarget) { var callTarget = (OpSDSLCallTarget)temp[index - 1]; - var composition = mixinResult.Compositions[callTarget.Target]; + var composition = mixinNode.Compositions[callTarget.Target]; methodMixinGroup = composition; Spv.Dis(temp, Spv.DisassemblerFlags.Id); @@ -563,7 +381,7 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo { // Try again as a stage method (only if not a base call) if (methodMixinGroup.Stage == null || !methodMixinGroup.Stage.MethodGroups.TryGetValue(functionCall.Function, out methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {names[functionCall.Function]}"); + throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[functionCall.Function]}"); foundInStage = true; } @@ -571,8 +389,9 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo if (isBaseCall) { // We currently do not allow calling base stage method from a non-stage method + // (if we were to allow them later, we would need to tweak following detection code as ShaderIndex comparison is only valid for items within the same MixinNode) if (foundInStage) - throw new InvalidOperationException($"Method {names[functionCall.Function]} was found but a base call can't be performed on a stage method from a non-stage method"); + throw new InvalidOperationException($"Method {globalContext.Names[functionCall.Function]} was found but a base call can't be performed on a stage method from a non-stage method"); // Is it a base call? if yes, find the direct parent // Let's find the method in same group just before ours @@ -588,7 +407,7 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo } if (!baseMethodFound) - throw new InvalidOperationException($"Can't find a base method for {names[functionCall.Function]}"); + throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionCall.Function]}"); SetOpNop(temp[index - 1].Data.Memory.Span); } @@ -599,167 +418,8 @@ MixinResult MergeSDSLMixin(MixinResultGlobal global, SpirvContext context, Symbo } } } - - for (var index = mixinStart; index < mixinEnd; index++) - { - var i = temp[index]; - if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction) - { - SetOpNop(i.Data.Memory.Span); - } - - if (i.Op == Op.OpTypePointer) - { - - } - } - - if (currentCompositionPath != null) - temp.Add(new OpSDSLEffectEnd()); - - return mixinResult; - } - - private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinResult mixinResult) - { - ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); - for (var index = shaderStart; index < shaderEnd; index++) - { - var i = temp[index]; - - if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) - { - shaderInfo.Names.Add(nameInstruction.Target, nameInstruction.Name); - } - else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) - { - var functionName = shaderInfo.Names[function.ResultId]; - shaderInfo!.Functions.Add(functionName, function.ResultId); - } - else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) - { - var variableName = shaderInfo.Names[variable.ResultId]; - shaderInfo!.Variables.Add(variableName, (variable.ResultId, types[variable.ResultType])); - } - } } - private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinResult mixinResult) - { - var importedShaders = new Dictionary(); - var idRemapping = new Dictionary(); - for (var index = shaderStart; index < temp.Count; index++) - { - var i = temp[index]; - - if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) - { - if (idRemapping.ContainsKey(nameInstruction.Target)) - { - SetOpNop(i.Data.Memory.Span); - shaderInfo.Names.Remove(nameInstruction.Target); - } - } - else if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) - { - SetOpNop(i.Data.Memory.Span); - } - else if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) - { - if (importShader.Type == ImportType.Inherit) - { - importedShaders.Add(importShader.ResultId, mixinResult.ShadersByName[importShader.ShaderName]); - - SetOpNop(i.Data.Memory.Span); - } - } - else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) - { - if (importedShaders.TryGetValue(importVariable.Shader, out var importedShader)) - { - var importedVariable = importedShader.Variables[importVariable.VariableName]; - - idRemapping.Add(importVariable.ResultId, importedVariable.Id); - - SetOpNop(i.Data.Memory.Span); - } - } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) - { - if (importedShaders.TryGetValue(importFunction.Shader, out var importedShader)) - { - if (importedShader.Functions.ContainsKey(importFunction.FunctionName)) - { - var importedFunction = importedShader.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - } - else if (importedShader.Stage != null && importedShader.Stage.Functions.ContainsKey(importFunction.FunctionName)) - { - var importedFunction = importedShader.Stage.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - } - else - { - idRemapping.Add(importFunction.ResultId, 0); - } - - SetOpNop(i.Data.Memory.Span); - } - } - - foreach (var op in i.Data) - { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) - { - if (to1 == 0) - throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[0]} at instruction {index}"); - op.Words[0] = to1; - } - - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - { - if (to2 == 0) - throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[1]} at instruction {index}"); - op.Words[1] = to2; - } - } - } - } - - class ShaderInfo(int shaderIndex, string shaderName, int startInstruction, int endInstruction) - { - public int ShaderIndex { get; } = shaderIndex; - - public string ShaderName { get; } = shaderName; - - /// - /// The for the same shader at the top-level (for all the stage members, if any). - /// - public ShaderInfo? Stage { get; set; } - - /// - /// Kept for debug purpose. - /// - public string? CompositionPath { get; set; } - - public int StartInstruction { get; } = startInstruction; - public int EndInstruction { get; } = endInstruction; - - public Dictionary Names { get; } = new(); - - - public Dictionary Functions { get; } = new(); - public Dictionary Variables { get; } = new(); - - public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; - } static void SetOpNop(Span words) { @@ -802,4 +462,17 @@ public static void OffsetIds(OpData inst, int offset) } } } + + private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) + { + for (int i = 0; i < temp.Count; i++) + { + // Remove Nop + if (temp[i].Op == Op.OpNop) + temp.RemoveAt(i--); + // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) + else if (temp[i].Op == Op.OpSDSLShader || temp[i].Op == Op.OpSDSLShaderEnd || temp[i].Op == Op.OpSDSLEffect || temp[i].Op == Op.OpSDSLEffectEnd) + temp.RemoveAt(i--); + } + } } \ No newline at end of file From 7d10c1e6ef15f5fd99240dd7c32944b8ca2a0dfb Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 19 Oct 2025 15:57:55 +0200 Subject: [PATCH 0495/1182] Implementing texture compilation MVP --- assets/SDSL/TestTexture.sdsl | 38 +++ src/Stride.Graphics.RHI/SamplerDesc.cs | 51 ++++ .../Examples.Spirv.cs | 14 +- .../Buffers/NewSpirvBuffer.cs | 14 +- .../Information/InstructionInfo.cs | 116 +------- .../Information/LogicalOperand.Size.cs | 2 +- .../Information/LogicalOperand.cs | 35 +-- .../Information/LogicalOperandArray.cs | 4 +- .../Literals/ParameterizedFlag.cs | 23 ++ .../Parsing/OpDataEnumerator.cs | 191 ++++--------- src/Stride.Shaders.Spirv.Generators/Data.cs | 13 + .../Extensions/spirv.sdsl.grammar-ext.json | 108 ------- src/Stride.Shaders.Spirv.Generators/Range.cs | 268 ++++++++++++++++++ .../SPVGenerator.Helpers.Naming.cs | 4 + .../SPVGenerator.Helpers.Preprocessing.cs | 48 +++- .../SPVGenerator.Info.cs | 163 ++++++----- .../SPVGenerator.Instructions.cs | 69 +++-- .../SPVGenerator.cs | 5 +- src/Stride.Shaders/Core/Symbol.cs | 4 +- src/Stride.Shaders/Core/SymbolTypes.cs | 79 ++++-- .../Parsing/SDSL/AST/Expression.cs | 110 ++++--- .../Parsing/SDSL/AST/Literals.cs | 19 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 23 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 37 ++- .../ShaderParsers/ShaderDataParsers.cs | 14 +- src/Stride.Shaders/Spirv/Building/Context.cs | 8 +- .../Spirv/Processing/StreamAnalyzer.cs | 30 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 70 +---- 28 files changed, 919 insertions(+), 641 deletions(-) create mode 100644 assets/SDSL/TestTexture.sdsl create mode 100644 src/Stride.Graphics.RHI/SamplerDesc.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs delete mode 100644 src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json create mode 100644 src/Stride.Shaders.Spirv.Generators/Range.cs diff --git a/assets/SDSL/TestTexture.sdsl b/assets/SDSL/TestTexture.sdsl new file mode 100644 index 0000000000..0b86533c46 --- /dev/null +++ b/assets/SDSL/TestTexture.sdsl @@ -0,0 +1,38 @@ +namespace Stride.Shaders.Tests; + +shader TestBasic : TestBase +{ + stream float4 InputPosition : POSITION; + stream float4 Position : SV_POSITION; + stream float4 ExtraColor : COLOR; + stream float4 TexCoord : TEXCOORD0; + + stage SamplerState Sampler; + stage Texture2D Texture0; + + cbuffer Test123 + { + float4 CBufferValue1; + } + + void VSMain() + { + streams.Position = streams.InputPosition; + return; + } + + void Test() + { + streams.ColorTarget = streams.ExtraColor; + SetColor(streams.ExtraColor); + return; + } + + void PSMain() + { + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); + streams.ColorTarget = streams.ExtraColor * CBufferValue1 * Texture0.Sample(Sampler, TexCoord); + //Test(); + return; + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/SamplerDesc.cs b/src/Stride.Graphics.RHI/SamplerDesc.cs new file mode 100644 index 0000000000..333ecd90bc --- /dev/null +++ b/src/Stride.Graphics.RHI/SamplerDesc.cs @@ -0,0 +1,51 @@ +using Silk.NET.Maths; + +namespace Stride.Graphics.RHI; + + +public enum FilterKind +{ + Nearest = 0, + Linear = 1, + CubicExt = 2, + CubicImg = 3 +} + +public enum TextureAddressMode +{ + Repeat = 0, + Wrap = 1, + Mirror = 2, + Clamp = 3, + Border = 4, + MirrorOnce = 5 +} +public enum ComparisonOperation +{ + Never = 0, + Less = 1, + Equal = 2, + LessEqual = 3, + Greater = 4, + NotEqual = 5, + GreaterEqual = 6, + Always = 7 +} + +public struct SamplerDesc +{ + public float MipLODBias { get; set; } + public float MipLodBias { get; set; } + public float MinLod { get; set; } + public float MaxLod { get; set; } + public float MaxAnisotropy { get; set; } + public bool UnnormalizedCoordinates { get; set; } + // VkSamplerMipmapMode mipmapMode; + public FilterKind Filter { get; set; } + public TextureAddressMode AddressU { get; set; } + public TextureAddressMode AddressV { get; set; } + public TextureAddressMode AddressW { get; set; } + public ComparisonOperation CompareOp { get; set; } + public Vector4D BorderColor { get; set; } + +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 09baa98dfc..93317ab357 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -109,14 +109,14 @@ public static void CreateNewShader() buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); buffer.FluentAdd(new OpConstant(t_int, id++, 4), out var constant8); buffer.FluentAdd(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_3); - buffer.FluentAdd(new OpDecorate(t_array, Decoration.ArrayStride, 16)); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 0, Decoration.Offset, 0)); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 1, Decoration.Offset, 16)); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 2, Decoration.Offset, 96)); - buffer.FluentAdd(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, 0)); - buffer.FluentAdd(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, 112)); + buffer.FluentAdd(new OpDecorate(t_array, ParameterizedFlags.DecorationArrayStride(16))); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 0, ParameterizedFlags.DecorationOffset(0))); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 1, ParameterizedFlags.DecorationOffset(16))); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 2, ParameterizedFlags.DecorationOffset(96))); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 0, ParameterizedFlags.DecorationOffset(0))); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 1, ParameterizedFlags.DecorationOffset(112))); buffer.FluentAdd(new OpDecorate(t_struct2, Decoration.Block)); - buffer.FluentAdd(new OpDecorate(v_struct2, Decoration.DescriptorSet, 0)); + buffer.FluentAdd(new OpDecorate(v_struct2, ParameterizedFlags.DecorationDescriptorSet(0))); buffer.FluentAdd(new OpDecorate(v_input_2, Decoration.NoPerspective)); buffer.FluentAdd(new OpName(t_p_func, "main")); buffer.FluentAdd(new OpName(t_struct, "S")); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 342a82056e..3706f7b158 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -357,16 +357,8 @@ public static class IMemoryInstructionExtensions public static LogicalOperandArray GetInfo(this ref T op) where T : struct, IMemoryInstruction { - Decoration? decoration = op switch - { - OpDecorate opd => opd.Decoration, - OpDecorateId opd => opd.Decoration, - OpDecorateString opd => opd.Decoration, - OpMemberDecorate opd => opd.Decoration, - OpMemberDecorateString opd => opd.Decoration, - _ => null - }; - - return InstructionInfo.GetInfo((Op)(op.InstructionMemory.Span[0] & 0xFFFF), decoration); + if(op.DataIndex is OpDataIndex odi) + return InstructionInfo.GetInfo(odi.Data); + return InstructionInfo.GetInfo(op.InstructionMemory.Span); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index 80765d2f81..e6fc6a57b5 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -9,11 +9,6 @@ namespace Stride.Shaders.Spirv.Core; -public record struct OperandKey(Op Op, Decoration? Decoration = null) -{ - public static implicit operator OperandKey(Op op) => new(op); -} - /// /// Singleton object containing informations on every spirv instructions, used for spirv parsing. @@ -21,60 +16,8 @@ public record struct OperandKey(Op Op, Decoration? Decoration = null) public partial class InstructionInfo { public static InstructionInfo Instance { get; } = new(); - readonly Dictionary Info = []; - InstructionInfo() - { - Info.Add(new(Op.OpDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "specId")])); - Info.Add(new(Op.OpDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "arrayStride")])); - Info.Add(new(Op.OpDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "matrixStride")])); - Info.Add(new(Op.OpDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "additionalInteger", "builtin")])); - Info.Add(new(Op.OpDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "scopeId")])); - Info.Add(new(Op.OpDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "streamNumber")])); - Info.Add(new(Op.OpDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "location")])); - Info.Add(new(Op.OpDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "index")])); - Info.Add(new(Op.OpDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "descriptorSet")])); - Info.Add(new(Op.OpDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "offset")])); - Info.Add(new(Op.OpDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "bufferNumber")])); - Info.Add(new(Op.OpDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "stride")])); - Info.Add(new(Op.OpDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "additionalInteger", "roundingMode")])); - Info.Add(new(Op.OpDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "additionalInteger", "fastMathMode")])); - Info.Add(new(Op.OpDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalInteger", "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "additionalInteger2", "linkageType")])); - Info.Add(new(Op.OpDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "inputAttachmentIndex")])); - Info.Add(new(Op.OpDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "alignment")])); - Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "maxByteOffset")])); - Info.Add(new(Op.OpDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "alignmentId")])); - Info.Add(new(Op.OpDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "maxByteOffsetId")])); - Info.Add(new(Op.OpDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "viewportIndex")])); - Info.Add(new(Op.OpDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "counterBufferId")])); - Info.Add(new(Op.OpDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "additionalInteger", "functionParameterAttribute")])); - Info.Add(new(Op.OpDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalString", "semanticName")])); + readonly Dictionary Info = []; - Info.Add(new(Op.OpMemberDecorate, Decoration.SpecId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "specId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.ArrayStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "arrayStride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MatrixStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "matrixStride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.BuiltIn), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.BuiltIn, OperandQuantifier.One, "additionalInteger", "builtin")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.UniformId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "scopeId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Stream), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "streamNumber")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Location), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "location")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Index), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "index")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.DescriptorSet), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "descriptorSet")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Offset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "offset")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.XfbBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "bufferNumber")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.XfbStride), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "stride")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FPRoundingMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPRoundingMode, OperandQuantifier.One, "additionalInteger", "roundingMode")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FPFastMathMode), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FPFastMathMode, OperandQuantifier.One, "additionalInteger", "fastMathMode")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.LinkageAttributes), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalInteger", "name"), new(OperandKind.LinkageType, OperandQuantifier.One, "additionalInteger2", "linkageType")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.InputAttachmentIndex), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "inputAttachmentIndex")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.Alignment), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "alignment")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffset), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "maxByteOffset")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.AlignmentId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "alignmentId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.MaxByteOffsetId), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "maxByteOffsetId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.SecondaryViewportRelativeNV), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "additionalInteger", "viewportIndex")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.CounterBuffer), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.IdRef, OperandQuantifier.One, "additionalInteger", "counterBufferId")])); - Info.Add(new(Op.OpMemberDecorate, Decoration.FuncParamAttr), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.FunctionParameterAttribute, OperandQuantifier.One, "additionalInteger", "functionParameterAttribute")])); - Info.Add(new(Op.OpMemberDecorateString, Decoration.UserSemantic), new(null, [new(OperandKind.IdRef, OperandQuantifier.One, "target"), new(OperandKind.LiteralInteger, OperandQuantifier.One, "accessor"), new(OperandKind.Decoration, OperandQuantifier.One, "decoration"), new(OperandKind.LiteralString, OperandQuantifier.One, "additionalString", "semanticName")])); - - } /// /// Register information about a SPIR-V instruction /// @@ -83,55 +26,22 @@ public partial class InstructionInfo /// /// /// - internal void Register(OperandKey op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null) + internal void Register(Op op, OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? spvClass = null, OperandParameters? parameters = null) { if (Info.TryGetValue(op, out var list)) - list.Add(new(kind, quantifier, name)); + list.Add(new(name, kind, quantifier, parameters ?? [])); else - Info.Add(op, new(spvClass, [new(kind, quantifier, name)])); + Info.Add(op, new(spvClass, [new(name, kind, quantifier, parameters ?? [])])); } + public static LogicalOperandArray GetInfo(Op op) + => Instance.Info[op]; + public static LogicalOperandArray GetInfo(Span words) + => GetInfo((Op)(words[0] & 0xFFFF)); - - public static LogicalOperandArray GetInfo(Op op, Decoration? decoration = null) - => GetInfo(new OperandKey(op, decoration)); - - /// - /// Gets information for the instruction operation. - /// - /// - /// - public static LogicalOperandArray GetInfo(OperandKey op) - { - if (op.Decoration is not null && !Instance.Info.ContainsKey(op)) - return Instance.Info[op with { Decoration = null }]; - return Instance.Info[op]; - } - - public static LogicalOperandArray GetInfo(Instruction instruction) - { - Decoration? decoration = instruction.OpCode switch - { - Op.OpDecorateString - or Op.OpDecorate - or Op.OpDecorateId => (Decoration)instruction.Operands[1], - Op.OpMemberDecorate - or Op.OpMemberDecorateString => (Decoration)instruction.Operands[2], - _ => null - }; - return GetInfo(new OperandKey(instruction.OpCode, decoration)); - } + public static LogicalOperandArray GetInfo(Instruction instruction) + => GetInfo(instruction.Words); + public static LogicalOperandArray GetInfo(OpData instruction) - { - Decoration? decoration = instruction.Op switch - { - Op.OpDecorateString - or Op.OpDecorate - or Op.OpDecorateId => (Decoration)instruction.Memory.Span[1], - Op.OpMemberDecorate - or Op.OpMemberDecorateString => (Decoration)instruction.Memory.Span[2], - _ => null - }; - return GetInfo(new OperandKey(instruction.Op, decoration)); - } -} + => GetInfo(instruction.Op); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs index 53b629fef8..1589d18398 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs @@ -14,7 +14,7 @@ public enum OperandWordSize Variable, Rest } -public readonly partial struct LogicalOperand +public readonly partial record struct LogicalOperand { public int GetWordSize() { diff --git a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs index 7d2d45bf52..35fb0b15b4 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs @@ -1,35 +1,24 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Text; using System.Threading.Tasks; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core; + +public record struct ParameterizedOperand(string? Name, OperandKind Kind); +public readonly record struct ParameterizedOperandKey(OperandKind Kind, int Value); + +public class OperandParameters : Dictionary; + /// /// Information on SPIR-V instruction operands /// -public readonly partial struct LogicalOperand +public readonly partial record struct LogicalOperand(string? Name, OperandKind? Kind, OperandQuantifier? Quantifier, OperandParameters Parameters) { - public string? Name { get; init; } - public string? DecorationName { get; init; } - public OperandKind? Kind { get; init; } - public OperandQuantifier? Quantifier { get; init; } - - public LogicalOperand() { } - - public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null, string? decorationName = null) - { - Name = name; - Kind = kind; - DecorationName = decorationName; - Quantifier = quantifier; - } - public LogicalOperand(string kind, string quantifier, string? name = null, string? decorationName = null) - { - Name = name; - Kind = Enum.Parse(kind); - DecorationName = decorationName; - Quantifier = Enum.Parse(quantifier); - } -} + public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null) : this(name, kind, quantifier, []) { } + public LogicalOperand(string kind, string quantifier, string? name = null) : this(name, Enum.Parse(kind), Enum.Parse(quantifier), []) { } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs index 66210296b5..bbb17f2a3d 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs @@ -14,9 +14,7 @@ public readonly struct LogicalOperandArray(string? className, List LogicalOperands { get; } = operands ?? []; public int Count => LogicalOperands.Count; - - public bool IsReadOnly => false; - + public LogicalOperand this[int index] { get => LogicalOperands[index]; diff --git a/src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs b/src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs new file mode 100644 index 0000000000..0cf9a891b1 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs @@ -0,0 +1,23 @@ +using System.Reflection.Metadata; +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core; + +public record struct ParameterizedFlag(T Value, MemoryOwner Parameters) : IDisposable + where T : Enum +{ + public readonly Span Span => Parameters.Span; + public ParameterizedFlag(T value, ReadOnlySpan parameters) + : this(value, MemoryOwner.Allocate(parameters.Length)) + { + parameters.CopyTo(Parameters.Span); + } + public readonly void Dispose() => Parameters.Dispose(); + public readonly Span.Enumerator GetEnumerator() => Parameters.Span.GetEnumerator(); + public static implicit operator ParameterizedFlag(T value) => new(value, MemoryOwner.Empty); + + public readonly override string ToString() + { + return $"{Value}"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 525f9fceda..edb55260fc 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -1,3 +1,5 @@ +using System.Reflection.Metadata.Ecma335; +using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Core.Parsing; @@ -13,27 +15,15 @@ public ref struct OpDataEnumerator readonly LogicalOperandArray logicalOperands; int wid; int oid; + int pid; + int startOperand; public OpDataEnumerator(Span instruction) { this.instruction = instruction; - - Decoration? decoration = null; - switch (OpCode) - { - case Op.OpDecorate: - case Op.OpDecorateId: - case Op.OpDecorateString: - decoration = (Decoration)instruction[2]; - break; - case Op.OpMemberDecorate: - case Op.OpMemberDecorateString: - decoration = (Decoration)instruction[3]; - break; - } - - logicalOperands = InstructionInfo.GetInfo(new OperandKey(OpCode, decoration)); + logicalOperands = InstructionInfo.GetInfo(instruction); oid = -1; + pid = -1; wid = 0; } @@ -51,67 +41,38 @@ public bool MoveNext() else { var logOp = logicalOperands[oid]; - (bool result, int newWid, int newOid) = OpCode switch + (int newWid, int newOid, int newPid, startOperand) = logOp switch { - Op.OpDecorate => oid switch - { - 0 => (true, wid + 1, oid + 1), - _ => (Decoration)Operands[wid] switch + { Parameters: OperandParameters { Count: > 0 } p } when pid == -1 && p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && p[new(logOp.Kind ?? OperandKind.None, Operands[wid])].Length > 0 => + (wid + 1, oid, 0, wid), + { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => + p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch { - Decoration.BuiltIn - or Decoration.Location - or Decoration.SpecId - or Decoration.ArrayStride - or Decoration.MatrixStride - or Decoration.UniformId - or Decoration.Stream - or Decoration.Component - or Decoration.Index - or Decoration.Binding - or Decoration.DescriptorSet - or Decoration.Offset - or Decoration.XfbBuffer - or Decoration.XfbStride - or Decoration.FuncParamAttr - or Decoration.FPRoundingMode - or Decoration.FPFastMathMode - or Decoration.InputAttachmentIndex - or Decoration.Alignment - or Decoration.MaxByteOffset - or Decoration.AlignmentId - or Decoration.MaxByteOffsetId - or Decoration.SecondaryViewportRelativeNV - or Decoration.CounterBuffer => (true, wid + 1, oid + 1), - Decoration.LinkageAttributes => throw new NotImplementedException(), - _ => (false, wid, oid) - } - }, - _ => logOp switch - { - { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => (true, wid + 2, oid + 1), - { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => (true, wid + Operands[wid..].LengthOfString(), oid + 1), - { Quantifier: OperandQuantifier.One, Kind: _ } => (true, wid + 1, oid + 1), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => (wid < Operands.Length - 2, wid + (wid < Operands.Length - 2 ? 2 : 0), oid + (wid < Operands.Length - 2 ? 1 : 0)), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } - => (wid < Operands.Length - 1, wid + (wid < Operands.Length - 1 ? Operands[wid..].LengthOfString() : 0), oid + (wid < Operands.Length ? 1 : 0)), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } - => (wid < Operands.Length - 1, wid + (wid < Operands.Length ? 1 : 0), oid + (wid < Operands.Length ? 1 : 0)), - { Quantifier: OperandQuantifier.ZeroOrMore } - => (wid < Operands.Length - 1, wid < Operands.Length - 1 ? Operands.Length : wid, oid + (wid < Operands.Length - 1 ? 0 : 1)), - _ => (false, wid, oid) - } + { Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } => (wid + 2, oid, pid + 1, startOperand), + { Kind: OperandKind.LiteralString } => (wid + Operands[wid..].LengthOfString(), oid, pid + 1, startOperand), + { Kind: _ } => (wid + 1, oid, pid + 1, startOperand) + }, + { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => (wid + 2, oid + 1, -1, -1), + { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => (wid + Operands[wid..].LengthOfString(), oid + 1, -1, -1), + { Quantifier: OperandQuantifier.One, Kind: _ } => (wid + 1, oid + 1, -1, -1), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => (wid + (wid < Operands.Length - 2 ? 2 : 0), oid + (wid < Operands.Length - 2 ? 1 : 0), -1, -1), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } + => (wid + (wid < Operands.Length - 1 ? Operands[wid..].LengthOfString() : 0), oid + (wid < Operands.Length ? 1 : 0), -1, -1), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } + => (wid + (wid < Operands.Length ? 1 : 0), oid + (wid < Operands.Length ? 1 : 0), -1, -1), + { Quantifier: OperandQuantifier.ZeroOrMore } + => (wid < Operands.Length - 1 ? Operands.Length : wid, oid + (wid < Operands.Length - 1 ? 0 : 1), -1, -1), + _ => throw new NotImplementedException($"Couldn't handle operand {logOp}") }; wid = newWid; oid = newOid; - if (oid < logicalOperands.Count) - return logicalOperands[oid].Quantifier switch - { - OperandQuantifier.One => result && wid < Operands.Length && oid < logicalOperands.Count, - _ => result && oid < logicalOperands.Count - }; - else return false; + pid = newPid; + // Reasons to return false : + // - no operands left + // - current operand has no kind (i.e. None) + return !(wid >= Operands.Length || oid >= logicalOperands.Count); } } @@ -119,68 +80,36 @@ public SpvOperand ParseCurrent() { var logOp = logicalOperands[oid]; - return OpCode switch + return logOp switch { - Op.OpDecorate => oid switch + { Parameters: OperandParameters { Count: > 0 } } when pid == -1 => + new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[startOperand])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => + p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch { - 0 => new(logOp.Name, OperandKind.IdRef, OperandQuantifier.One, Operands.Slice(wid, 1)), - 1 => new(logOp.Name, OperandKind.Decoration, OperandQuantifier.One, Operands.Slice(wid, 1)), - 2 => new SpvOperand() with - { - Kind = (Decoration)Operands[1] switch - { - Decoration.BuiltIn => OperandKind.BuiltIn, - Decoration.Location => OperandKind.LiteralInteger, - Decoration.SpecId => OperandKind.LiteralSpecConstantOpInteger, - Decoration.ArrayStride => OperandKind.LiteralInteger, - Decoration.MatrixStride => OperandKind.LiteralInteger, - Decoration.UniformId => OperandKind.IdScope, - Decoration.Stream => OperandKind.LiteralInteger, - Decoration.Component => OperandKind.LiteralInteger, - Decoration.Index => OperandKind.LiteralInteger, - Decoration.Binding => OperandKind.LiteralInteger, - Decoration.DescriptorSet => OperandKind.LiteralInteger, - Decoration.Offset => OperandKind.LiteralInteger, - Decoration.XfbBuffer => OperandKind.LiteralInteger, - Decoration.XfbStride => OperandKind.LiteralInteger, - Decoration.FuncParamAttr => OperandKind.FunctionParameterAttribute, - Decoration.FPRoundingMode => OperandKind.FPRoundingMode, - Decoration.FPFastMathMode => OperandKind.FPFastMathMode, - Decoration.LinkageAttributes => OperandKind.LiteralString, - Decoration.InputAttachmentIndex => OperandKind.LiteralInteger, - Decoration.Alignment => OperandKind.LiteralInteger, - Decoration.MaxByteOffset => OperandKind.LiteralInteger, - Decoration.AlignmentId => OperandKind.IdRef, - Decoration.MaxByteOffsetId => OperandKind.IdRef, - Decoration.SecondaryViewportRelativeNV => OperandKind.LiteralInteger, - Decoration.CounterBuffer => OperandKind.IdRef, - _ => OperandKind.None - }, - Quantifier = OperandQuantifier.One, - Words = Operands.Slice(wid, 1) - }, - _ => throw new NotImplementedException() + { Name: string n, Kind: OperandKind k } when k.ToString().StartsWith("Pair") => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + { Name: string n, Kind: OperandKind.LiteralString } => new(n, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + { Name: string n, Kind: OperandKind k } => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + _ => throw new NotImplementedException($"Couldn't handle operand kind {logOp.Kind}") }, - _ => logOp switch - { - { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } l - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), - { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), - { Quantifier: OperandQuantifier.One, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } - => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), - { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands.Slice(wid, 1) : []), - { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), - { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } - => throw new Exception("params of strings is not yet implemented"), - { Quantifier: OperandQuantifier.ZeroOrMore, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), - _ => throw new NotImplementedException() - } + { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } l + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + { Quantifier: OperandQuantifier.One, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } + => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands.Slice(wid, 1) : []), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } + => throw new Exception("params of strings is not yet implemented"), + { Quantifier: OperandQuantifier.ZeroOrMore, Kind: _ } + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), + _ => throw new NotImplementedException() + }; } diff --git a/src/Stride.Shaders.Spirv.Generators/Data.cs b/src/Stride.Shaders.Spirv.Generators/Data.cs index 5f615e29db..b191e1dba4 100644 --- a/src/Stride.Shaders.Spirv.Generators/Data.cs +++ b/src/Stride.Shaders.Spirv.Generators/Data.cs @@ -53,6 +53,16 @@ public override void Write(Utf8JsonWriter writer, EquatableDictionary? Capabilities { get; set; } + [JsonPropertyName("parameters")] + public EquatableList? Parameters { get; set; } [JsonPropertyName("version")] public string Version { get; set; } } @@ -89,6 +101,7 @@ public record struct OperandData public string? Class { get; set; } public string? TypeName { get; set; } public bool IsIndexKnown { get; set; } + public bool IsParameterized { get; set; } } public record struct InstructionData diff --git a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json deleted file mode 100644 index 38d12b30f6..0000000000 --- a/src/Stride.Shaders.Spirv.Generators/Extensions/spirv.sdsl.grammar-ext.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "instructions": [ - { - "opname": "OpSDSLShader", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "shaderName" - } - ] - }, - { - "opname": "OpSDSLShaderEnd", - "class": "Miscellaneous" - }, - { - "opname": "OpSDSLMixinInherit", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdRef", - "name": "shader" - } - ] - }, - { - "opname": "OpSDSLCompose", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixin" - }, - { - "kind": "LiteralString", - "name": "name" - } - ] - }, - { - "opname": "OpSDSLStage", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdRef", - "name": "stagedElement" - } - ] - }, - { - "opname": "OpSDSLImportShader", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdResult" - }, - { - "kind": "LiteralString", - "name": "shaderName" - } - ] - }, - { - "opname": "OpSDSLImportFunction", - "class": "Miscellaneous", - "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { - "kind": "LiteralString", - "name": "functionName" - }, - { - "kind": "IdRef", - "name": "shader" - } - ] - }, - { - "opname": "OpSDSLImportVariable", - "class": "Miscellaneous", - "operands": [ - { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { - "kind": "LiteralString", - "name": "variableName" - }, - { - "kind": "IdRef", - "name": "shader" - } - ] - } - ], - "operand_kinds": [ - { - "kind": "ExecutionModel", - "enumerants": [ - { - "enumerant": "Mixin", - "value": 5367 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Range.cs b/src/Stride.Shaders.Spirv.Generators/Range.cs new file mode 100644 index 0000000000..d1a283481e --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/Range.cs @@ -0,0 +1,268 @@ +// https://github.com/dotnet/runtime/blob/419e949d258ecee4c40a460fb09c66d974229623/src/libraries/System.Private.CoreLib/src/System/Index.cs +// https://github.com/dotnet/runtime/blob/419e949d258ecee4c40a460fb09c66d974229623/src/libraries/System.Private.CoreLib/src/System/Range.cs + +using System.Runtime.CompilerServices; + +namespace System +{ + /// Represent a type can be used to index a collection either from the start or the end. + /// + /// Index is used by the C# compiler to support the new index syntax + /// + /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; + /// int lastElement = someArray[^1]; // lastElement = 5 + /// + /// + internal readonly struct Index : IEquatable + { + private readonly int _value; + + /// Construct an Index using a value and indicating if the index is from the start or from the end. + /// The index value. it has to be zero or positive number. + /// Indicating if the index is from the start or from the end. + /// + /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Index(int value, bool fromEnd = false) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + if (fromEnd) + _value = ~value; + else + _value = value; + } + + // The following private constructors mainly created for perf reason to avoid the checks + private Index(int value) + { + _value = value; + } + + /// Create an Index pointing at first element. + public static Index Start => new(0); + + /// Create an Index pointing at beyond last element. + public static Index End => new(~0); + + /// Create an Index from the start at the position indicated by the value. + /// The index value from the start. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Index FromStart(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(value); + } + + /// Create an Index from the end at the position indicated by the value. + /// The index value from the end. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Index FromEnd(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(~value); + } + + /// Returns the index value. + public int Value + { + get + { + if (_value < 0) + { + return ~_value; + } + else + { + return _value; + } + } + } + + /// Indicates whether the index is from the start or the end. + public bool IsFromEnd => _value < 0; + + /// Calculate the offset from the start using the giving collection length. + /// The length of the collection that the Index will be used with. length has to be a positive value + /// + /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values. + /// we don't validate either the returned offset is greater than the input length. + /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and + /// then used to index a collection will get out of range exception which will be same affect as the validation. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetOffset(int length) + { + var offset = _value; + if (IsFromEnd) + { + // offset = length - (~value) + // offset = length + (~(~value) + 1) + // offset = length + value + 1 + + offset += length + 1; + } + return offset; + } + + /// Indicates whether the current Index object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => value is Index index && _value == index._value; + + /// Indicates whether the current Index object is equal to another Index object. + /// An object to compare with this object + public bool Equals(Index other) => _value == other._value; + + /// Returns the hash code for this instance. + public override int GetHashCode() => _value; + + /// Converts integer number to an Index. + public static implicit operator Index(int value) => FromStart(value); + + /// Converts the value of the current Index object to its equivalent string representation. + public override string ToString() + { + if (IsFromEnd) + return "^" + ((uint)Value).ToString(); + + return ((uint)Value).ToString(); + } + } + + /// Represent a range has start and end indexes. + /// + /// Range is used by the C# compiler to support the range syntax. + /// + /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 }; + /// int[] subArray1 = someArray[0..2]; // { 1, 2 } + /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } + /// + /// + /// Construct a Range object using the start and end indexes. + /// Represent the inclusive start index of the range. + /// Represent the exclusive end index of the range. + internal readonly struct Range(Index start, Index end) : IEquatable + { + /// Represent the inclusive start index of the Range. + public Index Start { get; } = start; + + /// Represent the exclusive end index of the Range. + public Index End { get; } = end; + + /// Indicates whether the current Range object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => + value is Range r && + r.Start.Equals(Start) && + r.End.Equals(End); + + /// Indicates whether the current Range object is equal to another Range object. + /// An object to compare with this object + public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End); + + /// Returns the hash code for this instance. + public override int GetHashCode() + { + return Start.GetHashCode() * 31 + End.GetHashCode(); + } + + /// Converts the value of the current Range object to its equivalent string representation. + public override string ToString() + { + return Start + ".." + End; + } + + /// Create a Range object starting from start index to the end of the collection. + public static Range StartAt(Index start) => new(start, Index.End); + + /// Create a Range object starting from first element in the collection to the end Index. + public static Range EndAt(Index end) => new(Index.Start, end); + + /// Create a Range object starting from first element to the end. + public static Range All => new(Index.Start, Index.End); + + /// Calculate the start offset and length of range object using a collection length. + /// The length of the collection that the range will be used with. length has to be a positive value. + /// + /// For performance reason, we don't validate the input length parameter against negative values. + /// It is expected Range will be used with collections which always have non negative length/count. + /// We validate the range is inside the length scope though. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public (int Offset, int Length) GetOffsetAndLength(int length) + { + int start; + var startIndex = Start; + if (startIndex.IsFromEnd) + start = length - startIndex.Value; + else + start = startIndex.Value; + + int end; + var endIndex = End; + if (endIndex.IsFromEnd) + end = length - endIndex.Value; + else + end = endIndex.Value; + + if ((uint)end > (uint)length || (uint)start > (uint)end) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + return (start, end - start); + } + } +} + +namespace System.Runtime.CompilerServices +{ + internal static class RuntimeHelpers + { + /// + /// Slices the specified array using the specified range. + /// + public static T[] GetSubArray(T[] array, Range range) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + (int offset, int length) = range.GetOffsetAndLength(array.Length); + + if (default(T) != null || typeof(T[]) == array.GetType()) + { + // We know the type of the array to be exactly T[]. + + if (length == 0) + { + return []; + } + + var dest = new T[length]; + Array.Copy(array, offset, dest, 0, length); + return dest; + } + else + { + // The array is actually a U[] where U:T. + var dest = (T[])Array.CreateInstance(array.GetType().GetElementType(), length); + Array.Copy(array, offset, dest, 0, length); + return dest; + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index bdd835c82e..9f309ef9ba 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -104,6 +104,8 @@ public static void PreProcessOperands(InstructionData op, Dictionary enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) + e.IsParameterized = true; operands[i] = e; } } @@ -279,5 +281,7 @@ public static string ConvertOperandName(string input, string? quant = null, bool (string v, _) => v }; } + static string LowerFirst(string s) + => char.IsLower(s[0]) ? s : $"{char.ToLowerInvariant(s[0])}{s[1..]}"; } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index b5e294497f..6de07d88be 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -54,7 +54,7 @@ public SpirvGrammar PreProcessGrammar(ImmutableArray files, Canc { grammarKinds[pk.Key].Enumerants?.AsList()?.AddRange(pk.Value.Enumerants?.AsList() ?? []); if (grammarKinds[pk.Key].Category is null || grammarKinds[pk.Key].Category.Length == 0) - grammarKinds[pk.Key] = grammarKinds[pk.Key] with { Category = pk.Value.Category}; + grammarKinds[pk.Key] = grammarKinds[pk.Key] with { Category = pk.Value.Category }; } else grammarKinds[pk.Key] = pk.Value; @@ -66,6 +66,52 @@ public SpirvGrammar PreProcessGrammar(ImmutableArray files, Canc return grammar; } + public SpirvGrammar PreProcessEnumerants(SpirvGrammar grammar, CancellationToken _) + { + if (grammar.OperandKinds?.AsDictionary() is Dictionary dict) + { + foreach (var opkind in dict.Values) + { + if (opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(e => e.Parameters?.AsList() is List { Count: > 0 })) + { + for (int i = 0; i < enumerants.Count; i++) + { + var enumerant = enumerants[i]; + var buffer = new List<(string, string)>(24); + if (enumerant.Parameters?.AsList() is List parameters) + { + for (int j = 0; j < parameters.Count; j++) + { + var param = parameters[j]; + param.Name = param.Name switch + { + string s when s.Any(char.IsPunctuation) => LowerFirst(string.Join("", s.Where(char.IsLetterOrDigit))), + null or "" => $"{KindToVariableName(param.Kind)}{j}", + _ => $"parameter{j}" + }; + param.CSType = param.Kind switch + { + "LiteralInteger" => "int", + "LiteralContextDependentNumber" => "int", + "LiteralString" => "string", + string s when s.StartsWith("Id") => "int", + string s => dict[s].Category switch + { + "BitEnum" => $"{param.Kind}Mask", + _ => param.Kind + }, + _ => throw new NotImplementedException($"Type {param.Kind} not implemented for parameterized flag generation"), + }; + parameters[j] = param; + } + } + } + } + } + } + return grammar; + } + public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationToken _) { var config = Configuration.Default.WithDefaultLoader(); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 157075ebc9..84383ef81f 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -1,42 +1,88 @@ using Microsoft.CodeAnalysis; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; using System.Text; -using System.Threading.Tasks; -using System.IO; -using System.Reflection; -using System.Text.Json; -using System.Security.Claims; -using System.Runtime.InteropServices.ComTypes; using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.CSharp; +using System; namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator { + public void CreateParameterizedFuncs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) + { + context.RegisterImplementationSourceOutput( + grammarProvider, + GenerateParameterizedFunctions + ); + } public void CreateInfo(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { GenerateKinds(context, grammarProvider); - - IncrementalValueProvider> infoProvider = - grammarProvider - .SelectMany(static (grammar, _) => grammar.Instructions!.Value) - .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) - .Collect() - .Select(static (arr, _) => new EquatableList([.. arr])); - context.RegisterImplementationSourceOutput( - infoProvider, + grammarProvider, GenerateInstructionInformation ); } - static void GenerateInstructionInformation(SourceProductionContext spc, EquatableList instructions) + + public void GenerateParameterizedFunctions(SourceProductionContext context, SpirvGrammar grammar) + { + if (grammar.OperandKinds?.AsDictionary() is Dictionary dict) + { + var code = new StringBuilder(); + code.AppendLine(@" + using static Stride.Shaders.Spirv.Specification; + namespace Stride.Shaders.Spirv.Core; + + public static class ParameterizedFlags + {" + ); + var selection = + dict.Values + .Where(enumeration => enumeration.Enumerants?.AsList() is List { Count: > 0 } l && l.Any(e => e.Parameters?.AsList() is List { Count: > 0 })) + .SelectMany(enumeration => (enumeration.Enumerants?.AsList() ?? []).Select(e => (enumeration.Kind, e))) + .Where(x => x.e.Parameters?.AsList() is List { Count: > 0 }); + foreach (var (kind, enumerant) in selection) + { + var realKind = kind; + if (dict[kind].Category is "BitEnum") + realKind = $"{kind}Mask"; + code.Append($"public static ParameterizedFlag<{realKind}> {kind}{enumerant.Name}("); + foreach (var param in enumerant.Parameters?.AsList() ?? []) + { + code.Append($"{param.CSType} {param.Name}"); + if (param != enumerant.Parameters?.AsList()?.Last()) + code.Append(", "); + } + code.AppendLine(")") + .Append($" => new ParameterizedFlag<{realKind}>({realKind}.{enumerant.Name}, [{ + string.Join(", ", (enumerant.Parameters?.AsList() ?? []).Select(x => x.CSType switch + { + "float" => $"BitConverter.SingleToInt32({x.Name})", + "string" => $".. {x.Name}.AsDisposableLiteralValue().Words", + "int" => x.Name, + _ => $"(int){x.Name}", + + })) + }]);"); + } + code.AppendLine("}"); + context.AddSource( + "ParameterizedFlags.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + + } + static void GenerateInstructionInformation(SourceProductionContext spc, SpirvGrammar grammar) { var code = new StringBuilder(); code @@ -49,8 +95,10 @@ public partial class InstructionInfo static InstructionInfo() {" ); - foreach (var instruction in instructions) - GenerateInfo(instruction, code); + if (grammar.Instructions?.AsList() is List instructions) + foreach (var instruction in instructions) + if (!instruction.OpName.Contains("GLSL")) + GenerateInfo(instruction, code, grammar); code.AppendLine("Instance.InitOrder();}}"); spc.AddSource( @@ -82,9 +130,9 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In .AppendLine("public enum OperandKind") .AppendLine("{") .AppendLine(" None,"); - if(kinds.AsDictionary() is Dictionary dict) - foreach (var kind in dict.Values) - builder.AppendLine($" {kind.Kind},"); + if (kinds.AsDictionary() is Dictionary dict) + foreach (var kind in dict.Values) + builder.AppendLine($" {kind.Kind},"); builder .AppendLine("}"); spc.AddSource("OperandKind.gen.cs", builder.ToString()); @@ -110,62 +158,39 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In } - public static void GenerateInfo(InstructionData op, StringBuilder code) + public static void GenerateInfo(InstructionData op, StringBuilder code, SpirvGrammar grammar) { var opname = op.OpName; var spvClass = op.Class; - if (opname == "OpExtInst") - { - code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, \"resultType\", \"GLSL\");"); - code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, \"resultId\", \"GLSL\");"); - code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, \"set\", \"GLSL\");"); - code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.LiteralInteger, OperandQuantifier.One, \"instruction\", \"GLSL\");"); - code.AppendLine("Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, \"values\", \"GLSL\");"); - } - else if (op.Operands is EquatableList operands) + if (op.Operands?.AsList() is List operands && grammar.OperandKinds?.AsDictionary() is Dictionary dict) { foreach (var operand in operands) { - // var hasKind = operand.Kind; - // var hasQuant = operand.Quantifier; - // var hasName = operand.Name; - if (operand.Kind is string kind) + code.Append($"Instance.Register(Op.{opname}, OperandKind.{operand.Kind ?? ""}, OperandQuantifier.{operand.Quantifier switch { "*" => "ZeroOrMore", "?" => "ZeroOrOne", _ => "One" }}, \"{operand.Name}\", \"{spvClass ?? "Debug"}\""); + if (dict.TryGetValue(operand.Kind ?? throw new Exception("Operand is null in registering"), out var opkind) && opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) { - if (operand.Quantifier is string quant) - { - code - .Append("Instance.Register(Op.") - .Append(opname) - .Append(", OperandKind.") - .Append(kind) - .Append(", OperandQuantifier.") - .Append(ConvertQuantifier(quant)) - .Append(", ") - .Append(operand.Name is null ? $"\"{ConvertNameQuantToName(kind, quant)}\"" : $"\"{ConvertNameQuantToName(operand.Name, quant)}\"") - .Append($", \"{spvClass}\"") - .AppendLine(");"); - } - else - { - code - .Append("Instance.Register(Op.") - .Append(opname) - .Append(", OperandKind.") - .Append(kind) - .Append(", OperandQuantifier.One, ") - .Append(operand.Name is null ? $"\"{ConvertKindToName(kind)}\"" : $"\"{ConvertOperandName(operand.Name)}\"") - .Append($", \"{spvClass}\"") - .AppendLine(");"); - } - + // code.Append($", [{string.Join(", ", opkind.Enumerants?.Select(x => $"new({x.Name ?? "null"}, OperandKind.{x.})") ?? [])}]"); + code.Append(", new() {") + .Append( + string.Join( + ", ", + enumerants + .Where(e => e.Parameters?.AsList() is List { Count: > 0 }) + .Select( + enumerant => + $"[new(OperandKind.{operand.Kind}, {enumerant.Value})] = [{string.Join(", ", enumerant.Parameters?.AsList().Select(param => $"new(\"{param.Name ?? ConvertKindToName(param.Kind)}\", OperandKind.{param.Kind})") ?? [])}]" + ) + ) + ) + .Append("});"); } + else + code.AppendLine(", []);"); } } else - { code.Append("Instance.Register(Op.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); - } } -} +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 572e4b577f..1059879493 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -51,8 +51,8 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv if (instruction.OpName.EndsWith("Constant")) WriteConstantInstructions(grammar, instruction, builder, body1, body2, body3, body4); - else if (instruction.OpName.Contains("Decorate")) - WriteDecorateInstructions(grammar, instruction, builder, body1, body2, body3, body4); + // else if (instruction.OpName.Contains("Decorate")) + // WriteDecorateInstructions(grammar, instruction, builder, body1, body2, body3, body4); else if (instruction.OpName.StartsWith("OpCopyMemory")) WriteCopyMemoryInstructions(grammar, instruction, body1, body2, body3, body4); else if (instruction.OpName.Contains("GLSL")) @@ -72,31 +72,36 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv ); } + public static (string TypeName, string FieldName, string OperandName) ToTypeFieldAndOperandName(OperandData operand) { - string typename = (operand.Kind, operand.Quantifier, operand.Class) switch + string typename = (operand.Kind, operand.Quantifier, operand.Class, operand.IsParameterized) switch { - (string s, null or "", _) when s.StartsWith("Id") => "int", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", null or "", _) => "int", - ("LiteralFloat", null or "", _) => "float", - ("LiteralString", null or "", _) => "string", - (string s, null or "", _) when s.StartsWith("Pair") => "(int, int)", - (string s, null or "", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask", - (string s, null or "", "ValueEnum") when !s.StartsWith("Literal") => s, - (string s, "?", _) when s.StartsWith("Id") => "int?", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "?", _) => "int?", - ("LiteralFloat", "?", _) => "float?", - ("LiteralString", "?", _) => "string?", - (string s, "?", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask?", - (string s, "?", "ValueEnum") when !s.StartsWith("Literal") => $"{s}?", - (string s, "*", _) when s.StartsWith("Id") => $"LiteralArray", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "*", _) => "LiteralArray", - ("LiteralFloat", "*", _) => "LiteralArray", + (string s, null or "", "ValueEnum", true) => $"ParameterizedFlag<{s}>", + (string s, null or "", "BitEnum", true) => $"ParameterizedFlag<{s}Mask>", + (string s, null or "", _, false) when s.StartsWith("Id") => "int", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", null or "", _, false) => "int", + ("LiteralFloat", null or "", _, false) => "float", + ("LiteralString", null or "", _, false) => "string", + (string s, null or "", _, false) when s.StartsWith("Pair") => "(int, int)", + (string s, null or "", "BitEnum", false) when !s.StartsWith("Literal") => $"{s}Mask", + (string s, null or "", "ValueEnum", false) when !s.StartsWith("Literal") => s, + (string s, "?", "ValueEnum", true) => $"ParameterizedFlag<{s}>?", + (string s, "?", "BitEnum", true) => $"ParameterizedFlag<{s}Mask>?", + (string s, "?", _, false) when s.StartsWith("Id") => "int?", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "?", _, false) => "int?", + ("LiteralFloat", "?", _, false) => "float?", + ("LiteralString", "?", _, false) => "string?", + (string s, "?", "BitEnum", false) when !s.StartsWith("Literal") => $"{s}Mask?", + (string s, "?", "ValueEnum", false) when !s.StartsWith("Literal") => $"{s}?", + (string s, "*", _, false) when s.StartsWith("Id") => $"LiteralArray", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "*", _, false) => "LiteralArray", + ("LiteralFloat", "*", _, false) => "LiteralArray", // ("LiteralString", "*", _) => "LiteralArray", - (string s, "*", _) when s.StartsWith("Pair") => $"LiteralArray<(int, int)>", - (string s, "*", "BitEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}Mask>", - (string s, "*", "ValueEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}>", - ("LiteralContextDependentNumber", null or "", _) => "LiteralValue", + (string s, "*", _, false) when s.StartsWith("Pair") => $"LiteralArray<(int, int)>", + (string s, "*", "BitEnum", false) when !s.StartsWith("Literal") => $"LiteralArray<{s}Mask>", + (string s, "*", "ValueEnum", false) when !s.StartsWith("Literal") => $"LiteralArray<{s}>", + ("LiteralContextDependentNumber", null or "", _, false) => "LiteralValue", _ => throw new NotImplementedException($"Could not generate C# type for '{operand.Kind}{operand.Quantifier}'") }; @@ -127,15 +132,17 @@ public static (string TypeName, string FieldName, string OperandName) ToTypeFiel static string ToSpreadOperator(OperandData operand) { (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - return (operand.Class, operand.Quantifier) switch + return (operand.Class, operand.Quantifier, operand.IsParameterized) switch { - (string s, null or "") when s.Contains("Id") => $"{fieldName}", - (string s, "?") when s.Contains("Id") => $".. {fieldName} is null ? (Span)[] : [{fieldName}.Value]", - (string s, null or "") when s.Contains("Enum") => $"(int){fieldName}", - (string s, "?") when s.Contains("Enum") => $".. {fieldName} is null ? (Span)[] : [(int){fieldName}.Value]", - (string, "*") => $".. {fieldName}.Words", - (string, "?") => $".. {fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words", - (_, "?") => $".. {fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words", + (string s, null or "", false) when s.Contains("Id") => $"{fieldName}", + (string s, "?", false) when s.Contains("Id") => $".. ({fieldName} is null ? (Span)[] : [{fieldName}.Value])", + (string s, null or "", false) when s.Contains("Enum") => $"(int){fieldName}", + (string s, null or "", true) when s.Contains("Enum") => $".. (Span)[(int){fieldName}.Value, .. {fieldName}.Span]", + (string s, "?", false) when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value])", + (string s, "?", true) when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value.Value, .. {fieldName}.Value.Span])", + (string, "*", false) => $".. {fieldName}.Words", + (string, "?", false) => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", + (_, "?", false) => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", _ => $".. {fieldName}.AsDisposableLiteralValue().Words" }; } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 7e228325d4..4c55dda197 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -24,15 +24,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context) options.Converters.Add(new EquatableListJsonConverter()); if (!options.Converters.Any(x => x is EquatableListJsonConverter)) options.Converters.Add(new EquatableListJsonConverter()); - + if (!options.Converters.Any(x => x is EquatableListJsonConverter)) + options.Converters.Add(new EquatableListJsonConverter()); var grammarData = context .AdditionalTextsProvider .Where(IsSpirvSpecification) .Collect() .Select(PreProcessGrammar) + .Select(PreProcessEnumerants) .Select(PreProcessInstructions); + CreateParameterizedFuncs(context, grammarData); CreateInfo(context, grammarData); CreateSDSLOp(context, grammarData); GenerateStructs(context, grammarData); diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 88164d45a4..e854fb8ed9 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -18,7 +18,9 @@ public enum SymbolKind Composition, CBuffer, TBuffer, - RGroup + RGroup, + SamplerState, + SamplerComparisonState, } public enum Storage : ushort diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index d85d60ee85..d1b18eade2 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text; using Stride.Shaders.Spirv; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Core; @@ -16,17 +17,17 @@ public abstract record SymbolType() public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolType result) { - if(ScalarType.Types.TryGetValue(name, out var s)) + if (ScalarType.Types.TryGetValue(name, out var s)) { result = s; return true; } - else if(VectorType.Types.TryGetValue(name, out var v)) + else if (VectorType.Types.TryGetValue(name, out var v)) { result = v; return true; } - else if(MatrixType.Types.TryGetValue(name, out var m)) + else if (MatrixType.Types.TryGetValue(name, out var m)) { result = m; return true; @@ -42,6 +43,35 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT return false; } } + public static bool TryGetBufferType(string name, string? templateType, [MaybeNullWhen(false)] out SymbolType result) + { + (result, bool found) = (name, templateType) switch + { + ("Buffer", "float") => (new BufferType(ScalarType.From("float"), -1) as SymbolType, true), + ("Buffer", "int") => (new BufferType(ScalarType.From("int"), -1), true), + ("Buffer", "uint") => (new BufferType(ScalarType.From("uint"), -1), true), + ("Buffer", "float2") => (new BufferType(VectorType.From("float2"), -1), true), + ("Buffer", "float3") => (new BufferType(VectorType.From("float3"), -1), true), + ("Buffer", "float4") => (new BufferType(VectorType.From("float4"), -1), true), + ("Buffer", "int2") => (new BufferType(VectorType.From("int2"), -1), true), + ("Buffer", "int3") => (new BufferType(VectorType.From("int3"), -1), true), + ("Buffer", "int4") => (new BufferType(VectorType.From("int4"), -1), true), + ("Buffer", "uint2") => (new BufferType(VectorType.From("uint2"), -1), true), + ("Buffer", "uint3") => (new BufferType(VectorType.From("uint3"), -1), true), + ("Buffer", "uint4") => (new BufferType(VectorType.From("uint4"), -1), true), + ("Texture", null) => (new Texture1DType(VectorType.From("float4")), true), + ("Texture1D", null) => (new Texture1DType(VectorType.From("float4")), true), + ("Texture2D", null) => (new Texture2DType(VectorType.From("float4")), true), + ("Texture3D", null) => (new Texture3DType(VectorType.From("float4")), true), + ("Texture", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType)), true), + ("Texture1D", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType)), true), + ("Texture2D", "int4" or "uint4" or "float4") => (new Texture2DType(VectorType.From(templateType)), true), + ("Texture3D", "int4" or "uint4" or "float4") => (new Texture3DType(VectorType.From(templateType)), true), + + _ => (null, false) + }; + return found; + } } public sealed record UndefinedType(string TypeName) : SymbolType() @@ -63,7 +93,7 @@ public sealed partial record ScalarType(string TypeName) : SymbolType() public override string ToString() => TypeName; } public sealed partial record VectorType(ScalarType BaseType, int Size) : SymbolType() -{ +{ public override string ToString() => $"{BaseType}{Size}"; } public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Columns) : SymbolType() @@ -113,22 +143,39 @@ public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() public override string ToString() => $"Buffer<{BaseType}, {Size}>"; } +// TODO: Add sampler parameters +public sealed record SamplerType(string Name) : SymbolType() +{ + public override string ToId() => $"{Name}"; + public override string ToString() => $"SamplerState {Name}"; +} +public sealed record SampledImage(TextureType ImageType) : SymbolType() +{ + public override string ToString() => $"SampledImage<{ImageType}>"; +} + +public abstract record TextureType(SymbolType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() +{ + public override string ToId() => $"Texture_{ReturnType}"; + public override string ToString() => $"Texture<{ReturnType}>({Dimension}, {Depth}, {Arrayed}, {Multisampled}, {Sampled}, {Format})"; +} -public abstract record TextureType(SymbolType BaseType) : SymbolType() +public sealed record Texture1DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture<{BaseType}>"; + public override string ToString() => $"Texture1D<{ReturnType}>"; } -public sealed record Texture1DType(SymbolType BaseType, int Size) : TextureType(BaseType) +public sealed record Texture2DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture<{BaseType}, {Size}>"; + public override string ToString() => $"Texture2D<{ReturnType}>"; } -public sealed record Texture2DType(SymbolType BaseType, int Width, int Height) : TextureType(BaseType) +public sealed record Texture3DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture<{BaseType}, {Width}, {Height}>"; + public override string ToString() => $"Texture3D<{ReturnType}>"; } -public sealed record Texture3DType(SymbolType BaseType, int Width, int Height, int Depth) : TextureType(BaseType) + +public sealed record TextureCubeType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture<{BaseType}, {Width}, {Height}, {Depth}>"; + public override string ToString() => $"TextureCube<{ReturnType}>"; } public sealed record FunctionGroupType() : SymbolType(); @@ -137,7 +184,7 @@ public sealed record FunctionType(SymbolType ReturnType, List Parame { public bool Equals(FunctionType? other) { - if(other is null) + if (other is null) return false; if (ReturnType == null || other.ReturnType == null) return false; @@ -164,7 +211,7 @@ public override string ToId() for (int i = 0; i < ParameterTypes.Count; i++) { builder.Append(ParameterTypes[i].ToId()); - builder.Append('_'); + builder.Append('_'); } return builder.Append(ReturnType.ToId()).ToString(); } @@ -173,10 +220,10 @@ public override string ToString() { var builder = new StringBuilder(); builder.Append($"fn("); - for(int i = 0; i < ParameterTypes.Count; i++) + for (int i = 0; i < ParameterTypes.Count; i++) { builder.Append(ParameterTypes[i]); - if(i < ParameterTypes.Count - 1) + if (i < ParameterTypes.Count - 1) builder.Append('*'); } return builder.Append($")->{ReturnType}").ToString(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index c726a2bda9..caae2fa33f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -203,49 +203,87 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil result = Source.Compile(table, shader, compiler); currentValueType = Source.Type; } - - Span indexes = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i <= Accessors.Count; i++) + if (Source is Identifier { ValueType: TextureType or Texture2DType or Texture3DType } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) + { + result = Source.Compile(table, shader, compiler); + if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) + { + var samplerValue = implicitSampling.Parameters.Values[0].Compile(table, shader, compiler); + var texCoordValue = implicitSampling.Parameters.Values[1].Compile(table, shader, compiler); + var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); + var loadSampler = builder.Insert(new OpLoad(samplerValue.TypeId, context.Bound++, samplerValue.Id, Specification.MemoryAccessMask.None)); + var loadCoord = builder.Insert(new OpLoad(texCoordValue.TypeId, context.Bound++, texCoordValue.Id, Specification.MemoryAccessMask.None)); + var loadTexture = builder.Insert(new OpLoad(result.TypeId, context.Bound++, result.Id, Specification.MemoryAccessMask.None)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, loadTexture.ResultId, loadSampler.ResultId)); + var returnType = context.GetOrRegister(((TextureType)Source.ValueType).ReturnType); + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, loadCoord.ResultId, Specification.ImageOperandsMask.None)); + Type = ((TextureType)Source.ValueType).ReturnType; + return new(sample.ResultId, sample.ResultType); + } + else if (Accessors is [MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling]) + { + var samplerValue = explicitSampling.Parameters.Values[0].Compile(table, shader, compiler); + var texCoordValue = explicitSampling.Parameters.Values[1].Compile(table, shader, compiler); + var levelValue = explicitSampling.Parameters.Values[2].Compile(table, shader, compiler); + + var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); + var loadSampler = builder.Insert(new OpLoad(samplerValue.TypeId, context.Bound++, samplerValue.Id, Specification.MemoryAccessMask.None)); + var loadCoord = builder.Insert(new OpLoad(texCoordValue.TypeId, context.Bound++, texCoordValue.Id, Specification.MemoryAccessMask.None)); + var loadTexture = builder.Insert(new OpLoad(result.TypeId, context.Bound++, result.Id, Specification.MemoryAccessMask.None)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, loadTexture.ResultId, loadSampler.ResultId)); + var returnType = context.GetOrRegister(((TextureType)Source.ValueType).ReturnType); + var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, loadCoord.ResultId, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); + Type = ((TextureType)Source.ValueType).ReturnType; + return new(sample.ResultId, sample.ResultType); + } + else + throw new InvalidOperationException("Invalid Sample method call"); + } + else { - // Last accessor (or method call next) - if (i == Accessors.Count || Accessors[i] is MethodCall) + Span indexes = stackalloc int[Accessors.Count]; + for (var i = firstIndex; i <= Accessors.Count; i++) { - // Do we need to issue an OpAccessChain? - if (i > firstIndex) + // Last accessor (or method call next) + if (i == Accessors.Count || Accessors[i] is MethodCall) { - var resultType = context.GetOrRegister(Type); - var accessChain = builder.Insert(new OpAccessChain(variable, resultType, result.Id, [.. indexes.Slice(firstIndex, i - firstIndex)])); - result = new SpirvValue(accessChain.ResultId, resultType); + // Do we need to issue an OpAccessChain? + if (i > firstIndex) + { + var resultType = context.GetOrRegister(Type); + var accessChain = builder.Insert(new OpAccessChain(variable, resultType, result.Id, [.. indexes.Slice(firstIndex, i - firstIndex)])); + result = new SpirvValue(accessChain.ResultId, resultType); + } + + if (i == Accessors.Count) + break; + + firstIndex = i + 1; } - if (i == Accessors.Count) - break; - - firstIndex = i + 1; - } + var accessor = Accessors[i]; + switch (currentValueType, accessor) + { + case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + methodCall2.MemberCall = result; + result = methodCall2.Compile(table, shader, compiler); + break; + case (PointerType { BaseType: StructType s }, Identifier field): + var index = s.TryGetFieldIndex(field); + if (index == -1) + throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); + indexLiteral.Compile(table, shader, compiler); + indexes[i] = context.CreateConstant(indexLiteral).Id; + break; + // TODO: Swizzle, etc. + default: + throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + } - var accessor = Accessors[i]; - switch (currentValueType, accessor) - { - case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): - methodCall2.MemberCall = result; - result = methodCall2.Compile(table, shader, compiler); - break; - case (PointerType { BaseType: StructType s }, Identifier field): - var index = s.TryGetFieldIndex(field); - if (index == -1) - throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); - //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.Compile(table, shader, compiler); - indexes[i] = context.CreateConstant(indexLiteral).Id; - break; - // TODO: Swizzle, etc. - default: - throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + currentValueType = accessor.Type; } - - currentValueType = accessor.Type; } Type = currentValueType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index c87dbdd245..dc0994df21 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -170,13 +170,13 @@ public override SymbolType GenerateType(SymbolTable table) { var result = TypeName.ResolveType(table); - var tmp = (Core.VectorType)result ?? throw new NotImplementedException(); + var tmp = (VectorType)result ?? throw new NotImplementedException(); foreach (var v in Values) { if ( v.Type is ScalarType st && tmp.BaseType != st - || (v.Type is Core.VectorType vt && vt.BaseType != tmp.BaseType) - || (v.Type is Core.VectorType vt2 && vt2.Size > tmp.Size) + || (v.Type is VectorType vt && vt.BaseType != tmp.BaseType) + || (v.Type is VectorType vt2 && vt2.Size > tmp.Size) ) table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); } @@ -304,7 +304,18 @@ public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolT symbolType = numeric; return true; } - + else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) + { + table.DeclaredTypes.Add(bufferType.ToString(), bufferType); + symbolType = bufferType; + return true; + } + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) + { + table.DeclaredTypes.Add(genericBufferType.ToString(), genericBufferType); + symbolType = genericBufferType; + return true; + } return false; } // else if (IsArray && Generics.Count == 0) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index e6a46c4422..ff586e5017 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -26,7 +26,7 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) - public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) { names = []; types = []; @@ -79,16 +79,16 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var innerType = types[pointerInstruction.Type]; types.Add(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); } - else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is {} voidInstruction) + else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is { } voidInstruction) { types.Add(voidInstruction.ResultId, ScalarType.From("void")); } - else if (instruction.Op == Op.OpTypeVector && (OpTypeVector)instruction is {} vectorInstruction) + else if (instruction.Op == Op.OpTypeVector && (OpTypeVector)instruction is { } vectorInstruction) { var innerType = (ScalarType)types[vectorInstruction.ComponentType]; types.Add(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); } - else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is {} typeStructInstruction) + else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { var structName = names[typeStructInstruction.ResultId]; var fieldsData = typeStructInstruction.Values; @@ -102,7 +102,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); } - else if (instruction.Op == Op.OpTypeFunction && (OpTypeFunction)instruction is {} typeFunctionInstruction) + else if (instruction.Op == Op.OpTypeFunction && (OpTypeFunction)instruction is { } typeFunctionInstruction) { var returnType = types[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); @@ -218,9 +218,9 @@ public void Compile(CompilerUnit compiler, SymbolTable table) { if (!svar.TypeName.TryResolveType(table, out var memberType)) { - memberType = LoadExternalShaderType(table, svar.TypeName.Name); - - table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); + memberType = LoadExternalShaderType(table, svar.TypeName.Name); + + table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); } svar.Type = new PointerType(memberType, Specification.StorageClass.Private); @@ -235,6 +235,11 @@ public void Compile(CompilerUnit compiler, SymbolTable table) //symbols.Add(symbol); } } + else if (member is ShaderSamplerState samplerState) + { + samplerState.Type = new SamplerType(samplerState.Name); + table.DeclaredTypes.Add(samplerState.Type.ToString(), samplerState.Type); + } } var currentShader = new ShaderSymbol(Name, symbols); @@ -285,6 +290,8 @@ public void Compile(CompilerUnit compiler, SymbolTable table) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); // In case calling a method not yet processed, we first register method types // (SPIR-V allow forward calling) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 911c3d6b4b..d30d766088 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -19,7 +19,7 @@ public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : } -public class SamplerStateAssign(Identifier name, Expression value, TextLocation info) : ShaderElement(info) +public class SamplerStateParameter(Identifier name, Expression value, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; public Expression Value { get; set; } = value; @@ -33,17 +33,42 @@ public override string ToString() public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; - public List Members { get; set; } = []; + public List Parameters { get; set; } = []; + + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + // TODO: sampler states with paramters not implemented + // The main issue is that SPIR-V doesn't have a direct equivalent of sampler states with parameters. + // We can create a basic sampler, but handling parameters would require a more complex approach, + // potentially storing parameters in a new SDSL specific instruction or decorations + + if (Parameters.Count > 0) + table.Errors.Add(new SemanticErrors(Info, "Sampler states with parameters are not supported in SPIR-V generation.")); + + (_, var context) = compiler; + Type = new PointerType(new SamplerType(Name), Specification.StorageClass.UniformConstant); + if (!table.RootSymbols.TryGetValue(Name, out _)) + { + context + .FluentAdd(new OpTypeSampler(context.Bound++), out var register) + .FluentAdd(new OpName(register.ResultId, Name), out _); + + var sid = new SymbolID(Name, SymbolKind.SamplerState); + var symbol = new Symbol(sid, Type, register.ResultId); + table.RootSymbols.Add(Name, symbol); + } + else throw new Exception($"SamplerState {Name} already defined"); + } public override string ToString() { - return $"SamplerState {Name} ({string.Join(", ", Members)})"; + return $"SamplerState {Name} ({string.Join(", ", Parameters)})"; } } public class ShaderSamplerComparisonState(Identifier name, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; - public List Members { get; set; } = []; + public List Members { get; set; } = []; public override string ToString() { @@ -92,7 +117,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpVariable(registeredType, variable, Specification.StorageClass.Private, null)); context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) - context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name)); context.AddName(variable, Name); var sid = @@ -207,7 +232,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = argSym; } - + var (builder, context) = compiler; if (Type is FunctionType ftype) { diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index ee5ffe99f9..92b03ad60e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -109,14 +109,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { parsed = new(identifier, scanner[position..scanner.Position]) { - Members = assignments + Parameters = assignments }; return true; } @@ -130,7 +130,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -141,7 +141,7 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateAssign(identifier, expression, scanner[position..scanner.Position]); + parsed = new SamplerStateParameter(identifier, expression, scanner[position..scanner.Position]); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -163,7 +163,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) @@ -184,7 +184,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateAssign parsed, in ParseError? orError = null) + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -195,7 +195,7 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateAssign(identifier, expression, scanner[position..scanner.Position]); + parsed = new SamplerStateParameter(identifier, expression, scanner[position..scanner.Position]); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index b1be4b92f4..08c02138c8 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -175,7 +175,11 @@ public int GetOrRegister(SymbolType? type) FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), ShaderSymbol s => RegisterShaderType(s), - // TextureSymbol t => Buffer.AddOpTypeImage(Bound++, Register(t.BaseType), t.), + Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, + SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; @@ -216,7 +220,7 @@ private int RegisterCBuffer(ConstantBufferSymbol cb) { if (index > 0) throw new NotImplementedException("Offset"); - Buffer.Add(new OpMemberDecorate(result, index, Decoration.Offset, 0)); + Buffer.Add(new OpMemberDecorate(result, index, ParameterizedFlags.DecorationOffset(0))); } return result; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 4db2f92a50..6e612bfed1 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -160,13 +160,17 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (instruction.Op == Op.OpDecorateString && ((OpDecorateString)instruction) is { - Decoration: Decoration.UserSemantic, Target: int t, - AdditionalString: string n + Decoration: + { + Value: Decoration.UserSemantic, + Parameters: { } m + } } ) { - semanticTable[t] = n; + using var n = new LiteralValue(m.Span); + semanticTable[t] = n.Value; } } } @@ -221,7 +225,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con if (stream.Value.Stream.Output) { - if (stream.Value.Stream.OutputLayoutLocation is {} outputLayoutLocation) + if (stream.Value.Stream.OutputLayoutLocation is { } outputLayoutLocation) { outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); } @@ -245,10 +249,10 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); if (stream.Value.Stream.InputLayoutLocation == null) stream.Value.Stream.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.InputLayoutLocation.Value)); + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.InputLayoutLocation.Value))); if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); inputStreams.Add((stream.Value.Stream, variable.ResultId)); } @@ -261,7 +265,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con if (stream.Value.Stream.Semantic?.ToUpperInvariant() == "SV_POSITION") { - context.Add(new OpDecorate(variable, Decoration.BuiltIn, (int)BuiltIn.Position)); + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); } else { @@ -274,9 +278,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Stream.Name}]"); } - context.Add(new OpDecorate(variable, Decoration.Location, stream.Value.Stream.OutputLayoutLocation.Value)); + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.OutputLayoutLocation.Value))); if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Stream.Semantic)); + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); } outputStreams.Add((stream.Value.Stream, variable.ResultId)); @@ -287,7 +291,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con // Add new entry point wrapper context.FluentAdd(new OpTypeFunction(context.Bound++, voidType, []), out var newEntryPointFunctionType); - buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType) , out var newEntryPointFunction); + buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); buffer.Add(new OpLabel(context.Bound++)); context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); @@ -305,7 +309,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var stream in outputStreams) { var baseType = ((PointerType)stream.Info.Type).BaseType; - buffer.FluentAdd(new OpLoad( context.Types[baseType], context.Bound++, stream.Info.VariableId, null), out var loadedValue); + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Info.VariableId, null), out var loadedValue); buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); } @@ -323,7 +327,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var block in analysisResult.Blocks) pvariables[pvariableIndex++] = block; - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [..pvariables])); + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables])); } return newEntryPointFunction; @@ -346,7 +350,7 @@ private void ProcessMethod(NewSpirvBuffer buffer, List callStack, int funct if (streams.TryGetValue(load.Pointer, out var streamInfo) && !streamInfo.Stream.Write) streamInfo.Stream.Read = true; } - else if(instruction.Op is Op.OpStore && (OpStore)instruction is { } store) + else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { if (streams.TryGetValue(store.Pointer, out var streamInfo)) streamInfo.Stream.Write = true; diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index f73e12f054..adc49e4667 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -4,7 +4,6 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; using System.Numerics; -using System.Reflection.Metadata.Ecma335; using System.Runtime.CompilerServices; using System.Text; using static Stride.Shaders.Spirv.Specification; @@ -13,33 +12,25 @@ namespace Stride.Shaders.Spirv.Tools; public static partial class Spv { - public enum DisassemblerFlags + public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = false) { - Id = 1, - Name = 2, - NameAndId = Name | Id, - InstructionIndex = 4, - } - - public static string Dis(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) - { - var writer = new DisWriter(buffer, flags, writeToConsole); + var writer = new DisWriter(buffer, useNames, writeToConsole); writer.Disassemble(); writer.ToString(); return writer.ToString(); } - public static string Dis(SpirvReader reader, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) + public static string Dis(SpirvReader reader, bool useNames = true, bool writeToConsole = false) { using var buffer = new NewSpirvBuffer(reader.Words); - var writer = new DisWriter(buffer, flags, writeToConsole); + var writer = new DisWriter(buffer, useNames, writeToConsole); writer.Disassemble(); return writer.ToString(); } - struct DisWriter(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) + struct DisWriter(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) { - DisData data = new(buffer, flags, writeToConsole); + DisData data = new(buffer, useNames, writeToConsole); readonly StringBuilder builder = new(); readonly DisWriter AppendLine(string text, ConsoleColor? color = null) @@ -74,17 +65,7 @@ readonly DisWriter Append(T text, ConsoleColor? color = null) readonly DisWriter AppendIdRef(int id, bool useNames = true) { if (data.UseNames && useNames && data.NameTable.TryGetValue(id, out var name)) - { - Append($"%{name}", ConsoleColor.Green); - if (data.UseIds) - { - Append("["); - Append($"{id}", ConsoleColor.Green); - Append("]"); - } - Append(" "); - return this; - } + return Append($"%{name} ", ConsoleColor.Green); else return Append($"%{id} ", ConsoleColor.Green); } readonly DisWriter AppendIdRefs(Span ids) @@ -188,13 +169,6 @@ readonly DisWriter AppendResultId(int? id = null) AppendRepeatChar(' ', data.IdOffset - name.Length - 1 - 3); Append('%', ConsoleColor.Cyan); Append(name, ConsoleColor.Cyan); - if (data.UseIds) - { - Append("["); - Append($"{id}", ConsoleColor.Cyan); - Append("]"); - - } } else { @@ -239,15 +213,8 @@ public void Disassemble() data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; } } - - int index = 0; foreach (var instruction in data) { - if (data.UseInstructionIndex) - { - Append($"SPV_{index:0000}: "); - index++; - } DisInstruction(instruction, this); } } @@ -690,13 +657,6 @@ or OperandKind.LiteralSpecConstantOpInteger (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, - OperandKind.ImportType => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), }; // _ = (operand.Kind, operand.Quantifier) switch @@ -816,18 +776,14 @@ struct DisData : IDisposable public HashSet UsedNames { get; } = new(); public NewSpirvBuffer Buffer { get; } public int IdOffset { get; private set; } - public DisassemblerFlags Flags { get; private set; } + public bool UseNames { get; private set; } public bool WriteToConsole { get; private set; } - public bool UseNames => (Flags & DisassemblerFlags.Name) != 0; - public bool UseIds => (Flags & DisassemblerFlags.Id) != 0; - public bool UseInstructionIndex => (Flags & DisassemblerFlags.InstructionIndex) != 0; - - public DisData(NewSpirvBuffer buffer, DisassemblerFlags flags, bool writeToConsole) + public DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) { Buffer = buffer; NameTable = []; - Flags = flags; + UseNames = useNames; WriteToConsole = writeToConsole; ComputeIdOffset(); } @@ -852,7 +808,7 @@ void ComputeIdOffset() { if (i.Op == Op.OpName) { - var nameInst = (OpName)i; + var nameInst = new OpName(i); maxName = maxName > nameInst.Name.Length ? maxName : nameInst.Name.Length; } else if (i.Op == Op.OpMemberName) @@ -873,8 +829,4 @@ public readonly void Dispose() key.Dispose(); } } - - - - } \ No newline at end of file From ca79609401eaf94932cfec3533f9972dead029e6 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 20 Oct 2025 12:43:22 +0200 Subject: [PATCH 0496/1182] Correction, went back to disasm flags --- .../SDSL/ShaderMixer.cs | 6 +- .../Stride.Shaders.Compilers.csproj | 2 +- .../Literals/LiteralArray.cs | 8 +- .../SPVGenerator.Info.cs | 60 ++- .../SPVGenerator.Instructions.cs | 9 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Spirv/Processing/StreamAnalyzer.cs | 14 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 508 ++---------------- .../Spirv/Tools/SpirvDis.Appends.cs | 274 ---------- .../Spirv/Tools/SpirvDis.Writer.cs | 58 -- src/Stride.Shaders/Spirv/Tools/SpirvDis.cs | 172 ------ 12 files changed, 119 insertions(+), 996 deletions(-) delete mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs delete mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs delete mode 100644 src/Stride.Shaders/Spirv/Tools/SpirvDis.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5bbfd7a36a..5c1dc34bf6 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -42,7 +42,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) CleanupUnnecessaryInstructions(temp); temp.Sort(); - Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); + Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); new StreamAnalyzer().Process(table, temp, context); @@ -364,7 +364,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB var composition = mixinNode.Compositions[callTarget.Target]; methodMixinGroup = composition; - Spv.Dis(temp, Spv.DisassemblerFlags.Id); + Spv.Dis(temp, DisassemblerFlags.Id); var functionName = externalFunctions[functionCall.Function]; var functionId = composition.MethodGroupsByName[functionName]; @@ -374,7 +374,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB SetOpNop(temp[index - 1].Data.Memory.Span); } - Spv.Dis(temp, Spv.DisassemblerFlags.NameAndId | Spv.DisassemblerFlags.InstructionIndex); + Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); bool foundInStage = false; if (!methodMixinGroup.MethodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 1a1c0a984d..a3475c90da 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 187de8ce1a..26124a1490 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -44,9 +44,15 @@ or LiteralArray MemoryOwner Memory { get; set { field?.Dispose(); field = value; } } public readonly ReadOnlySpan Words => Memory is not null ? Memory.Span : []; MemoryOwner Elements { get; set { field?.Dispose(); field = value; } } - public readonly int WordCount => Elements.Length; + public readonly int WordCount => Elements?.Length ?? -1; + public LiteralArray() + { + Elements = MemoryOwner.Empty; + Memory = MemoryOwner.Empty; + } + public LiteralArray(MemoryOwner elements) { Elements = elements; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 84383ef81f..de38a0a58e 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -57,16 +57,14 @@ public static class ParameterizedFlags code.Append(", "); } code.AppendLine(")") - .Append($" => new ParameterizedFlag<{realKind}>({realKind}.{enumerant.Name}, [{ - string.Join(", ", (enumerant.Parameters?.AsList() ?? []).Select(x => x.CSType switch - { - "float" => $"BitConverter.SingleToInt32({x.Name})", - "string" => $".. {x.Name}.AsDisposableLiteralValue().Words", - "int" => x.Name, - _ => $"(int){x.Name}", - - })) - }]);"); + .Append($" => new ParameterizedFlag<{realKind}>({realKind}.{enumerant.Name}, [{string.Join(", ", (enumerant.Parameters?.AsList() ?? []).Select(x => x.CSType switch + { + "float" => $"BitConverter.SingleToInt32({x.Name})", + "string" => $".. {x.Name}.AsDisposableLiteralValue().Words", + "int" => x.Name, + _ => $"(int){x.Name}", + + }))}]);"); } code.AppendLine("}"); context.AddSource( @@ -122,20 +120,42 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In static (spc, kinds) => { var builder = new StringBuilder(); - builder - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum OperandKind") - .AppendLine("{") - .AppendLine(" None,"); if (kinds.AsDictionary() is Dictionary dict) + { + builder + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum OperandKind") + .AppendLine("{") + .AppendLine(" None,"); foreach (var kind in dict.Values) builder.AppendLine($" {kind.Kind},"); - builder + builder + .AppendLine("}"); + + builder.AppendLine() + .AppendLine("public static class OperandKindExtensions") + .AppendLine("{") + .AppendLine("public static string? ToEnumValueString(this int value, OperandKind kind)") + .AppendLine("{") + .AppendLine("return kind switch") + .AppendLine("{"); + foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) + builder.AppendLine($" OperandKind.{kind.Kind} => (({kind.Kind}{(kind.Category is "BitEnum" ? "Mask" : "")})value).ToString(),"); + builder.AppendLine(" _ => null") + .AppendLine("};") + .AppendLine("}") .AppendLine("}"); - spc.AddSource("OperandKind.gen.cs", builder.ToString()); + } + spc.AddSource("OperandKind.gen.cs", SourceText.From( + SyntaxFactory + .ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + )); } ); // var code = new StringBuilder() diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 1059879493..ece6aed38e 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -61,7 +61,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv } } spc.AddSource( - $"Instructions.g.cs", + $"Instructions.gen.cs", SourceText.From( SyntaxFactory .ParseCompilationUnit(builder.ToString()) @@ -199,6 +199,13 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst } body2.AppendLine("}"); + foreach(var operand in operands.Where(o => o.Quantifier == "*")) + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + body2.AppendLine($"if({fieldName}.WordCount == -1)") + .AppendLine($"{fieldName} = new();"); + } + body3 .AppendLine("UpdateInstructionMemory();") .AppendLine("}"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index ff586e5017..1e8e6d99bf 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -102,7 +102,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); } - else if (instruction.Op == Op.OpTypeFunction && (OpTypeFunction)instruction is { } typeFunctionInstruction) + else if (instruction.Op == Op.OpTypeFunction && new OpTypeFunction(instruction) is { } typeFunctionInstruction) { var returnType = types[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index d30d766088..d79c3a9ac8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -117,7 +117,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpVariable(registeredType, variable, Specification.StorageClass.Private, null)); context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name)); + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); var sid = diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 6e612bfed1..7a75135d1b 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -96,12 +96,12 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { var streams = new SortedList(); - HashSet blockTypes = new(); - Dictionary blockPointerTypes = new(); - List blockIds = new(); + HashSet blockTypes = []; + Dictionary blockPointerTypes = []; + List blockIds = []; // Build name table - SortedList nameTable = []; + SortedList nameTable = []; SortedList semanticTable = []; foreach (var instruction in buffer) { @@ -137,7 +137,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform { if (instruction.Op == Op.OpDecorate - && ((OpDecorate)instruction) is { Decoration: Decoration.Block, Target: var bufferType }) + && ((OpDecorate)instruction) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) { blockTypes.Add(bufferType); } @@ -187,7 +187,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) ) { var name = nameTable.TryGetValue(variable.ResultId, out var nameId) - ? nameId.Name + ? nameId : $"unnamed_{variable.ResultId}"; var type = context.ReverseTypes[variable.ResultType]; semanticTable.TryGetValue(variable.ResultId, out var semantic); @@ -291,7 +291,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con // Add new entry point wrapper context.FluentAdd(new OpTypeFunction(context.Bound++, voidType, []), out var newEntryPointFunctionType); - buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); + buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); buffer.Add(new OpLabel(context.Bound++)); context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index adc49e4667..f02f8e3482 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -10,27 +10,35 @@ namespace Stride.Shaders.Spirv.Tools; +[Flags] +public enum DisassemblerFlags +{ + Id = 1, + Name = 2, + InstructionIndex = 4, +} + public static partial class Spv { - public static string Dis(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = false) + public static string Dis(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - var writer = new DisWriter(buffer, useNames, writeToConsole); + var writer = new DisWriter(buffer, flags, writeToConsole); writer.Disassemble(); writer.ToString(); return writer.ToString(); } - public static string Dis(SpirvReader reader, bool useNames = true, bool writeToConsole = false) + public static string Dis(SpirvReader reader, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { using var buffer = new NewSpirvBuffer(reader.Words); - var writer = new DisWriter(buffer, useNames, writeToConsole); + var writer = new DisWriter(buffer, flags, writeToConsole); writer.Disassemble(); return writer.ToString(); } - struct DisWriter(NewSpirvBuffer buffer, bool useNames = true, bool writeToConsole = true) + struct DisWriter(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) { - DisData data = new(buffer, useNames, writeToConsole); + DisData data = new(buffer, flags, writeToConsole); readonly StringBuilder builder = new(); readonly DisWriter AppendLine(string text, ConsoleColor? color = null) @@ -65,7 +73,19 @@ readonly DisWriter Append(T text, ConsoleColor? color = null) readonly DisWriter AppendIdRef(int id, bool useNames = true) { if (data.UseNames && useNames && data.NameTable.TryGetValue(id, out var name)) - return Append($"%{name} ", ConsoleColor.Green); + { + Append($"%{name}", ConsoleColor.Green); + if (data.UseIds) + { + Append("["); + Append($"{id}", ConsoleColor.Green); + Append("]"); + } + Append(" "); + return this; + } + + else return Append($"%{id} ", ConsoleColor.Green); } readonly DisWriter AppendIdRefs(Span ids) @@ -105,6 +125,13 @@ readonly DisWriter AppendEnums(SpvOperand operand) return this; } + readonly DisWriter AppendEnums(OperandKind kind, SpvOperand operand) + { + foreach (ref var value in operand.Words) + Append(value.ToEnumValueString(kind), ConsoleColor.Yellow).Append(' '); + return this; + } + readonly DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) { Append('"', ConsoleColor.Green).Append(value.Value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); @@ -169,6 +196,13 @@ readonly DisWriter AppendResultId(int? id = null) AppendRepeatChar(' ', data.IdOffset - name.Length - 1 - 3); Append('%', ConsoleColor.Cyan); Append(name, ConsoleColor.Cyan); + if (data.UseIds) + { + Append("["); + Append($"{id}", ConsoleColor.Cyan); + Append("]"); + + } } else { @@ -190,7 +224,7 @@ readonly DisWriter AppendResultId(int? id = null) } - public void Disassemble() + public readonly void Disassemble() { DisHeader(); foreach (var instruction in data) @@ -279,456 +313,14 @@ or OperandKind.LiteralSpecConstantOpInteger }, OperandKind.LiteralFloat => AppendLiteralNumber(operand.ToLiteral()), OperandKind.LiteralString => AppendLiteralString(operand.ToLiteral()), - OperandKind.ImageOperands => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FPFastMathMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.SelectionControl => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.LoopControl => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FunctionControl => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.MemorySemantics => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.MemoryAccess => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.KernelProfilingInfo => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.RayFlags => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FragmentShadingRate => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.RawAccessChainOperands => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.SourceLanguage => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.ExecutionModel => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.AddressingModel => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.MemoryModel => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.ExecutionMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.StorageClass => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.Dim => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.SamplerAddressingMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.SamplerFilterMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.ImageFormat => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.ImageChannelOrder => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.ImageChannelDataType => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FPRoundingMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FPDenormMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.QuantizationModes => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FPOperationMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.OverflowModes => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.LinkageType => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.AccessQualifier => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.HostAccessQualifier => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FunctionParameterAttribute => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.Decoration => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.BuiltIn => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.Scope => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.GroupOperation => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.KernelEnqueueFlags => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.Capability => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.RayQueryIntersection => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.RayQueryCommittedIntersectionType => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.RayQueryCandidateIntersectionType => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.PackedVectorFormat => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.CooperativeMatrixOperands => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.CooperativeMatrixLayout => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.CooperativeMatrixUse => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.CooperativeMatrixReduce => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.TensorClampMode => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.TensorAddressingOperands => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.InitializationModeQualifier => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.LoadCacheControl => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.StoreCacheControl => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.NamedMaximumNumberOfRegisters => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FPEncoding => (operand.Quantifier, operand.Words.Length) switch - { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), - (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), - _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - OperandKind.FunctionFlags => (operand.Quantifier, operand.Words.Length) switch + OperandKind k => (operand.Quantifier, operand.Words.Length) switch { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(operand).Append(' '), + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.Words[0].ToEnumValueString(k), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(k, operand).Append(' '), (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - }, - _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), + } }; - // _ = (operand.Kind, operand.Quantifier) switch - // { - // (OperandKind.IdResult, _) => Append(""), - // ( - // OperandKind.LiteralInteger - // or OperandKind.LiteralExtInstInteger - // or OperandKind.LiteralSpecConstantOpInteger, - // OperandQuantifier.One - // ) => AppendLiteralNumber(operand.ToLiteral()), - // (OperandKind.LiteralContextDependentNumber, OperandQuantifier.One) => AppendContextDependentNumber(operand, data, buffer), - // (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.One) => AppendIdRef(operand.ToLiteral()), - // (OperandKind.IdRef or OperandKind.IdResultType, OperandQuantifier.ZeroOrMore) => AppendIdRefs(operand.Words), - // (OperandKind.LiteralFloat, OperandQuantifier.One) => AppendLiteralNumber(operand.ToLiteral()), - // (OperandKind.LiteralString, OperandQuantifier.One) => AppendLiteralString(operand.ToLiteral()), - // (OperandKind.ImageOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPFastMathMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.SelectionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.LoopControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FunctionControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.MemorySemantics, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.MemoryAccess, OperandQuantifier.One or OperandQuantifier.ZeroOrOne) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.KernelProfilingInfo, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.RayFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FragmentShadingRate, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.RawAccessChainOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.SourceLanguage, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.ExecutionModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.AddressingModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.MemoryModel, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.ExecutionMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.StorageClass, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.Dim, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.SamplerAddressingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.SamplerFilterMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.ImageFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.ImageChannelOrder, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.ImageChannelDataType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPRoundingMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPDenormMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.QuantizationModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPOperationMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.OverflowModes, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.LinkageType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.AccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.HostAccessQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FunctionParameterAttribute, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.Decoration, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.BuiltIn, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.Scope, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.GroupOperation, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.KernelEnqueueFlags, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.Capability, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.RayQueryIntersection, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.RayQueryCommittedIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.RayQueryCandidateIntersectionType, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.PackedVectorFormat, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.CooperativeMatrixOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.CooperativeMatrixLayout, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.CooperativeMatrixUse, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.CooperativeMatrixReduce, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.TensorClampMode, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.TensorAddressingOperands, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.InitializationModeQualifier, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.LoadCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.StoreCacheControl, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.NamedMaximumNumberOfRegisters, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPEncoding, OperandQuantifier.One) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // (OperandKind.FPEncoding, OperandQuantifier.ZeroOrOne) => Append(operand.ToEnum().ToString(), ConsoleColor.Yellow).Append(' '), - // _ => throw new Exception($"Unhandled operand kind {operand.Kind} with quantifier {operand.Quantifier}"), - // }; } AppendLine(""); } @@ -776,14 +368,16 @@ struct DisData : IDisposable public HashSet UsedNames { get; } = new(); public NewSpirvBuffer Buffer { get; } public int IdOffset { get; private set; } - public bool UseNames { get; private set; } + public DisassemblerFlags Flags { get; private set; } + public bool UseNames => (Flags & DisassemblerFlags.Name) != 0; + public bool UseIds => (Flags & DisassemblerFlags.Id) != 0; public bool WriteToConsole { get; private set; } - public DisData(NewSpirvBuffer buffer, bool useNames, bool writeToConsole) + public DisData(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { Buffer = buffer; NameTable = []; - UseNames = useNames; + Flags = flags; WriteToConsole = writeToConsole; ComputeIdOffset(); } diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs deleted file mode 100644 index 6d0e9f20df..0000000000 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Appends.cs +++ /dev/null @@ -1,274 +0,0 @@ -using static Stride.Shaders.Spirv.Specification; -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Spirv.Tools; - - -public partial struct SpirvDis -{ - public readonly void Append(IdResult? result) - { - - if (result != null) - { - var tmp = result.Value; - var size = 1; - while (tmp > 0) - { - tmp /= 10; - size += 1; - } - writer.Append(' ', IdOffset - 1 - size).Append('%', ConsoleColor.Blue).Append(result!.Value.Value, ConsoleColor.Blue); - } - else - writer.Append(' ', IdOffset); - - } - internal readonly void Append(NameId name) - { - writer.Append(' ', Math.Max(0, IdOffset - 2 - name.Name.Length)).Append('%', ConsoleColor.Blue).Append(name.Name, ConsoleColor.Blue); - } - - public readonly void Append(T value) where T : Enum - { - var name = Enum.GetName(typeof(T), value); - if (name == "MaskNone") - name = "None"; - writer.Append(' ').Append(name); - } - public readonly void Append(IdRef id, bool ignoreName = false) - { - - if (UseNames && !ignoreName && nameTable.TryGetValue(id, out var name)) - writer.Append(" %", ConsoleColor.DarkYellow).Append(name.Name, ConsoleColor.DarkYellow); - else - writer.Append(" %", ConsoleColor.DarkYellow).Append(id.Value, ConsoleColor.DarkYellow); - } - public readonly void Append(IdResultType id) - { - if (UseNames && nameTable.TryGetValue(id, out var name)) - writer.Append(" %", ConsoleColor.DarkYellow).Append(name.Name, ConsoleColor.DarkYellow); - else - writer.Append(" %", ConsoleColor.DarkYellow).Append(id.Value, ConsoleColor.DarkYellow); - } - public readonly void AppendInt(int v) - { - writer.Append(' ').Append(v, ConsoleColor.Red); - } - public readonly void AppendConst(int typeId, Span words) - { - writer.Append(' '); - foreach (var e in buffer.InstructionsSpan) - { - if (e.ResultId is int rid && rid == typeId) - { - if (e.OpCode == Op.OpTypeInt) - { - writer.Append(words.Length == 1 ? words[0] : words[0] << 32 | words[1], ConsoleColor.Red); - return; - } - else if (e.OpCode == Op.OpTypeFloat) - { - writer.Append( - words.Length == 1 ? - BitConverter.Int32BitsToSingle(words[0]) - : BitConverter.Int64BitsToDouble(words[0] << 32 | words[1]), - - ConsoleColor.Red - ); - return; - } - } - } - } - public readonly void AppendLiteral(LiteralInteger v) - { - writer.Append(' ').Append(v.Data, ConsoleColor.Red); - } - - public readonly void AppendLiteral(LiteralFloat v) - { - if (v.WordCount == 1) - writer.Append(' ').Append(Convert.ToSingle(v.Data.Span[0] & 0xFFFF), ConsoleColor.Red); - else if (v.WordCount == 2) - writer.Append(' ').Append(Convert.ToDouble(v.Data), ConsoleColor.Red); - } - public readonly void AppendLiteral(LiteralString v, bool quoted = false) - { - if (!quoted) - writer.Append(' ').Append(v.Value); - else - writer.Append(' ').Append('"').Append(v.Value, ConsoleColor.Green).Append('"'); - } - public readonly void Append(PairLiteralIntegerIdRef v) - { - (int, int) value = v; - AppendInt(value.Item1); - Append(new IdRef(value.Item2)); - } - public readonly void Append(PairIdRefLiteralInteger v) - { - (int, int) value = v; - Append(new IdRef(value.Item1)); - AppendInt(value.Item2); - } - public readonly void Append(PairIdRefIdRef v) - { - (int, int) value = v; - Append(new IdRef(value.Item1)); - Append(new IdRef(value.Item2)); - } - public readonly void AppendLine() => writer.AppendLine(); - - public readonly void Append(in SpvOperand o, in Instruction instruction) - { - if (o.Kind == OperandKind.IdRef) - foreach (var e in o.Words) - Append(new IdRef(e), false); - else if (o.Kind == OperandKind.IdResultType) - foreach (var e in o.Words) - Append((IdResultType)e); - else if (o.Kind == OperandKind.PairLiteralIntegerIdRef) - for (int i = 0; i < o.Words.Length; i += 2) - Append(new PairLiteralIntegerIdRef((o.Words[i], o.Words[i + 1]))); - else if (o.Kind == OperandKind.PairIdRefLiteralInteger) - for (int i = 0; i < o.Words.Length; i += 2) - Append(new PairIdRefLiteralInteger((o.Words[i], o.Words[i + 1]))); - else if (o.Kind == OperandKind.PairIdRefIdRef) - for (int i = 0; i < o.Words.Length; i += 2) - Append(new PairIdRefIdRef((o.Words[i], o.Words[i + 1]))); - else if ( - o.Kind == OperandKind.LiteralContextDependentNumber - && (instruction.OpCode == Op.OpConstant || instruction.OpCode == Op.OpSpecConstant) - && instruction.ResultType is int rtype - ) - { - AppendConst(rtype, o.Words); - } - else if (o.Kind == OperandKind.LiteralContextDependentNumber) - AppendLiteral(o.To()); - else if (o.Kind == OperandKind.PackedVectorFormat) - foreach (var e in o.Words) - Append((PackedVectorFormat)e); - else if (o.Kind == OperandKind.ImageOperands) - foreach (var e in o.Words) - Append((ImageOperandsMask)e); - else if (o.Kind == OperandKind.FPFastMathMode) - foreach (var e in o.Words) - Append((FPFastMathModeMask)e); - else if (o.Kind == OperandKind.SelectionControl) - foreach (var e in o.Words) - Append((SelectionControlMask)e); - else if (o.Kind == OperandKind.LoopControl) - foreach (var e in o.Words) - Append((LoopControlMask)e); - else if (o.Kind == OperandKind.FunctionControl) - foreach (var e in o.Words) - Append((FunctionControlMask)e); - else if (o.Kind == OperandKind.MemorySemantics) - foreach (var e in o.Words) - Append((MemorySemanticsMask)e); - else if (o.Kind == OperandKind.MemoryAccess) - foreach (var e in o.Words) - Append((MemoryAccessMask)e); - else if (o.Kind == OperandKind.KernelProfilingInfo) - foreach (var e in o.Words) - Append((KernelProfilingInfoMask)e); - else if (o.Kind == OperandKind.RayFlags) - foreach (var e in o.Words) - Append((RayFlagsMask)e); - else if (o.Kind == OperandKind.FragmentShadingRate) - foreach (var e in o.Words) - Append((FragmentShadingRateMask)e); - else if (o.Kind == OperandKind.SourceLanguage) - foreach (var e in o.Words) - Append((SourceLanguage)e); - else if (o.Kind == OperandKind.ExecutionModel) - foreach (var e in o.Words) - Append((ExecutionModel)e); - else if (o.Kind == OperandKind.AddressingModel) - foreach (var e in o.Words) - Append((AddressingModel)e); - else if (o.Kind == OperandKind.MemoryModel) - foreach (var e in o.Words) - Append((MemoryModel)e); - else if (o.Kind == OperandKind.ExecutionMode) - foreach (var e in o.Words) - Append((ExecutionMode)e); - else if (o.Kind == OperandKind.StorageClass) - foreach (var e in o.Words) - Append((StorageClass)e); - else if (o.Kind == OperandKind.Dim) - foreach (var e in o.Words) - Append((Dim)e); - else if (o.Kind == OperandKind.SamplerAddressingMode) - foreach (var e in o.Words) - Append((SamplerAddressingMode)e); - else if (o.Kind == OperandKind.SamplerFilterMode) - foreach (var e in o.Words) - Append((SamplerFilterMode)e); - else if (o.Kind == OperandKind.ImageFormat) - foreach (var e in o.Words) - Append((ImageFormat)e); - else if (o.Kind == OperandKind.ImageChannelOrder) - foreach (var e in o.Words) - Append((ImageChannelOrder)e); - else if (o.Kind == OperandKind.ImageChannelDataType) - foreach (var e in o.Words) - Append((ImageChannelDataType)e); - else if (o.Kind == OperandKind.FPRoundingMode) - foreach (var e in o.Words) - Append((FPRoundingMode)e); - else if (o.Kind == OperandKind.LinkageType) - foreach (var e in o.Words) - Append((LinkageType)e); - else if (o.Kind == OperandKind.AccessQualifier) - foreach (var e in o.Words) - Append((AccessQualifier)e); - else if (o.Kind == OperandKind.FunctionParameterAttribute) - foreach (var e in o.Words) - Append((FunctionParameterAttribute)e); - else if (o.Kind == OperandKind.Decoration) - foreach (var e in o.Words) - Append((Decoration)e); - else if (o.Kind == OperandKind.BuiltIn) - foreach (var e in o.Words) - Append((BuiltIn)e); - else if (o.Kind == OperandKind.Scope) - foreach (var e in o.Words) - Append((Scope)e); - else if (o.Kind == OperandKind.GroupOperation) - foreach (var e in o.Words) - Append((GroupOperation)e); - else if (o.Kind == OperandKind.KernelEnqueueFlags) - foreach (var e in o.Words) - Append((KernelEnqueueFlags)e); - else if (o.Kind == OperandKind.Capability) - foreach (var e in o.Words) - Append((Capability)e); - else if (o.Kind == OperandKind.RayQueryIntersection) - foreach (var e in o.Words) - Append((RayQueryIntersection)e); - else if (o.Kind == OperandKind.RayQueryCommittedIntersectionType) - foreach (var e in o.Words) - Append((RayQueryCommittedIntersectionType)e); - else if (o.Kind == OperandKind.RayQueryCandidateIntersectionType) - foreach (var e in o.Words) - Append((RayQueryCandidateIntersectionType)e); - else if (o.Kind == OperandKind.IdMemorySemantics) - foreach (var e in o.Words) - AppendInt((IdMemorySemantics)e); - else if (o.Kind == OperandKind.IdScope) - foreach (var e in o.Words) - AppendInt((IdScope)e); - else if (o.Kind == OperandKind.IdRef) - foreach (var e in o.Words) - Append((IdRef)e); - else if (o.Kind == OperandKind.LiteralInteger) - foreach (var e in o.Words) - AppendInt(e); - else if (o.Kind == OperandKind.LiteralString) - AppendLiteral(new LiteralString(o.Words), quoted: true); - - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs deleted file mode 100644 index b79854ced7..0000000000 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.Writer.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Text; - -namespace Stride.Shaders.Spirv.Tools; - - - -public struct DisWriter() -{ - public bool WriteToConsole { get; set; } - readonly StringBuilder builder = new(); - - public readonly DisWriter Append(char value, int repeatCount, ConsoleColor? color = null) - { - builder.Append(value, repeatCount); - if(WriteToConsole) - { - if(color is ConsoleColor c) - Console.ForegroundColor = c; - Console.Write(new string(value, repeatCount)); - Console.ResetColor(); - } - return this; - } - public readonly DisWriter Append(T value, ConsoleColor? color = null) - { - builder.Append(value); - if(WriteToConsole) - { - if(color is ConsoleColor c) - Console.ForegroundColor = c; - Console.Write(value); - Console.ResetColor(); - } - return this; - } - public readonly DisWriter AppendLine() - { - builder.AppendLine(); - if(WriteToConsole) - Console.WriteLine(); - return this; - } - public readonly DisWriter AppendLine(string machin, ConsoleColor? color = null) - { - builder.AppendLine(machin); - if(WriteToConsole) - { - if(color is ConsoleColor c) - Console.ForegroundColor = c; - Console.WriteLine(machin); - Console.ResetColor(); - } - return this; - } - - public readonly void Clear() => builder.Clear(); - public readonly override string ToString() => builder.ToString(); -} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs b/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs deleted file mode 100644 index 858d192efc..0000000000 --- a/src/Stride.Shaders/Spirv/Tools/SpirvDis.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System.Text; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Core; -using static Stride.Shaders.Spirv.Specification; -using System.Runtime.CompilerServices; - -namespace Stride.Shaders.Spirv.Tools; - - -internal record struct NameId(string Name); - -public partial struct SpirvDis - where TBuffer : ISpirvBuffer - -{ - public readonly static int MAX_OFFSET = 16; - TBuffer buffer; - DisWriter writer = new(); - int IdOffset { get; init; } - bool UseNames { get; init; } - - // avoid name collisions - private HashSet usedNames = []; - SortedList nameTable = []; - - public SpirvDis(TBuffer buff, bool useNames = false) - { - buffer = buff; - if(buff.InstructionsSpan.Length == 0) - return; - writer = new(); - UseNames = useNames; - IdOffset = 9; - if (!useNames) - { - var bound = buff.Header.Bound; - IdOffset = 3; - while (bound > 0) - { - bound /= 10; - IdOffset += 1; - } - } - else - { - var maxName = 0; - foreach (var i in buffer.InstructionsSpan) - { - if ( - (i.OpCode == Op.OpName || i.OpCode == Op.OpMemberName) - && i.TryGetOperand("name", out LiteralString? name) - && name is not null - ) - { - maxName = maxName > name.Value.Value.Length ? maxName : name.Value.Value.Length; - } - } - IdOffset += maxName; - } - IdOffset = Math.Min(IdOffset, MAX_OFFSET); - } - - - public string Disassemble(bool writeToConsole = false) - { - writer = writer with { WriteToConsole = writeToConsole }; - writer.Clear(); - - if (buffer.HasHeader) - { - var header = buffer.Header; - writer - .AppendLine("; SPIR-V") - .AppendLine($"; Version: {header.Version}") - .AppendLine($"; Generator: {header.Generator}") - .AppendLine($"; Bound: {header.Bound}") - .AppendLine($"; Schema: {header.Schema}"); - } - - if(buffer.InstructionsSpan.Length == 0) - return ""; - - // First pass: scan names - foreach (var e in buffer.InstructionsSpan) - { - CheckNameTable(e); - } - - // Second pass: disassemble - foreach (var e in buffer.InstructionsSpan) - { - if (UseNames && e.ResultId is int id && nameTable.TryGetValue(id, out var nid)) - Append(nid); - else - Append(e.ResultId != null ? new IdResult(e.ResultId.Value) : null); - - writer.Append(' '); - if (e.ResultId is int) - writer.Append('='); - - AppendLiteral(Enum.GetName(e.OpCode) ?? "Op.OpNop"); - foreach (var o in e) - Append(o, e); - - AppendLine(); - } - return writer.ToString(); - } - - // TODO : add other names - public readonly void CheckNameTable(Instruction instruction) - { - if ( - UseNames - && (instruction.OpCode == Op.OpName || instruction.OpCode == Op.OpMemberName) - && instruction.TryGetOperand("target", out IdRef? target) && target is IdRef t - && instruction.TryGetOperand("name", out LiteralString? name) && name is LiteralString n - ) - { - UpdateNameTable(t, n.Value); - } - else if (instruction.OpCode == Op.OpTypeVoid) - UpdateNameTable(instruction.ResultId!.Value, "void"); - else if (instruction.OpCode == Op.OpTypeBool) - UpdateNameTable(instruction.ResultId!.Value, "bool"); - else if (instruction.OpCode == Op.OpTypeInt) - { - var type = instruction.Operands[1..] switch - { - [8, 0] => "byte", - [16, 0] => "ushort", - [32, 0] => "uint", - [64, 0] => "ulong", - [8, 1] => "sbyte", - [16, 1] => "short", - [32, 1] => "int", - [64, 1] => "long", - _ => "int" - }; - UpdateNameTable(instruction.ResultId!.Value, type); - } - else if (instruction.OpCode == Op.OpTypeFloat) - { - var size = instruction.Operands[1]; - UpdateNameTable(instruction.ResultId!.Value, size switch {16 => "half", 32 => "float", 64 => "double", _ => throw new NotImplementedException()}); - } - else if (instruction.OpCode == Op.OpTypeVector) - { - //UpdateNameTable(instruction.ResultId!.Value, nameTable[instruction.Operands[1]].Name + instruction.Operands[2]); - } - - - } - - private readonly void UpdateNameTable(int id, string name) - { - if (!usedNames.Add(name)) - { - int extraId = 0; - var tentativeName = name; - while (!usedNames.Add(tentativeName)) - tentativeName = $"{name}_{extraId++}"; - name = tentativeName; - } - nameTable[id] = new(name); - } - - public readonly override string ToString() - { - return writer.ToString(); - } -} \ No newline at end of file From 2a1936f3c5a1742d66ff9ceeb687af98c7a53d3c Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 28 Oct 2025 00:07:51 +0100 Subject: [PATCH 0497/1182] case sensitive --- .../{ShaderBufferParsers.Cs => ShaderBufferParsers.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/{ShaderBufferParsers.Cs => ShaderBufferParsers.cs} (100%) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs similarity index 100% rename from src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.Cs rename to src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs From 24268e4b170aa661efc444a00dd4765f071cd9ba Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 28 Oct 2025 00:08:36 +0100 Subject: [PATCH 0498/1182] fix parsing buffer names, dis and bound computation --- .../SDSL/ShaderMixer.cs | 19 ++--- src/Stride.Shaders.Experiments/Examples.cs | 29 +++++--- src/Stride.Shaders.Experiments/Program.cs | 8 ++- .../Buffers/NewSpirvBuffer.cs | 27 ++++--- .../ShaderParsers/ShaderBufferParsers.cs | 8 ++- .../Parsing/SDSL/ShaderSource.cs | 14 ++-- src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- .../Spirv/Building/CompilerUnit.cs | 20 +++--- src/Stride.Shaders/Spirv/Building/Context.cs | 4 +- .../Spirv/Processing/PostProcessor.cs | 71 +++++++------------ .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 - src/Stride.Shaders/Spirv/Tools/Dis.cs | 35 +++++---- 12 files changed, 121 insertions(+), 117 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5c1dc34bf6..06a06df45a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -18,8 +18,9 @@ namespace Stride.Shaders.Compilers.SDSL; -public partial class ShaderMixer(IExternalShaderLoader ShaderLoader) +public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { + public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; public void MergeSDSL(string entryShaderName, out byte[] bytecode) { var temp = new NewSpirvBuffer(); @@ -42,7 +43,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) CleanupUnnecessaryInstructions(temp); temp.Sort(); - Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); + // Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); new StreamAnalyzer().Process(table, temp, context); @@ -60,21 +61,21 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) bytecode = temp.ToBytecode(); - //File.WriteAllBytes("test.spv", bytecode); + // File.WriteAllBytes("test.spv", bytecode); - Spv.Dis(temp); + // Spv.Dis(temp, DisassemblerFlags.Id, writeToConsole: true); //File.WriteAllText("test.spvdis", source); } class MixinGlobalContext { - public Dictionary Names { get; } = new(); - public Dictionary Types { get; } = new(); + public Dictionary Names { get; } = []; + public Dictionary Types { get; } = []; } class MixinNodeContext { - public MixinNode Result { get; } + public MixinNode? Result { get; } } @@ -114,7 +115,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, var compositionMixin = mixinSource.Compositions[variable.Key]; var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; var compositionResult = MergeMixinNode(globalContext, context, table, buffer, compositionMixin, mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); - + mixinNode.Compositions.Add(variable.Value.Id, compositionResult); } } @@ -163,7 +164,7 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad for (var index = 0; index < shader.Count; index++) { var i = shader[index]; - + // Do we need to skip variable/functions? (depending on stage/non-stage) { var include = true; diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 1c10789788..3139e217f1 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -10,6 +10,7 @@ using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Spirv.Core.Buffers; using SourceLanguage = Silk.NET.Shaderc.SourceLanguage; +using Silk.NET.SPIRV; namespace Stride.Shaders.Experiments; @@ -218,25 +219,37 @@ public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out Ne return false; } var text = MonoGamePreProcessor.OpenAndRun(filename); - var sdslc = new SDSLC(); - sdslc.ShaderLoader = this; + var sdslc = new SDSLC + { + ShaderLoader = this + }; return sdslc.Compile(text, out buffer); } } - public static void CompileSDSL() + public static void CompileSDSL(string shaderName) { - var text = MonoGamePreProcessor.OpenAndRun("./assets/SDSL/TestBasic.sdsl"); + // if(Directory.GetCurrentDirectory().Contains("bin\\Debug")) + // { + // var info = new DirectoryInfo(Directory.GetCurrentDirectory()); + // while(!info.GetDirectories().Any(d => d.Name is "assets") || !info.GetFiles().Any(d => d.Name is "SDSL.sln") ) + // info = info.Parent!; + // Directory.SetCurrentDirectory(info.FullName); + // } + var text = MonoGamePreProcessor.OpenAndRun($"./assets/SDSL/{shaderName}.sdsl"); var sdslc = new SDSLC { ShaderLoader = new ShaderLoader() }; - sdslc.Compile(text, out var buffer); + if (sdslc.Compile(text, out var buffer) && buffer is not null) + { + Spirv.Tools.Spv.Dis(buffer, writeToConsole: true); + var bytecode = buffer.ToBytecode(); + File.WriteAllBytes("TestBasic.sdspv", bytecode); + var code = new SpirvTranslator(bytecode.AsMemory().Cast()); + } - var bytecode = buffer.ToBytecode(); - File.WriteAllBytes("TestBasic.sdspv", bytecode); - var code = new SpirvTranslator(bytecode.AsMemory().Cast()); // Console.WriteLine(code.Translate(Backend.Hlsl)); } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index e9b3267f41..e29b866bde 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -4,11 +4,13 @@ using System.Runtime.InteropServices; using Stride.Shaders.Spirv.Tools; -Examples.TranslateHLSL(); +// Examples.CompileSDSL("RenderTests/If"); //Examples.CompileSDSL(); -var shaderMixer = new ShaderMixer(new Examples.ShaderLoader()); -shaderMixer.MergeSDSL("TestBasic", out var bytecode); +var loader = new Examples.ShaderLoader(); +loader.LoadExternalFile("Test", out var testBuffer); +var shaderMixer = new ShaderMixer(loader); +shaderMixer.MergeSDSL("If", out var bytecode); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 3706f7b158..08974d4ef5 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -162,10 +162,14 @@ public NewSpirvBuffer(Span span) : this() } - public void Add(OpData data) + void UpdateBound(OpData data) { if (data.IdResult is int index && index >= Header.Bound) Header = Header with { Bound = index + 1 }; + } + + public void Add(OpData data) + { Instructions.Add(data); } @@ -179,6 +183,7 @@ public OpData Add(in T instruction) where T : struct, IMemoryInstruction Instructions.Add(new(instruction.InstructionMemory)); } else Instructions.Add(new(instruction.InstructionMemory)); + UpdateBound(Instructions[^1]); return Instructions[^1]; } @@ -193,9 +198,7 @@ public void AddRef(ref T instruction) where T : struct, IMemoryInstruction } else Instructions.Add(new(instruction.InstructionMemory)); instruction.DataIndex = new(Instructions.Count - 1, this); - - if (instruction.GetInfo().GetResultIndex(out int rid) && instruction.InstructionMemory.Span[rid + 1] >= Header.Bound) - Header = Header with { Bound = instruction.InstructionMemory.Span[rid + 1] + 1 }; + UpdateBound(Instructions[^1]); } public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction { @@ -208,8 +211,7 @@ public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryIn } else Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; - if (tmp.GetInfo().GetResultIndex(out int rid) && tmp.InstructionMemory.Span[rid + 1] >= Header.Bound) - Header = Header with { Bound = tmp.InstructionMemory.Span[rid + 1] + 1 }; + UpdateBound(Instructions[^1]); return this; } public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction @@ -223,21 +225,15 @@ public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : str Instructions.Add(new(instruction.InstructionMemory)); } else Instructions.Add(new(instruction.InstructionMemory)); - var tmp = instruction; - if (tmp.GetInfo().GetResultIndex(out int rid) && instruction.InstructionMemory.Span[rid + 1] >= Header.Bound) - Header = Header with { Bound = instruction.InstructionMemory.Span[rid + 1] + 1 }; + UpdateBound(Instructions[^1]); return this; } - public void Insert(int index, OpData data) - => Instructions.Insert(index, data); public T Insert(int index, in T data) where T : struct, IMemoryInstruction { Instructions.Insert(index, new(data.InstructionMemory)); - var tmp = data; - if (tmp.GetInfo().GetResultIndex(out int rid) && tmp.InstructionMemory.Span[rid + 1] >= Header.Bound) - Header = Header with { Bound = tmp.InstructionMemory.Span[rid + 1] + 1 }; + UpdateBound(Instructions[^1]); return data; } public OpData InsertData(int index, in T data) @@ -245,6 +241,7 @@ public OpData InsertData(int index, in T data) { var result = new OpData(data.InstructionMemory); Instructions.Insert(index, result); + UpdateBound(result); return result; } @@ -357,7 +354,7 @@ public static class IMemoryInstructionExtensions public static LogicalOperandArray GetInfo(this ref T op) where T : struct, IMemoryInstruction { - if(op.DataIndex is OpDataIndex odi) + if (op.DataIndex is OpDataIndex odi) return InstructionInfo.GetInfo(odi.Data); return InstructionInfo.GetInfo(op.InstructionMemory.Span); } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs index 942ddcbe0c..517f84f30c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs @@ -163,6 +163,12 @@ public static bool Member(ref TScanner scanner, ParseResult result, ou public static bool BufferName(ref TScanner scanner, ParseResult result, out Identifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - return LiteralsParser.Identifier(ref scanner, result, out parsed, orError); + parsed = null!; + if(Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out List identifiers, 1, true, ".", orError)) + { + parsed = new Identifier(string.Join(".", identifiers.Select(i => i.Name)), scanner[identifiers[0].Info.Range.Start..identifiers[^1].Info.Range.End]); + return true; + } + else return false; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs index 537bff5aa6..68e8427b5f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs +++ b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs @@ -42,18 +42,18 @@ public string ToClassName() return result.ToString(); } - public bool Equals(ShaderClassSource shaderClassSource) + public bool Equals(ShaderClassSource? shaderClassSource) { - if (ReferenceEquals(null, shaderClassSource)) return false; + if (shaderClassSource is null) return false; if (ReferenceEquals(this, shaderClassSource)) return true; return string.Equals(ClassName, shaderClassSource.ClassName) && GenericArguments.SequenceEqual(shaderClassSource.GenericArguments); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { - if (ReferenceEquals(null, obj)) return false; + if (obj is null) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != GetType()) return false; return Equals((ShaderClassSource)obj); @@ -82,9 +82,9 @@ public override string ToString() public sealed class ShaderMixinSource : ShaderSource { - public List Mixins { get; } = new(); + public List Mixins { get; } = []; - public Dictionary Compositions { get; } = new(); + public Dictionary Compositions { get; } = []; public override string ToString() { @@ -94,7 +94,7 @@ public override string ToString() if (Mixins != null && Mixins.Count > 0) { - result.Append(" "); + result.Append(' '); for (int i = 0; i < Mixins.Count; i++) { if (i > 0) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index e1d894c778..a5837e7d44 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -97,6 +97,6 @@ public Op GetLastInstructionType() public override string ToString() { - return Spv.Dis(Buffer); + return Spv.Dis(Buffer, writeToConsole: false); } } diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index fd5ee0442c..7afe779db5 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -34,15 +34,15 @@ public NewSpirvBuffer ToBuffer() Context.Sort(); return NewSpirvBuffer.Merge(Context.GetBuffer(), Builder.GetBuffer()); } - public override string ToString() - { - var builder = new StringBuilder(); - builder - .AppendLine("Context : ") - .AppendLine(Spv.Dis(Context.GetBuffer())) - .AppendLine("Functions : ") - .AppendLine(Spv.Dis(Builder.GetBuffer())); - return builder.ToString(); - } + // public override string ToString() + // { + // var builder = new StringBuilder(); + // builder + // .AppendLine("Context : ") + // .AppendLine(Spv.Dis(Context.GetBuffer())) + // .AppendLine("Functions : ") + // .AppendLine(Spv.Dis(Builder.GetBuffer())); + // return builder.ToString(); + // } #pragma warning restore CS0618 // Type or member is obsolete } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 08c02138c8..6078924595 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -17,7 +17,7 @@ public interface IExternalShaderLoader public abstract class ShaderLoaderBase : IExternalShaderLoader { - private Dictionary loadedShaders = new(); + private Dictionary loadedShaders = []; public void RegisterShader(string name, NewSpirvBuffer buffer) { @@ -338,6 +338,6 @@ public SpirvContext FluentAdd(in T value, out T result) public override string ToString() { - return Spv.Dis(Buffer); + return Spv.Dis(Buffer, writeToConsole: false); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs index 8f7368bd46..44a60ebd15 100644 --- a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -1,48 +1,29 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Processing; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; -// namespace Stride.Shaders.Spirv.PostProcessing; +namespace Stride.Shaders.Spirv.PostProcessing; -// /// -// /// Nano pass merger/optimizer/compiler -// /// -// public static class PostProcessor -// { -// public static SpirvBuffer Process(string mixinName) -// { -// var buffer = new SpirvBuffer(); -// var mixin = MixinSourceProvider.Get(mixinName); -// var parents = MixinSourceProvider.GetMixinGraph(mixinName); -// var bound = 0; -// foreach(var p in parents) -// { -// foreach (var i in p.Instructions) -// buffer.Duplicate(i.AsRef(), bound); -// bound += p.Bound; -// } -// foreach(var i in mixin.Instructions) -// buffer.Duplicate(i.AsRef(), bound); -// Apply(buffer); +/// +/// Nano pass merger/optimizer/compiler +/// +public static class SpirvProcessor +{ + public static void Process(NewSpirvBuffer buffer) + { + // Apply(buffer); + // Apply(buffer); + // Apply(buffer); + Apply(buffer); + // Apply(buffer); + // Apply(buffer); + // Apply(buffer); + } -// return new(buffer); -// } - -// static void Apply(SpirvBuffer buffer) -// { -// Apply(buffer); -// Apply(buffer); -// Apply(buffer); -// Apply(buffer); -// Apply(buffer); -// Apply(buffer); -// Apply(buffer); -// } - -// static void Apply(SpirvBuffer buffer) -// where T : struct, INanoPass -// { -// var p = new T(); -// p.Apply(buffer); -// } -// } \ No newline at end of file + static void Apply(NewSpirvBuffer buffer) + where T : struct, INanoPass + { + var p = new T(); + p.Apply(buffer); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 7b9777f3e4..4c3967bad7 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -18,7 +18,6 @@ namespace Stride.Shaders.Spirv.Processing; /// public struct TypeDuplicateRemover : INanoPass { - public readonly void Apply(NewSpirvBuffer buffer) { for (var index = 0; index < buffer.Count; index++) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index f02f8e3482..f572ccd21c 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -24,7 +24,6 @@ public static string Dis(NewSpirvBuffer buffer, DisassemblerFlags flags = Disass { var writer = new DisWriter(buffer, flags, writeToConsole); writer.Disassemble(); - writer.ToString(); return writer.ToString(); } @@ -43,29 +42,35 @@ struct DisWriter(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFl readonly DisWriter AppendLine(string text, ConsoleColor? color = null) { - if (color is not null) + if (writeToConsole) { - var previousColor = Console.ForegroundColor; - Console.ForegroundColor = color.Value; - Console.WriteLine(text); - Console.ForegroundColor = previousColor; + if (color is not null) + { + var previousColor = Console.ForegroundColor; + Console.ForegroundColor = color.Value; + Console.WriteLine(text); + Console.ForegroundColor = previousColor; + } + else + Console.WriteLine(text); } - else - Console.WriteLine(text); builder.AppendLine(text); return this; } readonly DisWriter Append(T text, ConsoleColor? color = null) { - if (color is not null) + if (data.WriteToConsole) { - var previousColor = Console.ForegroundColor; - Console.ForegroundColor = color.Value; - Console.Write(text); - Console.ForegroundColor = previousColor; + if (color is not null) + { + var previousColor = Console.ForegroundColor; + Console.ForegroundColor = color.Value; + Console.Write(text); + Console.ForegroundColor = previousColor; + } + else + Console.Write(text); } - else - Console.Write(text); builder.Append(text); return this; } From 255ba7195962176a553f227569d37a9d12e645e7 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 28 Oct 2025 01:05:54 +0100 Subject: [PATCH 0499/1182] Better spirv post processor --- .../SDSL/ShaderMixer.cs | 23 +- .../Buffers/NewSpirvBuffer.cs | 20 +- src/Stride.Shaders/Spirv/Building/Context.cs | 2 + .../Spirv/Processing/BoundReducer.cs | 197 +++++++----------- .../Spirv/Processing/PostProcessor.cs | 6 +- .../Spirv/Processing/SDSLOpRemover.cs | 58 ++---- .../Spirv/Processing/StreamAnalyzer.cs | 4 +- 7 files changed, 126 insertions(+), 184 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 06a06df45a..e1730ac062 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -15,6 +15,7 @@ using System.Runtime.InteropServices; using Stride.Shaders.Parsing.SDSL; using static Stride.Shaders.Spirv.Specification; +using Stride.Shaders.Spirv.PostProcessing; namespace Stride.Shaders.Compilers.SDSL; @@ -43,28 +44,24 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) CleanupUnnecessaryInstructions(temp); temp.Sort(); - // Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); - new StreamAnalyzer().Process(table, temp, context); - foreach (var inst in context.GetBuffer()) + foreach (var inst in context) temp.Add(inst.Data); - new TypeDuplicateRemover().Apply(temp); - for (int i = 0; i < temp.Count; i++) - { - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); - } + + // Final processing + SpirvProcessor.Process(temp); + temp.Sort(); bytecode = temp.ToBytecode(); - // File.WriteAllBytes("test.spv", bytecode); - - // Spv.Dis(temp, DisassemblerFlags.Id, writeToConsole: true); - //File.WriteAllText("test.spvdis", source); +#if DEBUG + File.WriteAllBytes("test.spv", bytecode); + File.WriteAllText("test.spvdis", Spv.Dis(temp)); +#endif } class MixinGlobalContext diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 08974d4ef5..5cfe660f1f 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -23,8 +23,24 @@ public struct OpData : IDisposable, IComparable public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } public readonly Op Op => (Op)(Memory.Span[0] & 0xFFFF); - public readonly int? IdResult => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : null; - public readonly int? IdResultType => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; + public readonly int? IdResult + { + get => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : null; + set + { + if (InstructionInfo.GetInfo(this).GetResultIndex(out var index) && value is not null) + Memory.Span[index + 1] = value ?? 0; + } + } + public readonly int? IdResultType + { + get => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; + set + { + if (InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) && value is not null) + Memory.Span[index + 1] = value ?? 0; + } + } public OpData() { diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 6078924595..7c4e7b1020 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -336,6 +336,8 @@ public SpirvContext FluentAdd(in T value, out T result) [Obsolete("Use the insert method instead")] public NewSpirvBuffer GetBuffer() => Buffer; + public NewSpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); + public override string ToString() { return Spv.Dis(Buffer, writeToConsole: false); diff --git a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs index 666ce792d1..9461482147 100644 --- a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs +++ b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs @@ -1,127 +1,88 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using System; -// using System.Collections.Generic; -// using System.Linq; -// using System.Runtime.CompilerServices; -// using System.Text; -// using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; -// namespace Stride.Shaders.Spirv.Processing; +namespace Stride.Shaders.Spirv.Processing; -// /// -// /// Makes sure indices used in spirv module are all continuous. -// /// -// public struct BoundReducer : INanoPass -// { -// public BoundReducer() { } +/// +/// Makes sure indices used in spirv module are all continuous. +/// +public struct BoundReducer() : INanoPass +{ -// public void Apply(SpirvBuffer buffer) -// { -// // First step is to find the next idResult -// // If it's previous + 1 then it's okay, previous is now updated -// // If it's above previous + 1, then it's not okay and we switch + public readonly void Apply(NewSpirvBuffer buffer) + { + // First step is to find the next idResult + // If it's previous + 1 then it's okay, previous is now updated + // If it's above previous + 1, then it's not okay and we switch -// var finished = false; -// var previousId = 0; -// var next = Instruction.Empty; -// var countIds = 0; + var finished = false; + var previousId = 0; + OpData? next = null!; + var countIds = 0; -// foreach (var i in buffer.Instructions) -// countIds += i.ResultId != null ? 1 : 0; -// while (!finished && previousId < countIds) -// { -// var countAbove = 0; -// foreach(var i in buffer.Instructions) -// { -// if(i.ResultId == previousId + 1) -// { -// countAbove += 1; -// previousId += 1; -// next = i; -// break; -// } -// else if (next.IsEmpty && i.ResultId > previousId + 1) -// { -// countAbove += 1; -// next = i; -// } -// else if(!next.IsEmpty && i.ResultId > previousId + 1 && i.ResultId < next.ResultId) -// { -// countAbove += 1; -// next = i; -// } -// } -// if (countAbove == 0) -// finished = true; -// else if(next.ResultId > previousId + 1) -// { -// next.AsRef().SetResultId(previousId + 1); -// ReplaceRefs(next.ResultId ?? -1, previousId + 1, buffer); -// } -// } + foreach (var i in buffer) + countIds += i.Data.IdResult != null ? 1 : 0; + while (!finished && previousId < countIds) + { + var countAbove = 0; + foreach(var i in buffer) + { + if(i.Data.IdResult == previousId + 1) + { + countAbove += 1; + previousId += 1; + next = i.Data; + break; + } + else if (next is null && i.Data.IdResult > previousId + 1) + { + countAbove += 1; + next = i.Data; + } + else if(next is not null && i.Data.IdResult > previousId + 1 && i.Data.IdResult < (next?.IdResult ?? 0)) + { + countAbove += 1; + next = i.Data; + } + } + if (countAbove == 0) + finished = true; + else if(next is OpData && (next?.IdResult ?? 0) > previousId + 1) + { + next?.IdResult = previousId + 1; + ReplaceRefs(next?.IdResult ?? -1, previousId + 1, buffer); + } + } -// buffer.RecomputeBound(); -// } -// static void ReplaceRefs(int from, int to, SpirvBuffer buffer) -// { -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// foreach (var (_, f) in buffer.Functions) -// foreach (var i in f.UnorderedInstructions) -// { -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// } -// static void ReplaceRefs(int from, int to, SpirvBuffer func) -// { -// foreach (var i in func) -// { -// foreach (var op in i) -// { -// if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairIdRefLiteralInteger) -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// else if (op.Kind == OperandKind.PairIdRefIdRef) -// { -// op.Words[0] = op.Words[0] == from ? to : op.Words[0]; -// op.Words[1] = op.Words[1] == from ? to : op.Words[1]; -// } -// } -// } -// } -// } + + } + static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) + { + foreach (var i in buffer) + { + foreach (var op in i.Data) + { + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairIdRefIdRef) + { + op.Words[0] = op.Words[0] == from ? to : op.Words[0]; + op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + } + } + } + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs index 44a60ebd15..05c373ab47 100644 --- a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -11,13 +11,9 @@ public static class SpirvProcessor { public static void Process(NewSpirvBuffer buffer) { - // Apply(buffer); - // Apply(buffer); - // Apply(buffer); Apply(buffer); - // Apply(buffer); // Apply(buffer); - // Apply(buffer); + Apply(buffer); } static void Apply(NewSpirvBuffer buffer) diff --git a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs index bb39462fcd..74cb96bc46 100644 --- a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs @@ -1,46 +1,18 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Core.Parsing; -// using System; -// using System.Collections.Generic; -// using System.Linq; -// using System.Text; -// using System.Threading.Tasks; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Specification; -// namespace Stride.Shaders.Spirv.Processing; +namespace Stride.Shaders.Spirv.Processing; -// /// -// /// Removes SDSL specific instructions -// /// -// public struct OpRemover : INanoPass -// { - -// public void Apply(SpirvBuffer buffer) -// { -// var decl = new InstructionEnumerator(buffer.Declarations); -// while(decl.MoveNext()) -// { -// var i = decl.Current; -// if (InstructionInfo.Operators.Contains(i.OpCode)) -// SetOpNop(i.AsRef()); -// } -// foreach (var (_, f) in buffer.Functions) -// { -// var func = new InstructionEnumerator(f); -// while(func.MoveNext()) -// { -// var i = func.Current; -// if (InstructionInfo.Operators.Contains(i.OpCode)) -// SetOpNop(i.AsRef()); -// } -// } -// } - -// static void SetOpNop(RefInstruction i) -// { -// i.Words[0] = i.WordCount << 16; -// i.Operands.Clear(); -// } - -// } +/// +/// Removes SDSL specific instructions +/// +public struct NOPRemover : INanoPass +{ + public readonly void Apply(NewSpirvBuffer buffer) + { + for (int i = 0; i < buffer.Count; i++) + if (buffer[i].Op == Op.OpNop) + buffer.RemoveAt(i--); + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 7a75135d1b..115169b0d0 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -35,9 +35,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - record struct AnalysisResult(SortedList Streams, List Blocks) - { - } + record struct AnalysisResult(SortedList Streams, List Blocks); public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { From e5f0136d4fd2b7fe18de122d749f51f2001e0dfe Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 5 Nov 2025 11:18:22 +0900 Subject: [PATCH 0500/1182] Fix braces (nested ifs) --- .../SPVGenerator.Instructions.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index ece6aed38e..c5ee0341e1 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -186,14 +186,22 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst // Body 2 body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); + bool needCloseBrace = false; // Optional operands if (operand.Quantifier == "?") + { + body2.AppendLine("{"); body2.AppendLine("if (o.Words.Length > 0)"); + needCloseBrace = true; + } if (typename.StartsWith("LiteralArray")) body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); + + if (needCloseBrace) + body2.AppendLine("}"); // Body 3 body3.AppendLine($"{fieldName} = {operandName};"); } From 0f68fbc5215fe6ccfb371fcedb1931dcb7fef0a0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 5 Nov 2025 11:19:34 +0900 Subject: [PATCH 0501/1182] Properly set ParameterizedFlag.Parameters when reconstructing instruction from OpDataIndex --- .../SPVGenerator.Instructions.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index c5ee0341e1..ca679cb29f 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -202,6 +202,17 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst if (needCloseBrace) body2.AppendLine("}"); + + if (grammar.OperandKinds?.AsDictionary() is Dictionary dict + && dict.TryGetValue(operand.Kind, out var opkind) && opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) + { + body2.AppendLine($"else if({string.Join(" || ", enumerants + .Where(e => e.Parameters?.AsList() is List { Count: > 0 }) + .SelectMany(enumerant => enumerant.Parameters?.AsList()) + .Select(param => $"o.Name == \"{param.Name ?? ConvertKindToName(param.Kind)}\""))})"); + body2.AppendLine($"{fieldName} = new({fieldName}{(typename.EndsWith("?") ? ".Value" : "")}.Value, o.Words);"); + } + // Body 3 body3.AppendLine($"{fieldName} = {operandName};"); } From 05b22f5d722ef0ace65de837c84286e5355260e9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 5 Nov 2025 12:54:00 +0900 Subject: [PATCH 0502/1182] Tests: adjust test values to avoid rounding errors --- assets/SDSL/RenderTests/CompositionTest1.sdsl | 8 +++---- .../RenderTests/CompositionTestStage1.sdsl | 24 +++++++++---------- .../RenderTests/CompositionTestStage2.sdsl | 17 +++++-------- .../RenderTests/ConstantFloat4Return.sdsl | 2 +- assets/SDSL/RenderTests/For.sdsl | 4 ++-- assets/SDSL/RenderTests/ForBreak.sdsl | 6 ++--- assets/SDSL/RenderTests/ForContinue.sdsl | 6 ++--- assets/SDSL/RenderTests/IfElse.sdsl | 2 +- assets/SDSL/RenderTests/IfElseif.sdsl | 2 +- assets/SDSL/RenderTests/IfElseifElse.sdsl | 4 ++-- assets/SDSL/RenderTests/IfElseifElseif.sdsl | 4 ++-- .../SDSL/RenderTests/MethodForwardCall.sdsl | 2 +- assets/SDSL/RenderTests/PositionStreams.sdsl | 2 +- .../SDSL/RenderTests/SimpleInheritance.sdsl | 4 ++-- .../SimpleInheritanceAbstract.sdsl | 4 ++-- .../SimpleInheritanceBaseThis.sdsl | 4 ++-- .../SDSL/RenderTests/StreamPassthroughPS.sdsl | 2 +- assets/SDSL/RenderTests/StreamVSToPS.sdsl | 2 +- 18 files changed, 47 insertions(+), 52 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionTest1.sdsl b/assets/SDSL/RenderTests/CompositionTest1.sdsl index ecb36503e4..eabee005e6 100644 --- a/assets/SDSL/RenderTests/CompositionTest1.sdsl +++ b/assets/SDSL/RenderTests/CompositionTest1.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F) +// PSMain(ExpectedResult=#32323232) namespace Stride.Shaders.Tests; @@ -6,7 +6,7 @@ shader CompositionBase { float4 Compute() { - return float4(0.1, 0.1, 0.1, 0.1); + return float4(10.0, 10.0, 10.0, 10.0) / 255.0; } }; @@ -14,7 +14,7 @@ shader CompositionShaderA : CompositionBase { override float4 Compute() { - return float4(0.2, 0.2, 0.2, 0.2); + return float4(20.0, 20.0, 20.0, 20.0) / 255.0; } }; @@ -22,7 +22,7 @@ shader CompositionShaderB : CompositionBase { override float4 Compute() { - return base.Compute() + float4(0.1, 0.1, 0.1, 0.1); + return base.Compute() + float4(10.0, 10.0, 10.0, 10.0) / 255.0; } }; diff --git a/assets/SDSL/RenderTests/CompositionTestStage1.sdsl b/assets/SDSL/RenderTests/CompositionTestStage1.sdsl index 2dc1d6fe8a..ee15c919d2 100644 --- a/assets/SDSL/RenderTests/CompositionTestStage1.sdsl +++ b/assets/SDSL/RenderTests/CompositionTestStage1.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#BF407FFF) +// PSMain(ExpectedResult=#06020408) namespace Stride.Shaders.Tests; @@ -6,22 +6,22 @@ shader CompositionBase { stage float BaseStageMethod1() { - return 0.125; + return 1.0; } stage float BaseStageMethod2() { - return 0.125; + return 1.0; } stage float BaseStageMethod3() { - return 0.125; + return 1.0; } stage float BaseStageMethod4() { - return 0.25; + return 2.0; } }; @@ -29,12 +29,12 @@ shader CompositionShaderA : CompositionBase { stage override float BaseStageMethod2() { - return base.BaseStageMethod2() + 0.125; + return base.BaseStageMethod2() + 1.0; } stage override float BaseStageMethod4() { - return base.BaseStageMethod4() + 0.25; + return base.BaseStageMethod4() + 2.0; } }; @@ -42,12 +42,12 @@ shader CompositionShaderB : CompositionBase { stage override float BaseStageMethod3() { - return base.BaseStageMethod3() + 0.375; + return base.BaseStageMethod3() + 3.0; } stage override float BaseStageMethod4() { - return base.BaseStageMethod4() + 0.25; + return base.BaseStageMethod4() + 2.0; } }; @@ -60,17 +60,17 @@ shader CompositionTest : CompositionBase stage override float BaseStageMethod1() { - return base.BaseStageMethod1() + 0.625; + return base.BaseStageMethod1() + 5.0; } stage override float BaseStageMethod4() { - return base.BaseStageMethod4() + 0.25; + return base.BaseStageMethod4() + 2.0; } void PSMain() { - streams.ColorTarget = float4(BaseStageMethod1(), BaseStageMethod2(), BaseStageMethod3(), BaseStageMethod4()); + streams.ColorTarget = float4(BaseStageMethod1(), BaseStageMethod2(), BaseStageMethod3(), BaseStageMethod4()) / 255.0; } }; diff --git a/assets/SDSL/RenderTests/CompositionTestStage2.sdsl b/assets/SDSL/RenderTests/CompositionTestStage2.sdsl index 7cfedeca57..ee9b2187ca 100644 --- a/assets/SDSL/RenderTests/CompositionTestStage2.sdsl +++ b/assets/SDSL/RenderTests/CompositionTestStage2.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#BFBFFFFF) +// PSMain(ExpectedResult=#09090000) namespace Stride.Shaders.Tests; @@ -6,17 +6,12 @@ shader CompositionBase { stage float BaseStageMethod1() { - return 0.25; - } - - float ComputeBase() - { - return 0.1; + return 2.0; } float ComputeThis() { - return 0.1; + return 2.0; } }; @@ -24,7 +19,7 @@ shader CompositionShaderA : CompositionBase { stage override float BaseStageMethod1() { - return base.BaseStageMethod1() + 0.25; + return base.BaseStageMethod1() + 3.0; } override float ComputeThis() @@ -37,7 +32,7 @@ shader CompositionShaderB : CompositionBase { stage override float BaseStageMethod1() { - return base.BaseStageMethod1() + 0.25; + return base.BaseStageMethod1() + 4.0; } override float ComputeThis() @@ -55,7 +50,7 @@ shader CompositionTest void PSMain() { - streams.ColorTarget = float4(Comp0.ComputeThis(), Comp1.ComputeThis(), 1.0, 1.0); + streams.ColorTarget = float4(Comp0.ComputeThis(), Comp1.ComputeThis(), 0.0, 0.0) / 255.0; } }; diff --git a/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl b/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl index c934c4779a..9f5f493637 100644 --- a/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl +++ b/assets/SDSL/RenderTests/ConstantFloat4Return.sdsl @@ -8,6 +8,6 @@ shader ConstantFloat4Return void PSMain() { - streams.ColorTarget = float4(1.0, 0.0, 0.5, 1.0); + streams.ColorTarget = float4(255.0, 0.0, 127.0, 255.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/For.sdsl b/assets/SDSL/RenderTests/For.sdsl index 4cbdd90453..a51a4d7741 100644 --- a/assets/SDSL/RenderTests/For.sdsl +++ b/assets/SDSL/RenderTests/For.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F) +// PSMain(ExpectedResult=#05050505) namespace Stride.Shaders.Tests; @@ -11,7 +11,7 @@ shader For streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < 5; ++i) { - streams.ColorTarget += float4(0.1, 0.1, 0.1, 0.1); + streams.ColorTarget += float4(1.0, 1.0, 1.0, 1.0) / 255.0; } } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/ForBreak.sdsl b/assets/SDSL/RenderTests/ForBreak.sdsl index c348ea039e..4b757457aa 100644 --- a/assets/SDSL/RenderTests/ForBreak.sdsl +++ b/assets/SDSL/RenderTests/ForBreak.sdsl @@ -1,5 +1,5 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=10) -// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=5) +// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.Test=10) +// PSMain(ExpectedResult=#05050505, cbuffer.Test=5) // PSMain(ExpectedResult=#00000000, cbuffer.Test=0) namespace Stride.Shaders.Tests; @@ -20,7 +20,7 @@ shader ForBreak { if (i == Test1) break; - streams.ColorTarget += float4(0.1, 0.1, 0.1, 0.1); + streams.ColorTarget += float4(1.0, 1.0, 1.0, 1.0) / 255.0; } } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/ForContinue.sdsl b/assets/SDSL/RenderTests/ForContinue.sdsl index 9f690552b4..8337870ba1 100644 --- a/assets/SDSL/RenderTests/ForContinue.sdsl +++ b/assets/SDSL/RenderTests/ForContinue.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F0000) +// PSMain(ExpectedResult=#05050000) namespace Stride.Shaders.Tests; @@ -18,13 +18,13 @@ shader ForContinue { if (i % 2 == 0) continue; - streams.ColorTarget += float4(0.1, 0.0, 0.0, 0.0); + streams.ColorTarget += float4(1.0, 0.0, 0.0, 0.0) / 255.0; } for (i = 0; i < 10; ++i) { if (i % 2 == 1) continue; - streams.ColorTarget += float4(0.0, 0.1, 0.0, 0.0); + streams.ColorTarget += float4(0.0, 1.0, 0.0, 0.0) / 255.0; } } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElse.sdsl b/assets/SDSL/RenderTests/IfElse.sdsl index 9760baa68d..4d525334a3 100644 --- a/assets/SDSL/RenderTests/IfElse.sdsl +++ b/assets/SDSL/RenderTests/IfElse.sdsl @@ -18,6 +18,6 @@ shader IfElse if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElseif.sdsl b/assets/SDSL/RenderTests/IfElseif.sdsl index fa75f4d288..9dba34113e 100644 --- a/assets/SDSL/RenderTests/IfElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseif.sdsl @@ -19,6 +19,6 @@ shader IfElseif if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else if (Test1 == 2) - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElseifElse.sdsl b/assets/SDSL/RenderTests/IfElseifElse.sdsl index 108345c5c6..3dbc4b5dc4 100644 --- a/assets/SDSL/RenderTests/IfElseifElse.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElse.sdsl @@ -19,8 +19,8 @@ shader IfElseifElse if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else if (Test1 == 2) - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; else - streams.ColorTarget = float4(1.0, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(255.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/IfElseifElseif.sdsl b/assets/SDSL/RenderTests/IfElseifElseif.sdsl index 8d84db5d06..759e1f78b6 100644 --- a/assets/SDSL/RenderTests/IfElseifElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElseif.sdsl @@ -20,8 +20,8 @@ shader IfElseifElseif if (Test1 == 1) streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0); else if (Test1 == 2) - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; else if (Test1 == 3) - streams.ColorTarget = float4(1.0, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(255.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/MethodForwardCall.sdsl b/assets/SDSL/RenderTests/MethodForwardCall.sdsl index ab49b51f50..200cf06cc3 100644 --- a/assets/SDSL/RenderTests/MethodForwardCall.sdsl +++ b/assets/SDSL/RenderTests/MethodForwardCall.sdsl @@ -20,6 +20,6 @@ shader MethodForwardCall void Test() { - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/PositionStreams.sdsl b/assets/SDSL/RenderTests/PositionStreams.sdsl index cb89bc0dfe..9b254a6002 100644 --- a/assets/SDSL/RenderTests/PositionStreams.sdsl +++ b/assets/SDSL/RenderTests/PositionStreams.sdsl @@ -15,6 +15,6 @@ shader PositionStreams void PSMain() { - streams.ColorTarget = float4(0.5, 0.5, 0.5, 0.5); + streams.ColorTarget = float4(127.0, 127.0, 127.0, 127.0) / 255.0; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/SimpleInheritance.sdsl b/assets/SDSL/RenderTests/SimpleInheritance.sdsl index 8a61ade03b..74fffa82cc 100644 --- a/assets/SDSL/RenderTests/SimpleInheritance.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritance.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F) +// PSMain(ExpectedResult=#01010101) namespace Stride.Shaders.Tests; @@ -25,7 +25,7 @@ shader SimpleInheritance : SimpleInheritanceBase void Test() { streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); - SetColor(float4(0.5, 0.5, 0.5, 0.5)); + SetColor(float4(1.0, 1.0, 1.0, 1.0) / 255.0); } void PSMain() diff --git a/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl index ceeb4c335e..cbeea1d4a2 100644 --- a/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritanceAbstract.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F) +// PSMain(ExpectedResult=#01010101) namespace Stride.Shaders.Tests; @@ -25,7 +25,7 @@ shader SimpleInheritanceBase3 : SimpleInheritanceBase2 void Test() { streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); - SetColor(float4(0.5, 0.5, 0.5, 0.5)); + SetColor(float4(1.0, 1.0, 1.0, 1.0) / 255.0); } void PSMain() diff --git a/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl b/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl index dd10166c5c..83241c9211 100644 --- a/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl +++ b/assets/SDSL/RenderTests/SimpleInheritanceBaseThis.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#FFFFFFFF) +// PSMain(ExpectedResult=#02020202) namespace Stride.Shaders.Tests; @@ -16,7 +16,7 @@ shader SimpleInheritanceBase void Test() { streams.ColorTarget = float4(0.0, 1.0, 1.0, 0.0); - this.SetColor(float4(0.5, 0.5, 0.5, 0.5)); + this.SetColor(float4(1.0, 1.0, 1.0, 1.0) / 255.0); } void PSMain() diff --git a/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl index eac936a4b5..3e9facf76e 100644 --- a/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl +++ b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/StreamVSToPS.sdsl b/assets/SDSL/RenderTests/StreamVSToPS.sdsl index a59cf9693c..801da69678 100644 --- a/assets/SDSL/RenderTests/StreamVSToPS.sdsl +++ b/assets/SDSL/RenderTests/StreamVSToPS.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.5 0.5 0.5 0.5)) +// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; From e7d6313784004a2f08199c81e3137cef922a72cb Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 12 Nov 2025 16:20:07 +0100 Subject: [PATCH 0503/1182] adding dll and first binding code --- .gitattributes | 1 + .../Direct3D/Spv2DXIL.cs | 129 ++++++++++++++++++ .../Stride.Shaders.Compilers.csproj | 8 ++ .../native/spirv_to_dxil.dll | 3 + src/Stride.Shaders.Experiments/Program.cs | 3 + 5 files changed, 144 insertions(+) create mode 100644 .gitattributes create mode 100644 src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs create mode 100644 src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..7e2639079b --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +src/Stride.Shaders.Compilers/native/*.dll filter=lfs diff=lfs merge=lfs -text diff --git a/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs new file mode 100644 index 0000000000..5452f919dc --- /dev/null +++ b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -0,0 +1,129 @@ +using System.Runtime.InteropServices; + +namespace Stride.Shaders.Compilers.Direct3D; +public enum ShaderStage +{ + DXIL_SPIRV_SHADER_NONE = -1, + DXIL_SPIRV_SHADER_VERTEX = 0, + DXIL_SPIRV_SHADER_TESS_CTRL = 1, + DXIL_SPIRV_SHADER_TESS_EVAL = 2, + DXIL_SPIRV_SHADER_GEOMETRY = 3, + DXIL_SPIRV_SHADER_FRAGMENT = 4, + DXIL_SPIRV_SHADER_COMPUTE = 5, + DXIL_SPIRV_SHADER_KERNEL = 14, +} + +public struct DebugOptions +{ + bool dump_nir; +} + + +public struct RuntimeConf +{ + struct runtime_data_cbv + { + ushort register_space; + ushort base_shader_register; + } + + + struct PushConstantCBV + { + ushort register_space; + ushort base_shader_register; + } + + enum FirstVertexAndBaseInstanceMode; + enum WorkgroupIdMode; + + struct YZFlip + { + // mode != DXIL_SPIRV_YZ_FLIP_NONE only valid on vertex/geometry stages. + enum Mode; + + // Y/Z flip masks (one bit per viewport) + ushort y_mask; + ushort z_mask; + } + + // The caller supports read-only images to be turned into SRV accesses, + // which allows us to run the nir_opt_access() pass + bool declared_read_only_images_as_srvs; + + // The caller supports read-write images to be turned into SRV accesses, + // if they are found not to be written + bool inferred_read_only_images_as_srvs; + + // Force sample rate shading on a fragment shader + bool force_sample_rate_shading; + + // View index needs to be lowered to a UBO lookup + bool lower_view_index; + // View index also needs to be forwarded to RT layer output + bool lower_view_index_to_rt_layer; + + // Affects which features can be used by the shader + enum Shader_model_max; +} + +public unsafe delegate void MSGCallback(void* priv, string msg); + +public unsafe struct DXILSpirvLogger +{ + void* priv; + MSGCallback log; +} + +public unsafe struct DXILSpirvObject { + struct Metadata; + struct Binary { + void *buffer; + nint size; + } +} +public unsafe struct Specialization +{ + ushort id; + void* value; + bool defined_on_module; +} + +public enum ValidatorVersion { + NO_DXIL_VALIDATION, + DXIL_VALIDATOR_1_0 = 0x10000, + DXIL_VALIDATOR_1_1, + DXIL_VALIDATOR_1_2, + DXIL_VALIDATOR_1_3, + DXIL_VALIDATOR_1_4, + DXIL_VALIDATOR_1_5, + DXIL_VALIDATOR_1_6, + DXIL_VALIDATOR_1_7, + DXIL_VALIDATOR_1_8, +}; + + +public static partial class Spv2DXIL +{ + + // Import user32.dll (containing the function we need) and define + // the method corresponding to the native function. + [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] + public static unsafe partial int spirv_to_dxil( + uint* words, + nint word_count, + Specialization* specializations, + uint num_specializations, + ShaderStage stage, + string entry_point_name, + ValidatorVersion validator_version_max, + DebugOptions* debug_options, + RuntimeConf* conf, + DXILSpirvLogger* logger, + DXILSpirvObject* out_dxil + ); + + + [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] + public static partial ulong spirv_to_dxil_get_version(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index a3475c90da..12d74a0985 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -13,6 +13,14 @@ + + + Always + + + + + net9.0 enable diff --git a/src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll b/src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll new file mode 100644 index 0000000000..3005432c94 --- /dev/null +++ b/src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d297308f57af16ca5913232e5b9fa8e1f30fcde9073622883bc811a7413a32b6 +size 7740416 diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index e29b866bde..d770b7d0d2 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -3,6 +3,9 @@ using Stride.Shaders.Spirv.Core.Buffers; using System.Runtime.InteropServices; using Stride.Shaders.Spirv.Tools; +using Stride.Shaders.Compilers.Direct3D; + +Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); // Examples.CompileSDSL("RenderTests/If"); From 085c1648c6aa407693b499f08a44d42f89efc563 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 13 Nov 2025 10:35:43 +0900 Subject: [PATCH 0504/1182] Update to .NET 10.0 --- src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj | 2 +- src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj | 2 +- src/Stride.Shaders.Experiments/Examples.Spirv.cs | 2 +- src/Stride.Shaders.Experiments/Program.cs | 2 +- .../Stride.Shaders.Experiments.csproj | 2 +- src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj | 2 +- src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj | 3 +-- src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj | 2 +- src/Stride.Shaders/Stride.Shaders.csproj | 3 +-- 9 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj index 8e2b1f0510..80a1afc7fb 100644 --- a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj +++ b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable true diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index a3475c90da..82d8c6512e 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -14,7 +14,7 @@ - net9.0 + net10.0 enable enable true diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 93317ab357..0a9b14bd73 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -283,7 +283,7 @@ public static void ParseWorking() var bytes = File.ReadAllBytes(path); - var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytes)); + var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytes.AsSpan())); var extInst = (OpExtInstImport)buffer[1] ; Console.WriteLine(extInst.Name); } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index e29b866bde..8a6abc4082 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -11,7 +11,7 @@ loader.LoadExternalFile("Test", out var testBuffer); var shaderMixer = new ShaderMixer(loader); shaderMixer.MergeSDSL("If", out var bytecode); -var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode)); +var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index d57c2a62e4..281c1249da 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -4,7 +4,7 @@ Exe - net9.0 + net10.0 enable enable true diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index a1970af07f..849ee22ec2 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 61e31fa4fb..d1d96bdcd3 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,12 +1,11 @@ - net9.0 + net10.0 enable enable true Generated - preview diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index e398cbba8f..2110d87e2b 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -1,7 +1,7 @@  - net9.0 + net10.0 enable enable diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 89987e6e88..5ed5678ae1 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -6,10 +6,9 @@ - net9.0 + net10.0 enable enable - preview True From 3ef6bf20d706cbf3b0ae78b0196e37e1faf0a147 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 13 Nov 2025 11:38:25 +0900 Subject: [PATCH 0505/1182] Remove composition variables (invalid SPIR-V) --- .../SDSL/ShaderMixer.ShaderInfo.cs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 418dd5e7c3..02af4f5f83 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -40,6 +40,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) { ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); + var removedIds = new HashSet(); for (var index = shaderStart; index < shaderEnd; index++) { var i = temp[index]; @@ -56,7 +57,37 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { var variableName = shaderInfo.Names[variable.ResultId]; - shaderInfo!.Variables.Add(variableName, (variable.ResultId, types[variable.ResultType])); + var variableType = types[variable.ResultType]; + shaderInfo!.Variables.Add(variableName, (variable.ResultId, variableType)); + + // Remove SPIR-V variables to other shaders (already stored in ShaderInfo and not valid SPIR-V) + if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + { + SetOpNop(i.Data.Memory.Span); + removedIds.Add(variable.ResultId); + } + } + else if (i.Data.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) + { + // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) + var pointedType = types[typePointer.Type]; + if (pointedType is ShaderSymbol) + { + SetOpNop(i.Data.Memory.Span); + removedIds.Add(typePointer.ResultId); + } + } + } + + // Second pass to remove OpName + for (var index = shaderStart; index < shaderEnd; index++) + { + var i = temp[index]; + + if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + { + if (removedIds.Contains(nameInstruction.Target)) + SetOpNop(i.Data.Memory.Span); } } } From a8761037f27e66f4e6fcb56fd7a39859d4fa5821 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 13 Nov 2025 11:40:21 +0900 Subject: [PATCH 0506/1182] Bumped nuget packages --- .../Stride.Shaders.Compilers.csproj | 10 +++++----- src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj | 8 ++++---- .../Stride.Shaders.Spirv.Core.csproj | 4 ++-- .../Stride.Shaders.Spirv.Generators.csproj | 14 +++++++------- .../Stride.Shaders.Parsing.Tests.csproj | 11 +++++++---- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 82d8c6512e..a1c9d649a8 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -6,11 +6,11 @@ - - - - - + + + + + diff --git a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj index 849ee22ec2..6f1a2f6c9e 100644 --- a/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ b/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj @@ -9,13 +9,13 @@ - + - - + + - + diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index d1d96bdcd3..2172d6c292 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,4 +1,4 @@ - + net10.0 @@ -11,7 +11,7 @@ - + diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 58f3e67c96..2798e4fb65 100644 --- a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -13,14 +13,14 @@ - + - - - - - - + + + + + + diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 2110d87e2b..6f4416625b 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -11,11 +11,14 @@ - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - + From 28ad3580d5aee178107813a69b5b8ea5f7279b7a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 12 Nov 2025 21:08:33 +0100 Subject: [PATCH 0507/1182] fix op cst ctor --- .../SPVGenerator.Instructions.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index ca679cb29f..b2bf22de5c 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -542,8 +542,7 @@ private set static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("DataIndex = index;"); + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { From 1b79571a56bc0577899c1aaacc14b083f7c51633 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 18 Nov 2025 17:55:35 +0100 Subject: [PATCH 0508/1182] parsing intrinsics --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 574 ++++++++++++++++++ .../Parsing/SDSL/AST/Expression.cs | 1 - .../PrimaryExpressionParsers.cs | 86 ++- 3 files changed, 659 insertions(+), 2 deletions(-) create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs new file mode 100644 index 0000000000..3cb5c64fd1 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -0,0 +1,574 @@ +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; + +namespace Stride.Shaders.Parsing.SDSL; + + +public class RoundCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("round", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class RoundEvenCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("roundeven", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class TruncCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("trunc", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sabs", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fsign", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ssign", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FloorCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("floor", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class CeilCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ceil", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fract", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class RadiansCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("radians", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class DegreesCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("degrees", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class CosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cos", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class TanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tan", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AsinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AcosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acos", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AtanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sinh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class CoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cosh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class TanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tanh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AsinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asinh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AcoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acosh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class AtanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atanh", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class Atan2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan2", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PowCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class ExpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class LogCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class Exp2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp2", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class Log2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log2", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sqrt", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class InverseSqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("inversesqrt", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class DeterminantCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("determinant", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class MatrixInverseCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("matrixinverse", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class ModfCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modf", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class ModfStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modfstruct", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmax", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umax", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smax", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fclamp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("uclamp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sclamp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmix", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class IMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("imix", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class StepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("step", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smoothstep", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FmaCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fma", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FrexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FrexpStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexpstruct", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class LdexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ldexp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm4x8", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm4x8", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packhalf2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class PackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packdouble2x32", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackhalf2x16", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm4x8", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm4x8", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class UnpackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackdouble2x32", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class LengthCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("length", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("distance", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class CrossCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cross", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("normalize", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("faceforward", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("reflect", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class RefractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("refract", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FindILsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findilsb", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FindSMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findsmsb", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class FindUMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findumsb", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class InterpolateAtCentroidCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatcentroid", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class InterpolateAtSampleCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatsample", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class InterpolateAtOffsetCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatoffset", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class NMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmin", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class NMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmax", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} +public class NClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nclamp", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index caae2fa33f..cf1b52c500 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -90,7 +90,6 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); } - public override string ToString() { return $"{Name}({string.Join(", ", Parameters)})"; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 8dbcc0980d..16a040f1d2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -51,7 +51,91 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char(')', ref scanner, advance: true)) { - parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); + parsed = (identifier.Name, parameters.Values.Count) switch + { + ("Round", 1) => new RoundCall(parameters, scanner[position..scanner.Position]), + ("RoundEven", 1) => new RoundEvenCall(parameters, scanner[position..scanner.Position]), + ("Trunc", 1) => new TruncCall(parameters, scanner[position..scanner.Position]), + ("FAbs", 1) => new FAbsCall(parameters, scanner[position..scanner.Position]), + ("SAbs", 1) => new SAbsCall(parameters, scanner[position..scanner.Position]), + ("FSign", 1) => new FSignCall(parameters, scanner[position..scanner.Position]), + ("SSign", 1) => new SSignCall(parameters, scanner[position..scanner.Position]), + ("Floor", 1) => new FloorCall(parameters, scanner[position..scanner.Position]), + ("Ceil", 1) => new CeilCall(parameters, scanner[position..scanner.Position]), + ("Fract", 1) => new FractCall(parameters, scanner[position..scanner.Position]), + ("Radians", 1) => new RadiansCall(parameters, scanner[position..scanner.Position]), + ("Degrees", 1) => new DegreesCall(parameters, scanner[position..scanner.Position]), + ("Sin", 1) => new SinCall(parameters, scanner[position..scanner.Position]), + ("Cos", 1) => new CosCall(parameters, scanner[position..scanner.Position]), + ("Tan", 1) => new TanCall(parameters, scanner[position..scanner.Position]), + ("Asin", 1) => new AsinCall(parameters, scanner[position..scanner.Position]), + ("Acos", 1) => new AcosCall(parameters, scanner[position..scanner.Position]), + ("Atan", 1) => new AtanCall(parameters, scanner[position..scanner.Position]), + ("Sinh", 1) => new SinhCall(parameters, scanner[position..scanner.Position]), + ("Cosh", 1) => new CoshCall(parameters, scanner[position..scanner.Position]), + ("Tanh", 1) => new TanhCall(parameters, scanner[position..scanner.Position]), + ("Asinh", 1) => new AsinhCall(parameters, scanner[position..scanner.Position]), + ("Acosh", 1) => new AcoshCall(parameters, scanner[position..scanner.Position]), + ("Atanh", 1) => new AtanhCall(parameters, scanner[position..scanner.Position]), + ("Atan2", 2) => new Atan2Call(parameters, scanner[position..scanner.Position]), + ("Pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), + ("Exp", 1) => new ExpCall(parameters, scanner[position..scanner.Position]), + ("Log", 1) => new LogCall(parameters, scanner[position..scanner.Position]), + ("Exp2", 1) => new Exp2Call(parameters, scanner[position..scanner.Position]), + ("Log2", 1) => new Log2Call(parameters, scanner[position..scanner.Position]), + ("Sqrt", 1) => new SqrtCall(parameters, scanner[position..scanner.Position]), + ("InverseSqrt", 1) => new InverseSqrtCall(parameters, scanner[position..scanner.Position]), + ("Determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), + ("MatrixInverse", 1) => new MatrixInverseCall(parameters, scanner[position..scanner.Position]), + ("Modf", 2) => new ModfCall(parameters, scanner[position..scanner.Position]), + ("ModfStruct", 1) => new ModfStructCall(parameters, scanner[position..scanner.Position]), + ("FMin", 2) => new FMinCall(parameters, scanner[position..scanner.Position]), + ("UMin", 2) => new UMinCall(parameters, scanner[position..scanner.Position]), + ("SMin", 2) => new SMinCall(parameters, scanner[position..scanner.Position]), + ("FMax", 2) => new FMaxCall(parameters, scanner[position..scanner.Position]), + ("UMax", 2) => new UMaxCall(parameters, scanner[position..scanner.Position]), + ("SMax", 2) => new SMaxCall(parameters, scanner[position..scanner.Position]), + ("FClamp", 3) => new FClampCall(parameters, scanner[position..scanner.Position]), + ("UClamp", 3) => new UClampCall(parameters, scanner[position..scanner.Position]), + ("SClamp", 3) => new SClampCall(parameters, scanner[position..scanner.Position]), + ("FMix", 3) => new FMixCall(parameters, scanner[position..scanner.Position]), + ("IMix", 3) => new IMixCall(parameters, scanner[position..scanner.Position]), + ("Step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), + ("SmoothStep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), + ("Fma", 3) => new FmaCall(parameters, scanner[position..scanner.Position]), + ("Frexp", 2) => new FrexpCall(parameters, scanner[position..scanner.Position]), + ("FrexpStruct", 1) => new FrexpStructCall(parameters, scanner[position..scanner.Position]), + ("Ldexp", 2) => new LdexpCall(parameters, scanner[position..scanner.Position]), + ("PackSnorm4x8", 1) => new PackSnorm4x8Call(parameters, scanner[position..scanner.Position]), + ("PackUnorm4x8", 1) => new PackUnorm4x8Call(parameters, scanner[position..scanner.Position]), + ("PackSnorm2x16", 1) => new PackSnorm2x16Call(parameters, scanner[position..scanner.Position]), + ("PackUnorm2x16", 1) => new PackUnorm2x16Call(parameters, scanner[position..scanner.Position]), + ("PackHalf2x16", 1) => new PackHalf2x16Call(parameters, scanner[position..scanner.Position]), + ("PackDouble2x32", 1) => new PackDouble2x32Call(parameters, scanner[position..scanner.Position]), + ("UnpackSnorm2x16", 1) => new UnpackSnorm2x16Call(parameters, scanner[position..scanner.Position]), + ("UnpackUnorm2x16", 1) => new UnpackUnorm2x16Call(parameters, scanner[position..scanner.Position]), + ("UnpackHalf2x16", 1) => new UnpackHalf2x16Call(parameters, scanner[position..scanner.Position]), + ("UnpackSnorm4x8", 1) => new UnpackSnorm4x8Call(parameters, scanner[position..scanner.Position]), + ("UnpackUnorm4x8", 1) => new UnpackUnorm4x8Call(parameters, scanner[position..scanner.Position]), + ("UnpackDouble2x32", 1) => new UnpackDouble2x32Call(parameters, scanner[position..scanner.Position]), + ("Length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), + ("Distance", 2) => new DistanceCall(parameters, scanner[position..scanner.Position]), + ("Cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), + ("Normalize", 1) => new NormalizeCall(parameters, scanner[position..scanner.Position]), + ("FaceForward", 3) => new FaceForwardCall(parameters, scanner[position..scanner.Position]), + ("Reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), + ("Refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), + ("FindILsb", 1) => new FindILsbCall(parameters, scanner[position..scanner.Position]), + ("FindSMsb", 1) => new FindSMsbCall(parameters, scanner[position..scanner.Position]), + ("FindUMsb", 1) => new FindUMsbCall(parameters, scanner[position..scanner.Position]), + ("InterpolateAtCentroid", 2) => new InterpolateAtCentroidCall(parameters, scanner[position..scanner.Position]), + ("InterpolateAtSample", 2) => new InterpolateAtSampleCall(parameters, scanner[position..scanner.Position]), + ("InterpolateAtOffset", 2) => new InterpolateAtOffsetCall(parameters, scanner[position..scanner.Position]), + ("NMin", 2) => new NMinCall(parameters, scanner[position..scanner.Position]), + ("NMax", 2) => new NMaxCall(parameters, scanner[position..scanner.Position]), + ("NClamp", 3) => new NClampCall(parameters, scanner[position..scanner.Position]), + _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]) + }; return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); From 2ea369dcef2f12a02b0cf71897e2b132f8216ce3 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 18 Nov 2025 18:14:28 +0100 Subject: [PATCH 0509/1182] writing some compilation code --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 169 +++++++++++++++--- src/Stride.Shaders/Spirv/Building/Context.cs | 17 +- 2 files changed, 161 insertions(+), 25 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 3cb5c64fd1..08a18545c5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDSL; @@ -9,168 +10,288 @@ public class RoundCall(ShaderExpressionList parameters, TextLocation info) : Met { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRound(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class RoundEvenCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("roundeven", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class TruncCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("trunc", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLTrunc(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sabs", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fsign", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ssign", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FloorCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("floor", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class CeilCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ceil", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fract", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class RadiansCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("radians", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class DegreesCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("degrees", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class CosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cos", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class TanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tan", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AsinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AcosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acos", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AtanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sinh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class CoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cosh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class TanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tanh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AsinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asinh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AcoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acosh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class AtanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atanh", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if(context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class Atan2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan2", info), parameters, info) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 7c4e7b1020..c73830cbf2 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -50,6 +50,8 @@ public class SpirvContext public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; NewSpirvBuffer Buffer { get; set; } = new(); + public int? GLSLSet { get; private set; } + public void PutShaderName(string name) { if (Name is null) @@ -59,6 +61,19 @@ public void PutShaderName(string name) } else throw new NotImplementedException(); } + public void ImportGLSL() + { + foreach(var i in Buffer) + { + if(i.Op == Op.OpExtInstImport && (OpExtInstImport)i is { Name: "GLSL.std.450" }) + { + GLSLSet ??= ((OpExtInstImport)i).ResultId; + return; + } + } + Buffer.Insert(1, new OpExtInstImport(Bound++, "GLSL.std.450")); + GLSLSet = Bound - 1; + } public void AddName(int target, string name) => Buffer.Add(new OpName(target, name)); @@ -280,7 +295,7 @@ public SpirvValue CreateConstant(Literal literal) }; if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) - return result; + return result; var instruction = literal switch { BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), From ae2402907c75c84f9bcb34dcaceef20406ac9644 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Wed, 19 Nov 2025 10:36:28 +0100 Subject: [PATCH 0510/1182] compilation of GLSL intrinsics functions --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 543 +++++++++++++----- 1 file changed, 414 insertions(+), 129 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 08a18545c5..eb257574ab 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -11,10 +11,10 @@ public class RoundCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRound(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRound(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -23,10 +23,10 @@ public class RoundEvenCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -35,10 +35,10 @@ public class TruncCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLTrunc(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLTrunc(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -47,10 +47,10 @@ public class FAbsCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -59,10 +59,10 @@ public class SAbsCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -71,10 +71,10 @@ public class FSignCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -83,10 +83,10 @@ public class SSignCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -95,10 +95,10 @@ public class FloorCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -107,10 +107,10 @@ public class CeilCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -119,10 +119,10 @@ public class FractCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -131,10 +131,10 @@ public class RadiansCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var radians = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -143,10 +143,10 @@ public class DegreesCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var radians = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -155,10 +155,10 @@ public class SinCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -167,10 +167,10 @@ public class CosCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -179,10 +179,10 @@ public class TanCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -191,10 +191,10 @@ public class AsinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -203,10 +203,10 @@ public class AcosCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -215,10 +215,10 @@ public class AtanCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var y_over_x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(y_over_x.TypeId, context.Bound++, context.GLSLSet ?? -1, y_over_x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -227,10 +227,10 @@ public class SinhCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -239,10 +239,10 @@ public class CoshCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -251,10 +251,10 @@ public class TanhCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -263,10 +263,10 @@ public class AsinhCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -275,10 +275,10 @@ public class AcoshCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -287,10 +287,10 @@ public class AtanhCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); - if(context.GLSLSet == null) + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -298,398 +298,683 @@ public class Atan2Call(ShaderExpressionList parameters, TextLocation info) : Met { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLAtan2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PowCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class ExpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLExp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class LogCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLLog(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class Exp2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp2", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLExp2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class Log2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log2", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLLog2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sqrt", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLSqrt(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class InverseSqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("inversesqrt", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLInverseSqrt(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class DeterminantCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("determinant", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLDeterminant(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class MatrixInverseCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("matrixinverse", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLMatrixInverse(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class ModfCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modf", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, i) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLModf(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, i.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class ModfStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modfstruct", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLModfStruct(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmax", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umax", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smax", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fclamp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("uclamp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sclamp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmix", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y, a) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class IMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("imix", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y, a) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLIMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class StepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("step", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (edge, x) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLStep(edge.TypeId, context.Bound++, context.GLSLSet ?? -1, edge.Id, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smoothstep", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (edge0, edge1, x) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLSmoothStep(edge0.TypeId, context.Bound++, context.GLSLSet ?? -1, edge0.Id, edge1.Id, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FmaCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fma", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (a, b, c) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GLSLSet ?? -1, a.Id, b.Id, a.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FrexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, exp) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFrexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FrexpStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexpstruct", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLMatrixInverse(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class LdexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ldexp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, exp) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLLdexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm4x8", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackSnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm4x8", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackUnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackSnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackUnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packhalf2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class PackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packdouble2x32", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLPackDouble2x32(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackSnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackUnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackhalf2x16", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var v = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm4x8", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackSnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm4x8", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackUnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class UnpackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackdouble2x32", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var p = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLUnpackDouble2x32(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class LengthCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("length", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLLength(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("distance", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (p0, p1) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLDistance(p0.TypeId, context.Bound++, context.GLSLSet ?? -1, p0.Id, p1.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class CrossCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cross", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLCross(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("normalize", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var x = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLNormalize(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("faceforward", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (N, I, Nre) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GLSLSet ?? -1, N.Id, I.Id, Nre.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("reflect", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (I, N) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLReflect(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class RefractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("refract", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (I, N, eta) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLRefract(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id, eta.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FindILsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findilsb", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var value = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFindILsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FindSMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findsmsb", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var value = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFindSMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class FindUMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findumsb", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var value = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLFindUMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class InterpolateAtCentroidCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatcentroid", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var interpolant = Parameters.Values[0].Compile(table, shader, compiler); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLInterpolateAtCentroid(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class InterpolateAtSampleCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatsample", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (interpolant, sample) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLInterpolateAtSample(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, sample.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class InterpolateAtOffsetCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatoffset", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (interpolant, offset) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLInterpolateAtOffset(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, offset.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class NMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmin", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLNMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class NMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmax", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLNMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); } } public class NClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nclamp", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new GLSLNClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); + return new(instruction.ResultId, instruction.ResultType); } } \ No newline at end of file From 02f9a6aad2974921cc9646228b4bdd31b31d00f6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 21 Nov 2025 19:14:24 +0900 Subject: [PATCH 0511/1182] Texture: improvements and fixes so that it work all the way to SDSL and unit tests --- assets/SDSL/RenderTests/Textures.sdsl | 17 +++++++++ .../FrameRenderer.OpenGL.cs | 29 ++++++++++++++- .../SpirvTranslator.cs | 16 +++++++++ src/Stride.Shaders/Core/SymbolTypes.cs | 33 ++++++++--------- .../Parsing/SDSL/AST/Expression.cs | 32 ++++++++--------- .../Parsing/SDSL/AST/Literals.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 36 +++++++++++++++++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 17 ++++++--- .../Spirv/Processing/StreamAnalyzer.cs | 30 +++++++++++++--- 9 files changed, 164 insertions(+), 48 deletions(-) create mode 100644 assets/SDSL/RenderTests/Textures.sdsl diff --git a/assets/SDSL/RenderTests/Textures.sdsl b/assets/SDSL/RenderTests/Textures.sdsl new file mode 100644 index 0000000000..8158c29418 --- /dev/null +++ b/assets/SDSL/RenderTests/Textures.sdsl @@ -0,0 +1,17 @@ +// PSMain(ExpectedResult=#1357ABCD, texture.SPIRV_Cross_CombinedTexture1Sampler1=#1357ABCD) + +namespace Stride.Shaders.Tests; + +shader Textures +{ + stream float4 ColorTarget : SV_Target0; + stream float4 TexCoord : TEXCOORD; + + stage Texture2D Texture1; + stage SamplerState Sampler1; + + void PSMain() + { + streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord); + } +} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs index 58505c6a06..8777802f2c 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs @@ -1,7 +1,10 @@ -using Silk.NET.Maths; +using Silk.NET.Core.Native; +using Silk.NET.Maths; using Silk.NET.OpenGL; using Silk.NET.Windowing; using System; +using System.Drawing; +using System.Globalization; using System.Text; namespace Stride.Graphics.RHI; @@ -233,6 +236,30 @@ public override unsafe void RenderFrame(Span result) Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); } + else if (param.Key.StartsWith("texture.")) + { + if (!param.Value.StartsWith("#")) + throw new NotSupportedException(); + + var textureName = param.Key.Substring("texture.".Length); + var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, textureName); + if (location == -1) + throw new InvalidOperationException($"Could not find resource {textureName}"); + + var texture = Gl.GenTexture(); + Gl.BindTexture(GLEnum.Texture2D, texture); + + var hexColor = param.Value.Substring(1); + uint color = uint.Parse(hexColor.Substring(0, 8), NumberStyles.HexNumber); + color = (((color << 24) & 0xff000000) | + ((color << 8) & 0xff0000) | + ((color >> 8) & 0xff00) | + ((color >> 24) & 0xff)); + + Gl.TexImage2D(GLEnum.Texture2D, 0, (int)GLEnum.Rgba, 1, 1, 0, GLEnum.Rgba, GLEnum.UnsignedByte, (void*)&color); + + Gl.ProgramUniform1(Shader, location, texture); + } } //Draw the geometry. diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 3b73cc8191..57d53586a5 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -81,6 +81,22 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string Name, E if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); + + if (cross.CompilerBuildCombinedImageSamplers(compiler) != Result.Success) + throw new Exception($"{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers"); + + nuint numSamplers = 0; + CombinedImageSampler* combinedImageSamplers = null; + if (cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers) != Result.Success) + throw new Exception($"{cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers)}"); + + for (uint i = 0; i < numSamplers; ++i) + { + var textureName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].ImageId); + var samplerName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].SamplerId); + cross.CompilerSetName(compiler, combinedImageSamplers[i].CombinedId, $"SPIRV_Cross_Combined{textureName}{samplerName}"); + } + if (cross.CompilerCompile(compiler, &translated) != Result.Success) throw new Exception($"{cross.CompilerCompile(compiler, &translated)} : could not compile code"); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index d1b18eade2..6d085b4fdf 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -50,6 +50,7 @@ public static bool TryGetBufferType(string name, string? templateType, [MaybeNul ("Buffer", "float") => (new BufferType(ScalarType.From("float"), -1) as SymbolType, true), ("Buffer", "int") => (new BufferType(ScalarType.From("int"), -1), true), ("Buffer", "uint") => (new BufferType(ScalarType.From("uint"), -1), true), + // TODO: Use scalar type instead of vector type as in SPIR-V spec? ("Buffer", "float2") => (new BufferType(VectorType.From("float2"), -1), true), ("Buffer", "float3") => (new BufferType(VectorType.From("float3"), -1), true), ("Buffer", "float4") => (new BufferType(VectorType.From("float4"), -1), true), @@ -59,14 +60,14 @@ public static bool TryGetBufferType(string name, string? templateType, [MaybeNul ("Buffer", "uint2") => (new BufferType(VectorType.From("uint2"), -1), true), ("Buffer", "uint3") => (new BufferType(VectorType.From("uint3"), -1), true), ("Buffer", "uint4") => (new BufferType(VectorType.From("uint4"), -1), true), - ("Texture", null) => (new Texture1DType(VectorType.From("float4")), true), - ("Texture1D", null) => (new Texture1DType(VectorType.From("float4")), true), - ("Texture2D", null) => (new Texture2DType(VectorType.From("float4")), true), - ("Texture3D", null) => (new Texture3DType(VectorType.From("float4")), true), - ("Texture", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType)), true), - ("Texture1D", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType)), true), - ("Texture2D", "int4" or "uint4" or "float4") => (new Texture2DType(VectorType.From(templateType)), true), - ("Texture3D", "int4" or "uint4" or "float4") => (new Texture3DType(VectorType.From(templateType)), true), + ("Texture", null) => (new Texture1DType(ScalarType.From("float")), true), + ("Texture1D", null) => (new Texture1DType(ScalarType.From("float")), true), + ("Texture2D", null) => (new Texture2DType(ScalarType.From("float")), true), + ("Texture3D", null) => (new Texture3DType(ScalarType.From("float")), true), + ("Texture", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType).BaseType), true), + ("Texture1D", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType).BaseType), true), + ("Texture2D", "int4" or "uint4" or "float4") => (new Texture2DType(VectorType.From(templateType).BaseType), true), + ("Texture3D", "int4" or "uint4" or "float4") => (new Texture3DType(VectorType.From(templateType).BaseType), true), _ => (null, false) }; @@ -144,36 +145,36 @@ public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() } // TODO: Add sampler parameters -public sealed record SamplerType(string Name) : SymbolType() +public sealed record SamplerType() : SymbolType() { - public override string ToId() => $"{Name}"; - public override string ToString() => $"SamplerState {Name}"; + public override string ToId() => $"type_sampler"; + public override string ToString() => $"SamplerState"; } public sealed record SampledImage(TextureType ImageType) : SymbolType() { public override string ToString() => $"SampledImage<{ImageType}>"; } -public abstract record TextureType(SymbolType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() +public abstract record TextureType(ScalarType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() { public override string ToId() => $"Texture_{ReturnType}"; public override string ToString() => $"Texture<{ReturnType}>({Dimension}, {Depth}, {Arrayed}, {Multisampled}, {Sampled}, {Format})"; } -public sealed record Texture1DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) +public sealed record Texture1DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture1D<{ReturnType}>"; } -public sealed record Texture2DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) +public sealed record Texture2DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture2D<{ReturnType}>"; } -public sealed record Texture3DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) +public sealed record Texture3DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture3D<{ReturnType}>"; } -public sealed record TextureCubeType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) +public sealed record TextureCubeType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"TextureCube<{ReturnType}>"; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index caae2fa33f..46cb5daed2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -205,34 +205,30 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } if (Source is Identifier { ValueType: TextureType or Texture2DType or Texture3DType } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) { - result = Source.Compile(table, shader, compiler); + result = Source.CompileAsValue(table, shader, compiler); if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) { - var samplerValue = implicitSampling.Parameters.Values[0].Compile(table, shader, compiler); - var texCoordValue = implicitSampling.Parameters.Values[1].Compile(table, shader, compiler); + var textureValue = result; + var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, shader, compiler); + var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, shader, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); - var loadSampler = builder.Insert(new OpLoad(samplerValue.TypeId, context.Bound++, samplerValue.Id, Specification.MemoryAccessMask.None)); - var loadCoord = builder.Insert(new OpLoad(texCoordValue.TypeId, context.Bound++, texCoordValue.Id, Specification.MemoryAccessMask.None)); - var loadTexture = builder.Insert(new OpLoad(result.TypeId, context.Bound++, result.Id, Specification.MemoryAccessMask.None)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, loadTexture.ResultId, loadSampler.ResultId)); - var returnType = context.GetOrRegister(((TextureType)Source.ValueType).ReturnType); - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, loadCoord.ResultId, Specification.ImageOperandsMask.None)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(new VectorType(((TextureType)Source.ValueType).ReturnType, 4)); + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, Specification.ImageOperandsMask.None)); Type = ((TextureType)Source.ValueType).ReturnType; return new(sample.ResultId, sample.ResultType); } else if (Accessors is [MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling]) { - var samplerValue = explicitSampling.Parameters.Values[0].Compile(table, shader, compiler); - var texCoordValue = explicitSampling.Parameters.Values[1].Compile(table, shader, compiler); - var levelValue = explicitSampling.Parameters.Values[2].Compile(table, shader, compiler); + var textureValue = result; + var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, shader, compiler); + var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, shader, compiler); + var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, shader, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); - var loadSampler = builder.Insert(new OpLoad(samplerValue.TypeId, context.Bound++, samplerValue.Id, Specification.MemoryAccessMask.None)); - var loadCoord = builder.Insert(new OpLoad(texCoordValue.TypeId, context.Bound++, texCoordValue.Id, Specification.MemoryAccessMask.None)); - var loadTexture = builder.Insert(new OpLoad(result.TypeId, context.Bound++, result.Id, Specification.MemoryAccessMask.None)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, loadTexture.ResultId, loadSampler.ResultId)); - var returnType = context.GetOrRegister(((TextureType)Source.ValueType).ReturnType); - var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, loadCoord.ResultId, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(new VectorType(((TextureType)Source.ValueType).ReturnType, 4)); + var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); Type = ((TextureType)Source.ValueType).ReturnType; return new(sample.ResultId, sample.ResultType); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index dc0994df21..f8acefaba4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -294,7 +294,7 @@ public class TypeName(string name, TextLocation info, bool isArray) : Literal(in public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolType symbolType) { - if (!IsArray && Generics.Count == 0) + if (!IsArray) { if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) return true; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 1e8e6d99bf..e00acd36d9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -112,6 +112,32 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); } + else if (instruction.Op == Op.OpTypeImage && new OpTypeImage(instruction) is { } typeImage) + { + var sampledType = (ScalarType)types[typeImage.SampledType]; + TextureType textureType = typeImage.Dim switch + { + Dim.Dim1D => new Texture1DType(sampledType), + Dim.Dim2D => new Texture2DType(sampledType), + Dim.Dim3D => new Texture3DType(sampledType), + Dim.Cube => new TextureCubeType(sampledType), + _ => throw new NotImplementedException(), + }; + textureType = textureType with + { + Depth = typeImage.Depth, + Arrayed = typeImage.Arrayed == 1 ? true : false, + Multisampled = typeImage.MS == 1 ? true : false, + Format = typeImage.Imageformat, + Sampled = typeImage.Sampled, + }; + + types.Add(typeImage.ResultId, textureType); + } + else if (instruction.Op == Op.OpTypeSampler && new OpTypeSampler(instruction) is { } typeSampler) + { + types.Add(typeSampler.ResultId, new SamplerType()); + } else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { if (importShader.Type == ImportType.External) @@ -223,7 +249,11 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); } - svar.Type = new PointerType(memberType, Specification.StorageClass.Private); + var storageClass = Specification.StorageClass.Private; + if (memberType is TextureType) + storageClass = Specification.StorageClass.UniformConstant; + + svar.Type = new PointerType(memberType, storageClass); table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); } else if (member is CBuffer cb) @@ -237,8 +267,8 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } else if (member is ShaderSamplerState samplerState) { - samplerState.Type = new SamplerType(samplerState.Name); - table.DeclaredTypes.Add(samplerState.Type.ToString(), samplerState.Type); + samplerState.Type = new SamplerType(); + table.DeclaredTypes.TryAdd(samplerState.Type.ToString(), samplerState.Type); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index d79c3a9ac8..17c371fa56 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; using Stride.Shaders.Parsing.Analysis; @@ -7,6 +6,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System.Collections.Immutable; using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -46,16 +46,18 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.Errors.Add(new SemanticErrors(Info, "Sampler states with parameters are not supported in SPIR-V generation.")); (_, var context) = compiler; - Type = new PointerType(new SamplerType(Name), Specification.StorageClass.UniformConstant); + Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); + var registeredType = context.GetOrRegister(Type); if (!table.RootSymbols.TryGetValue(Name, out _)) { context - .FluentAdd(new OpTypeSampler(context.Bound++), out var register) + .FluentAdd(new OpVariable(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, null), out var register) .FluentAdd(new OpName(register.ResultId, Name), out _); var sid = new SymbolID(Name, SymbolKind.SamplerState); var symbol = new Symbol(sid, Type, register.ResultId); - table.RootSymbols.Add(Name, symbol); + table.CurrentShader.Components.Add(symbol); + table.CurrentFrame.Add(Name, symbol); } else throw new Exception($"SamplerState {Name} already defined"); } @@ -113,8 +115,13 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var (builder, context) = compiler; var registeredType = context.GetOrRegister(Type); var variable = context.Bound++; + // TODO: Add a StreamSDSL storage class? - context.Add(new OpVariable(registeredType, variable, Specification.StorageClass.Private, null)); + var storageClass = Specification.StorageClass.Private; + if (Type is PointerType pointerType) + storageClass = pointerType.StorageClass; + + context.Add(new OpVariable(registeredType, variable, storageClass, null)); context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 115169b0d0..5f21aa11c1 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -6,6 +6,7 @@ using System.IO; using Stride.Shaders.Parsing.Analysis; using static Stride.Shaders.Spirv.Specification; +using System.Runtime.InteropServices; namespace Stride.Shaders.Spirv.Processing { @@ -35,7 +36,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - record struct AnalysisResult(SortedList Streams, List Blocks); + record struct AnalysisResult(SortedList Streams, List Blocks, List Resources); public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { @@ -75,6 +76,13 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); } + int currentBinding = 0; + foreach (var resource in analysisResult.Resources) + { + context.Add(new OpDecorate(resource, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(resource, ParameterizedFlags.DecorationBinding(currentBinding++))); + } + buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } @@ -97,6 +105,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) HashSet blockTypes = []; Dictionary blockPointerTypes = []; List blockIds = []; + List resources = []; // Build name table SortedList nameTable = []; @@ -181,8 +190,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { Storageclass: StorageClass.Private, ResultId: int - } variable - ) + } variable) { var name = nameTable.TryGetValue(variable.ResultId, out var nameId) ? nameId @@ -191,9 +199,23 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) semanticTable.TryGetValue(variable.ResultId, out var semantic); streams.Add(variable.ResultId, (new StreamInfo(semantic, name, type, variable.ResultId), true)); } + + if (instruction.Op == Op.OpVariable && ((OpVariable)instruction) is + { + Storageclass: StorageClass.UniformConstant, + ResultId: int + } resource) + { + var name = nameTable.TryGetValue(resource.ResultId, out var nameId) + ? nameId + : $"unnamed_{resource.ResultId}"; + var type = context.ReverseTypes[resource.ResultType]; + + resources.Add(resource.ResultId); + } } - return new(streams, blockIds); + return new(streams, blockIds, resources); } private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult) From 61c60160c4cb7c1452907e48d4f7536d387a06fa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 26 Nov 2025 13:37:50 +0900 Subject: [PATCH 0512/1182] Improved spirv-to-dxil bindings --- .../Direct3D/Spv2DXIL.cs | 126 ++++++++++++------ 1 file changed, 84 insertions(+), 42 deletions(-) diff --git a/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index 5452f919dc..ad55774662 100644 --- a/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -1,5 +1,8 @@ +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +[assembly: DisableRuntimeMarshalling] + namespace Stride.Shaders.Compilers.Direct3D; public enum ShaderStage { @@ -15,72 +18,110 @@ public enum ShaderStage public struct DebugOptions { - bool dump_nir; + public bool dump_nir; } +public enum FlipMode +{ + YZFlipNone = 0, + // Y-flip is unconditional: pos.y = -pos.y + // Z-flip is unconditional: pos.z = -pos.z + 1.0f + YFlipUnconditional = 1 << 0, + ZFlipUnconditional = 1 << 1, + YZFlipUnconditional = YFlipUnconditional | ZFlipUnconditional, + // Y-flip/Z-flip info are passed through a sysval + YFlipConditional = 1 << 2, + ZFlipConditional = 1 << 2, + YZFlipConditional = YFlipConditional | ZFlipConditional, +} -public struct RuntimeConf +public enum SysvalType +{ + // The sysval can be inlined in the shader as a constant zero + Zero, + // The sysval has a supported DXIL equivalent + Native, + // The sysval might be nonzero and has no DXIL equivalent, so it + // will need to be provided by the runtime_data constant buffer + RuntimeData, +} + +public enum dxil_shader_model { - struct runtime_data_cbv - { - ushort register_space; - ushort base_shader_register; - } + SHADER_MODEL_6_0 = 0x60000, + SHADER_MODEL_6_1, + SHADER_MODEL_6_2, + SHADER_MODEL_6_3, + SHADER_MODEL_6_4, + SHADER_MODEL_6_5, + SHADER_MODEL_6_6, + SHADER_MODEL_6_7, + SHADER_MODEL_6_8, +} +public struct RegisterInfo +{ + public uint register_space; + public uint base_shader_register; +} - struct PushConstantCBV - { - ushort register_space; - ushort base_shader_register; - } - enum FirstVertexAndBaseInstanceMode; - enum WorkgroupIdMode; +public struct RuntimeConf +{ + public RegisterInfo runtime_data_cbv; + public RegisterInfo push_constant_cbv; - struct YZFlip - { - // mode != DXIL_SPIRV_YZ_FLIP_NONE only valid on vertex/geometry stages. - enum Mode; + public SysvalType first_vertex_and_base_instance_mode; + public SysvalType workgroup_id_mode; - // Y/Z flip masks (one bit per viewport) - ushort y_mask; - ushort z_mask; - } + // mode != DXIL_SPIRV_YZ_FLIP_NONE only valid on vertex/geometry stages. + public FlipMode yzflip_mode; + // Y/Z flip masks (one bit per viewport) + public ushort yzflip_y_mask; + public ushort yzflip_z_mask; // The caller supports read-only images to be turned into SRV accesses, // which allows us to run the nir_opt_access() pass - bool declared_read_only_images_as_srvs; + public bool declared_read_only_images_as_srvs; // The caller supports read-write images to be turned into SRV accesses, // if they are found not to be written - bool inferred_read_only_images_as_srvs; + public bool inferred_read_only_images_as_srvs; // Force sample rate shading on a fragment shader - bool force_sample_rate_shading; + public bool force_sample_rate_shading; // View index needs to be lowered to a UBO lookup - bool lower_view_index; + public bool lower_view_index; // View index also needs to be forwarded to RT layer output - bool lower_view_index_to_rt_layer; + public bool lower_view_index_to_rt_layer; // Affects which features can be used by the shader - enum Shader_model_max; + public dxil_shader_model shader_model_max; } +[UnmanagedFunctionPointer(CallingConvention.Cdecl)] public unsafe delegate void MSGCallback(void* priv, string msg); public unsafe struct DXILSpirvLogger { - void* priv; - MSGCallback log; + public void* priv; + public nint log; } public unsafe struct DXILSpirvObject { - struct Metadata; - struct Binary { - void *buffer; - nint size; - } + // Some sysval or other type of data is accessed which needs to be piped + // from the app/API implementation into the shader via a buffer + bool metadata_requires_runtime_data; + + // Specifically if a vertex shader needs the first-vertex or base-instance + // sysval. These are relevant since these can come from an indirect arg + // buffer, and therefore piping them to the runtime data buffer is extra + // complex. + bool metadata_needs_draw_sysvals; + + void *buffer; + nint size; } public unsafe struct Specialization { @@ -102,14 +143,15 @@ public enum ValidatorVersion { DXIL_VALIDATOR_1_8, }; - public static partial class Spv2DXIL { // Import user32.dll (containing the function we need) and define // the method corresponding to the native function. - [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] - public static unsafe partial int spirv_to_dxil( + [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return: MarshalAs(UnmanagedType.Bool)] + public static unsafe partial bool spirv_to_dxil( uint* words, nint word_count, Specialization* specializations, @@ -117,10 +159,10 @@ public static unsafe partial int spirv_to_dxil( ShaderStage stage, string entry_point_name, ValidatorVersion validator_version_max, - DebugOptions* debug_options, - RuntimeConf* conf, - DXILSpirvLogger* logger, - DXILSpirvObject* out_dxil + ref DebugOptions debug_options, + ref RuntimeConf conf, + ref DXILSpirvLogger logger, + out DXILSpirvObject out_dxil ); From 579375ab1d13b343fec49759a2155bd5cfa9036a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 26 Nov 2025 16:38:58 +0900 Subject: [PATCH 0513/1182] Fix intrinsics underlying method used --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index eb257574ab..45bff47b2a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -50,7 +50,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLFAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -62,7 +62,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLSAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -74,7 +74,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLFSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -86,7 +86,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLSSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -98,7 +98,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLFloor(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -110,7 +110,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLCeil(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -122,7 +122,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLFract(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -134,7 +134,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var radians = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); + var instruction = builder.Insert(new GLSLRadians(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -146,7 +146,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var radians = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); + var instruction = builder.Insert(new GLSLDegrees(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -158,7 +158,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLSin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -170,7 +170,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLCos(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -182,7 +182,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLTan(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -194,7 +194,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLAsin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -206,7 +206,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLAcos(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -218,7 +218,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var y_over_x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(y_over_x.TypeId, context.Bound++, context.GLSLSet ?? -1, y_over_x.Id)); + var instruction = builder.Insert(new GLSLAtan(y_over_x.TypeId, context.Bound++, context.GLSLSet ?? -1, y_over_x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -230,7 +230,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLSinh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -242,7 +242,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLCosh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -254,7 +254,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLTanh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -266,7 +266,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLAsinh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -278,7 +278,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLAcosh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -290,7 +290,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLAtanh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } From 7f8c664c8aec0d037754a96ebd6594e73049e247 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 11:28:19 +0900 Subject: [PATCH 0514/1182] Intrinsics: restarted from HLSL list; added basic ones --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 109 ++++++++---- .../PrimaryExpressionParsers.cs | 158 ++++++++++++++---- .../Spirv/Building/Builder.Expressions.cs | 7 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 4 + 4 files changed, 209 insertions(+), 69 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 45bff47b2a..011969fe64 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -1,7 +1,9 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; +using System; namespace Stride.Shaders.Parsing.SDSL; @@ -42,7 +44,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return new(instruction.ResultId, instruction.ResultType); } } -public class FAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) +public class AbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -50,35 +52,25 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class SAbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sabs", info), parameters, info) -{ - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fsign", info), parameters, info) -{ - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); + + var elementType = Parameters.Values[0].Type.GetElementType(); + if (elementType.IsFloating()) + { + var instruction = builder.Insert(new GLSLFAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + else if (elementType.IsInteger()) + { + var instruction = builder.Insert(new GLSLSAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + else + { + throw new InvalidOperationException($"Unknown type for abs: {elementType}"); + } } } -public class SSignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ssign", info), parameters, info) +public class SignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fsign", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -86,8 +78,22 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); + + var elementType = Parameters.Values[0].Type.GetElementType(); + if (elementType.IsFloating()) + { + var instruction = builder.Insert(new GLSLFSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + else if (elementType.IsInteger()) + { + var instruction = builder.Insert(new GLSLSSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + else + { + throw new InvalidOperationException($"Unknown type for abs: {elementType}"); + } } } public class FloorCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("floor", info), parameters, info) @@ -398,7 +404,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLDeterminant(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var resultType = Parameters.Values[0].Type.GetElementType(); + var instruction = builder.Insert(new GLSLDeterminant(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -794,7 +801,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var x = Parameters.Values[0].Compile(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLLength(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); + var resultType = Parameters.Values[0].Type.GetElementType(); + var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -977,4 +985,39 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var instruction = builder.Insert(new GLSLNClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); return new(instruction.ResultId, instruction.ResultType); } -} \ No newline at end of file +} +public class MulCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + if (context.GLSLSet == null) + context.ImportGLSL(); + + var xType = Parameters.Values[0].Type; + var yType = Parameters.Values[1].Type; + + if (xType.GetElementType() != yType.GetElementType()) + throw new NotImplementedException("mul type conversion is currently not implemented"); + + if (!xType.IsFloating()) + throw new NotImplementedException("Only implemented for floating types"); + + // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul + var result = (xType, yType) switch + { + (ScalarType type1, ScalarType type2) => builder.InsertData(new OpFMul(x.TypeId, context.Bound++, x.Id, y.Id)), + (ScalarType type1, VectorType type2) => builder.InsertData(new OpVectorTimesScalar(y.TypeId, context.Bound++, y.Id, x.Id)), + (ScalarType type1, MatrixType type2) => builder.InsertData(new OpMatrixTimesScalar(y.TypeId, context.Bound++, y.Id, x.Id)), + (VectorType type1, ScalarType type2) => builder.InsertData(new OpVectorTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), + (VectorType type1, VectorType type2) when type1.Size == type2.Size => builder.InsertData(new OpDot(x.TypeId, context.Bound++, x.Id, y.Id)), + (VectorType type1, MatrixType type2) when type1.Size == type2.Rows => builder.InsertData(new OpVectorTimesMatrix(context.GetOrRegister(new VectorType(type1.BaseType, type2.Columns)), context.Bound++, x.Id, y.Id)), + (MatrixType type1, ScalarType type2) => builder.InsertData(new OpMatrixTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), + (MatrixType type1, VectorType type2) when type1.Columns == type2.Size => builder.InsertData(new OpMatrixTimesVector(context.GetOrRegister(new VectorType(type1.BaseType, type1.Rows)), context.Bound++, x.Id, y.Id)), + (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type1.Rows, type2.Columns)), context.Bound++, x.Id, y.Id)), + }; + + return new SpirvValue(result); + } +} diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 16a040f1d2..ae86a20795 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -53,39 +53,132 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou { parsed = (identifier.Name, parameters.Values.Count) switch { - ("Round", 1) => new RoundCall(parameters, scanner[position..scanner.Position]), - ("RoundEven", 1) => new RoundEvenCall(parameters, scanner[position..scanner.Position]), - ("Trunc", 1) => new TruncCall(parameters, scanner[position..scanner.Position]), - ("FAbs", 1) => new FAbsCall(parameters, scanner[position..scanner.Position]), - ("SAbs", 1) => new SAbsCall(parameters, scanner[position..scanner.Position]), - ("FSign", 1) => new FSignCall(parameters, scanner[position..scanner.Position]), - ("SSign", 1) => new SSignCall(parameters, scanner[position..scanner.Position]), - ("Floor", 1) => new FloorCall(parameters, scanner[position..scanner.Position]), - ("Ceil", 1) => new CeilCall(parameters, scanner[position..scanner.Position]), + ("abort", _) => throw new NotImplementedException(), + ("abs", 1) => new AbsCall(parameters, scanner[position..scanner.Position]), + ("acos", 1) => new AcosCall(parameters, scanner[position..scanner.Position]), + ("all", _) => throw new NotImplementedException(), + ("AllMemoryBarrier", _) => throw new NotImplementedException(), + ("AllMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), + ("any", _) => throw new NotImplementedException(), + ("asdouble", _) => throw new NotImplementedException(), + ("asfloat", _) => throw new NotImplementedException(), + ("asin", 1) => new AsinCall(parameters, scanner[position..scanner.Position]), + ("asint", _) => throw new NotImplementedException(), + ("asuint", _) => throw new NotImplementedException(), + ("atan", 1) => new AtanCall(parameters, scanner[position..scanner.Position]), + ("atan2", 2) => new Atan2Call(parameters, scanner[position..scanner.Position]), + ("ceil", 1) => new CeilCall(parameters, scanner[position..scanner.Position]), + ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), + ("clamp", _) => throw new NotImplementedException(), + ("clip", _) => throw new NotImplementedException(), + ("cos", 1) => new CosCall(parameters, scanner[position..scanner.Position]), + ("cosh", 1) => new CoshCall(parameters, scanner[position..scanner.Position]), + ("countbits", _) => throw new NotImplementedException(), + ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), + ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), + ("ddx", _) => throw new NotImplementedException(), + ("ddx_coarse", _) => throw new NotImplementedException(), + ("ddx_fine", _) => throw new NotImplementedException(), + ("ddy", _) => throw new NotImplementedException(), + ("ddy_coarse", _) => throw new NotImplementedException(), + ("ddy_fine", _) => throw new NotImplementedException(), + ("degrees", 1) => new DegreesCall(parameters, scanner[position..scanner.Position]), + ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), + ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), + ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), + ("distance", _) => throw new NotImplementedException(), + ("dot", _) => throw new NotImplementedException(), + ("dst", _) => throw new NotImplementedException(), + ("errorf", _) => throw new NotImplementedException(), + ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), + ("EvaluateAttributeAtSample", _) => throw new NotImplementedException(), + ("EvaluateAttributeSnapped", _) => throw new NotImplementedException(), + ("exp", 1) => new ExpCall(parameters, scanner[position..scanner.Position]), + ("exp2", 1) => new Exp2Call(parameters, scanner[position..scanner.Position]), + ("f16to32", _) => throw new NotImplementedException(), + ("f32to16", _) => throw new NotImplementedException(), + ("faceforward", _) => throw new NotImplementedException(), + ("firstbithigh", _) => throw new NotImplementedException(), + ("firstbitlow", _) => throw new NotImplementedException(), + ("floor", 1) => new FloorCall(parameters, scanner[position..scanner.Position]), + ("fma", _) => throw new NotImplementedException(), + ("fmod", _) => throw new NotImplementedException(), + ("frac", _) => throw new NotImplementedException(), + ("frexp", _) => throw new NotImplementedException(), + ("fwidth", _) => throw new NotImplementedException(), + ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), + ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), + ("GroupMemoryBarrier", _) => throw new NotImplementedException(), + ("GroupMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), + ("InterlockedAdd", _) => throw new NotImplementedException(), + ("InterlockedAnd", _) => throw new NotImplementedException(), + ("InterlockedCompareExchange", _) => throw new NotImplementedException(), + ("InterlockedCompareStore", _) => throw new NotImplementedException(), + ("InterlockedExchange", _) => throw new NotImplementedException(), + ("InterlockedMax", _) => throw new NotImplementedException(), + ("InterlockedMin", _) => throw new NotImplementedException(), + ("InterlockedOr", _) => throw new NotImplementedException(), + ("InterlockedXor", _) => throw new NotImplementedException(), + ("isfinite", _) => throw new NotImplementedException(), + ("isinf", _) => throw new NotImplementedException(), + ("isnan", _) => throw new NotImplementedException(), + ("ldexp", _) => throw new NotImplementedException(), + ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), + ("lerp", _) => throw new NotImplementedException(), + ("lit", _) => throw new NotImplementedException(), + ("log", 1) => new LogCall(parameters, scanner[position..scanner.Position]), + ("log10", _) => throw new NotImplementedException(), + ("log2", 1) => new Log2Call(parameters, scanner[position..scanner.Position]), + ("mad", _) => throw new NotImplementedException(), + ("max", _) => throw new NotImplementedException(), + ("min", _) => throw new NotImplementedException(), + ("modf", _) => throw new NotImplementedException(), + ("msad4", _) => throw new NotImplementedException(), + ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), + ("noise", _) => throw new NotImplementedException(), + ("normalize", _) => throw new NotImplementedException(), + ("pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), + ("printf", _) => throw new NotImplementedException(), + ("Process2DQuadTessFactorsAvg", _) => throw new NotImplementedException(), + ("Process2DQuadTessFactorsMax", _) => throw new NotImplementedException(), + ("Process2DQuadTessFactorsMin", _) => throw new NotImplementedException(), + ("ProcessIsolineTessFactors", _) => throw new NotImplementedException(), + ("ProcessQuadTessFactorsAvg", _) => throw new NotImplementedException(), + ("ProcessQuadTessFactorsMax", _) => throw new NotImplementedException(), + ("ProcessQuadTessFactorsMin", _) => throw new NotImplementedException(), + ("ProcessTriTessFactorsAvg", _) => throw new NotImplementedException(), + ("ProcessTriTessFactorsMax", _) => throw new NotImplementedException(), + ("ProcessTriTessFactorsMin", _) => throw new NotImplementedException(), + ("radians", 1) => new RadiansCall(parameters, scanner[position..scanner.Position]), + ("rcp", _) => throw new NotImplementedException(), + ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), + ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), + ("reversebits", _) => throw new NotImplementedException(), + ("round", 1) => new RoundEvenCall(parameters, scanner[position..scanner.Position]), + ("rsqrt", 1) => new InverseSqrtCall(parameters, scanner[position..scanner.Position]), + ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), + ("sin", 1) => new SinCall(parameters, scanner[position..scanner.Position]), + ("sincos", _) => throw new NotImplementedException(), + ("sinh", 1) => new SinhCall(parameters, scanner[position..scanner.Position]), + ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), + ("sqrt", 1) => new SqrtCall(parameters, scanner[position..scanner.Position]), + ("step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), + ("tan", 1) => new TanCall(parameters, scanner[position..scanner.Position]), + ("tanh", 1) => new TanhCall(parameters, scanner[position..scanner.Position]), + ("tex1D" or "tex1Dbias" or "tex1Dgrad" or "tex1Dlod" or "tex1Dproj", _) => throw new NotImplementedException(), + ("tex2D" or "tex2Dbias" or "tex2Dgrad" or "tex2Dlod" or "tex2Dproj", _) => throw new NotImplementedException(), + ("tex3D" or "tex3Dbias" or "tex3Dgrad" or "tex3Dlod" or "tex3Dproj", _) => throw new NotImplementedException(), + ("texCUBE" or "texCUBEbias" or "texCUBEgrad" or "texCUBElod" or "texCUBEproj", _) => throw new NotImplementedException(), + ("transpose", _) => throw new NotImplementedException(), + ("trunc", 1) => new TruncCall(parameters, scanner[position..scanner.Position]), + _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]), + }; + /*parsed = (identifier.Name, parameters.Values.Count) switch + { ("Fract", 1) => new FractCall(parameters, scanner[position..scanner.Position]), - ("Radians", 1) => new RadiansCall(parameters, scanner[position..scanner.Position]), - ("Degrees", 1) => new DegreesCall(parameters, scanner[position..scanner.Position]), - ("Sin", 1) => new SinCall(parameters, scanner[position..scanner.Position]), - ("Cos", 1) => new CosCall(parameters, scanner[position..scanner.Position]), - ("Tan", 1) => new TanCall(parameters, scanner[position..scanner.Position]), - ("Asin", 1) => new AsinCall(parameters, scanner[position..scanner.Position]), - ("Acos", 1) => new AcosCall(parameters, scanner[position..scanner.Position]), - ("Atan", 1) => new AtanCall(parameters, scanner[position..scanner.Position]), - ("Sinh", 1) => new SinhCall(parameters, scanner[position..scanner.Position]), - ("Cosh", 1) => new CoshCall(parameters, scanner[position..scanner.Position]), - ("Tanh", 1) => new TanhCall(parameters, scanner[position..scanner.Position]), ("Asinh", 1) => new AsinhCall(parameters, scanner[position..scanner.Position]), ("Acosh", 1) => new AcoshCall(parameters, scanner[position..scanner.Position]), ("Atanh", 1) => new AtanhCall(parameters, scanner[position..scanner.Position]), - ("Atan2", 2) => new Atan2Call(parameters, scanner[position..scanner.Position]), - ("Pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), - ("Exp", 1) => new ExpCall(parameters, scanner[position..scanner.Position]), - ("Log", 1) => new LogCall(parameters, scanner[position..scanner.Position]), - ("Exp2", 1) => new Exp2Call(parameters, scanner[position..scanner.Position]), - ("Log2", 1) => new Log2Call(parameters, scanner[position..scanner.Position]), - ("Sqrt", 1) => new SqrtCall(parameters, scanner[position..scanner.Position]), - ("InverseSqrt", 1) => new InverseSqrtCall(parameters, scanner[position..scanner.Position]), - ("Determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), ("MatrixInverse", 1) => new MatrixInverseCall(parameters, scanner[position..scanner.Position]), ("Modf", 2) => new ModfCall(parameters, scanner[position..scanner.Position]), ("ModfStruct", 1) => new ModfStructCall(parameters, scanner[position..scanner.Position]), @@ -100,7 +193,6 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("SClamp", 3) => new SClampCall(parameters, scanner[position..scanner.Position]), ("FMix", 3) => new FMixCall(parameters, scanner[position..scanner.Position]), ("IMix", 3) => new IMixCall(parameters, scanner[position..scanner.Position]), - ("Step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), ("SmoothStep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), ("Fma", 3) => new FmaCall(parameters, scanner[position..scanner.Position]), ("Frexp", 2) => new FrexpCall(parameters, scanner[position..scanner.Position]), @@ -118,13 +210,9 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("UnpackSnorm4x8", 1) => new UnpackSnorm4x8Call(parameters, scanner[position..scanner.Position]), ("UnpackUnorm4x8", 1) => new UnpackUnorm4x8Call(parameters, scanner[position..scanner.Position]), ("UnpackDouble2x32", 1) => new UnpackDouble2x32Call(parameters, scanner[position..scanner.Position]), - ("Length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), ("Distance", 2) => new DistanceCall(parameters, scanner[position..scanner.Position]), - ("Cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), ("Normalize", 1) => new NormalizeCall(parameters, scanner[position..scanner.Position]), ("FaceForward", 3) => new FaceForwardCall(parameters, scanner[position..scanner.Position]), - ("Reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), - ("Refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), ("FindILsb", 1) => new FindILsbCall(parameters, scanner[position..scanner.Position]), ("FindSMsb", 1) => new FindSMsbCall(parameters, scanner[position..scanner.Position]), ("FindUMsb", 1) => new FindUMsbCall(parameters, scanner[position..scanner.Position]), @@ -135,7 +223,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("NMax", 2) => new NMaxCall(parameters, scanner[position..scanner.Position]), ("NClamp", 3) => new NClampCall(parameters, scanner[position..scanner.Position]), _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]) - }; + };*/ return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 4014034c31..b2c58637f9 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -147,7 +147,12 @@ public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral lite internal static class SymbolExtensions { - + public static ScalarType GetElementType(this SymbolType symbol) => symbol switch + { + ScalarType s => s, + VectorType v => v.BaseType, + MatrixType m => m.BaseType, + }; public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "sbyte" or "short" or "int" or "long" }; public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "byte" or "ushort" or "uint" or "ulong" }; public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { TypeName: "half" or "float" or "double" }; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index a5837e7d44..ca49b59f7b 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -87,6 +87,10 @@ public T Insert(in T value) where T : struct, IMemoryInstruction => Buffer.Insert(Position++, value); + public OpData InsertData(in T value) + where T : struct, IMemoryInstruction + => Buffer.InsertData(Position++, value); + [Obsolete("Use the insert method instead")] public NewSpirvBuffer GetBuffer() => Buffer; From 3eb667a4caf1c7b224f80d7619462eb203fe1d25 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 26 Nov 2025 11:04:55 +0900 Subject: [PATCH 0515/1182] Added parsing for rgroup (information is not yet stored) --- assets/SDSL/RenderTests/Rgroups.sdsl | 21 ++++++++++ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- .../Parsing/SDSL/AST/ShaderElements.cs | 41 +++++++++++++++++-- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 assets/SDSL/RenderTests/Rgroups.sdsl diff --git a/assets/SDSL/RenderTests/Rgroups.sdsl b/assets/SDSL/RenderTests/Rgroups.sdsl new file mode 100644 index 0000000000..d5787ec654 --- /dev/null +++ b/assets/SDSL/RenderTests/Rgroups.sdsl @@ -0,0 +1,21 @@ +// PSMain(ExpectedResult=#1357ABCD, texture.SPIRV_Cross_CombinedTexture1Sampler1=#1357ABCD) + +namespace Stride.Shaders.Tests; + +shader Rgroups +{ + stream float4 ColorTarget : SV_Target0; + stream float4 TexCoord : TEXCOORD; + + stage SamplerState Sampler1; + + rgroup Group1 + { + stage Texture2D Texture1; + } + + void PSMain() + { + streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index e00acd36d9..87857df64e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -316,7 +316,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) context.Add(new OpSDSLMixinInherit(shader.ResultId)); } - foreach (var member in Elements.OfType()) + foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index e78525fdae..7af644e653 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -156,6 +156,8 @@ public override void ProcessSymbol(SymbolTable table) _ => throw new NotSupportedException() }; } + + public abstract void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler); } public class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) @@ -202,7 +204,7 @@ public override string ToString() public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { - public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); @@ -222,5 +224,38 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com } } -public sealed class RGroup(string name, TextLocation info) : ShaderBuffer(name, info); -public sealed class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info); +public sealed class RGroup(string name, TextLocation info) : ShaderBuffer(name, info) +{ + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + var (builder, context) = compiler; + + for (var index = 0; index < Members.Count; index++) + { + var member = Members[index]; + + (var storageClass, var kind) = member.Type switch + { + TextureType => (Specification.StorageClass.UniformConstant, SymbolKind.Variable), + SamplerType => (Specification.StorageClass.UniformConstant, SymbolKind.SamplerState), + _ => throw new NotImplementedException(), + }; + + var type = new PointerType(member.Type, storageClass); + var typeId = context.GetOrRegister(type); + context.FluentAdd(new OpVariable(typeId, context.Bound++, storageClass, null), out var variable); + context.AddName(variable.ResultId, member.Name); + var sid = new SymbolID(member.Name, kind, Storage.Uniform); + var symbol = new Symbol(sid, type, variable.ResultId); + table.CurrentFrame.Add(member.Name, symbol); + } + } +} + +public sealed class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info) +{ + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + throw new NotImplementedException(); + } +} From 8486cb149e2065c9f367f6790a720d8871ae9a34 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 26 Nov 2025 16:21:17 +0900 Subject: [PATCH 0516/1182] MergeSDSL: work with ShaderSource --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 4 ++-- src/Stride.Shaders.Experiments/Program.cs | 3 ++- src/Stride.Shaders.Tests/RenderingTests.cs | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e1730ac062..6e328f2ebd 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -22,7 +22,7 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(string entryShaderName, out byte[] bytecode) + public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) { var temp = new NewSpirvBuffer(); @@ -30,7 +30,7 @@ public void MergeSDSL(string entryShaderName, out byte[] bytecode) var table = new SymbolTable(); var effectEvaluator = new EffectEvaluator(ShaderLoader); - var shaderSource = effectEvaluator.EvaluateEffects(new ShaderClassSource(entryShaderName)); + shaderSource = effectEvaluator.EvaluateEffects(shaderSource); var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 8a6abc4082..a14b563b56 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using System.Runtime.InteropServices; using Stride.Shaders.Spirv.Tools; +using Stride.Shaders.Parsing.SDSL; // Examples.CompileSDSL("RenderTests/If"); @@ -10,7 +11,7 @@ var loader = new Examples.ShaderLoader(); loader.LoadExternalFile("Test", out var testBuffer); var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL("If", out var bytecode); +shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index aa35fd1b44..5ce9b65257 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -11,6 +11,7 @@ using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; using System.Diagnostics.CodeAnalysis; @@ -50,7 +51,7 @@ public void RenderTest1(string shaderName, string methodName, string args) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader()); - shaderMixer.MergeSDSL(shaderName, out var bytecode); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode); File.WriteAllBytes($"{shaderName}.spv", bytecode); // Convert to GLSL From e37f71870a56955b86a4ec7db8e69f86d940e1ab Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 26 Nov 2025 16:21:49 +0900 Subject: [PATCH 0517/1182] StreamAnalyzer: include resources in entry point --- src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 5f21aa11c1..b7879d266b 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -336,7 +336,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Blocks.Count]; + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Blocks.Count + analysisResult.Resources.Count]; int pvariableIndex = 0; foreach (var inputStream in inputStreams) pvariables[pvariableIndex++] = inputStream.Id; @@ -344,8 +344,11 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con pvariables[pvariableIndex++] = outputStream.Id; foreach (var privateStream in privateStreams) pvariables[pvariableIndex++] = privateStream.VariableId; + // TODO: filter blocks and resources actually used by this entrypoint with ProcessMethod()? foreach (var block in analysisResult.Blocks) pvariables[pvariableIndex++] = block; + foreach (var resource in analysisResult.Resources) + pvariables[pvariableIndex++] = resource; context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables])); } From a4bfb674b0b1e0e56395f7df203ce5300ddb7b6e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 11:44:32 +0900 Subject: [PATCH 0518/1182] Added simple intrinsics test --- assets/SDSL/RenderTests/Intrinsics.sdsl | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 assets/SDSL/RenderTests/Intrinsics.sdsl diff --git a/assets/SDSL/RenderTests/Intrinsics.sdsl b/assets/SDSL/RenderTests/Intrinsics.sdsl new file mode 100644 index 0000000000..84f533c604 --- /dev/null +++ b/assets/SDSL/RenderTests/Intrinsics.sdsl @@ -0,0 +1,13 @@ +// PSMain(ExpectedResult=#00FFFF00) + +namespace Stride.Shaders.Tests; + +shader Intrinsics +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(sin(0), cos(0), sin(radians(90)), cos(radians(90))); + } +} \ No newline at end of file From b61639821baaed3a71225db5b071779628953195 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 12:03:35 +0900 Subject: [PATCH 0519/1182] Generics (only for float literals) --- assets/SDSL/RenderTests/GenericsFloat.sdsl | 33 +++ .../SDSL/EffectEvaluator.cs | 2 +- .../SDSL/ShaderMixer.MixinNode.cs | 4 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 7 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 35 +-- .../SDSL/ShaderMixer.cs | 24 +- .../Buffers/NewSpirvBuffer.cs | 11 + .../Extensions/spirv.sdsl.grammar-ext.json | 28 +- .../Literals/LiteralArray.cs | 2 +- src/Stride.Shaders.Tests/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 12 +- src/Stride.Shaders/Core/SymbolTypes.cs | 13 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 76 +++-- .../Parsing/SDSL/ShaderSource.cs | 5 +- .../Spirv/Building/Builder.Class.cs | 261 ++++++++++++++++-- src/Stride.Shaders/Spirv/Building/Context.cs | 3 +- 16 files changed, 443 insertions(+), 75 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsFloat.sdsl diff --git a/assets/SDSL/RenderTests/GenericsFloat.sdsl b/assets/SDSL/RenderTests/GenericsFloat.sdsl new file mode 100644 index 0000000000..3a754af928 --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsFloat.sdsl @@ -0,0 +1,33 @@ +// PSMain(ExpectedResult=#11FFFFFF) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader ComputeFixed : Compute +{ + override float Compute() + { + return base.Compute() + TVALUE / 255.0; + } +} + +shader ComputeFixed2 : ComputeFixed +{ +} + +shader GenericsFloat : ComputeFixed<7.0>, ComputeFixed2<10.0>, ComputeFixed2<7.0> +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 2a02aad15d..160c3446a0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -20,7 +20,7 @@ public ShaderSource EvaluateEffects(ShaderSource source) if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) throw new NotImplementedException(); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, new ShaderClassInstantiation(classSource.ClassName, []), ResolveStep.Compile); if (buffer[0].Op == Op.OpSDSLEffect) { var mixinTree = new ShaderMixinSource(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 5c843c1568..80e7409a5f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -1,4 +1,6 @@ -namespace Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Spirv.Building; + +namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 02af4f5f83..3b15b39952 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Core; using static Stride.Shaders.Spirv.Specification; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Compilers.SDSL; @@ -92,7 +93,7 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader } } - private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderClassInstantiation classSource, ShaderInfo shaderInfo, MixinNode mixinNode) { var importedShaders = new Dictionary(); var idRemapping = new Dictionary(); @@ -116,7 +117,9 @@ private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderE { if (importShader.Type == Specification.ImportType.Inherit) { - importedShaders.Add(importShader.ResultId, mixinNode.ShadersByName[importShader.ShaderName]); + //var shaderClassSource = Spirv.Building.SpirvBuilder.ConvertToShaderClassSource(temp, shaderStart, shaderEnd, importShader); + var shaderClassSource = classSource.ShaderReferences[importShader.ResultId - classSource.OffsetId]; + importedShaders.Add(importShader.ResultId, mixinNode.ShadersByName[shaderClassSource.ToClassName()]); SetOpNop(i.Data.Memory.Span); } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 31fdd1aa42..519fc69295 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -17,33 +17,34 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinSource? root = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinInstantiation? root = null) { bool isRoot = root == null; - var mixinList = new List(); + var mixinList = new List(); var shaderMixinSource = shaderSource switch { ShaderMixinSource mixinSource2 => mixinSource2, ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, }; + foreach (var mixinToMerge in shaderMixinSource.Mixins) { - if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) - throw new NotImplementedException(); - - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName); - SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList); - if (!mixinList.Contains(mixinToMerge)) - mixinList.Add(mixinToMerge); + if (mixinToMerge.GenericArguments.Length > 0) + throw new NotImplementedException("Generics at the top-level shaders is not supported"); + var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2, ResolveStep.Mix); + mixinToMerge2.Buffer = buffer; + //SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); } - shaderMixinSource.Mixins.Clear(); - shaderMixinSource.Mixins.AddRange(mixinList); + var compositions = new Dictionary(); + var result = new ShaderMixinInstantiation(mixinList, compositions); - foreach (var shaderName in mixinList) + foreach (var shaderName in mixinList.ToArray()) { - var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderName.ClassName); + var shader = shaderName.Buffer; ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); bool hasStage = false; @@ -61,8 +62,8 @@ private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shader { compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; } - compositionMixin = (ShaderMixinSource)EvaluateInheritanceAndCompositions(compositionMixin, root ?? shaderMixinSource); - shaderMixinSource.Compositions[variableName] = compositionMixin; + var composition = EvaluateInheritanceAndCompositions(compositionMixin, root ?? result); + compositions[variableName] = composition; } } @@ -75,13 +76,13 @@ private ShaderMixinSource EvaluateInheritanceAndCompositions(ShaderSource shader // If there are any stage variables, add class to root if (!isRoot && hasStage) { - var shaderNameStageOnly = new ShaderClassSource(shaderName.ClassName) { GenericArguments = shaderName.GenericArguments, ImportStageOnly = true }; + var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, ShaderReferences = shaderName.ShaderReferences }; // Make sure it's not already added yet (either standard or stage only) if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) root!.Mixins.Add(shaderNameStageOnly); } } - return shaderMixinSource; + return result; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 6e328f2ebd..2286e0252e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -61,6 +61,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) #if DEBUG File.WriteAllBytes("test.spv", bytecode); File.WriteAllText("test.spvdis", Spv.Dis(temp)); + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif } @@ -76,7 +77,7 @@ class MixinNodeContext } - MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinSource mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) + MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { if (currentCompositionPath != null) buffer.Add(new OpSDSLEffect(currentCompositionPath)); @@ -136,19 +137,18 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, return mixinNode; } - private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, ShaderMixinSource mixinSource, MixinNode mixinNode) + private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) { var isRoot = mixinNode.Stage == null; var offset = context.Bound; var nextOffset = 0; var shaders = mixinNode.Shaders; - var shadersByName = mixinNode.ShadersByName; mixinNode.StartInstruction = temp.Count; foreach (var shaderClass in mixinSource.Mixins) { - var shader = SpirvBuilder.GetOrLoadShader(ShaderLoader, shaderClass.ClassName); + var shader = shaderClass.Buffer; offset += nextOffset; nextOffset = 0; shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; @@ -209,6 +209,10 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad OffsetIds(i2, offset); } + shaderClass.Start = shaderStart; + shaderClass.End = shaderStart; + shaderClass.OffsetId = offset; + // Build ShaderInfo var shaderInfo = new ShaderInfo(shaders.Count, shaderClass.ClassName, shaderStart, temp.Count); shaderInfo.CompositionPath = mixinNode.CompositionPath; @@ -217,11 +221,11 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo, mixinNode); - shadersByName.Add(shaderClass.ClassName, shaderInfo); + mixinNode.ShadersByName.Add(shaderClass.ToClassName(), shaderInfo); shaders.Add(shaderInfo); // Remap ids from inherited class (OpSDSLImport*) - RemapInheritedIds(temp, shaderStart, temp.Count, shaderInfo, mixinNode); + RemapInheritedIds(temp, shaderStart, temp.Count, shaderClass, shaderInfo, mixinNode); } mixinNode.EndInstruction = temp.Count; @@ -259,7 +263,9 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, var i = temp[index]; if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) { - currentShader = mixinNode.ShadersByName[shaderInstruction.ShaderName]; + //currentShader = mixinNode.ShadersByName[shaderInstruction.ShaderName]; + // TODO: better way to find ShaderInfo + currentShader = mixinNode.Shaders.First(x => index >= x.StartInstruction && index < x.EndInstruction); } else if (i.Data.Op == Op.OpSDSLShaderEnd) { @@ -362,8 +368,6 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB var composition = mixinNode.Compositions[callTarget.Target]; methodMixinGroup = composition; - Spv.Dis(temp, DisassemblerFlags.Id); - var functionName = externalFunctions[functionCall.Function]; var functionId = composition.MethodGroupsByName[functionName]; @@ -372,8 +376,6 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB SetOpNop(temp[index - 1].Data.Memory.Span); } - Spv.Dis(temp, DisassemblerFlags.Name & DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex); - bool foundInStage = false; if (!methodMixinGroup.MethodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) { diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 5cfe660f1f..33973ebf9f 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -276,6 +276,17 @@ public bool RemoveAt(int index) return true; } + public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction + { + if (index < 0 || index >= Instructions.Count) + throw new InvalidOperationException(); + + Instructions[index].Dispose(); + Instructions[index] = new(instruction.InstructionMemory); + UpdateBound(Instructions[index]); + return Instructions[index]; + } + public Enumerator GetEnumerator() => new(this); public ref struct Enumerator(NewSpirvBuffer buffer) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 9e7c03bc75..8573d46a84 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -69,13 +69,18 @@ { "kind": "IdResult" }, + { + "kind": "ImportType", + "name": "type" + }, { "kind": "LiteralString", "name": "shaderName" }, { - "kind": "ImportType", - "name": "type" + "kind": "IdRef", + "quantifier": "*", + "name": "generics" } ] }, @@ -166,6 +171,25 @@ "name": "mixin" } ] + }, + { + "opname": "OpSDSLGenericParameter", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" } + ] + }, + { + "opname": "OpConstantStringSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" }, + { + "kind": "LiteralString", + "name": "'Literal String'" + } + ] } ], "operand_kinds": [ diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 26124a1490..f8153f8f4b 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -43,7 +43,7 @@ or LiteralArray MemoryOwner Memory { get; set { field?.Dispose(); field = value; } } public readonly ReadOnlySpan Words => Memory is not null ? Memory.Span : []; - MemoryOwner Elements { get; set { field?.Dispose(); field = value; } } + public MemoryOwner Elements { get; set { field?.Dispose(); field = value; } } public readonly int WordCount => Elements?.Length ?? -1; diff --git a/src/Stride.Shaders.Tests/Program.cs b/src/Stride.Shaders.Tests/Program.cs index 43e330bab8..efbe01f782 100644 --- a/src/Stride.Shaders.Tests/Program.cs +++ b/src/Stride.Shaders.Tests/Program.cs @@ -2,4 +2,4 @@ [assembly: CaptureConsole] -//new RenderingTests().RenderTest1("SimpleInheritanceBaseThis", "PSMain", "ExpectedResult=#FFFFFFFF"); \ No newline at end of file +//new RenderingTests().RenderTest1("GenericsFloat", "PSMain", "ExpectedResult=#FFFFFFFF"); \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 5ce9b65257..d136972eae 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -14,12 +14,14 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; +using Spv = Stride.Shaders.Spirv.Tools.Spv; namespace Stride.Shaders.Parsing.Tests; @@ -41,7 +43,15 @@ public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out Ne var text = MonoGamePreProcessor.OpenAndRun(filename); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; - return sdslc.Compile(text, out buffer); + + var result = sdslc.Compile(text, out buffer); +#if DEBUG + if (result) + { + Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } +#endif + return result; } } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 6d085b4fdf..8080b7bf2e 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,6 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Text; using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Core; @@ -236,7 +237,8 @@ public sealed record StreamsSymbol : SymbolType; public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type)> Members) : StructuredType(Name, Members); public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public sealed record ShaderSymbol(string Name, List Components) : SymbolType + +public sealed record ShaderSymbol(string Name, int[] GenericArguments, List Components) : SymbolType { public Symbol Get(string name, SymbolKind kind) { @@ -256,4 +258,13 @@ public bool TryGet(string name, SymbolKind kind, out Symbol? value) value = null!; return false; } + + public string ToClassName() + { + if (GenericArguments.Length == 0) + return Name; + + var className = new ShaderClassInstantiation(Name, GenericArguments); + return className.ToClassName(); + } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 87857df64e..f2971190b3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Core.Analysis; @@ -6,8 +7,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; using System; using System.Reflection; +using System.Reflection.Metadata; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -142,7 +145,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { if (importShader.Type == ImportType.External) { - types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, [])); + types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray(), [])); } } } @@ -162,7 +165,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } } - private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string className) + private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassInstantiation classSource) { ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); @@ -194,15 +197,20 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, string class var sid = new SymbolID(functionName, SymbolKind.Method, FunctionFlags: functionFlags); symbols.Add(new(sid, functionType, functionInstruction.ResultId)); } + + if (instruction.Op == Op.OpSDSLGenericParameter) + { + throw new NotImplementedException(); + } } - var shaderType = new ShaderSymbol(className, symbols); + var shaderType = new ShaderSymbol(classSource.ClassName, classSource.GenericArguments, symbols); return shaderType; } private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) { - table.DeclaredTypes.Add(shaderType.Name, shaderType); + //table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); } public void Compile(CompilerUnit compiler, SymbolTable table) @@ -212,18 +220,48 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Push(); - var inheritanceList = new List(); + var symbols = new List(); + var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; + if (Generics != null) + { + for (int i = 0; i < Generics.Parameters.Count; i++) + { + var genericParameter = Generics.Parameters[i]; + var genericParameterType = genericParameter.TypeName.ResolveType(table); + table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); + + var genericParameterTypeId = context.GetOrRegister(genericParameterType); + context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound)); + context.AddName(context.Bound, genericParameter.Name); + table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); + + openGenerics[i] = context.Bound; + + context.Bound++; + } + } + + var inheritanceList = new List(); foreach (var mixin in Mixins) { - SpirvBuilder.BuildInheritanceList(table.ShaderLoader, new ShaderClassSource(mixin.Name), inheritanceList); + var generics = new int[mixin.Generics != null ? mixin.Generics.Values.Count : 0]; + if (mixin.Generics != null) + { + for (int i = 0; i < mixin.Generics.Values.Count; i++) + { + generics[i] = mixin.Generics.Values[i].CompileAsValue(table, this, compiler).Id; + } + } + var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); + SpirvBuilder.BuildInheritanceList(table.ShaderLoader, shaderClassSource, inheritanceList, ResolveStep.Compile, context.GetBuffer()); } + var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { - LoadExternalShaderType(table, mixin.ClassName); + shaderSymbols.Add(LoadExternalShaderType(table, mixin)); } - var symbols = new List(); foreach (var member in Elements) { if (member is ShaderMethod func) @@ -244,7 +282,12 @@ public void Compile(CompilerUnit compiler, SymbolTable table) { if (!svar.TypeName.TryResolveType(table, out var memberType)) { - memberType = LoadExternalShaderType(table, svar.TypeName.Name); + if (svar.TypeName.Name.Contains("<")) + throw new NotImplementedException("Can't have member variables with generic shader types"); + var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); + classSource.Buffer = shader; + memberType = LoadExternalShaderType(table, classSource); table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); } @@ -272,7 +315,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } } - var currentShader = new ShaderSymbol(Name, symbols); + var currentShader = new ShaderSymbol(Name, openGenerics, symbols); RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; @@ -281,12 +324,10 @@ public void Compile(CompilerUnit compiler, SymbolTable table) member.ProcessSymbol(table); } - foreach (var mixin in inheritanceList) + foreach (var shaderType in shaderSymbols) { - var shaderType = (ShaderSymbol)table.DeclaredTypes[mixin.ClassName]; - // Import types and variables/functions - context.FluentAdd(new OpSDSLImportShader(context.Bound, new(shaderType.Name), ImportType.Inherit), out var shader); + context.FluentAdd(new OpSDSLImportShader(context.Bound, ImportType.Inherit, new(shaderType.Name), new(shaderType.GenericArguments.AsSpan())), out var shader); context.AddName(context.Bound, shaderType.Name); context.Bound++; @@ -334,12 +375,11 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Pop(); } - private static ShaderSymbol LoadExternalShaderType(SymbolTable table, string className) + private static ShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) { - if (!table.ShaderLoader.LoadExternalBuffer(className, out var shaderBuffer)) - throw new InvalidOperationException($"Type [{className}] not found"); + var shaderBuffer = classSource.Buffer; - var shaderType = CreateShaderType(shaderBuffer, className); + var shaderType = CreateShaderType(shaderBuffer, classSource); RegisterShaderType(table, shaderType); diff --git a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs index 68e8427b5f..dcb30edc45 100644 --- a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs +++ b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs @@ -29,8 +29,9 @@ public string ToClassName() return ClassName; var result = new StringBuilder(); - if (ImportStageOnly) - result.Append("stage "); + // We should make this optional as it currently bothers class registration by name + //if (ImportStageOnly) + // result.Append("stage "); result.Append(ClassName); if (GenericArguments != null && GenericArguments.Length > 0) { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index ae3db1447a..46edc02136 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,49 +1,278 @@ -using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Spirv.Core; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; + +public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); + +public enum ResolveStep +{ + Compile, + Mix, +} + +public record class ShaderClassInstantiation(string ClassName, int[] GenericArguments, bool ImportStageOnly = false) : IEquatable +{ + public NewSpirvBuffer Buffer { get; set; } + + public string ClassName { get; set; } = ClassName; + + public int[] GenericArguments { get; set; } = GenericArguments; + + public Dictionary ShaderReferences { get; set; } = new(); + + public int Start { get; set; } + public int End { get; set; } + + public int OffsetId { get; set; } + + public string ToClassName() + { + if ((GenericArguments == null || GenericArguments.Length == 0) && !ImportStageOnly) + return ClassName; + + var result = new StringBuilder(); + result.Append(ClassName); + if (GenericArguments != null && GenericArguments.Length > 0) + { + result.Append('<'); + result.Append(string.Join(",", GenericArguments)); + result.Append('>'); + } + + return result.ToString(); + } + + public virtual bool Equals(ShaderClassInstantiation? shaderClassSource) + { + if (shaderClassSource is null) return false; + if (ReferenceEquals(this, shaderClassSource)) return true; + return + string.Equals(ClassName, shaderClassSource.ClassName) && + GenericArguments.SequenceEqual(shaderClassSource.GenericArguments); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = ClassName?.GetHashCode() ?? 0; + if (GenericArguments != null) + { + foreach (var current in GenericArguments) + hashCode = (hashCode * 397) ^ (current.GetHashCode()); + } + + return hashCode; + } + } +} + public partial class SpirvBuilder { - public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, NewSpirvBuffer buffer, List inheritanceList) + private static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping - var shaderMapping = new Dictionary(); + var shaderMapping = classSource.ShaderReferences; foreach (var i in buffer) - if (i.Op == Specification.Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) - shaderMapping[importShader.ResultId] = new ShaderClassSource(importShader.ShaderName); + { + if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + { + var shaderClassSource = ConvertToShaderClassSource(buffer, 0, buffer.Count, importShader); + + shaderMapping[importShader.ResultId] = shaderClassSource; + } + } // Check inheritance foreach (var i in buffer) { - if (i.Op == Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) + if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { var shaderName = shaderMapping[inherit.Shader]; - BuildInheritanceList(shaderLoader, shaderName, inheritanceList); + BuildInheritanceList(shaderLoader, shaderName, inheritanceList, resolveStep, buffer); } } } - public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassSource classSource, List inheritanceList) + public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, OpSDSLImportShader importShader) { + return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); + } + + public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + { + // TODO: cache same instantiations within context? if (!inheritanceList.Contains(classSource)) { - if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) - throw new NotImplementedException(); + if (classSource.Buffer == null) + { + var shader = GetOrLoadShader(shaderLoader, classSource, resolveStep, parentBuffer); + classSource.Buffer = shader; + } + + if (!inheritanceList.Contains(classSource)) + { + BuildInheritanceList(shaderLoader, classSource, classSource.Buffer, inheritanceList, resolveStep); + inheritanceList.Add(classSource); + } + } + } - var shader = GetOrLoadShader(shaderLoader, classSource.ClassName); - BuildInheritanceList(shaderLoader, shader, inheritanceList); - inheritanceList.Add(classSource); + public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + { + // Instantiate generics + var copiedShader = new NewSpirvBuffer(); + foreach (var i in shader) + { + var i2 = new OpData(i.Data.Memory.Span); + copiedShader.Add(i2); } + shader = copiedShader; + + var generics = new List(); + var genericArgumentIndex = 0; + Dictionary idRemapping = new(); + HashSet targets = new(); + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + { + shaderDeclaration.ShaderName = classSource.ToClassName(); + } + else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is {} genericParameter) + { + idRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericArgumentIndex]); + targets.Add(classSource.GenericArguments[genericArgumentIndex]); + genericArgumentIndex++; + SetOpNop(i.Data.Memory.Span); + } + } + + // Remove OpName + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpName && (OpName)i is { } name) + { + if (idRemapping.ContainsKey(name.Target)) + SetOpNop(i.Data.Memory.Span); + } + } + + if (idRemapping.Count > 0) + RemapIds(shader, 0, shader.Count, idRemapping); + + // Try to resolve fully the new generic parameter values + var resolvedParameters = new Dictionary(); + if (parentBuffer != null) + { + for (var index = 0; index < parentBuffer.Count; index++) + { + var i = parentBuffer[index]; + if (i.Op == Op.OpConstant) + { + if (targets.Contains(i.Data.IdResult!.Value)) + { + var value = new LiteralValue(i.Data.Memory.Span[3..]); + resolvedParameters.Add(i.Data.IdResult!.Value, value.Value.ToString()); + + // import constant in current shader + + shader.Add(new OpConstant(i.Data.IdResultType!.Value, i.Data.IdResult!.Value, value.Value)); + } + } + else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + { + if (targets.Contains(genericParameter.ResultId)) + { + + } + } + } + } + + // Fully resolved? + if (resolvedParameters.Count == targets.Count) + { + var parameters = string.Join(',', classSource.GenericArguments.Select(x => resolvedParameters[x])); + var className = classSource.ClassName + "<" + parameters + ">"; + + if (resolveStep == ResolveStep.Mix) + { + classSource.ClassName = className; + classSource.GenericArguments = []; + } + + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + { + shaderDeclaration.ShaderName = classSource.ClassName + "<" + parameters + ">"; + } + } + } + + return shader; + } + + public static void SetOpNop(Span words) + { + words[0] = words.Length << 16; + words[1..].Clear(); + } + + private static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) + { + for (var index = shaderStart; index < buffer.Count; index++) + { + var i = buffer[index]; + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) + { + op.Words[0] = to1; + } + + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + { + op.Words[1] = to2; + } + } + } + } + + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + { + var shader = GetOrLoadShader(shaderLoader, classSource.ClassName); + + if (classSource.GenericArguments.Length > 0) + { + shader = InstantiateGenericShader(shader, classSource, resolveStep, parentBuffer); + } + + return shader; } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) + private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) { if (!shaderLoader.LoadExternalBuffer(className, out var buffer)) throw new InvalidOperationException($"Could not load shader [{className}]"); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index c73830cbf2..66ceb227a9 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; @@ -206,7 +207,7 @@ public int GetOrRegister(SymbolType? type) private int RegisterShaderType(ShaderSymbol shaderSymbol) { - FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), ImportType.External), out var shader); + FluentAdd(new OpSDSLImportShader(Bound++, ImportType.External, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); AddName(shader.ResultId, shaderSymbol.Name); for (var index = 0; index < shaderSymbol.Components.Count; index++) { From 56f1b175147ddff9e8133d3300bc4040a9404208 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 12:44:04 +0900 Subject: [PATCH 0520/1182] Disassemble only in debug mode --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index eb1925b43e..ad7bb64529 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -40,7 +40,9 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf throw new Exception("Some parse errors"); var merged = compiler.ToBuffer(); +#if DEBUG var dis = Spv.Dis(merged); +#endif lastBuffer = merged; ShaderLoader.RegisterShader(shader.Name, merged); @@ -51,7 +53,9 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf effect.Compile(compiler); var merged = compiler.ToBuffer(); +#if DEBUG var dis = Spv.Dis(merged); +#endif lastBuffer = merged; ShaderLoader.RegisterShader(effect.Name, merged); From 31af59fda629c10a483a3b4f38d70f465450f4e7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 13:00:31 +0900 Subject: [PATCH 0521/1182] Embed CppNet code directly in Stride.Shaders --- SDSL.sln | 19 ++----------------- .../Stride.Shaders.Experiments.csproj | 1 - .../Stride.Shaders.Parsing.Tests.csproj | 1 - src/Stride.Shaders/Stride.Shaders.csproj | 10 +++++++++- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/SDSL.sln b/SDSL.sln index 81e6424c55..b525de850e 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 +# Visual Studio Version 18 +VisualStudioVersion = 18.0.11222.15 d18.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9B25B78A-8418-4161-99D6-5E84611BDA59}" EndProject @@ -19,8 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CppNet", "submodules\CppNet8\CppNet.csproj", "{BFCBF799-91A7-93D7-A6A1-233537FD7E63}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Graphics.RHI", "src\Stride.Graphics.RHI\Stride.Graphics.RHI.csproj", "{050ED94E-2A9D-4145-BCD1-7B97E5D58365}" EndProject Global @@ -117,18 +115,6 @@ Global {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x64.Build.0 = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.ActiveCfg = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.Build.0 = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x64.ActiveCfg = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x64.Build.0 = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x86.ActiveCfg = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Debug|x86.Build.0 = Debug|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|Any CPU.Build.0 = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x64.ActiveCfg = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x64.Build.0 = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x86.ActiveCfg = Release|Any CPU - {BFCBF799-91A7-93D7-A6A1-233537FD7E63}.Release|x86.Build.0 = Release|Any CPU {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.Build.0 = Debug|Any CPU {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -153,7 +139,6 @@ Global {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} - {BFCBF799-91A7-93D7-A6A1-233537FD7E63} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {050ED94E-2A9D-4145-BCD1-7B97E5D58365} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index 281c1249da..b4d3bfaa1c 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -12,7 +12,6 @@ - diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 6f4416625b..a81bd88b02 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -27,7 +27,6 @@ - diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 5ed5678ae1..8c976425a1 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -1,8 +1,16 @@  + + + + + + + + + - From 76f11b104674802f9df0ceffb9dcdaf964cafca3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 16:11:53 +0900 Subject: [PATCH 0522/1182] Parser: Remove double-quote in StringLiteral value --- .../SDSL/Parsers/LiteralParsers/LiteralParsers.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 12a5d38eb3..bd54b32dff 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -216,11 +216,16 @@ public static bool StringLiteral(ref TScanner scanner, ParseResult res var position = scanner.Position; if (Tokens.Char('\"', ref scanner, advance: true)) { - Parsers.Until(ref scanner, '\"', advance: true); - if (scanner.Span[position..scanner.Position].Contains('\n')) - return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[position], scanner.Memory)); - parsed = new(scanner.Span[position..scanner.Position].ToString(), scanner[position..scanner.Position]); - return true; + var strStart = scanner.Position; + Parsers.Until(ref scanner, '\"', advance: false); + var strEnd = scanner.Position; + if (Tokens.Char('\"', ref scanner, advance: true)) + { + if (scanner.Span[position..scanner.Position].Contains('\n')) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[position], scanner.Memory)); + parsed = new(scanner.Span[strStart..strEnd].ToString(), scanner[position..scanner.Position]); + return true; + } } return Parsers.Exit(ref scanner, result, out parsed, position); } From 9fdfd92d1df61cd5a1cef5ca0c67dda10b60b02f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 16:13:15 +0900 Subject: [PATCH 0523/1182] Parser: allow string literal in generics parameters --- .../Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index ca4e5b0599..d463cce273 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -117,6 +117,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = vector; return true; } + else if (LiteralsParser.StringLiteral(ref scanner, result, out var stringLiteral)) + { + parsed = stringLiteral; + return true; + } else if (PostfixParser.Postfix(ref scanner, result, out var accessor)) { if (accessor is AccessorChainExpression ae && ae.Source is Identifier) From 17aa8176180211a2cd55ef0ed1a431595a4fbf94 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 16:13:53 +0900 Subject: [PATCH 0524/1182] Parser: ShaderMember.Attributes was not populated --- .../Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs index 517f84f30c..c41499483b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs @@ -155,6 +155,8 @@ public static bool Member(ref TScanner scanner, ParseResult result, ou ) { parsed = new ShaderMember(typeName, identifier, value, scanner[position..scanner.Position], isStage, streamKind); + if (hasAttributes) + parsed.Attributes = attributes.Attributes; return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); From 01ae8da98bd633364fbcb0a6e446fe262bf7b5a0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 27 Nov 2025 18:02:26 +0900 Subject: [PATCH 0525/1182] Generics: added support for LinkType --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 2 +- .../SDSL/ShaderMixer.cs | 7 ++- .../Extensions/spirv.sdsl.grammar-ext.json | 52 ++++++++++++++++++- src/Stride.Shaders/Core/SymbolTypes.cs | 2 + .../Parsing/SDSL/AST/Expression.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 16 +++++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 7 ++- .../Parsing/SDSL/AST/ShaderElements.cs | 35 +++++++++++++ .../Spirv/Building/Builder.Class.cs | 27 +++++++++- src/Stride.Shaders/Spirv/Building/Context.cs | 1 + 10 files changed, 143 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 519fc69295..a3c75cd2d7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -30,7 +30,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource foreach (var mixinToMerge in shaderMixinSource.Mixins) { - if (mixinToMerge.GenericArguments.Length > 0) + if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) throw new NotImplementedException("Generics at the top-level shaders is not supported"); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2, ResolveStep.Mix); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 2286e0252e..a774e5ed23 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -471,7 +471,12 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) if (temp[i].Op == Op.OpNop) temp.RemoveAt(i--); // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) - else if (temp[i].Op == Op.OpSDSLShader || temp[i].Op == Op.OpSDSLShaderEnd || temp[i].Op == Op.OpSDSLEffect || temp[i].Op == Op.OpSDSLEffectEnd) + else if (temp[i].Op == Op.OpSDSLShader + || temp[i].Op == Op.OpSDSLShaderEnd + || temp[i].Op == Op.OpSDSLEffect + || temp[i].Op == Op.OpSDSLEffectEnd + || temp[i].Op == Op.OpConstantStringSDSL + || temp[i].Op == Op.OpTypeGenericLinkSDSL) temp.RemoveAt(i--); } } diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 8573d46a84..822c6a10a5 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -177,7 +177,8 @@ "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, - { "kind": "IdResult" } + { "kind": "IdResult" }, + { "kind": "GenericParameterKindSDSL", "name": "kind" } ] }, { @@ -190,6 +191,13 @@ "name": "'Literal String'" } ] + }, + { + "opname": "OpTypeGenericLinkSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" } + ] } ], "operand_kinds": [ @@ -219,6 +227,34 @@ } ] }, + { + "category": "ValueEnum", + "kind": "Decoration", + "enumerants": [ + { + "enumerant": "LinkSDSL", + "value": 8000, + "parameters": [ + { + "kind": "LiteralString", + "name": "'Name'" + } + ], + "version": "1.0" + }, + { + "enumerant": "LinkIdSDSL", + "value": 8001, + "parameters": [ + { + "kind": "IdRef" + } + ], + "version": "1.0" + } + + ] + }, { "category": "ValueEnum", "kind": "ImportType", @@ -233,6 +269,20 @@ } ] }, + { + "category": "ValueEnum", + "kind": "GenericParameterKindSDSL", + "enumerants": [ + { + "enumerant": "Float", + "value": 0 + }, + { + "enumerant": "LinkType", + "value": 1 + } + ] + }, { "kind": "ExecutionModel", "enumerants": [ diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 8080b7bf2e..f6e9a0a623 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -268,3 +268,5 @@ public string ToClassName() return className.ToClassName(); } } + +public sealed record GenericLinkType : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 589114db61..ad0c28bd61 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -20,7 +20,7 @@ public abstract class Expression(TextLocation info) : ValueNode(info) public SymbolType? ValueType => Type is PointerType pointerType ? pointerType.BaseType : Type; - public SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public virtual SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var result = Compile(table, shader, compiler); return compiler.Builder.AsValue(compiler.Context, result); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index f8acefaba4..0cd3ce4190 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -22,7 +22,16 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); + // Note: we rely on undefined type (0); we assume those string literals will be used in only very specific cases where we expect them (i.e. generic instantiation parameters) and will be removed + return new SpirvValue(i.IdResult.Value, 0); + } + + public override SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + // Since we use type 0, CompileAsValue won't work + return Compile(table, shader, compiler); } public override string ToString() @@ -296,6 +305,11 @@ public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolT { if (!IsArray) { + if (Name == "LinkType") + { + symbolType = new GenericLinkType(); + return true; + } if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) return true; else if (SymbolType.TryGetNumeric(Name, out var numeric)) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index f2971190b3..a42ee9879b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -231,7 +231,12 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); - context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound)); + var genericParameterKind = genericParameterType switch + { + ScalarType { TypeName: "float" } => GenericParameterKindSDSL.Float, + GenericLinkType => GenericParameterKindSDSL.LinkType, + }; + context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, genericParameterKind)); context.AddName(context.Bound, genericParameter.Name); table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 7af644e653..4b80580801 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -220,6 +220,41 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, index); table.CurrentFrame.Add(member.Name, symbol); + + if (member.Attributes != null && member.Attributes.Count > 0) + { + foreach (var attribute in member.Attributes) + { + if (attribute is AnyShaderAttribute anyAttribute && anyAttribute.Name == "Link") + { + if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) + { + // Try to resolve generic parameter when encoded as string (deprecated) + if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) + { + // TODO: make it a warning only? + table.Errors.Add(new(Info, "LinkType generics should be passed without quotes")); + } + + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkLiteral.Value))); + } + else if (anyAttribute.Parameters[0] is Identifier identifier) + { + if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + { + throw new InvalidOperationException(); + } + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkSymbol.IdRef))); + } + else + { + throw new NotImplementedException($"Attribute {attribute} is not supported"); + } + } + else + throw new NotImplementedException($"Attribute {attribute} is not supported"); + } + } } } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 46edc02136..414e3ef889 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -159,7 +159,7 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha } } - // Remove OpName + // Remove OpName for (var index = 0; index < shader.Count; index++) { var i = shader[index]; @@ -188,10 +188,17 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha resolvedParameters.Add(i.Data.IdResult!.Value, value.Value.ToString()); // import constant in current shader - shader.Add(new OpConstant(i.Data.IdResultType!.Value, i.Data.IdResult!.Value, value.Value)); } } + else if (i.Op == Op.OpConstantStringSDSL && (OpConstantStringSDSL)i is { } constantString) + { + if (targets.Contains(i.Data.IdResult!.Value)) + { + var value = constantString.LiteralString; + resolvedParameters.Add(i.Data.IdResult!.Value, value); + } + } else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { if (targets.Contains(genericParameter.ResultId)) @@ -202,6 +209,22 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha } } + // Try to resolve LinkType generics + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpMemberDecorateString + && ((OpMemberDecorateString)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) + { + using var n = new LiteralValue(m.Span); + if (resolvedParameters.TryGetValue(n.Value, out var resolvedValue)) + { + linkDecorate.Decoration = new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]); + } + } + } + + // Fully resolved? if (resolvedParameters.Count == targets.Count) { diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 66ceb227a9..904cc084d4 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -196,6 +196,7 @@ public int GetOrRegister(SymbolType? type) Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, + GenericLinkType => Buffer.Add(new OpTypeGenericLinkSDSL(Bound++)).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; From 503545d48ae0fbcf01f17b7aad73560e7e32dc2c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 28 Nov 2025 11:52:55 +0900 Subject: [PATCH 0526/1182] Added support for cast and added conversion where needed (method calls, etc.) --- .../SDSL/ShaderMixer.cs | 2 + .../Parsing/SDSL/AST/Expression.cs | 30 ++-- .../Parsing/SDSL/AST/Statements.cs | 21 +-- .../DirectiveUnaryParsers.Prefix.cs | 2 +- .../ExpressionParsers/UnaryParsers.Prefix.cs | 2 +- .../Spirv/Building/Builder.Expressions.cs | 133 ++++++++++++++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 16 +++ 7 files changed, 180 insertions(+), 26 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a774e5ed23..23e701e39b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -478,6 +478,8 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) || temp[i].Op == Op.OpConstantStringSDSL || temp[i].Op == Op.OpTypeGenericLinkSDSL) temp.RemoveAt(i--); + else if (temp[i].Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) + temp.RemoveAt(i--); } } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index ad0c28bd61..e41c488919 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -64,17 +64,20 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil foreach (var p in list) { - var paramSource = p.Compile(table, shader, compiler).Id; - var paramType = context.GetOrRegister(functionType.ParameterTypes[tmp]); + var paramSource = p.CompileAsValue(table, shader, compiler); + var paramType = functionType.ParameterTypes[tmp]; // Wrap param in proper pointer type (function) var paramVariable = context.Bound++; + builder.AddFunctionVariable(context.GetOrRegister(paramType), paramVariable); - builder.AddFunctionVariable(paramType, paramVariable); + // Convert type (if necessary) + var paramValueType = paramType; + if (paramValueType is PointerType pointerType) + paramValueType = pointerType.BaseType; + paramSource = builder.Convert(context, paramSource, paramValueType); - var loadedParam = context.Bound++; - builder.Insert(new OpLoad(compiler.Context.Types[p.ValueType], loadedParam, paramSource, null)); - builder.Insert(new OpStore(paramVariable, loadedParam, null)); + builder.Insert(new OpStore(paramVariable, paramSource.Id, null)); compiledParams[tmp++] = paramVariable; } @@ -147,12 +150,19 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } } -public class CastExpression(string typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) +public class CastExpression(TypeName typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) { - public string TypeName { get; set; } = typeName; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public TypeName TypeName { get; set; } = typeName; + + public unsafe override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + var castType = TypeName.ResolveType(table); + var value = Expression.CompileAsValue(table, shader, compiler); + + Type = castType; + + return builder.Convert(context, value, castType); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 71ba58887f..3482d453d6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -125,7 +125,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit for (var index = 0; index < Variables.Count; index++) { if (Variables[index].Value != null) - compiledValues[index] = Variables[index].Value!.Compile(table, shader, compiler); + compiledValues[index] = Variables[index].Value!.CompileAsValue(table, shader, compiler); } // Compute type @@ -147,7 +147,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); } - var underlyingType = context.GetOrRegister(Type); + var underlyingType = Type; Type = new PointerType(Type, Specification.StorageClass.Function); var registeredType = context.GetOrRegister(Type); @@ -170,9 +170,8 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit { var source = compiledValues[index]; - var sourceLoad = context.Bound++; - builder.Insert(new OpLoad(underlyingType, sourceLoad, source.Id, Specification.MemoryAccessMask.None)); - source = new(sourceLoad, underlyingType); + // Make sure type is correct + source = builder.Convert(context, source, underlyingType); builder.Insert(new OpStore(variable, source.Id, null)); } @@ -194,16 +193,9 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit foreach (var variable in Variables) { var target = variable.Variable.Compile(table, shader, compiler); - var source = variable.Value!.Compile(table, shader, compiler); + var source = variable.Value!.CompileAsValue(table, shader, compiler); if (variable.Variable.Type is not PointerType) throw new InvalidOperationException("can only assign to pointer type"); - if (variable.Value!.Type is PointerType p) - { - var sourceLoad = context.Bound++; - var underlyingType = context.GetOrRegister(p.BaseType); - builder.Insert(new OpLoad(underlyingType, sourceLoad, source.Id, Specification.MemoryAccessMask.None)); - source = new(sourceLoad, underlyingType); - } if (variable.Operator != AssignOperator.Simple) { @@ -239,7 +231,8 @@ out var t source = builder.BinaryOperation(context, context.GetOrRegister(Type), left, binaryOperator, right); } - + // Make sure to convert to proper type + source = builder.Convert(context, source, variable.Variable.ValueType); builder.Insert(new OpStore(target.Id, source.Id, null)); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 5cf2138277..2638440a5c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -171,7 +171,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) ) { - parsed = new CastExpression(typeName.Name, Operator.Cast, lit, scanner[position..scanner.Position]); + parsed = new CastExpression(new TypeName(typeName.Name, typeName.Info, false), Operator.Cast, lit, scanner[position..scanner.Position]); return true; } else diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 8193b602dc..69376bdf55 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -106,7 +106,7 @@ public static bool Cast(ref TScanner scanner, ParseResult result, out && Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true) ) { - parsed = new CastExpression(typeName.Name, Operator.Cast, expression, scanner[position..scanner.Position]); + parsed = new CastExpression(typeName, Operator.Cast, expression, scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index b2c58637f9..9ff17ffcac 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -124,6 +124,139 @@ when l.IsInteger() && r.IsInteger() return new(instruction, name); } + public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolType castType) + { + var valueId = value.Id; + var valueType = context.ReverseTypes[value.TypeId]; + var originalType = valueType; + + // No conversion necessary? + if (castType == valueType) + return value; + + if (castType is StructType || valueType is StructType) + throw new NotImplementedException("Can't cast between structures (cast from {valueType} to {castType})"); + + // We don't support cast with object yet, filter for numeral types + if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) + || (valueType is not ScalarType && valueType is not VectorType && valueType is not MatrixType)) + throw new NotImplementedException($"Cast only work between numeral types (cast from {valueType} to {castType})"); + + Span values = stackalloc int[castType is MatrixType m ? m.Rows : 1]; + + // Truncating + switch (valueType, castType) + { + case (ScalarType s1, ScalarType s2): + values[0] = valueId; + break; + case (VectorType v1, ScalarType s2): + { + values[0] = Insert(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, valueId, [0])).ResultId; + valueType = v1.BaseType; + break; + } + case (VectorType v1, VectorType v2) when v1.Size <= v2.Size: + throw new InvalidOperationException($"Can't cast from {v1} to {v2} (more components)"); + case (VectorType v1, VectorType v2) when v1.Size > v2.Size: + { + Span valuesTemp = stackalloc int[v2.Size]; + for (int i = 0; i < v2.Size; ++i) + Insert(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), valuesTemp[i] = context.Bound++, valueId, [i])); + valueType = new VectorType(v1.BaseType, v2.Size); + values[0] = Insert(new OpCompositeConstruct(context.GetOrRegister(valueType), context.Bound++, new LiteralArray(valuesTemp))).ResultId; + break; + } + case (VectorType v1, MatrixType m2) when v1.Size != m2.Rows * m2.Columns: + throw new InvalidOperationException($"Can't cast from {v1} to {m2}"); + case (VectorType v1, MatrixType m2) when v1.Size == m2.Rows * m2.Columns: + throw new NotImplementedException($"Cast from {v1} to {m2} is not implemented (even though it should be valid since number of components is same"); + case (MatrixType m1, ScalarType s2): + values[0] = Insert(new OpCompositeExtract(context.GetOrRegister(m1.BaseType), context.Bound++, valueId, [0, 0])).ResultId; + break; + case (MatrixType m1, VectorType v2) when v2.Size != m1.Rows * m1.Columns: + throw new InvalidOperationException($"Can't cast from {m1} to {v2}"); + case (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns: + throw new NotImplementedException($"Cast from {m1} to {v2} is not implemented (even though it should be valid since number of components is same"); + case (MatrixType m1, MatrixType m2) when m1.Rows < m2.Rows || m1.Columns < m2.Columns: + throw new InvalidOperationException($"Can't cast from {m1} to {m2} (larger matrix)"); + case (MatrixType m1, MatrixType m2) when m1.Rows >= m2.Rows && m1.Columns >= m2.Columns: + { + for (int i = 0; i < m2.Rows; ++i) + { + values[i] = Insert(new OpCompositeExtract(context.GetOrRegister(new VectorType(m1.BaseType, m1.Columns)), context.Bound++, valueId, [i])).ResultId; + if (m1.Columns != m2.Columns) + { + Span shuffleIndices = stackalloc int[m2.Columns]; + for (int j = 0; j < m2.Columns; ++j) + shuffleIndices[j] = j; + values[i] = Insert(new OpVectorShuffle(context.GetOrRegister(new VectorType(m1.BaseType, m2.Columns)), context.Bound++, values[i], values[i], new(shuffleIndices))).ResultId; + } + } + valueType = new VectorType(m1.BaseType, m2.Columns); + break; + } + } + + // Type casting + // (process each vector one by one) + (int elementSize, var castTypeSameSize) = valueType switch + { + ScalarType s => (1, (SymbolType)castType.GetElementType()), + VectorType s => (s.Size, new VectorType(castType.GetElementType(), s.Size)), + }; + for (int i = 0; i < values.Length; ++i) + { + var rowValue = values[i]; + if (rowValue == 0) + throw new InvalidOperationException($"Type conversion from {originalType} to {castType} failed during conversion (current type: {valueType})"); + + var typeCasting = (valueType.GetElementType(), castType.GetElementType()) switch + { + // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion + (ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + + (ScalarType { TypeName: "float" }, ScalarType { TypeName: "bool" }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), + (ScalarType { TypeName: "int" }, ScalarType { TypeName: "bool" }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + + (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CreateConstant(new IntegerLiteral(new(32, false, true), 0, new())).Id)), + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CreateConstant(new FloatLiteral(new(32, true, true), 0.0, null, new())).Id)), + }; + values[i] = typeCasting.IdResult!.Value; + + // Update type + if (i == values.Length - 1) + valueType = castTypeSameSize; + } + + // Expanding + int result = values[0]; + switch (valueType, castType) + { + case (ScalarType, VectorType v2): + result = Insert(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new LiteralArray(Enumerable.Repeat(result, v2.Size).ToArray()))); + valueType = v2; + break; + case (ScalarType, MatrixType m2): + result = Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m2.BaseType, m2.Columns)), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Columns).ToArray()))); + result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Rows).ToArray()))); + valueType = m2; + break; + case (MatrixType, MatrixType m2): + // rebuild type + result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(values))); + valueType = m2; + break; + } + + if (valueType != castType) + throw new NotImplementedException($"Type conversion from {originalType} to {castType} failed after expansion (current type: {valueType})"); + + return new SpirvValue(result, context.GetOrRegister(castType)); + } + public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol functionSymbol, Span parameters) { // Note: Overload should have been chosen before diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 904cc084d4..df77901db6 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -279,6 +279,22 @@ int RegisterPointerType(PointerType pointerType) return id ?? -1; } + public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size) + { + var value = CreateConstant(literal); + if (size == 1) + return value; + + Span values = stackalloc int[size]; + for (int i = 0; i < size; ++i) + values[i] = size; + + var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); + var instruction = Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values))); + + return new(instruction); + } + public SpirvValue CreateConstant(Literal literal) { object literalValue = literal switch From af4c6e4f445813a6443556dabb762a59d159be5a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 28 Nov 2025 13:25:42 +0900 Subject: [PATCH 0527/1182] Rewrote BinaryOperation --- .../Examples.Spirv.cs | 1 - .../Parsing/Analysis/OperatorTable.cs | 74 ------- .../Parsing/SDSL/AST/Expression.cs | 17 +- .../Parsing/SDSL/AST/Statements.cs | 14 +- .../Spirv/Building/Builder.Expressions.cs | 200 +++++++++++++----- 5 files changed, 155 insertions(+), 151 deletions(-) delete mode 100644 src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 0a9b14bd73..f3959341c5 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -37,7 +37,6 @@ public static void GenerateSpirv() builder.SetPositionTo(block); var v = builder.BinaryOperation( context, - function.Parameters["a"].TypeId, function.Parameters["a"], Operator.Plus, function.Parameters["b"] ); builder.Return(v); diff --git a/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs b/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs deleted file mode 100644 index 3ba4093a48..0000000000 --- a/src/Stride.Shaders/Parsing/Analysis/OperatorTable.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDSL; - -namespace Stride.Shaders.Parsing.Analysis; - -public static class OperatorTable -{ - public static bool CheckBinaryOperation(SymbolType left, SymbolType right, Operator op) - { - return (left, right, op) switch - { - // Scalar operations - ( - ScalarType { TypeName: "int" or "long" }, ScalarType { TypeName: "int" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - or Operator.LeftShift or Operator.RightShift - or Operator.OR or Operator.XOR or Operator.AND - ) => true, - ( - ScalarType { TypeName: "float" or "double" }, ScalarType { TypeName: "double" or "float" or "int" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - ( - ScalarType { TypeName: "float" } or ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - - // Vector operations - ( - VectorType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, - VectorType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - // Matrix operations - ( - MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, - MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or ScalarType { TypeName: "int" or "float" or "long" or "double" }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - ( - MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or VectorType { BaseType: ScalarType { TypeName: "int" or "float" or "long" or "double" } }, - MatrixType { BaseType: ScalarType { TypeName: "int" or "long" or "float" } } or VectorType { BaseType: ScalarType { TypeName: "int" or "float" or "long" or "double" } }, - Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod - ) => true, - - _ => false, - }; - } - public static bool BinaryOperationResultingType(SymbolType left, SymbolType right, Operator op, out SymbolType? result) - { - // TODO : correct that part - result = ((int)op, left, right) switch - { - // Boolean operations - (>= 22 and < 26, ScalarType{ TypeName : "bool"}, ScalarType {TypeName: "bool"}) => left, - // Equalities - (>= 22 and < 26, ScalarType l, ScalarType r) when l == r => ScalarType.From("bool"), - // Linear algebra - (>=8 and < 13, ScalarType {TypeName: "int" or "uint" or "float" or "long" or "ulong" or "double"} l, ScalarType r) when l.TypeName == r.TypeName => right, - (>=8 and < 13, ScalarType { TypeName: "int" or "uint" or "long" or "ulong" }, ScalarType { TypeName: "float" or "double"}) => right, - (>=8 and < 13, ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" or "float" }) => left, - (>=8 and < 13, VectorType l, VectorType r) when l.BaseType == r.BaseType => right, - (>=8 and < 13, VectorType, ScalarType) => left, - (>=8 and < 13, MatrixType l, MatrixType r) when l.BaseType == r.BaseType => right, - (>=8 and < 13, MatrixType l, ScalarType r) => l, - (>=8 and < 13, MatrixType l, VectorType r) => l, - (>=8 and < 13, MatrixType { BaseType: ScalarType { TypeName: "int" } } l, MatrixType { BaseType: ScalarType { TypeName: "int" or "float" } } r) => l, - // Comparison - (>=18 and < 22, SymbolType l, SymbolType r) when l == r => ScalarType.From("bool"), - _ => null, - }; - return result != null; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index e41c488919..786c5b128f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -135,7 +135,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var indexLiteral = new IntegerLiteral(new(32, false, true), 1, new()); indexLiteral.Compile(table, shader, compiler); var constant1 = context.CreateConstant(indexLiteral); - var result = builder.BinaryOperation(context, context.GetOrRegister(pointerType.BaseType), expression, Operator.Plus, constant1); + var result = builder.BinaryOperation(context, expression, Operator.Plus, constant1); builder.Insert(new OpStore(expression.Id, result.Id, null)); @@ -320,20 +320,11 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { var left = Left.CompileAsValue(table, shader, compiler); var right = Right.CompileAsValue(table, shader, compiler); - if ( - OperatorTable.BinaryOperationResultingType( - Left.ValueType ?? throw new NotImplementedException("Missing type"), - Right.ValueType ?? throw new NotImplementedException("Missing type"), - Op, - out var t - ) - ) - Type = t; - else - table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); var (builder, context) = compiler; - return builder.BinaryOperation(context, context.GetOrRegister(Type), left, Op, right); + var result = builder.BinaryOperation(context, left, Op, right); + Type = context.ReverseTypes[result.TypeId]; + return result; } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 3482d453d6..bb42aacb44 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -216,19 +216,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var left = builder.AsValue(context, target); var right = builder.AsValue(context, source); - if ( - OperatorTable.BinaryOperationResultingType( - variable.Variable.ValueType ?? throw new NotImplementedException("Missing type"), - variable.Value.ValueType ?? throw new NotImplementedException("Missing type"), - binaryOperator, - out var t - ) - ) - Type = t; - else - table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); - - source = builder.BinaryOperation(context, context.GetOrRegister(Type), left, binaryOperator, right); + source = builder.BinaryOperation(context, left, binaryOperator, right); } // Make sure to convert to proper type diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 9ff17ffcac..7077859289 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -22,99 +22,180 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) return result; } - public SpirvValue BinaryOperation(SpirvContext context, int resultType, in SpirvValue left, Operator op, in SpirvValue right, string? name = null) + public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operator op, SpirvValue right, string? name = null) { + var leftType = context.ReverseTypes[left.TypeId]; + var rightType = context.ReverseTypes[right.TypeId]; + + var leftElementType = leftType.GetElementType(); + var rightElementType = rightType.GetElementType(); + + ScalarType desiredElementType; + + // Check base types + // TODO: special case for operators expecting different types (i.e. bit shifts) + switch (leftElementType, rightElementType) + { + case (ScalarType { TypeName: "long" }, _) or (_, ScalarType { TypeName: "long" }): + throw new NotImplementedException("64bit integers"); + + // Matching types + case (ScalarType { TypeName: "int" or "uint" or "float" or "double" } l, ScalarType r) when l == r: + desiredElementType = l; + break; + // If one side is float and other is non-floating, promote to floating + case (ScalarType { TypeName: "int" or "uint" } l, ScalarType { TypeName: "float" or "double" } r): + desiredElementType = r; + break; + case (ScalarType { TypeName: "float" or "double" } l, ScalarType { TypeName: "int" or "uint" } r): + desiredElementType = l; + break; + + // If one side is unsigned, promote to unsigned (bitcast) + case (ScalarType { TypeName: "int"} l, ScalarType { TypeName: "uint" } r): + desiredElementType = r; + break; + case (ScalarType { TypeName: "uint" } l, ScalarType { TypeName: "int" } r): + desiredElementType = l; + break; + default: + throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftType} and {rightType}"); + } + + // Check size + SymbolType resultType; + switch (leftType, rightType) + { + case (ScalarType l, ScalarType r): + resultType = desiredElementType; + break; + + case (ScalarType l, VectorType r): + resultType = r.WithElementType(desiredElementType); + break; + case (VectorType l, ScalarType r): + resultType = l.WithElementType(desiredElementType); + break; + case (VectorType l, VectorType r): + resultType = new VectorType(desiredElementType, Math.Min(l.Size, r.Size)); + break; + + case (ScalarType l, MatrixType r): + resultType = r.WithElementType(desiredElementType); + break; + case (MatrixType l, ScalarType r): + resultType = l.WithElementType(desiredElementType); + break; + case (MatrixType, VectorType): + case (VectorType, MatrixType): + throw new NotImplementedException("Binary expression between vector and matrix is not implemented"); + case (MatrixType l, MatrixType r): + resultType = new MatrixType(desiredElementType, Math.Min(l.Rows, r.Rows), Math.Min(l.Columns, r.Columns)); + break; + default: + throw new NotImplementedException($"Couldn't figure out type for binary operation between {leftType} and {rightType}"); + } + + left = Convert(context, left, resultType); + right = Convert(context, right, resultType); + + // Comparisons and logical operators + if (op == Operator.Greater || op == Operator.Lower || op == Operator.GreaterOrEqual || op == Operator.LowerOrEqual + || op == Operator.NotEquals || op == Operator.Equals || op == Operator.LogicalAND || op == Operator.LogicalOR) + resultType = resultType.WithElementType(ScalarType.From("bool")); + + var resultTypeId = context.GetOrRegister(resultType); var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch { (Operator.Plus, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpIAdd(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIAdd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Plus, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpFAdd(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFAdd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpISub(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpISub(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpFSub(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFSub(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpIMul(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIMul(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpFMul(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFMul(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) - => Buffer.InsertData(Position++, new OpUDiv(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpSDiv(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsFloatingVector() && r.IsFloatingVector() - => Buffer.InsertData(Position++, new OpFDiv(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() - => Buffer.InsertData(Position++, new OpUMod(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUMod(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) - => Buffer.InsertData(Position++, new OpSMod(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSMod(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsFloating() && r.IsNumber() - => Buffer.InsertData(Position++, new OpFMod(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFMod(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.RightShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LeftShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.AND, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseAnd(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseAnd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.OR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseOr(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseOr(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.XOR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseXor(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseXor(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertData(Position++, new OpLogicalAnd(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalAnd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) - => Buffer.InsertData(Position++, new OpLogicalOr(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Equals, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) - => Buffer.InsertData(Position++, new OpIEqual(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Lower, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) - => Buffer.InsertData(Position++, new OpSLessThan(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) - => Buffer.InsertData(Position++, new OpSLessThanEqual(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Greater, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) - => Buffer.InsertData(Position++, new OpSGreaterThan(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) - => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultType, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), _ => throw new NotImplementedException() }; @@ -150,6 +231,12 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy case (ScalarType s1, ScalarType s2): values[0] = valueId; break; + case (ScalarType s1, VectorType v2): + values[0] = valueId; + break; + case (ScalarType s1, MatrixType m2): + values[0] = valueId; + break; case (VectorType v1, ScalarType s2): { values[0] = Insert(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, valueId, [0])).ResultId; @@ -198,37 +285,44 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy } } - // Type casting - // (process each vector one by one) - (int elementSize, var castTypeSameSize) = valueType switch + if (valueType.GetElementType() != castType.GetElementType()) { - ScalarType s => (1, (SymbolType)castType.GetElementType()), - VectorType s => (s.Size, new VectorType(castType.GetElementType(), s.Size)), - }; - for (int i = 0; i < values.Length; ++i) - { - var rowValue = values[i]; - if (rowValue == 0) - throw new InvalidOperationException($"Type conversion from {originalType} to {castType} failed during conversion (current type: {valueType})"); - - var typeCasting = (valueType.GetElementType(), castType.GetElementType()) switch + // Type casting + // (process each vector one by one) + (int elementSize, var castTypeSameSize) = valueType switch + { + ScalarType s => (1, (SymbolType)castType.GetElementType()), + VectorType s => (s.Size, new VectorType(castType.GetElementType(), s.Size)), + }; + for (int i = 0; i < values.Length; ++i) { - // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion - (ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + var rowValue = values[i]; + if (rowValue == 0) + throw new InvalidOperationException($"Type conversion from {originalType} to {castType} failed during conversion (current type: {valueType})"); - (ScalarType { TypeName: "float" }, ScalarType { TypeName: "bool" }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), - (ScalarType { TypeName: "int" }, ScalarType { TypeName: "bool" }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + var typeCasting = (valueType.GetElementType(), castType.GetElementType()) switch + { + // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion + (ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { TypeName: "float" }, ScalarType { TypeName: "bool" }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), + (ScalarType { TypeName: "int" }, ScalarType { TypeName: "bool" }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CreateConstant(new IntegerLiteral(new(32, false, true), 0, new())).Id)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CreateConstant(new FloatLiteral(new(32, true, true), 0.0, null, new())).Id)), - }; - values[i] = typeCasting.IdResult!.Value; + (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CreateConstant(new IntegerLiteral(new(32, false, true), 0, new())).Id)), + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CreateConstant(new FloatLiteral(new(32, true, true), 0.0, null, new())).Id)), - // Update type - if (i == values.Length - 1) - valueType = castTypeSameSize; + // Bitcast (int=>uint or uint=>int) + (ScalarType { TypeName: "int" }, ScalarType { TypeName: "uint" }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { TypeName: "uint" }, ScalarType { TypeName: "int" }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + }; + values[i] = typeCasting.IdResult!.Value; + + // Update type + if (i == values.Length - 1) + valueType = castTypeSameSize; + } } // Expanding @@ -286,6 +380,12 @@ internal static class SymbolExtensions VectorType v => v.BaseType, MatrixType m => m.BaseType, }; + public static SymbolType WithElementType(this SymbolType symbol, ScalarType elementType) => symbol switch + { + ScalarType s => elementType, + VectorType v => v.BaseType == elementType ? v : v with { BaseType = elementType }, + MatrixType m => m.BaseType == elementType ? m : m with { BaseType = elementType }, + }; public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "sbyte" or "short" or "int" or "long" }; public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "byte" or "ushort" or "uint" or "ulong" }; public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { TypeName: "half" or "float" or "double" }; From 584ca6418063782dce4a5a1b7e3c458630190ff8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 1 Dec 2025 12:24:25 +0900 Subject: [PATCH 0528/1182] TypesDuplicatesRemover: rewritten with better code reuse and O(n*log(n)) complexity instead of O(n^2) --- .../Spirv/Processing/TypeDuplicatesRemover.cs | 238 +++++++++--------- 1 file changed, 122 insertions(+), 116 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 4c3967bad7..396622e22e 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Spirv.Core; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Collections.Generic; @@ -18,133 +19,141 @@ namespace Stride.Shaders.Spirv.Processing; /// public struct TypeDuplicateRemover : INanoPass { - public readonly void Apply(NewSpirvBuffer buffer) + public int[] FindItemsWithTypes(NewSpirvBuffer buffer, params Span ops) { + var itemCount = 0; for (var index = 0; index < buffer.Count; index++) { - var i = buffer[index].Data; - if (i.Op == Op.OpTypeVoid || i.Op == Op.OpTypeInt || i.Op == Op.OpTypeFloat) - { - for (var index2 = index + 1; index2 < buffer.Count; index2++) - { - var j = buffer[index2].Data; - if ( - (j.Op == Op.OpTypeVoid || j.Op == Op.OpTypeInt || - j.Op == Op.OpTypeFloat) - && i.IdResult != j.IdResult - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } - } - } + var i = buffer[index]; + if (ops.Contains(i.Op)) + itemCount++; } - + var result = new int[itemCount]; + itemCount = 0; for (var index = 0; index < buffer.Count; index++) { - var i = buffer[index].Data; - if (i.Op == Op.OpTypeVector) - { - for (var index2 = index + 1; index2 < buffer.Count; index2++) - { - var j = buffer[index2].Data; - if ( - j.Op == Op.OpTypeVector - && i.IdResult != j.IdResult - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } - } - } + var i = buffer[index]; + if (ops.Contains(i.Op)) + result[itemCount++] = index; } - for (var index = 0; index < buffer.Count; index++) + return result; + } + + record struct InstructionSortHelper(Op Op, int Index, MemoryOwner Memory) : IComparable + { + public int CompareTo(InstructionSortHelper other) => CompareOperations(this, other); + + private static int CompareOperations(InstructionSortHelper x, InstructionSortHelper y) { - var i = buffer[index].Data; - if (i.Op == Op.OpTypeMatrix) + var comparison = x.Op.CompareTo(y.Op); + if (comparison != 0) + return comparison; + + // Special values for searching bounds + if (x.Index == -1 || y.Index == int.MaxValue) + return -1; + if (y.Index == -1 || x.Index == int.MaxValue) + return 1; + + // Only process types that we care about + if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool + || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction) { - for (var index2 = index + 1; index2 < buffer.Count; index2++) - { - var j = buffer[index2].Data; - if ( - j.Op == Op.OpTypeMatrix - && i.IdResult != j.IdResult - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } - } + comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[2..], y.Memory.Span[2..]); + if (comparison != 0) + return comparison; } - } - for (var index = 0; index < buffer.Count; index++) - { - var i = buffer[index].Data; - if (i.Op == Op.OpTypePointer) + else if (x.Op == Op.OpName) { - for (var index2 = index + 1; index2 < buffer.Count; index2++) - { - var j = buffer[index2].Data; - if ( - j.Op == Op.OpTypePointer - && i.IdResult != j.IdResult - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } - } + comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[1..], y.Memory.Span[1..]); + if (comparison != 0) + return comparison; } + + comparison = x.Index.CompareTo(y.Index); + return comparison; } - for (var index = 0; index < buffer.Count; index++) + } + + public readonly void Apply(NewSpirvBuffer buffer) + { + var instructionsByOp = new List(); + foreach (var i in buffer) + instructionsByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data.Memory)); + instructionsByOp.Sort(); + + // Note: We process instruction by types depending on their dependencies + // i.e. a OpTypeFloat being unified means a OpTypeVector depending on it might too + + // Covers OpTypeVoid, OpTypeBool, OpTypeInt, OpTypeFloat at the same time (no interdependencies) + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false); + // Covers OpTypeVector, OpTypeMatrix at the same time + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeMatrix, true); + + ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true); + + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportShader, Op.OpSDSLImportShader, true); + // Covers OpSDSLImportFunction and OpSDSLImportVariable at the same time + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportFunction, Op.OpSDSLImportVariable, true); + + ProcessInstructions(buffer, instructionsByOp, Op.OpName, Op.OpName, true); + } + + private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort) + { + var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }); + var end = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = endOp, Index = int.MaxValue }); + + if (sort) { - var i = buffer[index].Data; - if (i.Op == Op.OpTypeFunction) - { - for (var index2 = index + 1; index2 < buffer.Count; index2++) - { - var j = buffer[index2].Data; - if ( - j.Op == Op.OpTypeFunction - && i.IdResult != j.IdResult - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } - } - } + // Sort again, but only those instructions (as previous replacements with ReplaceRefs might have changed order) + instructionsByOp.Sort(start, end - start, Comparer.Default); } - for (var index = 0; index < buffer.Count; index++) + + ProcessSortedInstructions(buffer, instructionsByOp, start, end); + } + + private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List instructionsByOp, int start, int end) + { + for (var firstIndex = start; firstIndex < end; ) { - var i = buffer[index].Data; - if (i.Op == Op.OpName) + var i = buffer[instructionsByOp[firstIndex].Index].Data; + + // Find first item that is different + int lastIndex; + for (lastIndex = firstIndex + 1; lastIndex < end; ++lastIndex) { - for (var index2 = index + 1; index2 < buffer.Count; index2++) + var j = instructionsByOp[lastIndex]; + var firstMemoryIndex = i.Op == Op.OpName ? 1 : 2; + if (!(i.Op == j.Op && MemoryExtensions.SequenceEqual(i.Memory.Span[firstMemoryIndex..], j.Memory.Span[firstMemoryIndex..]))) + break; + } + + // At least 2 similar items? + if (lastIndex - firstIndex > 1) + { + // Build list of IdResult matching first instruction + Span matchingRefs = new int[lastIndex - (firstIndex + 1)]; + for (var index = firstIndex + 1; index < lastIndex; ++index) { - var j = buffer[index2].Data; - if ( - j.Op == Op.OpName - && i.Memory.Span[1] == j.Memory.Span[1] - && MemoryExtensions.SequenceEqual(i.Memory.Span[2..], j.Memory.Span[2..]) - ) - { - ReplaceRefs(j.IdResult ?? -1, i.IdResult ?? -1, buffer); - SetOpNop(j.Memory.Span); - } + var j = buffer[instructionsByOp[index].Index].Data; + if (i.Op != Op.OpName) + matchingRefs[index - (firstIndex + 1)] = j.IdResult ?? throw new InvalidOperationException(); + SetOpNop(j.Memory.Span); } + + // Replace all IdResult at once to the one of first instruction + if (i.Op != Op.OpName) + ReplaceRefs(matchingRefs, i.IdResult ?? throw new InvalidOperationException(), buffer); } + + // Restart from last different instruction + firstIndex = lastIndex; } } - static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) + static void ReplaceRefs(Span from, int to, NewSpirvBuffer buffer) { foreach (var i in buffer) { @@ -155,23 +164,20 @@ static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) { foreach (ref var w in op.Words) { - if (w == from) + if (from.Contains(w)) w = to; } } - else if (op.Kind == OperandKind.IdResultType && op.Words[0] == from) + else if (op.Kind == OperandKind.IdResultType && from.Contains(op.Words[0])) + op.Words[0] = to; + else if (op.Kind == OperandKind.PairIdRefLiteralInteger && from.Contains(op.Words[0])) op.Words[0] = to; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger && op.Words[0] == from) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && op.Words[1] == from) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef && from.Contains(op.Words[1])) + op.Words[1] = to; else if (op.Kind == OperandKind.PairIdRefIdRef) { - if (op.Words[0] == from || op.Words[1] == from) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } + op.Words[0] = from.Contains(op.Words[0]) ? to : op.Words[0]; + op.Words[1] = from.Contains(op.Words[1]) ? to : op.Words[1]; } } } From ba8b5b608a7086021fdd88203d8af3d09e36b681 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 13:21:25 +0900 Subject: [PATCH 0529/1182] Parse all declarations in all namespaces as well as root declarations --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index ad7bb64529..745102c6e4 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -25,7 +25,9 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf } if(parsed.AST is ShaderFile sf) { - foreach (var declaration in sf.Namespaces.First().Declarations) + // TODO: support namespace + var declarations = sf.Namespaces.SelectMany(x => x.Declarations).Concat(sf.RootDeclarations); + foreach (var declaration in declarations) { if (declaration is ShaderClass shader) { From 06e33ea292287c8f53687a6382a79bede0b3a0b3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 13:30:57 +0900 Subject: [PATCH 0530/1182] Reorganized how importing external reference is done. Added OpThis and OpStage. Improved generics --- .../SDSL/EffectEvaluator.cs | 2 +- .../SDSL/ShaderMixer.MixinNode.cs | 5 + .../SDSL/ShaderMixer.ShaderInfo.cs | 93 +++----- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 2 +- .../SDSL/ShaderMixer.cs | 219 +++++++++++------- .../Buffers/NewSpirvBuffer.cs | 11 +- .../Extensions/spirv.sdsl.grammar-ext.json | 69 +++++- src/Stride.Shaders/Core/Symbol.cs | 2 +- src/Stride.Shaders/Core/SymbolTypes.cs | 19 -- .../Parsing/SDSL/AST/Expression.cs | 62 +++-- .../Parsing/SDSL/AST/Literals.cs | 25 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 79 ++++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 6 +- .../Parsing/SDSL/AST/ShaderElements.cs | 97 +++++--- .../SDSL/Parsers/Common/CommonParsers.cs | 44 ++-- .../ShaderParsers/ShaderDataParsers.cs | 7 +- .../ShaderParsers/ShaderElementParsers.cs | 5 - .../Spirv/Building/Builder.Class.cs | 171 +++++++++----- src/Stride.Shaders/Spirv/Building/Context.cs | 8 +- .../Spirv/Processing/StreamAnalyzer.cs | 3 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 3 +- 21 files changed, 576 insertions(+), 356 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 160c3446a0..2a02aad15d 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -20,7 +20,7 @@ public ShaderSource EvaluateEffects(ShaderSource source) if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) throw new NotImplementedException(); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, new ShaderClassInstantiation(classSource.ClassName, []), ResolveStep.Compile); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); if (buffer[0].Op == Op.OpSDSLEffect) { var mixinTree = new ShaderMixinSource(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 80e7409a5f..ab39427e3b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -40,7 +40,12 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary ShadersByName { get; } = new(); public Dictionary MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); + public Dictionary VariablesByName { get; } = new(); public Dictionary Compositions { get; } = new(); + + public Dictionary ExternalShaders { get; } = new(); + public Dictionary ExternalFunctions { get; } = new(); + public Dictionary ExternalVariables { get; } = new(); } class MethodGroup diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 3b15b39952..7952940d23 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -1,10 +1,11 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Globalization; using static Stride.Shaders.Spirv.Specification; -using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Compilers.SDSL; @@ -93,96 +94,54 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader } } - private void RemapInheritedIds(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderClassInstantiation classSource, ShaderInfo shaderInfo, MixinNode mixinNode) + private void BuildImportInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderClassInstantiation classSource, ShaderInfo shaderInfo, MixinNode mixinNode) { - var importedShaders = new Dictionary(); - var idRemapping = new Dictionary(); + var inheritedShaders = new HashSet(); for (var index = shaderStart; index < temp.Count; index++) { var i = temp[index]; - - if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) { - if (idRemapping.ContainsKey(nameInstruction.Target)) - { - SetOpNop(i.Data.Memory.Span); - shaderInfo.Names.Remove(nameInstruction.Target); - } + inheritedShaders.Add(mixinInherit.Shader); + SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) + } + + for (var index = shaderStart; index < temp.Count; index++) + { + var i = temp[index]; + + if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { + mixinNode.ExternalShaders.Add(importShader.ResultId, importShader.ShaderName); SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) { - if (importShader.Type == Specification.ImportType.Inherit) + if (mixinNode.ExternalShaders.ContainsKey(importFunction.Shader)) { - //var shaderClassSource = Spirv.Building.SpirvBuilder.ConvertToShaderClassSource(temp, shaderStart, shaderEnd, importShader); - var shaderClassSource = classSource.ShaderReferences[importShader.ResultId - classSource.OffsetId]; - importedShaders.Add(importShader.ResultId, mixinNode.ShadersByName[shaderClassSource.ToClassName()]); - + mixinNode.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName)); SetOpNop(i.Data.Memory.Span); } } else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) { - if (importedShaders.TryGetValue(importVariable.Shader, out var importedShader)) + if (mixinNode.ExternalShaders.ContainsKey(importVariable.Shader)) { - var importedVariable = importedShader.Variables[importVariable.VariableName]; - - idRemapping.Add(importVariable.ResultId, importedVariable.Id); - + mixinNode.ExternalVariables.Add(importVariable.ResultId, (importVariable.Shader, importVariable.VariableName)); SetOpNop(i.Data.Memory.Span); } } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + // Removing OpName for OpSDSLImportShader and OpSDSLImportFunction (they are always located after, so no problem to do it in a single pass) + else if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) { - if (importedShaders.TryGetValue(importFunction.Shader, out var importedShader)) + if (mixinNode.ExternalShaders.ContainsKey(nameInstruction.Target) + || mixinNode.ExternalFunctions.ContainsKey(nameInstruction.Target) + || mixinNode.ExternalVariables.ContainsKey(nameInstruction.Target)) { - if (importedShader.Functions.ContainsKey(importFunction.FunctionName)) - { - var importedFunction = importedShader.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - } - else if (importedShader.Stage != null && importedShader.Stage.Functions.ContainsKey(importFunction.FunctionName)) - { - var importedFunction = importedShader.Stage.Functions[importFunction.FunctionName]; - idRemapping.Add(importFunction.ResultId, importedFunction); - } - else - { - // We have some cases when function is removed (i.e. stage/non-stage depending on mixin node), but import is still there. - // In this case, we map to 0 and make sure it's not referenced during next step. - idRemapping.Add(importFunction.ResultId, 0); - } - SetOpNop(i.Data.Memory.Span); } } - - foreach (var op in i.Data) - { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) - { - if (to1 == 0) - throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[0]} at instruction {index}"); - op.Words[0] = to1; - } - - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - { - if (to2 == 0) - throw new InvalidOperationException($"Tried to remap a non-existing id {op.Words[1]} at instruction {index}"); - op.Words[1] = to2; - } - } } } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index a3c75cd2d7..77e6b725f3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -33,7 +33,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) throw new NotImplementedException("Generics at the top-level shaders is not supported"); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2, ResolveStep.Mix); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName); mixinToMerge2.Buffer = buffer; //SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList, ResolveStep.Mix); SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 23e701e39b..0f81730faa 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -2,20 +2,20 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.PostProcessing; using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; -using Stride.Shaders.Parsing.SDSL; using static Stride.Shaders.Spirv.Specification; -using Stride.Shaders.Spirv.PostProcessing; namespace Stride.Shaders.Compilers.SDSL; @@ -35,21 +35,24 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); // Root shader - MergeMixinNode(new MixinGlobalContext(), context, table, temp, shaderSource2); + var globalContext = new MixinGlobalContext(); + MergeMixinNode(globalContext, context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - CleanupUnnecessaryInstructions(temp); temp.Sort(); + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + new StreamAnalyzer().Process(table, temp, context); + CleanupUnnecessaryInstructions(temp); + foreach (var inst in context) temp.Add(inst.Data); - // Final processing SpirvProcessor.Process(temp); @@ -76,6 +79,12 @@ class MixinNodeContext public MixinNode? Result { get; } } + struct LinkInfo + { + public string LinkName; + public string ResourceGroup; + public string LogicalGroup; + } MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { @@ -96,7 +105,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, new TypeDuplicateRemover().Apply(buffer); //Console.WriteLine("Done type remapping"); - //Spv.Dis(buffer, true); + Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); // Build names and types mappings ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); @@ -125,7 +134,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = buffer[index]; - if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction) + if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable) { SetOpNop(i.Data.Memory.Span); } @@ -224,8 +233,7 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad mixinNode.ShadersByName.Add(shaderClass.ToClassName(), shaderInfo); shaders.Add(shaderInfo); - // Remap ids from inherited class (OpSDSLImport*) - RemapInheritedIds(temp, shaderStart, temp.Count, shaderClass, shaderInfo, mixinNode); + BuildImportInfo(temp, shaderStart, temp.Count, shaderClass, shaderInfo, mixinNode); } mixinNode.EndInstruction = temp.Count; @@ -256,6 +264,8 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } } + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + // Build method group info (override, etc.) ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) @@ -271,10 +281,15 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, { currentShader = null; } + else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass == Specification.StorageClass.Private) + { + var variableName = globalContext.Names[variable.ResultId]; + mixinNode.VariablesByName.Add(variableName, variable.ResultId); + } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && - (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) + (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { var functionName = globalContext.Names[function.ResultId]; @@ -282,6 +297,16 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) methodMixinGroup = methodMixinGroup.Stage; + // If OpSDSLFunctionInfo.Parent is coming from a OpSDSLImportFunction, find the real ID + if (functionInfo.Parent != 0) + { + if (mixinNode.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) + { + var shaderName = mixinNode.ExternalShaders[parentFunctionInfo.ShaderId]; + functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name]; + } + } + // Check if it has a parent (and if yes, share the MethodGroup) if (!methodMixinGroup.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) methodGroup = new MethodGroup { Name = functionName }; @@ -317,105 +342,131 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvBuffer temp, MixinNode mixinNode) { - var externalShaders = new HashSet(); - var externalFunctions = new Dictionary(); + var memberAccesses = new Dictionary(); + var thisInstructions = new HashSet(); + var baseInstructions = new HashSet(); + var stageInstructions = new HashSet(); ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = temp[index]; - // Only import shaders should be left - if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + currentShader = mixinNode.Shaders.Last(x => index >= x.StartInstruction); + + // Apply any OpMemberAccessSDSL remapping + if (memberAccesses.Count > 0) + SpirvBuilder.RemapIds(memberAccesses, i); + + if (i.Data.Op == Op.OpThisSDSL && (OpThisSDSL)i is { } thisInstruction) { - // Only external should be left - if (importShader.Type == ImportType.External) - { - externalShaders.Add(importShader.ResultId); - SetOpNop(i.Data.Memory.Span); - } + thisInstructions.Add(thisInstruction.ResultId); + SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + else if (i.Data.Op == Op.OpBaseSDSL && (OpBaseSDSL)i is { } baseInstruction) { - if (externalShaders.Contains(importFunction.Shader)) - { - externalFunctions.Add(importFunction.ResultId, importFunction.FunctionName); - SetOpNop(i.Data.Memory.Span); - } + baseInstructions.Add(baseInstruction.ResultId); + SetOpNop(i.Data.Memory.Span); } - // Removing OpName for OpSDSLImportShader and OpSDSLImportFunction (they are always located after, so no problem to do it in a single pass) - else if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + else if (i.Data.Op == Op.OpStageSDSL && (OpStageSDSL)i is { } stageInstruction) { - if (externalShaders.Contains(nameInstruction.Target) || externalFunctions.ContainsKey(nameInstruction.Target)) - { - SetOpNop(i.Data.Memory.Span); - } + stageInstructions.Add(stageInstruction.ResultId); + SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + else if (i.Data.Op == Op.OpMemberAccessSDSL && (OpMemberAccessSDSL)i is { } memberAccess) { - if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[function.ResultId]}"); + // Find out the proper mixin node (the member instance) + var isThis = thisInstructions.Contains(memberAccess.Instance); + var isBase = baseInstructions.Contains(memberAccess.Instance); + var isStage = stageInstructions.Contains(memberAccess.Instance); + MixinNode instanceMixinGroup; + if (isThis || isBase) + instanceMixinGroup = mixinNode; + else if (isStage) + instanceMixinGroup = mixinNode.Stage ?? mixinNode; + else + instanceMixinGroup = mixinNode.Compositions[memberAccess.Instance]; - currentShader = mixinNode.Shaders.Last(x => index >= x.StartInstruction); - } - else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) - { - var methodMixinGroup = mixinNode; - var isBaseCall = temp[index - 1].Op == Op.OpSDSLCallBase; + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // Process member call (composition) - if (temp[index - 1].Op == Op.OpSDSLCallTarget) + if (mixinNode.ExternalVariables.TryGetValue(memberAccess.Member, out var variable)) { - var callTarget = (OpSDSLCallTarget)temp[index - 1]; - var composition = mixinNode.Compositions[callTarget.Target]; - methodMixinGroup = composition; - - var functionName = externalFunctions[functionCall.Function]; - var functionId = composition.MethodGroupsByName[functionName]; - - functionCall.Function = functionId; - - SetOpNop(temp[index - 1].Data.Memory.Span); + instanceMixinGroup.VariablesByName.TryGetValue(variable.Name, out var variableId); + memberAccesses.Add(memberAccess.ResultId, variableId); } - - bool foundInStage = false; - if (!methodMixinGroup.MethodGroups.TryGetValue(functionCall.Function, out var methodGroupEntry)) + else if (globalContext.Types[memberAccess.ResultType] is FunctionType) { - // Try again as a stage method (only if not a base call) - if (methodMixinGroup.Stage == null || !methodMixinGroup.Stage.MethodGroups.TryGetValue(functionCall.Function, out methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[functionCall.Function]}"); - foundInStage = true; - } + // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL + var functionId = memberAccess.Member; + if (mixinNode.ExternalFunctions.TryGetValue(memberAccess.Member, out var function)) + // Process member call (composition) + functionId = instanceMixinGroup.MethodGroupsByName[function.Name]; + + bool foundInStage = false; + if (!instanceMixinGroup.MethodGroups.TryGetValue(functionId, out var methodGroupEntry)) + { + // Try again as a stage method (only if not a base call) + if (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroups.TryGetValue(functionId, out methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[functionId]}"); + foundInStage = true; + } - // Process base call - if (isBaseCall) - { - // We currently do not allow calling base stage method from a non-stage method - // (if we were to allow them later, we would need to tweak following detection code as ShaderIndex comparison is only valid for items within the same MixinNode) - if (foundInStage) - throw new InvalidOperationException($"Method {globalContext.Names[functionCall.Function]} was found but a base call can't be performed on a stage method from a non-stage method"); - - // Is it a base call? if yes, find the direct parent - // Let's find the method in same group just before ours - bool baseMethodFound = false; - for (int j = methodGroupEntry.Methods.Count - 1; j >= 0; --j) + // Process base call + if (isBase) { - if (methodGroupEntry.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) + // We currently do not allow calling base stage method from a non-stage method + // (if we were to allow them later, we would need to tweak following detection code as ShaderIndex comparison is only valid for items within the same MixinNode) + if (foundInStage) + throw new InvalidOperationException($"Method {globalContext.Names[functionId]} was found but a base call can't be performed on a stage method from a non-stage method"); + + // Is it a base call? if yes, find the direct parent + // Let's find the method in same group just before ours + bool baseMethodFound = false; + for (int j = methodGroupEntry.Methods.Count - 1; j >= 0; --j) { - functionCall.Function = methodGroupEntry.Methods[j].MethodId; - baseMethodFound = true; - break; + if (methodGroupEntry.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) + { + functionId = methodGroupEntry.Methods[j].MethodId; + baseMethodFound = true; + break; + } } - } - if (!baseMethodFound) - throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionCall.Function]}"); + if (!baseMethodFound) + throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionId]}"); - SetOpNop(temp[index - 1].Data.Memory.Span); + SetOpNop(temp[index - 1].Data.Memory.Span); + } + else + { + // If not, get the most derived implementation + functionId = methodGroupEntry.Methods[^1].MethodId; + } + + memberAccesses.Add(memberAccess.ResultId, functionId); } else { - // If not, get the most derived implementation - functionCall.Function = methodGroupEntry.Methods[^1].MethodId; + throw new InvalidOperationException($"Member {memberAccess.Member} not found"); + } + + SetOpNop(i.Data.Memory.Span); + } + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + { + if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) + throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[function.ResultId]}"); + } + else if (i.Data.Op == Op.OpFunctionEnd) + { + memberAccesses.Clear(); + } + else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) + { + if (memberAccesses.TryGetValue(functionCall.Function, out var functionId)) + { + functionCall.Function = functionId; } + + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } } } @@ -478,6 +529,8 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) || temp[i].Op == Op.OpConstantStringSDSL || temp[i].Op == Op.OpTypeGenericLinkSDSL) temp.RemoveAt(i--); + else if (temp[i].Op == Op.OpDecorateString && ((OpDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) + temp.RemoveAt(i--); else if (temp[i].Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) temp.RemoveAt(i--); } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 33973ebf9f..6879425cd4 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -59,8 +59,17 @@ public OpData(Span memory) public readonly void Dispose() => Memory.Dispose(); + public readonly SpvOperand Get(string name) + { + foreach (var o in this) + { + if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) + return o; + } + throw new Exception($"No operand '{name}' in op {Op}"); + } - public readonly bool TryGetOperand(string name, out T operand) + public readonly bool TryGet(string name, out T operand) { foreach (var o in this) { diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 822c6a10a5..8465bff541 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -88,8 +88,8 @@ "opname": "OpSDSLImportFunction", "class": "Miscellaneous", "operands": [ - { "kind": "IdResultType" }, { "kind": "IdResult" }, + { "kind": "IdResultType" }, { "kind": "LiteralString", "name": "functionName" @@ -108,8 +108,8 @@ "opname": "OpSDSLImportVariable", "class": "Miscellaneous", "operands": [ - { "kind": "IdResultType" }, { "kind": "IdResult" }, + { "kind": "IdResultType" }, { "kind": "LiteralString", "name": "variableName" @@ -120,6 +120,22 @@ } ] }, + { + "opname": "OpMemberAccessSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { + "kind": "IdRef", + "name": "instance" + }, + { + "kind": "IdRef", + "name": "member" + } + ] + }, { "opname": "OpSDSLFunctionInfo", "class": "Miscellaneous", @@ -135,18 +151,25 @@ ] }, { - "opname": "OpSDSLCallTarget", + "opname": "OpBaseSDSL", "class": "Miscellaneous", "operands": [ - { - "kind": "IdRef", - "name": "target" - } + { "kind": "IdResult" } ] }, { - "opname": "OpSDSLCallBase", - "class": "Miscellaneous" + "opname": "OpThisSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" } + ] + }, + { + "opname": "OpStageSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" } + ] }, { "opname": "OpSDSLMixin", @@ -178,7 +201,10 @@ "operands": [ { "kind": "IdResultType" }, { "kind": "IdResult" }, - { "kind": "GenericParameterKindSDSL", "name": "kind" } + { + "kind": "GenericParameterKindSDSL", + "name": "kind" + } ] }, { @@ -251,8 +277,29 @@ } ], "version": "1.0" + }, + { + "enumerant": "ResourceGroupSDSL", + "value": 8002, + "parameters": [ + { + "kind": "LiteralString", + "name": "'ResourceGroup'" + } + ], + "version": "1.0" + }, + { + "enumerant": "LogicalGroupSDSL", + "value": 8003, + "parameters": [ + { + "kind": "LiteralString", + "name": "'LogicalGroup'" + } + ], + "version": "1.0" } - ] }, { diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index e854fb8ed9..f66bef596f 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -46,7 +46,7 @@ public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, ImmutableArray GroupMembers = default); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, bool ImplicitThis = false, ImmutableArray GroupMembers = default); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index f6e9a0a623..4481fab15e 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -240,25 +240,6 @@ public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Typ public sealed record ShaderSymbol(string Name, int[] GenericArguments, List Components) : SymbolType { - public Symbol Get(string name, SymbolKind kind) - { - foreach (var e in Components) - if (e.Id.Kind == kind && e.Id.Name == name) - return e; - throw new ArgumentException($"{name} not found in Mixin {Name}"); - } - public bool TryGet(string name, SymbolKind kind, out Symbol? value) - { - foreach (var e in Components) - if (e.Id.Kind == kind && e.Id.Name == name) - { - value = e; - return true; - } - value = null!; - return false; - } - public string ToClassName() { if (GenericArguments.Length == 0) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 786c5b128f..4011505949 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -82,15 +82,26 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil compiledParams[tmp++] = paramVariable; } + int? instance = null; if (MemberCall != null) { - builder.Insert(new OpSDSLCallTarget(MemberCall.Value.Id)); + instance = MemberCall.Value.Id; } else if (IsBaseCall) { - builder.Insert(new OpSDSLCallBase()); + instance = builder.Insert(new OpBaseSDSL(context.Bound++)).ResultId; + } + else if (functionSymbol.ImplicitThis) + { + var isStage = (functionSymbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; + instance = isStage + ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId + : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; } + if (instance is int instanceId) + functionSymbol.IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId; + return builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); } public override string ToString() @@ -189,7 +200,6 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { var (builder, context) = compiler; SpirvValue result; - var variable = context.Bound++; int firstIndex = 0; SymbolType currentValueType; @@ -246,33 +256,45 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } else { - Span indexes = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i <= Accessors.Count; i++) + int lastCreatedChainStart = firstIndex; + void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) { - // Last accessor (or method call next) - if (i == Accessors.Count || Accessors[i] is MethodCall) + // Do we need to issue an OpAccessChain? + if (currentIndex > lastCreatedChainStart) { - // Do we need to issue an OpAccessChain? - if (i > firstIndex) - { - var resultType = context.GetOrRegister(Type); - var accessChain = builder.Insert(new OpAccessChain(variable, resultType, result.Id, [.. indexes.Slice(firstIndex, i - firstIndex)])); - result = new SpirvValue(accessChain.ResultId, resultType); - } - - if (i == Accessors.Count) - break; - - firstIndex = i + 1; + var resultType = context.GetOrRegister(currentValueType); + var test = new LiteralArray(indexes); + var accessChain = builder.Insert(new OpAccessChain(context.Bound++, resultType, result.Id, [.. indexes.Slice(lastCreatedChainStart, currentIndex - lastCreatedChainStart)])); + result = new SpirvValue(accessChain.ResultId, resultType); } + lastCreatedChainStart = nextStart; + } + + Span indexes = stackalloc int[Accessors.Count]; + for (var i = firstIndex; i < Accessors.Count; i++) + { var accessor = Accessors[i]; switch (currentValueType, accessor) { case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + // Emit OpAccessChain with everything so far + // next start is i + 1 because current value doesn't add a call + EmitOpAccessChain(i, i + 1, indexes); + methodCall2.MemberCall = result; result = methodCall2.Compile(table, shader, compiler); break; + case (PointerType { BaseType: ShaderSymbol s }, Identifier field): + // Emit OpAccessChain with everything so far + // next start is i + 1 because current value doesn't add a call + EmitOpAccessChain(i, i + 1, indexes); + + var matchingComponent = s.Components.First(x => x.Id.Kind == SymbolKind.Variable && x.Id.Name == field.Name); + accessor.Type = matchingComponent.Type; + var inst = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(matchingComponent.Type), context.Bound++, result.Id, matchingComponent.IdRef)); + result = new(inst.ResultId, inst.ResultType); + break; case (PointerType { BaseType: StructType s }, Identifier field): var index = s.TryGetFieldIndex(field); if (index == -1) @@ -289,6 +311,8 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil currentValueType = accessor.Type; } + + EmitOpAccessChain(Accessors.Count, Accessors.Count, indexes); } Type = currentValueType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 0cd3ce4190..36d5d5c975 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -6,6 +6,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Numerics; +using System.Reflection; using System.Text; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -236,10 +237,22 @@ public class Identifier(string name, TextLocation info) : Literal(info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var symbol = table.ResolveSymbol(Name); + var (builder, context) = compiler; + + if (!table.TryResolveSymbol(Name, out var symbol)) + { + // Maybe it's a static variable? try to resolve by loading file + var classSource = new ShaderClassInstantiation(Name, []); + classSource.Buffer = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); + var shaderType = ShaderClass.LoadExternalShaderType(table, classSource); + + ShaderClass.Inherit(table, context, shaderType, false); + // Let's add this shader + + throw new NotImplementedException(); + } Type = symbol.Type; - var (builder, context) = compiler; var resultType = context.GetOrRegister(Type); var result = new SpirvValue(symbol.IdRef, resultType, Name); @@ -250,6 +263,14 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil var index = context.CreateConstant(indexLiteral).Id; result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); } + else if (symbol.ImplicitThis is true) + { + var isStage = (symbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; + var instance = isStage + ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId + : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + result.Id = builder.Insert(new OpMemberAccessSDSL(resultType, context.Bound++, instance, symbol.IdRef)); + } return result; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a42ee9879b..84c0691c8b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -220,7 +220,6 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Push(); - var symbols = new List(); var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; if (Generics != null) { @@ -320,7 +319,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } } - var currentShader = new ShaderSymbol(Name, openGenerics, symbols); + var currentShader = new ShaderSymbol(Name, openGenerics, []); RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; @@ -331,35 +330,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) foreach (var shaderType in shaderSymbols) { - // Import types and variables/functions - context.FluentAdd(new OpSDSLImportShader(context.Bound, ImportType.Inherit, new(shaderType.Name), new(shaderType.GenericArguments.AsSpan())), out var shader); - context.AddName(context.Bound, shaderType.Name); - context.Bound++; - - foreach (var c in shaderType.Components) - { - if (c.Id.Kind == SymbolKind.Variable) - { - var variableTypeId = context.GetOrRegister(c.Type); - context.FluentAdd(new OpSDSLImportVariable(variableTypeId, context.Bound, c.Id.Name, shader.ResultId), out var variable); - context.AddName(context.Bound, c.Id.Name); - context.Bound++; - table.CurrentFrame.Add(c.Id.Name, c with { IdRef = variable.ResultId }); - } - else if (c.Id.Kind == SymbolKind.Method) - { - var functionType = (FunctionType)c.Type; - - var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.FluentAdd(new OpSDSLImportFunction(functionReturnTypeId, context.Bound, c.Id.Name, shader.ResultId, c.Id.FunctionFlags), out var function); - context.AddName(context.Bound, c.Id.Name); - context.Bound++; - table.CurrentFrame.Add(c.Id.Name, c with { IdRef = function.ResultId }); - } - } - - // Mark inherit - context.Add(new OpSDSLMixinInherit(shader.ResultId)); + Inherit(table, context, shaderType, true); } foreach (var member in Elements.OfType()) @@ -380,7 +351,51 @@ public void Compile(CompilerUnit compiler, SymbolTable table) table.Pop(); } - private static ShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) + public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol shaderType, bool addToRoot) + { + // Import types and variables/functions + var shaderId = context.Bound++; + context.FluentAdd(new OpSDSLImportShader(shaderId, ImportType.Inherit, new(shaderType.Name), new(shaderType.GenericArguments.AsSpan())), out var shader); + context.AddName(shaderId, shaderType.Name); + + for (int i = 0; i < shaderType.Components.Count; i++) + { + Symbol c = shaderType.Components[i]; + if (c.Id.Kind == SymbolKind.Variable) + { + var variableTypeId = context.GetOrRegister(c.Type); + context.FluentAdd(new OpSDSLImportVariable(context.Bound, variableTypeId, c.Id.Name, shader.ResultId), out var variable); + context.AddName(context.Bound, c.Id.Name); + context.Bound++; + shaderType.Components[i] = c = c with { IdRef = variable.ResultId, ImplicitThis = true }; + if (addToRoot) + table.CurrentFrame.Add(c.Id.Name, c); + } + else if (c.Id.Kind == SymbolKind.Method) + { + var functionType = (FunctionType)c.Type; + + var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); + context.FluentAdd(new OpSDSLImportFunction(context.Bound, functionReturnTypeId, c.Id.Name, shader.ResultId, c.Id.FunctionFlags), out var function); + context.AddName(context.Bound, c.Id.Name); + context.Bound++; + shaderType.Components[i] = c = c with { IdRef = function.ResultId, ImplicitThis = true }; + if (addToRoot) + table.CurrentFrame.Add(c.Id.Name, c); + } + } + + if (!addToRoot) + { + var symbol = new Symbol(new(shaderType.Name, SymbolKind.Shader), shaderType, shaderId); + table.CurrentFrame.Add(shaderType.Name, symbol); + } + + // Mark inherit + context.Add(new OpSDSLMixinInherit(shader.ResultId)); + } + + public static ShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) { var shaderBuffer = classSource.Buffer; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 17c371fa56..136515af69 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; using System.Collections.Immutable; +using System.Diagnostics.Metrics; using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -104,6 +105,7 @@ public sealed class ShaderMember( public TypeName TypeName { get; set; } = typeName; public Identifier? Semantic { get; set; } = semantic; public StreamKind StreamKind { get; set; } = streamKind; + public bool IsCompose { get; set; } public bool IsArray => TypeName?.IsArray ?? false; public Expression? Value { get; set; } = initialValue; public TypeModifier TypeModifier { get; set; } = typeModifier; @@ -127,6 +129,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); + var sid = new SymbolID ( @@ -225,7 +229,7 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; - var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id); + var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id, ImplicitThis: true); table.CurrentShader.Components.Add(symbol); table.CurrentFrame.Add(Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 4b80580801..1b1d25cdf8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; +using System; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -204,6 +205,46 @@ public override string ToString() public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { + public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable table, TextLocation info, List attributes) + { + if (attributes != null) + { + foreach (var attribute in attributes) + { + if (attribute is AnyShaderAttribute anyAttribute && anyAttribute.Name == "Link") + { + if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) + { + // Try to resolve generic parameter when encoded as string (deprecated) + if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) + { + // TODO: make it a warning only? + table.Errors.Add(new(info, "LinkType generics should be passed without quotes")); + } + + return (linkLiteral.Value, null); + } + else if (anyAttribute.Parameters[0] is Identifier identifier) + { + if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + { + throw new InvalidOperationException(); + } + return (null, linkSymbol.IdRef); + } + else + { + throw new NotImplementedException($"Attribute {attribute} is not supported"); + } + } + else + throw new NotImplementedException($"Attribute {attribute} is not supported"); + } + } + + return (null, null); + } + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; @@ -223,37 +264,11 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile if (member.Attributes != null && member.Attributes.Count > 0) { - foreach (var attribute in member.Attributes) - { - if (attribute is AnyShaderAttribute anyAttribute && anyAttribute.Name == "Link") - { - if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) - { - // Try to resolve generic parameter when encoded as string (deprecated) - if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) - { - // TODO: make it a warning only? - table.Errors.Add(new(Info, "LinkType generics should be passed without quotes")); - } - - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkLiteral.Value))); - } - else if (anyAttribute.Parameters[0] is Identifier identifier) - { - if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) - { - throw new InvalidOperationException(); - } - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkSymbol.IdRef))); - } - else - { - throw new NotImplementedException($"Attribute {attribute} is not supported"); - } - } - else - throw new NotImplementedException($"Attribute {attribute} is not supported"); - } + var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); + if (linkInfo.LinkId is int linkId) + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + else + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{member.Name}"))); } } } @@ -265,6 +280,10 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { var (builder, context) = compiler; + var splitDotIndex = Name.IndexOf('.'); + var resourceGroupName = splitDotIndex != -1 ? Name.Substring(0, splitDotIndex) : Name; + var logicalGroupName = splitDotIndex != -1 ? Name.Substring(splitDotIndex + 1) : null; + for (var index = 0; index < Members.Count; index++) { var member = Members[index]; @@ -280,11 +299,27 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var typeId = context.GetOrRegister(type); context.FluentAdd(new OpVariable(typeId, context.Bound++, storageClass, null), out var variable); context.AddName(variable.ResultId, member.Name); + + DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); + + context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationResourceGroupSDSL(resourceGroupName))); + if (logicalGroupName != null) + context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationLogicalGroupSDSL(logicalGroupName))); + var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, variable.ResultId); table.CurrentFrame.Add(member.Name, symbol); } } + + internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass shaderClass, SpirvContext context, TextLocation info, string memberName, List attributes, int variableId) + { + var linkInfo = CBuffer.ProcessLinkAttributes(table, info, attributes); + if (linkInfo.LinkId is int linkId) + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + else + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{memberName}"))); + } } public sealed class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index e9989cfb57..a8b255336a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -119,11 +119,12 @@ public static bool MethodModifiers(ref TScanner scanner, ParseResult r return matched; } - public static bool VariableModifiers(ref TScanner scanner, ParseResult result, out bool isStaged, out StreamKind streamKind, out InterpolationModifier interpolation, out TypeModifier typeModifier, out StorageClass storageClass, bool advance = true) + public static bool VariableModifiers(ref TScanner scanner, ParseResult result, out bool isStaged, out bool isCompose, out StreamKind streamKind, out InterpolationModifier interpolation, out TypeModifier typeModifier, out StorageClass storageClass, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; isStaged = false; + isCompose = false; streamKind = StreamKind.None; interpolation = InterpolationModifier.None; typeModifier = TypeModifier.None; @@ -133,7 +134,8 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult while ( Tokens.AnyOf( [ - "stage", + "stage", + "compose", "stream", "patchstream", "linear", @@ -161,41 +163,43 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult matched = true; if (match == "stage") isStaged = true; - else if(match == "stream") + else if (match == "compose") + isCompose = true; + else if (match == "stream") streamKind = StreamKind.Stream; - else if(match == "patchstream") + else if (match == "patchstream") streamKind = StreamKind.PatchStream; - else if(match == "linear") + else if (match == "linear") interpolation = InterpolationModifier.Linear; - else if(match == "centroid") + else if (match == "centroid") interpolation = InterpolationModifier.Centroid; - else if(match == "nointerpolation") + else if (match == "nointerpolation") interpolation = InterpolationModifier.NoInterpolation; - else if(match == "noperspective") + else if (match == "noperspective") interpolation = InterpolationModifier.NoPerspective; - else if(match == "sample") + else if (match == "sample") interpolation = InterpolationModifier.Sample; - else if(match == "extern") + else if (match == "extern") storageClass = StorageClass.Extern; - else if(match == "nointerpolation") + else if (match == "nointerpolation") storageClass = StorageClass.NoInterpolation; - else if(match == "precise") + else if (match == "precise") storageClass = StorageClass.Precise; - else if(match == "shared") + else if (match == "shared") storageClass = StorageClass.Shared; - else if(match == "groupshared") + else if (match == "groupshared") storageClass = StorageClass.GroupShared; - else if(match == "static") + else if (match == "static") storageClass = StorageClass.Static; - else if(match == "uniform") + else if (match == "uniform") storageClass = StorageClass.Uniform; - else if(match == "volatile") + else if (match == "volatile") storageClass = StorageClass.Volatile; - else if(match == "const") + else if (match == "const") typeModifier = TypeModifier.Const; - else if(match == "rowmajor") + else if (match == "rowmajor") typeModifier = TypeModifier.RowMajor; - else if(match == "columnmajor") + else if (match == "columnmajor") typeModifier = TypeModifier.ColumnMajor; else break; } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 92b03ad60e..f7319cdf90 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -19,12 +19,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); - if (Tokens.Literal("compose", ref scanner)) - return Parsers.Exit(ref scanner, result, out parsed, position); - - var hasModifier = - Parsers.VariableModifiers(ref scanner, result, out var isStaged, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) + Parsers.VariableModifiers(ref scanner, result, out var isStaged, out var isCompose, out var streamKind, out var interpolation, out var typeModifier, out var storageClass, advance: true) && Parsers.Spaces0(ref scanner, result, out _); if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out value)) @@ -40,6 +36,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, + IsCompose = isCompose, Interpolation = interpolation, StreamKind = streamKind, TypeModifier = typeModifier, diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 50ba2ba840..b5a9a294b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -35,11 +35,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = sampler; return true; } - else if (Compose(ref scanner, result, out var compose)) - { - parsed = compose; - return true; - } else if (Method(ref scanner, result, out var method)) { parsed = method; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 414e3ef889..a2846e48d5 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; using System; using System.Collections.Generic; using System.Globalization; @@ -128,8 +129,51 @@ public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, Shad } } - public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + public static object GetConstantValue(OpData data, NewSpirvBuffer buffer) { + int typeId = data.Op switch + { + Op.OpConstant or Op.OpSpecConstant => data.Memory.Span[1], + _ => throw new Exception("Unsupported context dependent number in instruction " + data.Op) + }; + var operand = data.Get("value"); + if (buffer.TryGetInstructionById(typeId, out var typeInst)) + { + if (typeInst.Op == Op.OpTypeInt) + { + var type = (OpTypeInt)typeInst; + return type switch + { + { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), + { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), + { Width: 64, Signedness: 0 } => operand.ToLiteral(), + { Width: 64, Signedness: 1 } => operand.ToLiteral(), + _ => throw new NotImplementedException("Unsupported int width " + type.Width), + }; + } + else if (typeInst.Op == Op.OpTypeFloat) + { + var type = new OpTypeFloat(typeInst); + return type switch + { + { Width: 16 } => operand.ToLiteral(), + { Width: 32 } => operand.ToLiteral(), + { Width: 64 } => operand.ToLiteral(), + _ => throw new NotImplementedException("Unsupported float width " + type.Width), + }; + } + else + throw new NotImplementedException("Unsupported context dependent number with type " + typeInst.Op); + } + else + throw new Exception("Cannot find type instruction for id " + typeId); + } + + public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) + { + if (parentBuffer == null) + throw new ArgumentNullException(nameof(parentBuffer)); + // Instantiate generics var copiedShader = new NewSpirvBuffer(); foreach (var i in shader) @@ -139,10 +183,10 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha } shader = copiedShader; - var generics = new List(); + // Collect ShaderName and OpSDSLGenericParameter + List generics = new(); var genericArgumentIndex = 0; - Dictionary idRemapping = new(); - HashSet targets = new(); + Dictionary> targets = new(); for (var index = 0; index < shader.Count; index++) { var i = shader[index]; @@ -152,27 +196,15 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha } else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is {} genericParameter) { - idRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericArgumentIndex]); - targets.Add(classSource.GenericArguments[genericArgumentIndex]); + generics.Add(genericParameter.ResultId); + if (!targets.TryGetValue(classSource.GenericArguments[genericArgumentIndex], out var genericParametersForThisArgument)) + targets.Add(classSource.GenericArguments[genericArgumentIndex], genericParametersForThisArgument = new()); + genericParametersForThisArgument.Add(genericParameter.ResultId); genericArgumentIndex++; - SetOpNop(i.Data.Memory.Span); - } - } - - // Remove OpName - for (var index = 0; index < shader.Count; index++) - { - var i = shader[index]; - if (i.Op == Op.OpName && (OpName)i is { } name) - { - if (idRemapping.ContainsKey(name.Target)) - SetOpNop(i.Data.Memory.Span); + SetOpNop(i.Data.Memory.Span); } } - if (idRemapping.Count > 0) - RemapIds(shader, 0, shader.Count, idRemapping); - // Try to resolve fully the new generic parameter values var resolvedParameters = new Dictionary(); if (parentBuffer != null) @@ -182,29 +214,33 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha var i = parentBuffer[index]; if (i.Op == Op.OpConstant) { - if (targets.Contains(i.Data.IdResult!.Value)) + if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) { - var value = new LiteralValue(i.Data.Memory.Span[3..]); - resolvedParameters.Add(i.Data.IdResult!.Value, value.Value.ToString()); + var value = GetConstantValue(i.Data, parentBuffer); // import constant in current shader - shader.Add(new OpConstant(i.Data.IdResultType!.Value, i.Data.IdResult!.Value, value.Value)); + foreach (var parameter in parameters) + { + resolvedParameters.Add(parameter, value.ToString()); + var i2 = new OpData(i.Data.Memory.Span); + i2.IdResult = parameter; + shader.Add(i2); + } } } else if (i.Op == Op.OpConstantStringSDSL && (OpConstantStringSDSL)i is { } constantString) { - if (targets.Contains(i.Data.IdResult!.Value)) + if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) { var value = constantString.LiteralString; - resolvedParameters.Add(i.Data.IdResult!.Value, value); + // This will be used later for resolving LinkType generics + foreach (var parameter in parameters) + resolvedParameters.Add(parameter, value); } } else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { - if (targets.Contains(genericParameter.ResultId)) - { - - } + // Unresolved parameter, keep as is } } } @@ -226,9 +262,9 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha // Fully resolved? - if (resolvedParameters.Count == targets.Count) + if (resolvedParameters.Count == generics.Count) { - var parameters = string.Join(',', classSource.GenericArguments.Select(x => resolvedParameters[x])); + var parameters = string.Join(',', generics.Select(x => resolvedParameters[x])); var className = classSource.ClassName + "<" + parameters + ">"; if (resolveStep == ResolveStep.Mix) @@ -242,10 +278,14 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha var i = shader[index]; if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) { - shaderDeclaration.ShaderName = classSource.ClassName + "<" + parameters + ">"; + shaderDeclaration.ShaderName = className; } } } + else if (resolveStep == ResolveStep.Mix) + { + throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); + } return shader; } @@ -256,46 +296,71 @@ public static void SetOpNop(Span words) words[1..].Clear(); } - private static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) + public static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) { for (var index = shaderStart; index < buffer.Count; index++) { var i = buffer[index]; - foreach (var op in i.Data) + RemapIds(idRemapping, i); + } + } + + public static void RemapIds(Dictionary idRemapping, OpDataIndex i) + { + foreach (var op in i.Data) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && idRemapping.TryGetValue(op.Words[0], out var to1)) { - if ((op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) - { - op.Words[0] = to1; - } + op.Words[0] = to1; + } - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) - { - op.Words[1] = to2; - } + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && idRemapping.TryGetValue(op.Words[1], out var to2)) + { + op.Words[1] = to2; } } } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + /// + /// Gets or load a shader, with generic instantiation (if requested). + /// + /// + /// The generics parameters should be in . + /// + /// + /// + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) { var shader = GetOrLoadShader(shaderLoader, classSource.ClassName); + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + if (classSource.GenericArguments.Length > 0) { + Console.WriteLine($"Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); + Console.WriteLine($"Instantiating from buffer generics {parentBuffer[0].Data}:"); + foreach (var i in parentBuffer) + { + if (i.Data.IdResult is int id && classSource.GenericArguments.Contains(id)) + { + Console.WriteLine($" - [{classSource.GenericArguments.IndexOf(id)}] %{id} => {i.Data}"); + } + } shader = InstantiateGenericShader(shader, classSource, resolveStep, parentBuffer); + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shader; } - private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) { if (!shaderLoader.LoadExternalBuffer(className, out var buffer)) throw new InvalidOperationException($"Could not load shader [{className}]"); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index df77901db6..bf9c298604 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -219,9 +219,15 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) var functionReturnTypeId = GetOrRegister(functionType.ReturnType); c.IdRef = Bound++; - Add(new OpSDSLImportFunction(functionReturnTypeId, c.IdRef, c.Id.Name, shader.ResultId, c.Id.FunctionFlags)); + Add(new OpSDSLImportFunction(c.IdRef, functionReturnTypeId, c.Id.Name, shader.ResultId, c.Id.FunctionFlags)); AddName(c.IdRef, c.Id.Name); } + else if (c.Id.Kind == SymbolKind.Variable) + { + + c.IdRef = Bound++; + Add(new OpSDSLImportVariable(c.IdRef, GetOrRegister(c.Type), c.Id.Name, shader.ResultId)); + } shaderSymbol.Components[index] = c; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index b7879d266b..bfcd57f97f 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -182,7 +182,6 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) } } - // Analyze streams foreach (var instruction in buffer) { @@ -408,7 +407,7 @@ public int FindMethodStart(NewSpirvBuffer buffer, int functionId) if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId) return index; } - throw new NotImplementedException(); + throw new InvalidOperationException($"Could not find start of method {functionId}"); } } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 396622e22e..09a4df3cb7 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -57,7 +57,8 @@ private static int CompareOperations(InstructionSortHelper x, InstructionSortHel // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool - || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction) + || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction + || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable) { comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[2..], y.Memory.Span[2..]); if (comparison != 0) From cfb57be38167ac56098ef971ef19c0cd80db1967 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 15:08:00 +0900 Subject: [PATCH 0531/1182] Compute offset in cbuffer --- src/Stride.Shaders/Core/SymbolTypes.cs | 7 ++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 ++++- .../Parsing/SDSL/AST/ShaderElements.cs | 17 ++++-- .../ShaderParsers/ShaderDataParsers.cs | 12 ++++ src/Stride.Shaders/Spirv/Building/Context.cs | 61 ++++++++++++++++--- 5 files changed, 97 insertions(+), 16 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 4481fab15e..678ee93328 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Text; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; @@ -106,7 +107,7 @@ public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"{BaseType}[{Size}]"; } -public record StructuredType(string Name, List<(string Name, SymbolType Type)> Members) : SymbolType() +public record StructuredType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : SymbolType() { public override string ToId() => Name; public override string ToString() => $"{Name}{{{string.Join(", ", Members.Select(x => $"{x.Type} {x.Name}"))}}}"; @@ -139,7 +140,7 @@ public int TryGetFieldIndex(string name) } -public sealed record StructType(string Name, List<(string Name, SymbolType Type)> Members) : StructuredType(Name, Members); +public sealed record StructType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members); public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"Buffer<{BaseType}, {Size}>"; @@ -234,7 +235,7 @@ public override string ToString() public sealed record StreamsSymbol : SymbolType; -public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type)> Members) : StructuredType(Name, Members); +public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members); public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 84c0691c8b..bdf2dcf67c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -95,13 +95,13 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { var structName = names[typeStructInstruction.ResultId]; var fieldsData = typeStructInstruction.Values; - var fields = new List<(string Name, SymbolType Type)>(); + var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); for (var index = 0; index < fieldsData.WordCount; index++) { var fieldData = fieldsData.Words[index]; var type = types[fieldData]; var name = memberNames[(typeStructInstruction.ResultId, index)]; - fields.Add((name, type)); + fields.Add((name, type, TypeModifier.None)); } types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); } @@ -149,8 +149,11 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } } } + + // Second pass (for processing when info from first pass is needed) foreach (var instruction in buffer) { + // ResultType might be declared after, so done in second pass if (instruction.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)instruction is { } importFunction) { if (types.TryGetValue(importFunction.Shader, out var type) && type is ShaderSymbol shaderSymbol) @@ -162,6 +165,15 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end shaderSymbol.Components.Add(symbol); } } + // Can be declared before OpTypeStruct, so done in second pass + else if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) + { + var structType = (StructType)types[memberDecorate.StructureType]; + if (memberDecorate.Decoration == Decoration.ColMajor) + structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.ColumnMajor }; + else if (memberDecorate.Decoration == Decoration.RowMajor) + structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.RowMajor }; + } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 1b1d25cdf8..40b0ce0561 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -138,13 +138,13 @@ public abstract class ShaderBuffer(string name, TextLocation info) : ShaderEleme public override void ProcessSymbol(SymbolTable table) { - var fields = new List<(string Name, SymbolType Type)>(); + var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); foreach (var smem in Members) { smem.Type = smem.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); - fields.Add((smem.Name, smem.Type)); + fields.Add((smem.Name, smem.Type, smem.TypeModifier)); } Type = new ConstantBufferSymbol(Name, fields); @@ -165,7 +165,11 @@ public class ShaderStructMember(TypeName typename, Identifier identifier, TextLo { public TypeName TypeName { get; set; } = typename; public SymbolType? Type { get; set; } + + public TypeModifier TypeModifier { get; set; } + public Identifier Name { get; set; } = identifier; + public List Attributes { get; set; } = []; public override string ToString() @@ -183,13 +187,13 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public override void ProcessSymbol(SymbolTable table) { - var fields = new List<(string Name, SymbolType Type)>(); + var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); foreach (var smem in Members) { smem.Type = smem.TypeName.ResolveType(table); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); - fields.Add((smem.Name, smem.Type)); + fields.Add((smem.Name, smem.Type, smem.TypeModifier)); } Type = new StructType(TypeName.ToString() ?? "", fields); @@ -262,6 +266,11 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, index); table.CurrentFrame.Add(member.Name, symbol); + if (member.TypeModifier != TypeModifier.ColumnMajor) + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); + else if (member.TypeModifier != TypeModifier.RowMajor) + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + if (member.Attributes != null && member.Attributes.Count > 0) { var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index f7319cdf90..0476a10a73 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -205,6 +205,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes); + + var hasTypeModifier = + Tokens.AnyOf( + ["const", "row_major", "column_major"], + ref scanner, + out var typemodifier, + advance: true) + && Parsers.Spaces1(ref scanner, result, out _) + ; + if ( Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _) @@ -215,6 +225,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new ShaderStructMember(typename, identifier, scanner[position..scanner.Position]); if (hasAttributes) parsed.Attributes = attributes.Attributes; + if (hasTypeModifier) + parsed.TypeModifier = typemodifier.ToTypeModifier(); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index bf9c298604..946ee22ec1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; +using System; using System.Diagnostics.CodeAnalysis; using System.Numerics; using static Stride.Shaders.Spirv.Specification; @@ -239,16 +240,53 @@ private int RegisterCBuffer(ConstantBufferSymbol cb) var result = RegisterStructuredType($"type.{cb.ToId()}", cb); Buffer.Add(new OpDecorate(result, Decoration.Block)); + int constantBufferOffset = 0; for (var index = 0; index < cb.Members.Count; index++) { - if (index > 0) - throw new NotImplementedException("Offset"); - Buffer.Add(new OpMemberDecorate(result, index, ParameterizedFlags.DecorationOffset(0))); + // Properly compute size and offset according to DirectX rules + var member = cb.Members[index]; + var memberSize = ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); + + Buffer.Add(new OpMemberDecorate(result, index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); } return result; } + public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, TypeModifier typeModifier) + => (symbol) switch + { + ScalarType { TypeName: "sbyte" or "byte" } => (1, 4), + ScalarType { TypeName: "short" or "ushort" } => (2, 4), + ScalarType { TypeName: "int" or "uint" or "float" } => (4, 4), + ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 4), + VectorType v => (TypeSizeInBuffer(v.BaseType, typeModifier).Size * v.Size, 4), + // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => (TypeSizeInBuffer(m.BaseType, typeModifier).Size * ((4 * m.Columns - 1) + m.Rows), 4), + MatrixType m when typeModifier == TypeModifier.RowMajor => (TypeSizeInBuffer(m.BaseType, typeModifier).Size * ((4 * m.Rows - 1) + m.Columns), 4), + // Round up to 16 bytes (size of float4) + ArrayType a => ((TypeSizeInBuffer(a.BaseType, typeModifier).Size + 15) / 16 * 16 * a.Size, 16), + // TODO: StructureType + }; + + // + // Computes the size of a member type, including its alignment and array size. + // It does so recursively for structs, and handles different parameter classes. + // + static int ComputeCBufferOffset(SymbolType type, TypeModifier typeModifier, ref int constantBufferOffset) + { + (var size, var alignment) = TypeSizeInBuffer(type, typeModifier); + + // Align to float4 if it is bigger than leftover space in current float4 + if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16) + alignment = 16; + + // Align offset and store it as member offset + constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment; + + return size; + } + int RegisterStructuredType(string name, StructuredType structSymbol) { Span types = stackalloc int[structSymbol.Members.Count]; @@ -256,11 +294,20 @@ int RegisterStructuredType(string name, StructuredType structSymbol) types[index] = GetOrRegister(structSymbol.Members[index].Type); var result = Buffer.Add(new OpTypeStruct(Bound++, [.. types])); - var id = result.IdResult; - AddName(id ?? -1, name); + var id = result.IdResult ?? throw new InvalidOperationException(); + AddName(id, name); for (var index = 0; index < structSymbol.Members.Count; index++) - AddMemberName(id ?? -1, index, structSymbol.Members[index].Name); - return id ?? -1; + { + var member = structSymbol.Members[index]; + AddMemberName(id, index, member.Name); + + if (member.TypeModifier != TypeModifier.ColumnMajor) + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); + else if (member.TypeModifier != TypeModifier.RowMajor) + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + + } + return id; } From ba941817a243cabbac0c03ede4888bbf82728328 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 17:48:42 +0900 Subject: [PATCH 0532/1182] Properly display parse errors --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 745102c6e4..869a5447aa 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -21,7 +21,7 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf lastBuffer = null; if (parsed.Errors.Count > 0) { - throw new Exception("Some parse errors"); + throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, parsed.Errors)}"); } if(parsed.AST is ShaderFile sf) { From d2ae0eb9d6fa2918c774b15d1818a3848f8b2b0f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 17:59:20 +0900 Subject: [PATCH 0533/1182] struct/cbuffer are imported only once and unified ImportType --- .../Extensions/spirv.sdsl.grammar-ext.json | 33 ++++++------ src/Stride.Shaders/Core/SymbolTypes.cs | 5 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 51 +++++++++---------- .../Parsing/SDSL/AST/ShaderElements.cs | 8 +++ src/Stride.Shaders/Spirv/Building/Context.cs | 37 +++++++++++--- 5 files changed, 80 insertions(+), 54 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 8465bff541..150a5d5d8d 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -69,10 +69,6 @@ { "kind": "IdResult" }, - { - "kind": "ImportType", - "name": "type" - }, { "kind": "LiteralString", "name": "shaderName" @@ -120,6 +116,21 @@ } ] }, + { + "opname": "OpSDSLImportStruct", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" }, + { + "kind": "LiteralString", + "name": "structName" + }, + { + "kind": "IdRef", + "name": "shader" + } + ] + }, { "opname": "OpMemberAccessSDSL", "class": "Miscellaneous", @@ -302,20 +313,6 @@ } ] }, - { - "category": "ValueEnum", - "kind": "ImportType", - "enumerants": [ - { - "enumerant": "External", - "value": 0 - }, - { - "enumerant": "Inherit", - "value": 1 - } - ] - }, { "category": "ValueEnum", "kind": "GenericParameterKindSDSL", diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 678ee93328..bcf41a847e 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -239,8 +239,11 @@ public sealed record ConstantBufferSymbol(string Name, List<(string Name, Symbol public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public sealed record ShaderSymbol(string Name, int[] GenericArguments, List Components) : SymbolType +public sealed record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { + public List Components { get; init; } = []; + public List StructTypes { get; init; } = []; + public string ToClassName() { if (GenericArguments.Length == 0) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index bdf2dcf67c..24f4d02014 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -143,16 +143,15 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { - if (importShader.Type == ImportType.External) - { - types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray(), [])); - } + types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray())); } } // Second pass (for processing when info from first pass is needed) - foreach (var instruction in buffer) + for (var i = start; i < end; i++) { + var instruction = buffer[i]; + // ResultType might be declared after, so done in second pass if (instruction.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)instruction is { } importFunction) { @@ -182,6 +181,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); var symbols = new List(); + var structTypes = new List(); for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; @@ -210,13 +210,22 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI symbols.Add(new(sid, functionType, functionInstruction.ResultId)); } + if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) + { + structTypes.Add((StructType)types[typeStructInstruction.ResultId]); + } + if (instruction.Op == Op.OpSDSLGenericParameter) { throw new NotImplementedException(); } } - var shaderType = new ShaderSymbol(classSource.ClassName, classSource.GenericArguments, symbols); + var shaderType = new ShaderSymbol(classSource.ClassName, classSource.GenericArguments) + { + Components = symbols, + StructTypes = structTypes, + }; return shaderType; } @@ -331,7 +340,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) } } - var currentShader = new ShaderSymbol(Name, openGenerics, []); + var currentShader = new ShaderSymbol(Name, openGenerics); RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; @@ -345,6 +354,8 @@ public void Compile(CompilerUnit compiler, SymbolTable table) Inherit(table, context, shaderType, true); } + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) @@ -365,35 +376,19 @@ public void Compile(CompilerUnit compiler, SymbolTable table) public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol shaderType, bool addToRoot) { - // Import types and variables/functions - var shaderId = context.Bound++; - context.FluentAdd(new OpSDSLImportShader(shaderId, ImportType.Inherit, new(shaderType.Name), new(shaderType.GenericArguments.AsSpan())), out var shader); - context.AddName(shaderId, shaderType.Name); + var shaderId = context.GetOrRegister(shaderType); - for (int i = 0; i < shaderType.Components.Count; i++) + foreach (var c in shaderType.Components) { - Symbol c = shaderType.Components[i]; if (c.Id.Kind == SymbolKind.Variable) { - var variableTypeId = context.GetOrRegister(c.Type); - context.FluentAdd(new OpSDSLImportVariable(context.Bound, variableTypeId, c.Id.Name, shader.ResultId), out var variable); - context.AddName(context.Bound, c.Id.Name); - context.Bound++; - shaderType.Components[i] = c = c with { IdRef = variable.ResultId, ImplicitThis = true }; if (addToRoot) - table.CurrentFrame.Add(c.Id.Name, c); + table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThis = true }); } else if (c.Id.Kind == SymbolKind.Method) { - var functionType = (FunctionType)c.Type; - - var functionReturnTypeId = context.GetOrRegister(functionType.ReturnType); - context.FluentAdd(new OpSDSLImportFunction(context.Bound, functionReturnTypeId, c.Id.Name, shader.ResultId, c.Id.FunctionFlags), out var function); - context.AddName(context.Bound, c.Id.Name); - context.Bound++; - shaderType.Components[i] = c = c with { IdRef = function.ResultId, ImplicitThis = true }; if (addToRoot) - table.CurrentFrame.Add(c.Id.Name, c); + table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThis = true }); } } @@ -404,7 +399,7 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol } // Mark inherit - context.Add(new OpSDSLMixinInherit(shader.ResultId)); + context.Add(new OpSDSLMixinInherit(shaderId)); } public static ShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 40b0ce0561..32449f022d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -200,6 +200,13 @@ public override void ProcessSymbol(SymbolTable table) table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); } + public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + var (builder, context) = compiler; + var structType = (StructType)Type; + context.DeclareStructuredType(structType.ToId(), structType); + } + public override string ToString() { return $"struct {TypeName} ({string.Join(", ", Members)})"; @@ -252,6 +259,7 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; + context.DeclareCBuffer((ConstantBufferSymbol)Type); var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 946ee22ec1..1fd8f711be 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -7,6 +7,7 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Numerics; +using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; @@ -188,7 +189,6 @@ public int GetOrRegister(SymbolType? type) MatrixType m => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, ArrayType a => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), - ConstantBufferSymbol cb => RegisterCBuffer(cb), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), ShaderSymbol s => RegisterShaderType(s), @@ -209,11 +209,20 @@ public int GetOrRegister(SymbolType? type) private int RegisterShaderType(ShaderSymbol shaderSymbol) { - FluentAdd(new OpSDSLImportShader(Bound++, ImportType.External, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); + FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); AddName(shader.ResultId, shaderSymbol.Name); - for (var index = 0; index < shaderSymbol.Components.Count; index++) + + // Import types and variables/functions + //foreach (var structType in shaderType.StructTypes) + //{ + // context.FluentAdd(new OpSDSLImportStruct(context.Bound, structType.Name, shaderId), out var @struct); + // context.AddName(context.Bound, structType.Name); + // context.Bound++; + //} + + var components = CollectionsMarshal.AsSpan(shaderSymbol.Components); + foreach (ref var c in components) { - var c = shaderSymbol.Components[index]; if (c.Id.Kind == SymbolKind.Method) { var functionType = (FunctionType)c.Type; @@ -225,19 +234,23 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) } else if (c.Id.Kind == SymbolKind.Variable) { + // Currently, we ignore cbuffer + // TOOD: review that + if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is StructType) + continue; c.IdRef = Bound++; Add(new OpSDSLImportVariable(c.IdRef, GetOrRegister(c.Type), c.Id.Name, shader.ResultId)); + AddName(c.IdRef, c.Id.Name); } - shaderSymbol.Components[index] = c; } return shader.ResultId; } - private int RegisterCBuffer(ConstantBufferSymbol cb) + public int DeclareCBuffer(ConstantBufferSymbol cb) { - var result = RegisterStructuredType($"type.{cb.ToId()}", cb); + var result = DeclareStructuredType($"type.{cb.ToId()}", cb); Buffer.Add(new OpDecorate(result, Decoration.Block)); int constantBufferOffset = 0; @@ -250,6 +263,8 @@ private int RegisterCBuffer(ConstantBufferSymbol cb) Buffer.Add(new OpMemberDecorate(result, index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); } + Types[cb] = result; + return result; } @@ -288,6 +303,11 @@ static int ComputeCBufferOffset(SymbolType type, TypeModifier typeModifier, ref } int RegisterStructuredType(string name, StructuredType structSymbol) + { + throw new InvalidOperationException(); + } + + public int DeclareStructuredType(string name, StructuredType structSymbol) { Span types = stackalloc int[structSymbol.Members.Count]; for (var index = 0; index < structSymbol.Members.Count; index++) @@ -307,6 +327,9 @@ int RegisterStructuredType(string name, StructuredType structSymbol) Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); } + + Types[structSymbol] = id; + return id; } From c1ce66035240533902f258cf85842e3254cd0e4b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 18:48:58 +0900 Subject: [PATCH 0534/1182] Fix OpAccessChain --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 4011505949..edf5cc5371 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -264,7 +264,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) { var resultType = context.GetOrRegister(currentValueType); var test = new LiteralArray(indexes); - var accessChain = builder.Insert(new OpAccessChain(context.Bound++, resultType, result.Id, [.. indexes.Slice(lastCreatedChainStart, currentIndex - lastCreatedChainStart)])); + var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. indexes.Slice(lastCreatedChainStart, currentIndex - lastCreatedChainStart)])); result = new SpirvValue(accessChain.ResultId, resultType); } @@ -295,7 +295,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) var inst = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(matchingComponent.Type), context.Bound++, result.Id, matchingComponent.IdRef)); result = new(inst.ResultId, inst.ResultType); break; - case (PointerType { BaseType: StructType s }, Identifier field): + case (PointerType { BaseType: StructType s } p, Identifier field): var index = s.TryGetFieldIndex(field); if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); @@ -303,6 +303,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); indexLiteral.Compile(table, shader, compiler); indexes[i] = context.CreateConstant(indexLiteral).Id; + accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); break; // TODO: Swizzle, etc. default: From c2f2de71f04f9718d549b96419b73892f064da89 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 18:49:13 +0900 Subject: [PATCH 0535/1182] Fix: Function variables were added twice --- src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index bb42aacb44..85d6176e8d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -156,8 +156,6 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit var d = Variables[index]; var variable = context.Bound++; - builder.Insert(new OpVariable(registeredType, variable, Specification.StorageClass.Function, null)); - builder.AddFunctionVariable(registeredType, variable); context.AddName(variable, d.Variable); From e2ec30a5f1d5ac92d0357085312748977a0ad8cf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 2 Dec 2025 19:37:32 +0900 Subject: [PATCH 0536/1182] Further progress on struct import --- .../SDSL/ShaderMixer.ShaderInfo.cs | 6 ++++ .../SDSL/ShaderMixer.cs | 23 +++++++++++++ src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 32 ++++++++++--------- src/Stride.Shaders/Spirv/Building/Context.cs | 17 ++++++---- .../Spirv/Processing/TypeDuplicatesRemover.cs | 3 +- 6 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 7952940d23..88ec0f4174 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -35,6 +35,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public Dictionary Names { get; } = new(); public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); + public Dictionary StructTypes { get; } = new(); public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } @@ -79,6 +80,11 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader removedIds.Add(typePointer.ResultId); } } + else if (i.Data.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) + { + var structName = shaderInfo.Names[typeStruct]; + shaderInfo!.StructTypes.Add(structName, typeStruct.ResultId); + } } // Second pass to remove OpName diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 0f81730faa..83a088cf74 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -107,6 +107,9 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, //Console.WriteLine("Done type remapping"); Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + // Import struct types + ImportStructTypes(globalContext, buffer, mixinNode); + // Build names and types mappings ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); @@ -340,6 +343,26 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } } + private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer buffer, MixinNode mixinNode) + { + var idRemapping = new Dictionary(); + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + if (i.Data.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)i is { } importStruct) + { + var shaderName = mixinNode.ExternalShaders[importStruct.Shader]; + var shader = mixinNode.ShadersByName[shaderName]; + var structId = shader.StructTypes[importStruct.StructName]; + idRemapping.Add(importStruct.ResultId, structId); + SetOpNop(i.Data.Memory.Span); + } + } + + SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); + } + private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvBuffer temp, MixinNode mixinNode) { var memberAccesses = new Dictionary(); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index bcf41a847e..3f1631e564 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -242,7 +242,7 @@ public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Typ public sealed record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { public List Components { get; init; } = []; - public List StructTypes { get; init; } = []; + public List<(StructType Type, int ImportedId)> StructTypes { get; init; } = []; public string ToClassName() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 24f4d02014..8af2b66e7e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -141,10 +141,16 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { types.Add(typeSampler.ResultId, new SamplerType()); } + // Unresolved content + // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray())); } + else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) + { + types.Add(importStruct.ResultId, new StructType(importStruct.StructName, [])); + } } // Second pass (for processing when info from first pass is needed) @@ -152,20 +158,8 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { var instruction = buffer[i]; - // ResultType might be declared after, so done in second pass - if (instruction.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)instruction is { } importFunction) - { - if (types.TryGetValue(importFunction.Shader, out var type) && type is ShaderSymbol shaderSymbol) - { - var returnType = types[importFunction.ResultType]; - var symbol = new Symbol(new(importFunction.FunctionName, SymbolKind.Method, FunctionFlags: importFunction.Flags), returnType, importFunction.ResultId); - // TODO: review if really necessary? - // (external functions are resolved differently) - shaderSymbol.Components.Add(symbol); - } - } // Can be declared before OpTypeStruct, so done in second pass - else if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) + if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) { var structType = (StructType)types[memberDecorate.StructureType]; if (memberDecorate.Decoration == Decoration.ColMajor) @@ -181,7 +175,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); var symbols = new List(); - var structTypes = new List(); + var structTypes = new List<(StructType Type, int ImportedId)>(); for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; @@ -212,7 +206,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { - structTypes.Add((StructType)types[typeStructInstruction.ResultId]); + structTypes.Add(((StructType)types[typeStructInstruction.ResultId], -1)); } if (instruction.Op == Op.OpSDSLGenericParameter) @@ -378,6 +372,14 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol { var shaderId = context.GetOrRegister(shaderType); + foreach (var structType in shaderType.StructTypes) + { + // Add the struct like if it was part of our shader (but using the imported id) + context.Types.Add(structType.Type, structType.ImportedId); + context.ReverseTypes.Add(structType.ImportedId, structType.Type); + table.DeclaredTypes.TryAdd(structType.Type.Name, structType.Type); + } + foreach (var c in shaderType.Components) { if (c.Id.Kind == SymbolKind.Variable) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 1fd8f711be..11d03e18ca 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -212,14 +212,17 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); AddName(shader.ResultId, shaderSymbol.Name); - // Import types and variables/functions - //foreach (var structType in shaderType.StructTypes) - //{ - // context.FluentAdd(new OpSDSLImportStruct(context.Bound, structType.Name, shaderId), out var @struct); - // context.AddName(context.Bound, structType.Name); - // context.Bound++; - //} + // Import struct + var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); + foreach (ref var structType in structTypes) + { + FluentAdd(new OpSDSLImportStruct(Bound++, structType.Type.Name, shader.ResultId), out var @struct); + AddName(@struct.ResultId, structType.Type.Name); + // Fill the ID + structType.ImportedId = @struct.ResultId; + } + // Import variables/functions var components = CollectionsMarshal.AsSpan(shaderSymbol.Components); foreach (ref var c in components) { diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 09a4df3cb7..7b1aff0b71 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -58,7 +58,7 @@ private static int CompareOperations(InstructionSortHelper x, InstructionSortHel // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction - || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable) + || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[2..], y.Memory.Span[2..]); if (comparison != 0) @@ -95,6 +95,7 @@ public readonly void Apply(NewSpirvBuffer buffer) ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true); ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportShader, Op.OpSDSLImportShader, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportStruct, Op.OpSDSLImportStruct, true); // Covers OpSDSLImportFunction and OpSDSLImportVariable at the same time ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportFunction, Op.OpSDSLImportVariable, true); From e46c0da23ffc290600a61b3269667c047fa0242d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 09:58:15 +0900 Subject: [PATCH 0537/1182] Constants: unified and simplified their declaration --- .../Parsing/SDSL/AST/Expression.cs | 8 +-- .../Parsing/SDSL/AST/Literals.cs | 56 ++---------------- .../Spirv/Building/Builder.Class.cs | 8 +++ .../Spirv/Building/Builder.Expressions.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 58 ++++++++++++++++++- 5 files changed, 73 insertions(+), 61 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index edf5cc5371..241cc580cc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -143,9 +143,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil Type = Expression.Type; if (Expression.Type is PointerType pointerType && pointerType.BaseType is ScalarType { TypeName: "int" or "long" }) { - var indexLiteral = new IntegerLiteral(new(32, false, true), 1, new()); - indexLiteral.Compile(table, shader, compiler); - var constant1 = context.CreateConstant(indexLiteral); + var constant1 = context.CompileConstant(1); var result = builder.BinaryOperation(context, expression, Operator.Plus, constant1); builder.Insert(new OpStore(expression.Id, result.Id, null)); @@ -300,9 +298,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - var indexLiteral = new IntegerLiteral(new(32, false, true), index, new()); - indexLiteral.Compile(table, shader, compiler); - indexes[i] = context.CreateConstant(indexLiteral).Id; + indexes[i] = context.CompileConstant(index).Id; accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); break; // TODO: Swizzle, etc. diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 36d5d5c975..44de7549ee 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -68,34 +68,7 @@ public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : Numb { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Type = Suffix switch - { - { Signed: true, Size: 8 } => ScalarType.From("sbyte"), - { Signed: true, Size: 16 } => ScalarType.From("short"), - { Signed: true, Size: 32 } => ScalarType.From("int"), - { Signed: true, Size: 64 } => ScalarType.From("long"), - { Signed: false, Size: 8 } => ScalarType.From("byte"), - { Signed: false, Size: 16 } => ScalarType.From("ushort"), - { Signed: false, Size: 32 } => ScalarType.From("uint"), - { Signed: false, Size: 64 } => ScalarType.From("ulong"), - _ => throw new NotImplementedException("Unsupported integer suffix") - }; - - - // _ = (Type, Suffix) switch - // { - // (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), - // (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), - // _ => throw new NotImplementedException("") - // }; - - var i = (Type, Suffix) switch - { - (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, LongValue)), - (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, IntValue)), - _ => throw new NotImplementedException("") - }; - return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); + return compiler.Context.CompileConstantLiteral(this); } } @@ -106,20 +79,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Type = Suffix.Size switch - { - 16 => ScalarType.From("half"), - 32 => ScalarType.From("float"), - 64 => ScalarType.From("double"), - _ => throw new NotImplementedException("Unsupported float") - }; - var i = (Type, Suffix) switch - { - (ScalarType, { Size: > 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, DoubleValue)), - (ScalarType, { Size: <= 32 }) => compiler.Context.Add(new OpConstant(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++, (float)DoubleValue)), - _ => throw new NotImplementedException("") - }; - return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); + return compiler.Context.CompileConstantLiteral(this); } } @@ -136,12 +96,7 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - var i = Value switch - { - true => compiler.Context.Add(new OpConstantTrue(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)), - false => compiler.Context.Add(new OpConstantFalse(compiler.Context.GetOrRegister(Type), compiler.Context.Bound++)) - }; - return new SpirvValue(i.IdResult ?? -1, i.IdResultType ?? -1, null); + return compiler.Context.CompileConstantLiteral(this); } } @@ -161,6 +116,7 @@ public bool IsConstant() public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + // TODO: avoid duplicates var (builder, context) = compiler; Span values = stackalloc int[Values.Count]; int tmp = 0; @@ -258,9 +214,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil if (symbol.AccessChain is int accessChainIndex) { - var indexLiteral = new IntegerLiteral(new(32, false, true), accessChainIndex, new()); - indexLiteral.Compile(table, shader, compiler); - var index = context.CreateConstant(indexLiteral).Id; + var index = context.CompileConstant(accessChainIndex).Id; result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); } else if (symbol.ImplicitThis is true) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index a2846e48d5..a922346172 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -129,6 +129,14 @@ public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, Shad } } + public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) + { + if (!buffer.TryGetInstructionById(constantId, out var constant)) + throw new Exception("Cannot find constant instruction for id " + constantId); + + return GetConstantValue(constant.Data, buffer); + } + public static object GetConstantValue(OpData data, NewSpirvBuffer buffer) { int typeId = data.Op switch diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 7077859289..47dcec9050 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -310,8 +310,8 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CreateConstant(new IntegerLiteral(new(32, false, true), 0, new())).Id)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CreateConstant(new FloatLiteral(new(32, true, true), 0.0, null, new())).Id)), + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), + (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), // Bitcast (int=>uint or uint=>int) (ScalarType { TypeName: "int" }, ScalarType { TypeName: "uint" }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 11d03e18ca..3bbabe9f35 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -1,5 +1,6 @@ using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; +using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -360,7 +361,7 @@ int RegisterPointerType(PointerType pointerType) public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size) { - var value = CreateConstant(literal); + var value = CompileConstantLiteral(literal); if (size == 1) return value; @@ -374,7 +375,30 @@ public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size return new(instruction); } - public SpirvValue CreateConstant(Literal literal) + public Literal CreateLiteral(object value, TextLocation location = default) + { + return value switch + { + bool i => new BoolLiteral(i, location), + sbyte i => new IntegerLiteral(new(8, false, true), i, location), + byte i => new IntegerLiteral(new(8, false, false), i, location), + short i => new IntegerLiteral(new(16, false, true), i, location), + ushort i => new IntegerLiteral(new(16, false, false), i, location), + int i => new IntegerLiteral(new(32, false, true), i, location), + uint i => new IntegerLiteral(new(32, false, false), i, location), + long i => new IntegerLiteral(new(64, false, true), i, location), + ulong i => new IntegerLiteral(new(64, false, false), (long)i, location), + float i => new FloatLiteral(new(32, true, true), i, null, location), + double i => new FloatLiteral(new(64, true, true), i, null, location), + }; + } + + public SpirvValue CompileConstant(object value, TextLocation location = default) + { + return CompileConstantLiteral(CreateLiteral(value, location)); + } + + public SpirvValue CompileConstantLiteral(Literal literal) { object literalValue = literal switch { @@ -391,8 +415,36 @@ public SpirvValue CreateConstant(Literal literal) }, }; + if (literal.Type == null) + { + literal.Type = literal switch + { + BoolLiteral lit => ScalarType.From("bool"), + IntegerLiteral lit => lit.Suffix switch + { + { Signed: true, Size: 8 } => ScalarType.From("sbyte"), + { Signed: true, Size: 16 } => ScalarType.From("short"), + { Signed: true, Size: 32 } => ScalarType.From("int"), + { Signed: true, Size: 64 } => ScalarType.From("long"), + { Signed: false, Size: 8 } => ScalarType.From("byte"), + { Signed: false, Size: 16 } => ScalarType.From("ushort"), + { Signed: false, Size: 32 } => ScalarType.From("uint"), + { Signed: false, Size: 64 } => ScalarType.From("ulong"), + _ => throw new NotImplementedException("Unsupported integer suffix") + }, + FloatLiteral lit => lit.Suffix.Size switch + { + 16 => ScalarType.From("half"), + 32 => ScalarType.From("float"), + 64 => ScalarType.From("double"), + _ => throw new NotImplementedException("Unsupported float") + }, + }; + } + if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) return result; + var instruction = literal switch { BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), @@ -405,6 +457,8 @@ public SpirvValue CreateConstant(Literal literal) { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), + { Size: <= 64, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), + { Size: <= 64, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), _ => throw new NotImplementedException() }, FloatLiteral lit => lit.Suffix.Size switch From 11ed8443176d163d04838457882e3af9480e11c3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 12:16:00 +0900 Subject: [PATCH 0538/1182] LiteralArray: use a single buffer so that changes are reflected easily --- .../Literals/LiteralArray.cs | 61 +------------------ .../Literals/LiteralValue.cs | 2 +- src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 4 +- 3 files changed, 6 insertions(+), 61 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index f8153f8f4b..290e901372 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -9,14 +9,14 @@ namespace Stride.Shaders.Spirv.Core; public static class LiteralArrayHelper { - public static LiteralArray Create(ReadOnlySpan elements) + public static LiteralArray Create(ReadOnlySpan elements) where T : struct { return new LiteralArray(elements); } } [CollectionBuilder(typeof(LiteralArrayHelper), "Create")] -public struct LiteralArray : ISpirvElement, IFromSpirv>, IDisposable +public struct LiteralArray : ISpirvElement, IFromSpirv>, IDisposable where T : struct { static LiteralArray() { @@ -34,44 +34,36 @@ or LiteralArray or LiteralArray or LiteralArray or LiteralArray - or LiteralArray or LiteralArray or LiteralArray<(int, int)> => true, _ => throw new Exception("Type not supported in SPIR-V") }; } - MemoryOwner Memory { get; set { field?.Dispose(); field = value; } } - public readonly ReadOnlySpan Words => Memory is not null ? Memory.Span : []; public MemoryOwner Elements { get; set { field?.Dispose(); field = value; } } public readonly int WordCount => Elements?.Length ?? -1; + public readonly ReadOnlySpan Words => Elements is not null ? MemoryMarshal.Cast(Elements.Span) : []; public LiteralArray() { Elements = MemoryOwner.Empty; - Memory = MemoryOwner.Empty; } public LiteralArray(MemoryOwner elements) { Elements = elements; - Memory = MemoryOwner.Empty; - UpdateWords(); } public LiteralArray(ReadOnlySpan elements) { Elements = MemoryOwner.Allocate(elements.Length); elements.CopyTo(Elements.Span); - Memory = MemoryOwner.Empty; - UpdateWords(); } public void Assign(LiteralArray owner) { Elements?.Dispose(); Elements = owner.Elements; - UpdateWords(); } public void Assign(MemoryOwner owner) { @@ -95,53 +87,6 @@ public void Assign(Span span) public readonly void Dispose() => Elements.Dispose(); - void UpdateWords() - { - Memory?.Dispose(); - var memorySize = Elements.Length > 0 && Elements.Span[0] is long or ulong or double or ValueTuple ? Elements.Length * 2 : Elements.Length; - Memory = MemoryOwner.Allocate(memorySize, AllocationMode.Clear); - var pos = 0; - foreach (var element in Elements.Span) - { - if (element is bool or byte or sbyte or short or ushort or int or uint or float) - { - Memory.Span[pos++] = element switch - { - bool b => b ? 1 : 0, - byte b => b, - sbyte sb => sb, - short s => s, - ushort us => us, - int i => i, - uint ui => (int)ui, - float f => BitConverter.SingleToInt32Bits(f), - _ => throw new NotImplementedException() - }; - } - else if (element is long or ulong or double or ValueTuple) - { - Memory.Span[pos++] = element switch - { - long l => (int)(l >> 32), - ulong ul => (int)(ul >> 32), - double d => (int)(BitConverter.DoubleToInt64Bits(d) >> 32), - ValueTuple vt => vt.Item1, - _ => throw new NotImplementedException() - }; - Memory.Span[pos++] = element switch - { - long l => (int)(l & 0xFFFFFFFF), - ulong ul => (int)(ul & 0xFFFFFFFF), - double d => (int)(BitConverter.DoubleToInt64Bits(d) & 0xFFFFFFFF), - ValueTuple vt => vt.Item2, - _ => throw new NotImplementedException() - }; - } - else throw new NotImplementedException(); - } - - } - public readonly Span.Enumerator GetEnumerator() => Elements.Span.GetEnumerator(); public static LiteralArray From(Span words) diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index 6b6022a452..dc8e2cad7a 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -284,7 +284,7 @@ public void Add(LiteralValue item) item.Words.CopyTo(Memory.Span[Length..]); Length += item.WordCount; } - public void Add(LiteralArray item) + public void Add(LiteralArray item) where T : struct { Expand(item.WordCount); item.Words.CopyTo(Memory.Span[Length..]); diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index 5f7516b53c..e04fbfa3b8 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -44,7 +44,7 @@ public readonly T ToLiteral() using var lit = new LiteralValue(Words); return lit.Value; } - public readonly LiteralArray ToLiteralArray() + public readonly LiteralArray ToLiteralArray() where T : struct => LiteralArray.From(Words); public readonly bool TryToLiteral(out LiteralValue literal) @@ -62,7 +62,7 @@ public readonly bool TryToLiteral(out LiteralValue literal) }; return true; } - public readonly bool TryToArray(out LiteralArray literal) + public readonly bool TryToArray(out LiteralArray literal) where T : struct { literal = default; (bool r, literal) = (literal, Kind) switch From bc43c40d205b2c6d67b494b107a28a4d4afb7a04 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 14:31:46 +0900 Subject: [PATCH 0539/1182] Allow to use Stride dll or a local copy of some files for Reflection and ShaderSource --- src/Directory.Build.props | 5 + .../Stride.Graphics.RHI.csproj | 4 + .../SDSL/EffectEvaluator.cs | 6 +- .../SpirvTranslator.cs | 2 + .../Stride.Shaders.Compilers.csproj | 7 + src/Stride.Shaders.Experiments/Program.cs | 1 + .../Stride.Shaders.Experiments.csproj | 5 +- .../Stride.Shaders.Parsing.Tests.csproj | 3 + .../Parsing/SDSL/ShaderSource.cs | 123 -- src/Stride.Shaders/Stride.Shaders.csproj | 9 + .../Core/DataContractAttribute.cs | 44 + .../Core/DataMemberAttribute.cs | 117 ++ .../Core/DataMemberIgnoreAttribute.cs | 9 + .../StrideImported/Core/DataMemberMode.cs | 35 + .../StrideImported/Core/ParameterKey.cs | 126 ++ .../StrideImported/Core/SortedList.cs | 1159 +++++++++++++++++ .../Core/StrideCoreExtensions.cs | 47 + .../Graphics/CompareFunction.cs | 59 + .../Graphics/SamplerStateDescription.cs | 232 ++++ .../Graphics/TextureAddressMode.cs | 46 + .../StrideImported/Graphics/TextureFilter.cs | 172 +++ .../StrideImported/Mathematics/Color4.cs | 628 +++++++++ .../ShadersReflection/ConstantBufferType.cs | 28 + .../EffectConstantBufferDescription.cs | 47 + .../ShadersReflection/EffectParameterClass.cs | 87 ++ .../EffectParameterKeyInfo.cs | 28 + .../ShadersReflection/EffectParameterType.cs | 203 +++ .../ShadersReflection/EffectReflection.cs | 64 + .../EffectResourceBindingDescription.cs | 51 + .../EffectSamplerStateBinding.cs | 38 + .../EffectTypeDescription.cs | 38 + .../EffectTypeMemberDescription.cs | 30 + .../EffectValueDescription.cs | 30 + .../ShaderInputAttributeDescription.cs | 15 + .../ShadersReflection/ShaderStage.cs | 48 + .../ShaderStreamOutputDeclarationEntry.cs | 43 + .../ShadersSource/ShaderArraySource.cs | 99 ++ .../ShadersSource/ShaderClassCode.cs | 64 + .../ShadersSource/ShaderClassSource.cs | 122 ++ .../ShadersSource/ShaderMacro.cs | 62 + .../ShadersSource/ShaderMixinSource.cs | 245 ++++ .../ShadersSource/ShaderSource.cs | 37 + .../ShadersSource/ShaderSourceCollection.cs | 55 + 43 files changed, 4146 insertions(+), 127 deletions(-) create mode 100644 src/Directory.Build.props delete mode 100644 src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/ParameterKey.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/SortedList.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs create mode 100644 src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs create mode 100644 src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs create mode 100644 src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs create mode 100644 src/Stride.Shaders/StrideImported/Mathematics/Color4.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000000..001ff6be2f --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj index 80a1afc7fb..5497c46f8f 100644 --- a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj +++ b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj @@ -14,6 +14,10 @@ + + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 2a02aad15d..cc465ad877 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -83,7 +83,7 @@ public void Merge(ShaderMixinSource mixinTree, ShaderSource source) { if (mixinTree.Compositions.TryGetValue(composition.Key, out var mixinTreeComposition)) mixinTree.Compositions.Add(composition.Key, mixinTreeComposition = new ShaderMixinSource()); - Merge(mixinTreeComposition, composition.Value); + Merge((ShaderMixinSource)mixinTreeComposition, composition.Value); } break; @@ -93,9 +93,9 @@ public void Merge(ShaderMixinSource mixinTree, ShaderSource source) public void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) { if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) - mixinTree.Compositions.Add(compositionName, composition = new()); + mixinTree.Compositions.Add(compositionName, composition = new ShaderMixinSource()); - Merge(composition, evaluatedSource); + Merge((ShaderMixinSource)composition, evaluatedSource); } } } diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 57d53586a5..e8f4280227 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -7,6 +7,8 @@ namespace Stride.Shaders.Compilers; +using Compiler = Silk.NET.SPIRV.Cross.Compiler; + public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { static readonly Cross cross = Cross.GetApi(); diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 3c521def40..7676b09203 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -14,6 +14,12 @@ + + $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + Always @@ -26,6 +32,7 @@ enable enable true + $(MSBuildProjectName)2 diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 5f6557eb39..75f92b6cad 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -5,6 +5,7 @@ using Stride.Shaders.Spirv.Tools; using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders; Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index b4d3bfaa1c..c5e015a552 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -12,10 +12,13 @@ + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + - + diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index a81bd88b02..6a16e1d9ac 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -19,6 +19,9 @@ + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + diff --git a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs b/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs deleted file mode 100644 index dcb30edc45..0000000000 --- a/src/Stride.Shaders/Parsing/SDSL/ShaderSource.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Text; - -namespace Stride.Shaders.Parsing.SDSL; - -public abstract class ShaderSource -{ - -} - -public sealed class ShaderClassSource(string className) : ShaderSource, IEquatable -{ - /// - /// Gets the name of the class. - /// - /// The name of the class. - public string ClassName { get; set; } = className; - - public bool ImportStageOnly { get; set; } = false; - - /// - /// Gets the generic parameters. - /// - /// The generic parameters. - public string[] GenericArguments { get; set; } = []; - - public string ToClassName() - { - if ((GenericArguments == null || GenericArguments.Length == 0) && !ImportStageOnly) - return ClassName; - - var result = new StringBuilder(); - // We should make this optional as it currently bothers class registration by name - //if (ImportStageOnly) - // result.Append("stage "); - result.Append(ClassName); - if (GenericArguments != null && GenericArguments.Length > 0) - { - result.Append('<'); - result.Append(string.Join(",", GenericArguments)); - result.Append('>'); - } - - return result.ToString(); - } - - public bool Equals(ShaderClassSource? shaderClassSource) - { - if (shaderClassSource is null) return false; - if (ReferenceEquals(this, shaderClassSource)) return true; - return - string.Equals(ClassName, shaderClassSource.ClassName) && - GenericArguments.SequenceEqual(shaderClassSource.GenericArguments); - } - - public override bool Equals(object? obj) - { - if (obj is null) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((ShaderClassSource)obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = ClassName?.GetHashCode() ?? 0; - if (GenericArguments != null) - { - foreach (var current in GenericArguments) - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - } - - return hashCode; - } - } - - public override string ToString() - { - return ToClassName(); - } -} - -public sealed class ShaderMixinSource : ShaderSource -{ - public List Mixins { get; } = []; - - public Dictionary Compositions { get; } = []; - - public override string ToString() - { - var result = new StringBuilder(); - - result.Append("mixin"); - - if (Mixins != null && Mixins.Count > 0) - { - result.Append(' '); - for (int i = 0; i < Mixins.Count; i++) - { - if (i > 0) - result.Append(", "); - result.Append(Mixins[i]); - } - } - - if (Compositions != null && Compositions.Count > 0) - { - result.Append(" ["); - var keys = Compositions.Keys.ToList(); - keys.Sort(); - for (int i = 0; i < keys.Count; i++) - { - var key = keys[i]; - if (i > 0) - result.Append(", "); - result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]); - } - result.Append("]"); - } - return result.ToString(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 8c976425a1..38dd3d6d70 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -7,17 +7,26 @@ + + + + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + + net10.0 enable enable True + $(MSBuildProjectName)2 diff --git a/src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs b/src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs new file mode 100644 index 0000000000..69435e3ae8 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs @@ -0,0 +1,44 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Core; + +/// +/// Indicates that a class can be serialized. +/// +[AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = false, Inherited = false)] +public class DataContractAttribute : Attribute +{ + /// + /// Initializes a new instance of the class. + /// + public DataContractAttribute() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The type alias name when serializing to a textual format. + public DataContractAttribute(string aliasName) + { + this.Alias = aliasName; + } + + /// + /// Gets or sets the alias name when serializing to a textual format. + /// + /// The alias name. + public string? Alias { get; } + + /// + /// Gets or sets a value indicating whether this is implicitly inherited by all its descendant classes. + /// + /// true if inherited; otherwise, false. + public bool Inherited { get; set; } + + /// + /// The default member mode. + /// + public DataMemberMode DefaultMemberMode { get; set; } = DataMemberMode.Default; +} diff --git a/src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs b/src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs new file mode 100644 index 0000000000..fb472f83f3 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs @@ -0,0 +1,117 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Core; + +/// +/// Specify the way to store a property or field of some class or structure. +/// +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] +public class DataMemberAttribute : Attribute +{ + public const uint DefaultMask = 1; + public const uint IgnoreMask = 0xF0000000; + + /// + /// Initializes a new instance of the class. + /// + public DataMemberAttribute() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The order. + public DataMemberAttribute(int order) + { + Order = order; + } + + /// + /// Initializes a new instance of the class. + /// + /// The name. + public DataMemberAttribute(string name) + { + Name = name; + } + + /// + /// Specify the way to store a property or field of some class or structure. + /// + /// The name. + /// The serialize method. + public DataMemberAttribute(string name, DataMemberMode mode) + { + Name = name; + Mode = mode; + } + + /// + /// Specify the way to store a property or field of some class or structure. + /// + /// The serialize method. + public DataMemberAttribute(DataMemberMode mode) + { + Mode = mode; + } + + /// + /// Initializes a new instance of the class. + /// + /// The order. + /// The mode. + public DataMemberAttribute(int order, DataMemberMode mode) + { + Order = order; + Mode = mode; + } + + /// + /// Initializes a new instance of the class. + /// + /// The order. + /// The name. + public DataMemberAttribute(int order, string name) + { + Order = order; + Name = name; + } + + /// + /// Initializes a new instance of the class. + /// + /// The order. + /// The name. + /// The mode. + public DataMemberAttribute(int order, string name, DataMemberMode mode) + { + Order = order; + Name = name; + Mode = mode; + } + + /// + /// Gets the name. + /// + /// The name. + public string? Name { get; } + + /// + /// Gets the serialize method1. + /// + /// The serialize method1. + public DataMemberMode Mode { get; } + + /// + /// Gets or sets the order. Default is -1 (default to alphabetical) + /// + /// The order. + public int? Order { get; set; } + + /// + /// Gets or sets the mask to filter out members. + /// + /// The mask. + public uint Mask { get; set; } = DefaultMask; +} diff --git a/src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs b/src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs new file mode 100644 index 0000000000..d54b062c70 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Core; + +/// +/// When specified on a property or field, it will not be used when serializing/deserializing. +/// +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)] +public class DataMemberIgnoreAttribute : Attribute; diff --git a/src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs b/src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs new file mode 100644 index 0000000000..721e314ec4 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Core; + +/// +/// Specify the way to store a property or field of some class or structure. +/// +public enum DataMemberMode +{ + /// + /// Use the default mode depending on the type of the field/property. + /// + Default = 0, + + /// + /// When restored, new object is created by using the parameters in + /// the YAML data and assigned to the property / field. When the + /// property / field is writeable, this is the default. + /// + Assign = 1, + + /// + /// Only valid for a property / field that return a class, no strings, primitives or value types. + /// When restored, instead of recreating the whole class, + /// the members are independently restored. When the property / field + /// is not writeable this is the default. + /// + Content = 2, + + /// + /// The property / field will not be stored. + /// + Never = 4, +} diff --git a/src/Stride.Shaders/StrideImported/Core/ParameterKey.cs b/src/Stride.Shaders/StrideImported/Core/ParameterKey.cs new file mode 100644 index 0000000000..f378616e24 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/ParameterKey.cs @@ -0,0 +1,126 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +#pragma warning disable SA1402 // File may only contain a single type +using Stride.Core; +using System; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Xml.Linq; + +namespace Stride.Rendering +{ + /// + /// Key of an effect parameter. + /// + public abstract class ParameterKey + { + protected string name; + + /// + /// Initializes a new instance of the class. + /// + /// Type of the property. + /// The name. + /// The length. + /// The metadatas. + protected ParameterKey(Type propertyType, string name, int length) + { + Length = length; + } + + public string Name { get => name; init => name = value; } + + /// + /// Gets the number of elements for this key. + /// + public int Length { get; private set; } + + public ParameterKeyType Type { get; protected set; } + + public abstract int Size { get; } + + internal void SetName(string nameParam) + { + if (nameParam == null) throw new ArgumentNullException(nameof(nameParam)); + + name = string.Intern(nameParam); + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + //return ReferenceEquals(this, obj); + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + var against = obj as ParameterKey; + if (against == null) return false; + return (Equals(against.Name, Name)); + } + + /// + /// Implements the operator ==. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static bool operator ==(ParameterKey left, ParameterKey right) + { + return Equals(left, right); + } + + /// + /// Implements the operator !=. + /// + /// The left. + /// The right. + /// + /// The result of the operator. + /// + public static bool operator !=(ParameterKey left, ParameterKey right) + { + return !Equals(left, right); + } + } + + public enum ParameterKeyType + { + Value, + Object, + Permutation, + } + + /// + /// Key of an gereric effect parameter. + /// + /// Type of the parameter key. + public abstract class ParameterKey : ParameterKey + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The name. + /// The length. + /// The metadatas. + protected ParameterKey(ParameterKeyType type, string name, int length = 1) + : base(typeof(T), name, length) + { + Type = type; + } + + public override int Size => Unsafe.SizeOf(); + + public override string ToString() + { + return string.Format("{0}", Name); + } + } +} diff --git a/src/Stride.Shaders/StrideImported/Core/SortedList.cs b/src/Stride.Shaders/StrideImported/Core/SortedList.cs new file mode 100644 index 0000000000..5860673080 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/SortedList.cs @@ -0,0 +1,1159 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// (ignore analyzers) +// +// System.Collections.Generic.SortedList.cs +// +// Author: +// Sergey Chaban (serge@wildwestsoftware.com) +// Duncan Mak (duncan@ximian.com) +// Herve Poussineau (hpoussineau@fr.st +// Zoltan Varga (vargaz@gmail.com) +// + +// +// Copyright (C) 2004 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections; +using System.Diagnostics; + +namespace Stride.Core.Collections; + +/// +/// Represents a collection of associated keys and values +/// that are sorted by the keys and are accessible by key +/// and by index. +/// +[DebuggerDisplay("Count = {" + nameof(Count) + "}")] +public class SortedList : IDictionary, IDictionary +{ + private static readonly int INITIAL_SIZE = 16; + + private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE } + + private int inUse; + private int modificationCount; + private KeyValuePair[] table; + private IComparer comparer; + private int defaultCapacity; + + // + // Constructors + // + public SortedList() + : this(INITIAL_SIZE, null) + { + } + + public SortedList(int capacity) + : this(capacity, null) + { + } + + public SortedList(int capacity, IComparer comparer) + { + if (capacity < 0) + throw new ArgumentOutOfRangeException(nameof(capacity)); + + defaultCapacity = capacity == 0 ? 0 : INITIAL_SIZE; + Init(comparer, capacity, true); + } + + public SortedList(IComparer comparer) + : this(INITIAL_SIZE, comparer) + { + } + + public SortedList(IDictionary dictionary) + : this(dictionary, null) + { + } + + public SortedList(IDictionary dictionary, IComparer comparer) + { + ArgumentNullException.ThrowIfNull(dictionary); + + Init(comparer, dictionary.Count, true); + + foreach (var kvp in dictionary) + Add(kvp.Key, kvp.Value); + } + + // + // Properties + // + + // ICollection + + public int Count => inUse; + + bool ICollection.IsSynchronized => false; + + object ICollection.SyncRoot => this; + + // IDictionary + + bool IDictionary.IsFixedSize => false; + + bool IDictionary.IsReadOnly => false; + + public TValue this[TKey key] + { + get + { + ArgumentNullException.ThrowIfNull(key); + + var i = Find(key); + + if (i >= 0) + return table[i].Value; + throw new KeyNotFoundException(); + } + set + { + ArgumentNullException.ThrowIfNull(key); + + PutImpl(key, value, true); + } + } + + object IDictionary.this[object key] + { + get + { + if (key is not TKey key1) + return null; + return this[key1]; + } + + set + { + this[ToKey(key)] = ToValue(value); + } + } + + public int Capacity + { + get + { + return table.Length; + } + + set + { + var current = this.table.Length; + + if (inUse > value) + { + throw new ArgumentOutOfRangeException("capacity too small"); + } + if (value == 0) + { + // return to default size + var newTable = new KeyValuePair[defaultCapacity]; + Array.Copy(table, newTable, inUse); + this.table = newTable; + } +#if NET_1_0 + else if (current > defaultCapacity && value < current) { + KeyValuePair [] newTable = new KeyValuePair [defaultCapacity]; + Array.Copy (table, newTable, inUse); + this.table = newTable; + } +#endif + else if (value > inUse) + { + var newTable = new KeyValuePair[value]; + Array.Copy(table, newTable, inUse); + this.table = newTable; + } + else if (value > current) + { + var newTable = new KeyValuePair[value]; + Array.Copy(table, newTable, current); + this.table = newTable; + } + } + } + + public IList Keys => new ListKeys(this); + + public IList Values => new ListValues(this); + + ICollection IDictionary.Keys => new ListKeys(this); + + ICollection IDictionary.Values => new ListValues(this); + + ICollection IDictionary.Keys => Keys; + + ICollection IDictionary.Values => Values; + + public IComparer Comparer => comparer; + + bool ICollection>.IsReadOnly => false; + + // + // Public instance methods. + // + + public void Add(TKey key, TValue value) + { + ArgumentNullException.ThrowIfNull(key); + + PutImpl(key, value, false); + } + + public bool ContainsKey(TKey key) + { + ArgumentNullException.ThrowIfNull(key); + + return (Find(key) >= 0); + } + + public bool Remove(TKey key) + { + ArgumentNullException.ThrowIfNull(key); + + var i = IndexOfKey(key); + if (i >= 0) + { + RemoveAt(i); + return true; + } + return false; + } + + // ICollection> + + void ICollection>.Clear() + { + defaultCapacity = INITIAL_SIZE; + this.table = new KeyValuePair[defaultCapacity]; + inUse = 0; + modificationCount++; + } + + public void Clear() + { + defaultCapacity = INITIAL_SIZE; + this.table = new KeyValuePair[defaultCapacity]; + inUse = 0; + modificationCount++; + } + + void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) + { + if (Count == 0) + return; + + ArgumentNullException.ThrowIfNull(array); + + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException(); + + if (arrayIndex >= array.Length) + throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length"); + if (Count > (array.Length - arrayIndex)) + throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array"); + + var i = arrayIndex; + foreach (var pair in this) + array[i++] = pair; + } + + void ICollection>.Add(KeyValuePair keyValuePair) + { + Add(keyValuePair.Key, keyValuePair.Value); + } + + bool ICollection>.Contains(KeyValuePair keyValuePair) + { + var i = Find(keyValuePair.Key); + + if (i >= 0) + return Comparer>.Default.Compare(table[i], keyValuePair) == 0; + return false; + } + + bool ICollection>.Remove(KeyValuePair keyValuePair) + { + var i = Find(keyValuePair.Key); + + if (i >= 0 && (Comparer>.Default.Compare(table[i], keyValuePair) == 0)) + { + RemoveAt(i); + return true; + } + return false; + } + + // IEnumerable> + + public Enumerator GetEnumerator() + { + return new Enumerator(this); + } + + IEnumerator> IEnumerable>.GetEnumerator() + { + return new Enumerator(this); + } + + // IEnumerable + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + // IDictionary + + void IDictionary.Add(object key, object value) + { + PutImpl(ToKey(key), ToValue(value), false); + } + + bool IDictionary.Contains(object key) + { + ArgumentNullException.ThrowIfNull(key); + if (key is not TKey key1) + return false; + + return (Find(key1) >= 0); + } + + IDictionaryEnumerator IDictionary.GetEnumerator() + { + return new DictionaryEnumerator(this, EnumeratorMode.ENTRY_MODE); + } + + void IDictionary.Remove(object key) + { + ArgumentNullException.ThrowIfNull(key); + if (key is not TKey key1) + return; + var i = IndexOfKey(key1); + if (i >= 0) RemoveAt(i); + } + + // ICollection + + void ICollection.CopyTo(Array array, int arrayIndex) + { + if (Count == 0) + return; + + ArgumentNullException.ThrowIfNull(array); + + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException(); + + if (array.Rank > 1) + throw new ArgumentException("array is multi-dimensional"); + if (arrayIndex >= array.Length) + throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length"); + if (Count > (array.Length - arrayIndex)) + throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array"); + + using var it = GetEnumerator(); + var i = arrayIndex; + + while (it.MoveNext()) + { + array.SetValue(it.Current, i++); + } + } + + // + // SortedList + // + + public void RemoveAt(int index) + { + var table = this.table; + var cnt = Count; + if (index >= 0 && index < cnt) + { + if (index != cnt - 1) + { + Array.Copy(table, index + 1, table, index, cnt - 1 - index); + } + else + { + table[index] = default(KeyValuePair); + } + --inUse; + ++modificationCount; + } + else + { + throw new ArgumentOutOfRangeException("index out of range"); + } + } + + public int IndexOfKey(TKey key) + { + ArgumentNullException.ThrowIfNull(key); + + var indx = 0; + try + { + indx = Find(key); + } + catch (Exception) + { + throw new InvalidOperationException(); + } + + return (indx | (indx >> 31)); + } + + public int IndexOfValue(TValue value) + { + if (inUse == 0) + return -1; + + for (var i = 0; i < inUse; i++) + { + var current = this.table[i]; + + if (Equals(value, current.Value)) + return i; + } + + return -1; + } + + public bool ContainsValue(TValue value) + { + return IndexOfValue(value) >= 0; + } + + public void TrimExcess() + { + if (inUse < table.Length * 0.9) + Capacity = inUse; + } + + public bool TryGetValue(TKey key, out TValue value) + { + ArgumentNullException.ThrowIfNull(key); + + var i = Find(key); + + if (i >= 0) + { + value = table[i].Value; + return true; + } + value = default(TValue); + return false; + } + + // + // Private methods + // + + private void EnsureCapacity(int n, int free) + { + var table = this.table; + KeyValuePair[] newTable = null; + var cap = Capacity; + var gap = (free >= 0 && free < Count); + + if (n > cap) + { + newTable = new KeyValuePair[n << 1]; + } + + if (newTable != null) + { + if (gap) + { + var copyLen = free; + if (copyLen > 0) + { + Array.Copy(table, 0, newTable, 0, copyLen); + } + copyLen = Count - free; + if (copyLen > 0) + { + Array.Copy(table, free, newTable, free + 1, copyLen); + } + } + else + { + // Just a resizing, copy the entire table. + Array.Copy(table, newTable, Count); + } + this.table = newTable; + } + else if (gap) + { + Array.Copy(table, free, table, free + 1, Count - free); + } + } + + private void PutImpl(TKey key, TValue value, bool overwrite) + { + ArgumentNullException.ThrowIfNull(key); + + var table = this.table; + + var freeIndx = -1; + + try + { + freeIndx = Find(key); + } + catch (Exception) + { + throw new InvalidOperationException(); + } + + if (freeIndx >= 0) + { + if (!overwrite) + throw new ArgumentException("element already exists"); + + table[freeIndx] = new KeyValuePair(key, value); + ++modificationCount; + return; + } + + freeIndx = ~freeIndx; + + if (freeIndx > Capacity + 1) + throw new Exception("SortedList::internal error (" + key + ", " + value + ") at [" + freeIndx + "]"); + + + EnsureCapacity(Count + 1, freeIndx); + + table = this.table; + table[freeIndx] = new KeyValuePair(key, value); + + ++inUse; + ++modificationCount; + + } + + private void Init(IComparer comparer, int capacity, bool forceSize) + { + if (comparer == null) + comparer = Comparer.Default; + this.comparer = comparer; + if (!forceSize && (capacity < defaultCapacity)) + capacity = defaultCapacity; + this.table = new KeyValuePair[capacity]; + this.inUse = 0; + this.modificationCount = 0; + } + + private void CopyToArray(Array arr, int i, EnumeratorMode mode) + { + ArgumentNullException.ThrowIfNull(arr); + + if (i < 0 || i + this.Count > arr.Length) + throw new ArgumentOutOfRangeException(nameof(i)); + + IEnumerator it = new DictionaryEnumerator(this, mode); + + while (it.MoveNext()) + { + arr.SetValue(it.Current, i++); + } + } + + private int Find(TKey key) + { + var table = this.table; + var len = Count; + + if (len == 0) return ~0; + + var left = 0; + var right = len - 1; + + while (left <= right) + { + var guess = (left + right) >> 1; + + var cmp = comparer.Compare(table[guess].Key, key); + if (cmp == 0) return guess; + + if (cmp < 0) left = guess + 1; + else right = guess - 1; + } + + return ~left; + } + + private TKey ToKey(object key) + { + ArgumentNullException.ThrowIfNull(key); + if (key is not TKey key1) + throw new ArgumentException("The value \"" + key + "\" isn't of type \"" + typeof(TKey) + "\" and can't be used in this generic collection.", nameof(key)); + return key1; + } + + private TValue ToValue(object value) + { + if (value is not TValue value1) + throw new ArgumentException("The value \"" + value + "\" isn't of type \"" + typeof(TValue) + "\" and can't be used in this generic collection.", nameof(value)); + return value1; + } + + internal TKey KeyAt(int index) + { + if (index >= 0 && index < Count) + return table[index].Key; + throw new ArgumentOutOfRangeException(nameof(index)); + } + + internal TValue ValueAt(int index) + { + if (index >= 0 && index < Count) + return table[index].Value; + throw new ArgumentOutOfRangeException(nameof(index)); + } + + // + // Inner classes + // + + public sealed class Enumerator : IEnumerator> + { + private SortedList host; + private int pos = -1; + + public Enumerator(SortedList host) + { + this.host = host; + } + + public void Dispose() + { + host = null; + } + + public bool MoveNext() + { + return ++pos < host.inUse; + } + + public void Reset() + { + throw new NotSupportedException(); + } + + object IEnumerator.Current => Current; + + public KeyValuePair Current => host.table[pos]; + } + + + private sealed class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator + { + private readonly SortedList host; + private int stamp; + private int pos; + private int size; + private readonly EnumeratorMode mode; + + private object currentKey; + private object currentValue; + + bool invalid = false; + + private static readonly string xstr = "SortedList.Enumerator: snapshot out of sync."; + + public DictionaryEnumerator(SortedList host, EnumeratorMode mode) + { + this.host = host; + stamp = host.modificationCount; + size = host.Count; + this.mode = mode; + Reset(); + } + + public DictionaryEnumerator(SortedList host) + : this(host, EnumeratorMode.ENTRY_MODE) + { + } + + public void Reset() + { + if (host.modificationCount != stamp || invalid) + throw new InvalidOperationException(xstr); + + pos = -1; + currentKey = null; + currentValue = null; + } + + public bool MoveNext() + { + if (host.modificationCount != stamp || invalid) + throw new InvalidOperationException(xstr); + + var table = host.table; + + if (++pos < size) + { + var entry = table[pos]; + + currentKey = entry.Key; + currentValue = entry.Value; + return true; + } + + currentKey = null; + currentValue = null; + return false; + } + + public DictionaryEntry Entry + { + get + { + if (invalid || pos >= size || pos == -1) + throw new InvalidOperationException(xstr); + + return new DictionaryEntry(currentKey, + currentValue); + } + } + + public object Key + { + get + { + if (invalid || pos >= size || pos == -1) + throw new InvalidOperationException(xstr); + return currentKey; + } + } + + public object Value + { + get + { + if (invalid || pos >= size || pos == -1) + throw new InvalidOperationException(xstr); + return currentValue; + } + } + + public object Current + { + get + { + if (invalid || pos >= size || pos == -1) + throw new InvalidOperationException(xstr); + + switch (mode) + { + case EnumeratorMode.KEY_MODE: + return currentKey; + case EnumeratorMode.VALUE_MODE: + return currentValue; + case EnumeratorMode.ENTRY_MODE: + return this.Entry; + + default: + throw new NotSupportedException(mode + " is not a supported mode."); + } + } + } + + // ICloneable + + public object Clone() + { + var e = new DictionaryEnumerator(host, mode); + e.stamp = stamp; + e.pos = pos; + e.size = size; + e.currentKey = currentKey; + e.currentValue = currentValue; + e.invalid = invalid; + return e; + } + } + + struct KeyEnumerator : IEnumerator, IDisposable + { + const int NOT_STARTED = -2; + + // this MUST be -1, because we depend on it in move next. + // we just decr the size, so, 0 - 1 == FINISHED + const int FINISHED = -1; + + readonly SortedList l; + int idx; + readonly int ver; + + internal KeyEnumerator(SortedList l) + { + this.l = l; + idx = NOT_STARTED; + ver = l.modificationCount; + } + + public void Dispose() + { + idx = NOT_STARTED; + } + + public bool MoveNext() + { + if (ver != l.modificationCount) + throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); + + if (idx == NOT_STARTED) + idx = l.Count; + + return idx != FINISHED && --idx != FINISHED; + } + + public TKey Current + { + get + { + if (idx < 0) + throw new InvalidOperationException(); + + return l.KeyAt(l.Count - 1 - idx); + } + } + + void IEnumerator.Reset() + { + if (ver != l.modificationCount) + throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); + + idx = NOT_STARTED; + } + + object IEnumerator.Current => Current; + } + + struct ValueEnumerator : IEnumerator, IDisposable + { + const int NOT_STARTED = -2; + + // this MUST be -1, because we depend on it in move next. + // we just decr the size, so, 0 - 1 == FINISHED + const int FINISHED = -1; + + readonly SortedList l; + int idx; + readonly int ver; + + internal ValueEnumerator(SortedList l) + { + this.l = l; + idx = NOT_STARTED; + ver = l.modificationCount; + } + + public void Dispose() + { + idx = NOT_STARTED; + } + + public bool MoveNext() + { + if (ver != l.modificationCount) + throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); + + if (idx == NOT_STARTED) + idx = l.Count; + + return idx != FINISHED && --idx != FINISHED; + } + + public TValue Current + { + get + { + if (idx < 0) + throw new InvalidOperationException(); + + return l.ValueAt(l.Count - 1 - idx); + } + } + + void IEnumerator.Reset() + { + if (ver != l.modificationCount) + throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); + + idx = NOT_STARTED; + } + + object IEnumerator.Current => Current; + } + + private class ListKeys : IList, IReadOnlyList, ICollection, IEnumerable + { + + private readonly SortedList host; + + public ListKeys(SortedList host) + { + ArgumentNullException.ThrowIfNull(host); + + this.host = host; + } + + // ICollection + + public virtual void Add(TKey item) + { + throw new NotSupportedException(); + } + + public virtual bool Remove(TKey key) + { + throw new NotSupportedException(); + } + + public virtual void Clear() + { + throw new NotSupportedException(); + } + + public virtual void CopyTo(TKey[] array, int arrayIndex) + { + if (host.Count == 0) + return; + ArgumentNullException.ThrowIfNull(array); + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException(); + if (arrayIndex >= array.Length) + throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length"); + if (Count > (array.Length - arrayIndex)) + throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array"); + + var j = arrayIndex; + for (var i = 0; i < Count; ++i) + array[j++] = host.KeyAt(i); + } + + public virtual bool Contains(TKey item) + { + return host.IndexOfKey(item) > -1; + } + + // + // IList + // + public virtual int IndexOf(TKey item) + { + return host.IndexOfKey(item); + } + + public virtual void Insert(int index, TKey item) + { + throw new NotSupportedException(); + } + + public virtual void RemoveAt(int index) + { + throw new NotSupportedException(); + } + + public virtual TKey this[int index] + { + get + { + return host.KeyAt(index); + } + set + { + throw new NotSupportedException("attempt to modify a key"); + } + } + + // + // IEnumerable + // + + public virtual IEnumerator GetEnumerator() + { + /* We couldn't use yield as it does not support Reset () */ + return new KeyEnumerator(host); + } + + // + // ICollection + // + + public virtual int Count => host.Count; + + public virtual bool IsSynchronized => ((ICollection)host).IsSynchronized; + + public virtual bool IsReadOnly => true; + + public virtual object SyncRoot => ((ICollection)host).SyncRoot; + + public virtual void CopyTo(Array array, int arrayIndex) + { + host.CopyToArray(array, arrayIndex, EnumeratorMode.KEY_MODE); + } + + // + // IEnumerable + // + + IEnumerator IEnumerable.GetEnumerator() + { + for (var i = 0; i < host.Count; ++i) + yield return host.KeyAt(i); + } + } + + private class ListValues : IList, IReadOnlyList, ICollection, IEnumerable + { + + private readonly SortedList host; + + public ListValues(SortedList host) + { + ArgumentNullException.ThrowIfNull(host); + + this.host = host; + } + + // ICollection + + public virtual void Add(TValue item) + { + throw new NotSupportedException(); + } + + public virtual bool Remove(TValue value) + { + throw new NotSupportedException(); + } + + public virtual void Clear() + { + throw new NotSupportedException(); + } + + public virtual void CopyTo(TValue[] array, int arrayIndex) + { + if (host.Count == 0) + return; + ArgumentNullException.ThrowIfNull(array); + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException(); + if (arrayIndex >= array.Length) + throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length"); + if (Count > (array.Length - arrayIndex)) + throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array"); + + var j = arrayIndex; + for (var i = 0; i < Count; ++i) + array[j++] = host.ValueAt(i); + } + + public virtual bool Contains(TValue item) + { + return host.IndexOfValue(item) > -1; + } + + // + // IList + // + public virtual int IndexOf(TValue item) + { + return host.IndexOfValue(item); + } + + public virtual void Insert(int index, TValue item) + { + throw new NotSupportedException(); + } + + public virtual void RemoveAt(int index) + { + throw new NotSupportedException(); + } + + public virtual TValue this[int index] + { + get + { + return host.ValueAt(index); + } + set + { + throw new NotSupportedException("attempt to modify a key"); + } + } + + // + // IEnumerable + // + + public virtual IEnumerator GetEnumerator() + { + /* We couldn't use yield as it does not support Reset () */ + return new ValueEnumerator(host); + } + + // + // ICollection + // + + public virtual int Count => host.Count; + + public virtual bool IsSynchronized => ((ICollection)host).IsSynchronized; + + public virtual bool IsReadOnly => true; + + public virtual object SyncRoot => ((ICollection)host).SyncRoot; + + public virtual void CopyTo(Array array, int arrayIndex) + { + host.CopyToArray(array, arrayIndex, EnumeratorMode.VALUE_MODE); + } + + // + // IEnumerable + // + + IEnumerator IEnumerable.GetEnumerator() + { + for (var i = 0; i < host.Count; ++i) + yield return host.ValueAt(i); + } + } + +} // SortedList + +// System.Collections.Generic diff --git a/src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs b/src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs new file mode 100644 index 0000000000..91a113ea9a --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs @@ -0,0 +1,47 @@ +using System.Runtime.InteropServices; + +namespace Stride.Core; + +internal static class StrideCoreExtensions +{ + /// Determines whether two sequences are equal. Comparing the elements is done using the default equality comparer for their type. + /// Allows either parameter to be null. + /// A thin wrapper around . + /// The type of the elements of the input sequences. + /// An enumerable to compare to . + /// An enumerable to compare to . + /// true if one of the following is true. + /// + /// and are the same object. + /// Neither enumerable is null and they have the same length and each of the elements in the enumerables compare equal pairwise. + /// + /// false otherwise. + public static bool SequenceEqualAllowNull(this IEnumerable first, IEnumerable second) + => SequenceEqualAllowNull(first, second, null); + + /// Determines whether two sequences are equal. Comparing the elements is done using the specified equality comparer. + /// Allows and/or to be null. + /// A thin wrapper around . + /// The type of the elements of the input sequences. + /// An enumerable to compare to . + /// An enumerable to compare to . + /// The equality comparer. + /// true if one of the following is true. + /// + /// and are the same object. + /// Neither enumerable is null and they have the same length and each of the elements in the enumerables compare equal pairwise. + /// + /// false otherwise. + public static bool SequenceEqualAllowNull(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) + { + if (ReferenceEquals(first, second)) return true; + if (first is null || second is null) return false; + if (first is List llist && second is List rlist) + { + var lhs = CollectionsMarshal.AsSpan(llist); + var rhs = CollectionsMarshal.AsSpan(rlist); + return lhs.SequenceEqual(rhs); + } + return first.SequenceEqual(second, comparer); + } +} diff --git a/src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs b/src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs new file mode 100644 index 0000000000..03a93a895d --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Graphics; + +/// +/// Identifies comparison functions that can be used to determine how the runtime compares +/// source (new) data against destination (existing) data before storing the new data. +/// +/// +/// The comparison functions can be used for a Depth-Stencil Buffer (see ) +/// for depth comparisons or rejections, or for stencil operations, or for Texture sampling +/// (see ). +/// +[DataContract] +public enum CompareFunction +{ + /// + /// Never pass the comparison. + /// + Never = 1, + + /// + /// If the source data is less than the destination data, the comparison passes. + /// + Less = 2, + + /// + /// If the source data is equal to the destination data, the comparison passes. + /// + Equal = 3, + + /// + /// If the source data is less than or equal to the destination data, the comparison passes. + /// + LessEqual = 4, + + /// + /// If the source data is greater than the destination data, the comparison passes. + /// + Greater = 5, + + /// + /// If the source data is not equal to the destination data, the comparison passes. + /// + NotEqual = 6, + + /// + /// If the source data is greater than or equal to the destination data, the comparison passes. + /// + GreaterEqual = 7, + + /// + /// Always pass the comparison. + /// + Always = 8 +} diff --git a/src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs b/src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs new file mode 100644 index 0000000000..251daf07ee --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs @@ -0,0 +1,232 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +using Stride.Core; +using Stride.Core.Mathematics; + +namespace Stride.Graphics; + +/// +/// Describes a Sampler State object, which determines how to sample Texture data. +/// +/// +[DataContract] +[StructLayout(LayoutKind.Sequential)] +public struct SamplerStateDescription : IEquatable +{ + #region Default values + + /// + /// Default value for . + /// + public const TextureFilter DefaultFilter = TextureFilter.Linear; + /// + /// Default value for . + /// + public const TextureAddressMode DefaultAddressU = TextureAddressMode.Clamp; + /// + /// Default value for . + /// + public const TextureAddressMode DefaultAddressV = TextureAddressMode.Clamp; + /// + /// Default value for . + /// + public const TextureAddressMode DefaultAddressW = TextureAddressMode.Clamp; + + /// + /// Default value for (black). + /// + public static readonly Color4 DefaultBorderColor = default; // Black (0,0,0,0) + + /// + /// Default value for . + /// + public const int DefaultMaxAnisotropy = 16; + /// + /// Default value for . + /// + public const float DefaultMinMipLevel = -float.MaxValue; + /// + /// Default value for . + /// + public const float DefaultMaxMipLevel = float.MaxValue; + /// + /// Default value for . + /// + public const float DefaultMipMapLevelOfDetailBias = 0.0f; + + /// + /// Default value for . + /// + public const CompareFunction DefaultCompareFunction = CompareFunction.Never; + + #endregion + + /// + /// Initializes a new instance of the structure + /// with default values. + /// + /// + public SamplerStateDescription() + { + } + + /// + /// Initializes a new instance of the structure + /// with default values, and a specific Texture filtering and addressing mode. + /// + /// The Texture filtering mode. + /// The Texture addressing mode for U, V, and W coordinates. + /// + public SamplerStateDescription(TextureFilter filter, TextureAddressMode addressMode) : this() + { + Filter = filter; + AddressU = AddressV = AddressW = addressMode; + } + + + /// + /// The filtering method to use when sampling a Texture. + /// + public TextureFilter Filter = DefaultFilter; + + /// + /// The method to use for resolving a U texture coordinate that is outside the [0, 1] range. + /// + public TextureAddressMode AddressU = DefaultAddressU; + + /// + /// The method to use for resolving a V texture coordinate that is outside the [0, 1] range. + /// + public TextureAddressMode AddressV = DefaultAddressV; + + /// + /// The method to use for resolving a W texture coordinate that is outside the [0, 1] range. + /// + public TextureAddressMode AddressW = DefaultAddressW; + + /// + /// The offset to apply from the calculated mipmap level. + /// + /// + /// For example, if a Texture should be sampled at mipmap level 3 and + /// is 2, then the Texture will be sampled at mipmap level 5. + /// + public float MipMapLevelOfDetailBias = DefaultMipMapLevelOfDetailBias; + + /// + /// The clamping value used if or + /// is specified in . Valid values are between 1 and 16. + /// + public int MaxAnisotropy = DefaultMaxAnisotropy; + + /// + /// A function that compares sampled data against existing sampled data. + /// + /// + /// This function will be used when specifying one of the comparison filtering modes in + /// . + /// + public CompareFunction CompareFunction = DefaultCompareFunction; + + /// + /// The border color to use if is specified for + /// , , or . + /// + public Color4 BorderColor = DefaultBorderColor; + + /// + /// The lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap + /// level and any level higher than that is less detailed. + /// + public float MinMipLevel = DefaultMinMipLevel; + + /// + /// The upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap + /// level and any level higher than that is less detailed. + /// + /// + /// This value must be greater than or equal to . + /// To have no upper limit set this to a large value such as . + /// + public float MaxMipLevel = DefaultMaxMipLevel; + + + /// + /// Returns a with default values. + /// + /// + /// The default values are: + /// + /// Linear filtering (). + /// for U, V, and W Texture coordinates. + /// No Mip LOD bias (0.0). + /// A default maximum anisotropy of 16x. + /// A comparison function that never passes (). + /// A border color of black ((0,0,0,0)). + /// + /// No clamping on Mip-levels ( is - and + /// is ). + /// + /// + /// + public static SamplerStateDescription Default => new(); + + + public static bool operator ==(SamplerStateDescription left, SamplerStateDescription right) + { + return left.Equals(right); + } + + public static bool operator !=(SamplerStateDescription left, SamplerStateDescription right) + { + return !(left == right); + } + + /// + public readonly bool Equals(SamplerStateDescription other) + { + return Filter == other.Filter + && AddressU == other.AddressU + && AddressV == other.AddressV + && AddressW == other.AddressW + && MipMapLevelOfDetailBias.Equals(other.MipMapLevelOfDetailBias) + && MaxAnisotropy == other.MaxAnisotropy + && CompareFunction == other.CompareFunction + && BorderColor.Equals(other.BorderColor) + && MinMipLevel.Equals(other.MinMipLevel) + && MaxMipLevel.Equals(other.MaxMipLevel); + } + + /// + public override readonly bool Equals(object obj) + { + return obj is SamplerStateDescription description && Equals(description); + } + + /// + public override readonly int GetHashCode() + { + var hash = new HashCode(); + hash.Add(Filter); + hash.Add(AddressU); + hash.Add(AddressV); + hash.Add(AddressW); + hash.Add(MipMapLevelOfDetailBias); + hash.Add(MaxAnisotropy); + hash.Add(CompareFunction); + hash.Add(BorderColor); + hash.Add(MinMipLevel); + hash.Add(MaxMipLevel); + return hash.ToHashCode(); + } + + /// + public override readonly string ToString() + { + return $"Sampler State {{Filter: {Filter}, Address UVW: {AddressU}, {AddressV}, {AddressW}, Mip LOD Bias: {MipMapLevelOfDetailBias}, Max Anisotropy: {MaxAnisotropy}, Compare Function: {CompareFunction}, Border Color: {BorderColor}, Min/Max MipLevel: {MinMipLevel} / {MaxMipLevel}}}"; + } +} diff --git a/src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs b/src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs new file mode 100644 index 0000000000..24338655a3 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Graphics; + +/// +/// Identifies a technique for resolving Texture coordinates that are outside +/// of the boundaries of a Texture (outside the [0, 1] range). +/// +[DataContract("TextureAddressMode")] +public enum TextureAddressMode +{ + /// + /// Tile the Texture at every (u,v) integer junction. + /// For example, for u values between 0 and 3, the Texture is repeated three times. + /// + Wrap = 1, + + /// + /// Flip the Texture at every (u,v) integer junction. + /// For u values between 0 and 1, for example, the Texture is addressed normally; + /// between 1 and 2, the Texture is flipped (mirrored); + /// between 2 and 3, the Texture is normal again; and so on. + /// + Mirror = 2, + + /// + /// Texture coordinates outside the range [0, 1] are set to the Texture color at 0 or 1, respectively. + /// + Clamp = 3, + + /// + /// Texture coordinates outside the range [0, 1] are set to the border color specified in + /// or HLSL code. + /// + Border = 4, + + /// + /// Similar to and . + /// Takes the absolute value of the Texture coordinate (thus, mirroring around 0), and then + /// clamps to the maximum value. + /// + MirrorOnce = 5 +} diff --git a/src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs b/src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs new file mode 100644 index 0000000000..7469d2e5aa --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs @@ -0,0 +1,172 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Graphics; + +/// +/// Identifies the filtering mode to use during Texture sampling. +/// +/// +/// During texture sampling, one or more texels are read and combined (this is called filtering) +/// to produce a single value. +/// +[DataContract("TextureFilter")] +public enum TextureFilter +{ + /// + /// Use point sampling for minification, magnification, and mip-level sampling. + /// + /// + /// Point sampling is the fastest texture filtering method. It is also the lowest quality, + /// because it just reads a single value and does not blend between texels. + /// + Point = 0, + + /// + /// Use point sampling for minification and magnification, and linear interpolation for mip-level sampling. + /// + /// + /// + MinMagPointMipLinear = 1, + + /// + /// Use point sampling for minification, linear interpolation for magnification, and point sampling for mip-level sampling. + /// + /// + /// + MinPointMagLinearMipPoint = 4, + + /// + /// Use point sampling for minification, linear interpolation for magnification and mip-level sampling. + /// + /// + /// + MinPointMagMipLinear = 5, + + /// + /// Use linear interpolation for minification, point sampling for magnification and mip-level sampling. + /// + /// + /// + MinLinearMagMipPoint = 16, + + /// + /// Use linear interpolation for minification, point sampling for magnification, and linear interpolation for mip-level sampling. + /// + /// + /// + MinLinearMagPointMipLinear = 17, + + /// + /// Use linear interpolation for minification and magnification, and point sampling for mip-level sampling. + /// + MinMagLinearMipPoint = 20, + + /// + /// Use linear interpolation for minification, magnification, and mip-level sampling. + /// + /// + /// Linear interpolation is slower than point sampling, but produces higher quality results. + /// Two samples are taken across the sampling direction, and a linearly interpolated value + /// is generated between those by blending them. + /// + Linear = 21, + + /// + /// Use anisotropic interpolation for minification, magnification, and mip-level sampling. + /// + /// + /// + /// When viewing a surface at a shallow angle, the Texture is stretched according to the perspective. + /// Point or linear interpolation sample in a circular area independent of the viewing angle, producing a + /// blurry or smeared appearance. + /// + /// + /// Anisotropic filtering addresses this by sampling Textures differently depending on the angle of the + /// surface relative to the viewer. + /// Instead of assuming a circular sampling footprint (as in isotropic methods like bilinear filtering), + /// it stretches the sampling region into an ellipse or more complex shapes that better fit the distorted + /// projection of the Texture, and takes more samples along that direction, depending on the anisotropy level. + /// + /// + /// It also interacts with mipmapping, selecting and interpolating from the appropriate mipmap levels, + /// to ensure that the correct Texture resolution is used, even when viewed at extreme angles. + /// + /// + Anisotropic = 85, + + /// + /// Use point sampling for minification, magnification, and mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + /// + /// Comparison filtering compares each sampled texel against a comparison value. + /// The boolean result is blended the same way that normal texture filtering is blended. + /// + /// + /// Comparison filters only work with textures that have the following formats: + /// , , + /// , and . + /// + /// + ComparisonPoint = 128, + + /// + /// Use point sampling for minification and magnification, and linear interpolation for mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinMagPointMipLinear = 129, + + /// + /// Use point sampling for minification, linear interpolation for magnification, and point sampling for mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinPointMagLinearMipPoint = 132, + + /// + /// Use point sampling for minification, and linear interpolation for magnification and mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinPointMagMipLinear = 133, + + /// + /// Use linear interpolation for minification, and point sampling for magnification and mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinLinearMagMipPoint = 144, + + /// + /// Use linear interpolation for minification, point sampling for magnification, and linear interpolation for mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinLinearMagPointMipLinear = 145, + + /// + /// Use linear interpolation for minification and magnification, and point sampling for mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonMinMagLinearMipPoint = 148, + + /// + /// Use linear interpolation for minification, magnification, and mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonLinear = 149, + + /// + /// Use anisotropic interpolation for minification, magnification, and mip-level sampling. + /// Compare the result to the comparison value. + /// + /// + ComparisonAnisotropic = 213 +} diff --git a/src/Stride.Shaders/StrideImported/Mathematics/Color4.cs b/src/Stride.Shaders/StrideImported/Mathematics/Color4.cs new file mode 100644 index 0000000000..ba6377679a --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Mathematics/Color4.cs @@ -0,0 +1,628 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// ----------------------------------------------------------------------------- +// Original code from SlimMath project. http://code.google.com/p/slimmath/ +// Greetings to SlimDX Group. Original code published with the following license: +// ----------------------------------------------------------------------------- +/* +* Copyright (c) 2007-2011 SlimDX Group +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Stride.Core.Mathematics; + +/// +/// A RGBA color value with 32-bit floating-point precision per channel. +/// +[DataContract("Color4")] +[StructLayout(LayoutKind.Sequential, Pack = 4)] +public struct Color4 : IEquatable, ISpanFormattable +{ + /// + /// The Black color (0, 0, 0, 1). + /// + public static readonly Color4 Black = new(red: 0, green: 0, blue: 0); + + /// + /// The White color (1, 1, 1, 1). + /// + public static readonly Color4 White = new(red: 1, green: 1, blue: 1); + + /// + /// The transparent black color (0, 0, 0, 0). + /// + public static readonly Color4 TransparentBlack = default; + + /// + /// The red component of the color. + /// + public float R; + + /// + /// The green component of the color. + /// + public float G; + + /// + /// The blue component of the color. + /// + public float B; + + /// + /// The alpha component of the color. + /// + public float A; + + /// + /// Initializes a new instance of the struct. + /// + /// The value that will be assigned to all components. + public Color4(float value) + { + R = value; + G = value; + B = value; + A = value; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The red component of the color. + /// The green component of the color. + /// The blue component of the color. + /// The alpha component of the color. + public Color4(float red, float green, float blue, float alpha = 1f) + { + R = red; + G = green; + B = blue; + A = alpha; + } + + /// + /// Initializes a new instance of the struct. + /// + /// A packed integer containing all four color components in RGBA order. + public Color4(uint rgba) + { + A = ((rgba >> 24) & 255) / 255.0f; + B = ((rgba >> 16) & 255) / 255.0f; + G = ((rgba >> 8) & 255) / 255.0f; + R = (rgba & 255) / 255.0f; + } + + /// + /// Initializes a new instance of the struct. + /// + /// A packed integer containing all four color components in RGBA order. + public Color4(int rgba) + { + A = ((rgba >> 24) & 255) / 255.0f; + B = ((rgba >> 16) & 255) / 255.0f; + G = ((rgba >> 8) & 255) / 255.0f; + R = (rgba & 255) / 255.0f; + } + + /// + /// Initializes a new instance of the struct. + /// + /// The values to assign to the red, green, blue, and alpha components of the color. This must be an array with four elements. + /// Thrown when is null. + /// Thrown when contains more or less than four elements. + public Color4(float[] values) + { + ArgumentNullException.ThrowIfNull(values); + if (values.Length is not 3 and not 4) + throw new ArgumentOutOfRangeException(nameof(values), "There must be 3 or 4 float[] values for Color4."); + + R = values[0]; + G = values[1]; + B = values[2]; + A = values.Length >= 4 ? values[3] : 1f; + } + + /// + /// Gets or sets the component at the specified index. + /// + /// The value of the red, green, blue, and alpha components, depending on the index. + /// The index of the component to access. Use 0 for the alpha component, 1 for the red component, 2 for the green component, and 3 for the blue component. + /// The value of the component at the specified index. + /// Thrown when the is out of the range [0, 3]. + public float this[int index] + { + readonly get + { + return index switch + { + 0 => R, + 1 => G, + 2 => B, + 3 => A, + _ => throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive."), + }; + } + + set + { + switch (index) + { + case 0: R = value; break; + case 1: G = value; break; + case 2: B = value; break; + case 3: A = value; break; + default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive."); + } + } + } + + /// + /// Converts the color into a packed integer. + /// + /// A packed integer containing all four color components. + public readonly int ToBgra() + { + uint a = (uint)(A * 255.0f) & 255; + uint r = (uint)(R * 255.0f) & 255; + uint g = (uint)(G * 255.0f) & 255; + uint b = (uint)(B * 255.0f) & 255; + + uint value = b; + value |= g << 8; + value |= r << 16; + value |= a << 24; + + return (int)value; + } + + /// + /// Converts the color into a packed integer. + /// + public readonly void ToBgra(out byte r, out byte g, out byte b, out byte a) + { + a = (byte)(A * 255.0f); + r = (byte)(R * 255.0f); + g = (byte)(G * 255.0f); + b = (byte)(B * 255.0f); + } + + /// + /// Converts the color into a packed integer. + /// + /// A packed integer containing all four color components. + public readonly int ToRgba() + { + uint a = (uint)(A * 255.0f) & 255; + uint r = (uint)(R * 255.0f) & 255; + uint g = (uint)(G * 255.0f) & 255; + uint b = (uint)(B * 255.0f) & 255; + + uint value = r; + value |= g << 8; + value |= b << 16; + value |= a << 24; + + return (int)value; + } + + /// + /// Creates an array containing the elements of the color. + /// + /// A four-element array containing the components of the color. + public readonly float[] ToArray() + { + return [R, G, B, A]; + } + + /// + /// Adds two colors. + /// + /// The first color to add. + /// The second color to add. + /// When the method completes, completes the sum of the two colors. + public static void Add(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) + { + result.A = left.A + right.A; + result.R = left.R + right.R; + result.G = left.G + right.G; + result.B = left.B + right.B; + } + + /// + /// Adds two colors. + /// + /// The first color to add. + /// The second color to add. + /// The sum of the two colors. + public static Color4 Add(Color4 left, Color4 right) + { + return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A); + } + + /// + /// Subtracts two colors. + /// + /// The first color to subtract. + /// The second color to subtract. + /// WHen the method completes, contains the difference of the two colors. + public static void Subtract(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) + { + result.A = left.A - right.A; + result.R = left.R - right.R; + result.G = left.G - right.G; + result.B = left.B - right.B; + } + + /// + /// Subtracts two colors. + /// + /// The first color to subtract. + /// The second color to subtract + /// The difference of the two colors. + public static Color4 Subtract(Color4 left, Color4 right) + { + return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A); + } + + /// + /// Modulates two colors. + /// + /// The first color to modulate. + /// The second color to modulate. + /// When the method completes, contains the modulated color. + public static void Modulate(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) + { + result.A = left.A * right.A; + result.R = left.R * right.R; + result.G = left.G * right.G; + result.B = left.B * right.B; + } + + /// + /// Modulates two colors. + /// + /// The first color to modulate. + /// The second color to modulate. + /// The modulated color. + public static Color4 Modulate(Color4 left, Color4 right) + { + return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A); + } + + /// + /// Scales a color. + /// + /// The color to scale. + /// The amount by which to scale. + /// When the method completes, contains the scaled color. + public static void Scale(ref readonly Color4 value, float scale, out Color4 result) + { + result.A = value.A * scale; + result.R = value.R * scale; + result.G = value.G * scale; + result.B = value.B * scale; + } + + /// + /// Scales a color. + /// + /// The color to scale. + /// The amount by which to scale. + /// The scaled color. + public static Color4 Scale(Color4 value, float scale) + { + return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); + } + + /// + /// Negates a color. + /// + /// The color to negate. + /// When the method completes, contains the negated color. + public static void Negate(ref readonly Color4 value, out Color4 result) + { + result.A = 1.0f - value.A; + result.R = 1.0f - value.R; + result.G = 1.0f - value.G; + result.B = 1.0f - value.B; + } + + /// + /// Negates a color. + /// + /// The color to negate. + /// The negated color. + public static Color4 Negate(Color4 value) + { + return new Color4(1.0f - value.R, 1.0f - value.G, 1.0f - value.B, 1.0f - value.A); + } + + /// + /// Restricts a value to be within a specified range. + /// + /// The value to clamp. + /// The minimum value. + /// The maximum value. + /// When the method completes, contains the clamped value. + public static void Clamp(ref readonly Color4 value, ref readonly Color4 min, ref readonly Color4 max, out Color4 result) + { + float alpha = value.A; + alpha = (alpha > max.A) ? max.A : alpha; + alpha = (alpha < min.A) ? min.A : alpha; + + float red = value.R; + red = (red > max.R) ? max.R : red; + red = (red < min.R) ? min.R : red; + + float green = value.G; + green = (green > max.G) ? max.G : green; + green = (green < min.G) ? min.G : green; + + float blue = value.B; + blue = (blue > max.B) ? max.B : blue; + blue = (blue < min.B) ? min.B : blue; + + result = new Color4(red, green, blue, alpha); + } + + /// + /// Restricts a value to be within a specified range. + /// + /// The value to clamp. + /// The minimum value. + /// The maximum value. + /// The clamped value. + public static Color4 Clamp(Color4 value, Color4 min, Color4 max) + { + Clamp(ref value, ref min, ref max, out var result); + return result; + } + + /// + /// Premultiplies the color components by the alpha value. + /// + /// The color to premultiply. + /// A color with premultiplied alpha. + public static Color4 PremultiplyAlpha(Color4 value) + { + return new Color4(value.R * value.A, value.G * value.A, value.B * value.A, value.A); + } + + /// + /// Adds two colors. + /// + /// The first color to add. + /// The second color to add. + /// The sum of the two colors. + public static Color4 operator +(Color4 left, Color4 right) + { + return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A); + } + + /// + /// Assert a color (return it unchanged). + /// + /// The color to assert (unchanged). + /// The asserted (unchanged) color. + public static Color4 operator +(Color4 value) + { + return value; + } + + /// + /// Subtracts two colors. + /// + /// The first color to subtract. + /// The second color to subtract. + /// The difference of the two colors. + public static Color4 operator -(Color4 left, Color4 right) + { + return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A); + } + + /// + /// Negates a color. + /// + /// The color to negate. + /// A negated color. + public static Color4 operator -(Color4 value) + { + return new Color4(-value.R, -value.G, -value.B, -value.A); + } + + /// + /// Scales a color. + /// + /// The factor by which to scale the color. + /// The color to scale. + /// The scaled color. + public static Color4 operator *(float scale, Color4 value) + { + return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); + } + + /// + /// Scales a color. + /// + /// The factor by which to scale the color. + /// The color to scale. + /// The scaled color. + public static Color4 operator *(Color4 value, float scale) + { + return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); + } + + /// + /// Modulates two colors. + /// + /// The first color to modulate. + /// The second color to modulate. + /// The modulated color. + public static Color4 operator *(Color4 left, Color4 right) + { + return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A); + } + + /// + /// Tests for equality between two objects. + /// + /// The first value to compare. + /// The second value to compare. + /// true if has the same value as ; otherwise, false. + public static bool operator ==(Color4 left, Color4 right) + { + return left.Equals(right); + } + + /// + /// Tests for inequality between two objects. + /// + /// The first value to compare. + /// The second value to compare. + /// true if has a different value than ; otherwise, false. + public static bool operator !=(Color4 left, Color4 right) + { + return !left.Equals(right); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static explicit operator int(Color4 value) + { + return value.ToRgba(); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// + /// The result of the conversion. + /// + public static explicit operator Color4(int value) + { + return new Color4(value); + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override readonly string ToString() => $"{this}"; + + /// + /// Returns a that represents this instance. + /// + /// The format. + /// The format provider. + /// + /// A that represents this instance. + /// + public readonly string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, IFormatProvider? formatProvider) + { + var handler = new DefaultInterpolatedStringHandler(11, 4, formatProvider); + handler.AppendLiteral("A:"); + handler.AppendFormatted(A, format); + handler.AppendLiteral(" R:"); + handler.AppendFormatted(R, format); + handler.AppendLiteral(" G:"); + handler.AppendFormatted(G, format); + handler.AppendLiteral(" B:"); + handler.AppendFormatted(B, format); + return handler.ToStringAndClear(); + } + + bool ISpanFormattable.TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) + { + var format1 = format.Length > 0 ? format.ToString() : null; + var handler = new MemoryExtensions.TryWriteInterpolatedStringHandler(11, 4, destination, provider, out _); + handler.AppendLiteral("A:"); + handler.AppendFormatted(A, format1); + handler.AppendLiteral(" R:"); + handler.AppendFormatted(R, format1); + handler.AppendLiteral(" G:"); + handler.AppendFormatted(G, format1); + handler.AppendLiteral(" B:"); + handler.AppendFormatted(B, format1); + return destination.TryWrite(ref handler, out charsWritten); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override readonly int GetHashCode() + { + return HashCode.Combine(A, R, G, B); + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public readonly bool Equals(Color4 other) + { + return A == other.A && R == other.R && G == other.G && B == other.B; + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override readonly bool Equals(object? value) + { + return value is Color4 color && Equals(color); + } + + /// + /// Deconstructs the vector's components into named variables. + /// + /// The R component + /// The G component + /// The B component + /// The A component + public readonly void Deconstruct(out float r, out float g, out float b, out float a) + { + r = R; + g = G; + b = B; + a = A; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs new file mode 100644 index 0000000000..121e4f81aa --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// Describes the type of constant buffer. + /// + [DataContract] + public enum ConstantBufferType + { + /// + /// An unknown buffer. + /// + Unknown, + + /// + /// A standard constant buffer + /// + ConstantBuffer, + + /// + /// A texture buffer + /// + TextureBuffer, + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs new file mode 100644 index 0000000000..abfb9bf11f --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs @@ -0,0 +1,47 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Diagnostics; +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// Description of a constant buffer. + /// + [DataContract] + [DebuggerDisplay("cbuffer {Name} : {Size} bytes")] + public class EffectConstantBufferDescription + { + /// + /// The name of this constant buffer. + /// + public string Name; + + /// + /// The size in bytes. + /// + public int Size; + + /// + /// The type of constant buffer. + /// + public ConstantBufferType Type; + + /// + /// The members of this constant buffer. + /// + public EffectValueDescription[] Members; + + //[DataMemberIgnore] + //public ObjectId Hash; + + /// + /// Clone the current instance of the constant buffer description. + /// + /// A clone copy of the description + public EffectConstantBufferDescription Clone() + { + return (EffectConstantBufferDescription)MemberwiseClone(); + } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs new file mode 100644 index 0000000000..63ebb4a31a --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs @@ -0,0 +1,87 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders; + +/// +/// Defines the class of a Effect / Shader parameter. +/// +/// +/// The class of a Effect / Shader parameter is not a C# ; it identifies the kind of variable +/// such as scalar, vector, object, and so on. +/// +[DataContract] +public enum EffectParameterClass : byte +{ + /// + /// The Shader parameter is a scalar value. + /// + Scalar = 0, + + /// + /// The Shader parameter is a vector value. + /// + Vector = 1, + + /// + /// The Shader parameter is a row-major matrix. + /// + MatrixRows = 2, + + /// + /// The Shader parameter is a column-major matrix. + /// + MatrixColumns = 3, + + /// + /// The Shader parameter is an object. + /// + Object = 4, + + /// + /// The Shader parameter is a structure. + /// + Struct = 5, + + /// + /// The Shader parameter is a class. + /// + InterfaceClass = 6, + + /// + /// The Shader parameter is an interface. + /// + InterfacePointer = 7, + + /// + /// The Shader parameter is a Sampler State object. + /// + Sampler = 8, + + /// + /// The Shader parameter is a Shader Resource View. + /// + ShaderResourceView = 9, + + /// + /// The Shader parameter is a Constant Buffer. + /// + ConstantBuffer = 10, + + /// + /// The Shader parameter is a Texture. + /// + TextureBuffer = 11, + + /// + /// The Shader parameter is an Unordered Access View. + /// + UnorderedAccessView = 12, + + /// + /// The Shader parameter is a vector value that represents a color. + /// + Color = 13 +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs new file mode 100644 index 0000000000..530edb6953 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs @@ -0,0 +1,28 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Diagnostics; + +using Stride.Core; +using Stride.Rendering; + +namespace Stride.Shaders; + +/// +/// Contains information about a key identifying an Effect / Shader parameter. +/// +[DataContract] +[DebuggerDisplay("{Key} ({KeyName})")] +public struct EffectParameterKeyInfo +{ + /// + /// The key that identifies the Effect / Shader parameter. + /// + [DataMemberIgnore] + public ParameterKey Key; + + /// + /// The name of the Effect / Shader parameter. + /// + public string KeyName; +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs new file mode 100644 index 0000000000..98daa0793b --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs @@ -0,0 +1,203 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders; + +/// +/// Values that identify various types of data, Textures, and Buffers that can be assigned to a Shader parameter. +/// +[DataContract] +public enum EffectParameterType : byte +{ + /// + /// The parameter is a reference. + /// + Void = 0, + + /// + /// The parameter is a boolean (i.e. ). + /// + Bool = 1, + + /// + /// The parameter is an integer (i.e. ). + /// + Int = 2, + + /// + /// The parameter is a single precision (32-bit) floating-point number (i.e. ). + /// + Float = 3, + + /// + /// The parameter is a . + /// + String = 4, + + /// + /// The parameter is a Texture. + /// + Texture = 5, + + /// + /// The parameter is a 1D Texture. + /// + Texture1D = 6, + + /// + /// The parameter is a 2D Texture. + /// + Texture2D = 7, + + /// + /// The parameter is a 3D Texture. + /// + Texture3D = 8, + + /// + /// The parameter is a Texture Cube. + /// + TextureCube = 9, + + /// + /// The parameter is a Sampler. + /// + Sampler = 10, + + /// + /// The parameter is a 1D Sampler. + /// + Sampler1D = 11, + + /// + /// The parameter is a 2D Sampler. + /// + Sampler2D = 12, + + /// + /// The parameter is a 3D Sampler. + /// + Sampler3D = 13, + + /// + /// The parameter is a Cube Sampler. + /// + SamplerCube = 14, + + /// + /// The parameter is an unsigned integer (i.e. ). + /// + UInt = 19, + + /// + /// The parameter is an 8-bit unsigned integer (i.e. ). + /// + UInt8 = 20, + + /// + /// The parameter is a Buffer. + /// + Buffer = 25, + + /// + /// The parameter is a Constant Buffer. + /// + ConstantBuffer = 26, + + /// + /// The parameter is a Texture. + /// + TextureBuffer = 27, + + /// + /// The parameter is a 1D Texture Array. + /// + Texture1DArray = 28, + + /// + /// The parameter is a 2D Texture Array. + /// + Texture2DArray = 29, + + /// + /// The parameter is a Multi-sampled 2D Texture. + /// + Texture2DMultisampled = 32, + + /// + /// The parameter is a Multi-sampled 2D Texture Array. + /// + Texture2DMultisampledArray = 33, + + /// + /// The parameter is a Cube Texture Array. + /// + TextureCubeArray = 34, + + /// + /// The parameter is a double precision (64-bit) floating-point number. + /// + Double = 39, + + /// + /// The parameter is a 1D Read-and-Write Texture. + /// + RWTexture1D = 40, + + /// + /// The parameter is an Array of 1D Read-and-Write Textures. + /// + RWTexture1DArray = 41, + + /// + /// The parameter is a 2D Read-and-Write Texture. + /// + RWTexture2D = 42, + + /// + /// The parameter is an Array of 2D Read-and-Write Textures. + /// + RWTexture2DArray = 43, + + /// + /// The parameter is a 3D Read-and-Write Texture. + /// + RWTexture3D = 44, + + /// + /// The parameter is a Read-and-Write Buffer. + /// + RWBuffer = 45, + + /// + /// The parameter is a Byte-Address Buffer. + /// + ByteAddressBuffer = 46, + + /// + /// The parameter is a Read-and-Write Byte-Address Buffer. + /// + RWByteAddressBuffer = 47, + + /// + /// The parameter is a Structured Buffer. + /// + StructuredBuffer = 48, + + /// + /// The parameter is a Read-and-Write Structured Buffer. + /// + RWStructuredBuffer = 49, + + /// + /// The parameter is an Append Structured Buffer. + /// + AppendStructuredBuffer = 50, + + /// + /// The parameter is a Consume Structured Buffer. + /// + ConsumeStructuredBuffer = 51 +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs new file mode 100644 index 0000000000..4aa0cd688d --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Collections.Generic; +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// The reflection data describing the parameters of a shader. + /// + [DataContract] + public class EffectReflection + { + /// + /// Initializes a new instance of the class. + /// + public EffectReflection() + { + SamplerStates = []; + ResourceBindings = []; + ConstantBuffers = []; + ShaderStreamOutputDeclarations = []; + InputAttributes = []; + } + + /// + /// Gets or sets the sampler states. + /// + /// The sampler states. + public List SamplerStates { get; set; } + + /// + /// Gets the parameter binding descriptions. + /// + /// The resource bindings. + public List ResourceBindings { get; set; } + + /// + /// Gets the constant buffer descriptions (if any). + /// + /// The constant buffers. + public List ConstantBuffers { get; set; } + + /// + /// Gets or sets the stream output declarations. + /// + /// The stream output declarations. + public List ShaderStreamOutputDeclarations { get; set; } + + /// + /// Gets or sets the stream output strides. + /// + /// The stream output strides. + public int[] StreamOutputStrides { get; set; } + + /// + /// Gets or sets the stream output rasterized stream. + /// + /// The stream output rasterized stream. + public int StreamOutputRasterizedStream { get; set; } + + public List InputAttributes { get; set; } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs new file mode 100644 index 0000000000..8b59e6f8cc --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs @@ -0,0 +1,51 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders; + +[DataContract] +public struct EffectResourceBindingDescription +{ + /// + /// Describes a shader parameter for a resource type. + /// + public EffectParameterKeyInfo KeyInfo; + + public EffectParameterClass Class; + + public EffectParameterType Type; + + public EffectTypeDescription ElementType; + + public string RawName; + + public string ResourceGroup; + + public ShaderStage Stage; + + public int SlotStart; + + public int SlotCount; + + public string LogicalGroup; + + + /// + public override readonly string ToString() + { + if (SlotCount <= 0) + return $""; + + string stage = Stage != ShaderStage.None ? $"{Stage} " : ""; + string bindingName = KeyInfo.Key is not null && !string.IsNullOrEmpty(RawName) + ? $" {KeyInfo.Key} -> {RawName}" + : ""; + string slots = SlotCount == 1 + ? $"(Slot {SlotStart})" + : $"(Slots {SlotStart} to {SlotStart + SlotCount - 1})"; + + return $"Binding [{stage}{Class}{bindingName} {slots}]"; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs new file mode 100644 index 0000000000..da2bc2c51c --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; +using Stride.Rendering; +using Stride.Graphics; + +namespace Stride.Shaders; + +[DataContract] +public class EffectSamplerStateBinding +{ + /// + /// Binding to a sampler. + /// + [DataMemberIgnore] + public ParameterKey Key; + + public string KeyName; + + public SamplerStateDescription Description; + + + public EffectSamplerStateBinding() { } + + public EffectSamplerStateBinding(string keyName, SamplerStateDescription description) + { + KeyName = keyName; + Description = description; + } + + + /// + public override string ToString() + { + return $"SamplerState {Key?.Name ?? KeyName} ({Description.Filter})"; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs new file mode 100644 index 0000000000..6db7e04129 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders; + +[DataContract] +public struct EffectTypeDescription +{ + /// + /// Describes a shader parameter type. + /// + public EffectParameterClass Class; + + public EffectParameterType Type; + + public int RowCount; + + public int ColumnCount; + + public int Elements; + + public int ElementSize; + + public string Name; + + public EffectTypeMemberDescription[] Members; + + + /// + public override readonly string ToString() + { + string name = Name is not null ? $" {Name}" : ""; + string rowsAndCols = RowCount > 1 || ColumnCount > 1 ? $" {RowCount}x{ColumnCount}" : ""; + return $"{Class}{rowsAndCols}{name}"; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs new file mode 100644 index 0000000000..5b25edb05f --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Diagnostics; +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// Describes a shader parameter member. + /// + [DataContract] + [DebuggerDisplay("{Name}: {Type}")] + public struct EffectTypeMemberDescription + { + /// + /// The name of this member. + /// + public string Name; + + /// + /// Offset in bytes into the parent structure (0 if not a structure member). + /// + public int Offset; + + /// + /// The type of this member. + /// + public EffectTypeDescription Type; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs new file mode 100644 index 0000000000..27d961a889 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Diagnostics; + +using Stride.Core; + +namespace Stride.Shaders; + +[DataContract] +[DebuggerDisplay("{Type.Class}{Type.RowCount}x{Type.ColumnCount} {KeyInfo.KeyName} -> {RawName}")] +public struct EffectValueDescription +{ + /// + /// Describes a shader parameter for a valuetype (usually stored in constant buffers). + /// + public EffectTypeDescription Type; + + public EffectParameterKeyInfo KeyInfo; + + public string RawName; + + public int Offset; + + public int Size; + + public object DefaultValue; + + public string LogicalGroup; +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs new file mode 100644 index 0000000000..b6b0cb3635 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders +{ + [DataContract] + public struct ShaderInputAttributeDescription + { + public string SemanticName; + + public int SemanticIndex; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs new file mode 100644 index 0000000000..0be41b5258 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs @@ -0,0 +1,48 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; + +namespace Stride.Shaders; + +/// +/// Specifies a particular shader stage. +/// +[DataContract] +public enum ShaderStage +{ + /// + /// No shader stage defined. + /// + None = 0, + + /// + /// The Vertex Shader stage. + /// + Vertex = 1, + + /// + /// The Hull Shader stage. + /// + Hull = 2, + + /// + /// The Domain Shader stage. + /// + Domain = 3, + + /// + /// The Geometry Shader stage. + /// + Geometry = 4, + + /// + /// The Pixel Shader stage. + /// + Pixel = 5, + + /// + /// The Compute Shader stage. + /// + Compute = 6 +} diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs new file mode 100644 index 0000000000..91ea8365e3 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// Description of a StreamOutput declaration entry. + /// + [DataContract] + public struct ShaderStreamOutputDeclarationEntry + { + /// + /// The stream index. + /// + public int Stream; + + /// + /// The semantic name. + /// + public string SemanticName; + + /// + /// The semantic index. + /// + public int SemanticIndex; + + /// + /// The start component + /// + public byte StartComponent; + + /// + /// The component count + /// + public byte ComponentCount; + + /// + /// The output slot + /// + public byte OutputSlot; + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs new file mode 100644 index 0000000000..1db96a0179 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs @@ -0,0 +1,99 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// An array of used only in shader mixin compositions. + /// + [DataContract("ShaderArraySource")] + public sealed class ShaderArraySource : ShaderSource, IEnumerable, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + public ShaderArraySource() + { + Values = new ShaderSourceCollection(); + } + + /// + /// Gets or sets the values. + /// + /// The values. + public ShaderSourceCollection Values { get; set; } + + /// + /// Adds the specified composition. + /// + /// The composition. + public void Add(ShaderSource composition) + { + Values.Add(composition); + } + + public override object Clone() + { + return new ShaderArraySource { Values = new ShaderSourceCollection(Values.Select(x => (ShaderSource)x.Clone())) }; + } + + public IEnumerator GetEnumerator() + { + return Values.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + public override string ToString() + { + return string.Format("[{0}]", Values != null ? string.Join(", ", Values) : string.Empty); + } + + public bool Equals(ShaderArraySource other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Values.Equals(other.Values); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj is ShaderArraySource && Equals((ShaderArraySource)obj); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + if (Values != null) + { + foreach (var current in Values) + hashCode = (hashCode*397) ^ (current?.GetHashCode() ?? 0); + } + return hashCode; + } + } + + public static bool operator ==(ShaderArraySource left, ShaderArraySource right) + { + return Equals(left, right); + } + + public static bool operator !=(ShaderArraySource left, ShaderArraySource right) + { + return !Equals(left, right); + } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs new file mode 100644 index 0000000000..42bbc1586f --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; + +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// A common base class for shader classes with source code. + /// + [DataContract("ShaderClassCode")] + public abstract class ShaderClassCode : ShaderSource + { + /// + /// Gets the name of the class. + /// + /// The name of the class. + [DataMember(10)] + public string ClassName { get; set; } + + /// + /// Gets the generic parameters. + /// + /// The generic parameters. + [DataMember(20)] + public string[] GenericArguments { get; set; } + + [DefaultValue(null)] + [DataMember(30)] + public Dictionary GenericParametersArguments { get; set; } + + /// + /// Returns a class name as a that represents this instance. + /// + /// A class name as a that represents this instance. + public string ToClassName() + { + if (GenericArguments == null) + return ClassName; + + var result = new StringBuilder(); + result.Append(ClassName); + if (GenericArguments != null && GenericArguments.Length > 0) + { + result.Append('<'); + result.Append(string.Join(",", GenericArguments)); + result.Append('>'); + } + + return result.ToString(); + } + + public override string ToString() + { + return ToClassName(); + } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs new file mode 100644 index 0000000000..9534f77b4d --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs @@ -0,0 +1,122 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Globalization; +using System.Linq; +using System.Text; + +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// A shader class based on .sdsl file, used for mixin. + /// + [DataContract("ShaderClassSource")] + public sealed class ShaderClassSource : ShaderClassCode, IEquatable + { + + /// + /// Initializes a new instance of the class. + /// + public ShaderClassSource() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + public ShaderClassSource(string className) + : this(className, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + /// The generic parameters. + public ShaderClassSource(string className, params string[] genericArguments) + { + ClassName = className; + GenericArguments = genericArguments; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the class. + /// The generic parameters. + public ShaderClassSource(string className, params object[] genericArguments) + { + ClassName = className; + if (genericArguments != null) + { + GenericArguments = new string[genericArguments.Length]; + for (int i = 0; i < genericArguments.Length; ++i) + { + var genArg = genericArguments[i]; + if (genArg is bool) + GenericArguments[i] = ((bool)genArg) ? "true" : "false"; + else + GenericArguments[i] = genArg == null ? "null" : Convert.ToString(genArg, CultureInfo.InvariantCulture); + } + } + } + + public bool Equals(ShaderClassSource shaderClassSource) + { + if (ReferenceEquals(null, shaderClassSource)) return false; + if (ReferenceEquals(this, shaderClassSource)) return true; + return + string.Equals(ClassName, shaderClassSource.ClassName) && + GenericArguments.SequenceEqualAllowNull(shaderClassSource.GenericArguments); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != GetType()) return false; + return Equals((ShaderClassSource)obj); + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = ClassName?.GetHashCode() ?? 0; + if (GenericArguments != null) + { + foreach (var current in GenericArguments) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + + return hashCode; + } + } + + public override object Clone() + { + return new ShaderClassSource(ClassName, GenericArguments = GenericArguments != null ? GenericArguments.ToArray() : null); + } + + public override string ToString() + { + return ToClassName(); + } + + /// + /// Performs an implicit conversion from to . + /// + /// Name of the class. + /// The result of the conversion. + public static implicit operator ShaderClassSource(string className) + { + return new ShaderClassSource(className); + } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs new file mode 100644 index 0000000000..18b217ecbd --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs @@ -0,0 +1,62 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; + +using Stride.Core; + +namespace Stride.Shaders; + +[DataContract] +public readonly struct ShaderMacro(string name, object definition) : IEquatable +{ + /// + /// Preprocessor macro. + /// + public readonly string Name = name ?? throw new ArgumentNullException(nameof(name)); + + public readonly string Definition = definition is not null + ? definition is bool + ? definition.ToString().ToLowerInvariant() + : definition.ToString() + : string.Empty; + + + public readonly bool Equals(ShaderMacro other) + { + return Equals(other.Name, Name) + && Equals(other.Definition, Definition); + } + + public override readonly bool Equals(object obj) + { + if (obj is null) + return false; + + return obj is ShaderMacro other && Equals(other); + } + + public override readonly int GetHashCode() + { + return HashCode.Combine(Name, Definition); + } + + public override readonly string ToString() + { + return $"{Name} = {Definition}"; + } + + #region Operators + + public static bool operator ==(ShaderMacro left, ShaderMacro right) + { + return left.Equals(right); + } + + public static bool operator !=(ShaderMacro left, ShaderMacro right) + { + return !(left == right); + } + + #endregion +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs new file mode 100644 index 0000000000..33aa927d8c --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs @@ -0,0 +1,245 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; + +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// A mixin performing a combination of and other mixins. + /// + [DataContract("ShaderMixinSource")] + public sealed class ShaderMixinSource : ShaderSource, IEquatable + { + /// + /// Initializes a new instance of the class. + /// + public ShaderMixinSource() + { + Mixins = new List(); + Compositions = new Stride.Core.Collections.SortedList(); + Macros = new List(); + } + + /// + /// Gets or sets the name of the sdfx effect linked to this node. + /// + /// The name of the sdfx effect. + [DataMember(0)] + [DefaultValue(null)] + public string Name { get; set; } + + [DataMemberIgnore] + public ShaderMixinSource Parent { get; set; } + + /// + /// Gets or sets the name of this mixin source (if this ShaderMixinSource was generated from a , + /// it contains the name of . + /// + /// The name. + //public string Name { get; set; } + + /// + /// Gets or sets the mixins. + /// + /// The mixins. + [DataMember(10)] + public List Mixins { get; set; } + + /// + /// Gets or sets the compositions. + /// + /// The compositions. + [DataMember(20)] + public Stride.Core.Collections.SortedList Compositions { get; set; } + + /// + /// Gets or sets the macros. + /// + /// The macros. + [DataMember(30)] + public List Macros { get; set; } + + /// + /// Adds a composition to this mixin. + /// + /// The name. + /// The shader source. + public void AddComposition(string name, ShaderSource shaderSource) + { + Compositions[name] = shaderSource; + } + + /// + /// Adds a composition to this mixin. + /// + /// The name. + /// The shader source element. + /// Returns the index of the composition in the array. + public int AddCompositionToArray(string name, ShaderSource shaderSourceElement) + { + ShaderSource shaderSource; + if (!Compositions.TryGetValue(name, out shaderSource)) + Compositions.Add(name, shaderSource = new ShaderArraySource()); + + var shaderArraySource = (ShaderArraySource)shaderSource; + shaderArraySource.Add(shaderSourceElement); + return shaderArraySource.Values.Count - 1; + } + + /// + /// Adds a macro to this mixin. + /// + /// The name. + /// The value. + public void AddMacro(string name, object value) + { + Macros.Add(new ShaderMacro(name, value)); + } + + /// + /// Clones from the specified . + /// + /// The parent mixin to clone from. + /// parent + public void CloneFrom(ShaderMixinSource parent) + { + if (parent == null) + throw new ArgumentNullException("parent", $"Cannot clone mixin [{Name}] from a null parent"); + + Mixins.AddRange(parent.Mixins); + Macros.AddRange(parent.Macros); + foreach (var shaderBasic in parent.Compositions) + { + Compositions[shaderBasic.Key] = shaderBasic.Value; + } + } + + /// + /// Clones from the specified . Clones members too. + /// + /// The parent mixin to clone from. + /// parent + public void DeepCloneFrom(ShaderMixinSource parent) + { + if (parent == null) + throw new ArgumentNullException("parent", $"Cannot deep clone mixin [{Name}] from a null parent"); + + foreach (var mixin in parent.Mixins) + Mixins.Add((ShaderClassCode)mixin.Clone()); + Macros.AddRange(parent.Macros); + foreach (var shaderBasic in parent.Compositions) + { + Compositions[shaderBasic.Key] = (ShaderSource)shaderBasic.Value.Clone(); + } + } + + public override bool Equals(object against) + { + if (ReferenceEquals(null, against)) return false; + if (ReferenceEquals(this, against)) return true; + if (against.GetType() != this.GetType()) return false; + return Equals((ShaderMixinSource)against); + } + + public bool Equals(ShaderMixinSource other) + { + if (other is null) return false; + if (ReferenceEquals(this, other)) return true; + + // Doesn't check for Parent for Children + return + Mixins.SequenceEqualAllowNull(other.Mixins) && + Macros.SequenceEqualAllowNull(other.Macros) && + Compositions.SequenceEqualAllowNull(other.Compositions); + } + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + foreach (var current in Mixins) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + foreach (var current in Macros) + hashCode = (hashCode * 397) ^ current.GetHashCode(); + foreach (var current in Compositions) + hashCode = (hashCode * 397) ^ current.GetHashCode(); + return hashCode; + } + } + + public override object Clone() + { + var newMixin = (ShaderMixinSource)MemberwiseClone(); + newMixin.Compositions = Compositions == null ? null : ToSortedList(Compositions.Select(x => new KeyValuePair(x.Key, (ShaderSource)x.Value.Clone()))); + newMixin.Mixins = Mixins == null ? null : Mixins.Select(x => (ShaderClassCode)x.Clone()).ToList(); + newMixin.Macros = Macros == null ? null : new List(Macros.ToArray()); + return newMixin; + } + + private static Stride.Core.Collections.SortedList ToSortedList(IEnumerable> list) + { + var values = new Stride.Core.Collections.SortedList(); + foreach (var item in list) + values.Add(item.Key, item.Value); + return values; + } + + public override string ToString() + { + var result = new StringBuilder(); + + result.Append("mixin"); + + if (Mixins != null && Mixins.Count > 0) + { + result.Append(" "); + for (int i = 0; i < Mixins.Count; i++) + { + if (i > 0) + result.Append(", "); + result.Append(Mixins[i]); + } + } + + if (Compositions != null && Compositions.Count > 0) + { + result.Append(" ["); + var keys = Compositions.Keys.ToList(); + keys.Sort(); + for (int i = 0; i < keys.Count; i++) + { + var key = keys[i]; + if (i > 0) + result.Append(", "); + result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]); + } + result.Append("]"); + } + return result.ToString(); + } + + internal bool ShouldSerializeMacros() + { + // If collection is non-null and empty, skip serialization + return Macros == null || Macros.Count != 0; + } + + internal bool ShouldSerializeMixins() + { + // If collection is non-null and empty, skip serialization + return Mixins == null || Mixins.Count != 0; + } + + internal bool ShouldSerializeCompositions() + { + // If collection is non-null and empty, skip serialization + return Compositions == null || Compositions.Count != 0; + } + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs new file mode 100644 index 0000000000..de0cb84007 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.IO; +using Stride.Core; + +namespace Stride.Shaders +{ + /// + /// A shader source. + /// + [DataContract("ShaderSource")] + public abstract class ShaderSource + { + /// + /// Gets or sets a value indicating whether this is a discard shader after it has been mixed. + /// + /// true if discard; otherwise, false. + [DataMemberIgnore] + public bool Discard { get; set; } + + /// + /// Deep clones this instance. + /// + /// A new instance. + public abstract object Clone(); + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// true if the specified is equal to this instance; otherwise, false. + public abstract override bool Equals(object against); + + public abstract override int GetHashCode(); + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs new file mode 100644 index 0000000000..42b1e483c6 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Collections.Generic; +using Stride.Core; + +namespace Stride.Shaders +{ + [DataContract] + public sealed class ShaderSourceCollection : List + { + public ShaderSourceCollection() + { + } + + public ShaderSourceCollection(IEnumerable collection) : base(collection) + { + } + + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + foreach (var current in this) + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + return hashCode; + } + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != this.GetType()) return false; + return Equals((ShaderSourceCollection)obj); + } + + public bool Equals(ShaderSourceCollection other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + if (Count != other.Count) + return false; + + for (int i = 0; i < Count; ++i) + { + if (!this[i].Equals(other[i])) + return false; + } + + return true; + } + } +} From 7e0e4682123932c50fa0930c1d764d9dd59e4c3f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 15:39:38 +0900 Subject: [PATCH 0540/1182] Moved FrameRenderer in Test project --- SDSL.sln | 17 +- src/Stride.Graphics.RHI/SamplerDesc.cs | 51 ----- .../Stride.Graphics.RHI.csproj | 23 --- .../FrameRenderer.OpenGL.cs | 2 +- .../FrameRenderer.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 181 +++--------------- .../Stride.Shaders.Parsing.Tests.csproj | 7 +- src/Stride.Shaders.Tests/TestHeaderParser.cs | 141 ++++++++++++++ 8 files changed, 177 insertions(+), 247 deletions(-) delete mode 100644 src/Stride.Graphics.RHI/SamplerDesc.cs delete mode 100644 src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj rename src/{Stride.Graphics.RHI => Stride.Shaders.Tests}/FrameRenderer.OpenGL.cs (99%) rename src/{Stride.Graphics.RHI => Stride.Shaders.Tests}/FrameRenderer.cs (90%) create mode 100644 src/Stride.Shaders.Tests/TestHeaderParser.cs diff --git a/SDSL.sln b/SDSL.sln index b525de850e..e100d4218d 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.0.11222.15 d18.0 +VisualStudioVersion = 18.0.11222.15 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9B25B78A-8418-4161-99D6-5E84611BDA59}" EndProject @@ -19,8 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Graphics.RHI", "src\Stride.Graphics.RHI\Stride.Graphics.RHI.csproj", "{050ED94E-2A9D-4145-BCD1-7B97E5D58365}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -115,18 +113,6 @@ Global {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x64.Build.0 = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.ActiveCfg = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.Build.0 = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|Any CPU.Build.0 = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x64.ActiveCfg = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x64.Build.0 = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x86.ActiveCfg = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Debug|x86.Build.0 = Debug|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|Any CPU.ActiveCfg = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|Any CPU.Build.0 = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x64.ActiveCfg = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x64.Build.0 = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x86.ActiveCfg = Release|Any CPU - {050ED94E-2A9D-4145-BCD1-7B97E5D58365}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -139,6 +125,5 @@ Global {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} - {050ED94E-2A9D-4145-BCD1-7B97E5D58365} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/src/Stride.Graphics.RHI/SamplerDesc.cs b/src/Stride.Graphics.RHI/SamplerDesc.cs deleted file mode 100644 index 333ecd90bc..0000000000 --- a/src/Stride.Graphics.RHI/SamplerDesc.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Silk.NET.Maths; - -namespace Stride.Graphics.RHI; - - -public enum FilterKind -{ - Nearest = 0, - Linear = 1, - CubicExt = 2, - CubicImg = 3 -} - -public enum TextureAddressMode -{ - Repeat = 0, - Wrap = 1, - Mirror = 2, - Clamp = 3, - Border = 4, - MirrorOnce = 5 -} -public enum ComparisonOperation -{ - Never = 0, - Less = 1, - Equal = 2, - LessEqual = 3, - Greater = 4, - NotEqual = 5, - GreaterEqual = 6, - Always = 7 -} - -public struct SamplerDesc -{ - public float MipLODBias { get; set; } - public float MipLodBias { get; set; } - public float MinLod { get; set; } - public float MaxLod { get; set; } - public float MaxAnisotropy { get; set; } - public bool UnnormalizedCoordinates { get; set; } - // VkSamplerMipmapMode mipmapMode; - public FilterKind Filter { get; set; } - public TextureAddressMode AddressU { get; set; } - public TextureAddressMode AddressV { get; set; } - public TextureAddressMode AddressW { get; set; } - public ComparisonOperation CompareOp { get; set; } - public Vector4D BorderColor { get; set; } - -} \ No newline at end of file diff --git a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj b/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj deleted file mode 100644 index 5497c46f8f..0000000000 --- a/src/Stride.Graphics.RHI/Stride.Graphics.RHI.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - net10.0 - enable - enable - true - latest - - - - - - - - - - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - - - diff --git a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs similarity index 99% rename from src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs rename to src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 8777802f2c..8d57fdd769 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -7,7 +7,7 @@ using System.Globalization; using System.Text; -namespace Stride.Graphics.RHI; +namespace Stride.Shaders.Parsing.Tests; diff --git a/src/Stride.Graphics.RHI/FrameRenderer.cs b/src/Stride.Shaders.Tests/FrameRenderer.cs similarity index 90% rename from src/Stride.Graphics.RHI/FrameRenderer.cs rename to src/Stride.Shaders.Tests/FrameRenderer.cs index d172a34d5e..fc6fc7d142 100644 --- a/src/Stride.Graphics.RHI/FrameRenderer.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.cs @@ -1,4 +1,4 @@ -namespace Stride.Graphics.RHI; +namespace Stride.Shaders.Parsing.Tests; public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? vertexSpirv = null, byte[]? fragmentSpirv = null) { diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index d136972eae..69e1aadfc4 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -1,12 +1,10 @@ using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; -using Silk.NET.OpenGL; using Silk.NET.SPIRV; using Silk.NET.SPIRV.Cross; using SixLabors.ImageSharp; using SixLabors.ImageSharp.PixelFormats; -using Stride.Graphics.RHI; using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; @@ -20,7 +18,6 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; -using System.Text.RegularExpressions; using Spv = Stride.Shaders.Spirv.Tools.Spv; namespace Stride.Shaders.Parsing.Tests; @@ -57,7 +54,7 @@ public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out Ne [Theory] [MemberData(nameof(GetTestFiles))] - public void RenderTest1(string shaderName, string methodName, string args) + public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader()); @@ -79,24 +76,30 @@ public void RenderTest1(string shaderName, string methodName, string args) // Execute test var renderer = new OpenGLFrameRenderer((uint)width, (uint)height); - // Setup parameters - var parameters = TestHeaderParser.ParseParameters(args); - foreach (var param in parameters) - renderer.Parameters.Add(param.Key, param.Value); - - renderer.FragmentShaderSource = codePS; - if (codeVS != null) - renderer.VertexShaderSource = codeVS; - using var frameBuffer = MemoryOwner.Allocate(width * height * 4); - renderer.RenderFrame(frameBuffer.Span); - var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); - Assert.Equal(width, pixels.Width); - Assert.Equal(height, pixels.Height); - - // Check output color value against expected result - var expectedColor = StringToRgba(parameters["ExpectedResult"]); - var pixel = pixels[0, 0].PackedValue; - Assert.Equal(expectedColor.ToString("X8"), pixel.ToString("X8")); + var code = File.ReadAllLines($"./assets/SDSL/RenderTests/{shaderName}.sdsl"); + foreach (var test in TestHeaderParser.ParseHeaders(code)) + { + renderer.Parameters.Clear(); + + // Setup parameters + var parameters = TestHeaderParser.ParseParameters(test.Parameters); + foreach (var param in parameters) + renderer.Parameters.Add(param.Key, param.Value); + + renderer.FragmentShaderSource = codePS; + if (codeVS != null) + renderer.VertexShaderSource = codeVS; + using var frameBuffer = MemoryOwner.Allocate(width * height * 4); + renderer.RenderFrame(frameBuffer.Span); + var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); + Assert.Equal(width, pixels.Width); + Assert.Equal(height, pixels.Height); + + // Check output color value against expected result + var expectedColor = StringToRgba(parameters["ExpectedResult"]); + var pixel = pixels[0, 0].PackedValue; + Assert.Equal(expectedColor.ToString("X8"), pixel.ToString("X8")); + } } public static IEnumerable GetTestFiles() @@ -105,12 +108,8 @@ public static IEnumerable GetTestFiles() { // Parse header var code = File.ReadAllLines(filename); - - foreach (var test in TestHeaderParser.ParseHeaders(code)) - { - var shadername = Path.GetFileNameWithoutExtension(filename); - yield return [shadername, test.Name, test.Parameters]; - } + var shadername = Path.GetFileNameWithoutExtension(filename); + yield return [shadername]; } yield break; @@ -131,130 +130,4 @@ public static uint StringToRgba(string? stringColor) } return intValue; } - -} - -// Note: generated with ChatGPT -public sealed class TestHeader -{ - public string Name { get; } - public string Parameters { get; } - - public TestHeader(string name, string parameters) - { - Name = name; - Parameters = parameters; - } - - public override string ToString() => - $"{Name}: {string.Join(", ", Parameters)}"; } - -public static class TestHeaderParser -{ - // Matches: // TestName (Param1=..., Param2=..., ...) - // name = "Test" in your example - // args = "Param1=1, Param2=1, ExpectedResult=0x7F7F7F7F" - private static readonly Regex HeaderRegex = - new Regex(@"^\s*//\s*(?[^(]+?)\s*\((?.*)\)\s*$", - RegexOptions.Compiled); - - /// - /// Parse all headers from the provided lines. - /// - public static IEnumerable ParseHeaders(IEnumerable lines) - { - foreach (var line in lines) - { - var m = HeaderRegex.Match(line); - if (!m.Success) continue; - - var name = m.Groups["name"].Value.Trim(); - var args = m.Groups["args"].Value; - - var parameters = ParseParameters(args); - yield return new TestHeader(name, args); - } - } - - /// - /// Splits "A=1, B=foo, ExpectedResult=0xFF" into a dictionary. - /// Supports quoted values with commas: A="hello, world". - /// - public static Dictionary ParseParameters(string args) - { - var result = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var piece in SplitArgs(args)) - { - if (string.IsNullOrWhiteSpace(piece)) continue; - - var eqIndex = piece.IndexOf('='); - if (eqIndex < 0) - { - // Parameter without value; store empty string - var keyOnly = piece.Trim(); - if (!result.ContainsKey(keyOnly)) - result[keyOnly] = string.Empty; - continue; - } - - var key = piece.Substring(0, eqIndex).Trim(); - var value = piece.Substring(eqIndex + 1).Trim(); - - // Strip matching quotes if present - if (value.Length >= 2 && - ((value[0] == '"' && value[^1] == '"') || (value[0] == '\'' && value[^1] == '\''))) - { - value = value.Substring(1, value.Length - 2); - } - - // Last-in wins on duplicate keys - result[key] = value; - } - return result; - } - - /// - /// Splits by commas but ignores commas inside quotes. - /// Accepts both single- and double-quoted values. - /// - private static IEnumerable SplitArgs(string args) - { - if (string.IsNullOrEmpty(args)) - yield break; - - var current = new List(args.Length); - bool inSingle = false, inDouble = false; - - for (int i = 0; i < args.Length; i++) - { - char c = args[i]; - - if (c == '\'' && !inDouble) - { - inSingle = !inSingle; - current.Add(c); - continue; - } - - if (c == '"' && !inSingle) - { - inDouble = !inDouble; - current.Add(c); - continue; - } - - if (c == ',' && !inSingle && !inDouble) - { - yield return new string(current.ToArray()).Trim(); - current.Clear(); - continue; - } - - current.Add(c); - } - - if (current.Count > 0) - yield return new string(current.ToArray()).Trim(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 6a16e1d9ac..e7f66ae13a 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -7,6 +7,7 @@ false true + True @@ -16,6 +17,11 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + @@ -32,7 +38,6 @@ - diff --git a/src/Stride.Shaders.Tests/TestHeaderParser.cs b/src/Stride.Shaders.Tests/TestHeaderParser.cs new file mode 100644 index 0000000000..37ae5a3d8c --- /dev/null +++ b/src/Stride.Shaders.Tests/TestHeaderParser.cs @@ -0,0 +1,141 @@ +using System.Text.RegularExpressions; + +namespace Stride.Shaders.Parsing.Tests; + +// Note: generated with ChatGPT +public sealed class TestHeader +{ + public string Name { get; } + public string Parameters { get; } + + public TestHeader(string name, string parameters) + { + Name = name; + Parameters = parameters; + } + + public override string ToString() => + $"{Name}: {string.Join(", ", Parameters)}"; +} + +public static class TestHeaderParser +{ + // Matches: // TestName (Param1=..., Param2=..., ...) + // name = "Test" in your example + // args = "Param1=1, Param2=1, ExpectedResult=0x7F7F7F7F" + private static readonly Regex HeaderRegex = + new Regex(@"^\s*//\s*(?[^(]+?)\s*\((?.*)\)\s*$", + RegexOptions.Compiled); + + /// + /// Parse all headers from the provided lines. + /// + public static IEnumerable ParseHeaders(IEnumerable lines) + { + foreach (var line in lines) + { + var m = HeaderRegex.Match(line); + if (!m.Success) continue; + + var name = m.Groups["name"].Value.Trim(); + var args = m.Groups["args"].Value; + + var parameters = ParseParameters(args); + yield return new TestHeader(name, args); + } + } + + /// + /// Splits "A=1, B=foo, ExpectedResult=0xFF" into a dictionary. + /// Supports quoted values with commas: A="hello, world". + /// + public static Dictionary ParseParameters(string args) + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var piece in SplitArgs(args)) + { + if (string.IsNullOrWhiteSpace(piece)) continue; + + var eqIndex = piece.IndexOf('='); + if (eqIndex < 0) + { + // Parameter without value; store empty string + var keyOnly = piece.Trim(); + if (!result.ContainsKey(keyOnly)) + result[keyOnly] = string.Empty; + continue; + } + + var key = piece.Substring(0, eqIndex).Trim(); + var value = piece.Substring(eqIndex + 1).Trim(); + + // Strip matching quotes if present + if (value.Length >= 2 && + ((value[0] == '"' && value[^1] == '"') || (value[0] == '\'' && value[^1] == '\''))) + { + value = value.Substring(1, value.Length - 2); + } + + // Last-in wins on duplicate keys + result[key] = value; + } + return result; + } + + /// + /// Splits by commas but ignores commas inside quotes. + /// Accepts both single- and double-quoted values. + /// + private static IEnumerable SplitArgs(string args) + { + if (string.IsNullOrEmpty(args)) + yield break; + + var current = new List(args.Length); + bool inSingleQuote = false; + bool inDoubleQuote = false; + int parenthesisLevel = 0; + + for (int i = 0; i < args.Length; i++) + { + char c = args[i]; + + if (c == '\'' && !inDoubleQuote) + { + inSingleQuote = !inSingleQuote; + current.Add(c); + continue; + } + + if (c == '"' && !inSingleQuote) + { + inDoubleQuote = !inDoubleQuote; + current.Add(c); + continue; + } + + if (c == '(' && !inSingleQuote && !inDoubleQuote) + { + parenthesisLevel++; + continue; + } + if (c == ')' && !inSingleQuote && !inDoubleQuote) + { + parenthesisLevel--; + continue; + } + + if (c == ',' && !inSingleQuote && !inDoubleQuote && parenthesisLevel == 0) + { + yield return new string(current.ToArray()).Trim(); + current.Clear(); + continue; + } + + current.Add(c); + } + + if (current.Count > 0) + yield return new string(current.ToArray()).Trim(); + } +} \ No newline at end of file From 6bd85f819c850e89fdca36161467476d8ba20ed3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 15:45:51 +0900 Subject: [PATCH 0541/1182] Added support for cbuffer reflection and merging. --- assets/SDSL/RenderTests/CBuffer.sdsl | 39 +++ assets/SDSL/RenderTests/ForBreak.sdsl | 6 +- assets/SDSL/RenderTests/If.sdsl | 4 +- assets/SDSL/RenderTests/IfElse.sdsl | 4 +- assets/SDSL/RenderTests/IfElseif.sdsl | 6 +- assets/SDSL/RenderTests/IfElseifElse.sdsl | 6 +- assets/SDSL/RenderTests/IfElseifElseif.sdsl | 8 +- .../SDSL/ShaderMixer.cs | 258 +++++++++++++++++- src/Stride.Shaders.Experiments/Program.cs | 2 +- .../Buffers/NewSpirvBuffer.cs | 27 +- .../Information/InstructionInfo.Order.cs | 1 + .../FrameRenderer.OpenGL.cs | 18 +- src/Stride.Shaders.Tests/RenderingTests.cs | 3 +- .../Spirv/Building/Builder.CBuffer.cs | 48 ++++ src/Stride.Shaders/Spirv/Building/Context.cs | 48 +--- .../Spirv/Processing/StreamAnalyzer.cs | 7 - 16 files changed, 406 insertions(+), 79 deletions(-) create mode 100644 assets/SDSL/RenderTests/CBuffer.sdsl create mode 100644 src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs diff --git a/assets/SDSL/RenderTests/CBuffer.sdsl b/assets/SDSL/RenderTests/CBuffer.sdsl new file mode 100644 index 0000000000..0855cd7a31 --- /dev/null +++ b/assets/SDSL/RenderTests/CBuffer.sdsl @@ -0,0 +1,39 @@ +// PSMain(ExpectedResult=#1113FFFF, cbuffer.Test=(Test1=17, Test2=19)) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader Compute2 : Compute +{ + cbuffer Test + { + int Test1; + } + + override float Compute() + { + return base.Compute() + (float)Test1 / 255.0; + } +} + +shader CBuffer : Compute2 +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test2; + } + + void PSMain() + { + streams.ColorTarget = float4(Compute(), Test2 / 255.0, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/ForBreak.sdsl b/assets/SDSL/RenderTests/ForBreak.sdsl index 4b757457aa..71c9f39d92 100644 --- a/assets/SDSL/RenderTests/ForBreak.sdsl +++ b/assets/SDSL/RenderTests/ForBreak.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.Test=10) -// PSMain(ExpectedResult=#05050505, cbuffer.Test=5) -// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) +// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.Test=(Test1=10)) +// PSMain(ExpectedResult=#05050505, cbuffer.Test=(Test1=5)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/If.sdsl b/assets/SDSL/RenderTests/If.sdsl index 191af2641e..7dc81ada68 100644 --- a/assets/SDSL/RenderTests/If.sdsl +++ b/assets/SDSL/RenderTests/If.sdsl @@ -1,5 +1,5 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) -// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElse.sdsl b/assets/SDSL/RenderTests/IfElse.sdsl index 4d525334a3..b0976113f4 100644 --- a/assets/SDSL/RenderTests/IfElse.sdsl +++ b/assets/SDSL/RenderTests/IfElse.sdsl @@ -1,5 +1,5 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseif.sdsl b/assets/SDSL/RenderTests/IfElseif.sdsl index 9dba34113e..ef1dbc9074 100644 --- a/assets/SDSL/RenderTests/IfElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseif.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) -// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseifElse.sdsl b/assets/SDSL/RenderTests/IfElseifElse.sdsl index 3dbc4b5dc4..9f10c8c891 100644 --- a/assets/SDSL/RenderTests/IfElseifElse.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElse.sdsl @@ -1,6 +1,6 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) -// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/assets/SDSL/RenderTests/IfElseifElseif.sdsl b/assets/SDSL/RenderTests/IfElseifElseif.sdsl index 759e1f78b6..21febe9d16 100644 --- a/assets/SDSL/RenderTests/IfElseifElseif.sdsl +++ b/assets/SDSL/RenderTests/IfElseifElseif.sdsl @@ -1,7 +1,7 @@ -// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=1) -// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=2) -// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=3) -// PSMain(ExpectedResult=#00000000, cbuffer.Test=0) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#FF7F7F7F, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=0)) namespace Stride.Shaders.Tests; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 83a088cf74..fd47a91b9e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -22,7 +22,7 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) + public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out EffectReflection effectReflection) { var temp = new NewSpirvBuffer(); @@ -48,6 +48,12 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) new StreamAnalyzer().Process(table, temp, context); + // Merge cbuffers and rgroups + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + MergeCBuffers(globalContext, context, temp); + Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + ComputeCBufferOffsets(globalContext, context, temp); + CleanupUnnecessaryInstructions(temp); foreach (var inst in context) @@ -66,12 +72,181 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode) File.WriteAllText("test.spvdis", Spv.Dis(temp)); Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif + + effectReflection = globalContext.Reflection; + } + + private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + { + var cbuffersByNames = buffer + .Where(x => x.Op == Op.OpVariable) + .Select(x => (OpVariable)x) + // Note: MemberOffset is simply a shift in Members index, not something like a byte offset + .Select(x => ( + Variable: x, + StructTypePtrId: x.ResultType, + StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + MemberOffset: 0)) + // TODO: Check Decoration.Block? + .Where(x => x.StructType != null) + .GroupBy(x => globalContext.Names[x.Variable.ResultId]); + + foreach (var cbuffersEntry in cbuffersByNames) + { + if (cbuffersEntry.Count() > 1) + { + var cbuffers = cbuffersEntry.ToList(); + var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); + int offset = 0; + // TODO: Analyze and skip cbuffers parts which are unused + foreach (ref var cbuffer in cbuffersSpan) + { + cbuffer.MemberOffset = offset; + offset += cbuffer.StructType.Members.Count; + } + var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); + var structTypes = cbuffers.Select(x => x.StructType); + var structTypeIds = cbuffers.ToDictionary(x => context.Types[x.StructType], x => x); + + var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); + var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); + var mergedCbufferPtrStructId = context.GetOrRegister(new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform)); + + // Remap member ids + foreach (var i in buffer) + { + if (i.Op == Op.OpMemberName && (OpMemberName)i is { } memberName) + { + if (structTypeIds.TryGetValue(memberName.Type, out var cbuffer)) + memberName.Member += cbuffer.MemberOffset; + } + else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { } memberDecorate) + { + if (structTypeIds.TryGetValue(memberDecorate.StructureType, out var cbuffer)) + memberDecorate.Member += cbuffer.MemberOffset; + } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { } memberDecorateString) + { + if (structTypeIds.TryGetValue(memberDecorateString.StructType, out var cbuffer)) + memberDecorateString.Member += cbuffer.MemberOffset; + } + else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberOffset > 0) + { + // According to spec, this must be a OpConstant (and we only create them with int) + var indexes = accessChain.Values.Elements.Span; + var constantId = indexes[0]; + var index = cbuffer.MemberOffset + (int)SpirvBuilder.GetConstantValue(constantId, buffer); + indexes[0] = context.CompileConstant(index).Id; + + // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) + accessChain.UpdateInstructionMemory(); + } + } + // Out of safety, check for any OpLoad/OpStore on the variables (forbidden, only OpAccessChain) + else if (i.Op == Op.OpLoad && (OpLoad)i is { } load) + { + if (variables.TryGetValue(load.Pointer, out var cbuffer)) + throw new NotSupportedException("Can't OpLoad with cbuffer"); + } + else if (i.Op == Op.OpStore && (OpStore)i is { } store) + { + if (variables.TryGetValue(store.Pointer, out var cbuffer)) + throw new NotSupportedException("Can't OpLoad with cbuffer"); + } + } + + var idRemapping = new Dictionary(); + // Update variable to use new type + idRemapping.Add(cbuffersSpan[0].StructTypePtrId, mergedCbufferPtrStructId); + + foreach (ref var cbuffer in cbuffersSpan.Slice(1)) + { + // Update all cbuffers access to be replaced with unified cbuffer + idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); + // Remove other cbuffer variables + SetOpNop(cbuffer.Variable.InstructionMemory.Span); + // TODO: Do we want to remove unecessary types? + // Maybe we don't care as they are not used anymore, they will be ignored. + // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? + } + + SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); + } + } + } + + private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + { + var cbuffers = buffer + .Where(x => x.Op == Op.OpVariable) + .Select(x => (OpVariable)x) + // Note: MemberOffset is simply a shift in Members index, not something like a byte offset + .Select(x => ( + Variable: x, + StructTypePtrId: x.ResultType, + StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + MemberOffset: 0)) + .Where(x => x.StructType != null) + .ToList(); + + EffectTypeDescription ConvertType(SymbolType symbolType) + { + return symbolType switch + { + ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1 }, + ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1 }, + // TODO: should we use RowCount instead? (need to update Stride) + VectorType v => ConvertType(v.BaseType) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, + MatrixType m => ConvertType(m.BaseType) with { Class = EffectParameterClass.Vector, RowCount = m.Rows, ColumnCount = m.Columns }, + }; + } + + foreach (var cbuffer in cbuffers) + { + int constantBufferOffset = 0; + var cb = cbuffer.StructType; + + var memberInfos = new EffectValueDescription[cb.Members.Count]; + for (var index = 0; index < cb.Members.Count; index++) + { + // Properly compute size and offset according to DirectX rules + var member = cb.Members[index]; + var memberSize = SpirvBuilder.ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); + + context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); + + memberInfos[index] = new EffectValueDescription + { + Type = ConvertType(member.Type), + RawName = member.Name, + Offset = constantBufferOffset, + Size = memberSize, + }; + + // Adjust offset for next item + constantBufferOffset += memberSize; + } + + globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription + { + Name = globalContext.Names[cbuffer.Variable.ResultId], + // Round buffer size to next multiple of 16 bytes + Size = (constantBufferOffset + 15) / 16 * 16, + + Type = ConstantBufferType.ConstantBuffer, + Members = memberInfos, + }); + } } class MixinGlobalContext { public Dictionary Names { get; } = []; public Dictionary Types { get; } = []; + + public EffectReflection Reflection { get; } = new(); } class MixinNodeContext @@ -110,6 +285,8 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Import struct types ImportStructTypes(globalContext, buffer, mixinNode); + Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + // Build names and types mappings ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); @@ -134,6 +311,71 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Patch method calls (virtual calls & base calls) PatchMethodCalls(globalContext, buffer, mixinNode); + // Process reflection + Dictionary linkInfos = new(); + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + // Fill linkInfos + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is + { + Target: int t, + Decoration: + { + Value: Decoration.LinkSDSL or Decoration.ResourceGroupSDSL or Decoration.LogicalGroupSDSL, + Parameters: { } m + } + } decoration) + { + using var n = new LiteralValue(m.Span); + ref var linkInfo = ref CollectionsMarshal.GetValueRefOrAddDefault(linkInfos, t, out _); + if (decoration.Decoration.Value == Decoration.LinkSDSL) + linkInfo.LinkName = n.Value; + else if (decoration.Decoration.Value == Decoration.ResourceGroupSDSL) + linkInfo.ResourceGroup = n.Value; + else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) + linkInfo.LogicalGroup = n.Value; + } + else if (i.Op == Op.OpVariable && (OpVariable)i is { } variable) + { + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType pointerType) + { + if (pointerType.BaseType is TextureType) + { + var name = globalContext.Names[variable.ResultId]; + linkInfos.TryGetValue(variable.ResultId, out var linkInfo); + var linkName = linkInfo.LinkName; + if (currentCompositionPath != null) + linkName = $"{currentCompositionPath}.{linkName}"; + + var slot = globalContext.Reflection.ResourceBindings.Count; + globalContext.Reflection.ResourceBindings.Add(new EffectResourceBindingDescription + { + KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, + Class = EffectParameterClass.ShaderResourceView, + Type = EffectParameterType.Texture, + ElementType = default, + RawName = name, + ResourceGroup = linkInfo.ResourceGroup, + //Stage = , // filed by ShaderCompiler + SlotStart = globalContext.Reflection.ResourceBindings.Count, + SlotCount = 1, + LogicalGroup = linkInfo.LogicalGroup, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(slot))); + } + else if (pointerType.BaseType is SamplerType) + { + + } + } + } + } + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = buffer[index]; @@ -360,6 +602,20 @@ private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer } } + // Remove associated OpName + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + if (i.Data.Op == Op.OpName && (OpName)i is { } name) + { + if (idRemapping.ContainsKey(name.Target)) + { + SetOpNop(i.Data.Memory.Span); + } + } + } + SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 75f92b6cad..1f67795585 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -15,7 +15,7 @@ var loader = new Examples.ShaderLoader(); loader.LoadExternalFile("Test", out var testBuffer); var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode); +shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 6879425cd4..84ea3aa02d 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -1,5 +1,6 @@ #pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. +using System.Collections; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; @@ -160,7 +161,7 @@ public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) public readonly ref OpData Data => ref Buffer.GetRef(Index); } -public sealed class NewSpirvBuffer() : IDisposable +public sealed class NewSpirvBuffer() : IDisposable, IEnumerable { public SpirvHeader Header { get; set; } = new("1.4", 0, 1); List Instructions { get; set; } = []; @@ -196,6 +197,7 @@ void UpdateBound(OpData data) public void Add(OpData data) { Instructions.Add(data); + UpdateBound(data); } public OpData Add(in T instruction) where T : struct, IMemoryInstruction @@ -298,7 +300,7 @@ public OpData Replace(int index, in T instruction) where T : struct, IMemoryI public Enumerator GetEnumerator() => new(this); - public ref struct Enumerator(NewSpirvBuffer buffer) + public struct Enumerator(NewSpirvBuffer buffer) : IEnumerator { readonly NewSpirvBuffer buffer = buffer; private readonly List list = buffer.Instructions; @@ -306,6 +308,12 @@ public ref struct Enumerator(NewSpirvBuffer buffer) public readonly OpDataIndex Current => new(index, buffer); + object IEnumerator.Current => Current; + + public void Dispose() + { + } + public bool MoveNext() { if (index < list.Count - 1) @@ -315,6 +323,11 @@ public bool MoveNext() } return false; } + + public void Reset() + { + index = -1; + } } public void Sort() @@ -377,6 +390,16 @@ public static NewSpirvBuffer Merge(NewSpirvBuffer buffer1, NewSpirvBuffer buffer result.Instructions.AddRange(buffer2.Instructions); return result; } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 9c4c660484..4a94e2c470 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -71,6 +71,7 @@ void InitOrder() foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) OrderGroup[(e, null)] = group; + group++; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) OrderGroup[(Op.OpVariable, e)] = group; diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 8d57fdd769..13ac60f4cf 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -2,6 +2,7 @@ using Silk.NET.Maths; using Silk.NET.OpenGL; using Silk.NET.Windowing; +using Stride.Shaders; using System; using System.Drawing; using System.Globalization; @@ -67,6 +68,7 @@ void main() 1, 2, 3 ]; + public EffectReflection EffectReflection { get; set; } public override unsafe void RenderFrame(Span result) { @@ -225,13 +227,21 @@ public override unsafe void RenderFrame(Span result) continue; Gl.UniformBlockBinding(Shader, blockIndex, 0); - // Note: we only support a single int value for now - if (!int.TryParse(param.Value, out var data)) - throw new NotImplementedException("Tests only support a single integer in cbuffer"); + var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == cbufferName); + var cbufferData = new byte[cbReflection.Size]; + foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) + { + var cbMemberReflection = cbReflection.Members.Single(x => x.RawName == cbufferParameter.Key); + if (cbMemberReflection.Type.Class != EffectParameterClass.Scalar || cbMemberReflection.Type.Type != EffectParameterType.Int) + throw new NotImplementedException(); + + fixed (byte* cbufferDataPtr = cbufferData) + *((int*)&cbufferDataPtr[cbMemberReflection.Offset]) = int.Parse(cbufferParameter.Value); + } Gl.GenBuffers(1, out uint ubo); Gl.BindBuffer(GLEnum.UniformBuffer, ubo); - Gl.BufferData(GLEnum.UniformBuffer, sizeof(uint), &data, GLEnum.DynamicDraw); + Gl.BufferData(GLEnum.UniformBuffer, (nuint)cbReflection.Size, cbufferData, GLEnum.DynamicDraw); Gl.BindBuffer(GLEnum.UniformBuffer, 0); // Unbind Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 69e1aadfc4..b9e77fcd4a 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -58,7 +58,7 @@ public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader()); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); File.WriteAllBytes($"{shaderName}.spv", bytecode); // Convert to GLSL @@ -90,6 +90,7 @@ public void RenderTest1(string shaderName) if (codeVS != null) renderer.VertexShaderSource = codeVS; using var frameBuffer = MemoryOwner.Allocate(width * height * 4); + renderer.EffectReflection = effectReflection; renderer.RenderFrame(frameBuffer.Span); var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); Assert.Equal(width, pixels.Width); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs new file mode 100644 index 0000000000..3192cca10a --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -0,0 +1,48 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Stride.Shaders.Spirv.Building; + +partial class SpirvBuilder +{ + public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, TypeModifier typeModifier) + { + // Helper to multiply size without changing alignment + static (int Size, int Alignment) MultiplySize((int Size, int Alignment) current, int count) => (current.Size * count, current.Alignment); + return (symbol) switch + { + ScalarType { TypeName: "sbyte" or "byte" } => (1, 1), + ScalarType { TypeName: "short" or "ushort" } => (2, 2), + ScalarType { TypeName: "int" or "uint" or "float" or "bool" } => (4, 4), + ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 8), + VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), + // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Columns - 1) + m.Rows)), + MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Rows - 1) + m.Columns)), + // Round up to 16 bytes (size of float4) + ArrayType a => ((TypeSizeInBuffer(a.BaseType, typeModifier).Size + 15) / 16 * 16 * a.Size, 16), + // TODO: StructureType + }; + } + + // + // Computes the size of a member type, including its alignment and array size. + // It does so recursively for structs, and handles different parameter classes. + // + public static int ComputeCBufferOffset(SymbolType type, TypeModifier typeModifier, ref int constantBufferOffset) + { + (var size, var alignment) = TypeSizeInBuffer(type, typeModifier); + + // Align to float4 if it is bigger than leftover space in current float4 + if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16) + alignment = 16; + + // Align offset and store it as member offset + constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment; + + return size; + } +} diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 3bbabe9f35..41ea86a608 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -257,55 +257,10 @@ public int DeclareCBuffer(ConstantBufferSymbol cb) var result = DeclareStructuredType($"type.{cb.ToId()}", cb); Buffer.Add(new OpDecorate(result, Decoration.Block)); - int constantBufferOffset = 0; - for (var index = 0; index < cb.Members.Count; index++) - { - // Properly compute size and offset according to DirectX rules - var member = cb.Members[index]; - var memberSize = ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); - - Buffer.Add(new OpMemberDecorate(result, index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); - } - - Types[cb] = result; return result; } - public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, TypeModifier typeModifier) - => (symbol) switch - { - ScalarType { TypeName: "sbyte" or "byte" } => (1, 4), - ScalarType { TypeName: "short" or "ushort" } => (2, 4), - ScalarType { TypeName: "int" or "uint" or "float" } => (4, 4), - ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 4), - VectorType v => (TypeSizeInBuffer(v.BaseType, typeModifier).Size * v.Size, 4), - // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later - MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => (TypeSizeInBuffer(m.BaseType, typeModifier).Size * ((4 * m.Columns - 1) + m.Rows), 4), - MatrixType m when typeModifier == TypeModifier.RowMajor => (TypeSizeInBuffer(m.BaseType, typeModifier).Size * ((4 * m.Rows - 1) + m.Columns), 4), - // Round up to 16 bytes (size of float4) - ArrayType a => ((TypeSizeInBuffer(a.BaseType, typeModifier).Size + 15) / 16 * 16 * a.Size, 16), - // TODO: StructureType - }; - - // - // Computes the size of a member type, including its alignment and array size. - // It does so recursively for structs, and handles different parameter classes. - // - static int ComputeCBufferOffset(SymbolType type, TypeModifier typeModifier, ref int constantBufferOffset) - { - (var size, var alignment) = TypeSizeInBuffer(type, typeModifier); - - // Align to float4 if it is bigger than leftover space in current float4 - if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16) - alignment = 16; - - // Align offset and store it as member offset - constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment; - - return size; - } - int RegisterStructuredType(string name, StructuredType structSymbol) { throw new InvalidOperationException(); @@ -317,7 +272,7 @@ public int DeclareStructuredType(string name, StructuredType structSymbol) for (var index = 0; index < structSymbol.Members.Count; index++) types[index] = GetOrRegister(structSymbol.Members[index].Type); - var result = Buffer.Add(new OpTypeStruct(Bound++, [.. types])); + var result = Add(new OpTypeStruct(Bound++, [.. types])); var id = result.IdResult ?? throw new InvalidOperationException(); AddName(id, name); for (var index = 0; index < structSymbol.Members.Count; index++) @@ -333,6 +288,7 @@ public int DeclareStructuredType(string name, StructuredType structSymbol) } Types[structSymbol] = id; + ReverseTypes[id] = structSymbol; return id; } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index bfcd57f97f..31e96f085e 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -76,13 +76,6 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); } - int currentBinding = 0; - foreach (var resource in analysisResult.Resources) - { - context.Add(new OpDecorate(resource, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(resource, ParameterizedFlags.DecorationBinding(currentBinding++))); - } - buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } From 669b226834db83a0806471522ddaef653cb07778 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 15:55:14 +0900 Subject: [PATCH 0542/1182] Handle duplicate cbuffer in same file --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 1 - .../Parsing/SDSL/AST/ShaderElements.cs | 1 - .../Spirv/Building/Builder.Functions.cs | 14 -------------- src/Stride.Shaders/Spirv/Building/Context.cs | 3 +-- 4 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 136515af69..8ec1c46c02 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -124,7 +124,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler storageClass = pointerType.StorageClass; context.Add(new OpVariable(registeredType, variable, storageClass, null)); - context.Variables.Add(Name, new(variable, registeredType, Name)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 32449f022d..0291c66f2d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -264,7 +264,6 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var variable = context.Bound++; // TODO: Add a StreamSDSL storage class? context.Add(new OpVariable(pointerType, variable, Specification.StorageClass.Uniform, null)); - context.Variables.Add(Name, new(variable, pointerType, Name)); context.AddName(variable, Name); for (var index = 0; index < Members.Count; index++) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 40cfe31fe9..8d7ff8a556 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -49,18 +49,4 @@ public SpirvValue AddFunctionParameter(SpirvContext context, string name, Symbol CurrentFunction!.Value.Parameters.Add(name, value); return value; } - public SpirvFunction CreateEntryPoint(SpirvContext context, ExecutionModel execModel, string name, FunctionType type, ReadOnlySpan variables, FunctionControlMask mask = FunctionControlMask.None) - { - Buffer.FluentAdd(new OpFunction(context.GetOrRegister(type.ReturnType), context.Bound++, mask, context.GetOrRegister(type)), out var func); - context.AddName(func, name); - context.SetEntryPoint(execModel, func, name, variables); - var result = new SpirvFunction(func.ResultId, name, type); - if(!variables.IsEmpty) - foreach(var p in variables) - context.AddName(context.Variables[p.Id.Name].Id, p.Id.Name); - CurrentFunction = result; - return result; - } - - } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 41ea86a608..9369e04b75 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -48,7 +48,6 @@ public class SpirvContext { public int Bound { get; set; } = 1; public string? Name { get; private set; } - public SortedList Variables { get; } = []; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; @@ -153,7 +152,7 @@ public void SetEntryPoint(ExecutionModel model, int function, string name, ReadO Span pvariables = stackalloc int[variables.Length]; int pos = 0; foreach (var v in variables) - pvariables[pos++] = Variables[v.Id.Name].Id; + pvariables[pos++] = v.IdRef; Buffer.Add(new OpEntryPoint(model, function, name, [.. pvariables])); } From 43d4827f58c4a9c34bc722a4648244b3268ff23b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 15:59:29 +0900 Subject: [PATCH 0543/1182] Add support for Matrix type --- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 5 +++++ src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 8af2b66e7e..b185a674c6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -91,6 +91,11 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var innerType = (ScalarType)types[vectorInstruction.ComponentType]; types.Add(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); } + else if (instruction.Op == Op.OpTypeMatrix && (OpTypeMatrix)instruction is { } matrixInstruction) + { + var innerType = (VectorType)types[matrixInstruction.ColumnType]; + types.Add(matrixInstruction.ResultId, new MatrixType(innerType.BaseType, innerType.Size, matrixInstruction.ColumnCount)); + } else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { var structName = names[typeStructInstruction.ResultId]; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9369e04b75..58163dc5fc 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -186,7 +186,7 @@ public int GetOrRegister(SymbolType? type) }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, - MatrixType m => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, + MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, ArrayType a => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), From 8ef02c00de8b2bfd019b38f0e1564bf55991740f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 21:47:52 +0900 Subject: [PATCH 0544/1182] Rewrote some of symbol resolution, so that cbuffer variables are accessible through inheritance and external classes --- assets/SDSL/RenderTests/CBuffer.sdsl | 6 +-- .../SDSL/ShaderMixer.MixinNode.cs | 1 - .../SDSL/ShaderMixer.cs | 30 ++++-------- src/Stride.Shaders/Core/Symbol.cs | 2 +- src/Stride.Shaders/Core/SymbolFrame.cs | 20 +++++++- src/Stride.Shaders/Core/SymbolTypes.cs | 41 ++++++++++++++-- .../Parsing/SDSL/AST/Expression.cs | 11 +++-- .../Parsing/SDSL/AST/Literals.cs | 36 ++++++++------ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 48 ++++++++++++++----- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Parsing/SDSL/AST/ShaderElements.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 21 ++++---- 12 files changed, 149 insertions(+), 73 deletions(-) diff --git a/assets/SDSL/RenderTests/CBuffer.sdsl b/assets/SDSL/RenderTests/CBuffer.sdsl index 0855cd7a31..011d2a5e0d 100644 --- a/assets/SDSL/RenderTests/CBuffer.sdsl +++ b/assets/SDSL/RenderTests/CBuffer.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1113FFFF, cbuffer.Test=(Test1=17, Test2=19)) +// PSMain(ExpectedResult=#1124FFFF, cbuffer.Test=(Test1=17, Test2=19)) namespace Stride.Shaders.Tests; @@ -28,12 +28,12 @@ shader CBuffer : Compute2 stream float4 ColorTarget : SV_Target0; cbuffer Test - { + { int Test2; } void PSMain() { - streams.ColorTarget = float4(Compute(), Test2 / 255.0, 1.0, 1.0); + streams.ColorTarget = float4(Compute(), (Test1 + Test2) / 255.0, 1.0, 1.0); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index ab39427e3b..fa6b39913c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -40,7 +40,6 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary ShadersByName { get; } = new(); public Dictionary MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); - public Dictionary VariablesByName { get; } = new(); public Dictionary Compositions { get; } = new(); public Dictionary ExternalShaders { get; } = new(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index fd47a91b9e..ad021e49fe 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -277,14 +277,14 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, //Console.WriteLine("Done SDSL importing"); //Spv.Dis(buffer, true); - new TypeDuplicateRemover().Apply(buffer); - - //Console.WriteLine("Done type remapping"); Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); // Import struct types ImportStructTypes(globalContext, buffer, mixinNode); + new TypeDuplicateRemover().Apply(buffer); + + //Console.WriteLine("Done type remapping"); Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); // Build names and types mappings @@ -526,11 +526,6 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, { currentShader = null; } - else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass == Specification.StorageClass.Private) - { - var variableName = globalContext.Names[variable.ResultId]; - mixinNode.VariablesByName.Add(variableName, variable.ResultId); - } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && @@ -668,8 +663,12 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB if (mixinNode.ExternalVariables.TryGetValue(memberAccess.Member, out var variable)) { - instanceMixinGroup.VariablesByName.TryGetValue(variable.Name, out var variableId); - memberAccesses.Add(memberAccess.ResultId, variableId); + var shaderName = mixinNode.ExternalShaders[variable.ShaderId]; + + var shaderInfo = mixinNode.ShadersByName[shaderName]; + if (!shaderInfo.Variables.TryGetValue(variable.Name, out var variableInfo)) + throw new InvalidOperationException($"External variable {variable.Name} not found"); + memberAccesses.Add(memberAccess.ResultId, variableInfo.Id); } else if (globalContext.Types[memberAccess.ResultType] is FunctionType) { @@ -711,8 +710,6 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB if (!baseMethodFound) throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionId]}"); - - SetOpNop(temp[index - 1].Data.Memory.Span); } else { @@ -738,15 +735,8 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB { memberAccesses.Clear(); } - else if (i.Data.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } functionCall) - { - if (memberAccesses.TryGetValue(functionCall.Function, out var functionId)) - { - functionCall.Function = functionId; - } - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - } + SpirvBuilder.RemapIds(memberAccesses, i); } } diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index f66bef596f..aeb7cd948b 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -46,7 +46,7 @@ public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); /// Defines a symbol. ///
/// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, bool ImplicitThis = false, ImmutableArray GroupMembers = default); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType ImplicitThisType = null, ImmutableArray GroupMembers = default); diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index d9942a8421..5cc2ba91d1 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -8,12 +8,19 @@ public class SymbolFrame() { readonly Dictionary symbols = []; + readonly List implicitShaders = []; + public Symbol this[string name] { get => symbols[name]; set => symbols[name] = value; } + public void AddImplicitShader(ShaderSymbol shaderSymbol) + { + implicitShaders.Add(shaderSymbol); + } + public void Add(string name, Symbol symbol) { if (symbol.Type is FunctionType && TryGetValue(name, out var existingSymbol)) @@ -37,7 +44,18 @@ public void Remove(string name) public bool ContainsKey(string name) => symbols.ContainsKey(name); public bool ContainsValue(Symbol symbol) => symbols.ContainsValue(symbol); public bool TryGetValue(string name, out Symbol symbol) - => symbols.TryGetValue(name, out symbol); + { + if (symbols.TryGetValue(name, out symbol)) + return true; + + foreach (var implicitShader in implicitShaders) + { + if (implicitShader.TryResolveSymbol(name, out symbol)) + return true; + } + + return false; + } public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 3f1631e564..647e28d7dc 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,8 +1,9 @@ -using System.Diagnostics.CodeAnalysis; -using System.Text; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Text; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Core; @@ -235,14 +236,17 @@ public override string ToString() public sealed record StreamsSymbol : SymbolType; -public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members); +public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members) +{ + public override string ToId() => $"type.{Name}"; +} public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { public List Components { get; init; } = []; - public List<(StructType Type, int ImportedId)> StructTypes { get; init; } = []; + public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; public string ToClassName() { @@ -252,6 +256,35 @@ public string ToClassName() var className = new ShaderClassInstantiation(Name, GenericArguments); return className.ToClassName(); } + + internal bool TryResolveSymbol(string name, out Symbol symbol) + { + foreach (var c in Components) + { + if (c.Id.Name == name) + { + symbol = c with { ImplicitThisType = c.Type }; + return true; + } + + if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) + { + for (int index = 0; index < cb.Members.Count; index++) + { + var member = cb.Members[index]; + if (member.Name == name) + { + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); + symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.IdRef, ImplicitThisType: c.Type, AccessChain: index); + return true; + } + } + } + } + + symbol = default; + return false; + } } public sealed record GenericLinkType : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 241cc580cc..b165145c75 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -91,7 +91,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { instance = builder.Insert(new OpBaseSDSL(context.Bound++)).ResultId; } - else if (functionSymbol.ImplicitThis) + else if (functionSymbol.ImplicitThisType is { } thisType) { var isStage = (functionSymbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; instance = isStage @@ -288,10 +288,13 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) // next start is i + 1 because current value doesn't add a call EmitOpAccessChain(i, i + 1, indexes); - var matchingComponent = s.Components.First(x => x.Id.Kind == SymbolKind.Variable && x.Id.Name == field.Name); + if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) + throw new InvalidOperationException(); + + // TODO: figure out instance (this vs composition) + result = Identifier.EmitSymbol(compiler, builder, context, matchingComponent); accessor.Type = matchingComponent.Type; - var inst = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(matchingComponent.Type), context.Bound++, result.Id, matchingComponent.IdRef)); - result = new(inst.ResultId, inst.ResultType); + break; case (PointerType { BaseType: StructType s } p, Identifier field): var index = s.TryGetFieldIndex(field); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 44de7549ee..b4a75d2ef7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -199,31 +199,39 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil { // Maybe it's a static variable? try to resolve by loading file var classSource = new ShaderClassInstantiation(Name, []); - classSource.Buffer = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); + classSource.Buffer = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, Name); var shaderType = ShaderClass.LoadExternalShaderType(table, classSource); + // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) ShaderClass.Inherit(table, context, shaderType, false); - // Let's add this shader - throw new NotImplementedException(); + symbol = table.ResolveSymbol(Name); } Type = symbol.Type; - var resultType = context.GetOrRegister(Type); - var result = new SpirvValue(symbol.IdRef, resultType, Name); + return EmitSymbol(compiler, builder, context, symbol); + } - if (symbol.AccessChain is int accessChainIndex) + public static SpirvValue EmitSymbol(CompilerUnit compiler, SpirvBuilder builder, SpirvContext context, Symbol symbol, int? instance = null) + { + var resultType = context.GetOrRegister(symbol.Type); + var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); + + if (symbol.ImplicitThisType is { } thisType) { - var index = context.CompileConstant(accessChainIndex).Id; - result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, symbol.IdRef, [index])); + var isStage = (symbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; + if (instance == null) + { + instance = isStage + ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId + : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + } + result.Id = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); } - else if (symbol.ImplicitThis is true) + if (symbol.AccessChain is int accessChainIndex) { - var isStage = (symbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; - var instance = isStage - ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId - : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; - result.Id = builder.Insert(new OpMemberAccessSDSL(resultType, context.Bound++, instance, symbol.IdRef)); + var index = context.CompileConstant(accessChainIndex).Id; + result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, result.Id, [index])); } return result; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index b185a674c6..b2f6f98a69 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -40,6 +40,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types) { var memberNames = new Dictionary<(int, int), string>(); + var blocks = new HashSet(); for (var i = start; i < end; i++) { var instruction = buffer[i]; @@ -53,6 +54,12 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end OpMemberName nameInstruction = instruction; memberNames.Add((nameInstruction.Type, nameInstruction.Member), nameInstruction.Name); } + else if (instruction.Op == Op.OpDecorate) + { + OpDecorate decorateInstruction = instruction; + if (decorateInstruction.Decoration.Value == Decoration.Block) + blocks.Add(decorateInstruction.Target); + } else if (instruction.Op == Op.OpTypeFloat) { OpTypeFloat floatInstruction = instruction; @@ -108,7 +115,10 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var name = memberNames[(typeStructInstruction.ResultId, index)]; fields.Add((name, type, TypeModifier.None)); } - types.Add(typeStructInstruction.ResultId, new StructType(structName, fields)); + StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) + ? new ConstantBufferSymbol(structName.StartsWith("type.") ? structName.Substring("type.".Length) : throw new InvalidOperationException(), fields) + : new StructType(structName, fields); + types.Add(typeStructInstruction.ResultId, structType); } else if (instruction.Op == Op.OpTypeFunction && new OpTypeFunction(instruction) is { } typeFunctionInstruction) { @@ -166,7 +176,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end // Can be declared before OpTypeStruct, so done in second pass if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) { - var structType = (StructType)types[memberDecorate.StructureType]; + var structType = (StructuredType)types[memberDecorate.StructureType]; if (memberDecorate.Decoration == Decoration.ColMajor) structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.ColumnMajor }; else if (memberDecorate.Decoration == Decoration.RowMajor) @@ -180,7 +190,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); var symbols = new List(); - var structTypes = new List<(StructType Type, int ImportedId)>(); + var structTypes = new List<(StructuredType Type, int ImportedId)>(); for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; @@ -211,7 +221,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { - structTypes.Add(((StructType)types[typeStructInstruction.ResultId], -1)); + structTypes.Add(((StructuredType)types[typeStructInstruction.ResultId], -1)); } if (instruction.Op == Op.OpSDSLGenericParameter) @@ -380,28 +390,44 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol foreach (var structType in shaderType.StructTypes) { // Add the struct like if it was part of our shader (but using the imported id) - context.Types.Add(structType.Type, structType.ImportedId); - context.ReverseTypes.Add(structType.ImportedId, structType.Type); table.DeclaredTypes.TryAdd(structType.Type.Name, structType.Type); } - foreach (var c in shaderType.Components) + if (addToRoot) + table.CurrentFrame.AddImplicitShader(shaderType); + /*foreach (var c in shaderType.Components) { if (c.Id.Kind == SymbolKind.Variable) { if (addToRoot) - table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThis = true }); + { + table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThisType = c.Type }); + + // cbuffer: add members + if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) + { + for (int index = 0; index < cb.Members.Count; index++) + { + var member = cb.Members[index]; + + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); + var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.IdRef, ImplicitThisType: c.Type, AccessChain: index); + + table.CurrentFrame.Add(member.Name, symbol); + } + } + } } else if (c.Id.Kind == SymbolKind.Method) { if (addToRoot) - table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThis = true }); + table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThisType = c.Type }); } - } + }*/ if (!addToRoot) { - var symbol = new Symbol(new(shaderType.Name, SymbolKind.Shader), shaderType, shaderId); + var symbol = new Symbol(new(shaderType.Name, SymbolKind.Shader), new PointerType(shaderType, Specification.StorageClass.Private), shaderId); table.CurrentFrame.Add(shaderType.Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 8ec1c46c02..bcf04ff1c6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -228,7 +228,7 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; - var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id, ImplicitThis: true); + var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id, ImplicitThisType: Type); table.CurrentShader.Components.Add(symbol); table.CurrentFrame.Add(Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 0291c66f2d..dc53acc757 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -204,7 +204,7 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com { var (builder, context) = compiler; var structType = (StructType)Type; - context.DeclareStructuredType(structType.ToId(), structType); + context.DeclareStructuredType(structType); } public override string ToString() @@ -270,7 +270,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { var member = Members[index]; var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, index); + var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, AccessChain: index); table.CurrentFrame.Add(member.Name, symbol); if (member.TypeModifier != TypeModifier.ColumnMajor) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 58163dc5fc..745c743c46 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -191,7 +191,7 @@ public int GetOrRegister(SymbolType? type) StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), - ShaderSymbol s => RegisterShaderType(s), + ShaderSymbol s => ImportShaderType(s), Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, @@ -207,7 +207,7 @@ public int GetOrRegister(SymbolType? type) } } - private int RegisterShaderType(ShaderSymbol shaderSymbol) + public int ImportShaderType(ShaderSymbol shaderSymbol) { FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); AddName(shader.ResultId, shaderSymbol.Name); @@ -216,10 +216,14 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); foreach (ref var structType in structTypes) { - FluentAdd(new OpSDSLImportStruct(Bound++, structType.Type.Name, shader.ResultId), out var @struct); + FluentAdd(new OpSDSLImportStruct(Bound++, structType.Type.ToId(), shader.ResultId), out var @struct); AddName(@struct.ResultId, structType.Type.Name); // Fill the ID structType.ImportedId = @struct.ResultId; + + // Register it so that it can be used right after during OpVariable for cbuffer + Types.Add(structType.Type, structType.ImportedId); + ReverseTypes.Add(structType.ImportedId, structType.Type); } // Import variables/functions @@ -237,11 +241,6 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) } else if (c.Id.Kind == SymbolKind.Variable) { - // Currently, we ignore cbuffer - // TOOD: review that - if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is StructType) - continue; - c.IdRef = Bound++; Add(new OpSDSLImportVariable(c.IdRef, GetOrRegister(c.Type), c.Id.Name, shader.ResultId)); AddName(c.IdRef, c.Id.Name); @@ -253,7 +252,7 @@ private int RegisterShaderType(ShaderSymbol shaderSymbol) public int DeclareCBuffer(ConstantBufferSymbol cb) { - var result = DeclareStructuredType($"type.{cb.ToId()}", cb); + var result = DeclareStructuredType(cb); Buffer.Add(new OpDecorate(result, Decoration.Block)); @@ -265,7 +264,7 @@ int RegisterStructuredType(string name, StructuredType structSymbol) throw new InvalidOperationException(); } - public int DeclareStructuredType(string name, StructuredType structSymbol) + public int DeclareStructuredType(StructuredType structSymbol) { Span types = stackalloc int[structSymbol.Members.Count]; for (var index = 0; index < structSymbol.Members.Count; index++) @@ -273,7 +272,7 @@ public int DeclareStructuredType(string name, StructuredType structSymbol) var result = Add(new OpTypeStruct(Bound++, [.. types])); var id = result.IdResult ?? throw new InvalidOperationException(); - AddName(id, name); + AddName(id, structSymbol.ToId()); for (var index = 0; index < structSymbol.Members.Count; index++) { var member = structSymbol.Members[index]; From 68ebb65ea79c8aa68443e3e89083d039a52b15d0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 3 Dec 2025 21:55:34 +0900 Subject: [PATCH 0545/1182] Use CompileAsValue for all intrinsics --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 174 +++++++++--------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 011969fe64..b77b42b01a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -13,7 +13,7 @@ public class RoundCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLRound(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -25,7 +25,7 @@ public class RoundEvenCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLRoundEven(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -37,7 +37,7 @@ public class TruncCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLTrunc(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -49,11 +49,11 @@ public class AbsCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var elementType = Parameters.Values[0].Type.GetElementType(); + var elementType = Parameters.Values[0].ValueType.GetElementType(); if (elementType.IsFloating()) { var instruction = builder.Insert(new GLSLFAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -75,11 +75,11 @@ public class SignCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var elementType = Parameters.Values[0].Type.GetElementType(); + var elementType = Parameters.Values[0].ValueType.GetElementType(); if (elementType.IsFloating()) { var instruction = builder.Insert(new GLSLFSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -101,7 +101,7 @@ public class FloorCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFloor(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -113,7 +113,7 @@ public class CeilCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLCeil(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -125,7 +125,7 @@ public class FractCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFract(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -137,7 +137,7 @@ public class RadiansCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var radians = Parameters.Values[0].Compile(table, shader, compiler); + var radians = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLRadians(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); @@ -149,7 +149,7 @@ public class DegreesCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var radians = Parameters.Values[0].Compile(table, shader, compiler); + var radians = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLDegrees(radians.TypeId, context.Bound++, context.GLSLSet ?? -1, radians.Id)); @@ -161,7 +161,7 @@ public class SinCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -173,7 +173,7 @@ public class CosCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLCos(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -185,7 +185,7 @@ public class TanCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLTan(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -197,7 +197,7 @@ public class AsinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAsin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -209,7 +209,7 @@ public class AcosCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAcos(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -221,7 +221,7 @@ public class AtanCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var y_over_x = Parameters.Values[0].Compile(table, shader, compiler); + var y_over_x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAtan(y_over_x.TypeId, context.Bound++, context.GLSLSet ?? -1, y_over_x.Id)); @@ -233,7 +233,7 @@ public class SinhCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSinh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -245,7 +245,7 @@ public class CoshCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLCosh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -257,7 +257,7 @@ public class TanhCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLTanh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -269,7 +269,7 @@ public class AsinhCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAsinh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -281,7 +281,7 @@ public class AcoshCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAcosh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -293,7 +293,7 @@ public class AtanhCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAtanh(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -305,7 +305,7 @@ public class Atan2Call(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLAtan2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -317,7 +317,7 @@ public class PowCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -329,7 +329,7 @@ public class ExpCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLExp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -341,7 +341,7 @@ public class LogCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLLog(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -353,7 +353,7 @@ public class Exp2Call(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLExp2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -365,7 +365,7 @@ public class Log2Call(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLLog2(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -377,7 +377,7 @@ public class SqrtCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSqrt(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -389,7 +389,7 @@ public class InverseSqrtCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLInverseSqrt(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -401,10 +401,10 @@ public class DeterminantCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var resultType = Parameters.Values[0].Type.GetElementType(); + var resultType = Parameters.Values[0].ValueType.GetElementType(); var instruction = builder.Insert(new GLSLDeterminant(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } @@ -414,7 +414,7 @@ public class MatrixInverseCall(ShaderExpressionList parameters, TextLocation inf public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLMatrixInverse(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -426,7 +426,7 @@ public class ModfCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, i) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, i) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLModf(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, i.Id)); @@ -438,7 +438,7 @@ public class ModfStructCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLModfStruct(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -450,7 +450,7 @@ public class FMinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -462,7 +462,7 @@ public class UMinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -474,7 +474,7 @@ public class SMinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -486,7 +486,7 @@ public class FMaxCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -498,7 +498,7 @@ public class UMaxCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -510,7 +510,7 @@ public class SMaxCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -522,7 +522,7 @@ public class FClampCall(ShaderExpressionList parameters, TextLocation info) : Me public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); @@ -534,7 +534,7 @@ public class UClampCall(ShaderExpressionList parameters, TextLocation info) : Me public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); @@ -546,7 +546,7 @@ public class SClampCall(ShaderExpressionList parameters, TextLocation info) : Me public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); @@ -558,7 +558,7 @@ public class FMixCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y, a) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); @@ -570,7 +570,7 @@ public class IMixCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y, a) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLIMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); @@ -582,7 +582,7 @@ public class StepCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (edge, x) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (edge, x) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLStep(edge.TypeId, context.Bound++, context.GLSLSet ?? -1, edge.Id, x.Id)); @@ -594,7 +594,7 @@ public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (edge0, edge1, x) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (edge0, edge1, x) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLSmoothStep(edge0.TypeId, context.Bound++, context.GLSLSet ?? -1, edge0.Id, edge1.Id, x.Id)); @@ -606,7 +606,7 @@ public class FmaCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (a, b, c) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (a, b, c) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GLSLSet ?? -1, a.Id, b.Id, a.Id)); @@ -618,7 +618,7 @@ public class FrexpCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, exp) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, exp) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFrexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); @@ -630,7 +630,7 @@ public class FrexpStructCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLMatrixInverse(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -642,7 +642,7 @@ public class LdexpCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, exp) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, exp) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLLdexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); @@ -654,7 +654,7 @@ public class PackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackSnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -666,7 +666,7 @@ public class PackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackUnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -678,7 +678,7 @@ public class PackSnorm2x16Call(ShaderExpressionList parameters, TextLocation inf public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackSnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -690,7 +690,7 @@ public class PackUnorm2x16Call(ShaderExpressionList parameters, TextLocation inf public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackUnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -702,7 +702,7 @@ public class PackHalf2x16Call(ShaderExpressionList parameters, TextLocation info public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -714,7 +714,7 @@ public class PackDouble2x32Call(ShaderExpressionList parameters, TextLocation in public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPackDouble2x32(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -726,7 +726,7 @@ public class UnpackSnorm2x16Call(ShaderExpressionList parameters, TextLocation i public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); + var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackSnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); @@ -738,7 +738,7 @@ public class UnpackUnorm2x16Call(ShaderExpressionList parameters, TextLocation i public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); + var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackUnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); @@ -750,7 +750,7 @@ public class UnpackHalf2x16Call(ShaderExpressionList parameters, TextLocation in public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].Compile(table, shader, compiler); + var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); @@ -762,7 +762,7 @@ public class UnpackSnorm4x8Call(ShaderExpressionList parameters, TextLocation in public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); + var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackSnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); @@ -774,7 +774,7 @@ public class UnpackUnorm4x8Call(ShaderExpressionList parameters, TextLocation in public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); + var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackUnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); @@ -786,7 +786,7 @@ public class UnpackDouble2x32Call(ShaderExpressionList parameters, TextLocation public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var p = Parameters.Values[0].Compile(table, shader, compiler); + var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLUnpackDouble2x32(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); @@ -798,10 +798,10 @@ public class LengthCall(ShaderExpressionList parameters, TextLocation info) : Me public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var resultType = Parameters.Values[0].Type.GetElementType(); + var resultType = Parameters.Values[0].ValueType.GetElementType(); var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } @@ -811,7 +811,7 @@ public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (p0, p1) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (p0, p1) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLDistance(p0.TypeId, context.Bound++, context.GLSLSet ?? -1, p0.Id, p1.Id)); @@ -823,7 +823,7 @@ public class CrossCall(ShaderExpressionList parameters, TextLocation info) : Met public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLCross(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -835,7 +835,7 @@ public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var x = Parameters.Values[0].Compile(table, shader, compiler); + var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLNormalize(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -847,7 +847,7 @@ public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (N, I, Nre) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (N, I, Nre) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GLSLSet ?? -1, N.Id, I.Id, Nre.Id)); @@ -859,7 +859,7 @@ public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (I, N) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (I, N) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLReflect(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id)); @@ -871,7 +871,7 @@ public class RefractCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (I, N, eta) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (I, N, eta) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLRefract(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id, eta.Id)); @@ -883,7 +883,7 @@ public class FindILsbCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var value = Parameters.Values[0].Compile(table, shader, compiler); + var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFindILsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); @@ -895,7 +895,7 @@ public class FindSMsbCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var value = Parameters.Values[0].Compile(table, shader, compiler); + var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFindSMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); @@ -907,7 +907,7 @@ public class FindUMsbCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var value = Parameters.Values[0].Compile(table, shader, compiler); + var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLFindUMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); @@ -919,7 +919,7 @@ public class InterpolateAtCentroidCall(ShaderExpressionList parameters, TextLoca public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var interpolant = Parameters.Values[0].Compile(table, shader, compiler); + var interpolant = Parameters.Values[0].CompileAsValue(table, shader, compiler); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLInterpolateAtCentroid(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id)); @@ -931,7 +931,7 @@ public class InterpolateAtSampleCall(ShaderExpressionList parameters, TextLocati public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (interpolant, sample) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (interpolant, sample) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLInterpolateAtSample(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, sample.Id)); @@ -943,7 +943,7 @@ public class InterpolateAtOffsetCall(ShaderExpressionList parameters, TextLocati public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (interpolant, offset) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (interpolant, offset) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLInterpolateAtOffset(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, offset.Id)); @@ -955,7 +955,7 @@ public class NMinCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLNMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -967,7 +967,7 @@ public class NMaxCall(ShaderExpressionList parameters, TextLocation info) : Meth public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLNMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -979,7 +979,7 @@ public class NClampCall(ShaderExpressionList parameters, TextLocation info) : Me public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler), Parameters.Values[2].Compile(table, shader, compiler)); + var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLNClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); @@ -991,17 +991,17 @@ public class MulCall(ShaderExpressionList parameters, TextLocation info) : Metho public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].Compile(table, shader, compiler), Parameters.Values[1].Compile(table, shader, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var xType = Parameters.Values[0].Type; - var yType = Parameters.Values[1].Type; + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; if (xType.GetElementType() != yType.GetElementType()) throw new NotImplementedException("mul type conversion is currently not implemented"); - if (!xType.IsFloating()) + if (!xType.GetElementType().IsFloating()) throw new NotImplementedException("Only implemented for floating types"); // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul From 723e2a15043f47fe32d931772b8973200315897c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 11:05:09 +0900 Subject: [PATCH 0546/1182] Added support for swizzle (not yet for l-value though) --- assets/SDSL/RenderTests/Swizzle.sdsl | 46 +++++++ src/Stride.Shaders.Tests/TestHeaderParser.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 127 ++++++++++++++++-- .../Parsing/SDSL/AST/Literals.cs | 2 +- .../Parsing/SDSL/AST/SymbolTypeProcess.cs | 62 --------- 5 files changed, 163 insertions(+), 76 deletions(-) create mode 100644 assets/SDSL/RenderTests/Swizzle.sdsl delete mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs diff --git a/assets/SDSL/RenderTests/Swizzle.sdsl b/assets/SDSL/RenderTests/Swizzle.sdsl new file mode 100644 index 0000000000..159d8df42e --- /dev/null +++ b/assets/SDSL/RenderTests/Swizzle.sdsl @@ -0,0 +1,46 @@ +// PSMain(ExpectedResult=#04040403, cbuffer.Test=(Test1=0)) +// PSMain(ExpectedResult=#01020101, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#04030201, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#04040302, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#01010101, cbuffer.Test=(Test1=4)) +// PSMain(ExpectedResult=#02040608, cbuffer.Test=(Test1=5)) +// PSMain(ExpectedResult=#02020202, cbuffer.Test=(Test1=6)) + +namespace Stride.Shaders.Tests; + +shader Swizzle +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(1.0 / 255.0, 2.0 / 255.0, 3.0 / 255.0, 4.0 / 255.0); + if (Test1 == 0) + streams.ColorTarget = streams.ColorTarget.wwwz; + if (Test1 == 1) + streams.ColorTarget = streams.ColorTarget.xyxx; + if (Test1 == 2) + streams.ColorTarget = streams.ColorTarget.wzyx; + if (Test1 == 3) + streams.ColorTarget = streams.ColorTarget.wzyx.xxyz; + if (Test1 == 4) + // Convert to scalar and back to vector + streams.ColorTarget = streams.ColorTarget.x.xxxx; + if (Test1 == 5) + // second swizzle is from a non-pointer value and will use OpVectorShuffle + streams.ColorTarget = (streams.ColorTarget.xyzw * 2).xyzw; + if (Test1 == 6) + // second swizzle is from a non-pointer value and will use OpCompositeExtract + streams.ColorTarget = (streams.ColorTarget.xyzw * 2).x.xxxx; + // TODO: swizzle target is not supported yet + //if (Test1 == 7) + // streams.ColorTarget.wxyz = streams.ColorTarget; + //if (Test1 == 8) + // streams.ColorTarget.wxyz.wyxz = streams.ColorTarget; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/TestHeaderParser.cs b/src/Stride.Shaders.Tests/TestHeaderParser.cs index 37ae5a3d8c..02b5879a1f 100644 --- a/src/Stride.Shaders.Tests/TestHeaderParser.cs +++ b/src/Stride.Shaders.Tests/TestHeaderParser.cs @@ -35,7 +35,7 @@ public static IEnumerable ParseHeaders(IEnumerable lines) foreach (var line in lines) { var m = HeaderRegex.Match(line); - if (!m.Success) continue; + if (!m.Success) break; var name = m.Groups["name"].Value.Trim(); var args = m.Groups["args"].Value; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index b165145c75..550e62f397 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -254,31 +254,36 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } else { - int lastCreatedChainStart = firstIndex; - void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) + int accessChainIdCount = 0; + void PushAccessChainId(Span accessChainIds, int accessChainIndex) + { + accessChainIds[accessChainIdCount++] = accessChainIndex; + } + void EmitOpAccessChain(Span accessChainIds) { // Do we need to issue an OpAccessChain? - if (currentIndex > lastCreatedChainStart) + if (accessChainIdCount > 0) { var resultType = context.GetOrRegister(currentValueType); - var test = new LiteralArray(indexes); - var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. indexes.Slice(lastCreatedChainStart, currentIndex - lastCreatedChainStart)])); + var test = new LiteralArray(accessChainIds); + var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); result = new SpirvValue(accessChain.ResultId, resultType); } - lastCreatedChainStart = nextStart; + accessChainIdCount = 0; } - Span indexes = stackalloc int[Accessors.Count]; + Span accessChainIds = stackalloc int[Accessors.Count]; for (var i = firstIndex; i < Accessors.Count; i++) { var accessor = Accessors[i]; + ProcessAgain: switch (currentValueType, accessor) { case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): // Emit OpAccessChain with everything so far // next start is i + 1 because current value doesn't add a call - EmitOpAccessChain(i, i + 1, indexes); + EmitOpAccessChain(accessChainIds); methodCall2.MemberCall = result; result = methodCall2.Compile(table, shader, compiler); @@ -286,7 +291,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) case (PointerType { BaseType: ShaderSymbol s }, Identifier field): // Emit OpAccessChain with everything so far // next start is i + 1 because current value doesn't add a call - EmitOpAccessChain(i, i + 1, indexes); + EmitOpAccessChain(accessChainIds); if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) throw new InvalidOperationException(); @@ -297,14 +302,103 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) break; case (PointerType { BaseType: StructType s } p, Identifier field): + var index = s.TryGetFieldIndex(field); if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - indexes[i] = context.CompileConstant(index).Id; + PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); break; - // TODO: Swizzle, etc. + // Swizzles + case (PointerType { BaseType: VectorType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + // For swizzle larger than one element, we need to do a OpLoad then do a OpVectorShuffle/OpCompositeExtract (next switch case) + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + + var load = builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null)); + result = new(load); + + currentValueType = s; + + goto ProcessAgain; + } + else + { + PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); + accessor.Type = new PointerType(s.BaseType, p.StorageClass); + } + break; + case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + + if (swizzle.Length > 1) + { + // Apply swizzle + var resultType = new VectorType(v.BaseType, swizzle.Length); + var shuffle = builder.InsertData(new OpVectorShuffle(context.GetOrRegister(resultType), context.Bound++, result.Id, result.Id, new(swizzleIndices))); + result = new(shuffle); + + accessor.Type = resultType; + } + else if (swizzle.Length == 1) + { + // Apply swizzle + var resultType = v.BaseType; + var extract = builder.InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, result.Id, [context.CompileConstant(swizzleIndices[0]).Id])); + result = new(extract); + + accessor.Type = resultType; + } + else + throw new InvalidOperationException(); + + break; + case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + // For swizzle larger than one element, we need to do a OpLoad then do a OpVectorShuffle/OpCompositeExtract (next switch case) + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + + var load = builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null)); + result = new(load); + + currentValueType = s; + + goto ProcessAgain; + } + else + { + // Do nothing + accessor.Type = currentValueType; + } + break; + case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + var resultType = new VectorType(s, swizzle.Length); + Span constructIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < constructIndices.Length; ++j) + constructIndices[j] = result.Id; + var construct = builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, new(constructIndices))); + result = new(construct); + + accessor.Type = resultType; + } + else + { + // Do nothing + accessor.Type = currentValueType; + } + break; default: throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); } @@ -312,7 +406,7 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) currentValueType = accessor.Type; } - EmitOpAccessChain(Accessors.Count, Accessors.Count, indexes); + EmitOpAccessChain(accessChainIds); } Type = currentValueType; @@ -320,6 +414,15 @@ void EmitOpAccessChain(int currentIndex, int nextStart, Span indexes) return result; } + private static int ConvertSwizzle(char c) + => c switch + { + 'x' or 'r' => 0, + 'y' or 'g' => 1, + 'z' or 'b' => 2, + 'w' or 'a' => 3, + }; + public override string ToString() { var builder = new StringBuilder().Append(Source); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index b4a75d2ef7..724fe49963 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -242,7 +242,7 @@ public override string ToString() return $"{Name}"; } - public bool IsSwizzle() + public bool IsVectorSwizzle() { if (Name.Length > 4) return false; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs b/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs deleted file mode 100644 index 8650ccc92d..0000000000 --- a/src/Stride.Shaders/Parsing/SDSL/AST/SymbolTypeProcess.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Stride.Shaders.Core; - -namespace Stride.Shaders.Parsing.SDSL.AST; - -public static class SymbolTypeProcessExtension -{ - public static bool TryAccess(this SymbolType symbol, Expression expression, out SymbolType? type) - { - type = null; - if( - symbol is ScalarType or VectorType - && expression is Identifier swizzle - && swizzle.IsSwizzle() - ) - { - if(symbol.TrySwizzle(swizzle, out type)) - { - swizzle.Type = type; - return true; - } - else throw new NotImplementedException(); - } - else if(symbol is MatrixType matrix && expression is Identifier matrixField && matrixField.IsMatrixField()) - { - type = matrix.BaseType; - matrixField.Type = type; - return true; - } - else if(symbol is StructType s && expression is Identifier field) - { - if(s.TryGetFieldType(field, out var ft)) - { - type = ft; - field.Type = ft; - return true; - } - else throw new NotImplementedException($"field {field} not found in type {s}"); - } - return false; - } - public static bool TrySwizzle(this SymbolType symbol, string swizzle, out SymbolType? type) - { - type = null; - if(symbol is ScalarType s) - { - foreach(var c in swizzle) - if(c != 'r' || c != 'x') - return false; - type = new VectorType(s, swizzle.Length); - return true; - } - else if(symbol is VectorType v) - { - if(swizzle.Length == 1) - type = v.BaseType; - else - type = new VectorType(v.BaseType, swizzle.Length); - return true; - } - else return false; - } -} \ No newline at end of file From 3fc1c4972101b5dbb8e894327df4bd54e6221580 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 11:12:58 +0900 Subject: [PATCH 0547/1182] Added dot() and normalize() intrinsic --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 23 +++++++++++++++++++ .../PrimaryExpressionParsers.cs | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index b77b42b01a..e3f7dd25f7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -830,6 +830,29 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil return new(instruction.ResultId, instruction.ResultType); } } + +public class DotCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("dot", info), parameters, info) +{ + public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); + + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[0].ValueType; + + if (xType != yType) + throw new NotImplementedException("dot needs to be applied on same types"); + + if (!xType.GetElementType().IsFloating()) + throw new NotImplementedException("dot: only implemented for floating types"); + + var resultType = xType.GetElementType(); + + var instruction = builder.Insert(new OpDot(context.GetOrRegister(resultType), context.Bound++, x.Id, y.Id)); + return new(instruction.ResultId, instruction.ResultType); + } +} public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("normalize", info), parameters, info) { public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index ae86a20795..b48e2ea714 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -87,7 +87,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), ("distance", _) => throw new NotImplementedException(), - ("dot", _) => throw new NotImplementedException(), + ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), ("dst", _) => throw new NotImplementedException(), ("errorf", _) => throw new NotImplementedException(), ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), @@ -136,7 +136,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("msad4", _) => throw new NotImplementedException(), ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), ("noise", _) => throw new NotImplementedException(), - ("normalize", _) => throw new NotImplementedException(), + ("normalize", _) => new NormalizeCall(parameters, scanner[position..scanner.Position]), ("pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), ("printf", _) => throw new NotImplementedException(), ("Process2DQuadTessFactorsAvg", _) => throw new NotImplementedException(), From e51e7ef2f4f7224f1b595b08fe9ed3a3fab872ee Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 11:24:27 +0900 Subject: [PATCH 0548/1182] Expression: ensure Type is set --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 162 +++++++++--------- .../Parsing/SDSL/AST/Expression.cs | 26 ++- .../Parsing/SDSL/AST/Literals.cs | 16 +- 3 files changed, 106 insertions(+), 98 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index e3f7dd25f7..c835095a32 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -10,7 +10,7 @@ namespace Stride.Shaders.Parsing.SDSL; public class RoundCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("round", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -22,7 +22,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class RoundEvenCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("roundeven", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -34,7 +34,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class TruncCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("trunc", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -46,7 +46,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -72,7 +72,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SignCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fsign", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -98,7 +98,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FloorCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("floor", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -110,7 +110,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class CeilCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ceil", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -122,7 +122,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fract", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -134,7 +134,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class RadiansCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("radians", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var radians = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -146,7 +146,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class DegreesCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("degrees", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var radians = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -158,7 +158,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -170,7 +170,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class CosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cos", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -182,7 +182,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class TanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tan", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -194,7 +194,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AsinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -206,7 +206,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AcosCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acos", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -218,7 +218,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AtanCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var y_over_x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -230,7 +230,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sinh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -242,7 +242,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class CoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cosh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -254,7 +254,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class TanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("tanh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -266,7 +266,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AsinhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("asinh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -278,7 +278,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AcoshCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("acosh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -290,7 +290,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class AtanhCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atanh", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -302,7 +302,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class Atan2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("atan2", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -314,7 +314,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PowCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -326,7 +326,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class ExpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -338,7 +338,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class LogCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -350,7 +350,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class Exp2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("exp2", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -362,7 +362,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class Log2Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("log2", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -374,7 +374,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sqrt", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -386,7 +386,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class InverseSqrtCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("inversesqrt", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -398,7 +398,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class DeterminantCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("determinant", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -411,7 +411,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class MatrixInverseCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("matrixinverse", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -423,7 +423,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class ModfCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modf", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, i) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -435,7 +435,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class ModfStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("modfstruct", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -447,7 +447,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -459,7 +459,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -471,7 +471,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -483,7 +483,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmax", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -495,7 +495,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umax", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -507,7 +507,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smax", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -519,7 +519,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fclamp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -531,7 +531,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("uclamp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -543,7 +543,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sclamp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -555,7 +555,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmix", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -567,7 +567,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class IMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("imix", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -579,7 +579,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class StepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("step", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (edge, x) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -591,7 +591,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smoothstep", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (edge0, edge1, x) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -603,7 +603,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FmaCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fma", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (a, b, c) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -615,7 +615,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FrexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, exp) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -627,7 +627,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FrexpStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexpstruct", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -639,7 +639,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class LdexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ldexp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, exp) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -651,7 +651,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm4x8", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -663,7 +663,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm4x8", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -675,7 +675,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -687,7 +687,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -699,7 +699,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packhalf2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -711,7 +711,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class PackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packdouble2x32", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -723,7 +723,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -735,7 +735,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -747,7 +747,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackhalf2x16", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var v = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -759,7 +759,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm4x8", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -771,7 +771,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm4x8", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -783,7 +783,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class UnpackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackdouble2x32", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var p = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -795,7 +795,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class LengthCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("length", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -808,7 +808,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("distance", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (p0, p1) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -820,7 +820,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class CrossCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cross", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -833,7 +833,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil public class DotCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("dot", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -855,7 +855,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("normalize", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -867,7 +867,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("faceforward", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (N, I, Nre) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -879,7 +879,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("reflect", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (I, N) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -891,7 +891,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class RefractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("refract", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (I, N, eta) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -903,7 +903,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FindILsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findilsb", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -915,7 +915,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FindSMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findsmsb", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -927,7 +927,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class FindUMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findumsb", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var value = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -939,7 +939,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class InterpolateAtCentroidCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatcentroid", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var interpolant = Parameters.Values[0].CompileAsValue(table, shader, compiler); @@ -951,7 +951,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class InterpolateAtSampleCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatsample", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (interpolant, sample) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -963,7 +963,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class InterpolateAtOffsetCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatoffset", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (interpolant, offset) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -975,7 +975,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class NMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmin", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -987,7 +987,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class NMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmax", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); @@ -999,7 +999,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class NClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nclamp", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); @@ -1011,7 +1011,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil } public class MulCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 550e62f397..925bc7a0c7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -16,7 +16,15 @@ namespace Stride.Shaders.Parsing.SDSL.AST; ///
public abstract class Expression(TextLocation info) : ValueNode(info) { - public abstract SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); + public SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + var result = CompileImpl(table, shader, compiler); + // In case type is not computed yet, make sure it is using SpirvValue.TypeId + Type ??= compiler.Context.ReverseTypes[result.TypeId]; + return result; + } + + public abstract SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler); public SymbolType? ValueType => Type is PointerType pointerType ? pointerType.BaseType : Type; @@ -35,7 +43,7 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public SpirvValue? MemberCall { get; set; } public bool IsBaseCall { get; set; } = false; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; @@ -117,7 +125,7 @@ public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) { public Mixin Mixin { get; set; } = mixin; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -136,7 +144,7 @@ public abstract class UnaryExpression(Expression expression, Operator op, TextLo public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var expression = Expression.CompileAsValue(table, shader, compiler); @@ -163,7 +171,7 @@ public class CastExpression(TypeName typeName, Operator op, Expression expressio { public TypeName TypeName { get; set; } = typeName; - public unsafe override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public unsafe override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var castType = TypeName.ResolveType(table); @@ -179,7 +187,7 @@ public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -194,7 +202,7 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; SpirvValue result; @@ -443,7 +451,7 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var left = Left.CompileAsValue(table, shader, compiler); var right = Right.CompileAsValue(table, shader, compiler); @@ -466,7 +474,7 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { Condition.CompileAsValue(table, shader, compiler); Left.CompileAsValue(table, shader, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 724fe49963..ff26c57461 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -21,7 +21,7 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); @@ -32,7 +32,7 @@ public override SpirvValue Compile(SymbolTable table, ShaderClass shader, Compil public override SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { // Since we use type 0, CompileAsValue won't work - return Compile(table, shader, compiler); + return CompileImpl(table, shader, compiler); } public override string ToString() @@ -66,7 +66,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -77,7 +77,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -94,7 +94,7 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.From("bool"); - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -114,7 +114,7 @@ public bool IsConstant() public abstract SymbolType GenerateType(SymbolTable table); - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { // TODO: avoid duplicates var (builder, context) = compiler; @@ -191,7 +191,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; @@ -334,7 +334,7 @@ public SymbolType ResolveType(SymbolTable table) return result; } - public override SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { throw new NotImplementedException(); } From 439157b77c8b91e5e19e94606bcef33f4ac83c30 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 17:23:59 +0900 Subject: [PATCH 0549/1182] Added support for floatX and floatXxY ctor() and array accessors --- assets/SDSL/RenderTests/CompositeCtor.sdsl | 39 +++++++++ .../Parsing/SDSL/AST/Expression.cs | 30 ++++++- .../Parsing/SDSL/AST/Literals.cs | 82 ++++++++++++------- .../ExpressionParsers/UnaryParsers.Postfix.cs | 2 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 5 +- .../Spirv/Building/Builder.Expressions.cs | 12 +-- 6 files changed, 129 insertions(+), 41 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositeCtor.sdsl diff --git a/assets/SDSL/RenderTests/CompositeCtor.sdsl b/assets/SDSL/RenderTests/CompositeCtor.sdsl new file mode 100644 index 0000000000..48d2e4d02f --- /dev/null +++ b/assets/SDSL/RenderTests/CompositeCtor.sdsl @@ -0,0 +1,39 @@ +// PSMain(ExpectedResult=#01020203, cbuffer.Test=(Test1=0)) +// PSMain(ExpectedResult=#01040403, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#01060606, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#02020101, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#06060101, cbuffer.Test=(Test1=4)) + +namespace Stride.Shaders.Tests; + +shader CompositeCtor +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + float f1 = 1.0 / 255.0; + float2 f2 = 2.0 / 255.0; + float2x2 f2x2 = float2x2(f1, f2 * 2.0, f1 * 3.0); + float3 f3 = float3(f1, f2 * 3.0); + float4 f4 = float4(f3, f1); + + float3x3 m = float3x3(f3, f2, f4); + + if (Test1 == 0) + streams.ColorTarget = float4(f1, f2, f1 * 3.0); + if (Test1 == 1) + streams.ColorTarget = float4(f2x2); + if (Test1 == 2) + streams.ColorTarget = m[0].xyzz; + if (Test1 == 3) + streams.ColorTarget = m[1].xyzz; + if (Test1 == 4) + streams.ColorTarget = m[2].xyzz; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 925bc7a0c7..fdcfa5bec3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -183,6 +183,21 @@ public unsafe override SpirvValue CompileImpl(SymbolTable table, ShaderClass sha } } + +public class IndexerExpression(Expression index, TextLocation info) : Expression(info) +{ + public Expression Index { get; set; } = index; + + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + public override string ToString() + { + return $"[{Index}]"; + } +} + public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; @@ -407,6 +422,17 @@ void EmitOpAccessChain(Span accessChainIds) accessor.Type = currentValueType; } break; + // Array indexer + case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): + var indexerValue = indexer.Index.CompileAsValue(table, shader, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + + accessor.Type = new PointerType(p.BaseType switch + { + MatrixType m => new VectorType(m.BaseType, m.Rows), + VectorType v => v.BaseType, + }, p.StorageClass); + break; default: throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); } @@ -435,8 +461,8 @@ public override string ToString() { var builder = new StringBuilder().Append(Source); foreach (var a in Accessors) - if (a is NumberLiteral) - builder.Append('[').Append(a).Append(']'); + if (a is IndexerExpression) + builder.Append(a); else if (a is PostfixIncrement) builder.Append(a); else diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ff26c57461..5dff0cdefc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -116,39 +116,68 @@ public bool IsConstant() public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - // TODO: avoid duplicates var (builder, context) = compiler; - Span values = stackalloc int[Values.Count]; - int tmp = 0; - foreach (var v in Values) - values[tmp++] = v.Compile(table, shader, compiler).Id; Type = GenerateType(table); - return builder.CompositeConstruct(context, this, [.. values]); - } -} -public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) -{ - public TypeName TypeName { get; set; } = typeName; + (var compositeCount, var totalCount) = Type switch + { + VectorType v => (v.Size, v.Size), + MatrixType m => (m.Rows, m.Columns * m.Rows), + }; - public override SymbolType GenerateType(SymbolTable table) - { - var result = TypeName.ResolveType(table); + Span values = stackalloc int[totalCount]; + Span compositeValues = stackalloc int[compositeCount]; - var tmp = (VectorType)result ?? throw new NotImplementedException(); - foreach (var v in Values) + // Note: There are a lot of opportunity to optimize by working with vector-to-vector copy (if they align correctly) and/or OpVectorShuffle, but it can get quite complex to handle all cases + // However, it is probably optimized by SPIRV-Cross or the compiler/driver, so maybe not worth optimzing (due to increased code cases/complexity) + var elementIndex = 0; + foreach (var sourceValue in Values) { - if ( - v.Type is ScalarType st && tmp.BaseType != st - || (v.Type is VectorType vt && vt.BaseType != tmp.BaseType) - || (v.Type is VectorType vt2 && vt2.Size > tmp.Size) - ) - table.Errors.Add(new(v.Info, SDSLErrorMessages.SDSL0106)); + var value = sourceValue.CompileAsValue(table, shader, compiler); + var valueType = sourceValue.ValueType; + + // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) + var elementType = valueType.GetElementType(); + for (int i = 0; i < valueType.GetElementCount(); ++i) + { + SpirvValue extractedValue = valueType switch + { + MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i / m.Rows, i % m.Rows]))), + VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i]))), + ScalarType s => value, + }; + // If too many elments, keep counting so that exception is still thrown a bit later, with total count + var currentElementIndex = elementIndex++; + if (currentElementIndex >= values.Length) + continue; + values[currentElementIndex] = builder.Convert(context, extractedValue, elementType).Id; + } } - return result; + if (elementIndex != totalCount) + throw new InvalidOperationException($"{nameof(VectorLiteral)}: Expecting {totalCount} elements but got {elementIndex} for type {Type}"); + + // Regroup by rows (if necessary, only for Matrix) + int compositeSize = totalCount / compositeCount; + for (int i = 0; i < compositeCount; ++i) + { + compositeValues[i] = Type switch + { + MatrixType m => builder.Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m.BaseType, compositeSize)), context.Bound++, [.. values.Slice(i * compositeSize, compositeSize)])).ResultId, + VectorType v => values[i], + }; + } + + var instruction = builder.Insert(new OpCompositeConstruct(context.GetOrRegister(Type), context.Bound++, [.. compositeValues])); + return new(instruction.ResultId, instruction.ResultType); } +} +public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) +{ + public TypeName TypeName { get; set; } = typeName; + + public override SymbolType GenerateType(SymbolTable table) => TypeName.ResolveType(table); public override string ToString() { @@ -163,14 +192,11 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; - public override SymbolType GenerateType(SymbolTable table) - { - throw new NotImplementedException(); - } + public override SymbolType GenerateType(SymbolTable table) => TypeName.ResolveType(table); public override string ToString() { - return $"{TypeName}{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; + return $"{TypeName}({string.Join(", ", Values.Select(x => x.ToString()))})"; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 2d207432fc..33670893f4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -26,7 +26,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Parsers.FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) ) { - ((AccessorChainExpression)parsed).Accessors.Add(indexer); + ((AccessorChainExpression)parsed).Accessors.Add(new IndexerExpression(indexer, indexer.Info)); } else if ( matched == "." diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index bd54b32dff..3e159a5485 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -382,10 +382,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char('(', ref scanner, advance: true)) { - var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), rows, cols, scanner[..]) - { - TypeName = new(baseType, scanner[(tnPos - baseType.Length)..(tnPos - 1)], isArray: false) - }; + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), rows, cols, scanner[..]); while (!scanner.IsEof) { Parsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 47dcec9050..749b553f74 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -361,12 +361,6 @@ public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol f var fcall = Buffer.InsertData(Position++, new OpFunctionCall(context.GetOrRegister(functionType.ReturnType), context.Bound++, functionSymbol.IdRef, [.. parameters])); return new(fcall, functionSymbol.Id.Name); } - - public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral literal, Span values) - { - var instruction = Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(literal.Type), context.Bound++, [.. values])); - return new(instruction.ResultId, instruction.ResultType); - } } @@ -374,6 +368,12 @@ public SpirvValue CompositeConstruct(SpirvContext context, CompositeLiteral lite internal static class SymbolExtensions { + public static int GetElementCount(this SymbolType symbol) => symbol switch + { + ScalarType s => 1, + VectorType v => v.Size, + MatrixType m => m.Rows * m.Columns, + }; public static ScalarType GetElementType(this SymbolType symbol) => symbol switch { ScalarType s => s, From 7cca5a993feec017bd64a69aa78245156e6361e8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 17:28:13 +0900 Subject: [PATCH 0550/1182] Fix matrix conversion --- src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 749b553f74..1294811498 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -338,7 +338,7 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Rows).ToArray()))); valueType = m2; break; - case (MatrixType, MatrixType m2): + case (VectorType, MatrixType m2): // rebuild type result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(values))); valueType = m2; From 0474caca458f5979a5a468b8584ab6dd942f861a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 17:42:12 +0900 Subject: [PATCH 0551/1182] BinaryOperation: better handle scalar & vector for every operations, and added a few more operators support --- .../Spirv/Building/Builder.Expressions.cs | 64 +++++++++++++++---- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 1294811498..5fa4942b74 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -96,6 +96,8 @@ public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operato throw new NotImplementedException($"Couldn't figure out type for binary operation between {leftType} and {rightType}"); } + // TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations) + // We'll need to review those cases left = Convert(context, left, resultType); right = Convert(context, right, resultType); @@ -106,50 +108,57 @@ public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operato var resultTypeId = context.GetOrRegister(resultType); - var instruction = (op, context.ReverseTypes[left.TypeId], context.ReverseTypes[right.TypeId]) switch + // Refresh types (after convert) + leftType = context.ReverseTypes[left.TypeId]; + rightType = context.ReverseTypes[right.TypeId]; + + leftElementType = leftType.GetElementType(); + rightElementType = rightType.GetElementType(); + + var instruction = (op, leftElementType, rightElementType) switch { (Operator.Plus, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpIAdd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Plus, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFAdd(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpISub(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFSub(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpIMul(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFMul(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) - when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() && SymbolExtensions.SameComponentCount(l, r) + when l.IsUnsignedInteger() && r.IsUnsignedInteger() => Buffer.InsertData(Position++, new OpUDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) - when l.IsIntegerVector() && r.IsIntegerVector() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpSDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) - when l.IsFloatingVector() && r.IsFloatingVector() + when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFDiv(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) - when l.IsUnsignedIntegerVector() && r.IsUnsignedIntegerVector() + when l.IsUnsignedInteger() && r.IsUnsignedInteger() => Buffer.InsertData(Position++, new OpUMod(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() && SymbolExtensions.SameComponentCountAndWidth(l, r) + when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpSMod(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) @@ -182,20 +191,49 @@ when l.IsInteger() && r.IsInteger() (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Equals, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + (Operator.Equals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Equals, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + + (Operator.NotEquals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) + => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.NotEquals, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Lower, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Lower, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + => Buffer.InsertData(Position++, new OpULessThan(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Lower, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.LowerOrEqual, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.LowerOrEqual, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Greater, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Greater, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + => Buffer.InsertData(Position++, new OpUGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Greater, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.GreaterOrEqual, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + => Buffer.InsertData(Position++, new OpUGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.GreaterOrEqual, ScalarType l, ScalarType r) + when l.IsFloating() && r.IsFloating() + => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), _ => throw new NotImplementedException() }; From a76f01b18cfe37570ec2920783f94058c5911ca9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 18:21:57 +0900 Subject: [PATCH 0552/1182] Added lerp() intrinsic --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 41 ++++++++++++++++++- .../PrimaryExpressionParsers.cs | 2 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index c835095a32..0a50b624b5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -7,6 +7,31 @@ namespace Stride.Shaders.Parsing.SDSL; +public static class IntrinsicHelper +{ + public static SymbolType FindCommonType(ScalarType baseType, params Span types) + { + // Check if any vector type (and get the minimum size) + int vectorTypeMinSize = 0; + foreach (var type in types) + { + if (type is VectorType v) + vectorTypeMinSize = vectorTypeMinSize == 0 ? v.Size : Math.Min(vectorTypeMinSize, v.Size); + } + + if (vectorTypeMinSize != 0) + return new VectorType(baseType, vectorTypeMinSize); + + // Otherwise, ensure it's all ScalarType + foreach (var type in types) + { + if (type is not ScalarType) + throw new InvalidOperationException($"Can't find a common type between {string.Join(",", types)}"); + } + + return baseType; + } +} public class RoundCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("round", info), parameters, info) { @@ -553,7 +578,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co return new(instruction.ResultId, instruction.ResultType); } } -public class FMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmix", info), parameters, info) +public class LerpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("lerp", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -561,7 +586,19 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); + + // Ensure all vectors have the same size + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + var aType = Parameters.Values[2].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.From("float"), xType, yType, aType); + + x = builder.Convert(context, x, resultType); + y = builder.Convert(context, y, resultType); + a = builder.Convert(context, a, resultType); + + var instruction = builder.Insert(new GLSLFMix(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); return new(instruction.ResultId, instruction.ResultType); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index b48e2ea714..ad29b1fcfa 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -124,7 +124,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("isnan", _) => throw new NotImplementedException(), ("ldexp", _) => throw new NotImplementedException(), ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), - ("lerp", _) => throw new NotImplementedException(), + ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), ("lit", _) => throw new NotImplementedException(), ("log", 1) => new LogCall(parameters, scanner[position..scanner.Position]), ("log10", _) => throw new NotImplementedException(), From 5bc66bebe208e1a48e11e4bf8c07cc8be5901aff Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 20:09:43 +0900 Subject: [PATCH 0553/1182] Added min() max() saturate() and clamp() intrinsics --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 179 +++++++----------- .../PrimaryExpressionParsers.cs | 7 +- .../Spirv/Building/Builder.Expressions.cs | 47 ++--- 3 files changed, 91 insertions(+), 142 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 0a50b624b5..37f4e72fee 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -69,7 +69,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co return new(instruction.ResultId, instruction.ResultType); } } -public class AbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fabs", info), parameters, info) +public class AbsCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("abs", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -470,7 +470,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co return new(instruction.ResultId, instruction.ResultType); } } -public class FMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmin", info), parameters, info) +public class MinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("min", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -478,59 +478,22 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umin", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class SMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smin", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fmax", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("umax", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); + + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + + var instruction = resultType.GetElementType() switch + { + ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + }; + return new(instruction); } } -public class SMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smax", info), parameters, info) +public class MaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("max", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -538,23 +501,22 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fclamp", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); - return new(instruction.ResultId, instruction.ResultType); + + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + + var instruction = resultType.GetElementType() switch + { + ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + }; + return new(instruction); } } -public class UClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("uclamp", info), parameters, info) +public class ClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("clamp", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { @@ -562,20 +524,53 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); - return new(instruction.ResultId, instruction.ResultType); + + // Ensure all vectors have the same size + var xType = Parameters.Values[0].ValueType; + var minValType = Parameters.Values[1].ValueType; + var maxValType = Parameters.Values[2].ValueType; + + var baseType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), minValType.GetElementType()), maxValType.GetElementType()); + var resultType = IntrinsicHelper.FindCommonType(baseType, xType, minValType, maxValType); + + x = builder.Convert(context, x, resultType); + minVal = builder.Convert(context, minVal, resultType); + maxVal = builder.Convert(context, maxVal, resultType); + + var instruction = baseType switch + { + ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + }; + return new(instruction); } } -public class SClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("sclamp", info), parameters, info) +public class SaturateCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("saturate", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); + var x = (Parameters.Values[0].CompileAsValue(table, shader, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); - return new(instruction.ResultId, instruction.ResultType); + + var xType = Parameters.Values[0].ValueType; + var constant0 = context.CompileConstant(0.0f); + var constant1 = context.CompileConstant(1.0f); + + var baseType = xType.GetElementType(); + // Ensure 0.0 amd 1.0 constants have same type as x + constant0 = builder.Convert(context, constant0, xType); + constant1 = builder.Convert(context, constant1, xType); + + var instruction = baseType switch + { + ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + }; + return new(instruction); } } public class LerpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("lerp", info), parameters, info) @@ -1010,42 +1005,6 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co return new(instruction.ResultId, instruction.ResultType); } } -public class NMinCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmin", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLNMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class NMaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nmax", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLNMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class NClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("nclamp", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, shader, compiler), Parameters.Values[1].CompileAsValue(table, shader, compiler), Parameters.Values[2].CompileAsValue(table, shader, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLNClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} public class MulCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index ad29b1fcfa..596a76ffa4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -69,7 +69,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("atan2", 2) => new Atan2Call(parameters, scanner[position..scanner.Position]), ("ceil", 1) => new CeilCall(parameters, scanner[position..scanner.Position]), ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), - ("clamp", _) => throw new NotImplementedException(), + ("clamp", _) => new ClampCall(parameters, scanner[position..scanner.Position]), ("clip", _) => throw new NotImplementedException(), ("cos", 1) => new CosCall(parameters, scanner[position..scanner.Position]), ("cosh", 1) => new CoshCall(parameters, scanner[position..scanner.Position]), @@ -130,8 +130,8 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("log10", _) => throw new NotImplementedException(), ("log2", 1) => new Log2Call(parameters, scanner[position..scanner.Position]), ("mad", _) => throw new NotImplementedException(), - ("max", _) => throw new NotImplementedException(), - ("min", _) => throw new NotImplementedException(), + ("max", _) => new MaxCall(parameters, scanner[position..scanner.Position]), + ("min", _) => new MinCall(parameters, scanner[position..scanner.Position]), ("modf", _) => throw new NotImplementedException(), ("msad4", _) => throw new NotImplementedException(), ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), @@ -156,6 +156,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("reversebits", _) => throw new NotImplementedException(), ("round", 1) => new RoundEvenCall(parameters, scanner[position..scanner.Position]), ("rsqrt", 1) => new InverseSqrtCall(parameters, scanner[position..scanner.Position]), + ("saturate", 1) => new SaturateCall(parameters, scanner[position..scanner.Position]), ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), ("sin", 1) => new SinCall(parameters, scanner[position..scanner.Position]), ("sincos", _) => throw new NotImplementedException(), diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 5fa4942b74..a7a6b07846 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -22,6 +22,23 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) return result; } + public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftElementType, SymbolType rightElementType) + { + return (leftElementType, rightElementType) switch + { + (ScalarType { TypeName: "long" }, _) or (_, ScalarType { TypeName: "long" }) => throw new NotImplementedException("64bit integers"), + // Matching types + (ScalarType { TypeName: "int" or "uint" or "float" or "double" } l, ScalarType r) when l == r => l, + // If one side is float and other is non-floating, promote to floating + (ScalarType { TypeName: "int" or "uint" } l, ScalarType { TypeName: "float" or "double" } r) => r, + (ScalarType { TypeName: "float" or "double" } l, ScalarType { TypeName: "int" or "uint" } r) => l, + // If one side is unsigned, promote to unsigned (bitcast) + (ScalarType { TypeName: "int" } l, ScalarType { TypeName: "uint" } r) => r, + (ScalarType { TypeName: "uint" } l, ScalarType { TypeName: "int" } r) => l, + _ => throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftElementType} and {rightElementType}"), + }; + } + public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operator op, SpirvValue right, string? name = null) { var leftType = context.ReverseTypes[left.TypeId]; @@ -30,37 +47,9 @@ public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operato var leftElementType = leftType.GetElementType(); var rightElementType = rightType.GetElementType(); - ScalarType desiredElementType; - // Check base types // TODO: special case for operators expecting different types (i.e. bit shifts) - switch (leftElementType, rightElementType) - { - case (ScalarType { TypeName: "long" }, _) or (_, ScalarType { TypeName: "long" }): - throw new NotImplementedException("64bit integers"); - - // Matching types - case (ScalarType { TypeName: "int" or "uint" or "float" or "double" } l, ScalarType r) when l == r: - desiredElementType = l; - break; - // If one side is float and other is non-floating, promote to floating - case (ScalarType { TypeName: "int" or "uint" } l, ScalarType { TypeName: "float" or "double" } r): - desiredElementType = r; - break; - case (ScalarType { TypeName: "float" or "double" } l, ScalarType { TypeName: "int" or "uint" } r): - desiredElementType = l; - break; - - // If one side is unsigned, promote to unsigned (bitcast) - case (ScalarType { TypeName: "int"} l, ScalarType { TypeName: "uint" } r): - desiredElementType = r; - break; - case (ScalarType { TypeName: "uint" } l, ScalarType { TypeName: "int" } r): - desiredElementType = l; - break; - default: - throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftType} and {rightType}"); - } + var desiredElementType = FindCommonBaseTypeForBinaryOperation(leftElementType, rightElementType); // Check size SymbolType resultType; From b417f571440a2260cc98fc68a6259fef8e321e1b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 21:09:15 +0900 Subject: [PATCH 0554/1182] fix: functions with more than 1 parameter were not properly handled --- src/Stride.Shaders/Spirv/Building/Context.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 745c743c46..37a94f5cde 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -295,9 +295,9 @@ public int DeclareStructuredType(StructuredType structSymbol) int RegisterFunctionType(FunctionType functionType) { Span types = stackalloc int[functionType.ParameterTypes.Count]; - int tmp = 0; - foreach (var f in functionType.ParameterTypes) - types[tmp] = GetOrRegister(f); + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + types[i] = GetOrRegister(functionType.ParameterTypes[i]); + var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); From e0201240c60117ab11a824efc7c4091c70ac5753 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 4 Dec 2025 21:09:44 +0900 Subject: [PATCH 0555/1182] Improved prefix unary operator (added support for ++, -- and -) --- .../Parsing/SDSL/AST/Expression.cs | 62 ++++++++++++++++--- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index fdcfa5bec3..8e8eebc848 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -147,18 +147,60 @@ public class PrefixExpression(Operator op, Expression expression, TextLocation i public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; - var expression = Expression.CompileAsValue(table, shader, compiler); - Type = Expression.Type; - if (Expression.Type is PointerType pointerType && pointerType.BaseType is ScalarType { TypeName: "int" or "long" }) - { - var constant1 = context.CompileConstant(1); - var result = builder.BinaryOperation(context, expression, Operator.Plus, constant1); + var expression = Expression.Compile(table, shader, compiler); + var type = Expression.Type; + + // Depending on the operator, we might need the pointer type + var isPointer = Expression.Type is PointerType; - builder.Insert(new OpStore(expression.Id, result.Id, null)); + var valueType = (Expression.Type is PointerType pointerType) + ? pointerType.BaseType + : type; - // Note: should we fetch the value again? (new OpLoad) - // return Expression.Compile(table, shader, compiler); - return result; + var valueExpression = isPointer + ? compiler.Builder.AsValue(compiler.Context, expression) + : expression; + + if (valueType is ScalarType or VectorType) + { + switch (Operator) + { + case Operator.Inc: + case Operator.Dec: + { + if (!isPointer) + throw new InvalidOperationException($"Can't use increment/decrement expression on non-pointer expression {Expression}"); + + // Use integer so that it gets converted to proper type according to expression type + var constant1 = context.CompileConstant(1); + var result = builder.BinaryOperation(context, valueExpression, Operator switch + { + Operator.Inc => Operator.Plus, + Operator.Dec => Operator.Minus, + }, constant1); + + // We store the modified value back in the variable + builder.Insert(new OpStore(expression.Id, result.Id, null)); + + Type = type; + return expression; + } + case Operator.Plus: + // Nothing to do + return expression; + case Operator.Minus: + { + var result = valueType.GetElementType() switch + { + var elementType when elementType.IsFloating() => builder.InsertData(new OpFNegate(valueExpression.TypeId, context.Bound++, valueExpression.Id)), + var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate(valueExpression.TypeId, context.Bound++, valueExpression.Id)), + }; + Type = valueType; + return new(result); + } + default: + throw new NotImplementedException($"unary operator {Operator} is not implemented"); + } } else { From 1cbabf2417d54842ce29d9800dc01481d5f2da89 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 5 Dec 2025 11:35:06 +0900 Subject: [PATCH 0556/1182] Improved OpData.ToString() for easier debugger experience when checking SPIR-V buffers --- .../Buffers/NewSpirvBuffer.cs | 29 ++++++++++++++++--- .../SPVGenerator.Info.cs | 11 ++++++- src/Stride.Shaders/Spirv/Tools/Dis.cs | 6 ++-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 84ea3aa02d..8fa628c513 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -116,23 +116,36 @@ public readonly int CompareTo(OpData other) public override string ToString() { var sb = new StringBuilder(); + // Check for IdResult first + foreach (var op in this) + { + switch (op.Kind) + { + case OperandKind.IdResult: + sb.Append("%"); + sb.Append(op.Words[0]); + sb.Append(" = "); + break; + } + } + sb.Append(Op); foreach (var op in this) { + if (op.Kind == OperandKind.IdResult) + continue; sb.Append(" "); switch (op.Kind) { - case OperandKind.IdResult: + case OperandKind.IdResultType: case OperandKind.IdRef: for (var index = 0; index < op.Words.Length; index++) { if (index > 0) sb.Append(" "); - var x = op.Words[index]; sb.Append("%"); - sb.Append(op.Words[0]); + sb.Append(op.Words[index]); } - break; case OperandKind.LiteralInteger when op.Words.Length == 1: foreach (var e in op.Words) @@ -143,6 +156,14 @@ public override string ToString() sb.Append(op.ToLiteral()); sb.Append('"'); break; + case OperandKind k when k.IsEnum(): + for (var index = 0; index < op.Words.Length; index++) + { + if (index > 0) + sb.Append(" "); + sb.Append(k.ConvertEnumValueToString(op.Words[index])); + } + break; default: sb.Append($"unknown_{op.Kind}"); if (op.Words.Length != 1) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index de38a0a58e..ba061b8a66 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -138,7 +138,16 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In builder.AppendLine() .AppendLine("public static class OperandKindExtensions") .AppendLine("{") - .AppendLine("public static string? ToEnumValueString(this int value, OperandKind kind)") + .AppendLine("public static bool IsEnum(this OperandKind kind)") + .AppendLine("{") + .AppendLine("return kind switch") + .AppendLine("{"); + foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) + builder.AppendLine($" OperandKind.{kind.Kind} => true,"); + builder.AppendLine(" _ => false") + .AppendLine("};") + .AppendLine("}") + .AppendLine("public static string? ConvertEnumValueToString(this OperandKind kind, int value)") .AppendLine("{") .AppendLine("return kind switch") .AppendLine("{"); diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index f572ccd21c..ac9c1651f2 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -133,7 +133,7 @@ readonly DisWriter AppendEnums(SpvOperand operand) readonly DisWriter AppendEnums(OperandKind kind, SpvOperand operand) { foreach (ref var value in operand.Words) - Append(value.ToEnumValueString(kind), ConsoleColor.Yellow).Append(' '); + Append(kind.ConvertEnumValueToString(value), ConsoleColor.Yellow).Append(' '); return this; } @@ -318,9 +318,9 @@ or OperandKind.LiteralSpecConstantOpInteger }, OperandKind.LiteralFloat => AppendLiteralNumber(operand.ToLiteral()), OperandKind.LiteralString => AppendLiteralString(operand.ToLiteral()), - OperandKind k => (operand.Quantifier, operand.Words.Length) switch + OperandKind k when k.IsEnum() => (operand.Quantifier, operand.Words.Length) switch { - (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(operand.Words[0].ToEnumValueString(k), ConsoleColor.Yellow).Append(' '), + (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => Append(k.ConvertEnumValueToString(operand.Words[0]), ConsoleColor.Yellow).Append(' '), (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(k, operand).Append(' '), (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) From c9af6a5bd949e26bb51da58cbedcdde19159f79d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 6 Dec 2025 00:39:03 +0900 Subject: [PATCH 0557/1182] Basic support for composition array --- .../SDSL/RenderTests/CompositionArray1.sdsl | 53 +++++++ assets/SDSL/RenderTests/CompositionTest2.sdsl | 36 +++++ .../SDSL/EffectEvaluator.cs | 49 +++++-- .../SDSL/ShaderMixer.MixinNode.cs | 2 + .../SDSL/ShaderMixer.ShaderInfo.cs | 30 +++- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 26 +++- .../SDSL/ShaderMixer.cs | 134 ++++++++++++++++-- .../Buffers/NewSpirvBuffer.cs | 20 ++- .../Extensions/spirv.sdsl.grammar-ext.json | 30 ++++ .../FrameRenderer.OpenGL.cs | 11 ++ .../Stride.Shaders.Parsing.Tests.csproj | 2 +- src/Stride.Shaders/Core/SymbolTypes.cs | 25 +++- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 23 ++- .../Parsing/SDSL/AST/Expression.cs | 16 ++- .../Parsing/SDSL/AST/Literals.cs | 76 +++++----- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 ++- .../Parsing/SDSL/AST/Statements.Flow.cs | 24 +++- .../Parsing/SDSL/AST/Statements.cs | 2 +- .../SDSL/Parsers/Common/CommonParsers.cs | 6 +- .../DirectiveUnaryParsers.Prefix.cs | 2 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 13 +- .../Spirv/Building/Builder.Class.cs | 9 +- src/Stride.Shaders/Spirv/Building/Context.cs | 3 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 3 + 24 files changed, 506 insertions(+), 105 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionArray1.sdsl create mode 100644 assets/SDSL/RenderTests/CompositionTest2.sdsl diff --git a/assets/SDSL/RenderTests/CompositionArray1.sdsl b/assets/SDSL/RenderTests/CompositionArray1.sdsl new file mode 100644 index 0000000000..81056feb4c --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionArray1.sdsl @@ -0,0 +1,53 @@ +// PSMain(ExpectedResult=#46464646) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float4 Compute() + { + return float4(5.0, 5.0, 5.0, 5.0) / 255.0; + } +}; + +shader CompositionShaderA : CompositionBase +{ + override float4 Compute() + { + return float4(20.0, 20.0, 20.0, 20.0) / 255.0; + } +}; + +shader CompositionShaderB : CompositionBase +{ + override float4 Compute() + { + return base.Compute() + float4(10.0, 10.0, 10.0, 10.0) / 255.0; + } +}; + +shader CompositionTest +{ + stream float4 ColorTarget : SV_Target0; + + stage compose CompositionBase Comp1; + stage compose CompositionBase Comps[]; + + void PSMain() + { + streams.ColorTarget = 0.0; + foreach(var comp in Comps) + { + streams.ColorTarget += comp.Compute(); + } + } +}; + +effect CompositionArray1 +{ + mixin CompositionTest; + mixin compose Comps += CompositionShaderA; + mixin compose Comps += CompositionShaderB; + mixin compose Comps += CompositionShaderA; + mixin compose Comps += CompositionShaderB; +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/CompositionTest2.sdsl b/assets/SDSL/RenderTests/CompositionTest2.sdsl new file mode 100644 index 0000000000..af9a3e5e31 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionTest2.sdsl @@ -0,0 +1,36 @@ +// PSMain(ExpectedResult=#0A0A0A0A) + +namespace Stride.Shaders.Tests; + +shader ExternalClass +{ + cbuffer PerView + { + stage float4 Eye; + }; +} + +shader CompositionBase +{ + float4 Compute() + { + return float4(10.0, 10.0, 10.0, 10.0) / 255.0 + ExternalClass.Eye; + } +}; + +shader CompositionTest2 +{ + stream float4 ColorTarget : SV_Target0; + + compose CompositionBase ShadingColor0; + + stage float4 Shading() + { + return ShadingColor0.Compute() + ExternalClass.Eye; + } + + void PSMain() + { + streams.ColorTarget = Shading(); + } +}; diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index cc465ad877..d9db117b31 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -40,6 +40,13 @@ public ShaderSource EvaluateEffects(ShaderSource source) MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); } + else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) + { + var instSource = new ShaderClassSource(mixinComposeArray.Mixin); + var evaluatedSource = EvaluateEffects(instSource); + + MergeCompositionArray(mixinTree, mixinComposeArray.Identifier, evaluatedSource); + } } return mixinTree; @@ -47,20 +54,32 @@ public ShaderSource EvaluateEffects(ShaderSource source) return classSource; case ShaderMixinSource mixinSource: - var result = new ShaderMixinSource(); - foreach (var mixin in mixinSource.Mixins) { - var evaluatedMixin = EvaluateEffects(mixin); - Merge(result, evaluatedMixin); - } + var result = new ShaderMixinSource(); + foreach (var mixin in mixinSource.Mixins) + { + var evaluatedMixin = EvaluateEffects(mixin); + Merge(result, evaluatedMixin); + } - foreach (var composition in mixinSource.Compositions) + foreach (var composition in mixinSource.Compositions) + { + var evaluatedMixin = EvaluateEffects(composition.Value); + MergeComposition(result, composition.Key, evaluatedMixin); + } + + return result; + } + case ShaderArraySource arraySource: { - var evaluatedMixin = EvaluateEffects(composition.Value); - MergeComposition(result, composition.Key, evaluatedMixin); + var result = new ShaderArraySource(); + foreach (var mixin in arraySource.Values) + { + var evaluatedMixin = EvaluateEffects(mixin); + result.Add(result); + } + return result; } - - return result; default: throw new NotImplementedException(); } @@ -97,5 +116,15 @@ public void MergeComposition(ShaderMixinSource mixinTree, string compositionName Merge((ShaderMixinSource)composition, evaluatedSource); } + + public void MergeCompositionArray(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) + { + if (!mixinTree.Compositions.TryGetValue(compositionName, out var source)) + mixinTree.Compositions.Add(compositionName, source = new ShaderArraySource()); + + var arraySource = (ShaderArraySource)source; + + arraySource.Add(evaluatedSource); + } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index fa6b39913c..afec9c2144 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -40,7 +40,9 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary ShadersByName { get; } = new(); public Dictionary MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); + public Dictionary Compositions { get; } = new(); + public Dictionary CompositionArrays { get; } = new(); public Dictionary ExternalShaders { get; } = new(); public Dictionary ExternalFunctions { get; } = new(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 88ec0f4174..ac57aae949 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -30,11 +30,12 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio /// public string? CompositionPath { get; set; } - public int StartInstruction { get; } = startInstruction; - public int EndInstruction { get; } = endInstruction; + public int StartInstruction { get; internal set; } = startInstruction; + public int EndInstruction { get; internal set; } = endInstruction; public Dictionary Names { get; } = new(); public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); + public Dictionary StructTypes { get; } = new(); public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; @@ -64,22 +65,41 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader shaderInfo!.Variables.Add(variableName, (variable.ResultId, variableType)); // Remove SPIR-V variables to other shaders (already stored in ShaderInfo and not valid SPIR-V) - if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + if (variableType is PointerType pointer && pointer.BaseType is (ShaderSymbol or ArrayType { BaseType: ShaderSymbol })) { SetOpNop(i.Data.Memory.Span); removedIds.Add(variable.ResultId); } } + // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) else if (i.Data.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) { - // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) var pointedType = types[typePointer.Type]; - if (pointedType is ShaderSymbol) + if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) { SetOpNop(i.Data.Memory.Span); removedIds.Add(typePointer.ResultId); } } + // Also remove arrays of shaders (used in composition arrays) + else if (i.Data.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) + { + var innerType = types[typeArray.ElementType]; + if (innerType is ShaderSymbol) + { + SetOpNop(i.Data.Memory.Span); + removedIds.Add(typeArray.ResultId); + } + } + else if (i.Data.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) + { + var innerType = types[typeRuntimeArray.ElementType]; + if (innerType is ShaderSymbol) + { + SetOpNop(i.Data.Memory.Span); + removedIds.Add(typeRuntimeArray.ResultId); + } + } else if (i.Data.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) { var structName = shaderInfo.Names[typeStruct]; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 77e6b725f3..34f1fdbe12 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -39,7 +39,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); } - var compositions = new Dictionary(); + var compositions = new Dictionary(); var result = new ShaderMixinInstantiation(mixinList, compositions); foreach (var shaderName in mixinList.ToArray()) @@ -53,17 +53,33 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { var variableType = types[variable.ResultType]; - if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol or ArrayType { BaseType: ShaderSymbol }) { var variableName = names[variable.ResultId]; // Make sure we have a ShaderMixinSource // If composition is not specified, use default class if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) { - compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; + if (pointer.BaseType is ShaderSymbol shaderSymbol) + compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; + else if (pointer.BaseType is ArrayType { BaseType: ShaderSymbol }) + compositionMixin = new ShaderArraySource(); + else + throw new NotImplementedException(); + } + + if (compositionMixin is ShaderArraySource shaderArraySource) + { + var variableCompositions = new List(); + foreach (var value in shaderArraySource.Values) + variableCompositions.Add(EvaluateInheritanceAndCompositions(value, root ?? result)); + compositions[variableName] = [..variableCompositions]; + } + else + { + var variableComposition = EvaluateInheritanceAndCompositions(compositionMixin, root ?? result); + compositions[variableName] = [variableComposition]; } - var composition = EvaluateInheritanceAndCompositions(compositionMixin, root ?? result); - compositions[variableName] = composition; } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index ad021e49fe..86208be1c7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,4 +1,5 @@ -using Silk.NET.SPIRV.Cross; +using CommunityToolkit.HighPerformance; +using Silk.NET.SPIRV.Cross; using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; @@ -12,6 +13,7 @@ using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; @@ -297,19 +299,35 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, { foreach (var variable in shader.Variables) { - if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol shaderSymbol) + if (variable.Value.Type is PointerType pointer && pointer.BaseType is ShaderSymbol or ArrayType { BaseType: ShaderSymbol }) { - var compositionMixin = mixinSource.Compositions[variable.Key]; - var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; - var compositionResult = MergeMixinNode(globalContext, context, table, buffer, compositionMixin, mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); + var compositionMixins = mixinSource.Compositions[variable.Key]; + var isCompositionArray = pointer.BaseType is ArrayType { BaseType: ShaderSymbol }; - mixinNode.Compositions.Add(variable.Value.Id, compositionResult); + if (!isCompositionArray && compositionMixins.Length != 1) + throw new InvalidOperationException($"Composition variable {variable.Key} is not an array but had {compositionMixins.Length} entries"); + + var compositionResults = new MixinNode[compositionMixins.Length]; + for (int i = 0; i < compositionMixins.Length; ++i) + { + var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; + if (isCompositionArray) + compositionPath += $"[{i}]"; + compositionResults[i] = MergeMixinNode(globalContext, context, table, buffer, compositionMixins[i], mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); + } + + if (isCompositionArray) + mixinNode.CompositionArrays.Add(variable.Value.Id, compositionResults); + else + mixinNode.Compositions.Add(variable.Value.Id, compositionResults[0]); } } } + ExpandForeach(globalContext, context, buffer, mixinNode); + // Patch method calls (virtual calls & base calls) - PatchMethodCalls(globalContext, buffer, mixinNode); + PatchMethodCalls(globalContext, context, buffer, mixinNode); // Process reflection Dictionary linkInfos = new(); @@ -614,12 +632,90 @@ private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); } - private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvBuffer temp, MixinNode mixinNode) + private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) + { + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = temp[index]; + + if (i.Data.Op == Op.OpForeachSDSL && (OpForeachSDSL)i is { } @foreach) + { + // Find matching ForeachEnd (taking into account nested foreach) + var depth = 1; + var endIndex = index; + while (depth > 0 && ++endIndex < temp.Count - 1) + { + if (temp[endIndex].Op == Op.OpForeachSDSL) + depth++; + else if (temp[endIndex].Op == Op.OpForeachEndSDSL) + depth--; + } + endIndex++; + + if (depth > 0) + throw new InvalidOperationException("Could not find end of foreach instruction"); + + // Check the variable + if (!mixinNode.CompositionArrays.TryGetValue(@foreach.Collection, out var compositions)) + throw new InvalidOperationException($"Could not find compositions for expression [{@foreach.Collection}]"); + + // Extract foreach buffer (with the foreach start/end) + var foreachBuffer = temp[index..endIndex]; + temp.RemoveRange(index, endIndex - index, false); + + var foreachBufferCopy = new List(); + for (int j = 0; j < compositions.Length; ++j) + { + var idRemapping = new Dictionary(); + + // Setup variable for iterator access + var accessChain = new OpAccessChain(0, context.Bound++, @foreach.Collection, [context.CompileConstant(j).Id]); + foreachBufferCopy.Add(new(accessChain.InstructionMemory)); + idRemapping.Add(@foreach.ResultId, accessChain); + + // Build a buffer with all foreach instructions (with new ids) + foreach (var i2 in foreachBuffer[1..^1]) // skip start/end + { + var i3 = new OpData(i2.Memory.Span); + // All result ids are remapped to new ids + if (i3.IdResult is int result) + idRemapping.Add(result, context.Bound++); + SpirvBuilder.RemapIds(idRemapping, i3); + + foreachBufferCopy.Add(i3); + } + } + temp.InsertRange(index, foreachBufferCopy.AsSpan()); + AdjustIndicesAfterAddingInstructions(mixinNode, index, foreachBufferCopy.Count); + + foreach (var inst in foreachBuffer) + inst.Dispose(); + } + } + } + + private static void AdjustIndicesAfterAddingInstructions(MixinNode mixinNode, int insertIndex, int insertCount) + { + if (mixinNode.StartInstruction > insertIndex) + mixinNode.StartInstruction += insertCount; + if (mixinNode.EndInstruction > insertIndex) + mixinNode.EndInstruction += insertCount; + foreach (var shader in mixinNode.Shaders) + { + if (shader.StartInstruction > insertIndex) + shader.StartInstruction += insertCount; + if (shader.EndInstruction > insertIndex) + shader.EndInstruction += insertCount; + } + } + + private static void PatchMethodCalls(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) { var memberAccesses = new Dictionary(); var thisInstructions = new HashSet(); var baseInstructions = new HashSet(); var stageInstructions = new HashSet(); + var compositionArrayAccesses = new Dictionary(); ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { @@ -628,7 +724,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB // Apply any OpMemberAccessSDSL remapping if (memberAccesses.Count > 0) - SpirvBuilder.RemapIds(memberAccesses, i); + SpirvBuilder.RemapIds(memberAccesses, i.Data); if (i.Data.Op == Op.OpThisSDSL && (OpThisSDSL)i is { } thisInstruction) { @@ -645,6 +741,16 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB stageInstructions.Add(stageInstruction.ResultId); SetOpNop(i.Data.Memory.Span); } + else if (i.Data.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions)) + { + var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer()); + compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); + + SetOpNop(i.Data.Memory.Span); + } + } else if (i.Data.Op == Op.OpMemberAccessSDSL && (OpMemberAccessSDSL)i is { } memberAccess) { // Find out the proper mixin node (the member instance) @@ -657,7 +763,11 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB else if (isStage) instanceMixinGroup = mixinNode.Stage ?? mixinNode; else - instanceMixinGroup = mixinNode.Compositions[memberAccess.Instance]; + { + if (!compositionArrayAccesses.TryGetValue(memberAccess.Instance, out instanceMixinGroup) + && !mixinNode.Compositions.TryGetValue(memberAccess.Instance, out instanceMixinGroup)) + throw new InvalidOperationException(); + } Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -665,7 +775,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB { var shaderName = mixinNode.ExternalShaders[variable.ShaderId]; - var shaderInfo = mixinNode.ShadersByName[shaderName]; + var shaderInfo = instanceMixinGroup.ShadersByName[shaderName]; if (!shaderInfo.Variables.TryGetValue(variable.Name, out var variableInfo)) throw new InvalidOperationException($"External variable {variable.Name} not found"); memberAccesses.Add(memberAccess.ResultId, variableInfo.Id); @@ -736,7 +846,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, NewSpirvB memberAccesses.Clear(); } - SpirvBuilder.RemapIds(memberAccesses, i); + SpirvBuilder.RemapIds(memberAccesses, i.Data); } } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 8fa628c513..8898d86c39 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -191,6 +191,8 @@ public sealed class NewSpirvBuffer() : IDisposable, IEnumerable // internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; public OpDataIndex this[int index] => new(index, this); + public List Slice(int start, int length) => Instructions.Slice(start, length); + public ref OpData GetRef(int index) => ref CollectionsMarshal.AsSpan(Instructions)[index]; @@ -308,6 +310,23 @@ public bool RemoveAt(int index) return true; } + public void RemoveRange(int index, int count, bool dispose) + { + if (dispose) + { + for (int i = index; i < index + count; ++i) + Instructions[i].Dispose(); + } + Instructions.RemoveRange(index, count); + } + + public void InsertRange(int index, ReadOnlySpan source) + { + Instructions.InsertRange(index, source); + for (int i = index; i < index + source.Length; ++i) + UpdateBound(Instructions[i]); + } + public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction { if (index < 0 || index >= Instructions.Count) @@ -423,7 +442,6 @@ IEnumerator IEnumerable.GetEnumerator() } } - public static class IMemoryInstructionExtensions { /// diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 150a5d5d8d..83d6c75311 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -206,6 +206,20 @@ } ] }, + { + "opname": "OpSDSLMixinComposeArray", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "identifier" + }, + { + "kind": "LiteralString", + "name": "mixin" + } + ] + }, { "opname": "OpSDSLGenericParameter", "class": "Miscellaneous", @@ -235,6 +249,22 @@ "operands": [ { "kind": "IdResult" } ] + }, + { + "opname": "OpForeachSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" }, + { "kind": "IdResultType" }, + { + "kind": "IdRef", + "name": "collection" + } + ] + }, + { + "opname": "OpForeachEndSDSL", + "class": "Miscellaneous" } ], "operand_kinds": [ diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 13ac60f4cf..e8427bacd4 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -4,6 +4,7 @@ using Silk.NET.Windowing; using Stride.Shaders; using System; +using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Text; @@ -70,6 +71,12 @@ void main() public EffectReflection EffectReflection { get; set; } + static unsafe void DebugCallback(GLEnum source, GLEnum type, int id, GLEnum severity, int length, nint message, nint userParam) + { + var messageDecoded = Encoding.ASCII.GetString((byte*)message.ToPointer(), length); + Debug.WriteLine($"[{severity}] {messageDecoded}"); + } + public override unsafe void RenderFrame(Span result) { var options = WindowOptions.Default; @@ -81,6 +88,10 @@ public override unsafe void RenderFrame(Span result) //Getting the opengl api for drawing to the screen. Gl = GL.GetApi(window); + Gl.Enable(EnableCap.DebugOutput); + Gl.Enable(EnableCap.DebugOutputSynchronous); + Gl.DebugMessageCallback(DebugCallback, null); + // Generate a FBO Gl.GenFramebuffers(1, out Fbo); Gl.BindFramebuffer(FramebufferTarget.Framebuffer, Fbo); diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index e7f66ae13a..7f9cb9f198 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -24,7 +24,7 @@ - + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 647e28d7dc..92bfdd55ec 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -104,9 +104,14 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum { public override string ToString() => $"{BaseType}{Rows}x{Columns}"; } +/// +/// Array type. +/// +/// The base type for the array. +/// The size of the array. If -1, it means size is not defined, such as using []. public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() { - public override string ToString() => $"{BaseType}[{Size}]"; + public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } public record StructuredType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : SymbolType() { @@ -285,6 +290,24 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) symbol = default; return false; } + + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append(Name); + if (GenericArguments.Length > 0) + { + builder.Append('<'); + for (int i = 0; i < GenericArguments.Length; i++) + { + if (i > 0) + builder.Append(','); + builder.Append(GenericArguments[i]); + } + builder.Append('>'); + } + return builder.ToString(); + } } public sealed record GenericLinkType : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index ffa1540b8d..ea9f91ad79 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -134,14 +134,14 @@ public abstract class Composable(); public abstract class ComposeValue(TextLocation info) : Node(info) { - public abstract void Compile(CompilerUnit compiler, Identifier identifier); + public abstract void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator); } public class ComposePathValue(string path, TextLocation info) : ComposeValue(info) { public string Path { get; set; } = path; - public override void Compile(CompilerUnit compiler, Identifier identifier) + public override void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator) { throw new NotImplementedException(); } @@ -155,13 +155,22 @@ public class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(in { public Mixin Mixin { get; set; } = mixin; - public override void Compile(CompilerUnit compiler, Identifier identifier) + public override void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator) { if (Mixin.Generics != null || Mixin.Path.Count > 0) throw new NotImplementedException(); - - compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name)); + switch (@operator) + { + case AssignOperator.Simple: + compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name)); + break; + case AssignOperator.Plus: + compiler.Builder.Insert(new OpSDSLMixinComposeArray(identifier.Name, Mixin.Name.Name)); + break; + default: + throw new ArgumentException(null, nameof(@operator)); + } } @@ -179,13 +188,13 @@ public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue public override void Compile(CompilerUnit compiler) { - ComposeValue.Compile(compiler, Identifier); + ComposeValue.Compile(compiler, Identifier, Operator); } public override string ToString() { - return $"mixin compose {Identifier} = {ComposeValue}"; + return $"mixin compose {Identifier} {Operator.ToAssignSymbol()} {ComposeValue}"; } } public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 8e8eebc848..b7e74bb284 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -35,6 +35,16 @@ public virtual SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, } } +/// +/// Used only for when size is not explicitly defined. +/// +/// +public class EmptyExpression(TextLocation info) : Expression(info) +{ + public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) => throw new NotImplementedException(); + public override string ToString() => string.Empty; +} + public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) { public Identifier Name = name; @@ -464,7 +474,11 @@ void EmitOpAccessChain(Span accessChainIds) accessor.Type = currentValueType; } break; - // Array indexer + // Array indexer for shader compositions + case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): + + break; + // Array indexer for vector/matrix case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): var indexerValue = indexer.Index.CompileAsValue(table, shader, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 5dff0cdefc..33a8c59517 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -303,54 +303,56 @@ public bool IsMatrixField() } } -public class TypeName(string name, TextLocation info, bool isArray) : Literal(info) +public class TypeName(string name, TextLocation info) : Literal(info) { public string Name { get; set; } = name; - public bool IsArray { get; set; } = isArray; + public bool IsArray => ArraySize != null && ArraySize.Count > 0; public List? ArraySize { get; set; } public List Generics { get; set; } = []; public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolType symbolType) { - if (!IsArray) + if (Name == "LinkType") { - if (Name == "LinkType") - { - symbolType = new GenericLinkType(); - return true; - } - if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) - return true; - else if (SymbolType.TryGetNumeric(Name, out var numeric)) - { - table.DeclaredTypes.Add(numeric.ToString(), numeric); - symbolType = numeric; - return true; - } - else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) - { - table.DeclaredTypes.Add(bufferType.ToString(), bufferType); - symbolType = bufferType; - return true; - } - else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) + symbolType = new GenericLinkType(); + } + else if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) + { + + } + else if (SymbolType.TryGetNumeric(Name, out var numeric)) + { + table.DeclaredTypes.Add(numeric.ToString(), numeric); + symbolType = numeric; + } + else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) + { + table.DeclaredTypes.Add(bufferType.ToString(), bufferType); + symbolType = bufferType; + } + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) + { + table.DeclaredTypes.Add(genericBufferType.ToString(), genericBufferType); + symbolType = genericBufferType; + } + + if (symbolType == null) + return false; + + if (IsArray) + { + foreach (var arraySize in ArraySize) { - table.DeclaredTypes.Add(genericBufferType.ToString(), genericBufferType); - symbolType = genericBufferType; - return true; + if (arraySize is EmptyExpression) + symbolType = new ArrayType(symbolType, -1); + else if (arraySize is IntegerLiteral i) + symbolType = new ArrayType(symbolType, (int)i.Value); + else + throw new NotImplementedException(); } - return false; } - // else if (IsArray && Generics.Count == 0) - // { - // if (table.DeclaredTypes.TryGetValue(Name, out var type) && ) - // { - // Type = new Core.Array(type, ) - // } - // else table.Errors.Add(new(Info, "type not found")); - // } - symbolType = null; - return false; + + return true; } public SymbolType ResolveType(SymbolTable table) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index b2f6f98a69..af0eb69910 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -120,6 +120,16 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end : new StructType(structName, fields); types.Add(typeStructInstruction.ResultId, structType); } + else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) + { + var innerType = types[typeArray.ElementType]; + types.Add(typeArray.ResultId, new ArrayType(innerType, typeArray.Length)); + } + else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) + { + var innerType = types[typeRuntimeArray.ElementType]; + types.Add(typeRuntimeArray.ResultId, new ArrayType(innerType, -1)); + } else if (instruction.Op == Op.OpTypeFunction && new OpTypeFunction(instruction) is { } typeFunctionInstruction) { var returnType = types[typeFunctionInstruction.ReturnType]; @@ -321,9 +331,11 @@ public void Compile(CompilerUnit compiler, SymbolTable table) var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); classSource.Buffer = shader; - memberType = LoadExternalShaderType(table, classSource); + var shaderType = LoadExternalShaderType(table, classSource); + table.DeclaredTypes.TryAdd(shaderType.ToString(), shaderType); - table.DeclaredTypes.TryAdd(memberType.ToString(), memberType); + // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) + memberType = svar.TypeName.ResolveType(table); } var storageClass = Specification.StorageClass.Private; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 4184a08273..6315e52b03 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -52,13 +52,23 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - Collection.Compile(table, shader, compiler); - if (Collection.Type is ArrayType arrSym) - { - var btype = arrSym.BaseType; - TypeName.Compile(table, shader, compiler); - } - throw new NotImplementedException(); + var (builder, context) = compiler; + + var collection = Collection.Compile(table, shader, compiler); + if (!(Collection.Type is PointerType p && p.BaseType is ArrayType arrayType)) + throw new InvalidOperationException("foreach: Array type is expected"); + + var variableType = new PointerType(arrayType.BaseType, Specification.StorageClass.Function); + + // Since foreach need to be processed and expanded later, we use custom opcode + // (we could emit a "For" loop statement, but it would be too complex to write a general decompiler for a "for" loop when processing it later) + var variableId = builder.Insert(new OpForeachSDSL(context.GetOrRegister(variableType), context.Bound++, collection.Id)); + table.Push(); + var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), variableType, variableId); + table.CurrentFrame.Add(Variable.Name, variableSymbol); + Body.Compile(table, shader, compiler); + table.Pop(); + builder.Insert(new OpForeachEndSDSL()); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 85d6176e8d..3530b45847 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -82,7 +82,7 @@ public class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocat public AssignOperator? Operator { get; set; } = op; public Expression? Value { get; set; } = value; public bool IsConst { get; set; } = isConst; - public TypeName TypeName { get; set; } = new("void", info, false); + public TypeName TypeName { get; set; } = new("void", info); public List? ArraySizes { get => TypeName.ArraySize; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index a8b255336a..b8c351088b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -385,8 +385,10 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result { if (FollowedBy(ref scanner, Tokens.Char('['), withSpaces: true, advance: true)) { - if(FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true)) - break; + if (FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true)) + { + arraySizes.Add(new EmptyExpression(scanner[(scanner.Position - 1)..(scanner.Position - 1)])); + } else if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) { arraySizes.Add(arraySize); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 2638440a5c..b2ce2d61ea 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -171,7 +171,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && DirectiveUnaryParsers.Primary(ref scanner, result, out var lit) ) { - parsed = new CastExpression(new TypeName(typeName.Name, typeName.Info, false), Operator.Cast, lit, scanner[position..scanner.Position]); + parsed = new CastExpression(new TypeName(typeName.Name, typeName.Info), Operator.Cast, lit, scanner[position..scanner.Position]); return true; } else diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 3e159a5485..6e74440b18 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -69,7 +69,7 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, var position = scanner.Position; if (Tokens.Char('_', ref scanner) || Tokens.Letter(ref scanner)) { - name = new TypeName("", new(), false); + name = new TypeName("", new()); scanner.Advance(1); while (Tokens.LetterOrDigit(ref scanner) || Tokens.Char('_', ref scanner)) scanner.Advance(1); @@ -99,7 +99,7 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, { ((TypeName)name).Name = scanner.Memory[position..scanner.Position].ToString().Trim(); name.Info = scanner[position..scanner.Position]; - ((TypeName)name).IsArray = true; + throw new NotImplementedException(); return true; } else @@ -107,7 +107,6 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, scanner.Position = intermediate; ((TypeName)name).Name = identifier.Name; name.Info = scanner[position..scanner.Position]; - ((TypeName)name).IsArray = false; return true; } } @@ -124,7 +123,7 @@ public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult } else if (Number(ref scanner, result, out var number)) { - parsed = new TypeName(number.ToString() ?? "", number.Info, isArray: false); + parsed = new TypeName(number.ToString() ?? "", number.Info); return true; } else return Parsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); @@ -163,7 +162,7 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char('(', ref scanner, advance: true)) { - var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), scanner[..]); + var p = new VectorLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos]), scanner[..]); while (!scanner.IsEof) { Parsers.Spaces0(ref scanner, result, out _); @@ -192,7 +191,7 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) ) { - parsed = new VectorLiteral(new TypeName(baseType, scanner[position..tnPos], isArray: false), scanner[position..scanner.Position]) + parsed = new VectorLiteral(new TypeName(baseType, scanner[position..tnPos]), scanner[position..scanner.Position]) { Values = [value] }; @@ -382,7 +381,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char('(', ref scanner, advance: true)) { - var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos], isArray: false), rows, cols, scanner[..]); + var p = new MatrixLiteral(new TypeName(scanner.Memory[position..tnPos].ToString(), scanner[position..tnPos]), rows, cols, scanner[..]); while (!scanner.IsEof) { Parsers.Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index a922346172..3d99658ec8 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -13,7 +13,7 @@ namespace Stride.Shaders.Spirv.Building; -public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); +public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); public enum ResolveStep { @@ -309,15 +309,16 @@ public static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEn for (var index = shaderStart; index < buffer.Count; index++) { var i = buffer[index]; - RemapIds(idRemapping, i); + RemapIds(idRemapping, i.Data); } } - public static void RemapIds(Dictionary idRemapping, OpDataIndex i) + public static void RemapIds(Dictionary idRemapping, OpData i) { - foreach (var op in i.Data) + foreach (var op in i) { if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResult || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.PairIdRefLiteralInteger || op.Kind == OperandKind.PairIdRefIdRef) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 37a94f5cde..b573dc78ef 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -187,7 +187,8 @@ public int GetOrRegister(SymbolType? type) }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, - ArrayType a => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, + ArrayType a when a.Size != -1 => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, + ArrayType a when a.Size == -1 => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 7b1aff0b71..cbc6f1b5da 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -58,6 +58,7 @@ private static int CompareOperations(InstructionSortHelper x, InstructionSortHel // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction + || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[2..], y.Memory.Span[2..]); @@ -91,6 +92,8 @@ public readonly void Apply(NewSpirvBuffer buffer) // Covers OpTypeVector, OpTypeMatrix at the same time ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeMatrix, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true); ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true); From 65e0f66719afa741f7ffe5894317b43db0e78779 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 6 Dec 2025 13:21:10 +0900 Subject: [PATCH 0558/1182] Unified Expression.Compile, Statement.Compile and EffectStatement.Compile parameters --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 8 +- .../Parsing/SDFX/AST/Effect.Flow.cs | 2 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 33 +- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 292 +++++++++--------- .../Parsing/SDSL/AST/Expression.cs | 68 ++-- .../Parsing/SDSL/AST/Literals.cs | 20 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Parsing/SDSL/AST/Statements.Control.cs | 20 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 28 +- .../Parsing/SDSL/AST/Statements.cs | 32 +- 11 files changed, 257 insertions(+), 252 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 869a5447aa..7d26cb1a19 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -36,7 +36,7 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf ShaderLoader = ShaderLoader }; var compiler = new CompilerUnit(); - shader.Compile(compiler, table); + shader.Compile(table, compiler); if (table.Errors.Count > 0) throw new Exception("Some parse errors"); @@ -51,8 +51,12 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf } else if (declaration is ShaderEffect effect) { + SymbolTable table = new() + { + ShaderLoader = ShaderLoader + }; var compiler = new CompilerUnit(); - effect.Compile(compiler); + effect.Compile(table, compiler); var merged = compiler.ToBuffer(); #if DEBUG diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs index 26bae8b66c..353ee16cf3 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs @@ -5,7 +5,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info) { - public override void Compile(CompilerUnit compiler) + public override void Compile(Analysis.SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index ea9f91ad79..b2375fcc00 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; @@ -18,13 +19,13 @@ public override string ToString() return string.Join("", Members.Select(x => $"{x}\n")); } - public void Compile(CompilerUnit compiler) + public void Compile(SymbolTable table, CompilerUnit compiler) { compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); foreach (var statement in Members) { - statement.Compile(compiler); + statement.Compile(table, compiler); } compiler.Builder.Insert(new OpSDSLEffectEnd()); @@ -33,7 +34,7 @@ public void Compile(CompilerUnit compiler) public abstract class EffectStatement(TextLocation info) : Node(info) { - public abstract void Compile(CompilerUnit compiler); + public abstract void Compile(SymbolTable table, CompilerUnit compiler); } public class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) @@ -42,7 +43,7 @@ public class ShaderSourceDeclaration(Identifier name, TextLocation info, Express public Expression? Value { get; set; } = value; public bool IsCollection => Name.Name.Contains("Collection"); - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -57,7 +58,7 @@ public class EffectStatementBlock(TextLocation info) : EffectStatement(info) { public List Statements { get; set; } = []; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -72,7 +73,7 @@ public class MixinUse(List mixin, TextLocation info) : EffectStatement(in { public List MixinName { get; set; } = mixin; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { foreach (var mixinName in MixinName) { @@ -92,7 +93,7 @@ public class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -107,7 +108,7 @@ public class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -122,7 +123,7 @@ public class MixinConst(string identifier, TextLocation info) : EffectStatement( { public string Identifier { get; set; } = identifier; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -186,7 +187,7 @@ public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue AssignOperator Operator { get; set; } = op; public ComposeValue ComposeValue { get; set; } = value; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { ComposeValue.Compile(compiler, Identifier, Operator); } @@ -202,7 +203,7 @@ public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocat public Identifier Identifier { get; set; } = identifier; public Identifier Source { get; set; } = source; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -217,7 +218,7 @@ public class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(inf { public Mixin MixinName { get; set; } = mixin; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -227,7 +228,7 @@ public class UsingParams(Identifier name, TextLocation info) : EffectStatement(i { public Identifier ParamsName { get; set; } = name; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -243,7 +244,7 @@ public class EffectBlock(TextLocation info) : EffectStatement(info) { public List Statements { get; set; } = []; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -255,7 +256,7 @@ public class EffectExpressionStatement(Statement statement, TextLocation info) : { public Statement Statement { get; set; } = statement; - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -263,7 +264,7 @@ public override void Compile(CompilerUnit compiler) public class EffectDiscardStatement(TextLocation info) : EffectStatement(info) { - public override void Compile(CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 37f4e72fee..c45b4f7a5a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -35,10 +35,10 @@ public static SymbolType FindCommonType(ScalarType baseType, params Span public abstract class Expression(TextLocation info) : ValueNode(info) { - public SpirvValue Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public SpirvValue Compile(SymbolTable table, CompilerUnit compiler) { - var result = CompileImpl(table, shader, compiler); + var result = CompileImpl(table, compiler); // In case type is not computed yet, make sure it is using SpirvValue.TypeId Type ??= compiler.Context.ReverseTypes[result.TypeId]; return result; } - public abstract SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler); + public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); public SymbolType? ValueType => Type is PointerType pointerType ? pointerType.BaseType : Type; - public virtual SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) { - var result = Compile(table, shader, compiler); + var result = Compile(table, compiler); return compiler.Builder.AsValue(compiler.Context, result); } } @@ -41,7 +41,7 @@ public virtual SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, /// public class EmptyExpression(TextLocation info) : Expression(info) { - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) => throw new NotImplementedException(); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() => string.Empty; } @@ -53,7 +53,7 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public SpirvValue? MemberCall { get; set; } public bool IsBaseCall { get; set; } = false; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -82,7 +82,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co foreach (var p in list) { - var paramSource = p.CompileAsValue(table, shader, compiler); + var paramSource = p.CompileAsValue(table, compiler); var paramType = functionType.ParameterTypes[tmp]; // Wrap param in proper pointer type (function) @@ -135,7 +135,7 @@ public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) { public Mixin Mixin { get; set; } = mixin; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -154,10 +154,10 @@ public abstract class UnaryExpression(Expression expression, Operator op, TextLo public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) { - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var expression = Expression.Compile(table, shader, compiler); + var expression = Expression.Compile(table, compiler); var type = Expression.Type; // Depending on the operator, we might need the pointer type @@ -223,11 +223,11 @@ public class CastExpression(TypeName typeName, Operator op, Expression expressio { public TypeName TypeName { get; set; } = typeName; - public unsafe override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public unsafe override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var castType = TypeName.ResolveType(table); - var value = Expression.CompileAsValue(table, shader, compiler); + var value = Expression.CompileAsValue(table, compiler); Type = castType; @@ -240,7 +240,7 @@ public class IndexerExpression(Expression index, TextLocation info) : Expression { public Expression Index { get; set; } = index; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -254,7 +254,7 @@ public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -269,7 +269,7 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; SpirvValue result; @@ -278,7 +278,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co SymbolType currentValueType; if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { - result = streamVar.Compile(table, shader, compiler); + result = streamVar.Compile(table, compiler); currentValueType = streamVar.Type; firstIndex = 1; } @@ -286,23 +286,23 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co { if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; - result = methodCall.Compile(table, shader, compiler); + result = methodCall.Compile(table, compiler); currentValueType = methodCall.Type; firstIndex = 1; } else { - result = Source.Compile(table, shader, compiler); + result = Source.Compile(table, compiler); currentValueType = Source.Type; } if (Source is Identifier { ValueType: TextureType or Texture2DType or Texture3DType } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) { - result = Source.CompileAsValue(table, shader, compiler); + result = Source.CompileAsValue(table, compiler); if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) { var textureValue = result; - var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, shader, compiler); - var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, shader, compiler); + var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(new VectorType(((TextureType)Source.ValueType).ReturnType, 4)); @@ -313,9 +313,9 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co else if (Accessors is [MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling]) { var textureValue = result; - var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, shader, compiler); - var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, shader, compiler); - var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, shader, compiler); + var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); + var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -361,7 +361,7 @@ void EmitOpAccessChain(Span accessChainIds) EmitOpAccessChain(accessChainIds); methodCall2.MemberCall = result; - result = methodCall2.Compile(table, shader, compiler); + result = methodCall2.Compile(table, compiler); break; case (PointerType { BaseType: ShaderSymbol s }, Identifier field): // Emit OpAccessChain with everything so far @@ -480,7 +480,7 @@ void EmitOpAccessChain(Span accessChainIds) break; // Array indexer for vector/matrix case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): - var indexerValue = indexer.Index.CompileAsValue(table, shader, compiler); + var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); accessor.Type = new PointerType(p.BaseType switch @@ -533,10 +533,10 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { - var left = Left.CompileAsValue(table, shader, compiler); - var right = Right.CompileAsValue(table, shader, compiler); + var left = Left.CompileAsValue(table, compiler); + var right = Right.CompileAsValue(table, compiler); var (builder, context) = compiler; var result = builder.BinaryOperation(context, left, Op, right); @@ -556,11 +556,11 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { - Condition.CompileAsValue(table, shader, compiler); - Left.CompileAsValue(table, shader, compiler); - Right.CompileAsValue(table, shader, compiler); + Condition.CompileAsValue(table, compiler); + Left.CompileAsValue(table, compiler); + Right.CompileAsValue(table, compiler); if (Condition.ValueType is not ScalarType { TypeName: "bool" }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); if (Left.ValueType != Right.ValueType) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 33a8c59517..1da98c6eb7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -21,7 +21,7 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); @@ -29,10 +29,10 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co return new SpirvValue(i.IdResult.Value, 0); } - public override SpirvValue CompileAsValue(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) { // Since we use type 0, CompileAsValue won't work - return CompileImpl(table, shader, compiler); + return CompileImpl(table, compiler); } public override string ToString() @@ -66,7 +66,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -77,7 +77,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -94,7 +94,7 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.From("bool"); - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -114,7 +114,7 @@ public bool IsConstant() public abstract SymbolType GenerateType(SymbolTable table); - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -134,7 +134,7 @@ public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, Co var elementIndex = 0; foreach (var sourceValue in Values) { - var value = sourceValue.CompileAsValue(table, shader, compiler); + var value = sourceValue.CompileAsValue(table, compiler); var valueType = sourceValue.ValueType; // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) @@ -217,7 +217,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -362,7 +362,7 @@ public SymbolType ResolveType(SymbolTable table) return result; } - public override SpirvValue CompileImpl(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index af0eb69910..0f9ba7bf9e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -253,7 +253,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp //table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); } - public void Compile(CompilerUnit compiler, SymbolTable table) + public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; context.PutShaderName(Name); @@ -293,7 +293,7 @@ public void Compile(CompilerUnit compiler, SymbolTable table) { for (int i = 0; i < mixin.Generics.Values.Count; i++) { - generics[i] = mixin.Generics.Values[i].CompileAsValue(table, this, compiler).Id; + generics[i] = mixin.Generics.Values[i].CompileAsValue(table, compiler).Id; } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index bcf04ff1c6..262f1adfd3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -283,7 +283,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.Push(); builder.CreateBlock(context); foreach (var s in body) - s.Compile(table, shader, compiler); + s.Compile(table, compiler); table.Pop(); } builder.EndFunction(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 0ce3ec46d1..630838129d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -18,7 +18,7 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - public override unsafe void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -33,7 +33,7 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi blockTrueIds[i] = context.Bound++; blockMergeIds[i] = context.Bound++; - var conditionValue = currentIf.Condition.CompileAsValue(table, shader, compiler); + var conditionValue = currentIf.Condition.CompileAsValue(table, compiler); if (currentIf.Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(currentIf.Condition.Info, "not a boolean")); @@ -46,7 +46,7 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi builder.Insert(new OpBranchConditional(conditionValue.Id, blockTrueIds[i], falseBlock ?? blockMergeIds[i], [])); builder.CreateBlock(context, blockTrueIds[i], $"if_true_{builder.IfBlockCount + i}"); - currentIf.Body.Compile(table, shader, compiler); + currentIf.Body.Compile(table, compiler); // Do we have a specific false block? if (falseBlock != null) @@ -58,7 +58,7 @@ public override unsafe void Compile(SymbolTable table, ShaderClass shader, Compi // If there's an else without condition and we are at the last iteration, add the code now (otherwise it will happen next loop) if (i + 1 == ElseIfs.Count + 1) - Else!.Compile(table, shader, compiler); + Else!.Compile(table, compiler); } } @@ -83,7 +83,7 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new InvalidOperationException("Handled by ConditionalFlow"); } @@ -96,11 +96,11 @@ public override string ToString() public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new InvalidOperationException("Handled by ConditionalFlow"); - Condition.CompileAsValue(table, shader, compiler); - Body.Compile(table, shader, compiler); + Condition.CompileAsValue(table, compiler); + Body.Compile(table, compiler); if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); @@ -115,9 +115,9 @@ public class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { - Body.Compile(table, shader, compiler); + Body.Compile(table, compiler); } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 6315e52b03..32f68be702 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -11,7 +11,7 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info) { - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -23,14 +23,14 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit } public class Discard(TextLocation info) : Statement(info) { - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } } public class Continue(TextLocation info) : Statement(info) { - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -50,11 +50,11 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public Statement Body { get; set; } = body; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var collection = Collection.Compile(table, shader, compiler); + var collection = Collection.Compile(table, compiler); if (!(Collection.Type is PointerType p && p.BaseType is ArrayType arrayType)) throw new InvalidOperationException("foreach: Array type is expected"); @@ -66,7 +66,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit table.Push(); var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), variableType, variableId); table.CurrentFrame.Add(Variable.Name, variableSymbol); - Body.Compile(table, shader, compiler); + Body.Compile(table, compiler); table.Pop(); builder.Insert(new OpForeachEndSDSL()); } @@ -84,10 +84,10 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public Statement Body { get; set; } = body; public ShaderAttribute? Attribute { get; internal set; } = attribute; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { - Condition.CompileAsValue(table, shader, compiler); - Body.Compile(table, shader, compiler); + Condition.CompileAsValue(table, compiler); + Body.Compile(table, compiler); if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); @@ -117,11 +117,11 @@ public class For(Statement initializer, Expression cond, List update, public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - Initializer.Compile(table, shader, compiler); + Initializer.Compile(table, compiler); // Prepare blocks ids var forCheckBlock = context.Bound++; @@ -135,7 +135,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit // Check block builder.CreateBlock(context, forCheckBlock, $"for_check_{builder.ForBlockCount}"); - var conditionValue = Condition.CompileAsValue(table, shader, compiler); + var conditionValue = Condition.CompileAsValue(table, compiler); if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); @@ -144,14 +144,14 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit // Body block builder.CreateBlock(context, forBodyBlock, $"for_body_{builder.ForBlockCount}"); - Body.Compile(table, shader, compiler); + Body.Compile(table, compiler); if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) builder.Insert(new OpBranch(currentEscapeBlocks.ContinueBlock)); // Continue block builder.CreateBlock(context, currentEscapeBlocks.ContinueBlock, $"for_continue_{builder.ForBlockCount}"); foreach (var update in Update) - update.Compile(table, shader, compiler); + update.Compile(table, compiler); if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) builder.Insert(new OpBranch(forCheckBlock)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 3530b45847..3b3aabeab1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -10,13 +10,13 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Statement(TextLocation info) : ValueNode(info) { - public abstract void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler); + public abstract void Compile(SymbolTable table, CompilerUnit compiler); } public class EmptyStatement(TextLocation info) : Statement(info) { public override SymbolType? Type { get => ScalarType.From("void"); set { } } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { } + public override void Compile(SymbolTable table, CompilerUnit compiler) { } public override string ToString() => ";"; } @@ -25,9 +25,9 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { - Expression.Compile(table, shader, compiler); + Expression.Compile(table, compiler); Type = ScalarType.From("void"); } public override string ToString() @@ -41,10 +41,10 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, _) = compiler; - builder.Return(Value?.Compile(table, shader, compiler)); + builder.Return(Value?.Compile(table, compiler)); Type = Value?.Type ?? ScalarType.From("void"); } public override string ToString() @@ -65,7 +65,7 @@ public class VariableAssign(Expression variable, bool isConst, TextLocation info public Expression? Value { get; set; } = value; public bool IsConst { get; set; } = isConst; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } @@ -89,10 +89,10 @@ public List? ArraySizes set => TypeName.ArraySize = value; } - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { Variable.Type = TypeName.ResolveType(table); - var initialValue = Value?.Compile(table, shader, compiler); + var initialValue = Value?.Compile(table, compiler); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); @@ -117,7 +117,7 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -125,7 +125,7 @@ public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit for (var index = 0; index < Variables.Count; index++) { if (Variables[index].Value != null) - compiledValues[index] = Variables[index].Value!.CompileAsValue(table, shader, compiler); + compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler); } // Compute type @@ -185,13 +185,13 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; foreach (var variable in Variables) { - var target = variable.Variable.Compile(table, shader, compiler); - var source = variable.Value!.CompileAsValue(table, shader, compiler); + var target = variable.Variable.Compile(table, compiler); + var source = variable.Value!.CompileAsValue(table, compiler); if (variable.Variable.Type is not PointerType) throw new InvalidOperationException("can only assign to pointer type"); @@ -234,13 +234,13 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public override void Compile(SymbolTable table, CompilerUnit compiler) { table.Push(); var (builder, context) = compiler; foreach (var s in Statements) { - s.Compile(table, shader, compiler); + s.Compile(table, compiler); if (SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) break; } From 154f614f054637fdb20fa919761b5e992464cd1f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 6 Dec 2025 13:31:10 +0900 Subject: [PATCH 0559/1182] Effect: added support for generics --- assets/SDSL/RenderTests/GenericsEffect.sdsl | 41 +++++ .../SDSL/EffectEvaluator.cs | 16 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 4 +- .../Extensions/spirv.sdsl.grammar-ext.json | 11 +- .../Information/InstructionInfo.Order.cs | 1 + src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 24 ++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 1 + .../Spirv/Building/Builder.Class.cs | 148 +++++++++++++----- 8 files changed, 197 insertions(+), 49 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsEffect.sdsl diff --git a/assets/SDSL/RenderTests/GenericsEffect.sdsl b/assets/SDSL/RenderTests/GenericsEffect.sdsl new file mode 100644 index 0000000000..c2428aa671 --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsEffect.sdsl @@ -0,0 +1,41 @@ +// PSMain(ExpectedResult=#11FFFFFF) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader ComputeFixed : Compute +{ + override float Compute() + { + return base.Compute() + TVALUE / 255.0; + } +} + +shader ComputeFixed2 : ComputeFixed +{ +} + +shader GenericsEffectTest : Compute +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + } +} + +effect GenericsEffect +{ + mixin GenericsEffectTest; + mixin ComputeFixed<7.0>; + mixin ComputeFixed2<10.0>; + mixin ComputeFixed2<7.0>; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index d9db117b31..f94e6d18cd 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -1,11 +1,12 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using Stride.Shaders.Spirv.Core; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Compilers.SDSL @@ -17,10 +18,8 @@ public ShaderSource EvaluateEffects(ShaderSource source) switch (source) { case ShaderClassSource classSource: - if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) - throw new NotImplementedException(); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName); if (buffer[0].Op == Op.OpSDSLEffect) { var mixinTree = new ShaderMixinSource(); @@ -28,7 +27,14 @@ public ShaderSource EvaluateEffects(ShaderSource source) { if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) { - var instSource = new ShaderClassSource(mixinInstruction.Mixin); + // Resolve generics + var genericArguments = new object[mixinInstruction.Values.Elements.Length]; + for (int i = 0; i < genericArguments.Length; i++) + { + genericArguments[i] = SpirvBuilder.GetConstantValue(mixinInstruction.Values.Elements.Span[i], buffer); + } + + var instSource = new ShaderClassSource(mixinInstruction.Mixin, genericArguments); var evaluatedSource = EvaluateEffects(instSource); Merge(mixinTree, evaluatedSource); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 34f1fdbe12..3ba3ed5238 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -30,10 +30,8 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource foreach (var mixinToMerge in shaderMixinSource.Mixins) { - if (mixinToMerge.GenericArguments != null && mixinToMerge.GenericArguments.Length > 0) - throw new NotImplementedException("Generics at the top-level shaders is not supported"); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName, mixinToMerge.GenericArguments); mixinToMerge2.Buffer = buffer; //SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList, ResolveStep.Mix); SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 83d6c75311..ee30b91b22 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -189,6 +189,11 @@ { "kind": "LiteralString", "name": "mixin" + }, + { + "kind": "IdRef", + "quantifier": "*", + "name": "generics" } ] }, @@ -352,8 +357,12 @@ "value": 0 }, { - "enumerant": "LinkType", + "enumerant": "Integer", "value": 1 + }, + { + "enumerant": "LinkType", + "value": 2 } ] }, diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 4a94e2c470..759ca2f645 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -26,6 +26,7 @@ void InitOrder() Span initSDSL = [ Op.OpNop, Op.OpSDSLShader, + Op.OpSDSLEffect, Op.OpCapability, Op.OpSDSLMixinInherit, Op.OpSDSLCompose diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index b2375fcc00..d28b0fbec8 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -21,14 +21,13 @@ public override string ToString() public void Compile(SymbolTable table, CompilerUnit compiler) { - compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); + var (builder, context) = compiler; + context.GetBuffer().Add(new OpSDSLEffect(Name.Name)); foreach (var statement in Members) { statement.Compile(table, compiler); } - - compiler.Builder.Insert(new OpSDSLEffectEnd()); } } @@ -77,10 +76,25 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { foreach (var mixinName in MixinName) { - if (mixinName.Generics != null || mixinName.Path.Count > 0) + if (mixinName.Path.Count > 0) throw new NotImplementedException(); - compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name)); + var genericCount = mixinName.Generics != null ? mixinName.Generics.Values.Count : 0; + var genericValues = new int[genericCount]; + if (genericCount > 0) + { + int genericIndex = 0; + foreach (var generic in mixinName.Generics) + { + if (generic is not Literal literal) + throw new InvalidOperationException($"Generic value {generic} is not a literal"); + var compiledValue = generic.Compile(table, compiler); + genericValues[genericIndex++] = compiledValue.Id; + } + } + + + compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name, [..genericValues])); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 0f9ba7bf9e..4337c0c966 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -273,6 +273,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var genericParameterKind = genericParameterType switch { ScalarType { TypeName: "float" } => GenericParameterKindSDSL.Float, + ScalarType { TypeName: "int" } => GenericParameterKindSDSL.Integer, GenericLinkType => GenericParameterKindSDSL.LinkType, }; context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, genericParameterKind)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 3d99658ec8..521e047311 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,4 +1,6 @@ -using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; @@ -177,54 +179,92 @@ public static object GetConstantValue(OpData data, NewSpirvBuffer buffer) throw new Exception("Cannot find type instruction for id " + typeId); } - public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) + private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer shader, string[] genericValues) { - if (parentBuffer == null) - throw new ArgumentNullException(nameof(parentBuffer)); + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); - // Instantiate generics - var copiedShader = new NewSpirvBuffer(); - foreach (var i in shader) + var bound = shader.Header.Bound; + + var genericValueIndex = 0; + for (var index = 0; index < shader.Count; index++) { - var i2 = new OpData(i.Data.Memory.Span); - copiedShader.Add(i2); + var i = shader[index]; + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + { + var genericValue = genericValues[genericValueIndex++]; + var type = types[genericParameter.ResultType]; + switch (type) + { + case ScalarType { TypeName: "int" }: + shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, int.Parse(genericValue))); + break; + case ScalarType { TypeName: "float" }: + shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, float.Parse(genericValue))); + break; + default: + throw new NotImplementedException(); + } + } + else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + { + shaderDeclaration.ShaderName += $"<{string.Join(',', genericValues)}>"; + } } - shader = copiedShader; - // Collect ShaderName and OpSDSLGenericParameter + // In case we had to increase bound (new instructions), update header + shader.Header = shader.Header with { Bound = bound }; + } + + private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer instantiatingBuffer) + { + Console.WriteLine($"Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); + Console.WriteLine($"Instantiating from buffer generics {instantiatingBuffer[0].Data}:"); + foreach (var i in instantiatingBuffer) + { + if (i.Data.IdResult is int id && classSource.GenericArguments.Contains(id)) + { + Console.WriteLine($" - [{classSource.GenericArguments.IndexOf(id)}] %{id} => {i.Data}"); + } + } + + // Map classSource.GenericArguments ids to OpSDSLGenericParameter.ResultId (in the order OpSDSLGenericParameter appears) + Dictionary> targets = new(); + + // Collect OpSDSLGenericParameter List generics = new(); var genericArgumentIndex = 0; - Dictionary> targets = new(); for (var index = 0; index < shader.Count; index++) { var i = shader[index]; - if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) - { - shaderDeclaration.ShaderName = classSource.ToClassName(); - } - else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is {} genericParameter) + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { generics.Add(genericParameter.ResultId); if (!targets.TryGetValue(classSource.GenericArguments[genericArgumentIndex], out var genericParametersForThisArgument)) targets.Add(classSource.GenericArguments[genericArgumentIndex], genericParametersForThisArgument = new()); genericParametersForThisArgument.Add(genericParameter.ResultId); genericArgumentIndex++; - SetOpNop(i.Data.Memory.Span); + SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + { + shaderDeclaration.ShaderName = classSource.ToClassName(); } } // Try to resolve fully the new generic parameter values + // Any parameter resolved will be stored in Dictionary with the string version of the parameter value) var resolvedParameters = new Dictionary(); - if (parentBuffer != null) + + if (instantiatingBuffer != null) { - for (var index = 0; index < parentBuffer.Count; index++) + for (var index = 0; index < instantiatingBuffer.Count; index++) { - var i = parentBuffer[index]; + var i = instantiatingBuffer[index]; if (i.Op == Op.OpConstant) { if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) { - var value = GetConstantValue(i.Data, parentBuffer); + var value = GetConstantValue(i.Data, instantiatingBuffer); // import constant in current shader foreach (var parameter in parameters) @@ -268,7 +308,6 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha } } - // Fully resolved? if (resolvedParameters.Count == generics.Count) { @@ -294,8 +333,6 @@ public static NewSpirvBuffer InstantiateGenericShader(NewSpirvBuffer shader, Sha { throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); } - - return shader; } public static void SetOpNop(Span words) @@ -353,22 +390,63 @@ public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, if (classSource.GenericArguments.Length > 0) { - Console.WriteLine($"Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); - Console.WriteLine($"Instantiating from buffer generics {parentBuffer[0].Data}:"); - foreach (var i in parentBuffer) - { - if (i.Data.IdResult is int id && classSource.GenericArguments.Contains(id)) - { - Console.WriteLine($" - [{classSource.GenericArguments.IndexOf(id)}] %{id} => {i.Data}"); - } - } - shader = InstantiateGenericShader(shader, classSource, resolveStep, parentBuffer); + // Copy shader + shader = CopyShader(shader); + + InstantiateGenericShaderUsingParentBuffer(shader, classSource, resolveStep, parentBuffer); Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shader; } + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues) + { + var shader = GetOrLoadShader(shaderLoader, className); + + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + + if (genericValues != null && genericValues.Length > 0) + { + // Copy shader + shader = CopyShader(shader); + + InstantiateGenericShaderUsingGenericValues(shader, genericValues); + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } + + return shader; + } + + public static NewSpirvBuffer CopyShader(NewSpirvBuffer shader) + { + var copiedShader = new NewSpirvBuffer(); + foreach (var i in shader) + { + var i2 = new OpData(i.Data.Memory.Span); + copiedShader.Add(i2); + } + shader = copiedShader; + return shader; + } + + public static List CollectGenerics(NewSpirvBuffer shader) + { + // Collect OpSDSLGenericParameter + List generics = new(); + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + { + generics.Add(genericParameter.ResultId); + SetOpNop(i.Data.Memory.Span); + } + } + + return generics; + } + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) { if (!shaderLoader.LoadExternalBuffer(className, out var buffer)) From 562714184bbfc5fb891951b79835b5ab2acab681 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 8 Dec 2025 11:38:48 +0900 Subject: [PATCH 0560/1182] Better handle external static class member access --- ...2.sdsl => CompositionExternalCBuffer.sdsl} | 2 +- ...nTest1.sdsl => CompositionMethodCall.sdsl} | 2 +- .../SDSL/RenderTests/CompositionVariable.sdsl | 52 +++++++++++++++++++ .../Parsing/SDSL/AST/Expression.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 3 +- 5 files changed, 57 insertions(+), 4 deletions(-) rename assets/SDSL/RenderTests/{CompositionTest2.sdsl => CompositionExternalCBuffer.sdsl} (93%) rename assets/SDSL/RenderTests/{CompositionTest1.sdsl => CompositionMethodCall.sdsl} (96%) create mode 100644 assets/SDSL/RenderTests/CompositionVariable.sdsl diff --git a/assets/SDSL/RenderTests/CompositionTest2.sdsl b/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl similarity index 93% rename from assets/SDSL/RenderTests/CompositionTest2.sdsl rename to assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl index af9a3e5e31..041c824471 100644 --- a/assets/SDSL/RenderTests/CompositionTest2.sdsl +++ b/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl @@ -18,7 +18,7 @@ shader CompositionBase } }; -shader CompositionTest2 +shader CompositionExternalCBuffer { stream float4 ColorTarget : SV_Target0; diff --git a/assets/SDSL/RenderTests/CompositionTest1.sdsl b/assets/SDSL/RenderTests/CompositionMethodCall.sdsl similarity index 96% rename from assets/SDSL/RenderTests/CompositionTest1.sdsl rename to assets/SDSL/RenderTests/CompositionMethodCall.sdsl index eabee005e6..75d054375d 100644 --- a/assets/SDSL/RenderTests/CompositionTest1.sdsl +++ b/assets/SDSL/RenderTests/CompositionMethodCall.sdsl @@ -40,7 +40,7 @@ shader CompositionTest } }; -effect CompositionTest1 +effect CompositionMethodCall { mixin CompositionTest; mixin compose Comp0 = CompositionShaderA; diff --git a/assets/SDSL/RenderTests/CompositionVariable.sdsl b/assets/SDSL/RenderTests/CompositionVariable.sdsl new file mode 100644 index 0000000000..7fbceb818b --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionVariable.sdsl @@ -0,0 +1,52 @@ +// PSMain(ExpectedResult=#0C0C0C0C) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float A; + void SetupA() + { + } +}; + +shader CompositionShaderA : CompositionBase +{ + override void SetupA() + { + A = 3.0; + } +}; + +shader CompositionShaderB : CompositionBase +{ + override void SetupA() + { + A = 7.0; + } +}; + +shader CompositionTest +{ + stream float4 ColorTarget : SV_Target0; + + CompositionBase Comp0; + CompositionBase Comp1; + CompositionBase Comp2; + + void PSMain() + { + Comp0.SetupA(); + Comp0.A = 5.0; + Comp1.SetupA(); + streams.ColorTarget = (Comp0.A + Comp1.A + Comp2.A) / 255.0; + } +}; + +effect CompositionVariable +{ + mixin CompositionTest; + mixin compose Comp0 = CompositionShaderA; + mixin compose Comp1 = CompositionShaderB; + // Comp2 will have default value +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index e807dd525a..fcd7e3a01e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -372,7 +372,7 @@ void EmitOpAccessChain(Span accessChainIds) throw new InvalidOperationException(); // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(compiler, builder, context, matchingComponent); + result = Identifier.EmitSymbol(compiler, builder, context, matchingComponent, result.Id); accessor.Type = matchingComponent.Type; break; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 1da98c6eb7..445a3bcf19 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -231,7 +231,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) ShaderClass.Inherit(table, context, shaderType, false); - symbol = table.ResolveSymbol(Name); + var @this = builder.Insert(new OpThisSDSL(context.Bound++)); + return new(@this.ResultId, context.GetOrRegister(new PointerType(shaderType, Spirv.Specification.StorageClass.Private))); } Type = symbol.Type; From 937dc0e10c9f2e66868cc4b491b219541dd09623 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 8 Dec 2025 19:24:02 +0900 Subject: [PATCH 0561/1182] Improvements for "stage" handling --- .../CompositionExternalCBuffer.sdsl | 13 +- ...age1.sdsl => CompositionStageMethod1.sdsl} | 2 +- ...age2.sdsl => CompositionStageMethod2.sdsl} | 2 +- .../RenderTests/CompositionStageVariable.sdsl | 51 ++++++++ .../SDSL/RenderTests/CompositionVariable.sdsl | 11 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 16 ++- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 6 +- .../SDSL/ShaderMixer.cs | 119 +++++++++++++----- .../Extensions/spirv.sdsl.grammar-ext.json | 36 ++++++ .../Information/InstructionInfo.Order.cs | 6 +- .../Parsing/OrderedEnumerator.cs | 2 +- .../FrameRenderer.OpenGL.cs | 16 ++- src/Stride.Shaders/Core/Symbol.cs | 4 +- src/Stride.Shaders/Core/SymbolFrame.cs | 2 +- .../Core/SymbolTypes.Globals.cs | 12 +- src/Stride.Shaders/Core/SymbolTypes.cs | 29 ++++- .../Parsing/Analysis/SymbolTable.cs | 3 + .../Parsing/SDSL/AST/Expression.cs | 6 +- .../Parsing/SDSL/AST/Literals.cs | 29 +++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 49 ++------ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 17 +-- .../Parsing/SDSL/AST/ShaderElements.cs | 17 ++- .../Spirv/Building/Builder.Class.cs | 48 +++++-- src/Stride.Shaders/Spirv/Building/Context.cs | 26 ++-- .../Spirv/Processing/StreamAnalyzer.cs | 8 +- 25 files changed, 387 insertions(+), 143 deletions(-) rename assets/SDSL/RenderTests/{CompositionTestStage1.sdsl => CompositionStageMethod1.sdsl} (97%) rename assets/SDSL/RenderTests/{CompositionTestStage2.sdsl => CompositionStageMethod2.sdsl} (96%) create mode 100644 assets/SDSL/RenderTests/CompositionStageVariable.sdsl diff --git a/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl b/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl index 041c824471..9c90e54f88 100644 --- a/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl +++ b/assets/SDSL/RenderTests/CompositionExternalCBuffer.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#0A0A0A0A) +// PSMain(ExpectedResult=#24242424, cbuffer.PerView=(Eye=7.0, Eye2=12.0)) namespace Stride.Shaders.Tests; @@ -6,7 +6,7 @@ shader ExternalClass { cbuffer PerView { - stage float4 Eye; + stage float Eye; }; } @@ -14,7 +14,7 @@ shader CompositionBase { float4 Compute() { - return float4(10.0, 10.0, 10.0, 10.0) / 255.0 + ExternalClass.Eye; + return float4(10.0, 10.0, 10.0, 10.0) / 255.0 + ExternalClass.Eye / 255.0; } }; @@ -22,11 +22,16 @@ shader CompositionExternalCBuffer { stream float4 ColorTarget : SV_Target0; + cbuffer PerView + { + stage float Eye2; + }; + compose CompositionBase ShadingColor0; stage float4 Shading() { - return ShadingColor0.Compute() + ExternalClass.Eye; + return ShadingColor0.Compute() + Eye2 / 255.0 + ExternalClass.Eye / 255.0; } void PSMain() diff --git a/assets/SDSL/RenderTests/CompositionTestStage1.sdsl b/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl similarity index 97% rename from assets/SDSL/RenderTests/CompositionTestStage1.sdsl rename to assets/SDSL/RenderTests/CompositionStageMethod1.sdsl index ee15c919d2..669fe6db92 100644 --- a/assets/SDSL/RenderTests/CompositionTestStage1.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl @@ -74,7 +74,7 @@ shader CompositionTest : CompositionBase } }; -effect CompositionTestStage1 +effect CompositionStageMethod1 { mixin CompositionTest; mixin compose Comp0 = CompositionShaderA; diff --git a/assets/SDSL/RenderTests/CompositionTestStage2.sdsl b/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl similarity index 96% rename from assets/SDSL/RenderTests/CompositionTestStage2.sdsl rename to assets/SDSL/RenderTests/CompositionStageMethod2.sdsl index ee9b2187ca..ec0bdea63b 100644 --- a/assets/SDSL/RenderTests/CompositionTestStage2.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl @@ -54,7 +54,7 @@ shader CompositionTest } }; -effect CompositionTestStage2 +effect CompositionStageMethod2 { mixin CompositionTest; mixin compose Comp0 = CompositionShaderA; diff --git a/assets/SDSL/RenderTests/CompositionStageVariable.sdsl b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl new file mode 100644 index 0000000000..e353433b21 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl @@ -0,0 +1,51 @@ +// PSMain(ExpectedResult=#1E1E1E1E) + +namespace Stride.Shaders.Tests; + +shader CompositionBase2 +{ + stage float A; +} + +shader CompositionBase : CompositionBase2 +{ + stage float B; + stage float C; + + float Compute() + { + return A + B + C; + } +}; + +shader CompositionShaderA : CompositionBase +{ +}; + +shader CompositionShaderB : CompositionBase +{ +}; + +shader CompositionTest : CompositionBase2 +{ + stream float4 ColorTarget : SV_Target0; + + CompositionBase Comp0; + CompositionBase Comp1; + + void PSMain() + { + A = 3.0; + Comp0.B = 5.0; + Comp1.C = 7.0; + streams.ColorTarget = (Comp0.Compute() + Comp1.Compute()) / 255.0; + } +}; + +effect CompositionStageVariable +{ + mixin CompositionTest; + mixin compose Comp0 = CompositionShaderA; + mixin compose Comp1 = CompositionShaderB; + // Comp2 will have default value +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/CompositionVariable.sdsl b/assets/SDSL/RenderTests/CompositionVariable.sdsl index 7fbceb818b..8400a26bdd 100644 --- a/assets/SDSL/RenderTests/CompositionVariable.sdsl +++ b/assets/SDSL/RenderTests/CompositionVariable.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#0C0C0C0C) +// PSMain(ExpectedResult=#0D0D0D0D) namespace Stride.Shaders.Tests; @@ -7,6 +7,12 @@ shader CompositionBase float A; void SetupA() { + A = 1.0; + } + + float Compute() + { + return A; } }; @@ -39,7 +45,8 @@ shader CompositionTest Comp0.SetupA(); Comp0.A = 5.0; Comp1.SetupA(); - streams.ColorTarget = (Comp0.A + Comp1.A + Comp2.A) / 255.0; + Comp2.SetupA(); + streams.ColorTarget = (Comp0.A + Comp1.A + Comp2.Compute()) / 255.0; } }; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index ac57aae949..d5f58c5c73 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -33,11 +33,20 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public int StartInstruction { get; internal set; } = startInstruction; public int EndInstruction { get; internal set; } = endInstruction; public Dictionary Names { get; } = new(); - public Dictionary Functions { get; } = new(); + public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); public Dictionary StructTypes { get; } = new(); + public (int Id, SymbolType Type) FindMember(string name) + { + if (Functions.TryGetValue(name, out var function)) + return (function.Id, function.Type); + if (Variables.TryGetValue(name, out var variable)) + return (variable.Id, variable.Type); + throw new KeyNotFoundException($"Member {name} was not found in shader {ShaderName}"); + } + public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } @@ -56,9 +65,10 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { var functionName = shaderInfo.Names[function.ResultId]; - shaderInfo!.Functions.Add(functionName, function.ResultId); + var functionType = (FunctionType)types[function.FunctionType]; + shaderInfo!.Functions.Add(functionName, (function.ResultId, functionType)); } - else if (i.Data.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { var variableName = shaderInfo.Names[variable.ResultId]; var variableType = types[variable.ResultType]; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 3ba3ed5238..7b6f6f2c20 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -48,8 +48,10 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource bool hasStage = false; foreach (var i in shader) { - if (i.Op == Op.OpVariable && (OpVariable)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { + hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; + var variableType = types[variable.ResultType]; if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol or ArrayType { BaseType: ShaderSymbol }) { @@ -90,7 +92,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource // If there are any stage variables, add class to root if (!isRoot && hasStage) { - var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, ShaderReferences = shaderName.ShaderReferences }; + var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; // Make sure it's not already added yet (either standard or stage only) if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) root!.Mixins.Add(shaderNameStageOnly); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 86208be1c7..e1216b0c29 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -81,8 +81,8 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { var cbuffersByNames = buffer - .Where(x => x.Op == Op.OpVariable) - .Select(x => (OpVariable)x) + .Where(x => x.Op == Op.OpVariableSDSL) + .Select(x => (OpVariableSDSL)x) // Note: MemberOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x, @@ -182,8 +182,8 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { var cbuffers = buffer - .Where(x => x.Op == Op.OpVariable) - .Select(x => (OpVariable)x) + .Where(x => x.Op == Op.OpVariableSDSL) + .Select(x => (OpVariableSDSL)x) // Note: MemberOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x, @@ -276,9 +276,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(context, buffer, mixinSource, mixinNode); - //Console.WriteLine("Done SDSL importing"); - //Spv.Dis(buffer, true); - + Console.WriteLine("Done SDSL importing"); Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); // Import struct types @@ -326,6 +324,8 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, ExpandForeach(globalContext, context, buffer, mixinNode); + Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + // Patch method calls (virtual calls & base calls) PatchMethodCalls(globalContext, context, buffer, mixinNode); @@ -355,7 +355,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) linkInfo.LogicalGroup = n.Value; } - else if (i.Op == Op.OpVariable && (OpVariable)i is { } variable) + else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) { var type = context.ReverseTypes[variable.ResultType]; if (type is PointerType pointerType) @@ -394,15 +394,6 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, } } - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = buffer[index]; - if (i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable) - { - SetOpNop(i.Data.Memory.Span); - } - } - if (currentCompositionPath != null) buffer.Add(new OpSDSLEffectEnd()); @@ -411,7 +402,8 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) { - var isRoot = mixinNode.Stage == null; + var isRootMixin = mixinNode.Stage == null; + var stage = mixinNode.Stage; var offset = context.Bound; var nextOffset = 0; @@ -420,6 +412,12 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad mixinNode.StartInstruction = temp.Count; foreach (var shaderClass in mixinSource.Mixins) { + if (shaderClass.ImportStageOnly) + { + if (!isRootMixin) + throw new InvalidOperationException("importing stage-only methods/variables is only possible at the root mixin"); + } + var shader = shaderClass.Buffer; offset += nextOffset; nextOffset = 0; @@ -429,6 +427,38 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad bool skipFunction = false; + var forbiddenIds = new HashSet(); + var remapIds = new Dictionary(); + var names = new Dictionary(); + + bool ProcessStageMember(int memberId, bool isStage) + { + var include = isStage switch + { + // Import stage members only if at root level + true => isRootMixin, + // Import non-stage members only if allowed, i.e. not a "stage-only inherit" + // ("stage-only inherit" only happen when a class with stage members is inherited in a composition, and the stage-only version is added to the root mixin) + false => !shaderClass.ImportStageOnly, + }; + + // If a stage member is skipped in a composition mixin, we want to remap to the version in the root mixin + if (isStage && !isRootMixin) + { + var stageShader = stage.ShadersByName[shaderClass.ToClassName()]; + var memberName = names[memberId].Name; + var stageMember = stageShader.FindMember(memberName); + remapIds.Add(offset + memberId, stageMember.Id); + } + // Otherwise, if not included, it means we need to forbid this IDs (which could only happen if referencing non-stage member from a stage method) + else if (!include) + { + forbiddenIds.Add(offset + memberId); + } + + return include; + } + // Copy instructions to main buffer for (var index = 0; index < shader.Count; index++) { @@ -437,23 +467,17 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad // Do we need to skip variable/functions? (depending on stage/non-stage) { var include = true; - if (i.Op == Op.OpFunction && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - include = isStage switch - { - // Import stage members only if root level - true => isRoot || shaderClass.ImportStageOnly, - // Import non-stage members only if import stage only is not specified - false => !shaderClass.ImportStageOnly, - }; + include = ProcessStageMember(function.ResultId, isStage); } - if (i.Op == Op.OpVariable) + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) { - // TODO + var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; + include = ProcessStageMember(variableInstruction.ResultId, isStage); } - if (!include) { // Special case for function: skip until function end @@ -466,6 +490,10 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad } } + // Also clear the name (note: this will happen in the copied new buffer + if (names.TryGetValue(i.Data.IdResult!.Value, out var name)) + SetOpNop(name.DataIndex!.Value.Data.Memory.Span); + // Go to next instruction continue; } @@ -477,8 +505,21 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) nextOffset = i.Data.IdResult.Value; + // Note: We add the instruction here (instead of previous loop over source shader) so that if it gets turned into OpNop, we don't do that in the source buffer but in the new copied buffer + // Also, we do that before the offset since we want dictionary key IDs to match source buffer + if (temp[^1].Op == Op.OpName) + { + OpName nameInstruction = temp[^1]; + names.Add(nameInstruction.Target, nameInstruction); + } + if (offset > 0) OffsetIds(i2, offset); + + if (SpirvBuilder.ContainIds(forbiddenIds, i2)) + throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); + + SpirvBuilder.RemapIds(remapIds, i2); } shaderClass.Start = shaderStart; @@ -561,7 +602,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, if (mixinNode.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) { var shaderName = mixinNode.ExternalShaders[parentFunctionInfo.ShaderId]; - functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name]; + functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name].Id; } } @@ -777,7 +818,19 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, SpirvCont var shaderInfo = instanceMixinGroup.ShadersByName[shaderName]; if (!shaderInfo.Variables.TryGetValue(variable.Name, out var variableInfo)) - throw new InvalidOperationException($"External variable {variable.Name} not found"); + { + // Try as a stage variable + if (instanceMixinGroup.Stage != null + && instanceMixinGroup.Stage.ShadersByName.TryGetValue(shaderName, out shaderInfo) + && shaderInfo.Variables.TryGetValue(variable.Name, out variableInfo)) + { + + } + else + { + throw new InvalidOperationException($"External variable {variable.Name} not found"); + } + } memberAccesses.Add(memberAccess.ResultId, variableInfo.Id); } else if (globalContext.Types[memberAccess.ResultType] is FunctionType) @@ -897,6 +950,10 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) { for (int i = 0; i < temp.Count; i++) { + // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) + if (temp[i].Op == Op.OpVariableSDSL && (OpVariableSDSL)temp[i] is { } variable) + temp.Replace(i, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, variable.Initializer)); + // Remove Nop if (temp[i].Op == Op.OpNop) temp.RemoveAt(i--); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index ee30b91b22..5993390c51 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -113,6 +113,10 @@ { "kind": "IdRef", "name": "shader" + }, + { + "kind": "VariableFlags", + "name": "flags" } ] }, @@ -131,6 +135,24 @@ } ] }, + { + "opname": "OpVariableSDSL", + "class": "Memory", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { "kind": "StorageClass" }, + { + "kind": "VariableFlags", + "name": "flags" + }, + { + "kind": "IdRef", + "quantifier": "?", + "name": "'Initializer'" + } + ] + }, { "opname": "OpMemberAccessSDSL", "class": "Miscellaneous", @@ -299,6 +321,20 @@ } ] }, + { + "category": "BitEnum", + "kind": "VariableFlags", + "enumerants": [ + { + "enumerant": "None", + "value": "0x0000" + }, + { + "enumerant": "Stage", + "value": "0x0001" + } + ] + }, { "category": "ValueEnum", "kind": "Decoration", diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 759ca2f645..6d143a889c 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -75,6 +75,8 @@ void InitOrder() group++; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) OrderGroup[(Op.OpVariable, e)] = group; + foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) + OrderGroup[(Op.OpVariableSDSL, e)] = group; OrderGroup[(Op.OpUndef, null)] = group; @@ -97,11 +99,11 @@ void InitOrder() /// public static int GetGroupOrder(Instruction instruction) { - return GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable ? (StorageClass)instruction.Words[3] : null); + return GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable || instruction.OpCode == Op.OpVariableSDSL ? (StorageClass)instruction.Words[3] : null); } public static int GetGroupOrder(Buffers.OpData instruction) { - return GetGroupOrder(instruction.Op, instruction.Op == Op.OpVariable ? (StorageClass)instruction.Memory.Span[3] : null); + return GetGroupOrder(instruction.Op, instruction.Op == Op.OpVariable || instruction.Op == Op.OpVariableSDSL ? (StorageClass)instruction.Memory.Span[3] : null); } /// diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs index 5062068be1..a62d1299d5 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs @@ -74,6 +74,6 @@ public bool MoveNext() readonly int GetGroupOrder(Instruction instruction) { - return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable ? (StorageClass)instruction.Words[3] : null); + return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable || instruction.OpCode == Op.OpVariableSDSL ? (StorageClass)instruction.Words[3] : null); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index e8427bacd4..2e7ce40c4c 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -243,11 +243,23 @@ public override unsafe void RenderFrame(Span result) foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) { var cbMemberReflection = cbReflection.Members.Single(x => x.RawName == cbufferParameter.Key); - if (cbMemberReflection.Type.Class != EffectParameterClass.Scalar || cbMemberReflection.Type.Type != EffectParameterType.Int) + if (cbMemberReflection.Type.Class != EffectParameterClass.Scalar) throw new NotImplementedException(); fixed (byte* cbufferDataPtr = cbufferData) - *((int*)&cbufferDataPtr[cbMemberReflection.Offset]) = int.Parse(cbufferParameter.Value); + { + switch (cbMemberReflection.Type.Type) + { + case EffectParameterType.Int: + *((int*)&cbufferDataPtr[cbMemberReflection.Offset]) = int.Parse(cbufferParameter.Value); + break; + case EffectParameterType.Float: + *((float*)&cbufferDataPtr[cbMemberReflection.Offset]) = float.Parse(cbufferParameter.Value); + break; + default: + throw new NotImplementedException(); + } + } } Gl.GenBuffers(1, out uint ubo); diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index aeb7cd948b..54e617709f 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -39,14 +39,14 @@ public enum StreamIO : byte Output } -public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0, Specification.FunctionFlagsMask FunctionFlags = Specification.FunctionFlagsMask.None); +public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0, bool IsStage = false); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); /// /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType ImplicitThisType = null, ImmutableArray GroupMembers = default); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default); diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 5cc2ba91d1..d503228ffd 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -27,7 +27,7 @@ public void Add(string name, Symbol symbol) { // If there is already a function symbol with same name, let's create or add to a group. if (existingSymbol.Type is FunctionType) - existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup, FunctionFlags: existingSymbol.Id.FunctionFlags), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); + existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup, IsStage: existingSymbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); diff --git a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs index aafa23f666..0e906d675b 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs @@ -47,10 +47,10 @@ public partial record VectorType internal static FrozenDictionary Init() { - var arr = new KeyValuePair[ScalarType.names.Length * 4]; + var arr = new KeyValuePair[ScalarType.names.Length * 3]; for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 1; x < 5; x++) - arr[i * 4 + (x - 1)] = new($"{ScalarType.names[i]}{x}", new(ScalarType.From(ScalarType.names[i]),x)); + for(int x = 2; x < 5; x++) + arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i]}{x}", new(ScalarType.From(ScalarType.names[i]),x)); return arr.ToFrozenDictionary(); } } @@ -62,10 +62,10 @@ public partial record MatrixType public static FrozenDictionary Types { get; } = Init(); internal static FrozenDictionary Init() { - var arr = new List>(ScalarType.names.Length * 4 * 4); + var arr = new List>(ScalarType.names.Length * 3 * 3); for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 1; x < 5; x++) - for(int y = 1; y < 5; y++) + for(int x = 2; x < 5; x++) + for(int y = 2; y < 5; y++) arr.Add(new($"{ScalarType.names[i]}{x}x{y}", new(ScalarType.From(ScalarType.names[i]),x,y))); return arr.ToFrozenDictionary(); } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 92bfdd55ec..5c41000963 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -98,10 +98,15 @@ public sealed partial record ScalarType(string TypeName) : SymbolType() } public sealed partial record VectorType(ScalarType BaseType, int Size) : SymbolType() { + public int Size { get; } = Size >= 2 ? Size : throw new ArgumentException("Argument must be at least 2.", nameof(Size)); + public override string ToString() => $"{BaseType}{Size}"; } public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Columns) : SymbolType() { + public int Rows { get; } = Rows >= 2 ? Rows : throw new ArgumentException("Argument must be at least 2.", nameof(Rows)); + public int Columns { get; } = Columns >= 2 ? Columns : throw new ArgumentException("Argument must be at least 2.", nameof(Columns)); + public override string ToString() => $"{BaseType}{Rows}x{Columns}"; } /// @@ -250,7 +255,10 @@ public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Typ public sealed record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { - public List Components { get; init; } = []; + public List<(Symbol Symbol, VariableFlagsMask Flags)> Variables { get; init; } = []; + + public List<(Symbol Symbol, FunctionFlagsMask Flags)> Methods { get; init; } = []; + public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; public string ToClassName() @@ -264,15 +272,24 @@ public string ToClassName() internal bool TryResolveSymbol(string name, out Symbol symbol) { - foreach (var c in Components) + foreach (var c in Methods) + { + if (c.Symbol.Id.Name == name) + { + symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + return true; + } + } + foreach (var c in Variables) { - if (c.Id.Name == name) + if (c.Symbol.Id.Name == name) { - symbol = c with { ImplicitThisType = c.Type }; + symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return true; } - if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) + // For cbuffer, all their members are visible directly at the top-level without referencing the cbuffer + if (c.Symbol.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) { for (int index = 0; index < cb.Members.Count; index++) { @@ -280,7 +297,7 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) if (member.Name == name) { var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.IdRef, ImplicitThisType: c.Type, AccessChain: index); + symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, MemberAccessWithImplicitThis: c.Symbol.Type, AccessChain: index); return true; } } diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 4d24af2532..da491d7592 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -21,7 +21,10 @@ public partial class SymbolTable : ISymbolProvider // Used by Identifier.ResolveSymbol public List CurrentSymbols { get; } = new(); + // Only valid during compilation (not during ShaderMixin phase) public ShaderSymbol? CurrentShader { get; set; } + // Only valid during compilation (not during ShaderMixin phase) + public List InheritedShaders { get; set; } public SymbolTable() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index fcd7e3a01e..7bdf8ec2ea 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -61,7 +61,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (MemberCall != null) { var type = (ShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - functionSymbol = type.Components.Single(x => x.Id.Name == Name); + functionSymbol = type.Methods.Single(x => x.Symbol.Id.Name == Name).Symbol; } else { @@ -109,9 +109,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { instance = builder.Insert(new OpBaseSDSL(context.Bound++)).ResultId; } - else if (functionSymbol.ImplicitThisType is { } thisType) + else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) { - var isStage = (functionSymbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; + var isStage = functionSymbol.Id.IsStage; instance = isStage ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 445a3bcf19..5feca40ca6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -225,14 +225,20 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { // Maybe it's a static variable? try to resolve by loading file var classSource = new ShaderClassInstantiation(Name, []); - classSource.Buffer = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, Name); - var shaderType = ShaderClass.LoadExternalShaderType(table, classSource); // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) - ShaderClass.Inherit(table, context, shaderType, false); + var inheritedShaderCount = table.InheritedShaders.Count; + classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.InheritedShaders, ResolveStep.Compile, builder.GetBuffer()); - var @this = builder.Insert(new OpThisSDSL(context.Bound++)); - return new(@this.ResultId, context.GetOrRegister(new PointerType(shaderType, Spirv.Specification.StorageClass.Private))); + for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) + { + table.InheritedShaders[i].Symbol = ShaderClass.LoadExternalShaderType(table, table.InheritedShaders[i]); + ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); + } + + symbol = table.ResolveSymbol(Name); + Type = symbol.Type; + return EmitSymbol(compiler, builder, context, symbol); } Type = symbol.Type; @@ -244,9 +250,18 @@ public static SpirvValue EmitSymbol(CompilerUnit compiler, SpirvBuilder builder, var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); - if (symbol.ImplicitThisType is { } thisType) + // Shader symbols are treated separately (we want to return only the shader instance (or this if not specified)) + if (symbol.Id.Kind == SymbolKind.Shader) + { + if (instance == null) + instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + result.Id = instance.Value; + return result; + } + + if (symbol.MemberAccessWithImplicitThis is { } thisType) { - var isStage = (symbol.Id.FunctionFlags & Spirv.Specification.FunctionFlagsMask.Stage) != 0; + var isStage = symbol.Id.IsStage; if (instance == null) { instance = isStage diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4337c0c966..7c7cb213b6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -199,20 +199,21 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI { ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); - var symbols = new List(); + var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); + var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); var structTypes = new List<(StructuredType Type, int ImportedId)>(); for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; - if (instruction.Op == Op.OpVariable && (OpVariable)instruction is { } variable && + if (instruction.Op == Op.OpVariableSDSL && (OpVariableSDSL)instruction is { } variable && variable.Storageclass != Specification.StorageClass.Function) { if (!names.TryGetValue(variable.ResultId, out var variableName)) variableName = $"_{variable.ResultId}"; var variableType = types[variable.ResultType]; - var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream); - symbols.Add(new(sid, variableType, variable.ResultId)); + var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); + variables.Add((new(sid, variableType, variable.ResultId), variable.Flags)); } if (instruction.Op == Op.OpFunction) @@ -225,8 +226,8 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI var functionName = names[functionInstruction.ResultId]; var functionType = types[functionInstruction.FunctionType]; - var sid = new SymbolID(functionName, SymbolKind.Method, FunctionFlags: functionFlags); - symbols.Add(new(sid, functionType, functionInstruction.ResultId)); + var sid = new SymbolID(functionName, SymbolKind.Method, IsStage: (functionFlags & FunctionFlagsMask.Stage) != 0); + methods.Add((new(sid, functionType, functionInstruction.ResultId), functionFlags)); } if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) @@ -242,7 +243,8 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI var shaderType = new ShaderSymbol(classSource.ClassName, classSource.GenericArguments) { - Components = symbols, + Variables = variables, + Methods = methods, StructTypes = structTypes, }; return shaderType; @@ -304,7 +306,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { - shaderSymbols.Add(LoadExternalShaderType(table, mixin)); + shaderSymbols.Add(mixin.Symbol = LoadExternalShaderType(table, mixin)); } foreach (var member in Elements) @@ -366,6 +368,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; + table.InheritedShaders = inheritanceList; foreach (var member in Elements) { member.ProcessSymbol(table); @@ -392,6 +395,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var method in Elements.OfType()) method.Compile(table, this, compiler); + table.InheritedShaders = null; table.CurrentShader = null; table.Pop(); } @@ -408,35 +412,6 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol if (addToRoot) table.CurrentFrame.AddImplicitShader(shaderType); - /*foreach (var c in shaderType.Components) - { - if (c.Id.Kind == SymbolKind.Variable) - { - if (addToRoot) - { - table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThisType = c.Type }); - - // cbuffer: add members - if (c.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) - { - for (int index = 0; index < cb.Members.Count; index++) - { - var member = cb.Members[index]; - - var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.IdRef, ImplicitThisType: c.Type, AccessChain: index); - - table.CurrentFrame.Add(member.Name, symbol); - } - } - } - } - else if (c.Id.Kind == SymbolKind.Method) - { - if (addToRoot) - table.CurrentFrame.Add(c.Id.Name, c with { ImplicitThisType = c.Type }); - } - }*/ if (!addToRoot) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 262f1adfd3..7649961695 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -52,12 +52,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (!table.RootSymbols.TryGetValue(Name, out _)) { context - .FluentAdd(new OpVariable(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, null), out var register) + .FluentAdd(new OpVariableSDSL(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null), out var register) .FluentAdd(new OpName(register.ResultId, Name), out _); var sid = new SymbolID(Name, SymbolKind.SamplerState); var symbol = new Symbol(sid, Type, register.ResultId); - table.CurrentShader.Components.Add(symbol); + table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); table.CurrentFrame.Add(Name, symbol); } else throw new Exception($"SamplerState {Name} already defined"); @@ -123,7 +123,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Type is PointerType pointerType) storageClass = pointerType.StorageClass; - context.Add(new OpVariable(registeredType, variable, storageClass, null)); + var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; + + context.Add(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, null)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); @@ -139,10 +141,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, _ => Storage.None - } + }, + IsStage: IsStaged ); var symbol = new Symbol(sid, Type, variable); - table.CurrentShader.Components.Add(symbol); + table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); table.CurrentFrame.Add(Name, symbol); } @@ -228,8 +231,8 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; - var symbol = new Symbol(new(Name, SymbolKind.Method, FunctionFlags: functionFlags), Type, function.Id, ImplicitThisType: Type); - table.CurrentShader.Components.Add(symbol); + var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type); + table.CurrentShader.Methods.Add((symbol, functionFlags)); table.CurrentFrame.Add(Name, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index dc53acc757..44533f9d49 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -262,13 +262,20 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile context.DeclareCBuffer((ConstantBufferSymbol)Type); var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; - // TODO: Add a StreamSDSL storage class? - context.Add(new OpVariable(pointerType, variable, Specification.StorageClass.Uniform, null)); - context.AddName(variable, Name); + + bool? isStaged = null; for (var index = 0; index < Members.Count; index++) { var member = Members[index]; + + // Use first member as reference + if (isStaged == null) + isStaged = member.IsStaged; + // Make sure IsStaged for all members match the first member (they're all the same) + if (isStaged != member.IsStaged) + throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, AccessChain: index); table.CurrentFrame.Add(member.Name, symbol); @@ -287,6 +294,10 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{member.Name}"))); } } + + // TODO: Add a StreamSDSL storage class? + context.Add(new OpVariableSDSL(pointerType, variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + context.AddName(variable, Name); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 521e047311..e500abe61d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -31,7 +31,7 @@ public record class ShaderClassInstantiation(string ClassName, int[] GenericArgu public int[] GenericArguments { get; set; } = GenericArguments; - public Dictionary ShaderReferences { get; set; } = new(); + public ShaderSymbol Symbol { get; set; } public int Start { get; set; } public int End { get; set; } @@ -55,6 +55,8 @@ public string ToClassName() return result.ToString(); } + public override string ToString() => $"{(ImportStageOnly ? "stage " : string.Empty)}{ToClassName()} Symbol: {Symbol} Buffer: {(Buffer != null ? "set" : "empty")} Start: {Start} End: {End} OffsetId: {OffsetId}"; + public virtual bool Equals(ShaderClassInstantiation? shaderClassSource) { if (shaderClassSource is null) return false; @@ -82,10 +84,10 @@ public override int GetHashCode() public partial class SpirvBuilder { - private static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) + private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping - var shaderMapping = classSource.ShaderReferences; + var shaderMapping = new Dictionary(); foreach (var i in buffer) { if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) @@ -112,10 +114,11 @@ public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); } - public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) { // TODO: cache same instantiations within context? - if (!inheritanceList.Contains(classSource)) + var index = inheritanceList.IndexOf(classSource); + if (index == -1) { if (classSource.Buffer == null) { @@ -123,12 +126,17 @@ public static void BuildInheritanceList(IExternalShaderLoader shaderLoader, Shad classSource.Buffer = shader; } - if (!inheritanceList.Contains(classSource)) + // Note: since shader instantiation might mutate classSource, perform a search again + index = inheritanceList.IndexOf(classSource); + if (index == -1) { - BuildInheritanceList(shaderLoader, classSource, classSource.Buffer, inheritanceList, resolveStep); + BuildInheritanceListHelper(shaderLoader, classSource, classSource.Buffer, inheritanceList, resolveStep); + index = inheritanceList.Count; inheritanceList.Add(classSource); } } + + return inheritanceList[index]; } public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) @@ -341,6 +349,32 @@ public static void SetOpNop(Span words) words[1..].Clear(); } + public static bool ContainIds(HashSet ids, OpData i) + { + foreach (var op in i) + { + if ((op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResult + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefLiteralInteger + || op.Kind == OperandKind.PairIdRefIdRef) + && op.Words.Length > 0 + && ids.Contains(op.Words[0])) + { + return true; + } + + if ((op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefIdRef) + && ids.Contains(op.Words[1])) + { + return true; + } + } + + return false; + } + public static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) { for (var index = shaderStart; index < buffer.Count; index++) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index b573dc78ef..7d2c237db8 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -228,23 +228,27 @@ public int ImportShaderType(ShaderSymbol shaderSymbol) } // Import variables/functions - var components = CollectionsMarshal.AsSpan(shaderSymbol.Components); - foreach (ref var c in components) + var methods = CollectionsMarshal.AsSpan(shaderSymbol.Methods); + foreach (ref var c in methods) { - if (c.Id.Kind == SymbolKind.Method) + if (c.Symbol.Id.Kind == SymbolKind.Method) { - var functionType = (FunctionType)c.Type; + var functionType = (FunctionType)c.Symbol.Type; var functionReturnTypeId = GetOrRegister(functionType.ReturnType); - c.IdRef = Bound++; - Add(new OpSDSLImportFunction(c.IdRef, functionReturnTypeId, c.Id.Name, shader.ResultId, c.Id.FunctionFlags)); - AddName(c.IdRef, c.Id.Name); + c.Symbol.IdRef = Bound++; + Add(new OpSDSLImportFunction(c.Symbol.IdRef, functionReturnTypeId, c.Symbol.Id.Name, shader.ResultId, c.Flags)); + AddName(c.Symbol.IdRef, c.Symbol.Id.Name); } - else if (c.Id.Kind == SymbolKind.Variable) + } + var variables = CollectionsMarshal.AsSpan(shaderSymbol.Variables); + foreach (ref var c in variables) + { + if (c.Symbol.Id.Kind == SymbolKind.Variable) { - c.IdRef = Bound++; - Add(new OpSDSLImportVariable(c.IdRef, GetOrRegister(c.Type), c.Id.Name, shader.ResultId)); - AddName(c.IdRef, c.Id.Name); + c.Symbol.IdRef = Bound++; + Add(new OpSDSLImportVariable(c.Symbol.IdRef, GetOrRegister(c.Symbol.Type), c.Symbol.Id.Name, shader.ResultId, c.Flags)); + AddName(c.Symbol.IdRef, c.Symbol.Id.Name); } } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 31e96f085e..99fa385bf9 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -147,8 +147,8 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { blockPointerTypes.Add(pointerType, bufferType2); } - else if (instruction.Op == Op.OpVariable - && ((OpVariable)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + else if (instruction.Op == Op.OpVariableSDSL + && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) { blockIds.Add(bufferId); @@ -178,7 +178,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // Analyze streams foreach (var instruction in buffer) { - if (instruction.Op == Op.OpVariable && ((OpVariable)instruction) is + if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Private, ResultId: int @@ -192,7 +192,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) streams.Add(variable.ResultId, (new StreamInfo(semantic, name, type, variable.ResultId), true)); } - if (instruction.Op == Op.OpVariable && ((OpVariable)instruction) is + if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.UniformConstant, ResultId: int From 164093f3fd6b7b14dc921bd8264e3040b553c8a9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 9 Dec 2025 19:58:23 +0900 Subject: [PATCH 0562/1182] Handle struct deduplication and generate proper reflection for cbuffer --- .../CompositionExternalStruct.sdsl | 41 +++++ .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 15 +- .../SDSL/ShaderMixer.cs | 170 +++++++++++++----- .../FrameRenderer.OpenGL.cs | 39 ++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 10 +- .../Spirv/Building/Builder.CBuffer.cs | 15 ++ .../Spirv/Processing/TypeDuplicatesRemover.cs | 156 +++++++++++++--- 7 files changed, 350 insertions(+), 96 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionExternalStruct.sdsl diff --git a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl new file mode 100644 index 0000000000..af5c586265 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl @@ -0,0 +1,41 @@ +// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.PerView=(Comp0.Light=(A=3), Comp1.Light=(A=7))) + +namespace Stride.Shaders.Tests; + +shader CompositionStruct +{ + struct Test1 + { + float A; + } +} + +shader CompositionBase : CompositionStruct +{ + cbuffer PerView + { + Test1 Light; + } + float4 Compute() + { + return (Light.A / 255.0).xxxx; + } +}; + +shader CompositionExternalStruct +{ + stream float4 ColorTarget : SV_Target0; + + compose CompositionBase Comp0; + compose CompositionBase Comp1; + + stage float4 Shading() + { + return Comp0.Compute() + Comp1.Compute(); + } + + void PSMain() + { + streams.ColorTarget = Shading(); + } +}; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 7b6f6f2c20..1db86491ad 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -33,12 +33,11 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName, mixinToMerge.GenericArguments); mixinToMerge2.Buffer = buffer; - //SpirvBuilder.BuildInheritanceList(ShaderLoader, buffer, mixinList, ResolveStep.Mix); SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); } var compositions = new Dictionary(); - var result = new ShaderMixinInstantiation(mixinList, compositions); + var result = new ShaderMixinInstantiation(new(), compositions); foreach (var shaderName in mixinList.ToArray()) { @@ -87,6 +86,11 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource { hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; } + + if (i.Op == Op.OpTypeStruct) + { + hasStage = true; + } } // If there are any stage variables, add class to root @@ -95,8 +99,15 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; // Make sure it's not already added yet (either standard or stage only) if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) + { root!.Mixins.Add(shaderNameStageOnly); + } } + + // Note: make sure to add only *after* compositions EvaluateInheritanceAndCompositions recursive call is done (a composition might add a "stage" inheritance with root!.Mixins.Add() + // and this should be done before the composition mixin is added. + // For example, a composition might import a struct, so if we import and mix the composition mixin before the "stage" one defining the struct, the struct is not defined before the composition using it. + result.Mixins.Add(shaderName); } return result; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e1216b0c29..548725aff0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,5 +1,6 @@ using CommunityToolkit.HighPerformance; using Silk.NET.SPIRV.Cross; +using Stride.Core.Extensions; using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; @@ -44,8 +45,6 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - temp.Sort(); - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); new StreamAnalyzer().Process(table, temp, context); @@ -56,6 +55,8 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); ComputeCBufferOffsets(globalContext, context, temp); + temp.Sort(); + CleanupUnnecessaryInstructions(temp); foreach (var inst in context) @@ -80,14 +81,20 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { + var mixinNodes = buffer + .Where(x => x.Op == Op.OpSDSLEffect) + .Select(x => (StartIndex: x.Index, Composition: ((OpSDSLEffect)x).EffectName)) + .ToList(); + var cbuffersByNames = buffer .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (OpVariableSDSL)x) + .Select(x => (Index: x.Index, Variable: (OpVariableSDSL)x)) // Note: MemberOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( - Variable: x, - StructTypePtrId: x.ResultType, - StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + Variable: x.Variable, + CompositionPath: mixinNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).Composition, + StructTypePtrId: x.Variable.ResultType, + StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, MemberOffset: 0)) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) @@ -108,31 +115,29 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex } var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); var structTypes = cbuffers.Select(x => x.StructType); - var structTypeIds = cbuffers.ToDictionary(x => context.Types[x.StructType], x => x); var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); var mergedCbufferPtrStructId = context.GetOrRegister(new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform)); - // Remap member ids - foreach (var i in buffer) + int memberIndex = 0; + foreach (ref var cbuffer in cbuffersSpan) { - if (i.Op == Op.OpMemberName && (OpMemberName)i is { } memberName) - { - if (structTypeIds.TryGetValue(memberName.Type, out var cbuffer)) - memberName.Member += cbuffer.MemberOffset; - } - else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { } memberDecorate) - { - if (structTypeIds.TryGetValue(memberDecorate.StructureType, out var cbuffer)) - memberDecorate.Member += cbuffer.MemberOffset; - } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { } memberDecorateString) + var compositionPath = cbuffer.CompositionPath; + + foreach (var member in cbuffer.StructType.Members) { - if (structTypeIds.TryGetValue(memberDecorateString.StructType, out var cbuffer)) - memberDecorateString.Member += cbuffer.MemberOffset; + var link = member.Name; + if (!compositionPath.IsNullOrEmpty()) + link = $"{compositionPath}.{link}"; + context.Add(new OpMemberDecorateString(mergedCbufferStructId, memberIndex++, ParameterizedFlags.DecorationLinkSDSL(link))); } - else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + } + + // Remap member ids + foreach (var i in buffer) + { + if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberOffset > 0) { @@ -159,13 +164,13 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex } } - var idRemapping = new Dictionary(); - // Update variable to use new type - idRemapping.Add(cbuffersSpan[0].StructTypePtrId, mergedCbufferPtrStructId); + // Update first variable to use new type + cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; + var idRemapping = new Dictionary(); foreach (ref var cbuffer in cbuffersSpan.Slice(1)) { - // Update all cbuffers access to be replaced with unified cbuffer + // Update all cbuffers access to be replaced with first variable (unified cbuffer) idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); // Remove other cbuffer variables SetOpNop(cbuffer.Variable.InstructionMemory.Span); @@ -179,6 +184,11 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex } } + private void DecorateStructOffsets() + { + + } + private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { var cbuffers = buffer @@ -193,22 +203,70 @@ private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContex .Where(x => x.StructType != null) .ToList(); - EffectTypeDescription ConvertType(SymbolType symbolType) + EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) + { + var structId = context.Types[s]; + var hasOffsetDecorations = false; + + foreach (var i in context.GetBuffer()) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructType == structId) + { + hasOffsetDecorations = true; + } + } + + var members = new EffectTypeMemberDescription[s.Members.Count]; + var offset = 0; + for (int i = 0; i < s.Members.Count; ++i) + { + members[i] = new EffectTypeMemberDescription + { + Name = s.Members[i].Name, + Type = ConvertType(context, s.Members[i].Type), + Offset = offset, + }; + + // Note: we assume if already added, the offsets were computed the same way + if (!hasOffsetDecorations) + context.Add(new OpMemberDecorate(context.Types[s], i, ParameterizedFlags.DecorationOffset(offset))); + + var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); + offset += memberSize; + } + return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members }; + } + + + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType) { return symbolType switch { ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1 }, ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1 }, + StructType s => ConvertStructType(context, s), // TODO: should we use RowCount instead? (need to update Stride) - VectorType v => ConvertType(v.BaseType) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, - MatrixType m => ConvertType(m.BaseType) with { Class = EffectParameterClass.Vector, RowCount = m.Rows, ColumnCount = m.Columns }, + VectorType v => ConvertType(context, v.BaseType) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, + MatrixType m => ConvertType(context, m.BaseType) with { Class = EffectParameterClass.Vector, RowCount = m.Rows, ColumnCount = m.Columns }, }; } + // Scan LinkSDSL decorations + Dictionary<(int StructType, int Member), string> links = new(); + foreach (var i in context.GetBuffer()) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + using var n = new LiteralValue(m.Span); + links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); + } + } + foreach (var cbuffer in cbuffers) { int constantBufferOffset = 0; var cb = cbuffer.StructType; + var structTypeId = context.Types[cb]; var memberInfos = new EffectValueDescription[cb.Members.Count]; for (var index = 0; index < cb.Members.Count; index++) @@ -219,10 +277,15 @@ EffectTypeDescription ConvertType(SymbolType symbolType) context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); + var keyName = member.Name; + if (links.TryGetValue((structTypeId, index), out var linkName)) + keyName = linkName; + memberInfos[index] = new EffectValueDescription { - Type = ConvertType(member.Type), + Type = ConvertType(context, member.Type), RawName = member.Name, + KeyInfo = new EffectParameterKeyInfo { KeyName = keyName }, Offset = constantBufferOffset, Size = memberSize, }; @@ -429,7 +492,8 @@ private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, Shad var forbiddenIds = new HashSet(); var remapIds = new Dictionary(); - var names = new Dictionary(); + var names = new Dictionary(); + var removedIds = new HashSet(); bool ProcessStageMember(int memberId, bool isStage) { @@ -446,7 +510,7 @@ bool ProcessStageMember(int memberId, bool isStage) if (isStage && !isRootMixin) { var stageShader = stage.ShadersByName[shaderClass.ToClassName()]; - var memberName = names[memberId].Name; + var memberName = names[memberId]; var stageMember = stageShader.FindMember(memberName); remapIds.Add(offset + memberId, stageMember.Id); } @@ -467,6 +531,11 @@ bool ProcessStageMember(int memberId, bool isStage) // Do we need to skip variable/functions? (depending on stage/non-stage) { var include = true; + if (i.Op == Op.OpName) + { + OpName nameInstruction = i; + names.Add(nameInstruction.Target, nameInstruction.Name); + } if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; @@ -480,6 +549,9 @@ bool ProcessStageMember(int memberId, bool isStage) if (!include) { + if (i.Data.IdResult is int id) + removedIds.Add(offset + id); + // Special case for function: skip until function end // (for other cases such as variable, skipping only current instruction is enough) if (i.Op == Op.OpFunction) @@ -490,10 +562,6 @@ bool ProcessStageMember(int memberId, bool isStage) } } - // Also clear the name (note: this will happen in the copied new buffer - if (names.TryGetValue(i.Data.IdResult!.Value, out var name)) - SetOpNop(name.DataIndex!.Value.Data.Memory.Span); - // Go to next instruction continue; } @@ -505,14 +573,6 @@ bool ProcessStageMember(int memberId, bool isStage) if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) nextOffset = i.Data.IdResult.Value; - // Note: We add the instruction here (instead of previous loop over source shader) so that if it gets turned into OpNop, we don't do that in the source buffer but in the new copied buffer - // Also, we do that before the offset since we want dictionary key IDs to match source buffer - if (temp[^1].Op == Op.OpName) - { - OpName nameInstruction = temp[^1]; - names.Add(nameInstruction.Target, nameInstruction); - } - if (offset > 0) OffsetIds(i2, offset); @@ -522,8 +582,26 @@ bool ProcessStageMember(int memberId, bool isStage) SpirvBuilder.RemapIds(remapIds, i2); } + for (var index = shaderStart; index < temp.Count; index++) + { + // Second pass: remove OpName/OpMember referencing to removed IDs + var i = temp[index]; + if (i.Op == Op.OpName && (OpName)i is { } name) + { + if (removedIds.Contains(name.Target)) + SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) + { + // Structure ID is always stored in first operand + var target = i.Data.Memory.Span[1]; + if (removedIds.Contains(target)) + SetOpNop(i.Data.Memory.Span); + } + } + shaderClass.Start = shaderStart; - shaderClass.End = shaderStart; + shaderClass.End = temp.Count; shaderClass.OffsetId = offset; // Build ShaderInfo diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 2e7ce40c4c..bef137c068 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -242,23 +242,11 @@ public override unsafe void RenderFrame(Span result) var cbufferData = new byte[cbReflection.Size]; foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) { - var cbMemberReflection = cbReflection.Members.Single(x => x.RawName == cbufferParameter.Key); - if (cbMemberReflection.Type.Class != EffectParameterClass.Scalar) - throw new NotImplementedException(); + var cbMemberReflection = cbReflection.Members.Single(x => x.KeyInfo.KeyName == cbufferParameter.Key); fixed (byte* cbufferDataPtr = cbufferData) { - switch (cbMemberReflection.Type.Type) - { - case EffectParameterType.Int: - *((int*)&cbufferDataPtr[cbMemberReflection.Offset]) = int.Parse(cbufferParameter.Value); - break; - case EffectParameterType.Float: - *((float*)&cbufferDataPtr[cbMemberReflection.Offset]) = float.Parse(cbufferParameter.Value); - break; - default: - throw new NotImplementedException(); - } + FillData(cbufferParameter.Value, cbMemberReflection.Type, cbMemberReflection.Offset, cbufferDataPtr); } } @@ -305,4 +293,27 @@ public override unsafe void RenderFrame(Span result) window.Dispose(); } + + private static unsafe void FillData(string value, EffectTypeDescription type, int offset, byte* cbufferDataPtr) + { + switch (type) + { + case { Class: EffectParameterClass.Struct }: + var structParameters = TestHeaderParser.ParseParameters(value); + foreach (var member in type.Members) + { + if (structParameters.TryGetValue(member.Name, out var memberValue)) + FillData(memberValue, member.Type, offset + member.Offset, cbufferDataPtr); + } + break; + case { Type: EffectParameterType.Int }: + *((int*)&cbufferDataPtr[offset]) = int.Parse(value); + break; + case { Type: EffectParameterType.Float }: + *((float*)&cbufferDataPtr[offset]) = float.Parse(value); + break; + default: + throw new NotImplementedException(); + } + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 7c7cb213b6..449078307c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -309,6 +309,11 @@ public void Compile(SymbolTable table, CompilerUnit compiler) shaderSymbols.Add(mixin.Symbol = LoadExternalShaderType(table, mixin)); } + foreach (var shaderType in shaderSymbols) + { + Inherit(table, context, shaderType, true); + } + foreach (var member in Elements) { if (member is ShaderMethod func) @@ -374,11 +379,6 @@ public void Compile(SymbolTable table, CompilerUnit compiler) member.ProcessSymbol(table); } - foreach (var shaderType in shaderSymbols) - { - Inherit(table, context, shaderType, true); - } - foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 3192cca10a..48dac79ea6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -18,6 +18,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type ScalarType { TypeName: "short" or "ushort" } => (2, 2), ScalarType { TypeName: "int" or "uint" or "float" or "bool" } => (4, 4), ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 8), + StructuredType s => StructSizeInBuffer(s), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Columns - 1) + m.Rows)), @@ -28,6 +29,20 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type }; } + private static (int, int) StructSizeInBuffer(StructuredType s) + { + var offset = 0; + + // Apply same rules as inside a cbuffer + foreach (var member in s.Members) + { + var memberSize = ComputeCBufferOffset(member.Type, member.TypeModifier, ref offset); + offset += memberSize; + } + + return (offset, 16); + } + // // Computes the size of a member type, including its alignment and array size. // It does so recursively for structs, and handles different parameter classes. diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index cbc6f1b5da..7ab7550c7f 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; @@ -39,13 +40,32 @@ public int[] FindItemsWithTypes(NewSpirvBuffer buffer, params Span ops) return result; } - record struct InstructionSortHelper(Op Op, int Index, MemoryOwner Memory) : IComparable + // Note: Target is only for OpName and OpMember + record struct InstructionSortHelper(Op Op, int Index, OpData Data) { - public int CompareTo(InstructionSortHelper other) => CompareOperations(this, other); + public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } - private static int CompareOperations(InstructionSortHelper x, InstructionSortHelper y) + // If it's a fake instruction for OpName/OpMember, we can also use Target instead of Memory.Span[1] + public int? TargetOverride { get; init; } + + public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; + } + + class OperationComparer(List NameInstructions) : IComparer + { + private static int RemapOp(Op op) { - var comparison = x.Op.CompareTo(y.Op); + // Make sure all OpName and OpMember are contiguous + return op switch + { + Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString => -1, + _ => (int)op, + }; + } + + public int Compare(InstructionSortHelper x, InstructionSortHelper y) + { + var comparison = RemapOp(x.Op).CompareTo(RemapOp(y.Op)); if (comparison != 0) return comparison; @@ -55,19 +75,42 @@ private static int CompareOperations(InstructionSortHelper x, InstructionSortHel if (y.Index == -1 || x.Index == int.MaxValue) return 1; + // Only for OpName and OpMember + if (x.Op == Op.OpName || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) + { + // Use TargetOverride if defined, otherwise Memory.Span[1] (where target would be stored) + comparison = (x.TargetOverride ?? x.Data.Memory.Span[1]).CompareTo(y.TargetOverride ?? y.Data.Memory.Span[1]); + if (comparison != 0) + return comparison; + } + // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray + || x.Op == Op.OpTypeStruct || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { - comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[2..], y.Memory.Span[2..]); + comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) return comparison; + + // For struct, we have some additional checks: same name and member info + if (x.Op == Op.OpTypeStruct) + { + comparison = CompareStructMetadata(x, y); + if (comparison != 0) + return comparison; + } } - else if (x.Op == Op.OpName) + else if (x.Op == Op.OpName || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { - comparison = MemoryExtensions.SequenceCompareTo(x.Memory.Span[1..], y.Memory.Span[1..]); + // Use actual op (they were all remapped to same ID in RemapOp() to be grouped by TargetId first) + comparison = x.Op.CompareTo(y.Op); + if (comparison != 0) + return comparison; + + comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory != null ? x.Data.Memory.Span[2..] : [], y.Data.Memory != null ? y.Data.Memory.Span[2..] : []); if (comparison != 0) return comparison; } @@ -75,55 +118,102 @@ private static int CompareOperations(InstructionSortHelper x, InstructionSortHel comparison = x.Index.CompareTo(y.Index); return comparison; } + + public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper y) + { + // Note: With RemapOp(), this will also find OpMember instructions + var target1 = x.Data.Memory.Span[1]; + var namesStart1 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 }, this); + var namesEnd1 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 + 1 }, this); + + var target2 = y.Data.Memory.Span[1]; + var namesStart2 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 }, this); + var namesEnd2 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 + 1 }, this); + + // Compare sequences (they should be the same) + for (int i = 0; i < Math.Max(namesEnd1 - namesStart1, namesEnd2 - namesStart2); ++i) + { + // If one sequence is longer than the other, define an ordering + if (i >= namesEnd1 - namesStart1) + return -1; + if (i >= namesEnd2 - namesStart2) + return 1; + + var comparison = Compare(NameInstructions[namesStart1 + i], NameInstructions[namesStart2 + i]); + if (comparison != 0) + return comparison; + } + + return 0; + } } public readonly void Apply(NewSpirvBuffer buffer) { var instructionsByOp = new List(); + var namesByOp = new List(); foreach (var i in buffer) - instructionsByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data.Memory)); - instructionsByOp.Sort(); + { + switch (i.Op) + { + case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: + // Target is always in operand 1 for all those instructions + namesByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); + break; + default: + instructionsByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); + break; + } + } + + var comparer = new OperationComparer(namesByOp); + // Note: since it contains no OpTypeStruct, it should not access OperationComparer.NameInstructions + namesByOp.Sort(comparer); + instructionsByOp.Sort(comparer); // Note: We process instruction by types depending on their dependencies // i.e. a OpTypeFloat being unified means a OpTypeVector depending on it might too // Covers OpTypeVoid, OpTypeBool, OpTypeInt, OpTypeFloat at the same time (no interdependencies) - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false, comparer); // Covers OpTypeVector, OpTypeMatrix at the same time - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeMatrix, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeMatrix, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeStruct, Op.OpTypeStruct, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportShader, Op.OpSDSLImportShader, true); - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportStruct, Op.OpSDSLImportStruct, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparer); + + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportShader, Op.OpSDSLImportShader, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportStruct, Op.OpSDSLImportStruct, true, comparer); // Covers OpSDSLImportFunction and OpSDSLImportVariable at the same time - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportFunction, Op.OpSDSLImportVariable, true); + ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportFunction, Op.OpSDSLImportVariable, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpName, Op.OpName, true); + // Note: due to RemapOp, this will also cover OpMemberDecorate and OpMemberName + ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparer); } - private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort) + private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer) { - var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }); - var end = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = endOp, Index = int.MaxValue }); + var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }, comparer); + var end = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = endOp, Index = int.MaxValue }, comparer); if (sort) { // Sort again, but only those instructions (as previous replacements with ReplaceRefs might have changed order) - instructionsByOp.Sort(start, end - start, Comparer.Default); + instructionsByOp.Sort(start, end - start, comparer); } - ProcessSortedInstructions(buffer, instructionsByOp, start, end); + ProcessSortedInstructions(buffer, instructionsByOp, start, end, comparer); } - private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List instructionsByOp, int start, int end) + private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer) { for (var firstIndex = start; firstIndex < end; ) { - var i = buffer[instructionsByOp[firstIndex].Index].Data; + var i = buffer[instructionsByOp[firstIndex].Index]; // Find first item that is different int lastIndex; @@ -131,26 +221,34 @@ private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List 1) { + bool isOpWithResultId = i.Op == Op.OpName || i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString; + // Build list of IdResult matching first instruction Span matchingRefs = new int[lastIndex - (firstIndex + 1)]; for (var index = firstIndex + 1; index < lastIndex; ++index) { var j = buffer[instructionsByOp[index].Index].Data; - if (i.Op != Op.OpName) + if (!isOpWithResultId) matchingRefs[index - (firstIndex + 1)] = j.IdResult ?? throw new InvalidOperationException(); SetOpNop(j.Memory.Span); } // Replace all IdResult at once to the one of first instruction - if (i.Op != Op.OpName) - ReplaceRefs(matchingRefs, i.IdResult ?? throw new InvalidOperationException(), buffer); + if (!isOpWithResultId) + ReplaceRefs(matchingRefs, i.Data.IdResult ?? throw new InvalidOperationException(), buffer); } // Restart from last different instruction From 32c87c75e379e38a7e36b8a1ea1ff68057344baa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 9 Dec 2025 23:10:08 +0900 Subject: [PATCH 0563/1182] Fix static accessor --- src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 8 ++++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 6 ------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 5feca40ca6..b6f3a10f80 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -1,5 +1,6 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -229,14 +230,17 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) var inheritedShaderCount = table.InheritedShaders.Count; classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.InheritedShaders, ResolveStep.Compile, builder.GetBuffer()); - for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { table.InheritedShaders[i].Symbol = ShaderClass.LoadExternalShaderType(table, table.InheritedShaders[i]); ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); } - symbol = table.ResolveSymbol(Name); + // We add the typename as a symbol (similar to static access in C#) + var shaderId = context.GetOrRegister(classSource.Symbol); + symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); + table.CurrentFrame.Add(classSource.Symbol.Name, symbol); + Type = symbol.Type; return EmitSymbol(compiler, builder, context, symbol); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 449078307c..62274fd7af 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -413,12 +413,6 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol if (addToRoot) table.CurrentFrame.AddImplicitShader(shaderType); - if (!addToRoot) - { - var symbol = new Symbol(new(shaderType.Name, SymbolKind.Shader), new PointerType(shaderType, Specification.StorageClass.Private), shaderId); - table.CurrentFrame.Add(shaderType.Name, symbol); - } - // Mark inherit context.Add(new OpSDSLMixinInherit(shaderId)); } From e16dd45a6deb5598e5367b2dc1f5e13be93895b5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 9 Dec 2025 23:10:49 +0900 Subject: [PATCH 0564/1182] Array: basic support --- .../SDSL/ShaderMixer.cs | 29 ++++++++++++++++--- .../FrameRenderer.OpenGL.cs | 9 ++++++ src/Stride.Shaders.Tests/TestHeaderParser.cs | 8 +++-- .../Parsing/SDSL/AST/Expression.cs | 27 +++++++++++------ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- .../Spirv/Building/Builder.CBuffer.cs | 3 +- src/Stride.Shaders/Spirv/Building/Context.cs | 11 ++++++- 7 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 548725aff0..a91177a77e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -206,8 +206,8 @@ private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContex EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) { var structId = context.Types[s]; - var hasOffsetDecorations = false; + var hasOffsetDecorations = false; foreach (var i in context.GetBuffer()) { if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructType == structId) @@ -234,7 +234,7 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); offset += memberSize; } - return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members }; + return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; } @@ -242,13 +242,34 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType) { return symbolType switch { - ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1 }, - ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1 }, + ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ArrayType a => ConvertArrayType(context, a), StructType s => ConvertStructType(context, s), // TODO: should we use RowCount instead? (need to update Stride) VectorType v => ConvertType(context, v.BaseType) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, MatrixType m => ConvertType(context, m.BaseType) with { Class = EffectParameterClass.Vector, RowCount = m.Rows, ColumnCount = m.Columns }, }; + + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a) + { + var typeId = context.Types[a]; + var elementType = ConvertType(context, a.BaseType); + + var hasStrideDecoration = false; + foreach (var i in context.GetBuffer()) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ArrayStride } } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) + { + hasStrideDecoration = true; + } + } + + var arrayStride = (elementType.ElementSize + 15) / 16 * 16; + context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); + + return elementType with { Elements = a.Size }; + } } // Scan LinkSDSL decorations diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index bef137c068..0b4ea5e167 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -298,6 +298,15 @@ private static unsafe void FillData(string value, EffectTypeDescription type, in { switch (type) { + case { Elements: > 1 }: + int index = 0; + var arrayStride = (type.ElementSize + 15) / 16 * 16; + foreach (var elementValue in TestHeaderParser.SplitArgs(value)) + { + FillData(elementValue, type with { Elements = 1 }, offset + arrayStride * index, cbufferDataPtr); + index++; + } + break; case { Class: EffectParameterClass.Struct }: var structParameters = TestHeaderParser.ParseParameters(value); foreach (var member in type.Members) diff --git a/src/Stride.Shaders.Tests/TestHeaderParser.cs b/src/Stride.Shaders.Tests/TestHeaderParser.cs index 02b5879a1f..0070a4032c 100644 --- a/src/Stride.Shaders.Tests/TestHeaderParser.cs +++ b/src/Stride.Shaders.Tests/TestHeaderParser.cs @@ -86,7 +86,7 @@ public static Dictionary ParseParameters(string args) /// Splits by commas but ignores commas inside quotes. /// Accepts both single- and double-quoted values. /// - private static IEnumerable SplitArgs(string args) + public static IEnumerable SplitArgs(string args) { if (string.IsNullOrEmpty(args)) yield break; @@ -96,6 +96,10 @@ private static IEnumerable SplitArgs(string args) bool inDoubleQuote = false; int parenthesisLevel = 0; + // Unwrap parenthesis + if (args[0] == '(' && args[^1] == ')') + args = args[1..^1]; + for (int i = 0; i < args.Length; i++) { char c = args[i]; @@ -117,12 +121,10 @@ private static IEnumerable SplitArgs(string args) if (c == '(' && !inSingleQuote && !inDoubleQuote) { parenthesisLevel++; - continue; } if (c == ')' && !inSingleQuote && !inDoubleQuote) { parenthesisLevel--; - continue; } if (c == ',' && !inSingleQuote && !inDoubleQuote && parenthesisLevel == 0) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 7bdf8ec2ea..24140ac628 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -476,19 +476,28 @@ void EmitOpAccessChain(Span accessChainIds) break; // Array indexer for shader compositions case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): - break; + // Array indexer for arrays + case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): + { + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + accessor.Type = new PointerType(t, p.StorageClass); + break; + } // Array indexer for vector/matrix case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): - var indexerValue = indexer.Index.CompileAsValue(table, compiler); - PushAccessChainId(accessChainIds, indexerValue.Id); - - accessor.Type = new PointerType(p.BaseType switch { - MatrixType m => new VectorType(m.BaseType, m.Rows), - VectorType v => v.BaseType, - }, p.StorageClass); - break; + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + + accessor.Type = new PointerType(p.BaseType switch + { + MatrixType m => new VectorType(m.BaseType, m.Rows), + VectorType v => v.BaseType, + }, p.StorageClass); + break; + } default: throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 62274fd7af..9ae201e5ac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -123,7 +123,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = types[typeArray.ElementType]; - types.Add(typeArray.ResultId, new ArrayType(innerType, typeArray.Length)); + types.Add(typeArray.ResultId, new ArrayType(innerType, (int)SpirvBuilder.GetConstantValue(typeArray.Length, buffer))); } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 48dac79ea6..12bb26a5cd 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -12,6 +12,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type { // Helper to multiply size without changing alignment static (int Size, int Alignment) MultiplySize((int Size, int Alignment) current, int count) => (current.Size * count, current.Alignment); + static (int Size, int Alignment) Array((int Size, int Alignment) current, int count) => ((current.Size + 15) / 16 * 16 * (count - 1) + current.Size, 16); return (symbol) switch { ScalarType { TypeName: "sbyte" or "byte" } => (1, 1), @@ -24,7 +25,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Columns - 1) + m.Rows)), MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Rows - 1) + m.Columns)), // Round up to 16 bytes (size of float4) - ArrayType a => ((TypeSizeInBuffer(a.BaseType, typeModifier).Size + 15) / 16 * 16 * a.Size, 16), + ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier), a.Size), // TODO: StructureType }; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 7d2c237db8..0e00c9c864 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -187,7 +187,7 @@ public int GetOrRegister(SymbolType? type) }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, - ArrayType a when a.Size != -1 => Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), a.Size)).IdResult, + ArrayType a when a.Size != -1 => RegisterArrayType(a), ArrayType a when a.Size == -1 => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), @@ -208,6 +208,15 @@ public int GetOrRegister(SymbolType? type) } } + private int? RegisterArrayType(ArrayType a) + { + var sizeId = a.Size != -1 + ? CompileConstant((int)a.Size).Id + : throw new NotImplementedException(); + + return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; + } + public int ImportShaderType(ShaderSymbol shaderSymbol) { FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); From 2c96413fb7e530fb8cdfb37eac367941cbc4c0c3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 08:49:51 +0900 Subject: [PATCH 0565/1182] Added support for scalar value ctors, i.e. float(3.0) --- assets/SDSL/RenderTests/CompositeCtor.sdsl | 5 +++-- src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 17 +++++++++++++++++ .../Parsers/LiteralParsers/LiteralParsers.cs | 5 +---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositeCtor.sdsl b/assets/SDSL/RenderTests/CompositeCtor.sdsl index 48d2e4d02f..056eaa06d5 100644 --- a/assets/SDSL/RenderTests/CompositeCtor.sdsl +++ b/assets/SDSL/RenderTests/CompositeCtor.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#01020203, cbuffer.Test=(Test1=0)) +// PSMain(ExpectedResult=#08020203, cbuffer.Test=(Test1=0)) // PSMain(ExpectedResult=#01040403, cbuffer.Test=(Test1=1)) // PSMain(ExpectedResult=#01060606, cbuffer.Test=(Test1=2)) // PSMain(ExpectedResult=#02020101, cbuffer.Test=(Test1=3)) @@ -19,6 +19,7 @@ shader CompositeCtor { float f1 = 1.0 / 255.0; float2 f2 = 2.0 / 255.0; + float f1b = float(7.0 / 255.0); float2x2 f2x2 = float2x2(f1, f2 * 2.0, f1 * 3.0); float3 f3 = float3(f1, f2 * 3.0); float4 f4 = float4(f3, f1); @@ -26,7 +27,7 @@ shader CompositeCtor float3x3 m = float3x3(f3, f2, f4); if (Test1 == 0) - streams.ColorTarget = float4(f1, f2, f1 * 3.0); + streams.ColorTarget = float4(f1 + f1b, f2, f1 * 3.0); if (Test1 == 1) streams.ColorTarget = float4(f2x2); if (Test1 == 2) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index b6f3a10f80..bc6cfcc458 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -101,6 +101,23 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } +public class ExpressionLiteral(Expression value, TypeName typeName, TextLocation info) : ValueLiteral(info) +{ + public Expression Value { get; set; } = value; + public TypeName TypeName { get; set; } = typeName; + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var castType = TypeName.ResolveType(table); + var value = Value.CompileAsValue(table, compiler); + + Type = castType; + + return builder.Convert(context, value, castType); + } +} + public abstract class CompositeLiteral(TextLocation info) : ValueLiteral(info) { public List Values { get; set; } = []; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 6e74440b18..75bd3bb57b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -191,10 +191,7 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) ) { - parsed = new VectorLiteral(new TypeName(baseType, scanner[position..tnPos]), scanner[position..scanner.Position]) - { - Values = [value] - }; + parsed = new ExpressionLiteral(value, new TypeName(baseType, scanner[position..tnPos]), scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position); From fa25e48748d89276100b4ea71f2b620286e60dd7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 09:40:56 +0900 Subject: [PATCH 0566/1182] Various improvements and fixes for literal values --- assets/SDSL/RenderTests/CompositeCtor.sdsl | 8 ++++++++ src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 4 ++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 +++++++- .../SDSL/Parsers/LiteralParsers/LiteralParsers.cs | 6 +++--- .../SDSL/Parsers/LiteralParsers/NumberParsers.cs | 13 ++++++++----- .../Spirv/Building/Builder.Expressions.cs | 4 +++- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositeCtor.sdsl b/assets/SDSL/RenderTests/CompositeCtor.sdsl index 056eaa06d5..976aa7c463 100644 --- a/assets/SDSL/RenderTests/CompositeCtor.sdsl +++ b/assets/SDSL/RenderTests/CompositeCtor.sdsl @@ -3,6 +3,7 @@ // PSMain(ExpectedResult=#01060606, cbuffer.Test=(Test1=2)) // PSMain(ExpectedResult=#02020101, cbuffer.Test=(Test1=3)) // PSMain(ExpectedResult=#06060101, cbuffer.Test=(Test1=4)) +// PSMain(ExpectedResult=#08131103, cbuffer.Test=(Test1=5)) namespace Stride.Shaders.Tests; @@ -26,6 +27,11 @@ shader CompositeCtor float3x3 m = float3x3(f3, f2, f4); + uint i1 = uint(0x0008); + float i2 = float(0x0013); + int i3 = int(-17) * -1; + int i4 = 3u; + if (Test1 == 0) streams.ColorTarget = float4(f1 + f1b, f2, f1 * 3.0); if (Test1 == 1) @@ -36,5 +42,7 @@ shader CompositeCtor streams.ColorTarget = m[1].xyzz; if (Test1 == 4) streams.ColorTarget = m[2].xyzz; + if (Test1 == 5) + streams.ColorTarget = float4(i1, i2, i3, i4) / 255.0; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index bc6cfcc458..e3815e6d03 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -84,9 +84,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } -public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(32, false, false), (long)value, info) +public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(value > uint.MaxValue ? 64 : 32, false, false), (long)value, info) { - public override SymbolType? Type => ScalarType.From("long"); + public override SymbolType? Type => Suffix.Size > 32 ? ScalarType.From("ulong") : ScalarType.From("uint"); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 9ae201e5ac..dd952d72e8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -77,7 +77,13 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeInt) { OpTypeInt intInstruction = instruction; - types.Add(intInstruction.ResultId, ScalarType.From("int")); + types.Add(intInstruction.ResultId, (intInstruction.Width, intInstruction.Signedness == 1) switch + { + (32, true) => ScalarType.From("int"), + (32, false) => ScalarType.From("uint"), + (64, true) => ScalarType.From("long"), + (64, false) => ScalarType.From("ulong"), + }); } else if (instruction.Op == Op.OpTypeBool) { diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 75bd3bb57b..d8d09bce50 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -311,7 +311,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { suffix = new(32, false, false); - if (Tokens.AnyOf(["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "U", "L"], ref scanner, out var matched, advance: true)) + if (Tokens.AnyOf(["u8", "u16", "u32", "u64", "i8", "i16", "i32", "i64", "u", "U", "l", "L"], ref scanner, out var matched, advance: true)) { suffix = matched switch { @@ -323,8 +323,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o "i16" => new(16, false, true), "i32" => new(32, false, true), "i64" => new(64, false, true), - "U" => new(32, false, false), - "L" => new(32, false, true), + "u" or "U" => new(32, false, false), + "l" or "L" => new(32, false, true), _ => throw new NotImplementedException() }; return true; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 32e147fa5a..8b7d29f480 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -116,15 +116,18 @@ public static bool Hex(ref TScanner scanner, ParseResult result, out L ulong sum = 0; - for (int i = 0; i < scanner.Position - position - 2; i += 1) + for (int i = position + 2; i < scanner.Position; i++) { - var v = Hex2int(scanner.Span[i]); - var add = v * Math.Pow(16, i); - if (ulong.MaxValue - sum < add) + // Check if multiplying by 16 would not overflow ulong + if ((sum & ~(ulong)long.MaxValue) != 0) { - result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner[position], scanner.Memory)); + result.Errors.Add(new ParseError("Hex value bigger than ulong.", scanner[i], scanner.Memory)); return false; } + + sum <<= 4; + var v = Hex2int(scanner.Span[i]); + sum += (uint)v; } parsed = new HexLiteral(sum, scanner[position..scanner.Position]); return true; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index a7a6b07846..0241446f46 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -28,7 +28,7 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle { (ScalarType { TypeName: "long" }, _) or (_, ScalarType { TypeName: "long" }) => throw new NotImplementedException("64bit integers"), // Matching types - (ScalarType { TypeName: "int" or "uint" or "float" or "double" } l, ScalarType r) when l == r => l, + (ScalarType { TypeName: "int" or "uint" or "float" or "double" or "bool" } l, ScalarType r) when l == r => l, // If one side is float and other is non-floating, promote to floating (ScalarType { TypeName: "int" or "uint" } l, ScalarType { TypeName: "float" or "double" } r) => r, (ScalarType { TypeName: "float" or "double" } l, ScalarType { TypeName: "int" or "uint" } r) => l, @@ -331,11 +331,13 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy { // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion (ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { TypeName: "float" }, ScalarType { TypeName: "uint" }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { TypeName: "float" }, ScalarType { TypeName: "bool" }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), (ScalarType { TypeName: "int" }, ScalarType { TypeName: "bool" }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { TypeName: "uint" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), From ab3a1acc0d7ff6facb3a3d6e85c2626f1900a23e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 11:52:43 +0900 Subject: [PATCH 0567/1182] Converted BasicBlock.cs to UTF8 --- .../Spirv/Building/BasicBlocks.cs | Bin 5260 -> 2554 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index d63151ed4f0a8bec40b2b3f514900272e34c63fa..18eb17c8064341a4ae3fefce9cc140500c0bc579 100644 GIT binary patch literal 2554 zcmb7GQE%EX5Ps)ZoOl9_f%ZCRs?cATybS;!7r0=WZGi}14MjSP;`E_Lr&ta6#mp^^ z`ZwEs!Q%$NBaVsUMIgju7~K_=4a*%ZVAir^!&9)zfw`izxP&~9363a>3`9Bs|I3q` zP${s8*Be9I@ZkT1w zT7HO%$Y2y7k2jW?n*QXLzDJF78PlXcwOFS7-$<1frK2$(j>bMg%7h-D-Vt>Ai*J?Q zPgez#&u#;Jf-irLSzb=U6|60e5c=$zN+~W{h3p6Nm z#!eJ=q%#gi!T~#O=)u7UFZX7C7$DVdd#QP>9X}yMyEzU1et$?bXBJ(#-aA*`6*X+* zFl(E3u*fyT$W=Eqi7b@o{2o%nFrt&I8cSzSs6(^mRlLwL*0ltGw9dB^sNOnM3NVJR za9Ncb{o)v&dUaDfhgPQu>()x;5Sx`{FZ{e*TNGP^pvyvw9iBx{ItHRVyn{oa8{w3P zH_XCkKWSVC5!}-yz)@qSVnKADLl^iM#uL+mt#ke!#7b$D%&jnXfrk+|I2lK3k1`RtYx-_53RAh8k$1q}6yl zS*~6?zU;`kb#%e)nc z6?>-_z*l(`IKESHkVnJi?6yRP)4iMt=t3fD92Y07(HHk{rApf z3Yjyxx@Q?pIfNB`e0q>RU)e?5#;|*Yr*mj-Ne5S(d`sI%sRJ3pbHzpdrQG!2E8!=R zJ!n}%+X$Lw@>>qVE?a#UG@r_`e3h4Sj=L-D8{!SxL^P-2dycCy&^IO)z}|LH{t#;k z@bBZhg`G**IS+g-;UV9g;5jWc-FvtyvTX`^ZAcv8y#zbRxym3)#?|@SPRhIqk`wIb z$2Ab&8U99iYN+qaGsy1Z`v87-;W?RzeK7y%Z`uO&f|k2vMYO)|1z4CuCv_Lu@NKnj zcs`^ph6(NX0;`NC#(*P6P8awvR>^x8YYXtnZ;b?avLEiq>rfg|e8kaW%u$QJMZKC;wr0P^jqgp{Q~b{75P!@TwMcV6 z-g_JDVNCtM3gMTF5d5y*w$F@Oy?k_ zu)_bsdlTd(D+}Xmw(?Qe8W~OvH~V#lig9VmC+HYK1FIst2{U>u7r|E5k;rrCd@bKg zqTw;n@Q5o%#beO+Y(mGSddwFwT8>g)=O(o3=Yeq;=Ky(REGV-#xVj8cwu>wFrv+F_ zL^G*cLhSuElCo9DeXEw{c^-GdqCRL{jQOyDe>3EkO$*E_=7ZPJLsYp5>hn)LWgL@N zU;ThQ8mIcO)$bNEYZB^gf;X1P0qwi2_r#l1R|h+E;)-pq)4i3m*!JU+>fs*bJ9_;{ zP=p<4L$P`e%HzWc#PFmSMAPS_I!L%?pB216RZk%uu-gNVxE$l6yOJa#_WW)q{K@aE12Tp{n!3pN?yI13K zJj+*NJv^HX!fe1iiMxP$Wz59WR_xUgWcUe1Pf4s6de&qOB>P@V{p4|g=cm9xPZ;b# zdeY0{VHjWJCW-sBgmw{+RyaNJOtY;WXJC1@sy!!=NG$g7%RUri;We9B96~ow>m6KK z^{ivXU8^;x#rRxGEu4YdYYTX7Hds9=u8@3}D{+OVpXK|BG$W4Pa*Qk94?~TnUF;jg zpHm5|_ceC0YT7i*j!G=KliAb{mR@5D{l9(X1b(z(Gi@sNeY+Z8r<*ui+v(6AtN*27 zFUi&rvcR*d@@75EwbElo0w Date: Wed, 10 Dec 2025 11:47:03 +0900 Subject: [PATCH 0568/1182] Added support for swizzle on target side --- assets/SDSL/RenderTests/Swizzle.sdsl | 14 ++- src/Stride.Shaders.Tests/RenderingTests.cs | 15 +-- .../Parsing/SDSL/AST/Expression.cs | 106 +++++++++--------- .../Parsing/SDSL/AST/Statements.Flow.cs | 1 + .../Parsing/SDSL/AST/Statements.cs | 31 ++++- .../Spirv/Building/BasicBlocks.cs | 48 ++++++++ .../Spirv/Building/Builder.Expressions.cs | 67 ++++++++++- 7 files changed, 209 insertions(+), 73 deletions(-) diff --git a/assets/SDSL/RenderTests/Swizzle.sdsl b/assets/SDSL/RenderTests/Swizzle.sdsl index 159d8df42e..5f0c083ae3 100644 --- a/assets/SDSL/RenderTests/Swizzle.sdsl +++ b/assets/SDSL/RenderTests/Swizzle.sdsl @@ -5,6 +5,9 @@ // PSMain(ExpectedResult=#01010101, cbuffer.Test=(Test1=4)) // PSMain(ExpectedResult=#02040608, cbuffer.Test=(Test1=5)) // PSMain(ExpectedResult=#02020202, cbuffer.Test=(Test1=6)) +// PSMain(ExpectedResult=#02030401, cbuffer.Test=(Test1=7)) +// PSMain(ExpectedResult=#02040103, cbuffer.Test=(Test1=8)) +// PSMain(ExpectedResult=#05060308, cbuffer.Test=(Test1=9)) namespace Stride.Shaders.Tests; @@ -37,10 +40,11 @@ shader Swizzle if (Test1 == 6) // second swizzle is from a non-pointer value and will use OpCompositeExtract streams.ColorTarget = (streams.ColorTarget.xyzw * 2).x.xxxx; - // TODO: swizzle target is not supported yet - //if (Test1 == 7) - // streams.ColorTarget.wxyz = streams.ColorTarget; - //if (Test1 == 8) - // streams.ColorTarget.wxyz.wyxz = streams.ColorTarget; + if (Test1 == 7) + streams.ColorTarget.wxyz = streams.ColorTarget; + if (Test1 == 8) + streams.ColorTarget.wxyz.wyxz = streams.ColorTarget; + if (Test1 == 9) + streams.ColorTarget.xyw += streams.ColorTarget.w; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index b9e77fcd4a..71b4ea869b 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -99,6 +99,12 @@ public void RenderTest1(string shaderName) // Check output color value against expected result var expectedColor = StringToRgba(parameters["ExpectedResult"]); var pixel = pixels[0, 0].PackedValue; + // Swap endianess + pixel = ((pixel & 0x000000FF) << 24) + | (pixel & 0x0000FF00) << 8 + | ((pixel & 0x00FF0000) >> 8) + | (pixel & 0xFF000000) >> 24; + Assert.Equal(expectedColor.ToString("X8"), pixel.ToString("X8")); } } @@ -121,13 +127,8 @@ public static uint StringToRgba(string? stringColor) var intValue = 0xFF000000; if (stringColor?.StartsWith('#') == true) { - if (stringColor.Length == "#00000000".Length && uint.TryParse(stringColor.AsSpan(1, 8), NumberStyles.HexNumber, null, out intValue)) - { - intValue = ((intValue & 0x000000FF) << 24) - | (intValue & 0x0000FF00) << 8 - | ((intValue & 0x00FF0000) >> 8) - | (intValue & 0xFF000000) >> 24; - } + if (stringColor.Length == "#00000000".Length) + uint.TryParse(stringColor.AsSpan(1, 8), NumberStyles.HexNumber, null, out intValue); } return intValue; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 24140ac628..2cacce6ad5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -26,12 +26,14 @@ public SpirvValue Compile(SymbolTable table, CompilerUnit compiler) public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); - public SymbolType? ValueType => Type is PointerType pointerType ? pointerType.BaseType : Type; + public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) { var result = Compile(table, compiler); - return compiler.Builder.AsValue(compiler.Context, result); + result = compiler.Builder.AsValue(compiler.Context, result); + ValueType = compiler.Context.ReverseTypes[result.TypeId]; + return result; } } @@ -178,6 +180,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) case Operator.Inc: case Operator.Dec: { + expression.ThrowIfSwizzle(); if (!isPointer) throw new InvalidOperationException($"Can't use increment/decrement expression on non-pointer expression {Expression}"); @@ -279,6 +282,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) { result = streamVar.Compile(table, compiler); + result.ThrowIfSwizzle(); currentValueType = streamVar.Type; firstIndex = 1; } @@ -287,6 +291,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; result = methodCall.Compile(table, compiler); + result.ThrowIfSwizzle(); currentValueType = methodCall.Type; firstIndex = 1; } @@ -295,7 +300,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) result = Source.Compile(table, compiler); currentValueType = Source.Type; } - if (Source is Identifier { ValueType: TextureType or Texture2DType or Texture3DType } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) + if (Source is Identifier { Type: PointerType { BaseType: TextureType or Texture2DType or Texture3DType } } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) { result = Source.CompileAsValue(table, compiler); if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) @@ -342,7 +347,7 @@ void EmitOpAccessChain(Span accessChainIds) var resultType = context.GetOrRegister(currentValueType); var test = new LiteralArray(accessChainIds); var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); - result = new SpirvValue(accessChain.ResultId, resultType); + result = new SpirvValue(accessChain.ResultId, resultType) { Swizzles = result.Swizzles }; } accessChainIdCount = 0; @@ -352,7 +357,6 @@ void EmitOpAccessChain(Span accessChainIds) for (var i = firstIndex; i < Accessors.Count; i++) { var accessor = Accessors[i]; - ProcessAgain: switch (currentValueType, accessor) { case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): @@ -389,17 +393,18 @@ void EmitOpAccessChain(Span accessChainIds) case (PointerType { BaseType: VectorType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { - // For swizzle larger than one element, we need to do a OpLoad then do a OpVectorShuffle/OpCompositeExtract (next switch case) - - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - var load = builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null)); - result = new(load); + result.ApplySwizzles(swizzleIndices); - currentValueType = s; + // Check resulting swizzles + for (int j = 0; j < result.Swizzles.Length; ++j) + if (swizzleIndices[j] >= s.Size) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - goto ProcessAgain; + accessor.Type = currentValueType; } else { @@ -408,50 +413,31 @@ void EmitOpAccessChain(Span accessChainIds) } break; case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - - Span swizzleIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - - if (swizzle.Length > 1) { - // Apply swizzle - var resultType = new VectorType(v.BaseType, swizzle.Length); - var shuffle = builder.InsertData(new OpVectorShuffle(context.GetOrRegister(resultType), context.Bound++, result.Id, result.Id, new(swizzleIndices))); - result = new(shuffle); + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - accessor.Type = resultType; - } - else if (swizzle.Length == 1) - { - // Apply swizzle - var resultType = v.BaseType; - var extract = builder.InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, result.Id, [context.CompileConstant(swizzleIndices[0]).Id])); - result = new(extract); + (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); + accessor.Type = v; - accessor.Type = resultType; + break; } - else - throw new InvalidOperationException(); - - break; case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { - // For swizzle larger than one element, we need to do a OpLoad then do a OpVectorShuffle/OpCompositeExtract (next switch case) + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); - - var load = builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null)); - result = new(load); - - currentValueType = s; - - goto ProcessAgain; + result.ApplySwizzles(swizzleIndices); + accessor.Type = currentValueType; } else { + if (ConvertSwizzle(swizzle[0]) != 0) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + // Do nothing accessor.Type = currentValueType; } @@ -459,14 +445,16 @@ void EmitOpAccessChain(Span accessChainIds) case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { - var resultType = new VectorType(s, swizzle.Length); - Span constructIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < constructIndices.Length; ++j) - constructIndices[j] = result.Id; - var construct = builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, new(constructIndices))); - result = new(construct); - - accessor.Type = resultType; + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + { + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + if (swizzleIndices[j] != 0) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } + + (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); + accessor.Type = s; } else { @@ -522,16 +510,22 @@ private static int ConvertSwizzle(char c) 'w' or 'a' => 3, }; - public override string ToString() + public override string ToString() => ToString(Accessors.Count); + + public string ToString(int accessorCount) { var builder = new StringBuilder().Append(Source); - foreach (var a in Accessors) + for (int i = 0; i < accessorCount; i++) + { + Expression? a = Accessors[i]; if (a is IndexerExpression) builder.Append(a); else if (a is PostfixIncrement) builder.Append(a); else builder.Append('.').Append(a); + } + return builder.ToString(); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 32f68be702..319c0a6fe2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -55,6 +55,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; var collection = Collection.Compile(table, compiler); + collection.ThrowIfSwizzle(); if (!(Collection.Type is PointerType p && p.BaseType is ArrayType arrayType)) throw new InvalidOperationException("foreach: Array type is expected"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 3b3aabeab1..575f851d3d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -44,7 +44,7 @@ public class Return(TextLocation info, Expression? expression = null) : Statemen public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, _) = compiler; - builder.Return(Value?.Compile(table, compiler)); + builder.Return(Value?.CompileAsValue(table, compiler)); Type = Value?.Type ?? ScalarType.From("void"); } public override string ToString() @@ -92,7 +92,7 @@ public List? ArraySizes public override void Compile(SymbolTable table, CompilerUnit compiler) { Variable.Type = TypeName.ResolveType(table); - var initialValue = Value?.Compile(table, compiler); + var initialValue = Value?.CompileAsValue(table, compiler); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); @@ -192,7 +192,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { var target = variable.Variable.Compile(table, compiler); var source = variable.Value!.CompileAsValue(table, compiler); - if (variable.Variable.Type is not PointerType) + if (variable.Variable.Type is not PointerType p) throw new InvalidOperationException("can only assign to pointer type"); if (variable.Operator != AssignOperator.Simple) @@ -218,7 +218,30 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } // Make sure to convert to proper type - source = builder.Convert(context, source, variable.Variable.ValueType); + var resultType = target.GetValueType(context, true); + source = builder.Convert(context, source, resultType); + + if (target.Swizzles != null) + { + var valueType = context.Types[p.BaseType]; + var loadId = builder.Insert(new OpLoad(valueType, context.Bound++, target.Id, null)).ResultId; + // Shuffle with new data + switch (p.BaseType) + { + case VectorType v: + Span shuffleIndices = stackalloc int[v.Size]; + // Default: source values + for (int j = 0; j < v.Size; ++j) + shuffleIndices[j] = j; + // Update using swizzle target (from 2nd new value vector) + for (int j = 0; j < target.Swizzles.Length; ++j) + shuffleIndices[target.Swizzles[j]] = v.Size + j; + source = new(builder.InsertData(new OpVectorShuffle(valueType, context.Bound++, loadId, source.Id, new(shuffleIndices)))); + break; + default: + throw new NotImplementedException(); + } + } builder.Insert(new OpStore(target.Id, source.Id, null)); } } diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index 18eb17c806..490daf1e06 100644 --- a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs +++ b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs @@ -33,6 +33,54 @@ public SpirvValue(OpData instruction, string? name = null) public int Id { get; set; } public int TypeId { get; set; } public string? Name { get; set; } + + /// + /// Swizzle to apply to the value. + /// + /// + /// Swizzle doesn't affect the . For example, float3().xy will have float3. + /// + public int[]? Swizzles { get; set; } + + public SymbolType GetValueType(SpirvContext context, bool includeSwizzles) + { + var type = context.ReverseTypes[TypeId]; + if (type is PointerType p) + type = p.BaseType; + + if (includeSwizzles && Swizzles != null) + { + type = (type, Swizzles.Length) switch + { + (ScalarType s, > 1) => new VectorType(s, Swizzles.Length), + (ScalarType s, 1) => s, + (VectorType v, >1) => new VectorType(v.BaseType, Swizzles.Length), + (VectorType v, 1) => v.BaseType, + }; + } + + return type; + } + + public void ApplySwizzles(Span swizzleIndices) + { + var oldSwizzles = Swizzles; + Swizzles = swizzleIndices.ToArray(); + if (oldSwizzles != null) + { + // Reapply swizzle on existing swizzles + for (int i = 0; i < Swizzles.Length; ++i) + Swizzles[i] = oldSwizzles[Swizzles[i]]; + } + + // TODO: remove swizzle if identity? + } + + internal void ThrowIfSwizzle() + { + if (Swizzles != null) + throw new InvalidOperationException("This expression doesn't handle swizzle"); + } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 0241446f46..83ca7c99b2 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -17,11 +17,76 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) { type = pointerType.BaseType; var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null)); - result = new(inst.ResultId, inst.ResultType); + result = new(inst.ResultId, inst.ResultType) { Swizzles = result.Swizzles }; } + + if (result.Swizzles != null) + { + (result, _) = ApplySwizzles(context, result, result.Swizzles); + } + return result; } + public (SpirvValue, SymbolType) ApplySwizzles(SpirvContext context, SpirvValue value, Span swizzleIndices) + { + var valueType = context.ReverseTypes[value.TypeId]; + return valueType switch + { + ScalarType s => ApplyScalarSwizzles(context, value, s, swizzleIndices), + VectorType v => ApplyVectorSwizzles(context, value, v, swizzleIndices), + }; + } + + public (SpirvValue, SymbolType) ApplyScalarSwizzles(SpirvContext context, SpirvValue value, ScalarType s, Span swizzleIndices) + { + var resultType = new VectorType(s, swizzleIndices.Length); + + Span constructIndices = stackalloc int[swizzleIndices.Length]; + for (int j = 0; j < constructIndices.Length; ++j) + { + if (swizzleIndices[j] != 0) + throw new InvalidOperationException("Invalid swizzle for scalar type"); + + constructIndices[j] = value.Id; + } + + SpirvValue result; + var construct = InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, new(constructIndices))); + result = new(construct); + return (result, resultType); + } + + public (SpirvValue, SymbolType) ApplyVectorSwizzles(SpirvContext context, SpirvValue value, VectorType v, Span swizzleIndices) + { + for (int j = 0; j < swizzleIndices.Length; ++j) + { + if (swizzleIndices[j] >= v.Size) + throw new InvalidOperationException("Invalid swizzle for vector type"); + } + + if (swizzleIndices.Length > 1) + { + // Apply swizzle + var resultType = new VectorType(v.BaseType, swizzleIndices.Length); + var shuffle = InsertData(new OpVectorShuffle(context.GetOrRegister(resultType), context.Bound++, value.Id, value.Id, new(swizzleIndices))); + value = new(shuffle); + + return (value, resultType); + } + else if (swizzleIndices.Length == 1) + { + // Apply swizzle + var resultType = v.BaseType; + var extract = InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, value.Id, [context.CompileConstant(swizzleIndices[0]).Id])); + value = new(extract); + + return (value, resultType); + } + else + throw new InvalidOperationException(); + } + public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftElementType, SymbolType rightElementType) { return (leftElementType, rightElementType) switch From 2739663aae130f6d8855ba48e379ed18d94e2a84 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 12:05:09 +0900 Subject: [PATCH 0569/1182] Added !bool operator --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 2cacce6ad5..41ba26a2be 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -198,6 +198,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Type = type; return expression; } + case Operator.Not: + { + if (valueType.GetElementType() is not ScalarType { TypeName: "bool" }) + throw new InvalidOperationException(); + var result = builder.Insert(new OpLogicalNot(valueExpression.TypeId, context.Bound++, valueExpression.Id)); + Type = valueType; + return new(result.ResultId, result.ResultType); + } case Operator.Plus: // Nothing to do return expression; From 2049a90cc70a99afef0027c90f3f2f0ab20c5408 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 18:43:24 +0900 Subject: [PATCH 0570/1182] Added support for postfix expressions ++ and -- --- .../SDSL/RenderTests/CompositionArray1.sdsl | 42 ++++--- .../SDSL/ShaderMixer.cs | 113 +++++++++--------- src/Stride.Shaders/Core/SymbolFrame.cs | 4 +- src/Stride.Shaders/Core/SymbolTypes.cs | 54 +++++---- .../Parsing/Analysis/SymbolTable.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 33 ++++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 64 ++++++++-- .../Spirv/Building/Builder.Class.cs | 96 ++++++++------- src/Stride.Shaders/Spirv/Building/Context.cs | 18 ++- 9 files changed, 263 insertions(+), 163 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionArray1.sdsl b/assets/SDSL/RenderTests/CompositionArray1.sdsl index 81056feb4c..703cbcedc0 100644 --- a/assets/SDSL/RenderTests/CompositionArray1.sdsl +++ b/assets/SDSL/RenderTests/CompositionArray1.sdsl @@ -1,44 +1,52 @@ -// PSMain(ExpectedResult=#46464646) +// PSMain(ExpectedResult=#1A250000) namespace Stride.Shaders.Tests; shader CompositionBase { - float4 Compute() + float Compute() { - return float4(5.0, 5.0, 5.0, 5.0) / 255.0; + return 3.0 / 255.0; } }; shader CompositionShaderA : CompositionBase { - override float4 Compute() + override float Compute() { - return float4(20.0, 20.0, 20.0, 20.0) / 255.0; + return 5.0 / 255.0; } }; shader CompositionShaderB : CompositionBase { - override float4 Compute() + override float Compute() { - return base.Compute() + float4(10.0, 10.0, 10.0, 10.0) / 255.0; + return base.Compute() + 13.0 / 255.0; } }; + +shader CompositionTestArray +{ + stage compose CompositionBase CompsInherited[]; +} -shader CompositionTest +shader CompositionTest : CompositionTestArray { stream float4 ColorTarget : SV_Target0; - stage compose CompositionBase Comp1; - stage compose CompositionBase Comps[]; + stage compose CompositionBase CompsLocal[]; void PSMain() { streams.ColorTarget = 0.0; - foreach(var comp in Comps) + foreach(var comp in CompsLocal) + { + streams.ColorTarget.x += comp.Compute(); + } + foreach(var comp in CompsInherited) { - streams.ColorTarget += comp.Compute(); + streams.ColorTarget.y += comp.Compute(); } } }; @@ -46,8 +54,10 @@ shader CompositionTest effect CompositionArray1 { mixin CompositionTest; - mixin compose Comps += CompositionShaderA; - mixin compose Comps += CompositionShaderB; - mixin compose Comps += CompositionShaderA; - mixin compose Comps += CompositionShaderB; + mixin compose CompsLocal += CompositionShaderA; + mixin compose CompsLocal += CompositionShaderA; + mixin compose CompsLocal += CompositionShaderB; + mixin compose CompsInherited += CompositionShaderA; + mixin compose CompsInherited += CompositionShaderB; + mixin compose CompsInherited += CompositionShaderB; } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a91177a77e..9db09bd137 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -30,7 +30,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect var temp = new NewSpirvBuffer(); var context = new SpirvContext(); - var table = new SymbolTable(); + var table = new SymbolTable { ShaderLoader = ShaderLoader }; var effectEvaluator = new EffectEvaluator(ShaderLoader); shaderSource = effectEvaluator.EvaluateEffects(shaderSource); @@ -406,12 +406,10 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, } } - ExpandForeach(globalContext, context, buffer, mixinNode); - Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); // Patch method calls (virtual calls & base calls) - PatchMethodCalls(globalContext, context, buffer, mixinNode); + ProcessMemberAccessAndForeach(globalContext, context, buffer, mixinNode); // Process reflection Dictionary linkInfos = new(); @@ -772,66 +770,60 @@ private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); } - private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) + private static void ExpandForeach(SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) { - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + // Find matching ForeachEnd (taking into account nested foreach) + var depth = 1; + var endIndex = index; + while (depth > 0 && ++endIndex < buffer.Count - 1) { - var i = temp[index]; - - if (i.Data.Op == Op.OpForeachSDSL && (OpForeachSDSL)i is { } @foreach) - { - // Find matching ForeachEnd (taking into account nested foreach) - var depth = 1; - var endIndex = index; - while (depth > 0 && ++endIndex < temp.Count - 1) - { - if (temp[endIndex].Op == Op.OpForeachSDSL) - depth++; - else if (temp[endIndex].Op == Op.OpForeachEndSDSL) - depth--; - } - endIndex++; - - if (depth > 0) - throw new InvalidOperationException("Could not find end of foreach instruction"); + if (buffer[endIndex].Op == Op.OpForeachSDSL) + depth++; + else if (buffer[endIndex].Op == Op.OpForeachEndSDSL) + depth--; + } + endIndex++; - // Check the variable - if (!mixinNode.CompositionArrays.TryGetValue(@foreach.Collection, out var compositions)) - throw new InvalidOperationException($"Could not find compositions for expression [{@foreach.Collection}]"); + if (depth > 0) + throw new InvalidOperationException("Could not find end of foreach instruction"); - // Extract foreach buffer (with the foreach start/end) - var foreachBuffer = temp[index..endIndex]; - temp.RemoveRange(index, endIndex - index, false); + // Check the variable + if (!mixinNode.CompositionArrays.TryGetValue(@foreach.Collection, out var compositions)) + throw new InvalidOperationException($"Could not find compositions for expression [{@foreach.Collection}]"); - var foreachBufferCopy = new List(); - for (int j = 0; j < compositions.Length; ++j) - { - var idRemapping = new Dictionary(); + // Extract foreach buffer (with the foreach start/end) + var foreachBuffer = buffer[index..endIndex]; + buffer.RemoveRange(index, endIndex - index, false); - // Setup variable for iterator access - var accessChain = new OpAccessChain(0, context.Bound++, @foreach.Collection, [context.CompileConstant(j).Id]); - foreachBufferCopy.Add(new(accessChain.InstructionMemory)); - idRemapping.Add(@foreach.ResultId, accessChain); + var foreachBufferCopy = new List(); + // Note: Make sure we replace the OpForeachSDSL with a first OpNop, so that if a for() loop works fine and don't miss an instruction without having to do index-- + foreachBufferCopy.Add(new OpData(new OpNop().InstructionMemory)); + for (int j = 0; j < compositions.Length; ++j) + { + var idRemapping = new Dictionary(); - // Build a buffer with all foreach instructions (with new ids) - foreach (var i2 in foreachBuffer[1..^1]) // skip start/end - { - var i3 = new OpData(i2.Memory.Span); - // All result ids are remapped to new ids - if (i3.IdResult is int result) - idRemapping.Add(result, context.Bound++); - SpirvBuilder.RemapIds(idRemapping, i3); + // Setup variable for iterator access + var accessChain = new OpAccessChain(0, context.Bound++, @foreach.Collection, [context.CompileConstant(j).Id]); + foreachBufferCopy.Add(new(accessChain.InstructionMemory)); + idRemapping.Add(@foreach.ResultId, accessChain); - foreachBufferCopy.Add(i3); - } - } - temp.InsertRange(index, foreachBufferCopy.AsSpan()); - AdjustIndicesAfterAddingInstructions(mixinNode, index, foreachBufferCopy.Count); + // Build a buffer with all foreach instructions (with new ids) + foreach (var i2 in foreachBuffer[1..^1]) // skip start/end + { + var i3 = new OpData(i2.Memory.Span); + // All result ids are remapped to new ids + if (i3.IdResult is int result) + idRemapping.Add(result, context.Bound++); + SpirvBuilder.RemapIds(idRemapping, i3); - foreach (var inst in foreachBuffer) - inst.Dispose(); + foreachBufferCopy.Add(i3); } } + buffer.InsertRange(index, foreachBufferCopy.AsSpan()); + AdjustIndicesAfterAddingInstructions(mixinNode, index, foreachBufferCopy.Count - foreachBuffer.Count); + + foreach (var inst in foreachBuffer) + inst.Dispose(); } private static void AdjustIndicesAfterAddingInstructions(MixinNode mixinNode, int insertIndex, int insertCount) @@ -849,7 +841,7 @@ private static void AdjustIndicesAfterAddingInstructions(MixinNode mixinNode, in } } - private static void PatchMethodCalls(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) + private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) { var memberAccesses = new Dictionary(); var thisInstructions = new HashSet(); @@ -866,7 +858,11 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, SpirvCont if (memberAccesses.Count > 0) SpirvBuilder.RemapIds(memberAccesses, i.Data); - if (i.Data.Op == Op.OpThisSDSL && (OpThisSDSL)i is { } thisInstruction) + if (i.Data.Op == Op.OpForeachSDSL && (OpForeachSDSL)i is { } @foreach) + { + ExpandForeach(context, temp, mixinNode, index, @foreach); + } + else if (i.Data.Op == Op.OpThisSDSL && (OpThisSDSL)i is { } thisInstruction) { thisInstructions.Add(thisInstruction.ResultId); SetOpNop(i.Data.Memory.Span); @@ -885,7 +881,7 @@ private static void PatchMethodCalls(MixinGlobalContext globalContext, SpirvCont { if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions)) { - var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer()); + var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer(), temp); compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); SetOpNop(i.Data.Memory.Span); @@ -1062,7 +1058,10 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) || temp[i].Op == Op.OpSDSLEffect || temp[i].Op == Op.OpSDSLEffectEnd || temp[i].Op == Op.OpConstantStringSDSL - || temp[i].Op == Op.OpTypeGenericLinkSDSL) + || temp[i].Op == Op.OpTypeGenericLinkSDSL + || temp[i].Op == Op.OpSDSLImportShader + || temp[i].Op == Op.OpSDSLImportFunction + || temp[i].Op == Op.OpSDSLImportVariable) temp.RemoveAt(i--); else if (temp[i].Op == Op.OpDecorateString && ((OpDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) temp.RemoveAt(i--); diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index d503228ffd..3b68ee0074 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -8,7 +8,7 @@ public class SymbolFrame() { readonly Dictionary symbols = []; - readonly List implicitShaders = []; + readonly List implicitShaders = []; public Symbol this[string name] { @@ -16,7 +16,7 @@ public Symbol this[string name] set => symbols[name] = value; } - public void AddImplicitShader(ShaderSymbol shaderSymbol) + public void AddImplicitShader(LoadedShaderSymbol shaderSymbol) { implicitShaders.Add(shaderSymbol); } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 5c41000963..39872b0159 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -253,14 +253,8 @@ public sealed record ConstantBufferSymbol(string Name, List<(string Name, Symbol public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public sealed record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType +public record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { - public List<(Symbol Symbol, VariableFlagsMask Flags)> Variables { get; init; } = []; - - public List<(Symbol Symbol, FunctionFlagsMask Flags)> Methods { get; init; } = []; - - public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; - public string ToClassName() { if (GenericArguments.Length == 0) @@ -270,6 +264,34 @@ public string ToClassName() return className.ToClassName(); } + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append(Name); + if (GenericArguments.Length > 0) + { + builder.Append('<'); + for (int i = 0; i < GenericArguments.Length; i++) + { + if (i > 0) + builder.Append(','); + builder.Append(GenericArguments[i]); + } + builder.Append('>'); + } + return builder.ToString(); + } +} + +public sealed record LoadedShaderSymbol(string Name, int[] GenericArguments) : ShaderSymbol(Name, GenericArguments) +{ + public List<(Symbol Symbol, VariableFlagsMask Flags)> Variables { get; init; } = []; + + public List<(Symbol Symbol, FunctionFlagsMask Flags)> Methods { get; init; } = []; + + public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; + + internal bool TryResolveSymbol(string name, out Symbol symbol) { foreach (var c in Methods) @@ -308,23 +330,7 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) return false; } - public override string ToString() - { - var builder = new StringBuilder(); - builder.Append(Name); - if (GenericArguments.Length > 0) - { - builder.Append('<'); - for (int i = 0; i < GenericArguments.Length; i++) - { - if (i > 0) - builder.Append(','); - builder.Append(GenericArguments[i]); - } - builder.Append('>'); - } - return builder.ToString(); - } + public override string ToString() => base.ToString(); } public sealed record GenericLinkType : SymbolType; diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index da491d7592..b2fee5a42f 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -22,7 +22,7 @@ public partial class SymbolTable : ISymbolProvider public List CurrentSymbols { get; } = new(); // Only valid during compilation (not during ShaderMixin phase) - public ShaderSymbol? CurrentShader { get; set; } + public LoadedShaderSymbol? CurrentShader { get; set; } // Only valid during compilation (not during ShaderMixin phase) public List InheritedShaders { get; set; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 41ba26a2be..0429fbb911 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -62,7 +62,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Symbol functionSymbol; if (MemberCall != null) { - var type = (ShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; + var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; functionSymbol = type.Methods.Single(x => x.Symbol.Id.Name == Name).Symbol; } else @@ -180,6 +180,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) case Operator.Inc: case Operator.Dec: { + // Not supported yet expression.ThrowIfSwizzle(); if (!isPointer) throw new InvalidOperationException($"Can't use increment/decrement expression on non-pointer expression {Expression}"); @@ -369,15 +370,13 @@ void EmitOpAccessChain(Span accessChainIds) { case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): // Emit OpAccessChain with everything so far - // next start is i + 1 because current value doesn't add a call EmitOpAccessChain(accessChainIds); methodCall2.MemberCall = result; result = methodCall2.Compile(table, compiler); break; - case (PointerType { BaseType: ShaderSymbol s }, Identifier field): + case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): // Emit OpAccessChain with everything so far - // next start is i + 1 because current value doesn't add a call EmitOpAccessChain(accessChainIds); if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) @@ -492,6 +491,32 @@ void EmitOpAccessChain(Span accessChainIds) MatrixType m => new VectorType(m.BaseType, m.Rows), VectorType v => v.BaseType, }, p.StorageClass); + break; + } + case (PointerType { BaseType: var type }, PostfixIncrement postfix): + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + + // Not supported yet + result.ThrowIfSwizzle(); + + var resultPointer = result; + + // This is what this chain return (value before modification) + result = builder.AsValue(context, result); + + // Use integer so that it gets converted to proper type according to expression type + var constant1 = context.CompileConstant(1); + var modifiedValue = builder.BinaryOperation(context, result, postfix.Operator switch + { + Operator.Inc => Operator.Plus, + Operator.Dec => Operator.Minus, + }, constant1); + + // We store the modified value back in the variable + builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null)); + break; } default: diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index dd952d72e8..edcacc792c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -18,6 +18,18 @@ namespace Stride.Shaders.Parsing.SDSL.AST; +public interface IShaderImporter +{ + ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer); +} + +public class EmptyShaderImporter : IShaderImporter +{ + public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) + { + return new ShaderSymbol(classSource.ClassName, classSource.GenericArguments); + } +} public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration(info) { @@ -29,16 +41,18 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) - public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types) + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types, IShaderImporter? shaderImporter = null) { names = []; types = []; - ProcessNameAndTypes(buffer, start, end, names, types); + ProcessNameAndTypes(buffer, start, end, names, types, shaderImporter); } - public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types) + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types, IShaderImporter? shaderImporter = null) { + var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); + var memberNames = new Dictionary<(int, int), string>(); var blocks = new HashSet(); for (var i = start; i < end; i++) @@ -172,11 +186,18 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { types.Add(typeSampler.ResultId, new SamplerType()); } + else if (instruction.Op == Op.OpTypeGenericLinkSDSL && (OpTypeGenericLinkSDSL)instruction is { } typeGenericLink) + { + types.Add(typeGenericLink.ResultId, new GenericLinkType()); + } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { - types.Add(importShader.ResultId, new ShaderSymbol(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray())); + var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); + var shaderSymbol = realShaderImporter.Import(classSource, buffer); + + types.Add(importShader.ResultId, shaderSymbol); } else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) { @@ -201,9 +222,26 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } } - private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassInstantiation classSource) + public class ShaderImporter(SymbolTable table) : IShaderImporter + { + public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) + { + // Already processed? + if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) + return (ShaderSymbol)symbolType; + + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, buffer); + classSource.Buffer = shader; + var shaderType = LoadExternalShaderType(table, classSource); + table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); + + return shaderType; + } + } + + private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBuffer buffer, ShaderClassInstantiation classSource) { - ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types); + ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types, new ShaderImporter(table)); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); @@ -247,7 +285,7 @@ private static ShaderSymbol CreateShaderType(NewSpirvBuffer buffer, ShaderClassI } } - var shaderType = new ShaderSymbol(classSource.ClassName, classSource.GenericArguments) + var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) { Variables = variables, Methods = methods, @@ -309,7 +347,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) SpirvBuilder.BuildInheritanceList(table.ShaderLoader, shaderClassSource, inheritanceList, ResolveStep.Compile, context.GetBuffer()); } - var shaderSymbols = new List(); + var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { shaderSymbols.Add(mixin.Symbol = LoadExternalShaderType(table, mixin)); @@ -346,7 +384,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); classSource.Buffer = shader; var shaderType = LoadExternalShaderType(table, classSource); - table.DeclaredTypes.TryAdd(shaderType.ToString(), shaderType); + table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) memberType = svar.TypeName.ResolveType(table); @@ -375,7 +413,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } - var currentShader = new ShaderSymbol(Name, openGenerics); + var currentShader = new LoadedShaderSymbol(Name, openGenerics); RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; @@ -406,7 +444,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.Pop(); } - public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol shaderType, bool addToRoot) + public static void Inherit(SymbolTable table, SpirvContext context, LoadedShaderSymbol shaderType, bool addToRoot) { var shaderId = context.GetOrRegister(shaderType); @@ -423,11 +461,11 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderSymbol context.Add(new OpSDSLMixinInherit(shaderId)); } - public static ShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) + public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) { var shaderBuffer = classSource.Buffer; - var shaderType = CreateShaderType(shaderBuffer, classSource); + var shaderType = CreateShaderType(table, shaderBuffer, classSource); RegisterShaderType(table, shaderType); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index e500abe61d..b04eb79a00 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -31,7 +31,7 @@ public record class ShaderClassInstantiation(string ClassName, int[] GenericArgu public int[] GenericArguments { get; set; } = GenericArguments; - public ShaderSymbol Symbol { get; set; } + public LoadedShaderSymbol Symbol { get; set; } public int Start { get; set; } public int End { get; set; } @@ -139,15 +139,20 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade return inheritanceList[index]; } - public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) + public static object GetConstantValue(int constantId, params ReadOnlySpan buffers) { - if (!buffer.TryGetInstructionById(constantId, out var constant)) - throw new Exception("Cannot find constant instruction for id " + constantId); + foreach (var buffer in buffers) + { + if (buffer.TryGetInstructionById(constantId, out var constant)) + { + return GetConstantValue(constant.Data, buffers); + } + } - return GetConstantValue(constant.Data, buffer); + throw new Exception("Cannot find constant instruction for id " + constantId); } - public static object GetConstantValue(OpData data, NewSpirvBuffer buffer) + public static object GetConstantValue(OpData data, params ReadOnlySpan buffers) { int typeId = data.Op switch { @@ -155,40 +160,44 @@ public static object GetConstantValue(OpData data, NewSpirvBuffer buffer) _ => throw new Exception("Unsupported context dependent number in instruction " + data.Op) }; var operand = data.Get("value"); - if (buffer.TryGetInstructionById(typeId, out var typeInst)) + foreach (var buffer in buffers) { - if (typeInst.Op == Op.OpTypeInt) + if (buffer.TryGetInstructionById(typeId, out var typeInst)) { - var type = (OpTypeInt)typeInst; - return type switch + if (typeInst.Op == Op.OpTypeInt) { - { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), - { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), - { Width: 64, Signedness: 0 } => operand.ToLiteral(), - { Width: 64, Signedness: 1 } => operand.ToLiteral(), - _ => throw new NotImplementedException("Unsupported int width " + type.Width), - }; - } - else if (typeInst.Op == Op.OpTypeFloat) - { - var type = new OpTypeFloat(typeInst); - return type switch + var type = (OpTypeInt)typeInst; + return type switch + { + { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), + { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), + { Width: 64, Signedness: 0 } => operand.ToLiteral(), + { Width: 64, Signedness: 1 } => operand.ToLiteral(), + _ => throw new NotImplementedException("Unsupported int width " + type.Width), + }; + } + else if (typeInst.Op == Op.OpTypeFloat) { - { Width: 16 } => operand.ToLiteral(), - { Width: 32 } => operand.ToLiteral(), - { Width: 64 } => operand.ToLiteral(), - _ => throw new NotImplementedException("Unsupported float width " + type.Width), - }; + var type = new OpTypeFloat(typeInst); + return type switch + { + { Width: 16 } => operand.ToLiteral(), + { Width: 32 } => operand.ToLiteral(), + { Width: 64 } => operand.ToLiteral(), + _ => throw new NotImplementedException("Unsupported float width " + type.Width), + }; + } + else + throw new NotImplementedException("Unsupported context dependent number with type " + typeInst.Op); } - else - throw new NotImplementedException("Unsupported context dependent number with type " + typeInst.Op); } - else - throw new Exception("Cannot find type instruction for id " + typeId); + throw new Exception("Cannot find type instruction for id " + typeId); } - private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer shader, string[] genericValues) + private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer shader, string className, string[] genericValues) { + Console.WriteLine($"[Shader] Instantiating {className} with values {string.Join(",", genericValues)}"); + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); var bound = shader.Header.Bound; @@ -225,8 +234,8 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer instantiatingBuffer) { - Console.WriteLine($"Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); - Console.WriteLine($"Instantiating from buffer generics {instantiatingBuffer[0].Data}:"); + Console.WriteLine($"[Shader] Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); + Console.WriteLine($"[Shader] Instantiating from buffer generics {instantiatingBuffer[0].Data}:"); foreach (var i in instantiatingBuffer) { if (i.Data.IdResult is int id && classSource.GenericArguments.Contains(id)) @@ -418,9 +427,10 @@ public static void RemapIds(Dictionary idRemapping, OpData i) /// public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) { - var shader = GetOrLoadShader(shaderLoader, classSource.ClassName); + var shader = GetOrLoadShader(shaderLoader, classSource.ClassName, out var isFromCache); - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + if (!isFromCache) + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); if (classSource.GenericArguments.Length > 0) { @@ -436,16 +446,17 @@ public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues) { - var shader = GetOrLoadShader(shaderLoader, className); + var shader = GetOrLoadShader(shaderLoader, className, out var isFromCache); - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + if (!isFromCache) + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); if (genericValues != null && genericValues.Length > 0) { // Copy shader shader = CopyShader(shader); - InstantiateGenericShaderUsingGenericValues(shader, genericValues); + InstantiateGenericShaderUsingGenericValues(shader, className, genericValues); Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } @@ -481,11 +492,16 @@ public static List CollectGenerics(NewSpirvBuffer shader) return generics; } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, out bool isFromCache) { - if (!shaderLoader.LoadExternalBuffer(className, out var buffer)) + Console.WriteLine($"[Shader] Requesting non-generic class {className}"); + + if (!shaderLoader.LoadExternalBuffer(className, out var buffer, out isFromCache)) throw new InvalidOperationException($"Could not load shader [{className}]"); + if (!isFromCache) + Console.WriteLine($"[Shader] Loading non-generic class {className} for 1st time"); + return buffer; } } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 0e00c9c864..f368f021a8 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -16,7 +16,7 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { public void RegisterShader(string name, NewSpirvBuffer buffer); - public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode); + public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); } public abstract class ShaderLoaderBase : IExternalShaderLoader @@ -30,14 +30,20 @@ public void RegisterShader(string name, NewSpirvBuffer buffer) public abstract bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); - public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) { - if (!loadedShaders.ContainsKey(name) && !LoadExternalFile(name, out buffer)) + if (loadedShaders.TryGetValue(name, out buffer)) + { + isFromCache = true; + return true; + } + + isFromCache = false; + if (!LoadExternalFile(name, out buffer)) { throw new InvalidOperationException($"Shader {name} could not be found"); } - buffer = loadedShaders[name]; return true; } } @@ -192,7 +198,7 @@ public int GetOrRegister(SymbolType? type) StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), - ShaderSymbol s => ImportShaderType(s), + LoadedShaderSymbol s => ImportShaderType(s), Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, @@ -217,7 +223,7 @@ public int GetOrRegister(SymbolType? type) return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; } - public int ImportShaderType(ShaderSymbol shaderSymbol) + public int ImportShaderType(LoadedShaderSymbol shaderSymbol) { FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); AddName(shader.ResultId, shaderSymbol.Name); From a39a00a78b21e2048e07f8f88201745cbaca2e36 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 19:15:41 +0900 Subject: [PATCH 0571/1182] Variable declaration with "var" keyword was using pointer type --- .../Extensions/spirv.sdsl.grammar-ext.json | 8 ++++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 3 ++- .../Parsing/SDSL/AST/Statements.cs | 15 +++++++++------ .../Spirv/Building/Builder.Class.cs | 18 ++++++++++++++++-- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 5993390c51..0ae5aec188 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -393,12 +393,16 @@ "value": 0 }, { - "enumerant": "Integer", + "enumerant": "Int", "value": 1 }, { - "enumerant": "LinkType", + "enumerant": "Bool", "value": 2 + }, + { + "enumerant": "LinkType", + "value": 20 } ] }, diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index edcacc792c..cceba8c262 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -319,7 +319,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var genericParameterKind = genericParameterType switch { ScalarType { TypeName: "float" } => GenericParameterKindSDSL.Float, - ScalarType { TypeName: "int" } => GenericParameterKindSDSL.Integer, + ScalarType { TypeName: "int" } => GenericParameterKindSDSL.Int, + ScalarType { TypeName: "bool" } => GenericParameterKindSDSL.Bool, GenericLinkType => GenericParameterKindSDSL.LinkType, }; context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, genericParameterKind)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 575f851d3d..6a4c1c62dc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -129,11 +129,12 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } // Compute type + SymbolType valueType; if (TypeName == "var") { if (Variables.Count == 1 && Variables[0].Value is not null) { - Type = Variables[0].Value!.Type; + valueType = Variables[0].Value!.ValueType; } else { @@ -143,12 +144,14 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } else { - Type = TypeName.ResolveType(table); - table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); + valueType = TypeName.ResolveType(table); + table.DeclaredTypes.TryAdd(TypeName.ToString(), valueType); } - var underlyingType = Type; - Type = new PointerType(Type, Specification.StorageClass.Function); + if (valueType is PointerType) + throw new InvalidOperationException(); + + Type = new PointerType(valueType, Specification.StorageClass.Function); var registeredType = context.GetOrRegister(Type); for (var index = 0; index < Variables.Count; index++) @@ -169,7 +172,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var source = compiledValues[index]; // Make sure type is correct - source = builder.Convert(context, source, underlyingType); + source = builder.Convert(context, source, valueType); builder.Insert(new OpStore(variable, source.Id, null)); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index b04eb79a00..de72a2d749 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -218,6 +218,15 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh case ScalarType { TypeName: "float" }: shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, float.Parse(genericValue))); break; + case ScalarType { TypeName: "bool" }: + if (bool.Parse(genericValue)) + shader.Replace(index, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); + else + shader.Replace(index, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); + break; + case GenericLinkType: + shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + break; default: throw new NotImplementedException(); } @@ -277,11 +286,16 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha for (var index = 0; index < instantiatingBuffer.Count; index++) { var i = instantiatingBuffer[index]; - if (i.Op == Op.OpConstant) + if (i.Op == Op.OpConstant || i.Op == Op.OpConstantTrue || i.Op == Op.OpConstantFalse) { if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) { - var value = GetConstantValue(i.Data, instantiatingBuffer); + var value = i.Op switch + { + Op.OpConstant => GetConstantValue(i.Data, instantiatingBuffer), + Op.OpConstantTrue => bool.TrueString.ToLowerInvariant(), + Op.OpConstantFalse => bool.FalseString.ToLowerInvariant(), + }; // import constant in current shader foreach (var parameter in parameters) From 83c2ff3cae88c04a556714cb8cf5da511eee27d8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 19:31:59 +0900 Subject: [PATCH 0572/1182] Disassembler: MemberName were erasing normal OpName --- src/Stride.Shaders/Spirv/Tools/Dis.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index ac9c1651f2..cc71ac4091 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -246,11 +246,6 @@ public readonly void Disassemble() } data.NameTable[nameInst.Target] = name; } - else if (instruction.Op == Op.OpMemberName) - { - var memberInst = (OpMemberName)instruction; - data.NameTable[memberInst.Type + memberInst.Member] = memberInst.Name; - } } foreach (var instruction in data) { From afd006874830fb3012e1b41c52e68dcbfa024298 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 10 Dec 2025 21:46:29 +0900 Subject: [PATCH 0573/1182] cbuffer: If multiple cbuffer with same name Test, they will be internally renamed Test.0 Test.1 etc. (until final merge) --- assets/SDSL/RenderTests/CBuffer.sdsl | 14 +++++++-- .../SDSL/ShaderMixer.cs | 30 ++++++++++++++++++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 17 +++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/assets/SDSL/RenderTests/CBuffer.sdsl b/assets/SDSL/RenderTests/CBuffer.sdsl index 011d2a5e0d..4953fcdc6b 100644 --- a/assets/SDSL/RenderTests/CBuffer.sdsl +++ b/assets/SDSL/RenderTests/CBuffer.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1124FFFF, cbuffer.Test=(Test1=17, Test2=19)) +// PSMain(ExpectedResult=#1129FFFF, cbuffer.Test=(Test1=17, Test2=19, Test3=3, Test4=2)) namespace Stride.Shaders.Tests; @@ -16,6 +16,10 @@ shader Compute2 : Compute { int Test1; } + cbuffer Test + { + int Test2; + } override float Compute() { @@ -29,11 +33,15 @@ shader CBuffer : Compute2 cbuffer Test { - int Test2; + int Test3; + } + cbuffer Test + { + int Test4; } void PSMain() { - streams.ColorTarget = float4(Compute(), (Test1 + Test2) / 255.0, 1.0, 1.0); + streams.ColorTarget = float4(Compute(), (Test1 + Test2 + Test3 + Test4) / 255.0, 1.0, 1.0); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9db09bd137..f10d5d6126 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -50,6 +50,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect new StreamAnalyzer().Process(table, temp, context); // Merge cbuffers and rgroups + // TODO: remove unused cbuffers (before merging them) Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); MergeCBuffers(globalContext, context, temp); Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -81,6 +82,16 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { + // If multiple cbuffer with same name Test, they will be renamed Test.0 Test.1 etc. + string GetCBufferFinalName(string cbufferName) + { + var dotIndex = cbufferName.IndexOf('.'); + if (dotIndex != -1) + return cbufferName.Substring(0, dotIndex); + + return cbufferName; + } + var mixinNodes = buffer .Where(x => x.Op == Op.OpSDSLEffect) .Select(x => (StartIndex: x.Index, Composition: ((OpSDSLEffect)x).EffectName)) @@ -98,7 +109,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex MemberOffset: 0)) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) - .GroupBy(x => globalContext.Names[x.Variable.ResultId]); + .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); foreach (var cbuffersEntry in cbuffersByNames) { @@ -166,6 +177,23 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex // Update first variable to use new type cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; + // Update name + globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; + foreach (var i in buffer) + { + if (i.Op == Op.OpName && (OpName)i is { } name) + { + // Ensure cbuffer variable name is correct (it might still have a pending number such as Test.0 if there was multiple buffers with same name) + if (cbuffersSpan[0].Variable.ResultId == name.Target) + name.Name = cbuffersEntry.Key; + // Remove any other OpName (after remapping they would all point to the merged variable) + foreach (var cbuffer in cbuffersSpan[1..]) + { + if (cbuffer.Variable.ResultId == name.Target) + SetOpNop(i.Data.Memory.Span); + } + } + } var idRemapping = new Dictionary(); foreach (ref var cbuffer in cbuffersSpan.Slice(1)) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index cceba8c262..e36aa784fb 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -419,6 +419,23 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.CurrentShader = currentShader; table.InheritedShaders = inheritanceList; + + // If multiple cbuffer with same name, they will be merged + // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpSDSLImportStruct/OpSDSLImportVariable would be ambiguous) + var cbuffersByNames = Elements.OfType().GroupBy(x => x.Name); + foreach (var cbufferGroup in cbuffersByNames) + { + if (cbufferGroup.Count() > 1) + { + int index = 0; + foreach (var cbuffer in cbufferGroup) + { + cbuffer.Name = $"{cbuffer.Name}.{index}"; + index++; + } + } + } + foreach (var member in Elements) { member.ProcessSymbol(table); From 47b7ee75b7e0d2503dbb98e625aa44347b214a51 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 12:19:28 +0900 Subject: [PATCH 0574/1182] Apply ColumnMajor/RowMajor only on matrices --- src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs | 11 +++++++---- src/Stride.Shaders/Spirv/Building/Context.cs | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 44533f9d49..de24dcac05 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -280,10 +280,13 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, AccessChain: index); table.CurrentFrame.Add(member.Name, symbol); - if (member.TypeModifier != TypeModifier.ColumnMajor) - context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); - else if (member.TypeModifier != TypeModifier.RowMajor) - context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + if (member.Type is MatrixType) + { + if (member.TypeModifier != TypeModifier.ColumnMajor) + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); + else if (member.TypeModifier != TypeModifier.RowMajor) + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + } if (member.Attributes != null && member.Attributes.Count > 0) { diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index f368f021a8..62ea220697 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -298,10 +298,13 @@ public int DeclareStructuredType(StructuredType structSymbol) var member = structSymbol.Members[index]; AddMemberName(id, index, member.Name); - if (member.TypeModifier != TypeModifier.ColumnMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); - else if (member.TypeModifier != TypeModifier.RowMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + if (member.Type is MatrixType) + { + if (member.TypeModifier != TypeModifier.ColumnMajor) + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); + else if (member.TypeModifier != TypeModifier.RowMajor) + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + } } From 4a35c62e1f1024df3973f91d194efd07afdc27f7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 12:19:52 +0900 Subject: [PATCH 0575/1182] Matrix: fix cbuffer offsets --- src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 12bb26a5cd..237f71be7d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -22,8 +22,8 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type StructuredType s => StructSizeInBuffer(s), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later - MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Columns - 1) + m.Rows)), - MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), ((4 * m.Rows - 1) + m.Columns)), + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), + MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Rows - 1)) + m.Columns), // Round up to 16 bytes (size of float4) ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier), a.Size), // TODO: StructureType From 2d4baa2ac8627c810080845ecef2769771a065a9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 12:20:29 +0900 Subject: [PATCH 0576/1182] Matrix: type duplicates were not unified, as OpTypeMatrix depends on OpTypeVector --- src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 7ab7550c7f..d99a4fca96 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -176,8 +176,8 @@ public readonly void Apply(NewSpirvBuffer buffer) // Covers OpTypeVoid, OpTypeBool, OpTypeInt, OpTypeFloat at the same time (no interdependencies) ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false, comparer); - // Covers OpTypeVector, OpTypeMatrix at the same time - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeMatrix, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeVector, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeMatrix, Op.OpTypeMatrix, true, comparer); ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true, comparer); From 95e2ff3bf4fb0cd22e2d6ef224a91ddd0414ce8b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 12:47:56 +0900 Subject: [PATCH 0577/1182] Translator: expose translated entry point name --- src/Stride.Shaders.Compilers/SpirvTranslator.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index e8f4280227..92dbd31337 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -13,7 +13,7 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { static readonly Cross cross = Cross.GetApi(); - public List<(string Name, ExecutionModel ExecutionModel)> GetEntryPoints(Backend backend = Backend.Hlsl) + public List<(string RealName, string TranslatedName, ExecutionModel ExecutionModel)> GetEntryPoints(Backend backend = Backend.Hlsl) { Context* context = null; ParsedIr* ir = null; @@ -33,7 +33,7 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); - var result = new List<(string Name, ExecutionModel ExecutionModel)>(); + var result = new List<(string RealName, string TranslatedName, ExecutionModel ExecutionModel)>(); EntryPoint * entry_points = null; nuint num_entry_points = 0; bool entryPointFound = false; @@ -42,7 +42,7 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { var entryPointModel = entry_points[i].ExecutionModel; var entryPointName = Marshal.PtrToStringAnsi((IntPtr)entry_points[i].Name)!; - result.Add((entryPointName, entryPointModel)); + result.Add((entryPointName, "main", entryPointModel)); } @@ -52,7 +52,7 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) return result; } - public readonly string Translate(Backend backend = Backend.Hlsl, (string Name, ExecutionModel ExecutionModel)? entryPoint = null) + public readonly string Translate(Backend backend = Backend.Hlsl, (string RealName, string TranslatedName, ExecutionModel ExecutionModel)? entryPoint = null) { string? translatedCode = null; Context* context = null; @@ -77,8 +77,8 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string Name, E if (entryPoint != null) { - if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.Name, entryPoint.Value.ExecutionModel) != Result.Success) - throw new Exception($"{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.Name, entryPoint.Value.ExecutionModel)} : could not set entry point"); + if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel) != Result.Success) + throw new Exception($"{cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel)} : could not set entry point"); } if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) From f8a087c3120cd0a6b20a0e4fef4a65ddf702fdf2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 14:54:53 +0900 Subject: [PATCH 0578/1182] Translator: HLSL use model 50 and rename cbuffer without type_ prefix --- .../SpirvTranslator.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 92dbd31337..e143bbe10a 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -75,6 +75,14 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); + if (backend == Backend.Hlsl) + { + CompilerOptions* compilerOptions = null; + cross.CompilerCreateCompilerOptions(compiler, ref compilerOptions); + cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50); + cross.CompilerInstallCompilerOptions(compiler, compilerOptions); + } + if (entryPoint != null) { if (cross.CompilerSetEntryPoint(compiler, entryPoint.Value.RealName, entryPoint.Value.ExecutionModel) != Result.Success) @@ -87,6 +95,24 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam if (cross.CompilerBuildCombinedImageSamplers(compiler) != Result.Success) throw new Exception($"{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers"); + // HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself) + if (backend == Backend.Hlsl) + { + ReflectedResource* resourcesList; + nuint resourcesCount; + cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourcesList, &resourcesCount); + for (uint i = 0; i < resourcesCount; ++i) + { + var resource = resourcesList[i]; + var cbufferName = Marshal.PtrToStringAnsi((IntPtr)resource.Name); + if (cbufferName.StartsWith("type.")) + { + cbufferName = cbufferName.Substring("type.".Length); + cross.CompilerSetName(compiler, resource.BaseTypeId, cbufferName); + } + } + } + nuint numSamplers = 0; CombinedImageSampler* combinedImageSamplers = null; if (cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers) != Result.Success) From cd36899f69c9916ad3e53aac6eaff918455713f8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 11 Dec 2025 15:31:57 +0900 Subject: [PATCH 0579/1182] StreamAnalyzer: handle PSMain/VSMain overrides, and check if SV_Target/Depth are actually written to before marking them as output --- .../Spirv/Processing/StreamAnalyzer.cs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 99fa385bf9..a40662184e 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -42,16 +42,25 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte { table.TryResolveSymbol("VSMain", out var entryPointVS); var entryPointPS = table.ResolveSymbol("PSMain"); + + if (entryPointVS.Type is FunctionGroupType) + entryPointVS = entryPointVS.GroupMembers[^1]; + if (entryPointPS.Type is FunctionGroupType) + entryPointPS = entryPointPS.GroupMembers[^1]; + if (entryPointPS.IdRef == 0) throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); var analysisResult = Analyze(buffer, context); var streams = analysisResult.Streams; - // Expected at the end of pixel shader + AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, streams); + + // If written to, they are expected at the end of pixel shader foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH")) + if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") + && stream.Value.Stream.Write) stream.Value.Stream.Output = true; } @@ -66,10 +75,14 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { + AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, streams); + // Expected at the end of vertex shader foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION"))) + // If written to, they are expected at the end of pixel shader + if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + && stream.Value.Stream.Write) stream.Value.Stream.Output = true; } @@ -214,8 +227,6 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con { var streams = analysisResult.Streams; - ProcessMethod(buffer, [], entryPointId, streams); - var stage = executionModel switch { ExecutionModel.Fragment => "PS", @@ -351,7 +362,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con /// /// Figure out (recursively) which streams are being read from and written to. /// - private void ProcessMethod(NewSpirvBuffer buffer, List callStack, int functionId, SortedList streams) + private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, SortedList streams) { var methodStart = FindMethodStart(buffer, functionId); for (var index = methodStart; index < buffer.Count; index++) @@ -386,7 +397,7 @@ private void ProcessMethod(NewSpirvBuffer buffer, List callStack, int funct if (callStack.Contains(functionId)) throw new InvalidOperationException($"Recursive call with method id {functionId}"); callStack.Add(functionId); - ProcessMethod(buffer, callStack, call.Function, streams); + AnalyzeStreamReadWrites(buffer, callStack, call.Function, streams); callStack.RemoveAt(callStack.Count - 1); } } From 32315e99e20a44f2df405fe0d08989834f68b268 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 13:41:55 +0900 Subject: [PATCH 0580/1182] EffectEvaluator: properly handle array composition --- .../SDSL/EffectEvaluator.cs | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index f94e6d18cd..77e67d27a0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -51,7 +51,7 @@ public ShaderSource EvaluateEffects(ShaderSource source) var instSource = new ShaderClassSource(mixinComposeArray.Mixin); var evaluatedSource = EvaluateEffects(instSource); - MergeCompositionArray(mixinTree, mixinComposeArray.Identifier, evaluatedSource); + MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); } } @@ -62,6 +62,10 @@ public ShaderSource EvaluateEffects(ShaderSource source) case ShaderMixinSource mixinSource: { var result = new ShaderMixinSource(); + foreach (var macro in mixinSource.Macros) + { + result.Macros.Add(macro); + } foreach (var mixin in mixinSource.Mixins) { var evaluatedMixin = EvaluateEffects(mixin); @@ -71,7 +75,14 @@ public ShaderSource EvaluateEffects(ShaderSource source) foreach (var composition in mixinSource.Compositions) { var evaluatedMixin = EvaluateEffects(composition.Value); - MergeComposition(result, composition.Key, evaluatedMixin); + if (evaluatedMixin is ShaderArraySource shaderArraySource) + { + MergeCompositionArray(result, composition.Key, shaderArraySource); + } + else + { + MergeComposition(result, composition.Key, evaluatedMixin); + } } return result; @@ -82,7 +93,7 @@ public ShaderSource EvaluateEffects(ShaderSource source) foreach (var mixin in arraySource.Values) { var evaluatedMixin = EvaluateEffects(mixin); - result.Add(result); + result.Add(evaluatedMixin); } return result; } @@ -123,13 +134,21 @@ public void MergeComposition(ShaderMixinSource mixinTree, string compositionName Merge((ShaderMixinSource)composition, evaluatedSource); } - public void MergeCompositionArray(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) + public void MergeCompositionArray(ShaderMixinSource mixinTree, string compositionName, ShaderArraySource evaluatedSource) { - if (!mixinTree.Compositions.TryGetValue(compositionName, out var source)) - mixinTree.Compositions.Add(compositionName, source = new ShaderArraySource()); + if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) + mixinTree.Compositions.Add(compositionName, composition = new ShaderArraySource()); + + var arraySource = (ShaderArraySource)composition; + arraySource.Values.AddRange(evaluatedSource.Values); + } - var arraySource = (ShaderArraySource)source; + public void MergeCompositionArrayItem(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) + { + if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) + mixinTree.Compositions.Add(compositionName, composition = new ShaderArraySource()); + var arraySource = (ShaderArraySource)composition; arraySource.Add(evaluatedSource); } } From 36c419fd5180f71ae60c6ad05fa228ddfd501927 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 13:43:16 +0900 Subject: [PATCH 0581/1182] Matrix: added line break in size evaluation --- src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 237f71be7d..df7b7e0425 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -22,8 +22,10 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type StructuredType s => StructSizeInBuffer(s), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later - MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), - MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Rows - 1)) + m.Columns), + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), + MatrixType m when typeModifier == TypeModifier.RowMajor + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Rows - 1)) + m.Columns), // Round up to 16 bytes (size of float4) ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier), a.Size), // TODO: StructureType From c8e436f300f612334422a0afa35e4bfb8e046cec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 13:44:36 +0900 Subject: [PATCH 0582/1182] Reflection: fix shader reflection data --- .../SDSL/ShaderMixer.cs | 367 ++++++++++++------ 1 file changed, 244 insertions(+), 123 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index f10d5d6126..96434be8fc 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -39,7 +39,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect // Root shader var globalContext = new MixinGlobalContext(); - MergeMixinNode(globalContext, context, table, temp, shaderSource2); + var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); @@ -56,6 +56,9 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); ComputeCBufferOffsets(globalContext, context, temp); + // Process reflection + ProcessReflection(globalContext, context, temp, rootMixin); + temp.Sort(); CleanupUnnecessaryInstructions(temp); @@ -92,36 +95,89 @@ string GetCBufferFinalName(string cbufferName) return cbufferName; } - var mixinNodes = buffer + // OpSDSLEffect is emitted for any non-root composition + var compositionNodes = buffer .Where(x => x.Op == Op.OpSDSLEffect) - .Select(x => (StartIndex: x.Index, Composition: ((OpSDSLEffect)x).EffectName)) + .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLEffect)x).EffectName)) + .ToList(); + + var shaders = buffer + .Where(x => x.Op == Op.OpSDSLShader) + .Select(x => (StartIndex: x.Index, ShaderName: ((OpSDSLShader)x).ShaderName)) .ToList(); var cbuffersByNames = buffer .Where(x => x.Op == Op.OpVariableSDSL) .Select(x => (Index: x.Index, Variable: (OpVariableSDSL)x)) - // Note: MemberOffset is simply a shift in Members index, not something like a byte offset + // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x.Variable, - CompositionPath: mixinNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).Composition, + CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, + ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, StructTypePtrId: x.Variable.ResultType, StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberOffset: 0)) + MemberIndexOffset: 0)) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); + var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); + + Dictionary<(int StructType, int Member), string> links = new(); + foreach (var i in buffer) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + if (cbufferStructTypes.Contains(memberDecorate.StructType)) + { + using var n = new LiteralValue(m.Span); + links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); + SetOpNop(i.Data.Memory.Span); + } + } + } + + void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset)> cbuffersSpan, int cbufferStructId) + { + int mergedMemberIndex = 0; + foreach (ref var cbuffer in cbuffersSpan) + { + var compositionPath = cbuffer.CompositionPath; + + for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) + { + var member = cbuffer.StructType.Members[memberIndex]; + + var link = $"{cbuffer.ShaderName}.{member.Name}"; + if (!compositionPath.IsNullOrEmpty()) + link = $"{link}.{compositionPath}"; + + // Check if there is already a decoration (i.e. from an explicit "Link") + if (links.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var linkValue)) + link = linkValue; + + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(link))); + } + } + } + foreach (var cbuffersEntry in cbuffersByNames) { - if (cbuffersEntry.Count() > 1) + var cbuffers = cbuffersEntry.ToList(); + var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); + + if (cbuffersEntry.Count() == 1) + { + DecorateLinks(cbuffersSpan, context.Types[cbuffersEntry.First().StructType]); + } + // More than 1 cbuffers with same name + else { - var cbuffers = cbuffersEntry.ToList(); - var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); int offset = 0; // TODO: Analyze and skip cbuffers parts which are unused foreach (ref var cbuffer in cbuffersSpan) { - cbuffer.MemberOffset = offset; + cbuffer.MemberIndexOffset = offset; offset += cbuffer.StructType.Members.Count; } var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); @@ -131,31 +187,19 @@ string GetCBufferFinalName(string cbufferName) var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); var mergedCbufferPtrStructId = context.GetOrRegister(new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform)); - int memberIndex = 0; - foreach (ref var cbuffer in cbuffersSpan) - { - var compositionPath = cbuffer.CompositionPath; - - foreach (var member in cbuffer.StructType.Members) - { - var link = member.Name; - if (!compositionPath.IsNullOrEmpty()) - link = $"{compositionPath}.{link}"; - context.Add(new OpMemberDecorateString(mergedCbufferStructId, memberIndex++, ParameterizedFlags.DecorationLinkSDSL(link))); - } - } + DecorateLinks(cbuffersSpan, mergedCbufferStructId); // Remap member ids foreach (var i in buffer) { if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { - if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberOffset > 0) + if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberIndexOffset > 0) { // According to spec, this must be a OpConstant (and we only create them with int) var indexes = accessChain.Values.Elements.Span; var constantId = indexes[0]; - var index = cbuffer.MemberOffset + (int)SpirvBuilder.GetConstantValue(constantId, buffer); + var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, buffer); indexes[0] = context.CompileConstant(index).Id; // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) @@ -212,22 +256,17 @@ string GetCBufferFinalName(string cbufferName) } } - private void DecorateStructOffsets() - { - - } - private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { var cbuffers = buffer .Where(x => x.Op == Op.OpVariableSDSL) .Select(x => (OpVariableSDSL)x) - // Note: MemberOffset is simply a shift in Members index, not something like a byte offset + // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x, StructTypePtrId: x.ResultType, StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberOffset: 0)) + MemberIndexOffset: 0)) .Where(x => x.StructType != null) .ToList(); @@ -251,38 +290,42 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) members[i] = new EffectTypeMemberDescription { Name = s.Members[i].Name, - Type = ConvertType(context, s.Members[i].Type), + Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier), Offset = offset, }; - // Note: we assume if already added, the offsets were computed the same way + var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); + + // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way if (!hasOffsetDecorations) context.Add(new OpMemberDecorate(context.Types[s], i, ParameterizedFlags.DecorationOffset(offset))); - var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); offset += memberSize; } return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; } - EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType) + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier) { return symbolType switch { ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ArrayType a => ConvertArrayType(context, a), + ArrayType a => ConvertArrayType(context, a, typeModifier), StructType s => ConvertStructType(context, s), // TODO: should we use RowCount instead? (need to update Stride) - VectorType v => ConvertType(context, v.BaseType) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, - MatrixType m => ConvertType(context, m.BaseType) with { Class = EffectParameterClass.Vector, RowCount = m.Rows, ColumnCount = m.Columns }, + VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Rows, ColumnCount = m.Columns }, + MatrixType m when typeModifier == TypeModifier.RowMajor + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Rows, ColumnCount = m.Columns }, }; - EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a) + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier) { var typeId = context.Types[a]; - var elementType = ConvertType(context, a.BaseType); + var elementType = ConvertType(context, a.BaseType, typeModifier); var hasStrideDecoration = false; foreach (var i in context.GetBuffer()) @@ -326,15 +369,14 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a) context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); - var keyName = member.Name; - if (links.TryGetValue((structTypeId, index), out var linkName)) - keyName = linkName; + if (!links.TryGetValue((structTypeId, index), out var linkName)) + throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); memberInfos[index] = new EffectValueDescription { - Type = ConvertType(context, member.Type), + Type = ConvertType(context, member.Type, member.TypeModifier), RawName = member.Name, - KeyInfo = new EffectParameterKeyInfo { KeyName = keyName }, + KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, Offset = constantBufferOffset, Size = memberSize, }; @@ -377,6 +419,7 @@ struct LinkInfo MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { + // We emit OPSDSLEffect for any non-root composition if (currentCompositionPath != null) buffer.Add(new OpSDSLEffect(currentCompositionPath)); @@ -388,17 +431,11 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(context, buffer, mixinSource, mixinNode); - Console.WriteLine("Done SDSL importing"); - Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // Import struct types ImportStructTypes(globalContext, buffer, mixinNode); new TypeDuplicateRemover().Apply(buffer); - //Console.WriteLine("Done type remapping"); - Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // Build names and types mappings ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); @@ -434,76 +471,9 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, } } - Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // Patch method calls (virtual calls & base calls) ProcessMemberAccessAndForeach(globalContext, context, buffer, mixinNode); - // Process reflection - Dictionary linkInfos = new(); - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = buffer[index]; - - // Fill linkInfos - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is - { - Target: int t, - Decoration: - { - Value: Decoration.LinkSDSL or Decoration.ResourceGroupSDSL or Decoration.LogicalGroupSDSL, - Parameters: { } m - } - } decoration) - { - using var n = new LiteralValue(m.Span); - ref var linkInfo = ref CollectionsMarshal.GetValueRefOrAddDefault(linkInfos, t, out _); - if (decoration.Decoration.Value == Decoration.LinkSDSL) - linkInfo.LinkName = n.Value; - else if (decoration.Decoration.Value == Decoration.ResourceGroupSDSL) - linkInfo.ResourceGroup = n.Value; - else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) - linkInfo.LogicalGroup = n.Value; - } - else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) - { - var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType pointerType) - { - if (pointerType.BaseType is TextureType) - { - var name = globalContext.Names[variable.ResultId]; - linkInfos.TryGetValue(variable.ResultId, out var linkInfo); - var linkName = linkInfo.LinkName; - if (currentCompositionPath != null) - linkName = $"{currentCompositionPath}.{linkName}"; - - var slot = globalContext.Reflection.ResourceBindings.Count; - globalContext.Reflection.ResourceBindings.Add(new EffectResourceBindingDescription - { - KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, - Class = EffectParameterClass.ShaderResourceView, - Type = EffectParameterType.Texture, - ElementType = default, - RawName = name, - ResourceGroup = linkInfo.ResourceGroup, - //Stage = , // filed by ShaderCompiler - SlotStart = globalContext.Reflection.ResourceBindings.Count, - SlotCount = 1, - LogicalGroup = linkInfo.LogicalGroup, - }); - - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(slot))); - } - else if (pointerType.BaseType is SamplerType) - { - - } - } - } - } - if (currentCompositionPath != null) buffer.Add(new OpSDSLEffectEnd()); @@ -647,6 +617,20 @@ bool ProcessStageMember(int memberId, bool isStage) } } + // Link attribute: postfix with composition path + if (mixinNode.CompositionPath != null) + { + foreach (var i in temp) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + var n = new LiteralValue(m.Span); + n.Value = $"{n.Value}.{mixinNode.CompositionPath}"; + n.Dispose(); + } + } + } + shaderClass.Start = shaderStart; shaderClass.End = temp.Count; shaderClass.OffsetId = offset; @@ -693,8 +677,6 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } } - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // Build method group info (override, etc.) ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) @@ -933,8 +915,6 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte throw new InvalidOperationException(); } - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - if (mixinNode.ExternalVariables.TryGetValue(memberAccess.Member, out var variable)) { var shaderName = mixinNode.ExternalShaders[variable.ShaderId]; @@ -1026,6 +1006,147 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } } + private static void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode) + { + // First, figure out latest used bindings (assume they are filled in order) + int srvSlot = 0; + int samplerSlot = 0; + int cbufferSlot = 0; + foreach (var resourceBinding in globalContext.Reflection.ResourceBindings) + { + switch (resourceBinding) + { + case { Class: EffectParameterClass.ShaderResourceView }: + srvSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + case { Class: EffectParameterClass.Sampler }: + samplerSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + case { Class: EffectParameterClass.ConstantBuffer }: + cbufferSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + } + } + + Dictionary linkInfos = new(); + string currentShaderName = string.Empty; + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + // Fill linkInfos + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is + { + Target: int t, + Decoration: + { + Value: Decoration.LinkSDSL or Decoration.ResourceGroupSDSL or Decoration.LogicalGroupSDSL, + Parameters: { } m + } + } decoration) + { + using var n = new LiteralValue(m.Span); + ref var linkInfo = ref CollectionsMarshal.GetValueRefOrAddDefault(linkInfos, t, out _); + if (decoration.Decoration.Value == Decoration.LinkSDSL) + linkInfo.LinkName = n.Value; + else if (decoration.Decoration.Value == Decoration.ResourceGroupSDSL) + linkInfo.ResourceGroup = n.Value; + else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) + linkInfo.LogicalGroup = n.Value; + } + else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + currentShaderName = shader.ShaderName; + } + else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) + { + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType pointerType) + { + var name = globalContext.Names[variable.ResultId]; + linkInfos.TryGetValue(variable.ResultId, out var linkInfo); + var linkName = linkInfo.LinkName ?? $"{currentShaderName}.{name}"; + if (mixinNode.CompositionPath != null) + linkName = $"{linkName}.{mixinNode.CompositionPath}"; + + var effectResourceBinding = new EffectResourceBindingDescription + { + KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, + ElementType = default, + RawName = name, + ResourceGroup = linkInfo.ResourceGroup, + //Stage = , // filed by ShaderCompiler + LogicalGroup = linkInfo.LogicalGroup, + }; + + if (pointerType.BaseType is TextureType) + { + var slot = globalContext.Reflection.ResourceBindings.Count; + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ShaderResourceView, + Type = EffectParameterType.Texture, + SlotStart = srvSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + + srvSlot++; + } + else if (pointerType.BaseType is SamplerType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.Sampler, + Type = EffectParameterType.Sampler, + SlotStart = samplerSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(samplerSlot))); + + cbufferSlot++; + } + else if (pointerType.BaseType is ConstantBufferSymbol) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ConstantBuffer, + Type = EffectParameterType.ConstantBuffer, + SlotStart = cbufferSlot, + SlotCount = 1, + // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) + // Anyway, since buffer is merged, KeyName with form ShaderName.VariableName doesn't make sense as it doesn't belong to a specific shader anymore + KeyInfo = new EffectParameterKeyInfo { KeyName = name }, + ResourceGroup = name, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(cbufferSlot))); + + cbufferSlot++; + } + } + } + } + + // Process compositions recursively + foreach (var composition in mixinNode.Compositions) + { + ProcessReflection(globalContext, context, buffer, composition.Value); + } + foreach (var compositionArray in mixinNode.CompositionArrays) + { + foreach (var composition in compositionArray.Value) + { + ProcessReflection(globalContext, context, buffer, composition); + } + } + } + static void SetOpNop(Span words) { From f5cefe4c0e7cf0873b04b1a34ef7fd1545229dd1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 20:15:30 +0900 Subject: [PATCH 0583/1182] Improved support for generics arrays --- assets/SDSL/RenderTests/CBufferArray.sdsl | 18 +++++ .../SDSL/RenderTests/GenericsArraySize.sdsl | 23 ++++++ src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 10 ++- .../Parsing/SDSL/AST/Literals.cs | 71 ++++++++++++++----- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 23 +++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 +- .../Parsing/SDSL/AST/ShaderElements.cs | 10 +-- .../Parsing/SDSL/AST/Statements.cs | 5 +- .../Spirv/Building/Builder.Class.cs | 55 ++++++++++++-- src/Stride.Shaders/Spirv/Building/Builder.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 6 +- 12 files changed, 183 insertions(+), 49 deletions(-) create mode 100644 assets/SDSL/RenderTests/CBufferArray.sdsl create mode 100644 assets/SDSL/RenderTests/GenericsArraySize.sdsl diff --git a/assets/SDSL/RenderTests/CBufferArray.sdsl b/assets/SDSL/RenderTests/CBufferArray.sdsl new file mode 100644 index 0000000000..f1f1c1d401 --- /dev/null +++ b/assets/SDSL/RenderTests/CBufferArray.sdsl @@ -0,0 +1,18 @@ +// PSMain(ExpectedResult=#03050709, cbuffer.Test=(Test2=(3,5,7,9))) + +namespace Stride.Shaders.Tests; + +shader CBufferArray +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test2[4]; + } + + void PSMain() + { + streams.ColorTarget = float4(Test2[0], Test2[1], Test2[2], Test2[3]) / 255.0; + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/GenericsArraySize.sdsl b/assets/SDSL/RenderTests/GenericsArraySize.sdsl new file mode 100644 index 0000000000..88be41a295 --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsArraySize.sdsl @@ -0,0 +1,23 @@ +// PSMain(ExpectedResult=#03050709, cbuffer.Test=(Test2=(3,5,7,9))) + +namespace Stride.Shaders.Tests; + +shader GenericsArrayBase +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test2[TArraySize]; + } + + void PSMain() + { + streams.ColorTarget = float4(Test2[0], Test2[1], Test2[2], Test2[3]) / 255.0; + } +} + +effect GenericsArraySize +{ + mixin GenericsArrayBase<4>; +} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 39872b0159..092872a80b 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -114,7 +114,7 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// /// The base type for the array. /// The size of the array. If -1, it means size is not defined, such as using []. -public sealed record ArrayType(SymbolType BaseType, int Size) : SymbolType() +public sealed record ArrayType(SymbolType BaseType, int Size, int? SizeExpressionId = null) : SymbolType() { public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 0429fbb911..65c21ebbb2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -26,6 +26,12 @@ public SpirvValue Compile(SymbolTable table, CompilerUnit compiler) public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); + // Only used for constant expression which should stay in the context buffer (not compiled inside a OpFunction) + public virtual SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + { + throw new NotImplementedException(); + } + public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) @@ -238,7 +244,7 @@ public class CastExpression(TypeName typeName, Operator op, Expression expressio public unsafe override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var castType = TypeName.ResolveType(table); + var castType = TypeName.ResolveType(table, context); var value = Expression.CompileAsValue(table, compiler); Type = castType; @@ -383,7 +389,7 @@ void EmitOpAccessChain(Span accessChainIds) throw new InvalidOperationException(); // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(compiler, builder, context, matchingComponent, result.Id); + result = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; break; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index e3815e6d03..ba9e7a31dd 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -109,7 +109,7 @@ public class ExpressionLiteral(Expression value, TypeName typeName, TextLocation public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var castType = TypeName.ResolveType(table); + var castType = TypeName.ResolveType(table, context); var value = Value.CompileAsValue(table, compiler); Type = castType; @@ -130,13 +130,13 @@ public bool IsConstant() return true; } - public abstract SymbolType GenerateType(SymbolTable table); + public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context); public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - Type = GenerateType(table); + Type = GenerateType(table, context); (var compositeCount, var totalCount) = Type switch { @@ -195,7 +195,7 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override SymbolType GenerateType(SymbolTable table) => TypeName.ResolveType(table); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context) => TypeName.ResolveType(table, context); public override string ToString() { @@ -210,7 +210,7 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; - public override SymbolType GenerateType(SymbolTable table) => TypeName.ResolveType(table); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context) => TypeName.ResolveType(table, context); public override string ToString() { @@ -220,7 +220,7 @@ public override string ToString() public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { - public override SymbolType GenerateType(SymbolTable table) + public override SymbolType GenerateType(SymbolTable table, SpirvContext context) { throw new NotImplementedException(); } @@ -235,18 +235,32 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; + public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + { + int position = context.GetBuffer().Count; + return CompileSymbol(table, context.GetBuffer(), ref position, context, true); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; + return CompileSymbol(table, builder.GetBuffer(), ref builder.Position, context, false); + } + + private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref int position, SpirvContext context, bool constantOnly) + { if (!table.TryResolveSymbol(Name, out var symbol)) { + if (constantOnly) + throw new NotImplementedException(); + // Maybe it's a static variable? try to resolve by loading file var classSource = new ShaderClassInstantiation(Name, []); // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.InheritedShaders, ResolveStep.Compile, builder.GetBuffer()); + classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.InheritedShaders, ResolveStep.Compile, buffer); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { table.InheritedShaders[i].Symbol = ShaderClass.LoadExternalShaderType(table, table.InheritedShaders[i]); @@ -259,14 +273,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) table.CurrentFrame.Add(classSource.Symbol.Name, symbol); Type = symbol.Type; - return EmitSymbol(compiler, builder, context, symbol); + return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } Type = symbol.Type; - return EmitSymbol(compiler, builder, context, symbol); + return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } - public static SpirvValue EmitSymbol(CompilerUnit compiler, SpirvBuilder builder, SpirvContext context, Symbol symbol, int? instance = null) + public static SpirvValue EmitSymbol(NewSpirvBuffer buffer, ref int position, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); @@ -274,27 +288,36 @@ public static SpirvValue EmitSymbol(CompilerUnit compiler, SpirvBuilder builder, // Shader symbols are treated separately (we want to return only the shader instance (or this if not specified)) if (symbol.Id.Kind == SymbolKind.Shader) { + if (constantOnly) + throw new NotImplementedException(); + if (instance == null) - instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + instance = buffer.Insert(position++, new OpThisSDSL(context.Bound++)).ResultId; result.Id = instance.Value; return result; } if (symbol.MemberAccessWithImplicitThis is { } thisType) { + if (constantOnly) + throw new NotImplementedException(); + var isStage = symbol.Id.IsStage; if (instance == null) { instance = isStage - ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId - : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + ? buffer.Insert(position++, new OpStageSDSL(context.Bound++)).ResultId + : buffer.Insert(position++, new OpThisSDSL(context.Bound++)).ResultId; } - result.Id = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); + result.Id = buffer.Insert(position++, new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); } if (symbol.AccessChain is int accessChainIndex) { + if (constantOnly) + throw new NotImplementedException(); + var index = context.CompileConstant(accessChainIndex).Id; - result.Id = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, result.Id, [index])); + result.Id = buffer.Insert(position++, new OpAccessChain(resultType, context.Bound++, result.Id, [index])); } return result; @@ -347,7 +370,7 @@ public class TypeName(string name, TextLocation info) : Literal(info) public List? ArraySize { get; set; } public List Generics { get; set; } = []; - public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolType symbolType) + public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWhen(false)] out SymbolType symbolType) { if (Name == "LinkType") { @@ -385,16 +408,19 @@ public bool TryResolveType(SymbolTable table, [MaybeNullWhen(false)] out SymbolT else if (arraySize is IntegerLiteral i) symbolType = new ArrayType(symbolType, (int)i.Value); else - throw new NotImplementedException(); + { + var constantArraySize = arraySize.CompileConstantValue(table, context); + symbolType = new ArrayType(symbolType, -1, constantArraySize.Id); + } } } return true; } - public SymbolType ResolveType(SymbolTable table) + public SymbolType ResolveType(SymbolTable table, SpirvContext context) { - if (!TryResolveType(table, out var result)) + if (!TryResolveType(table, context, out var result)) throw new InvalidOperationException($"Could not resolve type [{Name}]"); return result; } @@ -420,7 +446,14 @@ public override string ToString() builder.Append('[').Append(s.ToString()).Append(']'); return builder.ToString(); + } + public static string GetTypeNameWithoutGenerics(string typeName) + { + var indexGenerics = typeName.IndexOf('<'); + if (indexGenerics != -1) + typeName = typeName.Substring(0, indexGenerics); + return typeName; } public static implicit operator string(TypeName tn) => tn.Name; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index e36aa784fb..0eb2fd58a9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -143,7 +143,14 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = types[typeArray.ElementType]; - types.Add(typeArray.ResultId, new ArrayType(innerType, (int)SpirvBuilder.GetConstantValue(typeArray.Length, buffer))); + if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, buffer)) + { + types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); + } + else + { + types.Add(typeArray.ResultId, new ArrayType(innerType, -1, typeArray.Length)); + } } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) { @@ -312,7 +319,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) for (int i = 0; i < Generics.Parameters.Count; i++) { var genericParameter = Generics.Parameters[i]; - var genericParameterType = genericParameter.TypeName.ResolveType(table); + var genericParameterType = genericParameter.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); @@ -363,10 +370,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { if (member is ShaderMethod func) { - var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table), []); + var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table, context), []); foreach (var arg in func.Parameters) { - var argSym = arg.TypeName.ResolveType(table); + var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = new PointerType(argSym, Specification.StorageClass.Function); ftype.ParameterTypes.Add(arg.Type); @@ -377,7 +384,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } else if (member is ShaderMember svar) { - if (!svar.TypeName.TryResolveType(table, out var memberType)) + if (!svar.TypeName.TryResolveType(table, context, out var memberType)) { if (svar.TypeName.Name.Contains("<")) throw new NotImplementedException("Can't have member variables with generic shader types"); @@ -388,7 +395,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) - memberType = svar.TypeName.ResolveType(table); + memberType = svar.TypeName.ResolveType(table, context); } var storageClass = Specification.StorageClass.Private; @@ -402,7 +409,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { foreach (var cbMember in cb.Members) { - cbMember.Type = cbMember.TypeName.ResolveType(table); + cbMember.Type = cbMember.TypeName.ResolveType(table, context); //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); //symbols.Add(symbol); } @@ -438,7 +445,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var member in Elements) { - member.ProcessSymbol(table); + member.ProcessSymbol(table, context); } foreach (var member in Elements.OfType()) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 7649961695..7a65607cef 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -238,15 +238,16 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { + var (builder, context) = compiler; + table.Push(); foreach (var arg in Parameters) { - var argSym = arg.TypeName.ResolveType(table); + var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = argSym; } - var (builder, context) = compiler; if (Type is FunctionType ftype) { builder.BeginFunction(context, function); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index de24dcac05..d21e952c07 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -13,7 +13,7 @@ public abstract class ShaderElement(TextLocation info) : Node(info) { public SymbolType? Type { get; set; } - public virtual void ProcessSymbol(SymbolTable table) + public virtual void ProcessSymbol(SymbolTable table, SpirvContext context) { } } @@ -136,12 +136,12 @@ public abstract class ShaderBuffer(string name, TextLocation info) : ShaderEleme public string Name { get; set; } = name; public List Members { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); foreach (var smem in Members) { - smem.Type = smem.TypeName.ResolveType(table); + smem.Type = smem.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add((smem.Name, smem.Type, smem.TypeModifier)); @@ -185,12 +185,12 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public Identifier TypeName { get; set; } = typename; public List Members { get; set; } = []; - public override void ProcessSymbol(SymbolTable table) + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); foreach (var smem in Members) { - smem.Type = smem.TypeName.ResolveType(table); + smem.Type = smem.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add((smem.Name, smem.Type, smem.TypeModifier)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 6a4c1c62dc..497e58cb1c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -91,7 +91,8 @@ public List? ArraySizes public override void Compile(SymbolTable table, CompilerUnit compiler) { - Variable.Type = TypeName.ResolveType(table); + var (builder, context) = compiler; + Variable.Type = TypeName.ResolveType(table, context); var initialValue = Value?.CompileAsValue(table, compiler); if (Value is not null && Value.Type != Variable.Type) table.Errors.Add(new(TypeName.Info, "wrong type")); @@ -144,7 +145,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } else { - valueType = TypeName.ResolveType(table); + valueType = TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(TypeName.ToString(), valueType); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index de72a2d749..cb6258a664 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -139,6 +139,18 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade return inheritanceList[index]; } + public static bool TryGetInstructionById(int constantId, out OpDataIndex instruction, params ReadOnlySpan buffers) + { + foreach (var buffer in buffers) + { + if (buffer.TryGetInstructionById(constantId, out instruction)) + return true; + } + + instruction = default; + return false; + } + public static object GetConstantValue(int constantId, params ReadOnlySpan buffers) { foreach (var buffer in buffers) @@ -152,12 +164,41 @@ public static object GetConstantValue(int constantId, params ReadOnlySpan buffers) + { + foreach (var buffer in buffers) + { + if (buffer.TryGetInstructionById(constantId, out var constant)) + { + return TryGetConstantValue(constant.Data, out value, buffers); + } + } + + value = default; + return false; + } + public static object GetConstantValue(OpData data, params ReadOnlySpan buffers) { + if (!TryGetConstantValue(data, out var value, buffers)) + throw new InvalidOperationException($"Can't process constant {data.IdResult}"); + + return value; + } + + // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. + public static bool TryGetConstantValue(OpData data, out object value, params ReadOnlySpan buffers) + { + // Check for unresolved values + if (data.Op == Op.OpSDSLGenericParameter) + { + value = default; + return false; + } + int typeId = data.Op switch { Op.OpConstant or Op.OpSpecConstant => data.Memory.Span[1], - _ => throw new Exception("Unsupported context dependent number in instruction " + data.Op) }; var operand = data.Get("value"); foreach (var buffer in buffers) @@ -167,28 +208,30 @@ public static object GetConstantValue(OpData data, params ReadOnlySpan operand.ToLiteral(), { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), { Width: 64, Signedness: 0 } => operand.ToLiteral(), { Width: 64, Signedness: 1 } => operand.ToLiteral(), - _ => throw new NotImplementedException("Unsupported int width " + type.Width), + _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), }; + return true; } else if (typeInst.Op == Op.OpTypeFloat) { var type = new OpTypeFloat(typeInst); - return type switch + value = type switch { { Width: 16 } => operand.ToLiteral(), { Width: 32 } => operand.ToLiteral(), { Width: 64 } => operand.ToLiteral(), - _ => throw new NotImplementedException("Unsupported float width " + type.Width), + _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), }; + return true; } else - throw new NotImplementedException("Unsupported context dependent number with type " + typeInst.Op); + throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); } } throw new Exception("Cannot find type instruction for id " + typeId); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index ca49b59f7b..b10034443f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -12,10 +12,12 @@ namespace Stride.Shaders.Spirv.Building; // Should have utility functions to add instruction to the buffer public partial class SpirvBuilder() { + private int position; + NewSpirvBuffer Buffer { get; init; } = new(); public SpirvFunction? CurrentFunction { get; internal set; } public SpirvBlock? CurrentBlock { get; internal set; } - public int Position { get; internal set; } = 0; + public ref int Position => ref position; public void AddFunctionVariable(int paramType, int paramVariable) { diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 62ea220697..5f484c27dd 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -193,8 +193,8 @@ public int GetOrRegister(SymbolType? type) }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, - ArrayType a when a.Size != -1 => RegisterArrayType(a), - ArrayType a when a.Size == -1 => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, + ArrayType a when a.Size != -1 || a.SizeExpressionId != null => RegisterArrayType(a), + ArrayType a when a.Size == -1 && a.SizeExpressionId == null => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), @@ -218,7 +218,7 @@ public int GetOrRegister(SymbolType? type) { var sizeId = a.Size != -1 ? CompileConstant((int)a.Size).Id - : throw new NotImplementedException(); + : a.SizeExpressionId ?? throw new InvalidOperationException(); return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; } From f16cb60395463be64defc01f131d80277f289975 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 20:16:03 +0900 Subject: [PATCH 0584/1182] Fix foreach instruction operand order --- .../Extensions/spirv.sdsl.grammar-ext.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 0ae5aec188..64cb63d110 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -281,8 +281,8 @@ "opname": "OpForeachSDSL", "class": "Miscellaneous", "operands": [ - { "kind": "IdResult" }, { "kind": "IdResultType" }, + { "kind": "IdResult" }, { "kind": "IdRef", "name": "collection" From 1d211b93f6a27c00d67994b919ccc7029b9146c7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 20:16:57 +0900 Subject: [PATCH 0585/1182] Fix EffectEvaluator for nested composition arrays --- .../SDSL/EffectEvaluator.cs | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 77e67d27a0..87fa921b4b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -75,14 +75,7 @@ public ShaderSource EvaluateEffects(ShaderSource source) foreach (var composition in mixinSource.Compositions) { var evaluatedMixin = EvaluateEffects(composition.Value); - if (evaluatedMixin is ShaderArraySource shaderArraySource) - { - MergeCompositionArray(result, composition.Key, shaderArraySource); - } - else - { - MergeComposition(result, composition.Key, evaluatedMixin); - } + MergeComposition(result, composition.Key, evaluatedMixin); } return result; @@ -117,30 +110,29 @@ public void Merge(ShaderMixinSource mixinTree, ShaderSource source) foreach (var composition in mixinSource.Compositions) { - if (mixinTree.Compositions.TryGetValue(composition.Key, out var mixinTreeComposition)) - mixinTree.Compositions.Add(composition.Key, mixinTreeComposition = new ShaderMixinSource()); - Merge((ShaderMixinSource)mixinTreeComposition, composition.Value); + MergeComposition(mixinTree, composition.Key, composition.Value); } break; + default: + throw new InvalidOperationException(); } } - public void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) - { - if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) - mixinTree.Compositions.Add(compositionName, composition = new ShaderMixinSource()); - - Merge((ShaderMixinSource)composition, evaluatedSource); - } - - public void MergeCompositionArray(ShaderMixinSource mixinTree, string compositionName, ShaderArraySource evaluatedSource) + public void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource compositionToAdd) { if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) - mixinTree.Compositions.Add(compositionName, composition = new ShaderArraySource()); + mixinTree.Compositions.Add(compositionName, composition = compositionToAdd is ShaderArraySource ? new ShaderArraySource() : new ShaderMixinSource()); - var arraySource = (ShaderArraySource)composition; - arraySource.Values.AddRange(evaluatedSource.Values); + if (compositionToAdd is ShaderArraySource compositionArrayToAdd) + { + var compositionArray = (ShaderArraySource)composition; + compositionArray.Values.AddRange(compositionArrayToAdd); + } + else + { + Merge((ShaderMixinSource)composition, compositionToAdd); + } } public void MergeCompositionArrayItem(ShaderMixinSource mixinTree, string compositionName, ShaderSource evaluatedSource) From 91dd98ca99d8d0f32c2ad725b5a2c6eedf33fee6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 21:40:31 +0900 Subject: [PATCH 0586/1182] Fix KeyInfo --- assets/SDSL/RenderTests/CompositionExternalStruct.sdsl | 2 +- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 4 ++-- src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs | 9 ++++----- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl index af5c586265..8409e08307 100644 --- a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl +++ b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.PerView=(Comp0.Light=(A=3), Comp1.Light=(A=7))) +// PSMain(ExpectedResult=#0A0A0A0A, cbuffer.PerView=(Light.Comp0=(A=3), Light.Comp1=(A=7))) namespace Stride.Shaders.Tests; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 96434be8fc..d4eb1b3e0a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -148,7 +148,7 @@ void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string { var member = cbuffer.StructType.Members[memberIndex]; - var link = $"{cbuffer.ShaderName}.{member.Name}"; + var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; if (!compositionPath.IsNullOrEmpty()) link = $"{link}.{compositionPath}"; @@ -1065,7 +1065,7 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon { var name = globalContext.Names[variable.ResultId]; linkInfos.TryGetValue(variable.ResultId, out var linkInfo); - var linkName = linkInfo.LinkName ?? $"{currentShaderName}.{name}"; + var linkName = linkInfo.LinkName ?? $"{TypeName.GetTypeNameWithoutGenerics(currentShaderName)}.{name}"; if (mixinNode.CompositionPath != null) linkName = $"{linkName}.{mixinNode.CompositionPath}"; diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 0b4ea5e167..90343a6ac1 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -242,7 +242,7 @@ public override unsafe void RenderFrame(Span result) var cbufferData = new byte[cbReflection.Size]; foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) { - var cbMemberReflection = cbReflection.Members.Single(x => x.KeyInfo.KeyName == cbufferParameter.Key); + var cbMemberReflection = cbReflection.Members.Single(x => x.KeyInfo.KeyName.EndsWith(cbufferParameter.Key)); fixed (byte* cbufferDataPtr = cbufferData) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index d21e952c07..d36fffb015 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -230,7 +230,8 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) { // TODO: make it a warning only? - table.Errors.Add(new(info, "LinkType generics should be passed without quotes")); + //table.Errors.Add(new(info, "LinkType generics should be passed without quotes")); + return (null, linkLiteralSymbol.IdRef); } return (linkLiteral.Value, null); @@ -248,8 +249,6 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable throw new NotImplementedException($"Attribute {attribute} is not supported"); } } - else - throw new NotImplementedException($"Attribute {attribute} is not supported"); } } @@ -293,8 +292,8 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); if (linkInfo.LinkId is int linkId) context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); - else - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{member.Name}"))); + else if (linkInfo.LinkName != null) + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName))); } } From 7d4af5a720ae2ef975980ab4bc98ef7c6e59ba5d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 22:38:37 +0900 Subject: [PATCH 0587/1182] Keep OpSDSLImport in the bytecode until the end for easier debugging --- .../SDSL/ShaderMixer.ShaderInfo.cs | 13 ------------- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 3 +++ .../Spirv/Processing/TypeDuplicatesRemover.cs | 5 ----- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index d5f58c5c73..bf497cc4f8 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -150,14 +150,12 @@ private void BuildImportInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { mixinNode.ExternalShaders.Add(importShader.ResultId, importShader.ShaderName); - SetOpNop(i.Data.Memory.Span); } else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) { if (mixinNode.ExternalShaders.ContainsKey(importFunction.Shader)) { mixinNode.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName)); - SetOpNop(i.Data.Memory.Span); } } else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) @@ -165,17 +163,6 @@ private void BuildImportInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd if (mixinNode.ExternalShaders.ContainsKey(importVariable.Shader)) { mixinNode.ExternalVariables.Add(importVariable.ResultId, (importVariable.Shader, importVariable.VariableName)); - SetOpNop(i.Data.Memory.Span); - } - } - // Removing OpName for OpSDSLImportShader and OpSDSLImportFunction (they are always located after, so no problem to do it in a single pass) - else if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) - { - if (mixinNode.ExternalShaders.ContainsKey(nameInstruction.Target) - || mixinNode.ExternalFunctions.ContainsKey(nameInstruction.Target) - || mixinNode.ExternalVariables.ContainsKey(nameInstruction.Target)) - { - SetOpNop(i.Data.Memory.Span); } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index d4eb1b3e0a..a91eec2cbe 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -658,6 +658,9 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // Setup types in context foreach (var type in globalContext.Types) { + // Ignore ShaderSymbol which are not fully loaded (they are likely just OpSDSLImportShader) + if (type.Value is ShaderSymbol && type.Value is not LoadedShaderSymbol) + continue; if (!context.ReverseTypes.ContainsKey(type.Key)) { context.Types.Add(type.Value, type.Key); diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index d99a4fca96..ca78e541ef 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -186,11 +186,6 @@ public readonly void Apply(NewSpirvBuffer buffer) ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparer); ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportShader, Op.OpSDSLImportShader, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportStruct, Op.OpSDSLImportStruct, true, comparer); - // Covers OpSDSLImportFunction and OpSDSLImportVariable at the same time - ProcessInstructions(buffer, instructionsByOp, Op.OpSDSLImportFunction, Op.OpSDSLImportVariable, true, comparer); - // Note: due to RemapOp, this will also cover OpMemberDecorate and OpMemberName ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparer); } From 16ead61ccb334fbf78b3a3defafe64d1febb4378 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 22:39:07 +0900 Subject: [PATCH 0588/1182] Additional testing for Composition arrays --- .../SDSL/RenderTests/CompositionArray1.sdsl | 32 +++++--- .../CompositionArrayForeachNested.sdsl | 62 ++++++++++++++++ .../RenderTests/CompositionArrayNested.sdsl | 73 +++++++++++++++++++ 3 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl create mode 100644 assets/SDSL/RenderTests/CompositionArrayNested.sdsl diff --git a/assets/SDSL/RenderTests/CompositionArray1.sdsl b/assets/SDSL/RenderTests/CompositionArray1.sdsl index 703cbcedc0..c5266a3c5f 100644 --- a/assets/SDSL/RenderTests/CompositionArray1.sdsl +++ b/assets/SDSL/RenderTests/CompositionArray1.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1A250000) +// PSMain(ExpectedResult=#1A052510) namespace Stride.Shaders.Tests; @@ -28,36 +28,48 @@ shader CompositionShaderB : CompositionBase shader CompositionTestArray { - stage compose CompositionBase CompsInherited[]; + stage compose CompositionBase CompsInheritedStage[]; + compose CompositionBase CompsInherited[]; } shader CompositionTest : CompositionTestArray { stream float4 ColorTarget : SV_Target0; - stage compose CompositionBase CompsLocal[]; + stage compose CompositionBase CompsStage[]; + stage compose CompositionBase Comps[]; void PSMain() { streams.ColorTarget = 0.0; - foreach(var comp in CompsLocal) + foreach(var comp in CompsStage) { streams.ColorTarget.x += comp.Compute(); } - foreach(var comp in CompsInherited) + foreach(var comp in Comps) { streams.ColorTarget.y += comp.Compute(); } + foreach(var comp in CompsInheritedStage) + { + streams.ColorTarget.z += comp.Compute(); + } + foreach(var comp in CompsInherited) + { + streams.ColorTarget.w += comp.Compute(); + } } }; effect CompositionArray1 { mixin CompositionTest; - mixin compose CompsLocal += CompositionShaderA; - mixin compose CompsLocal += CompositionShaderA; - mixin compose CompsLocal += CompositionShaderB; - mixin compose CompsInherited += CompositionShaderA; - mixin compose CompsInherited += CompositionShaderB; + mixin compose CompsStage += CompositionShaderA; + mixin compose CompsStage += CompositionShaderA; + mixin compose CompsStage += CompositionShaderB; + mixin compose Comps += CompositionShaderA; + mixin compose CompsInheritedStage += CompositionShaderA; + mixin compose CompsInheritedStage += CompositionShaderB; + mixin compose CompsInheritedStage += CompositionShaderB; mixin compose CompsInherited += CompositionShaderB; } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl b/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl new file mode 100644 index 0000000000..5c17532429 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl @@ -0,0 +1,62 @@ +// PSMain(ExpectedResult=#18180000) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float Compute() + { + return 3.0 / 255.0; + } +}; + +shader CompositionShaderA : CompositionBase +{ + override float Compute() + { + return 5.0 / 255.0; + } +}; + +shader CompositionShaderB : CompositionBase +{ + override float Compute() + { + return base.Compute() + 4.0 / 255.0; // 7.0 + } +}; + +shader CompositionTestArray +{ + stage compose CompositionBase CompsInheritedStage[]; +} + +shader CompositionTest : CompositionTestArray +{ + stream float4 ColorTarget : SV_Target0; + + stage compose CompositionBase CompsStage[]; + stage compose CompositionBase Comps[]; + + void PSMain() + { + streams.ColorTarget = 0.0; + foreach(var comp2 in CompsInheritedStage) + { + foreach(var comp1 in Comps) + { + streams.ColorTarget.x += comp1.Compute(); + streams.ColorTarget.y += comp2.Compute(); + } + } + } +}; + +effect CompositionArray1 +{ + mixin CompositionTest; + mixin compose Comps += CompositionShaderA; + mixin compose Comps += CompositionShaderB; + mixin compose CompsInheritedStage += CompositionShaderA; + mixin compose CompsInheritedStage += CompositionShaderB; +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/CompositionArrayNested.sdsl b/assets/SDSL/RenderTests/CompositionArrayNested.sdsl new file mode 100644 index 0000000000..7d14024ec5 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionArrayNested.sdsl @@ -0,0 +1,73 @@ +// PSMain(ExpectedResult=#02000000) + +namespace Stride.Shaders.Tests; + +shader CompositionBase2 +{ + float Compute() + { + return 1.0 / 255.0; + } +}; + +shader CompositionShader2 : CompositionBase2 +{ + override float Compute() + { + return 2.0 / 255.0; + } +}; + +shader CompositionBase1 +{ + compose CompositionBase2 Comps2[]; + + float Compute() + { + return 3.0 / 255.0; + } +}; + +shader CompositionShader1 : CompositionBase1 +{ + override float Compute() + { + float result = 0.0; + foreach (var comp in Comps2) + { + result += comp.Compute(); + } + return result; + } +}; + +shader CompositionTestArray +{ + compose CompositionBase1 Comps[]; +} + +shader CompositionTest : CompositionTestArray +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = 0.0; + foreach(var comp in Comps) + { + streams.ColorTarget.x += comp.Compute(); + } + } +}; + +effect CompositionArray +{ + mixin CompositionShader1; + mixin compose Comps2 += CompositionShader2; +} + +effect CompositionArrayNested +{ + mixin CompositionTest; + mixin compose Comps += CompositionArray; +} \ No newline at end of file From e8eabde74de05fc8376735d840617cc2eafbe8e2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 22:54:29 +0900 Subject: [PATCH 0589/1182] Remove OpName for IDs created inside methods that are skipped --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 4 ++++ src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a91eec2cbe..fdd77d2d5e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -566,6 +566,7 @@ bool ProcessStageMember(int memberId, bool isStage) if (!include) { + // We store removed IDs for further OpName removals if (i.Data.IdResult is int id) removedIds.Add(offset + id); @@ -576,6 +577,9 @@ bool ProcessStageMember(int memberId, bool isStage) // Skip until end of function while (shader[++index].Op != Op.OpFunctionEnd) { + // We store removed IDs for further OpName removals + if (shader[index].Data.IdResult is int id2) + removedIds.Add(offset + id2); } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index ca78e541ef..69716898fa 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -89,6 +89,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray || x.Op == Op.OpTypeStruct + || x.Op == Op.OpTypeGenericLinkSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); @@ -186,6 +187,8 @@ public readonly void Apply(NewSpirvBuffer buffer) ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparer); ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeGenericLinkSDSL, Op.OpTypeGenericLinkSDSL, true, comparer); + // Note: due to RemapOp, this will also cover OpMemberDecorate and OpMemberName ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparer); } From 756f37e0f6cc1a88cf57a9699d6d94bca6eddd83 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 23:11:17 +0900 Subject: [PATCH 0590/1182] Check composition arrays in stage root mixin too --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index fdd77d2d5e..44b42ee01e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -804,8 +804,10 @@ private static void ExpandForeach(SpirvContext context, NewSpirvBuffer buffer, M if (depth > 0) throw new InvalidOperationException("Could not find end of foreach instruction"); - // Check the variable - if (!mixinNode.CompositionArrays.TryGetValue(@foreach.Collection, out var compositions)) + // Check the variable (both in current mixin node or in stage) + // TODO: should we register Compositions by ID in the global context instead, to avoid having to check Stage all the time?) + if (!mixinNode.CompositionArrays.TryGetValue(@foreach.Collection, out var compositions) + && (mixinNode.Stage == null || !mixinNode.Stage.CompositionArrays.TryGetValue(@foreach.Collection, out compositions))) throw new InvalidOperationException($"Could not find compositions for expression [{@foreach.Collection}]"); // Extract foreach buffer (with the foreach start/end) @@ -896,7 +898,8 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } else if (i.Data.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { - if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions)) + if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions) + || (mixinNode.Stage != null && mixinNode.Stage.CompositionArrays.TryGetValue(accessChain.BaseId, out compositions))) { var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer(), temp); compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); From 8270f613a2d3f9bdcea9d19f419abe24cc608e8c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 12 Dec 2025 23:55:39 +0900 Subject: [PATCH 0591/1182] Better shader cleanup to remove any SDSL specific data --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 14 +++++++++----- .../Information/InstructionInfo.Order.cs | 2 +- src/Stride.Shaders/Core/SymbolTypes.cs | 8 +++++++- .../Parsing/SDSL/AST/ShaderElements.cs | 4 ++-- src/Stride.Shaders/Spirv/Building/Builder.Class.cs | 4 ++-- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 44b42ee01e..df63c066fe 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -59,12 +59,12 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect // Process reflection ProcessReflection(globalContext, context, temp, rootMixin); - temp.Sort(); + foreach (var inst in context) + temp.Add(inst.Data); CleanupUnnecessaryInstructions(temp); - foreach (var inst in context) - temp.Add(inst.Data); + temp.Sort(); // Final processing SpirvProcessor.Process(temp); @@ -1222,9 +1222,13 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) || temp[i].Op == Op.OpSDSLImportFunction || temp[i].Op == Op.OpSDSLImportVariable) temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpDecorateString && ((OpDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) + else if (temp[i].Op == Op.OpDecorate && ((OpDecorate)temp[i]).Decoration.Value is Decoration.LinkIdSDSL) + temp.RemoveAt(i--); + else if (temp[i].Op == Op.OpMemberDecorate && ((OpMemberDecorate)temp[i]).Decoration.Value == Decoration.LinkIdSDSL) + temp.RemoveAt(i--); + else if (temp[i].Op == Op.OpDecorateString && ((OpDecorateString)temp[i]).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)temp[i]).Decoration.Value == Decoration.LinkSDSL) + else if (temp[i].Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)temp[i]).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) temp.RemoveAt(i--); } } diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 6d143a889c..015d235f49 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -69,7 +69,7 @@ void InitOrder() OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec"))) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x == Op.OpSDSLGenericParameter)) OrderGroup[(e, null)] = group; group++; diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 092872a80b..40ac0d177d 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -116,6 +116,7 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// The size of the array. If -1, it means size is not defined, such as using []. public sealed record ArrayType(SymbolType BaseType, int Size, int? SizeExpressionId = null) : SymbolType() { + public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } public record StructuredType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : SymbolType() @@ -151,7 +152,11 @@ public int TryGetFieldIndex(string name) } -public sealed record StructType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members); +public sealed record StructType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members) +{ + public override string ToString() => $"struct {base.ToString()}"; +} + public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() { public override string ToString() => $"Buffer<{BaseType}, {Size}>"; @@ -249,6 +254,7 @@ public sealed record StreamsSymbol : SymbolType; public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members) { public override string ToId() => $"type.{Name}"; + public override string ToString() => $"cbuffer {base.ToString()}"; } public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index d36fffb015..639fc26404 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -291,7 +291,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); if (linkInfo.LinkId is int linkId) - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); else if (linkInfo.LinkName != null) context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName))); } @@ -345,7 +345,7 @@ internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass sha { var linkInfo = CBuffer.ProcessLinkAttributes(table, info, attributes); if (linkInfo.LinkId is int linkId) - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); else context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{memberName}"))); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index cb6258a664..b85e17b2d4 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -371,8 +371,8 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha for (var index = 0; index < shader.Count; index++) { var i = shader[index]; - if (i.Op == Op.OpMemberDecorateString - && ((OpMemberDecorateString)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) + if (i.Op == Op.OpMemberDecorate + && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) { using var n = new LiteralValue(m.Span); if (resolvedParameters.TryGetValue(n.Value, out var resolvedValue)) From d0b1002355f397583c6e5a3581864b62ee4b74ab Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 13 Dec 2025 00:24:58 +0900 Subject: [PATCH 0592/1182] fixup array testing --- .../SDSL/RenderTests/CompositionArray1.sdsl | 2 +- .../CompositionArrayForInsideForeach.sdsl | 55 +++++++++++++++++++ .../SDSL/ShaderMixer.cs | 25 ++++++--- 3 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl diff --git a/assets/SDSL/RenderTests/CompositionArray1.sdsl b/assets/SDSL/RenderTests/CompositionArray1.sdsl index c5266a3c5f..bdc16f634a 100644 --- a/assets/SDSL/RenderTests/CompositionArray1.sdsl +++ b/assets/SDSL/RenderTests/CompositionArray1.sdsl @@ -37,7 +37,7 @@ shader CompositionTest : CompositionTestArray stream float4 ColorTarget : SV_Target0; stage compose CompositionBase CompsStage[]; - stage compose CompositionBase Comps[]; + compose CompositionBase Comps[]; void PSMain() { diff --git a/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl b/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl new file mode 100644 index 0000000000..8cb68e46fa --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl @@ -0,0 +1,55 @@ +// PSMain(ExpectedResult=#15080000) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float Compute() + { + return 3.0 / 255.0; + } +}; + +shader CompositionShaderA : CompositionBase +{ + override float Compute() + { + return 5.0 / 255.0; + } +}; + +shader CompositionShaderB : CompositionBase +{ + override float Compute() + { + return base.Compute() + 13.0 / 255.0; + } +}; + +shader CompositionTest +{ + stream float4 ColorTarget : SV_Target0; + + compose CompositionBase Comps[]; + + void PSMain() + { + streams.ColorTarget = 0.0; + foreach(var comp in Comps) + { + streams.ColorTarget.x += comp.Compute(); + + for (int i = 0; i < 4; ++i) + { + streams.ColorTarget.y += 1.0 / 255.0; + } + } + } +}; + +effect CompositionArray1 +{ + mixin CompositionTest; + mixin compose Comps += CompositionShaderA; + mixin compose Comps += CompositionShaderB; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index df63c066fe..22af9eb4f9 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -787,7 +787,7 @@ private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); } - private static void ExpandForeach(SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) + private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) { // Find matching ForeachEnd (taking into account nested foreach) var depth = 1; @@ -826,16 +826,25 @@ private static void ExpandForeach(SpirvContext context, NewSpirvBuffer buffer, M foreachBufferCopy.Add(new(accessChain.InstructionMemory)); idRemapping.Add(@foreach.ResultId, accessChain); + // Do a first pass to find all IDs (OpBranch might point to OpLabel which are defined further) + foreach (var i in foreachBuffer[1..^1]) + { + if (i.IdResult is int result) + { + // Also duplicate name (if any) + if (globalContext.Names.TryGetValue(result, out var name)) + context.AddName(context.Bound, name); + idRemapping.Add(result, context.Bound++); + } + } // Build a buffer with all foreach instructions (with new ids) - foreach (var i2 in foreachBuffer[1..^1]) // skip start/end + foreach (var i in foreachBuffer[1..^1]) // skip start/end { - var i3 = new OpData(i2.Memory.Span); + var i2 = new OpData(i.Memory.Span); // All result ids are remapped to new ids - if (i3.IdResult is int result) - idRemapping.Add(result, context.Bound++); - SpirvBuilder.RemapIds(idRemapping, i3); + SpirvBuilder.RemapIds(idRemapping, i2); - foreachBufferCopy.Add(i3); + foreachBufferCopy.Add(i2); } } buffer.InsertRange(index, foreachBufferCopy.AsSpan()); @@ -879,7 +888,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (i.Data.Op == Op.OpForeachSDSL && (OpForeachSDSL)i is { } @foreach) { - ExpandForeach(context, temp, mixinNode, index, @foreach); + ExpandForeach(globalContext, context, temp, mixinNode, index, @foreach); } else if (i.Data.Op == Op.OpThisSDSL && (OpThisSDSL)i is { } thisInstruction) { From bb484990d76f4c5d7f09b829924dce06dcf02ce5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 13 Dec 2025 00:59:34 +0900 Subject: [PATCH 0593/1182] Properly handle SV_IsFrontFace --- .../Spirv/Processing/StreamAnalyzer.cs | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index a40662184e..6eac599a2f 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -270,12 +270,21 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); - if (stream.Value.Stream.InputLayoutLocation == null) - stream.Value.Stream.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.InputLayoutLocation.Value))); - if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + switch (stream.Value.Stream.Semantic?.ToUpperInvariant()) + { + case "SV_ISFRONTFACE": + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FrontFacing))); + context.Add(new OpDecorate(variable, Decoration.Flat)); + break; + default: + if (stream.Value.Stream.InputLayoutLocation == null) + stream.Value.Stream.InputLayoutLocation = inputLayoutLocationCount++; + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.InputLayoutLocation.Value))); + if (stream.Value.Stream.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + break; + } inputStreams.Add((stream.Value.Stream, variable.ResultId)); } @@ -286,24 +295,25 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); context.AddName(variable, $"out_{stage}_{stream.Value.Stream.Name}"); - if (stream.Value.Stream.Semantic?.ToUpperInvariant() == "SV_POSITION") - { - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); - } - else + switch (stream.Value.Stream.Semantic?.ToUpperInvariant()) { - // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic - if (stream.Value.Stream.OutputLayoutLocation == null) - { - if (stream.Value.Stream.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) - stream.Value.Stream.OutputLayoutLocation = outputLayoutLocationCount++; - else - throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Stream.Name}]"); - } + case "SV_POSITION": + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); + break; + default: + // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic + if (stream.Value.Stream.OutputLayoutLocation == null) + { + if (stream.Value.Stream.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) + stream.Value.Stream.OutputLayoutLocation = outputLayoutLocationCount++; + else + throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Stream.Name}]"); + } - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.OutputLayoutLocation.Value))); - if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.OutputLayoutLocation.Value))); + if (stream.Value.Stream.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + break; } outputStreams.Add((stream.Value.Stream, variable.ResultId)); From 48ed80a8e3aada4812c5aa2352206be46787b275 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 14 Dec 2025 14:29:57 +0900 Subject: [PATCH 0594/1182] Macro (WIP) --- .../SDSL/EffectEvaluator.cs | 57 +++++++++++++------ src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 14 +++-- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 7 ++- src/Stride.Shaders.Experiments/Examples.cs | 13 +++-- src/Stride.Shaders.Experiments/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 11 +++- .../Parsing/Analysis/SymbolTable.cs | 1 + .../Parsing/SDSL/AST/Literals.cs | 3 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 6 +- .../Spirv/Building/Builder.Class.cs | 28 ++++----- .../Spirv/Building/CompilerUnit.cs | 2 + src/Stride.Shaders/Spirv/Building/Context.cs | 12 ++-- 12 files changed, 101 insertions(+), 55 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 87fa921b4b..c3386dcf5b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Parsing.SDSL; +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -13,12 +14,15 @@ namespace Stride.Shaders.Compilers.SDSL { internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) { + private Stack mixinSources = new(); + public ShaderSource EvaluateEffects(ShaderSource source) { switch (source) { case ShaderClassSource classSource: - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments); + var macros = mixinSources.Count > 0 ? mixinSources.Peek().Macros : []; + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); if (buffer[0].Op == Op.OpSDSLEffect) { @@ -63,21 +67,30 @@ public ShaderSource EvaluateEffects(ShaderSource source) { var result = new ShaderMixinSource(); foreach (var macro in mixinSource.Macros) - { result.Macros.Add(macro); - } - foreach (var mixin in mixinSource.Mixins) + + if (mixinSources.Count > 0) + PropagateMacrosFromParent(mixinSources.Peek(), result); + + mixinSources.Push(result); + try { - var evaluatedMixin = EvaluateEffects(mixin); - Merge(result, evaluatedMixin); - } + foreach (var mixin in mixinSource.Mixins) + { + var evaluatedMixin = EvaluateEffects(mixin); + Merge(result, evaluatedMixin); + } - foreach (var composition in mixinSource.Compositions) + foreach (var composition in mixinSource.Compositions) + { + var evaluatedMixin = EvaluateEffects(composition.Value); + MergeComposition(result, composition.Key, evaluatedMixin); + } + } + finally { - var evaluatedMixin = EvaluateEffects(composition.Value); - MergeComposition(result, composition.Key, evaluatedMixin); + mixinSources.Pop(); } - return result; } case ShaderArraySource arraySource: @@ -95,6 +108,20 @@ public ShaderSource EvaluateEffects(ShaderSource source) } } + private void PropagateMacrosFromParent(ShaderMixinSource parent, ShaderMixinSource child) + { + var existingMacros = new HashSet(); + foreach (var macro in child.Macros) + { + existingMacros.Add(macro.Name); + } + foreach (var macro in parent.Macros) + { + if (!existingMacros.Contains(macro.Name)) + child.AddMacro(macro.Name, macro.Definition); + } + } + public void Merge(ShaderMixinSource mixinTree, ShaderSource source) { switch (source) @@ -103,10 +130,8 @@ public void Merge(ShaderMixinSource mixinTree, ShaderSource source) mixinTree.Mixins.Add(classSource); break; case ShaderMixinSource mixinSource: - foreach (var mixin in mixinSource.Mixins) - { - mixinTree.Mixins.Add(mixin); - } + mixinTree.Macros.AddRange(mixinSource.Macros); + mixinTree.Mixins.AddRange(mixinSource.Mixins); foreach (var composition in mixinSource.Compositions) { diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 7d26cb1a19..2794277439 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -15,7 +15,7 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuffer lastBuffer) + public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer lastBuffer) { var parsed = SDSLParser.Parse(code); lastBuffer = null; @@ -33,9 +33,11 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf { SymbolTable table = new() { - ShaderLoader = ShaderLoader + ShaderLoader = ShaderLoader, + CurrentMacros = [..macros], }; var compiler = new CompilerUnit(); + compiler.Macros.AddRange(macros); shader.Compile(table, compiler); if (table.Errors.Count > 0) @@ -47,15 +49,17 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf #endif lastBuffer = merged; - ShaderLoader.RegisterShader(shader.Name, merged); + ShaderLoader.RegisterShader(shader.Name, macros, merged); } else if (declaration is ShaderEffect effect) { SymbolTable table = new() { - ShaderLoader = ShaderLoader + ShaderLoader = ShaderLoader, + CurrentMacros = [..macros], }; var compiler = new CompilerUnit(); + compiler.Macros.AddRange(macros); effect.Compile(table, compiler); var merged = compiler.ToBuffer(); @@ -64,7 +68,7 @@ public readonly bool Compile(string code, [MaybeNullWhen(false)] out NewSpirvBuf #endif lastBuffer = merged; - ShaderLoader.RegisterShader(effect.Name, merged); + ShaderLoader.RegisterShader(effect.Name, macros, merged); } else { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 1db86491ad..1d01de79b3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Core; +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; @@ -31,9 +32,9 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource foreach (var mixinToMerge in shaderMixinSource.Mixins) { var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName, mixinToMerge.GenericArguments); + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); mixinToMerge2.Buffer = buffer; - SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } var compositions = new Dictionary(); diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 3139e217f1..abd3aaeec2 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -210,7 +210,7 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) public class ShaderLoader : ShaderLoaderBase { - public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/{name}.sdsl"; if (!File.Exists(filename)) @@ -218,12 +218,17 @@ public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out Ne buffer = null; return false; } - var text = MonoGamePreProcessor.OpenAndRun(filename); + + var defines = new (string Name, string Definition)[macros.Length]; + for (int i = 0; i < macros.Length; ++i) + defines[i] = (macros[i].Name, macros[i].Definition); + + var text = MonoGamePreProcessor.OpenAndRun(filename, defines); var sdslc = new SDSLC { ShaderLoader = this }; - return sdslc.Compile(text, out buffer); + return sdslc.Compile(text, macros, out buffer); } } @@ -242,7 +247,7 @@ public static void CompileSDSL(string shaderName) { ShaderLoader = new ShaderLoader() }; - if (sdslc.Compile(text, out var buffer) && buffer is not null) + if (sdslc.Compile(text, [], out var buffer) && buffer is not null) { Spirv.Tools.Spv.Dis(buffer, writeToConsole: true); var bytecode = buffer.ToBytecode(); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 1f67795585..beb0c1c817 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -13,7 +13,7 @@ //Examples.CompileSDSL(); var loader = new Examples.ShaderLoader(); -loader.LoadExternalFile("Test", out var testBuffer); +loader.LoadExternalFile("Test", [], out var testBuffer); var shaderMixer = new ShaderMixer(loader); shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 71b4ea869b..5c44e70090 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -29,7 +29,7 @@ public class RenderingTests class ShaderLoader : ShaderLoaderBase { - public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; if (!File.Exists(filename)) @@ -37,11 +37,16 @@ public override bool LoadExternalFile(string name, [MaybeNullWhen(false)] out Ne buffer = null; return false; } - var text = MonoGamePreProcessor.OpenAndRun(filename); + + var defines = new (string Name, string Definition)[macros.Length]; + for (int i = 0; i < macros.Length; ++i) + defines[i] = (macros[i].Name, macros[i].Definition); + + var text = MonoGamePreProcessor.OpenAndRun(filename, defines); var sdslc = new SDSLC(); sdslc.ShaderLoader = this; - var result = sdslc.Compile(text, out buffer); + var result = sdslc.Compile(text, macros, out buffer); #if DEBUG if (result) { diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index b2fee5a42f..e6c0cf9942 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -23,6 +23,7 @@ public partial class SymbolTable : ISymbolProvider // Only valid during compilation (not during ShaderMixin phase) public LoadedShaderSymbol? CurrentShader { get; set; } + public List CurrentMacros { get; set; } // Only valid during compilation (not during ShaderMixin phase) public List InheritedShaders { get; set; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ba9e7a31dd..7ec730c657 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; @@ -260,7 +261,7 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref i // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.InheritedShaders, ResolveStep.Compile, buffer); + classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile, buffer); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { table.InheritedShaders[i].Symbol = ShaderClass.LoadExternalShaderType(table, table.InheritedShaders[i]); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 0eb2fd58a9..c49cda3333 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -237,7 +237,7 @@ public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) return (ShaderSymbol)symbolType; - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, buffer); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, buffer); classSource.Buffer = shader; var shaderType = LoadExternalShaderType(table, classSource); table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); @@ -352,7 +352,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); - SpirvBuilder.BuildInheritanceList(table.ShaderLoader, shaderClassSource, inheritanceList, ResolveStep.Compile, context.GetBuffer()); + SpirvBuilder.BuildInheritanceList(table.ShaderLoader, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile, context.GetBuffer()); } var shaderSymbols = new List(); @@ -389,7 +389,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) if (svar.TypeName.Name.Contains("<")) throw new NotImplementedException("Can't have member variables with generic shader types"); var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, ResolveStep.Compile, context.GetBuffer()); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context.GetBuffer()); classSource.Buffer = shader; var shaderType = LoadExternalShaderType(table, classSource); table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index b85e17b2d4..36cd7e3669 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Core; +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; @@ -84,7 +85,7 @@ public override int GetHashCode() public partial class SpirvBuilder { - private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) + private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping var shaderMapping = new Dictionary(); @@ -104,7 +105,7 @@ private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoade if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { var shaderName = shaderMapping[inherit.Shader]; - BuildInheritanceList(shaderLoader, shaderName, inheritanceList, resolveStep, buffer); + BuildInheritanceList(shaderLoader, shaderName, macros, inheritanceList, resolveStep, buffer); } } } @@ -114,7 +115,7 @@ public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); } - public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) { // TODO: cache same instantiations within context? var index = inheritanceList.IndexOf(classSource); @@ -122,7 +123,7 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade { if (classSource.Buffer == null) { - var shader = GetOrLoadShader(shaderLoader, classSource, resolveStep, parentBuffer); + var shader = GetOrLoadShader(shaderLoader, classSource, macros, resolveStep, parentBuffer); classSource.Buffer = shader; } @@ -130,7 +131,7 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade index = inheritanceList.IndexOf(classSource); if (index == -1) { - BuildInheritanceListHelper(shaderLoader, classSource, classSource.Buffer, inheritanceList, resolveStep); + BuildInheritanceListHelper(shaderLoader, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); index = inheritanceList.Count; inheritanceList.Add(classSource); } @@ -479,12 +480,13 @@ public static void RemapIds(Dictionary idRemapping, OpData i) /// /// /// The generics parameters should be in . + /// /// - /// /// - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) + /// + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) { - var shader = GetOrLoadShader(shaderLoader, classSource.ClassName, out var isFromCache); + var shader = GetOrLoadShader(shaderLoader, classSource.ClassName, macros, out var isFromCache); if (!isFromCache) Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -501,9 +503,9 @@ public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, return shader; } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan defines) { - var shader = GetOrLoadShader(shaderLoader, className, out var isFromCache); + var shader = GetOrLoadShader(shaderLoader, className, defines, out var isFromCache); if (!isFromCache) Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -549,11 +551,11 @@ public static List CollectGenerics(NewSpirvBuffer shader) return generics; } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, out bool isFromCache) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) { Console.WriteLine($"[Shader] Requesting non-generic class {className}"); - if (!shaderLoader.LoadExternalBuffer(className, out var buffer, out isFromCache)) + if (!shaderLoader.LoadExternalBuffer(className, defines, out var buffer, out isFromCache)) throw new InvalidOperationException($"Could not load shader [{className}]"); if (!isFromCache) diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 7afe779db5..8097ddfaeb 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -15,6 +15,8 @@ public class CompilerUnit public SpirvBuilder Builder { get; } public List Arguments { get; } + public List Macros { get; } = []; + public CompilerUnit() { Context = new SpirvContext(); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 5f484c27dd..8ddbaad36c 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -15,22 +15,22 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { - public void RegisterShader(string name, NewSpirvBuffer buffer); - public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); + public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer); + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); } public abstract class ShaderLoaderBase : IExternalShaderLoader { private Dictionary loadedShaders = []; - public void RegisterShader(string name, NewSpirvBuffer buffer) + public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer) { loadedShaders.Add(name, buffer); } - public abstract bool LoadExternalFile(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); + public abstract bool LoadExternalFile(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); - public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) { if (loadedShaders.TryGetValue(name, out buffer)) { @@ -39,7 +39,7 @@ public bool LoadExternalBuffer(string name, [MaybeNullWhen(false)] out NewSpirvB } isFromCache = false; - if (!LoadExternalFile(name, out buffer)) + if (!LoadExternalFile(name, defines, out buffer)) { throw new InvalidOperationException($"Shader {name} could not be found"); } From 1a6e2fb73f8d03909bb33292d19c25fc90490129 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 13:32:17 +0900 Subject: [PATCH 0595/1182] ImportShader: consider generics when creating type name --- assets/SDSL/RenderTests/GenericsLinkType.sdsl | 38 +++++++++++++++++++ .../SDSL/ShaderMixer.ShaderInfo.cs | 14 ++++++- .../Spirv/Building/Builder.Class.cs | 9 ++++- 3 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsLinkType.sdsl diff --git a/assets/SDSL/RenderTests/GenericsLinkType.sdsl b/assets/SDSL/RenderTests/GenericsLinkType.sdsl new file mode 100644 index 0000000000..dd221e63b8 --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsLinkType.sdsl @@ -0,0 +1,38 @@ +// PSMain(ExpectedResult=#08FFFFFF, cbuffer.Test=(Test123=05, Test456=03)) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader ComputeLink : Compute +{ + cbuffer Test + { + [Link(Link1)] + int Test1; + + [Link("Link2")] + int Test2; + } + + override float Compute() + { + return ((float)Test1 + (float)Test2) / 255.0; + } +} + +shader GenericsLinkType : ComputeLink<"Test123", "Test456"> +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index bf497cc4f8..a6afb495c6 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -149,7 +149,19 @@ private void BuildImportInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - mixinNode.ExternalShaders.Add(importShader.ResultId, importShader.ShaderName); + // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups + var shaderName = importShader.ShaderName; + if (importShader.Values.Elements.Length > 0) + { + var genericArguments = new object[importShader.Values.Elements.Length]; + for (int j = 0; j < genericArguments.Length; j++) + { + genericArguments[j] = SpirvBuilder.GetConstantValue(importShader.Values.Elements.Span[j], temp); + } + shaderName += $"<{string.Join(",", genericArguments)}>"; + } + + mixinNode.ExternalShaders.Add(importShader.ResultId, shaderName); } else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 36cd7e3669..20ee76e845 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -197,6 +197,13 @@ public static bool TryGetConstantValue(OpData data, out object value, params Rea return false; } + if (data.Op == Op.OpConstantStringSDSL) + { + var operand2 = data.Get("literalString"); + value = operand2.ToLiteral(); + return true; + } + int typeId = data.Op switch { Op.OpConstant or Op.OpSpecConstant => data.Memory.Span[1], @@ -378,7 +385,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha using var n = new LiteralValue(m.Span); if (resolvedParameters.TryGetValue(n.Value, out var resolvedValue)) { - linkDecorate.Decoration = new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]); + shader.Replace(index, new OpMemberDecorateString(linkDecorate.StructureType, linkDecorate.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } } From 8162a8204e08b52ea096f18a6f6fa5de5527c7a4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 13:36:28 +0900 Subject: [PATCH 0596/1182] SpirvTranslator: Preserve HLSL semantic for input variables (only in vertex shader) --- src/Stride.Shaders.Compilers/SpirvTranslator.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index e143bbe10a..36f5b505cb 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -111,6 +111,23 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam cross.CompilerSetName(compiler, resource.BaseTypeId, cbufferName); } } + + // Inputs: Apply UserSemantic (instead of TEXCOORD) + // This is a workaround until SPIRV-Cross supports UserSemantic + cross.ResourcesGetResourceListForType(resources, ResourceType.StageInput, &resourcesList, &resourcesCount); + var vertexInputRemap = stackalloc HlslVertexAttributeRemap[(int)resourcesCount]; + var vertexInputRemapCount = 0; + for (uint i = 0; i < resourcesCount; ++i) + { + if (cross.CompilerHasDecoration(compiler, resourcesList[i].Id, Decoration.Location) != 0 + && cross.CompilerHasDecoration(compiler, resourcesList[i].Id, Decoration.UserSemantic) != 0) + { + vertexInputRemap[vertexInputRemapCount].Location = cross.CompilerGetDecoration(compiler, resourcesList[i].Id, Decoration.Location); + vertexInputRemap[vertexInputRemapCount].Semantic = cross.CompilerGetDecorationString(compiler, resourcesList[i].Id, Decoration.UserSemantic); + vertexInputRemapCount++; + } + } + cross.CompilerHlslAddVertexAttributeRemap(compiler, vertexInputRemap, (nuint)vertexInputRemapCount); } nuint numSamplers = 0; From 41fbfe65eb7554ef4f456f2ef8938fc797499868 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 13:38:00 +0900 Subject: [PATCH 0597/1182] Generics: transform LinkId into Link even if shaders is instantiated with string generic arguments --- .../Spirv/Building/Builder.Class.cs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 20ee76e845..7522c3caf4 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -253,6 +253,8 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh var bound = shader.Header.Bound; + var resolvedLinks = new Dictionary(); + var genericValueIndex = 0; for (var index = 0; index < shader.Count; index++) { @@ -277,6 +279,7 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh break; case GenericLinkType: shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + resolvedLinks.Add(genericParameter.ResultId, genericValue); break; default: throw new NotImplementedException(); @@ -288,6 +291,8 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh } } + TransformResolvedLinkIdIntoLinkString(shader, resolvedLinks); + // In case we had to increase bound (new instructions), update header shader.Header = shader.Header with { Bound = bound }; } @@ -375,20 +380,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha } } - // Try to resolve LinkType generics - for (var index = 0; index < shader.Count; index++) - { - var i = shader[index]; - if (i.Op == Op.OpMemberDecorate - && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) - { - using var n = new LiteralValue(m.Span); - if (resolvedParameters.TryGetValue(n.Value, out var resolvedValue)) - { - shader.Replace(index, new OpMemberDecorateString(linkDecorate.StructureType, linkDecorate.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); - } - } - } + TransformResolvedLinkIdIntoLinkString(shader, resolvedParameters); // Fully resolved? if (resolvedParameters.Count == generics.Count) @@ -417,6 +409,24 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha } } + private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, Dictionary resolvedLinks) + { + // Try to resolve LinkType generics + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpMemberDecorate + && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) + { + using var n = new LiteralValue(m.Span); + if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) + { + shader.Replace(index, new OpMemberDecorateString(linkDecorate.StructureType, linkDecorate.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + } + } + } + } + public static void SetOpNop(Span words) { words[0] = words.Length << 16; From 17d8dbfe3283257cc6c62892e229388aa3387358 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 13:39:15 +0900 Subject: [PATCH 0598/1182] Reflection: keep cbuffer members logical groups during cbuffer merge --- .../SDSL/ShaderMixer.cs | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 22af9eb4f9..7e9b8215ed 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -95,6 +95,15 @@ string GetCBufferFinalName(string cbufferName) return cbufferName; } + string GetCBufferLogicalGroup(string cbufferName) + { + var dotIndex = cbufferName.IndexOf('.'); + if (dotIndex != -1) + return cbufferName.Substring(dotIndex + 1); + + return null; + } + // OpSDSLEffect is emitted for any non-root composition var compositionNodes = buffer .Where(x => x.Op == Op.OpSDSLEffect) @@ -116,7 +125,8 @@ string GetCBufferFinalName(string cbufferName) ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, StructTypePtrId: x.Variable.ResultType, StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberIndexOffset: 0)) + MemberIndexOffset: 0, + LogicalGroup: GetCBufferLogicalGroup(globalContext.Names[x.Variable.ResultId]))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); @@ -137,7 +147,7 @@ string GetCBufferFinalName(string cbufferName) } } - void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset)> cbuffersSpan, int cbufferStructId) + void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId) { int mergedMemberIndex = 0; foreach (ref var cbuffer in cbuffersSpan) @@ -157,6 +167,8 @@ void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string link = linkValue; context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(link))); + if (cbuffer.LogicalGroup != null) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); } } } @@ -343,8 +355,9 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo } } - // Scan LinkSDSL decorations + // Scan LinkSDSL and LogicalGroupSDSL decorations Dictionary<(int StructType, int Member), string> links = new(); + Dictionary<(int StructType, int Member), string> logicalGroups = new(); foreach (var i in context.GetBuffer()) { if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) @@ -352,6 +365,11 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo using var n = new LiteralValue(m.Span); links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) + { + using var n = new LiteralValue(m2.Span); + logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); + } } foreach (var cbuffer in cbuffers) @@ -371,6 +389,8 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo if (!links.TryGetValue((structTypeId, index), out var linkName)) throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); + // Allowed to be not set (in which case logicalGroup == null) + logicalGroups.TryGetValue((structTypeId, index), out var logicalGroup); memberInfos[index] = new EffectValueDescription { @@ -379,6 +399,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, Offset = constantBufferOffset, Size = memberSize, + LogicalGroup = logicalGroup, }; // Adjust offset for next item From c309854283de646dd97adc44b3db80ce1ac8daae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 14:13:02 +0900 Subject: [PATCH 0599/1182] Cbuffer merging: keep all decorations --- .../SDSL/ShaderMixer.cs | 84 ++++++++++++------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 7e9b8215ed..e43246b652 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; using Silk.NET.SPIRV.Cross; using Stride.Core.Extensions; using Stride.Shaders.Core; @@ -133,21 +134,25 @@ string GetCBufferLogicalGroup(string cbufferName) var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); - Dictionary<(int StructType, int Member), string> links = new(); + Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); foreach (var i in buffer) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) { - if (cbufferStructTypes.Contains(memberDecorate.StructType)) - { - using var n = new LiteralValue(m.Span); - links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); - SetOpNop(i.Data.Memory.Span); - } + using var n = new LiteralValue(m.Span); + if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); + } + else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) + { + if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); } } - void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId) + void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) { int mergedMemberIndex = 0; foreach (ref var cbuffer in cbuffersSpan) @@ -158,17 +163,37 @@ void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string { var member = cbuffer.StructType.Members[memberIndex]; - var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; - if (!compositionPath.IsNullOrEmpty()) - link = $"{link}.{compositionPath}"; + if (!decorations.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var decorationsForThisMember)) + decorations.Add((context.Types[cbuffer.StructType], memberIndex), decorationsForThisMember = new(new(), new())); + + decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); + + if (!newStructure) + { + // If not a new structure, we restart from 0 and add only what's necessary + // Note: we made sure to query linkValue before + decorationsForThisMember.StringDecorations.Clear(); + decorationsForThisMember.Decorations.Clear(); + } + + // If not specified, add default Link info + if (linkValue == null) + { + var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; + if (!compositionPath.IsNullOrEmpty()) + link = $"{link}.{compositionPath}"; - // Check if there is already a decoration (i.e. from an explicit "Link") - if (links.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var linkValue)) - link = linkValue; + decorationsForThisMember.StringDecorations.Add(Decoration.LinkSDSL, link); + } - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(link))); + // Also transfer LogicalGroup (from name) if (cbuffer.LogicalGroup != null) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); + decorationsForThisMember.StringDecorations.Add(Decoration.LogicalGroupSDSL, cbuffer.LogicalGroup); + + foreach (var stringDecoration in decorationsForThisMember.StringDecorations) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); + foreach (var decoration in decorationsForThisMember.Decorations) + context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); } } } @@ -180,7 +205,7 @@ void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string if (cbuffersEntry.Count() == 1) { - DecorateLinks(cbuffersSpan, context.Types[cbuffersEntry.First().StructType]); + ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); } // More than 1 cbuffers with same name else @@ -199,7 +224,7 @@ void DecorateLinks(Span<(OpVariableSDSL Variable, string CompositionPath, string var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); var mergedCbufferPtrStructId = context.GetOrRegister(new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform)); - DecorateLinks(cbuffersSpan, mergedCbufferStructId); + ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); // Remap member ids foreach (var i in buffer) @@ -358,17 +383,20 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo // Scan LinkSDSL and LogicalGroupSDSL decorations Dictionary<(int StructType, int Member), string> links = new(); Dictionary<(int StructType, int Member), string> logicalGroups = new(); - foreach (var i in context.GetBuffer()) + foreach (var temp in new[] { context.GetBuffer(), buffer }) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); - } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) + foreach (var i in temp) { - using var n = new LiteralValue(m2.Span); - logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + using var n = new LiteralValue(m.Span); + links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); + } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) + { + using var n = new LiteralValue(m2.Span); + logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); + } } } From e3998ad2c620750bb1ce6f3aae439b593c0a9698 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 14:32:16 +0900 Subject: [PATCH 0600/1182] Added support for static const variables (initializer is wrapped in a method, called in the entry point) --- assets/SDSL/RenderTests/StaticConstant.sdsl | 22 +++++++++++++++++ .../SDSL/ShaderMixer.cs | 5 ++-- .../Extensions/spirv.sdsl.grammar-ext.json | 2 +- .../SPVGenerator.Instructions.cs | 8 +++---- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 22 ++++++++++++++++- .../Parsing/SDSL/AST/Statements.cs | 14 +++++++---- .../Spirv/Processing/StreamAnalyzer.cs | 24 ++++++++++++++++++- 7 files changed, 84 insertions(+), 13 deletions(-) create mode 100644 assets/SDSL/RenderTests/StaticConstant.sdsl diff --git a/assets/SDSL/RenderTests/StaticConstant.sdsl b/assets/SDSL/RenderTests/StaticConstant.sdsl new file mode 100644 index 0000000000..71ce8c0efb --- /dev/null +++ b/assets/SDSL/RenderTests/StaticConstant.sdsl @@ -0,0 +1,22 @@ +// PSMain(ExpectedResult=#11111111) + +namespace Stride.Shaders.Tests; + +shader StaticConstant +{ + static const float Const1 = 17.0; + + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = float4(Const1, Const1, Const1, Const1) / 255.0; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e43246b652..eeb6ed342a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1060,7 +1060,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function && temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[function.ResultId]}"); @@ -1263,8 +1263,9 @@ private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) for (int i = 0; i < temp.Count; i++) { // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) + // Note: we ignore initializer as we store a method which is already processed during StreamAnalyzer (as opposed to a const for OpVariable) if (temp[i].Op == Op.OpVariableSDSL && (OpVariableSDSL)temp[i] is { } variable) - temp.Replace(i, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, variable.Initializer)); + temp.Replace(i, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); // Remove Nop if (temp[i].Op == Op.OpNop) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 64cb63d110..c0871f54cd 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -149,7 +149,7 @@ { "kind": "IdRef", "quantifier": "?", - "name": "'Initializer'" + "name": "'MethodInitializer'" } ] }, diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index b2bf22de5c..fa81db07a8 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -198,7 +198,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); if (needCloseBrace) body2.AppendLine("}"); @@ -351,7 +351,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i body2.AppendLine($"{fieldName} = o.To{typename}();"); else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); @@ -469,7 +469,7 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, } else if (operand.Class is string s && s.Contains("Enum")) body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); @@ -582,7 +582,7 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); else if (typename.StartsWith("LiteralValue")) body2.AppendLine($"{fieldName} = o.ToLiteral();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename}>();"); + else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); // Body 3 if (typename.StartsWith("LiteralArray")) body3.AppendLine($"{fieldName}.Assign({operandName});"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 7a65607cef..f1400c6e02 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -125,7 +125,27 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; - context.Add(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, null)); + int? initializerMethod = null; + if (Value != null) + { + var valueType = ((PointerType)Type).BaseType; + + // TODO: differentiate const from code that needs to go in entry point? + // TODO: move to entry point + var functionType = new FunctionType(valueType, []); + initializerMethod = builder.Insert(new OpFunction(context.GetOrRegister(valueType), context.Bound++, Specification.FunctionControlMask.Const, context.GetOrRegister(functionType))).ResultId; + builder.Insert(new OpLabel(context.Bound++)); + + var initialValue = Value.CompileAsValue(table, compiler); + initialValue = builder.Convert(context, initialValue, ((PointerType)Type).BaseType); + + builder.Return(initialValue); + builder.Insert(new OpFunctionEnd()); + + context.AddName(initializerMethod.Value, $"{Name}_Initializer"); + } + + context.Add(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, initializerMethod)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 497e58cb1c..8a53cca37a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -38,14 +38,20 @@ public override string ToString() public class Return(TextLocation info, Expression? expression = null) : Statement(info) { - public override SymbolType? Type { get => Value?.Type ?? ScalarType.From("void"); set { } } public Expression? Value { get; set; } = expression; public override void Compile(SymbolTable table, CompilerUnit compiler) { - var (builder, _) = compiler; - builder.Return(Value?.CompileAsValue(table, compiler)); - Type = Value?.Type ?? ScalarType.From("void"); + var (builder, context) = compiler; + SpirvValue? returnValue = null; + + Type = builder.CurrentFunction!.Value.FunctionType.ReturnType; + if (Value != null) + { + var value = Value.CompileAsValue(table, compiler); + returnValue = builder.Convert(context, value, Type); + } + builder.Return(returnValue); } public override string ToString() { diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 6eac599a2f..b4e8372afd 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -19,6 +19,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public SymbolType Type { get; } = type; public int VariableId { get; } = variableId; + public int? VariableMethodInitializerId { get; set; } public int? InputLayoutLocation { get; set; } public int? OutputLayoutLocation { get; set; } @@ -202,7 +203,15 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) : $"unnamed_{variable.ResultId}"; var type = context.ReverseTypes[variable.ResultType]; semanticTable.TryGetValue(variable.ResultId, out var semantic); - streams.Add(variable.ResultId, (new StreamInfo(semantic, name, type, variable.ResultId), true)); + + var stream = (new StreamInfo(semantic, name, type, variable.ResultId) + { + // Does it have an initializer? if yes, mark it as a value written in this stage + Write = variable.MethodInitializer != null, + VariableMethodInitializerId = variable.MethodInitializer, + }, true); + + streams.Add(variable.ResultId, stream); } if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is @@ -329,6 +338,19 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); { + // Variable initializers + foreach (var stream in streams) + { + // Note: we check Private to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) + if (stream.Value.Stream.Private + && stream.Value.Stream.VariableMethodInitializerId is int methodInitializerId) + { + var variableValueType = ((PointerType)stream.Value.Stream.Type).BaseType; + buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); + buffer.Add(new OpStore(stream.Value.Stream.VariableId, methodInitializerCall.ResultId, null)); + } + } + // Copy read variables from streams foreach (var stream in inputStreams) { From 8b65101701f2263512dfa19c6836761ad1a86956 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 15:29:28 +0900 Subject: [PATCH 0601/1182] Add OpVariable with builder rather than context --- .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 9 ++++----- src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f1400c6e02..97ba1b8b1e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -46,14 +46,13 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Parameters.Count > 0) table.Errors.Add(new SemanticErrors(Info, "Sampler states with parameters are not supported in SPIR-V generation.")); - (_, var context) = compiler; + (var builder, var context) = compiler; Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); var registeredType = context.GetOrRegister(Type); if (!table.RootSymbols.TryGetValue(Name, out _)) { - context - .FluentAdd(new OpVariableSDSL(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null), out var register) - .FluentAdd(new OpName(register.ResultId, Name), out _); + var register = builder.Insert(new OpVariableSDSL(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + context.AddName(register.ResultId, Name); var sid = new SymbolID(Name, SymbolKind.SamplerState); var symbol = new Symbol(sid, Type, register.ResultId); @@ -145,7 +144,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.AddName(initializerMethod.Value, $"{Name}_Initializer"); } - context.Add(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, initializerMethod)); + builder.Insert(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, initializerMethod)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 639fc26404..2fd557d947 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -298,7 +298,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } // TODO: Add a StreamSDSL storage class? - context.Add(new OpVariableSDSL(pointerType, variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + builder.Insert(new OpVariableSDSL(pointerType, variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable, Name); } } @@ -326,7 +326,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var type = new PointerType(member.Type, storageClass); var typeId = context.GetOrRegister(type); - context.FluentAdd(new OpVariable(typeId, context.Bound++, storageClass, null), out var variable); + var variable = builder.Insert(new OpVariable(typeId, context.Bound++, storageClass, null)); context.AddName(variable.ResultId, member.Name); DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); From 6949bbb9e2925cc207e10ce1a54f700349bd38e0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 16 Dec 2025 17:44:49 +0900 Subject: [PATCH 0602/1182] Instructions: added ctor from OpData --- .../SPVGenerator.Instructions.cs | 72 +++++++++++++++---- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index fa81db07a8..fba67067d6 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -151,11 +151,22 @@ static string ToSpreadOperator(OperandData operand) static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{"); + .AppendLine("{") + .AppendLine("InitializeProperties(index.Data);") + .AppendLine("DataIndex = index;") + .AppendLine("}"); + + body2.AppendLine($"public {instruction.OpName}(OpData data)") + .AppendLine("{") + .AppendLine("InitializeProperties(data);") + .AppendLine("}"); + + body2.AppendLine($"private void InitializeProperties(OpData data)") + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { - body2.AppendLine("foreach (var o in index.Data)") + body2.AppendLine("foreach (var o in data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -254,7 +265,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("DataIndex = index;").AppendLine("}"); + body2.AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction @@ -292,13 +303,25 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{"); + .AppendLine("{") + .AppendLine("InitializeProperties(index.Data);") + .AppendLine("DataIndex = index;") + .AppendLine("}"); + + body2.AppendLine($"public {instruction.OpName}(OpData data)") + .AppendLine("{") + .AppendLine("InitializeProperties(data);") + .AppendLine("}"); + + body2.AppendLine($"private void InitializeProperties(OpData data)") + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { @@ -314,7 +337,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i operands.Add(new() { Name = "additionalInteger2", Kind = "LiteralInteger", Quantifier = "?" }); } - body2.AppendLine("foreach (var o in index.Data)") + body2.AppendLine("foreach (var o in data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -388,7 +411,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("DataIndex = index;").AppendLine("}"); + body2.AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction @@ -420,6 +443,7 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } @@ -429,11 +453,22 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{"); + .AppendLine("{") + .AppendLine("InitializeProperties(index.Data);") + .AppendLine("DataIndex = index;") + .AppendLine("}"); + + body2.AppendLine($"public {instruction.OpName}(OpData data)") + .AppendLine("{") + .AppendLine("InitializeProperties(data);") + .AppendLine("}"); + + body2.AppendLine($"private void InitializeProperties(OpData data)") + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) { var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); - body2.AppendLine("foreach (var o in index.Data)") + body2.AppendLine("foreach (var o in data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -503,7 +538,7 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, .AppendLine("}"); } - body2.AppendLine("DataIndex = index;").AppendLine("}"); + body2.AppendLine("}"); builder.AppendLine($@" public struct {instruction.OpName} : IMemoryInstruction {{ @@ -534,6 +569,7 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); @@ -542,11 +578,22 @@ private set static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{"); + .AppendLine("{") + .AppendLine("InitializeProperties(index.Data);") + .AppendLine("DataIndex = index;") + .AppendLine("}"); + + body2.AppendLine($"public {instruction.OpName}(OpData data)") + .AppendLine("{") + .AppendLine("InitializeProperties(data);") + .AppendLine("}"); + + body2.AppendLine($"private void InitializeProperties(OpData data)") + .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) { - body2.AppendLine("foreach (var o in index.Data)") + body2.AppendLine("foreach (var o in data)") .AppendLine("{"); body3.Append($"public {instruction.OpName}(") @@ -622,7 +669,7 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i } else body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("DataIndex = index;").AppendLine("}"); + body2.AppendLine("}"); builder.AppendLine($@" // {string.Join(", ", instruction.Operands?.AsList().Select(x => $"{x.Name}:{x.Kind}"))} @@ -656,6 +703,7 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } From db2b114bced8806ce4c064ecafdace1486f2b380 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 17 Dec 2025 12:31:52 +0900 Subject: [PATCH 0603/1182] RemapIds: handle arrays --- .../Spirv/Building/Builder.Class.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 7522c3caf4..1b6a452429 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -476,18 +476,30 @@ public static void RemapIds(Dictionary idRemapping, OpData i) || op.Kind == OperandKind.IdResult || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && idRemapping.TryGetValue(op.Words[0], out var to1)) + || op.Kind == OperandKind.PairIdRefIdRef)) + { + foreach (ref var word in op.Words) + { + if (idRemapping.TryGetValue(word, out var to1)) + word = to1; + } + } + + if ((op.Kind == OperandKind.PairIdRefLiteralInteger) + && idRemapping.TryGetValue(op.Words[0], out var to2)) { - op.Words[0] = to1; + if (op.Quantifier != OperandQuantifier.One) + throw new NotImplementedException(); + op.Words[0] = to2; } if ((op.Kind == OperandKind.PairLiteralIntegerIdRef || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to2)) + && idRemapping.TryGetValue(op.Words[1], out var to3)) { - op.Words[1] = to2; + if (op.Quantifier != OperandQuantifier.One) + throw new NotImplementedException(); + op.Words[1] = to3; } } } From 710e23c6b3d59b7f0ea03c8da05a21d3ca5c25f5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 15 Dec 2025 18:59:25 +0900 Subject: [PATCH 0604/1182] Rearranged code so that we add all types in context during ShaderMixer --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 4 +- .../SDSL/ShaderMixer.MixinNode.cs | 4 - .../SDSL/ShaderMixer.ShaderInfo.cs | 127 ++--- .../SDSL/ShaderMixer.cs | 508 ++++++++++-------- .../Buffers/NewSpirvBuffer.cs | 14 +- .../Information/InstructionInfo.Order.cs | 8 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- .../Parsing/SDSL/AST/ShaderElements.cs | 8 - .../Spirv/Building/Builder.Class.cs | 19 +- src/Stride.Shaders/Spirv/Building/Context.cs | 14 +- .../Spirv/Processing/StreamAnalyzer.cs | 172 +++--- .../Spirv/Processing/TypeDuplicatesRemover.cs | 85 ++- 12 files changed, 509 insertions(+), 456 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 2794277439..0a3069b2fe 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -45,7 +45,7 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May var merged = compiler.ToBuffer(); #if DEBUG - var dis = Spv.Dis(merged); + var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif lastBuffer = merged; @@ -64,7 +64,7 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May var merged = compiler.ToBuffer(); #if DEBUG - var dis = Spv.Dis(merged); + var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif lastBuffer = merged; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index afec9c2144..34e50db222 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -43,10 +43,6 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary Compositions { get; } = new(); public Dictionary CompositionArrays { get; } = new(); - - public Dictionary ExternalShaders { get; } = new(); - public Dictionary ExternalFunctions { get; } = new(); - public Dictionary ExternalVariables { get; } = new(); } class MethodGroup diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index a6afb495c6..afbafc792a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Core; +using Silk.NET.SPIRV.Cross; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; @@ -32,7 +33,6 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public int StartInstruction { get; internal set; } = startInstruction; public int EndInstruction { get; internal set; } = endInstruction; - public Dictionary Names { get; } = new(); public Dictionary Functions { get; } = new(); public Dictionary Variables { get; } = new(); @@ -50,28 +50,33 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } - private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer context, int contextStart, int contextEnd, NewSpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) { - ShaderClass.ProcessNameAndTypes(temp, shaderStart, shaderEnd, out var names, out var types); var removedIds = new HashSet(); - for (var index = shaderStart; index < shaderEnd; index++) + for (var index = contextStart; index < contextEnd; index++) { - var i = temp[index]; + var i = context[index]; - if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) + if (i.Data.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) { - shaderInfo.Names.Add(nameInstruction.Target, nameInstruction.Name); + var structName = globalContext.Names[typeStruct]; + shaderInfo!.StructTypes.Add(structName, typeStruct.ResultId); } - else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) + } + for (var index = shaderStart; index < shaderEnd; index++) + { + var i = buffer[index]; + + if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - var functionName = shaderInfo.Names[function.ResultId]; - var functionType = (FunctionType)types[function.FunctionType]; + var functionName = globalContext.Names[function.ResultId]; + var functionType = (FunctionType)globalContext.Types[function.FunctionType]; shaderInfo!.Functions.Add(functionName, (function.ResultId, functionType)); } else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { - var variableName = shaderInfo.Names[variable.ResultId]; - var variableType = types[variable.ResultType]; + var variableName = globalContext.Names[variable.ResultId]; + var variableType = globalContext.Types[variable.ResultType]; shaderInfo!.Variables.Add(variableName, (variable.ResultId, variableType)); // Remove SPIR-V variables to other shaders (already stored in ShaderInfo and not valid SPIR-V) @@ -81,46 +86,12 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader removedIds.Add(variable.ResultId); } } - // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) - else if (i.Data.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) - { - var pointedType = types[typePointer.Type]; - if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) - { - SetOpNop(i.Data.Memory.Span); - removedIds.Add(typePointer.ResultId); - } - } - // Also remove arrays of shaders (used in composition arrays) - else if (i.Data.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) - { - var innerType = types[typeArray.ElementType]; - if (innerType is ShaderSymbol) - { - SetOpNop(i.Data.Memory.Span); - removedIds.Add(typeArray.ResultId); - } - } - else if (i.Data.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) - { - var innerType = types[typeRuntimeArray.ElementType]; - if (innerType is ShaderSymbol) - { - SetOpNop(i.Data.Memory.Span); - removedIds.Add(typeRuntimeArray.ResultId); - } - } - else if (i.Data.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) - { - var structName = shaderInfo.Names[typeStruct]; - shaderInfo!.StructTypes.Add(structName, typeStruct.ResultId); - } } // Second pass to remove OpName - for (var index = shaderStart; index < shaderEnd; index++) + for (var index = contextStart; index < contextEnd; index++) { - var i = temp[index]; + var i = context[index]; if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) { @@ -130,52 +101,36 @@ private void PopulateShaderInfo(NewSpirvBuffer temp, int shaderStart, int shader } } - private void BuildImportInfo(NewSpirvBuffer temp, int shaderStart, int shaderEnd, ShaderClassInstantiation classSource, ShaderInfo shaderInfo, MixinNode mixinNode) + private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, OpData i, NewSpirvBuffer contextBuffer) { - var inheritedShaders = new HashSet(); - for (var index = shaderStart; index < temp.Count; index++) + if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - var i = temp[index]; - if (i.Data.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } mixinInherit) - { - inheritedShaders.Add(mixinInherit.Shader); - SetOpNop(i.Data.Memory.Span); - } - } - - for (var index = shaderStart; index < temp.Count; index++) - { - var i = temp[index]; - - if (i.Data.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups + var shaderName = importShader.ShaderName; + if (importShader.Values.Elements.Length > 0) { - // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups - var shaderName = importShader.ShaderName; - if (importShader.Values.Elements.Length > 0) + var genericArguments = new object[importShader.Values.Elements.Length]; + for (int j = 0; j < genericArguments.Length; j++) { - var genericArguments = new object[importShader.Values.Elements.Length]; - for (int j = 0; j < genericArguments.Length; j++) - { - genericArguments[j] = SpirvBuilder.GetConstantValue(importShader.Values.Elements.Span[j], temp); - } - shaderName += $"<{string.Join(",", genericArguments)}>"; + genericArguments[j] = SpirvBuilder.GetConstantValue(importShader.Values.Elements.Span[j], contextBuffer); } - - mixinNode.ExternalShaders.Add(importShader.ResultId, shaderName); + shaderName += $"<{string.Join(",", genericArguments)}>"; } - else if (i.Data.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + + globalContext.ExternalShaders.Add(importShader.ResultId, shaderName); + } + else if (i.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + { + if (globalContext.ExternalShaders.ContainsKey(importFunction.Shader)) { - if (mixinNode.ExternalShaders.ContainsKey(importFunction.Shader)) - { - mixinNode.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName)); - } + globalContext.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName)); } - else if (i.Data.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + } + else if (i.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + { + if (globalContext.ExternalShaders.ContainsKey(importVariable.Shader)) { - if (mixinNode.ExternalShaders.ContainsKey(importVariable.Shader)) - { - mixinNode.ExternalVariables.Add(importVariable.ResultId, (importVariable.Shader, importVariable.VariableName)); - } + globalContext.ExternalVariables.Add(importVariable.ResultId, (importVariable.Shader, importVariable.VariableName)); } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index eeb6ed342a..9b2ae4ba8c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,7 +1,9 @@ using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; +using Silk.NET.Direct3D.Compilers; using Silk.NET.SPIRV.Cross; using Stride.Core.Extensions; +using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; @@ -46,15 +48,15 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); new StreamAnalyzer().Process(table, temp, context); // Merge cbuffers and rgroups // TODO: remove unused cbuffers (before merging them) - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); MergeCBuffers(globalContext, context, temp); - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); ComputeCBufferOffsets(globalContext, context, temp); // Process reflection @@ -63,7 +65,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect foreach (var inst in context) temp.Add(inst.Data); - CleanupUnnecessaryInstructions(temp); + CleanupUnnecessaryInstructions(globalContext, temp); temp.Sort(); @@ -135,7 +137,7 @@ string GetCBufferLogicalGroup(string cbufferName) var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); - foreach (var i in buffer) + foreach (var i in context) { if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) { @@ -222,7 +224,11 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); - var mergedCbufferPtrStructId = context.GetOrRegister(new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform)); + var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); + var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); + + globalContext.Types.Add(mergedCbufferStructId, mergedCbufferStruct); + globalContext.Types.Add(mergedCbufferPtrStructId, mergedCbufferPtrStruct); ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); @@ -236,7 +242,7 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s // According to spec, this must be a OpConstant (and we only create them with int) var indexes = accessChain.Values.Elements.Span; var constantId = indexes[0]; - var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, buffer); + var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, context.GetBuffer()); indexes[0] = context.CompileConstant(index).Id; // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) @@ -383,20 +389,17 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo // Scan LinkSDSL and LogicalGroupSDSL decorations Dictionary<(int StructType, int Member), string> links = new(); Dictionary<(int StructType, int Member), string> logicalGroups = new(); - foreach (var temp in new[] { context.GetBuffer(), buffer }) + foreach (var i in context) { - foreach (var i in temp) + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); - } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) - { - using var n = new LiteralValue(m2.Span); - logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); - } + using var n = new LiteralValue(m.Span); + links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); + } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) + { + using var n = new LiteralValue(m2.Span); + logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); } } @@ -452,6 +455,10 @@ class MixinGlobalContext public Dictionary Types { get; } = []; public EffectReflection Reflection { get; } = new(); + + public Dictionary ExternalShaders { get; } = new(); + public Dictionary ExternalFunctions { get; } = new(); + public Dictionary ExternalVariables { get; } = new(); } class MixinNodeContext @@ -473,20 +480,12 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, buffer.Add(new OpSDSLEffect(currentCompositionPath)); var mixinNode = new MixinNode(stage, currentCompositionPath); - - // Step: expand "for" - // TODO + var contextStart = context.GetBuffer().Count; // Merge all classes from mixinSource.Mixins in main buffer - ProcessMixinClasses(context, buffer, mixinSource, mixinNode); - - // Import struct types - ImportStructTypes(globalContext, buffer, mixinNode); - - new TypeDuplicateRemover().Apply(buffer); + ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); - // Build names and types mappings - ShaderClass.ProcessNameAndTypes(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, globalContext.Names, globalContext.Types); + Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), buffer), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); @@ -529,181 +528,262 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, return mixinNode; } - private void ProcessMixinClasses(SpirvContext context, NewSpirvBuffer temp, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) + private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) + { + mixinNode.StartInstruction = buffer.Count; + foreach (var shaderClass in mixinSource.Mixins) + { + var contextStart = context.GetBuffer().Count; + + var shaderInfo = MergeClassInBuffers(globalContext, context, buffer, mixinNode, shaderClass); + + mixinNode.ShadersByName.Add(shaderClass.ToClassName(), shaderInfo); + mixinNode.Shaders.Add(shaderInfo); + + // Note: we process name, types and struct right away, as they might be needed by the next Shader + ShaderClass.ProcessNameAndTypes(context.GetBuffer(), contextStart, context.GetBuffer().Count, globalContext.Names, globalContext.Types); + PopulateShaderInfo(globalContext, context.GetBuffer(), contextStart, context.GetBuffer().Count, buffer, shaderInfo.StartInstruction, shaderInfo.EndInstruction, shaderInfo, mixinNode); + } + + mixinNode.EndInstruction = buffer.Count; + } + + private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass) { var isRootMixin = mixinNode.Stage == null; - var stage = mixinNode.Stage; + if (shaderClass.ImportStageOnly) + { + if (!isRootMixin) + throw new InvalidOperationException("importing stage-only methods/variables is only possible at the root mixin"); + } + + var shader = shaderClass.Buffer; var offset = context.Bound; - var nextOffset = 0; - var shaders = mixinNode.Shaders; + // Remember when we started to add instructions in both context and main buffer + var shaderStart = buffer.Count; + var contextStart = context.GetBuffer().Count; + var names = new Dictionary(); - mixinNode.StartInstruction = temp.Count; - foreach (var shaderClass in mixinSource.Mixins) + var forbiddenIds = new HashSet(); + var remapIds = new Dictionary(); + var removedIds = new HashSet(); + + bool isContext = true; + + bool ProcessStageMember(int memberId, bool isStage) { - if (shaderClass.ImportStageOnly) + var include = isStage switch { - if (!isRootMixin) - throw new InvalidOperationException("importing stage-only methods/variables is only possible at the root mixin"); - } + // Import stage members only if at root level + true => isRootMixin, + // Import non-stage members only if allowed, i.e. not a "stage-only inherit" + // ("stage-only inherit" only happen when a class with stage members is inherited in a composition, and the stage-only version is added to the root mixin) + false => !shaderClass.ImportStageOnly, + }; - var shader = shaderClass.Buffer; - offset += nextOffset; - nextOffset = 0; - shader.Header = shader.Header with { Bound = shader.Header.Bound + offset }; + // If a stage member is skipped in a composition mixin, we want to remap to the version in the root mixin + if (isStage && !isRootMixin) + { + var stageShader = mixinNode.Stage.ShadersByName[shaderClass.ToClassName()]; + var memberName = names[memberId]; + var stageMember = stageShader.FindMember(memberName); + remapIds.Add(offset + memberId, stageMember.Id); + removedIds.Add(stageMember.Id); + } + // Otherwise, if not included, it means we need to forbid this IDs (which could only happen if referencing non-stage member from a stage method) + else if (!include) + { + forbiddenIds.Add(offset + memberId); + } - var shaderStart = temp.Count; + return include; + } - bool skipFunction = false; + var typeDuplicateInserter = new TypeDuplicateHelper(context.GetBuffer()); - var forbiddenIds = new HashSet(); - var remapIds = new Dictionary(); - var names = new Dictionary(); - var removedIds = new HashSet(); + // Copy instructions to main buffer + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; - bool ProcessStageMember(int memberId, bool isStage) + // Do we need to skip variable/functions? (depending on stage/non-stage) { - var include = isStage switch + var include = true; + if (i.Op == Op.OpName) { - // Import stage members only if at root level - true => isRootMixin, - // Import non-stage members only if allowed, i.e. not a "stage-only inherit" - // ("stage-only inherit" only happen when a class with stage members is inherited in a composition, and the stage-only version is added to the root mixin) - false => !shaderClass.ImportStageOnly, - }; - - // If a stage member is skipped in a composition mixin, we want to remap to the version in the root mixin - if (isStage && !isRootMixin) + OpName nameInstruction = i; + names.Add(nameInstruction.Target, nameInstruction.Name); + } + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { - var stageShader = stage.ShadersByName[shaderClass.ToClassName()]; - var memberName = names[memberId]; - var stageMember = stageShader.FindMember(memberName); - remapIds.Add(offset + memberId, stageMember.Id); + var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + include = ProcessStageMember(function.ResultId, isStage); } - // Otherwise, if not included, it means we need to forbid this IDs (which could only happen if referencing non-stage member from a stage method) - else if (!include) + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) { - forbiddenIds.Add(offset + memberId); + var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; + include = ProcessStageMember(variableInstruction.ResultId, isStage); } - return include; - } - - // Copy instructions to main buffer - for (var index = 0; index < shader.Count; index++) - { - var i = shader[index]; - - // Do we need to skip variable/functions? (depending on stage/non-stage) + if (!include) { - var include = true; - if (i.Op == Op.OpName) - { - OpName nameInstruction = i; - names.Add(nameInstruction.Target, nameInstruction.Name); - } - if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) - { - var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - include = ProcessStageMember(function.ResultId, isStage); - } - if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) - { - var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; - include = ProcessStageMember(variableInstruction.ResultId, isStage); - } + // We store removed IDs for further OpName removals + if (i.Data.IdResult is int id) + removedIds.Add(offset + id); - if (!include) + // Special case for function: skip until function end + // (for other cases such as variable, skipping only current instruction is enough) + if (i.Op == Op.OpFunction) { - // We store removed IDs for further OpName removals - if (i.Data.IdResult is int id) - removedIds.Add(offset + id); - - // Special case for function: skip until function end - // (for other cases such as variable, skipping only current instruction is enough) - if (i.Op == Op.OpFunction) + // Skip until end of function + while (shader[++index].Op != Op.OpFunctionEnd) { - // Skip until end of function - while (shader[++index].Op != Op.OpFunctionEnd) - { - // We store removed IDs for further OpName removals - if (shader[index].Data.IdResult is int id2) - removedIds.Add(offset + id2); - } + // We store removed IDs for further OpName removals + if (shader[index].Data.IdResult is int id2) + removedIds.Add(offset + id2); } - - // Go to next instruction - continue; } + + // Go to next instruction + continue; } + } - var i2 = new OpData(i.Data.Memory.Span); - temp.Add(i2); + var i2 = new OpData(i.Data.Memory.Span); - if (i.Data.IdResult != null && i.Data.IdResult.Value > nextOffset) - nextOffset = i.Data.IdResult.Value; + if (offset > 0) + OffsetIds(i2, offset); - if (offset > 0) - OffsetIds(i2, offset); + if (i2.IdResult != null) + context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); - if (SpirvBuilder.ContainIds(forbiddenIds, i2)) - throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); + if (SpirvBuilder.ContainIds(forbiddenIds, i2)) + throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); - SpirvBuilder.RemapIds(remapIds, i2); + SpirvBuilder.RemapIds(remapIds, i2); + + // Detect when we switch from context to main buffer + if (i2.Op == Op.OpSDSLShader) + { + isContext = false; } - for (var index = shaderStart; index < temp.Count; index++) + // Specific type instructions in context gets deduplicated before adding + bool addToContext = false; + if ( + // Types + i2.Op == Op.OpTypeVoid + || i2.Op == Op.OpTypeInt + || i2.Op == Op.OpTypeFloat + || i2.Op == Op.OpTypeBool + || i2.Op == Op.OpTypeVector + || i2.Op == Op.OpTypeMatrix + || i2.Op == Op.OpTypeArray + || i2.Op == Op.OpTypeRuntimeArray + || i2.Op == Op.OpTypeStruct + || i2.Op == Op.OpTypePointer + || i2.Op == Op.OpTypeFunction + || i2.Op == Op.OpTypeGenericLinkSDSL + || i2.Op == Op.OpSDSLImportShader + || i2.Op == Op.OpSDSLImportVariable + || i2.Op == Op.OpSDSLImportFunction + || i2.Op == Op.OpSDSLImportStruct) { - // Second pass: remove OpName/OpMember referencing to removed IDs - var i = temp[index]; - if (i.Op == Op.OpName && (OpName)i is { } name) + // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) + if (i2.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)i2 is { } importStruct) { - if (removedIds.Contains(name.Target)) - SetOpNop(i.Data.Memory.Span); + var shaderName = globalContext.ExternalShaders[importStruct.Shader]; + var shader2 = mixinNode.ShadersByName[shaderName]; + var structId = shader2.StructTypes[importStruct.StructName]; + remapIds.Add(importStruct.ResultId, structId); + removedIds.Add(structId); } - else if (i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) + // Check if type already exists in context (deduplicate them) + else if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) { - // Structure ID is always stored in first operand - var target = i.Data.Memory.Span[1]; - if (removedIds.Contains(target)) - SetOpNop(i.Data.Memory.Span); + if (i2.IdResult is int id) + { + remapIds.Add(id, existingInstruction.IdResult.Value); + removedIds.Add(existingInstruction.IdResult.Value); + } + } + else + { + addToContext = true; } } + // Does this belong in context or buffer? + else if (isContext) + { + addToContext = true; + } + else + { + buffer.Add(i2); + } - // Link attribute: postfix with composition path - if (mixinNode.CompositionPath != null) + // Process OpSDSLImport + ProcessImportInfo(globalContext, mixinNode, i2, context.GetBuffer()); + + if (addToContext) { - foreach (var i in temp) + // OpName and such: check if associated instruction has not been removed + if (i2.Op == Op.OpName || i2.Op == Op.OpDecorate || i2.Op == Op.OpDecorateString + || i2.Op == Op.OpMemberName || i2.Op == Op.OpMemberDecorate || i2.Op == Op.OpMemberDecorateString) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - var n = new LiteralValue(m.Span); - n.Value = $"{n.Value}.{mixinNode.CompositionPath}"; - n.Dispose(); - } + // Target/Structure ID is always stored in first operand for all those instructions + var target = i2.Memory.Span[1]; + if (removedIds.Contains(target)) + addToContext = false; } - } - - shaderClass.Start = shaderStart; - shaderClass.End = temp.Count; - shaderClass.OffsetId = offset; - // Build ShaderInfo - var shaderInfo = new ShaderInfo(shaders.Count, shaderClass.ClassName, shaderStart, temp.Count); - shaderInfo.CompositionPath = mixinNode.CompositionPath; - if (mixinNode.Stage != null && mixinNode.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) - shaderInfo.Stage = stageShaderInfo; + if (addToContext) + context.GetBuffer().Add(i2); + } + } - PopulateShaderInfo(temp, shaderStart, temp.Count, shaderInfo, mixinNode); + // Reprocess OpName/OpDecorate (they are defined before the OpType that was remapped, so we need to reprocess them) + for (int index = contextStart; index < context.GetBuffer().Count; ++index) + { + var i = context.GetBuffer()[index]; + + if (i.Op == Op.OpName + || i.Op == Op.OpMemberName + || i.Op == Op.OpDecorate + || i.Op == Op.OpDecorateString + || i.Op == Op.OpMemberDecorate + || i.Op == Op.OpMemberDecorateString) + { + SpirvBuilder.RemapIds(remapIds, i.Data); - mixinNode.ShadersByName.Add(shaderClass.ToClassName(), shaderInfo); - shaders.Add(shaderInfo); + var target = i.Data.Memory.Span[1]; + if (removedIds.Contains(target)) + SetOpNop(i.Data.Memory.Span); + } + } - BuildImportInfo(temp, shaderStart, temp.Count, shaderClass, shaderInfo, mixinNode); + // Link attribute: postfix with composition path + if (mixinNode.CompositionPath != null) + { + foreach (var i in buffer) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + var n = new LiteralValue(m.Span); + n.Value = $"{n.Value}.{mixinNode.CompositionPath}"; + n.Dispose(); + } + } } - mixinNode.EndInstruction = temp.Count; - context.Bound = offset + nextOffset + 1; + // Build ShaderInfo + var shaderInfo = new ShaderInfo(mixinNode.Shaders.Count, shaderClass.ClassName, shaderStart, buffer.Count); + shaderInfo.CompositionPath = mixinNode.CompositionPath; + if (mixinNode.Stage != null && mixinNode.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) + shaderInfo.Stage = stageShaderInfo; + + return shaderInfo; } private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, MixinNode mixinNode) @@ -762,9 +842,9 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // If OpSDSLFunctionInfo.Parent is coming from a OpSDSLImportFunction, find the real ID if (functionInfo.Parent != 0) { - if (mixinNode.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) + if (globalContext.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) { - var shaderName = mixinNode.ExternalShaders[parentFunctionInfo.ShaderId]; + var shaderName = globalContext.ExternalShaders[parentFunctionInfo.ShaderId]; functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name].Id; } } @@ -802,40 +882,6 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } } - private void ImportStructTypes(MixinGlobalContext globalContext, NewSpirvBuffer buffer, MixinNode mixinNode) - { - var idRemapping = new Dictionary(); - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = buffer[index]; - - if (i.Data.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)i is { } importStruct) - { - var shaderName = mixinNode.ExternalShaders[importStruct.Shader]; - var shader = mixinNode.ShadersByName[shaderName]; - var structId = shader.StructTypes[importStruct.StructName]; - idRemapping.Add(importStruct.ResultId, structId); - SetOpNop(i.Data.Memory.Span); - } - } - - // Remove associated OpName - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = buffer[index]; - - if (i.Data.Op == Op.OpName && (OpName)i is { } name) - { - if (idRemapping.ContainsKey(name.Target)) - { - SetOpNop(i.Data.Memory.Span); - } - } - } - - SpirvBuilder.RemapIds(buffer, mixinNode.StartInstruction, mixinNode.EndInstruction, idRemapping); - } - private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) { // Find matching ForeachEnd (taking into account nested foreach) @@ -983,9 +1029,9 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte throw new InvalidOperationException(); } - if (mixinNode.ExternalVariables.TryGetValue(memberAccess.Member, out var variable)) + if (globalContext.ExternalVariables.TryGetValue(memberAccess.Member, out var variable)) { - var shaderName = mixinNode.ExternalShaders[variable.ShaderId]; + var shaderName = globalContext.ExternalShaders[variable.ShaderId]; var shaderInfo = instanceMixinGroup.ShadersByName[shaderName]; if (!shaderInfo.Variables.TryGetValue(variable.Name, out var variableInfo)) @@ -1008,7 +1054,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte { // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL var functionId = memberAccess.Member; - if (mixinNode.ExternalFunctions.TryGetValue(memberAccess.Member, out var function)) + if (globalContext.ExternalFunctions.TryGetValue(memberAccess.Member, out var function)) // Process member call (composition) functionId = instanceMixinGroup.MethodGroupsByName[function.Name]; @@ -1258,37 +1304,61 @@ public static void OffsetIds(OpData inst, int offset) } } - private static void CleanupUnnecessaryInstructions(NewSpirvBuffer temp) + private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, NewSpirvBuffer temp) { - for (int i = 0; i < temp.Count; i++) + for (int index = 0; index < temp.Count; index++) { + var i = temp[index]; + // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) // Note: we ignore initializer as we store a method which is already processed during StreamAnalyzer (as opposed to a const for OpVariable) - if (temp[i].Op == Op.OpVariableSDSL && (OpVariableSDSL)temp[i] is { } variable) - temp.Replace(i, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) + temp.Replace(index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); // Remove Nop - if (temp[i].Op == Op.OpNop) - temp.RemoveAt(i--); + if (i.Op == Op.OpNop) + temp.RemoveAt(index--); // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) - else if (temp[i].Op == Op.OpSDSLShader - || temp[i].Op == Op.OpSDSLShaderEnd - || temp[i].Op == Op.OpSDSLEffect - || temp[i].Op == Op.OpSDSLEffectEnd - || temp[i].Op == Op.OpConstantStringSDSL - || temp[i].Op == Op.OpTypeGenericLinkSDSL - || temp[i].Op == Op.OpSDSLImportShader - || temp[i].Op == Op.OpSDSLImportFunction - || temp[i].Op == Op.OpSDSLImportVariable) - temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpDecorate && ((OpDecorate)temp[i]).Decoration.Value is Decoration.LinkIdSDSL) - temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpMemberDecorate && ((OpMemberDecorate)temp[i]).Decoration.Value == Decoration.LinkIdSDSL) - temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpDecorateString && ((OpDecorateString)temp[i]).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) - temp.RemoveAt(i--); - else if (temp[i].Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)temp[i]).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) - temp.RemoveAt(i--); + else if (i.Op == Op.OpSDSLShader + || i.Op == Op.OpSDSLShaderEnd + || i.Op == Op.OpSDSLEffect + || i.Op == Op.OpSDSLEffectEnd + || i.Op == Op.OpSDSLMixinInherit + || i.Op == Op.OpConstantStringSDSL + || i.Op == Op.OpTypeGenericLinkSDSL + || i.Op == Op.OpSDSLImportShader + || i.Op == Op.OpSDSLImportFunction + || i.Op == Op.OpSDSLImportVariable) + temp.RemoveAt(index--); + else if (i.Op == Op.OpDecorate && ((OpDecorate)i).Decoration.Value is Decoration.LinkIdSDSL) + temp.RemoveAt(index--); + else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i).Decoration.Value == Decoration.LinkIdSDSL) + temp.RemoveAt(index--); + else if (i.Op == Op.OpDecorateString && ((OpDecorateString)i).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + temp.RemoveAt(index--); + else if (i.Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)i).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + temp.RemoveAt(index--); + + // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) + else if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) + { + var pointedType = globalContext.Types[typePointer.Type]; + if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) + temp.RemoveAt(index--); + } + // Also remove arrays of shaders (used in composition arrays) + else if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) + { + var innerType = globalContext.Types[typeArray.ElementType]; + if (innerType is ShaderSymbol) + temp.RemoveAt(index--); + } + else if (i.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) + { + var innerType = globalContext.Types[typeRuntimeArray.ElementType]; + if (innerType is ShaderSymbol) + temp.RemoveAt(index--); + } } } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 8898d86c39..533b20e180 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -217,10 +217,11 @@ void UpdateBound(OpData data) Header = Header with { Bound = index + 1 }; } - public void Add(OpData data) + public OpDataIndex Add(OpData data) { Instructions.Add(data); UpdateBound(data); + return new OpDataIndex(Instructions.Count - 1, this); } public OpData Add(in T instruction) where T : struct, IMemoryInstruction @@ -327,6 +328,17 @@ public void InsertRange(int index, ReadOnlySpan source) UpdateBound(Instructions[i]); } + public OpData Replace(int index, OpData i) + { + if (index < 0 || index >= Instructions.Count) + throw new InvalidOperationException(); + + Instructions[index].Dispose(); + Instructions[index] = i; + UpdateBound(Instructions[index]); + return Instructions[index]; + } + public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction { if (index < 0 || index >= Instructions.Count) diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 015d235f49..98a35fde6b 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -28,15 +28,12 @@ void InitOrder() Op.OpSDSLShader, Op.OpSDSLEffect, Op.OpCapability, - Op.OpSDSLMixinInherit, Op.OpSDSLCompose ]; foreach (var e in initSDSL) OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpSDSLImport"))) - OrderGroup[(e, null)] = group; OrderGroup[(Op.OpExtension, null)] = group; group++; @@ -69,9 +66,12 @@ void InitOrder() OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x == Op.OpSDSLGenericParameter)) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x.ToString().StartsWith("OpSDSLImport") || x == Op.OpSDSLGenericParameter)) OrderGroup[(e, null)] = group; + group++; + OrderGroup[(Op.OpSDSLMixinInherit, null)] = group; + group++; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) OrderGroup[(Op.OpVariable, e)] = group; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index c49cda3333..f5888f5eac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -309,7 +309,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - context.PutShaderName(Name); + builder.Insert(new OpSDSLShader(name)); table.Push(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 2fd557d947..5df6ab57db 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -279,14 +279,6 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, AccessChain: index); table.CurrentFrame.Add(member.Name, symbol); - if (member.Type is MatrixType) - { - if (member.TypeModifier != TypeModifier.ColumnMajor) - context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); - else if (member.TypeModifier != TypeModifier.RowMajor) - context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); - } - if (member.Attributes != null && member.Attributes.Count > 0) { var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 1b6a452429..f3d14e13a6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -34,11 +34,6 @@ public record class ShaderClassInstantiation(string ClassName, int[] GenericArgu public LoadedShaderSymbol Symbol { get; set; } - public int Start { get; set; } - public int End { get; set; } - - public int OffsetId { get; set; } - public string ToClassName() { if ((GenericArguments == null || GenericArguments.Length == 0) && !ImportStageOnly) @@ -56,7 +51,7 @@ public string ToClassName() return result.ToString(); } - public override string ToString() => $"{(ImportStageOnly ? "stage " : string.Empty)}{ToClassName()} Symbol: {Symbol} Buffer: {(Buffer != null ? "set" : "empty")} Start: {Start} End: {End} OffsetId: {OffsetId}"; + public override string ToString() => $"{(ImportStageOnly ? "stage " : string.Empty)}{ToClassName()} Symbol: {Symbol} Buffer: {(Buffer != null ? "set" : "empty")}"; public virtual bool Equals(ShaderClassInstantiation? shaderClassSource) { @@ -310,7 +305,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha } // Map classSource.GenericArguments ids to OpSDSLGenericParameter.ResultId (in the order OpSDSLGenericParameter appears) - Dictionary> targets = new(); + Dictionary> targets = new(); // Collect OpSDSLGenericParameter List generics = new(); @@ -323,7 +318,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha generics.Add(genericParameter.ResultId); if (!targets.TryGetValue(classSource.GenericArguments[genericArgumentIndex], out var genericParametersForThisArgument)) targets.Add(classSource.GenericArguments[genericArgumentIndex], genericParametersForThisArgument = new()); - genericParametersForThisArgument.Add(genericParameter.ResultId); + genericParametersForThisArgument.Add((genericParameter.ResultId, index)); genericArgumentIndex++; SetOpNop(i.Data.Memory.Span); } @@ -356,10 +351,10 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha // import constant in current shader foreach (var parameter in parameters) { - resolvedParameters.Add(parameter, value.ToString()); + resolvedParameters.Add(parameter.ResultId, value.ToString()); var i2 = new OpData(i.Data.Memory.Span); - i2.IdResult = parameter; - shader.Add(i2); + i2.IdResult = parameter.ResultId; + shader.Replace(parameter.Index, i2); } } } @@ -370,7 +365,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha var value = constantString.LiteralString; // This will be used later for resolving LinkType generics foreach (var parameter in parameters) - resolvedParameters.Add(parameter, value); + resolvedParameters.Add(parameter.ResultId, value); } } else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 8ddbaad36c..3fb2fe75b5 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -53,7 +53,6 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ public class SpirvContext { public int Bound { get; set; } = 1; - public string? Name { get; private set; } public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; @@ -61,15 +60,6 @@ public class SpirvContext public int? GLSLSet { get; private set; } - public void PutShaderName(string name) - { - if (Name is null) - { - Name = name; - Buffer.Insert(0, new OpSDSLShader(name)); - } - else throw new NotImplementedException(); - } public void ImportGLSL() { foreach(var i in Buffer) @@ -301,9 +291,9 @@ public int DeclareStructuredType(StructuredType structSymbol) if (member.Type is MatrixType) { if (member.TypeModifier != TypeModifier.ColumnMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.ColMajor, []))); + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Decoration.ColMajor, []))); else if (member.TypeModifier != TypeModifier.RowMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Specification.Decoration.RowMajor, []))); + Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Decoration.RowMajor, []))); } } diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index b4e8372afd..b51b39c6f5 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -117,115 +117,121 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // Build name table SortedList nameTable = []; SortedList semanticTable = []; - foreach (var instruction in buffer) + foreach (var temp in new[] { context.GetBuffer(), buffer }) { - // Names + foreach (var instruction in temp) { - if (instruction.Op == Op.OpName - && ((OpName)instruction) is + // Names + { + if (instruction.Op == Op.OpName + && ((OpName)instruction) is + { + Target: int t, + Name: string n + } + ) { - Target: int t, - Name: string n + nameTable[t] = new(n); } - ) - { - nameTable[t] = new(n); - } - else if (instruction.Op == Op.OpMemberName - && ((OpMemberName)instruction) is + else if (instruction.Op == Op.OpMemberName + && ((OpMemberName)instruction) is + { + Type: int t2, + Member: int m, + Name: string n2 + } + ) { - Type: int t2, - Member: int m, - Name: string n2 + nameTable[t2] = new(n2); } - ) - { - nameTable[t2] = new(n2); } - } - // CBuffer - // Encoded in this format: - // OpDecorate %type_CBuffer1 Block - // %_ptr_Uniform_type_CBuffer1 = OpTypePointer Uniform %type_CBuffer1 - // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform - { - if (instruction.Op == Op.OpDecorate - && ((OpDecorate)instruction) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) - { - blockTypes.Add(bufferType); - } - else if (instruction.Op == Op.OpTypePointer - && ((OpTypePointer)instruction) is { Storageclass: StorageClass.Uniform, ResultId: var pointerType, Type: var bufferType2 } - && blockTypes.Contains(bufferType2)) - { - blockPointerTypes.Add(pointerType, bufferType2); - } - else if (instruction.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } - && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) + // CBuffer + // Encoded in this format: + // OpDecorate %type_CBuffer1 Block + // %_ptr_Uniform_type_CBuffer1 = OpTypePointer Uniform %type_CBuffer1 + // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform { - blockIds.Add(bufferId); + if (instruction.Op == Op.OpDecorate + && ((OpDecorate)instruction) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) + { + blockTypes.Add(bufferType); + } + else if (instruction.Op == Op.OpTypePointer + && ((OpTypePointer)instruction) is { Storageclass: StorageClass.Uniform, ResultId: var pointerType, Type: var bufferType2 } + && blockTypes.Contains(bufferType2)) + { + blockPointerTypes.Add(pointerType, bufferType2); + } + else if (instruction.Op == Op.OpVariableSDSL + && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) + { + blockIds.Add(bufferId); + } } - } - // Semantic - { - if (instruction.Op == Op.OpDecorateString - && ((OpDecorateString)instruction) is - { - Target: int t, - Decoration: + // Semantic + { + if (instruction.Op == Op.OpDecorateString + && ((OpDecorateString)instruction) is { - Value: Decoration.UserSemantic, - Parameters: { } m + Target: int t, + Decoration: + { + Value: Decoration.UserSemantic, + Parameters: { } m + } } + ) + { + using var n = new LiteralValue(m.Span); + semanticTable[t] = n.Value; } - ) - { - using var n = new LiteralValue(m.Span); - semanticTable[t] = n.Value; } } } // Analyze streams - foreach (var instruction in buffer) + foreach (var temp in new[] { context.GetBuffer(), buffer }) { - if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is - { - Storageclass: StorageClass.Private, - ResultId: int - } variable) + foreach (var instruction in temp) { - var name = nameTable.TryGetValue(variable.ResultId, out var nameId) - ? nameId - : $"unnamed_{variable.ResultId}"; - var type = context.ReverseTypes[variable.ResultType]; - semanticTable.TryGetValue(variable.ResultId, out var semantic); - - var stream = (new StreamInfo(semantic, name, type, variable.ResultId) + if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is + { + Storageclass: StorageClass.Private, + ResultId: int + } variable) { - // Does it have an initializer? if yes, mark it as a value written in this stage - Write = variable.MethodInitializer != null, - VariableMethodInitializerId = variable.MethodInitializer, - }, true); + var name = nameTable.TryGetValue(variable.ResultId, out var nameId) + ? nameId + : $"unnamed_{variable.ResultId}"; + var type = context.ReverseTypes[variable.ResultType]; + semanticTable.TryGetValue(variable.ResultId, out var semantic); - streams.Add(variable.ResultId, stream); - } + var stream = (new StreamInfo(semantic, name, type, variable.ResultId) + { + // Does it have an initializer? if yes, mark it as a value written in this stage + Write = variable.MethodInitializer != null, + VariableMethodInitializerId = variable.MethodInitializer, + }, true); - if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is + streams.Add(variable.ResultId, stream); + } + + if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is + { + Storageclass: StorageClass.UniformConstant, + ResultId: int + } resource) { - Storageclass: StorageClass.UniformConstant, - ResultId: int - } resource) - { - var name = nameTable.TryGetValue(resource.ResultId, out var nameId) - ? nameId - : $"unnamed_{resource.ResultId}"; - var type = context.ReverseTypes[resource.ResultType]; + var name = nameTable.TryGetValue(resource.ResultId, out var nameId) + ? nameId + : $"unnamed_{resource.ResultId}"; + var type = context.ReverseTypes[resource.ResultType]; - resources.Add(resource.ResultId); + resources.Add(resource.ResultId); + } } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 69716898fa..9d98872e28 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -18,7 +18,7 @@ namespace Stride.Shaders.Spirv.Processing; /// Remove duplicate simple types. /// Should be applied after the IdRefOffsetter. /// -public struct TypeDuplicateRemover : INanoPass +public struct TypeDuplicateHelper { public int[] FindItemsWithTypes(NewSpirvBuffer buffer, params Span ops) { @@ -51,7 +51,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; } - class OperationComparer(List NameInstructions) : IComparer + class OperationComparer(List NameInstructions, bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -70,13 +70,16 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return comparison; // Special values for searching bounds - if (x.Index == -1 || y.Index == int.MaxValue) - return -1; - if (y.Index == -1 || x.Index == int.MaxValue) - return 1; + if (UseIndices) + { + if (x.Index == -1 || y.Index == int.MaxValue) + return -1; + if (y.Index == -1 || x.Index == int.MaxValue) + return 1; + } // Only for OpName and OpMember - if (x.Op == Op.OpName || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) + if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { // Use TargetOverride if defined, otherwise Memory.Span[1] (where target would be stored) comparison = (x.TargetOverride ?? x.Data.Memory.Span[1]).CompareTo(y.TargetOverride ?? y.Data.Memory.Span[1]); @@ -104,7 +107,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return comparison; } } - else if (x.Op == Op.OpName || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) + else if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { // Use actual op (they were all remapped to same ID in RemapOp() to be grouped by TargetId first) comparison = x.Op.CompareTo(y.Op); @@ -116,7 +119,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return comparison; } - comparison = x.Index.CompareTo(y.Index); + comparison = UseIndices ? x.Index.CompareTo(y.Index) : 0; return comparison; } @@ -149,10 +152,17 @@ public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper } } - public readonly void Apply(NewSpirvBuffer buffer) + private NewSpirvBuffer buffer; + private List instructionsByOp; + private List namesByOp; + private OperationComparer comparerSort; + private OperationComparer comparerInsert; + + public TypeDuplicateHelper(NewSpirvBuffer buffer) { - var instructionsByOp = new List(); - var namesByOp = new List(); + this.buffer = buffer; + instructionsByOp = new(); + namesByOp = new(); foreach (var i in buffer) { switch (i.Op) @@ -167,30 +177,49 @@ public readonly void Apply(NewSpirvBuffer buffer) } } - var comparer = new OperationComparer(namesByOp); + comparerSort = new OperationComparer(namesByOp, true); // Note: since it contains no OpTypeStruct, it should not access OperationComparer.NameInstructions - namesByOp.Sort(comparer); - instructionsByOp.Sort(comparer); + namesByOp.Sort(comparerSort); + instructionsByOp.Sort(comparerSort); + + comparerInsert = new OperationComparer(namesByOp, false); + } + + public bool CheckForDuplicates(OpData data, out OpData foundData) + { + var index = instructionsByOp.BinarySearch(new InstructionSortHelper { Op = data.Op, Index = -1, Data = data }, comparerInsert); + + if (index >= 0) + { + foundData = instructionsByOp[index].Data; + return true; + } + + foundData = data; + return false; + } + public void RemoveDuplicates() + { // Note: We process instruction by types depending on their dependencies // i.e. a OpTypeFloat being unified means a OpTypeVector depending on it might too // Covers OpTypeVoid, OpTypeBool, OpTypeInt, OpTypeFloat at the same time (no interdependencies) - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeVector, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeMatrix, Op.OpTypeMatrix, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVoid, Op.OpTypeFloat, false, comparerSort); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeVector, Op.OpTypeVector, true, comparerSort); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeMatrix, Op.OpTypeMatrix, true, comparerSort); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeArray, Op.OpTypeRuntimeArray, true, comparerSort); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeStruct, Op.OpTypeStruct, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeStruct, Op.OpTypeStruct, true, comparerSort); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparer); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparerSort); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparerSort); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeGenericLinkSDSL, Op.OpTypeGenericLinkSDSL, true, comparer); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeGenericLinkSDSL, Op.OpTypeGenericLinkSDSL, true, comparerSort); // Note: due to RemapOp, this will also cover OpMemberDecorate and OpMemberName - ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparer); + ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparerSort); } private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer) @@ -290,3 +319,11 @@ static void SetOpNop(Span words) words[1..].Clear(); } } + +public struct TypeDuplicateRemover : INanoPass +{ + public void Apply(NewSpirvBuffer buffer) + { + new TypeDuplicateHelper(buffer).RemoveDuplicates(); + } +} From 5162c8a0b64760c5b34377373700db0ddd83e6f7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 17 Dec 2025 15:04:11 +0900 Subject: [PATCH 0605/1182] ShaderMixer: Moved cbuffer code to a separate file --- .../SDSL/ShaderMixer.CBuffers.cs | 382 ++++++++++++++++++ .../SDSL/ShaderMixer.cs | 363 ----------------- 2 files changed, 382 insertions(+), 363 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs new file mode 100644 index 0000000000..6d6ed48cc8 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -0,0 +1,382 @@ +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Core.Extensions; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Compilers.SDSL +{ + partial class ShaderMixer + { + private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + { + // If multiple cbuffer with same name Test, they will be renamed Test.0 Test.1 etc. + string GetCBufferFinalName(string cbufferName) + { + var dotIndex = cbufferName.IndexOf('.'); + if (dotIndex != -1) + return cbufferName.Substring(0, dotIndex); + + return cbufferName; + } + + string GetCBufferLogicalGroup(string cbufferName) + { + var dotIndex = cbufferName.IndexOf('.'); + if (dotIndex != -1) + return cbufferName.Substring(dotIndex + 1); + + return null; + } + + // OpSDSLEffect is emitted for any non-root composition + var compositionNodes = buffer + .Where(x => x.Op == Op.OpSDSLEffect) + .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLEffect)x).EffectName)) + .ToList(); + + var shaders = buffer + .Where(x => x.Op == Op.OpSDSLShader) + .Select(x => (StartIndex: x.Index, ShaderName: ((OpSDSLShader)x).ShaderName)) + .ToList(); + + var cbuffersByNames = buffer + .Where(x => x.Op == Op.OpVariableSDSL) + .Select(x => (Index: x.Index, Variable: (OpVariableSDSL)x)) + // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset + .Select(x => ( + Variable: x.Variable, + CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, + ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, + StructTypePtrId: x.Variable.ResultType, + StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + MemberIndexOffset: 0, + LogicalGroup: GetCBufferLogicalGroup(globalContext.Names[x.Variable.ResultId]))) + // TODO: Check Decoration.Block? + .Where(x => x.StructType != null) + .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); + + var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); + + Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); + foreach (var i in context) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) + { + using var n = new LiteralValue(m.Span); + if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); + } + else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) + { + if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); + } + } + + void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) + { + int mergedMemberIndex = 0; + foreach (ref var cbuffer in cbuffersSpan) + { + var compositionPath = cbuffer.CompositionPath; + + for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) + { + var member = cbuffer.StructType.Members[memberIndex]; + + if (!decorations.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var decorationsForThisMember)) + decorations.Add((context.Types[cbuffer.StructType], memberIndex), decorationsForThisMember = new(new(), new())); + + decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); + + if (!newStructure) + { + // If not a new structure, we restart from 0 and add only what's necessary + // Note: we made sure to query linkValue before + decorationsForThisMember.StringDecorations.Clear(); + decorationsForThisMember.Decorations.Clear(); + } + + // If not specified, add default Link info + if (linkValue == null) + { + var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; + if (!compositionPath.IsNullOrEmpty()) + link = $"{link}.{compositionPath}"; + + decorationsForThisMember.StringDecorations.Add(Decoration.LinkSDSL, link); + } + + // Also transfer LogicalGroup (from name) + if (cbuffer.LogicalGroup != null) + decorationsForThisMember.StringDecorations.Add(Decoration.LogicalGroupSDSL, cbuffer.LogicalGroup); + + foreach (var stringDecoration in decorationsForThisMember.StringDecorations) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); + foreach (var decoration in decorationsForThisMember.Decorations) + context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); + } + } + } + + foreach (var cbuffersEntry in cbuffersByNames) + { + var cbuffers = cbuffersEntry.ToList(); + var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); + + if (cbuffersEntry.Count() == 1) + { + ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); + } + // More than 1 cbuffers with same name + else + { + int offset = 0; + // TODO: Analyze and skip cbuffers parts which are unused + foreach (ref var cbuffer in cbuffersSpan) + { + cbuffer.MemberIndexOffset = offset; + offset += cbuffer.StructType.Members.Count; + } + var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); + var structTypes = cbuffers.Select(x => x.StructType); + + var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); + var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); + var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); + var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); + + globalContext.Types.Add(mergedCbufferStructId, mergedCbufferStruct); + globalContext.Types.Add(mergedCbufferPtrStructId, mergedCbufferPtrStruct); + + ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); + + // Remap member ids + foreach (var i in buffer) + { + if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberIndexOffset > 0) + { + // According to spec, this must be a OpConstant (and we only create them with int) + var indexes = accessChain.Values.Elements.Span; + var constantId = indexes[0]; + var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, context.GetBuffer()); + indexes[0] = context.CompileConstant(index).Id; + + // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) + accessChain.UpdateInstructionMemory(); + } + } + // Out of safety, check for any OpLoad/OpStore on the variables (forbidden, only OpAccessChain) + else if (i.Op == Op.OpLoad && (OpLoad)i is { } load) + { + if (variables.TryGetValue(load.Pointer, out var cbuffer)) + throw new NotSupportedException("Can't OpLoad with cbuffer"); + } + else if (i.Op == Op.OpStore && (OpStore)i is { } store) + { + if (variables.TryGetValue(store.Pointer, out var cbuffer)) + throw new NotSupportedException("Can't OpLoad with cbuffer"); + } + } + + // Update first variable to use new type + cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; + // Update name + globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; + foreach (var i in buffer) + { + if (i.Op == Op.OpName && (OpName)i is { } name) + { + // Ensure cbuffer variable name is correct (it might still have a pending number such as Test.0 if there was multiple buffers with same name) + if (cbuffersSpan[0].Variable.ResultId == name.Target) + name.Name = cbuffersEntry.Key; + // Remove any other OpName (after remapping they would all point to the merged variable) + foreach (var cbuffer in cbuffersSpan[1..]) + { + if (cbuffer.Variable.ResultId == name.Target) + SetOpNop(i.Data.Memory.Span); + } + } + } + + var idRemapping = new Dictionary(); + foreach (ref var cbuffer in cbuffersSpan.Slice(1)) + { + // Update all cbuffers access to be replaced with first variable (unified cbuffer) + idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); + // Remove other cbuffer variables + SetOpNop(cbuffer.Variable.InstructionMemory.Span); + // TODO: Do we want to remove unecessary types? + // Maybe we don't care as they are not used anymore, they will be ignored. + // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? + } + + SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); + } + } + } + + private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + { + var cbuffers = buffer + .Where(x => x.Op == Op.OpVariableSDSL) + .Select(x => (OpVariableSDSL)x) + // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset + .Select(x => ( + Variable: x, + StructTypePtrId: x.ResultType, + StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + MemberIndexOffset: 0)) + .Where(x => x.StructType != null) + .ToList(); + + EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) + { + var structId = context.Types[s]; + + var hasOffsetDecorations = false; + foreach (var i in context.GetBuffer()) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructType == structId) + { + hasOffsetDecorations = true; + } + } + + var members = new EffectTypeMemberDescription[s.Members.Count]; + var offset = 0; + for (int i = 0; i < s.Members.Count; ++i) + { + members[i] = new EffectTypeMemberDescription + { + Name = s.Members[i].Name, + Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier), + Offset = offset, + }; + + var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); + + // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way + if (!hasOffsetDecorations) + context.Add(new OpMemberDecorate(context.Types[s], i, ParameterizedFlags.DecorationOffset(offset))); + + offset += memberSize; + } + return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; + } + + + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier) + { + return symbolType switch + { + ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ArrayType a => ConvertArrayType(context, a, typeModifier), + StructType s => ConvertStructType(context, s), + // TODO: should we use RowCount instead? (need to update Stride) + VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Rows, ColumnCount = m.Columns }, + MatrixType m when typeModifier == TypeModifier.RowMajor + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Rows, ColumnCount = m.Columns }, + }; + + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier) + { + var typeId = context.Types[a]; + var elementType = ConvertType(context, a.BaseType, typeModifier); + + var hasStrideDecoration = false; + foreach (var i in context.GetBuffer()) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ArrayStride } } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) + { + hasStrideDecoration = true; + } + } + + var arrayStride = (elementType.ElementSize + 15) / 16 * 16; + context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); + + return elementType with { Elements = a.Size }; + } + } + + // Scan LinkSDSL and LogicalGroupSDSL decorations + Dictionary<(int StructType, int Member), string> links = new(); + Dictionary<(int StructType, int Member), string> logicalGroups = new(); + foreach (var i in context) + { + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) + { + using var n = new LiteralValue(m.Span); + links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); + } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) + { + using var n = new LiteralValue(m2.Span); + logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); + } + } + + foreach (var cbuffer in cbuffers) + { + int constantBufferOffset = 0; + var cb = cbuffer.StructType; + var structTypeId = context.Types[cb]; + + var memberInfos = new EffectValueDescription[cb.Members.Count]; + for (var index = 0; index < cb.Members.Count; index++) + { + // Properly compute size and offset according to DirectX rules + var member = cb.Members[index]; + var memberSize = SpirvBuilder.ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); + + context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); + + if (!links.TryGetValue((structTypeId, index), out var linkName)) + throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); + // Allowed to be not set (in which case logicalGroup == null) + logicalGroups.TryGetValue((structTypeId, index), out var logicalGroup); + + memberInfos[index] = new EffectValueDescription + { + Type = ConvertType(context, member.Type, member.TypeModifier), + RawName = member.Name, + KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, + Offset = constantBufferOffset, + Size = memberSize, + LogicalGroup = logicalGroup, + }; + + // Adjust offset for next item + constantBufferOffset += memberSize; + } + + globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription + { + Name = globalContext.Names[cbuffer.Variable.ResultId], + // Round buffer size to next multiple of 16 bytes + Size = (constantBufferOffset + 15) / 16 * 16, + + Type = ConstantBufferType.ConstantBuffer, + Members = memberInfos, + }); + } + } + } +} diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9b2ae4ba8c..54f6e52211 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -86,369 +86,6 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect effectReflection = globalContext.Reflection; } - private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) - { - // If multiple cbuffer with same name Test, they will be renamed Test.0 Test.1 etc. - string GetCBufferFinalName(string cbufferName) - { - var dotIndex = cbufferName.IndexOf('.'); - if (dotIndex != -1) - return cbufferName.Substring(0, dotIndex); - - return cbufferName; - } - - string GetCBufferLogicalGroup(string cbufferName) - { - var dotIndex = cbufferName.IndexOf('.'); - if (dotIndex != -1) - return cbufferName.Substring(dotIndex + 1); - - return null; - } - - // OpSDSLEffect is emitted for any non-root composition - var compositionNodes = buffer - .Where(x => x.Op == Op.OpSDSLEffect) - .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLEffect)x).EffectName)) - .ToList(); - - var shaders = buffer - .Where(x => x.Op == Op.OpSDSLShader) - .Select(x => (StartIndex: x.Index, ShaderName: ((OpSDSLShader)x).ShaderName)) - .ToList(); - - var cbuffersByNames = buffer - .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (Index: x.Index, Variable: (OpVariableSDSL)x)) - // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset - .Select(x => ( - Variable: x.Variable, - CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, - ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, - StructTypePtrId: x.Variable.ResultType, - StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberIndexOffset: 0, - LogicalGroup: GetCBufferLogicalGroup(globalContext.Names[x.Variable.ResultId]))) - // TODO: Check Decoration.Block? - .Where(x => x.StructType != null) - .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); - - var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); - - Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); - } - else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) - { - if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); - } - } - - void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) - { - int mergedMemberIndex = 0; - foreach (ref var cbuffer in cbuffersSpan) - { - var compositionPath = cbuffer.CompositionPath; - - for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) - { - var member = cbuffer.StructType.Members[memberIndex]; - - if (!decorations.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var decorationsForThisMember)) - decorations.Add((context.Types[cbuffer.StructType], memberIndex), decorationsForThisMember = new(new(), new())); - - decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); - - if (!newStructure) - { - // If not a new structure, we restart from 0 and add only what's necessary - // Note: we made sure to query linkValue before - decorationsForThisMember.StringDecorations.Clear(); - decorationsForThisMember.Decorations.Clear(); - } - - // If not specified, add default Link info - if (linkValue == null) - { - var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; - if (!compositionPath.IsNullOrEmpty()) - link = $"{link}.{compositionPath}"; - - decorationsForThisMember.StringDecorations.Add(Decoration.LinkSDSL, link); - } - - // Also transfer LogicalGroup (from name) - if (cbuffer.LogicalGroup != null) - decorationsForThisMember.StringDecorations.Add(Decoration.LogicalGroupSDSL, cbuffer.LogicalGroup); - - foreach (var stringDecoration in decorationsForThisMember.StringDecorations) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); - foreach (var decoration in decorationsForThisMember.Decorations) - context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); - } - } - } - - foreach (var cbuffersEntry in cbuffersByNames) - { - var cbuffers = cbuffersEntry.ToList(); - var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); - - if (cbuffersEntry.Count() == 1) - { - ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); - } - // More than 1 cbuffers with same name - else - { - int offset = 0; - // TODO: Analyze and skip cbuffers parts which are unused - foreach (ref var cbuffer in cbuffersSpan) - { - cbuffer.MemberIndexOffset = offset; - offset += cbuffer.StructType.Members.Count; - } - var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); - var structTypes = cbuffers.Select(x => x.StructType); - - var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); - var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); - var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); - var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); - - globalContext.Types.Add(mergedCbufferStructId, mergedCbufferStruct); - globalContext.Types.Add(mergedCbufferPtrStructId, mergedCbufferPtrStruct); - - ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); - - // Remap member ids - foreach (var i in buffer) - { - if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) - { - if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberIndexOffset > 0) - { - // According to spec, this must be a OpConstant (and we only create them with int) - var indexes = accessChain.Values.Elements.Span; - var constantId = indexes[0]; - var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, context.GetBuffer()); - indexes[0] = context.CompileConstant(index).Id; - - // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) - accessChain.UpdateInstructionMemory(); - } - } - // Out of safety, check for any OpLoad/OpStore on the variables (forbidden, only OpAccessChain) - else if (i.Op == Op.OpLoad && (OpLoad)i is { } load) - { - if (variables.TryGetValue(load.Pointer, out var cbuffer)) - throw new NotSupportedException("Can't OpLoad with cbuffer"); - } - else if (i.Op == Op.OpStore && (OpStore)i is { } store) - { - if (variables.TryGetValue(store.Pointer, out var cbuffer)) - throw new NotSupportedException("Can't OpLoad with cbuffer"); - } - } - - // Update first variable to use new type - cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; - // Update name - globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; - foreach (var i in buffer) - { - if (i.Op == Op.OpName && (OpName)i is { } name) - { - // Ensure cbuffer variable name is correct (it might still have a pending number such as Test.0 if there was multiple buffers with same name) - if (cbuffersSpan[0].Variable.ResultId == name.Target) - name.Name = cbuffersEntry.Key; - // Remove any other OpName (after remapping they would all point to the merged variable) - foreach (var cbuffer in cbuffersSpan[1..]) - { - if (cbuffer.Variable.ResultId == name.Target) - SetOpNop(i.Data.Memory.Span); - } - } - } - - var idRemapping = new Dictionary(); - foreach (ref var cbuffer in cbuffersSpan.Slice(1)) - { - // Update all cbuffers access to be replaced with first variable (unified cbuffer) - idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); - // Remove other cbuffer variables - SetOpNop(cbuffer.Variable.InstructionMemory.Span); - // TODO: Do we want to remove unecessary types? - // Maybe we don't care as they are not used anymore, they will be ignored. - // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? - } - - SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); - } - } - } - - private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) - { - var cbuffers = buffer - .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (OpVariableSDSL)x) - // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset - .Select(x => ( - Variable: x, - StructTypePtrId: x.ResultType, - StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberIndexOffset: 0)) - .Where(x => x.StructType != null) - .ToList(); - - EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) - { - var structId = context.Types[s]; - - var hasOffsetDecorations = false; - foreach (var i in context.GetBuffer()) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructType == structId) - { - hasOffsetDecorations = true; - } - } - - var members = new EffectTypeMemberDescription[s.Members.Count]; - var offset = 0; - for (int i = 0; i < s.Members.Count; ++i) - { - members[i] = new EffectTypeMemberDescription - { - Name = s.Members[i].Name, - Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier), - Offset = offset, - }; - - var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); - - // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way - if (!hasOffsetDecorations) - context.Add(new OpMemberDecorate(context.Types[s], i, ParameterizedFlags.DecorationOffset(offset))); - - offset += memberSize; - } - return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; - } - - - EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier) - { - return symbolType switch - { - ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ArrayType a => ConvertArrayType(context, a, typeModifier), - StructType s => ConvertStructType(context, s), - // TODO: should we use RowCount instead? (need to update Stride) - VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, - MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Rows, ColumnCount = m.Columns }, - MatrixType m when typeModifier == TypeModifier.RowMajor - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Rows, ColumnCount = m.Columns }, - }; - - EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier) - { - var typeId = context.Types[a]; - var elementType = ConvertType(context, a.BaseType, typeModifier); - - var hasStrideDecoration = false; - foreach (var i in context.GetBuffer()) - { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ArrayStride } } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) - { - hasStrideDecoration = true; - } - } - - var arrayStride = (elementType.ElementSize + 15) / 16 * 16; - context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); - - return elementType with { Elements = a.Size }; - } - } - - // Scan LinkSDSL and LogicalGroupSDSL decorations - Dictionary<(int StructType, int Member), string> links = new(); - Dictionary<(int StructType, int Member), string> logicalGroups = new(); - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); - } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) - { - using var n = new LiteralValue(m2.Span); - logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); - } - } - - foreach (var cbuffer in cbuffers) - { - int constantBufferOffset = 0; - var cb = cbuffer.StructType; - var structTypeId = context.Types[cb]; - - var memberInfos = new EffectValueDescription[cb.Members.Count]; - for (var index = 0; index < cb.Members.Count; index++) - { - // Properly compute size and offset according to DirectX rules - var member = cb.Members[index]; - var memberSize = SpirvBuilder.ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); - - context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); - - if (!links.TryGetValue((structTypeId, index), out var linkName)) - throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); - // Allowed to be not set (in which case logicalGroup == null) - logicalGroups.TryGetValue((structTypeId, index), out var logicalGroup); - - memberInfos[index] = new EffectValueDescription - { - Type = ConvertType(context, member.Type, member.TypeModifier), - RawName = member.Name, - KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, - Offset = constantBufferOffset, - Size = memberSize, - LogicalGroup = logicalGroup, - }; - - // Adjust offset for next item - constantBufferOffset += memberSize; - } - - globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription - { - Name = globalContext.Names[cbuffer.Variable.ResultId], - // Round buffer size to next multiple of 16 bytes - Size = (constantBufferOffset + 15) / 16 * 16, - - Type = ConstantBufferType.ConstantBuffer, - Members = memberInfos, - }); - } - } - class MixinGlobalContext { public Dictionary Names { get; } = []; From 57a1e3fe109ac7a916c23a348b3d7e19ce872865 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 17 Dec 2025 17:55:03 +0900 Subject: [PATCH 0606/1182] Buffer (note: tests failing with OpenGL due to texbuffer implementation not working and some other issues) --- assets/SDSL/RenderTests/Buffers.sdsl | 16 ++++++ assets/SDSL/RenderTests/TextureLoad.sdsl | 16 ++++++ .../{Textures.sdsl => TextureSample.sdsl} | 2 +- .../FrameRenderer.OpenGL.cs | 47 +++++++++++++++++ src/Stride.Shaders/Core/SymbolTypes.cs | 50 +++++++++---------- .../Parsing/SDSL/AST/Expression.cs | 31 +++++++++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 41 ++++++++------- .../Parsing/SDSL/AST/ShaderElements.cs | 1 + src/Stride.Shaders/Spirv/Building/Context.cs | 1 + 9 files changed, 155 insertions(+), 50 deletions(-) create mode 100644 assets/SDSL/RenderTests/Buffers.sdsl create mode 100644 assets/SDSL/RenderTests/TextureLoad.sdsl rename assets/SDSL/RenderTests/{Textures.sdsl => TextureSample.sdsl} (94%) diff --git a/assets/SDSL/RenderTests/Buffers.sdsl b/assets/SDSL/RenderTests/Buffers.sdsl new file mode 100644 index 0000000000..7d53cae3ba --- /dev/null +++ b/assets/SDSL/RenderTests/Buffers.sdsl @@ -0,0 +1,16 @@ +// PSMain(ExpectedResult=#1357ABCD, buffer.Buffer1=#1357ABCD) + +namespace Stride.Shaders.Tests; + +shader Buffers +{ + stream float4 ColorTarget : SV_Target0; + stream float4 TexCoord : TEXCOORD; + + stage Buffer Buffer1; + + void PSMain() + { + streams.ColorTarget = Buffer1.Load(0); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/TextureLoad.sdsl b/assets/SDSL/RenderTests/TextureLoad.sdsl new file mode 100644 index 0000000000..0c10e15bbb --- /dev/null +++ b/assets/SDSL/RenderTests/TextureLoad.sdsl @@ -0,0 +1,16 @@ +// PSMain(ExpectedResult=#1357ABCD, texture.Texture1=#1357ABCD) + +namespace Stride.Shaders.Tests; + +shader TextureLoad +{ + stream float4 ColorTarget : SV_Target0; + stream float4 TexCoord : TEXCOORD; + + stage Texture2D Texture1; + + void PSMain() + { + streams.ColorTarget = Texture1.Load(int3(0, 0, 0)); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/Textures.sdsl b/assets/SDSL/RenderTests/TextureSample.sdsl similarity index 94% rename from assets/SDSL/RenderTests/Textures.sdsl rename to assets/SDSL/RenderTests/TextureSample.sdsl index 8158c29418..fdd6e27c8e 100644 --- a/assets/SDSL/RenderTests/Textures.sdsl +++ b/assets/SDSL/RenderTests/TextureSample.sdsl @@ -2,7 +2,7 @@ namespace Stride.Shaders.Tests; -shader Textures +shader TextureSample { stream float4 ColorTarget : SV_Target0; stream float4 TexCoord : TEXCOORD; diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index 90343a6ac1..ffc659e5a8 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -228,6 +228,7 @@ public override unsafe void RenderFrame(Span result) Gl.BindVertexArray(Vao); Gl.UseProgram(Shader); + int bufferCount = 0; foreach (var param in Parameters) { if (param.Key.StartsWith("cbuffer.")) @@ -263,6 +264,12 @@ public override unsafe void RenderFrame(Span result) throw new NotSupportedException(); var textureName = param.Key.Substring("texture.".Length); + + var index = Gl.GetProgramResourceIndex(Shader, GLEnum.Uniform, textureName); + GLEnum type; + var requestedProps = GLEnum.Type; + Gl.GetProgramResource(Shader, GLEnum.Uniform, 0, 1, &requestedProps, 1, null, (int*)&type); + var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, textureName); if (location == -1) throw new InvalidOperationException($"Could not find resource {textureName}"); @@ -281,6 +288,46 @@ public override unsafe void RenderFrame(Span result) Gl.ProgramUniform1(Shader, location, texture); } + else if (param.Key.StartsWith("buffer.")) + { + if (!param.Value.StartsWith("#")) + throw new NotSupportedException(); + + var bufferName = param.Key.Substring("buffer.".Length); + var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, bufferName); + if (location == -1) + throw new InvalidOperationException($"Could not find resource {bufferName}"); + + var buffer = Gl.GenBuffer(); + Gl.BindBuffer(BufferTargetARB.TextureBuffer, buffer); + + var hexColor = param.Value.Substring(1); + uint color = uint.Parse(hexColor.Substring(0, 8), NumberStyles.HexNumber); + color = (((color << 24) & 0xff000000) | + ((color << 8) & 0xff0000) | + ((color >> 8) & 0xff00) | + ((color >> 24) & 0xff)); + + Gl.BufferData(BufferTargetARB.TextureBuffer, sizeof(uint), (void*)&color, BufferUsageARB.StaticDraw); + + var texture = Gl.GenTexture(); + Gl.ActiveTexture(GLEnum.Texture0 + bufferCount); + Gl.BindTexture(GLEnum.TextureBuffer, texture); + // TODO: Check if this is really valid to cast PixelInternalFormat to SizedInternalFormat in all cases? + Gl.TexBuffer(TextureTarget.TextureBuffer, GLEnum.Rgba8ui, buffer); + + Gl.ProgramUniform1(Shader, location, bufferCount); + + bufferCount++; + } + } + + Gl.ValidateProgram(Shader); + var validateStatus = Gl.GetProgram(Shader, GLEnum.ValidateStatus); + if (validateStatus != (int)GLEnum.True) + { + var validationLog = Gl.GetProgramInfoLog(Shader); + throw new InvalidOperationException($"Validation error: {validationLog}"); } //Draw the geometry. diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 40ac0d177d..080ecc1105 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -46,31 +46,31 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT return false; } } - public static bool TryGetBufferType(string name, string? templateType, [MaybeNullWhen(false)] out SymbolType result) + public static bool TryGetBufferType(string name, string? templateTypeName, [MaybeNullWhen(false)] out SymbolType result) { - (result, bool found) = (name, templateType) switch + SymbolType? templateType = null; + if (templateTypeName != null && !SymbolType.TryGetNumeric(templateTypeName, out templateType)) { - ("Buffer", "float") => (new BufferType(ScalarType.From("float"), -1) as SymbolType, true), - ("Buffer", "int") => (new BufferType(ScalarType.From("int"), -1), true), - ("Buffer", "uint") => (new BufferType(ScalarType.From("uint"), -1), true), - // TODO: Use scalar type instead of vector type as in SPIR-V spec? - ("Buffer", "float2") => (new BufferType(VectorType.From("float2"), -1), true), - ("Buffer", "float3") => (new BufferType(VectorType.From("float3"), -1), true), - ("Buffer", "float4") => (new BufferType(VectorType.From("float4"), -1), true), - ("Buffer", "int2") => (new BufferType(VectorType.From("int2"), -1), true), - ("Buffer", "int3") => (new BufferType(VectorType.From("int3"), -1), true), - ("Buffer", "int4") => (new BufferType(VectorType.From("int4"), -1), true), - ("Buffer", "uint2") => (new BufferType(VectorType.From("uint2"), -1), true), - ("Buffer", "uint3") => (new BufferType(VectorType.From("uint3"), -1), true), - ("Buffer", "uint4") => (new BufferType(VectorType.From("uint4"), -1), true), - ("Texture", null) => (new Texture1DType(ScalarType.From("float")), true), - ("Texture1D", null) => (new Texture1DType(ScalarType.From("float")), true), - ("Texture2D", null) => (new Texture2DType(ScalarType.From("float")), true), - ("Texture3D", null) => (new Texture3DType(ScalarType.From("float")), true), - ("Texture", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType).BaseType), true), - ("Texture1D", "int4" or "uint4" or "float4") => (new Texture1DType(VectorType.From(templateType).BaseType), true), - ("Texture2D", "int4" or "uint4" or "float4") => (new Texture2DType(VectorType.From(templateType).BaseType), true), - ("Texture3D", "int4" or "uint4" or "float4") => (new Texture3DType(VectorType.From(templateType).BaseType), true), + result = null; + return false; + } + + if (templateType == null) + templateType = ScalarType.From("float"); + + var scalarType = templateType switch + { + VectorType v => v.BaseType, + ScalarType s => s, + }; + + (result, bool found) = (name, scalarType) switch + { + ("Buffer", ScalarType { TypeName: "float" or "int" or "uint" }) => (new BufferType(scalarType) as SymbolType, true), + ("Texture", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture1DType(scalarType) as SymbolType, true), + ("Texture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture1DType(scalarType) as SymbolType, true), + ("Texture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture2DType(scalarType) as SymbolType, true), + ("Texture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture3DType(scalarType) as SymbolType, true), _ => (null, false) }; @@ -157,9 +157,9 @@ public sealed record StructType(string Name, List<(string Name, SymbolType Type, public override string ToString() => $"struct {base.ToString()}"; } -public sealed record BufferType(SymbolType BaseType, int Size) : SymbolType() +public sealed record BufferType(ScalarType BaseType) : SymbolType() { - public override string ToString() => $"Buffer<{BaseType}, {Size}>"; + public override string ToString() => $"Buffer<{BaseType}>"; } // TODO: Add sampler parameters diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 65c21ebbb2..8236af4ddb 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -315,38 +315,55 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) result = Source.Compile(table, compiler); currentValueType = Source.Type; } - if (Source is Identifier { Type: PointerType { BaseType: TextureType or Texture2DType or Texture3DType } } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) + if (Source is Identifier { Type: PointerType { BaseType: Texture1DType or Texture2DType or Texture3DType } } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) { result = Source.CompileAsValue(table, compiler); + var textureType = (TextureType)Source.ValueType; if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) { + Type = new VectorType(textureType.ReturnType, 4); + var textureValue = result; var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); - var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(new VectorType(((TextureType)Source.ValueType).ReturnType, 4)); + var returnType = context.GetOrRegister(Type); var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, Specification.ImageOperandsMask.None)); - Type = ((TextureType)Source.ValueType).ReturnType; return new(sample.ResultId, sample.ResultType); } else if (Accessors is [MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling]) { + Type = new VectorType(textureType.ReturnType, 4); + var textureValue = result; var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); - var typeSampledImage = context.GetOrRegister(new SampledImage((TextureType)Source.ValueType)); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(new VectorType(((TextureType)Source.ValueType).ReturnType, 4)); + var returnType = context.GetOrRegister(Type); var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); - Type = ((TextureType)Source.ValueType).ReturnType; return new(sample.ResultId, sample.ResultType); } else throw new InvalidOperationException("Invalid Sample method call"); } + else if (Source is Identifier { Type: PointerType { BaseType: BufferType or TextureType } pointerType } && Accessors is [MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load]) + { + Type = new VectorType(pointerType.BaseType switch + { + BufferType b => b.BaseType, + TextureType t => t.ReturnType, + }, 4); + + var returnType = context.GetOrRegister(Type); + var coords = load.Parameters.Values[0].CompileAsValue(table, compiler); + var resource = result; + var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null)); + return new(loadResult.ResultId, loadResult.ResultType); + } else { int accessChainIdCount = 0; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index f5888f5eac..a9409c3f7b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -170,24 +170,31 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeImage && new OpTypeImage(instruction) is { } typeImage) { var sampledType = (ScalarType)types[typeImage.SampledType]; - TextureType textureType = typeImage.Dim switch + if (typeImage.Dim == Dim.Buffer) { - Dim.Dim1D => new Texture1DType(sampledType), - Dim.Dim2D => new Texture2DType(sampledType), - Dim.Dim3D => new Texture3DType(sampledType), - Dim.Cube => new TextureCubeType(sampledType), - _ => throw new NotImplementedException(), - }; - textureType = textureType with + types.Add(typeImage.ResultId, new BufferType(sampledType)); + } + else { - Depth = typeImage.Depth, - Arrayed = typeImage.Arrayed == 1 ? true : false, - Multisampled = typeImage.MS == 1 ? true : false, - Format = typeImage.Imageformat, - Sampled = typeImage.Sampled, - }; - - types.Add(typeImage.ResultId, textureType); + TextureType textureType = typeImage.Dim switch + { + Dim.Dim1D => new Texture1DType(sampledType), + Dim.Dim2D => new Texture2DType(sampledType), + Dim.Dim3D => new Texture3DType(sampledType), + Dim.Cube => new TextureCubeType(sampledType), + _ => throw new NotImplementedException(), + }; + textureType = textureType with + { + Depth = typeImage.Depth, + Arrayed = typeImage.Arrayed == 1 ? true : false, + Multisampled = typeImage.MS == 1 ? true : false, + Format = typeImage.Imageformat, + Sampled = typeImage.Sampled, + }; + + types.Add(typeImage.ResultId, textureType); + } } else if (instruction.Op == Op.OpTypeSampler && new OpTypeSampler(instruction) is { } typeSampler) { @@ -399,7 +406,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } var storageClass = Specification.StorageClass.Private; - if (memberType is TextureType) + if (memberType is TextureType || memberType is BufferType) storageClass = Specification.StorageClass.UniformConstant; svar.Type = new PointerType(memberType, storageClass); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 5df6ab57db..1cdc9c465c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -313,6 +313,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { TextureType => (Specification.StorageClass.UniformConstant, SymbolKind.Variable), SamplerType => (Specification.StorageClass.UniformConstant, SymbolKind.SamplerState), + BufferType => (Specification.StorageClass.UniformConstant, SymbolKind.TBuffer), _ => throw new NotImplementedException(), }; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 3fb2fe75b5..304173f070 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -193,6 +193,7 @@ public int GetOrRegister(SymbolType? type) Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, + BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Dim.Buffer, 2, 0, 0, 1, ImageFormat.Unknown, null)).IdResult, SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, GenericLinkType => Buffer.Add(new OpTypeGenericLinkSDSL(Bound++)).IdResult, // StructSymbol st => RegisterStruct(st), From 2aa0ea0e874f5ed77ed54838e8091bbfcaf292fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 17 Dec 2025 19:18:12 +0900 Subject: [PATCH 0607/1182] Deduplicate structures --- .../CompositionExternalStruct.sdsl | 15 +++++- .../SDSL/ShaderMixer.CBuffers.cs | 7 ++- .../SDSL/ShaderMixer.ShaderInfo.cs | 10 ---- .../SDSL/ShaderMixer.cs | 42 +++++++++++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 ++-- .../Spirv/Processing/TypeDuplicatesRemover.cs | 47 ++++++++++++++----- 6 files changed, 90 insertions(+), 39 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl index 8409e08307..c820f30db8 100644 --- a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl +++ b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl @@ -8,6 +8,12 @@ shader CompositionStruct { float A; } + + // Use struct as a parameter + float ExtractValue(Test1 t) + { + return t.A; + } } shader CompositionBase : CompositionStruct @@ -16,9 +22,16 @@ shader CompositionBase : CompositionStruct { Test1 Light; } + + // Use struct as a parameter + float ExtractValue2(Test1 t) + { + return t.A; + } + float4 Compute() { - return (Light.A / 255.0).xxxx; + return float2(ExtractValue(Light) / 255.0, ExtractValue2(Light) / 255.0).xyxy; } }; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 6d6ed48cc8..4dbd8838c2 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -108,6 +108,9 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s decorationsForThisMember.Decorations.Clear(); } + // Note: We don't mutate decorationsForThisMember because multiple cbuffer might share the same struct + // We emit OpMemberDecorateString directly on the resulting cbufferStructId + // If not specified, add default Link info if (linkValue == null) { @@ -115,12 +118,12 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s if (!compositionPath.IsNullOrEmpty()) link = $"{link}.{compositionPath}"; - decorationsForThisMember.StringDecorations.Add(Decoration.LinkSDSL, link); + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(link))); } // Also transfer LogicalGroup (from name) if (cbuffer.LogicalGroup != null) - decorationsForThisMember.StringDecorations.Add(Decoration.LogicalGroupSDSL, cbuffer.LogicalGroup); + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); foreach (var stringDecoration in decorationsForThisMember.StringDecorations) context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index afbafc792a..2053ec6671 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -53,16 +53,6 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer context, int contextStart, int contextEnd, NewSpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) { var removedIds = new HashSet(); - for (var index = contextStart; index < contextEnd; index++) - { - var i = context[index]; - - if (i.Data.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) - { - var structName = globalContext.Names[typeStruct]; - shaderInfo!.StructTypes.Add(structName, typeStruct.ResultId); - } - } for (var index = shaderStart; index < shaderEnd; index++) { var i = buffer[index]; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 54f6e52211..87f82645f8 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -239,6 +239,8 @@ bool ProcessStageMember(int memberId, bool isStage) var typeDuplicateInserter = new TypeDuplicateHelper(context.GetBuffer()); + var structTypes = new Dictionary(); + // Copy instructions to main buffer for (var index = 0; index < shader.Count; index++) { @@ -336,18 +338,31 @@ bool ProcessStageMember(int memberId, bool isStage) remapIds.Add(importStruct.ResultId, structId); removedIds.Add(structId); } - // Check if type already exists in context (deduplicate them) - else if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) + else { - if (i2.IdResult is int id) + // Check if type already exists in context (deduplicate them) + if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) { - remapIds.Add(id, existingInstruction.IdResult.Value); - removedIds.Add(existingInstruction.IdResult.Value); + if (i2.IdResult is int id) + { + remapIds.Add(id, existingInstruction.IdResult.Value); + removedIds.Add(existingInstruction.IdResult.Value); + } + } + else + { + addToContext = true; + } + + // OpTypeStruct is the only type that can be defined by the shader. + // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. + if (i2.Op == Op.OpTypeStruct && (OpTypeStruct)i2 is { } typeStruct) + { + var structName = names[typeStruct.ResultId - offset]; + if (!remapIds.TryGetValue(typeStruct.ResultId, out var structId)) + structId = typeStruct.ResultId; + structTypes.Add(structName, structId); } - } - else - { - addToContext = true; } } // Does this belong in context or buffer? @@ -376,7 +391,12 @@ bool ProcessStageMember(int memberId, bool isStage) } if (addToContext) - context.GetBuffer().Add(i2); + { + var i2Index = context.GetBuffer().Add(i2); + + // Add latest OpName/OpMemberName so that OpTypeStruct can be properly deduplicated + typeDuplicateInserter.AddNameInstruction(i2Index); + } } } @@ -416,6 +436,8 @@ bool ProcessStageMember(int memberId, bool isStage) // Build ShaderInfo var shaderInfo = new ShaderInfo(mixinNode.Shaders.Count, shaderClass.ClassName, shaderStart, buffer.Count); + foreach (var structType in structTypes) + shaderInfo.StructTypes.Add(structType.Key, structType.Value); shaderInfo.CompositionPath = mixinNode.CompositionPath; if (mixinNode.Stage != null && mixinNode.Stage.ShadersByName.TryGetValue(shaderClass.ClassName, out var stageShaderInfo)) shaderInfo.Stage = stageShaderInfo; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a9409c3f7b..60b12d57af 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -375,6 +375,9 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var member in Elements) { + // Do this early: we want struct to be available for function parameters (same loop) + member.ProcessSymbol(table, context); + if (member is ShaderMethod func) { var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table, context), []); @@ -450,11 +453,6 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } - foreach (var member in Elements) - { - member.ProcessSymbol(table, context); - } - foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 9d98872e28..54b3671fcd 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -18,7 +18,7 @@ namespace Stride.Shaders.Spirv.Processing; /// Remove duplicate simple types. /// Should be applied after the IdRefOffsetter. /// -public struct TypeDuplicateHelper +public class TypeDuplicateHelper { public int[] FindItemsWithTypes(NewSpirvBuffer buffer, params Span ops) { @@ -51,7 +51,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; } - class OperationComparer(List NameInstructions, bool UseIndices) : IComparer + class OperationComparer(Func> RequestNameInstructions, bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -125,14 +125,16 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper y) { + var nameInstructions = RequestNameInstructions(); + // Note: With RemapOp(), this will also find OpMember instructions var target1 = x.Data.Memory.Span[1]; - var namesStart1 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 }, this); - var namesEnd1 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 + 1 }, this); + var namesStart1 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 }, this); + var namesEnd1 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 + 1 }, this); var target2 = y.Data.Memory.Span[1]; - var namesStart2 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 }, this); - var namesEnd2 = ~NameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 + 1 }, this); + var namesStart2 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 }, this); + var namesEnd2 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 + 1 }, this); // Compare sequences (they should be the same) for (int i = 0; i < Math.Max(namesEnd1 - namesStart1, namesEnd2 - namesStart2); ++i) @@ -143,7 +145,7 @@ public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper if (i >= namesEnd2 - namesStart2) return 1; - var comparison = Compare(NameInstructions[namesStart1 + i], NameInstructions[namesStart2 + i]); + var comparison = Compare(nameInstructions[namesStart1 + i], nameInstructions[namesStart2 + i] with { TargetOverride = target1 }); if (comparison != 0) return comparison; } @@ -157,12 +159,14 @@ public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper private List namesByOp; private OperationComparer comparerSort; private OperationComparer comparerInsert; + private bool namesSorted; public TypeDuplicateHelper(NewSpirvBuffer buffer) { this.buffer = buffer; instructionsByOp = new(); namesByOp = new(); + namesSorted = false; foreach (var i in buffer) { switch (i.Op) @@ -177,12 +181,33 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) } } - comparerSort = new OperationComparer(namesByOp, true); - // Note: since it contains no OpTypeStruct, it should not access OperationComparer.NameInstructions - namesByOp.Sort(comparerSort); + comparerSort = new OperationComparer(GetSortedNames, true); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(namesByOp, false); + comparerInsert = new OperationComparer(GetSortedNames, false); + } + + public void AddNameInstruction(OpDataIndex i) + { + switch (i.Op) + { + case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: + // Target is always in operand 1 for all those instructions + namesByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); + namesSorted = false; + break; + } + } + + private List GetSortedNames() + { + // If any name was added, sort them + if (!namesSorted) + { + namesByOp.Sort(comparerSort); + namesSorted = true; + } + return namesByOp; } public bool CheckForDuplicates(OpData data, out OpData foundData) From 40c0624ffc31b56ba739160ba785f070d5e16f6f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 17 Dec 2025 19:48:06 +0900 Subject: [PATCH 0608/1182] Various fixes for Texture/Sampler so that they can be properly accessed through inheritance --- assets/SDSL/RenderTests/Rgroups.sdsl | 16 ++++++++++++---- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 2 ++ src/Stride.Shaders.Experiments/Examples.cs | 6 ++++++ src/Stride.Shaders.Tests/RenderingTests.cs | 6 ++++++ src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 3 +++ .../Parsing/SDSL/AST/ShaderElements.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 2 ++ .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 + 8 files changed, 33 insertions(+), 5 deletions(-) diff --git a/assets/SDSL/RenderTests/Rgroups.sdsl b/assets/SDSL/RenderTests/Rgroups.sdsl index d5787ec654..f9064adb22 100644 --- a/assets/SDSL/RenderTests/Rgroups.sdsl +++ b/assets/SDSL/RenderTests/Rgroups.sdsl @@ -1,8 +1,16 @@ -// PSMain(ExpectedResult=#1357ABCD, texture.SPIRV_Cross_CombinedTexture1Sampler1=#1357ABCD) +// PSMain(ExpectedResult=#12140000, texture.SPIRV_Cross_CombinedTexture1Sampler1=#12000000, texture.SPIRV_Cross_CombinedTexture2Sampler1=#00140000) namespace Stride.Shaders.Tests; -shader Rgroups +shader RgroupBase +{ + rgroup Group1 + { + stage Texture2D Texture1; + } +} + +shader Rgroups : RgroupBase { stream float4 ColorTarget : SV_Target0; stream float4 TexCoord : TEXCOORD; @@ -11,11 +19,11 @@ shader Rgroups rgroup Group1 { - stage Texture2D Texture1; + stage Texture2D Texture2; } void PSMain() { - streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord); + streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord) + Texture2.Sample(Sampler1, streams.TexCoord); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 87f82645f8..2c7680e34a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -323,6 +323,8 @@ bool ProcessStageMember(int memberId, bool isStage) || i2.Op == Op.OpTypeStruct || i2.Op == Op.OpTypePointer || i2.Op == Op.OpTypeFunction + || i2.Op == Op.OpTypeImage + || i2.Op == Op.OpTypeSampler || i2.Op == Op.OpTypeGenericLinkSDSL || i2.Op == Op.OpSDSLImportShader || i2.Op == Op.OpSDSLImportVariable diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index abd3aaeec2..59667a2bd8 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -210,6 +210,12 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) public class ShaderLoader : ShaderLoaderBase { + public override bool Exists(string name) + { + var filename = $"./assets/SDSL/{name}.sdsl"; + return File.Exists(filename); + } + public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/{name}.sdsl"; diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 5c44e70090..93fdd5d36f 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -29,6 +29,12 @@ public class RenderingTests class ShaderLoader : ShaderLoaderBase { + public override bool Exists(string name) + { + var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; + return File.Exists(filename); + } + public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 7ec730c657..bae6ecb1f8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -256,6 +256,9 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref i if (constantOnly) throw new NotImplementedException(); + if (!table.ShaderLoader.Exists(Name)) + throw new InvalidOperationException($"Symbol [{Name}] could not be found."); + // Maybe it's a static variable? try to resolve by loading file var classSource = new ShaderClassInstantiation(Name, []); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 1cdc9c465c..2d4b6696a2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -319,7 +319,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var type = new PointerType(member.Type, storageClass); var typeId = context.GetOrRegister(type); - var variable = builder.Insert(new OpVariable(typeId, context.Bound++, storageClass, null)); + var variable = builder.Insert(new OpVariableSDSL(typeId, context.Bound++, storageClass, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable.ResultId, member.Name); DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 304173f070..98538a5b9c 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -16,6 +16,7 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer); + public bool Exists(string name); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); } @@ -28,6 +29,7 @@ public void RegisterShader(string name, ReadOnlySpan defines, NewSp loadedShaders.Add(name, buffer); } + public abstract bool Exists(string name); public abstract bool LoadExternalFile(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 54b3671fcd..c3d8297acf 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -92,6 +92,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray || x.Op == Op.OpTypeStruct + || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler || x.Op == Op.OpTypeGenericLinkSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { From 98e436c740b0bbb959d7ee1aaaa1a6af0e1ca4dc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 18 Dec 2025 18:23:48 +0900 Subject: [PATCH 0609/1182] Switched unit testing to D3D11 --- assets/SDSL/RenderTests/Buffers.sdsl | 2 +- assets/SDSL/RenderTests/Rgroups.sdsl | 4 +- .../SDSL/RenderTests/StreamPassthroughPS.sdsl | 4 +- assets/SDSL/RenderTests/StreamVSToPS.sdsl | 4 +- assets/SDSL/RenderTests/TextureLoad.sdsl | 2 +- assets/SDSL/RenderTests/TextureSample.sdsl | 4 +- assets/SDSL/TestTexture.sdsl | 2 +- .../SpirvTranslator.cs | 29 +- .../FrameRenderer.D3D11.cs | 674 ++++++++++++++++++ .../FrameRenderer.OpenGL.cs | 96 +-- src/Stride.Shaders.Tests/FrameRenderer.cs | 48 ++ src/Stride.Shaders.Tests/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 8 +- 13 files changed, 782 insertions(+), 97 deletions(-) create mode 100644 src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs diff --git a/assets/SDSL/RenderTests/Buffers.sdsl b/assets/SDSL/RenderTests/Buffers.sdsl index 7d53cae3ba..e0ffbb9b93 100644 --- a/assets/SDSL/RenderTests/Buffers.sdsl +++ b/assets/SDSL/RenderTests/Buffers.sdsl @@ -5,7 +5,7 @@ namespace Stride.Shaders.Tests; shader Buffers { stream float4 ColorTarget : SV_Target0; - stream float4 TexCoord : TEXCOORD; + stream float2 TexCoord : TEXCOORD; stage Buffer Buffer1; diff --git a/assets/SDSL/RenderTests/Rgroups.sdsl b/assets/SDSL/RenderTests/Rgroups.sdsl index f9064adb22..f46034272c 100644 --- a/assets/SDSL/RenderTests/Rgroups.sdsl +++ b/assets/SDSL/RenderTests/Rgroups.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#12140000, texture.SPIRV_Cross_CombinedTexture1Sampler1=#12000000, texture.SPIRV_Cross_CombinedTexture2Sampler1=#00140000) +// PSMain(ExpectedResult=#12140000, texture.Texture1=#12000000, texture.Texture2=#00140000) namespace Stride.Shaders.Tests; @@ -13,7 +13,7 @@ shader RgroupBase shader Rgroups : RgroupBase { stream float4 ColorTarget : SV_Target0; - stream float4 TexCoord : TEXCOORD; + stream float2 TexCoord : TEXCOORD; stage SamplerState Sampler1; diff --git a/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl index 3e9facf76e..9ee2e8f794 100644 --- a/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl +++ b/assets/SDSL/RenderTests/StreamPassthroughPS.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.498 0.498 0.498 0.498)) +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; @@ -7,7 +7,7 @@ shader StreamPassthroughPS stream float4 Position : POSITION; stream float4 ShadingPosition : SV_Position; stream float4 ColorTarget : SV_Target0; - stream float4 ExtraColor; + stream float4 ExtraColor : EXTRA_COLOR; void VSMain() { diff --git a/assets/SDSL/RenderTests/StreamVSToPS.sdsl b/assets/SDSL/RenderTests/StreamVSToPS.sdsl index 801da69678..26aad793ba 100644 --- a/assets/SDSL/RenderTests/StreamVSToPS.sdsl +++ b/assets/SDSL/RenderTests/StreamVSToPS.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.ExtraColor=(0.498 0.498 0.498 0.498)) +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; @@ -7,7 +7,7 @@ shader StreamVSToPS stream float4 Position : POSITION; stream float4 ShadingPosition : SV_Position; stream float4 ColorTarget : SV_Target0; - stream float4 ExtraColor; + stream float4 ExtraColor : EXTRA_COLOR; stream float4 ExtraColor2; void VSMain() diff --git a/assets/SDSL/RenderTests/TextureLoad.sdsl b/assets/SDSL/RenderTests/TextureLoad.sdsl index 0c10e15bbb..d49e531fe9 100644 --- a/assets/SDSL/RenderTests/TextureLoad.sdsl +++ b/assets/SDSL/RenderTests/TextureLoad.sdsl @@ -5,7 +5,7 @@ namespace Stride.Shaders.Tests; shader TextureLoad { stream float4 ColorTarget : SV_Target0; - stream float4 TexCoord : TEXCOORD; + stream float2 TexCoord : TEXCOORD; stage Texture2D Texture1; diff --git a/assets/SDSL/RenderTests/TextureSample.sdsl b/assets/SDSL/RenderTests/TextureSample.sdsl index fdd6e27c8e..7b36cfe25c 100644 --- a/assets/SDSL/RenderTests/TextureSample.sdsl +++ b/assets/SDSL/RenderTests/TextureSample.sdsl @@ -1,11 +1,11 @@ -// PSMain(ExpectedResult=#1357ABCD, texture.SPIRV_Cross_CombinedTexture1Sampler1=#1357ABCD) +// PSMain(ExpectedResult=#1357ABCD, texture.Texture1=#1357ABCD) namespace Stride.Shaders.Tests; shader TextureSample { stream float4 ColorTarget : SV_Target0; - stream float4 TexCoord : TEXCOORD; + stream float2 TexCoord : TEXCOORD; stage Texture2D Texture1; stage SamplerState Sampler1; diff --git a/assets/SDSL/TestTexture.sdsl b/assets/SDSL/TestTexture.sdsl index 0b86533c46..d9b2efc695 100644 --- a/assets/SDSL/TestTexture.sdsl +++ b/assets/SDSL/TestTexture.sdsl @@ -5,7 +5,7 @@ shader TestBasic : TestBase stream float4 InputPosition : POSITION; stream float4 Position : SV_POSITION; stream float4 ExtraColor : COLOR; - stream float4 TexCoord : TEXCOORD0; + stream float2 TexCoord : TEXCOORD; stage SamplerState Sampler; stage Texture2D Texture0; diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 36f5b505cb..b5fcbdf1fa 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -92,9 +92,6 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam if (cross.CompilerCreateShaderResources(compiler, &resources) != Result.Success) throw new Exception($"{cross.CompilerCreateShaderResources(compiler, &resources)} : could not create shader resources"); - if (cross.CompilerBuildCombinedImageSamplers(compiler) != Result.Success) - throw new Exception($"{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers"); - // HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself) if (backend == Backend.Hlsl) { @@ -128,18 +125,26 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam } } cross.CompilerHlslAddVertexAttributeRemap(compiler, vertexInputRemap, (nuint)vertexInputRemapCount); - } - nuint numSamplers = 0; - CombinedImageSampler* combinedImageSamplers = null; - if (cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers) != Result.Success) - throw new Exception($"{cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers)}"); + cross.CompilerHlslSetResourceBindingFlags(compiler, 0); + } - for (uint i = 0; i < numSamplers; ++i) + if (backend == Backend.Glsl) { - var textureName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].ImageId); - var samplerName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].SamplerId); - cross.CompilerSetName(compiler, combinedImageSamplers[i].CombinedId, $"SPIRV_Cross_Combined{textureName}{samplerName}"); + if (cross.CompilerBuildCombinedImageSamplers(compiler) != Result.Success) + throw new Exception($"{cross.CompilerBuildCombinedImageSamplers(compiler)} : Could not enable combined image samplers"); + + nuint numSamplers = 0; + CombinedImageSampler* combinedImageSamplers = null; + if (cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers) != Result.Success) + throw new Exception($"{cross.CompilerGetCombinedImageSamplers(compiler, &combinedImageSamplers, ref numSamplers)}"); + + for (uint i = 0; i < numSamplers; ++i) + { + var textureName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].ImageId); + var samplerName = cross.CompilerGetNameS(compiler, combinedImageSamplers[i].SamplerId); + cross.CompilerSetName(compiler, combinedImageSamplers[i].CombinedId, $"SPIRV_Cross_Combined{textureName}{samplerName}"); + } } if (cross.CompilerCompile(compiler, &translated) != Result.Success) diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs new file mode 100644 index 0000000000..7efd372f45 --- /dev/null +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -0,0 +1,674 @@ +using CommunityToolkit.HighPerformance; +using Silk.NET.Core.Native; +using Silk.NET.Direct3D.Compilers; +using Silk.NET.Direct3D11; +using Silk.NET.DXGI; +using Silk.NET.Maths; +using Silk.NET.Windowing; +using Stride.Shaders; +using System; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; + +namespace Stride.Shaders.Parsing.Tests; + + + +public class D3D11FrameRenderer(uint width = 800, uint height = 600, byte[]? fragmentSpirv = null, byte[]? vertexSpirv = null) : FrameRenderer(width, height, vertexSpirv, fragmentSpirv) +{ + static IWindow? window; + DXGI dxgi = null!; + D3D11 d3d11 = null!; + D3DCompiler compiler = null!; + + uint width = width; + uint height = height; + + ComPtr factory = default; + ComPtr swapchain = default; + ComPtr device = default; + ComPtr deviceContext = default; + ComPtr vertexBuffer = default; + ComPtr indexBuffer = default; + ComPtr vertexShader = default; + ComPtr pixelShader = default; + ComPtr inputLayout = default; + + byte[]? fragmentSpirv = fragmentSpirv; + + //Vertex shaders are run on each vertex. + public string VertexShaderSource = @" +struct vs_in { + float3 position_local : POSITION; + float2 texcoord : TEXCOORD; +}; + +struct vs_out { + float2 texcoord : TEXCOORD; + float4 position_clip : SV_POSITION; +}; + +vs_out main(vs_in input) { + vs_out output = (vs_out)0; + output.position_clip = float4(input.position_local, 1.0); + output.texcoord = input.texcoord; + return output; +} + "; + + //Fragment shaders are run on each fragment/pixel of the geometry. + public string PixelShaderSource = @" +struct vs_out { + float4 position_clip : SV_POSITION; + float2 texcoord : TEXCOORD; +}; + +float4 main(vs_out input) : SV_TARGET { + return float4( 1.0, 0.5, 0.2, 1.0 ); +} + "; + + //Vertex data, uploaded to the VBO. + private static readonly float[] Vertices = + [ + //X Y Z + 1f, 1f, 0f, 1.0f, 1.0f, + 1f, -1f, 0f, 1.0f, 0.0f, + -1f,-1f, 0f, 0.0f, 0.0f, + -1f, 1f, 1f, 0.0f, 1.0f, + ]; + + //Index data, uploaded to the EBO. + private static readonly uint[] Indices = + [ + 0, 1, 3, + 1, 2, 3 + ]; + + public EffectReflection EffectReflection { get; set; } + + public override unsafe void RenderFrame(Span result) + { + var options = WindowOptions.Default; + options.Size = new Vector2D((int)width, (int)height); + options.IsVisible = false; + options.API = GraphicsAPI.None; + window = Window.Create(options); + window.Initialize(); + + // Source for most of the code: + // https://github.com/dotnet/Silk.NET/blob/main/examples/CSharp/Direct3D11%20Tutorials/Tutorial%201.2%20-%20Hello%20quad/Program.cs + dxgi = DXGI.GetApi(window); + d3d11 = D3D11.GetApi(window); + compiler = D3DCompiler.GetApi(); + + // Create our D3D11 logical device. + SilkMarshal.ThrowHResult + ( + d3d11.CreateDevice + ( + default(ComPtr), + D3DDriverType.Hardware, + Software: default, + (uint)CreateDeviceFlag.Debug, + null, + 0, + D3D11.SdkVersion, + ref device, + null, + ref deviceContext + ) + ); + + if (OperatingSystem.IsWindows()) + { + // Log debug messages for this device (given that we've enabled the debug flag). Don't do this in release code! + device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint)msg.PDescription))); + } + + // Create our swapchain. + var swapChainDesc = new SwapChainDesc1 + { + BufferCount = 2, // double buffered + Format = Format.FormatR8G8B8A8Unorm, + BufferUsage = DXGI.UsageRenderTargetOutput, + SwapEffect = SwapEffect.FlipDiscard, + SampleDesc = new SampleDesc(1, 0) + }; + + // Create our DXGI factory to allow us to create a swapchain. + factory = dxgi.CreateDXGIFactory(); + + // Create the swapchain. + SilkMarshal.ThrowHResult + ( + factory.CreateSwapChainForHwnd + ( + device, + window.Native!.DXHandle!.Value, + in swapChainDesc, + null, + ref Unsafe.NullRef(), + ref swapchain + ) + ); + + // Create our vertex buffer. + var bufferDesc = new BufferDesc + { + ByteWidth = (uint)(Vertices.Length * sizeof(float)), + Usage = Usage.Default, + BindFlags = (uint)BindFlag.VertexBuffer, + }; + + fixed (float* vertexData = Vertices) + { + var subresourceData = new SubresourceData + { + PSysMem = vertexData + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBuffer)); + } + + // Create our index buffer. + bufferDesc = new BufferDesc + { + ByteWidth = (uint)(Indices.Length * sizeof(uint)), + Usage = Usage.Default, + BindFlags = (uint)BindFlag.IndexBuffer, + }; + + fixed (uint* indexData = Indices) + { + var subresourceData = new SubresourceData + { + PSysMem = indexData + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref indexBuffer)); + } + + var vertexShaderBytes = Encoding.ASCII.GetBytes(VertexShaderSource); + var pixelShaderBytes = Encoding.ASCII.GetBytes(PixelShaderSource); + + // Compile vertex shader. + ComPtr vertexCode = default; + ComPtr vertexErrors = default; + HResult hr = compiler.Compile + ( + in vertexShaderBytes[0], + (nuint)vertexShaderBytes.Length, + nameof(VertexShaderSource), + null, + ref Unsafe.NullRef(), + "main", + "vs_5_0", + 0, + 0, + ref vertexCode, + ref vertexErrors + ); + + // Check for compilation errors. + if (hr.IsFailure) + { + if (vertexErrors.Handle is not null) + { + Console.WriteLine(SilkMarshal.PtrToString((nint)vertexErrors.GetBufferPointer())); + } + + hr.Throw(); + } + + // Compile pixel shader. + ComPtr pixelCode = default; + ComPtr pixelErrors = default; + hr = compiler.Compile + ( + in pixelShaderBytes[0], + (nuint)pixelShaderBytes.Length, + nameof(PixelShaderSource), + null, + ref Unsafe.NullRef(), + "main", + "ps_5_0", + 0, + 0, + ref pixelCode, + ref pixelErrors + ); + + // Check for compilation errors. + if (hr.IsFailure) + { + if (pixelErrors.Handle is not null) + { + Console.WriteLine(SilkMarshal.PtrToString((nint)pixelErrors.GetBufferPointer())); + } + + hr.Throw(); + } + + // Create vertex shader. + SilkMarshal.ThrowHResult + ( + device.CreateVertexShader + ( + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref vertexShader + ) + ); + + // Create pixel shader. + SilkMarshal.ThrowHResult + ( + device.CreatePixelShader + ( + pixelCode.GetBufferPointer(), + pixelCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref pixelShader + ) + ); + + // Describe the layout of the input data for the shader. + fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) + fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) + { + var inputElements = new List + { + new() + { + SemanticName = pos, + SemanticIndex = 0, + Format = Format.FormatR32G32B32Float, + InputSlot = 0, + AlignedByteOffset = 0, + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + }, + new() + { + SemanticName = texcoord, + SemanticIndex = 0, // TEXCOORD0 + Format = Format.FormatR32G32Float, + InputSlot = 0, + AlignedByteOffset = uint.MaxValue, // AUTO + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + } + }; + + // Keep in memory (even if GC) until call to CreateInputLayout + var streamSemanticNamesMemory = new List(); + + // Start at input slot 1 (0 is standard vertex data) + uint inputSlot = 1; + foreach (var parameter in Parameters) + { + if (parameter.Key.StartsWith("stream.")) + { + var streamSemanticName = parameter.Key.Substring("stream.".Length); + + var streamSemanticNameMemory = SilkMarshal.StringToMemory(streamSemanticName); + streamSemanticNamesMemory.Add(streamSemanticNameMemory); + + inputElements.Add(new InputElementDesc + { + SemanticName = (byte*)streamSemanticNameMemory, + SemanticIndex = 0, + Format = Format.FormatR32G32B32A32Float, + InputSlot = inputSlot, + AlignedByteOffset = 0, + InputSlotClass = InputClassification.PerInstanceData, + InstanceDataStepRate = 0, + }); + + // Also create the vertex and bind it right away + var floatValues = parameter.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries).Select(x => float.Parse(x)).ToArray(); + bufferDesc = new BufferDesc + { + ByteWidth = (uint)(sizeof(float) * floatValues.Length), // up to 4 floats + Usage = Usage.Default, + BindFlags = (uint)BindFlag.VertexBuffer, + }; + + ComPtr vertexBufferForStream = default; + fixed (float* floatValuesPtr = floatValues) + { + var subresourceData = new SubresourceData + { + PSysMem = floatValuesPtr + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBufferForStream)); + } + + deviceContext.IASetVertexBuffers(inputSlot, 1, vertexBufferForStream, 0, 0); + inputSlot++; + } + } + + fixed (InputElementDesc* inputElementsPtr = inputElements.AsSpan()) + SilkMarshal.ThrowHResult + ( + device.CreateInputLayout + ( + inputElementsPtr, + (uint)inputElements.Count, + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref inputLayout + ) + ); + } + + // Clean up any resources. + vertexCode.Dispose(); + vertexErrors.Dispose(); + pixelCode.Dispose(); + pixelErrors.Dispose(); + + ComPtr renderTexture = default; + ComPtr renderTextureStaging = default; + + var textureDesc = new Texture2DDesc + { + Width = width, + Height = height, + Format = Format.FormatR8G8B8A8Unorm, + MipLevels = 1, + BindFlags = (uint)(BindFlag.ShaderResource | BindFlag.RenderTarget), + Usage = Usage.Default, + CPUAccessFlags = 0, + MiscFlags = (uint)ResourceMiscFlag.None, + SampleDesc = new SampleDesc(1, 0), + ArraySize = 1 + }; + + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D + ( + in textureDesc, + default, + ref renderTexture + ) + ); + + textureDesc.BindFlags = 0; + textureDesc.Usage = Usage.Staging; + textureDesc.CPUAccessFlags = (uint)CpuAccessFlag.Read; + + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D + ( + in textureDesc, + default, + ref renderTextureStaging + ) + ); + + // Create a view over the render target. + ComPtr renderTargetView = default; + SilkMarshal.ThrowHResult(device.CreateRenderTargetView(renderTexture, null, ref renderTargetView)); + + // Clear the render target to be all black ahead of rendering. + var backgroundColour = new[] { 0.0f, 0.0f, 0.0f, 1.0f }; + deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]); + + // Update the rasterizer state with the current viewport. + var viewport = new Viewport(0, 0, width, height, 0, 1); + deviceContext.RSSetViewports(1, in viewport); + deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); + + // Update the input assembler to use our shader input layout, and associated vertex & index buffers. + deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); + deviceContext.IASetInputLayout(inputLayout); + deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); + deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); + + // Bind our shaders. + deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); + deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); + + foreach (var param in Parameters) + { + var dotIndex = param.Key.IndexOf("."); + if (dotIndex == -1) + continue; + + var resourceType = param.Key.Substring(0, dotIndex); + if (resourceType != "cbuffer" && resourceType != "texture" && resourceType != "buffer") + continue; + + var resourceName = param.Key.Substring(dotIndex + 1); + var resourceReflection = EffectReflection.ResourceBindings.Single(x => x.RawName == resourceName); + + if (resourceType == "cbuffer") + { + var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == resourceName); + var cbufferData = new byte[cbReflection.Size]; + foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) + { + var cbMemberReflection = cbReflection.Members.Single(x => x.KeyInfo.KeyName.EndsWith(cbufferParameter.Key)); + + fixed (byte* cbufferDataPtr = cbufferData) + { + FillData(cbufferParameter.Value, cbMemberReflection.Type, cbMemberReflection.Offset, cbufferDataPtr); + } + } + + // Create cbuffer + // Create our vertex buffer. + ComPtr cbuffer = default; + bufferDesc = new BufferDesc + { + ByteWidth = (uint)cbReflection.Size, + Usage = Usage.Default, + BindFlags = (uint)BindFlag.ConstantBuffer, + }; + + fixed (byte* cbufferDataPtr = cbufferData) + { + var subresourceData = new SubresourceData + { + PSysMem = cbufferDataPtr + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref cbuffer)); + } + deviceContext.VSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); + deviceContext.PSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); + } + else if (resourceType == "buffer") + { + var color = ParseColor(param.Value); + + // Create cbuffer + // Create our vertex buffer. + ComPtr buffer = default; + bufferDesc = new BufferDesc + { + ByteWidth = sizeof(uint), + Usage = Usage.Default, + BindFlags = (uint)BindFlag.ShaderResource, + StructureByteStride = sizeof(uint), + }; + + { + var subresourceData = new SubresourceData + { + PSysMem = (byte*)&color, + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref buffer)); + } + + // Create a view of the texture for the shader. + ComPtr bufferSRV = default; + var srvDesc = new ShaderResourceViewDesc + { + Format = Format.FormatR8G8B8A8Unorm, + ViewDimension = D3DSrvDimension.D3DSrvDimensionBuffer, + Anonymous = new ShaderResourceViewDescUnion + { + Buffer = new() + { + NumElements = 1, + FirstElement = 0, + } + }, + }; + + SilkMarshal.ThrowHResult + ( + device.CreateShaderResourceView + ( + buffer, + in srvDesc, + ref bufferSRV + ) + ); + + deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); + deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); + } + else if (resourceType == "texture") + { + var color = ParseColor(param.Value); + + textureDesc = new Texture2DDesc + { + Width = 1, + Height = 1, + Format = Format.FormatR8G8B8A8Unorm, + MipLevels = 1, + BindFlags = (uint)BindFlag.ShaderResource, + Usage = Usage.Default, + CPUAccessFlags = 0, + MiscFlags = (uint)ResourceMiscFlag.None, + SampleDesc = new SampleDesc(1, 0), + ArraySize = 1 + }; + + var subresourceData = new SubresourceData + { + PSysMem = &color, + SysMemPitch = sizeof(int) * 1, + SysMemSlicePitch = sizeof(int) * 1 * 1, + }; + + ComPtr texture = default; + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D + ( + in textureDesc, + in subresourceData, + ref texture + ) + ); + + // Create a view of the texture for the shader. + ComPtr textureSRV = default; + var srvDesc = new ShaderResourceViewDesc + { + Format = Format.FormatR8G8B8A8Unorm, + ViewDimension = D3DSrvDimension.D3DSrvDimensionTexture2D, + Anonymous = new ShaderResourceViewDescUnion + { + Texture2D = new() + { + MipLevels = 1, + MostDetailedMip = 0, + } + }, + }; + + SilkMarshal.ThrowHResult + ( + device.CreateShaderResourceView + ( + texture, + in srvDesc, + ref textureSRV + ) + ); + + deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); + deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); + } + } + + // Draw the quad. + deviceContext.DrawIndexed(6, 0, 0); + + deviceContext.CopyResource(renderTextureStaging, renderTexture); + + MappedSubresource mappedResource = default; + deviceContext.Map(renderTextureStaging, 0, Map.MapRead, 0, ref mappedResource); + var span = new Span(mappedResource.PData, (int)(width * height * 4)); + span.CopyTo(result); + deviceContext.Unmap(renderTextureStaging, 0); + + // Still do a copy to backbuffer and present, for debugging purpose (i.e. if we run RenderDoc or such debug tools) + var framebuffer = swapchain.GetBuffer(0); + + deviceContext.CopySubresourceRegion(framebuffer, 0, 0, 0, 0, renderTexture, 0, null); + + // Present the drawn image. + swapchain.Present(1, 0); + + renderTextureStaging.Dispose(); + renderTexture.Dispose(); + + renderTargetView.Dispose(); + + framebuffer.Dispose(); + + window.Close(); + window.Dispose(); + + } + + private static unsafe void FillData(string value, EffectTypeDescription type, int offset, byte* cbufferDataPtr) + { + switch (type) + { + case { Elements: > 1 }: + int index = 0; + var arrayStride = (type.ElementSize + 15) / 16 * 16; + foreach (var elementValue in TestHeaderParser.SplitArgs(value)) + { + FillData(elementValue, type with { Elements = 1 }, offset + arrayStride * index, cbufferDataPtr); + index++; + } + break; + case { Class: EffectParameterClass.Struct }: + var structParameters = TestHeaderParser.ParseParameters(value); + foreach (var member in type.Members) + { + if (structParameters.TryGetValue(member.Name, out var memberValue)) + FillData(memberValue, member.Type, offset + member.Offset, cbufferDataPtr); + } + break; + case { Type: EffectParameterType.Int }: + *((int*)&cbufferDataPtr[offset]) = int.Parse(value); + break; + case { Type: EffectParameterType.Float }: + *((float*)&cbufferDataPtr[offset]) = float.Parse(value); + break; + default: + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index ffc659e5a8..c7b4c10eee 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -42,7 +42,7 @@ void main() "; //Fragment shaders are run on each fragment/pixel of the geometry. - public string FragmentShaderSource = @" + public string PixelShaderSource = @" #version 330 core out vec4 FragColor; @@ -112,7 +112,7 @@ public override unsafe void RenderFrame(Span result) Gl.BindBuffer(BufferTargetARB.ArrayBuffer, Vbo); //Binding the buffer. fixed (void* v = &Vertices[0]) { - Gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(Vertices.Length * sizeof(uint)), v, BufferUsageARB.StaticDraw); //Setting buffer data. + Gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(Vertices.Length * sizeof(float)), v, BufferUsageARB.StaticDraw); //Setting buffer data. } //Initializing a element buffer that holds the index data. @@ -150,7 +150,7 @@ public override unsafe void RenderFrame(Span result) } else { - Gl.ShaderSource(fragmentShader, FragmentShaderSource); + Gl.ShaderSource(fragmentShader, PixelShaderSource); Gl.CompileShader(fragmentShader); } @@ -203,6 +203,7 @@ public override unsafe void RenderFrame(Span result) continue; var paramName = param.Key.Substring("stream.".Length); + // TODO: need to scan for semantic name? attribName = attribName.Substring("in_VS_".Length); if (paramName == attribName) @@ -231,15 +232,24 @@ public override unsafe void RenderFrame(Span result) int bufferCount = 0; foreach (var param in Parameters) { - if (param.Key.StartsWith("cbuffer.")) + var dotIndex = param.Key.IndexOf("."); + if (dotIndex == -1) + continue; + + var resourceType = param.Key.Substring(0, dotIndex); + if (resourceType != "cbuffer" && resourceType != "texture" && resourceType != "buffer") + continue; + + var resourceName = param.Key.Substring(dotIndex + 1); + + if (resourceType == "cbuffer") { - var cbufferName = param.Key.Substring("cbuffer.".Length); - var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{cbufferName}"); + var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{resourceName}"); if ((GLEnum)blockIndex == GLEnum.InvalidIndex) continue; Gl.UniformBlockBinding(Shader, blockIndex, 0); - var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == cbufferName); + var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == resourceName); var cbufferData = new byte[cbReflection.Size]; foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) { @@ -247,7 +257,7 @@ public override unsafe void RenderFrame(Span result) fixed (byte* cbufferDataPtr = cbufferData) { - FillData(cbufferParameter.Value, cbMemberReflection.Type, cbMemberReflection.Offset, cbufferDataPtr); + FillCBufferData(cbufferParameter.Value, cbMemberReflection.Type, cbMemberReflection.Offset, cbufferDataPtr); } } @@ -258,56 +268,37 @@ public override unsafe void RenderFrame(Span result) Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); } - else if (param.Key.StartsWith("texture.")) + else if (resourceType == "texture") { - if (!param.Value.StartsWith("#")) - throw new NotSupportedException(); - - var textureName = param.Key.Substring("texture.".Length); + var color = ParseColor(param.Value); - var index = Gl.GetProgramResourceIndex(Shader, GLEnum.Uniform, textureName); + var index = Gl.GetProgramResourceIndex(Shader, GLEnum.Uniform, resourceName); GLEnum type; var requestedProps = GLEnum.Type; Gl.GetProgramResource(Shader, GLEnum.Uniform, 0, 1, &requestedProps, 1, null, (int*)&type); - var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, textureName); + var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, resourceName); if (location == -1) - throw new InvalidOperationException($"Could not find resource {textureName}"); + throw new InvalidOperationException($"Could not find resource {resourceName}"); var texture = Gl.GenTexture(); Gl.BindTexture(GLEnum.Texture2D, texture); - var hexColor = param.Value.Substring(1); - uint color = uint.Parse(hexColor.Substring(0, 8), NumberStyles.HexNumber); - color = (((color << 24) & 0xff000000) | - ((color << 8) & 0xff0000) | - ((color >> 8) & 0xff00) | - ((color >> 24) & 0xff)); - Gl.TexImage2D(GLEnum.Texture2D, 0, (int)GLEnum.Rgba, 1, 1, 0, GLEnum.Rgba, GLEnum.UnsignedByte, (void*)&color); Gl.ProgramUniform1(Shader, location, texture); } - else if (param.Key.StartsWith("buffer.")) + else if (resourceType == "buffer") { - if (!param.Value.StartsWith("#")) - throw new NotSupportedException(); + var color = ParseColor(param.Value); - var bufferName = param.Key.Substring("buffer.".Length); - var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, bufferName); + var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, resourceName); if (location == -1) - throw new InvalidOperationException($"Could not find resource {bufferName}"); + throw new InvalidOperationException($"Could not find resource {resourceName}"); var buffer = Gl.GenBuffer(); Gl.BindBuffer(BufferTargetARB.TextureBuffer, buffer); - var hexColor = param.Value.Substring(1); - uint color = uint.Parse(hexColor.Substring(0, 8), NumberStyles.HexNumber); - color = (((color << 24) & 0xff000000) | - ((color << 8) & 0xff0000) | - ((color >> 8) & 0xff00) | - ((color >> 24) & 0xff)); - Gl.BufferData(BufferTargetARB.TextureBuffer, sizeof(uint), (void*)&color, BufferUsageARB.StaticDraw); var texture = Gl.GenTexture(); @@ -338,38 +329,5 @@ public override unsafe void RenderFrame(Span result) window.SwapBuffers(); window.Close(); window.Dispose(); - - } - - private static unsafe void FillData(string value, EffectTypeDescription type, int offset, byte* cbufferDataPtr) - { - switch (type) - { - case { Elements: > 1 }: - int index = 0; - var arrayStride = (type.ElementSize + 15) / 16 * 16; - foreach (var elementValue in TestHeaderParser.SplitArgs(value)) - { - FillData(elementValue, type with { Elements = 1 }, offset + arrayStride * index, cbufferDataPtr); - index++; - } - break; - case { Class: EffectParameterClass.Struct }: - var structParameters = TestHeaderParser.ParseParameters(value); - foreach (var member in type.Members) - { - if (structParameters.TryGetValue(member.Name, out var memberValue)) - FillData(memberValue, member.Type, offset + member.Offset, cbufferDataPtr); - } - break; - case { Type: EffectParameterType.Int }: - *((int*)&cbufferDataPtr[offset]) = int.Parse(value); - break; - case { Type: EffectParameterType.Float }: - *((float*)&cbufferDataPtr[offset]) = float.Parse(value); - break; - default: - throw new NotImplementedException(); - } } } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/FrameRenderer.cs b/src/Stride.Shaders.Tests/FrameRenderer.cs index fc6fc7d142..97be4e8d84 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.cs @@ -1,3 +1,5 @@ +using System.Globalization; + namespace Stride.Shaders.Parsing.Tests; public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? vertexSpirv = null, byte[]? fragmentSpirv = null) @@ -9,5 +11,51 @@ public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? public Dictionary Parameters { get; } = new(); + protected static unsafe void FillCBufferData(string value, EffectTypeDescription type, int offset, byte* cbufferDataPtr) + { + switch (type) + { + case { Elements: > 1 }: + int index = 0; + var arrayStride = (type.ElementSize + 15) / 16 * 16; + foreach (var elementValue in TestHeaderParser.SplitArgs(value)) + { + FillCBufferData(elementValue, type with { Elements = 1 }, offset + arrayStride * index, cbufferDataPtr); + index++; + } + break; + case { Class: EffectParameterClass.Struct }: + var structParameters = TestHeaderParser.ParseParameters(value); + foreach (var member in type.Members) + { + if (structParameters.TryGetValue(member.Name, out var memberValue)) + FillCBufferData(memberValue, member.Type, offset + member.Offset, cbufferDataPtr); + } + break; + case { Type: EffectParameterType.Int }: + *((int*)&cbufferDataPtr[offset]) = int.Parse(value); + break; + case { Type: EffectParameterType.Float }: + *((float*)&cbufferDataPtr[offset]) = float.Parse(value); + break; + default: + throw new NotImplementedException(); + } + } + + protected static unsafe uint ParseColor(string value) + { + if (!value.StartsWith("#")) + throw new NotSupportedException(); + + var hexColor = value.Substring(1); + uint color = uint.Parse(hexColor.Substring(0, 8), NumberStyles.HexNumber); + color = (((color << 24) & 0xff000000) | + ((color << 8) & 0xff0000) | + ((color >> 8) & 0xff00) | + ((color >> 24) & 0xff)); + return color; + } + public abstract void RenderFrame(Span bytes); } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/Program.cs b/src/Stride.Shaders.Tests/Program.cs index efbe01f782..1dde504f7d 100644 --- a/src/Stride.Shaders.Tests/Program.cs +++ b/src/Stride.Shaders.Tests/Program.cs @@ -2,4 +2,4 @@ [assembly: CaptureConsole] -//new RenderingTests().RenderTest1("GenericsFloat", "PSMain", "ExpectedResult=#FFFFFFFF"); \ No newline at end of file +//new RenderingTests().RenderTest1("SimpleInheritance"); \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 93fdd5d36f..322836dd65 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -75,9 +75,9 @@ public void RenderTest1(string shaderName) // Convert to GLSL var translator = new SpirvTranslator(bytecode.AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); - var codePS = translator.Translate(Backend.Glsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); + var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) - ? translator.Translate(Backend.Glsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) : null; if (codeVS != null) @@ -85,7 +85,7 @@ public void RenderTest1(string shaderName) Console.WriteLine(codePS); // Execute test - var renderer = new OpenGLFrameRenderer((uint)width, (uint)height); + var renderer = new D3D11FrameRenderer((uint)width, (uint)height); var code = File.ReadAllLines($"./assets/SDSL/RenderTests/{shaderName}.sdsl"); foreach (var test in TestHeaderParser.ParseHeaders(code)) @@ -97,7 +97,7 @@ public void RenderTest1(string shaderName) foreach (var param in parameters) renderer.Parameters.Add(param.Key, param.Value); - renderer.FragmentShaderSource = codePS; + renderer.PixelShaderSource = codePS; if (codeVS != null) renderer.VertexShaderSource = codeVS; using var frameBuffer = MemoryOwner.Allocate(width * height * 4); From 953a20155d3f10a63c18259ba26b1e1e16dc6707 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 18 Dec 2025 20:34:54 +0900 Subject: [PATCH 0610/1182] Stop deduplicating struct (instead, share it as a "stage" type and dedup name for cbuffer ones) --- .../SDSL/ShaderMixer.cs | 61 +++++++++++++------ .../Parsing/SDSL/AST/ShaderElements.cs | 20 +++++- .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 2c7680e34a..6442f29d69 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -208,7 +208,7 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo bool isContext = true; - bool ProcessStageMember(int memberId, bool isStage) + bool ProcessStageMemberOrType(int memberId, bool isStage) { var include = isStage switch { @@ -223,10 +223,12 @@ bool ProcessStageMember(int memberId, bool isStage) if (isStage && !isRootMixin) { var stageShader = mixinNode.Stage.ShadersByName[shaderClass.ToClassName()]; - var memberName = names[memberId]; - var stageMember = stageShader.FindMember(memberName); - remapIds.Add(offset + memberId, stageMember.Id); - removedIds.Add(stageMember.Id); + var memberOrTypeName = names[memberId]; + var stageMemberOrTypeId = stageShader.StructTypes.TryGetValue(memberOrTypeName, out var structTypeId) + ? structTypeId + : stageShader.FindMember(memberOrTypeName).Id; + remapIds.Add(offset + memberId, stageMemberOrTypeId); + removedIds.Add(stageMemberOrTypeId); } // Otherwise, if not included, it means we need to forbid this IDs (which could only happen if referencing non-stage member from a stage method) else if (!include) @@ -257,12 +259,16 @@ bool ProcessStageMember(int memberId, bool isStage) if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - include = ProcessStageMember(function.ResultId, isStage); + include = ProcessStageMemberOrType(function.ResultId, isStage); } if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) { var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; - include = ProcessStageMember(variableInstruction.ResultId, isStage); + include = ProcessStageMemberOrType(variableInstruction.ResultId, isStage); + } + if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) + { + include = ProcessStageMemberOrType(typeStruct.ResultId, true); } if (!include) @@ -320,7 +326,6 @@ bool ProcessStageMember(int memberId, bool isStage) || i2.Op == Op.OpTypeMatrix || i2.Op == Op.OpTypeArray || i2.Op == Op.OpTypeRuntimeArray - || i2.Op == Op.OpTypeStruct || i2.Op == Op.OpTypePointer || i2.Op == Op.OpTypeFunction || i2.Op == Op.OpTypeImage @@ -336,7 +341,9 @@ bool ProcessStageMember(int memberId, bool isStage) { var shaderName = globalContext.ExternalShaders[importStruct.Shader]; var shader2 = mixinNode.ShadersByName[shaderName]; - var structId = shader2.StructTypes[importStruct.StructName]; + if (!shader2.StructTypes.TryGetValue(importStruct.StructName, out var structId) + && (shader2.Stage == null || !shader2.Stage.StructTypes.TryGetValue(importStruct.StructName, out structId))) + throw new InvalidOperationException($"Struct {importStruct.StructName} not found in shader {shaderName}"); remapIds.Add(importStruct.ResultId, structId); removedIds.Add(structId); } @@ -355,16 +362,6 @@ bool ProcessStageMember(int memberId, bool isStage) { addToContext = true; } - - // OpTypeStruct is the only type that can be defined by the shader. - // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. - if (i2.Op == Op.OpTypeStruct && (OpTypeStruct)i2 is { } typeStruct) - { - var structName = names[typeStruct.ResultId - offset]; - if (!remapIds.TryGetValue(typeStruct.ResultId, out var structId)) - structId = typeStruct.ResultId; - structTypes.Add(structName, structId); - } } } // Does this belong in context or buffer? @@ -377,6 +374,16 @@ bool ProcessStageMember(int memberId, bool isStage) buffer.Add(i2); } + // OpTypeStruct is the only type that can be defined by the shader. + // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. + if (i2.Op == Op.OpTypeStruct && (OpTypeStruct)i2 is { } typeStruct2) + { + var structName = names[typeStruct2.ResultId - offset]; + if (!remapIds.TryGetValue(typeStruct2.ResultId, out var structId)) + structId = typeStruct2.ResultId; + structTypes.Add(structName, structId); + } + // Process OpSDSLImport ProcessImportInfo(globalContext, mixinNode, i2, context.GetBuffer()); @@ -870,6 +877,22 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon srvSlot++; } + else if (pointerType.BaseType is BufferType) + { + var slot = globalContext.Reflection.ResourceBindings.Count; + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ShaderResourceView, + Type = EffectParameterType.Buffer, + SlotStart = srvSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + + srvSlot++; + } else if (pointerType.BaseType is SamplerType) { globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 2d4b6696a2..c8d7acb8c4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -5,6 +5,7 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using System; +using System.Collections.Generic; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -196,8 +197,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) fields.Add((smem.Name, smem.Type, smem.TypeModifier)); } - Type = new StructType(TypeName.ToString() ?? "", fields); - table.DeclaredTypes.TryAdd(TypeName.ToString(), Type); + Type = new StructType(TypeName.ToString(), fields); + table.DeclaredTypes.Add(TypeName.ToString(), Type); } public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) @@ -258,7 +259,20 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; - context.DeclareCBuffer((ConstantBufferSymbol)Type); + + var constantBufferType = (ConstantBufferSymbol)Type; + + // We try to avoid clash in case multiple cbuffer with same name + int tryCount = 0; + var typeName = constantBufferType.Name; + while (!table.DeclaredTypes.TryAdd(constantBufferType.ToId(), Type)) + { + typeName = $"{typeName}_{++tryCount}"; + constantBufferType = constantBufferType with { Name = typeName }; + } + Type = constantBufferType; + + context.DeclareCBuffer(constantBufferType); var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index c3d8297acf..0b8c33e774 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -91,7 +91,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray - || x.Op == Op.OpTypeStruct + //|| x.Op == Op.OpTypeStruct || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler || x.Op == Op.OpTypeGenericLinkSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) From 0b310286d550d8c890ac7ed9f67195a1c8bf5262 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 18 Dec 2025 20:35:42 +0900 Subject: [PATCH 0611/1182] Improved the ShaderLoader.Exists() to check the cache --- src/Stride.Shaders.Experiments/Examples.cs | 4 ++-- src/Stride.Shaders.Experiments/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 4 ++-- src/Stride.Shaders/Spirv/Building/Context.cs | 12 ++++++++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 59667a2bd8..7b90aad3e3 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -210,13 +210,13 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) public class ShaderLoader : ShaderLoaderBase { - public override bool Exists(string name) + protected override bool ExternalFileExists(string name) { var filename = $"./assets/SDSL/{name}.sdsl"; return File.Exists(filename); } - public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + protected override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/{name}.sdsl"; if (!File.Exists(filename)) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index beb0c1c817..896048b31d 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -13,7 +13,7 @@ //Examples.CompileSDSL(); var loader = new Examples.ShaderLoader(); -loader.LoadExternalFile("Test", [], out var testBuffer); +loader.LoadExternalBuffer("Test", [], out var testBuffer, out _); var shaderMixer = new ShaderMixer(loader); shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _); var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 322836dd65..883de97cd2 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -29,13 +29,13 @@ public class RenderingTests class ShaderLoader : ShaderLoaderBase { - public override bool Exists(string name) + protected override bool ExternalFileExists(string name) { var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; return File.Exists(filename); } - public override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + protected override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) { var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; if (!File.Exists(filename)) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 98538a5b9c..e2e08548bf 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -29,8 +29,16 @@ public void RegisterShader(string name, ReadOnlySpan defines, NewSp loadedShaders.Add(name, buffer); } - public abstract bool Exists(string name); - public abstract bool LoadExternalFile(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); + public bool Exists(string name) + { + if (loadedShaders.ContainsKey(name)) + return true; + + return ExternalFileExists(name); + } + + protected abstract bool ExternalFileExists(string name); + protected abstract bool LoadExternalFile(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) { From 167459941a02a42471efc28829c849b2baba50c8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 18 Dec 2025 20:55:48 +0900 Subject: [PATCH 0612/1182] Array: try to keep size expression (even if we could compute a size) to differentiate types --- src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 13 ++++++++++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index bae6ecb1f8..3356f7c496 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -68,6 +68,11 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { + public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + { + return context.CompileConstantLiteral(this); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); @@ -409,12 +414,14 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { if (arraySize is EmptyExpression) symbolType = new ArrayType(symbolType, -1); - else if (arraySize is IntegerLiteral i) - symbolType = new ArrayType(symbolType, (int)i.Value); else { + var arrayComputedSize = -1; + if (arraySize is IntegerLiteral i) + arrayComputedSize = (int)i.Value; + var constantArraySize = arraySize.CompileConstantValue(table, context); - symbolType = new ArrayType(symbolType, -1, constantArraySize.Id); + symbolType = new ArrayType(symbolType, arrayComputedSize, constantArraySize.Id); } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 60b12d57af..e4ce391489 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -145,7 +145,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var innerType = types[typeArray.ElementType]; if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, buffer)) { - types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); + types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject, typeArray.Length)); } else { From 1631d5f6cd36f11740e33027a8d11484660065f0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Dec 2025 11:58:30 +0900 Subject: [PATCH 0613/1182] Change how external shaders are imported to properly use cache --- .../CompositionExternalStruct.sdsl | 5 +- .../Parsing/SDSL/AST/Literals.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 57 ++++++++++++++----- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl index c820f30db8..effbb4e036 100644 --- a/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl +++ b/assets/SDSL/RenderTests/CompositionExternalStruct.sdsl @@ -8,7 +8,10 @@ shader CompositionStruct { float A; } +} +shader CompositionBase2 : CompositionStruct +{ // Use struct as a parameter float ExtractValue(Test1 t) { @@ -16,7 +19,7 @@ shader CompositionStruct } } -shader CompositionBase : CompositionStruct +shader CompositionBase : CompositionStruct, CompositionBase2 { cbuffer PerView { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 3356f7c496..7b764e3433 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -272,7 +272,7 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref i classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile, buffer); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { - table.InheritedShaders[i].Symbol = ShaderClass.LoadExternalShaderType(table, table.InheritedShaders[i]); + table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, table.InheritedShaders[i]); ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index e4ce391489..a9ba99a175 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -52,6 +52,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types, IShaderImporter? shaderImporter = null) { var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); + var importedShaders = new Dictionary(); var memberNames = new Dictionary<(int, int), string>(); var blocks = new HashSet(); @@ -215,7 +216,15 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) { - types.Add(importStruct.ResultId, new StructType(importStruct.StructName, [])); + var shaderSymbol = (ShaderSymbol)types[importStruct.Shader]; + if (shaderSymbol is LoadedShaderSymbol loadedShaderSymbol) + { + types.Add(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == importStruct.StructName).Type); + } + else + { + types.Add(importStruct.ResultId, new StructType(importStruct.StructName, [])); + } } } @@ -240,16 +249,7 @@ public class ShaderImporter(SymbolTable table) : IShaderImporter { public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) { - // Already processed? - if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) - return (ShaderSymbol)symbolType; - - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, buffer); - classSource.Buffer = shader; - var shaderType = LoadExternalShaderType(table, classSource); - table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); - - return shaderType; + return LoadAndCacheExternalShaderType(table, classSource, buffer); } } @@ -310,7 +310,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBu private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) { - //table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); + table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); } public void Compile(SymbolTable table, CompilerUnit compiler) @@ -365,7 +365,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { - shaderSymbols.Add(mixin.Symbol = LoadExternalShaderType(table, mixin)); + shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderType(table, mixin)); } foreach (var shaderType in shaderSymbols) @@ -401,8 +401,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context.GetBuffer()); classSource.Buffer = shader; - var shaderType = LoadExternalShaderType(table, classSource); - table.DeclaredTypes.TryAdd(shaderType.ToClassName(), shaderType); + var shaderType = LoadAndCacheExternalShaderType(table, classSource, context.GetBuffer()); // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) memberType = svar.TypeName.ResolveType(table, context); @@ -491,6 +490,34 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader context.Add(new OpSDSLMixinInherit(shaderId)); } + public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) + { + // Already processed? + if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) + return (LoadedShaderSymbol)symbolType; + + if (classSource.Buffer == null) + throw new InvalidOperationException($"{nameof(classSource)}.{nameof(classSource.Buffer)} need to be set"); + + var shaderType = LoadExternalShaderType(table, classSource); + return shaderType; + } + + public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource, NewSpirvBuffer parentBuffer) + { + // Already processed? + if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) + return (LoadedShaderSymbol)symbolType; + + if (classSource.Buffer == null) + { + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, parentBuffer); + classSource.Buffer = shader; + } + var shaderType = LoadExternalShaderType(table, classSource); + return shaderType; + } + public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) { var shaderBuffer = classSource.Buffer; From cb3da9083a5149d1dc78c379bd8291318fea9091 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Dec 2025 16:48:25 +0900 Subject: [PATCH 0614/1182] Streams: allow multiple OpAccessChain on same variable --- src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index b51b39c6f5..d78ecfe941 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -426,7 +426,7 @@ private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, // Map the pointer access as access to the underlying stream (if any) // i.e., streams.A.B will share same streamInfo as streams.A // TODO: what happens in case of partial write? - streams.Add(accessChain.ResultId, (streamInfo.Stream, false)); + streams.TryAdd(accessChain.ResultId, (streamInfo.Stream, false)); } } else if (instruction.Op == Op.OpFunctionCall && (OpFunctionCall)instruction is { } call) From fef087d119555d8de13fffc6f7d23f28d6800f95 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Dec 2025 16:52:10 +0900 Subject: [PATCH 0615/1182] Added missing IsNullOrEmpty extension method --- .../Core/EnumerableExtensions.cs | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs diff --git a/src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs b/src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs new file mode 100644 index 0000000000..5db8f6dfa6 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs @@ -0,0 +1,168 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections; +using System.Diagnostics.Contracts; + +namespace Stride.Core.Extensions; + +public static class EnumerableExtensions +{ + /// + /// Tells whether a sequence is null or empty. + /// + /// The source sequence. + /// Returns true if the sequence is null or empty, false if it is not null and contains at least one element. + [Pure] + public static bool IsNullOrEmpty(this IEnumerable source) + { + if (source == null) + return true; + + var enumerator = source.GetEnumerator() ?? throw new ArgumentException("Invalid 'source' IEnumerable."); + return enumerator.MoveNext() == false; + } + + /// + /// Executes an action for each (casted) item of the given enumerable. + /// + /// Type of the item value in the enumerable. + /// Input enumerable to work on. + /// Action performed for each item in the enumerable. + /// This extension method do not yield. It acts just like a foreach statement, and performs a cast to a typed enumerable in the middle. + public static void ForEach(this IEnumerable source, Action action) + { + source.Cast().ForEach(action); + } + + /// + /// Executes an action for each item of the given enumerable. + /// + /// Type of the item value in the enumerable. + /// Input enumerable to work on. + /// Action performed for each item in the enumerable. + /// This extension method do not yield. It acts just like a foreach statement. + public static void ForEach(this IEnumerable source, Action action) + { + foreach (var item in source) + { + action(item); + } + } + + /// + /// An extension method that searches for the first match and returns its index. + /// + /// Generic type parameter. + /// Input enumerable to work on. + /// The predicate. + /// The index of the first element matching. + [Pure] + public static int IndexOf(this IEnumerable source, Func predicate) + { + var index = 0; + foreach (var item in source) + { + if (predicate(item)) + return index; + index++; + } + return -1; + } + + /// + /// An extension method that searches for the last match and returns its index. + /// + /// Generic type parameter. + /// Input enumerable to work on. + /// The predicate. + /// The index of the last element matching. + [Pure] + public static int LastIndexOf(this IEnumerable source, Func predicate) + { + if (source is IList list) + { + // Faster search for lists. + for (var i = list.Count - 1; i >= 0; --i) + { + if (predicate(list[i])) + return i; + } + return -1; + } + var index = 0; + var lastIndex = -1; + foreach (var item in source) + { + if (predicate(item)) + lastIndex = index; + index++; + } + return lastIndex; + } + + /// + /// Filters out null items from the enumerable. + /// + /// Generic type parameter. + /// Input enumerable to work on. + /// An enumeration of all items in that are not null. + [Pure] + public static IEnumerable NotNull(this IEnumerable source) where T : class + { + foreach (var item in source) + { + if (item is not null) + yield return item; + } + } + + /// + /// Filters out null items from the enumerable. + /// + /// Generic type parameter. + /// Input enumerable to work on. + /// An enumeration of all items in that are not null. + [Pure] + public static IEnumerable NotNull(this IEnumerable source) where T : struct + { + foreach (var item in source) + { + if (item.HasValue) + yield return item.Value; + } + } + + /// + /// Enumerates the linked list nodes. + /// + /// The linked list. + /// An enumeration of the linked list nodes. + [Pure] + internal static IEnumerable> EnumerateNodes(this LinkedList list) + { + var node = list.First; + while (node != null) + { + yield return node; + node = node.Next; + } + } + + /// + /// Calculates a combined hash code for items of the enumerbale. + /// + /// Generic type parameter. + /// Input enumerable to work on. + /// A combined hash code or 0 if the source is empty. + [Pure] + public static int ToHashCode(this IEnumerable source) where T : class + { + if (source.IsNullOrEmpty()) return 0; + + unchecked + { + return source.Aggregate(17, (hash, item) => hash * 23 + item.GetHashCode()); + } + } +} From 1e1ac00d5126e94d36a98265626054ce703ea2c9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Dec 2025 17:28:56 +0900 Subject: [PATCH 0616/1182] Import variables and methods lazily --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 8 +-- .../SDSL/ShaderMixer.cs | 2 +- src/Stride.Shaders/Core/SymbolFrame.cs | 7 +- src/Stride.Shaders/Core/SymbolTypes.cs | 31 ++++++++- .../Parsing/Analysis/SymbolTable.cs | 10 ++- .../Parsing/SDSL/AST/Expression.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 64 +++++++++---------- 8 files changed, 80 insertions(+), 50 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 0a3069b2fe..1b46fb71f0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -31,12 +31,12 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May { if (declaration is ShaderClass shader) { - SymbolTable table = new() + var compiler = new CompilerUnit(); + SymbolTable table = new(compiler.Context) { ShaderLoader = ShaderLoader, CurrentMacros = [..macros], }; - var compiler = new CompilerUnit(); compiler.Macros.AddRange(macros); shader.Compile(table, compiler); @@ -53,12 +53,12 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May } else if (declaration is ShaderEffect effect) { - SymbolTable table = new() + var compiler = new CompilerUnit(); + SymbolTable table = new(compiler.Context) { ShaderLoader = ShaderLoader, CurrentMacros = [..macros], }; - var compiler = new CompilerUnit(); compiler.Macros.AddRange(macros); effect.Compile(table, compiler); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 6442f29d69..7504c63917 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -33,7 +33,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect var temp = new NewSpirvBuffer(); var context = new SpirvContext(); - var table = new SymbolTable { ShaderLoader = ShaderLoader }; + var table = new SymbolTable(context) { ShaderLoader = ShaderLoader }; var effectEvaluator = new EffectEvaluator(ShaderLoader); shaderSource = effectEvaluator.EvaluateEffects(shaderSource); diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 3b68ee0074..2a657b8fb1 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -1,10 +1,11 @@ using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; using System.Collections.Immutable; using System.Xml.Linq; namespace Stride.Shaders.Core; -public class SymbolFrame() +public class SymbolFrame(SpirvContext context) { readonly Dictionary symbols = []; @@ -50,7 +51,7 @@ public bool TryGetValue(string name, out Symbol symbol) foreach (var implicitShader in implicitShaders) { - if (implicitShader.TryResolveSymbol(name, out symbol)) + if (implicitShader.TryResolveSymbol(context, name, out symbol)) return true; } @@ -60,6 +61,6 @@ public bool TryGetValue(string name, out Symbol symbol) public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); } -public sealed class RootSymbolFrame : SymbolFrame +public sealed class RootSymbolFrame(SpirvContext context) : SymbolFrame(context) { } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 080ecc1105..2e8d52d0fe 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Spirv.Building; using System; using System.Diagnostics.CodeAnalysis; +using System.Runtime.InteropServices; using System.Text; using static Stride.Shaders.Spirv.Specification; @@ -298,20 +299,38 @@ public sealed record LoadedShaderSymbol(string Name, int[] GenericArguments) : S public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; - internal bool TryResolveSymbol(string name, out Symbol symbol) + internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol symbol) { - foreach (var c in Methods) + + var shaderId = context.GetOrRegister(this); + + var methods = CollectionsMarshal.AsSpan(Methods); + foreach (ref var c in methods) { if (c.Symbol.Id.Name == name) { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); + } + symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + return true; } } - foreach (var c in Variables) + var variables = CollectionsMarshal.AsSpan(Variables); + foreach (ref var c in variables) { if (c.Symbol.Id.Name == name) { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); + } + symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return true; } @@ -324,6 +343,12 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) var member = cb.Members[index]; if (member.Name == name) { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); + } + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, MemberAccessWithImplicitThis: c.Symbol.Type, AccessChain: index); return true; diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index e6c0cf9942..acc949301b 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -13,7 +13,9 @@ public partial class SymbolTable : ISymbolProvider { public Dictionary DeclaredTypes { get; } = []; - public RootSymbolFrame RootSymbols { get; } = new(); + public SpirvContext Context { get; init; } + + public RootSymbolFrame RootSymbols { get; } public List Errors { get; } = []; // Used by Identifier.ResolveSymbol @@ -27,12 +29,14 @@ public partial class SymbolTable : ISymbolProvider // Only valid during compilation (not during ShaderMixin phase) public List InheritedShaders { get; set; } - public SymbolTable() + public SymbolTable(SpirvContext context) { + Context = context; + RootSymbols = new(context); Push(RootSymbols); } - public void Push() => CurrentSymbols.Add(new()); + public void Push() => CurrentSymbols.Add(new(Context)); public void Push(SymbolFrame symbolFrame) => CurrentSymbols.Add(symbolFrame); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 8236af4ddb..3bed720208 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -69,7 +69,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (MemberCall != null) { var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - functionSymbol = type.Methods.Single(x => x.Symbol.Id.Name == Name).Symbol; + type.TryResolveSymbol(context, Name, out functionSymbol); } else { @@ -402,7 +402,7 @@ void EmitOpAccessChain(Span accessChainIds) // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); - if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) + if (!s.TryResolveSymbol(context, field.Name, out var matchingComponent)) throw new InvalidOperationException(); // TODO: figure out instance (this vs composition) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a9ba99a175..97bb527766 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -271,7 +271,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBu var variableType = types[variable.ResultType]; var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); - variables.Add((new(sid, variableType, variable.ResultId), variable.Flags)); + variables.Add((new(sid, variableType, 0), variable.Flags)); } if (instruction.Op == Op.OpFunction) @@ -285,7 +285,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBu var functionType = types[functionInstruction.FunctionType]; var sid = new SymbolID(functionName, SymbolKind.Method, IsStage: (functionFlags & FunctionFlagsMask.Stage) != 0); - methods.Add((new(sid, functionType, functionInstruction.ResultId), functionFlags)); + methods.Add((new(sid, functionType, 0), functionFlags)); } if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index e2e08548bf..21d641134f 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -233,44 +233,44 @@ public int ImportShaderType(LoadedShaderSymbol shaderSymbol) var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); foreach (ref var structType in structTypes) { - FluentAdd(new OpSDSLImportStruct(Bound++, structType.Type.ToId(), shader.ResultId), out var @struct); - AddName(@struct.ResultId, structType.Type.Name); - // Fill the ID - structType.ImportedId = @struct.ResultId; - - // Register it so that it can be used right after during OpVariable for cbuffer - Types.Add(structType.Type, structType.ImportedId); - ReverseTypes.Add(structType.ImportedId, structType.Type); + ImportShaderStruct(shader, structType.Type, out structType.ImportedId); } - // Import variables/functions - var methods = CollectionsMarshal.AsSpan(shaderSymbol.Methods); - foreach (ref var c in methods) - { - if (c.Symbol.Id.Kind == SymbolKind.Method) - { - var functionType = (FunctionType)c.Symbol.Type; - var functionReturnTypeId = GetOrRegister(functionType.ReturnType); - - c.Symbol.IdRef = Bound++; - Add(new OpSDSLImportFunction(c.Symbol.IdRef, functionReturnTypeId, c.Symbol.Id.Name, shader.ResultId, c.Flags)); - AddName(c.Symbol.IdRef, c.Symbol.Id.Name); - } - } - var variables = CollectionsMarshal.AsSpan(shaderSymbol.Variables); - foreach (ref var c in variables) - { - if (c.Symbol.Id.Kind == SymbolKind.Variable) - { - c.Symbol.IdRef = Bound++; - Add(new OpSDSLImportVariable(c.Symbol.IdRef, GetOrRegister(c.Symbol.Type), c.Symbol.Id.Name, shader.ResultId, c.Flags)); - AddName(c.Symbol.IdRef, c.Symbol.Id.Name); - } - } + // Note: Variables and methods are imported lazily in LoadedShaderSymbol.TryResolveSymbol() return shader.ResultId; } + private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) + { + FluentAdd(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId), out var @struct); + AddName(@struct.ResultId, structType.Name); + + // Fill the ID + structImportedId = @struct.ResultId; + + // Register it so that it can be used right after during OpVariable for cbuffer + Types.Add(structType, structImportedId); + ReverseTypes.Add(structImportedId, structType); + } + + public void ImportShaderVariable(int shaderId, ref Symbol symbol, VariableFlagsMask flags) + { + symbol.IdRef = Bound++; + Add(new OpSDSLImportVariable(symbol.IdRef, GetOrRegister(symbol.Type), symbol.Id.Name, shaderId, flags)); + AddName(symbol.IdRef, symbol.Id.Name); + } + + public void ImportShaderMethod(int shaderId, ref Symbol symbol, FunctionFlagsMask flags) + { + var functionType = (FunctionType)symbol.Type; + var functionReturnTypeId = GetOrRegister(functionType.ReturnType); + + symbol.IdRef = Bound++; + Add(new OpSDSLImportFunction(symbol.IdRef, functionReturnTypeId, symbol.Id.Name, shaderId, flags)); + AddName(symbol.IdRef, symbol.Id.Name); + } + public int DeclareCBuffer(ConstantBufferSymbol cb) { var result = DeclareStructuredType(cb); From e188016a18f2c148e87af539a461eb7b5b05daff Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 19 Dec 2025 17:55:54 +0900 Subject: [PATCH 0617/1182] Overloads: handle very simple case with different number of parameters --- .../SDSL/ShaderMixer.MixinNode.cs | 6 ++- .../SDSL/ShaderMixer.ShaderInfo.cs | 20 +++++--- .../SDSL/ShaderMixer.cs | 46 ++++++++++++------- .../Extensions/spirv.sdsl.grammar-ext.json | 5 +- src/Stride.Shaders/Core/SymbolTypes.cs | 14 +++++- .../Parsing/SDSL/AST/Expression.cs | 10 +++- src/Stride.Shaders/Spirv/Building/Context.cs | 4 +- 7 files changed, 74 insertions(+), 31 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 34e50db222..8c4cc2bd0e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Compilers.SDSL; @@ -38,7 +39,7 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public List Shaders { get; } = new(); public Dictionary ShadersByName { get; } = new(); - public Dictionary MethodGroupsByName { get; } = new(); + public Dictionary<(string MethodName, FunctionType FunctionType), int> MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); public Dictionary Compositions { get; } = new(); @@ -49,6 +50,7 @@ class MethodGroup { public string Name; public ShaderInfo Shader; + public FunctionType FunctionType; public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 2053ec6671..1554268c4c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -33,15 +33,21 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public int StartInstruction { get; internal set; } = startInstruction; public int EndInstruction { get; internal set; } = endInstruction; - public Dictionary Functions { get; } = new(); + public Dictionary> Functions { get; } = new(); public Dictionary Variables { get; } = new(); public Dictionary StructTypes { get; } = new(); - public (int Id, SymbolType Type) FindMember(string name) + public (int Id, SymbolType Type) FindMember(string name, FunctionType? functionType = null) { - if (Functions.TryGetValue(name, out var function)) - return (function.Id, function.Type); + if (Functions.TryGetValue(name, out var functions)) + { + foreach (var function in functions) + { + if (function.Type == functionType) + return (function.Id, function.Type); + } + } if (Variables.TryGetValue(name, out var variable)) return (variable.Id, variable.Type); throw new KeyNotFoundException($"Member {name} was not found in shader {ShaderName}"); @@ -61,7 +67,9 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer { var functionName = globalContext.Names[function.ResultId]; var functionType = (FunctionType)globalContext.Types[function.FunctionType]; - shaderInfo!.Functions.Add(functionName, (function.ResultId, functionType)); + if (!shaderInfo!.Functions.TryGetValue(functionName, out var functions)) + shaderInfo.Functions.Add(functionName, functions = new()); + functions.Add((function.ResultId, functionType)); } else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { @@ -113,7 +121,7 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin { if (globalContext.ExternalShaders.ContainsKey(importFunction.Shader)) { - globalContext.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName)); + globalContext.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName, importFunction.FunctionType)); } } else if (i.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 7504c63917..867752abf4 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -48,15 +48,11 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - new StreamAnalyzer().Process(table, temp, context); // Merge cbuffers and rgroups // TODO: remove unused cbuffers (before merging them) - Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); MergeCBuffers(globalContext, context, temp); - Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), temp), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); ComputeCBufferOffsets(globalContext, context, temp); // Process reflection @@ -94,7 +90,7 @@ class MixinGlobalContext public EffectReflection Reflection { get; } = new(); public Dictionary ExternalShaders { get; } = new(); - public Dictionary ExternalFunctions { get; } = new(); + public Dictionary ExternalFunctions { get; } = new(); public Dictionary ExternalVariables { get; } = new(); } @@ -208,7 +204,8 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo bool isContext = true; - bool ProcessStageMemberOrType(int memberId, bool isStage) + // Note: FunctionType is only required when looking for stage function + bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isStage) { var include = isStage switch { @@ -226,7 +223,7 @@ bool ProcessStageMemberOrType(int memberId, bool isStage) var memberOrTypeName = names[memberId]; var stageMemberOrTypeId = stageShader.StructTypes.TryGetValue(memberOrTypeName, out var structTypeId) ? structTypeId - : stageShader.FindMember(memberOrTypeName).Id; + : stageShader.FindMember(memberOrTypeName, functionType).Id; remapIds.Add(offset + memberId, stageMemberOrTypeId); removedIds.Add(stageMemberOrTypeId); } @@ -259,16 +256,31 @@ bool ProcessStageMemberOrType(int memberId, bool isStage) if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - include = ProcessStageMemberOrType(function.ResultId, isStage); + // Note: BuildTypesAndMethodGroups has not been called for this mixin so context.Types/ReverseTypes is not filled + // However: + // - FunctionType is only required when looking for stage function + // - In that case, root stage mixin MergeMixinNode => BuildTypesAndMethodGroups would have been called for this function type + // - function type is already deduplicated (in this loop) + // So the lookup will work when it is necessary + + FunctionType? functionType = default; + // First, assuming FunctionType is a duplicate from a previous shader, we could find the already existing type by applying offset and remapIds + if (remapIds.TryGetValue(function.FunctionType + offset, out var remappedFunctionTypeId) + // Then, we can find the actual type in context.ReverseTypes + && context.ReverseTypes.TryGetValue(remappedFunctionTypeId, out var functionType2)) + functionType = (FunctionType)functionType2; + + + include = ProcessStageMemberOrType(function.ResultId, functionType, isStage); } if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) { var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; - include = ProcessStageMemberOrType(variableInstruction.ResultId, isStage); + include = ProcessStageMemberOrType(variableInstruction.ResultId, null, isStage); } if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) { - include = ProcessStageMemberOrType(typeStruct.ResultId, true); + include = ProcessStageMemberOrType(typeStruct.ResultId, null, true); } if (!include) @@ -502,6 +514,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { var functionName = globalContext.Names[function.ResultId]; + var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; var methodMixinGroup = mixinNode; if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) @@ -513,13 +526,14 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, if (globalContext.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) { var shaderName = globalContext.ExternalShaders[parentFunctionInfo.ShaderId]; - functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name].Id; + var parentFunctionType = context.ReverseTypes[parentFunctionInfo.FunctionType]; + functionInfo.Parent = mixinNode.ShadersByName[shaderName].Functions[parentFunctionInfo.Name].First(x => x.Type == parentFunctionType).Id; } } // Check if it has a parent (and if yes, share the MethodGroup) if (!methodMixinGroup.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) - methodGroup = new MethodGroup { Name = functionName }; + methodGroup = new MethodGroup { Name = functionName, FunctionType = functionType }; methodGroup.Shader = currentShader; methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); @@ -527,8 +541,8 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; // Also add lookup by name - if (!methodMixinGroup.MethodGroupsByName.TryGetValue(functionName, out var methodGroups)) - methodMixinGroup.MethodGroupsByName.Add(functionName, function.ResultId); + if (!methodMixinGroup.MethodGroupsByName.TryGetValue((functionName, functionType), out var methodGroups)) + methodMixinGroup.MethodGroupsByName.Add((functionName, functionType), function.ResultId); // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) @@ -718,13 +732,13 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } memberAccesses.Add(memberAccess.ResultId, variableInfo.Id); } - else if (globalContext.Types[memberAccess.ResultType] is FunctionType) + else if (globalContext.Types[memberAccess.ResultType] is FunctionType functionType) { // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL var functionId = memberAccess.Member; if (globalContext.ExternalFunctions.TryGetValue(memberAccess.Member, out var function)) // Process member call (composition) - functionId = instanceMixinGroup.MethodGroupsByName[function.Name]; + functionId = instanceMixinGroup.MethodGroupsByName[(function.Name, functionType)]; bool foundInStage = false; if (!instanceMixinGroup.MethodGroups.TryGetValue(functionId, out var methodGroupEntry)) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index c0871f54cd..27e48d2586 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -85,7 +85,10 @@ "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, - { "kind": "IdResultType" }, + { + "kind": "IdResultType", + "name": "functionType" + }, { "kind": "LiteralString", "name": "functionName" diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 2e8d52d0fe..82f4f31ffd 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -301,6 +301,8 @@ public sealed record LoadedShaderSymbol(string Name, int[] GenericArguments) : S internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol symbol) { + bool found = false; + symbol = default; var shaderId = context.GetOrRegister(this); @@ -315,11 +317,19 @@ internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol sym context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); } - symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + // Combine method symbols if multiple matches + var methodSymbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; - return true; + symbol = found + ? new Symbol(new(name, SymbolKind.MethodGroup, IsStage: symbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [symbol, methodSymbol]) + : methodSymbol; + + found = true; } } + if (found) + return true; + var variables = CollectionsMarshal.AsSpan(Variables); foreach (ref var c in variables) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 3bed720208..df7726df4b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -76,9 +76,15 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) functionSymbol = table.ResolveSymbol(Name); } - // TODO: find proper overload + // Choose appropriate method to call if (functionSymbol.Type is FunctionGroupType) - functionSymbol = functionSymbol.GroupMembers.First(); + { + // Find methods matching number of parameters + var matchingMethods = functionSymbol.GroupMembers.Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); + + // TODO: find proper overload + functionSymbol = matchingMethods.First(); + } var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 21d641134f..ecb8edcbd3 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -264,10 +264,10 @@ public void ImportShaderVariable(int shaderId, ref Symbol symbol, VariableFlagsM public void ImportShaderMethod(int shaderId, ref Symbol symbol, FunctionFlagsMask flags) { var functionType = (FunctionType)symbol.Type; - var functionReturnTypeId = GetOrRegister(functionType.ReturnType); + var functionTypeId = GetOrRegister(functionType); symbol.IdRef = Bound++; - Add(new OpSDSLImportFunction(symbol.IdRef, functionReturnTypeId, symbol.Id.Name, shaderId, flags)); + Add(new OpSDSLImportFunction(symbol.IdRef, functionTypeId, symbol.Id.Name, shaderId, flags)); AddName(symbol.IdRef, symbol.Id.Name); } From b305b7e426bed83d33c7b68b3a9cb5ac70060860 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 20 Dec 2025 11:19:12 +0900 Subject: [PATCH 0618/1182] Added support for out parameters --- .../SDSL/ShaderMixer.cs | 20 +++++-- .../Examples.Spirv.cs | 2 +- .../Extensions/spirv.sdsl.grammar-ext.json | 16 ++++++ .../Literals/LiteralArray.cs | 13 +++-- src/Stride.Shaders/Core/SymbolTypes.cs | 18 +++++- .../Parsing/SDSL/AST/Expression.cs | 56 +++++++++++++------ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 +-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Parsing/SDSL/AST/ShaderElements.cs | 22 ++++++++ .../ShaderParsers/ShaderMethodParsers.cs | 13 ++++- .../Spirv/Building/Builder.Functions.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 9 ++- .../Spirv/Processing/StreamAnalyzer.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 22 +++++++- 15 files changed, 161 insertions(+), 48 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 867752abf4..5b58666fc5 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -118,8 +118,6 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); - Spv.Dis(NewSpirvBuffer.Merge(context.GetBuffer(), buffer), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); // Compositions (recursive) @@ -340,6 +338,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS || i2.Op == Op.OpTypeRuntimeArray || i2.Op == Op.OpTypePointer || i2.Op == Op.OpTypeFunction + || i2.Op == Op.OpTypeFunctionSDSL || i2.Op == Op.OpTypeImage || i2.Op == Op.OpTypeSampler || i2.Op == Op.OpTypeGenericLinkSDSL @@ -988,14 +987,14 @@ public static void OffsetIds(OpData inst, int offset) { if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) { - if (o.Words[i * 2 + 0] != 0) - o.Words[i * 2 + 0] += offset; + if (o.Words[i + 0] != 0) + o.Words[i + 0] += offset; } if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) { - if (o.Words[i * 2 + 1] != 0) - o.Words[i * 2 + 1] += offset; + if (o.Words[i + 1] != 0) + o.Words[i + 1] += offset; } } } @@ -1013,6 +1012,15 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) temp.Replace(index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); + // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) + if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) + { + Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; + for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) + parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; + temp.Replace(index, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); + } + // Remove Nop if (i.Op == Op.OpNop) temp.RemoveAt(index--); diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index f3959341c5..3f134c7025 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -27,7 +27,7 @@ public static void GenerateSpirv() var function = builder.DeclareFunction( context, "add", - new(ScalarType.From("int"), [ScalarType.From("int"), ScalarType.From("int")]) + new(ScalarType.From("int"), [(ScalarType.From("int"), default), (ScalarType.From("int"), default)]) ); builder.BeginFunction(context, function); builder.AddFunctionParameter(context, "a", ScalarType.From("int")); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 27e48d2586..372ff080b5 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -172,6 +172,22 @@ } ] }, + { + "opname": "OpTypeFunctionSDSL", + "class": "Type-Declaration", + "operands": [ + { "kind": "IdResult" }, + { + "kind": "IdRef", + "name": "'Return Type'" + }, + { + "kind": "PairIdRefLiteralInteger", + "quantifier": "*", + "name": "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." + } + ] + }, { "opname": "OpSDSLFunctionInfo", "class": "Miscellaneous", diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 290e901372..2689603c22 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -140,21 +140,26 @@ public static LiteralArray From(Span words) } return new(owner); } - else if (value is long or double && words.Length % 2 == 0) + else if (value is long or double or ValueTuple && words.Length % 2 == 0) { var owner = MemoryOwner.Allocate(words.Length / 2); - for (int i = 0; i < words.Length; i += 2) + for (int i = 0; i < owner.Length; i++) { if (value is long) { - long b = words[i] << 32 | words[i + 1]; + long b = words[i * 2] << 32 | words[i * 2 + 1]; owner.Span[i] = Unsafe.As(ref b); } else if (value is double) { - double b = BitConverter.Int64BitsToDouble(words[i] << 32 | words[i + 1]); + double b = BitConverter.Int64BitsToDouble(words[i * 2] << 32 | words[i * 2 + 1]); owner.Span[i] = Unsafe.As(ref b); } + else if (value is ValueTuple) + { + ValueTuple t = (words[i * 2], words[i * 2 + 1]); + owner.Span[i] = Unsafe.As, T>(ref t); + } } return new(owner); } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 82f4f31ffd..a4ecb6547a 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -200,7 +200,7 @@ public sealed record TextureCubeType(ScalarType ReturnType) : TextureType(Return public sealed record FunctionGroupType() : SymbolType(); -public sealed record FunctionType(SymbolType ReturnType, List ParameterTypes) : SymbolType() +public sealed record FunctionType(SymbolType ReturnType, List<(SymbolType Type, ParameterModifiers Modifiers)> ParameterTypes) : SymbolType() { public bool Equals(FunctionType? other) { @@ -230,7 +230,21 @@ public override string ToId() builder.Append($"fn_"); for (int i = 0; i < ParameterTypes.Count; i++) { - builder.Append(ParameterTypes[i].ToId()); + if (ParameterTypes[i].Modifiers.HasFlag(ParameterModifiers.Const)) + builder.Append("const "); + switch (ParameterTypes[i].Modifiers) + { + case var flag when flag.HasFlag(ParameterModifiers.InOut): + builder.Append("inout "); + break; + case var flag when flag.HasFlag(ParameterModifiers.Out): + builder.Append("out "); + break; + case var flag when flag.HasFlag(ParameterModifiers.In): + builder.Append("in "); + break; + } + builder.Append(ParameterTypes[i].Type.ToId()); builder.Append('_'); } return builder.Append(ReturnType.ToId()).ToString(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index df7726df4b..2532d511c9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -89,29 +89,31 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Type = functionType.ReturnType; - var list = parameters.Values; + Span compiledParams = stackalloc int[parameters.Values.Count]; - Span compiledParams = stackalloc int[list.Count]; - var tmp = 0; - - foreach (var p in list) + for (int i = 0; i < parameters.Values.Count; i++) { - var paramSource = p.CompileAsValue(table, compiler); - var paramType = functionType.ParameterTypes[tmp]; - // Wrap param in proper pointer type (function) + var paramDefinition = functionType.ParameterTypes[i]; var paramVariable = context.Bound++; - builder.AddFunctionVariable(context.GetOrRegister(paramType), paramVariable); + builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); - // Convert type (if necessary) - var paramValueType = paramType; - if (paramValueType is PointerType pointerType) - paramValueType = pointerType.BaseType; - paramSource = builder.Convert(context, paramSource, paramValueType); + // Note: "in" is implicit, so we match in all cases except if out + var inOutFlags = paramDefinition.Modifiers & ParameterModifiers.InOut; + if (inOutFlags != ParameterModifiers.Out) + { + var paramSource = parameters.Values[i].CompileAsValue(table, compiler); - builder.Insert(new OpStore(paramVariable, paramSource.Id, null)); + // Convert type (if necessary) + var paramExpectedValueType = paramDefinition.Type; + if (paramExpectedValueType is PointerType pointerType) + paramExpectedValueType = pointerType.BaseType; + paramSource = builder.Convert(context, paramSource, paramExpectedValueType); - compiledParams[tmp++] = paramVariable; + builder.Insert(new OpStore(paramVariable, paramSource.Id, null)); + } + + compiledParams[i] = paramVariable; } int? instance = null; @@ -134,7 +136,27 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (instance is int instanceId) functionSymbol.IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId; - return builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + + for (int i = 0; i < parameters.Values.Count; i++) + { + var paramDefinition = functionType.ParameterTypes[i]; + if (paramDefinition.Modifiers.HasFlag(ParameterModifiers.Out)) + { + var paramDefinitionType = (PointerType)paramDefinition.Type; + var paramVariable = compiledParams[i]; + var paramTarget = parameters.Values[i].Compile(table, compiler); + var paramTargetType = (PointerType)context.ReverseTypes[paramTarget.TypeId]; + + if (paramTargetType.BaseType != paramDefinitionType.BaseType) + throw new InvalidOperationException($"Value of type {paramTargetType.BaseType} can't be used as out parameter {i} of type {paramDefinitionType.BaseType} in method call [{this}]"); + + var loadedResult = builder.Insert(new OpLoad(context.GetOrRegister(paramTargetType.BaseType), context.Bound++, paramVariable, null)).ResultId; + builder.Insert(new OpStore(paramTarget.Id, loadedResult, null)); + } + } + + return result; } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 97bb527766..6069d2f68d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -158,13 +158,13 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var innerType = types[typeRuntimeArray.ElementType]; types.Add(typeRuntimeArray.ResultId, new ArrayType(innerType, -1)); } - else if (instruction.Op == Op.OpTypeFunction && new OpTypeFunction(instruction) is { } typeFunctionInstruction) + else if (instruction.Op == Op.OpTypeFunctionSDSL && new OpTypeFunctionSDSL(instruction) is { } typeFunctionInstruction) { var returnType = types[typeFunctionInstruction.ReturnType]; - var parameterTypes = new List(); + var parameterTypes = new List<(SymbolType Type, ParameterModifiers Flags)>(); foreach (var operand in typeFunctionInstruction.Values) { - parameterTypes.Add(types[operand]); + parameterTypes.Add((types[operand.Item1], (ParameterModifiers)operand.Item2)); } types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); } @@ -386,7 +386,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = new PointerType(argSym, Specification.StorageClass.Function); - ftype.ParameterTypes.Add(arg.Type); + ftype.ParameterTypes.Add((arg.Type, arg.Modifiers)); } func.Type = ftype; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 97ba1b8b1e..b97749ac00 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -177,14 +177,14 @@ public override string ToString() } } -public class MethodParameter(TypeName type, Identifier name, TextLocation info, string? storage = null, Expression? arraySize = null, Identifier? semantic = null) : Node(info) +public class MethodParameter(TypeName type, Identifier name, TextLocation info, ParameterModifiers modifiers = ParameterModifiers.None, Expression? arraySize = null, Identifier? semantic = null) : Node(info) { public TypeName TypeName { get; set; } = type; public SymbolType? Type { get; set; } public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; public Expression? ArraySize { get; set; } = arraySize; - public string? Storage { get; set; } = storage; + public ParameterModifiers Modifiers { get; set; } = modifiers; public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index c8d7acb8c4..5a9c9af437 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -57,6 +57,17 @@ public enum StreamKind PatchStream } +[Flags] +public enum ParameterModifiers : int +{ + None = 0x0, + In = 0x1, + Out = 0x2, + InOut = In | Out, + + Const = 0x10, +} + public static class ShaderVariableInformationExtensions { public static StreamKind ToStreamKind(this string str) @@ -106,6 +117,17 @@ public static TypeModifier ToTypeModifier(this string str) _ => TypeModifier.None }; } + + public static ParameterModifiers ToParameterModifiers(this string str) + { + return str switch + { + "in" => ParameterModifiers.In, + "out" => ParameterModifiers.Out, + "inout" => ParameterModifiers.InOut, + "const" => ParameterModifiers.Const, + }; + } } public class ShaderVariable(TypeName typeName, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 88489aa3e5..c47f99cf0d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -61,8 +61,15 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { var position = scanner.Position; - if (!(Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var storage, advance: true) && Parsers.Spaces1(ref scanner, result, out _))) + ParameterModifiers modifiers = ParameterModifiers.None; + if (Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var modifiersString, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) + { + modifiers = modifiersString.ToParameterModifiers(); + } + else + { scanner.Position = position; + } if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var identifier, out var value, advance: true) ) { @@ -72,12 +79,12 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r && Parsers.Spaces0(ref scanner, result, out _) ) { - parsed = new(typename, identifier, scanner[position..scanner.Position], storage, semantic: semantic); + parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers, semantic: semantic); return true; } else { - parsed = new(typename, identifier, scanner[position..scanner.Position], storage); + parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers); return true; } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 8d7ff8a556..fed7ff80f7 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -13,7 +13,7 @@ public SpirvFunction DeclareFunction(SpirvContext context, string name, Function { var func = context.Bound++; foreach (var t in ftype.ParameterTypes) - context.GetOrRegister(t); + context.GetOrRegister(t.Type); context.AddName(func, name); var result = new SpirvFunction(func, name, ftype) { IsStage = isStage }; return result; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index ecb8edcbd3..3a5aa58934 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -318,11 +318,14 @@ public int DeclareStructuredType(StructuredType structSymbol) int RegisterFunctionType(FunctionType functionType) { - Span types = stackalloc int[functionType.ParameterTypes.Count]; + Span<(int, int)> types = stackalloc (int, int)[functionType.ParameterTypes.Count]; for (int i = 0; i < functionType.ParameterTypes.Count; i++) - types[i] = GetOrRegister(functionType.ParameterTypes[i]); + { + types[i].Item1 = GetOrRegister(functionType.ParameterTypes[i].Type); + types[i].Item2 = (int)functionType.ParameterTypes[i].Modifiers; + } - var result = Buffer.Add(new OpTypeFunction(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); + var result = Buffer.Add(new OpTypeFunctionSDSL(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); return result.IdResult ?? -1; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index d78ecfe941..e2deb06c4a 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -338,7 +338,7 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpTypeVoid(context.Bound++), out var voidType); // Add new entry point wrapper - context.FluentAdd(new OpTypeFunction(context.Bound++, voidType, []), out var newEntryPointFunctionType); + context.FluentAdd(new OpTypeFunctionSDSL(context.Bound++, voidType, []), out var newEntryPointFunctionType); buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); buffer.Add(new OpLabel(context.Bound++)); context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 0b8c33e774..389c1b52be 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -89,7 +89,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool - || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction + || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeFunctionSDSL || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray //|| x.Op == Op.OpTypeStruct || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index cc71ac4091..aa68a5c235 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -229,6 +229,23 @@ readonly DisWriter AppendResultId(int? id = null) } + private DisWriter AppendPairIdRefLiteralIntegers(SpvOperand operand) + { + var count = operand.Quantifier switch + { + OperandQuantifier.One => 1, + OperandQuantifier.ZeroOrMore => operand.Words.Length / 2, + OperandQuantifier.ZeroOrOne => operand.Words.Length == 0 ? 0 : 1, + }; + + for (int i = 0; i < count; ++i) + { + AppendIdRef(operand.Words[i * 2]); + AppendLiteralNumber(operand.Words[i * 2 + 1]); + } + return this; + } + public readonly void Disassemble() { DisHeader(); @@ -319,15 +336,14 @@ or OperandKind.LiteralSpecConstantOpInteger (OperandQuantifier.ZeroOrMore, > 0) => AppendEnums(k, operand).Append(' '), (OperandQuantifier.ZeroOrOne or OperandQuantifier.ZeroOrMore, 0) => Append(""), _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) - } + }, + OperandKind.PairIdRefLiteralInteger => AppendPairIdRefLiteralIntegers(operand), }; } AppendLine(""); } } - - public readonly override string ToString() => builder.ToString(); } From 9ea9da811ce8bdf9e19af2d83d544f0b23a113b1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 21 Dec 2025 10:26:17 +0900 Subject: [PATCH 0619/1182] Added support for semantic generic --- assets/SDSL/RenderTests/GenericsSemantic.sdsl | 38 ++++++++++++++ .../SDSL/ShaderMixer.cs | 5 +- .../Extensions/spirv.sdsl.grammar-ext.json | 26 ++++------ src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 10 +++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 13 ++--- .../Spirv/Building/Builder.Class.cs | 51 +++++++++++++++++-- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 4 +- 9 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsSemantic.sdsl diff --git a/assets/SDSL/RenderTests/GenericsSemantic.sdsl b/assets/SDSL/RenderTests/GenericsSemantic.sdsl new file mode 100644 index 0000000000..c9f8f7cd2c --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsSemantic.sdsl @@ -0,0 +1,38 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float4 Compute() + { + return 0.0; + } +} + +shader ComputeSemantic : Compute +{ + stream float4 Test : TSemantic; + + override float4 Compute() + { + return Test; + } +} + +shader GenericsSemantic : ComputeSemantic<"EXTRA_COLOR"> +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = Compute(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5b58666fc5..172dd8675b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -341,7 +341,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS || i2.Op == Op.OpTypeFunctionSDSL || i2.Op == Op.OpTypeImage || i2.Op == Op.OpTypeSampler - || i2.Op == Op.OpTypeGenericLinkSDSL + || i2.Op == Op.OpTypeGenericSDSL || i2.Op == Op.OpSDSLImportShader || i2.Op == Op.OpSDSLImportVariable || i2.Op == Op.OpSDSLImportFunction @@ -449,6 +449,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS { var n = new LiteralValue(m.Span); n.Value = $"{n.Value}.{mixinNode.CompositionPath}"; + memberDecorate.Decoration = new(memberDecorate.Decoration.Value, n.Words); n.Dispose(); } } @@ -1031,7 +1032,7 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLEffectEnd || i.Op == Op.OpSDSLMixinInherit || i.Op == Op.OpConstantStringSDSL - || i.Op == Op.OpTypeGenericLinkSDSL + || i.Op == Op.OpTypeGenericSDSL || i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 372ff080b5..adbf23632f 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -271,11 +271,7 @@ "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, - { "kind": "IdResult" }, - { - "kind": "GenericParameterKindSDSL", - "name": "kind" - } + { "kind": "IdResult" } ] }, { @@ -290,10 +286,14 @@ ] }, { - "opname": "OpTypeGenericLinkSDSL", + "opname": "OpTypeGenericSDSL", "class": "Miscellaneous", "operands": [ - { "kind": "IdResult" } + { "kind": "IdResult" }, + { + "kind": "GenericParameterKindSDSL", + "name": "kind" + } ] }, { @@ -408,20 +408,16 @@ "kind": "GenericParameterKindSDSL", "enumerants": [ { - "enumerant": "Float", - "value": 0 - }, - { - "enumerant": "Int", + "enumerant": "LinkType", "value": 1 }, { - "enumerant": "Bool", + "enumerant": "Semantic", "value": 2 }, { - "enumerant": "LinkType", - "value": 20 + "enumerant": "MemberName", + "value": 3 } ] }, diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index a4ecb6547a..d4a2c0a382 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -388,4 +388,4 @@ internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol sym public override string ToString() => base.ToString(); } -public sealed record GenericLinkType : SymbolType; +public sealed record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 7b764e3433..58139603c3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -383,7 +383,15 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { if (Name == "LinkType") { - symbolType = new GenericLinkType(); + symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.LinkType); + } + else if (Name == "Semantic") + { + symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.Semantic); + } + else if (Name == "MemberName") + { + symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberName); } else if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 6069d2f68d..69c31bbc7b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -201,9 +201,9 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { types.Add(typeSampler.ResultId, new SamplerType()); } - else if (instruction.Op == Op.OpTypeGenericLinkSDSL && (OpTypeGenericLinkSDSL)instruction is { } typeGenericLink) + else if (instruction.Op == Op.OpTypeGenericSDSL && (OpTypeGenericSDSL)instruction is { } typeGeneric) { - types.Add(typeGenericLink.ResultId, new GenericLinkType()); + types.Add(typeGeneric.ResultId, new GenericParameterType(typeGeneric.Kind)); } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid @@ -330,14 +330,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); - var genericParameterKind = genericParameterType switch - { - ScalarType { TypeName: "float" } => GenericParameterKindSDSL.Float, - ScalarType { TypeName: "int" } => GenericParameterKindSDSL.Int, - ScalarType { TypeName: "bool" } => GenericParameterKindSDSL.Bool, - GenericLinkType => GenericParameterKindSDSL.LinkType, - }; - context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, genericParameterKind)); + context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound)); context.AddName(context.Bound, genericParameter.Name); table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index f3d14e13a6..c9cf2fabd3 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -249,6 +250,7 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh var bound = shader.Header.Bound; var resolvedLinks = new Dictionary(); + var semantics = new Dictionary(); var genericValueIndex = 0; for (var index = 0; index < shader.Count; index++) @@ -272,10 +274,14 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh else shader.Replace(index, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); break; - case GenericLinkType: + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); resolvedLinks.Add(genericParameter.ResultId, genericValue); break; + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: + shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + semantics.Add(names[genericParameter.ResultId], genericValue); + break; default: throw new NotImplementedException(); } @@ -286,12 +292,41 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh } } + TransformResolvedSemantics(shader, semantics); TransformResolvedLinkIdIntoLinkString(shader, resolvedLinks); // In case we had to increase bound (new instructions), update header shader.Header = shader.Header with { Bound = bound }; } + private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary semantics) + { + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m } } decorate) + { + var n = new LiteralValue(m.Span); + if (semantics.TryGetValue(n.Value, out var newSemantic)) + { + n.Value = newSemantic; + decorate.Decoration = new(decorate.Decoration.Value, n.Words); + } + n.Dispose(); + } + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m2 } } decorate2) + { + var n = new LiteralValue(m2.Span); + if (semantics.TryGetValue(n.Value, out var newSemantic)) + { + n.Value = newSemantic; + decorate2.Decoration = new(decorate2.Decoration.Value, n.Words); + } + n.Dispose(); + } + } + } + private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer instantiatingBuffer) { Console.WriteLine($"[Shader] Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); @@ -304,8 +339,10 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha } } + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + // Map classSource.GenericArguments ids to OpSDSLGenericParameter.ResultId (in the order OpSDSLGenericParameter appears) - Dictionary> targets = new(); + Dictionary> targets = new(); // Collect OpSDSLGenericParameter List generics = new(); @@ -318,7 +355,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha generics.Add(genericParameter.ResultId); if (!targets.TryGetValue(classSource.GenericArguments[genericArgumentIndex], out var genericParametersForThisArgument)) targets.Add(classSource.GenericArguments[genericArgumentIndex], genericParametersForThisArgument = new()); - genericParametersForThisArgument.Add((genericParameter.ResultId, index)); + genericParametersForThisArgument.Add((genericParameter.ResultId, types[genericParameter.ResultType], index)); genericArgumentIndex++; SetOpNop(i.Data.Memory.Span); } @@ -331,7 +368,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha // Try to resolve fully the new generic parameter values // Any parameter resolved will be stored in Dictionary with the string version of the parameter value) var resolvedParameters = new Dictionary(); - + var semantics = new Dictionary(); if (instantiatingBuffer != null) { for (var index = 0; index < instantiatingBuffer.Count; index++) @@ -365,7 +402,12 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha var value = constantString.LiteralString; // This will be used later for resolving LinkType generics foreach (var parameter in parameters) + { resolvedParameters.Add(parameter.ResultId, value); + + if (parameter.Type is GenericParameterType { Kind: GenericParameterKindSDSL.Semantic }) + semantics.Add(names[parameter.ResultId], value); + } } } else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) @@ -375,6 +417,7 @@ private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer sha } } + TransformResolvedSemantics(shader, semantics); TransformResolvedLinkIdIntoLinkString(shader, resolvedParameters); // Fully resolved? diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 3a5aa58934..2b093822d1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -205,7 +205,7 @@ public int GetOrRegister(SymbolType? type) SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Dim.Buffer, 2, 0, 0, 1, ImageFormat.Unknown, null)).IdResult, SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, - GenericLinkType => Buffer.Add(new OpTypeGenericLinkSDSL(Bound++)).IdResult, + GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 389c1b52be..358200adc8 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -93,7 +93,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray //|| x.Op == Op.OpTypeStruct || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler - || x.Op == Op.OpTypeGenericLinkSDSL + || x.Op == Op.OpTypeGenericSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) { comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); @@ -242,7 +242,7 @@ public void RemoveDuplicates() ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparerSort); ProcessInstructions(buffer, instructionsByOp, Op.OpTypeFunction, Op.OpTypeFunction, true, comparerSort); - ProcessInstructions(buffer, instructionsByOp, Op.OpTypeGenericLinkSDSL, Op.OpTypeGenericLinkSDSL, true, comparerSort); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeGenericSDSL, Op.OpTypeGenericSDSL, true, comparerSort); // Note: due to RemapOp, this will also cover OpMemberDecorate and OpMemberName ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparerSort); From c3a9f917e4e27f1d0d27d7ae126f3b44936ab0e4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 21 Dec 2025 17:45:31 +0900 Subject: [PATCH 0620/1182] Unit tests for out parameter and simple overloads --- assets/SDSL/RenderTests/MethodOut.sdsl | 24 +++++++++++++++++ assets/SDSL/RenderTests/Overloads.sdsl | 36 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 assets/SDSL/RenderTests/MethodOut.sdsl create mode 100644 assets/SDSL/RenderTests/Overloads.sdsl diff --git a/assets/SDSL/RenderTests/MethodOut.sdsl b/assets/SDSL/RenderTests/MethodOut.sdsl new file mode 100644 index 0000000000..d9273060d5 --- /dev/null +++ b/assets/SDSL/RenderTests/MethodOut.sdsl @@ -0,0 +1,24 @@ +// PSMain(ExpectedResult=#7D7D7D7D) + +namespace Stride.Shaders.Tests; + +shader MethodOut +{ + stream float4 ColorTarget : SV_Target0; + + void Test(out float4 test) + { + test = float4(127.0, 127.0, 127.0, 127.0) / 255.0; + } + + void Test2(inout float4 test) + { + test -= 2.0 / 255.0; + } + + void PSMain() + { + Test(streams.ColorTarget); + Test2(streams.ColorTarget); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/Overloads.sdsl b/assets/SDSL/RenderTests/Overloads.sdsl new file mode 100644 index 0000000000..4e3a5960d7 --- /dev/null +++ b/assets/SDSL/RenderTests/Overloads.sdsl @@ -0,0 +1,36 @@ +// PSMain(ExpectedResult=#0103060A) + +namespace Stride.Shaders.Tests; + +shader OverloadBase +{ + float TestMethod(int a, int b) + { + return a + b; + } + + float TestMethod(int a, int b, int c, int d) + { + return a + b + c + d; + } +} + +shader Overloads : OverloadBase +{ + stream float4 ColorTarget : SV_Target0; + + float TestMethod(int a) + { + return a; + } + + float TestMethod(int a, int b, int c) + { + return a + b + c; + } + + void PSMain() + { + streams.ColorTarget = float4(TestMethod(1), TestMethod(1, 2), TestMethod(1, 2, 3), TestMethod(1, 2, 3, 4)) / 255.0; + } +} \ No newline at end of file From c6876efcbd24fcca3be23e64e3a8b916a252260f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 21 Dec 2025 17:39:41 +0900 Subject: [PATCH 0621/1182] Rewrote the Generics instantiation code to reuse most code between both instantiation kinds --- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 5 - .../Spirv/Building/Builder.Class.cs | 323 ++++++++---------- 2 files changed, 149 insertions(+), 179 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 69c31bbc7b..fc0d07190f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -292,11 +292,6 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBu { structTypes.Add(((StructuredType)types[typeStructInstruction.ResultId], -1)); } - - if (instruction.Op == Op.OpSDSLGenericParameter) - { - throw new NotImplementedException(); - } } var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index c9cf2fabd3..80e100f1fe 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,6 +1,5 @@ using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -9,7 +8,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Reflection.Metadata; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; @@ -241,10 +239,88 @@ public static bool TryGetConstantValue(OpData data, out object value, params Rea throw new Exception("Cannot find type instruction for id " + typeId); } - private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer shader, string className, string[] genericValues) + record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, int Index, string Name, bool Resolved, object Value); + + abstract class GenericResolver + { + public abstract bool NeedsResolve(); + public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value); + + public virtual void PostProcess(string classNameWithGenerics, List genericParameters) + { + } + } + + class GenericResolverFromValues(string[]? genericValues) : GenericResolver + { + public override bool NeedsResolve() => genericValues != null && genericValues.Length > 0; + + public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) + { + var genericValue = genericValues![index]; + switch (genericParameterType) + { + case ScalarType { TypeName: "int" }: + value = int.Parse(genericValue); + return true; + case ScalarType { TypeName: "float" }: + value = float.Parse(genericValue); + return true; + case ScalarType { TypeName: "bool" }: + value = bool.Parse(genericValue); + return true; + case GenericParameterType g: + value = genericValue; + return true; + default: + throw new NotImplementedException(); + } + } + } + + class GenericResolverFromClassInstantiation(ShaderClassInstantiation classSource, NewSpirvBuffer instantiatingBuffer, ResolveStep resolveStep) : GenericResolver { - Console.WriteLine($"[Shader] Instantiating {className} with values {string.Join(",", genericValues)}"); + private Dictionary names; + + public override bool NeedsResolve() => classSource.GenericArguments.Length > 0; + + public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) + { + if (!TryGetConstantValue(classSource.GenericArguments[index], out value, instantiatingBuffer)) + { + if (names == null) + ShaderClass.ProcessNameAndTypes(instantiatingBuffer, 0, instantiatingBuffer.Count, out names, out _); + + value = names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) + ? $"%{genericArgumentName}[{classSource.GenericArguments[index]}]" + : $"%{classSource.GenericArguments[index]}"; + return false; + } + + return true; + } + + public override void PostProcess(string classNameWithGenerics, List genericParameters) + { + // Fully resolved? + if (genericParameters.All(x => x.Resolved)) + { + if (resolveStep == ResolveStep.Mix) + { + classSource.ClassName = classNameWithGenerics; + classSource.GenericArguments = []; + } + } + else if (resolveStep == ResolveStep.Mix) + { + throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); + } + } + } + + private static void InstantiateGenericShader(NewSpirvBuffer shader, string className, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) + { ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); var bound = shader.Header.Bound; @@ -252,43 +328,68 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); - var genericValueIndex = 0; - for (var index = 0; index < shader.Count; index++) + var genericParameters = new List(); + foreach (var i in shader) { - var i = shader[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { - var genericValue = genericValues[genericValueIndex++]; - var type = types[genericParameter.ResultType]; - switch (type) - { - case ScalarType { TypeName: "int" }: - shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, int.Parse(genericValue))); - break; - case ScalarType { TypeName: "float" }: - shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, float.Parse(genericValue))); - break; - case ScalarType { TypeName: "bool" }: - if (bool.Parse(genericValue)) - shader.Replace(index, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); - else - shader.Replace(index, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); - break; - case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: - shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); - resolvedLinks.Add(genericParameter.ResultId, genericValue); - break; - case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: - shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); - semantics.Add(names[genericParameter.ResultId], genericValue); - break; - default: - throw new NotImplementedException(); - } + var genericParameterType = types[genericParameter.ResultType]; + var genericParameterName = names[genericParameter.ResultId]; + var resolved = genericResolver.TryResolveGenericValue(genericParameterType, genericParameterName, genericParameters.Count, out var genericValue); + genericParameters.Add(new(genericParameterType, genericParameter.ResultId, genericParameter.ResultType, i.Index, genericParameterName, resolved, genericValue)); + } + } + + Console.WriteLine($"[Shader] Instantiating {className} with values {string.Join(",", genericParameters.Select(x => x.Value))}"); + + StringBuilder classNameWithGenericsBuilder = new(); + classNameWithGenericsBuilder.Append(className).Append("<"); + + for (int i = 0; i < genericParameters.Count; i++) + { + var genericParameter = genericParameters[i]; + var index = genericParameter.Index; + if (i > 0) + classNameWithGenericsBuilder.Append(","); + classNameWithGenericsBuilder.Append(genericParameter.Value.ToString()); + + if (!genericParameter.Resolved) + continue; + + switch (genericParameter.Type) + { + case ScalarType { TypeName: "int" }: + shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, (int)genericParameter.Value)); + break; + case ScalarType { TypeName: "float" }: + shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, (float)genericParameter.Value)); + break; + case ScalarType { TypeName: "bool" }: + if ((bool)genericParameter.Value) + shader.Replace(index, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); + else + shader.Replace(index, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); + break; + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: + shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, (string)genericParameter.Value)); + resolvedLinks.Add(genericParameter.ResultId, (string)genericParameter.Value); + break; + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: + shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, (string)genericParameter.Value)); + semantics.Add(names[genericParameter.ResultId], (string)genericParameter.Value); + break; + default: + throw new NotImplementedException(); } - else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + } + classNameWithGenericsBuilder.Append(">"); + var classNameWithGenerics = classNameWithGenericsBuilder.ToString(); + + foreach (var i in shader) + { + if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) { - shaderDeclaration.ShaderName += $"<{string.Join(',', genericValues)}>"; + shaderDeclaration.ShaderName = classNameWithGenerics; } } @@ -297,6 +398,8 @@ private static void InstantiateGenericShaderUsingGenericValues(NewSpirvBuffer sh // In case we had to increase bound (new instructions), update header shader.Header = shader.Header with { Bound = bound }; + + genericResolver.PostProcess(classNameWithGenerics, genericParameters); } private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary semantics) @@ -327,126 +430,6 @@ private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary } } - private static void InstantiateGenericShaderUsingParentBuffer(NewSpirvBuffer shader, ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer instantiatingBuffer) - { - Console.WriteLine($"[Shader] Instantiating {classSource.ClassName} with parameters {string.Join(",", classSource.GenericArguments.Select(x => $"%{x}"))}"); - Console.WriteLine($"[Shader] Instantiating from buffer generics {instantiatingBuffer[0].Data}:"); - foreach (var i in instantiatingBuffer) - { - if (i.Data.IdResult is int id && classSource.GenericArguments.Contains(id)) - { - Console.WriteLine($" - [{classSource.GenericArguments.IndexOf(id)}] %{id} => {i.Data}"); - } - } - - ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); - - // Map classSource.GenericArguments ids to OpSDSLGenericParameter.ResultId (in the order OpSDSLGenericParameter appears) - Dictionary> targets = new(); - - // Collect OpSDSLGenericParameter - List generics = new(); - var genericArgumentIndex = 0; - for (var index = 0; index < shader.Count; index++) - { - var i = shader[index]; - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) - { - generics.Add(genericParameter.ResultId); - if (!targets.TryGetValue(classSource.GenericArguments[genericArgumentIndex], out var genericParametersForThisArgument)) - targets.Add(classSource.GenericArguments[genericArgumentIndex], genericParametersForThisArgument = new()); - genericParametersForThisArgument.Add((genericParameter.ResultId, types[genericParameter.ResultType], index)); - genericArgumentIndex++; - SetOpNop(i.Data.Memory.Span); - } - else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) - { - shaderDeclaration.ShaderName = classSource.ToClassName(); - } - } - - // Try to resolve fully the new generic parameter values - // Any parameter resolved will be stored in Dictionary with the string version of the parameter value) - var resolvedParameters = new Dictionary(); - var semantics = new Dictionary(); - if (instantiatingBuffer != null) - { - for (var index = 0; index < instantiatingBuffer.Count; index++) - { - var i = instantiatingBuffer[index]; - if (i.Op == Op.OpConstant || i.Op == Op.OpConstantTrue || i.Op == Op.OpConstantFalse) - { - if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) - { - var value = i.Op switch - { - Op.OpConstant => GetConstantValue(i.Data, instantiatingBuffer), - Op.OpConstantTrue => bool.TrueString.ToLowerInvariant(), - Op.OpConstantFalse => bool.FalseString.ToLowerInvariant(), - }; - - // import constant in current shader - foreach (var parameter in parameters) - { - resolvedParameters.Add(parameter.ResultId, value.ToString()); - var i2 = new OpData(i.Data.Memory.Span); - i2.IdResult = parameter.ResultId; - shader.Replace(parameter.Index, i2); - } - } - } - else if (i.Op == Op.OpConstantStringSDSL && (OpConstantStringSDSL)i is { } constantString) - { - if (targets.TryGetValue(i.Data.IdResult!.Value, out var parameters)) - { - var value = constantString.LiteralString; - // This will be used later for resolving LinkType generics - foreach (var parameter in parameters) - { - resolvedParameters.Add(parameter.ResultId, value); - - if (parameter.Type is GenericParameterType { Kind: GenericParameterKindSDSL.Semantic }) - semantics.Add(names[parameter.ResultId], value); - } - } - } - else if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) - { - // Unresolved parameter, keep as is - } - } - } - - TransformResolvedSemantics(shader, semantics); - TransformResolvedLinkIdIntoLinkString(shader, resolvedParameters); - - // Fully resolved? - if (resolvedParameters.Count == generics.Count) - { - var parameters = string.Join(',', generics.Select(x => resolvedParameters[x])); - var className = classSource.ClassName + "<" + parameters + ">"; - - if (resolveStep == ResolveStep.Mix) - { - classSource.ClassName = className; - classSource.GenericArguments = []; - } - - for (var index = 0; index < shader.Count; index++) - { - var i = shader[index]; - if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) - { - shaderDeclaration.ShaderName = className; - } - } - } - else if (resolveStep == ResolveStep.Mix) - { - throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); - } - } - private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, Dictionary resolvedLinks) { // Try to resolve LinkType generics @@ -553,36 +536,28 @@ public static void RemapIds(Dictionary idRemapping, OpData i) /// public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) { - var shader = GetOrLoadShader(shaderLoader, classSource.ClassName, macros, out var isFromCache); - - if (!isFromCache) - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - - if (classSource.GenericArguments.Length > 0) - { - // Copy shader - shader = CopyShader(shader); - - InstantiateGenericShaderUsingParentBuffer(shader, classSource, resolveStep, parentBuffer); - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - } + return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromClassInstantiation(classSource, parentBuffer, resolveStep), macros); + } - return shader; + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) + { + return GetOrLoadShader(shaderLoader, className, new GenericResolverFromValues(genericValues), macros); } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan defines) + + private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { - var shader = GetOrLoadShader(shaderLoader, className, defines, out var isFromCache); + var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); if (!isFromCache) Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - if (genericValues != null && genericValues.Length > 0) + if (genericResolver.NeedsResolve()) { // Copy shader shader = CopyShader(shader); - InstantiateGenericShaderUsingGenericValues(shader, className, genericValues); + InstantiateGenericShader(shader, className, genericResolver, shaderLoader, macros); Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } From 83c31dfe4c888a6dea61761eb48f8032c5c1d302 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 21 Dec 2025 22:27:38 +0900 Subject: [PATCH 0622/1182] Fix: OpCompositeExtract should use int, not Constant IdRef --- src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 83ca7c99b2..b12fa40194 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -78,7 +78,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) { // Apply swizzle var resultType = v.BaseType; - var extract = InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, value.Id, [context.CompileConstant(swizzleIndices[0]).Id])); + var extract = InsertData(new OpCompositeExtract(context.GetOrRegister(resultType), context.Bound++, value.Id, [swizzleIndices[0]])); value = new(extract); return (value, resultType); From a5ce791d195ae9b502c99246f6d8818653f89069 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 21 Dec 2025 23:59:53 +0900 Subject: [PATCH 0623/1182] Added support for MemberName generics --- .../SDSL/RenderTests/GenericsMemberName.sdsl | 29 +++++ .../ShaderLoaderBase.cs | 115 ++++++++++++++++++ src/Stride.Shaders.Experiments/Examples.cs | 22 +--- .../Extensions/spirv.sdsl.grammar-ext.json | 18 +++ src/Stride.Shaders.Tests/RenderingTests.cs | 24 ++-- src/Stride.Shaders/Core/SymbolTypes.cs | 1 + .../Parsing/SDSL/AST/Literals.cs | 4 + src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 8 +- .../Spirv/Building/Builder.Class.cs | 69 ++++++++++- src/Stride.Shaders/Spirv/Building/Context.cs | 39 +----- 11 files changed, 269 insertions(+), 76 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsMemberName.sdsl create mode 100644 src/Stride.Shaders.Compilers/ShaderLoaderBase.cs diff --git a/assets/SDSL/RenderTests/GenericsMemberName.sdsl b/assets/SDSL/RenderTests/GenericsMemberName.sdsl new file mode 100644 index 0000000000..614232d18d --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsMemberName.sdsl @@ -0,0 +1,29 @@ +// PSMain(ExpectedResult=#1EFFFFFF) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader ComputeMember : Compute +{ + override float Compute() + { + return base.Compute() + float4(10.0, 20.0, 30.0, 40.0).TMember / 255.0; + } +} + +shader GenericsMemberName : ComputeMember<"r">, ComputeMember<"g"> +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs new file mode 100644 index 0000000000..f1af8ac032 --- /dev/null +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -0,0 +1,115 @@ +using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Parsing; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text; + +namespace Stride.Shaders.Compilers; + +public abstract class ShaderLoaderBase : IExternalShaderLoader +{ + record struct ShaderLoadKey(ShaderMacro[] Macros) + { + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + foreach (var current in Macros) + hashCode = (hashCode * 397) ^ (current.GetHashCode()); + return hashCode; + } + } + + public bool Equals(ShaderLoadKey other) + { + return Macros.SequenceEqual(other.Macros); + } + } + + private Dictionary> loadedShaders = []; + + public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer) + { + if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) + loadedShaders.Add(name, loadedShadersByName = new()); + loadedShadersByName.Add(new(defines.ToArray()), buffer); + } + + public bool Exists(string name) + { + if (loadedShaders.ContainsKey(name)) + return true; + + return ExternalFileExists(name); + } + + protected abstract bool ExternalFileExists(string name); + protected abstract bool LoadExternalFileContent(string name, out string filename, out string code); + + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) + { + if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + { + isFromCache = true; + return true; + } + + isFromCache = false; + if (!ExternalFileExists(name)) + { + throw new InvalidOperationException($"Shader {name} could not be found"); + } + + if (!LoadExternalFileContent(name, out var filename, out var code)) + { + throw new InvalidOperationException($"Shader {name} could not be loaded"); + } + + if (!LoadFromCode(filename, code, defines, out buffer)) + { + throw new InvalidOperationException($"Shader {name} could not be compiled"); + } + + return true; + } + + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) + { + if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + { + isFromCache = true; + return true; + } + + var filename = $"{code}.sdsl"; + + isFromCache = false; + if (!LoadFromCode(filename, code, defines, out buffer)) + { + throw new InvalidOperationException($"Shader {name} could not be compiled"); + } + + return true; + } + + protected virtual bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out NewSpirvBuffer buffer) + { + var defines = new (string Name, string Definition)[macros.Length]; + for (int i = 0; i < macros.Length; ++i) + defines[i] = (macros[i].Name, macros[i].Definition); + + var text = MonoGamePreProcessor.Run(code, Path.GetFileName(filename), defines); + var sdslc = new SDSLC + { + ShaderLoader = this, + }; + + return sdslc.Compile(text, macros, out buffer); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 7b90aad3e3..0031af10df 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -216,25 +216,11 @@ protected override bool ExternalFileExists(string name) return File.Exists(filename); } - protected override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + protected override bool LoadExternalFileContent(string name, out string filename, out string code) { - var filename = $"./assets/SDSL/{name}.sdsl"; - if (!File.Exists(filename)) - { - buffer = null; - return false; - } - - var defines = new (string Name, string Definition)[macros.Length]; - for (int i = 0; i < macros.Length; ++i) - defines[i] = (macros[i].Name, macros[i].Definition); - - var text = MonoGamePreProcessor.OpenAndRun(filename, defines); - var sdslc = new SDSLC - { - ShaderLoader = this - }; - return sdslc.Compile(text, macros, out buffer); + filename = $"./assets/SDSL/{name}.sdsl"; + code = File.ReadAllText(filename); + return true; } } diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index adbf23632f..fba536e88e 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -311,6 +311,20 @@ { "opname": "OpForeachEndSDSL", "class": "Miscellaneous" + }, + { + "opname": "OpUnresolvableShaderSDSL", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "shaderCode" + }, + { + "kind": "LiteralInteger", + "name": "shaderCodeNameEnd" + } + ] } ], "operand_kinds": [ @@ -418,6 +432,10 @@ { "enumerant": "MemberName", "value": 3 + }, + { + "enumerant": "MemberNameResolved", + "value": 4 } ] }, diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 883de97cd2..fad53f60c8 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -35,24 +35,16 @@ protected override bool ExternalFileExists(string name) return File.Exists(filename); } - protected override bool LoadExternalFile(string name, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer buffer) + protected override bool LoadExternalFileContent(string name, out string filename, out string code) { - var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; - if (!File.Exists(filename)) - { - buffer = null; - return false; - } - - var defines = new (string Name, string Definition)[macros.Length]; - for (int i = 0; i < macros.Length; ++i) - defines[i] = (macros[i].Name, macros[i].Definition); - - var text = MonoGamePreProcessor.OpenAndRun(filename, defines); - var sdslc = new SDSLC(); - sdslc.ShaderLoader = this; + filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; + code = File.ReadAllText(filename); + return true; + } - var result = sdslc.Compile(text, macros, out buffer); + protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out NewSpirvBuffer buffer) + { + var result = base.LoadFromCode(filename, code, macros, out buffer); #if DEBUG if (result) { diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index d4a2c0a382..a04d02cd5c 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -296,6 +296,7 @@ public override string ToString() { if (i > 0) builder.Append(','); + builder.Append('%'); builder.Append(GenericArguments[i]); } builder.Append('>'); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 58139603c3..339cfe5a6d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -393,6 +393,10 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberName); } + else if (Name == "MemberNameResolved") + { + symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberNameResolved); + } else if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index fc0d07190f..b9d35e3d97 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -316,6 +316,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.Push(); var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; + var hasUnresolvableGenerics = false; if (Generics != null) { for (int i = 0; i < Generics.Parameters.Count; i++) @@ -332,6 +333,9 @@ public void Compile(SymbolTable table, CompilerUnit compiler) openGenerics[i] = context.Bound; context.Bound++; + + if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) + hasUnresolvableGenerics = true; } } @@ -453,8 +457,18 @@ public void Compile(SymbolTable table, CompilerUnit compiler) // (SPIR-V allow forward calling) foreach (var method in Elements.OfType()) method.Declare(table, this, compiler); + foreach (var method in Elements.OfType()) - method.Compile(table, this, compiler); + method.Compile(table, this, compiler, hasUnresolvableGenerics); + + if (hasUnresolvableGenerics) + { + var code = Info.Text.ToString(); + // We also store end of name so that we can later easily use macro system to rename generics without changing the generics header + var nameInfo = Generics?.Parameters.LastOrDefault().Name.Info ?? Name.Info; + var endOfNameIndex = nameInfo.Range.End.Value - Info.Range.Start.Value; + builder.Insert(new OpUnresolvableShaderSDSL(Info.Text.ToString(), endOfNameIndex)); + } table.InheritedShaders = null; table.CurrentShader = null; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b97749ac00..a5da31a77d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -255,7 +255,7 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.CurrentFrame.Add(Name, symbol); } - public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler, bool hasUnresolvableGenerics) { var (builder, context) = compiler; @@ -301,7 +301,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.CurrentFrame.Add(p.Name, new(new(p.Name, SymbolKind.Variable), parameterType, paramValue.Id)); } - if (Body is BlockStatement body) + if (Body is BlockStatement body && !hasUnresolvableGenerics) { table.Push(); builder.CreateBlock(context); @@ -309,6 +309,10 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler s.Compile(table, compiler); table.Pop(); } + else + { + builder.Insert(new OpUnreachable()); + } builder.EndFunction(); } else throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 80e100f1fe..bfc6795846 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,5 +1,6 @@ using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; +using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -9,6 +10,7 @@ using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using static Stride.Shaders.Spirv.Specification; @@ -43,7 +45,7 @@ public string ToClassName() if (GenericArguments != null && GenericArguments.Length > 0) { result.Append('<'); - result.Append(string.Join(",", GenericArguments)); + result.Append(string.Join(",", GenericArguments.Select(x => $"%{x}"))); result.Append('>'); } @@ -378,6 +380,10 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, (string)genericParameter.Value)); semantics.Add(names[genericParameter.ResultId], (string)genericParameter.Value); break; + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.MemberNameResolved: + // There should be no more reference to this MemberName (it should have been resolved during InstantiateMemberNames()) + shader.Replace(index, new OpNop()); + break; default: throw new NotImplementedException(); } @@ -430,6 +436,65 @@ private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary } } + private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, string shaderName, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) + { + bool hasUnresolvableShader = false; + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpUnresolvableShaderSDSL && (OpUnresolvableShaderSDSL)i is { } unresolvableShader) + { + hasUnresolvableShader = true; + } + } + + if (!hasUnresolvableShader) + return shader; + + var instantiatedGenericsMacros = new List<(string Name, string Definition)>(); + var genericParameterIndex = 0; + ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + for (var index = 0; index < shader.Count; index++) + { + var i = shader[index]; + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + { + var genericParameterName = names[genericParameter.ResultId]; + var genericParameterType = types[genericParameter.ResultType]; + if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) + { + if (genericResolver.TryResolveGenericValue(genericParameterType, genericParameterName, genericParameterIndex, out var value)) + instantiatedGenericsMacros.Add((names[genericParameter], value.ToString())); + } + genericParameterIndex++; + } + else if (i.Op == Op.OpUnresolvableShaderSDSL && (OpUnresolvableShaderSDSL)i is { } unresolvableShader) + { + var code = unresolvableShader.ShaderCode; + if (instantiatedGenericsMacros.Count > 0) + { + // Add something to shaderName (which is used as key in ShaderLoader cache) + var originalShaderName = shaderName; + shaderName += $"_{string.Join("_", instantiatedGenericsMacros.Select(x => x.Definition))}"; + + // Note: we apply the preprocessor only the shader body to transform generics parameter into their actual value without touching the generic definition + code = code.Substring(0, unresolvableShader.ShaderCodeNameEnd) + // Update shader name for ShaderLoader cache + .Replace(originalShaderName, shaderName) + // Mark MemberName as resolved + .Replace("MemberName ", "MemberNameResolved ") + + MonoGamePreProcessor.Run(code.Substring(unresolvableShader.ShaderCodeNameEnd), $"{shaderName}.sdsl", CollectionsMarshal.AsSpan(instantiatedGenericsMacros)); + } + + if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shader, out _)) + throw new InvalidOperationException(); + return shader; + } + } + + return shader; + } + private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, Dictionary resolvedLinks) { // Try to resolve LinkType generics @@ -554,6 +619,8 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader if (genericResolver.NeedsResolve()) { + shader = InstantiateMemberNames(shader, className, genericResolver, shaderLoader, macros); + // Copy shader shader = CopyShader(shader); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 2b093822d1..c5d57be07f 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -18,44 +18,7 @@ public interface IExternalShaderLoader public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer); public bool Exists(string name); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); -} - -public abstract class ShaderLoaderBase : IExternalShaderLoader -{ - private Dictionary loadedShaders = []; - - public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer) - { - loadedShaders.Add(name, buffer); - } - - public bool Exists(string name) - { - if (loadedShaders.ContainsKey(name)) - return true; - - return ExternalFileExists(name); - } - - protected abstract bool ExternalFileExists(string name); - protected abstract bool LoadExternalFile(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer); - - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) - { - if (loadedShaders.TryGetValue(name, out buffer)) - { - isFromCache = true; - return true; - } - - isFromCache = false; - if (!LoadExternalFile(name, defines, out buffer)) - { - throw new InvalidOperationException($"Shader {name} could not be found"); - } - - return true; - } + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other From 4ea1198f38ac81f91e8c9f1d7035f009e0f0c289 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 00:14:10 +0900 Subject: [PATCH 0624/1182] Generics: unresolved identifiers are considered to be string constant as a fallback --- assets/SDSL/RenderTests/GenericsMemberName.sdsl | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/assets/SDSL/RenderTests/GenericsMemberName.sdsl b/assets/SDSL/RenderTests/GenericsMemberName.sdsl index 614232d18d..b49f6b9ec0 100644 --- a/assets/SDSL/RenderTests/GenericsMemberName.sdsl +++ b/assets/SDSL/RenderTests/GenericsMemberName.sdsl @@ -18,7 +18,7 @@ shader ComputeMember : Compute } } -shader GenericsMemberName : ComputeMember<"r">, ComputeMember<"g"> +shader GenericsMemberName : ComputeMember<"r">, ComputeMember { stream float4 ColorTarget : SV_Target0; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index b9d35e3d97..8cbb15f38b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -347,7 +347,22 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { for (int i = 0; i < mixin.Generics.Values.Count; i++) { - generics[i] = mixin.Generics.Values[i].CompileAsValue(table, compiler).Id; + // Special case: if it's an identifier and can't be resolved, we'll consider it's a string instead + if (mixin.Generics.Values[i] is Identifier identifier) + { + if (table.TryResolveSymbol(identifier.Name, out var symbol)) + { + generics[i] = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, symbol, false).Id; + } + else + { + generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).IdResult.Value; + } + } + else + { + generics[i] = mixin.Generics.Values[i].CompileAsValue(table, compiler).Id; + } } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); From 1c1c18c0dd07b5812db439207dca0b14f40fda3d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 00:19:49 +0900 Subject: [PATCH 0625/1182] Allow SamplerState inside Rgroups --- assets/SDSL/RenderTests/Rgroups.sdsl | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/assets/SDSL/RenderTests/Rgroups.sdsl b/assets/SDSL/RenderTests/Rgroups.sdsl index f46034272c..dd4c0a1b34 100644 --- a/assets/SDSL/RenderTests/Rgroups.sdsl +++ b/assets/SDSL/RenderTests/Rgroups.sdsl @@ -15,11 +15,11 @@ shader Rgroups : RgroupBase stream float4 ColorTarget : SV_Target0; stream float2 TexCoord : TEXCOORD; - stage SamplerState Sampler1; rgroup Group1 { stage Texture2D Texture2; + stage SamplerState Sampler1; } void PSMain() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 339cfe5a6d..a80b9933e1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -416,6 +416,10 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh table.DeclaredTypes.Add(genericBufferType.ToString(), genericBufferType); symbolType = genericBufferType; } + else if (Name == "SamplerState") + { + symbolType = new SamplerType(); + } if (symbolType == null) return false; From e23f75fad1af76083a3961b841944be9d3e208aa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 00:34:51 +0900 Subject: [PATCH 0626/1182] Moved Texture.Sample/Load as part of normal OpAccessChain so that swizzle can be applied right after --- assets/SDSL/RenderTests/TextureSample.sdsl | 4 +- .../Parsing/SDSL/AST/Expression.cs | 406 +++++++++--------- 2 files changed, 211 insertions(+), 199 deletions(-) diff --git a/assets/SDSL/RenderTests/TextureSample.sdsl b/assets/SDSL/RenderTests/TextureSample.sdsl index 7b36cfe25c..9db879ae89 100644 --- a/assets/SDSL/RenderTests/TextureSample.sdsl +++ b/assets/SDSL/RenderTests/TextureSample.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1357ABCD, texture.Texture1=#1357ABCD) +// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD) namespace Stride.Shaders.Tests; @@ -12,6 +12,6 @@ shader TextureSample void PSMain() { - streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord); + streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord).yxwz; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 2532d511c9..8cddcbe363 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -343,243 +343,255 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) result = Source.Compile(table, compiler); currentValueType = Source.Type; } - if (Source is Identifier { Type: PointerType { BaseType: Texture1DType or Texture2DType or Texture3DType } } && Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }]) - { - result = Source.CompileAsValue(table, compiler); - var textureType = (TextureType)Source.ValueType; - if (Accessors is [MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling]) - { - Type = new VectorType(textureType.ReturnType, 4); - - var textureValue = result; - var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(Type); - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, Specification.ImageOperandsMask.None)); - return new(sample.ResultId, sample.ResultType); - } - else if (Accessors is [MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling]) - { - Type = new VectorType(textureType.ReturnType, 4); - - var textureValue = result; - var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); - var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); - - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(Type); - var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); - return new(sample.ResultId, sample.ResultType); - } - else - throw new InvalidOperationException("Invalid Sample method call"); - } - else if (Source is Identifier { Type: PointerType { BaseType: BufferType or TextureType } pointerType } && Accessors is [MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load]) + + int accessChainIdCount = 0; + void PushAccessChainId(Span accessChainIds, int accessChainIndex) { - Type = new VectorType(pointerType.BaseType switch - { - BufferType b => b.BaseType, - TextureType t => t.ReturnType, - }, 4); - - var returnType = context.GetOrRegister(Type); - var coords = load.Parameters.Values[0].CompileAsValue(table, compiler); - var resource = result; - var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null)); - return new(loadResult.ResultId, loadResult.ResultType); + accessChainIds[accessChainIdCount++] = accessChainIndex; } - else + void EmitOpAccessChain(Span accessChainIds) { - int accessChainIdCount = 0; - void PushAccessChainId(Span accessChainIds, int accessChainIndex) - { - accessChainIds[accessChainIdCount++] = accessChainIndex; - } - void EmitOpAccessChain(Span accessChainIds) + // Do we need to issue an OpAccessChain? + if (accessChainIdCount > 0) { - // Do we need to issue an OpAccessChain? - if (accessChainIdCount > 0) - { - var resultType = context.GetOrRegister(currentValueType); - var test = new LiteralArray(accessChainIds); - var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); - result = new SpirvValue(accessChain.ResultId, resultType) { Swizzles = result.Swizzles }; - } - - accessChainIdCount = 0; + var resultType = context.GetOrRegister(currentValueType); + var test = new LiteralArray(accessChainIds); + var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); + result = new SpirvValue(accessChain.ResultId, resultType) { Swizzles = result.Swizzles }; } - Span accessChainIds = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i < Accessors.Count; i++) + accessChainIdCount = 0; + } + + Span accessChainIds = stackalloc int[Accessors.Count]; + for (var i = firstIndex; i < Accessors.Count; i++) + { + var accessor = Accessors[i]; + switch (currentValueType, accessor) { - var accessor = Accessors[i]; - switch (currentValueType, accessor) - { - case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + case (PointerType { BaseType: Texture1DType or Texture2DType or Texture3DType }, MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }): + { // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); + var textureValue = builder.AsValue(context, result); - methodCall2.MemberCall = result; - result = methodCall2.Compile(table, compiler); - break; - case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + // Load texture as value + result = builder.AsValue(context, result); - if (!s.TryResolveSymbol(context, field.Name, out var matchingComponent)) - throw new InvalidOperationException(); + var textureType = (TextureType)context.ReverseTypes[result.TypeId]; + if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling) + { + var resultType = new VectorType(textureType.ReturnType, 4); - // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, matchingComponent, false, result.Id); - accessor.Type = matchingComponent.Type; + var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(resultType); + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, Specification.ImageOperandsMask.None)); - break; - case (PointerType { BaseType: StructType s } p, Identifier field): - - var index = s.TryGetFieldIndex(field); - if (index == -1) - throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); - //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); - accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); - break; - // Swizzles - case (PointerType { BaseType: VectorType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - if (swizzle.Length > 1) + result = new(sample.ResultId, sample.ResultType); + accessor.Type = resultType; + } + else if (accessor is MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling) { - Span swizzleIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + var resultType = new VectorType(textureType.ReturnType, 4); - result.ApplySwizzles(swizzleIndices); + var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); + var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); - // Check resulting swizzles - for (int j = 0; j < result.Swizzles.Length; ++j) - if (swizzleIndices[j] >= s.Size) - throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(resultType); + var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); - accessor.Type = currentValueType; + result = new(sample.ResultId, sample.ResultType); + accessor.Type = resultType; } else - { - PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); - accessor.Type = new PointerType(s.BaseType, p.StorageClass); - } + throw new InvalidOperationException("Invalid Sample method call"); break; - case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - { - Span swizzleIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - - (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); - accessor.Type = v; + } + case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load): + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); - break; - } - case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - if (swizzle.Length > 1) + var resultType = new VectorType(pointerType.BaseType switch { - Span swizzleIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + BufferType b => b.BaseType, + TextureType t => t.ReturnType, + }, 4); + + var resource = builder.AsValue(context, result); + var returnType = context.GetOrRegister(resultType); + var coords = load.Parameters.Values[0].CompileAsValue(table, compiler); + var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null)); + result = new(loadResult.ResultId, loadResult.ResultType); + accessor.Type = resultType; + break; + } + case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + + methodCall2.MemberCall = result; + result = methodCall2.Compile(table, compiler); + break; + case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + + if (!s.TryResolveSymbol(context, field.Name, out var matchingComponent)) + throw new InvalidOperationException(); + + // TODO: figure out instance (this vs composition) + result = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, matchingComponent, false, result.Id); + accessor.Type = matchingComponent.Type; + + break; + case (PointerType { BaseType: StructType s } p, Identifier field): + + var index = s.TryGetFieldIndex(field); + if (index == -1) + throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; + PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); + accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); + break; + // Swizzles + case (PointerType { BaseType: VectorType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - result.ApplySwizzles(swizzleIndices); - accessor.Type = currentValueType; - } - else - { - if (ConvertSwizzle(swizzle[0]) != 0) + result.ApplySwizzles(swizzleIndices); + + // Check resulting swizzles + for (int j = 0; j < result.Swizzles.Length; ++j) + if (swizzleIndices[j] >= s.Size) throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - // Do nothing - accessor.Type = currentValueType; - } + accessor.Type = currentValueType; + } + else + { + PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); + accessor.Type = new PointerType(s.BaseType, p.StorageClass); + } + break; + case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + { + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + + (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); + accessor.Type = v; + break; - case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - if (swizzle.Length > 1) - { - Span swizzleIndices = stackalloc int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - { - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - if (swizzleIndices[j] != 0) - throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - } - - (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); - accessor.Type = s; - } - else + } + case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + + result.ApplySwizzles(swizzleIndices); + accessor.Type = currentValueType; + } + else + { + if (ConvertSwizzle(swizzle[0]) != 0) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + + // Do nothing + accessor.Type = currentValueType; + } + break; + case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + if (swizzle.Length > 1) + { + Span swizzleIndices = stackalloc int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) { - // Do nothing - accessor.Type = currentValueType; + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + if (swizzleIndices[j] != 0) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); } + + (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); + accessor.Type = s; + } + else + { + // Do nothing + accessor.Type = currentValueType; + } + break; + // Array indexer for shader compositions + case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): + break; + // Array indexer for arrays + case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): + { + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + accessor.Type = new PointerType(t, p.StorageClass); break; - // Array indexer for shader compositions - case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): - break; - // Array indexer for arrays - case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): - { - var indexerValue = indexer.Index.CompileAsValue(table, compiler); - PushAccessChainId(accessChainIds, indexerValue.Id); - accessor.Type = new PointerType(t, p.StorageClass); - break; - } - // Array indexer for vector/matrix - case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): - { - var indexerValue = indexer.Index.CompileAsValue(table, compiler); - PushAccessChainId(accessChainIds, indexerValue.Id); - - accessor.Type = new PointerType(p.BaseType switch - { - MatrixType m => new VectorType(m.BaseType, m.Rows), - VectorType v => v.BaseType, - }, p.StorageClass); - break; - } - case (PointerType { BaseType: var type }, PostfixIncrement postfix): - { - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + } + // Array indexer for vector/matrix + case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): + { + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); - // Not supported yet - result.ThrowIfSwizzle(); + accessor.Type = new PointerType(p.BaseType switch + { + MatrixType m => new VectorType(m.BaseType, m.Rows), + VectorType v => v.BaseType, + }, p.StorageClass); + break; + } + case (PointerType { BaseType: var type }, PostfixIncrement postfix): + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); - var resultPointer = result; + // Not supported yet + result.ThrowIfSwizzle(); - // This is what this chain return (value before modification) - result = builder.AsValue(context, result); + var resultPointer = result; - // Use integer so that it gets converted to proper type according to expression type - var constant1 = context.CompileConstant(1); - var modifiedValue = builder.BinaryOperation(context, result, postfix.Operator switch - { - Operator.Inc => Operator.Plus, - Operator.Dec => Operator.Minus, - }, constant1); + // This is what this chain return (value before modification) + result = builder.AsValue(context, result); - // We store the modified value back in the variable - builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null)); + // Use integer so that it gets converted to proper type according to expression type + var constant1 = context.CompileConstant(1); + var modifiedValue = builder.BinaryOperation(context, result, postfix.Operator switch + { + Operator.Inc => Operator.Plus, + Operator.Dec => Operator.Minus, + }, constant1); - break; - } - default: - throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); - } + // We store the modified value back in the variable + builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null)); - currentValueType = accessor.Type; + break; + } + default: + throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); } - EmitOpAccessChain(accessChainIds); + currentValueType = accessor.Type; } + EmitOpAccessChain(accessChainIds); + Type = currentValueType; return result; From e4b01b95f83fee1039ddef11dfa5f36ff1435ba4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 14:13:23 +0900 Subject: [PATCH 0627/1182] Added ternary operator --- assets/SDSL/RenderTests/TernaryOperator.sdsl | 34 +++++++ .../Parsing/SDSL/AST/Expression.cs | 88 +++++++++++++++++-- .../Parsing/SDSL/AST/Statements.Control.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 31 ++++++- 4 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 assets/SDSL/RenderTests/TernaryOperator.sdsl diff --git a/assets/SDSL/RenderTests/TernaryOperator.sdsl b/assets/SDSL/RenderTests/TernaryOperator.sdsl new file mode 100644 index 0000000000..b70a3fabba --- /dev/null +++ b/assets/SDSL/RenderTests/TernaryOperator.sdsl @@ -0,0 +1,34 @@ +// PSMain(ExpectedResult=#FF0000FF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#FF0000FF, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=4)) + +namespace Stride.Shaders.Tests; + +shader TernaryOperator +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + + float4 v1 = float4(1.0, 0.0, 0.0, 1.0); + + // Those two should use OpSelect + if (Test1 == 1) + streams.ColorTarget = v1 > 0.5 ? 1.0 : 0.0; + if (Test1 == 2) + streams.ColorTarget = v1 > 0.5 ? float4(1.0, 1.0, 1.0, 1.0) : float4(0.0, 0.0, 0.0, 0.0); + // Those two should use OpBranch + if (Test1 == 3) + streams.ColorTarget = v1.x > 0.5 ? float4(1.0, 1.0, 1.0, 1.0) : float4(0.0, 0.0, 0.0, 0.0); + if (Test1 == 4) + streams.ColorTarget = v1.y > 0.5 ? float4(1.0, 1.0, 1.0, 1.0) : float4(0.0, 0.0, 0.0, 0.0); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 8cddcbe363..b2dc6ab78c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -657,14 +657,88 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { - Condition.CompileAsValue(table, compiler); - Left.CompileAsValue(table, compiler); - Right.CompileAsValue(table, compiler); - if (Condition.ValueType is not ScalarType { TypeName: "bool" }) - table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - if (Left.ValueType != Right.ValueType) + var (builder, context) = compiler; + + var conditionValue = Condition.CompileAsValue(table, compiler); + + var leftValueBuffer = new NewSpirvBuffer(); + var rightValueBuffer = new NewSpirvBuffer(); + + // We store left/right values in temporary buffer: we need to emit them now to know type but we don't want to actually insert them later in builder buffer + SpirvValue leftResult; + using (builder.UseTemporaryBuffer(leftValueBuffer)) + leftResult = Left.CompileAsValue(table, compiler); + SpirvValue rightResult; + using (builder.UseTemporaryBuffer(rightValueBuffer)) + rightResult = Right.CompileAsValue(table, compiler); + + if (Condition.ValueType.GetElementType() is not ScalarType { TypeName: "bool" }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - throw new NotImplementedException(); + + var scalarType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(Left.ValueType.GetElementType(), Right.ValueType.GetElementType()); + var resultType = (Condition.ValueType, Left.ValueType, Right.ValueType) switch + { + // If condition is a vector, we need to use this vector size instead + (VectorType c, _, _) => new VectorType(scalarType, c.Size), + (ScalarType c, ScalarType, ScalarType) => scalarType, + (ScalarType c, VectorType v1, ScalarType s2) => v1.WithElementType(scalarType), + (ScalarType c, ScalarType s1, VectorType v2) => v2.WithElementType(scalarType), + (ScalarType c, VectorType v1, VectorType v2) => new VectorType(scalarType, Math.Min(v1.Size, v2.Size)), + }; + + // Convert type for Left/Right + using (builder.UseTemporaryBuffer(leftValueBuffer)) + leftResult = builder.Convert(context, leftResult, resultType); + using (builder.UseTemporaryBuffer(rightValueBuffer)) + rightResult = builder.Convert(context, rightResult, resultType); + + // TODO: Review choice between if/else like branch (OpBranchConditional) which evaluate only one side, or select (OpSelect) which evaluate both side but can work per component but is limited to specific types + // It seems HLSL 2021 changed the behavior to align it with C-style short-circuiting. + // For now, we use OpSelect only with per-component, otherwise we use if/else branching + bool isBranching = Condition.ValueType is ScalarType; + + if (isBranching) + { + var resultVariable = context.Bound++; + builder.AddFunctionVariable(context.GetOrRegister(new PointerType(resultType, Specification.StorageClass.Function)), resultVariable); + + var blockMergeId = context.Bound++; + var blockTrueId = context.Bound++; + var blockFalseId = context.Bound++; + + // OpSelectionMerge and OpBranchConditional (will be filled later) + builder.Insert(new OpSelectionMerge(blockMergeId, Specification.SelectionControlMask.None)); + builder.Insert(new OpBranchConditional(conditionValue.Id, blockTrueId, blockFalseId, [])); + + // Block when choosing left value + builder.CreateBlock(context, blockTrueId, $"ternary_true"); + builder.Merge(leftValueBuffer); + builder.Insert(new OpStore(resultVariable, leftResult.Id, null)); + builder.Insert(new OpBranch(blockMergeId)); + + // Block when choosing right value + builder.CreateBlock(context, blockFalseId, $"ternary_false"); + builder.Merge(rightValueBuffer); + builder.Insert(new OpStore(resultVariable, rightResult.Id, null)); + builder.Insert(new OpBranch(blockMergeId)); + + builder.CreateBlock(context, blockMergeId, "ternary_merge"); + var result = builder.Insert(new OpLoad(context.GetOrRegister(resultType), context.Bound++, resultVariable, null)); + return new(result.ResultId, result.ResultType); + } + else + { + if (resultType is VectorType v && Condition.ValueType is ScalarType conditionScalar) + { + conditionValue = builder.Convert(context, conditionValue, new VectorType(conditionScalar, v.Size)); + } + + builder.Merge(leftValueBuffer); + builder.Merge(rightValueBuffer); + + var result = builder.Insert(new OpSelect(context.GetOrRegister(resultType), context.Bound++, conditionValue.Id, leftResult.Id, rightResult.Id)); + return new(result.ResultId, result.ResultType); + } } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 630838129d..17b03266e5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -41,7 +41,7 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) ? context.Bound++ : null; - // OpSelectionMerge and OpBranchConditional (will be filled later) + // OpSelectionMerge and OpBranchConditional builder.Insert(new OpSelectionMerge(blockMergeIds[i], Specification.SelectionControlMask.None)); builder.Insert(new OpBranchConditional(conditionValue.Id, blockTrueIds[i], falseBlock ?? blockMergeIds[i], [])); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index b10034443f..27b7dc2782 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -14,7 +15,8 @@ public partial class SpirvBuilder() { private int position; - NewSpirvBuffer Buffer { get; init; } = new(); + NewSpirvBuffer buffer = new(); + NewSpirvBuffer Buffer { get => buffer; init => buffer = value; } public SpirvFunction? CurrentFunction { get; internal set; } public SpirvBlock? CurrentBlock { get; internal set; } public ref int Position => ref position; @@ -105,4 +107,31 @@ public override string ToString() { return Spv.Dis(Buffer, writeToConsole: false); } + + public UseTemporaryBufferHelper UseTemporaryBuffer(NewSpirvBuffer buffer, int? position = null) + { + var result = new UseTemporaryBufferHelper(this, this.buffer, this.position); + this.buffer = buffer; + this.position = position ?? buffer.Count; + return result; + } + + public void Merge(NewSpirvBuffer other) + { + var instructions = new List(); + foreach (var instruction in other) + instructions.Add(instruction.Data); + + buffer.InsertRange(Position, instructions.AsSpan()); + Position += other.Count; + } + + public struct UseTemporaryBufferHelper(SpirvBuilder builder, NewSpirvBuffer buffer, int position) : IDisposable + { + public void Dispose() + { + builder.buffer = buffer; + builder.position = position; + } + } } From cef75d1739e29d48c6c087bcd255fd5bbcda068c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 14:45:16 +0900 Subject: [PATCH 0628/1182] table.DeclaredTypes: use full type name --- .../Parsing/SDSL/AST/Literals.cs | 57 +++++++++++-------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index a80b9933e1..8f41fe2815 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -397,28 +397,33 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberNameResolved); } - else if (table.DeclaredTypes.TryGetValue(Name, out symbolType)) + else { + var fullTypeName = GenerateTypeName(includeGenerics: true, includeArray: false); - } - else if (SymbolType.TryGetNumeric(Name, out var numeric)) - { - table.DeclaredTypes.Add(numeric.ToString(), numeric); - symbolType = numeric; - } - else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) - { - table.DeclaredTypes.Add(bufferType.ToString(), bufferType); - symbolType = bufferType; - } - else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) - { - table.DeclaredTypes.Add(genericBufferType.ToString(), genericBufferType); - symbolType = genericBufferType; - } - else if (Name == "SamplerState") - { - symbolType = new SamplerType(); + if (table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) + { + + } + else if (SymbolType.TryGetNumeric(Name, out var numeric)) + { + table.DeclaredTypes.Add(fullTypeName, numeric); + symbolType = numeric; + } + else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) + { + table.DeclaredTypes.Add(fullTypeName, bufferType); + symbolType = bufferType; + } + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) + { + table.DeclaredTypes.Add(fullTypeName, genericBufferType); + symbolType = genericBufferType; + } + else if (Name == "SamplerState") + { + symbolType = new SamplerType(); + } } if (symbolType == null) @@ -457,18 +462,24 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) throw new NotImplementedException(); } - public override string ToString() + public override string ToString() => GenerateTypeName(includeGenerics: true, includeArray: true); + + public string GenerateTypeName(bool includeGenerics = true, bool includeArray = true) { + // Fast path + if ((Generics.Count == 0 || !includeGenerics) && (!includeArray || ArraySize == null)) + return Name; + var builder = new StringBuilder(); builder.Append(Name); - if (Generics.Count > 0) + if (includeGenerics && Generics.Count > 0) { builder.Append('<'); foreach (var g in Generics) builder.Append(g.ToString()).Append(", "); builder.Append('>'); } - if (ArraySize != null) + if (includeArray && ArraySize != null) foreach (var s in ArraySize) builder.Append('[').Append(s.ToString()).Append(']'); From 4f37e06df86879e3df40fdc6f14c2355713aaaff Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 14:46:30 +0900 Subject: [PATCH 0629/1182] Added TextureCube --- src/Stride.Shaders/Core/SymbolTypes.cs | 1 + src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 3 +-- src/Stride.Shaders/Spirv/Building/Context.cs | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index a04d02cd5c..53380a9d98 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -72,6 +72,7 @@ public static bool TryGetBufferType(string name, string? templateTypeName, [Mayb ("Texture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture1DType(scalarType) as SymbolType, true), ("Texture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture2DType(scalarType) as SymbolType, true), ("Texture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture3DType(scalarType) as SymbolType, true), + ("TextureCube", ScalarType { TypeName: "float" or "int" or "uint" }) => (new TextureCubeType(scalarType) as SymbolType, true), _ => (null, false) }; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index b2dc6ab78c..bf8820c3d4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -369,7 +369,7 @@ void EmitOpAccessChain(Span accessChainIds) var accessor = Accessors[i]; switch (currentValueType, accessor) { - case (PointerType { BaseType: Texture1DType or Texture2DType or Texture3DType }, MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }): + case (PointerType { BaseType: TextureType textureType }, MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }): { // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); @@ -378,7 +378,6 @@ void EmitOpAccessChain(Span accessChainIds) // Load texture as value result = builder.AsValue(context, result); - var textureType = (TextureType)context.ReverseTypes[result.TypeId]; if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling) { var resultType = new VectorType(textureType.ReturnType, 4); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index c5d57be07f..51b36d5870 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -165,6 +165,7 @@ public int GetOrRegister(SymbolType? type) Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + TextureCubeType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Dim.Buffer, 2, 0, 0, 1, ImageFormat.Unknown, null)).IdResult, SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, From e741f158ab7578a68a51c0d22dc9e0175d6e1eec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 16:25:42 +0900 Subject: [PATCH 0630/1182] SamplerState parameters are properly parsed and kept in reflection --- .../SDSL/ShaderMixer.cs | 57 ++++ .../Stride.Shaders.Compilers.csproj | 3 + .../Extensions/spirv.sdsl.grammar-ext.json | 304 ++++++++++++++++++ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 72 ++++- 4 files changed, 427 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 172dd8675b..bee55fe838 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -826,6 +826,7 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon Dictionary linkInfos = new(); string currentShaderName = string.Empty; + var samplerStates = new Dictionary(); for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = buffer[index]; @@ -854,6 +855,59 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon { currentShaderName = shader.ShaderName; } + else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && (OpDecorate)i is + { + Decoration: + { + Value: Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW + or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD, + Parameters: { } p + } + } decorate) + { + ref var samplerState = ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var added); + if (added) + samplerState = Graphics.SamplerStateDescription.Default; + switch (decorate.Decoration.Value) + { + case Decoration.SamplerStateFilter: + samplerState.Filter = (Graphics.TextureFilter)p.Span[0]; + break; + case Decoration.SamplerStateAddressU: + samplerState.AddressU = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Decoration.SamplerStateAddressV: + samplerState.AddressV = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Decoration.SamplerStateAddressW: + samplerState.AddressW = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Decoration.SamplerStateMipLODBias: + { + using var n = new LiteralValue(p.Span); + samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); + break; + } + case Decoration.SamplerStateMaxAnisotropy: + samplerState.MaxAnisotropy = p.Span[0]; + break; + case Decoration.SamplerStateComparisonFunc: + samplerState.CompareFunction = (Graphics.CompareFunction)p.Span[0]; + break; + case Decoration.SamplerStateMinLOD: + { + using var n = new LiteralValue(p.Span); + samplerState.MinMipLevel = float.Parse(n.Value); + break; + } + case Decoration.SamplerStateMaxLOD: + { + using var n = new LiteralValue(p.Span); + samplerState.MaxMipLevel = float.Parse(n.Value); + break; + } + } + } else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) { var type = context.ReverseTypes[variable.ResultType]; @@ -920,6 +974,9 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(samplerSlot))); + if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) + globalContext.Reflection.SamplerStates.Add(new EffectSamplerStateBinding(linkName, samplerState)); + cbufferSlot++; } else if (pointerType.BaseType is ConstantBufferSymbol) diff --git a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 7676b09203..3f0428b485 100644 --- a/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -20,6 +20,9 @@ $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.dll + Always diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index fba536e88e..a3a3755f8c 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -414,6 +414,96 @@ } ], "version": "1.0" + }, + { + "enumerant": "SamplerStateFilter", + "value": 8020, + "parameters": [ + { + "kind": "SamplerFilterSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressU", + "value": 8021, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressV", + "value": 8022, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressW", + "value": 8023, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMipLODBias", + "value": 8024, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMaxAnisotropy", + "value": 8025, + "parameters": [ + { + "kind": "LiteralInteger" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateComparisonFunc", + "value": 8026, + "parameters": [ + { + "kind": "SamplerComparisonFuncSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMinLOD", + "value": 8027, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMaxLOD", + "value": 8028, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" } ] }, @@ -447,6 +537,220 @@ "value": 5367 } ] + }, + { + "category": "ValueEnum", + "kind": "SamplerTextureAddressModeSDSL", + "enumerants": [ + { + "enumerant": "Wrap", + "value": 1 + }, + { + "enumerant": "Mirror", + "value": 2 + }, + { + "enumerant": "Clamp", + "value": 3 + }, + { + "enumerant": "Border", + "value": 4 + }, + { + "enumerant": "MirrorOnce", + "value": 5 + } + ] + }, + { + "category": "ValueEnum", + "kind": "SamplerFilterSDSL", + "enumerants": [ + { + "enumerant": "MIN_MAG_MIP_POINT", + "value": "0" + }, + { + "enumerant": "MIN_MAG_POINT_MIP_LINEAR", + "value": "0x1" + }, + { + "enumerant": "MIN_POINT_MAG_LINEAR_MIP_POINT", + "value": "0x4" + }, + { + "enumerant": "MIN_POINT_MAG_MIP_LINEAR", + "value": "0x5" + }, + { + "enumerant": "MIN_LINEAR_MAG_MIP_POINT", + "value": "0x10" + }, + { + "enumerant": "MIN_LINEAR_MAG_POINT_MIP_LINEAR", + "value": "0x11" + }, + { + "enumerant": "MIN_MAG_LINEAR_MIP_POINT", + "value": "0x14" + }, + { + "enumerant": "MIN_MAG_MIP_LINEAR", + "value": "0x15" + }, + { + "enumerant": "ANISOTROPIC", + "value": "0x55" + }, + { + "enumerant": "COMPARISON_MIN_MAG_MIP_POINT", + "value": "0x80" + }, + { + "enumerant": "COMPARISON_MIN_MAG_POINT_MIP_LINEAR", + "value": "0x81" + }, + { + "enumerant": "COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT", + "value": "0x84" + }, + { + "enumerant": "COMPARISON_MIN_POINT_MAG_MIP_LINEAR", + "value": "0x85" + }, + { + "enumerant": "COMPARISON_MIN_LINEAR_MAG_MIP_POINT", + "value": "0x90" + }, + { + "enumerant": "COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR", + "value": "0x91" + }, + { + "enumerant": "COMPARISON_MIN_MAG_LINEAR_MIP_POINT", + "value": "0x94" + }, + { + "enumerant": "COMPARISON_MIN_MAG_MIP_LINEAR", + "value": "0x95" + }, + { + "enumerant": "COMPARISON_ANISOTROPIC", + "value": "0xd5" + }, + { + "enumerant": "MINIMUM_MIN_MAG_MIP_POINT", + "value": "0x100" + }, + { + "enumerant": "MINIMUM_MIN_MAG_POINT_MIP_LINEAR", + "value": "0x101" + }, + { + "enumerant": "MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT", + "value": "0x104" + }, + { + "enumerant": "MINIMUM_MIN_POINT_MAG_MIP_LINEAR", + "value": "0x105" + }, + { + "enumerant": "MINIMUM_MIN_LINEAR_MAG_MIP_POINT", + "value": "0x110" + }, + { + "enumerant": "MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR", + "value": "0x111" + }, + { + "enumerant": "MINIMUM_MIN_MAG_LINEAR_MIP_POINT", + "value": "0x114" + }, + { + "enumerant": "MINIMUM_MIN_MAG_MIP_LINEAR", + "value": "0x115" + }, + { + "enumerant": "MINIMUM_ANISOTROPIC", + "value": "0x155" + }, + { + "enumerant": "MAXIMUM_MIN_MAG_MIP_POINT", + "value": "0x180" + }, + { + "enumerant": "MAXIMUM_MIN_MAG_POINT_MIP_LINEAR", + "value": "0x181" + }, + { + "enumerant": "MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT", + "value": "0x184" + }, + { + "enumerant": "MAXIMUM_MIN_POINT_MAG_MIP_LINEAR", + "value": "0x185" + }, + { + "enumerant": "MAXIMUM_MIN_LINEAR_MAG_MIP_POINT", + "value": "0x190" + }, + { + "enumerant": "MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR", + "value": "0x191" + }, + { + "enumerant": "MAXIMUM_MIN_MAG_LINEAR_MIP_POINT", + "value": "0x194" + }, + { + "enumerant": "MAXIMUM_MIN_MAG_MIP_LINEAR", + "value": "0x195" + }, + { + "enumerant": "MAXIMUM_ANISOTROPIC", + "value": "0x1d5" + } + ] + }, + { + "category": "ValueEnum", + "kind": "SamplerComparisonFuncSDSL", + "enumerants": [ + { + "enumerant": "Never", + "value": 1 + }, + { + "enumerant": "Less", + "value": 2 + }, + { + "enumerant": "Equal", + "value": 3 + }, + { + "enumerant": "LessEqual", + "value": 4 + }, + { + "enumerant": "Greater", + "value": 5 + }, + { + "enumerant": "NotEqual", + "value": 6 + }, + { + "enumerant": "GreaterEqual", + "value": 7 + }, + { + "enumerant": "Always", + "value": 8 + } + ] } ] } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index a5da31a77d..66b8e09fb2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -38,20 +38,74 @@ public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMe public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { - // TODO: sampler states with paramters not implemented - // The main issue is that SPIR-V doesn't have a direct equivalent of sampler states with parameters. - // We can create a basic sampler, but handling parameters would require a more complex approach, - // potentially storing parameters in a new SDSL specific instruction or decorations - - if (Parameters.Count > 0) - table.Errors.Add(new SemanticErrors(Info, "Sampler states with parameters are not supported in SPIR-V generation.")); - (var builder, var context) = compiler; Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); var registeredType = context.GetOrRegister(Type); if (!table.RootSymbols.TryGetValue(Name, out _)) { - var register = builder.Insert(new OpVariableSDSL(registeredType, context.Bound++, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + var variableId = context.Bound++; + + // We store SamplerState as decoration for later processing during ShaderMixer.ProcessReflection() + // Note: we make sure to do it before the OpVariableSDSL as per SPIR-V spec so that it is correctly processed later + foreach (var parameter in Parameters) + { + switch (parameter.Name) + { + case "Filter": + { + var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); + builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateFilter(filter))); + break; + } + case "AddressU": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressU(addressMode))); + break; + } + case "AddressV": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressV(addressMode))); + break; + } + case "AddressW": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressW(addressMode))); + break; + } + case "MipLODBias": + { + var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; + builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMipLODBias(mipLODBias.ToString()))); + break; + } + case "MaxAnisotropy": + { + var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; + builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateMaxAnisotropy(maxAnisotropy))); + break; + } + case "MinLOD": + { + var minLOD = (float)((FloatLiteral)parameter.Value).Value; + builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMinLOD(minLOD.ToString()))); + break; + } + case "MaxLOD": + { + var maxLOD = (float)((FloatLiteral)parameter.Value).Value; + builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMaxLOD(maxLOD.ToString()))); + break; + } + case "BorderColor": + default: + throw new NotImplementedException(); + } + } + + var register = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(register.ResultId, Name); var sid = new SymbolID(Name, SymbolKind.SamplerState); From fd66096b028d785053d9708721ec8832d83523db Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 16:46:55 +0900 Subject: [PATCH 0631/1182] Fix: sampler state slots were not properly set --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index bee55fe838..5baf48a70f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -977,7 +977,7 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) globalContext.Reflection.SamplerStates.Add(new EffectSamplerStateBinding(linkName, samplerState)); - cbufferSlot++; + samplerSlot++; } else if (pointerType.BaseType is ConstantBufferSymbol) { From 8ea3f246872166819b13546c2a7a38d75264bf0e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 16:53:10 +0900 Subject: [PATCH 0632/1182] StreamAnalyzer: include only resources that are explcitly referenced --- .../Spirv/Processing/StreamAnalyzer.cs | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index e2deb06c4a..a14d25ee93 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -37,7 +37,12 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - record struct AnalysisResult(SortedList Streams, List Blocks, List Resources); + class ResourceInfo + { + public bool Used { get; set; } + } + + record struct AnalysisResult(SortedList Streams, List Blocks, SortedList Resources); public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { @@ -55,7 +60,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte var analysisResult = Analyze(buffer, context); var streams = analysisResult.Streams; - AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, streams); + AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, analysisResult); // If written to, they are expected at the end of pixel shader foreach (var stream in streams) @@ -76,7 +81,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { - AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, streams); + AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, analysisResult); // Expected at the end of vertex shader foreach (var stream in streams) @@ -112,7 +117,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) HashSet blockTypes = []; Dictionary blockPointerTypes = []; List blockIds = []; - List resources = []; + SortedList resources = []; // Build name table SortedList nameTable = []; @@ -230,7 +235,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) : $"unnamed_{resource.ResultId}"; var type = context.ReverseTypes[resource.ResultType]; - resources.Add(resource.ResultId); + resources.Add(resource.ResultId, new ResourceInfo()); } } } @@ -389,9 +394,12 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var block in analysisResult.Blocks) pvariables[pvariableIndex++] = block; foreach (var resource in analysisResult.Resources) - pvariables[pvariableIndex++] = resource; + { + if (resource.Value.Used) + pvariables[pvariableIndex++] = resource.Key; + } - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables])); + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); } return newEntryPointFunction; @@ -400,8 +408,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con /// /// Figure out (recursively) which streams are being read from and written to. /// - private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, SortedList streams) + private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult) { + var streams = analysisResult.Streams; var methodStart = FindMethodStart(buffer, functionId); for (var index = methodStart; index < buffer.Count; index++) { @@ -413,11 +422,15 @@ private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, { if (streams.TryGetValue(load.Pointer, out var streamInfo) && !streamInfo.Stream.Write) streamInfo.Stream.Read = true; + if (analysisResult.Resources.TryGetValue(load.Pointer, out var resourceInfo)) + resourceInfo.Used = true; } else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { if (streams.TryGetValue(store.Pointer, out var streamInfo)) streamInfo.Stream.Write = true; + if (analysisResult.Resources.TryGetValue(store.Pointer, out var resourceInfo)) + resourceInfo.Used = true; } else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) { @@ -435,7 +448,7 @@ private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, if (callStack.Contains(functionId)) throw new InvalidOperationException($"Recursive call with method id {functionId}"); callStack.Add(functionId); - AnalyzeStreamReadWrites(buffer, callStack, call.Function, streams); + AnalyzeStreamReadWrites(buffer, callStack, call.Function, analysisResult); callStack.RemoveAt(callStack.Count - 1); } } From fc96e90ec8e594e4cdee7d8c12285c3c9c23f783 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 17:20:03 +0900 Subject: [PATCH 0633/1182] Links were broken --- assets/SDSL/RenderTests/TextureLinks.sdsl | 24 +++++++++++++++++++ .../SDSL/ShaderMixer.cs | 21 +++++++++------- .../FrameRenderer.D3D11.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 16 ++++++------- 4 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 assets/SDSL/RenderTests/TextureLinks.sdsl diff --git a/assets/SDSL/RenderTests/TextureLinks.sdsl b/assets/SDSL/RenderTests/TextureLinks.sdsl new file mode 100644 index 0000000000..5fbbe663d5 --- /dev/null +++ b/assets/SDSL/RenderTests/TextureLinks.sdsl @@ -0,0 +1,24 @@ +// PSMain(ExpectedResult=#1357ABCD, texture.Tex1=#13570000, texture.Tex2=#0000ABCD) + +namespace Stride.Shaders.Tests; + +shader TextureLinks +{ + stream float4 ColorTarget : SV_Target0; + stream float2 TexCoord : TEXCOORD; + + [Link("Tex1")] + stage Texture2D Texture1; + stage SamplerState Sampler1; + + rgroup Group1 + { + [Link("Tex2")] + stage Texture2D Texture2; + } + + void PSMain() + { + streams.ColorTarget = Texture1.Sample(Sampler1, streams.TexCoord) + Texture2.Sample(Sampler1, streams.TexCoord); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5baf48a70f..95933e525b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -824,13 +824,11 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } } + // TODO: do this once at root level and reuse for child mixin Dictionary linkInfos = new(); - string currentShaderName = string.Empty; var samplerStates = new Dictionary(); - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + foreach (var i in context) { - var i = buffer[index]; - // Fill linkInfos if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { @@ -851,10 +849,6 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) linkInfo.LogicalGroup = n.Value; } - else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) - { - currentShaderName = shader.ShaderName; - } else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && (OpDecorate)i is { Decoration: @@ -908,6 +902,17 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } } } + } + + string currentShaderName = string.Empty; + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + currentShaderName = shader.ShaderName; + } else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) { var type = context.ReverseTypes[variable.ResultType]; diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 7efd372f45..ffc188bf65 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -451,7 +451,7 @@ ref renderTextureStaging continue; var resourceName = param.Key.Substring(dotIndex + 1); - var resourceReflection = EffectReflection.ResourceBindings.Single(x => x.RawName == resourceName); + var resourceReflection = EffectReflection.ResourceBindings.Single(x => x.KeyInfo.KeyName.EndsWith(resourceName)); if (resourceType == "cbuffer") { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 66b8e09fb2..cd9c973bdf 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -54,49 +54,49 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler case "Filter": { var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateFilter(filter))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateFilter(filter))); break; } case "AddressU": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressU(addressMode))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressU(addressMode))); break; } case "AddressV": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressV(addressMode))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressV(addressMode))); break; } case "AddressW": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressW(addressMode))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressW(addressMode))); break; } case "MipLODBias": { var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; - builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMipLODBias(mipLODBias.ToString()))); + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMipLODBias(mipLODBias.ToString()))); break; } case "MaxAnisotropy": { var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; - builder.Insert(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateMaxAnisotropy(maxAnisotropy))); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateMaxAnisotropy(maxAnisotropy))); break; } case "MinLOD": { var minLOD = (float)((FloatLiteral)parameter.Value).Value; - builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMinLOD(minLOD.ToString()))); + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMinLOD(minLOD.ToString()))); break; } case "MaxLOD": { var maxLOD = (float)((FloatLiteral)parameter.Value).Value; - builder.Insert(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMaxLOD(maxLOD.ToString()))); + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMaxLOD(maxLOD.ToString()))); break; } case "BorderColor": From 80e8e45212a616fba17c2215215546f56eb8b017 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 17:32:41 +0900 Subject: [PATCH 0634/1182] Links: also support OpDecorate (before was only OpMemberDecorate) --- assets/SDSL/RenderTests/GenericsLinkType.sdsl | 26 ++++++++++++++----- .../Spirv/Building/Builder.Class.cs | 13 +++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/assets/SDSL/RenderTests/GenericsLinkType.sdsl b/assets/SDSL/RenderTests/GenericsLinkType.sdsl index dd221e63b8..5ca61c444b 100644 --- a/assets/SDSL/RenderTests/GenericsLinkType.sdsl +++ b/assets/SDSL/RenderTests/GenericsLinkType.sdsl @@ -1,10 +1,10 @@ -// PSMain(ExpectedResult=#08FFFFFF, cbuffer.Test=(Test123=05, Test456=03)) +// PSMain(ExpectedResult=#08182838, cbuffer.Test=(Test123=05, Test456=03), texture.MyTex1=#00102030) namespace Stride.Shaders.Tests; shader Compute { - float Compute() + float4 Compute() { return 0.0; } @@ -21,18 +21,32 @@ shader ComputeLink : Compute int Test2; } - override float Compute() + override float4 Compute() { - return ((float)Test1 + (float)Test2) / 255.0; + return base.Compute() + ((float)Test1 + (float)Test2) / 255.0; } } -shader GenericsLinkType : ComputeLink<"Test123", "Test456"> +shader ComputeTextureLink : Compute +{ + rgroup TestR + { + [Link(Link1)] + stage Texture2D Texture1; + } + + override float4 Compute() + { + return base.Compute() + Texture1.Load(int3(0, 0, 0)); + } +} + +shader GenericsLinkType : ComputeLink<"Test123", "Test456">, ComputeTextureLink<"MyTex1"> { stream float4 ColorTarget : SV_Target0; void PSMain() { - streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + streams.ColorTarget = Compute(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index bfc6795846..e980aa9a6b 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -501,13 +501,20 @@ private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, for (var index = 0; index < shader.Count; index++) { var i = shader[index]; - if (i.Op == Op.OpMemberDecorate - && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) + if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) { using var n = new LiteralValue(m.Span); if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) { - shader.Replace(index, new OpMemberDecorateString(linkDecorate.StructureType, linkDecorate.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + shader.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + } + } + else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m2 } } linkDecorate2) + { + using var n = new LiteralValue(m2.Span); + if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) + { + shader.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } } From 0c680e92282f7e2cae863a10b9c8c17d4866541c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 22:39:41 +0900 Subject: [PATCH 0635/1182] Avoid name collision and give more sensible debug names --- .../SDSL/ShaderMixer.CBuffers.cs | 4 +- .../SDSL/ShaderMixer.cs | 76 +++++++++++++++++-- .../Extensions/spirv.sdsl.grammar-ext.json | 12 ++- 3 files changed, 82 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 4dbd8838c2..bf3bb072df 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -39,8 +39,8 @@ string GetCBufferLogicalGroup(string cbufferName) // OpSDSLEffect is emitted for any non-root composition var compositionNodes = buffer - .Where(x => x.Op == Op.OpSDSLEffect) - .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLEffect)x).EffectName)) + .Where(x => x.Op == Op.OpSDSLComposition) + .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLComposition)x).CompositionPath)) .ToList(); var shaders = buffer diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 95933e525b..cb4fb57189 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -55,6 +55,10 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect MergeCBuffers(globalContext, context, temp); ComputeCBufferOffsets(globalContext, context, temp); + // Try to give variables more sensible names + // Note: since we mutate OpName and globalContext.Names, try to do that as late as possible because some code earlier use names to match variables/types + RenameVariables(globalContext, context, temp); + // Process reflection ProcessReflection(globalContext, context, temp, rootMixin); @@ -110,7 +114,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, { // We emit OPSDSLEffect for any non-root composition if (currentCompositionPath != null) - buffer.Add(new OpSDSLEffect(currentCompositionPath)); + buffer.Add(new OpSDSLComposition(currentCompositionPath)); var mixinNode = new MixinNode(stage, currentCompositionPath); var contextStart = context.GetBuffer().Count; @@ -154,7 +158,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, ProcessMemberAccessAndForeach(globalContext, context, buffer, mixinNode); if (currentCompositionPath != null) - buffer.Add(new OpSDSLEffectEnd()); + buffer.Add(new OpSDSLCompositionEnd()); return mixinNode; } @@ -268,7 +272,6 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS && context.ReverseTypes.TryGetValue(remappedFunctionTypeId, out var functionType2)) functionType = (FunctionType)functionType2; - include = ProcessStageMemberOrType(function.ResultId, functionType, isStage); } if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) @@ -802,6 +805,65 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } } + private void RenameVariables(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + { + // Collect variables by names + string? compositionPath = null; + var shaderNameWithComposition = string.Empty; + Dictionary prefixes = new(); + foreach (var i in temp) + { + if (i.Op == Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) + { + compositionPath = composition.CompositionPath; + } + else if (i.Op == Op.OpSDSLCompositionEnd) + { + compositionPath = null; + } + else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + shaderNameWithComposition = compositionPath != null + ? $"{compositionPath}.{shader.ShaderName}" + : shader.ShaderName; + } + else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { Storageclass: Specification.StorageClass.UniformConstant } variable) + { + // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore + var type = globalContext.Types[variable.ResultType]; + if (type is not ConstantBufferSymbol) + prefixes[variable.ResultId] = shaderNameWithComposition; + } + else if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } structType) + { + prefixes[structType.ResultId] = shaderNameWithComposition; + } + else if (i.Op == Op.OpFunction && (OpFunction)i is { } function) + { + prefixes[function.ResultId] = shaderNameWithComposition; + } + } + + // Now, reprocess context with those names + char[] invalidChars = { '<', '>', '[', ']', '.', ',', '-' }; + foreach (var i in context) + { + if (i.Op == Op.OpName && (OpName)i is { } name) + { + if (prefixes.TryGetValue(name.Target, out var prefix)) + { + var updatedName = $"{prefix}.{name.Name}"; + name.Name = updatedName; + + // Now, make sure it's all valid HLSL/GLSL characters (this will replace multiple invalid characters with a single underscore) + // Otherwise, EffectReflection RawName won't match + updatedName = string.Join("_", updatedName.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)); + globalContext.Names[name.Target] = updatedName; + } + } + } + } + private static void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode) { // First, figure out latest used bindings (assume they are filled in order) @@ -859,8 +921,8 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } } decorate) { - ref var samplerState = ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var added); - if (added) + ref var samplerState = ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var exists); + if (!exists) samplerState = Graphics.SamplerStateDescription.Default; switch (decorate.Decoration.Value) { @@ -1090,8 +1152,8 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) else if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLShaderEnd - || i.Op == Op.OpSDSLEffect - || i.Op == Op.OpSDSLEffectEnd + || i.Op == Op.OpSDSLComposition + || i.Op == Op.OpSDSLCompositionEnd || i.Op == Op.OpSDSLMixinInherit || i.Op == Op.OpConstantStringSDSL || i.Op == Op.OpTypeGenericSDSL diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index a3a3755f8c..be018c1fa8 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -25,7 +25,17 @@ ] }, { - "opname": "OpSDSLEffectEnd", + "opname": "OpSDSLComposition", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "compositionPath" + } + ] + }, + { + "opname": "OpSDSLCompositionEnd", "class": "Miscellaneous" }, { From 797c2e3e9720362ea0ebd024430cbdae3fe6f170 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 22:39:55 +0900 Subject: [PATCH 0636/1182] Reflection: output proper texture type --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index cb4fb57189..11767db139 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -996,13 +996,20 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon LogicalGroup = linkInfo.LogicalGroup, }; - if (pointerType.BaseType is TextureType) + if (pointerType.BaseType is TextureType t) { var slot = globalContext.Reflection.ResourceBindings.Count; globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with { Class = EffectParameterClass.ShaderResourceView, - Type = EffectParameterType.Texture, + Type = (t, t.Multisampled) switch + { + (Texture1DType, false) => EffectParameterType.Texture1D, + (Texture2DType, false) => EffectParameterType.Texture2D, + (Texture2DType, true) => EffectParameterType.Texture2DMultisampled, + (Texture3DType, false) => EffectParameterType.Texture3D, + (TextureCubeType, false) => EffectParameterType.TextureCube, + }, SlotStart = srvSlot, SlotCount = 1, }); From 37e12f54879b113339ceadc318bc25533b096194 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 23:28:51 +0900 Subject: [PATCH 0637/1182] Streams: merge variables with same semantic --- .../Spirv/Processing/StreamAnalyzer.cs | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index a14d25ee93..c649491582 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -58,6 +58,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); var analysisResult = Analyze(buffer, context); + MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, analysisResult); @@ -98,6 +99,38 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } + private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) + { + Dictionary remapIds = new(); + foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Stream.Semantic != null).GroupBy(x => x.Value.Stream.Semantic)) + { + // Make sure they all have the same type + var firstStream = streamWithSameSemantic.First(); + foreach (var stream in streamWithSameSemantic.Skip(1)) + { + if (stream.Value.Stream.Type != firstStream.Value.Stream.Type) + throw new InvalidOperationException($"Two variables with same semantic {stream.Value.Stream.Semantic} have different types {stream.Value.Stream.Type} and {firstStream.Value.Stream.Type}"); + + // Remap variable + remapIds.Add(stream.Key, firstStream.Key); + } + } + + // Remove duplicate streams + foreach (var i in buffer) + { + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { } variable && remapIds.ContainsKey(variable.ResultId)) + { + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + + foreach (var remapId in remapIds) + analysisResult.Streams.Remove(remapId.Key); + + SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); + } + private static void PropagateStreamsFromPreviousStage(SortedList streams) { foreach (var stream in streams) From e47cfa1a99c096f2c59e994c93d2fce1c7c8d5a2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 22 Dec 2025 23:29:35 +0900 Subject: [PATCH 0638/1182] Streams: fix stream being duplicated due to accesschain (which was causing some other side effect bugs) --- .../Spirv/Processing/StreamAnalyzer.cs | 128 +++++++++--------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index c649491582..0e54eef738 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -42,7 +42,7 @@ class ResourceInfo public bool Used { get; set; } } - record struct AnalysisResult(SortedList Streams, List Blocks, SortedList Resources); + record struct AnalysisResult(SortedList Streams, List Blocks, SortedList Resources); public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { @@ -66,9 +66,9 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // If written to, they are expected at the end of pixel shader foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") - && stream.Value.Stream.Write) - stream.Value.Stream.Output = true; + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") + && stream.Value.Write) + stream.Value.Output = true; } var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult); @@ -76,8 +76,8 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) { - if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) - stream.Value.Stream.Read = false; + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) + stream.Value.Read = false; } PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) @@ -88,9 +88,9 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte foreach (var stream in streams) { // If written to, they are expected at the end of pixel shader - if (stream.Value.Stream.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - && stream.Value.Stream.Write) - stream.Value.Stream.Output = true; + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + && stream.Value.Write) + stream.Value.Output = true; } GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); @@ -102,14 +102,14 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) { Dictionary remapIds = new(); - foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Stream.Semantic != null).GroupBy(x => x.Value.Stream.Semantic)) + foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Semantic != null).GroupBy(x => x.Value.Semantic)) { // Make sure they all have the same type var firstStream = streamWithSameSemantic.First(); foreach (var stream in streamWithSameSemantic.Skip(1)) { - if (stream.Value.Stream.Type != firstStream.Value.Stream.Type) - throw new InvalidOperationException($"Two variables with same semantic {stream.Value.Stream.Semantic} have different types {stream.Value.Stream.Type} and {firstStream.Value.Stream.Type}"); + if (stream.Value.Type != firstStream.Value.Type) + throw new InvalidOperationException($"Two variables with same semantic {stream.Value.Semantic} have different types {stream.Value.Type} and {firstStream.Value.Type}"); // Remap variable remapIds.Add(stream.Key, firstStream.Key); @@ -131,21 +131,21 @@ private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); } - private static void PropagateStreamsFromPreviousStage(SortedList streams) + private static void PropagateStreamsFromPreviousStage(SortedList streams) { foreach (var stream in streams) { - stream.Value.Stream.OutputLayoutLocation = stream.Value.Stream.InputLayoutLocation; - stream.Value.Stream.InputLayoutLocation = null; - stream.Value.Stream.Output = stream.Value.Stream.Read; - stream.Value.Stream.Read = false; - stream.Value.Stream.Write = false; + stream.Value.OutputLayoutLocation = stream.Value.InputLayoutLocation; + stream.Value.InputLayoutLocation = null; + stream.Value.Output = stream.Value.Input; + stream.Value.Read = false; + stream.Value.Write = false; } } private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { - var streams = new SortedList(); + var streams = new SortedList(); HashSet blockTypes = []; Dictionary blockPointerTypes = []; @@ -247,12 +247,12 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) var type = context.ReverseTypes[variable.ResultType]; semanticTable.TryGetValue(variable.ResultId, out var semantic); - var stream = (new StreamInfo(semantic, name, type, variable.ResultId) + var stream = new StreamInfo(semantic, name, type, variable.ResultId) { // Does it have an initializer? if yes, mark it as a value written in this stage Write = variable.MethodInitializer != null, VariableMethodInitializerId = variable.MethodInitializer, - }, true); + }; streams.Add(variable.ResultId, stream); } @@ -295,13 +295,9 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var stream in streams) { - // Only direct access to global variables (not temporary variables created within function) - if (!stream.Value.IsDirect) - continue; - - if (stream.Value.Stream.Output) + if (stream.Value.Output) { - if (stream.Value.Stream.OutputLayoutLocation is { } outputLayoutLocation) + if (stream.Value.OutputLayoutLocation is { } outputLayoutLocation) { outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); } @@ -310,66 +306,62 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var stream in streams) { - // Only direct access to global variables (not temporary variables created within function) - if (!stream.Value.IsDirect) - continue; - - var baseType = ((PointerType)stream.Value.Stream.Type).BaseType; - if (stream.Value.Stream.Private) - privateStreams.Add(stream.Value.Stream); + var baseType = ((PointerType)stream.Value.Type).BaseType; + if (stream.Value.Private) + privateStreams.Add(stream.Value); - if (stream.Value.Stream.Input) + if (stream.Value.Input) { context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); - context.AddName(variable, $"in_{stage}_{stream.Value.Stream.Name}"); + context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - switch (stream.Value.Stream.Semantic?.ToUpperInvariant()) + switch (stream.Value.Semantic?.ToUpperInvariant()) { case "SV_ISFRONTFACE": context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FrontFacing))); context.Add(new OpDecorate(variable, Decoration.Flat)); break; default: - if (stream.Value.Stream.InputLayoutLocation == null) - stream.Value.Stream.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.InputLayoutLocation.Value))); - if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + if (stream.Value.InputLayoutLocation == null) + stream.Value.InputLayoutLocation = inputLayoutLocationCount++; + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.InputLayoutLocation.Value))); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); break; } - inputStreams.Add((stream.Value.Stream, variable.ResultId)); + inputStreams.Add((stream.Value, variable.ResultId)); } - if (stream.Value.Stream.Output) + if (stream.Value.Output) { context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Output, context.Types[baseType]), out var pointerType); context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); - context.AddName(variable, $"out_{stage}_{stream.Value.Stream.Name}"); + context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - switch (stream.Value.Stream.Semantic?.ToUpperInvariant()) + switch (stream.Value.Semantic?.ToUpperInvariant()) { case "SV_POSITION": context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); break; default: // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic - if (stream.Value.Stream.OutputLayoutLocation == null) + if (stream.Value.OutputLayoutLocation == null) { - if (stream.Value.Stream.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) - stream.Value.Stream.OutputLayoutLocation = outputLayoutLocationCount++; + if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) + stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; else - throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Stream.Name}]"); + throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); } - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.Stream.OutputLayoutLocation.Value))); - if (stream.Value.Stream.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Stream.Semantic))); + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.OutputLayoutLocation.Value))); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); break; } - outputStreams.Add((stream.Value.Stream, variable.ResultId)); + outputStreams.Add((stream.Value, variable.ResultId)); } } @@ -386,12 +378,12 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con foreach (var stream in streams) { // Note: we check Private to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) - if (stream.Value.Stream.Private - && stream.Value.Stream.VariableMethodInitializerId is int methodInitializerId) + if (stream.Value.Private + && stream.Value.VariableMethodInitializerId is int methodInitializerId) { - var variableValueType = ((PointerType)stream.Value.Stream.Type).BaseType; + var variableValueType = ((PointerType)stream.Value.Type).BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); - buffer.Add(new OpStore(stream.Value.Stream.VariableId, methodInitializerCall.ResultId, null)); + buffer.Add(new OpStore(stream.Value.VariableId, methodInitializerCall.ResultId, null)); } } @@ -444,6 +436,14 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult) { var streams = analysisResult.Streams; + var streamsAccessChains = new Dictionary(); + + bool TryGetStream(int streamId, out StreamInfo streamInfo) + { + return streams.TryGetValue(streamId, out streamInfo) + || streamsAccessChains.TryGetValue(streamId, out streamInfo); + } + var methodStart = FindMethodStart(buffer, functionId); for (var index = methodStart; index < buffer.Count; index++) { @@ -453,26 +453,26 @@ private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, if (instruction.Op is Op.OpLoad && (OpLoad)instruction is { } load) { - if (streams.TryGetValue(load.Pointer, out var streamInfo) && !streamInfo.Stream.Write) - streamInfo.Stream.Read = true; + if (TryGetStream(load.Pointer, out var streamInfo) && !streamInfo.Write) + streamInfo.Read = true; if (analysisResult.Resources.TryGetValue(load.Pointer, out var resourceInfo)) resourceInfo.Used = true; } else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { - if (streams.TryGetValue(store.Pointer, out var streamInfo)) - streamInfo.Stream.Write = true; + if (TryGetStream(store.Pointer, out var streamInfo)) + streamInfo.Write = true; if (analysisResult.Resources.TryGetValue(store.Pointer, out var resourceInfo)) resourceInfo.Used = true; } else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) { - if (streams.TryGetValue(accessChain.BaseId, out var streamInfo)) + if (TryGetStream(accessChain.BaseId, out var streamInfo)) { // Map the pointer access as access to the underlying stream (if any) // i.e., streams.A.B will share same streamInfo as streams.A // TODO: what happens in case of partial write? - streams.TryAdd(accessChain.ResultId, (streamInfo.Stream, false)); + streamsAccessChains.TryAdd(accessChain.ResultId, streamInfo); } } else if (instruction.Op == Op.OpFunctionCall && (OpFunctionCall)instruction is { } call) From 7a83ed0635652612b7bd19ed811621e0af75c783 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 23 Dec 2025 00:03:55 +0900 Subject: [PATCH 0639/1182] Streams: better handle builtin (esp. for SV_Position) --- .../Spirv/Processing/StreamAnalyzer.cs | 66 +++++++++++-------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 0e54eef738..2dc60ab5ee 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -304,6 +304,25 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con } } + bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) + { + switch (stream.Semantic?.ToUpperInvariant()) + { + case "SV_POSITION" when executionModel is ExecutionModel.Geometry or ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation or ExecutionModel.Vertex: + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); + return true; + case "SV_POSITION" when executionModel is ExecutionModel.Fragment: + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FragCoord))); + return true; + case "SV_ISFRONTFACE": + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FrontFacing))); + context.Add(new OpDecorate(variable, Decoration.Flat)); + return true; + default: + return false; + } + } + foreach (var stream in streams) { var baseType = ((PointerType)stream.Value.Type).BaseType; @@ -316,19 +335,13 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - switch (stream.Value.Semantic?.ToUpperInvariant()) + if (!ProcessBuiltinsDecoration(variable.ResultId, stream.Value)) { - case "SV_ISFRONTFACE": - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FrontFacing))); - context.Add(new OpDecorate(variable, Decoration.Flat)); - break; - default: - if (stream.Value.InputLayoutLocation == null) - stream.Value.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.InputLayoutLocation.Value))); - if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); - break; + if (stream.Value.InputLayoutLocation == null) + stream.Value.InputLayoutLocation = inputLayoutLocationCount++; + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.InputLayoutLocation.Value))); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); } inputStreams.Add((stream.Value, variable.ResultId)); @@ -340,25 +353,20 @@ private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext con context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - switch (stream.Value.Semantic?.ToUpperInvariant()) + if (!ProcessBuiltinsDecoration(variable.ResultId, stream.Value)) { - case "SV_POSITION": - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); - break; - default: - // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic - if (stream.Value.OutputLayoutLocation == null) - { - if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) - stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; - else - throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); - } + // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic + if (stream.Value.OutputLayoutLocation == null) + { + if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) + stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; + else + throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); + } - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.OutputLayoutLocation.Value))); - if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); - break; + context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.OutputLayoutLocation.Value))); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); } outputStreams.Add((stream.Value, variable.ResultId)); From bffad68931bdef179b841b20da2ef8635f409160 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 23 Dec 2025 21:33:15 +0900 Subject: [PATCH 0640/1182] Streams: if no output in PSMain, remove it altogether (i.e. for shadow casters) --- .../Spirv/Processing/StreamAnalyzer.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index 2dc60ab5ee..f4a9ad71e6 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -70,8 +70,14 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte && stream.Value.Write) stream.Value.Output = true; } - - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult); + + // Check if there is any output + // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) + if (streams.Any(x => x.Value.Output)) + { + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult); + buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); + } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) @@ -84,10 +90,9 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte { AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, analysisResult); - // Expected at the end of vertex shader + // If written to, they are expected at the end of vertex shader foreach (var stream in streams) { - // If written to, they are expected at the end of pixel shader if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) && stream.Value.Write) stream.Value.Output = true; @@ -95,8 +100,6 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); } - - buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) From ce7f96436bc478a715b3cc11784dbaf37f13c45c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 23 Dec 2025 22:33:32 +0900 Subject: [PATCH 0641/1182] Generics: better handle cases such as PerView.Lighting which need to become a string --- .../Parsing/SDSL/AST/Literals.cs | 19 +++++++++++++++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 ++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 8f41fe2815..fd6f5f54b0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -23,14 +23,19 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) { - var (builder, context) = compiler; var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); // Note: we rely on undefined type (0); we assume those string literals will be used in only very specific cases where we expect them (i.e. generic instantiation parameters) and will be removed return new SpirvValue(i.IdResult.Value, 0); } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + return CompileConstantValue(table, context); + } + public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) { // Since we use type 0, CompileAsValue won't work @@ -84,6 +89,11 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); + public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + { + return context.CompileConstantLiteral(this); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); @@ -101,6 +111,11 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.From("bool"); + public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + { + return context.CompileConstantLiteral(this); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 8cbb15f38b..a3055c35e3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -352,16 +352,20 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { if (table.TryResolveSymbol(identifier.Name, out var symbol)) { - generics[i] = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, symbol, false).Id; + generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; } else { generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).IdResult.Value; } } + else if (mixin.Generics.Values[i] is AccessorChainExpression accessChain) + { + generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, accessChain.ToString())).IdResult.Value; + } else { - generics[i] = mixin.Generics.Values[i].CompileAsValue(table, compiler).Id; + generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; } } } From 4330962b44dfbf298f15d1703b14224ed439a383 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 23 Dec 2025 22:34:12 +0900 Subject: [PATCH 0642/1182] Intrinsics: added diastance() and some other minor fixes --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 27 ++++++++++++++++--- .../PrimaryExpressionParsers.cs | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index c45b4f7a5a..70fedb66ad 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -484,6 +484,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var resultType = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + x = builder.Convert(context, x, resultType); + y = builder.Convert(context, y, resultType); + var instruction = resultType.GetElementType() switch { ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), @@ -507,6 +510,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var resultType = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + x = builder.Convert(context, x, resultType); + y = builder.Convert(context, y, resultType); + var instruction = resultType.GetElementType() switch { ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), @@ -833,7 +839,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var x = Parameters.Values[0].CompileAsValue(table, compiler); if (context.GLSLSet == null) context.ImportGLSL(); - var resultType = Parameters.Values[0].ValueType.GetElementType(); + + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("float")); + x = builder.Convert(context, x, parameterType); + + var resultType = ScalarType.From("float"); var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } @@ -843,10 +853,19 @@ public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var (p0, p1) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.From("float"), xType, yType); + + x = builder.Convert(context, x, resultType); + y = builder.Convert(context, y, resultType); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLDistance(p0.TypeId, context.Bound++, context.GLSLSet ?? -1, p0.Id, p1.Id)); + var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -871,7 +890,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); var xType = Parameters.Values[0].ValueType; - var yType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; if (xType != yType) throw new NotImplementedException("dot needs to be applied on same types"); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 596a76ffa4..72b2f8f23d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -86,7 +86,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), - ("distance", _) => throw new NotImplementedException(), + ("distance", _) => new DistanceCall(parameters, scanner[position..scanner.Position]), ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), ("dst", _) => throw new NotImplementedException(), ("errorf", _) => throw new NotImplementedException(), From aaa824261c871b525d5ec0d815ea90dd8dc42049 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Dec 2025 00:51:02 +0900 Subject: [PATCH 0643/1182] Rewrote constant system to be able to support OpSpecConstantOp --- .../SDSL/RenderTests/GenericsArraySize.sdsl | 6 +- .../SDSL/ShaderMixer.cs | 2 +- .../Parsing/OpDataEnumerator.cs | 15 +++ .../Parsing/SDSL/AST/Expression.cs | 9 +- .../Parsing/SDSL/AST/Literals.cs | 37 +----- .../Spirv/Building/Builder.Class.cs | 124 +++++++++--------- .../Spirv/Building/CompilerUnit.cs | 7 + .../Spirv/Building/ExpressionExtensions.cs | 86 ++++++++++++ 8 files changed, 185 insertions(+), 101 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs diff --git a/assets/SDSL/RenderTests/GenericsArraySize.sdsl b/assets/SDSL/RenderTests/GenericsArraySize.sdsl index 88be41a295..615f44430c 100644 --- a/assets/SDSL/RenderTests/GenericsArraySize.sdsl +++ b/assets/SDSL/RenderTests/GenericsArraySize.sdsl @@ -2,13 +2,13 @@ namespace Stride.Shaders.Tests; -shader GenericsArrayBase +shader GenericsArrayBase { stream float4 ColorTarget : SV_Target0; cbuffer Test { - int Test2[TArraySize]; + int Test2[TArraySizeHalf * 2]; } void PSMain() @@ -19,5 +19,5 @@ shader GenericsArrayBase effect GenericsArraySize { - mixin GenericsArrayBase<4>; + mixin GenericsArrayBase<2>; } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 11767db139..cefd22daef 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -690,7 +690,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions) || (mixinNode.Stage != null && mixinNode.Stage.CompositionArrays.TryGetValue(accessChain.BaseId, out compositions))) { - var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer(), temp); + var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer()); compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); SetOpNop(i.Data.Memory.Span); diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index edb55260fc..b3237c81a2 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -22,6 +22,21 @@ public OpDataEnumerator(Span instruction) { this.instruction = instruction; logicalOperands = InstructionInfo.GetInfo(instruction); + // If OpSpecConstantOp, there is an inner OpCode which will define additional inner operands + if (OpCode == Op.OpSpecConstantOp) + { + var combinedLogicalOperands = new List(); + foreach (var o in logicalOperands) + combinedLogicalOperands.Add(o); + var innerOpCode = (Op)instruction[3]; + var innerLogicalOperands = InstructionInfo.GetInfo(innerOpCode); + // Start from third operand (skip ResultType/ResultId) + for (int i = 2; i < innerLogicalOperands.Count; ++i) + { + combinedLogicalOperands.Add(innerLogicalOperands[i]); + } + logicalOperands = new LogicalOperandArray(logicalOperands.ClassName, combinedLogicalOperands); + } oid = -1; pid = -1; wid = 0; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index bf8820c3d4..4789c84c51 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -20,18 +20,13 @@ public SpirvValue Compile(SymbolTable table, CompilerUnit compiler) { var result = CompileImpl(table, compiler); // In case type is not computed yet, make sure it is using SpirvValue.TypeId - Type ??= compiler.Context.ReverseTypes[result.TypeId]; + if (result.TypeId != 0) + Type ??= compiler.Context.ReverseTypes[result.TypeId]; return result; } public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); - // Only used for constant expression which should stay in the context buffer (not compiled inside a OpFunction) - public virtual SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) - { - throw new NotImplementedException(); - } - public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index fd6f5f54b0..ffb1bc8e25 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -23,19 +23,15 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { + var (builder, context) = compiler; + var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); // Note: we rely on undefined type (0); we assume those string literals will be used in only very specific cases where we expect them (i.e. generic instantiation parameters) and will be removed return new SpirvValue(i.IdResult.Value, 0); } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - return CompileConstantValue(table, context); - } - public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) { // Since we use type 0, CompileAsValue won't work @@ -73,11 +69,6 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) - { - return context.CompileConstantLiteral(this); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); @@ -89,11 +80,6 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) - { - return context.CompileConstantLiteral(this); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); @@ -111,11 +97,6 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.From("bool"); - public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) - { - return context.CompileConstantLiteral(this); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); @@ -256,20 +237,14 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override SpirvValue CompileConstantValue(SymbolTable table, SpirvContext context) - { - int position = context.GetBuffer().Count; - return CompileSymbol(table, context.GetBuffer(), ref position, context, true); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - return CompileSymbol(table, builder.GetBuffer(), ref builder.Position, context, false); + return CompileSymbol(table, builder.GetBuffer(), ref builder.Position, context, builder.CurrentFunction == null); } - private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref int position, SpirvContext context, bool constantOnly) + private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref int position, SpirvContext context, bool constantOnly) { if (!table.TryResolveSymbol(Name, out var symbol)) { @@ -304,7 +279,7 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer buffer, ref i return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } - public static SpirvValue EmitSymbol(NewSpirvBuffer buffer, ref int position, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) + public static SpirvValue EmitSymbol(NewSpirvBuffer? buffer, ref int position, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index e980aa9a6b..1978009036 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -136,107 +136,113 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade return inheritanceList[index]; } - public static bool TryGetInstructionById(int constantId, out OpDataIndex instruction, params ReadOnlySpan buffers) + public static bool TryGetInstructionById(int constantId, out OpDataIndex instruction, NewSpirvBuffer buffer) { - foreach (var buffer in buffers) - { - if (buffer.TryGetInstructionById(constantId, out instruction)) - return true; - } + if (buffer.TryGetInstructionById(constantId, out instruction)) + return true; instruction = default; return false; } - public static object GetConstantValue(int constantId, params ReadOnlySpan buffers) + public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) { - foreach (var buffer in buffers) + if (buffer.TryGetInstructionById(constantId, out var constant)) { - if (buffer.TryGetInstructionById(constantId, out var constant)) - { - return GetConstantValue(constant.Data, buffers); - } + return GetConstantValue(constant, buffer); } throw new Exception("Cannot find constant instruction for id " + constantId); } - public static bool TryGetConstantValue(int constantId, out object value, params ReadOnlySpan buffers) + public static bool TryGetConstantValue(int constantId, out object value, NewSpirvBuffer buffer) { - foreach (var buffer in buffers) + if (buffer.TryGetInstructionById(constantId, out var constant)) { - if (buffer.TryGetInstructionById(constantId, out var constant)) - { - return TryGetConstantValue(constant.Data, out value, buffers); - } + return TryGetConstantValue(constant, out value, buffer); } value = default; return false; } - public static object GetConstantValue(OpData data, params ReadOnlySpan buffers) + public static object GetConstantValue(OpDataIndex i, NewSpirvBuffer buffer) { - if (!TryGetConstantValue(data, out var value, buffers)) - throw new InvalidOperationException($"Can't process constant {data.IdResult}"); + if (!TryGetConstantValue(i, out var value, buffer)) + throw new InvalidOperationException($"Can't process constant {i.Data.IdResult}"); return value; } // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. - public static bool TryGetConstantValue(OpData data, out object value, params ReadOnlySpan buffers) + public static bool TryGetConstantValue(OpDataIndex i, out object value, NewSpirvBuffer buffer) { + value = default; + // Check for unresolved values - if (data.Op == Op.OpSDSLGenericParameter) + if (i.Op == Op.OpSDSLGenericParameter) { - value = default; return false; } - if (data.Op == Op.OpConstantStringSDSL) + if (i.Op == Op.OpConstantStringSDSL) { - var operand2 = data.Get("literalString"); + var operand2 = i.Data.Get("literalString"); value = operand2.ToLiteral(); return true; } - int typeId = data.Op switch + if (i.Op == Op.OpSpecConstantOp) { - Op.OpConstant or Op.OpSpecConstant => data.Memory.Span[1], + var op = (Op)i.Data.Memory.Span[3]; + switch (op) + { + case Op.OpIMul: + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, buffer)) + return false; + if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, buffer)) + return false; + value = (int)left * (int)right; + return true; + default: + throw new NotImplementedException(); + } + } + + int typeId = i.Op switch + { + Op.OpConstant or Op.OpSpecConstant => i.Data.Memory.Span[1], }; - var operand = data.Get("value"); - foreach (var buffer in buffers) + var operand = i.Data.Get("value"); + if (buffer.TryGetInstructionById(typeId, out var typeInst)) { - if (buffer.TryGetInstructionById(typeId, out var typeInst)) + if (typeInst.Op == Op.OpTypeInt) { - if (typeInst.Op == Op.OpTypeInt) + var type = (OpTypeInt)typeInst; + value = type switch { - var type = (OpTypeInt)typeInst; - value = type switch - { - { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), - { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), - { Width: 64, Signedness: 0 } => operand.ToLiteral(), - { Width: 64, Signedness: 1 } => operand.ToLiteral(), - _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), - }; - return true; - } - else if (typeInst.Op == Op.OpTypeFloat) + { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), + { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), + { Width: 64, Signedness: 0 } => operand.ToLiteral(), + { Width: 64, Signedness: 1 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), + }; + return true; + } + else if (typeInst.Op == Op.OpTypeFloat) + { + var type = new OpTypeFloat(typeInst); + value = type switch { - var type = new OpTypeFloat(typeInst); - value = type switch - { - { Width: 16 } => operand.ToLiteral(), - { Width: 32 } => operand.ToLiteral(), - { Width: 64 } => operand.ToLiteral(), - _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), - }; - return true; - } - else - throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); + { Width: 16 } => operand.ToLiteral(), + { Width: 32 } => operand.ToLiteral(), + { Width: 64 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), + }; + return true; } + else + throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); } throw new Exception("Cannot find type instruction for id " + typeId); } @@ -621,8 +627,8 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader { var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); - if (!isFromCache) - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + //if (!isFromCache) + // Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); if (genericResolver.NeedsResolve()) { @@ -632,7 +638,7 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader shader = CopyShader(shader); InstantiateGenericShader(shader, className, genericResolver, shaderLoader, macros); - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shader; diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 8097ddfaeb..5f974f4251 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -24,6 +24,13 @@ public CompilerUnit() Arguments = []; } + public CompilerUnit(SpirvContext context, SpirvBuilder builder) + { + Context = context; + Builder = builder; + Arguments = []; + } + public void Deconstruct(out SpirvBuilder builder, out SpirvContext context) { builder = Builder; diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs new file mode 100644 index 0000000000..f87633292f --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -0,0 +1,86 @@ +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Building; + +public static class ExpressionExtensions +{ + public static HashSet SpecConstantSupportedOps = new() + { + Op.OpSConvert, + Op.OpUConvert, + Op.OpFConvert, + Op.OpSNegate, + Op.OpNot, + Op.OpIAdd, + Op.OpISub, + Op.OpIMul, + Op.OpUDiv, + Op.OpSDiv, + Op.OpUMod, + Op.OpSRem, + Op.OpSMod, + Op.OpShiftRightLogical, + Op.OpShiftRightArithmetic, + Op.OpShiftLeftLogical, + Op.OpBitwiseOr, + Op.OpBitwiseXor, + Op.OpBitwiseAnd, + Op.OpVectorShuffle, + Op.OpCompositeExtract, + Op.OpCompositeInsert, + Op.OpLogicalOr, + Op.OpLogicalAnd, + Op.OpLogicalNot, + Op.OpLogicalEqual, + Op.OpLogicalNotEqual, + Op.OpSelect, + Op.OpIEqual, + Op.OpINotEqual, + Op.OpULessThan, + Op.OpSLessThan, + Op.OpUGreaterThan, + Op.OpSGreaterThan, + Op.OpULessThanEqual, + Op.OpSLessThanEqual, + Op.OpUGreaterThanEqual, + Op.OpSGreaterThanEqual, + }; + + public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context) + { + var compiler = new CompilerUnit(context, new()); + var result = expression.Compile(table, compiler); + + var buffer = compiler.Builder.GetBuffer(); + + // Process each instruction and check if it can be converted to constant version + for (int index = 0; index < buffer.Count; ++index) + { + var i = buffer[index]; + + // Check if opcode is supported + if (!SpecConstantSupportedOps.Contains(i.Op)) + throw new InvalidOperationException($"OpCode {i.Op} not supported when compiling constant {expression}"); + + var resultType = i.Data.Memory.Span[1]; + var resultId = i.Data.Memory.Span[2]; + + Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; + instruction[0] |= instruction.Length << 16; + + // TODO: Check no IdRef to things outside context is done + + context.GetBuffer().Add(new OpData(instruction)); + + result = new(resultId, resultType); + } + + buffer.Dispose(); + + return result; + } +} From f022898318668933b50652e1f5176b3a187eb8f0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Dec 2025 00:57:30 +0900 Subject: [PATCH 0644/1182] ShaderMixer: Make sure generic class instantiation doesn't add invalid character to class name --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.Class.cs | 2 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index cefd22daef..a79da73eb0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -857,7 +857,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont // Now, make sure it's all valid HLSL/GLSL characters (this will replace multiple invalid characters with a single underscore) // Otherwise, EffectReflection RawName won't match - updatedName = string.Join("_", updatedName.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)); + updatedName = SpirvBuilder.RemoveInvalidCharactersFromSymbol(updatedName); globalContext.Names[name.Target] = updatedName; } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 1978009036..38cfda41b4 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -481,7 +481,7 @@ private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, stri { // Add something to shaderName (which is used as key in ShaderLoader cache) var originalShaderName = shaderName; - shaderName += $"_{string.Join("_", instantiatedGenericsMacros.Select(x => x.Definition))}"; + shaderName += $"_{string.Join("_", instantiatedGenericsMacros.Select(x => RemoveInvalidCharactersFromSymbol(x.Definition)))}"; // Note: we apply the preprocessor only the shader body to transform generics parameter into their actual value without touching the generic definition code = code.Substring(0, unresolvableShader.ShaderCodeNameEnd) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 27b7dc2782..41a72951fa 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -134,4 +134,10 @@ public void Dispose() builder.position = position; } } + + static char[] invalidChars = { '<', '>', '[', ']', '.', ',', '-' }; + public static string RemoveInvalidCharactersFromSymbol(string name) + { + return string.Join("_", name.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)); + } } From ff0d94472bf807dd24411c965ceafeb0286eddaf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Dec 2025 00:39:56 +0900 Subject: [PATCH 0645/1182] TypeDuplicateRemover: simplify code since no need to handle OpTypeStruct --- .../SDSL/ShaderMixer.cs | 3 - .../Spirv/Processing/TypeDuplicatesRemover.cs | 64 ++----------------- 2 files changed, 4 insertions(+), 63 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a79da73eb0..e40d2e53bf 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -416,9 +416,6 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (addToContext) { var i2Index = context.GetBuffer().Add(i2); - - // Add latest OpName/OpMemberName so that OpTypeStruct can be properly deduplicated - typeDuplicateInserter.AddNameInstruction(i2Index); } } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 358200adc8..950bad1653 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -51,7 +51,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; } - class OperationComparer(Func> RequestNameInstructions, bool UseIndices) : IComparer + class OperationComparer(bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -91,7 +91,6 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeFunctionSDSL || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray - //|| x.Op == Op.OpTypeStruct || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler || x.Op == Op.OpTypeGenericSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) @@ -99,14 +98,6 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) return comparison; - - // For struct, we have some additional checks: same name and member info - if (x.Op == Op.OpTypeStruct) - { - comparison = CompareStructMetadata(x, y); - if (comparison != 0) - return comparison; - } } else if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { @@ -123,36 +114,6 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) comparison = UseIndices ? x.Index.CompareTo(y.Index) : 0; return comparison; } - - public int CompareStructMetadata(InstructionSortHelper x, InstructionSortHelper y) - { - var nameInstructions = RequestNameInstructions(); - - // Note: With RemapOp(), this will also find OpMember instructions - var target1 = x.Data.Memory.Span[1]; - var namesStart1 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 }, this); - var namesEnd1 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target1 + 1 }, this); - - var target2 = y.Data.Memory.Span[1]; - var namesStart2 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 }, this); - var namesEnd2 = ~nameInstructions.BinarySearch(new InstructionSortHelper { Op = Op.OpName, TargetOverride = target2 + 1 }, this); - - // Compare sequences (they should be the same) - for (int i = 0; i < Math.Max(namesEnd1 - namesStart1, namesEnd2 - namesStart2); ++i) - { - // If one sequence is longer than the other, define an ordering - if (i >= namesEnd1 - namesStart1) - return -1; - if (i >= namesEnd2 - namesStart2) - return 1; - - var comparison = Compare(nameInstructions[namesStart1 + i], nameInstructions[namesStart2 + i] with { TargetOverride = target1 }); - if (comparison != 0) - return comparison; - } - - return 0; - } } private NewSpirvBuffer buffer; @@ -182,22 +143,11 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) } } - comparerSort = new OperationComparer(GetSortedNames, true); + comparerSort = new OperationComparer(true); + namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(GetSortedNames, false); - } - - public void AddNameInstruction(OpDataIndex i) - { - switch (i.Op) - { - case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: - // Target is always in operand 1 for all those instructions - namesByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); - namesSorted = false; - break; - } + comparerInsert = new OperationComparer(false); } private List GetSortedNames() @@ -276,12 +226,6 @@ private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List Date: Thu, 25 Dec 2025 01:00:57 +0900 Subject: [PATCH 0646/1182] TypeDuplicateRemover: allow to add and remove instruction without full rebuild --- .../Buffers/NewSpirvBuffer.cs | 17 ++-- .../Spirv/Processing/TypeDuplicatesRemover.cs | 79 ++++++++++++++++--- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 533b20e180..104fd04bfe 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -224,6 +224,13 @@ public OpDataIndex Add(OpData data) return new OpDataIndex(Instructions.Count - 1, this); } + public OpDataIndex Insert(int index, OpData data) + { + Instructions.Insert(index, data); + UpdateBound(data); + return new OpDataIndex(index, this); + } + public OpData Add(in T instruction) where T : struct, IMemoryInstruction { if (instruction.DataIndex is OpDataIndex odi) @@ -302,16 +309,16 @@ public OpData InsertData(int index, in T data) /// /// /// true if the instruction was successfully removed - public bool RemoveAt(int index) + public void RemoveAt(int index, bool dispose = true) { if (index < 0 || index >= Instructions.Count) - return false; - Instructions[index].Dispose(); + throw new ArgumentOutOfRangeException(); + if (dispose) + Instructions[index].Dispose(); Instructions.RemoveAt(index); - return true; } - public void RemoveRange(int index, int count, bool dispose) + public void RemoveRange(int index, int count, bool dispose = true) { if (dispose) { diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 950bad1653..a67fb1d043 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using static Stride.Shaders.Spirv.Specification; @@ -131,16 +132,7 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) namesSorted = false; foreach (var i in buffer) { - switch (i.Op) - { - case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: - // Target is always in operand 1 for all those instructions - namesByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); - break; - default: - instructionsByOp.Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); - break; - } + GetTargetList(i.Data).Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); } comparerSort = new OperationComparer(true); @@ -150,6 +142,73 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) comparerInsert = new OperationComparer(false); } + public void InsertInstruction(int index, OpData data) + { + buffer.Insert(index, data); + + // Adjust indices + var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); + for (int i = 0; i < namesByOp.Count; i++) + { + ref var inst = ref namesByOpSpan[i]; + if (inst.Index >= index) + inst.Index++; + } + var instructionsByOpSpan = CollectionsMarshal.AsSpan(instructionsByOp); + for (int i = 0; i < instructionsByOp.Count; i++) + { + ref var inst = ref instructionsByOpSpan[i]; + if (inst.Index >= index) + inst.Index++; + } + + // Add new item + var targetList = GetTargetList(data); + var newItem = new InstructionSortHelper(data.Op, index, data); + var sortedInsertionIndex = targetList.BinarySearch(newItem, comparerSort); + // Since comparerSort uses Index as last key, it should never be an exact match + if (sortedInsertionIndex >= 0) + throw new InvalidOperationException(); + targetList.Insert(~sortedInsertionIndex, newItem); + } + + public void RemoveInstructionAt(int index, bool dispose) + { + buffer.RemoveAt(index, dispose); + + // Adjust indices and remove at same time + var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); + for (int i = 0; i < namesByOp.Count; i++) + { + ref var inst = ref namesByOpSpan[i]; + if (inst.Index > index) + inst.Index--; + else if (inst.Index == index) + namesByOp.RemoveAt(i--); + } + var instructionsByOpSpan = CollectionsMarshal.AsSpan(instructionsByOp); + for (int i = 0; i < instructionsByOp.Count; i++) + { + ref var inst = ref instructionsByOpSpan[i]; + if (inst.Index > index) + inst.Index--; + else if (inst.Index == index) + instructionsByOp.RemoveAt(i--); + } + } + + private List GetTargetList(OpData data) + { + switch (data.Op) + { + case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: + // Target is always in operand 1 for all those instructions + return namesByOp; + default: + return instructionsByOp; + } + } + private List GetSortedNames() { // If any name was added, sort them From 55d27dfff57dba4d721b7e968f278e965ba55dbc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Dec 2025 01:23:59 +0900 Subject: [PATCH 0647/1182] TypeDuplicateRemover: Deduplicate OpTypeArray by computing constant --- .../Spirv/Processing/TypeDuplicatesRemover.cs | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index a67fb1d043..ab272b42c7 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; @@ -52,7 +53,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; } - class OperationComparer(bool UseIndices) : IComparer + class OperationComparer(NewSpirvBuffer Buffer, bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -91,7 +92,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) // Only process types that we care about if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeFunctionSDSL - || x.Op == Op.OpTypeArray || x.Op == Op.OpTypeRuntimeArray + || x.Op == Op.OpTypeRuntimeArray || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler || x.Op == Op.OpTypeGenericSDSL || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) @@ -100,6 +101,17 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) if (comparison != 0) return comparison; } + // For arrays, we have some additional checks: same name and member info + else if (x.Op == Op.OpTypeArray) + { + comparison = x.Data.Memory.Span[2].CompareTo(y.Data.Memory.Span[2]); + if (comparison != 0) + return comparison; + + comparison = CompareIntConstant(Buffer, x.Data.Memory.Span[3], y.Data.Memory.Span[3]); + if (comparison != 0) + return comparison; + } else if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { // Use actual op (they were all remapped to same ID in RemapOp() to be grouped by TargetId first) @@ -117,6 +129,25 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) } } + private static int CompareIntConstant(NewSpirvBuffer buffer, int id1, int id2) + { + if (id1 == id2) + return 0; + + var value1Success = SpirvBuilder.TryGetConstantValue(id1, out var value1, buffer); + var value2Success = SpirvBuilder.TryGetConstantValue(id2, out var value2, buffer); + + return (value1Success, value2Success) switch + { + // Both succeeds: compare values + (true, true) => ((int)value1).CompareTo((int)value2), + // Only one succeeds (use bool order) + (true, false) or (false, true) => value1Success.CompareTo(value2Success), + // Both fails: use ID + (false, false) => id1.CompareTo(id2), + }; + } + private NewSpirvBuffer buffer; private List instructionsByOp; private List namesByOp; @@ -135,11 +166,11 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) GetTargetList(i.Data).Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); } - comparerSort = new OperationComparer(true); + comparerSort = new OperationComparer(buffer, true); namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(false); + comparerInsert = new OperationComparer(buffer, false); } public void InsertInstruction(int index, OpData data) From f07bc0bbcd680c870de65d9f31793cbe6a1ad4c3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Dec 2025 15:56:51 +0900 Subject: [PATCH 0648/1182] StreamAnalyzer: reset resource used between stages --- src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index f4a9ad71e6..dd7fe4b33b 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -85,6 +85,11 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) stream.Value.Read = false; } + // Reset resource used for next stage + foreach (var resource in analysisResult.Resources) + { + resource.Value.Used = false; + } PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { From c02373ad9efa01b74720a6995dcf7d1ca70a83ca Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Dec 2025 15:57:18 +0900 Subject: [PATCH 0649/1182] StreamAnalyzer: remove unused code? --- .../Spirv/Processing/StreamAnalyzer.cs | 116 +++++++++++++++--- 1 file changed, 102 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs index dd7fe4b33b..8f1f7a007a 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs @@ -31,19 +31,32 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public bool Output { get; set; } public bool Private => Input || Output || Read || Write; - public bool Read { get; set; } - public bool Write { get; set; } + public bool Read { get => field; set { field = value; UsedAnyStage = true; } } + public bool Write { get => field; set { field = value; UsedAnyStage = true; } } + public bool UsedAnyStage { get; private set; } public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } class ResourceInfo { - public bool Used { get; set; } + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } } record struct AnalysisResult(SortedList Streams, List Blocks, SortedList Resources); + class LiveAnalysis + { + public HashSet ReferencedMethods { get; } = new(); + } + public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { table.TryResolveSymbol("VSMain", out var entryPointVS); @@ -61,7 +74,8 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; - AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, analysisResult); + var liveAnalysis = new LiveAnalysis(); + AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, analysisResult, liveAnalysis); // If written to, they are expected at the end of pixel shader foreach (var stream in streams) @@ -75,7 +89,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult); + var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis); buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); } @@ -88,12 +102,12 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // Reset resource used for next stage foreach (var resource in analysisResult.Resources) { - resource.Value.Used = false; + resource.Value.UsedThisStage = false; } PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { - AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, analysisResult); + AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, analysisResult, liveAnalysis); // If written to, they are expected at the end of vertex shader foreach (var stream in streams) @@ -103,7 +117,76 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte stream.Value.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis); + } + + // Remove unreferenced code + var removedIds = new HashSet(); + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index]; + if (i.Op == Op.OpFunction && (OpFunction)i is { } function) + { + if (!liveAnalysis.ReferencedMethods.Contains(function.ResultId)) + { + removedIds.Add(function.ResultId); + while (buffer[index].Op != Op.OpFunctionEnd) + { + if (buffer[index].Data.IdResult is int resultId) + removedIds.Add(resultId); + SpirvBuilder.SetOpNop(buffer[index++].Data.Memory.Span); + } + + SpirvBuilder.SetOpNop(buffer[index].Data.Memory.Span); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.UniformConstant, + ResultId: int + } resource) + { + var resourceInfo = analysisResult.Resources[resource.ResultId]; + if (!resourceInfo.UsedAnyStage) + { + removedIds.Add(resource.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Private, + ResultId: int + } stream + && streams.TryGetValue(stream.ResultId, out var streamInfo)) + { + if (!streamInfo.UsedAnyStage) + { + removedIds.Add(stream.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + + foreach (var i in context) + { + if (i.Op == Op.OpName && ((OpName)i) is { } name) + { + if (removedIds.Contains(name.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) + { + if (removedIds.Contains(decorate.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpDecorateString && ((OpDecorateString)i) is { } decorateString) + { + if (removedIds.Contains(decorateString.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } } } @@ -284,7 +367,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(streams, blockIds, resources); } - private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult) + private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var streams = analysisResult.Streams; @@ -397,6 +480,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) if (stream.Value.Private && stream.Value.VariableMethodInitializerId is int methodInitializerId) { + liveAnalysis.ReferencedMethods.Add(methodInitializerId); + var variableValueType = ((PointerType)stream.Value.Type).BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); buffer.Add(new OpStore(stream.Value.VariableId, methodInitializerCall.ResultId, null)); @@ -436,10 +521,11 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) pvariables[pvariableIndex++] = block; foreach (var resource in analysisResult.Resources) { - if (resource.Value.Used) + if (resource.Value.UsedThisStage) pvariables[pvariableIndex++] = resource.Key; } + liveAnalysis.ReferencedMethods.Add(newEntryPointFunction); context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); } @@ -449,8 +535,10 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) /// /// Figure out (recursively) which streams are being read from and written to. /// - private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult) + private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { + liveAnalysis.ReferencedMethods.Add(functionId); + var streams = analysisResult.Streams; var streamsAccessChains = new Dictionary(); @@ -472,14 +560,14 @@ bool TryGetStream(int streamId, out StreamInfo streamInfo) if (TryGetStream(load.Pointer, out var streamInfo) && !streamInfo.Write) streamInfo.Read = true; if (analysisResult.Resources.TryGetValue(load.Pointer, out var resourceInfo)) - resourceInfo.Used = true; + resourceInfo.UsedThisStage = true; } else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { if (TryGetStream(store.Pointer, out var streamInfo)) streamInfo.Write = true; if (analysisResult.Resources.TryGetValue(store.Pointer, out var resourceInfo)) - resourceInfo.Used = true; + resourceInfo.UsedThisStage = true; } else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) { @@ -497,7 +585,7 @@ bool TryGetStream(int streamId, out StreamInfo streamInfo) if (callStack.Contains(functionId)) throw new InvalidOperationException($"Recursive call with method id {functionId}"); callStack.Add(functionId); - AnalyzeStreamReadWrites(buffer, callStack, call.Function, analysisResult); + AnalyzeStreamReadWrites(buffer, callStack, call.Function, analysisResult, liveAnalysis); callStack.RemoveAt(callStack.Count - 1); } } From cbf03d32d786a5641d88041ae0c059a9731c64ab Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 25 Dec 2025 16:50:48 +0900 Subject: [PATCH 0650/1182] ShaderMixer: Removed more non-standard decorations --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e40d2e53bf..cab3b9fc3e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1165,13 +1165,12 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable) temp.RemoveAt(index--); - else if (i.Op == Op.OpDecorate && ((OpDecorate)i).Decoration.Value is Decoration.LinkIdSDSL) + else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration.Value is + Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL + or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW + or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) temp.RemoveAt(index--); - else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i).Decoration.Value == Decoration.LinkIdSDSL) - temp.RemoveAt(index--); - else if (i.Op == Op.OpDecorateString && ((OpDecorateString)i).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) - temp.RemoveAt(index--); - else if (i.Op == Op.OpMemberDecorateString && ((OpMemberDecorateString)i).Decoration.Value is Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + else if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration.Value is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) temp.RemoveAt(index--); // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) From e50ed300731fba9935fcefe185a28afbabdda331 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Dec 2025 02:02:55 +0900 Subject: [PATCH 0651/1182] StreamAnalyzer: remove unused code (part2) --- .../SDSL/ShaderMixer.CBuffers.cs | 75 ++-- .../SDSL/ShaderMixer.cs | 26 +- .../Extensions/spirv.sdsl.grammar-ext.json | 253 ++++++------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 46 ++- .../Parsing/SDSL/AST/ShaderElements.cs | 33 +- .../Spirv/Building/Builder.Class.cs | 41 ++- src/Stride.Shaders/Spirv/Building/Builder.cs | 2 +- src/Stride.Shaders/Spirv/Building/Context.cs | 1 + ...treamAnalyzer.cs => InterfaceProcessor.cs} | 339 ++++++++++++++---- 9 files changed, 552 insertions(+), 264 deletions(-) rename src/Stride.Shaders/Spirv/Processing/{StreamAnalyzer.cs => InterfaceProcessor.cs} (65%) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index bf3bb072df..10aba96ede 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -18,23 +18,35 @@ partial class ShaderMixer { private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { - // If multiple cbuffer with same name Test, they will be renamed Test.0 Test.1 etc. - string GetCBufferFinalName(string cbufferName) + // Collect Decorations + Dictionary logicalGroups = new(); + Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); + foreach (var i in context) { - var dotIndex = cbufferName.IndexOf('.'); - if (dotIndex != -1) - return cbufferName.Substring(0, dotIndex); - - return cbufferName; + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) + { + using var n = new LiteralValue(m.Span); + if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); + } + else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) + { + if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) + decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); + decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); + } + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: var m3 } } decorateLogicalGroup) + { + using var n = new LiteralValue(m3.Span); + logicalGroups.Add(decorateLogicalGroup.Target, n.Value); + } } - string GetCBufferLogicalGroup(string cbufferName) + string? GetCBufferLogicalGroup(int variableId) { - var dotIndex = cbufferName.IndexOf('.'); - if (dotIndex != -1) - return cbufferName.Substring(dotIndex + 1); - - return null; + logicalGroups.TryGetValue(variableId, out var logicalGroup); + return logicalGroup; } // OpSDSLEffect is emitted for any non-root composition @@ -59,31 +71,13 @@ string GetCBufferLogicalGroup(string cbufferName) StructTypePtrId: x.Variable.ResultType, StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, MemberIndexOffset: 0, - LogicalGroup: GetCBufferLogicalGroup(globalContext.Names[x.Variable.ResultId]))) + LogicalGroup: GetCBufferLogicalGroup(x.Variable.ResultId))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) - .GroupBy(x => GetCBufferFinalName(globalContext.Names[x.Variable.ResultId])); + .GroupBy(x => ShaderClass.GetCBufferRealName(globalContext.Names[x.Variable.ResultId])); var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); - Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); - } - else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) - { - if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); - } - } - void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) { int mergedMemberIndex = 0; @@ -133,11 +127,17 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s } } + var idRemapping = new Dictionary(); + var removedIds = new HashSet(); foreach (var cbuffersEntry in cbuffersByNames) { var cbuffers = cbuffersEntry.ToList(); var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); + // In all cases, we update name to one without .0 .1 suffix + // (we do it even for case count == 1 because all buffer except one might have been optimized away) + globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; + if (cbuffersEntry.Count() == 1) { ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); @@ -197,8 +197,6 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s // Update first variable to use new type cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; - // Update name - globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) @@ -215,21 +213,22 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s } } - var idRemapping = new Dictionary(); foreach (ref var cbuffer in cbuffersSpan.Slice(1)) { // Update all cbuffers access to be replaced with first variable (unified cbuffer) idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); + removedIds.Add(cbuffer.Variable.ResultId); // Remove other cbuffer variables SetOpNop(cbuffer.Variable.InstructionMemory.Span); // TODO: Do we want to remove unecessary types? // Maybe we don't care as they are not used anymore, they will be ignored. // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? } - - SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); } } + + SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); + SpirvBuilder.RemapIds(context.GetBuffer(), 0, context.GetBuffer().Count, idRemapping); } private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index cab3b9fc3e..010a1835e5 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -48,7 +48,8 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - new StreamAnalyzer().Process(table, temp, context); + // Process streams and remove unused code/cbuffer/variable/resources + new InterfaceProcessor().Process(table, temp, context); // Merge cbuffers and rgroups // TODO: remove unused cbuffers (before merging them) @@ -194,6 +195,7 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo var shader = shaderClass.Buffer; var offset = context.Bound; + var resourceGroupOffset = context.ResourceGroupBound; // Remember when we started to add instructions in both context and main buffer var shaderStart = buffer.Count; @@ -316,10 +318,19 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (i2.IdResult != null) context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); + // ResourceGroupId: adjust offsets too + if (i2.Op == Op.OpDecorate && (OpDecorate)i2 is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + { + // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly + ref var resourceGroupId = ref i2.Memory.Span[3]; + resourceGroupId += resourceGroupOffset; + context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, resourceGroupId + 1); + } + if (SpirvBuilder.ContainIds(forbiddenIds, i2)) throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); - SpirvBuilder.RemapIds(remapIds, i2); + SpirvBuilder.RemapIds(remapIds, ref i2); // Detect when we switch from context to main buffer if (i2.Op == Op.OpSDSLShader) @@ -432,7 +443,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) { - SpirvBuilder.RemapIds(remapIds, i.Data); + SpirvBuilder.RemapIds(remapIds, ref i.Data); var target = i.Data.Memory.Span[1]; if (removedIds.Contains(target)) @@ -619,7 +630,7 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext { var i2 = new OpData(i.Memory.Span); // All result ids are remapped to new ids - SpirvBuilder.RemapIds(idRemapping, i2); + SpirvBuilder.RemapIds(idRemapping, ref i2); foreachBufferCopy.Add(i2); } @@ -661,7 +672,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte // Apply any OpMemberAccessSDSL remapping if (memberAccesses.Count > 0) - SpirvBuilder.RemapIds(memberAccesses, i.Data); + SpirvBuilder.RemapIds(memberAccesses, ref i.Data); if (i.Data.Op == Op.OpForeachSDSL && (OpForeachSDSL)i is { } @foreach) { @@ -798,7 +809,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte memberAccesses.Clear(); } - SpirvBuilder.RemapIds(memberAccesses, i.Data); + SpirvBuilder.RemapIds(memberAccesses, ref i.Data); } } @@ -842,7 +853,6 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont } // Now, reprocess context with those names - char[] invalidChars = { '<', '>', '[', ']', '.', ',', '-' }; foreach (var i in context) { if (i.Op == Op.OpName && (OpName)i is { } name) @@ -1166,7 +1176,7 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportVariable) temp.RemoveAt(index--); else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration.Value is - Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL + Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) temp.RemoveAt(index--); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index be018c1fa8..6158f6966b 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -381,141 +381,152 @@ { "category": "ValueEnum", "kind": "Decoration", - "enumerants": [ - { - "enumerant": "LinkSDSL", - "value": 8000, - "parameters": [ + "enumerants": [ { - "kind": "LiteralString", - "name": "'Name'" - } - ], - "version": "1.0" - }, - { - "enumerant": "LinkIdSDSL", - "value": 8001, - "parameters": [ + "enumerant": "LinkSDSL", + "value": 8000, + "parameters": [ + { + "kind": "LiteralString", + "name": "'Name'" + } + ], + "version": "1.0" + }, { - "kind": "IdRef" - } - ], - "version": "1.0" - }, - { - "enumerant": "ResourceGroupSDSL", - "value": 8002, - "parameters": [ + "enumerant": "LinkIdSDSL", + "value": 8001, + "parameters": [ + { + "kind": "IdRef" + } + ], + "version": "1.0" + }, { - "kind": "LiteralString", - "name": "'ResourceGroup'" - } - ], - "version": "1.0" - }, - { - "enumerant": "LogicalGroupSDSL", - "value": 8003, - "parameters": [ + "enumerant": "ResourceGroupSDSL", + "value": 8002, + "parameters": [ + { + "kind": "LiteralString", + "name": "'ResourceGroup'" + } + ], + "version": "1.0" + }, { - "kind": "LiteralString", - "name": "'LogicalGroup'" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateFilter", - "value": 8020, - "parameters": [ + "enumerant": "ResourceGroupIdSDSL", + "value": 8003, + "parameters": [ + { + "kind": "LiteralInteger", + "name": "'ResourceGroup'" + } + ], + "version": "1.0" + }, { - "kind": "SamplerFilterSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressU", - "value": 8021, - "parameters": [ + "enumerant": "LogicalGroupSDSL", + "value": 8004, + "parameters": [ + { + "kind": "LiteralString", + "name": "'LogicalGroup'" + } + ], + "version": "1.0" + }, { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressV", - "value": 8022, - "parameters": [ + "enumerant": "SamplerStateFilter", + "value": 8020, + "parameters": [ + { + "kind": "SamplerFilterSDSL" + } + ], + "version": "1.0" + }, { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressW", - "value": 8023, - "parameters": [ + "enumerant": "SamplerStateAddressU", + "value": 8021, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMipLODBias", - "value": 8024, - "parameters": [ + "enumerant": "SamplerStateAddressV", + "value": 8022, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxAnisotropy", - "value": 8025, - "parameters": [ + "enumerant": "SamplerStateAddressW", + "value": 8023, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, { - "kind": "LiteralInteger" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateComparisonFunc", - "value": 8026, - "parameters": [ + "enumerant": "SamplerStateMipLODBias", + "value": 8024, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, { - "kind": "SamplerComparisonFuncSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMinLOD", - "value": 8027, - "parameters": [ + "enumerant": "SamplerStateMaxAnisotropy", + "value": 8025, + "parameters": [ + { + "kind": "LiteralInteger" + } + ], + "version": "1.0" + }, { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxLOD", - "value": 8028, - "parameters": [ + "enumerant": "SamplerStateComparisonFunc", + "value": 8026, + "parameters": [ + { + "kind": "SamplerComparisonFuncSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMinLOD", + "value": 8027, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, { - "kind": "LiteralString" + "enumerant": "SamplerStateMaxLOD", + "value": 8028, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" } - ], - "version": "1.0" - } - ] + ] }, { "category": "ValueEnum", diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a3055c35e3..9d02e985b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -447,21 +447,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.CurrentShader = currentShader; table.InheritedShaders = inheritanceList; - // If multiple cbuffer with same name, they will be merged - // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpSDSLImportStruct/OpSDSLImportVariable would be ambiguous) - var cbuffersByNames = Elements.OfType().GroupBy(x => x.Name); - foreach (var cbufferGroup in cbuffersByNames) - { - if (cbufferGroup.Count() > 1) - { - int index = 0; - foreach (var cbuffer in cbufferGroup) - { - cbuffer.Name = $"{cbuffer.Name}.{index}"; - index++; - } - } - } + RenameCBufferVariables(); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); @@ -494,6 +480,36 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.Pop(); } + // If multiple cbuffer with same name, they will be merged + // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpSDSLImportStruct/OpSDSLImportVariable would be ambiguous) + private void RenameCBufferVariables() + { + var cbuffersByNames = Elements.OfType().GroupBy(x => x.Name); + foreach (var cbufferGroup in cbuffersByNames) + { + if (cbufferGroup.Count() > 1) + { + int index = 0; + foreach (var cbuffer in cbufferGroup) + { + cbuffer.Name = $"{cbuffer.Name}.{index}"; + index++; + } + } + } + } + + // If multiple cbuffer with same name Test, they will be renamed Test.0 Test.1 etc. + public static string GetCBufferRealName(string cbufferName) + { + var dotIndex = cbufferName.IndexOf('.'); + if (dotIndex != -1) + return cbufferName.Substring(0, dotIndex); + + return cbufferName; + } + + public static void Inherit(SymbolTable table, SpirvContext context, LoadedShaderSymbol shaderType, bool addToRoot) { var shaderId = context.GetOrRegister(shaderType); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 5a9c9af437..79b76bb894 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -154,11 +154,19 @@ public override string ToString() } } -public abstract class ShaderBuffer(string name, TextLocation info) : ShaderElement(info) +public abstract class ShaderBuffer : ShaderElement { - public string Name { get; set; } = name; + public string Name { get; set; } + public string? LogicalGroup { get; } = null; public List Members { get; set; } = []; + public ShaderBuffer(string name, TextLocation info) : base(info) + { + var dotIndex = name.IndexOf('.'); + Name = dotIndex != -1 ? name.Substring(0, dotIndex) : name; + LogicalGroup = dotIndex != -1 ? name.Substring(dotIndex + 1) : null; + } + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); @@ -284,7 +292,8 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var constantBufferType = (ConstantBufferSymbol)Type; - // We try to avoid clash in case multiple cbuffer with same name + // We try to avoid clash in case multiple cbuffer TYPE with same name + // The variable itself is handled by adding a .0 .1 etc. in Shader.RenameCBufferVariables() int tryCount = 0; var typeName = constantBufferType.Name; while (!table.DeclaredTypes.TryAdd(constantBufferType.ToId(), Type)) @@ -298,6 +307,10 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); var variable = context.Bound++; + context.AddName(variable, Name); + if (LogicalGroup != null) + context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationLogicalGroupSDSL(LogicalGroup))); + bool? isStaged = null; for (var index = 0; index < Members.Count; index++) @@ -327,7 +340,6 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile // TODO: Add a StreamSDSL storage class? builder.Insert(new OpVariableSDSL(pointerType, variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); - context.AddName(variable, Name); } } @@ -337,9 +349,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { var (builder, context) = compiler; - var splitDotIndex = Name.IndexOf('.'); - var resourceGroupName = splitDotIndex != -1 ? Name.Substring(0, splitDotIndex) : Name; - var logicalGroupName = splitDotIndex != -1 ? Name.Substring(splitDotIndex + 1) : null; + var resourceGroupId = context.ResourceGroupBound++; for (var index = 0; index < Members.Count; index++) { @@ -360,9 +370,12 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); - context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationResourceGroupSDSL(resourceGroupName))); - if (logicalGroupName != null) - context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationLogicalGroupSDSL(logicalGroupName))); + context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationResourceGroupSDSL(Name))); + // We also store an ID because multiple rgroup might have the same name, + // but we still want to know which one was in the same "block" when we try to optimize them (we can only optimize a resource if all the resource in the same rgroup block can be optimized) + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationResourceGroupIdSDSL(resourceGroupId))); + if (LogicalGroup != null) + context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationLogicalGroupSDSL(LogicalGroup))); var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, variable.ResultId); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 38cfda41b4..cc1c927f5a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL.AST; @@ -563,12 +564,23 @@ public static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEn for (var index = shaderStart; index < buffer.Count; index++) { var i = buffer[index]; - RemapIds(idRemapping, i.Data); + RemapIds(idRemapping, ref i.Data); } } - public static void RemapIds(Dictionary idRemapping, OpData i) + public static void RemapIds(Dictionary idRemapping, ref OpData i) { + // Special case: remove OpName and such + if (i.Op == Op.OpName || i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString + || i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) + { + // Target/Structure ID is always stored in first operand for all those instructions + var target = i.Memory.Span[1]; + if (idRemapping.ContainsKey(target)) + SetOpNop(i.Memory.Span); + return; + } + foreach (var op in i) { if ((op.Kind == OperandKind.IdRef @@ -582,6 +594,31 @@ public static void RemapIds(Dictionary idRemapping, OpData i) if (idRemapping.TryGetValue(word, out var to1)) word = to1; } + + // Special case: remove duplicates in OpEntryPoint + // TODO: It's a bit ugly but we could make it better later with some syntactic sugar helper + if (i.Op == Op.OpEntryPoint && op.Quantifier == OperandQuantifier.ZeroOrMore) + { + var existing = new HashSet(); + var target = 0; + for (int index = 0; index < op.Words.Length; ++index) + { + if (existing.Add(op.Words[index])) + { + op.Words[target++] = op.Words[index]; + } + } + // Adjust new size + var length = i.Memory.Span[0] >> 16; + length -= op.Words.Length - target; + i.Memory.Span[0] = ((int)i.Memory.Span[0] & 0xFFFF) | (length << 16); + + var tmp = MemoryOwner.Allocate(length); + i.Memory.Span.Slice(0, length).CopyTo(tmp.Span); + i.Memory.Dispose(); + i = new(tmp); + + } } if ((op.Kind == OperandKind.PairIdRefLiteralInteger) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 41a72951fa..471abcc93a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -135,7 +135,7 @@ public void Dispose() } } - static char[] invalidChars = { '<', '>', '[', ']', '.', ',', '-' }; + static char[] invalidChars = { '<', '>', '[', ']', '.', ',', '-', '#' }; public static string RemoveInvalidCharactersFromSymbol(string name) { return string.Join("_", name.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries)); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 51b36d5870..5444935f1f 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -25,6 +25,7 @@ public interface IExternalShaderLoader // SPIR-V parameters public class SpirvContext { + public int ResourceGroupBound { get; set; } = 1; public int Bound { get; set; } = 1; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; diff --git a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs similarity index 65% rename from src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs rename to src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 8f1f7a007a..300ded4e03 100644 --- a/src/Stride.Shaders/Spirv/Processing/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -10,7 +10,10 @@ namespace Stride.Shaders.Spirv.Processing { - public class StreamAnalyzer + /// + /// Help to process streams and simplify the interface (resources, methods, cbuffer) of the shader. + /// + public class InterfaceProcessor { class StreamInfo(string? semantic, string name, SymbolType type, int variableId) { @@ -38,8 +41,36 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - class ResourceInfo + class ResourceInfo(string name) { + public string Name { get; } = name; + + public ResourceGroup ResourceGroup { get; set; } + + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } + } + + record class ResourceGroup + { + public bool Used { get; set; } + public string Name { get; set; } + public string? LogicalGroup { get; set; } + public List Resources { get; } = new(); + } + + record class CBufferInfo(string name) + { + public string Name { get; } = name; + + public string? LogicalGroup { get; set; } + /// /// Used during current stage being processed? /// @@ -50,11 +81,40 @@ class ResourceInfo public bool UsedAnyStage { get; private set; } } - record struct AnalysisResult(SortedList Streams, List Blocks, SortedList Resources); + class LogicalGroupInfo + { + public List Resources { get; } = new(); + public List CBuffers { get; } = new(); + } + + record struct AnalysisResult(SortedList Streams, SortedList CBuffers, SortedList ResourceGroups, SortedList Resources); + + class MethodInfo + { + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } + } class LiveAnalysis { - public HashSet ReferencedMethods { get; } = new(); + public Dictionary ReferencedMethods { get; } = new(); + + public bool MarkMethodUsed(int functionId) + { + if (!ReferencedMethods.TryGetValue(functionId, out MethodInfo methodInfo)) + ReferencedMethods.Add(functionId, methodInfo = new MethodInfo()); + + var previousValue = methodInfo.UsedThisStage; + methodInfo.UsedThisStage = true; + // Returns tree when added first time + return !previousValue; + } } public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) @@ -68,7 +128,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte entryPointPS = entryPointPS.GroupMembers[^1]; if (entryPointPS.IdRef == 0) - throw new InvalidOperationException($"{nameof(StreamAnalyzer)}: At least a pixel shader is expected"); + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel shader is expected"); var analysisResult = Analyze(buffer, context); MergeSameSemanticVariables(table, context, buffer, analysisResult); @@ -84,7 +144,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte && stream.Value.Write) stream.Value.Output = true; } - + // Check if there is any output // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) @@ -99,11 +159,13 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) stream.Value.Read = false; } - // Reset resource used for next stage + // Reset cbuffer/resource/methods used for next stage foreach (var resource in analysisResult.Resources) - { resource.Value.UsedThisStage = false; - } + foreach (var cbuffer in analysisResult.CBuffers) + cbuffer.Value.UsedThisStage = false; + foreach (var method in liveAnalysis.ReferencedMethods) + method.Value.UsedThisStage = false; PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { @@ -120,14 +182,74 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis); } + // This will remove a lot of unused methods, resources and variables + // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) + RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); + } + + private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, SortedList streams, LiveAnalysis liveAnalysis) + { // Remove unreferenced code var removedIds = new HashSet(); + + // First, build resource group (used status and logical groups) + var logicalGroups = new Dictionary(); + foreach (var resourceGroup in analysisResult.ResourceGroups) + { + foreach (var resource in resourceGroup.Value.Resources) + { + if (resource.UsedAnyStage) + { + resourceGroup.Value.Used = true; + } + + if (resourceGroup.Value.LogicalGroup != null) + { + ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{resourceGroup.Value.Name}.{resourceGroup.Value.LogicalGroup}", out var exists); + if (!exists) + logicalGroup = new(); + logicalGroup.Resources.Add(resourceGroup.Value); + } + } + } + // Complete logical groups with cbuffers + foreach (var cbuffer in analysisResult.CBuffers) + { + if (cbuffer.Value.LogicalGroup != null) + { + ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{cbuffer.Value.Name}.{cbuffer.Value.LogicalGroup}", out var exists); + if (!exists) + logicalGroup = new(); + logicalGroup.CBuffers.Add(cbuffer.Value); + } + } + + // Check logical group: if any resource is used, mark everything as used + // TODO: make sure register allocation is contiguous + foreach (var logicalGroup in logicalGroups) + { + var logicalGroupUsed = false; + foreach (var resource in logicalGroup.Value.Resources) + logicalGroupUsed |= resource.Used; + foreach (var cbuffer in logicalGroup.Value.CBuffers) + logicalGroupUsed |= cbuffer.UsedAnyStage; + + if (logicalGroupUsed) + { + // Mark everything as used + foreach (var resource in logicalGroup.Value.Resources) + resource.Used = logicalGroupUsed; + foreach (var cbuffer in logicalGroup.Value.CBuffers) + cbuffer.UsedThisStage = logicalGroupUsed; + } + } + for (var index = 0; index < buffer.Count; index++) { var i = buffer[index]; if (i.Op == Op.OpFunction && (OpFunction)i is { } function) { - if (!liveAnalysis.ReferencedMethods.Contains(function.ResultId)) + if (!liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId)) { removedIds.Add(function.ResultId); while (buffer[index].Op != Op.OpFunctionEnd) @@ -141,6 +263,20 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte } } + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Uniform, + ResultId: int + } variable + && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) + { + if (!cbufferInfo.UsedAnyStage) + { + removedIds.Add(variable.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { Storageclass: StorageClass.UniformConstant, @@ -148,7 +284,9 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte } resource) { var resourceInfo = analysisResult.Resources[resource.ResultId]; - if (!resourceInfo.UsedAnyStage) + // If resource has a rgroup, check its state (if any resource is used in the group, we need to keep every resource) + // If no rgroup, we check the resource itself + if (!(resourceInfo.ResourceGroup?.Used ?? false || resourceInfo.UsedAnyStage)) { removedIds.Add(resource.ResultId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); @@ -240,7 +378,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) HashSet blockTypes = []; Dictionary blockPointerTypes = []; - List blockIds = []; + SortedList cbuffers = []; SortedList resources = []; // Build name table @@ -296,7 +434,10 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) { - blockIds.Add(bufferId); + var name = nameTable[bufferId]; + // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) + // Adjust for it + cbuffers.Add(bufferId, new(name)); } } @@ -322,49 +463,98 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) } // Analyze streams - foreach (var temp in new[] { context.GetBuffer(), buffer }) + foreach (var i in buffer) { - foreach (var instruction in temp) + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Private, + ResultId: int + } variable) { - if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is - { - Storageclass: StorageClass.Private, - ResultId: int - } variable) + var name = nameTable.TryGetValue(variable.ResultId, out var nameId) + ? nameId + : $"unnamed_{variable.ResultId}"; + var type = context.ReverseTypes[variable.ResultType]; + semanticTable.TryGetValue(variable.ResultId, out var semantic); + + var stream = new StreamInfo(semantic, name, type, variable.ResultId) { - var name = nameTable.TryGetValue(variable.ResultId, out var nameId) - ? nameId - : $"unnamed_{variable.ResultId}"; - var type = context.ReverseTypes[variable.ResultType]; - semanticTable.TryGetValue(variable.ResultId, out var semantic); + // Does it have an initializer? if yes, mark it as a value written in this stage + Write = variable.MethodInitializer != null, + VariableMethodInitializerId = variable.MethodInitializer, + }; - var stream = new StreamInfo(semantic, name, type, variable.ResultId) - { - // Does it have an initializer? if yes, mark it as a value written in this stage - Write = variable.MethodInitializer != null, - VariableMethodInitializerId = variable.MethodInitializer, - }; + streams.Add(variable.ResultId, stream); + } - streams.Add(variable.ResultId, stream); - } + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.UniformConstant, + ResultId: int + } resource) + { + var name = nameTable.TryGetValue(resource.ResultId, out var nameId) + ? nameId + : $"unnamed_{resource.ResultId}"; + var type = context.ReverseTypes[resource.ResultType]; - if (instruction.Op == Op.OpVariableSDSL && ((OpVariableSDSL)instruction) is - { - Storageclass: StorageClass.UniformConstant, - ResultId: int - } resource) + resources.Add(resource.ResultId, new ResourceInfo(name)); + } + } + + // Process ResourceGroupId and build ResourceGroups + SortedList resourceGroups = new(); + foreach (var i in context) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + { + var n = new LiteralValue(m.Span); + + if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) { - var name = nameTable.TryGetValue(resource.ResultId, out var nameId) - ? nameId - : $"unnamed_{resource.ResultId}"; - var type = context.ReverseTypes[resource.ResultType]; + if (!resourceGroups.TryGetValue(n.Value, out var resourceGroup)) + resourceGroups.Add(n.Value, resourceGroup = new()); + + resourceGroup.Resources.Add(resourceInfo); + + resourceInfo.ResourceGroup = resourceGroup; - resources.Add(resource.ResultId, new ResourceInfo()); } + n.Dispose(); } } - return new(streams, blockIds, resources); + // Process ResourceGroup and LogicalGroup decorations + foreach (var i in context) + { + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.ResourceGroupSDSL, Parameters: { } m2 } } resourceGroupDecorate) + { + if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) + // Note: ResourceGroup should not be null if set + && resourceInfo.ResourceGroup.Name == null) + { + using var n = new LiteralValue(m2.Span); + resourceInfo.ResourceGroup.Name = n.Value; + } + } + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m3 } } logicalGroupDecorate) + { + if (resources.TryGetValue(logicalGroupDecorate.Target, out var resourceInfo) + // Note: ResourceGroup should not be null if this decoration is set + && resourceInfo.ResourceGroup.LogicalGroup == null) + { + using var n = new LiteralValue(m3.Span); + resourceInfo.ResourceGroup.LogicalGroup = n.Value; + } + else if (cbuffers.TryGetValue(logicalGroupDecorate.Target, out var cbufferInfo)) + { + using var n = new LiteralValue(m3.Span); + cbufferInfo.LogicalGroup = n.Value; + } + } + } + + return new(streams, cbuffers, resourceGroups, resources); } private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) @@ -480,7 +670,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) if (stream.Value.Private && stream.Value.VariableMethodInitializerId is int methodInitializerId) { - liveAnalysis.ReferencedMethods.Add(methodInitializerId); + liveAnalysis.MarkMethodUsed(methodInitializerId); var variableValueType = ((PointerType)stream.Value.Type).BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); @@ -508,7 +698,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.Blocks.Count + analysisResult.Resources.Count]; + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count]; int pvariableIndex = 0; foreach (var inputStream in inputStreams) pvariables[pvariableIndex++] = inputStream.Id; @@ -516,16 +706,18 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) pvariables[pvariableIndex++] = outputStream.Id; foreach (var privateStream in privateStreams) pvariables[pvariableIndex++] = privateStream.VariableId; - // TODO: filter blocks and resources actually used by this entrypoint with ProcessMethod()? - foreach (var block in analysisResult.Blocks) - pvariables[pvariableIndex++] = block; + foreach (var cbuffer in analysisResult.CBuffers) + { + if (cbuffer.Value.UsedThisStage) + pvariables[pvariableIndex++] = cbuffer.Key; + } foreach (var resource in analysisResult.Resources) { if (resource.Value.UsedThisStage) pvariables[pvariableIndex++] = resource.Key; } - liveAnalysis.ReferencedMethods.Add(newEntryPointFunction); + liveAnalysis.MarkMethodUsed(newEntryPointFunction); context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); } @@ -537,16 +729,12 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) /// private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { - liveAnalysis.ReferencedMethods.Add(functionId); + // Mark as used, and check if already processed + if (!liveAnalysis.MarkMethodUsed(functionId)) + return; var streams = analysisResult.Streams; - var streamsAccessChains = new Dictionary(); - - bool TryGetStream(int streamId, out StreamInfo streamInfo) - { - return streams.TryGetValue(streamId, out streamInfo) - || streamsAccessChains.TryGetValue(streamId, out streamInfo); - } + var accessChainBases = new Dictionary(); var methodStart = FindMethodStart(buffer, functionId); for (var index = methodStart; index < buffer.Count; index++) @@ -557,27 +745,40 @@ bool TryGetStream(int streamId, out StreamInfo streamInfo) if (instruction.Op is Op.OpLoad && (OpLoad)instruction is { } load) { - if (TryGetStream(load.Pointer, out var streamInfo) && !streamInfo.Write) + // Check for access chains + if (!accessChainBases.TryGetValue(load.Pointer, out var pointer)) + pointer = load.Pointer; + + if (streams.TryGetValue(pointer, out var streamInfo) && !streamInfo.Write) streamInfo.Read = true; - if (analysisResult.Resources.TryGetValue(load.Pointer, out var resourceInfo)) + if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) resourceInfo.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + cbufferInfo.UsedThisStage = true; } else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) { - if (TryGetStream(store.Pointer, out var streamInfo)) + // Check for access chains + if (!accessChainBases.TryGetValue(store.Pointer, out var pointer)) + pointer = store.Pointer; + + if (streams.TryGetValue(pointer, out var streamInfo)) streamInfo.Write = true; - if (analysisResult.Resources.TryGetValue(store.Pointer, out var resourceInfo)) + if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) resourceInfo.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + cbufferInfo.UsedThisStage = true; } else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) { - if (TryGetStream(accessChain.BaseId, out var streamInfo)) - { - // Map the pointer access as access to the underlying stream (if any) - // i.e., streams.A.B will share same streamInfo as streams.A - // TODO: what happens in case of partial write? - streamsAccessChains.TryAdd(accessChain.ResultId, streamInfo); - } + // Any read or write through an access chain will be treated as doing it on the main variable. + // i.e., streams.A.B will share same streamInfo as streams.A + // TODO: what happens in case of partial write? + var currentBase = accessChain.BaseId; + // Recurse in case we have multiple access chain chained after each other + while (accessChainBases.TryGetValue(currentBase, out var nextBase)) + currentBase = nextBase; + accessChainBases.Add(accessChain.ResultId, currentBase); } else if (instruction.Op == Op.OpFunctionCall && (OpFunctionCall)instruction is { } call) { From 167841f14ef8b176fcb572c4b83e93560c522cbf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Dec 2025 12:18:07 +0900 Subject: [PATCH 0652/1182] Instructions: Made them ref struct and store OpData as a ref field --- .../SDSL/ShaderMixer.CBuffers.cs | 35 +++-- .../SDSL/ShaderMixer.ShaderInfo.cs | 8 +- .../SDSL/ShaderMixer.cs | 16 ++- .../Examples.Spirv.cs | 2 +- .../Buffers/NewSpirvBuffer.cs | 63 ++------- .../Literals/LiteralArray.cs | 5 + .../SPVGenerator.Instructions.cs | 128 ++++++++++-------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 3 +- .../Spirv/Building/Builder.Class.cs | 20 +-- src/Stride.Shaders/Spirv/Building/Builder.cs | 4 +- src/Stride.Shaders/Spirv/Building/Context.cs | 6 +- .../Spirv/Processing/InterfaceProcessor.cs | 8 +- 12 files changed, 139 insertions(+), 159 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 10aba96ede..14724dba9b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -62,23 +62,23 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex var cbuffersByNames = buffer .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (Index: x.Index, Variable: (OpVariableSDSL)x)) + .Select(x => (Index: x.Index, Variable: x)) // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x.Variable, CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, - StructTypePtrId: x.Variable.ResultType, - StructType: context.ReverseTypes[x.Variable.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + StructTypePtrId: x.Variable.Data.IdResultType.Value, + StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, MemberIndexOffset: 0, - LogicalGroup: GetCBufferLogicalGroup(x.Variable.ResultId))) + LogicalGroup: GetCBufferLogicalGroup(x.Variable.Data.IdResult.Value))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) - .GroupBy(x => ShaderClass.GetCBufferRealName(globalContext.Names[x.Variable.ResultId])); + .GroupBy(x => ShaderClass.GetCBufferRealName(globalContext.Names[x.Variable.Data.IdResult.Value])); var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); - void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) + void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) { int mergedMemberIndex = 0; foreach (ref var cbuffer in cbuffersSpan) @@ -136,7 +136,7 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s // In all cases, we update name to one without .0 .1 suffix // (we do it even for case count == 1 because all buffer except one might have been optimized away) - globalContext.Names[cbuffersSpan[0].Variable.ResultId] = cbuffersEntry.Key; + globalContext.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; if (cbuffersEntry.Count() == 1) { @@ -152,7 +152,7 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s cbuffer.MemberIndexOffset = offset; offset += cbuffer.StructType.Members.Count; } - var variables = cbuffers.ToDictionary(x => x.Variable.ResultId, x => x); + var variables = cbuffers.ToDictionary(x => x.Variable.Data.IdResult.Value, x => x); var structTypes = cbuffers.Select(x => x.StructType); var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); @@ -196,18 +196,18 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s } // Update first variable to use new type - cbuffersSpan[0].Variable.ResultType = mergedCbufferPtrStructId; + cbuffersSpan[0].Variable.Data.IdResultType = mergedCbufferPtrStructId; foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) { // Ensure cbuffer variable name is correct (it might still have a pending number such as Test.0 if there was multiple buffers with same name) - if (cbuffersSpan[0].Variable.ResultId == name.Target) + if (cbuffersSpan[0].Variable.Data.IdResult == name.Target) name.Name = cbuffersEntry.Key; // Remove any other OpName (after remapping they would all point to the merged variable) foreach (var cbuffer in cbuffersSpan[1..]) { - if (cbuffer.Variable.ResultId == name.Target) + if (cbuffer.Variable.Data.IdResult == name.Target) SetOpNop(i.Data.Memory.Span); } } @@ -216,10 +216,10 @@ void ProcessDecorations(Span<(OpVariableSDSL Variable, string CompositionPath, s foreach (ref var cbuffer in cbuffersSpan.Slice(1)) { // Update all cbuffers access to be replaced with first variable (unified cbuffer) - idRemapping.Add(cbuffer.Variable.ResultId, cbuffersSpan[0].Variable.ResultId); - removedIds.Add(cbuffer.Variable.ResultId); + idRemapping.Add(cbuffer.Variable.Data.IdResult.Value, cbuffersSpan[0].Variable.Data.IdResult.Value); + removedIds.Add(cbuffer.Variable.Data.IdResult.Value); // Remove other cbuffer variables - SetOpNop(cbuffer.Variable.InstructionMemory.Span); + SetOpNop(cbuffer.Variable.Data.Memory.Span); // TODO: Do we want to remove unecessary types? // Maybe we don't care as they are not used anymore, they will be ignored. // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? @@ -235,12 +235,11 @@ private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContex { var cbuffers = buffer .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (OpVariableSDSL)x) // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x, - StructTypePtrId: x.ResultType, - StructType: context.ReverseTypes[x.ResultType] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + StructTypePtrId: x.Data.IdResultType.Value, + StructType: context.ReverseTypes[x.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, MemberIndexOffset: 0)) .Where(x => x.StructType != null) .ToList(); @@ -371,7 +370,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription { - Name = globalContext.Names[cbuffer.Variable.ResultId], + Name = globalContext.Names[cbuffer.Variable.Data.IdResult.Value], // Round buffer size to next multiple of 16 bytes Size = (constantBufferOffset + 15) / 16 * 16, diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 1554268c4c..1368d30477 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -99,9 +99,9 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer } } - private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, OpData i, NewSpirvBuffer contextBuffer) + private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, ref OpData i, NewSpirvBuffer contextBuffer) { - if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + if (i.Op == Op.OpSDSLImportShader && new OpSDSLImportShader(ref i) is { } importShader) { // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups var shaderName = importShader.ShaderName; @@ -117,14 +117,14 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin globalContext.ExternalShaders.Add(importShader.ResultId, shaderName); } - else if (i.Op == Op.OpSDSLImportFunction && (OpSDSLImportFunction)i is { } importFunction) + else if (i.Op == Op.OpSDSLImportFunction && new OpSDSLImportFunction(ref i) is { } importFunction) { if (globalContext.ExternalShaders.ContainsKey(importFunction.Shader)) { globalContext.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName, importFunction.FunctionType)); } } - else if (i.Op == Op.OpSDSLImportVariable && (OpSDSLImportVariable)i is { } importVariable) + else if (i.Op == Op.OpSDSLImportVariable && new OpSDSLImportVariable(ref i) is { } importVariable) { if (globalContext.ExternalShaders.ContainsKey(importVariable.Shader)) { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 010a1835e5..c796a8adb2 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -319,12 +319,14 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); // ResourceGroupId: adjust offsets too - if (i2.Op == Op.OpDecorate && (OpDecorate)i2 is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) { // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly - ref var resourceGroupId = ref i2.Memory.Span[3]; - resourceGroupId += resourceGroupOffset; - context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, resourceGroupId + 1); + var n = new LiteralValue(m.Span); + n.Value += resourceGroupOffset; + resourceGroupIdDecorate.Decoration = new(resourceGroupIdDecorate.Decoration.Value, n.Words); + context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, n.Value + 1); + n.Dispose(); } if (SpirvBuilder.ContainIds(forbiddenIds, i2)) @@ -362,7 +364,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS || i2.Op == Op.OpSDSLImportStruct) { // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) - if (i2.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)i2 is { } importStruct) + if (i2.Op == Op.OpSDSLImportStruct && new OpSDSLImportStruct(ref i2) is { } importStruct) { var shaderName = globalContext.ExternalShaders[importStruct.Shader]; var shader2 = mixinNode.ShadersByName[shaderName]; @@ -401,7 +403,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // OpTypeStruct is the only type that can be defined by the shader. // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. - if (i2.Op == Op.OpTypeStruct && (OpTypeStruct)i2 is { } typeStruct2) + if (i2.Op == Op.OpTypeStruct && new OpTypeStruct(ref i2) is { } typeStruct2) { var structName = names[typeStruct2.ResultId - offset]; if (!remapIds.TryGetValue(typeStruct2.ResultId, out var structId)) @@ -410,7 +412,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } // Process OpSDSLImport - ProcessImportInfo(globalContext, mixinNode, i2, context.GetBuffer()); + ProcessImportInfo(globalContext, mixinNode, ref i2, context.GetBuffer()); if (addToContext) { diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 3f134c7025..6cb5d19427 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -65,7 +65,7 @@ public static void CreateNewShader() buffer.FluentAdd(new OpCapability(Capability.Shader)); var extInstImport = new OpExtInstImport(id++, "GLSL.std.450"); - buffer.AddRef(ref extInstImport); + buffer.Add(extInstImport); buffer.FluentAdd(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 104fd04bfe..169b4655d5 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -2,6 +2,7 @@ using System.Collections; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using CommunityToolkit.HighPerformance; @@ -14,7 +15,7 @@ namespace Stride.Shaders.Spirv.Core.Buffers; public interface IMemoryInstruction { - OpDataIndex? DataIndex { get; set; } + ref OpData OpData { get; } MemoryOwner InstructionMemory { get; } public void UpdateInstructionMemory(); } @@ -231,71 +232,37 @@ public OpDataIndex Insert(int index, OpData data) return new OpDataIndex(index, this); } - public OpData Add(in T instruction) where T : struct, IMemoryInstruction + public OpData Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct { - if (instruction.DataIndex is OpDataIndex odi) - { - if (odi.Buffer == this) - return odi.Data; - else - Instructions.Add(new(instruction.InstructionMemory)); - } - else Instructions.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); UpdateBound(Instructions[^1]); return Instructions[^1]; } - public void AddRef(ref T instruction) where T : struct, IMemoryInstruction + public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction, allows ref struct { - if (instruction.DataIndex is OpDataIndex odi) - { - if (odi.Buffer == this) - return; - else - Instructions.Add(new(instruction.InstructionMemory)); - } - else Instructions.Add(new(instruction.InstructionMemory)); - instruction.DataIndex = new(Instructions.Count - 1, this); - UpdateBound(Instructions[^1]); - } - public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction - { - if (instruction.DataIndex is OpDataIndex odi) - { - if (odi.Buffer == this) - return this; - else - Instructions.Add(new(instruction.InstructionMemory)); - } - else Instructions.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; UpdateBound(Instructions[^1]); return this; } - public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction + public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct { result = instruction; - if (instruction.DataIndex is OpDataIndex odi) - { - if (odi.Buffer == this) - return this; - else - Instructions.Add(new(instruction.InstructionMemory)); - } - else Instructions.Add(new(instruction.InstructionMemory)); + Instructions.Add(new(instruction.InstructionMemory)); UpdateBound(Instructions[^1]); return this; } public T Insert(int index, in T data) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct { Instructions.Insert(index, new(data.InstructionMemory)); UpdateBound(Instructions[^1]); return data; } public OpData InsertData(int index, in T data) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct { var result = new OpData(data.InstructionMemory); Instructions.Insert(index, result); @@ -346,7 +313,7 @@ public OpData Replace(int index, OpData i) return Instructions[index]; } - public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction + public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct { if (index < 0 || index >= Instructions.Count) throw new InvalidOperationException(); @@ -468,11 +435,11 @@ public static class IMemoryInstructionExtensions /// /// /// - public static LogicalOperandArray GetInfo(this ref T op) - where T : struct, IMemoryInstruction + public static LogicalOperandArray GetInfo(this T op) + where T : struct, IMemoryInstruction, allows ref struct { - if (op.DataIndex is OpDataIndex odi) - return InstructionInfo.GetInfo(odi.Data); + if (!Unsafe.IsNullRef(ref op.OpData)) + return InstructionInfo.GetInfo(op.OpData); return InstructionInfo.GetInfo(op.InstructionMemory.Span); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index 2689603c22..f68e2181db 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -85,6 +85,11 @@ public void Assign(Span span) span.CopyTo(Elements.Span); } + public LiteralArray Slice(int start, int length) + { + return new LiteralArray(Elements.Slice(start, length)); + } + public readonly void Dispose() => Elements.Dispose(); public readonly Span.Enumerator GetEnumerator() => Elements.Span.GetEnumerator(); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index fba67067d6..d61bc32590 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -30,6 +30,7 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv .AppendLine("using CommunityToolkit.HighPerformance.Buffers;") .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") .AppendLine("using System.Numerics;") + .AppendLine("using System.Runtime.CompilerServices;") .AppendLine() .AppendLine("namespace Stride.Shaders.Spirv.Core;") .AppendLine() @@ -152,16 +153,17 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") .AppendLine("{") - .AppendLine("InitializeProperties(index.Data);") - .AppendLine("DataIndex = index;") + .AppendLine("InitializeProperties(ref index.Data);") + .AppendLine("opData = ref index.Data;") .AppendLine("}"); - body2.AppendLine($"public {instruction.OpName}(OpData data)") + body2.AppendLine($"public {instruction.OpName}(ref OpData data)") .AppendLine("{") - .AppendLine("InitializeProperties(data);") + .AppendLine("InitializeProperties(ref data);") + .AppendLine("opData = ref data;") .AppendLine("}"); - body2.AppendLine($"private void InitializeProperties(OpData data)") + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) @@ -238,6 +240,7 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst body3 .AppendLine("UpdateInstructionMemory();") + .AppendLine("opData = ref Unsafe.NullRef();") .AppendLine("}"); // Body 4 @@ -268,24 +271,25 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst body2.AppendLine("}"); builder.AppendLine($@" - public struct {instruction.OpName} : IMemoryInstruction + public ref partial struct {instruction.OpName} : IMemoryInstruction {{ - public OpDataIndex? DataIndex {{ get; set; }} + private ref OpData opData; + public ref OpData OpData => ref opData; public MemoryOwner InstructionMemory {{ - readonly get + get {{ - if (DataIndex is OpDataIndex odi) - return odi.Data.Memory; + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; else return field; }} private set {{ - if (DataIndex is OpDataIndex odi) + if (!Unsafe.IsNullRef(ref OpData)) {{ - odi.Data.Memory.Dispose(); - odi.Data.Memory = value; + OpData.Memory.Dispose(); + OpData.Memory = value; }} else field = value; }} @@ -303,7 +307,6 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } @@ -311,16 +314,17 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") .AppendLine("{") - .AppendLine("InitializeProperties(index.Data);") - .AppendLine("DataIndex = index;") + .AppendLine("InitializeProperties(ref index.Data);") + .AppendLine("opData = ref index.Data;") .AppendLine("}"); - body2.AppendLine($"public {instruction.OpName}(OpData data)") + body2.AppendLine($"public {instruction.OpName}(ref OpData data)") .AppendLine("{") - .AppendLine("InitializeProperties(data);") + .AppendLine("InitializeProperties(ref data);") + .AppendLine("opData = ref data;") .AppendLine("}"); - body2.AppendLine($"private void InitializeProperties(OpData data)") + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) @@ -384,6 +388,7 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i body3 .AppendLine("UpdateInstructionMemory();") + .AppendLine("opData = ref Unsafe.NullRef();") .AppendLine("}"); // Body 4 @@ -414,24 +419,25 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i body2.AppendLine("}"); builder.AppendLine($@" - public struct {instruction.OpName} : IMemoryInstruction + public ref struct {instruction.OpName} : IMemoryInstruction {{ - public OpDataIndex? DataIndex {{ get; set; }} + private ref OpData opData; + public ref OpData OpData => ref opData; public MemoryOwner InstructionMemory {{ - readonly get + get {{ - if (DataIndex is OpDataIndex odi) - return odi.Data.Memory; + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; else return field; }} private set {{ - if (DataIndex is OpDataIndex odi) + if (!Unsafe.IsNullRef(ref OpData)) {{ - odi.Data.Memory.Dispose(); - odi.Data.Memory = value; + OpData.Memory.Dispose(); + OpData.Memory = value; }} else field = value; }} @@ -443,7 +449,6 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } @@ -454,16 +459,17 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") .AppendLine("{") - .AppendLine("InitializeProperties(index.Data);") - .AppendLine("DataIndex = index;") + .AppendLine("InitializeProperties(ref index.Data);") + .AppendLine("opData = ref index.Data;") .AppendLine("}"); - body2.AppendLine($"public {instruction.OpName}(OpData data)") + body2.AppendLine($"public {instruction.OpName}(ref OpData data)") .AppendLine("{") - .AppendLine("InitializeProperties(data);") + .AppendLine("InitializeProperties(ref data);") + .AppendLine("opData = ref data;") .AppendLine("}"); - body2.AppendLine($"private void InitializeProperties(OpData data)") + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) { @@ -512,9 +518,12 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, } body2.AppendLine("}"); - body3.AppendLine("UpdateInstructionMemory();") + body3 + .AppendLine("UpdateInstructionMemory();") + .AppendLine("opData = ref Unsafe.NullRef();") .AppendLine("}"); + // Body 4 body4.AppendLine("public void UpdateInstructionMemory()") @@ -540,24 +549,25 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, } body2.AppendLine("}"); builder.AppendLine($@" - public struct {instruction.OpName} : IMemoryInstruction + public ref struct {instruction.OpName} : IMemoryInstruction {{ - public OpDataIndex? DataIndex {{ get; set; }} + private ref OpData opData; + public ref OpData OpData => ref opData; public MemoryOwner InstructionMemory {{ - readonly get + get {{ - if (DataIndex is OpDataIndex odi) - return odi.Data.Memory; + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; else return field; }} private set {{ - if (DataIndex is OpDataIndex odi) + if (!Unsafe.IsNullRef(ref OpData)) {{ - odi.Data.Memory.Dispose(); - odi.Data.Memory = value; + OpData.Memory.Dispose(); + OpData.Memory = value; }} else field = value; }} @@ -569,7 +579,6 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); @@ -579,16 +588,17 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i { body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") .AppendLine("{") - .AppendLine("InitializeProperties(index.Data);") - .AppendLine("DataIndex = index;") + .AppendLine("InitializeProperties(ref index.Data);") + .AppendLine("opData = ref index.Data;") .AppendLine("}"); - body2.AppendLine($"public {instruction.OpName}(OpData data)") + body2.AppendLine($"public {instruction.OpName}(ref OpData data)") .AppendLine("{") - .AppendLine("InitializeProperties(data);") + .AppendLine("InitializeProperties(ref data);") + .AppendLine("opData = ref data;") .AppendLine("}"); - body2.AppendLine($"private void InitializeProperties(OpData data)") + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); if (instruction.Operands?.AsList() is List operands) @@ -641,7 +651,9 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); body2.AppendLine("}"); - body3.AppendLine("UpdateInstructionMemory();") + body3 + .AppendLine("UpdateInstructionMemory();") + .AppendLine("opData = ref Unsafe.NullRef();") .AppendLine("}"); // Body 4 @@ -673,25 +685,26 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i builder.AppendLine($@" // {string.Join(", ", instruction.Operands?.AsList().Select(x => $"{x.Name}:{x.Kind}"))} - public struct {instruction.OpName} : IMemoryInstruction + public ref struct {instruction.OpName} : IMemoryInstruction where T : struct, INumber {{ - public OpDataIndex? DataIndex {{ get; set; }} + private ref OpData opData; + public ref OpData OpData => ref opData; public MemoryOwner InstructionMemory {{ - readonly get + get {{ - if (DataIndex is OpDataIndex odi) - return odi.Data.Memory; + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; else return field; }} private set {{ - if (DataIndex is OpDataIndex odi) + if (!Unsafe.IsNullRef(ref OpData)) {{ - odi.Data.Memory.Dispose(); - odi.Data.Memory = value; + OpData.Memory.Dispose(); + OpData.Memory = value; }} else field = value; }} @@ -703,7 +716,6 @@ private set {body4} public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - public static implicit operator {instruction.OpName}(OpData data) => new(data); }} "); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 9d02e985b9..683ed95e3f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -219,7 +219,8 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var shaderSymbol = (ShaderSymbol)types[importStruct.Shader]; if (shaderSymbol is LoadedShaderSymbol loadedShaderSymbol) { - types.Add(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == importStruct.StructName).Type); + var structName = importStruct.StructName; + types.Add(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == structName).Type); } else { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index cc1c927f5a..8c5986f51d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -596,28 +596,22 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) } // Special case: remove duplicates in OpEntryPoint - // TODO: It's a bit ugly but we could make it better later with some syntactic sugar helper if (i.Op == Op.OpEntryPoint && op.Quantifier == OperandQuantifier.ZeroOrMore) { + var entryPoint = new OpEntryPoint(ref i); + var existing = new HashSet(); var target = 0; - for (int index = 0; index < op.Words.Length; ++index) + for (int index = 0; index < entryPoint.Values.Elements.Length; ++index) { - if (existing.Add(op.Words[index])) + if (existing.Add(entryPoint.Values.Elements.Span[index])) { - op.Words[target++] = op.Words[index]; + entryPoint.Values.Elements.Span[target++] = entryPoint.Values.Elements.Span[index]; } } - // Adjust new size - var length = i.Memory.Span[0] >> 16; - length -= op.Words.Length - target; - i.Memory.Span[0] = ((int)i.Memory.Span[0] & 0xFFFF) | (length << 16); - - var tmp = MemoryOwner.Allocate(length); - i.Memory.Span.Slice(0, length).CopyTo(tmp.Span); - i.Memory.Dispose(); - i = new(tmp); + // Slice and reassign to refresh InstructionMemory and size + entryPoint.Values = entryPoint.Values.Slice(0, target); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 471abcc93a..f5890cd2e9 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -88,11 +88,11 @@ public void SetPositionTo(TBlock block, bool beggining = false) public T Insert(in T value) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct => Buffer.Insert(Position++, value); public OpData InsertData(in T value) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct => Buffer.InsertData(Position++, value); [Obsolete("Use the insert method instead")] diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 5444935f1f..34e6c277e4 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -428,16 +428,16 @@ public SpirvValue CompileConstantLiteral(Literal literal) } public OpData Insert(int index, in T value) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct => Buffer.InsertData(index, value); public OpData Add(in T value) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct => Buffer.Add(value); public SpirvContext FluentAdd(in T value, out T result) - where T : struct, IMemoryInstruction + where T : struct, IMemoryInstruction, allows ref struct { Buffer.FluentAdd(value, out result); return this; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 300ded4e03..ff2744f1ef 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -149,8 +149,8 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - var psWrapper = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis); - buffer.FluentAdd(new OpExecutionMode(psWrapper.ResultId, ExecutionMode.OriginUpperLeft)); + var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis); + buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft)); } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages @@ -557,7 +557,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(streams, cbuffers, resourceGroups, resources); } - private OpFunction GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var streams = analysisResult.Streams; @@ -721,7 +721,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); } - return newEntryPointFunction; + return newEntryPointFunction.ResultId; } /// From 2ecbd2b63b25010483f39dffe988c9fbbf039e22 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Dec 2025 12:31:18 +0900 Subject: [PATCH 0653/1182] NewSpirvBuffer: FluentAdd and Insert/InsertData now attach the instruction to the buffer so that further mutation also work --- .../Buffers/NewSpirvBuffer.cs | 16 +++++++++------ .../SPVGenerator.Instructions.cs | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 169b4655d5..38e9e09ba4 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -16,6 +16,7 @@ namespace Stride.Shaders.Spirv.Core.Buffers; public interface IMemoryInstruction { ref OpData OpData { get; } + void Attach(OpDataIndex dataIndex); MemoryOwner InstructionMemory { get; } public void UpdateInstructionMemory(); } @@ -250,22 +251,25 @@ public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : str { result = instruction; Instructions.Add(new(instruction.InstructionMemory)); + instruction.Attach(new(Instructions.Count - 1, this)); UpdateBound(Instructions[^1]); return this; } - public T Insert(int index, in T data) + public T Insert(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct { - Instructions.Insert(index, new(data.InstructionMemory)); - UpdateBound(Instructions[^1]); - return data; + Instructions.Insert(index, new(instruction.InstructionMemory)); + instruction.Attach(new(index, this)); + UpdateBound(Instructions[index]); + return instruction; } - public OpData InsertData(int index, in T data) + public OpData InsertData(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct { - var result = new OpData(data.InstructionMemory); + var result = new OpData(instruction.InstructionMemory); Instructions.Insert(index, result); + instruction.Attach(new(index, this)); UpdateBound(result); return result; } diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index d61bc32590..db5b1fa36b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -163,6 +163,11 @@ static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData inst .AppendLine("opData = ref data;") .AppendLine("}"); + body2.AppendLine($"public void Attach(OpDataIndex index)") + .AppendLine("{") + .AppendLine("opData = ref index.Data;") + .AppendLine("}"); + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); @@ -324,6 +329,11 @@ static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData i .AppendLine("opData = ref data;") .AppendLine("}"); + body2.AppendLine($"public void Attach(OpDataIndex index)") + .AppendLine("{") + .AppendLine("opData = ref index.Data;") + .AppendLine("}"); + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); @@ -469,6 +479,11 @@ static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, .AppendLine("opData = ref data;") .AppendLine("}"); + body2.AppendLine($"public void Attach(OpDataIndex index)") + .AppendLine("{") + .AppendLine("opData = ref index.Data;") + .AppendLine("}"); + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) @@ -598,6 +613,11 @@ static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData i .AppendLine("opData = ref data;") .AppendLine("}"); + body2.AppendLine($"public void Attach(OpDataIndex index)") + .AppendLine("{") + .AppendLine("opData = ref index.Data;") + .AppendLine("}"); + body2.AppendLine($"private void InitializeProperties(ref OpData data)") .AppendLine("{"); From 56fc40235a510d876865e8d6758caa5bc922437c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Dec 2025 14:46:00 +0900 Subject: [PATCH 0654/1182] Effect: added support for generics in compose --- .../SDSL/EffectEvaluator.cs | 23 ++++---- .../Extensions/spirv.sdsl.grammar-ext.json | 14 ++++- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 55 +++++++++++-------- 3 files changed, 58 insertions(+), 34 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index c3386dcf5b..b2bcbbca64 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -18,6 +18,16 @@ internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) public ShaderSource EvaluateEffects(ShaderSource source) { + object[] GetGenericsArguments(NewSpirvBuffer buffer, ReadOnlySpan genericIds) + { + var genericArguments = new object[genericIds.Length]; + for (int i = 0; i < genericArguments.Length; i++) + { + genericArguments[i] = SpirvBuilder.GetConstantValue(genericIds[i], buffer); + } + return genericArguments; + } + switch (source) { case ShaderClassSource classSource: @@ -31,28 +41,21 @@ public ShaderSource EvaluateEffects(ShaderSource source) { if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) { - // Resolve generics - var genericArguments = new object[mixinInstruction.Values.Elements.Length]; - for (int i = 0; i < genericArguments.Length; i++) - { - genericArguments[i] = SpirvBuilder.GetConstantValue(mixinInstruction.Values.Elements.Span[i], buffer); - } - - var instSource = new ShaderClassSource(mixinInstruction.Mixin, genericArguments); + var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(buffer, mixinInstruction.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); Merge(mixinTree, evaluatedSource); } else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) { - var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin); + var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(buffer, mixinComposeInstruction.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); } else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) { - var instSource = new ShaderClassSource(mixinComposeArray.Mixin); + var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(buffer, mixinComposeArray.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 6158f6966b..9b3e511772 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -257,8 +257,13 @@ "name": "identifier" }, { - "kind": "LiteralString", - "name": "mixin" + "kind": "LiteralString", + "name": "mixin" + }, + { + "kind": "IdRef", + "quantifier": "*", + "name": "generics" } ] }, @@ -273,6 +278,11 @@ { "kind": "LiteralString", "name": "mixin" + }, + { + "kind": "IdRef", + "quantifier": "*", + "name": "generics" } ] }, diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index d28b0fbec8..359705f6d0 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL; @@ -29,6 +30,25 @@ public void Compile(SymbolTable table, CompilerUnit compiler) statement.Compile(table, compiler); } } + + internal static int[] CompileGenerics(SymbolTable table, CompilerUnit compiler, ShaderExpressionList? generics) + { + var genericCount = generics != null ? generics.Values.Count : 0; + var genericValues = new int[genericCount]; + if (genericCount > 0) + { + int genericIndex = 0; + foreach (var generic in generics) + { + if (generic is not Literal literal) + throw new InvalidOperationException($"Generic value {generic} is not a literal"); + var compiledValue = generic.Compile(table, compiler); + genericValues[genericIndex++] = compiledValue.Id; + } + } + + return genericValues; + } } public abstract class EffectStatement(TextLocation info) : Node(info) @@ -79,22 +99,9 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) if (mixinName.Path.Count > 0) throw new NotImplementedException(); - var genericCount = mixinName.Generics != null ? mixinName.Generics.Values.Count : 0; - var genericValues = new int[genericCount]; - if (genericCount > 0) - { - int genericIndex = 0; - foreach (var generic in mixinName.Generics) - { - if (generic is not Literal literal) - throw new InvalidOperationException($"Generic value {generic} is not a literal"); - var compiledValue = generic.Compile(table, compiler); - genericValues[genericIndex++] = compiledValue.Id; - } - } - + int[] genericValues = ShaderEffect.CompileGenerics(table, compiler, mixinName.Generics); - compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name, [..genericValues])); + compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name, [.. genericValues])); } } @@ -149,14 +156,14 @@ public abstract class Composable(); public abstract class ComposeValue(TextLocation info) : Node(info) { - public abstract void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator); + public abstract void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator); } public class ComposePathValue(string path, TextLocation info) : ComposeValue(info) { public string Path { get; set; } = path; - public override void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator) + public override void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator) { throw new NotImplementedException(); } @@ -170,18 +177,22 @@ public class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(in { public Mixin Mixin { get; set; } = mixin; - public override void Compile(CompilerUnit compiler, Identifier identifier, AssignOperator @operator) + public override void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator) { - if (Mixin.Generics != null || Mixin.Path.Count > 0) + var (builder, context) = compiler; + + if (Mixin.Path.Count > 0) throw new NotImplementedException(); + var generics = ShaderEffect.CompileGenerics(table, compiler, Mixin.Generics); + switch (@operator) { case AssignOperator.Simple: - compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name)); + compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name, new(generics))); break; case AssignOperator.Plus: - compiler.Builder.Insert(new OpSDSLMixinComposeArray(identifier.Name, Mixin.Name.Name)); + compiler.Builder.Insert(new OpSDSLMixinComposeArray(identifier.Name, Mixin.Name.Name, new(generics))); break; default: throw new ArgumentException(null, nameof(@operator)); @@ -203,7 +214,7 @@ public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue public override void Compile(SymbolTable table, CompilerUnit compiler) { - ComposeValue.Compile(compiler, Identifier, Operator); + ComposeValue.Compile(table, compiler, Identifier, Operator); } From 97669f517332ddfe1a43fe6c44287038522216cf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 26 Dec 2025 15:15:02 +0900 Subject: [PATCH 0655/1182] Fixed generic cbuffer stage items not working (because it was added only once) --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 1d01de79b3..30dd3757e2 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -31,9 +31,19 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource foreach (var mixinToMerge in shaderMixinSource.Mixins) { + var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); + var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge2.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); mixinToMerge2.Buffer = buffer; + // Copy back updated shader name (in case it had generic parameters) + foreach (var i in buffer) + { + if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) + { + mixinToMerge2.ClassName = shaderInstruction.ShaderName; + break; + } + } SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } From 5cd4252464e0f8adaf683dfd5d294a3b59c7350b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 24 Dec 2025 02:22:19 +0900 Subject: [PATCH 0656/1182] Rewrite generic system to properly handle generics inside generics --- .../CompositionGenericsLinkType.sdsl | 52 +++ .../SDSL/RenderTests/GenericInheritance.sdsl | 39 ++ .../SDSL/RenderTests/GenericsArraySize.sdsl | 11 +- .../SDSL/ShaderMixer.CBuffers.cs | 5 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 8 +- .../SDSL/ShaderMixer.cs | 35 +- .../Extensions/spirv.sdsl.grammar-ext.json | 26 +- .../Information/InstructionInfo.Order.cs | 2 +- src/Stride.Shaders/Core/SymbolTypes.cs | 3 +- .../Parsing/SDSL/AST/Literals.cs | 32 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 38 +- .../Spirv/Building/Builder.Class.cs | 351 ++++++++++++++---- src/Stride.Shaders/Spirv/Building/Context.cs | 34 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 96 +++-- 14 files changed, 565 insertions(+), 167 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl create mode 100644 assets/SDSL/RenderTests/GenericInheritance.sdsl diff --git a/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl new file mode 100644 index 0000000000..516ed3f152 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl @@ -0,0 +1,52 @@ +// PSMain(ExpectedResult=#01050304, cbuffer.Test=(TestBase=01,LinkValue1=05, LinkValue2=03, LinkValue3=04)) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float Compute() + { + return 0.0; + } +} + +shader ComputeLink : Compute +{ + cbuffer Test + { + [Link("Link1")] + stage int Test1; + } + + override float Compute() + { + return (float)Test1; + } +} + +shader GenericsLinkType +{ + stream float4 ColorTarget : SV_Target0; + + Compute Comp0; + Compute Comp1; + Compute Comp2; + + cbuffer Test + { + stage int TestBase; + } + + void PSMain() + { + streams.ColorTarget = float4((float)TestBase, Comp0.Compute(), Comp1.Compute(), Comp2.Compute()) / 255.0; + } +} + +effect CompositionGenericLinkType +{ + mixin GenericsLinkType; + mixin compose Comp0 = ComputeLink<"LinkValue1">; + mixin compose Comp1 = ComputeLink<"LinkValue2">; + mixin compose Comp2 = ComputeLink<"LinkValue3">; +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/GenericInheritance.sdsl b/assets/SDSL/RenderTests/GenericInheritance.sdsl new file mode 100644 index 0000000000..653c79d5c2 --- /dev/null +++ b/assets/SDSL/RenderTests/GenericInheritance.sdsl @@ -0,0 +1,39 @@ +// PSMain(ExpectedResult=#02030804, cbuffer.Test=(Test123=02)) + +namespace Stride.Shaders.Tests; + +shader Compute +{ + float4 Compute() + { + return 0.0; + } +} + +shader A : Compute +{ + cbuffer Test + { + [Link(Link1)] + int Test1; + } + + override float4 Compute() + { + return float4(Test1, I1, I2, I3) / 255.0; + } +} + +shader B : A<3, Link2, I, 4> +{ +} + +shader GenericInheritance : B<8, "Test123"> +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + streams.ColorTarget = Compute(); + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/GenericsArraySize.sdsl b/assets/SDSL/RenderTests/GenericsArraySize.sdsl index 615f44430c..2000fb495f 100644 --- a/assets/SDSL/RenderTests/GenericsArraySize.sdsl +++ b/assets/SDSL/RenderTests/GenericsArraySize.sdsl @@ -2,14 +2,17 @@ namespace Stride.Shaders.Tests; -shader GenericsArrayBase +shader GenericsArrayBase2 { - stream float4 ColorTarget : SV_Target0; - cbuffer Test { - int Test2[TArraySizeHalf * 2]; + int Test2[TArraySizeHalf2 * 2]; } +} + +shader GenericsArrayBase : GenericsArrayBase2<1, 2, TArraySizeHalf> +{ + stream float4 ColorTarget : SV_Target0; void PSMain() { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 14724dba9b..68a9646286 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -251,9 +251,10 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) var hasOffsetDecorations = false; foreach (var i in context.GetBuffer()) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructType == structId) + if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructureType == structId) { hasOffsetDecorations = true; + break; } } @@ -272,7 +273,7 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way if (!hasOffsetDecorations) - context.Add(new OpMemberDecorate(context.Types[s], i, ParameterizedFlags.DecorationOffset(offset))); + context.Add(new OpMemberDecorate(structId, i, ParameterizedFlags.DecorationOffset(offset))); offset += memberSize; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 30dd3757e2..e1a95d9725 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -18,7 +18,7 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource shaderSource, ShaderMixinInstantiation? root = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext context, ShaderSource shaderSource, ShaderMixinInstantiation? root = null) { bool isRoot = root == null; var mixinList = new List(); @@ -44,7 +44,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource break; } } - SpirvBuilder.BuildInheritanceList(ShaderLoader, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceList(ShaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } var compositions = new Dictionary(); @@ -82,12 +82,12 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(ShaderSource { var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(value, root ?? result)); + variableCompositions.Add(EvaluateInheritanceAndCompositions(context, value, root ?? result)); compositions[variableName] = [..variableCompositions]; } else { - var variableComposition = EvaluateInheritanceAndCompositions(compositionMixin, root ?? result); + var variableComposition = EvaluateInheritanceAndCompositions(context, compositionMixin, root ?? result); compositions[variableName] = [variableComposition]; } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index c796a8adb2..6f7ee4a33d 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -38,10 +38,14 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect var effectEvaluator = new EffectEvaluator(ShaderLoader); shaderSource = effectEvaluator.EvaluateEffects(shaderSource); - var shaderSource2 = EvaluateInheritanceAndCompositions(shaderSource); + var shaderSource2 = EvaluateInheritanceAndCompositions(context, shaderSource); // Root shader var globalContext = new MixinGlobalContext(); + + // Process name and types imported by constants due to generics instantiation + ShaderClass.ProcessNameAndTypes(context.GetBuffer(), 0, context.GetBuffer().Count, globalContext.Names, globalContext.Types); + var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); @@ -79,8 +83,8 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect bytecode = temp.ToBytecode(); #if DEBUG - File.WriteAllBytes("test.spv", bytecode); - File.WriteAllText("test.spvdis", Spv.Dis(temp)); + //File.WriteAllBytes("test.spv", bytecode); + //File.WriteAllText("test.spvdis", Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif @@ -342,26 +346,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // Specific type instructions in context gets deduplicated before adding bool addToContext = false; - if ( - // Types - i2.Op == Op.OpTypeVoid - || i2.Op == Op.OpTypeInt - || i2.Op == Op.OpTypeFloat - || i2.Op == Op.OpTypeBool - || i2.Op == Op.OpTypeVector - || i2.Op == Op.OpTypeMatrix - || i2.Op == Op.OpTypeArray - || i2.Op == Op.OpTypeRuntimeArray - || i2.Op == Op.OpTypePointer - || i2.Op == Op.OpTypeFunction - || i2.Op == Op.OpTypeFunctionSDSL - || i2.Op == Op.OpTypeImage - || i2.Op == Op.OpTypeSampler - || i2.Op == Op.OpTypeGenericSDSL - || i2.Op == Op.OpSDSLImportShader - || i2.Op == Op.OpSDSLImportVariable - || i2.Op == Op.OpSDSLImportFunction - || i2.Op == Op.OpSDSLImportStruct) + if (TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i2.Op)) { // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) if (i2.Op == Op.OpSDSLImportStruct && new OpSDSLImportStruct(ref i2) is { } importStruct) @@ -381,8 +366,8 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS { if (i2.IdResult is int id) { - remapIds.Add(id, existingInstruction.IdResult.Value); - removedIds.Add(existingInstruction.IdResult.Value); + remapIds.Add(id, existingInstruction.Data.IdResult.Value); + removedIds.Add(existingInstruction.Data.IdResult.Value); } } else diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 9b3e511772..e5d4aa05eb 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -291,7 +291,31 @@ "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, - { "kind": "IdResult" } + { "kind": "IdResult" }, + { + "kind": "LiteralInteger", + "name": "index" + }, + { + "kind": "LiteralString", + "name": "declaringClass" + } + ] + }, + { + "opname": "OpSDSLGenericReference", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { + "kind": "LiteralInteger", + "name": "index" + }, + { + "kind": "LiteralString", + "name": "declaringClass" + } ] }, { diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 98a35fde6b..62921afa3d 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -66,7 +66,7 @@ void InitOrder() OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x.ToString().StartsWith("OpSDSLImport") || x == Op.OpSDSLGenericParameter)) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x.ToString().StartsWith("OpSDSLImport") || x == Op.OpSDSLGenericParameter || x == Op.OpSDSLGenericReference)) OrderGroup[(e, null)] = group; group++; diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 53380a9d98..6a1f30712a 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -116,7 +117,7 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// /// The base type for the array. /// The size of the array. If -1, it means size is not defined, such as using []. -public sealed record ArrayType(SymbolType BaseType, int Size, int? SizeExpressionId = null) : SymbolType() +public sealed record ArrayType(SymbolType BaseType, int Size, (int Id, NewSpirvBuffer Buffer)? SizeExpression = null) : SymbolType() { public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ffb1bc8e25..0232429b24 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -259,10 +259,10 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile, buffer); + classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { - table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, table.InheritedShaders[i]); + table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); } @@ -421,19 +421,27 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh if (IsArray) { - foreach (var arraySize in ArraySize) + var fullTypeName = GenerateTypeName(includeGenerics: true, includeArray: true); + + var arraySymbolType = symbolType; + if (!table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) { - if (arraySize is EmptyExpression) - symbolType = new ArrayType(symbolType, -1); - else + foreach (var arraySize in ArraySize) { - var arrayComputedSize = -1; - if (arraySize is IntegerLiteral i) - arrayComputedSize = (int)i.Value; - - var constantArraySize = arraySize.CompileConstantValue(table, context); - symbolType = new ArrayType(symbolType, arrayComputedSize, constantArraySize.Id); + if (arraySize is EmptyExpression) + arraySymbolType = new ArrayType(arraySymbolType, -1); + else + { + var arrayComputedSize = -1; + if (arraySize is IntegerLiteral i) + arrayComputedSize = (int)i.Value; + + var constantArraySize = arraySize.CompileConstantValue(table, context); + arraySymbolType = new ArrayType(arraySymbolType, arrayComputedSize, (constantArraySize.Id, context.GetBuffer())); + } } + + table.DeclaredTypes.Add(fullTypeName, symbolType = arraySymbolType); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 683ed95e3f..9f7f725ddd 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -144,13 +144,15 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = types[typeArray.ElementType]; - if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, buffer)) + if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, buffer, false)) { - types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject, typeArray.Length)); + types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); } else { - types.Add(typeArray.ResultId, new ArrayType(innerType, -1, typeArray.Length)); + // Constant can't be computed; we need to save aside all opcodes + var bufferForConstant = SpirvBuilder.ExtractConstantAsSpirvBuffer(buffer, typeArray.Length); + types.Add(typeArray.ResultId, new ArrayType(innerType, -1, (typeArray.Length, bufferForConstant))); } } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) @@ -246,17 +248,17 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } } - public class ShaderImporter(SymbolTable table) : IShaderImporter + public class ShaderImporter(SymbolTable table, SpirvContext context) : IShaderImporter { public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) { - return LoadAndCacheExternalShaderType(table, classSource, buffer); + return LoadAndCacheExternalShaderType(table, context, classSource, buffer); } } - private static LoadedShaderSymbol CreateShaderType(SymbolTable table, NewSpirvBuffer buffer, ShaderClassInstantiation classSource) + private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, ShaderClassInstantiation classSource) { - ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types, new ShaderImporter(table)); + ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types, new ShaderImporter(table, context)); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); @@ -327,7 +329,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); - context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound)); + context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, i, Name.Name)); context.AddName(context.Bound, genericParameter.Name); table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); @@ -371,13 +373,13 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); - SpirvBuilder.BuildInheritanceList(table.ShaderLoader, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile, context.GetBuffer()); + SpirvBuilder.BuildInheritanceList(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile); } var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { - shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderType(table, mixin)); + shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderType(table, context, mixin)); } foreach (var shaderType in shaderSymbols) @@ -411,9 +413,9 @@ public void Compile(SymbolTable table, CompilerUnit compiler) if (svar.TypeName.Name.Contains("<")) throw new NotImplementedException("Can't have member variables with generic shader types"); var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context.GetBuffer()); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context); classSource.Buffer = shader; - var shaderType = LoadAndCacheExternalShaderType(table, classSource, context.GetBuffer()); + var shaderType = LoadAndCacheExternalShaderType(table, context, classSource); // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) memberType = svar.TypeName.ResolveType(table, context); @@ -528,7 +530,7 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader context.Add(new OpSDSLMixinInherit(shaderId)); } - public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) + public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { // Already processed? if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) @@ -537,11 +539,11 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl if (classSource.Buffer == null) throw new InvalidOperationException($"{nameof(classSource)}.{nameof(classSource.Buffer)} need to be set"); - var shaderType = LoadExternalShaderType(table, classSource); + var shaderType = LoadExternalShaderType(table, context, classSource); return shaderType; } - public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource, NewSpirvBuffer parentBuffer) + public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, NewSpirvBuffer parentBuffer) { // Already processed? if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) @@ -552,15 +554,15 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, parentBuffer); classSource.Buffer = shader; } - var shaderType = LoadExternalShaderType(table, classSource); + var shaderType = LoadExternalShaderType(table, context, classSource); return shaderType; } - public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, ShaderClassInstantiation classSource) + public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { var shaderBuffer = classSource.Buffer; - var shaderType = CreateShaderType(table, shaderBuffer, classSource); + var shaderType = CreateShaderType(table, context, shaderBuffer, classSource); RegisterShaderType(table, shaderType); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 8c5986f51d..407f198881 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -5,6 +5,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; using System.Collections.Generic; @@ -82,12 +83,17 @@ public override int GetHashCode() public partial class SpirvBuilder { - private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) + private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping var shaderMapping = new Dictionary(); + var genericParameterRemapping = new Dictionary(); foreach (var i in buffer) { + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + { + genericParameterRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericParameter.Index]); + } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { var shaderClassSource = ConvertToShaderClassSource(buffer, 0, buffer.Count, importShader); @@ -96,13 +102,35 @@ private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoade } } + int RemapGenericParameter(int localGeneric) + { + if (genericParameterRemapping.TryGetValue(localGeneric, out var generic)) + return generic; + + // Otherwise, assume it's a constsant we need to import + var constantBuffer = ExtractConstantAsSpirvBuffer(buffer, localGeneric); + int index = context.GetBuffer().Count; + var bound = context.Bound; + var resultId = InsertBufferWithoutDuplicates(context.GetBuffer(), ref index, ref bound, null, constantBuffer); + context.Bound = bound; + + return resultId; + } + // Check inheritance foreach (var i in buffer) { if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { var shaderName = shaderMapping[inherit.Shader]; - BuildInheritanceList(shaderLoader, shaderName, macros, inheritanceList, resolveStep, buffer); + + // Remap/import generics + var remappedGenericArguments = shaderName.GenericArguments.ToArray(); + for (int index = 0; index < remappedGenericArguments.Length; index++) + remappedGenericArguments[index] = RemapGenericParameter(remappedGenericArguments[index]); + + var remappedShaderName = shaderName with { GenericArguments = remappedGenericArguments }; + BuildInheritanceList(shaderLoader, context, remappedShaderName, macros, inheritanceList, resolveStep); } } } @@ -112,7 +140,7 @@ public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); } - public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep, NewSpirvBuffer? parentBuffer = null) + public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep) { // TODO: cache same instantiations within context? var index = inheritanceList.IndexOf(classSource); @@ -120,7 +148,7 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade { if (classSource.Buffer == null) { - var shader = GetOrLoadShader(shaderLoader, classSource, macros, resolveStep, parentBuffer); + var shader = GetOrLoadShader(shaderLoader, classSource, macros, resolveStep, context); classSource.Buffer = shader; } @@ -128,7 +156,7 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade index = inheritanceList.IndexOf(classSource); if (index == -1) { - BuildInheritanceListHelper(shaderLoader, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); + BuildInheritanceListHelper(shaderLoader, context, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); index = inheritanceList.Count; inheritanceList.Add(classSource); } @@ -150,38 +178,40 @@ public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) { if (buffer.TryGetInstructionById(constantId, out var constant)) { - return GetConstantValue(constant, buffer); + return ResolveConstantValue(constant, buffer); } throw new Exception("Cannot find constant instruction for id " + constantId); } - public static bool TryGetConstantValue(int constantId, out object value, NewSpirvBuffer buffer) + public static bool TryGetConstantValue(int constantId, out object value, out int typeId, NewSpirvBuffer buffer, bool simplifyInBuffer = false) { if (buffer.TryGetInstructionById(constantId, out var constant)) { - return TryGetConstantValue(constant, out value, buffer); + return TryGetConstantValue(constant, out value, out typeId, buffer, simplifyInBuffer); } + typeId = default; value = default; return false; } - public static object GetConstantValue(OpDataIndex i, NewSpirvBuffer buffer) + public static object ResolveConstantValue(OpDataIndex i, NewSpirvBuffer buffer) { - if (!TryGetConstantValue(i, out var value, buffer)) + if (!TryGetConstantValue(i, out var value, out _, buffer, false)) throw new InvalidOperationException($"Can't process constant {i.Data.IdResult}"); return value; } // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. - public static bool TryGetConstantValue(OpDataIndex i, out object value, NewSpirvBuffer buffer) + public static bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, NewSpirvBuffer buffer, bool simplifyInBuffer = false) { + typeId = default; value = default; // Check for unresolved values - if (i.Op == Op.OpSDSLGenericParameter) + if (i.Op == Op.OpSDSLGenericParameter || i.Op == Op.OpSDSLGenericReference) { return false; } @@ -195,22 +225,28 @@ public static bool TryGetConstantValue(OpDataIndex i, out object value, NewSpirv if (i.Op == Op.OpSpecConstantOp) { + var resultType = i.Data.Memory.Span[1]; + var resultId = i.Data.Memory.Span[2]; var op = (Op)i.Data.Memory.Span[3]; switch (op) { case Op.OpIMul: - if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, buffer)) + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, out var leftTypeId, buffer)) return false; - if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, buffer)) + if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, out var rightTypeId, buffer)) + return false; + if (leftTypeId != resultType || rightTypeId != resultType) return false; value = (int)left * (int)right; + if (simplifyInBuffer) + buffer.Replace(i.Index, new OpConstant(resultType, resultId, (int)value)); return true; default: throw new NotImplementedException(); } } - int typeId = i.Op switch + typeId = i.Op switch { Op.OpConstant or Op.OpSpecConstant => i.Data.Memory.Span[1], }; @@ -248,18 +284,123 @@ public static bool TryGetConstantValue(OpDataIndex i, out object value, NewSpirv throw new Exception("Cannot find type instruction for id " + typeId); } - record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, int Index, string Name, bool Resolved, object Value); + public static NewSpirvBuffer ExtractConstantAsSpirvBuffer(NewSpirvBuffer buffer, int constantId) + { + // First, run a simplification pass + // TODO: separate simplification from computing value? + TryGetConstantValue(constantId, out _, out _, buffer, true); + + // Go backward and find any reference + var newBuffer = new NewSpirvBuffer(); + var referenced = new HashSet { constantId }; + var instructions = new List(); + for (int index = buffer.Count - 1; index >= 0; --index) + { + var i = buffer[index]; + if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) + { + var i2 = new OpData(i.Data.Memory.Span); + + // Then add IdRef operands to next requested instructions or types + foreach (var op in i2) + { + if (op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefIdRef) + { + foreach (ref var word in op.Words) + { + referenced.Add(word); + } + } + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefLiteralInteger) + { + throw new NotImplementedException(); + } + } + + instructions.Add(i2); + } + } + + // Since we went backward, reverse the list + instructions.Reverse(); + foreach (var i in instructions) + newBuffer.Add(i); + return newBuffer; + } + + record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, int Index, string Name, bool Resolved, string Value); abstract class GenericResolver { public abstract bool NeedsResolve(); + public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value); + public abstract bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue); public virtual void PostProcess(string classNameWithGenerics, List genericParameters) { } } + public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int instructionIndex, ref int bound, int? desiredResultId, NewSpirvBuffer source) + { + // Import in current buffer (without duplicate) + var typeDuplicateInserter = new TypeDuplicateHelper(target); + var remapIds = new Dictionary(); + int lastResultId = -1; + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + RemapIds(remapIds, ref i.Data); + + //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() + var isGenericReference = i.Op == Op.OpSDSLGenericReference; + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; + + // Note: we also try to avoid duplciate for constants (which should have been resolved) + // otherwise a generic type might have 2 different instantiation with same parameters + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) + && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData)) + { + // Make sure this data is declared at current index, otherwise move it. + // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops + if (existingData.Index > instructionIndex) + { + var existingDataCopy = new OpData(existingData.Data.Memory); + typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); + existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); + } + remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); + lastResultId = existingData.Data.IdResult.Value; + } + else + { + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericReference; + + // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID + var resultId = index == source.Count - 1 && desiredResultId != null + ? desiredResultId.Value + : bound++; + + remapIds.Add(i.Data.IdResult.Value, resultId); + i.Data.IdResult = resultId; + typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + + lastResultId = resultId; + } + } + + return lastResultId; + } + + /// + /// Instantiate generics using string values (they will be imported in the generic shader being specialized). + /// class GenericResolverFromValues(string[]? genericValues) : GenericResolver { public override bool NeedsResolve() => genericValues != null && genericValues.Length > 0; @@ -285,30 +426,114 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str throw new NotImplementedException(); } } + + public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue) + { + var genericParameter = (OpSDSLGenericParameter)buffer[instructionIndex]; + var genericValue = genericValues![genericIndex]; + textValue = genericValue; + switch (genericParameterType) + { + case ScalarType { TypeName: "int" }: + buffer.Replace(instructionIndex, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, int.Parse(genericValue))); + return true; + case ScalarType { TypeName: "float" }: + buffer.Replace(instructionIndex, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, float.Parse(genericValue))); + return true; + case ScalarType { TypeName: "bool" }: + if (bool.Parse(genericValue)) + buffer.Replace(instructionIndex, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); + else + buffer.Replace(instructionIndex, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); + return true; + case GenericParameterType g: + buffer.Replace(instructionIndex, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + return true; + default: + throw new NotImplementedException(); + } + } } - class GenericResolverFromClassInstantiation(ShaderClassInstantiation classSource, NewSpirvBuffer instantiatingBuffer, ResolveStep resolveStep) : GenericResolver + /// + /// Instantiate generics using another buffer for the shader constants. If a context is specified, constants will be imported there, otherwise inside the generic shader being instantiated. + /// + class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) : GenericResolver { private Dictionary names; public override bool NeedsResolve() => classSource.GenericArguments.Length > 0; + private string GetIdRefAsString(int index) + { + if (names == null) + ShaderClass.ProcessNameAndTypes(declaringBuffer, 0, declaringBuffer.Count, out names, out _); + + return names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) + ? $"%{genericArgumentName}[{classSource.GenericArguments[index]}]" + : $"%{classSource.GenericArguments[index]}"; + } + public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) { - if (!TryGetConstantValue(classSource.GenericArguments[index], out value, instantiatingBuffer)) + if (!TryGetConstantValue(classSource.GenericArguments[index], out value, out _, declaringBuffer, false)) { - if (names == null) - ShaderClass.ProcessNameAndTypes(instantiatingBuffer, 0, instantiatingBuffer.Count, out names, out _); - - value = names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) - ? $"%{genericArgumentName}[{classSource.GenericArguments[index]}]" - : $"%{classSource.GenericArguments[index]}"; + value = GetIdRefAsString(index); return false; } return true; } + public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue) + { + // Check if generic value can already be computed (no OpSDSLGenericParameter and such) + if (TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, declaringBuffer, false)) + { + // TODO: shortcut: store it right away and finish here + textValue = constantValue.ToString(); + } + else + { + textValue = GetIdRefAsString(genericIndex); + } + + var genericParameter = (OpSDSLGenericParameter)buffer[instructionIndex]; + var bufferWithConstant = ExtractConstantAsSpirvBuffer(declaringBuffer, classSource.GenericArguments[genericIndex]); + + bool resolved = true; + + // Remap OpSDSLGenericParameter to OpSDSLGenericReference + for (int index = 0; index < bufferWithConstant.Count; ++index) + { + var i = bufferWithConstant[index]; + + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter2) + { + bufferWithConstant.Replace(index, new OpSDSLGenericReference(genericParameter2.ResultType, genericParameter2.ResultId, genericParameter2.Index, genericParameter2.DeclaringClass)); + resolved = false; + } + } + + buffer.RemoveAt(instructionIndex); + + // TODO: Try to simplify constant + var bound = buffer.Header.Bound; + int resultId = InsertBufferWithoutDuplicates(buffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); + buffer.Header = buffer.Header with { Bound = bound }; + + if (resultId != genericParameter.ResultId) + { + // Need to remap all existing references + RemapIds(buffer, 0, buffer.Count, new Dictionary { { genericParameter.ResultId, resultId } }); + } + + // Since we removed one instruction earlier, adjust for it so that next loop process just after what has just been added + instructionIndex--; + + return true; + } + public override void PostProcess(string classNameWithGenerics, List genericParameters) { // Fully resolved? @@ -327,25 +552,44 @@ public override void PostProcess(string classNameWithGenerics, List macros) { ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); - var bound = shader.Header.Bound; - var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); var genericParameters = new List(); - foreach (var i in shader) + for (int index = 0; index < shader.Count; ++index) { + var i = shader[index]; + if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { var genericParameterType = types[genericParameter.ResultType]; var genericParameterName = names[genericParameter.ResultId]; - var resolved = genericResolver.TryResolveGenericValue(genericParameterType, genericParameterName, genericParameters.Count, out var genericValue); - genericParameters.Add(new(genericParameterType, genericParameter.ResultId, genericParameter.ResultType, i.Index, genericParameterName, resolved, genericValue)); + var resolved = genericResolver.ResolveGenericValueInBuffer(genericParameterType, genericParameterName, genericParameters.Count, shader, ref index, out var textValue); + genericParameters.Add(new(genericParameterType, genericParameter.ResultId, genericParameter.ResultType, i.Index, genericParameterName, resolved, textValue)); + + switch (genericParameterType) + { + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: + resolvedLinks.Add(genericParameter.ResultId, textValue); + break; + case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: + semantics.Add(names[genericParameter.ResultId], textValue); + break; + } + } + + if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) + { + // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant) + if (!TryGetInstructionById(typeArray.Length, out var lengthInstruction, shader)) + throw new InvalidOperationException(); + if (lengthInstruction.Op != Op.OpConstant && TryGetConstantValue(typeArray.Length, out var value, out _, shader, true)) + { + } } } @@ -361,39 +605,6 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class if (i > 0) classNameWithGenericsBuilder.Append(","); classNameWithGenericsBuilder.Append(genericParameter.Value.ToString()); - - if (!genericParameter.Resolved) - continue; - - switch (genericParameter.Type) - { - case ScalarType { TypeName: "int" }: - shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, (int)genericParameter.Value)); - break; - case ScalarType { TypeName: "float" }: - shader.Replace(index, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, (float)genericParameter.Value)); - break; - case ScalarType { TypeName: "bool" }: - if ((bool)genericParameter.Value) - shader.Replace(index, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); - else - shader.Replace(index, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); - break; - case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: - shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, (string)genericParameter.Value)); - resolvedLinks.Add(genericParameter.ResultId, (string)genericParameter.Value); - break; - case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: - shader.Replace(index, new OpConstantStringSDSL(genericParameter.ResultId, (string)genericParameter.Value)); - semantics.Add(names[genericParameter.ResultId], (string)genericParameter.Value); - break; - case GenericParameterType g when g.Kind is GenericParameterKindSDSL.MemberNameResolved: - // There should be no more reference to this MemberName (it should have been resolved during InstantiateMemberNames()) - shader.Replace(index, new OpNop()); - break; - default: - throw new NotImplementedException(); - } } classNameWithGenericsBuilder.Append(">"); var classNameWithGenerics = classNameWithGenericsBuilder.ToString(); @@ -409,9 +620,6 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class TransformResolvedSemantics(shader, semantics); TransformResolvedLinkIdIntoLinkString(shader, resolvedLinks); - // In case we had to increase bound (new instructions), update header - shader.Header = shader.Header with { Bound = bound }; - genericResolver.PostProcess(classNameWithGenerics, genericParameters); } @@ -643,9 +851,14 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) /// /// /// - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer parentBuffer) + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, SpirvContext context) + { + return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context.GetBuffer()), macros); + } + + public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) { - return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromClassInstantiation(classSource, parentBuffer, resolveStep), macros); + return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, declaringBuffer), macros); } public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) @@ -669,7 +882,7 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader shader = CopyShader(shader); InstantiateGenericShader(shader, className, genericResolver, shaderLoader, macros); - //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shader; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 34e6c277e4..0cad5cc8ec 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -157,8 +157,8 @@ public int GetOrRegister(SymbolType? type) }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, - ArrayType a when a.Size != -1 || a.SizeExpressionId != null => RegisterArrayType(a), - ArrayType a when a.Size == -1 && a.SizeExpressionId == null => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, + ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), + ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f), PointerType p => RegisterPointerType(p), @@ -182,9 +182,33 @@ public int GetOrRegister(SymbolType? type) private int? RegisterArrayType(ArrayType a) { - var sizeId = a.Size != -1 - ? CompileConstant((int)a.Size).Id - : a.SizeExpressionId ?? throw new InvalidOperationException(); + int sizeId; + if (a.Size != -1) + { + sizeId = CompileConstant((int)a.Size).Id; + } + else if (a.SizeExpression is { } sizeExpression) + { + // Import constants + var importBuffer = sizeExpression.Buffer; + if (importBuffer != Buffer) + { + var index = Buffer.Count; + var bound = Bound; + var resultId = SpirvBuilder.InsertBufferWithoutDuplicates(Buffer, ref index, ref bound, null, importBuffer); + Bound = bound; + + sizeId = resultId; + } + else + { + sizeId = sizeExpression.Id; + } + } + else + { + throw new InvalidOperationException(); + } return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index ab272b42c7..c1617b9889 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -47,10 +47,7 @@ record struct InstructionSortHelper(Op Op, int Index, OpData Data) { public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } - // If it's a fake instruction for OpName/OpMember, we can also use Target instead of Memory.Span[1] - public int? TargetOverride { get; init; } - - public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Target:{TargetOverride}"; + public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Index: {Index}"; } class OperationComparer(NewSpirvBuffer Buffer, bool UseIndices) : IComparer @@ -80,35 +77,44 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return 1; } - // Only for OpName and OpMember + // Only for OpName and OpMember: we sort by target + // Note: RemapOp earlier made sure we sort first per Target then OpCode, i.e.: + // OpName %3 "Test" + // OpDecorate %3 .... + // OpName %4 "Test2" if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { - // Use TargetOverride if defined, otherwise Memory.Span[1] (where target would be stored) - comparison = (x.TargetOverride ?? x.Data.Memory.Span[1]).CompareTo(y.TargetOverride ?? y.Data.Memory.Span[1]); + comparison = (x.Data.Memory.Span[1]).CompareTo(y.Data.Memory.Span[1]); if (comparison != 0) return comparison; } // Only process types that we care about - if (x.Op == Op.OpTypeVoid || x.Op == Op.OpTypeInt || x.Op == Op.OpTypeFloat || x.Op == Op.OpTypeBool - || x.Op == Op.OpTypeVector || x.Op == Op.OpTypeMatrix || x.Op == Op.OpTypePointer || x.Op == Op.OpTypeFunction || x.Op == Op.OpTypeFunctionSDSL - || x.Op == Op.OpTypeRuntimeArray - || x.Op == Op.OpTypeImage || x.Op == Op.OpTypeSampler - || x.Op == Op.OpTypeGenericSDSL - || x.Op == Op.OpSDSLImportShader || x.Op == Op.OpSDSLImportFunction || x.Op == Op.OpSDSLImportVariable || x.Op == Op.OpSDSLImportStruct) + // For arrays, we have some additional checks: same name and member info + if (x.Op == Op.OpTypeArray) { - comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); + comparison = x.Data.Memory.Span[2].CompareTo(y.Data.Memory.Span[2]); + if (comparison != 0) + return comparison; + + comparison = CompareIntConstant(Buffer, x.Data.Memory.Span[3], y.Data.Memory.Span[3]); if (comparison != 0) return comparison; } - // For arrays, we have some additional checks: same name and member info - else if (x.Op == Op.OpTypeArray) + // Standard ResultType/ResultId instructions: ignore ResultId (Span[2]) and compare the rest + else if (x.Op == Op.OpSDSLGenericParameter) { - comparison = x.Data.Memory.Span[2].CompareTo(y.Data.Memory.Span[2]); + comparison = x.Data.Memory.Span[1].CompareTo(y.Data.Memory.Span[1]); if (comparison != 0) return comparison; - comparison = CompareIntConstant(Buffer, x.Data.Memory.Span[3], y.Data.Memory.Span[3]); + comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[3..], y.Data.Memory.Span[3..]); + if (comparison != 0) + return comparison; + } + else if (OpCheckDuplicateForTypesAndImport(x.Op) || OpCheckDuplicateForConstant(x.Op)) + { + comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) return comparison; } @@ -134,8 +140,8 @@ private static int CompareIntConstant(NewSpirvBuffer buffer, int id1, int id2) if (id1 == id2) return 0; - var value1Success = SpirvBuilder.TryGetConstantValue(id1, out var value1, buffer); - var value2Success = SpirvBuilder.TryGetConstantValue(id2, out var value2, buffer); + var value1Success = SpirvBuilder.TryGetConstantValue(id1, out var value1, out _, buffer, false); + var value2Success = SpirvBuilder.TryGetConstantValue(id2, out var value2, out _, buffer, false); return (value1Success, value2Success) switch { @@ -173,9 +179,9 @@ public TypeDuplicateHelper(NewSpirvBuffer buffer) comparerInsert = new OperationComparer(buffer, false); } - public void InsertInstruction(int index, OpData data) + public OpDataIndex InsertInstruction(int index, OpData data) { - buffer.Insert(index, data); + var result = buffer.Insert(index, data); // Adjust indices var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); @@ -201,6 +207,8 @@ public void InsertInstruction(int index, OpData data) if (sortedInsertionIndex >= 0) throw new InvalidOperationException(); targetList.Insert(~sortedInsertionIndex, newItem); + + return result; } public void RemoveInstructionAt(int index, bool dispose) @@ -251,17 +259,55 @@ private List GetSortedNames() return namesByOp; } - public bool CheckForDuplicates(OpData data, out OpData foundData) + public static bool OpCheckDuplicateForTypesAndImport(Op op) + { + return op == Op.OpTypeVoid + || op == Op.OpTypeInt + || op == Op.OpTypeFloat + || op == Op.OpTypeBool + || op == Op.OpTypeVector + || op == Op.OpTypeMatrix + || op == Op.OpTypeArray + || op == Op.OpTypeRuntimeArray + || op == Op.OpTypePointer + || op == Op.OpTypeFunction + || op == Op.OpTypeFunctionSDSL + || op == Op.OpTypeImage + || op == Op.OpTypeSampler + || op == Op.OpTypeGenericSDSL + || op == Op.OpSDSLImportShader + || op == Op.OpSDSLImportVariable + || op == Op.OpSDSLImportFunction + || op == Op.OpSDSLImportStruct; + } + + public static bool OpCheckDuplicateForConstant(Op op) + { + return op == Op.OpConstant + || op == Op.OpConstantTrue + || op == Op.OpConstantFalse + || op == Op.OpConstantNull + || op == Op.OpConstantSampler + || op == Op.OpConstantComposite + || op == Op.OpConstantStringSDSL + || op == Op.OpSpecConstant + || op == Op.OpSpecConstantComposite + || op == Op.OpSpecConstantTrue + || op == Op.OpSpecConstantFalse + || op == Op.OpSpecConstantOp; + } + + public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) { var index = instructionsByOp.BinarySearch(new InstructionSortHelper { Op = data.Op, Index = -1, Data = data }, comparerInsert); if (index >= 0) { - foundData = instructionsByOp[index].Data; + foundData = new(instructionsByOp[index].Index, buffer); return true; } - foundData = data; + foundData = default; return false; } From a577005806828e0c9f43fa86a3d413b04acce557 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 02:21:28 +0900 Subject: [PATCH 0657/1182] Added support for array initializers --- assets/SDSL/RenderTests/Literals.sdsl | 41 +++++++ .../Parsing/SDSL/AST/Literals.cs | 108 ++++++++++++------ .../Parsing/SDSL/AST/Statements.cs | 18 ++- 3 files changed, 127 insertions(+), 40 deletions(-) create mode 100644 assets/SDSL/RenderTests/Literals.sdsl diff --git a/assets/SDSL/RenderTests/Literals.sdsl b/assets/SDSL/RenderTests/Literals.sdsl new file mode 100644 index 0000000000..7ad6a346cc --- /dev/null +++ b/assets/SDSL/RenderTests/Literals.sdsl @@ -0,0 +1,41 @@ +// PSMain(ExpectedResult=#00FF0000, cbuffer.Test=(Test1=0)) +// PSMain(ExpectedResult=#0000FF00, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#FF00FF00, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#FF000000, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#FFFFFF00, cbuffer.Test=(Test1=4)) +// PSMain(ExpectedResult=#090A0B0C, cbuffer.Test=(Test1=6)) + +namespace Stride.Shaders.Tests; + +shader Literals +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + streams.ColorTarget = float4(0.0, 0.0, 0.0, 0.0); + if (Test1 >= 0 && Test1 <= 4) + { + static const float4 colors[5] = { float4(0,1,0,0), float4(0,0,1,0), float4(1,0,1,0), float4(1,0,0,0), float4(1,1,1,0)}; + streams.ColorTarget = colors[Test1]; + } + // TODO + //else if (Test1 == 5) + //{ + // // we will need to forward expected type in AST child to do this one well + // //float4x4 m = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + // float4x4 m = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 }; + // streams.ColorTarget = m[2] / 255.0; + //} + else if (Test1 == 6) + { + float4x4 m = float4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16); + streams.ColorTarget = m[2] / 255.0; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 0232429b24..2a12cedf71 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -132,18 +132,26 @@ public bool IsConstant() return true; } - public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context); + public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues); public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - Type = GenerateType(table, context); + var sourceValues = new (SpirvValue Value, SymbolType Type)[Values.Count]; + for (int i = 0; i < sourceValues.Length; ++i) + { + var sourceValue = Values[i].CompileAsValue(table, compiler); + sourceValues[i] = (sourceValue, Values[i].ValueType); + } + + Type = GenerateType(table, context, sourceValues); (var compositeCount, var totalCount) = Type switch { VectorType v => (v.Size, v.Size), MatrixType m => (m.Rows, m.Columns * m.Rows), + ArrayType t => (t.Size, t.Size), }; Span values = stackalloc int[totalCount]; @@ -152,26 +160,33 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Note: There are a lot of opportunity to optimize by working with vector-to-vector copy (if they align correctly) and/or OpVectorShuffle, but it can get quite complex to handle all cases // However, it is probably optimized by SPIRV-Cross or the compiler/driver, so maybe not worth optimzing (due to increased code cases/complexity) var elementIndex = 0; - foreach (var sourceValue in Values) + foreach (var sourceValue in sourceValues) { - var value = sourceValue.CompileAsValue(table, compiler); - var valueType = sourceValue.ValueType; + var value = sourceValue.Value; + var valueType = sourceValue.Type; // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) - var elementType = valueType.GetElementType(); - for (int i = 0; i < valueType.GetElementCount(); ++i) + if (Type is ScalarType or VectorType or MatrixType) { - SpirvValue extractedValue = valueType switch + var elementType = valueType.GetElementType(); + for (int i = 0; i < valueType.GetElementCount(); ++i) { - MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i / m.Rows, i % m.Rows]))), - VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i]))), - ScalarType s => value, - }; - // If too many elments, keep counting so that exception is still thrown a bit later, with total count - var currentElementIndex = elementIndex++; - if (currentElementIndex >= values.Length) - continue; - values[currentElementIndex] = builder.Convert(context, extractedValue, elementType).Id; + SpirvValue extractedValue = valueType switch + { + MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i / m.Rows, i % m.Rows]))), + VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i]))), + ScalarType s => value, + }; + // If too many elments, keep counting so that exception is still thrown a bit later, with total count + var currentElementIndex = elementIndex++; + if (currentElementIndex >= values.Length) + continue; + values[currentElementIndex] = builder.Convert(context, extractedValue, elementType).Id; + } + } + else if (Type is ArrayType arrayType) + { + values[elementIndex++] = builder.Convert(context, value, arrayType.BaseType).Id; } } @@ -186,6 +201,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { MatrixType m => builder.Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m.BaseType, compositeSize)), context.Bound++, [.. values.Slice(i * compositeSize, compositeSize)])).ResultId, VectorType v => values[i], + ArrayType => values[i], }; } @@ -197,7 +213,7 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context) => TypeName.ResolveType(table, context); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) => TypeName.ResolveType(table, context); public override string ToString() { @@ -212,7 +228,7 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context) => TypeName.ResolveType(table, context); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) => TypeName.ResolveType(table, context); public override string ToString() { @@ -222,9 +238,19 @@ public override string ToString() public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { - public override SymbolType GenerateType(SymbolTable table, SpirvContext context) + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) { - throw new NotImplementedException(); + // We might be able to remove those exceptions by having better type inference (checking assigned variable) + if (sourceValues.Length == 0) + throw new NotImplementedException("Array needs at least one element"); + + for (int i = 1; i < sourceValues.Length; ++i) + { + if (sourceValues[i].Type != sourceValues[0].Type) + throw new NotImplementedException("Arrays expect same type for all elements"); + } + + return new ArrayType(sourceValues[0].Type, sourceValues.Length); } public override string ToString() @@ -426,20 +452,8 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh var arraySymbolType = symbolType; if (!table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) { - foreach (var arraySize in ArraySize) - { - if (arraySize is EmptyExpression) - arraySymbolType = new ArrayType(arraySymbolType, -1); - else - { - var arrayComputedSize = -1; - if (arraySize is IntegerLiteral i) - arrayComputedSize = (int)i.Value; - - var constantArraySize = arraySize.CompileConstantValue(table, context); - arraySymbolType = new ArrayType(arraySymbolType, arrayComputedSize, (constantArraySize.Id, context.GetBuffer())); - } - } + if (ArraySize != null) + arraySymbolType = GenerateArrayType(table, context, arraySymbolType, ArraySize); table.DeclaredTypes.Add(fullTypeName, symbolType = arraySymbolType); } @@ -448,6 +462,30 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh return true; } + public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext context, SymbolType arraySymbolType, List arraySizes) + { + foreach (var arraySize in arraySizes) + { + if (arraySize is EmptyExpression) + arraySymbolType = new ArrayType(arraySymbolType, -1); + else + { + var arrayComputedSize = -1; + if (arraySize is IntegerLiteral i) + arrayComputedSize = (int)i.Value; + + var constantArraySize = arraySize.CompileConstantValue(table, context); + if (SpirvBuilder.TryGetConstantValue(constantArraySize.Id, out var value, out _, context.GetBuffer(), true)) + arrayComputedSize = (int)value; + arraySymbolType = arrayComputedSize != -1 + ? new ArrayType(arraySymbolType, arrayComputedSize) + : new ArrayType(arraySymbolType, arrayComputedSize, (constantArraySize.Id, context.GetBuffer())); + } + } + + return arraySymbolType; + } + public SymbolType ResolveType(SymbolTable table, SpirvContext context) { if (!TryResolveType(table, context, out var result)) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 8a53cca37a..044e93e39d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -160,26 +160,34 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) Type = new PointerType(valueType, Specification.StorageClass.Function); - var registeredType = context.GetOrRegister(Type); for (var index = 0; index < Variables.Count; index++) { var d = Variables[index]; + var variableValueType = valueType; + if (d.ArraySizes != null) + variableValueType = TypeName.GenerateArrayType(table, context, variableValueType, d.ArraySizes); + + var variableType = new PointerType(variableValueType, Specification.StorageClass.Function); + + // TODO: Check if any array is empty and fill with initializer info (if any, otherwise error) + var variable = context.Bound++; - builder.AddFunctionVariable(registeredType, variable); + var variableTypeId = context.GetOrRegister(variableType); + builder.AddFunctionVariable(variableTypeId, variable); context.AddName(variable, d.Variable); - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), Type, variable)); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), variableType, variable)); if (builder.CurrentFunction is SpirvFunction f) - f.Variables.Add(d.Variable, new(variable, registeredType, d.Variable)); + f.Variables.Add(d.Variable, new(variable, variableTypeId, d.Variable)); if (d.Value != null) { var source = compiledValues[index]; // Make sure type is correct - source = builder.Convert(context, source, valueType); + source = builder.Convert(context, source, variableValueType); builder.Insert(new OpStore(variable, source.Id, null)); } From a5ed65d648d736adcb16202da27fc9d6a9100e89 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 15:05:39 +0900 Subject: [PATCH 0658/1182] Added expectedType during compile --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 146 +++++++++--------- .../Parsing/SDSL/AST/Expression.cs | 30 ++-- .../Parsing/SDSL/AST/Literals.cs | 18 +-- .../Parsing/SDSL/AST/Statements.cs | 26 ++-- .../Spirv/Building/ExpressionExtensions.cs | 26 ++-- 5 files changed, 131 insertions(+), 115 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 70fedb66ad..9dafebfc93 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -35,7 +35,7 @@ public static SymbolType FindCommonType(ScalarType baseType, params Span public abstract class Expression(TextLocation info) : ValueNode(info) { - public SpirvValue Compile(SymbolTable table, CompilerUnit compiler) + public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - var result = CompileImpl(table, compiler); + var result = CompileImpl(table, compiler, expectedType); // In case type is not computed yet, make sure it is using SpirvValue.TypeId if (result.TypeId != 0) Type ??= compiler.Context.ReverseTypes[result.TypeId]; return result; } - public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); + public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null); public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } - public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) + public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - var result = Compile(table, compiler); + var result = Compile(table, compiler, expectedType); result = compiler.Builder.AsValue(compiler.Context, result); ValueType = compiler.Context.ReverseTypes[result.TypeId]; return result; @@ -44,7 +44,7 @@ public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compile /// public class EmptyExpression(TextLocation info) : Expression(info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) => throw new NotImplementedException(); public override string ToString() => string.Empty; } @@ -56,7 +56,7 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public SpirvValue? MemberCall { get; set; } public bool IsBaseCall { get; set; } = false; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; @@ -166,7 +166,7 @@ public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) { public Mixin Mixin { get; set; } = mixin; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { throw new NotImplementedException(); } @@ -185,7 +185,7 @@ public abstract class UnaryExpression(Expression expression, Operator op, TextLo public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; var expression = Expression.Compile(table, compiler); @@ -264,7 +264,7 @@ public class CastExpression(TypeName typeName, Operator op, Expression expressio { public TypeName TypeName { get; set; } = typeName; - public unsafe override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public unsafe override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; var castType = TypeName.ResolveType(table, context); @@ -281,7 +281,7 @@ public class IndexerExpression(Expression index, TextLocation info) : Expression { public Expression Index { get; set; } = index; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { throw new NotImplementedException(); } @@ -295,7 +295,7 @@ public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { throw new NotImplementedException(); } @@ -310,7 +310,7 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; SpirvValue result; @@ -626,7 +626,7 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var left = Left.CompileAsValue(table, compiler); var right = Right.CompileAsValue(table, compiler); @@ -649,7 +649,7 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 2a12cedf71..a506900d6e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -23,7 +23,7 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; @@ -32,7 +32,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) return new SpirvValue(i.IdResult.Value, 0); } - public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { // Since we use type 0, CompileAsValue won't work return CompileImpl(table, compiler); @@ -69,7 +69,7 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { return compiler.Context.CompileConstantLiteral(this); } @@ -80,7 +80,7 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { return compiler.Context.CompileConstantLiteral(this); } @@ -97,7 +97,7 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.From("bool"); - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { return compiler.Context.CompileConstantLiteral(this); } @@ -108,7 +108,7 @@ public class ExpressionLiteral(Expression value, TypeName typeName, TextLocation public Expression Value { get; set; } = value; public TypeName TypeName { get; set; } = typeName; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; var castType = TypeName.ResolveType(table, context); @@ -134,7 +134,7 @@ public bool IsConstant() public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues); - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; @@ -263,7 +263,7 @@ public class Identifier(string name, TextLocation info) : Literal(info) public static implicit operator string(Identifier identifier) => identifier.Name; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; @@ -493,7 +493,7 @@ public SymbolType ResolveType(SymbolTable table, SpirvContext context) return result; } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { throw new NotImplementedException(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 044e93e39d..c7fdb0344c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -98,9 +98,9 @@ public List? ArraySizes public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - Variable.Type = TypeName.ResolveType(table, context); - var initialValue = Value?.CompileAsValue(table, compiler); - if (Value is not null && Value.Type != Variable.Type) + var variableValueType = TypeName.ResolveType(table, context); + var initialValue = Value?.CompileAsValue(table, compiler, variableValueType); + if (Value is not null && Value.ValueType != variableValueType) table.Errors.Add(new(TypeName.Info, "wrong type")); throw new NotImplementedException(); @@ -129,16 +129,19 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; var compiledValues = new SpirvValue[Variables.Count]; - for (var index = 0; index < Variables.Count; index++) - { - if (Variables[index].Value != null) - compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler); - } // Compute type SymbolType valueType; - if (TypeName == "var") + var isVarType = TypeName == "var"; + if (isVarType) { + // Compile first then guess type (for non-var, we delay compilation of intial values later so that we can infer type using full typename and arrays) + for (var index = 0; index < Variables.Count; index++) + { + if (Variables[index].Value != null) + compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler); + } + if (Variables.Count == 1 && Variables[0].Value is not null) { valueType = Variables[0].Value!.ValueType; @@ -182,8 +185,13 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) if (builder.CurrentFunction is SpirvFunction f) f.Variables.Add(d.Variable, new(variable, variableTypeId, d.Variable)); + // Check initial value if (d.Value != null) { + // var type: already computed + if (!isVarType) + compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler, variableValueType); + var source = compiledValues[index]; // Make sure type is correct diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index f87633292f..3999c9c840 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -8,7 +8,7 @@ namespace Stride.Shaders.Spirv.Building; public static class ExpressionExtensions { - public static HashSet SpecConstantSupportedOps = new() + public static HashSet SpecConstantOpSupportedOps = new() { Op.OpSConvert, Op.OpUConvert, @@ -62,15 +62,23 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol { var i = buffer[index]; - // Check if opcode is supported - if (!SpecConstantSupportedOps.Contains(i.Op)) - throw new InvalidOperationException($"OpCode {i.Op} not supported when compiling constant {expression}"); - - var resultType = i.Data.Memory.Span[1]; - var resultId = i.Data.Memory.Span[2]; + if (i.Op == Op.OpCompositeConstruct) + { + i.Data.Memory.Span[0] = (int)Op.OpConstantComposite | (i.Data.Memory.Length << 16); + } + // Rewrite using OpSpecConstantOp when possible + else if(SpecConstantOpSupportedOps.Contains(i.Op)) + { + var resultType = i.Data.Memory.Span[1]; + var resultId = i.Data.Memory.Span[2]; - Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; - instruction[0] |= instruction.Length << 16; + Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; + instruction[0] |= instruction.Length << 16; + } + else + { + throw new InvalidOperationException($"OpCode {i.Op} not supported when compiling constant {expression}"); + } // TODO: Check no IdRef to things outside context is done From b92f6fa75a1e4c68fffe3455768b8368a61cfeb3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 18:04:15 +0900 Subject: [PATCH 0659/1182] Parser: vector/matrix termination was improperly checked --- .../Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index d8d09bce50..13c3180c19 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -177,7 +177,7 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou else if (Tokens.Char(')', ref scanner, advance: true)) break; } - if (scanner.IsEof) + if (scanner.IsEof && scanner.Span[scanner.Position - 1] != ')') return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0004, scanner[scanner.Position], scanner.Memory)); if (p.Values.Count != size && p.Values.Count > size) return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0005, scanner[scanner.Position], scanner.Memory)); @@ -394,7 +394,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else if (Tokens.Char(')', ref scanner, advance: true)) break; } - if (scanner.IsEof) + if (scanner.IsEof && scanner.Span[scanner.Position - 1] != ')') return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0008, scanner[scanner.Position], scanner.Memory)); if (p.Values.Count != rows * cols && p.Values.Count > rows * cols) return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0002, scanner[scanner.Position], scanner.Memory)); From 087b2262e3eedee60ac7229361727cdf682a0465 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 18:43:50 +0900 Subject: [PATCH 0660/1182] Generics: handle float4 --- assets/SDSL/RenderTests/GenericsEffect.sdsl | 31 +++++-- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 68 +++++++------- .../Spirv/Building/Builder.Class.cs | 93 +++++++++++++------ .../Spirv/Building/ExpressionExtensions.cs | 36 +++++-- 5 files changed, 150 insertions(+), 80 deletions(-) diff --git a/assets/SDSL/RenderTests/GenericsEffect.sdsl b/assets/SDSL/RenderTests/GenericsEffect.sdsl index c2428aa671..a2091d124f 100644 --- a/assets/SDSL/RenderTests/GenericsEffect.sdsl +++ b/assets/SDSL/RenderTests/GenericsEffect.sdsl @@ -1,10 +1,10 @@ -// PSMain(ExpectedResult=#11FFFFFF) +// PSMain(ExpectedResult=#34302425) namespace Stride.Shaders.Tests; shader Compute { - float Compute() + float4 Compute() { return 0.0; } @@ -12,14 +12,26 @@ shader Compute shader ComputeFixed : Compute { - override float Compute() + override float4 Compute() { - return base.Compute() + TVALUE / 255.0; + return base.Compute() + float4(TVALUE, 0, 0, 0); } } shader ComputeFixed2 : ComputeFixed { + override float4 Compute() + { + return base.Compute() + float4(0, TVALUE2, 0, 0); + } +} + +shader ComputeFixed3 : Compute +{ + override float4 Compute() + { + return base.Compute() + TVALUE2; + } } shader GenericsEffectTest : Compute @@ -28,14 +40,19 @@ shader GenericsEffectTest : Compute void PSMain() { - streams.ColorTarget = float4(Compute(), 1.0, 1.0, 1.0); + streams.ColorTarget = Compute() / 255.0; } } effect GenericsEffect { mixin GenericsEffectTest; - mixin ComputeFixed<7.0>; + + mixin ComputeFixed<4.0>; + mixin ComputeFixed<6.0>; mixin ComputeFixed2<10.0>; - mixin ComputeFixed2<7.0>; + mixin ComputeFixed2<6.0>; + + mixin ComputeFixed3; + mixin ComputeFixed3; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 359705f6d0..2f45b7e6fb 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -42,7 +42,7 @@ internal static int[] CompileGenerics(SymbolTable table, CompilerUnit compiler, { if (generic is not Literal literal) throw new InvalidOperationException($"Generic value {generic} is not a literal"); - var compiledValue = generic.Compile(table, compiler); + var compiledValue = generic.CompileConstantValue(table, compiler.Context); genericValues[genericIndex++] = compiledValue.Id; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index a506900d6e..9d9428843e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -71,6 +71,13 @@ public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : Numb { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { + // If expectedType is float, handle it: + if (expectedType is ScalarType { TypeName: "float" }) + { + Type = expectedType; + return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), value, null, info)); + } + return compiler.Context.CompileConstantLiteral(this); } } @@ -132,26 +139,19 @@ public bool IsConstant() return true; } - public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues); + public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType); public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; - var sourceValues = new (SpirvValue Value, SymbolType Type)[Values.Count]; - for (int i = 0; i < sourceValues.Length; ++i) - { - var sourceValue = Values[i].CompileAsValue(table, compiler); - sourceValues[i] = (sourceValue, Values[i].ValueType); - } - - Type = GenerateType(table, context, sourceValues); + Type = GenerateType(table, context, expectedType); - (var compositeCount, var totalCount) = Type switch + (var compositeCount, var totalCount, var expectedElementType) = Type switch { - VectorType v => (v.Size, v.Size), - MatrixType m => (m.Rows, m.Columns * m.Rows), - ArrayType t => (t.Size, t.Size), + VectorType v => (v.Size, v.Size, v.BaseType), + MatrixType m => (m.Rows, m.Columns * m.Rows, m.BaseType), + ArrayType t => (t.Size, t.Size, t.BaseType), }; Span values = stackalloc int[totalCount]; @@ -160,33 +160,35 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, // Note: There are a lot of opportunity to optimize by working with vector-to-vector copy (if they align correctly) and/or OpVectorShuffle, but it can get quite complex to handle all cases // However, it is probably optimized by SPIRV-Cross or the compiler/driver, so maybe not worth optimzing (due to increased code cases/complexity) var elementIndex = 0; - foreach (var sourceValue in sourceValues) + for (int i = 0; i < Values.Count; i++) { - var value = sourceValue.Value; - var valueType = sourceValue.Type; - + // Note: we can compute expected element type only if there are as many source values as expected elements + // i.e. float3(float, float, float) is OK but float3(float, float2) is not as we don't know which element will be which before compiling them (we would need 2-pass compilation for that) + var value = Values[i].CompileAsValue(table, compiler, expectedElementType); + var valueType = Values[i].ValueType; + // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) if (Type is ScalarType or VectorType or MatrixType) { - var elementType = valueType.GetElementType(); - for (int i = 0; i < valueType.GetElementCount(); ++i) + var sourceElementType = valueType.GetElementType(); + for (int j = 0; j < valueType.GetElementCount(); ++j) { SpirvValue extractedValue = valueType switch { - MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i / m.Rows, i % m.Rows]))), - VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(elementType), context.Bound++, value.Id, [i]))), + MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j / m.Rows, j % m.Rows]))), + VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j]))), ScalarType s => value, }; // If too many elments, keep counting so that exception is still thrown a bit later, with total count var currentElementIndex = elementIndex++; if (currentElementIndex >= values.Length) continue; - values[currentElementIndex] = builder.Convert(context, extractedValue, elementType).Id; + values[currentElementIndex] = builder.Convert(context, extractedValue, expectedElementType).Id; } } else if (Type is ArrayType arrayType) { - values[elementIndex++] = builder.Convert(context, value, arrayType.BaseType).Id; + values[elementIndex++] = builder.Convert(context, value, expectedElementType).Id; } } @@ -213,7 +215,7 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) => TypeName.ResolveType(table, context); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) => TypeName.ResolveType(table, context); public override string ToString() { @@ -228,7 +230,7 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) => TypeName.ResolveType(table, context); + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) => TypeName.ResolveType(table, context); public override string ToString() { @@ -238,19 +240,13 @@ public override string ToString() public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, (SpirvValue Value, SymbolType Type)[] sourceValues) + public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) { - // We might be able to remove those exceptions by having better type inference (checking assigned variable) - if (sourceValues.Length == 0) - throw new NotImplementedException("Array needs at least one element"); - - for (int i = 1; i < sourceValues.Length; ++i) - { - if (sourceValues[i].Type != sourceValues[0].Type) - throw new NotImplementedException("Arrays expect same type for all elements"); - } + // If we have any expected type (i.e. it's being assigned to a variable), use it + if (expectedType != null) + return expectedType; - return new ArrayType(sourceValues[0].Type, sourceValues.Length); + throw new InvalidOperationException("Can't infer array type"); } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 407f198881..a3628a34ec 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -2,6 +2,8 @@ using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -81,6 +83,23 @@ public override int GetHashCode() } } +// Constant vector (generated by TryGetConstantValue) +public class ConstantVector +{ + public object[] Values; + + public override string ToString() + { + var type = Values[0] switch + { + float => "float", + }; + + return $"{type}{Values.Length}({string.Join(",", Values)})"; + } +} + + public partial class SpirvBuilder { private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) @@ -245,6 +264,21 @@ public static bool TryGetConstantValue(OpDataIndex i, out object value, out int throw new NotImplementedException(); } } + if ((i.Op == Op.OpConstantComposite || i.Op == Op.OpSpecConstantComposite) && (OpConstantComposite)i is { } constantComposite) + { + var values = constantComposite.Values; + var constants = new object[values.WordCount]; + for (int j = 0; j < values.WordCount; ++j) + { + if (!TryGetConstantValue(values.Elements.Span[j], out constants[j], out _, buffer)) + return false; + } + + // For now we assume it's a vector type (but we would need to revisit that later if we handle more advanced constants such as matrix or arrays) + value = new ConstantVector { Values = constants }; + + return true; + } typeId = i.Op switch { @@ -382,19 +416,31 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i if (isGenericReference) i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericReference; - // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID - var resultId = index == source.Count - 1 && desiredResultId != null - ? desiredResultId.Value - : bound++; + if (i.Data.IdResult.HasValue) + { + // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID + var resultId = index == source.Count - 1 && desiredResultId != null + ? desiredResultId.Value + : bound++; - remapIds.Add(i.Data.IdResult.Value, resultId); - i.Data.IdResult = resultId; - typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + remapIds.Add(i.Data.IdResult.Value, resultId); + i.Data.IdResult = resultId; + typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); - lastResultId = resultId; + lastResultId = resultId; + } } } + if (lastResultId == -1) + throw new InvalidOperationException("Could not find any instruction with a value"); + + if (desiredResultId != null && lastResultId != desiredResultId) + { + // Need to remap all existing references + RemapIds(target, 0, target.Count, new Dictionary { { desiredResultId.Value, lastResultId } }); + } + return lastResultId; } @@ -434,17 +480,18 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType textValue = genericValue; switch (genericParameterType) { - case ScalarType { TypeName: "int" }: - buffer.Replace(instructionIndex, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, int.Parse(genericValue))); - return true; - case ScalarType { TypeName: "float" }: - buffer.Replace(instructionIndex, new OpConstant(genericParameter.ResultType, genericParameter.ResultId, float.Parse(genericValue))); - return true; - case ScalarType { TypeName: "bool" }: - if (bool.Parse(genericValue)) - buffer.Replace(instructionIndex, new OpConstantTrue(genericParameter.ResultType, genericParameter.ResultId)); - else - buffer.Replace(instructionIndex, new OpConstantFalse(genericParameter.ResultType, genericParameter.ResultId)); + case ScalarType or VectorType: + var scanner = new Scanner(textValue); + ParseResult pr = new ParseResult(); + if (!ExpressionParser.Expression(ref scanner, pr, out var expression)) + throw new InvalidOperationException("Can't parse generic value"); + var localContext = new SpirvContext(); + var result = expression.CompileConstantValue(new SymbolTable(localContext), localContext, genericParameterType); + buffer.RemoveAt(instructionIndex); + var bound = buffer.Header.Bound; + SpirvBuilder.InsertBufferWithoutDuplicates(buffer, ref instructionIndex, ref bound, genericParameter.ResultId, localContext.GetBuffer()); + buffer.Header = buffer.Header with { Bound = bound }; + instructionIndex--; return true; case GenericParameterType g: buffer.Replace(instructionIndex, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); @@ -522,12 +569,6 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType int resultId = InsertBufferWithoutDuplicates(buffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); buffer.Header = buffer.Header with { Bound = bound }; - if (resultId != genericParameter.ResultId) - { - // Need to remap all existing references - RemapIds(buffer, 0, buffer.Count, new Dictionary { { genericParameter.ResultId, resultId } }); - } - // Since we removed one instruction earlier, adjust for it so that next loop process just after what has just been added instructionIndex--; @@ -882,7 +923,7 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader shader = CopyShader(shader); InstantiateGenericShader(shader, className, genericResolver, shaderLoader, macros); - Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shader; diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index 3999c9c840..b799b8a41d 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core.Buffers; @@ -48,13 +49,26 @@ public static class ExpressionExtensions Op.OpSLessThanEqual, Op.OpUGreaterThanEqual, Op.OpSGreaterThanEqual, + + // Note: those are not supported in standard shaders (only compute) + // but we'll make sure to simplify them once they can be resolved. + // We need them for SpirvBuilder.Convert() support + // However, it seems so far the expectedType system seems enough to use float4(int, int, int, int) in generics, so they are not implemented for now + //Op.OpConvertFToS, + //Op.OpConvertFToU, + //Op.OpConvertSToF, + //Op.OpConvertUToF, + //Op.OpBitcast, }; - public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context) + public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context, SymbolType? expectedType = null) { var compiler = new CompilerUnit(context, new()); - var result = expression.Compile(table, compiler); - + var result = expression.CompileAsValue(table, compiler, expectedType); + + if (expectedType != null) + compiler.Builder.Convert(context, result, expectedType); + var buffer = compiler.Builder.GetBuffer(); // Process each instruction and check if it can be converted to constant version @@ -64,7 +78,11 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol if (i.Op == Op.OpCompositeConstruct) { - i.Data.Memory.Span[0] = (int)Op.OpConstantComposite | (i.Data.Memory.Length << 16); + i.Data.Memory.Span[0] = (int)Op.OpSpecConstantComposite | (i.Data.Memory.Length << 16); + + // TODO: Check no IdRef to things outside context + var instruction = context.GetBuffer().Add(new(i.Data.Memory.Span)); + result = new(instruction.Data); } // Rewrite using OpSpecConstantOp when possible else if(SpecConstantOpSupportedOps.Contains(i.Op)) @@ -74,17 +92,15 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; instruction[0] |= instruction.Length << 16; + + // TODO: Check no IdRef to things outside context + context.GetBuffer().Add(new OpData(instruction)); + result = new(resultId, resultType); } else { throw new InvalidOperationException($"OpCode {i.Op} not supported when compiling constant {expression}"); } - - // TODO: Check no IdRef to things outside context is done - - context.GetBuffer().Add(new OpData(instruction)); - - result = new(resultId, resultType); } buffer.Dispose(); From 0ba51481512b3ac3cfc3d07e51d2441ef1242c82 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 18:45:44 +0900 Subject: [PATCH 0661/1182] Texture: added SampleCmpLevelZero and SampleCmp --- .../Parsing/SDSL/AST/Expression.cs | 25 ++++++++++++++++++- .../Parsing/SDSL/AST/Literals.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 13 ++++++---- .../ShaderParsers/ShaderDataParsers.cs | 2 +- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index c632b6884f..a4bdcbbab8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -364,7 +364,10 @@ void EmitOpAccessChain(Span accessChainIds) var accessor = Accessors[i]; switch (currentValueType, accessor) { - case (PointerType { BaseType: TextureType textureType }, MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 }): + case (PointerType { BaseType: TextureType textureType }, + MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } + or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } + or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 }): { // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); @@ -403,6 +406,26 @@ void EmitOpAccessChain(Span accessChainIds) result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; } + else if (accessor is MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 } sampleCompare) + { + var resultType = new VectorType(textureType.ReturnType, 4); + + var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler); + var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(resultType); + + var levelZero = context.CompileConstant(0.0f); + var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" + ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, ParameterizedFlags.ImageOperandsLod(levelZero.Id))) + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, Specification.ImageOperandsMask.None)); + + result = new(sample.IdResult!.Value, sample.IdResultType!.Value); + accessor.Type = resultType; + } else throw new InvalidOperationException("Invalid Sample method call"); break; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 9d9428843e..cbd17efa73 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -432,7 +432,7 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh table.DeclaredTypes.Add(fullTypeName, genericBufferType); symbolType = genericBufferType; } - else if (Name == "SamplerState") + else if (Name == "SamplerState" || Name == "SamplerComparisonState") { symbolType = new SamplerType(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index cd9c973bdf..9d1aea3f4d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -99,6 +99,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMaxLOD(maxLOD.ToString()))); break; } + case "ComparisonFunc": + { + var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateComparisonFunc(filter))); + break; + } case "BorderColor": default: throw new NotImplementedException(); @@ -121,14 +127,11 @@ public override string ToString() return $"SamplerState {Name} ({string.Join(", ", Parameters)})"; } } -public class ShaderSamplerComparisonState(Identifier name, TextLocation info) : MethodOrMember(info) +public class ShaderSamplerComparisonState(Identifier name, TextLocation info) : ShaderSamplerState(name, info) { - public Identifier Name { get; set; } = name; - public List Members { get; set; } = []; - public override string ToString() { - return $"SamplerState {Name} ({string.Join(", ", Members)})"; + return $"SamplerComparisonState {Name} ({string.Join(", ", Parameters)})"; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 0476a10a73..ced55d0ca2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -167,7 +167,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = new(identifier, scanner[position..scanner.Position]) { - Members = assignments + Parameters = assignments }; return true; } From 9e09ed6d0c00528c73cde2d237bbcebf39f57e23 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 27 Dec 2025 23:43:23 +0900 Subject: [PATCH 0662/1182] Unified symbol resolution to mostly use LoadedShaderSymbol (even for main shader being compiled). Also properly load inheritance hierarchy to find inherited symbols (both in main shader and composition) --- .../SDSL/ShaderMixer.MixinNode.cs | 2 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 2 +- .../SDSL/ShaderMixer.cs | 21 +++-- src/Stride.Shaders/Core/SymbolFrame.cs | 19 ++-- src/Stride.Shaders/Core/SymbolTypes.cs | 94 ++++++++++++++----- .../Parsing/Analysis/SymbolTable.cs | 18 ++-- .../Parsing/SDSL/AST/Expression.cs | 9 +- .../Parsing/SDSL/AST/Literals.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 32 +++++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 3 - .../Parsing/SDSL/AST/ShaderElements.cs | 14 +-- .../Spirv/Building/Builder.Class.cs | 8 +- 12 files changed, 140 insertions(+), 84 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 8c4cc2bd0e..0a775e45ee 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -51,7 +51,7 @@ class MethodGroup public string Name; public ShaderInfo Shader; public FunctionType FunctionType; - public List<(ShaderInfo Shader, int MethodId)> Methods { get; } = new(); + public List<(ShaderInfo Shader, int MethodId, Spirv.Specification.FunctionFlagsMask Flags)> Methods { get; } = new(); public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index e1a95d9725..4221885669 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -44,7 +44,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext break; } } - SpirvBuilder.BuildInheritanceList(ShaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceListIncludingSelf(ShaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } var compositions = new Dictionary(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 6f7ee4a33d..fd50c82dfc 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -534,7 +534,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, methodGroup = new MethodGroup { Name = functionName, FunctionType = functionType }; methodGroup.Shader = currentShader; - methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId)); + methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId, Flags: functionInfo.Flags)); methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; @@ -555,7 +555,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, else { // Remove the OpSDSLFunctionInfo - SetOpNop(temp[index + 1].Data.Memory.Span); + //SetOpNop(temp[index + 1].Data.Memory.Span); } } } @@ -747,6 +747,9 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte foundInStage = true; } + // Default: most derived implementation + var selectedMethod = methodGroupEntry.Methods[^1]; + // Process base call if (isBase) { @@ -762,7 +765,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte { if (methodGroupEntry.Methods[j].Shader.ShaderIndex < currentShader.ShaderIndex) { - functionId = methodGroupEntry.Methods[j].MethodId; + selectedMethod = methodGroupEntry.Methods[j]; baseMethodFound = true; break; } @@ -771,11 +774,10 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (!baseMethodFound) throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionId]}"); } - else - { - // If not, get the most derived implementation - functionId = methodGroupEntry.Methods[^1].MethodId; - } + + if ((selectedMethod.Flags & FunctionFlagsMask.Abstract) != 0) + throw new InvalidOperationException($"Trying to call an abstract method {selectedMethod.Shader.ShaderName}.{globalContext.Names[functionId]}"); + functionId = selectedMethod.MethodId; memberAccesses.Add(memberAccess.ResultId, functionId); } @@ -1160,7 +1162,8 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpTypeGenericSDSL || i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction - || i.Op == Op.OpSDSLImportVariable) + || i.Op == Op.OpSDSLImportVariable + || i.Op == Op.OpSDSLFunctionInfo) temp.RemoveAt(index--); else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration.Value is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 2a657b8fb1..93790597c9 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -9,19 +9,12 @@ public class SymbolFrame(SpirvContext context) { readonly Dictionary symbols = []; - readonly List implicitShaders = []; - public Symbol this[string name] { get => symbols[name]; set => symbols[name] = value; } - public void AddImplicitShader(LoadedShaderSymbol shaderSymbol) - { - implicitShaders.Add(shaderSymbol); - } - public void Add(string name, Symbol symbol) { if (symbol.Type is FunctionType && TryGetValue(name, out var existingSymbol)) @@ -49,11 +42,13 @@ public bool TryGetValue(string name, out Symbol symbol) if (symbols.TryGetValue(name, out symbol)) return true; - foreach (var implicitShader in implicitShaders) - { - if (implicitShader.TryResolveSymbol(context, name, out symbol)) - return true; - } + return false; + } + + public bool TryGetValues(string name, List result) + { + if (symbols.TryGetValue(name, out var symbol)) + result.Add(symbol); return false; } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 6a1f30712a..9774fc5a82 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -1,3 +1,4 @@ +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; @@ -314,38 +315,36 @@ public sealed record LoadedShaderSymbol(string Name, int[] GenericArguments) : S public List<(Symbol Symbol, FunctionFlagsMask Flags)> Methods { get; init; } = []; public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; + public List InheritedShaders { get; init; } = []; + internal bool TryResolveSymbol(SymbolTable symbolTable, SpirvContext context, string name, out Symbol symbol) + { + if (TryResolveSymbolNoRecursion(this == symbolTable.CurrentShader, context, name, out symbol)) + return true; + + // Process inherited classes + // note: since it contains all indirectly inherited method too, which is why it is splitted with TryResolveSymbolNoRecursion + foreach (var inheritedShader in InheritedShaders) + if (inheritedShader.TryResolveSymbolNoRecursion(false, context, name, out symbol)) + return true; + + return false; + } - internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol symbol) + private bool TryResolveSymbolNoRecursion(bool isCurrentShader, SpirvContext context, string name, out Symbol symbol) { - bool found = false; symbol = default; - var shaderId = context.GetOrRegister(this); - - var methods = CollectionsMarshal.AsSpan(Methods); - foreach (ref var c in methods) + var found = BuildMethodGroup(isCurrentShader, context, name, ref symbol); + if (found) { - if (c.Symbol.Id.Name == name) + // If any method is found, let's process inherited classes too: we need all method groups to find proper override + foreach (var inheritedClass in InheritedShaders) { - if (c.Symbol.IdRef == 0) - { - // Emit symbol - context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); - } - - // Combine method symbols if multiple matches - var methodSymbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; - - symbol = found - ? new Symbol(new(name, SymbolKind.MethodGroup, IsStage: symbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [symbol, methodSymbol]) - : methodSymbol; - - found = true; + inheritedClass.BuildMethodGroup(false, context, name, ref symbol); } - } - if (found) return true; + } var variables = CollectionsMarshal.AsSpan(Variables); foreach (ref var c in variables) @@ -355,10 +354,13 @@ internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol sym if (c.Symbol.IdRef == 0) { // Emit symbol + var shaderId = context.GetOrRegister(this); context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); } - symbol = c.Symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + symbol = c.Symbol; + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return true; } @@ -373,11 +375,14 @@ internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol sym if (c.Symbol.IdRef == 0) { // Emit symbol + var shaderId = context.GetOrRegister(this); context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); } var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, MemberAccessWithImplicitThis: c.Symbol.Type, AccessChain: index); + symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, AccessChain: index); + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return true; } } @@ -388,6 +393,45 @@ internal bool TryResolveSymbol(SpirvContext context, string name, out Symbol sym return false; } + private bool BuildMethodGroup(bool isCurrentShader, SpirvContext context, string name, ref Symbol symbol) + { + var found = false; + var methods = CollectionsMarshal.AsSpan(Methods); + foreach (ref var c in methods) + { + if (c.Symbol.Id.Name == name) + { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + // TODO: emit it only when this specific method is *selected* as proper overload (signature) & override (base vs this) + var shaderId = context.GetOrRegister(this); + context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); + } + + // Combine method symbols if multiple matches + var methodSymbol = c.Symbol; + + if (!isCurrentShader) + methodSymbol = methodSymbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + + // If symbol is set, complete it as a method group + symbol = symbol.Type switch + { + // First time: just assign to symbol + null => methodSymbol, + // Second time: create a method group + FunctionType => new Symbol(new(name, SymbolKind.MethodGroup, IsStage: symbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [symbol, methodSymbol]), + // Third time and later: complete method group + FunctionGroupType => symbol with { GroupMembers = symbol.GroupMembers.Add(methodSymbol) }, + }; + + found = true; + } + } + return found; + } + public override string ToString() => base.ToString(); } diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index acc949301b..adbf31737f 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -49,20 +49,16 @@ public SymbolTable(SpirvContext context) return scope; } - public void Import(ISymbolProvider symbols) - { - foreach (var (name, type) in symbols.DeclaredTypes) - DeclaredTypes.TryAdd(name, type); - foreach (var (name, symbol) in symbols.RootSymbols) - RootSymbols.Add(name, symbol); - } - public bool TryResolveSymbol(string name, out Symbol symbol) { for (int i = CurrentSymbols.Count - 1; i >= 0; i--) if (CurrentSymbols[i].TryGetValue(name, out symbol)) return true; + + if (CurrentShader != null && CurrentShader.TryResolveSymbol(this, Context, name, out symbol)) + return true; + symbol = default; return false; } @@ -77,6 +73,10 @@ public Symbol ResolveSymbol(string name) } } - throw new NotImplementedException($"Cannot find symbol {name}."); + if (CurrentShader != null && CurrentShader.TryResolveSymbol(this, Context, name, out var symbol2)) + return symbol2; + + + throw new NotImplementedException($"Cannot find symbol {name} in main context (current shader is {CurrentShader?.Name}"); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index a4bdcbbab8..b1252f0b8b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -64,7 +64,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (MemberCall != null) { var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - type.TryResolveSymbol(context, Name, out functionSymbol); + if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) + throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); } else { @@ -77,7 +78,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, // Find methods matching number of parameters var matchingMethods = functionSymbol.GroupMembers.Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); - // TODO: find proper overload + // TODO: find proper overload (different signature) + // We take first element, so in case there is multiple override, it will take the most-derived implementation + // Note: this will be reevaluted during ShaderMixer (base/this, etc.) but it won't change overload (different signature) functionSymbol = matchingMethods.First(); } var functionType = (FunctionType)functionSymbol.Type; @@ -460,7 +463,7 @@ void EmitOpAccessChain(Span accessChainIds) // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); - if (!s.TryResolveSymbol(context, field.Name, out var matchingComponent)) + if (!s.TryResolveSymbol(table, context, field.Name, out var matchingComponent)) throw new InvalidOperationException(); // TODO: figure out instance (this vs composition) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index cbd17efa73..12ccd3f3e5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -281,7 +281,7 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceList(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); + classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 9f7f725ddd..be575c7206 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -297,11 +297,21 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte } } + // Build full inheritance list + List inheritanceList = new(); + SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), buffer, inheritanceList, ResolveStep.Compile); + + // Load all the inherited shaders + List inheritedShaderSymbols = new(); + foreach (var inheritedClass in inheritanceList) + inheritedShaderSymbols.Add(LoadAndCacheExternalShaderType(table, context, inheritedClass)); + var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) { Variables = variables, Methods = methods, StructTypes = structTypes, + InheritedShaders = inheritedShaderSymbols, }; return shaderType; } @@ -331,7 +341,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var genericParameterTypeId = context.GetOrRegister(genericParameterType); context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, i, Name.Name)); context.AddName(context.Bound, genericParameter.Name); - table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); + + // Note: we skip MemberName because they should have been replaced with the preprocessor during SpirvBuilder.InstantiateMemberNames() step + if (genericParameterType is not GenericParameterType { Kind: GenericParameterKindSDSL.MemberName or GenericParameterKindSDSL.MemberNameResolved }) + table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); openGenerics[i] = context.Bound; @@ -373,9 +386,15 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); - SpirvBuilder.BuildInheritanceList(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile); + SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile); } + var currentShader = new LoadedShaderSymbol(Name, openGenerics); + RegisterShaderType(table, currentShader); + + table.CurrentShader = currentShader; + table.InheritedShaders = inheritanceList; + var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { @@ -444,12 +463,6 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } - var currentShader = new LoadedShaderSymbol(Name, openGenerics); - RegisterShaderType(table, currentShader); - - table.CurrentShader = currentShader; - table.InheritedShaders = inheritanceList; - RenameCBufferVariables(); foreach (var member in Elements.OfType()) @@ -523,8 +536,9 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader table.DeclaredTypes.TryAdd(structType.Type.Name, structType.Type); } + if (addToRoot) - table.CurrentFrame.AddImplicitShader(shaderType); + table.CurrentShader.InheritedShaders.Add(shaderType); // Mark inherit context.Add(new OpSDSLMixinInherit(shaderId)); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 9d1aea3f4d..026bdac05f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -117,7 +117,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var sid = new SymbolID(Name, SymbolKind.SamplerState); var symbol = new Symbol(sid, Type, register.ResultId); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); - table.CurrentFrame.Add(Name, symbol); } else throw new Exception($"SamplerState {Name} already defined"); } @@ -222,7 +221,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler ); var symbol = new Symbol(sid, Type, variable); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); - table.CurrentFrame.Add(Name, symbol); } public override string ToString() @@ -309,7 +307,6 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type); table.CurrentShader.Methods.Add((symbol, functionFlags)); - table.CurrentFrame.Add(Name, symbol); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler, bool hasUnresolvableGenerics) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 79b76bb894..6d8dbfa6fc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -304,7 +304,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile Type = constantBufferType; context.DeclareCBuffer(constantBufferType); - var pointerType = context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Uniform)); + var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); var variable = context.Bound++; context.AddName(variable, Name); @@ -324,10 +324,6 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile if (isStaged != member.IsStaged) throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); - var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - var symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), variable, AccessChain: index); - table.CurrentFrame.Add(member.Name, symbol); - if (member.Attributes != null && member.Attributes.Count > 0) { var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); @@ -339,7 +335,11 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } // TODO: Add a StreamSDSL storage class? - builder.Insert(new OpVariableSDSL(pointerType, variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + + var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); + var symbol = new Symbol(sid, pointerType, variable); + table.CurrentShader.Variables.Add((symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } } @@ -379,7 +379,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, variable.ResultId); - table.CurrentFrame.Add(member.Name, symbol); + table.CurrentShader.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index a3628a34ec..fcf60c7531 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -102,7 +102,7 @@ public override string ToString() public partial class SpirvBuilder { - private static void BuildInheritanceListHelper(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) + public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping var shaderMapping = new Dictionary(); @@ -149,7 +149,7 @@ int RemapGenericParameter(int localGeneric) remappedGenericArguments[index] = RemapGenericParameter(remappedGenericArguments[index]); var remappedShaderName = shaderName with { GenericArguments = remappedGenericArguments }; - BuildInheritanceList(shaderLoader, context, remappedShaderName, macros, inheritanceList, resolveStep); + BuildInheritanceListIncludingSelf(shaderLoader, context, remappedShaderName, macros, inheritanceList, resolveStep); } } } @@ -159,7 +159,7 @@ public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); } - public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep) + public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep) { // TODO: cache same instantiations within context? var index = inheritanceList.IndexOf(classSource); @@ -175,7 +175,7 @@ public static ShaderClassInstantiation BuildInheritanceList(IExternalShaderLoade index = inheritanceList.IndexOf(classSource); if (index == -1) { - BuildInheritanceListHelper(shaderLoader, context, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); + BuildInheritanceListWithoutSelf(shaderLoader, context, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); index = inheritanceList.Count; inheritanceList.Add(classSource); } From d49b24d167d8bd552a13505d5e5465837d9a12fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 28 Dec 2025 00:28:27 +0900 Subject: [PATCH 0663/1182] Various SPIR-V validation fixes --- .../SDSL/ShaderMixer.CBuffers.cs | 29 +++++++++++++++---- .../SDSL/ShaderMixer.cs | 5 ++-- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 3 +- .../Parsing/SDSL/AST/Expression.cs | 5 +++- src/Stride.Shaders/Spirv/Building/Context.cs | 9 ------ .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 + 6 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 68a9646286..8b6ccfdedd 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -262,6 +262,8 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) var offset = 0; for (int i = 0; i < s.Members.Count; ++i) { + var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); + members[i] = new EffectTypeMemberDescription { Name = s.Members[i].Name, @@ -269,11 +271,9 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) Offset = offset, }; - var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); - // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way if (!hasOffsetDecorations) - context.Add(new OpMemberDecorate(structId, i, ParameterizedFlags.DecorationOffset(offset))); + DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); offset += memberSize; } @@ -311,8 +311,12 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo } } - var arrayStride = (elementType.ElementSize + 15) / 16 * 16; - context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); + if (!hasStrideDecoration) + { + var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier).Size; + var arrayStride = (elementSize + 15) / 16 * 16; + context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); + } return elementType with { Elements = a.Size }; } @@ -348,7 +352,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo var member = cb.Members[index]; var memberSize = SpirvBuilder.ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); - context.Add(new OpMemberDecorate(context.Types[cbuffer.StructType], index, ParameterizedFlags.DecorationOffset(constantBufferOffset))); + DecorateMember(context, structTypeId, index, constantBufferOffset, memberSize, member.Type, member.TypeModifier); if (!links.TryGetValue((structTypeId, index), out var linkName)) throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); @@ -380,5 +384,18 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo }); } } + + private static void DecorateMember(SpirvContext context, int structTypeId, int index, int offset, int size, SymbolType memberType, TypeModifier memberTypeModifier) + { + context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationOffset(offset))); + if (memberType is MatrixType or ArrayType { BaseType: MatrixType }) + { + if (memberTypeModifier != TypeModifier.ColumnMajor) + context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.ColMajor, []))); + else if (memberTypeModifier != TypeModifier.RowMajor) + context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.RowMajor, []))); + context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationMatrixStride(16))); + } + } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index fd50c82dfc..c4986fdfa4 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -49,8 +49,9 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); context.Insert(0, new OpCapability(Capability.Shader)); - context.Insert(1, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - context.Insert(2, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); + context.Insert(1, new OpCapability(Capability.SampledBuffer)); + context.Insert(2, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + context.Insert(3, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); // Process streams and remove unused code/cbuffer/variable/resources new InterfaceProcessor().Process(table, temp, context); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 9dafebfc93..a245956259 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -858,7 +858,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; - var resultType = IntrinsicHelper.FindCommonType(ScalarType.From("float"), xType, yType); + var resultType = ScalarType.From("float"); + var inputTypes = IntrinsicHelper.FindCommonType(resultType, xType, yType); x = builder.Convert(context, x, resultType); y = builder.Convert(context, y, resultType); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index b1252f0b8b..df81ec9830 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -400,6 +400,7 @@ void EmitOpAccessChain(Span accessChainIds) var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); + levelValue = builder.Convert(context, levelValue, ScalarType.From("float")); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -411,7 +412,9 @@ void EmitOpAccessChain(Span accessChainIds) } else if (accessor is MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 } sampleCompare) { - var resultType = new VectorType(textureType.ReturnType, 4); + var resultType = textureType.ReturnType; + if (resultType is not ScalarType) + throw new InvalidOperationException(); var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 0cad5cc8ec..578d95c7f5 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -287,15 +287,6 @@ public int DeclareStructuredType(StructuredType structSymbol) { var member = structSymbol.Members[index]; AddMemberName(id, index, member.Name); - - if (member.Type is MatrixType) - { - if (member.TypeModifier != TypeModifier.ColumnMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Decoration.ColMajor, []))); - else if (member.TypeModifier != TypeModifier.RowMajor) - Add(new OpMemberDecorate(id, index, new ParameterizedFlag(Decoration.RowMajor, []))); - } - } Types[structSymbol] = id; diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index c1617b9889..8c1c0a476c 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -274,6 +274,7 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpTypeFunctionSDSL || op == Op.OpTypeImage || op == Op.OpTypeSampler + || op == Op.OpTypeSampledImage || op == Op.OpTypeGenericSDSL || op == Op.OpSDSLImportShader || op == Op.OpSDSLImportVariable From daabed6e46d8bbdb1823e59698eac874d086f248 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 29 Dec 2025 23:37:21 +0900 Subject: [PATCH 0664/1182] Improved SPVGenerator performance (and fixed GLSL documentation) --- .../SPVGenerator.Helpers.Preprocessing.cs | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 6de07d88be..d87b6cd5a6 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -118,7 +118,7 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok var htmlContext = BrowsingContext.New(config); var coreTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); coreTask.Wait(); - var glslTask = htmlContext.OpenAsync(req => req.Content(grammar.CoreDoc)); + var glslTask = htmlContext.OpenAsync(req => req.Content(grammar.GLSLDoc)); glslTask.Wait(); var coreDoc = coreTask.Result; var glslDoc = glslTask.Result; @@ -127,32 +127,47 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok // var buffer = new List(24); if (grammar.Instructions?.AsList() is List instructions) { + // Prebuilt for fast lookup + var tableblocksCore = coreDoc!.QuerySelectorAll($"p.tableblock").ToArray(); + var coreNodesById = new Dictionary(); + foreach (var tableblock in tableblocksCore) + { + var firstNode = tableblock.ChildNodes.FirstOrDefault(); + if (firstNode is IElement element && element.NodeName == "A" && element.Id != null) + coreNodesById.Add(element.Id, tableblock); + } + var tableblocksGLSL = glslDoc!.QuerySelectorAll($"p.tableblock").ToArray(); + var glslNodesByName = new Dictionary(); + foreach (var tableblock in tableblocksGLSL) + { + var firstNode = tableblock.ChildNodes.FirstOrDefault(); + if (firstNode is IElement element && element.NodeName == "STRONG") + glslNodesByName.Add(element.TextContent, tableblock); + } + for (int i = 0; i < instructions.Count; i++) // foreach (var instruction in grammar.Instructions) { var instruction = grammar.Instructions.Value.AsList()![i]!; // setup the documentation - var cells = instruction.OpName switch + var element = instruction.OpName switch { - string v when !v.StartsWith("Op") => glslDoc.QuerySelectorAll($"p.tableblock:has(strong:contains(\"{instruction.OpName.Replace("GLSL", "")}\"))"), + string v when !v.StartsWith("Op") => glslNodesByName.ContainsKey(instruction.OpName.Replace("GLSL", "")) ? glslNodesByName[instruction.OpName.Replace("GLSL", "")] : null, string v when v.Contains("SDSL") => null, // SDSL does not have documentation - string => coreDoc!.QuerySelectorAll($"p.tableblock:has(#{instruction.OpName})"), + string => coreNodesById.ContainsKey(instruction.OpName) ? coreNodesById[instruction.OpName] : null, }; - if (cells is not null) + if (element is not null) { - if (cells.FirstOrDefault() is IElement element) - { - var split = element.TextContent.Split('\n'); - builder.Clear(); - builder.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); - foreach (var t in split.Skip(1)) - if (!string.IsNullOrEmpty(t)) - builder.Append("/// ") - .Append(t.Replace("", "id")) - .AppendLine(""); - builder.AppendLine("/// "); - } + var split = element.TextContent.Split('\n'); + builder.Clear(); + builder.AppendLine("/// ").Append("/// ").Append(split[0]).AppendLine(""); + foreach (var t in split.Skip(1)) + if (!string.IsNullOrEmpty(t)) + builder.Append("/// ") + .Append(t.Replace("", "id")) + .AppendLine(""); + builder.AppendLine("/// "); instruction.Documentation = builder.ToString(); } From 486d16238b7f4ce422a6f93be92670120224fa97 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 30 Dec 2025 18:03:10 +0900 Subject: [PATCH 0665/1182] Rewrote streams processing to use a struct instead. This allow Streams to be passed as an argument --- SDSL.sln | 15 + assets/SDSL/RenderTests/GenericsSemantic.sdsl | 2 +- assets/SDSL/RenderTests/StreamParameter.sdsl | 27 ++ .../SDSL/ShaderMixer.cs | 15 +- .../Examples.Spirv.cs | 2 +- .../Stride.Shaders.Generators.csproj | 19 + .../TypeVisitorGenerator.cs | 327 +++++++++++++ .../Extensions/spirv.sdsl.grammar-ext.json | 18 + .../Core/SymbolTypes.Visitors.cs | 120 +++++ src/Stride.Shaders/Core/SymbolTypes.cs | 64 ++- .../Parsing/SDSL/AST/Expression.cs | 17 +- .../Parsing/SDSL/AST/Literals.cs | 18 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 16 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 + .../Parsing/SDSL/AST/ShaderElements.cs | 9 +- src/Stride.Shaders/Spirv/Building/Context.cs | 1 + .../Spirv/Processing/InterfaceProcessor.cs | 445 +++++++++++++++--- .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 + src/Stride.Shaders/Stride.Shaders.csproj | 5 + 19 files changed, 999 insertions(+), 124 deletions(-) create mode 100644 assets/SDSL/RenderTests/StreamParameter.sdsl create mode 100644 src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj create mode 100644 src/Stride.Shaders.Generators/TypeVisitorGenerator.cs create mode 100644 src/Stride.Shaders/Core/SymbolTypes.Visitors.cs diff --git a/SDSL.sln b/SDSL.sln index e100d4218d..3aa97d8d68 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -19,6 +19,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators", "src\Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -113,6 +115,18 @@ Global {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x64.Build.0 = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.ActiveCfg = Release|Any CPU {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}.Release|x86.Build.0 = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|x64.ActiveCfg = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|x64.Build.0 = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|x86.ActiveCfg = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Debug|x86.Build.0 = Debug|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|Any CPU.Build.0 = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x64.ActiveCfg = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x64.Build.0 = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x86.ActiveCfg = Release|Any CPU + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -125,5 +139,6 @@ Global {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/assets/SDSL/RenderTests/GenericsSemantic.sdsl b/assets/SDSL/RenderTests/GenericsSemantic.sdsl index c9f8f7cd2c..0a8b6ac6fd 100644 --- a/assets/SDSL/RenderTests/GenericsSemantic.sdsl +++ b/assets/SDSL/RenderTests/GenericsSemantic.sdsl @@ -16,7 +16,7 @@ shader ComputeSemantic : Compute override float4 Compute() { - return Test; + return streams.Test; } } diff --git a/assets/SDSL/RenderTests/StreamParameter.sdsl b/assets/SDSL/RenderTests/StreamParameter.sdsl new file mode 100644 index 0000000000..d4f2deed1d --- /dev/null +++ b/assets/SDSL/RenderTests/StreamParameter.sdsl @@ -0,0 +1,27 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) + +namespace Stride.Shaders.Tests; + +shader StreamParameter +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + stream float4 ExtraColor : EXTRA_COLOR; + + float4 Test(Streams streamsCopy) + { + return streamsCopy.ExtraColor; + } + + void VSMain() + { + Test(streams); + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = Test(streams); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index c4986fdfa4..02467a50a9 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -71,7 +71,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect foreach (var inst in context) temp.Add(inst.Data); - CleanupUnnecessaryInstructions(globalContext, temp); + CleanupUnnecessaryInstructions(globalContext, context, temp); temp.Sort(); @@ -470,9 +470,6 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // Setup types in context foreach (var type in globalContext.Types) { - // Ignore ShaderSymbol which are not fully loaded (they are likely just OpSDSLImportShader) - if (type.Value is ShaderSymbol && type.Value is not LoadedShaderSymbol) - continue; if (!context.ReverseTypes.ContainsKey(type.Key)) { context.Types.Add(type.Value, type.Key); @@ -1130,14 +1127,14 @@ public static void OffsetIds(OpData inst, int offset) } } - private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, NewSpirvBuffer temp) + private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) { for (int index = 0; index < temp.Count; index++) { var i = temp[index]; // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) - // Note: we ignore initializer as we store a method which is already processed during StreamAnalyzer (as opposed to a const for OpVariable) + // Note: we ignore initializer as we store a method which is already processed during InterfaceProcessor (as opposed to a const for OpVariable) if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) temp.Replace(index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); @@ -1177,20 +1174,20 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) else if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) { - var pointedType = globalContext.Types[typePointer.Type]; + var pointedType = context.ReverseTypes[typePointer.Type]; if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) temp.RemoveAt(index--); } // Also remove arrays of shaders (used in composition arrays) else if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { - var innerType = globalContext.Types[typeArray.ElementType]; + var innerType = context.ReverseTypes[typeArray.ElementType]; if (innerType is ShaderSymbol) temp.RemoveAt(index--); } else if (i.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) { - var innerType = globalContext.Types[typeRuntimeArray.ElementType]; + var innerType = context.ReverseTypes[typeRuntimeArray.ElementType]; if (innerType is ShaderSymbol) temp.RemoveAt(index--); } diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 6cb5d19427..5f942e2d66 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -27,7 +27,7 @@ public static void GenerateSpirv() var function = builder.DeclareFunction( context, "add", - new(ScalarType.From("int"), [(ScalarType.From("int"), default), (ScalarType.From("int"), default)]) + new(ScalarType.From("int"), [new(ScalarType.From("int"), default), new(ScalarType.From("int"), default)]) ); builder.BeginFunction(context, function); builder.AddFunctionParameter(context, "a", ScalarType.From("int")); diff --git a/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj new file mode 100644 index 0000000000..b8d19916eb --- /dev/null +++ b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.0 + latest + enable + enable + true + + + + + + + + + + + \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs b/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs new file mode 100644 index 0000000000..954f4e398d --- /dev/null +++ b/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs @@ -0,0 +1,327 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace Stride.Shaders.Spirv.Generators +{ + [Generator] + internal class TypeVisitorGenerator : IIncrementalGenerator + { + public void Initialize(IncrementalGeneratorInitializationContext context) + { + context.RegisterImplementationSourceOutput( + context.CompilationProvider, GenerateVisitors); + } + + private void GenerateVisitors(SourceProductionContext context, Compilation compilation) + { + var classVisitor = new SymbolTypeClassFinder(); + classVisitor.Visit(compilation.GlobalNamespace); + + var symbolTypes = classVisitor.SymbolTypes; + + var sb = new StringBuilder(); + + var typeAndGenericFormat = new SymbolDisplayFormat(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameOnly, SymbolDisplayGenericsOptions.IncludeTypeParameters); + + // Source: Stride old shader system VisitorGenerated.tt preprocessed with RuntimeTextTemplate1.tt and linePragmas="false" + sb.Append("namespace" + + " Stride.Shaders.Core\r\n{\r\n public partial class TypeVisitor" + + "\r\n {\r\n"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + var returnType = type.IsValueType ? "bool" : "TResult"; + sb.AppendLine($" public virtual {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine("{"); + if (type.IsValueType) + sb.AppendLine($"return DefaultVisit(ref {variableName});"); + else + sb.AppendLine($"return DefaultVisit({variableName});"); + sb.AppendLine("}"); + } + sb.Append(" }\r\n\r\n public partial class TypeRewriter\r\n {\r\n"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + var returnType = type.IsValueType ? "bool" : "SymbolType"; + sb.AppendLine($" public override {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine("{"); + // Process public fields and properties (with getter+setter) + var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); + foreach (var member in GetNodeMembers(type)) + { + var memberType = GetSymbolType(member); + var memberTypeName = memberType.ToDisplayString(); + var memberVariableName = member.Name.First().ToString().ToLower() + member.Name.Substring(1) + "Temp"; + var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && IsSymbolType(x.TypeArguments[0]))?.TypeArguments[0]; + var isNode = IsSymbolType(memberType); + if (isNode) + { + sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(memberType.IsValueType ? "Node" : "Type")}({variableName}.{member.Name});"); + sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); + sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + } + else if (nodeListElementType != null) + { + sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(nodeListElementType.IsValueType ? "Node" : "Type")}List({variableName}.{member.Name});"); + sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); + sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + } + } + if (type.IsValueType) + { + sb.AppendLine($" return base.Visit{genericParameters}(ref {variableName});"); + } + else + { + sb.AppendLine($" return (SymbolType)base.Visit{genericParameters}({variableName});"); + } + sb.Append("}\r\n"); + } + sb.Append(" }\r\n\r\n public partial class TypeVisitor\r\n {\r\n"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + sb.Append(" public virtual void Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(typeName); + sb.Append(" "); + sb.Append(variableName); + sb.Append(")\r\n {\r\n DefaultVisit("); + sb.Append(variableName); + sb.Append(");\r\n }\r\n"); + } + sb.Append(" }\r\n\r\n public partial class TypeWalker\r\n {\r\n"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + sb.Append(" public override void Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(typeName); + sb.Append(" "); + sb.Append(variableName); + sb.Append(")\r\n {\r\n"); + // Process public fields and properties (with getter+setter) + var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); + foreach (var member in GetNodeMembers(type)) + { + var memberType = GetSymbolType(member); + var memberTypeName = memberType.ToDisplayString(); + var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && IsSymbolType(x.TypeArguments[0]))?.TypeArguments[0]; + var isNode = IsSymbolType(memberType); + if (isNode) + { + sb.Append($" Visit{(memberType.IsValueType ? "Node" : "Type")}("); + sb.Append(variableName); + sb.Append("."); + sb.Append(member.Name); + sb.Append(");\r\n"); + } + else if (nodeListElementType != null) + { + sb.Append($" Visit{(nodeListElementType.IsValueType ? "Node" : "Type")}List("); + sb.Append(variableName); + sb.Append("."); + sb.Append(member.Name); + sb.Append(");\r\n"); + } + } + sb.Append(" base.Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(variableName); + sb.Append(");\r\n }\r\n"); + } + sb.Append(" }\r\n}\r\n\r\n"); + + foreach (var type in symbolTypes) + { + sb.Append("namespace "); + sb.Append(type.ContainingNamespace.ToDisplayString()); + sb.AppendLine("{"); + sb.AppendLine("public partial record"); + if (type.IsValueType) + sb.Append("struct "); + sb.Append(type.ToDisplayString(typeAndGenericFormat)); + sb.Append(@$" + {{ + public {(!type.IsValueType ? "override" : string.Empty)} void Accept(TypeVisitor visitor) + {{"); + sb.AppendLine("visitor.Visit(this);"); + sb.AppendLine("}"); + if (type.IsValueType) + { + sb.AppendLine("public bool Accept(TypeVisitor visitor)"); + sb.AppendLine("{"); + sb.AppendLine("return visitor.Visit(ref this);"); + } + else + { + sb.AppendLine("public override TResult Accept(TypeVisitor visitor)"); + sb.AppendLine("{"); + sb.AppendLine("return visitor.Visit(this);"); + } + sb.AppendLine("} } }"); + } + sb.AppendLine(); + + context.AddSource("TypeVisitors.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(sb.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + + private static IEnumerable GetNodeTypes(INamedTypeSymbol symbol) + { + while (symbol != null && IsSymbolType(symbol)) + { + yield return symbol; + symbol = symbol.BaseType; + } + } + + private static IEnumerable GetNodeMembers(INamedTypeSymbol nodeType) + { + foreach (var currentNodeType in GetNodeTypes(nodeType).Reverse()) + { + foreach (var member in currentNodeType.GetMembers().Where(CanVisitMember)) + yield return member; + } + } + + private static bool CanVisitMember(ISymbol symbol) + { + if (symbol.DeclaredAccessibility != Accessibility.Public || symbol.IsStatic) + return false; + + if (symbol.GetAttributes().Any(x => x.AttributeClass.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) + return false; + + if (symbol.Kind == SymbolKind.Field) + { + var field = (IFieldSymbol)symbol; + if (field.IsReadOnly) + return false; + + return true; + } + + if (symbol.Kind == SymbolKind.Property) + { + var property = (IPropertySymbol)symbol; + if (property.IsReadOnly || property.IsWriteOnly || property.IsIndexer) + return false; + + if (property.GetMethod.DeclaredAccessibility != Accessibility.Public + || property.SetMethod.DeclaredAccessibility != Accessibility.Public) + return false; + + return true; + } + + return false; + } + + private static bool IsSymbolType(ITypeSymbol type) + { + if (GetBaseTypesAndThis(type).Any(t => t.ToDisplayString() == "Stride.Shaders.Core.SymbolType")) + return true; + + if (type.IsValueType && type.Interfaces.Any(t => t.ToDisplayString() == "Stride.Shaders.Core.ISymbolTypeNode")) + return true; + + return false; + } + + private static IEnumerable GetBaseTypesAndThis(ITypeSymbol type) + { + var current = type; + while (current != null) + { + yield return current; + current = current.BaseType; + } + } + + private static ITypeSymbol GetSymbolType(ISymbol symbol) + { + var localSymbol = symbol as ILocalSymbol; + if (localSymbol != null) + { + return localSymbol.Type; + } + + var fieldSymbol = symbol as IFieldSymbol; + if (fieldSymbol != null) + { + return fieldSymbol.Type; + } + + var propertySymbol = symbol as IPropertySymbol; + if (propertySymbol != null) + { + return propertySymbol.Type; + } + + var parameterSymbol = symbol as IParameterSymbol; + if (parameterSymbol != null) + { + return parameterSymbol.Type; + } + + var aliasSymbol = symbol as IAliasSymbol; + if (aliasSymbol != null) + { + return aliasSymbol.Target as ITypeSymbol; + } + + return symbol as ITypeSymbol; + } + + + class SymbolTypeClassFinder : SymbolVisitor + { + public List SymbolTypes = new List(); + + public override void VisitNamedType(INamedTypeSymbol symbol) + { + if (IsSymbolType(symbol) && !symbol.IsAbstract) + SymbolTypes.Add(symbol); + } + + public override void VisitNamespace(INamespaceSymbol symbol) + { + foreach (var childSymbol in symbol.GetMembers()) + { + //We must implement the visitor pattern ourselves and + //accept the child symbols in order to visit their children + childSymbol.Accept(this); + } + } + } + } +} diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index e5d4aa05eb..8943e842e9 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -233,6 +233,13 @@ { "kind": "IdResult" } ] }, + { + "opname": "OpStreamsSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" } + ] + }, { "opname": "OpSDSLMixin", "class": "Miscellaneous", @@ -340,6 +347,13 @@ } ] }, + { + "opname": "OpTypeStreamsSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" } + ] + }, { "opname": "OpForeachSDSL", "class": "Miscellaneous", @@ -409,6 +423,10 @@ { "enumerant": "Stage", "value": "0x0001" + }, + { + "enumerant": "Stream", + "value": "0x0002" } ] }, diff --git a/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs new file mode 100644 index 0000000000..73e044991d --- /dev/null +++ b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs @@ -0,0 +1,120 @@ +namespace Stride.Shaders.Core; + +public abstract partial class TypeVisitor +{ + protected virtual void VisitNodeList(List list) where T : ISymbolTypeNode + { + foreach (var item in list) + VisitNode(item); + } + + protected virtual void VisitTypeList(List list) where T : ShaderSymbol + { + foreach (var item in list) + VisitType(item); + } + + public virtual void DefaultVisit(SymbolType type) + { + } + + public void DefaultVisit(T node) where T : struct, ISymbolTypeNode + { + } + + public virtual void VisitType(SymbolType type) + { + type?.Accept(this); + } + + public virtual void VisitNode(T node) where T : ISymbolTypeNode + { + node?.Accept(this); + } +} + +public partial class TypeWalker : TypeVisitor +{ +} + +public abstract partial class TypeVisitor +{ + public virtual TResult DefaultVisit(SymbolType node) + { + return default; + } + + public virtual bool DefaultVisit(ref T node) where T : struct, ISymbolTypeNode + { + return true; + } + + public virtual TResult VisitType(SymbolType type) + { + return type.Accept(this); + } + + public virtual bool VisitNode(ref T node) where T : struct, ISymbolTypeNode + { + return node.Accept(this); + } + +} + +public abstract partial class TypeRewriter : TypeVisitor +{ + protected TypeRewriter() + { + } + + public override SymbolType DefaultVisit(SymbolType node) + { + return node; + } + + protected List VisitTypeList(List list) where T : SymbolType + { + List? newList = null; + for (int i = 0; i < list.Count; ++i) + { + var previousValue = list[i]; + var temp = VisitType(previousValue); + + // First time change? + if (!ReferenceEquals(previousValue, temp) && newList == null) + newList = [.. list.Slice(0, i)]; + + if (newList != null) + { + if (temp != null) + newList.Add((T)temp); + } + } + + return newList ?? list; + } + + protected List VisitNodeList(List list) where T : struct, ISymbolTypeNode + { + var equalityComparer = EqualityComparer.Default; + + List? newList = null; + for (int i = 0; i < list.Count; ++i) + { + var value = list[i]; + var keep = VisitNode(ref value); + + // First time change? + if ((!keep || !equalityComparer.Equals(value, list[i])) && newList == null) + newList = [.. list.Slice(0, i)]; + + if (newList != null) + { + if (keep) + newList.Add(value); + } + } + + return newList ?? list; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 9774fc5a82..ace543ef58 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -11,7 +11,12 @@ namespace Stride.Shaders.Core; +public interface ISymbolTypeNode +{ + public void Accept(TypeVisitor visitor); + public bool Accept(TypeVisitor visitor); +} public abstract record SymbolType() { @@ -80,9 +85,13 @@ public static bool TryGetBufferType(string name, string? templateTypeName, [Mayb }; return found; } + + public abstract void Accept(TypeVisitor visitor); + + public abstract TResult Accept(TypeVisitor visitor); } -public sealed record UndefinedType(string TypeName) : SymbolType() +public sealed partial record UndefinedType(string TypeName) : SymbolType() { public override string ToString() { @@ -90,7 +99,7 @@ public override string ToString() } } -public sealed record PointerType(SymbolType BaseType, Specification.StorageClass StorageClass) : SymbolType() +public sealed partial record PointerType(SymbolType BaseType, Specification.StorageClass StorageClass) : SymbolType() { public override string ToId() => $"ptr_{StorageClass}_{BaseType.ToId()}"; public override string ToString() => $"*{BaseType}"; @@ -118,12 +127,15 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// /// The base type for the array. /// The size of the array. If -1, it means size is not defined, such as using []. -public sealed record ArrayType(SymbolType BaseType, int Size, (int Id, NewSpirvBuffer Buffer)? SizeExpression = null) : SymbolType() +public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, NewSpirvBuffer Buffer)? SizeExpression = null) : SymbolType() { public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } -public record StructuredType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : SymbolType() + +public partial record struct StructuredTypeMember(string Name, SymbolType Type, TypeModifier TypeModifier) : ISymbolTypeNode; + +public partial record StructuredType(string Name, List Members) : SymbolType() { public override string ToId() => Name; public override string ToString() => $"{Name}{{{string.Join(", ", Members.Select(x => $"{x.Type} {x.Name}"))}}}"; @@ -153,57 +165,58 @@ public int TryGetFieldIndex(string name) return -1; } - } -public sealed record StructType(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members) +public sealed partial record StructType(string Name, List Members) : StructuredType(Name, Members) { public override string ToString() => $"struct {base.ToString()}"; } -public sealed record BufferType(ScalarType BaseType) : SymbolType() +public sealed partial record BufferType(ScalarType BaseType) : SymbolType() { public override string ToString() => $"Buffer<{BaseType}>"; } // TODO: Add sampler parameters -public sealed record SamplerType() : SymbolType() +public sealed partial record SamplerType() : SymbolType() { public override string ToId() => $"type_sampler"; public override string ToString() => $"SamplerState"; } -public sealed record SampledImage(TextureType ImageType) : SymbolType() +public sealed partial record SampledImage(TextureType ImageType) : SymbolType() { public override string ToString() => $"SampledImage<{ImageType}>"; } -public abstract record TextureType(ScalarType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() +public abstract partial record TextureType(ScalarType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() { public override string ToId() => $"Texture_{ReturnType}"; public override string ToString() => $"Texture<{ReturnType}>({Dimension}, {Depth}, {Arrayed}, {Multisampled}, {Sampled}, {Format})"; } -public sealed record Texture1DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture1DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture1D<{ReturnType}>"; } -public sealed record Texture2DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture2DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture2D<{ReturnType}>"; } -public sealed record Texture3DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture3DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"Texture3D<{ReturnType}>"; } -public sealed record TextureCubeType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record TextureCubeType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"TextureCube<{ReturnType}>"; } -public sealed record FunctionGroupType() : SymbolType(); +public sealed partial record FunctionGroupType() : SymbolType(); + +public partial record struct FunctionParameter(SymbolType Type, ParameterModifiers Modifiers) : ISymbolTypeNode; -public sealed record FunctionType(SymbolType ReturnType, List<(SymbolType Type, ParameterModifiers Modifiers)> ParameterTypes) : SymbolType() +public sealed partial record FunctionType(SymbolType ReturnType, List ParameterTypes) : SymbolType() { public bool Equals(FunctionType? other) { @@ -267,17 +280,17 @@ public override string ToString() } } -public sealed record StreamsSymbol : SymbolType; +public sealed partial record StreamsSymbol : SymbolType; -public sealed record ConstantBufferSymbol(string Name, List<(string Name, SymbolType Type, TypeModifier TypeModifier)> Members) : StructuredType(Name, Members) +public sealed partial record ConstantBufferSymbol(string Name, List Members) : StructuredType(Name, Members) { public override string ToId() => $"type.{Name}"; public override string ToString() => $"cbuffer {base.ToString()}"; } -public sealed record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public sealed record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; +public sealed partial record ParamsSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; +public sealed partial record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType +public partial record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { public string ToClassName() { @@ -308,7 +321,7 @@ public override string ToString() } } -public sealed record LoadedShaderSymbol(string Name, int[] GenericArguments) : ShaderSymbol(Name, GenericArguments) +public sealed partial record LoadedShaderSymbol(string Name, int[] GenericArguments) : ShaderSymbol(Name, GenericArguments) { public List<(Symbol Symbol, VariableFlagsMask Flags)> Variables { get; init; } = []; @@ -435,4 +448,9 @@ private bool BuildMethodGroup(bool isCurrentShader, SpirvContext context, string public override string ToString() => base.ToString(); } -public sealed record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; +public sealed partial record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; + +public sealed partial record StreamsType : SymbolType +{ + public override string ToString() => "Streams"; +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index df81ec9830..246a44b027 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -320,14 +320,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, int firstIndex = 0; SymbolType currentValueType; - if (Source is Identifier { Name: "streams" } streams && Accessors[0] is Identifier streamVar) - { - result = streamVar.Compile(table, compiler); - result.ThrowIfSwizzle(); - currentValueType = streamVar.Type; - firstIndex = 1; - } - else if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) + if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) { if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; @@ -473,6 +466,14 @@ void EmitOpAccessChain(Span accessChainIds) result = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; + break; + case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): + // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now\ + streamVar.AllowStreamVariables = true; + var streamVariableResult = streamVar.Compile(table, compiler); + streamVariableResult.ThrowIfSwizzle(); + PushAccessChainId(accessChainIds, streamVariableResult.Id); + accessor.Type = streamVar.Type; break; case (PointerType { BaseType: StructType s } p, Identifier field): diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 12ccd3f3e5..9c99284d40 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -255,6 +255,7 @@ public override string ToString() public class Identifier(string name, TextLocation info) : Literal(info) { + internal bool AllowStreamVariables { get; set; } public string Name { get; set; } = name; public static implicit operator string(Identifier identifier) => identifier.Name; @@ -268,6 +269,12 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref int position, SpirvContext context, bool constantOnly) { + if (Name == "streams") + { + var result = buffer.Insert(position++, new OpStreamsSDSL(context.Bound++)); + return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(), Specification.StorageClass.Private))); + } + if (!table.TryResolveSymbol(Name, out var symbol)) { if (constantOnly) @@ -292,12 +299,11 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref var shaderId = context.GetOrRegister(classSource.Symbol); symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); table.CurrentFrame.Add(classSource.Symbol.Name, symbol); - - Type = symbol.Type; - return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } - Type = symbol.Type; + if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) + throw new InvalidOperationException("Streams member used without an base type"); + Type = symbol.Type; return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } @@ -409,6 +415,10 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberNameResolved); } + else if (Name == "Streams") + { + symbolType = new StreamsType(); + } else { var fullTypeName = GenerateTypeName(includeGenerics: true, includeArray: false); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index be575c7206..2b185ba32d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -128,13 +128,13 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { var structName = names[typeStructInstruction.ResultId]; var fieldsData = typeStructInstruction.Values; - var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); + var fields = new List(); for (var index = 0; index < fieldsData.WordCount; index++) { var fieldData = fieldsData.Words[index]; var type = types[fieldData]; var name = memberNames[(typeStructInstruction.ResultId, index)]; - fields.Add((name, type, TypeModifier.None)); + fields.Add(new(name, type, TypeModifier.None)); } StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) ? new ConstantBufferSymbol(structName.StartsWith("type.") ? structName.Substring("type.".Length) : throw new InvalidOperationException(), fields) @@ -163,10 +163,10 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeFunctionSDSL && new OpTypeFunctionSDSL(instruction) is { } typeFunctionInstruction) { var returnType = types[typeFunctionInstruction.ReturnType]; - var parameterTypes = new List<(SymbolType Type, ParameterModifiers Flags)>(); + var parameterTypes = new List(); foreach (var operand in typeFunctionInstruction.Values) { - parameterTypes.Add((types[operand.Item1], (ParameterModifiers)operand.Item2)); + parameterTypes.Add(new(types[operand.Item1], (ParameterModifiers)operand.Item2)); } types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); } @@ -207,6 +207,10 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end { types.Add(typeGeneric.ResultId, new GenericParameterType(typeGeneric.Kind)); } + else if (instruction.Op == Op.OpTypeStreamsSDSL && (OpTypePointer)instruction is { } typeStreams) + { + types.Add(typeStreams.ResultId, new StreamsType()); + } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) @@ -273,7 +277,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte variableName = $"_{variable.ResultId}"; var variableType = types[variable.ResultType]; - var sid = new SymbolID(variableName, SymbolKind.Variable, Storage.Stream, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); + var sid = new SymbolID(variableName, SymbolKind.Variable, variable.Flags.HasFlag(VariableFlagsMask.Stream) ? Storage.Stream : 0, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); variables.Add((new(sid, variableType, 0), variable.Flags)); } @@ -419,7 +423,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = new PointerType(argSym, Specification.StorageClass.Function); - ftype.ParameterTypes.Add((arg.Type, arg.Modifiers)); + ftype.ParameterTypes.Add(new(arg.Type, arg.Modifiers)); } func.Type = ftype; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 026bdac05f..99c1d55c88 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -179,6 +179,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler storageClass = pointerType.StorageClass; var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; + if (StreamKind == StreamKind.Stream) + variableFlags |= Specification.VariableFlagsMask.Stream; int? initializerMethod = null; if (Value != null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 6d8dbfa6fc..a028ab4188 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -169,13 +169,13 @@ public ShaderBuffer(string name, TextLocation info) : base(info) public override void ProcessSymbol(SymbolTable table, SpirvContext context) { - var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); + var fields = new List(); foreach (var smem in Members) { smem.Type = smem.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); - fields.Add((smem.Name, smem.Type, smem.TypeModifier)); + fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); } Type = new ConstantBufferSymbol(Name, fields); @@ -218,13 +218,13 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public override void ProcessSymbol(SymbolTable table, SpirvContext context) { - var fields = new List<(string Name, SymbolType Type, TypeModifier TypeModifier)>(); + var fields = new List(); foreach (var smem in Members) { smem.Type = smem.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); - fields.Add((smem.Name, smem.Type, smem.TypeModifier)); + fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); } Type = new StructType(TypeName.ToString(), fields); @@ -334,7 +334,6 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } } - // TODO: Add a StreamSDSL storage class? builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 578d95c7f5..15cdac0eab 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -171,6 +171,7 @@ public int GetOrRegister(SymbolType? type) BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Dim.Buffer, 2, 0, 0, 1, ImageFormat.Unknown, null)).IdResult, SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, + StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(Bound++)).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index ff2744f1ef..f8f1e58957 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Parsing.Analysis; using static Stride.Shaders.Spirv.Specification; using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance; namespace Stride.Shaders.Spirv.Processing { @@ -20,9 +21,7 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public string? Semantic { get; } = semantic; public string Name { get; } = name; public SymbolType Type { get; } = type; - public int VariableId { get; } = variableId; - public int? VariableMethodInitializerId { get; set; } public int? InputLayoutLocation { get; set; } public int? OutputLayoutLocation { get; set; } @@ -31,16 +30,36 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) /// We automatically mark input: a variable read before it's written to, or an output without a write. /// public bool Input => Read || (Output && !Write); - public bool Output { get; set; } - public bool Private => Input || Output || Read || Write; + public bool Output { get => field; set { field = value; UsedAnyStage = true; } } + public bool UsedThisStage => Input || Output || Read || Write; public bool Read { get => field; set { field = value; UsedAnyStage = true; } } public bool Write { get => field; set { field = value; UsedAnyStage = true; } } public bool UsedAnyStage { get; private set; } + public int StreamStructFieldIndex { get; internal set; } public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } + class VariableInfo(string name, SymbolType type, int variableId) + { + public string Name { get; } = name; + public SymbolType Type { get; } = type; + + public int VariableId { get; } = variableId; + public int? VariableMethodInitializerId { get; set; } + + + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } + } + class ResourceInfo(string name) { public string Name { get; } = name; @@ -87,7 +106,7 @@ class LogicalGroupInfo public List CBuffers { get; } = new(); } - record struct AnalysisResult(SortedList Streams, SortedList CBuffers, SortedList ResourceGroups, SortedList Resources); + record struct AnalysisResult(Dictionary Names, Dictionary Streams, Dictionary Variables, Dictionary CBuffers, Dictionary ResourceGroups, Dictionary Resources); class MethodInfo { @@ -99,17 +118,32 @@ class MethodInfo /// Used at all (in any stage) /// public bool UsedAnyStage { get; private set; } + + public List? OriginalMethodCode { get; set; } + public int? ThisStageMethodId { get; set; } + + // True if the method depends on STREAMS type (also if used by any OpFunctionCall recursively) + public bool HasStreamAccess { get; internal set; } } class LiveAnalysis { public Dictionary ReferencedMethods { get; } = new(); - public bool MarkMethodUsed(int functionId) + public HashSet ExtraReferencedMethods { get; } = new(); + + public MethodInfo GetOrCreateMethodInfo(int functionId) { if (!ReferencedMethods.TryGetValue(functionId, out MethodInfo methodInfo)) ReferencedMethods.Add(functionId, methodInfo = new MethodInfo()); + return methodInfo; + } + + public bool MarkMethodUsed(int functionId) + { + var methodInfo = GetOrCreateMethodInfo(functionId); + var previousValue = methodInfo.UsedThisStage; methodInfo.UsedThisStage = true; // Returns tree when added first time @@ -135,7 +169,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte var streams = analysisResult.Streams; var liveAnalysis = new LiveAnalysis(); - AnalyzeStreamReadWrites(buffer, [], entryPointPS.IdRef, analysisResult, liveAnalysis); + AnalyzeStreamReadWrites(buffer, context, entryPointPS.IdRef, analysisResult, liveAnalysis); // If written to, they are expected at the end of pixel shader foreach (var stream in streams) @@ -160,16 +194,22 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte stream.Value.Read = false; } // Reset cbuffer/resource/methods used for next stage + foreach (var variable in analysisResult.Variables) + variable.Value.UsedThisStage = false; foreach (var resource in analysisResult.Resources) resource.Value.UsedThisStage = false; foreach (var cbuffer in analysisResult.CBuffers) cbuffer.Value.UsedThisStage = false; foreach (var method in liveAnalysis.ReferencedMethods) + { method.Value.UsedThisStage = false; + method.Value.ThisStageMethodId = null; + } + PropagateStreamsFromPreviousStage(streams); if (entryPointVS.IdRef != 0) { - AnalyzeStreamReadWrites(buffer, [], entryPointVS.IdRef, analysisResult, liveAnalysis); + AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); // If written to, they are expected at the end of vertex shader foreach (var stream in streams) @@ -187,7 +227,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); } - private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, SortedList streams, LiveAnalysis liveAnalysis) + private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) { // Remove unreferenced code var removedIds = new HashSet(); @@ -249,7 +289,9 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c var i = buffer[index]; if (i.Op == Op.OpFunction && (OpFunction)i is { } function) { - if (!liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId)) + bool isReferenced = liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId) + || liveAnalysis.ExtraReferencedMethods.Contains(function.ResultId); + if (!isReferenced) { removedIds.Add(function.ResultId); while (buffer[index].Op != Op.OpFunctionEnd) @@ -297,14 +339,22 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c { Storageclass: StorageClass.Private, ResultId: int - } stream - && streams.TryGetValue(stream.ResultId, out var streamInfo)) + } variable2) { - if (!streamInfo.UsedAnyStage) + if (variable2.Flags.HasFlag(VariableFlagsMask.Stream)) { - removedIds.Add(stream.ResultId); + // Always removed as we now use streams structure + removedIds.Add(variable2.ResultId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); } + else + { + if (!analysisResult.Variables.TryGetValue(variable2.ResultId, out var variableInfo) || !variableInfo.UsedAnyStage) + { + removedIds.Add(variable2.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } } } @@ -325,6 +375,16 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (removedIds.Contains(decorateString.Target)) SpirvBuilder.SetOpNop(i.Data.Memory.Span); } + else if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer) + { + if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) + { + var streamsTypeSearch = new StreamsTypeSearch(); + streamsTypeSearch.VisitType(type); + if (streamsTypeSearch.Found) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } } } @@ -360,7 +420,7 @@ private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); } - private static void PropagateStreamsFromPreviousStage(SortedList streams) + private static void PropagateStreamsFromPreviousStage(Dictionary streams) { foreach (var stream in streams) { @@ -374,16 +434,17 @@ private static void PropagateStreamsFromPreviousStage(SortedList(); + var streams = new Dictionary(); HashSet blockTypes = []; Dictionary blockPointerTypes = []; - SortedList cbuffers = []; - SortedList resources = []; + Dictionary cbuffers = []; + Dictionary resources = []; + Dictionary variables = []; // Build name table - SortedList nameTable = []; - SortedList semanticTable = []; + Dictionary nameTable = []; + Dictionary semanticTable = []; foreach (var temp in new[] { context.GetBuffer(), buffer }) { foreach (var instruction in temp) @@ -475,16 +536,23 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) ? nameId : $"unnamed_{variable.ResultId}"; var type = context.ReverseTypes[variable.ResultType]; - semanticTable.TryGetValue(variable.ResultId, out var semantic); - var stream = new StreamInfo(semantic, name, type, variable.ResultId) + if (variable.Flags.HasFlag(VariableFlagsMask.Stream)) { - // Does it have an initializer? if yes, mark it as a value written in this stage - Write = variable.MethodInitializer != null, - VariableMethodInitializerId = variable.MethodInitializer, - }; + semanticTable.TryGetValue(variable.ResultId, out var semantic); + + if (variable.MethodInitializer != null) + throw new NotImplementedException("Variable initializer is not supported on streams variable"); - streams.Add(variable.ResultId, stream); + streams.Add(variable.ResultId, new StreamInfo(semantic, name, type, variable.ResultId)); + } + else + { + variables.Add(variable.ResultId, new VariableInfo(name, type, variable.ResultId) + { + VariableMethodInitializerId = variable.MethodInitializer, + }); + } } if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is @@ -503,7 +571,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) } // Process ResourceGroupId and build ResourceGroups - SortedList resourceGroups = new(); + Dictionary resourceGroups = new(); foreach (var i in context) { if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) @@ -554,7 +622,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) } } - return new(streams, cbuffers, resourceGroups, resources); + return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); } private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) @@ -607,7 +675,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) foreach (var stream in streams) { var baseType = ((PointerType)stream.Value.Type).BaseType; - if (stream.Value.Private) + + if (stream.Value.UsedThisStage) privateStreams.Add(stream.Value); if (stream.Value.Input) @@ -654,6 +723,29 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) } } + var fields = new List(); + foreach (var stream in privateStreams) + { + stream.StreamStructFieldIndex = fields.Count; + fields.Add(new(stream.Name, stream.Type, default)); + } + var streamsType = new StructType($"{stage}_STREAMS", fields); + context.DeclareStructuredType(streamsType); + + // Create a static global streams variable + context.FluentAdd(new OpVariable(context.GetOrRegister(new PointerType(streamsType, StorageClass.Private)), context.Bound++, StorageClass.Private, null), out var streamsVariable); + context.AddName(streamsVariable.ResultId, $"streams{stage}"); + + // Patch any OpStreams/OpAccessChain to use the new struct + foreach (var method in liveAnalysis.ReferencedMethods) + { + if (method.Value.UsedThisStage && method.Value.HasStreamAccess) + { + DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis); + PatchStreamsAccesses(buffer, context, method.Key, streamsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + } + } + context.FluentAdd(new OpTypeVoid(context.Bound++), out var voidType); // Add new entry point wrapper @@ -664,48 +756,57 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) { // Variable initializers - foreach (var stream in streams) + foreach (var variable in analysisResult.Variables) { // Note: we check Private to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) - if (stream.Value.Private - && stream.Value.VariableMethodInitializerId is int methodInitializerId) + if (variable.Value.UsedThisStage + && variable.Value.VariableMethodInitializerId is int methodInitializerId) { - liveAnalysis.MarkMethodUsed(methodInitializerId); + liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); - var variableValueType = ((PointerType)stream.Value.Type).BaseType; + var variableValueType = ((PointerType)variable.Value.Type).BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); - buffer.Add(new OpStore(stream.Value.VariableId, methodInitializerCall.ResultId, null)); + buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null)); } } - // Copy read variables from streams + // Copy variables from input to streams struct foreach (var stream in inputStreams) { var baseType = ((PointerType)stream.Info.Type).BaseType; + buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null), out var loadedValue); - buffer.Add(new OpStore(stream.Info.VariableId, loadedValue.ResultId, null)); + buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null)); } buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPointId, [])); + // Copy variables from streams struct to output foreach (var stream in outputStreams) { var baseType = ((PointerType)stream.Info.Type).BaseType; - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Info.VariableId, null), out var loadedValue); + buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null), out var loadedValue); buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); } + buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + privateStreams.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count]; + // Note: we overallocate and filter with UsedThisStage after + Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count]; int pvariableIndex = 0; foreach (var inputStream in inputStreams) pvariables[pvariableIndex++] = inputStream.Id; foreach (var outputStream in outputStreams) pvariables[pvariableIndex++] = outputStream.Id; - foreach (var privateStream in privateStreams) - pvariables[pvariableIndex++] = privateStream.VariableId; + pvariables[pvariableIndex++] = streamsVariable.ResultId; + foreach (var variable in analysisResult.Variables) + { + if (variable.Value.UsedThisStage) + pvariables[pvariableIndex++] = variable.Key; + } foreach (var cbuffer in analysisResult.CBuffers) { if (cbuffer.Value.UsedThisStage) @@ -717,88 +818,298 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) pvariables[pvariableIndex++] = resource.Key; } - liveAnalysis.MarkMethodUsed(newEntryPointFunction); + liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); } return newEntryPointFunction.ResultId; } + void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + { + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + + (var methodStart, var methodEnd) = FindMethodBounds(buffer, functionId); + + // One function might need to be duplicated in case it is used by different shader stages with STREAMS: + // On first time (in a stage), we backup method original content before mutation + // On second time (in a different stage), we copy the method (from original content) + if (methodInfo.OriginalMethodCode == null) + { + // Copy instructions memory (since we're going to mutate them and want to retain original version) + var methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); + foreach (ref var i in methodInstructions.AsSpan()) + i = new OpData(i.Memory.Span); + + methodInfo.OriginalMethodCode = methodInstructions; + } + else + { + // Need to reinsert method with new IDs + var remapIds = new Dictionary(); + var copiedInstructions = new List(); + foreach (var i in methodInfo.OriginalMethodCode) + { + // Save copied function ID + if (i.Op == Op.OpFunction) + methodInfo.ThisStageMethodId = context.Bound; + + var i2 = new OpData(i.Memory.Span); + if (i2.IdResult.HasValue) + remapIds.Add(i2.IdResult.Value, context.Bound++); + SpirvBuilder.RemapIds(remapIds, ref i2); + copiedInstructions.Add(i2); + + // Copy names too + if (i.IdResult is int resultId) + { + if (analysisResult.Names.TryGetValue(resultId, out var name)) + context.AddName(i2.IdResult!.Value, name); + } + } + + if (methodInfo.ThisStageMethodId == null) + throw new InvalidOperationException(); + + liveAnalysis.ExtraReferencedMethods.Add(methodInfo.ThisStageMethodId.Value); + + buffer.InsertRange(methodEnd, copiedInstructions.AsSpan()); + } + } + + class StreamsTypeReplace(SymbolType streamsReplacement) : TypeRewriter + { + public override SymbolType Visit(StreamsType streamsType) + { + return streamsReplacement; + } + } + + class StreamsTypeSearch : TypeWalker + { + public bool Found { get; private set; } + public override void Visit(StreamsType streamsType) + { + Found = true; + } + } + + void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + { + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + + (var methodStart, var methodEnd) = FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); + + var streams = analysisResult.Streams; + var streamsInstructionIds = new HashSet(); + + var method = (OpFunction)buffer[methodStart]; + var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; + + methodType = (FunctionType)new StreamsTypeReplace(streamsStructType).Visit(methodType); + method.FunctionType = context.GetOrRegister(methodType); + + // Remap ids for streams type to actual struct type + var remapIds = new Dictionary + { + { context.GetOrRegister(new StreamsType()), context.GetOrRegister(streamsStructType) }, + { context.GetOrRegister(new PointerType(new StreamsType(), StorageClass.Private)), context.GetOrRegister(new PointerType(streamsStructType, StorageClass.Private)) }, + { context.GetOrRegister(new PointerType(new StreamsType(), StorageClass.Function)), context.GetOrRegister(new PointerType(streamsStructType, StorageClass.Function)) }, + }; + + // TODO: remap method type! + for (int index = methodStart; index < methodEnd; ++index) + { + var i = buffer[index]; + + if (i.Op == Op.OpStreamsSDSL && (OpAccessChain)i is { } streamsInstruction) + { + streamsInstructionIds.Add(streamsInstruction.ResultId); + remapIds.Add(streamsInstruction.ResultId, streamsVariableId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op is Op.OpVariable && (OpVariable)i is { } variable) + { + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + streamsInstructionIds.Add(variable.ResultId); + } + else if (i.Op is Op.OpFunctionParameter && (OpFunctionParameter)i is { } functionParameter) + { + var type = context.ReverseTypes[functionParameter.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + streamsInstructionIds.Add(functionParameter.ResultId); + } + else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + // In case it's a streams access, patch acces to use STREAMS struct with proper index + if (streamsInstructionIds.Contains(accessChain.BaseId)) + { + var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamInfo = streams[streamVariableId]; + var streamStructMemberIndex = streamInfo.StreamStructFieldIndex; + + // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that + // we'll need a better way to update LiteralArray and propagate changes + accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; + + // Force refresh of InstructionMemory + accessChain.BaseId = streamsVariableId; + } + } + else if (i.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } call) + { + var calledMethodInfo = liveAnalysis.ReferencedMethods[call.Function]; + // In case we copied the method, use the new ID + if (calledMethodInfo.ThisStageMethodId is int updatedMethodId) + call.Function = updatedMethodId; + } + + SpirvBuilder.RemapIds(remapIds, ref i.Data); + } + } + /// /// Figure out (recursively) which streams are being read from and written to. /// - private void AnalyzeStreamReadWrites(NewSpirvBuffer buffer, List callStack, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { - // Mark as used, and check if already processed - if (!liveAnalysis.MarkMethodUsed(functionId)) - return; + // Check if already processed + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + if (methodInfo.UsedThisStage) + { + return methodInfo.HasStreamAccess; + } + // Mark as used + methodInfo.UsedThisStage = true; + + // If method was mutated by another stage, we work on the original copy instead + List methodInstructions; + if (methodInfo.OriginalMethodCode != null) + { + methodInstructions = methodInfo.OriginalMethodCode; + } + else + { + (var methodStart, var methodEnd) = FindMethodBounds(buffer, functionId); + methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); + } + + var streamsInstructionIds = new HashSet(); var streams = analysisResult.Streams; + var variables = analysisResult.Variables; var accessChainBases = new Dictionary(); - var methodStart = FindMethodStart(buffer, functionId); - for (var index = methodStart; index < buffer.Count; index++) + foreach (ref var i in methodInstructions.AsSpan()) { - var instruction = buffer[index]; - if (instruction.Op == Op.OpFunctionEnd) - break; - - if (instruction.Op is Op.OpLoad && (OpLoad)instruction is { } load) + // Check for any Streams variable + if (i.Op is Op.OpFunction && new OpFunction(ref i) is { } function) + { + var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; + var streamsTypeSearch = new StreamsTypeSearch(); + streamsTypeSearch.Visit(functionType); + if (streamsTypeSearch.Found) + methodInfo.HasStreamAccess = true; + } + else if (i.Op is Op.OpVariable && new OpVariable(ref i) is { } variable) { - // Check for access chains + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + { + // Note: we should restrict to R except if inout variable + streamsInstructionIds.Add(variable.ResultId); + methodInfo.HasStreamAccess = true; + } + } + // and for any Streams parameter + else if (i.Op is Op.OpFunctionParameter && new OpFunctionParameter(ref i) is { } functionParameter) + { + var type = context.ReverseTypes[functionParameter.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + { + // Note: we should restrict to R except if inout variable + streamsInstructionIds.Add(functionParameter.ResultId); + methodInfo.HasStreamAccess = true; + } + } + else if (i.Op is Op.OpLoad && new OpLoad(ref i) is { } load) + { + // Check for indirect access chains if (!accessChainBases.TryGetValue(load.Pointer, out var pointer)) pointer = load.Pointer; if (streams.TryGetValue(pointer, out var streamInfo) && !streamInfo.Write) streamInfo.Read = true; + if (variables.TryGetValue(pointer, out var variableInfo)) + variableInfo.UsedThisStage = true; if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) resourceInfo.UsedThisStage = true; if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } - else if (instruction.Op is Op.OpStore && (OpStore)instruction is { } store) + else if (i.Op is Op.OpStore && new OpStore(ref i) is { } store) { - // Check for access chains + // Check for indirect access chains if (!accessChainBases.TryGetValue(store.Pointer, out var pointer)) pointer = store.Pointer; if (streams.TryGetValue(pointer, out var streamInfo)) streamInfo.Write = true; + if (variables.TryGetValue(pointer, out var variableInfo)) + variableInfo.UsedThisStage = true; if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) resourceInfo.UsedThisStage = true; if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } - else if (instruction is { Op: Op.OpAccessChain } && (OpAccessChain)instruction is { } accessChain) + else if (i.Op == Op.OpStreamsSDSL && new OpAccessChain(ref i) is { } streamsInstruction) + { + streamsInstructionIds.Add(streamsInstruction.ResultId); + methodInfo.HasStreamAccess = true; + } + else if (i.Op == Op.OpAccessChain && new OpAccessChain(ref i) is { } accessChain) { + var currentBase = accessChain.BaseId; + + // In case it's a streams access, mark the stream as being the base + if (streamsInstructionIds.Contains(currentBase)) + { + var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamInfo = streams[streamVariableId]; + + // Set this base for OpStore/OpLoad stream R/W analysis + currentBase = streamVariableId; + } + // Any read or write through an access chain will be treated as doing it on the main variable. // i.e., streams.A.B will share same streamInfo as streams.A // TODO: what happens in case of partial write? - var currentBase = accessChain.BaseId; // Recurse in case we have multiple access chain chained after each other while (accessChainBases.TryGetValue(currentBase, out var nextBase)) currentBase = nextBase; accessChainBases.Add(accessChain.ResultId, currentBase); } - else if (instruction.Op == Op.OpFunctionCall && (OpFunctionCall)instruction is { } call) + else if (i.Op == Op.OpFunctionCall && new OpFunctionCall(ref i) is { } call) { // Process call - if (callStack.Contains(functionId)) - throw new InvalidOperationException($"Recursive call with method id {functionId}"); - callStack.Add(functionId); - AnalyzeStreamReadWrites(buffer, callStack, call.Function, analysisResult, liveAnalysis); - callStack.RemoveAt(callStack.Count - 1); + methodInfo.HasStreamAccess |= AnalyzeStreamReadWrites(buffer, context, call.Function, analysisResult, liveAnalysis); } } + + return methodInfo.HasStreamAccess; } - public int FindMethodStart(NewSpirvBuffer buffer, int functionId) + public (int Start, int End) FindMethodBounds(NewSpirvBuffer buffer, int functionId) { + int? start = null; for (var index = 0; index < buffer.Count; index++) { var instruction = buffer[index]; if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId) - return index; + start = index; + if (instruction.Op is Op.OpFunctionEnd && start is int startIndex) + return (startIndex, index + 1); } throw new InvalidOperationException($"Could not find start of method {functionId}"); } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 8c1c0a476c..6fb77b6695 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -276,6 +276,7 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpTypeSampler || op == Op.OpTypeSampledImage || op == Op.OpTypeGenericSDSL + || op == Op.OpTypeStreamsSDSL || op == Op.OpSDSLImportShader || op == Op.OpSDSLImportVariable || op == Op.OpSDSLImportFunction diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 38dd3d6d70..0a648b011e 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -7,12 +7,14 @@ +
+ @@ -27,6 +29,9 @@ enable True $(MSBuildProjectName)2 + CS8785;$(WarningsAsErrors) + true + Generated
From 4d7cc5f5d9780ed3fa50f551e7891492a7a93dd0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 30 Dec 2025 18:07:05 +0900 Subject: [PATCH 0666/1182] D3D11 tests: Make sure to cancel the async InfoQueueCallback thread --- src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index ffc188bf65..639c91a391 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -124,10 +124,11 @@ ref deviceContext ) ); + var cts = new CancellationTokenSource(); if (OperatingSystem.IsWindows()) { // Log debug messages for this device (given that we've enabled the debug flag). Don't do this in release code! - device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint)msg.PDescription))); + device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint)msg.PDescription)), cts.Token); } // Create our swapchain. @@ -635,6 +636,9 @@ ref textureSRV framebuffer.Dispose(); + cts.Cancel(); + cts.Dispose(); + window.Close(); window.Dispose(); From acece5d9ef4001ee46ab9d788ea0d092816a3ba3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 30 Dec 2025 18:21:51 +0900 Subject: [PATCH 0667/1182] If/else: added support for detecting unreachable merge (i.e. if both true and false return a value) --- .../Parsing/SDSL/AST/Statements.Control.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 17b03266e5..e4ab18de40 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -24,6 +24,7 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) var blockTrueIds = stackalloc int[ElseIfs.Count + 1]; var blockMergeIds = stackalloc int[ElseIfs.Count + 1]; + var isMergeBlockReachable = stackalloc bool[ElseIfs.Count + 1]; // Create and connect true/false blocks for (int i = 0; i < ElseIfs.Count + 1; ++i) @@ -52,7 +53,10 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) if (falseBlock != null) { if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + { + isMergeBlockReachable[i] = true; builder.Insert(new OpBranch(blockMergeIds[i])); + } builder.CreateBlock(context, falseBlock.Value, $"if_false_{builder.IfBlockCount + i}"); @@ -60,14 +64,23 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) if (i + 1 == ElseIfs.Count + 1) Else!.Compile(table, compiler); } + else + { + isMergeBlockReachable[i] = true; + } } // Create and connect merge branches for (int i = ElseIfs.Count; i >= 0; --i) { if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + { + isMergeBlockReachable[i] = true; builder.Insert(new OpBranch(blockMergeIds[i])); + } builder.CreateBlock(context, blockMergeIds[i], $"if_merge_{builder.IfBlockCount + i}"); + if (!isMergeBlockReachable[i]) + builder.Insert(new OpUnreachable()); } builder.IfBlockCount += ElseIfs.Count + 1; From 1fae981b2676601617a363ab2de98b814c813157 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 31 Dec 2025 16:13:28 +0900 Subject: [PATCH 0668/1182] InterfaceProcessor: avoid context.GetBuffer() --- .../Spirv/Processing/InterfaceProcessor.cs | 118 +++++++++--------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index f8f1e58957..f6146596b9 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -445,80 +445,68 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // Build name table Dictionary nameTable = []; Dictionary semanticTable = []; - foreach (var temp in new[] { context.GetBuffer(), buffer }) + foreach (var i in context) { - foreach (var instruction in temp) + // Names { - // Names - { - if (instruction.Op == Op.OpName - && ((OpName)instruction) is - { - Target: int t, - Name: string n - } - ) + if (i.Op == Op.OpName + && ((OpName)i) is { - nameTable[t] = new(n); + Target: int t, + Name: string n } - else if (instruction.Op == Op.OpMemberName - && ((OpMemberName)instruction) is - { - Type: int t2, - Member: int m, - Name: string n2 - } - ) + ) + { + nameTable[t] = new(n); + } + else if (i.Op == Op.OpMemberName + && ((OpMemberName)i) is { - nameTable[t2] = new(n2); + Type: int t2, + Member: int m, + Name: string n2 } + ) + { + nameTable[t2] = new(n2); } + } - // CBuffer - // Encoded in this format: - // OpDecorate %type_CBuffer1 Block - // %_ptr_Uniform_type_CBuffer1 = OpTypePointer Uniform %type_CBuffer1 - // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform + // CBuffer + // Encoded in this format: + // OpDecorate %type_CBuffer1 Block + // %_ptr_Uniform_type_CBuffer1 = OpTypePointer Uniform %type_CBuffer1 + // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform + { + if (i.Op == Op.OpDecorate + && ((OpDecorate)i) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) { - if (instruction.Op == Op.OpDecorate - && ((OpDecorate)instruction) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) - { - blockTypes.Add(bufferType); - } - else if (instruction.Op == Op.OpTypePointer - && ((OpTypePointer)instruction) is { Storageclass: StorageClass.Uniform, ResultId: var pointerType, Type: var bufferType2 } - && blockTypes.Contains(bufferType2)) - { - blockPointerTypes.Add(pointerType, bufferType2); - } - else if (instruction.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)instruction) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } - && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) - { - var name = nameTable[bufferId]; - // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) - // Adjust for it - cbuffers.Add(bufferId, new(name)); - } + blockTypes.Add(bufferType); } - - // Semantic + else if (i.Op == Op.OpTypePointer + && ((OpTypePointer)i) is { Storageclass: StorageClass.Uniform, ResultId: var pointerType, Type: var bufferType2 } + && blockTypes.Contains(bufferType2)) { - if (instruction.Op == Op.OpDecorateString - && ((OpDecorateString)instruction) is + blockPointerTypes.Add(pointerType, bufferType2); + } + } + + // Semantic + { + if (i.Op == Op.OpDecorateString + && ((OpDecorateString)i) is + { + Target: int t, + Decoration: { - Target: int t, - Decoration: - { - Value: Decoration.UserSemantic, - Parameters: { } m - } + Value: Decoration.UserSemantic, + Parameters: { } m } - ) - { - using var n = new LiteralValue(m.Span); - semanticTable[t] = n.Value; } + ) + { + using var n = new LiteralValue(m.Span); + semanticTable[t] = n.Value; } } } @@ -526,6 +514,16 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // Analyze streams foreach (var i in buffer) { + if (i.Op == Op.OpVariableSDSL + && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) + { + var name = nameTable[bufferId]; + // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) + // Adjust for it + cbuffers.Add(bufferId, new(name)); + } + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Private, From d62abfae8324750a46997955c57337dc72c30a4f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 31 Dec 2025 18:41:44 +0900 Subject: [PATCH 0669/1182] Shaders: split buffer into context+buffer --- .../SDSL/EffectEvaluator.cs | 16 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 24 +- .../SDSL/ShaderMixer.cs | 271 +++++++++--------- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 2 +- .../Parsing/SDSL/AST/Literals.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 25 +- .../Spirv/Building/Builder.Class.cs | 44 ++- src/Stride.Shaders/Spirv/Building/Context.cs | 1 + 8 files changed, 209 insertions(+), 176 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index b2bcbbca64..e0576b3a3a 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -18,12 +18,12 @@ internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) public ShaderSource EvaluateEffects(ShaderSource source) { - object[] GetGenericsArguments(NewSpirvBuffer buffer, ReadOnlySpan genericIds) + object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds) { var genericArguments = new object[genericIds.Length]; for (int i = 0; i < genericArguments.Length; i++) { - genericArguments[i] = SpirvBuilder.GetConstantValue(genericIds[i], buffer); + genericArguments[i] = SpirvBuilder.GetConstantValue(genericIds[i], context.GetBuffer()); } return genericArguments; } @@ -32,30 +32,30 @@ object[] GetGenericsArguments(NewSpirvBuffer buffer, ReadOnlySpan genericId { case ShaderClassSource classSource: var macros = mixinSources.Count > 0 ? mixinSources.Peek().Macros : []; - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); + var shaderBuffers = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); - if (buffer[0].Op == Op.OpSDSLEffect) + if (shaderBuffers.Buffer[0].Op == Op.OpSDSLEffect) { var mixinTree = new ShaderMixinSource(); - foreach (var instruction in buffer) + foreach (var instruction in shaderBuffers.Buffer) { if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) { - var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(buffer, mixinInstruction.Values.Elements.Span)); + var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinInstruction.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); Merge(mixinTree, evaluatedSource); } else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) { - var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(buffer, mixinComposeInstruction.Values.Elements.Span)); + var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeInstruction.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); } else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) { - var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(buffer, mixinComposeArray.Values.Elements.Span)); + var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeArray.Values.Elements.Span)); var evaluatedSource = EvaluateEffects(instSource); MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 4221885669..13925d7c69 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -31,12 +31,12 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext foreach (var mixinToMerge in shaderMixinSource.Mixins) { - var buffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); + var shaderBuffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); - mixinToMerge2.Buffer = buffer; + mixinToMerge2.Buffer = shaderBuffer; // Copy back updated shader name (in case it had generic parameters) - foreach (var i in buffer) + foreach (var i in shaderBuffer.Buffer) { if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) { @@ -52,11 +52,18 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext foreach (var shaderName in mixinList.ToArray()) { - var shader = shaderName.Buffer; - ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + var shader = shaderName.Buffer.Value; + ShaderClass.ProcessNameAndTypes(shader.Context.GetBuffer(), 0, shader.Context.GetBuffer().Count, out var names, out var types); bool hasStage = false; - foreach (var i in shader) + foreach (var i in shader.Context) + { + if (i.Op == Op.OpTypeStruct) + { + hasStage = true; + } + } + foreach (var i in shader.Buffer) { if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { @@ -97,11 +104,6 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext { hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; } - - if (i.Op == Op.OpTypeStruct) - { - hasStage = true; - } } // If there are any stage variables, add class to root diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 02467a50a9..c560c98721 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -198,7 +198,7 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo throw new InvalidOperationException("importing stage-only methods/variables is only possible at the root mixin"); } - var shader = shaderClass.Buffer; + var shaderBuffers = shaderClass.Buffer.Value; var offset = context.Bound; var resourceGroupOffset = context.ResourceGroupBound; @@ -250,171 +250,174 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS var structTypes = new Dictionary(); // Copy instructions to main buffer - for (var index = 0; index < shader.Count; index++) + foreach (var shader in new[] { shaderBuffers.Context.GetBuffer(), shaderBuffers.Buffer }) { - var i = shader[index]; - - // Do we need to skip variable/functions? (depending on stage/non-stage) + for (var index = 0; index < shader.Count; index++) { - var include = true; - if (i.Op == Op.OpName) - { - OpName nameInstruction = i; - names.Add(nameInstruction.Target, nameInstruction.Name); - } - if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) - { - var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - // Note: BuildTypesAndMethodGroups has not been called for this mixin so context.Types/ReverseTypes is not filled - // However: - // - FunctionType is only required when looking for stage function - // - In that case, root stage mixin MergeMixinNode => BuildTypesAndMethodGroups would have been called for this function type - // - function type is already deduplicated (in this loop) - // So the lookup will work when it is necessary - - FunctionType? functionType = default; - // First, assuming FunctionType is a duplicate from a previous shader, we could find the already existing type by applying offset and remapIds - if (remapIds.TryGetValue(function.FunctionType + offset, out var remappedFunctionTypeId) - // Then, we can find the actual type in context.ReverseTypes - && context.ReverseTypes.TryGetValue(remappedFunctionTypeId, out var functionType2)) - functionType = (FunctionType)functionType2; - - include = ProcessStageMemberOrType(function.ResultId, functionType, isStage); - } - if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) - { - var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; - include = ProcessStageMemberOrType(variableInstruction.ResultId, null, isStage); - } - if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) - { - include = ProcessStageMemberOrType(typeStruct.ResultId, null, true); - } + var i = shader[index]; - if (!include) + // Do we need to skip variable/functions? (depending on stage/non-stage) { - // We store removed IDs for further OpName removals - if (i.Data.IdResult is int id) - removedIds.Add(offset + id); + var include = true; + if (i.Op == Op.OpName) + { + OpName nameInstruction = i; + names.Add(nameInstruction.Target, nameInstruction.Name); + } + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) + { + var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + // Note: BuildTypesAndMethodGroups has not been called for this mixin so context.Types/ReverseTypes is not filled + // However: + // - FunctionType is only required when looking for stage function + // - In that case, root stage mixin MergeMixinNode => BuildTypesAndMethodGroups would have been called for this function type + // - function type is already deduplicated (in this loop) + // So the lookup will work when it is necessary + + FunctionType? functionType = default; + // First, assuming FunctionType is a duplicate from a previous shader, we could find the already existing type by applying offset and remapIds + if (remapIds.TryGetValue(function.FunctionType + offset, out var remappedFunctionTypeId) + // Then, we can find the actual type in context.ReverseTypes + && context.ReverseTypes.TryGetValue(remappedFunctionTypeId, out var functionType2)) + functionType = (FunctionType)functionType2; + + include = ProcessStageMemberOrType(function.ResultId, functionType, isStage); + } + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) + { + var isStage = (variableInstruction.Flags & VariableFlagsMask.Stage) != 0; + include = ProcessStageMemberOrType(variableInstruction.ResultId, null, isStage); + } + if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStruct) + { + include = ProcessStageMemberOrType(typeStruct.ResultId, null, true); + } - // Special case for function: skip until function end - // (for other cases such as variable, skipping only current instruction is enough) - if (i.Op == Op.OpFunction) + if (!include) { - // Skip until end of function - while (shader[++index].Op != Op.OpFunctionEnd) + // We store removed IDs for further OpName removals + if (i.Data.IdResult is int id) + removedIds.Add(offset + id); + + // Special case for function: skip until function end + // (for other cases such as variable, skipping only current instruction is enough) + if (i.Op == Op.OpFunction) { - // We store removed IDs for further OpName removals - if (shader[index].Data.IdResult is int id2) - removedIds.Add(offset + id2); + // Skip until end of function + while (shader[++index].Op != Op.OpFunctionEnd) + { + // We store removed IDs for further OpName removals + if (shader[index].Data.IdResult is int id2) + removedIds.Add(offset + id2); + } } - } - // Go to next instruction - continue; + // Go to next instruction + continue; + } } - } - - var i2 = new OpData(i.Data.Memory.Span); - if (offset > 0) - OffsetIds(i2, offset); + var i2 = new OpData(i.Data.Memory.Span); - if (i2.IdResult != null) - context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); + if (offset > 0) + OffsetIds(i2, offset); - // ResourceGroupId: adjust offsets too - if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) - { - // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly - var n = new LiteralValue(m.Span); - n.Value += resourceGroupOffset; - resourceGroupIdDecorate.Decoration = new(resourceGroupIdDecorate.Decoration.Value, n.Words); - context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, n.Value + 1); - n.Dispose(); - } + if (i2.IdResult != null) + context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); - if (SpirvBuilder.ContainIds(forbiddenIds, i2)) - throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); + // ResourceGroupId: adjust offsets too + if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + { + // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly + var n = new LiteralValue(m.Span); + n.Value += resourceGroupOffset; + resourceGroupIdDecorate.Decoration = new(resourceGroupIdDecorate.Decoration.Value, n.Words); + context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, n.Value + 1); + n.Dispose(); + } - SpirvBuilder.RemapIds(remapIds, ref i2); + if (SpirvBuilder.ContainIds(forbiddenIds, i2)) + throw new InvalidOperationException($"Stage instruction {i.Data} references a non-stage ID"); - // Detect when we switch from context to main buffer - if (i2.Op == Op.OpSDSLShader) - { - isContext = false; - } + SpirvBuilder.RemapIds(remapIds, ref i2); - // Specific type instructions in context gets deduplicated before adding - bool addToContext = false; - if (TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i2.Op)) - { - // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) - if (i2.Op == Op.OpSDSLImportStruct && new OpSDSLImportStruct(ref i2) is { } importStruct) + // Detect when we switch from context to main buffer + if (i2.Op == Op.OpSDSLShader) { - var shaderName = globalContext.ExternalShaders[importStruct.Shader]; - var shader2 = mixinNode.ShadersByName[shaderName]; - if (!shader2.StructTypes.TryGetValue(importStruct.StructName, out var structId) - && (shader2.Stage == null || !shader2.Stage.StructTypes.TryGetValue(importStruct.StructName, out structId))) - throw new InvalidOperationException($"Struct {importStruct.StructName} not found in shader {shaderName}"); - remapIds.Add(importStruct.ResultId, structId); - removedIds.Add(structId); + isContext = false; } - else + + // Specific type instructions in context gets deduplicated before adding + bool addToContext = false; + if (TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i2.Op)) { - // Check if type already exists in context (deduplicate them) - if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) + // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) + if (i2.Op == Op.OpSDSLImportStruct && new OpSDSLImportStruct(ref i2) is { } importStruct) { - if (i2.IdResult is int id) - { - remapIds.Add(id, existingInstruction.Data.IdResult.Value); - removedIds.Add(existingInstruction.Data.IdResult.Value); - } + var shaderName = globalContext.ExternalShaders[importStruct.Shader]; + var shader2 = mixinNode.ShadersByName[shaderName]; + if (!shader2.StructTypes.TryGetValue(importStruct.StructName, out var structId) + && (shader2.Stage == null || !shader2.Stage.StructTypes.TryGetValue(importStruct.StructName, out structId))) + throw new InvalidOperationException($"Struct {importStruct.StructName} not found in shader {shaderName}"); + remapIds.Add(importStruct.ResultId, structId); + removedIds.Add(structId); } else { - addToContext = true; + // Check if type already exists in context (deduplicate them) + if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) + { + if (i2.IdResult is int id) + { + remapIds.Add(id, existingInstruction.Data.IdResult.Value); + removedIds.Add(existingInstruction.Data.IdResult.Value); + } + } + else + { + addToContext = true; + } } } - } - // Does this belong in context or buffer? - else if (isContext) - { - addToContext = true; - } - else - { - buffer.Add(i2); - } - - // OpTypeStruct is the only type that can be defined by the shader. - // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. - if (i2.Op == Op.OpTypeStruct && new OpTypeStruct(ref i2) is { } typeStruct2) - { - var structName = names[typeStruct2.ResultId - offset]; - if (!remapIds.TryGetValue(typeStruct2.ResultId, out var structId)) - structId = typeStruct2.ResultId; - structTypes.Add(structName, structId); - } - - // Process OpSDSLImport - ProcessImportInfo(globalContext, mixinNode, ref i2, context.GetBuffer()); + // Does this belong in context or buffer? + else if (isContext) + { + addToContext = true; + } + else + { + buffer.Add(i2); + } - if (addToContext) - { - // OpName and such: check if associated instruction has not been removed - if (i2.Op == Op.OpName || i2.Op == Op.OpDecorate || i2.Op == Op.OpDecorateString - || i2.Op == Op.OpMemberName || i2.Op == Op.OpMemberDecorate || i2.Op == Op.OpMemberDecorateString) + // OpTypeStruct is the only type that can be defined by the shader. + // In case it's deduplicated (i.e. used in two separate mixin nodes), we still want to have it in shaderInfo.StructTypes, so let's save it aside now. + if (i2.Op == Op.OpTypeStruct && new OpTypeStruct(ref i2) is { } typeStruct2) { - // Target/Structure ID is always stored in first operand for all those instructions - var target = i2.Memory.Span[1]; - if (removedIds.Contains(target)) - addToContext = false; + var structName = names[typeStruct2.ResultId - offset]; + if (!remapIds.TryGetValue(typeStruct2.ResultId, out var structId)) + structId = typeStruct2.ResultId; + structTypes.Add(structName, structId); } + // Process OpSDSLImport + ProcessImportInfo(globalContext, mixinNode, ref i2, context.GetBuffer()); + if (addToContext) { - var i2Index = context.GetBuffer().Add(i2); + // OpName and such: check if associated instruction has not been removed + if (i2.Op == Op.OpName || i2.Op == Op.OpDecorate || i2.Op == Op.OpDecorateString + || i2.Op == Op.OpMemberName || i2.Op == Op.OpMemberDecorate || i2.Op == Op.OpMemberDecorateString) + { + // Target/Structure ID is always stored in first operand for all those instructions + var target = i2.Memory.Span[1]; + if (removedIds.Contains(target)) + addToContext = false; + } + + if (addToContext) + { + var i2Index = context.GetBuffer().Add(i2); + } } } } diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 2f45b7e6fb..1f29af16ee 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -23,8 +23,8 @@ public override string ToString() public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - context.GetBuffer().Add(new OpSDSLEffect(Name.Name)); + compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); foreach (var statement in Members) { statement.Compile(table, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 9c99284d40..31401d26f7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -302,7 +302,7 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref } if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) - throw new InvalidOperationException("Streams member used without an base type"); + throw new InvalidOperationException($"Streams member {Name} used without an object"); Type = symbol.Type; return EmitSymbol(buffer, ref position, context, symbol, constantOnly); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 2b185ba32d..fa6315257e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -71,7 +71,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } else if (instruction.Op == Op.OpDecorate) { - OpDecorate decorateInstruction = instruction; + var decorateInstruction = new OpDecorate(instruction); if (decorateInstruction.Decoration.Value == Decoration.Block) blocks.Add(decorateInstruction.Target); } @@ -162,6 +162,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } else if (instruction.Op == Op.OpTypeFunctionSDSL && new OpTypeFunctionSDSL(instruction) is { } typeFunctionInstruction) { + var tmp = new OpTypeFunction(instruction); var returnType = types[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); foreach (var operand in typeFunctionInstruction.Values) @@ -260,16 +261,24 @@ public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer } } - private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, ShaderClassInstantiation classSource) + private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, ShaderBuffers shaderBuffers, ShaderClassInstantiation classSource) { - ProcessNameAndTypes(buffer, 0, buffer.Count, out var names, out var types, new ShaderImporter(table, context)); + ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types, new ShaderImporter(table, context)); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); var structTypes = new List<(StructuredType Type, int ImportedId)>(); - for (var index = 0; index < buffer.Count; index++) + + foreach (var i in shaderBuffers.Context) + { + if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStructInstruction) + { + structTypes.Add(((StructuredType)types[typeStructInstruction.ResultId], -1)); + } + } + for (var index = 0; index < shaderBuffers.Buffer.Count; index++) { - var instruction = buffer[index]; + var instruction = shaderBuffers.Buffer[index]; if (instruction.Op == Op.OpVariableSDSL && (OpVariableSDSL)instruction is { } variable && variable.Storageclass != Specification.StorageClass.Function) { @@ -284,7 +293,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte if (instruction.Op == Op.OpFunction) { var functionFlags = FunctionFlagsMask.None; - if (buffer[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)buffer[index + 1] is { } functionInfo) + if (shaderBuffers.Buffer[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shaderBuffers.Buffer[index + 1] is { } functionInfo) functionFlags = functionInfo.Flags; OpFunction functionInstruction = instruction; @@ -303,7 +312,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte // Build full inheritance list List inheritanceList = new(); - SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), buffer, inheritanceList, ResolveStep.Compile); + SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context.GetBuffer(), inheritanceList, ResolveStep.Compile); // Load all the inherited shaders List inheritedShaderSymbols = new(); @@ -580,7 +589,7 @@ public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, Spirv { var shaderBuffer = classSource.Buffer; - var shaderType = CreateShaderType(table, context, shaderBuffer, classSource); + var shaderType = CreateShaderType(table, context, shaderBuffer.Value, classSource); RegisterShaderType(table, shaderType); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index fcf60c7531..cda4c1a550 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -23,6 +23,8 @@ namespace Stride.Shaders.Spirv.Building; public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); +public record struct ShaderBuffers(SpirvContext Context, NewSpirvBuffer Buffer); + public enum ResolveStep { Compile, @@ -31,7 +33,7 @@ public enum ResolveStep public record class ShaderClassInstantiation(string ClassName, int[] GenericArguments, bool ImportStageOnly = false) : IEquatable { - public NewSpirvBuffer Buffer { get; set; } + public ShaderBuffers? Buffer { get; set; } public string ClassName { get; set; } = ClassName; @@ -102,12 +104,12 @@ public override string ToString() public partial class SpirvBuilder { - public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer buffer, List inheritanceList, ResolveStep resolveStep) + public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer contextBuffer, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping var shaderMapping = new Dictionary(); var genericParameterRemapping = new Dictionary(); - foreach (var i in buffer) + foreach (var i in contextBuffer) { if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { @@ -115,7 +117,7 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - var shaderClassSource = ConvertToShaderClassSource(buffer, 0, buffer.Count, importShader); + var shaderClassSource = ConvertToShaderClassSource(contextBuffer, 0, contextBuffer.Count, importShader); shaderMapping[importShader.ResultId] = shaderClassSource; } @@ -127,7 +129,7 @@ int RemapGenericParameter(int localGeneric) return generic; // Otherwise, assume it's a constsant we need to import - var constantBuffer = ExtractConstantAsSpirvBuffer(buffer, localGeneric); + var constantBuffer = ExtractConstantAsSpirvBuffer(contextBuffer, localGeneric); int index = context.GetBuffer().Count; var bound = context.Bound; var resultId = InsertBufferWithoutDuplicates(context.GetBuffer(), ref index, ref bound, null, constantBuffer); @@ -137,7 +139,7 @@ int RemapGenericParameter(int localGeneric) } // Check inheritance - foreach (var i in buffer) + foreach (var i in contextBuffer) { if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { @@ -175,7 +177,7 @@ public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExtern index = inheritanceList.IndexOf(classSource); if (index == -1) { - BuildInheritanceListWithoutSelf(shaderLoader, context, classSource, macros, classSource.Buffer, inheritanceList, resolveStep); + BuildInheritanceListWithoutSelf(shaderLoader, context, classSource, macros, classSource.Buffer.Value.Context.GetBuffer(), inheritanceList, resolveStep); index = inheritanceList.Count; inheritanceList.Add(classSource); } @@ -892,26 +894,27 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) /// /// /// - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, SpirvContext context) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, SpirvContext context) { return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context.GetBuffer()), macros); } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) { return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, declaringBuffer), macros); } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) { return GetOrLoadShader(shaderLoader, className, new GenericResolverFromValues(genericValues), macros); } - - private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) + private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); + // Split context and buffer + //if (!isFromCache) // Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -926,7 +929,22 @@ private static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } - return shader; + var context = new SpirvContext(); + var buffer = new NewSpirvBuffer(); + var isContext = true; + foreach (var i in shader) + { + // Find when switching from context to actual shader/effect + if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLEffect) + isContext = false; + + if (isContext) + context.GetBuffer().Add(i.Data); + else + buffer.Add(i.Data); + } + + return new ShaderBuffers(context, buffer); } public static NewSpirvBuffer CopyShader(NewSpirvBuffer shader) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 15cdac0eab..50183e70ce 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -29,6 +29,7 @@ public class SpirvContext public int Bound { get; set; } = 1; public Dictionary Types { get; } = []; public Dictionary ReverseTypes { get; } = []; + public Dictionary Names { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; NewSpirvBuffer Buffer { get; set; } = new(); From 06ed10825980b5877df034fc08993afb7a9bfcc7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 31 Dec 2025 18:53:04 +0900 Subject: [PATCH 0670/1182] Context: Removed MixinGlobalContext.Names/Types (use SpirvContext instead) --- .../SDSL/ShaderMixer.CBuffers.cs | 9 ++-- .../SDSL/ShaderMixer.ShaderInfo.cs | 12 ++--- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 7 ++- .../SDSL/ShaderMixer.cs | 49 +++++++------------ src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 29 ++++++++--- 5 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 8b6ccfdedd..2d97aa3144 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -74,7 +74,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex LogicalGroup: GetCBufferLogicalGroup(x.Variable.Data.IdResult.Value))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) - .GroupBy(x => ShaderClass.GetCBufferRealName(globalContext.Names[x.Variable.Data.IdResult.Value])); + .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.Variable.Data.IdResult.Value])); var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); @@ -136,7 +136,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // In all cases, we update name to one without .0 .1 suffix // (we do it even for case count == 1 because all buffer except one might have been optimized away) - globalContext.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; + context.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; if (cbuffersEntry.Count() == 1) { @@ -160,9 +160,6 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); - globalContext.Types.Add(mergedCbufferStructId, mergedCbufferStruct); - globalContext.Types.Add(mergedCbufferPtrStructId, mergedCbufferPtrStruct); - ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); // Remap member ids @@ -375,7 +372,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription { - Name = globalContext.Names[cbuffer.Variable.Data.IdResult.Value], + Name = context.Names[cbuffer.Variable.Data.IdResult.Value], // Round buffer size to next multiple of 16 bytes Size = (constantBufferOffset + 15) / 16 * 16, diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 1368d30477..c80ae4a393 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -56,7 +56,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } - private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer context, int contextStart, int contextEnd, NewSpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext context, int contextStart, int contextEnd, NewSpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) { var removedIds = new HashSet(); for (var index = shaderStart; index < shaderEnd; index++) @@ -65,16 +65,16 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - var functionName = globalContext.Names[function.ResultId]; - var functionType = (FunctionType)globalContext.Types[function.FunctionType]; + var functionName = context.Names[function.ResultId]; + var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; if (!shaderInfo!.Functions.TryGetValue(functionName, out var functions)) shaderInfo.Functions.Add(functionName, functions = new()); functions.Add((function.ResultId, functionType)); } else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) { - var variableName = globalContext.Names[variable.ResultId]; - var variableType = globalContext.Types[variable.ResultType]; + var variableName = context.Names[variable.ResultId]; + var variableType = context.ReverseTypes[variable.ResultType]; shaderInfo!.Variables.Add(variableName, (variable.ResultId, variableType)); // Remove SPIR-V variables to other shaders (already stored in ShaderInfo and not valid SPIR-V) @@ -89,7 +89,7 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, NewSpirvBuffer // Second pass to remove OpName for (var index = contextStart; index < contextEnd; index++) { - var i = context[index]; + var i = context.GetBuffer()[index]; if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 13925d7c69..af56320695 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -53,8 +53,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext foreach (var shaderName in mixinList.ToArray()) { var shader = shaderName.Buffer.Value; - ShaderClass.ProcessNameAndTypes(shader.Context.GetBuffer(), 0, shader.Context.GetBuffer().Count, out var names, out var types); - + ShaderClass.ProcessNameAndTypes(shader.Context); bool hasStage = false; foreach (var i in shader.Context) { @@ -69,10 +68,10 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext { hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; - var variableType = types[variable.ResultType]; + var variableType = shader.Context.ReverseTypes[variable.ResultType]; if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol or ArrayType { BaseType: ShaderSymbol }) { - var variableName = names[variable.ResultId]; + var variableName = shader.Context.Names[variable.ResultId]; // Make sure we have a ShaderMixinSource // If composition is not specified, use default class if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index c560c98721..df4f86da07 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -44,7 +44,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect var globalContext = new MixinGlobalContext(); // Process name and types imported by constants due to generics instantiation - ShaderClass.ProcessNameAndTypes(context.GetBuffer(), 0, context.GetBuffer().Count, globalContext.Names, globalContext.Types); + ShaderClass.ProcessNameAndTypes(context); var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); @@ -94,9 +94,6 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect class MixinGlobalContext { - public Dictionary Names { get; } = []; - public Dictionary Types { get; } = []; - public EffectReflection Reflection { get; } = new(); public Dictionary ExternalShaders { get; } = new(); @@ -182,8 +179,8 @@ private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext mixinNode.Shaders.Add(shaderInfo); // Note: we process name, types and struct right away, as they might be needed by the next Shader - ShaderClass.ProcessNameAndTypes(context.GetBuffer(), contextStart, context.GetBuffer().Count, globalContext.Names, globalContext.Types); - PopulateShaderInfo(globalContext, context.GetBuffer(), contextStart, context.GetBuffer().Count, buffer, shaderInfo.StartInstruction, shaderInfo.EndInstruction, shaderInfo, mixinNode); + ShaderClass.ProcessNameAndTypes(context, contextStart, context.GetBuffer().Count); + PopulateShaderInfo(globalContext, context, contextStart, context.GetBuffer().Count, buffer, shaderInfo.StartInstruction, shaderInfo.EndInstruction, shaderInfo, mixinNode); } mixinNode.EndInstruction = buffer.Count; @@ -470,24 +467,14 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, MixinNode mixinNode) { - // Setup types in context - foreach (var type in globalContext.Types) - { - if (!context.ReverseTypes.ContainsKey(type.Key)) - { - context.Types.Add(type.Value, type.Key); - context.ReverseTypes.Add(type.Key, type.Value); - } - } - // Add symbol for each method in current type (equivalent to implicit this pointer) for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = temp[index]; if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - var functionName = globalContext.Names[function.ResultId]; - var symbol = new Symbol(new(functionName, SymbolKind.Method), globalContext.Types[function.FunctionType], function.ResultId); + var functionName = context.Names[function.ResultId]; + var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId); table.CurrentFrame.Add(functionName, symbol); } } @@ -512,7 +499,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { - var functionName = globalContext.Names[function.ResultId]; + var functionName = context.Names[function.ResultId]; var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; var methodMixinGroup = mixinNode; @@ -540,8 +527,8 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; // Also add lookup by name - if (!methodMixinGroup.MethodGroupsByName.TryGetValue((functionName, functionType), out var methodGroups)) - methodMixinGroup.MethodGroupsByName.Add((functionName, functionType), function.ResultId); + if (!methodMixinGroup.MethodGroupsByName.TryGetValue(new(functionName, functionType), out var methodGroups)) + methodMixinGroup.MethodGroupsByName.Add(new(functionName, functionType), function.ResultId); // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) @@ -608,7 +595,7 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext if (i.IdResult is int result) { // Also duplicate name (if any) - if (globalContext.Names.TryGetValue(result, out var name)) + if (context.Names.TryGetValue(result, out var name)) context.AddName(context.Bound, name); idRemapping.Add(result, context.Bound++); } @@ -731,7 +718,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } memberAccesses.Add(memberAccess.ResultId, variableInfo.Id); } - else if (globalContext.Types[memberAccess.ResultType] is FunctionType functionType) + else if (context.ReverseTypes[memberAccess.ResultType] is FunctionType functionType) { // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL var functionId = memberAccess.Member; @@ -744,7 +731,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte { // Try again as a stage method (only if not a base call) if (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroups.TryGetValue(functionId, out methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[functionId]}"); + throw new InvalidOperationException($"Can't find method group info for {context.Names[functionId]}"); foundInStage = true; } @@ -757,7 +744,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte // We currently do not allow calling base stage method from a non-stage method // (if we were to allow them later, we would need to tweak following detection code as ShaderIndex comparison is only valid for items within the same MixinNode) if (foundInStage) - throw new InvalidOperationException($"Method {globalContext.Names[functionId]} was found but a base call can't be performed on a stage method from a non-stage method"); + throw new InvalidOperationException($"Method {context.Names[functionId]} was found but a base call can't be performed on a stage method from a non-stage method"); // Is it a base call? if yes, find the direct parent // Let's find the method in same group just before ours @@ -773,11 +760,11 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } if (!baseMethodFound) - throw new InvalidOperationException($"Can't find a base method for {globalContext.Names[functionId]}"); + throw new InvalidOperationException($"Can't find a base method for {context.Names[functionId]}"); } if ((selectedMethod.Flags & FunctionFlagsMask.Abstract) != 0) - throw new InvalidOperationException($"Trying to call an abstract method {selectedMethod.Shader.ShaderName}.{globalContext.Names[functionId]}"); + throw new InvalidOperationException($"Trying to call an abstract method {selectedMethod.Shader.ShaderName}.{context.Names[functionId]}"); functionId = selectedMethod.MethodId; memberAccesses.Add(memberAccess.ResultId, functionId); @@ -792,7 +779,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function && temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) - throw new InvalidOperationException($"Can't find method group info for {globalContext.Names[function.ResultId]}"); + throw new InvalidOperationException($"Can't find method group info for {context.Names[function.ResultId]}"); } else if (i.Data.Op == Op.OpFunctionEnd) { @@ -828,7 +815,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { Storageclass: Specification.StorageClass.UniformConstant } variable) { // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore - var type = globalContext.Types[variable.ResultType]; + var type = context.ReverseTypes[variable.ResultType]; if (type is not ConstantBufferSymbol) prefixes[variable.ResultId] = shaderNameWithComposition; } @@ -855,7 +842,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont // Now, make sure it's all valid HLSL/GLSL characters (this will replace multiple invalid characters with a single underscore) // Otherwise, EffectReflection RawName won't match updatedName = SpirvBuilder.RemoveInvalidCharactersFromSymbol(updatedName); - globalContext.Names[name.Target] = updatedName; + context.Names[name.Target] = updatedName; } } } @@ -977,7 +964,7 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon var type = context.ReverseTypes[variable.ResultType]; if (type is PointerType pointerType) { - var name = globalContext.Names[variable.ResultId]; + var name = context.Names[variable.ResultId]; linkInfos.TryGetValue(variable.ResultId, out var linkInfo); var linkName = linkInfo.LinkName ?? $"{TypeName.GetTypeNameWithoutGenerics(currentShaderName)}.{name}"; if (mixinNode.CompositionPath != null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index fa6315257e..7190557f51 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -49,6 +49,21 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end ProcessNameAndTypes(buffer, start, end, names, types, shaderImporter); } + public static void ProcessNameAndTypes(SpirvContext context, int start, int end, IShaderImporter? shaderImporter = null) + { + ProcessNameAndTypes(context.GetBuffer(), start, end, context.Names, context.ReverseTypes, shaderImporter); + foreach (var type in context.ReverseTypes) + { + if (!context.Types.ContainsKey(type.Value)) + context.Types.Add(type.Value, type.Key); + } + } + + public static void ProcessNameAndTypes(SpirvContext context, IShaderImporter? shaderImporter = null) + { + ProcessNameAndTypes(context, 0, context.GetBuffer().Count, shaderImporter); + } + public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types, IShaderImporter? shaderImporter = null) { var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); @@ -263,7 +278,7 @@ public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, ShaderBuffers shaderBuffers, ShaderClassInstantiation classSource) { - ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types, new ShaderImporter(table, context)); + ProcessNameAndTypes(shaderBuffers.Context, new ShaderImporter(table, context)); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); @@ -273,7 +288,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte { if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } typeStructInstruction) { - structTypes.Add(((StructuredType)types[typeStructInstruction.ResultId], -1)); + structTypes.Add(((StructuredType)shaderBuffers.Context.ReverseTypes[typeStructInstruction.ResultId], -1)); } } for (var index = 0; index < shaderBuffers.Buffer.Count; index++) @@ -282,9 +297,9 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte if (instruction.Op == Op.OpVariableSDSL && (OpVariableSDSL)instruction is { } variable && variable.Storageclass != Specification.StorageClass.Function) { - if (!names.TryGetValue(variable.ResultId, out var variableName)) + if (!shaderBuffers.Context.Names.TryGetValue(variable.ResultId, out var variableName)) variableName = $"_{variable.ResultId}"; - var variableType = types[variable.ResultType]; + var variableType = shaderBuffers.Context.ReverseTypes[variable.ResultType]; var sid = new SymbolID(variableName, SymbolKind.Variable, variable.Flags.HasFlag(VariableFlagsMask.Stream) ? Storage.Stream : 0, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); variables.Add((new(sid, variableType, 0), variable.Flags)); @@ -297,8 +312,8 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte functionFlags = functionInfo.Flags; OpFunction functionInstruction = instruction; - var functionName = names[functionInstruction.ResultId]; - var functionType = types[functionInstruction.FunctionType]; + var functionName = shaderBuffers.Context.Names[functionInstruction.ResultId]; + var functionType = shaderBuffers.Context.ReverseTypes[functionInstruction.FunctionType]; var sid = new SymbolID(functionName, SymbolKind.Method, IsStage: (functionFlags & FunctionFlagsMask.Stage) != 0); methods.Add((new(sid, functionType, 0), functionFlags)); @@ -306,7 +321,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { - structTypes.Add(((StructuredType)types[typeStructInstruction.ResultId], -1)); + structTypes.Add(((StructuredType)shaderBuffers.Context.ReverseTypes[typeStructInstruction.ResultId], -1)); } } From 9ccd2dd822f5cc50d390de57c2489c99188f24d7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 00:10:40 +0900 Subject: [PATCH 0671/1182] Use SpirvContext in generics instantiation code --- .../Spirv/Building/Builder.Class.cs | 122 ++++++++++-------- src/Stride.Shaders/Spirv/Building/Context.cs | 12 +- 2 files changed, 81 insertions(+), 53 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index cda4c1a550..39aa211eb0 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -374,7 +374,7 @@ abstract class GenericResolver public abstract bool NeedsResolve(); public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value); - public abstract bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue); + public abstract bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue); public virtual void PostProcess(string classNameWithGenerics, List genericParameters) { @@ -440,7 +440,7 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i if (desiredResultId != null && lastResultId != desiredResultId) { // Need to remap all existing references - RemapIds(target, 0, target.Count, new Dictionary { { desiredResultId.Value, lastResultId } }); + RemapIds(target, 0, target.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); } return lastResultId; @@ -475,9 +475,10 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str } } - public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue) + public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - var genericParameter = (OpSDSLGenericParameter)buffer[instructionIndex]; + var contextBuffer = context.GetBuffer(); + var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; var genericValue = genericValues![genericIndex]; textValue = genericValue; switch (genericParameterType) @@ -489,14 +490,14 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType throw new InvalidOperationException("Can't parse generic value"); var localContext = new SpirvContext(); var result = expression.CompileConstantValue(new SymbolTable(localContext), localContext, genericParameterType); - buffer.RemoveAt(instructionIndex); - var bound = buffer.Header.Bound; - SpirvBuilder.InsertBufferWithoutDuplicates(buffer, ref instructionIndex, ref bound, genericParameter.ResultId, localContext.GetBuffer()); - buffer.Header = buffer.Header with { Bound = bound }; + contextBuffer.RemoveAt(instructionIndex); + var bound = context.Bound; + SpirvBuilder.InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, localContext.GetBuffer()); + context.Bound = bound; instructionIndex--; return true; case GenericParameterType g: - buffer.Replace(instructionIndex, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + contextBuffer.Replace(instructionIndex, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); return true; default: throw new NotImplementedException(); @@ -534,8 +535,9 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str return true; } - public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, NewSpirvBuffer buffer, ref int instructionIndex, out string textValue) + public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { + var contextBuffer = context.GetBuffer(); // Check if generic value can already be computed (no OpSDSLGenericParameter and such) if (TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, declaringBuffer, false)) { @@ -547,7 +549,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType textValue = GetIdRefAsString(genericIndex); } - var genericParameter = (OpSDSLGenericParameter)buffer[instructionIndex]; + var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; var bufferWithConstant = ExtractConstantAsSpirvBuffer(declaringBuffer, classSource.GenericArguments[genericIndex]); bool resolved = true; @@ -564,12 +566,12 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType } } - buffer.RemoveAt(instructionIndex); + contextBuffer.RemoveAt(instructionIndex); // TODO: Try to simplify constant - var bound = buffer.Header.Bound; - int resultId = InsertBufferWithoutDuplicates(buffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); - buffer.Header = buffer.Header with { Bound = bound }; + var bound = contextBuffer.Header.Bound; + int resultId = InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); + contextBuffer.Header = contextBuffer.Header with { Bound = bound }; // Since we removed one instruction earlier, adjust for it so that next loop process just after what has just been added instructionIndex--; @@ -595,23 +597,22 @@ public override void PostProcess(string classNameWithGenerics, List macros) + private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, string className, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) { - ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); + ShaderClass.ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types); var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); var genericParameters = new List(); - for (int index = 0; index < shader.Count; ++index) + for (int index = 0; index < shaderBuffers.Context.GetBuffer().Count; ++index) { - var i = shader[index]; - + var i = shaderBuffers.Context.GetBuffer()[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { var genericParameterType = types[genericParameter.ResultType]; var genericParameterName = names[genericParameter.ResultId]; - var resolved = genericResolver.ResolveGenericValueInBuffer(genericParameterType, genericParameterName, genericParameters.Count, shader, ref index, out var textValue); + var resolved = genericResolver.ResolveGenericValueInBuffer(genericParameterType, genericParameterName, genericParameters.Count, shaderBuffers.Context, ref index, out var textValue); genericParameters.Add(new(genericParameterType, genericParameter.ResultId, genericParameter.ResultType, i.Index, genericParameterName, resolved, textValue)); switch (genericParameterType) @@ -628,9 +629,9 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant) - if (!TryGetInstructionById(typeArray.Length, out var lengthInstruction, shader)) + if (!TryGetInstructionById(typeArray.Length, out var lengthInstruction, shaderBuffers.Context.GetBuffer())) throw new InvalidOperationException(); - if (lengthInstruction.Op != Op.OpConstant && TryGetConstantValue(typeArray.Length, out var value, out _, shader, true)) + if (lengthInstruction.Op != Op.OpConstant && TryGetConstantValue(typeArray.Length, out var value, out _, shaderBuffers.Context.GetBuffer(), true)) { } } @@ -652,7 +653,7 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class classNameWithGenericsBuilder.Append(">"); var classNameWithGenerics = classNameWithGenericsBuilder.ToString(); - foreach (var i in shader) + foreach (var i in shaderBuffers.Buffer) { if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) { @@ -660,17 +661,17 @@ private static void InstantiateGenericShader(NewSpirvBuffer shader, string class } } - TransformResolvedSemantics(shader, semantics); - TransformResolvedLinkIdIntoLinkString(shader, resolvedLinks); + TransformResolvedSemantics(shaderBuffers.Context.GetBuffer(), semantics); + TransformResolvedLinkIdIntoLinkString(shaderBuffers.Context.GetBuffer(), resolvedLinks); genericResolver.PostProcess(classNameWithGenerics, genericParameters); } - private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary semantics) + private static void TransformResolvedSemantics(NewSpirvBuffer contextBuffer, Dictionary semantics) { - for (var index = 0; index < shader.Count; index++) + for (var index = 0; index < contextBuffer.Count; index++) { - var i = shader[index]; + var i = contextBuffer[index]; if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m } } decorate) { var n = new LiteralValue(m.Span); @@ -694,12 +695,12 @@ private static void TransformResolvedSemantics(NewSpirvBuffer shader, Dictionary } } - private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, string shaderName, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) + private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, string shaderName, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) { bool hasUnresolvableShader = false; - for (var index = 0; index < shader.Count; index++) + for (var index = 0; index < shaderBuffers.Buffer.Count; index++) { - var i = shader[index]; + var i = shaderBuffers.Buffer[index]; if (i.Op == Op.OpUnresolvableShaderSDSL && (OpUnresolvableShaderSDSL)i is { } unresolvableShader) { hasUnresolvableShader = true; @@ -707,14 +708,13 @@ private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, stri } if (!hasUnresolvableShader) - return shader; + return; var instantiatedGenericsMacros = new List<(string Name, string Definition)>(); var genericParameterIndex = 0; - ShaderClass.ProcessNameAndTypes(shader, 0, shader.Count, out var names, out var types); - for (var index = 0; index < shader.Count; index++) + ShaderClass.ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types); + foreach (var i in shaderBuffers.Context) { - var i = shader[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { var genericParameterName = names[genericParameter.ResultId]; @@ -726,7 +726,10 @@ private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, stri } genericParameterIndex++; } - else if (i.Op == Op.OpUnresolvableShaderSDSL && (OpUnresolvableShaderSDSL)i is { } unresolvableShader) + } + foreach (var i in shaderBuffers.Buffer) + { + if (i.Op == Op.OpUnresolvableShaderSDSL && (OpUnresolvableShaderSDSL)i is { } unresolvableShader) { var code = unresolvableShader.ShaderCode; if (instantiatedGenericsMacros.Count > 0) @@ -744,27 +747,26 @@ private static NewSpirvBuffer InstantiateMemberNames(NewSpirvBuffer shader, stri + MonoGamePreProcessor.Run(code.Substring(unresolvableShader.ShaderCodeNameEnd), $"{shaderName}.sdsl", CollectionsMarshal.AsSpan(instantiatedGenericsMacros)); } - if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shader, out _)) + if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out var shader, out _)) throw new InvalidOperationException(); - return shader; + + shaderBuffers = CreateShaderBuffers(shader); } } - - return shader; } - private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, Dictionary resolvedLinks) + private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer contextBuffer, Dictionary resolvedLinks) { // Try to resolve LinkType generics - for (var index = 0; index < shader.Count; index++) + for (var index = 0; index < contextBuffer.Count; index++) { - var i = shader[index]; + var i = contextBuffer[index]; if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) { using var n = new LiteralValue(m.Span); if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) { - shader.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + contextBuffer.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m2 } } linkDecorate2) @@ -772,7 +774,7 @@ private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer shader, using var n = new LiteralValue(m2.Span); if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) { - shader.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + contextBuffer.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } } @@ -913,6 +915,8 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, { var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); + var shaderBuffers = CreateShaderBuffers(shader); + // Split context and buffer //if (!isFromCache) @@ -920,15 +924,23 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, if (genericResolver.NeedsResolve()) { - shader = InstantiateMemberNames(shader, className, genericResolver, shaderLoader, macros); + InstantiateMemberNames(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - // Copy shader - shader = CopyShader(shader); + shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) { Bound = shader.Header.Bound }; + shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); - InstantiateGenericShader(shader, className, genericResolver, shaderLoader, macros); + InstantiateGenericShader(ref shaderBuffers, className, genericResolver, shaderLoader, macros); //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + + shaderBuffers.Context.GetBuffer().Header = shaderBuffers.Context.GetBuffer().Header with { Bound = shaderBuffers.Context.Bound }; + shaderBuffers.Buffer.Header = shaderBuffers.Buffer.Header with { Bound = shaderBuffers.Context.Bound }; } + return shaderBuffers; + } + + private static ShaderBuffers CreateShaderBuffers(NewSpirvBuffer shader) + { var context = new SpirvContext(); var buffer = new NewSpirvBuffer(); var isContext = true; @@ -944,10 +956,16 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, buffer.Add(i.Data); } - return new ShaderBuffers(context, buffer); + context.GetBuffer().Header = shader.Header; + buffer.Header = shader.Header; + + context.Bound = shader.Header.Bound; + + var shaderBuffers = new ShaderBuffers(context, buffer); + return shaderBuffers; } - public static NewSpirvBuffer CopyShader(NewSpirvBuffer shader) + public static NewSpirvBuffer CopyBuffer(NewSpirvBuffer shader) { var copiedShader = new NewSpirvBuffer(); foreach (var i in shader) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 50183e70ce..6e4c5368d1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -31,10 +31,20 @@ public class SpirvContext public Dictionary ReverseTypes { get; } = []; public Dictionary Names { get; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; - NewSpirvBuffer Buffer { get; set; } = new(); + NewSpirvBuffer Buffer { get; init; } public int? GLSLSet { get; private set; } + public SpirvContext() + { + Buffer = new(); + } + + public SpirvContext(NewSpirvBuffer buffer) + { + Buffer = buffer; + } + public void ImportGLSL() { foreach(var i in Buffer) From aa50ce5a7babb066b3145646c7744c0c8e3281fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 18:29:10 +0900 Subject: [PATCH 0672/1182] Rearrange InsertBufferWithoutDuplicates to better respect desiredResultId --- .../Spirv/Building/Builder.Class.cs | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 39aa211eb0..7b885a808f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -387,6 +387,19 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i var typeDuplicateInserter = new TypeDuplicateHelper(target); var remapIds = new Dictionary(); int lastResultId = -1; + + var lastResultIndex = -1; + if (desiredResultId != null) + { + // Find last index returning a value (that's the value we want remapped to desiredResultId) + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + if (i.Data.IdResult is not null) + lastResultIndex = index; + } + } + for (int index = 0; index < source.Count; ++index) { var i = source[index]; @@ -397,10 +410,10 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i if (isGenericReference) i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; - // Note: we also try to avoid duplciate for constants (which should have been resolved) - // otherwise a generic type might have 2 different instantiation with same parameters - if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData)) + // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || isGenericReference) + && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) + && (index != lastResultIndex || desiredResultId == null)) { // Make sure this data is declared at current index, otherwise move it. // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops @@ -421,7 +434,7 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i if (i.Data.IdResult.HasValue) { // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID - var resultId = index == source.Count - 1 && desiredResultId != null + var resultId = index == lastResultIndex && desiredResultId != null ? desiredResultId.Value : bound++; @@ -437,11 +450,9 @@ public static int InsertBufferWithoutDuplicates(NewSpirvBuffer target, ref int i if (lastResultId == -1) throw new InvalidOperationException("Could not find any instruction with a value"); + // Note: we made sure to not copy last instruction which should have the constant we want if (desiredResultId != null && lastResultId != desiredResultId) - { - // Need to remap all existing references - RemapIds(target, 0, target.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); - } + throw new InvalidOperationException(); return lastResultId; } From 453c7bee8cf51c1153fdc40b3cad5ae6a8054b72 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 02:36:02 +0900 Subject: [PATCH 0673/1182] Start transition from Buffer to Context --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 1 - src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 136 ++++++++++-------- .../Spirv/Building/Builder.Class.cs | 62 ++++---- src/Stride.Shaders/Spirv/Building/Context.cs | 11 +- 4 files changed, 113 insertions(+), 97 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index af56320695..2f7ac11266 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -53,7 +53,6 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext foreach (var shaderName in mixinList.ToArray()) { var shader = shaderName.Buffer.Value; - ShaderClass.ProcessNameAndTypes(shader.Context); bool hasStage = false; foreach (var i in shader.Context) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 7190557f51..0d0ac5a883 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -20,12 +20,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public interface IShaderImporter { - ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer); + ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext); } public class EmptyShaderImporter : IShaderImporter { - public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) + public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) { return new ShaderSymbol(classSource.ClassName, classSource.GenericArguments); } @@ -41,31 +41,35 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) - public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, out Dictionary names, out Dictionary types, IShaderImporter? shaderImporter = null) + public static void ProcessNameAndTypes(SpirvContext context, IShaderImporter? shaderImporter = null, bool allowReplace = false) { - names = []; - types = []; - - ProcessNameAndTypes(buffer, start, end, names, types, shaderImporter); + ProcessNameAndTypes(context, 0, context.GetBuffer().Count, shaderImporter, allowReplace); } - public static void ProcessNameAndTypes(SpirvContext context, int start, int end, IShaderImporter? shaderImporter = null) + public static void ProcessNameAndTypes(SpirvContext context, int start, int end, IShaderImporter? shaderImporter = null, bool allowReplace = false) { - ProcessNameAndTypes(context.GetBuffer(), start, end, context.Names, context.ReverseTypes, shaderImporter); - foreach (var type in context.ReverseTypes) + void RegisterType(int typeId, SymbolType symbolType) { - if (!context.Types.ContainsKey(type.Value)) - context.Types.Add(type.Value, type.Key); + if (allowReplace && context.ReverseTypes.TryGetValue(typeId, out var existingSymbolType)) + { + context.ReverseTypes[typeId] = symbolType; + context.Types.Remove(existingSymbolType); + } + else + { + context.ReverseTypes.Add(typeId, symbolType); + } + context.Types.Add(symbolType, typeId); } - } - public static void ProcessNameAndTypes(SpirvContext context, IShaderImporter? shaderImporter = null) - { - ProcessNameAndTypes(context, 0, context.GetBuffer().Count, shaderImporter); - } + void RegisterName(int target, string name) + { + if (allowReplace) + context.Names[target] = name; + else + context.Names.Add(target, name); + } - public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end, Dictionary names, Dictionary types, IShaderImporter? shaderImporter = null) - { var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); var importedShaders = new Dictionary(); @@ -73,11 +77,11 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end var blocks = new HashSet(); for (var i = start; i < end; i++) { - var instruction = buffer[i]; + var instruction = context.GetBuffer()[i]; if (instruction.Op == Op.OpName) { OpName nameInstruction = instruction; - names.Add(nameInstruction.Target, nameInstruction.Name); + RegisterName(nameInstruction.Target, nameInstruction.Name); } else if (instruction.Op == Op.OpMemberName) { @@ -96,7 +100,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end //if (floatInstruction.FloatingPointEncoding != 0) // throw new InvalidOperationException(); - types.Add(floatInstruction.ResultId, floatInstruction.Width switch + RegisterType(floatInstruction.ResultId, floatInstruction.Width switch { 16 => ScalarType.From("half"), 32 => ScalarType.From("float"), @@ -107,7 +111,7 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeInt) { OpTypeInt intInstruction = instruction; - types.Add(intInstruction.ResultId, (intInstruction.Width, intInstruction.Signedness == 1) switch + RegisterType(intInstruction.ResultId, (intInstruction.Width, intInstruction.Signedness == 1) switch { (32, true) => ScalarType.From("int"), (32, false) => ScalarType.From("uint"), @@ -118,80 +122,80 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end else if (instruction.Op == Op.OpTypeBool) { OpTypeBool boolInstruction = instruction; - types.Add(boolInstruction.ResultId, ScalarType.From("bool")); + RegisterType(boolInstruction.ResultId, ScalarType.From("bool")); } else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is { } pointerInstruction) { - var innerType = types[pointerInstruction.Type]; - types.Add(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); + var innerType = context.ReverseTypes[pointerInstruction.Type]; + RegisterType(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); } else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is { } voidInstruction) { - types.Add(voidInstruction.ResultId, ScalarType.From("void")); + RegisterType(voidInstruction.ResultId, ScalarType.From("void")); } else if (instruction.Op == Op.OpTypeVector && (OpTypeVector)instruction is { } vectorInstruction) { - var innerType = (ScalarType)types[vectorInstruction.ComponentType]; - types.Add(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); + var innerType = (ScalarType)context.ReverseTypes[vectorInstruction.ComponentType]; + RegisterType(vectorInstruction.ResultId, new VectorType(innerType, vectorInstruction.ComponentCount)); } else if (instruction.Op == Op.OpTypeMatrix && (OpTypeMatrix)instruction is { } matrixInstruction) { - var innerType = (VectorType)types[matrixInstruction.ColumnType]; - types.Add(matrixInstruction.ResultId, new MatrixType(innerType.BaseType, innerType.Size, matrixInstruction.ColumnCount)); + var innerType = (VectorType)context.ReverseTypes[matrixInstruction.ColumnType]; + RegisterType(matrixInstruction.ResultId, new MatrixType(innerType.BaseType, innerType.Size, matrixInstruction.ColumnCount)); } else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { - var structName = names[typeStructInstruction.ResultId]; + var structName = context.Names[typeStructInstruction.ResultId]; var fieldsData = typeStructInstruction.Values; var fields = new List(); for (var index = 0; index < fieldsData.WordCount; index++) { var fieldData = fieldsData.Words[index]; - var type = types[fieldData]; + var type = context.ReverseTypes[fieldData]; var name = memberNames[(typeStructInstruction.ResultId, index)]; fields.Add(new(name, type, TypeModifier.None)); } StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) ? new ConstantBufferSymbol(structName.StartsWith("type.") ? structName.Substring("type.".Length) : throw new InvalidOperationException(), fields) : new StructType(structName, fields); - types.Add(typeStructInstruction.ResultId, structType); + RegisterType(typeStructInstruction.ResultId, structType); } else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { - var innerType = types[typeArray.ElementType]; - if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, buffer, false)) + var innerType = context.ReverseTypes[typeArray.ElementType]; + if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, context.GetBuffer(), false)) { - types.Add(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); + RegisterType(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); } else { // Constant can't be computed; we need to save aside all opcodes - var bufferForConstant = SpirvBuilder.ExtractConstantAsSpirvBuffer(buffer, typeArray.Length); - types.Add(typeArray.ResultId, new ArrayType(innerType, -1, (typeArray.Length, bufferForConstant))); + var bufferForConstant = SpirvBuilder.ExtractConstantAsSpirvBuffer(context.GetBuffer(), typeArray.Length); + RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, (typeArray.Length, bufferForConstant))); } } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) { - var innerType = types[typeRuntimeArray.ElementType]; - types.Add(typeRuntimeArray.ResultId, new ArrayType(innerType, -1)); + var innerType = context.ReverseTypes[typeRuntimeArray.ElementType]; + RegisterType(typeRuntimeArray.ResultId, new ArrayType(innerType, -1)); } else if (instruction.Op == Op.OpTypeFunctionSDSL && new OpTypeFunctionSDSL(instruction) is { } typeFunctionInstruction) { var tmp = new OpTypeFunction(instruction); - var returnType = types[typeFunctionInstruction.ReturnType]; + var returnType = context.ReverseTypes[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); foreach (var operand in typeFunctionInstruction.Values) { - parameterTypes.Add(new(types[operand.Item1], (ParameterModifiers)operand.Item2)); + parameterTypes.Add(new(context.ReverseTypes[operand.Item1], (ParameterModifiers)operand.Item2)); } - types.Add(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); + RegisterType(typeFunctionInstruction.ResultId, new FunctionType(returnType, parameterTypes)); } else if (instruction.Op == Op.OpTypeImage && new OpTypeImage(instruction) is { } typeImage) { - var sampledType = (ScalarType)types[typeImage.SampledType]; + var sampledType = (ScalarType)context.ReverseTypes[typeImage.SampledType]; if (typeImage.Dim == Dim.Buffer) { - types.Add(typeImage.ResultId, new BufferType(sampledType)); + RegisterType(typeImage.ResultId, new BufferType(sampledType)); } else { @@ -212,41 +216,41 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end Sampled = typeImage.Sampled, }; - types.Add(typeImage.ResultId, textureType); + RegisterType(typeImage.ResultId, textureType); } } else if (instruction.Op == Op.OpTypeSampler && new OpTypeSampler(instruction) is { } typeSampler) { - types.Add(typeSampler.ResultId, new SamplerType()); + RegisterType(typeSampler.ResultId, new SamplerType()); } else if (instruction.Op == Op.OpTypeGenericSDSL && (OpTypeGenericSDSL)instruction is { } typeGeneric) { - types.Add(typeGeneric.ResultId, new GenericParameterType(typeGeneric.Kind)); + RegisterType(typeGeneric.ResultId, new GenericParameterType(typeGeneric.Kind)); } else if (instruction.Op == Op.OpTypeStreamsSDSL && (OpTypePointer)instruction is { } typeStreams) { - types.Add(typeStreams.ResultId, new StreamsType()); + RegisterType(typeStreams.ResultId, new StreamsType()); } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); - var shaderSymbol = realShaderImporter.Import(classSource, buffer); + var shaderSymbol = realShaderImporter.Import(classSource, context); - types.Add(importShader.ResultId, shaderSymbol); + RegisterType(importShader.ResultId, shaderSymbol); } else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) { - var shaderSymbol = (ShaderSymbol)types[importStruct.Shader]; + var shaderSymbol = (ShaderSymbol)context.ReverseTypes[importStruct.Shader]; if (shaderSymbol is LoadedShaderSymbol loadedShaderSymbol) { var structName = importStruct.StructName; - types.Add(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == structName).Type); + RegisterType(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == structName).Type); } else { - types.Add(importStruct.ResultId, new StructType(importStruct.StructName, [])); + RegisterType(importStruct.ResultId, new StructType(importStruct.StructName, [])); } } } @@ -254,12 +258,12 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end // Second pass (for processing when info from first pass is needed) for (var i = start; i < end; i++) { - var instruction = buffer[i]; + var instruction = context.GetBuffer()[i]; // Can be declared before OpTypeStruct, so done in second pass if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) { - var structType = (StructuredType)types[memberDecorate.StructureType]; + var structType = (StructuredType)context.ReverseTypes[memberDecorate.StructureType]; if (memberDecorate.Decoration == Decoration.ColMajor) structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.ColumnMajor }; else if (memberDecorate.Decoration == Decoration.RowMajor) @@ -268,17 +272,25 @@ public static void ProcessNameAndTypes(NewSpirvBuffer buffer, int start, int end } } + class ReplaceTypes(Dictionary TypesToReplace) : TypeRewriter + { + public override SymbolType DefaultVisit(SymbolType node) => TypesToReplace.TryGetValue(node, out var result) ? result : node; + } + public class ShaderImporter(SymbolTable table, SpirvContext context) : IShaderImporter { - public ShaderSymbol Import(ShaderClassInstantiation classSource, NewSpirvBuffer buffer) + public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) { - return LoadAndCacheExternalShaderType(table, context, classSource, buffer); + return LoadAndCacheExternalShaderType(table, context, classSource, declaringContext); } } private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, ShaderBuffers shaderBuffers, ShaderClassInstantiation classSource) { - ProcessNameAndTypes(shaderBuffers.Context, new ShaderImporter(table, context)); + // Reprocess types, this is necessary for: + // - ArrayType (with proper updated constants without generics) + // - ShaderClass (properly loaded as LoadedShaderSymbol) + ProcessNameAndTypes(shaderBuffers.Context, new ShaderImporter(table, context), true); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); @@ -585,7 +597,7 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl return shaderType; } - public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, NewSpirvBuffer parentBuffer) + public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, SpirvContext declaringContext) { // Already processed? if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) @@ -593,7 +605,7 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl if (classSource.Buffer == null) { - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, parentBuffer); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, declaringContext); classSource.Buffer = shader; } var shaderType = LoadExternalShaderType(table, context, classSource); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 7b885a808f..7a6cd272dd 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -505,10 +505,9 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType var bound = context.Bound; SpirvBuilder.InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, localContext.GetBuffer()); context.Bound = bound; - instructionIndex--; return true; case GenericParameterType g: - contextBuffer.Replace(instructionIndex, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + contextBuffer.Replace(instructionIndex++, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); return true; default: throw new NotImplementedException(); @@ -519,7 +518,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType /// /// Instantiate generics using another buffer for the shader constants. If a context is specified, constants will be imported there, otherwise inside the generic shader being instantiated. /// - class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSource, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) : GenericResolver + class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSource, ResolveStep resolveStep, SpirvContext declaringContext) : GenericResolver { private Dictionary names; @@ -527,17 +526,14 @@ class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSourc private string GetIdRefAsString(int index) { - if (names == null) - ShaderClass.ProcessNameAndTypes(declaringBuffer, 0, declaringBuffer.Count, out names, out _); - - return names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) + return declaringContext.Names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) ? $"%{genericArgumentName}[{classSource.GenericArguments[index]}]" : $"%{classSource.GenericArguments[index]}"; } public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) { - if (!TryGetConstantValue(classSource.GenericArguments[index], out value, out _, declaringBuffer, false)) + if (!TryGetConstantValue(classSource.GenericArguments[index], out value, out _, declaringContext.GetBuffer(), false)) { value = GetIdRefAsString(index); return false; @@ -550,7 +546,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType { var contextBuffer = context.GetBuffer(); // Check if generic value can already be computed (no OpSDSLGenericParameter and such) - if (TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, declaringBuffer, false)) + if (TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, declaringContext.GetBuffer(), false)) { // TODO: shortcut: store it right away and finish here textValue = constantValue.ToString(); @@ -561,7 +557,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType } var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; - var bufferWithConstant = ExtractConstantAsSpirvBuffer(declaringBuffer, classSource.GenericArguments[genericIndex]); + var bufferWithConstant = ExtractConstantAsSpirvBuffer(declaringContext.GetBuffer(), classSource.GenericArguments[genericIndex]); bool resolved = true; @@ -584,9 +580,6 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType int resultId = InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); contextBuffer.Header = contextBuffer.Header with { Bound = bound }; - // Since we removed one instruction earlier, adjust for it so that next loop process just after what has just been added - instructionIndex--; - return true; } @@ -610,8 +603,6 @@ public override void PostProcess(string classNameWithGenerics, List macros) { - ShaderClass.ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types); - var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); @@ -621,18 +612,26 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st var i = shaderBuffers.Context.GetBuffer()[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { - var genericParameterType = types[genericParameter.ResultType]; - var genericParameterName = names[genericParameter.ResultId]; + var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; + var genericParameterName = shaderBuffers.Context.Names[genericParameter.ResultId]; + var instructionStart = index; var resolved = genericResolver.ResolveGenericValueInBuffer(genericParameterType, genericParameterName, genericParameters.Count, shaderBuffers.Context, ref index, out var textValue); genericParameters.Add(new(genericParameterType, genericParameter.ResultId, genericParameter.ResultType, i.Index, genericParameterName, resolved, textValue)); + // Process new types (if any) + // Note: this might fail in case of types being reordered? (review that if it happens in more advanced cases) + ShaderClass.ProcessNameAndTypes(shaderBuffers.Context, instructionStart, index); + + // Since we are positioned after the newly added instruction, adjust for it to consider next loop ++index + index--; + switch (genericParameterType) { case GenericParameterType g when g.Kind is GenericParameterKindSDSL.LinkType: resolvedLinks.Add(genericParameter.ResultId, textValue); break; case GenericParameterType g when g.Kind is GenericParameterKindSDSL.Semantic: - semantics.Add(names[genericParameter.ResultId], textValue); + semantics.Add(shaderBuffers.Context.Names[genericParameter.ResultId], textValue); break; } } @@ -723,17 +722,16 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri var instantiatedGenericsMacros = new List<(string Name, string Definition)>(); var genericParameterIndex = 0; - ShaderClass.ProcessNameAndTypes(shaderBuffers.Context.GetBuffer(), 0, shaderBuffers.Context.GetBuffer().Count, out var names, out var types); foreach (var i in shaderBuffers.Context) { if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { - var genericParameterName = names[genericParameter.ResultId]; - var genericParameterType = types[genericParameter.ResultType]; + var genericParameterName = shaderBuffers.Context.Names[genericParameter.ResultId]; + var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) { if (genericResolver.TryResolveGenericValue(genericParameterType, genericParameterName, genericParameterIndex, out var value)) - instantiatedGenericsMacros.Add((names[genericParameter], value.ToString())); + instantiatedGenericsMacros.Add((shaderBuffers.Context.Names[genericParameter], value.ToString())); } genericParameterIndex++; } @@ -758,6 +756,7 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri + MonoGamePreProcessor.Run(code.Substring(unresolvableShader.ShaderCodeNameEnd), $"{shaderName}.sdsl", CollectionsMarshal.AsSpan(instantiatedGenericsMacros)); } + // TODO: Cache? if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out var shader, out _)) throw new InvalidOperationException(); @@ -909,12 +908,7 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) /// public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, SpirvContext context) { - return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context.GetBuffer()), macros); - } - - public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, NewSpirvBuffer declaringBuffer) - { - return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, declaringBuffer), macros); + return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context), macros); } public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) @@ -925,7 +919,6 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); - var shaderBuffers = CreateShaderBuffers(shader); // Split context and buffer @@ -933,11 +926,19 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, //if (!isFromCache) // Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + // TODO: generics cache? if (genericResolver.NeedsResolve()) { InstantiateMemberNames(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) { Bound = shader.Header.Bound }; + // Copy buffers (we don't want to edit original buffer as it might be reloaded through caching + shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) + { + Bound = shader.Header.Bound, + Names = new(shaderBuffers.Context.Names), + Types = new(shaderBuffers.Context.Types), + ReverseTypes = new(shaderBuffers.Context.ReverseTypes), + }; shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, className, genericResolver, shaderLoader, macros); @@ -973,6 +974,7 @@ private static ShaderBuffers CreateShaderBuffers(NewSpirvBuffer shader) context.Bound = shader.Header.Bound; var shaderBuffers = new ShaderBuffers(context, buffer); + ShaderClass.ProcessNameAndTypes(shaderBuffers.Context); return shaderBuffers; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 6e4c5368d1..a757bc7fbb 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -27,9 +27,9 @@ public class SpirvContext { public int ResourceGroupBound { get; set; } = 1; public int Bound { get; set; } = 1; - public Dictionary Types { get; } = []; - public Dictionary ReverseTypes { get; } = []; - public Dictionary Names { get; } = []; + public Dictionary Types { get; init; } = []; + public Dictionary ReverseTypes { get; init; } = []; + public Dictionary Names { get; init; } = []; public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; NewSpirvBuffer Buffer { get; init; } @@ -60,7 +60,10 @@ public void ImportGLSL() } public void AddName(int target, string name) - => Buffer.Add(new OpName(target, name)); + { + Buffer.Add(new OpName(target, name)); + Names.Add(target, name); + } public void AddMemberName(int target, int accessor, string name) => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); From 1b4ba69ed324459c8844768cdde9801fd9989938 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 15:46:00 +0900 Subject: [PATCH 0674/1182] Separated SpirvHeader from SpirvBuffer --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 10 +- .../SDSL/ShaderMixer.cs | 5 +- .../ShaderLoaderBase.cs | 10 +- .../Examples.Spirv.cs | 8 +- src/Stride.Shaders.Experiments/Examples.cs | 2 +- src/Stride.Shaders.Experiments/Program.cs | 3 +- .../Buffers/NewSpirvBuffer.cs | 134 ++++++++++++------ .../Parsing/SpirvHeader.cs | 2 + src/Stride.Shaders.Tests/RenderingTests.cs | 4 +- .../Spirv/Building/Builder.Class.cs | 20 +-- src/Stride.Shaders/Spirv/Building/Context.cs | 12 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 33 +++-- 12 files changed, 150 insertions(+), 93 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 1b46fb71f0..f9796c2b75 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -15,7 +15,7 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out NewSpirvBuffer lastBuffer) + public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out SpirvBytecode lastBuffer) { var parsed = SDSLParser.Parse(code); lastBuffer = null; @@ -47,9 +47,9 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May #if DEBUG var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif - lastBuffer = merged; + lastBuffer = new(merged); - ShaderLoader.RegisterShader(shader.Name, macros, merged); + ShaderLoader.RegisterShader(shader.Name, macros, lastBuffer); } else if (declaration is ShaderEffect effect) { @@ -66,9 +66,9 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May #if DEBUG var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); #endif - lastBuffer = merged; + lastBuffer = new(merged); - ShaderLoader.RegisterShader(effect.Name, macros, merged); + ShaderLoader.RegisterShader(effect.Name, macros, lastBuffer); } else { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index df4f86da07..feb75b63af 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1,6 +1,7 @@ using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Silk.NET.Direct3D.Compilers; +using Silk.NET.Direct3D12; using Silk.NET.SPIRV.Cross; using Stride.Core.Extensions; using Stride.Shaders.Compilers.Direct3D; @@ -28,7 +29,7 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out EffectReflection effectReflection) + public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection) { var temp = new NewSpirvBuffer(); @@ -81,7 +82,7 @@ public void MergeSDSL(ShaderSource shaderSource, out byte[] bytecode, out Effect temp.Sort(); - bytecode = temp.ToBytecode(); + bytecode = SpirvBytecode.CreateBytecodeFromBuffers(temp); #if DEBUG //File.WriteAllBytes("test.spv", bytecode); diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs index f1af8ac032..2aa43314bc 100644 --- a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -30,9 +30,9 @@ public bool Equals(ShaderLoadKey other) } } - private Dictionary> loadedShaders = []; + private Dictionary> loadedShaders = []; - public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer) + public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode buffer) { if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) loadedShaders.Add(name, loadedShadersByName = new()); @@ -50,7 +50,7 @@ public bool Exists(string name) protected abstract bool ExternalFileExists(string name); protected abstract bool LoadExternalFileContent(string name, out string filename, out string code); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) { if (loadedShaders.TryGetValue(name, out var loadedShadersByName) && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) @@ -78,7 +78,7 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ return true; } - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) { if (loadedShaders.TryGetValue(name, out var loadedShadersByName) && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) @@ -98,7 +98,7 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan macros, out NewSpirvBuffer buffer) + protected virtual bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out SpirvBytecode buffer) { var defines = new (string Name, string Definition)[macros.Length]; for (int i = 0; i < macros.Length; ++i) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 5f942e2d66..5bfaf7c961 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -140,12 +140,12 @@ public static void CreateNewShader() buffer.FluentAdd(new OpFunctionEnd()); buffer.Sort(); - var span = buffer.ToBuffer(); + var bytecode = buffer.ToBytecode(); Spv.Dis(buffer); File.WriteAllBytes( "test.spv", - MemoryMarshal.Cast(span.Span) + bytecode ); } @@ -282,8 +282,8 @@ public static void ParseWorking() var bytes = File.ReadAllBytes(path); - var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytes.AsSpan())); - var extInst = (OpExtInstImport)buffer[1] ; + using var bytecode = SpirvBytecode.CreateBufferFromBytecode(bytes); + var extInst = (OpExtInstImport)bytecode.Buffer[1]; Console.WriteLine(extInst.Name); } } diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 0031af10df..1dde96c65e 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -242,7 +242,7 @@ public static void CompileSDSL(string shaderName) if (sdslc.Compile(text, [], out var buffer) && buffer is not null) { Spirv.Tools.Spv.Dis(buffer, writeToConsole: true); - var bytecode = buffer.ToBytecode(); + var bytecode = buffer.ToBytecode().ToArray(); File.WriteAllBytes("TestBasic.sdspv", bytecode); var code = new SpirvTranslator(bytecode.AsMemory().Cast()); } diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 896048b31d..d7d40bb179 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -16,7 +16,8 @@ loader.LoadExternalBuffer("Test", [], out var testBuffer, out _); var shaderMixer = new ShaderMixer(loader); shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _); -var buffer = new NewSpirvBuffer(MemoryMarshal.Cast(bytecode.AsSpan())); + +using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); var source = Spv.Dis(buffer); File.WriteAllText("test.spvdis", source); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 38e9e09ba4..fd02f79d5b 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -184,9 +184,93 @@ public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) public readonly ref OpData Data => ref Buffer.GetRef(Index); } +public record SpirvBytecode(SpirvHeader Header, NewSpirvBuffer Buffer) : IDisposable +{ + public SpirvBytecode(NewSpirvBuffer buffer) : this(CreateHeader(buffer), buffer) + { + } + + public void Dispose() => Buffer.Dispose(); + + public static SpirvHeader CreateHeader(NewSpirvBuffer buffer) + { + var header = new SpirvHeader("1.4", 0, 1); + var bound = 1; + foreach (var i in buffer) + { + ref var data = ref i.Data; + if (data.IdResult is int index && index >= bound) + bound = index + 1; + } + return new SpirvHeader("1.4", 0, bound); + } + + public Span ToBytecode() + { + return CreateBytecodeFromBuffers(Header, false, Buffer); + } + + public static SpirvBytecode CreateBufferFromBytecode(Span span) + { + return CreateBufferFromBytecode(MemoryMarshal.Cast(span)); + } + + public static SpirvBytecode CreateBufferFromBytecode(Span span) + { + if (span[0] != MagicNumber) + throw new InvalidOperationException("SPIRV Magic number not found"); + + var header = SpirvHeader.Read(span); + + return new(header, new NewSpirvBuffer(span[SpirvHeader.IntSpanSize..])); + } + + public static SpanOwner CreateSpanFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) + { + int instructionsMemorySize = 0; + var bound = header.Bound; + foreach (var buffer in buffers) + { + foreach (var i in buffer) + { + ref var data = ref i.Data; + if (data.IdResult is int index && index >= bound) + bound = index + 1; + + instructionsMemorySize += data.Memory.Length; + } + } + + header = header with { Bound = bound }; + + var result = SpanOwner.Allocate(5 + instructionsMemorySize); + var span = result.Span; + header.WriteTo(span); + var offset = 5; + foreach (var buffer in buffers) + { + foreach (var i in buffer) + { + i.Data.Memory.Span.CopyTo(span[offset..]); + offset += i.Data.Memory.Length; + } + } + return result; + } + + public static Span CreateBytecodeFromBuffers(params Span buffers) + { + return CreateBytecodeFromBuffers(new("1.4", 0, 1), true, buffers); + } + + public static Span CreateBytecodeFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) + { + return MemoryMarshal.AsBytes(CreateSpanFromBuffers(header, computeBounds, buffers).Span); + } +} + public sealed class NewSpirvBuffer() : IDisposable, IEnumerable { - public SpirvHeader Header { get; set; } = new("1.4", 0, 1); List Instructions { get; set; } = []; public int Count => Instructions.Count; @@ -198,11 +282,10 @@ public sealed class NewSpirvBuffer() : IDisposable, IEnumerable public ref OpData GetRef(int index) => ref CollectionsMarshal.AsSpan(Instructions)[index]; - public NewSpirvBuffer(Span span) : this() + public NewSpirvBuffer(Span instructions) : this() { - if (span[0] == MagicNumber) - Header = SpirvHeader.Read(span); - var instructions = span[5..]; + if (instructions.Length > 0 && instructions[0] == MagicNumber) + throw new InvalidOperationException(); int wid = 0; while (wid < instructions.Length) @@ -212,31 +295,21 @@ public NewSpirvBuffer(Span span) : this() } } - - void UpdateBound(OpData data) - { - if (data.IdResult is int index && index >= Header.Bound) - Header = Header with { Bound = index + 1 }; - } - public OpDataIndex Add(OpData data) { Instructions.Add(data); - UpdateBound(data); return new OpDataIndex(Instructions.Count - 1, this); } public OpDataIndex Insert(int index, OpData data) { Instructions.Insert(index, data); - UpdateBound(data); return new OpDataIndex(index, this); } public OpData Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct { Instructions.Add(new(instruction.InstructionMemory)); - UpdateBound(Instructions[^1]); return Instructions[^1]; } @@ -244,7 +317,6 @@ public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryIn { Instructions.Add(new(instruction.InstructionMemory)); var tmp = instruction; - UpdateBound(Instructions[^1]); return this; } public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct @@ -252,7 +324,6 @@ public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : str result = instruction; Instructions.Add(new(instruction.InstructionMemory)); instruction.Attach(new(Instructions.Count - 1, this)); - UpdateBound(Instructions[^1]); return this; } @@ -261,7 +332,6 @@ public T Insert(int index, in T instruction) { Instructions.Insert(index, new(instruction.InstructionMemory)); instruction.Attach(new(index, this)); - UpdateBound(Instructions[index]); return instruction; } public OpData InsertData(int index, in T instruction) @@ -270,7 +340,6 @@ public OpData InsertData(int index, in T instruction) var result = new OpData(instruction.InstructionMemory); Instructions.Insert(index, result); instruction.Attach(new(index, this)); - UpdateBound(result); return result; } @@ -302,8 +371,6 @@ public void RemoveRange(int index, int count, bool dispose = true) public void InsertRange(int index, ReadOnlySpan source) { Instructions.InsertRange(index, source); - for (int i = index; i < index + source.Length; ++i) - UpdateBound(Instructions[i]); } public OpData Replace(int index, OpData i) @@ -313,7 +380,6 @@ public OpData Replace(int index, OpData i) Instructions[index].Dispose(); Instructions[index] = i; - UpdateBound(Instructions[index]); return Instructions[index]; } @@ -324,7 +390,6 @@ public OpData Replace(int index, in T instruction) where T : struct, IMemoryI Instructions[index].Dispose(); Instructions[index] = new(instruction.InstructionMemory); - UpdateBound(Instructions[index]); return Instructions[index]; } @@ -369,23 +434,9 @@ public void Sort() Instructions.AddRange(sortedInstructions); } - public byte[] ToBytecode() - { - return MemoryMarshal.AsBytes(ToBuffer().Span).ToArray(); - } - - public SpanOwner ToBuffer() + public Span ToBytecode() { - var result = SpanOwner.Allocate(5 + Instructions.Sum(i => i.Memory.Length)); - var span = result.Span; - Header.WriteTo(span); - var offset = 5; - foreach (var instruction in Instructions) - { - instruction.Memory.Span.CopyTo(span[offset..]); - offset += instruction.Memory.Length; - } - return result; + return SpirvBytecode.CreateBytecodeFromBuffers(this); } public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) @@ -412,10 +463,7 @@ public void Dispose() public static NewSpirvBuffer Merge(NewSpirvBuffer buffer1, NewSpirvBuffer buffer2) { - var result = new NewSpirvBuffer - { - Header = new SpirvHeader("1.4", Math.Max(buffer1.Header.Generator, buffer2.Header.Generator), Math.Max(buffer1.Header.Bound, buffer2.Header.Bound)) - }; + var result = new NewSpirvBuffer(); result.Instructions.AddRange(buffer1.Instructions); result.Instructions.AddRange(buffer2.Instructions); return result; diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index ec8e055035..b0e70d135d 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -41,6 +41,8 @@ public SpirvVersion(string version) /// public readonly struct SpirvHeader { + public const int IntSpanSize = 5; + public uint MagicNumber { get; init; } public SpirvVersion VersionNumber { get; init; } public int Generator { get; init; } diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index fad53f60c8..56de140137 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -42,7 +42,7 @@ protected override bool LoadExternalFileContent(string name, out string filename return true; } - protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out NewSpirvBuffer buffer) + protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out SpirvBytecode buffer) { var result = base.LoadFromCode(filename, code, macros, out buffer); #if DEBUG @@ -65,7 +65,7 @@ public void RenderTest1(string shaderName) File.WriteAllBytes($"{shaderName}.spv", bytecode); // Convert to GLSL - var translator = new SpirvTranslator(bytecode.AsMemory().Cast()); + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 7a6cd272dd..7121371684 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -576,9 +576,9 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType contextBuffer.RemoveAt(instructionIndex); // TODO: Try to simplify constant - var bound = contextBuffer.Header.Bound; + var bound = context.Bound; int resultId = InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); - contextBuffer.Header = contextBuffer.Header with { Bound = bound }; + context.Bound = bound; return true; } @@ -934,7 +934,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, // Copy buffers (we don't want to edit original buffer as it might be reloaded through caching shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) { - Bound = shader.Header.Bound, + Bound = shaderBuffers.Context.Bound, Names = new(shaderBuffers.Context.Names), Types = new(shaderBuffers.Context.Types), ReverseTypes = new(shaderBuffers.Context.ReverseTypes), @@ -943,34 +943,28 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, InstantiateGenericShader(ref shaderBuffers, className, genericResolver, shaderLoader, macros); //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - - shaderBuffers.Context.GetBuffer().Header = shaderBuffers.Context.GetBuffer().Header with { Bound = shaderBuffers.Context.Bound }; - shaderBuffers.Buffer.Header = shaderBuffers.Buffer.Header with { Bound = shaderBuffers.Context.Bound }; } return shaderBuffers; } - private static ShaderBuffers CreateShaderBuffers(NewSpirvBuffer shader) + private static ShaderBuffers CreateShaderBuffers(SpirvBytecode shader) { var context = new SpirvContext(); var buffer = new NewSpirvBuffer(); var isContext = true; - foreach (var i in shader) + foreach (var i in shader.Buffer) { // Find when switching from context to actual shader/effect if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLEffect) isContext = false; if (isContext) - context.GetBuffer().Add(i.Data); + context.Add(i.Data); else buffer.Add(i.Data); } - context.GetBuffer().Header = shader.Header; - buffer.Header = shader.Header; - context.Bound = shader.Header.Bound; var shaderBuffers = new ShaderBuffers(context, buffer); @@ -1007,7 +1001,7 @@ public static List CollectGenerics(NewSpirvBuffer shader) return generics; } - public static NewSpirvBuffer GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) + public static SpirvBytecode GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) { Console.WriteLine($"[Shader] Requesting non-generic class {className}"); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index a757bc7fbb..1ff74f46db 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -15,18 +15,19 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { - public void RegisterShader(string name, ReadOnlySpan defines, NewSpirvBuffer buffer); + public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode buffer); public bool Exists(string name); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out NewSpirvBuffer bytecode, out bool isFromCache); + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters public class SpirvContext { + private int bound = 1; public int ResourceGroupBound { get; set; } = 1; - public int Bound { get; set; } = 1; + public ref int Bound => ref bound; public Dictionary Types { get; init; } = []; public Dictionary ReverseTypes { get; init; } = []; public Dictionary Names { get; init; } = []; @@ -465,6 +466,9 @@ public OpData Add(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.Add(value); + public OpDataIndex Add(OpData data) + => Buffer.Add(data); + public SpirvContext FluentAdd(in T value, out T result) where T : struct, IMemoryInstruction, allows ref struct diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index aa68a5c235..a256541d2d 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -20,24 +20,31 @@ public enum DisassemblerFlags public static partial class Spv { - public static string Dis(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) + public static string Dis(NewSpirvBuffer bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - var writer = new DisWriter(buffer, flags, writeToConsole); + var writer = new DisWriter(new(new("undefined", 0, 1), bytecode), flags, writeToConsole); + writer.Disassemble(); + return writer.ToString(); + } + + public static string Dis(SpirvBytecode bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) + { + var writer = new DisWriter(bytecode, flags, writeToConsole); writer.Disassemble(); return writer.ToString(); } public static string Dis(SpirvReader reader, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - using var buffer = new NewSpirvBuffer(reader.Words); + using var buffer = SpirvBytecode.CreateBufferFromBytecode(reader.Words); var writer = new DisWriter(buffer, flags, writeToConsole); writer.Disassemble(); return writer.ToString(); } - struct DisWriter(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) + struct DisWriter(SpirvBytecode bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = true) { - DisData data = new(buffer, flags, writeToConsole); + DisData data = new(bytecode, flags, writeToConsole); readonly StringBuilder builder = new(); readonly DisWriter AppendLine(string text, ConsoleColor? color = null) @@ -272,7 +279,7 @@ public readonly void Disassemble() public readonly void DisHeader() { - var header = data.Buffer.Header; + var header = data.Bytecode.Header; AppendLine($"; SPIR-V"); AppendLine($"; Version: {header.VersionNumber >> 16}.{header.VersionNumber & 0xFF}"); AppendLine($"; Generator: {header.Generator}"); @@ -319,7 +326,7 @@ or OperandKind.LiteralSpecConstantOpInteger (OperandQuantifier.ZeroOrMore, _) => AppendLiteralNumbers(operand.Words), _ => throw new NotImplementedException("Unsupported literal integer quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, - OperandKind.LiteralContextDependentNumber => AppendContextDependentNumber(operand, data, buffer), + OperandKind.LiteralContextDependentNumber => AppendContextDependentNumber(operand, data, bytecode.Buffer), OperandKind.IdRef or OperandKind.IdResultType => (operand.Quantifier, operand.Words.Length) switch { @@ -382,16 +389,16 @@ struct DisData : IDisposable static int MAX_OFFSET = 16; public Dictionary NameTable { get; } public HashSet UsedNames { get; } = new(); - public NewSpirvBuffer Buffer { get; } + public SpirvBytecode Bytecode { get; } public int IdOffset { get; private set; } public DisassemblerFlags Flags { get; private set; } public bool UseNames => (Flags & DisassemblerFlags.Name) != 0; public bool UseIds => (Flags & DisassemblerFlags.Id) != 0; public bool WriteToConsole { get; private set; } - public DisData(NewSpirvBuffer buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) + public DisData(SpirvBytecode buffer, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - Buffer = buffer; + Bytecode = buffer; NameTable = []; Flags = flags; WriteToConsole = writeToConsole; @@ -403,7 +410,7 @@ void ComputeIdOffset() IdOffset = 9; if (!UseNames) { - var bound = Buffer.Header.Bound; + var bound = Bytecode.Header.Bound; IdOffset = 3; while (bound > 0) { @@ -414,7 +421,7 @@ void ComputeIdOffset() else { var maxName = 0; - foreach (var i in Buffer) + foreach (var i in Bytecode.Buffer) { if (i.Op == Op.OpName) { @@ -431,7 +438,7 @@ void ComputeIdOffset() } IdOffset = Math.Min(IdOffset, MAX_OFFSET); } - public readonly NewSpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); + public readonly NewSpirvBuffer.Enumerator GetEnumerator() => Bytecode.Buffer.GetEnumerator(); public readonly void Dispose() { From c786bc448d802a4772379428862ee46ac0c89ff8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 18:30:58 +0900 Subject: [PATCH 0675/1182] Moved InsertWithoutDuplicates and ExtractConstantAsSpirvBuffer to SpirvContext --- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../Spirv/Building/Builder.Class.cs | 150 ++-------------- src/Stride.Shaders/Spirv/Building/Context.cs | 164 +++++++++++++----- 3 files changed, 133 insertions(+), 185 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 0d0ac5a883..c1f4ca6da0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -170,7 +170,7 @@ void RegisterName(int target, string name) else { // Constant can't be computed; we need to save aside all opcodes - var bufferForConstant = SpirvBuilder.ExtractConstantAsSpirvBuffer(context.GetBuffer(), typeArray.Length); + var bufferForConstant = context.ExtractConstantAsSpirvBuffer(typeArray.Length); RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, (typeArray.Length, bufferForConstant))); } } @@ -339,7 +339,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte // Build full inheritance list List inheritanceList = new(); - SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context.GetBuffer(), inheritanceList, ResolveStep.Compile); + SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context, inheritanceList, ResolveStep.Compile); // Load all the inherited shaders List inheritedShaderSymbols = new(); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 7121371684..52a9758b10 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -104,12 +104,12 @@ public override string ToString() public partial class SpirvBuilder { - public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, NewSpirvBuffer contextBuffer, List inheritanceList, ResolveStep resolveStep) + public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext topLevelContext, ShaderClassInstantiation classSource, ReadOnlySpan macros, SpirvContext declaringContext, List inheritanceList, ResolveStep resolveStep) { // Build shader name mapping var shaderMapping = new Dictionary(); var genericParameterRemapping = new Dictionary(); - foreach (var i in contextBuffer) + foreach (var i in declaringContext) { if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { @@ -117,7 +117,7 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - var shaderClassSource = ConvertToShaderClassSource(contextBuffer, 0, contextBuffer.Count, importShader); + var shaderClassSource = ConvertToShaderClassSource(declaringContext.GetBuffer(), 0, declaringContext.GetBuffer().Count, importShader); shaderMapping[importShader.ResultId] = shaderClassSource; } @@ -129,17 +129,14 @@ int RemapGenericParameter(int localGeneric) return generic; // Otherwise, assume it's a constsant we need to import - var constantBuffer = ExtractConstantAsSpirvBuffer(contextBuffer, localGeneric); - int index = context.GetBuffer().Count; - var bound = context.Bound; - var resultId = InsertBufferWithoutDuplicates(context.GetBuffer(), ref index, ref bound, null, constantBuffer); - context.Bound = bound; + var constantBuffer = declaringContext.ExtractConstantAsSpirvBuffer(localGeneric); + var resultId = topLevelContext.InsertWithoutDuplicates(null, constantBuffer); return resultId; } // Check inheritance - foreach (var i in contextBuffer) + foreach (var i in declaringContext) { if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { @@ -151,7 +148,7 @@ int RemapGenericParameter(int localGeneric) remappedGenericArguments[index] = RemapGenericParameter(remappedGenericArguments[index]); var remappedShaderName = shaderName with { GenericArguments = remappedGenericArguments }; - BuildInheritanceListIncludingSelf(shaderLoader, context, remappedShaderName, macros, inheritanceList, resolveStep); + BuildInheritanceListIncludingSelf(shaderLoader, topLevelContext, remappedShaderName, macros, inheritanceList, resolveStep); } } } @@ -177,7 +174,7 @@ public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExtern index = inheritanceList.IndexOf(classSource); if (index == -1) { - BuildInheritanceListWithoutSelf(shaderLoader, context, classSource, macros, classSource.Buffer.Value.Context.GetBuffer(), inheritanceList, resolveStep); + BuildInheritanceListWithoutSelf(shaderLoader, context, classSource, macros, classSource.Buffer.Value.Context, inheritanceList, resolveStep); index = inheritanceList.Count; inheritanceList.Add(classSource); } @@ -320,53 +317,6 @@ public static bool TryGetConstantValue(OpDataIndex i, out object value, out int throw new Exception("Cannot find type instruction for id " + typeId); } - public static NewSpirvBuffer ExtractConstantAsSpirvBuffer(NewSpirvBuffer buffer, int constantId) - { - // First, run a simplification pass - // TODO: separate simplification from computing value? - TryGetConstantValue(constantId, out _, out _, buffer, true); - - // Go backward and find any reference - var newBuffer = new NewSpirvBuffer(); - var referenced = new HashSet { constantId }; - var instructions = new List(); - for (int index = buffer.Count - 1; index >= 0; --index) - { - var i = buffer[index]; - if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) - { - var i2 = new OpData(i.Data.Memory.Span); - - // Then add IdRef operands to next requested instructions or types - foreach (var op in i2) - { - if (op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefIdRef) - { - foreach (ref var word in op.Words) - { - referenced.Add(word); - } - } - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefLiteralInteger) - { - throw new NotImplementedException(); - } - } - - instructions.Add(i2); - } - } - - // Since we went backward, reverse the list - instructions.Reverse(); - foreach (var i in instructions) - newBuffer.Add(i); - return newBuffer; - } - record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, int Index, string Name, bool Resolved, string Value); abstract class GenericResolver @@ -381,82 +331,6 @@ public virtual void PostProcess(string classNameWithGenerics, List(); - int lastResultId = -1; - - var lastResultIndex = -1; - if (desiredResultId != null) - { - // Find last index returning a value (that's the value we want remapped to desiredResultId) - for (int index = 0; index < source.Count; ++index) - { - var i = source[index]; - if (i.Data.IdResult is not null) - lastResultIndex = index; - } - } - - for (int index = 0; index < source.Count; ++index) - { - var i = source[index]; - RemapIds(remapIds, ref i.Data); - - //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() - var isGenericReference = i.Op == Op.OpSDSLGenericReference; - if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; - - // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) - if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) - && (index != lastResultIndex || desiredResultId == null)) - { - // Make sure this data is declared at current index, otherwise move it. - // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops - if (existingData.Index > instructionIndex) - { - var existingDataCopy = new OpData(existingData.Data.Memory); - typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); - existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); - } - remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); - lastResultId = existingData.Data.IdResult.Value; - } - else - { - if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericReference; - - if (i.Data.IdResult.HasValue) - { - // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID - var resultId = index == lastResultIndex && desiredResultId != null - ? desiredResultId.Value - : bound++; - - remapIds.Add(i.Data.IdResult.Value, resultId); - i.Data.IdResult = resultId; - typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); - - lastResultId = resultId; - } - } - } - - if (lastResultId == -1) - throw new InvalidOperationException("Could not find any instruction with a value"); - - // Note: we made sure to not copy last instruction which should have the constant we want - if (desiredResultId != null && lastResultId != desiredResultId) - throw new InvalidOperationException(); - - return lastResultId; - } - /// /// Instantiate generics using string values (they will be imported in the generic shader being specialized). /// @@ -502,9 +376,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType var localContext = new SpirvContext(); var result = expression.CompileConstantValue(new SymbolTable(localContext), localContext, genericParameterType); contextBuffer.RemoveAt(instructionIndex); - var bound = context.Bound; - SpirvBuilder.InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, localContext.GetBuffer()); - context.Bound = bound; + context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, localContext.GetBuffer()); return true; case GenericParameterType g: contextBuffer.Replace(instructionIndex++, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); @@ -557,7 +429,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType } var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; - var bufferWithConstant = ExtractConstantAsSpirvBuffer(declaringContext.GetBuffer(), classSource.GenericArguments[genericIndex]); + var bufferWithConstant = declaringContext.ExtractConstantAsSpirvBuffer(classSource.GenericArguments[genericIndex]); bool resolved = true; @@ -577,7 +449,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType // TODO: Try to simplify constant var bound = context.Bound; - int resultId = InsertBufferWithoutDuplicates(contextBuffer, ref instructionIndex, ref bound, genericParameter.ResultId, bufferWithConstant); + int resultId = context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, bufferWithConstant); context.Bound = bound; return true; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 1ff74f46db..594b0a5728 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; using System.Diagnostics.CodeAnalysis; @@ -92,46 +93,6 @@ public int AddConstant(TScalar value) throw new Exception("Constant has no result id"); } - public void AddGlobalVariable(Symbol variable) - { - throw new NotImplementedException(); - // var t = GetOrRegister(variable.Type); - // if (variable.Id.Storage == Storage.Stream) - // { - // foreach(var usage in SymbolProvider.RootSymbols.StreamUsages[variable.Id]) - // { - // var i = Buffer.AddOpVariable( - // Bound++, - // t, - // usage.IO switch - // { - // StreamIO.Input => StorageClass.Input, - // StreamIO.Output => StorageClass.Output, - // _ => throw new NotImplementedException() - // }, - // null - // ); - // Variables[variable.Id.Name] = i.ResultId!.Value; - // AddName(i, $"{usage.EntryPoint.ToString()}_{usage.IO.ToString()}_{variable.Id.Name}"); - // } - // } - // else - // { - // var storage = variable.Id.Storage switch - // { - // Storage.UniformConstant => StorageClass.UniformConstant, - // Storage.Uniform => StorageClass.Uniform, - // Storage.Function => StorageClass.Function, - // Storage.Generic => StorageClass.Generic, - // _ => throw new NotImplementedException("Variable has to have a storage class") - // }; - // var i = Buffer.AddOpVariable(Bound++, t, storage, null); - // Variables[variable.Id.Name] = i.ResultId!.Value; - // AddName(i, $"{variable.Id.Name}"); - // } - } - - public void SetEntryPoint(ExecutionModel model, int function, string name, ReadOnlySpan variables) { Span pvariables = stackalloc int[variables.Length]; @@ -209,10 +170,7 @@ public int GetOrRegister(SymbolType? type) var importBuffer = sizeExpression.Buffer; if (importBuffer != Buffer) { - var index = Buffer.Count; - var bound = Bound; - var resultId = SpirvBuilder.InsertBufferWithoutDuplicates(Buffer, ref index, ref bound, null, importBuffer); - Bound = bound; + var resultId = InsertWithoutDuplicates(null, importBuffer); sizeId = resultId; } @@ -479,6 +437,124 @@ public SpirvContext FluentAdd(in T value, out T result) public void Sort() => Buffer.Sort(); + public int InsertWithoutDuplicates(int? desiredResultId, NewSpirvBuffer source) + { + var index = Buffer.Count; + return InsertWithoutDuplicates(ref index, desiredResultId, source); + } + + public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, NewSpirvBuffer source) + { + // Import in current buffer (without duplicate) + var typeDuplicateInserter = new TypeDuplicateHelper(Buffer); + var remapIds = new Dictionary(); + int lastResultId = -1; + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + SpirvBuilder.RemapIds(remapIds, ref i.Data); + + //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() + var isGenericReference = i.Op == Op.OpSDSLGenericReference; + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; + + // Note: we also try to avoid duplciate for constants (which should have been resolved) + // otherwise a generic type might have 2 different instantiation with same parameters + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) + && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData)) + { + // Make sure this data is declared at current index, otherwise move it. + // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops + if (existingData.Index > instructionIndex) + { + var existingDataCopy = new OpData(existingData.Data.Memory); + typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); + existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); + } + remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); + lastResultId = existingData.Data.IdResult.Value; + } + else + { + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericReference; + + if (i.Data.IdResult.HasValue) + { + // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID + var resultId = index == source.Count - 1 && desiredResultId != null + ? desiredResultId.Value + : bound++; + + remapIds.Add(i.Data.IdResult.Value, resultId); + i.Data.IdResult = resultId; + typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + + lastResultId = resultId; + } + } + } + + if (lastResultId == -1) + throw new InvalidOperationException("Could not find any instruction with a value"); + + if (desiredResultId != null && lastResultId != desiredResultId) + { + // Need to remap all existing references + SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); + } + + return lastResultId; + } + + public NewSpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) + { + // First, run a simplification pass + // TODO: separate simplification from computing value? + SpirvBuilder.TryGetConstantValue(constantId, out _, out _, Buffer, true); + + // Go backward and find any reference + var newBuffer = new NewSpirvBuffer(); + var referenced = new HashSet { constantId }; + var instructions = new List(); + for (int index = Buffer.Count - 1; index >= 0; --index) + { + var i = Buffer[index]; + if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) + { + var i2 = new OpData(i.Data.Memory.Span); + + // Then add IdRef operands to next requested instructions or types + foreach (var op in i2) + { + if (op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefIdRef) + { + foreach (ref var word in op.Words) + { + referenced.Add(word); + } + } + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefLiteralInteger) + { + throw new NotImplementedException(); + } + } + + instructions.Add(i2); + } + } + + // Since we went backward, reverse the list + instructions.Reverse(); + foreach (var i in instructions) + newBuffer.Add(i); + return newBuffer; + } + [Obsolete("Use the insert method instead")] public NewSpirvBuffer GetBuffer() => Buffer; From 5ad033bc58b2e16181091670480b4e310ee64ea4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 18:35:27 +0900 Subject: [PATCH 0676/1182] Fix InsertWithoutDuplicates() to better match desired id --- src/Stride.Shaders/Spirv/Building/Context.cs | 29 ++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 594b0a5728..c85c71662b 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -449,6 +449,19 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI var typeDuplicateInserter = new TypeDuplicateHelper(Buffer); var remapIds = new Dictionary(); int lastResultId = -1; + + var lastResultIndex = -1; + if (desiredResultId != null) + { + // Find last index returning a value (that's the value we want remapped to desiredResultId) + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + if (i.Data.IdResult is not null) + lastResultIndex = index; + } + } + for (int index = 0; index < source.Count; ++index) { var i = source[index]; @@ -459,10 +472,10 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI if (isGenericReference) i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; - // Note: we also try to avoid duplciate for constants (which should have been resolved) - // otherwise a generic type might have 2 different instantiation with same parameters + // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData)) + && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) + && (index != lastResultIndex || desiredResultId == null)) { // Make sure this data is declared at current index, otherwise move it. // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops @@ -483,7 +496,7 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI if (i.Data.IdResult.HasValue) { // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID - var resultId = index == source.Count - 1 && desiredResultId != null + var resultId = index == lastResultIndex && desiredResultId != null ? desiredResultId.Value : bound++; @@ -499,11 +512,11 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI if (lastResultId == -1) throw new InvalidOperationException("Could not find any instruction with a value"); + // Note: we made sure to not copy last instruction which should have the constant we want, so this case shouldn't happen anymore if (desiredResultId != null && lastResultId != desiredResultId) - { - // Need to remap all existing references - SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); - } + throw new InvalidOperationException(); + // Note: if we were to readd this, we would also need to process the main buffer + //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); return lastResultId; } From 91160a1e5bee1a3daee1fe18d369294e764c346e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 16:14:25 +0900 Subject: [PATCH 0677/1182] ConvertToShaderClassSource: use SpirvContext --- src/Stride.Shaders/Spirv/Building/Builder.Class.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 52a9758b10..be48c0bf64 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -117,7 +117,7 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { - var shaderClassSource = ConvertToShaderClassSource(declaringContext.GetBuffer(), 0, declaringContext.GetBuffer().Count, importShader); + var shaderClassSource = ConvertToShaderClassSource(declaringContext, importShader); shaderMapping[importShader.ResultId] = shaderClassSource; } @@ -153,7 +153,7 @@ int RemapGenericParameter(int localGeneric) } } - public static ShaderClassInstantiation ConvertToShaderClassSource(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, OpSDSLImportShader importShader) + public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpSDSLImportShader importShader) { return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); } From 5df8936c28735370fd05bc7a0c472bb3a4cdce45 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 20:07:44 +0900 Subject: [PATCH 0678/1182] Moved Constants fonctions to SpirvContext --- .../SDSL/EffectEvaluator.cs | 2 +- .../SDSL/ShaderMixer.CBuffers.cs | 2 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 4 +- .../SDSL/ShaderMixer.cs | 12 +- .../Parsing/SDSL/AST/Literals.cs | 2 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 2 +- .../Spirv/Building/Builder.Class.cs | 142 +-------------- .../Spirv/Building/Context.Constants.cs | 162 +++++++++++++++++ .../Spirv/Building/Context.ExtractBuffers.cs | 139 +++++++++++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 163 +----------------- .../Spirv/Processing/PostProcessor.cs | 6 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 38 ++-- 12 files changed, 340 insertions(+), 334 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Building/Context.Constants.cs create mode 100644 src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index e0576b3a3a..396645b6c1 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -23,7 +23,7 @@ object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds var genericArguments = new object[genericIds.Length]; for (int i = 0; i < genericArguments.Length; i++) { - genericArguments[i] = SpirvBuilder.GetConstantValue(genericIds[i], context.GetBuffer()); + genericArguments[i] = context.GetConstantValue(genericIds[i]); } return genericArguments; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 2d97aa3144..024737d68f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -172,7 +172,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // According to spec, this must be a OpConstant (and we only create them with int) var indexes = accessChain.Values.Elements.Span; var constantId = indexes[0]; - var index = cbuffer.MemberIndexOffset + (int)SpirvBuilder.GetConstantValue(constantId, context.GetBuffer()); + var index = cbuffer.MemberIndexOffset + (int)context.GetConstantValue(constantId); indexes[0] = context.CompileConstant(index).Id; // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index c80ae4a393..4efdbd040e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -99,7 +99,7 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext c } } - private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, ref OpData i, NewSpirvBuffer contextBuffer) + private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, ref OpData i, SpirvContext context) { if (i.Op == Op.OpSDSLImportShader && new OpSDSLImportShader(ref i) is { } importShader) { @@ -110,7 +110,7 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin var genericArguments = new object[importShader.Values.Elements.Length]; for (int j = 0; j < genericArguments.Length; j++) { - genericArguments[j] = SpirvBuilder.GetConstantValue(importShader.Values.Elements.Span[j], contextBuffer); + genericArguments[j] = context.GetConstantValue(importShader.Values.Elements.Span[j]); } shaderName += $"<{string.Join(",", genericArguments)}>"; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index feb75b63af..b6f10aeea7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -74,12 +74,6 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef CleanupUnnecessaryInstructions(globalContext, context, temp); - temp.Sort(); - - // Final processing - SpirvProcessor.Process(temp); - - temp.Sort(); bytecode = SpirvBytecode.CreateBytecodeFromBuffers(temp); @@ -243,7 +237,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS return include; } - var typeDuplicateInserter = new TypeDuplicateHelper(context.GetBuffer()); + var typeDuplicateInserter = new TypeDuplicateHelper(context); var structTypes = new Dictionary(); @@ -398,7 +392,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } // Process OpSDSLImport - ProcessImportInfo(globalContext, mixinNode, ref i2, context.GetBuffer()); + ProcessImportInfo(globalContext, mixinNode, ref i2, context); if (addToContext) { @@ -674,7 +668,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions) || (mixinNode.Stage != null && mixinNode.Stage.CompositionArrays.TryGetValue(accessChain.BaseId, out compositions))) { - var compositionIndex = (int)SpirvBuilder.GetConstantValue(accessChain.Values.Elements.Span[0], context.GetBuffer()); + var compositionIndex = (int)context.GetConstantValue(accessChain.Values.Elements.Span[0]); compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); SetOpNop(i.Data.Memory.Span); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 31401d26f7..cd30895705 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -481,7 +481,7 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte arrayComputedSize = (int)i.Value; var constantArraySize = arraySize.CompileConstantValue(table, context); - if (SpirvBuilder.TryGetConstantValue(constantArraySize.Id, out var value, out _, context.GetBuffer(), true)) + if (context.TryGetConstantValue(constantArraySize.Id, out var value, out _, true)) arrayComputedSize = (int)value; arraySymbolType = arrayComputedSize != -1 ? new ArrayType(arraySymbolType, arrayComputedSize) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index c1f4ca6da0..b6feb516ab 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -163,7 +163,7 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = context.ReverseTypes[typeArray.ElementType]; - if (SpirvBuilder.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, context.GetBuffer(), false)) + if (context.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, false)) { RegisterType(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index be48c0bf64..de24b855e0 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -183,140 +183,6 @@ public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExtern return inheritanceList[index]; } - public static bool TryGetInstructionById(int constantId, out OpDataIndex instruction, NewSpirvBuffer buffer) - { - if (buffer.TryGetInstructionById(constantId, out instruction)) - return true; - - instruction = default; - return false; - } - - public static object GetConstantValue(int constantId, NewSpirvBuffer buffer) - { - if (buffer.TryGetInstructionById(constantId, out var constant)) - { - return ResolveConstantValue(constant, buffer); - } - - throw new Exception("Cannot find constant instruction for id " + constantId); - } - - public static bool TryGetConstantValue(int constantId, out object value, out int typeId, NewSpirvBuffer buffer, bool simplifyInBuffer = false) - { - if (buffer.TryGetInstructionById(constantId, out var constant)) - { - return TryGetConstantValue(constant, out value, out typeId, buffer, simplifyInBuffer); - } - - typeId = default; - value = default; - return false; - } - - public static object ResolveConstantValue(OpDataIndex i, NewSpirvBuffer buffer) - { - if (!TryGetConstantValue(i, out var value, out _, buffer, false)) - throw new InvalidOperationException($"Can't process constant {i.Data.IdResult}"); - - return value; - } - - // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. - public static bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, NewSpirvBuffer buffer, bool simplifyInBuffer = false) - { - typeId = default; - value = default; - - // Check for unresolved values - if (i.Op == Op.OpSDSLGenericParameter || i.Op == Op.OpSDSLGenericReference) - { - return false; - } - - if (i.Op == Op.OpConstantStringSDSL) - { - var operand2 = i.Data.Get("literalString"); - value = operand2.ToLiteral(); - return true; - } - - if (i.Op == Op.OpSpecConstantOp) - { - var resultType = i.Data.Memory.Span[1]; - var resultId = i.Data.Memory.Span[2]; - var op = (Op)i.Data.Memory.Span[3]; - switch (op) - { - case Op.OpIMul: - if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, out var leftTypeId, buffer)) - return false; - if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, out var rightTypeId, buffer)) - return false; - if (leftTypeId != resultType || rightTypeId != resultType) - return false; - value = (int)left * (int)right; - if (simplifyInBuffer) - buffer.Replace(i.Index, new OpConstant(resultType, resultId, (int)value)); - return true; - default: - throw new NotImplementedException(); - } - } - if ((i.Op == Op.OpConstantComposite || i.Op == Op.OpSpecConstantComposite) && (OpConstantComposite)i is { } constantComposite) - { - var values = constantComposite.Values; - var constants = new object[values.WordCount]; - for (int j = 0; j < values.WordCount; ++j) - { - if (!TryGetConstantValue(values.Elements.Span[j], out constants[j], out _, buffer)) - return false; - } - - // For now we assume it's a vector type (but we would need to revisit that later if we handle more advanced constants such as matrix or arrays) - value = new ConstantVector { Values = constants }; - - return true; - } - - typeId = i.Op switch - { - Op.OpConstant or Op.OpSpecConstant => i.Data.Memory.Span[1], - }; - var operand = i.Data.Get("value"); - if (buffer.TryGetInstructionById(typeId, out var typeInst)) - { - if (typeInst.Op == Op.OpTypeInt) - { - var type = (OpTypeInt)typeInst; - value = type switch - { - { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), - { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), - { Width: 64, Signedness: 0 } => operand.ToLiteral(), - { Width: 64, Signedness: 1 } => operand.ToLiteral(), - _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), - }; - return true; - } - else if (typeInst.Op == Op.OpTypeFloat) - { - var type = new OpTypeFloat(typeInst); - value = type switch - { - { Width: 16 } => operand.ToLiteral(), - { Width: 32 } => operand.ToLiteral(), - { Width: 64 } => operand.ToLiteral(), - _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), - }; - return true; - } - else - throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); - } - throw new Exception("Cannot find type instruction for id " + typeId); - } - record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, int Index, string Name, bool Resolved, string Value); abstract class GenericResolver @@ -405,7 +271,7 @@ private string GetIdRefAsString(int index) public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) { - if (!TryGetConstantValue(classSource.GenericArguments[index], out value, out _, declaringContext.GetBuffer(), false)) + if (!declaringContext.TryGetConstantValue(classSource.GenericArguments[index], out value, out _, false)) { value = GetIdRefAsString(index); return false; @@ -418,7 +284,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType { var contextBuffer = context.GetBuffer(); // Check if generic value can already be computed (no OpSDSLGenericParameter and such) - if (TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, declaringContext.GetBuffer(), false)) + if (declaringContext.TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, false)) { // TODO: shortcut: store it right away and finish here textValue = constantValue.ToString(); @@ -511,9 +377,9 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant) - if (!TryGetInstructionById(typeArray.Length, out var lengthInstruction, shaderBuffers.Context.GetBuffer())) + if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(typeArray.Length, out var lengthInstruction)) throw new InvalidOperationException(); - if (lengthInstruction.Op != Op.OpConstant && TryGetConstantValue(typeArray.Length, out var value, out _, shaderBuffers.Context.GetBuffer(), true)) + if (lengthInstruction.Op != Op.OpConstant && shaderBuffers.Context.TryGetConstantValue(typeArray.Length, out var value, out _, true)) { } } diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs new file mode 100644 index 0000000000..02b4770791 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -0,0 +1,162 @@ +using System.Numerics; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Building; + +public partial class SpirvContext +{ + public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; + + public int AddConstant(TScalar value) + where TScalar : INumber + { + var data = value switch + { + byte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("byte")), Bound++, v)), + sbyte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("sbyte")), Bound++, v)), + ushort v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ushort")), Bound++, v)), + short v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("short")), Bound++, v)), + uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("uint")), Bound++, v)), + int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("int")), Bound++, v)), + ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ulong")), Bound++, v)), + long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("long")), Bound++, v)), + Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), + float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("float")), Bound++, v)), + double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("bdouble")), Bound++, v)), + _ => throw new NotImplementedException() + }; + if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) + return data.Memory.Span[index + 1]; + throw new Exception("Constant has no result id"); + } + + public object GetConstantValue(int constantId) + { + if (Buffer.TryGetInstructionById(constantId, out var constant)) + { + return ResolveConstantValue(constant); + } + + throw new Exception("Cannot find constant instruction for id " + constantId); + } + + public bool TryGetConstantValue(int constantId, out object value, out int typeId, bool simplifyInBuffer = false) + { + if (Buffer.TryGetInstructionById(constantId, out var constant)) + { + return TryGetConstantValue(constant, out value, out typeId, simplifyInBuffer); + } + + typeId = default; + value = default; + return false; + } + + public object ResolveConstantValue(OpDataIndex i) + { + if (!TryGetConstantValue(i, out var value, out _, false)) + throw new InvalidOperationException($"Can't process constant {i.Data.IdResult}"); + + return value; + } + + // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. + public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, bool simplifyInBuffer = false) + { + typeId = default; + value = default; + + // Check for unresolved values + if (i.Op == Specification.Op.OpSDSLGenericParameter || i.Op == Specification.Op.OpSDSLGenericReference) + { + return false; + } + + if (i.Op == Specification.Op.OpConstantStringSDSL) + { + var operand2 = i.Data.Get("literalString"); + value = operand2.ToLiteral(); + return true; + } + + if (i.Op == Specification.Op.OpSpecConstantOp) + { + var resultType = i.Data.Memory.Span[1]; + var resultId = i.Data.Memory.Span[2]; + var op = (Specification.Op)i.Data.Memory.Span[3]; + switch (op) + { + case Specification.Op.OpIMul: + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, out var leftTypeId)) + return false; + if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, out var rightTypeId)) + return false; + if (leftTypeId != resultType || rightTypeId != resultType) + return false; + value = (int)left * (int)right; + if (simplifyInBuffer) + Buffer.Replace(i.Index, new OpConstant(resultType, resultId, (int)value)); + return true; + default: + throw new NotImplementedException(); + } + } + + if ((i.Op == Specification.Op.OpConstantComposite || i.Op == Specification.Op.OpSpecConstantComposite) && + (OpConstantComposite)i is { } constantComposite) + { + var values = constantComposite.Values; + var constants = new object[values.WordCount]; + for (int j = 0; j < values.WordCount; ++j) + { + if (!TryGetConstantValue(values.Elements.Span[j], out constants[j], out _)) + return false; + } + + // For now we assume it's a vector type (but we would need to revisit that later if we handle more advanced constants such as matrix or arrays) + value = new ConstantVector { Values = constants }; + + return true; + } + + typeId = i.Op switch + { + Specification.Op.OpConstant or Specification.Op.OpSpecConstant => i.Data.Memory.Span[1], + }; + var operand = i.Data.Get("value"); + if (Buffer.TryGetInstructionById(typeId, out var typeInst)) + { + if (typeInst.Op == Specification.Op.OpTypeInt) + { + var type = (OpTypeInt)typeInst; + value = type switch + { + { Width: <= 32, Signedness: 0 } => operand.ToLiteral(), + { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), + { Width: 64, Signedness: 0 } => operand.ToLiteral(), + { Width: 64, Signedness: 1 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), + }; + return true; + } + else if (typeInst.Op == Specification.Op.OpTypeFloat) + { + var type = new OpTypeFloat(typeInst); + value = type switch + { + { Width: 16 } => operand.ToLiteral(), + { Width: 32 } => operand.ToLiteral(), + { Width: 64 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), + }; + return true; + } + else + throw new NotImplementedException($"Unsupported context dependent number with type {typeInst.Op}"); + } + + throw new Exception("Cannot find type instruction for id " + typeId); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs new file mode 100644 index 0000000000..c50e1d4ccf --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs @@ -0,0 +1,139 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing; + +namespace Stride.Shaders.Spirv.Building; + +public partial class SpirvContext +{ + public int InsertWithoutDuplicates(int? desiredResultId, NewSpirvBuffer source) + { + var index = Buffer.Count; + return InsertWithoutDuplicates(ref index, desiredResultId, source); + } + + public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, NewSpirvBuffer source) + { + // Import in current buffer (without duplicate) + var typeDuplicateInserter = new TypeDuplicateHelper(this); + var remapIds = new Dictionary(); + int lastResultId = -1; + + var lastResultIndex = -1; + if (desiredResultId != null) + { + // Find last index returning a value (that's the value we want remapped to desiredResultId) + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + if (i.Data.IdResult is not null) + lastResultIndex = index; + } + } + + for (int index = 0; index < source.Count; ++index) + { + var i = source[index]; + SpirvBuilder.RemapIds(remapIds, ref i.Data); + + //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() + var isGenericReference = i.Op == Specification.Op.OpSDSLGenericReference; + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; + + // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) + && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) + && (index != lastResultIndex || desiredResultId == null)) + { + // Make sure this data is declared at current index, otherwise move it. + // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops + if (existingData.Index > instructionIndex) + { + var existingDataCopy = new OpData(existingData.Data.Memory); + typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); + existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); + } + remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); + lastResultId = existingData.Data.IdResult.Value; + } + else + { + if (isGenericReference) + i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; + + if (i.Data.IdResult.HasValue) + { + // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID + var resultId = index == lastResultIndex && desiredResultId != null + ? desiredResultId.Value + : bound++; + + remapIds.Add(i.Data.IdResult.Value, resultId); + i.Data.IdResult = resultId; + typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + + lastResultId = resultId; + } + } + } + + if (lastResultId == -1) + throw new InvalidOperationException("Could not find any instruction with a value"); + + // Note: we made sure to not copy last instruction which should have the constant we want, so this case shouldn't happen anymore + if (desiredResultId != null && lastResultId != desiredResultId) + throw new InvalidOperationException(); + // Note: if we were to readd this, we would also need to process the main buffer + //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); + + return lastResultId; + } + + public NewSpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) + { + // First, run a simplification pass + // TODO: separate simplification from computing value? + TryGetConstantValue(constantId, out _, out _, true); + + // Go backward and find any reference + var newBuffer = new NewSpirvBuffer(); + var referenced = new HashSet { constantId }; + var instructions = new List(); + for (int index = Buffer.Count - 1; index >= 0; --index) + { + var i = Buffer[index]; + if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) + { + var i2 = new OpData(i.Data.Memory.Span); + + // Then add IdRef operands to next requested instructions or types + foreach (var op in i2) + { + if (op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.PairIdRefIdRef) + { + foreach (ref var word in op.Words) + { + referenced.Add(word); + } + } + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef + || op.Kind == OperandKind.PairIdRefLiteralInteger) + { + throw new NotImplementedException(); + } + } + + instructions.Add(i2); + } + } + + // Since we went backward, reverse the list + instructions.Reverse(); + foreach (var i in instructions) + newBuffer.Add(i); + return newBuffer; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index c85c71662b..2af744581e 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -24,7 +24,7 @@ public interface IExternalShaderLoader // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters -public class SpirvContext +public partial class SpirvContext { private int bound = 1; public int ResourceGroupBound { get; set; } = 1; @@ -32,7 +32,6 @@ public class SpirvContext public Dictionary Types { get; init; } = []; public Dictionary ReverseTypes { get; init; } = []; public Dictionary Names { get; init; } = []; - public Dictionary<(SymbolType Type, object Value), SpirvValue> LiteralConstants { get; } = []; NewSpirvBuffer Buffer { get; init; } public int? GLSLSet { get; private set; } @@ -70,29 +69,6 @@ public void AddName(int target, string name) public void AddMemberName(int target, int accessor, string name) => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); - public int AddConstant(TScalar value) - where TScalar : INumber - { - var data = value switch - { - byte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("byte")), Bound++, v)), - sbyte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("sbyte")), Bound++, v)), - ushort v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ushort")), Bound++, v)), - short v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("short")), Bound++, v)), - uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("uint")), Bound++, v)), - int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("int")), Bound++, v)), - ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ulong")), Bound++, v)), - long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("long")), Bound++, v)), - Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), - float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("float")), Bound++, v)), - double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("bdouble")), Bound++, v)), - _ => throw new NotImplementedException() - }; - if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) - return data.Memory.Span[index + 1]; - throw new Exception("Constant has no result id"); - } - public void SetEntryPoint(ExecutionModel model, int function, string name, ReadOnlySpan variables) { Span pvariables = stackalloc int[variables.Length]; @@ -420,6 +396,9 @@ public OpData Insert(int index, in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.InsertData(index, value); + public OpDataIndex Insert(int index, OpData data) + => Buffer.Insert(index, data); + public OpData Add(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.Add(value); @@ -427,6 +406,9 @@ public OpData Add(in T value) public OpDataIndex Add(OpData data) => Buffer.Add(data); + public void RemoveAt(int index, bool dispose) + => Buffer.RemoveAt(index, dispose); + public SpirvContext FluentAdd(in T value, out T result) where T : struct, IMemoryInstruction, allows ref struct @@ -437,137 +419,6 @@ public SpirvContext FluentAdd(in T value, out T result) public void Sort() => Buffer.Sort(); - public int InsertWithoutDuplicates(int? desiredResultId, NewSpirvBuffer source) - { - var index = Buffer.Count; - return InsertWithoutDuplicates(ref index, desiredResultId, source); - } - - public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, NewSpirvBuffer source) - { - // Import in current buffer (without duplicate) - var typeDuplicateInserter = new TypeDuplicateHelper(Buffer); - var remapIds = new Dictionary(); - int lastResultId = -1; - - var lastResultIndex = -1; - if (desiredResultId != null) - { - // Find last index returning a value (that's the value we want remapped to desiredResultId) - for (int index = 0; index < source.Count; ++index) - { - var i = source[index]; - if (i.Data.IdResult is not null) - lastResultIndex = index; - } - } - - for (int index = 0; index < source.Count; ++index) - { - var i = source[index]; - SpirvBuilder.RemapIds(remapIds, ref i.Data); - - //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() - var isGenericReference = i.Op == Op.OpSDSLGenericReference; - if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericParameter; - - // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) - if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) - && (index != lastResultIndex || desiredResultId == null)) - { - // Make sure this data is declared at current index, otherwise move it. - // Note: it should be safe to do so as the source buffer has all the dependencies and they should have been inserted in previous loops - if (existingData.Index > instructionIndex) - { - var existingDataCopy = new OpData(existingData.Data.Memory); - typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); - existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); - } - remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); - lastResultId = existingData.Data.IdResult.Value; - } - else - { - if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Op.OpSDSLGenericReference; - - if (i.Data.IdResult.HasValue) - { - // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID - var resultId = index == lastResultIndex && desiredResultId != null - ? desiredResultId.Value - : bound++; - - remapIds.Add(i.Data.IdResult.Value, resultId); - i.Data.IdResult = resultId; - typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); - - lastResultId = resultId; - } - } - } - - if (lastResultId == -1) - throw new InvalidOperationException("Could not find any instruction with a value"); - - // Note: we made sure to not copy last instruction which should have the constant we want, so this case shouldn't happen anymore - if (desiredResultId != null && lastResultId != desiredResultId) - throw new InvalidOperationException(); - // Note: if we were to readd this, we would also need to process the main buffer - //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); - - return lastResultId; - } - - public NewSpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) - { - // First, run a simplification pass - // TODO: separate simplification from computing value? - SpirvBuilder.TryGetConstantValue(constantId, out _, out _, Buffer, true); - - // Go backward and find any reference - var newBuffer = new NewSpirvBuffer(); - var referenced = new HashSet { constantId }; - var instructions = new List(); - for (int index = Buffer.Count - 1; index >= 0; --index) - { - var i = Buffer[index]; - if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) - { - var i2 = new OpData(i.Data.Memory.Span); - - // Then add IdRef operands to next requested instructions or types - foreach (var op in i2) - { - if (op.Kind == OperandKind.IdRef - || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefIdRef) - { - foreach (ref var word in op.Words) - { - referenced.Add(word); - } - } - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefLiteralInteger) - { - throw new NotImplementedException(); - } - } - - instructions.Add(i2); - } - } - - // Since we went backward, reverse the list - instructions.Reverse(); - foreach (var i in instructions) - newBuffer.Add(i); - return newBuffer; - } - [Obsolete("Use the insert method instead")] public NewSpirvBuffer GetBuffer() => Buffer; diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs index 05c373ab47..7fff1e531d 100644 --- a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -11,9 +11,9 @@ public static class SpirvProcessor { public static void Process(NewSpirvBuffer buffer) { - Apply(buffer); - // Apply(buffer); - Apply(buffer); + //Apply(buffer); + //Apply(buffer); + //Apply(buffer); } static void Apply(NewSpirvBuffer buffer) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 6fb77b6695..cab698cef3 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -50,7 +50,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Index: {Index}"; } - class OperationComparer(NewSpirvBuffer Buffer, bool UseIndices) : IComparer + class OperationComparer(SpirvContext Context, bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -97,7 +97,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) if (comparison != 0) return comparison; - comparison = CompareIntConstant(Buffer, x.Data.Memory.Span[3], y.Data.Memory.Span[3]); + comparison = CompareIntConstant(Context, x.Data.Memory.Span[3], y.Data.Memory.Span[3]); if (comparison != 0) return comparison; } @@ -135,13 +135,13 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) } } - private static int CompareIntConstant(NewSpirvBuffer buffer, int id1, int id2) + private static int CompareIntConstant(SpirvContext context, int id1, int id2) { if (id1 == id2) return 0; - var value1Success = SpirvBuilder.TryGetConstantValue(id1, out var value1, out _, buffer, false); - var value2Success = SpirvBuilder.TryGetConstantValue(id2, out var value2, out _, buffer, false); + var value1Success = context.TryGetConstantValue(id1, out var value1, out _, false); + var value2Success = context.TryGetConstantValue(id2, out var value2, out _, false); return (value1Success, value2Success) switch { @@ -154,34 +154,34 @@ private static int CompareIntConstant(NewSpirvBuffer buffer, int id1, int id2) }; } - private NewSpirvBuffer buffer; + private SpirvContext context; private List instructionsByOp; private List namesByOp; private OperationComparer comparerSort; private OperationComparer comparerInsert; private bool namesSorted; - public TypeDuplicateHelper(NewSpirvBuffer buffer) + public TypeDuplicateHelper(SpirvContext context) { - this.buffer = buffer; + this.context = context; instructionsByOp = new(); namesByOp = new(); namesSorted = false; - foreach (var i in buffer) + foreach (var i in context) { GetTargetList(i.Data).Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); } - comparerSort = new OperationComparer(buffer, true); + comparerSort = new OperationComparer(context, true); namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(buffer, false); + comparerInsert = new OperationComparer(context, false); } public OpDataIndex InsertInstruction(int index, OpData data) { - var result = buffer.Insert(index, data); + var result = context.Insert(index, data); // Adjust indices var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); @@ -213,7 +213,7 @@ public OpDataIndex InsertInstruction(int index, OpData data) public void RemoveInstructionAt(int index, bool dispose) { - buffer.RemoveAt(index, dispose); + context.RemoveAt(index, dispose); // Adjust indices and remove at same time var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); @@ -305,7 +305,7 @@ public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) if (index >= 0) { - foundData = new(instructionsByOp[index].Index, buffer); + foundData = new(instructionsByOp[index].Index, context.GetBuffer()); return true; } @@ -315,6 +315,8 @@ public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) public void RemoveDuplicates() { + var buffer = context.GetBuffer(); + // Note: We process instruction by types depending on their dependencies // i.e. a OpTypeFloat being unified means a OpTypeVector depending on it might too @@ -427,11 +429,3 @@ static void SetOpNop(Span words) words[1..].Clear(); } } - -public struct TypeDuplicateRemover : INanoPass -{ - public void Apply(NewSpirvBuffer buffer) - { - new TypeDuplicateHelper(buffer).RemoveDuplicates(); - } -} From f27e15f829af8b0585c05fdc5efe8f6ea7b4e689 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 17:15:45 +0900 Subject: [PATCH 0679/1182] Removed further usage of Context.GetBuffer() --- .../SDSL/ShaderMixer.CBuffers.cs | 4 +-- .../SDSL/ShaderMixer.ShaderInfo.cs | 2 +- .../SDSL/ShaderMixer.cs | 16 ++++----- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 6 ++-- .../Spirv/Building/Builder.Class.cs | 35 +++++++++---------- src/Stride.Shaders/Spirv/Building/Context.cs | 15 ++++++-- .../Spirv/Building/ExpressionExtensions.cs | 4 +-- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 024737d68f..ce5a8a8057 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -246,7 +246,7 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) var structId = context.Types[s]; var hasOffsetDecorations = false; - foreach (var i in context.GetBuffer()) + foreach (var i in context) { if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructureType == structId) { @@ -300,7 +300,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo var elementType = ConvertType(context, a.BaseType, typeModifier); var hasStrideDecoration = false; - foreach (var i in context.GetBuffer()) + foreach (var i in context) { if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ArrayStride } } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 4efdbd040e..d10c0c3334 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -89,7 +89,7 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext c // Second pass to remove OpName for (var index = contextStart; index < contextEnd; index++) { - var i = context.GetBuffer()[index]; + var i = context[index]; if (i.Data.Op == Op.OpName && (OpName)i is { } nameInstruction) { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index b6f10aeea7..135de38c9f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -115,7 +115,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, buffer.Add(new OpSDSLComposition(currentCompositionPath)); var mixinNode = new MixinNode(stage, currentCompositionPath); - var contextStart = context.GetBuffer().Count; + var contextStart = context.Count; // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); @@ -166,7 +166,7 @@ private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext mixinNode.StartInstruction = buffer.Count; foreach (var shaderClass in mixinSource.Mixins) { - var contextStart = context.GetBuffer().Count; + var contextStart = context.Count; var shaderInfo = MergeClassInBuffers(globalContext, context, buffer, mixinNode, shaderClass); @@ -174,8 +174,8 @@ private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext mixinNode.Shaders.Add(shaderInfo); // Note: we process name, types and struct right away, as they might be needed by the next Shader - ShaderClass.ProcessNameAndTypes(context, contextStart, context.GetBuffer().Count); - PopulateShaderInfo(globalContext, context, contextStart, context.GetBuffer().Count, buffer, shaderInfo.StartInstruction, shaderInfo.EndInstruction, shaderInfo, mixinNode); + ShaderClass.ProcessNameAndTypes(context, contextStart, context.Count); + PopulateShaderInfo(globalContext, context, contextStart, context.Count, buffer, shaderInfo.StartInstruction, shaderInfo.EndInstruction, shaderInfo, mixinNode); } mixinNode.EndInstruction = buffer.Count; @@ -196,7 +196,7 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo // Remember when we started to add instructions in both context and main buffer var shaderStart = buffer.Count; - var contextStart = context.GetBuffer().Count; + var contextStart = context.Count; var names = new Dictionary(); var forbiddenIds = new HashSet(); @@ -408,16 +408,16 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (addToContext) { - var i2Index = context.GetBuffer().Add(i2); + context.Add(i2); } } } } // Reprocess OpName/OpDecorate (they are defined before the OpType that was remapped, so we need to reprocess them) - for (int index = contextStart; index < context.GetBuffer().Count; ++index) + for (int index = contextStart; index < context.Count; ++index) { - var i = context.GetBuffer()[index]; + var i = context[index]; if (i.Op == Op.OpName || i.Op == Op.OpMemberName diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index b6feb516ab..98f40fddbe 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -43,7 +43,7 @@ public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration public static void ProcessNameAndTypes(SpirvContext context, IShaderImporter? shaderImporter = null, bool allowReplace = false) { - ProcessNameAndTypes(context, 0, context.GetBuffer().Count, shaderImporter, allowReplace); + ProcessNameAndTypes(context, 0, context.Count, shaderImporter, allowReplace); } public static void ProcessNameAndTypes(SpirvContext context, int start, int end, IShaderImporter? shaderImporter = null, bool allowReplace = false) @@ -77,7 +77,7 @@ void RegisterName(int target, string name) var blocks = new HashSet(); for (var i = start; i < end; i++) { - var instruction = context.GetBuffer()[i]; + var instruction = context[i]; if (instruction.Op == Op.OpName) { OpName nameInstruction = instruction; @@ -258,7 +258,7 @@ void RegisterName(int target, string name) // Second pass (for processing when info from first pass is needed) for (var i = start; i < end; i++) { - var instruction = context.GetBuffer()[i]; + var instruction = context[i]; // Can be declared before OpTypeStruct, so done in second pass if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index de24b855e0..da7809b9c5 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -228,8 +228,7 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - var contextBuffer = context.GetBuffer(); - var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; + var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; var genericValue = genericValues![genericIndex]; textValue = genericValue; switch (genericParameterType) @@ -241,11 +240,11 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType throw new InvalidOperationException("Can't parse generic value"); var localContext = new SpirvContext(); var result = expression.CompileConstantValue(new SymbolTable(localContext), localContext, genericParameterType); - contextBuffer.RemoveAt(instructionIndex); + context.RemoveAt(instructionIndex); context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, localContext.GetBuffer()); return true; case GenericParameterType g: - contextBuffer.Replace(instructionIndex++, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); + context.Replace(instructionIndex++, new OpConstantStringSDSL(genericParameter.ResultId, genericValue)); return true; default: throw new NotImplementedException(); @@ -282,7 +281,6 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - var contextBuffer = context.GetBuffer(); // Check if generic value can already be computed (no OpSDSLGenericParameter and such) if (declaringContext.TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, false)) { @@ -294,7 +292,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType textValue = GetIdRefAsString(genericIndex); } - var genericParameter = (OpSDSLGenericParameter)contextBuffer[instructionIndex]; + var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; var bufferWithConstant = declaringContext.ExtractConstantAsSpirvBuffer(classSource.GenericArguments[genericIndex]); bool resolved = true; @@ -311,7 +309,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType } } - contextBuffer.RemoveAt(instructionIndex); + context.RemoveAt(instructionIndex); // TODO: Try to simplify constant var bound = context.Bound; @@ -345,9 +343,9 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st var semantics = new Dictionary(); var genericParameters = new List(); - for (int index = 0; index < shaderBuffers.Context.GetBuffer().Count; ++index) + for (int index = 0; index < shaderBuffers.Context.Count; ++index) { - var i = shaderBuffers.Context.GetBuffer()[index]; + var i = shaderBuffers.Context[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; @@ -409,17 +407,16 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } - TransformResolvedSemantics(shaderBuffers.Context.GetBuffer(), semantics); - TransformResolvedLinkIdIntoLinkString(shaderBuffers.Context.GetBuffer(), resolvedLinks); + TransformResolvedSemantics(shaderBuffers.Context, semantics); + TransformResolvedLinkIdIntoLinkString(shaderBuffers.Context, resolvedLinks); genericResolver.PostProcess(classNameWithGenerics, genericParameters); } - private static void TransformResolvedSemantics(NewSpirvBuffer contextBuffer, Dictionary semantics) + private static void TransformResolvedSemantics(SpirvContext context, Dictionary semantics) { - for (var index = 0; index < contextBuffer.Count; index++) + foreach (var i in context) { - var i = contextBuffer[index]; if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m } } decorate) { var n = new LiteralValue(m.Span); @@ -503,18 +500,18 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri } } - private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer contextBuffer, Dictionary resolvedLinks) + private static void TransformResolvedLinkIdIntoLinkString(SpirvContext context, Dictionary resolvedLinks) { // Try to resolve LinkType generics - for (var index = 0; index < contextBuffer.Count; index++) + for (var index = 0; index < context.Count; index++) { - var i = contextBuffer[index]; + var i = context[index]; if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) { using var n = new LiteralValue(m.Span); if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) { - contextBuffer.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + context.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m2 } } linkDecorate2) @@ -522,7 +519,7 @@ private static void TransformResolvedLinkIdIntoLinkString(NewSpirvBuffer context using var n = new LiteralValue(m2.Span); if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) { - contextBuffer.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + context.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); } } } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 2af744581e..7a35b78c6c 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -32,6 +32,11 @@ public partial class SpirvContext public Dictionary Types { get; init; } = []; public Dictionary ReverseTypes { get; init; } = []; public Dictionary Names { get; init; } = []; + + public OpDataIndex this[int index] => new(index, Buffer); + + public int Count => Buffer.Count; + NewSpirvBuffer Buffer { get; init; } public int? GLSLSet { get; private set; } @@ -392,7 +397,11 @@ public SpirvValue CompileConstantLiteral(Literal literal) return result; } - public OpData Insert(int index, in T value) + public T Insert(int index, in T value) + where T : struct, IMemoryInstruction, allows ref struct + => Buffer.Insert(index, value); + + public OpData InsertData(int index, in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.InsertData(index, value); @@ -406,9 +415,11 @@ public OpData Add(in T value) public OpDataIndex Add(OpData data) => Buffer.Add(data); - public void RemoveAt(int index, bool dispose) + public void RemoveAt(int index, bool dispose = true) => Buffer.RemoveAt(index, dispose); + public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct + => Buffer.Replace(index, instruction); public SpirvContext FluentAdd(in T value, out T result) where T : struct, IMemoryInstruction, allows ref struct diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index b799b8a41d..ce06d85c83 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -81,7 +81,7 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol i.Data.Memory.Span[0] = (int)Op.OpSpecConstantComposite | (i.Data.Memory.Length << 16); // TODO: Check no IdRef to things outside context - var instruction = context.GetBuffer().Add(new(i.Data.Memory.Span)); + var instruction = context.Add(new(i.Data.Memory.Span)); result = new(instruction.Data); } // Rewrite using OpSpecConstantOp when possible @@ -94,7 +94,7 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol instruction[0] |= instruction.Length << 16; // TODO: Check no IdRef to things outside context - context.GetBuffer().Add(new OpData(instruction)); + context.Add(new OpData(instruction)); result = new(resultId, resultType); } else From dfbf163122d655d153a02d0dc02b0c24d7fef120 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 17:21:26 +0900 Subject: [PATCH 0680/1182] Furhter splitted SpirvContext method into partial files --- .../Spirv/Building/Context.Constants.cs | 124 +++++++ src/Stride.Shaders/Spirv/Building/Context.cs | 313 ------------------ .../Spirv/Building/SpirvContext.Types.cs | 207 ++++++++++++ 3 files changed, 331 insertions(+), 313 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index 02b4770791..06c8257379 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -1,5 +1,7 @@ using System.Numerics; using Stride.Shaders.Core; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -159,4 +161,126 @@ public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, throw new Exception("Cannot find type instruction for id " + typeId); } + + public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size) + { + var value = CompileConstantLiteral(literal); + if (size == 1) + return value; + + Span values = stackalloc int[size]; + for (int i = 0; i < size; ++i) + values[i] = size; + + var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); + var instruction = Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values))); + + return new(instruction); + } + + public Literal CreateLiteral(object value, TextLocation location = default) + { + return value switch + { + bool i => new BoolLiteral(i, location), + sbyte i => new IntegerLiteral(new(8, false, true), i, location), + byte i => new IntegerLiteral(new(8, false, false), i, location), + short i => new IntegerLiteral(new(16, false, true), i, location), + ushort i => new IntegerLiteral(new(16, false, false), i, location), + int i => new IntegerLiteral(new(32, false, true), i, location), + uint i => new IntegerLiteral(new(32, false, false), i, location), + long i => new IntegerLiteral(new(64, false, true), i, location), + ulong i => new IntegerLiteral(new(64, false, false), (long)i, location), + float i => new FloatLiteral(new(32, true, true), i, null, location), + double i => new FloatLiteral(new(64, true, true), i, null, location), + }; + } + + public SpirvValue CompileConstant(object value, TextLocation location = default) + { + return CompileConstantLiteral(CreateLiteral(value, location)); + } + + public SpirvValue CompileConstantLiteral(Literal literal) + { + object literalValue = literal switch + { + BoolLiteral lit => lit.Value, + IntegerLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.LongValue, + _ => lit.IntValue, + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => lit.DoubleValue, + _ => (float)lit.DoubleValue, + }, + }; + + if (literal.Type == null) + { + literal.Type = literal switch + { + BoolLiteral lit => ScalarType.From("bool"), + IntegerLiteral lit => lit.Suffix switch + { + { Signed: true, Size: 8 } => ScalarType.From("sbyte"), + { Signed: true, Size: 16 } => ScalarType.From("short"), + { Signed: true, Size: 32 } => ScalarType.From("int"), + { Signed: true, Size: 64 } => ScalarType.From("long"), + { Signed: false, Size: 8 } => ScalarType.From("byte"), + { Signed: false, Size: 16 } => ScalarType.From("ushort"), + { Signed: false, Size: 32 } => ScalarType.From("uint"), + { Signed: false, Size: 64 } => ScalarType.From("ulong"), + _ => throw new NotImplementedException("Unsupported integer suffix") + }, + FloatLiteral lit => lit.Suffix.Size switch + { + 16 => ScalarType.From("half"), + 32 => ScalarType.From("float"), + 64 => ScalarType.From("double"), + _ => throw new NotImplementedException("Unsupported float") + }, + }; + } + + if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) + return result; + + var instruction = literal switch + { + BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), + BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(GetOrRegister(lit.Type), Bound++)), + IntegerLiteral lit => lit.Suffix switch + { + { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (byte)lit.IntValue)), + { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), + { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), + { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), + { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), + { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), + { Size: <= 64, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), + { Size: <= 64, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), + _ => throw new NotImplementedException() + }, + FloatLiteral lit => lit.Suffix.Size switch + { + > 32 => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.DoubleValue)), + _ => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (float)lit.DoubleValue)), + }, + _ => throw new NotImplementedException() + }; + + result = new(instruction); + LiteralConstants.Add((literal.Type, literalValue), result); + AddName(result.Id, literal switch + { + BoolLiteral lit => $"{lit.Type}_{lit.Value}", + IntegerLiteral lit => $"{lit.Type}_{lit.Value}", + FloatLiteral lit => $"{lit.Type}_{lit.Value}", + _ => throw new NotImplementedException() + }); + return result; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 7a35b78c6c..e422ce04d1 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -83,319 +83,6 @@ public void SetEntryPoint(ExecutionModel model, int function, string name, ReadO Buffer.Add(new OpEntryPoint(model, function, name, [.. pvariables])); } - public int GetOrRegister(SymbolType? type) - { - if (type is null) - throw new ArgumentException($"Type is null"); - if (Types.TryGetValue(type, out var res)) - return res; - else - { - var instruction = type switch - { - ScalarType s => - s.TypeName switch - { - "void" => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, - "bool" => Buffer.Add(new OpTypeBool(Bound++)).IdResult, - "sbyte" => Buffer.Add(new OpTypeInt(Bound++, 8, 1)).IdResult, - "byte" => Buffer.Add(new OpTypeInt(Bound++, 8, 0)).IdResult, - "ushort" => Buffer.Add(new OpTypeInt(Bound++, 16, 1)).IdResult, - "short" => Buffer.Add(new OpTypeInt(Bound++, 16, 0)).IdResult, - "int" => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, - "uint" => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, - "long" => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, - "ulong" => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, - "half" => Buffer.Add(new OpTypeFloat(Bound++, 16, null)).IdResult, - "float" => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, - "double" => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, - _ => throw new NotImplementedException($"Can't add type {type}") - - }, - VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, - MatrixType m => Buffer.Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)).IdResult, - ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), - ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, - StructType st => RegisterStructuredType(st.ToId(), st), - FunctionType f => RegisterFunctionType(f), - PointerType p => RegisterPointerType(p), - LoadedShaderSymbol s => ImportShaderType(s), - Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - TextureCubeType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, - BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Dim.Buffer, 2, 0, 0, 1, ImageFormat.Unknown, null)).IdResult, - SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, - GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, - StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(Bound++)).IdResult, - // StructSymbol st => RegisterStruct(st), - _ => throw new NotImplementedException($"Can't add type {type}") - }; - Types[type] = instruction ?? -1; - ReverseTypes[instruction ?? -1] = type; - return instruction ?? -1; - } - } - - private int? RegisterArrayType(ArrayType a) - { - int sizeId; - if (a.Size != -1) - { - sizeId = CompileConstant((int)a.Size).Id; - } - else if (a.SizeExpression is { } sizeExpression) - { - // Import constants - var importBuffer = sizeExpression.Buffer; - if (importBuffer != Buffer) - { - var resultId = InsertWithoutDuplicates(null, importBuffer); - - sizeId = resultId; - } - else - { - sizeId = sizeExpression.Id; - } - } - else - { - throw new InvalidOperationException(); - } - - return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; - } - - public int ImportShaderType(LoadedShaderSymbol shaderSymbol) - { - FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), out var shader); - AddName(shader.ResultId, shaderSymbol.Name); - - // Import struct - var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); - foreach (ref var structType in structTypes) - { - ImportShaderStruct(shader, structType.Type, out structType.ImportedId); - } - - // Note: Variables and methods are imported lazily in LoadedShaderSymbol.TryResolveSymbol() - - return shader.ResultId; - } - - private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) - { - FluentAdd(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId), out var @struct); - AddName(@struct.ResultId, structType.Name); - - // Fill the ID - structImportedId = @struct.ResultId; - - // Register it so that it can be used right after during OpVariable for cbuffer - Types.Add(structType, structImportedId); - ReverseTypes.Add(structImportedId, structType); - } - - public void ImportShaderVariable(int shaderId, ref Symbol symbol, VariableFlagsMask flags) - { - symbol.IdRef = Bound++; - Add(new OpSDSLImportVariable(symbol.IdRef, GetOrRegister(symbol.Type), symbol.Id.Name, shaderId, flags)); - AddName(symbol.IdRef, symbol.Id.Name); - } - - public void ImportShaderMethod(int shaderId, ref Symbol symbol, FunctionFlagsMask flags) - { - var functionType = (FunctionType)symbol.Type; - var functionTypeId = GetOrRegister(functionType); - - symbol.IdRef = Bound++; - Add(new OpSDSLImportFunction(symbol.IdRef, functionTypeId, symbol.Id.Name, shaderId, flags)); - AddName(symbol.IdRef, symbol.Id.Name); - } - - public int DeclareCBuffer(ConstantBufferSymbol cb) - { - var result = DeclareStructuredType(cb); - - Buffer.Add(new OpDecorate(result, Decoration.Block)); - - return result; - } - - int RegisterStructuredType(string name, StructuredType structSymbol) - { - throw new InvalidOperationException(); - } - - public int DeclareStructuredType(StructuredType structSymbol) - { - Span types = stackalloc int[structSymbol.Members.Count]; - for (var index = 0; index < structSymbol.Members.Count; index++) - types[index] = GetOrRegister(structSymbol.Members[index].Type); - - var result = Add(new OpTypeStruct(Bound++, [.. types])); - var id = result.IdResult ?? throw new InvalidOperationException(); - AddName(id, structSymbol.ToId()); - for (var index = 0; index < structSymbol.Members.Count; index++) - { - var member = structSymbol.Members[index]; - AddMemberName(id, index, member.Name); - } - - Types[structSymbol] = id; - ReverseTypes[id] = structSymbol; - - return id; - } - - - int RegisterFunctionType(FunctionType functionType) - { - Span<(int, int)> types = stackalloc (int, int)[functionType.ParameterTypes.Count]; - for (int i = 0; i < functionType.ParameterTypes.Count; i++) - { - types[i].Item1 = GetOrRegister(functionType.ParameterTypes[i].Type); - types[i].Item2 = (int)functionType.ParameterTypes[i].Modifiers; - } - - var result = Buffer.Add(new OpTypeFunctionSDSL(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); - // disabled for now: currently it generates name with {}, not working with most SPIRV tools - // AddName(result, functionType.ToId()); - return result.IdResult ?? -1; - } - - int RegisterPointerType(PointerType pointerType) - { - var baseType = GetOrRegister(pointerType.BaseType); - var result = Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); - var id = result.IdResult; - AddName(id ?? -1, pointerType.ToId()); - return id ?? -1; - } - - public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size) - { - var value = CompileConstantLiteral(literal); - if (size == 1) - return value; - - Span values = stackalloc int[size]; - for (int i = 0; i < size; ++i) - values[i] = size; - - var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); - var instruction = Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values))); - - return new(instruction); - } - - public Literal CreateLiteral(object value, TextLocation location = default) - { - return value switch - { - bool i => new BoolLiteral(i, location), - sbyte i => new IntegerLiteral(new(8, false, true), i, location), - byte i => new IntegerLiteral(new(8, false, false), i, location), - short i => new IntegerLiteral(new(16, false, true), i, location), - ushort i => new IntegerLiteral(new(16, false, false), i, location), - int i => new IntegerLiteral(new(32, false, true), i, location), - uint i => new IntegerLiteral(new(32, false, false), i, location), - long i => new IntegerLiteral(new(64, false, true), i, location), - ulong i => new IntegerLiteral(new(64, false, false), (long)i, location), - float i => new FloatLiteral(new(32, true, true), i, null, location), - double i => new FloatLiteral(new(64, true, true), i, null, location), - }; - } - - public SpirvValue CompileConstant(object value, TextLocation location = default) - { - return CompileConstantLiteral(CreateLiteral(value, location)); - } - - public SpirvValue CompileConstantLiteral(Literal literal) - { - object literalValue = literal switch - { - BoolLiteral lit => lit.Value, - IntegerLiteral lit => lit.Suffix.Size switch - { - > 32 => lit.LongValue, - _ => lit.IntValue, - }, - FloatLiteral lit => lit.Suffix.Size switch - { - > 32 => lit.DoubleValue, - _ => (float)lit.DoubleValue, - }, - }; - - if (literal.Type == null) - { - literal.Type = literal switch - { - BoolLiteral lit => ScalarType.From("bool"), - IntegerLiteral lit => lit.Suffix switch - { - { Signed: true, Size: 8 } => ScalarType.From("sbyte"), - { Signed: true, Size: 16 } => ScalarType.From("short"), - { Signed: true, Size: 32 } => ScalarType.From("int"), - { Signed: true, Size: 64 } => ScalarType.From("long"), - { Signed: false, Size: 8 } => ScalarType.From("byte"), - { Signed: false, Size: 16 } => ScalarType.From("ushort"), - { Signed: false, Size: 32 } => ScalarType.From("uint"), - { Signed: false, Size: 64 } => ScalarType.From("ulong"), - _ => throw new NotImplementedException("Unsupported integer suffix") - }, - FloatLiteral lit => lit.Suffix.Size switch - { - 16 => ScalarType.From("half"), - 32 => ScalarType.From("float"), - 64 => ScalarType.From("double"), - _ => throw new NotImplementedException("Unsupported float") - }, - }; - } - - if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) - return result; - - var instruction = literal switch - { - BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), - BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(GetOrRegister(lit.Type), Bound++)), - IntegerLiteral lit => lit.Suffix switch - { - { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (byte)lit.IntValue)), - { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), - { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), - { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), - { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), - { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), - { Size: <= 64, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), - { Size: <= 64, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), - _ => throw new NotImplementedException() - }, - FloatLiteral lit => lit.Suffix.Size switch - { - > 32 => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.DoubleValue)), - _ => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (float)lit.DoubleValue)), - }, - _ => throw new NotImplementedException() - }; - - result = new(instruction); - LiteralConstants.Add((literal.Type, literalValue), result); - AddName(result.Id, literal switch - { - BoolLiteral lit => $"{lit.Type}_{lit.Value}", - IntegerLiteral lit => $"{lit.Type}_{lit.Value}", - FloatLiteral lit => $"{lit.Type}_{lit.Value}", - _ => throw new NotImplementedException() - }); - return result; - } public T Insert(int index, in T value) where T : struct, IMemoryInstruction, allows ref struct diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs new file mode 100644 index 0000000000..579bfac285 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -0,0 +1,207 @@ +using System.Runtime.InteropServices; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Spirv.Building; + +public partial class SpirvContext +{ + public int GetOrRegister(SymbolType? type) + { + if (type is null) + throw new ArgumentException($"Type is null"); + if (Types.TryGetValue(type, out var res)) + return res; + else + { + var instruction = type switch + { + ScalarType s => + s.TypeName switch + { + "void" => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, + "bool" => Buffer.Add(new OpTypeBool(Bound++)).IdResult, + "sbyte" => Buffer.Add(new OpTypeInt(Bound++, 8, 1)).IdResult, + "byte" => Buffer.Add(new OpTypeInt(Bound++, 8, 0)).IdResult, + "ushort" => Buffer.Add(new OpTypeInt(Bound++, 16, 1)).IdResult, + "short" => Buffer.Add(new OpTypeInt(Bound++, 16, 0)).IdResult, + "int" => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, + "uint" => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, + "long" => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, + "ulong" => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, + "half" => Buffer.Add(new OpTypeFloat(Bound++, 16, null)).IdResult, + "float" => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, + "double" => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, + _ => throw new NotImplementedException($"Can't add type {type}") + }, + VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, + MatrixType m => Buffer + .Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)) + .IdResult, + ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), + ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer + .Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, + StructType st => RegisterStructuredType(st.ToId(), st), + FunctionType f => RegisterFunctionType(f), + PointerType p => RegisterPointerType(p), + LoadedShaderSymbol s => ImportShaderType(s), + Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + TextureCubeType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, + BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Specification.Dim.Buffer, + 2, 0, 0, 1, Specification.ImageFormat.Unknown, null)).IdResult, + SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, + GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, + StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(Bound++)).IdResult, + // StructSymbol st => RegisterStruct(st), + _ => throw new NotImplementedException($"Can't add type {type}") + }; + Types[type] = instruction ?? -1; + ReverseTypes[instruction ?? -1] = type; + return instruction ?? -1; + } + } + + private int? RegisterArrayType(ArrayType a) + { + int sizeId; + if (a.Size != -1) + { + sizeId = CompileConstant((int)a.Size).Id; + } + else if (a.SizeExpression is { } sizeExpression) + { + // Import constants + var importBuffer = sizeExpression.Buffer; + if (importBuffer != Buffer) + { + var resultId = InsertWithoutDuplicates(null, importBuffer); + + sizeId = resultId; + } + else + { + sizeId = sizeExpression.Id; + } + } + else + { + throw new InvalidOperationException(); + } + + return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; + } + + public int ImportShaderType(LoadedShaderSymbol shaderSymbol) + { + FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), + out var shader); + AddName(shader.ResultId, shaderSymbol.Name); + + // Import struct + var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); + foreach (ref var structType in structTypes) + { + ImportShaderStruct(shader, structType.Type, out structType.ImportedId); + } + + // Note: Variables and methods are imported lazily in LoadedShaderSymbol.TryResolveSymbol() + + return shader.ResultId; + } + + private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) + { + FluentAdd(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId), out var @struct); + AddName(@struct.ResultId, structType.Name); + + // Fill the ID + structImportedId = @struct.ResultId; + + // Register it so that it can be used right after during OpVariable for cbuffer + Types.Add(structType, structImportedId); + ReverseTypes.Add(structImportedId, structType); + } + + public void ImportShaderVariable(int shaderId, ref Symbol symbol, Specification.VariableFlagsMask flags) + { + symbol.IdRef = Bound++; + Add(new OpSDSLImportVariable(symbol.IdRef, GetOrRegister(symbol.Type), symbol.Id.Name, shaderId, flags)); + AddName(symbol.IdRef, symbol.Id.Name); + } + + public void ImportShaderMethod(int shaderId, ref Symbol symbol, Specification.FunctionFlagsMask flags) + { + var functionType = (FunctionType)symbol.Type; + var functionTypeId = GetOrRegister(functionType); + + symbol.IdRef = Bound++; + Add(new OpSDSLImportFunction(symbol.IdRef, functionTypeId, symbol.Id.Name, shaderId, flags)); + AddName(symbol.IdRef, symbol.Id.Name); + } + + public int DeclareCBuffer(ConstantBufferSymbol cb) + { + var result = DeclareStructuredType(cb); + + Buffer.Add(new OpDecorate(result, Specification.Decoration.Block)); + + return result; + } + + private int RegisterStructuredType(string name, StructuredType structSymbol) + { + throw new InvalidOperationException(); + } + + public int DeclareStructuredType(StructuredType structSymbol) + { + Span types = stackalloc int[structSymbol.Members.Count]; + for (var index = 0; index < structSymbol.Members.Count; index++) + types[index] = GetOrRegister(structSymbol.Members[index].Type); + + var result = Add(new OpTypeStruct(Bound++, [.. types])); + var id = result.IdResult ?? throw new InvalidOperationException(); + AddName(id, structSymbol.ToId()); + for (var index = 0; index < structSymbol.Members.Count; index++) + { + var member = structSymbol.Members[index]; + AddMemberName(id, index, member.Name); + } + + Types[structSymbol] = id; + ReverseTypes[id] = structSymbol; + + return id; + } + + private int RegisterFunctionType(FunctionType functionType) + { + Span<(int, int)> types = stackalloc (int, int)[functionType.ParameterTypes.Count]; + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + { + types[i].Item1 = GetOrRegister(functionType.ParameterTypes[i].Type); + types[i].Item2 = (int)functionType.ParameterTypes[i].Modifiers; + } + + var result = Buffer.Add(new OpTypeFunctionSDSL(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); + // disabled for now: currently it generates name with {}, not working with most SPIRV tools + // AddName(result, functionType.ToId()); + return result.IdResult ?? -1; + } + + private int RegisterPointerType(PointerType pointerType) + { + var baseType = GetOrRegister(pointerType.BaseType); + var result = Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); + var id = result.IdResult; + AddName(id ?? -1, pointerType.ToId()); + return id ?? -1; + } +} \ No newline at end of file From b6ff89e2392f0f87bb686957e4697ff17067904f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 17:57:15 +0900 Subject: [PATCH 0681/1182] Added support for bool generics --- assets/SDSL/RenderTests/GenericsEffect.sdsl | 19 +++++++++++++++++-- .../Parsers/ShaderParsers/ShaderParameters.cs | 5 +++++ .../Spirv/Building/Builder.Class.cs | 2 ++ .../Spirv/Building/Context.Constants.cs | 11 +++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/assets/SDSL/RenderTests/GenericsEffect.sdsl b/assets/SDSL/RenderTests/GenericsEffect.sdsl index a2091d124f..8db83b979a 100644 --- a/assets/SDSL/RenderTests/GenericsEffect.sdsl +++ b/assets/SDSL/RenderTests/GenericsEffect.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#34302425) +// PSMain(ExpectedResult=#3935292A) namespace Stride.Shaders.Tests; @@ -34,7 +34,22 @@ shader ComputeFixed3 : Compute } } -shader GenericsEffectTest : Compute +shader ComputeBool : Compute +{ + override float4 Compute() + { + if (T1) + { + if (T2) + { + return 5.0; + } + } + return 0.0; + } +} + +shader GenericsEffectTest : Compute, ComputeBool { stream float4 ColorTarget : SV_Target0; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index d463cce273..8d19ee8ab7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -112,6 +112,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = number; return true; } + else if (LiteralsParser.Boolean(ref scanner, result, out var boolean)) + { + parsed = boolean; + return true; + } else if (LiteralsParser.Vector(ref scanner, result, out var vector)) { parsed = vector; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index da7809b9c5..4d44292108 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -113,6 +113,8 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL { if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { + if (genericParameter.Index >= classSource.GenericArguments.Length) + throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassName()}"); genericParameterRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericParameter.Index]); } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index 06c8257379..b782e62e75 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -123,6 +123,17 @@ public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, return true; } + if (i.Op == Specification.Op.OpConstantTrue) + { + value = true; + return true; + } + if (i.Op == Specification.Op.OpConstantFalse) + { + value = false; + return true; + } + typeId = i.Op switch { Specification.Op.OpConstant or Specification.Op.OpSpecConstant => i.Data.Memory.Span[1], From 6503bd50b73e91a367feec07370f16e587c8d52e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 21:31:56 +0900 Subject: [PATCH 0682/1182] Fix Parser with array accessor --- assets/SDSL/RenderTests/ArrayParameter.sdsl | 75 +++++++++++++++++++ .../SDSL/Parsers/Common/CommonParsers.cs | 2 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 28 +++---- 3 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 assets/SDSL/RenderTests/ArrayParameter.sdsl diff --git a/assets/SDSL/RenderTests/ArrayParameter.sdsl b/assets/SDSL/RenderTests/ArrayParameter.sdsl new file mode 100644 index 0000000000..bdc16f634a --- /dev/null +++ b/assets/SDSL/RenderTests/ArrayParameter.sdsl @@ -0,0 +1,75 @@ +// PSMain(ExpectedResult=#1A052510) + +namespace Stride.Shaders.Tests; + +shader CompositionBase +{ + float Compute() + { + return 3.0 / 255.0; + } +}; + +shader CompositionShaderA : CompositionBase +{ + override float Compute() + { + return 5.0 / 255.0; + } +}; + +shader CompositionShaderB : CompositionBase +{ + override float Compute() + { + return base.Compute() + 13.0 / 255.0; + } +}; + +shader CompositionTestArray +{ + stage compose CompositionBase CompsInheritedStage[]; + compose CompositionBase CompsInherited[]; +} + +shader CompositionTest : CompositionTestArray +{ + stream float4 ColorTarget : SV_Target0; + + stage compose CompositionBase CompsStage[]; + compose CompositionBase Comps[]; + + void PSMain() + { + streams.ColorTarget = 0.0; + foreach(var comp in CompsStage) + { + streams.ColorTarget.x += comp.Compute(); + } + foreach(var comp in Comps) + { + streams.ColorTarget.y += comp.Compute(); + } + foreach(var comp in CompsInheritedStage) + { + streams.ColorTarget.z += comp.Compute(); + } + foreach(var comp in CompsInherited) + { + streams.ColorTarget.w += comp.Compute(); + } + } +}; + +effect CompositionArray1 +{ + mixin CompositionTest; + mixin compose CompsStage += CompositionShaderA; + mixin compose CompsStage += CompositionShaderA; + mixin compose CompsStage += CompositionShaderB; + mixin compose Comps += CompositionShaderA; + mixin compose CompsInheritedStage += CompositionShaderA; + mixin compose CompsInheritedStage += CompositionShaderB; + mixin compose CompsInheritedStage += CompositionShaderB; + mixin compose CompsInherited += CompositionShaderB; +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index b8c351088b..76a235eec0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -399,7 +399,7 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result } else break; } - return true; + return arraySizes.Count > 0; } public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Mixin mixin, out Expression? arraySize, out Expression? value, bool advance = true) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 13c3180c19..3a28d07b65 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -69,11 +69,11 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, var position = scanner.Position; if (Tokens.Char('_', ref scanner) || Tokens.Letter(ref scanner)) { - name = new TypeName("", new()); scanner.Advance(1); while (Tokens.LetterOrDigit(ref scanner) || Tokens.Char('_', ref scanner)) scanner.Advance(1); var identifier = new Identifier(scanner.Memory[position..scanner.Position].ToString(), scanner[position..scanner.Position]); + name = new TypeName(identifier.Name, scanner[position..scanner.Position]); var intermediate = scanner.Position; @@ -83,32 +83,26 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); if (!Parsers.FollowedBy(ref scanner, Tokens.Char('>'), withSpaces: true, advance: true)) return Parsers.Exit(ref scanner, result, out name, position); - ((TypeName)name).Generics = generics; + name.Info = scanner[position..scanner.Position]; + name.Generics = generics; intermediate = scanner.Position; } + else + { + scanner.Position = intermediate; + } - - if ( - Parsers.Spaces0(ref scanner, result, out _) - && Tokens.Char('[', ref scanner, advance: true) - && Parsers.Spaces0(ref scanner, result, out _) - && Parsers.Optional(ref scanner, new ExpressionParser(), result, out _) - && Parsers.Spaces0(ref scanner, result, out _) - && Tokens.Char(']', ref scanner, advance: true) - ) + if (Parsers.FollowedByDelList(ref scanner, result, Parsers.ArraySizes, out List arraySize, withSpaces: true, advance: true)) { - ((TypeName)name).Name = scanner.Memory[position..scanner.Position].ToString().Trim(); name.Info = scanner[position..scanner.Position]; - throw new NotImplementedException(); - return true; + name.ArraySize = arraySize; } else { scanner.Position = intermediate; - ((TypeName)name).Name = identifier.Name; - name.Info = scanner[position..scanner.Position]; - return true; } + + return true; } else return Parsers.Exit(ref scanner, result, out name, position, orError); } From d9137476fbd472164757a17e87a8e12497cc2bd0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 22:42:44 +0900 Subject: [PATCH 0683/1182] Array: various improvements for proper array size evaluation and casting --- assets/SDSL/RenderTests/ArrayParameter.sdsl | 88 ++++++------------- src/Stride.Shaders/Core/SymbolTypes.cs | 2 + .../Spirv/Building/Builder.Expressions.cs | 18 +++- .../Spirv/Building/SpirvContext.Types.cs | 6 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 4 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 11 +++ 6 files changed, 64 insertions(+), 65 deletions(-) diff --git a/assets/SDSL/RenderTests/ArrayParameter.sdsl b/assets/SDSL/RenderTests/ArrayParameter.sdsl index bdc16f634a..a49ef258ff 100644 --- a/assets/SDSL/RenderTests/ArrayParameter.sdsl +++ b/assets/SDSL/RenderTests/ArrayParameter.sdsl @@ -1,75 +1,41 @@ -// PSMain(ExpectedResult=#1A052510) +// PSMain(ExpectedResult=#24242424) namespace Stride.Shaders.Tests; -shader CompositionBase +shader SphericalHarmonicsUtils { - float Compute() - { - return 3.0 / 255.0; - } -}; - -shader CompositionShaderA : CompositionBase -{ - override float Compute() - { - return 5.0 / 255.0; - } -}; - -shader CompositionShaderB : CompositionBase -{ - override float Compute() - { - return base.Compute() + 13.0 / 255.0; - } -}; + float4 EvaluateSphericalHarmonics(float4 sphericalColors[TOrder * TOrder]) + { + float4 result = 0.0; + for (int i = 0; i < TOrder * TOrder; ++i) + { + sphericalColors[i] = i / 255.0; + result += sphericalColors[i]; + } + return result; + } +} -shader CompositionTestArray +shader SphericalHarmonicsEnvironmentColor : SphericalHarmonicsUtils { - stage compose CompositionBase CompsInheritedStage[]; - compose CompositionBase CompsInherited[]; -} + cbuffer PerView.Lighting + { + [Color] + float4 SphericalColors[TOrder * TOrder]; + } + + float4 Compute() + { + return EvaluateSphericalHarmonics(SphericalColors); + } +}; -shader CompositionTest : CompositionTestArray +shader ArrayParameter : SphericalHarmonicsEnvironmentColor<3> { stream float4 ColorTarget : SV_Target0; - stage compose CompositionBase CompsStage[]; - compose CompositionBase Comps[]; - void PSMain() { - streams.ColorTarget = 0.0; - foreach(var comp in CompsStage) - { - streams.ColorTarget.x += comp.Compute(); - } - foreach(var comp in Comps) - { - streams.ColorTarget.y += comp.Compute(); - } - foreach(var comp in CompsInheritedStage) - { - streams.ColorTarget.z += comp.Compute(); - } - foreach(var comp in CompsInherited) - { - streams.ColorTarget.w += comp.Compute(); - } + streams.ColorTarget = Compute(); } }; - -effect CompositionArray1 -{ - mixin CompositionTest; - mixin compose CompsStage += CompositionShaderA; - mixin compose CompsStage += CompositionShaderA; - mixin compose CompsStage += CompositionShaderB; - mixin compose Comps += CompositionShaderA; - mixin compose CompsInheritedStage += CompositionShaderA; - mixin compose CompsInheritedStage += CompositionShaderB; - mixin compose CompsInheritedStage += CompositionShaderB; - mixin compose CompsInherited += CompositionShaderB; -} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index ace543ef58..05ea6fcd2b 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -129,6 +129,8 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// The size of the array. If -1, it means size is not defined, such as using []. public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, NewSpirvBuffer Buffer)? SizeExpression = null) : SymbolType() { + // We want this mutable for internal use + public (int Id, NewSpirvBuffer Buffer)? SizeExpression { get; set; } = SizeExpression; public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index b12fa40194..d27a21a952 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -308,7 +308,23 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy return value; if (castType is StructType || valueType is StructType) - throw new NotImplementedException("Can't cast between structures (cast from {valueType} to {castType})"); + throw new NotImplementedException($"Can't cast between structures (cast from {valueType} to {castType})"); + + if (castType is ArrayType a1 && valueType is ArrayType a2) + { + if (a1.BaseType == a2.BaseType) + { + if (a1.Size != -1 && a1.Size != a2.Size) + throw new InvalidOperationException(($"Can't cast between array of different sizes (cast from {valueType} to {castType})")); + // Some sizes are undetermined; this can only happen during compilation due to incomplete generics type + // TODO: do a "check pass" later to make sure this won't happen after generics instantiation? + return value; + } + else + { + throw new InvalidOperationException(($"Can't cast between array of different types (cast from {valueType} to {castType})")); + } + } // We don't support cast with object yet, filter for numeral types if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index 579bfac285..467c0a01c3 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -82,7 +82,11 @@ public int GetOrRegister(SymbolType? type) if (importBuffer != Buffer) { var resultId = InsertWithoutDuplicates(null, importBuffer); - + a.SizeExpression = (resultId, Buffer); + // Now that we reference a constant in context buffer, + // check again if array is not already added (if constants are unified, it should work) + if (Types.TryGetValue(a, out var res)) + return res; sizeId = resultId; } else diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index cab698cef3..81e5da1e84 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -102,7 +102,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return comparison; } // Standard ResultType/ResultId instructions: ignore ResultId (Span[2]) and compare the rest - else if (x.Op == Op.OpSDSLGenericParameter) + else if (x.Op == Op.OpSDSLGenericParameter || OpCheckDuplicateForConstant(x.Op)) { comparison = x.Data.Memory.Span[1].CompareTo(y.Data.Memory.Span[1]); if (comparison != 0) @@ -112,7 +112,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) if (comparison != 0) return comparison; } - else if (OpCheckDuplicateForTypesAndImport(x.Op) || OpCheckDuplicateForConstant(x.Op)) + else if (OpCheckDuplicateForTypesAndImport(x.Op)) { comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index a256541d2d..898a24daaa 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Spirv.Core; @@ -8,6 +9,8 @@ using System.Text; using static Stride.Shaders.Spirv.Specification; +[assembly: DebuggerDisplay("{Stride.Shaders.Spirv.Tools.SpirvBufferExtensions.GetDebuggerDisplay(this)}", Target = typeof(NewSpirvBuffer))] + namespace Stride.Shaders.Spirv.Tools; [Flags] @@ -18,6 +21,14 @@ public enum DisassemblerFlags InstructionIndex = 4, } +public static class SpirvBufferExtensions +{ + public static string GetDebuggerDisplay(this NewSpirvBuffer buffer) + { + return Spv.Dis(buffer, DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex | DisassemblerFlags.Name); + } +} + public static partial class Spv { public static string Dis(NewSpirvBuffer bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) From 4fe4d8b33fc3062b8167b78141bb6156259b5ac0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 22:55:46 +0900 Subject: [PATCH 0684/1182] Added test for array assign --- assets/SDSL/RenderTests/ArrayAssign.sdsl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 assets/SDSL/RenderTests/ArrayAssign.sdsl diff --git a/assets/SDSL/RenderTests/ArrayAssign.sdsl b/assets/SDSL/RenderTests/ArrayAssign.sdsl new file mode 100644 index 0000000000..d91e54ac10 --- /dev/null +++ b/assets/SDSL/RenderTests/ArrayAssign.sdsl @@ -0,0 +1,15 @@ +// PSMain(ExpectedResult=#04040404) + +namespace Stride.Shaders.Tests; + +shader ArrayAssign +{ + stream float4 ColorTarget : SV_Target0; + + void PSMain() + { + float4 test[4]; + test[0] = 4.0 / 255.0; + streams.ColorTarget = test[0]; + } +}; From b513d698947732bee76cadec3684503aa7391887 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 23:06:05 +0900 Subject: [PATCH 0685/1182] SpirvFunction: stop storing unused info about internal variables (they can clash names anyway) --- src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs | 3 --- src/Stride.Shaders/Spirv/Building/BasicBlocks.cs | 1 - 2 files changed, 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index c7fdb0344c..eabd24722e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -182,9 +182,6 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), variableType, variable)); - if (builder.CurrentFunction is SpirvFunction f) - f.Variables.Add(d.Variable, new(variable, variableTypeId, d.Variable)); - // Check initial value if (d.Value != null) { diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index 490daf1e06..c23aa8f4c5 100644 --- a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs +++ b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs @@ -105,7 +105,6 @@ public struct SpirvFunction(int id, string name, FunctionType type) : IInstructi public bool IsStage { get; set; } public FunctionType FunctionType { get; private set; } = type; public Dictionary Parameters { get; } = []; - public Dictionary Variables { get; } = []; public SortedList BasicBlocks { get; } = []; } From f77bb2326a4f3e0bfc6ec43bce621c56efe60674 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 1 Jan 2026 23:38:17 +0900 Subject: [PATCH 0686/1182] Parser: function default values --- .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 6 +++--- .../SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 99c1d55c88..c5a5d2b004 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -234,18 +234,18 @@ public override string ToString() } } -public class MethodParameter(TypeName type, Identifier name, TextLocation info, ParameterModifiers modifiers = ParameterModifiers.None, Expression? arraySize = null, Identifier? semantic = null) : Node(info) +public class MethodParameter(TypeName type, Identifier name, TextLocation info, ParameterModifiers modifiers = ParameterModifiers.None, Expression? defaultValue = null, Identifier? semantic = null) : Node(info) { public TypeName TypeName { get; set; } = type; public SymbolType? Type { get; set; } public Identifier Name { get; set; } = name; public Identifier? Semantic { get; set; } = semantic; - public Expression? ArraySize { get; set; } = arraySize; + public Expression? DefaultValue { get; set; } = defaultValue; public ParameterModifiers Modifiers { get; set; } = modifiers; public override string ToString() { - return $"{Type} {Name}"; + return $"{Type} {Name}{(DefaultValue != null ? $" = {DefaultValue}" : "")}"; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index c47f99cf0d..8c0c68f84a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -79,12 +79,12 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r && Parsers.Spaces0(ref scanner, result, out _) ) { - parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers, semantic: semantic); + parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers, value, semantic: semantic); return true; } else { - parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers); + parsed = new(typename, identifier, scanner[position..scanner.Position], modifiers, value); return true; } } From 2e17b4b108f2aa4858c2eaf6ec5897f72ecdaeca Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 2 Jan 2026 00:05:29 +0900 Subject: [PATCH 0687/1182] Added support for default parameters --- .../RenderTests/MethodDefaultParameters.sdsl | 26 ++++++++++ .../SDSL/ShaderMixer.cs | 3 +- .../Extensions/spirv.sdsl.grammar-ext.json | 11 +++++ src/Stride.Shaders/Core/Symbol.cs | 5 +- .../Parsing/SDSL/AST/Expression.cs | 48 +++++++++++++++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 18 +++++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 30 +++++++++++- 7 files changed, 130 insertions(+), 11 deletions(-) create mode 100644 assets/SDSL/RenderTests/MethodDefaultParameters.sdsl diff --git a/assets/SDSL/RenderTests/MethodDefaultParameters.sdsl b/assets/SDSL/RenderTests/MethodDefaultParameters.sdsl new file mode 100644 index 0000000000..fe12bc0c4a --- /dev/null +++ b/assets/SDSL/RenderTests/MethodDefaultParameters.sdsl @@ -0,0 +1,26 @@ +// PSMain(ExpectedResult=#04070000) + +namespace Stride.Shaders.Tests; + +shader MethodDefaultParametersBase +{ + float TestInherited(int a, int b = 5) + { + return a + b; + } +} + +shader MethodDefaultParameters : MethodDefaultParametersBase +{ + stream float4 ColorTarget : SV_Target0; + + float TestLocal(int a, int b = 3) + { + return a + b; + } + + void PSMain() + { + streams.ColorTarget = float4(TestLocal(1), TestInherited(2), 0, 0) / 255.0; + } +}; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 135de38c9f..cd7f53d8f1 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1149,7 +1149,8 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLFunctionInfo) temp.RemoveAt(index--); else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration.Value is - Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL + Decoration.FunctionParameterDefaultValueSDSL + or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) temp.RemoveAt(index--); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 8943e842e9..e4a52f8bbc 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -577,6 +577,17 @@ } ], "version": "1.0" + }, + { + "enumerant": "FunctionParameterDefaultValueSDSL", + "value": 8040, + "parameters": [ + { + "kind": "IdRef", + "quantifier": "*" + } + ], + "version": "1.0" } ] }, diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 54e617709f..a6cec31897 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -1,5 +1,6 @@ using System.Collections.Immutable; using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Core; @@ -42,11 +43,13 @@ public enum StreamIO : byte public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0, bool IsStage = false); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); +public record struct MethodSymbolDefaultParameters(SpirvContext SourceContext, int[] DefaultValues); + /// /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 246a44b027..d55cbbda74 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Text; +using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -87,7 +88,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, Type = functionType.ReturnType; - Span compiledParams = stackalloc int[parameters.Values.Count]; + Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; + + if (parameters.Values.Count > functionType.ParameterTypes.Count) + throw new InvalidOperationException($"Function {Name} was called with {parameters.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); for (int i = 0; i < parameters.Values.Count; i++) { @@ -113,6 +117,40 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, compiledParams[i] = paramVariable; } + + // Find default parameters decoration (if any) + var missingParameters = functionType.ParameterTypes.Count - parameters.Values.Count; + var defaultParameters = 0; + if (missingParameters > 0 && functionSymbol.MethodDefaultParameters is {} methodDefaultParameters) + { + // Is there enough parameters now? + if (missingParameters <= methodDefaultParameters.DefaultValues.Length) + { + // Import missing parameters + for (int i = 0; i < missingParameters; ++i) + { + var paramDefinition = functionType.ParameterTypes[parameters.Values.Count + i]; + + var source = methodDefaultParameters.DefaultValues[^(missingParameters - i)]; + // Import in current buffer + if (methodDefaultParameters.SourceContext != context) + { + var bufferForConstant = methodDefaultParameters.SourceContext.ExtractConstantAsSpirvBuffer(source); + source = context.InsertWithoutDuplicates(null, bufferForConstant); + } + + var paramVariable = context.Bound++; + builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); + builder.Insert(new OpStore(paramVariable, source, null)); + + compiledParams[parameters.Values.Count + i] = paramVariable; + } + missingParameters = 0; + } + } + + if (missingParameters > 0) + throw new InvalidOperationException($"Function {Name} was called with {parameters.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); int? instance = null; if (MemberCall != null) @@ -133,7 +171,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (instance is int instanceId) functionSymbol.IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId; - + var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); for (int i = 0; i < parameters.Values.Count; i++) @@ -381,7 +419,7 @@ void EmitOpAccessChain(Span accessChainIds) var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, Specification.ImageOperandsMask.None)); + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ImageOperandsMask.None)); result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; @@ -420,7 +458,7 @@ void EmitOpAccessChain(Span accessChainIds) var levelZero = context.CompileConstant(0.0f); var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, ParameterizedFlags.ImageOperandsLod(levelZero.Id))) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, Specification.ImageOperandsMask.None)); + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, ImageOperandsMask.None)); result = new(sample.IdResult!.Value, sample.IdResultType!.Value); accessor.Type = resultType; @@ -731,7 +769,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var blockFalseId = context.Bound++; // OpSelectionMerge and OpBranchConditional (will be filled later) - builder.Insert(new OpSelectionMerge(blockMergeId, Specification.SelectionControlMask.None)); + builder.Insert(new OpSelectionMerge(blockMergeId, SelectionControlMask.None)); builder.Insert(new OpBranchConditional(conditionValue.Id, blockTrueId, blockFalseId, [])); // Block when choosing left value diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 98f40fddbe..3065ef3300 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -294,6 +294,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); + var methodsDefaultParameters = new Dictionary(); var structTypes = new List<(StructuredType Type, int ImportedId)>(); foreach (var i in shaderBuffers.Context) @@ -302,6 +303,14 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte { structTypes.Add(((StructuredType)shaderBuffers.Context.ReverseTypes[typeStructInstruction.ResultId], -1)); } + else if (i.Op == Op.OpDecorate && (OpDecorate)i is + { + Decoration: { Value: Decoration.FunctionParameterDefaultValueSDSL }, + Target: var target, + } decorateFunctionParameters) + { + methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.Decoration.Span.ToArray())); + } } for (var index = 0; index < shaderBuffers.Buffer.Count; index++) { @@ -328,7 +337,10 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte var functionType = shaderBuffers.Context.ReverseTypes[functionInstruction.FunctionType]; var sid = new SymbolID(functionName, SymbolKind.Method, IsStage: (functionFlags & FunctionFlagsMask.Stage) != 0); - methods.Add((new(sid, functionType, 0), functionFlags)); + MethodSymbolDefaultParameters? methodDefaultParameters = methodsDefaultParameters.TryGetValue(functionInstruction.ResultId, out var methodDefaultParametersValue) + ? methodDefaultParametersValue + : null; + methods.Add((new(sid, functionType, 0, MethodDefaultParameters: methodDefaultParameters), functionFlags)); } if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) @@ -458,8 +470,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = new PointerType(argSym, Specification.StorageClass.Function); - ftype.ParameterTypes.Add(new(arg.Type, arg.Modifiers)); + arg.Type = argSym; + ftype.ParameterTypes.Add(new(new PointerType(arg.Type, Specification.StorageClass.Function), arg.Modifiers)); } func.Type = ftype; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c5a5d2b004..13e171ca54 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -306,8 +306,33 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler functionFlags |= Specification.FunctionFlagsMask.Virtual; if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; + + Span defaultParameters = stackalloc int[Parameters.Count]; + var firstDefaultParameter = -1; + for (var index = 0; index < Parameters.Count; index++) + { + var arg = Parameters[index]; + if (firstDefaultParameter != -1 && arg.DefaultValue == null) + throw new InvalidOperationException($"Parameter {index} ({arg.Name}) in method {Name} doesn't have a default but a previous argument had a default value"); + if (arg.DefaultValue != null) + { + if (firstDefaultParameter == -1) + firstDefaultParameter = index; + defaultParameters[index] = arg.DefaultValue.CompileConstantValue(table, context, arg.Type).Id; + } + } var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type); + + if (firstDefaultParameter != -1) + { + context.Add(new OpDecorate(function.Id, new ParameterizedFlag( + Specification.Decoration.FunctionParameterDefaultValueSDSL, + defaultParameters.Slice(firstDefaultParameter)))); + + symbol.MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()); + } + table.CurrentShader.Methods.Add((symbol, functionFlags)); } @@ -316,8 +341,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var (builder, context) = compiler; table.Push(); - foreach (var arg in Parameters) + Span defaultParameters = stackalloc int[Parameters.Count]; + var firstDefaultParameter = -1; + for (var index = 0; index < Parameters.Count; index++) { + var arg = Parameters[index]; var argSym = arg.TypeName.ResolveType(table, context); table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); arg.Type = argSym; From 8eb713c1c4e43b50e94349e0a2136d775ffd043d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 5 Jan 2026 20:05:05 +0900 Subject: [PATCH 0688/1182] Added support for == and != for bool --- src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index d27a21a952..47308c7731 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -245,12 +245,16 @@ when l.IsInteger() && r.IsInteger() (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.Equals, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertData(Position++, new OpLogicalEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Equals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Equals, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + (Operator.NotEquals, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + => Buffer.InsertData(Position++, new OpLogicalNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.NotEquals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.NotEquals, ScalarType l, ScalarType r) From 689f14cf1d00df1306ae0457dff43b35b997921d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 5 Jan 2026 21:45:07 +0900 Subject: [PATCH 0689/1182] Added support for offset in Texture.Sample() methods (WIP: still need fix for ImageOperands) --- .../Parsing/SDSL/AST/Expression.cs | 70 ++++++++++++++++--- .../Spirv/Building/Builder.Expressions.cs | 3 + 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index d55cbbda74..58bff0f2a1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -399,49 +399,84 @@ void EmitOpAccessChain(Span accessChainIds) switch (currentValueType, accessor) { case (PointerType { BaseType: TextureType textureType }, - MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } - or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } - or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 }): + MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } + or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } + or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 }): { // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); var textureValue = builder.AsValue(context, result); + var textureCoordSize = textureType switch + { + Texture1DType { Arrayed: false } => 1, + Texture2DType { Arrayed: false } => 2, + Texture3DType { Arrayed: false } => 3, + }; + var offsetSize = textureCoordSize; + if (textureType.Arrayed) + textureCoordSize++; // Load texture as value result = builder.AsValue(context, result); - if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 } implicitSampling) + if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } implicitSampling) { var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); + texCoordValue = builder.Convert(context, texCoordValue, ScalarType.From("float").GetVectorOrScalar(textureCoordSize)); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ImageOperandsMask.None)); + + ParameterizedFlag? flags = null; + if (implicitSampling.Parameters.Values.Count > 2) + { + var offset = implicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); + offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + // TODO: determine when ConstOffset + flags = new ParameterizedFlag(ImageOperandsMask.Offset, [offset.Id]); + } + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, flags)); result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; } - else if (accessor is MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 } explicitSampling) + else if (accessor is MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } explicitSampling) { var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); + texCoordValue = builder.Convert(context, texCoordValue, new VectorType(ScalarType.From("float"), textureCoordSize)); + var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); levelValue = builder.Convert(context, levelValue, ScalarType.From("float")); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, ParameterizedFlags.ImageOperandsLod(levelValue.Id))); + + ParameterizedFlag flags; + if (explicitSampling.Parameters.Values.Count > 3) + { + var offset = explicitSampling.Parameters.Values[3].CompileAsValue(table, compiler); + offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + // TODO: determine when ConstOffset + flags = new ParameterizedFlag(ImageOperandsMask.Lod | ImageOperandsMask.Offset, [levelValue.Id, offset.Id]); + } + else + { + flags = new ParameterizedFlag(ImageOperandsMask.Lod, [levelValue.Id]); + } + var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, flags)); result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; } - else if (accessor is MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 } sampleCompare) + else if (accessor is MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 } sampleCompare) { var resultType = textureType.ReturnType; if (resultType is not ScalarType) @@ -449,16 +484,29 @@ void EmitOpAccessChain(Span accessChainIds) var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler); + texCoordValue = builder.Convert(context, texCoordValue, new VectorType(ScalarType.From("float"), textureCoordSize)); + var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - var levelZero = context.CompileConstant(0.0f); + ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" + ? ParameterizedFlags.ImageOperandsLod(context.CompileConstant(0.0f).Id) + : ImageOperandsMask.None; + + if (sampleCompare.Parameters.Values.Count > 3) + { + var offset = sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler); + offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + // TODO: determine when ConstOffset + flags = new ParameterizedFlag(flags.Value | ImageOperandsMask.Offset, [..flags.Span, offset.Id]); + } + var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, ParameterizedFlags.ImageOperandsLod(levelZero.Id))) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, ImageOperandsMask.None)); + ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags)) + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags)); result = new(sample.IdResult!.Value, sample.IdResultType!.Value); accessor.Type = resultType; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 47308c7731..8bbf9ee7a9 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -482,6 +482,9 @@ public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol f internal static class SymbolExtensions { + public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) + => size == 1 ? scalar : new VectorType(scalar, size); + public static int GetElementCount(this SymbolType symbol) => symbol switch { ScalarType s => 1, From 7b8288582e822411c83f24940480964dc6b23c0c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 6 Jan 2026 15:14:21 +0900 Subject: [PATCH 0690/1182] OpDataEnumerator: Handle ImageOperands flags --- .../Parsing/OpDataEnumerator.cs | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index b3237c81a2..b4892113d8 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -36,7 +36,7 @@ public OpDataEnumerator(Span instruction) combinedLogicalOperands.Add(innerLogicalOperands[i]); } logicalOperands = new LogicalOperandArray(logicalOperands.ClassName, combinedLogicalOperands); - } + } oid = -1; pid = -1; wid = 0; @@ -44,6 +44,39 @@ public OpDataEnumerator(Span instruction) public SpvOperand Current => ParseCurrent(); + public bool FindOperandInfo(OperandParameters p, ParameterizedOperandKey key, out ParameterizedOperand[] operands) + { + if (p.TryGetValue(key, out operands)) + return true; + + // ImageOperands is used as a flag. Each flag set will expect corresponding operand(s) (flags should be tested in ascending order) + // TODO: Does it apply to other operand kinds as well? + if (key.Kind == OperandKind.ImageOperands) + { + // In case it's run multithreaded + lock (p) + { + // First time we encounter this combination, build it using flags + var operandsList = new List(); + foreach (var parameter in p) + { + if ((parameter.Key.Value & key.Value) != 0) + { + operandsList.AddRange(parameter.Value); + } + } + + operands = operandsList.ToArray(); + + // Add to cache for next query + p.Add(key, operands); + return true; + } + } + + return false; + } + public bool MoveNext() { if (oid < 0) @@ -58,10 +91,12 @@ public bool MoveNext() var logOp = logicalOperands[oid]; (int newWid, int newOid, int newPid, startOperand) = logOp switch { - { Parameters: OperandParameters { Count: > 0 } p } when pid == -1 && p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && p[new(logOp.Kind ?? OperandKind.None, Operands[wid])].Length > 0 => + { Parameters: OperandParameters { Count: > 0 } p } + when pid == -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[wid]), out var operands) && operands.Length > 0 => (wid + 1, oid, 0, wid), - { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => - p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch + { Parameters: OperandParameters { Count: > 0 } p } + when startOperand != -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[startOperand]), out var operands) && pid < operands.Length => + operands[pid] switch { { Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } => (wid + 2, oid, pid + 1, startOperand), { Kind: OperandKind.LiteralString } => (wid + Operands[wid..].LengthOfString(), oid, pid + 1, startOperand), From 632ce4281830137141e5be6d36deda2a723845aa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 6 Jan 2026 19:32:21 +0900 Subject: [PATCH 0691/1182] Merge all global non-static variables into a Globals cbuffer --- .../RenderTests/CompositionStageVariable.sdsl | 6 +- .../SDSL/RenderTests/CompositionVariable.sdsl | 2 +- .../SDSL/ShaderMixer.CBuffers.cs | 98 ++++++++++++++++++- .../SDSL/ShaderMixer.cs | 36 +++++-- .../Buffers/NewSpirvBuffer.cs | 8 ++ .../Parsing/SDSL/AST/Literals.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 13 +-- .../ShaderParsers/ShaderDataParsers.cs | 2 + .../Spirv/Processing/InterfaceProcessor.cs | 31 ++---- 10 files changed, 161 insertions(+), 43 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionStageVariable.sdsl b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl index e353433b21..f33a07d6e3 100644 --- a/assets/SDSL/RenderTests/CompositionStageVariable.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl @@ -4,13 +4,13 @@ namespace Stride.Shaders.Tests; shader CompositionBase2 { - stage float A; + stage static float A; } shader CompositionBase : CompositionBase2 { - stage float B; - stage float C; + stage static float B; + stage static float C; float Compute() { diff --git a/assets/SDSL/RenderTests/CompositionVariable.sdsl b/assets/SDSL/RenderTests/CompositionVariable.sdsl index 8400a26bdd..2f6783520e 100644 --- a/assets/SDSL/RenderTests/CompositionVariable.sdsl +++ b/assets/SDSL/RenderTests/CompositionVariable.sdsl @@ -4,7 +4,7 @@ namespace Stride.Shaders.Tests; shader CompositionBase { - float A; + static float A; void SetupA() { A = 1.0; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index ce5a8a8057..2c5f2ecc29 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -11,12 +11,108 @@ using System.Runtime.InteropServices; using System.Text; using static Stride.Shaders.Spirv.Specification; +using StorageClass = Stride.Shaders.Parsing.SDSL.AST.StorageClass; namespace Stride.Shaders.Compilers.SDSL { partial class ShaderMixer { - private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + { + var members = new List(); + // Remap from variable ID to member index in our new struct + var variableToMemberIndices = new Dictionary(); + // Collect any variable not a stream, not static and not a block + HashSet blockTypes = []; + int firstVariableIndex = -1; + foreach (var i in temp) + { + if (i.Op == Op.OpVariableSDSL + && ((OpVariableSDSL)i) is { Storageclass: Specification.StorageClass.Uniform } variable + && context.ReverseTypes[variable.ResultType] is PointerType { BaseType: var variableType } + && variableType is not ConstantBufferSymbol) + { + firstVariableIndex = i.Index; + variableToMemberIndices.Add(variable.ResultId, members.Count); + members.Add(new(context.Names[variable.ResultId], variableType, TypeModifier.None)); + SetOpNop(i.Data.Memory.Span); + } + } + + // No global members? Let's finish now + if (members.Count == 0) + return; + + var globalCBufferType = new ConstantBufferSymbol("Globals", members); + var globalCBufferTypeId = context.DeclareCBuffer(globalCBufferType); + for (var index = 0; index < members.Count; index++) + { + var member = members[index]; + context.AddMemberName(globalCBufferTypeId, index, member.Name); + } + + // Note: we make sure to add at a previous variable index, otherwise the OpVariableSDSL won't be inside the root MixinNode.StartInstruction/EndInstruction + temp.FluentReplace(firstVariableIndex, new OpVariableSDSL(context.GetOrRegister(new PointerType(globalCBufferType, Specification.StorageClass.Uniform)), context.Bound++, Specification.StorageClass.Uniform, VariableFlagsMask.Stage, null), out var cbufferVariable); + context.AddName(cbufferVariable.ResultId, "Globals"); + + // Replace all accesses + int instructionsAddedInThisMethod = 0; + for (var index = 0; index < temp.Count; index++) + { + var i = temp[index]; + if (i.Op == Op.OpFunctionEnd) + { + // Since we might have inserted instructions, offset all Start/End instructions indices + AdjustIndicesAfterAppendInstructions(rootMixin, i.Index, instructionsAddedInThisMethod); + instructionsAddedInThisMethod = 0; + } + if (i.Op is Op.OpLoad && (OpLoad)i is { } load) + { + if (variableToMemberIndices.TryGetValue(load.Pointer, out var memberIndex)) + { + load.Pointer = context.Bound; + instructionsAddedInThisMethod++; + temp.Insert(index++, new OpAccessChain( + context.GetOrRegister(new PointerType(members[memberIndex].Type, Specification.StorageClass.Uniform)), + context.Bound++, + cbufferVariable.ResultId, + [context.CompileConstant(memberIndex).Id])); + } + } + else if (i.Op is Op.OpStore && (OpStore)i is { } store) + { + if (variableToMemberIndices.TryGetValue(store.Pointer, out var memberIndex)) + { + store.Pointer = context.Bound; + instructionsAddedInThisMethod++; + temp.Insert(index++, new OpAccessChain( + context.GetOrRegister(new PointerType(members[memberIndex].Type, Specification.StorageClass.Uniform)), + context.Bound++, + cbufferVariable.ResultId, + [context.CompileConstant(memberIndex).Id])); + } + } + else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + if (variableToMemberIndices.TryGetValue(accessChain.BaseId, out var memberIndex)) + { + accessChain.Values = new([context.CompileConstant(memberIndex).Id, ..accessChain.Values.Elements.Span]); + accessChain.BaseId = cbufferVariable.ResultId; + } + } + } + + // Update entry points to include this cbuffer + foreach (var i in context) + { + if (i.Op == Op.OpEntryPoint && (OpEntryPoint)i is {} entryPoint) + { + entryPoint.Values = new([..entryPoint.Values, cbufferVariable.ResultId]); + } + } + } + + private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { // Collect Decorations Dictionary logicalGroups = new(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index cd7f53d8f1..9c628e7ff9 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -55,10 +55,19 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef context.Insert(3, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); // Process streams and remove unused code/cbuffer/variable/resources - new InterfaceProcessor().Process(table, temp, context); + var interfaceProcessor = new InterfaceProcessor + { + CodeInserted = (int index, int count) => AdjustIndicesAfterAppendInstructions(rootMixin, index, count) + }; + interfaceProcessor.Process(table, temp, context); + + // Any non-static variable is moved to a "Globals" default cbuffer + // TODO: future language improvement: + // force cbuffer to be epxlicit? (and not need "static" anymore for mixin nodes member, which is weird) + // It's a breaking change and will require some changes to Stride shaders (esp. in post effects) + GenerateDefaultCBuffer(rootMixin, globalContext, context, temp); // Merge cbuffers and rgroups - // TODO: remove unused cbuffers (before merging them) MergeCBuffers(globalContext, context, temp); ComputeCBufferOffsets(globalContext, context, temp); @@ -606,25 +615,40 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext } } buffer.InsertRange(index, foreachBufferCopy.AsSpan()); - AdjustIndicesAfterAddingInstructions(mixinNode, index, foreachBufferCopy.Count - foreachBuffer.Count); + AdjustIndicesAfterAppendInstructions(mixinNode.Stage ?? mixinNode, index, foreachBufferCopy.Count - foreachBuffer.Count); foreach (var inst in foreachBuffer) inst.Dispose(); } - private static void AdjustIndicesAfterAddingInstructions(MixinNode mixinNode, int insertIndex, int insertCount) + // Note: if added between two mixin, it will belong to the one before (as if appending) + // it also means adding before anything else is not supported + private static void AdjustIndicesAfterAppendInstructions(MixinNode mixinNode, int insertIndex, int insertCount) { + if (insertIndex == 0) + throw new NotImplementedException(); + + // Nothing to shift + if (insertCount == 0) + return; + if (mixinNode.StartInstruction > insertIndex) mixinNode.StartInstruction += insertCount; - if (mixinNode.EndInstruction > insertIndex) + if (mixinNode.EndInstruction >= insertIndex) mixinNode.EndInstruction += insertCount; foreach (var shader in mixinNode.Shaders) { if (shader.StartInstruction > insertIndex) shader.StartInstruction += insertCount; - if (shader.EndInstruction > insertIndex) + if (shader.EndInstruction >= insertIndex) shader.EndInstruction += insertCount; } + + foreach (var composition in mixinNode.Compositions) + AdjustIndicesAfterAppendInstructions(composition.Value, insertIndex, insertCount); + foreach (var compositions in mixinNode.CompositionArrays) + foreach (var composition in compositions.Value) + AdjustIndicesAfterAppendInstructions(composition, insertIndex, insertCount); } private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index fd02f79d5b..1de4520c8a 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -393,6 +393,14 @@ public OpData Replace(int index, in T instruction) where T : struct, IMemoryI return Instructions[index]; } + public NewSpirvBuffer FluentReplace(int index, in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct + { + Replace(index, instruction); + instruction.Attach(new(index, this)); + result = instruction; + return this; + } + public Enumerator GetEnumerator() => new(this); public struct Enumerator(NewSpirvBuffer buffer) : IEnumerator diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index cd30895705..3c152c2647 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -146,7 +146,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var (builder, context) = compiler; Type = GenerateType(table, context, expectedType); - + if (Type is ArrayType t2 && t2.Size == -1) + Type = new ArrayType(t2.BaseType, Values.Count); + (var compositeCount, var totalCount, var expectedElementType) = Type switch { VectorType v => (v.Size, v.Size, v.BaseType), diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 3065ef3300..24b38b9a01 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -492,7 +492,9 @@ public void Compile(SymbolTable table, CompilerUnit compiler) memberType = svar.TypeName.ResolveType(table, context); } - var storageClass = Specification.StorageClass.Private; + var storageClass = svar.StorageClass == StorageClass.Static || svar.StreamKind == StreamKind.Stream + ? Specification.StorageClass.Private + : Specification.StorageClass.Uniform; if (memberType is TextureType || memberType is BufferType) storageClass = Specification.StorageClass.UniformConstant; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 13e171ca54..4bb4c983e0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -173,10 +173,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var registeredType = context.GetOrRegister(Type); var variable = context.Bound++; - // TODO: Add a StreamSDSL storage class? - var storageClass = Specification.StorageClass.Private; - if (Type is PointerType pointerType) - storageClass = pointerType.StorageClass; + var pointerType = (PointerType)Type; var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; if (StreamKind == StreamKind.Stream) @@ -185,7 +182,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler int? initializerMethod = null; if (Value != null) { - var valueType = ((PointerType)Type).BaseType; + var valueType = pointerType.BaseType; // TODO: differentiate const from code that needs to go in entry point? // TODO: move to entry point @@ -194,7 +191,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler builder.Insert(new OpLabel(context.Bound++)); var initialValue = Value.CompileAsValue(table, compiler); - initialValue = builder.Convert(context, initialValue, ((PointerType)Type).BaseType); + initialValue = builder.Convert(context, initialValue, pointerType.BaseType); builder.Return(initialValue); builder.Insert(new OpFunctionEnd()); @@ -202,7 +199,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.AddName(initializerMethod.Value, $"{Name}_Initializer"); } - builder.Insert(new OpVariableSDSL(registeredType, variable, storageClass, variableFlags, initializerMethod)); + builder.Insert(new OpVariableSDSL(registeredType, variable, pointerType.StorageClass, variableFlags, initializerMethod)); if (Semantic != null) context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); context.AddName(variable, Name); @@ -221,7 +218,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler }, IsStage: IsStaged ); - var symbol = new Symbol(sid, Type, variable); + var symbol = new Symbol(sid, pointerType, variable); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index ced55d0ca2..834f96d803 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -39,6 +39,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o IsCompose = isCompose, Interpolation = interpolation, StreamKind = streamKind, + StorageClass = storageClass, TypeModifier = typeModifier, }; return true; @@ -53,6 +54,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o IsStaged = isStaged, Interpolation = interpolation, StreamKind = streamKind, + StorageClass = storageClass, TypeModifier = typeModifier, }; return true; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index f6146596b9..b4c6b5c7da 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -16,6 +16,10 @@ namespace Stride.Shaders.Spirv.Processing /// public class InterfaceProcessor { + public delegate void CodeInsertedDelegate(int index, int count); + + public CodeInsertedDelegate CodeInserted { get; set; } + class StreamInfo(string? semantic, string name, SymbolType type, int variableId) { public string? Semantic { get; } = semantic; @@ -472,25 +476,6 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) } } - // CBuffer - // Encoded in this format: - // OpDecorate %type_CBuffer1 Block - // %_ptr_Uniform_type_CBuffer1 = OpTypePointer Uniform %type_CBuffer1 - // %CBuffer1 = OpVariable %_ptr_Uniform_type_CBuffer1 Uniform - { - if (i.Op == Op.OpDecorate - && ((OpDecorate)i) is { Decoration: { Value: Decoration.Block }, Target: var bufferType }) - { - blockTypes.Add(bufferType); - } - else if (i.Op == Op.OpTypePointer - && ((OpTypePointer)i) is { Storageclass: StorageClass.Uniform, ResultId: var pointerType, Type: var bufferType2 } - && blockTypes.Contains(bufferType2)) - { - blockPointerTypes.Add(pointerType, bufferType2); - } - } - // Semantic { if (i.Op == Op.OpDecorateString @@ -516,7 +501,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) { if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } - && blockPointerTypes.TryGetValue(pointerType2, out var bufferType3)) + && context.ReverseTypes[pointerType2] is PointerType { BaseType: ConstantBufferSymbol }) { var name = nameTable[bufferId]; // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) @@ -871,7 +856,9 @@ void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int liveAnalysis.ExtraReferencedMethods.Add(methodInfo.ThisStageMethodId.Value); + // TODO: adjust mixin instructions ranges buffer.InsertRange(methodEnd, copiedInstructions.AsSpan()); + CodeInserted?.Invoke(methodEnd, copiedInstructions.Count); } } @@ -920,7 +907,7 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct { var i = buffer[index]; - if (i.Op == Op.OpStreamsSDSL && (OpAccessChain)i is { } streamsInstruction) + if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) { streamsInstructionIds.Add(streamsInstruction.ResultId); remapIds.Add(streamsInstruction.ResultId, streamsVariableId); @@ -1061,7 +1048,7 @@ private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } - else if (i.Op == Op.OpStreamsSDSL && new OpAccessChain(ref i) is { } streamsInstruction) + else if (i.Op == Op.OpStreamsSDSL && new OpStreamsSDSL(ref i) is { } streamsInstruction) { streamsInstructionIds.Add(streamsInstruction.ResultId); methodInfo.HasStreamAccess = true; From 79887c5fd282df0ad983522f6c018d461282dba6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 7 Jan 2026 00:19:33 +0900 Subject: [PATCH 0692/1182] SamplerState: process link info too --- .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4bb4c983e0..11c236685c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -111,11 +111,13 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler } } - var register = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); - context.AddName(register.ResultId, Name); + var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + context.AddName(variable.ResultId, Name); + + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); var sid = new SymbolID(Name, SymbolKind.SamplerState); - var symbol = new Symbol(sid, Type, register.ResultId); + var symbol = new Symbol(sid, Type, variable.ResultId); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } else throw new Exception($"SamplerState {Name} already defined"); From 6547b28f58832542135620f431cbdf719533f8c8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 7 Jan 2026 00:29:00 +0900 Subject: [PATCH 0693/1182] Globals cbuffer: also remap link info --- .../SDSL/ShaderMixer.CBuffers.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 2c5f2ecc29..f64f518c74 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -110,6 +110,21 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob entryPoint.Values = new([..entryPoint.Values, cbufferVariable.ResultId]); } } + + // Remap decorations + foreach (var i in context) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is {} decorate) + { + if (variableToMemberIndices.TryGetValue(decorate.Target, out var memberIndex)) + i.Buffer.Replace(i.Index, new OpMemberDecorate(globalCBufferTypeId, memberIndex, decorate.Decoration)); + } + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is {} decorateString) + { + if (variableToMemberIndices.TryGetValue(decorateString.Target, out var memberIndex)) + i.Buffer.Replace(i.Index, new OpMemberDecorateString(globalCBufferTypeId, memberIndex, decorateString.Decoration)); + } + } } private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) From aee073b1b21c1e38e4c80a5f94ae7b4dc1d7719e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 10:50:45 +0900 Subject: [PATCH 0694/1182] Fixed AdjustIndicesAfterAppendInstructions() --- .../SDSL/ShaderMixer.CBuffers.cs | 3 +- .../SDSL/ShaderMixer.MixinNode.cs | 24 +++++++- .../SDSL/ShaderMixer.cs | 56 +++++++++++-------- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index f64f518c74..0f565fcec3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -63,7 +63,8 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob if (i.Op == Op.OpFunctionEnd) { // Since we might have inserted instructions, offset all Start/End instructions indices - AdjustIndicesAfterAppendInstructions(rootMixin, i.Index, instructionsAddedInThisMethod); + if (instructionsAddedInThisMethod > 0) + AdjustIndicesAfterAppendInstructions(rootMixin, i.Index, instructionsAddedInThisMethod); instructionsAddedInThisMethod = 0; } if (i.Op is Op.OpLoad && (OpLoad)i is { } load) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 0a775e45ee..98af94391e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -1,4 +1,5 @@ -using Stride.Shaders.Core; +using System.Text; +using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Compilers.SDSL; @@ -44,6 +45,27 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary Compositions { get; } = new(); public Dictionary CompositionArrays { get; } = new(); + + public override string ToString() + => $"MixinNode ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction}) ({Shaders.Count} shaders, {Compositions.Count} compositions, {CompositionArrays.Count} composition arrays)"; + + public string ToDetailedString() + { + var sb = new StringBuilder(); + Recurse(sb, this); + return sb.ToString(); + + static void Recurse(StringBuilder sb, MixinNode node, int indent = 0) + { + sb.Append(' ', indent * 2); + sb.AppendLine(node.ToString()); + foreach (var composition in node.Compositions) + Recurse(sb, composition.Value, indent + 1); + foreach (var compositions in node.CompositionArrays) + foreach (var composition in compositions.Value) + Recurse(sb, composition, indent + 1); + } + } } class MethodGroup diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9c628e7ff9..29e1061c83 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -579,7 +579,7 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext // Extract foreach buffer (with the foreach start/end) var foreachBuffer = buffer[index..endIndex]; - buffer.RemoveRange(index, endIndex - index, false); + buffer.RemoveRange(index, foreachBuffer.Count, false); var foreachBufferCopy = new List(); // Note: Make sure we replace the OpForeachSDSL with a first OpNop, so that if a for() loop works fine and don't miss an instruction without having to do index-- @@ -615,40 +615,50 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext } } buffer.InsertRange(index, foreachBufferCopy.AsSpan()); - AdjustIndicesAfterAppendInstructions(mixinNode.Stage ?? mixinNode, index, foreachBufferCopy.Count - foreachBuffer.Count); + // Note: mixinNode is not added to rootMixin hierarchy yet + // Moreover, we are the last mixin (or one of our child is) + // So we need (and it's safe) to call this on mixinNode rather than root node + AdjustIndicesAfterAppendInstructions(mixinNode, index, foreachBufferCopy.Count - foreachBuffer.Count); foreach (var inst in foreachBuffer) inst.Dispose(); } - // Note: if added between two mixin, it will belong to the one before (as if appending) - // it also means adding before anything else is not supported - private static void AdjustIndicesAfterAppendInstructions(MixinNode mixinNode, int insertIndex, int insertCount) + // Note: Make sure to call it on propre node (i.e. either last mixin node (if just added) or root, otherwise it won't increment the MixinNode after current one + // If added between two mixin, it will belong to the one before (as if appending) + // it also means adding before or at the start the first (root) mixin is forbidden + private static void AdjustIndicesAfterAppendInstructions(MixinNode rootMixin, int insertIndex, int insertCount) { - if (insertIndex == 0) - throw new NotImplementedException(); - + // Check bounds: we can't add before or at start of first mixin + if (insertIndex <= rootMixin.StartInstruction) + throw new ArgumentOutOfRangeException(nameof(insertIndex)); + // Nothing to shift if (insertCount == 0) return; + + AdjustIndicesAfterAppendInstructionsInner(rootMixin, insertIndex, insertCount); - if (mixinNode.StartInstruction > insertIndex) - mixinNode.StartInstruction += insertCount; - if (mixinNode.EndInstruction >= insertIndex) - mixinNode.EndInstruction += insertCount; - foreach (var shader in mixinNode.Shaders) + static void AdjustIndicesAfterAppendInstructionsInner(MixinNode mixinNode, int insertIndex, int insertCount) { - if (shader.StartInstruction > insertIndex) - shader.StartInstruction += insertCount; - if (shader.EndInstruction >= insertIndex) - shader.EndInstruction += insertCount; - } + if (mixinNode.StartInstruction > insertIndex) + mixinNode.StartInstruction += insertCount; + if (mixinNode.EndInstruction >= insertIndex) + mixinNode.EndInstruction += insertCount; + foreach (var shader in mixinNode.Shaders) + { + if (shader.StartInstruction > insertIndex) + shader.StartInstruction += insertCount; + if (shader.EndInstruction >= insertIndex) + shader.EndInstruction += insertCount; + } - foreach (var composition in mixinNode.Compositions) - AdjustIndicesAfterAppendInstructions(composition.Value, insertIndex, insertCount); - foreach (var compositions in mixinNode.CompositionArrays) - foreach (var composition in compositions.Value) - AdjustIndicesAfterAppendInstructions(composition, insertIndex, insertCount); + foreach (var composition in mixinNode.Compositions) + AdjustIndicesAfterAppendInstructionsInner(composition.Value, insertIndex, insertCount); + foreach (var compositions in mixinNode.CompositionArrays) + foreach (var composition in compositions.Value) + AdjustIndicesAfterAppendInstructionsInner(composition, insertIndex, insertCount); + } } private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) From 2fbd23756f6944d36114866f69afbed398b17008 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 14:47:40 +0900 Subject: [PATCH 0695/1182] Added cbuffer globals test --- assets/SDSL/RenderTests/CBufferGlobals.sdsl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 assets/SDSL/RenderTests/CBufferGlobals.sdsl diff --git a/assets/SDSL/RenderTests/CBufferGlobals.sdsl b/assets/SDSL/RenderTests/CBufferGlobals.sdsl new file mode 100644 index 0000000000..4b6fe51da9 --- /dev/null +++ b/assets/SDSL/RenderTests/CBufferGlobals.sdsl @@ -0,0 +1,15 @@ +// PSMain(ExpectedResult=#10101010, cbuffer.Globals=(Test=16)) + +namespace Stride.Shaders.Tests; + +shader CBufferGlobals +{ + stream float4 ColorTarget : SV_Target0; + + stage float Test; + + void PSMain() + { + streams.ColorTarget = Test / 255.0; + } +}; From eb98d0e519d8be5eff67ac64c722a3007afc44e0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 14:48:21 +0900 Subject: [PATCH 0696/1182] Added support for TextureCube --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 58bff0f2a1..40d2bdfd65 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -408,9 +408,9 @@ void EmitOpAccessChain(Span accessChainIds) var textureValue = builder.AsValue(context, result); var textureCoordSize = textureType switch { - Texture1DType { Arrayed: false } => 1, - Texture2DType { Arrayed: false } => 2, - Texture3DType { Arrayed: false } => 3, + Texture1DType => 1, + Texture2DType => 2, + Texture3DType or TextureCubeType => 3, }; var offsetSize = textureCoordSize; if (textureType.Arrayed) From 5306befee3cf09014d6551593a3d62ad11c13ce5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 15:25:56 +0900 Subject: [PATCH 0697/1182] Added support for accessing generics external class --- assets/SDSL/RenderTests/GenericsExternal.sdsl | 48 +++++++++++++++++++ .../SDSL/ShaderMixer.cs | 4 +- src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 31 +++++++++++- .../Parsing/SDSL/AST/Literals.cs | 20 ++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../Spirv/Building/Builder.Class.cs | 6 +-- 7 files changed, 95 insertions(+), 20 deletions(-) create mode 100644 assets/SDSL/RenderTests/GenericsExternal.sdsl diff --git a/assets/SDSL/RenderTests/GenericsExternal.sdsl b/assets/SDSL/RenderTests/GenericsExternal.sdsl new file mode 100644 index 0000000000..cfdfa85e7f --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsExternal.sdsl @@ -0,0 +1,48 @@ +// PSMain(ExpectedResult=#03050A0A, cbuffer.PerView=(Data=(3.0, 5.0))) + +namespace Stride.Shaders.Tests; + +shader ExternalClass +{ + cbuffer PerView + { + stage float Data[TArraySize]; + }; +} + +shader CompositionBase +{ + abstract float4 Compute(); +}; + + +shader CompositionGenerics +{ + override float4 Compute() + { + return float4(ExternalClass.Data[0], ExternalClass.Data[1], 10.0, 10.0) / 255.0; + } +}; + +shader GenericsExternalShader +{ + stream float4 ColorTarget : SV_Target0; + + compose CompositionBase ShadingColor0; + + stage float4 Shading() + { + return ShadingColor0.Compute(); + } + + void PSMain() + { + streams.ColorTarget = Shading(); + } +}; + +effect GenericsExternal +{ + mixin GenericsExternalShader; + mixin compose ShadingColor0 = CompositionGenerics<2>; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 29e1061c83..080da7c4e4 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -179,7 +179,7 @@ private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext var shaderInfo = MergeClassInBuffers(globalContext, context, buffer, mixinNode, shaderClass); - mixinNode.ShadersByName.Add(shaderClass.ToClassName(), shaderInfo); + mixinNode.ShadersByName.Add(shaderClass.ToClassNameWithGenerics(), shaderInfo); mixinNode.Shaders.Add(shaderInfo); // Note: we process name, types and struct right away, as they might be needed by the next Shader @@ -229,7 +229,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // If a stage member is skipped in a composition mixin, we want to remap to the version in the root mixin if (isStage && !isRootMixin) { - var stageShader = mixinNode.Stage.ShadersByName[shaderClass.ToClassName()]; + var stageShader = mixinNode.Stage.ShadersByName[shaderClass.ToClassNameWithGenerics()]; var memberOrTypeName = names[memberId]; var stageMemberOrTypeId = stageShader.StructTypes.TryGetValue(memberOrTypeName, out var structTypeId) ? structTypeId diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 05ea6fcd2b..0f873cf7fc 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -300,7 +300,7 @@ public string ToClassName() return Name; var className = new ShaderClassInstantiation(Name, GenericArguments); - return className.ToClassName(); + return className.ToClassNameWithGenerics(); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 40d2bdfd65..ac5d9dd418 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; @@ -209,7 +210,33 @@ public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - throw new NotImplementedException(); + var (builder, context) = compiler; + + // MixinAccess is same as Identifier static variable case, except we have generics (which is why MixinAccess was chosen over Identifier) + var generics = SDFX.AST.ShaderEffect.CompileGenerics(table, compiler, Mixin.Generics); + var classSource = new ShaderClassInstantiation(Mixin.Name, generics); + if (!table.TryResolveSymbol(classSource.ToClassNameWithGenerics(), out var symbol)) + { + if (!table.ShaderLoader.Exists(classSource.ClassName)) + throw new InvalidOperationException($"Symbol [{classSource.ClassName}] could not be found."); + + // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) + var inheritedShaderCount = table.InheritedShaders.Count; + classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); + for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) + { + table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); + ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); + } + + // We add the typename as a symbol (similar to static access in C#) + var shaderId = context.GetOrRegister(classSource.Symbol); + symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); + table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); + } + + Type = symbol.Type; + return Identifier.EmitSymbol(builder, context, symbol, builder.CurrentFunction == null); } public override string ToString() { @@ -549,7 +576,7 @@ void EmitOpAccessChain(Span accessChainIds) throw new InvalidOperationException(); // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(builder.GetBuffer(), ref builder.Position, context, matchingComponent, false, result.Id); + result = Identifier.EmitSymbol(builder, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; break; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 3c152c2647..989dbabfae 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -266,14 +266,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, { var (builder, context) = compiler; - return CompileSymbol(table, builder.GetBuffer(), ref builder.Position, context, builder.CurrentFunction == null); + return CompileSymbol(table, builder, context, builder.CurrentFunction == null); } - private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref int position, SpirvContext context, bool constantOnly) + private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) { if (Name == "streams") { - var result = buffer.Insert(position++, new OpStreamsSDSL(context.Bound++)); + var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(), Specification.StorageClass.Private))); } @@ -306,10 +306,10 @@ private SpirvValue CompileSymbol(SymbolTable table, NewSpirvBuffer? buffer, ref if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) throw new InvalidOperationException($"Streams member {Name} used without an object"); Type = symbol.Type; - return EmitSymbol(buffer, ref position, context, symbol, constantOnly); + return EmitSymbol(builder, context, symbol, constantOnly); } - public static SpirvValue EmitSymbol(NewSpirvBuffer? buffer, ref int position, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) + public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); @@ -321,7 +321,7 @@ public static SpirvValue EmitSymbol(NewSpirvBuffer? buffer, ref int position, Sp throw new NotImplementedException(); if (instance == null) - instance = buffer.Insert(position++, new OpThisSDSL(context.Bound++)).ResultId; + instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; result.Id = instance.Value; return result; } @@ -335,10 +335,10 @@ public static SpirvValue EmitSymbol(NewSpirvBuffer? buffer, ref int position, Sp if (instance == null) { instance = isStage - ? buffer.Insert(position++, new OpStageSDSL(context.Bound++)).ResultId - : buffer.Insert(position++, new OpThisSDSL(context.Bound++)).ResultId; + ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId + : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; } - result.Id = buffer.Insert(position++, new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); + result.Id = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); } if (symbol.AccessChain is int accessChainIndex) { @@ -346,7 +346,7 @@ public static SpirvValue EmitSymbol(NewSpirvBuffer? buffer, ref int position, Sp throw new NotImplementedException(); var index = context.CompileConstant(accessChainIndex).Id; - result.Id = buffer.Insert(position++, new OpAccessChain(resultType, context.Bound++, result.Id, [index])); + result.Id = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [index])); } return result; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 24b38b9a01..6f2a6dc1f6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -601,7 +601,7 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { // Already processed? - if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) + if (table.DeclaredTypes.TryGetValue(classSource.ToClassNameWithGenerics(), out var symbolType)) return (LoadedShaderSymbol)symbolType; if (classSource.Buffer == null) @@ -614,7 +614,7 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, SpirvContext declaringContext) { // Already processed? - if (table.DeclaredTypes.TryGetValue(classSource.ToClassName(), out var symbolType)) + if (table.DeclaredTypes.TryGetValue(classSource.ToClassNameWithGenerics(), out var symbolType)) return (LoadedShaderSymbol)symbolType; if (classSource.Buffer == null) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 4d44292108..59437fe4b5 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -41,7 +41,7 @@ public record class ShaderClassInstantiation(string ClassName, int[] GenericArgu public LoadedShaderSymbol Symbol { get; set; } - public string ToClassName() + public string ToClassNameWithGenerics() { if ((GenericArguments == null || GenericArguments.Length == 0) && !ImportStageOnly) return ClassName; @@ -58,7 +58,7 @@ public string ToClassName() return result.ToString(); } - public override string ToString() => $"{(ImportStageOnly ? "stage " : string.Empty)}{ToClassName()} Symbol: {Symbol} Buffer: {(Buffer != null ? "set" : "empty")}"; + public override string ToString() => $"{(ImportStageOnly ? "stage " : string.Empty)}{ToClassNameWithGenerics()} Symbol: {Symbol} Buffer: {(Buffer != null ? "set" : "empty")}"; public virtual bool Equals(ShaderClassInstantiation? shaderClassSource) { @@ -114,7 +114,7 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { if (genericParameter.Index >= classSource.GenericArguments.Length) - throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassName()}"); + throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}"); genericParameterRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericParameter.Index]); } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) From 320d1df9ca43655b64319fb0f2e92e542a968cae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 15:28:22 +0900 Subject: [PATCH 0698/1182] Stop disassembling in main code. This is now done in tests or Stride itself --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 6 ------ src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 6 ------ src/Stride.Shaders.Compilers/ShaderLoaderBase.cs | 4 ++-- src/Stride.Shaders.Tests/RenderingTests.cs | 13 +++++++++++-- src/Stride.Shaders/Spirv/Building/Builder.Class.cs | 4 ---- src/Stride.Shaders/Spirv/Building/Context.cs | 2 +- 6 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index f9796c2b75..eb5b14e89f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -44,9 +44,6 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May throw new Exception("Some parse errors"); var merged = compiler.ToBuffer(); -#if DEBUG - var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); -#endif lastBuffer = new(merged); ShaderLoader.RegisterShader(shader.Name, macros, lastBuffer); @@ -63,9 +60,6 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May effect.Compile(table, compiler); var merged = compiler.ToBuffer(); -#if DEBUG - var dis = Spv.Dis(merged, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); -#endif lastBuffer = new(merged); ShaderLoader.RegisterShader(effect.Name, macros, lastBuffer); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 080da7c4e4..27e23cdf21 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -87,12 +87,6 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef bytecode = SpirvBytecode.CreateBytecodeFromBuffers(temp); -#if DEBUG - //File.WriteAllBytes("test.spv", bytecode); - //File.WriteAllText("test.spvdis", Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); - Spv.Dis(temp, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); -#endif - effectReflection = globalContext.Reflection; } diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 2aa43314bc..b1a8c0a8e5 100644 --- a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -32,11 +32,11 @@ public bool Equals(ShaderLoadKey other) private Dictionary> loadedShaders = []; - public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode buffer) + public virtual void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode) { if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) loadedShaders.Add(name, loadedShadersByName = new()); - loadedShadersByName.Add(new(defines.ToArray()), buffer); + loadedShadersByName.Add(new(defines.ToArray()), bytecode); } public bool Exists(string name) diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 56de140137..7622bd9ccc 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -45,14 +45,21 @@ protected override bool LoadExternalFileContent(string name, out string filename protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out SpirvBytecode buffer) { var result = base.LoadFromCode(filename, code, macros, out buffer); -#if DEBUG if (result) { + Console.WriteLine($"Loading shader {filename}"); Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } -#endif return result; } + + public override void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode) + { + base.RegisterShader(name, defines, bytecode); + + Console.WriteLine($"Registering shader {name}"); + Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } } [Theory] @@ -62,7 +69,9 @@ public void RenderTest1(string shaderName) // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader()); shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); + File.WriteAllBytes($"{shaderName}.spv", bytecode); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 59437fe4b5..41b63c7058 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -660,9 +660,6 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, // Split context and buffer - //if (!isFromCache) - // Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - // TODO: generics cache? if (genericResolver.NeedsResolve()) { @@ -679,7 +676,6 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - //Spv.Dis(shader, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); } return shaderBuffers; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index e422ce04d1..1312433c08 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -16,7 +16,7 @@ namespace Stride.Shaders.Spirv.Building; public interface IExternalShaderLoader { - public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode buffer); + public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode); public bool Exists(string name); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); From 12ec89e6d4a7bad2bcf205817fdce57c687c74a3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 17:54:28 +0900 Subject: [PATCH 0699/1182] Swap Rows/Columns when converting HLSL=>SPIR-V --- .../SDSL/ShaderMixer.CBuffers.cs | 15 ++++++++++----- src/Stride.Shaders/Core/SymbolTypes.Globals.cs | 9 +++++---- src/Stride.Shaders/Core/SymbolTypes.cs | 3 ++- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 7 ++++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 5 +++-- .../Parsing/SDSL/AST/ShaderElements.cs | 3 +++ .../Spirv/Building/Builder.CBuffer.cs | 7 ++++--- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 0f565fcec3..a056fcd729 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -399,11 +399,13 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, T ArrayType a => ConvertArrayType(context, a, typeModifier), StructType s => ConvertStructType(context, s), // TODO: should we use RowCount instead? (need to update Stride) - VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, ColumnCount = v.Size }, + VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, RowCount = 1, ColumnCount = v.Size }, + // Note: this is HLSL-style so Rows/Columns meaning is swapped + // however, for type/class, both TypeModifier and EffectParameterType are following HLSL MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Rows, ColumnCount = m.Columns }, + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Columns, ColumnCount = m.Rows }, MatrixType m when typeModifier == TypeModifier.RowMajor - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Rows, ColumnCount = m.Columns }, + => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Columns, ColumnCount = m.Rows }, }; EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier) @@ -499,9 +501,12 @@ private static void DecorateMember(SpirvContext context, int structTypeId, int i context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationOffset(offset))); if (memberType is MatrixType or ArrayType { BaseType: MatrixType }) { - if (memberTypeModifier != TypeModifier.ColumnMajor) + // HLSL row_major => SPIR-V ColMajor + // HLSL column_major => SPIR-V RowMajor + // HLSL nothing => SPIR-V RowMajor + if (memberTypeModifier == TypeModifier.RowMajor) context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.ColMajor, []))); - else if (memberTypeModifier != TypeModifier.RowMajor) + else context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.RowMajor, []))); context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationMatrixStride(16))); } diff --git a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs index 0e906d675b..574f2f5d6a 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs @@ -49,7 +49,7 @@ internal static FrozenDictionary Init() { var arr = new KeyValuePair[ScalarType.names.Length * 3]; for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 2; x < 5; x++) + for(int x = 2; x <= 4; x++) arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i]}{x}", new(ScalarType.From(ScalarType.names[i]),x)); return arr.ToFrozenDictionary(); } @@ -64,9 +64,10 @@ internal static FrozenDictionary Init() { var arr = new List>(ScalarType.names.Length * 3 * 3); for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 2; x < 5; x++) - for(int y = 2; y < 5; y++) - arr.Add(new($"{ScalarType.names[i]}{x}x{y}", new(ScalarType.From(ScalarType.names[i]),x,y))); + for(int x = 2; x <= 4; x++) + for(int y = 2; y <= 4; y++) + // Note: this is HLSL-style so Rows/Columns meaning is swapped + arr.Add(new($"{ScalarType.names[i]}{y}x{x}", new(ScalarType.From(ScalarType.names[i]),x,y))); return arr.ToFrozenDictionary(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 0f873cf7fc..602ebb979f 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -120,7 +120,8 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum public int Rows { get; } = Rows >= 2 ? Rows : throw new ArgumentException("Argument must be at least 2.", nameof(Rows)); public int Columns { get; } = Columns >= 2 ? Columns : throw new ArgumentException("Argument must be at least 2.", nameof(Columns)); - public override string ToString() => $"{BaseType}{Rows}x{Columns}"; + // Note: this is HLSL-style so Rows/Columns meaning is swapped + public override string ToString() => $"{BaseType}{Columns}x{Rows}"; } /// /// Array type. diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index a245956259..ab0d4dba1c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -1044,6 +1044,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, throw new NotImplementedException("Only implemented for floating types"); // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul + // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns and multiplication order need to be swapped var result = (xType, yType) switch { (ScalarType type1, ScalarType type2) => builder.InsertData(new OpFMul(x.TypeId, context.Bound++, x.Id, y.Id)), @@ -1051,10 +1052,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, (ScalarType type1, MatrixType type2) => builder.InsertData(new OpMatrixTimesScalar(y.TypeId, context.Bound++, y.Id, x.Id)), (VectorType type1, ScalarType type2) => builder.InsertData(new OpVectorTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), (VectorType type1, VectorType type2) when type1.Size == type2.Size => builder.InsertData(new OpDot(x.TypeId, context.Bound++, x.Id, y.Id)), - (VectorType type1, MatrixType type2) when type1.Size == type2.Rows => builder.InsertData(new OpVectorTimesMatrix(context.GetOrRegister(new VectorType(type1.BaseType, type2.Columns)), context.Bound++, x.Id, y.Id)), + (VectorType type1, MatrixType type2) when type1.Size == type2.Columns => builder.InsertData(new OpMatrixTimesVector(context.GetOrRegister(new VectorType(type1.BaseType, type2.Rows)), context.Bound++, y.Id, x.Id)), (MatrixType type1, ScalarType type2) => builder.InsertData(new OpMatrixTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), - (MatrixType type1, VectorType type2) when type1.Columns == type2.Size => builder.InsertData(new OpMatrixTimesVector(context.GetOrRegister(new VectorType(type1.BaseType, type1.Rows)), context.Bound++, x.Id, y.Id)), - (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type1.Rows, type2.Columns)), context.Bound++, x.Id, y.Id)), + (MatrixType type1, VectorType type2) when type1.Rows == type2.Size => builder.InsertData(new OpVectorTimesMatrix(context.GetOrRegister(new VectorType(type1.BaseType, type1.Columns)), context.Bound++, y.Id, x.Id)), + (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type2.Rows, type1.Columns)), context.Bound++, y.Id, x.Id)), }; return new SpirvValue(result); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 6f2a6dc1f6..383ba433e5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -264,10 +264,11 @@ void RegisterName(int target, string name) if (instruction.Op == Op.OpMemberDecorate && (OpMemberDecorate)instruction is { } memberDecorate) { var structType = (StructuredType)context.ReverseTypes[memberDecorate.StructureType]; + // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns if (memberDecorate.Decoration == Decoration.ColMajor) - structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.ColumnMajor }; - else if (memberDecorate.Decoration == Decoration.RowMajor) structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.RowMajor }; + else if (memberDecorate.Decoration == Decoration.RowMajor) + structType.Members[memberDecorate.Member] = structType.Members[memberDecorate.Member] with { TypeModifier = TypeModifier.ColumnMajor }; } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index a028ab4188..74208c1005 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -33,6 +33,9 @@ public enum StorageClass Volatile } +/// +/// Note: row/column major is defined from HLSL point of view (SPIR-V will have opposite) +/// public enum TypeModifier { None, diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index df7b7e0425..95dd8ff9ab 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -21,11 +21,12 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 8), StructuredType s => StructSizeInBuffer(s), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), - // Note: HLSL default is ColumnMajor, review that for GLSL/Vulkan later + // Note: this is HLSL-style so Rows/Columns meaning is swapped + // Note: HLSL default is ColumnMajor MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), - MatrixType m when typeModifier == TypeModifier.RowMajor => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Rows - 1)) + m.Columns), + MatrixType m when typeModifier == TypeModifier.RowMajor + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), // Round up to 16 bytes (size of float4) ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier), a.Size), // TODO: StructureType From 6354f9bc76094fca109bbc660da0f8d62fcbc8ea Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 8 Jan 2026 22:31:03 +0900 Subject: [PATCH 0700/1182] Links were not properly updated with composition path in cbuffers --- .../CompositionGenericsLinkType.sdsl | 22 ++++-- .../SDSL/ShaderMixer.CBuffers.cs | 72 +++++++++++-------- .../SDSL/ShaderMixer.cs | 32 ++++----- .../Parsing/SDSL/AST/ShaderElements.cs | 4 +- 4 files changed, 76 insertions(+), 54 deletions(-) diff --git a/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl index 516ed3f152..50b50c08b6 100644 --- a/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl +++ b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#01050304, cbuffer.Test=(TestBase=01,LinkValue1=05, LinkValue2=03, LinkValue3=04)) +// PSMain(ExpectedResult=#01050304, cbuffer.Test=(TestBase=01,LinkValue1=05, LinkValue2=03, LinkValue3.Comp2=04)) namespace Stride.Shaders.Tests; @@ -10,7 +10,7 @@ shader Compute } } -shader ComputeLink : Compute +shader ComputeLinkStage : Compute { cbuffer Test { @@ -24,6 +24,20 @@ shader ComputeLink : Compute } } +shader ComputeLink : Compute +{ + cbuffer Test + { + [Link("Link1")] + int Test1; + } + + override float Compute() + { + return (float)Test1; + } +} + shader GenericsLinkType { stream float4 ColorTarget : SV_Target0; @@ -46,7 +60,7 @@ shader GenericsLinkType effect CompositionGenericLinkType { mixin GenericsLinkType; - mixin compose Comp0 = ComputeLink<"LinkValue1">; - mixin compose Comp1 = ComputeLink<"LinkValue2">; + mixin compose Comp0 = ComputeLinkStage<"LinkValue1">; + mixin compose Comp1 = ComputeLinkStage<"LinkValue2">; mixin compose Comp2 = ComputeLink<"LinkValue3">; } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index a056fcd729..d95f1decb6 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -190,11 +190,13 @@ private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); + // Transfer decorations to new type, and also update Link decorations void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) { int mergedMemberIndex = 0; foreach (ref var cbuffer in cbuffersSpan) { + var variable = (OpVariableSDSL)cbuffer.Variable.Buffer[cbuffer.Variable.Index]; var compositionPath = cbuffer.CompositionPath; for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) @@ -204,37 +206,46 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri if (!decorations.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var decorationsForThisMember)) decorations.Add((context.Types[cbuffer.StructType], memberIndex), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); - - if (!newStructure) + bool hasLink = decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); + bool linkUpdated = false; + // If not specified, add default Link info + if (!hasLink) + linkValue = GenerateLinkName(cbuffer.ShaderName, member.Name); + if (!compositionPath.IsNullOrEmpty()) { - // If not a new structure, we restart from 0 and add only what's necessary - // Note: we made sure to query linkValue before - decorationsForThisMember.StringDecorations.Clear(); - decorationsForThisMember.Decorations.Clear(); + linkUpdated = true; + linkValue = ComposeLinkName((variable.Flags & VariableFlagsMask.Stage) != 0, linkValue, compositionPath); } - // Note: We don't mutate decorationsForThisMember because multiple cbuffer might share the same struct - // We emit OpMemberDecorateString directly on the resulting cbufferStructId - - // If not specified, add default Link info - if (linkValue == null) + if (newStructure) { - var link = $"{TypeName.GetTypeNameWithoutGenerics(cbuffer.ShaderName)}.{member.Name}"; - if (!compositionPath.IsNullOrEmpty()) - link = $"{link}.{compositionPath}"; + // Note: We don't mutate decorationsForThisMember because multiple cbuffer might share the same struct + // We emit OpMemberDecorateString directly on the resulting cbufferStructId + if (!hasLink || linkUpdated) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(linkValue))); - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(link))); - } - - // Also transfer LogicalGroup (from name) - if (cbuffer.LogicalGroup != null) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); + // Also transfer LogicalGroup (from name) + if (cbuffer.LogicalGroup != null) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); - foreach (var stringDecoration in decorationsForThisMember.StringDecorations) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); - foreach (var decoration in decorationsForThisMember.Decorations) - context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); + foreach (var stringDecoration in decorationsForThisMember.StringDecorations) + { + if (stringDecoration.Key == Decoration.LinkSDSL && !linkUpdated) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); + } + foreach (var decoration in decorationsForThisMember.Decorations) + context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); + } + else + { + if (!hasLink) + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(linkValue))); + else if (linkUpdated) + { + // Need to mutate LinkSDSL with new value + throw new NotImplementedException(); + } + } } } } @@ -250,12 +261,13 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // (we do it even for case count == 1 because all buffer except one might have been optimized away) context.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; - if (cbuffersEntry.Count() == 1) - { - ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); - } + // Optimization (not fully implemented, cf NotImplementedException in ProcessDecorations(), so disabled for now) + //if (cbuffersEntry.Count() == 1) + //{ + // ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); + //} // More than 1 cbuffers with same name - else + //else { int offset = 0; // TODO: Analyze and skip cbuffers parts which are unused diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 27e23cdf21..b8590884b7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -184,6 +184,18 @@ private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext mixinNode.EndInstruction = buffer.Count; } + private static string GenerateLinkName(string shaderName, string variableName) + { + return $"{TypeName.GetTypeNameWithoutGenerics(shaderName)}.{variableName}"; + } + + private static string ComposeLinkName(bool isStaging, string linkName, string? compositionPath = null) + { + if (!isStaging && compositionPath != null) + linkName += $".{compositionPath}"; + return linkName; + } + private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass) { var isRootMixin = mixinNode.Stage == null; @@ -437,21 +449,6 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } } - // Link attribute: postfix with composition path - if (mixinNode.CompositionPath != null) - { - foreach (var i in buffer) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - var n = new LiteralValue(m.Span); - n.Value = $"{n.Value}.{mixinNode.CompositionPath}"; - memberDecorate.Decoration = new(memberDecorate.Decoration.Value, n.Words); - n.Dispose(); - } - } - } - // Build ShaderInfo var shaderInfo = new ShaderInfo(mixinNode.Shaders.Count, shaderClass.ClassName, shaderStart, buffer.Count); foreach (var structType in structTypes) @@ -989,9 +986,8 @@ private static void ProcessReflection(MixinGlobalContext globalContext, SpirvCon { var name = context.Names[variable.ResultId]; linkInfos.TryGetValue(variable.ResultId, out var linkInfo); - var linkName = linkInfo.LinkName ?? $"{TypeName.GetTypeNameWithoutGenerics(currentShaderName)}.{name}"; - if (mixinNode.CompositionPath != null) - linkName = $"{linkName}.{mixinNode.CompositionPath}"; + var linkName = linkInfo.LinkName ?? GenerateLinkName(currentShaderName, name); + linkName = ComposeLinkName((variable.Flags & VariableFlagsMask.Stage) != 0, linkName, mixinNode.CompositionPath); var effectResourceBinding = new EffectResourceBindingDescription { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 74208c1005..d233de2032 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -390,8 +390,8 @@ internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass sha var linkInfo = CBuffer.ProcessLinkAttributes(table, info, attributes); if (linkInfo.LinkId is int linkId) context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); - else - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName ?? $"{shaderClass.Name}.{memberName}"))); + else if (linkInfo.LinkName != null) + context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName))); } } From f4eb1c9c5900c21fec53d51d1a38d995f559e83a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 10 Jan 2026 13:03:48 +0900 Subject: [PATCH 0701/1182] Process Link, ResourceGroup and LogicalGroup in a single place --- .../SDSL/ShaderMixer.CBuffers.cs | 129 ++---- .../SDSL/ShaderMixer.Reflection.cs | 396 ++++++++++++++++++ .../SDSL/ShaderMixer.cs | 307 +------------- 3 files changed, 451 insertions(+), 381 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index d95f1decb6..0ec4ded948 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -23,7 +23,6 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob // Remap from variable ID to member index in our new struct var variableToMemberIndices = new Dictionary(); // Collect any variable not a stream, not static and not a block - HashSet blockTypes = []; int firstVariableIndex = -1; foreach (var i in temp) { @@ -128,10 +127,9 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob } } - private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { // Collect Decorations - Dictionary logicalGroups = new(); Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); foreach (var i in context) { @@ -148,17 +146,12 @@ private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); } - else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: var m3 } } decorateLogicalGroup) - { - using var n = new LiteralValue(m3.Span); - logicalGroups.Add(decorateLogicalGroup.Target, n.Value); - } } string? GetCBufferLogicalGroup(int variableId) { - logicalGroups.TryGetValue(variableId, out var logicalGroup); - return logicalGroup; + resourceLinks.TryGetValue(variableId, out var linkName); + return linkName.LogicalGroup; } // OpSDSLEffect is emitted for any non-root composition @@ -181,75 +174,56 @@ private static void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, StructTypePtrId: x.Variable.Data.IdResultType.Value, - StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is ConstantBufferSymbol s ? s : null, MemberIndexOffset: 0, LogicalGroup: GetCBufferLogicalGroup(x.Variable.Data.IdResult.Value))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.Variable.Data.IdResult.Value])); - var cbufferStructTypes = cbuffersByNames.SelectMany(x => x).Select(x => context.Types[x.StructType]).ToHashSet(); - - // Transfer decorations to new type, and also update Link decorations - void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, StructuredType? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, int cbufferStructId, bool newStructure) + // This helper method will transfer decorations from the old structure to the new merged structure + // Also, it will add a default "Link" decoration if none was set + void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) { + var cbufferStructId = context.Types[cbufferStruct]; int mergedMemberIndex = 0; + var links = new string[cbufferStruct.Members.Count]; foreach (ref var cbuffer in cbuffersSpan) { - var variable = (OpVariableSDSL)cbuffer.Variable.Buffer[cbuffer.Variable.Index]; - var compositionPath = cbuffer.CompositionPath; - for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) { - var member = cbuffer.StructType.Members[memberIndex]; - if (!decorations.TryGetValue((context.Types[cbuffer.StructType], memberIndex), out var decorationsForThisMember)) decorations.Add((context.Types[cbuffer.StructType], memberIndex), decorationsForThisMember = new(new(), new())); - bool hasLink = decorationsForThisMember.StringDecorations.TryGetValue(Decoration.LinkSDSL, out var linkValue); - bool linkUpdated = false; - // If not specified, add default Link info - if (!hasLink) - linkValue = GenerateLinkName(cbuffer.ShaderName, member.Name); - if (!compositionPath.IsNullOrEmpty()) - { - linkUpdated = true; - linkValue = ComposeLinkName((variable.Flags & VariableFlagsMask.Stage) != 0, linkValue, compositionPath); - } - if (newStructure) { - // Note: We don't mutate decorationsForThisMember because multiple cbuffer might share the same struct - // We emit OpMemberDecorateString directly on the resulting cbufferStructId - if (!hasLink || linkUpdated) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(linkValue))); - - // Also transfer LogicalGroup (from name) - if (cbuffer.LogicalGroup != null) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLogicalGroupSDSL(cbuffer.LogicalGroup))); - + // Transfer previous decorations foreach (var stringDecoration in decorationsForThisMember.StringDecorations) - { - if (stringDecoration.Key == Decoration.LinkSDSL && !linkUpdated) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); - } + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); foreach (var decoration in decorationsForThisMember.Decorations) context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); } - else - { - if (!hasLink) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, ParameterizedFlags.DecorationLinkSDSL(linkValue))); - else if (linkUpdated) - { - // Need to mutate LinkSDSL with new value - throw new NotImplementedException(); - } - } } } } + // Transfer cbufferMemberLinks to new structure + (string Link, string LogicalGroup)[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) + { + var cbufferStructId = context.Types[cbufferStruct]; + int mergedMemberIndex = 0; + var links = new (string Link, string LogicalGroup)[cbufferStruct.Members.Count]; + foreach (ref var cbuffer in cbuffersSpan) + { + for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) + { + links[mergedMemberIndex] = cbufferMemberLinks[cbuffer.Variable.Data.IdResult.Value][memberIndex]; + } + } + + return links; + } + var idRemapping = new Dictionary(); var removedIds = new HashSet(); foreach (var cbuffersEntry in cbuffersByNames) @@ -261,13 +235,12 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // (we do it even for case count == 1 because all buffer except one might have been optimized away) context.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; - // Optimization (not fully implemented, cf NotImplementedException in ProcessDecorations(), so disabled for now) - //if (cbuffersEntry.Count() == 1) - //{ - // ProcessDecorations(cbuffersSpan, context.Types[cbuffersEntry.First().StructType], false); - //} + if (cbuffersEntry.Count() == 1) + { + ProcessDecorations(cbuffersSpan, cbuffersEntry.First().StructType, false); + } // More than 1 cbuffers with same name - //else + else { int offset = 0; // TODO: Analyze and skip cbuffers parts which are unused @@ -284,8 +257,8 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); - ProcessDecorations(cbuffersSpan, mergedCbufferStructId, true); - + ProcessDecorations(cbuffersSpan, mergedCbufferStruct, true); + // Remap member ids foreach (var i in buffer) { @@ -318,6 +291,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // Update first variable to use new type cbuffersSpan[0].Variable.Data.IdResultType = mergedCbufferPtrStructId; + cbufferMemberLinks[cbuffersSpan[0].Variable.Data.IdResult.Value] = GenerateCBufferLinks(cbuffersSpan[0].Variable.Data.IdResult.Value, cbuffersSpan, mergedCbufferStruct); foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) @@ -352,7 +326,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri SpirvBuilder.RemapIds(context.GetBuffer(), 0, context.GetBuffer().Count, idRemapping); } - private void ComputeCBufferOffsets(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { var cbuffers = buffer .Where(x => x.Op == Op.OpVariableSDSL) @@ -445,23 +419,6 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo } } - // Scan LinkSDSL and LogicalGroupSDSL decorations - Dictionary<(int StructType, int Member), string> links = new(); - Dictionary<(int StructType, int Member), string> logicalGroups = new(); - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LinkSDSL, Parameters: { } m } } memberDecorate) - { - using var n = new LiteralValue(m.Span); - links.Add((memberDecorate.StructType, memberDecorate.Member), n.Value); - } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m2 } } memberDecorate2) - { - using var n = new LiteralValue(m2.Span); - logicalGroups.Add((memberDecorate2.StructType, memberDecorate2.Member), n.Value); - } - } - foreach (var cbuffer in cbuffers) { int constantBufferOffset = 0; @@ -469,6 +426,9 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo var structTypeId = context.Types[cb]; var memberInfos = new EffectValueDescription[cb.Members.Count]; + if (!cbufferMemberLinks.TryGetValue(cbuffer.Variable.Data.IdResult.Value, out var cbufferLinks)) + throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.Variable.Data.IdResult.Value]}; it should have been generated during {MergeCBuffers}"); + for (var index = 0; index < cb.Members.Count; index++) { // Properly compute size and offset according to DirectX rules @@ -477,19 +437,16 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo DecorateMember(context, structTypeId, index, constantBufferOffset, memberSize, member.Type, member.TypeModifier); - if (!links.TryGetValue((structTypeId, index), out var linkName)) - throw new InvalidOperationException($"Could not find cbuffer member link info; it should have been generated during {MergeCBuffers}"); - // Allowed to be not set (in which case logicalGroup == null) - logicalGroups.TryGetValue((structTypeId, index), out var logicalGroup); + var linkInfo = cbufferLinks[index]; memberInfos[index] = new EffectValueDescription { Type = ConvertType(context, member.Type, member.TypeModifier), RawName = member.Name, - KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, + KeyInfo = new EffectParameterKeyInfo { KeyName = linkInfo.Link }, Offset = constantBufferOffset, Size = memberSize, - LogicalGroup = logicalGroup, + LogicalGroup = linkInfo.LogicalGroup, }; // Adjust offset for next item diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs new file mode 100644 index 0000000000..bea2c2ced2 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -0,0 +1,396 @@ +using System.Runtime.InteropServices; +using Stride.Shaders.Core; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Compilers.SDSL; + +public partial class ShaderMixer +{ + private Dictionary resourceLinks = new(); + // Note: cbuffer might share same struct, which is why we store this info per variable instead of per struct (as per OpMemberDecorate was doing) + private Dictionary cbufferMemberLinks = new(); + + private static bool IsResourceType(SymbolType type) + => type is TextureType or SamplerType or BufferType or ConstantBufferSymbol; + + // Process LinkSDSL, ResourceGroupSDSL and LogicalGroupSDSL; Info will be stored in resourceLinks and cbufferMemberLinks + private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) + { + // Link attribute: postfix with composition path + string? compositionPath = null; + string? shaderName = null; + + var variableDecorationLinks = new Dictionary(); + var structDecorationLinks = new Dictionary<(int, int), string>(); + + foreach (var i in context) + { + if (i.Op == Specification.Op.OpDecorateString && (OpDecorateString)i is + { Decoration: { Value: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL, Parameters: { } m } } decorate) + { + using var n = new LiteralValue(m.Span); + ref var link = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationLinks, decorate.Target, out _); + switch (decorate.Decoration.Value) + { + case Specification.Decoration.LinkSDSL: + link.Link = n.Value; + break; + case Specification.Decoration.ResourceGroupSDSL: + link.ResourceGroup = n.Value; + break; + case Specification.Decoration.LogicalGroupSDSL: + link.LogicalGroup = n.Value; + break; + default: + throw new NotImplementedException(); + } + } + else if (i.Op == Specification.Op.OpMemberDecorateString && (OpMemberDecorateString)i is + { Decoration: { Value: Specification.Decoration.LinkSDSL, Parameters: { } m2 } } memberDecorate) + { + using var n = new LiteralValue(m2.Span); + structDecorationLinks[(memberDecorate.StructType, memberDecorate.Member)] = n.Value; + } + } + + // Collect variable infos + foreach (var i in buffer) + { + if (i.Op == Specification.Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) + { + compositionPath = composition.CompositionPath; + } + else if (i.Op == Specification.Op.OpSDSLCompositionEnd) + { + compositionPath = null; + shaderName = null; + } + else if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + shaderName = shader.ShaderName; + } + else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) + { + bool isStage = (variableInstruction.Flags & Specification.VariableFlagsMask.Stage) != 0; + var variablePointerType = (PointerType)context.ReverseTypes[variableInstruction.ResultType]; + var variableType = variablePointerType.BaseType; + + if (IsResourceType(variableType)) + { + if (!variableDecorationLinks.TryGetValue(variableInstruction.ResultId, out var linkInfo) + || linkInfo.Link == null) + linkInfo.Link = GenerateLinkName(shaderName, context.Names[variableInstruction.ResultId]); + + if (!isStage) + linkInfo.Link = ComposeLinkName(linkInfo.Link, compositionPath); + + resourceLinks[variableInstruction.ResultId] = linkInfo; + + if (variableType is ConstantBufferSymbol cb) + { + var constantBufferStructId = context.Types[cb]; + (string Link, string LogicalGroup)[] memberLinks = new (string Link, string LogicalGroup)[cb.Members.Count]; + for (var index = 0; index < cb.Members.Count; index++) + { + var member = cb.Members[index]; + if (!structDecorationLinks.TryGetValue((constantBufferStructId, index), out var memberLink) + || memberLink == null) + memberLink = GenerateLinkName(shaderName, member.Name); + + if (!isStage) + memberLink = ComposeLinkName(memberLink, compositionPath); + memberLinks[index] = (memberLink, linkInfo.LogicalGroup); + } + + cbufferMemberLinks.Add(variableInstruction.ResultId, memberLinks); + } + } + } + } + } + + private void RenameVariables(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + { + // Collect variables by names + string? compositionPath = null; + var shaderNameWithComposition = string.Empty; + Dictionary prefixes = new(); + foreach (var i in temp) + { + if (i.Op == Specification.Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) + { + compositionPath = composition.CompositionPath; + } + else if (i.Op == Specification.Op.OpSDSLCompositionEnd) + { + compositionPath = null; + } + else if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + shaderNameWithComposition = compositionPath != null + ? $"{compositionPath}.{shader.ShaderName}" + : shader.ShaderName; + } + else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is + { Storageclass: Specification.StorageClass.UniformConstant } variable) + { + // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore + var type = context.ReverseTypes[variable.ResultType]; + if (type is not ConstantBufferSymbol) + prefixes[variable.ResultId] = shaderNameWithComposition; + } + else if (i.Op == Specification.Op.OpTypeStruct && (OpTypeStruct)i is { } structType) + { + prefixes[structType.ResultId] = shaderNameWithComposition; + } + else if (i.Op == Specification.Op.OpFunction && (OpFunction)i is { } function) + { + prefixes[function.ResultId] = shaderNameWithComposition; + } + } + + // Now, reprocess context with those names + foreach (var i in context) + { + if (i.Op == Specification.Op.OpName && (OpName)i is { } name) + { + if (prefixes.TryGetValue(name.Target, out var prefix)) + { + var updatedName = $"{prefix}.{name.Name}"; + name.Name = updatedName; + + // Now, make sure it's all valid HLSL/GLSL characters (this will replace multiple invalid characters with a single underscore) + // Otherwise, EffectReflection RawName won't match + updatedName = SpirvBuilder.RemoveInvalidCharactersFromSymbol(updatedName); + context.Names[name.Target] = updatedName; + } + } + } + } + + // Emit reflection (except ConstantBuffers which was emitted during ComputeCBufferReflection) + private void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode) + { + // First, figure out latest used bindings (assume they are filled in order) + int srvSlot = 0; + int samplerSlot = 0; + int cbufferSlot = 0; + foreach (var resourceBinding in globalContext.Reflection.ResourceBindings) + { + switch (resourceBinding) + { + case { Class: EffectParameterClass.ShaderResourceView }: + srvSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + case { Class: EffectParameterClass.Sampler }: + samplerSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + case { Class: EffectParameterClass.ConstantBuffer }: + cbufferSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; + break; + } + } + + // TODO: do this once at root level and reuse for child mixin + var samplerStates = new Dictionary(); + foreach (var i in context) + { + if ((i.Op == Specification.Op.OpDecorate || i.Op == Specification.Op.OpDecorateString) && + (OpDecorate)i is + { + Decoration: + { + Value: Specification.Decoration.SamplerStateFilter + or Specification.Decoration.SamplerStateAddressU + or Specification.Decoration.SamplerStateAddressV + or Specification.Decoration.SamplerStateAddressW + or Specification.Decoration.SamplerStateMipLODBias + or Specification.Decoration.SamplerStateMaxAnisotropy + or Specification.Decoration.SamplerStateComparisonFunc + or Specification.Decoration.SamplerStateMinLOD + or Specification.Decoration.SamplerStateMaxLOD, + Parameters: { } p + } + } decorate) + { + ref var samplerState = + ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var exists); + if (!exists) + samplerState = Graphics.SamplerStateDescription.Default; + switch (decorate.Decoration.Value) + { + case Specification.Decoration.SamplerStateFilter: + samplerState.Filter = (Graphics.TextureFilter)p.Span[0]; + break; + case Specification.Decoration.SamplerStateAddressU: + samplerState.AddressU = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Specification.Decoration.SamplerStateAddressV: + samplerState.AddressV = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Specification.Decoration.SamplerStateAddressW: + samplerState.AddressW = (Graphics.TextureAddressMode)p.Span[0]; + break; + case Specification.Decoration.SamplerStateMipLODBias: + { + using var n = new LiteralValue(p.Span); + samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); + break; + } + case Specification.Decoration.SamplerStateMaxAnisotropy: + samplerState.MaxAnisotropy = p.Span[0]; + break; + case Specification.Decoration.SamplerStateComparisonFunc: + samplerState.CompareFunction = (Graphics.CompareFunction)p.Span[0]; + break; + case Specification.Decoration.SamplerStateMinLOD: + { + using var n = new LiteralValue(p.Span); + samplerState.MinMipLevel = float.Parse(n.Value); + break; + } + case Specification.Decoration.SamplerStateMaxLOD: + { + using var n = new LiteralValue(p.Span); + samplerState.MaxMipLevel = float.Parse(n.Value); + break; + } + } + } + } + + string currentShaderName = string.Empty; + for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + { + var i = buffer[index]; + + if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + { + currentShaderName = shader.ShaderName; + } + else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) + { + var variablePointerType = (PointerType)context.ReverseTypes[variable.ResultType]; + var variableType = variablePointerType.BaseType; + + if (IsResourceType(variableType)) + { + var name = context.Names[variable.ResultId]; + + resourceLinks.TryGetValue(variable.ResultId, out var linkInfo); + var linkName = variableType switch + { + // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) + // Anyway, since buffer is merged, KeyName with form ShaderName.VariableName doesn't make sense as it doesn't belong to a specific shader anymore + ConstantBufferSymbol cb => name, + _ => linkInfo.Link ?? throw new InvalidOperationException($"Missing Link info for variable {name}"), + }; + + var effectResourceBinding = new EffectResourceBindingDescription + { + KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, + ElementType = default, + RawName = name, + ResourceGroup = linkInfo.ResourceGroup, + //Stage = , // filed by ShaderCompiler + LogicalGroup = linkInfo.LogicalGroup, + }; + + if (variableType is TextureType t) + { + var slot = globalContext.Reflection.ResourceBindings.Count; + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ShaderResourceView, + Type = (t, t.Multisampled) switch + { + (Texture1DType, false) => EffectParameterType.Texture1D, + (Texture2DType, false) => EffectParameterType.Texture2D, + (Texture2DType, true) => EffectParameterType.Texture2DMultisampled, + (Texture3DType, false) => EffectParameterType.Texture3D, + (TextureCubeType, false) => EffectParameterType.TextureCube, + }, + SlotStart = srvSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + + srvSlot++; + } + else if (variableType is BufferType) + { + var slot = globalContext.Reflection.ResourceBindings.Count; + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ShaderResourceView, + Type = EffectParameterType.Buffer, + SlotStart = srvSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + + srvSlot++; + } + else if (variableType is SamplerType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.Sampler, + Type = EffectParameterType.Sampler, + SlotStart = samplerSlot, + SlotCount = 1, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add( + new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(samplerSlot))); + + if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) + globalContext.Reflection.SamplerStates.Add( + new EffectSamplerStateBinding(linkName, samplerState)); + + samplerSlot++; + } + else if (variableType is ConstantBufferSymbol) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ConstantBuffer, + Type = EffectParameterType.ConstantBuffer, + SlotStart = cbufferSlot, + SlotCount = 1, + ResourceGroup = name, + }); + + context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add( + new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(cbufferSlot))); + + cbufferSlot++; + } + } + } + } + + // Process compositions recursively + foreach (var composition in mixinNode.Compositions) + { + ProcessReflection(globalContext, context, buffer, composition.Value); + } + + foreach (var compositionArray in mixinNode.CompositionArrays) + { + foreach (var composition in compositionArray.Value) + { + ProcessReflection(globalContext, context, buffer, composition); + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index b8590884b7..9593bc53a8 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using static Stride.Shaders.Spirv.Specification; @@ -60,16 +61,19 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef CodeInserted = (int index, int count) => AdjustIndicesAfterAppendInstructions(rootMixin, index, count) }; interfaceProcessor.Process(table, temp, context); - + // Any non-static variable is moved to a "Globals" default cbuffer // TODO: future language improvement: // force cbuffer to be epxlicit? (and not need "static" anymore for mixin nodes member, which is weird) // It's a breaking change and will require some changes to Stride shaders (esp. in post effects) GenerateDefaultCBuffer(rootMixin, globalContext, context, temp); + // Process Link (add CompositionPath, generate missing ones, etc.) + ProcessLinks(context, temp); + // Merge cbuffers and rgroups MergeCBuffers(globalContext, context, temp); - ComputeCBufferOffsets(globalContext, context, temp); + ComputeCBufferReflection(globalContext, context, temp); // Try to give variables more sensible names // Note: since we mutate OpName and globalContext.Names, try to do that as late as possible because some code earlier use names to match variables/types @@ -104,13 +108,6 @@ class MixinNodeContext public MixinNode? Result { get; } } - struct LinkInfo - { - public string LinkName; - public string ResourceGroup; - public string LogicalGroup; - } - MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { // We emit OPSDSLEffect for any non-root composition @@ -122,7 +119,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); - + BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); // Compositions (recursive) @@ -189,13 +186,16 @@ private static string GenerateLinkName(string shaderName, string variableName) return $"{TypeName.GetTypeNameWithoutGenerics(shaderName)}.{variableName}"; } - private static string ComposeLinkName(bool isStaging, string linkName, string? compositionPath = null) + private static string ComposeLinkName(string linkName, string? compositionPath = null) { - if (!isStaging && compositionPath != null) + if (compositionPath != null) linkName += $".{compositionPath}"; return linkName; } + // Append CompositionPath to "Link" for any non-stage variable + // Also force-emit the missing "Link" decorations + private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass) { var isRootMixin = mixinNode.Stage == null; @@ -810,289 +810,6 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte } } - private void RenameVariables(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) - { - // Collect variables by names - string? compositionPath = null; - var shaderNameWithComposition = string.Empty; - Dictionary prefixes = new(); - foreach (var i in temp) - { - if (i.Op == Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) - { - compositionPath = composition.CompositionPath; - } - else if (i.Op == Op.OpSDSLCompositionEnd) - { - compositionPath = null; - } - else if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) - { - shaderNameWithComposition = compositionPath != null - ? $"{compositionPath}.{shader.ShaderName}" - : shader.ShaderName; - } - else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { Storageclass: Specification.StorageClass.UniformConstant } variable) - { - // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore - var type = context.ReverseTypes[variable.ResultType]; - if (type is not ConstantBufferSymbol) - prefixes[variable.ResultId] = shaderNameWithComposition; - } - else if (i.Op == Op.OpTypeStruct && (OpTypeStruct)i is { } structType) - { - prefixes[structType.ResultId] = shaderNameWithComposition; - } - else if (i.Op == Op.OpFunction && (OpFunction)i is { } function) - { - prefixes[function.ResultId] = shaderNameWithComposition; - } - } - - // Now, reprocess context with those names - foreach (var i in context) - { - if (i.Op == Op.OpName && (OpName)i is { } name) - { - if (prefixes.TryGetValue(name.Target, out var prefix)) - { - var updatedName = $"{prefix}.{name.Name}"; - name.Name = updatedName; - - // Now, make sure it's all valid HLSL/GLSL characters (this will replace multiple invalid characters with a single underscore) - // Otherwise, EffectReflection RawName won't match - updatedName = SpirvBuilder.RemoveInvalidCharactersFromSymbol(updatedName); - context.Names[name.Target] = updatedName; - } - } - } - } - - private static void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode) - { - // First, figure out latest used bindings (assume they are filled in order) - int srvSlot = 0; - int samplerSlot = 0; - int cbufferSlot = 0; - foreach (var resourceBinding in globalContext.Reflection.ResourceBindings) - { - switch (resourceBinding) - { - case { Class: EffectParameterClass.ShaderResourceView }: - srvSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - case { Class: EffectParameterClass.Sampler }: - samplerSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - case { Class: EffectParameterClass.ConstantBuffer }: - cbufferSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - } - } - - // TODO: do this once at root level and reuse for child mixin - Dictionary linkInfos = new(); - var samplerStates = new Dictionary(); - foreach (var i in context) - { - // Fill linkInfos - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is - { - Target: int t, - Decoration: - { - Value: Decoration.LinkSDSL or Decoration.ResourceGroupSDSL or Decoration.LogicalGroupSDSL, - Parameters: { } m - } - } decoration) - { - using var n = new LiteralValue(m.Span); - ref var linkInfo = ref CollectionsMarshal.GetValueRefOrAddDefault(linkInfos, t, out _); - if (decoration.Decoration.Value == Decoration.LinkSDSL) - linkInfo.LinkName = n.Value; - else if (decoration.Decoration.Value == Decoration.ResourceGroupSDSL) - linkInfo.ResourceGroup = n.Value; - else if (decoration.Decoration.Value == Decoration.LogicalGroupSDSL) - linkInfo.LogicalGroup = n.Value; - } - else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && (OpDecorate)i is - { - Decoration: - { - Value: Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW - or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD, - Parameters: { } p - } - } decorate) - { - ref var samplerState = ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var exists); - if (!exists) - samplerState = Graphics.SamplerStateDescription.Default; - switch (decorate.Decoration.Value) - { - case Decoration.SamplerStateFilter: - samplerState.Filter = (Graphics.TextureFilter)p.Span[0]; - break; - case Decoration.SamplerStateAddressU: - samplerState.AddressU = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Decoration.SamplerStateAddressV: - samplerState.AddressV = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Decoration.SamplerStateAddressW: - samplerState.AddressW = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Decoration.SamplerStateMipLODBias: - { - using var n = new LiteralValue(p.Span); - samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); - break; - } - case Decoration.SamplerStateMaxAnisotropy: - samplerState.MaxAnisotropy = p.Span[0]; - break; - case Decoration.SamplerStateComparisonFunc: - samplerState.CompareFunction = (Graphics.CompareFunction)p.Span[0]; - break; - case Decoration.SamplerStateMinLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MinMipLevel = float.Parse(n.Value); - break; - } - case Decoration.SamplerStateMaxLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MaxMipLevel = float.Parse(n.Value); - break; - } - } - } - } - - string currentShaderName = string.Empty; - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = buffer[index]; - - if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shader) - { - currentShaderName = shader.ShaderName; - } - else if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) - { - var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType pointerType) - { - var name = context.Names[variable.ResultId]; - linkInfos.TryGetValue(variable.ResultId, out var linkInfo); - var linkName = linkInfo.LinkName ?? GenerateLinkName(currentShaderName, name); - linkName = ComposeLinkName((variable.Flags & VariableFlagsMask.Stage) != 0, linkName, mixinNode.CompositionPath); - - var effectResourceBinding = new EffectResourceBindingDescription - { - KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, - ElementType = default, - RawName = name, - ResourceGroup = linkInfo.ResourceGroup, - //Stage = , // filed by ShaderCompiler - LogicalGroup = linkInfo.LogicalGroup, - }; - - if (pointerType.BaseType is TextureType t) - { - var slot = globalContext.Reflection.ResourceBindings.Count; - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with - { - Class = EffectParameterClass.ShaderResourceView, - Type = (t, t.Multisampled) switch - { - (Texture1DType, false) => EffectParameterType.Texture1D, - (Texture2DType, false) => EffectParameterType.Texture2D, - (Texture2DType, true) => EffectParameterType.Texture2DMultisampled, - (Texture3DType, false) => EffectParameterType.Texture3D, - (TextureCubeType, false) => EffectParameterType.TextureCube, - }, - SlotStart = srvSlot, - SlotCount = 1, - }); - - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); - - srvSlot++; - } - else if (pointerType.BaseType is BufferType) - { - var slot = globalContext.Reflection.ResourceBindings.Count; - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with - { - Class = EffectParameterClass.ShaderResourceView, - Type = EffectParameterType.Buffer, - SlotStart = srvSlot, - SlotCount = 1, - }); - - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); - - srvSlot++; - } - else if (pointerType.BaseType is SamplerType) - { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with - { - Class = EffectParameterClass.Sampler, - Type = EffectParameterType.Sampler, - SlotStart = samplerSlot, - SlotCount = 1, - }); - - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(samplerSlot))); - - if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) - globalContext.Reflection.SamplerStates.Add(new EffectSamplerStateBinding(linkName, samplerState)); - - samplerSlot++; - } - else if (pointerType.BaseType is ConstantBufferSymbol) - { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with - { - Class = EffectParameterClass.ConstantBuffer, - Type = EffectParameterType.ConstantBuffer, - SlotStart = cbufferSlot, - SlotCount = 1, - // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) - // Anyway, since buffer is merged, KeyName with form ShaderName.VariableName doesn't make sense as it doesn't belong to a specific shader anymore - KeyInfo = new EffectParameterKeyInfo { KeyName = name }, - ResourceGroup = name, - }); - - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(cbufferSlot))); - - cbufferSlot++; - } - } - } - } - - // Process compositions recursively - foreach (var composition in mixinNode.Compositions) - { - ProcessReflection(globalContext, context, buffer, composition.Value); - } - foreach (var compositionArray in mixinNode.CompositionArrays) - { - foreach (var composition in compositionArray.Value) - { - ProcessReflection(globalContext, context, buffer, composition); - } - } - } - static void SetOpNop(Span words) { From 96d1a861d67e12aad3fb97e819d1a3b02b4a0c59 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 10 Jan 2026 15:41:20 +0900 Subject: [PATCH 0702/1182] ProcessReflection for the whole buffer (it was skipping Globals cbuffer which didn't belong to a MixinNode) --- .../SDSL/ShaderMixer.CBuffers.cs | 15 +++- .../SDSL/ShaderMixer.Reflection.cs | 71 +++++++------------ .../SDSL/ShaderMixer.cs | 10 +-- 3 files changed, 43 insertions(+), 53 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 0ec4ded948..2513c710f6 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -21,7 +21,8 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob { var members = new List(); // Remap from variable ID to member index in our new struct - var variableToMemberIndices = new Dictionary(); + var variables = new List(); + var variableToMemberIndices = new Dictionary(); // Collect any variable not a stream, not static and not a block int firstVariableIndex = -1; foreach (var i in temp) @@ -34,6 +35,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob firstVariableIndex = i.Index; variableToMemberIndices.Add(variable.ResultId, members.Count); members.Add(new(context.Names[variable.ResultId], variableType, TypeModifier.None)); + variables.Add(variable.ResultId); SetOpNop(i.Data.Memory.Span); } } @@ -44,16 +46,23 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob var globalCBufferType = new ConstantBufferSymbol("Globals", members); var globalCBufferTypeId = context.DeclareCBuffer(globalCBufferType); + var links = new (string? Link, string? LogicalGroup)[members.Count]; for (var index = 0; index < members.Count; index++) { var member = members[index]; context.AddMemberName(globalCBufferTypeId, index, member.Name); + + var linkInfo = variableLinks[variables[index]]; + links[index] = (linkInfo.Link, linkInfo.LogicalGroup); } - + // Note: we make sure to add at a previous variable index, otherwise the OpVariableSDSL won't be inside the root MixinNode.StartInstruction/EndInstruction temp.FluentReplace(firstVariableIndex, new OpVariableSDSL(context.GetOrRegister(new PointerType(globalCBufferType, Specification.StorageClass.Uniform)), context.Bound++, Specification.StorageClass.Uniform, VariableFlagsMask.Stage, null), out var cbufferVariable); context.AddName(cbufferVariable.ResultId, "Globals"); + // Update cbuffer links + cbufferMemberLinks[cbufferVariable.ResultId] = links; + // Replace all accesses int instructionsAddedInThisMethod = 0; for (var index = 0; index < temp.Count; index++) @@ -150,7 +159,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex string? GetCBufferLogicalGroup(int variableId) { - resourceLinks.TryGetValue(variableId, out var linkName); + variableLinks.TryGetValue(variableId, out var linkName); return linkName.LogicalGroup; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index bea2c2ced2..720ce34167 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer { - private Dictionary resourceLinks = new(); + private Dictionary variableLinks = new(); // Note: cbuffer might share same struct, which is why we store this info per variable instead of per struct (as per OpMemberDecorate was doing) private Dictionary cbufferMemberLinks = new(); @@ -78,35 +78,32 @@ private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) var variablePointerType = (PointerType)context.ReverseTypes[variableInstruction.ResultType]; var variableType = variablePointerType.BaseType; - if (IsResourceType(variableType)) - { - if (!variableDecorationLinks.TryGetValue(variableInstruction.ResultId, out var linkInfo) - || linkInfo.Link == null) - linkInfo.Link = GenerateLinkName(shaderName, context.Names[variableInstruction.ResultId]); + if (!variableDecorationLinks.TryGetValue(variableInstruction.ResultId, out var linkInfo) + || linkInfo.Link == null) + linkInfo.Link = GenerateLinkName(shaderName, context.Names[variableInstruction.ResultId]); - if (!isStage) - linkInfo.Link = ComposeLinkName(linkInfo.Link, compositionPath); + if (!isStage) + linkInfo.Link = ComposeLinkName(linkInfo.Link, compositionPath); - resourceLinks[variableInstruction.ResultId] = linkInfo; - - if (variableType is ConstantBufferSymbol cb) + variableLinks[variableInstruction.ResultId] = linkInfo; + + if (variableType is ConstantBufferSymbol cb) + { + var constantBufferStructId = context.Types[cb]; + (string Link, string LogicalGroup)[] memberLinks = new (string Link, string LogicalGroup)[cb.Members.Count]; + for (var index = 0; index < cb.Members.Count; index++) { - var constantBufferStructId = context.Types[cb]; - (string Link, string LogicalGroup)[] memberLinks = new (string Link, string LogicalGroup)[cb.Members.Count]; - for (var index = 0; index < cb.Members.Count; index++) - { - var member = cb.Members[index]; - if (!structDecorationLinks.TryGetValue((constantBufferStructId, index), out var memberLink) - || memberLink == null) - memberLink = GenerateLinkName(shaderName, member.Name); - - if (!isStage) - memberLink = ComposeLinkName(memberLink, compositionPath); - memberLinks[index] = (memberLink, linkInfo.LogicalGroup); - } - - cbufferMemberLinks.Add(variableInstruction.ResultId, memberLinks); + var member = cb.Members[index]; + if (!structDecorationLinks.TryGetValue((constantBufferStructId, index), out var memberLink) + || memberLink == null) + memberLink = GenerateLinkName(shaderName, member.Name); + + if (!isStage) + memberLink = ComposeLinkName(memberLink, compositionPath); + memberLinks[index] = (memberLink, linkInfo.LogicalGroup); } + + cbufferMemberLinks.Add(variableInstruction.ResultId, memberLinks); } } } @@ -172,7 +169,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont } // Emit reflection (except ConstantBuffers which was emitted during ComputeCBufferReflection) - private void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode) + private void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) { // First, figure out latest used bindings (assume they are filled in order) int srvSlot = 0; @@ -263,10 +260,8 @@ or Specification.Decoration.SamplerStateMinLOD } string currentShaderName = string.Empty; - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) + foreach (var i in buffer) { - var i = buffer[index]; - if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) { currentShaderName = shader.ShaderName; @@ -280,7 +275,7 @@ or Specification.Decoration.SamplerStateMinLOD { var name = context.Names[variable.ResultId]; - resourceLinks.TryGetValue(variable.ResultId, out var linkInfo); + variableLinks.TryGetValue(variable.ResultId, out var linkInfo); var linkName = variableType switch { // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) @@ -378,19 +373,5 @@ or Specification.Decoration.SamplerStateMinLOD } } } - - // Process compositions recursively - foreach (var composition in mixinNode.Compositions) - { - ProcessReflection(globalContext, context, buffer, composition.Value); - } - - foreach (var compositionArray in mixinNode.CompositionArrays) - { - foreach (var composition in compositionArray.Value) - { - ProcessReflection(globalContext, context, buffer, composition); - } - } } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9593bc53a8..68d413a0fe 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -62,15 +62,15 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef }; interfaceProcessor.Process(table, temp, context); + // Process Link (add CompositionPath, generate missing ones, etc.) + ProcessLinks(context, temp); + // Any non-static variable is moved to a "Globals" default cbuffer // TODO: future language improvement: // force cbuffer to be epxlicit? (and not need "static" anymore for mixin nodes member, which is weird) // It's a breaking change and will require some changes to Stride shaders (esp. in post effects) GenerateDefaultCBuffer(rootMixin, globalContext, context, temp); - - // Process Link (add CompositionPath, generate missing ones, etc.) - ProcessLinks(context, temp); - + // Merge cbuffers and rgroups MergeCBuffers(globalContext, context, temp); ComputeCBufferReflection(globalContext, context, temp); @@ -80,7 +80,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef RenameVariables(globalContext, context, temp); // Process reflection - ProcessReflection(globalContext, context, temp, rootMixin); + ProcessReflection(globalContext, context, temp); foreach (var inst in context) temp.Add(inst.Data); From feba4c58a6e5d122b73744133c320d9e78277114 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 10 Jan 2026 16:13:40 +0900 Subject: [PATCH 0703/1182] Build composition keys the opposite way (as Stride expects them) --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 68d413a0fe..b28cc66352 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -138,9 +138,12 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, var compositionResults = new MixinNode[compositionMixins.Length]; for (int i = 0; i < compositionMixins.Length; ++i) { - var compositionPath = currentCompositionPath != null ? $"{currentCompositionPath}.{variable.Key}" : variable.Key; + var localKey = variable.Key; if (isCompositionArray) - compositionPath += $"[{i}]"; + localKey += $"[{i}]"; + // TODO: Review: it seems like Stride compose variable the opposite way that we expect + // Let's change it so that it becomes {currentCompositionPath}.{localKey}! + var compositionPath = currentCompositionPath != null ? $"{localKey}.{currentCompositionPath}" : localKey; compositionResults[i] = MergeMixinNode(globalContext, context, table, buffer, compositionMixins[i], mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); } From 1ba028b5e1e9580d51f18b037f3b1f3bd3a1015b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 12 Jan 2026 11:18:19 +0100 Subject: [PATCH 0704/1182] Updated generator, 3 rendering tests failing --- .../SDSL/ShaderMixer.CBuffers.cs | 35 +- .../SDSL/ShaderMixer.Reflection.cs | 43 +- .../SDSL/ShaderMixer.cs | 12 +- .../Examples.Spirv.cs | 20 +- .../Literals/EnumerantParameters.cs | 89 ++ src/Stride.Shaders.Spirv.Generators/Range.cs | 268 ----- .../SPVGenerator.EnumerantParams.cs | 266 +++++ .../SPVGenerator.Helpers.Naming.cs | 19 +- .../SPVGenerator.Helpers.Preprocessing.cs | 13 +- .../SPVGenerator.Info.cs | 14 +- .../SPVGenerator.Instructions.cs | 957 ++++++------------ .../SPVGenerator.cs | 2 +- .../Stride.Shaders.Spirv.Generators.csproj | 4 + .../Parsing/SDSL/AST/Expression.cs | 58 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 6 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 24 +- .../Parsing/SDSL/AST/ShaderElements.cs | 16 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 2 +- .../Parsing/SDSL/AST/Statements.cs | 6 +- .../Spirv/Building/Builder.Class.cs | 38 +- .../Spirv/Building/Builder.Expressions.cs | 2 +- .../Spirv/Building/SpirvContext.Types.cs | 2 +- .../Spirv/Processing/InterfaceProcessor.cs | 61 +- 23 files changed, 841 insertions(+), 1116 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs delete mode 100644 src/Stride.Shaders.Spirv.Generators/Range.cs create mode 100644 src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 2513c710f6..c7e918d504 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -126,12 +126,12 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob if (i.Op == Op.OpDecorate && (OpDecorate)i is {} decorate) { if (variableToMemberIndices.TryGetValue(decorate.Target, out var memberIndex)) - i.Buffer.Replace(i.Index, new OpMemberDecorate(globalCBufferTypeId, memberIndex, decorate.Decoration)); + i.Buffer.Replace(i.Index, new OpMemberDecorate(globalCBufferTypeId, memberIndex, decorate.Decoration, decorate.DecorationParameters)); } else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is {} decorateString) { if (variableToMemberIndices.TryGetValue(decorateString.Target, out var memberIndex)) - i.Buffer.Replace(i.Index, new OpMemberDecorateString(globalCBufferTypeId, memberIndex, decorateString.Decoration)); + i.Buffer.Replace(i.Index, new OpMemberDecorateString(globalCBufferTypeId, memberIndex, decorateString.Decoration, decorateString.Value)); } } } @@ -142,18 +142,17 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); foreach (var i in context) { - if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Parameters: var m } } memberDecorate) + if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Value: string m } memberDecorate) { - using var n = new LiteralValue(m.Span); if (!decorations.TryGetValue((memberDecorate.StructType, memberDecorate.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration.Value, n.Value); + decorations.Add((memberDecorate.StructType, memberDecorate.Member), decorationsForThisMember = new([], [])); + decorationsForThisMember.StringDecorations.Add(memberDecorate.Decoration, m); } - else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Parameters: var m2 } } memberDecorate2) + else if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { DecorationParameters: var m2 } memberDecorate2) { if (!decorations.TryGetValue((memberDecorate2.StructureType, memberDecorate2.Member), out var decorationsForThisMember)) - decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new(new(), new())); - decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration.Value, m2); + decorations.Add((memberDecorate2.StructureType, memberDecorate2.Member), decorationsForThisMember = new([], [])); + decorationsForThisMember.Decorations.Add(memberDecorate2.Decoration, m2.Words); } } @@ -208,9 +207,9 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri { // Transfer previous decorations foreach (var stringDecoration in decorationsForThisMember.StringDecorations) - context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(stringDecoration.Key, [.. stringDecoration.Value.AsDisposableLiteralValue().Words]))); + context.Add(new OpMemberDecorateString(cbufferStructId, mergedMemberIndex, stringDecoration.Key, stringDecoration.Value)); foreach (var decoration in decorationsForThisMember.Decorations) - context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, new ParameterizedFlag(decoration.Key, decoration.Value))); + context.Add(new OpMemberDecorate(cbufferStructId, mergedMemberIndex, decoration.Key, [..decoration.Value.Span])); } } } @@ -355,7 +354,7 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) var hasOffsetDecorations = false; foreach (var i in context) { - if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: { Value: Decoration.Offset } } memberDecorate && memberDecorate.StructureType == structId) + if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: Decoration.Offset } memberDecorate && memberDecorate.StructureType == structId) { hasOffsetDecorations = true; break; @@ -411,7 +410,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo var hasStrideDecoration = false; foreach (var i in context) { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ArrayStride } } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ArrayStride } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) { hasStrideDecoration = true; } @@ -421,7 +420,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo { var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier).Size; var arrayStride = (elementSize + 15) / 16 * 16; - context.Add(new OpDecorate(typeId, ParameterizedFlags.DecorationArrayStride(arrayStride))); + context.Add(new OpDecorate(typeId, Decoration.ArrayStride, [arrayStride])); } return elementType with { Elements = a.Size }; @@ -476,17 +475,17 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo private static void DecorateMember(SpirvContext context, int structTypeId, int index, int offset, int size, SymbolType memberType, TypeModifier memberTypeModifier) { - context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationOffset(offset))); + context.Add(new OpMemberDecorate(structTypeId, index, Decoration.Offset, [offset])); if (memberType is MatrixType or ArrayType { BaseType: MatrixType }) { // HLSL row_major => SPIR-V ColMajor // HLSL column_major => SPIR-V RowMajor // HLSL nothing => SPIR-V RowMajor if (memberTypeModifier == TypeModifier.RowMajor) - context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.ColMajor, []))); + context.Add(new OpMemberDecorate(structTypeId, index, Decoration.ColMajor, [])); else - context.Add(new OpMemberDecorate(structTypeId, index, new ParameterizedFlag(Decoration.RowMajor, []))); - context.Add(new OpMemberDecorate(structTypeId, index, ParameterizedFlags.DecorationMatrixStride(16))); + context.Add(new OpMemberDecorate(structTypeId, index, Decoration.RowMajor, [])); + context.Add(new OpMemberDecorate(structTypeId, index, Decoration.MatrixStride, [16])); } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 720ce34167..a3785c28b7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -29,30 +29,28 @@ private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) foreach (var i in context) { if (i.Op == Specification.Op.OpDecorateString && (OpDecorateString)i is - { Decoration: { Value: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL, Parameters: { } m } } decorate) + { Decoration: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL, Value: string m } decorate) { - using var n = new LiteralValue(m.Span); ref var link = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationLinks, decorate.Target, out _); - switch (decorate.Decoration.Value) + switch (decorate.Decoration) { case Specification.Decoration.LinkSDSL: - link.Link = n.Value; + link.Link = m; break; case Specification.Decoration.ResourceGroupSDSL: - link.ResourceGroup = n.Value; + link.ResourceGroup = m; break; case Specification.Decoration.LogicalGroupSDSL: - link.LogicalGroup = n.Value; + link.LogicalGroup = m; break; default: throw new NotImplementedException(); } } else if (i.Op == Specification.Op.OpMemberDecorateString && (OpMemberDecorateString)i is - { Decoration: { Value: Specification.Decoration.LinkSDSL, Parameters: { } m2 } } memberDecorate) + { Decoration: Specification.Decoration.LinkSDSL, Value: string m2 } memberDecorate) { - using var n = new LiteralValue(m2.Span); - structDecorationLinks[(memberDecorate.StructType, memberDecorate.Member)] = n.Value; + structDecorationLinks[(memberDecorate.StructType, memberDecorate.Member)] = m2; } } @@ -198,9 +196,8 @@ private void ProcessReflection(MixinGlobalContext globalContext, SpirvContext co if ((i.Op == Specification.Op.OpDecorate || i.Op == Specification.Op.OpDecorateString) && (OpDecorate)i is { - Decoration: - { - Value: Specification.Decoration.SamplerStateFilter + Decoration : + Specification.Decoration.SamplerStateFilter or Specification.Decoration.SamplerStateAddressU or Specification.Decoration.SamplerStateAddressV or Specification.Decoration.SamplerStateAddressW @@ -209,15 +206,15 @@ or Specification.Decoration.SamplerStateMaxAnisotropy or Specification.Decoration.SamplerStateComparisonFunc or Specification.Decoration.SamplerStateMinLOD or Specification.Decoration.SamplerStateMaxLOD, - Parameters: { } p - } + DecorationParameters: { } p + } decorate) { ref var samplerState = ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var exists); if (!exists) samplerState = Graphics.SamplerStateDescription.Default; - switch (decorate.Decoration.Value) + switch (decorate.Decoration) { case Specification.Decoration.SamplerStateFilter: samplerState.Filter = (Graphics.TextureFilter)p.Span[0]; @@ -312,8 +309,8 @@ or Specification.Decoration.SamplerStateMinLOD SlotCount = 1, }); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); srvSlot++; } @@ -328,8 +325,8 @@ or Specification.Decoration.SamplerStateMinLOD SlotCount = 1, }); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(srvSlot))); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); srvSlot++; } @@ -343,9 +340,9 @@ or Specification.Decoration.SamplerStateMinLOD SlotCount = 1, }); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); context.Add( - new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(samplerSlot))); + new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [samplerSlot])); if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) globalContext.Reflection.SamplerStates.Add( @@ -364,9 +361,9 @@ or Specification.Decoration.SamplerStateMinLOD ResourceGroup = name, }); - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationDescriptorSet(0))); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); context.Add( - new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationBinding(cbufferSlot))); + new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [cbufferSlot])); cbufferSlot++; } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index b28cc66352..d3f9dd4cb0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -336,14 +336,10 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS context.Bound = Math.Max(context.Bound, i2.IdResult.Value + 1); // ResourceGroupId: adjust offsets too - if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) { // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly - var n = new LiteralValue(m.Span); - n.Value += resourceGroupOffset; - resourceGroupIdDecorate.Decoration = new(resourceGroupIdDecorate.Decoration.Value, n.Words); - context.ResourceGroupBound = Math.Max(context.ResourceGroupBound, n.Value + 1); - n.Dispose(); + resourceGroupIdDecorate.DecorationParameters = [m.Span[0] + resourceGroupOffset]; } if (SpirvBuilder.ContainIds(forbiddenIds, i2)) @@ -892,13 +888,13 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportVariable || i.Op == Op.OpSDSLFunctionInfo) temp.RemoveAt(index--); - else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration.Value is + else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) temp.RemoveAt(index--); - else if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration.Value is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + else if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) temp.RemoveAt(index--); // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 5bfaf7c961..d31f9f8a38 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -108,15 +108,15 @@ public static void CreateNewShader() buffer.FluentAdd(new OpTypePointer(id++, StorageClass.Function, t_int), out var t_p_func); buffer.FluentAdd(new OpConstant(t_int, id++, 4), out var constant8); buffer.FluentAdd(new OpVariable(t_p_input, id++, StorageClass.Input, null), out var v_input_3); - buffer.FluentAdd(new OpDecorate(t_array, ParameterizedFlags.DecorationArrayStride(16))); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 0, ParameterizedFlags.DecorationOffset(0))); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 1, ParameterizedFlags.DecorationOffset(16))); - buffer.FluentAdd(new OpMemberDecorate(t_struct, 2, ParameterizedFlags.DecorationOffset(96))); - buffer.FluentAdd(new OpMemberDecorate(t_struct2, 0, ParameterizedFlags.DecorationOffset(0))); - buffer.FluentAdd(new OpMemberDecorate(t_struct2, 1, ParameterizedFlags.DecorationOffset(112))); - buffer.FluentAdd(new OpDecorate(t_struct2, Decoration.Block)); - buffer.FluentAdd(new OpDecorate(v_struct2, ParameterizedFlags.DecorationDescriptorSet(0))); - buffer.FluentAdd(new OpDecorate(v_input_2, Decoration.NoPerspective)); + buffer.FluentAdd(new OpDecorate(t_array, Decoration.ArrayStride, [16])); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 0, Decoration.Offset, [0])); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 1, Decoration.Offset, [16])); + buffer.FluentAdd(new OpMemberDecorate(t_struct, 2, Decoration.Offset, [96])); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 0, Decoration.Offset, [0])); + buffer.FluentAdd(new OpMemberDecorate(t_struct2, 1, Decoration.Offset, [112])); + buffer.FluentAdd(new OpDecorate(t_struct2, Decoration.Block, [])); + buffer.FluentAdd(new OpDecorate(v_struct2, Decoration.DescriptorSet, [0])); + buffer.FluentAdd(new OpDecorate(v_input_2, Decoration.NoPerspective, [])); buffer.FluentAdd(new OpName(t_p_func, "main")); buffer.FluentAdd(new OpName(t_struct, "S")); buffer.FluentAdd(new OpMemberName(t_struct, 0, "b")); @@ -133,7 +133,7 @@ public static void CreateNewShader() buffer.FluentAdd(new OpFunctionEnd()); buffer.FluentAdd(new OpFunction(t_void, id++, FunctionControlMask.None, t_func), out var main); buffer.FluentAdd(new OpEntryPoint(ExecutionModel.Fragment, main, "PSMain", [v_output, v_input, v_input_2, v_input_3])); - buffer.FluentAdd(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft)); + buffer.FluentAdd(new OpExecutionMode(main, ExecutionMode.OriginLowerLeft, [])); buffer.FluentAdd(new OpLabel(id++), out var label2); buffer.FluentAdd(new OpFunctionCall(t_int, id++, add, [constant7, constant7]), out var resAdd); buffer.FluentAdd(new OpReturn()); diff --git a/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs b/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs new file mode 100644 index 0000000000..5afd8db2c5 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs @@ -0,0 +1,89 @@ +using CommunityToolkit.HighPerformance.Buffers; +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Text; + +namespace Stride.Shaders.Spirv.Core; + + +public interface IEnumerantParameter where T : IEnumerantParameter, allows ref struct +{ + abstract static T Create(Span words); +} + + +public static class EnumerantParametersBuilder +{ + public static EnumerantParameters Create(ReadOnlySpan words) + { + return new EnumerantParameters(words); + } +} + + + + +[CollectionBuilder(typeof(EnumerantParametersBuilder), "Create")] +public ref partial struct EnumerantParameters +{ + public MemoryOwner Words { get; private set; } + public Span Span => Words.Span; + public EnumerantParameters() + { + Words = MemoryOwner.Empty; + } + + public EnumerantParameters(params ReadOnlySpan words) + { + Words = MemoryOwner.Allocate(words.Length); + words.CopyTo(Words.Span); + } + public EnumerantParameters(Span words) + { + Words = MemoryOwner.Allocate(words.Length); + words.CopyTo(Words.Span); + } + + public EnumerantParameters(MemoryOwner words) + { + Words = words; + } + public readonly Span.Enumerator GetEnumerator() => Words.Span.GetEnumerator(); + + public readonly T To() + where T : IEnumerantParameter, allows ref struct + { + return T.Create(Words.Span); + } + + public readonly void Dispose() + { + Words?.Dispose(); + } +} + + +internal ref struct EnumerantParametersReader(Span words) +{ + readonly Span words = words; + int position = 0; + public bool End => position >= words.Length; + public int ReadInt() + => words[position++]; + public T ReadEnum() where T : Enum + => Unsafe.As(ref words[position++]); + public long ReadLong() + => words[position++] | (words[position++] << 32); + public float ReadFloat() + => BitConverter.Int32BitsToSingle(words[position++]); + public double ReadDouble() + => BitConverter.Int64BitsToDouble(words[position++] | (words[position++] << 32)); + + public string ReadString() + { + using var lit = new LiteralValue(words[position..]); + position += lit.Words.Length; + return lit.Value; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/Range.cs b/src/Stride.Shaders.Spirv.Generators/Range.cs deleted file mode 100644 index d1a283481e..0000000000 --- a/src/Stride.Shaders.Spirv.Generators/Range.cs +++ /dev/null @@ -1,268 +0,0 @@ -// https://github.com/dotnet/runtime/blob/419e949d258ecee4c40a460fb09c66d974229623/src/libraries/System.Private.CoreLib/src/System/Index.cs -// https://github.com/dotnet/runtime/blob/419e949d258ecee4c40a460fb09c66d974229623/src/libraries/System.Private.CoreLib/src/System/Range.cs - -using System.Runtime.CompilerServices; - -namespace System -{ - /// Represent a type can be used to index a collection either from the start or the end. - /// - /// Index is used by the C# compiler to support the new index syntax - /// - /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; - /// int lastElement = someArray[^1]; // lastElement = 5 - /// - /// - internal readonly struct Index : IEquatable - { - private readonly int _value; - - /// Construct an Index using a value and indicating if the index is from the start or from the end. - /// The index value. it has to be zero or positive number. - /// Indicating if the index is from the start or from the end. - /// - /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Index(int value, bool fromEnd = false) - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); - } - - if (fromEnd) - _value = ~value; - else - _value = value; - } - - // The following private constructors mainly created for perf reason to avoid the checks - private Index(int value) - { - _value = value; - } - - /// Create an Index pointing at first element. - public static Index Start => new(0); - - /// Create an Index pointing at beyond last element. - public static Index End => new(~0); - - /// Create an Index from the start at the position indicated by the value. - /// The index value from the start. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Index FromStart(int value) - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); - } - - return new Index(value); - } - - /// Create an Index from the end at the position indicated by the value. - /// The index value from the end. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Index FromEnd(int value) - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); - } - - return new Index(~value); - } - - /// Returns the index value. - public int Value - { - get - { - if (_value < 0) - { - return ~_value; - } - else - { - return _value; - } - } - } - - /// Indicates whether the index is from the start or the end. - public bool IsFromEnd => _value < 0; - - /// Calculate the offset from the start using the giving collection length. - /// The length of the collection that the Index will be used with. length has to be a positive value - /// - /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values. - /// we don't validate either the returned offset is greater than the input length. - /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and - /// then used to index a collection will get out of range exception which will be same affect as the validation. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetOffset(int length) - { - var offset = _value; - if (IsFromEnd) - { - // offset = length - (~value) - // offset = length + (~(~value) + 1) - // offset = length + value + 1 - - offset += length + 1; - } - return offset; - } - - /// Indicates whether the current Index object is equal to another object of the same type. - /// An object to compare with this object - public override bool Equals(object? value) => value is Index index && _value == index._value; - - /// Indicates whether the current Index object is equal to another Index object. - /// An object to compare with this object - public bool Equals(Index other) => _value == other._value; - - /// Returns the hash code for this instance. - public override int GetHashCode() => _value; - - /// Converts integer number to an Index. - public static implicit operator Index(int value) => FromStart(value); - - /// Converts the value of the current Index object to its equivalent string representation. - public override string ToString() - { - if (IsFromEnd) - return "^" + ((uint)Value).ToString(); - - return ((uint)Value).ToString(); - } - } - - /// Represent a range has start and end indexes. - /// - /// Range is used by the C# compiler to support the range syntax. - /// - /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 }; - /// int[] subArray1 = someArray[0..2]; // { 1, 2 } - /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } - /// - /// - /// Construct a Range object using the start and end indexes. - /// Represent the inclusive start index of the range. - /// Represent the exclusive end index of the range. - internal readonly struct Range(Index start, Index end) : IEquatable - { - /// Represent the inclusive start index of the Range. - public Index Start { get; } = start; - - /// Represent the exclusive end index of the Range. - public Index End { get; } = end; - - /// Indicates whether the current Range object is equal to another object of the same type. - /// An object to compare with this object - public override bool Equals(object? value) => - value is Range r && - r.Start.Equals(Start) && - r.End.Equals(End); - - /// Indicates whether the current Range object is equal to another Range object. - /// An object to compare with this object - public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End); - - /// Returns the hash code for this instance. - public override int GetHashCode() - { - return Start.GetHashCode() * 31 + End.GetHashCode(); - } - - /// Converts the value of the current Range object to its equivalent string representation. - public override string ToString() - { - return Start + ".." + End; - } - - /// Create a Range object starting from start index to the end of the collection. - public static Range StartAt(Index start) => new(start, Index.End); - - /// Create a Range object starting from first element in the collection to the end Index. - public static Range EndAt(Index end) => new(Index.Start, end); - - /// Create a Range object starting from first element to the end. - public static Range All => new(Index.Start, Index.End); - - /// Calculate the start offset and length of range object using a collection length. - /// The length of the collection that the range will be used with. length has to be a positive value. - /// - /// For performance reason, we don't validate the input length parameter against negative values. - /// It is expected Range will be used with collections which always have non negative length/count. - /// We validate the range is inside the length scope though. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public (int Offset, int Length) GetOffsetAndLength(int length) - { - int start; - var startIndex = Start; - if (startIndex.IsFromEnd) - start = length - startIndex.Value; - else - start = startIndex.Value; - - int end; - var endIndex = End; - if (endIndex.IsFromEnd) - end = length - endIndex.Value; - else - end = endIndex.Value; - - if ((uint)end > (uint)length || (uint)start > (uint)end) - { - throw new ArgumentOutOfRangeException(nameof(length)); - } - - return (start, end - start); - } - } -} - -namespace System.Runtime.CompilerServices -{ - internal static class RuntimeHelpers - { - /// - /// Slices the specified array using the specified range. - /// - public static T[] GetSubArray(T[] array, Range range) - { - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - - (int offset, int length) = range.GetOffsetAndLength(array.Length); - - if (default(T) != null || typeof(T[]) == array.GetType()) - { - // We know the type of the array to be exactly T[]. - - if (length == 0) - { - return []; - } - - var dest = new T[length]; - Array.Copy(array, offset, dest, 0, length); - return dest; - } - else - { - // The array is actually a U[] where U:T. - var dest = (T[])Array.CreateInstance(array.GetType().GetElementType(), length); - Array.Copy(array, offset, dest, 0, length); - return dest; - } - } - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs new file mode 100644 index 0000000000..9e702b9f54 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs @@ -0,0 +1,266 @@ +using AngleSharp.Common; +using AngleSharp.Text; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; +using System.Text; + +namespace Stride.Shaders.Spirv.Generators; + +public partial class SPVGenerator : IIncrementalGenerator +{ + + public void CreateEnumerantParameters(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) + { + context.RegisterImplementationSourceOutput( + grammarProvider, + GenerateEnumerantParameters + ); + } + + public static void GenerateEnumerantParameters(SourceProductionContext spc, SpirvGrammar grammar) + { + if (grammar.OperandKinds?.AsDictionary()?.Values?.ToList() is List opkinds) + { + spc.AddSource( + $"EnumerantParameters.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(@$" + using static Stride.Shaders.Spirv.Specification; + using CommunityToolkit.HighPerformance; + using CommunityToolkit.HighPerformance.Buffers; + using Stride.Shaders.Spirv.Core.Buffers; + + namespace Stride.Shaders.Spirv.Core; + + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateEnumerantParameterSingle(i, grammar)))} + + public ref partial struct EnumerantParameters + {{ + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateImplicitCasting(i, grammar)))} + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).SelectMany(k => k.Enumerants?.AsList() ?? []).Select(e => e.Parameters) + .Select(p => new EquatableList(p?.AsList().Select(x => x.Kind.ToCSType()).ToList() ?? [])) + .Where(p => p.Count > 1) + .Distinct() + .Select(i => GenerateImplicitTuples(i, grammar)))} + }} + ") + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + } + + public static string GenerateImplicitTuples(in EquatableList parameters, in SpirvGrammar grammar) + { + var sb = StringBuilderPool.Get(); + StringBuilderPool.Return(sb); + if (parameters.AsList() is List { Count: > 0 } paramsList) + { + sb.AppendLine(@$" + public static implicit operator EnumerantParameters(({string.Join(", ", paramsList)}) tuple) + {{ + Span span = ["); + for (int i = 0; i < paramsList.Count; i++) + { + var parameter = paramsList[i]; + var pName = $"tuple.Item{i + 1}"; + + if (i > 0) + sb.Append(", "); + + if (parameter is "int") + sb.Append($"{pName}"); + else if (parameter is "float") + sb.Append($"BitConverter.SingleToInt32Bits({pName})"); + else if (parameter is "string") + sb.Append($"..{pName}.AsDisposableLiteralValue().Words"); + else + sb.Append($"(int){pName}"); + } + sb.AppendLine("];"); + sb.AppendLine(@" + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + "); + } + return sb.ToString(); + } + public static string GenerateImplicitCasting(in OpKind opkind, in SpirvGrammar grammar) + { + var sb = StringBuilderPool.Get(); + + foreach (var enumerant in (opkind.Enumerants?.AsList() ?? []).Where(e => (e.Parameters?.AsList() ?? []).Count > 0)) + { + if (enumerant.Parameters?.AsList() is List { Count: > 0 } parameters) + { + + var structName = enumerant.Name switch + { + "FPFastMathMode" => "FPFastMathModeParameter", + "FPRoundingMode" => "FPRoundingModeParameter", + "BuiltIn" => "BuiltInParameter", + _ => enumerant.Name + }; + + sb.AppendLine(@$" + public static implicit operator EnumerantParameters({opkind.Kind}Params.{structName} parameter) + {{ + Span span = ["); + + foreach (var parameter in parameters) + { + if (parameter != parameters[0]) + sb.Append(", "); + var typename = parameter.Kind switch + { + "LiteralString" => "string", + "LiteralInteger" or "IdRef" => "int", + "LiteralFloat" => "float", + "FPFastMathMode" => "FPFastMathModeMask", + _ => parameter.Kind + }; + var pName = $"parameter.{parameter.Name?[0..1].ToUpperInvariant()}{parameter.Name?[1..]}"; + if (parameters.Count == 1 && (parameter.Kind == enumerant.Name || $"{parameter.Name?[0..1].ToUpperInvariant()}{parameter.Name?[1..]}" == enumerant.Name)) + pName = "parameter.Value"; + + + if (parameter.Kind is "LiteralInteger" or "IdRef") + sb.Append($"{pName}"); + else if (parameter.Kind is "LiteralFloat") + sb.Append($"BitConverter.SingleToInt32Bits({pName})"); + else if (parameter.Kind is "LiteralString") + sb.Append($"..{pName}.AsDisposableLiteralValue().Words"); + else + sb.Append($"(int){pName}"); + } + sb.AppendLine("];"); + sb.AppendLine(@" + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + "); + + + } + } + var result = sb.ToString(); + StringBuilderPool.Return(sb); + return result; + } + public static string GenerateEnumerantParameterSingle(in OpKind opkind, in SpirvGrammar grammar) + { + var sb = StringBuilderPool.Get(); + sb.AppendLine($"public static class {opkind.Kind}Params") + .AppendLine("{"); + foreach (var enumerant in (opkind.Enumerants?.AsList() ?? []).Where(e => (e.Parameters?.AsList() ?? []).Count > 0)) + { + + + if (enumerant.Parameters?.AsList() is List { Count: > 0 } parameters) + { + var structName = enumerant.Name switch + { + "FPFastMathMode" => "FPFastMathModeParameter", + "FPRoundingMode" => "FPRoundingModeParameter", + "BuiltIn" => "BuiltInParameter", + _ => enumerant.Name + }; + sb.Append($"public ref struct {structName}("); + if (parameters is [{ } op] && (op.Kind == enumerant.Name || $"{op.Name?[0..1].ToUpperInvariant()}{op.Name?[1..]}" == enumerant.Name)) + { + var typename = op.Kind.ToCSType(); + sb.Append($"{typename} value"); + } + else + { + + foreach (var parameter in parameters) + { + if (parameter != parameters[0]) + sb.Append(", "); + var typename = parameter.Kind.ToCSType(); + sb.Append($"{typename} {parameter.Name}"); + + } + } + + sb.AppendLine($") : IEnumerantParameter<{structName}>") + .AppendLine("{"); + + + + if (parameters is [{ } onlyParam] && (onlyParam.Kind == enumerant.Name || $"{onlyParam.Name?[0..1].ToUpperInvariant()}{onlyParam.Name?[1..]}" == enumerant.Name)) + { + var typename = onlyParam.Kind.ToCSType(); + sb.AppendLine($"public {typename} Value {{ get; set; }} = value;"); + } + else + { + + foreach (var parameter in parameters) + { + var typename = parameter.Kind.ToCSType(); + sb.AppendLine($"\tpublic {typename} {parameter.Name?[0..1].ToUpperInvariant()}{parameter.Name?[1..]} {{ get; set; }} = {parameter.Name};"); + + } + } + + + sb.Append(@$" + public static {structName} Create(Span words) + {{ + var reader = new EnumerantParametersReader(words); + var parameter = new {structName} + {{"); + + foreach (var parameter in parameters) + { + var pname = parameters.Count == 1 && (parameter.Kind == enumerant.Name || $"{parameter.Name?[0..1].ToUpperInvariant()}{parameter.Name?[1..]}" == enumerant.Name) + ? "Value" + : $"{parameter.Name?[0..1].ToUpperInvariant()}{parameter.Name?[1..]}"; + var typename = parameter.Kind.ToCSType(); + sb.AppendLine($"{pname} = reader.Read{typename switch { "int" => "Int", "float" => "Float", "string" => "String", string s => $"Enum<{s}>" }}(),"); + + } + sb.AppendLine(@$" + }}; + return parameter; + }} + }}"); + + } + } + + + sb.AppendLine("}"); + StringBuilderPool.Return(sb); + return sb.ToString(); + } + + + +} + +file static class KindExtensions +{ + public static string ToCSType(this string kind) + { + return kind switch + { + "LiteralString" => "string", + "LiteralInteger" or "IdRef" or "IdScope" => "int", + "LiteralFloat" => "float", + "FPFastMathMode" => "FPFastMathModeMask", + _ => kind + }; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 9f309ef9ba..0bcb5d7d98 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -60,6 +60,10 @@ public static void PreProcessOperands(InstructionData op, Dictionary operands) { + if (op.OpName.EndsWith("DecorateString")) + operands.Add(new() { Kind = "LiteralString", Name = "value" }); + else if (op.OpName.EndsWith("DecorateId")) + operands.Add(new() { Kind = "IdRef", Name = "value" }); bool computable = true; for (int i = 0; i < operands.Count; i++) { @@ -72,7 +76,7 @@ public static void PreProcessOperands(InstructionData op, Dictionary computable }; var kind = e.Kind; - var realKind = ConvertKind(kind!, operandKinds); + var realKind = ConvertKind(kind, operandKinds); if (e.Quantifier is not null) { if (e.Name is string name) @@ -99,12 +103,17 @@ public static void PreProcessOperands(InstructionData op, Dictionary enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) + e.Class = operandKinds[kind].Category; + if ( + !op.OpName.EndsWith("DecorateString") + && !op.OpName.EndsWith("DecorateId") + && operandKinds[kind].Enumerants?.AsList() is List enumerants + && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 }) + ) e.IsParameterized = true; operands[i] = e; } @@ -284,4 +293,4 @@ public static string ConvertOperandName(string input, string? quant = null, bool static string LowerFirst(string s) => char.IsLower(s[0]) ? s : $"{char.ToLowerInvariant(s[0])}{s[1..]}"; -} +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index d87b6cd5a6..e3c4296696 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -42,10 +42,7 @@ public SpirvGrammar PreProcessGrammar(ImmutableArray files, Canc grammar.Revision = parsed.Revision; } if (parsed.Instructions is not null) - { - grammar.Instructions?.AsList()?.AddRange(parsed.Instructions?.AsList() ?? []); - } if (parsed.OperandKinds?.AsDictionary() is Dictionary parsedKinds && grammar.OperandKinds?.AsDictionary() is Dictionary grammarKinds) { foreach (var pk in parsedKinds) @@ -111,7 +108,7 @@ string s when s.StartsWith("Id") => "int", } return grammar; } - + public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationToken _) { var config = Configuration.Default.WithDefaultLoader(); @@ -127,6 +124,7 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok // var buffer = new List(24); if (grammar.Instructions?.AsList() is List instructions) { + var extinst = instructions.First(x => x.OpName == "OpExtInst"); // Prebuilt for fast lookup var tableblocksCore = coreDoc!.QuerySelectorAll($"p.tableblock").ToArray(); var coreNodesById = new Dictionary(); @@ -146,7 +144,6 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok } for (int i = 0; i < instructions.Count; i++) - // foreach (var instruction in grammar.Instructions) { var instruction = grammar.Instructions.Value.AsList()![i]!; @@ -178,7 +175,13 @@ string v when v.Contains("SDSL") => null, // SDSL does not have documentation var buffer = new List<(string, string)>(24); if (instruction.Operands?.AsList() is List operands) + { + if (instruction.OpName.StartsWith("GLSL")) + { + operands.InsertRange(0, extinst.Operands?.AsList().Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }) ?? []); + } PreProcessOperands(instruction, grammar.OperandKinds?.AsDictionary()!, buffer); + } instructions[i] = instruction; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index ba061b8a66..a50026b1d3 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -58,13 +58,13 @@ public static class ParameterizedFlags } code.AppendLine(")") .Append($" => new ParameterizedFlag<{realKind}>({realKind}.{enumerant.Name}, [{string.Join(", ", (enumerant.Parameters?.AsList() ?? []).Select(x => x.CSType switch - { - "float" => $"BitConverter.SingleToInt32({x.Name})", - "string" => $".. {x.Name}.AsDisposableLiteralValue().Words", - "int" => x.Name, - _ => $"(int){x.Name}", + { + "float" => $"BitConverter.SingleToInt32({x.Name})", + "string" => $".. {x.Name}.AsDisposableLiteralValue().Words", + "int" => x.Name, + _ => $"(int){x.Name}", - }))}]);"); + }))}]);"); } code.AppendLine("}"); context.AddSource( @@ -198,7 +198,7 @@ public static void GenerateInfo(InstructionData op, StringBuilder code, SpirvGra { code.Append($"Instance.Register(Op.{opname}, OperandKind.{operand.Kind ?? ""}, OperandQuantifier.{operand.Quantifier switch { "*" => "ZeroOrMore", "?" => "ZeroOrOne", _ => "One" }}, \"{operand.Name}\", \"{spvClass ?? "Debug"}\""); - if (dict.TryGetValue(operand.Kind ?? throw new Exception("Operand is null in registering"), out var opkind) && opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) + if (operand.IsParameterized && dict.TryGetValue(operand.Kind ?? throw new Exception("Operand is null in registering"), out var opkind) && opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) { // code.Append($", [{string.Join(", ", opkind.Enumerants?.Select(x => $"new({x.Name ?? "null"}, OperandKind.{x.})") ?? [])}]"); code.Append(", new() {") diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index db5b1fa36b..0da90dce54 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -2,6 +2,8 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; +using System.Collections.Concurrent; +using System.Dynamic; using System.Text; using System.Text.Json; @@ -9,738 +11,375 @@ namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator : IIncrementalGenerator { + internal class StringBuilderPool + { + public static StringBuilderPool Instance { get; } = new(); + readonly ConcurrentBag pool = []; + private StringBuilderPool() { } + public static StringBuilder Get() + { + var sb = Instance.pool.TryTake(out var builder) ? builder : new(); + sb.Clear(); + return sb; + } + public static void Return(StringBuilder builder) => Instance.pool.Add(builder); + } public void GenerateStructs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - // var sdslInstructionsData = - // grammarProvider - // .Select(static (grammar, _) => grammar.Instructions ?? new([])); - context.RegisterImplementationSourceOutput( grammarProvider, GenerateInstructionStructs ); } + public static void GenerateInstructionStructs(SourceProductionContext spc, SpirvGrammar grammar) { - StringBuilder builder = new(); - builder - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("using CommunityToolkit.HighPerformance;") - .AppendLine("using CommunityToolkit.HighPerformance.Buffers;") - .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("using System.Numerics;") - .AppendLine("using System.Runtime.CompilerServices;") - .AppendLine() - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine() - .AppendLine(); - StringBuilder body1 = new(); - StringBuilder body2 = new(); - StringBuilder body3 = new(); - StringBuilder body4 = new(); if (grammar.Instructions?.AsList() is List instructions) { - foreach (var instruction in instructions) - { - - body1.Clear(); - body2.Clear(); - body3.Clear(); - body4.Clear(); - - - if (instruction.OpName.EndsWith("Constant")) - WriteConstantInstructions(grammar, instruction, builder, body1, body2, body3, body4); - // else if (instruction.OpName.Contains("Decorate")) - // WriteDecorateInstructions(grammar, instruction, builder, body1, body2, body3, body4); - else if (instruction.OpName.StartsWith("OpCopyMemory")) - WriteCopyMemoryInstructions(grammar, instruction, body1, body2, body3, body4); - else if (instruction.OpName.Contains("GLSL")) - WriteGLSLCode(grammar, instruction, builder, body1, body2, body3, body4); - else WriteOtherInstructions(grammar, instruction, builder, body1, body2, body3, body4); - } + spc.AddSource( + $"Instructions.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(@$" + using static Stride.Shaders.Spirv.Specification; + using CommunityToolkit.HighPerformance; + using CommunityToolkit.HighPerformance.Buffers; + using Stride.Shaders.Spirv.Core.Buffers; + using System.Numerics; + using System.Runtime.CompilerServices; + + namespace Stride.Shaders.Spirv.Core; + + {string.Join("\n", instructions.Select(i => GenerateInstructionStructsSingle(i, grammar)))} + + ") + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); } - spc.AddSource( - $"Instructions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(builder.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); } - - - public static (string TypeName, string FieldName, string OperandName) ToTypeFieldAndOperandName(OperandData operand) + public static string GenerateInstructionStructsSingle(InstructionData instruction, SpirvGrammar grammar) { - string typename = (operand.Kind, operand.Quantifier, operand.Class, operand.IsParameterized) switch - { - (string s, null or "", "ValueEnum", true) => $"ParameterizedFlag<{s}>", - (string s, null or "", "BitEnum", true) => $"ParameterizedFlag<{s}Mask>", - (string s, null or "", _, false) when s.StartsWith("Id") => "int", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", null or "", _, false) => "int", - ("LiteralFloat", null or "", _, false) => "float", - ("LiteralString", null or "", _, false) => "string", - (string s, null or "", _, false) when s.StartsWith("Pair") => "(int, int)", - (string s, null or "", "BitEnum", false) when !s.StartsWith("Literal") => $"{s}Mask", - (string s, null or "", "ValueEnum", false) when !s.StartsWith("Literal") => s, - (string s, "?", "ValueEnum", true) => $"ParameterizedFlag<{s}>?", - (string s, "?", "BitEnum", true) => $"ParameterizedFlag<{s}Mask>?", - (string s, "?", _, false) when s.StartsWith("Id") => "int?", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "?", _, false) => "int?", - ("LiteralFloat", "?", _, false) => "float?", - ("LiteralString", "?", _, false) => "string?", - (string s, "?", "BitEnum", false) when !s.StartsWith("Literal") => $"{s}Mask?", - (string s, "?", "ValueEnum", false) when !s.StartsWith("Literal") => $"{s}?", - (string s, "*", _, false) when s.StartsWith("Id") => $"LiteralArray", - ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "*", _, false) => "LiteralArray", - ("LiteralFloat", "*", _, false) => "LiteralArray", - // ("LiteralString", "*", _) => "LiteralArray", - (string s, "*", _, false) when s.StartsWith("Pair") => $"LiteralArray<(int, int)>", - (string s, "*", "BitEnum", false) when !s.StartsWith("Literal") => $"LiteralArray<{s}Mask>", - (string s, "*", "ValueEnum", false) when !s.StartsWith("Literal") => $"LiteralArray<{s}>", - ("LiteralContextDependentNumber", null or "", _, false) => "LiteralValue", - _ => throw new NotImplementedException($"Could not generate C# type for '{operand.Kind}{operand.Quantifier}'") - }; - + if (instruction.OpName.StartsWith("OpCopyMemory") || instruction.OpName.StartsWith("OpCooperativeMatrixLoad") || instruction.OpName.StartsWith("OpCooperativeMatrixStore")) + return ""; + var structBuilder = StringBuilderPool.Get(); + // var extinst = Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); - string fieldName; - string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); - if (operand.Name is null or "") - fieldName = ConvertKindToName(operand.Kind, false); + if (instruction.OpName.EndsWith("Constant")) + structBuilder.AppendLine($"public ref partial struct {instruction.OpName} : IMemoryInstruction\n where T : struct, INumber"); else - { - var nameBuilder = new StringBuilder(); - bool first = true; - foreach (var c in operand.Name) - { - if (char.IsLetterOrDigit(c) || c == '_') - { - nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; - } - - } - fieldName = nameBuilder.ToString(); - } - return (typename, fieldName, operandName); - } + structBuilder.AppendLine(@$"public ref partial struct {instruction.OpName} : IMemoryInstruction"); + structBuilder.AppendLine(@$" + {{ + private ref OpData opData; + public ref OpData OpData => ref opData; + public MemoryOwner InstructionMemory + {{ + get + {{ + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + }} + private set + {{ + if (!Unsafe.IsNullRef(ref OpData)) + {{ + OpData.Memory.Dispose(); + OpData.Memory = value; + }} + else + field = value; + }} + }} + public {instruction.OpName}() + {{ + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.{(instruction.OpName.StartsWith("GLSL") ? "OpExtInst" : instruction.OpName)} | (1 << 16); + }} + "); - static string ToSpreadOperator(OperandData operand) - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - return (operand.Class, operand.Quantifier, operand.IsParameterized) switch - { - (string s, null or "", false) when s.Contains("Id") => $"{fieldName}", - (string s, "?", false) when s.Contains("Id") => $".. ({fieldName} is null ? (Span)[] : [{fieldName}.Value])", - (string s, null or "", false) when s.Contains("Enum") => $"(int){fieldName}", - (string s, null or "", true) when s.Contains("Enum") => $".. (Span)[(int){fieldName}.Value, .. {fieldName}.Span]", - (string s, "?", false) when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value])", - (string s, "?", true) when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value.Value, .. {fieldName}.Value.Span])", - (string, "*", false) => $".. {fieldName}.Words", - (string, "?", false) => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", - (_, "?", false) => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", - _ => $".. {fieldName}.AsDisposableLiteralValue().Words" - }; - } - static void WriteOtherInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) - { - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref index.Data);") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"public {instruction.OpName}(ref OpData data)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref data);") - .AppendLine("opData = ref data;") - .AppendLine("}"); - - body2.AppendLine($"public void Attach(OpDataIndex index)") - .AppendLine("{") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"private void InitializeProperties(ref OpData data)") - .AppendLine("{"); + structBuilder + .AppendLine(@$" + public {instruction.OpName}(OpDataIndex index) + {{ + InitializeProperties(ref index.Data); + opData = ref index.Data; + }} + + public {instruction.OpName}(ref OpData data) + {{ + InitializeProperties(ref data); + opData = ref data; + }}" + ); if (instruction.Operands?.AsList() is List operands) { - body2.AppendLine("foreach (var o in data)") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - // Body 1 - - if (operands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - var tmp = -1; - foreach (var operand in operands) + foreach (var op in operands) { - tmp += 1; - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(op); if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); + structBuilder.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); + else if (op.IsParameterized) + structBuilder.Append(@$" + public {typename} {fieldName} {{ get; set; }} + public EnumerantParameters {fieldName}Parameters {{ get; set {{ field.Dispose(); field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}" + ); + else if (instruction.OpName.EndsWith("Constant") && typename.StartsWith("LiteralValue")) + structBuilder.Append($"public T {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - - // Body 2 - body2.AppendLine($"{(tmp == 0 ? "" : "else ")}if(o.Name == \"{operandName}\")"); - bool needCloseBrace = false; - // Optional operands - if (operand.Quantifier == "?") - { - body2.AppendLine("{"); - body2.AppendLine("if (o.Words.Length > 0)"); - needCloseBrace = true; - } - if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To{typename}();"); - else if (operand.Class is string s && s.Contains("Enum")) - body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); - - if (needCloseBrace) - body2.AppendLine("}"); - - if (grammar.OperandKinds?.AsDictionary() is Dictionary dict - && dict.TryGetValue(operand.Kind, out var opkind) && opkind.Enumerants?.AsList() is List enumerants && enumerants.Any(x => x.Parameters?.AsList() is List { Count: > 0 })) - { - body2.AppendLine($"else if({string.Join(" || ", enumerants - .Where(e => e.Parameters?.AsList() is List { Count: > 0 }) - .SelectMany(enumerant => enumerant.Parameters?.AsList()) - .Select(param => $"o.Name == \"{param.Name ?? ConvertKindToName(param.Kind)}\""))})"); - body2.AppendLine($"{fieldName} = new({fieldName}{(typename.EndsWith("?") ? ".Value" : "")}.Value, o.Words);"); - } - - // Body 3 - body3.AppendLine($"{fieldName} = {operandName};"); + structBuilder.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); } - body2.AppendLine("}"); - foreach(var operand in operands.Where(o => o.Quantifier == "*")) + if (operands.Any(x => x is { Kind: "IdResult" })) { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - body2.AppendLine($"if({fieldName}.WordCount == -1)") - .AppendLine($"{fieldName} = new();"); + structBuilder.AppendLine(@$" + public static implicit operator int({instruction.OpName}{(instruction.OpName.EndsWith("Constant") ? "" : "")} inst) => inst.ResultId;" + ); } - - body3 - .AppendLine("UpdateInstructionMemory();") - .AppendLine("opData = ref Unsafe.NullRef();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") - .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") - .Append(string.Join(", ", operands.Select(ToSpreadOperator))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); + structBuilder.AppendLine(@$" + public {instruction.OpName}({string.Join(", ", operands.Select(ToFunctionParameters))}) + {{ + {string.Join("\n", operands.Select(ToAssignSimple))} + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + }} + " + ); } - else - body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); + structBuilder.AppendLine(@$" - builder.AppendLine($@" - public ref partial struct {instruction.OpName} : IMemoryInstruction + public void Attach(OpDataIndex index) {{ - private ref OpData opData; - public ref OpData OpData => ref opData; - public MemoryOwner InstructionMemory - {{ - get - {{ - if (!Unsafe.IsNullRef(ref OpData)) - return OpData.Memory; - else return field; - }} - - private set - {{ - if (!Unsafe.IsNullRef(ref OpData)) - {{ - OpData.Memory.Dispose(); - OpData.Memory = value; - }} - else field = value; - }} - }} + opData = ref index.Data; + }} - public {instruction.OpName}() + public void UpdateInstructionMemory() + {{ + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.{ToSpreadOperators(instruction, grammar)}]; + instruction[0] |= instruction.Length << 16; + if(instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else {{ - InstructionMemory = MemoryOwner.Allocate(1); - InstructionMemory.Span[0] = (int)Op.{instruction.OpName} | (1 << 16); + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; }} - - {body1} - {body2} - {body3} - {body4} - - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); }} - "); - } - static void WriteDecorateInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) - { - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref index.Data);") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"public {instruction.OpName}(ref OpData data)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref data);") - .AppendLine("opData = ref data;") - .AppendLine("}"); - - body2.AppendLine($"public void Attach(OpDataIndex index)") - .AppendLine("{") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"private void InitializeProperties(ref OpData data)") - .AppendLine("{"); - - if (instruction.Operands?.AsList() is List operands) - { - if (instruction.OpName.EndsWith("Id")) - // Note: not sure if this is correct, it might need to be an array (quantifier *) which we don't support nicely yet - operands.Add(new() { Name = "additionalId", Kind = "IdRef" }); - else if (instruction.OpName.EndsWith("String")) - operands.Add(new() { Name = "additionalString", Kind = "LiteralString", Quantifier = "?" }); - else - { - // Note: not sure if this is correct, it might need to be an array (quantifier *) which we don't support nicely yet - operands.Add(new() { Name = "additionalInteger", Kind = "LiteralInteger", Quantifier = "?" }); - operands.Add(new() { Name = "additionalInteger2", Kind = "LiteralInteger", Quantifier = "?" }); - } - - body2.AppendLine("foreach (var o in data)") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName} {(typename.EndsWith("?") ? "= null" : "")}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - - // Body 1 - - if (operands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - var tmp = -1; - foreach (var operand in operands) - { - tmp += 1; - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - - // Body 2 - if (tmp != 0) - body2.Append($"else "); - body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To{typename}();"); - else if (operand.Class is string s && s.Contains("Enum")) - body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); - // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); - } - body2.AppendLine("}"); - - body3 - .AppendLine("UpdateInstructionMemory();") - .AppendLine("opData = ref Unsafe.NullRef();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") - .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") - .Append(string.Join(", ", operands.Select(ToSpreadOperator))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); - - } - else - body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); - - builder.AppendLine($@" - public ref struct {instruction.OpName} : IMemoryInstruction + private void InitializeProperties(ref OpData data) {{ - private ref OpData opData; - public ref OpData OpData => ref opData; - public MemoryOwner InstructionMemory + foreach (var o in data) {{ - get + switch(o.Name) {{ - if (!Unsafe.IsNullRef(ref OpData)) - return OpData.Memory; - else return field; - }} - - private set - {{ - if (!Unsafe.IsNullRef(ref OpData)) - {{ - OpData.Memory.Dispose(); - OpData.Memory = value; - }} - else field = value; + {ToAssignSwitchCases(instruction.Operands?.AsList() ?? [], grammar)} + // We ignore unrecognized operands + default: break; }} }} - {body1} - {body2} - {body3} - {body4} - - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); + {string.Join( + "\n", + (instruction.Operands?.AsList() ?? []) + .Where(x => x.Quantifier == "*") + .Select( + x => + { + var (typename, fieldname, operandname) = ToTypeFieldAndOperandName(x); + return $"if({fieldname}.WordCount == -1) {fieldname} = new();"; + } + ) + )} }} - "); + public static implicit operator {instruction.OpName}{(instruction.OpName.EndsWith("Constant") ? "" : "")}(OpDataIndex odi) => new(odi);"); + + if (instruction.Operands?.AsList() is List ops && ops.Any(x => x is { Quantifier: "*" } or { IsParameterized: true })) + { + structBuilder.AppendLine(@$" + public void Dispose() + {{ + {string.Join("\n", ops.Where(x => x is { Quantifier: "*" }).Select(ToTypeFieldAndOperandName).Select(t => $"{t.FieldName}.Dispose();"))} + {string.Join("\n", ops.Where(x => x is { IsParameterized: true }).Select(ToTypeFieldAndOperandName).Select(t => $"{t.FieldName}Parameters.Dispose();"))} + }} + "); + } + structBuilder.AppendLine("}"); + StringBuilderPool.Return(structBuilder); + return structBuilder.ToString(); + } - static void WriteGLSLCode(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + public static string ToSpreadOperators(InstructionData instruction, SpirvGrammar grammar) { - var extinst = grammar.Instructions?.AsList().First(x => x.OpName == "OpExtInst") ?? throw new Exception("Could not find OpExtInst instruction"); - - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref index.Data);") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"public {instruction.OpName}(ref OpData data)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref data);") - .AppendLine("opData = ref data;") - .AppendLine("}"); - - body2.AppendLine($"public void Attach(OpDataIndex index)") - .AppendLine("{") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"private void InitializeProperties(ref OpData data)") - .AppendLine("{"); - if (instruction.Operands?.AsList() is List operands && extinst.Operands?.AsList() is List extOperands) + // (instruction.OpName.StartsWith("GLSL") ? "OpExtInst" : instruction.OpName)}, {string.Join(", ", (instruction.Operands?.AsList() ?? []).Select(ToSpreadOperator)) + if (instruction.Operands?.AsList() is List operands) { - var allOperands = extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" } and not { Kind: "LiteralExtInstInteger" }); - body2.AppendLine("foreach (var o in data)") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", allOperands.Select(x => + var sb = StringBuilderPool.Get(); + if (instruction.OpName.StartsWith("GLSL")) { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - - // Body 1 - if (allOperands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - body1.AppendLine($"public int Instruction => {instruction.OpCode};"); - foreach (var operand in allOperands) - { - - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - - // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray")) + sb.Append("OpExtInst, "); + foreach (var operand in operands) { - body2.AppendLine($"{fieldName} = o.To{typename}();"); + if (operand != operands[0]) + sb.Append(", "); + sb.Append(ToSpreadOperator(operand)); + var (_, fieldname, _) = ToTypeFieldAndOperandName(operand); + if (fieldname == "Set") + sb.Append($", {instruction.OpCode}"); } - else if (operand.Class is string s && s.Contains("Enum")) - body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); - // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); } - body2.AppendLine("}"); - - body3 - .AppendLine("UpdateInstructionMemory();") - .AppendLine("opData = ref Unsafe.NullRef();") - .AppendLine("}"); - - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") - .Append($"Span instruction = [(int)Op.{extinst.OpName}, ") - .Append(string.Join(", ", extOperands.Concat(operands).Where(x => x is not { Kind: "IdRef", Quantifier: "*" }).Select(ToSpreadOperator))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); + else + sb.Append(instruction.OpName).Append(", ").Append(string.Join(", ", operands.Select(ToSpreadOperator))); + StringBuilderPool.Return(sb); + return sb.ToString(); + } + return instruction.OpName; + } + public static string ToAssignSimple(OperandData operand) + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + return $"{fieldName} = {operandName};{(operand.IsParameterized ? $"\n{fieldName}Parameters = {operandName}Parameters;" : "")}"; + } + public static string ToAssignSwitchCases(List operands, SpirvGrammar grammar) + { + var sb = StringBuilderPool.Get(); + foreach (var operand in operands) + { + sb.AppendLine(ToAssignSwitchCase(operand)); + if (operand.IsParameterized) + break; } - body2.AppendLine("}"); - builder.AppendLine($@" - public ref struct {instruction.OpName} : IMemoryInstruction - {{ - private ref OpData opData; - public ref OpData OpData => ref opData; - public MemoryOwner InstructionMemory - {{ - get - {{ - if (!Unsafe.IsNullRef(ref OpData)) - return OpData.Memory; - else return field; - }} + StringBuilderPool.Return(sb); + return sb.ToString(); + } + public static string ToAssignSwitchCase(OperandData operand) + { + var sb = StringBuilderPool.Get(); - private set - {{ - if (!Unsafe.IsNullRef(ref OpData)) - {{ - OpData.Memory.Dispose(); - OpData.Memory = value; - }} - else field = value; - }} - }} + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - {body1} - {body2} - {body3} - {body4} + var isOptional = operand.Quantifier == "?"; + var isArray = typename.StartsWith("LiteralArray"); + var opClass = operand.Class; + var isParameterized = operand.IsParameterized; + sb.Append($"case \"{operandName}\" : "); + if (isOptional) + sb.AppendLine("if (o.Words.Length > 0){"); + + if (isArray) + sb.AppendLine($"{fieldName} = o.To{typename}();"); + + else if (opClass == "ValueEnum" && isParameterized) + sb.AppendLine(@$" + {fieldName} = o.ToEnum<{operand.Kind}>(); + {fieldName}Parameters = new(data.Memory.Span[(o.Offset+2)..]); + "); + else if (opClass == "BitEnum" && isParameterized) + sb.AppendLine(@$" + {fieldName} = o.ToEnum<{operand.Kind}Mask>(); + if(data.Memory.Span.Length > o.Offset + 1) + {fieldName}Parameters = new(data.Memory.Span[(o.Offset+2)..]); + "); + else if (opClass == "BitEnum" && !isParameterized) + sb.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}Mask>();"); + else if (opClass == "ValueEnum" && !isParameterized) + sb.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}>();"); + else + sb.AppendLine($"{fieldName} = o.ToLiteral<{typename.Replace("?", "")}>();"); + if (isOptional) + sb.AppendLine("}"); + sb.Append("break;"); - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - }} - "); + StringBuilderPool.Return(sb); + return sb.ToString(); + } + public static string ToFunctionParameters(OperandData operand) + { + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + return operand.IsParameterized ? $"{typename} {operandName}, EnumerantParameters {operandName}Parameters" : $"{typename} {operandName}"; } - static void WriteConstantInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder builder, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + public static (string TypeName, string FieldName, string OperandName) ToTypeFieldAndOperandName(OperandData operand) { - body2.AppendLine($"public {instruction.OpName}(OpDataIndex index)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref index.Data);") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"public {instruction.OpName}(ref OpData data)") - .AppendLine("{") - .AppendLine("InitializeProperties(ref data);") - .AppendLine("opData = ref data;") - .AppendLine("}"); - - body2.AppendLine($"public void Attach(OpDataIndex index)") - .AppendLine("{") - .AppendLine("opData = ref index.Data;") - .AppendLine("}"); - - body2.AppendLine($"private void InitializeProperties(ref OpData data)") - .AppendLine("{"); - - if (instruction.Operands?.AsList() is List operands) + string typename = (operand.Kind, operand.Quantifier, operand.Class) switch { - body2.AppendLine("foreach (var o in data)") - .AppendLine("{"); - - body3.Append($"public {instruction.OpName}(") - .Append(string.Join(", ", operands.Select(x => - { - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(x); - return $"{typename} {operandName}"; - }))) - .AppendLine(")") - .AppendLine("{"); - - - // Body 1 + (string s, null or "", _) when s.StartsWith("Id") => "int", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", null or "", _) => "int", + ("LiteralFloat", null or "", _) => "float", + ("LiteralString", null or "", _) => "string", + (string s, null or "", _) when s.StartsWith("Pair") => "(int, int)", + (string s, null or "", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask", + (string s, null or "", "ValueEnum") when !s.StartsWith("Literal") => s, + (string s, "?", _) when s.StartsWith("Id") => "int?", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "?", _) => "int?", + ("LiteralFloat", "?", _) => "float?", + ("LiteralString", "?", _) => "string?", + (string s, "?", "BitEnum") when !s.StartsWith("Literal") => $"{s}Mask?", + (string s, "?", "ValueEnum") when !s.StartsWith("Literal") => $"{s}?", + (string s, "*", _) when s.StartsWith("Id") => $"LiteralArray", + ("LiteralInteger" or "LiteralExtInstInteger" or "LiteralSpecConstantOpInteger", "*", _) => "LiteralArray", + ("LiteralFloat", "*", _) => "LiteralArray", + // ("LiteralString", "*", _) => "LiteralArray", + (string s, "*", _) when s.StartsWith("Pair") => $"LiteralArray<(int, int)>", + (string s, "*", "BitEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}Mask>", + (string s, "*", "ValueEnum") when !s.StartsWith("Literal") => $"LiteralArray<{s}>", + ("LiteralContextDependentNumber", null or "", _) => "LiteralValue", + _ => throw new NotImplementedException($"Could not generate C# type for '{operand.Kind}{operand.Quantifier}'") + }; - foreach (var operand in operands) + string fieldName; + string operandName = ConvertOperandName(operand.Name ?? ConvertKindToName(operand.Kind), operand.Quantifier); + if (operand.Name is null or "") + fieldName = ConvertKindToName(operand.Kind, false); + else + { + var nameBuilder = new StringBuilder(); + bool first = true; + foreach (var c in operand.Name) { + if (char.IsLetterOrDigit(c) || c == '_') + { + nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); + first &= false; + } - (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); - - if (typename.StartsWith("LiteralArray")) - body1.Append($"public {typename} {fieldName} {{ get; set {{ field.Assign(value); if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - else if (typename.StartsWith("LiteralValue")) - body1.Append($"public T {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - else - body1.Append($"public {typename} {fieldName} {{ get; set {{ field = value; if(InstructionMemory is not null) UpdateInstructionMemory(); }} }}"); - - // Body 2 - body2.AppendLine($"if(o.Name == \"{operandName}\")"); - if (typename.StartsWith("LiteralArray")) - body2.AppendLine($"{fieldName} = o.To{typename}();"); - else if (operand.Class is string s && s.Contains("Enum")) - body2.AppendLine($"{fieldName} = o.ToEnum<{operand.Kind}{(operand.Class is "BitEnum" ? "Mask" : "")}>();"); - else if (typename.StartsWith("LiteralValue")) - body2.AppendLine($"{fieldName} = o.ToLiteral();"); - else body2.AppendLine($"{fieldName} = o.ToLiteral<{typename.TrimEnd('?')}>();"); - // Body 3 - if (typename.StartsWith("LiteralArray")) - body3.AppendLine($"{fieldName}.Assign({operandName});"); - else body3.AppendLine($"{fieldName} = {operandName};"); } - - if (operands.Any(x => x is { Kind: "IdResult" })) - body1.AppendLine($"public static implicit operator Id({instruction.OpName} inst) => new Id(inst.ResultId);") - .AppendLine($"public static implicit operator int({instruction.OpName} inst) => inst.ResultId;"); - body2.AppendLine("}"); - - body3 - .AppendLine("UpdateInstructionMemory();") - .AppendLine("opData = ref Unsafe.NullRef();") - .AppendLine("}"); - - // Body 4 - - body4.AppendLine("public void UpdateInstructionMemory()") - .AppendLine("{") - .AppendLine("if(InstructionMemory is null) InstructionMemory = MemoryOwner.Empty;") - .Append($"Span instruction = [(int)Op.{instruction.OpName}, ") - .Append(string.Join(", ", operands.Select(ToSpreadOperator))) - .Append("];") - .AppendLine(@" - instruction[0] |= instruction.Length << 16; - if(instruction.Length == InstructionMemory.Length) - instruction.CopyTo(InstructionMemory.Span); - else - { - var tmp = MemoryOwner.Allocate(instruction.Length); - instruction.CopyTo(tmp.Span); - InstructionMemory?.Dispose(); - InstructionMemory = tmp; - }" - ) - .AppendLine("}"); - + fieldName = nameBuilder.ToString(); } - else - body4.AppendLine("public void UpdateInstructionMemory(){}"); - body2.AppendLine("}"); - - builder.AppendLine($@" - // {string.Join(", ", instruction.Operands?.AsList().Select(x => $"{x.Name}:{x.Kind}"))} - public ref struct {instruction.OpName} : IMemoryInstruction - where T : struct, INumber - {{ - private ref OpData opData; - public ref OpData OpData => ref opData; - public MemoryOwner InstructionMemory - {{ - get - {{ - if (!Unsafe.IsNullRef(ref OpData)) - return OpData.Memory; - else return field; - }} - - private set - {{ - if (!Unsafe.IsNullRef(ref OpData)) - {{ - OpData.Memory.Dispose(); - OpData.Memory = value; - }} - else field = value; - }} - }} + return (typename, fieldName, operandName); + } - {body1} - {body2} - {body3} - {body4} - public static implicit operator {instruction.OpName}(OpDataIndex odi) => new(odi); - }} - "); - } - static void WriteCopyMemoryInstructions(SpirvGrammar grammar, in InstructionData instruction, StringBuilder body1, StringBuilder body2, StringBuilder body3, StringBuilder body4) + static string ToSpreadOperator(OperandData operand) { - + (string typename, string fieldName, string operandName) = ToTypeFieldAndOperandName(operand); + return (operand.Class, operand.Quantifier) switch + { + (string s, null or "") when s.Contains("Id") => $"{fieldName}", + (string s, "?") when s.Contains("Id") => $".. ({fieldName} is null ? (Span)[] : [{fieldName}.Value])", + (string s, null or "") when s.Contains("Enum") => + operand.IsParameterized ? $"(int){fieldName}, .. {fieldName}Parameters" : $"(int){fieldName}", + (string s, "?") when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value])", + (string, "*") => $".. {fieldName}.Words", + (string, "?") => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", + (_, "?") => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", + _ => $".. {fieldName}.AsDisposableLiteralValue().Words" + }; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 4c55dda197..fa159c2cca 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -35,7 +35,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .Select(PreProcessEnumerants) .Select(PreProcessInstructions); - CreateParameterizedFuncs(context, grammarData); + CreateEnumerantParameters(context, grammarData); CreateInfo(context, grammarData); CreateSDSLOp(context, grammarData); GenerateStructs(context, grammarData); diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 2798e4fb65..7e5adde62c 100644 --- a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -17,6 +17,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index ac5d9dd418..2903b13d7a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; @@ -113,7 +114,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, paramExpectedValueType = pointerType.BaseType; paramSource = builder.Convert(context, paramSource, paramExpectedValueType); - builder.Insert(new OpStore(paramVariable, paramSource.Id, null)); + builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); } compiledParams[i] = paramVariable; @@ -142,7 +143,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var paramVariable = context.Bound++; builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); - builder.Insert(new OpStore(paramVariable, source, null)); + builder.Insert(new OpStore(paramVariable, source, null, [])); compiledParams[parameters.Values.Count + i] = paramVariable; } @@ -188,8 +189,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (paramTargetType.BaseType != paramDefinitionType.BaseType) throw new InvalidOperationException($"Value of type {paramTargetType.BaseType} can't be used as out parameter {i} of type {paramDefinitionType.BaseType} in method call [{this}]"); - var loadedResult = builder.Insert(new OpLoad(context.GetOrRegister(paramTargetType.BaseType), context.Bound++, paramVariable, null)).ResultId; - builder.Insert(new OpStore(paramTarget.Id, loadedResult, null)); + var loadedResult = builder.Insert(new OpLoad(context.GetOrRegister(paramTargetType.BaseType), context.Bound++, paramVariable, null, [])).ResultId; + builder.Insert(new OpStore(paramTarget.Id, loadedResult, null, [])); } } @@ -291,7 +292,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, }, constant1); // We store the modified value back in the variable - builder.Insert(new OpStore(expression.Id, result.Id, null)); + builder.Insert(new OpStore(expression.Id, result.Id, null, [])); Type = type; return expression; @@ -458,15 +459,17 @@ void EmitOpAccessChain(Span accessChainIds) var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - ParameterizedFlag? flags = null; + ImageOperandsMask? imask = null; + EnumerantParameters imParams = []; if (implicitSampling.Parameters.Values.Count > 2) { var offset = implicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); // TODO: determine when ConstOffset - flags = new ParameterizedFlag(ImageOperandsMask.Offset, [offset.Id]); + imask = ImageOperandsMask.Offset; + imParams = new EnumerantParameters(offset.Id); } - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, flags)); + var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; @@ -485,20 +488,24 @@ void EmitOpAccessChain(Span accessChainIds) var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - - ParameterizedFlag flags; + + ImageOperandsMask imask = ImageOperandsMask.None; + EnumerantParameters imParams = []; + if (explicitSampling.Parameters.Values.Count > 3) { var offset = explicitSampling.Parameters.Values[3].CompileAsValue(table, compiler); offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); // TODO: determine when ConstOffset - flags = new ParameterizedFlag(ImageOperandsMask.Lod | ImageOperandsMask.Offset, [levelValue.Id, offset.Id]); + imask = ImageOperandsMask.Lod | ImageOperandsMask.Offset; + imParams = new EnumerantParameters(levelValue.Id, offset.Id); } else { - flags = new ParameterizedFlag(ImageOperandsMask.Lod, [levelValue.Id]); + imask = ImageOperandsMask.Lod; + imParams = new EnumerantParameters(levelValue.Id); } - var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, flags)); + var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; @@ -519,21 +526,24 @@ void EmitOpAccessChain(Span accessChainIds) var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? ParameterizedFlags.ImageOperandsLod(context.CompileConstant(0.0f).Id) - : ImageOperandsMask.None; + + ImageOperandsMask flags = sampleCompare.Name.Name is "SampleCmpLevelZero" ? ImageOperandsMask.Lod : ImageOperandsMask.None; + EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new () : new (context.CompileConstant(0.0f).Id); + //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" if (sampleCompare.Parameters.Values.Count > 3) { var offset = sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler); offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); // TODO: determine when ConstOffset - flags = new ParameterizedFlag(flags.Value | ImageOperandsMask.Offset, [..flags.Span, offset.Id]); + flags |= ImageOperandsMask.Offset; + imParams = new EnumerantParameters([..imParams, offset.Id]); + //flags = new ParameterizedFlag(flags | ImageOperandsMask.Offset, new(..imParams.Span, offset.Id]); } var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags)) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags)); + ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)) + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)); result = new(sample.IdResult!.Value, sample.IdResultType!.Value); accessor.Type = resultType; @@ -556,7 +566,7 @@ void EmitOpAccessChain(Span accessChainIds) var resource = builder.AsValue(context, result); var returnType = context.GetOrRegister(resultType); var coords = load.Parameters.Values[0].CompileAsValue(table, compiler); - var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null)); + var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null, [])); result = new(loadResult.ResultId, loadResult.ResultType); accessor.Type = resultType; break; @@ -716,7 +726,7 @@ void EmitOpAccessChain(Span accessChainIds) }, constant1); // We store the modified value back in the variable - builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null)); + builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null, [])); break; } @@ -850,17 +860,17 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, // Block when choosing left value builder.CreateBlock(context, blockTrueId, $"ternary_true"); builder.Merge(leftValueBuffer); - builder.Insert(new OpStore(resultVariable, leftResult.Id, null)); + builder.Insert(new OpStore(resultVariable, leftResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); // Block when choosing right value builder.CreateBlock(context, blockFalseId, $"ternary_false"); builder.Merge(rightValueBuffer); - builder.Insert(new OpStore(resultVariable, rightResult.Id, null)); + builder.Insert(new OpStore(resultVariable, rightResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); builder.CreateBlock(context, blockMergeId, "ternary_merge"); - var result = builder.Insert(new OpLoad(context.GetOrRegister(resultType), context.Bound++, resultVariable, null)); + var result = builder.Insert(new OpLoad(context.GetOrRegister(resultType), context.Bound++, resultVariable, null, [])); return new(result.ResultId, result.ResultType); } else diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 383ba433e5..8365d608b6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -91,7 +91,7 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpDecorate) { var decorateInstruction = new OpDecorate(instruction); - if (decorateInstruction.Decoration.Value == Decoration.Block) + if (decorateInstruction.Decoration == Decoration.Block) blocks.Add(decorateInstruction.Target); } else if (instruction.Op == Op.OpTypeFloat) @@ -306,11 +306,11 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte } else if (i.Op == Op.OpDecorate && (OpDecorate)i is { - Decoration: { Value: Decoration.FunctionParameterDefaultValueSDSL }, + Decoration: Decoration.FunctionParameterDefaultValueSDSL, Target: var target, } decorateFunctionParameters) { - methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.Decoration.Span.ToArray())); + methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.DecorationParameters.Span.ToArray())); } } for (var index = 0; index < shaderBuffers.Buffer.Count; index++) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 11c236685c..6214ae219d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -54,55 +54,55 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler case "Filter": { var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateFilter(filter))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateFilter, [(int)filter])); break; } case "AddressU": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressU(addressMode))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressU, [(int)addressMode])); break; } case "AddressV": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressV(addressMode))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressV, [(int)addressMode])); break; } case "AddressW": { var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateAddressW(addressMode))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressW, [(int)addressMode])); break; } case "MipLODBias": { var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMipLODBias(mipLODBias.ToString()))); + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMipLODBias, mipLODBias.ToString())); break; } case "MaxAnisotropy": { var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateMaxAnisotropy(maxAnisotropy))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateMaxAnisotropy, [maxAnisotropy])); break; } case "MinLOD": { var minLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMinLOD(minLOD.ToString()))); + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMinLOD, minLOD.ToString())); break; } case "MaxLOD": { var maxLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationSamplerStateMaxLOD(maxLOD.ToString()))); + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMaxLOD, maxLOD.ToString())); break; } case "ComparisonFunc": { var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationSamplerStateComparisonFunc(filter))); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateComparisonFunc, [(int)filter])); break; } case "BorderColor": @@ -203,7 +203,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler builder.Insert(new OpVariableSDSL(registeredType, variable, pointerType.StorageClass, variableFlags, initializerMethod)); if (Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(Semantic.Name))); + context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); @@ -325,9 +325,7 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (firstDefaultParameter != -1) { - context.Add(new OpDecorate(function.Id, new ParameterizedFlag( - Specification.Decoration.FunctionParameterDefaultValueSDSL, - defaultParameters.Slice(firstDefaultParameter)))); + context.Add(new OpDecorate(function.Id, Specification.Decoration.FunctionParameterDefaultValueSDSL, [.. defaultParameters[firstDefaultParameter..]])); symbol.MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index d233de2032..42c2f89730 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -312,7 +312,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile context.AddName(variable, Name); if (LogicalGroup != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationLogicalGroupSDSL(LogicalGroup))); + context.Add(new OpDecorateString(variable, Specification.Decoration.LogicalGroupSDSL, LogicalGroup)); bool? isStaged = null; @@ -331,9 +331,9 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile { var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); if (linkInfo.LinkId is int linkId) - context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, Specification.Decoration.LinkIdSDSL, [linkId])); else if (linkInfo.LinkName != null) - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName))); + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, Specification.Decoration.LinkSDSL, linkInfo.LinkName)); } } @@ -372,12 +372,12 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); - context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationResourceGroupSDSL(Name))); + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.ResourceGroupSDSL, Name)); // We also store an ID because multiple rgroup might have the same name, // but we still want to know which one was in the same "block" when we try to optimize them (we can only optimize a resource if all the resource in the same rgroup block can be optimized) - context.Add(new OpDecorate(variable.ResultId, ParameterizedFlags.DecorationResourceGroupIdSDSL(resourceGroupId))); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.ResourceGroupIdSDSL, [resourceGroupId])); if (LogicalGroup != null) - context.Add(new OpDecorateString(variable.ResultId, ParameterizedFlags.DecorationLogicalGroupSDSL(LogicalGroup))); + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.LogicalGroupSDSL, LogicalGroup)); var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, variable.ResultId); @@ -389,9 +389,9 @@ internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass sha { var linkInfo = CBuffer.ProcessLinkAttributes(table, info, attributes); if (linkInfo.LinkId is int linkId) - context.Add(new OpDecorate(variableId, ParameterizedFlags.DecorationLinkIdSDSL(linkId))); + context.Add(new OpDecorate(variableId, Specification.Decoration.LinkIdSDSL, [linkId])); else if (linkInfo.LinkName != null) - context.Add(new OpDecorateString(variableId, ParameterizedFlags.DecorationLinkSDSL(linkInfo.LinkName))); + context.Add(new OpDecorateString(variableId, Specification.Decoration.LinkSDSL, linkInfo.LinkName)); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 319c0a6fe2..551c65aa86 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -140,7 +140,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) if (Condition.ValueType != ScalarType.From("bool")) table.Errors.Add(new(Condition.Info, "not a boolean")); - builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None)); + builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None, [])); builder.Insert(new OpBranchConditional(conditionValue.Id, forBodyBlock, currentEscapeBlocks.MergeBlock, [])); // Body block diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index eabd24722e..9f7629fca4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -194,7 +194,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) // Make sure type is correct source = builder.Convert(context, source, variableValueType); - builder.Insert(new OpStore(variable, source.Id, null)); + builder.Insert(new OpStore(variable, source.Id, null, [])); } } } @@ -247,7 +247,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) if (target.Swizzles != null) { var valueType = context.Types[p.BaseType]; - var loadId = builder.Insert(new OpLoad(valueType, context.Bound++, target.Id, null)).ResultId; + var loadId = builder.Insert(new OpLoad(valueType, context.Bound++, target.Id, null, [])).ResultId; // Shuffle with new data switch (p.BaseType) { @@ -265,7 +265,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) throw new NotImplementedException(); } } - builder.Insert(new OpStore(target.Id, source.Id, null)); + builder.Insert(new OpStore(target.Id, source.Id, null, [])); } } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 41b63c7058..645f52494a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -419,25 +419,15 @@ private static void TransformResolvedSemantics(SpirvContext context, Dictionary< { foreach (var i in context) { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m } } decorate) + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.UserSemantic, Value: string m } decorate) { - var n = new LiteralValue(m.Span); - if (semantics.TryGetValue(n.Value, out var newSemantic)) - { - n.Value = newSemantic; - decorate.Decoration = new(decorate.Decoration.Value, n.Words); - } - n.Dispose(); + if (semantics.TryGetValue(m, out var newSemantic)) + decorate.Value = newSemantic; } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: { Value: Decoration.UserSemantic, Parameters: { } m2 } } decorate2) + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: Decoration.UserSemantic, Value : string m2 } decorate2) { - var n = new LiteralValue(m2.Span); - if (semantics.TryGetValue(n.Value, out var newSemantic)) - { - n.Value = newSemantic; - decorate2.Decoration = new(decorate2.Decoration.Value, n.Words); - } - n.Dispose(); + if (semantics.TryGetValue(m2, out var newSemantic)) + decorate2.Value = newSemantic; } } } @@ -508,20 +498,20 @@ private static void TransformResolvedLinkIdIntoLinkString(SpirvContext context, for (var index = 0; index < context.Count; index++) { var i = context[index]; - if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m } } linkDecorate) + if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { Decoration: Decoration.LinkIdSDSL, DecorationParameters: { } m } linkDecorate) { - using var n = new LiteralValue(m.Span); - if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) + var n = m.To(); + if (resolvedLinks.TryGetValue(n.IdRef0, out var resolvedValue)) { - context.Replace(index, new OpDecorateString(linkDecorate.Target, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + context.Replace(index, new OpDecorateString(linkDecorate.Target, Decoration.LinkSDSL, resolvedValue)); } } - else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: { Value: Decoration.LinkIdSDSL, Parameters: { } m2 } } linkDecorate2) + else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: Decoration.LinkIdSDSL, DecorationParameters: { } m2 } linkDecorate2) { - using var n = new LiteralValue(m2.Span); - if (resolvedLinks.TryGetValue(n.Value, out var resolvedValue)) + var n = m2.To(); + if (resolvedLinks.TryGetValue(n.IdRef0, out var resolvedValue)) { - context.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, new ParameterizedFlag(Decoration.LinkSDSL, [.. resolvedValue.AsDisposableLiteralValue().Words]))); + context.Replace(index, new OpMemberDecorateString(linkDecorate2.StructureType, linkDecorate2.Member, Decoration.LinkSDSL, resolvedValue)); } } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 8bbf9ee7a9..e80b407936 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -16,7 +16,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) if (type is PointerType pointerType) { type = pointerType.BaseType; - var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null)); + var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null, [])); result = new(inst.ResultId, inst.ResultType) { Swizzles = result.Swizzles }; } diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index 467c0a01c3..16bc757fbd 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -154,7 +154,7 @@ public int DeclareCBuffer(ConstantBufferSymbol cb) { var result = DeclareStructuredType(cb); - Buffer.Add(new OpDecorate(result, Specification.Decoration.Block)); + Buffer.Add(new OpDecorate(result, Specification.Decoration.Block, [])); return result; } diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index b4c6b5c7da..93d48b8bf6 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -188,7 +188,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte if (streams.Any(x => x.Value.Output)) { var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis); - buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft)); + buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages @@ -482,16 +482,13 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) && ((OpDecorateString)i) is { Target: int t, - Decoration: - { - Value: Decoration.UserSemantic, - Parameters: { } m - } + Decoration: Decoration.UserSemantic, + Value: string m + } ) { - using var n = new LiteralValue(m.Span); - semanticTable[t] = n.Value; + semanticTable[t] = m; } } } @@ -557,50 +554,46 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) Dictionary resourceGroups = new(); foreach (var i in context) { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: { Value: Decoration.ResourceGroupIdSDSL, Parameters: { } m } } resourceGroupIdDecorate) + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) { - var n = new LiteralValue(m.Span); + var n = m.To(); if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) { - if (!resourceGroups.TryGetValue(n.Value, out var resourceGroup)) - resourceGroups.Add(n.Value, resourceGroup = new()); + if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) + resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); resourceGroup.Resources.Add(resourceInfo); resourceInfo.ResourceGroup = resourceGroup; } - n.Dispose(); } } // Process ResourceGroup and LogicalGroup decorations foreach (var i in context) { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.ResourceGroupSDSL, Parameters: { } m2 } } resourceGroupDecorate) + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) { if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) // Note: ResourceGroup should not be null if set && resourceInfo.ResourceGroup.Name == null) { - using var n = new LiteralValue(m2.Span); - resourceInfo.ResourceGroup.Name = n.Value; + resourceInfo.ResourceGroup.Name = m2; } } - else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: { Value: Decoration.LogicalGroupSDSL, Parameters: { } m3 } } logicalGroupDecorate) + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.LogicalGroupSDSL, Value: string m3 } logicalGroupDecorate) { if (resources.TryGetValue(logicalGroupDecorate.Target, out var resourceInfo) // Note: ResourceGroup should not be null if this decoration is set && resourceInfo.ResourceGroup.LogicalGroup == null) { - using var n = new LiteralValue(m3.Span); - resourceInfo.ResourceGroup.LogicalGroup = n.Value; + resourceInfo.ResourceGroup.LogicalGroup = m3; } else if (cbuffers.TryGetValue(logicalGroupDecorate.Target, out var cbufferInfo)) { - using var n = new LiteralValue(m3.Span); - cbufferInfo.LogicalGroup = n.Value; + cbufferInfo.LogicalGroup = m3; } } } @@ -641,14 +634,14 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) switch (stream.Semantic?.ToUpperInvariant()) { case "SV_POSITION" when executionModel is ExecutionModel.Geometry or ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation or ExecutionModel.Vertex: - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.Position))); + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.Position])); return true; case "SV_POSITION" when executionModel is ExecutionModel.Fragment: - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FragCoord))); + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FragCoord])); return true; case "SV_ISFRONTFACE": - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationBuiltIn(BuiltIn.FrontFacing))); - context.Add(new OpDecorate(variable, Decoration.Flat)); + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FrontFacing])); + context.Add(new OpDecorate(variable, Decoration.Flat, [])); return true; default: return false; @@ -672,9 +665,9 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) { if (stream.Value.InputLayoutLocation == null) stream.Value.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.InputLayoutLocation.Value))); + context.Add(new OpDecorate(variable, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); + context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } inputStreams.Add((stream.Value, variable.ResultId)); @@ -697,9 +690,9 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); } - context.Add(new OpDecorate(variable, ParameterizedFlags.DecorationLocation(stream.Value.OutputLayoutLocation.Value))); + context.Add(new OpDecorate(variable, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, ParameterizedFlags.DecorationUserSemantic(stream.Value.Semantic))); + context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } outputStreams.Add((stream.Value, variable.ResultId)); @@ -749,7 +742,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) var variableValueType = ((PointerType)variable.Value.Type).BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); - buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null)); + buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null, [])); } } @@ -758,8 +751,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) { var baseType = ((PointerType)stream.Info.Type).BaseType; buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null), out var loadedValue); - buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null)); + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null, []), out var loadedValue); + buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null, [])); } buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPointId, [])); @@ -769,8 +762,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) { var baseType = ((PointerType)stream.Info.Type).BaseType; buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null), out var loadedValue); - buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null)); + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, []), out var loadedValue); + buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); } From 6e51bd1a926967b2ded1c6006ca1828f2406fb4a Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 12 Jan 2026 17:14:07 +0100 Subject: [PATCH 0705/1182] Finished updating generator --- .../Parsing/OpDataEnumerator.cs | 33 +++++++++---------- src/Stride.Shaders.Spirv.Core/SpvLiteral.cs | 7 ++-- .../Spirv/Building/Builder.Class.cs | 1 + 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index b4892113d8..a18f4ee689 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -67,7 +67,7 @@ public bool FindOperandInfo(OperandParameters p, ParameterizedOperandKey key, ou } operands = operandsList.ToArray(); - + // Add to cache for next query p.Add(key, operands); return true; @@ -91,12 +91,10 @@ public bool MoveNext() var logOp = logicalOperands[oid]; (int newWid, int newOid, int newPid, startOperand) = logOp switch { - { Parameters: OperandParameters { Count: > 0 } p } - when pid == -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[wid]), out var operands) && operands.Length > 0 => + { Parameters: OperandParameters { Count: > 0 } p } when pid == -1 && p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && p[new(logOp.Kind ?? OperandKind.None, Operands[wid])].Length > 0 => (wid + 1, oid, 0, wid), - { Parameters: OperandParameters { Count: > 0 } p } - when startOperand != -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[startOperand]), out var operands) && pid < operands.Length => - operands[pid] switch + { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => + p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch { { Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } => (wid + 2, oid, pid + 1, startOperand), { Kind: OperandKind.LiteralString } => (wid + Operands[wid..].LengthOfString(), oid, pid + 1, startOperand), @@ -123,6 +121,7 @@ public bool MoveNext() // - no operands left // - current operand has no kind (i.e. None) return !(wid >= Operands.Length || oid >= logicalOperands.Count); + } } @@ -133,31 +132,31 @@ public SpvOperand ParseCurrent() return logOp switch { { Parameters: OperandParameters { Count: > 0 } } when pid == -1 => - new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1), wid, true), { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[startOperand])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch { - { Name: string n, Kind: OperandKind k } when k.ToString().StartsWith("Pair") => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), - { Name: string n, Kind: OperandKind.LiteralString } => new(n, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), - { Name: string n, Kind: OperandKind k } => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + { Name: string n, Kind: OperandKind k } when k.ToString().StartsWith("Pair") => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2), wid), + { Name: string n, Kind: OperandKind.LiteralString } => new(n, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString()), wid), + { Name: string n, Kind: OperandKind k } => new(n, k, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1), wid), _ => throw new NotImplementedException($"Couldn't handle operand kind {logOp.Kind}") }, { Quantifier: OperandQuantifier.One, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } l - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), - { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), - { Quantifier: OperandQuantifier.One, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1)), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2), wid), + { Quantifier: OperandQuantifier.One, Kind: OperandKind.LiteralString } => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString()), wid), + { Quantifier: OperandQuantifier.One, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 1), wid), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2)), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, 2), wid), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: OperandKind.LiteralString } - => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString())), + => new(logOp.Name, OperandKind.LiteralString, logOp.Quantifier ?? OperandQuantifier.One, Operands.Slice(wid, Operands[wid..].LengthOfString()), wid), { Quantifier: OperandQuantifier.ZeroOrOne, Kind: _ } => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands.Slice(wid, 1) : []), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : [], wid), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: OperandKind.LiteralString } => throw new Exception("params of strings is not yet implemented"), { Quantifier: OperandQuantifier.ZeroOrMore, Kind: _ } - => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : []), + => new(logOp.Name, logOp.Kind ?? OperandKind.None, logOp.Quantifier ?? OperandQuantifier.One, wid < Operands.Length ? Operands[wid..] : [], wid), _ => throw new NotImplementedException() }; diff --git a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs index e04fbfa3b8..23bd77311a 100644 --- a/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -13,22 +13,25 @@ public ref struct SpvOperand public OperandQuantifier Quantifier { get; init; } public Span Words { get; init; } public int Offset { get; init; } + public bool IsParameterizedEnumerant { get; init; } - public SpvOperand(OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0) + public SpvOperand(OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0, bool isParameterizedEnumerant = false) { Kind = kind; Quantifier = quantifier; Words = words; Offset = idRefOffset; + IsParameterizedEnumerant = isParameterizedEnumerant; } - public SpvOperand(string? name, OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0) + public SpvOperand(string? name, OperandKind kind, OperandQuantifier quantifier, Span words, int idRefOffset = 0, bool isParameterizedEnumerant = false) { Name = name; Kind = kind; Quantifier = quantifier; Words = words; Offset = idRefOffset; + IsParameterizedEnumerant = isParameterizedEnumerant; } public void ReplaceIdResult(int replacement) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 645f52494a..5712d974fa 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -508,6 +508,7 @@ private static void TransformResolvedLinkIdIntoLinkString(SpirvContext context, } else if (i.Op == Op.OpMemberDecorate && ((OpMemberDecorate)i) is { Decoration: Decoration.LinkIdSDSL, DecorationParameters: { } m2 } linkDecorate2) { + var tmp = new OpMemberDecorate(i); var n = m2.To(); if (resolvedLinks.TryGetValue(n.IdRef0, out var resolvedValue)) { From 675876f24fd4d5dd2b375476e5f643cbf73ce34c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 13 Jan 2026 21:40:58 +0900 Subject: [PATCH 0706/1182] Streams: fix variable access (they were replaced by streams global) --- assets/SDSL/RenderTests/StreamParameter.sdsl | 8 +++++--- .../Spirv/Processing/InterfaceProcessor.cs | 19 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/assets/SDSL/RenderTests/StreamParameter.sdsl b/assets/SDSL/RenderTests/StreamParameter.sdsl index d4f2deed1d..4a7a97de1c 100644 --- a/assets/SDSL/RenderTests/StreamParameter.sdsl +++ b/assets/SDSL/RenderTests/StreamParameter.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) +// PSMain(ExpectedResult=#807FFFFF, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; @@ -11,7 +11,7 @@ shader StreamParameter float4 Test(Streams streamsCopy) { - return streamsCopy.ExtraColor; + return float4(streamsCopy.ExtraColor.x, streams.ExtraColor.y, 1.0, 1.0); } void VSMain() @@ -22,6 +22,8 @@ shader StreamParameter void PSMain() { - streams.ColorTarget = Test(streams); + Streams streamsCopy = streams; + streamsCopy.ExtraColor += 1.0 / 255.0; + streams.ColorTarget = Test(streamsCopy); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 93d48b8bf6..390bc656d1 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -879,7 +879,8 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct (var methodStart, var methodEnd) = FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); var streams = analysisResult.Streams; - var streamsInstructionIds = new HashSet(); + // true => implicit (streams.), false => specific variable + var streamsInstructionIds = new Dictionary(); var method = (OpFunction)buffer[methodStart]; var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; @@ -902,7 +903,7 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) { - streamsInstructionIds.Add(streamsInstruction.ResultId); + streamsInstructionIds.Add(streamsInstruction.ResultId, true); remapIds.Add(streamsInstruction.ResultId, streamsVariableId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); } @@ -910,18 +911,18 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct { var type = context.ReverseTypes[variable.ResultType]; if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(variable.ResultId); + streamsInstructionIds.Add(variable.ResultId, false); } else if (i.Op is Op.OpFunctionParameter && (OpFunctionParameter)i is { } functionParameter) { var type = context.ReverseTypes[functionParameter.ResultType]; if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(functionParameter.ResultId); + streamsInstructionIds.Add(functionParameter.ResultId, false); } else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { // In case it's a streams access, patch acces to use STREAMS struct with proper index - if (streamsInstructionIds.Contains(accessChain.BaseId)) + if (streamsInstructionIds.TryGetValue(accessChain.BaseId, out var isImplicit)) { var streamVariableId = accessChain.Values.Elements.Span[0]; var streamInfo = streams[streamVariableId]; @@ -931,8 +932,12 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct // we'll need a better way to update LiteralArray and propagate changes accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; - // Force refresh of InstructionMemory - accessChain.BaseId = streamsVariableId; + if (isImplicit) + accessChain.BaseId = streamsVariableId; + else + // Force refresh of InstructionMemory + // TODO: remove when accessChain.Values update properly the instruction + accessChain.BaseId = accessChain.BaseId; } } else if (i.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } call) From 1e03683946e57bb321b59a18ecc6e862f7f068e0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 13 Jan 2026 21:44:38 +0900 Subject: [PATCH 0707/1182] ShaderSource evaluator: properly merge indirect stage inheritance with direct inheritance (even if it happens later) --- ...tionInheritanceStageIndirectAndDirect.sdsl | 48 +++++++++++ .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 79 ++++++++++++++----- 2 files changed, 107 insertions(+), 20 deletions(-) create mode 100644 assets/SDSL/RenderTests/CompositionInheritanceStageIndirectAndDirect.sdsl diff --git a/assets/SDSL/RenderTests/CompositionInheritanceStageIndirectAndDirect.sdsl b/assets/SDSL/RenderTests/CompositionInheritanceStageIndirectAndDirect.sdsl new file mode 100644 index 0000000000..bcef6f0fa8 --- /dev/null +++ b/assets/SDSL/RenderTests/CompositionInheritanceStageIndirectAndDirect.sdsl @@ -0,0 +1,48 @@ +// PSMain(ExpectedResult=#24242424, cbuffer.PerView=(Eye=7.0, Eye2=12.0)) + +namespace Stride.Shaders.Tests; + +// This class will be inherited twice by CompositionInheritanceStageIndirectAndDirect +// - first through ShadingColor0 (but it will be stage-only inheritance) +// - then from ExternalClass being in the inheritance list (full inheritance) +// This test makes sure the full inheritance override the stage-only inheritance, while still happening early enough +shader ExternalClass +{ + cbuffer PerView + { + stage float Eye; + }; +} + +shader CompositionBase +{ + float4 Compute() + { + return float4(10.0, 10.0, 10.0, 10.0) / 255.0 + ExternalClass.Eye / 255.0; + } +}; + +shader CompositionExternalBase +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer PerView + { + stage float Eye2; + }; + + compose CompositionBase ShadingColor0; +}; + +shader CompositionInheritanceStageIndirectAndDirect : CompositionExternalBase, ExternalClass +{ + stage float4 Shading() + { + return ShadingColor0.Compute() + Eye2 / 255.0 + Eye / 255.0; + } + + void PSMain() + { + streams.ColorTarget = Shading(); + } +}; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 2f7ac11266..4b6715f3e5 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -18,9 +18,8 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext context, ShaderSource shaderSource, ShaderMixinInstantiation? root = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext context, ShaderSource shaderSource, Action? addToRoot = null) { - bool isRoot = root == null; var mixinList = new List(); var shaderMixinSource = shaderSource switch @@ -29,6 +28,9 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, }; + var compositions = new Dictionary(); + var result = new ShaderMixinInstantiation(new(), compositions); + foreach (var mixinToMerge in shaderMixinSource.Mixins) { var shaderBuffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); @@ -44,14 +46,59 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext break; } } + SpirvBuilder.BuildInheritanceListIncludingSelf(ShaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } + + ProcessClasses(context, mixinList, shaderMixinSource, result, compositions, addToRoot); - var compositions = new Dictionary(); - var result = new ShaderMixinInstantiation(new(), compositions); + return result; + } + + private void ProcessClasses(SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null) + { + int shaderIndex = 0; + + var addToRootRecursive = addToRoot; + if (addToRootRecursive == null) + { + addToRootRecursive = shaderName => + { + var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; + + + // Make sure it's not already added yet (either standard or stage only) + if (!result.Mixins.Contains(shaderName) && !result!.Mixins.Contains(shaderNameStageOnly)) + { + // Check if mixin will be added in future as a non-stage + if (mixinList.Contains(shaderName)) + { + // Special case: the current stage-only mixin is planned to be added later as a normal mixin at the root level + // It's a bit complex: we need to inherit from it right now instead of later + // (if we simply do a result.Mixins.Add as in normal case, the shader would be added twice) + var currentlyMixedList = mixinList[0..shaderIndex]; + SpirvBuilder.BuildInheritanceListIncludingSelf(ShaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); - foreach (var shaderName in mixinList.ToArray()) + var newShadersToMergeNow = currentlyMixedList[shaderIndex..]; + mixinList.InsertRange(shaderIndex, newShadersToMergeNow); + + // Note: we're not removing duplicates as we do an extra duplicate check at the beginning of the mixinList loop + } + else + { + result.Mixins.Add(shaderNameStageOnly); + } + } + }; + } + + for (; shaderIndex < mixinList.Count; shaderIndex++) { + var shaderName = mixinList[shaderIndex]; + // Note: this should only happen due to addToRootRecursive readding some mixin earlier + if (result.Mixins.Contains(shaderName)) + continue; + var shader = shaderName.Buffer.Value; bool hasStage = false; foreach (var i in shader.Context) @@ -61,6 +108,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext hasStage = true; } } + foreach (var i in shader.Buffer) { if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) @@ -87,40 +135,31 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext { var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(context, value, root ?? result)); + variableCompositions.Add(EvaluateInheritanceAndCompositions(context, value, addToRootRecursive)); compositions[variableName] = [..variableCompositions]; } else { - var variableComposition = EvaluateInheritanceAndCompositions(context, compositionMixin, root ?? result); + var variableComposition = EvaluateInheritanceAndCompositions(context, compositionMixin, addToRootRecursive); compositions[variableName] = [variableComposition]; } } } - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is {} functionInfo) + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } functionInfo) { hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; } } // If there are any stage variables, add class to root - if (!isRoot && hasStage) - { - var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; - // Make sure it's not already added yet (either standard or stage only) - if (!root!.Mixins.Contains(shaderName) && !root!.Mixins.Contains(shaderNameStageOnly)) - { - root!.Mixins.Add(shaderNameStageOnly); - } - } - + if (hasStage) + addToRoot?.Invoke(shaderName); + // Note: make sure to add only *after* compositions EvaluateInheritanceAndCompositions recursive call is done (a composition might add a "stage" inheritance with root!.Mixins.Add() // and this should be done before the composition mixin is added. // For example, a composition might import a struct, so if we import and mix the composition mixin before the "stage" one defining the struct, the struct is not defined before the composition using it. result.Mixins.Add(shaderName); } - - return result; } } \ No newline at end of file From 35d15a21c8d72afcbec61f3bd087c6fbd40378c0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 13 Jan 2026 21:47:58 +0900 Subject: [PATCH 0708/1182] Added support for SV_Depth --- src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 390bc656d1..89aa8e042b 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -633,6 +633,9 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) { switch (stream.Semantic?.ToUpperInvariant()) { + case "SV_DEPTH" when executionModel is ExecutionModel.Fragment: + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FragDepth])); + return true; case "SV_POSITION" when executionModel is ExecutionModel.Geometry or ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation or ExecutionModel.Vertex: context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.Position])); return true; From 11ab3c51f82170f9522156a91812afbbfb2dde3e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 13 Jan 2026 23:54:45 +0900 Subject: [PATCH 0709/1182] Generate GLSLOp and simplified similar intrinsics --- .../SPVGenerator.Instructions.cs | 2 +- .../SPVGenerator.SDSLOp.cs | 51 +-- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 322 ++---------------- .../PrimaryExpressionParsers.cs | 47 +-- 4 files changed, 60 insertions(+), 362 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 0da90dce54..7913d338bc 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -238,7 +238,7 @@ public static string ToSpreadOperators(InstructionData instruction, SpirvGrammar sb.Append(ToSpreadOperator(operand)); var (_, fieldname, _) = ToTypeFieldAndOperandName(operand); if (fieldname == "Set") - sb.Append($", {instruction.OpCode}"); + sb.Append($", (int)GLSLOp.{instruction.OpName}"); } } else diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 619c85550a..971171b953 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -25,7 +25,7 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr var instructionsProvider = grammarProvider .SelectMany(static (grammar, b) => grammar.Instructions?.AsList() ?? []) - .Where(static x => x.OpName is not null && !x.OpName.Contains("GLSL")) + .Where(static x => x.OpName is not null) .Collect() .Select(static (arr, _) => new EquatableList([.. arr])); @@ -38,19 +38,24 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList instructionArray) { + var members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; + int lastnum = members.Values.Max(); + var code = new StringBuilder(); code .AppendLine("using static Stride.Shaders.Spirv.Specification;") .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("namespace Stride.Shaders.Spirv;") .AppendLine("") - .AppendLine("public enum SDSLOp : int") + .AppendLine("public static partial class Specification") + .AppendLine("{") + .AppendLine("public enum Op : int") .AppendLine("{"); - Dictionary members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; - int lastnum = members.Values.Max(); foreach (var instruction in instructionArray!) { + if (instruction.OpName.Contains("GLSL")) + continue; if (members.TryGetValue(instruction.OpName, out var value)) { if (instruction.OpName.Contains("SDSL") && value <= 0) @@ -63,45 +68,19 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList(ref TScanner scanner, ParseResult result, ou { ("abort", _) => throw new NotImplementedException(), ("abs", 1) => new AbsCall(parameters, scanner[position..scanner.Position]), - ("acos", 1) => new AcosCall(parameters, scanner[position..scanner.Position]), + ("acos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAcos), ("all", _) => throw new NotImplementedException(), ("AllMemoryBarrier", _) => throw new NotImplementedException(), ("AllMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), ("any", _) => throw new NotImplementedException(), ("asdouble", _) => throw new NotImplementedException(), ("asfloat", _) => throw new NotImplementedException(), - ("asin", 1) => new AsinCall(parameters, scanner[position..scanner.Position]), + ("asin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAsin), ("asint", _) => throw new NotImplementedException(), ("asuint", _) => throw new NotImplementedException(), - ("atan", 1) => new AtanCall(parameters, scanner[position..scanner.Position]), - ("atan2", 2) => new Atan2Call(parameters, scanner[position..scanner.Position]), - ("ceil", 1) => new CeilCall(parameters, scanner[position..scanner.Position]), + ("atan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan), + ("atan2", 2) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), + ("ceil", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCeil), ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), ("clamp", _) => new ClampCall(parameters, scanner[position..scanner.Position]), ("clip", _) => throw new NotImplementedException(), - ("cos", 1) => new CosCall(parameters, scanner[position..scanner.Position]), - ("cosh", 1) => new CoshCall(parameters, scanner[position..scanner.Position]), + ("cos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCos), + ("cosh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCosh), ("countbits", _) => throw new NotImplementedException(), ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), @@ -82,7 +83,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("ddy", _) => throw new NotImplementedException(), ("ddy_coarse", _) => throw new NotImplementedException(), ("ddy_fine", _) => throw new NotImplementedException(), - ("degrees", 1) => new DegreesCall(parameters, scanner[position..scanner.Position]), + ("degrees", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLDegrees), ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), @@ -93,14 +94,14 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), ("EvaluateAttributeAtSample", _) => throw new NotImplementedException(), ("EvaluateAttributeSnapped", _) => throw new NotImplementedException(), - ("exp", 1) => new ExpCall(parameters, scanner[position..scanner.Position]), - ("exp2", 1) => new Exp2Call(parameters, scanner[position..scanner.Position]), + ("exp", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp), + ("exp2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp2), ("f16to32", _) => throw new NotImplementedException(), ("f32to16", _) => throw new NotImplementedException(), ("faceforward", _) => throw new NotImplementedException(), ("firstbithigh", _) => throw new NotImplementedException(), ("firstbitlow", _) => throw new NotImplementedException(), - ("floor", 1) => new FloorCall(parameters, scanner[position..scanner.Position]), + ("floor", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFloor), ("fma", _) => throw new NotImplementedException(), ("fmod", _) => throw new NotImplementedException(), ("frac", _) => throw new NotImplementedException(), @@ -126,9 +127,9 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), ("lit", _) => throw new NotImplementedException(), - ("log", 1) => new LogCall(parameters, scanner[position..scanner.Position]), - ("log10", _) => throw new NotImplementedException(), - ("log2", 1) => new Log2Call(parameters, scanner[position..scanner.Position]), + ("log", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog), + ("log10", _) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2, (float)Math.Log10(2.0)), + ("log2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2), ("mad", _) => throw new NotImplementedException(), ("max", _) => new MaxCall(parameters, scanner[position..scanner.Position]), ("min", _) => new MinCall(parameters, scanner[position..scanner.Position]), @@ -149,29 +150,29 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("ProcessTriTessFactorsAvg", _) => throw new NotImplementedException(), ("ProcessTriTessFactorsMax", _) => throw new NotImplementedException(), ("ProcessTriTessFactorsMin", _) => throw new NotImplementedException(), - ("radians", 1) => new RadiansCall(parameters, scanner[position..scanner.Position]), + ("radians", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRadians), ("rcp", _) => throw new NotImplementedException(), ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), ("reversebits", _) => throw new NotImplementedException(), - ("round", 1) => new RoundEvenCall(parameters, scanner[position..scanner.Position]), - ("rsqrt", 1) => new InverseSqrtCall(parameters, scanner[position..scanner.Position]), + ("round", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRoundEven), + ("rsqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLInverseSqrt), ("saturate", 1) => new SaturateCall(parameters, scanner[position..scanner.Position]), ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), - ("sin", 1) => new SinCall(parameters, scanner[position..scanner.Position]), + ("sin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSin), ("sincos", _) => throw new NotImplementedException(), - ("sinh", 1) => new SinhCall(parameters, scanner[position..scanner.Position]), + ("sinh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSinh), ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), - ("sqrt", 1) => new SqrtCall(parameters, scanner[position..scanner.Position]), + ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), ("step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), - ("tan", 1) => new TanCall(parameters, scanner[position..scanner.Position]), - ("tanh", 1) => new TanhCall(parameters, scanner[position..scanner.Position]), + ("tan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTan), + ("tanh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTanh), ("tex1D" or "tex1Dbias" or "tex1Dgrad" or "tex1Dlod" or "tex1Dproj", _) => throw new NotImplementedException(), ("tex2D" or "tex2Dbias" or "tex2Dgrad" or "tex2Dlod" or "tex2Dproj", _) => throw new NotImplementedException(), ("tex3D" or "tex3Dbias" or "tex3Dgrad" or "tex3Dlod" or "tex3Dproj", _) => throw new NotImplementedException(), ("texCUBE" or "texCUBEbias" or "texCUBEgrad" or "texCUBElod" or "texCUBEproj", _) => throw new NotImplementedException(), ("transpose", _) => throw new NotImplementedException(), - ("trunc", 1) => new TruncCall(parameters, scanner[position..scanner.Position]), + ("trunc", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTrunc), _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]), }; /*parsed = (identifier.Name, parameters.Values.Count) switch From 9123d88395099bc5c3de5ed783b5117df88ef4f2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 13 Jan 2026 23:55:06 +0900 Subject: [PATCH 0710/1182] Reapply changes for OperandKind.ImageOperands --- .../RenderTests/TextureSampleLevelOffset.sdsl | 17 +++++++++++++++++ .../Parsing/OpDataEnumerator.cs | 8 +++++--- 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl diff --git a/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl b/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl new file mode 100644 index 0000000000..f1decbc6bd --- /dev/null +++ b/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl @@ -0,0 +1,17 @@ +// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD) + +namespace Stride.Shaders.Tests; + +shader TextureSampleLevelOffset +{ + stream float4 ColorTarget : SV_Target0; + stream float2 TexCoord : TEXCOORD; + + stage Texture2D Texture1; + stage SamplerState Sampler1; + + void PSMain() + { + streams.ColorTarget = Texture1.SampleLevel(Sampler1, streams.TexCoord, 0.0, int2(3, 2)).yxwz; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index a18f4ee689..cc428a39d3 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -91,10 +91,12 @@ public bool MoveNext() var logOp = logicalOperands[oid]; (int newWid, int newOid, int newPid, startOperand) = logOp switch { - { Parameters: OperandParameters { Count: > 0 } p } when pid == -1 && p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && p[new(logOp.Kind ?? OperandKind.None, Operands[wid])].Length > 0 => + { Parameters: OperandParameters { Count: > 0 } p } + when pid == -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[wid]), out var operands) && operands.Length > 0 => (wid + 1, oid, 0, wid), - { Parameters: OperandParameters { Count: > 0 } p } when p.ContainsKey(new(logOp.Kind ?? OperandKind.None, Operands[wid])) && pid < p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])].Length => - p[new(logOp.Kind ?? OperandKind.None, Operands[startOperand])][pid] switch + { Parameters: OperandParameters { Count: > 0 } p } + when startOperand != -1 && FindOperandInfo(p, new(logOp.Kind ?? OperandKind.None, Operands[startOperand]), out var operands) && pid < operands.Length => + operands[pid] switch { { Kind: OperandKind.PairIdRefIdRef or OperandKind.PairIdRefLiteralInteger or OperandKind.PairLiteralIntegerIdRef } => (wid + 2, oid, pid + 1, startOperand), { Kind: OperandKind.LiteralString } => (wid + Operands[wid..].LengthOfString(), oid, pid + 1, startOperand), From 8b38605ab0389916ea04fe70fe7ed7fa9aea0831 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 10:44:58 +0900 Subject: [PATCH 0711/1182] Improved System Value semantic system --- src/Stride.Shaders.Tests/RenderingTests.cs | 2 +- .../Spirv/Processing/InterfaceProcessor.cs | 77 ++++++++++++++----- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 7622bd9ccc..bf5d89c21d 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -71,7 +71,7 @@ public void RenderTest1(string shaderName) shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); File.WriteAllBytes($"{shaderName}.spv", bytecode); - File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 89aa8e042b..82d180ee71 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -20,6 +20,12 @@ public class InterfaceProcessor public CodeInsertedDelegate CodeInserted { get; set; } + enum StreamVariableType + { + Input, + Output, + } + class StreamInfo(string? semantic, string name, SymbolType type, int variableId) { public string? Semantic { get; } = semantic; @@ -187,7 +193,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis); + var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); } @@ -223,7 +229,7 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte stream.Value.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis); + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); } // This will remove a lot of unused methods, resources and variables @@ -601,7 +607,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); } - private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; @@ -629,23 +635,50 @@ private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, E } } - bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) + bool AddBuiltin(int variable, BuiltIn builtin) + { + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)builtin])); + return true; + } + + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo stream) { switch (stream.Semantic?.ToUpperInvariant()) { - case "SV_DEPTH" when executionModel is ExecutionModel.Fragment: - context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FragDepth])); - return true; - case "SV_POSITION" when executionModel is ExecutionModel.Geometry or ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation or ExecutionModel.Vertex: - context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.Position])); - return true; - case "SV_POSITION" when executionModel is ExecutionModel.Fragment: - context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FragCoord])); - return true; - case "SV_ISFRONTFACE": - context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)BuiltIn.FrontFacing])); - context.Add(new OpDecorate(variable, Decoration.Flat, [])); - return true; + case "SV_DEPTH": + if (executionModel is ExecutionModel.Fragment && type == StreamVariableType.Output) + return AddBuiltin(variable, BuiltIn.FragDepth); + return false; + case {} semantic when semantic.StartsWith("SV_TARGET"): + if (executionModel is ExecutionModel.Fragment && type == StreamVariableType.Output) + { + // If it fails, default is 0 + int.TryParse(semantic.Substring("SV_TARGET".Length), out var targetIndex); + context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); + return true; + } + return false; + case "SV_POSITION": + if (isFirstActiveShader && type == StreamVariableType.Output) + return AddBuiltin(variable, BuiltIn.Position); + if (executionModel == ExecutionModel.Fragment && type == StreamVariableType.Input) + return AddBuiltin(variable, BuiltIn.FragCoord); + return false; + // TODO: Check if first stage + case "SV_INSTANCEID": + if (isFirstActiveShader && type == StreamVariableType.Input) + return AddBuiltin(variable, BuiltIn.InstanceIndex); + return false; + case "SV_VERTEXID" when isFirstActiveShader: + if (isFirstActiveShader && type == StreamVariableType.Input) + return AddBuiltin(variable, BuiltIn.VertexIndex); + return false; + case "SV_ISFRONTFACE" when isFirstActiveShader: + if (isFirstActiveShader && type == StreamVariableType.Input) + return AddBuiltin(variable, BuiltIn.FrontFacing); + return false; + case {} semantic when semantic.StartsWith("SV_"): + throw new NotImplementedException($"System-value Semantic not implemented: {semantic}"); default: return false; } @@ -664,7 +697,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - if (!ProcessBuiltinsDecoration(variable.ResultId, stream.Value)) + if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Input, stream.Value)) { if (stream.Value.InputLayoutLocation == null) stream.Value.InputLayoutLocation = inputLayoutLocationCount++; @@ -672,6 +705,9 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) if (stream.Value.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } + + if (!baseType.GetElementType().IsFloating()) + context.Add(new OpDecorate(variable, Decoration.Flat, [])); inputStreams.Add((stream.Value, variable.ResultId)); } @@ -682,7 +718,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - if (!ProcessBuiltinsDecoration(variable.ResultId, stream.Value)) + if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Output, stream.Value)) { // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic if (stream.Value.OutputLayoutLocation == null) @@ -697,6 +733,9 @@ bool ProcessBuiltinsDecoration(int variable, StreamInfo stream) if (stream.Value.Semantic != null) context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } + + if (!baseType.GetElementType().IsFloating()) + context.Add(new OpDecorate(variable, Decoration.Flat, [])); outputStreams.Add((stream.Value, variable.ResultId)); } From dd09f887a7f110e7567dd9dd965552bf929cfb9a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 11:07:55 +0900 Subject: [PATCH 0712/1182] Allow constants to be referenced between shaders --- .../RenderTests/ConstantTypeConversion.sdsl | 19 +++++++++ .../SDSL/RenderTests/GenericsArraySize2.sdsl | 28 +++++++++++++ .../Extensions/spirv.sdsl.grammar-ext.json | 7 +++- .../Stride.Shaders.Parsing.Tests.csproj | 3 ++ src/Stride.Shaders/Core/Symbol.cs | 4 +- .../Parsing/SDSL/AST/Literals.cs | 14 ++++++- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 39 ++++++++++++++++++- .../Spirv/Building/Context.Constants.cs | 9 ++++- src/Stride.Shaders/Spirv/Building/Context.cs | 27 +++++++++++++ 9 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 assets/SDSL/RenderTests/ConstantTypeConversion.sdsl create mode 100644 assets/SDSL/RenderTests/GenericsArraySize2.sdsl diff --git a/assets/SDSL/RenderTests/ConstantTypeConversion.sdsl b/assets/SDSL/RenderTests/ConstantTypeConversion.sdsl new file mode 100644 index 0000000000..e8969b3378 --- /dev/null +++ b/assets/SDSL/RenderTests/ConstantTypeConversion.sdsl @@ -0,0 +1,19 @@ +// PSMain(ExpectedResult=#04000010) + +namespace Stride.Shaders.Tests; + +shader ConstantTypeConversion +{ + stream float4 ColorTarget : SV_Target0; + + static const float T1 = 1.0; + // Note: we multiply with an integer on purpose (const can't convert type so proper type inference needs to happen) + static const float T2 = T1 * 4; + + static const float4 T3 = float4(T2, 0, 0, T2 * 4); + + void PSMain() + { + streams.ColorTarget = T3 / 255.0; + } +} \ No newline at end of file diff --git a/assets/SDSL/RenderTests/GenericsArraySize2.sdsl b/assets/SDSL/RenderTests/GenericsArraySize2.sdsl new file mode 100644 index 0000000000..20806c2b4a --- /dev/null +++ b/assets/SDSL/RenderTests/GenericsArraySize2.sdsl @@ -0,0 +1,28 @@ +// PSMain(ExpectedResult=#03050709, cbuffer.Test=(Test2=(3,5,7,9))) + +namespace Stride.Shaders.Tests; + +shader GenericsArrayBase2 +{ + static const int TArraySize = TArraySizeHalf2 + TArraySizeHalf2; + cbuffer Test + { + int Test2[TArraySize]; + } +} + +shader GenericsArrayBase : GenericsArrayBase2<1, 2, TArraySizeHalf> +{ + stream float4 ColorTarget : SV_Target0; + static const int TArraySize2 = TArraySize; + + void PSMain() + { + streams.ColorTarget = float4(Test2[0], Test2[1], Test2[2], Test2[3]) / 255.0; + } +} + +effect GenericsArraySize2 +{ + mixin GenericsArrayBase<2>; +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index e4a52f8bbc..dfc31f61f8 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -588,7 +588,12 @@ } ], "version": "1.0" - } + }, + { + "enumerant": "ShaderConstantSDSL", + "value": 8060, + "version": "1.0" + } ] }, { diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 7f9cb9f198..92fe7f60d3 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -8,6 +8,9 @@ false true True + + + true diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index a6cec31897..f635330b26 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -45,11 +45,13 @@ public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); public record struct MethodSymbolDefaultParameters(SpirvContext SourceContext, int[] DefaultValues); +public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId); + /// /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 989dbabfae..3f06106fa4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -326,7 +326,19 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, return result; } - if (symbol.MemberAccessWithImplicitThis is { } thisType) + if (symbol.ExternalConstant is { } externalConstant) + { + if (externalConstant.SourceContext != context) + { + var bufferForConstant = externalConstant.SourceContext.ExtractConstantAsSpirvBuffer(externalConstant.ConstantId); + result.Id = context.InsertWithoutDuplicates(null, bufferForConstant); + } + else + { + result.Id = externalConstant.ConstantId; + } + } + else if (symbol.MemberAccessWithImplicitThis is { } thisType) { if (constantOnly) throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 8365d608b6..a78633b5f5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -312,7 +312,20 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte { methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.DecorationParameters.Span.ToArray())); } + else if (i.Op == Op.OpDecorate && (OpDecorate)i is + { + Decoration: Decoration.ShaderConstantSDSL, + Target: var target2, + } decorateShaderConstant) + { + if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) + throw new InvalidOperationException(); + var resultType = typeInstruction.Data.IdResultType.Value; + var symbol = new Symbol(new(shaderBuffers.Context.Names[target2], SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2)); + variables.Add((symbol, VariableFlagsMask.None)); + } } + for (var index = 0; index < shaderBuffers.Buffer.Count; index++) { var instruction = shaderBuffers.Buffer[index]; @@ -499,8 +512,26 @@ public void Compile(SymbolTable table, CompilerUnit compiler) if (memberType is TextureType || memberType is BufferType) storageClass = Specification.StorageClass.UniformConstant; - svar.Type = new PointerType(memberType, storageClass); - table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + if (svar.TypeModifier == TypeModifier.Const) + { + if (svar.Value == null) + throw new InvalidOperationException($"Constant {svar.Name} doesn't have a value"); + + // Constant: compile right away + var constantValue = svar.Value.CompileConstantValue(table, context, memberType); + context.SetName(constantValue.Id, svar.Name); + var symbol = new Symbol(new(svar.Name, SymbolKind.Constant), memberType, constantValue.Id); + table.CurrentFrame.Add(svar.Name, symbol); + svar.Type = memberType; + + // This constant is visible when inherited + context.Add(new OpDecorate(constantValue.Id, Decoration.ShaderConstantSDSL, [])); + } + else + { + svar.Type = new PointerType(memberType, storageClass); + table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); + } } else if (member is CBuffer cb) { @@ -525,7 +556,11 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) + { + if (member.TypeModifier == TypeModifier.Const) + continue; member.Compile(table, this, compiler); + } foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index b782e62e75..f8e727c84d 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -91,13 +91,20 @@ public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, switch (op) { case Specification.Op.OpIMul: + case Specification.Op.OpIAdd: + case Specification.Op.OpISub: if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, out var leftTypeId)) return false; if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, out var rightTypeId)) return false; if (leftTypeId != resultType || rightTypeId != resultType) return false; - value = (int)left * (int)right; + value = op switch + { + Specification.Op.OpIMul => (int)left * (int)right, + Specification.Op.OpIAdd => (int)left + (int)right, + Specification.Op.OpISub => (int)left - (int)right, + }; if (simplifyInBuffer) Buffer.Replace(i.Index, new OpConstant(resultType, resultId, (int)value)); return true; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 1312433c08..d968d7ffb6 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -65,12 +65,39 @@ public void ImportGLSL() GLSLSet = Bound - 1; } + /// + /// Add a new name to a target ID. It should not have been set before. + /// + /// + /// public void AddName(int target, string name) { Buffer.Add(new OpName(target, name)); Names.Add(target, name); } + /// + /// Adds or updates a name to a target ID. + /// + /// + /// + public void SetName(int target, string name) + { + Names[target] = name; + + foreach (var i in Buffer) + { + if (i.Op == Op.OpName && (OpName)i is { } nameInstruction && nameInstruction.Target == target) + { + nameInstruction.Name = name; + return; + } + } + + // Not found, create new one + Buffer.Add(new OpName(target, name)); + } + public void AddMemberName(int target, int accessor, string name) => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); From 97f1010583629bc95abfadb69626c63b0046bbd0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 12:33:59 +0900 Subject: [PATCH 0713/1182] if/for/while: allow non-bool scalar for condition (using implicit conversion) --- .../Parsing/SDSL/AST/Statements.Control.cs | 12 +++++------- .../Parsing/SDSL/AST/Statements.Flow.cs | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index e4ab18de40..a5386388e7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -35,8 +35,11 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) blockMergeIds[i] = context.Bound++; var conditionValue = currentIf.Condition.CompileAsValue(table, compiler); - if (currentIf.Condition.ValueType != ScalarType.From("bool")) - table.Errors.Add(new(currentIf.Condition.Info, "not a boolean")); + if (currentIf.Condition.ValueType is not ScalarType) + table.Errors.Add(new(currentIf.Condition.Info, "if statement conditional expressions must evaluate to a scalar")); + + // Might need implicit conversion from float/int to bool + conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); int? falseBlock = (i + 1 < ElseIfs.Count + 1 || Else != null) ? context.Bound++ @@ -112,11 +115,6 @@ public class ElseIf(Expression condition, Statement body, TextLocation info) : I public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new InvalidOperationException("Handled by ConditionalFlow"); - Condition.CompileAsValue(table, compiler); - Body.Compile(table, compiler); - if (Condition.ValueType != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); - throw new NotImplementedException(); } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 551c65aa86..c296288b27 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -87,10 +87,16 @@ public class While(Expression condition, Statement body, TextLocation info, Shad public override void Compile(SymbolTable table, CompilerUnit compiler) { - Condition.CompileAsValue(table, compiler); + var (builder, context) = compiler; + + var conditionValue = Condition.CompileAsValue(table, compiler); + if (Condition.ValueType is not ScalarType) + table.Errors.Add(new(Condition.Info, "while statement condition expression must evaluate to a scalar")); + + // Might need implicit conversion from float/int to bool + conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); + Body.Compile(table, compiler); - if (Condition.ValueType != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); throw new NotImplementedException(); } @@ -137,8 +143,11 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) builder.CreateBlock(context, forCheckBlock, $"for_check_{builder.ForBlockCount}"); var conditionValue = Condition.CompileAsValue(table, compiler); - if (Condition.ValueType != ScalarType.From("bool")) - table.Errors.Add(new(Condition.Info, "not a boolean")); + if (Condition.ValueType is not ScalarType) + table.Errors.Add(new(Condition.Info, "for statement condition expression must evaluate to a scalar")); + + // Might need implicit conversion from float/int to bool + conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None, [])); builder.Insert(new OpBranchConditional(conditionValue.Id, forBodyBlock, currentEscapeBlocks.MergeBlock, [])); From 2e5daff3f48d883cd2db8af1f87665572afe0584 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 12:34:50 +0900 Subject: [PATCH 0714/1182] AccessorChainExpression: allow non-pointer array/vector/matrix types (i.e. constants) --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 12 ++++++++++++ src/Stride.Shaders/Spirv/Building/Builder.cs | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 2903b13d7a..6397ac129a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -704,6 +704,18 @@ void EmitOpAccessChain(Span accessChainIds) }, p.StorageClass); break; } + // For indexer accessor into non pointer types, we can't use OpCompositeExtract (it expects a constant) + // So we load the value into a variable and use normal path + case (ArrayType or VectorType or MatrixType, IndexerExpression indexer): + { + // We need to load as a variable to use OpAccessChain + accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); + var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(accessor.Type), context.Bound++); + builder.Insert(new OpStore(functionVariable, result.Id, null, [])); + // Process again the same item with new type + --i; + break; + } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { // Emit OpAccessChain with everything so far diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index f5890cd2e9..40277c0e88 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -21,7 +21,7 @@ public partial class SpirvBuilder() public SpirvBlock? CurrentBlock { get; internal set; } public ref int Position => ref position; - public void AddFunctionVariable(int paramType, int paramVariable) + public int AddFunctionVariable(int paramType, int paramVariable) { if (CurrentFunction is not SpirvFunction f) throw new InvalidOperationException(); @@ -38,6 +38,8 @@ public void AddFunctionVariable(int paramType, int paramVariable) Position = currentPosition + 1; CurrentBlock = currentBlock; + + return paramVariable; } From 8daeae02406bf6fcb53bb4ad5fc2612a7dc125f6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 12:36:06 +0900 Subject: [PATCH 0715/1182] Missing case for SV semantic --- .../Spirv/Processing/InterfaceProcessor.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 82d180ee71..fb1e93da33 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -666,17 +666,18 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo return false; // TODO: Check if first stage case "SV_INSTANCEID": - if (isFirstActiveShader && type == StreamVariableType.Input) + if (type == StreamVariableType.Input) return AddBuiltin(variable, BuiltIn.InstanceIndex); return false; - case "SV_VERTEXID" when isFirstActiveShader: - if (isFirstActiveShader && type == StreamVariableType.Input) + case "SV_VERTEXID": + if (executionModel is ExecutionModel.Vertex && type == StreamVariableType.Input) return AddBuiltin(variable, BuiltIn.VertexIndex); return false; - case "SV_ISFRONTFACE" when isFirstActiveShader: - if (isFirstActiveShader && type == StreamVariableType.Input) + case "SV_ISFRONTFACE": + if ((executionModel is ExecutionModel.Fragment && type == StreamVariableType.Input) + || (executionModel is ExecutionModel.Geometry && type == StreamVariableType.Output)) return AddBuiltin(variable, BuiltIn.FrontFacing); - return false; + throw new NotImplementedException($"Invalid use of System-value semantic {stream.Semantic} as {type} in stage {executionModel}"); case {} semantic when semantic.StartsWith("SV_"): throw new NotImplementedException($"System-value Semantic not implemented: {semantic}"); default: From 1c722b53a7c4061af5aa44de7858972b2e343036 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 12:38:18 +0900 Subject: [PATCH 0716/1182] Handle more complex constants (if they can't be resolved as standard SPIR-V, we do it ourselves at the end of ShaderMixer) --- .../SDSL/ShaderMixer.cs | 17 +++++ .../Parsing/SDSL/AST/Expression.cs | 11 +++- .../Spirv/Building/Context.Constants.cs | 62 +++++++++++++++++-- .../Spirv/Building/ExpressionExtensions.cs | 25 +++++--- 4 files changed, 99 insertions(+), 16 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index d3f9dd4cb0..717bee6676 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -82,6 +82,8 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef // Process reflection ProcessReflection(globalContext, context, temp); + SimplifyNonAllowedConstants(context, temp); + foreach (var inst in context) temp.Add(inst.Data); @@ -851,6 +853,21 @@ public static void OffsetIds(OpData inst, int offset) } } } + + private void SimplifyNonAllowedConstants(SpirvContext context, NewSpirvBuffer temp) + { + foreach (var i in context) + { + if (i.Op == Op.OpSpecConstantOp && (OpSpecConstantOp)i is { } specConstantOp) + { + if (ExpressionExtensions.ComputeSpecConstantOpSupportedOps.Contains((Op)specConstantOp.Opcode)) + { + // Simplify the constant + context.TryGetConstantValue(i, out _, out _, true); + } + } + } + } private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 6397ac129a..569127defd 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -793,8 +793,15 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - var left = Left.CompileAsValue(table, compiler); - var right = Right.CompileAsValue(table, compiler); + var expectedOperandType = Op switch + { + Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div or Operator.Mod => expectedType, + // TODO: review XOR/OR/Shift etc. + _ => null, + }; + + var left = Left.CompileAsValue(table, compiler, expectedOperandType); + var right = Right.CompileAsValue(table, compiler, expectedOperandType); var (builder, context) = compiler; var result = builder.BinaryOperation(context, left, Op, right); diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index f8e727c84d..e6d1bb2b89 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -90,9 +90,44 @@ public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, var op = (Specification.Op)i.Data.Memory.Span[3]; switch (op) { - case Specification.Op.OpIMul: + // Conversions + case Specification.Op.OpConvertFToS: + case Specification.Op.OpConvertFToU: + case Specification.Op.OpConvertSToF: + case Specification.Op.OpConvertUToF: + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var convertOperand, out var convertOperandTypeId)) + return false; + value = op switch + { + // Note: first cast to object is important, otherwise int/float will be cast as float + Specification.Op.OpConvertFToS => (object)(int)(float)convertOperand, + Specification.Op.OpConvertFToU => (uint)(float)convertOperand, + Specification.Op.OpConvertSToF => (float)(int)convertOperand, + Specification.Op.OpConvertUToF => (float)(uint)convertOperand, + }; + break; + // Unary operations + case Specification.Op.OpSNegate: + case Specification.Op.OpFNegate: + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var unaryOperand, out var unaryOperandTypeId)) + return false; + if (unaryOperandTypeId != resultType) + return false; + value = op switch + { + // Note: first cast to object is important, otherwise int/float will be cast as float + Specification.Op.OpSNegate => (object)(-(int)unaryOperand), + Specification.Op.OpFNegate => -(float)unaryOperand, + }; + break; + // Binary operations case Specification.Op.OpIAdd: case Specification.Op.OpISub: + case Specification.Op.OpIMul: + case Specification.Op.OpFAdd: + case Specification.Op.OpFSub: + case Specification.Op.OpFMul: + case Specification.Op.OpFDiv: if (!TryGetConstantValue(i.Data.Memory.Span[4], out var left, out var leftTypeId)) return false; if (!TryGetConstantValue(i.Data.Memory.Span[5], out var right, out var rightTypeId)) @@ -101,16 +136,31 @@ public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, return false; value = op switch { - Specification.Op.OpIMul => (int)left * (int)right, - Specification.Op.OpIAdd => (int)left + (int)right, + // Note: first cast to object is important, otherwise int/float will be cast as float + Specification.Op.OpIAdd => (object)((int)left + (int)right), Specification.Op.OpISub => (int)left - (int)right, + Specification.Op.OpIMul => (int)left * (int)right, + Specification.Op.OpFAdd => (float)left + (float)right, + Specification.Op.OpFSub => (float)left - (float)right, + Specification.Op.OpFMul => (float)left * (float)right, + Specification.Op.OpFDiv => (float)left / (float)right, }; - if (simplifyInBuffer) - Buffer.Replace(i.Index, new OpConstant(resultType, resultId, (int)value)); - return true; + break; default: throw new NotImplementedException(); } + + if (simplifyInBuffer) + { + if (value is int valueI) + Buffer.Replace(i.Index, new OpConstant(resultType, resultId, valueI)); + else if (value is float valueF) + Buffer.Replace(i.Index, new OpConstant(resultType, resultId, valueF)); + else + throw new NotImplementedException(); + } + + return true; } if ((i.Op == Specification.Op.OpConstantComposite || i.Op == Specification.Op.OpSpecConstantComposite) && diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index ce06d85c83..577be0c253 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Spirv.Building; public static class ExpressionExtensions { - public static HashSet SpecConstantOpSupportedOps = new() + public static HashSet ShaderSpecConstantOpSupportedOps = new() { Op.OpSConvert, Op.OpUConvert, @@ -49,16 +49,25 @@ public static class ExpressionExtensions Op.OpSLessThanEqual, Op.OpUGreaterThanEqual, Op.OpSGreaterThanEqual, - + }; + + public static HashSet ComputeSpecConstantOpSupportedOps = new() + { // Note: those are not supported in standard shaders (only compute) // but we'll make sure to simplify them once they can be resolved. // We need them for SpirvBuilder.Convert() support // However, it seems so far the expectedType system seems enough to use float4(int, int, int, int) in generics, so they are not implemented for now - //Op.OpConvertFToS, - //Op.OpConvertFToU, - //Op.OpConvertSToF, - //Op.OpConvertUToF, - //Op.OpBitcast, + Op.OpConvertFToS, + Op.OpConvertFToU, + Op.OpConvertSToF, + Op.OpConvertUToF, + Op.OpFNegate, + Op.OpFAdd, + Op.OpFSub, + Op.OpFMul, + Op.OpFDiv, + Op.OpFRem, + Op.OpFMod, }; public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context, SymbolType? expectedType = null) @@ -85,7 +94,7 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol result = new(instruction.Data); } // Rewrite using OpSpecConstantOp when possible - else if(SpecConstantOpSupportedOps.Contains(i.Op)) + else if(ShaderSpecConstantOpSupportedOps.Contains(i.Op) || ComputeSpecConstantOpSupportedOps.Contains(i.Op)) { var resultType = i.Data.Memory.Span[1]; var resultId = i.Data.Memory.Span[2]; From b916b08bfa593872ef1a23f3a67ec3005dbca89f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 14:26:42 +0900 Subject: [PATCH 0717/1182] BinaryExpression: fix mixup between <= and >= for float comparison --- src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index e80b407936..c120456d9a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -275,7 +275,7 @@ when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Greater, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), From 619b5dd0d2f57da2803efc883e10fad6f351b375 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 14:54:09 +0900 Subject: [PATCH 0718/1182] Added support for ddx/ddy/fwidth intrinsics --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 16 ++++++++++++++++ .../PrimaryExpressionParsers.cs | 15 ++++++++------- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index f4d4dc893f..1fd35e1f1c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -779,3 +779,19 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return new SpirvValue(result); } } + +public class FloatUnaryCall(ShaderExpressionList parameters, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + var x = Parameters.Values[0].CompileAsValue(table, compiler); + + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("float")); + x = builder.Convert(context, x, parameterType); + + var instruction = builder.Insert(new OpFwidth(x.TypeId, context.Bound++, x.Id)); + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + return new(instruction.ResultId, instruction.ResultType); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 23f56e6a26..abc3ade818 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -52,6 +52,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char(')', ref scanner, advance: true)) { + // TODO: handle matrices (most of those OPs support only vectors) parsed = (identifier.Name, parameters.Values.Count) switch { ("abort", _) => throw new NotImplementedException(), @@ -77,12 +78,12 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("countbits", _) => throw new NotImplementedException(), ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), - ("ddx", _) => throw new NotImplementedException(), - ("ddx_coarse", _) => throw new NotImplementedException(), - ("ddx_fine", _) => throw new NotImplementedException(), - ("ddy", _) => throw new NotImplementedException(), - ("ddy_coarse", _) => throw new NotImplementedException(), - ("ddy_fine", _) => throw new NotImplementedException(), + ("ddx", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdx), + ("ddx_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxCoarse), + ("ddx_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxFine), + ("ddy", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdy), + ("ddy_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyCoarse), + ("ddy_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyFine), ("degrees", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLDegrees), ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), @@ -106,7 +107,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("fmod", _) => throw new NotImplementedException(), ("frac", _) => throw new NotImplementedException(), ("frexp", _) => throw new NotImplementedException(), - ("fwidth", _) => throw new NotImplementedException(), + ("fwidth", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFwidth), ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), ("GroupMemoryBarrier", _) => throw new NotImplementedException(), From 04e2d64d8ccb70a27da19a210be4046d3d63d931 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 15:21:52 +0900 Subject: [PATCH 0719/1182] Reorganized intrinsics and added asint/asfloat and any/all --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 30 ++++ .../PrimaryExpressionParsers.cs | 128 ++++++++++-------- 2 files changed, 104 insertions(+), 54 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 1fd35e1f1c..5ad25e8bef 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -780,6 +780,22 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } } +public class BoolToScalarBoolCall(ShaderExpressionList parameters, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + var x = Parameters.Values[0].CompileAsValue(table, compiler); + + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("bool")); + x = builder.Convert(context, x, parameterType); + + var instruction = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.From("bool")), context.Bound++, x.Id)); + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + return new(instruction.ResultId, instruction.ResultType); + } +} + public class FloatUnaryCall(ShaderExpressionList parameters, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) @@ -794,4 +810,18 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } +} + +public class BitcastCall(ShaderExpressionList parameters, TextLocation info, ScalarType expectedBaseType) : MethodCall(new("bitcast", info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + var x = Parameters.Values[0].CompileAsValue(table, compiler); + + var resultType = Parameters.Values[0].ValueType.WithElementType(expectedBaseType); + + var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(resultType), context.Bound++, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index abc3ade818..9a15464912 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -1,4 +1,5 @@ using System.Security.AccessControl; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; @@ -55,59 +56,100 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou // TODO: handle matrices (most of those OPs support only vectors) parsed = (identifier.Name, parameters.Values.Count) switch { - ("abort", _) => throw new NotImplementedException(), - ("abs", 1) => new AbsCall(parameters, scanner[position..scanner.Position]), - ("acos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAcos), - ("all", _) => throw new NotImplementedException(), - ("AllMemoryBarrier", _) => throw new NotImplementedException(), - ("AllMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), - ("any", _) => throw new NotImplementedException(), - ("asdouble", _) => throw new NotImplementedException(), - ("asfloat", _) => throw new NotImplementedException(), + // Bool + ("all", _) => new BoolToScalarBoolCall(parameters, scanner[position..scanner.Position], Specification.Op.OpAll), + ("any", _) => new BoolToScalarBoolCall(parameters, scanner[position..scanner.Position], Specification.Op.OpAny), + + // Cast + ("asdouble", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("double")), + ("asfloat", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("float")), + ("asint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("int")), + ("asuint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("uint")), + + // Trigo + ("sin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSin), + ("sinh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSinh), ("asin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAsin), - ("asint", _) => throw new NotImplementedException(), - ("asuint", _) => throw new NotImplementedException(), - ("atan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan), - ("atan2", 2) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), - ("ceil", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCeil), - ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), - ("clamp", _) => new ClampCall(parameters, scanner[position..scanner.Position]), - ("clip", _) => throw new NotImplementedException(), ("cos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCos), ("cosh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCosh), - ("countbits", _) => throw new NotImplementedException(), - ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), - ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), + ("acos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAcos), + ("atan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan), + ("atan2", 2) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), + ("tan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTan), + ("tanh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTanh), + ("sincos", _) => throw new NotImplementedException(), + + // Derivatives ("ddx", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdx), ("ddx_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxCoarse), ("ddx_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxFine), ("ddy", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdy), ("ddy_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyCoarse), ("ddy_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyFine), + ("fwidth", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFwidth), + + // Per component math + ("abs", 1) => new AbsCall(parameters, scanner[position..scanner.Position]), + ("floor", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFloor), + ("ceil", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCeil), + ("trunc", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTrunc), + ("clamp", _) => new ClampCall(parameters, scanner[position..scanner.Position]), + ("max", _) => new MaxCall(parameters, scanner[position..scanner.Position]), + ("min", _) => new MinCall(parameters, scanner[position..scanner.Position]), + ("degrees", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLDegrees), + ("radians", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRadians), + + ("exp", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp), + ("exp2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp2), + ("log", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog), + ("log10", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2, (float)Math.Log10(2.0)), + ("log2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2), + ("pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), + + ("round", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRoundEven), + ("rsqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLInverseSqrt), + ("saturate", 1) => new SaturateCall(parameters, scanner[position..scanner.Position]), + ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), + ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), + ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), + ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), + ("step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), + + // Vector math + ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), + ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), + ("distance", _) => new DistanceCall(parameters, scanner[position..scanner.Position]), + ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), + ("normalize", _) => new NormalizeCall(parameters, scanner[position..scanner.Position]), + ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), + + ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), + ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), + + ("abort", _) => throw new NotImplementedException(), + ("AllMemoryBarrier", _) => throw new NotImplementedException(), + ("AllMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), + ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), + ("clip", _) => throw new NotImplementedException(), + ("countbits", _) => throw new NotImplementedException(), + ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), - ("distance", _) => new DistanceCall(parameters, scanner[position..scanner.Position]), - ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), - ("dst", _) => throw new NotImplementedException(), ("errorf", _) => throw new NotImplementedException(), ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), ("EvaluateAttributeAtSample", _) => throw new NotImplementedException(), ("EvaluateAttributeSnapped", _) => throw new NotImplementedException(), - ("exp", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp), - ("exp2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp2), ("f16to32", _) => throw new NotImplementedException(), ("f32to16", _) => throw new NotImplementedException(), ("faceforward", _) => throw new NotImplementedException(), ("firstbithigh", _) => throw new NotImplementedException(), ("firstbitlow", _) => throw new NotImplementedException(), - ("floor", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFloor), ("fma", _) => throw new NotImplementedException(), ("fmod", _) => throw new NotImplementedException(), ("frac", _) => throw new NotImplementedException(), ("frexp", _) => throw new NotImplementedException(), - ("fwidth", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFwidth), ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), ("GroupMemoryBarrier", _) => throw new NotImplementedException(), @@ -125,21 +167,11 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("isinf", _) => throw new NotImplementedException(), ("isnan", _) => throw new NotImplementedException(), ("ldexp", _) => throw new NotImplementedException(), - ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), - ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), ("lit", _) => throw new NotImplementedException(), - ("log", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog), - ("log10", _) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2, (float)Math.Log10(2.0)), - ("log2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2), ("mad", _) => throw new NotImplementedException(), - ("max", _) => new MaxCall(parameters, scanner[position..scanner.Position]), - ("min", _) => new MinCall(parameters, scanner[position..scanner.Position]), ("modf", _) => throw new NotImplementedException(), ("msad4", _) => throw new NotImplementedException(), - ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), ("noise", _) => throw new NotImplementedException(), - ("normalize", _) => new NormalizeCall(parameters, scanner[position..scanner.Position]), - ("pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), ("printf", _) => throw new NotImplementedException(), ("Process2DQuadTessFactorsAvg", _) => throw new NotImplementedException(), ("Process2DQuadTessFactorsMax", _) => throw new NotImplementedException(), @@ -151,29 +183,17 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("ProcessTriTessFactorsAvg", _) => throw new NotImplementedException(), ("ProcessTriTessFactorsMax", _) => throw new NotImplementedException(), ("ProcessTriTessFactorsMin", _) => throw new NotImplementedException(), - ("radians", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRadians), ("rcp", _) => throw new NotImplementedException(), - ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), - ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), ("reversebits", _) => throw new NotImplementedException(), - ("round", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRoundEven), - ("rsqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLInverseSqrt), - ("saturate", 1) => new SaturateCall(parameters, scanner[position..scanner.Position]), - ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), - ("sin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSin), - ("sincos", _) => throw new NotImplementedException(), - ("sinh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSinh), - ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), - ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), - ("step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), - ("tan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTan), - ("tanh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTanh), + ("transpose", _) => throw new NotImplementedException(), + + // Obsolete + ("dst", _) => throw new NotImplementedException(), ("tex1D" or "tex1Dbias" or "tex1Dgrad" or "tex1Dlod" or "tex1Dproj", _) => throw new NotImplementedException(), ("tex2D" or "tex2Dbias" or "tex2Dgrad" or "tex2Dlod" or "tex2Dproj", _) => throw new NotImplementedException(), ("tex3D" or "tex3Dbias" or "tex3Dgrad" or "tex3Dlod" or "tex3Dproj", _) => throw new NotImplementedException(), ("texCUBE" or "texCUBEbias" or "texCUBEgrad" or "texCUBElod" or "texCUBEproj", _) => throw new NotImplementedException(), - ("transpose", _) => throw new NotImplementedException(), - ("trunc", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTrunc), + _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]), }; /*parsed = (identifier.Name, parameters.Values.Count) switch From e0cbbe157474e13dc82802173b233dcd24372c4e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 18:43:45 +0900 Subject: [PATCH 0720/1182] Bases for compute shader --- .../SDSL/ShaderMixer.cs | 11 +- .../FrameRenderer.D3D11.cs | 496 +++++++++--------- src/Stride.Shaders.Tests/RenderingTests.cs | 64 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 21 + .../ShaderParsers/ShaderMethodParsers.cs | 7 +- .../Spirv/Building/ExpressionExtensions.cs | 19 +- .../Spirv/Processing/InterfaceProcessor.cs | 116 ++-- 7 files changed, 420 insertions(+), 314 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 717bee6676..84f80adb58 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -49,12 +49,11 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef ShaderClass.ProcessNameAndTypes(context); var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); - + context.Insert(0, new OpCapability(Capability.Shader)); context.Insert(1, new OpCapability(Capability.SampledBuffer)); context.Insert(2, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - context.Insert(3, new OpExtension("SPV_GOOGLE_hlsl_functionality1")); - + // Process streams and remove unused code/cbuffer/variable/resources var interfaceProcessor = new InterfaceProcessor { @@ -82,7 +81,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef // Process reflection ProcessReflection(globalContext, context, temp); - SimplifyNonAllowedConstants(context, temp); + SimplifyNotSupportedConstantsInShader(context, temp); foreach (var inst in context) temp.Add(inst.Data); @@ -854,13 +853,13 @@ public static void OffsetIds(OpData inst, int offset) } } - private void SimplifyNonAllowedConstants(SpirvContext context, NewSpirvBuffer temp) + private void SimplifyNotSupportedConstantsInShader(SpirvContext context, NewSpirvBuffer temp) { foreach (var i in context) { if (i.Op == Op.OpSpecConstantOp && (OpSpecConstantOp)i is { } specConstantOp) { - if (ExpressionExtensions.ComputeSpecConstantOpSupportedOps.Contains((Op)specConstantOp.Opcode)) + if (!ExpressionExtensions.ShaderSpecConstantOpSupportedOps.Contains((Op)specConstantOp.Opcode)) { // Simplify the constant context.TryGetConstantValue(i, out _, out _, true); diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 639c91a391..3e51a5e93c 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -36,6 +36,7 @@ public class D3D11FrameRenderer(uint width = 800, uint height = 600, byte[]? fra ComPtr indexBuffer = default; ComPtr vertexShader = default; ComPtr pixelShader = default; + ComPtr computeShader = default; ComPtr inputLayout = default; byte[]? fragmentSpirv = fragmentSpirv; @@ -60,6 +61,8 @@ vs_out main(vs_in input) { } "; + public string? ComputeShaderSource; + //Fragment shaders are run on each fragment/pixel of the geometry. public string PixelShaderSource = @" struct vs_out { @@ -90,6 +93,44 @@ float4 main(vs_out input) : SV_TARGET { ]; public EffectReflection EffectReflection { get; set; } + + public unsafe ComPtr CompileShader(string shaderModel, string source) + { + ComPtr code = default; + ComPtr errors = default; + var sourceBytes = Encoding.ASCII.GetBytes(source); + + // Compile shader + HResult hr = compiler.Compile + ( + in sourceBytes[0], + (nuint)sourceBytes.Length, + nameof(VertexShaderSource), + null, + ref Unsafe.NullRef(), + "main", + shaderModel, + 0, + 0, + ref code, + ref errors + ); + + // Check for compilation errors. + if (hr.IsFailure) + { + if (errors.Handle is not null) + { + Console.WriteLine(SilkMarshal.PtrToString((nint)errors.GetBufferPointer())); + } + + hr.Throw(); + } + + errors.Dispose(); + + return code; + } public override unsafe void RenderFrame(Span result) { @@ -194,253 +235,258 @@ ref swapchain SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref indexBuffer)); } - var vertexShaderBytes = Encoding.ASCII.GetBytes(VertexShaderSource); - var pixelShaderBytes = Encoding.ASCII.GetBytes(PixelShaderSource); - - // Compile vertex shader. - ComPtr vertexCode = default; - ComPtr vertexErrors = default; - HResult hr = compiler.Compile - ( - in vertexShaderBytes[0], - (nuint)vertexShaderBytes.Length, - nameof(VertexShaderSource), - null, - ref Unsafe.NullRef(), - "main", - "vs_5_0", - 0, - 0, - ref vertexCode, - ref vertexErrors - ); - - // Check for compilation errors. - if (hr.IsFailure) + if (ComputeShaderSource != null) { - if (vertexErrors.Handle is not null) - { - Console.WriteLine(SilkMarshal.PtrToString((nint)vertexErrors.GetBufferPointer())); - } - - hr.Throw(); - } + ComPtr computeCode = CompileShader("cs_5_0", ComputeShaderSource); + + // Create vertex shader. + SilkMarshal.ThrowHResult + ( + device.CreateComputeShader + ( + computeCode.GetBufferPointer(), + computeCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref computeShader + ) + ); - // Compile pixel shader. - ComPtr pixelCode = default; - ComPtr pixelErrors = default; - hr = compiler.Compile - ( - in pixelShaderBytes[0], - (nuint)pixelShaderBytes.Length, - nameof(PixelShaderSource), - null, - ref Unsafe.NullRef(), - "main", - "ps_5_0", - 0, - 0, - ref pixelCode, - ref pixelErrors - ); + deviceContext.CSSetShader(computeShader, ref Unsafe.NullRef>(), 0); + + ApplyParameters(); - // Check for compilation errors. - if (hr.IsFailure) - { - if (pixelErrors.Handle is not null) - { - Console.WriteLine(SilkMarshal.PtrToString((nint)pixelErrors.GetBufferPointer())); - } + deviceContext.Dispatch(32, 32, 1); - hr.Throw(); + computeCode.Dispose(); } + else + { + // Compile vertex shader. + ComPtr vertexCode = CompileShader("vs_5_0", VertexShaderSource); + ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); - // Create vertex shader. - SilkMarshal.ThrowHResult - ( - device.CreateVertexShader + // Create vertex shader. + SilkMarshal.ThrowHResult ( - vertexCode.GetBufferPointer(), - vertexCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref vertexShader - ) - ); + device.CreateVertexShader + ( + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref vertexShader + ) + ); - // Create pixel shader. - SilkMarshal.ThrowHResult - ( - device.CreatePixelShader + // Create pixel shader. + SilkMarshal.ThrowHResult ( - pixelCode.GetBufferPointer(), - pixelCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref pixelShader - ) - ); - - // Describe the layout of the input data for the shader. - fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) - fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) - { - var inputElements = new List - { - new() - { - SemanticName = pos, - SemanticIndex = 0, - Format = Format.FormatR32G32B32Float, - InputSlot = 0, - AlignedByteOffset = 0, - InputSlotClass = InputClassification.PerVertexData, - InstanceDataStepRate = 0 - }, - new() - { - SemanticName = texcoord, - SemanticIndex = 0, // TEXCOORD0 - Format = Format.FormatR32G32Float, - InputSlot = 0, - AlignedByteOffset = uint.MaxValue, // AUTO - InputSlotClass = InputClassification.PerVertexData, - InstanceDataStepRate = 0 - } - }; - - // Keep in memory (even if GC) until call to CreateInputLayout - var streamSemanticNamesMemory = new List(); - - // Start at input slot 1 (0 is standard vertex data) - uint inputSlot = 1; - foreach (var parameter in Parameters) + device.CreatePixelShader + ( + pixelCode.GetBufferPointer(), + pixelCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref pixelShader + ) + ); + + // Describe the layout of the input data for the shader. + fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) + fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) { - if (parameter.Key.StartsWith("stream.")) + var inputElements = new List { - var streamSemanticName = parameter.Key.Substring("stream.".Length); - - var streamSemanticNameMemory = SilkMarshal.StringToMemory(streamSemanticName); - streamSemanticNamesMemory.Add(streamSemanticNameMemory); - - inputElements.Add(new InputElementDesc + new() { - SemanticName = (byte*)streamSemanticNameMemory, + SemanticName = pos, SemanticIndex = 0, - Format = Format.FormatR32G32B32A32Float, - InputSlot = inputSlot, + Format = Format.FormatR32G32B32Float, + InputSlot = 0, AlignedByteOffset = 0, - InputSlotClass = InputClassification.PerInstanceData, - InstanceDataStepRate = 0, - }); - - // Also create the vertex and bind it right away - var floatValues = parameter.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries).Select(x => float.Parse(x)).ToArray(); - bufferDesc = new BufferDesc + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + }, + new() { - ByteWidth = (uint)(sizeof(float) * floatValues.Length), // up to 4 floats - Usage = Usage.Default, - BindFlags = (uint)BindFlag.VertexBuffer, - }; + SemanticName = texcoord, + SemanticIndex = 0, // TEXCOORD0 + Format = Format.FormatR32G32Float, + InputSlot = 0, + AlignedByteOffset = uint.MaxValue, // AUTO + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + } + }; + + // Keep in memory (even if GC) until call to CreateInputLayout + var streamSemanticNamesMemory = new List(); - ComPtr vertexBufferForStream = default; - fixed (float* floatValuesPtr = floatValues) + // Start at input slot 1 (0 is standard vertex data) + uint inputSlot = 1; + foreach (var parameter in Parameters) + { + if (parameter.Key.StartsWith("stream.")) { - var subresourceData = new SubresourceData + var streamSemanticName = parameter.Key.Substring("stream.".Length); + + var streamSemanticNameMemory = SilkMarshal.StringToMemory(streamSemanticName); + streamSemanticNamesMemory.Add(streamSemanticNameMemory); + + inputElements.Add(new InputElementDesc { - PSysMem = floatValuesPtr + SemanticName = (byte*)streamSemanticNameMemory, + SemanticIndex = 0, + Format = Format.FormatR32G32B32A32Float, + InputSlot = inputSlot, + AlignedByteOffset = 0, + InputSlotClass = InputClassification.PerInstanceData, + InstanceDataStepRate = 0, + }); + + // Also create the vertex and bind it right away + var floatValues = parameter.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries).Select(x => float.Parse(x)).ToArray(); + bufferDesc = new BufferDesc + { + ByteWidth = (uint)(sizeof(float) * floatValues.Length), // up to 4 floats + Usage = Usage.Default, + BindFlags = (uint)BindFlag.VertexBuffer, }; - SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBufferForStream)); - } + ComPtr vertexBufferForStream = default; + fixed (float* floatValuesPtr = floatValues) + { + var subresourceData = new SubresourceData + { + PSysMem = floatValuesPtr + }; + + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBufferForStream)); + } - deviceContext.IASetVertexBuffers(inputSlot, 1, vertexBufferForStream, 0, 0); - inputSlot++; + deviceContext.IASetVertexBuffers(inputSlot, 1, vertexBufferForStream, 0, 0); + inputSlot++; + } } + + fixed (InputElementDesc* inputElementsPtr = inputElements.AsSpan()) + SilkMarshal.ThrowHResult + ( + device.CreateInputLayout + ( + inputElementsPtr, + (uint)inputElements.Count, + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref inputLayout + ) + ); } + + ComPtr renderTexture = default; + ComPtr renderTextureStaging = default; + + var textureDesc = new Texture2DDesc + { + Width = width, + Height = height, + Format = Format.FormatR8G8B8A8Unorm, + MipLevels = 1, + BindFlags = (uint)(BindFlag.ShaderResource | BindFlag.RenderTarget), + Usage = Usage.Default, + CPUAccessFlags = 0, + MiscFlags = (uint)ResourceMiscFlag.None, + SampleDesc = new SampleDesc(1, 0), + ArraySize = 1 + }; - fixed (InputElementDesc* inputElementsPtr = inputElements.AsSpan()) SilkMarshal.ThrowHResult ( - device.CreateInputLayout + device.CreateTexture2D ( - inputElementsPtr, - (uint)inputElements.Count, - vertexCode.GetBufferPointer(), - vertexCode.GetBufferSize(), - ref inputLayout + in textureDesc, + default, + ref renderTexture ) ); - } - // Clean up any resources. - vertexCode.Dispose(); - vertexErrors.Dispose(); - pixelCode.Dispose(); - pixelErrors.Dispose(); + textureDesc.BindFlags = 0; + textureDesc.Usage = Usage.Staging; + textureDesc.CPUAccessFlags = (uint)CpuAccessFlag.Read; - ComPtr renderTexture = default; - ComPtr renderTextureStaging = default; + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D + ( + in textureDesc, + default, + ref renderTextureStaging + ) + ); - var textureDesc = new Texture2DDesc - { - Width = width, - Height = height, - Format = Format.FormatR8G8B8A8Unorm, - MipLevels = 1, - BindFlags = (uint)(BindFlag.ShaderResource | BindFlag.RenderTarget), - Usage = Usage.Default, - CPUAccessFlags = 0, - MiscFlags = (uint)ResourceMiscFlag.None, - SampleDesc = new SampleDesc(1, 0), - ArraySize = 1 - }; + // Create a view over the render target. + ComPtr renderTargetView = default; + SilkMarshal.ThrowHResult(device.CreateRenderTargetView(renderTexture, null, ref renderTargetView)); - SilkMarshal.ThrowHResult - ( - device.CreateTexture2D - ( - in textureDesc, - default, - ref renderTexture - ) - ); + // Clear the render target to be all black ahead of rendering. + var backgroundColour = new[] { 0.0f, 0.0f, 0.0f, 1.0f }; + deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]); - textureDesc.BindFlags = 0; - textureDesc.Usage = Usage.Staging; - textureDesc.CPUAccessFlags = (uint)CpuAccessFlag.Read; + // Update the rasterizer state with the current viewport. + var viewport = new Viewport(0, 0, width, height, 0, 1); + deviceContext.RSSetViewports(1, in viewport); + deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); - SilkMarshal.ThrowHResult - ( - device.CreateTexture2D - ( - in textureDesc, - default, - ref renderTextureStaging - ) - ); + // Update the input assembler to use our shader input layout, and associated vertex & index buffers. + deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); + deviceContext.IASetInputLayout(inputLayout); + deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); + deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); + + // Bind our shaders. + deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); + deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); - // Create a view over the render target. - ComPtr renderTargetView = default; - SilkMarshal.ThrowHResult(device.CreateRenderTargetView(renderTexture, null, ref renderTargetView)); + ApplyParameters(); + + // Draw the quad. + deviceContext.DrawIndexed(6, 0, 0); + + deviceContext.CopyResource(renderTextureStaging, renderTexture); - // Clear the render target to be all black ahead of rendering. - var backgroundColour = new[] { 0.0f, 0.0f, 0.0f, 1.0f }; - deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]); + MappedSubresource mappedResource = default; + deviceContext.Map(renderTextureStaging, 0, Map.MapRead, 0, ref mappedResource); + var span = new Span(mappedResource.PData, (int)(width * height * 4)); + span.CopyTo(result); + deviceContext.Unmap(renderTextureStaging, 0); - // Update the rasterizer state with the current viewport. - var viewport = new Viewport(0, 0, width, height, 0, 1); - deviceContext.RSSetViewports(1, in viewport); - deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); + // Still do a copy to backbuffer and present, for debugging purpose (i.e. if we run RenderDoc or such debug tools) + var framebuffer = swapchain.GetBuffer(0); - // Update the input assembler to use our shader input layout, and associated vertex & index buffers. - deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); - deviceContext.IASetInputLayout(inputLayout); - deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); - deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); + deviceContext.CopySubresourceRegion(framebuffer, 0, 0, 0, 0, renderTexture, 0, null); - // Bind our shaders. - deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); - deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); + renderTextureStaging.Dispose(); + renderTexture.Dispose(); + renderTargetView.Dispose(); + + framebuffer.Dispose(); + + vertexCode.Dispose(); + pixelCode.Dispose(); + } + + // Present the drawn image. + swapchain.Present(1, 0); + + cts.Cancel(); + cts.Dispose(); + + window.Close(); + window.Dispose(); + } + + private unsafe void ApplyParameters() + { + BufferDesc bufferDesc; foreach (var param in Parameters) { var dotIndex = param.Key.IndexOf("."); @@ -487,6 +533,7 @@ ref renderTextureStaging SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref cbuffer)); } + deviceContext.CSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.VSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.PSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); } @@ -540,6 +587,7 @@ ref bufferSRV ) ); + deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); } @@ -547,7 +595,7 @@ ref bufferSRV { var color = ParseColor(param.Value); - textureDesc = new Texture2DDesc + var textureDesc = new Texture2DDesc { Width = 1, Height = 1, @@ -605,43 +653,11 @@ ref textureSRV ) ); + deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); } } - - // Draw the quad. - deviceContext.DrawIndexed(6, 0, 0); - - deviceContext.CopyResource(renderTextureStaging, renderTexture); - - MappedSubresource mappedResource = default; - deviceContext.Map(renderTextureStaging, 0, Map.MapRead, 0, ref mappedResource); - var span = new Span(mappedResource.PData, (int)(width * height * 4)); - span.CopyTo(result); - deviceContext.Unmap(renderTextureStaging, 0); - - // Still do a copy to backbuffer and present, for debugging purpose (i.e. if we run RenderDoc or such debug tools) - var framebuffer = swapchain.GetBuffer(0); - - deviceContext.CopySubresourceRegion(framebuffer, 0, 0, 0, 0, renderTexture, 0, null); - - // Present the drawn image. - swapchain.Present(1, 0); - - renderTextureStaging.Dispose(); - renderTexture.Dispose(); - - renderTargetView.Dispose(); - - framebuffer.Dispose(); - - cts.Cancel(); - cts.Dispose(); - - window.Close(); - window.Dispose(); - } private static unsafe void FillData(string value, EffectTypeDescription type, int offset, byte* cbufferDataPtr) diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index bf5d89c21d..be525cb989 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -27,17 +27,17 @@ public class RenderingTests static int width = 1; static int height = 1; - class ShaderLoader : ShaderLoaderBase + class ShaderLoader(string basePath) : ShaderLoaderBase { protected override bool ExternalFileExists(string name) { - var filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; + var filename = $"{basePath}/{name}.sdsl"; return File.Exists(filename); } protected override bool LoadExternalFileContent(string name, out string filename, out string code) { - filename = $"./assets/SDSL/RenderTests/{name}.sdsl"; + filename = $"{basePath}/{name}.sdsl"; code = File.ReadAllText(filename); return true; } @@ -63,11 +63,30 @@ public override void RegisterShader(string name, ReadOnlySpan defin } [Theory] - [MemberData(nameof(GetTestFiles))] + [MemberData(nameof(GetComputeTestFiles))] + public void ComputeTest1(string shaderName) + { + // Compiler shader + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); + + File.WriteAllBytes($"{shaderName}.spv", bytecode); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + + // Convert to GLSL + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); + var entryPoints = translator.GetEntryPoints(); + var codeCS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.GLCompute)); + + Console.WriteLine(codeCS); + } + + [Theory] + [MemberData(nameof(GetRenderTestFiles))] public void RenderTest1(string shaderName) { // Compiler shader - var shaderMixer = new ShaderMixer(new ShaderLoader()); + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/RenderTests")); shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); File.WriteAllBytes($"{shaderName}.spv", bytecode); @@ -76,14 +95,24 @@ public void RenderTest1(string shaderName) // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); - var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); - var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) - ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) - : null; + + string? GetShaderCode(ExecutionModel executionModel) + { + return (entryPoints.Any(x => x.ExecutionModel == executionModel)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == executionModel)) + : null; + } + + var codeCS = GetShaderCode(ExecutionModel.GLCompute); + var codePS = GetShaderCode(ExecutionModel.Fragment); + var codeVS = GetShaderCode(ExecutionModel.Vertex); if (codeVS != null) Console.WriteLine(codeVS); - Console.WriteLine(codePS); + if (codePS != null) + Console.WriteLine(codePS); + if (codeCS != null) + Console.WriteLine(codeCS); // Execute test var renderer = new D3D11FrameRenderer((uint)width, (uint)height); @@ -98,9 +127,11 @@ public void RenderTest1(string shaderName) foreach (var param in parameters) renderer.Parameters.Add(param.Key, param.Value); + renderer.ComputeShaderSource = codeCS; renderer.PixelShaderSource = codePS; if (codeVS != null) renderer.VertexShaderSource = codeVS; + using var frameBuffer = MemoryOwner.Allocate(width * height * 4); renderer.EffectReflection = effectReflection; renderer.RenderFrame(frameBuffer.Span); @@ -121,17 +152,24 @@ public void RenderTest1(string shaderName) } } - public static IEnumerable GetTestFiles() + public static IEnumerable GetRenderTestFiles() { foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/RenderTests")) { // Parse header - var code = File.ReadAllLines(filename); var shadername = Path.GetFileNameWithoutExtension(filename); yield return [shadername]; } + } - yield break; + public static IEnumerable GetComputeTestFiles() + { + foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/ComputeTests")) + { + // Parse header + var shadername = Path.GetFileNameWithoutExtension(filename); + yield return [shadername]; + } } public static uint StringToRgba(string? stringColor) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 6214ae219d..bd7e88e8a0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -337,6 +337,27 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var (builder, context) = compiler; + foreach (var attribute in Attributes) + { + if (attribute is AnyShaderAttribute numThreads && numThreads.Name == "numthreads") + { + Span parameters = stackalloc int[numThreads.Parameters.Count]; + for (var index = 0; index < numThreads.Parameters.Count; index++) + { + var parameter = numThreads.Parameters[index]; + + // TODO: avoid emitting in context (use a temp buffer?) + var constantArraySize = parameter.CompileConstantValue(table, context); + if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) + throw new InvalidOperationException(); + + parameters[index] = (int)value; + } + + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); + } + } + table.Push(); Span defaultParameters = stackalloc int[Parameters.Count]; var firstDefaultParameter = -1; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 8c0c68f84a..360b635df0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -168,7 +168,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - else if (isClone || isOverride || isStatic || isStaged) + else { if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { @@ -182,11 +182,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } } - else if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) - { - parsed.Info = scanner[position..scanner.Position]; - return true; - } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index 577be0c253..1a14d140c8 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -51,16 +51,21 @@ public static class ExpressionExtensions Op.OpSGreaterThanEqual, }; - public static HashSet ComputeSpecConstantOpSupportedOps = new() + public static HashSet KernelSpecConstantOpSupportedOps = new() { - // Note: those are not supported in standard shaders (only compute) + // Note: those are not supported in shaders // but we'll make sure to simplify them once they can be resolved. - // We need them for SpirvBuilder.Convert() support - // However, it seems so far the expectedType system seems enough to use float4(int, int, int, int) in generics, so they are not implemented for now + // They are needed for more complex constants. Op.OpConvertFToS, Op.OpConvertFToU, Op.OpConvertSToF, Op.OpConvertUToF, + Op.OpUConvert, + Op.OpConvertPtrToU, + Op.OpConvertUToPtr, + Op.OpGenericCastToPtr, + Op.OpPtrCastToGeneric, + Op.OpBitcast, Op.OpFNegate, Op.OpFAdd, Op.OpFSub, @@ -68,6 +73,10 @@ public static class ExpressionExtensions Op.OpFDiv, Op.OpFRem, Op.OpFMod, + Op.OpAccessChain, + Op.OpInBoundsAccessChain, + Op.OpPtrAccessChain, + Op.OpInBoundsPtrAccessChain, }; public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context, SymbolType? expectedType = null) @@ -94,7 +103,7 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol result = new(instruction.Data); } // Rewrite using OpSpecConstantOp when possible - else if(ShaderSpecConstantOpSupportedOps.Contains(i.Op) || ComputeSpecConstantOpSupportedOps.Contains(i.Op)) + else if(ShaderSpecConstantOpSupportedOps.Contains(i.Op) || KernelSpecConstantOpSupportedOps.Contains(i.Op)) { var resultType = i.Data.Memory.Span[1]; var resultId = i.Data.Memory.Span[2]; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index fb1e93da33..e7b6a29e78 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -164,72 +164,99 @@ public bool MarkMethodUsed(int functionId) public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { table.TryResolveSymbol("VSMain", out var entryPointVS); - var entryPointPS = table.ResolveSymbol("PSMain"); + table.TryResolveSymbol("PSMain", out var entryPointPS); + table.TryResolveSymbol("CSMain", out var entryPointCS); + if (entryPointCS.Type is FunctionGroupType) + entryPointCS = entryPointCS.GroupMembers[^1]; if (entryPointVS.Type is FunctionGroupType) entryPointVS = entryPointVS.GroupMembers[^1]; if (entryPointPS.Type is FunctionGroupType) entryPointPS = entryPointPS.GroupMembers[^1]; - if (entryPointPS.IdRef == 0) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel shader is expected"); + if (entryPointPS.IdRef == 0 && entryPointCS.IdRef == 0) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); + if (entryPointPS.IdRef != 0 && entryPointCS.IdRef != 0) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); + + var entryPointPSOrCS = entryPointCS.IdRef != 0 ? entryPointCS : entryPointPS; var analysisResult = Analyze(buffer, context); MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; var liveAnalysis = new LiveAnalysis(); - AnalyzeStreamReadWrites(buffer, context, entryPointPS.IdRef, analysisResult, liveAnalysis); + AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); - // If written to, they are expected at the end of pixel shader - foreach (var stream in streams) + if (entryPointCS.IdRef != 0) { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") - && stream.Value.Write) - stream.Value.Output = true; - } + var csWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.GLCompute, entryPointCS.IdRef, entryPointCS.Id.Name, analysisResult, liveAnalysis, false); - // Check if there is any output - // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) - if (streams.Any(x => x.Value.Output)) - { - var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); - buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); - } - - // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages - foreach (var stream in streams) - { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) - stream.Value.Read = false; + // Move OpExecutionMode on new CSMain wrapper (and remove others) + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) + { + if (executionMode.EntryPoint == entryPointCS.IdRef) + executionMode.EntryPoint = csWrapperId; + else + SpirvBuilder.SetOpNop(executionMode.OpData.Memory.Span); + } + } } - // Reset cbuffer/resource/methods used for next stage - foreach (var variable in analysisResult.Variables) - variable.Value.UsedThisStage = false; - foreach (var resource in analysisResult.Resources) - resource.Value.UsedThisStage = false; - foreach (var cbuffer in analysisResult.CBuffers) - cbuffer.Value.UsedThisStage = false; - foreach (var method in liveAnalysis.ReferencedMethods) + if (entryPointPS.IdRef != 0) { - method.Value.UsedThisStage = false; - method.Value.ThisStageMethodId = null; - } + // If written to, they are expected at the end of pixel shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") + && stream.Value.Write) + stream.Value.Output = true; + } - PropagateStreamsFromPreviousStage(streams); - if (entryPointVS.IdRef != 0) - { - AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); + // Check if there is any output + // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) + if (streams.Any(x => x.Value.Output)) + { + var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); + buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); + } - // If written to, they are expected at the end of vertex shader + // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - && stream.Value.Write) - stream.Value.Output = true; + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) + stream.Value.Read = false; + } + + // Reset cbuffer/resource/methods used for next stage + foreach (var variable in analysisResult.Variables) + variable.Value.UsedThisStage = false; + foreach (var resource in analysisResult.Resources) + resource.Value.UsedThisStage = false; + foreach (var cbuffer in analysisResult.CBuffers) + cbuffer.Value.UsedThisStage = false; + foreach (var method in liveAnalysis.ReferencedMethods) + { + method.Value.UsedThisStage = false; + method.Value.ThisStageMethodId = null; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); + PropagateStreamsFromPreviousStage(streams); + if (entryPointVS.IdRef != 0) + { + AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); + + // If written to, they are expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + && stream.Value.Write) + stream.Value.Output = true; + } + + GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); + } } // This will remove a lot of unused methods, resources and variables @@ -615,6 +642,7 @@ private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, E { ExecutionModel.Fragment => "PS", ExecutionModel.Vertex => "VS", + ExecutionModel.GLCompute => "CS", _ => throw new NotImplementedException() }; List<(StreamInfo Info, int Id)> inputStreams = []; @@ -765,7 +793,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo } } - context.FluentAdd(new OpTypeVoid(context.Bound++), out var voidType); + var voidType = context.GetOrRegister(ScalarType.From("void")); // Add new entry point wrapper context.FluentAdd(new OpTypeFunctionSDSL(context.Bound++, voidType, []), out var newEntryPointFunctionType); From 5e7338650fa7672447d10fdf05d83b8f1d5f886e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 18:54:22 +0900 Subject: [PATCH 0721/1182] Parse RW MS and Array texture types --- src/Stride.Shaders/Core/SymbolTypes.cs | 50 ++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 602ebb979f..86af872e7d 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -72,18 +72,40 @@ public static bool TryGetBufferType(string name, string? templateTypeName, [Mayb ScalarType s => s, }; - (result, bool found) = (name, scalarType) switch + SymbolType? foundType = (name, scalarType) switch { - ("Buffer", ScalarType { TypeName: "float" or "int" or "uint" }) => (new BufferType(scalarType) as SymbolType, true), - ("Texture", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture1DType(scalarType) as SymbolType, true), - ("Texture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture1DType(scalarType) as SymbolType, true), - ("Texture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture2DType(scalarType) as SymbolType, true), - ("Texture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => (new Texture3DType(scalarType) as SymbolType, true), - ("TextureCube", ScalarType { TypeName: "float" or "int" or "uint" }) => (new TextureCubeType(scalarType) as SymbolType, true), - - _ => (null, false) + ("Buffer", ScalarType { TypeName: "float" or "int" or "uint" }) => new BufferType(scalarType), + + ("Texture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType), + ("Texture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType), + ("Texture2DMS", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Multisampled = true }, + ("Texture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType), + ("TextureCube", ScalarType { TypeName: "float" or "int" or "uint" }) => new TextureCubeType(scalarType), + + ("Texture1DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Arrayed = true }, + ("Texture2DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Arrayed = true }, + ("Texture2DMSArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Multisampled = true, Arrayed = true }, + ("Texture3DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType) { Arrayed = true }, + ("TextureCubeArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new TextureCubeType(scalarType) { Arrayed = true }, + + ("RWTexture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Sampled = 2 }, + ("RWTexture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Sampled = 2 }, + ("RWTexture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType) { Sampled = 2 }, + + ("RWTexture1DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Sampled = 2, Arrayed = true }, + ("RWTexture2DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Sampled = 2, Arrayed = true }, + + _ => null, }; - return found; + + if (foundType != null) + { + result = foundType; + return true; + } + + result = null; + return false; } public abstract void Accept(TypeVisitor visitor); @@ -199,20 +221,20 @@ public abstract partial record TextureType(ScalarType ReturnType, Dim Dimension, public sealed partial record Texture1DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture1D<{ReturnType}>"; + public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture1D{(Arrayed ? "Array" : "")}<{ReturnType}>"; } public sealed partial record Texture2DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture2D<{ReturnType}>"; + public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture2D{(Multisampled ? "MS" : "")}{(Arrayed ? "Array" : "")}<{ReturnType}>"; } public sealed partial record Texture3DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"Texture3D<{ReturnType}>"; + public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture3D{(Arrayed ? "Array" : "")}<{ReturnType}>"; } public sealed partial record TextureCubeType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) { - public override string ToString() => $"TextureCube<{ReturnType}>"; + public override string ToString() => $"TextureCube{(Arrayed ? "Array" : "")}<{ReturnType}>"; } public sealed partial record FunctionGroupType() : SymbolType(); From 38812823889ab336e815eedf48a8d6091360b3f0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 14 Jan 2026 22:47:08 +0900 Subject: [PATCH 0722/1182] Removed SpirvValue.Swizzle and instead use a proper l-value system --- .../Parsing/SDSL/AST/Expression.cs | 290 ++++++++++++++++-- .../Parsing/SDSL/AST/Literals.cs | 15 + .../Parsing/SDSL/AST/Statements.Flow.cs | 1 - .../Parsing/SDSL/AST/Statements.cs | 23 +- .../Spirv/Building/BasicBlocks.cs | 39 --- .../Spirv/Building/Builder.Expressions.cs | 7 +- 6 files changed, 284 insertions(+), 91 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 569127defd..a57119ffd5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -28,6 +28,14 @@ public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? return result; } + /// + /// Assign to l-value. + /// + public virtual void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + { + throw new InvalidOperationException($"{this} is not a l-value and cannot be assigned to."); + } + public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null); public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } @@ -279,7 +287,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, case Operator.Dec: { // Not supported yet - expression.ThrowIfSwizzle(); if (!isPointer) throw new InvalidOperationException($"Can't use increment/decrement expression on non-pointer expression {Expression}"); @@ -379,7 +386,167 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; + public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + { + var lvalue = CompileHelper(table, compiler, null, true, out var remainingIndex); + + if (remainingIndex == 0) + base.SetValue(table, compiler, value); + + var (builder, context) = compiler; + + // Only things left should be: + // - RWBuffer/Texture setters + // - Swizzles + + // We do one pass forward to compute type and coalesce swizzle + int[]? swizzleIndices = null; + int swizzleIndicesSetByAccessor = -1; + + var currentValueType = Accessors[remainingIndex - 1].Type; + for (var i = remainingIndex; i < Accessors.Count; i++) + { + var accessor = Accessors[i]; + switch (currentValueType, accessor) + { + case (PointerType { BaseType: TextureType or BufferType } p, IndexerExpression indexer): + + accessor.Type = new VectorType(p.BaseType switch + { + BufferType b => b.BaseType, + TextureType t => t.ReturnType, + }, 4); + break; + case (PointerType { BaseType: VectorType or ScalarType } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + { + (var size, ScalarType baseType) = p.BaseType switch + { + ScalarType s => (1, s), + VectorType v => (v.Size, v.BaseType), + }; + + swizzleIndices = new int[swizzle.Length]; + swizzleIndicesSetByAccessor = i; + for (int j = 0; j < swizzle.Length; ++j) + { + swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + if (swizzleIndices[j] >= size) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } + + accessor.Type = p.BaseType; + + break; + } + case (VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + { + if (swizzleIndices == null || swizzleIndicesSetByAccessor != i - 1) + throw new InvalidOperationException("No previous swizzle but already value type on l-value"); + + (var size, ScalarType baseType) = currentValueType switch + { + ScalarType s => (1, s), + VectorType v => (v.Size, v.BaseType), + }; + + // Combine swizzles with previous ones + var newSwizzleIndices = new int[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + { + newSwizzleIndices[j] = swizzleIndices[ConvertSwizzle(swizzle[j])]; + if (newSwizzleIndices[j] >= size) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } + + Accessors.RemoveAt(i--); + Span vectorFields = ['x', 'y', 'z', 'w']; + Span newSwizzle = stackalloc char[swizzle.Length]; + for (int j = 0; j < swizzle.Length; ++j) + { + newSwizzle[j] = vectorFields[newSwizzleIndices[j]]; + } + + Accessors[i] = accessor = new Identifier(new(newSwizzle), default); + + swizzleIndices = newSwizzleIndices; + swizzleIndicesSetByAccessor = 1; + accessor.Type = baseType.GetVectorOrScalar(swizzle.Length); + break; + } + default: + throw new NotImplementedException(); + } + + currentValueType = accessor.Type; + } + + // Process from end + for (var i = Accessors.Count - 1; i >= remainingIndex; --i) + { + var accessor = Accessors[i]; + currentValueType = Accessors[i - 1].Type; + + switch (currentValueType, accessor) + { + case (PointerType { BaseType: BufferType b }, IndexerExpression indexer): + // Only allow if it's the last item to process + if (i != remainingIndex) + throw new NotImplementedException(); + + throw new NotImplementedException(); + case (PointerType { BaseType: TextureType t }, IndexerExpression indexer): + // Only allow if it's the last item to process + if (i != remainingIndex) + throw new NotImplementedException(); + + var index = indexer.CompileAsValue(table, compiler); + builder.Insert(new OpImageWrite(lvalue.Id, index.Id, value.Id, null, [])); + break; + case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + // It should have been coalesced + throw new InvalidOperationException(); + case (PointerType { BaseType: VectorType } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + // Swizzle: we transform the value to assign accordingly + if (i != remainingIndex) + // TODO: Handle more complex cases like texture[0].w += 3.0; + throw new NotImplementedException(); + + currentValueType = p.BaseType; + + // We load the original value (in case we assign to only part of it, i.e. a.yz = 3.0;) + var targetValue = builder.Insert(new OpLoad(context.GetOrRegister(currentValueType), context.Bound++, lvalue.Id, null, [])).ResultId; + + // Shuffle with new data + switch (p.BaseType) + { + case VectorType v: + Span shuffleIndices = stackalloc int[v.Size]; + // Default: source values + for (int j = 0; j < v.Size; ++j) + shuffleIndices[j] = j; + // Update using swizzle target (from 2nd new value vector) + for (int j = 0; j < swizzle.Length; ++j) + shuffleIndices[ConvertSwizzle(swizzle[j])] = v.Size + j; + value = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(currentValueType), context.Bound++, targetValue, value.Id, new(shuffleIndices)))); + break; + default: + throw new NotImplementedException(); + } + break; + } + } + + var expectedType = (PointerType)context.ReverseTypes[lvalue.TypeId]; + value = builder.Convert(context, value, expectedType.BaseType); + builder.Insert(new OpStore(lvalue.Id, value.Id, null, [])); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + return CompileHelper(table, compiler, expectedType, false, out _); + } + + public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType, bool lvalue, out int remainingIndex) { var (builder, context) = compiler; SpirvValue result; @@ -391,7 +558,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; result = methodCall.Compile(table, compiler); - result.ThrowIfSwizzle(); currentValueType = methodCall.Type; firstIndex = 1; } @@ -406,6 +572,13 @@ void PushAccessChainId(Span accessChainIds, int accessChainIndex) { accessChainIds[accessChainIdCount++] = accessChainIndex; } + + void ThrowErrorOnLValue() + { + if (lvalue) + base.SetValue(table, compiler, default); + } + void EmitOpAccessChain(Span accessChainIds) { // Do we need to issue an OpAccessChain? @@ -414,14 +587,14 @@ void EmitOpAccessChain(Span accessChainIds) var resultType = context.GetOrRegister(currentValueType); var test = new LiteralArray(accessChainIds); var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); - result = new SpirvValue(accessChain.ResultId, resultType) { Swizzles = result.Swizzles }; + result = new SpirvValue(accessChain.ResultId, resultType); } accessChainIdCount = 0; } Span accessChainIds = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i < Accessors.Count; i++) + for (var i = remainingIndex = firstIndex; i < Accessors.Count; remainingIndex = ++i) { var accessor = Accessors[i]; switch (currentValueType, accessor) @@ -431,6 +604,8 @@ void EmitOpAccessChain(Span accessChainIds) or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 }): { + ThrowErrorOnLValue(); + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); var textureValue = builder.AsValue(context, result); @@ -444,9 +619,6 @@ void EmitOpAccessChain(Span accessChainIds) if (textureType.Arrayed) textureCoordSize++; - // Load texture as value - result = builder.AsValue(context, result); - if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } implicitSampling) { var resultType = new VectorType(textureType.ReturnType, 4); @@ -554,6 +726,8 @@ void EmitOpAccessChain(Span accessChainIds) } case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load): { + ThrowErrorOnLValue(); + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); @@ -571,7 +745,39 @@ void EmitOpAccessChain(Span accessChainIds) accessor.Type = resultType; break; } + case (PointerType { BaseType: BufferType b }, IndexerExpression indexer): + { + // Texture/Buffer writes are handled as l-value assign + if (lvalue) + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + return result; + } + + throw new NotImplementedException(); + + break; + } + case (PointerType { BaseType: TextureType t }, IndexerExpression indexer): + { + // Texture/Buffer writes are handled as l-value assign + if (lvalue) + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + return result; + } + + var indexValue = indexer.CompileAsValue(table, compiler); + throw new NotImplementedException(); + //builder.Insert(new OpImageRead(lvalue.Id, indexValue.Id, value.Id, null, [])); + + break; + } case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + ThrowErrorOnLValue(); + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); @@ -588,18 +794,18 @@ void EmitOpAccessChain(Span accessChainIds) // TODO: figure out instance (this vs composition) result = Identifier.EmitSymbol(builder, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; - + + if (accessor.Type is not PointerType) + ThrowErrorOnLValue(); break; case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now\ streamVar.AllowStreamVariables = true; var streamVariableResult = streamVar.Compile(table, compiler); - streamVariableResult.ThrowIfSwizzle(); PushAccessChainId(accessChainIds, streamVariableResult.Id); accessor.Type = streamVar.Type; break; case (PointerType { BaseType: StructType s } p, Identifier field): - var index = s.TryGetFieldIndex(field); if (index == -1) throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); @@ -608,33 +814,50 @@ void EmitOpAccessChain(Span accessChainIds) accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); break; // Swizzles - case (PointerType { BaseType: VectorType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + case (PointerType { BaseType: VectorType v } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { + // Swizzle assignment is handled as l-value assign + if (lvalue) + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + return result; + } + + // Load value + EmitOpAccessChain(accessChainIds); + result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, []))); + Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) + { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - - result.ApplySwizzles(swizzleIndices); - - // Check resulting swizzles - for (int j = 0; j < result.Swizzles.Length; ++j) - if (swizzleIndices[j] >= s.Size) + if (swizzleIndices[j] >= v.Size) throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } + (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); + accessor.Type = currentValueType; } else { PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); - accessor.Type = new PointerType(s.BaseType, p.StorageClass); + accessor.Type = new PointerType(v.BaseType, p.StorageClass); } break; case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): { + ThrowErrorOnLValue(); + Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) + { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + if (swizzleIndices[j] >= v.Size) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); accessor.Type = v; @@ -644,11 +867,27 @@ void EmitOpAccessChain(Span accessChainIds) case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { + // Swizzle assignment is handled as l-value assign + if (lvalue) + { + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds); + return result; + } + + // Load value + EmitOpAccessChain(accessChainIds); + result = new(builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null, []))); + Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) + { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); + if (swizzleIndices[j] != 0) + throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } - result.ApplySwizzles(swizzleIndices); + (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); accessor.Type = currentValueType; } else @@ -661,6 +900,10 @@ void EmitOpAccessChain(Span accessChainIds) } break; case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + // Swizzle assignment is handled differently + if (lvalue) + return result; + if (swizzle.Length > 1) { Span swizzleIndices = stackalloc int[swizzle.Length]; @@ -682,7 +925,7 @@ void EmitOpAccessChain(Span accessChainIds) break; // Array indexer for shader compositions case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): - break; + throw new NotImplementedException(); // Array indexer for arrays case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): { @@ -708,6 +951,8 @@ void EmitOpAccessChain(Span accessChainIds) // So we load the value into a variable and use normal path case (ArrayType or VectorType or MatrixType, IndexerExpression indexer): { + ThrowErrorOnLValue(); + // We need to load as a variable to use OpAccessChain accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(accessor.Type), context.Bound++); @@ -718,12 +963,11 @@ void EmitOpAccessChain(Span accessChainIds) } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { + ThrowErrorOnLValue(); + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds); - // Not supported yet - result.ThrowIfSwizzle(); - var resultPointer = result; // This is what this chain return (value before modification) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 3f06106fa4..621a6e9abb 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -364,6 +364,21 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, return result; } + public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + { + var (builder, context) = compiler; + + value = builder.AsValue(context, value); + var target = CompileSymbol(table, builder, context, false); + + if (Type is not PointerType) + // Throw exception (default behavior) + base.SetValue(table, compiler, value); + + value = builder.Convert(context, value, ((PointerType)Type).BaseType); + builder.Insert(new OpStore(target.Id, value.Id, null, [])); + } + public override string ToString() { return $"{Name}"; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index c296288b27..4a2fefc0b8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -55,7 +55,6 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; var collection = Collection.Compile(table, compiler); - collection.ThrowIfSwizzle(); if (!(Collection.Type is PointerType p && p.BaseType is ArrayType arrayType)) throw new InvalidOperationException("foreach: Array type is expected"); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 9f7629fca4..f4966ef5ec 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -244,28 +244,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var resultType = target.GetValueType(context, true); source = builder.Convert(context, source, resultType); - if (target.Swizzles != null) - { - var valueType = context.Types[p.BaseType]; - var loadId = builder.Insert(new OpLoad(valueType, context.Bound++, target.Id, null, [])).ResultId; - // Shuffle with new data - switch (p.BaseType) - { - case VectorType v: - Span shuffleIndices = stackalloc int[v.Size]; - // Default: source values - for (int j = 0; j < v.Size; ++j) - shuffleIndices[j] = j; - // Update using swizzle target (from 2nd new value vector) - for (int j = 0; j < target.Swizzles.Length; ++j) - shuffleIndices[target.Swizzles[j]] = v.Size + j; - source = new(builder.InsertData(new OpVectorShuffle(valueType, context.Bound++, loadId, source.Id, new(shuffleIndices)))); - break; - default: - throw new NotImplementedException(); - } - } - builder.Insert(new OpStore(target.Id, source.Id, null, [])); + variable.Variable.SetValue(table, compiler, source); } } public override string ToString() diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index c23aa8f4c5..a05b56f1f1 100644 --- a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs +++ b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs @@ -34,53 +34,14 @@ public SpirvValue(OpData instruction, string? name = null) public int TypeId { get; set; } public string? Name { get; set; } - /// - /// Swizzle to apply to the value. - /// - /// - /// Swizzle doesn't affect the . For example, float3().xy will have float3. - /// - public int[]? Swizzles { get; set; } - public SymbolType GetValueType(SpirvContext context, bool includeSwizzles) { var type = context.ReverseTypes[TypeId]; if (type is PointerType p) type = p.BaseType; - if (includeSwizzles && Swizzles != null) - { - type = (type, Swizzles.Length) switch - { - (ScalarType s, > 1) => new VectorType(s, Swizzles.Length), - (ScalarType s, 1) => s, - (VectorType v, >1) => new VectorType(v.BaseType, Swizzles.Length), - (VectorType v, 1) => v.BaseType, - }; - } - return type; } - - public void ApplySwizzles(Span swizzleIndices) - { - var oldSwizzles = Swizzles; - Swizzles = swizzleIndices.ToArray(); - if (oldSwizzles != null) - { - // Reapply swizzle on existing swizzles - for (int i = 0; i < Swizzles.Length; ++i) - Swizzles[i] = oldSwizzles[Swizzles[i]]; - } - - // TODO: remove swizzle if identity? - } - - internal void ThrowIfSwizzle() - { - if (Swizzles != null) - throw new InvalidOperationException("This expression doesn't handle swizzle"); - } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index c120456d9a..fe51e8203f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -17,12 +17,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) { type = pointerType.BaseType; var inst = Insert(new OpLoad(context.Types[type], context.Bound++, result.Id, null, [])); - result = new(inst.ResultId, inst.ResultType) { Swizzles = result.Swizzles }; - } - - if (result.Swizzles != null) - { - (result, _) = ApplySwizzles(context, result, result.Swizzles); + result = new(inst.ResultId, inst.ResultType); } return result; From 8553e98c52a6a5bd5f1aedc6e2c007e719c3d831 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 16 Jan 2026 14:03:10 +0900 Subject: [PATCH 0723/1182] Rewrote the lvalue assign system --- assets/SDSL/ComputeTests/CSEmpty.sdsl | 20 + .../FrameRenderer.D3D11.cs | 423 ++++++++-------- .../FrameRenderer.OpenGL.cs | 2 +- src/Stride.Shaders.Tests/FrameRenderer.cs | 2 - src/Stride.Shaders.Tests/RenderingTests.cs | 66 ++- src/Stride.Shaders/Core/Symbol.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 478 +++++++++--------- .../Parsing/SDSL/AST/Literals.cs | 10 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 39 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Parsing/SDSL/AST/Statements.cs | 4 +- .../Spirv/Building/BasicBlocks.cs | 2 +- .../Spirv/Building/Builder.Expressions.cs | 5 +- 13 files changed, 550 insertions(+), 507 deletions(-) create mode 100644 assets/SDSL/ComputeTests/CSEmpty.sdsl diff --git a/assets/SDSL/ComputeTests/CSEmpty.sdsl b/assets/SDSL/ComputeTests/CSEmpty.sdsl new file mode 100644 index 0000000000..a577e5868e --- /dev/null +++ b/assets/SDSL/ComputeTests/CSEmpty.sdsl @@ -0,0 +1,20 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +shader CSEmpty +{ + stage stream uint3 GroupId : SV_GroupID; + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + stage stream uint3 GroupThreadId : SV_GroupThreadID; + stage stream uint GroupIndex : SV_GroupIndex; + + RWTexture2D Output; + //RWStructuredBuffer Output; + + [numthreads(32, 32, 1)] + void CSMain() + { + Output[int2(0, 0)].zx += float2(0,1); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 3e51a5e93c..2ef0c34997 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -75,6 +75,8 @@ float4 main(vs_out input) : SV_TARGET { } "; + private CancellationTokenSource cts; + //Vertex data, uploaded to the VBO. private static readonly float[] Vertices = [ @@ -132,7 +134,7 @@ ref errors return code; } - public override unsafe void RenderFrame(Span result) + public unsafe void SetupTest() { var options = WindowOptions.Default; options.Size = new Vector2D((int)width, (int)height); @@ -165,7 +167,7 @@ ref deviceContext ) ); - var cts = new CancellationTokenSource(); + cts = new CancellationTokenSource(); if (OperatingSystem.IsWindows()) { // Log debug messages for this device (given that we've enabled the debug flag). Don't do this in release code! @@ -234,254 +236,259 @@ ref swapchain SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref indexBuffer)); } + } - if (ComputeShaderSource != null) - { - ComPtr computeCode = CompileShader("cs_5_0", ComputeShaderSource); + public void PresentAndFinish() + { + // Present the drawn image. + swapchain.Present(1, 0); + + cts.Cancel(); + cts.Dispose(); + + window.Close(); + window.Dispose(); + } + + public unsafe void Compute() + { + ComPtr computeCode = CompileShader("cs_5_0", ComputeShaderSource); - // Create vertex shader. - SilkMarshal.ThrowHResult + // Create vertex shader. + SilkMarshal.ThrowHResult + ( + device.CreateComputeShader ( - device.CreateComputeShader - ( - computeCode.GetBufferPointer(), - computeCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref computeShader - ) - ); - - deviceContext.CSSetShader(computeShader, ref Unsafe.NullRef>(), 0); + computeCode.GetBufferPointer(), + computeCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref computeShader + ) + ); + + deviceContext.CSSetShader(computeShader, ref Unsafe.NullRef>(), 0); - ApplyParameters(); + ApplyParameters(); - deviceContext.Dispatch(32, 32, 1); + deviceContext.Dispatch(32, 32, 1); - computeCode.Dispose(); - } - else - { - // Compile vertex shader. - ComPtr vertexCode = CompileShader("vs_5_0", VertexShaderSource); - ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); + computeCode.Dispose(); + } + + public unsafe void RenderFrame(Span result) + { + BufferDesc bufferDesc; + // Compile vertex shader. + ComPtr vertexCode = CompileShader("vs_5_0", VertexShaderSource); + ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); - // Create vertex shader. - SilkMarshal.ThrowHResult + // Create vertex shader. + SilkMarshal.ThrowHResult + ( + device.CreateVertexShader ( - device.CreateVertexShader - ( - vertexCode.GetBufferPointer(), - vertexCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref vertexShader - ) - ); - - // Create pixel shader. - SilkMarshal.ThrowHResult + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref vertexShader + ) + ); + + // Create pixel shader. + SilkMarshal.ThrowHResult + ( + device.CreatePixelShader ( - device.CreatePixelShader - ( - pixelCode.GetBufferPointer(), - pixelCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref pixelShader - ) - ); + pixelCode.GetBufferPointer(), + pixelCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref pixelShader + ) + ); - // Describe the layout of the input data for the shader. - fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) - fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) + // Describe the layout of the input data for the shader. + fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) + fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) + { + var inputElements = new List { - var inputElements = new List + new() { - new() - { - SemanticName = pos, - SemanticIndex = 0, - Format = Format.FormatR32G32B32Float, - InputSlot = 0, - AlignedByteOffset = 0, - InputSlotClass = InputClassification.PerVertexData, - InstanceDataStepRate = 0 - }, - new() - { - SemanticName = texcoord, - SemanticIndex = 0, // TEXCOORD0 - Format = Format.FormatR32G32Float, - InputSlot = 0, - AlignedByteOffset = uint.MaxValue, // AUTO - InputSlotClass = InputClassification.PerVertexData, - InstanceDataStepRate = 0 - } - }; + SemanticName = pos, + SemanticIndex = 0, + Format = Format.FormatR32G32B32Float, + InputSlot = 0, + AlignedByteOffset = 0, + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + }, + new() + { + SemanticName = texcoord, + SemanticIndex = 0, // TEXCOORD0 + Format = Format.FormatR32G32Float, + InputSlot = 0, + AlignedByteOffset = uint.MaxValue, // AUTO + InputSlotClass = InputClassification.PerVertexData, + InstanceDataStepRate = 0 + } + }; - // Keep in memory (even if GC) until call to CreateInputLayout - var streamSemanticNamesMemory = new List(); + // Keep in memory (even if GC) until call to CreateInputLayout + var streamSemanticNamesMemory = new List(); - // Start at input slot 1 (0 is standard vertex data) - uint inputSlot = 1; - foreach (var parameter in Parameters) + // Start at input slot 1 (0 is standard vertex data) + uint inputSlot = 1; + foreach (var parameter in Parameters) + { + if (parameter.Key.StartsWith("stream.")) { - if (parameter.Key.StartsWith("stream.")) + var streamSemanticName = parameter.Key.Substring("stream.".Length); + + var streamSemanticNameMemory = SilkMarshal.StringToMemory(streamSemanticName); + streamSemanticNamesMemory.Add(streamSemanticNameMemory); + + inputElements.Add(new InputElementDesc { - var streamSemanticName = parameter.Key.Substring("stream.".Length); + SemanticName = (byte*)streamSemanticNameMemory, + SemanticIndex = 0, + Format = Format.FormatR32G32B32A32Float, + InputSlot = inputSlot, + AlignedByteOffset = 0, + InputSlotClass = InputClassification.PerInstanceData, + InstanceDataStepRate = 0, + }); - var streamSemanticNameMemory = SilkMarshal.StringToMemory(streamSemanticName); - streamSemanticNamesMemory.Add(streamSemanticNameMemory); + // Also create the vertex and bind it right away + var floatValues = parameter.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries).Select(x => float.Parse(x)).ToArray(); + bufferDesc = new BufferDesc + { + ByteWidth = (uint)(sizeof(float) * floatValues.Length), // up to 4 floats + Usage = Usage.Default, + BindFlags = (uint)BindFlag.VertexBuffer, + }; - inputElements.Add(new InputElementDesc - { - SemanticName = (byte*)streamSemanticNameMemory, - SemanticIndex = 0, - Format = Format.FormatR32G32B32A32Float, - InputSlot = inputSlot, - AlignedByteOffset = 0, - InputSlotClass = InputClassification.PerInstanceData, - InstanceDataStepRate = 0, - }); - - // Also create the vertex and bind it right away - var floatValues = parameter.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries).Select(x => float.Parse(x)).ToArray(); - bufferDesc = new BufferDesc + ComPtr vertexBufferForStream = default; + fixed (float* floatValuesPtr = floatValues) + { + var subresourceData = new SubresourceData { - ByteWidth = (uint)(sizeof(float) * floatValues.Length), // up to 4 floats - Usage = Usage.Default, - BindFlags = (uint)BindFlag.VertexBuffer, + PSysMem = floatValuesPtr }; - ComPtr vertexBufferForStream = default; - fixed (float* floatValuesPtr = floatValues) - { - var subresourceData = new SubresourceData - { - PSysMem = floatValuesPtr - }; - - SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBufferForStream)); - } - - deviceContext.IASetVertexBuffers(inputSlot, 1, vertexBufferForStream, 0, 0); - inputSlot++; + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, in subresourceData, ref vertexBufferForStream)); } + + deviceContext.IASetVertexBuffers(inputSlot, 1, vertexBufferForStream, 0, 0); + inputSlot++; } + } - fixed (InputElementDesc* inputElementsPtr = inputElements.AsSpan()) - SilkMarshal.ThrowHResult + fixed (InputElementDesc* inputElementsPtr = inputElements.AsSpan()) + SilkMarshal.ThrowHResult + ( + device.CreateInputLayout ( - device.CreateInputLayout - ( - inputElementsPtr, - (uint)inputElements.Count, - vertexCode.GetBufferPointer(), - vertexCode.GetBufferSize(), - ref inputLayout - ) - ); - } + inputElementsPtr, + (uint)inputElements.Count, + vertexCode.GetBufferPointer(), + vertexCode.GetBufferSize(), + ref inputLayout + ) + ); + } - ComPtr renderTexture = default; - ComPtr renderTextureStaging = default; + ComPtr renderTexture = default; + ComPtr renderTextureStaging = default; - var textureDesc = new Texture2DDesc - { - Width = width, - Height = height, - Format = Format.FormatR8G8B8A8Unorm, - MipLevels = 1, - BindFlags = (uint)(BindFlag.ShaderResource | BindFlag.RenderTarget), - Usage = Usage.Default, - CPUAccessFlags = 0, - MiscFlags = (uint)ResourceMiscFlag.None, - SampleDesc = new SampleDesc(1, 0), - ArraySize = 1 - }; + var textureDesc = new Texture2DDesc + { + Width = width, + Height = height, + Format = Format.FormatR8G8B8A8Unorm, + MipLevels = 1, + BindFlags = (uint)(BindFlag.ShaderResource | BindFlag.RenderTarget), + Usage = Usage.Default, + CPUAccessFlags = 0, + MiscFlags = (uint)ResourceMiscFlag.None, + SampleDesc = new SampleDesc(1, 0), + ArraySize = 1 + }; - SilkMarshal.ThrowHResult + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D ( - device.CreateTexture2D - ( - in textureDesc, - default, - ref renderTexture - ) - ); + in textureDesc, + default, + ref renderTexture + ) + ); - textureDesc.BindFlags = 0; - textureDesc.Usage = Usage.Staging; - textureDesc.CPUAccessFlags = (uint)CpuAccessFlag.Read; + textureDesc.BindFlags = 0; + textureDesc.Usage = Usage.Staging; + textureDesc.CPUAccessFlags = (uint)CpuAccessFlag.Read; - SilkMarshal.ThrowHResult + SilkMarshal.ThrowHResult + ( + device.CreateTexture2D ( - device.CreateTexture2D - ( - in textureDesc, - default, - ref renderTextureStaging - ) - ); - - // Create a view over the render target. - ComPtr renderTargetView = default; - SilkMarshal.ThrowHResult(device.CreateRenderTargetView(renderTexture, null, ref renderTargetView)); - - // Clear the render target to be all black ahead of rendering. - var backgroundColour = new[] { 0.0f, 0.0f, 0.0f, 1.0f }; - deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]); - - // Update the rasterizer state with the current viewport. - var viewport = new Viewport(0, 0, width, height, 0, 1); - deviceContext.RSSetViewports(1, in viewport); - deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); - - // Update the input assembler to use our shader input layout, and associated vertex & index buffers. - deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); - deviceContext.IASetInputLayout(inputLayout); - deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); - deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); - - // Bind our shaders. - deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); - deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); - - ApplyParameters(); - - // Draw the quad. - deviceContext.DrawIndexed(6, 0, 0); - - deviceContext.CopyResource(renderTextureStaging, renderTexture); + in textureDesc, + default, + ref renderTextureStaging + ) + ); - MappedSubresource mappedResource = default; - deviceContext.Map(renderTextureStaging, 0, Map.MapRead, 0, ref mappedResource); - var span = new Span(mappedResource.PData, (int)(width * height * 4)); - span.CopyTo(result); - deviceContext.Unmap(renderTextureStaging, 0); + // Create a view over the render target. + ComPtr renderTargetView = default; + SilkMarshal.ThrowHResult(device.CreateRenderTargetView(renderTexture, null, ref renderTargetView)); - // Still do a copy to backbuffer and present, for debugging purpose (i.e. if we run RenderDoc or such debug tools) - var framebuffer = swapchain.GetBuffer(0); + // Clear the render target to be all black ahead of rendering. + var backgroundColour = new[] { 0.0f, 0.0f, 0.0f, 1.0f }; + deviceContext.ClearRenderTargetView(renderTargetView, ref backgroundColour[0]); - deviceContext.CopySubresourceRegion(framebuffer, 0, 0, 0, 0, renderTexture, 0, null); + // Update the rasterizer state with the current viewport. + var viewport = new Viewport(0, 0, width, height, 0, 1); + deviceContext.RSSetViewports(1, in viewport); + deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); - renderTextureStaging.Dispose(); - renderTexture.Dispose(); + // Update the input assembler to use our shader input layout, and associated vertex & index buffers. + deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); + deviceContext.IASetInputLayout(inputLayout); + deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); + deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); - renderTargetView.Dispose(); + // Bind our shaders. + deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); + deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); - framebuffer.Dispose(); + ApplyParameters(); - vertexCode.Dispose(); - pixelCode.Dispose(); - } + // Draw the quad. + deviceContext.DrawIndexed(6, 0, 0); + + deviceContext.CopyResource(renderTextureStaging, renderTexture); - // Present the drawn image. - swapchain.Present(1, 0); + MappedSubresource mappedResource = default; + deviceContext.Map(renderTextureStaging, 0, Map.MapRead, 0, ref mappedResource); + var span = new Span(mappedResource.PData, (int)(width * height * 4)); + span.CopyTo(result); + deviceContext.Unmap(renderTextureStaging, 0); - cts.Cancel(); - cts.Dispose(); + // Still do a copy to backbuffer and present, for debugging purpose (i.e. if we run RenderDoc or such debug tools) + var framebuffer = swapchain.GetBuffer(0); - window.Close(); - window.Dispose(); + deviceContext.CopySubresourceRegion(framebuffer, 0, 0, 0, 0, renderTexture, 0, null); + + renderTextureStaging.Dispose(); + renderTexture.Dispose(); + + renderTargetView.Dispose(); + + framebuffer.Dispose(); + + vertexCode.Dispose(); + pixelCode.Dispose(); } private unsafe void ApplyParameters() diff --git a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs index c7b4c10eee..4ee2add02a 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs @@ -77,7 +77,7 @@ static unsafe void DebugCallback(GLEnum source, GLEnum type, int id, GLEnum seve Debug.WriteLine($"[{severity}] {messageDecoded}"); } - public override unsafe void RenderFrame(Span result) + public unsafe void RenderFrame(Span result) { var options = WindowOptions.Default; options.Size = new Vector2D((int)width, (int)height); diff --git a/src/Stride.Shaders.Tests/FrameRenderer.cs b/src/Stride.Shaders.Tests/FrameRenderer.cs index 97be4e8d84..f3864d4cf3 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.cs @@ -56,6 +56,4 @@ protected static unsafe uint ParseColor(string value) ((color >> 24) & 0xff)); return color; } - - public abstract void RenderFrame(Span bytes); } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index be525cb989..a88551e019 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -79,6 +79,24 @@ public void ComputeTest1(string shaderName) var codeCS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.GLCompute)); Console.WriteLine(codeCS); + + // Execute test + var renderer = new D3D11FrameRenderer((uint)width, (uint)height); + + renderer.ComputeShaderSource = codeCS; + renderer.EffectReflection = effectReflection; + + var code = File.ReadAllLines($"./assets/SDSL/ComputeTests/{shaderName}.sdsl"); + foreach (var test in TestHeaderParser.ParseHeaders(code)) + { + var parameters = TestHeaderParser.ParseParameters(test.Parameters); + SetupTestParameters(renderer, parameters); + + renderer.SetupTest(); + renderer.Compute(); + // Present is useful for RenderDoc and other graphics capture programs + renderer.PresentAndFinish(); + } } [Theory] @@ -95,46 +113,34 @@ public void RenderTest1(string shaderName) // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); - - string? GetShaderCode(ExecutionModel executionModel) - { - return (entryPoints.Any(x => x.ExecutionModel == executionModel)) - ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == executionModel)) - : null; - } - - var codeCS = GetShaderCode(ExecutionModel.GLCompute); - var codePS = GetShaderCode(ExecutionModel.Fragment); - var codeVS = GetShaderCode(ExecutionModel.Vertex); + var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); + var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + : null; if (codeVS != null) Console.WriteLine(codeVS); - if (codePS != null) - Console.WriteLine(codePS); - if (codeCS != null) - Console.WriteLine(codeCS); + Console.WriteLine(codePS); // Execute test var renderer = new D3D11FrameRenderer((uint)width, (uint)height); + if (codeVS != null) + renderer.VertexShaderSource = codeVS; + renderer.PixelShaderSource = codePS; + renderer.EffectReflection = effectReflection; + var code = File.ReadAllLines($"./assets/SDSL/RenderTests/{shaderName}.sdsl"); foreach (var test in TestHeaderParser.ParseHeaders(code)) { - renderer.Parameters.Clear(); - - // Setup parameters var parameters = TestHeaderParser.ParseParameters(test.Parameters); - foreach (var param in parameters) - renderer.Parameters.Add(param.Key, param.Value); + SetupTestParameters(renderer, parameters); - renderer.ComputeShaderSource = codeCS; - renderer.PixelShaderSource = codePS; - if (codeVS != null) - renderer.VertexShaderSource = codeVS; - using var frameBuffer = MemoryOwner.Allocate(width * height * 4); - renderer.EffectReflection = effectReflection; + renderer.SetupTest(); renderer.RenderFrame(frameBuffer.Span); + // Present is useful for RenderDoc and other graphics capture programs + renderer.PresentAndFinish(); var pixels = Image.LoadPixelData(frameBuffer.Span, width, height); Assert.Equal(width, pixels.Width); Assert.Equal(height, pixels.Height); @@ -152,6 +158,14 @@ public void RenderTest1(string shaderName) } } + private static void SetupTestParameters(D3D11FrameRenderer renderer, Dictionary parameters) + { + // Setup parameters + renderer.Parameters.Clear(); + foreach (var param in parameters) + renderer.Parameters.Add(param.Key, param.Value); + } + public static IEnumerable GetRenderTestFiles() { foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/RenderTests")) diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index f635330b26..4d4056cf53 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -51,7 +51,7 @@ public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null); +public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, LoadedShaderSymbol? OwnerType = null); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index a57119ffd5..1a618e97aa 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -31,7 +31,12 @@ public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? /// /// Assign to l-value. /// - public virtual void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + public virtual void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue rvalue) + { + ThrowErrorOnLValue(); + } + + protected void ThrowErrorOnLValue() { throw new InvalidOperationException($"{this} is not a l-value and cannot be assigned to."); } @@ -67,33 +72,33 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public SpirvValue? MemberCall { get; set; } public bool IsBaseCall { get; set; } = false; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public SpirvValue CompileBaseOrThis(SymbolTable table, CompilerUnit compiler) { + // TODO: Move this to Identifer.Compile; however, we can't do it as long as we need to differentiate between OpThis and OpStage var (builder, context) = compiler; - - Symbol functionSymbol; - if (MemberCall != null) + var functionSymbol = ResolveFunctionSymbol(table, context); + if (IsBaseCall) { - var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) - throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); + return new(builder.InsertData(new OpBaseSDSL(context.Bound++)).IdResult.Value, 0); + } + else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) + { + var isStage = functionSymbol.Id.IsStage; + return isStage + ? new(builder.InsertData(new OpStageSDSL(context.Bound++)).IdResult.Value, 0) + : new(builder.InsertData(new OpThisSDSL(context.Bound++)).IdResult.Value, 0); } else { - functionSymbol = table.ResolveSymbol(Name); + throw new InvalidOperationException(); } + } - // Choose appropriate method to call - if (functionSymbol.Type is FunctionGroupType) - { - // Find methods matching number of parameters - var matchingMethods = functionSymbol.GroupMembers.Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; - // TODO: find proper overload (different signature) - // We take first element, so in case there is multiple override, it will take the most-derived implementation - // Note: this will be reevaluted during ShaderMixer (base/this, etc.) but it won't change overload (different signature) - functionSymbol = matchingMethods.First(); - } + var functionSymbol = ResolveFunctionSymbol(table, context); var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; @@ -204,6 +209,54 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return result; } + + private Symbol ResolveFunctionSymbol(SymbolTable table, SpirvContext context) + { + Symbol functionSymbol; + // Note: for now, TypeId 0 is used for this/base; let's improve that later + if (MemberCall != null && MemberCall.Value.TypeId != 0) + { + var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; + if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) + throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); + } + else + { + functionSymbol = table.ResolveSymbol(Name); + } + + // Choose appropriate method to call + if (functionSymbol.Type is FunctionGroupType) + { + // Find methods matching number of parameters + var matchingMethods = functionSymbol.GroupMembers.Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); + + // TODO: find proper overload (different signature) + // We take first element, so in case there is multiple override, it will take the most-derived implementation + // Note: this will be reevaluted during ShaderMixer (base/this, etc.) but it won't change overload (different signature) + functionSymbol = matchingMethods.First(); + } + + return functionSymbol; + } + + private Symbol ResolveSymbol(SymbolTable table, SpirvContext context) + { + Symbol functionSymbol; + if (MemberCall != null) + { + var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; + if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) + throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); + } + else + { + functionSymbol = table.ResolveSymbol(Name); + } + + return functionSymbol; + } + public override string ToString() { return $"{Name}({string.Join(", ", Parameters)})"; @@ -386,148 +439,74 @@ public class AccessorChainExpression(Expression source, TextLocation info) : Exp public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + private SpirvValue[] intermediateValues; + + public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue rvalue) { - var lvalue = CompileHelper(table, compiler, null, true, out var remainingIndex); - - if (remainingIndex == 0) - base.SetValue(table, compiler, value); - var (builder, context) = compiler; + // See how far we can compute the lvalue + CompileHelper(table, compiler, null); + // Only things left should be: // - RWBuffer/Texture setters // - Swizzles - // We do one pass forward to compute type and coalesce swizzle - int[]? swizzleIndices = null; - int swizzleIndicesSetByAccessor = -1; - - var currentValueType = Accessors[remainingIndex - 1].Type; - for (var i = remainingIndex; i < Accessors.Count; i++) + // Process from end + for (var i = Accessors.Count - 1; i >= 0; --i) { var accessor = Accessors[i]; - switch (currentValueType, accessor) - { - case (PointerType { BaseType: TextureType or BufferType } p, IndexerExpression indexer): - - accessor.Type = new VectorType(p.BaseType switch - { - BufferType b => b.BaseType, - TextureType t => t.ReturnType, - }, 4); - break; - case (PointerType { BaseType: VectorType or ScalarType } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - { - (var size, ScalarType baseType) = p.BaseType switch - { - ScalarType s => (1, s), - VectorType v => (v.Size, v.BaseType), - }; - - swizzleIndices = new int[swizzle.Length]; - swizzleIndicesSetByAccessor = i; - for (int j = 0; j < swizzle.Length; ++j) - { - swizzleIndices[j] = ConvertSwizzle(swizzle[j]); - if (swizzleIndices[j] >= size) - throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - } - - accessor.Type = p.BaseType; - - break; - } - case (VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - { - if (swizzleIndices == null || swizzleIndicesSetByAccessor != i - 1) - throw new InvalidOperationException("No previous swizzle but already value type on l-value"); - - (var size, ScalarType baseType) = currentValueType switch - { - ScalarType s => (1, s), - VectorType v => (v.Size, v.BaseType), - }; + var currentValueType = i > 0 ? Accessors[i - 1].Type : Source.Type; + var resultValueType = Accessors[i].Type; + var lvalueBase = intermediateValues[1 + i - 1]; + var lvalueResult = intermediateValues[1 + i]; - // Combine swizzles with previous ones - var newSwizzleIndices = new int[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - { - newSwizzleIndices[j] = swizzleIndices[ConvertSwizzle(swizzle[j])]; - if (newSwizzleIndices[j] >= size) - throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - } - - Accessors.RemoveAt(i--); - Span vectorFields = ['x', 'y', 'z', 'w']; - Span newSwizzle = stackalloc char[swizzle.Length]; - for (int j = 0; j < swizzle.Length; ++j) - { - newSwizzle[j] = vectorFields[newSwizzleIndices[j]]; - } - - Accessors[i] = accessor = new Identifier(new(newSwizzle), default); - - swizzleIndices = newSwizzleIndices; - swizzleIndicesSetByAccessor = 1; - accessor.Type = baseType.GetVectorOrScalar(swizzle.Length); - break; - } - default: - throw new NotImplementedException(); + // if lvalue is a pointer, we can simply assign to it + if (resultValueType is PointerType) + { + var expectedType = (PointerType)context.ReverseTypes[lvalueResult.TypeId]; + rvalue = builder.Convert(context, rvalue, expectedType.BaseType); + builder.Insert(new OpStore(lvalueResult.Id, rvalue.Id, null, [])); + return; } - - currentValueType = accessor.Type; - } - - // Process from end - for (var i = Accessors.Count - 1; i >= remainingIndex; --i) - { - var accessor = Accessors[i]; - currentValueType = Accessors[i - 1].Type; switch (currentValueType, accessor) { - case (PointerType { BaseType: BufferType b }, IndexerExpression indexer): - // Only allow if it's the last item to process - if (i != remainingIndex) - throw new NotImplementedException(); - + case (PointerType { BaseType: BufferType bufferType }, IndexerExpression indexer): throw new NotImplementedException(); - case (PointerType { BaseType: TextureType t }, IndexerExpression indexer): - // Only allow if it's the last item to process - if (i != remainingIndex) - throw new NotImplementedException(); - - var index = indexer.CompileAsValue(table, compiler); - builder.Insert(new OpImageWrite(lvalue.Id, index.Id, value.Id, null, [])); - break; - case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - // It should have been coalesced - throw new InvalidOperationException(); - case (PointerType { BaseType: VectorType } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): + // ImageWrite + case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): + var resultType = new VectorType(textureType.ReturnType, 4); + + var imageValue = builder.AsValue(context, lvalueBase); + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.From("int")); + var texelValue = builder.Convert(context, rvalue, resultType); + builder.Insert(new OpImageWrite(imageValue.Id, imageCoordValue.Id, texelValue.Id, null, [])); + // We stop there + return; + case (PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): // Swizzle: we transform the value to assign accordingly - if (i != remainingIndex) - // TODO: Handle more complex cases like texture[0].w += 3.0; - throw new NotImplementedException(); - currentValueType = p.BaseType; + // We load the original value (if pointer) + if (currentValueType is PointerType p) + { + rvalue = new(builder.InsertData(new OpLoad(context.GetOrRegister(currentValueType), context.Bound++, rvalue.Id, null, []))); + currentValueType = p.BaseType; + } - // We load the original value (in case we assign to only part of it, i.e. a.yz = 3.0;) - var targetValue = builder.Insert(new OpLoad(context.GetOrRegister(currentValueType), context.Bound++, lvalue.Id, null, [])).ResultId; - // Shuffle with new data - switch (p.BaseType) + switch (currentValueType) { case VectorType v: Span shuffleIndices = stackalloc int[v.Size]; - // Default: source values + // Default: lvalue for (int j = 0; j < v.Size; ++j) shuffleIndices[j] = j; // Update using swizzle target (from 2nd new value vector) for (int j = 0; j < swizzle.Length; ++j) shuffleIndices[ConvertSwizzle(swizzle[j])] = v.Size + j; - value = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(currentValueType), context.Bound++, targetValue, value.Id, new(shuffleIndices)))); + // Compute the rvalue at this step (by possibly combining with lvalue if not writing every component) + rvalue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(currentValueType), context.Bound++, lvalueBase.Id, rvalue.Id, new(shuffleIndices)))); break; default: throw new NotImplementedException(); @@ -535,19 +514,23 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal break; } } - - var expectedType = (PointerType)context.ReverseTypes[lvalue.TypeId]; - value = builder.Convert(context, value, expectedType.BaseType); - builder.Insert(new OpStore(lvalue.Id, value.Id, null, [])); + + // We should not reach this point (unless we can't write back to lvalue) + ThrowErrorOnLValue(); } public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - return CompileHelper(table, compiler, expectedType, false, out _); + return CompileHelper(table, compiler, expectedType); } - public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType, bool lvalue, out int remainingIndex) + public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType) { + if (intermediateValues != null) + return intermediateValues[^1]; + + intermediateValues = new SpirvValue[Accessors.Count + 1]; + var (builder, context) = compiler; SpirvValue result; @@ -557,14 +540,21 @@ public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, Symbol { if (Source is Identifier { Name: "base" }) methodCall.IsBaseCall = true; + result = methodCall.CompileBaseOrThis(table, compiler); + intermediateValues[0] = result; + + methodCall.IsBaseCall = false; + methodCall.MemberCall = result; result = methodCall.Compile(table, compiler); - currentValueType = methodCall.Type; + currentValueType = context.ReverseTypes[result.TypeId]; firstIndex = 1; + intermediateValues[1] = result; } else { result = Source.Compile(table, compiler); currentValueType = Source.Type; + intermediateValues[0] = result; } int accessChainIdCount = 0; @@ -572,14 +562,8 @@ void PushAccessChainId(Span accessChainIds, int accessChainIndex) { accessChainIds[accessChainIdCount++] = accessChainIndex; } - - void ThrowErrorOnLValue() - { - if (lvalue) - base.SetValue(table, compiler, default); - } - void EmitOpAccessChain(Span accessChainIds) + void EmitOpAccessChain(Span accessChainIds, int i) { // Do we need to issue an OpAccessChain? if (accessChainIdCount > 0) @@ -588,15 +572,66 @@ void EmitOpAccessChain(Span accessChainIds) var test = new LiteralArray(accessChainIds); var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); result = new SpirvValue(accessChain.ResultId, resultType); + + intermediateValues[1 + i] = result; } accessChainIdCount = 0; } + // If current and next accessors are swizzle, combine them + void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accessor) + { + if (i + 1 < Accessors.Count + && currentValueType is PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType + && Accessors[i] is Identifier { Name: var swizzle1 } id1 && id1.IsVectorSwizzle() + && Accessors[i + 1] is Identifier { Name: var swizzle2 } id2 && id2.IsVectorSwizzle()) + { + var vectorOrScalarType = currentValueType is PointerType p ? p.BaseType : currentValueType; + + (var size, ScalarType baseType) = vectorOrScalarType switch + { + ScalarType s => (1, s), + VectorType v => (v.Size, v.BaseType), + }; + + var swizzleIndices = new int[swizzle1.Length]; + for (int j = 0; j < swizzle1.Length; ++j) + { + swizzleIndices[j] = ConvertSwizzle(swizzle1[j]); + if (swizzleIndices[j] >= size) + throw new InvalidOperationException($"Swizzle {Accessors[i]} is out of bound for expression {ToString(i)} of type {vectorOrScalarType}"); + } + + // Combine swizzles with previous ones + var newSwizzleIndices = new int[swizzle2.Length]; + for (int j = 0; j < swizzle2.Length; ++j) + { + newSwizzleIndices[j] = swizzleIndices[ConvertSwizzle(swizzle2[j])]; + if (newSwizzleIndices[j] >= size) + throw new InvalidOperationException($"Swizzle {Accessors[i + 1]} is out of bound for expression {ToString(i)} of type {currentValueType}"); + } + + Accessors.RemoveAt(i + 1); + Span vectorFields = ['x', 'y', 'z', 'w']; + Span newSwizzle = stackalloc char[swizzle2.Length]; + for (int j = 0; j < swizzle2.Length; ++j) + { + newSwizzle[j] = vectorFields[newSwizzleIndices[j]]; + } + + Accessors[i] = accessor = new Identifier(new(newSwizzle), default); + } + } + Span accessChainIds = stackalloc int[Accessors.Count]; - for (var i = remainingIndex = firstIndex; i < Accessors.Count; remainingIndex = ++i) + + for (var i = firstIndex; i < Accessors.Count; ++i) { var accessor = Accessors[i]; + + CoalesceSwizzles(i, currentValueType, ref accessor); + switch (currentValueType, accessor) { case (PointerType { BaseType: TextureType textureType }, @@ -604,29 +639,17 @@ void EmitOpAccessChain(Span accessChainIds) or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 }): { - ThrowErrorOnLValue(); - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); var textureValue = builder.AsValue(context, result); - var textureCoordSize = textureType switch - { - Texture1DType => 1, - Texture2DType => 2, - Texture3DType or TextureCubeType => 3, - }; - var offsetSize = textureCoordSize; - if (textureType.Arrayed) - textureCoordSize++; if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } implicitSampling) { var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); - texCoordValue = builder.Convert(context, texCoordValue, ScalarType.From("float").GetVectorOrScalar(textureCoordSize)); - + var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); @@ -635,8 +658,7 @@ void EmitOpAccessChain(Span accessChainIds) EnumerantParameters imParams = []; if (implicitSampling.Parameters.Values.Count > 2) { - var offset = implicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); - offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + var offset = ConvertOffset(context, builder, textureType, implicitSampling.Parameters.Values[2].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset imask = ImageOperandsMask.Offset; imParams = new EnumerantParameters(offset.Id); @@ -651,8 +673,7 @@ void EmitOpAccessChain(Span accessChainIds) var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler); - texCoordValue = builder.Convert(context, texCoordValue, new VectorType(ScalarType.From("float"), textureCoordSize)); + var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); levelValue = builder.Convert(context, levelValue, ScalarType.From("float")); @@ -666,8 +687,7 @@ void EmitOpAccessChain(Span accessChainIds) if (explicitSampling.Parameters.Values.Count > 3) { - var offset = explicitSampling.Parameters.Values[3].CompileAsValue(table, compiler); - offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + var offset = ConvertOffset(context, builder, textureType, explicitSampling.Parameters.Values[3].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset imask = ImageOperandsMask.Lod | ImageOperandsMask.Offset; imParams = new EnumerantParameters(levelValue.Id, offset.Id); @@ -689,8 +709,7 @@ void EmitOpAccessChain(Span accessChainIds) throw new InvalidOperationException(); var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler); - texCoordValue = builder.Convert(context, texCoordValue, new VectorType(ScalarType.From("float"), textureCoordSize)); + var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); @@ -705,8 +724,7 @@ void EmitOpAccessChain(Span accessChainIds) if (sampleCompare.Parameters.Values.Count > 3) { - var offset = sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler); - offset = builder.Convert(context, offset, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + var offset = ConvertOffset(context, builder, textureType, sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset flags |= ImageOperandsMask.Offset; imParams = new EnumerantParameters([..imParams, offset.Id]); @@ -726,10 +744,8 @@ void EmitOpAccessChain(Span accessChainIds) } case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load): { - ThrowErrorOnLValue(); - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); var resultType = new VectorType(pointerType.BaseType switch { @@ -747,46 +763,31 @@ void EmitOpAccessChain(Span accessChainIds) } case (PointerType { BaseType: BufferType b }, IndexerExpression indexer): { - // Texture/Buffer writes are handled as l-value assign - if (lvalue) - { - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); - return result; - } - throw new NotImplementedException(); - - break; } - case (PointerType { BaseType: TextureType t }, IndexerExpression indexer): + case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): { - // Texture/Buffer writes are handled as l-value assign - if (lvalue) - { - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); - return result; - } + var resultType = new VectorType(textureType.ReturnType, 4); - var indexValue = indexer.CompileAsValue(table, compiler); - throw new NotImplementedException(); - //builder.Insert(new OpImageRead(lvalue.Id, indexValue.Id, value.Id, null, [])); + var imageValue = builder.AsValue(context, result); + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.From("int")); + var imageRead = builder.Insert(new OpImageRead(context.GetOrRegister(resultType), context.Bound++, imageValue.Id, imageCoordValue.Id, null, [])); + + result = new(imageRead.ResultId, imageRead.ResultType); + accessor.Type = resultType; break; } case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): - ThrowErrorOnLValue(); - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); methodCall2.MemberCall = result; result = methodCall2.Compile(table, compiler); break; case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); if (!s.TryResolveSymbol(table, context, field.Name, out var matchingComponent)) throw new InvalidOperationException(); @@ -794,9 +795,6 @@ void EmitOpAccessChain(Span accessChainIds) // TODO: figure out instance (this vs composition) result = Identifier.EmitSymbol(builder, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; - - if (accessor.Type is not PointerType) - ThrowErrorOnLValue(); break; case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now\ @@ -817,16 +815,8 @@ void EmitOpAccessChain(Span accessChainIds) case (PointerType { BaseType: VectorType v } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { - // Swizzle assignment is handled as l-value assign - if (lvalue) - { - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); - return result; - } - // Load value - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, []))); Span swizzleIndices = stackalloc int[swizzle.Length]; @@ -839,7 +829,7 @@ void EmitOpAccessChain(Span accessChainIds) (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); - accessor.Type = currentValueType; + accessor.Type = new VectorType(v.BaseType, swizzle.Length); } else { @@ -849,8 +839,6 @@ void EmitOpAccessChain(Span accessChainIds) break; case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): { - ThrowErrorOnLValue(); - Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { @@ -860,23 +848,15 @@ void EmitOpAccessChain(Span accessChainIds) } (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); - accessor.Type = v; + accessor.Type = v.BaseType.GetVectorOrScalar(swizzle.Length); break; } case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { - // Swizzle assignment is handled as l-value assign - if (lvalue) - { - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); - return result; - } - // Load value - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null, []))); Span swizzleIndices = stackalloc int[swizzle.Length]; @@ -888,7 +868,7 @@ void EmitOpAccessChain(Span accessChainIds) } (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); - accessor.Type = currentValueType; + accessor.Type = new VectorType(s, swizzle.Length); } else { @@ -900,10 +880,6 @@ void EmitOpAccessChain(Span accessChainIds) } break; case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): - // Swizzle assignment is handled differently - if (lvalue) - return result; - if (swizzle.Length > 1) { Span swizzleIndices = stackalloc int[swizzle.Length]; @@ -951,8 +927,6 @@ void EmitOpAccessChain(Span accessChainIds) // So we load the value into a variable and use normal path case (ArrayType or VectorType or MatrixType, IndexerExpression indexer): { - ThrowErrorOnLValue(); - // We need to load as a variable to use OpAccessChain accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(accessor.Type), context.Bound++); @@ -963,10 +937,8 @@ void EmitOpAccessChain(Span accessChainIds) } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { - ThrowErrorOnLValue(); - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, i - 1); var resultPointer = result; @@ -991,14 +963,44 @@ void EmitOpAccessChain(Span accessChainIds) } currentValueType = accessor.Type; + // only if OpAccessChain is emitted (otherwise there is no value) + if (accessChainIdCount == 0) + intermediateValues[1 + i] = result; } - EmitOpAccessChain(accessChainIds); + EmitOpAccessChain(accessChainIds, Accessors.Count - 1); Type = currentValueType; return result; } + + SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue, ScalarType baseType) + { + var textureCoordSize = textureType switch + { + Texture1DType => 1, + Texture2DType => 2, + Texture3DType or TextureCubeType => 3, + }; + if (textureType.Arrayed) + textureCoordSize++; + spirvValue = builder.Convert(context, spirvValue, baseType.GetVectorOrScalar(textureCoordSize)); + return spirvValue; + } + + SpirvValue ConvertOffset(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue) + { + var offsetSize = textureType switch + { + Texture1DType => 1, + Texture2DType => 2, + Texture3DType or TextureCubeType => 3, + }; + + spirvValue = builder.Convert(context, spirvValue, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + return spirvValue; + } private static int ConvertSwizzle(char c) => c switch diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 621a6e9abb..81b753ff7c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -364,19 +364,19 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, return result; } - public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue value) + public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue rvalue) { var (builder, context) = compiler; - value = builder.AsValue(context, value); + rvalue = builder.AsValue(context, rvalue); var target = CompileSymbol(table, builder, context, false); if (Type is not PointerType) // Throw exception (default behavior) - base.SetValue(table, compiler, value); + base.SetValue(table, compiler, rvalue); - value = builder.Convert(context, value, ((PointerType)Type).BaseType); - builder.Insert(new OpStore(target.Id, value.Id, null, [])); + rvalue = builder.Convert(context, rvalue, ((PointerType)Type).BaseType); + builder.Insert(new OpStore(target.Id, rvalue.Id, null, [])); } public override string ToString() diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index a78633b5f5..8f9f0b57a3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -297,6 +297,23 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); var methodsDefaultParameters = new Dictionary(); var structTypes = new List<(StructuredType Type, int ImportedId)>(); + + // Build full inheritance list + List inheritanceList = new(); + SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context, inheritanceList, ResolveStep.Compile); + + // Load all the inherited shaders + List inheritedShaderSymbols = new(); + foreach (var inheritedClass in inheritanceList) + inheritedShaderSymbols.Add(LoadAndCacheExternalShaderType(table, context, inheritedClass)); + + var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) + { + Variables = variables, + Methods = methods, + StructTypes = structTypes, + InheritedShaders = inheritedShaderSymbols, + }; foreach (var i in shaderBuffers.Context) { @@ -321,7 +338,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) throw new InvalidOperationException(); var resultType = typeInstruction.Data.IdResultType.Value; - var symbol = new Symbol(new(shaderBuffers.Context.Names[target2], SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2)); + var symbol = new Symbol(new(shaderBuffers.Context.Names[target2], SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2), OwnerType: shaderType); variables.Add((symbol, VariableFlagsMask.None)); } } @@ -337,7 +354,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte var variableType = shaderBuffers.Context.ReverseTypes[variable.ResultType]; var sid = new SymbolID(variableName, SymbolKind.Variable, variable.Flags.HasFlag(VariableFlagsMask.Stream) ? Storage.Stream : 0, IsStage: (variable.Flags & VariableFlagsMask.Stage) != 0); - variables.Add((new(sid, variableType, 0), variable.Flags)); + variables.Add((new(sid, variableType, 0, OwnerType: shaderType), variable.Flags)); } if (instruction.Op == Op.OpFunction) @@ -354,7 +371,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte MethodSymbolDefaultParameters? methodDefaultParameters = methodsDefaultParameters.TryGetValue(functionInstruction.ResultId, out var methodDefaultParametersValue) ? methodDefaultParametersValue : null; - methods.Add((new(sid, functionType, 0, MethodDefaultParameters: methodDefaultParameters), functionFlags)); + methods.Add((new(sid, functionType, 0, MethodDefaultParameters: methodDefaultParameters, OwnerType: shaderType), functionFlags)); } if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) @@ -363,22 +380,6 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte } } - // Build full inheritance list - List inheritanceList = new(); - SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context, inheritanceList, ResolveStep.Compile); - - // Load all the inherited shaders - List inheritedShaderSymbols = new(); - foreach (var inheritedClass in inheritanceList) - inheritedShaderSymbols.Add(LoadAndCacheExternalShaderType(table, context, inheritedClass)); - - var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) - { - Variables = variables, - Methods = methods, - StructTypes = structTypes, - InheritedShaders = inheritedShaderSymbols, - }; return shaderType; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index bd7e88e8a0..c4dc888ba2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -220,7 +220,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler }, IsStage: IsStaged ); - var symbol = new Symbol(sid, pointerType, variable); + var symbol = new Symbol(sid, pointerType, variable, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } @@ -321,7 +321,7 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler } } - var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type); + var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type, OwnerType: table.CurrentShader); if (firstDefaultParameter != -1) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index f4966ef5ec..924698dad0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -215,8 +215,6 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { var target = variable.Variable.Compile(table, compiler); var source = variable.Value!.CompileAsValue(table, compiler); - if (variable.Variable.Type is not PointerType p) - throw new InvalidOperationException("can only assign to pointer type"); if (variable.Operator != AssignOperator.Simple) { @@ -241,7 +239,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } // Make sure to convert to proper type - var resultType = target.GetValueType(context, true); + var resultType = target.GetValueType(context); source = builder.Convert(context, source, resultType); variable.Variable.SetValue(table, compiler, source); diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index a05b56f1f1..a562e406c0 100644 --- a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs +++ b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs @@ -34,7 +34,7 @@ public SpirvValue(OpData instruction, string? name = null) public int TypeId { get; set; } public string? Name { get; set; } - public SymbolType GetValueType(SpirvContext context, bool includeSwizzles) + public SymbolType GetValueType(SpirvContext context) { var type = context.ReverseTypes[TypeId]; if (type is PointerType p) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index fe51e8203f..f1a6d925f6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -350,7 +350,10 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy valueType = v1.BaseType; break; } - case (VectorType v1, VectorType v2) when v1.Size <= v2.Size: + case (VectorType v1, VectorType v2) when v1.Size == v2.Size: + values[0] = valueId; + break; + case (VectorType v1, VectorType v2) when v1.Size < v2.Size: throw new InvalidOperationException($"Can't cast from {v1} to {v2} (more components)"); case (VectorType v1, VectorType v2) when v1.Size > v2.Size: { From 12de0fe3b51d371df7d747c545bc937c1827ce3d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 17 Jan 2026 00:00:56 +0900 Subject: [PATCH 0724/1182] Simplified base/this (no more specific handling in AccessChainExpression) --- .../SDSL/ShaderMixer.cs | 17 ++--- .../Parsing/SDSL/AST/Expression.cs | 65 +++---------------- .../Parsing/SDSL/AST/Literals.cs | 19 ++++-- 3 files changed, 27 insertions(+), 74 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 84f80adb58..7fe3404a57 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -704,12 +704,9 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte // Find out the proper mixin node (the member instance) var isThis = thisInstructions.Contains(memberAccess.Instance); var isBase = baseInstructions.Contains(memberAccess.Instance); - var isStage = stageInstructions.Contains(memberAccess.Instance); MixinNode instanceMixinGroup; if (isThis || isBase) instanceMixinGroup = mixinNode; - else if (isStage) - instanceMixinGroup = mixinNode.Stage ?? mixinNode; else { if (!compositionArrayAccesses.TryGetValue(memberAccess.Instance, out instanceMixinGroup) @@ -725,13 +722,9 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (!shaderInfo.Variables.TryGetValue(variable.Name, out var variableInfo)) { // Try as a stage variable - if (instanceMixinGroup.Stage != null + if (!(instanceMixinGroup.Stage != null && instanceMixinGroup.Stage.ShadersByName.TryGetValue(shaderName, out shaderInfo) - && shaderInfo.Variables.TryGetValue(variable.Name, out variableInfo)) - { - - } - else + && shaderInfo.Variables.TryGetValue(variable.Name, out variableInfo))) { throw new InvalidOperationException($"External variable {variable.Name} not found"); } @@ -743,8 +736,12 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte // In case of functions, OpMemberAccessSDSL.Member could either be a OpFunction or a OpImportFunctionSDSL var functionId = memberAccess.Member; if (globalContext.ExternalFunctions.TryGetValue(memberAccess.Member, out var function)) + { // Process member call (composition) - functionId = instanceMixinGroup.MethodGroupsByName[(function.Name, functionType)]; + if (!instanceMixinGroup.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId) + && (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId))) + throw new InvalidOperationException($"Can't find function ID for {context.Names[functionId]}"); + } bool foundInStage = false; if (!instanceMixinGroup.MethodGroups.TryGetValue(functionId, out var methodGroupEntry)) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 1a618e97aa..ae59c6d83c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -70,29 +70,6 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public ShaderExpressionList Parameters = parameters; public SpirvValue? MemberCall { get; set; } - public bool IsBaseCall { get; set; } = false; - - public SpirvValue CompileBaseOrThis(SymbolTable table, CompilerUnit compiler) - { - // TODO: Move this to Identifer.Compile; however, we can't do it as long as we need to differentiate between OpThis and OpStage - var (builder, context) = compiler; - var functionSymbol = ResolveFunctionSymbol(table, context); - if (IsBaseCall) - { - return new(builder.InsertData(new OpBaseSDSL(context.Bound++)).IdResult.Value, 0); - } - else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) - { - var isStage = functionSymbol.Id.IsStage; - return isStage - ? new(builder.InsertData(new OpStageSDSL(context.Bound++)).IdResult.Value, 0) - : new(builder.InsertData(new OpThisSDSL(context.Bound++)).IdResult.Value, 0); - } - else - { - throw new InvalidOperationException(); - } - } public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { @@ -172,16 +149,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, { instance = MemberCall.Value.Id; } - else if (IsBaseCall) - { - instance = builder.Insert(new OpBaseSDSL(context.Bound++)).ResultId; - } else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) { - var isStage = functionSymbol.Id.IsStage; - instance = isStage - ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId - : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; } if (instance is int instanceId) @@ -534,28 +504,9 @@ public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, Symbol var (builder, context) = compiler; SpirvValue result; - int firstIndex = 0; - SymbolType currentValueType; - if ((Source is Identifier { Name: "base" } || Source is Identifier { Name: "this" }) && Accessors[0] is MethodCall methodCall) - { - if (Source is Identifier { Name: "base" }) - methodCall.IsBaseCall = true; - result = methodCall.CompileBaseOrThis(table, compiler); - intermediateValues[0] = result; - - methodCall.IsBaseCall = false; - methodCall.MemberCall = result; - result = methodCall.Compile(table, compiler); - currentValueType = context.ReverseTypes[result.TypeId]; - firstIndex = 1; - intermediateValues[1] = result; - } - else - { - result = Source.Compile(table, compiler); - currentValueType = Source.Type; - intermediateValues[0] = result; - } + result = Source.Compile(table, compiler); + var currentValueType = Source.Type; + intermediateValues[0] = result; int accessChainIdCount = 0; void PushAccessChainId(Span accessChainIds, int accessChainIndex) @@ -626,7 +577,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso Span accessChainIds = stackalloc int[Accessors.Count]; - for (var i = firstIndex; i < Accessors.Count; ++i) + for (var i = 0; i < Accessors.Count; ++i) { var accessor = Accessors[i]; @@ -778,12 +729,12 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } - case (PointerType { BaseType: ShaderSymbol s }, MethodCall methodCall2): + case (_, MethodCall methodCall): // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - methodCall2.MemberCall = result; - result = methodCall2.Compile(table, compiler); + methodCall.MemberCall = result; + result = methodCall.Compile(table, compiler); break; case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): // Emit OpAccessChain with everything so far diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 81b753ff7c..020d18ebf7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -271,6 +271,17 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) { + if (Name == "this") + { + var result = builder.Insert(new OpThisSDSL(context.Bound++)); + return new(result.ResultId, 0); + } + if (Name == "base") + { + var result = builder.Insert(new OpBaseSDSL(context.Bound++)); + return new(result.ResultId, 0); + } + if (Name == "streams") { var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); @@ -343,13 +354,7 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, if (constantOnly) throw new NotImplementedException(); - var isStage = symbol.Id.IsStage; - if (instance == null) - { - instance = isStage - ? builder.Insert(new OpStageSDSL(context.Bound++)).ResultId - : builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; - } + instance ??= builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; result.Id = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(thisType), context.Bound++, instance.Value, result.Id)); } if (symbol.AccessChain is int accessChainIndex) From 474ab16db45c8d9fe646c99e1361cc02188cbcb7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 19 Jan 2026 22:06:21 +0900 Subject: [PATCH 0725/1182] Progress on StructuredBuffer --- assets/SDSL/ComputeTests/CSEmpty.sdsl | 11 +- .../SDSL/ShaderMixer.CBuffers.cs | 169 ++++++++++-------- .../SDSL/ShaderMixer.Reflection.cs | 26 ++- .../SpirvTranslator.cs | 2 + src/Stride.Shaders/Core/SymbolTypes.cs | 82 +++++---- .../Parsing/SDSL/AST/Expression.cs | 14 +- .../Parsing/SDSL/AST/Literals.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 12 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 + .../Spirv/Building/Builder.CBuffer.cs | 54 ++++-- .../Spirv/Building/SpirvContext.Types.cs | 15 ++ .../Spirv/Processing/InterfaceProcessor.cs | 2 +- 12 files changed, 259 insertions(+), 137 deletions(-) diff --git a/assets/SDSL/ComputeTests/CSEmpty.sdsl b/assets/SDSL/ComputeTests/CSEmpty.sdsl index a577e5868e..1ba6daf981 100644 --- a/assets/SDSL/ComputeTests/CSEmpty.sdsl +++ b/assets/SDSL/ComputeTests/CSEmpty.sdsl @@ -9,12 +9,19 @@ shader CSEmpty stage stream uint3 GroupThreadId : SV_GroupThreadID; stage stream uint GroupIndex : SV_GroupIndex; + struct Test + { + float3 A1; + float2 A2; + }; + RWTexture2D Output; - //RWStructuredBuffer Output; + RWStructuredBuffer Output2; [numthreads(32, 32, 1)] void CSMain() { - Output[int2(0, 0)].zx += float2(0,1); + Output[int2(0, 0)].zx = float2(0,1); + Output2[3].A2 = float2(0,1); } } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index c7e918d504..a6eb5da41f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -17,6 +17,8 @@ namespace Stride.Shaders.Compilers.SDSL { partial class ShaderMixer { + public Dictionary decoratedArraysAndStructs = new(); + private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) { var members = new List(); @@ -195,7 +197,6 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri { var cbufferStructId = context.Types[cbufferStruct]; int mergedMemberIndex = 0; - var links = new string[cbufferStruct.Members.Count]; foreach (ref var cbuffer in cbuffersSpan) { for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) @@ -334,98 +335,116 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri SpirvBuilder.RemapIds(context.GetBuffer(), 0, context.GetBuffer().Count, idRemapping); } - private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + EffectTypeDescription ConvertStructType(SpirvContext context, StructType s, SpirvBuilder.AlignmentRules alignmentRules) { - var cbuffers = buffer - .Where(x => x.Op == Op.OpVariableSDSL) - // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset - .Select(x => ( - Variable: x, - StructTypePtrId: x.Data.IdResultType.Value, - StructType: context.ReverseTypes[x.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, - MemberIndexOffset: 0)) - .Where(x => x.StructType != null) - .ToList(); - - EffectTypeDescription ConvertStructType(SpirvContext context, StructType s) + var structId = context.Types[s]; + if (decoratedArraysAndStructs.TryGetValue(structId, out var existingAlignmentRules)) { - var structId = context.Types[s]; - - var hasOffsetDecorations = false; - foreach (var i in context) + if (existingAlignmentRules != alignmentRules) + throw new InvalidOperationException($"Using type {s.ToId()} with both {alignmentRules} and {existingAlignmentRules} rules"); + } + else + decoratedArraysAndStructs.Add(structId, alignmentRules); + + var hasOffsetDecorations = false; + foreach (var i in context) + { + if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: Decoration.Offset } memberDecorate && memberDecorate.StructureType == structId) { - if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: Decoration.Offset } memberDecorate && memberDecorate.StructureType == structId) - { - hasOffsetDecorations = true; - break; - } + hasOffsetDecorations = true; + break; } + } - var members = new EffectTypeMemberDescription[s.Members.Count]; - var offset = 0; - for (int i = 0; i < s.Members.Count; ++i) - { - var memberSize = SpirvBuilder.ComputeCBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset); + var members = new EffectTypeMemberDescription[s.Members.Count]; + var offset = 0; + for (int i = 0; i < s.Members.Count; ++i) + { + var memberSize = SpirvBuilder.ComputeBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset, alignmentRules).Size; - members[i] = new EffectTypeMemberDescription - { - Name = s.Members[i].Name, - Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier), - Offset = offset, - }; + members[i] = new EffectTypeMemberDescription + { + Name = s.Members[i].Name, + Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier, alignmentRules), + Offset = offset, + }; - // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way - if (!hasOffsetDecorations) - DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); + // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way + if (!hasOffsetDecorations) + DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); - offset += memberSize; - } - return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; + offset += memberSize; } + return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; + } - - EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier) + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) + { + return symbolType switch + { + ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ArrayType a => ConvertArrayType(context, a, typeModifier, alignmentRules), + StructType s => ConvertStructType(context, s, alignmentRules), + // TODO: should we use RowCount instead? (need to update Stride) + VectorType v => ConvertType(context, v.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.Vector, RowCount = 1, ColumnCount = v.Size }, + // Note: this is HLSL-style so Rows/Columns meaning is swapped + // however, for type/class, both TypeModifier and EffectParameterType are following HLSL + MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None + => ConvertType(context, m.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Columns, ColumnCount = m.Rows }, + MatrixType m when typeModifier == TypeModifier.RowMajor + => ConvertType(context, m.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Columns, ColumnCount = m.Rows }, + }; + + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { - return symbolType switch + var typeId = context.Types[a]; + if (decoratedArraysAndStructs.TryGetValue(typeId, out var existingAlignmentRules)) { - ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ArrayType a => ConvertArrayType(context, a, typeModifier), - StructType s => ConvertStructType(context, s), - // TODO: should we use RowCount instead? (need to update Stride) - VectorType v => ConvertType(context, v.BaseType, typeModifier) with { Class = EffectParameterClass.Vector, RowCount = 1, ColumnCount = v.Size }, - // Note: this is HLSL-style so Rows/Columns meaning is swapped - // however, for type/class, both TypeModifier and EffectParameterType are following HLSL - MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Columns, ColumnCount = m.Rows }, - MatrixType m when typeModifier == TypeModifier.RowMajor - => ConvertType(context, m.BaseType, typeModifier) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Columns, ColumnCount = m.Rows }, - }; + if (existingAlignmentRules != alignmentRules) + throw new InvalidOperationException($"Using type {a.ToId()} with both {alignmentRules} and {existingAlignmentRules} rules"); + } + else + decoratedArraysAndStructs.Add(typeId, alignmentRules); + + var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); - EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier) + var hasStrideDecoration = false; + foreach (var i in context) { - var typeId = context.Types[a]; - var elementType = ConvertType(context, a.BaseType, typeModifier); - - var hasStrideDecoration = false; - foreach (var i in context) + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ArrayStride } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ArrayStride } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) - { - hasStrideDecoration = true; - } + hasStrideDecoration = true; } + } - if (!hasStrideDecoration) + if (!hasStrideDecoration) + { + var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size; + var arrayStride = alignmentRules switch { - var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier).Size; - var arrayStride = (elementSize + 15) / 16 * 16; - context.Add(new OpDecorate(typeId, Decoration.ArrayStride, [arrayStride])); - } - - return elementType with { Elements = a.Size }; + SpirvBuilder.AlignmentRules.CBuffer => (elementSize + 15) / 16 * 16, + SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, + }; + context.Add(new OpDecorate(typeId, Decoration.ArrayStride, [arrayStride])); } + + return elementType with { Elements = a.Size }; } + } + + private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + { + var cbuffers = buffer + .Where(x => x.Op == Op.OpVariableSDSL) + // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset + .Select(x => ( + Variable: x, + StructTypePtrId: x.Data.IdResultType.Value, + StructType: context.ReverseTypes[x.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, + MemberIndexOffset: 0)) + .Where(x => x.StructType != null) + .ToList(); foreach (var cbuffer in cbuffers) { @@ -441,7 +460,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo { // Properly compute size and offset according to DirectX rules var member = cb.Members[index]; - var memberSize = SpirvBuilder.ComputeCBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset); + var memberSize = SpirvBuilder.ComputeBufferOffset(member.Type, member.TypeModifier, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer).Size; DecorateMember(context, structTypeId, index, constantBufferOffset, memberSize, member.Type, member.TypeModifier); @@ -449,7 +468,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo memberInfos[index] = new EffectValueDescription { - Type = ConvertType(context, member.Type, member.TypeModifier), + Type = ConvertType(context, member.Type, member.TypeModifier, SpirvBuilder.AlignmentRules.CBuffer), RawName = member.Name, KeyInfo = new EffectParameterKeyInfo { KeyName = linkInfo.Link }, Offset = constantBufferOffset, diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index a3785c28b7..87dd3b1358 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -14,7 +15,7 @@ public partial class ShaderMixer private Dictionary cbufferMemberLinks = new(); private static bool IsResourceType(SymbolType type) - => type is TextureType or SamplerType or BufferType or ConstantBufferSymbol; + => type is TextureType or SamplerType or BufferType or StructuredBufferType or ConstantBufferSymbol; // Process LinkSDSL, ResourceGroupSDSL and LogicalGroupSDSL; Info will be stored in resourceLinks and cbufferMemberLinks private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) @@ -130,7 +131,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont : shader.ShaderName; } else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is - { Storageclass: Specification.StorageClass.UniformConstant } variable) + { Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer } variable) { // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore var type = context.ReverseTypes[variable.ResultType]; @@ -293,7 +294,6 @@ or Specification.Decoration.SamplerStateMinLOD if (variableType is TextureType t) { - var slot = globalContext.Reflection.ResourceBindings.Count; globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with { Class = EffectParameterClass.ShaderResourceView, @@ -316,7 +316,6 @@ or Specification.Decoration.SamplerStateMinLOD } else if (variableType is BufferType) { - var slot = globalContext.Reflection.ResourceBindings.Count; globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with { Class = EffectParameterClass.ShaderResourceView, @@ -330,6 +329,25 @@ or Specification.Decoration.SamplerStateMinLOD srvSlot++; } + else if (variableType is StructuredBufferType structuredBufferType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Class = EffectParameterClass.ShaderResourceView, + Type = structuredBufferType.WriteAllowed ? EffectParameterType.RWStructuredBuffer : EffectParameterType.StructuredBuffer, + SlotStart = srvSlot, + SlotCount = 1, + }); + + var baseType = structuredBufferType.BaseType; + // This will add array stride and offsets decorations + ConvertType(context, baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer); + + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); + + srvSlot++; + } else if (variableType is SamplerType) { globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index b5fcbdf1fa..7fe801569e 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -80,6 +80,7 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam CompilerOptions* compilerOptions = null; cross.CompilerCreateCompilerOptions(compiler, ref compilerOptions); cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50); + cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.HlslPreserveStructuredBuffers, 1); cross.CompilerInstallCompilerOptions(compiler, compilerOptions); } @@ -95,6 +96,7 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam // HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself) if (backend == Backend.Hlsl) { + ReflectedResource* resourcesList; nuint resourcesCount; cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourcesList, &resourcesCount); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 86af872e7d..1ad0dbe061 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -54,46 +54,53 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT return false; } } - public static bool TryGetBufferType(string name, string? templateTypeName, [MaybeNullWhen(false)] out SymbolType result) + public static bool TryGetBufferType(SymbolTable table, SpirvContext context, string name, TypeName? templateTypeName, [MaybeNullWhen(false)] out SymbolType result) { - SymbolType? templateType = null; - if (templateTypeName != null && !SymbolType.TryGetNumeric(templateTypeName, out templateType)) + // Special case: StructuredBuffer allows non vector/scalar types so treat it earlier + switch (name) { - result = null; - return false; + case "StructuredBuffer": + case "RWStructuredBuffer": + var templateType = templateTypeName.ResolveType(table, context); + result = new StructuredBufferType(templateType, name.StartsWith("RW")); + return true; } - if (templateType == null) - templateType = ScalarType.From("float"); - - var scalarType = templateType switch + // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) + static ScalarType ResolveScalarType(SymbolTable table, SpirvContext context, TypeName? templateTypeName) { - VectorType v => v.BaseType, - ScalarType s => s, - }; + var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.From("float4"); - SymbolType? foundType = (name, scalarType) switch + return templateType switch + { + VectorType v => v.BaseType, + ScalarType s => s, + }; + } + + SymbolType? foundType = name switch { - ("Buffer", ScalarType { TypeName: "float" or "int" or "uint" }) => new BufferType(scalarType), - - ("Texture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType), - ("Texture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType), - ("Texture2DMS", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Multisampled = true }, - ("Texture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType), - ("TextureCube", ScalarType { TypeName: "float" or "int" or "uint" }) => new TextureCubeType(scalarType), + "Buffer" => new BufferType(ResolveScalarType(table, context, templateTypeName)), + "RWBuffer" => new BufferType(ResolveScalarType(table, context, templateTypeName), true), + + "Texture1D" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)), + "Texture2D" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)), + "Texture2DMS" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Multisampled = true }, + "Texture3D" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)), + "TextureCube" => new TextureCubeType(ResolveScalarType(table, context, templateTypeName)), - ("Texture1DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Arrayed = true }, - ("Texture2DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Arrayed = true }, - ("Texture2DMSArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Multisampled = true, Arrayed = true }, - ("Texture3DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType) { Arrayed = true }, - ("TextureCubeArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new TextureCubeType(scalarType) { Arrayed = true }, - - ("RWTexture1D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Sampled = 2 }, - ("RWTexture2D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Sampled = 2 }, - ("RWTexture3D", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture3DType(scalarType) { Sampled = 2 }, - - ("RWTexture1DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture1DType(scalarType) { Sampled = 2, Arrayed = true }, - ("RWTexture2DArray", ScalarType { TypeName: "float" or "int" or "uint" }) => new Texture2DType(scalarType) { Sampled = 2, Arrayed = true }, + "Texture1DArray" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, + "Texture2DArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, + "Texture2DMSArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Multisampled = true, Arrayed = true }, + "Texture3DArray" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, + "TextureCubeArray" => new TextureCubeType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, + + "RWTexture1D" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, + "RWTexture2D" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, + "RWTexture3D" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, + + "RWTexture1DArray" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2, Arrayed = true }, + "RWTexture2DArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2, Arrayed = true }, _ => null, }; @@ -197,9 +204,16 @@ public sealed partial record StructType(string Name, List public override string ToString() => $"struct {base.ToString()}"; } -public sealed partial record BufferType(ScalarType BaseType) : SymbolType() +public sealed partial record StructuredBufferType(SymbolType BaseType, bool WriteAllowed = false) : StructuredType($"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +{ + public override string ToId() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>"; + + public override string ToString() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType}>"; +} + +public sealed partial record BufferType(ScalarType BaseType, bool WriteAllowed = false) : SymbolType() { - public override string ToString() => $"Buffer<{BaseType}>"; + public override string ToString() => $"{(WriteAllowed ? "RW" : "")}Buffer<{BaseType}>"; } // TODO: Add sampler parameters diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index ae59c6d83c..6c3a6b3bdf 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -575,7 +575,8 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } } - Span accessChainIds = stackalloc int[Accessors.Count]; + // Some accessors push up to 2 values on the stack + Span accessChainIds = stackalloc int[Accessors.Count * 2]; for (var i = 0; i < Accessors.Count; ++i) { @@ -716,6 +717,17 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { throw new NotImplementedException(); } + case (PointerType { BaseType: StructuredBufferType bufferType }, IndexerExpression indexer): + { + // StructuredBuffer are declared as OpTypeStruct { OpTypeRuntimeArray } + // so first, we push a 0 to access the OpTypeRuntimeArray + PushAccessChainId(accessChainIds, context.CompileConstant(0).Id); + // Then we push the index inside the array + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); + break; + } case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): { var resultType = new VectorType(textureType.ReturnType, 4); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 020d18ebf7..7b28ae4c72 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -466,12 +466,12 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh table.DeclaredTypes.Add(fullTypeName, numeric); symbolType = numeric; } - else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) + else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(table, context, Name, null, out var bufferType)) { table.DeclaredTypes.Add(fullTypeName, bufferType); symbolType = bufferType; } - else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0].Name, out var genericBufferType)) + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(table, context, Name, Generics[0], out var genericBufferType)) { table.DeclaredTypes.Add(fullTypeName, genericBufferType); symbolType = genericBufferType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 8f9f0b57a3..85e6ca50f9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -152,11 +152,17 @@ void RegisterName(int target, string name) { var fieldData = fieldsData.Words[index]; var type = context.ReverseTypes[fieldData]; - var name = memberNames[(typeStructInstruction.ResultId, index)]; + if (!memberNames.TryGetValue((typeStructInstruction.ResultId, index), out var name)) + name = $"_member{index}"; fields.Add(new(name, type, TypeModifier.None)); } StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) - ? new ConstantBufferSymbol(structName.StartsWith("type.") ? structName.Substring("type.".Length) : throw new InvalidOperationException(), fields) + ? structName switch + { + var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type), + var s when s.StartsWith("type.") => new ConstantBufferSymbol(structName.Substring("type.".Length), fields), + _ => throw new InvalidOperationException(), + } : new StructType(structName, fields); RegisterType(typeStructInstruction.ResultId, structType); } @@ -512,6 +518,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) : Specification.StorageClass.Uniform; if (memberType is TextureType || memberType is BufferType) storageClass = Specification.StorageClass.UniformConstant; + if (memberType is StructuredBufferType) + storageClass = Specification.StorageClass.StorageBuffer; if (svar.TypeModifier == TypeModifier.Const) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c4dc888ba2..e1ed8237b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -206,6 +206,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); + if (pointerType.BaseType is StructuredBufferType) + { + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"structuredbuffer:<{pointerType.BaseType.ToId().ToLowerInvariant()}>")); + } + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); var sid = diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 95dd8ff9ab..691527cdfe 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -8,60 +8,82 @@ namespace Stride.Shaders.Spirv.Building; partial class SpirvBuilder { - public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, TypeModifier typeModifier) + public enum AlignmentRules + { + CBuffer, + StructuredBuffer, + } + + public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, TypeModifier typeModifier, AlignmentRules alignmentRules) { // Helper to multiply size without changing alignment static (int Size, int Alignment) MultiplySize((int Size, int Alignment) current, int count) => (current.Size * count, current.Alignment); - static (int Size, int Alignment) Array((int Size, int Alignment) current, int count) => ((current.Size + 15) / 16 * 16 * (count - 1) + current.Size, 16); + + static (int Size, int Alignment) Array((int Size, int Alignment) current, int count, AlignmentRules alignmentRules) => alignmentRules switch + { + AlignmentRules.CBuffer => ((current.Size + 15) / 16 * 16 * (count - 1) + current.Size, 16), + AlignmentRules.StructuredBuffer => (current.Size * count, current.Alignment), + }; return (symbol) switch { ScalarType { TypeName: "sbyte" or "byte" } => (1, 1), ScalarType { TypeName: "short" or "ushort" } => (2, 2), ScalarType { TypeName: "int" or "uint" or "float" or "bool" } => (4, 4), ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 8), - StructuredType s => StructSizeInBuffer(s), - VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier), v.Size), + StructuredType s => StructSizeInBuffer(s, alignmentRules), + VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules), v.Size), // Note: this is HLSL-style so Rows/Columns meaning is swapped // Note: HLSL default is ColumnMajor MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Rows - 1)) + m.Columns), + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), alignmentRules == AlignmentRules.CBuffer ? (4 * (m.Rows - 1)) + m.Columns : m.Rows * m.Columns * 4), MatrixType m when typeModifier == TypeModifier.RowMajor - => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier), (4 * (m.Columns - 1)) + m.Rows), + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), alignmentRules == AlignmentRules.CBuffer ? (4 * (m.Columns - 1)) + m.Rows : m.Rows * m.Columns * 4), // Round up to 16 bytes (size of float4) - ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier), a.Size), + ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules), a.Size, alignmentRules), // TODO: StructureType }; } - private static (int, int) StructSizeInBuffer(StructuredType s) + private static (int, int) StructSizeInBuffer(StructuredType s, AlignmentRules alignmentRules) { var offset = 0; + var maxAlignment = 0; // Apply same rules as inside a cbuffer foreach (var member in s.Members) { - var memberSize = ComputeCBufferOffset(member.Type, member.TypeModifier, ref offset); - offset += memberSize; + var memberSizeAndAlignment = ComputeBufferOffset(member.Type, member.TypeModifier, ref offset, alignmentRules); + offset += memberSizeAndAlignment.Size; + maxAlignment = Math.Max(memberSizeAndAlignment.Alignment, maxAlignment); } - return (offset, 16); + var alignment = alignmentRules switch + { + AlignmentRules.CBuffer => 16, + AlignmentRules.StructuredBuffer => maxAlignment, + }; + + return (offset, alignment); } // // Computes the size of a member type, including its alignment and array size. // It does so recursively for structs, and handles different parameter classes. // - public static int ComputeCBufferOffset(SymbolType type, TypeModifier typeModifier, ref int constantBufferOffset) + public static (int Size, int Alignment) ComputeBufferOffset(SymbolType type, TypeModifier typeModifier, ref int constantBufferOffset, AlignmentRules alignmentRules) { - (var size, var alignment) = TypeSizeInBuffer(type, typeModifier); + (var size, var alignment) = TypeSizeInBuffer(type, typeModifier, alignmentRules); // Align to float4 if it is bigger than leftover space in current float4 - if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16) - alignment = 16; + if (alignmentRules == AlignmentRules.CBuffer) + { + if (constantBufferOffset / 16 != (constantBufferOffset + size - 1) / 16) + alignment = 16; + } // Align offset and store it as member offset constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment; - return size; + return (size, alignment); } } diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index 16bc757fbd..ceaca9a5c6 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -56,6 +56,7 @@ public int GetOrRegister(SymbolType? type) SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Specification.Dim.Buffer, 2, 0, 0, 1, Specification.ImageFormat.Unknown, null)).IdResult, + StructuredBufferType b => RegisterStructuredBufferType(b), SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(Bound++)).IdResult, @@ -68,6 +69,20 @@ public int GetOrRegister(SymbolType? type) } } + private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) + { + var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).IdResult.Value; + + var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).IdResult.Value; + AddName(bufferType, $"type.StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); + Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); + + // TODO: Add array stride and offsets + Buffer.Add(new OpDecorate(bufferType, Specification.Decoration.Block, [])); + + return bufferType; + } + private int? RegisterArrayType(ArrayType a) { int sizeId; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index e7b6a29e78..88475caebb 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -570,7 +570,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant, + Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, ResultId: int } resource) { From f11503bad5e808083ab95a577e8007c46f2e803f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 20 Jan 2026 09:18:54 +0900 Subject: [PATCH 0726/1182] Separated code to add struct/array decorations --- .../SDSL/ShaderMixer.CBuffers.cs | 70 ++------------- .../SDSL/ShaderMixer.Decorations.cs | 87 +++++++++++++++++++ .../SDSL/ShaderMixer.Reflection.cs | 3 +- 3 files changed, 96 insertions(+), 64 deletions(-) create mode 100644 src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index a6eb5da41f..622589aab0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -11,14 +11,11 @@ using System.Runtime.InteropServices; using System.Text; using static Stride.Shaders.Spirv.Specification; -using StorageClass = Stride.Shaders.Parsing.SDSL.AST.StorageClass; namespace Stride.Shaders.Compilers.SDSL { partial class ShaderMixer { - public Dictionary decoratedArraysAndStructs = new(); - private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) { var members = new List(); @@ -337,53 +334,30 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri EffectTypeDescription ConvertStructType(SpirvContext context, StructType s, SpirvBuilder.AlignmentRules alignmentRules) { - var structId = context.Types[s]; - if (decoratedArraysAndStructs.TryGetValue(structId, out var existingAlignmentRules)) - { - if (existingAlignmentRules != alignmentRules) - throw new InvalidOperationException($"Using type {s.ToId()} with both {alignmentRules} and {existingAlignmentRules} rules"); - } - else - decoratedArraysAndStructs.Add(structId, alignmentRules); + EmitStructDecorations(context, s, alignmentRules, out int size, out var offsets); - var hasOffsetDecorations = false; - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorate && (OpMemberDecorate)i is { Decoration: Decoration.Offset } memberDecorate && memberDecorate.StructureType == structId) - { - hasOffsetDecorations = true; - break; - } - } - var members = new EffectTypeMemberDescription[s.Members.Count]; - var offset = 0; for (int i = 0; i < s.Members.Count; ++i) { - var memberSize = SpirvBuilder.ComputeBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset, alignmentRules).Size; - members[i] = new EffectTypeMemberDescription { Name = s.Members[i].Name, Type = ConvertType(context, s.Members[i].Type, s.Members[i].TypeModifier, alignmentRules), - Offset = offset, + Offset = offsets[i], }; - - // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way - if (!hasOffsetDecorations) - DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); - - offset += memberSize; } - return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = offset }; + return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = size }; } EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { return symbolType switch { + ScalarType { TypeName: "bool" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Bool, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { TypeName: "uint" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.UInt, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { TypeName: "double" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Double, RowCount = 1, ColumnCount = 1, ElementSize = 8 }, ArrayType a => ConvertArrayType(context, a, typeModifier, alignmentRules), StructType s => ConvertStructType(context, s, alignmentRules), // TODO: should we use RowCount instead? (need to update Stride) @@ -398,37 +372,9 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, T EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { - var typeId = context.Types[a]; - if (decoratedArraysAndStructs.TryGetValue(typeId, out var existingAlignmentRules)) - { - if (existingAlignmentRules != alignmentRules) - throw new InvalidOperationException($"Using type {a.ToId()} with both {alignmentRules} and {existingAlignmentRules} rules"); - } - else - decoratedArraysAndStructs.Add(typeId, alignmentRules); - - var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); - - var hasStrideDecoration = false; - foreach (var i in context) - { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ArrayStride } arrayStrideDecoration && arrayStrideDecoration.Target == typeId) - { - hasStrideDecoration = true; - } - } - - if (!hasStrideDecoration) - { - var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size; - var arrayStride = alignmentRules switch - { - SpirvBuilder.AlignmentRules.CBuffer => (elementSize + 15) / 16 * 16, - SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, - }; - context.Add(new OpDecorate(typeId, Decoration.ArrayStride, [arrayStride])); - } + EmitArrayStrideDecorations(context, a, typeModifier, alignmentRules, out var arrayStride); + var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); return elementType with { Elements = a.Size }; } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs new file mode 100644 index 0000000000..ea6eaaea82 --- /dev/null +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -0,0 +1,87 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Compilers.SDSL; + +public partial class ShaderMixer +{ + private Dictionary decoratedStructs = new(); + private Dictionary decoratedArrays = new(); + + private void EmitTypeDecorationsRecursively(SpirvContext context, SymbolType symbolType, SpirvBuilder.AlignmentRules alignmentRules, TypeModifier typeModifier = TypeModifier.None) + { + switch (symbolType) + { + case ArrayType a: + EmitArrayStrideDecorations(context, a, typeModifier, alignmentRules, out _); + EmitTypeDecorationsRecursively(context, a.BaseType, alignmentRules, typeModifier); + break; + case StructType s: + EmitStructDecorations(context, s, alignmentRules, out _, out _); + foreach (var member in s.Members) + EmitTypeDecorationsRecursively(context, member.Type, alignmentRules, member.TypeModifier); + break; + case VectorType: + case MatrixType: + case ScalarType: + break; + default: + throw new NotImplementedException($"Type {symbolType} not implemented"); + } + + ; + } + + private void EmitArrayStrideDecorations(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules, out int arrayStride) + { + var typeId = context.Types[a]; + if (decoratedArrays.TryGetValue(typeId, out var arrayDecoration)) + { + if (arrayDecoration.Rules != alignmentRules) + throw new InvalidOperationException($"Using type {a.ToId()} with both {alignmentRules} and {arrayDecoration.Rules} rules"); + + arrayStride = arrayDecoration.Stride; + return; + } + + var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size; + arrayStride = alignmentRules switch + { + SpirvBuilder.AlignmentRules.CBuffer => (elementSize + 15) / 16 * 16, + SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, + }; + context.Add(new OpDecorate(typeId, Specification.Decoration.ArrayStride, [arrayStride])); + } + + private void EmitStructDecorations(SpirvContext context, StructType s, SpirvBuilder.AlignmentRules alignmentRules, out int size, out int[] offsets) + { + var structId = context.Types[s]; + if (decoratedStructs.TryGetValue(structId, out var structDecoration)) + { + if (structDecoration.Rules != alignmentRules) + throw new InvalidOperationException($"Using type {s.ToId()} with both {alignmentRules} and {structDecoration.Rules} rules"); + offsets = structDecoration.Offsets; + size = structDecoration.Size; + return; + } + + var offset = 0; + offsets = new int[s.Members.Count]; + for (int i = 0; i < s.Members.Count; ++i) + { + var memberSize = SpirvBuilder.ComputeBufferOffset(s.Members[i].Type, s.Members[i].TypeModifier, ref offset, alignmentRules).Size; + + // Note: we assume if already added by another cbuffer using this type, the offsets were computed the same way + offsets[i] = offset; + DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); + + offset += memberSize; + } + + decoratedStructs[structId] = (alignmentRules, offset, offsets); + size = offset; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 87dd3b1358..2b171f0143 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -1,6 +1,5 @@ using System.Runtime.InteropServices; using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -341,7 +340,7 @@ or Specification.Decoration.SamplerStateMinLOD var baseType = structuredBufferType.BaseType; // This will add array stride and offsets decorations - ConvertType(context, baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer); + EmitTypeDecorationsRecursively(context, baseType, SpirvBuilder.AlignmentRules.StructuredBuffer); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); From 8d71964ea10557f9685b40b1d022c3784034bed5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 20 Jan 2026 14:50:31 +0900 Subject: [PATCH 0727/1182] Added support for Interlocked and compute barriers --- .../SDSL/ShaderMixer.cs | 4 +- .../MemoryInstruction.cs | 26 ----- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 100 ++++++++++++++++++ .../PrimaryExpressionParsers.cs | 37 ++++--- .../Spirv/Building/Builder.Class.cs | 10 +- .../Spirv/Building/Context.ExtractBuffers.cs | 6 +- .../Spirv/Processing/BoundReducer.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 2 + 9 files changed, 142 insertions(+), 47 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 7fe3404a57..6da13077c9 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -820,7 +820,9 @@ public static void OffsetIds(OpData inst, int offset) { if (o.Kind == OperandKind.IdRef || o.Kind == OperandKind.IdResult - || o.Kind == OperandKind.IdResultType) + || o.Kind == OperandKind.IdResultType + || o.Kind == OperandKind.IdScope + || o.Kind == OperandKind.IdMemorySemantics) { for (int i = 0; i < o.Words.Length; ++i) { diff --git a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index bb39798e0f..86d2c2d12b 100644 --- a/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -128,30 +128,4 @@ public bool TryGetOperand(string name, out T? operand) operand = null; return false; } - - public void OffsetIds(int offset) - { - foreach (var o in this) - { - if (o.Kind == OperandKind.IdRef - || o.Kind == OperandKind.IdResult - || o.Kind == OperandKind.IdResultType) - { - for (int i = 0; i < o.Words.Length; ++i) - o.Words[i] += offset; - } - else if (o.Kind == OperandKind.PairIdRefLiteralInteger - || o.Kind == OperandKind.PairLiteralIntegerIdRef - || o.Kind == OperandKind.PairIdRefIdRef) - { - for (int i = 0; i < o.Words.Length; i += 2) - { - if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 0] += offset; - if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) - o.Words[i * 2 + 1] += offset; - } - } - } - } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 5ad25e8bef..a5b63ce741 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -824,4 +824,104 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(resultType), context.Bound++, x.Id)); return new(instruction.ResultId, instruction.ResultType); } +} + +public class MemoryBarrierCall(ShaderExpressionList parameters, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); + return new(); + } +} + +public class ControlBarrierCall(ShaderExpressionList parameters, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); + return new(); + } +} + +public enum InterlockedOp +{ + Add, + And, + Or, + Xor, + Max, + Min, + Exchange, + CompareExchange, + CompareStore, +} + +public class InterlockedCall(ShaderExpressionList parameters, TextLocation info, InterlockedOp op) : MethodCall(new($"Interlocked{op}", info), parameters, info) +{ + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + { + var (builder, context) = compiler; + var dest = Parameters.Values[0].Compile(table, compiler); + if (Parameters.Values[0].Type is not PointerType pointerType || pointerType.BaseType is not ScalarType { TypeName: "uint" or "int" } s) + throw new InvalidOperationException($"l-value int or uint expected but got {Parameters.Values[0].Type}"); + + var resultType = s; + + var value = Parameters.Values[1].CompileAsValue(table, compiler); + value = builder.Convert(context, value, resultType); + + SpirvValue result; + // If there is an out parameter to save original value + int? originalValueIndex; + if (op == InterlockedOp.CompareStore || op == InterlockedOp.CompareExchange) + { + var value2 = Parameters.Values[2].CompileAsValue(table, compiler); + value2 = builder.Convert(context, value2, resultType); + + var instruction = builder.Insert(new OpAtomicCompareExchange(context.GetOrRegister(resultType), context.Bound++, dest.Id, + context.CompileConstant((int)Specification.Scope.Device).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + value2.Id, + value.Id)); + result = new SpirvValue(instruction.ResultId, instruction.ResultType); + originalValueIndex = op == InterlockedOp.CompareExchange ? 3 : null; + } + else + { + var instruction = builder.Insert(new OpAtomicIAdd(context.GetOrRegister(resultType), context.Bound++, dest.Id, + context.CompileConstant((int)Specification.Scope.Device).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + value.Id)); + // Update instruction type (they all share same memory layout) + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)(op switch + { + InterlockedOp.Add => Specification.Op.OpAtomicIAdd, + InterlockedOp.And => Specification.Op.OpAtomicAnd, + InterlockedOp.Or => Specification.Op.OpAtomicOr, + InterlockedOp.Xor => Specification.Op.OpAtomicXor, + InterlockedOp.Max => s.IsSigned() ? Specification.Op.OpAtomicSMax : Specification.Op.OpAtomicUMax, + InterlockedOp.Min => s.IsSigned() ? Specification.Op.OpAtomicSMin : Specification.Op.OpAtomicUMin, + InterlockedOp.Exchange => Specification.Op.OpAtomicExchange, + }); + result = new SpirvValue(instruction.ResultId, instruction.ResultType); + originalValueIndex = Parameters.Values.Count == 3 ? 2 : null; + } + + // Out parameter? + if (originalValueIndex is { } originalValueIndex2) + { + var resultLocation = Parameters.Values[originalValueIndex2].Compile(table, compiler); + if (Parameters.Values[originalValueIndex2].Type is not PointerType resultPointerType) + throw new InvalidOperationException($"out parameter is not a l-value, got {Parameters.Values[0].Type} instead"); + + result = builder.Convert(context, result, resultPointerType.BaseType); + builder.Insert(new OpStore(resultLocation.Id, result.Id, null, [])); + } + + return new(); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 9a15464912..4d21fedb5d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -54,6 +54,9 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou if (Tokens.Char(')', ref scanner, advance: true)) { // TODO: handle matrices (most of those OPs support only vectors) + const Specification.MemorySemanticsMask allMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; + const Specification.MemorySemanticsMask deviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; + const Specification.MemorySemanticsMask groupMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.AcquireRelease; parsed = (identifier.Name, parameters.Values.Count) switch { // Bool @@ -128,15 +131,30 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), + // Compute Barriers + ("AllMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, allMemoryBarrierMemorySemanticsMask), + ("AllMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, allMemoryBarrierMemorySemanticsMask), + ("DeviceMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, deviceMemoryBarrierMemorySemanticsMask), + ("DeviceMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, deviceMemoryBarrierMemorySemanticsMask), + ("GroupMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, groupMemoryBarrierMemorySemanticsMask), + ("GroupMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, groupMemoryBarrierMemorySemanticsMask), + + // Compute interlocked + ("InterlockedAdd", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Add), + ("InterlockedAnd", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.And), + ("InterlockedOr", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Or), + ("InterlockedXor", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Xor), + ("InterlockedMax", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Max), + ("InterlockedMin", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Min), + ("InterlockedExchange", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Exchange), + ("InterlockedCompareExchange", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.CompareExchange), + ("InterlockedCompareStore", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.CompareStore), + ("abort", _) => throw new NotImplementedException(), - ("AllMemoryBarrier", _) => throw new NotImplementedException(), - ("AllMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), ("clip", _) => throw new NotImplementedException(), ("countbits", _) => throw new NotImplementedException(), ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), - ("DeviceMemoryBarrier", _) => throw new NotImplementedException(), - ("DeviceMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), ("errorf", _) => throw new NotImplementedException(), ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), ("EvaluateAttributeAtSample", _) => throw new NotImplementedException(), @@ -152,17 +170,6 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("frexp", _) => throw new NotImplementedException(), ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), - ("GroupMemoryBarrier", _) => throw new NotImplementedException(), - ("GroupMemoryBarrierWithGroupSync", _) => throw new NotImplementedException(), - ("InterlockedAdd", _) => throw new NotImplementedException(), - ("InterlockedAnd", _) => throw new NotImplementedException(), - ("InterlockedCompareExchange", _) => throw new NotImplementedException(), - ("InterlockedCompareStore", _) => throw new NotImplementedException(), - ("InterlockedExchange", _) => throw new NotImplementedException(), - ("InterlockedMax", _) => throw new NotImplementedException(), - ("InterlockedMin", _) => throw new NotImplementedException(), - ("InterlockedOr", _) => throw new NotImplementedException(), - ("InterlockedXor", _) => throw new NotImplementedException(), ("isfinite", _) => throw new NotImplementedException(), ("isinf", _) => throw new NotImplementedException(), ("isnan", _) => throw new NotImplementedException(), diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 5712d974fa..1c640a61b0 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -531,6 +531,8 @@ public static bool ContainIds(HashSet ids, OpData i) if ((op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResult || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics || op.Kind == OperandKind.PairIdRefLiteralInteger || op.Kind == OperandKind.PairIdRefIdRef) && op.Words.Length > 0 @@ -574,11 +576,15 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) foreach (var op in i) { - if ((op.Kind == OperandKind.IdRef + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResult || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef)) + || op.Kind == OperandKind.PairIdRefIdRef + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics) { foreach (ref var word in op.Words) { diff --git a/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs index c50e1d4ccf..0778693f89 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs @@ -112,7 +112,11 @@ public NewSpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) { if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType - || op.Kind == OperandKind.PairIdRefIdRef) + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics + || op.Kind == OperandKind.PairIdRefIdRef + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics) { foreach (ref var word in op.Words) { diff --git a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs index 9461482147..fae58eeae9 100644 --- a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs +++ b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs @@ -71,7 +71,7 @@ static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) { foreach (var op in i.Data) { - if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType) + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.IdScope || op.Kind == OperandKind.IdMemorySemantics) op.Words[0] = op.Words[0] == from ? to : op.Words[0]; else if (op.Kind == OperandKind.PairIdRefLiteralInteger) op.Words[0] = op.Words[0] == from ? to : op.Words[0]; diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 81e5da1e84..aa3b5a8f8c 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -400,7 +400,7 @@ static void ReplaceRefs(Span from, int to, NewSpirvBuffer buffer) var opcode = i.Op; foreach (var op in i.Data) { - if (op.Kind == OperandKind.IdRef) + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdScope || op.Kind == OperandKind.IdMemorySemantics) { foreach (ref var w in op.Words) { diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 898a24daaa..83d496f5ba 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -331,6 +331,8 @@ public readonly void DisInstruction(in OpDataIndex instruction, in DisWriter wri OperandKind.LiteralInteger or OperandKind.LiteralExtInstInteger or OperandKind.LiteralSpecConstantOpInteger + or OperandKind.IdScope + or OperandKind.IdMemorySemantics => (operand.Quantifier, operand.Words.Length) switch { (OperandQuantifier.One or OperandQuantifier.ZeroOrOne, 1) => AppendLiteralNumber(operand.ToLiteral()), From 694dd5dc050d27db1f3c75c8dd76dc777fbc384d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 20 Jan 2026 19:29:50 +0900 Subject: [PATCH 0728/1182] Generics: cache results --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 18 +- .../ShaderLoaderBase.cs | 54 +----- src/Stride.Shaders.Experiments/Examples.cs | 29 +-- src/Stride.Shaders.Tests/RenderingTests.cs | 23 ++- .../Spirv/Building/Builder.Class.cs | 177 +++++++++--------- .../Spirv/Building/CompilerUnit.cs | 6 + .../Spirv/Building/Context.Constants.cs | 15 +- src/Stride.Shaders/Spirv/Building/Context.cs | 63 ++++++- src/Stride.Shaders/Spirv/Tools/Dis.cs | 11 ++ 9 files changed, 209 insertions(+), 187 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index eb5b14e89f..b500fc023c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -15,10 +15,10 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out SpirvBytecode lastBuffer) + public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) { var parsed = SDSLParser.Parse(code); - lastBuffer = null; + lastBuffer = default; if (parsed.Errors.Count > 0) { throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, parsed.Errors)}"); @@ -43,10 +43,8 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May if (table.Errors.Count > 0) throw new Exception("Some parse errors"); - var merged = compiler.ToBuffer(); - lastBuffer = new(merged); - - ShaderLoader.RegisterShader(shader.Name, macros, lastBuffer); + lastBuffer = compiler.ToShaderBuffers(); + ShaderLoader.Cache.RegisterShader(shader.Name, macros, lastBuffer); } else if (declaration is ShaderEffect effect) { @@ -59,10 +57,8 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May compiler.Macros.AddRange(macros); effect.Compile(table, compiler); - var merged = compiler.ToBuffer(); - lastBuffer = new(merged); - - ShaderLoader.RegisterShader(effect.Name, macros, lastBuffer); + lastBuffer = compiler.ToShaderBuffers(); + ShaderLoader.Cache.RegisterShader(effect.Name, macros, lastBuffer); } else { @@ -74,7 +70,7 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May } else { - lastBuffer = null; + lastBuffer = default; return false; } } diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs index b1a8c0a8e5..af0f0c3b06 100644 --- a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -9,39 +9,13 @@ namespace Stride.Shaders.Compilers; -public abstract class ShaderLoaderBase : IExternalShaderLoader +public abstract class ShaderLoaderBase(IShaderCache cache) : IExternalShaderLoader { - record struct ShaderLoadKey(ShaderMacro[] Macros) - { - public override int GetHashCode() - { - unchecked - { - int hashCode = 0; - foreach (var current in Macros) - hashCode = (hashCode * 397) ^ (current.GetHashCode()); - return hashCode; - } - } - - public bool Equals(ShaderLoadKey other) - { - return Macros.SequenceEqual(other.Macros); - } - } - - private Dictionary> loadedShaders = []; - - public virtual void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode) - { - if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) - loadedShaders.Add(name, loadedShadersByName = new()); - loadedShadersByName.Add(new(defines.ToArray()), bytecode); - } + public IShaderCache Cache => cache; public bool Exists(string name) { - if (loadedShaders.ContainsKey(name)) + if (cache.Exists(name)) return true; return ExternalFileExists(name); @@ -50,16 +24,12 @@ public bool Exists(string name) protected abstract bool ExternalFileExists(string name); protected abstract bool LoadExternalFileContent(string name, out string filename, out string code); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out bool isFromCache) { - if (loadedShaders.TryGetValue(name, out var loadedShadersByName) - && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) - { - isFromCache = true; + isFromCache = cache.TryLoadFromCache(name, defines, out buffer); + if (isFromCache) return true; - } - isFromCache = false; if (!ExternalFileExists(name)) { throw new InvalidOperationException($"Shader {name} could not be found"); @@ -78,18 +48,14 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ return true; } - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out bool isFromCache) { - if (loadedShaders.TryGetValue(name, out var loadedShadersByName) - && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) - { - isFromCache = true; + isFromCache = cache.TryLoadFromCache(name, defines, out buffer); + if (isFromCache) return true; - } var filename = $"{code}.sdsl"; - isFromCache = false; if (!LoadFromCode(filename, code, defines, out buffer)) { throw new InvalidOperationException($"Shader {name} could not be compiled"); @@ -98,7 +64,7 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan macros, out SpirvBytecode buffer) + protected virtual bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out ShaderBuffers buffer) { var defines = new (string Name, string Definition)[macros.Length]; for (int i = 0; i < macros.Length; ++i) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 1dde96c65e..72922d044c 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -208,7 +208,7 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) return false; } - public class ShaderLoader : ShaderLoaderBase + public class ShaderLoader() : ShaderLoaderBase(new ShaderCache()) { protected override bool ExternalFileExists(string name) { @@ -223,31 +223,4 @@ protected override bool LoadExternalFileContent(string name, out string filename return true; } } - - public static void CompileSDSL(string shaderName) - { - // if(Directory.GetCurrentDirectory().Contains("bin\\Debug")) - // { - // var info = new DirectoryInfo(Directory.GetCurrentDirectory()); - // while(!info.GetDirectories().Any(d => d.Name is "assets") || !info.GetFiles().Any(d => d.Name is "SDSL.sln") ) - // info = info.Parent!; - // Directory.SetCurrentDirectory(info.FullName); - // } - var text = MonoGamePreProcessor.OpenAndRun($"./assets/SDSL/{shaderName}.sdsl"); - - var sdslc = new SDSLC - { - ShaderLoader = new ShaderLoader() - }; - if (sdslc.Compile(text, [], out var buffer) && buffer is not null) - { - Spirv.Tools.Spv.Dis(buffer, writeToConsole: true); - var bytecode = buffer.ToBytecode().ToArray(); - File.WriteAllBytes("TestBasic.sdspv", bytecode); - var code = new SpirvTranslator(bytecode.AsMemory().Cast()); - } - - // Console.WriteLine(code.Translate(Backend.Hlsl)); - - } } \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index a88551e019..daa95fc298 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -27,7 +27,18 @@ public class RenderingTests static int width = 1; static int height = 1; - class ShaderLoader(string basePath) : ShaderLoaderBase + class TestShaderCache : ShaderCache + { + public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode) + { + base.RegisterShader(name, defines, bytecode); + + Console.WriteLine($"Registering shader {name}"); + Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } + } + + class ShaderLoader(string basePath) : ShaderLoaderBase(new TestShaderCache()) { protected override bool ExternalFileExists(string name) { @@ -42,7 +53,7 @@ protected override bool LoadExternalFileContent(string name, out string filename return true; } - protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out SpirvBytecode buffer) + protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out ShaderBuffers buffer) { var result = base.LoadFromCode(filename, code, macros, out buffer); if (result) @@ -52,14 +63,6 @@ protected override bool LoadFromCode(string filename, string code, ReadOnlySpan< } return result; } - - public override void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode) - { - base.RegisterShader(name, defines, bytecode); - - Console.WriteLine($"Registering shader {name}"); - Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - } } [Theory] diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 1c640a61b0..94e9156145 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -189,12 +189,23 @@ record struct GenericParameter(SymbolType Type, int ResultId, int ResultType, in abstract class GenericResolver { - public abstract bool NeedsResolve(); + public abstract int GenericArgumentCount { get; } + public virtual IShaderCache? Cache => null; + + public abstract string ResolveGenericAsString(int genericIndex); public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value); public abstract bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue); - public virtual void PostProcess(string classNameWithGenerics, List genericParameters) + public virtual void ValidateGenericParameters(string classNameWithGenerics, List genericParameters) + { + } + + /// + /// This will be executed in all cases for generic classes (even if generic instantiation was in the cache). + /// + /// + public virtual void PostProcess(string classNameWithGenerics) { } } @@ -204,7 +215,8 @@ public virtual void PostProcess(string classNameWithGenerics, List class GenericResolverFromValues(string[]? genericValues) : GenericResolver { - public override bool NeedsResolve() => genericValues != null && genericValues.Length > 0; + public override int GenericArgumentCount => genericValues?.Length ?? 0; + public override string ResolveGenericAsString(int genericIndex) => genericValues[genericIndex]; public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) { @@ -259,9 +271,24 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType /// class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSource, ResolveStep resolveStep, SpirvContext declaringContext) : GenericResolver { - private Dictionary names; + public override int GenericArgumentCount => classSource.GenericArguments.Length; - public override bool NeedsResolve() => classSource.GenericArguments.Length > 0; + public override IShaderCache? Cache => declaringContext.GenericCache; + + public override string ResolveGenericAsString(int genericIndex) + { + var constantId = classSource.GenericArguments[genericIndex]; + if (!declaringContext.GenericValueCache.TryGetValue(constantId, out var textValue)) + { + textValue = declaringContext.TryGetConstantValue(constantId, out var constantValue, out _, false) + ? constantValue.ToString() + : GetIdRefAsString(genericIndex); + + declaringContext.GenericValueCache.Add(constantId, textValue); + } + + return textValue; + } private string GetIdRefAsString(int index) { @@ -283,16 +310,8 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - // Check if generic value can already be computed (no OpSDSLGenericParameter and such) - if (declaringContext.TryGetConstantValue(classSource.GenericArguments[genericIndex], out var constantValue, out _, false)) - { - // TODO: shortcut: store it right away and finish here - textValue = constantValue.ToString(); - } - else - { - textValue = GetIdRefAsString(genericIndex); - } + // TODO: optimization: if it can be resolved fully (declaringContext.TryGetConstantValue succeeds), we could simply use/inject the value as is + textValue = ResolveGenericAsString(genericIndex); var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; var bufferWithConstant = declaringContext.ExtractConstantAsSpirvBuffer(classSource.GenericArguments[genericIndex]); @@ -321,29 +340,33 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType return true; } - public override void PostProcess(string classNameWithGenerics, List genericParameters) + public override void ValidateGenericParameters(string classNameWithGenerics, List genericParameters) { // Fully resolved? - if (genericParameters.All(x => x.Resolved)) + if (resolveStep == ResolveStep.Mix) { - if (resolveStep == ResolveStep.Mix) + if (!genericParameters.All(x => x.Resolved)) { - classSource.ClassName = classNameWithGenerics; - classSource.GenericArguments = []; + throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); } } - else if (resolveStep == ResolveStep.Mix) + } + + public override void PostProcess(string classNameWithGenerics) + { + if (resolveStep == ResolveStep.Mix) { - throw new InvalidOperationException("During mix phase, shaders generics are expected to be fully resolved"); + classSource.ClassName = classNameWithGenerics; + classSource.GenericArguments = []; } } } - private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, string className, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) + private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, string classNameWithGenerics, GenericResolver genericResolver, IExternalShaderLoader shaderLoader, ReadOnlySpan macros) { var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); - + var genericParameters = new List(); for (int index = 0; index < shaderBuffers.Context.Count; ++index) { @@ -385,34 +408,33 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } - Console.WriteLine($"[Shader] Instantiating {className} with values {string.Join(",", genericParameters.Select(x => x.Value))}"); - - StringBuilder classNameWithGenericsBuilder = new(); - classNameWithGenericsBuilder.Append(className).Append("<"); - - for (int i = 0; i < genericParameters.Count; i++) - { - var genericParameter = genericParameters[i]; - var index = genericParameter.Index; - if (i > 0) - classNameWithGenericsBuilder.Append(","); - classNameWithGenericsBuilder.Append(genericParameter.Value.ToString()); - } - classNameWithGenericsBuilder.Append(">"); - var classNameWithGenerics = classNameWithGenericsBuilder.ToString(); + Console.WriteLine($"[Shader] Instantiating {classNameWithGenerics}"); foreach (var i in shaderBuffers.Buffer) { if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) - { shaderDeclaration.ShaderName = classNameWithGenerics; - } } TransformResolvedSemantics(shaderBuffers.Context, semantics); TransformResolvedLinkIdIntoLinkString(shaderBuffers.Context, resolvedLinks); - genericResolver.PostProcess(classNameWithGenerics, genericParameters); + genericResolver.ValidateGenericParameters(classNameWithGenerics, genericParameters); + } + + private static string BuildGenericClassName(string className, GenericResolver resolver) + { + StringBuilder sb = new(); + sb.Append(className).Append("<"); + + for (int i = 0; i < resolver.GenericArgumentCount; i++) + { + if (i > 0) + sb.Append(","); + sb.Append(resolver.ResolveGenericAsString(i)); + } + sb.Append(">"); + return sb.ToString(); } private static void TransformResolvedSemantics(SpirvContext context, Dictionary semantics) @@ -484,10 +506,8 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri } // TODO: Cache? - if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out var shader, out _)) + if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shaderBuffers, out _)) throw new InvalidOperationException(); - - shaderBuffers = CreateShaderBuffers(shader); } } } @@ -652,53 +672,42 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { - var shader = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); - var shaderBuffers = CreateShaderBuffers(shader); + var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); // Split context and buffer // TODO: generics cache? - if (genericResolver.NeedsResolve()) + if (genericResolver.GenericArgumentCount > 0) { - InstantiateMemberNames(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - - // Copy buffers (we don't want to edit original buffer as it might be reloaded through caching - shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) + // First, try to build name for cache lookup + var classNameWithGenerics = BuildGenericClassName(className, genericResolver); + var cache = genericResolver.Cache ?? shaderLoader.Cache; + if (shaderLoader.Cache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers)) { - Bound = shaderBuffers.Context.Bound, - Names = new(shaderBuffers.Context.Names), - Types = new(shaderBuffers.Context.Types), - ReverseTypes = new(shaderBuffers.Context.ReverseTypes), - }; - shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); - - InstantiateGenericShader(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - } - - return shaderBuffers; - } - - private static ShaderBuffers CreateShaderBuffers(SpirvBytecode shader) - { - var context = new SpirvContext(); - var buffer = new NewSpirvBuffer(); - var isContext = true; - foreach (var i in shader.Buffer) - { - // Find when switching from context to actual shader/effect - if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLEffect) - isContext = false; - - if (isContext) - context.Add(i.Data); + shaderBuffers = cachedShaderBuffers; + } else - buffer.Add(i.Data); - } + { + InstantiateMemberNames(ref shaderBuffers, className, genericResolver, shaderLoader, macros); - context.Bound = shader.Header.Bound; + // Copy buffers (we don't want to edit original non-instantiated code as it might be reloaded through caching + shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) + { + Bound = shaderBuffers.Context.Bound, + Names = new(shaderBuffers.Context.Names), + Types = new(shaderBuffers.Context.Types), + ReverseTypes = new(shaderBuffers.Context.ReverseTypes), + }; + shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); + + InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); + shaderLoader.Cache.RegisterShader(classNameWithGenerics, macros, shaderBuffers); + } + + // Run in all cases (even if cached) + genericResolver.PostProcess(classNameWithGenerics); + } - var shaderBuffers = new ShaderBuffers(context, buffer); - ShaderClass.ProcessNameAndTypes(shaderBuffers.Context); return shaderBuffers; } @@ -731,7 +740,7 @@ public static List CollectGenerics(NewSpirvBuffer shader) return generics; } - public static SpirvBytecode GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) { Console.WriteLine($"[Shader] Requesting non-generic class {className}"); diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 5f974f4251..76777d5bf4 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -43,6 +43,12 @@ public NewSpirvBuffer ToBuffer() Context.Sort(); return NewSpirvBuffer.Merge(Context.GetBuffer(), Builder.GetBuffer()); } + + public ShaderBuffers ToShaderBuffers() + { + Context.Sort(); + return new(Context, Builder.GetBuffer()); + } // public override string ToString() // { // var builder = new StringBuilder(); diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index e6d1bb2b89..2cc43f490d 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -1,4 +1,5 @@ -using System.Numerics; +using System.Diagnostics.CodeAnalysis; +using System.Numerics; using Stride.Shaders.Core; using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.SDSL.AST; @@ -44,15 +45,15 @@ public object GetConstantValue(int constantId) throw new Exception("Cannot find constant instruction for id " + constantId); } - public bool TryGetConstantValue(int constantId, out object value, out int typeId, bool simplifyInBuffer = false) + public bool TryGetConstantValue(int constantId, [MaybeNullWhen(false)] out object value, out int typeId, bool simplifyInBuffer = false) { if (Buffer.TryGetInstructionById(constantId, out var constant)) { return TryGetConstantValue(constant, out value, out typeId, simplifyInBuffer); } - typeId = default; - value = default; + typeId = 0; + value = null; return false; } @@ -65,10 +66,10 @@ public object ResolveConstantValue(OpDataIndex i) } // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. - public bool TryGetConstantValue(OpDataIndex i, out object value, out int typeId, bool simplifyInBuffer = false) + public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object value, out int typeId, bool simplifyInBuffer = false) { - typeId = default; - value = default; + typeId = 0; + value = null; // Check for unresolved values if (i.Op == Specification.Op.OpSDSLGenericParameter || i.Op == Specification.Op.OpSDSLGenericReference) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index d968d7ffb6..fbbcbe4f62 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -14,18 +14,75 @@ namespace Stride.Shaders.Spirv.Building; +public interface IShaderCache +{ + public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode); + public bool Exists(string name); + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer); +} + +public class ShaderCache : IShaderCache +{ + record struct ShaderLoadKey(ShaderMacro[] Macros) + { + public override int GetHashCode() + { + unchecked + { + int hashCode = 0; + foreach (var current in Macros) + hashCode = (hashCode * 397) ^ (current.GetHashCode()); + return hashCode; + } + } + + public bool Equals(ShaderLoadKey other) + { + return Macros.SequenceEqual(other.Macros); + } + } + + private Dictionary> loadedShaders = []; + + public bool Exists(string name) => loadedShaders.ContainsKey(name); + + public virtual void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode) + { + if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) + loadedShaders.Add(name, loadedShadersByName = new()); + loadedShadersByName.Add(new(defines.ToArray()), bytecode); + } + + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer) + { + if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + { + return true; + } + + buffer = default; + return false; + } +} + public interface IExternalShaderLoader { - public void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode); + public IShaderCache Cache { get; } + public bool Exists(string name); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode bytecode, out bool isFromCache); + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out bool isFromCache); + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out bool isFromCache); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other // SPIR-V parameters public partial class SpirvContext { + // Used internally by GenericResolverFromInstantiatingBuffer (cache from constant ID to string representation) + internal IShaderCache GenericCache { get; } = new ShaderCache(); + internal Dictionary GenericValueCache { get; } = new(); + private int bound = 1; public int ResourceGroupBound { get; set; } = 1; public ref int Bound => ref bound; diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 83d496f5ba..925d31b0aa 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -7,6 +7,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Text; +using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; [assembly: DebuggerDisplay("{Stride.Shaders.Spirv.Tools.SpirvBufferExtensions.GetDebuggerDisplay(this)}", Target = typeof(NewSpirvBuffer))] @@ -27,10 +28,20 @@ public static string GetDebuggerDisplay(this NewSpirvBuffer buffer) { return Spv.Dis(buffer, DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex | DisassemblerFlags.Name); } + public static string GetDebuggerDisplay(this ShaderBuffers buffers) + { + return Spv.Dis(buffers, DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex | DisassemblerFlags.Name); + } } public static partial class Spv { + public static string Dis(ShaderBuffers buffers, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) + { + var writer = new DisWriter(new(new("undefined", 0, 1), NewSpirvBuffer.Merge(buffers.Context.GetBuffer(), buffers.Buffer)), flags, writeToConsole); + writer.Disassemble(); + return writer.ToString(); + } public static string Dis(NewSpirvBuffer bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { var writer = new DisWriter(new(new("undefined", 0, 1), bytecode), flags, writeToConsole); From 24eb24b05c7aa9646cff3842cd86d2a1a8da76db Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 00:15:58 +0900 Subject: [PATCH 0729/1182] Record hash sources for any used shader file --- .../SDSL/EffectEvaluator.cs | 4 +- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 7 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 16 +- .../SDSL/ShaderMixer.cs | 45 +- .../ShaderLoaderBase.cs | 29 +- src/Stride.Shaders.Experiments/Examples.cs | 13 +- src/Stride.Shaders.Experiments/Program.cs | 4 +- .../Stride.Shaders.Experiments.csproj | 3 + src/Stride.Shaders.Tests/RenderingTests.cs | 24 +- .../Stride.Shaders.Parsing.Tests.csproj | 3 + .../Spirv/Building/Builder.Class.cs | 16 +- src/Stride.Shaders/Spirv/Building/Context.cs | 32 +- src/Stride.Shaders/Stride.Shaders.csproj | 3 + .../ShadersSource/HashSourceCollection.cs | 46 ++ .../StrideImported/ShadersSource/ObjectId.cs | 334 +++++++++++++ .../ShadersSource/ObjectIdBuilder.cs | 437 ++++++++++++++++++ .../StrideImported/ShadersSource/Utilities.cs | 205 ++++++++ 17 files changed, 1160 insertions(+), 61 deletions(-) create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs create mode 100644 src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 396645b6c1..6aca044118 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Compilers.SDSL { - internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) + internal class EffectEvaluator(IExternalShaderLoader shaderLoader) { private Stack mixinSources = new(); @@ -32,7 +32,7 @@ object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds { case ShaderClassSource classSource: var macros = mixinSources.Count > 0 ? mixinSources.Peek().Macros : []; - var shaderBuffers = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); + var shaderBuffers = SpirvBuilder.GetOrLoadShader(shaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); if (shaderBuffers.Buffer[0].Op == Op.OpSDSLEffect) { diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index b500fc023c..8fc410d140 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -9,13 +9,14 @@ using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using Stride.Core.Storage; using Stride.Shaders.Parsing.SDFX.AST; namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) + public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) { var parsed = SDSLParser.Parse(code); lastBuffer = default; @@ -44,7 +45,7 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May throw new Exception("Some parse errors"); lastBuffer = compiler.ToShaderBuffers(); - ShaderLoader.Cache.RegisterShader(shader.Name, macros, lastBuffer); + ShaderLoader.FileCache.RegisterShader(shader.Name, macros, lastBuffer, hash); } else if (declaration is ShaderEffect effect) { @@ -58,7 +59,7 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May effect.Compile(table, compiler); lastBuffer = compiler.ToShaderBuffers(); - ShaderLoader.Cache.RegisterShader(effect.Name, macros, lastBuffer); + ShaderLoader.FileCache.RegisterShader(effect.Name, macros, lastBuffer, hash); } else { diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 4b6715f3e5..0dc0e3f60f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -18,7 +18,7 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext context, ShaderSource shaderSource, Action? addToRoot = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderSource shaderSource, Action? addToRoot = null) { var mixinList = new List(); @@ -33,7 +33,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext foreach (var mixinToMerge in shaderMixinSource.Mixins) { - var shaderBuffer = SpirvBuilder.GetOrLoadShader(ShaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); + var shaderBuffer = SpirvBuilder.GetOrLoadShader(shaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); mixinToMerge2.Buffer = shaderBuffer; @@ -47,15 +47,15 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(SpirvContext } } - SpirvBuilder.BuildInheritanceListIncludingSelf(ShaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); } - ProcessClasses(context, mixinList, shaderMixinSource, result, compositions, addToRoot); + ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot); return result; } - private void ProcessClasses(SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null) + private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null) { int shaderIndex = 0; @@ -77,7 +77,7 @@ private void ProcessClasses(SpirvContext context, List // It's a bit complex: we need to inherit from it right now instead of later // (if we simply do a result.Mixins.Add as in normal case, the shader would be added twice) var currentlyMixedList = mixinList[0..shaderIndex]; - SpirvBuilder.BuildInheritanceListIncludingSelf(ShaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); var newShadersToMergeNow = currentlyMixedList[shaderIndex..]; mixinList.InsertRange(shaderIndex, newShadersToMergeNow); @@ -135,12 +135,12 @@ private void ProcessClasses(SpirvContext context, List { var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(context, value, addToRootRecursive)); + variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, value, addToRootRecursive)); compositions[variableName] = [..variableCompositions]; } else { - var variableComposition = EvaluateInheritanceAndCompositions(context, compositionMixin, addToRootRecursive); + var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, compositionMixin, addToRootRecursive); compositions[variableName] = [variableComposition]; } } diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 6da13077c9..243486e188 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -23,6 +23,8 @@ using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Text; +using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Compilers.SDSL; @@ -30,17 +32,19 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection) + + public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources) { var temp = new NewSpirvBuffer(); var context = new SpirvContext(); - var table = new SymbolTable(context) { ShaderLoader = ShaderLoader }; + var shaderLoader = new CaptureLoadedShaders(ShaderLoader); + var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; - var effectEvaluator = new EffectEvaluator(ShaderLoader); + var effectEvaluator = new EffectEvaluator(shaderLoader); shaderSource = effectEvaluator.EvaluateEffects(shaderSource); - var shaderSource2 = EvaluateInheritanceAndCompositions(context, shaderSource); + var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderSource); // Root shader var globalContext = new MixinGlobalContext(); @@ -93,6 +97,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef bytecode = SpirvBytecode.CreateBytecodeFromBuffers(temp); effectReflection = globalContext.Reflection; + usedHashSources = shaderLoader.Sources; } class MixinGlobalContext @@ -934,4 +939,36 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio } } } +} + +public class CaptureLoadedShaders(IExternalShaderLoader inner) : IExternalShaderLoader +{ + /// + /// Cache per file. + /// + /// Expects hash to be stored. + public IShaderCache FileCache => inner.FileCache; + /// + /// Cache per generic instantiation. + /// + /// Hashes are not needed. + public IShaderCache GenericCache => inner.GenericCache; + + public HashSourceCollection Sources { get; } = new(); + + public bool Exists(string name) => inner.Exists(name); + + public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) + => inner.LoadExternalFileContent(name, out filename, out code, out hash); + + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) + { + var result = inner.LoadExternalBuffer(name, defines, out bytecode, out hash, out isFromCache); + if (!Sources.ContainsKey(name)) + Sources.Add(name, hash); + return result; + } + + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) + => inner.LoadExternalBuffer(name, code, defines, out bytecode, out hash, out isFromCache); } \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs index af0f0c3b06..acafcbe4be 100644 --- a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -6,27 +6,29 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; +using Stride.Core.Storage; namespace Stride.Shaders.Compilers; -public abstract class ShaderLoaderBase(IShaderCache cache) : IExternalShaderLoader +public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShaderLoader { - public IShaderCache Cache => cache; + public IShaderCache FileCache => fileCache; + public IShaderCache GenericCache { get; } = new ShaderCache(); public bool Exists(string name) { - if (cache.Exists(name)) + if (fileCache.Exists(name)) return true; return ExternalFileExists(name); } protected abstract bool ExternalFileExists(string name); - protected abstract bool LoadExternalFileContent(string name, out string filename, out string code); + public abstract bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = cache.TryLoadFromCache(name, defines, out buffer); + isFromCache = fileCache.TryLoadFromCache(name, defines, out buffer, out hash); if (isFromCache) return true; @@ -35,12 +37,12 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ throw new InvalidOperationException($"Shader {name} could not be found"); } - if (!LoadExternalFileContent(name, out var filename, out var code)) + if (!LoadExternalFileContent(name, out var filename, out var code, out hash)) { throw new InvalidOperationException($"Shader {name} could not be loaded"); } - if (!LoadFromCode(filename, code, defines, out buffer)) + if (!LoadFromCode(filename, code, hash, defines, out buffer)) { throw new InvalidOperationException($"Shader {name} could not be compiled"); } @@ -48,15 +50,16 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ return true; } - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out bool isFromCache) + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = cache.TryLoadFromCache(name, defines, out buffer); + isFromCache = fileCache.TryLoadFromCache(name, defines, out buffer, out hash); if (isFromCache) return true; var filename = $"{code}.sdsl"; - if (!LoadFromCode(filename, code, defines, out buffer)) + hash = ObjectId.FromBytes(Encoding.UTF8.GetBytes(code)); + if (!LoadFromCode(filename, code, hash, defines, out buffer)) { throw new InvalidOperationException($"Shader {name} could not be compiled"); } @@ -64,7 +67,7 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan macros, out ShaderBuffers buffer) + protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) { var defines = new (string Name, string Definition)[macros.Length]; for (int i = 0; i < macros.Length; ++i) @@ -76,6 +79,6 @@ protected virtual bool LoadFromCode(string filename, string code, ReadOnlySpan + + $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index daa95fc298..3679205170 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -18,6 +18,7 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; +using Stride.Core.Storage; using Spv = Stride.Shaders.Spirv.Tools.Spv; namespace Stride.Shaders.Parsing.Tests; @@ -29,9 +30,9 @@ public class RenderingTests class TestShaderCache : ShaderCache { - public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode) + public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { - base.RegisterShader(name, defines, bytecode); + base.RegisterShader(name, defines, bytecode, hash); Console.WriteLine($"Registering shader {name}"); Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); @@ -46,16 +47,23 @@ protected override bool ExternalFileExists(string name) return File.Exists(filename); } - protected override bool LoadExternalFileContent(string name, out string filename, out string code) + public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { filename = $"{basePath}/{name}.sdsl"; - code = File.ReadAllText(filename); + + var fileData = File.ReadAllBytes(filename); + hash = ObjectId.FromBytes(fileData); + + // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file + using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); + code = reader.ReadToEnd(); + return true; } - protected override bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out ShaderBuffers buffer) + protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) { - var result = base.LoadFromCode(filename, code, macros, out buffer); + var result = base.LoadFromCode(filename, code, hash, macros, out buffer); if (result) { Console.WriteLine($"Loading shader {filename}"); @@ -71,7 +79,7 @@ public void ComputeTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -108,7 +116,7 @@ public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/RenderTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 92fe7f60d3..58701d9067 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -28,6 +28,9 @@ + + $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 94e9156145..8f8efb50f6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -17,6 +17,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; +using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; @@ -506,7 +507,7 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri } // TODO: Cache? - if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shaderBuffers, out _)) + if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shaderBuffers, out _, out _)) throw new InvalidOperationException(); } } @@ -672,7 +673,7 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { - var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var isFromCache); + var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var hash, out var isFromCache); // Split context and buffer @@ -681,10 +682,11 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, { // First, try to build name for cache lookup var classNameWithGenerics = BuildGenericClassName(className, genericResolver); - var cache = genericResolver.Cache ?? shaderLoader.Cache; - if (shaderLoader.Cache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers)) + var cache = genericResolver.Cache ?? shaderLoader.GenericCache; + if (shaderLoader.GenericCache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers, out var cachedHash)) { shaderBuffers = cachedShaderBuffers; + hash = cachedHash; } else { @@ -701,7 +703,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); - shaderLoader.Cache.RegisterShader(classNameWithGenerics, macros, shaderBuffers); + shaderLoader.GenericCache.RegisterShader(classNameWithGenerics, macros, shaderBuffers, hash); } // Run in all cases (even if cached) @@ -740,11 +742,11 @@ public static List CollectGenerics(NewSpirvBuffer shader) return generics; } - public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out bool isFromCache) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out ObjectId hash, out bool isFromCache) { Console.WriteLine($"[Shader] Requesting non-generic class {className}"); - if (!shaderLoader.LoadExternalBuffer(className, defines, out var buffer, out isFromCache)) + if (!shaderLoader.LoadExternalBuffer(className, defines, out var buffer, out hash, out isFromCache)) throw new InvalidOperationException($"Could not load shader [{className}]"); if (!isFromCache) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index fbbcbe4f62..28e6e97d4d 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -10,15 +10,16 @@ using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.InteropServices; +using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Building; public interface IShaderCache { - public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode); + public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash); public bool Exists(string name); - public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer); + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash); } public class ShaderCache : IShaderCache @@ -42,25 +43,30 @@ public bool Equals(ShaderLoadKey other) } } - private Dictionary> loadedShaders = []; + private Dictionary BuffersPerMacros)> loadedShaders = []; public bool Exists(string name) => loadedShaders.ContainsKey(name); - public virtual void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode) + public virtual void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { - if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) - loadedShaders.Add(name, loadedShadersByName = new()); - loadedShadersByName.Add(new(defines.ToArray()), bytecode); + ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, name, out var exists); + if (!exists) + loadedShadersByName = hash != null ? new(hash.Value, new()) : new(); + loadedShadersByName.BuffersPerMacros.Add(new(defines.ToArray()), bytecode); + if (hash != null) + loadedShadersByName.Hash = hash.Value; } - public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer) + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) { if (loadedShaders.TryGetValue(name, out var loadedShadersByName) - && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + && loadedShadersByName.BuffersPerMacros.TryGetValue(new(defines.ToArray()), out buffer)) { + hash = loadedShadersByName.Hash; return true; } + hash = default; buffer = default; return false; } @@ -68,11 +74,13 @@ public bool TryLoadFromCache(string name, ReadOnlySpan defines, [Ma public interface IExternalShaderLoader { - public IShaderCache Cache { get; } + public IShaderCache FileCache { get; } + public IShaderCache GenericCache { get; } public bool Exists(string name); - public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out bool isFromCache); - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out bool isFromCache); + public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 0a648b011e..8455ca4beb 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -18,6 +18,9 @@ + + $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs b/src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs new file mode 100644 index 0000000000..92a61ee993 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs @@ -0,0 +1,46 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; +using System.Collections.Generic; + +using Stride.Core; +using Stride.Core.Storage; + +namespace Stride.Shaders; + +/// +/// A collection associating the Shader source URLs and their corresponding s. +/// +[DataContract] +public sealed class HashSourceCollection : Dictionary, IEquatable +{ + /// + /// Initializes a new instance of the class. + /// + public HashSourceCollection() { } + + + /// + public bool Equals(HashSourceCollection other) + { + if (other is null) + return false; + if (ReferenceEquals(this, other)) + return true; + + return Utilities.Compare(this, other); + } + + /// + public override bool Equals(object obj) + { + return obj is HashSourceCollection other && Equals(other); + } + + /// + public override int GetHashCode() + { + return Utilities.GetHashCode(this); + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs new file mode 100644 index 0000000000..bbc591d2af --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs @@ -0,0 +1,334 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Stride.Core.Storage; + +/// +/// A hash to uniquely identify data. +/// +[StructLayout(LayoutKind.Sequential, Pack = 4)] +#if !STRIDE_ASSEMBLY_PROCESSOR +[DataContract("ObjectId"),Serializable] +#endif +public unsafe partial struct ObjectId : IEquatable, IComparable +{ + // *************************************************************** + // NOTE: This file is shared with the AssemblyProcessor. + // If this file is modified, the AssemblyProcessor has to be + // recompiled separately. See build\Stride-AssemblyProcessor.sln + // *************************************************************** + + // Murmurshash3 ahsh size is 128 bits. + public const int HashSize = 16; + public const int HashStringLength = HashSize * 2; + private const int HashSizeInUInt = HashSize / sizeof(uint); + private const string HexDigits = "0123456789abcdef"; + + public static readonly ObjectId Empty = new(); + + private uint hash1; + private uint hash2; + private uint hash3; + private uint hash4; + + /// + /// Initializes a new instance of the struct. + /// + /// The hash. + /// hash + /// ObjectId value doesn't match expected size. + public ObjectId(byte[] hash) + { +#if NET7_0_OR_GREATER + ArgumentNullException.ThrowIfNull(hash); +#else + if (hash is null) throw new ArgumentNullException(nameof(hash)); +#endif // NET7_0_OR_GREATER + + if (hash.Length != HashSize) + throw new InvalidOperationException("ObjectId value doesn't match expected size."); + + fixed (byte* hashSource = hash) + { + var hashSourceCurrent = (uint*)hashSource; + hash1 = *hashSourceCurrent++; + hash2 = *hashSourceCurrent++; + hash3 = *hashSourceCurrent++; + hash4 = *hashSourceCurrent; + } + } + + public ObjectId(uint hash1, uint hash2, uint hash3, uint hash4) + { + this.hash1 = hash1; + this.hash2 = hash2; + this.hash3 = hash3; + this.hash4 = hash4; + } + + public static explicit operator ObjectId(Guid guid) + { + return Unsafe.As(ref guid); + } + + public static ObjectId Combine(ObjectId left, ObjectId right) + { + // Note: we don't carry (probably not worth the performance hit) + return new ObjectId + { + hash1 = left.hash1 * 3 + right.hash1, + hash2 = left.hash2 * 3 + right.hash2, + hash3 = left.hash3 * 3 + right.hash3, + hash4 = left.hash4 * 3 + right.hash4, + }; + } + + public static void Combine(ref ObjectId left, ref ObjectId right, out ObjectId result) + { + // Note: we don't carry (probably not worth the performance hit) + result = new ObjectId + { + hash1 = left.hash1 * 3 + right.hash1, + hash2 = left.hash2 * 3 + right.hash2, + hash3 = left.hash3 * 3 + right.hash3, + hash4 = left.hash4 * 3 + right.hash4, + }; + } + + /// + /// Performs an explicit conversion from to []. + /// + /// The object id. + /// The result of the conversion. + public static explicit operator byte[](ObjectId objectId) + { + var result = new byte[HashSize]; + var hashSource = &objectId.hash1; + fixed (byte* hashDest = result) + { + var hashSourceCurrent = (uint*)hashSource; + var hashDestCurrent = (uint*)hashDest; + for (var i = 0; i < HashSizeInUInt; ++i) + *hashDestCurrent++ = *hashSourceCurrent++; + } + return result; + } + + /// + /// Implements the ==. + /// + /// The left. + /// The right. + /// The result of the operator. + public static bool operator ==(ObjectId left, ObjectId right) + { + return left.Equals(right); + } + + /// + /// Implements the !=. + /// + /// The left. + /// The right. + /// The result of the operator. + public static bool operator !=(ObjectId left, ObjectId right) + { + return !left.Equals(right); + } + + /// + /// Tries to parse an from a string. + /// + /// The input hexa string. + /// The result ObjectId. + /// true if parsing was successfull, false otherwise + public static bool TryParse(string input, out ObjectId result) + { + if (input.Length != HashStringLength) + { + result = Empty; + return false; + } + + var hash = stackalloc byte[HashSize]; + for (var i = 0; i < HashStringLength; i += 2) + { + var c1 = input[i]; + var c2 = input[i + 1]; + + int digit1, digit2; + if (((digit1 = HexDigits.IndexOf(c1)) == -1) + || ((digit2 = HexDigits.IndexOf(c2)) == -1)) + { + result = Empty; + return false; + } + + hash[i >> 1] = (byte)((digit1 << 4) | digit2); + } + + var hashSpan = new Span(hash, HashSizeInUInt); + result = new ObjectId(hashSpan[0], hashSpan[1], hashSpan[2], hashSpan[3]); + return true; + } + + /// + public bool Equals(ObjectId other) + { + // Compare content + fixed (uint* xPtr = &hash1) + { + var x1 = xPtr; + var y1 = &other.hash1; + + for (var i = 0; i < HashSizeInUInt; ++i) + { + if (*x1++ != *y1++) + return false; + } + } + + return true; + } + + /// + public override bool Equals(object? obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is ObjectId objectId && Equals(objectId); + } + + /// + public override readonly int GetHashCode() => (int)hash1; + + /// + public int CompareTo(ObjectId other) + { + // Compare content + fixed (uint* xPtr = &hash1) + { + var x1 = xPtr; + var y1 = &other.hash1; + + for (var i = 0; i < HashSizeInUInt; ++i) + { + var compareResult = (*x1++).CompareTo(*y1++); + if (compareResult != 0) + return compareResult; + } + } + + return 0; + } + + public override string ToString() + { +#if NET6_0_OR_GREATER + fixed (uint* hashStart = &hash1) + { + return string.Create(HashStringLength, (IntPtr)hashStart, (c, state) => + { + var hashBytes = (byte*)state; + for (var i = 0; i < HashStringLength; ++i) + { + var index0 = i >> 1; + var b = (byte)(hashBytes[index0] >> 4); + c[i++] = HexDigits[b]; + + b = (byte)(hashBytes[index0] & 0x0F); + c[i] = HexDigits[b]; + } + }); + } +#else + Span span = stackalloc char[HashStringLength]; + + fixed (uint* hashStart = &hash1) + { + var hashBytes = (byte*)hashStart; + for (var i = 0; i < HashStringLength; ++i) + { + var index0 = i >> 1; + var b = (byte)(hashBytes[index0] >> 4); + span[i++] = HexDigits[b]; + + b = (byte)(hashBytes[index0] & 0x0F); + span[i] = HexDigits[b]; + } + } + return ((ReadOnlySpan)span).ToString(); +#endif + } + + /// + /// Gets a from this object identifier. + /// + /// Guid. + public Guid ToGuid() + { + return Unsafe.As(ref this); + } + + /// + /// News this instance. + /// + /// ObjectId. + public static ObjectId New() + { + return FromBytes(Guid.NewGuid().ToByteArray()); + } + + /// + /// Computes a hash from a byte buffer. + /// + /// The byte buffer. + /// The hash of the object. + /// buffer + public static ObjectId FromBytes(ReadOnlySpan buffer) + { + var builder = new ObjectIdBuilder(); + builder.Write(buffer); + return builder.ComputeHash(); + } + + /// + /// Computes a hash from a byte buffer. + /// + /// The byte buffer. + /// The hash of the object. + /// buffer + public static ObjectId FromBytes(byte[] buffer) + { +#if NET7_0_OR_GREATER + ArgumentNullException.ThrowIfNull(buffer); +#else + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); +#endif // NET7_0_OR_GREATER + + return FromBytes(buffer, 0, buffer.Length); + } + + /// + /// Computes a hash from a byte buffer. + /// + /// The byte buffer. + /// The offset into the buffer. + /// The number of bytes to read from the buffer starting at offset position. + /// The hash of the object. + /// buffer + public static ObjectId FromBytes(byte[] buffer, int offset, int count) + { +#if NET7_0_OR_GREATER + ArgumentNullException.ThrowIfNull(buffer); +#else + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); +#endif // NET7_0_OR_GREATER + + var builder = new ObjectIdBuilder(); + builder.Write(buffer, offset, count); + return builder.ComputeHash(); + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs b/src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs new file mode 100644 index 0000000000..0f753dc6d9 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs @@ -0,0 +1,437 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// (ignore analyzers) +// +// Copyright 2012 Darren Kopp +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Stride.Core.Storage; + +/// +/// A builder for using Murmurshash3 128 bits +/// +[StructLayout(LayoutKind.Sequential, Pack = 4)] +public unsafe struct ObjectIdBuilder +{ + // *************************************************************** + // NOTE: This file is shared with the AssemblyProcessor. + // If this file is modified, the AssemblyProcessor has to be + // recompiled separately. See build\Stride-AssemblyProcessor.sln + // *************************************************************** + + private readonly uint seed; + const uint C1 = 0x239b961b; + const uint C2 = 0xab0e9789; + const uint C3 = 0x38b34ae5; + const uint C4 = 0xa1e38b93; + + public ObjectIdBuilder(uint seed = 0) + { + this.seed = seed; + + // initialize hash values to seed values + H1 = H2 = H3 = H4 = seed; + currentLength = 0; + + currentBlock1 = 0; + currentBlock2 = 0; + currentBlock3 = 0; + currentBlock4 = 0; + } + + public uint Seed => seed; + public int Length => currentLength; + + private uint H1; + private uint H2; + private uint H3; + private uint H4; + private int currentLength; + + private uint currentBlock1; + private uint currentBlock2; + private uint currentBlock3; + private uint currentBlock4; + + public void Reset() + { + // initialize hash values to seed values + H1 = H2 = H3 = H4 = Seed; + currentLength = 0; + } + + /// + /// Gets the current calculated hash. + /// + /// The current hash. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ObjectId ComputeHash() + { + ComputeHash(out var result); + return result; + } + + /// + /// Gets the current calculated hash. + /// + /// The current hash. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void ComputeHash(out ObjectId result) + { + // create our keys and initialize to 0 + uint k1 = 0, k2 = 0, k3 = 0, k4 = 0; + + var remainder = currentLength % 16; + + fixed (uint* currentBlockStart = ¤tBlock1) + { + var tail = (byte*)currentBlockStart; + + // determine how many bytes we have left to work with based on length + switch (remainder) + { + case 15: k4 ^= (uint)tail[14] << 16; goto case 14; + case 14: k4 ^= (uint)tail[13] << 8; goto case 13; + case 13: k4 ^= (uint)tail[12] << 0; goto case 12; + case 12: k3 ^= (uint)tail[11] << 24; goto case 11; + case 11: k3 ^= (uint)tail[10] << 16; goto case 10; + case 10: k3 ^= (uint)tail[9] << 8; goto case 9; + case 9: k3 ^= (uint)tail[8] << 0; goto case 8; + case 8: k2 ^= (uint)tail[7] << 24; goto case 7; + case 7: k2 ^= (uint)tail[6] << 16; goto case 6; + case 6: k2 ^= (uint)tail[5] << 8; goto case 5; + case 5: k2 ^= (uint)tail[4] << 0; goto case 4; + case 4: k1 ^= (uint)tail[3] << 24; goto case 3; + case 3: k1 ^= (uint)tail[2] << 16; goto case 2; + case 2: k1 ^= (uint)tail[1] << 8; goto case 1; + case 1: k1 ^= (uint)tail[0] << 0; break; + } + } + + var h4 = H4 ^ RotateLeft((k4 * C4), 18) * C1; + var h3 = H3 ^ RotateLeft((k3 * C3), 17) * C4; + var h2 = H2 ^ RotateLeft((k2 * C2), 16) * C3; + var h1 = H1 ^ RotateLeft((k1 * C1), 15) * C2; + + var len = (uint)currentLength; + // pipelining friendly algorithm + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += (h2 + h3 + h4); + h2 += h1; h3 += h1; h4 += h1; + + h1 = FMix(h1); + h2 = FMix(h2); + h3 = FMix(h3); + h4 = FMix(h4); + + h1 += (h2 + h3 + h4); + h2 += h1; h3 += h1; h4 += h1; + + fixed (void* ptr = &result) + { + var h = (uint*)ptr; + *h++ = h1; + *h++ = h2; + *h++ = h3; + *h = h4; + } + } + + /// + /// Writes a byte to the builder. + /// + /// The value. + public void WriteByte(byte value) + { + ref var currentBlock = ref Unsafe.As(ref currentBlock1); + + var position = currentLength++ & 15; + + Unsafe.Add(ref currentBlock, position) = value; + + if (position == 15) + { + BodyCore(ref currentBlock); + } + } + + + /// + /// Writes a buffer of byte to this builder. + /// + /// The buffer. + /// buffer + /// buffer + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(byte[] buffer) + { +#if NET7_0_OR_GREATER + ArgumentNullException.ThrowIfNull(buffer); +#else + if (buffer is null) throw new ArgumentNullException(nameof(buffer)); +#endif // NET7_0_OR_GREATER + + Write(buffer.AsSpan()); + } + + /// + /// Writes a buffer of byte to this builder. + /// + /// The buffer. + /// The offset. + /// The count. + /// buffer + /// count;Offset + Count is out of range + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(byte[] buffer, int offset, int count) + => Write(buffer.AsSpan(offset, count)); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(string str) + => Write(str.AsSpan()); + + /// + /// Writes the specified buffer to this instance. + /// + /// Type must be a struct + /// The data. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(T data) where T : unmanaged + { +#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER + Write(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref data), Unsafe.SizeOf())); +#else + fixed (byte* buffer = &Unsafe.As(ref data)) + Write(new ReadOnlySpan(buffer, Unsafe.SizeOf())); +#endif + } + + /// + /// Writes the specified buffer to this instance. + /// + /// Type must be a struct + /// The buffer. + /// The offset. + /// The count. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(T[] buffer, int offset, int count) where T : unmanaged + => Write(buffer.AsSpan(offset, count)); + + /// + /// Writes the specified buffer to this instance. + /// + /// Type must be a struct + /// The buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Write(ReadOnlySpan buffer) where T : unmanaged + => Write(MemoryMarshal.AsBytes(buffer)); + + /// + /// Writes a buffer of byte to this builder. + /// + /// The buffer. + /// The lenght. + /// buffer + /// count;Offset + Count is out of range + [Obsolete("Use Write(ReadOnlySpan)")] + public void Write(byte* buffer, int length) + { + fixed (uint* currentBlockStart = ¤tBlock1) + { + var currentBlock = (byte*)currentBlockStart; + var position = currentLength % 16; + + currentLength += length; + + // Partial block to continue? + if (position != 0) + { + var remainder = 16 - position; + + var partialLength = length; + if (partialLength > remainder) + partialLength = remainder; + + var dest = currentBlock + position; + for (var copyLength = partialLength; copyLength > 0; --copyLength) + *dest++ = *buffer++; + length -= partialLength; + + //Utilities.CopyMemory((IntPtr)currentBlock + position, (IntPtr)buffer, partialLength); + //buffer += partialLength; + //length -= partialLength; + + if (partialLength == remainder) + { + BodyCore(currentBlock); + } + } + + if (length > 0) + { + var blocks = length / 16; + length -= blocks * 16; + + // Main loop + while (blocks-- > 0) + { + BodyCore(buffer); + buffer += 16; + } + + // Start partial block + for (; length > 0; --length) + *currentBlock++ = *buffer++; + //if (length > 0) + //{ + // Utilities.CopyMemory((IntPtr)currentBlock, (IntPtr)buffer, length); + //} + } + } + } + + /// + /// Writes a buffer of byte to this builder. + /// + /// The readonly span. + /// buffer + /// count;Offset + Count is out of range + public void Write(ReadOnlySpan span) + { + ref var currentBlock = ref Unsafe.As(ref currentBlock1); + var position = currentLength % 16; + ref byte buffer = ref Unsafe.AsRef(in span.GetPinnableReference()); + int length = span.Length; + + currentLength += length; + + // Partial block to continue? + if (position != 0) + { + var remainder = 16 - position; + + var partialLength = length; + if (partialLength > remainder) + partialLength = remainder; + +#warning PERF: Do not copy byte-for-byte. + ref var dest = ref Unsafe.Add(ref currentBlock, position); + for (var copyLength = partialLength; copyLength > 0; --copyLength) + { + dest = buffer; + dest = ref Unsafe.Add(ref dest, 1); + buffer = ref Unsafe.Add(ref buffer, 1); + } + length -= partialLength; + + if (partialLength == remainder) + { + BodyCore(ref currentBlock); + } + } + + if (length > 0) + { + var blocks = length / 16; + length -= blocks * 16; + + // Main loop + while (blocks-- > 0) + { + BodyCore(ref buffer); + buffer = ref Unsafe.Add(ref buffer, 16); + } + + // Start partial block +#warning PERF: Do not copy byte-for-byte. + for (; length > 0; --length) + { + currentBlock = buffer; + currentBlock = ref Unsafe.Add(ref currentBlock, 1); + buffer = ref Unsafe.Add(ref buffer, 1); + } + } + } + [MethodImpl(MethodImplOptions.AggressiveInlining), Obsolete("Use BodyCore(ref byte)")] + private void BodyCore(byte* data) + { + var b = (uint*)data; + + // K1 - consume first integer + H1 ^= RotateLeft((*b++ * C1), 15) * C2; + H1 = (RotateLeft(H1, 19) + H2) * 5 + 0x561ccd1b; + + // K2 - consume second integer + H2 ^= RotateLeft((*b++ * C2), 16) * C3; + H2 = (RotateLeft(H2, 17) + H3) * 5 + 0x0bcaa747; + + // K3 - consume third integer + H3 ^= RotateLeft((*b++ * C3), 17) * C4; + H3 = (RotateLeft(H3, 15) + H4) * 5 + 0x96cd1c35; + + // K4 - consume fourth integer + H4 ^= RotateLeft((*b++ * C4), 18) * C1; + H4 = (RotateLeft(H4, 13) + H1) * 5 + 0x32ac3b17; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void BodyCore(ref byte data) + { + ref var b = ref Unsafe.As(ref data); + + // K1 - consume first integer + H1 ^= RotateLeft((b * C1), 15) * C2; + H1 = (RotateLeft(H1, 19) + H2) * 5 + 0x561ccd1b; + b = ref Unsafe.Add(ref b, 1); + + // K2 - consume second integer + H2 ^= RotateLeft((b * C2), 16) * C3; + H2 = (RotateLeft(H2, 17) + H3) * 5 + 0x0bcaa747; + b = ref Unsafe.Add(ref b, 1); + + // K3 - consume third integer + H3 ^= RotateLeft((b * C3), 17) * C4; + H3 = (RotateLeft(H3, 15) + H4) * 5 + 0x96cd1c35; + b = ref Unsafe.Add(ref b, 1); + + // K4 - consume fourth integer + H4 ^= RotateLeft((b * C4), 18) * C1; + H4 = (RotateLeft(H4, 13) + H1) * 5 + 0x32ac3b17; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static uint RotateLeft(uint x, byte r) + { +#if NETCOREAPP3_0_OR_GREATER + return BitOperations.RotateLeft(x, r); +#else + return (x << r) | (x >> (32 - r)); +#endif + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static uint FMix(uint h) + { + // pipelining friendly algorithm + h = (h ^ (h >> 16)) * 0x85ebca6b; + h = (h ^ (h >> 13)) * 0xc2b2ae35; + return h ^ (h >> 16); + } +} diff --git a/src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs b/src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs new file mode 100644 index 0000000000..7577d3d099 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs @@ -0,0 +1,205 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Collections; +using System.Diagnostics; + +namespace Stride.Core; + +/// +/// Provides a set of static utility methods for collection operations, and general-purpose helpers. +/// +public static class Utilities +{ + /// + /// Disposes an object if not , + /// and sets it to . + /// + /// The disposable object to dispose. + public static void Dispose(ref T? disposable) where T : class, IDisposable + { + disposable?.Dispose(); + disposable = null; + } + + /// + /// Read stream to a byte[] buffer + /// + /// input stream + /// a byte[] buffer + [Obsolete("Allocates. Read into the destination.")] + public static byte[] ReadStream(Stream stream) + { + Debug.Assert(stream != null); + Debug.Assert(stream.CanRead); + + var readLength = (int)(stream.Length - stream.Position); + + Debug.Assert(readLength <= (stream.Length - stream.Position)); + + if (readLength == 0) + { + return []; + } + + var buffer = new byte[readLength]; + var bytesRead = 0; + + while (bytesRead < readLength) + { + bytesRead += stream.Read(buffer, bytesRead, readLength - bytesRead); + } + + return buffer; + } + + /// + /// Computes a hashcode for a dictionary. + /// + /// Hashcode for the list. + public static int GetHashCode(IDictionary dict) + { + if (dict is null) + return 0; + + var hashCode = 0; + foreach (DictionaryEntry keyValue in dict) + { + hashCode = (hashCode * 397) ^ keyValue.Key.GetHashCode(); + hashCode = (hashCode * 397) ^ (keyValue.Value?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Computes a hashcode for an enumeration + /// + /// An enumerator. + /// Hashcode for the list. + public static int GetHashCode(IEnumerable it) + { + if (it is null) + return 0; + + var hashCode = 0; + foreach (var current in it) + { + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Computes a hashcode for an enumeration + /// + /// An enumerator. + /// Hashcode for the list. + public static int GetHashCode(IEnumerator it) + { + if (it is null) + return 0; + + var hashCode = 0; + while (it.MoveNext()) + { + var current = it.Current; + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Compares two collection, element by elements. + /// + /// The collection to compare from. + /// The colllection to compare to. + /// True if lists are identical (but no necessarely of the same time). False otherwise. + public static bool Compare(IDictionary first, IDictionary second) + { + if (ReferenceEquals(first, second)) return true; + if (first is null || second is null) return false; + if (first.Count != second.Count) return false; + + var comparer = EqualityComparer.Default; + + foreach (var keyValue in first) + { + if (!second.TryGetValue(keyValue.Key, out var secondValue)) return false; + if (!comparer.Equals(keyValue.Value, secondValue)) return false; + } + + // Check that all keys in second are in first + return second.Keys.All(first.ContainsKey); + } + + /// + /// Compares two collection, element by elements. + /// + /// The collection to compare from. + /// The colllection to compare to. + /// True if lists are identical (but not necessarily in the same order). False otherwise. + /// Concrete SortedList is favored over interface to avoid enumerator object allocation. + public static bool Compare(Collections.SortedList first, Collections.SortedList second) + { + if (ReferenceEquals(first, second)) return true; + if (first is null || second is null) return false; + if (first.Count != second.Count) return false; + + var comparer = EqualityComparer.Default; + + foreach (var keyValue in first) + { + if (!second.TryGetValue(keyValue.Key, out var secondValue)) return false; + if (!comparer.Equals(keyValue.Value, secondValue)) return false; + } + + return true; + } + + /// + /// Linq assisted full tree iteration and collection in a single line. + /// Warning, could be slow. + /// + /// The type to iterate. + /// The root item + /// The function to retrieve a child + public static IEnumerable IterateTree(T root, Func> childrenF) + { + var q = new List { root }; + while (q.Count != 0) + { + var c = q[0]; + q.RemoveAt(0); + q.AddRange(childrenF(c) ?? []); + yield return c; + } + } + + /// + /// Converts a raw time to a . + /// + /// The delta. + /// The . + public static TimeSpan ConvertRawToTimestamp(long delta) + => delta == 0 ? default : TimeSpan.FromTicks(delta * TimeSpan.TicksPerSecond / Stopwatch.Frequency); +} From fbaeb460a5cbb4edc9d152699947c0b655274eab Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 00:47:38 +0900 Subject: [PATCH 0730/1182] Fix: SymbolType.TryGetBufferType() --- src/Stride.Shaders/Core/SymbolTypes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 1ad0dbe061..15e7efbd69 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -69,7 +69,7 @@ public static bool TryGetBufferType(SymbolTable table, SpirvContext context, str // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) static ScalarType ResolveScalarType(SymbolTable table, SpirvContext context, TypeName? templateTypeName) { - var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.From("float4"); + var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.From("float"); return templateType switch { From a82b7a5ceab06759fd22567c234d97b29ac956fa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 00:48:05 +0900 Subject: [PATCH 0731/1182] l-value: allow assigning back to source (root) element --- .../Parsing/SDSL/AST/Expression.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 6c3a6b3bdf..2d00683993 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -415,7 +415,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal { var (builder, context) = compiler; - // See how far we can compute the lvalue + // Compute the l-value (and all its intermediate values) CompileHelper(table, compiler, null); // Only things left should be: @@ -458,14 +458,15 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal // Swizzle: we transform the value to assign accordingly // We load the original value (if pointer) - if (currentValueType is PointerType p) + var lvalueType = currentValueType; + if (lvalueType is PointerType p) { - rvalue = new(builder.InsertData(new OpLoad(context.GetOrRegister(currentValueType), context.Bound++, rvalue.Id, null, []))); - currentValueType = p.BaseType; + lvalueBase = new(builder.InsertData(new OpLoad(context.GetOrRegister(lvalueType), context.Bound++, lvalueBase.Id, null, []))); + lvalueType = p.BaseType; } // Shuffle with new data - switch (currentValueType) + switch (lvalueType) { case VectorType v: Span shuffleIndices = stackalloc int[v.Size]; @@ -476,7 +477,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal for (int j = 0; j < swizzle.Length; ++j) shuffleIndices[ConvertSwizzle(swizzle[j])] = v.Size + j; // Compute the rvalue at this step (by possibly combining with lvalue if not writing every component) - rvalue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(currentValueType), context.Bound++, lvalueBase.Id, rvalue.Id, new(shuffleIndices)))); + rvalue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(lvalueType), context.Bound++, lvalueBase.Id, rvalue.Id, new(shuffleIndices)))); break; default: throw new NotImplementedException(); @@ -485,6 +486,14 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal } } + // Need to assign to Source + if (Source.Type is PointerType expectedType2) + { + rvalue = builder.Convert(context, rvalue, expectedType2.BaseType); + builder.Insert(new OpStore(intermediateValues[0].Id, rvalue.Id, null, [])); + return; + } + // We should not reach this point (unless we can't write back to lvalue) ThrowErrorOnLValue(); } From 9405fef88bbf2131a474a40325a53eafe989000d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 01:23:17 +0900 Subject: [PATCH 0732/1182] ScalarType: use enum instead of string --- .../SDSL/ShaderMixer.CBuffers.cs | 10 +-- .../Examples.Spirv.cs | 10 +-- .../Core/SymbolTypes.Globals.cs | 44 ++++------- src/Stride.Shaders/Core/SymbolTypes.cs | 41 +++++++++- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 42 +++++------ .../Parsing/SDSL/AST/Expression.cs | 18 ++--- .../Parsing/SDSL/AST/Literals.cs | 6 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 18 ++--- .../Parsing/SDSL/AST/Statements.Control.cs | 2 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 4 +- .../Parsing/SDSL/AST/Statements.cs | 4 +- .../PrimaryExpressionParsers.cs | 8 +- .../Spirv/Building/Builder.CBuffer.cs | 6 +- .../Spirv/Building/Builder.Class.cs | 6 +- .../Spirv/Building/Builder.Expressions.cs | 74 +++++++++---------- .../Spirv/Building/Builder.Functions.cs | 2 +- .../Spirv/Building/Context.Constants.cs | 42 +++++------ .../Spirv/Building/SpirvContext.Types.cs | 23 +++--- .../Spirv/Processing/InterfaceProcessor.cs | 2 +- 19 files changed, 182 insertions(+), 180 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 622589aab0..ef01e7bd92 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -353,11 +353,11 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, T { return symbolType switch { - ScalarType { TypeName: "bool" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Bool, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "uint" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.UInt, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "int" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "float" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, - ScalarType { TypeName: "double" } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Double, RowCount = 1, ColumnCount = 1, ElementSize = 8 }, + ScalarType { Type: Scalar.Boolean } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Bool, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { Type: Scalar.UInt } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.UInt, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { Type: Scalar.Int } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Int, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { Type: Scalar.Float } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Float, RowCount = 1, ColumnCount = 1, ElementSize = 4 }, + ScalarType { Type: Scalar.Double } => new EffectTypeDescription { Class = EffectParameterClass.Scalar, Type = EffectParameterType.Double, RowCount = 1, ColumnCount = 1, ElementSize = 8 }, ArrayType a => ConvertArrayType(context, a, typeModifier, alignmentRules), StructType s => ConvertStructType(context, s, alignmentRules), // TODO: should we use RowCount instead? (need to update Stride) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index d31f9f8a38..15433f9c85 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -18,8 +18,8 @@ public static void GenerateSpirv() var compiler = new CompilerUnit(); var (builder, context) = compiler; - context.GetOrRegister(new MatrixType(ScalarType.From("float"), 4, 3)); - context.GetOrRegister(ScalarType.From("int")); + context.GetOrRegister(new MatrixType(ScalarType.Float, 4, 3)); + context.GetOrRegister(ScalarType.Int); // context.AddGlobalVariable(new(new("color", SymbolKind.Variable, Storage.Stream), VectorType.From("float4"))); @@ -27,11 +27,11 @@ public static void GenerateSpirv() var function = builder.DeclareFunction( context, "add", - new(ScalarType.From("int"), [new(ScalarType.From("int"), default), new(ScalarType.From("int"), default)]) + new(ScalarType.Int, [new(ScalarType.Int, default), new(ScalarType.Int, default)]) ); builder.BeginFunction(context, function); - builder.AddFunctionParameter(context, "a", ScalarType.From("int")); - builder.AddFunctionParameter(context, "b", ScalarType.From("int")); + builder.AddFunctionParameter(context, "a", ScalarType.Int); + builder.AddFunctionParameter(context, "b", ScalarType.Int); builder.SetPositionTo(function); var block = builder.CreateBlock(context, "sourceBlock"); builder.SetPositionTo(block); diff --git a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs index 574f2f5d6a..b24c0ff455 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs @@ -5,39 +5,21 @@ namespace Stride.Shaders.Core; public partial record ScalarType { - public static string[] names = [ - "bool", - "byte", - "sbyte", - "short", - "ushort", - "half", - "int", - "uint", - "float", - "long", - "ulong", - "double" + internal static KeyValuePair[] names = [ + new("void", Void), + new("bool", Boolean), + new("int", Int), + new("uint", UInt), + new("long", Int64), + new("ulong", UInt64), + new("float", Float), + new("double", Double), ]; public static ScalarType From(string s) => Types[s]; public static FrozenDictionary Types { get; } = Init(); - // static Scalar() - // { - // var arr = new KeyValuePair[names.Length + 1]; - // arr[0] = new("void", new("void")); - // for(int i = 1; i < names.Length; i++) - // arr[i] = new(names[i], new(names[i])); - // Types = FrozenDictionary.ToFrozenDictionary(arr); - // } - internal static FrozenDictionary Init() - { - var arr = new KeyValuePair[names.Length + 1]; - arr[0] = new("void", new("void")); - for(int i = 1; i < names.Length + 1; i++) - arr[i] = new(names[i - 1], new(names[i - 1])); - return arr.ToFrozenDictionary(); - } + internal static FrozenDictionary Init() => + FrozenDictionary.Create(names); } public partial record VectorType @@ -50,7 +32,7 @@ internal static FrozenDictionary Init() var arr = new KeyValuePair[ScalarType.names.Length * 3]; for(int i = 0; i < ScalarType.names.Length; i++) for(int x = 2; x <= 4; x++) - arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i]}{x}", new(ScalarType.From(ScalarType.names[i]),x)); + arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i].Key}{x}", new(ScalarType.names[i].Value,x)); return arr.ToFrozenDictionary(); } } @@ -67,7 +49,7 @@ internal static FrozenDictionary Init() for(int x = 2; x <= 4; x++) for(int y = 2; y <= 4; y++) // Note: this is HLSL-style so Rows/Columns meaning is swapped - arr.Add(new($"{ScalarType.names[i]}{y}x{x}", new(ScalarType.From(ScalarType.names[i]),x,y))); + arr.Add(new($"{ScalarType.names[i].Key}{y}x{x}", new(ScalarType.names[i].Value,x,y))); return arr.ToFrozenDictionary(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 15e7efbd69..9715fb392b 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -45,7 +45,7 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT } else if (name == "void") { - result = ScalarType.From("void"); + result = ScalarType.Void; return true; } else @@ -69,7 +69,7 @@ public static bool TryGetBufferType(SymbolTable table, SpirvContext context, str // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) static ScalarType ResolveScalarType(SymbolTable table, SpirvContext context, TypeName? templateTypeName) { - var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.From("float"); + var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.Float; return templateType switch { @@ -134,9 +134,42 @@ public sealed partial record PointerType(SymbolType BaseType, Specification.Stor public override string ToString() => $"*{BaseType}"; } -public sealed partial record ScalarType(string TypeName) : SymbolType() +public enum Scalar { - public override string ToString() => TypeName; + Void, + Boolean, + Int, + UInt, + Int64, + UInt64, + //Half, + Float, + Double +} + +public sealed partial record ScalarType(Scalar Type) : SymbolType() +{ + public static ScalarType Void { get; } = new(Scalar.Void); + public static ScalarType Boolean { get; } = new(Scalar.Boolean); + public static ScalarType Int { get; } = new(Scalar.Int); + public static ScalarType UInt { get; } = new(Scalar.UInt); + public static ScalarType Int64 { get; } = new(Scalar.Int64); + public static ScalarType UInt64 { get; } = new(Scalar.UInt64); + public static ScalarType Float { get; } = new(Scalar.Float); + public static ScalarType Double { get; } = new(Scalar.Double); + + public override string ToString() => Type switch + { + Scalar.Void => "void", + Scalar.Boolean => "bool", + Scalar.Int => "int", + Scalar.UInt => "uint", + Scalar.Int64 => "long", + Scalar.UInt64 => "ulong", + Scalar.Float => "float", + Scalar.Double => "double", + _ => throw new ArgumentOutOfRangeException() + }; } public sealed partial record VectorType(ScalarType BaseType, int Size) : SymbolType() { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index a5b63ce741..4cdfa1c7cd 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -120,7 +120,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (context.GLSLSet == null) context.ImportGLSL(); - var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("float")); + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); x = builder.Convert(context, x, parameterType); var instruction = builder.Insert(new GLSLExp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); @@ -207,9 +207,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var instruction = resultType.GetElementType() switch { - ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), }; return new(instruction); } @@ -233,9 +233,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var instruction = resultType.GetElementType() switch { - ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), }; return new(instruction); } @@ -263,9 +263,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var instruction = baseType switch { - ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), - ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), - ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), }; return new(instruction); } @@ -290,9 +290,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var instruction = baseType switch { - ScalarType { TypeName: "float" } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), - ScalarType { TypeName: "uint" } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), - ScalarType { TypeName: "int" } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), }; return new(instruction); } @@ -311,7 +311,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var yType = Parameters.Values[1].ValueType; var aType = Parameters.Values[2].ValueType; - var resultType = IntrinsicHelper.FindCommonType(ScalarType.From("float"), xType, yType, aType); + var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType, aType); x = builder.Convert(context, x, resultType); y = builder.Convert(context, y, resultType); @@ -558,10 +558,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (context.GLSLSet == null) context.ImportGLSL(); - var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("float")); + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); x = builder.Convert(context, x, parameterType); - var resultType = ScalarType.From("float"); + var resultType = ScalarType.Float; var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } @@ -576,7 +576,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; - var resultType = ScalarType.From("float"); + var resultType = ScalarType.Float; var inputTypes = IntrinsicHelper.FindCommonType(resultType, xType, yType); x = builder.Convert(context, x, resultType); @@ -787,10 +787,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); - var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("bool")); + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Boolean); x = builder.Convert(context, x, parameterType); - var instruction = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.From("bool")), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.Boolean), context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } @@ -803,7 +803,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); - var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.From("float")); + var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); x = builder.Convert(context, x, parameterType); var instruction = builder.Insert(new OpFwidth(x.TypeId, context.Bound++, x.Id)); @@ -865,7 +865,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, { var (builder, context) = compiler; var dest = Parameters.Values[0].Compile(table, compiler); - if (Parameters.Values[0].Type is not PointerType pointerType || pointerType.BaseType is not ScalarType { TypeName: "uint" or "int" } s) + if (Parameters.Values[0].Type is not PointerType pointerType || pointerType.BaseType is not ScalarType { Type: Scalar.UInt or Scalar.Int } s) throw new InvalidOperationException($"l-value int or uint expected but got {Parameters.Values[0].Type}"); var resultType = s; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 2d00683993..c65829c2d4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -329,7 +329,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } case Operator.Not: { - if (valueType.GetElementType() is not ScalarType { TypeName: "bool" }) + if (valueType.GetElementType() is not ScalarType { Type: Scalar.Boolean }) throw new InvalidOperationException(); var result = builder.Insert(new OpLogicalNot(valueExpression.TypeId, context.Bound++, valueExpression.Id)); Type = valueType; @@ -449,7 +449,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal var resultType = new VectorType(textureType.ReturnType, 4); var imageValue = builder.AsValue(context, lvalueBase); - var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.From("int")); + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); var texelValue = builder.Convert(context, rvalue, resultType); builder.Insert(new OpImageWrite(imageValue.Id, imageCoordValue.Id, texelValue.Id, null, [])); // We stop there @@ -609,7 +609,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); + var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -634,10 +634,10 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso var resultType = new VectorType(textureType.ReturnType, 4); var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); + var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); - levelValue = builder.Convert(context, levelValue, ScalarType.From("float")); + levelValue = builder.Convert(context, levelValue, ScalarType.Float); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -670,7 +670,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso throw new InvalidOperationException(); var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.From("float")); + var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); @@ -742,7 +742,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso var resultType = new VectorType(textureType.ReturnType, 4); var imageValue = builder.AsValue(context, result); - var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.From("int")); + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); var imageRead = builder.Insert(new OpImageRead(context.GetOrRegister(resultType), context.Bound++, imageValue.Id, imageCoordValue.Id, null, [])); result = new(imageRead.ResultId, imageRead.ResultType); @@ -970,7 +970,7 @@ SpirvValue ConvertOffset(SpirvContext context, SpirvBuilder builder, TextureType Texture3DType or TextureCubeType => 3, }; - spirvValue = builder.Convert(context, spirvValue, ScalarType.From("int").GetVectorOrScalar(offsetSize)); + spirvValue = builder.Convert(context, spirvValue, ScalarType.Int.GetVectorOrScalar(offsetSize)); return spirvValue; } @@ -1056,7 +1056,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, using (builder.UseTemporaryBuffer(rightValueBuffer)) rightResult = Right.CompileAsValue(table, compiler); - if (Condition.ValueType.GetElementType() is not ScalarType { TypeName: "bool" }) + if (Condition.ValueType.GetElementType() is not ScalarType { Type: Scalar.Boolean }) table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); var scalarType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(Left.ValueType.GetElementType(), Right.ValueType.GetElementType()); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 7b28ae4c72..ea7586339c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -72,7 +72,7 @@ public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : Numb public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { // If expectedType is float, handle it: - if (expectedType is ScalarType { TypeName: "float" }) + if (expectedType is ScalarType { Type: Scalar.Float }) { Type = expectedType; return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), value, null, info)); @@ -95,14 +95,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(value > uint.MaxValue ? 64 : 32, false, false), (long)value, info) { - public override SymbolType? Type => Suffix.Size > 32 ? ScalarType.From("ulong") : ScalarType.From("uint"); + public override SymbolType? Type => Suffix.Size > 32 ? ScalarType.UInt64 : ScalarType.UInt; } public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; - public override SymbolType? Type => ScalarType.From("bool"); + public override SymbolType? Type => ScalarType.Boolean; public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 85e6ca50f9..63201c9695 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -102,9 +102,9 @@ void RegisterName(int target, string name) RegisterType(floatInstruction.ResultId, floatInstruction.Width switch { - 16 => ScalarType.From("half"), - 32 => ScalarType.From("float"), - 64 => ScalarType.From("double"), + 16 => throw new NotImplementedException(), + 32 => ScalarType.Float, + 64 => ScalarType.Double, _ => throw new InvalidOperationException(), }); } @@ -113,16 +113,16 @@ void RegisterName(int target, string name) OpTypeInt intInstruction = instruction; RegisterType(intInstruction.ResultId, (intInstruction.Width, intInstruction.Signedness == 1) switch { - (32, true) => ScalarType.From("int"), - (32, false) => ScalarType.From("uint"), - (64, true) => ScalarType.From("long"), - (64, false) => ScalarType.From("ulong"), + (32, true) => ScalarType.Int, + (32, false) => ScalarType.UInt, + (64, true) => ScalarType.Int64, + (64, false) => ScalarType.UInt64, }); } else if (instruction.Op == Op.OpTypeBool) { OpTypeBool boolInstruction = instruction; - RegisterType(boolInstruction.ResultId, ScalarType.From("bool")); + RegisterType(boolInstruction.ResultId, ScalarType.Boolean); } else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is { } pointerInstruction) { @@ -131,7 +131,7 @@ void RegisterName(int target, string name) } else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is { } voidInstruction) { - RegisterType(voidInstruction.ResultId, ScalarType.From("void")); + RegisterType(voidInstruction.ResultId, ScalarType.Void); } else if (instruction.Op == Op.OpTypeVector && (OpTypeVector)instruction is { } vectorInstruction) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index a5386388e7..87c8d13507 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -39,7 +39,7 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) table.Errors.Add(new(currentIf.Condition.Info, "if statement conditional expressions must evaluate to a scalar")); // Might need implicit conversion from float/int to bool - conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); + conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); int? falseBlock = (i + 1 < ElseIfs.Count + 1 || Else != null) ? context.Bound++ diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 4a2fefc0b8..39d2557134 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -93,7 +93,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) table.Errors.Add(new(Condition.Info, "while statement condition expression must evaluate to a scalar")); // Might need implicit conversion from float/int to bool - conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); + conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); Body.Compile(table, compiler); throw new NotImplementedException(); @@ -146,7 +146,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) table.Errors.Add(new(Condition.Info, "for statement condition expression must evaluate to a scalar")); // Might need implicit conversion from float/int to bool - conditionValue = builder.Convert(context, conditionValue, ScalarType.From("bool")); + conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None, [])); builder.Insert(new OpBranchConditional(conditionValue.Id, forBodyBlock, currentEscapeBlocks.MergeBlock, [])); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 924698dad0..42cfbde0c2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -15,7 +15,7 @@ public abstract class Statement(TextLocation info) : ValueNode(info) public class EmptyStatement(TextLocation info) : Statement(info) { - public override SymbolType? Type { get => ScalarType.From("void"); set { } } + public override SymbolType? Type { get => ScalarType.Void; set { } } public override void Compile(SymbolTable table, CompilerUnit compiler) { } public override string ToString() => ";"; } @@ -28,7 +28,7 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta public override void Compile(SymbolTable table, CompilerUnit compiler) { Expression.Compile(table, compiler); - Type = ScalarType.From("void"); + Type = ScalarType.Void; } public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 4d21fedb5d..b43c2ad554 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -64,10 +64,10 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("any", _) => new BoolToScalarBoolCall(parameters, scanner[position..scanner.Position], Specification.Op.OpAny), // Cast - ("asdouble", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("double")), - ("asfloat", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("float")), - ("asint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("int")), - ("asuint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.From("uint")), + ("asdouble", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Double), + ("asfloat", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Float), + ("asint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Int), + ("asuint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.UInt), // Trigo ("sin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSin), diff --git a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs index 691527cdfe..d7cd1699ff 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs @@ -26,10 +26,8 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type }; return (symbol) switch { - ScalarType { TypeName: "sbyte" or "byte" } => (1, 1), - ScalarType { TypeName: "short" or "ushort" } => (2, 2), - ScalarType { TypeName: "int" or "uint" or "float" or "bool" } => (4, 4), - ScalarType { TypeName: "long" or "ulong" or "double" } => (8, 8), + ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Boolean } => (4, 4), + ScalarType { Type: Scalar.Int64 or Scalar.UInt64 or Scalar.Double } => (8, 8), StructuredType s => StructSizeInBuffer(s, alignmentRules), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules), v.Size), // Note: this is HLSL-style so Rows/Columns meaning is swapped diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 8f8efb50f6..990dbf96b2 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -224,13 +224,13 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str var genericValue = genericValues![index]; switch (genericParameterType) { - case ScalarType { TypeName: "int" }: + case ScalarType { Type: Scalar.Int }: value = int.Parse(genericValue); return true; - case ScalarType { TypeName: "float" }: + case ScalarType { Type: Scalar.Float }: value = float.Parse(genericValue); return true; - case ScalarType { TypeName: "bool" }: + case ScalarType { Type: Scalar.Boolean }: value = bool.Parse(genericValue); return true; case GenericParameterType g: diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index f1a6d925f6..f19c2930e6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -86,15 +86,15 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle { return (leftElementType, rightElementType) switch { - (ScalarType { TypeName: "long" }, _) or (_, ScalarType { TypeName: "long" }) => throw new NotImplementedException("64bit integers"), + (ScalarType { Type: Scalar.Int64 }, _) or (_, ScalarType { Type: Scalar.Int64 }) => throw new NotImplementedException("64bit integers"), // Matching types - (ScalarType { TypeName: "int" or "uint" or "float" or "double" or "bool" } l, ScalarType r) when l == r => l, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double or Scalar.Boolean } l, ScalarType r) when l == r => l, // If one side is float and other is non-floating, promote to floating - (ScalarType { TypeName: "int" or "uint" } l, ScalarType { TypeName: "float" or "double" } r) => r, - (ScalarType { TypeName: "float" or "double" } l, ScalarType { TypeName: "int" or "uint" } r) => l, + (ScalarType { Type: Scalar.Int or Scalar.UInt } l, ScalarType { Type: Scalar.Float or Scalar.Double } r) => r, + (ScalarType { Type: Scalar.Float or Scalar.Double } l, ScalarType { Type: Scalar.Int or Scalar.UInt } r) => l, // If one side is unsigned, promote to unsigned (bitcast) - (ScalarType { TypeName: "int" } l, ScalarType { TypeName: "uint" } r) => r, - (ScalarType { TypeName: "uint" } l, ScalarType { TypeName: "int" } r) => l, + (ScalarType { Type: Scalar.Int } l, ScalarType { Type: Scalar.UInt } r) => r, + (ScalarType { Type: Scalar.UInt } l, ScalarType { Type: Scalar.Int } r) => l, _ => throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftElementType} and {rightElementType}"), }; } @@ -153,7 +153,7 @@ public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operato // Comparisons and logical operators if (op == Operator.Greater || op == Operator.Lower || op == Operator.GreaterOrEqual || op == Operator.LowerOrEqual || op == Operator.NotEquals || op == Operator.Equals || op == Operator.LogicalAND || op == Operator.LogicalOR) - resultType = resultType.WithElementType(ScalarType.From("bool")); + resultType = resultType.WithElementType(ScalarType.Boolean); var resultTypeId = context.GetOrRegister(resultType); @@ -234,55 +234,55 @@ when l.IsInteger() && r.IsInteger() when l.IsInteger() && r.IsInteger() => Buffer.InsertData(Position++, new OpBitwiseXor(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.LogicalAND, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + (Operator.LogicalAND, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) => Buffer.InsertData(Position++, new OpLogicalAnd(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.LogicalOR, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + (Operator.LogicalOR, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Equals, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + (Operator.Equals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) => Buffer.InsertData(Position++, new OpLogicalEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Equals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) + (Operator.Equals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Equals, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.NotEquals, ScalarType { TypeName: "bool" }, ScalarType { TypeName: "bool" }) + (Operator.NotEquals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) => Buffer.InsertData(Position++, new OpLogicalNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.NotEquals, ScalarType { TypeName: "int" or "uint" }, ScalarType { TypeName: "int" or "uint" }) + (Operator.NotEquals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.NotEquals, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Lower, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + (Operator.Lower, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Lower, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + (Operator.Lower, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) => Buffer.InsertData(Position++, new OpULessThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Lower, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.LowerOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + (Operator.LowerOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.LowerOrEqual, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + (Operator.LowerOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Greater, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + (Operator.Greater, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.Greater, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + (Operator.Greater, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) => Buffer.InsertData(Position++, new OpUGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.Greater, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() => Buffer.InsertData(Position++, new OpFOrdGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.GreaterOrEqual, ScalarType { TypeName: "int" }, ScalarType { TypeName: "int" }) + (Operator.GreaterOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), - (Operator.GreaterOrEqual, ScalarType { TypeName: "uint" }, ScalarType { TypeName: "uint" }) + (Operator.GreaterOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) => Buffer.InsertData(Position++, new OpUGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() @@ -413,21 +413,21 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy var typeCasting = (valueType.GetElementType(), castType.GetElementType()) switch { // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion - (ScalarType { TypeName: "float" }, ScalarType { TypeName: "int" }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "float" }, ScalarType { TypeName: "uint" }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "float" }, ScalarType { TypeName: "bool" }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), - (ScalarType { TypeName: "int" }, ScalarType { TypeName: "bool" }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), - (ScalarType { TypeName: "int" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "uint" }, ScalarType { TypeName: "float" }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "int" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), - (ScalarType { TypeName: "bool" }, ScalarType { TypeName: "float" }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), // Bitcast (int=>uint or uint=>int) - (ScalarType { TypeName: "int" }, ScalarType { TypeName: "uint" }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { TypeName: "uint" }, ScalarType { TypeName: "int" }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), }; values[i] = typeCasting.IdResult!.Value; @@ -501,9 +501,9 @@ public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) VectorType v => v.BaseType == elementType ? v : v with { BaseType = elementType }, MatrixType m => m.BaseType == elementType ? m : m with { BaseType = elementType }, }; - public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "sbyte" or "short" or "int" or "long" }; - public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { TypeName: "byte" or "ushort" or "uint" or "ulong" }; - public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { TypeName: "half" or "float" or "double" }; + public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Int or Scalar.Int64 }; + public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.UInt or Scalar.UInt64 }; + public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Float or Scalar.Double }; public static bool IsInteger(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsUnsignedInteger(); public static bool IsNumber(this SymbolType symbol) => symbol.IsInteger() || symbol.IsFloating(); public static bool IsSigned(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsFloating(); @@ -538,10 +538,8 @@ public static bool SameComponentCount(SymbolType left, SymbolType right) public static bool SameBaseTypeWidth(SymbolType left, SymbolType right) => (right, left) switch { - (ScalarType { TypeName: "byte" or "sbyte" }, ScalarType { TypeName: "byte" or "sbyte" }) => true, - (ScalarType { TypeName: "ushort" or "short" or "half" }, ScalarType { TypeName: "ushort" or "short" or "half" }) => true, - (ScalarType { TypeName: "uint" or "int" or "float" }, ScalarType { TypeName: "uint" or "int" or "float" }) => true, - (ScalarType { TypeName: "ulong" or "long" or "double" }, ScalarType { TypeName: "ulong" or "long" or "double" }) => true, + (ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.Float }, ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.Float }) => true, + (ScalarType { Type: Scalar.UInt64 or Scalar.Int64 or Scalar.Double }, ScalarType { Type: Scalar.UInt64 or Scalar.Int64 or Scalar.Double }) => true, (VectorType l, ScalarType r) => SameBaseType(l.BaseType, r), (ScalarType l, VectorType r) => SameBaseType(l, r.BaseType), (VectorType l, VectorType r) => SameBaseType(l.BaseType, r.BaseType), diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index fed7ff80f7..e2fd38e7a1 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -32,7 +32,7 @@ public void EndFunction() var lastInstruction = Buffer[Position - 1]; if (!IsBlockTermination(lastInstruction.Op)) { - if (CurrentFunction.Value.FunctionType.ReturnType != ScalarType.From("void")) + if (CurrentFunction.Value.FunctionType.ReturnType != ScalarType.Void) throw new InvalidOperationException("No function termination, but a return value is expected"); Return(null); diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index 2cc43f490d..fe75532580 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -17,17 +17,13 @@ public int AddConstant(TScalar value) { var data = value switch { - byte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("byte")), Bound++, v)), - sbyte v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("sbyte")), Bound++, v)), - ushort v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ushort")), Bound++, v)), - short v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("short")), Bound++, v)), - uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("uint")), Bound++, v)), - int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("int")), Bound++, v)), - ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("ulong")), Bound++, v)), - long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("long")), Bound++, v)), - Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), - float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("float")), Bound++, v)), - double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("bdouble")), Bound++, v)), + uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.UInt), Bound++, v)), + int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Int), Bound++, v)), + ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.UInt64), Bound++, v)), + long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Int64), Bound++, v)), + //Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), + float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Float), Bound++, v)), + double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Double), Bound++, v)), _ => throw new NotImplementedException() }; if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) @@ -291,24 +287,24 @@ public SpirvValue CompileConstantLiteral(Literal literal) { literal.Type = literal switch { - BoolLiteral lit => ScalarType.From("bool"), + BoolLiteral lit => ScalarType.Boolean, IntegerLiteral lit => lit.Suffix switch { - { Signed: true, Size: 8 } => ScalarType.From("sbyte"), - { Signed: true, Size: 16 } => ScalarType.From("short"), - { Signed: true, Size: 32 } => ScalarType.From("int"), - { Signed: true, Size: 64 } => ScalarType.From("long"), - { Signed: false, Size: 8 } => ScalarType.From("byte"), - { Signed: false, Size: 16 } => ScalarType.From("ushort"), - { Signed: false, Size: 32 } => ScalarType.From("uint"), - { Signed: false, Size: 64 } => ScalarType.From("ulong"), + //{ Signed: true, Size: 8 } => ScalarType.SByte, + //{ Signed: true, Size: 16 } => ScalarType.Short, + { Signed: true, Size: 32 } => ScalarType.Int, + { Signed: true, Size: 64 } => ScalarType.Int64, + //{ Signed: false, Size: 8 } => ScalarType.UByte, + //{ Signed: false, Size: 16 } => ScalarType.UShort, + { Signed: false, Size: 32 } => ScalarType.UInt, + { Signed: false, Size: 64 } => ScalarType.UInt64, _ => throw new NotImplementedException("Unsupported integer suffix") }, FloatLiteral lit => lit.Suffix.Size switch { - 16 => ScalarType.From("half"), - 32 => ScalarType.From("float"), - 64 => ScalarType.From("double"), + //16 => ScalarType.Half, + 32 => ScalarType.Float, + 64 => ScalarType.Double, _ => throw new NotImplementedException("Unsupported float") }, }; diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index ceaca9a5c6..e11a387cf1 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -17,21 +17,16 @@ public int GetOrRegister(SymbolType? type) var instruction = type switch { ScalarType s => - s.TypeName switch + s.Type switch { - "void" => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, - "bool" => Buffer.Add(new OpTypeBool(Bound++)).IdResult, - "sbyte" => Buffer.Add(new OpTypeInt(Bound++, 8, 1)).IdResult, - "byte" => Buffer.Add(new OpTypeInt(Bound++, 8, 0)).IdResult, - "ushort" => Buffer.Add(new OpTypeInt(Bound++, 16, 1)).IdResult, - "short" => Buffer.Add(new OpTypeInt(Bound++, 16, 0)).IdResult, - "int" => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, - "uint" => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, - "long" => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, - "ulong" => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, - "half" => Buffer.Add(new OpTypeFloat(Bound++, 16, null)).IdResult, - "float" => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, - "double" => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, + Scalar.Void => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, + Scalar.Boolean => Buffer.Add(new OpTypeBool(Bound++)).IdResult, + Scalar.Int => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, + Scalar.UInt => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, + Scalar.Int64 => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, + Scalar.UInt64 => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, + Scalar.Float => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, + Scalar.Double => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, _ => throw new NotImplementedException($"Can't add type {type}") }, VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 88475caebb..05542b8830 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -793,7 +793,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo } } - var voidType = context.GetOrRegister(ScalarType.From("void")); + var voidType = context.GetOrRegister(ScalarType.Void); // Add new entry point wrapper context.FluentAdd(new OpTypeFunctionSDSL(context.Bound++, voidType, []), out var newEntryPointFunctionType); From 71639134dcc9a48b0fef768583f5423dd75a4a55 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 01:24:26 +0900 Subject: [PATCH 0733/1182] SymbolType.TryGetNumeric: void is already handled by ScalarType.Types --- src/Stride.Shaders/Core/SymbolTypes.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 9715fb392b..09a0193097 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -43,11 +43,6 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT result = m; return true; } - else if (name == "void") - { - result = ScalarType.Void; - return true; - } else { result = null; From 4e2075c565d37c98b85d8774f671236bb5d2e520 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 16:38:02 +0900 Subject: [PATCH 0734/1182] Fixed operand processing code --- .../SDSL/ShaderMixer.cs | 10 +-- .../Spirv/Building/Builder.Class.cs | 79 +++++++++++++------ 2 files changed, 59 insertions(+), 30 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 243486e188..1f9eaf4eca 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -827,7 +827,8 @@ public static void OffsetIds(OpData inst, int offset) || o.Kind == OperandKind.IdResult || o.Kind == OperandKind.IdResultType || o.Kind == OperandKind.IdScope - || o.Kind == OperandKind.IdMemorySemantics) + || o.Kind == OperandKind.IdMemorySemantics + || o.Kind == OperandKind.PairIdRefIdRef) { for (int i = 0; i < o.Words.Length; ++i) { @@ -836,18 +837,17 @@ public static void OffsetIds(OpData inst, int offset) } } else if (o.Kind == OperandKind.PairIdRefLiteralInteger - || o.Kind == OperandKind.PairLiteralIntegerIdRef - || o.Kind == OperandKind.PairIdRefIdRef) + || o.Kind == OperandKind.PairLiteralIntegerIdRef) { for (int i = 0; i < o.Words.Length; i += 2) { - if (o.Kind == OperandKind.PairIdRefLiteralInteger || o.Kind == OperandKind.PairIdRefIdRef) + if (o.Kind == OperandKind.PairIdRefLiteralInteger) { if (o.Words[i + 0] != 0) o.Words[i + 0] += offset; } - if (o.Kind == OperandKind.PairLiteralIntegerIdRef || o.Kind == OperandKind.PairIdRefIdRef) + if (o.Kind == OperandKind.PairLiteralIntegerIdRef) { if (o.Words[i + 1] != 0) o.Words[i + 1] += offset; diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 990dbf96b2..025996e54d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -549,24 +549,28 @@ public static bool ContainIds(HashSet ids, OpData i) { foreach (var op in i) { - if ((op.Kind == OperandKind.IdRef + if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResult || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.IdScope || op.Kind == OperandKind.IdMemorySemantics - || op.Kind == OperandKind.PairIdRefLiteralInteger || op.Kind == OperandKind.PairIdRefIdRef) - && op.Words.Length > 0 - && ids.Contains(op.Words[0])) { - return true; + foreach (var word in op.Words) + if (ids.Contains(word)) + return true; } - - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && ids.Contains(op.Words[1])) + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) { - return true; + for (int j = 0; j < op.Words.Length; j += 2) + if (ids.Contains(op.Words[j])) + return true; + } + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + { + for (int j = 1; j < op.Words.Length; j += 2) + if (ids.Contains(op.Words[j])) + return true; } } @@ -602,10 +606,7 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.IdScope || op.Kind == OperandKind.IdMemorySemantics - || op.Kind == OperandKind.PairIdRefLiteralInteger - || op.Kind == OperandKind.PairIdRefIdRef - || op.Kind == OperandKind.IdScope - || op.Kind == OperandKind.IdMemorySemantics) + || op.Kind == OperandKind.PairIdRefIdRef) { foreach (ref var word in op.Words) { @@ -633,21 +634,49 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) } } - if ((op.Kind == OperandKind.PairIdRefLiteralInteger) - && idRemapping.TryGetValue(op.Words[0], out var to2)) + if (op.Kind == OperandKind.PairIdRefLiteralInteger) { - if (op.Quantifier != OperandQuantifier.One) - throw new NotImplementedException(); - op.Words[0] = to2; + for (int j = 0; j < op.Words.Length; j += 2) + { + if (idRemapping.TryGetValue(op.Words[j], out var to2)) + op.Words[j] = to2; + } } - if ((op.Kind == OperandKind.PairLiteralIntegerIdRef - || op.Kind == OperandKind.PairIdRefIdRef) - && idRemapping.TryGetValue(op.Words[1], out var to3)) + if (op.Kind == OperandKind.PairLiteralIntegerIdRef) { - if (op.Quantifier != OperandQuantifier.One) - throw new NotImplementedException(); - op.Words[1] = to3; + for (int j = 1; j < op.Words.Length; j += 2) + { + if (idRemapping.TryGetValue(op.Words[j], out var to2)) + op.Words[j] = to2; + } + } + } + } + + public static void CollectIds(OpData i, HashSet ids) + { + foreach (var op in i) + { + if (op.Kind == OperandKind.IdRef + || op.Kind == OperandKind.IdResult + || op.Kind == OperandKind.IdResultType + || op.Kind == OperandKind.IdScope + || op.Kind == OperandKind.IdMemorySemantics + || op.Kind == OperandKind.PairIdRefIdRef) + { + foreach (var word in op.Words) + ids.Add(word); + } + else if (op.Kind == OperandKind.PairIdRefLiteralInteger) + { + for (int j = 0; j < op.Words.Length; j += 2) + ids.Add(op.Words[j]); + } + else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) + { + for (int j = 1; j < op.Words.Length; j += 2) + ids.Add(op.Words[j]); } } } From 00a23d9053ff4d284a760b0896d9826fd94abeae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 16:47:59 +0900 Subject: [PATCH 0735/1182] Remove OpName for Streams pointer types and global CBuffer variables --- .../SDSL/ShaderMixer.CBuffers.cs | 7 +++- .../Spirv/Processing/InterfaceProcessor.cs | 34 ++++++++++++------- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index ef01e7bd92..25aa0837a6 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -119,7 +119,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob } } - // Remap decorations + // Remap decorations and remove OpName foreach (var i in context) { if (i.Op == Op.OpDecorate && (OpDecorate)i is {} decorate) @@ -132,6 +132,11 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob if (variableToMemberIndices.TryGetValue(decorateString.Target, out var memberIndex)) i.Buffer.Replace(i.Index, new OpMemberDecorateString(globalCBufferTypeId, memberIndex, decorateString.Decoration, decorateString.Value)); } + else if (i.Op == Op.OpName && (OpName)i is { } name) + { + if (variableToMemberIndices.ContainsKey(name.Target)) + SetOpNop(i.Data.Memory.Span); + } } } diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 05542b8830..e778a9a870 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -395,14 +395,29 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c } } + // Remove all OpTypeStreamsSDSL or any type that depends on it + // (we do that before the OpName/OpDecorate pass) foreach (var i in context) { - if (i.Op == Op.OpName && ((OpName)i) is { } name) + if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer) { - if (removedIds.Contains(name.Target)) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); + if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) + { + var streamsTypeSearch = new StreamsTypeSearch(); + streamsTypeSearch.VisitType(type); + if (streamsTypeSearch.Found) + { + removedIds.Add(i.Data.IdResult.Value); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } } - else if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) + } + + // Remove OpName/OpDecorate + foreach (var i in context) + { + if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) { if (removedIds.Contains(decorate.Target)) SpirvBuilder.SetOpNop(i.Data.Memory.Span); @@ -412,15 +427,10 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (removedIds.Contains(decorateString.Target)) SpirvBuilder.SetOpNop(i.Data.Memory.Span); } - else if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer) + else if (i.Op == Op.OpName && ((OpName)i) is { } name) { - if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) - { - var streamsTypeSearch = new StreamsTypeSearch(); - streamsTypeSearch.VisitType(type); - if (streamsTypeSearch.Found) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } + if (removedIds.Contains(name.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); } } } From 86c81814ae692825af9c1c548eb0dc770b8900d2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 16:51:17 +0900 Subject: [PATCH 0736/1182] MergeSDSL now returns list of entry points --- .../SDSL/ShaderMixer.cs | 5 ++-- src/Stride.Shaders.Experiments/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 4 +-- .../Spirv/Processing/InterfaceProcessor.cs | 27 ++++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 1f9eaf4eca..10be2d818d 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -26,6 +26,7 @@ using System.Text; using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; +using EntryPoint = Stride.Shaders.Core.EntryPoint; namespace Stride.Shaders.Compilers.SDSL; @@ -33,7 +34,7 @@ public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources) + public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) { var temp = new NewSpirvBuffer(); @@ -63,7 +64,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef { CodeInserted = (int index, int count) => AdjustIndicesAfterAppendInstructions(rootMixin, index, count) }; - interfaceProcessor.Process(table, temp, context); + entryPoints = interfaceProcessor.Process(table, temp, context); // Process Link (add CompositionPath, generate missing ones, etc.) ProcessLinks(context, temp); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 798704862e..618f96c245 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -15,7 +15,7 @@ var loader = new Examples.ShaderLoader(); loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _, out _); +shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _, out _, out _); using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); var source = Spv.Dis(buffer); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 3679205170..5cd634c913 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -79,7 +79,7 @@ public void ComputeTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -116,7 +116,7 @@ public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/RenderTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index e778a9a870..d8cf45f44c 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -161,8 +161,10 @@ public bool MarkMethodUsed(int functionId) } } - public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) + public List<(string Name, int Id, ShaderStage Stage)> Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { + var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); + table.TryResolveSymbol("VSMain", out var entryPointVS); table.TryResolveSymbol("PSMain", out var entryPointPS); table.TryResolveSymbol("CSMain", out var entryPointCS); @@ -190,7 +192,8 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte if (entryPointCS.IdRef != 0) { - var csWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.GLCompute, entryPointCS.IdRef, entryPointCS.Id.Name, analysisResult, liveAnalysis, false); + (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.GLCompute, entryPointCS.IdRef, entryPointCS.Id.Name, analysisResult, liveAnalysis, false); + entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); // Move OpExecutionMode on new CSMain wrapper (and remove others) foreach (var i in context) @@ -218,7 +221,9 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - var psWrapperId = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); + (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); + entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); + buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); } @@ -255,13 +260,16 @@ public void Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext conte stream.Value.Output = true; } - GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); + (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); + entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); } } // This will remove a lot of unused methods, resources and variables // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); + + return entryPoints; } private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) @@ -644,7 +652,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); } - private int GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) + private (int Id, string Name) GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; @@ -806,10 +814,11 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo var voidType = context.GetOrRegister(ScalarType.Void); // Add new entry point wrapper - context.FluentAdd(new OpTypeFunctionSDSL(context.Bound++, voidType, []), out var newEntryPointFunctionType); + var newEntryPointFunctionType = context.GetOrRegister(new FunctionType(ScalarType.Void, [])); buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); buffer.Add(new OpLabel(context.Bound++)); - context.AddName(newEntryPointFunction, $"{entryPointName}_Wrapper"); + entryPointName = $"{entryPointName}_Wrapper"; + context.AddName(newEntryPointFunction, entryPointName); { // Variable initializers @@ -876,10 +885,10 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo } liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, $"{entryPointName}_Wrapper", [.. pvariables.Slice(0, pvariableIndex)])); + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. pvariables.Slice(0, pvariableIndex)])); } - return newEntryPointFunction.ResultId; + return (newEntryPointFunction.ResultId, entryPointName); } void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) From 6f27ea87f2d21bf7f907ae327372fcb5fb0d4307 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 16:51:31 +0900 Subject: [PATCH 0737/1182] Clean ShaderConstantSDSL decorations --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 10be2d818d..18152c9340 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -911,6 +911,7 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont temp.RemoveAt(index--); else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL + or Decoration.ShaderConstantSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) From 5eada2283526e07adc25680041ad635d41cd539a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 19:02:09 +0900 Subject: [PATCH 0738/1182] InterfaceProcessor: Fix STREAMS member types --- .../Spirv/Processing/InterfaceProcessor.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index d8cf45f44c..337d9c1ce3 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -26,11 +26,11 @@ enum StreamVariableType Output, } - class StreamInfo(string? semantic, string name, SymbolType type, int variableId) + class StreamInfo(string? semantic, string name, PointerType type, int variableId) { public string? Semantic { get; } = semantic; public string Name { get; } = name; - public SymbolType Type { get; } = type; + public PointerType Type { get; } = type; public int VariableId { get; } = variableId; public int? InputLayoutLocation { get; set; } @@ -51,10 +51,10 @@ class StreamInfo(string? semantic, string name, SymbolType type, int variableId) public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; } - class VariableInfo(string name, SymbolType type, int variableId) + class VariableInfo(string name, PointerType type, int variableId) { public string Name { get; } = name; - public SymbolType Type { get; } = type; + public PointerType Type { get; } = type; public int VariableId { get; } = variableId; public int? VariableMethodInitializerId { get; set; } @@ -566,7 +566,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) var name = nameTable.TryGetValue(variable.ResultId, out var nameId) ? nameId : $"unnamed_{variable.ResultId}"; - var type = context.ReverseTypes[variable.ResultType]; + var type = (PointerType)context.ReverseTypes[variable.ResultType]; if (variable.Flags.HasFlag(VariableFlagsMask.Stream)) { @@ -733,7 +733,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo foreach (var stream in streams) { - var baseType = ((PointerType)stream.Value.Type).BaseType; + var baseType = stream.Value.Type.BaseType; if (stream.Value.UsedThisStage) privateStreams.Add(stream.Value); @@ -792,7 +792,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo foreach (var stream in privateStreams) { stream.StreamStructFieldIndex = fields.Count; - fields.Add(new(stream.Name, stream.Type, default)); + fields.Add(new(stream.Name, stream.Type.BaseType, default)); } var streamsType = new StructType($"{stage}_STREAMS", fields); context.DeclareStructuredType(streamsType); @@ -830,7 +830,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo { liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); - var variableValueType = ((PointerType)variable.Value.Type).BaseType; + var variableValueType = variable.Value.Type.BaseType; buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null, [])); } @@ -839,7 +839,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo // Copy variables from input to streams struct foreach (var stream in inputStreams) { - var baseType = ((PointerType)stream.Info.Type).BaseType; + var baseType = stream.Info.Type.BaseType; buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null, []), out var loadedValue); buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null, [])); @@ -850,7 +850,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo // Copy variables from streams struct to output foreach (var stream in outputStreams) { - var baseType = ((PointerType)stream.Info.Type).BaseType; + var baseType = stream.Info.Type.BaseType; buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, []), out var loadedValue); buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); From 4be5d84cd83977dba7572ffbf87c85d08c32d8ec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 21 Jan 2026 19:13:50 +0900 Subject: [PATCH 0739/1182] Improved OpName removal (and do a catch-all at the end just in case) --- .../SDSL/ShaderMixer.cs | 69 ++++++++++++++++--- .../Buffers/NewSpirvBuffer.cs | 10 +-- src/Stride.Shaders/Spirv/Building/Context.cs | 15 ++++ 3 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 18152c9340..2b13667683 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -534,10 +534,14 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // If abstract, let's erase the whole function if ((functionInfo.Flags & FunctionFlagsMask.Abstract) != 0) { + var removedIds = new HashSet(); while (temp[index].Op != Op.OpFunctionEnd) { + if (temp[index].Data.IdResult is {} idResult) + removedIds.Add(idResult); SetOpNop(temp[index++].Data.Memory.Span); } + context.RemoveNames(removedIds); SetOpNop(temp[index].Data.Memory.Span); } @@ -611,7 +615,17 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext foreachBufferCopy.Add(i2); } } + + // Clean OpName used by removed instructions (only for IdResult) + var removedIds = new HashSet(); + foreach (var i in foreachBuffer) + if (i.IdResult is { } idResult) + removedIds.Add(idResult); + context.RemoveNames(removedIds); + + // Insert new code buffer.InsertRange(index, foreachBufferCopy.AsSpan()); + // Note: mixinNode is not added to rootMixin hierarchy yet // Moreover, we are the last mixin (or one of our child is) // So we need (and it's safe) to call this on mixinNode rather than root node @@ -875,14 +889,24 @@ private void SimplifyNotSupportedConstantsInShader(SpirvContext context, NewSpir private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) { - for (int index = 0; index < temp.Count; index++) + var ids = new HashSet(); + foreach (var i in temp) { - var i = temp[index]; + // Collect IDs (except for OpName) + if (i.Op != Op.OpName) + SpirvBuilder.CollectIds(i.Data, ids); + } + + // Remove in a single pass (we do in-place without RemoveAt otherwise it would be up to O(n^2) complexity) + int insertIndex = 0; + for (int sourceIndex = 0; sourceIndex < temp.Count; sourceIndex++) + { + var i = temp[sourceIndex]; // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) // Note: we ignore initializer as we store a method which is already processed during InterfaceProcessor (as opposed to a const for OpVariable) if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) - temp.Replace(index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); + temp.Replace(sourceIndex, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) @@ -890,12 +914,13 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; - temp.Replace(index, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); + temp.Replace(sourceIndex, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); } + var keep = true; // Remove Nop if (i.Op == Op.OpNop) - temp.RemoveAt(index--); + keep = false; // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) else if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLShaderEnd @@ -908,38 +933,60 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable || i.Op == Op.OpSDSLFunctionInfo) - temp.RemoveAt(index--); + keep = false; else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL or Decoration.ShaderConstantSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) - temp.RemoveAt(index--); + keep = false; else if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) - temp.RemoveAt(index--); + keep = false; // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) else if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) { var pointedType = context.ReverseTypes[typePointer.Type]; if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) - temp.RemoveAt(index--); + keep = false; } // Also remove arrays of shaders (used in composition arrays) else if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { var innerType = context.ReverseTypes[typeArray.ElementType]; if (innerType is ShaderSymbol) - temp.RemoveAt(index--); + keep = false; } else if (i.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) { var innerType = context.ReverseTypes[typeRuntimeArray.ElementType]; if (innerType is ShaderSymbol) - temp.RemoveAt(index--); + keep = false; + } + + // Remove unnecessary OpName + // Note: we should issue a warning and make sure those are deleted as we process stuff? + if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) + { + if (!ids.Contains(nameInstruction.Target)) + keep = false; + } + + if (keep) + { + if (insertIndex++ != sourceIndex) + // Note: we're not using Dispose() since we simply move it + temp.Replace(insertIndex - 1, temp[sourceIndex].Data, false); + } + else + { + temp[sourceIndex].Data.Dispose(); } } + + // Remove leftover instructions (they have been either disposed or moved so no need to dispose them + temp.RemoveRange(insertIndex, temp.Count - insertIndex, false); } } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 1de4520c8a..463f37850c 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -373,22 +373,24 @@ public void InsertRange(int index, ReadOnlySpan source) Instructions.InsertRange(index, source); } - public OpData Replace(int index, OpData i) + public OpData Replace(int index, OpData i, bool dispose = true) { if (index < 0 || index >= Instructions.Count) throw new InvalidOperationException(); - Instructions[index].Dispose(); + if (dispose) + Instructions[index].Dispose(); Instructions[index] = i; return Instructions[index]; } - public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct + public OpData Replace(int index, in T instruction, bool dispose = true) where T : struct, IMemoryInstruction, allows ref struct { if (index < 0 || index >= Instructions.Count) throw new InvalidOperationException(); - Instructions[index].Dispose(); + if (dispose) + Instructions[index].Dispose(); Instructions[index] = new(instruction.InstructionMemory); return Instructions[index]; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 28e6e97d4d..c3f392d822 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -207,6 +207,21 @@ public SpirvContext FluentAdd(in T value, out T result) return this; } + public void RemoveNames(HashSet ids) + { + foreach (var i in Buffer) + { + if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) + { + if (ids.Contains(nameInstruction.Target)) + { + Names.Remove(nameInstruction.Target); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + } + public void Sort() => Buffer.Sort(); [Obsolete("Use the insert method instead")] From 01bb0647c16cb8e8777d498669e827ac6b97f26b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 10:31:31 +0900 Subject: [PATCH 0740/1182] Improved OpName/OpDecorate removal during semantic merging --- .../SDSL/ShaderMixer.cs | 4 ++-- src/Stride.Shaders/Spirv/Building/Context.cs | 14 +++++++++-- .../Spirv/Processing/InterfaceProcessor.cs | 24 +++++-------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 2b13667683..ff9a52ff83 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -541,7 +541,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, removedIds.Add(idResult); SetOpNop(temp[index++].Data.Memory.Span); } - context.RemoveNames(removedIds); + context.RemoveNameAndDecorations(removedIds); SetOpNop(temp[index].Data.Memory.Span); } @@ -621,7 +621,7 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext foreach (var i in foreachBuffer) if (i.IdResult is { } idResult) removedIds.Add(idResult); - context.RemoveNames(removedIds); + context.RemoveNameAndDecorations(removedIds); // Insert new code buffer.InsertRange(index, foreachBufferCopy.AsSpan()); diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index c3f392d822..9575743298 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -207,11 +207,21 @@ public SpirvContext FluentAdd(in T value, out T result) return this; } - public void RemoveNames(HashSet ids) + public void RemoveNameAndDecorations(HashSet ids) { foreach (var i in Buffer) { - if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) + if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) + { + if (ids.Contains(decorate.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpDecorateString && ((OpDecorateString)i) is { } decorateString) + { + if (ids.Contains(decorateString.Target)) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) { if (ids.Contains(nameInstruction.Target)) { diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 337d9c1ce3..bc2f572e5d 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -423,24 +423,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c } // Remove OpName/OpDecorate - foreach (var i in context) - { - if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) - { - if (removedIds.Contains(decorate.Target)) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - else if (i.Op == Op.OpDecorateString && ((OpDecorateString)i) is { } decorateString) - { - if (removedIds.Contains(decorateString.Target)) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - else if (i.Op == Op.OpName && ((OpName)i) is { } name) - { - if (removedIds.Contains(name.Target)) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } + context.RemoveNameAndDecorations(removedIds); } private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) @@ -461,13 +444,18 @@ private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, } // Remove duplicate streams + HashSet removedIds = new(); foreach (var i in buffer) { if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { } variable && remapIds.ContainsKey(variable.ResultId)) { SpirvBuilder.SetOpNop(i.Data.Memory.Span); + removedIds.Add(variable.ResultId); } } + + // Remove OpName/OpDecorate + context.RemoveNameAndDecorations(removedIds); foreach (var remapId in remapIds) analysisResult.Streams.Remove(remapId.Key); From c6d846030744ec5018db37de937738bda237eb01 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 11:00:31 +0900 Subject: [PATCH 0741/1182] Added more type conversion in intrinsics --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 57 ++++++++++++++++--- .../PrimaryExpressionParsers.cs | 2 +- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 4cdfa1c7cd..728bd95955 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -104,6 +104,15 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); + + x = builder.Convert(context, x, resultType); + y = builder.Convert(context, y, resultType); + if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); @@ -577,10 +586,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var yType = Parameters.Values[1].ValueType; var resultType = ScalarType.Float; - var inputTypes = IntrinsicHelper.FindCommonType(resultType, xType, yType); + var inputType = IntrinsicHelper.FindCommonType(resultType, xType, yType); - x = builder.Convert(context, x, resultType); - y = builder.Convert(context, y, resultType); + x = builder.Convert(context, x, inputType); + y = builder.Convert(context, y, inputType); if (context.GLSLSet == null) context.ImportGLSL(); @@ -640,10 +649,21 @@ public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; - var (N, I, Nre) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); + var (n, i, ng) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); + + var nType = Parameters.Values[0].ValueType; + var iType = Parameters.Values[1].ValueType; + var ngType = Parameters.Values[2].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, nType, iType, ngType); + + n = builder.Convert(context, n, resultType); + i = builder.Convert(context, i, resultType); + ng = builder.Convert(context, ng, resultType); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GLSLSet ?? -1, N.Id, I.Id, Nre.Id)); + var instruction = builder.Insert(new GLSLFaceForward(n.TypeId, context.Bound++, context.GLSLSet ?? -1, n.Id, i.Id, ng.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -652,10 +672,19 @@ public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; - var (I, N) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + var (i, n) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + + var iType = Parameters.Values[0].ValueType; + var nType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); + + i = builder.Convert(context, i, resultType); + n = builder.Convert(context, n, resultType); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLReflect(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id)); + var instruction = builder.Insert(new GLSLReflect(i.TypeId, context.Bound++, context.GLSLSet ?? -1, i.Id, n.Id)); return new(instruction.ResultId, instruction.ResultType); } } @@ -664,10 +693,20 @@ public class RefractCall(ShaderExpressionList parameters, TextLocation info) : M public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; - var (I, N, eta) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); + var (i, n, eta) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); + + var iType = Parameters.Values[0].ValueType; + var nType = Parameters.Values[1].ValueType; + + var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); + + i = builder.Convert(context, i, resultType); + n = builder.Convert(context, n, resultType); + eta = builder.Convert(context, eta, ScalarType.Float); + if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRefract(I.TypeId, context.Bound++, context.GLSLSet ?? -1, I.Id, N.Id, eta.Id)); + var instruction = builder.Insert(new GLSLRefract(i.TypeId, context.Bound++, context.GLSLSet ?? -1, i.Id, n.Id, eta.Id)); return new(instruction.ResultId, instruction.ResultType); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index b43c2ad554..1221bb8da2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -130,6 +130,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), + ("faceforward", _) => new FaceForwardCall(parameters, scanner[position..scanner.Position]), // Compute Barriers ("AllMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, allMemoryBarrierMemorySemanticsMask), @@ -161,7 +162,6 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("EvaluateAttributeSnapped", _) => throw new NotImplementedException(), ("f16to32", _) => throw new NotImplementedException(), ("f32to16", _) => throw new NotImplementedException(), - ("faceforward", _) => throw new NotImplementedException(), ("firstbithigh", _) => throw new NotImplementedException(), ("firstbitlow", _) => throw new NotImplementedException(), ("fma", _) => throw new NotImplementedException(), From ee26f46df5064ef9d50d5215970885f0660537f7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 12:01:06 +0900 Subject: [PATCH 0742/1182] Cleanup OpName/OpDecorate more aggressively --- .../SDSL/ShaderMixer.cs | 120 +++++++++++------- 1 file changed, 71 insertions(+), 49 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index ff9a52ff83..22858d2fbc 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -887,42 +887,40 @@ private void SimplifyNotSupportedConstantsInShader(SpirvContext context, NewSpir } } - private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + private static void RemoveInstructionWhere(NewSpirvBuffer buffer, Func match) { - var ids = new HashSet(); - foreach (var i in temp) - { - // Collect IDs (except for OpName) - if (i.Op != Op.OpName) - SpirvBuilder.CollectIds(i.Data, ids); - } - - // Remove in a single pass (we do in-place without RemoveAt otherwise it would be up to O(n^2) complexity) int insertIndex = 0; - for (int sourceIndex = 0; sourceIndex < temp.Count; sourceIndex++) + for (int sourceIndex = 0; sourceIndex < buffer.Count; sourceIndex++) { - var i = temp[sourceIndex]; + var i = buffer[sourceIndex]; + var remove = match(i); - // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) - // Note: we ignore initializer as we store a method which is already processed during InterfaceProcessor (as opposed to a const for OpVariable) - if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) - temp.Replace(sourceIndex, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); - - // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) - if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) + if (!remove) { - Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; - for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) - parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; - temp.Replace(sourceIndex, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); + if (insertIndex++ != sourceIndex) + // Note: we're not using Dispose() since we simply move it + buffer.Replace(insertIndex - 1, buffer[sourceIndex].Data, false); } + else + { + buffer[sourceIndex].Data.Dispose(); + } + } + + // Remove leftover instructions (they have been either disposed or moved so no need to dispose them) + buffer.RemoveRange(insertIndex, buffer.Count - insertIndex, false); + } - var keep = true; + private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + { + // Remove in a single pass (we do in-place without RemoveAt otherwise it would be up to O(n^2) complexity) + RemoveInstructionWhere(temp, i => + { // Remove Nop if (i.Op == Op.OpNop) - keep = false; + return true; // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) - else if (i.Op == Op.OpSDSLShader + if (i.Op == Op.OpSDSLShader || i.Op == Op.OpSDSLShaderEnd || i.Op == Op.OpSDSLComposition || i.Op == Op.OpSDSLCompositionEnd @@ -933,60 +931,84 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable || i.Op == Op.OpSDSLFunctionInfo) - keep = false; - else if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is + return true; + if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL or Decoration.ShaderConstantSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) - keep = false; - else if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) - keep = false; + return true; + if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + return true; // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) - else if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) + if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) { var pointedType = context.ReverseTypes[typePointer.Type]; if (pointedType is ShaderSymbol || pointedType is ArrayType { BaseType: ShaderSymbol }) - keep = false; + return true; } // Also remove arrays of shaders (used in composition arrays) else if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { var innerType = context.ReverseTypes[typeArray.ElementType]; if (innerType is ShaderSymbol) - keep = false; + return true; } else if (i.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)i is { } typeRuntimeArray) { var innerType = context.ReverseTypes[typeRuntimeArray.ElementType]; if (innerType is ShaderSymbol) - keep = false; + return true; } + return false; + }); + + var ids = new HashSet(); + foreach (var i in temp) + { + // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) + // Note: we ignore initializer as we store a method which is already processed during InterfaceProcessor (as opposed to a const for OpVariable) + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) + temp.Replace(i.Index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); - // Remove unnecessary OpName - // Note: we should issue a warning and make sure those are deleted as we process stuff? + // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) + if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) + { + Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; + for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) + parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; + temp.Replace(i.Index, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); + } + + // Collect IDs (except for OpName/OpDecorate/OpDecorateString metadata) + if (i.Op != Op.OpName && i.Op != Op.OpDecorate && i.Op != Op.OpDecorateString) + SpirvBuilder.CollectIds(i.Data, ids); + } + + // Remove unnecessary OpName/OpDecorate/OpDecorateString + // Note: we should issue a warning and make sure those are deleted as we process stuff? + RemoveInstructionWhere(temp, i => + { if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) { if (!ids.Contains(nameInstruction.Target)) - keep = false; + return true; } - - if (keep) + if (i.Op == Op.OpDecorate && (OpDecorate)i is {} decorate) { - if (insertIndex++ != sourceIndex) - // Note: we're not using Dispose() since we simply move it - temp.Replace(insertIndex - 1, temp[sourceIndex].Data, false); + if (!ids.Contains(decorate.Target)) + return true; } - else + if (i.Op == Op.OpDecorate && (OpDecorateString)i is {} decorateString) { - temp[sourceIndex].Data.Dispose(); + if (!ids.Contains(decorateString.Target)) + return true; } - } - - // Remove leftover instructions (they have been either disposed or moved so no need to dispose them - temp.RemoveRange(insertIndex, temp.Count - insertIndex, false); + + return false; + }); } } From d1180d098d8c66f8041c7d9acdb5f2ab934e18c4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 12:01:24 +0900 Subject: [PATCH 0743/1182] Fix AccessorChainExpression OpLoad (invalid type) --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index c65829c2d4..08f87f59b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -461,7 +461,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal var lvalueType = currentValueType; if (lvalueType is PointerType p) { - lvalueBase = new(builder.InsertData(new OpLoad(context.GetOrRegister(lvalueType), context.Bound++, lvalueBase.Id, null, []))); + lvalueBase = new(builder.InsertData(new OpLoad(context.GetOrRegister(p.BaseType), context.Bound++, lvalueBase.Id, null, []))); lvalueType = p.BaseType; } From f50cb725c2bc1c61c0cce7df1502f44ac4976a59 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 12:03:04 +0900 Subject: [PATCH 0744/1182] Store InputAttributes in EffectReflection --- .../SDSL/ShaderMixer.cs | 2 +- .../Spirv/Processing/InterfaceProcessor.cs | 41 +++++++++++++++++-- .../ShaderInputAttributeDescription.cs | 2 + 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 22858d2fbc..de4de96199 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -64,7 +64,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef { CodeInserted = (int index, int count) => AdjustIndicesAfterAppendInstructions(rootMixin, index, count) }; - entryPoints = interfaceProcessor.Process(table, temp, context); + (entryPoints, globalContext.Reflection.InputAttributes) = interfaceProcessor.Process(table, temp, context); // Process Link (add CompositionPath, generate missing ones, etc.) ProcessLinks(context, temp); diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index bc2f572e5d..7e3a64b116 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Parsing.Analysis; using static Stride.Shaders.Spirv.Specification; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using CommunityToolkit.HighPerformance; namespace Stride.Shaders.Spirv.Processing @@ -161,7 +162,9 @@ public bool MarkMethodUsed(int functionId) } } - public List<(string Name, int Id, ShaderStage Stage)> Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) + public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); + + public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); @@ -207,6 +210,9 @@ public bool MarkMethodUsed(int functionId) } } } + + var inputAttributes = new List(); + if (entryPointPS.IdRef != 0) { // If written to, they are expected at the end of pixel shader @@ -262,6 +268,19 @@ public bool MarkMethodUsed(int functionId) (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); + + // Process shader input attributes + foreach (var stream in streams) + { + // Note: built-ins won't have a inputLayoutLocation so they will be skipped + if (stream.Value.Input && stream.Value.InputLayoutLocation is {} inputLayoutLocation) + { + if (stream.Value.Semantic == null) + throw new InvalidOperationException($"Vertex shader input {stream.Value.Name} doesn't have semantic"); + var semantic = ParseSemantic(stream.Value.Semantic); + inputAttributes.Add(new ShaderInputAttributeDescription { Location = inputLayoutLocation, SemanticName = semantic.Name, SemanticIndex = semantic.Index }); + } + } } } @@ -269,7 +288,7 @@ public bool MarkMethodUsed(int functionId) // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); - return entryPoints; + return new(entryPoints, inputAttributes); } private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) @@ -844,7 +863,6 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); } - buffer.Add(new OpReturn()); buffer.Add(new OpFunctionEnd()); @@ -1174,5 +1192,22 @@ private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context } throw new InvalidOperationException($"Could not find start of method {functionId}"); } + + private static readonly Regex MatchSemanticName = new Regex(@"([A-Za-z_]+)(\d*)"); + private static (string Name, int Index) ParseSemantic(string semantic) + { + var match = MatchSemanticName.Match(semantic); + if (!match.Success) + return (semantic, 0); + + string baseName = match.Groups[1].Value; + int value = 0; + if (!string.IsNullOrEmpty(match.Groups[2].Value)) + { + value = int.Parse(match.Groups[2].Value); + } + + return (baseName, value); + } } } diff --git a/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs index b6b0cb3635..1aadbf6c2f 100644 --- a/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs +++ b/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs @@ -8,6 +8,8 @@ namespace Stride.Shaders [DataContract] public struct ShaderInputAttributeDescription { + public int Location; + public string SemanticName; public int SemanticIndex; From 3cc383cf2c8429b42e4a8051569c532f7150ad3e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 12:03:45 +0900 Subject: [PATCH 0745/1182] Added options to control if cbuffer, texture and samplers use same register space or not --- .../SDSL/ShaderMixer.Reflection.cs | 28 ++++++------------- .../SDSL/ShaderMixer.cs | 10 +++++-- src/Stride.Shaders.Experiments/Program.cs | 2 +- src/Stride.Shaders.Tests/RenderingTests.cs | 4 +-- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 2b171f0143..494fac90d3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -167,27 +167,15 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont } // Emit reflection (except ConstantBuffers which was emitted during ComputeCBufferReflection) - private void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, Options options) { - // First, figure out latest used bindings (assume they are filled in order) - int srvSlot = 0; - int samplerSlot = 0; - int cbufferSlot = 0; - foreach (var resourceBinding in globalContext.Reflection.ResourceBindings) - { - switch (resourceBinding) - { - case { Class: EffectParameterClass.ShaderResourceView }: - srvSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - case { Class: EffectParameterClass.Sampler }: - samplerSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - case { Class: EffectParameterClass.ConstantBuffer }: - cbufferSlot = resourceBinding.SlotStart + resourceBinding.SlotCount; - break; - } - } + Span slotCounts = stackalloc int[options.ResourcesRegisterSeparate ? 3 : 1]; + slotCounts.Clear(); + + // If areResourcesSharingSlots is true, every slot type will point to same value + ref var srvSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 0 : 0]; + ref var samplerSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 1 : 0]; + ref var cbufferSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 2 : 0]; // TODO: do this once at root level and reuse for child mixin var samplerStates = new Dictionary(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index de4de96199..18fd397ebf 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -32,9 +32,15 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer(IExternalShaderLoader shaderLoader) { + /// + /// + /// + /// For D3D11/12: t, b and s registers are separate (and should be kept as low as possible so we number them from 0 in each category). + public record struct Options(bool ResourcesRegisterSeparate); + public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) + public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) { var temp = new NewSpirvBuffer(); @@ -84,7 +90,7 @@ public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out Ef RenameVariables(globalContext, context, temp); // Process reflection - ProcessReflection(globalContext, context, temp); + ProcessReflection(globalContext, context, temp, options); SimplifyNotSupportedConstantsInShader(context, temp); diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 618f96c245..59326f7f34 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -15,7 +15,7 @@ var loader = new Examples.ShaderLoader(); loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _, out _, out _); +shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); var source = Spv.Dis(buffer); diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 5cd634c913..2d35c33471 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -79,7 +79,7 @@ public void ComputeTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -116,7 +116,7 @@ public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/RenderTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); From 026560e2c74aad21c4765fd4b2e228fc2c700029 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:11:53 +0900 Subject: [PATCH 0746/1182] Perf: create TypeDuplicateHelper once to avoid full sort every shader --- .../SDSL/ShaderMixer.cs | 10 +++---- .../Spirv/Processing/TypeDuplicatesRemover.cs | 30 +++++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 18fd397ebf..c7980d02f7 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -180,11 +180,13 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) { mixinNode.StartInstruction = buffer.Count; + var typeDuplicateInserter = new TypeDuplicateHelper(context); + foreach (var shaderClass in mixinSource.Mixins) { var contextStart = context.Count; - var shaderInfo = MergeClassInBuffers(globalContext, context, buffer, mixinNode, shaderClass); + var shaderInfo = MergeClassInBuffers(globalContext, context, buffer, mixinNode, shaderClass, typeDuplicateInserter); mixinNode.ShadersByName.Add(shaderClass.ToClassNameWithGenerics(), shaderInfo); mixinNode.Shaders.Add(shaderInfo); @@ -212,7 +214,7 @@ private static string ComposeLinkName(string linkName, string? compositionPath = // Append CompositionPath to "Link" for any non-stage variable // Also force-emit the missing "Link" decorations - private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass) + private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass, TypeDuplicateHelper typeDuplicateInserter) { var isRootMixin = mixinNode.Stage == null; if (shaderClass.ImportStageOnly) @@ -268,8 +270,6 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS return include; } - var typeDuplicateInserter = new TypeDuplicateHelper(context); - var structTypes = new Dictionary(); // Copy instructions to main buffer @@ -435,7 +435,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (addToContext) { - context.Add(i2); + typeDuplicateInserter.InsertInstruction(context.Count, i2); } } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index aa3b5a8f8c..792020b05b 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -183,20 +183,24 @@ public OpDataIndex InsertInstruction(int index, OpData data) { var result = context.Insert(index, data); - // Adjust indices - var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); - for (int i = 0; i < namesByOp.Count; i++) - { - ref var inst = ref namesByOpSpan[i]; - if (inst.Index >= index) - inst.Index++; - } - var instructionsByOpSpan = CollectionsMarshal.AsSpan(instructionsByOp); - for (int i = 0; i < instructionsByOp.Count; i++) + // Adjust indices (optimization: we skip if we added at last index) + if (index != context.Count - 1) { - ref var inst = ref instructionsByOpSpan[i]; - if (inst.Index >= index) - inst.Index++; + var namesByOpSpan = CollectionsMarshal.AsSpan(namesByOp); + for (int i = 0; i < namesByOp.Count; i++) + { + ref var inst = ref namesByOpSpan[i]; + if (inst.Index >= index) + inst.Index++; + } + + var instructionsByOpSpan = CollectionsMarshal.AsSpan(instructionsByOp); + for (int i = 0; i < instructionsByOp.Count; i++) + { + ref var inst = ref instructionsByOpSpan[i]; + if (inst.Index >= index) + inst.Index++; + } } // Add new item From d1bbc7935842371a154f3d4f2ac573311ede1c41 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:12:22 +0900 Subject: [PATCH 0747/1182] Fix: avoid adding OpDecorate ArrayStride multiple times --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs index ea6eaaea82..0c396d7575 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -54,6 +54,8 @@ private void EmitArrayStrideDecorations(SpirvContext context, ArrayType a, TypeM SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, }; context.Add(new OpDecorate(typeId, Specification.Decoration.ArrayStride, [arrayStride])); + + decoratedArrays[typeId] = (alignmentRules, arrayStride); } private void EmitStructDecorations(SpirvContext context, StructType s, SpirvBuilder.AlignmentRules alignmentRules, out int size, out int[] offsets) From 2ab79b5ef6dc992ff32861f31e8f35b4a5b98aa5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:13:05 +0900 Subject: [PATCH 0748/1182] Fix: Invalid image operands for SampleCmp/SampleCmpLevelZero --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 08f87f59b9..f60fa123aa 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -680,7 +680,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso ImageOperandsMask flags = sampleCompare.Name.Name is "SampleCmpLevelZero" ? ImageOperandsMask.Lod : ImageOperandsMask.None; - EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new () : new (context.CompileConstant(0.0f).Id); + EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new (context.CompileConstant(0.0f).Id) : new (); //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" if (sampleCompare.Parameters.Values.Count > 3) From 7daf977ecb9e26c1cbaee555e148aa6d3274c0df Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:13:34 +0900 Subject: [PATCH 0749/1182] Spv2DXIL: expose result parameters --- src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index ad55774662..f5160e7c94 100644 --- a/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -112,16 +112,16 @@ public unsafe struct DXILSpirvLogger public unsafe struct DXILSpirvObject { // Some sysval or other type of data is accessed which needs to be piped // from the app/API implementation into the shader via a buffer - bool metadata_requires_runtime_data; + public bool metadata_requires_runtime_data; // Specifically if a vertex shader needs the first-vertex or base-instance // sysval. These are relevant since these can come from an indirect arg // buffer, and therefore piping them to the runtime data buffer is extra // complex. - bool metadata_needs_draw_sysvals; + public bool metadata_needs_draw_sysvals; - void *buffer; - nint size; + public void *buffer; + public nint size; } public unsafe struct Specialization { From aa7617940944eea2e593866274833370649ec41a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 14:42:57 +0900 Subject: [PATCH 0750/1182] Rewrote Texture/Buffer Load() and indexer (read and writes) --- .../Parsing/SDSL/AST/Expression.cs | 110 +++++++++++++----- 1 file changed, 78 insertions(+), 32 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index f60fa123aa..8580987537 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -443,17 +443,29 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal switch (currentValueType, accessor) { case (PointerType { BaseType: BufferType bufferType }, IndexerExpression indexer): - throw new NotImplementedException(); + { + var resultType = new VectorType(bufferType.BaseType, 4); + var buffer = builder.AsValue(context, lvalueBase); + + var location = indexer.Index.CompileAsValue(table, compiler); + location = builder.Convert(context, location, ScalarType.Int); + var bufferValue = builder.Convert(context, rvalue, resultType); + builder.Insert(new OpImageWrite(buffer.Id, location.Id, bufferValue.Id, null, [])); + // We stop there + return; + } // ImageWrite case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): + { var resultType = new VectorType(textureType.ReturnType, 4); - - var imageValue = builder.AsValue(context, lvalueBase); + var image = builder.AsValue(context, lvalueBase); + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); var texelValue = builder.Convert(context, rvalue, resultType); - builder.Insert(new OpImageWrite(imageValue.Id, imageCoordValue.Id, texelValue.Id, null, [])); + builder.Insert(new OpImageWrite(image.Id, imageCoordValue.Id, texelValue.Id, null, [])); // We stop there return; + } case (PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): // Swizzle: we transform the value to assign accordingly @@ -586,7 +598,51 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Some accessors push up to 2 values on the stack Span accessChainIds = stackalloc int[Accessors.Count * 2]; + + (SpirvValue Value, SymbolType ResultType) BufferLoad(BufferType bufferType, SpirvValue buffer, Expression locationExpression) + { + var resultType = new VectorType(bufferType.BaseType, 4); + + buffer = builder.AsValue(context, buffer); + var location = locationExpression.CompileAsValue(table, compiler); + location = builder.Convert(context, location, ScalarType.Int); + + var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(resultType), context.Bound++, buffer.Id, location.Id, null, [])); + return (new(loadResult.ResultId, loadResult.ResultType), resultType); + } + (SpirvValue Value, SymbolType ResultType) TextureLoad(TextureType textureType, SpirvValue buffer, Expression coordinatesExpression, bool containsLod) + { + var resultType = new VectorType(textureType.ReturnType, 4); + + var imageCoordValue = ConvertTexCoord(context, builder, textureType, coordinatesExpression.CompileAsValue(table, compiler), ScalarType.Int, containsLod); + var imageCoordType = context.ReverseTypes[imageCoordValue.TypeId]; + SpirvValue lod; + + if (containsLod) + { + // We get all components except last one (LOD) + var imageCoordSize = imageCoordType.GetElementCount(); + imageCoordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); + Span shuffleIndices = stackalloc int[imageCoordSize - 1]; + for (int i = 0; i < shuffleIndices.Length; ++i) + shuffleIndices[i] = i; + + // Note: assign LOD first because we truncate imageCoordValue right after + lod = new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, imageCoordValue.Id, [shuffleIndices.Length - 1]))); + imageCoordValue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(imageCoordType), context.Bound++, imageCoordValue.Id, imageCoordValue.Id, new(shuffleIndices)))); + } + else + { + lod = context.CompileConstant(0.0f); + } + + buffer = builder.AsValue(context, buffer); + + var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(resultType), context.Bound++, buffer.Id, imageCoordValue.Id, ImageOperandsMask.Lod, new EnumerantParameters(lod.Id))); + return (new(loadResult.ResultId, loadResult.ResultType), resultType); + } + for (var i = 0; i < Accessors.Count; ++i) { var accessor = Accessors[i]; @@ -707,24 +763,25 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - - var resultType = new VectorType(pointerType.BaseType switch + + (result, accessor.Type) = pointerType.BaseType switch { - BufferType b => b.BaseType, - TextureType t => t.ReturnType, - }, 4); - - var resource = builder.AsValue(context, result); - var returnType = context.GetOrRegister(resultType); - var coords = load.Parameters.Values[0].CompileAsValue(table, compiler); - var loadResult = builder.Insert(new OpImageFetch(returnType, context.Bound++, resource.Id, coords.Id, null, [])); - result = new(loadResult.ResultId, loadResult.ResultType); - accessor.Type = resultType; + BufferType b => BufferLoad(b, result, load.Parameters.Values[0]), + TextureType t => TextureLoad(t, result, load.Parameters.Values[0], true), + }; break; } - case (PointerType { BaseType: BufferType b }, IndexerExpression indexer): + case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): { - throw new NotImplementedException(); + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + + (result, accessor.Type) = pointerType.BaseType switch + { + BufferType b => BufferLoad(b, result, indexer.Index), + TextureType t => TextureLoad(t, result, indexer.Index, false), + }; + break; } case (PointerType { BaseType: StructuredBufferType bufferType }, IndexerExpression indexer): { @@ -737,19 +794,6 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); break; } - case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): - { - var resultType = new VectorType(textureType.ReturnType, 4); - - var imageValue = builder.AsValue(context, result); - var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); - var imageRead = builder.Insert(new OpImageRead(context.GetOrRegister(resultType), context.Bound++, imageValue.Id, imageCoordValue.Id, null, [])); - - result = new(imageRead.ResultId, imageRead.ResultType); - accessor.Type = resultType; - - break; - } case (_, MethodCall methodCall): // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -947,7 +991,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso return result; } - SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue, ScalarType baseType) + SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue, ScalarType baseType, bool hasLod = false) { var textureCoordSize = textureType switch { @@ -957,6 +1001,8 @@ SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureTy }; if (textureType.Arrayed) textureCoordSize++; + if (hasLod) + textureCoordSize++; spirvValue = builder.Convert(context, spirvValue, baseType.GetVectorOrScalar(textureCoordSize)); return spirvValue; } From 6164e1505744b43580bb26309a697b552f956eb1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 14:43:19 +0900 Subject: [PATCH 0751/1182] Rewrote SV semantic processing --- .../Spirv/Processing/InterfaceProcessor.cs | 74 +++++++++---------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 7e3a64b116..806684862b 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -694,48 +694,44 @@ bool AddBuiltin(int variable, BuiltIn builtin) return true; } + bool AddLocation(int variable, string location) + { + // If it fails, default is 0 + int.TryParse(location, out var targetIndex); + context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); + return true; + } + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo stream) { - switch (stream.Semantic?.ToUpperInvariant()) + // Note: false means it needs to be forwarded + // TODO: review the case where we don't use automatic forwarding for HS/DS/GS stages, i.e. SV_POSITION and SV_PrimitiveID + return (executionModel, type, stream.Semantic?.ToUpperInvariant()) switch { - case "SV_DEPTH": - if (executionModel is ExecutionModel.Fragment && type == StreamVariableType.Output) - return AddBuiltin(variable, BuiltIn.FragDepth); - return false; - case {} semantic when semantic.StartsWith("SV_TARGET"): - if (executionModel is ExecutionModel.Fragment && type == StreamVariableType.Output) - { - // If it fails, default is 0 - int.TryParse(semantic.Substring("SV_TARGET".Length), out var targetIndex); - context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); - return true; - } - return false; - case "SV_POSITION": - if (isFirstActiveShader && type == StreamVariableType.Output) - return AddBuiltin(variable, BuiltIn.Position); - if (executionModel == ExecutionModel.Fragment && type == StreamVariableType.Input) - return AddBuiltin(variable, BuiltIn.FragCoord); - return false; - // TODO: Check if first stage - case "SV_INSTANCEID": - if (type == StreamVariableType.Input) - return AddBuiltin(variable, BuiltIn.InstanceIndex); - return false; - case "SV_VERTEXID": - if (executionModel is ExecutionModel.Vertex && type == StreamVariableType.Input) - return AddBuiltin(variable, BuiltIn.VertexIndex); - return false; - case "SV_ISFRONTFACE": - if ((executionModel is ExecutionModel.Fragment && type == StreamVariableType.Input) - || (executionModel is ExecutionModel.Geometry && type == StreamVariableType.Output)) - return AddBuiltin(variable, BuiltIn.FrontFacing); - throw new NotImplementedException($"Invalid use of System-value semantic {stream.Semantic} as {type} in stage {executionModel}"); - case {} semantic when semantic.StartsWith("SV_"): - throw new NotImplementedException($"System-value Semantic not implemented: {semantic}"); - default: - return false; - } + // SV_Depth/SV_Target + (ExecutionModel.Fragment, StreamVariableType.Output, "SV_DEPTH") => AddBuiltin(variable, BuiltIn.FragDepth), + (ExecutionModel.Fragment, StreamVariableType.Output, {} semantic) when semantic.StartsWith("SV_TARGET") => AddLocation(variable, semantic.Substring("SV_TARGET".Length)), + // SV_Position + (ExecutionModel.Vertex, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), + (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), + (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.FragCoord), + // SV_InstanceID/SV_VertexID + (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(variable, BuiltIn.InstanceIndex), + (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(variable, BuiltIn.VertexIndex), + (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID" or "SV_VERTEXID") => false, + // SV_IsFrontFace + (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(variable, BuiltIn.FrontFacing), + // SV_PrimitiveID + (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PrimitiveID") => AddBuiltin(variable, BuiltIn.PrimitiveId), + (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PrimitiveID") => AddBuiltin(variable, BuiltIn.PrimitiveId), + // Compute shaders + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPID") => AddBuiltin(variable, BuiltIn.WorkgroupId), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPINDEX") => AddBuiltin(variable, BuiltIn.LocalInvocationIndex), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPTHREADID") => AddBuiltin(variable, BuiltIn.LocalInvocationId), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_DISPATCHTHREADID") => AddBuiltin(variable, BuiltIn.GlobalInvocationId), + (_, _, {} semantic) when semantic.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic} for stage {executionModel} as {type}"), + _ => false, + }; } foreach (var stream in streams) From 959c2be0b66cd36f63a7a22b9fa70dadd4f65893 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 15:55:27 +0900 Subject: [PATCH 0752/1182] Moved some code from ShaderClass.Compile() into ProcessSymbol() --- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 77 +------------------ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 71 +++++++++++++++++ .../Parsing/SDSL/AST/ShaderElements.cs | 8 ++ 3 files changed, 81 insertions(+), 75 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 63201c9695..5251f68d87 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -479,83 +479,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) Inherit(table, context, shaderType, true); } + // Process symbols and generate types foreach (var member in Elements) { - // Do this early: we want struct to be available for function parameters (same loop) member.ProcessSymbol(table, context); - - if (member is ShaderMethod func) - { - var ftype = new FunctionType(func.ReturnTypeName.ResolveType(table, context), []); - foreach (var arg in func.Parameters) - { - var argSym = arg.TypeName.ResolveType(table, context); - table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = argSym; - ftype.ParameterTypes.Add(new(new PointerType(arg.Type, Specification.StorageClass.Function), arg.Modifiers)); - } - func.Type = ftype; - - table.DeclaredTypes.TryAdd(func.Type.ToString(), func.Type); - } - else if (member is ShaderMember svar) - { - if (!svar.TypeName.TryResolveType(table, context, out var memberType)) - { - if (svar.TypeName.Name.Contains("<")) - throw new NotImplementedException("Can't have member variables with generic shader types"); - var classSource = new ShaderClassInstantiation(svar.TypeName.Name, []); - var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context); - classSource.Buffer = shader; - var shaderType = LoadAndCacheExternalShaderType(table, context, classSource); - - // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) - memberType = svar.TypeName.ResolveType(table, context); - } - - var storageClass = svar.StorageClass == StorageClass.Static || svar.StreamKind == StreamKind.Stream - ? Specification.StorageClass.Private - : Specification.StorageClass.Uniform; - if (memberType is TextureType || memberType is BufferType) - storageClass = Specification.StorageClass.UniformConstant; - if (memberType is StructuredBufferType) - storageClass = Specification.StorageClass.StorageBuffer; - - if (svar.TypeModifier == TypeModifier.Const) - { - if (svar.Value == null) - throw new InvalidOperationException($"Constant {svar.Name} doesn't have a value"); - - // Constant: compile right away - var constantValue = svar.Value.CompileConstantValue(table, context, memberType); - context.SetName(constantValue.Id, svar.Name); - var symbol = new Symbol(new(svar.Name, SymbolKind.Constant), memberType, constantValue.Id); - table.CurrentFrame.Add(svar.Name, symbol); - svar.Type = memberType; - - // This constant is visible when inherited - context.Add(new OpDecorate(constantValue.Id, Decoration.ShaderConstantSDSL, [])); - } - else - { - svar.Type = new PointerType(memberType, storageClass); - table.DeclaredTypes.TryAdd(svar.Type.ToString(), svar.Type); - } - } - else if (member is CBuffer cb) - { - foreach (var cbMember in cb.Members) - { - cbMember.Type = cbMember.TypeName.ResolveType(table, context); - //var symbol = new Symbol(new(cbMember.Name, SymbolKind.CBuffer), cbMember.Type); - //symbols.Add(symbol); - } - } - else if (member is ShaderSamplerState samplerState) - { - samplerState.Type = new SamplerType(); - table.DeclaredTypes.TryAdd(samplerState.Type.ToString(), samplerState.Type); - } } RenameCBufferVariables(); @@ -573,7 +500,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); - // In case calling a method not yet processed, we first register method types + // In case a moethod calling another method not yet processed, we first declare all methods // (SPIR-V allow forward calling) foreach (var method in Elements.OfType()) method.Declare(table, this, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e1ed8237b9..261deb08c3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -8,6 +8,7 @@ using Stride.Shaders.Spirv.Tools; using System.Collections.Immutable; using System.Diagnostics.Metrics; +using CommunityToolkit.HighPerformance; using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -36,6 +37,13 @@ public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMe public Identifier Name { get; set; } = name; public List Parameters { get; set; } = []; + public override void ProcessSymbol(SymbolTable table, SpirvContext context) + { + base.ProcessSymbol(table, context); + Type = new SamplerType(); + table.DeclaredTypes.TryAdd(Type.ToString(), Type); + } + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { (var builder, var context) = compiler; @@ -169,6 +177,52 @@ public sealed class ShaderMember( public StorageClass StorageClass { get; set; } = storageClass; public InterpolationModifier Interpolation { get; set; } = interpolation; + public override void ProcessSymbol(SymbolTable table, SpirvContext context) + { + base.ProcessSymbol(table, context); + if (!TypeName.TryResolveType(table, context, out var memberType)) + { + if (TypeName.Name.Contains("<")) + throw new NotImplementedException("Can't have member variables with generic shader types"); + var classSource = new ShaderClassInstantiation(TypeName.Name, []); + var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context); + classSource.Buffer = shader; + var shaderType = ShaderClass.LoadAndCacheExternalShaderType(table, context, classSource); + + // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) + memberType = TypeName.ResolveType(table, context); + } + + var storageClass = StorageClass == StorageClass.Static || StreamKind == StreamKind.Stream + ? Specification.StorageClass.Private + : Specification.StorageClass.Uniform; + if (memberType is TextureType || memberType is BufferType) + storageClass = Specification.StorageClass.UniformConstant; + if (memberType is StructuredBufferType) + storageClass = Specification.StorageClass.StorageBuffer; + + if (TypeModifier == TypeModifier.Const) + { + if (Value == null) + throw new InvalidOperationException($"Constant {Name} doesn't have a value"); + + // Constant: compile right away + var constantValue = Value.CompileConstantValue(table, context, memberType); + context.SetName(constantValue.Id, Name); + var symbol = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id); + table.CurrentFrame.Add(Name, symbol); + Type = memberType; + + // This constant is visible when inherited + context.Add(new OpDecorate(constantValue.Id, Specification.Decoration.ShaderConstantSDSL, [])); + } + else + { + Type = new PointerType(memberType, storageClass); + table.DeclaredTypes.TryAdd(Type.ToString(), Type); + } + } + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { var (builder, context) = compiler; @@ -201,6 +255,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.AddName(initializerMethod.Value, $"{Name}_Initializer"); } + // Note: StorageClass was decided in Shader.Compile() builder.Insert(new OpVariableSDSL(registeredType, variable, pointerType.StorageClass, variableFlags, initializerMethod)); if (Semantic != null) context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); @@ -294,6 +349,22 @@ public class ShaderMethod( public List Parameters { get; set; } = []; public BlockStatement? Body { get; set; } + + public override void ProcessSymbol(SymbolTable table, SpirvContext context) + { + base.ProcessSymbol(table, context); + var ftype = new FunctionType(ReturnTypeName.ResolveType(table, context), []); + foreach (var arg in Parameters) + { + var argSym = arg.TypeName.ResolveType(table, context); + table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + arg.Type = argSym; + ftype.ParameterTypes.Add(new(new PointerType(arg.Type, Specification.StorageClass.Function), arg.Modifiers)); + } + Type = ftype; + + table.DeclaredTypes.TryAdd(Type.ToString(), Type); + } public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 42c2f89730..a9a523d540 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -221,6 +221,7 @@ public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElemen public override void ProcessSymbol(SymbolTable table, SpirvContext context) { + base.ProcessSymbol(table, context); var fields = new List(); foreach (var smem in Members) { @@ -289,6 +290,13 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable return (null, null); } + public override void ProcessSymbol(SymbolTable table, SpirvContext context) + { + base.ProcessSymbol(table, context); + foreach (var cbMember in Members) + cbMember.Type = cbMember.TypeName.ResolveType(table, context); + } + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; From ed88d4d1c120d5a080714c0bf98b2acce13755c3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 16:47:02 +0900 Subject: [PATCH 0753/1182] Added support for groupshared --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 16 +++++++++------- .../Spirv/Processing/InterfaceProcessor.cs | 4 ++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 261deb08c3..91433f0399 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -193,13 +193,15 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) memberType = TypeName.ResolveType(table, context); } - var storageClass = StorageClass == StorageClass.Static || StreamKind == StreamKind.Stream - ? Specification.StorageClass.Private - : Specification.StorageClass.Uniform; - if (memberType is TextureType || memberType is BufferType) - storageClass = Specification.StorageClass.UniformConstant; - if (memberType is StructuredBufferType) - storageClass = Specification.StorageClass.StorageBuffer; + var storageClass = (memberType, StorageClass, StreamKind) switch + { + (TextureType or BufferType, _, _) => Specification.StorageClass.UniformConstant, + (StructuredBufferType, _, _) => Specification.StorageClass.StorageBuffer, + (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, + (_, StorageClass.Static, _) => Specification.StorageClass.Private, + (_, _, StreamKind.Stream) => Specification.StorageClass.Private, + _ => Specification.StorageClass.Uniform, + }; if (TypeModifier == TypeModifier.Const) { diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 806684862b..c208241320 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -401,7 +401,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private, + Storageclass: StorageClass.Private or StorageClass.Workgroup, ResultId: int } variable2) { @@ -566,7 +566,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private, + Storageclass: StorageClass.Private or StorageClass.Workgroup, ResultId: int } variable) { From 523e382f585651744b2ce132a5e8e61460145908 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 17:25:37 +0900 Subject: [PATCH 0754/1182] Better support for RW resources and UAV reflection --- .../SDSL/ShaderMixer.Reflection.cs | 95 +++++++++---------- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 3 +- .../Spirv/Building/SpirvContext.Types.cs | 4 +- 3 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 494fac90d3..f4b4f44f6e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -169,13 +169,14 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont // Emit reflection (except ConstantBuffers which was emitted during ComputeCBufferReflection) private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, Options options) { - Span slotCounts = stackalloc int[options.ResourcesRegisterSeparate ? 3 : 1]; + Span slotCounts = stackalloc int[options.ResourcesRegisterSeparate ? 4 : 1]; slotCounts.Clear(); // If areResourcesSharingSlots is true, every slot type will point to same value ref var srvSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 0 : 0]; ref var samplerSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 1 : 0]; ref var cbufferSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 2 : 0]; + ref var uavSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 3 : 0]; // TODO: do this once at root level and reuse for child mixin var samplerStates = new Dictionary(); @@ -279,61 +280,59 @@ or Specification.Decoration.SamplerStateMinLOD LogicalGroup = linkInfo.LogicalGroup, }; - if (variableType is TextureType t) + if (variableType is TextureType or BufferType or StructuredBufferType) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + bool isUAV = variableType switch { - Class = EffectParameterClass.ShaderResourceView, - Type = (t, t.Multisampled) switch - { - (Texture1DType, false) => EffectParameterType.Texture1D, - (Texture2DType, false) => EffectParameterType.Texture2D, - (Texture2DType, true) => EffectParameterType.Texture2DMultisampled, - (Texture3DType, false) => EffectParameterType.Texture3D, - (TextureCubeType, false) => EffectParameterType.TextureCube, - }, - SlotStart = srvSlot, - SlotCount = 1, - }); + TextureType t1 => t1.Sampled == 2, + BufferType b1 => b1.WriteAllowed, + StructuredBufferType sb1 => sb1.WriteAllowed, + }; + ref var slot = ref (isUAV ? ref uavSlot : ref srvSlot); + effectResourceBinding.Class = isUAV ? EffectParameterClass.UnorderedAccessView : EffectParameterClass.ShaderResourceView; + effectResourceBinding.SlotStart = slot; + effectResourceBinding.SlotCount = 1; context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [slot])); - srvSlot++; - } - else if (variableType is BufferType) - { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with - { - Class = EffectParameterClass.ShaderResourceView, - Type = EffectParameterType.Buffer, - SlotStart = srvSlot, - SlotCount = 1, - }); + slot++; - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); - - srvSlot++; - } - else if (variableType is StructuredBufferType structuredBufferType) - { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + if (variableType is TextureType t) { - Class = EffectParameterClass.ShaderResourceView, - Type = structuredBufferType.WriteAllowed ? EffectParameterType.RWStructuredBuffer : EffectParameterType.StructuredBuffer, - SlotStart = srvSlot, - SlotCount = 1, - }); - - var baseType = structuredBufferType.BaseType; - // This will add array stride and offsets decorations - EmitTypeDecorationsRecursively(context, baseType, SpirvBuilder.AlignmentRules.StructuredBuffer); - - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [srvSlot])); + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Type = (t, t.Multisampled, t.Sampled == 2) switch + { + (Texture1DType, false, false) => EffectParameterType.Texture1D, + (Texture2DType, false, false) => EffectParameterType.Texture2D, + (Texture2DType, true, false) => EffectParameterType.Texture2DMultisampled, + (Texture3DType, false, false) => EffectParameterType.Texture3D, + (TextureCubeType, false, false) => EffectParameterType.TextureCube, + (Texture1DType, false, true) => EffectParameterType.RWTexture1D, + (Texture2DType, false, true) => EffectParameterType.RWTexture2D, + (Texture3DType, false, true) => EffectParameterType.RWTexture3D, + }, + }); + } + else if (variableType is BufferType bufferType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Type = bufferType.WriteAllowed ? EffectParameterType.RWBuffer : EffectParameterType.Buffer, + }); + } + else if (variableType is StructuredBufferType structuredBufferType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Type = structuredBufferType.WriteAllowed ? EffectParameterType.RWStructuredBuffer : EffectParameterType.StructuredBuffer, + }); - srvSlot++; + var baseType = structuredBufferType.BaseType; + // This will add array stride and offsets decorations + EmitTypeDecorationsRecursively(context, baseType, SpirvBuilder.AlignmentRules.StructuredBuffer); + } } else if (variableType is SamplerType) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 5251f68d87..51659de264 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -160,6 +160,7 @@ void RegisterName(int target, string name) ? structName switch { var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type), + var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type, true), var s when s.StartsWith("type.") => new ConstantBufferSymbol(structName.Substring("type.".Length), fields), _ => throw new InvalidOperationException(), } @@ -201,7 +202,7 @@ void RegisterName(int target, string name) var sampledType = (ScalarType)context.ReverseTypes[typeImage.SampledType]; if (typeImage.Dim == Dim.Buffer) { - RegisterType(typeImage.ResultId, new BufferType(sampledType)); + RegisterType(typeImage.ResultId, new BufferType(sampledType, typeImage.Sampled == 2)); } else { diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index e11a387cf1..fab74e8c9d 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -50,7 +50,7 @@ public int GetOrRegister(SymbolType? type) t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Specification.Dim.Buffer, - 2, 0, 0, 1, Specification.ImageFormat.Unknown, null)).IdResult, + 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, StructuredBufferType b => RegisterStructuredBufferType(b), SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, @@ -69,7 +69,7 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).IdResult.Value; var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).IdResult.Value; - AddName(bufferType, $"type.StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); + AddName(bufferType, $"type.{(structuredBufferType.WriteAllowed ? "RW" : "")}StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); // TODO: Add array stride and offsets From cd7353d895c91593d79eef41c7efa1d19dfee955 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 18:03:07 +0900 Subject: [PATCH 0755/1182] Instructions: EnumerantParameters were skipped in case quantifier was "?" --- .../SPVGenerator.Instructions.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 7913d338bc..35844dad93 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -374,8 +374,13 @@ static string ToSpreadOperator(OperandData operand) (string s, null or "") when s.Contains("Id") => $"{fieldName}", (string s, "?") when s.Contains("Id") => $".. ({fieldName} is null ? (Span)[] : [{fieldName}.Value])", (string s, null or "") when s.Contains("Enum") => - operand.IsParameterized ? $"(int){fieldName}, .. {fieldName}Parameters" : $"(int){fieldName}", - (string s, "?") when s.Contains("Enum") => $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value])", + operand.IsParameterized + ? $"(int){fieldName}, .. {fieldName}Parameters" + : $"(int){fieldName}", + (string s, "?") when s.Contains("Enum") => + operand.IsParameterized + ? $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value, ..{fieldName}Parameters])" + : $".. ({fieldName} is null ? (Span)[] : [(int){fieldName}.Value])", (string, "*") => $".. {fieldName}.Words", (string, "?") => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", (_, "?") => $".. ({fieldName} is null ? (Span)[] : {fieldName}.AsDisposableLiteralValue().Words)", From 9686a88cb38fc968ecfe19b6f6a08e3ba2af7b5f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 27 Jan 2026 18:52:51 +0900 Subject: [PATCH 0756/1182] Fix atan2 intrinsic --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 32 +++---------------- .../PrimaryExpressionParsers.cs | 8 ++--- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 728bd95955..59613a0507 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -98,7 +98,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return new(instruction.ResultId, instruction.ResultType); } } -public class PowCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) +public class GLSLFloatBinaryCall(ShaderExpressionList parameters, TextLocation info, Specification.GLSLOp op) : MethodCall(new(op.ToString(), info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { @@ -116,11 +116,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (context.GLSLSet == null) context.ImportGLSL(); var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + // Adjust OpCode only since Pow/Atan2 share the same operands + instruction.InstructionMemory.Span[4] = (int)op; + var result = new SpirvValue(instruction.ResultId, instruction.ResultType); return new(instruction.ResultId, instruction.ResultType); } } -public class GLSLFloatUnaryCall(ShaderExpressionList parameters, TextLocation info, Specification.GLSLOp op, float? multiplyConstant = null) : MethodCall(new("exp", info), parameters, info) +public class GLSLFloatUnaryCall(ShaderExpressionList parameters, TextLocation info, Specification.GLSLOp op, float? multiplyConstant = null) : MethodCall(new(op.ToString(), info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { @@ -342,18 +345,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return new(instruction.ResultId, instruction.ResultType); } } -public class StepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("step", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (edge, x) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLStep(edge.TypeId, context.Bound++, context.GLSLSet ?? -1, edge.Id, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smoothstep", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) @@ -597,19 +588,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return new(instruction.ResultId, instruction.ResultType); } } -public class CrossCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("cross", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLCross(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} - public class DotCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("dot", info), parameters, info) { public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 1221bb8da2..9de097516a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -77,7 +77,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("cosh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCosh), ("acos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAcos), ("atan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan), - ("atan2", 2) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), + ("atan2", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), ("tan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTan), ("tanh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTanh), ("sincos", _) => throw new NotImplementedException(), @@ -108,7 +108,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("log", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog), ("log10", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2, (float)Math.Log10(2.0)), ("log2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2), - ("pow", 2) => new PowCall(parameters, scanner[position..scanner.Position]), + ("pow", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLPow), ("round", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRoundEven), ("rsqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLInverseSqrt), @@ -117,12 +117,12 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), - ("step", 2) => new StepCall(parameters, scanner[position..scanner.Position]), + ("step", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLStep), // Vector math ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), - ("cross", 2) => new CrossCall(parameters, scanner[position..scanner.Position]), + ("cross", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCross), ("distance", _) => new DistanceCall(parameters, scanner[position..scanner.Position]), ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), ("normalize", _) => new NormalizeCall(parameters, scanner[position..scanner.Position]), From 8aee2162630b0fe92b3a19e28cf754286068d608 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 Jan 2026 13:27:24 +0900 Subject: [PATCH 0757/1182] Separated symbol resolution from symbol importing --- .../SDSL/ShaderMixer.ShaderInfo.cs | 2 + .../SDSL/ShaderMixer.cs | 17 +- .../Examples.Spirv.cs | 6 +- src/Stride.Shaders/Core/SymbolTypes.cs | 151 +++++++++++++----- .../Parsing/Analysis/SymbolTable.cs | 5 +- .../Parsing/SDSL/AST/Expression.cs | 57 +++---- .../Parsing/SDSL/AST/Literals.cs | 7 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 9 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 10 +- .../Parsing/SDSL/AST/ShaderElements.cs | 6 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 2 +- .../Parsing/SDSL/AST/Statements.cs | 4 +- src/Stride.Shaders/Parsing/SDSLERR.cs | 3 + .../Spirv/Building/Builder.Expressions.cs | 49 ++++-- 14 files changed, 213 insertions(+), 115 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index d10c0c3334..351b1ba89e 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -25,6 +25,8 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio /// The for the same shader at the top-level (for all the stage members, if any). /// public ShaderInfo? Stage { get; set; } + + public LoadedShaderSymbol Symbol { get; set; } /// /// Kept for debug purpose. diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index c7980d02f7..e8fb72b816 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -463,6 +463,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // Build ShaderInfo var shaderInfo = new ShaderInfo(mixinNode.Shaders.Count, shaderClass.ClassName, shaderStart, buffer.Count); + shaderInfo.Symbol = shaderClass.Symbol; foreach (var structType in structTypes) shaderInfo.StructTypes.Add(structType.Key, structType.Value); shaderInfo.CompositionPath = mixinNode.CompositionPath; @@ -474,18 +475,6 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, MixinNode mixinNode) { - // Add symbol for each method in current type (equivalent to implicit this pointer) - for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) - { - var i = temp[index]; - if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) - { - var functionName = context.Names[function.ResultId]; - var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId); - table.CurrentFrame.Add(functionName, symbol); - } - } - // Build method group info (override, etc.) ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) @@ -508,6 +497,10 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, { var functionName = context.Names[function.ResultId]; var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; + + // Add symbol for each method in current type (equivalent to implicit this pointer) + var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId, OwnerType: currentShader.Symbol); + table.CurrentFrame.Add(functionName, symbol); var methodMixinGroup = mixinNode; if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 15433f9c85..76f27161fb 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -1,6 +1,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Core.Parsing; @@ -17,6 +18,7 @@ public static void GenerateSpirv() { var compiler = new CompilerUnit(); var (builder, context) = compiler; + var table = new SymbolTable(context); context.GetOrRegister(new MatrixType(ScalarType.Float, 4, 3)); context.GetOrRegister(ScalarType.Int); @@ -36,8 +38,10 @@ public static void GenerateSpirv() var block = builder.CreateBlock(context, "sourceBlock"); builder.SetPositionTo(block); var v = builder.BinaryOperation( + table, context, - function.Parameters["a"], Operator.Plus, function.Parameters["b"] + function.Parameters["a"], Operator.Plus, function.Parameters["b"], + default ); builder.Return(v); builder.EndFunction(); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 09a0193097..37904403f9 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -397,31 +397,137 @@ public sealed partial record LoadedShaderSymbol(string Name, int[] GenericArgume public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; public List InheritedShaders { get; init; } = []; - internal bool TryResolveSymbol(SymbolTable symbolTable, SpirvContext context, string name, out Symbol symbol) + public static Symbol ImportSymbol(SymbolTable table, Symbol symbol) { - if (TryResolveSymbolNoRecursion(this == symbolTable.CurrentShader, context, name, out symbol)) + bool isCurrentShader = symbol.OwnerType == table.CurrentShader; + + // Check if symbol is already imported + if (symbol.IdRef != 0) + { + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = symbol.Type }; + return symbol; + } + + // Find same symbol in owner type + if (symbol.OwnerType == null) + throw new InvalidOperationException(); + + var context = table.Context; + + if (isCurrentShader && symbol.IdRef == 0) + throw new InvalidOperationException("Symbols in current shader should be resolved"); + + if (symbol.Type is FunctionGroupType) + throw new InvalidOperationException($"Can't import symbol for {nameof(FunctionGroupType)}"); + + if (symbol.Type is FunctionType) + { + var methods = CollectionsMarshal.AsSpan(symbol.OwnerType.Methods); + foreach (ref var c in methods) + { + if (c.Symbol.Id == symbol.Id && c.Symbol.Type == symbol.Type) + { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + // TODO: emit it only when this specific method is *selected* as proper overload (signature) & override (base vs this) + var shaderId = context.GetOrRegister(symbol.OwnerType); + context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); + } + + symbol.IdRef = c.Symbol.IdRef; + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + + return symbol; + } + } + } + else + { + var variables = CollectionsMarshal.AsSpan(symbol.OwnerType.Variables); + foreach (ref var c in variables) + { + if (c.Symbol.Id == symbol.Id && c.Symbol.Type == symbol.Type) + { + if (c.Symbol.IdRef == 0) + { + // Emit symbol + var shaderId = context.GetOrRegister(symbol.OwnerType); + context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); + } + + symbol.IdRef = c.Symbol.IdRef; + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + return symbol; + } + + if (c.Symbol.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) + { + for (int index = 0; index < cb.Members.Count; index++) + { + var member = cb.Members[index]; + var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); + var cbufferSymbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, AccessChain: index, OwnerType: symbol.OwnerType); + + if (cbufferSymbol.Id == symbol.Id && cbufferSymbol.Type == symbol.Type) + { + if (c.Symbol.IdRef == 0 && context != null) + { + // Emit symbol + var shaderId = context.GetOrRegister(symbol.OwnerType); + context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); + } + + symbol.IdRef = c.Symbol.IdRef; + if (!isCurrentShader) + symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + + return symbol; + } + } + } + } + } + + throw new InvalidOperationException($"Symbol {symbol} could not be imported because it was not found in its owner type {symbol.OwnerType}"); + } + + /// + /// Try to resolve a symbol in shader or inherited shader. If is null, you can use this method without importing type or symbol in a context (useful for type evaluation). + /// + /// + /// If not null, the method or symbol will be imported in this context. + /// + /// + /// + internal bool TryResolveSymbol(string name, out Symbol symbol) + { + if (TryResolveSymbolNoRecursion(name, out symbol)) return true; // Process inherited classes // note: since it contains all indirectly inherited method too, which is why it is splitted with TryResolveSymbolNoRecursion foreach (var inheritedShader in InheritedShaders) - if (inheritedShader.TryResolveSymbolNoRecursion(false, context, name, out symbol)) + if (inheritedShader.TryResolveSymbolNoRecursion(name, out symbol)) return true; return false; } - private bool TryResolveSymbolNoRecursion(bool isCurrentShader, SpirvContext context, string name, out Symbol symbol) + private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) { symbol = default; - var found = BuildMethodGroup(isCurrentShader, context, name, ref symbol); + var found = BuildMethodGroup(name, ref symbol); if (found) { // If any method is found, let's process inherited classes too: we need all method groups to find proper override foreach (var inheritedClass in InheritedShaders) { - inheritedClass.BuildMethodGroup(false, context, name, ref symbol); + inheritedClass.BuildMethodGroup(name, ref symbol); } return true; } @@ -431,16 +537,7 @@ private bool TryResolveSymbolNoRecursion(bool isCurrentShader, SpirvContext cont { if (c.Symbol.Id.Name == name) { - if (c.Symbol.IdRef == 0) - { - // Emit symbol - var shaderId = context.GetOrRegister(this); - context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); - } - symbol = c.Symbol; - if (!isCurrentShader) - symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return true; } @@ -452,17 +549,8 @@ private bool TryResolveSymbolNoRecursion(bool isCurrentShader, SpirvContext cont var member = cb.Members[index]; if (member.Name == name) { - if (c.Symbol.IdRef == 0) - { - // Emit symbol - var shaderId = context.GetOrRegister(this); - context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); - } - var sid = new SymbolID(member.Name, SymbolKind.CBuffer, Storage.Uniform); - symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, AccessChain: index); - if (!isCurrentShader) - symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; + symbol = new Symbol(sid, new PointerType(member.Type, Specification.StorageClass.Uniform), c.Symbol.IdRef, AccessChain: index, OwnerType: c.Symbol.OwnerType); return true; } } @@ -473,7 +561,7 @@ private bool TryResolveSymbolNoRecursion(bool isCurrentShader, SpirvContext cont return false; } - private bool BuildMethodGroup(bool isCurrentShader, SpirvContext context, string name, ref Symbol symbol) + private bool BuildMethodGroup(string name, ref Symbol symbol) { var found = false; var methods = CollectionsMarshal.AsSpan(Methods); @@ -481,20 +569,9 @@ private bool BuildMethodGroup(bool isCurrentShader, SpirvContext context, string { if (c.Symbol.Id.Name == name) { - if (c.Symbol.IdRef == 0) - { - // Emit symbol - // TODO: emit it only when this specific method is *selected* as proper overload (signature) & override (base vs this) - var shaderId = context.GetOrRegister(this); - context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); - } - // Combine method symbols if multiple matches var methodSymbol = c.Symbol; - if (!isCurrentShader) - methodSymbol = methodSymbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; - // If symbol is set, complete it as a method group symbol = symbol.Type switch { diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index adbf31737f..f42e263846 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -51,12 +51,11 @@ public SymbolTable(SpirvContext context) public bool TryResolveSymbol(string name, out Symbol symbol) { - for (int i = CurrentSymbols.Count - 1; i >= 0; i--) if (CurrentSymbols[i].TryGetValue(name, out symbol)) return true; - if (CurrentShader != null && CurrentShader.TryResolveSymbol(this, Context, name, out symbol)) + if (CurrentShader != null && CurrentShader.TryResolveSymbol(name, out symbol)) return true; symbol = default; @@ -73,7 +72,7 @@ public Symbol ResolveSymbol(string name) } } - if (CurrentShader != null && CurrentShader.TryResolveSymbol(this, Context, name, out var symbol2)) + if (CurrentShader != null && CurrentShader.TryResolveSymbol(name, out var symbol2)) return symbol2; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 8580987537..3e79463702 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -69,13 +69,16 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public Identifier Name = name; public ShaderExpressionList Parameters = parameters; + public LoadedShaderSymbol? MemberCallBaseType { get; set; } public SpirvValue? MemberCall { get; set; } public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var (builder, context) = compiler; - var functionSymbol = ResolveFunctionSymbol(table, context); + var functionSymbol = ResolveFunctionSymbol(table); + functionSymbol = LoadedShaderSymbol.ImportSymbol(table, functionSymbol); + var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; @@ -96,7 +99,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var inOutFlags = paramDefinition.Modifiers & ParameterModifiers.InOut; if (inOutFlags != ParameterModifiers.Out) { - var paramSource = parameters.Values[i].CompileAsValue(table, compiler); + var paramSource = parameters.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); // Convert type (if necessary) var paramExpectedValueType = paramDefinition.Type; @@ -166,7 +169,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, { var paramDefinitionType = (PointerType)paramDefinition.Type; var paramVariable = compiledParams[i]; - var paramTarget = parameters.Values[i].Compile(table, compiler); + var paramTarget = parameters.Values[i].Compile(table, compiler, paramDefinitionType); var paramTargetType = (PointerType)context.ReverseTypes[paramTarget.TypeId]; if (paramTargetType.BaseType != paramDefinitionType.BaseType) @@ -180,15 +183,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return result; } - private Symbol ResolveFunctionSymbol(SymbolTable table, SpirvContext context) + private Symbol ResolveFunctionSymbol(SymbolTable table) { Symbol functionSymbol; // Note: for now, TypeId 0 is used for this/base; let's improve that later if (MemberCall != null && MemberCall.Value.TypeId != 0) { - var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) - throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); + if (!MemberCallBaseType.TryResolveSymbol(Name, out functionSymbol)) + throw new InvalidOperationException($"Method {Name} could not be found in type {MemberCallBaseType.Name}"); } else { @@ -198,35 +200,19 @@ private Symbol ResolveFunctionSymbol(SymbolTable table, SpirvContext context) // Choose appropriate method to call if (functionSymbol.Type is FunctionGroupType) { - // Find methods matching number of parameters - var matchingMethods = functionSymbol.GroupMembers.Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); - + var matchingMethods = functionSymbol.GroupMembers + // Find methods matching number of parameters + .Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); + // TODO: find proper overload (different signature) // We take first element, so in case there is multiple override, it will take the most-derived implementation - // Note: this will be reevaluted during ShaderMixer (base/this, etc.) but it won't change overload (different signature) + // Note: this will be reevaluted during ShaderMixer (which specific override depending on base/this, etc.) but it won't change overload (different signature) functionSymbol = matchingMethods.First(); } return functionSymbol; } - private Symbol ResolveSymbol(SymbolTable table, SpirvContext context) - { - Symbol functionSymbol; - if (MemberCall != null) - { - var type = (LoadedShaderSymbol)((PointerType)context.ReverseTypes[MemberCall.Value.TypeId]).BaseType; - if (!type.TryResolveSymbol(table, context, Name, out functionSymbol)) - throw new InvalidOperationException($"Method {Name} could not be found in type {type.Name}"); - } - else - { - functionSymbol = table.ResolveSymbol(Name); - } - - return functionSymbol; - } - public override string ToString() { return $"{Name}({string.Join(", ", Parameters)})"; @@ -315,11 +301,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, // Use integer so that it gets converted to proper type according to expression type var constant1 = context.CompileConstant(1); - var result = builder.BinaryOperation(context, valueExpression, Operator switch + var result = builder.BinaryOperation(table, context, valueExpression, Operator switch { Operator.Inc => Operator.Plus, Operator.Dec => Operator.Minus, - }, constant1); + }, constant1, info); // We store the modified value back in the variable builder.Insert(new OpStore(expression.Id, result.Id, null, [])); @@ -798,6 +784,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); + methodCall.MemberCallBaseType = result.TypeId != 0 ? (LoadedShaderSymbol)((PointerType)currentValueType).BaseType : null; methodCall.MemberCall = result; result = methodCall.Compile(table, compiler); break; @@ -805,9 +792,11 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - if (!s.TryResolveSymbol(table, context, field.Name, out var matchingComponent)) + if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) throw new InvalidOperationException(); + matchingComponent = LoadedShaderSymbol.ImportSymbol(table, matchingComponent); + // TODO: figure out instance (this vs composition) result = Identifier.EmitSymbol(builder, context, matchingComponent, false, result.Id); accessor.Type = matchingComponent.Type; @@ -963,11 +952,11 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Use integer so that it gets converted to proper type according to expression type var constant1 = context.CompileConstant(1); - var modifiedValue = builder.BinaryOperation(context, result, postfix.Operator switch + var modifiedValue = builder.BinaryOperation(table, context, result, postfix.Operator switch { Operator.Inc => Operator.Plus, Operator.Dec => Operator.Minus, - }, constant1); + }, constant1, info); // We store the modified value back in the variable builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null, [])); @@ -1068,7 +1057,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var right = Right.CompileAsValue(table, compiler, expectedOperandType); var (builder, context) = compiler; - var result = builder.BinaryOperation(context, left, Op, right); + var result = builder.BinaryOperation(table, context, left, Op, right, info); Type = context.ReverseTypes[result.TypeId]; return result; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ea7586339c..a0957ccc98 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -317,11 +317,16 @@ private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvC if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) throw new InvalidOperationException($"Streams member {Name} used without an object"); Type = symbol.Type; + + symbol = LoadedShaderSymbol.ImportSymbol(table, symbol); return EmitSymbol(builder, context, symbol, constantOnly); } public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { + if (symbol.IdRef == 0) + throw new InvalidOperationException($"Symbol {symbol} has not been imported or created properly"); + var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); @@ -336,7 +341,7 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, result.Id = instance.Value; return result; } - + if (symbol.ExternalConstant is { } externalConstant) { if (externalConstant.SourceContext != context) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 51659de264..b5d448b0f0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -400,9 +400,11 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; builder.Insert(new OpSDSLShader(name)); - table.Push(); - var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; + var currentShader = new LoadedShaderSymbol(Name, openGenerics); + table.Push(); + table.CurrentShader = currentShader; + var hasUnresolvableGenerics = false; if (Generics != null) { @@ -418,7 +420,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) // Note: we skip MemberName because they should have been replaced with the preprocessor during SpirvBuilder.InstantiateMemberNames() step if (genericParameterType is not GenericParameterType { Kind: GenericParameterKindSDSL.MemberName or GenericParameterKindSDSL.MemberNameResolved }) - table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound)); + table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound, OwnerType: table.CurrentShader)); openGenerics[i] = context.Bound; @@ -463,7 +465,6 @@ public void Compile(SymbolTable table, CompilerUnit compiler) SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile); } - var currentShader = new LoadedShaderSymbol(Name, openGenerics); RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 91433f0399..b866cd0574 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -125,7 +125,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); var sid = new SymbolID(Name, SymbolKind.SamplerState); - var symbol = new Symbol(sid, Type, variable.ResultId); + var symbol = new Symbol(sid, Type, variable.ResultId, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } else throw new Exception($"SamplerState {Name} already defined"); @@ -211,7 +211,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) // Constant: compile right away var constantValue = Value.CompileConstantValue(table, context, memberType); context.SetName(constantValue.Id, Name); - var symbol = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id); + var symbol = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id, OwnerType: table.CurrentShader); table.CurrentFrame.Add(Name, symbol); Type = memberType; @@ -457,10 +457,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { // Find parent function var parentSymbol = table.ResolveSymbol(function.Name); - // TODO: find proper overload + // If multiple symbol with same name, find the proper overload (it should have the exact same signature) if (parentSymbol.Type is FunctionGroupType) parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); + parentSymbol = LoadedShaderSymbol.ImportSymbol(table, parentSymbol); + functionInfo.Parent = parentSymbol.IdRef; functionInfo.Flags |= Specification.FunctionFlagsMask.Override; } @@ -478,7 +480,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); - table.CurrentFrame.Add(p.Name, new(new(p.Name, SymbolKind.Variable), parameterType, paramValue.Id)); + table.CurrentFrame.Add(p.Name, new(new(p.Name, SymbolKind.Variable), parameterType, paramValue.Id, OwnerType: table.CurrentShader)); } if (Body is BlockStatement body && !hasUnresolvableGenerics) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index a9a523d540..b98b0826fc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -264,6 +264,7 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable // Try to resolve generic parameter when encoded as string (deprecated) if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) { + linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, linkLiteralSymbol); // TODO: make it a warning only? //table.Errors.Add(new(info, "LinkType generics should be passed without quotes")); return (null, linkLiteralSymbol.IdRef); @@ -277,6 +278,7 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable { throw new InvalidOperationException(); } + linkSymbol = LoadedShaderSymbol.ImportSymbol(table, linkSymbol); return (null, linkSymbol.IdRef); } else @@ -348,7 +350,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); - var symbol = new Symbol(sid, pointerType, variable); + var symbol = new Symbol(sid, pointerType, variable, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } } @@ -388,7 +390,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.LogicalGroupSDSL, LogicalGroup)); var sid = new SymbolID(member.Name, kind, Storage.Uniform); - var symbol = new Symbol(sid, type, variable.ResultId); + var symbol = new Symbol(sid, type, variable.ResultId, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 39d2557134..12279dc1e6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -64,7 +64,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) // (we could emit a "For" loop statement, but it would be too complex to write a general decompiler for a "for" loop when processing it later) var variableId = builder.Insert(new OpForeachSDSL(context.GetOrRegister(variableType), context.Bound++, collection.Id)); table.Push(); - var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), variableType, variableId); + var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), variableType, variableId, OwnerType: table.CurrentShader); table.CurrentFrame.Add(Variable.Name, variableSymbol); Body.Compile(table, compiler); table.Pop(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 42cfbde0c2..26954eded5 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -180,7 +180,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) builder.AddFunctionVariable(variableTypeId, variable); context.AddName(variable, d.Variable); - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), variableType, variable)); + table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), variableType, variable, OwnerType: table.CurrentShader)); // Check initial value if (d.Value != null) @@ -235,7 +235,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var left = builder.AsValue(context, target); var right = builder.AsValue(context, source); - source = builder.BinaryOperation(context, left, binaryOperator, right); + source = builder.BinaryOperation(table, context, left, binaryOperator, right, info); } // Make sure to convert to proper type diff --git a/src/Stride.Shaders/Parsing/SDSLERR.cs b/src/Stride.Shaders/Parsing/SDSLERR.cs index 7b17567640..1e9c9051af 100644 --- a/src/Stride.Shaders/Parsing/SDSLERR.cs +++ b/src/Stride.Shaders/Parsing/SDSLERR.cs @@ -5,6 +5,7 @@ namespace Stride.Shaders.Parsing; /// public static class SDSLErrorMessages { + // Parse errors public const string SDSL0001 = "SDSL0001: Unexpected token"; public const string SDSL0002 = "SDSL0002: vector size not supported"; public const string SDSL0003 = "SDSL0003: matrix size not supported"; @@ -60,4 +61,6 @@ public static class SDSLErrorMessages public const string SDSL0104 = "SDSL0104: Cannot infer type"; public const string SDSL0105 = "SDSL0105: Unrecognized node"; public const string SDSL0106 = "SDSL0106: Unsupported type"; + public const string SDSL0107 = "SDSL0107: Binary expression between vector and matrix is not implemented"; + public const string SDSL0108 = "SDSL0108: Couldn't figure out type for binary operation between {0} and {1}"; } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index f19c2930e6..f1d0fbc88c 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -99,18 +100,15 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle }; } - public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operator op, SpirvValue right, string? name = null) + public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOperation(SymbolTable table, SymbolType leftType, Operator op, SymbolType rightType, TextLocation info) { - var leftType = context.ReverseTypes[left.TypeId]; - var rightType = context.ReverseTypes[right.TypeId]; - var leftElementType = leftType.GetElementType(); var rightElementType = rightType.GetElementType(); // Check base types // TODO: special case for operators expecting different types (i.e. bit shifts) var desiredElementType = FindCommonBaseTypeForBinaryOperation(leftElementType, rightElementType); - + // Check size SymbolType resultType; switch (leftType, rightType) @@ -137,32 +135,46 @@ public SpirvValue BinaryOperation(SpirvContext context, SpirvValue left, Operato break; case (MatrixType, VectorType): case (VectorType, MatrixType): - throw new NotImplementedException("Binary expression between vector and matrix is not implemented"); + table.Errors.Add(new (info, SDSLErrorMessages.SDSL0107)); + return null; case (MatrixType l, MatrixType r): resultType = new MatrixType(desiredElementType, Math.Min(l.Rows, r.Rows), Math.Min(l.Columns, r.Columns)); break; default: - throw new NotImplementedException($"Couldn't figure out type for binary operation between {leftType} and {rightType}"); + table.Errors.Add(new (info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); + return null; } - // TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations) - // We'll need to review those cases - left = Convert(context, left, resultType); - right = Convert(context, right, resultType); - + var operandType = resultType; + // Comparisons and logical operators if (op == Operator.Greater || op == Operator.Lower || op == Operator.GreaterOrEqual || op == Operator.LowerOrEqual || op == Operator.NotEquals || op == Operator.Equals || op == Operator.LogicalAND || op == Operator.LogicalOR) resultType = resultType.WithElementType(ScalarType.Boolean); + return (operandType, resultType); + } + + public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, SpirvValue left, Operator op, SpirvValue right, TextLocation info, string? name = null) + { + var leftType = context.ReverseTypes[left.TypeId]; + var rightType = context.ReverseTypes[right.TypeId]; + + (var operandType, var resultType) = AnalyzeBinaryOperation(table, leftType, op, rightType, info) ?? throw new InvalidOperationException("Type of binary operation could not be determined"); + + // TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations) + // We'll need to review those cases + left = Convert(context, left, operandType); + right = Convert(context, right, operandType); + var resultTypeId = context.GetOrRegister(resultType); // Refresh types (after convert) leftType = context.ReverseTypes[left.TypeId]; rightType = context.ReverseTypes[right.TypeId]; - leftElementType = leftType.GetElementType(); - rightElementType = rightType.GetElementType(); + var leftElementType = leftType.GetElementType(); + var rightElementType = rightType.GetElementType(); var instruction = (op, leftElementType, rightElementType) switch { @@ -480,6 +492,15 @@ public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol f internal static class SymbolExtensions { + public static SymbolType GetValueType(this SymbolType type) + { + return type switch + { + PointerType pointerType => pointerType.BaseType, + _ => type + }; + } + public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) => size == 1 ? scalar : new VectorType(scalar, size); From 267da5f1436bdd55b58eee032bb9f9a17c73871e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 Jan 2026 14:23:22 +0900 Subject: [PATCH 0758/1182] Swizzle: fix type --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 3e79463702..df0eb6ce27 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -896,7 +896,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); - accessor.Type = s; + accessor.Type = s.GetVectorOrScalar(swizzle.Length); } else { From e95e71a7537b87ca9226989287e841d13632bb55 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 28 Jan 2026 20:21:29 +0900 Subject: [PATCH 0759/1182] Separate ProcessSymbol from Compile --- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 2 +- .../Examples.Spirv.cs | 2 +- src/Stride.Shaders/Core/Symbol.cs | 5 +- src/Stride.Shaders/Core/SymbolFrame.cs | 18 +- src/Stride.Shaders/Core/SymbolTypes.cs | 59 +- src/Stride.Shaders/Parsing/ASTNode.cs | 2 +- .../Parsing/Analysis/SymbolTable.cs | 22 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 11 +- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 650 ++++++------------ .../Parsing/SDSL/AST/Expression.cs | 556 ++++++++++----- .../Parsing/SDSL/AST/Literals.cs | 230 +++++-- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 34 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 355 +++++----- .../Parsing/SDSL/AST/ShaderElements.cs | 112 +-- .../Parsing/SDSL/AST/Statements.Control.cs | 24 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 53 +- .../Parsing/SDSL/AST/Statements.cs | 141 ++-- src/Stride.Shaders/Parsing/SDSLERR.cs | 5 + .../Spirv/Building/Builder.Class.cs | 8 +- .../Spirv/Building/Builder.Expressions.cs | 4 +- .../Spirv/Building/Builder.Functions.cs | 2 +- .../Spirv/Building/Context.Constants.cs | 54 +- .../Spirv/Building/ExpressionExtensions.cs | 1 + .../Spirv/Processing/InterfaceProcessor.cs | 18 +- 24 files changed, 1331 insertions(+), 1037 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 8fc410d140..4bebadc900 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -42,7 +42,7 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan 0) - throw new Exception("Some parse errors"); + throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, table.Errors)}"); lastBuffer = compiler.ToShaderBuffers(); ShaderLoader.FileCache.RegisterShader(shader.Name, macros, lastBuffer, hash); diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 76f27161fb..7117995fab 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -26,7 +26,7 @@ public static void GenerateSpirv() // context.AddGlobalVariable(new(new("color", SymbolKind.Variable, Storage.Stream), VectorType.From("float4"))); - var function = builder.DeclareFunction( + var function = SpirvBuilder.DeclareFunction( context, "add", new(ScalarType.Int, [new(ScalarType.Int, default), new(ScalarType.Int, default)]) diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 4d4056cf53..676d97afa8 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -51,7 +51,10 @@ public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId /// Defines a symbol. /// /// Only used for specific such as -public record struct Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, LoadedShaderSymbol? OwnerType = null); +public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, LoadedShaderSymbol? OwnerType = null) +{ + public int IdRef { get; set; } = IdRef; +} diff --git a/src/Stride.Shaders/Core/SymbolFrame.cs b/src/Stride.Shaders/Core/SymbolFrame.cs index 93790597c9..e05a214ecb 100644 --- a/src/Stride.Shaders/Core/SymbolFrame.cs +++ b/src/Stride.Shaders/Core/SymbolFrame.cs @@ -1,11 +1,13 @@ using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; using System.Collections.Immutable; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Xml.Linq; namespace Stride.Shaders.Core; -public class SymbolFrame(SpirvContext context) +public class SymbolFrame { readonly Dictionary symbols = []; @@ -23,8 +25,7 @@ public void Add(string name, Symbol symbol) if (existingSymbol.Type is FunctionType) existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup, IsStage: existingSymbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); - existingSymbol.GroupMembers = existingSymbol.GroupMembers.Add(symbol); - + existingSymbol = existingSymbol with { GroupMembers = existingSymbol.GroupMembers.Add(symbol) }; symbols[name] = existingSymbol; } else @@ -33,6 +34,15 @@ public void Add(string name, Symbol symbol) } } + public void UpdateId(string name, int id) + { + ref var symbol = ref CollectionsMarshal.GetValueRefOrNullRef(symbols, name); + if (Unsafe.IsNullRef(ref symbol)) + throw new InvalidOperationException(); + + symbol.IdRef = id; + } + public void Remove(string name) => symbols.Remove(name); public bool ContainsKey(string name) => symbols.ContainsKey(name); @@ -56,6 +66,6 @@ public bool TryGetValues(string name, List result) public Dictionary.Enumerator GetEnumerator() => symbols.GetEnumerator(); } -public sealed class RootSymbolFrame(SpirvContext context) : SymbolFrame(context) +public sealed class RootSymbolFrame() : SymbolFrame() { } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 37904403f9..eb628dab5d 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -49,22 +49,22 @@ public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolT return false; } } - public static bool TryGetBufferType(SymbolTable table, SpirvContext context, string name, TypeName? templateTypeName, [MaybeNullWhen(false)] out SymbolType result) + public static bool TryGetBufferType(string name, TypeName? templateTypeName, [MaybeNullWhen(false)] out SymbolType result) { // Special case: StructuredBuffer allows non vector/scalar types so treat it earlier switch (name) { case "StructuredBuffer": case "RWStructuredBuffer": - var templateType = templateTypeName.ResolveType(table, context); + var templateType = templateTypeName.Type; result = new StructuredBufferType(templateType, name.StartsWith("RW")); return true; } // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) - static ScalarType ResolveScalarType(SymbolTable table, SpirvContext context, TypeName? templateTypeName) + static ScalarType ResolveScalarType(TypeName? templateTypeName) { - var templateType = templateTypeName?.ResolveType(table, context) ?? ScalarType.Float; + var templateType = templateTypeName?.Type ?? ScalarType.Float; return templateType switch { @@ -75,27 +75,27 @@ static ScalarType ResolveScalarType(SymbolTable table, SpirvContext context, Typ SymbolType? foundType = name switch { - "Buffer" => new BufferType(ResolveScalarType(table, context, templateTypeName)), - "RWBuffer" => new BufferType(ResolveScalarType(table, context, templateTypeName), true), - - "Texture1D" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)), - "Texture2D" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)), - "Texture2DMS" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Multisampled = true }, - "Texture3D" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)), - "TextureCube" => new TextureCubeType(ResolveScalarType(table, context, templateTypeName)), + "Buffer" => new BufferType(ResolveScalarType(templateTypeName)), + "RWBuffer" => new BufferType(ResolveScalarType(templateTypeName), true), + + "Texture1D" => new Texture1DType(ResolveScalarType(templateTypeName)), + "Texture2D" => new Texture2DType(ResolveScalarType(templateTypeName)), + "Texture2DMS" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true }, + "Texture3D" => new Texture3DType(ResolveScalarType(templateTypeName)), + "TextureCube" => new TextureCubeType(ResolveScalarType(templateTypeName)), - "Texture1DArray" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, - "Texture2DArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, - "Texture2DMSArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Multisampled = true, Arrayed = true }, - "Texture3DArray" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, - "TextureCubeArray" => new TextureCubeType(ResolveScalarType(table, context, templateTypeName)) { Arrayed = true }, - - "RWTexture1D" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, - "RWTexture2D" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, - "RWTexture3D" => new Texture3DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2 }, - - "RWTexture1DArray" => new Texture1DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2, Arrayed = true }, - "RWTexture2DArray" => new Texture2DType(ResolveScalarType(table, context, templateTypeName)) { Sampled = 2, Arrayed = true }, + "Texture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, + "Texture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, + "Texture2DMSArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true, Arrayed = true }, + "Texture3DArray" => new Texture3DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, + "TextureCubeArray" => new TextureCubeType(ResolveScalarType(templateTypeName)) { Arrayed = true }, + + "RWTexture1D" => new Texture1DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, + "RWTexture2D" => new Texture2DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, + "RWTexture3D" => new Texture3DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, + + "RWTexture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, + "RWTexture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, _ => null, }; @@ -397,7 +397,7 @@ public sealed partial record LoadedShaderSymbol(string Name, int[] GenericArgume public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; public List InheritedShaders { get; init; } = []; - public static Symbol ImportSymbol(SymbolTable table, Symbol symbol) + public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbol symbol) { bool isCurrentShader = symbol.OwnerType == table.CurrentShader; @@ -413,8 +413,6 @@ public static Symbol ImportSymbol(SymbolTable table, Symbol symbol) if (symbol.OwnerType == null) throw new InvalidOperationException(); - var context = table.Context; - if (isCurrentShader && symbol.IdRef == 0) throw new InvalidOperationException("Symbols in current shader should be resolved"); @@ -573,7 +571,7 @@ private bool BuildMethodGroup(string name, ref Symbol symbol) var methodSymbol = c.Symbol; // If symbol is set, complete it as a method group - symbol = symbol.Type switch + symbol = symbol?.Type switch { // First time: just assign to symbol null => methodSymbol, @@ -595,6 +593,11 @@ private bool BuildMethodGroup(string name, ref Symbol symbol) public sealed partial record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; public sealed partial record StreamsType : SymbolType +{ + public override string ToString() => "Streams"; +} + +public sealed partial record ShaderMixinType : SymbolType { public override string ToString() => "Streams"; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/ASTNode.cs b/src/Stride.Shaders/Parsing/ASTNode.cs index 257c7ea631..caaf3dd7bf 100644 --- a/src/Stride.Shaders/Parsing/ASTNode.cs +++ b/src/Stride.Shaders/Parsing/ASTNode.cs @@ -16,7 +16,7 @@ public abstract class Node(TextLocation info) /// /// AST Node with a type /// -public class ValueNode(TextLocation info) : Node(info) +public abstract class ValueNode(TextLocation info) : Node(info) { public virtual SymbolType? Type { get; set; } = null; } diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index f42e263846..98dc665b67 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -7,7 +7,10 @@ namespace Stride.Shaders.Parsing.Analysis; -public record struct SemanticErrors(TextLocation Location, string Message); +public record struct SemanticError(TextLocation Location, string Message) +{ + override public string ToString() => $"{Location}: {Message}"; +} public partial class SymbolTable : ISymbolProvider { @@ -16,7 +19,7 @@ public partial class SymbolTable : ISymbolProvider public SpirvContext Context { get; init; } public RootSymbolFrame RootSymbols { get; } - public List Errors { get; } = []; + public List Errors { get; } = []; // Used by Identifier.ResolveSymbol public SymbolFrame CurrentFrame => CurrentSymbols[^1]; @@ -32,20 +35,20 @@ public partial class SymbolTable : ISymbolProvider public SymbolTable(SpirvContext context) { Context = context; - RootSymbols = new(context); + RootSymbols = new(); Push(RootSymbols); } - public void Push() => CurrentSymbols.Add(new(Context)); + public void Push() => CurrentSymbols.Add(new()); public void Push(SymbolFrame symbolFrame) => CurrentSymbols.Add(symbolFrame); public IExternalShaderLoader ShaderLoader { get; set; } - public SymbolFrame? Pop() + public SymbolFrame Pop() { - var scope = CurrentSymbols?[^1]; - CurrentSymbols?.RemoveAt(CurrentSymbols.Count - 1); + var scope = CurrentSymbols[^1]; + CurrentSymbols.RemoveAt(CurrentSymbols.Count - 1); return scope; } @@ -78,4 +81,9 @@ public Symbol ResolveSymbol(string name) throw new NotImplementedException($"Cannot find symbol {name} in main context (current shader is {CurrentShader?.Name}"); } + + public void AddError(SemanticError error) + { + Errors.Add(error); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 1f29af16ee..9e3e57aeff 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -26,12 +26,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); foreach (var statement in Members) - { statement.Compile(table, compiler); - } } - internal static int[] CompileGenerics(SymbolTable table, CompilerUnit compiler, ShaderExpressionList? generics) + internal static int[] CompileGenerics(SymbolTable table, SpirvContext context, ShaderExpressionList? generics) { var genericCount = generics != null ? generics.Values.Count : 0; var genericValues = new int[genericCount]; @@ -42,7 +40,8 @@ internal static int[] CompileGenerics(SymbolTable table, CompilerUnit compiler, { if (generic is not Literal literal) throw new InvalidOperationException($"Generic value {generic} is not a literal"); - var compiledValue = generic.CompileConstantValue(table, compiler.Context); + generic.ProcessSymbol(table); + var compiledValue = generic.CompileConstantValue(table, context); genericValues[genericIndex++] = compiledValue.Id; } } @@ -99,7 +98,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) if (mixinName.Path.Count > 0) throw new NotImplementedException(); - int[] genericValues = ShaderEffect.CompileGenerics(table, compiler, mixinName.Generics); + int[] genericValues = ShaderEffect.CompileGenerics(table, compiler.Context, mixinName.Generics); compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name, [.. genericValues])); } @@ -184,7 +183,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler, Identifie if (Mixin.Path.Count > 0) throw new NotImplementedException(); - var generics = ShaderEffect.CompileGenerics(table, compiler, Mixin.Generics); + var generics = ShaderEffect.CompileGenerics(table, context, Mixin.Generics); switch (@operator) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index 59613a0507..c4ad485ec2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -36,7 +36,12 @@ public static SymbolType FindCommonType(ScalarType baseType, params Span builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), @@ -228,22 +202,24 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class MaxCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("max", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + Type = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var xType = Parameters.Values[0].ValueType; - var yType = Parameters.Values[1].ValueType; - - var resultType = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); + x = builder.Convert(context, x, Type); + y = builder.Convert(context, y, Type); - x = builder.Convert(context, x, resultType); - y = builder.Convert(context, y, resultType); - - var instruction = resultType.GetElementType() switch + var instruction = Type.GetElementType() switch { ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), @@ -254,7 +230,17 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class ClampCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("clamp", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + protected ScalarType baseType; + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + var xType = Parameters.Values[0].ValueType; + var minValType = Parameters.Values[1].ValueType; + var maxValType = Parameters.Values[2].ValueType; + baseType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), minValType.GetElementType()), maxValType.GetElementType()); + Type = IntrinsicHelper.FindCommonType(baseType, xType, minValType, maxValType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (x, minVal, maxVal) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); @@ -266,12 +252,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var minValType = Parameters.Values[1].ValueType; var maxValType = Parameters.Values[2].ValueType; - var baseType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), minValType.GetElementType()), maxValType.GetElementType()); - var resultType = IntrinsicHelper.FindCommonType(baseType, xType, minValType, maxValType); - - x = builder.Convert(context, x, resultType); - minVal = builder.Convert(context, minVal, resultType); - maxVal = builder.Convert(context, maxVal, resultType); + x = builder.Convert(context, x, Type); + minVal = builder.Convert(context, minVal, Type); + maxVal = builder.Convert(context, maxVal, Type); var instruction = baseType switch { @@ -284,7 +267,12 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class SaturateCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("saturate", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = Parameters.Values[0].ValueType; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = (Parameters.Values[0].CompileAsValue(table, compiler)); @@ -311,247 +299,54 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class LerpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("lerp", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - // Ensure all vectors have the same size + ProcessParameterSymbols(table, null); var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; var aType = Parameters.Values[2].ValueType; - - var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType, aType); - - x = builder.Convert(context, x, resultType); - y = builder.Convert(context, y, resultType); - a = builder.Convert(context, a, resultType); - - var instruction = builder.Insert(new GLSLFMix(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); - return new(instruction.ResultId, instruction.ResultType); + Type = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType, aType); } -} -public class IMixCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("imix", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y, a) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLIMix(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); + + x = builder.Convert(context, x, Type); + y = builder.Convert(context, y, Type); + a = builder.Convert(context, a, Type); + + var instruction = builder.Insert(new GLSLFMix(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); return new(instruction.ResultId, instruction.ResultType); } } public class SmoothStepCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("smoothstep", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (edge0, edge1, x) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSmoothStep(edge0.TypeId, context.Bound++, context.GLSLSet ?? -1, edge0.Id, edge1.Id, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FmaCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("fma", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (a, b, c) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GLSLSet ?? -1, a.Id, b.Id, a.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FrexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexp", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (x, exp) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFrexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FrexpStructCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("frexpstruct", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var x = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLMatrixInverse(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class LdexpCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("ldexp", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (x, exp) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLLdexp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, exp.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class PackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm4x8", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackSnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class PackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm4x8", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackUnorm4x8(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class PackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packsnorm2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackSnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); + ProcessParameterSymbols(table, null); + Type = Parameters.Values[0].ValueType; } -} -public class PackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packunorm2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackUnorm2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class PackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packhalf2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class PackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("packdouble2x32", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPackDouble2x32(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UnpackSnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var p = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackSnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UnpackUnorm2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var p = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackUnorm2x16(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UnpackHalf2x16Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackhalf2x16", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var v = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackHalf2x16(v.TypeId, context.Bound++, context.GLSLSet ?? -1, v.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UnpackSnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpacksnorm4x8", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var p = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackSnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class UnpackUnorm4x8Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackunorm4x8", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var p = Parameters.Values[0].CompileAsValue(table, compiler); + var (edge0, edge1, x) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackUnorm4x8(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); + var instruction = builder.Insert(new GLSLSmoothStep(edge0.TypeId, context.Bound++, context.GLSLSet ?? -1, edge0.Id, edge1.Id, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } -public class UnpackDouble2x32Call(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("unpackdouble2x32", info), parameters, info) +public class LengthCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("length", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var p = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLUnpackDouble2x32(p.TypeId, context.Bound++, context.GLSLSet ?? -1, p.Id)); - return new(instruction.ResultId, instruction.ResultType); + ProcessParameterSymbols(table, null); + Type = ScalarType.Float; } -} -public class LengthCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("length", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); @@ -561,14 +356,18 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); x = builder.Convert(context, x, parameterType); - var resultType = ScalarType.Float; - var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id)); + var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } public class DistanceCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("distance", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = ScalarType.Float; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); @@ -576,25 +375,22 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; - var resultType = ScalarType.Float; - var inputType = IntrinsicHelper.FindCommonType(resultType, xType, yType); + var inputType = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); x = builder.Convert(context, x, inputType); y = builder.Convert(context, y, inputType); if (context.GLSLSet == null) context.ImportGLSL(); - var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(resultType), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); + var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); return new(instruction.ResultId, instruction.ResultType); } } public class DotCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("dot", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - + ProcessParameterSymbols(table, null); var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; @@ -604,15 +400,25 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (!xType.GetElementType().IsFloating()) throw new NotImplementedException("dot: only implemented for floating types"); - var resultType = xType.GetElementType(); - - var instruction = builder.Insert(new OpDot(context.GetOrRegister(resultType), context.Bound++, x.Id, y.Id)); + Type = xType.GetElementType(); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); + + var instruction = builder.Insert(new OpDot(context.GetOrRegister(Type), context.Bound++, x.Id, y.Id)); return new(instruction.ResultId, instruction.ResultType); } } public class NormalizeCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("normalize", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = Parameters.Values[0].ValueType; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); @@ -624,20 +430,22 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class FaceForwardCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("faceforward", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (n, i, ng) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); - + ProcessParameterSymbols(table, null); var nType = Parameters.Values[0].ValueType; var iType = Parameters.Values[1].ValueType; var ngType = Parameters.Values[2].ValueType; - - var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, nType, iType, ngType); - - n = builder.Convert(context, n, resultType); - i = builder.Convert(context, i, resultType); - ng = builder.Convert(context, ng, resultType); + Type = IntrinsicHelper.FindCommonType(ScalarType.Float, nType, iType, ngType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (n, i, ng) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); + + n = builder.Convert(context, n, Type); + i = builder.Convert(context, i, Type); + ng = builder.Convert(context, ng, Type); if (context.GLSLSet == null) context.ImportGLSL(); @@ -647,18 +455,20 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class ReflectCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("reflect", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (i, n) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - + ProcessParameterSymbols(table, null); var iType = Parameters.Values[0].ValueType; var nType = Parameters.Values[1].ValueType; + Type = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (i, n) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); - - i = builder.Convert(context, i, resultType); - n = builder.Convert(context, n, resultType); + i = builder.Convert(context, i, Type); + n = builder.Convert(context, n, Type); if (context.GLSLSet == null) context.ImportGLSL(); @@ -668,18 +478,20 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } public class RefractCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("refract", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + var iType = Parameters.Values[0].ValueType; + var nType = Parameters.Values[1].ValueType; + Type = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (i, n, eta) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler), Parameters.Values[2].CompileAsValue(table, compiler)); - var iType = Parameters.Values[0].ValueType; - var nType = Parameters.Values[1].ValueType; - - var resultType = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); - - i = builder.Convert(context, i, resultType); - n = builder.Convert(context, n, resultType); + i = builder.Convert(context, i, Type); + n = builder.Convert(context, n, Type); eta = builder.Convert(context, eta, ScalarType.Float); if (context.GLSLSet == null) @@ -688,81 +500,33 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return new(instruction.ResultId, instruction.ResultType); } } -public class FindILsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findilsb", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var value = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFindILsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FindSMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findsmsb", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var value = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFindSMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FindUMsbCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("findumsb", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var value = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFindUMsb(value.TypeId, context.Bound++, context.GLSLSet ?? -1, value.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class InterpolateAtCentroidCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatcentroid", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var interpolant = Parameters.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLInterpolateAtCentroid(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class InterpolateAtSampleCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatsample", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - var (builder, context) = compiler; - var (interpolant, sample) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLInterpolateAtSample(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, sample.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class InterpolateAtOffsetCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("interpolateatoffset", info), parameters, info) +public class MulCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - var (interpolant, offset) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLInterpolateAtOffset(interpolant.TypeId, context.Bound++, context.GLSLSet ?? -1, interpolant.Id, offset.Id)); - return new(instruction.ResultId, instruction.ResultType); + ProcessParameterSymbols(table, null); + var xType = Parameters.Values[0].ValueType; + var yType = Parameters.Values[1].ValueType; + + if (xType.GetElementType() != yType.GetElementType()) + throw new NotImplementedException("mul type conversion is currently not implemented"); + if (!xType.GetElementType().IsFloating()) + throw new NotImplementedException("Only implemented for floating types"); + + Type = (xType, yType) switch + { + (ScalarType type1, ScalarType type2) => type1, + (ScalarType type1, VectorType type2) => type2, + (ScalarType type1, MatrixType type2) => type2, + (VectorType type1, ScalarType type2) => type1, + (VectorType type1, VectorType type2) when type1.Size == type2.Size => type1, + (VectorType type1, MatrixType type2) when type1.Size == type2.Columns => new VectorType(type1.BaseType, type2.Rows), + (MatrixType type1, ScalarType type2) => type1, + (MatrixType type1, VectorType type2) when type1.Rows == type2.Size => new VectorType(type1.BaseType, type1.Columns), + (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => new MatrixType(type1.BaseType, type2.Rows, type1.Columns), + }; } -} -public class MulCall(ShaderExpressionList parameters, TextLocation info) : MethodCall(new("pow", info), parameters, info) -{ - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var (x, y) = (Parameters.Values[0].CompileAsValue(table, compiler), Parameters.Values[1].CompileAsValue(table, compiler)); @@ -772,12 +536,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var xType = Parameters.Values[0].ValueType; var yType = Parameters.Values[1].ValueType; - if (xType.GetElementType() != yType.GetElementType()) - throw new NotImplementedException("mul type conversion is currently not implemented"); - - if (!xType.GetElementType().IsFloating()) - throw new NotImplementedException("Only implemented for floating types"); - // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns and multiplication order need to be swapped var result = (xType, yType) switch @@ -799,7 +557,12 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, public class BoolToScalarBoolCall(ShaderExpressionList parameters, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = ScalarType.Boolean; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); @@ -807,7 +570,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Boolean); x = builder.Convert(context, x, parameterType); - var instruction = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.Boolean), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpAny(context.GetOrRegister(Type), context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } @@ -815,13 +578,16 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, public class FloatUnaryCall(ShaderExpressionList parameters, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); - - var parameterType = Parameters.Values[0].ValueType.WithElementType(ScalarType.Float); - x = builder.Convert(context, x, parameterType); + x = builder.Convert(context, x, Type); var instruction = builder.Insert(new OpFwidth(x.TypeId, context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; @@ -831,21 +597,29 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, public class BitcastCall(ShaderExpressionList parameters, TextLocation info, ScalarType expectedBaseType) : MethodCall(new("bitcast", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = Parameters.Values[0].ValueType.WithElementType(expectedBaseType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var x = Parameters.Values[0].CompileAsValue(table, compiler); - var resultType = Parameters.Values[0].ValueType.WithElementType(expectedBaseType); - - var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(resultType), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(Type), context.Bound++, x.Id)); return new(instruction.ResultId, instruction.ResultType); } } public class MemoryBarrierCall(ShaderExpressionList parameters, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = ScalarType.Void; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); @@ -855,7 +629,12 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, public class ControlBarrierCall(ShaderExpressionList parameters, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + Type = ScalarType.Void; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); @@ -878,7 +657,12 @@ public enum InterlockedOp public class InterlockedCall(ShaderExpressionList parameters, TextLocation info, InterlockedOp op) : MethodCall(new($"Interlocked{op}", info), parameters, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Type = ScalarType.Void; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var dest = Parameters.Values[0].Compile(table, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index df0eb6ce27..7bc5a67b17 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Diagnostics; using System.Text; using static Stride.Shaders.Spirv.Specification; @@ -19,12 +20,24 @@ namespace Stride.Shaders.Parsing.SDSL.AST; /// public abstract class Expression(TextLocation info) : ValueNode(info) { + /// + /// Compute and optionally emit diagnostics. + /// + /// + /// + public virtual void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); + public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { - var result = CompileImpl(table, compiler, expectedType); - // In case type is not computed yet, make sure it is using SpirvValue.TypeId - if (result.TypeId != 0) - Type ??= compiler.Context.ReverseTypes[result.TypeId]; + if (Type == null) + throw new InvalidOperationException($"{nameof(ProcessSymbol)} was not called on expression {this}"); + + var result = CompileImpl(table, compiler); + + // Check types are matching + if (result.TypeId != 0 && Type != compiler.Context.ReverseTypes[result.TypeId]) + throw new InvalidOperationException($"{nameof(ProcessSymbol)} computed type {Type} but {nameof(Compile)} created a value of type {compiler.Context.ReverseTypes[result.TypeId]} on expression {this}"); + return result; } @@ -41,15 +54,14 @@ protected void ThrowErrorOnLValue() throw new InvalidOperationException($"{this} is not a l-value and cannot be assigned to."); } - public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null); + public abstract SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler); - public SymbolType? ValueType { get => field ?? throw new InvalidOperationException($"Can't query {nameof(ValueType)} before calling {nameof(CompileAsValue)}"); private set; } + public SymbolType? ValueType => Type?.GetValueType(); public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { var result = Compile(table, compiler, expectedType); result = compiler.Builder.AsValue(compiler.Context, result); - ValueType = compiler.Context.ReverseTypes[result.TypeId]; return result; } } @@ -60,7 +72,8 @@ public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compile /// public class EmptyExpression(TextLocation info) : Expression(info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) => throw new NotImplementedException(); + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException(); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() => string.Empty; } @@ -68,17 +81,40 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo { public Identifier Name = name; public ShaderExpressionList Parameters = parameters; - - public LoadedShaderSymbol? MemberCallBaseType { get; set; } + + public SymbolType? MemberCallBaseType { get; set; } public SpirvValue? MemberCall { get; set; } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public Symbol ResolvedFunctionSymbol { get; set; } + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + if (!TryResolveFunctionSymbol(table, out var functionSymbol)) + return; + + var functionType = (FunctionType)functionSymbol.Type; + Type = functionType.ReturnType; + + ProcessParameterSymbols(table, functionType); + + ResolvedFunctionSymbol = functionSymbol; + } + + public void ProcessParameterSymbols(SymbolTable table, FunctionType? functionType) + { + for (var index = 0; index < Parameters.Values.Count; index++) + { + var parameter = Parameters.Values[index]; + var parameterExpectedType = functionType?.ParameterTypes[index].Type; + parameter.ProcessSymbol(table, parameterExpectedType); + } + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var functionSymbol = ResolveFunctionSymbol(table); - functionSymbol = LoadedShaderSymbol.ImportSymbol(table, functionSymbol); - + var functionSymbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedFunctionSymbol); var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; @@ -158,7 +194,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, } if (instance is int instanceId) - functionSymbol.IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId; + // Note: we make a copy to not mutate original + functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); @@ -183,14 +220,17 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, return result; } - private Symbol ResolveFunctionSymbol(SymbolTable table) + private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymbol) { - Symbol functionSymbol; // Note: for now, TypeId 0 is used for this/base; let's improve that later - if (MemberCall != null && MemberCall.Value.TypeId != 0) + if (MemberCallBaseType is LoadedShaderSymbol loadedShaderSymbol) { - if (!MemberCallBaseType.TryResolveSymbol(Name, out functionSymbol)) - throw new InvalidOperationException($"Method {Name} could not be found in type {MemberCallBaseType.Name}"); + if (!loadedShaderSymbol.TryResolveSymbol(Name, out functionSymbol)) + { + functionSymbol = default; + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0109, Name))); + return false; + } } else { @@ -210,7 +250,7 @@ private Symbol ResolveFunctionSymbol(SymbolTable table) functionSymbol = matchingMethods.First(); } - return functionSymbol; + return true; } public override string ToString() @@ -226,12 +266,14 @@ public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) { public Mixin Mixin { get; set; } = mixin; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public Symbol ResolvedSymbol { get; set; } + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; + var context = table.Context; // MixinAccess is same as Identifier static variable case, except we have generics (which is why MixinAccess was chosen over Identifier) - var generics = SDFX.AST.ShaderEffect.CompileGenerics(table, compiler, Mixin.Generics); + var generics = SDFX.AST.ShaderEffect.CompileGenerics(table, context, Mixin.Generics); var classSource = new ShaderClassInstantiation(Mixin.Name, generics); if (!table.TryResolveSymbol(classSource.ToClassNameWithGenerics(), out var symbol)) { @@ -253,8 +295,15 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); } + ResolvedSymbol = symbol; Type = symbol.Type; - return Identifier.EmitSymbol(builder, context, symbol, builder.CurrentFunction == null); + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + + return Identifier.EmitSymbol(builder, context, ResolvedSymbol, builder.CurrentFunction == null); } public override string ToString() { @@ -271,7 +320,25 @@ public abstract class UnaryExpression(Expression expression, Operator op, TextLo public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + switch (Operator) + { + case Operator.Inc: + case Operator.Dec: + case Operator.Not: + case Operator.Plus: + case Operator.Minus: + expression.ProcessSymbol(table, expectedType); + Type = expression.Type; + break; + default: + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0111, $"Prefix operator {Operator}"))); + break; + } + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; var expression = Expression.Compile(table, compiler); @@ -349,10 +416,18 @@ public class CastExpression(TypeName typeName, Operator op, Expression expressio { public TypeName TypeName { get; set; } = typeName; - public unsafe override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + TypeName.ProcessSymbol(table); + Expression.ProcessSymbol(table, expectedType); + Type = TypeName.Type; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var castType = TypeName.ResolveType(table, context); + TypeName.ProcessSymbol(table); + var castType = TypeName.Type; var value = Expression.CompileAsValue(table, compiler); Type = castType; @@ -366,10 +441,9 @@ public class IndexerExpression(Expression index, TextLocation info) : Expression { public Expression Index { get; set; } = index; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - throw new NotImplementedException(); - } + // Used only in AccessChainExpression + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException(); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() { return $"[{Index}]"; @@ -380,10 +454,9 @@ public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) - { - throw new NotImplementedException(); - } + // Used only in AccessChainExpression + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException(); + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() { return $"{Operator.ToSymbol()}"; @@ -402,7 +475,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal var (builder, context) = compiler; // Compute the l-value (and all its intermediate values) - CompileHelper(table, compiler, null); + CompileHelper(table, compiler); // Only things left should be: // - RWBuffer/Texture setters @@ -496,33 +569,56 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal ThrowErrorOnLValue(); } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - return CompileHelper(table, compiler, expectedType); + Source.ProcessSymbol(table); + var currentValueType = Source.Type; + + CompileHelper(table, null); } - public SpirvValue CompileHelper(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { - if (intermediateValues != null) - return intermediateValues[^1]; + return CompileHelper(table, compiler); + } - intermediateValues = new SpirvValue[Accessors.Count + 1]; - - var (builder, context) = compiler; - SpirvValue result; + // Since there are many switch case, we do both ProcessSymbols and Compile in the same functions to make sure to not miss anything (depending on if compiler is set) + public SpirvValue CompileHelper(SymbolTable table, CompilerUnit? compiler = null) + { + if (compiler != null) + { + if (intermediateValues != null) + return intermediateValues[^1]; + intermediateValues = new SpirvValue[Accessors.Count + 1]; + } + + var context = compiler?.Context; + var builder = compiler?.Builder; + SpirvValue result = default; - result = Source.Compile(table, compiler); + if (builder != null) + { + result = Source.Compile(table, compiler!); + intermediateValues[0] = result; + } + else + { + Source.ProcessSymbol(table); + } var currentValueType = Source.Type; - intermediateValues[0] = result; int accessChainIdCount = 0; void PushAccessChainId(Span accessChainIds, int accessChainIndex) { + if (compiler == null) + throw new InvalidOperationException(); accessChainIds[accessChainIdCount++] = accessChainIndex; } void EmitOpAccessChain(Span accessChainIds, int i) { + if (compiler == null) + throw new InvalidOperationException(); // Do we need to issue an OpAccessChain? if (accessChainIdCount > 0) { @@ -585,6 +681,15 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Some accessors push up to 2 values on the stack Span accessChainIds = stackalloc int[Accessors.Count * 2]; + VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) + { + return pointerType.BaseType switch + { + BufferType b => new VectorType(b.BaseType, 4), + TextureType t => new VectorType(t.ReturnType, 4), + }; + } + (SpirvValue Value, SymbolType ResultType) BufferLoad(BufferType bufferType, SpirvValue buffer, Expression locationExpression) { var resultType = new VectorType(bufferType.BaseType, 4); @@ -600,7 +705,6 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso (SpirvValue Value, SymbolType ResultType) TextureLoad(TextureType textureType, SpirvValue buffer, Expression coordinatesExpression, bool containsLod) { var resultType = new VectorType(textureType.ReturnType, 4); - var imageCoordValue = ConvertTexCoord(context, builder, textureType, coordinatesExpression.CompileAsValue(table, compiler), ScalarType.Int, containsLod); var imageCoordType = context.ReverseTypes[imageCoordValue.TypeId]; SpirvValue lod; @@ -633,23 +737,29 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { var accessor = Accessors[i]; - CoalesceSwizzles(i, currentValueType, ref accessor); - + if (compiler == null) + CoalesceSwizzles(i, currentValueType, ref accessor); + switch (currentValueType, accessor) { case (PointerType { BaseType: TextureType textureType }, MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } - or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } - or MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 }): + or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 }): { + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = new VectorType(textureType.ReturnType, 4); + break; + } + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); var textureValue = builder.AsValue(context, result); + var resultType = accessor.Type; if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } implicitSampling) { - var resultType = new VectorType(textureType.ReturnType, 4); - var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); @@ -673,8 +783,6 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } else if (accessor is MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } explicitSampling) { - var resultType = new VectorType(textureType.ReturnType, 4); - var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); @@ -705,48 +813,68 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; } - else if (accessor is MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 } sampleCompare) - { - var resultType = textureType.ReturnType; - if (resultType is not ScalarType) - throw new InvalidOperationException(); - - var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); - - var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); + else + throw new InvalidOperationException("Invalid Sample method call"); + break; + } + case (PointerType { BaseType: TextureType textureType }, + MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 } sampleCompare): + { + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = textureType.ReturnType; + if (accessor.Type is not ScalarType) + throw new InvalidOperationException(); + break; + } - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(resultType); + var resultType = textureType.ReturnType; + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + var textureValue = builder.AsValue(context, result); + + var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); + var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); + + var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); - ImageOperandsMask flags = sampleCompare.Name.Name is "SampleCmpLevelZero" ? ImageOperandsMask.Lod : ImageOperandsMask.None; - EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new (context.CompileConstant(0.0f).Id) : new (); - //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" - - if (sampleCompare.Parameters.Values.Count > 3) - { - var offset = ConvertOffset(context, builder, textureType, sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler)); - // TODO: determine when ConstOffset - flags |= ImageOperandsMask.Offset; - imParams = new EnumerantParameters([..imParams, offset.Id]); - //flags = new ParameterizedFlag(flags | ImageOperandsMask.Offset, new(..imParams.Span, offset.Id]); - } + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); + var returnType = context.GetOrRegister(resultType); - var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)); - result = new(sample.IdResult!.Value, sample.IdResultType!.Value); - accessor.Type = resultType; - } - else - throw new InvalidOperationException("Invalid Sample method call"); - break; + ImageOperandsMask flags = sampleCompare.Name.Name is "SampleCmpLevelZero" ? ImageOperandsMask.Lod : ImageOperandsMask.None; + EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new (context.CompileConstant(0.0f).Id) : new (); + //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" + + if (sampleCompare.Parameters.Values.Count > 3) + { + var offset = ConvertOffset(context, builder, textureType, sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler)); + // TODO: determine when ConstOffset + flags |= ImageOperandsMask.Offset; + imParams = new EnumerantParameters([..imParams, offset.Id]); + //flags = new ParameterizedFlag(flags | ImageOperandsMask.Offset, new(..imParams.Span, offset.Id]); } + + var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" + ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)) + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)); + + result = new(sample.IdResult!.Value, sample.IdResultType!.Value); + accessor.Type = resultType; + break; + } case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load): { + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = ComputeBufferOrTextureAccessReturnType(pointerType); + break; + } + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -759,6 +887,13 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): { + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = ComputeBufferOrTextureAccessReturnType(pointerType); + break; + } + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -771,55 +906,95 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } case (PointerType { BaseType: StructuredBufferType bufferType }, IndexerExpression indexer): { + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); + break; + } + // StructuredBuffer are declared as OpTypeStruct { OpTypeRuntimeArray } // so first, we push a 0 to access the OpTypeRuntimeArray PushAccessChainId(accessChainIds, context.CompileConstant(0).Id); // Then we push the index inside the array var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); - accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); break; } case (_, MethodCall methodCall): + if (compiler == null) + { + methodCall.MemberCallBaseType = ((PointerType)currentValueType).BaseType; + methodCall.ProcessSymbol(table); + break; + } + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - - methodCall.MemberCallBaseType = result.TypeId != 0 ? (LoadedShaderSymbol)((PointerType)currentValueType).BaseType : null; methodCall.MemberCall = result; result = methodCall.Compile(table, compiler); break; case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - - if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) - throw new InvalidOperationException(); + if (compiler == null) + { + if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0112, field.Name, new AccessorChainExpression(Source, info) { Accessors = Accessors[0..i] }, currentValueType))); + return default; + } - matchingComponent = LoadedShaderSymbol.ImportSymbol(table, matchingComponent); + field.ResolvedSymbol = matchingComponent; + accessor.Type = matchingComponent.Type; + break; + } + var importedVariable = LoadedShaderSymbol.ImportSymbol(table, context, field.ResolvedSymbol); + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(builder, context, matchingComponent, false, result.Id); - accessor.Type = matchingComponent.Type; + result = Identifier.EmitSymbol(builder, context, importedVariable, false, result.Id); break; case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): + if (compiler == null) + { + streamVar.AllowStreamVariables = true; + streamVar.ProcessSymbol(table); + accessor.Type = streamVar.Type; + break; + } + // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now\ - streamVar.AllowStreamVariables = true; var streamVariableResult = streamVar.Compile(table, compiler); PushAccessChainId(accessChainIds, streamVariableResult.Id); - accessor.Type = streamVar.Type; break; case (PointerType { BaseType: StructType s } p, Identifier field): var index = s.TryGetFieldIndex(field); - if (index == -1) - throw new InvalidOperationException($"field {accessor} not found in struct type {s}"); + if (compiler == null) + { + if (index == -1) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0113, field.Name, currentValueType))); + return default; + } + + accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); + break; + } //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); - accessor.Type = new PointerType(s.Members[index].Type, p.StorageClass); break; // Swizzles case (PointerType { BaseType: VectorType v } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { + if (compiler == null) + { + accessor.Type = new VectorType(v.BaseType, swizzle.Length); + break; + } + // Load value EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, []))); @@ -833,17 +1008,26 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); - - accessor.Type = new VectorType(v.BaseType, swizzle.Length); } else { + if (compiler == null) + { + accessor.Type = new PointerType(v.BaseType, p.StorageClass); + break; + } + PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); - accessor.Type = new PointerType(v.BaseType, p.StorageClass); } break; case (VectorType v, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): { + if (compiler == null) + { + accessor.Type = v.BaseType.GetVectorOrScalar(swizzle.Length); + break; + } + Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { @@ -853,13 +1037,18 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); - accessor.Type = v.BaseType.GetVectorOrScalar(swizzle.Length); break; } case (PointerType { BaseType: ScalarType s } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { + if (compiler == null) + { + accessor.Type = new VectorType(s, swizzle.Length); + break; + } + // Load value EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null, []))); @@ -873,20 +1062,29 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); - accessor.Type = new VectorType(s, swizzle.Length); } else { + // Do nothing + if (compiler == null) + { + accessor.Type = currentValueType; + break; + } + if (ConvertSwizzle(swizzle[0]) != 0) throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); - - // Do nothing - accessor.Type = currentValueType; } break; case (ScalarType s, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { + if (compiler == null) + { + accessor.Type = s.GetVectorOrScalar(swizzle.Length); + break; + } + Span swizzleIndices = stackalloc int[swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { @@ -896,12 +1094,15 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); - accessor.Type = s.GetVectorOrScalar(swizzle.Length); } else { // Do nothing - accessor.Type = currentValueType; + if (compiler == null) + { + accessor.Type = currentValueType; + break; + } } break; // Array indexer for shader compositions @@ -910,30 +1111,45 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Array indexer for arrays case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): { + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(t, p.StorageClass); + break; + } var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); - accessor.Type = new PointerType(t, p.StorageClass); break; } // Array indexer for vector/matrix case (PointerType { BaseType: VectorType or MatrixType } p, IndexerExpression indexer): { + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(p.BaseType switch + { + MatrixType m => new VectorType(m.BaseType, m.Rows), + VectorType v => v.BaseType, + }, p.StorageClass); + break; + } + var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); - - accessor.Type = new PointerType(p.BaseType switch - { - MatrixType m => new VectorType(m.BaseType, m.Rows), - VectorType v => v.BaseType, - }, p.StorageClass); break; } // For indexer accessor into non pointer types, we can't use OpCompositeExtract (it expects a constant) // So we load the value into a variable and use normal path case (ArrayType or VectorType or MatrixType, IndexerExpression indexer): { + if (compiler == null) + { + accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); + break; + } + // We need to load as a variable to use OpAccessChain - accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(accessor.Type), context.Bound++); builder.Insert(new OpStore(functionVariable, result.Id, null, [])); // Process again the same item with new type @@ -942,6 +1158,12 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { + if (compiler == null) + { + accessor.Type = type; + break; + } + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -969,11 +1191,12 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso currentValueType = accessor.Type; // only if OpAccessChain is emitted (otherwise there is no value) - if (accessChainIdCount == 0) + if (compiler != null && accessChainIdCount == 0) intermediateValues[1 + i] = result; } - EmitOpAccessChain(accessChainIds, Accessors.Count - 1); + if (compiler != null) + EmitOpAccessChain(accessChainIds, Accessors.Count - 1); Type = currentValueType; @@ -1044,7 +1267,9 @@ public class BinaryExpression(Expression left, Operator op, Expression right, Te public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + private SymbolType expectedOperandType; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { var expectedOperandType = Op switch { @@ -1053,6 +1278,24 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, _ => null, }; + Left.ProcessSymbol(table, expectedOperandType); + Right.ProcessSymbol(table, expectedOperandType); + + var analysisResult = SpirvBuilder.AnalyzeBinaryOperation(table, Left.ValueType, Op, Right.ValueType, info); + + // If type is different than expected, try again with proper type + // this will help in some cases (i.e. emit literal as float instead of integer, which is necessary for constants) + expectedOperandType = analysisResult?.OperandType; + if (Left.ValueType != expectedOperandType) + Left.ProcessSymbol(table, expectedOperandType); + if (Right.ValueType != expectedOperandType) + Right.ProcessSymbol(table, expectedOperandType); + + Type = analysisResult?.ResultType; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { var left = Left.CompileAsValue(table, compiler, expectedOperandType); var right = Right.CompileAsValue(table, compiler, expectedOperandType); @@ -1074,28 +1317,18 @@ public class TernaryExpression(Expression cond, Expression left, Expression righ public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - var (builder, context) = compiler; - - var conditionValue = Condition.CompileAsValue(table, compiler); - - var leftValueBuffer = new NewSpirvBuffer(); - var rightValueBuffer = new NewSpirvBuffer(); - - // We store left/right values in temporary buffer: we need to emit them now to know type but we don't want to actually insert them later in builder buffer - SpirvValue leftResult; - using (builder.UseTemporaryBuffer(leftValueBuffer)) - leftResult = Left.CompileAsValue(table, compiler); - SpirvValue rightResult; - using (builder.UseTemporaryBuffer(rightValueBuffer)) - rightResult = Right.CompileAsValue(table, compiler); - + Condition.ProcessSymbol(table); + if (Condition.ValueType.GetElementType() is not ScalarType { Type: Scalar.Boolean }) - table.Errors.Add(new(Condition.Info, SDSLErrorMessages.SDSL0106)); + table.AddError(new(Condition.Info, SDSLErrorMessages.SDSL0106)); + + Left.ProcessSymbol(table); + Right.ProcessSymbol(table); var scalarType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(Left.ValueType.GetElementType(), Right.ValueType.GetElementType()); - var resultType = (Condition.ValueType, Left.ValueType, Right.ValueType) switch + Type = (Condition.ValueType, Left.ValueType, Right.ValueType) switch { // If condition is a vector, we need to use this vector size instead (VectorType c, _, _) => new VectorType(scalarType, c.Size), @@ -1104,12 +1337,13 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, (ScalarType c, ScalarType s1, VectorType v2) => v2.WithElementType(scalarType), (ScalarType c, VectorType v1, VectorType v2) => new VectorType(scalarType, Math.Min(v1.Size, v2.Size)), }; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; - // Convert type for Left/Right - using (builder.UseTemporaryBuffer(leftValueBuffer)) - leftResult = builder.Convert(context, leftResult, resultType); - using (builder.UseTemporaryBuffer(rightValueBuffer)) - rightResult = builder.Convert(context, rightResult, resultType); + var conditionValue = Condition.CompileAsValue(table, compiler); // TODO: Review choice between if/else like branch (OpBranchConditional) which evaluate only one side, or select (OpSelect) which evaluate both side but can work per component but is limited to specific types // It seems HLSL 2021 changed the behavior to align it with C-style short-circuiting. @@ -1119,7 +1353,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, if (isBranching) { var resultVariable = context.Bound++; - builder.AddFunctionVariable(context.GetOrRegister(new PointerType(resultType, Specification.StorageClass.Function)), resultVariable); + builder.AddFunctionVariable(context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Function)), resultVariable); var blockMergeId = context.Bound++; var blockTrueId = context.Bound++; @@ -1131,31 +1365,35 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, // Block when choosing left value builder.CreateBlock(context, blockTrueId, $"ternary_true"); - builder.Merge(leftValueBuffer); + var leftResult = Left.CompileAsValue(table, compiler); + leftResult = builder.Convert(context, leftResult, Type); builder.Insert(new OpStore(resultVariable, leftResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); // Block when choosing right value builder.CreateBlock(context, blockFalseId, $"ternary_false"); - builder.Merge(rightValueBuffer); + var rightResult = Right.CompileAsValue(table, compiler); + rightResult = builder.Convert(context, rightResult, Type); builder.Insert(new OpStore(resultVariable, rightResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); builder.CreateBlock(context, blockMergeId, "ternary_merge"); - var result = builder.Insert(new OpLoad(context.GetOrRegister(resultType), context.Bound++, resultVariable, null, [])); + var result = builder.Insert(new OpLoad(context.GetOrRegister(Type), context.Bound++, resultVariable, null, [])); return new(result.ResultId, result.ResultType); } else { - if (resultType is VectorType v && Condition.ValueType is ScalarType conditionScalar) + if (Type is VectorType v && Condition.ValueType is ScalarType conditionScalar) { conditionValue = builder.Convert(context, conditionValue, new VectorType(conditionScalar, v.Size)); } - builder.Merge(leftValueBuffer); - builder.Merge(rightValueBuffer); + var leftResult = Left.CompileAsValue(table, compiler); + leftResult = builder.Convert(context, leftResult, Type); + var rightResult = Right.CompileAsValue(table, compiler); + rightResult = builder.Convert(context, rightResult, Type); - var result = builder.Insert(new OpSelect(context.GetOrRegister(resultType), context.Bound++, conditionValue.Id, leftResult.Id, rightResult.Id)); + var result = builder.Insert(new OpSelect(context.GetOrRegister(Type), context.Bound++, conditionValue.Id, leftResult.Id, rightResult.Id)); return new(result.ResultId, result.ResultType); } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index a0957ccc98..fc7b97da6d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Reflection; @@ -23,7 +24,13 @@ public class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + // Note: string doesn't have a real type + Type = null; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -69,15 +76,22 @@ public override string ToString() public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Type = expectedType is ScalarType { Type: Scalar.Float } + // If expectedType is float, handle it + ? ScalarType.Float + : SpirvContext.ComputeLiteralType(this); + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { // If expectedType is float, handle it: - if (expectedType is ScalarType { Type: Scalar.Float }) + if (Type is ScalarType { Type: Scalar.Float }) { - Type = expectedType; return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), value, null, info)); } - + return compiler.Context.CompileConstantLiteral(this); } } @@ -86,8 +100,13 @@ public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, Tex { public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Type = SpirvContext.ComputeLiteralType(this); + } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -103,8 +122,13 @@ public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.Boolean; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Type = ScalarType.Boolean; + } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } @@ -114,16 +138,20 @@ public class ExpressionLiteral(Expression value, TypeName typeName, TextLocation { public Expression Value { get; set; } = value; public TypeName TypeName { get; set; } = typeName; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + TypeName.ProcessSymbol(table); + Value.ProcessSymbol(table); + Type = TypeName.Type; + } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var castType = TypeName.ResolveType(table, context); var value = Value.CompileAsValue(table, compiler); - Type = castType; - - return builder.Convert(context, value, castType); + return builder.Convert(context, value, Type); } } @@ -139,16 +167,10 @@ public bool IsConstant() return true; } - public abstract SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType); - - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - Type = GenerateType(table, context, expectedType); - if (Type is ArrayType t2 && t2.Size == -1) - Type = new ArrayType(t2.BaseType, Values.Count); - (var compositeCount, var totalCount, var expectedElementType) = Type switch { VectorType v => (v.Size, v.Size, v.BaseType), @@ -217,7 +239,23 @@ public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLite { public TypeName TypeName { get; set; } = typeName; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) => TypeName.ResolveType(table, context); + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + TypeName.ProcessSymbol(table); + var elementType = TypeName.Type.GetElementType(); + + foreach (var value in Values) + { + value.ProcessSymbol(table); + if (value.Type is not PointerType && value.Type.GetElementType() != elementType) + { + var expectedTypeForItem = value.Type.WithElementType(elementType); + value.ProcessSymbol(table, expectedTypeForItem); + } + } + + Type = TypeName.Type; + } public override string ToString() { @@ -232,7 +270,24 @@ public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation i public int Rows { get; set; } = rows; public int Cols { get; set; } = cols; - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) => TypeName.ResolveType(table, context); + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + TypeName.ProcessSymbol(table); + var elementType = TypeName.Type.GetElementType(); + + foreach (var value in Values) + { + value.ProcessSymbol(table); + if (value.Type is not PointerType && value.ValueType.GetElementType() != elementType) + { + var expectedTypeForItem = value.Type.WithElementType(elementType); + value.ProcessSymbol(table, expectedTypeForItem); + } + } + + Type = TypeName.Type; + } public override string ToString() { @@ -242,13 +297,34 @@ public override string ToString() public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { - public override SymbolType GenerateType(SymbolTable table, SpirvContext context, SymbolType expectedType) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - // If we have any expected type (i.e. it's being assigned to a variable), use it - if (expectedType != null) - return expectedType; + Type = expectedType; + var expectedElementType = (expectedType as ArrayType)?.BaseType; + + foreach (var value in Values) + value.ProcessSymbol(table, expectedElementType); + + if (Type == null && Values.Count > 0) + Type = new ArrayType(Values[0].ValueType, Values.Count); + + if (Type != null) + { + if (Type is ArrayType arrayType && arrayType.Size == -1) + Type = new ArrayType(arrayType.BaseType, Values.Count); + } + else + { + table.AddError(new(info, "Can't figure out type of array")); + return; + } - throw new InvalidOperationException("Can't infer array type"); + var itemType = ((ArrayType)Type).BaseType; + foreach (var value in Values) + { + if (value.Type is not PointerType && value.Type != itemType) + value.ProcessSymbol(table, itemType); + } } public override string ToString() @@ -259,10 +335,55 @@ public class Identifier(string name, TextLocation info) : Literal(info) { internal bool AllowStreamVariables { get; set; } public string Name { get; set; } = name; + + public Symbol ResolvedSymbol { get; set; } public static implicit operator string(Identifier identifier) => identifier.Name; - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + if (Name == "this" || Name == "base") + Type = new PointerType(new ShaderMixinType(), Specification.StorageClass.Private); + else if (Name == "streams") + Type = new PointerType(new StreamsType(), Specification.StorageClass.Private); + else + { + if (!table.TryResolveSymbol(Name, out var symbol)) + { + var context = table.Context; + if (!table.ShaderLoader.Exists(Name)) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0110, Name))); + return; + } + + // Maybe it's a static variable? try to resolve by loading file + var classSource = new ShaderClassInstantiation(Name, []); + + // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) + var inheritedShaderCount = table.InheritedShaders.Count; + classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); + for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) + { + table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); + ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); + } + + // We add the typename as a symbol (similar to static access in C#) + var shaderId = context.GetOrRegister(classSource.Symbol); + symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); + table.CurrentFrame.Add(classSource.Symbol.Name, symbol); + } + + if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) + throw new InvalidOperationException($"Streams member {Name} used without an object"); + + ResolvedSymbol = symbol; + Type = symbol.Type; + } + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -288,37 +409,7 @@ private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvC return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(), Specification.StorageClass.Private))); } - if (!table.TryResolveSymbol(Name, out var symbol)) - { - if (constantOnly) - throw new NotImplementedException(); - - if (!table.ShaderLoader.Exists(Name)) - throw new InvalidOperationException($"Symbol [{Name}] could not be found."); - - // Maybe it's a static variable? try to resolve by loading file - var classSource = new ShaderClassInstantiation(Name, []); - - // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) - var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); - for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) - { - table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); - ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); - } - - // We add the typename as a symbol (similar to static access in C#) - var shaderId = context.GetOrRegister(classSource.Symbol); - symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); - table.CurrentFrame.Add(classSource.Symbol.Name, symbol); - } - - if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) - throw new InvalidOperationException($"Streams member {Name} used without an object"); - Type = symbol.Type; - - symbol = LoadedShaderSymbol.ImportSymbol(table, symbol); + var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); return EmitSymbol(builder, context, symbol, constantOnly); } @@ -435,7 +526,7 @@ public class TypeName(string name, TextLocation info) : Literal(info) public bool IsArray => ArraySize != null && ArraySize.Count > 0; public List? ArraySize { get; set; } public List Generics { get; set; } = []; - + public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWhen(false)] out SymbolType symbolType) { if (Name == "LinkType") @@ -461,7 +552,6 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh else { var fullTypeName = GenerateTypeName(includeGenerics: true, includeArray: false); - if (table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) { @@ -471,12 +561,12 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh table.DeclaredTypes.Add(fullTypeName, numeric); symbolType = numeric; } - else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(table, context, Name, null, out var bufferType)) + else if (!IsArray && Generics.Count == 0 && SymbolType.TryGetBufferType(Name, null, out var bufferType)) { table.DeclaredTypes.Add(fullTypeName, bufferType); symbolType = bufferType; } - else if (Generics.Count == 1 && SymbolType.TryGetBufferType(table, context, Name, Generics[0], out var genericBufferType)) + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0], out var genericBufferType)) { table.DeclaredTypes.Add(fullTypeName, genericBufferType); symbolType = genericBufferType; @@ -531,17 +621,27 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte return arraySymbolType; } - public SymbolType ResolveType(SymbolTable table, SpirvContext context) + protected SymbolType ResolveType(SymbolTable table, SpirvContext context) { if (!TryResolveType(table, context, out var result)) throw new InvalidOperationException($"Could not resolve type [{Name}]"); return result; } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) + // Used only indirectly + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - throw new NotImplementedException(); + if (ArraySize != null) + foreach (var arraySize in ArraySize) + if (arraySize is not EmptyExpression) + arraySize.ProcessSymbol(table); + foreach (var generic in Generics) + generic.ProcessSymbol(table); + + Type = ResolveType(table, table.Context); } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() => GenerateTypeName(includeGenerics: true, includeArray: true); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index b5d448b0f0..cf2fbff1be 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -394,7 +394,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp { table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); } - + public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -411,7 +411,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) for (int i = 0; i < Generics.Parameters.Count; i++) { var genericParameter = Generics.Parameters[i]; - var genericParameterType = genericParameter.TypeName.ResolveType(table, context); + genericParameter.TypeName.ProcessSymbol(table); + var genericParameterType = genericParameter.TypeName.Type; table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); @@ -444,6 +445,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { if (table.TryResolveSymbol(identifier.Name, out var symbol)) { + mixin.Generics.Values[i].ProcessSymbol(table); generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; } else @@ -457,6 +459,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } else { + mixin.Generics.Values[i].ProcessSymbol(table); generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; } } @@ -482,31 +485,38 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } // Process symbols and generate types - foreach (var member in Elements) - { + foreach (var member in Elements.OfType()) + member.ProcessSymbol(table, context); + foreach (var member in Elements.OfType()) member.ProcessSymbol(table, context); + foreach (var member in Elements.OfType()) + member.ProcessSymbol(table, context); + foreach (var member in Elements.OfType()) + member.ProcessSymbol(table, context); + // In case a method is calling another method not yet processed, we first declare all methods, then analysis of method body + // (SPIR-V allow forward calling) + foreach (var method in Elements.OfType()) + method.ProcessSymbol(table, context); + if (!hasUnresolvableGenerics) + { + foreach (var member in Elements.OfType()) + member.ProcessSymbolBody(table, context); } RenameCBufferVariables(); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); - foreach (var member in Elements.OfType()) - member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) { if (member.TypeModifier == TypeModifier.Const) continue; member.Compile(table, this, compiler); } + foreach (var member in Elements.OfType()) + member.Compile(table, this, compiler); foreach (var member in Elements.OfType()) member.Compile(table, this, compiler); - - // In case a moethod calling another method not yet processed, we first declare all methods - // (SPIR-V allow forward calling) - foreach (var method in Elements.OfType()) - method.Declare(table, this, compiler); - foreach (var method in Elements.OfType()) method.Compile(table, this, compiler, hasUnresolvableGenerics); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b866cd0574..c949faa179 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -36,99 +36,100 @@ public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMe { public Identifier Name { get; set; } = name; public List Parameters { get; set; } = []; + + public Symbol Symbol { get; private set; } public override void ProcessSymbol(SymbolTable table, SpirvContext context) { base.ProcessSymbol(table, context); - Type = new SamplerType(); + Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); table.DeclaredTypes.TryAdd(Type.ToString(), Type); + + var sid = new SymbolID(Name, SymbolKind.SamplerState); + Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); + table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) { (var builder, var context) = compiler; - Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); var registeredType = context.GetOrRegister(Type); - if (!table.RootSymbols.TryGetValue(Name, out _)) - { - var variableId = context.Bound++; + if (table.RootSymbols.TryGetValue(Name, out _)) + throw new Exception($"SamplerState {Name} already defined"); + + var variableId = context.Bound++; - // We store SamplerState as decoration for later processing during ShaderMixer.ProcessReflection() - // Note: we make sure to do it before the OpVariableSDSL as per SPIR-V spec so that it is correctly processed later - foreach (var parameter in Parameters) + // We store SamplerState as decoration for later processing during ShaderMixer.ProcessReflection() + // Note: we make sure to do it before the OpVariableSDSL as per SPIR-V spec so that it is correctly processed later + foreach (var parameter in Parameters) + { + switch (parameter.Name) { - switch (parameter.Name) - { - case "Filter": - { - var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateFilter, [(int)filter])); - break; - } - case "AddressU": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressU, [(int)addressMode])); - break; - } - case "AddressV": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressV, [(int)addressMode])); - break; - } - case "AddressW": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressW, [(int)addressMode])); - break; - } - case "MipLODBias": - { - var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMipLODBias, mipLODBias.ToString())); - break; - } - case "MaxAnisotropy": - { - var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateMaxAnisotropy, [maxAnisotropy])); - break; - } - case "MinLOD": - { - var minLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMinLOD, minLOD.ToString())); - break; - } - case "MaxLOD": - { - var maxLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMaxLOD, maxLOD.ToString())); - break; - } - case "ComparisonFunc": - { - var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateComparisonFunc, [(int)filter])); - break; - } - case "BorderColor": - default: - throw new NotImplementedException(); - } + case "Filter": + { + var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateFilter, [(int)filter])); + break; + } + case "AddressU": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressU, [(int)addressMode])); + break; + } + case "AddressV": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressV, [(int)addressMode])); + break; + } + case "AddressW": + { + var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressW, [(int)addressMode])); + break; + } + case "MipLODBias": + { + var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMipLODBias, mipLODBias.ToString())); + break; + } + case "MaxAnisotropy": + { + var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateMaxAnisotropy, [maxAnisotropy])); + break; + } + case "MinLOD": + { + var minLOD = (float)((FloatLiteral)parameter.Value).Value; + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMinLOD, minLOD.ToString())); + break; + } + case "MaxLOD": + { + var maxLOD = (float)((FloatLiteral)parameter.Value).Value; + context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMaxLOD, maxLOD.ToString())); + break; + } + case "ComparisonFunc": + { + var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateComparisonFunc, [(int)filter])); + break; + } + case "BorderColor": + default: + throw new NotImplementedException(); } - - var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); - context.AddName(variable.ResultId, Name); - - RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); - - var sid = new SymbolID(Name, SymbolKind.SamplerState); - var symbol = new Symbol(sid, Type, variable.ResultId, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } - else throw new Exception($"SamplerState {Name} already defined"); + + var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + context.AddName(variable.ResultId, Name); + Symbol.IdRef = variableId; + + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } public override string ToString() @@ -177,9 +178,13 @@ public sealed class ShaderMember( public StorageClass StorageClass { get; set; } = storageClass; public InterpolationModifier Interpolation { get; set; } = interpolation; + public Symbol Symbol { get; private set; } + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { base.ProcessSymbol(table, context); + foreach (var generic in TypeName.Generics) + generic.ProcessSymbol(table); if (!TypeName.TryResolveType(table, context, out var memberType)) { if (TypeName.Name.Contains("<")) @@ -189,8 +194,9 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) classSource.Buffer = shader; var shaderType = ShaderClass.LoadAndCacheExternalShaderType(table, context, classSource); - // Resolve again (we don't use shaderType direclty, because it might lack info such as ArrayType) - memberType = TypeName.ResolveType(table, context); + // Resolve again (we don't use shaderType directly, because it might lack info such as ArrayType) + TypeName.ProcessSymbol(table); + memberType = TypeName.Type; } var storageClass = (memberType, StorageClass, StreamKind) switch @@ -211,8 +217,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) // Constant: compile right away var constantValue = Value.CompileConstantValue(table, context, memberType); context.SetName(constantValue.Id, Name); - var symbol = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id, OwnerType: table.CurrentShader); - table.CurrentFrame.Add(Name, symbol); + var constant = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id, OwnerType: table.CurrentShader); + table.CurrentFrame.Add(Name, constant); Type = memberType; // This constant is visible when inherited @@ -223,6 +229,21 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) Type = new PointerType(memberType, storageClass); table.DeclaredTypes.TryAdd(Type.ToString(), Type); } + + var sid = + new SymbolID + ( + Name, + TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, + StreamKind switch + { + StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, + _ => Storage.None + }, + IsStage: IsStaged + ); + Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); + table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -262,6 +283,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Semantic != null) context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); + + Symbol.IdRef = variable; if (pointerType.BaseType is StructuredBufferType) { @@ -269,21 +292,6 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler } RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); - - var sid = - new SymbolID - ( - Name, - TypeModifier == TypeModifier.Const ? SymbolKind.Constant : SymbolKind.Variable, - StreamKind switch - { - StreamKind.Stream or StreamKind.PatchStream => Storage.Stream, - _ => Storage.None - }, - IsStage: IsStaged - ); - var symbol = new Symbol(sid, pointerType, variable, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } public override string ToString() @@ -352,27 +360,14 @@ public class ShaderMethod( public BlockStatement? Body { get; set; } + public SymbolFrame SymbolFrame { get; private set; } + public List ParameterSymbols { get; private set; } = new(); + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { - base.ProcessSymbol(table, context); - var ftype = new FunctionType(ReturnTypeName.ResolveType(table, context), []); - foreach (var arg in Parameters) - { - var argSym = arg.TypeName.ResolveType(table, context); - table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = argSym; - ftype.ParameterTypes.Add(new(new PointerType(arg.Type, Specification.StorageClass.Function), arg.Modifiers)); - } - Type = ftype; - - table.DeclaredTypes.TryAdd(Type.ToString(), Type); - } - - public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler) - { - var (builder, context) = compiler; - - function = builder.DeclareFunction(context, Name, (FunctionType)Type, IsStaged); + ReturnTypeName.ProcessSymbol(table); + var ftype = new FunctionType(ReturnTypeName.Type, []); + function = SpirvBuilder.DeclareFunction(context, Name, ftype, IsStaged); var functionFlags = Specification.FunctionFlagsMask.None; if (IsAbstract) @@ -384,6 +379,21 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; + table.Push(); + ParameterSymbols.Clear(); + foreach (var p in Parameters) + { + p.TypeName.ProcessSymbol(table); + var argSym = p.TypeName.Type; + table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); + p.Type = argSym; + var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); + ftype.ParameterTypes.Add(new(parameterType, p.Modifiers)); + var parameterSymbol = new Symbol(new(p.Name, SymbolKind.Variable), parameterType, 0, OwnerType: table.CurrentShader); + table.CurrentFrame.Add(p.Name, parameterSymbol); + ParameterSymbols.Add(parameterSymbol); + } + Span defaultParameters = stackalloc int[Parameters.Count]; var firstDefaultParameter = -1; for (var index = 0; index < Parameters.Count; index++) @@ -399,18 +409,32 @@ public void Declare(SymbolTable table, ShaderClass shader, CompilerUnit compiler } } - var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), Type, function.Id, MemberAccessWithImplicitThis: Type, OwnerType: table.CurrentShader); + var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), ftype, function.Id, MemberAccessWithImplicitThis: ftype, OwnerType: table.CurrentShader); if (firstDefaultParameter != -1) { context.Add(new OpDecorate(function.Id, Specification.Decoration.FunctionParameterDefaultValueSDSL, [.. defaultParameters[firstDefaultParameter..]])); - symbol.MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()); + symbol = symbol with + { + MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()), + }; } - + + Type = ftype; + table.DeclaredTypes.TryAdd(Type.ToString(), Type); + + SymbolFrame = table.Pop(); table.CurrentShader.Methods.Add((symbol, functionFlags)); } + public void ProcessSymbolBody(SymbolTable table, SpirvContext context) + { + table.Push(SymbolFrame); + Body?.ProcessSymbol(table); + table.Pop(); + } + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler, bool hasUnresolvableGenerics) { var (builder, context) = compiler; @@ -436,69 +460,56 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler } } - table.Push(); - Span defaultParameters = stackalloc int[Parameters.Count]; - var firstDefaultParameter = -1; - for (var index = 0; index < Parameters.Count; index++) - { - var arg = Parameters[index]; - var argSym = arg.TypeName.ResolveType(table, context); - table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); - arg.Type = argSym; - } - - if (Type is FunctionType ftype) - { - builder.BeginFunction(context, function); + if (Type is not FunctionType ftype) + throw new InvalidOperationException(); - var functionInfo = new OpSDSLFunctionInfo(Specification.FunctionFlagsMask.None, 0); + table.Push(SymbolFrame); + builder.BeginFunction(context, function); - if (IsOverride == true) - { - // Find parent function - var parentSymbol = table.ResolveSymbol(function.Name); - // If multiple symbol with same name, find the proper overload (it should have the exact same signature) - if (parentSymbol.Type is FunctionGroupType) - parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); + var functionInfo = new OpSDSLFunctionInfo(Specification.FunctionFlagsMask.None, 0); - parentSymbol = LoadedShaderSymbol.ImportSymbol(table, parentSymbol); + if (IsOverride) + { + // Find parent function + var parentSymbol = table.ResolveSymbol(function.Name); + // If multiple symbol with same name, find the proper overload (it should have the exact same signature) + if (parentSymbol.Type is FunctionGroupType) + parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); - functionInfo.Parent = parentSymbol.IdRef; - functionInfo.Flags |= Specification.FunctionFlagsMask.Override; - } + parentSymbol = LoadedShaderSymbol.ImportSymbol(table, context, parentSymbol); - if (IsAbstract == true) - functionInfo.Flags |= Specification.FunctionFlagsMask.Abstract; - if (IsVirtual == true) - functionInfo.Flags |= Specification.FunctionFlagsMask.Virtual; - if (IsStaged) - functionInfo.Flags |= Specification.FunctionFlagsMask.Stage; + functionInfo.Parent = parentSymbol.IdRef; + functionInfo.Flags |= Specification.FunctionFlagsMask.Override; + } - builder.Insert(functionInfo); + if (IsAbstract == true) + functionInfo.Flags |= Specification.FunctionFlagsMask.Abstract; + if (IsVirtual == true) + functionInfo.Flags |= Specification.FunctionFlagsMask.Virtual; + if (IsStaged) + functionInfo.Flags |= Specification.FunctionFlagsMask.Stage; - foreach (var p in Parameters) - { - var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); - var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); - table.CurrentFrame.Add(p.Name, new(new(p.Name, SymbolKind.Variable), parameterType, paramValue.Id, OwnerType: table.CurrentShader)); - } + builder.Insert(functionInfo); - if (Body is BlockStatement body && !hasUnresolvableGenerics) - { - table.Push(); - builder.CreateBlock(context); - foreach (var s in body) - s.Compile(table, compiler); - table.Pop(); - } - else - { - builder.Insert(new OpUnreachable()); - } - builder.EndFunction(); + for (var index = 0; index < Parameters.Count; index++) + { + var p = Parameters[index]; + var parameterSymbol = ParameterSymbols[index]; + var parameterType = parameterSymbol.Type; + var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); + parameterSymbol.IdRef = paramValue.Id; } - else throw new NotImplementedException(); + if (Body is BlockStatement body && !hasUnresolvableGenerics) + { + builder.CreateBlock(context); + Body.Compile(table, compiler); + } + else + { + builder.Insert(new OpUnreachable()); + } + builder.EndFunction(); table.Pop(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index b98b0826fc..ec0bbe0df6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -175,7 +175,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var fields = new List(); foreach (var smem in Members) { - smem.Type = smem.TypeName.ResolveType(table, context); + smem.TypeName.ProcessSymbol(table); + smem.Type = smem.TypeName.Type; table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); @@ -225,7 +226,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var fields = new List(); foreach (var smem in Members) { - smem.Type = smem.TypeName.ResolveType(table, context); + smem.TypeName.ProcessSymbol(table); + smem.Type = smem.TypeName.Type; table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); @@ -251,7 +253,10 @@ public override string ToString() public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { - public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable table, TextLocation info, List attributes) + public Symbol Symbol { get; private set; } + private bool? isStaged; + + public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable table, SpirvContext context, TextLocation info, List attributes) { if (attributes != null) { @@ -264,9 +269,9 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable // Try to resolve generic parameter when encoded as string (deprecated) if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) { - linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, linkLiteralSymbol); + linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); // TODO: make it a warning only? - //table.Errors.Add(new(info, "LinkType generics should be passed without quotes")); + //table.AddError(new(info, "LinkType generics should be passed without quotes")); return (null, linkLiteralSymbol.IdRef); } @@ -278,7 +283,7 @@ public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable { throw new InvalidOperationException(); } - linkSymbol = LoadedShaderSymbol.ImportSymbol(table, linkSymbol); + linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); return (null, linkSymbol.IdRef); } else @@ -296,13 +301,26 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) { base.ProcessSymbol(table, context); foreach (var cbMember in Members) - cbMember.Type = cbMember.TypeName.ResolveType(table, context); - } + { + cbMember.TypeName.ProcessSymbol(table); + cbMember.Type = cbMember.TypeName.Type; + } - public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) - { - var (builder, context) = compiler; + var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); + + isStaged = null; + for (var index = 0; index < Members.Count; index++) + { + var member = Members[index]; + // Use first member as reference + if (isStaged == null) + isStaged = member.IsStaged; + // Make sure IsStaged for all members match the first member (they're all the same) + if (isStaged != member.IsStaged) + throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); + } + var constantBufferType = (ConstantBufferSymbol)Type; // We try to avoid clash in case multiple cbuffer TYPE with same name @@ -312,34 +330,32 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile while (!table.DeclaredTypes.TryAdd(constantBufferType.ToId(), Type)) { typeName = $"{typeName}_{++tryCount}"; - constantBufferType = constantBufferType with { Name = typeName }; + Type = constantBufferType = constantBufferType with { Name = typeName }; } - Type = constantBufferType; context.DeclareCBuffer(constantBufferType); - var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); - var variable = context.Bound++; + + var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); + Symbol = new Symbol(sid, pointerType, context.Bound++, OwnerType: table.CurrentShader); + table.CurrentShader.Variables.Add((Symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + } + + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + var (builder, context) = compiler; + var variable = Symbol.IdRef; context.AddName(variable, Name); if (LogicalGroup != null) context.Add(new OpDecorateString(variable, Specification.Decoration.LogicalGroupSDSL, LogicalGroup)); - bool? isStaged = null; - for (var index = 0; index < Members.Count; index++) { var member = Members[index]; - // Use first member as reference - if (isStaged == null) - isStaged = member.IsStaged; - // Make sure IsStaged for all members match the first member (they're all the same) - if (isStaged != member.IsStaged) - throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); - if (member.Attributes != null && member.Attributes.Count > 0) { - var linkInfo = ProcessLinkAttributes(table, Info, member.Attributes); + var linkInfo = ProcessLinkAttributes(table, context, Info, member.Attributes); if (linkInfo.LinkId is int linkId) context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, Specification.Decoration.LinkIdSDSL, [linkId])); else if (linkInfo.LinkName != null) @@ -347,26 +363,22 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } } - builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, isStaged == true ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); - - var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); - var symbol = new Symbol(sid, pointerType, variable, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); + builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); } } public sealed class RGroup(string name, TextLocation info) : ShaderBuffer(name, info) { - public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + public List Symbols { get; } = new(); + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { - var (builder, context) = compiler; - - var resourceGroupId = context.ResourceGroupBound++; + base.ProcessSymbol(table, context); + Symbols.Clear(); for (var index = 0; index < Members.Count; index++) { var member = Members[index]; - (var storageClass, var kind) = member.Type switch { TextureType => (Specification.StorageClass.UniformConstant, SymbolKind.Variable), @@ -374,10 +386,30 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile BufferType => (Specification.StorageClass.UniformConstant, SymbolKind.TBuffer), _ => throw new NotImplementedException(), }; - + var type = new PointerType(member.Type, storageClass); + var sid = new SymbolID(member.Name, kind, Storage.Uniform); + var symbol = new Symbol(sid, type, 0, OwnerType: table.CurrentShader); + table.CurrentShader.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + Symbols.Add(symbol); + } + } + + public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) + { + var (builder, context) = compiler; + + var resourceGroupId = context.ResourceGroupBound++; + + for (var index = 0; index < Members.Count; index++) + { + var member = Members[index]; + var symbol = Symbols[index]; + + var type = (PointerType)symbol.Type; var typeId = context.GetOrRegister(type); - var variable = builder.Insert(new OpVariableSDSL(typeId, context.Bound++, storageClass, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + var variable = builder.Insert(new OpVariableSDSL(typeId, context.Bound++, type.StorageClass, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); + symbol.IdRef = variable; context.AddName(variable.ResultId, member.Name); DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); @@ -388,16 +420,12 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.ResourceGroupIdSDSL, [resourceGroupId])); if (LogicalGroup != null) context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.LogicalGroupSDSL, LogicalGroup)); - - var sid = new SymbolID(member.Name, kind, Storage.Uniform); - var symbol = new Symbol(sid, type, variable.ResultId, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } } internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass shaderClass, SpirvContext context, TextLocation info, string memberName, List attributes, int variableId) { - var linkInfo = CBuffer.ProcessLinkAttributes(table, info, attributes); + var linkInfo = CBuffer.ProcessLinkAttributes(table, context, info, attributes); if (linkInfo.LinkId is int linkId) context.Add(new OpDecorate(variableId, Specification.Decoration.LinkIdSDSL, [linkId])); else if (linkInfo.LinkName != null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 87c8d13507..5040131a5b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -17,6 +17,14 @@ public class ConditionalFlow(If first, TextLocation info) : Flow(info) public List ElseIfs { get; set; } = []; public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } + + public override void ProcessSymbol(SymbolTable table) + { + If.ProcessSymbol(table); + foreach (var elseIf in ElseIfs) + elseIf.ProcessSymbol(table); + Else?.ProcessSymbol(table); + } public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) { @@ -36,7 +44,7 @@ public override unsafe void Compile(SymbolTable table, CompilerUnit compiler) var conditionValue = currentIf.Condition.CompileAsValue(table, compiler); if (currentIf.Condition.ValueType is not ScalarType) - table.Errors.Add(new(currentIf.Condition.Info, "if statement conditional expressions must evaluate to a scalar")); + table.AddError(new(currentIf.Condition.Info, "if statement conditional expressions must evaluate to a scalar")); // Might need implicit conversion from float/int to bool conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); @@ -99,6 +107,12 @@ public class If(Expression condition, Statement body, TextLocation info) : Flow( public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; + public override void ProcessSymbol(SymbolTable table) + { + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table); + } + public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new InvalidOperationException("Handled by ConditionalFlow"); @@ -112,10 +126,6 @@ public override string ToString() public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new InvalidOperationException("Handled by ConditionalFlow"); - } public override string ToString() { return $"else if({Condition}){Body}"; @@ -126,6 +136,10 @@ public class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; + public override void ProcessSymbol(SymbolTable table) + { + Body.ProcessSymbol(table); + } public override void Compile(SymbolTable table, CompilerUnit compiler) { Body.Compile(table, compiler); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 12279dc1e6..2042e8ca8f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -11,6 +11,9 @@ public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); public class Break(TextLocation info) : Statement(info) { + public override void ProcessSymbol(SymbolTable table) + { + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -23,6 +26,9 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } public class Discard(TextLocation info) : Statement(info) { + public override void ProcessSymbol(SymbolTable table) + { + } public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); @@ -30,6 +36,9 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } public class Continue(TextLocation info) : Statement(info) { + public override void ProcessSymbol(SymbolTable table) + { + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -49,7 +58,33 @@ public class ForEach(TypeName typename, Identifier variable, Expression collecti public Expression Collection { get; set; } = collection; public Statement Body { get; set; } = body; + public SymbolFrame SymbolFrame { get; set; } + + public override void ProcessSymbol(SymbolTable table) + { + Collection.ProcessSymbol(table); + if (!(Collection.Type is PointerType p && p.BaseType is ArrayType arrayType)) + throw new InvalidOperationException("foreach: Array type is expected"); + + var variableType = new PointerType(arrayType.BaseType, Specification.StorageClass.Function); + Variable.Type = variableType; + + if (TypeName.Name != "var") + TypeName.ProcessSymbol(table, variableType); + else + TypeName.Type = arrayType.BaseType; + + // TODO: check conversions + if (variableType.BaseType != TypeName.Type) + throw new InvalidOperationException("foreach: collection and variable type not matching"); + + table.Push(); + var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), Variable.Type, 0, OwnerType: table.CurrentShader); + table.CurrentFrame.Add(Variable.Name, variableSymbol); + Body.ProcessSymbol(table); + SymbolFrame = table.Pop(); + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -63,9 +98,8 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) // Since foreach need to be processed and expanded later, we use custom opcode // (we could emit a "For" loop statement, but it would be too complex to write a general decompiler for a "for" loop when processing it later) var variableId = builder.Insert(new OpForeachSDSL(context.GetOrRegister(variableType), context.Bound++, collection.Id)); - table.Push(); - var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), variableType, variableId, OwnerType: table.CurrentShader); - table.CurrentFrame.Add(Variable.Name, variableSymbol); + table.Push(SymbolFrame); + SymbolFrame.UpdateId(Variable.Name, variableId); Body.Compile(table, compiler); table.Pop(); builder.Insert(new OpForeachEndSDSL()); @@ -90,7 +124,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var conditionValue = Condition.CompileAsValue(table, compiler); if (Condition.ValueType is not ScalarType) - table.Errors.Add(new(Condition.Info, "while statement condition expression must evaluate to a scalar")); + table.AddError(new(Condition.Info, "while statement condition expression must evaluate to a scalar")); // Might need implicit conversion from float/int to bool conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); @@ -123,6 +157,15 @@ public class For(Statement initializer, Expression cond, List update, public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + Initializer.ProcessSymbol(table); + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table); + foreach (var update in Update) + update.ProcessSymbol(table); + } + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -143,7 +186,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var conditionValue = Condition.CompileAsValue(table, compiler); if (Condition.ValueType is not ScalarType) - table.Errors.Add(new(Condition.Info, "for statement condition expression must evaluate to a scalar")); + table.AddError(new(Condition.Info, "for statement condition expression must evaluate to a scalar")); // Might need implicit conversion from float/int to bool conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 26954eded5..3353a18823 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -10,6 +10,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Statement(TextLocation info) : ValueNode(info) { + /// + /// Compute and optionally emit diagnostics. + /// + /// + public virtual void ProcessSymbol(SymbolTable table) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); + public abstract void Compile(SymbolTable table, CompilerUnit compiler); } @@ -24,9 +30,15 @@ public class ExpressionStatement(Expression expression, TextLocation info) : Sta { public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; + + public override void ProcessSymbol(SymbolTable table) + { + Expression.ProcessSymbol(table); + } public override void Compile(SymbolTable table, CompilerUnit compiler) { + Expression.ProcessSymbol(table); Expression.Compile(table, compiler); Type = ScalarType.Void; } @@ -39,17 +51,23 @@ public override string ToString() public class Return(TextLocation info, Expression? expression = null) : Statement(info) { public Expression? Value { get; set; } = expression; + + public override void ProcessSymbol(SymbolTable table) + { + Value?.ProcessSymbol(table); + Type = Value?.Type ?? ScalarType.Void; + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; SpirvValue? returnValue = null; - Type = builder.CurrentFunction!.Value.FunctionType.ReturnType; + var realReturnType = builder.CurrentFunction!.Value.FunctionType.ReturnType; if (Value != null) { var value = Value.CompileAsValue(table, compiler); - returnValue = builder.Convert(context, value, Type); + returnValue = builder.Convert(context, value, realReturnType); } builder.Return(returnValue); } @@ -94,14 +112,38 @@ public List? ArraySizes get => TypeName.ArraySize; set => TypeName.ArraySize = value; } + + public override void ProcessSymbol(SymbolTable table) + { + Value?.ProcessSymbol(table, TypeName.Type); + SymbolType valueType; + if (TypeName.Name == "var") + { + if (Value == null) + table.Errors.Add(new(Info, "can't infer `var` type without a value")); + valueType = Value.ValueType; + } + else + { + TypeName.ProcessSymbol(table); + valueType = TypeName.Type; + } + Type = new PointerType(valueType, Specification.StorageClass.Function); + Variable.Type = Type; + + // TODO: type check with conversion allowed + //if (Value is not null && Value.Type != Variable.Type) + // table.AddError(new(TypeName.Info, "wrong type")); + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var variableValueType = TypeName.ResolveType(table, context); + TypeName.ProcessSymbol(table); + var variableValueType = TypeName.Type; var initialValue = Value?.CompileAsValue(table, compiler, variableValueType); if (Value is not null && Value.ValueType != variableValueType) - table.Errors.Add(new(TypeName.Info, "wrong type")); + table.AddError(new(TypeName.Info, "wrong type")); throw new NotImplementedException(); } @@ -124,72 +166,46 @@ public class Declare(TypeName typename, TextLocation info) : Declaration(typenam { public List Variables { get; set; } = []; - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; + public List VariableSymbols { get; } = new(); - var compiledValues = new SpirvValue[Variables.Count]; - - // Compute type - SymbolType valueType; - var isVarType = TypeName == "var"; - if (isVarType) - { - // Compile first then guess type (for non-var, we delay compilation of intial values later so that we can infer type using full typename and arrays) - for (var index = 0; index < Variables.Count; index++) - { - if (Variables[index].Value != null) - compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler); - } - - if (Variables.Count == 1 && Variables[0].Value is not null) - { - valueType = Variables[0].Value!.ValueType; - } - else - { - table.Errors.Add(new(Info, SDSLErrorMessages.SDSL0104)); - return; - } - } - else + public override void ProcessSymbol(SymbolTable table) + { + VariableSymbols.Clear(); + for (var index = 0; index < Variables.Count; index++) { - valueType = TypeName.ResolveType(table, context); - table.DeclaredTypes.TryAdd(TypeName.ToString(), valueType); + var declaration = Variables[index]; + declaration.TypeName = new TypeName(TypeName.Name, info) { ArraySize = declaration.ArraySizes }; + declaration.ProcessSymbol(table); + + var variableSymbol = new Symbol(new(declaration.Variable, SymbolKind.Variable), declaration.Type, 0, OwnerType: table.CurrentShader); + table.CurrentFrame.Add(declaration.Variable, variableSymbol); + VariableSymbols.Add(variableSymbol); } + + Type = Variables[0].Type; + } - if (valueType is PointerType) - throw new InvalidOperationException(); - - Type = new PointerType(valueType, Specification.StorageClass.Function); + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; for (var index = 0; index < Variables.Count; index++) { var d = Variables[index]; - var variableValueType = valueType; - if (d.ArraySizes != null) - variableValueType = TypeName.GenerateArrayType(table, context, variableValueType, d.ArraySizes); - - var variableType = new PointerType(variableValueType, Specification.StorageClass.Function); - - // TODO: Check if any array is empty and fill with initializer info (if any, otherwise error) - var variable = context.Bound++; + var variableType = (PointerType)d.Type; + var variableValueType = variableType.BaseType; var variableTypeId = context.GetOrRegister(variableType); builder.AddFunctionVariable(variableTypeId, variable); context.AddName(variable, d.Variable); - table.CurrentFrame.Add(d.Variable, new(new(d.Variable, SymbolKind.Variable), variableType, variable, OwnerType: table.CurrentShader)); + VariableSymbols[index].IdRef = variable; // Check initial value if (d.Value != null) { - // var type: already computed - if (!isVarType) - compiledValues[index] = Variables[index].Value!.CompileAsValue(table, compiler, variableValueType); - - var source = compiledValues[index]; + var source = Variables[index].Value!.CompileAsValue(table, compiler, variableValueType); // Make sure type is correct source = builder.Convert(context, source, variableValueType); @@ -208,6 +224,15 @@ public class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; + public override void ProcessSymbol(SymbolTable table) + { + foreach (var variable in Variables) + { + variable.Variable.ProcessSymbol(table); + variable.Value!.ProcessSymbol(table); + } + } + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -257,9 +282,19 @@ public class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public override void Compile(SymbolTable table, CompilerUnit compiler) + public SymbolFrame SymbolFrame; + + public override void ProcessSymbol(SymbolTable table) { table.Push(); + foreach (var statement in Statements) + statement.ProcessSymbol(table); + SymbolFrame = table.Pop(); + } + + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + table.Push(SymbolFrame); var (builder, context) = compiler; foreach (var s in Statements) { diff --git a/src/Stride.Shaders/Parsing/SDSLERR.cs b/src/Stride.Shaders/Parsing/SDSLERR.cs index 1e9c9051af..130ab926d5 100644 --- a/src/Stride.Shaders/Parsing/SDSLERR.cs +++ b/src/Stride.Shaders/Parsing/SDSLERR.cs @@ -63,4 +63,9 @@ public static class SDSLErrorMessages public const string SDSL0106 = "SDSL0106: Unsupported type"; public const string SDSL0107 = "SDSL0107: Binary expression between vector and matrix is not implemented"; public const string SDSL0108 = "SDSL0108: Couldn't figure out type for binary operation between {0} and {1}"; + public const string SDSL0109 = "SDSL0109: Could not resolve method {0} in type {1}"; + public const string SDSL0110 = "SDSL0110: Use of undeclared identifier '{0}'"; + public const string SDSL0111 = "SDSL0111: Unimplemented: {0}"; + public const string SDSL0112 = "SDSL0112: Could not resolve member {0} in expression {1} of type {2}"; + public const string SDSL0113 = "SDSL0113: Could not resolve member {0} in structure of type {1}"; } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 025996e54d..b9ba5ae3c0 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -409,7 +409,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } - Console.WriteLine($"[Shader] Instantiating {classNameWithGenerics}"); + //Console.WriteLine($"[Shader] Instantiating {classNameWithGenerics}"); foreach (var i in shaderBuffers.Buffer) { @@ -773,13 +773,13 @@ public static List CollectGenerics(NewSpirvBuffer shader) public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, ReadOnlySpan defines, out ObjectId hash, out bool isFromCache) { - Console.WriteLine($"[Shader] Requesting non-generic class {className}"); + //Console.WriteLine($"[Shader] Requesting non-generic class {className}"); if (!shaderLoader.LoadExternalBuffer(className, defines, out var buffer, out hash, out isFromCache)) throw new InvalidOperationException($"Could not load shader [{className}]"); - if (!isFromCache) - Console.WriteLine($"[Shader] Loading non-generic class {className} for 1st time"); + //if (!isFromCache) + // Console.WriteLine($"[Shader] Loading non-generic class {className} for 1st time"); return buffer; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index f1d0fbc88c..453704bf3a 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -135,13 +135,13 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper break; case (MatrixType, VectorType): case (VectorType, MatrixType): - table.Errors.Add(new (info, SDSLErrorMessages.SDSL0107)); + table.AddError(new (info, SDSLErrorMessages.SDSL0107)); return null; case (MatrixType l, MatrixType r): resultType = new MatrixType(desiredElementType, Math.Min(l.Rows, r.Rows), Math.Min(l.Columns, r.Columns)); break; default: - table.Errors.Add(new (info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); + table.AddError(new (info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); return null; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index e2fd38e7a1..aff13c1d1f 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder { - public SpirvFunction DeclareFunction(SpirvContext context, string name, FunctionType ftype, bool isStage = false) + public static SpirvFunction DeclareFunction(SpirvContext context, string name, FunctionType ftype, bool isStage = false) { var func = context.Bound++; foreach (var t in ftype.ParameterTypes) diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index fe75532580..058cbc97cd 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -283,32 +283,7 @@ public SpirvValue CompileConstantLiteral(Literal literal) }, }; - if (literal.Type == null) - { - literal.Type = literal switch - { - BoolLiteral lit => ScalarType.Boolean, - IntegerLiteral lit => lit.Suffix switch - { - //{ Signed: true, Size: 8 } => ScalarType.SByte, - //{ Signed: true, Size: 16 } => ScalarType.Short, - { Signed: true, Size: 32 } => ScalarType.Int, - { Signed: true, Size: 64 } => ScalarType.Int64, - //{ Signed: false, Size: 8 } => ScalarType.UByte, - //{ Signed: false, Size: 16 } => ScalarType.UShort, - { Signed: false, Size: 32 } => ScalarType.UInt, - { Signed: false, Size: 64 } => ScalarType.UInt64, - _ => throw new NotImplementedException("Unsupported integer suffix") - }, - FloatLiteral lit => lit.Suffix.Size switch - { - //16 => ScalarType.Half, - 32 => ScalarType.Float, - 64 => ScalarType.Double, - _ => throw new NotImplementedException("Unsupported float") - }, - }; - } + literal.Type ??= ComputeLiteralType(literal); if (LiteralConstants.TryGetValue((literal.Type, literalValue), out var result)) return result; @@ -348,4 +323,31 @@ public SpirvValue CompileConstantLiteral(Literal literal) }); return result; } + + public static ScalarType ComputeLiteralType(Literal literal) + { + return literal switch + { + BoolLiteral lit => ScalarType.Boolean, + IntegerLiteral lit => lit.Suffix switch + { + //{ Signed: true, Size: 8 } => ScalarType.SByte, + //{ Signed: true, Size: 16 } => ScalarType.Short, + { Signed: true, Size: 32 } => ScalarType.Int, + { Signed: true, Size: 64 } => ScalarType.Int64, + //{ Signed: false, Size: 8 } => ScalarType.UByte, + //{ Signed: false, Size: 16 } => ScalarType.UShort, + { Signed: false, Size: 32 } => ScalarType.UInt, + { Signed: false, Size: 64 } => ScalarType.UInt64, + _ => throw new NotImplementedException("Unsupported integer suffix") + }, + FloatLiteral lit => lit.Suffix.Size switch + { + //16 => ScalarType.Half, + 32 => ScalarType.Float, + 64 => ScalarType.Double, + _ => throw new NotImplementedException("Unsupported float") + }, + }; + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs index 1a14d140c8..177df1c305 100644 --- a/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs +++ b/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs @@ -82,6 +82,7 @@ public static class ExpressionExtensions public static SpirvValue CompileConstantValue(this Expression expression, SymbolTable table, SpirvContext context, SymbolType? expectedType = null) { var compiler = new CompilerUnit(context, new()); + expression.ProcessSymbol(table, expectedType); var result = expression.CompileAsValue(table, compiler, expectedType); if (expectedType != null) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index c208241320..311c65785f 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -172,19 +172,19 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con table.TryResolveSymbol("PSMain", out var entryPointPS); table.TryResolveSymbol("CSMain", out var entryPointCS); - if (entryPointCS.Type is FunctionGroupType) + if (entryPointCS?.Type is FunctionGroupType) entryPointCS = entryPointCS.GroupMembers[^1]; - if (entryPointVS.Type is FunctionGroupType) + if (entryPointVS?.Type is FunctionGroupType) entryPointVS = entryPointVS.GroupMembers[^1]; - if (entryPointPS.Type is FunctionGroupType) + if (entryPointPS?.Type is FunctionGroupType) entryPointPS = entryPointPS.GroupMembers[^1]; - if (entryPointPS.IdRef == 0 && entryPointCS.IdRef == 0) + if (entryPointPS == null && entryPointCS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); - if (entryPointPS.IdRef != 0 && entryPointCS.IdRef != 0) + if (entryPointPS == null && entryPointCS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); - var entryPointPSOrCS = entryPointCS.IdRef != 0 ? entryPointCS : entryPointPS; + var entryPointPSOrCS = entryPointCS ?? entryPointPS; var analysisResult = Analyze(buffer, context); MergeSameSemanticVariables(table, context, buffer, analysisResult); @@ -193,7 +193,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con var liveAnalysis = new LiveAnalysis(); AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); - if (entryPointCS.IdRef != 0) + if (entryPointCS != null) { (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.GLCompute, entryPointCS.IdRef, entryPointCS.Id.Name, analysisResult, liveAnalysis, false); entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); @@ -213,7 +213,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con var inputAttributes = new List(); - if (entryPointPS.IdRef != 0) + if (entryPointPS != null) { // If written to, they are expected at the end of pixel shader foreach (var stream in streams) @@ -254,7 +254,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con } PropagateStreamsFromPreviousStage(streams); - if (entryPointVS.IdRef != 0) + if (entryPointVS != null) { AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); From 0e691badfd05b58fffd448dcb46050753a030e5b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 29 Jan 2026 16:38:40 +0900 Subject: [PATCH 0760/1182] Added support for method overload (choose best overload according to arguments and function signature) --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 198 +++++++++--------- .../Parsing/SDSL/AST/Expression.cs | 140 ++++++++----- .../Spirv/Building/Builder.Expressions.cs | 82 ++++++++ 3 files changed, 274 insertions(+), 146 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index c4ad485ec2..d6e52e8681 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -34,21 +34,21 @@ public static SymbolType FindCommonType(ScalarType baseType, params Span Specification.Op.OpAtomicExchange, }); result = new SpirvValue(instruction.ResultId, instruction.ResultType); - originalValueIndex = Parameters.Values.Count == 3 ? 2 : null; + originalValueIndex = Arguments.Values.Count == 3 ? 2 : null; } // Out parameter? if (originalValueIndex is { } originalValueIndex2) { - var resultLocation = Parameters.Values[originalValueIndex2].Compile(table, compiler); - if (Parameters.Values[originalValueIndex2].Type is not PointerType resultPointerType) - throw new InvalidOperationException($"out parameter is not a l-value, got {Parameters.Values[0].Type} instead"); + var resultLocation = Arguments.Values[originalValueIndex2].Compile(table, compiler); + if (Arguments.Values[originalValueIndex2].Type is not PointerType resultPointerType) + throw new InvalidOperationException($"out parameter is not a l-value, got {Arguments.Values[0].Type} instead"); result = builder.Convert(context, result, resultPointerType.BaseType); builder.Insert(new OpStore(resultLocation.Id, result.Id, null, [])); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 7bc5a67b17..246b18d80a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -77,10 +77,10 @@ public class EmptyExpression(TextLocation info) : Expression(info) public override string ToString() => string.Empty; } -public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLocation info) : Expression(info) +public class MethodCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : Expression(info) { public Identifier Name = name; - public ShaderExpressionList Parameters = parameters; + public ShaderExpressionList Arguments = arguments; public SymbolType? MemberCallBaseType { get; set; } public SpirvValue? MemberCall { get; set; } @@ -89,22 +89,21 @@ public class MethodCall(Identifier name, ShaderExpressionList parameters, TextLo public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { + ProcessParameterSymbols(table); if (!TryResolveFunctionSymbol(table, out var functionSymbol)) return; var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; - ProcessParameterSymbols(table, functionType); - ResolvedFunctionSymbol = functionSymbol; } - public void ProcessParameterSymbols(SymbolTable table, FunctionType? functionType) + public void ProcessParameterSymbols(SymbolTable table, FunctionType? functionType = null) { - for (var index = 0; index < Parameters.Values.Count; index++) + for (var index = 0; index < Arguments.Values.Count; index++) { - var parameter = Parameters.Values[index]; + var parameter = Arguments.Values[index]; var parameterExpectedType = functionType?.ParameterTypes[index].Type; parameter.ProcessSymbol(table, parameterExpectedType); } @@ -121,10 +120,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; - if (parameters.Values.Count > functionType.ParameterTypes.Count) - throw new InvalidOperationException($"Function {Name} was called with {parameters.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); + if (arguments.Values.Count > functionType.ParameterTypes.Count) + throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); - for (int i = 0; i < parameters.Values.Count; i++) + for (int i = 0; i < arguments.Values.Count; i++) { // Wrap param in proper pointer type (function) var paramDefinition = functionType.ParameterTypes[i]; @@ -135,7 +134,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var inOutFlags = paramDefinition.Modifiers & ParameterModifiers.InOut; if (inOutFlags != ParameterModifiers.Out) { - var paramSource = parameters.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); // Convert type (if necessary) var paramExpectedValueType = paramDefinition.Type; @@ -150,7 +149,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } // Find default parameters decoration (if any) - var missingParameters = functionType.ParameterTypes.Count - parameters.Values.Count; + var missingParameters = functionType.ParameterTypes.Count - arguments.Values.Count; var defaultParameters = 0; if (missingParameters > 0 && functionSymbol.MethodDefaultParameters is {} methodDefaultParameters) { @@ -160,7 +159,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Import missing parameters for (int i = 0; i < missingParameters; ++i) { - var paramDefinition = functionType.ParameterTypes[parameters.Values.Count + i]; + var paramDefinition = functionType.ParameterTypes[arguments.Values.Count + i]; var source = methodDefaultParameters.DefaultValues[^(missingParameters - i)]; // Import in current buffer @@ -174,14 +173,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); builder.Insert(new OpStore(paramVariable, source, null, [])); - compiledParams[parameters.Values.Count + i] = paramVariable; + compiledParams[arguments.Values.Count + i] = paramVariable; } missingParameters = 0; } } if (missingParameters > 0) - throw new InvalidOperationException($"Function {Name} was called with {parameters.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); + throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); int? instance = null; if (MemberCall != null) @@ -199,14 +198,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); - for (int i = 0; i < parameters.Values.Count; i++) + for (int i = 0; i < arguments.Values.Count; i++) { var paramDefinition = functionType.ParameterTypes[i]; if (paramDefinition.Modifiers.HasFlag(ParameterModifiers.Out)) { var paramDefinitionType = (PointerType)paramDefinition.Type; var paramVariable = compiledParams[i]; - var paramTarget = parameters.Values[i].Compile(table, compiler, paramDefinitionType); + var paramTarget = arguments.Values[i].Compile(table, compiler, paramDefinitionType); var paramTargetType = (PointerType)context.ReverseTypes[paramTarget.TypeId]; if (paramTargetType.BaseType != paramDefinitionType.BaseType) @@ -238,16 +237,63 @@ private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymb } // Choose appropriate method to call + // We just care about overload (different signature), not override (base/this/most derived) as this will be resolved in ShaderMixer later if (functionSymbol.Type is FunctionGroupType) { - var matchingMethods = functionSymbol.GroupMembers - // Find methods matching number of parameters - .Where(x => ((FunctionType)x.Type).ParameterTypes.Count == parameters.Values.Count); + // Note: int.MaxValue means incompatible + static int OverloadScore(Symbol functionSymbol, ShaderExpressionList arguments) + { + // Check argument count + var functionType = (FunctionType)functionSymbol.Type; + if (arguments.Values.Count > functionType.ParameterTypes.Count || arguments.Values.Count < functionType.ParameterTypes.Count + (functionSymbol.MethodDefaultParameters?.DefaultValues.Length ?? 0)) + return int.MaxValue; + + // Check if argument can be converted + var score = 0; + for (var index = 0; index < arguments.Values.Count; index++) + { + var argument = arguments.Values[index]; + var parameter = functionType.ParameterTypes[index]; + var argScore = SpirvBuilder.CanConvertScore(argument.ValueType, parameter.Type.GetValueType()); + if (argScore == int.MaxValue) + return int.MaxValue; + + score += argScore; + } + + // method with fewer optional parameters that need to be filled in by default values is generally preferred + score += functionType.ParameterTypes.Count - arguments.Values.Count; + + return score; + } - // TODO: find proper overload (different signature) - // We take first element, so in case there is multiple override, it will take the most-derived implementation - // Note: this will be reevaluted during ShaderMixer (which specific override depending on base/this, etc.) but it won't change overload (different signature) - functionSymbol = matchingMethods.First(); + var accessibleMethods = functionSymbol.GroupMembers + // Check overload score + .Select(x => (Score: OverloadScore(x, arguments), Symbol: x)) + // Remove non-applicable methods + .Where(x => x.Score != int.MaxValue) + // Group by signature/score (we assume method with exact same signature means they are overriding each other, but we might need to do a better check using override info) + .GroupBy(x => (x.Score, x.Symbol.Type)) + // Sort by best match (score) + .OrderBy(x => x.Key.Score) + .ToList(); + + if (accessibleMethods.Count == 0) + { + table.AddError(new(info, $"Can't find a valid method overload to call for {Name} (among {functionSymbol.GroupMembers} candidate(s))")); + return false; + } + + // Check if there is an ambiguous call (multiple method groups with the lowest score) + if (accessibleMethods.Count > 1 && accessibleMethods[0].Key.Score == accessibleMethods[1].Key.Score) + { + table.AddError(new(info, $"Ambiguous method overload when calling for {Name} (among {functionSymbol.GroupMembers} candidate(s))")); + return false; + } + + // Note: actual override (base/this) will be reevaluted during ShaderMixer, but overload (different signature) won't be changed + // So we just pick the method with the lowest score + functionSymbol = accessibleMethods[0].First().Symbol; } return true; @@ -255,7 +301,7 @@ private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymb public override string ToString() { - return $"{Name}({string.Join(", ", Parameters)})"; + return $"{Name}({string.Join(", ", Arguments)})"; } } @@ -743,8 +789,8 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) switch (currentValueType, accessor) { case (PointerType { BaseType: TextureType textureType }, - MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } - or MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 }): + MethodCall { Name.Name: "Sample", Arguments.Values.Count: 2 or 3 } + or MethodCall { Name.Name: "SampleLevel", Arguments.Values.Count: 3 or 4 }): { if (compiler == null) { @@ -758,10 +804,10 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) var textureValue = builder.AsValue(context, result); var resultType = accessor.Type; - if (accessor is MethodCall { Name.Name: "Sample", Parameters.Values.Count: 2 or 3 } implicitSampling) + if (accessor is MethodCall { Name.Name: "Sample", Arguments.Values.Count: 2 or 3 } implicitSampling) { - var samplerValue = implicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); + var samplerValue = implicitSampling.Arguments.Values[0].CompileAsValue(table, compiler); + var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -769,9 +815,9 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) ImageOperandsMask? imask = null; EnumerantParameters imParams = []; - if (implicitSampling.Parameters.Values.Count > 2) + if (implicitSampling.Arguments.Values.Count > 2) { - var offset = ConvertOffset(context, builder, textureType, implicitSampling.Parameters.Values[2].CompileAsValue(table, compiler)); + var offset = ConvertOffset(context, builder, textureType, implicitSampling.Arguments.Values[2].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset imask = ImageOperandsMask.Offset; imParams = new EnumerantParameters(offset.Id); @@ -781,12 +827,12 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) result = new(sample.ResultId, sample.ResultType); accessor.Type = resultType; } - else if (accessor is MethodCall { Name.Name: "SampleLevel", Parameters.Values.Count: 3 or 4 } explicitSampling) + else if (accessor is MethodCall { Name.Name: "SampleLevel", Arguments.Values.Count: 3 or 4 } explicitSampling) { - var samplerValue = explicitSampling.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); + var samplerValue = explicitSampling.Arguments.Values[0].CompileAsValue(table, compiler); + var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); - var levelValue = explicitSampling.Parameters.Values[2].CompileAsValue(table, compiler); + var levelValue = explicitSampling.Arguments.Values[2].CompileAsValue(table, compiler); levelValue = builder.Convert(context, levelValue, ScalarType.Float); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); @@ -796,9 +842,9 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) ImageOperandsMask imask = ImageOperandsMask.None; EnumerantParameters imParams = []; - if (explicitSampling.Parameters.Values.Count > 3) + if (explicitSampling.Arguments.Values.Count > 3) { - var offset = ConvertOffset(context, builder, textureType, explicitSampling.Parameters.Values[3].CompileAsValue(table, compiler)); + var offset = ConvertOffset(context, builder, textureType, explicitSampling.Arguments.Values[3].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset imask = ImageOperandsMask.Lod | ImageOperandsMask.Offset; imParams = new EnumerantParameters(levelValue.Id, offset.Id); @@ -818,7 +864,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) break; } case (PointerType { BaseType: TextureType textureType }, - MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Parameters.Values.Count: 3 or 4 } sampleCompare): + MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Arguments.Values.Count: 3 or 4 } sampleCompare): { if (compiler == null) { @@ -835,10 +881,10 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) EmitOpAccessChain(accessChainIds, i - 1); var textureValue = builder.AsValue(context, result); - var samplerValue = sampleCompare.Parameters.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Parameters.Values[1].CompileAsValue(table, compiler), ScalarType.Float); + var samplerValue = sampleCompare.Arguments.Values[0].CompileAsValue(table, compiler); + var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); - var compareValue = sampleCompare.Parameters.Values[2].CompileAsValue(table, compiler); + var compareValue = sampleCompare.Arguments.Values[2].CompileAsValue(table, compiler); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); @@ -849,9 +895,9 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new (context.CompileConstant(0.0f).Id) : new (); //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" - if (sampleCompare.Parameters.Values.Count > 3) + if (sampleCompare.Arguments.Values.Count > 3) { - var offset = ConvertOffset(context, builder, textureType, sampleCompare.Parameters.Values[3].CompileAsValue(table, compiler)); + var offset = ConvertOffset(context, builder, textureType, sampleCompare.Arguments.Values[3].CompileAsValue(table, compiler)); // TODO: determine when ConstOffset flags |= ImageOperandsMask.Offset; imParams = new EnumerantParameters([..imParams, offset.Id]); @@ -866,7 +912,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) accessor.Type = resultType; break; } - case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Parameters.Values.Count: 1 } load): + case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Arguments.Values.Count: 1 } load): { if (compiler == null) { @@ -880,8 +926,8 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) (result, accessor.Type) = pointerType.BaseType switch { - BufferType b => BufferLoad(b, result, load.Parameters.Values[0]), - TextureType t => TextureLoad(t, result, load.Parameters.Values[0], true), + BufferType b => BufferLoad(b, result, load.Arguments.Values[0]), + TextureType t => TextureLoad(t, result, load.Arguments.Values[0], true), }; break; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 453704bf3a..2dc37278bd 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -308,6 +308,87 @@ when l.IsFloating() && r.IsFloating() return new(instruction, name); } + /// + /// Check if a type can be converted to another. + /// + /// + /// + /// 0 if perfect match, int.MaxValue if failure, a score higher than 0 otherwise. + public static int CanConvertScore(SymbolType valueType, SymbolType castType) + { + if (castType == valueType) + return 0; + + if (castType is StructType || valueType is StructType) + throw new NotImplementedException($"Can't cast between structures (cast from {valueType} to {castType})"); + + if (castType is ArrayType a1 && valueType is ArrayType a2) + { + if (a1.BaseType == a2.BaseType) + { + if (a1.Size != -1 && a1.Size != a2.Size) + return int.MaxValue; + // Some sizes are undetermined; this can only happen during compilation due to incomplete generics type + // TODO: do a "check pass" later to make sure this won't happen after generics instantiation? + return 0; + } + else + { + return int.MaxValue; + } + } + + // We don't support cast with object yet, filter for numeral types + if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) + || (valueType is not ScalarType && valueType is not VectorType && valueType is not MatrixType)) + throw new NotImplementedException($"Cast only work between numeral types (cast from {valueType} to {castType})"); + + var conversionScore = (valueType, castType) switch + { + // Promotion scalar to scalar, vector or matrix (replicate value) + (ScalarType, ScalarType or VectorType or MatrixType) => 1, + // Truncation + (VectorType or MatrixType, ScalarType) => 1, + // Vector cast + (VectorType v1, VectorType v2) when v1.Size == v2.Size => 1, + (VectorType v1, VectorType v2) when v1.Size < v2.Size => int.MaxValue, + // Emit warning? (warning: implicit truncation of vector type) + (VectorType v1, VectorType v2) when v1.Size > v2.Size => 1, + (VectorType v1, MatrixType m2) when v1.Size != m2.Rows * m2.Columns => int.MaxValue, + (VectorType v1, MatrixType m2) when v1.Size == m2.Rows * m2.Columns => 1, + (MatrixType m1, VectorType v2) when v2.Size != m1.Rows * m1.Columns => int.MaxValue, + // Note: conversions such as float2x2=>float4 are allowed but not implemented in Convert() + (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, + (MatrixType m1, MatrixType m2) when m1.Rows < m2.Rows || m1.Columns < m2.Columns => int.MaxValue, + (MatrixType m1, MatrixType m2) when m1.Rows >= m2.Rows && m1.Columns >= m2.Columns => 1, + _ => int.MaxValue + }; + + if (conversionScore == int.MaxValue) + return int.MaxValue; + + // Check element types now + var scalarScore = (valueType.GetElementType(), castType.GetElementType()) switch + { + (ScalarType s1, ScalarType s2) when s1 == s2 => 0, + + // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => 7, + (ScalarType { Type: Scalar.Float or Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => 7, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => 1, + + // Bitcast (int=>uint or uint=>int) + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => 2, + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => 2, + + _ => int.MaxValue, + }; + if (scalarScore == int.MaxValue) + return int.MaxValue; + + return conversionScore + scalarScore; + } + public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolType castType) { var valueId = value.Id; @@ -430,6 +511,7 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, false), 0, new()), elementSize).Id)), (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), From 0a53ddb0f57df954bbd9850ecf809138a7d1d04d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 29 Jan 2026 16:48:18 +0900 Subject: [PATCH 0761/1182] Reflection: process [Color] attribute --- .../SDSL/ShaderMixer.CBuffers.cs | 34 +- .../SDSL/ShaderMixer.Reflection.cs | 89 +++-- .../SDSL/ShaderMixer.cs | 4 +- .../Extensions/spirv.sdsl.grammar-ext.json | 320 +++++++++--------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 + .../Parsing/SDSL/AST/ShaderElements.cs | 88 +++-- 6 files changed, 306 insertions(+), 231 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 25aa0837a6..60fc710548 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -45,14 +45,15 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob var globalCBufferType = new ConstantBufferSymbol("Globals", members); var globalCBufferTypeId = context.DeclareCBuffer(globalCBufferType); - var links = new (string? Link, string? LogicalGroup)[members.Count]; + // Transfer metadata from variable to cbuffer member + var memberMetadata = new CBufferMemberMetadata[members.Count]; for (var index = 0; index < members.Count; index++) { var member = members[index]; context.AddMemberName(globalCBufferTypeId, index, member.Name); - var linkInfo = variableLinks[variables[index]]; - links[index] = (linkInfo.Link, linkInfo.LogicalGroup); + var metadata = variableMetadata[variables[index]]; + memberMetadata[index] = new(Link: metadata.Link, LogicalGroup: metadata.LogicalGroup, Color: metadata.Color); } // Note: we make sure to add at a previous variable index, otherwise the OpVariableSDSL won't be inside the root MixinNode.StartInstruction/EndInstruction @@ -60,7 +61,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob context.AddName(cbufferVariable.ResultId, "Globals"); // Update cbuffer links - cbufferMemberLinks[cbufferVariable.ResultId] = links; + cbufferMemberMetadata[cbufferVariable.ResultId] = memberMetadata; // Replace all accesses int instructionsAddedInThisMethod = 0; @@ -162,7 +163,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex string? GetCBufferLogicalGroup(int variableId) { - variableLinks.TryGetValue(variableId, out var linkName); + variableMetadata.TryGetValue(variableId, out var linkName); return linkName.LogicalGroup; } @@ -219,16 +220,15 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri } // Transfer cbufferMemberLinks to new structure - (string Link, string LogicalGroup)[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) + CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) { - var cbufferStructId = context.Types[cbufferStruct]; int mergedMemberIndex = 0; - var links = new (string Link, string LogicalGroup)[cbufferStruct.Members.Count]; + var links = new CBufferMemberMetadata[cbufferStruct.Members.Count]; foreach (ref var cbuffer in cbuffersSpan) { for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) { - links[mergedMemberIndex] = cbufferMemberLinks[cbuffer.Variable.Data.IdResult.Value][memberIndex]; + links[mergedMemberIndex] = cbufferMemberMetadata[cbuffer.Variable.Data.IdResult.Value][memberIndex]; } } @@ -302,7 +302,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri // Update first variable to use new type cbuffersSpan[0].Variable.Data.IdResultType = mergedCbufferPtrStructId; - cbufferMemberLinks[cbuffersSpan[0].Variable.Data.IdResult.Value] = GenerateCBufferLinks(cbuffersSpan[0].Variable.Data.IdResult.Value, cbuffersSpan, mergedCbufferStruct); + cbufferMemberMetadata[cbuffersSpan[0].Variable.Data.IdResult.Value] = GenerateCBufferLinks(cbuffersSpan[0].Variable.Data.IdResult.Value, cbuffersSpan, mergedCbufferStruct); foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) @@ -404,7 +404,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon var structTypeId = context.Types[cb]; var memberInfos = new EffectValueDescription[cb.Members.Count]; - if (!cbufferMemberLinks.TryGetValue(cbuffer.Variable.Data.IdResult.Value, out var cbufferLinks)) + if (!cbufferMemberMetadata.TryGetValue(cbuffer.Variable.Data.IdResult.Value, out var cbufferMetadata)) throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.Variable.Data.IdResult.Value]}; it should have been generated during {MergeCBuffers}"); for (var index = 0; index < cb.Members.Count; index++) @@ -415,17 +415,23 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon DecorateMember(context, structTypeId, index, constantBufferOffset, memberSize, member.Type, member.TypeModifier); - var linkInfo = cbufferLinks[index]; + var metadata = cbufferMetadata[index]; memberInfos[index] = new EffectValueDescription { Type = ConvertType(context, member.Type, member.TypeModifier, SpirvBuilder.AlignmentRules.CBuffer), RawName = member.Name, - KeyInfo = new EffectParameterKeyInfo { KeyName = linkInfo.Link }, + KeyInfo = new EffectParameterKeyInfo { KeyName = metadata.Link }, Offset = constantBufferOffset, Size = memberSize, - LogicalGroup = linkInfo.LogicalGroup, + LogicalGroup = metadata.LogicalGroup, }; + if (metadata.Color) + { + if (member.Type is not VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 }) + throw new InvalidOperationException("[Color] attribute can only be applied on float3/float4 vector types"); + memberInfos[index].Type.Class = EffectParameterClass.Color; + } // Adjust offset for next item constantBufferOffset += memberSize; diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index f4b4f44f6e..82980bd9a0 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -9,9 +10,12 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer { - private Dictionary variableLinks = new(); + private record struct VariableMetadata(string? Link = null, string? ResourceGroup = null, string? LogicalGroup = null, bool Color = false); + private record struct CBufferMemberMetadata(string? Link = null, string? LogicalGroup = null, bool Color = false); + + private Dictionary variableMetadata = new(); // Note: cbuffer might share same struct, which is why we store this info per variable instead of per struct (as per OpMemberDecorate was doing) - private Dictionary cbufferMemberLinks = new(); + private Dictionary cbufferMemberMetadata = new(); private static bool IsResourceType(SymbolType type) => type is TextureType or SamplerType or BufferType or StructuredBufferType or ConstantBufferSymbol; @@ -23,34 +27,68 @@ private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) string? compositionPath = null; string? shaderName = null; - var variableDecorationLinks = new Dictionary(); - var structDecorationLinks = new Dictionary<(int, int), string>(); + var variableDecorationMetadata = new Dictionary(); + var structDecorationMetadata = new Dictionary<(int, int), CBufferMemberMetadata>(); foreach (var i in context) { - if (i.Op == Specification.Op.OpDecorateString && (OpDecorateString)i is - { Decoration: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL, Value: string m } decorate) + if (i.Op == Specification.Op.OpDecorate && (OpDecorate)i is + { Decoration: Specification.Decoration.ColorSDSL } decorate) { - ref var link = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationLinks, decorate.Target, out _); + ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationMetadata, decorate.Target, out _); switch (decorate.Decoration) + { + case Specification.Decoration.ColorSDSL: + metadata.Color = true; + break; + default: + throw new NotImplementedException(); + } + } + else if (i.Op == Specification.Op.OpDecorateString && (OpDecorateString)i is + { Decoration: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL } decorateString) + { + ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationMetadata, decorateString.Target, out _); + switch (decorateString.Decoration) { case Specification.Decoration.LinkSDSL: - link.Link = m; + metadata.Link = decorateString.Value; break; case Specification.Decoration.ResourceGroupSDSL: - link.ResourceGroup = m; + metadata.ResourceGroup = decorateString.Value; break; case Specification.Decoration.LogicalGroupSDSL: - link.LogicalGroup = m; + metadata.LogicalGroup = decorateString.Value; + break; + default: + throw new NotImplementedException(); + } + } + else if (i.Op == Specification.Op.OpMemberDecorate && (OpMemberDecorate)i is + { Decoration: Specification.Decoration.ColorSDSL } memberDecorate) + { + ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(structDecorationMetadata, (memberDecorate.StructureType, memberDecorate.Member), out _); + switch (memberDecorate.Decoration) + { + case Specification.Decoration.ColorSDSL: + metadata.Color = true; break; default: throw new NotImplementedException(); } } else if (i.Op == Specification.Op.OpMemberDecorateString && (OpMemberDecorateString)i is - { Decoration: Specification.Decoration.LinkSDSL, Value: string m2 } memberDecorate) + { Decoration: Specification.Decoration.LinkSDSL } memberDecorateString) { - structDecorationLinks[(memberDecorate.StructType, memberDecorate.Member)] = m2; + ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(structDecorationMetadata, (memberDecorateString.StructType, memberDecorateString.Member), out _); + switch (memberDecorateString.Decoration) + { + case Specification.Decoration.LinkSDSL: + metadata.Link = memberDecorateString.Value; + break; + default: + throw new NotImplementedException(); + } } } @@ -76,32 +114,33 @@ private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) var variablePointerType = (PointerType)context.ReverseTypes[variableInstruction.ResultType]; var variableType = variablePointerType.BaseType; - if (!variableDecorationLinks.TryGetValue(variableInstruction.ResultId, out var linkInfo) - || linkInfo.Link == null) - linkInfo.Link = GenerateLinkName(shaderName, context.Names[variableInstruction.ResultId]); + if (!variableDecorationMetadata.TryGetValue(variableInstruction.ResultId, out var metadata) + || metadata.Link == null) + metadata.Link = GenerateLinkName(shaderName, context.Names[variableInstruction.ResultId]); if (!isStage) - linkInfo.Link = ComposeLinkName(linkInfo.Link, compositionPath); + metadata.Link = ComposeLinkName(metadata.Link, compositionPath); - variableLinks[variableInstruction.ResultId] = linkInfo; + variableMetadata[variableInstruction.ResultId] = metadata; if (variableType is ConstantBufferSymbol cb) { var constantBufferStructId = context.Types[cb]; - (string Link, string LogicalGroup)[] memberLinks = new (string Link, string LogicalGroup)[cb.Members.Count]; + CBufferMemberMetadata[] memberLinks = new CBufferMemberMetadata[cb.Members.Count]; for (var index = 0; index < cb.Members.Count; index++) { var member = cb.Members[index]; - if (!structDecorationLinks.TryGetValue((constantBufferStructId, index), out var memberLink) - || memberLink == null) - memberLink = GenerateLinkName(shaderName, member.Name); + if (!structDecorationMetadata.TryGetValue((constantBufferStructId, index), out var memberLink) + || memberLink.Link == null) + memberLink.Link = GenerateLinkName(shaderName, member.Name); if (!isStage) - memberLink = ComposeLinkName(memberLink, compositionPath); - memberLinks[index] = (memberLink, linkInfo.LogicalGroup); + memberLink.Link = ComposeLinkName(memberLink.Link, compositionPath); + memberLink.LogicalGroup = metadata.LogicalGroup; + memberLinks[index] = memberLink; } - cbufferMemberLinks.Add(variableInstruction.ResultId, memberLinks); + cbufferMemberMetadata.Add(variableInstruction.ResultId, memberLinks); } } } @@ -261,7 +300,7 @@ or Specification.Decoration.SamplerStateMinLOD { var name = context.Names[variable.ResultId]; - variableLinks.TryGetValue(variable.ResultId, out var linkInfo); + variableMetadata.TryGetValue(variable.ResultId, out var linkInfo); var linkName = variableType switch { // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e8fb72b816..e07163251f 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -934,11 +934,11 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL or Decoration.ShaderConstantSDSL - or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL + or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) return true; - if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) return true; // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index dfc31f61f8..1ce016b9d3 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -434,161 +434,171 @@ "category": "ValueEnum", "kind": "Decoration", "enumerants": [ - { - "enumerant": "LinkSDSL", - "value": 8000, - "parameters": [ - { - "kind": "LiteralString", - "name": "'Name'" - } - ], - "version": "1.0" - }, - { - "enumerant": "LinkIdSDSL", - "value": 8001, - "parameters": [ - { - "kind": "IdRef" - } - ], - "version": "1.0" - }, - { - "enumerant": "ResourceGroupSDSL", - "value": 8002, - "parameters": [ - { - "kind": "LiteralString", - "name": "'ResourceGroup'" - } - ], - "version": "1.0" - }, - { - "enumerant": "ResourceGroupIdSDSL", - "value": 8003, - "parameters": [ - { - "kind": "LiteralInteger", - "name": "'ResourceGroup'" - } - ], - "version": "1.0" - }, - { - "enumerant": "LogicalGroupSDSL", - "value": 8004, - "parameters": [ - { - "kind": "LiteralString", - "name": "'LogicalGroup'" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateFilter", - "value": 8020, - "parameters": [ - { - "kind": "SamplerFilterSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressU", - "value": 8021, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressV", - "value": 8022, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressW", - "value": 8023, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMipLODBias", - "value": 8024, - "parameters": [ - { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxAnisotropy", - "value": 8025, - "parameters": [ - { - "kind": "LiteralInteger" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateComparisonFunc", - "value": 8026, - "parameters": [ - { - "kind": "SamplerComparisonFuncSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMinLOD", - "value": 8027, - "parameters": [ - { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxLOD", - "value": 8028, - "parameters": [ - { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "FunctionParameterDefaultValueSDSL", - "value": 8040, - "parameters": [ - { - "kind": "IdRef", - "quantifier": "*" - } - ], - "version": "1.0" - }, + { + "enumerant": "LinkSDSL", + "value": 8000, + "parameters": [ + { + "kind": "LiteralString", + "name": "'Name'" + } + ], + "version": "1.0" + }, + { + "enumerant": "LinkIdSDSL", + "value": 8001, + "parameters": [ + { + "kind": "IdRef" + } + ], + "version": "1.0" + }, + { + "enumerant": "ColorSDSL", + "value": 8002, + "parameters": [ + { + "kind": "IdRef" + } + ], + "version": "1.0" + }, + { + "enumerant": "ResourceGroupSDSL", + "value": 8010, + "parameters": [ + { + "kind": "LiteralString", + "name": "'ResourceGroup'" + } + ], + "version": "1.0" + }, + { + "enumerant": "ResourceGroupIdSDSL", + "value": 8011, + "parameters": [ + { + "kind": "LiteralInteger", + "name": "'ResourceGroup'" + } + ], + "version": "1.0" + }, + { + "enumerant": "LogicalGroupSDSL", + "value": 8004, + "parameters": [ + { + "kind": "LiteralString", + "name": "'LogicalGroup'" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateFilter", + "value": 8020, + "parameters": [ + { + "kind": "SamplerFilterSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressU", + "value": 8021, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressV", + "value": 8022, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateAddressW", + "value": 8023, + "parameters": [ + { + "kind": "SamplerTextureAddressModeSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMipLODBias", + "value": 8024, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMaxAnisotropy", + "value": 8025, + "parameters": [ + { + "kind": "LiteralInteger" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateComparisonFunc", + "value": 8026, + "parameters": [ + { + "kind": "SamplerComparisonFuncSDSL" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMinLOD", + "value": 8027, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, + { + "enumerant": "SamplerStateMaxLOD", + "value": 8028, + "parameters": [ + { + "kind": "LiteralString" + } + ], + "version": "1.0" + }, + { + "enumerant": "FunctionParameterDefaultValueSDSL", + "value": 8040, + "parameters": [ + { + "kind": "IdRef", + "quantifier": "*" + } + ], + "version": "1.0" + }, { "enumerant": "ShaderConstantSDSL", "value": 8060, diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c949faa179..19520ba988 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -244,6 +244,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) ); Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + + Value?.ProcessSymbol(table, memberType); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index ec0bbe0df6..c4c30ef26f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -250,51 +250,65 @@ public override string ToString() } } - public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { public Symbol Symbol { get; private set; } private bool? isStaged; - - public static (string? LinkName, int? LinkId) ProcessLinkAttributes(SymbolTable table, SpirvContext context, TextLocation info, List attributes) + + public record struct AttributeAnalysisResult(string? LinkName = null, int? LinkId = null, bool Color = false); + + public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, SpirvContext context, TextLocation info, List attributes) { + var result = new AttributeAnalysisResult(); if (attributes != null) { foreach (var attribute in attributes) { - if (attribute is AnyShaderAttribute anyAttribute && anyAttribute.Name == "Link") + if (attribute is AnyShaderAttribute anyAttribute) { - if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) - { - // Try to resolve generic parameter when encoded as string (deprecated) - if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) - { - linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); - // TODO: make it a warning only? - //table.AddError(new(info, "LinkType generics should be passed without quotes")); - return (null, linkLiteralSymbol.IdRef); - } - - return (linkLiteral.Value, null); - } - else if (anyAttribute.Parameters[0] is Identifier identifier) + switch (anyAttribute.Name) { - if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + case "Link": { - throw new InvalidOperationException(); + if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) + { + // Try to resolve generic parameter when encoded as string (deprecated) + if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) + { + linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); + // TODO: make it a warning only? + //table.AddError(new(info, "LinkType generics should be passed without quotes")); + result.LinkId = linkLiteralSymbol.IdRef; + } + else + { + result.LinkName = linkLiteral.Value; + } + } + else if (anyAttribute.Parameters[0] is Identifier identifier) + { + if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + { + throw new InvalidOperationException(); + } + linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); + result.LinkId = linkSymbol.IdRef; + } + else + { + throw new NotImplementedException($"Attribute {attribute} is not supported"); + } + break; } - linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); - return (null, linkSymbol.IdRef); - } - else - { - throw new NotImplementedException($"Attribute {attribute} is not supported"); + case "Color": + result.Color = true; + break; } } } } - return (null, null); + return result; } public override void ProcessSymbol(SymbolTable table, SpirvContext context) @@ -355,11 +369,13 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile if (member.Attributes != null && member.Attributes.Count > 0) { - var linkInfo = ProcessLinkAttributes(table, context, Info, member.Attributes); - if (linkInfo.LinkId is int linkId) + var attributesInfo = ProcessAttributes(table, context, Info, member.Attributes); + if (attributesInfo.LinkId is int linkId) context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, Specification.Decoration.LinkIdSDSL, [linkId])); - else if (linkInfo.LinkName != null) - context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, Specification.Decoration.LinkSDSL, linkInfo.LinkName)); + else if (attributesInfo.LinkName != null) + context.Add(new OpMemberDecorateString(context.GetOrRegister(Type), index, Specification.Decoration.LinkSDSL, attributesInfo.LinkName)); + if (attributesInfo.Color) + context.Add(new OpMemberDecorate(context.GetOrRegister(Type), index, Specification.Decoration.ColorSDSL, new EnumerantParameters())); } } @@ -425,11 +441,13 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass shaderClass, SpirvContext context, TextLocation info, string memberName, List attributes, int variableId) { - var linkInfo = CBuffer.ProcessLinkAttributes(table, context, info, attributes); - if (linkInfo.LinkId is int linkId) + var attributesInfo = CBuffer.ProcessAttributes(table, context, info, attributes); + if (attributesInfo.LinkId is int linkId) context.Add(new OpDecorate(variableId, Specification.Decoration.LinkIdSDSL, [linkId])); - else if (linkInfo.LinkName != null) - context.Add(new OpDecorateString(variableId, Specification.Decoration.LinkSDSL, linkInfo.LinkName)); + else if (attributesInfo.LinkName != null) + context.Add(new OpDecorateString(variableId, Specification.Decoration.LinkSDSL, attributesInfo.LinkName)); + else if (attributesInfo.Color) + context.Add(new OpDecorate(variableId, Specification.Decoration.ColorSDSL, new EnumerantParameters())); } } From 6de25ccc741c88734888d1b5d67d09a108ce44a5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 Jan 2026 00:46:56 +0900 Subject: [PATCH 0762/1182] Improvements to texture Sample/Load parsing (unified code for image operand like LOD/offset) --- .../Literals/EnumerantParameters.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 142 +++++++++++------- 2 files changed, 91 insertions(+), 53 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs b/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs index 5afd8db2c5..8f87402f64 100644 --- a/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs +++ b/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs @@ -39,7 +39,7 @@ public EnumerantParameters(params ReadOnlySpan words) Words = MemoryOwner.Allocate(words.Length); words.CopyTo(Words.Span); } - public EnumerantParameters(Span words) + public EnumerantParameters(scoped Span words) { Words = MemoryOwner.Allocate(words.Length); words.CopyTo(Words.Span); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 246b18d80a..e1c5c3cbae 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -748,7 +748,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) return (new(loadResult.ResultId, loadResult.ResultType), resultType); } - (SpirvValue Value, SymbolType ResultType) TextureLoad(TextureType textureType, SpirvValue buffer, Expression coordinatesExpression, bool containsLod) + (SpirvValue Value, SymbolType ResultType) TextureLoad(TextureType textureType, SpirvValue buffer, Expression coordinatesExpression, Expression? offsetExpression, Expression? sampleIndexExpression, bool containsLod) { var resultType = new VectorType(textureType.ReturnType, 4); var imageCoordValue = ConvertTexCoord(context, builder, textureType, coordinatesExpression.CompileAsValue(table, compiler), ScalarType.Int, containsLod); @@ -765,7 +765,9 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) shuffleIndices[i] = i; // Note: assign LOD first because we truncate imageCoordValue right after - lod = new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, imageCoordValue.Id, [shuffleIndices.Length - 1]))); + // Extract LOD (last coordinate) as a separate value + lod = new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, imageCoordValue.Id, [imageCoordSize - 1]))); + // Remove last component (LOD) from texcoord imageCoordValue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(imageCoordType), context.Bound++, imageCoordValue.Id, imageCoordValue.Id, new(shuffleIndices)))); } else @@ -775,7 +777,14 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) buffer = builder.AsValue(context, buffer); - var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(resultType), context.Bound++, buffer.Id, imageCoordValue.Id, ImageOperandsMask.Lod, new EnumerantParameters(lod.Id))); + SpirvValue? offset = offsetExpression != null + ? ConvertOffset(context, builder, textureType, offsetExpression.CompileAsValue(table, compiler)) + : null; + SpirvValue? sampleIndex = sampleIndexExpression != null + ? builder.Convert(context, sampleIndexExpression.CompileAsValue(table, compiler), ScalarType.Int) + : null; + TextureGenerateImageOperands(lod, offset, sampleIndex, out var imask, out var imParams); + var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(resultType), context.Bound++, buffer.Id, imageCoordValue.Id, imask, imParams)); return (new(loadResult.ResultId, loadResult.ResultType), resultType); } @@ -813,15 +822,10 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - ImageOperandsMask? imask = null; - EnumerantParameters imParams = []; - if (implicitSampling.Arguments.Values.Count > 2) - { - var offset = ConvertOffset(context, builder, textureType, implicitSampling.Arguments.Values[2].CompileAsValue(table, compiler)); - // TODO: determine when ConstOffset - imask = ImageOperandsMask.Offset; - imParams = new EnumerantParameters(offset.Id); - } + SpirvValue? offset = implicitSampling.Arguments.Values.Count >= 3 + ? ConvertOffset(context, builder, textureType, implicitSampling.Arguments.Values[2].CompileAsValue(table, compiler)) + : null; + TextureGenerateImageOperands(null, offset, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); result = new(sample.ResultId, sample.ResultType); @@ -839,21 +843,10 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - ImageOperandsMask imask = ImageOperandsMask.None; - EnumerantParameters imParams = []; - - if (explicitSampling.Arguments.Values.Count > 3) - { - var offset = ConvertOffset(context, builder, textureType, explicitSampling.Arguments.Values[3].CompileAsValue(table, compiler)); - // TODO: determine when ConstOffset - imask = ImageOperandsMask.Lod | ImageOperandsMask.Offset; - imParams = new EnumerantParameters(levelValue.Id, offset.Id); - } - else - { - imask = ImageOperandsMask.Lod; - imParams = new EnumerantParameters(levelValue.Id); - } + SpirvValue? offset = explicitSampling.Arguments.Values.Count >= 4 + ? ConvertOffset(context, builder, textureType, explicitSampling.Arguments.Values[3].CompileAsValue(table, compiler)) + : null; + TextureGenerateImageOperands(levelValue, offset, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); result = new(sample.ResultId, sample.ResultType); @@ -889,33 +882,43 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); var returnType = context.GetOrRegister(resultType); - - - ImageOperandsMask flags = sampleCompare.Name.Name is "SampleCmpLevelZero" ? ImageOperandsMask.Lod : ImageOperandsMask.None; - EnumerantParameters imParams = sampleCompare.Name.Name is "SampleCmpLevelZero" ? new (context.CompileConstant(0.0f).Id) : new (); - //ParameterizedFlag flags = sampleCompare.Name.Name == "SampleCmpLevelZero" - - if (sampleCompare.Arguments.Values.Count > 3) - { - var offset = ConvertOffset(context, builder, textureType, sampleCompare.Arguments.Values[3].CompileAsValue(table, compiler)); - // TODO: determine when ConstOffset - flags |= ImageOperandsMask.Offset; - imParams = new EnumerantParameters([..imParams, offset.Id]); - //flags = new ParameterizedFlag(flags | ImageOperandsMask.Offset, new(..imParams.Span, offset.Id]); - } - + + SpirvValue? offset = sampleCompare.Arguments.Values.Count >= 4 + ? ConvertOffset(context, builder, textureType, sampleCompare.Arguments.Values[3].CompileAsValue(table, compiler)) + : null; + TextureGenerateImageOperands(context.CompileConstant(0.0f), offset, null, out var imask, out var imParams); var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, flags, imParams)); + ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, imask, imParams)) + : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, imask, imParams)); result = new(sample.IdResult!.Value, sample.IdResultType!.Value); accessor.Type = resultType; break; } - case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Arguments.Values.Count: 1 } load): + case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Arguments.Values.Count: 1 or 2 or 3 } load): { if (compiler == null) { + // Check parameter count + switch (pointerType.BaseType) + { + case BufferType b: + if (load.Arguments.Values.Count != 1) + table.AddError(new(info, "Buffer.Load expects a single argument")); + break; + case TextureType t: + var requiredArguments = 1; + if (t.Multisampled) + requiredArguments++; + + // One optional argument (offset) + if (load.Arguments.Values.Count != requiredArguments && load.Arguments.Values.Count != requiredArguments + 1) + table.AddError(new(info, $"Texture.Load expects {requiredArguments} or {requiredArguments + 1} arguments")); + break; + default: + throw new ArgumentOutOfRangeException(nameof(pointerType.BaseType)); + } + ((MethodCall)accessor).ProcessParameterSymbols(table, null); accessor.Type = ComputeBufferOrTextureAccessReturnType(pointerType); break; @@ -923,12 +926,22 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - - (result, accessor.Type) = pointerType.BaseType switch + + switch (pointerType.BaseType) { - BufferType b => BufferLoad(b, result, load.Arguments.Values[0]), - TextureType t => TextureLoad(t, result, load.Arguments.Values[0], true), - }; + case BufferType b: + (result, accessor.Type) = BufferLoad(b, result, load.Arguments.Values[0]); + break; + case TextureType t: + var sampleIndex = t.Multisampled ? load.Arguments.Values[1] : null; + var offsetArgIndex = t.Multisampled ? 2 : 1; + var offset = load.Arguments.Values.Count >= offsetArgIndex + 1 ? load.Arguments.Values[offsetArgIndex] : null; + (result, accessor.Type) = TextureLoad(t, result, load.Arguments.Values[0], offset, sampleIndex, true); + break; + default: + throw new ArgumentOutOfRangeException(nameof(pointerType.BaseType)); + } + break; } case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): @@ -946,7 +959,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) (result, accessor.Type) = pointerType.BaseType switch { BufferType b => BufferLoad(b, result, indexer.Index), - TextureType t => TextureLoad(t, result, indexer.Index, false), + TextureType t => TextureLoad(t, result, indexer.Index, null, null, false), }; break; } @@ -1248,7 +1261,32 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) return result; } - + + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams) + { + imask = ImageOperandsMask.None; + // Allocate for worst case (3 operands) + Span operands = stackalloc int[3]; + int operandCount = 0; + if (lod != null) + { + imask |= ImageOperandsMask.Lod; + operands[operandCount++] = lod.Value.Id; + } + if (offset != null) + { + imask |= ImageOperandsMask.Offset; + operands[operandCount++] = offset.Value.Id; + } + if (sampleIndex != null) + { + imask |= ImageOperandsMask.Sample; + operands[operandCount++] = sampleIndex.Value.Id; + } + + imParams = operandCount > 0 ? new EnumerantParameters(operands.Slice(0, operandCount)) : new EnumerantParameters(); + } + SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue, ScalarType baseType, bool hasLod = false) { var textureCoordSize = textureType switch From ea5e2b497b7ce10b736395f7cac16a7c49b070ec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 Jan 2026 00:47:12 +0900 Subject: [PATCH 0763/1182] Intrisics: fmod and frac --- .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 26 ++++++++++++++++++- .../PrimaryExpressionParsers.cs | 6 ++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs index d6e52e8681..49733c2814 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs @@ -118,7 +118,6 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); // Adjust OpCode only since Pow/Atan2 share the same operands instruction.InstructionMemory.Span[4] = (int)op; - var result = new SpirvValue(instruction.ResultId, instruction.ResultType); return new(instruction.ResultId, instruction.ResultType); } } @@ -576,6 +575,31 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } +public class FloatBinaryCall(ShaderExpressionList arguments, TextLocation info, Specification.Op op) : MethodCall(new(op.ToString(), info), arguments, info) +{ + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + ProcessParameterSymbols(table, null); + var xType = Arguments.Values[0].ValueType; + var yType = Arguments.Values[1].ValueType; + Type = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); + + x = builder.Convert(context, x, Type); + y = builder.Convert(context, y, Type); + + if (context.GLSLSet == null) + context.ImportGLSL(); + var instruction = builder.Insert(new OpFRem(x.TypeId, context.Bound++, x.Id, y.Id)); + // Adjust OpCode only since Pow/Atan2 share the same operands + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + return new(instruction.ResultId, instruction.ResultType); + } +} public class FloatUnaryCall(ShaderExpressionList arguments, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), arguments, info) { public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 9de097516a..e52c1fc80d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -118,7 +118,9 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), ("step", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLStep), - + ("frac", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFract), + ("fmod", 2) => new FloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFRem), + // Vector math ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), @@ -165,8 +167,6 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou ("firstbithigh", _) => throw new NotImplementedException(), ("firstbitlow", _) => throw new NotImplementedException(), ("fma", _) => throw new NotImplementedException(), - ("fmod", _) => throw new NotImplementedException(), - ("frac", _) => throw new NotImplementedException(), ("frexp", _) => throw new NotImplementedException(), ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), From 524ae13cb5a8f76009fce7fcbdecc479020922f3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 Jan 2026 01:47:48 +0900 Subject: [PATCH 0764/1182] Matrix swizzles --- assets/SDSL/RenderTests/Swizzle.sdsl | 6 ++ .../Parsing/SDSL/AST/Expression.cs | 59 ++++++++++++++++++- .../Parsing/SDSL/AST/Literals.cs | 59 +++++++++++++++++++ .../Spirv/Building/Builder.Expressions.cs | 17 ++++++ 4 files changed, 138 insertions(+), 3 deletions(-) diff --git a/assets/SDSL/RenderTests/Swizzle.sdsl b/assets/SDSL/RenderTests/Swizzle.sdsl index 5f0c083ae3..cbeaf18c1d 100644 --- a/assets/SDSL/RenderTests/Swizzle.sdsl +++ b/assets/SDSL/RenderTests/Swizzle.sdsl @@ -8,6 +8,7 @@ // PSMain(ExpectedResult=#02030401, cbuffer.Test=(Test1=7)) // PSMain(ExpectedResult=#02040103, cbuffer.Test=(Test1=8)) // PSMain(ExpectedResult=#05060308, cbuffer.Test=(Test1=9)) +// PSMain(ExpectedResult=#0109030B, cbuffer.Test=(Test1=10)) namespace Stride.Shaders.Tests; @@ -46,5 +47,10 @@ shader Swizzle streams.ColorTarget.wxyz.wyxz = streams.ColorTarget; if (Test1 == 9) streams.ColorTarget.xyw += streams.ColorTarget.w; + if (Test1 == 10) + { + float4x4 m = float4x4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) / 255.0; + streams.ColorTarget = m._11_31_13_33; + } } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index e1c5c3cbae..58b9d676f3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -571,6 +571,8 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal // We stop there return; } + case (PointerType { BaseType: MatrixType } or MatrixType, Identifier { Name: var swizzle } id) when id.IsMatrixSwizzle((MatrixType)currentValueType.GetValueType(), out var swizzles): + throw new NotImplementedException("Assign back to matrix swizzle is not implemented yet"); case (PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): // Swizzle: we transform the value to assign accordingly @@ -661,7 +663,7 @@ void PushAccessChainId(Span accessChainIds, int accessChainIndex) accessChainIds[accessChainIdCount++] = accessChainIndex; } - void EmitOpAccessChain(Span accessChainIds, int i) + void EmitOpAccessChain(Span accessChainIds, int? intermediateValueIndex) { if (compiler == null) throw new InvalidOperationException(); @@ -669,11 +671,11 @@ void EmitOpAccessChain(Span accessChainIds, int i) if (accessChainIdCount > 0) { var resultType = context.GetOrRegister(currentValueType); - var test = new LiteralArray(accessChainIds); var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); result = new SpirvValue(accessChain.ResultId, resultType); - intermediateValues[1 + i] = result; + if (intermediateValueIndex != null) + intermediateValues[1 + intermediateValueIndex.Value] = result; } accessChainIdCount = 0; @@ -1045,6 +1047,56 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); break; // Swizzles + case (PointerType { BaseType: MatrixType m } p, Identifier id) when id.IsMatrixSwizzle(m, out var swizzles): + { + if (swizzles.Count > 1) + { + if (compiler == null) + { + if (swizzles.Count > 4) + { + table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + return default; + } + + accessor.Type = new VectorType(m.BaseType, swizzles.Count); + break; + } + + EmitOpAccessChain(accessChainIds, i - 1); + (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); + } + else + { + // Keep as a pointer + if (compiler == null) + { + accessor.Type = new PointerType(m.BaseType, p.StorageClass); + break; + } + + PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Column).Id); + PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Row).Id); + } + break; + } + case (MatrixType m, Identifier id) when id.IsMatrixSwizzle(m, out var swizzles): + { + if (compiler == null) + { + if (swizzles.Count > 4) + { + table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + return default; + } + + accessor.Type = m.BaseType.GetVectorOrScalar(swizzles.Count); + break; + } + + (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); + break; + } case (PointerType { BaseType: VectorType v } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { @@ -1070,6 +1122,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) } else { + // Keep as a pointer if (compiler == null) { accessor.Type = new PointerType(v.BaseType, p.StorageClass); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index fc7b97da6d..ec43f8fdd8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -510,6 +510,65 @@ public bool IsVectorSwizzle() return true; } + public bool IsMatrixSwizzle(MatrixType m, [MaybeNullWhen(false)] out List<(int Column, int Row)> swizzles) + { + /// + /// Parses a single component token: "11" or "m22" (no leading underscore). + /// + static bool TryParseOne(ReadOnlySpan token, int cols, int rows, out (int Column, int Row) component) + { + component = default; + + if ((token.Length != 3 && token.Length != 4) || token[0] != '_') + return false; + + int i = 1; + if (token[i] == 'm' || token[i] == 'M') + i++; + + // Need exactly two digits after optional 'm' + if (token.Length - i != 2) return false; + + char cCh = token[i + 0]; + char rCh = token[i + 1]; + + if (cCh < '0' || cCh > '9' || rCh < '0' || rCh > '9') return false; + + // HLSL uses both zero-based and one-based indices: _11 means row 0 col 0 and _m11 means row 1 column 1 + var offset = (i == 2 ? 0 : 1); + int col = (cCh - '0') - offset; + int row = (rCh - '0') - offset; + + if (col < 0 || row < 0) return false; + if (col >= cols || row >= rows) return false; + + component = (col, row); + return true; + } + + swizzles = null; + if (Name[0] != '_') + return false; + + var startIndex = 0; + var currentIndex = 0; + var result = new List<(int, int)>(); + while (currentIndex < Name.Length) + { + if (++currentIndex == Name.Length || Name[currentIndex] == '_') + { + if (!TryParseOne(Name.AsSpan(startIndex, currentIndex - startIndex), m.Rows, m.Columns, out var component)) + return false; + + result.Add(component); + startIndex = currentIndex; + } + } + + swizzles = result; + return true; + } + public bool IsMatrixField() { return diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index 2dc37278bd..ec9b191092 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -82,6 +82,23 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) else throw new InvalidOperationException(); } + + public (SpirvValue, SymbolType) ApplyMatrixSwizzles(SpirvContext context, SpirvValue value, MatrixType m, Span<(int Column, int Row)> swizzles) + { + Span elements = stackalloc int[swizzles.Length]; + for (var swizzleIndex = 0; swizzleIndex < swizzles.Length; swizzleIndex++) + { + var swizzle = swizzles[swizzleIndex]; + elements[swizzleIndex] = Insert(new OpCompositeExtract(context.GetOrRegister(m.BaseType), context.Bound++, value.Id, [swizzle.Column, swizzle.Row])).ResultId; + } + + var resultType = m.BaseType.GetVectorOrScalar(swizzles.Length); + value = swizzles.Length > 1 + ? new(InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, [..elements]))) + : new(elements[0], context.GetOrRegister(resultType)); + + return (value, resultType); + } public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftElementType, SymbolType rightElementType) { From 358907708081ba66b92aa4e222f9c77abb26c81b Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Fri, 30 Jan 2026 01:12:11 +0100 Subject: [PATCH 0765/1182] working on effect interpreter --- assets/SDFX/BasicEffect.sdfx | 31 ++++ .../SDSL/EffectEvaluator.cs | 138 +++++++++++------ src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 16 ++ .../SDSL/ShaderMixer.cs | 5 +- .../ShaderLoaderBase.cs | 2 +- .../Examples.Effects.cs | 139 ++++++++++++++++++ src/Stride.Shaders.Experiments/Program.cs | 20 +-- .../Extensions/spirv.sdsl.grammar-ext.json | 102 +++++++++++++ src/Stride.Shaders/Core/SymbolTypes.cs | 27 ++++ .../Parsing/SDFX/AST/Effect.Flow.cs | 52 ++++++- .../Parsing/SDFX/AST/Effect.Parameters.cs | 17 +++ src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 11 +- .../StrideImported/Core/ParameterKeyInfo.cs | 57 +++++++ 13 files changed, 549 insertions(+), 68 deletions(-) create mode 100644 assets/SDFX/BasicEffect.sdfx create mode 100644 src/Stride.Shaders.Experiments/Examples.Effects.cs create mode 100644 src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs diff --git a/assets/SDFX/BasicEffect.sdfx b/assets/SDFX/BasicEffect.sdfx new file mode 100644 index 0000000000..403845cf18 --- /dev/null +++ b/assets/SDFX/BasicEffect.sdfx @@ -0,0 +1,31 @@ +namespace Stride.Rendering.Images; + + +shader A +{ + int a; +} + +shader B +{ + float b; +} + + +params BasicParams +{ + bool MixA; + bool MixB; +} + +effect BasicEffect +{ + using params BasicParams; + + mixin(A); + + if(BasicParams.MixA) + mixin(A); + if(BasicParams.MixB) + mixin(B); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 396645b6c1..22022b14a3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance; +using Stride.Rendering; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -16,56 +17,20 @@ internal class EffectEvaluator(IExternalShaderLoader ShaderLoader) { private Stack mixinSources = new(); - public ShaderSource EvaluateEffects(ShaderSource source) + public ShaderSource EvaluateEffects(ShaderSource source, IDictionary? parameters = null) { - object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds) - { - var genericArguments = new object[genericIds.Length]; - for (int i = 0; i < genericArguments.Length; i++) - { - genericArguments[i] = context.GetConstantValue(genericIds[i]); - } - return genericArguments; - } + // For our tests the ShaderSource is a ShaderClassSource, just a name of a shader to load switch (source) { case ShaderClassSource classSource: var macros = mixinSources.Count > 0 ? mixinSources.Peek().Macros : []; var shaderBuffers = SpirvBuilder.GetOrLoadShader(ShaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); - - if (shaderBuffers.Buffer[0].Op == Op.OpSDSLEffect) + return shaderBuffers.Buffer[0].Op switch { - var mixinTree = new ShaderMixinSource(); - foreach (var instruction in shaderBuffers.Buffer) - { - if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) - { - var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinInstruction.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - Merge(mixinTree, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) - { - var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeInstruction.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) - { - var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeArray.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); - } - } - - return mixinTree; - } - - return classSource; + Op.OpSDSLEffect => EffectInterpreter(shaderBuffers, parameters), + _ => classSource + }; case ShaderMixinSource mixinSource: { var result = new ShaderMixinSource(); @@ -111,6 +76,85 @@ object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds } } + private ShaderMixinSource EffectInterpreter(ShaderBuffers shaderBuffers, IDictionary? parameters) + { + var mixinTree = new ShaderMixinSource(); + int i = 0; + var count = shaderBuffers.Buffer.Count; + while (i < count) + { + var instruction = shaderBuffers.Buffer[i]; + + // If we reach a conditional instruction we need to evaluate the conditions after it. + // If it's false we need to check if there's another conditional instruction after it (ParamsTrue / Else) + // Once we reach the OpSDSLConditionalEnd + if (instruction.Op is Op.OpSDSLConditionalStart) + { + i += 1; + bool conditionMet = false; + while(!conditionMet) + { + if (instruction.Op is Op.OpSDSLParamsTrue && (OpSDSLParamsTrue)instruction is { } condition) + { + if (parameters?.TryGetValue(condition.ParamsName, out var bparam) ?? false) + { + // TODO: Where are the values ? + if (bparam is ParameterKey boolParam) + { + throw new NotImplementedException(); + } + else if (bparam is ParameterKey shparam) + { + throw new NotImplementedException(); + } + } + } + else if(instruction.Op is Op.OpSDSLElse) + { + if(!conditionMet) + { + conditionMet = true; + // TODO: Apply else branch + } + } + else if(instruction.Op is Op.OpSDSLConditionalEnd) + { + break; + } + } + } + else if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) + { + var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinInstruction.Values.Elements.Span)); + var evaluatedSource = EvaluateEffects(instSource); + + Merge(mixinTree, evaluatedSource); + } + else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) + { + var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeInstruction.Values.Elements.Span)); + var evaluatedSource = EvaluateEffects(instSource); + + MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); + } + else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) + { + var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeArray.Values.Elements.Span)); + var evaluatedSource = EvaluateEffects(instSource); + + MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); + } + else if (instruction.Op == Op.OpSDSLMixinChild && (OpSDSLMixinChild)instruction is { } mixinChild) + { + throw new NotImplementedException(); + } + + i += 1; + } + + return mixinTree; + } + private void PropagateMacrosFromParent(ShaderMixinSource parent, ShaderMixinSource child) { var existingMacros = new HashSet(); @@ -171,5 +215,15 @@ public void MergeCompositionArrayItem(ShaderMixinSource mixinTree, string compos var arraySource = (ShaderArraySource)composition; arraySource.Add(evaluatedSource); } + + static object[] GetGenericsArguments(SpirvContext context, ReadOnlySpan genericIds) + { + var genericArguments = new object[genericIds.Length]; + for (int i = 0; i < genericArguments.Length; i++) + { + genericArguments[i] = context.GetConstantValue(genericIds[i]); + } + return genericArguments; + } } } diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index eb5b14e89f..5b7c2baae3 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -64,6 +64,22 @@ public readonly bool Compile(string code, ReadOnlySpan macros, [May ShaderLoader.RegisterShader(effect.Name, macros, lastBuffer); } + else if (declaration is EffectParameters parameters) + { + var compiler = new CompilerUnit(); + SymbolTable table = new(compiler.Context) + { + ShaderLoader = ShaderLoader, + CurrentMacros = [..macros], + }; + compiler.Macros.AddRange(macros); + parameters.Compile(table, compiler); + + var merged = compiler.ToBuffer(); + lastBuffer = new(merged); + + ShaderLoader.RegisterShader(parameters.Name, [], lastBuffer); + } else { throw new NotImplementedException($"Compiling declaration [{declaration.GetType()}] is not implemented"); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index d3f9dd4cb0..0832165012 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -32,12 +32,15 @@ public partial class ShaderMixer(IExternalShaderLoader shaderLoader) public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; public void MergeSDSL(ShaderSource shaderSource, out Span bytecode, out EffectReflection effectReflection) { + // Create new buffer for the merged result var temp = new NewSpirvBuffer(); + // This is the global context for this merge operation var context = new SpirvContext(); var table = new SymbolTable(context) { ShaderLoader = ShaderLoader }; var effectEvaluator = new EffectEvaluator(ShaderLoader); + // We basically put the shader we want to merge through the EffectEvaluator to resolve all mixins/compositions first shaderSource = effectEvaluator.EvaluateEffects(shaderSource); var shaderSource2 = EvaluateInheritanceAndCompositions(context, shaderSource); @@ -339,7 +342,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (i2.Op == Op.OpDecorate && new OpDecorate(ref i2) is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) { // Somehow data doesn't get mutated inside i2 if we update resourceGroupIdDecorate.Decoration, so we reference buffer directly - resourceGroupIdDecorate.DecorationParameters = [m.Span[0] + resourceGroupOffset]; + resourceGroupIdDecorate.DecorationParameters = new(m.Span[0] + resourceGroupOffset); } if (SpirvBuilder.ContainIds(forbiddenIds, i2)) diff --git a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs index b1a8c0a8e5..4f845f8056 100644 --- a/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -87,7 +87,7 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan> loadedShaders = []; + + public virtual void RegisterShader(string name, ReadOnlySpan defines, SpirvBytecode bytecode) + { + if (!loadedShaders.TryGetValue(name, out var loadedShadersByName)) + loadedShaders.Add(name, loadedShadersByName = new()); + loadedShadersByName.Add(new(defines.ToArray()), bytecode); + } + + public bool Exists(string name) + { + if (loadedShaders.ContainsKey(name)) + return true; + + return ExternalFileExists(name); + } + + + public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) + { + if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + { + isFromCache = true; + return true; + } + + isFromCache = false; + if (!ExternalFileExists(name)) + { + throw new InvalidOperationException($"Shader {name} could not be found"); + } + + if (!LoadExternalFileContent(name, out var filename, out var code)) + { + throw new InvalidOperationException($"Shader {name} could not be loaded"); + } + + if (!LoadFromCode(filename, code, defines, out buffer)) + { + throw new InvalidOperationException($"Shader {name} could not be compiled"); + } + + return true; + } + + public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out SpirvBytecode buffer, out bool isFromCache) + { + if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + && loadedShadersByName.TryGetValue(new(defines.ToArray()), out buffer)) + { + isFromCache = true; + return true; + } + + var filename = $"{code}{(Path.HasExtension(code) ? "" : ".sdsl")}"; + + isFromCache = false; + if (!LoadFromCode(filename, code, defines, out buffer)) + { + throw new InvalidOperationException($"Shader {name} could not be compiled"); + } + + return true; + } + + protected virtual bool LoadFromCode(string filename, string code, ReadOnlySpan macros, out SpirvBytecode buffer) + { + var defines = new (string Name, string Definition)[macros.Length]; + for (int i = 0; i < macros.Length; ++i) + defines[i] = (macros[i].Name, macros[i].Definition); + + var text = MonoGamePreProcessor.Run(code, Path.GetFileName(filename), defines); + var sdslc = new SDSLC + { + ShaderLoader = this, + }; + + return sdslc.Compile(text, macros, out buffer); + } + protected bool ExternalFileExists(string name) + { + var filename = $"./assets/SDFX/{name}{(Path.HasExtension(name) ? "" : ".sdsl")}"; + return File.Exists(filename); + } + + protected bool LoadExternalFileContent(string name, out string filename, out string code) + { + filename = $"./assets/SDFX/{name}{(Path.HasExtension(name) ? "" : ".sdsl")}"; + code = File.ReadAllText(filename); + return true; + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index d7d40bb179..4fea8b337f 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -7,23 +7,5 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders; -Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); -// Examples.CompileSDSL("RenderTests/If"); - -//Examples.CompileSDSL(); -var loader = new Examples.ShaderLoader(); -loader.LoadExternalBuffer("Test", [], out var testBuffer, out _); -var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), out var bytecode, out _); - -using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); -var source = Spv.Dis(buffer); -File.WriteAllText("test.spvdis", source); - - -// Examples.TryAllFiles(); -// Examples.CreateShader(); - -// Examples.GenerateSpirv(); -// Examples.CreateNewShader(); \ No newline at end of file +Examples.CompileBasicEffect(); \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index e4a52f8bbc..3a05ce4512 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -24,6 +24,98 @@ } ] }, + { + "opname": "OpSDSLParamsUse", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "paramsName" + } + ] + }, + { + "opname": "OpSDSLMixinUse", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLMixinChild", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLMixinClone", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, + { + "opname": "OpSDSLParams", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "name" + } + ] + }, + { + "opname": "OpSDSLParamsField", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "name" + }, + { + "kind": "LiteralString", + "name": "cstype" + } + ] + }, + { + "opname": "OpSDSLConditionalStart", + "class": "Miscellaneous" + }, + { + "opname": "OpSDSLConditionalEnd", + "class": "Miscellaneous" + }, + { + "opname": "OpSDSLParamsTrue", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "paramsName" + } + ] + }, + { + "opname": "OpSDSLElse", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "mixinName" + } + ] + }, { "opname": "OpSDSLComposition", "class": "Miscellaneous", @@ -835,6 +927,16 @@ "value": 8 } ] + }, + { + "category": "ValueEnum", + "kind": "StorageClass", + "enumerants": [ + { + "enumerant": "Params", + "value": 8000 + } + ] } ] } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 602ebb979f..6afc91360e 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -89,6 +89,33 @@ public static bool TryGetBufferType(string name, string? templateTypeName, [Mayb public abstract void Accept(TypeVisitor visitor); public abstract TResult Accept(TypeVisitor visitor); + + internal static SymbolType Of() + { + return typeof(T) switch + { + var t when t == typeof(void) => ScalarType.From("void"), + var t when t == typeof(bool) => ScalarType.From("bool"), + var t when t == typeof(byte) => ScalarType.From("byte"), + var t when t == typeof(sbyte) => ScalarType.From("sbyte"), + var t when t == typeof(short) => ScalarType.From("short"), + var t when t == typeof(ushort) => ScalarType.From("ushort"), + var t when t == typeof(Half) => ScalarType.From("half"), + var t when t == typeof(int) => ScalarType.From("int"), + var t when t == typeof(uint) => ScalarType.From("uint"), + var t when t == typeof(float) => ScalarType.From("float"), + var t when t == typeof(double) => ScalarType.From("double"), + + var t when t == typeof(System.Numerics.Vector2) => VectorType.From("float2"), + var t when t == typeof(System.Numerics.Vector3) => VectorType.From("float3"), + var t when t == typeof(System.Numerics.Vector4) => VectorType.From("float4"), + + var t when t == typeof(System.Numerics.Matrix3x2) => MatrixType.From("float3x2"), + var t when t == typeof(System.Numerics.Matrix4x4) => MatrixType.From("float4x4"), + + _ => throw new NotSupportedException($"Type '{typeof(T)}' is not supported as a SymbolType."), + }; + } } public sealed partial record UndefinedType(string TypeName) : SymbolType() diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs index 353ee16cf3..b8e798cf3b 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs @@ -1,6 +1,8 @@ +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info) @@ -16,23 +18,54 @@ public class EffectControl(If first, TextLocation info) : EffectFlow(info) public If If { get; set; } = first; public List ElseIfs { get; set; } = []; public Else? Else { get; set; } + + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + compiler.Builder.Insert(new OpSDSLConditionalStart()); + If.Compile(table, compiler); + foreach(var elseIf in ElseIfs) + elseIf.Compile(table, compiler); + Else?.Compile(table, compiler); + compiler.Builder.Insert(new OpSDSLConditionalEnd()); + } public override string ToString() { return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; } } -public class If(SDSL.AST.Expression condition, EffectStatement body, TextLocation info) : EffectFlow(info) +public class If(Expression condition, EffectStatement body, TextLocation info) : EffectFlow(info) { - public SDSL.AST.Expression Condition { get; set; } = condition; + public Expression Condition { get; set; } = condition; public EffectStatement Body { get; set; } = body; + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + _ = Condition switch + { + AccessorChainExpression { Source : Identifier, Accessors : [Identifier]} ace => + compiler.Builder.Insert(new OpSDSLParamsTrue(ace.ToString())), + BinaryExpression {Left : AccessorChainExpression { Source : Identifier, Accessors : [Identifier]} ace, Op : Core.Operator.NotEquals, Right : Identifier {Name : "null"}} => + compiler.Builder.Insert(new OpSDSLParamsTrue(ace.ToString())), + _ => throw new NotImplementedException() + }; + + _ = Body switch + { + EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Parameters.Values : [Identifier m]}}} + => compiler.Builder.Insert(new OpSDSLMixinUse(m.Name)), + EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Parameters.Values : [AccessorChainExpression {Source : Identifier, Accessors : [Identifier]} ace]}}} + => compiler.Builder.Insert(new OpSDSLMixinUse(ace.ToString())), + _ => throw new NotImplementedException() + }; + } + public override string ToString() { return $"if({Condition})\n{Body}"; } } -public class ElseIf(SDSL.AST.Expression condition, EffectStatement body, TextLocation info) : If(condition, body, info) +public class ElseIf(Expression condition, EffectStatement body, TextLocation info) : If(condition, body, info) { public override string ToString() { @@ -43,6 +76,19 @@ public override string ToString() public class Else(EffectStatement body, TextLocation info) : EffectFlow(info) { public EffectStatement Body { get; set; } = body; + + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + compiler.Builder.Insert(new OpSDSLElse()); + _ = Body switch + { + EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Parameters.Values : [Identifier m]}}} + => compiler.Builder.Insert(new OpSDSLMixinUse(m.Name)), + EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Parameters.Values : [AccessorChainExpression {Source : Identifier, Accessors : [Identifier]} ace]}}} + => compiler.Builder.Insert(new OpSDSLMixinUse(ace.ToString())), + _ => throw new NotImplementedException() + }; + } public override string ToString() { return $"else {Body}"; diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs index fcc521013c..0b51d5d74d 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs @@ -1,4 +1,8 @@ +using Stride.Shaders.Core.Analysis; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDFX.AST; @@ -7,6 +11,13 @@ public class EffectParameters(TypeName name, TextLocation info) : ShaderDeclarat { public TypeName Name { get; set; } = name; public List Parameters { get; set; } = []; + + public void Compile(SymbolTable table, CompilerUnit compiler) + { + compiler.Builder.Insert(new OpSDSLParams(Name.Name)); + foreach(var parameter in Parameters) + parameter.Compile(table, compiler); + } } @@ -15,4 +26,10 @@ public class EffectParameter(TypeName type, Identifier identifier, TextLocation public TypeName Type { get; set; } = type; public Identifier Identifier { get; set;} = identifier; public Expression? DefaultValue { get; set; } = value; + + public void Compile(SymbolTable table, CompilerUnit compiler) + { + var (_, context) = compiler; + context.Add(new OpSDSLParamsField(Identifier, Type)); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 1f29af16ee..6e5b986eba 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -255,7 +255,8 @@ public class UsingParams(Identifier name, TextLocation info) : EffectStatement(i public override void Compile(SymbolTable table, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, _) = compiler; + builder.Insert(new OpSDSLParamsUse(ParamsName.Name)); } @@ -283,7 +284,13 @@ public class EffectExpressionStatement(Statement statement, TextLocation info) : public override void Compile(SymbolTable table, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, _) = compiler; + if (Statement is ExpressionStatement { Expression: MethodCall { Name.Name: "mixin", Parameters.Values: [Identifier mixin] } }) + builder.Insert(new OpSDSLMixinUse(mixin.Name)); + else + { + throw new NotImplementedException(); + } } } diff --git a/src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs b/src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs new file mode 100644 index 0000000000..91b3e46a8e --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs @@ -0,0 +1,57 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; + +using Stride.Core; + +namespace Stride.Rendering; + +[DataContract] +public record struct ParameterKeyInfo(ParameterKey Key, int Offset, int Count, int BindingSlot) : IEquatable +{ + public const int Invalid = -1; + #region Convenience properties + + public readonly bool IsValueParameter => Offset != Invalid; + + public readonly bool IsResourceParameter => BindingSlot != Invalid; + + #endregion + + + public ParameterKeyInfo(ParameterKey key, int offset, int count) : this(key, offset, count, Invalid) + { + } + + public ParameterKeyInfo(ParameterKey key, int bindingSlot) : this(key, Invalid, 1, bindingSlot) + { + Offset = Invalid; + Count = 1; + } + + + // internal readonly ParameterAccessor GetObjectAccessor() + // { + // return new ParameterAccessor(BindingSlot, Count); + // } + + // internal readonly ParameterAccessor GetValueAccessor() + // { + // return new ParameterAccessor(Offset, Count); + // } + + + /// + public override readonly string ToString() + { + if (Key is null) + return "Invalid Parameter Key"; + + return IsResourceParameter + ? $"Object \"{Key}\" at Binding Slot {BindingSlot}" + : $"Value \"{Key}\" at Offset {Offset}" + (Count > 1 + ? $" (Count {Count})" + : string.Empty); + } +} \ No newline at end of file From b15d7d0b14c137689d051b6e99abd91f8cad87e9 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 Feb 2026 16:01:48 +0100 Subject: [PATCH 0766/1182] added DXC submodule --- .gitmodules | 3 +++ submodules/DirectXShaderCompiler | 1 + 2 files changed, 4 insertions(+) create mode 160000 submodules/DirectXShaderCompiler diff --git a/.gitmodules b/.gitmodules index 6b8d134039..69d3201fa8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "submodules/SpirvRegistry"] path = submodules/SpirvRegistry url = https://github.com/KhronosGroup/Registry-Root-SPIR-V +[submodule "submodules/DirectXShaderCompiler"] + path = submodules/DirectXShaderCompiler + url = https://github.com/microsoft/DirectXShaderCompiler diff --git a/submodules/DirectXShaderCompiler b/submodules/DirectXShaderCompiler new file mode 160000 index 0000000000..83e35657fb --- /dev/null +++ b/submodules/DirectXShaderCompiler @@ -0,0 +1 @@ +Subproject commit 83e35657fb2c606e1c60ba0c741e5b60913b6735 From b8fb42927a34d203660f647dfa4797f711716f64 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 Feb 2026 16:01:53 +0100 Subject: [PATCH 0767/1182] ParserCode --- .../IntrinsicGenerator.cs | 25 ++ .../Intrinsics/Goal.md | 86 +++++ .../Intrinsics/IntrinAST.cs | 62 ++++ .../Intrinsics/Parser.cs | 336 ++++++++++++++++++ .../Stride.Shaders.Generators.csproj | 4 + .../Core/IntrinsicsParameters.cs | 25 ++ src/Stride.Shaders/Stride.Shaders.csproj | 3 + 7 files changed, 541 insertions(+) create mode 100644 src/Stride.Shaders.Generators/IntrinsicGenerator.cs create mode 100644 src/Stride.Shaders.Generators/Intrinsics/Goal.md create mode 100644 src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs create mode 100644 src/Stride.Shaders.Generators/Intrinsics/Parser.cs create mode 100644 src/Stride.Shaders/Core/IntrinsicsParameters.cs diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs new file mode 100644 index 0000000000..a150de61bb --- /dev/null +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -0,0 +1,25 @@ +using Microsoft.CodeAnalysis; +using Stride.Shaders.Generators.Intrinsics; + +namespace Stride.Shaders.Generators; + +[Generator] +internal class IntrinsicsGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var file = + context + .AdditionalTextsProvider + .Where(x => x.Path.EndsWith("gen_intrin_main.txt")) + .SelectMany(ParseInstrinsics); + } + + + static List ParseInstrinsics(AdditionalText text, CancellationToken ct) + { + var scanner = new Scanner(text.GetText(ct)?.ToString() ?? ""); + + return null!; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Intrinsics/Goal.md b/src/Stride.Shaders.Generators/Intrinsics/Goal.md new file mode 100644 index 0000000000..c1177b5feb --- /dev/null +++ b/src/Stride.Shaders.Generators/Intrinsics/Goal.md @@ -0,0 +1,86 @@ +# Xen's Idea + +```csharp +using System; +using System.Collections.Generic; + +//Source: +//namespace Intrinsics { +//void [[]] clip(in float<> x); +//void [[]] clip2(in float<2> x); +//$type1 [[rn]] cos(in float_like<> x); +//} + +// becomes => + +// === definitions (incomplete) === +enum ParameterKind { In, Out }; +enum BaseType { Void, Any, Float, FloatLike, Numeric, Match }; + +record struct ParameterType(BaseType BaseType, int? VectorSize = null, (int, int)? Match = null) +{ + public static ParameterType NewMatch(int a, int b) => new ParameterType(BaseType.Match, Match: (a, b)); +} + +// Note: VectorSize null means not a vector, 0 means <> (any size) and a specific size means <{specific size}> +record struct Parameter(ParameterKind Kind, ParameterType Type, string Name); + +// Note: I think we can ignroe attributes in [[]] and operand details (like ": reinterpret_fuse_double") +record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) +{ + public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan parameters) + : this(@return, parameters.ToArray()) + {} +} + +// =========== +// PHASE1 (for matching intrinsics in PrimaryExpressionParsers.cs) and as helper in various method such as texture method processing in AccessChainExpression: +// (then we can just use IntrinsicDefinition in the code) +class Definitions +{ + public Dictionary Intrinsics = new + { + ["clip"] = new[] { new IntrinsicDefinition(new ParameterType(BaseType.Void), new Parameter(ParameterKind.In, new(BaseType.Float, 0), "x")) }, + ["clip2"] = new[] { new IntrinsicDefinition(new ParameterType(BaseType.Void), new Parameter(ParameterKind.In, new(BaseType.Float, 2), "x")) }, + // Note: $type1 => $match(1,1) (cf gen_intrin_main.txt) + ["cos"] = new[] { new IntrinsicDefinition(ParameterType.NewMatch(1, 1), new Parameter(ParameterKind.In, new(BaseType.FloatLike), "x")) }, + }; + public Dictionary Texture1DMethods = new + { + ["GetDimensions"] = new[] + { + // Multiple overloads + new IntrinsicDefinition(new ParameterType(BaseType.Void), new Parameter(ParameterKind.In, BaseType.UInt, "x"), new Parameter(ParameterKind.Out, new(BaseType.UIntOnly), "width"), new Parameter(ParameterKind.Out, ParameterType.NewMatch(2, 2), "levels")), + new IntrinsicDefinition(new ParameterType(BaseType.Void), new Parameter(ParameterKind.In, BaseType.UInt, "x"), new Parameter(ParameterKind.Out, new(BaseType.FloatLike), "width"), new Parameter(ParameterKind.Out, ParameterType.NewMatch(2, 2), "levels")), + } + }; +} + +// ==================== +// PHASE2 (optional, TBD) +// Later, we could even generate helpers so that all types arrive properly in intrinsics stub, i.e. +public partial class Exp : MethodCall +{ + public void ProcessSymbol() + { + // Here we can auto generate output type based on definition + } + + public void Compile(SpirvBuilder builder) + { + // Auto generate parameters + x = Parameters[0]; + x = builder.Convert(Float); + return CompileImpl(builder, x) + } + + partial SpirvValue CompileImpl(SpirvBuilder builder, SpirvValue x) +} + +//Then we only need to do this manually: +partial class Exp +{ + partial SpirvValue CompileImpl(SpirvBuilder builder, SpirvValue x) => builder.Insert(new GLSLExp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); +} + +``` \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs new file mode 100644 index 0000000000..9629f827fa --- /dev/null +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -0,0 +1,62 @@ + +using System.Collections; + +namespace Stride.Shaders.Generators.Intrinsics; + +// \[\[[attr]\]\] ([ [, ... ]]) [ : ] + +internal abstract record Node(TextLocation Location); + +internal record Identifier(string Name, TextLocation Location) : Node(Location); + + +internal record Attributes(string[] Values, TextLocation Location) : Node(Location); + + +internal record Layout(string Size1, string? Size2, TextLocation Location) : Node(Location); + +internal record Typename(string Name, Layout? Size, TextLocation Location) : Node(Location); +internal record NumericType(Layout Size, TextLocation Location) : Typename("numeric", Size, Location); + +internal record Matching(int ComponentA, int ComponentB, TextLocation Location) : Node(Location); +internal record ClassTMatch(TextLocation Location) : Matching(-1, 0,Location); +internal record FuncMatch(TextLocation Location) : Matching(-3, 0, Location); +internal record Func2Match(TextLocation Location) : Matching(-3, 0, Location); +internal record TypeMatch(int ComponentA, TextLocation Location) : Matching(ComponentA, ComponentA, Location); + + +internal record TypeInfo(Typename Typename, TextLocation Location, Matching? Match = null) : Node(Location); +internal record IntrinsicOp(string Operator, TextLocation Location) : Node(Location); +internal record ArgumentQualifier(string Qualifier, TextLocation Location, string? OptionalQualifier = null) : Node(Location); + +internal record ArgumentParameter(ArgumentQualifier Qualifier, TypeInfo TypeInfo, Identifier Name, TextLocation Location) : Node(Location); + +internal record IntrinsicDeclaration(Identifier Name, TypeInfo ReturnType, EquatableList Parameters, TextLocation Location, Attributes? Attributes = null, IntrinsicOp? Operator = null) : Node(Location); + +internal record NamespaceDeclaration(Identifier Name, EquatableList Intrinsics, TextLocation Location) : Node(Location); + + + +internal readonly struct EquatableList(List items) +{ + public List Items { get; } = items; + + public readonly override bool Equals(object? obj) + { + if (obj is EquatableList other) + return Items.SequenceEqual(other.Items); + return false; + } + + public readonly override int GetHashCode() + { + int hash = 17; + foreach (var item in Items) + hash = hash * 31 + (item?.GetHashCode() ?? 0); + return hash; + } + public void Deconstruct(out List items) => items = Items; + + public List.Enumerator GetEnumerator() + => Items.GetEnumerator(); +} diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs new file mode 100644 index 0000000000..d932a774eb --- /dev/null +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -0,0 +1,336 @@ +namespace Stride.Shaders.Generators.Intrinsics; + +using System; + +internal record struct TextLocation(string Code, Range Range); + +internal ref struct Scanner(string code) +{ + internal readonly string Code { get; } = code; + internal int Position { get; private set; } = 0; + internal readonly bool EOF => Position >= Code.Length; + + internal readonly char Peek => Position < Code.Length ? Code[Position] : '\0'; + + internal Stack Errors { get; } = []; + + internal void Advance(int size = 1) => Position += size; + internal bool Backtrack(int position) + { + Position = position; + return false; + } + internal bool Backtrack(int position, out T value) + { + Position = position; + value = default!; + return false; + } + + internal readonly bool Success() + { + return true; + } + + internal bool Match(ReadOnlySpan expected, bool advance = false) + { + if (Code.AsSpan(Position).StartsWith(expected, StringComparison.Ordinal)) + { + if (advance) + Advance(expected.Length); + return true; + } + return false; + } + internal bool MatchLetter(bool advance = false) + { + if (Position < Code.Length && char.IsLetter(Peek)) + { + if (advance) + Advance(1); + return true; + } + return false; + } + internal bool MatchDigit(bool advance = false) => MatchDigit(0..9, advance); + internal bool MatchDigit(Range range, bool advance = false) + { + if (Position < Code.Length && char.IsDigit(Peek)) + { + if (advance) + Advance(1); + return true; + } + return false; + } + internal bool MatchLetterOrDigit(bool advance = false) + { + if (MatchLetter(advance)) + return true; + else if (MatchDigit(advance)) + return true; + else return false; + } + + internal bool MatchWhiteSpace(int minimum = 0, bool advance = false) + { + var start = Position; + while (Position < Code.Length && char.IsWhiteSpace(Peek)) + Position++; + if (Position - start >= minimum) + { + if (!advance) + Backtrack(start); + return true; + } + else return Backtrack(start); + } + + internal bool FollowedBy(ReadOnlySpan expected, bool advance = false) + { + var start = Position; + if (MatchWhiteSpace(advance: true) && Match(expected, advance: false)) + { + if (advance) + Advance(expected.Length); + else + Position = start; + return true; + } + return Backtrack(start); + } + + internal bool AnyUntil(ReadOnlySpan expected, bool advance = false) + { + var start = Position; + while (Position < Code.Length && !Match(expected, advance: false)) + Advance(1); + if (Position < Code.Length) + { + if (advance) + Advance(expected.Length); + return true; + } + return Backtrack(start); + } + internal bool AnyOf(out string matched, bool advance = false, params ReadOnlySpan expected) + { + var start = Position; + foreach (var exp in expected) + { + if (Match(exp, advance)) + { + matched = exp; + return true; + } + } + return Backtrack(start, out matched); + } +} + + + +internal static class ParsersExtensions +{ + internal static bool Identifier(this ref Scanner scanner, out Identifier identifier) + { + var position = scanner.Position; + if (scanner.MatchLetter() || scanner.Match("_")) + { + scanner.Advance(); + while (scanner.MatchLetterOrDigit() || scanner.Match("_")) + scanner.Advance(); + + var name = scanner.Code[position..scanner.Position]; + identifier = new Identifier(name.ToString(), new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + return scanner.Backtrack(position, out identifier); + } + + internal static bool ArgumentQualifier(this ref Scanner scanner, out ArgumentQualifier qualifier) + { + var position = scanner.Position; + if (scanner.AnyOf(out var matched, advance: true, "in", "out", "inout")) + { + var tmp = scanner.Position; + scanner.MatchWhiteSpace(); + if (scanner.AnyOf(out var optionalQualifier, advance: true, "row_major", "col_major")) + { + qualifier = new ArgumentQualifier(matched, new TextLocation(scanner.Code, position..scanner.Position), optionalQualifier); + return scanner.Success(); + } + else scanner.Backtrack(tmp); + qualifier = new ArgumentQualifier(matched, new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + return scanner.Backtrack(position, out qualifier); + } + + internal static bool TypeMatching(this ref Scanner scanner, out Matching typeInfo) + { + var position = scanner.Position; + if (scanner.Match("$classT", true)) + { + typeInfo = new ClassTMatch(new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + else if (scanner.Match("$funcT", true)) + { + typeInfo = new FuncMatch(new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + else if (scanner.Match("$funcT2", true)) + { + typeInfo = new Func2Match(new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + else if (scanner.Match("$type", true)) + { + var tmpPos = scanner.Position; + while (scanner.MatchDigit(true)) ; + int component = int.Parse(scanner.Code[tmpPos..scanner.Position]); + typeInfo = new TypeMatch(component, new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + else if (scanner.Match("$match<", true)) + { + var tmpPos1 = scanner.Position; + while (scanner.MatchDigit(true)) ; + int componentA = int.Parse(scanner.Code[tmpPos1..scanner.Position]); + scanner.MatchWhiteSpace(); + if (scanner.Match(",", true)) + { + scanner.MatchWhiteSpace(); + var tmpPos2 = scanner.Position; + while (scanner.MatchDigit(true)) ; + int componentB = int.Parse(scanner.Code[tmpPos2..scanner.Position]); + scanner.MatchWhiteSpace(); + if (scanner.Match(">", true)) + { + typeInfo = new Matching(componentA, componentB, new TextLocation(scanner.Code, position..scanner.Position)); + return scanner.Success(); + } + else return scanner.Backtrack(position, out typeInfo); + } + else return scanner.Backtrack(position, out typeInfo); + } + else return scanner.Backtrack(position, out typeInfo); + } + + internal static bool TypeInfo(this ref Scanner scanner, out TypeInfo typeInfo) + { + var position = scanner.Position; + if (scanner.TypeMatching(out var typematch)) + { + if(typematch is ClassTMatch or FuncMatch or Func2Match) + { + typeInfo = new TypeInfo(new Typename("void", null, new TextLocation(scanner.Code, position..scanner.Position)), new TextLocation(scanner.Code, position..scanner.Position), typematch); + return scanner.Success(); + } + else if(typematch is TypeMatch tm) + { + typeInfo = new TypeInfo(new Typename("$to_resolve", null, new TextLocation(scanner.Code, position..scanner.Position)), new TextLocation(scanner.Code, position..scanner.Position), typematch); + return scanner.Success(); + } + } + return scanner.Backtrack(position, out typeInfo); + } + + internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) + { + var position = scanner.Position; + if (scanner.Match("<", true)) + { + scanner.MatchWhiteSpace(); + var size1Pos = scanner.Position; + while (scanner.MatchLetterOrDigit(true)) ; + var size1 = scanner.Code[size1Pos..scanner.Position].ToString(); + scanner.MatchWhiteSpace(); + if (scanner.Match(",", true)) + { + scanner.MatchWhiteSpace(); + var size2Pos = scanner.Position; + while (scanner.MatchLetterOrDigit(true)) ; + var size2 = scanner.Code[size2Pos..scanner.Position].ToString(); + scanner.MatchWhiteSpace(); + } + if (scanner.Match(">", true)) + { + layout = new Layout(size1, null, new TextLocation(scanner.Code, position..scanner.Position)); + return true; + } + else return scanner.Backtrack(position, out layout); + } + return scanner.Backtrack(position, out layout); + } + internal static bool Typename(this ref Scanner scanner, out Typename typename) + { + var position = scanner.Position; + if (scanner.Identifier(out var id)) + { + scanner.MatchWhiteSpace(); + if (scanner.LayoutSize(out var layout)) + { + typename = new Typename(id.Name, layout, new TextLocation(scanner.Code, position..scanner.Position)); + return true; + } + else + { + typename = new Typename(id.Name, null, new TextLocation(scanner.Code, position..scanner.Position)); + return true; + } + } + typename = null!; + return false; + } + + internal static bool IntrinsicOp(this ref Scanner scanner, out IntrinsicOp intrinsicOp) + { + var position = scanner.Position; + if (scanner.Match(":", true)) + { + scanner.MatchWhiteSpace(); + if (scanner.Identifier(out var id) && scanner.FollowedBy(";", advance: true)) + { + intrinsicOp = new IntrinsicOp(id.Name, new TextLocation(scanner.Code, position..scanner.Position)); + return true; + } + else + return scanner.Backtrack(position, out intrinsicOp); + } + return scanner.Backtrack(position, out intrinsicOp); + } + + internal static bool Attribute(this ref Scanner scanner, out Attributes attributes) + { + var position = scanner.Position; + if (scanner.Match("[[", true)) + { + var attributeStart = scanner.Position; + scanner.MatchWhiteSpace(); + if (scanner.AnyUntil("]]", true)) + { + attributes = new(scanner.Code[attributeStart..(scanner.Position - 2)].ToString().Split(','), new(scanner.Code, position..scanner.Position)); + } + else if (scanner.Match("]]", true)) + { + attributes = new(Array.Empty(), new(scanner.Code, position..scanner.Position)); + return true; + } + else return scanner.Backtrack(position, out attributes); + + } + return scanner.Backtrack(position, out attributes); + } +} + +static class Machin +{ + static void Main() + { + var scanner = new Scanner("hello world"); + + + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index b8d19916eb..a53ae771c5 100644 --- a/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -11,6 +11,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/src/Stride.Shaders/Core/IntrinsicsParameters.cs b/src/Stride.Shaders/Core/IntrinsicsParameters.cs new file mode 100644 index 0000000000..ff626fdbc3 --- /dev/null +++ b/src/Stride.Shaders/Core/IntrinsicsParameters.cs @@ -0,0 +1,25 @@ +namespace Stride.Shaders.Core; + + +internal enum ParameterKind { In, Out }; +internal enum BaseType { Void, Any, Float, FloatLike, Numeric, Match }; + +internal record struct ParameterType(BaseType BaseType, int? VectorSize = null, (int, int)? Match = null) +{ + public static ParameterType NewMatch(int a, int b) => new ParameterType(BaseType.Match, Match: (a, b)); +} + +internal record struct Parameter(ParameterKind Kind, ParameterType Type, string Name); + +internal record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) +{ + public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan parameters) + : this(@return, parameters.ToArray()) + {} +} + + +internal static partial class IntrinsicsDefinitions +{ + +} \ No newline at end of file diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 8455ca4beb..4a3b258485 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -10,6 +10,9 @@ + + + From a49fffa87f82e406a8c3740bdc013646d878c740 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Sun, 1 Feb 2026 23:03:22 +0100 Subject: [PATCH 0768/1182] testing parser --- src/Stride.Shaders.Experiments/Program.cs | 31 ++- .../Stride.Shaders.Experiments.csproj | 5 + .../Intrinsics/IntrinAST.cs | 10 +- .../Intrinsics/Parser.cs | 189 +++++++++++++++--- 4 files changed, 195 insertions(+), 40 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 59326f7f34..72bee65f27 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -7,23 +7,32 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders; -Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); -// Examples.CompileSDSL("RenderTests/If"); +// Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); -//Examples.CompileSDSL(); -var loader = new Examples.ShaderLoader(); -loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); -var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); +// // Examples.CompileSDSL("RenderTests/If"); -using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); -var source = Spv.Dis(buffer); -File.WriteAllText("test.spvdis", source); +// //Examples.CompileSDSL(); +// var loader = new Examples.ShaderLoader(); +// loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); +// var shaderMixer = new ShaderMixer(loader); +// shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); + +// using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); +// var source = Spv.Dis(buffer); +// File.WriteAllText("test.spvdis", source); // Examples.TryAllFiles(); // Examples.CreateShader(); // Examples.GenerateSpirv(); -// Examples.CreateNewShader(); \ No newline at end of file +// Examples.CreateNewShader(); + + +Directory.SetCurrentDirectory(@"C:\Users\kafia\source\repos\SDSL\"); + +var file = string.Join("\n", File.ReadLines(@".\submodules\DirectXShaderCompiler\utils\hct\gen_intrin_main.txt").Where(x => !x.StartsWith("//"))); + +Stride.Shaders.Generators.Intrinsics.IntrinParser.Parse(file, out var result); +Console.WriteLine(result); \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index 4f444c2a9c..5ff0a50f90 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -24,4 +24,9 @@ + + + + + diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs index 9629f827fa..56c2737227 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -1,5 +1,6 @@ using System.Collections; +using System.Runtime.CompilerServices; namespace Stride.Shaders.Generators.Intrinsics; @@ -29,14 +30,19 @@ internal record TypeInfo(Typename Typename, TextLocation Location, Matching? Mat internal record IntrinsicOp(string Operator, TextLocation Location) : Node(Location); internal record ArgumentQualifier(string Qualifier, TextLocation Location, string? OptionalQualifier = null) : Node(Location); -internal record ArgumentParameter(ArgumentQualifier Qualifier, TypeInfo TypeInfo, Identifier Name, TextLocation Location) : Node(Location); +internal record IntrinsicParameter(ArgumentQualifier? Qualifier, TypeInfo TypeInfo, Identifier Name, TextLocation Location) : Node(Location); -internal record IntrinsicDeclaration(Identifier Name, TypeInfo ReturnType, EquatableList Parameters, TextLocation Location, Attributes? Attributes = null, IntrinsicOp? Operator = null) : Node(Location); +internal record IntrinsicDeclaration(Identifier Name, TypeInfo ReturnType, EquatableList Parameters, TextLocation Location, Attributes? Attributes = null, IntrinsicOp? Operator = null) : Node(Location); internal record NamespaceDeclaration(Identifier Name, EquatableList Intrinsics, TextLocation Location) : Node(Location); +static class EquatableListBuilder +{ + public static EquatableList Create(ReadOnlySpan items) => new([..items]); +} +[CollectionBuilder(typeof(EquatableListBuilder), "Create")] internal readonly struct EquatableList(List items) { public List Items { get; } = items; diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs index d932a774eb..3f39e41003 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -1,6 +1,7 @@ namespace Stride.Shaders.Generators.Intrinsics; using System; +using System.Text.Json; internal record struct TextLocation(string Code, Range Range); @@ -151,10 +152,11 @@ internal static bool Identifier(this ref Scanner scanner, out Identifier identif internal static bool ArgumentQualifier(this ref Scanner scanner, out ArgumentQualifier qualifier) { var position = scanner.Position; - if (scanner.AnyOf(out var matched, advance: true, "in", "out", "inout")) + if (scanner.AnyOf(out var matched, advance: true, "inout", "in", "out", "ref")) { var tmp = scanner.Position; - scanner.MatchWhiteSpace(); + if (!scanner.MatchWhiteSpace(1, true)) + return scanner.Backtrack(position, out qualifier); if (scanner.AnyOf(out var optionalQualifier, advance: true, "row_major", "col_major")) { qualifier = new ArgumentQualifier(matched, new TextLocation(scanner.Code, position..scanner.Position), optionalQualifier); @@ -198,14 +200,14 @@ internal static bool TypeMatching(this ref Scanner scanner, out Matching typeInf var tmpPos1 = scanner.Position; while (scanner.MatchDigit(true)) ; int componentA = int.Parse(scanner.Code[tmpPos1..scanner.Position]); - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); if (scanner.Match(",", true)) { - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); var tmpPos2 = scanner.Position; while (scanner.MatchDigit(true)) ; int componentB = int.Parse(scanner.Code[tmpPos2..scanner.Position]); - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); if (scanner.Match(">", true)) { typeInfo = new Matching(componentA, componentB, new TextLocation(scanner.Code, position..scanner.Position)); @@ -223,16 +225,31 @@ internal static bool TypeInfo(this ref Scanner scanner, out TypeInfo typeInfo) var position = scanner.Position; if (scanner.TypeMatching(out var typematch)) { - if(typematch is ClassTMatch or FuncMatch or Func2Match) + if (typematch is ClassTMatch or FuncMatch or Func2Match) { typeInfo = new TypeInfo(new Typename("void", null, new TextLocation(scanner.Code, position..scanner.Position)), new TextLocation(scanner.Code, position..scanner.Position), typematch); return scanner.Success(); } - else if(typematch is TypeMatch tm) + else if (typematch is TypeMatch tm) { typeInfo = new TypeInfo(new Typename("$to_resolve", null, new TextLocation(scanner.Code, position..scanner.Position)), new TextLocation(scanner.Code, position..scanner.Position), typematch); return scanner.Success(); } + else if (typematch is Matching m) + { + scanner.MatchWhiteSpace(advance: true); + if (scanner.Typename(out var typename)) + { + typeInfo = new TypeInfo(typename, new TextLocation(scanner.Code, position..scanner.Position), typematch); + return scanner.Success(); + } + else return scanner.Backtrack(position, out typeInfo); + } + } + else if (scanner.Typename(out var typename)) + { + typeInfo = new TypeInfo(typename, new TextLocation(scanner.Code, position..scanner.Position), null); + return scanner.Success(); } return scanner.Backtrack(position, out typeInfo); } @@ -242,18 +259,18 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) var position = scanner.Position; if (scanner.Match("<", true)) { - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); var size1Pos = scanner.Position; while (scanner.MatchLetterOrDigit(true)) ; var size1 = scanner.Code[size1Pos..scanner.Position].ToString(); - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); if (scanner.Match(",", true)) { - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); var size2Pos = scanner.Position; while (scanner.MatchLetterOrDigit(true)) ; var size2 = scanner.Code[size2Pos..scanner.Position].ToString(); - scanner.MatchWhiteSpace(); + scanner.MatchWhiteSpace(advance: true); } if (scanner.Match(">", true)) { @@ -269,7 +286,8 @@ internal static bool Typename(this ref Scanner scanner, out Typename typename) var position = scanner.Position; if (scanner.Identifier(out var id)) { - scanner.MatchWhiteSpace(); + var tmpPos = scanner.Position; + scanner.MatchWhiteSpace(advance: true); if (scanner.LayoutSize(out var layout)) { typename = new Typename(id.Name, layout, new TextLocation(scanner.Code, position..scanner.Position)); @@ -277,6 +295,7 @@ internal static bool Typename(this ref Scanner scanner, out Typename typename) } else { + scanner.Backtrack(tmpPos); typename = new Typename(id.Name, null, new TextLocation(scanner.Code, position..scanner.Position)); return true; } @@ -290,8 +309,8 @@ internal static bool IntrinsicOp(this ref Scanner scanner, out IntrinsicOp intri var position = scanner.Position; if (scanner.Match(":", true)) { - scanner.MatchWhiteSpace(); - if (scanner.Identifier(out var id) && scanner.FollowedBy(";", advance: true)) + scanner.MatchWhiteSpace(advance: true); + if (scanner.Identifier(out var id)) { intrinsicOp = new IntrinsicOp(id.Name, new TextLocation(scanner.Code, position..scanner.Position)); return true; @@ -302,35 +321,151 @@ internal static bool IntrinsicOp(this ref Scanner scanner, out IntrinsicOp intri return scanner.Backtrack(position, out intrinsicOp); } - internal static bool Attribute(this ref Scanner scanner, out Attributes attributes) + internal static bool Attributes(this ref Scanner scanner, out Attributes attributes) { var position = scanner.Position; if (scanner.Match("[[", true)) { var attributeStart = scanner.Position; - scanner.MatchWhiteSpace(); - if (scanner.AnyUntil("]]", true)) + scanner.MatchWhiteSpace(advance: true); + if (scanner.AnyUntil("]]")) { + if (scanner.EOF || !scanner.Match("]]", true)) + return scanner.Backtrack(position, out attributes); attributes = new(scanner.Code[attributeStart..(scanner.Position - 2)].ToString().Split(','), new(scanner.Code, position..scanner.Position)); + return scanner.Success(); } - else if (scanner.Match("]]", true)) + } + return scanner.Backtrack(position, out attributes); + } + + internal static bool IntrinsicParameter(this ref Scanner scanner, out IntrinsicParameter parameter) + { + var position = scanner.Position; + parameter = new(null, null!, null!, new()); + if(scanner.Match("...", true)) + { + parameter = parameter with { Name = new Identifier("...", new TextLocation(scanner.Code, position..scanner.Position)), Location = new TextLocation(scanner.Code, position..scanner.Position) }; + return scanner.Success(); + } + if (scanner.ArgumentQualifier(out var qualifier)) + { + parameter = parameter with { Qualifier = qualifier }; + if (!scanner.MatchWhiteSpace(1, advance: true)) + return scanner.Backtrack(position, out parameter); + } + if (scanner.TypeInfo(out var typeInfo)) + { + parameter = parameter with { TypeInfo = typeInfo }; + if (!scanner.MatchWhiteSpace(1, advance: true)) + return scanner.Backtrack(position, out parameter); + if (scanner.Identifier(out var name)) { - attributes = new(Array.Empty(), new(scanner.Code, position..scanner.Position)); - return true; + parameter = parameter with { Name = name, Location = new TextLocation(scanner.Code, position..scanner.Position) }; + return scanner.Success(); } - else return scanner.Backtrack(position, out attributes); + else return scanner.Backtrack(position, out parameter); + } + else return scanner.Backtrack(position, out parameter); + } + + internal static bool IntrinsicDeclaration(this ref Scanner scanner, out IntrinsicDeclaration intrinsic) + { + var position = scanner.Position; + intrinsic = new(null!, null!, [], new()); + if (scanner.TypeInfo(out var returnType)) + { + intrinsic = intrinsic with { ReturnType = returnType }; + if (!scanner.MatchWhiteSpace(1, true)) + return scanner.Backtrack(position, out intrinsic); + if (scanner.Attributes(out var attributes)) + { + intrinsic = intrinsic with { Attributes = attributes }; + if (!scanner.MatchWhiteSpace(1, true)) + return scanner.Backtrack(position, out intrinsic); + } + + if (scanner.Identifier(out var name)) + { + scanner.MatchWhiteSpace(advance: true); + if (scanner.Match("(", true)) + { + do + { + scanner.MatchWhiteSpace(advance: true); + scanner.IntrinsicParameter(out var parameter); + scanner.MatchWhiteSpace(advance: true); + intrinsic.Parameters.Items.Add(parameter); + } + while (!scanner.EOF && scanner.Match(",", true)); + if (scanner.EOF || !scanner.Match(")", true)) + return scanner.Backtrack(position, out intrinsic); + scanner.MatchWhiteSpace(advance: true); + if (scanner.IntrinsicOp(out var op)) + intrinsic = intrinsic with { Location = new TextLocation(scanner.Code, position..scanner.Position), Operator = op }; + if (!scanner.FollowedBy(";", advance: true)) + return scanner.Backtrack(position, out intrinsic); + return scanner.Success(); + } + } } - return scanner.Backtrack(position, out attributes); + return scanner.Backtrack(position, out intrinsic); + } + + internal static bool NamespaceDeclaration(this ref Scanner scanner, out NamespaceDeclaration namespaceDecl) + { + var position = scanner.Position; + namespaceDecl = new(null!, [], new()); + if (scanner.Match("namespace", true)) + { + scanner.MatchWhiteSpace(1, true); + if (scanner.Identifier(out var name)) + { + scanner.MatchWhiteSpace(advance: true); + if (scanner.Match("{", true)) + { + scanner.MatchWhiteSpace(advance: true); + while (!scanner.EOF && scanner.IntrinsicDeclaration(out var intrinsic)) + { + namespaceDecl.Intrinsics.Items.Add(intrinsic); + scanner.MatchWhiteSpace(advance: true); + } + if (scanner.EOF || !(scanner.Match("}", true) && scanner.FollowedBy("namespace", advance: true))) + return scanner.Backtrack(position, out namespaceDecl); + namespaceDecl = namespaceDecl with { Name = name, Location = new TextLocation(scanner.Code, position..scanner.Position) }; + return scanner.Success(); + } + } + } + return scanner.Backtrack(position, out namespaceDecl); + } + internal static bool IntrinsicFile(this ref Scanner scanner, out EquatableList namespaces) + { + var position = scanner.Position; + namespaces = []; + scanner.MatchWhiteSpace(advance: true); + while (!scanner.EOF && scanner.NamespaceDeclaration(out var namespaceDecl)) + { + namespaces.Items.Add(namespaceDecl); + scanner.MatchWhiteSpace(advance: true); + } + return scanner.Success(); } } -static class Machin +public static class IntrinParser { - static void Main() + public static bool Parse(string code, out string result) { - var scanner = new Scanner("hello world"); - - + var scanner = new Scanner(code); + var parsed = scanner.IntrinsicFile(out var ns); + if (!scanner.EOF) + { + result = $"error -> {scanner.Code[scanner.Position..Math.Min(scanner.Position + 25, scanner.Code.Length)]}"; + return false; + } + result = JsonSerializer.Serialize(ns, new JsonSerializerOptions { WriteIndented = true }); + return true; } } \ No newline at end of file From 70b7f5b93fff72cb8f82d13173f2cdb022b1ce52 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Mon, 2 Feb 2026 02:49:32 +0100 Subject: [PATCH 0769/1182] working on effect interpreter --- src/Stride.Shaders.Experiments/Program.cs | 11 +--- .../Stride.Shaders.Experiments.csproj | 6 -- .../IntrinsicGenerator.cs | 50 ++++++++++++-- .../Intrinsics/IntrinAST.cs | 3 +- .../Intrinsics/Parser.cs | 66 +++++++++++++++---- .../Spirv/Building/BasicBlocks.cs | 2 +- 6 files changed, 105 insertions(+), 33 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 72bee65f27..65ea683dd3 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -6,6 +6,7 @@ using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders; +using System.Text.Json; // Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); @@ -27,12 +28,4 @@ // Examples.CreateShader(); // Examples.GenerateSpirv(); -// Examples.CreateNewShader(); - - -Directory.SetCurrentDirectory(@"C:\Users\kafia\source\repos\SDSL\"); - -var file = string.Join("\n", File.ReadLines(@".\submodules\DirectXShaderCompiler\utils\hct\gen_intrin_main.txt").Where(x => !x.StartsWith("//"))); - -Stride.Shaders.Generators.Intrinsics.IntrinParser.Parse(file, out var result); -Console.WriteLine(result); \ No newline at end of file +// Examples.CreateNewShader(); \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index 5ff0a50f90..ef8b8ed80b 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -23,10 +23,4 @@ - - - - - - diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index a150de61bb..a8bba30ed4 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -1,4 +1,7 @@ +using System.Text; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; using Stride.Shaders.Generators.Intrinsics; namespace Stride.Shaders.Generators; @@ -8,18 +11,55 @@ internal class IntrinsicsGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { - var file = + var file = context .AdditionalTextsProvider .Where(x => x.Path.EndsWith("gen_intrin_main.txt")) - .SelectMany(ParseInstrinsics); + .Select(ParseInstrinsics); + + context.RegisterSourceOutput(file, GenerateIntrinsicsData); } - static List ParseInstrinsics(AdditionalText text, CancellationToken ct) + static void GenerateIntrinsicsData(SourceProductionContext spc, EquatableList ns) { - var scanner = new Scanner(text.GetText(ct)?.ToString() ?? ""); + var builder = new StringBuilder(); + + builder.AppendLine(""" + namespace Stride.Shaders.Core; + + internal static partial class IntrinsicsDefinitions + { + """); + + if (ns.Items.Count == 0) + builder.AppendLine("// No intrinsics parsed"); + foreach (var n in ns) + { + builder.AppendLine($"internal static Dictionary {n.Name.Name} = new()") + .AppendLine("{"); + foreach (var intrin in n.Intrinsics) + builder.AppendLine($"[\"{intrin.Name.Name}\"] = [],"); + builder.AppendLine("};"); + } + builder.AppendLine("}"); - return null!; + spc.AddSource( + "IntrinsicsData.g.cs", + SourceText.From( + SyntaxFactory.ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + + + internal static EquatableList ParseInstrinsics(AdditionalText text, CancellationToken ct) + { + if (IntrinParser.ProcessAndParse(text.GetText()?.ToString() ?? "", out var ns)) + return ns; + else return []; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs index 56c2737227..27f551347c 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -1,12 +1,13 @@ using System.Collections; using System.Runtime.CompilerServices; +using System.Text.Json.Serialization; namespace Stride.Shaders.Generators.Intrinsics; // \[\[[attr]\]\] ([ [, ... ]]) [ : ] -internal abstract record Node(TextLocation Location); +internal abstract record Node([property:JsonIgnore]TextLocation Location); internal record Identifier(string Name, TextLocation Location) : Node(Location); diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs index 3f39e41003..e5f8e09cb2 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -177,14 +177,14 @@ internal static bool TypeMatching(this ref Scanner scanner, out Matching typeInf typeInfo = new ClassTMatch(new TextLocation(scanner.Code, position..scanner.Position)); return scanner.Success(); } - else if (scanner.Match("$funcT", true)) + else if (scanner.Match("$funcT2", true)) { - typeInfo = new FuncMatch(new TextLocation(scanner.Code, position..scanner.Position)); + typeInfo = new Func2Match(new TextLocation(scanner.Code, position..scanner.Position)); return scanner.Success(); } - else if (scanner.Match("$funcT2", true)) + else if (scanner.Match("$funcT", true)) { - typeInfo = new Func2Match(new TextLocation(scanner.Code, position..scanner.Position)); + typeInfo = new FuncMatch(new TextLocation(scanner.Code, position..scanner.Position)); return scanner.Success(); } else if (scanner.Match("$type", true)) @@ -198,6 +198,7 @@ internal static bool TypeMatching(this ref Scanner scanner, out Matching typeInf else if (scanner.Match("$match<", true)) { var tmpPos1 = scanner.Position; + scanner.Match("-", true); while (scanner.MatchDigit(true)) ; int componentA = int.Parse(scanner.Code[tmpPos1..scanner.Position]); scanner.MatchWhiteSpace(advance: true); @@ -205,6 +206,7 @@ internal static bool TypeMatching(this ref Scanner scanner, out Matching typeInf { scanner.MatchWhiteSpace(advance: true); var tmpPos2 = scanner.Position; + scanner.Match("-", true); while (scanner.MatchDigit(true)) ; int componentB = int.Parse(scanner.Code[tmpPos2..scanner.Position]); scanner.MatchWhiteSpace(advance: true); @@ -263,18 +265,19 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) var size1Pos = scanner.Position; while (scanner.MatchLetterOrDigit(true)) ; var size1 = scanner.Code[size1Pos..scanner.Position].ToString(); + string? size2 = null; scanner.MatchWhiteSpace(advance: true); if (scanner.Match(",", true)) { scanner.MatchWhiteSpace(advance: true); var size2Pos = scanner.Position; while (scanner.MatchLetterOrDigit(true)) ; - var size2 = scanner.Code[size2Pos..scanner.Position].ToString(); + size2 = scanner.Code[size2Pos..scanner.Position].ToString(); scanner.MatchWhiteSpace(advance: true); } if (scanner.Match(">", true)) { - layout = new Layout(size1, null, new TextLocation(scanner.Code, position..scanner.Position)); + layout = new Layout(size1, size2, new TextLocation(scanner.Code, position..scanner.Position)); return true; } else return scanner.Backtrack(position, out layout); @@ -388,6 +391,7 @@ internal static bool IntrinsicDeclaration(this ref Scanner scanner, out Intrinsi if (scanner.Identifier(out var name)) { + intrinsic = intrinsic with { Name = name }; scanner.MatchWhiteSpace(advance: true); if (scanner.Match("(", true)) { @@ -454,18 +458,58 @@ internal static bool IntrinsicFile(this ref Scanner scanner, out EquatableList result) + => Parse(PreProcess(code), out result); + + internal static string PreProcess(string code) + => string.Join("\n", code.Split('\n').Where(line => !line.TrimStart().StartsWith("//"))); + internal static bool Parse(string code, out EquatableList result) { var scanner = new Scanner(code); - var parsed = scanner.IntrinsicFile(out var ns); + if(scanner.IntrinsicFile(out var ns)) + { + foreach(var n in ns) + { + for(int i = 0; i < n.Intrinsics.Items.Count; i++) + { + var intrinsic = n.Intrinsics.Items[i]; + if(intrinsic.ReturnType is { Typename.Name: "$to_resolve" }) + { + intrinsic = intrinsic with + { + ReturnType = intrinsic.Parameters.Items[intrinsic.ReturnType.Match is TypeMatch tm ? tm.ComponentA - 1 : 0].TypeInfo + }; + } + for(int j = 0; j < intrinsic.Parameters.Items.Count; j++) + { + var parameter = intrinsic.Parameters.Items[j]; + if(parameter is not null && parameter.TypeInfo is { Typename.Name: "$to_resolve", Match: TypeMatch {ComponentA : >= 0} tm}) + { + parameter = tm switch + { + { ComponentA: 0 } => parameter with { TypeInfo = intrinsic.ReturnType }, + _ => parameter with { TypeInfo = intrinsic.Parameters.Items[tm.ComponentA - 1].TypeInfo } + }; + + intrinsic.Parameters.Items[j] = parameter; + } + } + + n.Intrinsics.Items[i] = intrinsic; + + } + } + } + if (!scanner.EOF) { - result = $"error -> {scanner.Code[scanner.Position..Math.Min(scanner.Position + 25, scanner.Code.Length)]}"; + result = []; return false; } - result = JsonSerializer.Serialize(ns, new JsonSerializerOptions { WriteIndented = true }); + result = ns; return true; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs index a562e406c0..17cf184ca4 100644 --- a/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs +++ b/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Spirv.Building; /// A SPIR-V value representing the result of an instruction /// public struct SpirvValue -{ +{ /// IdResult of the instruction /// IdResultType of the instruction /// Optional name attached to the value From ae4a455c7741f0c367106c2a133067babf6e7acd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 30 Jan 2026 15:21:11 +0900 Subject: [PATCH 0770/1182] Geometry shader --- assets/SDSL/RenderTests/StreamGS.sdsl | 40 ++ .../SDSL/ShaderMixer.CBuffers.cs | 4 +- .../SDSL/ShaderMixer.cs | 26 +- .../SpirvTranslator.cs | 1 - .../Buffers/NewSpirvBuffer.cs | 2 +- .../Extensions/spirv.sdsl.grammar-ext.json | 64 ++- .../FrameRenderer.D3D11.cs | 26 +- src/Stride.Shaders.Tests/RenderingTests.cs | 7 + src/Stride.Shaders/Core/Symbol.cs | 1 + src/Stride.Shaders/Core/SymbolTypes.cs | 61 ++- .../Parsing/Analysis/SymbolTable.cs | 35 +- .../Parsing/SDSL/AST/Expression.cs | 37 ++ .../Parsing/SDSL/AST/Literals.cs | 19 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 8 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 37 +- .../Parsing/SDSL/AST/ShaderElements.cs | 15 +- .../ShaderParsers/ShaderMethodParsers.cs | 2 +- .../Spirv/Building/Builder.Class.cs | 8 +- .../Spirv/Building/Builder.Expressions.cs | 24 +- .../Spirv/Building/Context.Constants.cs | 42 +- .../Spirv/Building/SpirvContext.Types.cs | 155 ++++--- .../Spirv/Processing/InterfaceProcessor.cs | 395 ++++++++++++++---- .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 + 23 files changed, 801 insertions(+), 209 deletions(-) create mode 100644 assets/SDSL/RenderTests/StreamGS.sdsl diff --git a/assets/SDSL/RenderTests/StreamGS.sdsl b/assets/SDSL/RenderTests/StreamGS.sdsl new file mode 100644 index 0000000000..011e612e20 --- /dev/null +++ b/assets/SDSL/RenderTests/StreamGS.sdsl @@ -0,0 +1,40 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) + +namespace Stride.Shaders.Tests; + +shader StreamGS +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + stream float4 ExtraColor : EXTRA_COLOR; + stream float4 ExtraColor2; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + streams.ExtraColor2 = streams.ExtraColor; + } + + [maxvertexcount(3)] + void GSMain(triangle Input input[3], inout PointStream outStream) + { + streams = input[0]; + + streams.ShadingPosition = 0.5f * streams.ShadingPosition; + + outStream.Append(streams); + + for (int i = 0; i < 2; ++i) + { + outStream.Append(streams); + } + + outStream.RestartStrip(); + } + + void PSMain() + { + streams.ColorTarget = streams.ExtraColor2; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 60fc710548..82031d027b 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -44,7 +44,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob return; var globalCBufferType = new ConstantBufferSymbol("Globals", members); - var globalCBufferTypeId = context.DeclareCBuffer(globalCBufferType); + var globalCBufferTypeId = context.DeclareCBuffer(globalCBufferType, context.Bound++); // Transfer metadata from variable to cbuffer member var memberMetadata = new CBufferMemberMetadata[members.Count]; for (var index = 0; index < members.Count; index++) @@ -264,7 +264,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData var structTypes = cbuffers.Select(x => x.StructType); var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); - var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct); + var mergedCbufferStructId = context.DeclareCBuffer(mergedCbufferStruct, context.Bound++); var mergedCbufferPtrStruct = new PointerType(mergedCbufferStruct, Specification.StorageClass.Uniform); var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e07163251f..bfbd0940e1 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -45,6 +45,8 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span var temp = new NewSpirvBuffer(); var context = new SpirvContext(); + context.Add(new OpCapability(Capability.Shader)); + context.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); var shaderLoader = new CaptureLoadedShaders(ShaderLoader); var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; @@ -61,10 +63,24 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); - context.Insert(0, new OpCapability(Capability.Shader)); - context.Insert(1, new OpCapability(Capability.SampledBuffer)); - context.Insert(2, new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); - + // Add optional capabilities + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 0 or 1) + { + context.Add(new OpCapability(Capability.SampledBuffer)); + break; + } + } + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 2) + { + context.Add(new OpCapability(Capability.ImageBuffer)); + break; + } + } + // Process streams and remove unused code/cbuffer/variable/resources var interfaceProcessor = new InterfaceProcessor { @@ -983,7 +999,7 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio // Collect IDs (except for OpName/OpDecorate/OpDecorateString metadata) if (i.Op != Op.OpName && i.Op != Op.OpDecorate && i.Op != Op.OpDecorateString) - SpirvBuilder.CollectIds(i.Data, ids); + SpirvBuilder.CollectIds(i.Data, id => ids.Add(id)); } // Remove unnecessary OpName/OpDecorate/OpDecorateString diff --git a/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/src/Stride.Shaders.Compilers/SpirvTranslator.cs index 7fe801569e..9d23eac64f 100644 --- a/src/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/src/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -45,7 +45,6 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) result.Add((entryPointName, "main", entryPointModel)); } - cross.ContextReleaseAllocations(context); cross.ContextDestroy(context); diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 463f37850c..3a26718c3d 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -368,7 +368,7 @@ public void RemoveRange(int index, int count, bool dispose = true) Instructions.RemoveRange(index, count); } - public void InsertRange(int index, ReadOnlySpan source) + public void InsertRange(int index, params ReadOnlySpan source) { Instructions.InsertRange(index, source); } diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 1ce016b9d3..62573e0095 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -351,7 +351,23 @@ "opname": "OpTypeStreamsSDSL", "class": "Miscellaneous", "operands": [ - { "kind": "IdResult" } + { "kind": "IdResult" }, + { + "kind": "StreamsKindSDSL", + "name": "kind" + } + ] + }, + { + "opname": "OpTypeGeometryStreamOutputSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { + "kind": "GeometryStreamOutputKindSDSL", + "name": "kind" + } ] }, { @@ -383,6 +399,16 @@ "name": "shaderCodeNameEnd" } ] + }, + { + "opname": "OpEmitVertexSDSL", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "Output" + } + ] } ], "operand_kinds": [ @@ -628,6 +654,42 @@ } ] }, + { + "category": "ValueEnum", + "kind": "StreamsKindSDSL", + "enumerants": [ + { + "enumerant": "Input", + "value": 1 + }, + { + "enumerant": "Streams", + "value": 2 + }, + { + "enumerant": "Output", + "value": 3 + } + ] + }, + { + "category": "ValueEnum", + "kind": "GeometryStreamOutputKindSDSL", + "enumerants": [ + { + "enumerant": "Point", + "value": 1 + }, + { + "enumerant": "Line", + "value": 2 + }, + { + "enumerant": "Triangle", + "value": 3 + } + ] + }, { "kind": "ExecutionModel", "enumerants": [ diff --git a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 2ef0c34997..85cd47ee43 100644 --- a/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -35,6 +35,7 @@ public class D3D11FrameRenderer(uint width = 800, uint height = 600, byte[]? fra ComPtr vertexBuffer = default; ComPtr indexBuffer = default; ComPtr vertexShader = default; + ComPtr geometryShader = default; ComPtr pixelShader = default; ComPtr computeShader = default; ComPtr inputLayout = default; @@ -63,6 +64,8 @@ vs_out main(vs_in input) { public string? ComputeShaderSource; + public string? GeometryShaderSource; + //Fragment shaders are run on each fragment/pixel of the geometry. public string PixelShaderSource = @" struct vs_out { @@ -107,7 +110,7 @@ public unsafe ComPtr CompileShader(string shaderModel, string source ( in sourceBytes[0], (nuint)sourceBytes.Length, - nameof(VertexShaderSource), + nameof(source), null, ref Unsafe.NullRef(), "main", @@ -280,6 +283,7 @@ public unsafe void RenderFrame(Span result) BufferDesc bufferDesc; // Compile vertex shader. ComPtr vertexCode = CompileShader("vs_5_0", VertexShaderSource); + ComPtr geometryCode = GeometryShaderSource != null ? CompileShader("gs_5_0", GeometryShaderSource) : null; ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); // Create vertex shader. @@ -293,6 +297,21 @@ ref Unsafe.NullRef(), ref vertexShader ) ); + + // Create geometry shader. + if (geometryCode.Handle != null) + { + SilkMarshal.ThrowHResult + ( + device.CreateGeometryShader + ( + geometryCode.GetBufferPointer(), + geometryCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref geometryShader + ) + ); + } // Create pixel shader. SilkMarshal.ThrowHResult @@ -460,6 +479,8 @@ ref renderTextureStaging // Bind our shaders. deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); + if (geometryShader.Handle != null) + deviceContext.GSSetShader(geometryShader, ref Unsafe.NullRef>(), 0); deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); ApplyParameters(); @@ -542,6 +563,7 @@ private unsafe void ApplyParameters() } deviceContext.CSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.VSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); + deviceContext.GSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.PSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); } else if (resourceType == "buffer") @@ -596,6 +618,7 @@ ref bufferSRV deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); + deviceContext.GSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); } else if (resourceType == "texture") @@ -662,6 +685,7 @@ ref textureSRV deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); + deviceContext.GSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); } } diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 2d35c33471..c98f14b168 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -128,9 +128,14 @@ public void RenderTest1(string shaderName) var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) : null; + var codeGS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Geometry)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Geometry)) + : null; if (codeVS != null) Console.WriteLine(codeVS); + if (codeGS != null) + Console.WriteLine(codeGS); Console.WriteLine(codePS); // Execute test @@ -138,6 +143,8 @@ public void RenderTest1(string shaderName) if (codeVS != null) renderer.VertexShaderSource = codeVS; + if (codeGS != null) + renderer.GeometryShaderSource = codeGS; renderer.PixelShaderSource = codePS; renderer.EffectReflection = effectReflection; diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index 676d97afa8..c31ed925a5 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -54,6 +54,7 @@ public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, LoadedShaderSymbol? OwnerType = null) { public int IdRef { get; set; } = IdRef; + public SymbolType Type { get; set; } = Type; } diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index eb628dab5d..f9aab75829 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -492,6 +492,28 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo throw new InvalidOperationException($"Symbol {symbol} could not be imported because it was not found in its owner type {symbol.OwnerType}"); } + + /// + /// Try to resolve a symbol in shader or inherited shader. If is null, you can use this method without importing type or symbol in a context (useful for type evaluation). + /// + /// + /// If not null, the method or symbol will be imported in this context. + /// + /// + /// + internal bool TryResolveSymbol(int id, out Symbol symbol) + { + if (TryResolveSymbolNoRecursion(id, out symbol)) + return true; + + // Process inherited classes + // note: since it contains all indirectly inherited method too, which is why it is splitted with TryResolveSymbolNoRecursion + foreach (var inheritedShader in InheritedShaders) + if (inheritedShader.TryResolveSymbolNoRecursion(id, out symbol)) + return true; + + return false; + } /// /// Try to resolve a symbol in shader or inherited shader. If is null, you can use this method without importing type or symbol in a context (useful for type evaluation). @@ -515,6 +537,32 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) return false; } + private bool TryResolveSymbolNoRecursion(int id, out Symbol symbol) + { + var methods = CollectionsMarshal.AsSpan(Methods); + foreach (ref var c in methods) + { + if (c.Symbol.IdRef == id) + { + symbol = c.Symbol; + return true; + } + } + + var variables = CollectionsMarshal.AsSpan(Variables); + foreach (ref var c in variables) + { + if (c.Symbol.IdRef == id) + { + symbol = c.Symbol; + return true; + } + } + + symbol = default; + return false; + } + private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) { symbol = default; @@ -592,12 +640,19 @@ private bool BuildMethodGroup(string name, ref Symbol symbol) public sealed partial record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; -public sealed partial record StreamsType : SymbolType + +public sealed partial record StreamsType(StreamsKindSDSL Kind) : SymbolType +{ + public override string ToString() => Kind.ToString(); +} + +public sealed partial record GeometryStreamType(SymbolType BaseType, GeometryStreamOutputKindSDSL Kind) : SymbolType { - public override string ToString() => "Streams"; + public override string ToId() => $"{Kind.ToString()}Stream<{BaseType.ToId()}>"; + public override string ToString() => $"{Kind.ToString()}Stream<{BaseType}>"; } public sealed partial record ShaderMixinType : SymbolType { - public override string ToString() => "Streams"; + public override string ToString() => "mixin"; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 98dc665b67..8613b25830 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; @@ -52,7 +53,7 @@ public SymbolFrame Pop() return scope; } - public bool TryResolveSymbol(string name, out Symbol symbol) + public bool TryResolveSymbol(string name, [MaybeNullWhen(false)] out Symbol symbol) { for (int i = CurrentSymbols.Count - 1; i >= 0; i--) if (CurrentSymbols[i].TryGetValue(name, out symbol)) @@ -61,25 +62,43 @@ public bool TryResolveSymbol(string name, out Symbol symbol) if (CurrentShader != null && CurrentShader.TryResolveSymbol(name, out symbol)) return true; - symbol = default; + symbol = null; return false; } - public Symbol ResolveSymbol(string name) + public bool TryResolveSymbol(int id, [MaybeNullWhen(false)] out Symbol symbol) { for (int i = CurrentSymbols.Count - 1; i >= 0; --i) { - if (CurrentSymbols[i].TryGetValue(name, out var symbol)) + foreach (var symbol2 in CurrentSymbols[i]) { - return symbol; + if (symbol2.Value.IdRef == id) + { + symbol = symbol2.Value; + return true; + } } } - if (CurrentShader != null && CurrentShader.TryResolveSymbol(name, out var symbol2)) - return symbol2; + if (CurrentShader != null && CurrentShader.TryResolveSymbol(id, out symbol)) + return true; + symbol = null; + return false; + } + + public Symbol ResolveSymbol(int id) + { + if (!TryResolveSymbol(id, out var symbol)) + throw new NotImplementedException($"Cannot find symbol with ID {id} in main context (current shader is {CurrentShader?.Name}"); + return symbol; + } - throw new NotImplementedException($"Cannot find symbol {name} in main context (current shader is {CurrentShader?.Name}"); + public Symbol ResolveSymbol(string name) + { + if (!TryResolveSymbol(name, out var symbol)) + throw new NotImplementedException($"Cannot find symbol {name} in main context (current shader is {CurrentShader?.Name}"); + return symbol; } public void AddError(SemanticError error) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 58b9d676f3..61cbf22b57 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -982,6 +982,43 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) PushAccessChainId(accessChainIds, indexerValue.Id); break; } + case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, + MethodCall { Name.Name: "Append", Arguments.Values.Count: 1 } methodCall): + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = ScalarType.Void; + break; + } + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + + var output = methodCall.Arguments.Values[0].CompileAsValue(table, compiler); + var streamsType = (StreamsType)methodCall.Arguments.Values[0].ValueType; + // Note: if it was a Streams, implicit cast it to Output + if (streamsType.Kind == StreamsKindSDSL.Streams) + output = new (builder.InsertData(new OpCopyLogical(context.GetOrRegister(new StreamsType(StreamsKindSDSL.Output)), context.Bound++, output.Id))); + else if (streamsType.Kind == StreamsKindSDSL.Input) + throw new InvalidOperationException("StreamOutput.Append() only accepts Streams or Output objects"); + builder.Insert(new OpEmitVertexSDSL(output.Id)); + result = default; + break; + case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, + MethodCall { Name.Name: "RestartStrip", Arguments.Values.Count: 0 }): + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = ScalarType.Void; + break; + } + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + + builder.Insert(new OpEndPrimitive()); + result = default; + break; case (_, MethodCall methodCall): if (compiler == null) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ec43f8fdd8..d7f2440f82 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -345,7 +345,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = if (Name == "this" || Name == "base") Type = new PointerType(new ShaderMixinType(), Specification.StorageClass.Private); else if (Name == "streams") - Type = new PointerType(new StreamsType(), Specification.StorageClass.Private); + Type = new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private); else { if (!table.TryResolveSymbol(Name, out var symbol)) @@ -406,9 +406,9 @@ private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvC if (Name == "streams") { var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); - return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(), Specification.StorageClass.Private))); + return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private))); } - + var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); return EmitSymbol(builder, context, symbol, constantOnly); } @@ -604,9 +604,9 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberNameResolved); } - else if (Name == "Streams") + else if (Name == "Streams" || Name == "Input" || Name == "Output") { - symbolType = new StreamsType(); + symbolType = new StreamsType(Enum.Parse(Name)); } else { @@ -614,6 +614,15 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh if (table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) { + } + else if (Name == "PointStream" || Name == "LineStream" || Name == "TriangleStream") + { + symbolType = new GeometryStreamType(Generics[0].ResolveType(table, context), Name switch + { + "PointStream" => Specification.GeometryStreamOutputKindSDSL.Point, + "LineStream" => Specification.GeometryStreamOutputKindSDSL.Line, + "TriangleStream" => Specification.GeometryStreamOutputKindSDSL.Triangle, + }); } else if (SymbolType.TryGetNumeric(Name, out var numeric)) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index cf2fbff1be..2dcf73b3cc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -234,9 +234,13 @@ void RegisterName(int target, string name) { RegisterType(typeGeneric.ResultId, new GenericParameterType(typeGeneric.Kind)); } - else if (instruction.Op == Op.OpTypeStreamsSDSL && (OpTypePointer)instruction is { } typeStreams) + else if (instruction.Op == Op.OpTypeStreamsSDSL && (OpTypeStreamsSDSL)instruction is { } typeStreams) { - RegisterType(typeStreams.ResultId, new StreamsType()); + RegisterType(typeStreams.ResultId, new StreamsType(typeStreams.Kind)); + } + else if (instruction.Op == Op.OpTypeGeometryStreamOutputSDSL && (OpTypeGeometryStreamOutputSDSL)instruction is { } typeGeometryStreamOutput) + { + RegisterType(typeGeometryStreamOutput.ResultId, new GeometryStreamType(context.ReverseTypes[typeGeometryStreamOutput.BaseType], typeGeometryStreamOutput.Kind)); } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 19520ba988..59f6be26e7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -443,22 +443,37 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler foreach (var attribute in Attributes) { - if (attribute is AnyShaderAttribute numThreads && numThreads.Name == "numthreads") + if (attribute is AnyShaderAttribute anyAttribute) { - Span parameters = stackalloc int[numThreads.Parameters.Count]; - for (var index = 0; index < numThreads.Parameters.Count; index++) + if (anyAttribute.Name == "numthreads") { - var parameter = numThreads.Parameters[index]; - - // TODO: avoid emitting in context (use a temp buffer?) - var constantArraySize = parameter.CompileConstantValue(table, context); - if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) - throw new InvalidOperationException(); + Span parameters = stackalloc int[anyAttribute.Parameters.Count]; + for (var index = 0; index < anyAttribute.Parameters.Count; index++) + { + var parameter = anyAttribute.Parameters[index]; + + // TODO: avoid emitting in context (use a temp buffer?) + var constantArraySize = parameter.CompileConstantValue(table, context); + if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) + throw new InvalidOperationException(); + + parameters[index] = (int)value; + } - parameters[index] = (int)value; + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); } + else if (anyAttribute.Name == "maxvertexcount") + { + var maxVertexCount = anyAttribute.Parameters[0].CompileConstantValue(table, context); + if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _, false)) + throw new InvalidOperationException(); - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); + } + else + { + throw new NotImplementedException($"Can't parse method attribute {anyAttribute} on method {Name}"); + } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index c4c30ef26f..7bc5179c70 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -69,6 +69,12 @@ public enum ParameterModifiers : int InOut = In | Out, Const = 0x10, + + Point = 0x20, + Line = 0x40, + LineAdjacency = 0x80, + Triangle = 0x100, + TriangleAdjacency = 0x200, } public static class ShaderVariableInformationExtensions @@ -129,6 +135,11 @@ public static ParameterModifiers ToParameterModifiers(this string str) "out" => ParameterModifiers.Out, "inout" => ParameterModifiers.InOut, "const" => ParameterModifiers.Const, + "point" => ParameterModifiers.Point, + "line" => ParameterModifiers.Line, + "lineadj" => ParameterModifiers.LineAdjacency, + "triangle" => ParameterModifiers.Triangle, + "triangleadj" => ParameterModifiers.TriangleAdjacency, }; } } @@ -241,7 +252,7 @@ public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit com { var (builder, context) = compiler; var structType = (StructType)Type; - context.DeclareStructuredType(structType); + context.DeclareStructuredType(structType, context.Bound++); } public override string ToString() @@ -347,7 +358,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) Type = constantBufferType = constantBufferType with { Name = typeName }; } - context.DeclareCBuffer(constantBufferType); + context.DeclareCBuffer(constantBufferType, context.Bound++); var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); Symbol = new Symbol(sid, pointerType, context.Bound++, OwnerType: table.CurrentShader); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 360b635df0..0a45db0a5b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -62,7 +62,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r var position = scanner.Position; ParameterModifiers modifiers = ParameterModifiers.None; - if (Tokens.AnyOf(["inout", "in", "out", "triangle", "point", "const"], ref scanner, out var modifiersString, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) + if (Tokens.AnyOf(["inout", "in", "out", "const", "point", "lineadj", "line", "triangleadj", "triangle"], ref scanner, out var modifiersString, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { modifiers = modifiersString.ToParameterModifiers(); } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index b9ba5ae3c0..0ad2c66356 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -654,7 +654,7 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) } } - public static void CollectIds(OpData i, HashSet ids) + public static void CollectIds(OpData i, Action ids) { foreach (var op in i) { @@ -666,17 +666,17 @@ public static void CollectIds(OpData i, HashSet ids) || op.Kind == OperandKind.PairIdRefIdRef) { foreach (var word in op.Words) - ids.Add(word); + ids(word); } else if (op.Kind == OperandKind.PairIdRefLiteralInteger) { for (int j = 0; j < op.Words.Length; j += 2) - ids.Add(op.Words[j]); + ids(op.Words[j]); } else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) { for (int j = 1; j < op.Words.Length; j += 2) - ids.Add(op.Words[j]); + ids(op.Words[j]); } } } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index ec9b191092..f2698691a5 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -354,6 +354,12 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) return int.MaxValue; } } + + if (castType is StreamsType { Kind: var targetKind } + && valueType is StreamsType { Kind: var sourceKind } + // Note: order is Input, Streams, Output + && targetKind > sourceKind) + return 1; // We don't support cast with object yet, filter for numeral types if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) @@ -435,6 +441,14 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy } } + if (castType is StreamsType { Kind: var targetKind } + && valueType is StreamsType { Kind: var sourceKind } + // Note: order is Input, Streams, Output + && targetKind > sourceKind) + { + return new(InsertData(new OpCopyLogical(context.GetOrRegister(castType), context.Bound++, value.Id))); + } + // We don't support cast with object yet, filter for numeral types if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) || (valueType is not ScalarType && valueType is not VectorType && valueType is not MatrixType)) @@ -526,15 +540,15 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), - (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), - (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, false), 0, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpINotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, false), 0, new()), elementSize).Id)), (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), - (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), // Bitcast (int=>uint or uint=>int) (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index 058cbc97cd..3c61fe0a69 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -227,20 +227,50 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object throw new Exception("Cannot find type instruction for id " + typeId); } - public unsafe SpirvValue CreateConstantCompositeRepeat(Literal literal, int size) + public SpirvValue CreateDefaultConstantComposite(SymbolType type) + { + // TODO: cache results (either here or even more generally for any composite constant even if non-zero) + return type switch + { + ScalarType { Type: Scalar.Boolean } => CompileConstantLiteral(new BoolLiteral(false, new())), + ScalarType { Type: Scalar.Int } => CompileConstantLiteral(new IntegerLiteral(new(32, false, true), 0, new())), + ScalarType { Type: Scalar.UInt } => CompileConstantLiteral(new IntegerLiteral(new(32, false, false), 0, new())), + ScalarType { Type: Scalar.Int64 } => CompileConstantLiteral(new IntegerLiteral(new(64, false, true), 0, new())), + ScalarType { Type: Scalar.UInt64 } => CompileConstantLiteral(new IntegerLiteral(new(64, false, false), 0, new())), + ScalarType { Type: Scalar.Float } => CompileConstantLiteral(new FloatLiteral(new(32, true, false), 0.0, null, new())), + ScalarType { Type: Scalar.Double } => CompileConstantLiteral(new FloatLiteral(new(64, true, false), 0.0, null, new())), + VectorType v => CreateConstantCompositeRepeat(v, CreateDefaultConstantComposite(v.BaseType), v.Size), + MatrixType m => CreateConstantCompositeRepeat(m, CreateDefaultConstantComposite(m.BaseType.GetVectorOrScalar(m.Rows)), m.Columns), + StructType s => ProcessStruct(s), + ArrayType a when a.Size != -1 => CreateConstantCompositeRepeat(a, CreateDefaultConstantComposite(a.BaseType), a.Size), + }; + + SpirvValue ProcessStruct(StructType structType) + { + Span values = stackalloc int[structType.Members.Count]; + for (int i = 0; i < values.Length; ++i) + values[i] = CreateDefaultConstantComposite(structType.Members[i].Type).Id; + return new(Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); + } + } + + public SpirvValue CreateConstantCompositeVectorRepeat(Literal literal, int size) { var value = CompileConstantLiteral(literal); if (size == 1) return value; + + var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); + return CreateConstantCompositeRepeat(type, value, size); + } + public unsafe SpirvValue CreateConstantCompositeRepeat(SymbolType type, SpirvValue value, int size) + { Span values = stackalloc int[size]; for (int i = 0; i < size; ++i) - values[i] = size; + values[i] = value.Id; - var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); - var instruction = Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values))); - - return new(instruction); + return new(Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); } public Literal CreateLiteral(object value, TextLocation location = default) diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index fab74e8c9d..88b174927e 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -6,62 +6,88 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvContext { + public void ReplaceType() + { + throw new NotImplementedException(); + } + public int GetOrRegister(SymbolType? type) { if (type is null) throw new ArgumentException($"Type is null"); if (Types.TryGetValue(type, out var res)) return res; - else + + return RegisterType(type, Bound++); + } + + public int RemoveType(SymbolType type) + { + var typeId = Types[type]; + foreach (var i in Buffer) { - var instruction = type switch + if (i.Data.IdResult == typeId) { - ScalarType s => - s.Type switch - { - Scalar.Void => Buffer.Add(new OpTypeVoid(Bound++)).IdResult, - Scalar.Boolean => Buffer.Add(new OpTypeBool(Bound++)).IdResult, - Scalar.Int => Buffer.Add(new OpTypeInt(Bound++, 32, 1)).IdResult, - Scalar.UInt => Buffer.Add(new OpTypeInt(Bound++, 32, 0)).IdResult, - Scalar.Int64 => Buffer.Add(new OpTypeInt(Bound++, 64, 1)).IdResult, - Scalar.UInt64 => Buffer.Add(new OpTypeInt(Bound++, 64, 0)).IdResult, - Scalar.Float => Buffer.Add(new OpTypeFloat(Bound++, 32, null)).IdResult, - Scalar.Double => Buffer.Add(new OpTypeFloat(Bound++, 64, null)).IdResult, - _ => throw new NotImplementedException($"Can't add type {type}") - }, - VectorType v => Buffer.Add(new OpTypeVector(Bound++, GetOrRegister(v.BaseType), v.Size)).IdResult, - MatrixType m => Buffer - .Add(new OpTypeMatrix(Bound++, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)) - .IdResult, - ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), - ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer - .Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(a.BaseType))).IdResult, - StructType st => RegisterStructuredType(st.ToId(), st), - FunctionType f => RegisterFunctionType(f), - PointerType p => RegisterPointerType(p), - LoadedShaderSymbol s => ImportShaderType(s), - Texture1DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture2DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture3DType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - TextureCubeType t => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - SamplerType st => Buffer.Add(new OpTypeSampler(Bound++)).IdResult, - BufferType b => Buffer.Add(new OpTypeImage(Bound++, GetOrRegister(b.BaseType), Specification.Dim.Buffer, - 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, - StructuredBufferType b => RegisterStructuredBufferType(b), - SampledImage si => Buffer.Add(new OpTypeSampledImage(Bound++, GetOrRegister(si.ImageType))).IdResult, - GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(Bound++, g.Kind)).IdResult, - StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(Bound++)).IdResult, - // StructSymbol st => RegisterStruct(st), - _ => throw new NotImplementedException($"Can't add type {type}") - }; - Types[type] = instruction ?? -1; - ReverseTypes[instruction ?? -1] = type; - return instruction ?? -1; + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + Types.Remove(type); + ReverseTypes.Remove(typeId); + return typeId; + } } + + throw new InvalidOperationException($"Type to remove {type} was not found"); + } + + public int RegisterType(SymbolType type, int id) + { + var instruction = type switch + { + ScalarType s => + s.Type switch + { + Scalar.Void => Buffer.Add(new OpTypeVoid(id)).IdResult, + Scalar.Boolean => Buffer.Add(new OpTypeBool(id)).IdResult, + Scalar.Int => Buffer.Add(new OpTypeInt(id, 32, 1)).IdResult, + Scalar.UInt => Buffer.Add(new OpTypeInt(id, 32, 0)).IdResult, + Scalar.Int64 => Buffer.Add(new OpTypeInt(id, 64, 1)).IdResult, + Scalar.UInt64 => Buffer.Add(new OpTypeInt(id, 64, 0)).IdResult, + Scalar.Float => Buffer.Add(new OpTypeFloat(id, 32, null)).IdResult, + Scalar.Double => Buffer.Add(new OpTypeFloat(id, 64, null)).IdResult, + _ => throw new NotImplementedException($"Can't add type {type}") + }, + VectorType v => Buffer.Add(new OpTypeVector(id, GetOrRegister(v.BaseType), v.Size)).IdResult, + MatrixType m => Buffer + .Add(new OpTypeMatrix(id, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)) + .IdResult, + ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), + ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer + .Add(new OpTypeRuntimeArray(id, GetOrRegister(a.BaseType))).IdResult, + StructType st => RegisterStructuredType(st.ToId(), st), + FunctionType f => RegisterFunctionType(f, id), + PointerType p => RegisterPointerType(p, id), + LoadedShaderSymbol s => ImportShaderType(s, id), + Texture1DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture2DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture3DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + TextureCubeType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + SamplerType st => Buffer.Add(new OpTypeSampler(id)).IdResult, + BufferType b => Buffer.Add(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, + 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, + StructuredBufferType b => RegisterStructuredBufferType(b), + SampledImage si => Buffer.Add(new OpTypeSampledImage(id, GetOrRegister(si.ImageType))).IdResult, + GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(id, g.Kind)).IdResult, + StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(id, s.Kind)).IdResult, + GeometryStreamType so => Buffer.Add(new OpTypeGeometryStreamOutputSDSL(id, GetOrRegister(so.BaseType), so.Kind)).IdResult, + // StructSymbol st => RegisterStruct(st), + _ => throw new NotImplementedException($"Can't add type {type}") + }; + Types[type] = instruction ?? -1; + ReverseTypes[instruction ?? -1] = type; + return instruction ?? -1; } private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) @@ -112,22 +138,21 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; } - public int ImportShaderType(LoadedShaderSymbol shaderSymbol) + public int ImportShaderType(LoadedShaderSymbol shaderSymbol, int id) { - FluentAdd(new OpSDSLImportShader(Bound++, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan())), - out var shader); - AddName(shader.ResultId, shaderSymbol.Name); + Add(new OpSDSLImportShader(id, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan()))); + AddName(id, shaderSymbol.Name); // Import struct var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); foreach (ref var structType in structTypes) { - ImportShaderStruct(shader, structType.Type, out structType.ImportedId); + ImportShaderStruct(id, structType.Type, out structType.ImportedId); } // Note: Variables and methods are imported lazily in LoadedShaderSymbol.TryResolveSymbol() - return shader.ResultId; + return id; } private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) @@ -160,9 +185,9 @@ public void ImportShaderMethod(int shaderId, ref Symbol symbol, Specification.Fu AddName(symbol.IdRef, symbol.Id.Name); } - public int DeclareCBuffer(ConstantBufferSymbol cb) + public int DeclareCBuffer(ConstantBufferSymbol cb, int id) { - var result = DeclareStructuredType(cb); + var result = DeclareStructuredType(cb, id); Buffer.Add(new OpDecorate(result, Specification.Decoration.Block, [])); @@ -174,14 +199,13 @@ private int RegisterStructuredType(string name, StructuredType structSymbol) throw new InvalidOperationException(); } - public int DeclareStructuredType(StructuredType structSymbol) + public int DeclareStructuredType(StructuredType structSymbol, int id) { Span types = stackalloc int[structSymbol.Members.Count]; for (var index = 0; index < structSymbol.Members.Count; index++) types[index] = GetOrRegister(structSymbol.Members[index].Type); - var result = Add(new OpTypeStruct(Bound++, [.. types])); - var id = result.IdResult ?? throw new InvalidOperationException(); + Add(new OpTypeStruct(id, [.. types])); AddName(id, structSymbol.ToId()); for (var index = 0; index < structSymbol.Members.Count; index++) { @@ -195,7 +219,7 @@ public int DeclareStructuredType(StructuredType structSymbol) return id; } - private int RegisterFunctionType(FunctionType functionType) + private int RegisterFunctionType(FunctionType functionType, int id) { Span<(int, int)> types = stackalloc (int, int)[functionType.ParameterTypes.Count]; for (int i = 0; i < functionType.ParameterTypes.Count; i++) @@ -204,18 +228,17 @@ private int RegisterFunctionType(FunctionType functionType) types[i].Item2 = (int)functionType.ParameterTypes[i].Modifiers; } - var result = Buffer.Add(new OpTypeFunctionSDSL(Bound++, GetOrRegister(functionType.ReturnType), [.. types])); + Buffer.Add(new OpTypeFunctionSDSL(id, GetOrRegister(functionType.ReturnType), [.. types])); // disabled for now: currently it generates name with {}, not working with most SPIRV tools // AddName(result, functionType.ToId()); - return result.IdResult ?? -1; + return id; } - private int RegisterPointerType(PointerType pointerType) + private int RegisterPointerType(PointerType pointerType, int id) { var baseType = GetOrRegister(pointerType.BaseType); - var result = Add(new OpTypePointer(Bound++, pointerType.StorageClass, baseType)); - var id = result.IdResult; - AddName(id ?? -1, pointerType.ToId()); - return id ?? -1; + Add(new OpTypePointer(id, pointerType.StorageClass, baseType)); + AddName(id, pointerType.ToId()); + return id; } } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 311c65785f..8799b53a68 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -9,6 +9,7 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; using CommunityToolkit.HighPerformance; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Spirv.Processing { @@ -31,8 +32,11 @@ class StreamInfo(string? semantic, string name, PointerType type, int variableId { public string? Semantic { get; } = semantic; public string Name { get; } = name; - public PointerType Type { get; } = type; + public SymbolType Type { get; } = type.BaseType; public int VariableId { get; } = variableId; + + public int? InputId { get; set; } + public int? OutputId { get; set; } public int? InputLayoutLocation { get; set; } public int? OutputLayoutLocation { get; set; } @@ -47,6 +51,8 @@ class StreamInfo(string? semantic, string name, PointerType type, int variableId public bool Read { get => field; set { field = value; UsedAnyStage = true; } } public bool Write { get => field; set { field = value; UsedAnyStage = true; } } public bool UsedAnyStage { get; private set; } + public int? InputStructFieldIndex { get; internal set; } + public int? OutputStructFieldIndex { get; internal set; } public int StreamStructFieldIndex { get; internal set; } public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; @@ -169,11 +175,14 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); table.TryResolveSymbol("VSMain", out var entryPointVS); + table.TryResolveSymbol("GSMain", out var entryPointGS); table.TryResolveSymbol("PSMain", out var entryPointPS); table.TryResolveSymbol("CSMain", out var entryPointCS); if (entryPointCS?.Type is FunctionGroupType) entryPointCS = entryPointCS.GroupMembers[^1]; + if (entryPointGS?.Type is FunctionGroupType) + entryPointGS = entryPointGS.GroupMembers[^1]; if (entryPointVS?.Type is FunctionGroupType) entryPointVS = entryPointVS.GroupMembers[^1]; if (entryPointPS?.Type is FunctionGroupType) @@ -195,20 +204,8 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con if (entryPointCS != null) { - (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.GLCompute, entryPointCS.IdRef, entryPointCS.Id.Name, analysisResult, liveAnalysis, false); + (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); - - // Move OpExecutionMode on new CSMain wrapper (and remove others) - foreach (var i in context) - { - if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) - { - if (executionMode.EntryPoint == entryPointCS.IdRef) - executionMode.EntryPoint = csWrapperId; - else - SpirvBuilder.SetOpNop(executionMode.OpData.Memory.Span); - } - } } var inputAttributes = new List(); @@ -227,7 +224,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.Fragment, entryPointPS.IdRef, entryPointPS.Id.Name, analysisResult, liveAnalysis, false); + (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); @@ -241,32 +238,45 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con } // Reset cbuffer/resource/methods used for next stage - foreach (var variable in analysisResult.Variables) - variable.Value.UsedThisStage = false; - foreach (var resource in analysisResult.Resources) - resource.Value.UsedThisStage = false; - foreach (var cbuffer in analysisResult.CBuffers) - cbuffer.Value.UsedThisStage = false; - foreach (var method in liveAnalysis.ReferencedMethods) - { - method.Value.UsedThisStage = false; - method.Value.ThisStageMethodId = null; - } + ResetUsedThisStage(analysisResult, liveAnalysis); PropagateStreamsFromPreviousStage(streams); + + if (entryPointGS != null) + { + AnalyzeStreamReadWrites(buffer, context, entryPointGS.IdRef, analysisResult, liveAnalysis); + + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + stream.Value.Output = true; + } + + (var gsWrapperId, var gsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Geometry, entryPointGS, analysisResult, liveAnalysis, false); + entryPoints.Add((gsWrapperName, gsWrapperId, ShaderStage.Geometry)); + + // Reset cbuffer/resource/methods used for next stage + ResetUsedThisStage(analysisResult, liveAnalysis); + + PropagateStreamsFromPreviousStage(streams); + + if (entryPointVS == null) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a geometry shader is specified, a vertex shader is needed too"); + } + if (entryPointVS != null) { AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); - // If written to, they are expected at the end of vertex shader + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader foreach (var stream in streams) { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - && stream.Value.Write) + if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) stream.Value.Output = true; } - (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(buffer, context, ExecutionModel.Vertex, entryPointVS.IdRef, entryPointVS.Id.Name, analysisResult, liveAnalysis, true); + (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); // Process shader input attributes @@ -291,6 +301,21 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con return new(entryPoints, inputAttributes); } + private static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + { + foreach (var variable in analysisResult.Variables) + variable.Value.UsedThisStage = false; + foreach (var resource in analysisResult.Resources) + resource.Value.UsedThisStage = false; + foreach (var cbuffer in analysisResult.CBuffers) + cbuffer.Value.UsedThisStage = false; + foreach (var method in liveAnalysis.ReferencedMethods) + { + method.Value.UsedThisStage = false; + method.Value.ThisStageMethodId = null; + } + } + private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) { // Remove unreferenced code @@ -371,7 +396,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Uniform, + Storageclass: Specification.StorageClass.Uniform, ResultId: int } variable && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) @@ -385,7 +410,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant, + Storageclass: Specification.StorageClass.UniformConstant, ResultId: int } resource) { @@ -401,7 +426,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup, + Storageclass: Specification.StorageClass.Private or Specification.StorageClass.Workgroup, ResultId: int } variable2) { @@ -422,11 +447,11 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c } } - // Remove all OpTypeStreamsSDSL or any type that depends on it + // Remove all OpTypeStreamsSDSL and OpTypeGeometryStreamOutputSDSL or any type that depends on it // (we do that before the OpName/OpDecorate pass) foreach (var i in context) { - if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer) + if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) { if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) { @@ -555,7 +580,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) foreach (var i in buffer) { if (i.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + && ((OpVariableSDSL)i) is { Storageclass: Specification.StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } && context.ReverseTypes[pointerType2] is PointerType { BaseType: ConstantBufferSymbol }) { var name = nameTable[bufferId]; @@ -566,7 +591,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup, + Storageclass: Specification.StorageClass.Private or Specification.StorageClass.Workgroup, ResultId: int } variable) { @@ -595,7 +620,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, + Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer, ResultId: int } resource) { @@ -659,20 +684,20 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); } - private (int Id, string Name) GenerateStreamWrapper(NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, int entryPointId, string entryPointName, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) + private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; var stage = executionModel switch { - ExecutionModel.Fragment => "PS", ExecutionModel.Vertex => "VS", + ExecutionModel.Geometry => "GS", + ExecutionModel.Fragment => "PS", ExecutionModel.GLCompute => "CS", _ => throw new NotImplementedException() }; List<(StreamInfo Info, int Id)> inputStreams = []; List<(StreamInfo Info, int Id)> outputStreams = []; - List privateStreams = []; int inputLayoutLocationCount = 0; int outputLayoutLocationCount = 0; @@ -712,7 +737,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo (ExecutionModel.Fragment, StreamVariableType.Output, "SV_DEPTH") => AddBuiltin(variable, BuiltIn.FragDepth), (ExecutionModel.Fragment, StreamVariableType.Output, {} semantic) when semantic.StartsWith("SV_TARGET") => AddLocation(variable, semantic.Substring("SV_TARGET".Length)), // SV_Position - (ExecutionModel.Vertex, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), + (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.FragCoord), // SV_InstanceID/SV_VertexID @@ -734,17 +759,19 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo }; } + var entryPointFunctionType = (FunctionType)entryPoint.Type; + var geometryInputSize = executionModel == ExecutionModel.Geometry ? ((ArrayType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size : 1; + foreach (var stream in streams) { - var baseType = stream.Value.Type.BaseType; - - if (stream.Value.UsedThisStage) - privateStreams.Add(stream.Value); - if (stream.Value.Input) { - context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Input, context.Types[baseType]), out var pointerType); - context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Input, null), out var variable); + // Note: for geometry shader, we process multiple inputs at once (in an array) + var streamInputType = new PointerType(executionModel == ExecutionModel.Geometry + ? new ArrayType(stream.Value.Type, geometryInputSize) + : stream.Value.Type, + Specification.StorageClass.Input); + context.FluentAdd(new OpVariable(context.GetOrRegister(streamInputType), context.Bound++, Specification.StorageClass.Input, null), out var variable); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Input, stream.Value)) @@ -756,16 +783,17 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } - if (!baseType.GetElementType().IsFloating()) + if (!stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); + stream.Value.InputId = variable.ResultId; inputStreams.Add((stream.Value, variable.ResultId)); } if (stream.Value.Output) { - context.FluentAdd(new OpTypePointer(context.Bound++, StorageClass.Output, context.Types[baseType]), out var pointerType); - context.FluentAdd(new OpVariable(pointerType, context.Bound++, StorageClass.Output, null), out var variable); + var streamOutputType = new PointerType(stream.Value.Type, Specification.StorageClass.Output); + context.FluentAdd(new OpVariable(context.GetOrRegister(streamOutputType), context.Bound++, Specification.StorageClass.Output, null), out var variable); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Output, stream.Value)) @@ -784,24 +812,49 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); } - if (!baseType.GetElementType().IsFloating()) + if (!stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); + stream.Value.OutputId = variable.ResultId; outputStreams.Add((stream.Value, variable.ResultId)); } } var fields = new List(); - foreach (var stream in privateStreams) + var inputFields = new List(); + var outputFields = new List(); + foreach (var stream in streams) + { + stream.Value.InputStructFieldIndex = null; + stream.Value.OutputStructFieldIndex = null; + if (stream.Value.UsedThisStage) + { + stream.Value.StreamStructFieldIndex = fields.Count; + fields.Add(new(stream.Value.Name, stream.Value.Type, default)); + } + } + + foreach (var stream in inputStreams) + { + stream.Info.InputStructFieldIndex = inputFields.Count; + inputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); + } + + foreach (var stream in outputStreams) { - stream.StreamStructFieldIndex = fields.Count; - fields.Add(new(stream.Name, stream.Type.BaseType, default)); + stream.Info.OutputStructFieldIndex = outputFields.Count; + outputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); } + + var inputType = new StructType($"{stage}_INPUT", inputFields); + var outputType = new StructType($"{stage}_OUTPUT", outputFields); var streamsType = new StructType($"{stage}_STREAMS", fields); - context.DeclareStructuredType(streamsType); + context.DeclareStructuredType(inputType, context.Bound++); + context.DeclareStructuredType(outputType, context.Bound++); + context.DeclareStructuredType(streamsType, context.Bound++); // Create a static global streams variable - context.FluentAdd(new OpVariable(context.GetOrRegister(new PointerType(streamsType, StorageClass.Private)), context.Bound++, StorageClass.Private, null), out var streamsVariable); + context.FluentAdd(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null), out var streamsVariable); context.AddName(streamsVariable.ResultId, $"streams{stage}"); // Patch any OpStreams/OpAccessChain to use the new struct @@ -810,7 +863,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo if (method.Value.UsedThisStage && method.Value.HasStreamAccess) { DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis); - PatchStreamsAccesses(buffer, context, method.Key, streamsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, streamsVariable.ResultId, analysisResult, liveAnalysis); } } @@ -820,7 +873,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo var newEntryPointFunctionType = context.GetOrRegister(new FunctionType(ScalarType.Void, [])); buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); buffer.Add(new OpLabel(context.Bound++)); - entryPointName = $"{entryPointName}_Wrapper"; + var variableInsertIndex = buffer.Count; + var entryPointName = $"{entryPoint.Id.Name}_Wrapper"; context.AddName(newEntryPointFunction, entryPointName); { @@ -839,24 +893,84 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo } } - // Copy variables from input to streams struct - foreach (var stream in inputStreams) + // Setup input and call original main() + if (executionModel == ExecutionModel.Geometry) { - var baseType = stream.Info.Type.BaseType; - buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, stream.Id, null, []), out var loadedValue); - buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null, [])); - } + context.Add(new OpCapability(Capability.Geometry)); - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPointId, [])); + // Copy variables to Input[X] which is first method parameter of main() + // Pattern is a loop over index i looking like: + // inputs[i].Position = gl_Position[i]; + // inputs[i].Normal = in_GS_normals[i]; + var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, geometryInputSize), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + context.AddName(inputsVariable, "inputs"); - // Copy variables from streams struct to output - foreach (var stream in outputStreams) + Span inputLoadValues = stackalloc int[inputFields.Count]; + for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + { + var stream = inputStreams[inputIndex]; + buffer.FluentAdd(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, geometryInputSize)), context.Bound++, stream.Id, null, []), out var loadedValue); + inputLoadValues[inputIndex] = loadedValue.ResultId; + } + + Span inputFieldValues = stackalloc int[inputFields.Count]; + Span inputValues = stackalloc int[geometryInputSize]; + for (int arrayIndex = 0; arrayIndex < geometryInputSize; ++arrayIndex) + { + for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + { + var stream = inputStreams[inputIndex]; + inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).IdResult.Value; + } + + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).IdResult.Value; + } + + var inputsData = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, geometryInputSize)), context.Bound++, [..inputValues])).IdResult.Value; + buffer.Add(new OpStore(inputsVariable, inputsData, null, [])); + + // Change signature of main() to not use output anymore + // Note: OpFunctionParameter will be removed as part of PatchStreamsAccesses() + var entryPointTypeId = context.RemoveType(entryPoint.Type); + entryPoint.Type = entryPointFunctionType with { ParameterTypes = entryPointFunctionType.ParameterTypes[0..^1] }; + var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; + if (executionMode == ParameterModifiers.None) + throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); + context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch + { + ParameterModifiers.Point => ExecutionMode.InputPoints, + ParameterModifiers.Line => ExecutionMode.InputLines, + ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, + ParameterModifiers.Triangle => ExecutionMode.Triangles, + ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, + }, [])); + entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; + context.RegisterType(entryPoint.Type, entryPointTypeId); + + // Call main(inputs) + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, [inputsVariable])); + } + else { - var baseType = stream.Info.Type.BaseType; - buffer.FluentAdd(new OpAccessChain(context.Types[stream.Info.Type], context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, []), out var loadedValue); - buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); + // Copy variables from input to streams struct + foreach (var stream in inputStreams) + { + buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); + buffer.FluentAdd(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.Id, null, []), out var loadedValue); + buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null, [])); + } + + // Call main() + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, [])); + + // Copy variables from streams struct to output + foreach (var stream in outputStreams) + { + var baseType = stream.Info.Type; + buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); + buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, []), out var loadedValue); + buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); + } } buffer.Add(new OpReturn()); @@ -889,6 +1003,16 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. pvariables.Slice(0, pvariableIndex)])); } + + // Move OpExecutionMode on new wrapper + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) + { + if (executionMode.EntryPoint == entryPoint.IdRef) + executionMode.EntryPoint = newEntryPointFunction.ResultId; + } + } return (newEntryPointFunction.ResultId, entryPointName); } @@ -947,11 +1071,16 @@ void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int } } - class StreamsTypeReplace(SymbolType streamsReplacement) : TypeRewriter + class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement) : TypeRewriter { public override SymbolType Visit(StreamsType streamsType) { - return streamsReplacement; + return streamsType.Kind switch + { + StreamsKindSDSL.Streams => streamsReplacement, + StreamsKindSDSL.Input => inputReplacement, + StreamsKindSDSL.Output => outputReplacement, + }; } } @@ -962,9 +1091,13 @@ public override void Visit(StreamsType streamsType) { Found = true; } + public override void Visit(GeometryStreamType geometryStreamsType) + { + Found = true; + } } - void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, StructType inputStructType, StructType outputStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); @@ -977,22 +1110,42 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct var method = (OpFunction)buffer[methodStart]; var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; - methodType = (FunctionType)new StreamsTypeReplace(streamsStructType).Visit(methodType); - method.FunctionType = context.GetOrRegister(methodType); + var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType); + var newMethodType = (FunctionType)streamTypeReplacer.Visit(methodType); + if (!ReferenceEquals(newMethodType, methodType)) + { + methodType = newMethodType; + method.FunctionType = context.GetOrRegister(methodType); + var symbol = table.ResolveSymbol(functionId); + symbol.Type = methodType; + } + // Remap ids for streams type to actual struct type - var remapIds = new Dictionary + var remapIds = new Dictionary(); + var processedIds = new HashSet(); + + // Check if type contains any Streams/Input/Output (and if yes, register the replacement) + void CheckStreamTypes(int id) { - { context.GetOrRegister(new StreamsType()), context.GetOrRegister(streamsStructType) }, - { context.GetOrRegister(new PointerType(new StreamsType(), StorageClass.Private)), context.GetOrRegister(new PointerType(streamsStructType, StorageClass.Private)) }, - { context.GetOrRegister(new PointerType(new StreamsType(), StorageClass.Function)), context.GetOrRegister(new PointerType(streamsStructType, StorageClass.Function)) }, - }; + if (processedIds.Add(id) && context.ReverseTypes.TryGetValue(id, out var type)) + { + // New type, check it + var replacedType = streamTypeReplacer.VisitType(type); + if (!ReferenceEquals(replacedType, type)) + remapIds.Add(id, context.GetOrRegister(replacedType)); + } + } // TODO: remap method type! - for (int index = methodStart; index < methodEnd; ++index) + Span tempIdsForStreamCopy = stackalloc int[streams.Values.Count]; + for (int index = methodStart; ; ++index) { var i = buffer[index]; + if (i.Op == Op.OpFunctionEnd) + break; + if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) { streamsInstructionIds.Add(streamsInstruction.ResultId, true); @@ -1010,6 +1163,9 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct var type = context.ReverseTypes[functionParameter.ResultType]; if (type is PointerType { BaseType: StreamsType }) streamsInstructionIds.Add(functionParameter.ResultId, false); + // Remove StreamOutput parameter + else if (type is PointerType { BaseType: GeometryStreamType }) + SpirvBuilder.SetOpNop(i.Data.Memory.Span); } else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { @@ -1032,6 +1188,73 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct accessChain.BaseId = accessChain.BaseId; } } + else if (i.Op == Op.OpCopyLogical && (OpCopyLogical)i is { } copyLogical) + { + // Cast input to streams + var targetType = context.ReverseTypes[copyLogical.ResultType]; + if (targetType is StreamsType { Kind: StreamsKindSDSL.Streams }) + { + foreach (var stream in streams) + { + // Part of streams? + if (stream.Value.UsedThisStage) + { + if (stream.Value.Input) + { + // Extract value from streams + tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = buffer.Insert(index++, + new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), + context.Bound++, + copyLogical.Operand, + [stream.Value.InputStructFieldIndex.Value])).ResultId; + } + else + { + // Otherwise use default value + tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = context.CreateDefaultConstantComposite(stream.Value.Type).Id; + } + } + } + + // Update index (otherwise copyLogical fields will point to invalid data) + i.Index = index; + buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [..tempIdsForStreamCopy.Slice(0, streamsStructType.Members.Count)])); + } + else if (targetType is StreamsType { Kind: StreamsKindSDSL.Output }) + { + foreach (var stream in streams) + { + // Part of streams? + if (stream.Value.Output) + { + // Extract value from streams + tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex.Value] = buffer.Insert(index++, + new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), + context.Bound++, + copyLogical.Operand, + [stream.Value.StreamStructFieldIndex])).ResultId; + } + } + + // Update index (otherwise copyLogical fields will point to invalid data) + i.Index = index; + buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [..tempIdsForStreamCopy.Slice(0, outputStructType.Members.Count)])); + } + } + else if (i.Op == Op.OpEmitVertexSDSL && (OpEmitVertexSDSL)i is { } emitVertex) + { + var output = emitVertex.Output; + foreach (var stream in streams) + { + if (stream.Value.Output) + { + var outputValue = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, output, [stream.Value.OutputStructFieldIndex.Value])).ResultId; + buffer.Insert(index++, new OpStore(stream.Value.OutputId.Value, outputValue, MemoryAccessMask.None, [])); + } + } + + buffer.Replace(index, new OpEmitVertex()); + } else if (i.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } call) { var calledMethodInfo = liveAnalysis.ReferencedMethods[call.Function]; @@ -1040,6 +1263,8 @@ void PatchStreamsAccesses(NewSpirvBuffer buffer, SpirvContext context, int funct call.Function = updatedMethodId; } + SpirvBuilder.CollectIds(i.Data, CheckStreamTypes); + SpirvBuilder.RemapIds(remapIds, ref i.Data); } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 792020b05b..d42d851d54 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -281,6 +281,7 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpTypeSampledImage || op == Op.OpTypeGenericSDSL || op == Op.OpTypeStreamsSDSL + || op == Op.OpTypeGeometryStreamOutputSDSL || op == Op.OpSDSLImportShader || op == Op.OpSDSLImportVariable || op == Op.OpSDSLImportFunction From 8e91269fc70216f9d95bea6635b36403b1d2c870 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 2 Feb 2026 21:28:36 +0900 Subject: [PATCH 0771/1182] Tessellation: Hull and Domain shader (with constant streams) --- .../SDSL/RenderTests/StreamTessellation.sdsl | 52 ++ .../SDSL/ShaderMixer.cs | 1 + .../Examples.Spirv.cs | 4 +- .../Extensions/spirv.sdsl.grammar-ext.json | 41 +- src/Stride.Shaders.Tests/RenderingTests.cs | 7 +- src/Stride.Shaders/Core/SymbolTypes.cs | 6 + .../Parsing/SDSL/AST/Expression.cs | 21 +- .../Parsing/SDSL/AST/Literals.cs | 23 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 63 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 8 +- .../Spirv/Building/Builder.Functions.cs | 56 +- .../Spirv/Building/SpirvContext.Types.cs | 23 +- .../Spirv/Processing/InterfaceProcessor.cs | 737 ++++++++++++++---- .../Spirv/Processing/TypeDuplicatesRemover.cs | 1 + 15 files changed, 863 insertions(+), 184 deletions(-) create mode 100644 assets/SDSL/RenderTests/StreamTessellation.sdsl diff --git a/assets/SDSL/RenderTests/StreamTessellation.sdsl b/assets/SDSL/RenderTests/StreamTessellation.sdsl new file mode 100644 index 0000000000..bb90d0b315 --- /dev/null +++ b/assets/SDSL/RenderTests/StreamTessellation.sdsl @@ -0,0 +1,52 @@ +// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) + +namespace Stride.Shaders.Tests; + +shader StreamTessellation +{ + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + stream float4 ColorTarget : SV_Target0; + stream float4 ExtraColor : EXTRA_COLOR; + stream float4 ExtraColor2; + + patchstream float Edges[3] : SV_TessFactor; + patchstream float Inside[2] : SV_InsideTessFactor; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + streams.ExtraColor2 = streams.ExtraColor; + } + + void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) + { + constants.Edges[0] = 1.0; + constants.Edges[1] = 1.0; + constants.Edges[2] = 1.0; + constants.Edges[3] = 1.0; + constants.Inside[0] = 1.0 * 3.12; + constants.Inside[1] = 1.0 * 3.12; + } + + [outputcontrolpoints(3)] + [patchconstantfunc("HSConstantMain")] + void HSMain(InputPatch input, out Output output, uint uCPID : SV_OutputControlPointID) + { + streams = input[uCPID]; + + output = streams; + } + + [domain("tri")] + void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) + { + streams = input[0]; + output = streams; + } + + void PSMain() + { + streams.ColorTarget = streams.ExtraColor2; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index bfbd0940e1..da398d3077 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -950,6 +950,7 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL or Decoration.ShaderConstantSDSL + or Decoration.PatchConstantFuncSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 7117995fab..31f903c61c 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -32,8 +32,8 @@ public static void GenerateSpirv() new(ScalarType.Int, [new(ScalarType.Int, default), new(ScalarType.Int, default)]) ); builder.BeginFunction(context, function); - builder.AddFunctionParameter(context, "a", ScalarType.Int); - builder.AddFunctionParameter(context, "b", ScalarType.Int); + builder.EmitFunctionParameter(context, "a", ScalarType.Int); + builder.EmitFunctionParameter(context, "b", ScalarType.Int); builder.SetPositionTo(function); var block = builder.CreateBlock(context, "sourceBlock"); builder.SetPositionTo(block); diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 62573e0095..2921e1a9d9 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -366,7 +366,23 @@ { "kind" : "IdRef", "name" : "'Base Type'" }, { "kind": "GeometryStreamOutputKindSDSL", - "name": "kind" + "name": "Kind" + } + ] + }, + { + "opname": "OpTypePatchSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResult" }, + { "kind" : "IdRef", "name" : "'Base Type'" }, + { + "kind": "PatchTypeKindSDSL", + "name": "Kind" + }, + { + "kind": "LiteralInteger", + "name": "Size" } ] }, @@ -629,6 +645,11 @@ "enumerant": "ShaderConstantSDSL", "value": 8060, "version": "1.0" + }, + { + "enumerant": "PatchConstantFuncSDSL", + "value": 8070, + "version": "1.0" } ] }, @@ -669,6 +690,10 @@ { "enumerant": "Output", "value": 3 + }, + { + "enumerant": "Constants", + "value": 4 } ] }, @@ -690,6 +715,20 @@ } ] }, + { + "category": "ValueEnum", + "kind": "PatchTypeKindSDSL", + "enumerants": [ + { + "enumerant": "Input", + "value": 1 + }, + { + "enumerant": "Output", + "value": 2 + } + ] + }, { "kind": "ExecutionModel", "enumerants": [ diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index c98f14b168..87c25e5ac5 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -125,12 +125,15 @@ public void RenderTest1(string shaderName) var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); - var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) - ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + var codeHS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.TessellationControl)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationControl)) : null; var codeGS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Geometry)) ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Geometry)) : null; + var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + : null; if (codeVS != null) Console.WriteLine(codeVS); diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index f9aab75829..79fdb55fe8 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -652,6 +652,12 @@ public sealed partial record GeometryStreamType(SymbolType BaseType, GeometryStr public override string ToString() => $"{Kind.ToString()}Stream<{BaseType}>"; } +public sealed partial record PatchType(SymbolType BaseType, PatchTypeKindSDSL Kind, int Size) : SymbolType +{ + public override string ToId() => $"{Kind.ToString()}Patch<{BaseType.ToId()}, {Size}>"; + public override string ToString() => $"{Kind.ToString()}Patch<{BaseType}, {Size}>"; +} + public sealed partial record ShaderMixinType : SymbolType { public override string ToString() => "mixin"; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 61cbf22b57..2225da778f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1059,12 +1059,15 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) { streamVar.AllowStreamVariables = true; streamVar.ProcessSymbol(table); - accessor.Type = streamVar.Type; + accessor.Type = (PointerType)streamVar.Type with { StorageClass = p.StorageClass }; break; } - // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now\ + // Since we cheated a bit by overwriting the accessor.Type, set it back during Compile() + accessor.Type = (PointerType)accessor.Type with { StorageClass = Specification.StorageClass.Private }; + // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now var streamVariableResult = streamVar.Compile(table, compiler); + accessor.Type = (PointerType)accessor.Type with { StorageClass = p.StorageClass }; PushAccessChainId(accessChainIds, streamVariableResult.Id); break; case (PointerType { BaseType: StructType s } p, Identifier field): @@ -1305,6 +1308,18 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) --i; break; } + case (PointerType { BaseType: PatchType { BaseType: var t } } p, IndexerExpression indexer): + { + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(t, p.StorageClass); + break; + } + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); + break; + } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { if (compiler == null) @@ -1335,7 +1350,7 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) break; } default: - throw new NotImplementedException($"unknown accessor {accessor} in expression {this}"); + throw new NotImplementedException($"unknown accessor {accessor} on type {currentValueType} in expression {this}"); } currentValueType = accessor.Type; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index d7f2440f82..0dc498fe63 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -584,7 +584,7 @@ public class TypeName(string name, TextLocation info) : Literal(info) public string Name { get; set; } = name; public bool IsArray => ArraySize != null && ArraySize.Count > 0; public List? ArraySize { get; set; } - public List Generics { get; set; } = []; + public List Generics { get; set; } = []; public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWhen(false)] out SymbolType symbolType) { @@ -604,8 +604,15 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh { symbolType = new GenericParameterType(Specification.GenericParameterKindSDSL.MemberNameResolved); } - else if (Name == "Streams" || Name == "Input" || Name == "Output") + else if (Name is nameof(Specification.StreamsKindSDSL.Streams) + or nameof(Specification.StreamsKindSDSL.Input) + or nameof(Specification.StreamsKindSDSL.Output) + or "Input2" + or nameof(Specification.StreamsKindSDSL.Constants)) { + // In Hull shader, Input2 (obsolete) is same as Output + if (Name == "Input2") + Name = nameof(Specification.StreamsKindSDSL.Output); symbolType = new StreamsType(Enum.Parse(Name)); } else @@ -617,13 +624,21 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh } else if (Name == "PointStream" || Name == "LineStream" || Name == "TriangleStream") { - symbolType = new GeometryStreamType(Generics[0].ResolveType(table, context), Name switch + symbolType = new GeometryStreamType(((TypeName)Generics[0]).ResolveType(table, context), Name switch { "PointStream" => Specification.GeometryStreamOutputKindSDSL.Point, "LineStream" => Specification.GeometryStreamOutputKindSDSL.Line, "TriangleStream" => Specification.GeometryStreamOutputKindSDSL.Triangle, }); } + else if (Name == "InputPatch" || Name == "OutputPatch") + { + symbolType = new PatchType(((TypeName)Generics[0]).ResolveType(table, context), Name switch + { + "InputPatch" => Specification.PatchTypeKindSDSL.Input, + "OutputPatch" => Specification.PatchTypeKindSDSL.Output, + }, ((NumberLiteral)Generics[1]).IntValue); + } else if (SymbolType.TryGetNumeric(Name, out var numeric)) { table.DeclaredTypes.Add(fullTypeName, numeric); @@ -634,7 +649,7 @@ public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWh table.DeclaredTypes.Add(fullTypeName, bufferType); symbolType = bufferType; } - else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, Generics[0], out var genericBufferType)) + else if (Generics.Count == 1 && SymbolType.TryGetBufferType(Name, (TypeName)Generics[0], out var genericBufferType)) { table.DeclaredTypes.Add(fullTypeName, genericBufferType); symbolType = genericBufferType; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 2dcf73b3cc..4f21943b5a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -242,6 +242,10 @@ void RegisterName(int target, string name) { RegisterType(typeGeometryStreamOutput.ResultId, new GeometryStreamType(context.ReverseTypes[typeGeometryStreamOutput.BaseType], typeGeometryStreamOutput.Kind)); } + else if (instruction.Op == Op.OpTypePatchSDSL && (OpTypePatchSDSL)instruction is { } typePatch) + { + RegisterType(typePatch.ResultId, new PatchType(context.ReverseTypes[typePatch.BaseType], typePatch.Kind, typePatch.Size)); + } // Unresolved content // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 59f6be26e7..d722df5ce0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -205,10 +205,10 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) (StructuredBufferType, _, _) => Specification.StorageClass.StorageBuffer, (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, (_, StorageClass.Static, _) => Specification.StorageClass.Private, - (_, _, StreamKind.Stream) => Specification.StorageClass.Private, + (_, _, StreamKind.Stream or StreamKind.PatchStream) => Specification.StorageClass.Private, _ => Specification.StorageClass.Uniform, }; - + if (TypeModifier == TypeModifier.Const) { if (Value == null) @@ -257,7 +257,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var pointerType = (PointerType)Type; var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; - if (StreamKind == StreamKind.Stream) + if (StreamKind == StreamKind.Stream || StreamKind == StreamKind.PatchStream) variableFlags |= Specification.VariableFlagsMask.Stream; int? initializerMethod = null; @@ -288,10 +288,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler Symbol.IdRef = variable; + if (StreamKind == StreamKind.PatchStream) + context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); + if (pointerType.BaseType is StructuredBufferType) - { context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"structuredbuffer:<{pointerType.BaseType.ToId().ToLowerInvariant()}>")); - } RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } @@ -409,6 +410,13 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) firstDefaultParameter = index; defaultParameters[index] = arg.DefaultValue.CompileConstantValue(table, context, arg.Type).Id; } + + if (arg.Semantic != null) + { + // We use OpMemberDecorateString on the function ID + // but this is not valid so we'll need to make sure to remove that after the ShaderMixer + context.Add(new OpMemberDecorateString(function.Id, index, Specification.Decoration.UserSemantic, arg.Semantic)); + } } var symbol = new Symbol(new(Name, SymbolKind.Method, IsStage: IsStaged), ftype, function.Id, MemberAccessWithImplicitThis: ftype, OwnerType: table.CurrentShader); @@ -470,6 +478,49 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); } + else if (anyAttribute.Name == "outputcontrolpoints") + { + var outputControlPoints = anyAttribute.Parameters[0].CompileConstantValue(table, context); + if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _, false)) + throw new InvalidOperationException(); + + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)outputControlPointsValue))); + } + else if (anyAttribute.Name == "patchconstantfunc") + { + context.Add(new OpDecorateString(function.Id, Specification.Decoration.PatchConstantFuncSDSL, ((StringLiteral)anyAttribute.Parameters[0]).Value)); + } + else if (anyAttribute.Name == "domain") + { + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "tri" => Specification.ExecutionMode.Triangles, + "quad" => Specification.ExecutionMode.Quads, + "isolined" => Specification.ExecutionMode.Isolines, + }, [])); + } + else if (anyAttribute.Name == "partitioning") + { + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "fractional_odd" => Specification.ExecutionMode.SpacingFractionalOdd, + "fractional_even" => Specification.ExecutionMode.SpacingFractionalEven, + "integer" => Specification.ExecutionMode.SpacingEqual, + "pow2" => throw new NotSupportedException("partitioning pow2 is not supported in SPIR-V"), + }, [])); + } + else if (anyAttribute.Name == "outputtopology") + { + var value = ((StringLiteral)anyAttribute.Parameters[0]).Value; + if (value != "line") + { + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "triangle_cw" => Specification.ExecutionMode.VertexOrderCw, + "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw, + }, [])); + } + } else { throw new NotImplementedException($"Can't parse method attribute {anyAttribute} on method {Name}"); @@ -513,7 +564,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var p = Parameters[index]; var parameterSymbol = ParameterSymbols[index]; var parameterType = parameterSymbol.Type; - var paramValue = builder.AddFunctionParameter(context, p.Name, parameterType); + var paramValue = builder.EmitFunctionParameter(context, p.Name, parameterType); parameterSymbol.IdRef = paramValue.Id; } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 3a28d07b65..513fb298a8 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -80,7 +80,7 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, if (Parsers.FollowedBy(ref scanner, Tokens.Char('<'), withSpaces: true, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); + Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); if (!Parsers.FollowedBy(ref scanner, Tokens.Char('>'), withSpaces: true, advance: true)) return Parsers.Exit(ref scanner, result, out name, position); name.Info = scanner[position..scanner.Position]; @@ -107,17 +107,17 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, else return Parsers.Exit(ref scanner, result, out name, position, orError); } - public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, out TypeName parsed, in ParseError? orError = null) + public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (TypeName(ref scanner, result, out var typename)) { - parsed = (TypeName)typename; + parsed = typename; return true; } else if (Number(ref scanner, result, out var number)) { - parsed = new TypeName(number.ToString() ?? "", number.Info); + parsed = number; return true; } else return Parsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index aff13c1d1f..5944f337a0 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -41,7 +41,7 @@ public void EndFunction() Buffer.Insert(Position++, new OpFunctionEnd()); } - public SpirvValue AddFunctionParameter(SpirvContext context, string name, SymbolType type) + public SpirvValue EmitFunctionParameter(SpirvContext context, string name, SymbolType type) { var p = Buffer.Insert(Position++, new OpFunctionParameter(context.GetOrRegister(type), context.Bound++)); context.AddName(p, name); @@ -49,4 +49,58 @@ public SpirvValue AddFunctionParameter(SpirvContext context, string name, Symbol CurrentFunction!.Value.Parameters.Add(name, value); return value; } + + public static OpFunctionParameter GetFunctionParameter(NewSpirvBuffer buffer, Symbol method, int functionParameterIndex) + { + // Find OpFunctionParameter + var functionParameterCurrent = 0; + (var start, var end) = FindMethodBounds(buffer, method.IdRef); + for (int index = start; index < end; ++index) + { + var i = buffer[index]; + if (i.Op == Op.OpFunctionParameter && functionParameterCurrent++ == functionParameterIndex && (OpFunctionParameter)i is {} functionParameter) + { + return functionParameter; + } + } + + throw new InvalidOperationException(); + } + + public static void FunctionRemoveArgument(SpirvContext context, NewSpirvBuffer buffer, Symbol method, int argIndex) + { + var methodType = (FunctionType)method.Type; + method.Type = methodType with { ParameterTypes = methodType.ParameterTypes[0..^1] }; + + // Find OpFunctionParameter and remove it + var functionParameter = GetFunctionParameter(buffer, method, argIndex); + SetOpNop(functionParameter.InstructionMemory.Span); + } + + public static void FunctionReplaceArgument(SpirvContext context, NewSpirvBuffer buffer, Symbol method, int argIndex, SymbolType newType) + { + var methodType = (FunctionType)method.Type; + var parameterTypes = new List(methodType.ParameterTypes); + parameterTypes[argIndex] = parameterTypes[argIndex] with { Type = newType }; + method.Type = methodType with { ParameterTypes = parameterTypes }; + + // Find OpFunctionParameter and remove it + var functionParameter = GetFunctionParameter(buffer, method, argIndex); + functionParameter.ResultType = context.GetOrRegister(newType); + } + + public static (int Start, int End) FindMethodBounds(NewSpirvBuffer buffer, int functionId) + { + int? start = null; + for (var index = 0; index < buffer.Count; index++) + { + var instruction = buffer[index]; + if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId) + start = index; + if (instruction.Op is Op.OpFunctionEnd && start is int startIndex) + return (startIndex, index + 1); + } + throw new InvalidOperationException($"Could not find start of method {functionId}"); + } + } \ No newline at end of file diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index 88b174927e..c43837ffa3 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -6,11 +6,6 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvContext { - public void ReplaceType() - { - throw new NotImplementedException(); - } - public int GetOrRegister(SymbolType? type) { if (type is null) @@ -21,21 +16,34 @@ public int GetOrRegister(SymbolType? type) return RegisterType(type, Bound++); } + public void ReplaceType(SymbolType type, int id) + { + RemoveType(id); + RegisterType(type, id); + } + public int RemoveType(SymbolType type) { var typeId = Types[type]; + RemoveType(typeId); + return typeId; + } + + public void RemoveType(int typeId) + { foreach (var i in Buffer) { if (i.Data.IdResult == typeId) { SpirvBuilder.SetOpNop(i.Data.Memory.Span); + var type = ReverseTypes[typeId]; Types.Remove(type); ReverseTypes.Remove(typeId); - return typeId; + return; } } - throw new InvalidOperationException($"Type to remove {type} was not found"); + throw new InvalidOperationException($"Type to remove {typeId} was not found"); } public int RegisterType(SymbolType type, int id) @@ -82,6 +90,7 @@ public int RegisterType(SymbolType type, int id) GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(id, g.Kind)).IdResult, StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(id, s.Kind)).IdResult, GeometryStreamType so => Buffer.Add(new OpTypeGeometryStreamOutputSDSL(id, GetOrRegister(so.BaseType), so.Kind)).IdResult, + PatchType patch => Buffer.Add(new OpTypePatchSDSL(id, GetOrRegister(patch.BaseType), patch.Kind, patch.Size)).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 8799b53a68..26417e38ed 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -30,6 +30,7 @@ enum StreamVariableType class StreamInfo(string? semantic, string name, PointerType type, int variableId) { + public bool Patch { get; set; } public string? Semantic { get; } = semantic; public string Name { get; } = name; public SymbolType Type { get; } = type.BaseType; @@ -42,7 +43,7 @@ class StreamInfo(string? semantic, string name, PointerType type, int variableId public int? OutputLayoutLocation { get; set; } /// - /// We automatically mark input: a variable read before it's written to, or an output without a write. + /// We automatically mark input: a variable read before it's written to, or an output without a write /// public bool Input => Read || (Output && !Write); public bool Output { get => field; set { field = value; UsedAnyStage = true; } } @@ -53,6 +54,8 @@ class StreamInfo(string? semantic, string name, PointerType type, int variableId public bool UsedAnyStage { get; private set; } public int? InputStructFieldIndex { get; internal set; } public int? OutputStructFieldIndex { get; internal set; } + + // Note: if Patch is true, it will be index in CONSTANTS struct, otherwise STREAMS struct public int StreamStructFieldIndex { get; internal set; } public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; @@ -170,31 +173,31 @@ public bool MarkMethodUsed(int functionId) public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); + Symbol? ResolveEntryPoint(SymbolTable table, string name) + { + table.TryResolveSymbol(name, out var entryPoint); + return entryPoint?.Type switch + { + FunctionGroupType => entryPoint.GroupMembers[^1], + _ => entryPoint + }; + } + public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) { var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); - table.TryResolveSymbol("VSMain", out var entryPointVS); - table.TryResolveSymbol("GSMain", out var entryPointGS); - table.TryResolveSymbol("PSMain", out var entryPointPS); - table.TryResolveSymbol("CSMain", out var entryPointCS); + var entryPointVS = ResolveEntryPoint(table, "VSMain"); + var entryPointHS = ResolveEntryPoint(table, "HSMain"); + var entryPointDS = ResolveEntryPoint(table, "DSMain"); + var entryPointGS = ResolveEntryPoint(table, "GSMain"); + var entryPointPS = ResolveEntryPoint(table, "PSMain"); + var entryPointCS = ResolveEntryPoint(table, "CSMain"); - if (entryPointCS?.Type is FunctionGroupType) - entryPointCS = entryPointCS.GroupMembers[^1]; - if (entryPointGS?.Type is FunctionGroupType) - entryPointGS = entryPointGS.GroupMembers[^1]; - if (entryPointVS?.Type is FunctionGroupType) - entryPointVS = entryPointVS.GroupMembers[^1]; - if (entryPointPS?.Type is FunctionGroupType) - entryPointPS = entryPointPS.GroupMembers[^1]; - - if (entryPointPS == null && entryPointCS == null) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); + var entryPointPSOrCS = entryPointCS ?? entryPointPS ?? throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); if (entryPointPS == null && entryPointCS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); - var entryPointPSOrCS = entryPointCS ?? entryPointPS; - var analysisResult = Analyze(buffer, context); MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; @@ -207,6 +210,11 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); } + + if (entryPointHS != null || entryPointDS != null) + context.Add(new OpCapability(Capability.Tessellation)); + else if (entryPointGS != null) + context.Add(new OpCapability(Capability.Geometry)); var inputAttributes = new List(); @@ -215,9 +223,11 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con // If written to, they are expected at the end of pixel shader foreach (var stream in streams) { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") - && stream.Value.Write) - stream.Value.Output = true; + if (stream.Value.Semantic is { } semantic) + { + if ((semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") && stream.Value.Write) + stream.Value.Output = true; + } } // Check if there is any output @@ -241,28 +251,49 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con ResetUsedThisStage(analysisResult, liveAnalysis); PropagateStreamsFromPreviousStage(streams); - - if (entryPointGS != null) + + foreach (var entryPoint in new[] { (ExecutionModel.TessellationControl, entryPointHS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.Geometry, entryPointGS) }) { - AnalyzeStreamReadWrites(buffer, context, entryPointGS.IdRef, analysisResult, liveAnalysis); - - // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader - foreach (var stream in streams) + if (entryPoint.Item2 != null) { - if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - stream.Value.Output = true; - } + AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); + + // Find patch constant entry point and process it as well + var patchConstantEntryPoint = entryPoint.Item1 == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint.Item2) : null; + if (patchConstantEntryPoint != null) + AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); - (var gsWrapperId, var gsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Geometry, entryPointGS, analysisResult, liveAnalysis, false); - entryPoints.Add((gsWrapperName, gsWrapperId, ShaderStage.Geometry)); + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic) + { + if (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + stream.Value.Output = true; + + if (entryPoint.Item1 == ExecutionModel.TessellationControl + && (semantic.ToUpperInvariant().StartsWith("SV_TESSFACTOR") || semantic.ToUpperInvariant().StartsWith("SV_INSIDETESSFACTOR"))) + stream.Value.Output = true; + } + } - // Reset cbuffer/resource/methods used for next stage - ResetUsedThisStage(analysisResult, liveAnalysis); + (var wrapperId, var wrapperName) = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); + var stage = entryPoint.Item1 switch + { + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + }; + entryPoints.Add((wrapperName, wrapperId, stage)); + + // Reset cbuffer/resource/methods used for next stage + ResetUsedThisStage(analysisResult, liveAnalysis); - PropagateStreamsFromPreviousStage(streams); + PropagateStreamsFromPreviousStage(streams); - if (entryPointVS == null) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a geometry shader is specified, a vertex shader is needed too"); + if (entryPointVS == null) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); + } } if (entryPointVS != null) @@ -447,11 +478,11 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c } } - // Remove all OpTypeStreamsSDSL and OpTypeGeometryStreamOutputSDSL or any type that depends on it + // Remove all OpTypeStreamsSDSL, OpTypePatchSDSL and OpTypeGeometryStreamOutputSDSL or any type that depends on it // (we do that before the OpName/OpDecorate pass) foreach (var i in context) { - if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) + if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypePatchSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) { if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) { @@ -506,6 +537,24 @@ private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); } + + static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) + { + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is + { + EntryPoint: var target, + Mode: ExecutionMode.OutputVertices, + ModeParameters: { } m, + } && target == entryPoint.IdRef) + { + return m.Span[0]; + } + } + + throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); + } private static void PropagateStreamsFromPreviousStage(Dictionary streams) { @@ -532,6 +581,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) // Build name table Dictionary nameTable = []; Dictionary semanticTable = []; + HashSet patchVariables = []; foreach (var i in context) { // Names @@ -567,13 +617,18 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) Target: int t, Decoration: Decoration.UserSemantic, Value: string m - } ) { semanticTable[t] = m; } } + + // Patch + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Target: int t3, Decoration: Decoration.Patch }) + { + patchVariables.Add(t3); + } } // Analyze streams @@ -607,7 +662,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (variable.MethodInitializer != null) throw new NotImplementedException("Variable initializer is not supported on streams variable"); - streams.Add(variable.ResultId, new StreamInfo(semantic, name, type, variable.ResultId)); + streams.Add(variable.ResultId, new StreamInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); } else { @@ -691,13 +746,18 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) var stage = executionModel switch { ExecutionModel.Vertex => "VS", + ExecutionModel.TessellationControl => "HS", + ExecutionModel.TessellationEvaluation => "DS", ExecutionModel.Geometry => "GS", ExecutionModel.Fragment => "PS", ExecutionModel.GLCompute => "CS", _ => throw new NotImplementedException() }; - List<(StreamInfo Info, int Id)> inputStreams = []; - List<(StreamInfo Info, int Id)> outputStreams = []; + List<(StreamInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; + List<(StreamInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; + List<(StreamInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; + List<(StreamInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; + List entryPointExtraVariables = []; int inputLayoutLocationCount = 0; int outputLayoutLocationCount = 0; @@ -726,16 +786,64 @@ bool AddLocation(int variable, string location) context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); return true; } + + // Handle some conversions for builtins where type is not flexible + // need to handle array size adjust, and vector size adjust as per ProcessBuiltinsDecoration() symbolType processing + int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) + { + if (sourceType == castType) + return value; + + if (sourceType is VectorType v1 && castType is VectorType v2 && v1.BaseType == v2.BaseType) + { + Span components = stackalloc int[v2.Size]; + for (int i = 0; i < v2.Size; ++i) + { + components[i] = i < v1.Size + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).IdResult.Value + : context.CreateDefaultConstantComposite(v1.BaseType).Id; + } + + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).IdResult.Value; + } + + if (sourceType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType) + { + Span components = stackalloc int[a2.Size]; + for (int i = 0; i < a2.Size; ++i) + { + components[i] = i < a1.Size + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).IdResult.Value + : context.CreateDefaultConstantComposite(a1.BaseType).Id; + } + + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).IdResult.Value; + } + + throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); + } - bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo stream) + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) { + semantic = semantic?.ToUpperInvariant(); + symbolType = (executionModel, type, semantic) switch + { + // DX might use float[2] or float[3] or float[4] but Vulkan expects float[4] in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_TESSFACTOR") => new ArrayType(ScalarType.Float, 4), + // DX might use float or float[2] but Vulkan expects float[2] in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_INSIDETESSFACTOR") => new ArrayType(ScalarType.Float, 2), + // DX might use float2 or float3 but Vulkan expects float3 in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_DOMAINLOCATION") => new VectorType(ScalarType.Float, 3), + _ => symbolType, + }; + // Note: false means it needs to be forwarded // TODO: review the case where we don't use automatic forwarding for HS/DS/GS stages, i.e. SV_POSITION and SV_PrimitiveID - return (executionModel, type, stream.Semantic?.ToUpperInvariant()) switch + return (executionModel, type, semantic) switch { // SV_Depth/SV_Target (ExecutionModel.Fragment, StreamVariableType.Output, "SV_DEPTH") => AddBuiltin(variable, BuiltIn.FragDepth), - (ExecutionModel.Fragment, StreamVariableType.Output, {} semantic) when semantic.StartsWith("SV_TARGET") => AddLocation(variable, semantic.Substring("SV_TARGET".Length)), + (ExecutionModel.Fragment, StreamVariableType.Output, {} semantic2) when semantic2.StartsWith("SV_TARGET") => AddLocation(variable, semantic2.Substring("SV_TARGET".Length)), // SV_Position (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), @@ -747,56 +855,72 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo // SV_IsFrontFace (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(variable, BuiltIn.FrontFacing), // SV_PrimitiveID - (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PrimitiveID") => AddBuiltin(variable, BuiltIn.PrimitiveId), - (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PrimitiveID") => AddBuiltin(variable, BuiltIn.PrimitiveId), + (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PRIMITIVEID") => AddBuiltin(variable, BuiltIn.PrimitiveId), + (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PRIMITIVEID") => AddBuiltin(variable, BuiltIn.PrimitiveId), + // Tessellation + (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_TESSFACTOR") => AddBuiltin(variable, BuiltIn.TessLevelOuter), + (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_INSIDETESSFACTOR") => AddBuiltin(variable, BuiltIn.TessLevelInner), + (ExecutionModel.TessellationEvaluation, StreamVariableType.Input, "SV_DOMAINLOCATION") => AddBuiltin(variable, BuiltIn.TessCoord), + (ExecutionModel.TessellationControl, StreamVariableType.Input, "SV_OUTPUTCONTROLPOINTID") => AddBuiltin(variable, BuiltIn.InvocationId), // Compute shaders (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPID") => AddBuiltin(variable, BuiltIn.WorkgroupId), (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPINDEX") => AddBuiltin(variable, BuiltIn.LocalInvocationIndex), (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPTHREADID") => AddBuiltin(variable, BuiltIn.LocalInvocationId), (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_DISPATCHTHREADID") => AddBuiltin(variable, BuiltIn.GlobalInvocationId), - (_, _, {} semantic) when semantic.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic} for stage {executionModel} as {type}"), + (_, _, {} semantic2) when semantic2.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic2} for stage {executionModel} as {type}"), _ => false, }; } var entryPointFunctionType = (FunctionType)entryPoint.Type; - var geometryInputSize = executionModel == ExecutionModel.Geometry ? ((ArrayType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size : 1; + // TODO: check all parameters instead of hardcoded 0 + int? arrayInputSize = executionModel switch + { + ExecutionModel.Geometry => ((ArrayType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, + ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation => ((PatchType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, + _ => null, + }; + int? arrayOutputSize = executionModel switch + { + ExecutionModel.TessellationControl => FindOutputPatchSize(context, entryPoint), + _ => null, + }; foreach (var stream in streams) { if (stream.Value.Input) { - // Note: for geometry shader, we process multiple inputs at once (in an array) - var streamInputType = new PointerType(executionModel == ExecutionModel.Geometry - ? new ArrayType(stream.Value.Type, geometryInputSize) - : stream.Value.Type, - Specification.StorageClass.Input); - context.FluentAdd(new OpVariable(context.GetOrRegister(streamInputType), context.Bound++, Specification.StorageClass.Input, null), out var variable); - context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - - if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Input, stream.Value)) + var variableId = context.Bound++; + var variableType = stream.Value.Type; + if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, stream.Value.Semantic, ref variableType)) { if (stream.Value.InputLayoutLocation == null) stream.Value.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variable, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); + context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); + context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); } + + // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants + var streamInputType = new PointerType(!stream.Value.Patch && arrayInputSize != null + ? new ArrayType(variableType, arrayInputSize.Value) + : variableType, + Specification.StorageClass.Input); + context.FluentAdd(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null), out var variable); + context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - if (!stream.Value.Type.GetElementType().IsFloating()) + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); stream.Value.InputId = variable.ResultId; - inputStreams.Add((stream.Value, variable.ResultId)); + (stream.Value.Patch ? patchInputStreams : inputStreams).Add((stream.Value, variable.ResultId, variableType)); } if (stream.Value.Output) { - var streamOutputType = new PointerType(stream.Value.Type, Specification.StorageClass.Output); - context.FluentAdd(new OpVariable(context.GetOrRegister(streamOutputType), context.Bound++, Specification.StorageClass.Output, null), out var variable); - context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - - if (!ProcessBuiltinsDecoration(variable.ResultId, StreamVariableType.Output, stream.Value)) + var variableId = context.Bound++; + var variableType = stream.Value.Type; + if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Output, stream.Value.Semantic, ref variableType)) { // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic if (stream.Value.OutputLayoutLocation == null) @@ -807,20 +931,29 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); } - context.Add(new OpDecorate(variable, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); + context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variable, Decoration.UserSemantic, stream.Value.Semantic)); + context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); } + + // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants + var streamOutputType = new PointerType(!stream.Value.Patch && arrayOutputSize != null + ? new ArrayType(variableType, arrayOutputSize.Value) + : variableType, + Specification.StorageClass.Output); + context.FluentAdd(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null), out var variable); + context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - if (!stream.Value.Type.GetElementType().IsFloating()) + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); stream.Value.OutputId = variable.ResultId; - outputStreams.Add((stream.Value, variable.ResultId)); + (stream.Value.Patch ? patchOutputStreams : outputStreams).Add((stream.Value, variable.ResultId, variableType)); } } - var fields = new List(); + var streamFields = new List(); + var constantFields = new List(); var inputFields = new List(); var outputFields = new List(); foreach (var stream in streams) @@ -829,6 +962,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo stream.Value.OutputStructFieldIndex = null; if (stream.Value.UsedThisStage) { + var fields = (stream.Value.Patch) ? constantFields : streamFields; stream.Value.StreamStructFieldIndex = fields.Count; fields.Add(new(stream.Value.Name, stream.Value.Type, default)); } @@ -848,14 +982,21 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo var inputType = new StructType($"{stage}_INPUT", inputFields); var outputType = new StructType($"{stage}_OUTPUT", outputFields); - var streamsType = new StructType($"{stage}_STREAMS", fields); + var streamsType = new StructType($"{stage}_STREAMS", streamFields); + bool hasConstants = executionModel is ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation; + var constantsType = hasConstants ? new StructType($"{stage}_CONSTANTS", constantFields) : null; context.DeclareStructuredType(inputType, context.Bound++); context.DeclareStructuredType(outputType, context.Bound++); context.DeclareStructuredType(streamsType, context.Bound++); + if (hasConstants) + context.DeclareStructuredType(constantsType, context.Bound++); // Create a static global streams variable context.FluentAdd(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null), out var streamsVariable); context.AddName(streamsVariable.ResultId, $"streams{stage}"); + + // Find patch constant entry point + var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; // Patch any OpStreams/OpAccessChain to use the new struct foreach (var method in liveAnalysis.ReferencedMethods) @@ -863,7 +1004,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo if (method.Value.UsedThisStage && method.Value.HasStreamAccess) { DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis); - PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, streamsVariable.ResultId, analysisResult, liveAnalysis); + PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); } } @@ -881,7 +1022,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo // Variable initializers foreach (var variable in analysisResult.Variables) { - // Note: we check Private to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) + // Note: we check UsedThisStage to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) if (variable.Value.UsedThisStage && variable.Value.VariableMethodInitializerId is int methodInitializerId) { @@ -893,83 +1034,344 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo } } - // Setup input and call original main() - if (executionModel == ExecutionModel.Geometry) + // Update entry point type (since Streams type might have been replaced) + entryPointFunctionType = (FunctionType)entryPoint.Type; + + var builtinVariables = new Dictionary(); + int GetOrDeclareBuiltInValue(SymbolType type, string semantic) { - context.Add(new OpCapability(Capability.Geometry)); + semantic = semantic.ToUpperInvariant(); + if (builtinVariables.TryGetValue(semantic, out var result)) + { + if (result.Type != type) + throw new InvalidOperationException($"Semantic {semantic} requested with type {type} but last time with {result.Type}"); + return result.Id; + } + // Declare the global builtin + var variableId = context.Bound++; + if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, semantic, ref type)) + throw new InvalidOperationException(); + var variable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(type, Specification.StorageClass.Input)), variableId, Specification.StorageClass.Input, null)).IdResult.Value; + entryPointExtraVariables.Add(variable); + var value = buffer.Add(new OpLoad(context.GetOrRegister(type), context.Bound++, variable, null, [])).IdResult.Value; + builtinVariables.Add(semantic, (type, value)); + return value; + } + void FillSemanticArguments(FunctionType functionType, Span arguments) + { + foreach (var i in context) + { + if (i.Op == Op.OpMemberDecorateString + && ((OpMemberDecorateString)i) is + { + StructType: int t, + Decoration: Decoration.UserSemantic, + Value: string semantic, + Member: int argumentIndex, + } && t == entryPoint.IdRef + ) + { + var argumentType = ((PointerType)functionType.ParameterTypes[argumentIndex].Type).BaseType; + + var value = GetOrDeclareBuiltInValue(argumentType, semantic); + + // Create local variable with StorageClass.Function that we can use as argument + var localVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(argumentType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + buffer.Add(new OpStore(localVariable, value, null, [])); + arguments[argumentIndex] = localVariable; + + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + + // Fill parameters with semantics + Span arguments = stackalloc int[entryPointFunctionType.ParameterTypes.Count]; + FillSemanticArguments(entryPointFunctionType, arguments); + + // Setup input and call original main() + if (arrayInputSize != null) + { // Copy variables to Input[X] which is first method parameter of main() // Pattern is a loop over index i looking like: // inputs[i].Position = gl_Position[i]; // inputs[i].Normal = in_GS_normals[i]; - var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, geometryInputSize), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; context.AddName(inputsVariable, "inputs"); - Span inputLoadValues = stackalloc int[inputFields.Count]; - for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) - { - var stream = inputStreams[inputIndex]; - buffer.FluentAdd(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, geometryInputSize)), context.Bound++, stream.Id, null, []), out var loadedValue); - inputLoadValues[inputIndex] = loadedValue.ResultId; - } - - Span inputFieldValues = stackalloc int[inputFields.Count]; - Span inputValues = stackalloc int[geometryInputSize]; - for (int arrayIndex = 0; arrayIndex < geometryInputSize; ++arrayIndex) + int ConvertInputsArray() { + Span inputLoadValues = stackalloc int[inputFields.Count]; for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) { var stream = inputStreams[inputIndex]; - inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).IdResult.Value; + buffer.FluentAdd(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, []), out var loadedValue); + inputLoadValues[inputIndex] = loadedValue.ResultId; } + + Span inputFieldValues = stackalloc int[inputFields.Count]; + Span inputValues = stackalloc int[arrayInputSize.Value]; + for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + { + for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + { + var stream = inputStreams[inputIndex]; + inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).IdResult.Value; + inputFieldValues[inputIndex] = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); + } - inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).IdResult.Value; - } + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).IdResult.Value; + } - var inputsData = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, geometryInputSize)), context.Bound++, [..inputValues])).IdResult.Value; + var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).IdResult.Value; + return inputsData1; + } + + var inputsData = ConvertInputsArray(); + buffer.Add(new OpStore(inputsVariable, inputsData, null, [])); - - // Change signature of main() to not use output anymore - // Note: OpFunctionParameter will be removed as part of PatchStreamsAccesses() - var entryPointTypeId = context.RemoveType(entryPoint.Type); - entryPoint.Type = entryPointFunctionType with { ParameterTypes = entryPointFunctionType.ParameterTypes[0..^1] }; - var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; - if (executionMode == ParameterModifiers.None) - throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); - context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch + + var entryPointTypeId = context.GetOrRegister(entryPoint.Type); + if (executionModel == ExecutionModel.TessellationControl || executionModel == ExecutionModel.TessellationEvaluation) { - ParameterModifiers.Point => ExecutionMode.InputPoints, - ParameterModifiers.Line => ExecutionMode.InputLines, - ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, - ParameterModifiers.Triangle => ExecutionMode.Triangles, - ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, - }, [])); - entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; - context.RegisterType(entryPoint.Type, entryPointTypeId); - - // Call main(inputs) - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, [inputsVariable])); + bool hullTessellationOutputsGenerated = false; + int GenerateHullTessellationOutputs() + { + if (hullTessellationOutputsGenerated) + throw new InvalidOperationException("Hull OutputPatch can only be used in once place (constant patch)"); + hullTessellationOutputsGenerated = true; + var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + context.AddName(outputsVariable, "outputs"); + + for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + { + for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + { + var stream = outputStreams[outputIndex]; + var outputsVariablePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), + context.Bound++, outputsVariable, + [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).IdResult.Value; + var outputSourcePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), + context.Bound++, stream.Id, + [context.CompileConstant(arrayIndex).Id])).IdResult.Value; + var outputsSourceValue = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, outputSourcePtr, null, [])).IdResult.Value; + outputsSourceValue = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputsSourceValue); + buffer.Add(new OpStore(outputsVariablePtr, outputsSourceValue, null, [])); + } + } + + return outputsVariable; + } + + void FillTessellationArguments(Symbol function, Span arguments) + { + var functionType = (FunctionType)function.Type; + var functionTypeId = context.GetOrRegister(functionType); + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + { + var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; + var parameterModifiers = functionType.ParameterTypes[i].Modifiers; + switch (parameterType) + { + // Hull/Domain inputs + case PatchType inputPatchType when + (inputPatchType.Kind == PatchTypeKindSDSL.Input && executionModel == ExecutionModel.TessellationControl) + || (inputPatchType.Kind == PatchTypeKindSDSL.Output && executionModel == ExecutionModel.TessellationEvaluation): + { + // Change signature of main() to use an array instead of InputPatch + // InputPatch becomes HS_INPUT[X] + SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(inputPatchType.BaseType, inputPatchType.Size), Specification.StorageClass.Function)); + context.ReplaceType(function.Type, functionTypeId); + arguments[i] = inputsVariable; + break; + } + // Hull outputs + case PatchType { Kind: PatchTypeKindSDSL.Output } outputPatchType when executionModel == ExecutionModel.TessellationControl: + { + // Change signature of main() to use an array instead of InputPatch + // InputPatch becomes HS_INPUT[X] + SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(outputPatchType.BaseType, outputPatchType.Size), Specification.StorageClass.Function)); + context.ReplaceType(function.Type, functionTypeId); + arguments[i] = GenerateHullTessellationOutputs(); + break; + } + case StructType t when (t == constantsType) && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: + { + // Parameter is "HS_CONSTANTS constants" + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = constantVariable; + // Copy back values from semantic/builtin variables to Constants struct + foreach (var stream in patchInputStreams) + { + var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).IdResult.Value; + var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).IdResult.Value; + inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); + buffer.Add(new OpStore(inputPtr, inputResult, null, [])); + } + break; + } + case StructType t when (t == outputType || t == constantsType) && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" + var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = outVariable; + break; + } + case var t when arguments[i] == 0: + throw new NotImplementedException($"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}"); + } + } + } + + void ProcessTessellationArguments(Symbol function, Span arguments) + { + var functionType = (FunctionType)function.Type; + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + { + var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; + var parameterModifiers = functionType.ParameterTypes[i].Modifiers; + switch (parameterType) + { + case StructType t when t == outputType && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).IdResult.Value; + // Do we need to index into array? if yes, get index (gl_invocationID) + int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; + // Copy back values from Output struct to semantic/builtin variables + for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + { + var stream = outputStreams[outputIndex]; + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).IdResult.Value; + outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); + var outputTargetPtr = arrayOutputSize != null + ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), + context.Bound++, stream.Id, + [invocationIdValue.Value])).IdResult.Value + : stream.Id; + buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); + } + break; + } + case StructType t when t == constantsType && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).IdResult.Value; + // Copy back values from Output struct to semantic/builtin variables + foreach (var stream in patchOutputStreams) + { + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).IdResult.Value; + outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); + buffer.Add(new OpStore(stream.Id, outputResult, null, [])); + } + break; + } + } + } + } + + FillTessellationArguments(entryPoint, arguments); + + // Call main(inputs, output, ...) + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + + ProcessTessellationArguments(entryPoint, arguments); + + if (patchConstantEntryPoint != null) + { + // Insert a barrier + buffer.Add(new OpControlBarrier(context.CompileConstant(2).Id, context.CompileConstant(4).Id, context.CompileConstant(0).Id)); + + liveAnalysis.MarkMethodUsed(patchConstantEntryPoint.IdRef); + + // Load gl_InvocationID to check if we're invocation 0 + var invocationIdValue = GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID"); + + // Compare with 0 + var zeroConstant = context.CompileConstant(0u).Id; + var isInvocationZero = buffer.Add(new OpIEqual(context.GetOrRegister(ScalarType.Boolean), context.Bound++, invocationIdValue, zeroConstant)).IdResult.Value; + + // Create labels for if-then-merge + var thenLabel = context.Bound++; + var mergeLabel = context.Bound++; + + // Branch based on condition + buffer.Add(new OpSelectionMerge(mergeLabel, SelectionControlMask.None)); + buffer.Add(new OpBranchConditional(isInvocationZero, thenLabel, mergeLabel, [])); + + // Then block: call patch constant function + buffer.Add(new OpLabel(thenLabel)); + + var patchConstantEntryPointType = (FunctionType)patchConstantEntryPoint.Type; + Span patchArguments = stackalloc int[patchConstantEntryPointType.ParameterTypes.Count]; + FillSemanticArguments(patchConstantEntryPointType, patchArguments); + FillTessellationArguments(patchConstantEntryPoint, patchArguments); + buffer.Add(new OpFunctionCall(voidType, context.Bound++, patchConstantEntryPoint.IdRef, new(patchArguments))); + ProcessTessellationArguments(patchConstantEntryPoint, patchArguments); + + buffer.Add(new OpBranch(mergeLabel)); + + // Merge block + buffer.Add(new OpLabel(mergeLabel)); + } + } + else if (executionModel == ExecutionModel.Geometry) + { + // Change signature of main() to not use the output Stream anymore + SpirvBuilder.FunctionRemoveArgument(context, buffer, entryPoint, 1); + + // Extract and remove execution mode (line, point, triangleadj, etc.) + var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; + if (executionMode == ParameterModifiers.None) + throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); + entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; + + context.ReplaceType(entryPoint.Type, entryPointTypeId); + context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch + { + ParameterModifiers.Point => ExecutionMode.InputPoints, + ParameterModifiers.Line => ExecutionMode.InputLines, + ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, + ParameterModifiers.Triangle => ExecutionMode.Triangles, + ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, + }, [])); + + arguments[0] = inputsVariable; + + // Call main(inputs) + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + } } else { + // We assume a void returning function and Input/Output is all handled with streams + // Note: we could in the future support having Input/Output in the function signature, just like we do for HS/DS/GS + // Copy variables from input to streams struct foreach (var stream in inputStreams) { buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.Id, null, []), out var loadedValue); - buffer.Add(new OpStore(streamPointer.ResultId, loadedValue.ResultId, null, [])); + var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).IdResult.Value; + inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); + buffer.Add(new OpStore(streamPointer.ResultId, inputResult, null, [])); } // Call main() - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, [])); + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); // Copy variables from streams struct to output foreach (var stream in outputStreams) { var baseType = stream.Info.Type; buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - buffer.FluentAdd(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, []), out var loadedValue); - buffer.Add(new OpStore(stream.Id, loadedValue.ResultId, null, [])); + var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, [])).IdResult.Value; + outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); + buffer.Add(new OpStore(stream.Id, outputResult, null, [])); } } @@ -977,31 +1379,40 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo buffer.Add(new OpFunctionEnd()); // Note: we overallocate and filter with UsedThisStage after - Span pvariables = stackalloc int[inputStreams.Count + outputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count]; + Span entryPointInterfaceVariables = stackalloc int[inputStreams.Count + outputStreams.Count + patchInputStreams.Count + patchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; int pvariableIndex = 0; foreach (var inputStream in inputStreams) - pvariables[pvariableIndex++] = inputStream.Id; + entryPointInterfaceVariables[pvariableIndex++] = inputStream.InterfaceId; foreach (var outputStream in outputStreams) - pvariables[pvariableIndex++] = outputStream.Id; - pvariables[pvariableIndex++] = streamsVariable.ResultId; + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + foreach (var inputStream in patchInputStreams) + entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; + foreach (var outputStream in patchOutputStreams) + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + entryPointInterfaceVariables[pvariableIndex++] = streamsVariable.ResultId; foreach (var variable in analysisResult.Variables) { if (variable.Value.UsedThisStage) - pvariables[pvariableIndex++] = variable.Key; + entryPointInterfaceVariables[pvariableIndex++] = variable.Key; } foreach (var cbuffer in analysisResult.CBuffers) { if (cbuffer.Value.UsedThisStage) - pvariables[pvariableIndex++] = cbuffer.Key; + entryPointInterfaceVariables[pvariableIndex++] = cbuffer.Key; } foreach (var resource in analysisResult.Resources) { if (resource.Value.UsedThisStage) - pvariables[pvariableIndex++] = resource.Key; + entryPointInterfaceVariables[pvariableIndex++] = resource.Key; + } + + foreach (var variable in entryPointExtraVariables) + { + entryPointInterfaceVariables[pvariableIndex++] = variable; } liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. pvariables.Slice(0, pvariableIndex)])); + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. entryPointInterfaceVariables.Slice(0, pvariableIndex)])); } // Move OpExecutionMode on new wrapper @@ -1017,11 +1428,41 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, StreamInfo return (newEntryPointFunction.ResultId, entryPointName); } + private Symbol? ResolveHullPatchConstantEntryPoint(SymbolTable table, SpirvContext context, Symbol entryPoint) + { + // Check if there's a patch constant function and call it when gl_InvocationID == 0 + string? patchConstantFuncName = null; + foreach (var i in context) + { + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is + { + Target: int target, + Decoration: Decoration.PatchConstantFuncSDSL, + Value: string funcName + } && target == entryPoint.IdRef) + { + patchConstantFuncName = funcName; + break; + } + } + + Symbol? patchConstantEntryPoint = null; + if (patchConstantFuncName != null) + { + // Resolve the patch constant function + patchConstantEntryPoint = ResolveEntryPoint(table, patchConstantFuncName); + if (patchConstantEntryPoint == null) + throw new InvalidOperationException($"Hull shader patch constant function {patchConstantFuncName} was not found"); + } + + return patchConstantEntryPoint; + } + void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); - (var methodStart, var methodEnd) = FindMethodBounds(buffer, functionId); + (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); // One function might need to be duplicated in case it is used by different shader stages with STREAMS: // On first time (in a stage), we backup method original content before mutation @@ -1071,7 +1512,7 @@ void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int } } - class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement) : TypeRewriter + class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement, SymbolType? constantsReplacement) : TypeRewriter { public override SymbolType Visit(StreamsType streamsType) { @@ -1080,6 +1521,7 @@ public override SymbolType Visit(StreamsType streamsType) StreamsKindSDSL.Streams => streamsReplacement, StreamsKindSDSL.Input => inputReplacement, StreamsKindSDSL.Output => outputReplacement, + StreamsKindSDSL.Constants => constantsReplacement ?? throw new InvalidOperationException(), }; } } @@ -1095,13 +1537,18 @@ public override void Visit(GeometryStreamType geometryStreamsType) { Found = true; } + + public override void Visit(PatchType patchType) + { + Found = true; + } } - void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, StructType inputStructType, StructType outputStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, StructType inputStructType, StructType outputStructType, StructType? constantsStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); - (var methodStart, var methodEnd) = FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); + (var methodStart, _) = SpirvBuilder.FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); var streams = analysisResult.Streams; // true => implicit (streams.), false => specific variable @@ -1110,7 +1557,7 @@ void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext var method = (OpFunction)buffer[methodStart]; var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; - var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType); + var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); var newMethodType = (FunctionType)streamTypeReplacer.Visit(methodType); if (!ReferenceEquals(newMethodType, methodType)) { @@ -1119,7 +1566,6 @@ void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext var symbol = table.ResolveSymbol(functionId); symbol.Type = methodType; } - // Remap ids for streams type to actual struct type var remapIds = new Dictionary(); @@ -1163,9 +1609,6 @@ void CheckStreamTypes(int id) var type = context.ReverseTypes[functionParameter.ResultType]; if (type is PointerType { BaseType: StreamsType }) streamsInstructionIds.Add(functionParameter.ResultId, false); - // Remove StreamOutput parameter - else if (type is PointerType { BaseType: GeometryStreamType }) - SpirvBuilder.SetOpNop(i.Data.Memory.Span); } else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { @@ -1197,7 +1640,7 @@ void CheckStreamTypes(int id) foreach (var stream in streams) { // Part of streams? - if (stream.Value.UsedThisStage) + if (!stream.Value.Patch && stream.Value.UsedThisStage) { if (stream.Value.Input) { @@ -1225,7 +1668,7 @@ void CheckStreamTypes(int id) foreach (var stream in streams) { // Part of streams? - if (stream.Value.Output) + if (!stream.Value.Patch && stream.Value.Output) { // Extract value from streams tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex.Value] = buffer.Insert(index++, @@ -1292,7 +1735,7 @@ private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context } else { - (var methodStart, var methodEnd) = FindMethodBounds(buffer, functionId); + (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); } @@ -1400,20 +1843,6 @@ private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context return methodInfo.HasStreamAccess; } - public (int Start, int End) FindMethodBounds(NewSpirvBuffer buffer, int functionId) - { - int? start = null; - for (var index = 0; index < buffer.Count; index++) - { - var instruction = buffer[index]; - if (instruction.Op is Op.OpFunction && ((OpFunction)instruction).ResultId == functionId) - start = index; - if (instruction.Op is Op.OpFunctionEnd && start is int startIndex) - return (startIndex, index + 1); - } - throw new InvalidOperationException($"Could not find start of method {functionId}"); - } - private static readonly Regex MatchSemanticName = new Regex(@"([A-Za-z_]+)(\d*)"); private static (string Name, int Index) ParseSemantic(string semantic) { diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index d42d851d54..8fddb1f62c 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -282,6 +282,7 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpTypeGenericSDSL || op == Op.OpTypeStreamsSDSL || op == Op.OpTypeGeometryStreamOutputSDSL + || op == Op.OpTypePatchSDSL || op == Op.OpSDSLImportShader || op == Op.OpSDSLImportVariable || op == Op.OpSDSLImportFunction From 99dd53a92caf79f7962bdbb9bd133a3b43807a8a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 3 Feb 2026 19:40:13 +0900 Subject: [PATCH 0772/1182] Support [Color] on array of float3/float4 too --- src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 82031d027b..14e9fc7c98 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -428,7 +428,8 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon }; if (metadata.Color) { - if (member.Type is not VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 }) + var baseType = member.Type is ArrayType arrayType ? arrayType.BaseType : member.Type; + if (baseType is not VectorType { BaseType: { Type: Scalar.Float }, Size: 3 or 4 }) throw new InvalidOperationException("[Color] attribute can only be applied on float3/float4 vector types"); memberInfos[index].Type.Class = EffectParameterClass.Color; } From 20dc48217dc734785a3e57d22f03d0f4b7678cb9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 3 Feb 2026 21:11:56 +0900 Subject: [PATCH 0773/1182] Added T NewSpirvBuffer.Add for more easily getting ResultId --- .../SDSL/ShaderMixer.Reflection.cs | 6 +- .../Buffers/NewSpirvBuffer.cs | 9 ++- .../Parsing/SDSL/AST/Literals.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 4 +- .../Spirv/Building/Builder.Functions.cs | 2 +- .../Spirv/Building/Context.Constants.cs | 40 ++++++------ src/Stride.Shaders/Spirv/Building/Context.cs | 8 ++- .../Spirv/Building/SpirvContext.Types.cs | 54 ++++++++-------- .../Spirv/Processing/InterfaceProcessor.cs | 64 +++++++++---------- 9 files changed, 100 insertions(+), 91 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 82980bd9a0..8616b205e4 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -384,8 +384,7 @@ or Specification.Decoration.SamplerStateMinLOD }); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add( - new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [samplerSlot])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [samplerSlot])); if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) globalContext.Reflection.SamplerStates.Add( @@ -405,8 +404,7 @@ or Specification.Decoration.SamplerStateMinLOD }); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add( - new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [cbufferSlot])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [cbufferSlot])); cbufferSlot++; } diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs index 3a26718c3d..a59e341bb4 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs @@ -307,7 +307,14 @@ public OpDataIndex Insert(int index, OpData data) return new OpDataIndex(index, this); } - public OpData Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct + public T Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct + { + Instructions.Add(new(instruction.InstructionMemory)); + instruction.Attach(new(Instructions.Count - 1, this)); + return instruction; + } + + public OpData AddData(in T instruction) where T : struct, IMemoryInstruction, allows ref struct { Instructions.Add(new(instruction.InstructionMemory)); return Instructions[^1]; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 0dc498fe63..a6b082a651 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -34,9 +34,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var i = context.Add(new OpConstantStringSDSL(context.Bound++, Value)); + var constantString = context.Add(new OpConstantStringSDSL(context.Bound++, Value)).ResultId; // Note: we rely on undefined type (0); we assume those string literals will be used in only very specific cases where we expect them (i.e. generic instantiation parameters) and will be removed - return new SpirvValue(i.IdResult.Value, 0); + return new SpirvValue(constantString, 0); } public override SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index 4f21943b5a..fe5a2c4808 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -458,12 +458,12 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } else { - generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).IdResult.Value; + generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).ResultId; } } else if (mixin.Generics.Values[i] is AccessorChainExpression accessChain) { - generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, accessChain.ToString())).IdResult.Value; + generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, accessChain.ToString())).ResultId; } else { diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 5944f337a0..5ed798cd76 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -21,7 +21,7 @@ public static SpirvFunction DeclareFunction(SpirvContext context, string name, F public void BeginFunction(SpirvContext context, SpirvFunction function, FunctionControlMask mask = FunctionControlMask.None) { - Buffer.FluentAdd(new OpFunction(context.GetOrRegister(function.FunctionType.ReturnType), function.Id, mask, context.GetOrRegister(function.FunctionType)), out var func); + Buffer.Add(new OpFunction(context.GetOrRegister(function.FunctionType.ReturnType), function.Id, mask, context.GetOrRegister(function.FunctionType))); Position = Buffer.Count; CurrentFunction = function; } diff --git a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs index 3c61fe0a69..711e9c8781 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.Constants.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.Constants.cs @@ -17,13 +17,13 @@ public int AddConstant(TScalar value) { var data = value switch { - uint v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.UInt), Bound++, v)), - int v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Int), Bound++, v)), - ulong v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.UInt64), Bound++, v)), - long v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Int64), Bound++, v)), + uint v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.UInt), Bound++, v)), + int v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Int), Bound++, v)), + ulong v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.UInt64), Bound++, v)), + long v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Int64), Bound++, v)), //Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), - float v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Float), Bound++, v)), - double v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.Double), Bound++, v)), + float v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Float), Bound++, v)), + double v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Double), Bound++, v)), _ => throw new NotImplementedException() }; if (InstructionInfo.GetInfo(data).GetResultIndex(out var index)) @@ -250,7 +250,7 @@ SpirvValue ProcessStruct(StructType structType) Span values = stackalloc int[structType.Members.Count]; for (int i = 0; i < values.Length; ++i) values[i] = CreateDefaultConstantComposite(structType.Members[i].Type).Id; - return new(Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); + return new(Buffer.AddData(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); } } @@ -270,7 +270,7 @@ public unsafe SpirvValue CreateConstantCompositeRepeat(SymbolType type, SpirvVal for (int i = 0; i < size; ++i) values[i] = value.Id; - return new(Buffer.Add(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); + return new(Buffer.AddData(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); } public Literal CreateLiteral(object value, TextLocation location = default) @@ -320,24 +320,24 @@ public SpirvValue CompileConstantLiteral(Literal literal) var instruction = literal switch { - BoolLiteral { Value: true } lit => Buffer.Add(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), - BoolLiteral { Value: false } lit => Buffer.Add(new OpConstantFalse(GetOrRegister(lit.Type), Bound++)), + BoolLiteral { Value: true } lit => Buffer.AddData(new OpConstantTrue(GetOrRegister(lit.Type), Bound++)), + BoolLiteral { Value: false } lit => Buffer.AddData(new OpConstantFalse(GetOrRegister(lit.Type), Bound++)), IntegerLiteral lit => lit.Suffix switch { - { Size: <= 8, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (byte)lit.IntValue)), - { Size: <= 8, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), - { Size: <= 16, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), - { Size: <= 16, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), - { Size: <= 32, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), - { Size: <= 32, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), - { Size: <= 64, Signed: false } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), - { Size: <= 64, Signed: true } => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), + { Size: <= 8, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (byte)lit.IntValue)), + { Size: <= 8, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), + { Size: <= 16, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), + { Size: <= 16, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), + { Size: <= 32, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), + { Size: <= 32, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), + { Size: <= 64, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), + { Size: <= 64, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), _ => throw new NotImplementedException() }, FloatLiteral lit => lit.Suffix.Size switch { - > 32 => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.DoubleValue)), - _ => Buffer.Add(new OpConstant(GetOrRegister(lit.Type), Bound++, (float)lit.DoubleValue)), + > 32 => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.DoubleValue)), + _ => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (float)lit.DoubleValue)), }, _ => throw new NotImplementedException() }; diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9575743298..1f8cc2fcb6 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -164,7 +164,7 @@ public void SetName(int target, string name) } public void AddMemberName(int target, int accessor, string name) - => Buffer.Add(new OpMemberName(target, accessor, name.Replace('.', '_'))); + => Buffer.AddData(new OpMemberName(target, accessor, name.Replace('.', '_'))); public void SetEntryPoint(ExecutionModel model, int function, string name, ReadOnlySpan variables) { @@ -187,9 +187,13 @@ public OpData InsertData(int index, in T value) public OpDataIndex Insert(int index, OpData data) => Buffer.Insert(index, data); - public OpData Add(in T value) + public T Add(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.Add(value); + + public OpData AddData(in T value) + where T : struct, IMemoryInstruction, allows ref struct + => Buffer.AddData(value); public OpDataIndex Add(OpData data) => Buffer.Add(data); diff --git a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs index c43837ffa3..629df5d095 100644 --- a/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs +++ b/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs @@ -53,44 +53,44 @@ public int RegisterType(SymbolType type, int id) ScalarType s => s.Type switch { - Scalar.Void => Buffer.Add(new OpTypeVoid(id)).IdResult, - Scalar.Boolean => Buffer.Add(new OpTypeBool(id)).IdResult, - Scalar.Int => Buffer.Add(new OpTypeInt(id, 32, 1)).IdResult, - Scalar.UInt => Buffer.Add(new OpTypeInt(id, 32, 0)).IdResult, - Scalar.Int64 => Buffer.Add(new OpTypeInt(id, 64, 1)).IdResult, - Scalar.UInt64 => Buffer.Add(new OpTypeInt(id, 64, 0)).IdResult, - Scalar.Float => Buffer.Add(new OpTypeFloat(id, 32, null)).IdResult, - Scalar.Double => Buffer.Add(new OpTypeFloat(id, 64, null)).IdResult, + Scalar.Void => Buffer.AddData(new OpTypeVoid(id)).IdResult, + Scalar.Boolean => Buffer.AddData(new OpTypeBool(id)).IdResult, + Scalar.Int => Buffer.AddData(new OpTypeInt(id, 32, 1)).IdResult, + Scalar.UInt => Buffer.AddData(new OpTypeInt(id, 32, 0)).IdResult, + Scalar.Int64 => Buffer.AddData(new OpTypeInt(id, 64, 1)).IdResult, + Scalar.UInt64 => Buffer.AddData(new OpTypeInt(id, 64, 0)).IdResult, + Scalar.Float => Buffer.AddData(new OpTypeFloat(id, 32, null)).IdResult, + Scalar.Double => Buffer.AddData(new OpTypeFloat(id, 64, null)).IdResult, _ => throw new NotImplementedException($"Can't add type {type}") }, - VectorType v => Buffer.Add(new OpTypeVector(id, GetOrRegister(v.BaseType), v.Size)).IdResult, + VectorType v => Buffer.AddData(new OpTypeVector(id, GetOrRegister(v.BaseType), v.Size)).IdResult, MatrixType m => Buffer - .Add(new OpTypeMatrix(id, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)) + .AddData(new OpTypeMatrix(id, GetOrRegister(new VectorType(m.BaseType, m.Rows)), m.Columns)) .IdResult, ArrayType a when a.Size != -1 || a.SizeExpression != null => RegisterArrayType(a), ArrayType a when a.Size == -1 && a.SizeExpression == null => Buffer - .Add(new OpTypeRuntimeArray(id, GetOrRegister(a.BaseType))).IdResult, + .AddData(new OpTypeRuntimeArray(id, GetOrRegister(a.BaseType))).IdResult, StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f, id), PointerType p => RegisterPointerType(p, id), LoadedShaderSymbol s => ImportShaderType(s, id), - Texture1DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture2DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture3DType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + Texture3DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - TextureCubeType t => Buffer.Add(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, + TextureCubeType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - SamplerType st => Buffer.Add(new OpTypeSampler(id)).IdResult, - BufferType b => Buffer.Add(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, + SamplerType st => Buffer.AddData(new OpTypeSampler(id)).IdResult, + BufferType b => Buffer.AddData(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, StructuredBufferType b => RegisterStructuredBufferType(b), - SampledImage si => Buffer.Add(new OpTypeSampledImage(id, GetOrRegister(si.ImageType))).IdResult, - GenericParameterType g => Buffer.Add(new OpTypeGenericSDSL(id, g.Kind)).IdResult, - StreamsType s => Buffer.Add(new OpTypeStreamsSDSL(id, s.Kind)).IdResult, - GeometryStreamType so => Buffer.Add(new OpTypeGeometryStreamOutputSDSL(id, GetOrRegister(so.BaseType), so.Kind)).IdResult, - PatchType patch => Buffer.Add(new OpTypePatchSDSL(id, GetOrRegister(patch.BaseType), patch.Kind, patch.Size)).IdResult, + SampledImage si => Buffer.AddData(new OpTypeSampledImage(id, GetOrRegister(si.ImageType))).IdResult, + GenericParameterType g => Buffer.AddData(new OpTypeGenericSDSL(id, g.Kind)).IdResult, + StreamsType s => Buffer.AddData(new OpTypeStreamsSDSL(id, s.Kind)).IdResult, + GeometryStreamType so => Buffer.AddData(new OpTypeGeometryStreamOutputSDSL(id, GetOrRegister(so.BaseType), so.Kind)).IdResult, + PatchType patch => Buffer.AddData(new OpTypePatchSDSL(id, GetOrRegister(patch.BaseType), patch.Kind, patch.Size)).IdResult, // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; @@ -101,9 +101,9 @@ public int RegisterType(SymbolType type, int id) private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) { - var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).IdResult.Value; + var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).ResultId; - var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).IdResult.Value; + var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; AddName(bufferType, $"type.{(structuredBufferType.WriteAllowed ? "RW" : "")}StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); @@ -113,7 +113,7 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy return bufferType; } - private int? RegisterArrayType(ArrayType a) + private int RegisterArrayType(ArrayType a) { int sizeId; if (a.Size != -1) @@ -144,7 +144,7 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy throw new InvalidOperationException(); } - return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).IdResult; + return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).ResultId; } public int ImportShaderType(LoadedShaderSymbol shaderSymbol, int id) @@ -166,7 +166,7 @@ public int ImportShaderType(LoadedShaderSymbol shaderSymbol, int id) private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) { - FluentAdd(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId), out var @struct); + var @struct = Add(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId)); AddName(@struct.ResultId, structType.Name); // Fill the ID diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 26417e38ed..e9f50b160d 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -237,7 +237,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); - buffer.FluentAdd(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); + buffer.Add(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages @@ -800,11 +800,11 @@ int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int val for (int i = 0; i < v2.Size; ++i) { components[i] = i < v1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).IdResult.Value + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).ResultId : context.CreateDefaultConstantComposite(v1.BaseType).Id; } - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).IdResult.Value; + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).ResultId; } if (sourceType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType) @@ -813,11 +813,11 @@ int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int val for (int i = 0; i < a2.Size; ++i) { components[i] = i < a1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).IdResult.Value + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).ResultId : context.CreateDefaultConstantComposite(a1.BaseType).Id; } - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).IdResult.Value; + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).ResultId; } throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); @@ -906,7 +906,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se ? new ArrayType(variableType, arrayInputSize.Value) : variableType, Specification.StorageClass.Input); - context.FluentAdd(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null), out var variable); + var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) @@ -941,7 +941,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se ? new ArrayType(variableType, arrayOutputSize.Value) : variableType, Specification.StorageClass.Output); - context.FluentAdd(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null), out var variable); + var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) @@ -992,7 +992,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se context.DeclareStructuredType(constantsType, context.Bound++); // Create a static global streams variable - context.FluentAdd(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null), out var streamsVariable); + var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); context.AddName(streamsVariable.ResultId, $"streams{stage}"); // Find patch constant entry point @@ -1012,7 +1012,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se // Add new entry point wrapper var newEntryPointFunctionType = context.GetOrRegister(new FunctionType(ScalarType.Void, [])); - buffer.FluentAdd(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType), out var newEntryPointFunction); + var newEntryPointFunction = buffer.Add(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType)); buffer.Add(new OpLabel(context.Bound++)); var variableInsertIndex = buffer.Count; var entryPointName = $"{entryPoint.Id.Name}_Wrapper"; @@ -1029,7 +1029,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); var variableValueType = variable.Value.Type.BaseType; - buffer.FluentAdd(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, []), out var methodInitializerCall); + var methodInitializerCall = buffer.Add(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, [])); buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null, [])); } } @@ -1052,9 +1052,9 @@ int GetOrDeclareBuiltInValue(SymbolType type, string semantic) var variableId = context.Bound++; if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, semantic, ref type)) throw new InvalidOperationException(); - var variable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(type, Specification.StorageClass.Input)), variableId, Specification.StorageClass.Input, null)).IdResult.Value; + var variable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(type, Specification.StorageClass.Input)), variableId, Specification.StorageClass.Input, null)).ResultId; entryPointExtraVariables.Add(variable); - var value = buffer.Add(new OpLoad(context.GetOrRegister(type), context.Bound++, variable, null, [])).IdResult.Value; + var value = buffer.Add(new OpLoad(context.GetOrRegister(type), context.Bound++, variable, null, [])).ResultId; builtinVariables.Add(semantic, (type, value)); return value; } @@ -1106,7 +1106,7 @@ int ConvertInputsArray() for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) { var stream = inputStreams[inputIndex]; - buffer.FluentAdd(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, []), out var loadedValue); + var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, [])); inputLoadValues[inputIndex] = loadedValue.ResultId; } @@ -1117,14 +1117,14 @@ int ConvertInputsArray() for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) { var stream = inputStreams[inputIndex]; - inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).IdResult.Value; + inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).ResultId; inputFieldValues[inputIndex] = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); } - inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).IdResult.Value; + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).ResultId; } - var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).IdResult.Value; + var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).ResultId; return inputsData1; } @@ -1151,11 +1151,11 @@ int GenerateHullTessellationOutputs() var stream = outputStreams[outputIndex]; var outputsVariablePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), context.Bound++, outputsVariable, - [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).IdResult.Value; + [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).ResultId; var outputSourcePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), context.Bound++, stream.Id, - [context.CompileConstant(arrayIndex).Id])).IdResult.Value; - var outputsSourceValue = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, outputSourcePtr, null, [])).IdResult.Value; + [context.CompileConstant(arrayIndex).Id])).ResultId; + var outputsSourceValue = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, outputSourcePtr, null, [])).ResultId; outputsSourceValue = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputsSourceValue); buffer.Add(new OpStore(outputsVariablePtr, outputsSourceValue, null, [])); } @@ -1204,8 +1204,8 @@ void FillTessellationArguments(Symbol function, Span arguments) // Copy back values from semantic/builtin variables to Constants struct foreach (var stream in patchInputStreams) { - var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).IdResult.Value; - var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).IdResult.Value; + var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).ResultId; inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); buffer.Add(new OpStore(inputPtr, inputResult, null, [])); } @@ -1238,19 +1238,19 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).IdResult.Value; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; // Do we need to index into array? if yes, get index (gl_invocationID) int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; // Copy back values from Output struct to semantic/builtin variables for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) { var stream = outputStreams[outputIndex]; - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).IdResult.Value; + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); var outputTargetPtr = arrayOutputSize != null ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), context.Bound++, stream.Id, - [invocationIdValue.Value])).IdResult.Value + [invocationIdValue.Value])).ResultId : stream.Id; buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); } @@ -1261,11 +1261,11 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).IdResult.Value; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; // Copy back values from Output struct to semantic/builtin variables foreach (var stream in patchOutputStreams) { - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).IdResult.Value; + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); buffer.Add(new OpStore(stream.Id, outputResult, null, [])); } @@ -1294,7 +1294,7 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Compare with 0 var zeroConstant = context.CompileConstant(0u).Id; - var isInvocationZero = buffer.Add(new OpIEqual(context.GetOrRegister(ScalarType.Boolean), context.Bound++, invocationIdValue, zeroConstant)).IdResult.Value; + var isInvocationZero = buffer.Add(new OpIEqual(context.GetOrRegister(ScalarType.Boolean), context.Bound++, invocationIdValue, zeroConstant)).ResultId; // Create labels for if-then-merge var thenLabel = context.Bound++; @@ -1355,10 +1355,10 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Copy variables from input to streams struct foreach (var stream in inputStreams) { - buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).IdResult.Value; + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).ResultId; inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); - buffer.Add(new OpStore(streamPointer.ResultId, inputResult, null, [])); + buffer.Add(new OpStore(streamPointer, inputResult, null, [])); } // Call main() @@ -1368,8 +1368,8 @@ void ProcessTessellationArguments(Symbol function, Span arguments) foreach (var stream in outputStreams) { var baseType = stream.Info.Type; - buffer.FluentAdd(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id]), out var streamPointer); - var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer.ResultId, null, [])).IdResult.Value; + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer, null, [])).ResultId; outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); buffer.Add(new OpStore(stream.Id, outputResult, null, [])); } From 91aa1d43c31b7f9d6750c62a9df4a87819118db5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 3 Feb 2026 21:38:45 +0900 Subject: [PATCH 0774/1182] Phase1 --- .../Spirv/Processing/InterfaceProcessor.cs | 166 +----------------- .../Models/AnalysisResult.cs | 9 + .../Models/LiveAnalysis.cs | 47 +++++ .../Models/ResourceInfo.cs | 47 +++++ .../Models/StreamVariableInfo.cs | 42 +++++ .../Models/VariableInfo.cs | 21 +++ 6 files changed, 175 insertions(+), 157 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index e9f50b160d..56e402fdc7 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -10,6 +10,7 @@ using System.Text.RegularExpressions; using CommunityToolkit.HighPerformance; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; namespace Stride.Shaders.Spirv.Processing { @@ -21,155 +22,6 @@ public class InterfaceProcessor public delegate void CodeInsertedDelegate(int index, int count); public CodeInsertedDelegate CodeInserted { get; set; } - - enum StreamVariableType - { - Input, - Output, - } - - class StreamInfo(string? semantic, string name, PointerType type, int variableId) - { - public bool Patch { get; set; } - public string? Semantic { get; } = semantic; - public string Name { get; } = name; - public SymbolType Type { get; } = type.BaseType; - public int VariableId { get; } = variableId; - - public int? InputId { get; set; } - public int? OutputId { get; set; } - - public int? InputLayoutLocation { get; set; } - public int? OutputLayoutLocation { get; set; } - - /// - /// We automatically mark input: a variable read before it's written to, or an output without a write - /// - public bool Input => Read || (Output && !Write); - public bool Output { get => field; set { field = value; UsedAnyStage = true; } } - public bool UsedThisStage => Input || Output || Read || Write; - - public bool Read { get => field; set { field = value; UsedAnyStage = true; } } - public bool Write { get => field; set { field = value; UsedAnyStage = true; } } - public bool UsedAnyStage { get; private set; } - public int? InputStructFieldIndex { get; internal set; } - public int? OutputStructFieldIndex { get; internal set; } - - // Note: if Patch is true, it will be index in CONSTANTS struct, otherwise STREAMS struct - public int StreamStructFieldIndex { get; internal set; } - - public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; - } - - class VariableInfo(string name, PointerType type, int variableId) - { - public string Name { get; } = name; - public PointerType Type { get; } = type; - - public int VariableId { get; } = variableId; - public int? VariableMethodInitializerId { get; set; } - - - /// - /// Used during current stage being processed? - /// - public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } - /// - /// Used at all (in any stage) - /// - public bool UsedAnyStage { get; private set; } - } - - class ResourceInfo(string name) - { - public string Name { get; } = name; - - public ResourceGroup ResourceGroup { get; set; } - - /// - /// Used during current stage being processed? - /// - public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } - /// - /// Used at all (in any stage) - /// - public bool UsedAnyStage { get; private set; } - } - - record class ResourceGroup - { - public bool Used { get; set; } - public string Name { get; set; } - public string? LogicalGroup { get; set; } - public List Resources { get; } = new(); - } - - record class CBufferInfo(string name) - { - public string Name { get; } = name; - - public string? LogicalGroup { get; set; } - - /// - /// Used during current stage being processed? - /// - public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } - /// - /// Used at all (in any stage) - /// - public bool UsedAnyStage { get; private set; } - } - - class LogicalGroupInfo - { - public List Resources { get; } = new(); - public List CBuffers { get; } = new(); - } - - record struct AnalysisResult(Dictionary Names, Dictionary Streams, Dictionary Variables, Dictionary CBuffers, Dictionary ResourceGroups, Dictionary Resources); - - class MethodInfo - { - /// - /// Used during current stage being processed? - /// - public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } - /// - /// Used at all (in any stage) - /// - public bool UsedAnyStage { get; private set; } - - public List? OriginalMethodCode { get; set; } - public int? ThisStageMethodId { get; set; } - - // True if the method depends on STREAMS type (also if used by any OpFunctionCall recursively) - public bool HasStreamAccess { get; internal set; } - } - - class LiveAnalysis - { - public Dictionary ReferencedMethods { get; } = new(); - - public HashSet ExtraReferencedMethods { get; } = new(); - - public MethodInfo GetOrCreateMethodInfo(int functionId) - { - if (!ReferencedMethods.TryGetValue(functionId, out MethodInfo methodInfo)) - ReferencedMethods.Add(functionId, methodInfo = new MethodInfo()); - - return methodInfo; - } - - public bool MarkMethodUsed(int functionId) - { - var methodInfo = GetOrCreateMethodInfo(functionId); - - var previousValue = methodInfo.UsedThisStage; - methodInfo.UsedThisStage = true; - // Returns tree when added first time - return !previousValue; - } - } public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); @@ -347,7 +199,7 @@ private static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalys } } - private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) + private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) { // Remove unreferenced code var removedIds = new HashSet(); @@ -556,7 +408,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); } - private static void PropagateStreamsFromPreviousStage(Dictionary streams) + private static void PropagateStreamsFromPreviousStage(Dictionary streams) { foreach (var stream in streams) { @@ -570,7 +422,7 @@ private static void PropagateStreamsFromPreviousStage(Dictionary(); + var streams = new Dictionary(); HashSet blockTypes = []; Dictionary blockPointerTypes = []; @@ -662,7 +514,7 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) if (variable.MethodInitializer != null) throw new NotImplementedException("Variable initializer is not supported on streams variable"); - streams.Add(variable.ResultId, new StreamInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); + streams.Add(variable.ResultId, new StreamVariableInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); } else { @@ -753,10 +605,10 @@ private AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) ExecutionModel.GLCompute => "CS", _ => throw new NotImplementedException() }; - List<(StreamInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; - List<(StreamInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; - List<(StreamInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; - List<(StreamInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; + List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; List entryPointExtraVariables = []; int inputLayoutLocationCount = 0; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs new file mode 100644 index 0000000000..fedb1a7ca1 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs @@ -0,0 +1,9 @@ +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; + +internal record struct AnalysisResult( + Dictionary Names, + Dictionary Streams, + Dictionary Variables, + Dictionary CBuffers, + Dictionary ResourceGroups, + Dictionary Resources); diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs new file mode 100644 index 0000000000..fc1be1787d --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs @@ -0,0 +1,47 @@ +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; + +internal class MethodInfo +{ + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } + + public List? OriginalMethodCode { get; set; } + public int? ThisStageMethodId { get; set; } + + // True if the method depends on STREAMS type (also if used by any OpFunctionCall recursively) + public bool HasStreamAccess { get; internal set; } +} + +internal class LiveAnalysis +{ + public Dictionary ReferencedMethods { get; } = new(); + + public HashSet ExtraReferencedMethods { get; } = new(); + + public MethodInfo GetOrCreateMethodInfo(int functionId) + { + if (!ReferencedMethods.TryGetValue(functionId, out MethodInfo methodInfo)) + ReferencedMethods.Add(functionId, methodInfo = new MethodInfo()); + + return methodInfo; + } + + public bool MarkMethodUsed(int functionId) + { + var methodInfo = GetOrCreateMethodInfo(functionId); + + var previousValue = methodInfo.UsedThisStage; + methodInfo.UsedThisStage = true; + // Returns tree when added first time + return !previousValue; + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs new file mode 100644 index 0000000000..37c1b0dad2 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs @@ -0,0 +1,47 @@ +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; + +internal class ResourceInfo(string name) +{ + public string Name { get; } = name; + + public ResourceGroup ResourceGroup { get; set; } + + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } +} + +internal record class ResourceGroup +{ + public bool Used { get; set; } + public string Name { get; set; } + public string? LogicalGroup { get; set; } + public List Resources { get; } = new(); +} + +internal record class CBufferInfo(string name) +{ + public string Name { get; } = name; + + public string? LogicalGroup { get; set; } + + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } +} + +internal class LogicalGroupInfo +{ + public List Resources { get; } = new(); + public List CBuffers { get; } = new(); +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs new file mode 100644 index 0000000000..084f39684c --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs @@ -0,0 +1,42 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; + +internal enum StreamVariableType +{ + Input, + Output, +} + +internal class StreamVariableInfo(string? semantic, string name, PointerType type, int variableId) +{ + public bool Patch { get; set; } + public string? Semantic { get; } = semantic; + public string Name { get; } = name; + public SymbolType Type { get; } = type.BaseType; + public int VariableId { get; } = variableId; + + public int? InputId { get; set; } + public int? OutputId { get; set; } + + public int? InputLayoutLocation { get; set; } + public int? OutputLayoutLocation { get; set; } + + /// + /// We automatically mark input: a variable read before it's written to, or an output without a write + /// + public bool Input => Read || (Output && !Write); + public bool Output { get => field; set { field = value; UsedAnyStage = true; } } + public bool UsedThisStage => Input || Output || Read || Write; + + public bool Read { get => field; set { field = value; UsedAnyStage = true; } } + public bool Write { get => field; set { field = value; UsedAnyStage = true; } } + public bool UsedAnyStage { get; private set; } + public int? InputStructFieldIndex { get; internal set; } + public int? OutputStructFieldIndex { get; internal set; } + + // Note: if Patch is true, it will be index in CONSTANTS struct, otherwise STREAMS struct + public int StreamStructFieldIndex { get; internal set; } + + public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs new file mode 100644 index 0000000000..077c859597 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs @@ -0,0 +1,21 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; + +internal class VariableInfo(string name, PointerType type, int variableId) +{ + public string Name { get; } = name; + public PointerType Type { get; } = type; + + public int VariableId { get; } = variableId; + public int? VariableMethodInitializerId { get; set; } + + /// + /// Used during current stage being processed? + /// + public bool UsedThisStage { get => field; set { field = value; UsedAnyStage |= value; } } + /// + /// Used at all (in any stage) + /// + public bool UsedAnyStage { get; private set; } +} From 514fb27526efb5c3cec14bd4c9734c6c981571ec Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 Feb 2026 04:37:01 +0100 Subject: [PATCH 0775/1182] finished phase 1 of generator --- src/Stride.Shaders.Experiments/Program.cs | 18 ++-- .../IntrinsicGenerator.cs | 91 +++++++++++++++++-- .../Intrinsics/IntrinAST.cs | 17 +++- .../Intrinsics/Parser.cs | 5 + .../Core/IntrinsicsParameters.cs | 83 +++++++++++++++-- 5 files changed, 187 insertions(+), 27 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 65ea683dd3..c8239b1789 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -11,17 +11,17 @@ // Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); -// // Examples.CompileSDSL("RenderTests/If"); +// Examples.CompileSDSL("RenderTests/If"); -// //Examples.CompileSDSL(); -// var loader = new Examples.ShaderLoader(); -// loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); -// var shaderMixer = new ShaderMixer(loader); -// shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); +//Examples.CompileSDSL(); +var loader = new Examples.ShaderLoader(); +loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); +var shaderMixer = new ShaderMixer(loader); +shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); -// using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); -// var source = Spv.Dis(buffer); -// File.WriteAllText("test.spvdis", source); +using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); +var source = Spv.Dis(buffer); +File.WriteAllText("test.spvdis", source); // Examples.TryAllFiles(); diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index a8bba30ed4..b41341775f 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -1,4 +1,6 @@ +using System.Collections.Frozen; using System.Text; +using System.Text.Json; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; @@ -18,34 +20,102 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .Select(ParseInstrinsics); context.RegisterSourceOutput(file, GenerateIntrinsicsData); + + // context.RegisterSourceOutput(file, (spc, ns) => + // { + // spc.AddSource("IntrinsicsParsedData.cs", $"/*{JsonSerializer.Serialize(ns, new JsonSerializerOptions { WriteIndented = true })}*/"); + // }); } - static void GenerateIntrinsicsData(SourceProductionContext spc, EquatableList ns) + static void GenerateIntrinsicsData(SourceProductionContext spc, EquatableList namespaces) { var builder = new StringBuilder(); builder.AppendLine(""" namespace Stride.Shaders.Core; + using System.Collections.Frozen; + internal static partial class IntrinsicsDefinitions { """); - if (ns.Items.Count == 0) + if (namespaces.Items.Count == 0) builder.AppendLine("// No intrinsics parsed"); - foreach (var n in ns) + + foreach (var ns in namespaces) { - builder.AppendLine($"internal static Dictionary {n.Name.Name} = new()") + builder.AppendLine($"internal static FrozenDictionary {ns.Name.Name} {{ get; }} = new Dictionary()") .AppendLine("{"); - foreach (var intrin in n.Intrinsics) - builder.AppendLine($"[\"{intrin.Name.Name}\"] = [],"); - builder.AppendLine("};"); + foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name).Where(x => x.Key is not null && x.Key.Name is not "printf")) + { + builder.AppendLine($"[\"{intrinsicGroup.Key}\"] = ["); + foreach (var overload in intrinsicGroup.Where(i => i is not null)) + { + builder.Append("new("); + // Return type + builder.AppendLine($"new(\"{overload.ReturnType.Typename.Name}\""); + _ = overload.ReturnType.Typename switch + { + { Size: { Size1: string, Size2: string } } => builder.Append($", new(\"{overload.ReturnType.Typename.Size.Size1}\", \"{overload.ReturnType.Typename.Size.Size2}\")"), + { Size.Size1: string } => builder.Append($", new(\"{overload.ReturnType.Typename.Size.Size1}\")"), + _ => builder.Append(", null") + }; + + _ = overload.ReturnType.Match switch + { + Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), + _ => builder.Append(", null") + }; + builder.AppendLine("), "); + // Parameters + builder.AppendLine("["); + try + { + if(overload is not null && overload.Parameters.Items is not null) + foreach (var param in overload.Parameters.Items.Where(p => p is not null && p.Name.Name != "...")) + { + builder.Append("new("); + // Qualifier + _ = param.Qualifier switch + { + { Qualifier: string q, OptionalQualifier: string oq } => builder.Append($"FromString(\"{q}\"), FromStringOptional(\"{oq}\"), "), + { Qualifier: string q } => builder.Append($"FromString(\"{q}\"), null, "), + _ => builder.Append("null, null, ") + }; + + // Type + builder.Append($"new(\"{param.TypeInfo.Typename.Name}\""); + _ = param.TypeInfo.Typename switch + { + {Size : {Size1 : string, Size2 : string}} => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\", \"{param.TypeInfo.Typename.Size.Size2}\")"), + { Size.Size1: string } => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\")"), + _ => builder.Append(", null") + }; + _ = param.TypeInfo.Match switch + { + Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), + _ => builder.Append(", null") + }; + builder.Append($"), \"{param.Name.Name}\""); + builder.Append("), "); + } + } + catch (Exception ex) + { + builder.Append($"/* ERROR: {ex.StackTrace} {ex.Source} {ex.TargetSite} {ex.Message} */"); + } + builder.AppendLine("]), "); + } + builder.AppendLine("],"); + } + builder.AppendLine("}.ToFrozenDictionary();"); } builder.AppendLine("}"); spc.AddSource( - "IntrinsicsData.g.cs", + "IntrinsicsData.g.cs", SourceText.From( SyntaxFactory.ParseCompilationUnit(builder.ToString()) .NormalizeWhitespace() @@ -62,4 +132,9 @@ internal static EquatableList ParseInstrinsics(AdditionalT return ns; else return []; } +} + +public static class IntrinsicsGeneratorExtensions +{ + } \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs index 27f551347c..758247e361 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -9,7 +9,10 @@ namespace Stride.Shaders.Generators.Intrinsics; internal abstract record Node([property:JsonIgnore]TextLocation Location); -internal record Identifier(string Name, TextLocation Location) : Node(Location); +internal record Identifier(string Name, TextLocation Location) : Node(Location) +{ + public override string ToString() => Name; +} internal record Attributes(string[] Values, TextLocation Location) : Node(Location); @@ -17,8 +20,16 @@ internal record Attributes(string[] Values, TextLocation Location) : Node(Locati internal record Layout(string Size1, string? Size2, TextLocation Location) : Node(Location); -internal record Typename(string Name, Layout? Size, TextLocation Location) : Node(Location); -internal record NumericType(Layout Size, TextLocation Location) : Typename("numeric", Size, Location); +internal record Typename(string Name, Layout? Size, TextLocation Location) : Node(Location) +{ + public override string ToString() => Size switch + { + null => Name, + _ when Size.Size2 is null => $"{Name}{Size.Size1}", + _ => $"{Name}{Size.Size1}x{Size.Size2}", + }; +} +// internal record NumericType(Layout Size, TextLocation Location) : Typename("numeric", Size, Location); internal record Matching(int ComponentA, int ComponentB, TextLocation Location) : Node(Location); internal record ClassTMatch(TextLocation Location) : Matching(-1, 0,Location); diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs index e5f8e09cb2..289ff257b7 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -262,6 +262,11 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) if (scanner.Match("<", true)) { scanner.MatchWhiteSpace(advance: true); + if(scanner.Match(">", true)) + { + layout = new Layout("any", "any", new TextLocation(scanner.Code, position..scanner.Position)); + return true; + } var size1Pos = scanner.Position; while (scanner.MatchLetterOrDigit(true)) ; var size1 = scanner.Code[size1Pos..scanner.Position].ToString(); diff --git a/src/Stride.Shaders/Core/IntrinsicsParameters.cs b/src/Stride.Shaders/Core/IntrinsicsParameters.cs index ff626fdbc3..2b1bfd5482 100644 --- a/src/Stride.Shaders/Core/IntrinsicsParameters.cs +++ b/src/Stride.Shaders/Core/IntrinsicsParameters.cs @@ -1,15 +1,49 @@ +using System.Text.RegularExpressions; + namespace Stride.Shaders.Core; -internal enum ParameterKind { In, Out }; -internal enum BaseType { Void, Any, Float, FloatLike, Numeric, Match }; +internal enum Qualifier { In, Out, InOut, Ref }; +internal enum OptionalQualifier { RowMajor, ColumnMajor }; + -internal record struct ParameterType(BaseType BaseType, int? VectorSize = null, (int, int)? Match = null) +public record struct VectorSize(string X, string? Y = null); +internal record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int, int)? Match = null) { - public static ParameterType NewMatch(int a, int b) => new ParameterType(BaseType.Match, Match: (a, b)); + public ParameterType(int a, int b) : this(BaseType.Match, Match: (a, b)){} + public ParameterType(string baseType,VectorSize? VectorSize = null, (int, int)? matching = null) : + this( + baseType switch + { + "bool" => BaseType.Bool, + "int" => BaseType.Int, + "uint" => BaseType.Uint, + "u64" => BaseType.U64, + "float" => BaseType.Float, + "sampler1d" => BaseType.Sampler1d, + "sampler2d" => BaseType.Sampler2d, + "sampler3d" => BaseType.Sampler3d, + "sampler_cube" => BaseType.SamplerCube, + "sampler_cmp" => BaseType.SamplerCmp, + "sampler" => BaseType.Sampler, + "wave" => BaseType.Wave, + "void" => BaseType.Void, + "any_int" => BaseType.AnyInt, + "uint_only" => BaseType.UIntOnly, + "numeric" => BaseType.Numeric, + "any" => BaseType.Any, + "float_like" => BaseType.FloatLike, + "match" => BaseType.Match, + _ => throw new ArgumentException($"Unknown base type: {baseType}"), + }, + VectorSize, + matching + ) + + {} } -internal record struct Parameter(ParameterKind Kind, ParameterType Type, string Name); +internal record struct Parameter(Qualifier? Qualifier, OptionalQualifier? OptionalQualifier, ParameterType Type, string Name); internal record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) { @@ -21,5 +55,40 @@ public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan internal static partial class IntrinsicsDefinitions { - -} \ No newline at end of file + static Qualifier FromString(string str) => str switch + { + "in" => Qualifier.In, + "out" => Qualifier.Out, + "inout" => Qualifier.InOut, + "ref" => Qualifier.Ref, + _ => throw new ArgumentException($"Unknown qualifier: {str}"), + }; + static OptionalQualifier FromStringOptional(string str) => str switch + { + "row_major" => OptionalQualifier.RowMajor, + "column_major" => OptionalQualifier.ColumnMajor, + _ => throw new ArgumentException($"Unknown optional qualifier: {str}"), + }; +} + +internal enum BaseType { + Bool, + Int, + Uint, + U64, + Float, + Sampler1d, + Sampler2d, + Sampler3d, + SamplerCube, + SamplerCmp, + Sampler, + Wave, + Void, + AnyInt, + UIntOnly, + Numeric, + Any, + FloatLike, + Match +} \ No newline at end of file From 38df5c122d8fea31d291b03ff8972e94b9e66235 Mon Sep 17 00:00:00 2001 From: Youness KAFIA Date: Tue, 3 Feb 2026 05:11:04 +0100 Subject: [PATCH 0776/1182] little corrections --- src/Stride.Shaders.Experiments/Program.cs | 19 +++-- .../IntrinsicGenerator.cs | 67 +++++++-------- .../Core/IntrinsicsParameters.cs | 83 ++++++++++++++++--- 3 files changed, 111 insertions(+), 58 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index c8239b1789..470fdb848f 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders; using System.Text.Json; +using Stride.Shaders.Core; // Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); @@ -14,16 +15,20 @@ // Examples.CompileSDSL("RenderTests/If"); //Examples.CompileSDSL(); -var loader = new Examples.ShaderLoader(); -loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); -var shaderMixer = new ShaderMixer(loader); -shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); +// var loader = new Examples.ShaderLoader(); +// loader.LoadExternalBuffer("Test", [], out var testBuffer, out _, out _); +// var shaderMixer = new ShaderMixer(loader); +// shaderMixer.MergeSDSL(new ShaderClassSource("If"), new ShaderMixer.Options(), out var bytecode, out _, out _, out _); -using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); -var source = Spv.Dis(buffer); -File.WriteAllText("test.spvdis", source); +// using var buffer = SpirvBytecode.CreateBufferFromBytecode(bytecode); +// var source = Spv.Dis(buffer); +// File.WriteAllText("test.spvdis", source); +var i = IntrinsicsDefinitions.Intrinsics["saturate"]; + +Console.WriteLine(i); + // Examples.TryAllFiles(); // Examples.CreateShader(); diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index b41341775f..21037fcbd1 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -37,7 +37,7 @@ namespace Stride.Shaders.Core; using System.Collections.Frozen; - internal static partial class IntrinsicsDefinitions + public static partial class IntrinsicsDefinitions { """); @@ -46,7 +46,7 @@ internal static partial class IntrinsicsDefinitions foreach (var ns in namespaces) { - builder.AppendLine($"internal static FrozenDictionary {ns.Name.Name} {{ get; }} = new Dictionary()") + builder.AppendLine($"public static FrozenDictionary {ns.Name.Name} {{ get; }} = new Dictionary()") .AppendLine("{"); foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name).Where(x => x.Key is not null && x.Key.Name is not "printf")) { @@ -71,40 +71,34 @@ internal static partial class IntrinsicsDefinitions builder.AppendLine("), "); // Parameters builder.AppendLine("["); - try + + if(overload is not null && overload.Parameters.Items is not null) + foreach (var param in overload.Parameters.Items.Where(p => p is not null && p.Name.Name != "...")) { - if(overload is not null && overload.Parameters.Items is not null) - foreach (var param in overload.Parameters.Items.Where(p => p is not null && p.Name.Name != "...")) + builder.Append("new("); + // Qualifier + _ = param.Qualifier switch { - builder.Append("new("); - // Qualifier - _ = param.Qualifier switch - { - { Qualifier: string q, OptionalQualifier: string oq } => builder.Append($"FromString(\"{q}\"), FromStringOptional(\"{oq}\"), "), - { Qualifier: string q } => builder.Append($"FromString(\"{q}\"), null, "), - _ => builder.Append("null, null, ") - }; - - // Type - builder.Append($"new(\"{param.TypeInfo.Typename.Name}\""); - _ = param.TypeInfo.Typename switch - { - {Size : {Size1 : string, Size2 : string}} => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\", \"{param.TypeInfo.Typename.Size.Size2}\")"), - { Size.Size1: string } => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\")"), - _ => builder.Append(", null") - }; - _ = param.TypeInfo.Match switch - { - Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), - _ => builder.Append(", null") - }; - builder.Append($"), \"{param.Name.Name}\""); - builder.Append("), "); - } - } - catch (Exception ex) - { - builder.Append($"/* ERROR: {ex.StackTrace} {ex.Source} {ex.TargetSite} {ex.Message} */"); + { Qualifier: string q, OptionalQualifier: string oq } => builder.Append($"FromString(\"{q}\"), FromStringOptional(\"{oq}\"), "), + { Qualifier: string q } => builder.Append($"FromString(\"{q}\"), null, "), + _ => builder.Append("null, null, ") + }; + + // Type + builder.Append($"new(\"{param.TypeInfo.Typename.Name}\""); + _ = param.TypeInfo.Typename switch + { + {Size : {Size1 : string, Size2 : string}} => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\", \"{param.TypeInfo.Typename.Size.Size2}\")"), + { Size.Size1: string } => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\")"), + _ => builder.Append(", null") + }; + _ = param.TypeInfo.Match switch + { + Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), + _ => builder.Append(", null") + }; + builder.Append($"), \"{param.Name.Name}\""); + builder.Append("), "); } builder.AppendLine("]), "); } @@ -132,9 +126,4 @@ internal static EquatableList ParseInstrinsics(AdditionalT return ns; else return []; } -} - -public static class IntrinsicsGeneratorExtensions -{ - } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/IntrinsicsParameters.cs b/src/Stride.Shaders/Core/IntrinsicsParameters.cs index 2b1bfd5482..f195b7b65f 100644 --- a/src/Stride.Shaders/Core/IntrinsicsParameters.cs +++ b/src/Stride.Shaders/Core/IntrinsicsParameters.cs @@ -3,12 +3,12 @@ namespace Stride.Shaders.Core; -internal enum Qualifier { In, Out, InOut, Ref }; -internal enum OptionalQualifier { RowMajor, ColumnMajor }; +public enum Qualifier { In, Out, InOut, Ref }; +public enum OptionalQualifier { RowMajor, ColumnMajor }; public record struct VectorSize(string X, string? Y = null); -internal record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int, int)? Match = null) +public record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int, int)? Match = null) { public ParameterType(int a, int b) : this(BaseType.Match, Match: (a, b)){} public ParameterType(string baseType,VectorSize? VectorSize = null, (int, int)? matching = null) : @@ -17,23 +17,59 @@ public ParameterType(string baseType,VectorSize? VectorSize = null, (int, int)? { "bool" => BaseType.Bool, "int" => BaseType.Int, + "int16_t" => BaseType.Int16, + "int32_only" => BaseType.Int32Only, + "int64_t" => BaseType.Int64, + "int64_only" => BaseType.Int64Only, + "sint16or32_only" => BaseType.SInt16Or32, + "any_int" => BaseType.AnyInt, + "any_int32" => BaseType.AnyInt32, + "any_int64" => BaseType.AnyInt64, + "any_int16or32" => BaseType.AnyInt16Or32, "uint" => BaseType.Uint, + "uint16_t" => BaseType.Uint16, "u64" => BaseType.U64, "float" => BaseType.Float, + "float16" or "half" or "float16_t" => BaseType.Float16, + "any_float" => BaseType.AnyFloat, + "double" => BaseType.Float, + "double_only" => BaseType.DoubleOnly, "sampler1d" => BaseType.Sampler1d, "sampler2d" => BaseType.Sampler2d, "sampler3d" => BaseType.Sampler3d, "sampler_cube" => BaseType.SamplerCube, "sampler_cmp" => BaseType.SamplerCmp, "sampler" => BaseType.Sampler, + "any_sampler" => BaseType.AnySampler, "wave" => BaseType.Wave, "void" => BaseType.Void, - "any_int" => BaseType.AnyInt, "uint_only" => BaseType.UIntOnly, "numeric" => BaseType.Numeric, + "numeric16_only" => BaseType.Numeric16Only, + "numeric32_only" => BaseType.Numeric32Only, + "float32_only" => BaseType.Float32Only, "any" => BaseType.Any, "float_like" => BaseType.FloatLike, "match" => BaseType.Match, + "ByteAddressBuffer" => BaseType.ByteAddressBuffer, + "RWByteAddressBuffer" => BaseType.RWByteAddressBuffer, + "VkBufferPointer" => BaseType.VkBufferPointer, + "Texture2D" => BaseType.Texture2D, + "Texture2DArray" => BaseType.Texture2DArray, + "acceleration_struct" + or "ray_desc" + or "udt" + or "triangle_positions" + or "p32i8" + or "p32u8" + or "resource" + or "NodeRecordOrUAV" + or "LinAlg" + or "DxHitObject" + or "RayQuery" + or "ThreadNodeOutputRecords" + or "GroupNodeOutputRecords" + => BaseType.Other, _ => throw new ArgumentException($"Unknown base type: {baseType}"), }, VectorSize, @@ -43,9 +79,9 @@ public ParameterType(string baseType,VectorSize? VectorSize = null, (int, int)? {} } -internal record struct Parameter(Qualifier? Qualifier, OptionalQualifier? OptionalQualifier, ParameterType Type, string Name); +public record struct Parameter(Qualifier? Qualifier, OptionalQualifier? OptionalQualifier, ParameterType Type, string Name); -internal record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) +public record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) { public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan parameters) : this(@return, parameters.ToArray()) @@ -53,7 +89,7 @@ public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan } -internal static partial class IntrinsicsDefinitions +public static partial class IntrinsicsDefinitions { static Qualifier FromString(string str) => str switch { @@ -66,29 +102,52 @@ internal static partial class IntrinsicsDefinitions static OptionalQualifier FromStringOptional(string str) => str switch { "row_major" => OptionalQualifier.RowMajor, - "column_major" => OptionalQualifier.ColumnMajor, + "col_major" => OptionalQualifier.ColumnMajor, _ => throw new ArgumentException($"Unknown optional qualifier: {str}"), }; } -internal enum BaseType { +public enum BaseType { Bool, Int, + Int32Only, + Int16, + Int64, + SInt16Or32, + AnyInt, + AnyInt16Or32, + AnyInt32, + AnyInt64, + Int64Only, Uint, + Uint16, U64, Float, + Float16, + AnyFloat, + FloatLike, + Float32Only, + DoubleOnly, Sampler1d, Sampler2d, Sampler3d, SamplerCube, SamplerCmp, Sampler, + AnySampler, Wave, Void, - AnyInt, + Texture2D, + UIntOnly, Numeric, + Numeric16Only, + Numeric32Only, Any, - FloatLike, - Match + Match, + ByteAddressBuffer, + RWByteAddressBuffer, + VkBufferPointer, + Other, + Texture2DArray } \ No newline at end of file From 4efcac4de9f7421885e44e0aade11645d2138ee9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 00:06:32 +0900 Subject: [PATCH 0777/1182] Phase2 --- .../Spirv/Processing/InterfaceProcessor.cs | 352 +----------------- .../Analysis/ReadWriteAnalyzer.cs | 161 ++++++++ .../Analysis/SemanticAnalyzer.cs | 24 ++ .../Analysis/StreamAnalyzer.cs | 182 +++++++++ 4 files changed, 375 insertions(+), 344 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 56e402fdc7..7a88bdac93 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -11,6 +11,7 @@ using CommunityToolkit.HighPerformance; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; namespace Stride.Shaders.Spirv.Processing { @@ -50,12 +51,12 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con if (entryPointPS == null && entryPointCS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); - var analysisResult = Analyze(buffer, context); + var analysisResult = StreamAnalyzer.Analyze(buffer, context); MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; var liveAnalysis = new LiveAnalysis(); - AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); if (entryPointCS != null) { @@ -108,12 +109,12 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con { if (entryPoint.Item2 != null) { - AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); // Find patch constant entry point and process it as well var patchConstantEntryPoint = entryPoint.Item1 == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint.Item2) : null; if (patchConstantEntryPoint != null) - AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader foreach (var stream in streams) @@ -150,7 +151,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con if (entryPointVS != null) { - AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader foreach (var stream in streams) @@ -170,7 +171,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con { if (stream.Value.Semantic == null) throw new InvalidOperationException($"Vertex shader input {stream.Value.Name} doesn't have semantic"); - var semantic = ParseSemantic(stream.Value.Semantic); + var semantic = SemanticAnalyzer.ParseSemantic(stream.Value.Semantic); inputAttributes.Add(new ShaderInputAttributeDescription { Location = inputLayoutLocation, SemanticName = semantic.Name, SemanticIndex = semantic.Index }); } } @@ -338,7 +339,7 @@ private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext c { if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) { - var streamsTypeSearch = new StreamsTypeSearch(); + var streamsTypeSearch = new ReadWriteAnalyzer.StreamsTypeSearch(); streamsTypeSearch.VisitType(type); if (streamsTypeSearch.Found) { @@ -420,177 +421,6 @@ private static void PropagateStreamsFromPreviousStage(Dictionary(); - - HashSet blockTypes = []; - Dictionary blockPointerTypes = []; - Dictionary cbuffers = []; - Dictionary resources = []; - Dictionary variables = []; - - // Build name table - Dictionary nameTable = []; - Dictionary semanticTable = []; - HashSet patchVariables = []; - foreach (var i in context) - { - // Names - { - if (i.Op == Op.OpName - && ((OpName)i) is - { - Target: int t, - Name: string n - } - ) - { - nameTable[t] = new(n); - } - else if (i.Op == Op.OpMemberName - && ((OpMemberName)i) is - { - Type: int t2, - Member: int m, - Name: string n2 - } - ) - { - nameTable[t2] = new(n2); - } - } - - // Semantic - { - if (i.Op == Op.OpDecorateString - && ((OpDecorateString)i) is - { - Target: int t, - Decoration: Decoration.UserSemantic, - Value: string m - } - ) - { - semanticTable[t] = m; - } - } - - // Patch - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Target: int t3, Decoration: Decoration.Patch }) - { - patchVariables.Add(t3); - } - } - - // Analyze streams - foreach (var i in buffer) - { - if (i.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)i) is { Storageclass: Specification.StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } - && context.ReverseTypes[pointerType2] is PointerType { BaseType: ConstantBufferSymbol }) - { - var name = nameTable[bufferId]; - // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) - // Adjust for it - cbuffers.Add(bufferId, new(name)); - } - - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is - { - Storageclass: Specification.StorageClass.Private or Specification.StorageClass.Workgroup, - ResultId: int - } variable) - { - var name = nameTable.TryGetValue(variable.ResultId, out var nameId) - ? nameId - : $"unnamed_{variable.ResultId}"; - var type = (PointerType)context.ReverseTypes[variable.ResultType]; - - if (variable.Flags.HasFlag(VariableFlagsMask.Stream)) - { - semanticTable.TryGetValue(variable.ResultId, out var semantic); - - if (variable.MethodInitializer != null) - throw new NotImplementedException("Variable initializer is not supported on streams variable"); - - streams.Add(variable.ResultId, new StreamVariableInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); - } - else - { - variables.Add(variable.ResultId, new VariableInfo(name, type, variable.ResultId) - { - VariableMethodInitializerId = variable.MethodInitializer, - }); - } - } - - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is - { - Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer, - ResultId: int - } resource) - { - var name = nameTable.TryGetValue(resource.ResultId, out var nameId) - ? nameId - : $"unnamed_{resource.ResultId}"; - var type = context.ReverseTypes[resource.ResultType]; - - resources.Add(resource.ResultId, new ResourceInfo(name)); - } - } - - // Process ResourceGroupId and build ResourceGroups - Dictionary resourceGroups = new(); - foreach (var i in context) - { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) - { - var n = m.To(); - - if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) - { - if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) - resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); - - resourceGroup.Resources.Add(resourceInfo); - - resourceInfo.ResourceGroup = resourceGroup; - - } - } - } - - // Process ResourceGroup and LogicalGroup decorations - foreach (var i in context) - { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) - { - if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) - // Note: ResourceGroup should not be null if set - && resourceInfo.ResourceGroup.Name == null) - { - resourceInfo.ResourceGroup.Name = m2; - } - } - else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.LogicalGroupSDSL, Value: string m3 } logicalGroupDecorate) - { - if (resources.TryGetValue(logicalGroupDecorate.Target, out var resourceInfo) - // Note: ResourceGroup should not be null if this decoration is set - && resourceInfo.ResourceGroup.LogicalGroup == null) - { - resourceInfo.ResourceGroup.LogicalGroup = m3; - } - else if (cbuffers.TryGetValue(logicalGroupDecorate.Target, out var cbufferInfo)) - { - cbufferInfo.LogicalGroup = m3; - } - } - } - - return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); - } - private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; @@ -1378,24 +1208,6 @@ public override SymbolType Visit(StreamsType streamsType) } } - class StreamsTypeSearch : TypeWalker - { - public bool Found { get; private set; } - public override void Visit(StreamsType streamsType) - { - Found = true; - } - public override void Visit(GeometryStreamType geometryStreamsType) - { - Found = true; - } - - public override void Visit(PatchType patchType) - { - Found = true; - } - } - void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, StructType inputStructType, StructType outputStructType, StructType? constantsStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); @@ -1563,153 +1375,5 @@ void CheckStreamTypes(int id) SpirvBuilder.RemapIds(remapIds, ref i.Data); } } - - /// - /// Figure out (recursively) which streams are being read from and written to. - /// - private bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) - { - // Check if already processed - var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); - if (methodInfo.UsedThisStage) - { - return methodInfo.HasStreamAccess; - } - - // Mark as used - methodInfo.UsedThisStage = true; - - // If method was mutated by another stage, we work on the original copy instead - List methodInstructions; - if (methodInfo.OriginalMethodCode != null) - { - methodInstructions = methodInfo.OriginalMethodCode; - } - else - { - (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); - methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); - } - - var streamsInstructionIds = new HashSet(); - var streams = analysisResult.Streams; - var variables = analysisResult.Variables; - var accessChainBases = new Dictionary(); - - foreach (ref var i in methodInstructions.AsSpan()) - { - // Check for any Streams variable - if (i.Op is Op.OpFunction && new OpFunction(ref i) is { } function) - { - var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; - var streamsTypeSearch = new StreamsTypeSearch(); - streamsTypeSearch.Visit(functionType); - if (streamsTypeSearch.Found) - methodInfo.HasStreamAccess = true; - } - else if (i.Op is Op.OpVariable && new OpVariable(ref i) is { } variable) - { - var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - { - // Note: we should restrict to R except if inout variable - streamsInstructionIds.Add(variable.ResultId); - methodInfo.HasStreamAccess = true; - } - } - // and for any Streams parameter - else if (i.Op is Op.OpFunctionParameter && new OpFunctionParameter(ref i) is { } functionParameter) - { - var type = context.ReverseTypes[functionParameter.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - { - // Note: we should restrict to R except if inout variable - streamsInstructionIds.Add(functionParameter.ResultId); - methodInfo.HasStreamAccess = true; - } - } - else if (i.Op is Op.OpLoad && new OpLoad(ref i) is { } load) - { - // Check for indirect access chains - if (!accessChainBases.TryGetValue(load.Pointer, out var pointer)) - pointer = load.Pointer; - - if (streams.TryGetValue(pointer, out var streamInfo) && !streamInfo.Write) - streamInfo.Read = true; - if (variables.TryGetValue(pointer, out var variableInfo)) - variableInfo.UsedThisStage = true; - if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) - resourceInfo.UsedThisStage = true; - if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) - cbufferInfo.UsedThisStage = true; - } - else if (i.Op is Op.OpStore && new OpStore(ref i) is { } store) - { - // Check for indirect access chains - if (!accessChainBases.TryGetValue(store.Pointer, out var pointer)) - pointer = store.Pointer; - - if (streams.TryGetValue(pointer, out var streamInfo)) - streamInfo.Write = true; - if (variables.TryGetValue(pointer, out var variableInfo)) - variableInfo.UsedThisStage = true; - if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) - resourceInfo.UsedThisStage = true; - if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) - cbufferInfo.UsedThisStage = true; - } - else if (i.Op == Op.OpStreamsSDSL && new OpStreamsSDSL(ref i) is { } streamsInstruction) - { - streamsInstructionIds.Add(streamsInstruction.ResultId); - methodInfo.HasStreamAccess = true; - } - else if (i.Op == Op.OpAccessChain && new OpAccessChain(ref i) is { } accessChain) - { - var currentBase = accessChain.BaseId; - - // In case it's a streams access, mark the stream as being the base - if (streamsInstructionIds.Contains(currentBase)) - { - var streamVariableId = accessChain.Values.Elements.Span[0]; - var streamInfo = streams[streamVariableId]; - - // Set this base for OpStore/OpLoad stream R/W analysis - currentBase = streamVariableId; - } - - // Any read or write through an access chain will be treated as doing it on the main variable. - // i.e., streams.A.B will share same streamInfo as streams.A - // TODO: what happens in case of partial write? - // Recurse in case we have multiple access chain chained after each other - while (accessChainBases.TryGetValue(currentBase, out var nextBase)) - currentBase = nextBase; - accessChainBases.Add(accessChain.ResultId, currentBase); - } - else if (i.Op == Op.OpFunctionCall && new OpFunctionCall(ref i) is { } call) - { - // Process call - methodInfo.HasStreamAccess |= AnalyzeStreamReadWrites(buffer, context, call.Function, analysisResult, liveAnalysis); - } - } - - return methodInfo.HasStreamAccess; - } - - private static readonly Regex MatchSemanticName = new Regex(@"([A-Za-z_]+)(\d*)"); - private static (string Name, int Index) ParseSemantic(string semantic) - { - var match = MatchSemanticName.Match(semantic); - if (!match.Success) - return (semantic, 0); - - string baseName = match.Groups[1].Value; - int value = 0; - if (!string.IsNullOrEmpty(match.Groups[2].Value)) - { - value = int.Parse(match.Groups[2].Value); - } - - return (baseName, value); - } } } diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs new file mode 100644 index 0000000000..c3982e14da --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs @@ -0,0 +1,161 @@ +using Stride.Shaders.Core; +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; + +internal static class ReadWriteAnalyzer +{ + /// + /// Figure out (recursively) which streams are being read from and written to. + /// + public static bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + { + // Check if already processed + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + if (methodInfo.UsedThisStage) + { + return methodInfo.HasStreamAccess; + } + + // Mark as used + methodInfo.UsedThisStage = true; + + // If method was mutated by another stage, we work on the original copy instead + List methodInstructions; + if (methodInfo.OriginalMethodCode != null) + { + methodInstructions = methodInfo.OriginalMethodCode; + } + else + { + (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); + methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); + } + + var streamsInstructionIds = new HashSet(); + var streams = analysisResult.Streams; + var variables = analysisResult.Variables; + var accessChainBases = new Dictionary(); + + foreach (ref var i in CollectionsMarshal.AsSpan(methodInstructions)) + { + // Check for any Streams variable + if (i.Op is Op.OpFunction && new OpFunction(ref i) is { } function) + { + var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; + var streamsTypeSearch = new StreamsTypeSearch(); + streamsTypeSearch.Visit(functionType); + if (streamsTypeSearch.Found) + methodInfo.HasStreamAccess = true; + } + else if (i.Op is Op.OpVariable && new OpVariable(ref i) is { } variable) + { + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + { + // Note: we should restrict to R except if inout variable + streamsInstructionIds.Add(variable.ResultId); + methodInfo.HasStreamAccess = true; + } + } + // and for any Streams parameter + else if (i.Op is Op.OpFunctionParameter && new OpFunctionParameter(ref i) is { } functionParameter) + { + var type = context.ReverseTypes[functionParameter.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + { + // Note: we should restrict to R except if inout variable + streamsInstructionIds.Add(functionParameter.ResultId); + methodInfo.HasStreamAccess = true; + } + } + else if (i.Op is Op.OpLoad && new OpLoad(ref i) is { } load) + { + // Check for indirect access chains + if (!accessChainBases.TryGetValue(load.Pointer, out var pointer)) + pointer = load.Pointer; + + if (streams.TryGetValue(pointer, out var streamInfo) && !streamInfo.Write) + streamInfo.Read = true; + if (variables.TryGetValue(pointer, out var variableInfo)) + variableInfo.UsedThisStage = true; + if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) + resourceInfo.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + cbufferInfo.UsedThisStage = true; + } + else if (i.Op is Op.OpStore && new OpStore(ref i) is { } store) + { + // Check for indirect access chains + if (!accessChainBases.TryGetValue(store.Pointer, out var pointer)) + pointer = store.Pointer; + + if (streams.TryGetValue(pointer, out var streamInfo)) + streamInfo.Write = true; + if (variables.TryGetValue(pointer, out var variableInfo)) + variableInfo.UsedThisStage = true; + if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) + resourceInfo.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + cbufferInfo.UsedThisStage = true; + } + else if (i.Op == Op.OpStreamsSDSL && new OpStreamsSDSL(ref i) is { } streamsInstruction) + { + streamsInstructionIds.Add(streamsInstruction.ResultId); + methodInfo.HasStreamAccess = true; + } + else if (i.Op == Op.OpAccessChain && new OpAccessChain(ref i) is { } accessChain) + { + var currentBase = accessChain.BaseId; + + // In case it's a streams access, mark the stream as being the base + if (streamsInstructionIds.Contains(currentBase)) + { + var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamInfo = streams[streamVariableId]; + + // Set this base for OpStore/OpLoad stream R/W analysis + currentBase = streamVariableId; + } + + // Any read or write through an access chain will be treated as doing it on the main variable. + // i.e., streams.A.B will share same streamInfo as streams.A + // TODO: what happens in case of partial write? + // Recurse in case we have multiple access chain chained after each other + while (accessChainBases.TryGetValue(currentBase, out var nextBase)) + currentBase = nextBase; + accessChainBases.Add(accessChain.ResultId, currentBase); + } + else if (i.Op == Op.OpFunctionCall && new OpFunctionCall(ref i) is { } call) + { + // Process call + methodInfo.HasStreamAccess |= AnalyzeStreamReadWrites(buffer, context, call.Function, analysisResult, liveAnalysis); + } + } + + return methodInfo.HasStreamAccess; + } + + internal class StreamsTypeSearch : TypeWalker + { + public bool Found { get; private set; } + public override void Visit(StreamsType streamsType) + { + Found = true; + } + public override void Visit(GeometryStreamType geometryStreamsType) + { + Found = true; + } + + public override void Visit(PatchType patchType) + { + Found = true; + } + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs new file mode 100644 index 0000000000..8fb5c6066b --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs @@ -0,0 +1,24 @@ +using System.Text.RegularExpressions; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; + +internal static class SemanticAnalyzer +{ + private static readonly Regex MatchSemanticName = new Regex(@"([A-Za-z_]+)(\d*)"); + + public static (string Name, int Index) ParseSemantic(string semantic) + { + var match = MatchSemanticName.Match(semantic); + if (!match.Success) + return (semantic, 0); + + string baseName = match.Groups[1].Value; + int value = 0; + if (!string.IsNullOrEmpty(match.Groups[2].Value)) + { + value = int.Parse(match.Groups[2].Value); + } + + return (baseName, value); + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs new file mode 100644 index 0000000000..2fdcd5df01 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs @@ -0,0 +1,182 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; + +internal static class StreamAnalyzer +{ + public static AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) + { + var streams = new Dictionary(); + + HashSet blockTypes = []; + Dictionary blockPointerTypes = []; + Dictionary cbuffers = []; + Dictionary resources = []; + Dictionary variables = []; + + // Build name table + Dictionary nameTable = []; + Dictionary semanticTable = []; + HashSet patchVariables = []; + foreach (var i in context) + { + // Names + { + if (i.Op == Op.OpName + && ((OpName)i) is + { + Target: int t, + Name: string n + } + ) + { + nameTable[t] = new(n); + } + else if (i.Op == Op.OpMemberName + && ((OpMemberName)i) is + { + Type: int t2, + Member: int m, + Name: string n2 + } + ) + { + nameTable[t2] = new(n2); + } + } + + // Semantic + { + if (i.Op == Op.OpDecorateString + && ((OpDecorateString)i) is + { + Target: int t, + Decoration: Decoration.UserSemantic, + Value: string m + } + ) + { + semanticTable[t] = m; + } + } + + // Patch + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Target: int t3, Decoration: Decoration.Patch }) + { + patchVariables.Add(t3); + } + } + + // Analyze streams + foreach (var i in buffer) + { + if (i.Op == Op.OpVariableSDSL + && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + && context.ReverseTypes[pointerType2] is PointerType { BaseType: ConstantBufferSymbol }) + { + var name = nameTable[bufferId]; + // Note: cbuffer names might be suffixed with .0 .1 (as in Shader.RenameCBufferVariables) + // Adjust for it + cbuffers.Add(bufferId, new(name)); + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Private or StorageClass.Workgroup, + ResultId: int + } variable) + { + var name = nameTable.TryGetValue(variable.ResultId, out var nameId) + ? nameId + : $"unnamed_{variable.ResultId}"; + var type = (PointerType)context.ReverseTypes[variable.ResultType]; + + if (variable.Flags.HasFlag(VariableFlagsMask.Stream)) + { + semanticTable.TryGetValue(variable.ResultId, out var semantic); + + if (variable.MethodInitializer != null) + throw new NotImplementedException("Variable initializer is not supported on streams variable"); + + streams.Add(variable.ResultId, new StreamVariableInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); + } + else + { + variables.Add(variable.ResultId, new VariableInfo(name, type, variable.ResultId) + { + VariableMethodInitializerId = variable.MethodInitializer, + }); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, + ResultId: int + } resource) + { + var name = nameTable.TryGetValue(resource.ResultId, out var nameId) + ? nameId + : $"unnamed_{resource.ResultId}"; + var type = context.ReverseTypes[resource.ResultType]; + + resources.Add(resource.ResultId, new ResourceInfo(name)); + } + } + + // Process ResourceGroupId and build ResourceGroups + Dictionary resourceGroups = new(); + foreach (var i in context) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) + { + var n = m.To(); + + if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) + { + if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) + resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); + + resourceGroup.Resources.Add(resourceInfo); + + resourceInfo.ResourceGroup = resourceGroup; + + } + } + } + + // Process ResourceGroup and LogicalGroup decorations + foreach (var i in context) + { + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) + { + if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) + // Note: ResourceGroup should not be null if set + && resourceInfo.ResourceGroup.Name == null) + { + resourceInfo.ResourceGroup.Name = m2; + } + } + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.LogicalGroupSDSL, Value: string m3 } logicalGroupDecorate) + { + if (resources.TryGetValue(logicalGroupDecorate.Target, out var resourceInfo) + // Note: ResourceGroup should not be null if this decoration is set + && resourceInfo.ResourceGroup.LogicalGroup == null) + { + resourceInfo.ResourceGroup.LogicalGroup = m3; + } + else if (cbuffers.TryGetValue(logicalGroupDecorate.Target, out var cbufferInfo)) + { + cbufferInfo.LogicalGroup = m3; + } + } + } + + return new(nameTable, streams, variables, cbuffers, resourceGroups, resources); + } +} From cfeb3014911470b9be137eee474f8b8b8ffeac78 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 08:03:26 +0900 Subject: [PATCH 0778/1182] Phase3 --- .../Spirv/Processing/InterfaceProcessor.cs | 230 +----------------- .../Cleanup/DeadCodeRemover.cs | 192 +++++++++++++++ .../Cleanup/VariableMerger.cs | 70 ++++++ 3 files changed, 269 insertions(+), 223 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index 7a88bdac93..e0b7dd541a 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -12,6 +12,7 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; namespace Stride.Shaders.Spirv.Processing { @@ -52,7 +53,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); var analysisResult = StreamAnalyzer.Analyze(buffer, context); - MergeSameSemanticVariables(table, context, buffer, analysisResult); + VariableMerger.MergeSameSemanticVariables(table, context, buffer, analysisResult); var streams = analysisResult.Streams; var liveAnalysis = new LiveAnalysis(); @@ -101,9 +102,9 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con } // Reset cbuffer/resource/methods used for next stage - ResetUsedThisStage(analysisResult, liveAnalysis); + DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); - PropagateStreamsFromPreviousStage(streams); + VariableMerger.PropagateStreamsFromPreviousStage(streams); foreach (var entryPoint in new[] { (ExecutionModel.TessellationControl, entryPointHS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.Geometry, entryPointGS) }) { @@ -140,9 +141,9 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con entryPoints.Add((wrapperName, wrapperId, stage)); // Reset cbuffer/resource/methods used for next stage - ResetUsedThisStage(analysisResult, liveAnalysis); + DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); - PropagateStreamsFromPreviousStage(streams); + VariableMerger.PropagateStreamsFromPreviousStage(streams); if (entryPointVS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); @@ -180,216 +181,11 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con // This will remove a lot of unused methods, resources and variables // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) - RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); + DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); return new(entryPoints, inputAttributes); } - private static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalysis liveAnalysis) - { - foreach (var variable in analysisResult.Variables) - variable.Value.UsedThisStage = false; - foreach (var resource in analysisResult.Resources) - resource.Value.UsedThisStage = false; - foreach (var cbuffer in analysisResult.CBuffers) - cbuffer.Value.UsedThisStage = false; - foreach (var method in liveAnalysis.ReferencedMethods) - { - method.Value.UsedThisStage = false; - method.Value.ThisStageMethodId = null; - } - } - - private static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) - { - // Remove unreferenced code - var removedIds = new HashSet(); - - // First, build resource group (used status and logical groups) - var logicalGroups = new Dictionary(); - foreach (var resourceGroup in analysisResult.ResourceGroups) - { - foreach (var resource in resourceGroup.Value.Resources) - { - if (resource.UsedAnyStage) - { - resourceGroup.Value.Used = true; - } - - if (resourceGroup.Value.LogicalGroup != null) - { - ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{resourceGroup.Value.Name}.{resourceGroup.Value.LogicalGroup}", out var exists); - if (!exists) - logicalGroup = new(); - logicalGroup.Resources.Add(resourceGroup.Value); - } - } - } - // Complete logical groups with cbuffers - foreach (var cbuffer in analysisResult.CBuffers) - { - if (cbuffer.Value.LogicalGroup != null) - { - ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{cbuffer.Value.Name}.{cbuffer.Value.LogicalGroup}", out var exists); - if (!exists) - logicalGroup = new(); - logicalGroup.CBuffers.Add(cbuffer.Value); - } - } - - // Check logical group: if any resource is used, mark everything as used - // TODO: make sure register allocation is contiguous - foreach (var logicalGroup in logicalGroups) - { - var logicalGroupUsed = false; - foreach (var resource in logicalGroup.Value.Resources) - logicalGroupUsed |= resource.Used; - foreach (var cbuffer in logicalGroup.Value.CBuffers) - logicalGroupUsed |= cbuffer.UsedAnyStage; - - if (logicalGroupUsed) - { - // Mark everything as used - foreach (var resource in logicalGroup.Value.Resources) - resource.Used = logicalGroupUsed; - foreach (var cbuffer in logicalGroup.Value.CBuffers) - cbuffer.UsedThisStage = logicalGroupUsed; - } - } - - for (var index = 0; index < buffer.Count; index++) - { - var i = buffer[index]; - if (i.Op == Op.OpFunction && (OpFunction)i is { } function) - { - bool isReferenced = liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId) - || liveAnalysis.ExtraReferencedMethods.Contains(function.ResultId); - if (!isReferenced) - { - removedIds.Add(function.ResultId); - while (buffer[index].Op != Op.OpFunctionEnd) - { - if (buffer[index].Data.IdResult is int resultId) - removedIds.Add(resultId); - SpirvBuilder.SetOpNop(buffer[index++].Data.Memory.Span); - } - - SpirvBuilder.SetOpNop(buffer[index].Data.Memory.Span); - } - } - - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is - { - Storageclass: Specification.StorageClass.Uniform, - ResultId: int - } variable - && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) - { - if (!cbufferInfo.UsedAnyStage) - { - removedIds.Add(variable.ResultId); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } - - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is - { - Storageclass: Specification.StorageClass.UniformConstant, - ResultId: int - } resource) - { - var resourceInfo = analysisResult.Resources[resource.ResultId]; - // If resource has a rgroup, check its state (if any resource is used in the group, we need to keep every resource) - // If no rgroup, we check the resource itself - if (!(resourceInfo.ResourceGroup?.Used ?? false || resourceInfo.UsedAnyStage)) - { - removedIds.Add(resource.ResultId); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } - - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is - { - Storageclass: Specification.StorageClass.Private or Specification.StorageClass.Workgroup, - ResultId: int - } variable2) - { - if (variable2.Flags.HasFlag(VariableFlagsMask.Stream)) - { - // Always removed as we now use streams structure - removedIds.Add(variable2.ResultId); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - else - { - if (!analysisResult.Variables.TryGetValue(variable2.ResultId, out var variableInfo) || !variableInfo.UsedAnyStage) - { - removedIds.Add(variable2.ResultId); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } - } - } - - // Remove all OpTypeStreamsSDSL, OpTypePatchSDSL and OpTypeGeometryStreamOutputSDSL or any type that depends on it - // (we do that before the OpName/OpDecorate pass) - foreach (var i in context) - { - if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypePatchSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) - { - if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) - { - var streamsTypeSearch = new ReadWriteAnalyzer.StreamsTypeSearch(); - streamsTypeSearch.VisitType(type); - if (streamsTypeSearch.Found) - { - removedIds.Add(i.Data.IdResult.Value); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } - } - } - - // Remove OpName/OpDecorate - context.RemoveNameAndDecorations(removedIds); - } - - private void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) - { - Dictionary remapIds = new(); - foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Semantic != null).GroupBy(x => x.Value.Semantic)) - { - // Make sure they all have the same type - var firstStream = streamWithSameSemantic.First(); - foreach (var stream in streamWithSameSemantic.Skip(1)) - { - if (stream.Value.Type != firstStream.Value.Type) - throw new InvalidOperationException($"Two variables with same semantic {stream.Value.Semantic} have different types {stream.Value.Type} and {firstStream.Value.Type}"); - - // Remap variable - remapIds.Add(stream.Key, firstStream.Key); - } - } - - // Remove duplicate streams - HashSet removedIds = new(); - foreach (var i in buffer) - { - if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { } variable && remapIds.ContainsKey(variable.ResultId)) - { - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - removedIds.Add(variable.ResultId); - } - } - - // Remove OpName/OpDecorate - context.RemoveNameAndDecorations(removedIds); - - foreach (var remapId in remapIds) - analysisResult.Streams.Remove(remapId.Key); - - SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); - } static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) { @@ -409,18 +205,6 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); } - private static void PropagateStreamsFromPreviousStage(Dictionary streams) - { - foreach (var stream in streams) - { - stream.Value.OutputLayoutLocation = stream.Value.InputLayoutLocation; - stream.Value.InputLayoutLocation = null; - stream.Value.Output = stream.Value.Input; - stream.Value.Read = false; - stream.Value.Write = false; - } - } - private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs new file mode 100644 index 0000000000..68be3a8d58 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs @@ -0,0 +1,192 @@ +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; + +/// +/// Handles removal of unreferenced code including methods, variables, resources, and types. +/// +internal static class DeadCodeRemover +{ + /// + /// Resets the UsedThisStage flag for all variables, resources, cbuffers, and methods + /// in preparation for analyzing the next shader stage. + /// + public static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + { + foreach (var variable in analysisResult.Variables) + variable.Value.UsedThisStage = false; + foreach (var resource in analysisResult.Resources) + resource.Value.UsedThisStage = false; + foreach (var cbuffer in analysisResult.CBuffers) + cbuffer.Value.UsedThisStage = false; + foreach (var method in liveAnalysis.ReferencedMethods) + { + method.Value.UsedThisStage = false; + method.Value.ThisStageMethodId = null; + } + } + + /// + /// Removes unreferenced code including methods, variables, resources, cbuffers, and stream types. + /// Preserves logical groups and resource groups where at least one member is used. + /// + public static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) + { + // Remove unreferenced code + var removedIds = new HashSet(); + + // First, build resource group (used status and logical groups) + var logicalGroups = new Dictionary(); + foreach (var resourceGroup in analysisResult.ResourceGroups) + { + foreach (var resource in resourceGroup.Value.Resources) + { + if (resource.UsedAnyStage) + { + resourceGroup.Value.Used = true; + } + + if (resourceGroup.Value.LogicalGroup != null) + { + ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{resourceGroup.Value.Name}.{resourceGroup.Value.LogicalGroup}", out var exists); + if (!exists) + logicalGroup = new(); + logicalGroup.Resources.Add(resourceGroup.Value); + } + } + } + // Complete logical groups with cbuffers + foreach (var cbuffer in analysisResult.CBuffers) + { + if (cbuffer.Value.LogicalGroup != null) + { + ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{cbuffer.Value.Name}.{cbuffer.Value.LogicalGroup}", out var exists); + if (!exists) + logicalGroup = new(); + logicalGroup.CBuffers.Add(cbuffer.Value); + } + } + + // Check logical group: if any resource is used, mark everything as used + // TODO: make sure register allocation is contiguous + foreach (var logicalGroup in logicalGroups) + { + var logicalGroupUsed = false; + foreach (var resource in logicalGroup.Value.Resources) + logicalGroupUsed |= resource.Used; + foreach (var cbuffer in logicalGroup.Value.CBuffers) + logicalGroupUsed |= cbuffer.UsedAnyStage; + + if (logicalGroupUsed) + { + // Mark everything as used + foreach (var resource in logicalGroup.Value.Resources) + resource.Used = logicalGroupUsed; + foreach (var cbuffer in logicalGroup.Value.CBuffers) + cbuffer.UsedThisStage = logicalGroupUsed; + } + } + + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index]; + if (i.Op == Op.OpFunction && (OpFunction)i is { } function) + { + bool isReferenced = liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId) + || liveAnalysis.ExtraReferencedMethods.Contains(function.ResultId); + if (!isReferenced) + { + removedIds.Add(function.ResultId); + while (buffer[index].Op != Op.OpFunctionEnd) + { + if (buffer[index].Data.IdResult is int resultId) + removedIds.Add(resultId); + SpirvBuilder.SetOpNop(buffer[index++].Data.Memory.Span); + } + + SpirvBuilder.SetOpNop(buffer[index].Data.Memory.Span); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Uniform, + ResultId: int + } variable + && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) + { + if (!cbufferInfo.UsedAnyStage) + { + removedIds.Add(variable.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.UniformConstant, + ResultId: int + } resource) + { + var resourceInfo = analysisResult.Resources[resource.ResultId]; + // If resource has a rgroup, check its state (if any resource is used in the group, we need to keep every resource) + // If no rgroup, we check the resource itself + if (!(resourceInfo.ResourceGroup?.Used ?? false || resourceInfo.UsedAnyStage)) + { + removedIds.Add(resource.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is + { + Storageclass: StorageClass.Private or StorageClass.Workgroup, + ResultId: int + } variable2) + { + if (variable2.Flags.HasFlag(VariableFlagsMask.Stream)) + { + // Always removed as we now use streams structure + removedIds.Add(variable2.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else + { + if (!analysisResult.Variables.TryGetValue(variable2.ResultId, out var variableInfo) || !variableInfo.UsedAnyStage) + { + removedIds.Add(variable2.ResultId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + } + + // Remove all OpTypeStreamsSDSL, OpTypePatchSDSL and OpTypeGeometryStreamOutputSDSL or any type that depends on it + // (we do that before the OpName/OpDecorate pass) + foreach (var i in context) + { + if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypePatchSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) + { + if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) + { + var streamsTypeSearch = new ReadWriteAnalyzer.StreamsTypeSearch(); + streamsTypeSearch.VisitType(type); + if (streamsTypeSearch.Found) + { + removedIds.Add(i.Data.IdResult.Value); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + } + + // Remove OpName/OpDecorate + context.RemoveNameAndDecorations(removedIds); + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs new file mode 100644 index 0000000000..91413ce548 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs @@ -0,0 +1,70 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; + +/// +/// Handles merging of variables with the same semantic and propagating streams between shader stages. +/// +internal static class VariableMerger +{ + /// + /// Merges variables that have the same semantic into a single variable. + /// + public static void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) + { + Dictionary remapIds = new(); + foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Semantic != null).GroupBy(x => x.Value.Semantic)) + { + // Make sure they all have the same type + var firstStream = streamWithSameSemantic.First(); + foreach (var stream in streamWithSameSemantic.Skip(1)) + { + if (stream.Value.Type != firstStream.Value.Type) + throw new InvalidOperationException($"Two variables with same semantic {stream.Value.Semantic} have different types {stream.Value.Type} and {firstStream.Value.Type}"); + + // Remap variable + remapIds.Add(stream.Key, firstStream.Key); + } + } + + // Remove duplicate streams + HashSet removedIds = new(); + foreach (var i in buffer) + { + if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { } variable && remapIds.ContainsKey(variable.ResultId)) + { + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + removedIds.Add(variable.ResultId); + } + } + + // Remove OpName/OpDecorate + context.RemoveNameAndDecorations(removedIds); + + foreach (var remapId in remapIds) + analysisResult.Streams.Remove(remapId.Key); + + SpirvBuilder.RemapIds(buffer, 0, buffer.Count, remapIds); + } + + /// + /// Propagates stream variables from the previous shader stage by converting inputs to outputs. + /// + public static void PropagateStreamsFromPreviousStage(Dictionary streams) + { + foreach (var stream in streams) + { + stream.Value.OutputLayoutLocation = stream.Value.InputLayoutLocation; + stream.Value.InputLayoutLocation = null; + stream.Value.Output = stream.Value.Input; + stream.Value.Read = false; + stream.Value.Write = false; + } + } +} From 66fd01b78d6b6bea0767a9dd955f8ba8b4e6bdd6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 08:57:58 +0900 Subject: [PATCH 0779/1182] Phase4 --- .../Spirv/Processing/InterfaceProcessor.cs | 245 +----------------- .../Transformation/MethodDuplicator.cs | 79 ++++++ .../Transformation/StreamAccessPatcher.cs | 214 +++++++++++++++ 3 files changed, 297 insertions(+), 241 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index e0b7dd541a..ecd8a6f261 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -13,6 +13,7 @@ using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; namespace Stride.Shaders.Spirv.Processing { @@ -21,9 +22,7 @@ namespace Stride.Shaders.Spirv.Processing /// public class InterfaceProcessor { - public delegate void CodeInsertedDelegate(int index, int count); - - public CodeInsertedDelegate CodeInserted { get; set; } + public Action? CodeInserted { get; set; } public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); @@ -469,8 +468,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se { if (method.Value.UsedThisStage && method.Value.HasStreamAccess) { - DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis); - PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); + StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); } } @@ -923,241 +922,5 @@ void ProcessTessellationArguments(Symbol function, Span arguments) return patchConstantEntryPoint; } - - void DuplicateMethodIfNecessary(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) - { - var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); - - (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); - - // One function might need to be duplicated in case it is used by different shader stages with STREAMS: - // On first time (in a stage), we backup method original content before mutation - // On second time (in a different stage), we copy the method (from original content) - if (methodInfo.OriginalMethodCode == null) - { - // Copy instructions memory (since we're going to mutate them and want to retain original version) - var methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); - foreach (ref var i in methodInstructions.AsSpan()) - i = new OpData(i.Memory.Span); - - methodInfo.OriginalMethodCode = methodInstructions; - } - else - { - // Need to reinsert method with new IDs - var remapIds = new Dictionary(); - var copiedInstructions = new List(); - foreach (var i in methodInfo.OriginalMethodCode) - { - // Save copied function ID - if (i.Op == Op.OpFunction) - methodInfo.ThisStageMethodId = context.Bound; - - var i2 = new OpData(i.Memory.Span); - if (i2.IdResult.HasValue) - remapIds.Add(i2.IdResult.Value, context.Bound++); - SpirvBuilder.RemapIds(remapIds, ref i2); - copiedInstructions.Add(i2); - - // Copy names too - if (i.IdResult is int resultId) - { - if (analysisResult.Names.TryGetValue(resultId, out var name)) - context.AddName(i2.IdResult!.Value, name); - } - } - - if (methodInfo.ThisStageMethodId == null) - throw new InvalidOperationException(); - - liveAnalysis.ExtraReferencedMethods.Add(methodInfo.ThisStageMethodId.Value); - - // TODO: adjust mixin instructions ranges - buffer.InsertRange(methodEnd, copiedInstructions.AsSpan()); - CodeInserted?.Invoke(methodEnd, copiedInstructions.Count); - } - } - - class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement, SymbolType? constantsReplacement) : TypeRewriter - { - public override SymbolType Visit(StreamsType streamsType) - { - return streamsType.Kind switch - { - StreamsKindSDSL.Streams => streamsReplacement, - StreamsKindSDSL.Input => inputReplacement, - StreamsKindSDSL.Output => outputReplacement, - StreamsKindSDSL.Constants => constantsReplacement ?? throw new InvalidOperationException(), - }; - } - } - - void PatchStreamsAccesses(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, StructType inputStructType, StructType outputStructType, StructType? constantsStructType, int streamsVariableId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) - { - var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); - - (var methodStart, _) = SpirvBuilder.FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); - - var streams = analysisResult.Streams; - // true => implicit (streams.), false => specific variable - var streamsInstructionIds = new Dictionary(); - - var method = (OpFunction)buffer[methodStart]; - var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; - - var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); - var newMethodType = (FunctionType)streamTypeReplacer.Visit(methodType); - if (!ReferenceEquals(newMethodType, methodType)) - { - methodType = newMethodType; - method.FunctionType = context.GetOrRegister(methodType); - var symbol = table.ResolveSymbol(functionId); - symbol.Type = methodType; - } - - // Remap ids for streams type to actual struct type - var remapIds = new Dictionary(); - var processedIds = new HashSet(); - - // Check if type contains any Streams/Input/Output (and if yes, register the replacement) - void CheckStreamTypes(int id) - { - if (processedIds.Add(id) && context.ReverseTypes.TryGetValue(id, out var type)) - { - // New type, check it - var replacedType = streamTypeReplacer.VisitType(type); - if (!ReferenceEquals(replacedType, type)) - remapIds.Add(id, context.GetOrRegister(replacedType)); - } - } - - // TODO: remap method type! - Span tempIdsForStreamCopy = stackalloc int[streams.Values.Count]; - for (int index = methodStart; ; ++index) - { - var i = buffer[index]; - - if (i.Op == Op.OpFunctionEnd) - break; - - if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) - { - streamsInstructionIds.Add(streamsInstruction.ResultId, true); - remapIds.Add(streamsInstruction.ResultId, streamsVariableId); - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - else if (i.Op is Op.OpVariable && (OpVariable)i is { } variable) - { - var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(variable.ResultId, false); - } - else if (i.Op is Op.OpFunctionParameter && (OpFunctionParameter)i is { } functionParameter) - { - var type = context.ReverseTypes[functionParameter.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(functionParameter.ResultId, false); - } - else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) - { - // In case it's a streams access, patch acces to use STREAMS struct with proper index - if (streamsInstructionIds.TryGetValue(accessChain.BaseId, out var isImplicit)) - { - var streamVariableId = accessChain.Values.Elements.Span[0]; - var streamInfo = streams[streamVariableId]; - var streamStructMemberIndex = streamInfo.StreamStructFieldIndex; - - // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that - // we'll need a better way to update LiteralArray and propagate changes - accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; - - if (isImplicit) - accessChain.BaseId = streamsVariableId; - else - // Force refresh of InstructionMemory - // TODO: remove when accessChain.Values update properly the instruction - accessChain.BaseId = accessChain.BaseId; - } - } - else if (i.Op == Op.OpCopyLogical && (OpCopyLogical)i is { } copyLogical) - { - // Cast input to streams - var targetType = context.ReverseTypes[copyLogical.ResultType]; - if (targetType is StreamsType { Kind: StreamsKindSDSL.Streams }) - { - foreach (var stream in streams) - { - // Part of streams? - if (!stream.Value.Patch && stream.Value.UsedThisStage) - { - if (stream.Value.Input) - { - // Extract value from streams - tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = buffer.Insert(index++, - new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), - context.Bound++, - copyLogical.Operand, - [stream.Value.InputStructFieldIndex.Value])).ResultId; - } - else - { - // Otherwise use default value - tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = context.CreateDefaultConstantComposite(stream.Value.Type).Id; - } - } - } - - // Update index (otherwise copyLogical fields will point to invalid data) - i.Index = index; - buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [..tempIdsForStreamCopy.Slice(0, streamsStructType.Members.Count)])); - } - else if (targetType is StreamsType { Kind: StreamsKindSDSL.Output }) - { - foreach (var stream in streams) - { - // Part of streams? - if (!stream.Value.Patch && stream.Value.Output) - { - // Extract value from streams - tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex.Value] = buffer.Insert(index++, - new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), - context.Bound++, - copyLogical.Operand, - [stream.Value.StreamStructFieldIndex])).ResultId; - } - } - - // Update index (otherwise copyLogical fields will point to invalid data) - i.Index = index; - buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [..tempIdsForStreamCopy.Slice(0, outputStructType.Members.Count)])); - } - } - else if (i.Op == Op.OpEmitVertexSDSL && (OpEmitVertexSDSL)i is { } emitVertex) - { - var output = emitVertex.Output; - foreach (var stream in streams) - { - if (stream.Value.Output) - { - var outputValue = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, output, [stream.Value.OutputStructFieldIndex.Value])).ResultId; - buffer.Insert(index++, new OpStore(stream.Value.OutputId.Value, outputValue, MemoryAccessMask.None, [])); - } - } - - buffer.Replace(index, new OpEmitVertex()); - } - else if (i.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } call) - { - var calledMethodInfo = liveAnalysis.ReferencedMethods[call.Function]; - // In case we copied the method, use the new ID - if (calledMethodInfo.ThisStageMethodId is int updatedMethodId) - call.Function = updatedMethodId; - } - - SpirvBuilder.CollectIds(i.Data, CheckStreamTypes); - - SpirvBuilder.RemapIds(remapIds, ref i.Data); - } - } } } diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs new file mode 100644 index 0000000000..b2b488fa91 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs @@ -0,0 +1,79 @@ +using System.Runtime.InteropServices; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; + +/// +/// Handles duplication of methods for different shader stages. +/// +internal static class MethodDuplicator +{ + + /// + /// Duplicates a method if it's used by multiple shader stages with different STREAMS types. + /// On first use, backs up the original method code. On subsequent uses, creates a copy with new IDs. + /// + public static void DuplicateMethodIfNecessary( + NewSpirvBuffer buffer, + SpirvContext context, + int functionId, + AnalysisResult analysisResult, + LiveAnalysis liveAnalysis, + Action? codeInserted = null) + { + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + + (var methodStart, var methodEnd) = SpirvBuilder.FindMethodBounds(buffer, functionId); + + // One function might need to be duplicated in case it is used by different shader stages with STREAMS: + // On first time (in a stage), we backup method original content before mutation + // On second time (in a different stage), we copy the method (from original content) + if (methodInfo.OriginalMethodCode == null) + { + // Copy instructions memory (since we're going to mutate them and want to retain original version) + var methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); + foreach (ref var i in CollectionsMarshal.AsSpan(methodInstructions)) + i = new OpData(i.Memory.Span); + + methodInfo.OriginalMethodCode = methodInstructions; + } + else + { + // Need to reinsert method with new IDs + var remapIds = new Dictionary(); + var copiedInstructions = new List(); + foreach (var i in methodInfo.OriginalMethodCode) + { + // Save copied function ID + if (i.Op == Op.OpFunction) + methodInfo.ThisStageMethodId = context.Bound; + + var i2 = new OpData(i.Memory.Span); + if (i2.IdResult.HasValue) + remapIds.Add(i2.IdResult.Value, context.Bound++); + SpirvBuilder.RemapIds(remapIds, ref i2); + copiedInstructions.Add(i2); + + // Copy names too + if (i.IdResult is int resultId) + { + if (analysisResult.Names.TryGetValue(resultId, out var name)) + context.AddName(i2.IdResult!.Value, name); + } + } + + if (methodInfo.ThisStageMethodId == null) + throw new InvalidOperationException(); + + liveAnalysis.ExtraReferencedMethods.Add(methodInfo.ThisStageMethodId.Value); + + // TODO: adjust mixin instructions ranges + buffer.InsertRange(methodEnd, CollectionsMarshal.AsSpan(copiedInstructions)); + codeInserted?.Invoke(methodEnd, copiedInstructions.Count); + } + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs new file mode 100644 index 0000000000..468d5ff048 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs @@ -0,0 +1,214 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; + +/// +/// Handles patching of SPIR-V stream access instructions. +/// +internal static class StreamAccessPatcher +{ + /// + /// Type rewriter that replaces StreamsType with concrete struct types. + /// + private class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement, SymbolType? constantsReplacement) : TypeRewriter + { + public override SymbolType Visit(StreamsType streamsType) + { + return streamsType.Kind switch + { + StreamsKindSDSL.Streams => streamsReplacement, + StreamsKindSDSL.Input => inputReplacement, + StreamsKindSDSL.Output => outputReplacement, + StreamsKindSDSL.Constants => constantsReplacement ?? throw new InvalidOperationException(), + }; + } + } + + /// + /// Patches stream accesses in a method to use the concrete struct types instead of abstract stream types. + /// + public static void PatchStreamsAccesses( + SymbolTable table, + NewSpirvBuffer buffer, + SpirvContext context, + int functionId, + StructType streamsStructType, + StructType inputStructType, + StructType outputStructType, + StructType? constantsStructType, + int streamsVariableId, + AnalysisResult analysisResult, + LiveAnalysis liveAnalysis) + { + var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); + + (var methodStart, _) = SpirvBuilder.FindMethodBounds(buffer, methodInfo.ThisStageMethodId ?? functionId); + + var streams = analysisResult.Streams; + // true => implicit (streams.), false => specific variable + var streamsInstructionIds = new Dictionary(); + + var method = (OpFunction)buffer[methodStart]; + var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; + + var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); + var newMethodType = (FunctionType)streamTypeReplacer.Visit(methodType); + if (!ReferenceEquals(newMethodType, methodType)) + { + methodType = newMethodType; + method.FunctionType = context.GetOrRegister(methodType); + var symbol = table.ResolveSymbol(functionId); + symbol.Type = methodType; + } + + // Remap ids for streams type to actual struct type + var remapIds = new Dictionary(); + var processedIds = new HashSet(); + + // Check if type contains any Streams/Input/Output (and if yes, register the replacement) + void CheckStreamTypes(int id) + { + if (processedIds.Add(id) && context.ReverseTypes.TryGetValue(id, out var type)) + { + // New type, check it + var replacedType = streamTypeReplacer.VisitType(type); + if (!ReferenceEquals(replacedType, type)) + remapIds.Add(id, context.GetOrRegister(replacedType)); + } + } + + // TODO: remap method type! + Span tempIdsForStreamCopy = stackalloc int[streams.Values.Count]; + for (int index = methodStart; ; ++index) + { + var i = buffer[index]; + + if (i.Op == Op.OpFunctionEnd) + break; + + if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) + { + streamsInstructionIds.Add(streamsInstruction.ResultId, true); + remapIds.Add(streamsInstruction.ResultId, streamsVariableId); + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + else if (i.Op is Op.OpVariable && (OpVariable)i is { } variable) + { + var type = context.ReverseTypes[variable.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + streamsInstructionIds.Add(variable.ResultId, false); + } + else if (i.Op is Op.OpFunctionParameter && (OpFunctionParameter)i is { } functionParameter) + { + var type = context.ReverseTypes[functionParameter.ResultType]; + if (type is PointerType { BaseType: StreamsType }) + streamsInstructionIds.Add(functionParameter.ResultId, false); + } + else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) + { + // In case it's a streams access, patch acces to use STREAMS struct with proper index + if (streamsInstructionIds.TryGetValue(accessChain.BaseId, out var isImplicit)) + { + var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamInfo = streams[streamVariableId]; + var streamStructMemberIndex = streamInfo.StreamStructFieldIndex; + + // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that + // we'll need a better way to update LiteralArray and propagate changes + accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; + + if (isImplicit) + accessChain.BaseId = streamsVariableId; + else + // Force refresh of InstructionMemory + // TODO: remove when accessChain.Values update properly the instruction + accessChain.BaseId = accessChain.BaseId; + } + } + else if (i.Op == Op.OpCopyLogical && (OpCopyLogical)i is { } copyLogical) + { + // Cast input to streams + var targetType = context.ReverseTypes[copyLogical.ResultType]; + if (targetType is StreamsType { Kind: StreamsKindSDSL.Streams }) + { + foreach (var stream in streams) + { + // Part of streams? + if (!stream.Value.Patch && stream.Value.UsedThisStage) + { + if (stream.Value.Input) + { + // Extract value from streams + tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = buffer.Insert(index++, + new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), + context.Bound++, + copyLogical.Operand, + [stream.Value.InputStructFieldIndex.Value])).ResultId; + } + else + { + // Otherwise use default value + tempIdsForStreamCopy[stream.Value.StreamStructFieldIndex] = context.CreateDefaultConstantComposite(stream.Value.Type).Id; + } + } + } + + // Update index (otherwise copyLogical fields will point to invalid data) + i.Index = index; + buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [.. tempIdsForStreamCopy.Slice(0, streamsStructType.Members.Count)])); + } + else if (targetType is StreamsType { Kind: StreamsKindSDSL.Output }) + { + foreach (var stream in streams) + { + // Part of streams? + if (!stream.Value.Patch && stream.Value.Output) + { + // Extract value from streams + tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex.Value] = buffer.Insert(index++, + new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), + context.Bound++, + copyLogical.Operand, + [stream.Value.StreamStructFieldIndex])).ResultId; + } + } + + // Update index (otherwise copyLogical fields will point to invalid data) + i.Index = index; + buffer.Replace(index, new OpCompositeConstruct(copyLogical.ResultType, copyLogical.ResultId, [.. tempIdsForStreamCopy.Slice(0, outputStructType.Members.Count)])); + } + } + else if (i.Op == Op.OpEmitVertexSDSL && (OpEmitVertexSDSL)i is { } emitVertex) + { + var output = emitVertex.Output; + foreach (var stream in streams) + { + if (stream.Value.Output) + { + var outputValue = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, output, [stream.Value.OutputStructFieldIndex.Value])).ResultId; + buffer.Insert(index++, new OpStore(stream.Value.OutputId.Value, outputValue, MemoryAccessMask.None, [])); + } + } + + buffer.Replace(index, new OpEmitVertex()); + } + else if (i.Op == Op.OpFunctionCall && (OpFunctionCall)i is { } call) + { + var calledMethodInfo = liveAnalysis.ReferencedMethods[call.Function]; + // In case we copied the method, use the new ID + if (calledMethodInfo.ThisStageMethodId is int updatedMethodId) + call.Function = updatedMethodId; + } + + SpirvBuilder.CollectIds(i.Data, CheckStreamTypes); + + SpirvBuilder.RemapIds(remapIds, ref i.Data); + } + } +} From c6b6140a4b4e018eedbceb731eb7f7c590f73ba6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 10:09:18 +0900 Subject: [PATCH 0780/1182] Phase5 part1 --- .../Spirv/Processing/InterfaceProcessor.cs | 103 +------------ .../Generation/BuiltinProcessor.cs | 137 ++++++++++++++++++ .../StreamWrapperGenerator_README.md | 21 +++ 3 files changed, 166 insertions(+), 95 deletions(-) create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs create mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs index ecd8a6f261..b5cac9b506 100644 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs @@ -14,6 +14,7 @@ using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; namespace Stride.Shaders.Spirv.Processing { @@ -238,104 +239,16 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) } } - bool AddBuiltin(int variable, BuiltIn builtin) - { - context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)builtin])); - return true; - } - - bool AddLocation(int variable, string location) - { - // If it fails, default is 0 - int.TryParse(location, out var targetIndex); - context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); - return true; - } + // Delegate to BuiltinProcessor + bool AddBuiltin(int variable, BuiltIn builtin) => BuiltinProcessor.AddBuiltin(context, variable, builtin); - // Handle some conversions for builtins where type is not flexible - // need to handle array size adjust, and vector size adjust as per ProcessBuiltinsDecoration() symbolType processing - int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) - { - if (sourceType == castType) - return value; + bool AddLocation(int variable, string location) => BuiltinProcessor.AddLocation(context, variable, location); - if (sourceType is VectorType v1 && castType is VectorType v2 && v1.BaseType == v2.BaseType) - { - Span components = stackalloc int[v2.Size]; - for (int i = 0; i < v2.Size; ++i) - { - components[i] = i < v1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).ResultId - : context.CreateDefaultConstantComposite(v1.BaseType).Id; - } + int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) => + BuiltinProcessor.ConvertInterfaceVariable(buffer, context, sourceType, castType, value); - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).ResultId; - } - - if (sourceType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType) - { - Span components = stackalloc int[a2.Size]; - for (int i = 0; i < a2.Size; ++i) - { - components[i] = i < a1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).ResultId - : context.CreateDefaultConstantComposite(a1.BaseType).Id; - } - - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).ResultId; - } - - throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); - } - - bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) - { - semantic = semantic?.ToUpperInvariant(); - symbolType = (executionModel, type, semantic) switch - { - // DX might use float[2] or float[3] or float[4] but Vulkan expects float[4] in all cases - (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_TESSFACTOR") => new ArrayType(ScalarType.Float, 4), - // DX might use float or float[2] but Vulkan expects float[2] in all cases - (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_INSIDETESSFACTOR") => new ArrayType(ScalarType.Float, 2), - // DX might use float2 or float3 but Vulkan expects float3 in all cases - (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_DOMAINLOCATION") => new VectorType(ScalarType.Float, 3), - _ => symbolType, - }; - - // Note: false means it needs to be forwarded - // TODO: review the case where we don't use automatic forwarding for HS/DS/GS stages, i.e. SV_POSITION and SV_PrimitiveID - return (executionModel, type, semantic) switch - { - // SV_Depth/SV_Target - (ExecutionModel.Fragment, StreamVariableType.Output, "SV_DEPTH") => AddBuiltin(variable, BuiltIn.FragDepth), - (ExecutionModel.Fragment, StreamVariableType.Output, {} semantic2) when semantic2.StartsWith("SV_TARGET") => AddLocation(variable, semantic2.Substring("SV_TARGET".Length)), - // SV_Position - (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), - (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.Position), - (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(variable, BuiltIn.FragCoord), - // SV_InstanceID/SV_VertexID - (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(variable, BuiltIn.InstanceIndex), - (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(variable, BuiltIn.VertexIndex), - (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID" or "SV_VERTEXID") => false, - // SV_IsFrontFace - (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(variable, BuiltIn.FrontFacing), - // SV_PrimitiveID - (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PRIMITIVEID") => AddBuiltin(variable, BuiltIn.PrimitiveId), - (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PRIMITIVEID") => AddBuiltin(variable, BuiltIn.PrimitiveId), - // Tessellation - (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_TESSFACTOR") => AddBuiltin(variable, BuiltIn.TessLevelOuter), - (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_INSIDETESSFACTOR") => AddBuiltin(variable, BuiltIn.TessLevelInner), - (ExecutionModel.TessellationEvaluation, StreamVariableType.Input, "SV_DOMAINLOCATION") => AddBuiltin(variable, BuiltIn.TessCoord), - (ExecutionModel.TessellationControl, StreamVariableType.Input, "SV_OUTPUTCONTROLPOINTID") => AddBuiltin(variable, BuiltIn.InvocationId), - // Compute shaders - (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPID") => AddBuiltin(variable, BuiltIn.WorkgroupId), - (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPINDEX") => AddBuiltin(variable, BuiltIn.LocalInvocationIndex), - (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPTHREADID") => AddBuiltin(variable, BuiltIn.LocalInvocationId), - (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_DISPATCHTHREADID") => AddBuiltin(variable, BuiltIn.GlobalInvocationId), - (_, _, {} semantic2) when semantic2.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic2} for stage {executionModel} as {type}"), - _ => false, - }; - } + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) => + BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variable, type, semantic, ref symbolType); var entryPointFunctionType = (FunctionType)entryPoint.Type; // TODO: check all parameters instead of hardcoded 0 diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs new file mode 100644 index 0000000000..373a0b3aad --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs @@ -0,0 +1,137 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; + +/// +/// Handles processing of builtin variables and semantics (SV_*). +/// +internal static class BuiltinProcessor +{ + /// + /// Adds a BuiltIn decoration to a variable. + /// + public static bool AddBuiltin(SpirvContext context, int variable, BuiltIn builtin) + { + context.Add(new OpDecorate(variable, Decoration.BuiltIn, [(int)builtin])); + return true; + } + + /// + /// Adds a Location decoration to a variable. + /// + public static bool AddLocation(SpirvContext context, int variable, string location) + { + // If it fails, default is 0 + int.TryParse(location, out var targetIndex); + context.Add(new OpDecorate(variable, Decoration.Location, [targetIndex])); + return true; + } + + /// + /// Converts interface variables between types, handling vector and array size mismatches. + /// Used when builtin types have different sizes than shader types. + /// + public static int ConvertInterfaceVariable( + NewSpirvBuffer buffer, + SpirvContext context, + SymbolType sourceType, + SymbolType castType, + int value) + { + if (sourceType == castType) + return value; + + if (sourceType is VectorType v1 && castType is VectorType v2 && v1.BaseType == v2.BaseType) + { + Span components = stackalloc int[v2.Size]; + for (int i = 0; i < v2.Size; ++i) + { + components[i] = i < v1.Size + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).ResultId + : context.CreateDefaultConstantComposite(v1.BaseType).Id; + } + + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).ResultId; + } + + if (sourceType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType) + { + Span components = stackalloc int[a2.Size]; + for (int i = 0; i < a2.Size; ++i) + { + components[i] = i < a1.Size + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).ResultId + : context.CreateDefaultConstantComposite(a1.BaseType).Id; + } + + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).ResultId; + } + + throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); + } + + /// + /// Processes builtin decorations for system-value semantics (SV_*). + /// Adjusts types as needed for Vulkan compatibility and adds appropriate decorations. + /// + /// True if the variable is a builtin and doesn't need forwarding, false if it needs forwarding. + public static bool ProcessBuiltinsDecoration( + SpirvContext context, + ExecutionModel executionModel, + int variable, + StreamVariableType type, + string? semantic, + ref SymbolType symbolType) + { + semantic = semantic?.ToUpperInvariant(); + symbolType = (executionModel, type, semantic) switch + { + // DX might use float[2] or float[3] or float[4] but Vulkan expects float[4] in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_TESSFACTOR") => new ArrayType(ScalarType.Float, 4), + // DX might use float or float[2] but Vulkan expects float[2] in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_INSIDETESSFACTOR") => new ArrayType(ScalarType.Float, 2), + // DX might use float2 or float3 but Vulkan expects float3 in all cases + (ExecutionModel.TessellationControl, StreamVariableType.Output, "SV_DOMAINLOCATION") => new VectorType(ScalarType.Float, 3), + _ => symbolType, + }; + + // Note: false means it needs to be forwarded + // TODO: review the case where we don't use automatic forwarding for HS/DS/GS stages, i.e. SV_POSITION and SV_PrimitiveID + return (executionModel, type, semantic) switch + { + // SV_Depth/SV_Target + (ExecutionModel.Fragment, StreamVariableType.Output, "SV_DEPTH") => AddBuiltin(context, variable, BuiltIn.FragDepth), + (ExecutionModel.Fragment, StreamVariableType.Output, { } semantic2) when semantic2.StartsWith("SV_TARGET") => AddLocation(context, variable, semantic2.Substring("SV_TARGET".Length)), + // SV_Position + (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), + (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), + (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.FragCoord), + // SV_InstanceID/SV_VertexID + (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(context, variable, BuiltIn.InstanceIndex), + (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(context, variable, BuiltIn.VertexIndex), + (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID" or "SV_VERTEXID") => false, + // SV_IsFrontFace + (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(context, variable, BuiltIn.FrontFacing), + // SV_PrimitiveID + (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PRIMITIVEID") => AddBuiltin(context, variable, BuiltIn.PrimitiveId), + (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_PRIMITIVEID") => AddBuiltin(context, variable, BuiltIn.PrimitiveId), + // Tessellation + (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_TESSFACTOR") => AddBuiltin(context, variable, BuiltIn.TessLevelOuter), + (ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation, _, "SV_INSIDETESSFACTOR") => AddBuiltin(context, variable, BuiltIn.TessLevelInner), + (ExecutionModel.TessellationEvaluation, StreamVariableType.Input, "SV_DOMAINLOCATION") => AddBuiltin(context, variable, BuiltIn.TessCoord), + (ExecutionModel.TessellationControl, StreamVariableType.Input, "SV_OUTPUTCONTROLPOINTID") => AddBuiltin(context, variable, BuiltIn.InvocationId), + // Compute shaders + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPID") => AddBuiltin(context, variable, BuiltIn.WorkgroupId), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPINDEX") => AddBuiltin(context, variable, BuiltIn.LocalInvocationIndex), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_GROUPTHREADID") => AddBuiltin(context, variable, BuiltIn.LocalInvocationId), + (ExecutionModel.GLCompute, StreamVariableType.Input, "SV_DISPATCHTHREADID") => AddBuiltin(context, variable, BuiltIn.GlobalInvocationId), + (_, _, { } semantic2) when semantic2.StartsWith("SV_") => throw new NotImplementedException($"System-value Semantic not implemented: {semantic2} for stage {executionModel} as {type}"), + _ => false, + }; + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md new file mode 100644 index 0000000000..2b220c418d --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md @@ -0,0 +1,21 @@ +# StreamWrapperGenerator Extraction - Phase 5 + +## Status +Phase 5 is partially complete. The BuiltinProcessor has been successfully extracted. + +## Remaining Work +The `GenerateStreamWrapper` method (688 lines, lines 207-894 in InterfaceProcessor.cs) needs to be extracted into this class. + +## Approach +Due to the size and complexity of this method, with 10 local helper functions tightly coupled to local state, the extraction requires: + +1. Creating a static `GenerateStreamWrapper` method in StreamWrapperGenerator class +2. Adding parameters for dependencies: + - `Action? codeInserted` - for the CodeInserted delegate + - `Func findOutputPatchSize` - for FindOutputPatchSize method + - `Func resolveHullPatchConstantEntryPoint` - for ResolveHullPatchConstantEntryPoint method +3. Updating InterfaceProcessor to call the extracted method +4. Keeping the local helper functions within the method (they're tightly coupled) + +## Alternative Approach +Instead of a massive static method, consider creating StreamWrapperGenerator as an instance class that holds state (buffer, context, etc.) and breaks down the local functions into private methods. This would be a cleaner architecture but requires more extensive refactoring. From 05dca062b837e5b88ec0302ed10ea0df928a3a81 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 10:57:26 +0900 Subject: [PATCH 0781/1182] Fix: Group overloads together --- src/Stride.Shaders.Generators/IntrinsicGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index 21037fcbd1..650edb2987 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -48,7 +48,7 @@ public static partial class IntrinsicsDefinitions { builder.AppendLine($"public static FrozenDictionary {ns.Name.Name} {{ get; }} = new Dictionary()") .AppendLine("{"); - foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name).Where(x => x.Key is not null && x.Key.Name is not "printf")) + foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) { builder.AppendLine($"[\"{intrinsicGroup.Key}\"] = ["); foreach (var overload in intrinsicGroup.Where(i => i is not null)) From 5ff44336ccd256093a30da6e617edeb707243661 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 15:20:57 +0900 Subject: [PATCH 0782/1182] $typeN should only update typename, but should keep the matching info --- .../IntrinsicGenerator.cs | 4 ++-- .../Intrinsics/IntrinAST.cs | 4 ++-- .../Intrinsics/Parser.cs | 21 ++++++++++++------- .../Core/IntrinsicsParameters.cs | 6 +++--- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index 650edb2987..f2763a8b78 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -65,7 +65,7 @@ public static partial class IntrinsicsDefinitions _ = overload.ReturnType.Match switch { - Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), + Matching m => builder.Append($", new({m.LayoutIndex}, {m.BaseTypeIndex})"), _ => builder.Append(", null") }; builder.AppendLine("), "); @@ -94,7 +94,7 @@ public static partial class IntrinsicsDefinitions }; _ = param.TypeInfo.Match switch { - Matching m => builder.Append($", new({m.ComponentA}, {m.ComponentB})"), + Matching m => builder.Append($", new({m.LayoutIndex}, {m.BaseTypeIndex})"), _ => builder.Append(", null") }; builder.Append($"), \"{param.Name.Name}\""); diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs index 758247e361..375f7a7e97 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -31,11 +31,11 @@ internal record Typename(string Name, Layout? Size, TextLocation Location) : Nod } // internal record NumericType(Layout Size, TextLocation Location) : Typename("numeric", Size, Location); -internal record Matching(int ComponentA, int ComponentB, TextLocation Location) : Node(Location); +internal record Matching(int LayoutIndex, int BaseTypeIndex, TextLocation Location) : Node(Location); internal record ClassTMatch(TextLocation Location) : Matching(-1, 0,Location); internal record FuncMatch(TextLocation Location) : Matching(-3, 0, Location); internal record Func2Match(TextLocation Location) : Matching(-3, 0, Location); -internal record TypeMatch(int ComponentA, TextLocation Location) : Matching(ComponentA, ComponentA, Location); +internal record TypeMatch(int Index, TextLocation Location) : Matching(Index, Index, Location); internal record TypeInfo(Typename Typename, TextLocation Location, Matching? Match = null) : Node(Location); diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs index 289ff257b7..cd5c4643e6 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -483,23 +483,30 @@ internal static bool Parse(string code, out EquatableList var intrinsic = n.Intrinsics.Items[i]; if(intrinsic.ReturnType is { Typename.Name: "$to_resolve" }) { + var name = intrinsic.Parameters.Items[intrinsic.ReturnType.Match is TypeMatch tm ? tm.Index - 1 : throw new InvalidOperationException()].TypeInfo.Typename.Name; intrinsic = intrinsic with { - ReturnType = intrinsic.Parameters.Items[intrinsic.ReturnType.Match is TypeMatch tm ? tm.ComponentA - 1 : 0].TypeInfo + ReturnType = intrinsic.ReturnType with + { + Typename = intrinsic.ReturnType.Typename with { Name = name }, + } }; } for(int j = 0; j < intrinsic.Parameters.Items.Count; j++) { var parameter = intrinsic.Parameters.Items[j]; - if(parameter is not null && parameter.TypeInfo is { Typename.Name: "$to_resolve", Match: TypeMatch {ComponentA : >= 0} tm}) + if(parameter is not null && parameter.TypeInfo is { Typename.Name: "$to_resolve", Match: TypeMatch {Index : >= 0} tm}) { - parameter = tm switch + var name = tm switch + { + { Index: 0 } => intrinsic.ReturnType.Typename.Name, + _ => intrinsic.Parameters.Items[tm.Index - 1].TypeInfo.Typename.Name, + }; + + intrinsic.Parameters.Items[j] = intrinsic.Parameters.Items[j] with { - { ComponentA: 0 } => parameter with { TypeInfo = intrinsic.ReturnType }, - _ => parameter with { TypeInfo = intrinsic.Parameters.Items[tm.ComponentA - 1].TypeInfo } + TypeInfo = parameter.TypeInfo with { Typename = parameter.TypeInfo.Typename with { Name = name } } }; - - intrinsic.Parameters.Items[j] = parameter; } } diff --git a/src/Stride.Shaders/Core/IntrinsicsParameters.cs b/src/Stride.Shaders/Core/IntrinsicsParameters.cs index f195b7b65f..7657b1e83f 100644 --- a/src/Stride.Shaders/Core/IntrinsicsParameters.cs +++ b/src/Stride.Shaders/Core/IntrinsicsParameters.cs @@ -8,10 +8,10 @@ public enum OptionalQualifier { RowMajor, ColumnMajor }; public record struct VectorSize(string X, string? Y = null); -public record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int, int)? Match = null) +public record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int Layout, int BaseType)? Match = null) { - public ParameterType(int a, int b) : this(BaseType.Match, Match: (a, b)){} - public ParameterType(string baseType,VectorSize? VectorSize = null, (int, int)? matching = null) : + public ParameterType(int matchLayout, int matchBaseType) : this(BaseType.Match, Match: (matchLayout, matchBaseType)){} + public ParameterType(string baseType,VectorSize? VectorSize = null, (int Layout, int BaseType)? matching = null) : this( baseType switch { From 0559a7f07e08b362f885a9014fcd7e1eca7c886d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 4 Feb 2026 23:47:35 +0900 Subject: [PATCH 0783/1182] Rewrote intrinsics to use new system --- assets/SDSL/RenderTests/Intrinsics.sdsl | 31 +- src/Stride.Shaders.Experiments/Program.cs | 19 +- .../IntrinsicGenerator.cs | 66 ++ src/Stride.Shaders/Core/SymbolTypes.cs | 1 + .../Parsing/SDSL/AST/Expression.Intrinsics.cs | 752 ------------------ .../Parsing/SDSL/AST/Expression.cs | 113 +-- .../Parsing/SDSL/AST/IntrinsicCall.cs | 145 ++++ .../SDSL/AST/IntrinsicImplementations.cs | 522 ++++++++++++ .../SDSL/AST/IntrinsicTemplateExpander.cs | 357 +++++++++ .../Parsing/SDSL/AST/Literals.cs | 4 +- .../PrimaryExpressionParsers.cs | 205 +---- .../Spirv/Building/Builder.Expressions.cs | 34 +- src/Stride.Shaders/Spirv/Building/Context.cs | 8 + 13 files changed, 1237 insertions(+), 1020 deletions(-) delete mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs diff --git a/assets/SDSL/RenderTests/Intrinsics.sdsl b/assets/SDSL/RenderTests/Intrinsics.sdsl index 84f533c604..f542668c99 100644 --- a/assets/SDSL/RenderTests/Intrinsics.sdsl +++ b/assets/SDSL/RenderTests/Intrinsics.sdsl @@ -1,13 +1,40 @@ -// PSMain(ExpectedResult=#00FFFF00) +// PSMain(ExpectedResult=#00FFFF00, cbuffer.Test=(Test1=0)) +// PSMain(ExpectedResult=#9CB8D400, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#04060809, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#FF000000, cbuffer.Test=(Test1=3)) namespace Stride.Shaders.Tests; shader Intrinsics { stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } void PSMain() { - streams.ColorTarget = float4(sin(0), cos(0), sin(radians(90)), cos(radians(90))); + streams.ColorTarget = 0.0; + if (Test1 == 0) + streams.ColorTarget = float4(sin(0), cos(0), sin(radians(90)), cos(radians(90))); + else if (Test1 == 1) + { + float2x4 a1 = float2x4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0); + float4x3 a2 = float4x3(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0); + float2x3 a3 = mul(a1, a2) / 255.0; + streams.ColorTarget = float4(a3[0] + a3[1], 0.0); + } + else if (Test1 == 2) + { + // Test auto-generated loop over matrix type + float2x4 a = min(float2x4(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0), 6.0f) / 255.0; + streams.ColorTarget = a[0] + a[1]; + } + else if (Test1 == 3) + { + streams.ColorTarget = normalize(float4(0.1, 0.0, 0.0, 0.0)); + } } } \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 470fdb848f..20b803203f 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -8,6 +8,9 @@ using Stride.Shaders; using System.Text.Json; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; // Console.WriteLine(Spv2DXIL.spirv_to_dxil_get_version()); @@ -25,9 +28,19 @@ // File.WriteAllText("test.spvdis", source); -var i = IntrinsicsDefinitions.Intrinsics["saturate"]; - -Console.WriteLine(i); +var table = new SymbolTable(new SpirvContext()); +foreach (var i in IntrinsicsDefinitions.Intrinsics) +{ + try + { + var test = new IntrinsicCall(new(i.Key, default), new ShaderExpressionList(default), default); + test.ProcessSymbol(table); + } + catch (Exception e) + { + Console.WriteLine($"{i.Key}: couldn't process {e}"); + } +} // Examples.TryAllFiles(); // Examples.CreateShader(); diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index f2763a8b78..e7c7a81fcb 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -1,4 +1,5 @@ using System.Collections.Frozen; +using System.Diagnostics; using System.Text; using System.Text.Json; using Microsoft.CodeAnalysis; @@ -20,6 +21,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .Select(ParseInstrinsics); context.RegisterSourceOutput(file, GenerateIntrinsicsData); + context.RegisterSourceOutput(file, GenerateIntrinsicsCall); // context.RegisterSourceOutput(file, (spc, ns) => // { @@ -119,6 +121,70 @@ public static partial class IntrinsicsDefinitions ); } + static string GenerateParameters(List parameters) + { + return string.Concat(parameters.Where(x => x is not null).Select(p => $", SpirvValue {p.Name.Name}")); + } + + static string GenerateArguments(List parameters) + { + return string.Concat(parameters.Where(x => x is not null).Select((p, i) => $", new SpirvValue(compiledParams[{i}], context.GetOrRegister(functionType.ParameterTypes[{i}].Type))")); + } + + static string CapitalizeFirstLetter(string s) => char.ToUpper(s[0]) + s[1..]; + + static void GenerateIntrinsicsCall(SourceProductionContext spc, EquatableList namespaces) + { + var builder = new StringBuilder(); + + builder.AppendLine(""" + namespace Stride.Shaders.Parsing.SDSL; + + using System.Collections.Frozen; + using Stride.Shaders.Core; + using Stride.Shaders.Spirv.Building; + using Stride.Shaders.Parsing.Analysis; + + """); + + foreach (var ns in namespaces.Items.Where(x => x.Name.Name == "Intrinsics")) + { + builder.AppendLine($"public abstract class {ns.Name.Name}Declarations"); + builder.AppendLine("{"); + foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) + { + foreach (var overload in intrinsicGroup.Where(i => i is not null).GroupBy(x => GenerateParameters(x.Parameters.Items))) + { + builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{overload.Key}) => throw new NotImplementedException();"); + } + } + + builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string name, FunctionType functionType, Span compiledParams) {"); + builder.AppendLine("var (builder, context) = compiler;"); + builder.AppendLine("return (name, compiledParams.Length) switch {"); + foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) + { + foreach (var overload in intrinsicGroup.Where(i => i is not null).GroupBy(x => GenerateParameters(x.Parameters.Items))) + { + builder.AppendLine($"(\"{intrinsicGroup.Key}\", {overload.First().Parameters.Items.Count}) => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{GenerateArguments(overload.First().Parameters.Items)}),"); + } + } + builder.AppendLine("};"); + builder.AppendLine("}"); + } + builder.AppendLine("}"); + + spc.AddSource( + "IntrinsicsCall.g.cs", + SourceText.From( + SyntaxFactory.ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + internal static EquatableList ParseInstrinsics(AdditionalText text, CancellationToken ct) { diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index eb628dab5d..f10c2b52fd 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -178,6 +178,7 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum public int Columns { get; } = Columns >= 2 ? Columns : throw new ArgumentException("Argument must be at least 2.", nameof(Columns)); // Note: this is HLSL-style so Rows/Columns meaning is swapped + // float2x3 = OpTypeMatrix vec3 2 = MatrixType(Rows: 3, Columns: 2) public override string ToString() => $"{BaseType}{Columns}x{Rows}"; } /// diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs deleted file mode 100644 index 49733c2814..0000000000 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.Intrinsics.cs +++ /dev/null @@ -1,752 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.Analysis; -using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Core; -using System; -using Stride.Shaders.Spirv; - -namespace Stride.Shaders.Parsing.SDSL; - -public static class IntrinsicHelper -{ - public static SymbolType FindCommonType(ScalarType baseType, params Span types) - { - // Check if any vector type (and get the minimum size) - int vectorTypeMinSize = 0; - foreach (var type in types) - { - if (type is VectorType v) - vectorTypeMinSize = vectorTypeMinSize == 0 ? v.Size : Math.Min(vectorTypeMinSize, v.Size); - } - - if (vectorTypeMinSize != 0) - return new VectorType(baseType, vectorTypeMinSize); - - // Otherwise, ensure it's all ScalarType - foreach (var type in types) - { - if (type is not ScalarType) - throw new InvalidOperationException($"Can't find a common type between {string.Join(",", types)}"); - } - - return baseType; - } -} - -public class AbsCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("abs", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - - var elementType = Arguments.Values[0].ValueType.GetElementType(); - if (elementType.IsFloating()) - { - var instruction = builder.Insert(new GLSLFAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } - else if (elementType.IsInteger()) - { - var instruction = builder.Insert(new GLSLSAbs(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } - else - { - throw new InvalidOperationException($"Unknown type for abs: {elementType}"); - } - } -} -public class SignCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("fsign", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - - var elementType = Type.GetElementType(); - if (elementType.IsFloating()) - { - var instruction = builder.Insert(new GLSLFSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } - else if (elementType.IsInteger()) - { - var instruction = builder.Insert(new GLSLSSign(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } - else - { - throw new InvalidOperationException($"Unknown type for abs: {elementType}"); - } - } -} -public class GLSLFloatBinaryCall(ShaderExpressionList arguments, TextLocation info, Specification.GLSLOp op) : MethodCall(new(op.ToString(), info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - - x = builder.Convert(context, x, Type); - y = builder.Convert(context, y, Type); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLPow(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - // Adjust OpCode only since Pow/Atan2 share the same operands - instruction.InstructionMemory.Span[4] = (int)op; - return new(instruction.ResultId, instruction.ResultType); - } -} - -public class GLSLFloatUnaryCall(ShaderExpressionList arguments, TextLocation info, Specification.GLSLOp op, float? multiplyConstant = null) : MethodCall(new(op.ToString(), info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType.WithElementType(ScalarType.Float); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - - x = builder.Convert(context, x, Type); - - var instruction = builder.Insert(new GLSLExp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - // Adjust OpCode only since Exp/Exp2/Log/Log2 share the same operands - instruction.InstructionMemory.Span[4] = (int)op; - var result = new SpirvValue(instruction.ResultId, instruction.ResultType); - - if (multiplyConstant != null) - { - var constant = context.CompileConstant(multiplyConstant); - constant = builder.Convert(context, constant, Type); - var instruction2 = builder.Insert(new OpFMul(x.TypeId, context.Bound++, instruction.ResultId, constant.Id)); - result = new SpirvValue(instruction2.ResultId, instruction2.ResultType); - } - - return result; - } -} -public class DeterminantCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("determinant", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType.GetElementType(); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLDeterminant(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class MinCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("min", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - x = builder.Convert(context, x, Type); - y = builder.Convert(context, y, Type); - - var instruction = Type.GetElementType() switch - { - ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - }; - return new(instruction); - } -} -public class MaxCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("max", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), yType.GetElementType()), xType, yType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - x = builder.Convert(context, x, Type); - y = builder.Convert(context, y, Type); - - var instruction = Type.GetElementType() switch - { - ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMax(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)), - }; - return new(instruction); - } -} -public class ClampCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("clamp", info), arguments, info) -{ - protected ScalarType baseType; - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var minValType = Arguments.Values[1].ValueType; - var maxValType = Arguments.Values[2].ValueType; - baseType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(SpirvBuilder.FindCommonBaseTypeForBinaryOperation(xType.GetElementType(), minValType.GetElementType()), maxValType.GetElementType()); - Type = IntrinsicHelper.FindCommonType(baseType, xType, minValType, maxValType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, minVal, maxVal) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler), Arguments.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - // Ensure all vectors have the same size - var xType = Arguments.Values[0].ValueType; - var minValType = Arguments.Values[1].ValueType; - var maxValType = Arguments.Values[2].ValueType; - - x = builder.Convert(context, x, Type); - minVal = builder.Convert(context, minVal, Type); - maxVal = builder.Convert(context, maxVal, Type); - - var instruction = baseType switch - { - ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), - ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), - ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, minVal.Id, maxVal.Id)), - }; - return new(instruction); - } -} -public class SaturateCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("saturate", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = (Arguments.Values[0].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - var xType = Arguments.Values[0].ValueType; - var constant0 = context.CompileConstant(0.0f); - var constant1 = context.CompileConstant(1.0f); - - var baseType = xType.GetElementType(); - // Ensure 0.0 amd 1.0 constants have same type as x - constant0 = builder.Convert(context, constant0, xType); - constant1 = builder.Convert(context, constant1, xType); - - var instruction = baseType switch - { - ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), - ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), - ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id, constant0.Id, constant1.Id)), - }; - return new(instruction); - } -} -public class LerpCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("lerp", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - var aType = Arguments.Values[2].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType, aType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y, a) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler), Arguments.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - x = builder.Convert(context, x, Type); - y = builder.Convert(context, y, Type); - a = builder.Convert(context, a, Type); - - var instruction = builder.Insert(new GLSLFMix(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id, a.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class SmoothStepCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("smoothstep", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (edge0, edge1, x) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler), Arguments.Values[2].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLSmoothStep(edge0.TypeId, context.Bound++, context.GLSLSet ?? -1, edge0.Id, edge1.Id, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class LengthCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("length", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = ScalarType.Float; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - - var parameterType = Arguments.Values[0].ValueType.WithElementType(ScalarType.Float); - x = builder.Convert(context, x, parameterType); - - var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class DistanceCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("distance", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = ScalarType.Float; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - - var inputType = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); - - x = builder.Convert(context, x, inputType); - y = builder.Convert(context, y, inputType); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(Type), context.Bound++, context.GLSLSet ?? -1, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class DotCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("dot", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - - if (xType != yType) - throw new NotImplementedException("dot needs to be applied on same types"); - - if (!xType.GetElementType().IsFloating()) - throw new NotImplementedException("dot: only implemented for floating types"); - - Type = xType.GetElementType(); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - - var instruction = builder.Insert(new OpDot(context.GetOrRegister(Type), context.Bound++, x.Id, y.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class NormalizeCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("normalize", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLNormalize(x.TypeId, context.Bound++, context.GLSLSet ?? -1, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FaceForwardCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("faceforward", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var nType = Arguments.Values[0].ValueType; - var iType = Arguments.Values[1].ValueType; - var ngType = Arguments.Values[2].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, nType, iType, ngType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (n, i, ng) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler), Arguments.Values[2].CompileAsValue(table, compiler)); - - n = builder.Convert(context, n, Type); - i = builder.Convert(context, i, Type); - ng = builder.Convert(context, ng, Type); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLFaceForward(n.TypeId, context.Bound++, context.GLSLSet ?? -1, n.Id, i.Id, ng.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class ReflectCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("reflect", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var iType = Arguments.Values[0].ValueType; - var nType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (i, n) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - - i = builder.Convert(context, i, Type); - n = builder.Convert(context, n, Type); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLReflect(i.TypeId, context.Bound++, context.GLSLSet ?? -1, i.Id, n.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class RefractCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("refract", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var iType = Arguments.Values[0].ValueType; - var nType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, iType, nType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (i, n, eta) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler), Arguments.Values[2].CompileAsValue(table, compiler)); - - i = builder.Convert(context, i, Type); - n = builder.Convert(context, n, Type); - eta = builder.Convert(context, eta, ScalarType.Float); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new GLSLRefract(i.TypeId, context.Bound++, context.GLSLSet ?? -1, i.Id, n.Id, eta.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} -public class MulCall(ShaderExpressionList arguments, TextLocation info) : MethodCall(new("pow", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - - if (xType.GetElementType() != yType.GetElementType()) - throw new NotImplementedException("mul type conversion is currently not implemented"); - if (!xType.GetElementType().IsFloating()) - throw new NotImplementedException("Only implemented for floating types"); - - Type = (xType, yType) switch - { - (ScalarType type1, ScalarType type2) => type1, - (ScalarType type1, VectorType type2) => type2, - (ScalarType type1, MatrixType type2) => type2, - (VectorType type1, ScalarType type2) => type1, - (VectorType type1, VectorType type2) when type1.Size == type2.Size => type1, - (VectorType type1, MatrixType type2) when type1.Size == type2.Columns => new VectorType(type1.BaseType, type2.Rows), - (MatrixType type1, ScalarType type2) => type1, - (MatrixType type1, VectorType type2) when type1.Rows == type2.Size => new VectorType(type1.BaseType, type1.Columns), - (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => new MatrixType(type1.BaseType, type2.Rows, type1.Columns), - }; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - if (context.GLSLSet == null) - context.ImportGLSL(); - - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - - // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul - // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns and multiplication order need to be swapped - var result = (xType, yType) switch - { - (ScalarType type1, ScalarType type2) => builder.InsertData(new OpFMul(x.TypeId, context.Bound++, x.Id, y.Id)), - (ScalarType type1, VectorType type2) => builder.InsertData(new OpVectorTimesScalar(y.TypeId, context.Bound++, y.Id, x.Id)), - (ScalarType type1, MatrixType type2) => builder.InsertData(new OpMatrixTimesScalar(y.TypeId, context.Bound++, y.Id, x.Id)), - (VectorType type1, ScalarType type2) => builder.InsertData(new OpVectorTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), - (VectorType type1, VectorType type2) when type1.Size == type2.Size => builder.InsertData(new OpDot(x.TypeId, context.Bound++, x.Id, y.Id)), - (VectorType type1, MatrixType type2) when type1.Size == type2.Columns => builder.InsertData(new OpMatrixTimesVector(context.GetOrRegister(new VectorType(type1.BaseType, type2.Rows)), context.Bound++, y.Id, x.Id)), - (MatrixType type1, ScalarType type2) => builder.InsertData(new OpMatrixTimesScalar(x.TypeId, context.Bound++, x.Id, y.Id)), - (MatrixType type1, VectorType type2) when type1.Rows == type2.Size => builder.InsertData(new OpVectorTimesMatrix(context.GetOrRegister(new VectorType(type1.BaseType, type1.Columns)), context.Bound++, y.Id, x.Id)), - (MatrixType type1, MatrixType type2) when type1.Columns == type2.Rows => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type2.Rows, type1.Columns)), context.Bound++, y.Id, x.Id)), - }; - - return new SpirvValue(result); - } -} - -public class BoolToScalarBoolCall(ShaderExpressionList arguments, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = ScalarType.Boolean; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - - var parameterType = Arguments.Values[0].ValueType.WithElementType(ScalarType.Boolean); - x = builder.Convert(context, x, parameterType); - - var instruction = builder.Insert(new OpAny(context.GetOrRegister(Type), context.Bound++, x.Id)); - instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; - return new(instruction.ResultId, instruction.ResultType); - } -} - -public class FloatBinaryCall(ShaderExpressionList arguments, TextLocation info, Specification.Op op) : MethodCall(new(op.ToString(), info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - var xType = Arguments.Values[0].ValueType; - var yType = Arguments.Values[1].ValueType; - Type = IntrinsicHelper.FindCommonType(ScalarType.Float, xType, yType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var (x, y) = (Arguments.Values[0].CompileAsValue(table, compiler), Arguments.Values[1].CompileAsValue(table, compiler)); - - x = builder.Convert(context, x, Type); - y = builder.Convert(context, y, Type); - - if (context.GLSLSet == null) - context.ImportGLSL(); - var instruction = builder.Insert(new OpFRem(x.TypeId, context.Bound++, x.Id, y.Id)); - // Adjust OpCode only since Pow/Atan2 share the same operands - instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; - return new(instruction.ResultId, instruction.ResultType); - } -} -public class FloatUnaryCall(ShaderExpressionList arguments, TextLocation info, Specification.Op op) : MethodCall(new("fwidth", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType.WithElementType(ScalarType.Float); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - x = builder.Convert(context, x, Type); - - var instruction = builder.Insert(new OpFwidth(x.TypeId, context.Bound++, x.Id)); - instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; - return new(instruction.ResultId, instruction.ResultType); - } -} - -public class BitcastCall(ShaderExpressionList arguments, TextLocation info, ScalarType expectedBaseType) : MethodCall(new("bitcast", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = Arguments.Values[0].ValueType.WithElementType(expectedBaseType); - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var x = Arguments.Values[0].CompileAsValue(table, compiler); - - var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(Type), context.Bound++, x.Id)); - return new(instruction.ResultId, instruction.ResultType); - } -} - -public class MemoryBarrierCall(ShaderExpressionList arguments, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = ScalarType.Void; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); - return new(); - } -} - -public class ControlBarrierCall(ShaderExpressionList arguments, TextLocation info, string name, Specification.MemorySemanticsMask memorySemanticsMask) : MethodCall(new(name, info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - ProcessParameterSymbols(table, null); - Type = ScalarType.Void; - } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); - return new(); - } -} - -public enum InterlockedOp -{ - Add, - And, - Or, - Xor, - Max, - Min, - Exchange, - CompareExchange, - CompareStore, -} - -public class InterlockedCall(ShaderExpressionList arguments, TextLocation info, InterlockedOp op) : MethodCall(new($"Interlocked{op}", info), arguments, info) -{ - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - Type = ScalarType.Void; - } - - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - var dest = Arguments.Values[0].Compile(table, compiler); - if (Arguments.Values[0].Type is not PointerType pointerType || pointerType.BaseType is not ScalarType { Type: Scalar.UInt or Scalar.Int } s) - throw new InvalidOperationException($"l-value int or uint expected but got {Arguments.Values[0].Type}"); - - var resultType = s; - - var value = Arguments.Values[1].CompileAsValue(table, compiler); - value = builder.Convert(context, value, resultType); - - SpirvValue result; - // If there is an out parameter to save original value - int? originalValueIndex; - if (op == InterlockedOp.CompareStore || op == InterlockedOp.CompareExchange) - { - var value2 = Arguments.Values[2].CompileAsValue(table, compiler); - value2 = builder.Convert(context, value2, resultType); - - var instruction = builder.Insert(new OpAtomicCompareExchange(context.GetOrRegister(resultType), context.Bound++, dest.Id, - context.CompileConstant((int)Specification.Scope.Device).Id, - context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, - context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, - value2.Id, - value.Id)); - result = new SpirvValue(instruction.ResultId, instruction.ResultType); - originalValueIndex = op == InterlockedOp.CompareExchange ? 3 : null; - } - else - { - var instruction = builder.Insert(new OpAtomicIAdd(context.GetOrRegister(resultType), context.Bound++, dest.Id, - context.CompileConstant((int)Specification.Scope.Device).Id, - context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, - value.Id)); - // Update instruction type (they all share same memory layout) - instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)(op switch - { - InterlockedOp.Add => Specification.Op.OpAtomicIAdd, - InterlockedOp.And => Specification.Op.OpAtomicAnd, - InterlockedOp.Or => Specification.Op.OpAtomicOr, - InterlockedOp.Xor => Specification.Op.OpAtomicXor, - InterlockedOp.Max => s.IsSigned() ? Specification.Op.OpAtomicSMax : Specification.Op.OpAtomicUMax, - InterlockedOp.Min => s.IsSigned() ? Specification.Op.OpAtomicSMin : Specification.Op.OpAtomicUMin, - InterlockedOp.Exchange => Specification.Op.OpAtomicExchange, - }); - result = new SpirvValue(instruction.ResultId, instruction.ResultType); - originalValueIndex = Arguments.Values.Count == 3 ? 2 : null; - } - - // Out parameter? - if (originalValueIndex is { } originalValueIndex2) - { - var resultLocation = Arguments.Values[originalValueIndex2].Compile(table, compiler); - if (Arguments.Values[originalValueIndex2].Type is not PointerType resultPointerType) - throw new InvalidOperationException($"out parameter is not a l-value, got {Arguments.Values[0].Type} instead"); - - result = builder.Convert(context, result, resultPointerType.BaseType); - builder.Insert(new OpStore(resultLocation.Id, result.Id, null, [])); - } - - return new(); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 58b9d676f3..9c075cbba2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -120,6 +120,33 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; + ProcessInputArguments(table, compiler, functionType, compiledParams, functionSymbol.MethodDefaultParameters); + + int? instance = null; + if (MemberCall != null) + { + instance = MemberCall.Value.Id; + } + else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) + { + instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + } + + if (instance is int instanceId) + // Note: we make a copy to not mutate original + functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; + + var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + + ProcessOutputArguments(table, compiler, functionType, compiledParams); + + return result; + } + + protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams, MethodSymbolDefaultParameters? methodDefaultParameters = null) + { + var (builder, context) = compiler; + if (arguments.Values.Count > functionType.ParameterTypes.Count) throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); @@ -151,21 +178,21 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Find default parameters decoration (if any) var missingParameters = functionType.ParameterTypes.Count - arguments.Values.Count; var defaultParameters = 0; - if (missingParameters > 0 && functionSymbol.MethodDefaultParameters is {} methodDefaultParameters) + if (missingParameters > 0 && methodDefaultParameters is {} methodDefaultParametersValue) { // Is there enough parameters now? - if (missingParameters <= methodDefaultParameters.DefaultValues.Length) + if (missingParameters <= methodDefaultParametersValue.DefaultValues.Length) { // Import missing parameters for (int i = 0; i < missingParameters; ++i) { var paramDefinition = functionType.ParameterTypes[arguments.Values.Count + i]; - var source = methodDefaultParameters.DefaultValues[^(missingParameters - i)]; + var source = methodDefaultParametersValue.DefaultValues[^(missingParameters - i)]; // Import in current buffer - if (methodDefaultParameters.SourceContext != context) + if (methodDefaultParametersValue.SourceContext != context) { - var bufferForConstant = methodDefaultParameters.SourceContext.ExtractConstantAsSpirvBuffer(source); + var bufferForConstant = methodDefaultParametersValue.SourceContext.ExtractConstantAsSpirvBuffer(source); source = context.InsertWithoutDuplicates(null, bufferForConstant); } @@ -181,22 +208,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (missingParameters > 0) throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); - - int? instance = null; - if (MemberCall != null) - { - instance = MemberCall.Value.Id; - } - else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) - { - instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; - } - - if (instance is int instanceId) - // Note: we make a copy to not mutate original - functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; - - var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + } + + protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams) + { + var (builder, context) = compiler; for (int i = 0; i < arguments.Values.Count; i++) { @@ -215,8 +231,32 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) builder.Insert(new OpStore(paramTarget.Id, loadedResult, null, [])); } } + } - return result; + // Note: int.MaxValue means incompatible + public static int OverloadScore(FunctionType functionType, int defaultParameters, ShaderExpressionList arguments) + { + // Check argument count + if (arguments.Values.Count > functionType.ParameterTypes.Count || arguments.Values.Count < functionType.ParameterTypes.Count + defaultParameters) + return int.MaxValue; + + // Check if argument can be converted + var score = 0; + for (var index = 0; index < arguments.Values.Count; index++) + { + var argument = arguments.Values[index]; + var parameter = functionType.ParameterTypes[index]; + var argScore = SpirvBuilder.CanConvertScore(argument.ValueType, parameter.Type.GetValueType()); + if (argScore == int.MaxValue) + return int.MaxValue; + + score += argScore; + } + + // method with fewer optional parameters that need to be filled in by default values is generally preferred + score += functionType.ParameterTypes.Count - arguments.Values.Count; + + return score; } private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymbol) @@ -240,36 +280,9 @@ private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymb // We just care about overload (different signature), not override (base/this/most derived) as this will be resolved in ShaderMixer later if (functionSymbol.Type is FunctionGroupType) { - // Note: int.MaxValue means incompatible - static int OverloadScore(Symbol functionSymbol, ShaderExpressionList arguments) - { - // Check argument count - var functionType = (FunctionType)functionSymbol.Type; - if (arguments.Values.Count > functionType.ParameterTypes.Count || arguments.Values.Count < functionType.ParameterTypes.Count + (functionSymbol.MethodDefaultParameters?.DefaultValues.Length ?? 0)) - return int.MaxValue; - - // Check if argument can be converted - var score = 0; - for (var index = 0; index < arguments.Values.Count; index++) - { - var argument = arguments.Values[index]; - var parameter = functionType.ParameterTypes[index]; - var argScore = SpirvBuilder.CanConvertScore(argument.ValueType, parameter.Type.GetValueType()); - if (argScore == int.MaxValue) - return int.MaxValue; - - score += argScore; - } - - // method with fewer optional parameters that need to be filled in by default values is generally preferred - score += functionType.ParameterTypes.Count - arguments.Values.Count; - - return score; - } - var accessibleMethods = functionSymbol.GroupMembers // Check overload score - .Select(x => (Score: OverloadScore(x, arguments), Symbol: x)) + .Select(x => (Score: OverloadScore((FunctionType)x.Type, x.MethodDefaultParameters?.DefaultValues.Length ?? 0, arguments), Symbol: x)) // Remove non-applicable methods .Where(x => x.Score != int.MaxValue) // Group by signature/score (we assume method with exact same signature means they are overriding each other, but we might need to do a better check using override info) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs new file mode 100644 index 0000000000..879927713d --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs @@ -0,0 +1,145 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using System; + +namespace Stride.Shaders.Parsing.SDSL; + +public class IntrinsicCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : MethodCall(name, arguments, info) +{ + private static IntrinsicTemplateExpander TemplateExpander { get; } = new(); + private IntrinsicTemplateExpander.IntrinsicOverload BestOverload { get; set; } + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + // Process arguments + ProcessParameterSymbols(table); + + var overloads = TemplateExpander.GetOrGenerateIntrinsicsDefinition(Name.Name); + + // Figure out the best overload + BestOverload = default; + var bestOverloadScore = int.MaxValue; + foreach (var overload in overloads) + { + var overloadScore = OverloadScore(overload.Type, 0, Arguments); + if (overloadScore < bestOverloadScore) + { + // Better overload + BestOverload = overload; + bestOverloadScore = overloadScore; + // We won't get better than that (perfect match), stop there + if (overloadScore == 0) + break; + } + } + + if (BestOverload.Type == null) + throw new InvalidOperationException($"No overload found for intrinsic {Name} with arguments {Arguments}"); + + // Now we know the return type + Type = BestOverload.Type.ReturnType; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var functionType = BestOverload.Type; + + Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; + + ProcessInputArguments(table, compiler, functionType, compiledParams); + + // Check if we can automatically handle matrix (SPIR-V doesn't but HLSL does allow matrix on most types) + SpirvValue result; + if (BestOverload.AutoMatrixLoopLocations != null) + { + var (builder, context) = compiler; + + var innerFunctionType = new FunctionType(functionType.ReturnType, functionType.ParameterTypes.ToList()); + + // Extract rows + bool isReturnUsingLoop = false; + Span vectorValues = stackalloc int[BestOverload.AutoMatrixLoopLocations.Count * BestOverload.AutoMatrixLoopSize]; + for (var index = 0; index < BestOverload.AutoMatrixLoopLocations.Count; index++) + { + var location = BestOverload.AutoMatrixLoopLocations[index]; + + if (location.TemplateIndex != 0) + throw new InvalidOperationException("Matrix loop should only be generated for HLSL row parameter"); + + // Skip return type for now + if (location.SourceArgument == 0) + { + var returnType = (MatrixType)functionType.ReturnType; + innerFunctionType = innerFunctionType with + { + ReturnType = new VectorType(returnType.BaseType, returnType.Rows), + }; + isReturnUsingLoop = true; + continue; + } + + var parameterType = (MatrixType)functionType.ParameterTypes[location.SourceArgument - 1].Type; + var vectorType = new VectorType(parameterType.BaseType, parameterType.Rows); + for (int col = 0; col < BestOverload.AutoMatrixLoopSize; col++) + { + vectorValues[index * BestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[location.SourceArgument - 1], [col])).ResultId; + } + + innerFunctionType.ParameterTypes[location.SourceArgument - 1] = innerFunctionType.ParameterTypes[location.SourceArgument - 1] with { Type = vectorType }; + } + + // Call core function + Span results = stackalloc int[BestOverload.AutoMatrixLoopSize]; + for (int col = 0; col < BestOverload.AutoMatrixLoopSize; col++) + { + for (var index = 0; index < BestOverload.AutoMatrixLoopLocations.Count; index++) + { + var location = BestOverload.AutoMatrixLoopLocations[index]; + if (location.SourceArgument == 0) + continue; + compiledParams[location.SourceArgument - 1] = vectorValues[index * BestOverload.AutoMatrixLoopSize + col]; + } + + results[col] = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, Name.Name, innerFunctionType, compiledParams).Id; + } + + // Rebuild return value + if (isReturnUsingLoop) + { + if (Type is not MatrixType) + throw new InvalidOperationException("Return type should be a matrix"); + + result = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(Type), context.Bound++, [..results]))); + } + else + { + result = new(); + } + } + else + { + // No auto matrix loop + result = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, Name.Name, functionType, compiledParams); + } + + ProcessOutputArguments(table, compiler, functionType, compiledParams); + + return result; + } +} + +public enum InterlockedOp +{ + Add, + And, + Or, + Xor, + Max, + Min, + Exchange, + CompareExchange, + CompareStore, +} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs new file mode 100644 index 0000000000..f80296527a --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -0,0 +1,522 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Parsing.SDSL; + +internal class IntrinsicImplementations : IntrinsicsDeclarations +{ + public static IntrinsicImplementations Instance { get; } = new(); + + // Bool + public override SpirvValue CompileAll(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAll); + public override SpirvValue CompileAny(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAny); + + // Cast + public override SpirvValue CompileAsfloat(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue d, SpirvValue x, SpirvValue y) => throw new NotImplementedException(); + public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => throw new NotImplementedException(); + public override SpirvValue CompileAsfloat16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileAsint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileAsuint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + + // Trigo + public override SpirvValue CompileSin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); + public override SpirvValue CompileSinh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); + public override SpirvValue CompileAsin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); + public override SpirvValue CompileCos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + public override SpirvValue CompileCosh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); + public override SpirvValue CompileAcos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); + public override SpirvValue CompileTan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTan, x); + public override SpirvValue CompileTanh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); + public override SpirvValue CompileAtan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); + public override SpirvValue CompileAtan2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); + public override SpirvValue CompileSincos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c) => throw new NotImplementedException(); + + // Derivatives + public override SpirvValue CompileDdx(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdx, x); + public override SpirvValue CompileDdx_coarse(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdxCoarse, x); + public override SpirvValue CompileDdx_fine(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdxFine, x); + public override SpirvValue CompileDdy(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdy, x); + public override SpirvValue CompileDdy_coarse(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdyCoarse, x); + public override SpirvValue CompileDdy_fine(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdyFine, x); + public override SpirvValue CompileFwidth(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpFwidth, x); + + // Per component math + public override SpirvValue CompileAbs(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch + { + ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + ScalarType { Type: Scalar.UInt or Scalar.Int } => builder.InsertData(new GLSLSAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + }; + return new(instruction); + } + public override SpirvValue CompileFloor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFloor, x); + public override SpirvValue CompileCeil(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCeil, x); + public override SpirvValue CompileTrunc(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTrunc, x); + public override SpirvValue CompileMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch + { + ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + }; + return new(instruction); + } + + public override SpirvValue CompileMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch + { + ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + }; + return new(instruction); + } + + public override SpirvValue CompileClamp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue min, SpirvValue max) + { + var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch + { + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), + }; + return new(instruction); + } + + public override SpirvValue CompileRadians(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRadians, x); + public override SpirvValue CompileDegrees(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLDegrees, x); + + public override SpirvValue CompileExp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp, x); + public override SpirvValue CompileExp2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp2, x); + public override SpirvValue CompileLog(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog, x); + public override SpirvValue CompileLog10(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => MultiplyConstant(context, builder, functionType, CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog2, x), (float)Math.Log10(2.0)); + public override SpirvValue CompileLog2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog2, x); + public override SpirvValue CompilePow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLPow, x, y); + + // Vector math + public override SpirvValue CompileDistance(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileDot(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + var instruction = builder.Insert(new OpDot(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileCross(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCross, a, b); + + public override SpirvValue CompileDeterminant(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = builder.Insert(new GLSLDeterminant(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileLength(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileNormalize(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = builder.Insert(new GLSLNormalize(x.TypeId, context.Bound++, context.GetGLSL(), x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileMul(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul + // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns and multiplication order need to be swapped + var result = (context.ReverseTypes[a.TypeId], context.ReverseTypes[b.TypeId]) switch + { + (ScalarType type1, ScalarType type2) => builder.InsertData(new OpFMul(a.TypeId, context.Bound++, a.Id, b.Id)), + (ScalarType type1, VectorType type2) => builder.InsertData(new OpVectorTimesScalar(b.TypeId, context.Bound++, b.Id, a.Id)), + (ScalarType type1, MatrixType type2) => builder.InsertData(new OpMatrixTimesScalar(b.TypeId, context.Bound++, b.Id, a.Id)), + (VectorType type1, ScalarType type2) => builder.InsertData(new OpVectorTimesScalar(a.TypeId, context.Bound++, a.Id, b.Id)), + (VectorType type1, VectorType type2) when type1.Size == type2.Size => builder.InsertData(new OpDot(a.TypeId, context.Bound++, a.Id, b.Id)), + (VectorType type1, MatrixType type2) when type1.Size == type2.Columns => builder.InsertData(new OpMatrixTimesVector(context.GetOrRegister(new VectorType(type1.BaseType, type2.Rows)), context.Bound++, b.Id, a.Id)), + (MatrixType type1, ScalarType type2) => builder.InsertData(new OpMatrixTimesScalar(a.TypeId, context.Bound++, a.Id, b.Id)), + (MatrixType type1, VectorType type2) when type1.Rows == type2.Size => builder.InsertData(new OpVectorTimesMatrix(context.GetOrRegister(new VectorType(type1.BaseType, type1.Columns)), context.Bound++, b.Id, a.Id)), + // This is HLSL-style so Rows/Columns meaning is swapped + //float2x4 = OpTypeMatrix vec4 x2 = MatrixType(Rows: 4, Columns: 2) + //float4x3 = OpTypeMatrix vec3 x4 = MatrixType(Rows: 3, Columns: 4) + //float2x3 = OpTypeMatrix vec3 x2 = MatrixType(Rows: 3, Columns: 2) + // mul(float2x4,float4x3) => float2x3 + (MatrixType type1, MatrixType type2) when type1.Rows == type2.Columns => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type2.Rows, type1.Columns)), context.Bound++, b.Id, a.Id)), + }; + + return new SpirvValue(result); + } + + public override SpirvValue CompileReflect(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n) + { + var instruction = builder.Insert(new GLSLReflect(i.TypeId, context.Bound++, context.GetGLSL(), i.Id, n.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileRefract(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n, SpirvValue ri) + { + var instruction = builder.Insert(new GLSLRefract(i.TypeId, context.Bound++, context.GetGLSL(), i.Id, n.Id, ri.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileFaceforward(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue N, SpirvValue I, SpirvValue Ng) + { + var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GetGLSL(), N.Id, I.Id, Ng.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileRound(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRound, x); + public override SpirvValue CompileRsqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLInverseSqrt, x); + public override SpirvValue CompileSqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSqrt, x); + public override SpirvValue CompileStep(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue x) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLStep, a, x); + public override SpirvValue CompileSaturate(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + // Ensure 0.0 amd 1.0 constants have same type as x + var constant0 = builder.Convert(context, context.CompileConstant(0.0f), functionType.ReturnType); + var constant1 = builder.Convert(context, context.CompileConstant(1.0f), functionType.ReturnType); + + var instruction = functionType.ReturnType.GetElementType() switch + { + ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), + ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), + ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), + }; + return new(instruction); + } + public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = functionType.ReturnType.GetElementType() switch + { + ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.UInt64 or Scalar.Int64 } => builder.InsertData(new GLSLFSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + }; + return new(instruction); + } + + public override SpirvValue CompileSmoothstep(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue x) + { + var instruction = builder.Insert(new GLSLSmoothStep(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileLerp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue s) + { + var instruction = builder.Insert(new GLSLFMix(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, s.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + { + var instruction = builder.Insert(new OpFRem(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileFrac(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFract, x); + + // Compute Barriers + const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; + const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; + const Specification.MemorySemanticsMask GroupMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.AcquireRelease; + public override SpirvValue CompileAllMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileAllMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); + + // Compute interlocked + public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value); + public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value, original); + public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value); + public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value, original); + public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value); + public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value, original); + public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value); + public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value, original); + public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value); + public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value, original); + public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value); + public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value, original); + public override SpirvValue CompileInterlockedExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Exchange, result, value, original); + public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareStore, result, value, null, compare); + public override SpirvValue CompileInterlockedCompareExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareExchange, result, value, original, compare); + public override SpirvValue CompileInterlockedCompareStoreFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileInterlockedCompareExchangeFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => throw new NotImplementedException(); + + public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder builder, FunctionType functionType) + { + builder.Insert(new OpTerminateInvocation()); + return new(); + } + + public override SpirvValue CompileD3DCOLORtoUBYTE4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileGetRenderTargetSampleCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileGetRenderTargetSamplePosition(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s) => throw new NotImplementedException(); + public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileCountbits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeAtSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue index) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeCentroid(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeSnapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset) => throw new NotImplementedException(); + public override SpirvValue CompileGetAttributeAtVertex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue VertexID) => throw new NotImplementedException(); + public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileFirstbithigh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); + public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); + public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileIsinf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileIsnan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileIsnormal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileLdexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); + public override SpirvValue CompileLit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m) => throw new NotImplementedException(); + public override SpirvValue CompileMad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); + public override SpirvValue CompileModf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue ip) => throw new NotImplementedException(); + public override SpirvValue CompileMsad4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue reference, SpirvValue source, SpirvValue accum) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcessIsolineTessFactors(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawDetailFactor, SpirvValue RawDensityFactor, SpirvValue RoundedDetailFactorr, SpirvValue RoundedDensityFactor) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); + public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileReversebits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileSource_mark(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileTranspose(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileCheckAccessFullyMapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue status) => throw new NotImplementedException(); + public override SpirvValue CompileAddUint64(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); + public override SpirvValue CompileNonUniformResourceIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue index) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadLaneAt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue quadLane) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossX(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossY(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossDiagonal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileQuadAny(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); + public override SpirvValue CompileQuadAll(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); + public override SpirvValue CompileGetGroupWaveIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileGetGroupWaveCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileTraceRay(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue AccelerationStructure, SpirvValue RayFlags, SpirvValue InstanceInclusionMask, SpirvValue RayContributionToHitGroupIndex, SpirvValue MultiplierForGeometryContributionToHitGroupIndex, SpirvValue MissShaderIndex, SpirvValue Ray, SpirvValue Payload) => throw new NotImplementedException(); + public override SpirvValue CompileReportHit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue THit, SpirvValue HitKind, SpirvValue Attributes) => throw new NotImplementedException(); + public override SpirvValue CompileCallShader(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue ShaderIndex, SpirvValue Parameter) => throw new NotImplementedException(); + public override SpirvValue CompileIgnoreHit(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileAcceptHitAndEndSearch(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileDispatchRaysIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileDispatchRaysDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWorldRayOrigin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWorldRayDirection(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileObjectRayOrigin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileObjectRayDirection(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileRayTMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileRayTCurrent(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompilePrimitiveIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileInstanceID(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileInstanceIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileGeometryIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileHitKind(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileRayFlags(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld3x4(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject3x4(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + + // Wave + public override SpirvValue CompileWaveIsFirstLane(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWaveGetLaneIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWaveGetLaneCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAnyTrue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAllTrue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAllEqual(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBallot(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); + public override SpirvValue CompileWaveReadLaneAt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue lane) => throw new NotImplementedException(); + public override SpirvValue CompileWaveReadLaneFirst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMatch(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + + // Obsolete + public override SpirvValue CompileDst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); + public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBElod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); + + + public static SpirvValue CompileFloatUnaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.Op op, SpirvValue x) + { + var instruction = builder.Insert(new OpFwidth(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + return new(instruction.ResultId, instruction.ResultType); + } + + public static SpirvValue CompileGLSLFloatUnaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x) + { + var instruction = builder.Insert(new GLSLExp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); + // Adjust OpCode only since Exp/Exp2/Log/Log2 share the same operands + instruction.InstructionMemory.Span[4] = (int)op; + return new SpirvValue(instruction.ResultId, instruction.ResultType); + } + + public static SpirvValue MultiplyConstant(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, float multiplyConstant) + { + var constant = context.CompileConstant(multiplyConstant); + constant = builder.Convert(context, constant, context.ReverseTypes[value.TypeId]); + var instruction2 = builder.Insert(new OpFMul(context.GetOrRegister(functionType.ReturnType), context.Bound++, value.Id, constant.Id)); + return new SpirvValue(instruction2.ResultId, instruction2.ResultType); + } + + public static SpirvValue CompileGLSLFloatBinaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) + { + var instruction = builder.Insert(new GLSLPow(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, y.Id)); + // Adjust OpCode only since Pow/Atan2/etc. share the same operands + instruction.InstructionMemory.Span[4] = (int)op; + return new(instruction.ResultId, instruction.ResultType); + } + + public static SpirvValue CompileBitcastCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + + public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) + { + var destType = context.ReverseTypes[dest.TypeId]; + if (destType is not PointerType pointerType || pointerType.BaseType is not ScalarType { Type: Scalar.UInt or Scalar.Int } s) + throw new InvalidOperationException($"l-value int or uint expected but got {destType}"); + + var resultType = s; + + // If there is an out parameter to save original value + SpirvValue originalValue; + if (op == InterlockedOp.CompareStore || op == InterlockedOp.CompareExchange) + { + var instruction = builder.Insert(new OpAtomicCompareExchange(context.GetOrRegister(resultType), context.Bound++, dest.Id, + context.CompileConstant((int)Specification.Scope.Device).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + compare.Value.Id, + value.Id)); + originalValue = new SpirvValue(instruction.ResultId, instruction.ResultType); + } + else + { + var instruction = builder.Insert(new OpAtomicIAdd(context.GetOrRegister(resultType), context.Bound++, dest.Id, + context.CompileConstant((int)Specification.Scope.Device).Id, + context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, + value.Id)); + // Update instruction type (they all share same memory layout) + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)(op switch + { + InterlockedOp.Add => Specification.Op.OpAtomicIAdd, + InterlockedOp.And => Specification.Op.OpAtomicAnd, + InterlockedOp.Or => Specification.Op.OpAtomicOr, + InterlockedOp.Xor => Specification.Op.OpAtomicXor, + InterlockedOp.Max => s.IsSigned() ? Specification.Op.OpAtomicSMax : Specification.Op.OpAtomicUMax, + InterlockedOp.Min => s.IsSigned() ? Specification.Op.OpAtomicSMin : Specification.Op.OpAtomicUMin, + InterlockedOp.Exchange => Specification.Op.OpAtomicExchange, + }); + originalValue = new SpirvValue(instruction.ResultId, instruction.ResultType); + } + + // Out parameter? + if (originalLocation is {} originalLocationValue) + { + var originalLocationType = context.ReverseTypes[originalLocationValue.TypeId]; + if (originalLocationType is not PointerType originalLocationPointerType) + throw new InvalidOperationException($"out parameter is not a l-value, got {originalLocationType} instead"); + + originalValue = builder.Convert(context, originalValue, originalLocationPointerType.BaseType); + builder.Insert(new OpStore(originalLocationValue.Id, originalValue.Id, null, [])); + } + + return new(); + } + + public static SpirvValue CompileMemoryBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + { + builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); + return new(); + } + public static SpirvValue CompileControlBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + { + builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); + return new(); + } + + public static SpirvValue CompileBoolToScalarBoolCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, Specification.Op op) + { + // We handle matrix specifically in this case (auto loop doesn't work since it's not per item) + // So we simply run OpAny/OpAll on each column and then get a vector with all the bool to run through the normal path + var inputType = context.ReverseTypes[x.TypeId]; + if (inputType is MatrixType m) + { + var vectorType = new VectorType(m.BaseType, m.Rows); + Span vectorBools = stackalloc int[m.Columns]; + for (int i = 0; i < m.Columns; i++) + { + var vector = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, x.Id, [i]))); + vector = builder.Convert(context, vector, vectorType.WithElementType(ScalarType.Boolean)); + var instruction2 = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.Boolean), context.Bound++, vector.Id)); + instruction2.InstructionMemory.Span[0] = (int)(instruction2.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + vectorBools[i] = instruction2.ResultId; + } + + x = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(new VectorType(ScalarType.Boolean, m.Columns)), context.Bound++, [..vectorBools]))); + } + + var parameterType = context.ReverseTypes[x.TypeId].WithElementType(ScalarType.Boolean); + x = builder.Convert(context, x, parameterType); + + var instruction = builder.Insert(new OpAny(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; + return new(instruction.ResultId, instruction.ResultType); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs new file mode 100644 index 0000000000..054c9f1c18 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -0,0 +1,357 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using SymbolType = Stride.Shaders.Core.SymbolType; + +namespace Stride.Shaders.Parsing.SDSL; + +/// +/// Helps expand intrinsics from to multiple . +/// +public class IntrinsicTemplateExpander +{ + record SizePermutationGenerator(string? Name, List Sizes, List<(int SourceArgument, int TemplateIndex)> Locations) + { + public IEnumerable Generate() + { + foreach (var size in Sizes) + yield return new(size, this); + } + + public override string ToString() => $"SizePermutationGenerator(Name={Name}, Sizes={string.Join(", ", Sizes)}, Locations={string.Join(", ", Locations)})"; + } + + record BaseTypePermutationGenerator(SymbolType[] Types, int SourceArgument) + { + public IEnumerable Generate() + { + foreach (var type in Types) + yield return new(type, this); + } + + public override string ToString() => $"BaseTypePermutationGenerator(Types={string.Join(", ", Types)}, SourceArgument={SourceArgument})"; + } + + record SizePermutation(int Size, SizePermutationGenerator Generator); + record BaseTypePermutation(SymbolType Type, BaseTypePermutationGenerator Generator); + + record struct SizeValue(int Value, SizePermutationGenerator Generator); + + public record struct IntrinsicOverload(FunctionType Type, List<(int SourceArgument, int TemplateIndex)>? AutoMatrixLoopLocations, int AutoMatrixLoopSize); + Dictionary> intrinsicDefinitionsCache = new(); + + public List GetOrGenerateIntrinsicsDefinition(string name) + { + lock (intrinsicDefinitionsCache) + { + if (intrinsicDefinitionsCache.TryGetValue(name, out var result)) + return result; + + result = new(); + var intrinsicDefinitions = IntrinsicsDefinitions.Intrinsics[name]; + foreach (var intrinsicDefinition in intrinsicDefinitions) + { + List baseTypePermutationGenerators = new(); + List sizePermutationGenerators = new(); + + void AddVectorSizePermutation(int argument, int templateIndex, string name) + { + SizePermutationGenerator permutation; + + // name can be either a value (1,2,3,4,any) or a name (when multiple slots adjusted with same permutation, in which case value is [1,2,3,4]). + switch (name) + { + case "any" or "1" or "2" or "3" or "4": + permutation = new SizePermutationGenerator(null, name switch + { + "any" => [1,2,3,4], + "1" => [1], + "2" => [2], + "3" => [3], + "4" => [4], + }, new()); + sizePermutationGenerators.Add(permutation); + break; + default: + // use name as key (and find existing one if already declared) + permutation = sizePermutationGenerators.FirstOrDefault(x => x.Name == name); + if (permutation == null) + { + permutation = new SizePermutationGenerator(name, [1,2,3,4], new()); + sizePermutationGenerators.Add(permutation); + } + break; + } + + permutation.Locations.Add((argument, templateIndex)); + } + void AddBaseTypePermutation(int argument, SymbolType[] types) + { + baseTypePermutationGenerators.Add(new BaseTypePermutationGenerator(types, argument)); + } + + // Step 1: Find unconstrained patterns + for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) + { + var parameterType = index > 0 ? intrinsicDefinition.Parameters[index - 1].Type : intrinsicDefinition.Return; + + // Find which part can permutate freely + var isLayoutFree = parameterType.Match == null || parameterType.Match.Value.Layout == index; + var isBaseTypeFree = parameterType.Match == null || parameterType.Match.Value.BaseType == index; + //var isVectorSizeFree = parameterType.Match == null || parameterType.Match.Value.Size == 0; + + if (parameterType.VectorSize is {} vectorSize) + { + // Note: even if size is set using match (isLayoutFree is true), it can still be overriden (value is anything else than "any") so check for it + if (isLayoutFree || vectorSize.X != "any") + { + AddVectorSizePermutation(index, 0, vectorSize.X); + if (vectorSize.Y is { } vectorSizeY) + { + AddVectorSizePermutation(index, 1, vectorSizeY); + } + } + } + + if (isBaseTypeFree) + { + SymbolType[] baseTypes = parameterType.BaseType switch + { + BaseType.Bool => [ ScalarType.Boolean ], + BaseType.Int => [ ScalarType.Int ], + BaseType.Int32Only => [ ScalarType.Int ], + BaseType.Int16 => throw new NotImplementedException(), + BaseType.Int64 => [ ScalarType.Int64 ], + BaseType.SInt16Or32 => [ ScalarType.Int ], + BaseType.AnyInt => [ ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64 ], + BaseType.AnyInt16Or32 => [ ScalarType.Int, ScalarType.UInt ], + BaseType.AnyInt32 => [ ScalarType.Int, ScalarType.UInt ], + BaseType.AnyInt64 => [ ScalarType.Int64, ScalarType.UInt64 ], + BaseType.Int64Only => [ ScalarType.Int64 ], + BaseType.Uint => [ ScalarType.UInt ], + BaseType.Uint16 => throw new NotImplementedException(), + BaseType.U64 => [ ScalarType.UInt64 ], + BaseType.Float => [ ScalarType.Float ], + BaseType.Float16 => throw new NotImplementedException(), + BaseType.AnyFloat => [ ScalarType.Float, ScalarType.Double ], + BaseType.FloatLike => [ ScalarType.Float ], + BaseType.Float32Only => [ ScalarType.Float ], + BaseType.DoubleOnly => [ ScalarType.Double ], + BaseType.Sampler1d => throw new NotImplementedException(), + BaseType.Sampler2d => throw new NotImplementedException(), + BaseType.Sampler3d => throw new NotImplementedException(), + BaseType.SamplerCube => throw new NotImplementedException(), + BaseType.SamplerCmp => [ new SamplerType() ], + BaseType.Sampler => [ new SamplerType() ], + BaseType.AnySampler => [ new SamplerType() ], + BaseType.Wave => throw new NotImplementedException(), + BaseType.Void => [ ScalarType.Void ], + BaseType.Texture2D => throw new NotImplementedException(), + BaseType.UIntOnly => [ ScalarType.UInt, ScalarType.UInt64 ], + BaseType.Numeric => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64 ], + BaseType.Numeric16Only => throw new NotImplementedException(), + BaseType.Numeric32Only => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt ], + BaseType.Any => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean ], + BaseType.Match => throw new InvalidOperationException(), + BaseType.ByteAddressBuffer => throw new NotImplementedException(), + BaseType.RWByteAddressBuffer => throw new NotImplementedException(), + BaseType.VkBufferPointer => throw new NotImplementedException(), + BaseType.Other => throw new NotImplementedException(), + BaseType.Texture2DArray => throw new NotImplementedException(), + _ => throw new ArgumentOutOfRangeException() + }; + AddBaseTypePermutation(index, baseTypes); + } + } + + // Step 2: generate permutations for base types + var baseTypeSequences = new List>(); + foreach (var baseTypePermutationGenerator in baseTypePermutationGenerators) + baseTypeSequences.Add(new(baseTypePermutationGenerator.Generate())); + var baseTypePermutations = CartesianProduct.Generate(baseTypeSequences); + + // Step 3: generate permutations for vector/matrix sizes + var sizeSequences = new List>(); + foreach (var sizePermutationGenerator in sizePermutationGenerators) + sizeSequences.Add(new(sizePermutationGenerator.Generate())); + var sizePermutations = CartesianProduct.Generate(sizeSequences); + + // Step 4: generate signature using permutations + (SymbolType BaseType, SizeValue Size1, SizeValue Size2)[] parameterTypeHelper = new (SymbolType BaseType, SizeValue Size1, SizeValue Size2)[intrinsicDefinition.Parameters.Length + 1]; + SymbolType[] parameterTypes = new SymbolType[intrinsicDefinition.Parameters.Length + 1]; + foreach (var baseTypePermutationList in baseTypePermutations) + { + Array.Clear(parameterTypeHelper); + // Use base type permutations to fill initial types + foreach (var baseTypePermutation in baseTypePermutationList) + parameterTypeHelper[baseTypePermutation.Generator.SourceArgument].BaseType = baseTypePermutation.Type; + + // Set other parameters (which might use initial types) + // Only Match type should be left + for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) + { + var parameterType = index > 0 ? intrinsicDefinition.Parameters[index - 1].Type : intrinsicDefinition.Return; + // Make sure this parameter is not set yet by something else + if (parameterTypeHelper[index].BaseType == null) + { + // Note: we also check match index doesn't point back to us + if (parameterType.Match == null || parameterType.Match.Value.BaseType == index) + throw new InvalidOperationException($"Intrinsic {name}: Can't resolve parameter {index} of type {parameterType}"); + + parameterTypeHelper[index].BaseType = parameterTypeHelper[parameterType.Match.Value.BaseType].BaseType; + } + } + + // Now, iterate on size permutations + bool firstIteration = true; + foreach (var sizePermutationList in sizePermutations) + { + // Reset Sizes + for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) + { + parameterTypeHelper[index].Size1 = default; + parameterTypeHelper[index].Size2 = default; + } + + foreach (var sizePermutation in sizePermutationList) + { + foreach (var location in sizePermutation.Generator.Locations) + { + switch (location.TemplateIndex) + { + case 0: + parameterTypeHelper[location.SourceArgument].Size1 = new(sizePermutation.Size, sizePermutation.Generator); + break; + case 1: + parameterTypeHelper[location.SourceArgument].Size2 = new(sizePermutation.Size, sizePermutation.Generator); + break; + } + } + } + + // Use match() to fill size info + for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) + { + var parameterType = index > 0 ? intrinsicDefinition.Parameters[index - 1].Type : intrinsicDefinition.Return; + // Make sure this parameter is not set yet by something else + if (parameterTypeHelper[index].Size1.Value == 0) + { + if (parameterType.Match != null && parameterType.Match.Value.Layout != index) + { + parameterTypeHelper[index].Size1 = parameterTypeHelper[parameterType.Match.Value.Layout].Size1; + parameterTypeHelper[index].Size2 = parameterTypeHelper[parameterType.Match.Value.Layout].Size2; + + // Also register locations (to easily analyze matrix loops later) + if (firstIteration) + { + parameterTypeHelper[index].Size1.Generator?.Locations.Add(new(index, 0)); + parameterTypeHelper[index].Size2.Generator?.Locations.Add(new(index, 1)); + } + } + } + } + + firstIteration = false; + + List? autoMatrixLoopArguments = null; + SizePermutationGenerator? autoMatrixLoop = null; + FunctionType? autoMatrixLoopType = null; + int autoMatrixLoopSize = 0; + + // Generate real types using sizes + for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) + { + ref var resolvedBaseType = ref parameterTypeHelper[index]; + + if (resolvedBaseType.Size1.Value > 1 && resolvedBaseType.Size2.Value > 1) + { + if (resolvedBaseType.Size1.Generator.Name == null) + { + // If matrix types are generated from a size generator (without a name so that there is no specific row/column pattern like in mul()), + // we can automatically convert a call to multiple calls on each inner vector. + // So we try to remember this info here + if (autoMatrixLoop != null && autoMatrixLoop != resolvedBaseType.Size1.Generator) + throw new InvalidOperationException("Multiple matrix with different generators"); + autoMatrixLoop = resolvedBaseType.Size1.Generator; + autoMatrixLoopSize = resolvedBaseType.Size1.Value; + } + parameterTypes[index] = new MatrixType((ScalarType)resolvedBaseType.BaseType, resolvedBaseType.Size2.Value, resolvedBaseType.Size1.Value); + } + // Note: since in HLSL float4x1 and float1x4 maps to SPIR-V float4, we will have duplicates (but not a big deal) + else if (resolvedBaseType.Size1.Value > 1 || resolvedBaseType.Size2.Value > 1) + { + parameterTypes[index] = new VectorType((ScalarType)resolvedBaseType.BaseType, Math.Max(resolvedBaseType.Size1.Value, resolvedBaseType.Size2.Value)); + } + else + { + parameterTypes[index] = resolvedBaseType.BaseType; + } + } + + // Note: we remove auto matrix loop if result type is not either void or matrix of the desired size + if (autoMatrixLoop != null) + { + if (parameterTypes[0] != ScalarType.Void && (parameterTypes[0] is not MatrixType || parameterTypeHelper[0].Size1.Generator != autoMatrixLoop)) + autoMatrixLoop = null; + } + + var functionParameters = new List(); + for (int i = 0; i < intrinsicDefinition.Parameters.Length; ++i) + { + functionParameters.Add(new(parameterTypes[i + 1], intrinsicDefinition.Parameters[i].Qualifier switch + { + Qualifier.In => ParameterModifiers.In, + Qualifier.Out => ParameterModifiers.Out, + Qualifier.InOut or Qualifier.Ref => ParameterModifiers.InOut, + null => ParameterModifiers.None, + })); + } + var functionType = new FunctionType(parameterTypes[0], functionParameters); + + result.Add(new(functionType, autoMatrixLoop?.Locations, autoMatrixLoopSize)); + } + } + } + + intrinsicDefinitionsCache.Add(name, result); + return result; + } + } + + /// + /// Helper class to generate all permutations using cartesian product. + /// + class CartesianProduct + { + public static List> Generate(List> sequences) + { + var result = new List>(); + if (sequences == null || sequences.Count == 0) + { + return result; + } + + CartesianRecurse(result, new List(), sequences, 0); + return result; + } + + private static void CartesianRecurse(List> accumulator, List currentCombination, List> sequences, int sequenceIndex) + { + // Base case: If we have processed all sequences, add the current combination to the result + if (sequenceIndex == sequences.Count) + { + accumulator.Add(new List(currentCombination)); + return; + } + + // Recursive step: Iterate through the current sequence + foreach (T item in sequences[sequenceIndex]) + { + currentCombination.Add(item); + // Recurse to the next sequence + CartesianRecurse(accumulator, currentCombination, sequences, sequenceIndex + 1); + // Backtrack: Remove the last added item to explore the next item in the current sequence + currentCombination.RemoveAt(currentCombination.Count - 1); + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index ec43f8fdd8..ca613aa0f1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -174,7 +174,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) (var compositeCount, var totalCount, var expectedElementType) = Type switch { VectorType v => (v.Size, v.Size, v.BaseType), - MatrixType m => (m.Rows, m.Columns * m.Rows, m.BaseType), + MatrixType m => (m.Columns, m.Columns * m.Rows, m.BaseType), ArrayType t => (t.Size, t.Size, t.BaseType), }; @@ -199,7 +199,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { SpirvValue extractedValue = valueType switch { - MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j / m.Rows, j % m.Rows]))), + MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j / m.Columns, j % m.Rows]))), VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j]))), ScalarType s => value, }; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index e52c1fc80d..88c2d7b46c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -53,207 +53,14 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char(')', ref scanner, advance: true)) { - // TODO: handle matrices (most of those OPs support only vectors) - const Specification.MemorySemanticsMask allMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; - const Specification.MemorySemanticsMask deviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; - const Specification.MemorySemanticsMask groupMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.AcquireRelease; - parsed = (identifier.Name, parameters.Values.Count) switch + if (IntrinsicsDefinitions.Intrinsics.TryGetValue(identifier.Name, out var intrinsicDefinitions)) { - // Bool - ("all", _) => new BoolToScalarBoolCall(parameters, scanner[position..scanner.Position], Specification.Op.OpAll), - ("any", _) => new BoolToScalarBoolCall(parameters, scanner[position..scanner.Position], Specification.Op.OpAny), - - // Cast - ("asdouble", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Double), - ("asfloat", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Float), - ("asint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.Int), - ("asuint", _) => new BitcastCall(parameters, scanner[position..scanner.Position], ScalarType.UInt), - - // Trigo - ("sin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSin), - ("sinh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSinh), - ("asin", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAsin), - ("cos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCos), - ("cosh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCosh), - ("acos", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAcos), - ("atan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan), - ("atan2", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLAtan2), - ("tan", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTan), - ("tanh", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTanh), - ("sincos", _) => throw new NotImplementedException(), - - // Derivatives - ("ddx", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdx), - ("ddx_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxCoarse), - ("ddx_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdxFine), - ("ddy", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdy), - ("ddy_coarse", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyCoarse), - ("ddy_fine", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpDPdyFine), - ("fwidth", _) => new FloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFwidth), - - // Per component math - ("abs", 1) => new AbsCall(parameters, scanner[position..scanner.Position]), - ("floor", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFloor), - ("ceil", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCeil), - ("trunc", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLTrunc), - ("clamp", _) => new ClampCall(parameters, scanner[position..scanner.Position]), - ("max", _) => new MaxCall(parameters, scanner[position..scanner.Position]), - ("min", _) => new MinCall(parameters, scanner[position..scanner.Position]), - - ("degrees", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLDegrees), - ("radians", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRadians), - - ("exp", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp), - ("exp2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLExp2), - ("log", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog), - ("log10", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2, (float)Math.Log10(2.0)), - ("log2", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLLog2), - ("pow", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLPow), - - ("round", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLRoundEven), - ("rsqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLInverseSqrt), - ("saturate", 1) => new SaturateCall(parameters, scanner[position..scanner.Position]), - ("sign", 1) => new SignCall(parameters, scanner[position..scanner.Position]), - ("smoothstep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), - ("lerp", _) => new LerpCall(parameters, scanner[position..scanner.Position]), - ("sqrt", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLSqrt), - ("step", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLStep), - ("frac", 1) => new GLSLFloatUnaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLFract), - ("fmod", 2) => new FloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.Op.OpFRem), - - // Vector math - ("dot", _) => new DotCall(parameters, scanner[position..scanner.Position]), - ("determinant", 1) => new DeterminantCall(parameters, scanner[position..scanner.Position]), - ("cross", 2) => new GLSLFloatBinaryCall(parameters, scanner[position..scanner.Position], Specification.GLSLOp.GLSLCross), - ("distance", _) => new DistanceCall(parameters, scanner[position..scanner.Position]), - ("length", 1) => new LengthCall(parameters, scanner[position..scanner.Position]), - ("normalize", _) => new NormalizeCall(parameters, scanner[position..scanner.Position]), - ("mul", 2) => new MulCall(parameters, scanner[position..scanner.Position]), - - ("reflect", 2) => new ReflectCall(parameters, scanner[position..scanner.Position]), - ("refract", 3) => new RefractCall(parameters, scanner[position..scanner.Position]), - ("faceforward", _) => new FaceForwardCall(parameters, scanner[position..scanner.Position]), - - // Compute Barriers - ("AllMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, allMemoryBarrierMemorySemanticsMask), - ("AllMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, allMemoryBarrierMemorySemanticsMask), - ("DeviceMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, deviceMemoryBarrierMemorySemanticsMask), - ("DeviceMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, deviceMemoryBarrierMemorySemanticsMask), - ("GroupMemoryBarrier", _) => new MemoryBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, groupMemoryBarrierMemorySemanticsMask), - ("GroupMemoryBarrierWithGroupSync", _) => new ControlBarrierCall(parameters, scanner[position..scanner.Position], identifier.Name, groupMemoryBarrierMemorySemanticsMask), - - // Compute interlocked - ("InterlockedAdd", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Add), - ("InterlockedAnd", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.And), - ("InterlockedOr", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Or), - ("InterlockedXor", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Xor), - ("InterlockedMax", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Max), - ("InterlockedMin", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Min), - ("InterlockedExchange", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.Exchange), - ("InterlockedCompareExchange", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.CompareExchange), - ("InterlockedCompareStore", _) => new InterlockedCall(parameters, scanner[position..scanner.Position], InterlockedOp.CompareStore), - - ("abort", _) => throw new NotImplementedException(), - ("CheckAccessFullyMapped", _) => throw new NotImplementedException(), - ("clip", _) => throw new NotImplementedException(), - ("countbits", _) => throw new NotImplementedException(), - ("D3DCOLORtoUBYTE4", _) => throw new NotImplementedException(), - ("errorf", _) => throw new NotImplementedException(), - ("EvaluateAttributeCentroid", _) => throw new NotImplementedException(), - ("EvaluateAttributeAtSample", _) => throw new NotImplementedException(), - ("EvaluateAttributeSnapped", _) => throw new NotImplementedException(), - ("f16to32", _) => throw new NotImplementedException(), - ("f32to16", _) => throw new NotImplementedException(), - ("firstbithigh", _) => throw new NotImplementedException(), - ("firstbitlow", _) => throw new NotImplementedException(), - ("fma", _) => throw new NotImplementedException(), - ("frexp", _) => throw new NotImplementedException(), - ("GetRenderTargetSampleCount", _) => throw new NotImplementedException(), - ("GetRenderTargetSamplePosition", _) => throw new NotImplementedException(), - ("isfinite", _) => throw new NotImplementedException(), - ("isinf", _) => throw new NotImplementedException(), - ("isnan", _) => throw new NotImplementedException(), - ("ldexp", _) => throw new NotImplementedException(), - ("lit", _) => throw new NotImplementedException(), - ("mad", _) => throw new NotImplementedException(), - ("modf", _) => throw new NotImplementedException(), - ("msad4", _) => throw new NotImplementedException(), - ("noise", _) => throw new NotImplementedException(), - ("printf", _) => throw new NotImplementedException(), - ("Process2DQuadTessFactorsAvg", _) => throw new NotImplementedException(), - ("Process2DQuadTessFactorsMax", _) => throw new NotImplementedException(), - ("Process2DQuadTessFactorsMin", _) => throw new NotImplementedException(), - ("ProcessIsolineTessFactors", _) => throw new NotImplementedException(), - ("ProcessQuadTessFactorsAvg", _) => throw new NotImplementedException(), - ("ProcessQuadTessFactorsMax", _) => throw new NotImplementedException(), - ("ProcessQuadTessFactorsMin", _) => throw new NotImplementedException(), - ("ProcessTriTessFactorsAvg", _) => throw new NotImplementedException(), - ("ProcessTriTessFactorsMax", _) => throw new NotImplementedException(), - ("ProcessTriTessFactorsMin", _) => throw new NotImplementedException(), - ("rcp", _) => throw new NotImplementedException(), - ("reversebits", _) => throw new NotImplementedException(), - ("transpose", _) => throw new NotImplementedException(), - - // Obsolete - ("dst", _) => throw new NotImplementedException(), - ("tex1D" or "tex1Dbias" or "tex1Dgrad" or "tex1Dlod" or "tex1Dproj", _) => throw new NotImplementedException(), - ("tex2D" or "tex2Dbias" or "tex2Dgrad" or "tex2Dlod" or "tex2Dproj", _) => throw new NotImplementedException(), - ("tex3D" or "tex3Dbias" or "tex3Dgrad" or "tex3Dlod" or "tex3Dproj", _) => throw new NotImplementedException(), - ("texCUBE" or "texCUBEbias" or "texCUBEgrad" or "texCUBElod" or "texCUBEproj", _) => throw new NotImplementedException(), - - _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]), - }; - /*parsed = (identifier.Name, parameters.Values.Count) switch + parsed = new IntrinsicCall(identifier, parameters, scanner[position..scanner.Position]); + } + else { - ("Fract", 1) => new FractCall(parameters, scanner[position..scanner.Position]), - ("Asinh", 1) => new AsinhCall(parameters, scanner[position..scanner.Position]), - ("Acosh", 1) => new AcoshCall(parameters, scanner[position..scanner.Position]), - ("Atanh", 1) => new AtanhCall(parameters, scanner[position..scanner.Position]), - ("MatrixInverse", 1) => new MatrixInverseCall(parameters, scanner[position..scanner.Position]), - ("Modf", 2) => new ModfCall(parameters, scanner[position..scanner.Position]), - ("ModfStruct", 1) => new ModfStructCall(parameters, scanner[position..scanner.Position]), - ("FMin", 2) => new FMinCall(parameters, scanner[position..scanner.Position]), - ("UMin", 2) => new UMinCall(parameters, scanner[position..scanner.Position]), - ("SMin", 2) => new SMinCall(parameters, scanner[position..scanner.Position]), - ("FMax", 2) => new FMaxCall(parameters, scanner[position..scanner.Position]), - ("UMax", 2) => new UMaxCall(parameters, scanner[position..scanner.Position]), - ("SMax", 2) => new SMaxCall(parameters, scanner[position..scanner.Position]), - ("FClamp", 3) => new FClampCall(parameters, scanner[position..scanner.Position]), - ("UClamp", 3) => new UClampCall(parameters, scanner[position..scanner.Position]), - ("SClamp", 3) => new SClampCall(parameters, scanner[position..scanner.Position]), - ("FMix", 3) => new FMixCall(parameters, scanner[position..scanner.Position]), - ("IMix", 3) => new IMixCall(parameters, scanner[position..scanner.Position]), - ("SmoothStep", 3) => new SmoothStepCall(parameters, scanner[position..scanner.Position]), - ("Fma", 3) => new FmaCall(parameters, scanner[position..scanner.Position]), - ("Frexp", 2) => new FrexpCall(parameters, scanner[position..scanner.Position]), - ("FrexpStruct", 1) => new FrexpStructCall(parameters, scanner[position..scanner.Position]), - ("Ldexp", 2) => new LdexpCall(parameters, scanner[position..scanner.Position]), - ("PackSnorm4x8", 1) => new PackSnorm4x8Call(parameters, scanner[position..scanner.Position]), - ("PackUnorm4x8", 1) => new PackUnorm4x8Call(parameters, scanner[position..scanner.Position]), - ("PackSnorm2x16", 1) => new PackSnorm2x16Call(parameters, scanner[position..scanner.Position]), - ("PackUnorm2x16", 1) => new PackUnorm2x16Call(parameters, scanner[position..scanner.Position]), - ("PackHalf2x16", 1) => new PackHalf2x16Call(parameters, scanner[position..scanner.Position]), - ("PackDouble2x32", 1) => new PackDouble2x32Call(parameters, scanner[position..scanner.Position]), - ("UnpackSnorm2x16", 1) => new UnpackSnorm2x16Call(parameters, scanner[position..scanner.Position]), - ("UnpackUnorm2x16", 1) => new UnpackUnorm2x16Call(parameters, scanner[position..scanner.Position]), - ("UnpackHalf2x16", 1) => new UnpackHalf2x16Call(parameters, scanner[position..scanner.Position]), - ("UnpackSnorm4x8", 1) => new UnpackSnorm4x8Call(parameters, scanner[position..scanner.Position]), - ("UnpackUnorm4x8", 1) => new UnpackUnorm4x8Call(parameters, scanner[position..scanner.Position]), - ("UnpackDouble2x32", 1) => new UnpackDouble2x32Call(parameters, scanner[position..scanner.Position]), - ("Distance", 2) => new DistanceCall(parameters, scanner[position..scanner.Position]), - ("Normalize", 1) => new NormalizeCall(parameters, scanner[position..scanner.Position]), - ("FaceForward", 3) => new FaceForwardCall(parameters, scanner[position..scanner.Position]), - ("FindILsb", 1) => new FindILsbCall(parameters, scanner[position..scanner.Position]), - ("FindSMsb", 1) => new FindSMsbCall(parameters, scanner[position..scanner.Position]), - ("FindUMsb", 1) => new FindUMsbCall(parameters, scanner[position..scanner.Position]), - ("InterpolateAtCentroid", 2) => new InterpolateAtCentroidCall(parameters, scanner[position..scanner.Position]), - ("InterpolateAtSample", 2) => new InterpolateAtSampleCall(parameters, scanner[position..scanner.Position]), - ("InterpolateAtOffset", 2) => new InterpolateAtOffsetCall(parameters, scanner[position..scanner.Position]), - ("NMin", 2) => new NMinCall(parameters, scanner[position..scanner.Position]), - ("NMax", 2) => new NMaxCall(parameters, scanner[position..scanner.Position]), - ("NClamp", 3) => new NClampCall(parameters, scanner[position..scanner.Position]), - _ => new MethodCall(identifier, parameters, scanner[position..scanner.Position]) - };*/ + parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); + } return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs index ec9b191092..57964b5a00 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs @@ -362,22 +362,32 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) var conversionScore = (valueType, castType) switch { + // Same size + (ScalarType, ScalarType) => 0, + (VectorType v1, VectorType v2) when v1.Size == v2.Size => 0, + (MatrixType m1, MatrixType m2) when m1.Rows == m2.Rows && m1.Columns == m2.Columns => 0, + // Promotion scalar to scalar, vector or matrix (replicate value) - (ScalarType, ScalarType or VectorType or MatrixType) => 1, + (ScalarType, VectorType or MatrixType) => 1, + // Truncation - (VectorType or MatrixType, ScalarType) => 1, - // Vector cast - (VectorType v1, VectorType v2) when v1.Size == v2.Size => 1, - (VectorType v1, VectorType v2) when v1.Size < v2.Size => int.MaxValue, // Emit warning? (warning: implicit truncation of vector type) - (VectorType v1, VectorType v2) when v1.Size > v2.Size => 1, - (VectorType v1, MatrixType m2) when v1.Size != m2.Rows * m2.Columns => int.MaxValue, + (VectorType or MatrixType, ScalarType) => 13, + (VectorType v1, VectorType v2) when v1.Size > v2.Size => 13, + (MatrixType m1, MatrixType m2) when m1.Rows > m2.Rows && m1.Columns > m2.Columns => 13, + + // Note: conversions such as float2x2<=>float4 are allowed but not implemented in Convert() + (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, (VectorType v1, MatrixType m2) when v1.Size == m2.Rows * m2.Columns => 1, + + // vector<=>matrix but size doesn't match (impossible) + (VectorType v1, MatrixType m2) when v1.Size != m2.Rows * m2.Columns => int.MaxValue, (MatrixType m1, VectorType v2) when v2.Size != m1.Rows * m1.Columns => int.MaxValue, - // Note: conversions such as float2x2=>float4 are allowed but not implemented in Convert() - (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, + + // Expansion not from scalar (impossible) + (VectorType v1, VectorType v2) when v1.Size < v2.Size => int.MaxValue, (MatrixType m1, MatrixType m2) when m1.Rows < m2.Rows || m1.Columns < m2.Columns => int.MaxValue, - (MatrixType m1, MatrixType m2) when m1.Rows >= m2.Rows && m1.Columns >= m2.Columns => 1, + _ => int.MaxValue }; @@ -557,8 +567,8 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy valueType = v2; break; case (ScalarType, MatrixType m2): - result = Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m2.BaseType, m2.Columns)), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Columns).ToArray()))); - result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Rows).ToArray()))); + result = Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m2.BaseType, m2.Rows)), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Rows).ToArray()))); + result = Insert(new OpCompositeConstruct(context.GetOrRegister(m2), context.Bound++, new LiteralArray(Enumerable.Repeat(result, m2.Columns).ToArray()))); valueType = m2; break; case (VectorType, MatrixType m2): diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index 9575743298..fb5c8ac3e3 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -130,6 +130,14 @@ public void ImportGLSL() GLSLSet = Bound - 1; } + public int GetGLSL() + { + if (GLSLSet == null) + ImportGLSL(); + + return GLSLSet.Value; + } + /// /// Add a new name to a target ID. It should not have been set before. /// From 9b59223ce822cffe6185b7844980481c0f48bcb2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 5 Feb 2026 17:46:02 +0900 Subject: [PATCH 0784/1182] Auto-detect optional parameters --- .../IntrinsicGenerator.cs | 78 +++++++++++++----- .../Intrinsics/Parser.cs | 3 +- src/Stride.Shaders.Generators/Trie.cs | 79 +++++++++++++++++++ .../Parsing/SDSL/AST/IntrinsicCall.cs | 2 +- .../SDSL/AST/IntrinsicImplementations.cs | 30 +++---- .../SDSL/AST/IntrinsicTemplateExpander.cs | 5 +- .../AST/TextureIntrinsicImplementations.cs | 11 +++ 7 files changed, 166 insertions(+), 42 deletions(-) create mode 100644 src/Stride.Shaders.Generators/Trie.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index e7c7a81fcb..a2354cd81f 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -42,7 +42,7 @@ namespace Stride.Shaders.Core; public static partial class IntrinsicsDefinitions { """); - + if (namespaces.Items.Count == 0) builder.AppendLine("// No intrinsics parsed"); @@ -50,10 +50,10 @@ public static partial class IntrinsicsDefinitions { builder.AppendLine($"public static FrozenDictionary {ns.Name.Name} {{ get; }} = new Dictionary()") .AppendLine("{"); - foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) + foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not "printf")) { builder.AppendLine($"[\"{intrinsicGroup.Key}\"] = ["); - foreach (var overload in intrinsicGroup.Where(i => i is not null)) + foreach (var overload in intrinsicGroup) { builder.Append("new("); // Return type @@ -74,8 +74,7 @@ public static partial class IntrinsicsDefinitions // Parameters builder.AppendLine("["); - if(overload is not null && overload.Parameters.Items is not null) - foreach (var param in overload.Parameters.Items.Where(p => p is not null && p.Name.Name != "...")) + foreach (var param in overload.Parameters.Items.Where(p => p.Name.Name != "...")) { builder.Append("new("); // Qualifier @@ -121,17 +120,23 @@ public static partial class IntrinsicsDefinitions ); } - static string GenerateParameters(List parameters) + static string GenerateParameters(List parameters, bool optional = false) { - return string.Concat(parameters.Where(x => x is not null).Select(p => $", SpirvValue {p.Name.Name}")); + return string.Concat(parameters.Where(p => p.Name.Name != "...").Select(p => optional ? $", SpirvValue? {p.Name.Name} = null" : $", SpirvValue {p.Name.Name}")); } static string GenerateArguments(List parameters) { - return string.Concat(parameters.Where(x => x is not null).Select((p, i) => $", new SpirvValue(compiledParams[{i}], context.GetOrRegister(functionType.ParameterTypes[{i}].Type))")); + return string.Concat(parameters.Where(p => p.Name.Name != "...").Select((p, i) => $", new SpirvValue(compiledParams[{i}], context.GetOrRegister(functionType.ParameterTypes[{i}].Type))")); } static string CapitalizeFirstLetter(string s) => char.ToUpper(s[0]) + s[1..]; + + // Group of intrinsics with same parameter names (parameter types might differ) + record IntrinsicOverloadGroup(string Name, List Parameters, List Overloads) + { + public TrieNode TrieNode { get; set; } + } static void GenerateIntrinsicsCall(SourceProductionContext spc, EquatableList namespaces) { @@ -147,35 +152,72 @@ namespace Stride.Shaders.Parsing.SDSL; """); - foreach (var ns in namespaces.Items.Where(x => x.Name.Name == "Intrinsics")) + foreach (var ns in namespaces.Items) { + var intrinsicGroups = new Dictionary>(); + + foreach (var intrinsicGroup in ns.Intrinsics.Items + .Where(x => x.Parameters.Items.All(p => p.Name.Name != "...")) + .GroupBy(i => i.Name.Name)) + { + var trie = new Trie(); + foreach (var overload in intrinsicGroup.GroupBy(x => GenerateParameters(x.Parameters.Items))) + { + var parameters = overload.First().Parameters.Items.Where(p => p.Name.Name != "...").ToList(); + var intrinsicOverloadGroup = new IntrinsicOverloadGroup(intrinsicGroup.Key, parameters, overload.ToList()); + intrinsicOverloadGroup.TrieNode = trie.Insert(parameters.Select(p => p.Name.Name).ToList(), intrinsicOverloadGroup); + } + + // Try to attach method definition to a parent definition with optional parameter (only if one option) + // i.e. (a,b) and (a,b,c) will be grouped into (a,b,c?) + // however (a,b) (a,b,c) and (a,b,d) won't be merged as (a,b) has two possible optional parameter branches + + // To do that, we will simplify node with only a single leaves + trie.SimplifySingleLeaves(); + + intrinsicGroups.Add(intrinsicGroup.Key, trie); + } + + builder.AppendLine($"public abstract class {ns.Name.Name}Declarations"); builder.AppendLine("{"); - foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) + + foreach (var intrinsicGroup in intrinsicGroups) { - foreach (var overload in intrinsicGroup.Where(i => i is not null).GroupBy(x => GenerateParameters(x.Parameters.Items))) + foreach (var intrinsicOverloadGroup in intrinsicGroup.Value.EnumerateNodes()) { - builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{overload.Key}) => throw new NotImplementedException();"); + if (intrinsicOverloadGroup.Values.Count == 0) + continue; + + // Get parameters of first and last overload (the ones with the less and most parameters) + var mandatoryParameters1 = intrinsicOverloadGroup.Values.First().Parameters; + var mandatoryParameters2 = intrinsicOverloadGroup.Values.Last().Parameters; + var optionalParameters = mandatoryParameters2.GetRange(mandatoryParameters1.Count, mandatoryParameters2.Count - mandatoryParameters1.Count); + builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{GenerateParameters(mandatoryParameters1)}{GenerateParameters(optionalParameters, true)}) => throw new NotImplementedException();"); } } - + builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string name, FunctionType functionType, Span compiledParams) {"); builder.AppendLine("var (builder, context) = compiler;"); builder.AppendLine("return (name, compiledParams.Length) switch {"); - foreach (var intrinsicGroup in ns.Intrinsics.Items.GroupBy(i => i.Name.Name).Where(x => x.Key is not null && x.Key is not "printf")) + foreach (var intrinsicGroup in intrinsicGroups) { - foreach (var overload in intrinsicGroup.Where(i => i is not null).GroupBy(x => GenerateParameters(x.Parameters.Items))) + foreach (var intrinsicOverloadGroup in intrinsicGroup.Value.EnumerateNodes()) { - builder.AppendLine($"(\"{intrinsicGroup.Key}\", {overload.First().Parameters.Items.Count}) => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{GenerateArguments(overload.First().Parameters.Items)}),"); + foreach (var overload in intrinsicOverloadGroup.Values) + { + builder.AppendLine($"(\"{overload.Name}\", {overload.Parameters.Count}) => Compile{CapitalizeFirstLetter(overload.Name)}(context, builder, functionType{GenerateArguments(overload.Parameters)}),"); + } } } + builder.AppendLine("};"); builder.AppendLine("}"); + builder.AppendLine("}"); } - builder.AppendLine("}"); spc.AddSource( - "IntrinsicsCall.g.cs", + "IntrinsicsDeclarations.g.cs", SourceText.From( SyntaxFactory.ParseCompilationUnit(builder.ToString()) .NormalizeWhitespace() diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs index cd5c4643e6..cd321683d7 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/Parser.cs @@ -405,7 +405,8 @@ internal static bool IntrinsicDeclaration(this ref Scanner scanner, out Intrinsi scanner.MatchWhiteSpace(advance: true); scanner.IntrinsicParameter(out var parameter); scanner.MatchWhiteSpace(advance: true); - intrinsic.Parameters.Items.Add(parameter); + if (parameter != null) + intrinsic.Parameters.Items.Add(parameter); } while (!scanner.EOF && scanner.Match(",", true)); if (scanner.EOF || !scanner.Match(")", true)) diff --git a/src/Stride.Shaders.Generators/Trie.cs b/src/Stride.Shaders.Generators/Trie.cs new file mode 100644 index 0000000000..fbc9ba72cb --- /dev/null +++ b/src/Stride.Shaders.Generators/Trie.cs @@ -0,0 +1,79 @@ +using System.Reflection.Metadata; + +namespace Stride.Shaders.Generators; + +public class TrieNode +{ + public TrieNode() { } + public TrieNode(TrieNode parent, string name) + { + Parent = parent; + } + + public TrieNode? Parent { get; init; } + + // Dictionary to hold children, keyed by character + public Dictionary> Children { get; } = new(); + + // Optional: Store a value at this node + public List Values { get; } = new(); +} + +public class Trie where TValue : class +{ + private readonly TrieNode root = new(); + + public TrieNode Insert(List keys, TValue value) + { + var node = root; + foreach (string s in keys) + { + if (!node.Children.ContainsKey(s)) + node.Children[s] = new TrieNode(node, s); + node = node.Children[s]; + } + + node.Values.Add(value); + return node; + } + + public void SimplifySingleLeaves() => SimplifySingleLeaves(root); + + public IEnumerable> EnumerateNodes() => EnumerateNodes(root); + + // Try to attach method definition to a parent definition with optional parameter (only if one option) + // i.e. (a,b) and (a,b,c) will be grouped into (a,b,c?) + // however (a,b) (a,b,c) and (a,b,d) won't be merged as (a,b) has two possible optional parameter branches + private void SimplifySingleLeaves(TrieNode node) + { + // First we recurse + foreach (var child in node.Children.Values) + { + SimplifySingleLeaves(child); + } + + // Check if we can merge node with its child + if (node.Children.Count == 1 && node.Children.First().Value.Children.Count == 0) + { + var child = node.Children.First().Value; + node.Children.Clear(); + // Take over child values + node.Values.AddRange(child.Values); + } + } + + private IEnumerable> EnumerateNodes(TrieNode node) + { + // Return the current node itself + yield return node; + + // Recursively return all nodes in the child subtrees + foreach (var child in node.Children) + { + foreach (var node2 in EnumerateNodes(child.Value)) + { + yield return node2; + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs index 879927713d..ac11d996f0 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Parsing.SDSL; public class IntrinsicCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : MethodCall(name, arguments, info) { - private static IntrinsicTemplateExpander TemplateExpander { get; } = new(); + private static IntrinsicTemplateExpander TemplateExpander { get; } = new(IntrinsicsDefinitions.Intrinsics); private IntrinsicTemplateExpander.IntrinsicOverload BestOverload { get; set; } public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs index f80296527a..77e57b92f2 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -233,18 +233,12 @@ public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builde public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); // Compute interlocked - public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value); - public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value, original); - public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value); - public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value, original); - public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value); - public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value, original); - public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value); - public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value, original); - public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value); - public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value, original); - public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value); - public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value, original); + public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value, original); + public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value, original); + public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value, original); + public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value, original); + public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value, original); + public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value, original); public override SpirvValue CompileInterlockedExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Exchange, result, value, original); public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareStore, result, value, null, compare); public override SpirvValue CompileInterlockedCompareExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareExchange, result, value, original, compare); @@ -363,26 +357,22 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build // Obsolete public override SpirvValue CompileDst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); - public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex1Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex1Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex1Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex1Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex2Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex2Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex2Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex2Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex3Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex3Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); public override SpirvValue CompileTex3Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTex3Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); public override SpirvValue CompileTexCUBEbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileTexCUBEgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); public override SpirvValue CompileTexCUBElod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index 054c9f1c18..cfea0f9b06 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -1,3 +1,4 @@ +using System.Collections.Frozen; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using SymbolType = Stride.Shaders.Core.SymbolType; @@ -7,7 +8,7 @@ namespace Stride.Shaders.Parsing.SDSL; /// /// Helps expand intrinsics from to multiple . /// -public class IntrinsicTemplateExpander +public class IntrinsicTemplateExpander(FrozenDictionary intrinsicsDefinitions) { record SizePermutationGenerator(string? Name, List Sizes, List<(int SourceArgument, int TemplateIndex)> Locations) { @@ -47,7 +48,7 @@ public List GetOrGenerateIntrinsicsDefinition(string name) return result; result = new(); - var intrinsicDefinitions = IntrinsicsDefinitions.Intrinsics[name]; + var intrinsicDefinitions = intrinsicsDefinitions[name]; foreach (var intrinsicDefinition in intrinsicDefinitions) { List baseTypePermutationGenerators = new(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs new file mode 100644 index 0000000000..321b24a69b --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs @@ -0,0 +1,11 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Parsing.SDSL; + +internal class Texture2DIntrinsicImplementations : Texture2DMethodsDeclarations +{ + +} \ No newline at end of file From e3701d60c7b2aa0869aa3fd1aca17d1b548930b6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 5 Feb 2026 18:25:57 +0900 Subject: [PATCH 0785/1182] Unified IntrinsicCall into MethodCall --- src/Stride.Shaders.Experiments/Program.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 61 ++++++++++------ .../Parsing/SDSL/AST/IntrinsicCall.cs | 70 +++++++++---------- .../SDSL/AST/IntrinsicTemplateExpander.cs | 16 +++-- .../AST/TextureIntrinsicImplementations.cs | 7 +- .../PrimaryExpressionParsers.cs | 9 +-- 6 files changed, 91 insertions(+), 74 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Program.cs b/src/Stride.Shaders.Experiments/Program.cs index 20b803203f..ce6f8b0d9c 100644 --- a/src/Stride.Shaders.Experiments/Program.cs +++ b/src/Stride.Shaders.Experiments/Program.cs @@ -33,7 +33,7 @@ { try { - var test = new IntrinsicCall(new(i.Key, default), new ShaderExpressionList(default), default); + var test = new MethodCall(new(i.Key, default), new ShaderExpressionList(default), default); test.ProcessSymbol(table); } catch (Exception e) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 9c075cbba2..9b4bf59350 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -86,15 +86,27 @@ public class MethodCall(Identifier name, ShaderExpressionList arguments, TextLoc public SpirvValue? MemberCall { get; set; } public Symbol ResolvedFunctionSymbol { get; set; } + + private IntrinsicTemplateExpander.IntrinsicOverload? resolvedIntrinsicOverload; public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { ProcessParameterSymbols(table); - if (!TryResolveFunctionSymbol(table, out var functionSymbol)) - return; - var functionType = (FunctionType)functionSymbol.Type; - Type = functionType.ReturnType; + if (TryResolveFunctionSymbol(table, out var functionSymbol)) + { + var functionType = (FunctionType)functionSymbol.Type; + Type = functionType.ReturnType; + } + else if (IntrinsicCallHelper.TryResolveIntrinsic(table, name, arguments, out var resolvedIntrinsicOverloadValue)) + { + resolvedIntrinsicOverload = resolvedIntrinsicOverloadValue; + Type = resolvedIntrinsicOverload.Value.Type.ReturnType; + } + else + { + table.AddError(new(info, $"Can't find a valid method overload or intrinsic to call for {name}({string.Join(", ", arguments)})")); + } ResolvedFunctionSymbol = functionSymbol; } @@ -113,30 +125,36 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var functionSymbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedFunctionSymbol); - var functionType = (FunctionType)functionSymbol.Type; - - Type = functionType.ReturnType; + var functionSymbol = resolvedIntrinsicOverload != null ? null : LoadedShaderSymbol.ImportSymbol(table, context, ResolvedFunctionSymbol); + var functionType = resolvedIntrinsicOverload != null ? resolvedIntrinsicOverload.Value.Type : (FunctionType)functionSymbol.Type; Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; - ProcessInputArguments(table, compiler, functionType, compiledParams, functionSymbol.MethodDefaultParameters); + ProcessInputArguments(table, compiler, functionType, compiledParams, functionSymbol?.MethodDefaultParameters); - int? instance = null; - if (MemberCall != null) + SpirvValue result; + if (resolvedIntrinsicOverload != null) { - instance = MemberCall.Value.Id; + result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, name.Name, resolvedIntrinsicOverload.Value, compiledParams); } - else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) + else { - instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; - } + int? instance = null; + if (MemberCall != null) + { + instance = MemberCall.Value.Id; + } + else if (functionSymbol.MemberAccessWithImplicitThis is { } thisType) + { + instance = builder.Insert(new OpThisSDSL(context.Bound++)).ResultId; + } - if (instance is int instanceId) - // Note: we make a copy to not mutate original - functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; - - var result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + if (instance is int instanceId) + // Note: we make a copy to not mutate original + functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; + + result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); + } ProcessOutputArguments(table, compiler, functionType, compiledParams); @@ -273,7 +291,8 @@ private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymb } else { - functionSymbol = table.ResolveSymbol(Name); + if (!table.TryResolveSymbol(Name, out functionSymbol)) + return false; } // Choose appropriate method to call diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs index ac11d996f0..9c35ba6ef7 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs @@ -7,53 +7,49 @@ namespace Stride.Shaders.Parsing.SDSL; -public class IntrinsicCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : MethodCall(name, arguments, info) +public class IntrinsicCallHelper { private static IntrinsicTemplateExpander TemplateExpander { get; } = new(IntrinsicsDefinitions.Intrinsics); private IntrinsicTemplateExpander.IntrinsicOverload BestOverload { get; set; } - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + public static bool TryResolveIntrinsic(SymbolTable table, string name, ShaderExpressionList arguments, out IntrinsicTemplateExpander.IntrinsicOverload bestOverload) { - // Process arguments - ProcessParameterSymbols(table); + bestOverload = default; + if (!TemplateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) + { + return false; + } - var overloads = TemplateExpander.GetOrGenerateIntrinsicsDefinition(Name.Name); - // Figure out the best overload - BestOverload = default; + bestOverload = default; var bestOverloadScore = int.MaxValue; foreach (var overload in overloads) { - var overloadScore = OverloadScore(overload.Type, 0, Arguments); + var overloadScore = MethodCall.OverloadScore(overload.Type, 0, arguments); if (overloadScore < bestOverloadScore) { // Better overload - BestOverload = overload; + bestOverload = overload; bestOverloadScore = overloadScore; // We won't get better than that (perfect match), stop there if (overloadScore == 0) break; } } - - if (BestOverload.Type == null) - throw new InvalidOperationException($"No overload found for intrinsic {Name} with arguments {Arguments}"); - - // Now we know the return type - Type = BestOverload.Type.ReturnType; + + if (bestOverloadScore == int.MaxValue) + return false; + + return true; } - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, Span compiledParams) { - var functionType = BestOverload.Type; - - Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; + var functionType = bestOverload.Type; - ProcessInputArguments(table, compiler, functionType, compiledParams); - // Check if we can automatically handle matrix (SPIR-V doesn't but HLSL does allow matrix on most types) SpirvValue result; - if (BestOverload.AutoMatrixLoopLocations != null) + if (bestOverload.AutoMatrixLoopLocations != null) { var (builder, context) = compiler; @@ -61,10 +57,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Extract rows bool isReturnUsingLoop = false; - Span vectorValues = stackalloc int[BestOverload.AutoMatrixLoopLocations.Count * BestOverload.AutoMatrixLoopSize]; - for (var index = 0; index < BestOverload.AutoMatrixLoopLocations.Count; index++) + Span vectorValues = stackalloc int[bestOverload.AutoMatrixLoopLocations.Count * bestOverload.AutoMatrixLoopSize]; + for (var index = 0; index < bestOverload.AutoMatrixLoopLocations.Count; index++) { - var location = BestOverload.AutoMatrixLoopLocations[index]; + var location = bestOverload.AutoMatrixLoopLocations[index]; if (location.TemplateIndex != 0) throw new InvalidOperationException("Matrix loop should only be generated for HLSL row parameter"); @@ -83,36 +79,36 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var parameterType = (MatrixType)functionType.ParameterTypes[location.SourceArgument - 1].Type; var vectorType = new VectorType(parameterType.BaseType, parameterType.Rows); - for (int col = 0; col < BestOverload.AutoMatrixLoopSize; col++) + for (int col = 0; col < bestOverload.AutoMatrixLoopSize; col++) { - vectorValues[index * BestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[location.SourceArgument - 1], [col])).ResultId; + vectorValues[index * bestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[location.SourceArgument - 1], [col])).ResultId; } innerFunctionType.ParameterTypes[location.SourceArgument - 1] = innerFunctionType.ParameterTypes[location.SourceArgument - 1] with { Type = vectorType }; } // Call core function - Span results = stackalloc int[BestOverload.AutoMatrixLoopSize]; - for (int col = 0; col < BestOverload.AutoMatrixLoopSize; col++) + Span results = stackalloc int[bestOverload.AutoMatrixLoopSize]; + for (int col = 0; col < bestOverload.AutoMatrixLoopSize; col++) { - for (var index = 0; index < BestOverload.AutoMatrixLoopLocations.Count; index++) + for (var index = 0; index < bestOverload.AutoMatrixLoopLocations.Count; index++) { - var location = BestOverload.AutoMatrixLoopLocations[index]; + var location = bestOverload.AutoMatrixLoopLocations[index]; if (location.SourceArgument == 0) continue; - compiledParams[location.SourceArgument - 1] = vectorValues[index * BestOverload.AutoMatrixLoopSize + col]; + compiledParams[location.SourceArgument - 1] = vectorValues[index * bestOverload.AutoMatrixLoopSize + col]; } - results[col] = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, Name.Name, innerFunctionType, compiledParams).Id; + results[col] = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, name, innerFunctionType, compiledParams).Id; } // Rebuild return value if (isReturnUsingLoop) { - if (Type is not MatrixType) + if (functionType.ReturnType is not MatrixType) throw new InvalidOperationException("Return type should be a matrix"); - result = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(Type), context.Bound++, [..results]))); + result = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(functionType.ReturnType), context.Bound++, [..results]))); } else { @@ -122,10 +118,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) else { // No auto matrix loop - result = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, Name.Name, functionType, compiledParams); + result = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, name, functionType, compiledParams); } - - ProcessOutputArguments(table, compiler, functionType, compiledParams); return result; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index cfea0f9b06..f84454b206 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -1,4 +1,5 @@ using System.Collections.Frozen; +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using SymbolType = Stride.Shaders.Core.SymbolType; @@ -40,15 +41,20 @@ record struct SizeValue(int Value, SizePermutationGenerator Generator); public record struct IntrinsicOverload(FunctionType Type, List<(int SourceArgument, int TemplateIndex)>? AutoMatrixLoopLocations, int AutoMatrixLoopSize); Dictionary> intrinsicDefinitionsCache = new(); - public List GetOrGenerateIntrinsicsDefinition(string name) + public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(false)] out List result) { lock (intrinsicDefinitionsCache) { - if (intrinsicDefinitionsCache.TryGetValue(name, out var result)) - return result; + if (intrinsicDefinitionsCache.TryGetValue(name, out result)) + return true; + + if (!intrinsicsDefinitions.TryGetValue(name, out var intrinsicDefinitions)) + { + result = null; + return false; + } result = new(); - var intrinsicDefinitions = intrinsicsDefinitions[name]; foreach (var intrinsicDefinition in intrinsicDefinitions) { List baseTypePermutationGenerators = new(); @@ -314,7 +320,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) } intrinsicDefinitionsCache.Add(name, result); - return result; + return true; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs index 321b24a69b..5636f78fba 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs @@ -7,5 +7,10 @@ namespace Stride.Shaders.Parsing.SDSL; internal class Texture2DIntrinsicImplementations : Texture2DMethodsDeclarations { - + public static Texture2DIntrinsicImplementations Instance { get; } = new(); + + public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null) + { + return base.CompileSampleLevel(context, builder, functionType, s, x, lod, o, status); + } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 88c2d7b46c..9ba0b62131 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -53,14 +53,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou Parsers.Spaces0(ref scanner, result, out _); if (Tokens.Char(')', ref scanner, advance: true)) { - if (IntrinsicsDefinitions.Intrinsics.TryGetValue(identifier.Name, out var intrinsicDefinitions)) - { - parsed = new IntrinsicCall(identifier, parameters, scanner[position..scanner.Position]); - } - else - { - parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); - } + parsed = new MethodCall(identifier, parameters, scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); From fa2d15b1859b7e78f7aad411057bf2a0fc62f491 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 6 Feb 2026 14:48:31 +0900 Subject: [PATCH 0786/1182] Rewrote all texture/buffer methods using new intrinsic system. This simplifies AccessorChainExpression a lot. --- assets/SDSL/RenderTests/Buffers.sdsl | 4 +- assets/SDSL/RenderTests/TextureLoad.sdsl | 4 +- .../IntrinsicGenerator.cs | 146 +++++--- .../Intrinsics/IntrinAST.cs | 1 - src/Stride.Shaders.Generators/Trie.cs | 6 +- .../SDSL/AST/BufferMethodsImplementations.cs | 16 + .../Parsing/SDSL/AST/Expression.cs | 328 +++++------------- .../Parsing/SDSL/AST/IntrinsicCall.cs | 61 +++- .../SDSL/AST/IntrinsicImplementations.cs | 9 +- .../SDSL/AST/IntrinsicTemplateExpander.cs | 31 +- .../AST/TextureIntrinsicImplementations.cs | 16 - .../SDSL/AST/TextureMethodsImplementations.cs | 126 +++++++ 12 files changed, 430 insertions(+), 318 deletions(-) create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs delete mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs create mode 100644 src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs diff --git a/assets/SDSL/RenderTests/Buffers.sdsl b/assets/SDSL/RenderTests/Buffers.sdsl index e0ffbb9b93..036a9d5dfb 100644 --- a/assets/SDSL/RenderTests/Buffers.sdsl +++ b/assets/SDSL/RenderTests/Buffers.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1357ABCD, buffer.Buffer1=#1357ABCD) +// PSMain(ExpectedResult=#22446688, buffer.Buffer1=#11223344) namespace Stride.Shaders.Tests; @@ -11,6 +11,6 @@ shader Buffers void PSMain() { - streams.ColorTarget = Buffer1.Load(0); + streams.ColorTarget = Buffer1.Load(0) + Buffer1[0]; } } \ No newline at end of file diff --git a/assets/SDSL/RenderTests/TextureLoad.sdsl b/assets/SDSL/RenderTests/TextureLoad.sdsl index d49e531fe9..158e45a166 100644 --- a/assets/SDSL/RenderTests/TextureLoad.sdsl +++ b/assets/SDSL/RenderTests/TextureLoad.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#1357ABCD, texture.Texture1=#1357ABCD) +// PSMain(ExpectedResult=#22446688, texture.Texture1=#11223344) namespace Stride.Shaders.Tests; @@ -11,6 +11,6 @@ shader TextureLoad void PSMain() { - streams.ColorTarget = Texture1.Load(int3(0, 0, 0)); + streams.ColorTarget = Texture1.Load(int3(0, 0, 0)) + Texture1[int2(0,0)]; } } \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index a2354cd81f..a9f3041db9 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -125,16 +125,18 @@ static string GenerateParameters(List parameters, bool optio return string.Concat(parameters.Where(p => p.Name.Name != "...").Select(p => optional ? $", SpirvValue? {p.Name.Name} = null" : $", SpirvValue {p.Name.Name}")); } - static string GenerateArguments(List parameters) + static string GenerateArguments(List parameters, bool optional = false, int startIndex = 0) { - return string.Concat(parameters.Where(p => p.Name.Name != "...").Select((p, i) => $", new SpirvValue(compiledParams[{i}], context.GetOrRegister(functionType.ParameterTypes[{i}].Type))")); + return string.Concat(parameters.Where(p => p.Name.Name != "...").Select((p, i) => $", {(optional ? $"{p.Name.Name}:" : "")}new SpirvValue(compiledParams[{startIndex + i}], context.GetOrRegister(functionType.ParameterTypes[{startIndex + i}].Type))")); } static string CapitalizeFirstLetter(string s) => char.ToUpper(s[0]) + s[1..]; + static string UncapitalizeFirstLetter(string s) => char.ToLower(s[0]) + s[1..]; // Group of intrinsics with same parameter names (parameter types might differ) - record IntrinsicOverloadGroup(string Name, List Parameters, List Overloads) + record IntrinsicOverloadGroup(string Name, List MandatoryParameters, List OptionalParameters, List<(string DeclaringNamespace, IntrinsicDeclaration Declaration)> Overloads) { + public string Name { get; set; } = Name; public TrieNode TrieNode { get; set; } } @@ -152,61 +154,126 @@ namespace Stride.Shaders.Parsing.SDSL; """); - foreach (var ns in namespaces.Items) + builder.AppendLine("public interface IIntrinsicCompiler"); + builder.AppendLine("{"); + builder.AppendLine(" SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams);"); + builder.AppendLine("}"); + + static string IntrinsicDeclarationKey(NamespaceDeclaration arg) + { + var key = arg.Name.Name; + + // Merge RW and non-RW methods in same type + if (key.StartsWith("RW")) + key = key.Substring("RW".Length); + + + // Merge all texture methods in same type + if (key.StartsWith("Texture")) + return "TextureMethods"; + + return key; + } + + static bool DecodeThisType(string @namespace, out string typeName) + { + if (@namespace.EndsWith("Methods")) + { + typeName = @namespace.Substring(0, @namespace.Length - "Methods".Length); + return true; + } + + typeName = string.Empty; + return false; + } + + static string NormalizeParameters(string @namespace, string methodName, string parameterName) + { + return (@namespace, methodName, parameterName) switch + { + ("TextureMethods", "SampleCmp" or "SampleCmpLevelZero", "c") => "compareValue", + _ => parameterName, + }; + } + + foreach (var ns in namespaces.Items.GroupBy(IntrinsicDeclarationKey)) { - var intrinsicGroups = new Dictionary>(); + bool hasThis = DecodeThisType(ns.Key, out var thisType); + var thisParam = hasThis ? $", SpirvValue {UncapitalizeFirstLetter(thisType)}" : ""; + var thisArg = hasThis ? ", thisValue.Value" : ""; + + var intrinsicGroups = new Dictionary(); - foreach (var intrinsicGroup in ns.Intrinsics.Items - .Where(x => x.Parameters.Items.All(p => p.Name.Name != "...")) - .GroupBy(i => i.Name.Name)) + foreach (var intrinsicGroup in ns.SelectMany(x => x.Intrinsics.Items.Select(y => (DeclaringNamespace: x.Name.Name, Declaration: y))) + .Where(x => x.Declaration.Parameters.Items.All(p => p.Name.Name != "...")) + .GroupBy(i => i.Declaration.Name.Name)) { - var trie = new Trie(); - foreach (var overload in intrinsicGroup.GroupBy(x => GenerateParameters(x.Parameters.Items))) + // Normalize parameters + foreach (var x in intrinsicGroup) { - var parameters = overload.First().Parameters.Items.Where(p => p.Name.Name != "...").ToList(); - var intrinsicOverloadGroup = new IntrinsicOverloadGroup(intrinsicGroup.Key, parameters, overload.ToList()); - intrinsicOverloadGroup.TrieNode = trie.Insert(parameters.Select(p => p.Name.Name).ToList(), intrinsicOverloadGroup); + var parameters = x.Declaration.Parameters.Items.Select(p => p with { Name = p.Name with { Name = NormalizeParameters(ns.Key, x.Declaration.Name.Name, p.Name.Name) } }).ToList(); + x.Declaration.Parameters.Items.Clear(); + x.Declaration.Parameters.Items.AddRange(parameters); } - // Try to attach method definition to a parent definition with optional parameter (only if one option) - // i.e. (a,b) and (a,b,c) will be grouped into (a,b,c?) - // however (a,b) (a,b,c) and (a,b,d) won't be merged as (a,b) has two possible optional parameter branches - - // To do that, we will simplify node with only a single leaves - trie.SimplifySingleLeaves(); + // Find common parameters + var maxParameterCount = intrinsicGroup.Min(x => x.Declaration.Parameters.Items.Count); + var mandatoryParameters = intrinsicGroup.First().Declaration.Parameters.Items.GetRange(0, maxParameterCount); + for (int i = 0; i < maxParameterCount; ++i) + { + if (!intrinsicGroup.All(x => x.Declaration.Parameters.Items[i].Name.Name == mandatoryParameters[i].Name.Name)) + { + mandatoryParameters = mandatoryParameters.GetRange(0, i); + break; + } + } - intrinsicGroups.Add(intrinsicGroup.Key, trie); + var optionalParameters = intrinsicGroup + .SelectMany(x => x.Declaration.Parameters.Items.Skip(mandatoryParameters.Count)) + .GroupBy(x => x.Name.Name) + .Select(x => x.First()) + .ToList(); + + intrinsicGroups[intrinsicGroup.Key] = new IntrinsicOverloadGroup(intrinsicGroup.Key, mandatoryParameters, optionalParameters, intrinsicGroup.ToList()); } - - builder.AppendLine($"public abstract class {ns.Name.Name}Declarations"); + builder.AppendLine($"public abstract class {ns.Key}Declarations : IIntrinsicCompiler"); builder.AppendLine("{"); - + foreach (var intrinsicGroup in intrinsicGroups) { - foreach (var intrinsicOverloadGroup in intrinsicGroup.Value.EnumerateNodes()) - { - if (intrinsicOverloadGroup.Values.Count == 0) - continue; - - // Get parameters of first and last overload (the ones with the less and most parameters) - var mandatoryParameters1 = intrinsicOverloadGroup.Values.First().Parameters; - var mandatoryParameters2 = intrinsicOverloadGroup.Values.Last().Parameters; - var optionalParameters = mandatoryParameters2.GetRange(mandatoryParameters1.Count, mandatoryParameters2.Count - mandatoryParameters1.Count); - builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{GenerateParameters(mandatoryParameters1)}{GenerateParameters(optionalParameters, true)}) => throw new NotImplementedException();"); - } + // Get parameters of first and last overload (the ones with the less and most parameters) + var mandatoryParameters = intrinsicGroup.Value.MandatoryParameters; + + var optionalParameters = intrinsicGroup.Value.OptionalParameters; + builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{thisParam}{GenerateParameters(mandatoryParameters)}{GenerateParameters(optionalParameters, true)}) => throw new NotImplementedException();"); } - builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string name, FunctionType functionType, Span compiledParams) {"); + builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams) {"); builder.AppendLine("var (builder, context) = compiler;"); - builder.AppendLine("return (name, compiledParams.Length) switch {"); + builder.AppendLine("return (@namespace, name, compiledParams.Length) switch {"); foreach (var intrinsicGroup in intrinsicGroups) { - foreach (var intrinsicOverloadGroup in intrinsicGroup.Value.EnumerateNodes()) + var mandatoryParameters = intrinsicGroup.Value.MandatoryParameters; + builder.AppendLine($"// group {intrinsicGroup.Key}"); + + // We split by parameter count then parameters to know if we really need to include switch case in namepsace + foreach (var intrinsicOverloadsByParamCount in intrinsicGroup.Value.Overloads + .GroupBy(x => x.Declaration.Parameters.Items.Count)) { - foreach (var overload in intrinsicOverloadGroup.Values) + var intrinsicOverloadGroupsByParameters = intrinsicOverloadsByParamCount.GroupBy(x => GenerateParameters(x.Declaration.Parameters.Items)).ToList(); + foreach (var intrinsicOverloadGroups in intrinsicOverloadGroupsByParameters) { - builder.AppendLine($"(\"{overload.Name}\", {overload.Parameters.Count}) => Compile{CapitalizeFirstLetter(overload.Name)}(context, builder, functionType{GenerateArguments(overload.Parameters)}),"); + var optionalParameters = intrinsicOverloadGroups.First().Declaration.Parameters.Items.GetRange(mandatoryParameters.Count, intrinsicOverloadGroups.First().Declaration.Parameters.Items.Count - mandatoryParameters.Count); + + // If only one parameter signature for all overloads with same number of parameters, skip namespace + var declaredInNamespaces = intrinsicOverloadGroupsByParameters.Count > 1 + ? intrinsicOverloadGroups.Select(x => $"\"{x.DeclaringNamespace}\"").Distinct().ToArray() + : ["_"]; + foreach (var @namespace in declaredInNamespaces) + { + builder.AppendLine($"({@namespace}, \"{intrinsicGroup.Key}\", {intrinsicOverloadGroups.First().Declaration.Parameters.Items.Count}) => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}),"); + } } } } @@ -227,7 +294,6 @@ namespace Stride.Shaders.Parsing.SDSL; ); } - internal static EquatableList ParseInstrinsics(AdditionalText text, CancellationToken ct) { if (IntrinParser.ProcessAndParse(text.GetText()?.ToString() ?? "", out var ns)) diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs index 375f7a7e97..62651173cb 100644 --- a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs +++ b/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs @@ -17,7 +17,6 @@ internal record Identifier(string Name, TextLocation Location) : Node(Location) internal record Attributes(string[] Values, TextLocation Location) : Node(Location); - internal record Layout(string Size1, string? Size2, TextLocation Location) : Node(Location); internal record Typename(string Name, Layout? Size, TextLocation Location) : Node(Location) diff --git a/src/Stride.Shaders.Generators/Trie.cs b/src/Stride.Shaders.Generators/Trie.cs index fbc9ba72cb..1853218464 100644 --- a/src/Stride.Shaders.Generators/Trie.cs +++ b/src/Stride.Shaders.Generators/Trie.cs @@ -37,19 +37,19 @@ public TrieNode Insert(List keys, TValue value) return node; } - public void SimplifySingleLeaves() => SimplifySingleLeaves(root); + public void SimplifyRoot() => SimplifyRoot(root); public IEnumerable> EnumerateNodes() => EnumerateNodes(root); // Try to attach method definition to a parent definition with optional parameter (only if one option) // i.e. (a,b) and (a,b,c) will be grouped into (a,b,c?) // however (a,b) (a,b,c) and (a,b,d) won't be merged as (a,b) has two possible optional parameter branches - private void SimplifySingleLeaves(TrieNode node) + private void SimplifyRoot(TrieNode node) { // First we recurse foreach (var child in node.Children.Values) { - SimplifySingleLeaves(child); + SimplifyRoot(child); } // Check if we can merge node with its child diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs new file mode 100644 index 0000000000..573c39a957 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs @@ -0,0 +1,16 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; + +namespace Stride.Shaders.Parsing.SDSL.AST; + +public class BufferMethodsImplementations : BufferMethodsDeclarations +{ + public static BufferMethodsImplementations Instance { get; } = new(); + + public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue x, SpirvValue? status = null) + { + var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(functionType.ReturnType), context.Bound++, buffer.Id, x.Id, null, [])); + return new(loadResult.ResultId, loadResult.ResultType); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 9b4bf59350..7561b01738 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -30,7 +30,7 @@ public abstract class Expression(TextLocation info) : ValueNode(info) public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { if (Type == null) - throw new InvalidOperationException($"{nameof(ProcessSymbol)} was not called on expression {this}"); + throw new InvalidOperationException($"{nameof(ProcessSymbol)} was not called on expression {this} or type resolution failed"); var result = CompileImpl(table, compiler); @@ -87,25 +87,36 @@ public class MethodCall(Identifier name, ShaderExpressionList arguments, TextLoc public Symbol ResolvedFunctionSymbol { get; set; } + private IIntrinsicCompiler? resolvedIntrinsicCompiler; + private string? resolvedIntrinsicNamespace; private IntrinsicTemplateExpander.IntrinsicOverload? resolvedIntrinsicOverload; public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { ProcessParameterSymbols(table); - if (TryResolveFunctionSymbol(table, out var functionSymbol)) + var argumentValueTypes = new SymbolType[arguments.Values.Count]; + for (int i = 0; i < arguments.Values.Count; ++i) + argumentValueTypes[i] = arguments.Values[i].ValueType; + + if (TryResolveFunctionSymbol(table, argumentValueTypes, out var functionSymbol)) { var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; } - else if (IntrinsicCallHelper.TryResolveIntrinsic(table, name, arguments, out var resolvedIntrinsicOverloadValue)) - { - resolvedIntrinsicOverload = resolvedIntrinsicOverloadValue; - Type = resolvedIntrinsicOverload.Value.Type.ReturnType; - } else { - table.AddError(new(info, $"Can't find a valid method overload or intrinsic to call for {name}({string.Join(", ", arguments)})")); + if (IntrinsicCallHelper.TryResolveIntrinsic(table, MemberCallBaseType, name, argumentValueTypes, out var resolvedIntrinsic)) + { + resolvedIntrinsicCompiler = resolvedIntrinsic.Compiler; + resolvedIntrinsicNamespace = resolvedIntrinsic.Namespace; + resolvedIntrinsicOverload = resolvedIntrinsic.Overload; + Type = resolvedIntrinsicOverload.Value.Type.ReturnType; + } + else + { + table.AddError(new(info, $"Can't find a valid method overload or intrinsic to call for {name}({string.Join(", ", arguments)})")); + } } ResolvedFunctionSymbol = functionSymbol; @@ -135,7 +146,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) SpirvValue result; if (resolvedIntrinsicOverload != null) { - result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, name.Name, resolvedIntrinsicOverload.Value, compiledParams); + SpirvValue? @this = MemberCall != null ? builder.AsValue(context, MemberCall.Value) : null; + result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler, resolvedIntrinsicNamespace, name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams); } else { @@ -172,25 +184,39 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F { // Wrap param in proper pointer type (function) var paramDefinition = functionType.ParameterTypes[i]; - var paramVariable = context.Bound++; - builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); // Note: "in" is implicit, so we match in all cases except if out var inOutFlags = paramDefinition.Modifiers & ParameterModifiers.InOut; - if (inOutFlags != ParameterModifiers.Out) + + if (paramDefinition.Type is PointerType) { - var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + var paramVariable = context.Bound++; + builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); + + if (inOutFlags != ParameterModifiers.Out) + { + var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); - // Convert type (if necessary) - var paramExpectedValueType = paramDefinition.Type; - if (paramExpectedValueType is PointerType pointerType) - paramExpectedValueType = pointerType.BaseType; - paramSource = builder.Convert(context, paramSource, paramExpectedValueType); + // Convert type (if necessary) + var paramExpectedValueType = paramDefinition.Type; + if (paramExpectedValueType is PointerType pointerType) + paramExpectedValueType = pointerType.BaseType; + paramSource = builder.Convert(context, paramSource, paramExpectedValueType); - builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); + builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); + } + + compiledParams[i] = paramVariable; } + else + { + if ((inOutFlags & ParameterModifiers.Out) != 0) + throw new InvalidOperationException($"Function {Name} has an out parameter at index {i} but it's not a pointer type"); - compiledParams[i] = paramVariable; + var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + paramSource = builder.Convert(context, paramSource, paramDefinition.Type); + compiledParams[i] = paramSource.Id; + } } // Find default parameters decoration (if any) @@ -252,19 +278,19 @@ protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, } // Note: int.MaxValue means incompatible - public static int OverloadScore(FunctionType functionType, int defaultParameters, ShaderExpressionList arguments) + public static int OverloadScore(FunctionType functionType, int defaultParameters, SymbolType[] argumentValueTypes) { // Check argument count - if (arguments.Values.Count > functionType.ParameterTypes.Count || arguments.Values.Count < functionType.ParameterTypes.Count + defaultParameters) + if (argumentValueTypes.Length > functionType.ParameterTypes.Count || argumentValueTypes.Length < functionType.ParameterTypes.Count + defaultParameters) return int.MaxValue; // Check if argument can be converted var score = 0; - for (var index = 0; index < arguments.Values.Count; index++) + for (var index = 0; index < argumentValueTypes.Length; index++) { - var argument = arguments.Values[index]; + var argumentValueType = argumentValueTypes[index]; var parameter = functionType.ParameterTypes[index]; - var argScore = SpirvBuilder.CanConvertScore(argument.ValueType, parameter.Type.GetValueType()); + var argScore = SpirvBuilder.CanConvertScore(argumentValueType, parameter.Type.GetValueType()); if (argScore == int.MaxValue) return int.MaxValue; @@ -272,12 +298,12 @@ public static int OverloadScore(FunctionType functionType, int defaultParameters } // method with fewer optional parameters that need to be filled in by default values is generally preferred - score += functionType.ParameterTypes.Count - arguments.Values.Count; + score += functionType.ParameterTypes.Count - argumentValueTypes.Length; return score; } - private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymbol) + private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentValueTypes, out Symbol functionSymbol) { // Note: for now, TypeId 0 is used for this/base; let's improve that later if (MemberCallBaseType is LoadedShaderSymbol loadedShaderSymbol) @@ -301,7 +327,7 @@ private bool TryResolveFunctionSymbol(SymbolTable table, out Symbol functionSymb { var accessibleMethods = functionSymbol.GroupMembers // Check overload score - .Select(x => (Score: OverloadScore((FunctionType)x.Type, x.MethodDefaultParameters?.DefaultValues.Length ?? 0, arguments), Symbol: x)) + .Select(x => (Score: OverloadScore((FunctionType)x.Type, x.MethodDefaultParameters?.DefaultValues.Length ?? 0, argumentValueTypes), Symbol: x)) // Remove non-applicable methods .Where(x => x.Score != int.MaxValue) // Group by signature/score (we assume method with exact same signature means they are overriding each other, but we might need to do a better check using override info) @@ -761,67 +787,6 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Some accessors push up to 2 values on the stack Span accessChainIds = stackalloc int[Accessors.Count * 2]; - VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) - { - return pointerType.BaseType switch - { - BufferType b => new VectorType(b.BaseType, 4), - TextureType t => new VectorType(t.ReturnType, 4), - }; - } - - (SpirvValue Value, SymbolType ResultType) BufferLoad(BufferType bufferType, SpirvValue buffer, Expression locationExpression) - { - var resultType = new VectorType(bufferType.BaseType, 4); - - buffer = builder.AsValue(context, buffer); - var location = locationExpression.CompileAsValue(table, compiler); - location = builder.Convert(context, location, ScalarType.Int); - - var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(resultType), context.Bound++, buffer.Id, location.Id, null, [])); - return (new(loadResult.ResultId, loadResult.ResultType), resultType); - } - - (SpirvValue Value, SymbolType ResultType) TextureLoad(TextureType textureType, SpirvValue buffer, Expression coordinatesExpression, Expression? offsetExpression, Expression? sampleIndexExpression, bool containsLod) - { - var resultType = new VectorType(textureType.ReturnType, 4); - var imageCoordValue = ConvertTexCoord(context, builder, textureType, coordinatesExpression.CompileAsValue(table, compiler), ScalarType.Int, containsLod); - var imageCoordType = context.ReverseTypes[imageCoordValue.TypeId]; - SpirvValue lod; - - if (containsLod) - { - // We get all components except last one (LOD) - var imageCoordSize = imageCoordType.GetElementCount(); - imageCoordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); - Span shuffleIndices = stackalloc int[imageCoordSize - 1]; - for (int i = 0; i < shuffleIndices.Length; ++i) - shuffleIndices[i] = i; - - // Note: assign LOD first because we truncate imageCoordValue right after - // Extract LOD (last coordinate) as a separate value - lod = new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, imageCoordValue.Id, [imageCoordSize - 1]))); - // Remove last component (LOD) from texcoord - imageCoordValue = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(imageCoordType), context.Bound++, imageCoordValue.Id, imageCoordValue.Id, new(shuffleIndices)))); - } - else - { - lod = context.CompileConstant(0.0f); - } - - buffer = builder.AsValue(context, buffer); - - SpirvValue? offset = offsetExpression != null - ? ConvertOffset(context, builder, textureType, offsetExpression.CompileAsValue(table, compiler)) - : null; - SpirvValue? sampleIndex = sampleIndexExpression != null - ? builder.Convert(context, sampleIndexExpression.CompileAsValue(table, compiler), ScalarType.Int) - : null; - TextureGenerateImageOperands(lod, offset, sampleIndex, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(resultType), context.Bound++, buffer.Id, imageCoordValue.Id, imask, imParams)); - return (new(loadResult.ResultId, loadResult.ResultType), resultType); - } - for (var i = 0; i < Accessors.Count; ++i) { var accessor = Accessors[i]; @@ -831,170 +796,59 @@ VectorType ComputeBufferOrTextureAccessReturnType(PointerType pointerType) switch (currentValueType, accessor) { - case (PointerType { BaseType: TextureType textureType }, - MethodCall { Name.Name: "Sample", Arguments.Values.Count: 2 or 3 } - or MethodCall { Name.Name: "SampleLevel", Arguments.Values.Count: 3 or 4 }): - { - if (compiler == null) - { - ((MethodCall)accessor).ProcessParameterSymbols(table, null); - accessor.Type = new VectorType(textureType.ReturnType, 4); - break; - } - - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - var textureValue = builder.AsValue(context, result); - var resultType = accessor.Type; - - if (accessor is MethodCall { Name.Name: "Sample", Arguments.Values.Count: 2 or 3 } implicitSampling) - { - var samplerValue = implicitSampling.Arguments.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, implicitSampling.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); - - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(resultType); - - SpirvValue? offset = implicitSampling.Arguments.Values.Count >= 3 - ? ConvertOffset(context, builder, textureType, implicitSampling.Arguments.Values[2].CompileAsValue(table, compiler)) - : null; - TextureGenerateImageOperands(null, offset, null, out var imask, out var imParams); - var sample = builder.Insert(new OpImageSampleImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); - - result = new(sample.ResultId, sample.ResultType); - accessor.Type = resultType; - } - else if (accessor is MethodCall { Name.Name: "SampleLevel", Arguments.Values.Count: 3 or 4 } explicitSampling) - { - var samplerValue = explicitSampling.Arguments.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, explicitSampling.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); - - var levelValue = explicitSampling.Arguments.Values[2].CompileAsValue(table, compiler); - levelValue = builder.Convert(context, levelValue, ScalarType.Float); - - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(resultType); - - SpirvValue? offset = explicitSampling.Arguments.Values.Count >= 4 - ? ConvertOffset(context, builder, textureType, explicitSampling.Arguments.Values[3].CompileAsValue(table, compiler)) - : null; - TextureGenerateImageOperands(levelValue, offset, null, out var imask, out var imParams); - var sample = builder.Insert(new OpImageSampleExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, imask, imParams)); - - result = new(sample.ResultId, sample.ResultType); - accessor.Type = resultType; - } - else - throw new InvalidOperationException("Invalid Sample method call"); - break; - } - case (PointerType { BaseType: TextureType textureType }, - MethodCall { Name.Name: "SampleCmp" or "SampleCmpLevelZero", Arguments.Values.Count: 3 or 4 } sampleCompare): + case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): { if (compiler == null) { - ((MethodCall)accessor).ProcessParameterSymbols(table, null); - accessor.Type = textureType.ReturnType; - if (accessor.Type is not ScalarType) - throw new InvalidOperationException(); + indexer.Index.ProcessSymbol(table); + + // Note: Texture.Load expects one more coordinate + // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) + var indexerType = pointerType.BaseType is TextureType + ? indexer.Index.ValueType.GetElementType().GetVectorOrScalar(indexer.Index.ValueType.GetElementCount() + 1) + : indexer.Index.ValueType; + + if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType], out var resolvedIntrinsic2)) + throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); + accessor.Type = resolvedIntrinsic2.Overload.Type.ReturnType; break; } - var resultType = textureType.ReturnType; - // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - var textureValue = builder.AsValue(context, result); - var samplerValue = sampleCompare.Arguments.Values[0].CompileAsValue(table, compiler); - var texCoordValue = ConvertTexCoord(context, builder, textureType, sampleCompare.Arguments.Values[1].CompileAsValue(table, compiler), ScalarType.Float); + // Note: Texture.Load expects one more coordinate + // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) + var indexerType2 = pointerType.BaseType is TextureType + ? indexer.Index.ValueType.GetElementType().GetVectorOrScalar(indexer.Index.ValueType.GetElementCount() + 1) + : indexer.Index.ValueType; - var compareValue = sampleCompare.Arguments.Values[2].CompileAsValue(table, compiler); - - var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, textureValue.Id, samplerValue.Id)); - var returnType = context.GetOrRegister(resultType); + if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType2], out var resolvedIntrinsic)) + throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); - SpirvValue? offset = sampleCompare.Arguments.Values.Count >= 4 - ? ConvertOffset(context, builder, textureType, sampleCompare.Arguments.Values[3].CompileAsValue(table, compiler)) - : null; - TextureGenerateImageOperands(context.CompileConstant(0.0f), offset, null, out var imask, out var imParams); - var sample = sampleCompare.Name.Name == "SampleCmpLevelZero" - ? builder.InsertData(new OpImageSampleDrefExplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, imask, imParams)) - : builder.InsertData(new OpImageSampleDrefImplicitLod(returnType, context.Bound++, sampledImage.ResultId, texCoordValue.Id, compareValue.Id, imask, imParams)); - - result = new(sample.IdResult!.Value, sample.IdResultType!.Value); - accessor.Type = resultType; - break; - } - case (PointerType { BaseType: BufferType or TextureType } pointerType, MethodCall { Name.Name: "Load", Arguments.Values.Count: 1 or 2 or 3 } load): + // Generate Load parameter + var indexValue = indexer.Index.CompileAsValue(table, compiler); + var texcoordType = resolvedIntrinsic.Overload.Type.ParameterTypes[0].Type; + if (pointerType.BaseType is TextureType) { - if (compiler == null) - { - // Check parameter count - switch (pointerType.BaseType) - { - case BufferType b: - if (load.Arguments.Values.Count != 1) - table.AddError(new(info, "Buffer.Load expects a single argument")); - break; - case TextureType t: - var requiredArguments = 1; - if (t.Multisampled) - requiredArguments++; - - // One optional argument (offset) - if (load.Arguments.Values.Count != requiredArguments && load.Arguments.Values.Count != requiredArguments + 1) - table.AddError(new(info, $"Texture.Load expects {requiredArguments} or {requiredArguments + 1} arguments")); - break; - default: - throw new ArgumentOutOfRangeException(nameof(pointerType.BaseType)); - } - - ((MethodCall)accessor).ProcessParameterSymbols(table, null); - accessor.Type = ComputeBufferOrTextureAccessReturnType(pointerType); - break; - } - - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - - switch (pointerType.BaseType) - { - case BufferType b: - (result, accessor.Type) = BufferLoad(b, result, load.Arguments.Values[0]); - break; - case TextureType t: - var sampleIndex = t.Multisampled ? load.Arguments.Values[1] : null; - var offsetArgIndex = t.Multisampled ? 2 : 1; - var offset = load.Arguments.Values.Count >= offsetArgIndex + 1 ? load.Arguments.Values[offsetArgIndex] : null; - (result, accessor.Type) = TextureLoad(t, result, load.Arguments.Values[0], offset, sampleIndex, true); - break; - default: - throw new ArgumentOutOfRangeException(nameof(pointerType.BaseType)); - } - - break; + // Find expected type for array (same as Load() but with 1 less component) + var texcoordSize = texcoordType.GetElementCount(); + indexValue = builder.Convert(context, indexValue, texcoordType.GetElementType().GetVectorOrScalar(texcoordSize - 1)); + + Span values = stackalloc int[texcoordSize]; + for (int j = 0; j < texcoordSize - 1; ++j) + values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; + values[^1] = context.CompileConstant((int)0).Id; + indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [..values]))); } - case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): - { - if (compiler == null) + else { - indexer.Index.ProcessSymbol(table); - accessor.Type = ComputeBufferOrTextureAccessReturnType(pointerType); - break; + indexValue = builder.Convert(context, indexValue, texcoordType); } - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - - (result, accessor.Type) = pointerType.BaseType switch - { - BufferType b => BufferLoad(b, result, indexer.Index), - TextureType t => TextureLoad(t, result, indexer.Index, null, null, false), - }; + result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, result, [indexValue.Id]); + accessor.Type = resolvedIntrinsic.Overload.Type.ReturnType; + break; } case (PointerType { BaseType: StructuredBufferType bufferType }, IndexerExpression indexer): diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs index 9c35ba6ef7..0a0d46b0bc 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs @@ -4,28 +4,68 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using System; +using System.Collections.Frozen; +using Stride.Shaders.Spirv; namespace Stride.Shaders.Parsing.SDSL; public class IntrinsicCallHelper { - private static IntrinsicTemplateExpander TemplateExpander { get; } = new(IntrinsicsDefinitions.Intrinsics); - private IntrinsicTemplateExpander.IntrinsicOverload BestOverload { get; set; } + private static IntrinsicTemplateExpander? TemplateExpander { get; set; } + private static Dictionary ClassTemplateExpanders = new(); - public static bool TryResolveIntrinsic(SymbolTable table, string name, ShaderExpressionList arguments, out IntrinsicTemplateExpander.IntrinsicOverload bestOverload) + public static bool TryResolveIntrinsic(SymbolTable table, SymbolType? thisType, string name, SymbolType[] argumentValueTypes, out (IIntrinsicCompiler Compiler, string Namespace, IntrinsicTemplateExpander.IntrinsicOverload Overload) resolvedIntrinsic) { - bestOverload = default; - if (!TemplateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) + resolvedIntrinsic = default; + + static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @namespace, FrozenDictionary intrinsicsDefinitions) + { + if (!ClassTemplateExpanders.TryGetValue(type, out var value)) + ClassTemplateExpanders.Add(type, value = new(type, @namespace, intrinsicsDefinitions)); + return value; + } + + (var templateExpander, var intrinsicCompiler) = thisType switch + { + null => (TemplateExpander ??= new(null, nameof(IntrinsicsDefinitions.Intrinsics), IntrinsicsDefinitions.Intrinsics), (IIntrinsicCompiler)IntrinsicImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim1D, Sampled: not 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture1DMethods), IntrinsicsDefinitions.Texture1DMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim1D, Sampled: not 2, Arrayed: true, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture1DArrayMethods), IntrinsicsDefinitions.Texture1DArrayMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim1D, Sampled: 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture1DMethods), IntrinsicsDefinitions.RWTexture1DMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim1D, Sampled: 2, Arrayed: true, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture1DArrayMethods), IntrinsicsDefinitions.RWTexture1DArrayMethods), TextureMethodsImplementations.Instance), + + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: not 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture2DMethods), IntrinsicsDefinitions.Texture2DMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: not 2, Arrayed: true, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture2DArrayMethods), IntrinsicsDefinitions.Texture2DArrayMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: not 2, Arrayed: false, Multisampled: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture2DMSMethods), IntrinsicsDefinitions.Texture2DMSMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: not 2, Arrayed: true, Multisampled: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture2DArrayMSMethods), IntrinsicsDefinitions.Texture2DArrayMSMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture2DMethods), IntrinsicsDefinitions.RWTexture2DMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: 2, Arrayed: true, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture2DArrayMethods), IntrinsicsDefinitions.RWTexture2DArrayMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: 2, Arrayed: false, Multisampled: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture2DMSMethods), IntrinsicsDefinitions.RWTexture2DMSMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim2D, Sampled: 2, Arrayed: true, Multisampled: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture2DMSArrayMethods), IntrinsicsDefinitions.RWTexture2DMSArrayMethods), TextureMethodsImplementations.Instance), + + TextureType { Dimension: Specification.Dim.Dim3D, Sampled: not 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.Texture3DMethods), IntrinsicsDefinitions.Texture3DMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Dim3D, Sampled: 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWTexture3DMethods), IntrinsicsDefinitions.RWTexture3DMethods), TextureMethodsImplementations.Instance), + + TextureType { Dimension: Specification.Dim.Cube, Sampled: not 2, Arrayed: false, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.TextureCUBEMethods), IntrinsicsDefinitions.TextureCUBEMethods), TextureMethodsImplementations.Instance), + TextureType { Dimension: Specification.Dim.Cube, Sampled: not 2, Arrayed: true, Multisampled: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.TextureCUBEArrayMethods), IntrinsicsDefinitions.TextureCUBEArrayMethods), TextureMethodsImplementations.Instance), + + BufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.BufferMethods), IntrinsicsDefinitions.BufferMethods), BufferMethodsImplementations.Instance), + BufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWBufferMethods), IntrinsicsDefinitions.RWBufferMethods), BufferMethodsImplementations.Instance), + + StructuredBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.StructuredBufferMethods), IntrinsicsDefinitions.StructuredBufferMethods), null), + StructuredBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWStructuredBufferMethods), IntrinsicsDefinitions.RWStructuredBufferMethods), null), + }; + + if (!templateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) { return false; } // Figure out the best overload - bestOverload = default; + IntrinsicTemplateExpander.IntrinsicOverload bestOverload = default; var bestOverloadScore = int.MaxValue; foreach (var overload in overloads) { - var overloadScore = MethodCall.OverloadScore(overload.Type, 0, arguments); + var overloadScore = MethodCall.OverloadScore(overload.Type, 0, argumentValueTypes); if (overloadScore < bestOverloadScore) { // Better overload @@ -40,10 +80,11 @@ public static bool TryResolveIntrinsic(SymbolTable table, string name, ShaderExp if (bestOverloadScore == int.MaxValue) return false; + resolvedIntrinsic = (intrinsicCompiler, templateExpander.Namespace, bestOverload); return true; } - public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, Span compiledParams) + public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, IIntrinsicCompiler intrinsicCompiler, string @namespace, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, SpirvValue? thisValue, Span compiledParams) { var functionType = bestOverload.Type; @@ -99,7 +140,7 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil compiledParams[location.SourceArgument - 1] = vectorValues[index * bestOverload.AutoMatrixLoopSize + col]; } - results[col] = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, name, innerFunctionType, compiledParams).Id; + results[col] = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, innerFunctionType, thisValue, compiledParams).Id; } // Rebuild return value @@ -118,7 +159,7 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil else { // No auto matrix loop - result = IntrinsicImplementations.Instance.CompileIntrinsic(table, compiler, name, functionType, compiledParams); + result = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, functionType, thisValue, compiledParams); } return result; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs index 77e57b92f2..f6316d6f72 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -16,8 +16,13 @@ internal class IntrinsicImplementations : IntrinsicsDeclarations // Cast public override SpirvValue CompileAsfloat(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); public override SpirvValue CompileAsint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue d, SpirvValue x, SpirvValue y) => throw new NotImplementedException(); + public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue? d = null, SpirvValue? x = null, SpirvValue? y = null) + { + if (d == null && y == null) + return CompileBitcastCall(context, builder, functionType, x.Value); + throw new NotImplementedException(); + } + public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => throw new NotImplementedException(); public override SpirvValue CompileAsfloat16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileAsint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index f84454b206..134f541102 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -9,8 +9,10 @@ namespace Stride.Shaders.Parsing.SDSL; /// /// Helps expand intrinsics from to multiple . /// -public class IntrinsicTemplateExpander(FrozenDictionary intrinsicsDefinitions) +public class IntrinsicTemplateExpander(SymbolType? thisType, string @namespace, FrozenDictionary intrinsicsDefinitions) { + public string Namespace { get; } = @namespace; + record SizePermutationGenerator(string? Name, List Sizes, List<(int SourceArgument, int TemplateIndex)> Locations) { public IEnumerable Generate() @@ -41,6 +43,8 @@ record struct SizeValue(int Value, SizePermutationGenerator Generator); public record struct IntrinsicOverload(FunctionType Type, List<(int SourceArgument, int TemplateIndex)>? AutoMatrixLoopLocations, int AutoMatrixLoopSize); Dictionary> intrinsicDefinitionsCache = new(); + record struct ParameterTypeInfo(SymbolType BaseType, SizeValue Size1, SizeValue Size2); + public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(false)] out List result) { lock (intrinsicDefinitionsCache) @@ -53,7 +57,7 @@ public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(fal result = null; return false; } - + result = new(); foreach (var intrinsicDefinition in intrinsicDefinitions) { @@ -183,7 +187,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) var sizePermutations = CartesianProduct.Generate(sizeSequences); // Step 4: generate signature using permutations - (SymbolType BaseType, SizeValue Size1, SizeValue Size2)[] parameterTypeHelper = new (SymbolType BaseType, SizeValue Size1, SizeValue Size2)[intrinsicDefinition.Parameters.Length + 1]; + ParameterTypeInfo[] parameterTypeHelper = new ParameterTypeInfo[intrinsicDefinition.Parameters.Length + 1]; SymbolType[] parameterTypes = new SymbolType[intrinsicDefinition.Parameters.Length + 1]; foreach (var baseTypePermutationList in baseTypePermutations) { @@ -235,6 +239,20 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) } } + ParameterTypeInfo GetParameterInfo(int index) + { + if (index == -1) + { + return thisType switch + { + null => throw new ArgumentNullException(nameof(thisType)), + TextureType t => new(t.ReturnType, new(4, null), default), + BufferType b => new(b.BaseType, new(4, null), default), + }; + } + return parameterTypeHelper[index]; + } + // Use match() to fill size info for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) { @@ -244,8 +262,11 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) { if (parameterType.Match != null && parameterType.Match.Value.Layout != index) { - parameterTypeHelper[index].Size1 = parameterTypeHelper[parameterType.Match.Value.Layout].Size1; - parameterTypeHelper[index].Size2 = parameterTypeHelper[parameterType.Match.Value.Layout].Size2; + var paramInfo = GetParameterInfo(parameterType.Match.Value.Layout); + if (parameterTypeHelper[index].BaseType == ScalarType.Void) + parameterTypeHelper[index].BaseType = paramInfo.BaseType; + parameterTypeHelper[index].Size1 = paramInfo.Size1; + parameterTypeHelper[index].Size2 = paramInfo.Size2; // Also register locations (to easily analyze matrix loops later) if (firstIteration) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs deleted file mode 100644 index 5636f78fba..0000000000 --- a/src/Stride.Shaders/Parsing/SDSL/AST/TextureIntrinsicImplementations.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Spirv; -using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Core; - -namespace Stride.Shaders.Parsing.SDSL; - -internal class Texture2DIntrinsicImplementations : Texture2DMethodsDeclarations -{ - public static Texture2DIntrinsicImplementations Instance { get; } = new(); - - public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null) - { - return base.CompileSampleLevel(context, builder, functionType, s, x, lod, o, status); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs new file mode 100644 index 0000000000..ff78384b46 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -0,0 +1,126 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Parsing.SDSL; + +internal class TextureMethodsImplementations : TextureMethodsDeclarations +{ + public static TextureMethodsImplementations Instance { get; } = new(); + + public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? s = null) + { + if (status != null) + throw new NotImplementedException(); + + var imageCoordType = context.ReverseTypes[x.TypeId]; + + // We get all components except last one (LOD) + var imageCoordSize = imageCoordType.GetElementCount(); + imageCoordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); + Span shuffleIndices = stackalloc int[imageCoordSize - 1]; + for (int i = 0; i < shuffleIndices.Length; ++i) + shuffleIndices[i] = i; + + // Note: assign LOD first because we truncate imageCoordValue right after + // Extract LOD (last coordinate) as a separate value + var lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); + // Remove last component (LOD) from texcoord + x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(imageCoordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); + + TextureGenerateImageOperands(lod, o, s, out var imask, out var imParams); + var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); + return new(loadResult.ResultId, loadResult.ResultType); + } + + public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + var sample = builder.Insert(new OpImageSampleImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(lod, o, null, out var imask, out var imParams); + var sample = builder.Insert(new OpImageSampleExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(context.CompileConstant(0.0f), o, null, out var imask, out var imParams); + var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams) + { + imask = ImageOperandsMask.None; + // Allocate for worst case (3 operands) + Span operands = stackalloc int[3]; + int operandCount = 0; + if (lod != null) + { + imask |= ImageOperandsMask.Lod; + operands[operandCount++] = lod.Value.Id; + } + if (offset != null) + { + imask |= ImageOperandsMask.Offset; + operands[operandCount++] = offset.Value.Id; + } + if (sampleIndex != null) + { + imask |= ImageOperandsMask.Sample; + operands[operandCount++] = sampleIndex.Value.Id; + } + + imParams = operandCount > 0 ? new EnumerantParameters(operands.Slice(0, operandCount)) : new EnumerantParameters(); + } +} \ No newline at end of file From 7195d677d026e00cd5001db324a0f7c76679b552 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 6 Feb 2026 15:47:13 +0900 Subject: [PATCH 0787/1182] Phase5 part2 --- .../Spirv/Processing/InterfaceProcessor.cs | 839 ------------------ .../Analysis/ReadWriteAnalyzer.cs | 0 .../Analysis/SemanticAnalyzer.cs | 0 .../Analysis/StreamAnalyzer.cs | 0 .../Cleanup/DeadCodeRemover.cs | 0 .../Cleanup/VariableMerger.cs | 0 .../Generation/BuiltinProcessor.cs | 0 .../Generation/EntryPointWrapperGenerator.cs | 448 ++++++++++ .../StreamWrapperGenerator_README.md | 0 .../Interfaces/InterfaceProcessor.cs | 440 +++++++++ .../Models/AnalysisResult.cs | 0 .../Models/LiveAnalysis.cs | 0 .../Models/ResourceInfo.cs | 0 .../Models/StreamVariableInfo.cs | 0 .../Models/VariableInfo.cs | 0 .../Transformation/MethodDuplicator.cs | 0 .../Transformation/StreamAccessPatcher.cs | 0 17 files changed, 888 insertions(+), 839 deletions(-) delete mode 100644 src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Analysis/ReadWriteAnalyzer.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Analysis/SemanticAnalyzer.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Analysis/StreamAnalyzer.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Cleanup/DeadCodeRemover.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Cleanup/VariableMerger.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Generation/BuiltinProcessor.cs (100%) create mode 100644 src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Generation/StreamWrapperGenerator_README.md (100%) create mode 100644 src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Models/AnalysisResult.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Models/LiveAnalysis.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Models/ResourceInfo.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Models/StreamVariableInfo.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Models/VariableInfo.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Transformation/MethodDuplicator.cs (100%) rename src/Stride.Shaders/Spirv/Processing/{InterfaceProcessorInternal => Interfaces}/Transformation/StreamAccessPatcher.cs (100%) diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs deleted file mode 100644 index b5cac9b506..0000000000 --- a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessor.cs +++ /dev/null @@ -1,839 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Tools; -using System.IO; -using Stride.Shaders.Parsing.Analysis; -using static Stride.Shaders.Spirv.Specification; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; -using CommunityToolkit.HighPerformance; -using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; - -namespace Stride.Shaders.Spirv.Processing -{ - /// - /// Help to process streams and simplify the interface (resources, methods, cbuffer) of the shader. - /// - public class InterfaceProcessor - { - public Action? CodeInserted { get; set; } - - public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); - - Symbol? ResolveEntryPoint(SymbolTable table, string name) - { - table.TryResolveSymbol(name, out var entryPoint); - return entryPoint?.Type switch - { - FunctionGroupType => entryPoint.GroupMembers[^1], - _ => entryPoint - }; - } - - public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) - { - var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); - - var entryPointVS = ResolveEntryPoint(table, "VSMain"); - var entryPointHS = ResolveEntryPoint(table, "HSMain"); - var entryPointDS = ResolveEntryPoint(table, "DSMain"); - var entryPointGS = ResolveEntryPoint(table, "GSMain"); - var entryPointPS = ResolveEntryPoint(table, "PSMain"); - var entryPointCS = ResolveEntryPoint(table, "CSMain"); - - var entryPointPSOrCS = entryPointCS ?? entryPointPS ?? throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); - if (entryPointPS == null && entryPointCS == null) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); - - var analysisResult = StreamAnalyzer.Analyze(buffer, context); - VariableMerger.MergeSameSemanticVariables(table, context, buffer, analysisResult); - var streams = analysisResult.Streams; - - var liveAnalysis = new LiveAnalysis(); - ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); - - if (entryPointCS != null) - { - (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); - entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); - } - - if (entryPointHS != null || entryPointDS != null) - context.Add(new OpCapability(Capability.Tessellation)); - else if (entryPointGS != null) - context.Add(new OpCapability(Capability.Geometry)); - - var inputAttributes = new List(); - - if (entryPointPS != null) - { - // If written to, they are expected at the end of pixel shader - foreach (var stream in streams) - { - if (stream.Value.Semantic is { } semantic) - { - if ((semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") && stream.Value.Write) - stream.Value.Output = true; - } - } - - // Check if there is any output - // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) - if (streams.Any(x => x.Value.Output)) - { - (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); - entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); - - buffer.Add(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); - } - - // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages - foreach (var stream in streams) - { - if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) - stream.Value.Read = false; - } - - // Reset cbuffer/resource/methods used for next stage - DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); - - VariableMerger.PropagateStreamsFromPreviousStage(streams); - - foreach (var entryPoint in new[] { (ExecutionModel.TessellationControl, entryPointHS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.Geometry, entryPointGS) }) - { - if (entryPoint.Item2 != null) - { - ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); - - // Find patch constant entry point and process it as well - var patchConstantEntryPoint = entryPoint.Item1 == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint.Item2) : null; - if (patchConstantEntryPoint != null) - ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); - - // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader - foreach (var stream in streams) - { - if (stream.Value.Semantic is { } semantic) - { - if (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - stream.Value.Output = true; - - if (entryPoint.Item1 == ExecutionModel.TessellationControl - && (semantic.ToUpperInvariant().StartsWith("SV_TESSFACTOR") || semantic.ToUpperInvariant().StartsWith("SV_INSIDETESSFACTOR"))) - stream.Value.Output = true; - } - } - - (var wrapperId, var wrapperName) = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); - var stage = entryPoint.Item1 switch - { - ExecutionModel.TessellationControl => ShaderStage.Hull, - ExecutionModel.TessellationEvaluation => ShaderStage.Domain, - ExecutionModel.Geometry => ShaderStage.Geometry, - }; - entryPoints.Add((wrapperName, wrapperId, stage)); - - // Reset cbuffer/resource/methods used for next stage - DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); - - VariableMerger.PropagateStreamsFromPreviousStage(streams); - - if (entryPointVS == null) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); - } - } - - if (entryPointVS != null) - { - ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); - - // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader - foreach (var stream in streams) - { - if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - stream.Value.Output = true; - } - - (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); - entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); - - // Process shader input attributes - foreach (var stream in streams) - { - // Note: built-ins won't have a inputLayoutLocation so they will be skipped - if (stream.Value.Input && stream.Value.InputLayoutLocation is {} inputLayoutLocation) - { - if (stream.Value.Semantic == null) - throw new InvalidOperationException($"Vertex shader input {stream.Value.Name} doesn't have semantic"); - var semantic = SemanticAnalyzer.ParseSemantic(stream.Value.Semantic); - inputAttributes.Add(new ShaderInputAttributeDescription { Location = inputLayoutLocation, SemanticName = semantic.Name, SemanticIndex = semantic.Index }); - } - } - } - } - - // This will remove a lot of unused methods, resources and variables - // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) - DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); - - return new(entryPoints, inputAttributes); - } - - - static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) - { - foreach (var i in context) - { - if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is - { - EntryPoint: var target, - Mode: ExecutionMode.OutputVertices, - ModeParameters: { } m, - } && target == entryPoint.IdRef) - { - return m.Span[0]; - } - } - - throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); - } - - private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) - { - var streams = analysisResult.Streams; - - var stage = executionModel switch - { - ExecutionModel.Vertex => "VS", - ExecutionModel.TessellationControl => "HS", - ExecutionModel.TessellationEvaluation => "DS", - ExecutionModel.Geometry => "GS", - ExecutionModel.Fragment => "PS", - ExecutionModel.GLCompute => "CS", - _ => throw new NotImplementedException() - }; - List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; - List entryPointExtraVariables = []; - - int inputLayoutLocationCount = 0; - int outputLayoutLocationCount = 0; - - foreach (var stream in streams) - { - if (stream.Value.Output) - { - if (stream.Value.OutputLayoutLocation is { } outputLayoutLocation) - { - outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); - } - } - } - - // Delegate to BuiltinProcessor - bool AddBuiltin(int variable, BuiltIn builtin) => BuiltinProcessor.AddBuiltin(context, variable, builtin); - - bool AddLocation(int variable, string location) => BuiltinProcessor.AddLocation(context, variable, location); - - int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) => - BuiltinProcessor.ConvertInterfaceVariable(buffer, context, sourceType, castType, value); - - bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) => - BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variable, type, semantic, ref symbolType); - - var entryPointFunctionType = (FunctionType)entryPoint.Type; - // TODO: check all parameters instead of hardcoded 0 - int? arrayInputSize = executionModel switch - { - ExecutionModel.Geometry => ((ArrayType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, - ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation => ((PatchType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, - _ => null, - }; - int? arrayOutputSize = executionModel switch - { - ExecutionModel.TessellationControl => FindOutputPatchSize(context, entryPoint), - _ => null, - }; - - foreach (var stream in streams) - { - if (stream.Value.Input) - { - var variableId = context.Bound++; - var variableType = stream.Value.Type; - if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, stream.Value.Semantic, ref variableType)) - { - if (stream.Value.InputLayoutLocation == null) - stream.Value.InputLayoutLocation = inputLayoutLocationCount++; - context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); - if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); - } - - // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants - var streamInputType = new PointerType(!stream.Value.Patch && arrayInputSize != null - ? new ArrayType(variableType, arrayInputSize.Value) - : variableType, - Specification.StorageClass.Input); - var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); - context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - - if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) - context.Add(new OpDecorate(variable, Decoration.Flat, [])); - - stream.Value.InputId = variable.ResultId; - (stream.Value.Patch ? patchInputStreams : inputStreams).Add((stream.Value, variable.ResultId, variableType)); - } - - if (stream.Value.Output) - { - var variableId = context.Bound++; - var variableType = stream.Value.Type; - if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Output, stream.Value.Semantic, ref variableType)) - { - // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic - if (stream.Value.OutputLayoutLocation == null) - { - if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) - stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; - else - throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); - } - - context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); - if (stream.Value.Semantic != null) - context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); - } - - // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants - var streamOutputType = new PointerType(!stream.Value.Patch && arrayOutputSize != null - ? new ArrayType(variableType, arrayOutputSize.Value) - : variableType, - Specification.StorageClass.Output); - var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); - context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - - if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) - context.Add(new OpDecorate(variable, Decoration.Flat, [])); - - stream.Value.OutputId = variable.ResultId; - (stream.Value.Patch ? patchOutputStreams : outputStreams).Add((stream.Value, variable.ResultId, variableType)); - } - } - - var streamFields = new List(); - var constantFields = new List(); - var inputFields = new List(); - var outputFields = new List(); - foreach (var stream in streams) - { - stream.Value.InputStructFieldIndex = null; - stream.Value.OutputStructFieldIndex = null; - if (stream.Value.UsedThisStage) - { - var fields = (stream.Value.Patch) ? constantFields : streamFields; - stream.Value.StreamStructFieldIndex = fields.Count; - fields.Add(new(stream.Value.Name, stream.Value.Type, default)); - } - } - - foreach (var stream in inputStreams) - { - stream.Info.InputStructFieldIndex = inputFields.Count; - inputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); - } - - foreach (var stream in outputStreams) - { - stream.Info.OutputStructFieldIndex = outputFields.Count; - outputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); - } - - var inputType = new StructType($"{stage}_INPUT", inputFields); - var outputType = new StructType($"{stage}_OUTPUT", outputFields); - var streamsType = new StructType($"{stage}_STREAMS", streamFields); - bool hasConstants = executionModel is ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation; - var constantsType = hasConstants ? new StructType($"{stage}_CONSTANTS", constantFields) : null; - context.DeclareStructuredType(inputType, context.Bound++); - context.DeclareStructuredType(outputType, context.Bound++); - context.DeclareStructuredType(streamsType, context.Bound++); - if (hasConstants) - context.DeclareStructuredType(constantsType, context.Bound++); - - // Create a static global streams variable - var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); - context.AddName(streamsVariable.ResultId, $"streams{stage}"); - - // Find patch constant entry point - var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; - - // Patch any OpStreams/OpAccessChain to use the new struct - foreach (var method in liveAnalysis.ReferencedMethods) - { - if (method.Value.UsedThisStage && method.Value.HasStreamAccess) - { - MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); - StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); - } - } - - var voidType = context.GetOrRegister(ScalarType.Void); - - // Add new entry point wrapper - var newEntryPointFunctionType = context.GetOrRegister(new FunctionType(ScalarType.Void, [])); - var newEntryPointFunction = buffer.Add(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType)); - buffer.Add(new OpLabel(context.Bound++)); - var variableInsertIndex = buffer.Count; - var entryPointName = $"{entryPoint.Id.Name}_Wrapper"; - context.AddName(newEntryPointFunction, entryPointName); - - { - // Variable initializers - foreach (var variable in analysisResult.Variables) - { - // Note: we check UsedThisStage to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) - if (variable.Value.UsedThisStage - && variable.Value.VariableMethodInitializerId is int methodInitializerId) - { - liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); - - var variableValueType = variable.Value.Type.BaseType; - var methodInitializerCall = buffer.Add(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, [])); - buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null, [])); - } - } - - // Update entry point type (since Streams type might have been replaced) - entryPointFunctionType = (FunctionType)entryPoint.Type; - - var builtinVariables = new Dictionary(); - int GetOrDeclareBuiltInValue(SymbolType type, string semantic) - { - semantic = semantic.ToUpperInvariant(); - if (builtinVariables.TryGetValue(semantic, out var result)) - { - if (result.Type != type) - throw new InvalidOperationException($"Semantic {semantic} requested with type {type} but last time with {result.Type}"); - return result.Id; - } - - // Declare the global builtin - var variableId = context.Bound++; - if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, semantic, ref type)) - throw new InvalidOperationException(); - var variable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(type, Specification.StorageClass.Input)), variableId, Specification.StorageClass.Input, null)).ResultId; - entryPointExtraVariables.Add(variable); - var value = buffer.Add(new OpLoad(context.GetOrRegister(type), context.Bound++, variable, null, [])).ResultId; - builtinVariables.Add(semantic, (type, value)); - return value; - } - void FillSemanticArguments(FunctionType functionType, Span arguments) - { - foreach (var i in context) - { - if (i.Op == Op.OpMemberDecorateString - && ((OpMemberDecorateString)i) is - { - StructType: int t, - Decoration: Decoration.UserSemantic, - Value: string semantic, - Member: int argumentIndex, - } && t == entryPoint.IdRef - ) - { - var argumentType = ((PointerType)functionType.ParameterTypes[argumentIndex].Type).BaseType; - - var value = GetOrDeclareBuiltInValue(argumentType, semantic); - - // Create local variable with StorageClass.Function that we can use as argument - var localVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(argumentType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - buffer.Add(new OpStore(localVariable, value, null, [])); - arguments[argumentIndex] = localVariable; - - SpirvBuilder.SetOpNop(i.Data.Memory.Span); - } - } - } - - // Fill parameters with semantics - Span arguments = stackalloc int[entryPointFunctionType.ParameterTypes.Count]; - FillSemanticArguments(entryPointFunctionType, arguments); - - // Setup input and call original main() - if (arrayInputSize != null) - { - // Copy variables to Input[X] which is first method parameter of main() - // Pattern is a loop over index i looking like: - // inputs[i].Position = gl_Position[i]; - // inputs[i].Normal = in_GS_normals[i]; - var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - context.AddName(inputsVariable, "inputs"); - - int ConvertInputsArray() - { - Span inputLoadValues = stackalloc int[inputFields.Count]; - for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) - { - var stream = inputStreams[inputIndex]; - var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, [])); - inputLoadValues[inputIndex] = loadedValue.ResultId; - } - - Span inputFieldValues = stackalloc int[inputFields.Count]; - Span inputValues = stackalloc int[arrayInputSize.Value]; - for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) - { - for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) - { - var stream = inputStreams[inputIndex]; - inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).ResultId; - inputFieldValues[inputIndex] = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); - } - - inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).ResultId; - } - - var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).ResultId; - return inputsData1; - } - - var inputsData = ConvertInputsArray(); - - buffer.Add(new OpStore(inputsVariable, inputsData, null, [])); - - var entryPointTypeId = context.GetOrRegister(entryPoint.Type); - if (executionModel == ExecutionModel.TessellationControl || executionModel == ExecutionModel.TessellationEvaluation) - { - bool hullTessellationOutputsGenerated = false; - int GenerateHullTessellationOutputs() - { - if (hullTessellationOutputsGenerated) - throw new InvalidOperationException("Hull OutputPatch can only be used in once place (constant patch)"); - hullTessellationOutputsGenerated = true; - var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - context.AddName(outputsVariable, "outputs"); - - for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) - { - for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) - { - var stream = outputStreams[outputIndex]; - var outputsVariablePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), - context.Bound++, outputsVariable, - [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).ResultId; - var outputSourcePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), - context.Bound++, stream.Id, - [context.CompileConstant(arrayIndex).Id])).ResultId; - var outputsSourceValue = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, outputSourcePtr, null, [])).ResultId; - outputsSourceValue = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputsSourceValue); - buffer.Add(new OpStore(outputsVariablePtr, outputsSourceValue, null, [])); - } - } - - return outputsVariable; - } - - void FillTessellationArguments(Symbol function, Span arguments) - { - var functionType = (FunctionType)function.Type; - var functionTypeId = context.GetOrRegister(functionType); - for (int i = 0; i < functionType.ParameterTypes.Count; i++) - { - var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; - var parameterModifiers = functionType.ParameterTypes[i].Modifiers; - switch (parameterType) - { - // Hull/Domain inputs - case PatchType inputPatchType when - (inputPatchType.Kind == PatchTypeKindSDSL.Input && executionModel == ExecutionModel.TessellationControl) - || (inputPatchType.Kind == PatchTypeKindSDSL.Output && executionModel == ExecutionModel.TessellationEvaluation): - { - // Change signature of main() to use an array instead of InputPatch - // InputPatch becomes HS_INPUT[X] - SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(inputPatchType.BaseType, inputPatchType.Size), Specification.StorageClass.Function)); - context.ReplaceType(function.Type, functionTypeId); - arguments[i] = inputsVariable; - break; - } - // Hull outputs - case PatchType { Kind: PatchTypeKindSDSL.Output } outputPatchType when executionModel == ExecutionModel.TessellationControl: - { - // Change signature of main() to use an array instead of InputPatch - // InputPatch becomes HS_INPUT[X] - SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(outputPatchType.BaseType, outputPatchType.Size), Specification.StorageClass.Function)); - context.ReplaceType(function.Type, functionTypeId); - arguments[i] = GenerateHullTessellationOutputs(); - break; - } - case StructType t when (t == constantsType) && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: - { - // Parameter is "HS_CONSTANTS constants" - var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - arguments[i] = constantVariable; - // Copy back values from semantic/builtin variables to Constants struct - foreach (var stream in patchInputStreams) - { - var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).ResultId; - inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); - buffer.Add(new OpStore(inputPtr, inputResult, null, [])); - } - break; - } - case StructType t when (t == outputType || t == constantsType) && parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" - var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - arguments[i] = outVariable; - break; - } - case var t when arguments[i] == 0: - throw new NotImplementedException($"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}"); - } - } - } - - void ProcessTessellationArguments(Symbol function, Span arguments) - { - var functionType = (FunctionType)function.Type; - for (int i = 0; i < functionType.ParameterTypes.Count; i++) - { - var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; - var parameterModifiers = functionType.ParameterTypes[i].Modifiers; - switch (parameterType) - { - case StructType t when t == outputType && parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" - var outputVariable = arguments[i]; - // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; - // Do we need to index into array? if yes, get index (gl_invocationID) - int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; - // Copy back values from Output struct to semantic/builtin variables - for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) - { - var stream = outputStreams[outputIndex]; - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; - outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); - var outputTargetPtr = arrayOutputSize != null - ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), - context.Bound++, stream.Id, - [invocationIdValue.Value])).ResultId - : stream.Id; - buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); - } - break; - } - case StructType t when t == constantsType && parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" - var outputVariable = arguments[i]; - // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; - // Copy back values from Output struct to semantic/builtin variables - foreach (var stream in patchOutputStreams) - { - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; - outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); - buffer.Add(new OpStore(stream.Id, outputResult, null, [])); - } - break; - } - } - } - } - - FillTessellationArguments(entryPoint, arguments); - - // Call main(inputs, output, ...) - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); - - ProcessTessellationArguments(entryPoint, arguments); - - if (patchConstantEntryPoint != null) - { - // Insert a barrier - buffer.Add(new OpControlBarrier(context.CompileConstant(2).Id, context.CompileConstant(4).Id, context.CompileConstant(0).Id)); - - liveAnalysis.MarkMethodUsed(patchConstantEntryPoint.IdRef); - - // Load gl_InvocationID to check if we're invocation 0 - var invocationIdValue = GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID"); - - // Compare with 0 - var zeroConstant = context.CompileConstant(0u).Id; - var isInvocationZero = buffer.Add(new OpIEqual(context.GetOrRegister(ScalarType.Boolean), context.Bound++, invocationIdValue, zeroConstant)).ResultId; - - // Create labels for if-then-merge - var thenLabel = context.Bound++; - var mergeLabel = context.Bound++; - - // Branch based on condition - buffer.Add(new OpSelectionMerge(mergeLabel, SelectionControlMask.None)); - buffer.Add(new OpBranchConditional(isInvocationZero, thenLabel, mergeLabel, [])); - - // Then block: call patch constant function - buffer.Add(new OpLabel(thenLabel)); - - var patchConstantEntryPointType = (FunctionType)patchConstantEntryPoint.Type; - Span patchArguments = stackalloc int[patchConstantEntryPointType.ParameterTypes.Count]; - FillSemanticArguments(patchConstantEntryPointType, patchArguments); - FillTessellationArguments(patchConstantEntryPoint, patchArguments); - buffer.Add(new OpFunctionCall(voidType, context.Bound++, patchConstantEntryPoint.IdRef, new(patchArguments))); - ProcessTessellationArguments(patchConstantEntryPoint, patchArguments); - - buffer.Add(new OpBranch(mergeLabel)); - - // Merge block - buffer.Add(new OpLabel(mergeLabel)); - } - } - else if (executionModel == ExecutionModel.Geometry) - { - // Change signature of main() to not use the output Stream anymore - SpirvBuilder.FunctionRemoveArgument(context, buffer, entryPoint, 1); - - // Extract and remove execution mode (line, point, triangleadj, etc.) - var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; - if (executionMode == ParameterModifiers.None) - throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); - entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; - - context.ReplaceType(entryPoint.Type, entryPointTypeId); - context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch - { - ParameterModifiers.Point => ExecutionMode.InputPoints, - ParameterModifiers.Line => ExecutionMode.InputLines, - ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, - ParameterModifiers.Triangle => ExecutionMode.Triangles, - ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, - }, [])); - - arguments[0] = inputsVariable; - - // Call main(inputs) - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); - } - } - else - { - // We assume a void returning function and Input/Output is all handled with streams - // Note: we could in the future support having Input/Output in the function signature, just like we do for HS/DS/GS - - // Copy variables from input to streams struct - foreach (var stream in inputStreams) - { - var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).ResultId; - inputResult = ConvertInterfaceVariable(stream.InterfaceType, stream.Info.Type, inputResult); - buffer.Add(new OpStore(streamPointer, inputResult, null, [])); - } - - // Call main() - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); - - // Copy variables from streams struct to output - foreach (var stream in outputStreams) - { - var baseType = stream.Info.Type; - var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariable.ResultId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer, null, [])).ResultId; - outputResult = ConvertInterfaceVariable(stream.Info.Type, stream.InterfaceType, outputResult); - buffer.Add(new OpStore(stream.Id, outputResult, null, [])); - } - } - - buffer.Add(new OpReturn()); - buffer.Add(new OpFunctionEnd()); - - // Note: we overallocate and filter with UsedThisStage after - Span entryPointInterfaceVariables = stackalloc int[inputStreams.Count + outputStreams.Count + patchInputStreams.Count + patchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; - int pvariableIndex = 0; - foreach (var inputStream in inputStreams) - entryPointInterfaceVariables[pvariableIndex++] = inputStream.InterfaceId; - foreach (var outputStream in outputStreams) - entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; - foreach (var inputStream in patchInputStreams) - entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; - foreach (var outputStream in patchOutputStreams) - entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; - entryPointInterfaceVariables[pvariableIndex++] = streamsVariable.ResultId; - foreach (var variable in analysisResult.Variables) - { - if (variable.Value.UsedThisStage) - entryPointInterfaceVariables[pvariableIndex++] = variable.Key; - } - foreach (var cbuffer in analysisResult.CBuffers) - { - if (cbuffer.Value.UsedThisStage) - entryPointInterfaceVariables[pvariableIndex++] = cbuffer.Key; - } - foreach (var resource in analysisResult.Resources) - { - if (resource.Value.UsedThisStage) - entryPointInterfaceVariables[pvariableIndex++] = resource.Key; - } - - foreach (var variable in entryPointExtraVariables) - { - entryPointInterfaceVariables[pvariableIndex++] = variable; - } - - liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. entryPointInterfaceVariables.Slice(0, pvariableIndex)])); - } - - // Move OpExecutionMode on new wrapper - foreach (var i in context) - { - if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) - { - if (executionMode.EntryPoint == entryPoint.IdRef) - executionMode.EntryPoint = newEntryPointFunction.ResultId; - } - } - - return (newEntryPointFunction.ResultId, entryPointName); - } - - private Symbol? ResolveHullPatchConstantEntryPoint(SymbolTable table, SpirvContext context, Symbol entryPoint) - { - // Check if there's a patch constant function and call it when gl_InvocationID == 0 - string? patchConstantFuncName = null; - foreach (var i in context) - { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is - { - Target: int target, - Decoration: Decoration.PatchConstantFuncSDSL, - Value: string funcName - } && target == entryPoint.IdRef) - { - patchConstantFuncName = funcName; - break; - } - } - - Symbol? patchConstantEntryPoint = null; - if (patchConstantFuncName != null) - { - // Resolve the patch constant function - patchConstantEntryPoint = ResolveEntryPoint(table, patchConstantFuncName); - if (patchConstantEntryPoint == null) - throw new InvalidOperationException($"Hull shader patch constant function {patchConstantFuncName} was not found"); - } - - return patchConstantEntryPoint; - } - } -} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/ReadWriteAnalyzer.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/SemanticAnalyzer.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Analysis/StreamAnalyzer.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/DeadCodeRemover.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Cleanup/VariableMerger.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/BuiltinProcessor.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs new file mode 100644 index 0000000000..9236526a51 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -0,0 +1,448 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; + +internal static class EntryPointWrapperGenerator +{ + public static (int ResultId, string Name) GenerateWrapper( + NewSpirvBuffer buffer, + SpirvContext context, + Symbol entryPoint, + ExecutionModel executionModel, + string stage, + AnalysisResult analysisResult, + LiveAnalysis liveAnalysis, + List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams, + List inputFields, + List outputFields, + StructType inputType, + StructType outputType, + StructType streamsType, + StructType? constantsType, + int? arrayInputSize, + int? arrayOutputSize, + int streamsVariableId, + Symbol? patchConstantEntryPoint, + List entryPointExtraVariables) + { + var entryPointFunctionType = (FunctionType)entryPoint.Type; + var voidType = context.GetOrRegister(ScalarType.Void); + + // Add new entry point wrapper + var newEntryPointFunctionType = context.GetOrRegister(new FunctionType(ScalarType.Void, [])); + var newEntryPointFunction = buffer.Add(new OpFunction(voidType, context.Bound++, FunctionControlMask.None, newEntryPointFunctionType)); + buffer.Add(new OpLabel(context.Bound++)); + var variableInsertIndex = buffer.Count; + var entryPointName = $"{entryPoint.Id.Name}_Wrapper"; + context.AddName(newEntryPointFunction, entryPointName); + + // Variable initializers + foreach (var variable in analysisResult.Variables) + { + // Note: we check UsedThisStage to make sure variable is actually used in the shader (otherwise it won't be emitted if not part of all used variables in OpEntryPoint) + if (variable.Value.UsedThisStage + && variable.Value.VariableMethodInitializerId is int methodInitializerId) + { + liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); + + var variableValueType = variable.Value.Type.BaseType; + var methodInitializerCall = buffer.Add(new OpFunctionCall(context.GetOrRegister(variableValueType), context.Bound++, methodInitializerId, [])); + buffer.Add(new OpStore(variable.Value.VariableId, methodInitializerCall.ResultId, null, [])); + } + } + + // Update entry point type (since Streams type might have been replaced) + entryPointFunctionType = (FunctionType)entryPoint.Type; + + var builtinVariables = new Dictionary(); + + int GetOrDeclareBuiltInValue(SymbolType type, string semantic) + { + semantic = semantic.ToUpperInvariant(); + if (builtinVariables.TryGetValue(semantic, out var result)) + { + if (result.Type != type) + throw new InvalidOperationException($"Semantic {semantic} requested with type {type} but last time with {result.Type}"); + return result.Id; + } + + // Declare the global builtin + var variableId = context.Bound++; + if (!BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variableId, StreamVariableType.Input, semantic, ref type)) + throw new InvalidOperationException(); + var variable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(type, Specification.StorageClass.Input)), variableId, Specification.StorageClass.Input, null)).ResultId; + entryPointExtraVariables.Add(variable); + var value = buffer.Add(new OpLoad(context.GetOrRegister(type), context.Bound++, variable, null, [])).ResultId; + builtinVariables.Add(semantic, (type, value)); + return value; + } + + void FillSemanticArguments(FunctionType functionType, Span arguments) + { + foreach (var i in context) + { + if (i.Op == Op.OpMemberDecorateString + && ((OpMemberDecorateString)i) is + { + StructType: int t, + Decoration: Decoration.UserSemantic, + Value: string semantic, + Member: int argumentIndex, + } && t == entryPoint.IdRef + ) + { + var argumentType = ((PointerType)functionType.ParameterTypes[argumentIndex].Type).BaseType; + + var value = GetOrDeclareBuiltInValue(argumentType, semantic); + + // Create local variable with StorageClass.Function that we can use as argument + var localVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(argumentType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + buffer.Add(new OpStore(localVariable, value, null, [])); + arguments[argumentIndex] = localVariable; + + SpirvBuilder.SetOpNop(i.Data.Memory.Span); + } + } + } + + // Fill parameters with semantics + Span arguments = stackalloc int[entryPointFunctionType.ParameterTypes.Count]; + FillSemanticArguments(entryPointFunctionType, arguments); + + // Setup input and call original main() + if (arrayInputSize != null) + { + // Copy variables to Input[X] which is first method parameter of main() + // Pattern is a loop over index i looking like: + // inputs[i].Position = gl_Position[i]; + // inputs[i].Normal = in_GS_normals[i]; + var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + context.AddName(inputsVariable, "inputs"); + + int ConvertInputsArray() + { + Span inputLoadValues = stackalloc int[inputFields.Count]; + for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + { + var stream = inputStreams[inputIndex]; + var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, [])); + inputLoadValues[inputIndex] = loadedValue.ResultId; + } + + Span inputFieldValues = stackalloc int[inputFields.Count]; + Span inputValues = stackalloc int[arrayInputSize.Value]; + for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + { + for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + { + var stream = inputStreams[inputIndex]; + inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).ResultId; + inputFieldValues[inputIndex] = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); + } + + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).ResultId; + } + + var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).ResultId; + return inputsData1; + } + + var inputsData = ConvertInputsArray(); + + buffer.Add(new OpStore(inputsVariable, inputsData, null, [])); + + var entryPointTypeId = context.GetOrRegister(entryPoint.Type); + if (executionModel == ExecutionModel.TessellationControl || executionModel == ExecutionModel.TessellationEvaluation) + { + bool hullTessellationOutputsGenerated = false; + int GenerateHullTessellationOutputs() + { + if (hullTessellationOutputsGenerated) + throw new InvalidOperationException("Hull OutputPatch can only be used in once place (constant patch)"); + hullTessellationOutputsGenerated = true; + var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + context.AddName(outputsVariable, "outputs"); + + for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + { + for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + { + var stream = outputStreams[outputIndex]; + var outputsVariablePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), + context.Bound++, outputsVariable, + [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).ResultId; + var outputSourcePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), + context.Bound++, stream.Id, + [context.CompileConstant(arrayIndex).Id])).ResultId; + var outputsSourceValue = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, outputSourcePtr, null, [])).ResultId; + outputsSourceValue = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputsSourceValue); + buffer.Add(new OpStore(outputsVariablePtr, outputsSourceValue, null, [])); + } + } + + return outputsVariable; + } + + void FillTessellationArguments(Symbol function, Span arguments) + { + var functionType = (FunctionType)function.Type; + var functionTypeId = context.GetOrRegister(functionType); + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + { + var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; + var parameterModifiers = functionType.ParameterTypes[i].Modifiers; + switch (parameterType) + { + // Hull/Domain inputs + case PatchType inputPatchType when + (inputPatchType.Kind == PatchTypeKindSDSL.Input && executionModel == ExecutionModel.TessellationControl) + || (inputPatchType.Kind == PatchTypeKindSDSL.Output && executionModel == ExecutionModel.TessellationEvaluation): + { + // Change signature of main() to use an array instead of InputPatch + // InputPatch becomes HS_INPUT[X] + SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(inputPatchType.BaseType, inputPatchType.Size), Specification.StorageClass.Function)); + context.ReplaceType(function.Type, functionTypeId); + arguments[i] = inputsVariable; + break; + } + // Hull outputs + case PatchType { Kind: PatchTypeKindSDSL.Output } outputPatchType when executionModel == ExecutionModel.TessellationControl: + { + // Change signature of main() to use an array instead of InputPatch + // InputPatch becomes HS_INPUT[X] + SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(outputPatchType.BaseType, outputPatchType.Size), Specification.StorageClass.Function)); + context.ReplaceType(function.Type, functionTypeId); + arguments[i] = GenerateHullTessellationOutputs(); + break; + } + case StructType t when (t == constantsType) && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: + { + // Parameter is "HS_CONSTANTS constants" + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = constantVariable; + // Copy back values from semantic/builtin variables to Constants struct + foreach (var stream in patchInputStreams) + { + var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).ResultId; + inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); + buffer.Add(new OpStore(inputPtr, inputResult, null, [])); + } + break; + } + case StructType t when (t == outputType || t == constantsType) && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" + var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = outVariable; + break; + } + case var t when arguments[i] == 0: + throw new NotImplementedException($"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}"); + } + } + } + + void ProcessTessellationArguments(Symbol function, Span arguments) + { + var functionType = (FunctionType)function.Type; + for (int i = 0; i < functionType.ParameterTypes.Count; i++) + { + var parameterType = ((PointerType)functionType.ParameterTypes[i].Type).BaseType; + var parameterModifiers = functionType.ParameterTypes[i].Modifiers; + switch (parameterType) + { + case StructType t when t == outputType && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; + // Do we need to index into array? if yes, get index (gl_invocationID) + int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; + // Copy back values from Output struct to semantic/builtin variables + for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + { + var stream = outputStreams[outputIndex]; + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; + outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); + var outputTargetPtr = arrayOutputSize != null + ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), + context.Bound++, stream.Id, + [invocationIdValue.Value])).ResultId + : stream.Id; + buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); + } + break; + } + case StructType t when t == constantsType && parameterModifiers == ParameterModifiers.Out: + { + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; + // Copy back values from Output struct to semantic/builtin variables + foreach (var stream in patchOutputStreams) + { + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; + outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); + buffer.Add(new OpStore(stream.Id, outputResult, null, [])); + } + break; + } + } + } + } + + FillTessellationArguments(entryPoint, arguments); + + // Call main(inputs, output, ...) + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + + ProcessTessellationArguments(entryPoint, arguments); + + if (patchConstantEntryPoint != null) + { + // Insert a barrier + buffer.Add(new OpControlBarrier(context.CompileConstant(2).Id, context.CompileConstant(4).Id, context.CompileConstant(0).Id)); + + liveAnalysis.MarkMethodUsed(patchConstantEntryPoint.IdRef); + + // Load gl_InvocationID to check if we're invocation 0 + var invocationIdValue = GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID"); + + // Compare with 0 + var zeroConstant = context.CompileConstant(0u).Id; + var isInvocationZero = buffer.Add(new OpIEqual(context.GetOrRegister(ScalarType.Boolean), context.Bound++, invocationIdValue, zeroConstant)).ResultId; + + // Create labels for if-then-merge + var thenLabel = context.Bound++; + var mergeLabel = context.Bound++; + + // Branch based on condition + buffer.Add(new OpSelectionMerge(mergeLabel, SelectionControlMask.None)); + buffer.Add(new OpBranchConditional(isInvocationZero, thenLabel, mergeLabel, [])); + + // Then block: call patch constant function + buffer.Add(new OpLabel(thenLabel)); + + var patchConstantEntryPointType = (FunctionType)patchConstantEntryPoint.Type; + Span patchArguments = stackalloc int[patchConstantEntryPointType.ParameterTypes.Count]; + FillSemanticArguments(patchConstantEntryPointType, patchArguments); + FillTessellationArguments(patchConstantEntryPoint, patchArguments); + buffer.Add(new OpFunctionCall(voidType, context.Bound++, patchConstantEntryPoint.IdRef, new(patchArguments))); + ProcessTessellationArguments(patchConstantEntryPoint, patchArguments); + + buffer.Add(new OpBranch(mergeLabel)); + + // Merge block + buffer.Add(new OpLabel(mergeLabel)); + } + } + else if (executionModel == ExecutionModel.Geometry) + { + // Change signature of main() to not use the output Stream anymore + SpirvBuilder.FunctionRemoveArgument(context, buffer, entryPoint, 1); + + // Extract and remove execution mode (line, point, triangleadj, etc.) + var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; + if (executionMode == ParameterModifiers.None) + throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); + entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; + + context.ReplaceType(entryPoint.Type, entryPointTypeId); + context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch + { + ParameterModifiers.Point => ExecutionMode.InputPoints, + ParameterModifiers.Line => ExecutionMode.InputLines, + ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, + ParameterModifiers.Triangle => ExecutionMode.Triangles, + ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, + }, [])); + + arguments[0] = inputsVariable; + + // Call main(inputs) + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + } + } + else + { + // We assume a void returning function and Input/Output is all handled with streams + // Note: we could in the future support having Input/Output in the function signature, just like we do for HS/DS/GS + + // Copy variables from input to streams struct + foreach (var stream in inputStreams) + { + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).ResultId; + inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); + buffer.Add(new OpStore(streamPointer, inputResult, null, [])); + } + + // Call main() + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + + // Copy variables from streams struct to output + foreach (var stream in outputStreams) + { + var baseType = stream.Info.Type; + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer, null, [])).ResultId; + outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); + buffer.Add(new OpStore(stream.Id, outputResult, null, [])); + } + } + + buffer.Add(new OpReturn()); + buffer.Add(new OpFunctionEnd()); + + // Note: we overallocate and filter with UsedThisStage after + Span entryPointInterfaceVariables = stackalloc int[inputStreams.Count + outputStreams.Count + patchInputStreams.Count + patchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; + int pvariableIndex = 0; + foreach (var inputStream in inputStreams) + entryPointInterfaceVariables[pvariableIndex++] = inputStream.InterfaceId; + foreach (var outputStream in outputStreams) + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + foreach (var inputStream in patchInputStreams) + entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; + foreach (var outputStream in patchOutputStreams) + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + entryPointInterfaceVariables[pvariableIndex++] = streamsVariableId; + foreach (var variable in analysisResult.Variables) + { + if (variable.Value.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = variable.Key; + } + foreach (var cbuffer in analysisResult.CBuffers) + { + if (cbuffer.Value.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = cbuffer.Key; + } + foreach (var resource in analysisResult.Resources) + { + if (resource.Value.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = resource.Key; + } + + foreach (var variable in entryPointExtraVariables) + { + entryPointInterfaceVariables[pvariableIndex++] = variable; + } + + liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); + context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. entryPointInterfaceVariables.Slice(0, pvariableIndex)])); + + return (newEntryPointFunction.ResultId, entryPointName); + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/StreamWrapperGenerator_README.md similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Generation/StreamWrapperGenerator_README.md rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/StreamWrapperGenerator_README.md diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs new file mode 100644 index 0000000000..ebf2d41af6 --- /dev/null +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -0,0 +1,440 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; +using System.IO; +using Stride.Shaders.Parsing.Analysis; +using static Stride.Shaders.Spirv.Specification; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using CommunityToolkit.HighPerformance; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; +using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; + +namespace Stride.Shaders.Spirv.Processing.Interfaces +{ + /// + /// Help to process streams and simplify the interface (resources, methods, cbuffer) of the shader. + /// + public class InterfaceProcessor + { + public Action? CodeInserted { get; set; } + + public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); + + Symbol? ResolveEntryPoint(SymbolTable table, string name) + { + table.TryResolveSymbol(name, out var entryPoint); + return entryPoint?.Type switch + { + FunctionGroupType => entryPoint.GroupMembers[^1], + _ => entryPoint + }; + } + + public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) + { + var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); + + var entryPointVS = ResolveEntryPoint(table, "VSMain"); + var entryPointHS = ResolveEntryPoint(table, "HSMain"); + var entryPointDS = ResolveEntryPoint(table, "DSMain"); + var entryPointGS = ResolveEntryPoint(table, "GSMain"); + var entryPointPS = ResolveEntryPoint(table, "PSMain"); + var entryPointCS = ResolveEntryPoint(table, "CSMain"); + + var entryPointPSOrCS = entryPointCS ?? entryPointPS ?? throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: At least a pixel or compute shader is expected"); + if (entryPointPS == null && entryPointCS == null) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: Found both a pixel and a compute shader"); + + var analysisResult = StreamAnalyzer.Analyze(buffer, context); + VariableMerger.MergeSameSemanticVariables(table, context, buffer, analysisResult); + var streams = analysisResult.Streams; + + var liveAnalysis = new LiveAnalysis(); + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointPSOrCS.IdRef, analysisResult, liveAnalysis); + + if (entryPointCS != null) + { + (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); + entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); + } + + if (entryPointHS != null || entryPointDS != null) + context.Add(new OpCapability(Capability.Tessellation)); + else if (entryPointGS != null) + context.Add(new OpCapability(Capability.Geometry)); + + var inputAttributes = new List(); + + if (entryPointPS != null) + { + // If written to, they are expected at the end of pixel shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic) + { + if ((semantic.ToUpperInvariant().StartsWith("SV_TARGET") || semantic.ToUpperInvariant() == "SV_DEPTH") && stream.Value.Write) + stream.Value.Output = true; + } + } + + // Check if there is any output + // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) + if (streams.Any(x => x.Value.Output)) + { + (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); + entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); + + buffer.Add(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); + } + + // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic && (semantic.ToUpperInvariant() == "SV_COVERAGE" || semantic.ToUpperInvariant() == "SV_ISFRONTFACE" || semantic.ToUpperInvariant() == "VFACE")) + stream.Value.Read = false; + } + + // Reset cbuffer/resource/methods used for next stage + DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); + + VariableMerger.PropagateStreamsFromPreviousStage(streams); + + foreach (var entryPoint in new[] { (ExecutionModel.TessellationControl, entryPointHS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.Geometry, entryPointGS) }) + { + if (entryPoint.Item2 != null) + { + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); + + // Find patch constant entry point and process it as well + var patchConstantEntryPoint = entryPoint.Item1 == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint.Item2) : null; + if (patchConstantEntryPoint != null) + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); + + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic) + { + if (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + stream.Value.Output = true; + + if (entryPoint.Item1 == ExecutionModel.TessellationControl + && (semantic.ToUpperInvariant().StartsWith("SV_TESSFACTOR") || semantic.ToUpperInvariant().StartsWith("SV_INSIDETESSFACTOR"))) + stream.Value.Output = true; + } + } + + (var wrapperId, var wrapperName) = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); + var stage = entryPoint.Item1 switch + { + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + }; + entryPoints.Add((wrapperName, wrapperId, stage)); + + // Reset cbuffer/resource/methods used for next stage + DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); + + VariableMerger.PropagateStreamsFromPreviousStage(streams); + + if (entryPointVS == null) + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); + } + } + + if (entryPointVS != null) + { + ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); + + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader + foreach (var stream in streams) + { + if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + stream.Value.Output = true; + } + + (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); + entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); + + // Process shader input attributes + foreach (var stream in streams) + { + // Note: built-ins won't have a inputLayoutLocation so they will be skipped + if (stream.Value.Input && stream.Value.InputLayoutLocation is {} inputLayoutLocation) + { + if (stream.Value.Semantic == null) + throw new InvalidOperationException($"Vertex shader input {stream.Value.Name} doesn't have semantic"); + var semantic = SemanticAnalyzer.ParseSemantic(stream.Value.Semantic); + inputAttributes.Add(new ShaderInputAttributeDescription { Location = inputLayoutLocation, SemanticName = semantic.Name, SemanticIndex = semantic.Index }); + } + } + } + } + + // This will remove a lot of unused methods, resources and variables + // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) + DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); + + return new(entryPoints, inputAttributes); + } + + + static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) + { + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is + { + EntryPoint: var target, + Mode: ExecutionMode.OutputVertices, + ModeParameters: { } m, + } && target == entryPoint.IdRef) + { + return m.Span[0]; + } + } + + throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); + } + + private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) + { + var streams = analysisResult.Streams; + + var stage = executionModel switch + { + ExecutionModel.Vertex => "VS", + ExecutionModel.TessellationControl => "HS", + ExecutionModel.TessellationEvaluation => "DS", + ExecutionModel.Geometry => "GS", + ExecutionModel.Fragment => "PS", + ExecutionModel.GLCompute => "CS", + _ => throw new NotImplementedException() + }; + List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; + List entryPointExtraVariables = []; + + int inputLayoutLocationCount = 0; + int outputLayoutLocationCount = 0; + + foreach (var stream in streams) + { + if (stream.Value.Output) + { + if (stream.Value.OutputLayoutLocation is { } outputLayoutLocation) + { + outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); + } + } + } + + // Delegate to BuiltinProcessor + bool AddBuiltin(int variable, BuiltIn builtin) => BuiltinProcessor.AddBuiltin(context, variable, builtin); + + bool AddLocation(int variable, string location) => BuiltinProcessor.AddLocation(context, variable, location); + + int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) => + BuiltinProcessor.ConvertInterfaceVariable(buffer, context, sourceType, castType, value); + + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) => + BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variable, type, semantic, ref symbolType); + + var entryPointFunctionType = (FunctionType)entryPoint.Type; + // TODO: check all parameters instead of hardcoded 0 + int? arrayInputSize = executionModel switch + { + ExecutionModel.Geometry => ((ArrayType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, + ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation => ((PatchType)((PointerType)entryPointFunctionType.ParameterTypes[0].Type).BaseType).Size, + _ => null, + }; + int? arrayOutputSize = executionModel switch + { + ExecutionModel.TessellationControl => FindOutputPatchSize(context, entryPoint), + _ => null, + }; + + foreach (var stream in streams) + { + if (stream.Value.Input) + { + var variableId = context.Bound++; + var variableType = stream.Value.Type; + if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, stream.Value.Semantic, ref variableType)) + { + if (stream.Value.InputLayoutLocation == null) + stream.Value.InputLayoutLocation = inputLayoutLocationCount++; + context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); + } + + // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants + var streamInputType = new PointerType(!stream.Value.Patch && arrayInputSize != null + ? new ArrayType(variableType, arrayInputSize.Value) + : variableType, + Specification.StorageClass.Input); + var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); + context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); + + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) + context.Add(new OpDecorate(variable, Decoration.Flat, [])); + + stream.Value.InputId = variable.ResultId; + (stream.Value.Patch ? patchInputStreams : inputStreams).Add((stream.Value, variable.ResultId, variableType)); + } + + if (stream.Value.Output) + { + var variableId = context.Bound++; + var variableType = stream.Value.Type; + if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Output, stream.Value.Semantic, ref variableType)) + { + // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic + if (stream.Value.OutputLayoutLocation == null) + { + if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) + stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; + else + throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); + } + + context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); + if (stream.Value.Semantic != null) + context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); + } + + // Note: for geometry & tessellation shader, we process multiple inputs at once (in an array), except for patch constants + var streamOutputType = new PointerType(!stream.Value.Patch && arrayOutputSize != null + ? new ArrayType(variableType, arrayOutputSize.Value) + : variableType, + Specification.StorageClass.Output); + var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); + context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); + + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) + context.Add(new OpDecorate(variable, Decoration.Flat, [])); + + stream.Value.OutputId = variable.ResultId; + (stream.Value.Patch ? patchOutputStreams : outputStreams).Add((stream.Value, variable.ResultId, variableType)); + } + } + + var streamFields = new List(); + var constantFields = new List(); + var inputFields = new List(); + var outputFields = new List(); + foreach (var stream in streams) + { + stream.Value.InputStructFieldIndex = null; + stream.Value.OutputStructFieldIndex = null; + if (stream.Value.UsedThisStage) + { + var fields = (stream.Value.Patch) ? constantFields : streamFields; + stream.Value.StreamStructFieldIndex = fields.Count; + fields.Add(new(stream.Value.Name, stream.Value.Type, default)); + } + } + + foreach (var stream in inputStreams) + { + stream.Info.InputStructFieldIndex = inputFields.Count; + inputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); + } + + foreach (var stream in outputStreams) + { + stream.Info.OutputStructFieldIndex = outputFields.Count; + outputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); + } + + var inputType = new StructType($"{stage}_INPUT", inputFields); + var outputType = new StructType($"{stage}_OUTPUT", outputFields); + var streamsType = new StructType($"{stage}_STREAMS", streamFields); + bool hasConstants = executionModel is ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation; + var constantsType = hasConstants ? new StructType($"{stage}_CONSTANTS", constantFields) : null; + context.DeclareStructuredType(inputType, context.Bound++); + context.DeclareStructuredType(outputType, context.Bound++); + context.DeclareStructuredType(streamsType, context.Bound++); + if (hasConstants) + context.DeclareStructuredType(constantsType, context.Bound++); + + // Create a static global streams variable + var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); + context.AddName(streamsVariable.ResultId, $"streams{stage}"); + + // Find patch constant entry point + var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; + + // Patch any OpStreams/OpAccessChain to use the new struct + foreach (var method in liveAnalysis.ReferencedMethods) + { + if (method.Value.UsedThisStage && method.Value.HasStreamAccess) + { + MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); + StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + } + } + + // Generate entry point wrapper + var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper( + buffer, context, entryPoint, executionModel, stage, analysisResult, liveAnalysis, + inputStreams, outputStreams, patchInputStreams, patchOutputStreams, + inputFields, outputFields, inputType, outputType, streamsType, constantsType, + arrayInputSize, arrayOutputSize, streamsVariable.ResultId, patchConstantEntryPoint, + entryPointExtraVariables); + + // Move OpExecutionMode on new wrapper + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) + { + if (executionMode.EntryPoint == entryPoint.IdRef) + executionMode.EntryPoint = newEntryPointFunctionResultId; + } + } + + return (newEntryPointFunctionResultId, entryPointName); + } + + private Symbol? ResolveHullPatchConstantEntryPoint(SymbolTable table, SpirvContext context, Symbol entryPoint) + { + // Check if there's a patch constant function and call it when gl_InvocationID == 0 + string? patchConstantFuncName = null; + foreach (var i in context) + { + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is + { + Target: int target, + Decoration: Decoration.PatchConstantFuncSDSL, + Value: string funcName + } && target == entryPoint.IdRef) + { + patchConstantFuncName = funcName; + break; + } + } + + Symbol? patchConstantEntryPoint = null; + if (patchConstantFuncName != null) + { + // Resolve the patch constant function + patchConstantEntryPoint = ResolveEntryPoint(table, patchConstantFuncName); + if (patchConstantEntryPoint == null) + throw new InvalidOperationException($"Hull shader patch constant function {patchConstantFuncName} was not found"); + } + + return patchConstantEntryPoint; + } + } +} diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/AnalysisResult.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/LiveAnalysis.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/ResourceInfo.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/StreamVariableInfo.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Models/VariableInfo.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/MethodDuplicator.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs diff --git a/src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs similarity index 100% rename from src/Stride.Shaders/Spirv/Processing/InterfaceProcessorInternal/Transformation/StreamAccessPatcher.cs rename to src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs From 96b93887cfad0ec4a47749d72599be49f01dc24c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 6 Feb 2026 15:47:20 +0900 Subject: [PATCH 0788/1182] Fixes --- .../SDSL/ShaderMixer.cs | 1 + .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 4 +- .../Interfaces/Analysis/SemanticAnalyzer.cs | 2 +- .../Interfaces/Analysis/StreamAnalyzer.cs | 4 +- .../Interfaces/Cleanup/DeadCodeRemover.cs | 8 +- .../Interfaces/Cleanup/VariableMerger.cs | 4 +- .../Interfaces/Generation/BuiltinProcessor.cs | 4 +- .../Generation/EntryPointWrapperGenerator.cs | 26 +- .../Interfaces/InterfaceProcessor.cs | 249 ++++++++++-------- .../Interfaces/Models/AnalysisResult.cs | 2 +- .../Interfaces/Models/LiveAnalysis.cs | 2 +- .../Interfaces/Models/ResourceInfo.cs | 2 +- .../Interfaces/Models/StreamVariableInfo.cs | 2 +- .../Interfaces/Models/VariableInfo.cs | 2 +- .../Transformation/MethodDuplicator.cs | 4 +- .../Transformation/StreamAccessPatcher.cs | 4 +- 16 files changed, 169 insertions(+), 151 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index da398d3077..9dc61b62a5 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -25,6 +25,7 @@ using System.Runtime.InteropServices; using System.Text; using Stride.Core.Storage; +using Stride.Shaders.Spirv.Processing.Interfaces; using static Stride.Shaders.Spirv.Specification; using EntryPoint = Stride.Shaders.Core.EntryPoint; diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index c3982e14da..5339abc87e 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -3,10 +3,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Analysis; internal static class ReadWriteAnalyzer { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs index 8fb5c6066b..0fed074d1e 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Analysis; internal static class SemanticAnalyzer { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index 2fdcd5df01..b507678a49 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -2,10 +2,10 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Analysis; internal static class StreamAnalyzer { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 68be3a8d58..6c7264364a 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -2,11 +2,11 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Analysis; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Cleanup; /// /// Handles removal of unreferenced code including methods, variables, resources, and types. @@ -36,7 +36,7 @@ public static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalysi /// Removes unreferenced code including methods, variables, resources, cbuffers, and stream types. /// Preserves logical groups and resource groups where at least one member is used. /// - public static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, Dictionary streams, LiveAnalysis liveAnalysis) + public static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { // Remove unreferenced code var removedIds = new HashSet(); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs index 91413ce548..ff5a06f950 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs @@ -3,10 +3,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Cleanup; /// /// Handles merging of variables with the same semantic and propagating streams between shader stages. diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index 373a0b3aad..2b9beade7e 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -2,10 +2,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Generation; /// /// Handles processing of builtin variables and semantics (SV_*). diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 9236526a51..1e716b7e2a 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -4,27 +4,23 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Generation; internal static class EntryPointWrapperGenerator { - public static (int ResultId, string Name) GenerateWrapper( + public static (int ResultId, string Name) GenerateWrapper(SpirvContext context, NewSpirvBuffer buffer, - SpirvContext context, Symbol entryPoint, ExecutionModel executionModel, - string stage, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, - List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> inputStreams, List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams, List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams, - List inputFields, - List outputFields, StructType inputType, StructType outputType, StructType streamsType, @@ -32,8 +28,7 @@ public static (int ResultId, string Name) GenerateWrapper( int? arrayInputSize, int? arrayOutputSize, int streamsVariableId, - Symbol? patchConstantEntryPoint, - List entryPointExtraVariables) + Symbol? patchConstantEntryPoint) { var entryPointFunctionType = (FunctionType)entryPoint.Type; var voidType = context.GetOrRegister(ScalarType.Void); @@ -65,6 +60,7 @@ public static (int ResultId, string Name) GenerateWrapper( entryPointFunctionType = (FunctionType)entryPoint.Type; var builtinVariables = new Dictionary(); + var entryPointExtraVariables = new List(); int GetOrDeclareBuiltInValue(SymbolType type, string semantic) { @@ -131,15 +127,15 @@ void FillSemanticArguments(FunctionType functionType, Span arguments) int ConvertInputsArray() { - Span inputLoadValues = stackalloc int[inputFields.Count]; + Span inputLoadValues = stackalloc int[inputType.Members.Count]; for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) { var stream = inputStreams[inputIndex]; - var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.InterfaceId, null, [])); + var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.Id, null, [])); inputLoadValues[inputIndex] = loadedValue.ResultId; } - Span inputFieldValues = stackalloc int[inputFields.Count]; + Span inputFieldValues = stackalloc int[inputType.Members.Count]; Span inputValues = stackalloc int[arrayInputSize.Value]; for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) { @@ -385,7 +381,7 @@ void ProcessTessellationArguments(Symbol function, Span arguments) foreach (var stream in inputStreams) { var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.InterfaceId, null, [])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.Id, null, [])).ResultId; inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); buffer.Add(new OpStore(streamPointer, inputResult, null, [])); } @@ -411,7 +407,7 @@ void ProcessTessellationArguments(Symbol function, Span arguments) Span entryPointInterfaceVariables = stackalloc int[inputStreams.Count + outputStreams.Count + patchInputStreams.Count + patchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; int pvariableIndex = 0; foreach (var inputStream in inputStreams) - entryPointInterfaceVariables[pvariableIndex++] = inputStream.InterfaceId; + entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; foreach (var outputStream in outputStreams) entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; foreach (var inputStream in patchInputStreams) diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs index ebf2d41af6..99b63e404e 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -10,11 +10,11 @@ using System.Text.RegularExpressions; using CommunityToolkit.HighPerformance; using Stride.Shaders.Parsing.SDSL.AST; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Analysis; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Cleanup; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Generation; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Analysis; +using Stride.Shaders.Spirv.Processing.Interfaces.Cleanup; +using Stride.Shaders.Spirv.Processing.Interfaces.Transformation; +using Stride.Shaders.Spirv.Processing.Interfaces.Generation; namespace Stride.Shaders.Spirv.Processing.Interfaces { @@ -181,7 +181,7 @@ public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext con // This will remove a lot of unused methods, resources and variables // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) - DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, streams, liveAnalysis); + DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, liveAnalysis); return new(entryPoints, inputAttributes); } @@ -209,37 +209,10 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) { var streams = analysisResult.Streams; - var stage = executionModel switch - { - ExecutionModel.Vertex => "VS", - ExecutionModel.TessellationControl => "HS", - ExecutionModel.TessellationEvaluation => "DS", - ExecutionModel.Geometry => "GS", - ExecutionModel.Fragment => "PS", - ExecutionModel.GLCompute => "CS", - _ => throw new NotImplementedException() - }; - List<(StreamVariableInfo Info, int InterfaceId, SymbolType InterfaceType)> inputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams = []; - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams = []; - List entryPointExtraVariables = []; + var stage = ExecutionModelToStageId(executionModel); - int inputLayoutLocationCount = 0; - int outputLayoutLocationCount = 0; - foreach (var stream in streams) - { - if (stream.Value.Output) - { - if (stream.Value.OutputLayoutLocation is { } outputLayoutLocation) - { - outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); - } - } - } - // Delegate to BuiltinProcessor bool AddBuiltin(int variable, BuiltIn builtin) => BuiltinProcessor.AddBuiltin(context, variable, builtin); bool AddLocation(int variable, string location) => BuiltinProcessor.AddLocation(context, variable, location); @@ -247,9 +220,6 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) => BuiltinProcessor.ConvertInterfaceVariable(buffer, context, sourceType, castType, value); - bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) => - BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variable, type, semantic, ref symbolType); - var entryPointFunctionType = (FunctionType)entryPoint.Type; // TODO: check all parameters instead of hardcoded 0 int? arrayInputSize = executionModel switch @@ -263,7 +233,131 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se ExecutionModel.TessellationControl => FindOutputPatchSize(context, entryPoint), _ => null, }; + + // Generate stream variables + GenerateStreamVariables(context, executionModel, streams, arrayInputSize, arrayOutputSize, out var inputStreams, out var outputStreams, out var patchInputStreams, out var patchOutputStreams); + + // Generate streams struct types (i.e. VS_STREAMS VS_INPUT and VS_OUTPUT) + GenerateStreamStructTypes(context, executionModel, streams, inputStreams, outputStreams, out var inputType, out var outputType, out var streamsType, out var constantsType); + + // Create a static global streams variable + var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); + context.AddName(streamsVariable.ResultId, $"streams{stage}"); + + // Find patch constant entry point + var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; + + // Patch any OpStreams/OpAccessChain to use the new struct + foreach (var method in liveAnalysis.ReferencedMethods) + { + if (method.Value.UsedThisStage && method.Value.HasStreamAccess) + { + MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); + StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + } + } + + // Generate entry point wrapper + var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper(context, + buffer, entryPoint, executionModel, analysisResult, + liveAnalysis, inputStreams, outputStreams, patchInputStreams, + patchOutputStreams, inputType, outputType, streamsType, + constantsType, arrayInputSize, arrayOutputSize, streamsVariable.ResultId, + patchConstantEntryPoint); + + // Move OpExecutionMode on new wrapper + foreach (var i in context) + { + if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) + { + if (executionMode.EntryPoint == entryPoint.IdRef) + executionMode.EntryPoint = newEntryPointFunctionResultId; + } + } + + return (newEntryPointFunctionResultId, entryPointName); + } + + private static string ExecutionModelToStageId(ExecutionModel executionModel) + { + return executionModel switch + { + ExecutionModel.Vertex => "VS", + ExecutionModel.TessellationControl => "HS", + ExecutionModel.TessellationEvaluation => "DS", + ExecutionModel.Geometry => "GS", + ExecutionModel.Fragment => "PS", + ExecutionModel.GLCompute => "CS", + _ => throw new NotImplementedException() + }; + } + + private static void GenerateStreamStructTypes(SpirvContext context, ExecutionModel executionModel, Dictionary streams, List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> inputStreams, List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, out StructType inputType, out StructType outputType, out StructType streamsType, out StructType? constantsType) + { + var streamFields = new List(); + var constantFields = new List(); + var inputFields = new List(); + var outputFields = new List(); + foreach (var stream in streams) + { + stream.Value.InputStructFieldIndex = null; + stream.Value.OutputStructFieldIndex = null; + if (stream.Value.UsedThisStage) + { + var fields = (stream.Value.Patch) ? constantFields : streamFields; + stream.Value.StreamStructFieldIndex = fields.Count; + fields.Add(new(stream.Value.Name, stream.Value.Type, default)); + } + } + + // Build input/output types + foreach (var stream in inputStreams) + { + stream.Info.InputStructFieldIndex = inputFields.Count; + inputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); + } + + foreach (var stream in outputStreams) + { + stream.Info.OutputStructFieldIndex = outputFields.Count; + outputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); + } + + var stage = ExecutionModelToStageId(executionModel); + + inputType = new StructType($"{stage}_INPUT", inputFields); + outputType = new StructType($"{stage}_OUTPUT", outputFields); + streamsType = new StructType($"{stage}_STREAMS", streamFields); + bool hasConstants = executionModel is ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation; + constantsType = hasConstants ? new StructType($"{stage}_CONSTANTS", constantFields) : null; + context.DeclareStructuredType(inputType, context.Bound++); + context.DeclareStructuredType(outputType, context.Bound++); + context.DeclareStructuredType(streamsType, context.Bound++); + if (hasConstants) + context.DeclareStructuredType(constantsType, context.Bound++); + } + + private static void GenerateStreamVariables(SpirvContext context, ExecutionModel executionModel, Dictionary streams, int? arrayInputSize, int? arrayOutputSize, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> inputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams) + { + int inputLayoutLocationCount = 0; + int outputLayoutLocationCount = 0; + foreach (var stream in streams) + { + if (stream.Value.Output) + { + if (stream.Value.OutputLayoutLocation is { } outputLayoutLocation) + { + outputLayoutLocationCount = Math.Max(outputLayoutLocation + 1, outputLayoutLocationCount); + } + } + } + inputStreams = []; + outputStreams = []; + patchInputStreams = []; + patchOutputStreams = []; + + var stage = ExecutionModelToStageId(executionModel); foreach (var stream in streams) { if (stream.Value.Input) @@ -286,7 +380,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se Specification.StorageClass.Input); var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); @@ -321,7 +415,7 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se Specification.StorageClass.Output); var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); @@ -330,81 +424,8 @@ bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? se } } - var streamFields = new List(); - var constantFields = new List(); - var inputFields = new List(); - var outputFields = new List(); - foreach (var stream in streams) - { - stream.Value.InputStructFieldIndex = null; - stream.Value.OutputStructFieldIndex = null; - if (stream.Value.UsedThisStage) - { - var fields = (stream.Value.Patch) ? constantFields : streamFields; - stream.Value.StreamStructFieldIndex = fields.Count; - fields.Add(new(stream.Value.Name, stream.Value.Type, default)); - } - } - - foreach (var stream in inputStreams) - { - stream.Info.InputStructFieldIndex = inputFields.Count; - inputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); - } - - foreach (var stream in outputStreams) - { - stream.Info.OutputStructFieldIndex = outputFields.Count; - outputFields.Add(new(stream.Info.Name, stream.Info.Type, default)); - } - - var inputType = new StructType($"{stage}_INPUT", inputFields); - var outputType = new StructType($"{stage}_OUTPUT", outputFields); - var streamsType = new StructType($"{stage}_STREAMS", streamFields); - bool hasConstants = executionModel is ExecutionModel.TessellationControl or ExecutionModel.TessellationEvaluation; - var constantsType = hasConstants ? new StructType($"{stage}_CONSTANTS", constantFields) : null; - context.DeclareStructuredType(inputType, context.Bound++); - context.DeclareStructuredType(outputType, context.Bound++); - context.DeclareStructuredType(streamsType, context.Bound++); - if (hasConstants) - context.DeclareStructuredType(constantsType, context.Bound++); - - // Create a static global streams variable - var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); - context.AddName(streamsVariable.ResultId, $"streams{stage}"); - - // Find patch constant entry point - var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; - - // Patch any OpStreams/OpAccessChain to use the new struct - foreach (var method in liveAnalysis.ReferencedMethods) - { - if (method.Value.UsedThisStage && method.Value.HasStreamAccess) - { - MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); - StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); - } - } - - // Generate entry point wrapper - var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper( - buffer, context, entryPoint, executionModel, stage, analysisResult, liveAnalysis, - inputStreams, outputStreams, patchInputStreams, patchOutputStreams, - inputFields, outputFields, inputType, outputType, streamsType, constantsType, - arrayInputSize, arrayOutputSize, streamsVariable.ResultId, patchConstantEntryPoint, - entryPointExtraVariables); - - // Move OpExecutionMode on new wrapper - foreach (var i in context) - { - if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) - { - if (executionMode.EntryPoint == entryPoint.IdRef) - executionMode.EntryPoint = newEntryPointFunctionResultId; - } - } - - return (newEntryPointFunctionResultId, entryPointName); + bool ProcessBuiltinsDecoration(int variable, StreamVariableType type, string? semantic, ref SymbolType symbolType) => + BuiltinProcessor.ProcessBuiltinsDecoration(context, executionModel, variable, type, semantic, ref symbolType); } private Symbol? ResolveHullPatchConstantEntryPoint(SymbolTable table, SpirvContext context, Symbol entryPoint) diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs index fedb1a7ca1..25f64a4b36 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; internal record struct AnalysisResult( Dictionary Names, diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs index fc1be1787d..40b48930bd 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs @@ -1,7 +1,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; internal class MethodInfo { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs index 37c1b0dad2..37f1eff8d0 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs @@ -1,4 +1,4 @@ -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; internal class ResourceInfo(string name) { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs index 084f39684c..f41976db0f 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs @@ -1,6 +1,6 @@ using Stride.Shaders.Core; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; internal enum StreamVariableType { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs index 077c859597..7a2caaa459 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs @@ -1,6 +1,6 @@ using Stride.Shaders.Core; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; internal class VariableInfo(string name, PointerType type, int variableId) { diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs index b2b488fa91..6ad73478ad 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs @@ -2,10 +2,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Transformation; /// /// Handles duplication of methods for different shader stages. diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 468d5ff048..49722ad8ec 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -3,10 +3,10 @@ using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Models; using static Stride.Shaders.Spirv.Specification; -namespace Stride.Shaders.Spirv.Processing.InterfaceProcessorInternal.Transformation; +namespace Stride.Shaders.Spirv.Processing.Interfaces.Transformation; /// /// Handles patching of SPIR-V stream access instructions. From c86cb26d0f5860e2caa479f1270031f1b7a47ce1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Feb 2026 12:37:03 +0900 Subject: [PATCH 0789/1182] Reorganized SymbolType visitor generator to also work on Node --- .../TypeVisitorGenerator.cs | 327 --------------- .../VisitorGenerator.cs | 391 ++++++++++++++++++ .../Core/SymbolTypes.Visitors.cs | 22 +- src/Stride.Shaders/Core/SymbolTypes.cs | 6 +- 4 files changed, 405 insertions(+), 341 deletions(-) delete mode 100644 src/Stride.Shaders.Generators/TypeVisitorGenerator.cs create mode 100644 src/Stride.Shaders.Generators/VisitorGenerator.cs diff --git a/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs b/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs deleted file mode 100644 index 954f4e398d..0000000000 --- a/src/Stride.Shaders.Generators/TypeVisitorGenerator.cs +++ /dev/null @@ -1,327 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; - -namespace Stride.Shaders.Spirv.Generators -{ - [Generator] - internal class TypeVisitorGenerator : IIncrementalGenerator - { - public void Initialize(IncrementalGeneratorInitializationContext context) - { - context.RegisterImplementationSourceOutput( - context.CompilationProvider, GenerateVisitors); - } - - private void GenerateVisitors(SourceProductionContext context, Compilation compilation) - { - var classVisitor = new SymbolTypeClassFinder(); - classVisitor.Visit(compilation.GlobalNamespace); - - var symbolTypes = classVisitor.SymbolTypes; - - var sb = new StringBuilder(); - - var typeAndGenericFormat = new SymbolDisplayFormat(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameOnly, SymbolDisplayGenericsOptions.IncludeTypeParameters); - - // Source: Stride old shader system VisitorGenerated.tt preprocessed with RuntimeTextTemplate1.tt and linePragmas="false" - sb.Append("namespace" + - " Stride.Shaders.Core\r\n{\r\n public partial class TypeVisitor" + - "\r\n {\r\n"); - foreach (var type in symbolTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - - var returnType = type.IsValueType ? "bool" : "TResult"; - sb.AppendLine($" public virtual {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); - sb.AppendLine("{"); - if (type.IsValueType) - sb.AppendLine($"return DefaultVisit(ref {variableName});"); - else - sb.AppendLine($"return DefaultVisit({variableName});"); - sb.AppendLine("}"); - } - sb.Append(" }\r\n\r\n public partial class TypeRewriter\r\n {\r\n"); - foreach (var type in symbolTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - - var returnType = type.IsValueType ? "bool" : "SymbolType"; - sb.AppendLine($" public override {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); - sb.AppendLine("{"); - // Process public fields and properties (with getter+setter) - var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); - foreach (var member in GetNodeMembers(type)) - { - var memberType = GetSymbolType(member); - var memberTypeName = memberType.ToDisplayString(); - var memberVariableName = member.Name.First().ToString().ToLower() + member.Name.Substring(1) + "Temp"; - var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && IsSymbolType(x.TypeArguments[0]))?.TypeArguments[0]; - var isNode = IsSymbolType(memberType); - if (isNode) - { - sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(memberType.IsValueType ? "Node" : "Type")}({variableName}.{member.Name});"); - sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); - sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); - } - else if (nodeListElementType != null) - { - sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(nodeListElementType.IsValueType ? "Node" : "Type")}List({variableName}.{member.Name});"); - sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); - sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); - } - } - if (type.IsValueType) - { - sb.AppendLine($" return base.Visit{genericParameters}(ref {variableName});"); - } - else - { - sb.AppendLine($" return (SymbolType)base.Visit{genericParameters}({variableName});"); - } - sb.Append("}\r\n"); - } - sb.Append(" }\r\n\r\n public partial class TypeVisitor\r\n {\r\n"); - foreach (var type in symbolTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - - sb.Append(" public virtual void Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(typeName); - sb.Append(" "); - sb.Append(variableName); - sb.Append(")\r\n {\r\n DefaultVisit("); - sb.Append(variableName); - sb.Append(");\r\n }\r\n"); - } - sb.Append(" }\r\n\r\n public partial class TypeWalker\r\n {\r\n"); - foreach (var type in symbolTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - - sb.Append(" public override void Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(typeName); - sb.Append(" "); - sb.Append(variableName); - sb.Append(")\r\n {\r\n"); - // Process public fields and properties (with getter+setter) - var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); - foreach (var member in GetNodeMembers(type)) - { - var memberType = GetSymbolType(member); - var memberTypeName = memberType.ToDisplayString(); - var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && IsSymbolType(x.TypeArguments[0]))?.TypeArguments[0]; - var isNode = IsSymbolType(memberType); - if (isNode) - { - sb.Append($" Visit{(memberType.IsValueType ? "Node" : "Type")}("); - sb.Append(variableName); - sb.Append("."); - sb.Append(member.Name); - sb.Append(");\r\n"); - } - else if (nodeListElementType != null) - { - sb.Append($" Visit{(nodeListElementType.IsValueType ? "Node" : "Type")}List("); - sb.Append(variableName); - sb.Append("."); - sb.Append(member.Name); - sb.Append(");\r\n"); - } - } - sb.Append(" base.Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(variableName); - sb.Append(");\r\n }\r\n"); - } - sb.Append(" }\r\n}\r\n\r\n"); - - foreach (var type in symbolTypes) - { - sb.Append("namespace "); - sb.Append(type.ContainingNamespace.ToDisplayString()); - sb.AppendLine("{"); - sb.AppendLine("public partial record"); - if (type.IsValueType) - sb.Append("struct "); - sb.Append(type.ToDisplayString(typeAndGenericFormat)); - sb.Append(@$" - {{ - public {(!type.IsValueType ? "override" : string.Empty)} void Accept(TypeVisitor visitor) - {{"); - sb.AppendLine("visitor.Visit(this);"); - sb.AppendLine("}"); - if (type.IsValueType) - { - sb.AppendLine("public bool Accept(TypeVisitor visitor)"); - sb.AppendLine("{"); - sb.AppendLine("return visitor.Visit(ref this);"); - } - else - { - sb.AppendLine("public override TResult Accept(TypeVisitor visitor)"); - sb.AppendLine("{"); - sb.AppendLine("return visitor.Visit(this);"); - } - sb.AppendLine("} } }"); - } - sb.AppendLine(); - - context.AddSource("TypeVisitors.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(sb.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - } - - private static IEnumerable GetNodeTypes(INamedTypeSymbol symbol) - { - while (symbol != null && IsSymbolType(symbol)) - { - yield return symbol; - symbol = symbol.BaseType; - } - } - - private static IEnumerable GetNodeMembers(INamedTypeSymbol nodeType) - { - foreach (var currentNodeType in GetNodeTypes(nodeType).Reverse()) - { - foreach (var member in currentNodeType.GetMembers().Where(CanVisitMember)) - yield return member; - } - } - - private static bool CanVisitMember(ISymbol symbol) - { - if (symbol.DeclaredAccessibility != Accessibility.Public || symbol.IsStatic) - return false; - - if (symbol.GetAttributes().Any(x => x.AttributeClass.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) - return false; - - if (symbol.Kind == SymbolKind.Field) - { - var field = (IFieldSymbol)symbol; - if (field.IsReadOnly) - return false; - - return true; - } - - if (symbol.Kind == SymbolKind.Property) - { - var property = (IPropertySymbol)symbol; - if (property.IsReadOnly || property.IsWriteOnly || property.IsIndexer) - return false; - - if (property.GetMethod.DeclaredAccessibility != Accessibility.Public - || property.SetMethod.DeclaredAccessibility != Accessibility.Public) - return false; - - return true; - } - - return false; - } - - private static bool IsSymbolType(ITypeSymbol type) - { - if (GetBaseTypesAndThis(type).Any(t => t.ToDisplayString() == "Stride.Shaders.Core.SymbolType")) - return true; - - if (type.IsValueType && type.Interfaces.Any(t => t.ToDisplayString() == "Stride.Shaders.Core.ISymbolTypeNode")) - return true; - - return false; - } - - private static IEnumerable GetBaseTypesAndThis(ITypeSymbol type) - { - var current = type; - while (current != null) - { - yield return current; - current = current.BaseType; - } - } - - private static ITypeSymbol GetSymbolType(ISymbol symbol) - { - var localSymbol = symbol as ILocalSymbol; - if (localSymbol != null) - { - return localSymbol.Type; - } - - var fieldSymbol = symbol as IFieldSymbol; - if (fieldSymbol != null) - { - return fieldSymbol.Type; - } - - var propertySymbol = symbol as IPropertySymbol; - if (propertySymbol != null) - { - return propertySymbol.Type; - } - - var parameterSymbol = symbol as IParameterSymbol; - if (parameterSymbol != null) - { - return parameterSymbol.Type; - } - - var aliasSymbol = symbol as IAliasSymbol; - if (aliasSymbol != null) - { - return aliasSymbol.Target as ITypeSymbol; - } - - return symbol as ITypeSymbol; - } - - - class SymbolTypeClassFinder : SymbolVisitor - { - public List SymbolTypes = new List(); - - public override void VisitNamedType(INamedTypeSymbol symbol) - { - if (IsSymbolType(symbol) && !symbol.IsAbstract) - SymbolTypes.Add(symbol); - } - - public override void VisitNamespace(INamespaceSymbol symbol) - { - foreach (var childSymbol in symbol.GetMembers()) - { - //We must implement the visitor pattern ourselves and - //accept the child symbols in order to visit their children - childSymbol.Accept(this); - } - } - } - } -} diff --git a/src/Stride.Shaders.Generators/VisitorGenerator.cs b/src/Stride.Shaders.Generators/VisitorGenerator.cs new file mode 100644 index 0000000000..cfa3f528b7 --- /dev/null +++ b/src/Stride.Shaders.Generators/VisitorGenerator.cs @@ -0,0 +1,391 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Text; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; + +namespace Stride.Shaders.Spirv.Generators +{ + [Generator] + internal class VisitorGenerator : IIncrementalGenerator + { + public void Initialize(IncrementalGeneratorInitializationContext context) + { + context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateTypeVisitors); + //context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateNodeVisitors); + } + + private void GenerateTypeVisitors(SourceProductionContext context, Compilation compilation) + { + GenerateVisitorsBase(context, compilation, true, "Type", IsSymbolType); + } + + private void GenerateNodeVisitors(SourceProductionContext context, Compilation compilation) + { + GenerateVisitorsBase(context, compilation, false, "Node", IsNodeType); + } + + private string GenerateVariableName(string name) + { + var variableName = name.First().ToString().ToLower() + name.Substring(1); + if (variableName is "if" or "else" or "continue" or "while" or "return" or "break" or "for") + variableName = "@" + variableName; + + return variableName; + } + + private void GenerateVisitorsBase(SourceProductionContext context, Compilation compilation, bool generateRewriter, string visitorName, Func isNodeType) + { + var classVisitor = new NodeTypeClassFinder(isNodeType); + classVisitor.Visit(compilation.GlobalNamespace); + + var symbolTypes = classVisitor.SymbolTypes; + + var sb = new StringBuilder(); + + var typeAndGenericFormat = new SymbolDisplayFormat(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameOnly, SymbolDisplayGenericsOptions.IncludeTypeParameters); + + // Source: Stride old shader system VisitorGenerated.tt preprocessed with RuntimeTextTemplate1.tt and linePragmas="false" + sb.AppendLine("using Stride.Shaders.Core;"); + sb.AppendLine("namespace Stride.Shaders.Core"); + sb.AppendLine("{"); + sb.Append($" public partial class {visitorName}Visitor"); + sb.AppendLine(" {"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = GenerateVariableName(type.Name); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + sb.Append(" public virtual void Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(typeName); + sb.Append(" "); + sb.Append(variableName); + sb.Append(")\r\n {\r\n DefaultVisit("); + sb.Append(variableName); + sb.Append(");\r\n }\r\n"); + } + sb.Append($" }}\r\n\r\n public partial class {visitorName}Walker\r\n {{\r\n"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = GenerateVariableName(type.Name); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + sb.Append(" public override void Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(typeName); + sb.Append(" "); + sb.Append(variableName); + sb.Append(")\r\n {\r\n"); + // Process public fields and properties (with getter+setter) + var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); + foreach (var member in GetNodeMembers(type, isNodeType)) + { + var memberType = GetSymbolType(member); + var memberTypeName = memberType.ToDisplayString(); + var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && isNodeType(x.TypeArguments[0]))?.TypeArguments[0]; + var isNode = isNodeType(memberType); + if (isNode) + { + sb.Append($" Visit{(memberType.IsValueType ? "Item" : visitorName)}("); + sb.Append(variableName); + sb.Append("."); + sb.Append(member.Name); + sb.Append(");\r\n"); + } + else if (nodeListElementType != null) + { + sb.Append($" Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List("); + sb.Append(variableName); + sb.Append("."); + sb.Append(member.Name); + sb.Append(");\r\n"); + } + } + sb.Append(" base.Visit"); + sb.Append(genericParameters); + sb.Append("("); + sb.Append(variableName); + sb.Append(");\r\n }\r\n"); + } + + sb.AppendLine(" }"); + + if (generateRewriter) + { + sb.AppendLine($" public partial class {visitorName}Visitor"); + sb.AppendLine(" {"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = GenerateVariableName(type.Name); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + if (variableName is "if" or "else" or "continue" or "while" or "return" or "break" or "for") + { + variableName = "@" + variableName; + } + + var returnType = type.IsValueType ? "bool" : "TResult"; + sb.AppendLine($" public virtual {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine("{"); + if (type.IsValueType) + sb.AppendLine($"return DefaultVisit(ref {variableName});"); + else + sb.AppendLine($"return DefaultVisit({variableName});"); + sb.AppendLine("}"); + } + + sb.AppendLine(" }"); + + sb.AppendLine($" public partial class {visitorName}Rewriter"); + sb.AppendLine(" {"); + foreach (var type in symbolTypes) + { + var typeName = type.ToDisplayString(); + var variableName = GenerateVariableName(type.Name); + var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; + + var returnType = type.IsValueType ? "bool" : "SymbolType"; + sb.AppendLine($" public override {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine("{"); + // Process public fields and properties (with getter+setter) + var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); + foreach (var member in GetNodeMembers(type, isNodeType)) + { + var memberType = GetSymbolType(member); + var memberTypeName = memberType.ToDisplayString(); + var memberVariableName = GenerateVariableName(member.Name + "Temp"); + var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && isNodeType(x.TypeArguments[0]))?.TypeArguments[0]; + var isNode = isNodeType(memberType); + if (isNode) + { + sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(memberType.IsValueType ? "Item" : visitorName)}({variableName}.{member.Name});"); + sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); + sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + } + else if (nodeListElementType != null) + { + sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List({variableName}.{member.Name});"); + sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); + sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + } + } + if (type.IsValueType) + { + sb.AppendLine($" return base.Visit{genericParameters}(ref {variableName});"); + } + else + { + sb.AppendLine($" return (SymbolType)base.Visit{genericParameters}({variableName});"); + } + sb.Append("}\r\n"); + } + + sb.AppendLine(" }"); + } + + sb.AppendLine("}"); + + foreach (var type in symbolTypes) + { + sb.Append("namespace "); + sb.Append(type.ContainingNamespace.ToDisplayString()); + sb.AppendLine("{"); + + var typeKind = (type.IsRecord, type.IsValueType) switch + { + (true, true) => "record struct", + (true, false) => "record", + (false, true) => "struct", + (false, false) => "class", + }; + + sb.AppendLine($"public partial {typeKind}"); + sb.Append(type.ToDisplayString(typeAndGenericFormat)); + sb.Append(@$" + {{ + public {(!type.IsValueType ? "override" : string.Empty)} void Accept({visitorName}Visitor visitor) + {{"); + sb.AppendLine("visitor.Visit(this);"); + sb.AppendLine("}"); + if (generateRewriter) + { + if (type.IsValueType) + { + sb.AppendLine($"public bool Accept({visitorName}Visitor visitor)"); + sb.AppendLine("{"); + sb.AppendLine("return visitor.Visit(ref this);"); + sb.AppendLine("}"); + } + else + { + sb.AppendLine($"public override TResult Accept({visitorName}Visitor visitor)"); + sb.AppendLine("{"); + sb.AppendLine("return visitor.Visit(this);"); + sb.AppendLine("}"); + } + } + + sb.AppendLine("} }"); + } + sb.AppendLine(); + + context.AddSource($"{visitorName}Visitors.gen.cs", + SourceText.From( + SyntaxFactory + .ParseCompilationUnit(sb.ToString()) + .NormalizeWhitespace() + .ToFullString(), + Encoding.UTF8 + ) + ); + } + + private static IEnumerable GetNodeTypes(INamedTypeSymbol symbol, Func isNodeType) + { + while (symbol != null && isNodeType(symbol)) + { + yield return symbol; + symbol = symbol.BaseType; + } + } + + private static IEnumerable GetNodeMembers(INamedTypeSymbol nodeType, Func isNodeType) + { + foreach (var currentNodeType in GetNodeTypes(nodeType, isNodeType).Reverse()) + { + foreach (var member in currentNodeType.GetMembers().Where(CanVisitMember)) + yield return member; + } + } + + private static bool CanVisitMember(ISymbol symbol) + { + if (symbol.DeclaredAccessibility != Accessibility.Public || symbol.IsStatic) + return false; + + if (symbol.GetAttributes().Any(x => x.AttributeClass.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) + return false; + + if (symbol.Kind == SymbolKind.Field) + { + var field = (IFieldSymbol)symbol; + if (field.IsReadOnly) + return false; + + return true; + } + + if (symbol.Kind == SymbolKind.Property) + { + var property = (IPropertySymbol)symbol; + if (property.IsReadOnly || property.IsWriteOnly || property.IsIndexer) + return false; + + if (property.GetMethod == null || property.SetMethod == null) + return false; + + if (property.GetMethod.DeclaredAccessibility != Accessibility.Public + || property.SetMethod.DeclaredAccessibility != Accessibility.Public) + return false; + + return true; + } + + return false; + } + + private static bool IsSymbolType(ITypeSymbol type) + { + if (GetBaseTypesAndThis(type).Any(t => t.ToDisplayString() == "Stride.Shaders.Core.SymbolType")) + return true; + + if (type.IsValueType && type.Interfaces.Any(t => t.ToDisplayString() == "Stride.Shaders.Core.ISymbolTypeItem")) + return true; + + return false; + } + + private static bool IsNodeType(ITypeSymbol type) + { + if (GetBaseTypesAndThis(type).Any(t => t.ToDisplayString() == "Stride.Shaders.Parsing.Node")) + return true; + + return false; + } + + private static IEnumerable GetBaseTypesAndThis(ITypeSymbol type) + { + var current = type; + while (current != null) + { + yield return current; + current = current.BaseType; + } + } + + private static ITypeSymbol GetSymbolType(ISymbol symbol) + { + var localSymbol = symbol as ILocalSymbol; + if (localSymbol != null) + { + return localSymbol.Type; + } + + var fieldSymbol = symbol as IFieldSymbol; + if (fieldSymbol != null) + { + return fieldSymbol.Type; + } + + var propertySymbol = symbol as IPropertySymbol; + if (propertySymbol != null) + { + return propertySymbol.Type; + } + + var parameterSymbol = symbol as IParameterSymbol; + if (parameterSymbol != null) + { + return parameterSymbol.Type; + } + + var aliasSymbol = symbol as IAliasSymbol; + if (aliasSymbol != null) + { + return aliasSymbol.Target as ITypeSymbol; + } + + return symbol as ITypeSymbol; + } + + + class NodeTypeClassFinder(Func isNodeType) : SymbolVisitor + { + public List SymbolTypes = new(); + + public override void VisitNamedType(INamedTypeSymbol symbol) + { + if (isNodeType(symbol) && !symbol.IsAbstract) + SymbolTypes.Add(symbol); + } + + public override void VisitNamespace(INamespaceSymbol symbol) + { + foreach (var childSymbol in symbol.GetMembers()) + { + //We must implement the visitor pattern ourselves and + //accept the child symbols in order to visit their children + childSymbol.Accept(this); + } + } + } + } +} diff --git a/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs index 73e044991d..4bcd2044bc 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs @@ -2,13 +2,13 @@ namespace Stride.Shaders.Core; public abstract partial class TypeVisitor { - protected virtual void VisitNodeList(List list) where T : ISymbolTypeNode + protected virtual void VisitItemList(List list) where T : ISymbolTypeItem { foreach (var item in list) - VisitNode(item); + VisitItem(item); } - protected virtual void VisitTypeList(List list) where T : ShaderSymbol + protected virtual void VisitTypeList(List list) where T : SymbolType { foreach (var item in list) VisitType(item); @@ -18,7 +18,7 @@ public virtual void DefaultVisit(SymbolType type) { } - public void DefaultVisit(T node) where T : struct, ISymbolTypeNode + public void DefaultVisit(T item) where T : struct, ISymbolTypeItem { } @@ -27,9 +27,9 @@ public virtual void VisitType(SymbolType type) type?.Accept(this); } - public virtual void VisitNode(T node) where T : ISymbolTypeNode + public virtual void VisitItem(T item) where T : ISymbolTypeItem { - node?.Accept(this); + item?.Accept(this); } } @@ -44,7 +44,7 @@ public virtual TResult DefaultVisit(SymbolType node) return default; } - public virtual bool DefaultVisit(ref T node) where T : struct, ISymbolTypeNode + public virtual bool DefaultVisit(ref T item) where T : struct, ISymbolTypeItem { return true; } @@ -54,9 +54,9 @@ public virtual TResult VisitType(SymbolType type) return type.Accept(this); } - public virtual bool VisitNode(ref T node) where T : struct, ISymbolTypeNode + public virtual bool VisitItem(ref T item) where T : struct, ISymbolTypeItem { - return node.Accept(this); + return item.Accept(this); } } @@ -94,7 +94,7 @@ protected List VisitTypeList(List list) where T : SymbolType return newList ?? list; } - protected List VisitNodeList(List list) where T : struct, ISymbolTypeNode + protected List VisitItemList(List list) where T : struct, ISymbolTypeItem { var equalityComparer = EqualityComparer.Default; @@ -102,7 +102,7 @@ protected List VisitNodeList(List list) where T : struct, ISymbolTypeNo for (int i = 0; i < list.Count; ++i) { var value = list[i]; - var keep = VisitNode(ref value); + var keep = VisitItem(ref value); // First time change? if ((!keep || !equalityComparer.Equals(value, list[i])) && newList == null) diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index ed975506aa..d7803ea2a8 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Core; -public interface ISymbolTypeNode +public interface ISymbolTypeItem { public void Accept(TypeVisitor visitor); @@ -221,7 +221,7 @@ public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, N public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } -public partial record struct StructuredTypeMember(string Name, SymbolType Type, TypeModifier TypeModifier) : ISymbolTypeNode; +public partial record struct StructuredTypeMember(string Name, SymbolType Type, TypeModifier TypeModifier) : ISymbolTypeItem; public partial record StructuredType(string Name, List Members) : SymbolType() { @@ -309,7 +309,7 @@ public sealed partial record TextureCubeType(ScalarType ReturnType) : TextureTyp public sealed partial record FunctionGroupType() : SymbolType(); -public partial record struct FunctionParameter(SymbolType Type, ParameterModifiers Modifiers) : ISymbolTypeNode; +public partial record struct FunctionParameter(SymbolType Type, ParameterModifiers Modifiers) : ISymbolTypeItem; public sealed partial record FunctionType(SymbolType ReturnType, List ParameterTypes) : SymbolType() { From 983895f910a75ac07b3da66eb7967bf3d8c1a299 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Feb 2026 12:41:04 +0900 Subject: [PATCH 0790/1182] Effect parser: reuse non-effect statements --- .../Parsing/SDFX/AST/Effect.Flow.cs | 96 ++----------------- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 52 ++-------- .../Parsing/SDFX/Parsers/EffectParser.cs | 2 - .../EffectStatementParsers.Conditional.cs | 7 +- .../SDFX/Parsers/EffectStatementParsers.cs | 18 ++-- 5 files changed, 26 insertions(+), 149 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs index a30f4e584a..6f16c77679 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs @@ -7,102 +7,18 @@ namespace Stride.Shaders.Parsing.SDFX.AST; public class EffectFlow(TextLocation info) : EffectStatement(info) { - public override void Compile(Analysis.SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } -} - -public class EffectControl(If first, TextLocation info) : EffectFlow(info) -{ - public If If { get; set; } = first; - public List ElseIfs { get; set; } = []; - public Else? Else { get; set; } - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - compiler.Builder.Insert(new OpSDSLConditionalStart()); - If.Compile(table, compiler); - foreach(var elseIf in ElseIfs) - elseIf.Compile(table, compiler); - Else?.Compile(table, compiler); - compiler.Builder.Insert(new OpSDSLConditionalEnd()); - } - public override string ToString() - { - return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; - } -} -public class If(Expression condition, EffectStatement body, TextLocation info) : EffectFlow(info) -{ - public Expression Condition { get; set; } = condition; - public EffectStatement Body { get; set; } = body; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - _ = Condition switch - { - AccessorChainExpression { Source : Identifier, Accessors : [Identifier]} ace => - compiler.Builder.Insert(new OpSDSLParamsTrue(ace.ToString())), - BinaryExpression {Left : AccessorChainExpression { Source : Identifier, Accessors : [Identifier]} ace, Op : Core.Operator.NotEquals, Right : Identifier {Name : "null"}} => - compiler.Builder.Insert(new OpSDSLParamsTrue(ace.ToString())), - _ => throw new NotImplementedException() - }; - - _ = Body switch - { - EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Arguments.Values : [Identifier m]}}} - => compiler.Builder.Insert(new OpSDSLMixinUse(m.Name)), - EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Arguments.Values : [AccessorChainExpression {Source : Identifier, Accessors : [Identifier]} ace]}}} - => compiler.Builder.Insert(new OpSDSLMixinUse(ace.ToString())), - _ => throw new NotImplementedException() - }; - } - - public override string ToString() - { - return $"if({Condition})\n{Body}"; - } -} - -public class ElseIf(Expression condition, EffectStatement body, TextLocation info) : If(condition, body, info) -{ - public override string ToString() - { - return $"else if({Condition}){Body}"; - } -} - -public class Else(EffectStatement body, TextLocation info) : EffectFlow(info) -{ - public EffectStatement Body { get; set; } = body; - public override void Compile(SymbolTable table, CompilerUnit compiler) { - compiler.Builder.Insert(new OpSDSLElse()); - _ = Body switch - { - EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Arguments.Values : [Identifier m]}}} - => compiler.Builder.Insert(new OpSDSLMixinUse(m.Name)), - EffectExpressionStatement {Statement : ExpressionStatement { Expression : MethodCall {Name.Name : "mixin", Arguments.Values : [AccessorChainExpression {Source : Identifier, Accessors : [Identifier]} ace]}}} - => compiler.Builder.Insert(new OpSDSLMixinUse(ace.ToString())), - _ => throw new NotImplementedException() - }; - } - public override string ToString() - { - return $"else {Body}"; + throw new NotImplementedException(); } } - - -public class EffectForEach(SDSL.AST.TypeName typename, SDSL.AST.Identifier variable, SDSL.AST.Expression collection, EffectStatement body, TextLocation info) : EffectFlow(info) +public class EffectForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : EffectFlow(info) { - public SDSL.AST.TypeName Typename { get; set; } = typename; - public SDSL.AST.Identifier Variable { get; set; } = variable; - public SDSL.AST.Expression Collection { get; set; } = collection; - public EffectStatement Body { get; set; } = body; + public TypeName Typename { get; set; } = typename; + public Identifier Variable { get; set; } = variable; + public Expression Collection { get; set; } = collection; + public Statement Body { get; set; } = body; public override string ToString() { diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 94fe94a671..bfb1da3b15 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; public class ShaderEffect(TypeName name, bool isPartial, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; - public List Members { get; set; } = []; + public List Members { get; set; } = []; public bool IsPartial { get; set; } = isPartial; public override string ToString() @@ -25,6 +25,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); + foreach (var statement in Members) + statement.ProcessSymbol(table); foreach (var statement in Members) statement.Compile(table, compiler); } @@ -50,9 +52,8 @@ internal static int[] CompileGenerics(SymbolTable table, SpirvContext context, S } } -public abstract class EffectStatement(TextLocation info) : Node(info) +public abstract class EffectStatement(TextLocation info) : Statement(info) { - public abstract void Compile(SymbolTable table, CompilerUnit compiler); } public class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) @@ -72,24 +73,13 @@ public override string ToString() } } -public class EffectStatementBlock(TextLocation info) : EffectStatement(info) +public class MixinUse(List mixin, TextLocation info) : EffectStatement(info) { - public List Statements { get; set; } = []; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } + public List MixinName { get; set; } = mixin; - public override string ToString() + public override void ProcessSymbol(SymbolTable table) { - return string.Join("\n", Statements); } -} - -public class MixinUse(List mixin, TextLocation info) : EffectStatement(info) -{ - public List MixinName { get; set; } = mixin; public override void Compile(SymbolTable table, CompilerUnit compiler) { @@ -265,34 +255,6 @@ public override string ToString() } } -public class EffectBlock(TextLocation info) : EffectStatement(info) -{ - public List Statements { get; set; } = []; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - -} - - -public class EffectExpressionStatement(Statement statement, TextLocation info) : EffectStatement(info) -{ - public Statement Statement { get; set; } = statement; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - var (builder, _) = compiler; - if (Statement is ExpressionStatement { Expression: MethodCall { Name.Name: "mixin", Arguments.Values: [Identifier mixin] } }) - builder.Insert(new OpSDSLMixinUse(mixin.Name)); - else - { - throw new NotImplementedException(); - } - } -} - public class EffectDiscardStatement(TextLocation info) : EffectStatement(info) { public override void Compile(SymbolTable table, CompilerUnit compiler) diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs index c5681b3cee..ce290084af 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs @@ -49,6 +49,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public static bool Effect(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectParser().Match(ref scanner, result, out parsed, orError); - public static bool EffectStatement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs index 6e88cc1781..3390109c75 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -1,14 +1,15 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDFX.Parsers; using Stride.Shaders.Parsing.SDSL; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDFX; -public record struct EffectControlsParser : IParser +public record struct EffectControlsParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectControl parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -27,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Control(ref TScanner scanner, ParseResult result, out EffectControl parsed, ParseError? orError = null) + public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new EffectControlsParser().Match(ref scanner, result, out parsed, orError); diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs index a84336a428..d6f6cd1cff 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -6,9 +6,9 @@ namespace Stride.Shaders.Parsing.SDFX.Parsers; -public record struct EffectStatementParsers : IParser +public record struct EffectStatementParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (EffectBlock(ref scanner, result, out var block)) @@ -68,7 +68,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (StatementParsers.Expression(ref scanner, result, out var exp)) { - parsed = new EffectExpressionStatement(exp, scanner[position..scanner.Position]); + parsed = exp; return true; } else if ( @@ -82,7 +82,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Statement(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); @@ -125,20 +125,20 @@ public static bool MixinConst(ref TScanner scanner, ParseResult result public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); - public static bool EffectBlock(ref TScanner scanner, ParseResult result, out EffectStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool EffectBlock(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Tokens.Char('{', ref scanner, advance: true)) { - List statements = []; - while (SDSL.Parsers.FollowedByDel(ref scanner, result, Statement, out EffectStatement statement, withSpaces: true, advance: true)) + List statements = []; + while (SDSL.Parsers.FollowedByDel(ref scanner, result, Statement, out Statement statement, withSpaces: true, advance: true)) { statements.Add(statement); } if (!SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); - parsed = new EffectBlock(scanner[position..scanner.Position]) { Statements = statements }; + parsed = new BlockStatement(scanner[position..scanner.Position]) { Statements = statements }; return true; } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); @@ -308,7 +308,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if ( Tokens.Literal("mixin", ref scanner, advance: true) - && SDSL.Parsers.Spaces1(ref scanner, result, out _) + && SDSL.Parsers.Spaces0(ref scanner, result, out _) ) { var betweenParenthesis = SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true); From dcd94776756db613e2f29bacb78b75f9856df1ba Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Feb 2026 14:32:50 +0900 Subject: [PATCH 0791/1182] Added visitor for Node --- .../VisitorGenerator.cs | 74 +++++++++---------- src/Stride.Shaders/Core/Node.Visitors.cs | 40 ++++++++++ src/Stride.Shaders/Parsing/ASTNode.cs | 21 ++++-- .../Parsing/SDFX/AST/Effect.Flow.cs | 4 +- .../Parsing/SDFX/AST/Effect.Parameters.cs | 4 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 43 +++++------ .../Parsing/SDFX/MessageCode.cs | 53 +++++++++++++ .../Parsing/SDFX/Parsers/EffectParser.cs | 24 +----- .../SDFX/Parsers/EffectStatementParsers.cs | 2 +- .../Parsing/SDFX/ReportMessage.cs | 72 ++++++++++++++++++ .../Parsing/SDFX/ReportMessageLevel.cs | 25 +++++++ .../Parsing/SDSL/AST/Directives.cs | 24 +++--- .../Parsing/SDSL/AST/Expression.cs | 20 ++--- .../Parsing/SDSL/AST/Literals.cs | 22 +++--- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 12 +-- .../Parsing/SDSL/AST/ShaderAttributes.cs | 8 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 20 ++--- .../Parsing/SDSL/AST/ShaderElements.cs | 14 ++-- .../Parsing/SDSL/AST/ShaderGenericsValues.cs | 2 +- .../Parsing/SDSL/AST/Statements.Control.cs | 8 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 12 +-- .../Parsing/SDSL/AST/Statements.cs | 16 ++-- 22 files changed, 344 insertions(+), 176 deletions(-) create mode 100644 src/Stride.Shaders/Core/Node.Visitors.cs create mode 100644 src/Stride.Shaders/Parsing/SDFX/MessageCode.cs create mode 100644 src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs create mode 100644 src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs diff --git a/src/Stride.Shaders.Generators/VisitorGenerator.cs b/src/Stride.Shaders.Generators/VisitorGenerator.cs index cfa3f528b7..6b13a410fe 100644 --- a/src/Stride.Shaders.Generators/VisitorGenerator.cs +++ b/src/Stride.Shaders.Generators/VisitorGenerator.cs @@ -14,7 +14,7 @@ internal class VisitorGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateTypeVisitors); - //context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateNodeVisitors); + context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateNodeVisitors); } private void GenerateTypeVisitors(SourceProductionContext context, Compilation compilation) @@ -59,30 +59,22 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var variableName = GenerateVariableName(type.Name); var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - sb.Append(" public virtual void Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(typeName); - sb.Append(" "); - sb.Append(variableName); - sb.Append(")\r\n {\r\n DefaultVisit("); - sb.Append(variableName); - sb.Append(");\r\n }\r\n"); + sb.AppendLine($" public virtual void Visit{type.Name}{genericParameters}({typeName} {variableName})"); + sb.AppendLine(" {"); + sb.AppendLine($" DefaultVisit({variableName});"); + sb.AppendLine(" }"); } - sb.Append($" }}\r\n\r\n public partial class {visitorName}Walker\r\n {{\r\n"); + sb.Append(" }"); + sb.AppendLine($" public partial class {visitorName}Walker"); + sb.AppendLine(" {"); foreach (var type in symbolTypes) { var typeName = type.ToDisplayString(); var variableName = GenerateVariableName(type.Name); var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - sb.Append(" public override void Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(typeName); - sb.Append(" "); - sb.Append(variableName); - sb.Append(")\r\n {\r\n"); + sb.AppendLine($" public override void Visit{type.Name}{genericParameters}({typeName} {variableName})"); + sb.AppendLine(" {"); // Process public fields and properties (with getter+setter) var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); foreach (var member in GetNodeMembers(type, isNodeType)) @@ -91,28 +83,22 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var memberTypeName = memberType.ToDisplayString(); var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && isNodeType(x.TypeArguments[0]))?.TypeArguments[0]; var isNode = isNodeType(memberType); + var hasNullableAnnoation = memberType.NullableAnnotation; if (isNode) { - sb.Append($" Visit{(memberType.IsValueType ? "Item" : visitorName)}("); - sb.Append(variableName); - sb.Append("."); - sb.Append(member.Name); - sb.Append(");\r\n"); + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.AppendLine($"if ({variableName}.{member.Name} != null)"); + sb.AppendLine($" Visit{(memberType.IsValueType ? "Item" : visitorName)}({variableName}.{member.Name});"); } else if (nodeListElementType != null) { - sb.Append($" Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List("); - sb.Append(variableName); - sb.Append("."); - sb.Append(member.Name); - sb.Append(");\r\n"); + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.AppendLine($"if ({variableName}.{member.Name} != null)"); + sb.AppendLine($" Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List({variableName}.{member.Name});"); } } - sb.Append(" base.Visit"); - sb.Append(genericParameters); - sb.Append("("); - sb.Append(variableName); - sb.Append(");\r\n }\r\n"); + sb.AppendLine($" base.Visit{genericParameters}({variableName});"); + sb.AppendLine(" }"); } sb.AppendLine(" }"); @@ -153,7 +139,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; var returnType = type.IsValueType ? "bool" : "SymbolType"; - sb.AppendLine($" public override {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine($" public override {returnType} Visit{type.Name}{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); sb.AppendLine("{"); // Process public fields and properties (with getter+setter) var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); @@ -166,15 +152,23 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var isNode = isNodeType(memberType); if (isNode) { + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.Append($"if ({variableName}.{member.Name} != null) {{"); sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(memberType.IsValueType ? "Item" : visitorName)}({variableName}.{member.Name});"); sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.Append("}"); } else if (nodeListElementType != null) { + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.Append($"if ({variableName}.{member.Name} != null) {{"); sb.AppendLine($" var {memberVariableName} = ({memberTypeName})Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List({variableName}.{member.Name});"); sb.AppendLine($" if (!ReferenceEquals({memberVariableName}, {variableName}.{member.Name}))"); sb.AppendLine($" {variableName} = {variableName} with {{ {member.Name} = {memberVariableName} }};"); + if (memberType.NullableAnnotation == NullableAnnotation.Annotated) + sb.Append("}"); } } if (type.IsValueType) @@ -185,7 +179,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c { sb.AppendLine($" return (SymbolType)base.Visit{genericParameters}({variableName});"); } - sb.Append("}\r\n"); + sb.AppendLine("}"); } sb.AppendLine(" }"); @@ -207,12 +201,10 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c (false, false) => "class", }; - sb.AppendLine($"public partial {typeKind}"); - sb.Append(type.ToDisplayString(typeAndGenericFormat)); - sb.Append(@$" - {{ - public {(!type.IsValueType ? "override" : string.Empty)} void Accept({visitorName}Visitor visitor) - {{"); + sb.AppendLine($"public partial {typeKind} {type.ToDisplayString(typeAndGenericFormat)}"); + sb.AppendLine("{"); + sb.AppendLine($"public {(!type.IsValueType ? "override" : string.Empty)} void Accept({visitorName}Visitor visitor)"); + sb.AppendLine("{"); sb.AppendLine("visitor.Visit(this);"); sb.AppendLine("}"); if (generateRewriter) diff --git a/src/Stride.Shaders/Core/Node.Visitors.cs b/src/Stride.Shaders/Core/Node.Visitors.cs new file mode 100644 index 0000000000..63ab6c00f5 --- /dev/null +++ b/src/Stride.Shaders/Core/Node.Visitors.cs @@ -0,0 +1,40 @@ +using Stride.Shaders.Parsing; + +namespace Stride.Shaders.Core; + +public abstract partial class NodeVisitor +{ + protected virtual void VisitItemList(List list) where T : INodeItem + { + foreach (var item in list) + VisitItem(item); + } + + protected virtual void VisitNodeList(List list) where T : Node + { + foreach (var item in list) + VisitNode(item); + } + + public virtual void DefaultVisit(Node node) + { + } + + public void DefaultVisit(T node) where T : struct, INodeItem + { + } + + public virtual void VisitNode(Node node) + { + node?.Accept(this); + } + + public virtual void VisitItem(T node) where T : INodeItem + { + node?.Accept(this); + } +} + +public partial class NodeWalker : NodeVisitor +{ +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/ASTNode.cs b/src/Stride.Shaders/Parsing/ASTNode.cs index caaf3dd7bf..660575a49a 100644 --- a/src/Stride.Shaders/Parsing/ASTNode.cs +++ b/src/Stride.Shaders/Parsing/ASTNode.cs @@ -5,18 +5,25 @@ namespace Stride.Shaders.Parsing; +public interface INodeItem +{ + public void Accept(NodeVisitor visitor); +} + /// /// Base class for shader syntax tree elements /// -public abstract class Node(TextLocation info) +public abstract partial class Node(TextLocation info) { public TextLocation Info { get; set; } = info; + + public abstract void Accept(NodeVisitor visitor); } /// /// AST Node with a type /// -public abstract class ValueNode(TextLocation info) : Node(info) +public abstract partial class ValueNode(TextLocation info) : Node(info) { public virtual SymbolType? Type { get; set; } = null; } @@ -24,19 +31,19 @@ public abstract class ValueNode(TextLocation info) : Node(info) /// /// Empty node for empty result /// -public class NoNode() : Node(new()); +public partial class NoNode() : Node(new()); /// /// A declaration in SDSL/SDFX /// -public abstract class ShaderDeclaration(TextLocation info) : Node(info); +public abstract partial class ShaderDeclaration(TextLocation info) : Node(info); /// /// Shader file node containing usings, namespaces, shaders, effects or params /// -public class ShaderFile(TextLocation info) : Node(info) +public partial class ShaderFile(TextLocation info) : Node(info) { public List RootDeclarations { get; set; } = []; public List Namespaces { get; set; } = []; @@ -50,7 +57,7 @@ public override string ToString() /// /// Using instructions /// -public class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) +public partial class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) { public List NamespacePath { get; set; } = []; } @@ -58,7 +65,7 @@ public class UsingShaderNamespace(TextLocation info) : ShaderDeclaration(info) /// /// Namespace declaration /// -public class ShaderNamespace(TextLocation info) : Node(info) +public partial class ShaderNamespace(TextLocation info) : Node(info) { public List NamespacePath { get; set; } = []; public Identifier? Namespace { get; set; } diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs index 6f16c77679..7abc3f98f1 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs @@ -5,7 +5,7 @@ using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectFlow(TextLocation info) : EffectStatement(info) +public partial class EffectFlow(TextLocation info) : EffectStatement(info) { public override void Compile(SymbolTable table, CompilerUnit compiler) { @@ -13,7 +13,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } } -public class EffectForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : EffectFlow(info) +public partial class EffectForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : EffectFlow(info) { public TypeName Typename { get; set; } = typename; public Identifier Variable { get; set; } = variable; diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs index 0b51d5d74d..2304f70f4a 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs @@ -7,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class EffectParameters(TypeName name, TextLocation info) : ShaderDeclaration(info) +public partial class EffectParameters(TypeName name, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; public List Parameters { get; set; } = []; @@ -21,7 +21,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } -public class EffectParameter(TypeName type, Identifier identifier, TextLocation info, Expression? value = null) : Node(info) +public partial class EffectParameter(TypeName type, Identifier identifier, TextLocation info, Expression? value = null) : Node(info) { public TypeName Type { get; set; } = type; public Identifier Identifier { get; set;} = identifier; diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index bfb1da3b15..70a748ea0b 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -9,26 +9,22 @@ namespace Stride.Shaders.Parsing.SDFX.AST; -public class ShaderEffect(TypeName name, bool isPartial, TextLocation info) : ShaderDeclaration(info) +public partial class ShaderEffect(TypeName name, bool isPartial, TextLocation info) : ShaderDeclaration(info) { public TypeName Name { get; set; } = name; - public List Members { get; set; } = []; + + public BlockStatement Block { get; set; } public bool IsPartial { get; set; } = isPartial; - public override string ToString() - { - return string.Join("", Members.Select(x => $"{x}\n")); - } + public override string ToString() => Block.ToString(); public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); - foreach (var statement in Members) - statement.ProcessSymbol(table); - foreach (var statement in Members) - statement.Compile(table, compiler); + Block.ProcessSymbol(table); + Block.Compile(table, compiler); } internal static int[] CompileGenerics(SymbolTable table, SpirvContext context, ShaderExpressionList? generics) @@ -56,7 +52,7 @@ public abstract class EffectStatement(TextLocation info) : Statement(info) { } -public class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) +public partial class ShaderSourceDeclaration(Identifier name, TextLocation info, Expression? value = null) : EffectStatement(info) { public Identifier Name { get; set; } = name; public Expression? Value { get; set; } = value; @@ -73,7 +69,7 @@ public override string ToString() } } -public class MixinUse(List mixin, TextLocation info) : EffectStatement(info) +public partial class MixinUse(List mixin, TextLocation info) : EffectStatement(info) { public List MixinName { get; set; } = mixin; @@ -99,7 +95,7 @@ public override string ToString() return $"mixin {MixinName}"; } } -public class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) +public partial class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; @@ -114,7 +110,7 @@ public override string ToString() } } -public class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) +public partial class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; @@ -129,7 +125,7 @@ public override string ToString() } } -public class MixinConst(string identifier, TextLocation info) : EffectStatement(info) +public partial class MixinConst(string identifier, TextLocation info) : EffectStatement(info) { public string Identifier { get; set; } = identifier; @@ -148,7 +144,7 @@ public abstract class ComposeValue(TextLocation info) : Node(info) public abstract void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator); } -public class ComposePathValue(string path, TextLocation info) : ComposeValue(info) +public partial class ComposePathValue(string path, TextLocation info) : ComposeValue(info) { public string Path { get; set; } = path; @@ -162,7 +158,7 @@ public override string ToString() return Path.ToString(); } } -public class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(info) +public partial class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(info) { public Mixin Mixin { get; set; } = mixin; @@ -195,7 +191,7 @@ public override string ToString() } } -public class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue value, TextLocation info) : EffectStatement(info) +public partial class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue value, TextLocation info) : EffectStatement(info) { public Identifier Identifier { get; set; } = identifier; AssignOperator Operator { get; set; } = op; @@ -212,7 +208,7 @@ public override string ToString() return $"mixin compose {Identifier} {Operator.ToAssignSymbol()} {ComposeValue}"; } } -public class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) +public partial class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) { public Identifier Identifier { get; set; } = identifier; public Identifier Source { get; set; } = source; @@ -228,7 +224,7 @@ public override string ToString() } } -public class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) +public partial class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) { public Mixin MixinName { get; set; } = mixin; @@ -236,9 +232,9 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { throw new NotImplementedException(); } - } -public class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) + +public partial class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { public Identifier ParamsName { get; set; } = name; @@ -248,14 +244,13 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) builder.Insert(new OpSDSLParamsUse(ParamsName.Name)); } - public override string ToString() { return $"using params {ParamsName}"; } } -public class EffectDiscardStatement(TextLocation info) : EffectStatement(info) +public partial class EffectDiscardStatement(TextLocation info) : EffectStatement(info) { public override void Compile(SymbolTable table, CompilerUnit compiler) { diff --git a/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs b/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs new file mode 100644 index 0000000000..ec8be6ab08 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs @@ -0,0 +1,53 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Core.Shaders.Utility +{ + public partial class MessageCode + { + public readonly string Code; + + public readonly string Text; + + public MessageCode(string text) + { + Code = ""; + Text = text; + } + + public MessageCode(string code, string text) + { + Code = code; + Text = text; + } + + public static implicit operator MessageCode(string text) + { + return new MessageCode(text); + } + + #region Static members + + // Warnings + public static readonly MessageCode WarningUnknown = new MessageCode("W0000", "Unknown warning"); + + public static readonly MessageCode WarningTypeAsConstructor = new MessageCode("W0001", "Invalid type used as a constructor [{0}]"); + public static readonly MessageCode WarningTypeInferenceUnknownExpression = new MessageCode("W0002", "Type inference for unknown expression is supported [{0}]"); + public static readonly MessageCode WarningNoTypeReferenceMember = new MessageCode("W0003", "Unable to find type reference for member [{0}]"); + + // Error + public static readonly MessageCode ErrorAnalysisUnknown = new MessageCode("E0000", "Unknown analysis error"); + + public static readonly MessageCode ErrorBinaryTypeDeduction = new MessageCode("E0001", "Can't deduce type of binary operation between [{0}] and [{1}]"); + public static readonly MessageCode ErrorScalarTypeConversion = new MessageCode("E0002", "Unsupported scalar type conversion between [{0}] and [{1}]"); + public static readonly MessageCode ErrorIndexerType = new MessageCode("E0003", "Unable to find type for indexer: [{0}]"); + public static readonly MessageCode ErrorLiteralType = new MessageCode("E0004", "Unable to find type reference for literal value [{0}]"); + public static readonly MessageCode ErrorNoOverloadedMethod = new MessageCode("E0005", "Unable to find a suitable overloaded method [{0}]"); + public static readonly MessageCode ErrorNoReferencedMethod = new MessageCode("E0006", "Unable to find the referenced method [{0}]"); + public static readonly MessageCode ErrorNoTypeReferenceTypename = new MessageCode("E0008", "Unable to find type reference for typename [{0}]"); + + public static readonly MessageCode ErrorUnexpectedException = new MessageCode("E0009", "Unexpected exception: {0}"); + + + #endregion + } +} diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs index ce290084af..26372177e2 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs @@ -20,28 +20,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (LiteralsParser.TypeName(ref scanner, result, out var effectName) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { parsed = new((TypeName)effectName, isPartial, new()); - if (Tokens.Char('{', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) + if (EffectStatementParsers.EffectBlock(ref scanner, result, out var s) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { - while( - !scanner.IsEof - && !Tokens.Char('}', ref scanner) - ) - { - if (EffectStatementParsers.Statement(ref scanner, result, out var s) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) - { - parsed.Members.Add(s); - } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); - } - if(scanner.IsEof) - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0011, scanner[scanner.Position], scanner.Memory)); - else if(Tokens.Char('}', ref scanner, advance: true)) - { - parsed.Info = scanner[position..scanner.Position]; - SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); - return true; - } + parsed.Block = s; + return true; } + else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0011, scanner[scanner.Position], scanner.Memory)); } } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs index d6f6cd1cff..3c7e7cc733 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -125,7 +125,7 @@ public static bool MixinConst(ref TScanner scanner, ParseResult result public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); - public static bool EffectBlock(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool EffectBlock(ref TScanner scanner, ParseResult result, out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs b/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs new file mode 100644 index 0000000000..5214bcd2a0 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs @@ -0,0 +1,72 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Core.Shaders.Ast; + +namespace Stride.Core.Shaders.Utility +{ + /// + /// A report message. + /// + public class ReportMessage + { + #region Constants and Fields + + /// + /// Type of the message. + /// + public ReportMessageLevel Level; + + /// + /// Span and location attached to this message. + /// + public SourceSpan Span; + + /// + /// The error code. + /// + public string Code; + + /// + /// Text of the message. + /// + public string Text; + + #endregion + + #region Constructors and Destructors + + /// + /// Initializes a new instance of the class. + /// + public ReportMessage() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The type. + /// The error code. + /// The text. + /// The span. + public ReportMessage(ReportMessageLevel level, string code, string text, SourceSpan span) + { + this.Level = level; + this.Code = code; + this.Text = text; + this.Span = span; + } + + #endregion + + #region Public Methods + + /// + public override string ToString() + { + return string.Format("{0}: {1} {2} : {3}", this.Span, this.Level.ToString().ToLowerInvariant(), this.Code, this.Text); + } + + #endregion + } +} diff --git a/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs b/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs new file mode 100644 index 0000000000..fcc722c8f7 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +namespace Stride.Core.Shaders.Utility +{ + /// + /// Level of a . + /// + public enum ReportMessageLevel + { + /// + /// An informative message. + /// + Info = 0, + + /// + /// A warning message. + /// + Warning = 1, + + /// + /// An error message. + /// + Error = 2, + } +} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs index e784837327..747437d3ca 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs @@ -1,7 +1,7 @@ namespace Stride.Shaders.Parsing.SDSL.AST; -public class PreProcessableCode(TextLocation info) : Node(info) +public partial class PreProcessableCode(TextLocation info) : Node(info) { public List Snippets { get; set; } = []; public override string ToString() @@ -10,12 +10,12 @@ public override string ToString() } } -public abstract class DirectiveStatement(TextLocation info) : Node(info); +public abstract partial class DirectiveStatement(TextLocation info) : Node(info); /// /// Represents a directive code snippet /// /// -public class DirectiveCode(TextLocation info) : DirectiveStatement(info) +public partial class DirectiveCode(TextLocation info) : DirectiveStatement(info) { public override string ToString() { @@ -44,7 +44,7 @@ public abstract class DirectiveFlow(Expression? expression, TextLocation info) : /// /// /// -public class ObjectDefineDirective(Identifier identifier, Expression? expression, TextLocation info) : Directive(info) +public partial class ObjectDefineDirective(Identifier identifier, Expression? expression, TextLocation info) : Directive(info) { public Identifier Identifier { get; set; } = identifier; public Expression? Expression { get; set; } = expression; @@ -56,7 +56,7 @@ public class ObjectDefineDirective(Identifier identifier, Expression? expression /// /// /// -public class FunctionDefineDirective(Identifier functionName, string pattern, TextLocation info) : Directive(info) +public partial class FunctionDefineDirective(Identifier functionName, string pattern, TextLocation info) : Directive(info) { public Identifier FunctionName { get; set; } = functionName; public List Parameters { get; set; } = []; @@ -67,7 +67,7 @@ public class FunctionDefineDirective(Identifier functionName, string pattern, Te /// /// /// -public class IfDirective(Expression expression, TextLocation info) : DirectiveFlow(expression, info) +public partial class IfDirective(Expression expression, TextLocation info) : DirectiveFlow(expression, info) { public override string ToString() { @@ -80,7 +80,7 @@ public override string ToString() /// /// /// -public class IfDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) +public partial class IfDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) { public override string ToString() { @@ -92,7 +92,7 @@ public override string ToString() /// /// /// -public class IfNDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) +public partial class IfNDefDirective(Identifier value, TextLocation info) : IfDirective(value, info) { public override string ToString() { @@ -104,7 +104,7 @@ public override string ToString() /// /// /// -public class ElifDirective(Expression expression, TextLocation info) : IfDirective(expression, info) +public partial class ElifDirective(Expression expression, TextLocation info) : IfDirective(expression, info) { public override string ToString() { @@ -115,14 +115,14 @@ public override string ToString() /// Represents a directive conditional flow control #else /// /// -public class ElseDirective(TextLocation info) : DirectiveFlow(null, info) +public partial class ElseDirective(TextLocation info) : DirectiveFlow(null, info) { public override string ToString() { return $"#else\n{Code}"; } } -public class EndIfDirective(TextLocation info) : DirectiveFlow(null, info) +public partial class EndIfDirective(TextLocation info) : DirectiveFlow(null, info) { public override string ToString() { @@ -135,7 +135,7 @@ public override string ToString() /// /// /// -public class ConditionalDirectives(IfDirective ifExp, TextLocation info) : Directive(info) +public partial class ConditionalDirectives(IfDirective ifExp, TextLocation info) : Directive(info) { public IfDirective If { get; set; } = ifExp; public List Elifs { get; set; } = []; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 6a240fbbf0..9d32a92e5d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -70,14 +70,14 @@ public virtual SpirvValue CompileAsValue(SymbolTable table, CompilerUnit compile /// Used only for when size is not explicitly defined. /// /// -public class EmptyExpression(TextLocation info) : Expression(info) +public partial class EmptyExpression(TextLocation info) : Expression(info) { public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException(); public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() => string.Empty; } -public class MethodCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : Expression(info) +public partial class MethodCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : Expression(info) { public Identifier Name = name; public ShaderExpressionList Arguments = arguments; @@ -366,7 +366,7 @@ public override string ToString() /// /// Represents an accessed mixin. /// -public class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) +public partial class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) { public Mixin Mixin { get; set; } = mixin; @@ -422,7 +422,7 @@ public abstract class UnaryExpression(Expression expression, Operator op, TextLo public Operator Operator { get; set; } = op; } -public class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) +public partial class PrefixExpression(Operator op, Expression expression, TextLocation info) : UnaryExpression(expression, op, info) { public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { @@ -516,7 +516,7 @@ var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate } } -public class CastExpression(TypeName typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) +public partial class CastExpression(TypeName typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) { public TypeName TypeName { get; set; } = typeName; @@ -541,7 +541,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } -public class IndexerExpression(Expression index, TextLocation info) : Expression(info) +public partial class IndexerExpression(Expression index, TextLocation info) : Expression(info) { public Expression Index { get; set; } = index; @@ -554,7 +554,7 @@ public override string ToString() } } -public class PostfixIncrement(Operator op, TextLocation info) : Expression(info) +public partial class PostfixIncrement(Operator op, TextLocation info) : Expression(info) { public Operator Operator { get; set; } = op; @@ -567,7 +567,7 @@ public override string ToString() } } -public class AccessorChainExpression(Expression source, TextLocation info) : Expression(info) +public partial class AccessorChainExpression(Expression source, TextLocation info) : Expression(info) { public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; @@ -1336,7 +1336,7 @@ public string ToString(int accessorCount) } } -public class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) +public partial class BinaryExpression(Expression left, Operator op, Expression right, TextLocation info) : Expression(info) { public Operator Op { get; set; } = op; public Expression Left { get; set; } = left; @@ -1386,7 +1386,7 @@ public override string ToString() } } -public class TernaryExpression(Expression cond, Expression left, Expression right, TextLocation info) : Expression(info) +public partial class TernaryExpression(Expression cond, Expression left, Expression right, TextLocation info) : Expression(info) { public Expression Condition { get; set; } = cond; public Expression Left { get; set; } = left; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index d8ba686fa4..8522753f25 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -20,7 +20,7 @@ public abstract class Literal(TextLocation info) : Expression(info); public abstract class ValueLiteral(TextLocation info) : Literal(info); public abstract class ScalarLiteral(TextLocation info) : ValueLiteral(info); -public class StringLiteral(string value, TextLocation info) : Literal(info) +public partial class StringLiteral(string value, TextLocation info) : Literal(info) { public string Value { get; set; } = value; @@ -74,7 +74,7 @@ public override string ToString() } -public class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) +public partial class IntegerLiteral(Suffix suffix, long value, TextLocation info) : NumberLiteral(suffix, value, info) { public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { @@ -96,7 +96,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } -public sealed class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) +public sealed partial class FloatLiteral(Suffix suffix, double value, int? exponent, TextLocation info) : NumberLiteral(suffix, value, info) { public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); @@ -112,13 +112,13 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } -public sealed class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(value > uint.MaxValue ? 64 : 32, false, false), (long)value, info) +public sealed partial class HexLiteral(ulong value, TextLocation info) : IntegerLiteral(new(value > uint.MaxValue ? 64 : 32, false, false), (long)value, info) { public override SymbolType? Type => Suffix.Size > 32 ? ScalarType.UInt64 : ScalarType.UInt; } -public class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) +public partial class BoolLiteral(bool value, TextLocation info) : ScalarLiteral(info) { public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.Boolean; @@ -134,7 +134,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } -public class ExpressionLiteral(Expression value, TypeName typeName, TextLocation info) : ValueLiteral(info) +public partial class ExpressionLiteral(Expression value, TypeName typeName, TextLocation info) : ValueLiteral(info) { public Expression Value { get; set; } = value; public TypeName TypeName { get; set; } = typeName; @@ -235,7 +235,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) return new(instruction.ResultId, instruction.ResultType); } } -public class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) +public partial class VectorLiteral(TypeName typeName, TextLocation info) : CompositeLiteral(info) { public TypeName TypeName { get; set; } = typeName; @@ -264,7 +264,7 @@ public override string ToString() } -public class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : CompositeLiteral(info) +public partial class MatrixLiteral(TypeName typeName, int rows, int cols, TextLocation info) : CompositeLiteral(info) { public TypeName TypeName { get; set; } = typeName; public int Rows { get; set; } = rows; @@ -295,7 +295,7 @@ public override string ToString() } } -public class ArrayLiteral(TextLocation info) : CompositeLiteral(info) +public partial class ArrayLiteral(TextLocation info) : CompositeLiteral(info) { public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { @@ -331,7 +331,7 @@ public override string ToString() => $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; } -public class Identifier(string name, TextLocation info) : Literal(info) +public partial class Identifier(string name, TextLocation info) : Literal(info) { internal bool AllowStreamVariables { get; set; } public string Name { get; set; } = name; @@ -579,7 +579,7 @@ public bool IsMatrixField() } } -public class TypeName(string name, TextLocation info) : Literal(info) +public partial class TypeName(string name, TextLocation info) : Literal(info) { public string Name { get; set; } = name; public bool IsArray => ArraySize != null && ArraySize.Count > 0; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index fe5a2c4808..fafa299faf 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -31,7 +31,7 @@ public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext de } } -public class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration(info) +public partial class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration(info) { public Identifier Name { get; set; } = name; public List Elements { get; set; } = []; @@ -293,7 +293,7 @@ class ReplaceTypes(Dictionary TypesToReplace) : TypeRewr public override SymbolType DefaultVisit(SymbolType node) => TypesToReplace.TryGetValue(node, out var result) ? result : node; } - public class ShaderImporter(SymbolTable table, SpirvContext context) : IShaderImporter + public partial class ShaderImporter(SymbolTable table, SpirvContext context) : IShaderImporter { public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) { @@ -644,13 +644,13 @@ public override string ToString() } -public class ShaderGenerics(Identifier typename, Identifier name, TextLocation info) : Node(info) +public partial class ShaderGenerics(Identifier typename, Identifier name, TextLocation info) : Node(info) { public Identifier Name { get; set; } = name; public Identifier TypeName { get; set; } = typename; } -public class Mixin(Identifier name, TextLocation info) : Node(info) +public partial class Mixin(Identifier name, TextLocation info) : Node(info) { public List Path { get; set; } = []; public Identifier Name { get; set; } = name; @@ -664,11 +664,11 @@ public override string ToString() } public abstract class ShaderMixinValue(TextLocation info) : Node(info); -public class ShaderMixinExpression(Expression expression, TextLocation info) : ShaderMixinValue(info) +public partial class ShaderMixinExpression(Expression expression, TextLocation info) : ShaderMixinValue(info) { public Expression Value { get; set; } = expression; } -public class ShaderMixinIdentifier(Identifier identifier, TextLocation info) : ShaderMixinValue(info) +public partial class ShaderMixinIdentifier(Identifier identifier, TextLocation info) : ShaderMixinValue(info) { public Identifier Value { get; set; } = identifier; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs index 72859bc8b7..d3cbce705e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs @@ -4,12 +4,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class ShaderAttribute(TextLocation info) : Node(info); -public sealed class ShaderAttributeList(List attributes, TextLocation info) : Node(info) +public sealed partial class ShaderAttributeList(List attributes, TextLocation info) : Node(info) { public List Attributes { get; } = attributes; } -public class AnyShaderAttribute(Identifier name, TextLocation info, List parameters = null!) : ShaderAttribute(info) +public partial class AnyShaderAttribute(Identifier name, TextLocation info, List parameters = null!) : ShaderAttribute(info) { public Identifier Name { get; set; } = name; public List Parameters { get; } = parameters ?? []; @@ -25,7 +25,7 @@ public override string ToString() } -public class ResourceBind(int location, int space, TextLocation info) : ShaderAttribute(info) +public partial class ResourceBind(int location, int space, TextLocation info) : ShaderAttribute(info) { public int Location { get; set; } = location; public int Space { get; set; } = space; @@ -36,7 +36,7 @@ public override string ToString() } } -public class ColorType(TextLocation info) : ShaderAttribute(info) +public partial class ColorType(TextLocation info) : ShaderAttribute(info) { public override string ToString() => "COLOR"; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index d722df5ce0..763d12691d 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -17,11 +17,11 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class MethodOrMember(TextLocation info, bool isStaged = false) : ShaderElement(info) { public bool IsStaged { get; set; } = isStaged; - public List Attributes { get; set; } = []; + public List? Attributes { get; set; } = null; } -public class SamplerStateParameter(Identifier name, Expression value, TextLocation info) : ShaderElement(info) +public partial class SamplerStateParameter(Identifier name, Expression value, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; public Expression Value { get; set; } = value; @@ -32,7 +32,7 @@ public override string ToString() } } -public class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMember(info) +public partial class ShaderSamplerState(Identifier name, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; public List Parameters { get; set; } = []; @@ -137,7 +137,7 @@ public override string ToString() return $"SamplerState {Name} ({string.Join(", ", Parameters)})"; } } -public class ShaderSamplerComparisonState(Identifier name, TextLocation info) : ShaderSamplerState(name, info) +public partial class ShaderSamplerComparisonState(Identifier name, TextLocation info) : ShaderSamplerState(name, info) { public override string ToString() { @@ -146,7 +146,7 @@ public override string ToString() } -public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) +public partial class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; public Mixin Mixin { get; set; } = mixin; @@ -154,7 +154,7 @@ public class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocat public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; } -public sealed class ShaderMember( +public sealed partial class ShaderMember( TypeName typeName, Identifier identifier, Expression? initialValue, @@ -306,7 +306,7 @@ public override string ToString() } } -public class MethodParameter(TypeName type, Identifier name, TextLocation info, ParameterModifiers modifiers = ParameterModifiers.None, Expression? defaultValue = null, Identifier? semantic = null) : Node(info) +public partial class MethodParameter(TypeName type, Identifier name, TextLocation info, ParameterModifiers modifiers = ParameterModifiers.None, Expression? defaultValue = null, Identifier? semantic = null) : Node(info) { public TypeName TypeName { get; set; } = type; public SymbolType? Type { get; set; } @@ -321,7 +321,7 @@ public override string ToString() } } -public class ShaderMethod( +public partial class ShaderMethod( TypeName returnType, Identifier name, TextLocation info, @@ -592,12 +592,12 @@ public record struct ShaderParameter(TypeName TypeName, Identifier Name); public abstract class ParameterListNode(TextLocation info) : Node(info); -public class ShaderParameterDeclarations(TextLocation info) : ParameterListNode(info) +public partial class ShaderParameterDeclarations(TextLocation info) : ParameterListNode(info) { public List Parameters { get; set; } = []; } -public class ShaderExpressionList(TextLocation info) : ParameterListNode(info) +public partial class ShaderExpressionList(TextLocation info) : ParameterListNode(info) { public List Values { get; set; } = []; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 7bc5179c70..66bd60a949 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -144,7 +144,7 @@ public static ParameterModifiers ToParameterModifiers(this string str) } } -public class ShaderVariable(TypeName typeName, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) +public partial class ShaderVariable(TypeName typeName, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; public TypeName TypeName { get; set; } = typeName; @@ -157,7 +157,7 @@ public override string ToString() } } -public class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) +public partial class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; public TypeName TypeName { get; set; } = type; @@ -207,7 +207,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) public abstract void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler); } -public class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) +public partial class ShaderStructMember(TypeName typename, Identifier identifier, TextLocation info) : Node(info) { public TypeName TypeName { get; set; } = typename; public SymbolType? Type { get; set; } @@ -226,7 +226,7 @@ public override string ToString() } } -public class ShaderStruct(Identifier typename, TextLocation info) : ShaderElement(info) +public partial class ShaderStruct(Identifier typename, TextLocation info) : ShaderElement(info) { public Identifier TypeName { get; set; } = typename; public List Members { get; set; } = []; @@ -261,7 +261,7 @@ public override string ToString() } } -public sealed class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) +public sealed partial class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { public Symbol Symbol { get; private set; } private bool? isStaged; @@ -395,7 +395,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } } -public sealed class RGroup(string name, TextLocation info) : ShaderBuffer(name, info) +public sealed partial class RGroup(string name, TextLocation info) : ShaderBuffer(name, info) { public List Symbols { get; } = new(); public override void ProcessSymbol(SymbolTable table, SpirvContext context) @@ -462,7 +462,7 @@ internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass sha } } -public sealed class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info) +public sealed partial class TBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs index e4251c0346..6bd311f8e3 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs @@ -5,7 +5,7 @@ public interface IGenericValue; public abstract class ShaderGenericsValue(TextLocation info) : Node(info); -public class ValueTypeGenerics(ValueLiteral value,TextLocation info) : ShaderGenericsValue(info) +public partial class ValueTypeGenerics(ValueLiteral value,TextLocation info) : ShaderGenericsValue(info) { public ValueLiteral Value { get; set; } = value; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs index 5040131a5b..c5cef2c779 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Control(TextLocation info) : Flow(info); -public class ConditionalFlow(If first, TextLocation info) : Flow(info) +public partial class ConditionalFlow(If first, TextLocation info) : Flow(info) { public If If { get; set; } = first; public List ElseIfs { get; set; } = []; @@ -102,7 +102,7 @@ public override string ToString() return $"{If}{string.Join("\n", ElseIfs.Select(x => x.ToString()))}{Else}"; } } -public class If(Expression condition, Statement body, TextLocation info) : Flow(info) +public partial class If(Expression condition, Statement body, TextLocation info) : Flow(info) { public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; @@ -124,7 +124,7 @@ public override string ToString() } } -public class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) +public partial class ElseIf(Expression condition, Statement body, TextLocation info) : If(condition, body, info) { public override string ToString() { @@ -132,7 +132,7 @@ public override string ToString() } } -public class Else(Statement body, TextLocation info) : Flow(info) +public partial class Else(Statement body, TextLocation info) : Flow(info) { public Statement Body { get; set; } = body; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs index 2042e8ca8f..39967d7ce4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public abstract class Flow(TextLocation info) : Statement(info); public abstract class Loop(TextLocation info) : Flow(info); -public class Break(TextLocation info) : Statement(info) +public partial class Break(TextLocation info) : Statement(info) { public override void ProcessSymbol(SymbolTable table) { @@ -24,7 +24,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) builder.Insert(new OpBranch(escapeBlocks.MergeBlock)); } } -public class Discard(TextLocation info) : Statement(info) +public partial class Discard(TextLocation info) : Statement(info) { public override void ProcessSymbol(SymbolTable table) { @@ -34,7 +34,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) throw new NotImplementedException(); } } -public class Continue(TextLocation info) : Statement(info) +public partial class Continue(TextLocation info) : Statement(info) { public override void ProcessSymbol(SymbolTable table) { @@ -51,7 +51,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } -public class ForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : Loop(info) +public partial class ForEach(TypeName typename, Identifier variable, Expression collection, Statement body, TextLocation info) : Loop(info) { public TypeName TypeName { get; set; } = typename; public Identifier Variable { get; set; } = variable; @@ -112,7 +112,7 @@ public override string ToString() } -public class While(Expression condition, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +public partial class While(Expression condition, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Expression Condition { get; set; } = condition; public Statement Body { get; set; } = body; @@ -148,7 +148,7 @@ public enum ForAnnotationKind } public record struct ForAnnotation(ForAnnotationKind Kind, int? Count = null); -public class For(Statement initializer, Expression cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) +public partial class For(Statement initializer, Expression cond, List update, Statement body, TextLocation info, ShaderAttribute? attribute = null) : Loop(info) { public Statement Initializer { get; set; } = initializer; public Expression Condition { get; set; } = cond; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 3353a18823..50b4b5b560 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -19,14 +19,14 @@ public abstract class Statement(TextLocation info) : ValueNode(info) public abstract void Compile(SymbolTable table, CompilerUnit compiler); } -public class EmptyStatement(TextLocation info) : Statement(info) +public partial class EmptyStatement(TextLocation info) : Statement(info) { public override SymbolType? Type { get => ScalarType.Void; set { } } public override void Compile(SymbolTable table, CompilerUnit compiler) { } public override string ToString() => ";"; } -public class ExpressionStatement(Expression expression, TextLocation info) : Statement(info) +public partial class ExpressionStatement(Expression expression, TextLocation info) : Statement(info) { public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; @@ -48,7 +48,7 @@ public override string ToString() } } -public class Return(TextLocation info, Expression? expression = null) : Statement(info) +public partial class Return(TextLocation info, Expression? expression = null) : Statement(info) { public Expression? Value { get; set; } = expression; @@ -82,7 +82,7 @@ public abstract class Declaration(TypeName typename, TextLocation info) : Statem public TypeName TypeName { get; set; } = typename; } -public class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) +public partial class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) { public Expression Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; @@ -100,7 +100,7 @@ public override string ToString() Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" }; } -public class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) +public partial class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) { public Identifier Variable { get; set; } = variable; public AssignOperator? Operator { get; set; } = op; @@ -162,7 +162,7 @@ public override string ToString() }; } -public class Declare(TypeName typename, TextLocation info) : Declaration(typename, info) +public partial class Declare(TypeName typename, TextLocation info) : Declaration(typename, info) { public List Variables { get; set; } = []; @@ -220,7 +220,7 @@ public override string ToString() } } -public class Assign(TextLocation info) : Statement(info) +public partial class Assign(TextLocation info) : Statement(info) { public List Variables { get; set; } = []; @@ -278,7 +278,7 @@ public override string ToString() -public class BlockStatement(TextLocation info) : Statement(info) +public partial class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; From 58343e9a6fca05aa327fdced2f9a8cf9d8dcbe07 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Feb 2026 14:52:33 +0900 Subject: [PATCH 0792/1182] Changed visitors to include typename in override (easier with IDE to select proper override) --- .../VisitorGenerator.cs | 25 +++++++++++-------- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 8 +++--- .../Transformation/StreamAccessPatcher.cs | 4 +-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Stride.Shaders.Generators/VisitorGenerator.cs b/src/Stride.Shaders.Generators/VisitorGenerator.cs index 6b13a410fe..0abd6eb95f 100644 --- a/src/Stride.Shaders.Generators/VisitorGenerator.cs +++ b/src/Stride.Shaders.Generators/VisitorGenerator.cs @@ -35,6 +35,11 @@ private string GenerateVariableName(string name) return variableName; } + + private string GenerateVisitSuffix(INamedTypeSymbol type) + { + return type.Name; + } private void GenerateVisitorsBase(SourceProductionContext context, Compilation compilation, bool generateRewriter, string visitorName, Func isNodeType) { @@ -59,7 +64,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var variableName = GenerateVariableName(type.Name); var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - sb.AppendLine($" public virtual void Visit{type.Name}{genericParameters}({typeName} {variableName})"); + sb.AppendLine($" public virtual void Visit{GenerateVisitSuffix(type)}{genericParameters}({typeName} {variableName})"); sb.AppendLine(" {"); sb.AppendLine($" DefaultVisit({variableName});"); sb.AppendLine(" }"); @@ -73,7 +78,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var variableName = GenerateVariableName(type.Name); var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - sb.AppendLine($" public override void Visit{type.Name}{genericParameters}({typeName} {variableName})"); + sb.AppendLine($" public override void Visit{GenerateVisitSuffix(type)}{genericParameters}({typeName} {variableName})"); sb.AppendLine(" {"); // Process public fields and properties (with getter+setter) var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); @@ -97,7 +102,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c sb.AppendLine($" Visit{(nodeListElementType.IsValueType ? "Item" : visitorName)}List({variableName}.{member.Name});"); } } - sb.AppendLine($" base.Visit{genericParameters}({variableName});"); + sb.AppendLine($" base.Visit{GenerateVisitSuffix(type)}{genericParameters}({variableName});"); sb.AppendLine(" }"); } @@ -119,7 +124,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c } var returnType = type.IsValueType ? "bool" : "TResult"; - sb.AppendLine($" public virtual {returnType} Visit{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine($" public virtual {returnType} Visit{GenerateVisitSuffix(type)}{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); sb.AppendLine("{"); if (type.IsValueType) sb.AppendLine($"return DefaultVisit(ref {variableName});"); @@ -139,7 +144,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; var returnType = type.IsValueType ? "bool" : "SymbolType"; - sb.AppendLine($" public override {returnType} Visit{type.Name}{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); + sb.AppendLine($" public override {returnType} Visit{GenerateVisitSuffix(type)}{genericParameters}({(type.IsValueType ? "ref " : "")}{typeName} {variableName})"); sb.AppendLine("{"); // Process public fields and properties (with getter+setter) var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); @@ -173,11 +178,11 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c } if (type.IsValueType) { - sb.AppendLine($" return base.Visit{genericParameters}(ref {variableName});"); + sb.AppendLine($" return base.Visit{GenerateVisitSuffix(type)}{genericParameters}(ref {variableName});"); } else { - sb.AppendLine($" return (SymbolType)base.Visit{genericParameters}({variableName});"); + sb.AppendLine($" return (SymbolType)base.Visit{GenerateVisitSuffix(type)}{genericParameters}({variableName});"); } sb.AppendLine("}"); } @@ -205,7 +210,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c sb.AppendLine("{"); sb.AppendLine($"public {(!type.IsValueType ? "override" : string.Empty)} void Accept({visitorName}Visitor visitor)"); sb.AppendLine("{"); - sb.AppendLine("visitor.Visit(this);"); + sb.AppendLine($"visitor.Visit{GenerateVisitSuffix(type)}(this);"); sb.AppendLine("}"); if (generateRewriter) { @@ -213,14 +218,14 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c { sb.AppendLine($"public bool Accept({visitorName}Visitor visitor)"); sb.AppendLine("{"); - sb.AppendLine("return visitor.Visit(ref this);"); + sb.AppendLine($"return visitor.Visit{GenerateVisitSuffix(type)}(ref this);"); sb.AppendLine("}"); } else { sb.AppendLine($"public override TResult Accept({visitorName}Visitor visitor)"); sb.AppendLine("{"); - sb.AppendLine("return visitor.Visit(this);"); + sb.AppendLine($"return visitor.Visit{GenerateVisitSuffix(type)}(this);"); sb.AppendLine("}"); } } diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index 5339abc87e..d90a0c3064 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -49,7 +49,7 @@ public static bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext c { var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; var streamsTypeSearch = new StreamsTypeSearch(); - streamsTypeSearch.Visit(functionType); + streamsTypeSearch.VisitType(functionType); if (streamsTypeSearch.Found) methodInfo.HasStreamAccess = true; } @@ -144,16 +144,16 @@ public static bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext c internal class StreamsTypeSearch : TypeWalker { public bool Found { get; private set; } - public override void Visit(StreamsType streamsType) + public override void VisitStreamsType(StreamsType streamsType) { Found = true; } - public override void Visit(GeometryStreamType geometryStreamsType) + public override void VisitGeometryStreamType(GeometryStreamType geometryStreamsType) { Found = true; } - public override void Visit(PatchType patchType) + public override void VisitPatchType(PatchType patchType) { Found = true; } diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 49722ad8ec..13568c9962 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -18,7 +18,7 @@ internal static class StreamAccessPatcher /// private class StreamsTypeReplace(SymbolType streamsReplacement, SymbolType inputReplacement, SymbolType outputReplacement, SymbolType? constantsReplacement) : TypeRewriter { - public override SymbolType Visit(StreamsType streamsType) + public override SymbolType VisitStreamsType(StreamsType streamsType) { return streamsType.Kind switch { @@ -58,7 +58,7 @@ public static void PatchStreamsAccesses( var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); - var newMethodType = (FunctionType)streamTypeReplacer.Visit(methodType); + var newMethodType = (FunctionType)streamTypeReplacer.VisitType(methodType); if (!ReferenceEquals(newMethodType, methodType)) { methodType = newMethodType; From 4eb009d4a9832002cd4ac0ec6cdf9b86f377c60e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Feb 2026 18:23:36 +0900 Subject: [PATCH 0793/1182] effect mixin: use codegen instead of SPIR-V (WIP) --- assets/SDFX/BasicEffect.sdfx | 10 +- .../Examples.Effects.cs | 16 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 165 ----- .../Parsing/SDFX/EffectGenerator.cs | 497 ++++++++++++++ .../Parsing/SDFX/LoggerResult.cs | 175 +++++ .../SDFX/Parsers/EffectStatementParsers.cs | 233 ++----- .../Parsing/SDFX/ReportMessage.cs | 6 +- .../Parsing/SDFX/ShaderWriter.cs | 645 ++++++++++++++++++ .../Parsing/SDSL/AST/Expression.cs | 10 +- .../Parsing/SDSL/AST/Literals.cs | 4 +- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 77 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 127 ++-- .../SDSL/Parsers/Common/CommonParsers.cs | 12 +- .../PrimaryExpressionParsers.cs | 8 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 3 + .../ShaderParsers/CompositionParsers.cs | 2 +- .../ShaderParsers/ShaderClassParser.cs | 35 +- .../StatementParsers/StatementParsers.Flow.cs | 2 +- 18 files changed, 1544 insertions(+), 483 deletions(-) create mode 100644 src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs create mode 100644 src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs create mode 100644 src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs diff --git a/assets/SDFX/BasicEffect.sdfx b/assets/SDFX/BasicEffect.sdfx index 403845cf18..852dba68e7 100644 --- a/assets/SDFX/BasicEffect.sdfx +++ b/assets/SDFX/BasicEffect.sdfx @@ -22,10 +22,14 @@ effect BasicEffect { using params BasicParams; - mixin(A); + mixin compose Target1 = Test123; + mixin compose Target2 += Test123; + mixin macro Test = 1; + mixin A; + mixin (A); if(BasicParams.MixA) - mixin(A); + mixin (A); if(BasicParams.MixB) - mixin(B); + mixin (B); } \ No newline at end of file diff --git a/src/Stride.Shaders.Experiments/Examples.Effects.cs b/src/Stride.Shaders.Experiments/Examples.Effects.cs index f30637528b..83a167d403 100644 --- a/src/Stride.Shaders.Experiments/Examples.Effects.cs +++ b/src/Stride.Shaders.Experiments/Examples.Effects.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDFX; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; @@ -16,11 +17,18 @@ public static partial class Examples public static void CompileBasicEffect() { - var loader = new EffectLoader(); - loader.LoadExternalBuffer("BasicEffect.sdfx", [], out var effectBuffer, out _, out _); - loader.LoadExternalBuffer("BasicEffect", [], out effectBuffer, out _, out _); + var effect = File.ReadAllText("./assets/SDFX/BasicEffect.sdfx"); + var parsed = SDSLParser.Parse(effect); + if (parsed.Errors.Count > 0) + { + throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, parsed.Errors)}"); + } - Spv.Dis(effectBuffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + var effectGenerator = new EffectGenerator(); + effectGenerator.Run(parsed.AST); + var code = effectGenerator.Text; + + Console.WriteLine(code); } public class EffectLoader() : ShaderLoaderBase(new ShaderCache()) diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 70a748ea0b..44a4c9f2a1 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -69,171 +69,6 @@ public override string ToString() } } -public partial class MixinUse(List mixin, TextLocation info) : EffectStatement(info) -{ - public List MixinName { get; set; } = mixin; - - public override void ProcessSymbol(SymbolTable table) - { - } - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - foreach (var mixinName in MixinName) - { - if (mixinName.Path.Count > 0) - throw new NotImplementedException(); - - int[] genericValues = ShaderEffect.CompileGenerics(table, compiler.Context, mixinName.Generics); - - compiler.Builder.Insert(new OpSDSLMixin(mixinName.Name, [.. genericValues])); - } - } - - public override string ToString() - { - return $"mixin {MixinName}"; - } -} -public partial class MixinChild(Mixin mixin, TextLocation info) : EffectStatement(info) -{ - public Mixin MixinName { get; set; } = mixin; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - - public override string ToString() - { - return $"mixin child {MixinName}"; - } -} - -public partial class MixinClone(Mixin mixin, TextLocation info) : EffectStatement(info) -{ - public Mixin MixinName { get; set; } = mixin; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - - public override string ToString() - { - return $"mixin clone {MixinName}"; - } -} - -public partial class MixinConst(string identifier, TextLocation info) : EffectStatement(info) -{ - public string Identifier { get; set; } = identifier; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - -} - -public abstract class Composable(); - - -public abstract class ComposeValue(TextLocation info) : Node(info) -{ - public abstract void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator); -} - -public partial class ComposePathValue(string path, TextLocation info) : ComposeValue(info) -{ - public string Path { get; set; } = path; - - public override void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator) - { - throw new NotImplementedException(); - } - - public override string ToString() - { - return Path.ToString(); - } -} -public partial class ComposeMixinValue(Mixin mixin, TextLocation info) : ComposeValue(info) -{ - public Mixin Mixin { get; set; } = mixin; - - public override void Compile(SymbolTable table, CompilerUnit compiler, Identifier identifier, AssignOperator @operator) - { - var (builder, context) = compiler; - - if (Mixin.Path.Count > 0) - throw new NotImplementedException(); - - var generics = ShaderEffect.CompileGenerics(table, context, Mixin.Generics); - - switch (@operator) - { - case AssignOperator.Simple: - compiler.Builder.Insert(new OpSDSLMixinCompose(identifier.Name, Mixin.Name.Name, new(generics))); - break; - case AssignOperator.Plus: - compiler.Builder.Insert(new OpSDSLMixinComposeArray(identifier.Name, Mixin.Name.Name, new(generics))); - break; - default: - throw new ArgumentException(null, nameof(@operator)); - } - } - - - public override string ToString() - { - return Mixin.ToString(); - } -} - -public partial class MixinCompose(Identifier identifier, AssignOperator op, ComposeValue value, TextLocation info) : EffectStatement(info) -{ - public Identifier Identifier { get; set; } = identifier; - AssignOperator Operator { get; set; } = op; - public ComposeValue ComposeValue { get; set; } = value; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - ComposeValue.Compile(table, compiler, Identifier, Operator); - } - - - public override string ToString() - { - return $"mixin compose {Identifier} {Operator.ToAssignSymbol()} {ComposeValue}"; - } -} -public partial class MixinComposeAdd(Identifier identifier, Identifier source, TextLocation info) : EffectStatement(info) -{ - public Identifier Identifier { get; set; } = identifier; - public Identifier Source { get; set; } = source; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - - public override string ToString() - { - return $"mixin compose {Identifier} += {Source}"; - } -} - -public partial class ComposeParams(Mixin mixin, TextLocation info) : EffectStatement(info) -{ - public Mixin MixinName { get; set; } = mixin; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } -} - public partial class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) { public Identifier ParamsName { get; set; } = name; diff --git a/src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs b/src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs new file mode 100644 index 0000000000..496fe052c0 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs @@ -0,0 +1,497 @@ +using Stride.Core.Shaders.Utility; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDFX; + +public class EffectGenerator : ShaderWriter +{ + private readonly LoggerResult logging = new(); + private Stack contextStack = new(); + private Dictionary blockContexts = new(); + private BlockStatement currentBlock; + + private bool IsParameterDeclaredInContext(string parameter) + { + foreach (var context in contextStack) + { + if (context.DeclaredParameters.Contains(parameter)) + return true; + } + + return false; + } + + public bool Run(Node node) + { + void LogErrors() + { + foreach (var reportMessage in logging.Messages) + { + if (reportMessage.Level == ReportMessageLevel.Error) + { + Write("#error ").WriteLine(reportMessage.ToString()); + } + } + } + + var blockVisitor = new ShaderBlockVisitor(this, logging); + blockVisitor.VisitNode(node); + + if (logging.HasErrors) + { + LogErrors(); + return false; + } + + WriteLine("// "); + WriteLine("// Do not edit this file yourself!"); + WriteLine("//"); + WriteLine("// This code was generated by Stride Shader Mixin Code Generator."); + WriteLine("// To generate it yourself, please install Stride.VisualStudio.Package .vsix"); + WriteLine("// and re-save the associated .sdfx."); + WriteLine("// "); + WriteLine(); + + // No mixin found, just return + if (!blockVisitor.HasMixin && !blockVisitor.HasShaderClassType) + { + WriteLine("// Nothing to generate"); + return true; + } + + // Header of usings declaration + // TODO: Should probably be better to use fully qualified name of types to avoid conflicts. + + WriteLine("using System;"); + WriteLine("using Stride.Core;"); + WriteLine("using Stride.Rendering;"); + WriteLine("using Stride.Graphics;"); + WriteLine("using Stride.Shaders;"); + WriteLine("using Stride.Core.Mathematics;"); + WriteLine("using Buffer = Stride.Graphics.Buffer;"); + WriteLine(); + + // Visit the shader and generate the code + VisitNode(node); + + // If there are any errors log them into the shader + if (logging.HasErrors) + { + LogErrors(); + return false; + } + + return true; + } + + public override void VisitShaderEffect(ShaderEffect shaderEffect) + { + Write("internal static partial class ShaderMixins"); + { + OpenBrace(); + Write("internal partial class"); + Write(" "); + Write(shaderEffect.Name); + WriteSpace(); + Write(" : IShaderMixinBuilder"); + { + OpenBrace(); + // Generate the main generate method for each shader block + Write("public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)"); + { + VisitNode(shaderEffect.Block); + } + + WriteLine(); + WriteLine("[System.Runtime.CompilerServices.ModuleInitializer]"); + WriteLine("internal static void __Initialize__()"); + { + OpenBrace(); + Write("ShaderMixinManager.Register(\"").Write(shaderEffect.Name).Write("\", new ").Write(shaderEffect.Name).WriteLine("());"); + CloseBrace(); + } + CloseBrace(); + } + CloseBrace(); + } + } + + public override void VisitBlockStatement(BlockStatement blockStatement) + { + contextStack.Push(new ShaderBlockContext()); + base.VisitBlockStatement(blockStatement); + contextStack.Pop(); + } + + public override void VisitUsingShaderNamespace(UsingShaderNamespace usingShaderNamespace) + { + Write("using ").Write(string.Join('.', usingShaderNamespace.NamespacePath)).WriteLine(";"); + } + + public override void VisitShaderNamespace(ShaderNamespace shaderNamespace) + { + Write("namespace ").Write(string.Join(".", shaderNamespace.NamespacePath)); + OpenBrace(); + foreach (var node in shaderNamespace.Declarations) + { + VisitNode(node); + } + CloseBrace(); + } + + public override void VisitAssign(Assign assign) + { + if (assign.Variables.Count == 1 + && assign.Variables[0].Value is not null + && TryParameters(assign.Variables[0].Variable, out var typeTarget, out var typeMember)) + { + Write("context.SetParam(").Write(typeTarget).Write(".").Write(typeMember.ToString()).Write(", "); + VisitNode(assign.Variables[0].Value); + Write(")"); + } + else + { + base.VisitAssign(assign); + } + } + + public override void VisitAccessorChainExpression(AccessorChainExpression accessorChainExpression) + { + if (TryParameters(accessorChainExpression, out var typeTarget, out var typeMember)) + { + var key = typeTarget + "." + typeMember; + Write("context.GetParam(").Write(typeTarget).Write(".").Write(typeMember.ToString()).Write(")"); + } + else + { + base.VisitAccessorChainExpression(accessorChainExpression); + } + } + + private bool TryParameters(Expression expression, out string type, out string member) + { + type = null; + member = null; + var accessorChainExpression = expression as AccessorChainExpression; + if (accessorChainExpression == null || accessorChainExpression.Accessors.Count != 1 || !(accessorChainExpression.Source is ExternalShaderAccess accessMember)) + return false; + + var name = accessorChainExpression.Source.ToString(); + + bool foundDeclaredParameters = false; + if (IsParameterDeclaredInContext(name)) + { + type = name; + member = accessMember.ToString(); + foundDeclaredParameters = true; + } + + return foundDeclaredParameters; + } + + + private void ExtractGenericParameters(Expression mixinStatementValue, out Expression mixinName, out ShaderExpressionList? genericParameters) + { + if (mixinStatementValue is GenericIdentifier genericIdentifier) + { + mixinName = genericIdentifier.Name; + genericParameters = genericIdentifier.Generics; + } + else + { + mixinName = mixinStatementValue; + genericParameters = null; + } + } + + private void WriteGenericParameters(ShaderExpressionList? genericParameters) + { + if (genericParameters != null) + { + foreach (var genericParameter in genericParameters) + { + Write(", "); + VisitNode(genericParameter); + } + } + } + + public override void VisitMixin(Mixin mixinStatement) + { + switch (mixinStatement.Type) + { + case MixinStatementType.Default: + { + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + + WriteLinkLine(mixinStatement); + Write("context.Mixin(mixin, "); + WriteMixinName(mixinName); + WriteGenericParameters(genericParameters); + WriteLine(");"); + break; + } + case MixinStatementType.Child: + { + // mixin child can come in 2 flavour: + // 1) mixin child MyEffect + // => equivalent to 2) with "mixin child MyEffect = MyEffect" + // 2) mixin child MyGenericEffectName = MyEffect + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + var childName = mixinStatement.Target ?? (Identifier)mixinStatement.Value; + { + WriteLinkLine(mixinStatement); + Write("if (context.ChildEffectName == "); + WriteMixinName(childName); + Write(")"); + OpenBrace(); + + WriteLinkLine(mixinStatement); + Write("context.Mixin(mixin, "); + WriteMixinName(mixinName); + WriteGenericParameters(genericParameters); + WriteLine(");"); + WriteLine("return;"); + + CloseBrace(); + } + break; + } + case MixinStatementType.Remove: + { + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + + WriteLinkLine(mixinStatement); + Write("context.RemoveMixin(mixin, "); + WriteMixinName(mixinName); + WriteGenericParameters(genericParameters); + WriteLine(");"); + break; + } + case MixinStatementType.Macro: + { + WriteLinkLine(mixinStatement); + string macroName; + Expression macroValue; + + if (mixinStatement.Target != null) + { + macroName = mixinStatement.Target; + macroValue = mixinStatement.Value; + } + else + { + var variableReference = mixinStatement.Value as AccessorChainExpression; + if (variableReference == null || !(variableReference.Source is Identifier id) || !IsParameterDeclaredInContext(id.Name)) + { + logging.Error("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info); + macroName = "#INVALID_MACRO_NAME"; + macroValue = mixinStatement.Value; + } + else + { + macroName = ((Identifier)variableReference.Accessors[0]).Name; + macroValue = mixinStatement.Value; + } + } + + Write("mixin.AddMacro("); + Write(macroName); + Write(", "); + VisitNode(macroValue); + WriteLine(");"); + break; + } + case MixinStatementType.ComposeSet: + case MixinStatementType.ComposeAdd: + { + if (mixinStatement.Target == null) + { + logging.Error("Expecting assign expression for composition", mixinStatement.Value.Info); + return; + } + + var addCompositionFunction = "PushComposition"; + + // If it's a +=, let's create or complete a ShaderArraySource + if (mixinStatement.Type == MixinStatementType.ComposeAdd) + { + addCompositionFunction = "PushCompositionArray"; + } + + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + + OpenBrace(); + WriteLinkLine(mixinStatement); + Write("var __mixinToCompose__ = "); + WriteMixinName(mixinName); + WriteLine(";"); + WriteLine("var __subMixin = new ShaderMixinSource();"); + + WriteLinkLine(mixinStatement); + Write("context.").Write(addCompositionFunction).Write("(mixin, "); + WriteStringOrExpression(mixinStatement.Target); + WriteLine(", __subMixin);"); + + WriteLinkLine(mixinStatement); + Write("context.Mixin(__subMixin, __mixinToCompose__"); + WriteGenericParameters(genericParameters); + WriteLine(");"); + + WriteLinkLine(mixinStatement); + WriteLine("context.PopComposition();"); + CloseBrace(); + break; + } + } + } + + private void WriteMixinName(Expression mixinName) + { + WriteStringOrExpression(mixinName); + } + + private void WriteStringOrExpression(Expression expr) + { + // Output between "" only if the mixin name is only a variable + if (expr is Identifier) + Write("\""); + VisitNode(expr); + if (expr is Identifier) + Write("\""); + } + + public override void VisitUsingParams(UsingParams usingParametersStatement) + { + if (contextStack.Count == 0) + { + logging.Error("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Info); + return; + } + + var currentContext = contextStack.Peek(); + HashSet usings = currentContext.DeclaredParameters; + + var typeName = usingParametersStatement.ParamsName.Name; + if (usings.Contains(typeName)) + { + logging.Error("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Info); + return; + } + + usings.Add(typeName); + } + + public override void VisitShaderClass(ShaderClass shaderClass) + { + // Skip shaders + } + + public override void VisitEffectParameters(EffectParameters effectParameters) + { + Write("[DataContract]"); + WriteLinkLine(effectParameters); + Write("public partial class"); + Write(" "); + Write(effectParameters.Name); + WriteSpace(); + Write(": ShaderMixinParameters"); + { + OpenBrace(); + + foreach (var parameter in effectParameters.Parameters) + { + WriteLinkLine(parameter); + VisitNode(parameter.Type); + WriteSpace(); + VisitNode(parameter.Identifier); + if (parameter.DefaultValue != null) + throw new NotImplementedException(); + WriteLine(";"); + } + + CloseBrace(false).Write(";").WriteLine(); + } + } + + internal bool IsParameterKey(ShaderElement element) + { + if (element is not (ShaderVariable or ShaderMember)) return false; + + var storageClass = element switch + { + ShaderVariable v => v.StorageClass, + ShaderMember m => m.StorageClass, + }; + + // TODO: + // Don't generate a parameter key for variable stored storage qualifier: extern, const, compose, stream + //if (variable.Qualifiers.Contains(HlslStorageQualifier.Extern) || + // variable.Qualifiers.Contains(StorageQualifier.Const) || + // variable.Qualifiers.Contains(StrideStorageQualifier.Compose) || + // variable.Qualifiers.Contains(StrideStorageQualifier.PatchStream) || + // variable.Qualifiers.Contains(StorageQualifier.GroupShared) || + // variable.Qualifiers.Contains(StrideStorageQualifier.Stream)) + // return false; + // + //// Don't generate a parameter key for [Link] or [RenameLink] + //if (variable.Attributes.OfType().Any(x => x.Name == "RenameLink" || x.Name == "Link")) + // return false; + + return true; + } + + private class ShaderBlockContext + { + public readonly HashSet DeclaredParameters = new HashSet(); + } + + /// + /// Internal visitor to precalculate all available Parameters in the context + /// + private sealed class ShaderBlockVisitor : NodeWalker + { + private readonly LoggerResult logging; + private ShaderBlockContext currentContext; + + private readonly EffectGenerator parent; + + public ShaderBlockVisitor(EffectGenerator parent, LoggerResult logging) + { + this.parent = parent; + this.logging = logging; + } + + public bool HasMixin { get; private set; } + + public bool HasShaderClassType { get; private set; } + + public override void VisitEffectParameters(EffectParameters paramsBlock) + { + HasMixin = true; + } + + public override void VisitShaderClass(ShaderClass shaderClassType) + { + // Check if there are any parameter keys in ShaderClassType and ConstantBuffer + CheckParameterKeys(shaderClassType.Elements.OfType()); + CheckParameterKeys(shaderClassType.Elements.OfType().SelectMany(cbuffer => cbuffer.Members)); + } + + private void CheckParameterKeys(IEnumerable variables) + { + foreach (var variable in variables) + { + if (!HasShaderClassType) + { + if (parent.IsParameterKey(variable)) + { + HasShaderClassType = true; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs b/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs new file mode 100644 index 0000000000..f0cdce8069 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs @@ -0,0 +1,175 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Collections.Generic; +using System.IO; +using System.Text; +using Stride.Shaders.Parsing; + +namespace Stride.Core.Shaders.Utility +{ + /// + /// A class to collect parsing/expression messages. + /// + public class LoggerResult + { + /// + /// Initializes a new instance of the class. + /// + public LoggerResult() + { + this.Messages = new List(); + } + + /// + /// Gets or sets a value indicating whether this instance has errors. + /// + /// + /// true if this instance has errors; otherwise, false. + /// + public bool HasErrors { get; set; } + + /// + /// Gets or sets the messages. + /// + /// + /// The messages. + /// + public IList Messages { get; private set; } + + /// + /// Dumps the messages. + /// + /// The level. + /// The writer. + public void DumpMessages(ReportMessageLevel level, TextWriter writer) + { + foreach (var reportMessage in this.Messages) + { + if (reportMessage.Level >= level) + { + writer.WriteLine(reportMessage); + } + } + } + + /// + /// Copies all messages to another instance. + /// + /// The results. + public void CopyTo(LoggerResult results) + { + foreach (var reportMessage in this.Messages) + { + results.Messages.Add(reportMessage); + } + + if (HasErrors) + results.HasErrors = true; + } + + /// + /// Logs an Error with the specified message. + /// + /// The message. + /// The span. + public void Error(MessageCode message, TextLocation span) + { + this.AddMessage(ReportMessageLevel.Error, message, span); + } + + /// + /// Logs an Error with the specified message. + /// + /// The message. + /// The span. + /// The parameters. + public void Error(MessageCode message, TextLocation span, params object[] parameters) + { + this.AddMessage(ReportMessageLevel.Error, message, span, parameters); + } + + /// + /// Logs an Info with the specified message. + /// + /// The message. + /// The span. + public void Info(MessageCode message, TextLocation span) + { + this.AddMessage(ReportMessageLevel.Info, message, span); + } + + /// + /// Logs an Info with the specified message. + /// + /// The message. + /// The span. + /// The parameters. + public void Info(MessageCode message, TextLocation span, params object[] parameters) + { + this.AddMessage(ReportMessageLevel.Info, message, span, parameters); + } + + /// + /// Logs an Warning with the specified message. + /// + /// The message. + /// The span. + public void Warning(MessageCode message, TextLocation span) + { + this.AddMessage(ReportMessageLevel.Warning, message, span); + } + + /// + /// Logs an Warning with the specified message. + /// + /// The message. + /// The span. + /// The parameters. + public void Warning(MessageCode message, TextLocation span, params object[] parameters) + { + this.AddMessage(ReportMessageLevel.Warning, message, span, parameters); + } + + /// + /// Adds the message. + /// + /// The type. + /// The message. + /// The span. + protected void AddMessage(ReportMessageLevel level, MessageCode message, TextLocation span) + { + if (level == ReportMessageLevel.Error) this.HasErrors = true; + this.Messages.Add(new ReportMessage(level, message.Code, message.Text, span)); + } + + /// + /// Adds the message. + /// + /// The type. + /// The message. + /// The span. + /// The parameters. + protected void AddMessage(ReportMessageLevel level, MessageCode message, TextLocation span, params object[] parameters) + { + if (level == ReportMessageLevel.Error) this.HasErrors = true; + this.Messages.Add(new ReportMessage(level, message.Code, string.Format(message.Text, parameters), span)); + } + + public override string ToString() + { + var text = new StringBuilder(); + if (HasErrors) + { + foreach (var reportMessage in Messages) + { + text.AppendLine(reportMessage.ToString()); + } + } + else + { + text.AppendLine("OK"); + } + return text.ToString(); + } + } +} diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs index 3c7e7cc733..a58c4d85ac 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -21,36 +21,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p1; return true; } - else if (MixinCompose(ref scanner, result, out var p2)) + else if (Mixin(ref scanner, result, out var p2)) { parsed = p2; return true; } - else if (MixinComposeAdd(ref scanner, result, out var mca) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = mca; - return true; - } - else if (MixinChild(ref scanner, result, out var mc) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = mc; - return true; - } - else if (MixinClone(ref scanner, result, out var mcl) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = mcl; - return true; - } - else if (MixinConst(ref scanner, result, out var mconst) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = mconst; - return true; - } - else if (MixinUse(ref scanner, result, out var p3) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = p3; - return true; - } else if (EffectControlsParser.Control(ref scanner, result, out var control)) { parsed = control; @@ -86,42 +61,8 @@ public static bool Statement(ref TScanner scanner, ParseResult result, => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinCompose(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new MixinComposeParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinComposeAdd(ref TScanner scanner, ParseResult result, out MixinComposeAdd parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new MixinComposeAddParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinUse(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new MixinUseParser().Match(ref scanner, result, out parsed, orError); - public static bool MixinChild(ref TScanner scanner, ParseResult result, out MixinChild parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "child"], advance: true) - && SDSL.Parsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) - ) - { - parsed = new(mixin, scanner[position..scanner.Position]); - return true; - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - public static bool MixinClone(ref TScanner scanner, ParseResult result, out MixinClone parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "clone"], advance: true) - && SDSL.Parsers.FollowedByDel(ref scanner, result, ShaderClassParsers.Mixin, out Mixin mixin, withSpaces: true, advance: true) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) - ) - { - parsed = new(mixin, scanner[position..scanner.Position]); - return true; - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - public static bool MixinConst(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new MixinConstParser().Match(ref scanner, result, out parsed, orError); + public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => new MixinParser().Match(ref scanner, result, out parsed, orError); public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); @@ -179,152 +120,76 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct MixinConstParser : IParser +public record struct MixinParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinConst parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if ( - SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "macro"], advance: true) - || SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "const"], advance: true) - ) + var mixinType = MixinStatementType.Default; + if (Tokens.Literal("mixin", ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, null!, out _)) { - SDSL.Parsers.Spaces0(ref scanner, result, out _); - var tmp = scanner.Position; - SDSL.Parsers.Until(ref scanner, ';'); - if (Tokens.Char(';', ref scanner)) + if (Tokens.AnyOf(["compose", "child", "clone", "macro"], ref scanner, out var mixinTypeString, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { - parsed = new(scanner.Memory[tmp..scanner.Position].ToString().Trim(), scanner[position..scanner.Position]); - return true; + mixinType = mixinTypeString switch + { + "compose" => MixinStatementType.ComposeSet, + "child" => MixinStatementType.Child, + "clone" => MixinStatementType.Clone, + "macro" => MixinStatementType.Macro, + "remove" => MixinStatementType.Remove, + _ => throw new Exception("Invalid mixin type") + }; } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[position], scanner.Memory)); - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} -public record struct MixinComposeParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) - && LiteralsParser.Identifier(ref scanner, result, out var name) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && Tokens.AnyOf(["=", "+="], ref scanner, out var op, advance: true) - ) - { - if( - SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && ComposeValue(ref scanner, result, out var composeValue) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) - ) - { - parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue, scanner[position..scanner.Position]); - return true; - } - else if( - SDSL.Parsers.Spaces0(ref scanner, result, out _) - && ComposeValue(ref scanner, result, out var composeValue2) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) - ) + if (AssignOrExpression(ref scanner, result, out var statement) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - parsed = new MixinCompose(name, op.ToAssignOperator(), composeValue2, scanner[position..scanner.Position]); + if (mixinType is MixinStatementType.ComposeSet or MixinStatementType.Child or MixinStatementType.Macro + && statement is Assign { Variables: [{ Value: {} value, Variable: Identifier variable }] } assign) + { + if (assign.Variables[0].Operator == AssignOperator.Plus && mixinType == MixinStatementType.ComposeSet) + mixinType = MixinStatementType.ComposeAdd; + parsed = new Mixin(mixinType, variable, value, scanner[position..scanner.Position]); + } + else if (statement is ExpressionStatement expressionStatement) + { + parsed = new Mixin(mixinType, null, expressionStatement.Expression, scanner[position..scanner.Position]); + } + else + { + throw new Exception("Invalid mixin statement"); + } return true; } - } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - - public static bool ComposeValue(ref TScanner scanner, ParseResult result, out ComposeValue value, in ParseError? orError = null) where TScanner : struct, IScanner + + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; if( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) - && ( - SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) - || SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) - ) + PostfixParser.Postfix(ref scanner, result, out var variable) + && SDSL.Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) + && SDSL.Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) ) { - value = new ComposeMixinValue(mixin, scanner[position..scanner.Position]); - return true; - } - else - { - scanner.Position = position; - if(Tokens.IdentifierFirstChar(ref scanner, advance: true)) + parsed = new Assign(scanner[position..scanner.Position]) { - while( - Tokens.LetterOrDigit(ref scanner, advance: true) - || Tokens.Char('_', ref scanner, advance: true) - || Tokens.Char('.', ref scanner, advance: true) - ); - if( - SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) - || SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) - ) - { - value = new ComposePathValue(scanner.Memory[position..scanner.Position].ToString(), scanner[position..scanner.Position]); - return true; - } - } + Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] + }; + return true; } - return SDSL.Parsers.Exit(ref scanner, result, out value, position); - } -} - -public record struct MixinComposeAddParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinComposeAdd parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - SDSL.Parsers.SequenceOf(ref scanner, ["mixin", "compose"], advance: true) - && LiteralsParser.Identifier(ref scanner, result, out var name) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && Tokens.Literal("+=", ref scanner, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - + scanner.Position = position; + if( + ExpressionParser.Expression(ref scanner, result, out var expression) + && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), true) ) { - var start = scanner.Position; - SDSL.Parsers.Until(ref scanner, ';'); - parsed = new MixinComposeAdd(name, new(scanner.Memory[start..scanner.Position].ToString().Trim(), scanner[start..scanner.Position]), scanner[position..scanner.Position]); + parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - -public record struct MixinUseParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out MixinUse parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Tokens.Literal("mixin", ref scanner, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - ) - { - var betweenParenthesis = SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true); - if (SDSL.Parsers.Repeat(ref scanner, result, ShaderClassParsers.Mixin, out List mixins, 1, withSpaces: true, separator: ",")) - { - var checkParen = betweenParenthesis == SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true); - var finished = SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true); - if (finished && checkParen) - { - parsed = new(mixins, scanner[position..scanner.Position]); - return finished; - } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs b/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs index 5214bcd2a0..a99585e53b 100644 --- a/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs +++ b/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs @@ -1,6 +1,6 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; +using Stride.Shaders.Parsing; namespace Stride.Core.Shaders.Utility { @@ -19,7 +19,7 @@ public class ReportMessage /// /// Span and location attached to this message. /// - public SourceSpan Span; + public TextLocation Span; /// /// The error code. @@ -49,7 +49,7 @@ public ReportMessage() /// The error code. /// The text. /// The span. - public ReportMessage(ReportMessageLevel level, string code, string text, SourceSpan span) + public ReportMessage(ReportMessageLevel level, string code, string text, TextLocation span) { this.Level = level; this.Code = code; diff --git a/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs b/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs new file mode 100644 index 0000000000..3a9821bb48 --- /dev/null +++ b/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs @@ -0,0 +1,645 @@ +using System.Text; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Core; + +public class ShaderWriter : NodeWalker +{ + /// + /// Gets or sets a value indicating whether [enable new line]. + /// + /// + /// true if [enable new line]; otherwise, false. + /// + protected bool EnableNewLine { get; set; } = true; + + /// + /// Gets or sets the indent level. + /// + /// + /// The indent level. + /// + private int IndentLevel { get; set; } + + /// + /// Gets or sets a value indicating whether [new line]. + /// + /// + /// true if [new line]; otherwise, false. + /// + private bool NewLine { get; set; } + + /// + /// Gets or sets the string builder. + /// + /// + /// The string builder. + /// + private StringBuilder StringBuilder { get; set; } = new(); + + private void PrefixIndent() + { + if (NewLine) + { + for (int i = 0; i < IndentLevel; ++i) + Append(" "); + + NewLine = false; + } + } + + /// + /// Gets the text. + /// + public string Text => StringBuilder.ToString(); + + /// + /// Indents this instance. + /// + /// + /// this instance + /// + public ShaderWriter Indent() + { + IndentLevel++; + return this; + } + + /// + /// Outdents this instance. + /// + /// + /// this instance + /// + public ShaderWriter Outdent() + { + IndentLevel--; + return this; + } + + /// + /// Appends the specified text. + /// + /// + /// The text. + /// + /// + /// this instance + /// + protected ShaderWriter Append(string text) + { + StringBuilder.Append(text); + return this; + } + + /// + /// Closes the brace. + /// + /// + /// if set to true [new line]. + /// + /// + /// This instance + /// + protected ShaderWriter CloseBrace(bool newLine = true) + { + Outdent(); + Write("}"); + if (newLine) WriteLine(); + + return this; + } + + /// + /// Opens the brace. + /// + /// + /// This instance + /// + protected ShaderWriter OpenBrace() + { + WriteLine(); + Write("{"); + WriteLine(); + Indent(); + return this; + } + + /// + /// Writes the line. + /// + /// + /// This instance + /// + public ShaderWriter WriteLine() + { + if (EnableNewLine) + { + StringBuilder.AppendLine(); + NewLine = true; + } + + return this; + } + + /// + /// Writes the line. + /// + /// + /// The text. + /// + /// + /// this instance + /// + public ShaderWriter WriteLine(string text) + { + if (EnableNewLine) + { + PrefixIndent(); + StringBuilder.AppendLine(text); + NewLine = true; + } + else StringBuilder.Append(text); + + return this; + } + + /// + /// Writes the space. + /// + /// + /// this instance + /// + public ShaderWriter WriteSpace() + { + Append(" "); + return this; + } + + /// + /// Writes the specified text. + /// + /// + /// The text. + /// + /// + /// this instance + /// + public ShaderWriter Write(string text) + { + PrefixIndent(); + Append(text); + return this; + } + + /// + /// Writes the content of the statement. + /// + /// + /// The statement. + /// + protected void WriteStatementContent(Statement statement) + { + if (statement is BlockStatement) + { + VisitNode(statement); + } + else + { + WriteLine(); + Indent(); + VisitNode(statement); + Outdent(); + } + } + + public override void VisitIdentifier(Identifier identifier) + { + Write(identifier.Name); + } + + public override void VisitGenericIdentifier(GenericIdentifier identifier) + { + Write(identifier.Name); + if (identifier.Generics != null && identifier.Generics.Values.Count > 0) + { + Write("<"); + for (var i = 0; i < identifier.Generics.Values.Count; i++) + { + VisitNode(identifier.Generics.Values[i]); + if (i < identifier.Generics.Values.Count - 1) + Write(",").WriteSpace(); + } + Write(">"); + } + } + + public override void VisitExternalShaderAccess(ExternalShaderAccess externalShaderAccess) + { + VisitNode(externalShaderAccess.Mixin); + } + + public override void VisitTypeName(TypeName typeName) + { + Write(typeName.Name); + if (typeName.Generics.Count > 0) + { + Write("<"); + for (var i = 0; i < typeName.Generics.Count; i++) + { + VisitNode(typeName.Generics[i]); + if (i < typeName.Generics.Count - 1) Write(",").WriteSpace(); + } + Write(">"); + } + if (typeName.IsArray) + { + foreach (var size in typeName.ArraySize!) + { + Write("["); + VisitNode(size); + Write("]"); + } + } + } + + public override void VisitIntegerLiteral(IntegerLiteral integerLiteral) + { + Write(integerLiteral.Value.ToString()); + } + + public override void VisitFloatLiteral(FloatLiteral floatLiteral) + { + Write(floatLiteral.Value.ToString()); + } + + public override void VisitBoolLiteral(BoolLiteral boolLiteral) + { + Write(boolLiteral.Value ? "true" : "false"); + } + + public override void VisitStringLiteral(StringLiteral stringLiteral) + { + Write("\"").Write(stringLiteral.Value).Write("\""); + } + + public override void VisitBinaryExpression(BinaryExpression binaryExpression) + { + Write("("); + VisitNode(binaryExpression.Left); + WriteSpace().Write(binaryExpression.Op.ToSymbol()).WriteSpace(); + VisitNode(binaryExpression.Right); + Write(")"); + } + + public override void VisitPrefixExpression(PrefixExpression prefixExpression) + { + Write(prefixExpression.Operator.ToSymbol()); + VisitNode(prefixExpression.Expression); + } + + public override void VisitPostfixIncrement(PostfixIncrement postfixIncrement) + { + Write(postfixIncrement.Operator.ToSymbol()); + } + + public override void VisitMethodCall(MethodCall methodCall) + { + VisitNode(methodCall.Name); + Write("("); + for (var i = 0; i < methodCall.Arguments.Values.Count; i++) + { + VisitNode(methodCall.Arguments.Values[i]); + if (i < methodCall.Arguments.Values.Count - 1) Write(",").WriteSpace(); + } + Write(")"); + } + + public override void VisitIndexerExpression(IndexerExpression indexerExpression) + { + Write("["); + VisitNode(indexerExpression.Index); + Write("]"); + } + + public override void VisitCastExpression(CastExpression castExpression) + { + Write("("); + VisitNode(castExpression.TypeName); + Write(")"); + VisitNode(castExpression.Expression); + } + + public override void VisitTernaryExpression(TernaryExpression ternaryExpression) + { + Write("("); + VisitNode(ternaryExpression.Condition); + WriteSpace().Write("?").WriteSpace(); + VisitNode(ternaryExpression.Left); + WriteSpace().Write(":").WriteSpace(); + VisitNode(ternaryExpression.Right); + Write(")"); + } + + public override void VisitAccessorChainExpression(AccessorChainExpression accessorChainExpression) + { + VisitNode(accessorChainExpression.Source); + for (var i = 0; i < accessorChainExpression.Accessors.Count; i++) + { + var accessor = accessorChainExpression.Accessors[i]; + if (accessor is Identifier or MethodCall) Write("."); + VisitNode(accessor); + } + } + + public override void VisitExpressionStatement(ExpressionStatement expressionStatement) + { + Write(string.Empty); // Ensure indent + VisitNode(expressionStatement.Expression); + WriteLine(";"); + } + + public override void VisitReturn(Return @return) + { + Write("return"); + if (@return.Value != null) + { + WriteSpace(); + VisitNode(@return.Value); + } + WriteLine(";"); + } + + public override void VisitDeclare(Declare declare) + { + Write(string.Empty); // Ensure indent + VisitNode(declare.TypeName); + WriteSpace(); + for (var i = 0; i < declare.Variables.Count; i++) + { + VisitNode(declare.Variables[i]); + if (i < declare.Variables.Count - 1) Write(",").WriteSpace(); + } + WriteLine(";"); + } + + public override void VisitVariableAssign(VariableAssign variableAssign) + { + VisitNode(variableAssign.Variable); + if (variableAssign.Value != null) + { + WriteSpace().Write(variableAssign.Operator?.ToAssignSymbol() ?? "=").WriteSpace(); + VisitNode(variableAssign.Value); + } + } + + public override void VisitDeclaredVariableAssign(DeclaredVariableAssign declaredVariableAssign) + { + Write(string.Empty); // Ensure indent + VisitNode(declaredVariableAssign.TypeName); + WriteSpace(); + VisitNode(declaredVariableAssign.Variable); + if (declaredVariableAssign.Value != null) + { + WriteSpace().Write(declaredVariableAssign.Operator?.ToAssignSymbol() ?? "=").WriteSpace(); + VisitNode(declaredVariableAssign.Value); + } + WriteLine(";"); + } + + public override void VisitAssign(Assign assign) + { + Write(string.Empty); // Ensure indent + for (var i = 0; i < assign.Variables.Count; i++) + { + VisitNode(assign.Variables[i]); + if (i < assign.Variables.Count - 1) Write(",").WriteSpace(); + } + WriteLine(";"); + } + + public override void VisitShaderClass(ShaderClass shaderClass) + { + Write("shader").WriteSpace(); + VisitNode(shaderClass.Name); + if (shaderClass.Generics != null && shaderClass.Generics.Parameters.Count > 0) + { + Write("<"); + for (var i = 0; i < shaderClass.Generics.Parameters.Count; i++) + { + var p = shaderClass.Generics.Parameters[i]; + VisitNode(p.TypeName); + WriteSpace(); + VisitNode(p.Name); + if (i < shaderClass.Generics.Parameters.Count - 1) Write(",").WriteSpace(); + } + Write(">"); + } + + if (shaderClass.Mixins.Count > 0) + { + WriteSpace().Write(":").WriteSpace(); + for (var i = 0; i < shaderClass.Mixins.Count; i++) + { + VisitNode(shaderClass.Mixins[i]); + // Mixins can have generics too but let's see if Mixin class has them + if (i < shaderClass.Mixins.Count - 1) Write(",").WriteSpace(); + } + } + + WriteLine(); + OpenBrace(); + foreach (var element in shaderClass.Elements) + { + VisitNode(element); + } + CloseBrace(); + } + + public override void VisitShaderMember(ShaderMember shaderMember) + { + if (shaderMember.Attributes != null && shaderMember.Attributes.Count > 0) + { + Write("["); + for (var i = 0; i < shaderMember.Attributes.Count; i++) + { + VisitNode(shaderMember.Attributes[i]); + if (i < shaderMember.Attributes.Count - 1) Write(",").WriteSpace(); + } + WriteLine("]"); + } + + Write(string.Empty); // Indent + if (shaderMember.IsStaged) Write("stage").WriteSpace(); + if (shaderMember.StreamKind != StreamKind.None) Write(shaderMember.StreamKind.ToString().ToLowerInvariant()).WriteSpace(); + if (shaderMember.StorageClass != StorageClass.None) Write(shaderMember.StorageClass.ToString().ToLowerInvariant()).WriteSpace(); + + VisitNode(shaderMember.TypeName); + WriteSpace(); + VisitNode(shaderMember.Name); + if (shaderMember.Value != null) + { + WriteSpace().Write("=").WriteSpace(); + VisitNode(shaderMember.Value); + } + WriteLine(";"); + } + + public override void VisitShaderMethod(ShaderMethod shaderMethod) + { + Write(string.Empty); // Indent + if (shaderMethod.IsStaged) Write("stage").WriteSpace(); + if (shaderMethod.IsOverride) Write("override").WriteSpace(); + if (shaderMethod.IsStatic) Write("static").WriteSpace(); + + VisitNode(shaderMethod.ReturnTypeName); + WriteSpace(); + VisitNode(shaderMethod.Name); + Write("("); + for (var i = 0; i < shaderMethod.Parameters.Count; i++) + { + var p = shaderMethod.Parameters[i]; + VisitNode(p.TypeName); + WriteSpace(); + VisitNode(p.Name); + if (i < shaderMethod.Parameters.Count - 1) Write(",").WriteSpace(); + } + Write(")"); + + if (shaderMethod.Body != null) + { + WriteStatementContent(shaderMethod.Body); + } + else + { + WriteLine(";"); + } + } + + public override void VisitAnyShaderAttribute(AnyShaderAttribute anyShaderAttribute) + { + VisitNode(anyShaderAttribute.Name); + if (anyShaderAttribute.Parameters.Count > 0) + { + Write("("); + for (var i = 0; i < anyShaderAttribute.Parameters.Count; i++) + { + VisitNode(anyShaderAttribute.Parameters[i]); + if (i < anyShaderAttribute.Parameters.Count - 1) Write(",").WriteSpace(); + } + Write(")"); + } + } + + public override void VisitBreak(Break breakStatement) + { + WriteLine("break;"); + } + + public override void VisitContinue(Continue continueStatement) + { + WriteLine("continue;"); + } + + public override void VisitDiscard(Discard discardStatement) + { + WriteLine("discard;"); + } + + public override void VisitConditionalFlow(ConditionalFlow conditionalFlow) + { + VisitNode(conditionalFlow.If); + foreach (var elseIf in conditionalFlow.ElseIfs) + { + VisitNode(elseIf); + } + + if (conditionalFlow.Else != null) + { + VisitNode(conditionalFlow.Else); + } + } + + public override void VisitFor(For forStatement) + { + Write("for").WriteSpace().Write("("); + VisitNode(forStatement.Initializer); + WriteSpace(); + VisitNode(forStatement.Condition); + Write(";").WriteSpace(); + for (var i = 0; i < forStatement.Update.Count; i++) + { + VisitNode(forStatement.Update[i]); + if (i < forStatement.Update.Count - 1) Write(",").WriteSpace(); + } + Write(")"); + WriteStatementContent(forStatement.Body); + } + + public override void VisitWhile(While whileStatement) + { + Write("while").WriteSpace().Write("("); + VisitNode(whileStatement.Condition); + Write(")"); + WriteStatementContent(whileStatement.Body); + } + + public override void VisitForEach(ForEach forEach) + { + WriteLinkLine(forEach); + Write("foreach").WriteSpace().Write("("); + VisitNode(forEach.TypeName); + WriteSpace(); + VisitNode(forEach.Variable); + WriteSpace().Write("in").WriteSpace(); + VisitNode(forEach.Collection); + Write(")"); + WriteStatementContent(forEach.Body); + } + + public override void VisitBlockStatement(BlockStatement blockStatement) + { + WriteLinkLine(blockStatement); + OpenBrace(); + foreach (var statement in blockStatement.Statements) + { + VisitNode(statement); + } + + CloseBrace(); + } + + public override void VisitIf(If @if) + { + Write("if").WriteSpace().Write("("); + VisitNode(@if.Condition); + Write(")"); + WriteStatementContent(@if.Body); + } + + public override void VisitElseIf(ElseIf elseIf) + { + Write("else if").WriteSpace().Write("("); + VisitNode(elseIf.Condition); + Write(")"); + WriteStatementContent(elseIf.Body); + } + + public override void VisitElse(Else @else) + { + Write("else"); + WriteStatementContent(@else.Body); + } + + public override void DefaultVisit(Node node) + { + //throw new NotImplementedException($"No shader text writer for {node.GetType().Name}"); + } + + protected ShaderWriter WriteLinkLine(Node node) + { + return this; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 9d32a92e5d..9c0a65c111 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -366,9 +366,9 @@ public override string ToString() /// /// Represents an accessed mixin. /// -public partial class MixinAccess(Mixin mixin, TextLocation info) : Expression(info) +public partial class ExternalShaderAccess(GenericIdentifier mixin, TextLocation info) : Expression(info) { - public Mixin Mixin { get; set; } = mixin; + public GenericIdentifier Mixin { get; set; } = mixin; public Symbol ResolvedSymbol { get; set; } @@ -409,10 +409,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) return Identifier.EmitSymbol(builder, context, ResolvedSymbol, builder.CurrentFunction == null); } - public override string ToString() - { - return $"{Mixin}"; - } + + public override string ToString() => Mixin.ToString(); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index 8522753f25..a917b1240a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -331,7 +331,9 @@ public override string ToString() => $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; } -public partial class Identifier(string name, TextLocation info) : Literal(info) +public abstract partial class IdentifierBase(TextLocation info) : Literal(info); + +public partial class Identifier(string name, TextLocation info) : IdentifierBase(info) { internal bool AllowStreamVariables { get; set; } public string Name { get; set; } = name; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index fafa299faf..deb1be1b4a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -36,7 +36,7 @@ public partial class ShaderClass(Identifier name, TextLocation info) : ShaderDec public Identifier Name { get; set; } = name; public List Elements { get; set; } = []; public ShaderParameterDeclarations? Generics { get; set; } - public List Mixins { get; set; } = []; + public List Mixins { get; set; } = []; // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) @@ -650,25 +650,68 @@ public partial class ShaderGenerics(Identifier typename, Identifier name, TextLo public Identifier TypeName { get; set; } = typename; } -public partial class Mixin(Identifier name, TextLocation info) : Node(info) +/// +/// Type of a mixin. +/// +public enum MixinStatementType { - public List Path { get; set; } = []; - public Identifier Name { get; set; } = name; - public ShaderExpressionList? Generics { get; set; } - public override string ToString() - => Generics switch - { - null => Name.Name, - _ => $"{Name}<{Generics}>" - }; + /// + /// The default mixin (standard mixin). + /// + Default, + + /// + /// The compose mixin used to set a composition (using =). + /// + ComposeSet, + + /// + /// The compose mixin used to add a composition (using +=). + /// + ComposeAdd, + + /// + /// The child mixin used to specify a children shader. + /// + Child, + + /// + /// The clone mixin to clone the current mixins where the clone is emitted. + /// + Clone, + + /// + /// The remove mixin to remove a mixin from current mixins. + /// + Remove, + + /// + /// The macro mixin to declare a variable to be exposed in the mixin + /// + Macro, + + } -public abstract class ShaderMixinValue(TextLocation info) : Node(info); -public partial class ShaderMixinExpression(Expression expression, TextLocation info) : ShaderMixinValue(info) +public partial class GenericIdentifier(Identifier name, ShaderExpressionList? generics, TextLocation info) : IdentifierBase(info) { - public Expression Value { get; set; } = expression; + public Identifier Name { get; } = name; + public ShaderExpressionList? Generics { get; } = generics; + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + throw new NotImplementedException(); + } + + public override string ToString() => Generics != null ? $"{Name}<{string.Join(",", Generics.Values)}>" : Name.ToString(); } -public partial class ShaderMixinIdentifier(Identifier identifier, TextLocation info) : ShaderMixinValue(info) + +public partial class Mixin(MixinStatementType type, Identifier? target, Expression value, TextLocation info) : Statement(info) { - public Identifier Value { get; set; } = identifier; -} \ No newline at end of file + public MixinStatementType Type { get; } = type; + public Identifier? Target { get; } = target; + public Expression Value { get; } = value; + public override string ToString() => $"{Type} {Target} {Value}"; + + public override void Compile(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); +} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 763d12691d..e5d395223b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -146,12 +146,12 @@ public override string ToString() } -public partial class ShaderCompose(Identifier name, Mixin mixin, bool isArray, TextLocation info) : MethodOrMember(info) +public partial class ShaderCompose(Identifier name, IdentifierBase mixin, bool isArray, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; - public Mixin Mixin { get; set; } = mixin; + public IdentifierBase Shader { get; set; } = mixin; public bool IsArray { get; set; } = isArray; - public override string ToString() => $"compose {Mixin}{(IsArray ? "[]" : "")} {Name}"; + public override string ToString() => $"compose {Shader}{(IsArray ? "[]" : "")} {Name}"; } public sealed partial class ShaderMember( @@ -449,81 +449,84 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { var (builder, context) = compiler; - foreach (var attribute in Attributes) + if (Attributes != null) { - if (attribute is AnyShaderAttribute anyAttribute) + foreach (var attribute in Attributes) { - if (anyAttribute.Name == "numthreads") + if (attribute is AnyShaderAttribute anyAttribute) { - Span parameters = stackalloc int[anyAttribute.Parameters.Count]; - for (var index = 0; index < anyAttribute.Parameters.Count; index++) + if (anyAttribute.Name == "numthreads") { - var parameter = anyAttribute.Parameters[index]; + Span parameters = stackalloc int[anyAttribute.Parameters.Count]; + for (var index = 0; index < anyAttribute.Parameters.Count; index++) + { + var parameter = anyAttribute.Parameters[index]; - // TODO: avoid emitting in context (use a temp buffer?) - var constantArraySize = parameter.CompileConstantValue(table, context); - if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) - throw new InvalidOperationException(); + // TODO: avoid emitting in context (use a temp buffer?) + var constantArraySize = parameter.CompileConstantValue(table, context); + if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) + throw new InvalidOperationException(); - parameters[index] = (int)value; + parameters[index] = (int)value; + } + + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); } - - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); - } - else if (anyAttribute.Name == "maxvertexcount") - { - var maxVertexCount = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _, false)) - throw new InvalidOperationException(); + else if (anyAttribute.Name == "maxvertexcount") + { + var maxVertexCount = anyAttribute.Parameters[0].CompileConstantValue(table, context); + if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _, false)) + throw new InvalidOperationException(); - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); - } - else if (anyAttribute.Name == "outputcontrolpoints") - { - var outputControlPoints = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _, false)) - throw new InvalidOperationException(); + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); + } + else if (anyAttribute.Name == "outputcontrolpoints") + { + var outputControlPoints = anyAttribute.Parameters[0].CompileConstantValue(table, context); + if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _, false)) + throw new InvalidOperationException(); - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)outputControlPointsValue))); - } - else if (anyAttribute.Name == "patchconstantfunc") - { - context.Add(new OpDecorateString(function.Id, Specification.Decoration.PatchConstantFuncSDSL, ((StringLiteral)anyAttribute.Parameters[0]).Value)); - } - else if (anyAttribute.Name == "domain") - { - context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)outputControlPointsValue))); + } + else if (anyAttribute.Name == "patchconstantfunc") { - "tri" => Specification.ExecutionMode.Triangles, - "quad" => Specification.ExecutionMode.Quads, - "isolined" => Specification.ExecutionMode.Isolines, - }, [])); - } - else if (anyAttribute.Name == "partitioning") - { - context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + context.Add(new OpDecorateString(function.Id, Specification.Decoration.PatchConstantFuncSDSL, ((StringLiteral)anyAttribute.Parameters[0]).Value)); + } + else if (anyAttribute.Name == "domain") { - "fractional_odd" => Specification.ExecutionMode.SpacingFractionalOdd, - "fractional_even" => Specification.ExecutionMode.SpacingFractionalEven, - "integer" => Specification.ExecutionMode.SpacingEqual, - "pow2" => throw new NotSupportedException("partitioning pow2 is not supported in SPIR-V"), - }, [])); - } - else if (anyAttribute.Name == "outputtopology") - { - var value = ((StringLiteral)anyAttribute.Parameters[0]).Value; - if (value != "line") + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "tri" => Specification.ExecutionMode.Triangles, + "quad" => Specification.ExecutionMode.Quads, + "isolined" => Specification.ExecutionMode.Isolines, + }, [])); + } + else if (anyAttribute.Name == "partitioning") { context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch { - "triangle_cw" => Specification.ExecutionMode.VertexOrderCw, - "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw, + "fractional_odd" => Specification.ExecutionMode.SpacingFractionalOdd, + "fractional_even" => Specification.ExecutionMode.SpacingFractionalEven, + "integer" => Specification.ExecutionMode.SpacingEqual, + "pow2" => throw new NotSupportedException("partitioning pow2 is not supported in SPIR-V"), }, [])); } - } - else - { - throw new NotImplementedException($"Can't parse method attribute {anyAttribute} on method {Name}"); + else if (anyAttribute.Name == "outputtopology") + { + var value = ((StringLiteral)anyAttribute.Parameters[0]).Value; + if (value != "line") + { + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "triangle_cw" => Specification.ExecutionMode.VertexOrderCw, + "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw, + }, [])); + } + } + else + { + throw new NotImplementedException($"Can't parse method attribute {anyAttribute} on method {Name}"); + } } } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 76a235eec0..201a6e9f1f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -312,7 +312,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann return false; } - public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out Mixin mixin, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) + public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out GenericIdentifier mixin, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; @@ -320,7 +320,7 @@ public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, value = null!; if ( - ShaderClassParsers.Mixin(ref scanner, result, out mixin) + ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin) && Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out identifier)) { @@ -348,7 +348,7 @@ public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, { scanner.Position = position; if ( - ShaderClassParsers.Mixin(ref scanner, result, out mixin) + ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin) && FollowedByDelList(ref scanner, result, ArraySizes, out List sizes, withSpaces: true, advance: true) && Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out identifier)) @@ -402,7 +402,7 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result return arraySizes.Count > 0; } - public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Mixin mixin, out Expression? arraySize, out Expression? value, bool advance = true) + public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out GenericIdentifier mixin, out Expression? arraySize, out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; @@ -411,7 +411,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P if ( LiteralsParser.TypeName(ref scanner, result, out typeName) && Spaces1(ref scanner, result, out _) - && ShaderClassParsers.Mixin(ref scanner, result, out mixin)) + && ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin)) { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); @@ -451,7 +451,7 @@ public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, P && ExpressionParser.Expression(ref scanner, result, out arraySize) && FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) && Spaces1(ref scanner, result, out _) - && ShaderClassParsers.Mixin(ref scanner, result, out mixin)) + && ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin)) { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 9ba0b62131..b246db485a 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -21,7 +21,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parenthesis, ArrayLiteral, Method, - MixinAccess, + GenericIdentifier, Literal ); } @@ -95,16 +95,16 @@ public static bool ArrayLiteral(ref TScanner scanner, ParseResult resu else return Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool MixinAccess(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - ShaderClassParsers.Mixin(ref scanner, result, out var mixin) + ShaderClassParsers.GenericIdentifier(ref scanner, result, out var mixin) && Parsers.FollowedBy(ref scanner, Tokens.Char('.'), withSpaces: true) ) { - parsed = new MixinAccess(mixin, scanner[position..scanner.Position]); + parsed = new ExternalShaderAccess(mixin, scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 513fb298a8..a215cb8271 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -49,6 +49,9 @@ public static bool Literal(ref TScanner scanner, ParseResult result, o public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier identifier, in ParseError? orError = null) where TScanner : struct, IScanner => new IdentifierParser().Match(ref scanner, result, out identifier, orError); + public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + => new GenericIdentifierParser().Match(ref scanner, result, out parsed); public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index 1712a5fd33..e9a8bc02f1 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -21,7 +21,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); if (!Tokens.Char(';', ref scanner, advance: true)) return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[position], scanner.Memory)); - parsed = new(name, mixin, true, scanner[position..]) + parsed = new(name, mixin, arraysize.Count > 0, scanner[position..]) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 13145f9fb8..ae5cb76e5f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -20,12 +20,9 @@ public static bool Class(ref TScanner scanner, ParseResult result, out public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); - public static bool GenericsDefinition(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed) + public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new ShaderGenericsDefinitionParser().Match(ref scanner, result, out parsed); - public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new ShaderMixinParser().Match(ref scanner, result, out parsed); + => new GenericIdentifierParser().Match(ref scanner, result, out parsed); } public record struct SimpleShaderClassParser : IParser @@ -99,7 +96,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Tokens.Char(':', ref scanner, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - while (ShaderClassParsers.Mixin(ref scanner, result, out var mixin)) + while (ShaderClassParsers.GenericIdentifier(ref scanner, result, out var mixin)) { parsed.Mixins.Add(mixin); Parsers.Spaces0(ref scanner, result, out _); @@ -139,23 +136,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } -public record struct ShaderMixinParser : IParser +public record struct GenericIdentifierParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - List path = []; - do - { - if(LiteralsParser.Identifier(ref scanner, result, out var id)) - path.Add(id); - } - while (!scanner.IsEof && Tokens.Char('.', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)); - - if (path.Count > 0) + if (LiteralsParser.Identifier(ref scanner, result, out var typename) + && Parsers.Spaces0(ref scanner, result, out _)) { - var identifier = path[^1]; - parsed = new Mixin(identifier, scanner[..]); var tmpPos = scanner.Position; Parsers.Spaces0(ref scanner, result, out _); if ( @@ -164,18 +152,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { ParameterParsers.GenericsList(ref scanner, result, out var values); - parsed.Generics = values; - parsed.Path = path[..^1]; Parsers.Spaces0(ref scanner, result, out _); if (!Tokens.Char('>', ref scanner, advance: true)) return Parsers.Exit(ref scanner, result, out parsed, position); + parsed = new GenericIdentifier(typename, values, scanner[position..scanner.Position]); return true; } - else - { - scanner.Position = tmpPos; - return true; - } + scanner.Position = tmpPos; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 626b97230c..15cc77639e 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -120,7 +120,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes scanner.Position = position; if( ExpressionParser.Expression(ref scanner, result, out var expression) - && Parsers.FollowedBy(ref scanner, Tokens.Char(')')) + && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), true) ) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); From 9ad9d6d36d495043fa4cec3396ff0fe4e6ee8df1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Feb 2026 17:59:45 +0900 Subject: [PATCH 0794/1182] Removed Trie code --- .../IntrinsicGenerator.cs | 6 +- src/Stride.Shaders.Generators/Trie.cs | 79 ------------------- 2 files changed, 1 insertion(+), 84 deletions(-) delete mode 100644 src/Stride.Shaders.Generators/Trie.cs diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs index a9f3041db9..daa483f385 100644 --- a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators/IntrinsicGenerator.cs @@ -134,11 +134,7 @@ static string GenerateArguments(List parameters, bool option static string UncapitalizeFirstLetter(string s) => char.ToLower(s[0]) + s[1..]; // Group of intrinsics with same parameter names (parameter types might differ) - record IntrinsicOverloadGroup(string Name, List MandatoryParameters, List OptionalParameters, List<(string DeclaringNamespace, IntrinsicDeclaration Declaration)> Overloads) - { - public string Name { get; set; } = Name; - public TrieNode TrieNode { get; set; } - } + record IntrinsicOverloadGroup(string Name, List MandatoryParameters, List OptionalParameters, List<(string DeclaringNamespace, IntrinsicDeclaration Declaration)> Overloads); static void GenerateIntrinsicsCall(SourceProductionContext spc, EquatableList namespaces) { diff --git a/src/Stride.Shaders.Generators/Trie.cs b/src/Stride.Shaders.Generators/Trie.cs deleted file mode 100644 index 1853218464..0000000000 --- a/src/Stride.Shaders.Generators/Trie.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Reflection.Metadata; - -namespace Stride.Shaders.Generators; - -public class TrieNode -{ - public TrieNode() { } - public TrieNode(TrieNode parent, string name) - { - Parent = parent; - } - - public TrieNode? Parent { get; init; } - - // Dictionary to hold children, keyed by character - public Dictionary> Children { get; } = new(); - - // Optional: Store a value at this node - public List Values { get; } = new(); -} - -public class Trie where TValue : class -{ - private readonly TrieNode root = new(); - - public TrieNode Insert(List keys, TValue value) - { - var node = root; - foreach (string s in keys) - { - if (!node.Children.ContainsKey(s)) - node.Children[s] = new TrieNode(node, s); - node = node.Children[s]; - } - - node.Values.Add(value); - return node; - } - - public void SimplifyRoot() => SimplifyRoot(root); - - public IEnumerable> EnumerateNodes() => EnumerateNodes(root); - - // Try to attach method definition to a parent definition with optional parameter (only if one option) - // i.e. (a,b) and (a,b,c) will be grouped into (a,b,c?) - // however (a,b) (a,b,c) and (a,b,d) won't be merged as (a,b) has two possible optional parameter branches - private void SimplifyRoot(TrieNode node) - { - // First we recurse - foreach (var child in node.Children.Values) - { - SimplifyRoot(child); - } - - // Check if we can merge node with its child - if (node.Children.Count == 1 && node.Children.First().Value.Children.Count == 0) - { - var child = node.Children.First().Value; - node.Children.Clear(); - // Take over child values - node.Values.AddRange(child.Values); - } - } - - private IEnumerable> EnumerateNodes(TrieNode node) - { - // Return the current node itself - yield return node; - - // Recursively return all nodes in the child subtrees - foreach (var child in node.Children) - { - foreach (var node2 in EnumerateNodes(child.Value)) - { - yield return node2; - } - } - } -} \ No newline at end of file From 06332592ef8e2f2595d37b8d02513a89268247f9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 09:37:52 +0900 Subject: [PATCH 0795/1182] Further progress on effect mixin codegen --- SDSL.sln | 17 +- .../CompositionArrayForInsideForeach.sdsl | 2 +- .../CompositionArrayForeachNested.sdsl | 2 +- .../CompositionGenericsLinkType.sdsl | 8 +- .../RenderTests/CompositionMethodCall.sdsl | 6 +- .../RenderTests/CompositionStageMethod1.sdsl | 4 +- .../RenderTests/CompositionStageMethod2.sdsl | 4 +- .../RenderTests/CompositionStageVariable.sdsl | 4 +- .../SDSL/RenderTests/CompositionVariable.sdsl | 6 +- assets/SDSL/TestTexture.sdsl | 2 +- .../SDFX/StrideBakeLightProbeEffect.sdfx | 2 +- src/Directory.Build.props | 2 +- .../SDSL/EffectEvaluator.cs | 89 ++-- src/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 10 +- .../SDSL/ShaderMixer.cs | 7 +- .../Examples.Effects.cs | 6 +- .../Stride.Shaders.Experiments.csproj | 9 + .../IntrinsicGenerator.cs | 0 .../Intrinsics/Goal.md | 0 .../Intrinsics/IntrinAST.cs | 0 .../Intrinsics/Parser.cs | 0 .../Stride.Shaders.Generators.Internal.csproj | 24 + .../VisitorGenerator.cs | 0 .../EffectCodeWriter.cs} | 416 ++++++++++++++---- .../EffectGenerator.cs | 70 +++ .../ILRepack.targets | 37 ++ .../Stride.Shaders.Generators.csproj | 25 +- .../Extensions/spirv.sdsl.grammar-ext.json | 258 +++++------ .../Information/InstructionInfo.Order.cs | 4 +- .../SPVGenerator.SDSLOp.cs | 12 +- .../Stride.Shaders.Spirv.Generators.csproj | 2 +- src/Stride.Shaders.Tests/Program.cs | 6 +- src/Stride.Shaders.Tests/RenderingTests.cs | 20 +- .../Stride.Shaders.Parsing.Tests.csproj | 16 +- src/Stride.Shaders/Core/Symbol.cs | 1 + .../Core/SymbolTypes.Globals.cs | 2 + src/Stride.Shaders/Core/SymbolTypes.cs | 16 +- .../Parsing/Analysis/SymbolTable.cs | 3 + .../Parsing/SDFX/AST/Effect.Parameters.cs | 4 +- src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 78 +++- .../Parsing/SDFX/LoggerResult.cs | 175 -------- .../Parsing/SDFX/MessageCode.cs | 53 --- .../Parsing/SDFX/Parsers/EffectFileParsers.cs | 2 +- .../Parsing/SDFX/Parsers/EffectParser.cs | 4 +- .../EffectStatementParsers.Conditional.cs | 1 - .../Parsers/EffectStatementParsers.Flow.cs | 171 ++++++- .../SDFX/Parsers/EffectStatementParsers.cs | 39 +- .../Parsing/SDFX/Parsers/ParamsParsers.cs | 2 +- .../Parsing/SDFX/ReportMessage.cs | 72 --- .../Parsing/SDFX/ReportMessageLevel.cs | 25 -- .../Parsing/SDFX/ShaderWriter.cs | 46 +- .../Parsing/SDSL/AST/Expression.cs | 67 +-- .../Parsing/SDSL/AST/Literals.cs | 228 ++++++---- src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 120 ++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Parsing/SDSL/AST/ShaderElements.cs | 13 - .../Parsing/SDSL/AST/Statements.cs | 1 + .../SDSL/Parsers/Common/CommonParsers.cs | 140 ------ .../PrimaryExpressionParsers.cs | 13 +- .../ExpressionParsers/UnaryParsers.Postfix.cs | 2 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 41 +- .../ShaderParsers/CompositionParsers.cs | 4 +- .../ShaderParsers/ShaderClassParser.cs | 11 +- .../ShaderParsers/ShaderDataParsers.cs | 28 +- .../ShaderParsers/ShaderElementParsers.cs | 38 -- .../ShaderParsers/ShaderFileParsers.cs | 2 +- .../StatementParsers/StatementParsers.Flow.cs | 5 +- .../Parsing/Scanners/TextLocation.cs | 7 + .../Spirv/Storage/MixinStorage.cs | 39 -- src/Stride.Shaders/Stride.Shaders.csproj | 7 +- .../StrideImported/Graphics/Buffer.cs | 6 + 71 files changed, 1281 insertions(+), 1259 deletions(-) rename src/{Stride.Shaders.Generators => Stride.Shaders.Generators.Internal}/IntrinsicGenerator.cs (100%) rename src/{Stride.Shaders.Generators => Stride.Shaders.Generators.Internal}/Intrinsics/Goal.md (100%) rename src/{Stride.Shaders.Generators => Stride.Shaders.Generators.Internal}/Intrinsics/IntrinAST.cs (100%) rename src/{Stride.Shaders.Generators => Stride.Shaders.Generators.Internal}/Intrinsics/Parser.cs (100%) create mode 100644 src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj rename src/{Stride.Shaders.Generators => Stride.Shaders.Generators.Internal}/VisitorGenerator.cs (100%) rename src/{Stride.Shaders/Parsing/SDFX/EffectGenerator.cs => Stride.Shaders.Generators/EffectCodeWriter.cs} (53%) create mode 100644 src/Stride.Shaders.Generators/EffectGenerator.cs create mode 100644 src/Stride.Shaders.Generators/ILRepack.targets delete mode 100644 src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs delete mode 100644 src/Stride.Shaders/Parsing/SDFX/MessageCode.cs delete mode 100644 src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs delete mode 100644 src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs delete mode 100644 src/Stride.Shaders/Spirv/Storage/MixinStorage.cs create mode 100644 src/Stride.Shaders/StrideImported/Graphics/Buffer.cs diff --git a/SDSL.sln b/SDSL.sln index 3aa97d8d68..d638f6cf7c 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -19,7 +19,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators", "src\Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators.Internal", "src\Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators", "src\Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -127,6 +129,18 @@ Global {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x64.Build.0 = Release|Any CPU {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x86.ActiveCfg = Release|Any CPU {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}.Release|x86.Build.0 = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|x64.ActiveCfg = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|x64.Build.0 = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|x86.ActiveCfg = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Debug|x86.Build.0 = Debug|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|Any CPU.Build.0 = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|x64.ActiveCfg = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|x64.Build.0 = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|x86.ActiveCfg = Release|Any CPU + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -140,5 +154,6 @@ Global {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} + {4EEDDA27-A63C-4D7C-907B-B95ECAED3B11} = {9B25B78A-8418-4161-99D6-5E84611BDA59} EndGlobalSection EndGlobal diff --git a/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl b/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl index 8cb68e46fa..3c01db9a34 100644 --- a/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl +++ b/assets/SDSL/RenderTests/CompositionArrayForInsideForeach.sdsl @@ -47,7 +47,7 @@ shader CompositionTest } }; -effect CompositionArray1 +effect CompositionArrayForInsideForeach { mixin CompositionTest; mixin compose Comps += CompositionShaderA; diff --git a/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl b/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl index 5c17532429..9f9f047605 100644 --- a/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl +++ b/assets/SDSL/RenderTests/CompositionArrayForeachNested.sdsl @@ -52,7 +52,7 @@ shader CompositionTest : CompositionTestArray } }; -effect CompositionArray1 +effect CompositionArrayForeachNested { mixin CompositionTest; mixin compose Comps += CompositionShaderA; diff --git a/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl index 50b50c08b6..fd9eb7a03b 100644 --- a/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl +++ b/assets/SDSL/RenderTests/CompositionGenericsLinkType.sdsl @@ -42,9 +42,9 @@ shader GenericsLinkType { stream float4 ColorTarget : SV_Target0; - Compute Comp0; - Compute Comp1; - Compute Comp2; + compose Compute Comp0; + compose Compute Comp1; + compose Compute Comp2; cbuffer Test { @@ -57,7 +57,7 @@ shader GenericsLinkType } } -effect CompositionGenericLinkType +effect CompositionGenericsLinkType { mixin GenericsLinkType; mixin compose Comp0 = ComputeLinkStage<"LinkValue1">; diff --git a/assets/SDSL/RenderTests/CompositionMethodCall.sdsl b/assets/SDSL/RenderTests/CompositionMethodCall.sdsl index 75d054375d..0213b80927 100644 --- a/assets/SDSL/RenderTests/CompositionMethodCall.sdsl +++ b/assets/SDSL/RenderTests/CompositionMethodCall.sdsl @@ -30,9 +30,9 @@ shader CompositionTest { stream float4 ColorTarget : SV_Target0; - CompositionBase Comp0; - CompositionBase Comp1; - CompositionBase Comp2; + compose CompositionBase Comp0; + compose CompositionBase Comp1; + compose CompositionBase Comp2; void PSMain() { diff --git a/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl b/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl index 669fe6db92..2bfb65df22 100644 --- a/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageMethod1.sdsl @@ -55,8 +55,8 @@ shader CompositionTest : CompositionBase { stream float4 ColorTarget : SV_Target0; - CompositionBase Comp0; - CompositionBase Comp1; + compose CompositionBase Comp0; + compose CompositionBase Comp1; stage override float BaseStageMethod1() { diff --git a/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl b/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl index ec0bdea63b..b81cf343db 100644 --- a/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageMethod2.sdsl @@ -45,8 +45,8 @@ shader CompositionTest { stream float4 ColorTarget : SV_Target0; - CompositionBase Comp0; - CompositionBase Comp1; + compose CompositionBase Comp0; + compose CompositionBase Comp1; void PSMain() { diff --git a/assets/SDSL/RenderTests/CompositionStageVariable.sdsl b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl index f33a07d6e3..cce202b43f 100644 --- a/assets/SDSL/RenderTests/CompositionStageVariable.sdsl +++ b/assets/SDSL/RenderTests/CompositionStageVariable.sdsl @@ -30,8 +30,8 @@ shader CompositionTest : CompositionBase2 { stream float4 ColorTarget : SV_Target0; - CompositionBase Comp0; - CompositionBase Comp1; + compose CompositionBase Comp0; + compose CompositionBase Comp1; void PSMain() { diff --git a/assets/SDSL/RenderTests/CompositionVariable.sdsl b/assets/SDSL/RenderTests/CompositionVariable.sdsl index 2f6783520e..4352feb8f8 100644 --- a/assets/SDSL/RenderTests/CompositionVariable.sdsl +++ b/assets/SDSL/RenderTests/CompositionVariable.sdsl @@ -36,9 +36,9 @@ shader CompositionTest { stream float4 ColorTarget : SV_Target0; - CompositionBase Comp0; - CompositionBase Comp1; - CompositionBase Comp2; + compose CompositionBase Comp0; + compose CompositionBase Comp1; + compose CompositionBase Comp2; void PSMain() { diff --git a/assets/SDSL/TestTexture.sdsl b/assets/SDSL/TestTexture.sdsl index d9b2efc695..6a5e7dd598 100644 --- a/assets/SDSL/TestTexture.sdsl +++ b/assets/SDSL/TestTexture.sdsl @@ -1,6 +1,6 @@ namespace Stride.Shaders.Tests; -shader TestBasic : TestBase +shader TestTexture : TestBase { stream float4 InputPosition : POSITION; stream float4 Position : SV_POSITION; diff --git a/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx b/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx index 9d45809246..46076fb12e 100644 --- a/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx +++ b/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx @@ -5,7 +5,7 @@ using Stride.Rendering.Materials; namespace Stride.Rendering.LightProbes { - partial shader StrideBakeLightProbeEffect + partial effect StrideBakeLightProbeEffect { mixin BakeLightProbeShader; } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 001ff6be2f..c1f59a0925 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,5 +1,5 @@ - + $(MSBuildThisFileDirectory)\..\..\stride \ No newline at end of file diff --git a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 7f217e5721..a4d8e45873 100644 --- a/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -9,16 +9,22 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Stride.Shaders.Core; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Compilers.SDSL { + // Note: We currently use EffectCodeWriter to generate C# code instead. + // Kept around if we later switch to a full SPIR-V approach. + [Obsolete("Use C# EffectCodeWriter (and ShaderMixinManager) for now. Kept for future SPIR-V switch.")] internal class EffectEvaluator(IExternalShaderLoader shaderLoader) { private Stack mixinSources = new(); public ShaderSource EvaluateEffects(ShaderSource source, IDictionary? parameters = null) { + // Note: we currently use EffectCodeWriter to generate C# code instead + throw new NotImplementedException(); // For our tests the ShaderSource is a ShaderClassSource, just a name of a shader to load switch (source) @@ -26,9 +32,10 @@ public ShaderSource EvaluateEffects(ShaderSource source, IDictionary 0 ? mixinSources.Peek().Macros : []; var shaderBuffers = SpirvBuilder.GetOrLoadShader(shaderLoader, classSource.ClassName, classSource.GenericArguments, macros.AsSpan()); + throw new NotImplementedException(); return shaderBuffers.Buffer[0].Op switch { - Op.OpSDSLEffect => EffectInterpreter(shaderBuffers, parameters), + Op.OpEffectSDFX => EffectInterpreter(shaderBuffers, parameters), _ => classSource }; case ShaderMixinSource mixinSource: @@ -85,69 +92,29 @@ private ShaderMixinSource EffectInterpreter(ShaderBuffers shaderBuffers, IDictio { var instruction = shaderBuffers.Buffer[i]; - // If we reach a conditional instruction we need to evaluate the conditions after it. - // If it's false we need to check if there's another conditional instruction after it (ParamsTrue / Else) - // Once we reach the OpSDSLConditionalEnd - if (instruction.Op is Op.OpSDSLConditionalStart) + if (instruction.Op == Op.OpMixinSDFX && (OpMixinSDFX)instruction is { } mixinInstruction) { - i += 1; - bool conditionMet = false; - while(!conditionMet) + // Note: we currently use EffectCodeWriter to generate C# code instead + throw new NotImplementedException(); + string DecodeString(int id) => throw new NotImplementedException(); + var instSource = new ShaderClassSource(DecodeString(mixinInstruction.Value), mixinInstruction.Values); + var evaluatedSource = EvaluateEffects(instSource); + + switch (mixinInstruction.Kind) { - if (instruction.Op is Op.OpSDSLParamsTrue && (OpSDSLParamsTrue)instruction is { } condition) - { - if (parameters?.TryGetValue(condition.ParamsName, out var bparam) ?? false) - { - // TODO: Where are the values ? - if (bparam is ParameterKey boolParam) - { - throw new NotImplementedException(); - } - else if (bparam is ParameterKey shparam) - { - throw new NotImplementedException(); - } - } - } - else if(instruction.Op is Op.OpSDSLElse) - { - if(!conditionMet) - { - conditionMet = true; - // TODO: Apply else branch - } - } - else if(instruction.Op is Op.OpSDSLConditionalEnd) - { + case MixinKindSDFX.Default: + Merge(mixinTree, evaluatedSource); break; - } + case MixinKindSDFX.ComposeSet: + MergeComposition(mixinTree, DecodeString(mixinInstruction.Target), evaluatedSource); + break; + case MixinKindSDFX.ComposeAdd: + MergeCompositionArrayItem(mixinTree, DecodeString(mixinInstruction.Target), evaluatedSource); + break; + default: + throw new NotImplementedException(); } } - else if (instruction.Op == Op.OpSDSLMixin && (OpSDSLMixin)instruction is { } mixinInstruction) - { - var instSource = new ShaderClassSource(mixinInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinInstruction.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - Merge(mixinTree, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinCompose && (OpSDSLMixinCompose)instruction is { } mixinComposeInstruction) - { - var instSource = new ShaderClassSource(mixinComposeInstruction.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeInstruction.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - MergeComposition(mixinTree, mixinComposeInstruction.Identifier, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinComposeArray && (OpSDSLMixinComposeArray)instruction is { } mixinComposeArray) - { - var instSource = new ShaderClassSource(mixinComposeArray.Mixin, GetGenericsArguments(shaderBuffers.Context, mixinComposeArray.Values.Elements.Span)); - var evaluatedSource = EvaluateEffects(instSource); - - MergeCompositionArrayItem(mixinTree, mixinComposeArray.Identifier, evaluatedSource); - } - else if (instruction.Op == Op.OpSDSLMixinChild && (OpSDSLMixinChild)instruction is { } mixinChild) - { - throw new NotImplementedException(); - } i += 1; } @@ -194,8 +161,8 @@ public void Merge(ShaderMixinSource mixinTree, ShaderSource source) public void MergeComposition(ShaderMixinSource mixinTree, string compositionName, ShaderSource compositionToAdd) { if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) - mixinTree.Compositions.Add(compositionName, composition = compositionToAdd is ShaderArraySource ? new ShaderArraySource() : new ShaderMixinSource()); - + mixinTree.Compositions[compositionName] = composition = compositionToAdd is ShaderArraySource ? new ShaderArraySource() : new ShaderMixinSource(); + if (compositionToAdd is ShaderArraySource compositionArrayToAdd) { var compositionArray = (ShaderArraySource)composition; diff --git a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs index a74b36b0ad..386c403b63 100644 --- a/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -47,7 +47,13 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan var shaderLoader = new CaptureLoadedShaders(ShaderLoader); var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; - var effectEvaluator = new EffectEvaluator(shaderLoader); + //var effectEvaluator = new EffectEvaluator(shaderLoader); // We basically put the shader we want to merge through the EffectEvaluator to resolve all mixins/compositions first - shaderSource = effectEvaluator.EvaluateEffects(shaderSource); + //shaderSource = effectEvaluator.EvaluateEffects(shaderSource); + + if (shaderSource is ShaderMixinGeneratorSource mixinGeneratorSource) + shaderSource = ShaderMixinManager.Generate(mixinGeneratorSource.Name, new()); var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderSource); diff --git a/src/Stride.Shaders.Experiments/Examples.Effects.cs b/src/Stride.Shaders.Experiments/Examples.Effects.cs index 83a167d403..646d9498c6 100644 --- a/src/Stride.Shaders.Experiments/Examples.Effects.cs +++ b/src/Stride.Shaders.Experiments/Examples.Effects.cs @@ -17,14 +17,16 @@ public static partial class Examples public static void CompileBasicEffect() { - var effect = File.ReadAllText("./assets/SDFX/BasicEffect.sdfx"); + var filename = @"./assets/SDFX/BasicEffect.sdfx"; + var effect = File.ReadAllText(filename); + effect = MonoGamePreProcessor.Run(effect, filename, []); var parsed = SDSLParser.Parse(effect); if (parsed.Errors.Count > 0) { throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, parsed.Errors)}"); } - var effectGenerator = new EffectGenerator(); + var effectGenerator = new EffectCodeWriter(); effectGenerator.Run(parsed.AST); var code = effectGenerator.Text; diff --git a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index ef8b8ed80b..b7cc5f494e 100644 --- a/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -18,9 +18,18 @@ $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + + + + + EffectCodeWriter.cs + + diff --git a/src/Stride.Shaders.Generators/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs similarity index 100% rename from src/Stride.Shaders.Generators/IntrinsicGenerator.cs rename to src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs diff --git a/src/Stride.Shaders.Generators/Intrinsics/Goal.md b/src/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md similarity index 100% rename from src/Stride.Shaders.Generators/Intrinsics/Goal.md rename to src/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md diff --git a/src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs b/src/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs similarity index 100% rename from src/Stride.Shaders.Generators/Intrinsics/IntrinAST.cs rename to src/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs diff --git a/src/Stride.Shaders.Generators/Intrinsics/Parser.cs b/src/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs similarity index 100% rename from src/Stride.Shaders.Generators/Intrinsics/Parser.cs rename to src/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs diff --git a/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj b/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj new file mode 100644 index 0000000000..336f020614 --- /dev/null +++ b/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + latest + enable + enable + true + Stride.Shaders.Generators + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/VisitorGenerator.cs b/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs similarity index 100% rename from src/Stride.Shaders.Generators/VisitorGenerator.cs rename to src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs diff --git a/src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs b/src/Stride.Shaders.Generators/EffectCodeWriter.cs similarity index 53% rename from src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs rename to src/Stride.Shaders.Generators/EffectCodeWriter.cs index 496fe052c0..9a66eb6152 100644 --- a/src/Stride.Shaders/Parsing/SDFX/EffectGenerator.cs +++ b/src/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -1,27 +1,24 @@ using Stride.Core.Shaders.Utility; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Parsing.SDFX; -public class EffectGenerator : ShaderWriter +public class EffectCodeWriter : ShaderWriter { + private const string DefaultNameSpace = "Stride.Rendering"; + private readonly LoggerResult logging = new(); private Stack contextStack = new(); private Dictionary blockContexts = new(); private BlockStatement currentBlock; + private SymbolTable table = new(new()) { ResolveArraySizes = false, ResolveExternalTypes = false }; - private bool IsParameterDeclaredInContext(string parameter) - { - foreach (var context in contextStack) - { - if (context.DeclaredParameters.Contains(parameter)) - return true; - } - - return false; - } + private bool isProcessingColor = false; public bool Run(Node node) { @@ -44,7 +41,7 @@ void LogErrors() LogErrors(); return false; } - + WriteLine("// "); WriteLine("// Do not edit this file yourself!"); WriteLine("//"); @@ -85,21 +82,132 @@ void LogErrors() return true; } + + public override void VisitShaderStruct(ShaderStruct shaderStruct) + { + // Register struct in table + shaderStruct.ProcessSymbol(table, table.Context); + } + protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Identifier name, Expression? initialValue, List attributes) + { + isProcessingColor = attributes.OfType().Any(x => x.Name == "Color"); + var isArray = false; + + var variableType = attributes.OfType().Where(x => x.Name == "Type").Select(x => ((StringLiteral)x.Parameters[0]).Value).FirstOrDefault(); + var variableMap = attributes.OfType().Where(x => x.Name == "Map").Select(x => ((StringLiteral)x.Parameters[0]).Value).FirstOrDefault(); + + typeName.ProcessSymbol(table); + var type = typeName.Type; + + // ParameterKey shouldn't contain only the underlying type in case of arrays (we use slots) + var parameterType = type; + + string parameterKeyType; + if (isSdfx) + { + parameterKeyType = "Permutation"; + } + else + { + + while (parameterType is ArrayType a) + { + parameterType = a.BaseType; + } + + if (parameterType is ShaderSymbol or TextureType or BufferType or StructuredBufferType or SamplerType) + { + parameterKeyType = "Object"; + } + else + { + parameterKeyType = "Value"; + } + } + + Write($"public static readonly {parameterKeyType}ParameterKey<"); + if (variableType == null) + VisitNode(new TypeName(parameterType.ToString(), default) { Type = parameterType }); + else + Write(variableType); + Write("> "); + Write(name); + Write(" = "); + if (variableMap == null) + { + Write($"ParameterKeys.New{parameterKeyType}<"); + if (variableType == null) + VisitNode(new TypeName(parameterType.ToString(), default) { Type = parameterType }); + else + Write(variableType); + Write(">("); + if (initialValue != null) + { + var initialValueString = initialValue.ToString(); + + if (initialValueString != "null") + { + var initialValueType = type.ToId(); + + if (type is ArrayType) + initialValueString = initialValueType + initialValueString; + + // Rename float2/3/4 to Vector2/3/4 + if (initialValueString.StartsWith("float2", StringComparison.Ordinal) || + initialValueString.StartsWith("float3", StringComparison.Ordinal) || + initialValueString.StartsWith("float4", StringComparison.Ordinal)) + { + initialValueString = initialValueString.Replace("float", "new Vector"); + } + else if (type is ArrayType) + { + initialValueString = "new " + initialValueType; + } + if (isProcessingColor) + { + initialValueString = initialValueString.Replace("Vector3", "Color3"); + initialValueString = initialValueString.Replace("Vector4", "Color4"); + } + } + Write(initialValueString); + } + Write(")"); + } + else + { + Write(variableMap); + } + WriteLine(";"); + + isProcessingColor = false; + } + + private bool IsParameterDeclaredInContext(string parameter) + { + foreach (var context in contextStack) + { + if (context.DeclaredParameters.Contains(parameter)) + return true; + } + + return false; + } + public override void VisitShaderEffect(ShaderEffect shaderEffect) { - Write("internal static partial class ShaderMixins"); + WriteLine("internal static partial class ShaderMixins"); { OpenBrace(); Write("internal partial class"); Write(" "); Write(shaderEffect.Name); WriteSpace(); - Write(" : IShaderMixinBuilder"); + WriteLine(" : IShaderMixinBuilder"); { OpenBrace(); // Generate the main generate method for each shader block - Write("public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)"); + WriteLine("public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)"); { VisitNode(shaderEffect.Block); } @@ -118,6 +226,27 @@ public override void VisitShaderEffect(ShaderEffect shaderEffect) } } + public override void VisitShaderMember(ShaderMember shaderMember) + { + // Do nothing + if (IsParameterKey(shaderMember)) + WriteVariableAsParameterKey(false, shaderMember.TypeName, shaderMember.Name, shaderMember.Value, shaderMember.Attributes ?? []); + } + + public override void VisitShaderSamplerState(ShaderSamplerState shaderSamplerState) + { + // Do nothing + if (IsParameterKey(shaderSamplerState)) + WriteVariableAsParameterKey(false, new TypeName("SamplerState", default), shaderSamplerState.Name, null, shaderSamplerState.Attributes ?? []); + } + + public override void VisitShaderSamplerComparisonState(ShaderSamplerComparisonState shaderSamplerState) + { + // Do nothing + if (IsParameterKey(shaderSamplerState)) + WriteVariableAsParameterKey(false, new TypeName("SamplerState", default), shaderSamplerState.Name, null, shaderSamplerState.Attributes ?? []); + } + public override void VisitBlockStatement(BlockStatement blockStatement) { contextStack.Push(new ShaderBlockContext()); @@ -130,14 +259,42 @@ public override void VisitUsingShaderNamespace(UsingShaderNamespace usingShaderN Write("using ").Write(string.Join('.', usingShaderNamespace.NamespacePath)).WriteLine(";"); } + public override void VisitShaderFile(ShaderFile shaderFile) + { + var rootClasses = shaderFile.RootDeclarations.OfType().ToList(); + if (rootClasses.Count > 0) + { + shaderFile.RootDeclarations.RemoveAll(x => x is ShaderClass); + + // Make sure all top-level objects without namespace are wrapped inside a namespace + shaderFile.Namespaces.Add(new ShaderNamespace(default) + { + Namespace = new(DefaultNameSpace, default), + NamespacePath = DefaultNameSpace.Split('.').Select(x => new Identifier(x, default)).ToList(), + Declarations = rootClasses.ToList(), + }); + } + + base.VisitShaderFile(shaderFile); + } + public override void VisitShaderNamespace(ShaderNamespace shaderNamespace) { - Write("namespace ").Write(string.Join(".", shaderNamespace.NamespacePath)); + Write("namespace ").Write(string.Join(".", shaderNamespace.NamespacePath)).WriteLine(); OpenBrace(); - foreach (var node in shaderNamespace.Declarations) + + var declarations = shaderNamespace.Declarations; + + // If multiple ShaderClass, we get only the last one + // (otherwise our unit tests are generating too many collisions -- we could revisit that decision later if we allow more than one shader per file in production) + var lastShaderClass = declarations.OfType().LastOrDefault(); + declarations = declarations.Where(x => x is not ShaderClass || x == lastShaderClass).ToList(); + + foreach (var node in declarations) { VisitNode(node); } + CloseBrace(); } @@ -145,37 +302,42 @@ public override void VisitAssign(Assign assign) { if (assign.Variables.Count == 1 && assign.Variables[0].Value is not null - && TryParameters(assign.Variables[0].Variable, out var typeTarget, out var typeMember)) + && TryParameters(assign.Variables[0].Variable, out var typeTarget, out var typeMember, out var extraPath)) { Write("context.SetParam(").Write(typeTarget).Write(".").Write(typeMember.ToString()).Write(", "); VisitNode(assign.Variables[0].Value); Write(")"); + if (extraPath != null) + Write(".").Write(extraPath); } else { base.VisitAssign(assign); } } - + public override void VisitAccessorChainExpression(AccessorChainExpression accessorChainExpression) { - if (TryParameters(accessorChainExpression, out var typeTarget, out var typeMember)) + if (TryParameters(accessorChainExpression, out var typeTarget, out var typeMember, out var extraPath)) { var key = typeTarget + "." + typeMember; Write("context.GetParam(").Write(typeTarget).Write(".").Write(typeMember.ToString()).Write(")"); + if (extraPath != null) + Write(".").Write(extraPath); } else { base.VisitAccessorChainExpression(accessorChainExpression); } } - - private bool TryParameters(Expression expression, out string type, out string member) + + private bool TryParameters(Expression expression, out string type, out string member, out string? extraPath) { type = null; member = null; + extraPath = null; var accessorChainExpression = expression as AccessorChainExpression; - if (accessorChainExpression == null || accessorChainExpression.Accessors.Count != 1 || !(accessorChainExpression.Source is ExternalShaderAccess accessMember)) + if (accessorChainExpression == null || accessorChainExpression.Accessors[0] is not IdentifierBase accessMember) return false; var name = accessorChainExpression.Source.ToString(); @@ -185,6 +347,7 @@ private bool TryParameters(Expression expression, out string type, out string me { type = name; member = accessMember.ToString(); + extraPath = accessorChainExpression.Accessors.Count > 1 ? (string.Join(".", accessorChainExpression.Accessors[1..])) : null; foundDeclaredParameters = true; } @@ -194,10 +357,18 @@ private bool TryParameters(Expression expression, out string type, out string me private void ExtractGenericParameters(Expression mixinStatementValue, out Expression mixinName, out ShaderExpressionList? genericParameters) { - if (mixinStatementValue is GenericIdentifier genericIdentifier) + // Pattern like A.B + if (mixinStatementValue is AccessorChainExpression accessorChainExpression && accessorChainExpression.Accessors.Count > 0 && accessorChainExpression.Accessors[^1] is GenericIdentifier genericIdentifier1) { - mixinName = genericIdentifier.Name; - genericParameters = genericIdentifier.Generics; + // Recreate an access chain expression without the generics at the end + mixinName = new AccessorChainExpression(accessorChainExpression.Source, accessorChainExpression.Info) { Accessors = [..accessorChainExpression.Accessors[..^1], genericIdentifier1.Name] }; + genericParameters = genericIdentifier1.Generics; + } + // Pattern like A + else if (mixinStatementValue is GenericIdentifier genericIdentifier2) + { + mixinName = genericIdentifier2.Name; + genericParameters = genericIdentifier2.Generics; } else { @@ -217,12 +388,62 @@ private void WriteGenericParameters(ShaderExpressionList? genericParameters) } } } - + + public override void VisitVectorLiteral(VectorLiteral vectorLiteral) + { + Write("new "); + VisitNode(vectorLiteral.TypeName); + Write("("); + for (var index = 0; index < vectorLiteral.Values.Count; index++) + { + if (index > 0) + Write(", "); + VisitNode(vectorLiteral.Values[index]); + } + + Write(")"); + } + + public override void VisitTypeName(TypeName typeName) + { + if (VectorType.Types.TryGetValue(typeName.Name, out var v) && v is { BaseType.Type: Scalar.Float }) + { + if (isProcessingColor) + Write($"Color{v.Size}"); + else + Write($"Vector{v.Size}"); + } + else if (VectorType.Types.TryGetValue(typeName.Name, out var v2) && v2 is { BaseType.Type: Scalar.Int or Scalar.UInt }) + { + Write($"Int{v.Size}"); + } + else if (MatrixType.Types.TryGetValue(typeName.Name, out var m) && m is { Columns: 4, Rows: 4, BaseType.Type: Scalar.Float }) + { + Write("Matrix"); + } + else if (typeName.Type is BufferType or StructuredBufferType) + { + Write("Buffer"); + } + else if (typeName.Type is TextureType) + { + Write("Texture"); + } + else if (typeName.Type is SamplerType) + { + Write("SamplerState"); + } + else + { + base.VisitTypeName(typeName); + } + } + public override void VisitMixin(Mixin mixinStatement) { - switch (mixinStatement.Type) + switch (mixinStatement.Kind) { - case MixinStatementType.Default: + case Specification.MixinKindSDFX.Default: { ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); @@ -233,7 +454,7 @@ public override void VisitMixin(Mixin mixinStatement) WriteLine(");"); break; } - case MixinStatementType.Child: + case Specification.MixinKindSDFX.Child: { // mixin child can come in 2 flavour: // 1) mixin child MyEffect @@ -245,7 +466,7 @@ public override void VisitMixin(Mixin mixinStatement) WriteLinkLine(mixinStatement); Write("if (context.ChildEffectName == "); WriteMixinName(childName); - Write(")"); + WriteLine(")"); OpenBrace(); WriteLinkLine(mixinStatement); @@ -259,10 +480,10 @@ public override void VisitMixin(Mixin mixinStatement) } break; } - case MixinStatementType.Remove: + case Specification.MixinKindSDFX.Remove: { ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); - + WriteLinkLine(mixinStatement); Write("context.RemoveMixin(mixin, "); WriteMixinName(mixinName); @@ -270,15 +491,17 @@ public override void VisitMixin(Mixin mixinStatement) WriteLine(");"); break; } - case MixinStatementType.Macro: + case Specification.MixinKindSDFX.Macro: { WriteLinkLine(mixinStatement); - string macroName; + Expression macroName; Expression macroValue; if (mixinStatement.Target != null) { macroName = mixinStatement.Target; + if (macroName is Identifier id) + macroName = new StringLiteral(id.Name, id.Info); macroValue = mixinStatement.Value; } else @@ -286,41 +509,41 @@ public override void VisitMixin(Mixin mixinStatement) var variableReference = mixinStatement.Value as AccessorChainExpression; if (variableReference == null || !(variableReference.Source is Identifier id) || !IsParameterDeclaredInContext(id.Name)) { - logging.Error("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info); - macroName = "#INVALID_MACRO_NAME"; + logging.Error("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info.ToSourceSpan()); + macroName = new StringLiteral("#INVALID_MACRO_NAME", default); macroValue = mixinStatement.Value; } else { - macroName = ((Identifier)variableReference.Accessors[0]).Name; + macroName = new StringLiteral(((Identifier)variableReference.Accessors[0]).Name, variableReference.Accessors[0].Info); macroValue = mixinStatement.Value; } } Write("mixin.AddMacro("); - Write(macroName); + VisitNode(macroName); Write(", "); VisitNode(macroValue); WriteLine(");"); break; } - case MixinStatementType.ComposeSet: - case MixinStatementType.ComposeAdd: + case Specification.MixinKindSDFX.ComposeSet: + case Specification.MixinKindSDFX.ComposeAdd: { if (mixinStatement.Target == null) { - logging.Error("Expecting assign expression for composition", mixinStatement.Value.Info); + logging.Error("Expecting assign expression for composition", mixinStatement.Value.Info.ToSourceSpan()); return; } var addCompositionFunction = "PushComposition"; // If it's a +=, let's create or complete a ShaderArraySource - if (mixinStatement.Type == MixinStatementType.ComposeAdd) + if (mixinStatement.Kind == Specification.MixinKindSDFX.ComposeAdd) { addCompositionFunction = "PushCompositionArray"; } - + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); OpenBrace(); @@ -347,12 +570,12 @@ public override void VisitMixin(Mixin mixinStatement) } } } - + private void WriteMixinName(Expression mixinName) { WriteStringOrExpression(mixinName); } - + private void WriteStringOrExpression(Expression expr) { // Output between "" only if the mixin name is only a variable @@ -367,65 +590,97 @@ public override void VisitUsingParams(UsingParams usingParametersStatement) { if (contextStack.Count == 0) { - logging.Error("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Info); + logging.Error("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Info.ToSourceSpan()); return; } var currentContext = contextStack.Peek(); HashSet usings = currentContext.DeclaredParameters; - var typeName = usingParametersStatement.ParamsName.Name; - if (usings.Contains(typeName)) + // If simple name, it is a simple reference of a ParameterBlock + if (usingParametersStatement.ParamsName is Identifier type) { - logging.Error("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Info); - return; - } + var typeName = type.ToString(); + if (usings.Contains(typeName)) + { + logging.Error("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Info.ToSourceSpan()); + return; + } - usings.Add(typeName); + usings.Add(typeName); + } } - + public override void VisitShaderClass(ShaderClass shaderClass) { - // Skip shaders + table.Push(); + + // Process generic symbols (might be used in type arrays) + if (shaderClass.Generics != null) + { + for (int i = 0; i < shaderClass.Generics.Parameters.Count; i++) + shaderClass.ProcessGenericSymbol(table, table.Context, i, shaderClass.Generics.Parameters[i]); + } + + Write(shaderClass.Internal ? "internal " : "public "); + Write("static partial class "); + Write(shaderClass.Name); + WriteLine("Keys"); + { + OpenBrace(); + foreach (var decl in shaderClass.Elements) + { + if (decl is ShaderMember or ShaderStruct or ShaderSamplerState) + { + VisitNode(decl); + } + else if (decl is ShaderBuffer b) + { + foreach (var subDecl in b.Members) + { + VisitNode(subDecl); + } + } + } + CloseBrace(); + } + + table.Pop(); } - + public override void VisitEffectParameters(EffectParameters effectParameters) { - Write("[DataContract]"); + WriteLine("[DataContract]"); WriteLinkLine(effectParameters); Write("public partial class"); Write(" "); Write(effectParameters.Name); WriteSpace(); - Write(": ShaderMixinParameters"); + WriteLine(": ShaderMixinParameters"); { OpenBrace(); foreach (var parameter in effectParameters.Parameters) { WriteLinkLine(parameter); - VisitNode(parameter.Type); - WriteSpace(); - VisitNode(parameter.Identifier); + WriteVariableAsParameterKey(true, parameter.Type, parameter.Identifier, parameter.DefaultValue, []); if (parameter.DefaultValue != null) throw new NotImplementedException(); - WriteLine(";"); } - CloseBrace(false).Write(";").WriteLine(); + CloseBrace(false).WriteLine(); } } internal bool IsParameterKey(ShaderElement element) { - if (element is not (ShaderVariable or ShaderMember)) return false; - - var storageClass = element switch + if (element is ShaderMember member) { - ShaderVariable v => v.StorageClass, - ShaderMember m => m.StorageClass, - }; - + if (member.IsCompose + || member.TypeModifier == TypeModifier.Const + || member.StreamKind != StreamKind.None) + return false; + } // TODO: // Don't generate a parameter key for variable stored storage qualifier: extern, const, compose, stream //if (variable.Qualifiers.Contains(HlslStorageQualifier.Extern) || @@ -439,15 +694,15 @@ internal bool IsParameterKey(ShaderElement element) //// Don't generate a parameter key for [Link] or [RenameLink] //if (variable.Attributes.OfType().Any(x => x.Name == "RenameLink" || x.Name == "Link")) // return false; - + return true; } - + private class ShaderBlockContext { public readonly HashSet DeclaredParameters = new HashSet(); } - + /// /// Internal visitor to precalculate all available Parameters in the context /// @@ -456,9 +711,9 @@ private sealed class ShaderBlockVisitor : NodeWalker private readonly LoggerResult logging; private ShaderBlockContext currentContext; - private readonly EffectGenerator parent; + private readonly EffectCodeWriter parent; - public ShaderBlockVisitor(EffectGenerator parent, LoggerResult logging) + public ShaderBlockVisitor(EffectCodeWriter parent, LoggerResult logging) { this.parent = parent; this.logging = logging; @@ -473,14 +728,19 @@ public override void VisitEffectParameters(EffectParameters paramsBlock) HasMixin = true; } + public override void VisitShaderEffect(ShaderEffect shaderEffect) + { + HasMixin = true; + } + public override void VisitShaderClass(ShaderClass shaderClassType) { // Check if there are any parameter keys in ShaderClassType and ConstantBuffer - CheckParameterKeys(shaderClassType.Elements.OfType()); - CheckParameterKeys(shaderClassType.Elements.OfType().SelectMany(cbuffer => cbuffer.Members)); + CheckParameterKeys(shaderClassType.Elements.OfType()); + CheckParameterKeys(shaderClassType.Elements.OfType().SelectMany(cbuffer => cbuffer.Members)); } - private void CheckParameterKeys(IEnumerable variables) + private void CheckParameterKeys(IEnumerable variables) { foreach (var variable in variables) { diff --git a/src/Stride.Shaders.Generators/EffectGenerator.cs b/src/Stride.Shaders.Generators/EffectGenerator.cs new file mode 100644 index 0000000000..4de1202e5e --- /dev/null +++ b/src/Stride.Shaders.Generators/EffectGenerator.cs @@ -0,0 +1,70 @@ +using System.Diagnostics; +using System.Security.Cryptography; +using System.Text; +using Microsoft.CodeAnalysis; + +namespace Stride.Shaders.Parsing.SDFX; + +[Generator] +public class EffectGenerator : IIncrementalGenerator +{ + public void Initialize(IncrementalGeneratorInitializationContext context) + { + var shaderFiles = + context + .AdditionalTextsProvider + .Where(x => Path.GetExtension(x.Path).ToLowerInvariant() is ".sdfx" or ".sdsl"); + + context.RegisterSourceOutput(shaderFiles, GenerateShaderKeysAndEffects); + } + + private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, AdditionalText arg2) + { + var filename = GetSafeHintName(arg2.Path); + + try + { + var preprocessedText = MonoGamePreProcessor.Run(arg2.GetText().ToString(), arg2.Path); + var parsed = SDSLParser.Parse(preprocessedText); + if (parsed.Errors.Count > 0) + { + var sb = new StringBuilder(); + foreach (var error in parsed.Errors) + sb.AppendLine($"#error Parse error: {error}"); + arg1.AddSource(filename, sb.ToString()); + return; + } + + var effectCodeWriter = new EffectCodeWriter(); + effectCodeWriter.Run(parsed.AST); + arg1.AddSource(filename, effectCodeWriter.Text); + } + catch (Exception e) + { + var sb = new StringBuilder(); + sb.AppendLine($"#error Exception while running {nameof(EffectGenerator)} {e}"); + arg1.AddSource(filename, sb.ToString()); + } + } + + public static string GetSafeHintName(string absolutePath) + { + // 1. Get the file name without extension (e.g., "MyConfig") + string fileName = Path.GetFileName(absolutePath); + + // 2. Sanitize: Replace characters that are invalid in file names + char[] invalidChars = Path.GetInvalidFileNameChars(); + string sanitizedName = new string(fileName + .Select(c => invalidChars.Contains(c) ? '_' : c) + .ToArray()); + + // 3. Create a deterministic hash of the full path to avoid collisions + // for files with the same name in different directories. + using var sha1 = SHA1.Create(); + byte[] hashBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(absolutePath)); + string hash = BitConverter.ToString(hashBytes).Replace("-", "").Substring(0, 8); + + // 4. Combine into a stable hint name (e.g., "MyConfig_A1B2C3D4.g.cs") + return $"{sanitizedName}_{hash}.g.cs"; + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/ILRepack.targets b/src/Stride.Shaders.Generators/ILRepack.targets new file mode 100644 index 0000000000..3a2afde2cd --- /dev/null +++ b/src/Stride.Shaders.Generators/ILRepack.targets @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + $([System.IO.Directory]::GetFiles("%(Directories.Identity)", "*", System.IO.SearchOption.AllDirectories).get_Length()) + + + + + + \ No newline at end of file diff --git a/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index a53ae771c5..89d3a8693b 100644 --- a/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -1,23 +1,38 @@ - netstandard2.0 + net10.0 latest enable enable true + Stride.Shaders.Generators + true + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - + + + + + + + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + + $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + + + \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 895fd3c4d0..48815c26f5 100644 --- a/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -2,6 +2,7 @@ "instructions": [ { "opname": "OpSDSLShader", + "opcode" : 8000, "class": "Miscellaneous", "operands": [ { @@ -14,108 +15,6 @@ "opname": "OpSDSLShaderEnd", "class": "Miscellaneous" }, - { - "opname": "OpSDSLEffect", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "effectName" - } - ] - }, - { - "opname": "OpSDSLParamsUse", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "paramsName" - } - ] - }, - { - "opname": "OpSDSLMixinUse", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixinName" - } - ] - }, - { - "opname": "OpSDSLMixinChild", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixinName" - } - ] - }, - { - "opname": "OpSDSLMixinClone", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixinName" - } - ] - }, - { - "opname": "OpSDSLParams", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "name" - } - ] - }, - { - "opname": "OpSDSLParamsField", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "name" - }, - { - "kind": "LiteralString", - "name": "cstype" - } - ] - }, - { - "opname": "OpSDSLConditionalStart", - "class": "Miscellaneous" - }, - { - "opname": "OpSDSLConditionalEnd", - "class": "Miscellaneous" - }, - { - "opname": "OpSDSLParamsTrue", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "paramsName" - } - ] - }, - { - "opname": "OpSDSLElse", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixinName" - } - ] - }, { "opname": "OpSDSLComposition", "class": "Miscellaneous", @@ -332,59 +231,6 @@ { "kind": "IdResult" } ] }, - { - "opname": "OpSDSLMixin", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixin" - }, - { - "kind": "IdRef", - "quantifier": "*", - "name": "generics" - } - ] - }, - { - "opname": "OpSDSLMixinCompose", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "identifier" - }, - { - "kind": "LiteralString", - "name": "mixin" - }, - { - "kind": "IdRef", - "quantifier": "*", - "name": "generics" - } - ] - }, - { - "opname": "OpSDSLMixinComposeArray", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "identifier" - }, - { - "kind": "LiteralString", - "name": "mixin" - }, - { - "kind": "IdRef", - "quantifier": "*", - "name": "generics" - } - ] - }, { "opname": "OpSDSLGenericParameter", "class": "Miscellaneous", @@ -517,6 +363,74 @@ "name": "Output" } ] + }, + { + "opname": "OpEffectSDFX", + "opcode" : 9000, + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "effectName" + } + ] + }, + { + "opname": "OpParamsUseSDFX", + "class": "Miscellaneous", + "operands": [ + { + "kind": "IdRef", + "name": "paramsName" + } + ] + }, + { + "opname": "OpParamsSDFX", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "name" + } + ] + }, + { + "opname": "OpParamsFieldSDFX", + "class": "Miscellaneous", + "operands": [ + { + "kind": "LiteralString", + "name": "name" + }, + { + "kind": "LiteralString", + "name": "cstype" + } + ] + }, + { + "opname": "OpMixinSDFX", + "class": "Miscellaneous", + "operands": [ + { + "kind": "MixinKindSDFX", + "name": "kind" + }, + { + "kind": "IdRef", + "name": "target" + }, + { + "kind": "IdRef", + "name": "value" + }, + { + "kind": "IdRef", + "quantifier": "*", + "name": "generics" + } + ] } ], "operand_kinds": [ @@ -1053,6 +967,40 @@ "value": 8000 } ] + }, + { + "category": "ValueEnum", + "kind": "MixinKindSDFX", + "enumerants": [ + { + "enumerant": "Default", + "value": 0 + }, + { + "enumerant": "ComposeSet", + "value": 1 + }, + { + "enumerant": "ComposeAdd", + "value": 2 + }, + { + "enumerant": "Child", + "value": 3 + }, + { + "enumerant": "Clone", + "value": 4 + }, + { + "enumerant": "Remove", + "value": 5 + }, + { + "enumerant": "Macro", + "value": 6 + } + ] } ] } \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 62921afa3d..515d360af6 100644 --- a/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -17,7 +17,7 @@ public partial class InstructionInfo { Dictionary<(Op, StorageClass?), int> OrderGroup = new(); - public static ImmutableArray SDSLOperators { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().Contains("SDSL")).ToArray()); + public static ImmutableArray SDSLOperators { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().Contains("SDSL") || x.ToString().Contains("SDFX")).ToArray()); public static ImmutableArray OpTypes { get; } = ImmutableArray.Create(Enum.GetValues().Where(x => x.ToString().StartsWith("OpType")).ToArray()); void InitOrder() @@ -26,7 +26,7 @@ void InitOrder() Span initSDSL = [ Op.OpNop, Op.OpSDSLShader, - Op.OpSDSLEffect, + Op.OpEffectSDFX, Op.OpCapability, Op.OpSDSLCompose ]; diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 971171b953..46bde74b80 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -38,8 +38,8 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList instructionArray) { - var members = instructionArray.Where(x => !x.OpName.Contains("SDSL")).ToDictionary(x => x.OpName, y => y.OpCode)!; - int lastnum = members.Values.Max(); + var members = instructionArray.ToDictionary(x => x.OpName, y => y.OpCode)!; + int lastnum = 0; var code = new StringBuilder(); code @@ -58,14 +58,10 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList - netstandard2.0 + net10.0 latest enable enable diff --git a/src/Stride.Shaders.Tests/Program.cs b/src/Stride.Shaders.Tests/Program.cs index 1dde504f7d..e827753caf 100644 --- a/src/Stride.Shaders.Tests/Program.cs +++ b/src/Stride.Shaders.Tests/Program.cs @@ -2,4 +2,8 @@ [assembly: CaptureConsole] -//new RenderingTests().RenderTest1("SimpleInheritance"); \ No newline at end of file +//new RenderingTests().RenderTest1("SimpleInheritance"); + +public struct myStruct +{ +} \ No newline at end of file diff --git a/src/Stride.Shaders.Tests/RenderingTests.cs b/src/Stride.Shaders.Tests/RenderingTests.cs index 87c25e5ac5..fbd5b81789 100644 --- a/src/Stride.Shaders.Tests/RenderingTests.cs +++ b/src/Stride.Shaders.Tests/RenderingTests.cs @@ -79,7 +79,15 @@ public void ComputeTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + var shaderSource = ShaderMixinManager.Contains(shaderName) + ? new ShaderMixinGeneratorSource(shaderName) + : (ShaderSource)new ShaderClassSource(shaderName); + + // Force file to be parsed and all its shaders registered + // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) + shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); + + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -116,7 +124,15 @@ public void RenderTest1(string shaderName) { // Compiler shader var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/RenderTests")); - shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + var shaderSource = ShaderMixinManager.Contains(shaderName) + ? new ShaderMixinGeneratorSource(shaderName) + : (ShaderSource)new ShaderClassSource(shaderName); + + // Force file to be parsed and all its shaders registered + // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) + shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); + + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj index 58701d9067..6bef03184e 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj @@ -31,14 +31,28 @@ $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + $(StrideDirectory)\sources\core\Stride.Core.Mathematics\bin\Debug\net10.0\Stride.Core.Mathematics.dll + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + $(StrideDirectory)\sources\engine\Stride.Graphics\bin\Debug\net10.0\Direct3D11\Stride.Graphics.dll + + + $(StrideDirectory)\sources\engine\Stride\bin\Debug\net10.0\Stride.dll + + + $(StrideDirectory)\sources\engine\Stride.Rendering\bin\Debug\net10.0\Stride.Rendering.dll + + - + + diff --git a/src/Stride.Shaders/Core/Symbol.cs b/src/Stride.Shaders/Core/Symbol.cs index c31ed925a5..0570bb004c 100644 --- a/src/Stride.Shaders/Core/Symbol.cs +++ b/src/Stride.Shaders/Core/Symbol.cs @@ -22,6 +22,7 @@ public enum SymbolKind RGroup, SamplerState, SamplerComparisonState, + ExternalType, } public enum Storage : ushort diff --git a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs index b24c0ff455..ac3dda18d6 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Globals.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Globals.cs @@ -12,6 +12,7 @@ public partial record ScalarType new("uint", UInt), new("long", Int64), new("ulong", UInt64), + new("half", Half), new("float", Float), new("double", Double), ]; @@ -50,6 +51,7 @@ internal static FrozenDictionary Init() for(int y = 2; y <= 4; y++) // Note: this is HLSL-style so Rows/Columns meaning is swapped arr.Add(new($"{ScalarType.names[i].Key}{y}x{x}", new(ScalarType.names[i].Value,x,y))); + arr.Add(new KeyValuePair("matrix", new(ScalarType.Float,4,4))); return arr.ToFrozenDictionary(); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index d7803ea2a8..014fcb0fd6 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -25,7 +25,7 @@ public abstract record SymbolType() /// /// public virtual string ToId() => ToString(); - + public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolType result) { if (ScalarType.Types.TryGetValue(name, out var s)) @@ -164,7 +164,7 @@ public enum Scalar UInt, Int64, UInt64, - //Half, + Half, Float, Double } @@ -177,6 +177,7 @@ public sealed partial record ScalarType(Scalar Type) : SymbolType() public static ScalarType UInt { get; } = new(Scalar.UInt); public static ScalarType Int64 { get; } = new(Scalar.Int64); public static ScalarType UInt64 { get; } = new(Scalar.UInt64); + public static ScalarType Half { get; } = new(Scalar.Half); public static ScalarType Float { get; } = new(Scalar.Float); public static ScalarType Double { get; } = new(Scalar.Double); @@ -188,6 +189,7 @@ public sealed partial record ScalarType(Scalar Type) : SymbolType() Scalar.UInt => "uint", Scalar.Int64 => "long", Scalar.UInt64 => "ulong", + Scalar.Half => "half", Scalar.Float => "float", Scalar.Double => "double", _ => throw new ArgumentOutOfRangeException() @@ -226,7 +228,7 @@ public partial record struct StructuredTypeMember(string Name, SymbolType Type, public partial record StructuredType(string Name, List Members) : SymbolType() { public override string ToId() => Name; - public override string ToString() => $"{Name}{{{string.Join(", ", Members.Select(x => $"{x.Type} {x.Name}"))}}}"; + public override string ToString() => Name; public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType type) { @@ -257,13 +259,12 @@ public int TryGetFieldIndex(string name) public sealed partial record StructType(string Name, List Members) : StructuredType(Name, Members) { - public override string ToString() => $"struct {base.ToString()}"; + public override string ToString() => base.ToString(); } public sealed partial record StructuredBufferType(SymbolType BaseType, bool WriteAllowed = false) : StructuredType($"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) { public override string ToId() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>"; - public override string ToString() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType}>"; } @@ -689,4 +690,9 @@ public sealed partial record PatchType(SymbolType BaseType, PatchTypeKindSDSL Ki public sealed partial record ShaderMixinType : SymbolType { public override string ToString() => "mixin"; +} + +public sealed partial record ExternalType(string Name, ShaderExpressionList? Generics) : SymbolType +{ + public override string ToString() => Generics != null && Generics.Values.Count > 0 ? $"{Name}<{string.Join(",", Generics.Values)}>" : Name; } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs index 8613b25830..d2fd4ca826 100644 --- a/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs +++ b/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs @@ -15,6 +15,9 @@ public record struct SemanticError(TextLocation Location, string Message) public partial class SymbolTable : ISymbolProvider { + public bool ResolveArraySizes { get; set; } = true; + public bool ResolveExternalTypes { get; set; } = true; + public Dictionary DeclaredTypes { get; } = []; public SpirvContext Context { get; init; } diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs index 2304f70f4a..6470ed410d 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs @@ -14,7 +14,7 @@ public partial class EffectParameters(TypeName name, TextLocation info) : Shader public void Compile(SymbolTable table, CompilerUnit compiler) { - compiler.Builder.Insert(new OpSDSLParams(Name.Name)); + compiler.Builder.Insert(new OpParamsSDFX(Name.Name)); foreach(var parameter in Parameters) parameter.Compile(table, compiler); } @@ -30,6 +30,6 @@ public partial class EffectParameter(TypeName type, Identifier identifier, TextL public void Compile(SymbolTable table, CompilerUnit compiler) { var (_, context) = compiler; - context.Add(new OpSDSLParamsField(Identifier, Type)); + context.Add(new OpParamsFieldSDFX(Identifier, Type)); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs index 44a4c9f2a1..b57d7300ea 100644 --- a/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs +++ b/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -22,8 +23,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - compiler.Builder.Insert(new OpSDSLEffect(Name.Name)); - Block.ProcessSymbol(table); + builder.Insert(new OpEffectSDFX(Name.Name)); Block.Compile(table, compiler); } @@ -69,14 +69,21 @@ public override string ToString() } } -public partial class UsingParams(Identifier name, TextLocation info) : EffectStatement(info) +public partial class UsingParams(Expression name, TextLocation info) : EffectStatement(info) { - public Identifier ParamsName { get; set; } = name; + public Expression ParamsName { get; set; } = name; + + public override void ProcessSymbol(SymbolTable table) + { + ParamsName.ProcessSymbol(table); + } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, _) = compiler; - builder.Insert(new OpSDSLParamsUse(ParamsName.Name)); + + var paramsName = ParamsName.Compile(table, compiler); + builder.Insert(new OpParamsUseSDFX(paramsName.Id)); } public override string ToString() @@ -93,4 +100,65 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) } } +/// +/// Type of a mixin. +/// +public enum MixinStatementType +{ + /// + /// The default mixin (standard mixin). + /// + Default, + + /// + /// The compose mixin used to set a composition (using =). + /// + ComposeSet, + + /// + /// The compose mixin used to add a composition (using +=). + /// + ComposeAdd, + + /// + /// The child mixin used to specify a children shader. + /// + Child, + + /// + /// The clone mixin to clone the current mixins where the clone is emitted. + /// + Clone, + + /// + /// The remove mixin to remove a mixin from current mixins. + /// + Remove, + + /// + /// The macro mixin to declare a variable to be exposed in the mixin + /// + Macro, + + +} +public partial class Mixin(Specification.MixinKindSDFX kind, Identifier? target, Expression value, TextLocation info) : Statement(info) +{ + public Specification.MixinKindSDFX Kind { get; } = kind; + public Identifier? Target { get; } = target; + public Expression Value { get; } = value; + public override string ToString() => $"{Type} {Target} {Value}"; + + public override void ProcessSymbol(SymbolTable table) + { + } + + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + + throw new NotImplementedException(); + //builder.Insert(new OpMixinSDFX(Kind, Target?.Name ?? "", Value., Value.Generics)); + } +} diff --git a/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs b/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs deleted file mode 100644 index f0cdce8069..0000000000 --- a/src/Stride.Shaders/Parsing/SDFX/LoggerResult.cs +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.IO; -using System.Text; -using Stride.Shaders.Parsing; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// A class to collect parsing/expression messages. - /// - public class LoggerResult - { - /// - /// Initializes a new instance of the class. - /// - public LoggerResult() - { - this.Messages = new List(); - } - - /// - /// Gets or sets a value indicating whether this instance has errors. - /// - /// - /// true if this instance has errors; otherwise, false. - /// - public bool HasErrors { get; set; } - - /// - /// Gets or sets the messages. - /// - /// - /// The messages. - /// - public IList Messages { get; private set; } - - /// - /// Dumps the messages. - /// - /// The level. - /// The writer. - public void DumpMessages(ReportMessageLevel level, TextWriter writer) - { - foreach (var reportMessage in this.Messages) - { - if (reportMessage.Level >= level) - { - writer.WriteLine(reportMessage); - } - } - } - - /// - /// Copies all messages to another instance. - /// - /// The results. - public void CopyTo(LoggerResult results) - { - foreach (var reportMessage in this.Messages) - { - results.Messages.Add(reportMessage); - } - - if (HasErrors) - results.HasErrors = true; - } - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - public void Error(MessageCode message, TextLocation span) - { - this.AddMessage(ReportMessageLevel.Error, message, span); - } - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Error(MessageCode message, TextLocation span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Error, message, span, parameters); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - public void Info(MessageCode message, TextLocation span) - { - this.AddMessage(ReportMessageLevel.Info, message, span); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Info(MessageCode message, TextLocation span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Info, message, span, parameters); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - public void Warning(MessageCode message, TextLocation span) - { - this.AddMessage(ReportMessageLevel.Warning, message, span); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Warning(MessageCode message, TextLocation span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Warning, message, span, parameters); - } - - /// - /// Adds the message. - /// - /// The type. - /// The message. - /// The span. - protected void AddMessage(ReportMessageLevel level, MessageCode message, TextLocation span) - { - if (level == ReportMessageLevel.Error) this.HasErrors = true; - this.Messages.Add(new ReportMessage(level, message.Code, message.Text, span)); - } - - /// - /// Adds the message. - /// - /// The type. - /// The message. - /// The span. - /// The parameters. - protected void AddMessage(ReportMessageLevel level, MessageCode message, TextLocation span, params object[] parameters) - { - if (level == ReportMessageLevel.Error) this.HasErrors = true; - this.Messages.Add(new ReportMessage(level, message.Code, string.Format(message.Text, parameters), span)); - } - - public override string ToString() - { - var text = new StringBuilder(); - if (HasErrors) - { - foreach (var reportMessage in Messages) - { - text.AppendLine(reportMessage.ToString()); - } - } - else - { - text.AppendLine("OK"); - } - return text.ToString(); - } - } -} diff --git a/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs b/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs deleted file mode 100644 index ec8be6ab08..0000000000 --- a/src/Stride.Shaders/Parsing/SDFX/MessageCode.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Utility -{ - public partial class MessageCode - { - public readonly string Code; - - public readonly string Text; - - public MessageCode(string text) - { - Code = ""; - Text = text; - } - - public MessageCode(string code, string text) - { - Code = code; - Text = text; - } - - public static implicit operator MessageCode(string text) - { - return new MessageCode(text); - } - - #region Static members - - // Warnings - public static readonly MessageCode WarningUnknown = new MessageCode("W0000", "Unknown warning"); - - public static readonly MessageCode WarningTypeAsConstructor = new MessageCode("W0001", "Invalid type used as a constructor [{0}]"); - public static readonly MessageCode WarningTypeInferenceUnknownExpression = new MessageCode("W0002", "Type inference for unknown expression is supported [{0}]"); - public static readonly MessageCode WarningNoTypeReferenceMember = new MessageCode("W0003", "Unable to find type reference for member [{0}]"); - - // Error - public static readonly MessageCode ErrorAnalysisUnknown = new MessageCode("E0000", "Unknown analysis error"); - - public static readonly MessageCode ErrorBinaryTypeDeduction = new MessageCode("E0001", "Can't deduce type of binary operation between [{0}] and [{1}]"); - public static readonly MessageCode ErrorScalarTypeConversion = new MessageCode("E0002", "Unsupported scalar type conversion between [{0}] and [{1}]"); - public static readonly MessageCode ErrorIndexerType = new MessageCode("E0003", "Unable to find type for indexer: [{0}]"); - public static readonly MessageCode ErrorLiteralType = new MessageCode("E0004", "Unable to find type reference for literal value [{0}]"); - public static readonly MessageCode ErrorNoOverloadedMethod = new MessageCode("E0005", "Unable to find a suitable overloaded method [{0}]"); - public static readonly MessageCode ErrorNoReferencedMethod = new MessageCode("E0006", "Unable to find the referenced method [{0}]"); - public static readonly MessageCode ErrorNoTypeReferenceTypename = new MessageCode("E0008", "Unable to find type reference for typename [{0}]"); - - public static readonly MessageCode ErrorUnexpectedException = new MessageCode("E0009", "Unexpected exception: {0}"); - - - #endregion - } -} diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs index 877ec4ceb3..ad588443e3 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs @@ -1,7 +1,7 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; -namespace Stride.Shaders.Parsing.SDFX.Parsers; +namespace Stride.Shaders.Parsing.SDFX; // public record struct EffectFileParser : IParser // { diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs index 26372177e2..0d53a563e8 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs @@ -2,7 +2,7 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; -namespace Stride.Shaders.Parsing.SDFX.Parsers; +namespace Stride.Shaders.Parsing.SDFX; public record struct EffectParser : IParser @@ -22,6 +22,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new((TypeName)effectName, isPartial, new()); if (EffectStatementParsers.EffectBlock(ref scanner, result, out var s) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { + // Optional semi-colon + SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); parsed.Block = s; return true; } diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs index 3390109c75..2b6cd4bae9 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -1,5 +1,4 @@ using Stride.Shaders.Parsing.SDFX.AST; -using Stride.Shaders.Parsing.SDFX.Parsers; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs index a56bd1f098..24b6257611 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs @@ -1,5 +1,5 @@ +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDFX.AST; -using Stride.Shaders.Parsing.SDFX.Parsers; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; @@ -7,68 +7,197 @@ namespace Stride.Shaders.Parsing.SDFX; -public record struct FlowParsers : IParser +public record struct FlowParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (ForEach(ref scanner, result, out var fe, orError)) + var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && Parsers.Spaces0(ref scanner, result, out _); + if (!hasAttributes) + scanner.Position = position; + if (While(ref scanner, result, out var w, orError)) + { + if(hasAttributes) + w.Attribute = attribute; + parsed = w; + return true; + } + else if (ForEach(ref scanner, result, out var fe, orError)) { parsed = fe; return true; } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); + else if (For(ref scanner, result, out var f, orError)) + { + if(hasAttributes) + f.Attribute = attribute; + parsed = f; + return true; + } + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool ForEach(ref TScanner scanner, ParseResult result, out EffectForEach parsed, ParseError? orError = null) + public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new WhileParser().Match(ref scanner, result, out parsed, orError); + public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) where TScanner : struct, IScanner - => new EffectForEachParser().Match(ref scanner, result, out parsed, orError); + => new ForEachParser().Match(ref scanner, result, out parsed, orError); + public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new ForParser().Match(ref scanner, result, out parsed, orError); } +public record struct ForParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out For parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + Tokens.Literal("for", ref scanner, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + ) + { + Statement? init = null; + Expression? condition = null; + List? expressions = null; + Parsers.Spaces0(ref scanner, result, out _); + + // Parsing the initialization + if(StatementParsers.Expression(ref scanner, result, out init)){} + else if(StatementParsers.DeclareOrAssign(ref scanner, result, out init)){} + else if(StatementParsers.Empty(ref scanner, result, out init)){} + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0036, scanner[scanner.Position], scanner.Memory)); -public record struct EffectForEachParser : IParser + Parsers.Spaces0(ref scanner, result, out _); + // Parsing the condition + + if (ExpressionParser.Expression(ref scanner, result, out condition) + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) {} + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); + + Parsers.Spaces0(ref scanner, result, out _); + // parsing the final expression + + var tmpPos = scanner.Position; + + if (!Parsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) + expressions = [new EmptyStatement(scanner[tmpPos..scanner.Position])]; + if(!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + Parsers.Spaces0(ref scanner, result, out _); + + // parsing the block or statement + + if(EffectStatementParsers.Statement(ref scanner, result, out var body)) + { + parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); + return true; + } + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } + else return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } + + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if( + PostfixParser.Postfix(ref scanner, result, out var variable) + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + ) + { + parsed = new Assign(scanner[position..scanner.Position]) + { + Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] + }; + return true; + } + scanner.Position = position; + if(ExpressionParser.Expression(ref scanner, result, out var expression)) + { + parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); + return true; + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct ForEachParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectForEach parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, out ForEach parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Tokens.Literal("foreach", ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Literal("foreach", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (Tokens.Char('(', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { if ( LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) - && SDSL.Parsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) - && SDSL.Parsers.Spaces1(ref scanner, result, out _) + && Parsers.Spaces1(ref scanner, result, out _) ) { - if (Tokens.Literal("in", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) + if (Tokens.Literal("in", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { if ( ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) + && Parsers.Spaces0(ref scanner, result, out _) ) { - if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { - parsed = new((TypeName)typeName, identifier, collection, statement, scanner[position..scanner.Position]); + parsed = new(typeName, identifier, collection, statement, scanner[position..scanner.Position]); return true; } } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + } + } + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + } + } + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } +} + +public record struct WhileParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out While parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Tokens.Literal("while", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) + { + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) + { + parsed = new(expression, statement, scanner[position..scanner.Position]); + return true; } } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } \ No newline at end of file diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs index a58c4d85ac..ba3e2c4828 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -2,8 +2,10 @@ using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; +using Mixin = Stride.Shaders.Parsing.SDFX.AST.Mixin; -namespace Stride.Shaders.Parsing.SDFX.Parsers; +namespace Stride.Shaders.Parsing.SDFX; public record struct EffectStatementParsers : IParser @@ -36,9 +38,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = flow; return true; } - else if (ShaderSourceDeclaration(ref scanner, result, out var ssd)) + else if (StatementParsers.Declare(ref scanner, result, out var decl)) { - parsed = ssd; + parsed = decl; return true; } else if (StatementParsers.Expression(ref scanner, result, out var exp)) @@ -63,9 +65,9 @@ public static bool UsingParams(ref TScanner scanner, ParseResult resul => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinParser().Match(ref scanner, result, out parsed, orError); - public static bool Flow(ref TScanner scanner, ParseResult result, out EffectFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); - + public static bool EffectBlock(ref TScanner scanner, ParseResult result, out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -109,9 +111,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; if (SDSL.Parsers.SequenceOf(ref scanner, ["using", "params"], advance: true)) { - if (LiteralsParser.Identifier(ref scanner, result, out var identifier)) + if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - parsed = new(identifier, scanner[position..scanner.Position]); + parsed = new(expression, scanner[position..scanner.Position]); return true; } @@ -125,18 +127,18 @@ public record struct MixinParser : IParser public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - var mixinType = MixinStatementType.Default; + var mixinType = Specification.MixinKindSDFX.Default; if (Tokens.Literal("mixin", ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, null!, out _)) { if (Tokens.AnyOf(["compose", "child", "clone", "macro"], ref scanner, out var mixinTypeString, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) { mixinType = mixinTypeString switch { - "compose" => MixinStatementType.ComposeSet, - "child" => MixinStatementType.Child, - "clone" => MixinStatementType.Clone, - "macro" => MixinStatementType.Macro, - "remove" => MixinStatementType.Remove, + "compose" => Specification.MixinKindSDFX.ComposeSet, + "child" => Specification.MixinKindSDFX.Child, + "clone" => Specification.MixinKindSDFX.Clone, + "macro" => Specification.MixinKindSDFX.Macro, + "remove" => Specification.MixinKindSDFX.Remove, _ => throw new Exception("Invalid mixin type") }; } @@ -144,11 +146,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (AssignOrExpression(ref scanner, result, out var statement) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { - if (mixinType is MixinStatementType.ComposeSet or MixinStatementType.Child or MixinStatementType.Macro + if (mixinType is Specification.MixinKindSDFX.ComposeSet or Specification.MixinKindSDFX.Child or Specification.MixinKindSDFX.Macro && statement is Assign { Variables: [{ Value: {} value, Variable: Identifier variable }] } assign) { - if (assign.Variables[0].Operator == AssignOperator.Plus && mixinType == MixinStatementType.ComposeSet) - mixinType = MixinStatementType.ComposeAdd; + if (assign.Variables[0].Operator == AssignOperator.Plus && mixinType == Specification.MixinKindSDFX.ComposeSet) + mixinType = Specification.MixinKindSDFX.ComposeAdd; parsed = new Mixin(mixinType, variable, value, scanner[position..scanner.Position]); } else if (statement is ExpressionStatement expressionStatement) @@ -182,10 +184,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; } scanner.Position = position; - if( - ExpressionParser.Expression(ref scanner, result, out var expression) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), true) - ) + if(ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; diff --git a/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs b/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs index 0c03d26a5c..e2d5867b22 100644 --- a/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs @@ -1,7 +1,7 @@ using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDFX.AST; -namespace Stride.Shaders.Parsing.SDFX.Parsers; +namespace Stride.Shaders.Parsing.SDFX; public record struct ParamsParsers : IParser diff --git a/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs b/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs deleted file mode 100644 index a99585e53b..0000000000 --- a/src/Stride.Shaders/Parsing/SDFX/ReportMessage.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Shaders.Parsing; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// A report message. - /// - public class ReportMessage - { - #region Constants and Fields - - /// - /// Type of the message. - /// - public ReportMessageLevel Level; - - /// - /// Span and location attached to this message. - /// - public TextLocation Span; - - /// - /// The error code. - /// - public string Code; - - /// - /// Text of the message. - /// - public string Text; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ReportMessage() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The error code. - /// The text. - /// The span. - public ReportMessage(ReportMessageLevel level, string code, string text, TextLocation span) - { - this.Level = level; - this.Code = code; - this.Text = text; - this.Span = span; - } - - #endregion - - #region Public Methods - - /// - public override string ToString() - { - return string.Format("{0}: {1} {2} : {3}", this.Span, this.Level.ToString().ToLowerInvariant(), this.Code, this.Text); - } - - #endregion - } -} diff --git a/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs b/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs deleted file mode 100644 index fcc722c8f7..0000000000 --- a/src/Stride.Shaders/Parsing/SDFX/ReportMessageLevel.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Utility -{ - /// - /// Level of a . - /// - public enum ReportMessageLevel - { - /// - /// An informative message. - /// - Info = 0, - - /// - /// A warning message. - /// - Warning = 1, - - /// - /// An error message. - /// - Error = 2, - } -} diff --git a/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs b/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs index 3a9821bb48..091e0f1b2b 100644 --- a/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs +++ b/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs @@ -5,6 +5,9 @@ namespace Stride.Shaders.Core; +/// +/// Writes shader AST to text. Note that implementation is not complete and verified (it was only for SDFX needs), please don't use in production. +/// public class ShaderWriter : NodeWalker { /// @@ -120,7 +123,6 @@ protected ShaderWriter CloseBrace(bool newLine = true) /// protected ShaderWriter OpenBrace() { - WriteLine(); Write("{"); WriteLine(); Indent(); @@ -208,7 +210,6 @@ protected void WriteStatementContent(Statement statement) } else { - WriteLine(); Indent(); VisitNode(statement); Outdent(); @@ -236,11 +237,6 @@ public override void VisitGenericIdentifier(GenericIdentifier identifier) } } - public override void VisitExternalShaderAccess(ExternalShaderAccess externalShaderAccess) - { - VisitNode(externalShaderAccess.Mixin); - } - public override void VisitTypeName(TypeName typeName) { Write(typeName.Name); @@ -354,9 +350,15 @@ public override void VisitAccessorChainExpression(AccessorChainExpression access } } + public override void VisitParenthesisExpression(ParenthesisExpression parenthesisExpression) + { + Write("("); + VisitNode(parenthesisExpression.Expression); + Write(")"); + } + public override void VisitExpressionStatement(ExpressionStatement expressionStatement) { - Write(string.Empty); // Ensure indent VisitNode(expressionStatement.Expression); WriteLine(";"); } @@ -374,15 +376,11 @@ public override void VisitReturn(Return @return) public override void VisitDeclare(Declare declare) { - Write(string.Empty); // Ensure indent - VisitNode(declare.TypeName); - WriteSpace(); for (var i = 0; i < declare.Variables.Count; i++) { VisitNode(declare.Variables[i]); if (i < declare.Variables.Count - 1) Write(",").WriteSpace(); } - WriteLine(";"); } public override void VisitVariableAssign(VariableAssign variableAssign) @@ -397,9 +395,11 @@ public override void VisitVariableAssign(VariableAssign variableAssign) public override void VisitDeclaredVariableAssign(DeclaredVariableAssign declaredVariableAssign) { - Write(string.Empty); // Ensure indent - VisitNode(declaredVariableAssign.TypeName); - WriteSpace(); + if (declaredVariableAssign.TypeName.Name != "void") + { + VisitNode(declaredVariableAssign.TypeName); + WriteSpace(); + } VisitNode(declaredVariableAssign.Variable); if (declaredVariableAssign.Value != null) { @@ -411,7 +411,6 @@ public override void VisitDeclaredVariableAssign(DeclaredVariableAssign declared public override void VisitAssign(Assign assign) { - Write(string.Empty); // Ensure indent for (var i = 0; i < assign.Variables.Count; i++) { VisitNode(assign.Variables[i]); @@ -471,7 +470,6 @@ public override void VisitShaderMember(ShaderMember shaderMember) WriteLine("]"); } - Write(string.Empty); // Indent if (shaderMember.IsStaged) Write("stage").WriteSpace(); if (shaderMember.StreamKind != StreamKind.None) Write(shaderMember.StreamKind.ToString().ToLowerInvariant()).WriteSpace(); if (shaderMember.StorageClass != StorageClass.None) Write(shaderMember.StorageClass.ToString().ToLowerInvariant()).WriteSpace(); @@ -489,7 +487,6 @@ public override void VisitShaderMember(ShaderMember shaderMember) public override void VisitShaderMethod(ShaderMethod shaderMethod) { - Write(string.Empty); // Indent if (shaderMethod.IsStaged) Write("stage").WriteSpace(); if (shaderMethod.IsOverride) Write("override").WriteSpace(); if (shaderMethod.IsStatic) Write("static").WriteSpace(); @@ -510,6 +507,7 @@ public override void VisitShaderMethod(ShaderMethod shaderMethod) if (shaderMethod.Body != null) { + WriteLine(); WriteStatementContent(shaderMethod.Body); } else @@ -574,7 +572,7 @@ public override void VisitFor(For forStatement) VisitNode(forStatement.Update[i]); if (i < forStatement.Update.Count - 1) Write(",").WriteSpace(); } - Write(")"); + WriteLine(")"); WriteStatementContent(forStatement.Body); } @@ -582,7 +580,7 @@ public override void VisitWhile(While whileStatement) { Write("while").WriteSpace().Write("("); VisitNode(whileStatement.Condition); - Write(")"); + WriteLine(")"); WriteStatementContent(whileStatement.Body); } @@ -595,7 +593,7 @@ public override void VisitForEach(ForEach forEach) VisitNode(forEach.Variable); WriteSpace().Write("in").WriteSpace(); VisitNode(forEach.Collection); - Write(")"); + WriteLine(")"); WriteStatementContent(forEach.Body); } @@ -615,7 +613,7 @@ public override void VisitIf(If @if) { Write("if").WriteSpace().Write("("); VisitNode(@if.Condition); - Write(")"); + WriteLine(")"); WriteStatementContent(@if.Body); } @@ -623,13 +621,13 @@ public override void VisitElseIf(ElseIf elseIf) { Write("else if").WriteSpace().Write("("); VisitNode(elseIf.Condition); - Write(")"); + WriteLine(")"); WriteStatementContent(elseIf.Body); } public override void VisitElse(Else @else) { - Write("else"); + WriteLine("else"); WriteStatementContent(@else.Body); } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index 9c0a65c111..d7069123b9 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -77,6 +77,20 @@ public partial class EmptyExpression(TextLocation info) : Expression(info) public override string ToString() => string.Empty; } +public partial class ParenthesisExpression(Expression expression, TextLocation info) : Expression(info) +{ + public Expression Expression { get; set; } = expression; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Expression.ProcessSymbol(table, expectedType); + Type = Expression.Type; + } + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => Expression.Compile(table, compiler); + + public override string ToString() => $"({Expression})"; +} + public partial class MethodCall(Identifier name, ShaderExpressionList arguments, TextLocation info) : Expression(info) { public Identifier Name = name; @@ -363,57 +377,6 @@ public override string ToString() } } -/// -/// Represents an accessed mixin. -/// -public partial class ExternalShaderAccess(GenericIdentifier mixin, TextLocation info) : Expression(info) -{ - public GenericIdentifier Mixin { get; set; } = mixin; - - public Symbol ResolvedSymbol { get; set; } - - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - var context = table.Context; - - // MixinAccess is same as Identifier static variable case, except we have generics (which is why MixinAccess was chosen over Identifier) - var generics = SDFX.AST.ShaderEffect.CompileGenerics(table, context, Mixin.Generics); - var classSource = new ShaderClassInstantiation(Mixin.Name, generics); - if (!table.TryResolveSymbol(classSource.ToClassNameWithGenerics(), out var symbol)) - { - if (!table.ShaderLoader.Exists(classSource.ClassName)) - throw new InvalidOperationException($"Symbol [{classSource.ClassName}] could not be found."); - - // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) - var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); - for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) - { - table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); - ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); - } - - // We add the typename as a symbol (similar to static access in C#) - var shaderId = context.GetOrRegister(classSource.Symbol); - symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); - table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); - } - - ResolvedSymbol = symbol; - Type = symbol.Type; - } - - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - - return Identifier.EmitSymbol(builder, context, ResolvedSymbol, builder.CurrentFunction == null); - } - - public override string ToString() => Mixin.ToString(); -} - - public abstract class UnaryExpression(Expression expression, Operator op, TextLocation info) : Expression(info) { public Expression Expression { get; set; } = expression; @@ -936,7 +899,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso EmitOpAccessChain(accessChainIds, i - 1); // TODO: figure out instance (this vs composition) - result = Identifier.EmitSymbol(builder, context, importedVariable, false, result.Id); + result = IdentifierBase.EmitSymbol(builder, context, importedVariable, false, result.Id); break; case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): if (compiler == null) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs index a917b1240a..5cbdf30e1f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs @@ -132,6 +132,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(this); } + + public override string ToString() => Value ? "true" : "false"; } public partial class ExpressionLiteral(Expression value, TypeName typeName, TextLocation info) : ValueLiteral(info) @@ -331,89 +333,11 @@ public override string ToString() => $"{Values.Count}({string.Join(", ", Values.Select(x => x.ToString()))})"; } -public abstract partial class IdentifierBase(TextLocation info) : Literal(info); - -public partial class Identifier(string name, TextLocation info) : IdentifierBase(info) +public abstract partial class IdentifierBase(string name, TextLocation info) : Literal(info) { - internal bool AllowStreamVariables { get; set; } public string Name { get; set; } = name; - - public Symbol ResolvedSymbol { get; set; } - - public static implicit operator string(Identifier identifier) => identifier.Name; - - public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) - { - if (Name == "this" || Name == "base") - Type = new PointerType(new ShaderMixinType(), Specification.StorageClass.Private); - else if (Name == "streams") - Type = new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private); - else - { - if (!table.TryResolveSymbol(Name, out var symbol)) - { - var context = table.Context; - if (!table.ShaderLoader.Exists(Name)) - { - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0110, Name))); - return; - } - - // Maybe it's a static variable? try to resolve by loading file - var classSource = new ShaderClassInstantiation(Name, []); - - // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) - var inheritedShaderCount = table.InheritedShaders.Count; - classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); - for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) - { - table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); - ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); - } - - // We add the typename as a symbol (similar to static access in C#) - var shaderId = context.GetOrRegister(classSource.Symbol); - symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); - table.CurrentFrame.Add(classSource.Symbol.Name, symbol); - } - - if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) - throw new InvalidOperationException($"Streams member {Name} used without an object"); - - ResolvedSymbol = symbol; - Type = symbol.Type; - } - } - - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - - return CompileSymbol(table, builder, context, builder.CurrentFunction == null); - } - private SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) - { - if (Name == "this") - { - var result = builder.Insert(new OpThisSDSL(context.Bound++)); - return new(result.ResultId, 0); - } - if (Name == "base") - { - var result = builder.Insert(new OpBaseSDSL(context.Bound++)); - return new(result.ResultId, 0); - } - - if (Name == "streams") - { - var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); - return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private))); - } - - var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); - return EmitSymbol(builder, context, symbol, constantOnly); - } + public Symbol ResolvedSymbol { get; set; } public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { @@ -482,11 +406,74 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal builder.Insert(new OpStore(target.Id, rvalue.Id, null, [])); } - public override string ToString() + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + + return CompileSymbol(table, builder, context, builder.CurrentFunction == null); + } + + protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) + { + var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); + return EmitSymbol(builder, context, symbol, constantOnly); + } +} + +public partial class Identifier(string name, TextLocation info) : IdentifierBase(name, info) +{ + internal bool AllowStreamVariables { get; set; } + + public static implicit operator string(Identifier identifier) => identifier.Name; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - return $"{Name}"; + if (Name == "this" || Name == "base") + Type = new PointerType(new ShaderMixinType(), Specification.StorageClass.Private); + else if (Name == "streams") + Type = new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private); + else + { + if (!table.TryResolveSymbol(Name, out var symbol)) + { + symbol = GenericIdentifier.ResolveExternalShader(table, table.Context, info, Name, null); + } + + if (symbol != null) + { + if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) + table.AddError(new(info, $"Streams member {Name} used without an object")); + + ResolvedSymbol = symbol; + Type = symbol.Type; + } + } + } + + protected override SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) + { + if (Name == "this") + { + var result = builder.Insert(new OpThisSDSL(context.Bound++)); + return new(result.ResultId, 0); + } + if (Name == "base") + { + var result = builder.Insert(new OpBaseSDSL(context.Bound++)); + return new(result.ResultId, 0); + } + + if (Name == "streams") + { + var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); + return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private))); + } + + return base.CompileSymbol(table, builder, context, constantOnly); } + public override string ToString() => Name; + public bool IsVectorSwizzle() { if (Name.Length > 4) @@ -514,9 +501,7 @@ public bool IsVectorSwizzle() public bool IsMatrixSwizzle(MatrixType m, [MaybeNullWhen(false)] out List<(int Column, int Row)> swizzles) { - /// - /// Parses a single component token: "11" or "m22" (no leading underscore). - /// + // Parses a single component token: "11" or "m22" (no leading underscore). static bool TryParseOne(ReadOnlySpan token, int cols, int rows, out (int Column, int Row) component) { component = default; @@ -570,15 +555,67 @@ static bool TryParseOne(ReadOnlySpan token, int cols, int rows, out (int C swizzles = result; return true; } +} + +public partial class GenericIdentifier(Identifier name, ShaderExpressionList? generics, TextLocation info) : IdentifierBase(name, info) +{ + public Identifier Name { get; } = name; + public ShaderExpressionList? Generics { get; } = generics; - public bool IsMatrixField() + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { - return - Name.Length == 3 - && Name[0] == '_' - && char.IsDigit(Name[1]) && Name[1] - '0' > 0 && Name[1] - '0' < 5 - && char.IsDigit(Name[2]) && Name[2] - '0' > 0 && Name[2] - '0' < 5; + var context = table.Context; + + var symbol = ResolveExternalShader(table, context, info, Name, Generics); + + if (symbol != null) + { + ResolvedSymbol = symbol; + Type = symbol.Type; + } } + + internal static Symbol? ResolveExternalShader(SymbolTable table, SpirvContext context, TextLocation info, string name, ShaderExpressionList? generics) + { + if (!table.ResolveExternalTypes) + { + var type = new ExternalType(name, generics); + return new Symbol(new(name, SymbolKind.ExternalType), type, 0); + } + + // GenericIdentifier is same as Identifier static variable case, except we have generics (which is why GenericIdentifier was chosen over Identifier) + var compiledGenerics = SDFX.AST.ShaderEffect.CompileGenerics(table, context, generics); + var classSource = new ShaderClassInstantiation(name, compiledGenerics); + if (!table.TryResolveSymbol(classSource.ToClassNameWithGenerics(), out var symbol)) + { + if (!table.ShaderLoader.Exists(name)) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0110, name))); + return null; + } + + if (!table.ShaderLoader.Exists(classSource.ClassName)) + throw new InvalidOperationException($"Symbol [{classSource.ClassName}] could not be found."); + + // Shader is inherited (TODO: do we want to do something more "selective", i.e. import only the required variable if it's a cbuffer?) + var inheritedShaderCount = table.InheritedShaders.Count; + classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); + for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) + { + table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); + ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); + } + + // We add the typename as a symbol (similar to static access in C#) + var shaderId = context.GetOrRegister(classSource.Symbol); + symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); + table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); + } + + return symbol; + } + + public override string ToString() => Generics != null ? $"{Name}<{string.Join(",", Generics.Values)}>" : Name.ToString(); } public partial class TypeName(string name, TextLocation info) : Literal(info) @@ -686,7 +723,7 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte { foreach (var arraySize in arraySizes) { - if (arraySize is EmptyExpression) + if (!table.ResolveArraySizes || arraySize is EmptyExpression) arraySymbolType = new ArrayType(arraySymbolType, -1); else { @@ -709,7 +746,14 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte protected SymbolType ResolveType(SymbolTable table, SpirvContext context) { if (!TryResolveType(table, context, out var result)) + { + if (!table.ResolveExternalTypes) + { + return new ExternalType(name, null); + } throw new InvalidOperationException($"Could not resolve type [{Name}]"); + } + return result; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs index deb1be1b4a..e5624dba47 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs @@ -36,7 +36,8 @@ public partial class ShaderClass(Identifier name, TextLocation info) : ShaderDec public Identifier Name { get; set; } = name; public List Elements { get; set; } = []; public ShaderParameterDeclarations? Generics { get; set; } - public List Mixins { get; set; } = []; + public List Mixins { get; set; } = []; + public bool Internal { get; set; } // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) @@ -419,21 +420,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) for (int i = 0; i < Generics.Parameters.Count; i++) { var genericParameter = Generics.Parameters[i]; - genericParameter.TypeName.ProcessSymbol(table); + openGenerics[i] = ProcessGenericSymbol(table, context, i, genericParameter); var genericParameterType = genericParameter.TypeName.Type; - table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); - - var genericParameterTypeId = context.GetOrRegister(genericParameterType); - context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, i, Name.Name)); - context.AddName(context.Bound, genericParameter.Name); - - // Note: we skip MemberName because they should have been replaced with the preprocessor during SpirvBuilder.InstantiateMemberNames() step - if (genericParameterType is not GenericParameterType { Kind: GenericParameterKindSDSL.MemberName or GenericParameterKindSDSL.MemberNameResolved }) - table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound, OwnerType: table.CurrentShader)); - - openGenerics[i] = context.Bound; - - context.Bound++; if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) hasUnresolvableGenerics = true; @@ -443,32 +431,33 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var inheritanceList = new List(); foreach (var mixin in Mixins) { - var generics = new int[mixin.Generics != null ? mixin.Generics.Values.Count : 0]; - if (mixin.Generics != null) + var mixinGenerics = (mixin as GenericIdentifier)?.Generics; + var generics = new int[mixinGenerics != null ? mixinGenerics.Values.Count : 0]; + if (mixinGenerics != null) { - for (int i = 0; i < mixin.Generics.Values.Count; i++) + for (int i = 0; i < mixinGenerics.Values.Count; i++) { // Special case: if it's an identifier and can't be resolved, we'll consider it's a string instead - if (mixin.Generics.Values[i] is Identifier identifier) + if (mixinGenerics.Values[i] is Identifier identifier) { if (table.TryResolveSymbol(identifier.Name, out var symbol)) { - mixin.Generics.Values[i].ProcessSymbol(table); - generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; + mixinGenerics.Values[i].ProcessSymbol(table); + generics[i] = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; } else { generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).ResultId; } } - else if (mixin.Generics.Values[i] is AccessorChainExpression accessChain) + else if (mixinGenerics.Values[i] is AccessorChainExpression accessChain) { generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, accessChain.ToString())).ResultId; } else { - mixin.Generics.Values[i].ProcessSymbol(table); - generics[i] = mixin.Generics.Values[i].CompileConstantValue(table, context).Id; + mixinGenerics.Values[i].ProcessSymbol(table); + generics[i] = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; } } } @@ -542,6 +531,23 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.Pop(); } + public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int index, ShaderParameter genericParameter) + { + genericParameter.TypeName.ProcessSymbol(table); + var genericParameterType = genericParameter.TypeName.Type; + table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); + + var genericParameterTypeId = context.GetOrRegister(genericParameterType); + context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, index, Name.Name)); + context.AddName(context.Bound, genericParameter.Name); + + // Note: we skip MemberName because they should have been replaced with the preprocessor during SpirvBuilder.InstantiateMemberNames() step + if (genericParameterType is not GenericParameterType { Kind: GenericParameterKindSDSL.MemberName or GenericParameterKindSDSL.MemberNameResolved }) + table.CurrentFrame.Add(genericParameter.Name, new(new(genericParameter.Name, SymbolKind.ConstantGeneric), genericParameterType, context.Bound, OwnerType: table.CurrentShader)); + + return context.Bound++; + } + // If multiple cbuffer with same name, they will be merged // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpSDSLImportStruct/OpSDSLImportVariable would be ambiguous) private void RenameCBufferVariables() @@ -649,69 +655,3 @@ public partial class ShaderGenerics(Identifier typename, Identifier name, TextLo public Identifier Name { get; set; } = name; public Identifier TypeName { get; set; } = typename; } - -/// -/// Type of a mixin. -/// -public enum MixinStatementType -{ - /// - /// The default mixin (standard mixin). - /// - Default, - - /// - /// The compose mixin used to set a composition (using =). - /// - ComposeSet, - - /// - /// The compose mixin used to add a composition (using +=). - /// - ComposeAdd, - - /// - /// The child mixin used to specify a children shader. - /// - Child, - - /// - /// The clone mixin to clone the current mixins where the clone is emitted. - /// - Clone, - - /// - /// The remove mixin to remove a mixin from current mixins. - /// - Remove, - - /// - /// The macro mixin to declare a variable to be exposed in the mixin - /// - Macro, - - -} - -public partial class GenericIdentifier(Identifier name, ShaderExpressionList? generics, TextLocation info) : IdentifierBase(info) -{ - public Identifier Name { get; } = name; - public ShaderExpressionList? Generics { get; } = generics; - - public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - - public override string ToString() => Generics != null ? $"{Name}<{string.Join(",", Generics.Values)}>" : Name.ToString(); -} - -public partial class Mixin(MixinStatementType type, Identifier? target, Expression value, TextLocation info) : Statement(info) -{ - public MixinStatementType Type { get; } = type; - public Identifier? Target { get; } = target; - public Expression Value { get; } = value; - public override string ToString() => $"{Type} {Target} {Value}"; - - public override void Compile(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); -} diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e5d395223b..c54ed6644f 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -146,10 +146,10 @@ public override string ToString() } -public partial class ShaderCompose(Identifier name, IdentifierBase mixin, bool isArray, TextLocation info) : MethodOrMember(info) +public partial class ShaderCompose(Identifier name, TypeName shader, bool isArray, TextLocation info) : MethodOrMember(info) { public Identifier Name { get; set; } = name; - public IdentifierBase Shader { get; set; } = mixin; + public TypeName Shader { get; set; } = shader; public bool IsArray { get; set; } = isArray; public override string ToString() => $"compose {Shader}{(IsArray ? "[]" : "")} {Name}"; } diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs index 66bd60a949..c3a0998c56 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs @@ -144,19 +144,6 @@ public static ParameterModifiers ToParameterModifiers(this string str) } } -public partial class ShaderVariable(TypeName typeName, Identifier name, Expression? value, TextLocation info) : ShaderElement(info) -{ - public Identifier Name { get; set; } = name; - public TypeName TypeName { get; set; } = typeName; - public Expression? Value { get; set; } = value; - public StorageClass StorageClass { get; set; } = StorageClass.None; - public TypeModifier TypeModifier { get; set; } = TypeModifier.None; - public override string ToString() - { - return $"{(StorageClass != StorageClass.None ? $"{StorageClass} " : "")}{(TypeModifier != TypeModifier.None ? $"{TypeModifier} " : "")} {TypeName} {Name} = {Value}"; - } -} - public partial class TypeDef(TypeName type, Identifier name, TextLocation info) : ShaderElement(info) { public Identifier Name { get; set; } = name; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs index 50b4b5b560..d60f7acca4 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs @@ -150,6 +150,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) internal void ReplaceTypeName(TypeName typeName) { + TypeName.Name = typeName.Name; TypeName.Type = typeName.Type; TypeName.Info = typeName.Info; } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 201a6e9f1f..9b0a568681 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -312,71 +312,6 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann return false; } - public static bool MixinIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out GenericIdentifier mixin, out Identifier identifier, out List arraySize, out Expression? value, bool advance = true) - where TScanner : struct, IScanner - { - var position = scanner.Position; - arraySize = null!; - value = null!; - - if ( - ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin) - && Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out identifier)) - { - var tmp = scanner.Position; - Spaces0(ref scanner, result, out _); - if (!FollowedByDelList(ref scanner, result, ArraySizes, out arraySize, withSpaces: true, advance: true)) - { - scanner.Position = tmp; - } - tmp = scanner.Position; - if ( - !( - FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) - && FollowedBy(ref scanner, result, ExpressionParser.Expression, out value, withSpaces: true, advance: true) - ) - ) - { - scanner.Position = tmp; - } - if (!advance) - scanner.Position = position; - return true; - } - else - { - scanner.Position = position; - if ( - ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin) - && FollowedByDelList(ref scanner, result, ArraySizes, out List sizes, withSpaces: true, advance: true) - && Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out identifier)) - { - var tmp = scanner.Position; - Spaces0(ref scanner, result, out _); - if ( - !( - Tokens.Char('=', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out value) - ) - ) - { - scanner.Position = tmp; - } - if (!advance) - scanner.Position = position; - return true; - } - } - scanner.Position = position; - mixin = null!; - identifier = null!; - arraySize = null!; - return false; - } - public static bool ArraySizes(ref TScanner scanner, ParseResult result, out List arraySizes, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -402,81 +337,6 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result return arraySizes.Count > 0; } - public static bool TypeNameMixinArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out GenericIdentifier mixin, out Expression? arraySize, out Expression? value, bool advance = true) - where TScanner : struct, IScanner - { - var position = scanner.Position; - arraySize = null!; - value = null!; - if ( - LiteralsParser.TypeName(ref scanner, result, out typeName) - && Spaces1(ref scanner, result, out _) - && ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin)) - { - var tmp = scanner.Position; - Spaces0(ref scanner, result, out _); - if ( - !( - Tokens.Char('[', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out arraySize) - && Spaces0(ref scanner, result, out _) - && Tokens.Char(']', ref scanner, advance: true) - ) - ) - { - scanner.Position = tmp; - } - tmp = scanner.Position; - if ( - !( - Tokens.Char('=', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out value) - ) - ) - { - scanner.Position = tmp; - } - if (!advance) - scanner.Position = position; - return true; - } - else - { - scanner.Position = position; - if ( - LiteralsParser.TypeName(ref scanner, result, out typeName) - && FollowedBy(ref scanner, Tokens.Char('['), withSpaces: true, advance: true) - && ExpressionParser.Expression(ref scanner, result, out arraySize) - && FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) - && Spaces1(ref scanner, result, out _) - && ShaderClassParsers.GenericIdentifier(ref scanner, result, out mixin)) - { - var tmp = scanner.Position; - Spaces0(ref scanner, result, out _); - if ( - !( - Tokens.Char('=', ref scanner, advance: true) - && Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out value) - ) - ) - { - scanner.Position = tmp; - } - if (!advance) - scanner.Position = position; - return true; - } - } - scanner.Position = position; - typeName = null!; - mixin = null!; - arraySize = null!; - return false; - } - public static bool Optional(ref TScanner scanner, TTerminal terminal, bool advance = false) where TScanner : struct, IScanner where TTerminal : struct, IToken diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index b246db485a..7da7ec4e32 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -21,7 +21,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parenthesis, ArrayLiteral, Method, - GenericIdentifier, + IdentifierBase, Literal ); } @@ -68,11 +68,14 @@ public static bool Parenthesis(ref TScanner scanner, ParseResult resul if ( Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out parsed, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)) + && ExpressionParser.Expression(ref scanner, result, out var expr, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)) && Parsers.Spaces0(ref scanner, result, out _) && Tokens.Char(')', ref scanner, advance: true) ) + { + parsed = new ParenthesisExpression(expr, scanner[position..scanner.Position]); return true; + } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } @@ -95,16 +98,16 @@ public static bool ArrayLiteral(ref TScanner scanner, ParseResult resu else return Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool IdentifierBase(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - ShaderClassParsers.GenericIdentifier(ref scanner, result, out var mixin) + LiteralsParser.IdentifierBase(ref scanner, result, out var identifier) && Parsers.FollowedBy(ref scanner, Tokens.Char('.'), withSpaces: true) ) { - parsed = new ExternalShaderAccess(mixin, scanner[position..scanner.Position]); + parsed = identifier; return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 33670893f4..b868c93a84 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -37,7 +37,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if ( matched == "." - && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier accessor, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.IdentifierBase, out IdentifierBase accessor, withSpaces: true, advance: true) ) { ((AccessorChainExpression)parsed).Accessors.Add(accessor); diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index a215cb8271..f5e641d149 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -26,6 +26,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o literal = m; return true; } + else if (GenericIdentifier(ref scanner, result, out var g, orError)) + { + literal = g; + return true; + } else if (Identifier(ref scanner, result, out var i, orError)) { literal = i; @@ -51,8 +56,25 @@ public static bool Identifier(ref TScanner scanner, ParseResult result => new IdentifierParser().Match(ref scanner, result, out identifier, orError); public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new GenericIdentifierParser().Match(ref scanner, result, out parsed); + => new GenericIdentifierParser().Match(ref scanner, result, out parsed, orError); + public static bool IdentifierBase(ref TScanner scanner, ParseResult result, out IdentifierBase parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (GenericIdentifier(ref scanner, result, out var g, orError)) + { + parsed = g; + return true; + } + if (Identifier(ref scanner, result, out var i, orError)) + { + parsed = i; + return true; + } + parsed = default; + return Parsers.Exit(ref scanner, result, out parsed, position, orError);; + } public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -249,11 +271,20 @@ public record struct Suffix(int Size, bool IsFloatingPoint, bool Signed) { public readonly override string ToString() { - return (IsFloatingPoint, Signed) switch + return (IsFloatingPoint, Signed, Size) switch { - (true, _) => $"f{Size}", - (false, false) => $"u{Size}", - (false, true) => $"i{Size}", + // More specific suffixes + (true, _, 16) => "h", + (true, _, 32) => "f", + (true, _, 64) => "l", + (false, false, 32) => "u", + (false, true, 32) => "", + (false, false, 64) => "ul", + (false, true, 64) => "l", + + (true, _, _) => $"f{Size}", + (false, false, _) => $"u{Size}", + (false, true, _) => $"i{Size}", }; } } diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index e9a8bc02f1..b2e26bad60 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -16,12 +16,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Tokens.Literal("compose", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { var tmp = scanner.Position; - if (Parsers.MixinIdentifierArraySizeValue(ref scanner, result, out var mixin, out var name, out var arraysize, out var value, advance: true)) + if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var name, out var value, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); if (!Tokens.Char(';', ref scanner, advance: true)) return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[position], scanner.Memory)); - parsed = new(name, mixin, arraysize.Count > 0, scanner[position..]) + parsed = new(name, typeName, typeName.ArraySize is { Count: > 0 }, scanner[position..]) { Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index ae5cb76e5f..0562cb4bac 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -20,9 +20,6 @@ public static bool Class(ref TScanner scanner, ParseResult result, out public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); - public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new GenericIdentifierParser().Match(ref scanner, result, out parsed); } public record struct SimpleShaderClassParser : IParser @@ -67,8 +64,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { var position = scanner.Position; var tmp = position; + var @internal = false; if (Tokens.Literal("internal", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) + { + @internal = true; tmp = scanner.Position; + } if(Parsers.FollowedBy(ref scanner, Tokens.Literal("partial"), withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; if ( @@ -84,6 +85,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { parsed = new ShaderClass(identifier, scanner[..]); + parsed.Internal = @internal; if (Tokens.Char('<', ref scanner, advance: true)) { ParameterParsers.Declarations(ref scanner, result, out var generics); @@ -96,7 +98,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Tokens.Char(':', ref scanner, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - while (ShaderClassParsers.GenericIdentifier(ref scanner, result, out var mixin)) + while (LiteralsParser.IdentifierBase(ref scanner, result, out var mixin)) { parsed.Mixins.Add(mixin); Parsers.Spaces0(ref scanner, result, out _); @@ -135,7 +137,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } - public record struct GenericIdentifierParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 834f96d803..0c49ab77de 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -25,33 +25,21 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out value)) { - if ( - Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) - ) + Identifier? semantic = null; + if (Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true)) { - if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) - { - parsed = new(typeName, identifier, value, scanner[position..scanner.Position], semantic: semantic) - { - Attributes = hasAttributes ? attributes.Attributes : null!, - IsStaged = isStaged, - IsCompose = isCompose, - Interpolation = interpolation, - StreamKind = streamKind, - StorageClass = storageClass, - TypeModifier = typeModifier, - }; - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); + if (!Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out semantic, withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - else if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) + + if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = new(typeName, identifier, value, scanner[position..scanner.Position]) { + Semantic = semantic, Attributes = hasAttributes ? attributes.Attributes : null!, IsStaged = isStaged, + IsCompose = isCompose, Interpolation = interpolation, StreamKind = streamKind, StorageClass = storageClass, diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index b5a9a294b9..9fd96da1ae 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -93,44 +93,6 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou where TScanner : struct, IScanner => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); - public static bool ShaderVariable(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - - var hasStorageClass = - Tokens.AnyOf( - ["extern", "nointerpolation", "precise", "shared", "groupshared", "static", "uniform", "volatile"], - ref scanner, - out var storageClass, - advance: true) - && Parsers.Spaces1(ref scanner, result, out _) - ; - var hasTypeModifier = - Tokens.AnyOf( - ["const", "row_major", "column_major"], - ref scanner, - out var typemodifier, - advance: true) - && Parsers.Spaces1(ref scanner, result, out _) - ; - - if ( - Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typeName, out var identifier, out var value) - && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) - ) - { - parsed = new ShaderVariable(typeName, identifier, value, scanner[position..scanner.Position]) - { - StorageClass = storageClass.ToStorageClass(), - TypeModifier = typemodifier.ToTypeModifier() - }; - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - - } - public static bool TypeDef(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 18d6db46d1..0e6cd5cb8b 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -1,4 +1,4 @@ -using Stride.Shaders.Parsing.SDFX.Parsers; +using Stride.Shaders.Parsing.SDFX; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; diff --git a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 15cc77639e..856017c2b6 100644 --- a/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -118,10 +118,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; } scanner.Position = position; - if( - ExpressionParser.Expression(ref scanner, result, out var expression) - && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), true) - ) + if(ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; diff --git a/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs index 3ecaab3f96..0a40971a23 100644 --- a/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs +++ b/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs @@ -1,4 +1,5 @@ using CommunityToolkit.HighPerformance.Buffers; +using Stride.Core.Shaders.Ast; namespace Stride.Shaders.Parsing; @@ -17,6 +18,12 @@ public readonly override string ToString() { return $"[l{Line}-c{Column}]\n{Text.Span}"; } + + public SourceSpan ToSourceSpan() + { + // Not exact, but it's temporary anyway + return new SourceSpan(new SourceLocation(0, Line, Column), 0); + } } public static class SpanCharExtensions diff --git a/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs b/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs deleted file mode 100644 index 635a875ff6..0000000000 --- a/src/Stride.Shaders/Spirv/Storage/MixinStorage.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Spirv.Core.Buffers; - - -namespace Stride.Shaders.Spirv; - - - - -public record struct Mixin(string Name, NewSpirvBuffer Buffer); - - -public class MixinStorage -{ - public static MixinStorage Instance { get; } = new(); - Dictionary Storage { get; } = []; - - private MixinStorage(){} - - public static void RegisterOrUpdate(string name, NewSpirvBuffer buffer) - { - Instance.Storage[name] = new(name, buffer); - } - - public static bool TryRegister(string name, NewSpirvBuffer buffer) - { - return Instance.Storage.TryAdd(name, new(name, buffer)); - } - - public static Mixin Get(string name) - { - return Instance.Storage[name]; - } - - public static bool TryGet(string name, out Mixin mixin) - { - return Instance.Storage.TryGetValue(name, out mixin); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 4a3b258485..78ac76af05 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -11,19 +11,22 @@ - + - + $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll diff --git a/src/Stride.Shaders/StrideImported/Graphics/Buffer.cs b/src/Stride.Shaders/StrideImported/Graphics/Buffer.cs new file mode 100644 index 0000000000..904fe5b2c5 --- /dev/null +++ b/src/Stride.Shaders/StrideImported/Graphics/Buffer.cs @@ -0,0 +1,6 @@ +namespace Stride.Graphics; + +public class Buffer +{ + +} \ No newline at end of file From 5206a5adaed060631cfab5a7d2aa692f2f61bfae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 13:41:50 +0900 Subject: [PATCH 0796/1182] Fix non-pointer indexer access --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index d7069123b9..a37a450b6c 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -1144,15 +1144,22 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { if (compiler == null) { - accessor.Type = new PointerType(currentValueType, Specification.StorageClass.Function); + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(currentValueType switch + { + MatrixType m => new VectorType(m.BaseType, m.Rows), + VectorType v => v.BaseType, + ArrayType a => a.BaseType, + }, Specification.StorageClass.Function); break; } // We need to load as a variable to use OpAccessChain - var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(accessor.Type), context.Bound++); + var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(new PointerType(currentValueType, Specification.StorageClass.Function)), context.Bound++); builder.Insert(new OpStore(functionVariable, result.Id, null, [])); // Process again the same item with new type - --i; + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); break; } case (PointerType { BaseType: PatchType { BaseType: var t } } p, IndexerExpression indexer): From 08f3e011a81d290260a8535f6877fa82234126bf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 15:03:39 +0900 Subject: [PATCH 0797/1182] Fix Type of PrefixExpression (remove pointer) --- src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index a37a450b6c..b45ae36327 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -395,7 +395,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = case Operator.Plus: case Operator.Minus: expression.ProcessSymbol(table, expectedType); - Type = expression.Type; + Type = expression.ValueType; break; default: table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0111, $"Prefix operator {Operator}"))); @@ -475,6 +475,8 @@ var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate throw new NotImplementedException(); } } + + public override string ToString() => $"{Operator.ToSymbol()}{Expression}"; } public partial class CastExpression(TypeName typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) @@ -499,6 +501,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) return builder.Convert(context, value, castType); } + + public override string ToString() => $"({TypeName}){Expression}"; } From ad80c0c5014a8b689b24b5c07a8688ad23994cc7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 18:19:51 +0900 Subject: [PATCH 0798/1182] Reenable proper syntax highlighting for generators --- .../Stride.Shaders.Generators.Internal.csproj | 2 +- src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs | 4 ++-- .../SPVGenerator.EnumerantParams.cs | 2 +- src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs | 6 +++--- src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs | 2 +- .../SPVGenerator.Specification.cs | 2 +- .../Stride.Shaders.Spirv.Generators.csproj | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj b/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj index 336f020614..59fc459c40 100644 --- a/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj +++ b/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj @@ -1,7 +1,7 @@ - net10.0 + netstandard2.0 latest enable enable diff --git a/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs b/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs index 0abd6eb95f..7edd43586a 100644 --- a/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs +++ b/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs @@ -13,8 +13,8 @@ internal class VisitorGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { - context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateTypeVisitors); - context.RegisterImplementationSourceOutput(context.CompilationProvider, GenerateNodeVisitors); + context.RegisterSourceOutput(context.CompilationProvider, GenerateTypeVisitors); + context.RegisterSourceOutput(context.CompilationProvider, GenerateNodeVisitors); } private void GenerateTypeVisitors(SourceProductionContext context, Compilation compilation) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs index 9e702b9f54..23ba4be82b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs @@ -12,7 +12,7 @@ public partial class SPVGenerator : IIncrementalGenerator public void CreateEnumerantParameters(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - context.RegisterImplementationSourceOutput( + context.RegisterSourceOutput( grammarProvider, GenerateEnumerantParameters ); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index a50026b1d3..176046f986 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -12,7 +12,7 @@ public partial class SPVGenerator public void CreateParameterizedFuncs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) { - context.RegisterImplementationSourceOutput( + context.RegisterSourceOutput( grammarProvider, GenerateParameterizedFunctions ); @@ -21,7 +21,7 @@ public void CreateInfo(IncrementalGeneratorInitializationContext context, Increm { GenerateKinds(context, grammarProvider); - context.RegisterImplementationSourceOutput( + context.RegisterSourceOutput( grammarProvider, GenerateInstructionInformation ); @@ -116,7 +116,7 @@ private void GenerateKinds(IncrementalGeneratorInitializationContext context, In var kindsProvider = grammarProvider .Select(static (grammar, _) => grammar.OperandKinds!.Value); - context.RegisterImplementationSourceOutput(kindsProvider, + context.RegisterSourceOutput(kindsProvider, static (spc, kinds) => { var builder = new StringBuilder(); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 46bde74b80..589122704c 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -29,7 +29,7 @@ public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, Incr .Collect() .Select(static (arr, _) => new EquatableList([.. arr])); - context.RegisterImplementationSourceOutput( + context.RegisterSourceOutput( instructionsProvider, ExecuteSDSLOpCreation ); diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs index 8f788e95d2..63b491303b 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs @@ -13,7 +13,7 @@ public void CreateSpecification(IncrementalGeneratorInitializationContext contex var sdsloProvider = grammarProvider .Select(static (grammar, _) => grammar); - context.RegisterImplementationSourceOutput( + context.RegisterSourceOutput( sdsloProvider, GenerateSDSLSpecification ); diff --git a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 6d71bec121..7e5adde62c 100644 --- a/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -1,7 +1,7 @@ - net10.0 + netstandard2.0 latest enable enable From 229018851b484bb2a0af5e1c246a4d3251f64cc1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 18:31:58 +0900 Subject: [PATCH 0799/1182] Add support for SV_InstanceID and SV_VertexID in any shader stage --- .../Processing/Interfaces/Generation/BuiltinProcessor.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index 2b9beade7e..97f10a2592 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -111,11 +111,11 @@ public static bool ProcessBuiltinsDecoration( (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.FragCoord), - // SV_InstanceID/SV_VertexID + // Vertex shaders inputs (SV_InstanceID, SV_VertexID, etc.) (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(context, variable, BuiltIn.InstanceIndex), (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(context, variable, BuiltIn.VertexIndex), - (not ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID" or "SV_VERTEXID") => false, - // SV_IsFrontFace + (>= ExecutionModel.Vertex, _, "SV_INSTANCEID" or "SV_VERTEXID") => false, // forward from VS to the next stages + // Pixel shader inputs (SV_IsFrontFace) (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(context, variable, BuiltIn.FrontFacing), // SV_PrimitiveID (ExecutionModel.Geometry, StreamVariableType.Output, "SV_PRIMITIVEID") => AddBuiltin(context, variable, BuiltIn.PrimitiveId), From 7930259558edfc164749201bef6a102bcbcc3ff4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 15:16:39 +0900 Subject: [PATCH 0800/1182] Graphics: fix (again) prebuilt shader batch file --- .../Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd | 9 +++++---- .../Shaders093.Bytecodes/CompileShaders.cmd | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index 92c6691dd7..1fa0d17388 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -2,7 +2,8 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +rmdir /s %~dp0obj\ +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGL --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGLES --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd index 92c6691dd7..c09b8a2944 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd @@ -2,7 +2,8 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +rmdir /s %~dp0obj\ +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGL --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGLES --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg From 7474cc95971da06b096f3e28de16628648098e6b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 20:52:59 +0900 Subject: [PATCH 0801/1182] Graphics: Removed OpenGL & OpenGL ES --- build/Stride.Build.props | 4 - build/Stride.UnitTests.Build.targets | 3 - build/Stride.build | 26 +- sources/Directory.Packages.props | 3 - .../AssetCompilerContextExtensions.cs | 2 - .../EffectBytecodeToSourceCodeWriter.cs | 2 - .../Stride.Assets/Textures/TextureHelper.cs | 65 +- .../WindowsGameSettingsProfile.cs | 2 +- .../Stride.Engine.Tests/TesselationTest.cs | 2 - .../Rendering/Compositing/ForwardRenderer.cs | 6 +- .../Android/GamePlatformAndroid.cs | 2 +- .../Stride.Games/GameContextWinforms.cs | 2 +- .../engine/Stride.Games/Stride.Games.csproj | 1 - .../Stride.Games/iOS/GamePlatformiOS.cs | 2 +- .../RegressionHelpers.cs | 14 - .../Scripts/RunAndroidTest.bat | 6 +- .../Scripts/RunUniqueAndroidTest.bat | 4 +- .../Scripts/RunUniqueWindowsTest.bat | 12 - .../TestComputeShader.cs | 2 - .../TestHammersley.cs | 1 - .../TestLambertPrefilteringSH.cs | 2 - .../TestLambertPrefilteringSHPass2.cs | 1 - .../TestRadiancePrefilteringGgx.cs | 1 - .../TestGraphicsApiCheck.cs | 14 +- .../TestMultiTextures.cs | 2 +- .../Stride.Graphics.Tests/TestTexture.cs | 32 +- sources/engine/Stride.Graphics/BufferPool.cs | 4 +- .../engine/Stride.Graphics/DescriptorPool.cs | 2 +- .../engine/Stride.Graphics/DescriptorSet.cs | 2 +- .../Stride.Graphics/DescriptorSetLayout.cs | 2 +- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 2 +- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 2 +- .../Stride.Graphics/GraphicsDeviceFeatures.cs | 7 - .../engine/Stride.Graphics/NamespaceDoc.cs | 2 +- .../OpenGL/BlendState.OpenGL.cs | 151 -- .../Stride.Graphics/OpenGL/Buffer.OpenGL.cs | 230 --- .../OpenGL/CommandList.OpenGL.cs | 1830 ----------------- .../OpenGL/DepthStencilState.OpenGL.cs | 155 -- .../OpenGL/EffectProgram.OpenGL.cs | 783 ------- .../OpenGL/GlobalUsings.OpenGL.cs | 16 - .../OpenGL/GraphicsAdapter.OpenGL.cs | 115 -- .../OpenGL/GraphicsAdapterFactory.OpenGL.cs | 15 - .../OpenGL/GraphicsDevice.OpenGL.cs | 1057 ---------- .../OpenGL/GraphicsDeviceFeatures.OpenGL.cs | 160 -- .../OpenGL/GraphicsOutput.OpenGL.cs | 108 - .../OpenGL/GraphicsResource.OpenGL.cs | 29 - .../OpenGL/GraphicsResourceBase.OpenGL.cs | 44 - .../OpenGL/MappedResource.OpenGL.cs | 14 - .../OpenGL/OpenGLConvertExtensions.cs | 518 ----- .../Stride.Graphics/OpenGL/OpenGLUtils.cs | 86 - .../OpenGL/PipelineState.OpenGL.cs | 247 --- .../OpenGL/QueryPool.OpenGL.cs | 71 - .../OpenGL/RasterizerState.OpenGL.cs | 135 -- .../OpenGL/SamplerState.OpenGL.cs | 146 -- .../SwapChainGraphicsPresenter.OpenGL.cs | 134 -- .../Stride.Graphics/OpenGL/Texture.OpenGL.cs | 649 ------ .../OpenGL/UseOpenGLCreationContext.cs | 79 - .../Stride.Graphics/OpenGL/VertexAttrib.cs | 179 -- .../engine/Stride.Graphics/OpenGL/apply.bat | 10 - .../Stride.Graphics/RenderingSettings.cs | 11 - .../engine/Stride.Graphics/ResourceBinder.cs | 2 +- sources/engine/Stride.Graphics/SDL/Window.cs | 25 +- .../Shaders.Bytecodes/CompileShaders.cmd | 2 - .../GameSettings.sdgamesettings | 26 +- .../SpriteBatch.bytecode.OpenGL.Level_9_1.cs | 111 - ...SpriteBatch.bytecode.OpenGLES.Level_9_1.cs | 126 -- ...riteBatch.bytecodeSRgb.OpenGL.Level_9_1.cs | 115 -- ...teBatch.bytecodeSRgb.OpenGLES.Level_9_1.cs | 130 -- .../SpriteEffect.bytecode.OpenGL.Level_9_1.cs | 99 - ...priteEffect.bytecode.OpenGLES.Level_9_1.cs | 114 - .../UIEffect.bytecode.OpenGL.Level_9_1.cs | 88 - .../UIEffect.bytecode.OpenGLES.Level_9_1.cs | 103 - .../UIEffect.bytecodeSRgb.OpenGL.Level_9_1.cs | 92 - ...IEffect.bytecodeSRgb.OpenGLES.Level_9_1.cs | 107 - .../Shaders093.Bytecodes/CompileShaders.cmd | 2 - .../GameSettings.sdgamesettings | 28 +- ...tanceFieldFontBytecode.OpenGL.Level_9_3.cs | 99 - ...nceFieldFontBytecode.OpenGLES.Level_9_3.cs | 114 - ...tanceFieldFontBytecode.OpenGL.Level_9_3.cs | 103 - ...nceFieldFontBytecode.OpenGLES.Level_9_3.cs | 118 -- .../Stride.Graphics/Stride.Graphics.csproj | 3 - .../Vulkan/GraphicsAdapterFactory.Vulkan.cs | 2 +- .../build/Stride.Graphics.targets | 6 +- .../GameSettings.sdgamesettings | 4 - .../Rendering/Compositing/MSAAResolver.cs | 9 +- ...alSpecularMicrofacetEnvironmentGGXLUT.sdsl | 2 +- .../Rendering/Utils/Utilities.sdsl | 6 +- .../Stride.Shaders.Compiler/EffectCompiler.cs | 16 - .../OpenGL/ShaderCompiler.cs | 21 - .../Stride.Shaders.Tests/TestMixinCompiler.cs | 39 +- sources/engine/Stride/Graphics/DDSHelper.cs | 5 - .../Stride/Graphics/GraphicsPlatform.cs | 10 - .../engine/Stride/Graphics/GraphicsProfile.cs | 34 +- sources/targets/Stride.UnitTests.targets | 4 +- sources/targets/Stride.props | 14 +- sources/targets/Stride.targets | 8 - 96 files changed, 80 insertions(+), 8915 deletions(-) delete mode 100644 sources/engine/Stride.Graphics/OpenGL/BlendState.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/Buffer.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/CommandList.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/DepthStencilState.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/EffectProgram.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GlobalUsings.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsAdapterFactory.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsOutput.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsResource.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/GraphicsResourceBase.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/MappedResource.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/PipelineState.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/QueryPool.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/RasterizerState.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/SamplerState.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/Texture.OpenGL.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/UseOpenGLCreationContext.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/VertexAttrib.cs delete mode 100644 sources/engine/Stride.Graphics/OpenGL/apply.bat delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGL.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGLES.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGL.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGLES.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGL.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGLES.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGL.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGLES.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGL.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGLES.Level_9_1.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs diff --git a/build/Stride.Build.props b/build/Stride.Build.props index 693766b38f..d0b96f24b7 100644 --- a/build/Stride.Build.props +++ b/build/Stride.Build.props @@ -8,8 +8,4 @@ Direct3D11 - - - OpenGL - diff --git a/build/Stride.UnitTests.Build.targets b/build/Stride.UnitTests.Build.targets index 85e422e5e0..e750378237 100644 --- a/build/Stride.UnitTests.Build.targets +++ b/build/Stride.UnitTests.Build.targets @@ -1,8 +1,5 @@ - - OpenGL - Direct3D11 diff --git a/build/Stride.build b/build/Stride.build index 06145dbe98..e343709e06 100644 --- a/build/Stride.build +++ b/build/Stride.build @@ -171,16 +171,6 @@ Example of use: - - - - - - - - - - @@ -211,7 +201,7 @@ Example of use: Linux - + @@ -271,13 +261,13 @@ Example of use: - - - - - - - + + + + + + + diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index d67bd5c409..91c3815857 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -28,9 +28,6 @@ - - - diff --git a/sources/engine/Stride.Assets/AssetCompilerContextExtensions.cs b/sources/engine/Stride.Assets/AssetCompilerContextExtensions.cs index 57bb399dd1..e58769e934 100644 --- a/sources/engine/Stride.Assets/AssetCompilerContextExtensions.cs +++ b/sources/engine/Stride.Assets/AssetCompilerContextExtensions.cs @@ -49,9 +49,7 @@ public static GraphicsPlatform GetDefaultGraphicsPlatform(this PlatformType plat return GraphicsPlatform.Direct3D11; case PlatformType.Android: case PlatformType.iOS: - return GraphicsPlatform.OpenGLES; case PlatformType.Linux: - return GraphicsPlatform.OpenGL; case PlatformType.macOS: return GraphicsPlatform.Vulkan; default: diff --git a/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs b/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs index 7b2b853930..88772de4f0 100644 --- a/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs +++ b/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs @@ -65,8 +65,6 @@ public static void Write(string name, CompilerParameters parameters, EffectBytec { GraphicsPlatform.Direct3D11 or GraphicsPlatform.Direct3D12 => "STRIDE_GRAPHICS_API_DIRECT3D", - GraphicsPlatform.OpenGL => "STRIDE_GRAPHICS_API_OPENGLCORE", - GraphicsPlatform.OpenGLES => "STRIDE_GRAPHICS_API_OPENGLES", GraphicsPlatform.Vulkan => "STRIDE_GRAPHICS_API_VULKAN", _ => "undefined" diff --git a/sources/engine/Stride.Assets/Textures/TextureHelper.cs b/sources/engine/Stride.Assets/Textures/TextureHelper.cs index c8de023d51..c1fd4d2849 100644 --- a/sources/engine/Stride.Assets/Textures/TextureHelper.cs +++ b/sources/engine/Stride.Assets/Textures/TextureHelper.cs @@ -257,7 +257,6 @@ public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Siz { case GraphicsPlatform.Direct3D11: case GraphicsPlatform.Direct3D12: - case GraphicsPlatform.OpenGL: case GraphicsPlatform.Vulkan: // https://msdn.microsoft.com/en-us/library/windows/desktop/hh308955%28v=vs.85%29.aspx @@ -296,11 +295,11 @@ public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Siz // Support some specific optimized formats based on the hint or input type if (parameters.GraphicsProfile >= GraphicsProfile.Level_10_0) { - if (parameters.GraphicsPlatform != GraphicsPlatform.OpenGL && hint == TextureHint.NormalMap) + if (hint == TextureHint.NormalMap) { outputFormat = PixelFormat.BC5_UNorm; } - else if (parameters.GraphicsPlatform != GraphicsPlatform.OpenGL && hint == TextureHint.Grayscale) + else if (hint == TextureHint.Grayscale) { outputFormat = PixelFormat.BC4_UNorm; } @@ -313,40 +312,8 @@ public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Siz // TODO support the BC6/BC7 but they are so slow to compile that we can't use them right now } break; - case GraphicsPlatform.OpenGLES: // OpenGLES on Windows - if (inputImageFormat.IsHDR) - { - outputFormat = inputImageFormat; - } - else if (parameters.IsSRgb) - { - outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb; - } - else - { - switch (parameters.GraphicsProfile) - { - case GraphicsProfile.Level_9_1: - case GraphicsProfile.Level_9_2: - case GraphicsProfile.Level_9_3: - outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.R8G8B8A8_UNorm; - break; - case GraphicsProfile.Level_10_0: - case GraphicsProfile.Level_10_1: - case GraphicsProfile.Level_11_0: - case GraphicsProfile.Level_11_1: - case GraphicsProfile.Level_11_2: - // GLES3.0 starting from Level_10_0, this profile enables ETC2 compression on Android - outputFormat = alphaMode == AlphaFormat.None ? PixelFormat.ETC1 : PixelFormat.ETC2_RGBA; - break; - default: - throw new ArgumentOutOfRangeException("GraphicsProfile"); - } - } - break; default: - // OpenGL on Windows - // TODO: Need to handle OpenGL Desktop compression + // Null platform outputFormat = parameters.IsSRgb ? PixelFormat.R8G8B8A8_UNorm_SRgb : PixelFormat.R8G8B8A8_UNorm; break; } @@ -363,32 +330,6 @@ public static PixelFormat DetermineOutputFormat(ImportParameters parameters, Siz throw new ArgumentOutOfRangeException(); } - // OpenGLES: avoid BGRA (optional extension) - if (parameters.GraphicsPlatform == GraphicsPlatform.OpenGLES) - { - switch (outputFormat) - { - case PixelFormat.B8G8R8A8_UNorm: - outputFormat = PixelFormat.R8G8B8A8_UNorm; - break; - case PixelFormat.B8G8R8A8_UNorm_SRgb: - outputFormat = PixelFormat.R8G8B8A8_UNorm_SRgb; - break; - } - } - - // OpenGL and OpenGLES: avoid R5G6B5 (not implemented) - if (parameters.GraphicsPlatform == GraphicsPlatform.OpenGLES || parameters.GraphicsPlatform == GraphicsPlatform.OpenGL) - { - switch (outputFormat) - { - case PixelFormat.B5G5R5A1_UNorm: - case PixelFormat.B5G6R5_UNorm: - outputFormat = PixelFormat.R8G8B8A8_UNorm; - break; - } - } - return outputFormat; } diff --git a/sources/engine/Stride.Assets/WindowsGameSettingsProfile.cs b/sources/engine/Stride.Assets/WindowsGameSettingsProfile.cs index c891a8182f..f1fdfa364f 100644 --- a/sources/engine/Stride.Assets/WindowsGameSettingsProfile.cs +++ b/sources/engine/Stride.Assets/WindowsGameSettingsProfile.cs @@ -21,7 +21,7 @@ public WindowsGameSettingsProfile() public override IEnumerable GetSupportedGraphicsPlatforms() { - return new[] { GraphicsPlatform.Direct3D11, GraphicsPlatform.OpenGL, GraphicsPlatform.OpenGLES, }; + return [GraphicsPlatform.Direct3D11]; } } } diff --git a/sources/engine/Stride.Engine.Tests/TesselationTest.cs b/sources/engine/Stride.Engine.Tests/TesselationTest.cs index 3d87d98824..b00497cb1c 100644 --- a/sources/engine/Stride.Engine.Tests/TesselationTest.cs +++ b/sources/engine/Stride.Engine.Tests/TesselationTest.cs @@ -201,8 +201,6 @@ private void ChangeMaterial(int i) [SkippableFact] public void RunTestGame() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGL); - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); RunGameTest(new TesselationTest()); diff --git a/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs b/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs index f69c442f5d..d43a2aeb84 100644 --- a/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs +++ b/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs @@ -138,12 +138,8 @@ protected override void InitializeCore() actualMultisampleCount = (MultisampleCount)Math.Min((int)actualMultisampleCount, (int)GraphicsDevice.Features[DepthBufferFormat].MultisampleCountMax); // Note: we cannot support MSAA on DX10 now - if (GraphicsDevice.Features.HasMultiSampleDepthAsSRV == false && // TODO: Try enabling MSAA on DX9! - GraphicsDevice.Platform != GraphicsPlatform.OpenGL && - GraphicsDevice.Platform != GraphicsPlatform.OpenGLES) + if (GraphicsDevice.Features.HasMultiSampleDepthAsSRV == false) { - // OpenGL has MSAA support on every version. - // OpenGL ES has MSAA support starting from version 3.0. // Direct3D has MSAA support starting from version 11 because it requires multisample depth buffers as shader resource views. // Therefore we force-disable MSAA on any platform that doesn't support MSAA. diff --git a/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs b/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs index b03c236da2..d0d10eb440 100644 --- a/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs +++ b/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs @@ -95,7 +95,7 @@ public override List FindBestDevices(GameGraphicsPara public override void DeviceChanged(GraphicsDevice currentDevice, GraphicsDeviceInformation deviceInformation) { - // TODO: Check when it needs to be disabled on iOS (OpenGL)? + // TODO: Check when it needs to be disabled on Android? // Force to resize the gameWindow //gameWindow.Resize(deviceInformation.PresentationParameters.BackBufferWidth, deviceInformation.PresentationParameters.BackBufferHeight); } diff --git a/sources/engine/Stride.Games/GameContextWinforms.cs b/sources/engine/Stride.Games/GameContextWinforms.cs index 957e18d589..008d4fce9c 100644 --- a/sources/engine/Stride.Games/GameContextWinforms.cs +++ b/sources/engine/Stride.Games/GameContextWinforms.cs @@ -41,7 +41,7 @@ public GameContextWinforms(Control control, int requestedWidth = 0, int requeste private static Form CreateForm() { -#if !STRIDE_GRAPHICS_API_OPENGL && !STRIDE_GRAPHICS_API_NULL +#if !STRIDE_GRAPHICS_API_NULL return new GameForm(); #else // Not Reachable. diff --git a/sources/engine/Stride.Games/Stride.Games.csproj b/sources/engine/Stride.Games/Stride.Games.csproj index a598ea0bef..8d4f2627a9 100644 --- a/sources/engine/Stride.Games/Stride.Games.csproj +++ b/sources/engine/Stride.Games/Stride.Games.csproj @@ -28,7 +28,6 @@ Properties\SharedAssemblyInfo.cs - diff --git a/sources/engine/Stride.Games/iOS/GamePlatformiOS.cs b/sources/engine/Stride.Games/iOS/GamePlatformiOS.cs index e1c3a2f08c..ee0a8b5e35 100644 --- a/sources/engine/Stride.Games/iOS/GamePlatformiOS.cs +++ b/sources/engine/Stride.Games/iOS/GamePlatformiOS.cs @@ -95,7 +95,7 @@ public override List FindBestDevices(GameGraphicsPara public override void DeviceChanged(GraphicsDevice currentDevice, GraphicsDeviceInformation deviceInformation) { - // TODO: Check when it needs to be disabled on iOS (OpenGL)? + // TODO: Check when it needs to be disabled on iOS? // Force to resize the gameWindow //gameWindow.Resize(deviceInformation.PresentationParameters.BackBufferWidth, deviceInformation.PresentationParameters.BackBufferHeight); } diff --git a/sources/engine/Stride.Graphics.Regression/RegressionHelpers.cs b/sources/engine/Stride.Graphics.Regression/RegressionHelpers.cs index 3776b705e6..2d1b39fc38 100644 --- a/sources/engine/Stride.Graphics.Regression/RegressionHelpers.cs +++ b/sources/engine/Stride.Graphics.Regression/RegressionHelpers.cs @@ -53,10 +53,6 @@ public static ImageTestResultConnection GetDefaultImageTestResultConnection() result.DeviceName = "Direct3D12"; #elif STRIDE_GRAPHICS_API_DIRECT3D11 result.DeviceName = "Direct3D"; - #elif STRIDE_GRAPHICS_API_OPENGLES - result.DeviceName = "OpenGLES"; - #elif STRIDE_GRAPHICS_API_OPENGL - result.DeviceName = "OpenGL"; #elif STRIDE_GRAPHICS_API_VULKAN result.DeviceName = "Vulkan"; #endif @@ -96,10 +92,6 @@ public static string GetPlatformName(TestPlatform platform) { case TestPlatform.WindowsDx: return "Windows_Direct3D11"; - case TestPlatform.WindowsOgl: - return "Windows_OpenGL"; - case TestPlatform.WindowsOgles: - return "Windows_OpenGLES"; case TestPlatform.Android: return "Android"; case TestPlatform.Ios: @@ -119,10 +111,6 @@ public static TestPlatform GetPlatform() return TestPlatform.None; #elif STRIDE_GRAPHICS_API_DIRECT3D return TestPlatform.WindowsDx; -#elif STRIDE_GRAPHICS_API_OPENGLES - return TestPlatform.WindowsOgles; -#elif STRIDE_GRAPHICS_API_OPENGL - return TestPlatform.WindowsOgl; #elif STRIDE_GRAPHICS_API_VULKAN return TestPlatform.WindowsVulkan; #endif @@ -182,8 +170,6 @@ public enum TestPlatform { None, WindowsDx, - WindowsOgl, - WindowsOgles, WindowsVulkan, Android, Ios diff --git a/sources/engine/Stride.Graphics.Regression/Scripts/RunAndroidTest.bat b/sources/engine/Stride.Graphics.Regression/Scripts/RunAndroidTest.bat index 97bfc9702a..93ef8c1a3e 100644 --- a/sources/engine/Stride.Graphics.Regression/Scripts/RunAndroidTest.bat +++ b/sources/engine/Stride.Graphics.Regression/Scripts/RunAndroidTest.bat @@ -16,7 +16,7 @@ FOR /F "skip=1" %%D IN ('adb devices') DO ( C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\Projects\Stride\sources\engine\Stride.Graphics.RegressionTests\Stride.Graphics.RegressionTests.Android.csproj /p:SolutionName=Stride.Android;SolutionDir=C:\Projects\Stride\ /t:Install /p:AdbTarget="-s %%D" REM install the package -> should be done by bamboo too? - REM adb -s %%D -d install -r C:\Projects\Stride\Bin\Android-AnyCPU-OpenGLES\Stride.Graphics.RegressionTests-Signed.apk + REM adb -s %%D -d install -r C:\Projects\Stride\Bin\Android-AnyCPU-Vulkan\Stride.Graphics.RegressionTests-Signed.apk REM run it adb -s %%D shell am start -a android.intent.action.MAIN -n Stride.Graphics.RegressionTests/stride.graphics.regressiontests.Program -e STRIDE_SERVER_IP %1 -e STRIDE_SERVER_PORT %2 -e STRIDE_BUILD_NUMBER %3 @@ -29,7 +29,7 @@ adb -s %4 am shell force-stop Stride.Graphics.RegressionTests C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe C:\Projects\Stride\sources\engine\Stride.Graphics.RegressionTests\Stride.Graphics.RegressionTests.Android.csproj /p:SolutionName=Stride.Android;SolutionDir=C:\Projects\Stride\ /t:Install /p:AdbTarget="-s %4" REM install the package -> should be done by bamboo too? -REM adb -s %%D -d install -r C:\Projects\Stride\Bin\Android-AnyCPU-OpenGLES\Stride.Graphics.RegressionTests-Signed.apk +REM adb -s %%D -d install -r C:\Projects\Stride\Bin\Android-AnyCPU-Vulkan\Stride.Graphics.RegressionTests-Signed.apk REM run it -adb -s %4 shell am start -a android.intent.action.MAIN -n Stride.Graphics.RegressionTests/stride.graphics.regressiontests.Program -e STRIDE_SERVER_IP %1 -e STRIDE_SERVER_PORT %2 -e STRIDE_BUILD_NUMBER %3 -e STRIDE_DEVICE_SERIAL %4 \ No newline at end of file +adb -s %4 shell am start -a android.intent.action.MAIN -n Stride.Graphics.RegressionTests/stride.graphics.regressiontests.Program -e STRIDE_SERVER_IP %1 -e STRIDE_SERVER_PORT %2 -e STRIDE_BUILD_NUMBER %3 -e STRIDE_DEVICE_SERIAL %4 diff --git a/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueAndroidTest.bat b/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueAndroidTest.bat index f0935781ba..e1e65d8f18 100644 --- a/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueAndroidTest.bat +++ b/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueAndroidTest.bat @@ -13,7 +13,7 @@ adb -s %4 am shell force-stop Stride.Graphics.RegressionTests C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe %StrideSdkDir%\sources\engine\Stride.Graphics.RegressionTests\Stride.Graphics.RegressionTests.Android.csproj /p:SolutionName=Stride.Android /p:SolutionDir=%StrideSdkDir%\ /p:Configuration=Release /t:Install /p:AdbTarget="-s %4" REM install the package -> should be done by bamboo too? -REM adb -s %4 -d install -r %6\Bin\Android-AnyCPU-OpenGLES\Stride.Graphics.RegressionTests-Signed.apk +REM adb -s %4 -d install -r %6\Bin\Android-AnyCPU-Vulkan\Stride.Graphics.RegressionTests-Signed.apk REM run it -adb -s %4 shell am start -a android.intent.action.MAIN -n Stride.Graphics.RegressionTests/stride.graphics.regressiontests.TestRunner -e STRIDE_SERVER_IP %1 -e STRIDE_SERVER_PORT %2 -e STRIDE_BUILD_NUMBER %3 -e STRIDE_DEVICE_SERIAL %4 -e STRIDE_TEST_NAME %5 \ No newline at end of file +adb -s %4 shell am start -a android.intent.action.MAIN -n Stride.Graphics.RegressionTests/stride.graphics.regressiontests.TestRunner -e STRIDE_SERVER_IP %1 -e STRIDE_SERVER_PORT %2 -e STRIDE_BUILD_NUMBER %3 -e STRIDE_DEVICE_SERIAL %4 -e STRIDE_TEST_NAME %5 diff --git a/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueWindowsTest.bat b/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueWindowsTest.bat index 8c5176c71e..1b77cf7c9f 100644 --- a/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueWindowsTest.bat +++ b/sources/engine/Stride.Graphics.Regression/Scripts/RunUniqueWindowsTest.bat @@ -13,16 +13,4 @@ if %6 EQU PC_Direct3D11 ( REM run DirectX start Bin\Windows-AnyCPU-Direct3D\Stride.Graphics.RegressionTests.exe %1 %2 %3 %4 %5 -) else if %6 EQU PC_OpenGL ( - REM build OpenGL - REM C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe %StrideSdkDir%\sources\engine\Stride.Graphics.RegressionTests\Stride.Graphics.RegressionTests.csproj /p:SolutionName=Stride.OpenGL;SolutionDir=%StrideSdkDir%\ /t:Build - - REM run OpenGL - start Bin\Windows-AnyCPU-OpenGL\Stride.Graphics.RegressionTests.exe %1 %2 %3 %4 %5 -) else if %6 EQU PC_OpenGLES ( - REM build OpenGL ES - REM C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe %StrideSdkDir%\sources\engine\Stride.Graphics.RegressionTests\Stride.Graphics.RegressionTests.csproj /p:SolutionName=Stride.OpenGLES;SolutionDir=%StrideSdkDir%\ /t:Build - - REM run OpenGL ES - start Bin\Windows-AnyCPU-OpenGLES\Stride.Graphics.RegressionTests.exe %1 %2 %3 %4 %5 ) diff --git a/sources/engine/Stride.Graphics.Tests.11_0/TestComputeShader.cs b/sources/engine/Stride.Graphics.Tests.11_0/TestComputeShader.cs index 699bff091c..cacc0a306b 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/TestComputeShader.cs +++ b/sources/engine/Stride.Graphics.Tests.11_0/TestComputeShader.cs @@ -88,8 +88,6 @@ protected override void Draw(GameTime gameTime) [SkippableFact(Skip="This test is unmaintained and currently doesn't pass")] public void RunTest() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); - RunGameTest(new TestComputeShader()); } } diff --git a/sources/engine/Stride.Graphics.Tests.11_0/TestHammersley.cs b/sources/engine/Stride.Graphics.Tests.11_0/TestHammersley.cs index 9a4d64b0ce..5f08cbe74f 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/TestHammersley.cs +++ b/sources/engine/Stride.Graphics.Tests.11_0/TestHammersley.cs @@ -83,7 +83,6 @@ protected override void Draw(GameTime gameTime) [SkippableFact] public void RunImageLoad() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); RunGameTest(new TestHammersley()); diff --git a/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSH.cs b/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSH.cs index 15a21fa6ca..4b3b729df3 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSH.cs +++ b/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSH.cs @@ -176,8 +176,6 @@ protected override void Draw(GameTime gameTime) [SkippableFact] public void RunTestPass2() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); - RunGameTest(new TestLambertPrefilteringSH()); } } diff --git a/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSHPass2.cs b/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSHPass2.cs index c1d0ec4d57..e126dab209 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSHPass2.cs +++ b/sources/engine/Stride.Graphics.Tests.11_0/TestLambertPrefilteringSHPass2.cs @@ -136,7 +136,6 @@ private void CreateBufferData() [SkippableFact] public void RunTestPass2() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); RunGameTest(new TestLambertPrefilteringSHPass2()); diff --git a/sources/engine/Stride.Graphics.Tests.11_0/TestRadiancePrefilteringGgx.cs b/sources/engine/Stride.Graphics.Tests.11_0/TestRadiancePrefilteringGgx.cs index 2c150d78a5..9a813811db 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/TestRadiancePrefilteringGgx.cs +++ b/sources/engine/Stride.Graphics.Tests.11_0/TestRadiancePrefilteringGgx.cs @@ -239,7 +239,6 @@ private void CreateViewsFor(Texture texture) [SkippableFact] public void RunTest() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); RunGameTest(new TestRadiancePrefilteringGgx()); diff --git a/sources/engine/Stride.Graphics.Tests/TestGraphicsApiCheck.cs b/sources/engine/Stride.Graphics.Tests/TestGraphicsApiCheck.cs index 0b0314e56c..73b97d5acd 100644 --- a/sources/engine/Stride.Graphics.Tests/TestGraphicsApiCheck.cs +++ b/sources/engine/Stride.Graphics.Tests/TestGraphicsApiCheck.cs @@ -12,7 +12,7 @@ namespace Stride.Graphics { // CANNOT WORK INSIDE THE SAME SOLUTION. NEED TO RUN THIS OUTSIDE THE SOLUTION - [Description("Check public Graphics API consistency between Reference, Direct3D, OpenGL42, OpenGLES")] + [Description("Check public Graphics API consistency between Reference, Direct3D11, Direct3D12, Vulkan")] public class TestGraphicsApi { public const string Platform = "Windows"; @@ -24,8 +24,8 @@ public class TestGraphicsApi private static readonly string ReferencePath = Path.Combine(RootPath, GraphicsPath("Null")); private static readonly string GraphicsDirect3DPath = Path.Combine(RootPath, GraphicsPath("Direct3D")); - private static readonly string OpenGL4Path = Path.Combine(RootPath, GraphicsPath("OpenGL")); - private static readonly string OpenGLESPath = Path.Combine(RootPath, GraphicsPath("OpenGLES")); + private static readonly string GraphicsDirect3D12Path = Path.Combine(RootPath, GraphicsPath("Direct3D12")); + private static readonly string GraphicsVulkanPath = Path.Combine(RootPath, GraphicsPath("Vulkan")); private static string GraphicsPath(string api) { @@ -40,15 +40,15 @@ public void TestDirect3D() } [Fact] - public void TestOpenGL42() + public void TestDirect3D12() { - Assert.That(ApiCheck.DiffAssemblyToString(ReferencePath, OpenGL4Path), Is.Null); + Assert.That(ApiCheck.DiffAssemblyToString(ReferencePath, GraphicsDirect3D12Path), Is.Null); } [Fact] - public void TestOpenGLES() + public void TestVulkan() { - Assert.That(ApiCheck.DiffAssemblyToString(ReferencePath, OpenGLESPath), Is.Null); + Assert.That(ApiCheck.DiffAssemblyToString(ReferencePath, VulkanPath), Is.Null); } } } diff --git a/sources/engine/Stride.Graphics.Tests/TestMultiTextures.cs b/sources/engine/Stride.Graphics.Tests/TestMultiTextures.cs index 0a0ca80eff..70a0feeffe 100644 --- a/sources/engine/Stride.Graphics.Tests/TestMultiTextures.cs +++ b/sources/engine/Stride.Graphics.Tests/TestMultiTextures.cs @@ -59,7 +59,7 @@ protected override async Task LoadContent() var compiler = new EffectCompiler(); compiler.SourceDirectories.Add("assets/shaders"); var compilerCache = new EffectCompilerCache(compiler); - var compilerParameters = new CompilerParameters {Platform = GraphicsPlatform.OpenGLCore}; + var compilerParameters = new CompilerParameters(); var compilerResults = compilerCache.Compile(new ShaderMixinSource("MultiTexturesSpriteEffect"), compilerParameters); Assert.That(compilerResults.HasErrors, Is.False); diff --git a/sources/engine/Stride.Graphics.Tests/TestTexture.cs b/sources/engine/Stride.Graphics.Tests/TestTexture.cs index 992caebaf2..500248279e 100644 --- a/sources/engine/Stride.Graphics.Tests/TestTexture.cs +++ b/sources/engine/Stride.Graphics.Tests/TestTexture.cs @@ -190,9 +190,6 @@ public void TestTexture2DArray() [SkippableFact] public void TestTexture2DUnorderedAccess() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGL); - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); - PerformTest( game => { @@ -325,8 +322,6 @@ public void TestTexture3DRenderTarget() [SkippableFact] public void TestDepthStencilBuffer() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); - PerformTest( game => { @@ -365,8 +360,6 @@ public void TestDepthStencilBuffer() [SkippableFact(Skip = "Clear on a Read-Only Depth-Stencil Buffer should be undefined or throw exception; we should rewrite this test to do actual rendering with ReadOnly depth stencil bound?")] public void TestDepthStencilBufferWithNativeReadonly() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); - PerformTest( game => { @@ -402,13 +395,6 @@ public void TestDepthStencilBufferWithNativeReadonly() [SkippableTheory, MemberData(nameof(ImageFileTypes))] public void TestLoadSave(ImageFileType sourceFormat) { - Skip.If(Platform.Type == PlatformType.Android && ( - // TODO: Remove this when mipmap copy is supported on OpenGL by the engine - sourceFormat is ImageFileType.Stride or ImageFileType.Dds || - // TODO: Remove when the Tiff format is supported on Android - sourceFormat == ImageFileType.Tiff), - reason: "Unsupported case for Android"); - Skip.If(sourceFormat is ImageFileType.Wmp, reason: "No input image of this format"); // TODO: Remove this when Load/Save methods are implemented for these types @@ -499,10 +485,7 @@ public void TestLoadDraw(ImageFileType sourceFormat) [InlineData(GraphicsProfile.Level_10_0, GraphicsResourceUsage.Default)] public void TestGetData(GraphicsProfile profile, GraphicsResourceUsage usage) { - // TODO: Modify this when when supported on OpenGL var testArray = profile >= GraphicsProfile.Level_10_0; - // TODO: Remove this limitation when GetData is fixed on OpenGL ES for mip-levels other than 0 - var mipmaps = GraphicsDevice.Platform == GraphicsPlatform.OpenGLES && profile < GraphicsProfile.Level_10_0 ? 1 : 3; PerformTest( game => @@ -516,12 +499,12 @@ public void TestGetData(GraphicsProfile profile, GraphicsResourceUsage usage) : [ TextureFlags.None ]; var pixelFormat = PixelFormat.R8G8B8A8_UNorm; - var data = CreateDebugTextureData(width, height, mipmaps, arraySize, pixelFormat, DefaultColorComputer); + var data = CreateDebugTextureData(width, height, 3, arraySize, pixelFormat, DefaultColorComputer); foreach (var flag in flags) { - using var texture = CreateDebugTexture(game.GraphicsDevice, data, width, height, mipmaps, arraySize, pixelFormat, flag, usage); - CheckDebugTextureData(game.GraphicsContext, texture, width, height, mipmaps, arraySize, pixelFormat, flag, usage, DefaultColorComputer); + using var texture = CreateDebugTexture(game.GraphicsDevice, data, width, height, 3, arraySize, pixelFormat, flag, usage); + CheckDebugTextureData(game.GraphicsContext, texture, width, height, 3, arraySize, pixelFormat, flag, usage, DefaultColorComputer); } }, profile); @@ -534,10 +517,7 @@ public void TestGetData(GraphicsProfile profile, GraphicsResourceUsage usage) [InlineData(GraphicsProfile.Level_10_0, GraphicsResourceUsage.Default)] public void TestCopy(GraphicsProfile profile, GraphicsResourceUsage usageSource) { - // TODO: Modify this when when supported on OpenGL var testArray = profile >= GraphicsProfile.Level_10_0; - // TODO: Remove this limitation when GetData is fixed on OpenGL ES for mip-levels other than 0 - var mipmaps = GraphicsDevice.Platform == GraphicsPlatform.OpenGLES && profile < GraphicsProfile.Level_10_0 ? 1 : 3; PerformTest( game => @@ -557,7 +537,7 @@ public void TestCopy(GraphicsProfile profile, GraphicsResourceUsage usageSource) ? ColorComputerR8 : DefaultColorComputer; - var data = CreateDebugTextureData(width, height, mipmaps, arraySize, pixelFormat, colorComputer); + var data = CreateDebugTextureData(width, height, 3, arraySize, pixelFormat, colorComputer); TextureFlags[] sourceFlags = usageSource == GraphicsResourceUsage.Default ? [ TextureFlags.ShaderResource, TextureFlags.RenderTarget, TextureFlags.RenderTarget | TextureFlags.ShaderResource ] @@ -565,12 +545,12 @@ public void TestCopy(GraphicsProfile profile, GraphicsResourceUsage usageSource) foreach (var flag in sourceFlags) { - using var texture = CreateDebugTexture(game.GraphicsDevice, data, width, height, mipmaps, arraySize, pixelFormat, flag, usageSource); + using var texture = CreateDebugTexture(game.GraphicsDevice, data, width, height, 3, arraySize, pixelFormat, flag, usageSource); using var copyTexture = destinationStaged ? texture.ToStaging() : texture.Clone(); game.GraphicsContext.CommandList.Copy(texture, copyTexture); - CheckDebugTextureData(game.GraphicsContext, copyTexture, width, height, mipmaps, arraySize, pixelFormat, flag, usageSource, colorComputer); + CheckDebugTextureData(game.GraphicsContext, copyTexture, width, height, 3, arraySize, pixelFormat, flag, usageSource, colorComputer); } } } diff --git a/sources/engine/Stride.Graphics/BufferPool.cs b/sources/engine/Stride.Graphics/BufferPool.cs index d441b261c4..cd8630fafe 100644 --- a/sources/engine/Stride.Graphics/BufferPool.cs +++ b/sources/engine/Stride.Graphics/BufferPool.cs @@ -164,14 +164,14 @@ public enum BufferPoolAllocationType { /// /// Notify the allocator that this buffer won't be reused for much more than 1 (or few) draw calls. - /// In practice, on older D3D11 (not 11.1) and OpenGL ES 2.0 hardware, we won't use a dedicated cbuffer. + /// In practice, on older D3D11 (not 11.1), we won't use a dedicated cbuffer. /// This has no effect on new API where we can bind cbuffer offsets. /// UsedOnce, /// /// Notify the allocator that this buffer will be reused for many draw calls. - /// In practice, on older D3D11 (not 11.1) and OpenGL ES 2.0 hardware, we will use a dedicated cbuffer. + /// In practice, on older D3D11 (not 11.1), we will use a dedicated cbuffer. /// This has no effect on new API where we can bind cbuffer offsets. /// UsedMultipleTime diff --git a/sources/engine/Stride.Graphics/DescriptorPool.cs b/sources/engine/Stride.Graphics/DescriptorPool.cs index 05c7ca5592..b194c89a71 100644 --- a/sources/engine/Stride.Graphics/DescriptorPool.cs +++ b/sources/engine/Stride.Graphics/DescriptorPool.cs @@ -24,7 +24,7 @@ public static DescriptorPool New(GraphicsDevice graphicsDevice, DescriptorTypeCo return new DescriptorPool(graphicsDevice, counts); } -#if STRIDE_GRAPHICS_API_DIRECT3D11 || STRIDE_GRAPHICS_API_OPENGL || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) +#if STRIDE_GRAPHICS_API_DIRECT3D11 || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) /// /// The Descriptors allocated in this Descriptor Pool, along with their offset and size. diff --git a/sources/engine/Stride.Graphics/DescriptorSet.cs b/sources/engine/Stride.Graphics/DescriptorSet.cs index 80cb0bfd71..1e5f000402 100644 --- a/sources/engine/Stride.Graphics/DescriptorSet.cs +++ b/sources/engine/Stride.Graphics/DescriptorSet.cs @@ -22,7 +22,7 @@ public static DescriptorSet New(GraphicsDevice graphicsDevice, DescriptorPool po return new DescriptorSet(graphicsDevice, pool, layout); } -#if STRIDE_GRAPHICS_API_DIRECT3D11 || STRIDE_GRAPHICS_API_OPENGL || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) +#if STRIDE_GRAPHICS_API_DIRECT3D11 || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) /// /// An array of Descriptors in the Descriptor Set used for managing the Graphics Resources, diff --git a/sources/engine/Stride.Graphics/DescriptorSetLayout.cs b/sources/engine/Stride.Graphics/DescriptorSetLayout.cs index 564f427700..871d089577 100644 --- a/sources/engine/Stride.Graphics/DescriptorSetLayout.cs +++ b/sources/engine/Stride.Graphics/DescriptorSetLayout.cs @@ -25,7 +25,7 @@ public static DescriptorSetLayout New(GraphicsDevice device, DescriptorSetLayout return new DescriptorSetLayout(device, builder); } -#if STRIDE_GRAPHICS_API_DIRECT3D11 || STRIDE_GRAPHICS_API_OPENGL || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) +#if STRIDE_GRAPHICS_API_DIRECT3D11 || (STRIDE_GRAPHICS_API_VULKAN && STRIDE_GRAPHICS_NO_DESCRIPTOR_COPIES) /// /// The number of elements in the Descriptor Set Layout. diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index a16a718adc..ecf83fc0ab 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -187,7 +187,7 @@ ComPtr CreateQuery() /// Enables or disables profiling. /// /// to enable profiling; to disable it. - public void EnableProfile(bool enabledFlag) { } // TODO: Implement profiling with PIX markers? Currently, profiling is only implemented for OpenGL + public void EnableProfile(bool enabledFlag) { } // TODO: Implement profiling with PIX markers? /// /// Marks the Graphics Device Context as inactive on the current thread. diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index acc97d6f06..78c39f0162 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -240,7 +240,7 @@ public void Begin() /// Enables or disables profiling. /// /// to enable profiling; to disable it. - public void EnableProfile(bool enabledFlag) { } // TODO: Implement profiling with PIX markers? Currently, profiling is only implemented for OpenGL + public void EnableProfile(bool enabledFlag) { } // TODO: Implement profiling with PIX markers? /// /// Marks the Graphics Device Context as inactive on the current thread. diff --git a/sources/engine/Stride.Graphics/GraphicsDeviceFeatures.cs b/sources/engine/Stride.Graphics/GraphicsDeviceFeatures.cs index 8673e097c1..f4e3205575 100644 --- a/sources/engine/Stride.Graphics/GraphicsDeviceFeatures.cs +++ b/sources/engine/Stride.Graphics/GraphicsDeviceFeatures.cs @@ -164,13 +164,6 @@ public partial struct GraphicsDeviceFeatures /// public readonly FeaturesPerFormat this[PixelFormat pixelFormat] => mapFeaturesPerFormat[(int) pixelFormat]; -#if STRIDE_GRAPHICS_API_OPENGL - // Defined here to avoid CS0282 warning if defined in GraphicsDeviceFeatures.OpenGL.cs - internal string Vendor; - internal string Renderer; - internal System.Collections.Generic.IList SupportedExtensions; -#endif - /// /// Contains information about the features a supports for a particular . /// diff --git a/sources/engine/Stride.Graphics/NamespaceDoc.cs b/sources/engine/Stride.Graphics/NamespaceDoc.cs index 29c1896e7c..83a5ea48ac 100644 --- a/sources/engine/Stride.Graphics/NamespaceDoc.cs +++ b/sources/engine/Stride.Graphics/NamespaceDoc.cs @@ -3,7 +3,7 @@ namespace Stride.Graphics { /// - /// The namespace contains types that provides a unified Graphics API for Direct3D, OpenGL and OpenGLES. + /// The namespace contains types that provides a unified Graphics API for Direct3D 11, 12 and Vulkan. /// [System.Runtime.CompilerServices.CompilerGenerated] internal class NamespaceDoc diff --git a/sources/engine/Stride.Graphics/OpenGL/BlendState.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/BlendState.OpenGL.cs deleted file mode 100644 index 6cb567a367..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/BlendState.OpenGL.cs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - class BlendState - { - internal readonly ColorWriteChannels ColorWriteChannels; - - private readonly bool blendEnable; - private readonly BlendEquationModeEXT blendEquationModeColor; - private readonly BlendEquationModeEXT blendEquationModeAlpha; - private readonly BlendingFactor blendFactorSrcColor; - private readonly BlendingFactor blendFactorSrcAlpha; - private readonly BlendingFactor blendFactorDestColor; - private readonly BlendingFactor blendFactorDestAlpha; - private readonly uint blendEquationHash; - private readonly uint blendFuncHash; - - internal unsafe BlendState(BlendStateDescription blendStateDescription, bool hasRenderTarget) - { - var renderTargets = &blendStateDescription.RenderTargets[0]; - for (int i = 1; i < 8; ++i) - { - if (renderTargets[i].BlendEnable || renderTargets[i].ColorWriteChannels != ColorWriteChannels.All) - throw new NotSupportedException(); - } - - ColorWriteChannels = blendStateDescription.RenderTargets[0].ColorWriteChannels; - if (!hasRenderTarget) - ColorWriteChannels = 0; - - blendEnable = blendStateDescription.RenderTargets[0].BlendEnable; - - blendEquationModeColor = ToOpenGL(blendStateDescription.RenderTargets[0].ColorBlendFunction); - blendEquationModeAlpha = ToOpenGL(blendStateDescription.RenderTargets[0].AlphaBlendFunction); - blendFactorSrcColor = ToOpenGL(blendStateDescription.RenderTargets[0].ColorSourceBlend); - blendFactorSrcAlpha = ToOpenGL(blendStateDescription.RenderTargets[0].AlphaSourceBlend); - blendFactorDestColor = ToOpenGL(blendStateDescription.RenderTargets[0].ColorDestinationBlend); - blendFactorDestAlpha = ToOpenGL(blendStateDescription.RenderTargets[0].AlphaDestinationBlend); - - blendEquationHash = (uint)blendStateDescription.RenderTargets[0].ColorBlendFunction - | ((uint)blendStateDescription.RenderTargets[0].AlphaBlendFunction << 8); - - blendFuncHash = (uint)blendStateDescription.RenderTargets[0].ColorSourceBlend - | ((uint)blendStateDescription.RenderTargets[0].AlphaSourceBlend << 8) - | ((uint)blendStateDescription.RenderTargets[0].ColorDestinationBlend << 16) - | ((uint)blendStateDescription.RenderTargets[0].AlphaDestinationBlend << 24); - } - - public static BlendEquationModeEXT ToOpenGL(BlendFunction blendFunction) - { - switch (blendFunction) - { - case BlendFunction.Subtract: - return BlendEquationModeEXT.FuncSubtract; - case BlendFunction.Add: - return BlendEquationModeEXT.FuncAdd; - case BlendFunction.Max: - return BlendEquationModeEXT.Max; - case BlendFunction.Min: - return BlendEquationModeEXT.Min; - case BlendFunction.ReverseSubtract: - return BlendEquationModeEXT.FuncReverseSubtract; - default: - throw new NotSupportedException(); - } - } - - public static BlendingFactor ToOpenGL(Blend blend) - { - switch (blend) - { - case Blend.Zero: - return BlendingFactor.Zero; - case Blend.One: - return BlendingFactor.One; - case Blend.SourceColor: - return BlendingFactor.SrcColor; - case Blend.InverseSourceColor: - return BlendingFactor.OneMinusSrcColor; - case Blend.SourceAlpha: - return BlendingFactor.SrcAlpha; - case Blend.InverseSourceAlpha: - return BlendingFactor.OneMinusSrcAlpha; - case Blend.DestinationAlpha: - return BlendingFactor.DstAlpha; - case Blend.InverseDestinationAlpha: - return BlendingFactor.OneMinusDstAlpha; - case Blend.DestinationColor: - return BlendingFactor.DstColor; - case Blend.InverseDestinationColor: - return BlendingFactor.OneMinusDstColor; - case Blend.SourceAlphaSaturate: - return BlendingFactor.SrcAlphaSaturate; - case Blend.BlendFactor: - return BlendingFactor.ConstantColor; - case Blend.InverseBlendFactor: - return BlendingFactor.OneMinusConstantColor; - case Blend.SecondarySourceColor: - case Blend.InverseSecondarySourceColor: - case Blend.SecondarySourceAlpha: - case Blend.InverseSecondarySourceAlpha: - throw new NotSupportedException(); - default: - throw new ArgumentOutOfRangeException("blend"); - } - } - - internal void Apply(CommandList commandList, BlendState oldBlendState) - { - var GL = commandList.GL; - // note: need to update blend equation, blend function and color mask even when the blend state is disable in order to keep the hash based caching system valid - - if (blendEnable && !oldBlendState.blendEnable) - GL.Enable(EnableCap.Blend); - - if (blendEquationHash != oldBlendState.blendEquationHash) - GL.BlendEquationSeparate(blendEquationModeColor, blendEquationModeAlpha); - - if (blendFuncHash != oldBlendState.blendFuncHash) - GL.BlendFuncSeparate(blendFactorSrcColor, blendFactorDestColor, blendFactorSrcAlpha, blendFactorDestAlpha); - - if (commandList.NewBlendFactor != commandList.BoundBlendFactor) - { - commandList.BoundBlendFactor = commandList.NewBlendFactor; - GL.BlendColor(commandList.NewBlendFactor.R, commandList.NewBlendFactor.G, commandList.NewBlendFactor.B, commandList.NewBlendFactor.A); - } - - if (ColorWriteChannels != oldBlendState.ColorWriteChannels) - { - RestoreColorMask(GL); - } - - if (!blendEnable && oldBlendState.blendEnable) - GL.Disable(EnableCap.Blend); - } - - internal void RestoreColorMask(GL GL) - { - GL.ColorMask( - (ColorWriteChannels & ColorWriteChannels.Red) != 0, - (ColorWriteChannels & ColorWriteChannels.Green) != 0, - (ColorWriteChannels & ColorWriteChannels.Blue) != 0, - (ColorWriteChannels & ColorWriteChannels.Alpha) != 0); - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/Buffer.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/Buffer.OpenGL.cs deleted file mode 100644 index 4d52936d4a..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/Buffer.OpenGL.cs +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Diagnostics; -using System.Runtime.InteropServices; -using Stride.Core; - -namespace Stride.Graphics -{ - public unsafe partial class Buffer - { - internal const int BufferTextureEmulatedWidth = 4096; - - internal uint BufferId; - internal BufferTargetARB BufferTarget; - internal BufferUsageARB BufferUsageHint; - - private int bufferTextureElementSize; - - /// - /// Initializes a new instance of the class. - /// - /// The description. - /// Type of the buffer. - /// The view format. - /// The data pointer. - protected partial Buffer InitializeFromImpl(ref readonly BufferDescription description, BufferFlags viewFlags, PixelFormat viewFormat, IntPtr dataPointer) - { - bufferDescription = description; - ViewFlags = viewFlags; - - bool isCompressed; - OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref viewFormat, out TextureInternalFormat, out TextureFormat, out TextureType, out bufferTextureElementSize, out isCompressed); - - ViewFormat = viewFormat; - - Recreate(dataPointer); - - if (GraphicsDevice != null) - { - GraphicsDevice.RegisterBufferMemoryUsage(SizeInBytes); - } - - return this; - } - - public void Recreate(IntPtr dataPointer) - { - if ((ViewFlags & BufferFlags.VertexBuffer) == BufferFlags.VertexBuffer) - { - BufferTarget = BufferTargetARB.ArrayBuffer; - } - else if ((ViewFlags & BufferFlags.IndexBuffer) == BufferFlags.IndexBuffer) - { - BufferTarget = BufferTargetARB.ElementArrayBuffer; - } - else if ((ViewFlags & BufferFlags.ConstantBuffer) == BufferFlags.ConstantBuffer) - { - BufferTarget = BufferTargetARB.UniformBuffer; - } - else if ((ViewFlags & BufferFlags.UnorderedAccess) == BufferFlags.UnorderedAccess) - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException("GLES not support UnorderedAccess buffer"); -#else - BufferTarget = BufferTargetARB.ShaderStorageBuffer; -#endif - } - else if ((ViewFlags & BufferFlags.ShaderResource) == BufferFlags.ShaderResource && GraphicsDevice.HasTextureBuffers) - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - BufferTarget = BufferTargetARB.TextureBuffer; -#endif - } - - Init(dataPointer); - } - - /// - protected internal override bool OnRecreate() - { - base.OnRecreate(); - - if (Description.Usage == GraphicsResourceUsage.Immutable - || Description.Usage == GraphicsResourceUsage.Default) - return false; - - Recreate(IntPtr.Zero); - - return true; - } - - /// - protected internal override void OnDestroyed(bool immediately = false) - { - using (GraphicsDevice.UseOpenGLCreationContext()) - { - GL.DeleteTextures(1, in TextureId); - GL.DeleteBuffers(1, in BufferId); - } - - BufferId = 0; - - if (GraphicsDevice != null) - { - GraphicsDevice.RegisterBufferMemoryUsage(-SizeInBytes); - } - - base.OnDestroyed(immediately); - } - - protected void Init(IntPtr dataPointer) - { - switch (Description.Usage) - { - case GraphicsResourceUsage.Default: - case GraphicsResourceUsage.Immutable: - BufferUsageHint = BufferUsageARB.StaticDraw; - break; - case GraphicsResourceUsage.Dynamic: - case GraphicsResourceUsage.Staging: - BufferUsageHint = BufferUsageARB.DynamicDraw; - break; - default: - throw new ArgumentOutOfRangeException("description.Usage"); - } - - using (var openglContext = GraphicsDevice.UseOpenGLCreationContext()) - { - if ((Flags & BufferFlags.ShaderResource) != 0 && !GraphicsDevice.HasTextureBuffers) - { - // Create a texture instead of a buffer on platforms where it's not supported - elementCount = SizeInBytes / bufferTextureElementSize; - TextureTarget = TextureTarget.Texture2D; - GL.GenTextures(1, out TextureId); - GL.BindTexture(TextureTarget, TextureId); - - GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); - GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - - UpdateTextureSubResource(dataPointer, 0, 0, SizeInBytes); - - GL.BindTexture(TextureTarget, 0); - - if (openglContext.CommandList != null) - { - // If we messed up with some states of a command list, mark dirty states - openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null; - } - } - else - { - // If we're on main context, unbind VAO before binding context. - // It will be bound again on next draw. - //if (!creationContext.UseDeviceCreationContext) - // GraphicsDevice.UnbindVertexArrayObject(); - - GL.GenBuffers(1, out BufferId); - GL.BindBuffer(BufferTarget, BufferId); - GL.BufferData(BufferTarget, (UIntPtr)Description.SizeInBytes, (void*)dataPointer, BufferUsageHint); - GL.BindBuffer(BufferTarget, 0); - - if ((Flags & BufferFlags.ShaderResource) != 0) - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - TextureTarget = TextureTarget.TextureBuffer; - GL.GenTextures(1, out TextureId); - GL.BindTexture(TextureTarget, TextureId); - // TODO: Check if this is really valid to cast PixelInternalFormat to SizedInternalFormat in all cases? - GL.TexBuffer(TextureTarget.TextureBuffer, (SizedInternalFormat)TextureInternalFormat, BufferId); -#endif - } - } - } - } - - internal void UpdateTextureSubResource(IntPtr dataPointer, int subresouceLevel, int offset, int count) - { - // If overwriting everything, create a new texture - if (offset == 0 && count == SizeInBytes) - GL.TexImage2D(TextureTarget, subresouceLevel, TextureInternalFormat, (uint)Math.Min(BufferTextureEmulatedWidth, elementCount), (uint)(elementCount + BufferTextureEmulatedWidth - 1) / BufferTextureEmulatedWidth, 0, TextureFormat, TextureType, IntPtr.Zero); - - // Work with full elements - Debug.Assert(offset % bufferTextureElementSize == 0 && count % bufferTextureElementSize == 0, "When updating a buffer texture, offset and count should be a multiple of the element size"); - offset /= bufferTextureElementSize; - count /= bufferTextureElementSize; - - // Upload data - if (dataPointer != IntPtr.Zero) - { - // First line - if (offset % BufferTextureEmulatedWidth != 0) - { - var firstLineSize = Math.Min(count, BufferTextureEmulatedWidth - (offset % BufferTextureEmulatedWidth)); - - GL.TexSubImage2D(TextureTarget, 0, - offset % BufferTextureEmulatedWidth, offset / BufferTextureEmulatedWidth, // coordinates - (uint)(BufferTextureEmulatedWidth - (offset % BufferTextureEmulatedWidth)), 1, // size - TextureFormat, TextureType, (void*)dataPointer); - - offset += firstLineSize; - count -= firstLineSize; - dataPointer += firstLineSize * bufferTextureElementSize; - } - - // Middle lines - if (count / BufferTextureEmulatedWidth > 0) - GL.TexSubImage2D(TextureTarget, 0, - 0, offset / BufferTextureEmulatedWidth, // coordinates - BufferTextureEmulatedWidth, (uint)(count / BufferTextureEmulatedWidth), // size - TextureFormat, TextureType, (void*)dataPointer); - - // Last line is done separately (to avoid buffer overrun if last line is not multiple of BufferTextureEmulatedWidth) - if (count % BufferTextureEmulatedWidth != 0) - GL.TexSubImage2D(TextureTarget, 0, - 0, count / BufferTextureEmulatedWidth, // coordinates - (uint)(count % BufferTextureEmulatedWidth), 1, // size - TextureFormat, TextureType, (void*)(dataPointer + (count/ BufferTextureEmulatedWidth * BufferTextureEmulatedWidth) * bufferTextureElementSize)); - } - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/CommandList.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/CommandList.OpenGL.cs deleted file mode 100644 index 23ced5e5b5..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/CommandList.OpenGL.cs +++ /dev/null @@ -1,1830 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL - -using System; -using System.Threading; -using Stride.Core; -using Stride.Core.Mathematics; -using Stride; -using Stride.Shaders; -using Color4 = Stride.Core.Mathematics.Color4; - -namespace Stride.Graphics -{ - public partial class CommandList - { - // How many frames to wait before allowing non-blocking texture readbacks - private const int ReadbackFrameDelay = 2; - private const int MaxBoundRenderTargets = 16; - - internal uint enabledVertexAttribArrays; - private uint boundProgram = 0; - - internal int BoundStencilReference; - internal int NewStencilReference; - internal Color4 BoundBlendFactor; - internal Color4 NewBlendFactor; - - private bool vboDirty = true; - - private GraphicsDevice.FBOTexture boundDepthStencilBuffer; - private int boundRenderTargetCount = 0; - private GraphicsDevice.FBOTexture[] boundRenderTargets = new GraphicsDevice.FBOTexture[MaxBoundRenderTargets]; - internal GraphicsResource[] boundShaderResourceViews = new GraphicsResource[64]; - private GraphicsResource[] shaderResourceViews = new GraphicsResource[64]; - private SamplerState[] samplerStates = new SamplerState[64]; - - internal DepthStencilBoundState DepthStencilBoundState; - internal RasterizerBoundState RasterizerBoundState; - - private Buffer[] constantBuffers = new Buffer[64]; - - private uint boundFBO; - private bool needUpdateFBO = true; - - private PipelineState newPipelineState; - private PipelineState currentPipelineState; - - private DescriptorSet[] currentDescriptorSets = new DescriptorSet[32]; - - internal int activeTexture = 0; - - private IndexBufferView indexBuffer; - - private VertexBufferView[] vertexBuffers = new VertexBufferView[8]; - -#if !STRIDE_GRAPHICS_API_OPENGLES - private readonly float[] nativeViewports = new float[4 * MaxViewportAndScissorRectangleCount]; - private readonly int[] nativeScissorRectangles = new int[4 * MaxViewportAndScissorRectangleCount]; -#endif - - public static CommandList New(GraphicsDevice device) - { - if (device.InternalMainCommandList != null) - { - throw new InvalidOperationException("Can't create multiple command lists with OpenGL"); - } - return new CommandList(device); - } - - private CommandList(GraphicsDevice device) : base(device) - { - device.InternalMainCommandList = this; - - // Default state - DepthStencilBoundState.DepthBufferWriteEnable = true; - DepthStencilBoundState.StencilWriteMask = 0xFF; - RasterizerBoundState.FrontFaceDirection = FrontFaceDirection.Ccw; -#if !STRIDE_GRAPHICS_API_OPENGLES - RasterizerBoundState.PolygonMode = PolygonMode.Fill; -#endif - - ClearState(); - } - - // No OpenGL-specific implementation - public unsafe partial void Reset() { } - - // No OpenGL-specific implementation - public partial void Flush() { } - - // No OpenGL-specific implementation - public partial CompiledCommandList Close() - { - return default; - } - - public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - var clearFBO = GraphicsDevice.FindOrCreateFBO(depthStencilBuffer); - if (clearFBO != boundFBO) - GL.BindFramebuffer(FramebufferTarget.Framebuffer, clearFBO); - - ClearBufferMask clearBufferMask = - ((options & DepthStencilClearOptions.DepthBuffer) == DepthStencilClearOptions.DepthBuffer ? ClearBufferMask.DepthBufferBit : 0) - | ((options & DepthStencilClearOptions.Stencil) == DepthStencilClearOptions.Stencil ? ClearBufferMask.StencilBufferBit : 0); - GL.ClearDepth(depth); - GL.ClearStencil(stencil); - - // Check if we need to change depth mask - var currentDepthMask = DepthStencilBoundState.DepthBufferWriteEnable; - - if (!currentDepthMask) - GL.DepthMask(true); - GL.Clear(clearBufferMask); - if (!currentDepthMask) - GL.DepthMask(false); - - if (clearFBO != boundFBO) - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - } - - public void Clear(Texture renderTarget, Color4 color) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - var clearFBO = GraphicsDevice.FindOrCreateFBO(renderTarget); - if (clearFBO != boundFBO) - GL.BindFramebuffer(FramebufferTarget.Framebuffer, clearFBO); - - // Check if we need to change color mask - var blendState = currentPipelineState.BlendState; - var needColorMaskOverride = blendState.ColorWriteChannels != ColorWriteChannels.All; - - if (needColorMaskOverride) - GL.ColorMask(true, true, true, true); - - GL.ClearColor(color.R, color.G, color.B, color.A); - GL.Clear(ClearBufferMask.ColorBufferBit); - - // revert the color mask value as it was before - if (needColorMaskOverride) - blendState.RestoreColorMask(GL); - - if (clearFBO != boundFBO) - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - } - - public unsafe void ClearReadWrite(Buffer buffer, Vector4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if ((buffer.ViewFlags & BufferFlags.UnorderedAccess) != BufferFlags.UnorderedAccess) - throw new ArgumentException("Buffer does not support unordered access"); - - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - GL.ClearBufferData((BufferStorageTarget)buffer.BufferTarget, (SizedInternalFormat)buffer.TextureInternalFormat, buffer.TextureFormat, PixelType.UnsignedInt8888, value); - GL.BindBuffer(buffer.BufferTarget, 0); -#endif - } - - public unsafe void ClearReadWrite(Buffer buffer, Int4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if ((buffer.ViewFlags & BufferFlags.UnorderedAccess) != BufferFlags.UnorderedAccess) - throw new ArgumentException("Buffer does not support unordered access"); - - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - GL.ClearBufferData((BufferStorageTarget)buffer.BufferTarget, (SizedInternalFormat)buffer.TextureInternalFormat, buffer.TextureFormat, PixelType.UnsignedInt8888, value); - GL.BindBuffer(buffer.BufferTarget, 0); -#endif - } - - public unsafe void ClearReadWrite(Buffer buffer, UInt4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if ((buffer.ViewFlags & BufferFlags.UnorderedAccess) != BufferFlags.UnorderedAccess) - throw new ArgumentException("Buffer does not support unordered access"); - - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - GL.ClearBufferData((BufferStorageTarget)buffer.BufferTarget, (SizedInternalFormat)buffer.TextureInternalFormat, buffer.TextureFormat, PixelType.UnsignedInt8888, value); - GL.BindBuffer(buffer.BufferTarget, 0); -#endif - } - - public unsafe void ClearReadWrite(Texture texture, Vector4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - GL.BindTexture(texture.TextureTarget, texture.TextureId); - - GL.ClearTexImage(texture.TextureId, 0, texture.TextureFormat, texture.TextureType, value); - - GL.BindTexture(texture.TextureTarget, 0); - boundShaderResourceViews[0] = null; -#endif - } - - public unsafe void ClearReadWrite(Texture texture, Int4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - GL.BindTexture(texture.TextureTarget, texture.TextureId); - - GL.ClearTexImage(texture.TextureId, 0, texture.TextureFormat, texture.TextureType, value); - - GL.BindTexture(texture.TextureTarget, 0); - boundShaderResourceViews[0] = null; -#endif - } - - public unsafe void ClearReadWrite(Texture texture, UInt4 value) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - GL.BindTexture(texture.TextureTarget, texture.TextureId); - - GL.ClearTexImage(texture.TextureId, 0, texture.TextureFormat, texture.TextureType, value); - - GL.BindTexture(texture.TextureTarget, 0); - boundShaderResourceViews[0] = null; -#endif - } - - /// - /// OpenGL-specific implementation that clears and restores the state of the Graphics Device. - /// - private partial void ClearStateImpl() - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - // Clear sampler states - for (int i = 0; i < samplerStates.Length; ++i) - samplerStates[i] = null; - - for (int i = 0; i < boundShaderResourceViews.Length; ++i) - { - shaderResourceViews[i] = null; - } - - // Clear active texture state - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - - // set default states - currentPipelineState = GraphicsDevice.DefaultPipelineState; - newPipelineState = GraphicsDevice.DefaultPipelineState; - - // Actually reset states - //currentPipelineState.BlendState.Apply(); - GL.Disable(EnableCap.Blend); - GL.ColorMask(true, true, true, true); - currentPipelineState.DepthStencilState.Apply(this); - currentPipelineState.RasterizerState.Apply(this); - -#if STRIDE_GRAPHICS_API_OPENGLCORE - GL.Enable(EnableCap.FramebufferSrgb); -#endif - } - - /// - /// Copy a region of a into another. - /// - /// The source from which to copy the data - /// The region of the source to copy. - /// The destination into which to copy the data - /// This might alter some states such as currently bound texture. - public unsafe void CopyRegion(GraphicsResource source, int sourceSubResource, ResourceRegion? regionSource, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - var sourceTexture = source as Texture; - var destTexture = destination as Texture; - - if (sourceTexture == null || destTexture == null) - { - throw new NotSupportedException("Copy is only implemented for Texture objects."); - } - - // Get parent texture - if (sourceTexture.ParentTexture != null) - sourceTexture = sourceTexture.ParentTexture; - if (destTexture.ParentTexture != null) - destTexture = sourceTexture.ParentTexture; - - var sourceWidth = Texture.CalculateMipSize(sourceTexture.Description.Width, sourceSubResource % sourceTexture.MipLevelCount); - var sourceHeight = Texture.CalculateMipSize(sourceTexture.Description.Height, sourceSubResource % sourceTexture.MipLevelCount); - var sourceDepth = Texture.CalculateMipSize(sourceTexture.Description.Depth, sourceSubResource % sourceTexture.MipLevelCount); - - var sourceRegion = regionSource.HasValue ? regionSource.Value : new ResourceRegion(0, 0, 0, sourceWidth, sourceHeight, sourceDepth); - var sourceRectangle = new Rectangle(sourceRegion.Left, sourceRegion.Top, sourceRegion.Right - sourceRegion.Left, sourceRegion.Bottom - sourceRegion.Top); - - if (sourceRectangle.Width == 0 || sourceRectangle.Height == 0) - return; - - - if (destTexture.Description.Usage == GraphicsResourceUsage.Staging) - { - if (sourceTexture.Description.Usage == GraphicsResourceUsage.Staging) - { - // Staging => Staging - if (sourceRegion.Left != 0 || sourceRegion.Top != 0 || sourceRegion.Front != 0 - || sourceRegion.Right != sourceWidth || sourceRegion.Bottom != sourceHeight || sourceRegion.Back != sourceDepth) - { - throw new NotSupportedException("ReadPixels from staging texture to staging texture only support full copy of subresource"); - } - - GL.BindBuffer(BufferTargetARB.CopyReadBuffer, sourceTexture.PixelBufferObjectId); - GL.BindBuffer(BufferTargetARB.CopyWriteBuffer, destTexture.PixelBufferObjectId); - GL.CopyBufferSubData(CopyBufferSubDataTarget.CopyReadBuffer, CopyBufferSubDataTarget.CopyWriteBuffer, - (IntPtr)sourceTexture.ComputeBufferOffset(sourceSubResource, 0), - (IntPtr)destTexture.ComputeBufferOffset(destinationSubResource, 0), - (UIntPtr)destTexture.ComputeSubResourceSize(destinationSubResource)); - } - else - { - // GPU => Staging - if (dstX != 0 || dstY != 0 || dstZ != 0) - throw new NotSupportedException("ReadPixels from staging texture using non-zero destination is not supported"); - - GL.Viewport(0, 0, (uint)sourceWidth, (uint)sourceHeight); - - var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format); - - GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO); - var attachmentType = FramebufferAttachment.ColorAttachment0; - - for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice) - { - attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubResource / sourceTexture.MipLevelCount + depthSlice, sourceSubResource % sourceTexture.MipLevelCount)); - - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, destTexture.PixelBufferObjectId); - GL.ReadPixels(sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width, (uint)sourceRectangle.Height, destTexture.TextureFormat, destTexture.TextureType, (void*)destTexture.ComputeBufferOffset(destinationSubResource, depthSlice)); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); - - destTexture.PixelBufferFrame = GraphicsDevice.FrameCounter; - } - - // Unbind attachment - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget.Texture2D, 0, 0); - - // Restore FBO and viewport - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (uint)viewports[0].Width, (uint)viewports[0].Height); - } - return; - } - - // GPU => GPU - { - var isDepthBuffer = Texture.InternalIsDepthStencilFormat(sourceTexture.Format); - - // Use our temporary mutable FBO - GL.BindFramebuffer(FramebufferTarget.Framebuffer, isDepthBuffer ? GraphicsDevice.CopyDepthSourceFBO : GraphicsDevice.CopyColorSourceFBO); - - var attachmentType = FramebufferAttachment.ColorAttachment0; - - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - GL.Viewport(0, 0, (uint)sourceWidth, (uint)sourceHeight); - - GL.BindTexture(destTexture.TextureTarget, destTexture.TextureId); - - for (int depthSlice = sourceRegion.Front; depthSlice < sourceRegion.Back; ++depthSlice) - { - // Note: In practice, either it's a 2D texture array and its arrayslice can be non zero, or it's a 3D texture and it's depthslice can be non-zero, but not both at the same time - attachmentType = GraphicsDevice.UpdateFBO(FramebufferTarget.Framebuffer, new GraphicsDevice.FBOTexture(sourceTexture, sourceSubResource / sourceTexture.MipLevelCount + depthSlice, sourceSubResource % sourceTexture.MipLevelCount)); - - var arraySlice = destinationSubResource / destTexture.MipLevelCount; - var mipLevel = destinationSubResource % destTexture.MipLevelCount; - - switch (destTexture.TextureTarget) - { -#if !STRIDE_GRAPHICS_API_OPENGLES - case TextureTarget.Texture1D: - GL.CopyTexSubImage1D(TextureTarget.Texture1D, mipLevel, dstX, sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width); - break; -#endif - case TextureTarget.Texture2D: - GL.CopyTexSubImage2D(TextureTarget.Texture2D, mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width, (uint)sourceRectangle.Height); - break; - case TextureTarget.Texture2DArray: - GL.CopyTexSubImage3D(TextureTarget.Texture2DArray, mipLevel, dstX, dstY, arraySlice, sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width, (uint)sourceRectangle.Height); - break; - case TextureTarget.Texture3D: - GL.CopyTexSubImage3D(TextureTarget.Texture3D, mipLevel, dstX, dstY, depthSlice, sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width, (uint)sourceRectangle.Height); - break; - case TextureTarget.TextureCubeMap: - GL.CopyTexSubImage2D(Texture.GetTextureTargetForDataSet2D(destTexture.TextureTarget, arraySlice), mipLevel, dstX, dstY, sourceRectangle.Left, sourceRectangle.Top, (uint)sourceRectangle.Width, (uint)sourceRectangle.Height); - break; - default: - throw new NotSupportedException("Invalid texture target: " + destTexture.TextureTarget); - } - } - - // Unbind texture and force it to be set again next draw call - GL.BindTexture(destTexture.TextureTarget, 0); - boundShaderResourceViews[0] = null; - - // Unbind attachment - GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, attachmentType, TextureTarget.Texture2D, 0, 0); - - // Restore FBO and viewport - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (uint)viewports[0].Width, (uint)viewports[0].Height); - } - } - - internal unsafe void CopyScaler2D(Texture sourceTexture, Texture destTexture, Rectangle sourceRectangle, Rectangle destRectangle, bool flipY = false) - { - // Use rendering - GL.Viewport(0, 0, (uint)destTexture.Description.Width, (uint)destTexture.Description.Height); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.FindOrCreateFBO(destTexture)); - - var sourceRegionSize = new Vector2(sourceRectangle.Width, sourceRectangle.Height); - var destRegionSize = new Vector2(destRectangle.Width, destRectangle.Height); - - // Source - var sourceSize = new Vector2(sourceTexture.Width, sourceTexture.Height); - var sourceRegionLeftTop = new Vector2(sourceRectangle.Left, sourceRectangle.Top); - var sourceScale = new Vector2(sourceRegionSize.X / sourceSize.X, sourceRegionSize.Y / sourceSize.Y); - var sourceOffset = new Vector2(sourceRegionLeftTop.X / sourceSize.X, sourceRegionLeftTop.Y / sourceSize.Y); - - // Dest - var destSize = new Vector2(destTexture.Width, destTexture.Height); - var destRegionLeftTop = new Vector2(destRectangle.X, flipY ? destRectangle.Bottom : destRectangle.Y); - var destScale = new Vector2(destRegionSize.X / destSize.X, destRegionSize.Y / destSize.Y); - var destOffset = new Vector2(destRegionLeftTop.X / destSize.X, destRegionLeftTop.Y / destSize.Y); - - if (flipY) - destScale.Y = -destScale.Y; - - var enabledColors = new bool[4]; - GL.GetBoolean(GetPName.ColorWritemask, enabledColors); - var isDepthTestEnabled = GL.IsEnabled(EnableCap.DepthTest); - var isCullFaceEnabled = GL.IsEnabled(EnableCap.CullFace); - var isBlendEnabled = GL.IsEnabled(EnableCap.Blend); - var isStencilEnabled = GL.IsEnabled(EnableCap.StencilTest); - GL.Disable(EnableCap.DepthTest); - GL.Disable(EnableCap.CullFace); - GL.Disable(EnableCap.Blend); - GL.Disable(EnableCap.StencilTest); - GL.ColorMask(true, true, true, true); - - // TODO find a better way to detect if sRGB conversion is needed (need to detect if main frame buffer is sRGB or not at init time) -#if STRIDE_GRAPHICS_API_OPENGLES - // If we are copying from an SRgb texture to a non SRgb texture, we use a special SRGb copy shader - bool needSRgbConversion = sourceTexture.Description.Format.IsSRgb && destTexture == GraphicsDevice.WindowProvidedRenderTexture; -#else - bool needSRgbConversion = false; -#endif - int offsetLocation, scaleLocation; - var program = GraphicsDevice.GetCopyProgram(needSRgbConversion, out offsetLocation, out scaleLocation); - - GL.UseProgram(program); - - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, sourceTexture.TextureId); - boundShaderResourceViews[0] = null; - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - sourceTexture.BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp; - - vboDirty = true; - enabledVertexAttribArrays |= 1 << 0; - GL.EnableVertexAttribArray(0); - GL.BindBuffer(BufferTargetARB.ArrayBuffer, GraphicsDevice.GetSquareBuffer().BufferId); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, null); - GL.Uniform4(offsetLocation, sourceOffset.X, sourceOffset.Y, destOffset.X, destOffset.Y); - GL.Uniform4(scaleLocation, sourceScale.X, sourceScale.Y, destScale.X, destScale.Y); - GL.Viewport(0, 0, (uint)destTexture.Width, (uint)destTexture.Height); - GL.DrawArrays(PrimitiveTypeGl.TriangleStrip, 0, 4); - GL.UseProgram(boundProgram); - - // Restore context - if (isDepthTestEnabled) - GL.Enable(EnableCap.DepthTest); - if (isCullFaceEnabled) - GL.Enable(EnableCap.CullFace); - if (isBlendEnabled) - GL.Enable(EnableCap.Blend); - if (isStencilEnabled) - GL.Enable(EnableCap.StencilTest); - GL.ColorMask(enabledColors[0], enabledColors[1], enabledColors[2], enabledColors[3]); - - // Restore FBO and viewport - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (uint)viewports[0].Width, (uint)viewports[0].Height); - } - - internal unsafe void CopyScaler2D(Texture sourceTexture, Rectangle sourceRectangle, Rectangle destRectangle, bool needSRgbConversion = false, bool flipY = false) - { - // Use rendering - GL.Viewport(0, 0, (uint)sourceTexture.Description.Width, (uint)sourceTexture.Description.Height); - - var sourceRegionSize = new Vector2(sourceRectangle.Width, sourceRectangle.Height); - var destRegionSize = new Vector2(destRectangle.Width, destRectangle.Height); - - // Source - var sourceSize = new Vector2(sourceTexture.Width, sourceTexture.Height); - var sourceRegionLeftTop = new Vector2(sourceRectangle.Left, sourceRectangle.Top); - var sourceScale = new Vector2(sourceRegionSize.X / sourceSize.X, sourceRegionSize.Y / sourceSize.Y); - var sourceOffset = new Vector2(sourceRegionLeftTop.X / sourceSize.X, sourceRegionLeftTop.Y / sourceSize.Y); - - // Dest - var destSize = new Vector2(sourceTexture.Width, sourceTexture.Height); - var destRegionLeftTop = new Vector2(destRectangle.X, flipY ? destRectangle.Bottom : destRectangle.Y); - var destScale = new Vector2(destRegionSize.X / destSize.X, destRegionSize.Y / destSize.Y); - var destOffset = new Vector2(destRegionLeftTop.X / destSize.X, destRegionLeftTop.Y / destSize.Y); - - if (flipY) - destScale.Y = -destScale.Y; - - var enabledColors = new bool[4]; - GL.GetBoolean(GetPName.ColorWritemask, enabledColors); - var isDepthTestEnabled = GL.IsEnabled(EnableCap.DepthTest); - var isCullFaceEnabled = GL.IsEnabled(EnableCap.CullFace); - var isBlendEnabled = GL.IsEnabled(EnableCap.Blend); - var isStencilEnabled = GL.IsEnabled(EnableCap.StencilTest); - GL.Disable(EnableCap.DepthTest); - GL.Disable(EnableCap.CullFace); - GL.Disable(EnableCap.Blend); - GL.Disable(EnableCap.StencilTest); - GL.ColorMask(true, true, true, true); - - int offsetLocation, scaleLocation; - var program = GraphicsDevice.GetCopyProgram(needSRgbConversion, out offsetLocation, out scaleLocation); - - GL.UseProgram(program); - - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, sourceTexture.TextureId); - boundShaderResourceViews[0] = null; - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - sourceTexture.BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp; - - vboDirty = true; - enabledVertexAttribArrays |= 1 << 0; - GL.EnableVertexAttribArray(0); - GL.BindBuffer(BufferTargetARB.ArrayBuffer, GraphicsDevice.GetSquareBuffer().BufferId); - GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, null); - GL.Uniform4(offsetLocation, sourceOffset.X, sourceOffset.Y, destOffset.X, destOffset.Y); - GL.Uniform4(scaleLocation, sourceScale.X, sourceScale.Y, destScale.X, destScale.Y); - GL.Viewport(0, 0, (uint)sourceTexture.Width, (uint)sourceTexture.Height); - GL.DrawArrays(PrimitiveTypeGl.TriangleStrip, 0, 4); - GL.UseProgram(boundProgram); - - // Restore context - if (isDepthTestEnabled) - GL.Enable(EnableCap.DepthTest); - if (isCullFaceEnabled) - GL.Enable(EnableCap.CullFace); - if (isBlendEnabled) - GL.Enable(EnableCap.Blend); - if (isStencilEnabled) - GL.Enable(EnableCap.StencilTest); - GL.ColorMask(enabledColors[0], enabledColors[1], enabledColors[2], enabledColors[3]); - - // Restore viewport - GL.Viewport((int)viewports[0].X, (int)viewports[0].Y, (uint)viewports[0].Width, (uint)viewports[0].Height); - } - - /// - /// Copy a into another. - /// - /// The source from which to copy the data - /// The destination into which to copy the data - /// This might alter some states such as currently bound texture. - public void Copy(GraphicsResource source, GraphicsResource destination) - { - // Count subresources - var subresourceCount = 1; - var sourceTexture = source as Texture; - if (sourceTexture != null) - { - subresourceCount = sourceTexture.ArraySize * sourceTexture.MipLevelCount; - } - - // Copy each subresource - for (int i = 0; i < subresourceCount; ++i) - { - CopyRegion(source, i, null, destination, i); - } - } - - public void CopyMultisample(Texture sourceMultisampleTexture, int sourceSubResource, Texture destTexture, int destSubResource, PixelFormat format = PixelFormat.None) - { - // Check if the source and destination are compatible: - if (sourceMultisampleTexture.Width != destTexture.Width && - sourceMultisampleTexture.Height != destTexture.Height && - sourceMultisampleTexture.Format != destTexture.Format) // TODO: Blitting seems to be okay even if the sizes don't match, but only in case of non-MSAA buffers. - { - throw new InvalidOperationException("sourceMultisampleTexture and destTexture don't match in size and format!"); - } - - // Set up the read (source) buffer to use for the blitting operation: - var readFBOID = GraphicsDevice.FindOrCreateFBO(sourceMultisampleTexture); // Find the FBO that the sourceMultisampleTexture is bound to. - GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, readFBOID); - - // Set up the draw (destination) buffer to use for the blitting operation: - var drawFBOID = GraphicsDevice.FindOrCreateFBO(destTexture); // Find the FBO that the destTexture is bound to. - GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, drawFBOID); - - ClearBufferMask clearBufferMask; - BlitFramebufferFilter blitFramebufferFilter; - - // TODO: PERFORMANCE: We could copy the depth buffer AND color buffer at the same time by doing "ClearBufferMask.DepthBufferBit | ClearBufferMask.ColorBufferBit". - if (sourceMultisampleTexture.IsDepthBuffer && destTexture.IsDepthBuffer) - { - clearBufferMask = ClearBufferMask.DepthBufferBit; - blitFramebufferFilter = BlitFramebufferFilter.Nearest; // Must be set to nearest for depth buffers according to the spec: "GL_INVALID_OPERATION is generated if mask contains any of the GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and filter is not GL_NEAREST." - } - else - { - clearBufferMask = ClearBufferMask.ColorBufferBit; - blitFramebufferFilter = BlitFramebufferFilter.Linear; // TODO: STABILITY: For integer formats this has to be set to Nearest. - } - -#if !STRIDE_PLATFORM_IOS - // MSAA is not supported on iOS currently because OpenTK doesn't expose "GL.BlitFramebuffer()" on iOS for some reason. - // Do the actual blitting operation: - GL.BlitFramebuffer(0, 0, sourceMultisampleTexture.Width, sourceMultisampleTexture.Height, 0, 0, destTexture.Width, destTexture.Height, clearBufferMask, blitFramebufferFilter); -#endif - } - - public void CopyCount(Buffer sourceBuffer, Buffer destBuffer, int offsetToDest) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - throw new NotSupportedException(); - } - - public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if !STRIDE_GRAPHICS_API_OPENGLES - GL.DispatchCompute((uint)threadCountX, (uint)threadCountY, (uint)threadCountZ); -#else - throw new NotSupportedException(); -#endif - } - - public void Dispatch(Buffer indirectBuffer, int offsetInBytes) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if !STRIDE_GRAPHICS_API_OPENGLES - GL.BindBuffer(BufferTargetARB.DispatchIndirectBuffer, indirectBuffer.BufferId); - - GL.DispatchComputeIndirect((IntPtr)offsetInBytes); - - GL.BindBuffer(BufferTargetARB.DispatchIndirectBuffer, 0); -#else - throw new NotSupportedException(); -#endif - } - - public void Draw(int vertexCount, int startVertex = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - PreDraw(); - - GL.DrawArrays(newPipelineState.PrimitiveType, startVertex, (uint)vertexCount); - - GraphicsDevice.FrameTriangleCount += (uint)vertexCount; - GraphicsDevice.FrameDrawCalls++; - } - - public void DrawAuto(PrimitiveType primitiveType) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - PreDraw(); - - //GL.DrawArraysIndirect(newPipelineState.PrimitiveType, (IntPtr)0); - //GraphicsDevice.FrameDrawCalls++; - throw new NotSupportedException(); - } - - /// - /// Draw indexed, non-instanced primitives. - /// - /// Number of indices to draw. - /// The location of the first index read by the GPU from the index buffer. - /// A value added to each index before reading a vertex from the vertex buffer. - public unsafe void DrawIndexed(int indexCount, int startIndexLocation = 0, int baseVertexLocation = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - PreDraw(); - -#if STRIDE_GRAPHICS_API_OPENGLES - if (baseVertexLocation != 0) - throw new NotSupportedException("DrawIndexed with no null baseVertexLocation is not supported on OpenGL ES."); - GL.DrawElements(newPipelineState.PrimitiveType, (uint)indexCount, indexBuffer.Type, (void*)(indexBuffer.Offset + (startIndexLocation * indexBuffer.ElementSize))); -#else - GL.DrawElementsBaseVertex(newPipelineState.PrimitiveType, (uint)indexCount, indexBuffer.Type, (void*)(indexBuffer.Offset + (startIndexLocation * indexBuffer.ElementSize)), baseVertexLocation); -#endif - - GraphicsDevice.FrameDrawCalls++; - GraphicsDevice.FrameTriangleCount += (uint)indexCount; - } - - /// - /// Draw indexed, instanced primitives. - /// - /// Number of indices read from the index buffer for each instance. - /// Number of instances to draw. - /// The location of the first index read by the GPU from the index buffer. - /// A value added to each index before reading a vertex from the vertex buffer. - /// A value added to each index before reading per-instance data from a vertex buffer. - public unsafe void DrawIndexedInstanced(int indexCountPerInstance, int instanceCount, int startIndexLocation = 0, int baseVertexLocation = 0, int startInstanceLocation = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - PreDraw(); -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - GL.DrawElementsInstancedBaseVertex(newPipelineState.PrimitiveType, (uint)indexCountPerInstance, indexBuffer.Type, (void*)(indexBuffer.Offset + (startIndexLocation * indexBuffer.ElementSize)), (uint)instanceCount, baseVertexLocation); -#endif - - GraphicsDevice.FrameDrawCalls++; - GraphicsDevice.FrameTriangleCount += (uint)(indexCountPerInstance * instanceCount); - } - - /// - /// Draw indexed, instanced, GPU-generated primitives. - /// - /// A buffer containing the GPU generated primitives. - /// Offset in pBufferForArgs to the start of the GPU generated primitives. - public void DrawIndexedInstanced(Buffer argumentsBuffer, int alignedByteOffsetForArgs = 0) - { - - if (argumentsBuffer == null) throw new ArgumentNullException(nameof(argumentsBuffer)); - -#if DEBUG - //GraphicsDevice.EnsureContextActive(); -#endif - //PreDraw(); - - //GraphicsDevice.FrameDrawCalls++; - - throw new NotSupportedException(); - } - - /// - /// Draw non-indexed, instanced primitives. - /// - /// Number of vertices to draw. - /// Number of instances to draw. - /// Index of the first vertex. - /// A value added to each index before reading per-instance data from a vertex buffer. - public void DrawInstanced(int vertexCountPerInstance, int instanceCount, int startVertexLocation = 0, int startInstanceLocation = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - PreDraw(); - - GL.DrawArraysInstanced(newPipelineState.PrimitiveType, startVertexLocation, (uint)vertexCountPerInstance, (uint)instanceCount); - - GraphicsDevice.FrameDrawCalls++; - GraphicsDevice.FrameTriangleCount += (uint)(vertexCountPerInstance * instanceCount); - } - - /// - /// Draw instanced, GPU-generated primitives. - /// - /// An arguments buffer - /// Offset in pBufferForArgs to the start of the GPU generated primitives. - public void DrawInstanced(Buffer argumentsBuffer, int alignedByteOffsetForArgs = 0) - { - if (argumentsBuffer == null) - throw new ArgumentNullException(nameof(argumentsBuffer)); - -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - PreDraw(); - -#if STRIDE_GRAPHICS_API_OPENGLES - GraphicsDevice.FrameDrawCalls++; - throw new NotSupportedException(); -#else - GL.BindBuffer(BufferTargetARB.DrawIndirectBuffer, argumentsBuffer.BufferId); - - GL.DrawArraysIndirect(newPipelineState.PrimitiveType, (IntPtr)alignedByteOffsetForArgs); - - GL.BindBuffer(BufferTargetARB.DrawIndirectBuffer, 0); - - GraphicsDevice.FrameDrawCalls++; -#endif - } - - public void BeginProfile(Color4 profileColor, string name) - { - if (GraphicsDevice.ProfileEnabled) - { - GL.PushDebugGroup(DebugSource.DebugSourceApplication, 1, uint.MaxValue, name); - } - } - - public void EndProfile() - { - if (GraphicsDevice.ProfileEnabled) - { - GL.PopDebugGroup(); - } - } - - /// - /// Submit a timestamp query. - /// - /// The QueryPool owning the query. - /// The query index. - public void WriteTimestamp(QueryPool queryPool, int index) - { -#if STRIDE_GRAPHICS_API_OPENGLES - GraphicsDevice.GLExtDisjointTimerQuery.QueryCounter(queryPool.NativeQueries[index], QueryCounterTarget.Timestamp); -#else - GL.QueryCounter(queryPool.NativeQueries[index], QueryCounterTarget.Timestamp); -#endif - } - - public void ResetQueryPool(QueryPool queryPool) - { - } - - public unsafe partial MappedResource MapSubResource(GraphicsResource resource, int subResourceIndex, MapMode mapMode, bool doNotWait = false, int offsetInBytes = 0, int lengthInBytes = 0) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - // This resource has just been recycled by the GraphicsResourceAllocator, we force a rename to avoid GPU=>GPU sync point - if (resource.DiscardNextMap && mapMode == MapMode.WriteNoOverwrite) - mapMode = MapMode.WriteDiscard; - - - if (resource is Buffer buffer) - { - if (lengthInBytes == 0) - lengthInBytes = buffer.Description.SizeInBytes; - - IntPtr mapResult = IntPtr.Zero; - - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - - // Orphan the buffer (let driver knows we don't need it anymore) - if (mapMode == MapMode.WriteDiscard) - { - doNotWait = true; - GL.BufferData(buffer.BufferTarget, (uint)buffer.Description.SizeInBytes, null, buffer.BufferUsageHint); - } - - var unsynchronized = doNotWait && mapMode != MapMode.Read && mapMode != MapMode.ReadWrite; - - mapResult = (IntPtr)GL.MapBufferRange(buffer.BufferTarget, offsetInBytes, (UIntPtr)lengthInBytes, mapMode.ToOpenGLMask() | (unsynchronized ? MapBufferAccessMask.UnsynchronizedBit : 0)); - - return new MappedResource(resource, subResourceIndex, new DataBox { DataPointer = mapResult, SlicePitch = 0, RowPitch = 0 }); - } - - if (resource is Texture texture) - { - if (lengthInBytes == 0) - lengthInBytes = texture.ComputeSubResourceSize(subResourceIndex); - - if (mapMode == MapMode.Read) - { - if (texture.Description.Usage != GraphicsResourceUsage.Staging) - throw new NotSupportedException("Only staging textures can be mapped."); - - var mipLevel = subResourceIndex % texture.MipLevelCount; - - if (doNotWait) - { - // Wait at least 2 frames after last operation - if (GraphicsDevice.FrameCounter < texture.PixelBufferFrame + ReadbackFrameDelay) - { - return new MappedResource(resource, subResourceIndex, new DataBox(), offsetInBytes, lengthInBytes); - } - } - - return MapTexture(texture, true, BufferTargetARB.PixelPackBuffer, texture.PixelBufferObjectId, subResourceIndex, mapMode, offsetInBytes, lengthInBytes); - } - else if (mapMode == MapMode.WriteDiscard) - { - if (texture.Description.Usage != GraphicsResourceUsage.Dynamic) - throw new NotSupportedException("Only dynamic texture can be mapped."); - - // Create a temporary unpack pixel buffer - // TODO: Pool/allocator? (it's an upload buffer basically) - var pixelBufferObjectId = texture.GeneratePixelBufferObject(BufferTargetARB.PixelUnpackBuffer, PixelStoreParameter.UnpackAlignment, BufferUsageARB.DynamicCopy, texture.ComputeSubResourceSize(subResourceIndex)); - - return MapTexture(texture, false, BufferTargetARB.PixelUnpackBuffer, pixelBufferObjectId, subResourceIndex, mapMode, offsetInBytes, lengthInBytes); - } - } - - throw new NotSupportedException("MapSubResource not implemented for type " + resource.GetType()); - } - - public unsafe partial void UnmapSubResource(MappedResource unmapped) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - var texture = unmapped.Resource as Texture; - if (texture != null) - { - if (texture.Description.Usage == GraphicsResourceUsage.Staging) - { - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, texture.PixelBufferObjectId); - GL.UnmapBuffer(BufferTargetARB.PixelPackBuffer); - GL.BindBuffer(BufferTargetARB.PixelPackBuffer, 0); - } - else if (texture.Description.Usage == GraphicsResourceUsage.Dynamic) - { - GL.BindBuffer(BufferTargetARB.PixelUnpackBuffer, unmapped.PixelBufferObjectId); - GL.UnmapBuffer(BufferTargetARB.PixelUnpackBuffer); - - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - GL.BindTexture(texture.TextureTarget, texture.TextureId); - - var mipLevel = unmapped.SubResourceIndex % texture.MipLevelCount; - var arraySlice = unmapped.SubResourceIndex / texture.MipLevelCount; - - // Bind buffer to texture - switch (texture.TextureTarget) - { -#if !STRIDE_GRAPHICS_API_OPENGLES - case TextureTarget.Texture1D: - GL.TexSubImage1D(TextureTarget.Texture1D, mipLevel, 0, (uint)texture.Width, texture.TextureFormat, texture.TextureType, IntPtr.Zero); - break; -#endif - case TextureTarget.Texture2D: - GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel, 0, 0, (uint)texture.Width, (uint)texture.Height, texture.TextureFormat, texture.TextureType, IntPtr.Zero); - break; - case TextureTarget.Texture2DArray: - GL.TexSubImage3D(TextureTarget.Texture2DArray, mipLevel, 0, 0, arraySlice, (uint)texture.Width, (uint)texture.Height, 1, texture.TextureFormat, texture.TextureType, IntPtr.Zero); - break; - case TextureTarget.Texture3D: - GL.TexSubImage3D(TextureTarget.Texture3D, mipLevel, 0, 0, 0, (uint)texture.Width, (uint)texture.Height, (uint)texture.Depth, texture.TextureFormat, texture.TextureType, IntPtr.Zero); - break; - case TextureTarget.TextureCubeMap: - GL.TexSubImage2D(Texture.GetTextureTargetForDataSet2D(texture.TextureTarget, arraySlice), mipLevel, 0, 0, (uint)texture.Width, (uint)texture.Height, texture.TextureFormat, texture.TextureType, IntPtr.Zero); - break; - default: - throw new NotSupportedException("Invalid texture target: " + texture.TextureTarget); - } - GL.BindTexture(texture.TextureTarget, 0); - boundShaderResourceViews[0] = null; - GL.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0); - GL.DeleteBuffer(unmapped.PixelBufferObjectId); - } - else - { - throw new NotSupportedException("Not supported mapper operation for Usage: " + texture.Description.Usage); - } - } - else - { - var buffer = unmapped.Resource as Buffer; - if (buffer != null) - { - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - GL.UnmapBuffer(buffer.BufferTarget); - } - else // neither texture nor buffer - { - throw new NotImplementedException("UnmapSubResource not implemented for type " + unmapped.Resource.GetType()); - } - } - } - - private unsafe MappedResource MapTexture(Texture texture, bool adjustOffsetForSubResource, BufferTargetARB bufferTarget, uint pixelBufferObjectId, int subResourceIndex, MapMode mapMode, int offsetInBytes, int lengthInBytes) - { - int mipLevel = subResourceIndex % texture.MipLevelCount; - - GL.BindBuffer(bufferTarget, pixelBufferObjectId); - var mapResult = (IntPtr)GL.MapBufferRange(bufferTarget, (IntPtr)offsetInBytes + (adjustOffsetForSubResource ? texture.ComputeBufferOffset(subResourceIndex, 0) : 0), (UIntPtr)lengthInBytes, mapMode.ToOpenGLMask()); - GL.BindBuffer(bufferTarget, 0); - - return new MappedResource(texture, subResourceIndex, new DataBox { DataPointer = mapResult, SlicePitch = texture.ComputeSlicePitch(mipLevel), RowPitch = texture.ComputeRowPitch(mipLevel) }, offsetInBytes, lengthInBytes) - { - PixelBufferObjectId = pixelBufferObjectId - }; - } - - internal unsafe void PreDraw() - { - // Bind program - var program = newPipelineState.EffectProgram.ProgramId; - if (program != boundProgram) - { - boundProgram = program; - GL.UseProgram(boundProgram); - } - - int vertexBufferSlot = -1; - var vertexBufferView = default(VertexBufferView); - Buffer vertexBuffer = null; - - // TODO OPENGL compare newPipelineState.VertexAttribs directly - if (newPipelineState.VertexAttribs != currentPipelineState.VertexAttribs) - { - vboDirty = true; - } - - // Setup vertex buffers and vertex attributes - if (vboDirty) - { - foreach (var vertexAttrib in newPipelineState.VertexAttribs) - { - if (vertexAttrib.VertexBufferSlot != vertexBufferSlot) - { - vertexBufferSlot = vertexAttrib.VertexBufferSlot; - vertexBufferView = vertexBuffers[vertexBufferSlot]; - vertexBuffer = vertexBufferView.Buffer; - if (vertexBuffer != null) - { - var vertexBufferResource = vertexBufferView.Buffer.BufferId; - GL.BindBuffer(BufferTargetARB.ArrayBuffer, vertexBufferResource); - } - } - - var vertexAttribMask = 1U << vertexAttrib.AttributeIndex; - - // A stride of zero causes automatic stride calculation. To not use the attribute, unbind it in that case - if (vertexBuffer == null || vertexBufferView.Stride == 0) - { - // No VB bound, turn off this attribute - if ((enabledVertexAttribArrays & vertexAttribMask) != 0) - { - enabledVertexAttribArrays &= ~vertexAttribMask; - GL.DisableVertexAttribArray((uint)vertexAttrib.AttributeIndex); - } - continue; - } - - // Enable this attribute if not previously enabled - if ((enabledVertexAttribArrays & vertexAttribMask) == 0) - { - enabledVertexAttribArrays |= vertexAttribMask; - GL.EnableVertexAttribArray((uint)vertexAttrib.AttributeIndex); - } - - if (vertexAttrib.IsInteger && !vertexAttrib.Normalized) - GL.VertexAttribIPointer((uint)vertexAttrib.AttributeIndex, vertexAttrib.Size, (VertexAttribIType)vertexAttrib.Type, (uint)vertexBufferView.Stride, (void*)(vertexBufferView.Offset + vertexAttrib.Offset)); - else - GL.VertexAttribPointer((uint)vertexAttrib.AttributeIndex, vertexAttrib.Size, vertexAttrib.Type, vertexAttrib.Normalized, (uint)vertexBufferView.Stride, (void*)(vertexBufferView.Offset + vertexAttrib.Offset)); - } - - vboDirty = false; - } - - // Resources - newPipelineState.ResourceBinder.BindResources(this, currentDescriptorSets); - - // States - newPipelineState.Apply(this, currentPipelineState); - - foreach (var textureInfo in newPipelineState.EffectProgram.Textures) - { - var boundTexture = boundShaderResourceViews[textureInfo.TextureUnit]; - var shaderResourceView = shaderResourceViews[textureInfo.TextureUnit]; - if (shaderResourceView != null) - { - var texture = shaderResourceView as Texture; - var boundSamplerState = texture?.BoundSamplerState ?? GraphicsDevice.DefaultSamplerState; - var samplerState = samplerStates[textureInfo.TextureUnit] ?? GraphicsDevice.SamplerStates.LinearClamp; - - bool textureChanged = shaderResourceView != boundTexture; - bool samplerStateChanged = texture != null && samplerState != boundSamplerState; - - if (textureChanged || samplerStateChanged) - { - if (activeTexture != textureInfo.TextureUnit) - { - activeTexture = textureInfo.TextureUnit; - GL.ActiveTexture(TextureUnit.Texture0 + textureInfo.TextureUnit); - } - - // Lazy update for texture - if (textureChanged) - { - boundShaderResourceViews[textureInfo.TextureUnit] = shaderResourceView; - GL.BindTexture(shaderResourceView.TextureTarget, shaderResourceView.TextureId); - } - - // Lazy update for sampler state - if (samplerStateChanged && texture != null) - { - // TODO: Include hasMipmap in samplerStateChanged - bool hasMipmap = texture.Description.MipLevelCount > 1; - - samplerState.Apply(hasMipmap, boundSamplerState, texture.TextureTarget); - texture.BoundSamplerState = samplerState; - } - } - } - } - - // Update viewports - SetViewportImpl(); - - currentPipelineState = newPipelineState; - } - - /// - /// Sets a constant buffer to the shader pipeline. - /// - /// The shader stage. - /// The binding slot. - /// The constant buffer to set. - internal void SetConstantBuffer(ShaderStage stage, int slot, Buffer buffer) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - if (constantBuffers[slot] != buffer) - { - // TODO OPENGL if OpenGL ES 2, might be good to have some dirty flags to explain if cbuffer changed - constantBuffers[slot] = buffer; - GL.BindBufferBase(BufferTargetARB.UniformBuffer, (uint)slot, buffer != null ? buffer.BufferId : 0); - } - } - - private partial void SetRenderTargetsImpl(Texture depthStencilView, ReadOnlySpan renderTargetViews) - { - int numRenderTargets = renderTargetViews.Length; - - if (numRenderTargets > 0) - { - // Ensure size is coherent - var expectedWidth = renderTargetViews[0].Width; - var expectedHeight = renderTargetViews[0].Height; - - if (depthStencilBuffer is not null) - { - if (expectedWidth != depthStencilBuffer.Width || expectedHeight != depthStencilBuffer.Height) - throw new Exception("Depth buffer is not the same size as the render target"); - } - for (int i = 1; i < numRenderTargets; ++i) - { - if (renderTargetViews[i] != null && (expectedWidth != renderTargetViews[i].Width || expectedHeight != renderTargetViews[i].Height)) - throw new Exception("Render targets do not have the same size"); - } - } - -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - boundRenderTargetCount = numRenderTargets; - for (int i = 0; i < numRenderTargets; ++i) - boundRenderTargets[i] = renderTargetViews[i]; - - boundDepthStencilBuffer = depthStencilBuffer; - - needUpdateFBO = true; - - SetupTargets(); - } - - private void ResetTargetsImpl() - { - boundRenderTargetCount = 0; - } - - /// - /// Sets a sampler state to the shader pipeline. - /// - /// The shader stage. - /// The binding slot. - /// The sampler state to set. - public void SetSamplerState(ShaderStage stage, int slot, SamplerState samplerState) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - samplerStates[slot] = samplerState; - } - - private unsafe partial void SetScissorRectangleImpl(ref readonly Rectangle scissorRectangle) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - GL.Scissor(scissorRectangle.Left, scissorRectangle.Top, (uint)scissorRectangle.Width, (uint)scissorRectangle.Height); - } - - private unsafe partial void SetScissorRectanglesImpl(ReadOnlySpan scissorRectangles) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException(); -#else - uint scissorCount = (uint) scissorRectangles.Length; - - for (int i = 0; i < scissorCount; ++i) - { - scoped ref readonly Rectangle scissorRect = ref scissorRectangles[i]; - nativeScissorRectangles[4 * i] = scissorRect.X; - nativeScissorRectangles[4 * i + 1] = scissorRect.Y; - nativeScissorRectangles[4 * i + 2] = scissorRect.Width; - nativeScissorRectangles[4 * i + 3] = scissorRect.Height; - } - - GL.ScissorArray(first: 0, scissorCount, nativeScissorRectangles); -#endif - } - - /// - /// Sets a shader resource view to the shader pipeline. - /// - /// The shader stage. - /// The binding slot. - /// The shader resource view. - internal void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResource shaderResourceView) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - shaderResourceViews[slot] = shaderResourceView; - } - - /// - public void SetStreamTargets(params Buffer[] buffers) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - throw new NotSupportedException(); - } - - /// - /// Sets an unordered access view to the shader pipeline. - /// - /// The stage. - /// The slot. - /// The unordered access view. - /// The Append/Consume buffer offset. A value of -1 indicates the current offset - /// should be kept. Any other values set the hidden counter for that Appendable/Consumable - /// UAV. uavInitialCount is only relevant for UAVs which have the 'Append' or 'Counter' buffer - /// flag, otherwise the argument is ignored. - /// Invalid stage.;stage - internal void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView, int uavInitialOffset) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - if (stage != ShaderStage.Compute) - throw new ArgumentException("Invalid stage.", nameof(stage)); - - throw new NotSupportedException(); - } - - /// - /// Unsets an unordered access view from the shader pipeline. - /// - /// The unordered access view. - internal void UnsetUnorderedAccessView(GraphicsResource unorderedAccessView) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - //throw new NotImplementedException(); - } - - internal void SetupTargets() - { - if (needUpdateFBO) - { - boundFBO = GraphicsDevice.FindOrCreateFBO(boundDepthStencilBuffer, boundRenderTargets, boundRenderTargetCount); - } - GL.BindFramebuffer(FramebufferTarget.Framebuffer, boundFBO); - } - - public void SetPipelineState(PipelineState pipelineState) - { - newPipelineState = pipelineState ?? GraphicsDevice.DefaultPipelineState; - } - - public void SetVertexBuffer(int index, Buffer buffer, int offset, int stride) - { - var newVertexBuffer = new VertexBufferView(buffer, offset, stride); - if (vertexBuffers[index] != newVertexBuffer) - { - vboDirty = true; - vertexBuffers[index] = newVertexBuffer; - } - } - - public void SetIndexBuffer(Buffer buffer, int offset, bool is32bits) - { - var newIndexBuffer = new IndexBufferView(buffer, offset, is32bits); - if (indexBuffer != newIndexBuffer) - { - // Setup index buffer - indexBuffer = newIndexBuffer; - - // Setup index buffer - GL.BindBuffer(BufferTargetARB.ElementArrayBuffer, indexBuffer.Buffer != null ? indexBuffer.Buffer.BufferId : 0); - } - } - - public void ResourceBarrierTransition(GraphicsResource resource, GraphicsResourceState newState) - { - // Nothing to do - } - - public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets) - { - for (int i = 0; i < descriptorSets.Length; ++i) - { - currentDescriptorSets[index++] = descriptorSets[i]; - } - } - - public void SetStencilReference(int stencilReference) - { - NewStencilReference = stencilReference; - } - - public void SetBlendFactor(Color4 blendFactor) - { - NewBlendFactor = blendFactor; - } - - private void SetViewportImpl() - { - if (!viewportDirty) - return; - - viewportDirty = false; - -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - // TODO: Check all non-empty viewports are identical and match what is active in FBO! - UpdateViewport(viewports[0]); -#else - UpdateViewports(); -#endif - } - - private void UpdateViewport(Viewport viewport) - { - GL.DepthRange(viewport.MinDepth, viewport.MaxDepth); - GL.Viewport((int)viewport.X, (int)viewport.Y, (uint)viewport.Width, (uint)viewport.Height); - } - -#if !STRIDE_GRAPHICS_API_OPENGLES - private void UpdateViewports() - { - int nbViewports = viewports.Length; - for (int i = 0; i < boundViewportCount; ++i) - { - var currViewport = viewports[i]; - nativeViewports[4 * i] = currViewport.X; - nativeViewports[4 * i + 1] = currViewport.Y; - nativeViewports[4 * i + 2] = currViewport.Width; - nativeViewports[4 * i + 3] = currViewport.Height; - } - GL.DepthRange(viewports[0].MinDepth, viewports[0].MaxDepth); - GL.ViewportArray(0, (uint)boundViewportCount, nativeViewports); - } -#endif - - public void UnsetReadWriteBuffers() - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - } - - public void UnsetRenderTargets() - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - - SetRenderTargets([]); - } - - /// - /// Copies data from memory to a sub-resource created in non-mappable memory. - /// - /// The destination Graphics Resource to copy data to. - /// The sub-resource index of to copy data to. - /// The source data in CPU memory to copy. - /// is . - /// - /// - /// If is a Constant Buffer, it must be updated in full. - /// It is not possible to use this method to partially update a Constant Buffer. - /// - /// - /// A Graphics Resource cannot be used as a destination if: - /// - /// The resource was created with or . - /// The resource was created as a Depth-Stencil Buffer. - /// The resource is a Texture created with multi-sampling capability (see ). - /// - /// - /// - /// When returns, the application is free to change or even free the data pointed to by - /// because the method has already copied/snapped away the original contents. - /// - /// - internal unsafe void UpdateSubResource(GraphicsResource resource, int subResourceIndex, ReadOnlySpan sourceData) - { - ArgumentNullException.ThrowIfNull(resource); - - if (sourceData.IsEmpty) - return; - - fixed (byte* sourceDataPtr = sourceData) - { - UpdateSubResource(resource, subResourceIndex, new DataBox((nint) sourceDataPtr, sourceData.Length, 0)); - } - } - - internal unsafe void UpdateSubResource(GraphicsResource resource, int subResourceIndex, DataBox databox) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - var buffer = resource as Buffer; - if (buffer != null) - { - if (!GraphicsDevice.HasTextureBuffers && buffer.BufferId == 0) - { - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - // On platforms where it's not supported, we use a texture instead of a buffer - GL.BindTexture(buffer.TextureTarget, buffer.TextureId); - boundShaderResourceViews[0] = null; // bound active texture 0 has changed - - buffer.UpdateTextureSubResource(databox.DataPointer, 0, 0, buffer.ElementCount); - } - else - { - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - GL.BufferData(buffer.BufferTarget, (uint)buffer.Description.SizeInBytes, (void*)databox.DataPointer, buffer.BufferUsageHint); - } - } - else - { - var texture = resource as Texture; - if (texture != null) - { - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - // TODO: Handle pitchs - // TODO: handle other texture formats - GL.BindTexture(texture.TextureTarget, texture.TextureId); - boundShaderResourceViews[0] = null; // bound active texture 0 has changed - - var desc = texture.Description; - var mipLevel = subResourceIndex % texture.MipLevelCount; - var arraySlice = subResourceIndex / texture.MipLevelCount; - switch (texture.TextureTarget) - { -#if !STRIDE_GRAPHICS_API_OPENGLES - case TextureTarget.Texture1D: - GL.TexSubImage1D(TextureTarget.Texture1D, mipLevel, 0, (uint)desc.Width, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - break; -#endif - case TextureTarget.Texture2D: - GL.TexSubImage2D(TextureTarget.Texture2D, mipLevel, 0, 0, (uint)desc.Width, (uint)desc.Height, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - break; - case TextureTarget.Texture2DArray: - GL.TexSubImage3D(TextureTarget.Texture2DArray, mipLevel, 0, 0, arraySlice, (uint)desc.Width, (uint)desc.Height, 1, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - break; - case TextureTarget.Texture3D: - GL.TexSubImage3D(TextureTarget.Texture3D, mipLevel, 0, 0, 0, (uint)desc.Width, (uint)desc.Height, (uint)desc.Depth, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - break; - case TextureTarget.TextureCubeMap: - GL.TexSubImage2D(Texture.GetTextureTargetForDataSet2D(texture.TextureTarget, arraySlice), mipLevel, 0, 0, (uint)desc.Width, (uint)desc.Height, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - break; - default: - throw new NotImplementedException("UpdateSubResource not implemented for texture target " + texture.TextureTarget); - break; - } - } - else // neither texture nor buffer - { - throw new NotImplementedException("UpdateSubResource not implemented for type " + resource.GetType()); - } - } - } - - /// - /// Copies data from memory to a sub-resource created in non-mappable memory. - /// - /// The destination Graphics Resource to copy data to. - /// The sub-resource index of to copy data to. - /// The source data in CPU memory to copy. - /// - /// - /// A that defines the portion of the destination sub-resource to copy the resource data into. - /// Coordinates are in bytes for Buffers and in texels for Textures. - /// The dimensions of the source must fit the destination. - /// - /// - /// An empty region makes this method to not perform a copy operation. - /// It is considered empty if the top value is greater than or equal to the bottom value, - /// or the left value is greater than or equal to the right value, or the front value is greater than or equal to the back value. - /// - /// - /// is . - /// - internal unsafe void UpdateSubResource(GraphicsResource resource, int subResourceIndex, ReadOnlySpan sourceData, ResourceRegion region) - { - ArgumentNullException.ThrowIfNull(resource); - - if (sourceData.IsEmpty) - return; - - fixed (byte* sourceDataPtr = sourceData) - { - UpdateSubResource(resource, subResourceIndex, new DataBox((nint)sourceDataPtr, sourceData.Length, 0), region); - } - } - - internal unsafe partial void UpdateSubResource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region) - { -#if DEBUG - GraphicsDevice.EnsureContextActive(); -#endif - var texture = resource as Texture; - - if (texture != null) - { - var width = region.Right - region.Left; - var height = region.Bottom - region.Top; - var depth = region.Back - region.Front; - - var expectedRowPitch = width * texture.TexturePixelSize; - - // determine the opengl read Unpack Alignment - var packAlignment = 0; - if ((databox.RowPitch & 1) != 0) - { - if (databox.RowPitch == expectedRowPitch) - packAlignment = 1; - } - else if ((databox.RowPitch & 2) != 0) - { - var diff = databox.RowPitch - expectedRowPitch; - if (diff >= 0 && diff < 2) - packAlignment = 2; - } - else if ((databox.RowPitch & 4) != 0) - { - var diff = databox.RowPitch - expectedRowPitch; - if (diff >= 0 && diff < 4) - packAlignment = 4; - } - else if ((databox.RowPitch & 8) != 0) - { - var diff = databox.RowPitch - expectedRowPitch; - if (diff >= 0 && diff < 8) - packAlignment = 8; - } - else if (databox.RowPitch == expectedRowPitch) - { - packAlignment = 4; - } - if (packAlignment == 0) - throw new NotSupportedException("The data box RowPitch is not compatible with the region width. This requires additional copy to be implemented."); - - // change the Unpack Alignment - int previousPackAlignment; - GL.GetInteger(GetPName.UnpackAlignment, out previousPackAlignment); - GL.PixelStore(PixelStoreParameter.UnpackAlignment, packAlignment); - - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - // Update the texture region - GL.BindTexture(texture.TextureTarget, texture.TextureId); - if (texture.Dimension == TextureDimension.Texture3D) - GL.TexSubImage3D(texture.TextureTarget, subResourceIndex, region.Left, region.Top, region.Front, (uint)width, (uint)height, (uint)depth, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - else - GL.TexSubImage2D(texture.TextureTarget, subResourceIndex, region.Left, region.Top, (uint)width, (uint)height, texture.TextureFormat, texture.TextureType, (void*)databox.DataPointer); - boundShaderResourceViews[0] = null; // bound active texture 0 has changed - - // reset the Unpack Alignment - GL.PixelStore(PixelStoreParameter.UnpackAlignment, previousPackAlignment); - } - else - { - var buffer = resource as Buffer; - if (buffer != null) - { - if (!GraphicsDevice.HasTextureBuffers && buffer.BufferId == 0) - { - if (activeTexture != 0) - { - activeTexture = 0; - GL.ActiveTexture(TextureUnit.Texture0); - } - - // On platforms where it's not supported, we use a texture instead of a buffer - GL.BindTexture(buffer.TextureTarget, buffer.TextureId); - boundShaderResourceViews[0] = null; // bound active texture 0 has changed - - buffer.UpdateTextureSubResource(databox.DataPointer, 0, region.Left, region.Right - region.Left); - } - else - { - GL.BindBuffer(buffer.BufferTarget, buffer.BufferId); - if (region.Left == 0 && region.Right == buffer.SizeInBytes) - GL.BufferData(buffer.BufferTarget, (UIntPtr)region.Right, (void*)databox.DataPointer, buffer.BufferUsageHint); - else - GL.BufferSubData(buffer.BufferTarget, (IntPtr)region.Left, (UIntPtr)(region.Right - region.Left), (void*)databox.DataPointer); - GL.BindBuffer(buffer.BufferTarget, 0); - } - } - } - } - - struct VertexBufferView - { - public readonly Buffer Buffer; - public readonly int Offset; - public readonly int Stride; - - public VertexBufferView(Buffer buffer, int offset, int stride) - { - Buffer = buffer; - Offset = offset; - Stride = stride; - } - - public static bool operator ==(VertexBufferView left, VertexBufferView right) - { - return Equals(left.Buffer, right.Buffer) && left.Offset == right.Offset && left.Stride == right.Stride; - } - - public static bool operator !=(VertexBufferView left, VertexBufferView right) - { - return !(left == right); - } - - public override bool Equals(object other) - { - if (other is VertexBufferView) - { - VertexBufferView p = (VertexBufferView) other; - return Equals(Buffer, p.Buffer) && Offset == p.Offset && Stride == p.Stride; - } - else - { - return false; - } - } - - public override int GetHashCode() - { - int result = Buffer.GetHashCode(); - result = (result * 397) ^ Offset; - result = (result * 397) ^ Stride; - return result; - } - } - - struct IndexBufferView - { - public readonly Buffer Buffer; - public readonly int Offset; - public readonly DrawElementsType Type; - public readonly int ElementSize; - - public IndexBufferView(Buffer buffer, int offset, bool is32Bits) - { - Buffer = buffer; - Offset = offset; - Type = is32Bits ? DrawElementsType.UnsignedInt : DrawElementsType.UnsignedShort; - ElementSize = is32Bits ? 4 : 2; - } - - public static bool operator ==(IndexBufferView left, IndexBufferView right) - { - return Equals(left.Buffer, right.Buffer) && left.Offset == right.Offset && left.Type == right.Type && left.ElementSize == right.ElementSize; - } - - public static bool operator !=(IndexBufferView left, IndexBufferView right) - { - return !(left == right); - } - - public override bool Equals(object other) - { - if (other is IndexBufferView) - { - IndexBufferView p = (IndexBufferView)other; - return Equals(Buffer, p.Buffer) && Offset == p.Offset && Type == p.Type && ElementSize == p.ElementSize; - } - else - { - return false; - } - } - - public override int GetHashCode() - { - int result = Buffer.GetHashCode(); - result = (result * 397) ^ Offset; - result = (result * 397) ^ Type.GetHashCode(); - result = (result * 397) ^ ElementSize; - return result; - } - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/DepthStencilState.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/DepthStencilState.OpenGL.cs deleted file mode 100644 index 9382f238f7..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/DepthStencilState.OpenGL.cs +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - struct DepthStencilBoundState - { - // Depth - public bool DepthBufferEnable; - public bool DepthBufferWriteEnable; - public DepthFunction DepthFunction; - - // Stencil - public bool StencilEnable; - public byte StencilWriteMask; - public byte StencilMask; - - public StencilFaceState Faces; - } - - struct StencilFaceState - { - public StencilFunction FrontFaceStencilFunction; - public StencilOp FrontFaceDepthFailOp; - public StencilOp FrontFaceFailOp; - public StencilOp FrontFacePassOp; - - public StencilFunction BackFaceStencilFunction; - public StencilOp BackFaceDepthFailOp; - public StencilOp BackFaceFailOp; - public StencilOp BackFacePassOp; - - public bool Equals(StencilFaceState other) - { - return FrontFaceStencilFunction == other.FrontFaceStencilFunction && FrontFaceDepthFailOp == other.FrontFaceDepthFailOp && FrontFaceFailOp == other.FrontFaceFailOp && FrontFacePassOp == other.FrontFacePassOp && BackFaceStencilFunction == other.BackFaceStencilFunction && BackFaceDepthFailOp == other.BackFaceDepthFailOp && BackFaceFailOp == other.BackFaceFailOp && BackFacePassOp == other.BackFacePassOp; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is StencilFaceState && Equals((StencilFaceState)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = (int)FrontFaceStencilFunction; - hashCode = (hashCode * 397) ^ (int)FrontFaceDepthFailOp; - hashCode = (hashCode * 397) ^ (int)FrontFaceFailOp; - hashCode = (hashCode * 397) ^ (int)FrontFacePassOp; - hashCode = (hashCode * 397) ^ (int)BackFaceStencilFunction; - hashCode = (hashCode * 397) ^ (int)BackFaceDepthFailOp; - hashCode = (hashCode * 397) ^ (int)BackFaceFailOp; - hashCode = (hashCode * 397) ^ (int)BackFacePassOp; - return hashCode; - } - } - - public static bool operator ==(StencilFaceState left, StencilFaceState right) - { - return left.Equals(right); - } - - public static bool operator !=(StencilFaceState left, StencilFaceState right) - { - return !left.Equals(right); - } - } - - public class DepthStencilState - { - DepthStencilBoundState state; - - internal DepthStencilState(DepthStencilStateDescription depthStencilStateDescription, bool hasDepthStencilBuffer) - { - state.DepthBufferEnable = depthStencilStateDescription.DepthBufferEnable; - state.DepthBufferWriteEnable = depthStencilStateDescription.DepthBufferWriteEnable && hasDepthStencilBuffer; - - state.StencilEnable = depthStencilStateDescription.StencilEnable; - state.StencilMask = depthStencilStateDescription.StencilMask; - state.StencilWriteMask = depthStencilStateDescription.StencilWriteMask; - - state.DepthFunction = depthStencilStateDescription.DepthBufferFunction.ToOpenGLDepthFunction(); - - state.Faces.FrontFaceStencilFunction = depthStencilStateDescription.FrontFace.StencilFunction.ToOpenGLStencilFunction(); - state.Faces.FrontFaceDepthFailOp = depthStencilStateDescription.FrontFace.StencilDepthBufferFail.ToOpenGL(); - state.Faces.FrontFaceFailOp = depthStencilStateDescription.FrontFace.StencilFail.ToOpenGL(); - state.Faces.FrontFacePassOp = depthStencilStateDescription.FrontFace.StencilPass.ToOpenGL(); - - state.Faces.BackFaceStencilFunction = depthStencilStateDescription.BackFace.StencilFunction.ToOpenGLStencilFunction(); - state.Faces.BackFaceDepthFailOp = depthStencilStateDescription.BackFace.StencilDepthBufferFail.ToOpenGL(); - state.Faces.BackFaceFailOp = depthStencilStateDescription.BackFace.StencilFail.ToOpenGL(); - state.Faces.BackFacePassOp = depthStencilStateDescription.BackFace.StencilPass.ToOpenGL(); - } - - public void Apply(CommandList commandList) - { - var GL = commandList.GL; - - if (commandList.DepthStencilBoundState.DepthBufferEnable != state.DepthBufferEnable) - { - commandList.DepthStencilBoundState.DepthBufferEnable = state.DepthBufferEnable; - - if (state.DepthBufferEnable) - GL.Enable(EnableCap.DepthTest); - else - GL.Disable(EnableCap.DepthTest); - } - - if (state.DepthBufferEnable && commandList.DepthStencilBoundState.DepthFunction != state.DepthFunction) - { - commandList.DepthStencilBoundState.DepthFunction = state.DepthFunction; - GL.DepthFunc(state.DepthFunction); - } - - if (commandList.DepthStencilBoundState.DepthBufferWriteEnable != state.DepthBufferWriteEnable) - { - commandList.DepthStencilBoundState.DepthBufferWriteEnable = state.DepthBufferWriteEnable; - GL.DepthMask(state.DepthBufferWriteEnable); - } - - if (commandList.DepthStencilBoundState.StencilEnable != state.StencilEnable) - { - commandList.DepthStencilBoundState.StencilEnable = state.StencilEnable; - - if (state.StencilEnable) - GL.Enable(EnableCap.StencilTest); - else - GL.Disable(EnableCap.StencilTest); - } - - if (state.StencilEnable && commandList.DepthStencilBoundState.StencilWriteMask != state.StencilWriteMask) - { - commandList.DepthStencilBoundState.StencilWriteMask = state.StencilWriteMask; - GL.StencilMask(state.StencilWriteMask); - } - - // TODO: Properly handle stencil reference - if (state.StencilEnable && (commandList.DepthStencilBoundState.Faces != state.Faces || commandList.NewStencilReference != commandList.BoundStencilReference)) - { - commandList.DepthStencilBoundState.Faces = state.Faces; - commandList.BoundStencilReference = commandList.NewStencilReference; - - GL.StencilFuncSeparate(GLEnum.Front, state.Faces.FrontFaceStencilFunction, commandList.BoundStencilReference, state.StencilWriteMask); // set both faces - GL.StencilFuncSeparate(GLEnum.Back, state.Faces.BackFaceStencilFunction, commandList.BoundStencilReference, state.StencilWriteMask); // override back face - GL.StencilOpSeparate(GLEnum.Front, state.Faces.FrontFaceDepthFailOp, state.Faces.FrontFaceFailOp, state.Faces.FrontFacePassOp); - GL.StencilOpSeparate(GLEnum.Back, state.Faces.BackFaceDepthFailOp, state.Faces.BackFaceFailOp, state.Faces.BackFacePassOp); - } - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/EffectProgram.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/EffectProgram.OpenGL.cs deleted file mode 100644 index 80f6e96ccf..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/EffectProgram.OpenGL.cs +++ /dev/null @@ -1,783 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Text.RegularExpressions; -using Stride.Core; -using Stride.Core.Collections; -using Stride.Core.Diagnostics; -using Stride.Core.Extensions; -using Stride.Core.Serialization; -using Stride.Shaders; - -namespace Stride.Graphics -{ - class EffectProgram : GraphicsResourceBase - { - internal uint ProgramId; - - const string VertexShaderDepthClamp = @" -out float _edc_z; -void main() -{ - _edc_main(); - - // transform z to window coordinates - _edc_z = gl_Position.z / gl_Position.w; - _edc_z = (gl_DepthRange.diff * _edc_z + gl_DepthRange.near + gl_DepthRange.far) * 0.5; - - // prevent z-clipping - gl_Position.z = clamp(_edc_z, 0.0, 1.0); -} -"; - - const string FragmentShaderDepthClamp = @" -in float _edc_z; -void main() -{ - gl_FragDepth = clamp(_edc_z, 0.0, 1.0); - - _edc_main(); -} -"; - - private readonly LoggerResult reflectionResult = new LoggerResult(); - - private readonly EffectBytecode effectBytecode; - - public Dictionary Attributes { get; } = new Dictionary(); - -#if STRIDE_GRAPHICS_API_OPENGLES - // Fake cbuffer emulation binding - internal struct Uniform - { - public UniformType Type; - public int UniformIndex; - public int ConstantBufferSlot; - public int Offset; - public int Count; - public int CompareSize; - } - - // Start offsets for cbuffer - private static readonly int[] EmptyConstantBufferOffsets = { 0 }; - internal int[] ConstantBufferOffsets = EmptyConstantBufferOffsets; -#endif - - internal struct Texture - { - public int TextureUnit; - - public Texture(int textureUnit) - { - TextureUnit = textureUnit; - } - } - - internal EffectReflection Reflection; - - internal List Textures = new List(); - - private readonly bool emulateDepthClamp; - - internal EffectProgram(GraphicsDevice device, EffectBytecode bytecode, bool emulateDepthClamp) : base(device) - { - effectBytecode = bytecode; - this.emulateDepthClamp = emulateDepthClamp; - - // TODO OPENGL currently we modify the reflection info; need to find a better way to deal with that - Reflection = effectBytecode.Reflection; - CreateShaders(); - } - - protected internal override void OnDestroyed(bool immediately = false) - { - using (GraphicsDevice.UseOpenGLCreationContext()) - { - GL.DeleteProgram(ProgramId); - } - - ProgramId = 0; - - base.OnDestroyed(immediately); - } - - private void CreateShaders() - { - using (GraphicsDevice.UseOpenGLCreationContext()) - { - ProgramId = GL.CreateProgram(); - - // Attach shaders - foreach (var shader in effectBytecode.Stages) - { - ShaderType shaderStage; - switch (shader.Stage) - { - case ShaderStage.Vertex: - shaderStage = ShaderType.VertexShader; - break; - case ShaderStage.Pixel: - shaderStage = ShaderType.FragmentShader; - break; - default: - throw new Exception("Unsupported shader stage"); - } - - var shaderSource = shader.GetDataAsString(); - - //edit the source a little to emulateDepthClamp - if (emulateDepthClamp) - { - var mainPattern = new Regex(@"void\s+main\s*\(\)"); - if (shaderStage == ShaderType.VertexShader) - { - //bypass our regular main - shaderSource = mainPattern.Replace(shaderSource, @"void _edc_main()"); - shaderSource += VertexShaderDepthClamp; - } - else if (shaderStage == ShaderType.FragmentShader) - { - //bypass our regular main - shaderSource = mainPattern.Replace(shaderSource, @"void _edc_main()"); - shaderSource += FragmentShaderDepthClamp; - } - } - - // On OpenGL ES 3.1 and before, texture buffers are likely not supported so we have a fallback using textures - shaderSource = shaderSource.Replace("#define texelFetchBufferPlaceholder", - GraphicsDevice.HasTextureBuffers - ? "#define texelFetchBuffer(sampler, P) texelFetch(sampler, P)" - : ("#define samplerBuffer sampler2D\n" - + "#define isamplerBuffer isampler2D\n" - + "#define usamplerBuffer usampler2D\n" - + "#define texelFetchBuffer(sampler, P) texelFetch(sampler, ivec2((P) & 0xFFF, (P) >> 12), 0)\n")); - - var shaderId = GL.CreateShader(shaderStage); - GL.ShaderSource(shaderId, shaderSource); - GL.CompileShader(shaderId); - - int compileStatus; - GL.GetShader(shaderId, ShaderParameterName.CompileStatus, out compileStatus); - if (compileStatus != 1) - { - var glErrorMessage = GL.GetShaderInfoLog(shaderId); - throw new InvalidOperationException("Error while compiling GLSL shader. [{0}]".ToFormat(glErrorMessage)); - } - - GL.AttachShader(ProgramId, shaderId); - } - -#if !STRIDE_GRAPHICS_API_OPENGLES - // Mark program as retrievable (necessary for later GL.GetProgramBinary). - GL.ProgramParameter(ProgramId, ProgramParameterPName.ProgramBinaryRetrievableHint, 1); -#endif - - // Link OpenGL program - GL.LinkProgram(ProgramId); - - // Check link results - int linkStatus; - GL.GetProgram(ProgramId, ProgramPropertyARB.LinkStatus, out linkStatus); - if (linkStatus != 1) - { - var infoLog = GL.GetProgramInfoLog(ProgramId); - throw new InvalidOperationException("Error while linking GLSL shaders.\n" + infoLog); - } - - if (Attributes.Count == 0) // the shader wasn't analyzed yet // TODO Is it possible? - { - // Build attributes list for shader signature - int activeAttribCount; - GL.GetProgram(ProgramId, ProgramPropertyARB.ActiveAttributes, out activeAttribCount); - - for (uint activeAttribIndex = 0; activeAttribIndex < activeAttribCount; ++activeAttribIndex) - { - var attribName = GL.GetActiveAttrib(ProgramId, activeAttribIndex, out var size, out var type); - var attribIndex = GL.GetAttribLocation(ProgramId, attribName); - Attributes.Add(attribName, attribIndex); - } - } - - CreateReflection(Reflection, effectBytecode.Stages[0].Stage); // need to regenerate the Uniforms on OpenGL ES - } - - // output the gathered errors - foreach (var message in reflectionResult.Messages) - Console.WriteLine(message); - if (reflectionResult.HasErrors) - throw new Exception(reflectionResult.Messages.Select(x=>x.ToString()).Aggregate((x,y)=>x+"\n"+y)); - } - - /// - protected internal override bool OnRecreate() - { - base.OnRecreate(); - CreateShaders(); - return true; - } - - /// - protected override void Destroy() - { - using (GraphicsDevice.UseOpenGLCreationContext()) - { - GL.DeleteProgram(ProgramId); - } - - ProgramId = 0; - - base.Destroy(); - } - - /// - /// Create or updates the reflection for this shader - /// - /// the reflection from the hlsl - /// the shader pipeline stage - private void CreateReflection(EffectReflection effectReflection, ShaderStage stage) - { - int currentProgram; - GL.GetInteger(GetPName.CurrentProgram, out currentProgram); - GL.UseProgram(ProgramId); - - int uniformBlockCount; - GL.GetProgram(ProgramId, ProgramPropertyARB.ActiveUniformBlocks, out uniformBlockCount); - - var validConstantBuffers = new bool[effectReflection.ConstantBuffers.Count]; - for (uint uniformBlockIndex = 0; uniformBlockIndex < uniformBlockCount; ++uniformBlockIndex) - { - // TODO: get previous name to find te actual constant buffer in the reflexion - GL.GetActiveUniformBlockName(ProgramId, uniformBlockIndex, 1024, out var constantBufferNameLength, out string constantBufferName); - - var constantBufferDescriptionIndex = effectReflection.ConstantBuffers.FindIndex(x => x.Name == constantBufferName); - if (constantBufferDescriptionIndex == -1) - { - reflectionResult.Error($"Unable to find the constant buffer description [{constantBufferName}]"); - return; - } - var constantBufferIndex = effectReflection.ResourceBindings.FindIndex(x => x.RawName == constantBufferName); - if (constantBufferIndex == -1) - { - reflectionResult.Error($"Unable to find the constant buffer [{constantBufferName}]"); - return; - } - - var constantBufferDescription = effectReflection.ConstantBuffers[constantBufferDescriptionIndex]; - var constantBuffer = effectReflection.ResourceBindings[constantBufferIndex]; - - GL.GetActiveUniformBlock(ProgramId, uniformBlockIndex, UniformBlockPName.UniformBlockDataSize, out constantBufferDescription.Size); - - int uniformCount; - GL.GetActiveUniformBlock(ProgramId, uniformBlockIndex, UniformBlockPName.UniformBlockActiveUniforms, out uniformCount); - - // set the binding - GL.UniformBlockBinding(ProgramId, uniformBlockIndex, uniformBlockIndex); - - // Read uniforms desc - var uniformIndices = new uint[uniformCount]; - var uniformOffsets = new int[uniformCount]; - var uniformTypes = new int[uniformCount]; - var uniformNames = new string[uniformCount]; - GL.GetActiveUniformBlock(ProgramId, uniformBlockIndex, UniformBlockPName.UniformBlockActiveUniformIndices, MemoryMarshal.Cast(uniformIndices.AsSpan())); - GL.GetActiveUniforms(ProgramId, (uint)uniformIndices.Length, uniformIndices, UniformPName.UniformOffset, uniformOffsets); - GL.GetActiveUniforms(ProgramId, (uint)uniformIndices.Length, uniformIndices, UniformPName.UniformType, uniformTypes); - - for (int uniformIndex = 0; uniformIndex < uniformIndices.Length; ++uniformIndex) - { - uniformNames[uniformIndex] = GL.GetActiveUniform(ProgramId, uniformIndices[uniformIndex], out var uniformSize, out var uniformType); - } - - // Reoder by offset - var indexMapping = uniformIndices.Select((x, i) => new UniformMergeInfo { Offset = uniformOffsets[i], Type = (UniformType)uniformTypes[i], Name = uniformNames[i], NextOffset = 0 }).OrderBy(x => x.Offset).ToArray(); - indexMapping.Last().NextOffset = constantBufferDescription.Size; - - // Fill next offsets - for (int i = 1; i < indexMapping.Length; ++i) - { - indexMapping[i - 1].NextOffset = indexMapping[i].Offset; - } - - // Group arrays/structures into one variable (std140 layout is enough for offset determinism inside arrays/structures) - indexMapping = indexMapping.GroupBy(x => - { - // Use only first part of name (ignore structure/array part) - var name = x.Name; - if (name.Contains(".")) { name = name.Substring(0, name.IndexOf('.')); } - if (name.Contains("[")) { name = name.Substring(0, name.IndexOf('[')); } - return name; - }) - .Select(x => - { - var result = x.First(); - result.NextOffset = x.Last().NextOffset; - - // Check weither it's an array or a struct - int dotIndex = result.Name.IndexOf('.'); - int arrayIndex = result.Name.IndexOf('['); - - if (x.Count() > 1 && arrayIndex == -1 && dotIndex == -1) - throw new InvalidOperationException(); - - // TODO: Type processing - - result.Name = x.Key; - return result; - }).ToArray(); - - foreach (var variableIndexGroup in indexMapping) - { - var variableIndex = -1; - for (var tentativeIndex = 0; tentativeIndex < constantBufferDescription.Members.Length; ++tentativeIndex) - { - if (constantBufferDescription.Members[tentativeIndex].RawName == variableIndexGroup.Name) - { - variableIndex = tentativeIndex; - break; - } - } - - if (variableIndex == -1) - { - reflectionResult.Error($"Unable to find uniform [{variableIndexGroup.Name}] in constant buffer [{constantBufferName}]"); - continue; - } - var variable = constantBufferDescription.Members[variableIndex]; - variable.Type.Type = GetTypeFromActiveUniformType(variableIndexGroup.Type); - variable.Offset = variableIndexGroup.Offset; - variable.Size = variableIndexGroup.NextOffset - variableIndexGroup.Offset; - - constantBufferDescription.Members[variableIndex] = variable; - } - - constantBufferDescription.Type = ConstantBufferType.ConstantBuffer; - - constantBuffer.SlotCount = 1; // constant buffers are not arrays - constantBuffer.SlotStart = (int)uniformBlockIndex; - constantBuffer.Stage = stage; - - // store the new values - validConstantBuffers[constantBufferDescriptionIndex] = true; - effectReflection.ConstantBuffers[constantBufferDescriptionIndex] = constantBufferDescription; - effectReflection.ResourceBindings[constantBufferIndex] = constantBuffer; - } -//#endif - - // Remove unecessary cbuffer and resource bindings - - // Register textures, samplers, etc... - //TODO: (?) non texture/buffer uniform outside of a block - { - // Register "NoSampler", required by HLSL=>GLSL translation to support HLSL such as texture.Load(). - var noSampler = new EffectResourceBindingDescription { KeyInfo = { KeyName = "NoSampler" }, RawName = "NoSampler", Class = EffectParameterClass.Sampler, SlotStart = -1, SlotCount = 1 }; - Reflection.ResourceBindings.Add(noSampler); - - int activeUniformCount; - GL.GetProgram(ProgramId, ProgramPropertyARB.ActiveUniforms, out activeUniformCount); -#if !STRIDE_GRAPHICS_API_OPENGLES - var uniformTypes = new int[activeUniformCount]; - var uniformIndices = new uint[activeUniformCount]; - for (uint i = 0; i < uniformIndices.Length; ++i) - uniformIndices[i] = i; - GL.GetActiveUniforms(ProgramId, (uint)activeUniformCount, uniformIndices, UniformPName.UniformType, uniformTypes); -#endif - - int textureUnitCount = 0; - - const int sbCapacity = 128; - var sb = new StringBuilder(sbCapacity); - - for (uint activeUniformIndex = 0; activeUniformIndex < activeUniformCount; ++activeUniformIndex) - { - var uniformName = GL.GetActiveUniform(ProgramId, activeUniformIndex, out var uniformCount, out var uniformType); - -#if STRIDE_GRAPHICS_API_OPENGLES - //this is a special OpenglES case , it is declared as built in uniform, and the driver will take care of it, we just need to ignore it here - if (uniformName.StartsWith("gl_DepthRange")) - { - continue; - } -#endif - - switch (uniformType) - { - case UniformType.Sampler1D: - case UniformType.Sampler1DShadow: - case UniformType.IntSampler1D: - case UniformType.UnsignedIntSampler1D: - - case UniformType.SamplerBuffer: - case UniformType.UnsignedIntSamplerBuffer: - case UniformType.IntSamplerBuffer: - case UniformType.Sampler2D: - case UniformType.Sampler2DShadow: - case UniformType.Sampler3D: // TODO: remove Texture3D that is not available in OpenGL ES 2 - case UniformType.SamplerCube: - case UniformType.IntSampler2D: - case UniformType.IntSampler3D: - case UniformType.IntSamplerCube: - case UniformType.UnsignedIntSampler2D: - case UniformType.UnsignedIntSampler3D: - case UniformType.UnsignedIntSamplerCube: - var uniformIndex = GL.GetUniformLocation(ProgramId, uniformName); - - // Temporary way to scan which texture and sampler created this texture_sampler variable (to fix with new HLSL2GLSL converter) - - var startIndex = -1; - var textureReflectionIndex = -1; - var samplerReflectionIndex = -1; - do - { - int middlePart = uniformName.IndexOf('_', startIndex + 1); - var textureName = middlePart != -1 ? uniformName.Substring(0, middlePart) : uniformName; - var samplerName = middlePart != -1 ? uniformName.Substring(middlePart + 1) : null; - - textureReflectionIndex = - effectReflection.ResourceBindings.FindIndex(x => x.RawName == textureName); - samplerReflectionIndex = - effectReflection.ResourceBindings.FindIndex(x => x.RawName == samplerName); - - if (textureReflectionIndex != -1 && samplerReflectionIndex != -1) - break; - - startIndex = middlePart; - } while (startIndex != -1); - - if (startIndex == -1 || textureReflectionIndex == -1 || samplerReflectionIndex == -1) - { - reflectionResult.Error($"Unable to find sampler and texture corresponding to [{uniformName}]"); - continue; // Error - } - - var textureReflection = effectReflection.ResourceBindings[textureReflectionIndex]; - var samplerReflection = effectReflection.ResourceBindings[samplerReflectionIndex]; - - // Contrary to Direct3D, samplers and textures are part of the same object in OpenGL - // Since we are exposing the Direct3D representation, a single sampler parameter key can be used for several textures, a single texture can be used with several samplers. - // When such a case is detected, we need to duplicate the resource binding. - textureReflectionIndex = GetReflexionIndex(textureReflection, textureReflectionIndex, effectReflection.ResourceBindings); - samplerReflectionIndex = GetReflexionIndex(samplerReflection, samplerReflectionIndex, effectReflection.ResourceBindings); - - // Update texture uniform mapping - GL.Uniform1(uniformIndex, textureUnitCount); - - textureReflection.Stage = stage; - //textureReflection.Param.RawName = uniformName; - textureReflection.Type = GetTypeFromActiveUniformType(uniformType); - textureReflection.Class = EffectParameterClass.ShaderResourceView; - textureReflection.SlotStart = textureUnitCount; - textureReflection.SlotCount = 1; // TODO: texture arrays - - samplerReflection.Stage = stage; - samplerReflection.Class = EffectParameterClass.Sampler; - samplerReflection.SlotStart = textureUnitCount; - samplerReflection.SlotCount = 1; // TODO: texture arrays - - effectReflection.ResourceBindings[textureReflectionIndex] = textureReflection; - effectReflection.ResourceBindings[samplerReflectionIndex] = samplerReflection; - - Textures.Add(new Texture(textureUnitCount)); - - textureUnitCount++; - break; - } - } - - // Remove any optimized resource binding - effectReflection.ResourceBindings.RemoveAll(x => x.SlotStart == -1); - effectReflection.ConstantBuffers = effectReflection.ConstantBuffers.Where((cb, i) => validConstantBuffers[i]).ToList(); - } - - GL.UseProgram((uint)currentProgram); - } - - /// - /// Inserts the data in the list if this is a copy of a previously set one. - /// - /// The data. - /// The index in the list. - /// The list of bindings. - /// The new index of the data. - private static int GetReflexionIndex(EffectResourceBindingDescription data, int index, List bindings) - { - if (data.SlotCount != 0) - { - // slot count has been specified, this means that this resource was already configured - // We have to create a new entry for the data - var newIndex = bindings.Count; - bindings.Add(data); - return newIndex; - } - return index; - } - - private static int GetCountFromActiveUniformType(UniformType type) - { - switch (type) - { - case UniformType.Int: - case UniformType.Float: - case UniformType.Bool: - return 1; - case UniformType.IntVec2: - case UniformType.UnsignedIntVec2: - case UniformType.FloatVec2: - case UniformType.BoolVec2: - return 2; - case UniformType.IntVec3: - case UniformType.UnsignedIntVec3: - case UniformType.FloatVec3: - case UniformType.BoolVec3: - return 3; - case UniformType.IntVec4: - case UniformType.UnsignedIntVec4: - case UniformType.FloatVec4: - case UniformType.BoolVec4: - case UniformType.FloatMat2: - return 4; - case UniformType.FloatMat2x3: - case UniformType.FloatMat3x2: - return 6; - case UniformType.FloatMat2x4: - case UniformType.FloatMat4x2: - return 8; - case UniformType.FloatMat3: - return 9; - case UniformType.FloatMat3x4: - case UniformType.FloatMat4x3: - return 12; - case UniformType.FloatMat4: - return 16; - - case UniformType.Sampler2D: - case UniformType.SamplerCube: - case UniformType.Sampler3D: - case UniformType.Sampler2DShadow: - case UniformType.SamplerCubeShadow: - case UniformType.IntSampler2D: - case UniformType.IntSampler3D: - case UniformType.IntSamplerCube: - case UniformType.UnsignedIntSampler2D: - case UniformType.UnsignedIntSampler3D: - case UniformType.UnsignedIntSamplerCube: - case UniformType.Sampler2DArray: - case UniformType.Sampler2DArrayShadow: - case UniformType.IntSampler2DArray: - case UniformType.UnsignedIntSampler2DArray: -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.Sampler1D: - case UniformType.Sampler1DShadow: - case UniformType.Sampler2DRect: - case UniformType.Sampler2DRectShadow: - case UniformType.IntSampler1D: - case UniformType.IntSampler2DRect: - case UniformType.UnsignedIntSampler1D: - case UniformType.UnsignedIntSampler2DRect: - case UniformType.Sampler1DArray: - case UniformType.Sampler1DArrayShadow: - case UniformType.IntSampler1DArray: - case UniformType.UnsignedIntSampler1DArray: -#endif - return 1; -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.SamplerBuffer: - case UniformType.IntSamplerBuffer: - case UniformType.UnsignedIntSamplerBuffer: - return 1; - case UniformType.Sampler2DMultisample: - case UniformType.IntSampler2DMultisample: - case UniformType.UnsignedIntSampler2DMultisample: - return 1; - case UniformType.Sampler2DMultisampleArray: - case UniformType.IntSampler2DMultisampleArray: - case UniformType.UnsignedIntSampler2DMultisampleArray: -#endif - return 1; - default: - //TODO: log error ? - return 0; - } - } - - private static EffectParameterClass GetClassFromActiveUniformType(UniformType type) - { - switch (type) - { - case UniformType.Int: - case UniformType.Float: - case UniformType.Bool: - return EffectParameterClass.Scalar; - case UniformType.FloatVec2: - case UniformType.FloatVec3: - case UniformType.FloatVec4: - case UniformType.IntVec2: - case UniformType.IntVec3: - case UniformType.IntVec4: - case UniformType.BoolVec2: - case UniformType.BoolVec3: - case UniformType.BoolVec4: - case UniformType.UnsignedIntVec2: - case UniformType.UnsignedIntVec3: - case UniformType.UnsignedIntVec4: - return EffectParameterClass.Vector; - case UniformType.FloatMat2: - case UniformType.FloatMat3: - case UniformType.FloatMat4: - case UniformType.FloatMat2x3: - case UniformType.FloatMat2x4: - case UniformType.FloatMat3x2: - case UniformType.FloatMat3x4: - case UniformType.FloatMat4x2: - case UniformType.FloatMat4x3: - return EffectParameterClass.MatrixColumns; - //return EffectParameterClass.MatrixRows; - //return EffectParameterClass.Vector; - case UniformType.Sampler2D: - case UniformType.SamplerCube: - case UniformType.Sampler3D: - case UniformType.Sampler2DShadow: - case UniformType.Sampler2DArray: - case UniformType.Sampler2DArrayShadow: - case UniformType.SamplerCubeShadow: - case UniformType.IntSampler2D: - case UniformType.IntSampler3D: - case UniformType.IntSamplerCube: - case UniformType.IntSampler2DArray: - case UniformType.UnsignedIntSampler2D: - case UniformType.UnsignedIntSampler3D: - case UniformType.UnsignedIntSamplerCube: - case UniformType.UnsignedIntSampler2DArray: -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.Sampler1D: - case UniformType.Sampler1DShadow: - case UniformType.Sampler2DRect: - case UniformType.Sampler2DRectShadow: - case UniformType.Sampler1DArray: - case UniformType.SamplerBuffer: - case UniformType.Sampler1DArrayShadow: - case UniformType.IntSampler1D: - case UniformType.IntSampler2DRect: - case UniformType.IntSampler1DArray: - case UniformType.IntSamplerBuffer: - case UniformType.UnsignedIntSampler1D: - case UniformType.UnsignedIntSampler2DRect: - case UniformType.UnsignedIntSampler1DArray: - case UniformType.UnsignedIntSamplerBuffer: - case UniformType.Sampler2DMultisample: - case UniformType.IntSampler2DMultisample: - case UniformType.UnsignedIntSampler2DMultisample: - case UniformType.Sampler2DMultisampleArray: - case UniformType.IntSampler2DMultisampleArray: - case UniformType.UnsignedIntSampler2DMultisampleArray: -#endif - return EffectParameterClass.TextureBuffer; - default: - //TODO: log error ? - return EffectParameterClass.Object; - } - } - - private static EffectParameterType GetTypeFromActiveUniformType(UniformType type) - { - switch (type) - { - case UniformType.Int: - case UniformType.IntVec2: - case UniformType.IntVec3: - case UniformType.IntVec4: - return EffectParameterType.Int; - case UniformType.Float: - case UniformType.FloatVec2: - case UniformType.FloatVec3: - case UniformType.FloatVec4: - case UniformType.FloatMat2: - case UniformType.FloatMat3: - case UniformType.FloatMat4: - case UniformType.FloatMat2x3: - case UniformType.FloatMat2x4: - case UniformType.FloatMat3x2: - case UniformType.FloatMat3x4: - case UniformType.FloatMat4x2: - case UniformType.FloatMat4x3: - return EffectParameterType.Float; - case UniformType.Bool: - case UniformType.BoolVec2: - case UniformType.BoolVec3: - case UniformType.BoolVec4: - return EffectParameterType.Bool; - case UniformType.UnsignedIntVec2: - case UniformType.UnsignedIntVec3: - case UniformType.UnsignedIntVec4: - return EffectParameterType.UInt; -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.Sampler1D: - case UniformType.Sampler1DShadow: - case UniformType.IntSampler1D: - case UniformType.UnsignedIntSampler1D: - return EffectParameterType.Texture1D; -#endif - case UniformType.Sampler2D: - case UniformType.Sampler2DShadow: - case UniformType.IntSampler2D: - case UniformType.UnsignedIntSampler2D: -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.Sampler2DRect: - case UniformType.Sampler2DRectShadow: - case UniformType.IntSampler2DRect: - case UniformType.UnsignedIntSampler2DRect: -#endif - return EffectParameterType.Texture2D; - case UniformType.Sampler3D: - case UniformType.IntSampler3D: - case UniformType.UnsignedIntSampler3D: - return EffectParameterType.Texture3D; - case UniformType.SamplerCube: - case UniformType.SamplerCubeShadow: - case UniformType.IntSamplerCube: - case UniformType.UnsignedIntSamplerCube: - return EffectParameterType.TextureCube; - case UniformType.Sampler2DArray: - case UniformType.Sampler2DArrayShadow: - case UniformType.IntSampler2DArray: - case UniformType.UnsignedIntSampler2DArray: - return EffectParameterType.Texture2DArray; -#if !STRIDE_GRAPHICS_API_OPENGLES - case UniformType.Sampler1DArray: - case UniformType.Sampler1DArrayShadow: - case UniformType.IntSampler1DArray: - case UniformType.UnsignedIntSampler1DArray: - return EffectParameterType.Texture1DArray; - case UniformType.SamplerBuffer: - case UniformType.IntSamplerBuffer: - case UniformType.UnsignedIntSamplerBuffer: - return EffectParameterType.TextureBuffer; - case UniformType.Sampler2DMultisample: - case UniformType.IntSampler2DMultisample: - case UniformType.UnsignedIntSampler2DMultisample: - return EffectParameterType.Texture2DMultisampled; - case UniformType.Sampler2DMultisampleArray: - case UniformType.IntSampler2DMultisampleArray: - case UniformType.UnsignedIntSampler2DMultisampleArray: - return EffectParameterType.Texture2DMultisampledArray; -#endif - default: - //TODO: log error ? - return EffectParameterType.Void; - } - } - - class UniformMergeInfo - { - public UniformType Type; - public int Offset; - public int NextOffset; - public string Name; - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GlobalUsings.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GlobalUsings.OpenGL.cs deleted file mode 100644 index b4e42d5027..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GlobalUsings.OpenGL.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -// Global usings -#if STRIDE_GRAPHICS_API_OPENGLES -global using Silk.NET.OpenGLES; -global using Silk.NET.OpenGLES.Extensions.EXT; -global using PixelFormatGl = Silk.NET.OpenGLES.PixelFormat; -global using PrimitiveTypeGl = Silk.NET.OpenGLES.PrimitiveType; -#else -global using Silk.NET.OpenGL; -global using PixelFormatGl = Silk.NET.OpenGL.PixelFormat; -global using PrimitiveTypeGl = Silk.NET.OpenGL.PrimitiveType; -#endif -global using Texture = Stride.Graphics.Texture; -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs deleted file mode 100644 index 86aa6be165..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_GRAPHICS_API_OPENGL - -using Silk.NET.SDL; -using Stride.Graphics.OpenGL; - -namespace Stride.Graphics -{ - /// - /// Provides methods to retrieve and manipulate graphics adapters. - /// - public unsafe partial class GraphicsAdapter - { - private GraphicsProfile supportedGraphicsProfile; - internal int OpenGLVersion; - internal string OpenGLRenderer; - - internal static Silk.NET.SDL.Window* DefaultWindow; - - internal GraphicsAdapter() - { - // set default values - int detectedVersion = 100; - - string renderer, vendor, version; - int versionMajor, versionMinor; - - var SDL = Stride.Graphics.SDL.Window.SDL; - - // Initialize outputs - var numOutputs = SDL.GetNumVideoDisplays(); - graphicsOutputs = new GraphicsOutput[numOutputs]; - for (int outputIndex = 0; outputIndex < graphicsOutputs.Length; outputIndex++) - graphicsOutputs[outputIndex] = new GraphicsOutput(this, outputIndex); - - // Some platforms (i.e. Android) can only have a single window - var sdlWindow = DefaultWindow; - if (sdlWindow == null) - sdlWindow = SDL.CreateWindow("Stride Hidden OpenGL", 50, 50, 1280, 720, (uint)(WindowFlags.WindowHidden | WindowFlags.WindowOpengl)); - - using (var sdlContext = new SdlContext(SDL, sdlWindow)) - using (var gl = GL.GetApi(sdlContext)) - { -#if STRIDE_GRAPHICS_API_OPENGLES - SDL.GLSetAttribute(GLattr.GLContextProfileMask, (int)GLprofile.GLContextProfileES); -#else - SDL.GLSetAttribute(GLattr.GLContextProfileMask, (int)GLprofile.GLContextProfileCore); -#endif - sdlContext.Create(); - renderer = gl.GetStringS(StringName.Renderer); - vendor = gl.GetStringS(StringName.Vendor); - version = gl.GetStringS(StringName.Version); - gl.GetInteger(GetPName.MajorVersion, out versionMajor); - gl.GetInteger(GetPName.MinorVersion, out versionMinor); - } - if (sdlWindow != DefaultWindow) - SDL.DestroyWindow(sdlWindow); - - // Stay close to D3D: Cut renderer after first / (ex: "GeForce 670/PCIe/SSE2") - var rendererSlash = renderer.IndexOf('/'); - if (rendererSlash != -1) - renderer = renderer.Substring(0, rendererSlash); - - // Stay close to D3D: Remove "Corporation" from vendor - vendor = vendor.Replace(" Corporation", string.Empty); - - // Generate adapter Description - Description = $"{vendor} {renderer}"; - - // get real values - // Note: using glGetIntegerv(GL_MAJOR_VERSION / GL_MINOR_VERSION) only works on opengl (es) >= 3.0 - detectedVersion = versionMajor * 100 + versionMinor * 10; - supportedGraphicsProfile = OpenGLUtils.GetFeatureLevel(detectedVersion); - - OpenGLVersion = detectedVersion; - OpenGLRenderer = renderer; - } - - public bool IsProfileSupported(GraphicsProfile graphicsProfile) - { - // TODO: Check OpenGL version? - // TODO: ES specific code? - return graphicsProfile <= supportedGraphicsProfile; - } - - /// - /// Gets the description of this adapter. - /// - /// The description. - public string Description { get; } - - /// - /// Determines if this instance of GraphicsAdapter is the default adapter. - /// - public bool IsDefaultAdapter - { - get { return true; } - } - - /// - /// Gets or sets the vendor identifier. - /// - /// - /// The vendor identifier. - /// - public int VendorId - { - get { return 0; } - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapterFactory.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapterFactory.OpenGL.cs deleted file mode 100644 index 94ad7a44b1..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapterFactory.OpenGL.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -namespace Stride.Graphics -{ - public partial class GraphicsAdapterFactory - { - private static void InitializeInternal() - { - defaultAdapter = new GraphicsAdapter(); - adapters = new [] { defaultAdapter }; - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs deleted file mode 100644 index 9a3c30bb03..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs +++ /dev/null @@ -1,1057 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Silk.NET.Core.Contexts; -using Stride.Core; -using Stride.Core.Diagnostics; -using Stride.Core.Mathematics; -using Stride.Rendering; -using Stride.Shaders; -using Stride.Graphics.OpenGL; -using Color4 = Stride.Core.Mathematics.Color4; -#if STRIDE_PLATFORM_ANDROID -using Monitor = System.Threading.Monitor; -#endif - -#if STRIDE_UI_SDL -using Silk.NET.SDL; -using WindowState = Stride.Graphics.SDL.FormWindowState; -using System.Diagnostics; -#endif - -namespace Stride.Graphics -{ - /// - /// Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. - /// - public partial class GraphicsDevice - { - internal readonly int ConstantBufferDataPlacementAlignment = 16; - - private static readonly Logger Log = GlobalLogger.GetLogger("GraphicsDevice"); - - internal int FrameCounter; - - // Used when locking asyncCreationLockObject - private bool asyncCreationLockTaken; - - internal bool ApplicationPaused = false; - internal bool ProfileEnabled = false; - - internal object asyncCreationLockObject = new object(); - internal IGLContext deviceCreationContext; - - internal uint defaultVAO; - - internal uint CopyColorSourceFBO, CopyDepthSourceFBO; - - DebugProc debugCallbackInstance; - - private const GraphicsPlatform GraphicPlatform = -#if STRIDE_GRAPHICS_API_OPENGLES - GraphicsPlatform.OpenGLES; -#else - GraphicsPlatform.OpenGL; -#endif - - internal SamplerState DefaultSamplerState; - internal DepthStencilState defaultDepthStencilState; - internal BlendState defaultBlendState; - internal GraphicsProfile requestedGraphicsProfile; - internal int version; // queried version - internal int currentVersion; // glGetVersion - internal Texture WindowProvidedRenderTexture; - internal uint WindowProvidedFrameBuffer; - - internal bool HasDXT; - - internal bool HasDepthClamp; - - internal bool HasAnisotropicFiltering; - - internal bool HasTextureBuffers; - internal bool HasKhronosDebug; - internal bool HasTimerQueries; - - internal bool HasExtTextureFormatBGRA8888; - - private bool isFramebufferSRGB; - - private int contextBeginCounter = 0; - - // TODO: Use some LRU scheme to clean up FBOs if not used frequently anymore. - internal Dictionary existingFBOs = new Dictionary(); - - private static GraphicsDevice _currentGraphicsDevice = null; - - [ThreadStatic] private static List _graphicsDevicesInUse; - - public static GraphicsDevice Current - { - get - { - if (_graphicsDevicesInUse != null && _graphicsDevicesInUse.Count > 0) - return _graphicsDevicesInUse[_graphicsDevicesInUse.Count - 1]; - - return _currentGraphicsDevice; - } - - set - { - _currentGraphicsDevice = value; - } - } - -#if STRIDE_UI_SDL - private Stride.Graphics.SDL.Window gameWindow; - internal IGLContext MainGraphicsContext; - - internal unsafe IntPtr CurrentGraphicsContext => (IntPtr)Graphics.SDL.Window.SDL.GLGetCurrentContext(); -#endif - -#if STRIDE_GRAPHICS_API_OPENGLES - // Need to change sampler state depending on if texture has mipmap or not during PreDraw - private bool[] hasMipmaps = new bool[64]; -#endif - public GL GL { get; internal set; } -#if STRIDE_GRAPHICS_API_OPENGLES - public ExtDisjointTimerQuery GLExtDisjointTimerQuery { get; internal set; } -#endif - - private uint copyProgram = 0; - private int copyProgramOffsetLocation = -1; - private int copyProgramScaleLocation = -1; - - private uint copyProgramSRgb = 0; - private int copyProgramSRgbOffsetLocation = -1; - private int copyProgramSRgbScaleLocation = -1; - - internal float[] SquareVertices = { - 0.0f, 0.0f, - 1.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 1.0f, - }; - - internal Buffer SquareBuffer; - - /// - /// The tick frquency of timestamp queries in Hertz. - /// - public long TimestampFrequency { get; } = 1000_000_000L; - - /// - /// Gets the status of this device. - /// - public GraphicsDeviceStatus GraphicsDeviceStatus - { - get - { - // TODO implement GraphicsDeviceStatus for OpenGL - return GraphicsDeviceStatus.Normal; - } - } - - public void Use() - { - if (_graphicsDevicesInUse == null) - _graphicsDevicesInUse = new List(); - - if (!_graphicsDevicesInUse.Contains(this)) - _graphicsDevicesInUse.Add(this); - } - - public void Unuse() - { - if (_graphicsDevicesInUse == null) - return; - - _graphicsDevicesInUse.Remove(this); - - if (_graphicsDevicesInUse.Count == 0) - _graphicsDevicesInUse = null; - } - - internal UseOpenGLCreationContext UseOpenGLCreationContext() - { - return new UseOpenGLCreationContext(this); - } - - /// - /// Marks context as active on the current thread. - /// - public void Begin() - { - ++contextBeginCounter; - - if (contextBeginCounter == 1) - { - FrameCounter++; - - MainGraphicsContext.MakeCurrent(); - } - } - - /// - /// Unmarks context as active on the current thread. - /// - public void End() - { -#if DEBUG - EnsureContextActive(); -#endif - - --contextBeginCounter; - if (contextBeginCounter == 0) - { - UnbindGraphicsContext(MainGraphicsContext); - } - else if (contextBeginCounter < 0) - { - throw new Exception("End context was called more than Begin"); - } - } - - internal Buffer GetSquareBuffer() - { - if (SquareBuffer == null) - { - SquareBuffer = Buffer.Vertex.New(this, SquareVertices); - } - - return SquareBuffer; - } - - internal uint GetCopyProgram(bool srgb, out int offsetLocation, out int scaleLocation) - { - if (srgb) - { - if (copyProgramSRgb == 0) - { - copyProgramSRgb = CreateCopyProgram(true, out copyProgramSRgbOffsetLocation, out copyProgramSRgbScaleLocation); - } - offsetLocation = copyProgramSRgbOffsetLocation; - scaleLocation = copyProgramSRgbScaleLocation; - return copyProgramSRgb; - } - else - { - if (copyProgram == 0) - { - copyProgram = CreateCopyProgram(false, out copyProgramOffsetLocation, out copyProgramScaleLocation); - } - offsetLocation = copyProgramOffsetLocation; - scaleLocation = copyProgramScaleLocation; - return copyProgram; - } - } - - private uint CreateCopyProgram(bool srgb, out int offsetLocation, out int scaleLocation) - { -#if STRIDE_GRAPHICS_API_OPENGLES - // We aim at OpenGLES 3.0 or greater. - var shaderVersion = "#version 300 es"; -#else - var shaderVersion = "#version 410"; -#endif - - string copyVertexShaderSource = - shaderVersion + "\n" + - "in vec2 aPosition; \n" + - "out vec2 vTexCoord; \n" + - "uniform vec4 uScale; \n" + - "uniform vec4 uOffset; \n" + - "void main() \n" + - "{ \n" + - " vec4 transformedPosition = aPosition.xyxy * uScale + uOffset;" + - " gl_Position = vec4(transformedPosition.zw * 2.0 - 1.0, 0.0, 1.0); \n" + - " vTexCoord = transformedPosition.xy; \n" + - "} \n"; - - string copyFragmentShaderSource = - shaderVersion + "\n" + - "precision mediump float; \n" + - "in vec2 vTexCoord; \n" + - "out vec4 gFragColor;\n" + - "uniform sampler2D s_texture; \n" + - "void main() \n" + - "{ \n" + - " gFragColor = texture(s_texture, vTexCoord); \n" + - "} \n"; - - string copyFragmentShaderSourceSRgb = - shaderVersion + "\n" + - "precision mediump float; \n" + - "in vec2 vTexCoord; \n" + - "out vec4 gFragColor;\n" + - "uniform sampler2D s_texture; \n" + - "void main() \n" + - "{ \n" + - " vec4 color = texture(s_texture, vTexCoord); \n" + - " gFragColor = vec4(sqrt(color.rgb), color.a); \n" + // approximation of linear to SRgb - "} \n"; - - // First initialization of shader program - var vertexShader = TryCompileShader(ShaderType.VertexShader, copyVertexShaderSource); - var fragmentShader = TryCompileShader(ShaderType.FragmentShader, srgb ? copyFragmentShaderSourceSRgb : copyFragmentShaderSource); - - var program = GL.CreateProgram(); - GL.AttachShader(program, vertexShader); - GL.AttachShader(program, fragmentShader); - GL.BindAttribLocation(program, 0, "aPosition"); - GL.LinkProgram(program); - - int linkStatus; - GL.GetProgram(program, ProgramPropertyARB.LinkStatus, out linkStatus); - - if (linkStatus != 1) - throw new InvalidOperationException("Error while linking GLSL shaders."); - - GL.UseProgram(program); - var textureLocation = GL.GetUniformLocation(program, "s_texture"); - offsetLocation = GL.GetUniformLocation(program, "uOffset"); - scaleLocation = GL.GetUniformLocation(program, "uScale"); - GL.Uniform1(textureLocation, 0); - - return program; - } - - /// - /// Enables or disables profiling. - /// - /// to enable profiling; to disable it. - public void EnableProfile(bool enabledFlag) - { - ProfileEnabled = true; - } - - internal void EnsureContextActive() - { - // TODO: Better checks (is active context the expected one?) - var context = CurrentGraphicsContext; - if (context == IntPtr.Zero) - throw new InvalidOperationException("No OpenGL context bound."); - } - - public void ExecuteCommandList(CompiledCommandList commandList) - { -#if DEBUG - EnsureContextActive(); -#endif - - throw new NotImplementedException(); - } - - public void ExecuteCommandLists(int count, CompiledCommandList[] commandList) - { -#if DEBUG - EnsureContextActive(); -#endif - - throw new NotImplementedException(); - } - - internal uint FindOrCreateFBO(GraphicsResourceBase graphicsResource, int subresource) - { - if (graphicsResource == WindowProvidedRenderTexture) - return WindowProvidedFrameBuffer; - - var texture = graphicsResource as Texture; - if (texture != null) - { - return FindOrCreateFBO(new FBOTexture(texture, subresource / texture.MipLevelCount, subresource % texture.MipLevelCount)); - } - - throw new NotSupportedException(); - } - - internal uint FindOrCreateFBO(FBOTexture texture) - { - var isDepthBuffer = ((texture.Texture.Flags & TextureFlags.DepthStencil) != 0); - lock (existingFBOs) - { - foreach (var key in existingFBOs) - { - if ((isDepthBuffer && key.Key.DepthStencilBuffer == texture) - || !isDepthBuffer && key.Key.RenderTargetCount == 1 && key.Key.RenderTargets[0] == texture) - return key.Value; - } - } - - if (isDepthBuffer) - return FindOrCreateFBO(texture, null, 0); - return FindOrCreateFBO(null, new FBOTexture[] { texture }, 1); - } - - // TODO: I think having a class for FBOs would simplify some stuff. We could implement methods like "Bind()" for it. - uint GenerateFBO(FBOTexture depthStencilBuffer, FBOTexture[] renderTargets, int renderTargetCount) - { - GL.GenFramebuffers(1, out uint fboID); - GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboID); - UpdateFBO(FramebufferTarget.Framebuffer, depthStencilBuffer, renderTargets, renderTargetCount); - - var framebufferStatus = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); - if (framebufferStatus != GLEnum.FramebufferComplete) - { - throw new InvalidOperationException(string.Format("FBO is incomplete: {0} RTs: [RT0: {1}]; Depth {2} (error: {3})", - renderTargetCount, - renderTargets != null && renderTargets.Length > 0 && renderTargets[0].Texture != null ? renderTargets[0].Texture.TextureId : 0, - depthStencilBuffer.Texture != null ? depthStencilBuffer.Texture.TextureId : 0, - framebufferStatus)); - } - - FBOTexture[] newFBOTextures = null; - if (renderTargets != null) - { - newFBOTextures = (FBOTexture[])renderTargets.Clone(); - } - - FBOKey newFBOKey = new FBOKey(depthStencilBuffer, newFBOTextures, renderTargetCount); - existingFBOs.Add(newFBOKey, fboID); - - return fboID; - } - - internal uint FindOrCreateFBO(FBOTexture depthStencilBuffer, FBOTexture[] renderTargets, int renderTargetCount) // TODO: What's the point of passing an array that has reduntant elements? This could probably be reduced to only the "renderTargets" parameter. - { - // Check for existing FBO matching this configuration - lock (existingFBOs) // TODO: PERFORMANCE: Why is this lock here? Do we ever run this from multiple threads? If so, why? - { - // Check if the default-provided render target was requested: - // TODO: Need to disable some part of rendering if either is null - var isProvidedRenderTarget = (renderTargetCount == 1 && renderTargets[0] == WindowProvidedRenderTexture); - if (isProvidedRenderTarget && depthStencilBuffer.Texture != null) - { - throw new InvalidOperationException("It is impossible to bind device provided and user created buffers with OpenGL"); - } - if (depthStencilBuffer.Texture == null && (isProvidedRenderTarget || renderTargetCount == 0)) // device provided framebuffer - { - return WindowProvidedFrameBuffer; - } - - // Check if there is an already existing FBO: - var fboKey = new FBOKey(depthStencilBuffer, renderTargets, renderTargetCount); - - if (existingFBOs.TryGetValue(fboKey, out var fboID)) - return fboID; - - // Since the desired FBO doesn't already exist, we generate it: - return GenerateFBO(depthStencilBuffer, renderTargets, renderTargetCount); - } - } - - internal FramebufferAttachment UpdateFBO(FramebufferTarget framebufferTarget, FBOTexture renderTarget) - { - var texture = renderTarget.Texture; - var isDepthBuffer = Texture.InternalIsDepthStencilFormat(texture.Format); - if (isDepthBuffer) - { - return UpdateFBODepthStencilAttachment(framebufferTarget, renderTarget); - } - else - { - UpdateFBOColorAttachment(framebufferTarget, 0, renderTarget); - return FramebufferAttachment.ColorAttachment0; - } - } - - internal void UpdateFBO(FramebufferTarget framebufferTarget, FBOTexture depthStencilBuffer, FBOTexture[] renderTargets, int renderTargetCount) // TODO: What's the point of passing an array that has reduntant elements? This could probably be reduced to only the "renderTargets" parameter. - { - for (int i = 0; i < renderTargetCount; ++i) - { - UpdateFBOColorAttachment(framebufferTarget, i, renderTargets[i]); - } - -#if !STRIDE_GRAPHICS_API_OPENGLES - if (renderTargetCount <= 1) - { - GL.DrawBuffer(renderTargetCount != 0 ? DrawBufferMode.ColorAttachment0 : DrawBufferMode.None); - } - else -#endif - { - // Specify which attachments to render to (all of them in our case): - var drawBuffers = new DrawBufferMode[renderTargetCount]; - for (var i = 0; i < renderTargetCount; ++i) - drawBuffers[i] = DrawBufferMode.ColorAttachment0 + i; - GL.DrawBuffers((uint)renderTargetCount, drawBuffers); - } - - if (depthStencilBuffer.Texture != null) - { - UpdateFBODepthStencilAttachment(framebufferTarget, depthStencilBuffer); - } - } - - void BindColorAttachment(FramebufferTarget framebufferTarget, int i, FBOTexture renderTarget) - { - FramebufferAttachment attachment = FramebufferAttachment.ColorAttachment0 + i; - - if (renderTarget.Texture.IsMultiSampled) - { - if (renderTarget.Texture.IsRenderbuffer) - { - GL.FramebufferRenderbuffer(framebufferTarget, attachment, RenderbufferTarget.Renderbuffer, renderTarget.Texture.TextureId); - } - else - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException("Multisample textures are not supported on OpenGL ES."); -#else - GL.FramebufferTexture2D(framebufferTarget, attachment, renderTarget.Texture.TextureTarget, renderTarget.Texture.TextureId, renderTarget.MipLevel); -#endif - } - } - else - { - var textureTarget = Texture.GetTextureTargetForDataSet2D(renderTarget.Texture.TextureTarget, renderTarget.ArraySlice % 6); - GL.FramebufferTexture2D(framebufferTarget, attachment, textureTarget, renderTarget.Texture.TextureId, renderTarget.MipLevel); - } - } - - internal void UpdateFBOColorAttachment(FramebufferTarget framebufferTarget, int i, FBOTexture renderTarget) - { - switch (renderTarget.Texture.TextureTarget) - { -#if !STRIDE_GRAPHICS_API_OPENGLES - case TextureTarget.Texture1D: - GL.FramebufferTexture1D(framebufferTarget, FramebufferAttachment.ColorAttachment0 + i, TextureTarget.Texture1D, renderTarget.Texture.TextureId, renderTarget.MipLevel); - break; -#endif - case TextureTarget.Texture2D: - case TextureTarget.TextureCubeMap: - // We don't make use of the "TextureTarget.Texture2DMultisample" enum value on purpose, because it - // allows for better code sharing between OpenGL ES and OpenGL. We simply use "TextureTarget.Texture2D" - // and check the value of "IsMultiSampled" instead. This is because OpenGL ES doesn't support - // multisample textures, but only multisample renderbuffers. - BindColorAttachment(framebufferTarget, i, renderTarget); - break; - case TextureTarget.Texture2DArray: - case TextureTarget.Texture3D: - GL.FramebufferTextureLayer(framebufferTarget, FramebufferAttachment.ColorAttachment0 + i, renderTarget.Texture.TextureId, renderTarget.MipLevel, renderTarget.ArraySlice); - break; - default: - throw new NotImplementedException($"Can't bind FBO with target [{renderTarget.Texture.TextureTarget}]"); - } - } - - internal FramebufferAttachment UpdateFBODepthStencilAttachment(FramebufferTarget framebufferTarget, FBOTexture depthStencilBuffer) - { - bool useSharedAttachment = depthStencilBuffer.Texture.StencilId == depthStencilBuffer.Texture.TextureId; - var attachmentType = useSharedAttachment ? (FramebufferAttachment)GLEnum.DepthStencilAttachment : FramebufferAttachment.DepthAttachment; - - if (depthStencilBuffer.Texture.IsRenderbuffer) - { - // Bind depth-only or packed depth-stencil buffer - GL.FramebufferRenderbuffer(framebufferTarget, attachmentType, RenderbufferTarget.Renderbuffer, depthStencilBuffer.Texture.TextureId); - - // If stencil buffer is separate, it's resource id might be stored in depthStencilBuffer.Texture.StencilId - if (depthStencilBuffer.Texture.HasStencil && !useSharedAttachment) - { - GL.FramebufferRenderbuffer(framebufferTarget, FramebufferAttachment.StencilAttachment, RenderbufferTarget.Renderbuffer, depthStencilBuffer.Texture.StencilId); - } - } - else - { - var textureTarget2d = TextureTarget.Texture2D; - if (depthStencilBuffer.Texture.IsMultiSampled) - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException("Multisample textures are not supported on OpenGL ES."); -#else - textureTarget2d = TextureTarget.Texture2DMultisample; -#endif - } - - // Bind depth-only or packed depth-stencil buffer // TODO: What about separate depth and stencil? - GL.FramebufferTexture2D(framebufferTarget, attachmentType, textureTarget2d, depthStencilBuffer.Texture.TextureId, depthStencilBuffer.MipLevel); - } - - return attachmentType; - } - - internal uint TryCompileShader(ShaderType shaderType, string sourceCode) - { - var shaderGL = GL.CreateShader(shaderType); - GL.ShaderSource(shaderGL, sourceCode); - GL.CompileShader(shaderGL); - - var log = GL.GetShaderInfoLog(shaderGL); - - GL.GetShader(shaderGL, ShaderParameterName.CompileStatus, out var compileStatus); - - if (compileStatus != 1) - throw new InvalidOperationException("Error while compiling GLSL shader: \n" + log); - - return shaderGL; - } - - internal static void UnbindGraphicsContext(IGLContext graphicsContext) - { - graphicsContext.Clear(); - } - - private void OnApplicationPaused(object sender, EventArgs e) - { - // Block async resource creation - Monitor.Enter(asyncCreationLockObject, ref asyncCreationLockTaken); - - ApplicationPaused = true; - - using (UseOpenGLCreationContext()) - { - GL.Finish(); - } - - // Unset graphics context - UnbindGraphicsContext(MainGraphicsContext); - } - - private void OnApplicationResumed(object sender, EventArgs e) - { - // Reenable graphics context - MainGraphicsContext.MakeCurrent(); - - ApplicationPaused = false; - - // Reenable async resource creation - if (asyncCreationLockTaken) - { - Monitor.Exit(asyncCreationLockObject); - asyncCreationLockTaken = false; - } - } - - private string rendererName; - - private partial string GetRendererName() => rendererName; - - /// - /// Initialize the OpenGL-specific implementation of the Graphics Device. - /// - /// A non- list of the graphics profiles to try, in order of preference. - /// The device creation flags. - /// The window handle. - private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle) - { - // set default values - version = 100; - - requestedGraphicsProfile = GraphicsProfile.Level_9_1; - - // Find the first profile that is compatible with current GL version - foreach (var graphicsProfile in graphicsProfiles) - { - if (Adapter.IsProfileSupported(graphicsProfile)) - { - requestedGraphicsProfile = graphicsProfile; - break; - } - } - - // Find back OpenGL version from requested version - OpenGLUtils.GetGLVersion(requestedGraphicsProfile, out version); - - // check what is actually created - currentVersion = Adapter.OpenGLVersion; - rendererName = Adapter.OpenGLRenderer; - -#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS - //gameWindow.Load += OnApplicationResumed; - //gameWindow.Unload += OnApplicationPaused; -#endif - -#if STRIDE_UI_SDL - Debug.Assert(windowHandle is WindowHandle); - var handle = (WindowHandle) windowHandle; - - // NOTE : This null handling is specific for Linux AssetCompiler #2504 (refactor required?) - gameWindow = handle?.NativeWindow as SDL.Window ?? new SDL.Window(""); - - var SDL = Graphics.SDL.Window.SDL; - -#if STRIDE_GRAPHICS_API_OPENGLES - SDL.GLSetAttribute(GLattr.ContextProfileMask, (int)GLprofile.ES); -#else - SDL.GLSetAttribute(GLattr.ContextProfileMask, (int)GLprofile.Core); -#endif - - - if (IsDebugMode) - SDL.GLSetAttribute(GLattr.ContextFlags, (int)GLcontextFlag.DebugFlag); - - // Setup version - SDL.GLSetAttribute(GLattr.ContextMajorVersion, currentVersion / 100); - SDL.GLSetAttribute(GLattr.ContextMinorVersion, (currentVersion / 10) % 10); - - MainGraphicsContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle); - ((SdlContext)MainGraphicsContext).Create(); - if (MainGraphicsContext.Handle == IntPtr.Zero) - { - throw new Exception("Cannot create OpenGL context: " + SDL.GetErrorS()); - } - - // The context must be made current to initialize OpenGL - MainGraphicsContext.MakeCurrent(); -#else -#error Creating context is only implemented for SDL -#endif - - // Create shared context for creating graphics resources from other threads - SDL.GLSetAttribute(GLattr.ShareWithCurrentContext, 1); - deviceCreationContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle); - ((SdlContext)deviceCreationContext).Create(); - - MainGraphicsContext.MakeCurrent(); - - GL = GL.GetApi(MainGraphicsContext); -#if STRIDE_GRAPHICS_API_OPENGLES - GLExtDisjointTimerQuery = new ExtDisjointTimerQuery(MainGraphicsContext); -#endif - - // Create default OpenGL State objects - DefaultSamplerState = SamplerState.New(this, new SamplerStateDescription(TextureFilter.MinPointMagMipLinear, TextureAddressMode.Wrap) { MaxAnisotropy = 1 }).DisposeBy(this); - } - - /// - /// Initializes the platform-specific features of the Graphics Device once it has been fully initialized. - /// - private unsafe partial void InitializePostFeatures() - { - // Create and bind default VAO - GL.GenVertexArrays(1, out defaultVAO); - GL.BindVertexArray(defaultVAO); - - // Save current FBO aside - GL.GetInteger(GetPName.DrawFramebufferBinding, out var boundFBO); - - // Create FBO that will be used for copy operations - CopyColorSourceFBO = GL.GenFramebuffer(); - CopyDepthSourceFBO = GL.GenFramebuffer(); - - GL.BindFramebuffer(FramebufferTarget.Framebuffer, CopyDepthSourceFBO); - GL.ReadBuffer(ReadBufferMode.None); - - // Restore FBO - GL.BindFramebuffer(FramebufferTarget.Framebuffer, (uint)boundFBO); - - if (IsDebugMode && HasKhronosDebug) - { - GL.DebugMessageCallback(debugCallbackInstance ?? (debugCallbackInstance = DebugCallback), null); - GL.Enable(EnableCap.DebugOutputSynchronous); - ProfileEnabled = true; - - // Also do it on async creation context - deviceCreationContext.MakeCurrent(); - GL.DebugMessageCallback(debugCallbackInstance, IntPtr.Zero); - GL.Enable(EnableCap.DebugOutputSynchronous); - MainGraphicsContext.MakeCurrent(); - } - - // Create the main command list - InternalMainCommandList = CommandList.New(this); - } - - /// - /// Makes OpenGL-specific adjustments to the Pipeline State objects created by the Graphics Device. - /// - /// A Pipeline State description that can be modified and adjusted. - private partial void AdjustDefaultPipelineStateDescription(ref PipelineStateDescription pipelineStateDescription) - { - } - - private static void DebugCallback(GLEnum source, GLEnum type, int id, GLEnum severity, int length, IntPtr message, IntPtr userparam) - { - if ((DebugSeverity)severity == DebugSeverity.DebugSeverityHigh) - { - string msg = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(message); - Log.Error($"[GL] {source}; {type}; {id}; {severity}; {msg}"); - } - } - - /// - /// Releases the platform-specific Graphics Device and all its associated resources. - /// - protected partial void DestroyPlatformDevice() - { - // Hack: Reset the lock so that UseOpenGLCreationContext works (even if locked by previously called OnApplicationPaused, which might have been done in an unaccessible event thread) - // TODO: Does it work with Tegra3? - if (ApplicationPaused) - { - asyncCreationLockObject = new object(); - } - -#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS - //gameWindow.Load -= OnApplicationResumed; - //gameWindow.Unload -= OnApplicationPaused; -#endif - } - - internal void OnDestroyed(bool immediately = false) - { - // Clear existing FBOs - lock (existingFBOs) - { - existingFBOs.Clear(); - existingFBOs[new FBOKey(null, new FBOTexture[] { WindowProvidedRenderTexture }, 1)] = WindowProvidedFrameBuffer; - } - - //// Clear bound states - //for (int i = 0; i < boundTextures.Length; ++i) - //boundTextures[i] = null; - - //boundFrontFace = FrontFaceDirection.Ccw; - - //boundVertexArrayObject = null; - //enabledVertexAttribArrays = 0; - //boundDepthStencilState = null; - //boundStencilReference = 0; - //boundBlendState = null; - //boundRasterizerState = null; - //boundDepthStencilBuffer = null; - - //for (int i = 0; i < boundRenderTargets.Length; ++i) - //boundRenderTargets[i] = null; - - //boundFBO = 0; - //boundFBOHeight = 0; - //boundProgram = 0; - } - - /// - /// Tags a Graphics Resource as no having alive references, meaning it should be safe to dispose it - /// or discard its contents during the next or SetData operation. - /// - /// - /// A object identifying the Graphics Resource along some related allocation information. - /// - internal partial void TagResourceAsNotAlive(GraphicsResourceLink resourceLink) - { - if (resourceLink.Resource is GraphicsResource resource) - resource.DiscardNextMap = true; - } - - internal void InitDefaultRenderTarget(PresentationParameters presentationParameters) - { -#if DEBUG - EnsureContextActive(); -#endif - - // TODO: Provide unified ClientSize from GameWindow -#if STRIDE_GRAPHICS_API_OPENGLCORE - var width = gameWindow.ClientSize.Width; - var height = gameWindow.ClientSize.Height; -#else - var width = gameWindow.Size.Width; - var height = gameWindow.Size.Height; -#endif - WindowProvidedFrameBuffer = 0; - - // TODO OPENGL detect if created framebuffer is sRGB or not (note: improperly reported by FramebufferParameterName.FramebufferAttachmentColorEncoding) - isFramebufferSRGB = true; - - GL.BindFramebuffer(FramebufferTarget.Framebuffer, WindowProvidedFrameBuffer); - - // TODO: iOS (and possibly other platforms): get real render buffer ID for color/depth? - WindowProvidedRenderTexture = Texture.New2D(this, width, height, 1, - // TODO: As a workaround, because OpenTK(+OpenGLES) doesn't support to create SRgb backbuffer, we fake it by creating a non-SRgb here and CopyScaler2D is responsible to transform it to non SRgb - isFramebufferSRGB ? presentationParameters.BackBufferFormat : presentationParameters.BackBufferFormat.ToNonSRgb(), TextureFlags.RenderTarget | Texture.TextureFlagsCustomResourceId); - WindowProvidedRenderTexture.Reload = (graphicsResource, services) => { }; - - // Extract FBO render target - if (WindowProvidedFrameBuffer != 0) - { - int framebufferAttachmentType; - GL.GetFramebufferAttachmentParameter(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, FramebufferAttachmentParameterName.FramebufferAttachmentObjectType, out framebufferAttachmentType); - if (framebufferAttachmentType == (int)GLEnum.Texture) - { - int renderTargetTextureId; - GL.GetFramebufferAttachmentParameter(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, FramebufferAttachmentParameterName.FramebufferAttachmentObjectName, out renderTargetTextureId); - WindowProvidedRenderTexture.TextureId = (uint)renderTargetTextureId; - } - } - - existingFBOs[new FBOKey(null, new FBOTexture[] { WindowProvidedRenderTexture }, 1)] = WindowProvidedFrameBuffer; - } - - private class SwapChainBackend - { - /// - /// Default constructor to initialize fields that are not explicitly set to avoid warnings at compile time. - /// - internal SwapChainBackend() - { - PresentationParameters = null; - PresentCount = 0; - } - - public PresentationParameters PresentationParameters; - public int PresentCount; - } - - /// - /// Creates a swap chain from presentation parameters. - /// - /// The presentation parameters. - /// - private SwapChainBackend CreateSwapChainBackend(PresentationParameters presentationParameters) - { - var swapChainBackend = new SwapChainBackend(); - return swapChainBackend; - } - - /// - /// Gets the default presentation parameters associated with this graphics device. - /// - public PresentationParameters PresentationParameters - { - get { throw new InvalidOperationException(FrameworkResources.NoDefaultRenterTarget); } - } - - /// - /// Gets or sets a value indicating whether this GraphicsDevice is in fullscreen. - /// - /// - /// true if this GraphicsDevice is fullscreen; otherwise, false. - /// - public bool IsFullScreen - { - get - { -#if STRIDE_PLATFORM_DESKTOP - return gameWindow.WindowState == WindowState.Fullscreen; -#else - throw new NotImplementedException(); -#endif - } - - set - { -#if STRIDE_PLATFORM_DESKTOP - if (value ^ (gameWindow.WindowState == WindowState.Fullscreen)) - gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; -#else - throw new NotImplementedException(); -#endif - } - } - - internal struct FBOTexture : IEquatable - { - public readonly Texture Texture; - public readonly short ArraySlice; - public readonly short MipLevel; - - public FBOTexture(Texture texture, int arraySlice = 0, int mipLevel = 0) - { - Texture = texture; - ArraySlice = (short)arraySlice; - MipLevel = (short)mipLevel; - } - - public static implicit operator FBOTexture(Texture texture) - { - int arraySlice = 0; - int mipLevel = 0; - if (texture != null) - { - mipLevel = texture.MipLevel; - arraySlice = texture.ArraySlice; - } - - return new FBOTexture(texture, arraySlice, mipLevel); - } - - public bool Equals(FBOTexture other) - { - return Texture == other.Texture && ArraySlice == other.ArraySlice && MipLevel == other.MipLevel; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is FBOTexture && Equals((FBOTexture)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashCode = (Texture != null ? Texture.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ ArraySlice.GetHashCode(); - hashCode = (hashCode * 397) ^ MipLevel.GetHashCode(); - return hashCode; - } - } - - public static bool operator ==(FBOTexture left, FBOTexture right) - { - return left.Equals(right); - } - - public static bool operator !=(FBOTexture left, FBOTexture right) - { - return !left.Equals(right); - } - } - - internal struct FBOKey : IEquatable - { - public readonly FBOTexture DepthStencilBuffer; - public readonly FBOTexture[] RenderTargets; - public readonly int RenderTargetCount; - - public FBOKey(FBOTexture depthStencilBuffer, FBOTexture[] renderTargets, int renderTargetCount) - { - DepthStencilBuffer = depthStencilBuffer; - RenderTargetCount = renderTargetCount; - RenderTargets = RenderTargetCount != 0 ? renderTargets : null; - } - - public bool Equals(FBOKey obj2) - { - if (obj2.DepthStencilBuffer != DepthStencilBuffer) return false; - - // Should have same number of render targets - if (RenderTargetCount != obj2.RenderTargetCount) - return false; - - // Since both object have same LastRenderTarget, array is valid at least until this spot. - for (int i = 0; i < RenderTargetCount; ++i) - if (obj2.RenderTargets[i] != RenderTargets[i]) - return false; - - return true; - } - - public override bool Equals(object obj) - { - if (!(obj is FBOKey)) return false; - - var obj2 = (FBOKey)obj; - - return Equals(obj2); - } - - public override int GetHashCode() - { - var result = DepthStencilBuffer != null ? DepthStencilBuffer.GetHashCode() : 0; - if (RenderTargets != null) - { - for (int index = 0; index < RenderTargetCount; index++) - { - var renderTarget = RenderTargets[index]; - result ^= renderTarget != null ? renderTarget.GetHashCode() : 0; - } - } - return result; - } - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs deleted file mode 100644 index 88a9f5118d..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_GRAPHICS_API_OPENGL - -// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using Stride.Graphics.OpenGL; -using Stride.Core.Diagnostics; - -namespace Stride.Graphics -{ - /// - /// Features supported by a . - /// - /// - /// This class gives also features for a particular format, using the operator this[dxgiFormat] on this structure. - /// - public partial struct GraphicsDeviceFeatures - { - private const GetPName GL_MAX_SAMPLES = (GetPName)36183; // We define this constant here because it is not contained within OpenTK... - - private static Logger logger = GlobalLogger.GetLogger(nameof(GraphicsDeviceFeatures)); - - private void EnumerateMSAASupportPerFormat(GraphicsDevice deviceRoot) - { - var GL = deviceRoot.GL; - - // Query OpenGL for the highest supported multisample count: - int globalMaxMSAASamples; - GL.GetInteger(GLEnum.MaxSamples, out globalMaxMSAASamples); - - // Now select the highest engine-supported multisample mode: // TODO: Adjust comment. - MultisampleCount actualMultisampleCount = MultisampleCount.None; - - // Technically we could just cast "globalMaxMSAASamples" to "actualMultisampleCount", - // but AFAIK nothing prevents an implementation from exposing things like 6x MSAA or some other uncommon mode. - if (globalMaxMSAASamples >= 8) - { - // If the maximum supported MSAA mode by the OpenGL implementation is higher than the maximum supported by the engine (8xMSAA), we clamp it. - actualMultisampleCount = MultisampleCount.X8; - } - else if (globalMaxMSAASamples >= 4) - { - // If the maximum supported MSAA mode by the OpenGL implementation is between 4 and 7 samples, we fall back to the next lowest engine-supported one (4x). - actualMultisampleCount = MultisampleCount.X4; // 4-7 x MSAA => 4 x MSAA (next lowest) - } - else if (globalMaxMSAASamples == 2) - { - // If the maximum supported MSAA mode by the OpenGL implementation is between 2 and 3 samples, we fall back to the next lowest engine-supported one (2x). - actualMultisampleCount = MultisampleCount.X2; - } - - for (int i = 0; i < mapFeaturesPerFormat.Length; i++) - { - // TODO: This ignores the supported multisample capabilities of each render target format. But I don't know how to query this in OpenGL (assuming it's even possible at all). - mapFeaturesPerFormat[i] = new FeaturesPerFormat((PixelFormat)i, actualMultisampleCount, ComputeShaderFormatSupport.None, FormatSupport.None); - } - } - - internal GraphicsDeviceFeatures(GraphicsDevice deviceRoot) - { - mapFeaturesPerFormat = new FeaturesPerFormat[256]; - - HasSRgb = true; - - using (deviceRoot.UseOpenGLCreationContext()) - { - var GL = deviceRoot.GL; - Vendor = GL.GetStringS(StringName.Vendor); - Renderer = GL.GetStringS(StringName.Renderer); - int numExtensions; - GL.GetInteger(GetPName.NumExtensions, out numExtensions); - SupportedExtensions = new string[numExtensions]; - for (int extensionIndex = 0; extensionIndex < numExtensions; ++extensionIndex) - { - SupportedExtensions[extensionIndex] = GL.GetStringS(StringName.Extensions, (uint)extensionIndex); - } - } - -#if STRIDE_GRAPHICS_API_OPENGLES - deviceRoot.HasExtTextureFormatBGRA8888 = SupportedExtensions.Contains("GL_EXT_texture_format_BGRA8888") - || SupportedExtensions.Contains("GL_APPLE_texture_format_BGRA8888"); - deviceRoot.HasKhronosDebug = deviceRoot.currentVersion >= 320 || SupportedExtensions.Contains("GL_KHR_debug"); - deviceRoot.HasTimerQueries = SupportedExtensions.Contains("GL_EXT_disjoint_timer_query"); - - // Either 3.2+, or 3.1+ with GL_EXT_texture_buffer - // TODO: For now we don't have proper ES3 bindings on Android (and possibly iOS) - deviceRoot.HasTextureBuffers = false; - //deviceRoot.HasTextureBuffers = (deviceRoot.version >= 320) - // || (deviceRoot.version >= 310 && SupportedExtensions.Contains("GL_EXT_texture_buffer")); - - // Compute shaders available in OpenGL ES 3.1 - HasComputeShaders = deviceRoot.currentVersion >= 310; - HasDoublePrecision = false; - - HasDepthAsSRV = true; - HasDepthAsReadOnlyRT = true; - HasMultiSampleDepthAsSRV = true; - - deviceRoot.HasDepthClamp = SupportedExtensions.Contains("GL_ARB_depth_clamp"); - - // TODO: from 3.1: draw indirect, separate shader object - // TODO: check tessellation & geometry shaders: GL_ANDROID_extension_pack_es31a -#else - deviceRoot.HasDXT = SupportedExtensions.Contains("GL_EXT_texture_compression_s3tc"); - deviceRoot.HasTextureBuffers = true; - deviceRoot.HasExtTextureFormatBGRA8888 = true; - deviceRoot.HasKhronosDebug = deviceRoot.currentVersion >= 430 || SupportedExtensions.Contains("GL_KHR_debug"); - deviceRoot.HasTimerQueries = deviceRoot.version >= 320; - - // Compute shaders available in OpenGL 4.3 - HasComputeShaders = deviceRoot.version >= 430; - HasDoublePrecision = SupportedExtensions.Contains("GL_ARB_vertex_attrib_64bit"); - - HasDepthAsSRV = true; - HasDepthAsReadOnlyRT = true; - HasMultiSampleDepthAsSRV = true; - - deviceRoot.HasDepthClamp = true; - - // TODO: from 4.0: tessellation, draw indirect - // TODO: from 4.1: separate shader object -#endif - - deviceRoot.HasAnisotropicFiltering = SupportedExtensions.Contains("GL_EXT_texture_filter_anisotropic"); - - HasResourceRenaming = true; - - HasDriverCommandLists = false; - HasMultiThreadingConcurrentResources = false; - - // Find shader model based on OpenGL version (might need to check extensions more carefully) - RequestedProfile = deviceRoot.requestedGraphicsProfile; - CurrentProfile = OpenGLUtils.GetFeatureLevel(deviceRoot.currentVersion); - - EnumerateMSAASupportPerFormat(deviceRoot); - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsOutput.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsOutput.OpenGL.cs deleted file mode 100644 index 9e1e4bf687..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsOutput.OpenGL.cs +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL - -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Mathematics; - -namespace Stride.Graphics -{ - public partial class GraphicsOutput - { - private readonly int displayIndex; - - public string DisplayName { get; init; } - - public IntPtr MonitorHandle - { - get { return IntPtr.Zero; } - } - - /// - /// Initializes a new instance of . - /// - /// The Graphics Adapter the output depends on. - /// The index of the output. - /// is . - internal GraphicsOutput(GraphicsAdapter adapter, int displayIndex) - { - ArgumentNullException.ThrowIfNull(adapter); - - Adapter = adapter; - this.displayIndex = displayIndex; - - var SDL = Graphics.SDL.Window.SDL; - - unsafe - { - var bounds = new Silk.NET.Maths.Rectangle(); - SDL.GetDisplayBounds(displayIndex, &bounds); - DesktopBounds = new Rectangle(bounds.Origin.X, bounds.Origin.Y, bounds.Size.X, bounds.Size.Y); - } - - DisplayName = SDL.GetDisplayNameS(displayIndex); - } - - /// - /// Find the display mode that most closely matches the requested display mode. - /// - /// The target profile, as available formats are different depending on the feature level.. - /// The mode. - /// Returns the closes display mode. - public DisplayMode FindClosestMatchingDisplayMode(GraphicsProfile[] targetProfiles, DisplayMode mode) - { - var SDL = Stride.Graphics.SDL.Window.SDL; - - DisplayMode closest; - unsafe - { - var modeSDL = new Silk.NET.SDL.DisplayMode(0, mode.Width, mode.Height, mode.RefreshRate.Denominator / mode.RefreshRate.Numerator); - var closestSDL = new Silk.NET.SDL.DisplayMode(); - - SDL.GetClosestDisplayMode(displayIndex, &modeSDL, &closestSDL); - closest = new DisplayMode(PixelFormat.None, closestSDL.W, closestSDL.H, new Rational(1, closestSDL.RefreshRate)); - } - - return closest; - } - - private void InitializeSupportedDisplayModes() - { - var SDL = Stride.Graphics.SDL.Window.SDL; - - var modesMap = new Dictionary<(int w, int h, int refreshRate), DisplayMode>(); - var modeCount = SDL.GetNumDisplayModes(displayIndex); - - unsafe - { - for (int i = 0; i < modeCount; i++) - { - var sdlMode = new Silk.NET.SDL.DisplayMode(); - SDL.GetDisplayMode(displayIndex, i, &sdlMode); - - var key = (sdlMode.W, sdlMode.H, sdlMode.RefreshRate); - - if (!modesMap.ContainsKey(key)) - { - //We should probably convert the sdlMode format - //to the engine's Pixel Format - modesMap.Add(key, new DisplayMode(PixelFormat.None, sdlMode.W, sdlMode.H, new Rational(1, sdlMode.RefreshRate))); - } - } - } - - supportedDisplayModes = modesMap.Values.ToArray(); - } - - private void InitializeCurrentDisplayMode() - { - var SDL = Stride.Graphics.SDL.Window.SDL; - var mode = new DisplayMode(PixelFormat.None, DesktopBounds.Width, DesktopBounds.Height, new Rational(1, 0)); - - currentDisplayMode = FindClosestMatchingDisplayMode([], mode); - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsResource.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsResource.OpenGL.cs deleted file mode 100644 index 9e8b388242..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsResource.OpenGL.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_GRAPHICS_API_OPENGL - -namespace Stride.Graphics -{ - /// - /// GraphicsResource class - /// - public partial class GraphicsResource - { - internal bool DiscardNextMap; // Used to internally force a WriteDiscard (to force a rename) with the GraphicsResourceAllocator - - // Shaader resource view (Texture or Texture Buffer) - internal uint TextureId; - internal TextureTarget TextureTarget; - internal InternalFormat TextureInternalFormat; - internal PixelFormatGl TextureFormat; - internal PixelType TextureType; - internal int TexturePixelSize; - - - // No OpenGL-specific implementation - protected internal override void OnDestroyed(bool immediate = false) { } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsResourceBase.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsResourceBase.OpenGL.cs deleted file mode 100644 index 50754e6199..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsResourceBase.OpenGL.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - /// - /// GraphicsResource class - /// - public partial class GraphicsResourceBase - { - protected internal GL GL; - - - /// - /// Perform OpenGL-specific initialization of the Graphics Resource. - /// - private partial void Initialize() - { - GL = GraphicsDevice?.GL; - } - - /// - /// Called when the has been detected to be internally destroyed, - /// or when the methad has been called. Raises the event. - /// - protected internal virtual partial void OnDestroyed(bool immediately = false) - { - Destroyed?.Invoke(this, EventArgs.Empty); - } - - /// - /// Called when graphics device has been recreated. - /// - /// True if item transitioned to a state. - protected internal virtual bool OnRecreate() - { - return false; - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/MappedResource.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/MappedResource.OpenGL.cs deleted file mode 100644 index c1fa72bab6..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/MappedResource.OpenGL.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_GRAPHICS_API_OPENGL - -namespace Stride.Graphics -{ - public partial struct MappedResource - { - internal uint PixelBufferObjectId { get; init; } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs b/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs deleted file mode 100644 index 2e70040869..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs +++ /dev/null @@ -1,518 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - internal static class OpenGLConvertExtensions - { - public static PrimitiveTypeGl ToOpenGL(this PrimitiveType primitiveType) - { - switch (primitiveType) - { - case PrimitiveType.PointList: - return PrimitiveTypeGl.Points; - case PrimitiveType.LineList: - return PrimitiveTypeGl.Lines; - case PrimitiveType.LineStrip: - return PrimitiveTypeGl.LineStrip; - case PrimitiveType.TriangleList: - return PrimitiveTypeGl.Triangles; - case PrimitiveType.TriangleStrip: - return PrimitiveTypeGl.TriangleStrip; - default: - // Undefined - return PrimitiveTypeGl.Triangles; - } - } - - public static MapBufferAccessMask ToOpenGLMask(this MapMode mapMode) - { - switch (mapMode) - { - case MapMode.Read: - return MapBufferAccessMask.MapReadBit; - case MapMode.Write: - return MapBufferAccessMask.MapWriteBit; - case MapMode.ReadWrite: - return MapBufferAccessMask.MapReadBit | MapBufferAccessMask.MapWriteBit; - case MapMode.WriteDiscard: - return MapBufferAccessMask.MapWriteBit | MapBufferAccessMask.MapInvalidateBufferBit; - case MapMode.WriteNoOverwrite: - return MapBufferAccessMask.MapWriteBit | MapBufferAccessMask.MapUnsynchronizedBit; - default: - throw new ArgumentOutOfRangeException("mapMode"); - } - } - -#if STRIDE_GRAPHICS_API_OPENGLES - public static PrimitiveTypeGl ToOpenGLES(this PrimitiveType primitiveType) - { - switch (primitiveType) - { - case PrimitiveType.PointList: - return PrimitiveTypeGl.Points; - case PrimitiveType.LineList: - return PrimitiveTypeGl.Lines; - case PrimitiveType.LineStrip: - return PrimitiveTypeGl.LineStrip; - case PrimitiveType.TriangleList: - return PrimitiveTypeGl.Triangles; - case PrimitiveType.TriangleStrip: - return PrimitiveTypeGl.TriangleStrip; - default: - throw new NotImplementedException(); - } - } -#else - public static BufferAccessARB ToOpenGL(this MapMode mapMode) - { - switch (mapMode) - { - case MapMode.Read: - return BufferAccessARB.ReadOnly; - case MapMode.Write: - case MapMode.WriteDiscard: - case MapMode.WriteNoOverwrite: - return BufferAccessARB.WriteOnly; - case MapMode.ReadWrite: - return BufferAccessARB.ReadWrite; - default: - throw new ArgumentOutOfRangeException("mapMode"); - } - } -#endif - - public static TextureWrapMode ToOpenGL(this TextureAddressMode addressMode) - { - switch (addressMode) - { - case TextureAddressMode.Border: - return TextureWrapMode.ClampToBorder; - case TextureAddressMode.Clamp: - return TextureWrapMode.ClampToEdge; - case TextureAddressMode.Mirror: - return TextureWrapMode.MirroredRepeat; - case TextureAddressMode.Wrap: - return TextureWrapMode.Repeat; - default: - throw new NotImplementedException(); - } - } - - public static DepthFunction ToOpenGLDepthFunction(this CompareFunction function) - { - switch (function) - { - case CompareFunction.Always: - return DepthFunction.Always; - case CompareFunction.Equal: - return DepthFunction.Equal; - case CompareFunction.GreaterEqual: - return DepthFunction.Gequal; - case CompareFunction.Greater: - return DepthFunction.Greater; - case CompareFunction.LessEqual: - return DepthFunction.Lequal; - case CompareFunction.Less: - return DepthFunction.Less; - case CompareFunction.Never: - return DepthFunction.Never; - case CompareFunction.NotEqual: - return DepthFunction.Notequal; - default: - throw new NotImplementedException(); - } - } - - public static StencilFunction ToOpenGLStencilFunction(this CompareFunction function) - { - switch (function) - { - case CompareFunction.Always: - return StencilFunction.Always; - case CompareFunction.Equal: - return StencilFunction.Equal; - case CompareFunction.GreaterEqual: - return StencilFunction.Gequal; - case CompareFunction.Greater: - return StencilFunction.Greater; - case CompareFunction.LessEqual: - return StencilFunction.Lequal; - case CompareFunction.Less: - return StencilFunction.Less; - case CompareFunction.Never: - return StencilFunction.Never; - case CompareFunction.NotEqual: - return StencilFunction.Notequal; - default: - throw new NotImplementedException(); - } - } - - public static StencilOp ToOpenGL(this StencilOperation operation) - { - switch (operation) - { - case StencilOperation.Keep: - return StencilOp.Keep; - case StencilOperation.Zero: - return StencilOp.Zero; - case StencilOperation.Replace: - return StencilOp.Replace; - case StencilOperation.IncrementSaturation: - return StencilOp.Incr; - case StencilOperation.DecrementSaturation: - return StencilOp.Decr; - case StencilOperation.Invert: - return StencilOp.Invert; - case StencilOperation.Increment: - return StencilOp.IncrWrap; - case StencilOperation.Decrement: - return StencilOp.DecrWrap; - default: - throw new ArgumentOutOfRangeException("operation"); - } - } - - public static void ConvertPixelFormat(GraphicsDevice graphicsDevice, ref PixelFormat inputFormat, out InternalFormat internalFormat, out PixelFormatGl format, out PixelType type, - out int pixelSize, out bool compressed) - { - compressed = false; - - // If the Device doesn't support SRGB, we remap automatically the format to non-srgb - if (!graphicsDevice.Features.HasSRgb) - { - switch (inputFormat) - { - case PixelFormat.ETC2_RGB_SRgb: - inputFormat = PixelFormat.ETC2_RGB; - break; - case PixelFormat.ETC2_RGBA_SRgb: - inputFormat = PixelFormat.ETC2_RGBA; - break; - case PixelFormat.R8G8B8A8_UNorm_SRgb: - inputFormat = PixelFormat.R8G8B8A8_UNorm; - break; - case PixelFormat.B8G8R8A8_UNorm_SRgb: - inputFormat = PixelFormat.B8G8R8A8_UNorm; - break; - } - } - - switch (inputFormat) - { - case PixelFormat.A8_UNorm: - internalFormat = (InternalFormat)GLEnum.Alpha; - format = PixelFormatGl.Alpha; - type = PixelType.UnsignedByte; - pixelSize = 1; - break; - case PixelFormat.R8_UNorm: - internalFormat = InternalFormat.R8; - format = PixelFormatGl.Red; - type = PixelType.UnsignedByte; - pixelSize = 1; - break; - case PixelFormat.R8G8B8A8_UNorm: - internalFormat = InternalFormat.Rgba; - format = PixelFormatGl.Rgba; - type = PixelType.UnsignedByte; - pixelSize = 4; - break; - case PixelFormat.B8G8R8A8_UNorm: - if (!graphicsDevice.HasExtTextureFormatBGRA8888) - throw new NotSupportedException(); - - internalFormat = (InternalFormat)PixelFormatGl.Bgra; - format = PixelFormatGl.Bgra; - type = PixelType.UnsignedByte; - pixelSize = 4; - break; - case PixelFormat.R8G8B8A8_UNorm_SRgb: - internalFormat = InternalFormat.Srgb8Alpha8; - format = PixelFormatGl.Rgba; - type = PixelType.UnsignedByte; - pixelSize = 4; - break; -#if STRIDE_GRAPHICS_API_OPENGLCORE - case PixelFormat.B8G8R8A8_UNorm_SRgb: - // TODO: Check on iOS/Android and OpenGL 3 - internalFormat = InternalFormat.Srgb8Alpha8; - format = PixelFormatGl.Bgra; - type = PixelType.UnsignedByte; - pixelSize = 4; - break; - case PixelFormat.BC1_UNorm: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedRgbaS3TCDxt1Ext; - format = PixelFormatGl.Rgb; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; - case PixelFormat.BC1_UNorm_SRgb: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedSrgbAlphaS3TCDxt1Ext; - format = PixelFormatGl.Rgb; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; - case PixelFormat.BC2_UNorm: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedRgbaS3TCDxt3Ext; - format = PixelFormatGl.Rgba; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; - case PixelFormat.BC2_UNorm_SRgb: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedSrgbAlphaS3TCDxt3Ext; - format = PixelFormatGl.Rgba; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; - case PixelFormat.BC3_UNorm: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedRgbaS3TCDxt5Ext; - format = PixelFormatGl.Rgba; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; - case PixelFormat.BC3_UNorm_SRgb: - if (!graphicsDevice.HasDXT) - throw new NotSupportedException(); - internalFormat = InternalFormat.CompressedSrgbAlphaS3TCDxt5Ext; - format = PixelFormatGl.Rgba; - pixelSize = 4; - type = PixelType.UnsignedByte; - compressed = true; - break; -#endif - case PixelFormat.R16_SInt: - internalFormat = InternalFormat.R16i; - format = PixelFormatGl.RedInteger; - type = PixelType.Short; - pixelSize = 2; - break; - case PixelFormat.R16_UInt: - internalFormat = InternalFormat.R16ui; - format = PixelFormatGl.RedInteger; - type = PixelType.UnsignedShort; - pixelSize = 2; - break; - case PixelFormat.R16_Float: - internalFormat = InternalFormat.R16f; - format = PixelFormatGl.Red; - type = (PixelType)GLEnum.HalfFloat; - pixelSize = 2; - break; - case PixelFormat.R16G16_SInt: - internalFormat = InternalFormat.RG16i; - format = PixelFormatGl.RGInteger; - type = PixelType.Short; - pixelSize = 4; - break; - case PixelFormat.R16G16_UInt: - internalFormat = InternalFormat.RG16ui; - format = PixelFormatGl.RGInteger; - type = PixelType.UnsignedShort; - pixelSize = 4; - break; - case PixelFormat.R16G16_Float: - internalFormat = InternalFormat.RG16f; - format = PixelFormatGl.RG; - type = (PixelType)GLEnum.HalfFloat; - pixelSize = 4; - break; - case PixelFormat.R16G16B16A16_SInt: - internalFormat = InternalFormat.Rgba16i; - format = PixelFormatGl.RgbaInteger; - type = PixelType.Short; - pixelSize = 8; - break; - case PixelFormat.R16G16B16A16_UInt: - internalFormat = InternalFormat.Rgba16ui; - format = PixelFormatGl.RgbaInteger; - type = PixelType.UnsignedShort; - pixelSize = 8; - break; - case PixelFormat.R16G16B16A16_Float: - internalFormat = InternalFormat.Rgba16f; - format = PixelFormatGl.Rgba; - type = (PixelType)GLEnum.HalfFloat; - pixelSize = 8; - break; - case PixelFormat.R10G10B10A2_UNorm: - internalFormat = InternalFormat.Rgb10A2; - format = PixelFormatGl.Rgba; - type = PixelType.UnsignedInt1010102; - pixelSize = 4; - break; - case PixelFormat.R11G11B10_Float: - internalFormat = InternalFormat.R11fG11fB10f; - format = PixelFormatGl.Rgb; - type = (PixelType)GLEnum.HalfFloat; - pixelSize = 4; - break; - case PixelFormat.R32_SInt: - internalFormat = InternalFormat.R32i; - format = PixelFormatGl.RedInteger; - type = PixelType.Int; - pixelSize = 4; - break; - case PixelFormat.R32_UInt: - internalFormat = InternalFormat.R32ui; - format = PixelFormatGl.RedInteger; - type = PixelType.UnsignedInt; - pixelSize = 4; - break; - case PixelFormat.R32_Float: - internalFormat = InternalFormat.R32f; - format = PixelFormatGl.Red; - type = PixelType.Float; - pixelSize = 4; - break; - case PixelFormat.R32G32_SInt: - internalFormat = InternalFormat.RG32i; - format = PixelFormatGl.RGInteger; - type = PixelType.Int; - pixelSize = 8; - break; - case PixelFormat.R32G32_UInt: - internalFormat = InternalFormat.RG32ui; - format = PixelFormatGl.RGInteger; - type = PixelType.UnsignedInt; - pixelSize = 8; - break; - case PixelFormat.R32G32_Float: - internalFormat = InternalFormat.RG32f; - format = PixelFormatGl.RG; - type = PixelType.Float; - pixelSize = 8; - break; - case PixelFormat.R32G32B32_SInt: - internalFormat = InternalFormat.Rgb32i; - format = PixelFormatGl.RgbInteger; - type = PixelType.Int; - pixelSize = 12; - break; - case PixelFormat.R32G32B32_UInt: - internalFormat = InternalFormat.Rgb32ui; - format = PixelFormatGl.RgbInteger; - type = PixelType.UnsignedInt; - pixelSize = 12; - break; - case PixelFormat.R32G32B32_Float: - internalFormat = InternalFormat.Rgb32f; - format = PixelFormatGl.Rgb; - type = PixelType.Float; - pixelSize = 12; - break; - case PixelFormat.R32G32B32A32_SInt: - internalFormat = InternalFormat.Rgba32i; - format = PixelFormatGl.RgbaInteger; - type = PixelType.Int; - pixelSize = 16; - break; - case PixelFormat.R32G32B32A32_UInt: - internalFormat = InternalFormat.Rgba32ui; - format = PixelFormatGl.RgbaInteger; - type = PixelType.UnsignedInt; - pixelSize = 16; - break; - case PixelFormat.R32G32B32A32_Float: - internalFormat = InternalFormat.Rgba32f; - format = PixelFormatGl.Rgba; - type = PixelType.Float; - pixelSize = 16; - break; - case PixelFormat.D16_UNorm: - internalFormat = InternalFormat.DepthComponent16; - format = PixelFormatGl.DepthComponent; - type = PixelType.UnsignedShort; - pixelSize = 2; - break; - case PixelFormat.D24_UNorm_S8_UInt: - internalFormat = InternalFormat.Depth24Stencil8; - format = PixelFormatGl.DepthStencil; - type = (PixelType)GLEnum.UnsignedInt248; - pixelSize = 4; - break; - // TODO: Temporary depth format (need to decide relation between RenderTarget1D and Texture) - case PixelFormat.D32_Float: - internalFormat = InternalFormat.DepthComponent32f; - format = PixelFormatGl.DepthComponent; - type = PixelType.Float; - pixelSize = 4; - break; -#if STRIDE_GRAPHICS_API_OPENGLES - // Desktop OpenGLES - case PixelFormat.ETC1: - // TODO: Runtime check for extension? - internalFormat = InternalFormat.Etc1Rgb8Oes; - format = PixelFormatGl.Rgb; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; - case PixelFormat.ETC2_RGB: - internalFormat = InternalFormat.CompressedRgb8Etc2Oes; - format = PixelFormatGl.Rgb; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; - case PixelFormat.ETC2_RGB_SRgb: - internalFormat = InternalFormat.CompressedSrgb8Etc2Oes; - format = PixelFormatGl.Rgb; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; - case PixelFormat.ETC2_RGB_A1: - internalFormat = InternalFormat.CompressedRgb8PunchthroughAlpha1Etc2Oes; - format = PixelFormatGl.Rgba; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; - case PixelFormat.ETC2_RGBA: - internalFormat = InternalFormat.CompressedRgba8Etc2Eac; - format = PixelFormatGl.Rgba; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; - case PixelFormat.ETC2_RGBA_SRgb: - internalFormat = InternalFormat.CompressedSrgb8Alpha8Etc2Eac; - format = PixelFormatGl.Rgba; - compressed = true; - pixelSize = 2; - type = PixelType.UnsignedByte; - break; -#endif - case PixelFormat.None: // TODO: remove this - this is only for buffers used in compute shaders - internalFormat = InternalFormat.Rgba; - format = PixelFormatGl.Red; - type = PixelType.UnsignedByte; - pixelSize = 1; - break; - default: - throw new InvalidOperationException("Unsupported texture format: " + inputFormat); - } - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs b/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs deleted file mode 100644 index 071f68b2e1..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace Stride.Graphics.OpenGL -{ - /// - /// Converts between feature level and opengl versions - /// - internal static class OpenGLUtils - { -#if STRIDE_GRAPHICS_API_OPENGLES - public static IEnumerable GetGLVersions(GraphicsProfile[] graphicsProfiles) - { - yield return 3; - } - - public static void GetGLVersion(GraphicsProfile graphicsProfile, out int version) - { - switch (graphicsProfile) - { - case GraphicsProfile.Level_9_1: - case GraphicsProfile.Level_9_2: - case GraphicsProfile.Level_9_3: - case GraphicsProfile.Level_10_0: - case GraphicsProfile.Level_10_1: - version = 300; - return; - case GraphicsProfile.Level_11_0: - case GraphicsProfile.Level_11_1: - case GraphicsProfile.Level_11_2: - version = 310; - return; - default: - throw new ArgumentOutOfRangeException("graphicsProfile"); - } - } - - public static GraphicsProfile GetFeatureLevel(int version) - { - if (version >= 310) - return GraphicsProfile.Level_11_0; // missing tessellation and geometry shaders - return GraphicsProfile.Level_10_0; - } -#else - public static void GetGLVersion(GraphicsProfile graphicsProfile, out int version) - { - switch (graphicsProfile) - { - case GraphicsProfile.Level_9_1: - case GraphicsProfile.Level_9_2: - case GraphicsProfile.Level_9_3: - version = 330; - return; - case GraphicsProfile.Level_10_0: - case GraphicsProfile.Level_10_1: - version = 410; - return; - case GraphicsProfile.Level_11_0: - case GraphicsProfile.Level_11_1: - case GraphicsProfile.Level_11_2: - version = 440; - return; - default: - throw new ArgumentOutOfRangeException("graphicsProfile"); - } - } - - public static GraphicsProfile GetFeatureLevel(int version) - { - if (version >= 400) - { - if (version >= 440) - return GraphicsProfile.Level_11_0; - if (version >= 410) - return GraphicsProfile.Level_10_0; - } - return GraphicsProfile.Level_9_1; - } -#endif - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/PipelineState.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/PipelineState.OpenGL.cs deleted file mode 100644 index 4a69a76c11..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/PipelineState.OpenGL.cs +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Collections.Generic; -using Stride.Core; -using Stride.Core.Storage; -using Stride.Shaders; -using Stride.Core.Extensions; - -namespace Stride.Graphics -{ - public partial class PipelineState - { - internal readonly BlendState BlendState; - internal readonly DepthStencilState DepthStencilState; - - internal readonly RasterizerState RasterizerState; - - internal readonly EffectProgram EffectProgram; - - internal readonly PrimitiveTypeGl PrimitiveType; - internal readonly VertexAttrib[] VertexAttribs; - internal ResourceBinder ResourceBinder; - - private PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription pipelineStateDescription) : base(graphicsDevice) - { - // First time, build caches - var pipelineStateCache = GetPipelineStateCache(); - - var depthClampEmulation = !pipelineStateDescription.RasterizerState.DepthClipEnable && !graphicsDevice.HasDepthClamp; - - // Store states - BlendState = new BlendState(pipelineStateDescription.BlendState, pipelineStateDescription.Output.RenderTargetCount > 0); - RasterizerState = new RasterizerState(pipelineStateDescription.RasterizerState); - DepthStencilState = new DepthStencilState(pipelineStateDescription.DepthStencilState, pipelineStateDescription.Output.DepthStencilFormat != PixelFormat.None); - - PrimitiveType = pipelineStateDescription.PrimitiveType.ToOpenGL(); - - // Compile effect - var effectBytecode = pipelineStateDescription.EffectBytecode; - EffectProgram = effectBytecode != null ? pipelineStateCache.EffectProgramCache.Instantiate(Tuple.Create(effectBytecode, depthClampEmulation)) : null; - - var rootSignature = pipelineStateDescription.RootSignature; - if (rootSignature != null && effectBytecode != null) - ResourceBinder.Compile(rootSignature.EffectDescriptorSetReflection, effectBytecode); - - // Vertex attributes - if (pipelineStateDescription.InputElements != null) - { - var vertexAttribs = new List(); - foreach (var inputElement in pipelineStateDescription.InputElements) - { - // Query attribute name from effect - var attributeName = "a_" + inputElement.SemanticName + inputElement.SemanticIndex; - int attributeIndex; - if (!EffectProgram.Attributes.TryGetValue(attributeName, out attributeIndex)) - continue; - - var vertexElementFormat = VertexAttrib.ConvertVertexElementFormat(inputElement.Format); - vertexAttribs.Add(new VertexAttrib( - inputElement.InputSlot, - attributeIndex, - vertexElementFormat.Size, - vertexElementFormat.Type, - vertexElementFormat.Normalized, - inputElement.AlignedByteOffset)); - } - - VertexAttribs = pipelineStateCache.VertexAttribsCache.Instantiate(vertexAttribs.ToArray()); - } - } - - internal void Apply(CommandList commandList, PipelineState previousPipeline) - { - // Apply states - if (BlendState != previousPipeline.BlendState || commandList.NewBlendFactor != commandList.BoundBlendFactor) - BlendState.Apply(commandList, previousPipeline.BlendState); - if (RasterizerState != previousPipeline.RasterizerState) - RasterizerState.Apply(commandList); - if (DepthStencilState != previousPipeline.DepthStencilState || commandList.NewStencilReference != commandList.BoundStencilReference) - DepthStencilState.Apply(commandList); - } - - protected internal override void OnDestroyed(bool immediately = false) - { - var pipelineStateCache = GetPipelineStateCache(); - - if (EffectProgram != null) - pipelineStateCache.EffectProgramCache.Release(EffectProgram); - if (VertexAttribs != null) - pipelineStateCache.VertexAttribsCache.Release(VertexAttribs); - - base.OnDestroyed(immediately); - } - - struct VertexAttribsKey : IEquatable - { - public VertexAttrib[] Attribs; - public int Hash; - - public VertexAttribsKey(VertexAttrib[] attribs) - { - Attribs = attribs; - Hash = ArrayExtensions.ComputeHash(attribs); - } - - public bool Equals(VertexAttribsKey other) - { - return Hash == other.Hash && ArrayExtensions.ArraysEqual(Attribs, other.Attribs); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is VertexAttribsKey vertexAttribsKey && Equals(vertexAttribsKey); - } - - public override int GetHashCode() - { - return Hash; - } - - public static bool operator ==(VertexAttribsKey left, VertexAttribsKey right) - { - return left.Equals(right); - } - - public static bool operator !=(VertexAttribsKey left, VertexAttribsKey right) - { - return !left.Equals(right); - } - } - - // Small helper to cache SharpDX graphics objects - class GraphicsCache - { - private object lockObject = new object(); - - // Store instantiated objects - private readonly Dictionary storage = new Dictionary(); - // Used for quick removal - private readonly Dictionary reverse = new Dictionary(); - - private readonly Dictionary counter = new Dictionary(); - - private readonly Func computeKey; - private readonly Func computeValue; - - public GraphicsCache(Func computeKey, Func computeValue) - { - this.computeKey = computeKey; - this.computeValue = computeValue; - } - - public TValue Instantiate(TSource source) - { - lock (lockObject) - { - TValue value; - var key = computeKey(source); - if (!storage.TryGetValue(key, out value)) - { - value = computeValue(source); - storage.Add(key, value); - reverse.Add(value, key); - counter.Add(value, 1); - } - else - { - counter[value] = counter[value] + 1; - } - - return value; - } - } - - public void Release(TValue value) - { - // Should we remove it from the cache? - lock (lockObject) - { - int refCount; - if (!counter.TryGetValue(value, out refCount)) - return; - - counter[value] = --refCount; - if (refCount == 0) - { - counter.Remove(value); - reverse.Remove(value); - TKey key; - if (reverse.TryGetValue(value, out key)) - { - storage.Remove(key); - } - - var graphicsResource = value as IReferencable; - graphicsResource?.Release(); - } - } - } - - public void Dispose() - { - lock (lockObject) - { - // Release everything - foreach (var entry in reverse) - { - var graphicsResource = entry.Key as IReferencable; - graphicsResource?.Release(); - } - - reverse.Clear(); - storage.Clear(); - counter.Clear(); - } - } - } - - private DevicePipelineStateCache GetPipelineStateCache() - { - return GraphicsDevice.GetOrCreateSharedData(typeof(DevicePipelineStateCache), device => new DevicePipelineStateCache(device)); - } - - // Caches - private class DevicePipelineStateCache : IDisposable - { - public readonly GraphicsCache, EffectBytecode, EffectProgram> EffectProgramCache; - public readonly GraphicsCache VertexAttribsCache; - - public DevicePipelineStateCache(GraphicsDevice graphicsDevice) - { - EffectProgramCache = new GraphicsCache, EffectBytecode, EffectProgram>(source => source.Item1, source => new EffectProgram(graphicsDevice, source.Item1, source.Item2)); - VertexAttribsCache = new GraphicsCache(source => new VertexAttribsKey(source), source => source); - } - - public void Dispose() - { - EffectProgramCache.Dispose(); - VertexAttribsCache.Dispose(); - } - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/QueryPool.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/QueryPool.OpenGL.cs deleted file mode 100644 index cfd9652716..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/QueryPool.OpenGL.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL - -using System; - -namespace Stride.Graphics -{ - public partial class QueryPool - { - internal uint[] NativeQueries; - - public bool TryGetData(long[] dataArray) - { -#if STRIDE_PLATFORM_IOS - return false; -#else - for (var index = 0; index < NativeQueries.Length; index++) - { -#if STRIDE_GRAPHICS_API_OPENGLES - GraphicsDevice.GLExtDisjointTimerQuery.GetQueryObject(NativeQueries[index], QueryObjectParameterName.QueryResultAvailable, out long availability); -#else - GL.GetQueryObject(NativeQueries[index], QueryObjectParameterName.QueryResultAvailable, out long availability); -#endif - if (availability == 0) - return false; - -#if STRIDE_GRAPHICS_API_OPENGLES - GraphicsDevice.GLExtDisjointTimerQuery.GetQueryObject(NativeQueries[index], QueryObjectParameterName.QueryResult, out dataArray[index]); -#else - GL.GetQueryObject(NativeQueries[index], QueryObjectParameterName.QueryResult, out dataArray[index]); -#endif - } - - return true; -#endif - } - - /// - protected internal override void OnDestroyed(bool immediately = false) - { -#if !STRIDE_PLATFORM_IOS - GL.DeleteQueries((uint)QueryCount, NativeQueries); - NativeQueries = null; -#endif - base.OnDestroyed(immediately); - } - - /// - /// Platform-specific implementation that recreates the queries in the pool. - /// - private unsafe partial void Recreate() - { - switch (QueryType) - { - case QueryType.Timestamp: - break; - - default: - throw new NotImplementedException(); - } - - NativeQueries = new uint[QueryCount]; -#if !STRIDE_PLATFORM_IOS - GL.GenQueries((uint)QueryCount, NativeQueries); -#endif - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/RasterizerState.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/RasterizerState.OpenGL.cs deleted file mode 100644 index 107e47b07c..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/RasterizerState.OpenGL.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - struct RasterizerBoundState - { - public bool ScissorTestEnable; - - public bool DepthClamp; - - public bool NeedCulling; - public GLEnum CullMode; - public int DepthBias; - public float SlopeScaleDepthBias; - public FrontFaceDirection FrontFaceDirection; - -#if !STRIDE_GRAPHICS_API_OPENGLES - public PolygonMode PolygonMode; -#endif - } - - class RasterizerState - { - RasterizerBoundState State; - - internal RasterizerState(RasterizerStateDescription rasterizerStateDescription) - { - State.ScissorTestEnable = rasterizerStateDescription.ScissorTestEnable; - - State.DepthClamp = !rasterizerStateDescription.DepthClipEnable; - - State.NeedCulling = rasterizerStateDescription.CullMode != CullMode.None; - State.CullMode = GetCullMode(rasterizerStateDescription.CullMode); - - State.FrontFaceDirection = - rasterizerStateDescription.FrontFaceCounterClockwise - ? FrontFaceDirection.CW - : FrontFaceDirection.Ccw; - - State.DepthBias = rasterizerStateDescription.DepthBias; - State.SlopeScaleDepthBias = rasterizerStateDescription.SlopeScaleDepthBias; - -#if !STRIDE_GRAPHICS_API_OPENGLES - State.PolygonMode = rasterizerStateDescription.FillMode == FillMode.Solid ? PolygonMode.Fill : PolygonMode.Line; -#endif - - // TODO: DepthBiasClamp and various other properties are not fully supported yet - if (rasterizerStateDescription.DepthBiasClamp != 0.0f) throw new NotSupportedException(); - } - - public void Apply(CommandList commandList) - { - var GL = commandList.GL; - -#if !STRIDE_GRAPHICS_API_OPENGLES - if (commandList.RasterizerBoundState.PolygonMode != State.PolygonMode) - { - commandList.RasterizerBoundState.PolygonMode = State.PolygonMode; - GL.PolygonMode(GLEnum.FrontAndBack, State.PolygonMode); - } -#endif - - if (commandList.RasterizerBoundState.DepthBias != State.DepthBias || commandList.RasterizerBoundState.SlopeScaleDepthBias != State.SlopeScaleDepthBias) - { - commandList.RasterizerBoundState.DepthBias = State.DepthBias; - commandList.RasterizerBoundState.SlopeScaleDepthBias = State.SlopeScaleDepthBias; - GL.PolygonOffset(State.DepthBias, State.SlopeScaleDepthBias); - } - - if (commandList.RasterizerBoundState.FrontFaceDirection != State.FrontFaceDirection) - { - commandList.RasterizerBoundState.FrontFaceDirection = State.FrontFaceDirection; - GL.FrontFace(State.FrontFaceDirection); - } - - if (commandList.GraphicsDevice.HasDepthClamp) - { - if (commandList.RasterizerBoundState.DepthClamp != State.DepthClamp) - { - commandList.RasterizerBoundState.DepthClamp = State.DepthClamp; - if (State.DepthClamp) - GL.Enable(EnableCap.DepthClamp); - else - GL.Disable(EnableCap.DepthClamp); - } - } - - if (commandList.RasterizerBoundState.NeedCulling != State.NeedCulling) - { - commandList.RasterizerBoundState.NeedCulling = State.NeedCulling; - if (State.NeedCulling) - { - GL.Enable(EnableCap.CullFace); - } - else - { - GL.Disable(EnableCap.CullFace); - } - } - - if (commandList.RasterizerBoundState.CullMode != State.CullMode) - { - commandList.RasterizerBoundState.CullMode = State.CullMode; - GL.CullFace(State.CullMode); - } - - if (commandList.RasterizerBoundState.ScissorTestEnable != State.ScissorTestEnable) - { - commandList.RasterizerBoundState.ScissorTestEnable = State.ScissorTestEnable; - - if (State.ScissorTestEnable) - GL.Enable(EnableCap.ScissorTest); - else - GL.Disable(EnableCap.ScissorTest); - } - } - - private static GLEnum GetCullMode(CullMode cullMode) - { - switch (cullMode) - { - case CullMode.Front: - return GLEnum.Front; - case CullMode.Back: - return GLEnum.Back; - default: - return GLEnum.Back; // not used if CullMode.None - } - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/SamplerState.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/SamplerState.OpenGL.cs deleted file mode 100644 index 44b6d62c7a..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/SamplerState.OpenGL.cs +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using Stride.Core.Mathematics; - -namespace Stride.Graphics -{ - public partial class SamplerState - { - private const TextureFilter AnisotropicMask = TextureFilter.Anisotropic & ~TextureFilter.Linear; - private const TextureFilter ComparisonMask = TextureFilter.ComparisonLinear & ~TextureFilter.Linear; - - private TextureWrapMode textureWrapS; - private TextureWrapMode textureWrapT; - private TextureWrapMode textureWrapR; - - private TextureMinFilter minFilter; - private TextureMagFilter magFilter; -#if STRIDE_GRAPHICS_API_OPENGLES - private TextureMinFilter minFilterNoMipmap; -#endif - - private int maxAnisotropy; - - private float[] borderColor; - - private DepthFunction compareFunc; - private TextureCompareMode compareMode; - - private SamplerState(GraphicsDevice device, ref readonly SamplerStateDescription samplerStateDescription, string? name = null) - : base(device, name) - { - Description = samplerStateDescription; - - textureWrapS = samplerStateDescription.AddressU.ToOpenGL(); - textureWrapT = samplerStateDescription.AddressV.ToOpenGL(); - textureWrapR = samplerStateDescription.AddressW.ToOpenGL(); - - compareMode = TextureCompareMode.None; - - // ComparisonPoint can act as a mask for Comparison filters (0x80) - if ((samplerStateDescription.Filter & ComparisonMask) != 0) - compareMode = TextureCompareMode.CompareRefToTexture; - - compareFunc = samplerStateDescription.CompareFunction.ToOpenGLDepthFunction(); - borderColor = samplerStateDescription.BorderColor.ToArray(); - // TODO: How to do MipLinear vs MipPoint? - switch (samplerStateDescription.Filter & ~(ComparisonMask | AnisotropicMask)) // Ignore comparison (128) and anisotropic (64) part - { - case TextureFilter.MinMagLinearMipPoint: - minFilter = TextureMinFilter.LinearMipmapNearest; - magFilter = TextureMagFilter.Linear; - break; - case TextureFilter.Linear: - minFilter = TextureMinFilter.LinearMipmapLinear; - magFilter = TextureMagFilter.Linear; - break; - case TextureFilter.MinPointMagMipLinear: - minFilter = TextureMinFilter.NearestMipmapLinear; - magFilter = TextureMagFilter.Linear; - break; - case TextureFilter.Point: - minFilter = TextureMinFilter.NearestMipmapNearest; - magFilter = TextureMagFilter.Nearest; - break; - case TextureFilter.MinPointMagLinearMipPoint: - minFilter = TextureMinFilter.NearestMipmapNearest; - magFilter = TextureMagFilter.Linear; - break; - case TextureFilter.MinLinearMagMipPoint: - minFilter = TextureMinFilter.LinearMipmapNearest; - magFilter = TextureMagFilter.Nearest; - break; - case TextureFilter.MinMagPointMipLinear: - minFilter = TextureMinFilter.NearestMipmapLinear; - magFilter = TextureMagFilter.Nearest; - break; - case TextureFilter.MinLinearMagPointMipLinear: - minFilter = TextureMinFilter.LinearMipmapLinear; - magFilter = TextureMagFilter.Nearest; - break; - default: - throw new NotImplementedException(); - } - - maxAnisotropy = ((samplerStateDescription.Filter & AnisotropicMask) != 0) ? Description.MaxAnisotropy : 1; - -#if STRIDE_GRAPHICS_API_OPENGLES - // On OpenGL ES, we need to choose the appropriate min filter ourself if the texture doesn't contain mipmaps (done at PreDraw) - minFilterNoMipmap = minFilter; - if (minFilterNoMipmap == TextureMinFilter.LinearMipmapLinear) - minFilterNoMipmap = TextureMinFilter.Linear; - else if (minFilterNoMipmap == TextureMinFilter.NearestMipmapLinear) - minFilterNoMipmap = TextureMinFilter.Nearest; -#endif - } - - /// - protected internal override bool OnRecreate() - { - base.OnRecreate(); - return true; - } - - internal void Apply(bool hasMipmap, SamplerState oldSamplerState, TextureTarget target) - { - if (Description.MinMipLevel != oldSamplerState.Description.MinMipLevel) - GL.TexParameter(target, TextureParameterName.TextureMinLod, Description.MinMipLevel); - if (Description.MaxMipLevel != oldSamplerState.Description.MaxMipLevel) - GL.TexParameter(target, TextureParameterName.TextureMaxLod, Description.MaxMipLevel); - if (textureWrapR != oldSamplerState.textureWrapR) - GL.TexParameter(target, TextureParameterName.TextureWrapR, (int)textureWrapR); - if (compareMode != oldSamplerState.compareMode) - GL.TexParameter(target, TextureParameterName.TextureCompareMode, (int)compareMode); - if (compareFunc != oldSamplerState.compareFunc) - GL.TexParameter(target, TextureParameterName.TextureCompareFunc, (int)compareFunc); - -#if !STRIDE_GRAPHICS_API_OPENGLES - if (borderColor != oldSamplerState.borderColor) - GL.TexParameter(target, TextureParameterName.TextureBorderColor, borderColor); - if (Description.MipMapLevelOfDetailBias != oldSamplerState.Description.MipMapLevelOfDetailBias) - GL.TexParameter(target, TextureParameterName.TextureLodBias, Description.MipMapLevelOfDetailBias); - if (minFilter != oldSamplerState.minFilter) - GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)minFilter); -#else - // On OpenGL ES, we need to choose the appropriate min filter ourself if the texture doesn't contain mipmaps (done at PreDraw) - if (minFilter != oldSamplerState.minFilter) - GL.TexParameter(target, TextureParameterName.TextureMinFilter, hasMipmap ? (int)minFilter : (int)minFilterNoMipmap); -#endif - -#if !STRIDE_PLATFORM_IOS - if (maxAnisotropy != oldSamplerState.maxAnisotropy && GraphicsDevice.HasAnisotropicFiltering) - GL.TexParameter(target, (TextureParameterName)SamplerParameterF.TextureMaxAnisotropy, Description.MaxAnisotropy); -#endif - if (magFilter != oldSamplerState.magFilter) - GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)magFilter); - if (textureWrapS != oldSamplerState.textureWrapS) - GL.TexParameter(target, TextureParameterName.TextureWrapS, (int)textureWrapS); - if (textureWrapT != oldSamplerState.textureWrapT) - GL.TexParameter(target, TextureParameterName.TextureWrapT, (int)textureWrapT); - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs deleted file mode 100644 index 79db492cfa..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System.Collections.Generic; -using Rectangle = Stride.Core.Mathematics.Rectangle; -using Window = Stride.Graphics.SDL.Window; -using WindowState = Stride.Graphics.SDL.FormWindowState; - -namespace Stride.Graphics -{ - public class SwapChainGraphicsPresenter : GraphicsPresenter - { - private readonly Texture backBuffer; - private readonly GraphicsDevice graphicsDevice; - private readonly PresentationParameters startingPresentationParameters; - - public SwapChainGraphicsPresenter(GraphicsDevice device, PresentationParameters presentationParameters) : base(device, presentationParameters) - { - graphicsDevice = device; - startingPresentationParameters = presentationParameters; - device.InitDefaultRenderTarget(presentationParameters); - - backBuffer = Texture.New2D(device, Description.BackBufferWidth, Description.BackBufferHeight, presentationParameters.BackBufferFormat, TextureFlags.RenderTarget | TextureFlags.ShaderResource); - } - - public override Texture BackBuffer => backBuffer; - - public override object NativePresenter => null; - - public override bool IsFullScreen - { - get - { - return ((Window)Description.DeviceWindowHandle.NativeWindow).WindowState == WindowState.Fullscreen; - } - set - { - var gameWindow = (Window)Description.DeviceWindowHandle.NativeWindow; - Description.IsFullScreen = value; - if (gameWindow.Exists && value != (gameWindow.WindowState == WindowState.Fullscreen)) - gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; - } - } - - public override void EndDraw(CommandList commandList, bool present) - { - if (present) - { - // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it - commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture, - new Rectangle(0, 0, backBuffer.Width, backBuffer.Height), - new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true); - - // On macOS, `SwapBuffers` will swap whatever framebuffer is active and in our case it is not the window provided - // framebuffer, and in addition if the active framebuffer is single buffered, it won't do anything. Forcing a bind - // will ensure the window is updated. - commandList.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.WindowProvidedFrameBuffer); - commandList.GraphicsDevice.MainGraphicsContext.SwapBuffers(); - } - } - - public override void Present() - { - } - - protected override void ResizeBackBuffer(int width, int height, PixelFormat format) - { - graphicsDevice.OnDestroyed(); - - startingPresentationParameters.BackBufferWidth = width; - startingPresentationParameters.BackBufferHeight = height; - - graphicsDevice.InitDefaultRenderTarget(startingPresentationParameters); - - var newTextureDescrition = backBuffer.Description; - newTextureDescrition.Width = width; - newTextureDescrition.Height = height; - - // Manually update the texture - backBuffer.OnDestroyed(); - - var list = DestroyChildrenTextures(backBuffer); - - // Put it in our back buffer texture - backBuffer.InitializeFrom(newTextureDescrition); - - foreach (var texture in list) - { - texture.InitializeFrom(backBuffer, texture.ViewDescription); - } - } - - protected override void ResizeDepthStencilBuffer(int width, int height, PixelFormat format) - { - var newTextureDescrition = DepthStencilBuffer.Description; - newTextureDescrition.Width = width; - newTextureDescrition.Height = height; - - // Manually update the texture - DepthStencilBuffer.OnDestroyed(); - - var list = DestroyChildrenTextures(DepthStencilBuffer); - - // Put it in our back buffer texture - DepthStencilBuffer.InitializeFrom(newTextureDescrition); - - foreach (var texture in list) - { - texture.InitializeFrom(DepthStencilBuffer, texture.ViewDescription); - } - } - - /// - /// Calls for all children of the specified texture - /// - /// Specified parent texture - /// A list of the children textures which were destroyed - private List DestroyChildrenTextures(Texture parentTexture) - { - var list = new List(); - foreach (var resource in GraphicsDevice.Resources) - { - if (resource is Texture texture && texture.ParentTexture == parentTexture) - { - texture.OnDestroyed(); - list.Add(texture); - } - } - - return list; - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/Texture.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/Texture.OpenGL.cs deleted file mode 100644 index c066fe98ba..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/Texture.OpenGL.cs +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using Stride.Core; -using Stride.Core.Mathematics; - -namespace Stride.Graphics -{ - /// - /// Abstract class for all textures - /// - public unsafe partial class Texture - { - private const int TextureRowPitchAlignment = 1; - private const int TextureSubresourceAlignment = 1; - - internal const TextureFlags TextureFlagsCustomResourceId = (TextureFlags)0x1000; - - internal SamplerState BoundSamplerState; - internal int PixelBufferFrame; - internal int TextureTotalSize; - private uint pixelBufferObjectId; - private uint stencilId; - - internal int DepthPitch { get; set; } - internal int RowPitch { get; set; } - internal bool IsDepthBuffer { get; private set; } // TODO: Isn't this redundant? This gets set to the same value as IsDepthStencil... - internal bool HasStencil { get; private set; } - internal bool IsRenderbuffer { get; private set; } - - internal uint PixelBufferObjectId => pixelBufferObjectId; - - internal uint StencilId => stencilId; - - public static bool IsDepthStencilReadOnlySupported(GraphicsDevice device) - { - // always true on OpenGL - return true; - } - - /// - /// Swaps the Texture's internal data with another Texture. - /// - /// The other Texture. - internal void SwapInternal(Texture other) - { - (other.DepthPitch, DepthPitch) = (DepthPitch, other.DepthPitch); - - (other.RowPitch, RowPitch) = (RowPitch, other.RowPitch); - - (other.IsDepthBuffer, IsDepthBuffer) = (IsDepthBuffer, other.IsDepthBuffer); - - (other.HasStencil, HasStencil) = (HasStencil, other.HasStencil); - - (other.IsRenderbuffer, IsRenderbuffer) = (IsRenderbuffer, other.IsRenderbuffer); - - (BoundSamplerState, other.BoundSamplerState) = (other.BoundSamplerState, BoundSamplerState); - (PixelBufferFrame, other.PixelBufferFrame) = (other.PixelBufferFrame, PixelBufferFrame); - (TextureTotalSize, other.TextureTotalSize) = (other.TextureTotalSize, TextureTotalSize); - (pixelBufferObjectId, other.pixelBufferObjectId) = (other.pixelBufferObjectId, pixelBufferObjectId); - (stencilId, other.stencilId) = (other.stencilId, stencilId); - - (DiscardNextMap, other.DiscardNextMap) = (other.DiscardNextMap, DiscardNextMap); - (TextureId, other.TextureId) = (other.TextureId, TextureId); - (TextureTarget, other.TextureTarget) = (other.TextureTarget, TextureTarget); - (TextureInternalFormat, other.TextureInternalFormat) = (other.TextureInternalFormat, TextureInternalFormat); - (TextureFormat, other.TextureFormat) = (other.TextureFormat, TextureFormat); - (TextureType, other.TextureType) = (other.TextureType, TextureType); - (TexturePixelSize, other.TexturePixelSize) = (other.TexturePixelSize, TexturePixelSize); - } - - public void Recreate(DataBox[] dataBoxes = null) - { - InitializeFromImpl(dataBoxes); - } - - /// - /// Perform OpenGL-specific recreation of the Texture. - /// - private partial void OnRecreateImpl() - { - // Dependency: wait for underlying texture to be recreated - if (ParentTexture != null && ParentTexture.LifetimeState != GraphicsResourceLifetimeState.Active) - return; - - // Render Target / Depth Stencil are considered as "dynamic" - if ((Usage == GraphicsResourceUsage.Immutable - || Usage == GraphicsResourceUsage.Default) - && !IsRenderTarget && !IsDepthStencil) - return; - - if (ParentTexture == null && GraphicsDevice != null) - { - GraphicsDevice.RegisterTextureMemoryUsage(-SizeInBytes); - } - - InitializeFromImpl(); - } - -#if STRIDE_PLATFORM_ANDROID //&& USE_GLES_EXT_OES_TEXTURE - //Prototype: experiment creating GlTextureExternalOes texture - private void InitializeForExternalOESImpl() - { - // TODO: We should probably also set the other parameters if possible, because otherwise we end up with a texture whose metadata says it's of 0x0x0 size and has no format. - - if (TextureId == 0) - { - GL.GenTextures(1, out TextureId); - - //Android.Opengl.GLES20.GlBindTexture(Android.Opengl.GLES11Ext.GlTextureExternalOes, TextureId); - - //Any "proper" way to do this? (GLES20 could directly accept it, not GLES30 anymore) - TextureTarget = (TextureTarget) Android.Opengl.GLES11Ext.GlTextureExternalOes; - GL.BindTexture(TextureTarget, TextureId); - - //GL.BindTexture(TextureTarget, 0); - } - } -#endif - - private TextureTarget GetTextureTarget(TextureDimension dimension) - { - switch (Dimension) - { - case TextureDimension.Texture1D: -#if !STRIDE_GRAPHICS_API_OPENGLES - if (ArraySize > 1) - throw new PlatformNotSupportedException("Texture1DArray is not implemented under OpenGL"); - return TextureTarget.Texture1D; -#endif - case TextureDimension.Texture2D: - return ArraySize > 1 ? TextureTarget.Texture2DArray : TextureTarget.Texture2D; - case TextureDimension.Texture3D: - return TextureTarget.Texture3D; - case TextureDimension.TextureCube: - if (ArraySize > 6) - throw new PlatformNotSupportedException("TextureCubeArray is not implemented under OpenGL"); - return TextureTarget.TextureCubeMap; - } - - throw new ArgumentOutOfRangeException("TextureDimension couldn't be converted to a TextureTarget."); - } - - private void CopyParentAttributes() - { - TextureId = ParentTexture.TextureId; - - TextureInternalFormat = ParentTexture.TextureInternalFormat; - TextureFormat = ParentTexture.TextureFormat; - TextureType = ParentTexture.TextureType; - TextureTarget = ParentTexture.TextureTarget; - DepthPitch = ParentTexture.DepthPitch; - RowPitch = ParentTexture.RowPitch; - IsDepthBuffer = ParentTexture.IsDepthBuffer; - HasStencil = ParentTexture.HasStencil; - IsRenderbuffer = ParentTexture.IsRenderbuffer; - - stencilId = ParentTexture.StencilId; - pixelBufferObjectId = ParentTexture.PixelBufferObjectId; - } - - /// - /// Initializes the Texture from the specified data. - /// - /// - /// An array of structures pointing to the data for all the subresources to - /// initialize for the Texture. - /// - private partial void InitializeFromImpl(DataBox[] dataBoxes) - { - if (ParentTexture != null) - { - CopyParentAttributes(); - } - - if (TextureId == 0) - { - TextureTarget = GetTextureTarget(Dimension); - - OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out TextureInternalFormat, out TextureFormat, out TextureType, out TexturePixelSize, out var compressed); - - DepthPitch = Description.Width * Description.Height * TexturePixelSize; - RowPitch = Description.Width * TexturePixelSize; - - IsDepthBuffer = ((Description.Flags & TextureFlags.DepthStencil) != 0); - if (IsDepthBuffer) - { - HasStencil = InternalHasStencil(Format); - } - else - { - HasStencil = false; - } - - if ((Description.Flags & TextureFlagsCustomResourceId) != 0) - return; - - using (var openglContext = GraphicsDevice.UseOpenGLCreationContext()) - { - TextureTotalSize = ComputeBufferTotalSize(); - - if (Description.Usage == GraphicsResourceUsage.Staging) - { - InitializeStagingPixelBufferObject(dataBoxes); - return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay? - } - - // Depth textures are renderbuffers for now // TODO: PERFORMANCE: Why? I think we should change that so we can sample them directly. - // TODO: enable switch // TODO: What does this comment even mean? - - IsRenderbuffer = !Description.IsShaderResource; - - // Force to renderbuffer if MSAA is on because we don't support MSAA textures ATM (and they don't exist on OpenGL ES). - if (Description.IsMultiSampled) - { - // TODO: Ideally the caller of this method should be aware of this "force to renderbuffer", - // because the caller won't be able to bind it as a texture. - IsRenderbuffer = true; - } - - if (IsRenderbuffer) - { - CreateRenderbuffer(); - return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay? - } - - GL.GenTextures(1, out TextureId); - GL.BindTexture(TextureTarget, TextureId); - SetFilterMode(); - - if (Description.MipLevelCount == 0) - throw new NotImplementedException(); - - var setSize = TextureSetSize(TextureTarget); - - for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex) - { - int offsetArray = arrayIndex * Description.MipLevelCount; - - for (int mipLevel = 0; mipLevel < Description.MipLevelCount; ++mipLevel) - { - DataBox dataBox; - Int3 dimensions = new Int3(CalculateMipSize(Description.Width, mipLevel), - CalculateMipSize(Description.Height, mipLevel), - CalculateMipSize(Description.Depth, mipLevel)); - if (dataBoxes != null && mipLevel < dataBoxes.Length) - { - if (setSize > 1 && !compressed && dataBoxes[mipLevel].RowPitch != dimensions.X * TexturePixelSize) - throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D."); - // Might be possible, need to check API better. - dataBox = dataBoxes[offsetArray + mipLevel]; - } - else - { - dataBox = new DataBox(); - } - - switch (TextureTarget) - { - case TextureTarget.Texture1D: - CreateTexture1D(compressed, dimensions.X, mipLevel, dataBox); - break; - case TextureTarget.Texture2D: - case TextureTarget.TextureCubeMap: - CreateTexture2D(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox); - break; - case TextureTarget.Texture3D: - CreateTexture3D(compressed, dimensions.X, dimensions.Y, dimensions.Z, mipLevel, dataBox); - break; - case TextureTarget.Texture2DArray: - CreateTexture2DArray(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox); - break; - } - } - } - - GL.BindTexture(TextureTarget, 0); // This unbinds the texture. - if (openglContext.CommandList != null) - { - // If we messed up with some states of a command list, mark dirty states - openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null; - } - } - - GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes); - } - } - - private void CreateRenderbuffer() - { - if (Description.IsDepthStencil) // If it is a depth/stencil attachment: - { - ConvertDepthFormat(GraphicsDevice, Description.Format, out var depthRenderbufferFormat); - - CreateRenderbuffer(Width, Height, (int) Description.MultisampleCount, depthRenderbufferFormat, out TextureId); - - if (HasStencil) // If depth and stencil are stored inside the same renderbuffer: - { - stencilId = TextureId; - } - } - else if (Description.IsRenderTarget) // If it is a color attachment: - { - CreateRenderbuffer(Width, Height, (int) Description.MultisampleCount, TextureInternalFormat, out TextureId); - } - else - { - throw new NotSupportedException("Requested renderbuffer is neither a render target nor a depth/stencil attachment."); - } - - GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0); // Unbinds the renderbuffer. - } - - private void SetFilterMode() - { - if (Description.IsDepthStencil || Description.IsRenderTarget) // Set the filtering mode of depth, stencil and color FBO attachments: - { - // Disable filtering on FBO attachments: - GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest); // TODO: Do we enter this for MSAA buffers too? Is this an issue? - GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest); // TODO: Why would we force the filter to "nearest"? - GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge); - GL.TexParameter(TextureTarget, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge); - BoundSamplerState = GraphicsDevice.SamplerStates.PointClamp; - - if (HasStencil) - { - // Since we store depth and stencil in a single texture, we assign the depth buffer's texture ID as the stencil texture ID. - stencilId = TextureId; - } - } -#if STRIDE_GRAPHICS_API_OPENGLES - else if (Description.MipLevelCount <= 1) - { - GL.TexParameter(TextureTarget, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Nearest); // TODO: Why does this use the nearest filter for minification? Using Linear filtering would result in a smoother appearance for minified textures. - GL.TexParameter(TextureTarget, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Linear); - } -#endif - - GL.TexParameter(TextureTarget, TextureParameterName.TextureBaseLevel, 0); - GL.TexParameter(TextureTarget, TextureParameterName.TextureMaxLevel, Description.MipLevelCount - 1); - } - - private void CreateRenderbuffer(int width, int height, int multisampleCount, InternalFormat internalFormat, out uint textureID) - { - GL.GenRenderbuffers(1, out textureID); - GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, textureID); - - if (Description.IsMultiSampled) - { -#if !STRIDE_PLATFORM_IOS - // MSAA is not supported on iOS currently because OpenTK doesn't expose "GL.BlitFramebuffer()" on iOS for some reason. - GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, (uint) multisampleCount, internalFormat, (uint) width, (uint) height); -#endif - } - else - { - GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, internalFormat, (uint) width, (uint) height); - } - } - - private void CreateTexture1D(bool compressed, int width, int mipLevel, DataBox dataBox) - { - // TODO: STABILITY: Since 1D textures are not supported on OpenGL ES, what should we do in this case? Throw an exception? I mean currently we just silently ignore that case on OpenGL ES. -#if !STRIDE_GRAPHICS_API_OPENGLES - if (compressed) - { - GL.CompressedTexImage1D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, border: 0, (uint) dataBox.SlicePitch, (void*) dataBox.DataPointer); - } - else - { - GL.TexImage1D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, border: 0, TextureFormat, TextureType, (void*) dataBox.DataPointer); - } -#endif - } - - private void CreateTexture2D(bool compressed, int width, int height, int mipLevel, int arrayIndex, DataBox dataBox) - { - if (IsMultiSampled) - { - throw new InvalidOperationException("Currently if multisampling is on, a renderbuffer will be created (not a texture) in any case and this code will not be reached." + - "Therefore if this place is reached, it means something went wrong. Once multisampling has been implemented for OpenGL textures, you can remove this exception."); - - if (IsRenderbuffer) - { - GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, (uint) Description.MultisampleCount, TextureInternalFormat, (uint) width, (uint) height); - } - else - { -#if STRIDE_GRAPHICS_API_OPENGLES - throw new NotSupportedException("Multisample textures are not supported on OpenGL ES."); -#else - GL.TexImage2DMultisample(TextureTarget.Texture2DMultisample, (uint) Description.MultisampleCount, TextureInternalFormat, (uint) width, (uint) height, fixedsamplelocations: false); -#endif - } - } - else - { - var dataSetTarget = GetTextureTargetForDataSet2D(TextureTarget, arrayIndex); - if (compressed) - { - GL.CompressedTexImage2D(dataSetTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, border: 0, (uint) dataBox.SlicePitch, (void*) dataBox.DataPointer); - } - else - { - GL.TexImage2D(dataSetTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, border: 0, TextureFormat, TextureType, (void*) dataBox.DataPointer); - } - } - } - - private void CreateTexture3D(bool compressed, int width, int height, int depth, int mipLevel, DataBox dataBox) - { - if (compressed) - { - GL.CompressedTexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) depth, border: 0, (uint) dataBox.SlicePitch, (void*) dataBox.DataPointer); - } - else - { - GL.TexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) depth, border: 0, TextureFormat, TextureType, (void*) dataBox.DataPointer); - } - } - - private void CreateTexture2DArray(bool compressed, int width, int height, int mipLevel, int arrayIndex, DataBox dataBox) - { - // We create all array slices at once, but upload them one by one - if (arrayIndex == 0) - { - if (compressed) - { - GL.CompressedTexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, imageSize: 0, data: null); - } - else - { - GL.TexImage3D(TextureTarget, mipLevel, TextureInternalFormat, (uint) width, (uint) height, (uint) ArraySize, border: 0, TextureFormat, TextureType, null); - } - } - - if (dataBox.DataPointer != IntPtr.Zero) - { - if (compressed) - { - GL.CompressedTexSubImage3D(TextureTarget, mipLevel, xoffset: 0, yoffset: 0, arrayIndex, (uint) width, (uint) height, depth: 1, TextureInternalFormat, (uint) dataBox.SlicePitch, (void*) dataBox.DataPointer); - } - else - { - GL.TexSubImage3D(TextureTarget, mipLevel, xoffset: 0, yoffset: 0, arrayIndex, (uint) width, (uint) height, depth: 1, TextureFormat, TextureType, (void*) dataBox.DataPointer); - } - } - } - - /// - protected internal override void OnDestroyed(bool immediately = false) - { - using (GraphicsDevice.UseOpenGLCreationContext()) - { - if (TextureId != 0 && ParentTexture == null) - { - if (IsRenderbuffer) - GL.DeleteRenderbuffer(TextureId); - else - GL.DeleteTexture(TextureId); - - GraphicsDevice.RegisterTextureMemoryUsage(-SizeInBytes); - } - - if (stencilId != 0) - GL.DeleteRenderbuffer(stencilId); - - if (pixelBufferObjectId != 0) - GL.DeleteBuffer(pixelBufferObjectId); - } - - TextureTotalSize = 0; - TextureId = 0; - stencilId = 0; - pixelBufferObjectId = 0; - - base.OnDestroyed(immediately); - } - - private static void ConvertDepthFormat(GraphicsDevice graphicsDevice, PixelFormat requestedFormat, out InternalFormat depthFormat) - { - switch (requestedFormat) - { - case PixelFormat.D16_UNorm: - depthFormat = InternalFormat.DepthComponent16; - break; - case PixelFormat.D24_UNorm_S8_UInt: - depthFormat = InternalFormat.Depth24Stencil8; - break; - case PixelFormat.D32_Float: - depthFormat = InternalFormat.DepthComponent32; - break; - case PixelFormat.D32_Float_S8X24_UInt: - depthFormat = InternalFormat.Depth32fStencil8; - break; - default: - throw new NotImplementedException(); - } - } - - private static bool InternalHasStencil(PixelFormat format) - { - switch (format) - { - case PixelFormat.D32_Float_S8X24_UInt: - case PixelFormat.R32_Float_X8X24_Typeless: - case PixelFormat.X32_Typeless_G8X24_UInt: - case PixelFormat.D24_UNorm_S8_UInt: - case PixelFormat.R24_UNorm_X8_Typeless: - case PixelFormat.X24_Typeless_G8_UInt: - return true; - default: - return false; - } - } - - internal static bool InternalIsDepthStencilFormat(PixelFormat format) - { - switch (format) - { - case PixelFormat.D16_UNorm: - case PixelFormat.D32_Float: - case PixelFormat.D32_Float_S8X24_UInt: - case PixelFormat.R32_Float_X8X24_Typeless: - case PixelFormat.X32_Typeless_G8X24_UInt: - case PixelFormat.D24_UNorm_S8_UInt: - case PixelFormat.R24_UNorm_X8_Typeless: - case PixelFormat.X24_Typeless_G8_UInt: - return true; - default: - return false; - } - } - - internal static TextureTarget GetTextureTargetForDataSet2D(TextureTarget target, int arrayIndex) - { - // TODO: Proxy from ES 3.1? - if (target == TextureTarget.TextureCubeMap) - return TextureTarget.TextureCubeMapPositiveX + arrayIndex; - return target; - } - - internal static TextureTarget GetTextureTargetForDataSet3D(TextureTarget target) - { - return target; - } - - private static int TextureSetSize(TextureTarget target) - { - // TODO: improve that -#if !STRIDE_GRAPHICS_API_OPENGLES - if (target == TextureTarget.Texture1D) - return 1; -#endif - if (target == TextureTarget.Texture3D || target == TextureTarget.Texture2DArray) - return 3; - return 2; - } - - internal void InternalSetSize(int width, int height) - { - // Set backbuffer actual size - textureDescription.Width = width; - textureDescription.Height = height; - } - - internal static PixelFormat ComputeShaderResourceFormatFromDepthFormat(PixelFormat format) - { - return format; - } - - /// - /// Indicates if the Texture is flipped vertically, i.e. if the rows are ordered bottom-to-top instead of top-to-bottom. - /// - /// if the Texture is flipped; otherwise. - private partial bool IsFlipped() - { - return GraphicsDevice.WindowProvidedRenderTexture == this; - } - - private void InitializeStagingPixelBufferObject(DataBox[] dataBoxes) - { - pixelBufferObjectId = GeneratePixelBufferObject(BufferTargetARB.PixelPackBuffer, PixelStoreParameter.PackAlignment, BufferUsageARB.StreamRead, TextureTotalSize); - UploadInitialData(BufferTargetARB.PixelPackBuffer, dataBoxes); - } - - private unsafe void UploadInitialData(BufferTargetARB bufferTarget, DataBox[] dataBoxes) - { - // Upload initial data - int offset = 0; - var bufferData = IntPtr.Zero; - - if (PixelBufferObjectId != 0) - { - GL.BindBuffer(bufferTarget, PixelBufferObjectId); - bufferData = (IntPtr) GL.MapBufferRange(bufferTarget, IntPtr.Zero, (UIntPtr) TextureTotalSize, MapBufferAccessMask.MapWriteBit | MapBufferAccessMask.MapUnsynchronizedBit); - } - - if (bufferData != IntPtr.Zero) - { - for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex) - { - var offsetArray = arrayIndex * Description.MipLevelCount; - for (int i = 0; i < Description.MipLevelCount; ++i) - { - var data = IntPtr.Zero; - - var width = CalculateMipSize(Description.Width, mipLevel: i); - var height = CalculateMipSize(Description.Height, mipLevel: i); - var depth = CalculateMipSize(Description.Depth, mipLevel: i); - if (dataBoxes != null && i < dataBoxes.Length) - { - data = dataBoxes[offsetArray + i].DataPointer; - } - - if (data != IntPtr.Zero) - { - MemoryUtilities.CopyWithAlignmentFallback((void*) (bufferData + offset), (void*) data, (uint) (width * height * depth * TexturePixelSize)); - } - - offset += width*height*TexturePixelSize; - } - } - - if (PixelBufferObjectId != 0) - { - GL.UnmapBuffer(bufferTarget); - GL.BindBuffer(bufferTarget, 0); - } - } - } - - internal uint GeneratePixelBufferObject(BufferTargetARB target, PixelStoreParameter alignment, BufferUsageARB bufferUsage, int totalSize) - { - - GL.GenBuffers(1, out uint result); - GL.BindBuffer(target, result); - if (RowPitch < 4) - GL.PixelStore(alignment, 1); - GL.BufferData(target, (UIntPtr) totalSize, null, bufferUsage); - GL.BindBuffer(target, 0); - - return result; - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/UseOpenGLCreationContext.cs b/sources/engine/Stride.Graphics/OpenGL/UseOpenGLCreationContext.cs deleted file mode 100644 index fdf4d27139..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/UseOpenGLCreationContext.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; -using System.Linq; -using System.Runtime.InteropServices; -using System.Threading; -using Silk.NET.Core.Contexts; - -namespace Stride.Graphics -{ - /// - /// Used internally to provide a context for async resource creation - /// (such as texture or buffer created on a thread where no context is active). - /// - internal struct UseOpenGLCreationContext : IDisposable - { - public readonly CommandList CommandList; - - private readonly bool useDeviceCreationContext; - private readonly bool needUnbindContext; - - private readonly bool asyncCreationLockTaken; - private readonly object asyncCreationLockObject; - - private readonly IGLContext deviceCreationContext; - private readonly GL GL; - - public bool UseDeviceCreationContext => useDeviceCreationContext; - - public UseOpenGLCreationContext(GraphicsDevice graphicsDevice) - : this() - { - GL = graphicsDevice.GL; - if (graphicsDevice.CurrentGraphicsContext == IntPtr.Zero) - { - needUnbindContext = true; - useDeviceCreationContext = true; - - // Lock, since there is only one deviceCreationContext. - // TODO: Support multiple deviceCreationContext (TLS creation of context was crashing, need to investigate why) - asyncCreationLockObject = graphicsDevice.asyncCreationLockObject; - Monitor.Enter(graphicsDevice.asyncCreationLockObject, ref asyncCreationLockTaken); - - // Bind the context - deviceCreationContext = graphicsDevice.deviceCreationContext; - deviceCreationContext.MakeCurrent(); - } - else - { - // TODO Hardcoded to the fact it uses only one command list, this should be fixed - CommandList = graphicsDevice.InternalMainCommandList; - } - } - - public void Dispose() - { - try - { - if (needUnbindContext) - { - GL.Flush(); - - // Restore graphics context - GraphicsDevice.UnbindGraphicsContext(deviceCreationContext); - } - } - finally - { - // Unlock - if (asyncCreationLockTaken) - { - Monitor.Exit(asyncCreationLockObject); - } - } - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/VertexAttrib.cs b/sources/engine/Stride.Graphics/OpenGL/VertexAttrib.cs deleted file mode 100644 index 6a0adaa8ed..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/VertexAttrib.cs +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_OPENGL -using System; - -namespace Stride.Graphics -{ - internal struct VertexAttrib : IEquatable - { - public readonly int VertexBufferSlot; - public readonly int AttributeIndex; - public readonly int Size; - public readonly bool IsInteger; - public readonly VertexAttribPointerType Type; - public readonly bool Normalized; - public readonly int Offset; - - public VertexAttrib(int vertexBufferSlot, int attributeIndex, int size, VertexAttribPointerType type, bool normalized, int offset) - { - VertexBufferSlot = vertexBufferSlot; - AttributeIndex = attributeIndex; - Size = size; - IsInteger = IsIntegerHelper(type); - Type = type; - Normalized = normalized; - Offset = offset; - } - - public bool Equals(VertexAttrib other) - { - return VertexBufferSlot == other.VertexBufferSlot && AttributeIndex == other.AttributeIndex && Size == other.Size && IsInteger.Equals(other.IsInteger) && Type == other.Type && Normalized.Equals(other.Normalized) && Offset.Equals(other.Offset); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is VertexAttrib && Equals((VertexAttrib) obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = VertexBufferSlot; - hashCode = (hashCode * 397) ^ AttributeIndex; - hashCode = (hashCode * 397) ^ Size; - hashCode = (hashCode * 397) ^ IsInteger.GetHashCode(); - hashCode = (hashCode * 397) ^ (int) Type; - hashCode = (hashCode * 397) ^ Normalized.GetHashCode(); - hashCode = (hashCode * 397) ^ Offset; - return hashCode; - } - } - - public static bool operator ==(VertexAttrib left, VertexAttrib right) - { - return left.Equals(right); - } - - public static bool operator !=(VertexAttrib left, VertexAttrib right) - { - return !left.Equals(right); - } - - private static bool IsIntegerHelper(VertexAttribPointerType type) - { - switch (type) - { - case VertexAttribPointerType.Byte: - case VertexAttribPointerType.UnsignedByte: - case VertexAttribPointerType.Short: - case VertexAttribPointerType.UnsignedShort: - case VertexAttribPointerType.Int: - case VertexAttribPointerType.UnsignedInt: - return true; - default: - return false; - } - } - - internal struct ElementFormat - { - public readonly VertexAttribPointerType Type; - public readonly byte Size; - public readonly bool Normalized; - - public ElementFormat(VertexAttribPointerType type, byte size, bool normalized = false) - { - Type = type; - Size = size; - Normalized = normalized; - } - } - - internal static ElementFormat ConvertVertexElementFormat(PixelFormat format) - { - switch (format) - { - case PixelFormat.R8_SInt: - return new ElementFormat(VertexAttribPointerType.Byte, 1); - case PixelFormat.R8_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 1); - case PixelFormat.R16_SInt: - return new ElementFormat(VertexAttribPointerType.Short, 1); - case PixelFormat.R16_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 1); - case PixelFormat.R32_SInt: - return new ElementFormat(VertexAttribPointerType.Int, 4); - case PixelFormat.R32_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedInt, 4); - case PixelFormat.R8G8_SInt: - return new ElementFormat(VertexAttribPointerType.Byte, 2); - case PixelFormat.R8G8_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 2); - case PixelFormat.R16G16_SInt: - return new ElementFormat(VertexAttribPointerType.Short, 2); - case PixelFormat.R16G16_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 2); - case PixelFormat.R8G8B8A8_SInt: - return new ElementFormat(VertexAttribPointerType.Byte, 4); - case PixelFormat.R8G8B8A8_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 4); - case PixelFormat.R16G16B16A16_SInt: - return new ElementFormat(VertexAttribPointerType.Short, 4); - case PixelFormat.R16G16B16A16_UInt: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 4); - case PixelFormat.R32_Float: - return new ElementFormat(VertexAttribPointerType.Float, 1); - case PixelFormat.R32G32_Float: - return new ElementFormat(VertexAttribPointerType.Float, 2); - case PixelFormat.R32G32B32_Float: - return new ElementFormat(VertexAttribPointerType.Float, 3); - case PixelFormat.R32G32B32A32_Float: - return new ElementFormat(VertexAttribPointerType.Float, 4); - case PixelFormat.R8_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 1, true); - case PixelFormat.R8G8_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 2, true); - case PixelFormat.R8G8B8A8_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedByte, 4, true); - case PixelFormat.R8_SNorm: - return new ElementFormat(VertexAttribPointerType.Byte, 1, true); - case PixelFormat.R8G8_SNorm: - return new ElementFormat(VertexAttribPointerType.Byte, 2, true); - case PixelFormat.R8G8B8A8_SNorm: - return new ElementFormat(VertexAttribPointerType.Byte, 4, true); - case PixelFormat.R16_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 1, true); - case PixelFormat.R16G16_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 2, true); - case PixelFormat.R16G16B16A16_UNorm: - return new ElementFormat(VertexAttribPointerType.UnsignedShort, 4, true); - case PixelFormat.R16_SNorm: - return new ElementFormat(VertexAttribPointerType.Short, 1, true); - case PixelFormat.R16G16_SNorm: - return new ElementFormat(VertexAttribPointerType.Short, 2, true); - case PixelFormat.R16G16B16A16_SNorm: - return new ElementFormat(VertexAttribPointerType.Short, 4, true); -#if STRIDE_GRAPHICS_API_OPENGLES - // HALF_FLOAT for OpenGL ES 2.x (OES extension) - case PixelFormat.R16G16B16A16_Float: - return new ElementFormat((VertexAttribPointerType)0x8D61, 4); // HALF_FLOAT_OES - case PixelFormat.R16G16_Float: - return new ElementFormat((VertexAttribPointerType)0x8D61, 2); // HALF_FLOAT_OES -#else - // HALF_FLOAT for OpenGL and OpenGL ES 3.x (also used for OpenGL ES 2.0 under 3.0 emulator) - case PixelFormat.R16G16B16A16_Float: - return new ElementFormat((VertexAttribPointerType)0x8D61, 4); // HALF_FLOAT - case PixelFormat.R16G16_Float: - return new ElementFormat((VertexAttribPointerType)0x8D61, 2); // HALF_FLOAT -#endif - default: - throw new NotSupportedException(); - } - } - } -} - -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/apply.bat b/sources/engine/Stride.Graphics/OpenGL/apply.bat deleted file mode 100644 index db54ae7118..0000000000 --- a/sources/engine/Stride.Graphics/OpenGL/apply.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off -for %%f in (*.cs) do ( - echo %%f - copy %%f temp.txt - echo #if %1 > %%f - copy %%f+temp.txt %%f - echo. >> %%f - echo #endif >> %%f - del temp.txt -) \ No newline at end of file diff --git a/sources/engine/Stride.Graphics/RenderingSettings.cs b/sources/engine/Stride.Graphics/RenderingSettings.cs index 285b2c6c06..5be4bff557 100644 --- a/sources/engine/Stride.Graphics/RenderingSettings.cs +++ b/sources/engine/Stride.Graphics/RenderingSettings.cs @@ -47,17 +47,6 @@ public enum PreferredGraphicsPlatform /// Direct3D12, - /// - /// OpenGL. - /// - OpenGL, - - /// - /// OpenGL ES. - /// - [Display("OpenGL ES")] - OpenGLES, - /// /// Vulkan /// diff --git a/sources/engine/Stride.Graphics/ResourceBinder.cs b/sources/engine/Stride.Graphics/ResourceBinder.cs index b295aee1d5..6a4cc71e52 100644 --- a/sources/engine/Stride.Graphics/ResourceBinder.cs +++ b/sources/engine/Stride.Graphics/ResourceBinder.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_GRAPHICS_API_DIRECT3D11 || STRIDE_GRAPHICS_API_OPENGL +#if STRIDE_GRAPHICS_API_DIRECT3D11 using System; using System.Collections.Generic; diff --git a/sources/engine/Stride.Graphics/SDL/Window.cs b/sources/engine/Stride.Graphics/SDL/Window.cs index 990ea14792..0a52013937 100644 --- a/sources/engine/Stride.Graphics/SDL/Window.cs +++ b/sources/engine/Stride.Graphics/SDL/Window.cs @@ -52,9 +52,7 @@ public Window(string title) : this(title, IntPtr.Zero) { } public Window(string title, IntPtr parent) { WindowFlags flags = WindowFlags.AllowHighdpi; -#if STRIDE_GRAPHICS_API_OPENGL - flags |= WindowFlags.Opengl; -#elif STRIDE_GRAPHICS_API_VULKAN +#if STRIDE_GRAPHICS_API_VULKAN flags |= WindowFlags.Vulkan; #endif #if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS @@ -68,22 +66,7 @@ public Window(string title, IntPtr parent) { void* parentPtr = parent.ToPointer(); - if (flags.HasFlag(WindowFlags.WindowOpengl)) - { - // SDL doesn't create OpenGL context when using SDL_CreateWindowFrom. - // See https://wiki.libsdl.org/SDL_CreateWindowFrom - // and https://gamedev.stackexchange.com/a/119903. - var dummy = SDL.CreateWindow($"{title} - OpenGL Dummy", 0, 0, 1, 1, (uint)flags); - var addrStr = new IntPtr(dummy).ToString("X"); - SDL.SetHint(Sdl.HintVideoWindowSharePixelFormat, addrStr); - sdlHandle = SDL.CreateWindowFrom(parentPtr); - SDL.SetHint(Sdl.HintVideoWindowSharePixelFormat, string.Empty); - SDL.DestroyWindow(dummy); - } - else - { - sdlHandle = SDL.CreateWindowFrom(parentPtr); - } + sdlHandle = SDL.CreateWindowFrom(parentPtr); } else // no parent window { @@ -372,7 +355,7 @@ public unsafe Size2 ClientSize { get { -#if STRIDE_GRAPHICS_API_OPENGL || STRIDE_GRAPHICS_API_VULKAN +#if STRIDE_GRAPHICS_API_VULKAN int w, h; SDL.GLGetDrawableSize(sdlHandle, &w, &h); return new Size2(w, h); @@ -398,7 +381,7 @@ public unsafe Rectangle ClientRectangle { get { -#if STRIDE_GRAPHICS_API_OPENGL || STRIDE_GRAPHICS_API_VULKAN +#if STRIDE_GRAPHICS_API_VULKAN int w, h; SDL.GLGetDrawableSize(sdlHandle, &w, &h); return new Rectangle(0, 0, w, h); diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index 1fa0d17388..5af33d8787 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -4,6 +4,4 @@ set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe rmdir /s %~dp0obj\ %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGL --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGLES --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/GameSettings.sdgamesettings b/sources/engine/Stride.Graphics/Shaders.Bytecodes/GameSettings.sdgamesettings index 682f13884b..cb58795ef7 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/GameSettings.sdgamesettings +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/GameSettings.sdgamesettings @@ -15,31 +15,9 @@ Defaults: DisplayOrientation: LandscapeRight PreferredGraphicsPlatform: Default Overrides: - - ~Id: 763ecd98-6b47-46b2-b9cf-df108c4e22ad - Platforms: None - SpecificFilter: 10 - Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics - ~Id: 6ebf4062-a5b4-4e49-804d-c1358898525b - DefaultBackBufferWidth: 1280 - DefaultBackBufferHeight: 720 - DefaultGraphicsProfile: Level_9_1 - ColorSpace: Linear - DisplayOrientation: Default - PreferredGraphicsPlatform: OpenGL - - ~Id: 71828ddf-7547-4185-b18f-9c9f6d0d99e5 - Platforms: None - SpecificFilter: 11 - Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics - ~Id: b51ae642-8557-4c3b-a854-b4afaf572914 - DefaultBackBufferWidth: 1280 - DefaultBackBufferHeight: 720 - DefaultGraphicsProfile: Level_9_1 - ColorSpace: Linear - DisplayOrientation: Default - PreferredGraphicsPlatform: OpenGLES - ~Id: e2616dea-4867-4517-afd1-9ec1432228a8 Platforms: None - SpecificFilter: 12 + SpecificFilter: 10 Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics ~Id: f492a7ac-8c55-4191-83c6-768b9e5ba8de DefaultBackBufferWidth: 1280 @@ -59,6 +37,4 @@ PlatformFilters: - ^Mali\-4 - ^Mali\-T6 - ^Mali\-T7 - - Windows-OpenGL - - Windows-OpenGLES - Windows-Vulkan diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGL.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGL.Level_9_1.cs deleted file mode 100644 index df0697ad3b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGL.Level_9_1.cs +++ /dev/null @@ -1,111 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteBatch] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteBatch - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 80, 134, 148, 83, 74, -12, 44, 34, 209, 108, 151, 179, 116, 254, 127, 190, 0, 53, 8, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, -123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, -122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, -10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, -51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, -50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, -52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, -110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, -120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, -32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, -105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, -105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, -10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, -32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, -79, 76, 79, 82, 49, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, -13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 139, 146, 19, 82, 187, 64, 179, 158, 178, 164, 116, 43, 228, 24, 118, 236, 0, 116, 8, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, -52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, -99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, -100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, -32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, -50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, -100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, -88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, -49, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, -10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 50, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, -101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 110, -88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, -102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 51, 41, 41, 32, 60, -61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, -114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, -10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, -105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, -85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGLES.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGLES.Level_9_1.cs deleted file mode 100644 index 645dcf6e75..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.OpenGLES.Level_9_1.cs +++ /dev/null @@ -1,126 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteBatch] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteBatch - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 208, 247, 75, 11, 196, -201, 110, 225, 196, 73, 183, 140, 52, 19, 208, 134, 0, 32, 10, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, -101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, -97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, -108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, -109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, -112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, -59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, -97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, -111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, -76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, -101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, -32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 111, 105, -100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, -10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, -95, 105, 100, 55, 54, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, -32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, -10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, -100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, -95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, -32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, -116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, -111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, -100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, -67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 49, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, -108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, -105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 224, 19, 13, 9, 233, 121, 57, 159, 68, 138, -93, 54, 107, 215, 26, 255, 0, 93, 10, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, -104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, -101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, -114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, -105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, -67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, -68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, -101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, -108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, -32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, -116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, -102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, -87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, -105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, -49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, -111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, -46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, -83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, -50, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, -32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, -97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 102, -108, 111, 97, 116, 40, 49, 41, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 51, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, -80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, -110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, -61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, -48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, -101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, -110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, -40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGL.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGL.Level_9_1.cs deleted file mode 100644 index f48d6b008b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGL.Level_9_1.cs +++ /dev/null @@ -1,115 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteBatch] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteBatch - { - private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 148, 41, 241, 125, 174, -130, 123, 181, 151, 184, 176, 238, 118, 131, 159, 182, 0, 35, 9, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, -123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, -122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, -10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, -51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, -50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, -52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, -110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 118, 101, 99, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 51, 32, 115, 82, 71, -66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 118, 101, 99, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, -49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, -105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, -40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, -10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 97, 95, 67, 79, 76, -79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, -83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 67, -79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, -119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, -95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, -32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, -101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, -10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, -116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, -32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 95, -84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 49, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, -46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 139, 146, 19, 82, 187, 64, 179, -158, 178, 164, 116, 43, 228, 24, 118, 236, 0, 116, 8, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, -119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, -32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, -85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, -32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, -59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, -110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, -79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, -118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, -13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, -105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, -109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 50, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, -119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 44, 32, -48, 46, 48, 44, 32, 49, 46, 48, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, -32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 51, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, -61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, -10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, -95, 105, 100, 55, 54, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, -32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, -67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, -116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, -55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, -10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, -111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, -13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGLES.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGLES.Level_9_1.cs deleted file mode 100644 index e93b600594..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.OpenGLES.Level_9_1.cs +++ /dev/null @@ -1,130 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteBatch] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteBatch - { - private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 60, 42, 160, 115, 141, -214, 189, 184, 219, 116, 101, 151, 222, 16, 36, 171, 0, 14, 11, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, -101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, -97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, -108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, -109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, -112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, -59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, -97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, -111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, -76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, -101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, -32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, -52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 118, 101, 99, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 118, 101, 99, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, -46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, -50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, -112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 97, 95, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, -46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, -105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, -95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, -32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 84, 111, -76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, -59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, -112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, -48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 49, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, -105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 224, 19, 13, 9, 233, 121, 57, 159, 68, 138, 93, 54, 107, 215, 26, 255, 0, 93, 10, 0, 0, 35, 118, 101, 114, 115, 105, 111, -110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, -105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, -111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, -111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, -32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, -108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, -32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, -115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, -118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, -116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, -101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, -111, 97, 116, 40, 49, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, -115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 50, 41, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 32, 45, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, -105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, -109, 112, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 44, 32, 48, 46, 48, 44, 32, 49, 46, 48, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, -32, 48, 46, 53, 32, 43, 32, 48, 46, 53, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 102, 108, 111, 97, 116, 40, 51, 41, 41, -32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, -105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, -32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, -59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, -55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, -95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, -46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGL.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGL.Level_9_1.cs deleted file mode 100644 index 998b44a9ff..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGL.Level_9_1.cs +++ /dev/null @@ -1,99 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteEffect - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, -7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, -7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, -105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, -114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 49, 57, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 53, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, -120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, -56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 10, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 197, 28, -71, 53, 50, 246, 70, 142, 27, 184, 231, 50, 114, 52, 51, 181, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, -17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, -30, 97, 165, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 238, 33, 184, 26, 69, 173, 24, 123, 29, 184, 99, 129, 102, 191, 133, 82, 0, 83, 4, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, -69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, -117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, -59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, -82, 68, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, -73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, -112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, -111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, -32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, -105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, -116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, -95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 255, 65, 160, 172, -5, 189, 11, 161, 93, 123, 136, 1, 31, 128, 144, 127, 0, 127, 5, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, -49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 71, 108, 111, 98, 97, 108, 115, 32, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, -59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, -105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, -97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, -95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, -114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, -32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, -78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, -32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, -84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGLES.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGLES.Level_9_1.cs deleted file mode 100644 index 8bcf70aa33..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.OpenGLES.Level_9_1.cs +++ /dev/null @@ -1,114 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - public partial class SpriteEffect - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, -7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, -7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, -105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, -114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 49, 57, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 53, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, -120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, -56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 10, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 197, 28, -71, 53, 50, 246, 70, 142, 27, 184, 231, 50, 114, 52, 51, 181, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, -17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, -30, 97, 165, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 18, 242, 141, 243, 76, 111, 140, 150, 98, 52, 10, 20, 207, 2, 6, 68, 0, 62, 6, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, -104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, -114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, -59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, -83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, -10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, -112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, -32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 80, -101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, -10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, -82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, -32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 91, 123, 197, 56, 166, 57, 121, 75, 168, 184, 18, 100, 241, 161, 109, 245, 0, 106, 7, 0, 0, 35, 118, 101, 114, -115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, -99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, -105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, -101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, -111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, -97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, -116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 71, 108, 111, 98, 97, 108, 115, 32, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, -117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, -84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, -59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, -69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, -32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 118, 111, -105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, -111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, -117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, -116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, -105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, -105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGL.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGL.Level_9_1.cs deleted file mode 100644 index 93a16c215b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGL.Level_9_1.cs +++ /dev/null @@ -1,88 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [UIEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class UIEffect - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 255, 143, 44, 38, 165, 98, 255, 132, 93, 49, 195, 186, 113, 189, 27, 19, 0, 88, 6, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, -111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, -79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, -110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, -66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, -32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, -32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, -51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, -46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, -95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, -10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, -116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, -48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, -105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, -116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, -121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 231, 65, 242, 28, 74, 157, 40, 30, 151, 168, 231, 220, 148, 235, 19, 47, 0, 112, 5, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, -105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, -116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, -32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, -119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 102, 108, 111, 97, 116, 40, 48, 41, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, -32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, -32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, -73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, -95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, -108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, -80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGLES.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGLES.Level_9_1.cs deleted file mode 100644 index 76ee17c59f..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.OpenGLES.Level_9_1.cs +++ /dev/null @@ -1,103 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [UIEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class UIEffect - { - private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 30, 148, 139, 152, 194, 217, 240, 223, 42, 215, 156, 53, 27, 178, 176, 251, 0, 67, 8, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, -13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, -97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, -112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, -109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, -105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, -101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, -68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, -59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, -111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, -90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, -108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, -116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, -48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, -48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, -46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, -105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 89, 37, 248, 46, 30, 117, 76, 30, -165, 40, 2, 193, 12, 17, 72, 176, 0, 91, 7, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, -117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, -108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, -112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, -101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, -114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, -112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, -104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, -116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, -114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, -111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, -32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, -40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, -101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, -122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 102, 108, 111, 97, 116, 40, 48, 41, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, -69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, -104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, -105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, -40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGL.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGL.Level_9_1.cs deleted file mode 100644 index 776673bded..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGL.Level_9_1.cs +++ /dev/null @@ -1,92 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [UIEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class UIEffect - { - private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 25, 249, 232, 78, 186, 34, 99, 168, 42, 249, 249, 179, 206, 219, 107, 199, 0, 70, 7, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, -111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, -79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 84, 111, 76, -105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 118, 101, 99, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, -32, 118, 101, 99, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, -50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, -32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, -10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, -110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, -100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, -48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, -32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, -53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, -79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, -116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 231, 65, 242, 28, 74, -157, 40, 30, 151, 168, 231, 220, 148, 235, 19, 47, 0, 112, 5, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, -13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, -90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 102, 108, 111, -97, 116, 40, 48, 41, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, -108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, -117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, -117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, -67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, -32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, -116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGLES.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGLES.Level_9_1.cs deleted file mode 100644 index c0f55e7418..0000000000 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.OpenGLES.Level_9_1.cs +++ /dev/null @@ -1,107 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [UIEffect] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class UIEffect - { - private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 226, 118, 12, 26, 253, 74, 166, 51, 241, 98, 139, 242, 74, 86, 31, 132, 0, 49, 9, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, -13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, -97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, -112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, -109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, -105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, -101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, -68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, -59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, -111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, -90, 90, 76, 69, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 118, 101, 99, 52, 32, 115, 82, 71, 66, 97, 41, -13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 118, 101, 99, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, -40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, -10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 53, 32, 61, 32, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, -82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, -79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, -32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, -111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 89, 37, 248, 46, 30, 117, 76, 30, 165, 40, 2, 193, 12, 17, 72, 176, 0, 91, 7, 0, 0, 35, 118, 101, 114, 115, -105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, -105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, -105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, -99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, -32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, -119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, -109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, -83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, -32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, -84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, -97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, -13, 10, 105, 110, 32, 102, 108, 111, 97, 116, 32, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, -115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, -101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 102, 108, 111, 97, 116, 40, 48, 41, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, -10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, -10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 118, 95, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, -110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, -32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, -52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, -55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, -95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, -46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd index c09b8a2944..0adc57e98a 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd @@ -4,6 +4,4 @@ set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe rmdir /s %~dp0obj\ %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGL --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=OpenGLES --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/GameSettings.sdgamesettings b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/GameSettings.sdgamesettings index 7cd223bc15..3030a419d0 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/GameSettings.sdgamesettings +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/GameSettings.sdgamesettings @@ -15,31 +15,9 @@ Defaults: DisplayOrientation: LandscapeRight PreferredGraphicsPlatform: Default Overrides: - - ~Id: 763ecd98-6b47-46b2-b9cf-df108c4e22ad - Platforms: None - SpecificFilter: 10 - Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics - ~Id: 6ebf4062-a5b4-4e49-804d-c1358898525b - DefaultBackBufferWidth: 1280 - DefaultBackBufferHeight: 720 - DefaultGraphicsProfile: Level_9_3 - ColorSpace: Linear - DisplayOrientation: Default - PreferredGraphicsPlatform: OpenGL - - ~Id: 71828ddf-7547-4185-b18f-9c9f6d0d99e5 - Platforms: None - SpecificFilter: 11 - Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics - ~Id: b51ae642-8557-4c3b-a854-b4afaf572914 - DefaultBackBufferWidth: 1280 - DefaultBackBufferHeight: 720 - DefaultGraphicsProfile: Level_9_3 - ColorSpace: Linear - DisplayOrientation: Default - PreferredGraphicsPlatform: OpenGLES - ~Id: e2616dea-4867-4517-afd1-9ec1432228a8 Platforms: None - SpecificFilter: 12 + SpecificFilter: 10 Configuration: !Stride.Graphics.RenderingSettings,Stride.Graphics ~Id: f492a7ac-8c55-4191-83c6-768b9e5ba8de DefaultBackBufferWidth: 1280 @@ -59,6 +37,4 @@ PlatformFilters: - ^Mali\-4 - ^Mali\-T6 - ^Mali\-T7 - - Windows-OpenGL - - Windows-OpenGLES - - Windows-Vulkan \ No newline at end of file + - Windows-Vulkan diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs deleted file mode 100644 index d8dd952d0d..0000000000 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs +++ /dev/null @@ -1,99 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SignedDistanceFieldFontShader] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class SignedDistanceFieldFontShader - { - private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, -100, 101, 114, 1, 42, 59, 59, 143, 216, 91, 194, 71, 107, 170, 157, 209, 113, 123, 223, 11, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, 110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 9, 84, 101, 120, 116, -117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, 180, 232, 16, 46, 222, 107, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 187, 167, 54, 218, 157, 197, 228, 179, 173, 224, 62, 120, 243, 2, 136, 72, 0, 10, 5, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, -49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, -32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, -101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 118, 111, 105, 100, 32, -109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 97, -95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, -116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, -95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, -79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, -42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, -0, 5, 0, 0, 0, 1, 171, 205, 229, 53, 153, 241, 152, 21, 44, 161, 28, 39, 62, 171, 106, 42, 0, 104, 9, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, -95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, -82, 48, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 118, 101, 99, 52, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, -110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, -32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, -97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, -95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, -61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, -105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, -111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 102, 108, 111, 97, 116, 40, 48, 41, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, -120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, -66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, -32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, -102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, -32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, -120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 118, 101, -99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 111, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, -32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 115, 105, 103, 110, 101, 100, 77, -117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, -13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 51, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, -32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, -13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, -32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, -125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs deleted file mode 100644 index c071e504cd..0000000000 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs +++ /dev/null @@ -1,114 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SignedDistanceFieldFontShader] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class SignedDistanceFieldFontShader - { - private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, -100, 101, 114, 1, 42, 59, 59, 143, 216, 91, 194, 71, 107, 170, 157, 209, 113, 123, 223, 11, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, 110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 9, 84, 101, 120, 116, -117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, 180, 232, 16, 46, 222, 107, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 13, 241, 202, 98, 210, 166, 194, 215, 40, 156, 225, 116, 202, 225, 166, 253, 0, 245, 6, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, -48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, -32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, -111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, -108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, -32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, -97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, -50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, -99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, -80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, -10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, -118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, -118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, -85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, -95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, -95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, -61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, -48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, -86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, -13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, -79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, -59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 91, 185, 178, 90, 221, 111, 33, 15, 85, 77, 64, 136, 164, 191, 27, -4, 0, 81, 11, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, -32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, -111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, -114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, -108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, -13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, -114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, -111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, -10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, -105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, -13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, -32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, -79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, -111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, -52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, -108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, -101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, -100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, -100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, -121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, -61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 102, 108, 111, 97, 116, 40, 48, 41, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 59, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, -100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, -32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, -61, 32, 109, 105, 120, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, -115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 111, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, -10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, -115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, -52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, -118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, -111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, -114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, -13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, -111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, -112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, -100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, -83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, -48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs deleted file mode 100644 index 83209d4f46..0000000000 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGL.Level_9_3.cs +++ /dev/null @@ -1,103 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLCORE -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteSignedDistanceFieldFontShader] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class SpriteSignedDistanceFieldFontShader - { - private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -1, 182, 30, 36, 111, 246, 180, 175, 213, 1, 191, 88, 116, 137, 233, 235, 105, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 103, 177, 47, 3, 221, 157, 52, 231, 107, 111, 207, 181, 23, 175, 186, 140, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, -110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, -180, 232, 16, 46, 222, 107, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 54, 143, 26, 116, 195, 105, -197, 185, 153, 45, 212, 51, 162, 232, 171, 142, 0, 106, 5, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, -32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, -109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, -79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, -79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, -48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, -13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, -46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, -59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, -48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, -32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 49, -2, 187, 182, 235, 119, 164, 209, 221, 65, 131, 8, 208, 22, 114, 148, 0, 52, 9, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 52, 49, 48, 13, 10, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, -101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, -100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, 114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, -105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, 111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, -116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 102, 108, -111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, -40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, -111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, -123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 41, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, -48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 115, 97, -109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, -116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, -104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, -116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, -105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 102, 108, 111, 97, 116, 40, 48, 41, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, -97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, -61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, -112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, -97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, -49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, -44, 32, 118, 101, 99, 52, 40, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 118, 101, 99, 52, 40, 48, 44, 32, 48, -44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 111, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, -13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, -117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, -32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, -105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 44, 32, 118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, -48, 46, 102, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, -46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, -117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, -13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, -100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs deleted file mode 100644 index 06271250e2..0000000000 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.OpenGLES.Level_9_3.cs +++ /dev/null @@ -1,118 +0,0 @@ -#if STRIDE_GRAPHICS_API_OPENGLES -//------------------------------------------------------------------------------ -// -// Stride Effect Compiler File Generated: -// Effect [SpriteSignedDistanceFieldFontShader] -// -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Stride.Graphics -{ - internal partial class SpriteSignedDistanceFieldFontShader - { - private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -1, 182, 30, 36, 111, 246, 180, 175, 213, 1, 191, 88, 116, 137, 233, 235, 105, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 103, 177, 47, 3, 221, 157, 52, 231, 107, 111, 207, 181, 23, 175, 186, 140, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, -110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, -180, 232, 16, 46, 222, 107, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 3, 164, 170, 205, 96, 212, -38, 9, 196, 208, 133, 38, 72, 208, 185, 170, 0, 85, 7, 0, 0, 35, 118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, -105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, -114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, -109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, -111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, -112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, -108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, -13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, -99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, -99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, -10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, -80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, -101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 115, 116, 100, 49, 52, 48, 41, 32, 32, 117, 110, 105, 102, 111, 114, 109, 32, 80, 101, 114, 68, 114, 97, 119, 32, 123, 13, 10, 32, 32, 32, 32, 109, 97, 116, 52, -32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 111, 117, 116, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, -76, 79, 82, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 105, 110, 32, 118, 101, 99, 52, 32, 97, 95, 67, 79, 76, -79, 82, 48, 59, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 97, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, -10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 32, 61, 32, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 42, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, -85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 103, -108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 32, 61, 32, -95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 95, 67, 79, 76, 79, 82, 48, 32, 61, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, -13, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 122, 32, 42, 32, 50, 46, 48, 32, 45, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 119, 59, 13, 10, 32, 32, 32, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 32, 61, 32, 45, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 46, 121, 59, 13, 10, 125, 13, 10, 0, 5, 0, 0, 0, 1, 234, 231, 203, 197, 200, 208, 181, 126, 130, 235, 83, 226, 241, 23, 141, 48, 0, 29, 11, 0, 0, 35, -118, 101, 114, 115, 105, 111, 110, 32, 51, 48, 48, 32, 101, 115, 13, 10, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 102, 108, 111, 97, 116, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 104, 105, 103, 104, 112, 32, 105, 110, 116, 59, 13, 10, -112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, -101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, -114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, -10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, -115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, -110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 59, 13, 10, 112, 114, 101, 99, 105, 115, 105, 111, 110, 32, 108, 111, 119, 112, -32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 59, 13, 10, 13, 10, 35, 100, 101, 102, 105, 110, 101, 32, 116, 101, 120, 101, 108, 70, 101, 116, 99, 104, 66, 117, 102, 102, 101, 114, 80, 108, 97, 99, 101, 104, 111, 108, 100, 101, 114, 13, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, -32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 118, 101, 99, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 59, 13, 10, 117, 110, 105, 102, 111, -114, 109, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 108, 97, 121, 111, 117, 116, 40, 108, 111, 99, 97, 116, 105, 111, 110, 32, 61, 32, 48, 41, 32, 32, -111, 117, 116, 32, 118, 101, 99, 52, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 105, 110, 32, 118, 101, 99, 50, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, -10, 105, 110, 32, 118, 101, 99, 52, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, -10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 70, 111, 110, 116, 67, -111, 108, 111, 114, 95, 105, 100, 52, 40, 118, 101, 99, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, -111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, -110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, -116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, -98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, -111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, -116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 102, 108, 111, 97, 116, 40, 48, 41, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, -97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 102, 108, 111, 97, 116, 40, 50, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, -68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, -115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 98, -111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 32, 61, 32, 109, 105, 120, 40, 118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 118, 101, 99, 52, 40, 111, 112, 97, 99, 105, 116, 121, 41, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 101, 120, 116, 117, 114, 101, 40, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 95, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 118, 101, 99, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, -32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, -52, 44, 32, 118, 101, 99, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, 48, 46, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 109, 97, 105, 110, 40, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 48, 105, 110, 112, -117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 118, 95, 67, 79, 76, 79, 82, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 103, 108, 95, -70, 114, 97, 103, 67, 111, 111, 114, 100, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, -32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 48, 105, 110, 112, 117, 116, 95, 48, 46, 67, 111, -108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, -32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 59, 13, 10, 32, 32, 32, 32, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 95, 48, 111, 117, -116, 112, 117, 116, 95, 48, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 13, 10, - }; - } -} -#endif diff --git a/sources/engine/Stride.Graphics/Stride.Graphics.csproj b/sources/engine/Stride.Graphics/Stride.Graphics.csproj index 62f2fe13d1..36a024ac01 100644 --- a/sources/engine/Stride.Graphics/Stride.Graphics.csproj +++ b/sources/engine/Stride.Graphics/Stride.Graphics.csproj @@ -49,9 +49,6 @@ - - - diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs index 83c0132433..0fdea740fb 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs @@ -97,7 +97,7 @@ internal class GraphicsAdapterFactoryInstance : IDisposable internal VkInstanceApi NativeInstanceApi; internal bool HasXlibSurfaceSupport; - // We use GraphicsDevice (similar to OpenGL) + // We use GraphicsDevice name as logger private static readonly Logger Log = GlobalLogger.GetLogger("GraphicsDevice"); public unsafe GraphicsAdapterFactoryInstance(bool enableValidation) diff --git a/sources/engine/Stride.Graphics/build/Stride.Graphics.targets b/sources/engine/Stride.Graphics/build/Stride.Graphics.targets index 36756266aa..a81674e429 100644 --- a/sources/engine/Stride.Graphics/build/Stride.Graphics.targets +++ b/sources/engine/Stride.Graphics/build/Stride.Graphics.targets @@ -4,9 +4,9 @@ Direct3D11 Direct3D11 - OpenGLES - OpenGLES - OpenGL + Vulkan + Vulkan + Vulkan Vulkan $(StrideDefaultGraphicsApi) diff --git a/sources/engine/Stride.Particles/Shaders.Bytecodes/GameSettings.sdgamesettings b/sources/engine/Stride.Particles/Shaders.Bytecodes/GameSettings.sdgamesettings index 36fb5a77a1..6e14a0541a 100644 --- a/sources/engine/Stride.Particles/Shaders.Bytecodes/GameSettings.sdgamesettings +++ b/sources/engine/Stride.Particles/Shaders.Bytecodes/GameSettings.sdgamesettings @@ -9,7 +9,3 @@ TextureQuality: Fast Profiles: Windows: !WindowsGameSettingsProfile GraphicsPlatform: Direct3D11 - Windows-OpenGL: !WindowsGameSettingsProfile - GraphicsPlatform: OpenGL - Windows-OpenGLES: !WindowsGameSettingsProfile - GraphicsPlatform: OpenGLES diff --git a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolver.cs b/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolver.cs index 4f0bd280ac..9db8afc172 100644 --- a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolver.cs +++ b/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolver.cs @@ -162,14 +162,7 @@ protected override void DrawCore(RenderDrawContext drawContext) var svPosUnpack = new Vector4(0.5f * inputSize.Width, -0.5f * inputSize.Height, 0.5f * inputSize.Width, 0.5f * inputSize.Height); var textureSizeLess1 = new Vector2(inputSize.Width - 1.0f, inputSize.Height - 1.0f); - if (GraphicsDevice.Platform == GraphicsPlatform.OpenGL || - GraphicsDevice.Platform == GraphicsPlatform.OpenGLES || - FilterType == FilterTypes.Default) - { - // We currently only support the default hardware MSAA resolve on OpenGL and OpenGL ES. - drawContext.CommandList.CopyMultisample(input, 0, output, 0); - } - else if (input.IsDepthStencil) + if (input.IsDepthStencil) { System.Diagnostics.Debug.Assert(output.IsDepthStencil, "input and output IsDepthStencil don't match"); diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl index 85b3ca5762..2b386e4535 100644 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl @@ -15,7 +15,7 @@ namespace Stride.Rendering.Materials override float3 Compute(float3 specularColor, float alphaR, float nDotV) { float glossiness = 1.0f - sqrt(alphaR); -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 || STRIDE_GRAPHICS_API_OPENGL +#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 // SampleLevel doesn't work on D3D feature level 9 float4 environmentLightingDFG = EnvironmentLightingDFG_LUT.SampleLevel(LinearSampler, float2(glossiness, nDotV), 0); #else diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl b/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl index 85e878c077..b721e8b936 100644 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl @@ -45,12 +45,8 @@ shader Utilities return specularColor + (max(specularColor, gloss) - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; } - // flip the texture coordinate if on an opengl device. + // flip the texture coordinate if on an opengl device (since OpenGL is not supported anymore, do nothing) static float2 ConvertTexCoord(float2 texcoord) { -#ifdef STRIDE_GRAPHICS_API_OPENGL - return float2(texcoord.x, 1.0f - texcoord.y); -#else return texcoord; -#endif } }; diff --git a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs index 9ac4cd435f..0dd8031a90 100644 --- a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs @@ -116,14 +116,6 @@ public override TaskOrResult Compile(ShaderMixinSo shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_DIRECT3D", 1); shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_DIRECT3D12", 1); break; - case GraphicsPlatform.OpenGL: - shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_OPENGL", 1); - shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_OPENGLCORE", 1); - break; - case GraphicsPlatform.OpenGLES: - shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_OPENGL", 1); - shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_OPENGLES", 1); - break; case GraphicsPlatform.Vulkan: shaderMixinSource.AddMacro("STRIDE_GRAPHICS_API_VULKAN", 1); break; @@ -209,8 +201,6 @@ public override TaskOrResult Compile(ShaderMixinSo compiler = new Direct3D.ShaderCompiler(); break; #endif - case GraphicsPlatform.OpenGL: - case GraphicsPlatform.OpenGLES: case GraphicsPlatform.Vulkan: compiler = new OpenGL.ShaderCompiler(); break; @@ -223,12 +213,6 @@ public override TaskOrResult Compile(ShaderMixinSo #if STRIDE_PLATFORM_DESKTOP var stageStringBuilder = new StringBuilder(); #endif - // if the shader (non-compute) does not have a pixel shader, we should add it for OpenGL and OpenGL ES. - if ((effectParameters.Platform == GraphicsPlatform.OpenGL || effectParameters.Platform == GraphicsPlatform.OpenGLES) && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Pixel) && !parsingResult.EntryPoints.ContainsKey(ShaderStage.Compute)) - { - parsingResult.EntryPoints.Add(ShaderStage.Pixel, null); - } - foreach (var stageBinding in parsingResult.EntryPoints) { // Compile diff --git a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs index 18ca0d8d9a..c6625e6db3 100644 --- a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs @@ -55,14 +55,6 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad switch (effectParameters.Platform) { - case GraphicsPlatform.OpenGL: - shaderPlatform = GlslShaderPlatform.OpenGL; - shaderVersion = 410; - break; - case GraphicsPlatform.OpenGLES: - shaderPlatform = GlslShaderPlatform.OpenGLES; - shaderVersion = 300; - break; case GraphicsPlatform.Vulkan: shaderPlatform = GlslShaderPlatform.Vulkan; shaderVersion = 450; @@ -76,19 +68,6 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad if (shader == null) return shaderBytecodeResult; - if (effectParameters.Platform == GraphicsPlatform.OpenGLES) // TODO: Add check to run on android only. The current version breaks OpenGL ES on windows. - { - //TODO: Remove this ugly hack! - if (shaderSource.Contains($"Texture2D StrideInternal_TextureExt0") && shader.Contains("uniform sampler2D")) - { - if (shaderPlatform != GlslShaderPlatform.OpenGLES || shaderVersion != 300) - throw new Exception("Invalid GLES platform or version: require OpenGLES 300"); - - shader = shader.Replace("uniform sampler2D", "uniform samplerExternalOES"); - shader = shader.Replace("#version 300 es", "#version 300 es\n#extension GL_OES_EGL_image_external_essl3 : require"); - } - } - if (effectParameters.Platform == GraphicsPlatform.Vulkan) { string inputFileExtension; diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs b/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs index a28366d0fa..d118800e1a 100644 --- a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs +++ b/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs @@ -48,7 +48,7 @@ public void TestMaterial() compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shading")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Transformation")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Utils")); - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.OpenGL); + var compilerParameters = CreateCompilerParameters(GraphicsPlatform.Direct3D11); var layers = new MaterialBlendLayers(); layers.Add(new MaterialBlendLayer @@ -232,43 +232,6 @@ private void TestNoClean(out CompilerResults left, out CompilerResults right) } } - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestGlslCompiler() - { - VirtualFileSystem.RemountFileSystem("/shaders", "../../../../shaders"); - VirtualFileSystem.RemountFileSystem("/baseShaders", "../../../../engine/Stride.Graphics/Shaders"); - VirtualFileSystem.RemountFileSystem("/compiler", "Compiler"); - - - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider); - - compiler.SourceDirectories.Add("shaders"); - compiler.SourceDirectories.Add("compiler"); - compiler.SourceDirectories.Add("baseShaders"); - - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.OpenGL); - - var results = compiler.Compile(new ShaderMixinGeneratorSource("ToGlslEffect"), compilerParameters); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestGlslESCompiler() - { - VirtualFileSystem.RemountFileSystem("/shaders", "../../../../shaders"); - VirtualFileSystem.RemountFileSystem("/baseShaders", "../../../../engine/Stride.Graphics/Shaders"); - VirtualFileSystem.RemountFileSystem("/compiler", "Compiler"); - - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider); - - compiler.SourceDirectories.Add("shaders"); - compiler.SourceDirectories.Add("compiler"); - compiler.SourceDirectories.Add("baseShaders"); - - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.OpenGLES); - - var results = compiler.Compile(new ShaderMixinGeneratorSource("ToGlslEffect"), compilerParameters); - } - /// /// Creates the compiler parameters for the specified graphics platform. diff --git a/sources/engine/Stride/Graphics/DDSHelper.cs b/sources/engine/Stride/Graphics/DDSHelper.cs index 462a751719..041048cc8c 100644 --- a/sources/engine/Stride/Graphics/DDSHelper.cs +++ b/sources/engine/Stride/Graphics/DDSHelper.cs @@ -988,11 +988,6 @@ public static unsafe Image LoadFromDDSMemory(IntPtr pSource, int size, bool make { var flags = makeACopy ? DDSFlags.CopyMemory : DDSFlags.None; -#if STRIDE_PLATFORM_ANDROID - // Directly load image as RGBA instead of BGRA, because OpenGL ES devices don't support it out of the box (extension). - flags |= DDSFlags.ForceRgb; -#endif - ConversionFlags convFlags; ImageDescription mdata; // If the memory pointed is not a DDS memory, return null. diff --git a/sources/engine/Stride/Graphics/GraphicsPlatform.cs b/sources/engine/Stride/Graphics/GraphicsPlatform.cs index 7fbf2ec1fc..15e4c9b592 100644 --- a/sources/engine/Stride/Graphics/GraphicsPlatform.cs +++ b/sources/engine/Stride/Graphics/GraphicsPlatform.cs @@ -25,16 +25,6 @@ public enum GraphicsPlatform /// Direct3D12, - /// - /// GLSL OpenGL Shader. - /// - OpenGL, - - /// - /// GLSL OpenGL ES Shader. - /// - OpenGLES, - /// /// GLSL/SPIR-V Shader. /// diff --git a/sources/engine/Stride/Graphics/GraphicsProfile.cs b/sources/engine/Stride/Graphics/GraphicsProfile.cs index 87415c1d68..4f399cc2a9 100644 --- a/sources/engine/Stride/Graphics/GraphicsProfile.cs +++ b/sources/engine/Stride/Graphics/GraphicsProfile.cs @@ -12,7 +12,7 @@ namespace Stride.Graphics; /// /// The graphics profile only indicates which capabilities are available on the device, not which /// graphics API is used. For example, a Graphics Device with a -/// supports Direct3D 10.0, Direct3D 10.1, and Direct3D 11.0 APIs, as well as OpenGL ES 3.0. +/// supports Direct3D 10.0, Direct3D 10.1, and Direct3D 11.0 APIs. /// /// /// Some platforms may not support all graphics profiles, or may have additional restrictions. @@ -25,58 +25,58 @@ public enum GraphicsProfile { /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 9.0a (HLSL 3.0), - /// OpenGL ES 2.0, or Vulkan 1.0. + /// or Vulkan 1.0. /// - [Display("Level 9.1 ~ like Direct3D 9.0 / OpenGL ES 2.0 / Vulkan 1.0")] + [Display("Level 9.1 ~ like Direct3D 9.0 / Vulkan 1.0")] Level_9_1 = 0x9100, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 9.0b (HLSL 3.0), - /// OpenGL ES 2.0, or Vulkan 1.0. + /// or Vulkan 1.0. /// - [Display("Level 9.2 ~ like Direct3D 9.0b / OpenGL ES 2.0 / Vulkan 1.0")] + [Display("Level 9.2 ~ like Direct3D 9.0b / Vulkan 1.0")] Level_9_2 = 0x9200, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 9.0c (HLSL 3.0), - /// OpenGL ES 2.0, or Vulkan 1.0. + /// or Vulkan 1.0. /// - [Display("Level 9.3 ~ like Direct3D 9.0c / OpenGL ES 2.0 / Vulkan 1.0")] + [Display("Level 9.3 ~ like Direct3D 9.0c / Vulkan 1.0")] Level_9_3 = 0x9300, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 10 - /// (HLSL 4.0, Geometry Shaders), OpenGL ES 3.0, or Vulkan 1.0. + /// (HLSL 4.0, Geometry Shaders), or Vulkan 1.0. /// - [Display("Level 10.0 ~ like Direct3D 10.0 / OpenGL ES 3.0 / Vulkan 1.0")] + [Display("Level 10.0 ~ like Direct3D 10.0 / Vulkan 1.0")] Level_10_0 = 0xA000, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 10.1 - /// (HLSL 4.1, Geometry Shaders), OpenGL ES 3.0, or Vulkan 1.0. + /// (HLSL 4.1, Geometry Shaders), or Vulkan 1.0. /// - [Display("Level 10.1 ~ like Direct3D 10.1 / OpenGL ES 3.0 / Vulkan 1.0")] + [Display("Level 10.1 ~ like Direct3D 10.1 / Vulkan 1.0")] Level_10_1 = 0xA100, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 11 - /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), OpenGL ES 3.1, or Vulkan 1.1. + /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), or Vulkan 1.1. /// - [Display("Level 11.0 ~ like Direct3D 11.0 / OpenGL ES 3.1 / Vulkan 1.1")] + [Display("Level 11.0 ~ like Direct3D 11.0 / Vulkan 1.1")] Level_11_0 = 0xB000, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 11.1 - /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), OpenGL ES 3.1, or Vulkan 1.1. + /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), or Vulkan 1.1. /// - [Display("Level 11.1 ~ like Direct3D 11.1 / OpenGL ES 3.1 / Vulkan 1.1")] + [Display("Level 11.1 ~ like Direct3D 11.1 / Vulkan 1.1")] Level_11_1 = 0xB100, /// /// Identifies Graphics Devices with capabilities roughly at the level of DirectX 11.2 - /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), OpenGL ES 3.1, or Vulkan 1.1. + /// (HLSL 5.0, Compute Shaders, Domain Shaders, Hull Shaders), or Vulkan 1.1. /// - [Display("Level 11.2 ~ like Direct3D 11.2 / OpenGL ES 3.1 / Vulkan 1.1")] + [Display("Level 11.2 ~ like Direct3D 11.2 / Vulkan 1.1")] Level_11_2 = 0xB200 // Future? diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index 04f63e50d2..ebbc034e8c 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -10,9 +10,7 @@ $(StrideGraphicsApisTest) - OpenGL;Vulkan - OpenGL - Direct3D11;Direct3D12;OpenGL;OpenGLES;Vulkan + Direct3D11;Direct3D12;Vulkan Direct3D11 diff --git a/sources/targets/Stride.props b/sources/targets/Stride.props index 9396a818e1..9ac752a5f1 100644 --- a/sources/targets/Stride.props +++ b/sources/targets/Stride.props @@ -17,12 +17,12 @@ the active one that Visual Studio and IntelliSense takes into account --> - Direct3D11;Direct3D12;OpenGL;OpenGLES;Vulkan + Direct3D11;Direct3D12;Vulkan $(StrideGraphicsApis.Split(';', StringSplitOptions.RemoveEmptyEntries)[0]) Direct3D11 - OpenGLES - OpenGLES + Vulkan + Vulkan @@ -53,14 +53,6 @@ STRIDE_GRAPHICS_API_NULL - - STRIDE_GRAPHICS_API_OPENGL;STRIDE_GRAPHICS_API_OPENGLCORE - - - - STRIDE_GRAPHICS_API_OPENGL;STRIDE_GRAPHICS_API_OPENGLES - - STRIDE_GRAPHICS_API_VULKAN diff --git a/sources/targets/Stride.targets b/sources/targets/Stride.targets index d134619876..90b29bb075 100644 --- a/sources/targets/Stride.targets +++ b/sources/targets/Stride.targets @@ -24,14 +24,6 @@ STRIDE_GRAPHICS_API_NULL - - STRIDE_GRAPHICS_API_OPENGL;STRIDE_GRAPHICS_API_OPENGLCORE - - - - STRIDE_GRAPHICS_API_OPENGL;STRIDE_GRAPHICS_API_OPENGLES - - STRIDE_GRAPHICS_API_VULKAN From d84339d99ee1254201a7bc16e922c380270dcafb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 23:42:11 +0900 Subject: [PATCH 0802/1182] EffectCodeWriter: remove dependency to Stride LoggerResult --- .../EffectCodeWriter.cs | 28 ++++++++----------- .../Parsing/Scanners/TextLocation.cs | 8 ------ 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/Stride.Shaders.Generators/EffectCodeWriter.cs b/src/Stride.Shaders.Generators/EffectCodeWriter.cs index 9a66eb6152..65be69f2be 100644 --- a/src/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/src/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -1,4 +1,3 @@ -using Stride.Core.Shaders.Utility; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDFX.AST; @@ -12,7 +11,7 @@ public class EffectCodeWriter : ShaderWriter { private const string DefaultNameSpace = "Stride.Rendering"; - private readonly LoggerResult logging = new(); + private readonly List<(string Message, TextLocation Location)> logging = new(); private Stack contextStack = new(); private Dictionary blockContexts = new(); private BlockStatement currentBlock; @@ -24,19 +23,16 @@ public bool Run(Node node) { void LogErrors() { - foreach (var reportMessage in logging.Messages) + foreach (var reportMessage in logging) { - if (reportMessage.Level == ReportMessageLevel.Error) - { - Write("#error ").WriteLine(reportMessage.ToString()); - } + Write("#error ").WriteLine(reportMessage.ToString()); } } - var blockVisitor = new ShaderBlockVisitor(this, logging); + var blockVisitor = new ShaderBlockVisitor(this); blockVisitor.VisitNode(node); - if (logging.HasErrors) + if (logging.Count > 0) { LogErrors(); return false; @@ -74,7 +70,7 @@ void LogErrors() VisitNode(node); // If there are any errors log them into the shader - if (logging.HasErrors) + if (logging.Count > 0) { LogErrors(); return false; @@ -509,7 +505,7 @@ public override void VisitMixin(Mixin mixinStatement) var variableReference = mixinStatement.Value as AccessorChainExpression; if (variableReference == null || !(variableReference.Source is Identifier id) || !IsParameterDeclaredInContext(id.Name)) { - logging.Error("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info.ToSourceSpan()); + logging.Add(("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info)); macroName = new StringLiteral("#INVALID_MACRO_NAME", default); macroValue = mixinStatement.Value; } @@ -532,7 +528,7 @@ public override void VisitMixin(Mixin mixinStatement) { if (mixinStatement.Target == null) { - logging.Error("Expecting assign expression for composition", mixinStatement.Value.Info.ToSourceSpan()); + logging.Add(("Expecting assign expression for composition", mixinStatement.Value.Info)); return; } @@ -590,7 +586,7 @@ public override void VisitUsingParams(UsingParams usingParametersStatement) { if (contextStack.Count == 0) { - logging.Error("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Info.ToSourceSpan()); + logging.Add(("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Info)); return; } @@ -603,7 +599,7 @@ public override void VisitUsingParams(UsingParams usingParametersStatement) var typeName = type.ToString(); if (usings.Contains(typeName)) { - logging.Error("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Info.ToSourceSpan()); + logging.Add(("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Info)); return; } @@ -708,15 +704,13 @@ private class ShaderBlockContext /// private sealed class ShaderBlockVisitor : NodeWalker { - private readonly LoggerResult logging; private ShaderBlockContext currentContext; private readonly EffectCodeWriter parent; - public ShaderBlockVisitor(EffectCodeWriter parent, LoggerResult logging) + public ShaderBlockVisitor(EffectCodeWriter parent) { this.parent = parent; - this.logging = logging; } public bool HasMixin { get; private set; } diff --git a/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs b/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs index 0a40971a23..0223a997aa 100644 --- a/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs +++ b/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs @@ -1,6 +1,4 @@ using CommunityToolkit.HighPerformance.Buffers; -using Stride.Core.Shaders.Ast; - namespace Stride.Shaders.Parsing; public record struct TextLocation(ReadOnlyMemory Original, Range Range) @@ -18,12 +16,6 @@ public readonly override string ToString() { return $"[l{Line}-c{Column}]\n{Text.Span}"; } - - public SourceSpan ToSourceSpan() - { - // Not exact, but it's temporary anyway - return new SourceSpan(new SourceLocation(0, Line, Column), 0); - } } public static class SpanCharExtensions From d97d3dc94ff852652d1de01053da76f71c612b02 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 23:43:03 +0900 Subject: [PATCH 0803/1182] Experiments: add basePath in ShaderLoader for easier testing complex ShaderSource (using ToCode()) --- src/Stride.Shaders.Experiments/Examples.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stride.Shaders.Experiments/Examples.cs b/src/Stride.Shaders.Experiments/Examples.cs index 280c396149..63b20628a5 100644 --- a/src/Stride.Shaders.Experiments/Examples.cs +++ b/src/Stride.Shaders.Experiments/Examples.cs @@ -210,17 +210,17 @@ static bool ComputeIntersection(TextPosition position, Node node, out Node n) return false; } - public class ShaderLoader() : ShaderLoaderBase(new ShaderCache()) + public class ShaderLoader(string basePath) : ShaderLoaderBase(new ShaderCache()) { protected override bool ExternalFileExists(string name) { - var filename = $"./assets/SDSL/{name}.sdsl"; + var filename = $"{basePath}/{name}.sdsl"; return File.Exists(filename); } public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { - filename = $"./assets/SDSL/{name}.sdsl"; + filename = $"{basePath}/{name}.sdsl"; var fileData = File.ReadAllBytes(filename); hash = ObjectId.FromBytes(fileData); From b5b52dad62549751d62e1c9001c6c943d3585227 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 23:43:42 +0900 Subject: [PATCH 0804/1182] ShaderSource evaluator: fixed special case when a ShaderSource is inherited first as stage then non-stage --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 0dc0e3f60f..333bcec863 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -75,14 +75,11 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con { // Special case: the current stage-only mixin is planned to be added later as a normal mixin at the root level // It's a bit complex: we need to inherit from it right now instead of later - // (if we simply do a result.Mixins.Add as in normal case, the shader would be added twice) - var currentlyMixedList = mixinList[0..shaderIndex]; + var currentlyMixedList = result.Mixins[..]; SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); - var newShadersToMergeNow = currentlyMixedList[shaderIndex..]; - mixinList.InsertRange(shaderIndex, newShadersToMergeNow); - - // Note: we're not removing duplicates as we do an extra duplicate check at the beginning of the mixinList loop + var newShadersToMergeNow = currentlyMixedList[result.Mixins.Count..]; + result.Mixins.AddRange(newShadersToMergeNow); } else { @@ -95,10 +92,11 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con for (; shaderIndex < mixinList.Count; shaderIndex++) { var shaderName = mixinList[shaderIndex]; + // Note: this should only happen due to addToRootRecursive readding some mixin earlier if (result.Mixins.Contains(shaderName)) continue; - + var shader = shaderName.Buffer.Value; bool hasStage = false; foreach (var i in shader.Context) From 42deaf7b1e9624f10aa0dcefa5905933c6ee063f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 10:19:56 +0900 Subject: [PATCH 0805/1182] Restore StrideGraphicsApis for linux --- build/Stride.Build.props | 3 +++ build/Stride.UnitTests.Build.targets | 3 +++ 2 files changed, 6 insertions(+) diff --git a/build/Stride.Build.props b/build/Stride.Build.props index d0b96f24b7..75f98464c0 100644 --- a/build/Stride.Build.props +++ b/build/Stride.Build.props @@ -8,4 +8,7 @@ Direct3D11 + + Vulkan + diff --git a/build/Stride.UnitTests.Build.targets b/build/Stride.UnitTests.Build.targets index e750378237..596166fd6e 100644 --- a/build/Stride.UnitTests.Build.targets +++ b/build/Stride.UnitTests.Build.targets @@ -1,5 +1,8 @@ + + Vulkan + Direct3D11 From 9b43a5d2ab0db9f462366e0279adda2b9c031cd7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:22:03 +0900 Subject: [PATCH 0806/1182] [Shaders] Added ShaderSourceToCode class to easily generate C# code to recreate a specific ShaderSource --- .../Stride.Shaders/ShaderSourceToCode.cs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 sources/engine/Stride.Shaders/ShaderSourceToCode.cs diff --git a/sources/engine/Stride.Shaders/ShaderSourceToCode.cs b/sources/engine/Stride.Shaders/ShaderSourceToCode.cs new file mode 100644 index 0000000000..c6c67d9380 --- /dev/null +++ b/sources/engine/Stride.Shaders/ShaderSourceToCode.cs @@ -0,0 +1,106 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Stride.Shaders +{ + /// + /// Generates C# code to easily recreate a specific (i.e. for a unit test). + /// + internal static class ShaderSourceToCode + { + public static string ToCode(this ShaderSource source) + { + var sb = new StringBuilder(); + ToCode(source, sb); + return sb.ToString(); + } + + static void ToCode(ShaderSource source, StringBuilder sb) + { + switch (source) + { + case ShaderClassSource classSource: + sb.Append($"new ShaderClassSource(\"{classSource.ClassName}\""); + if (classSource.GenericArguments != null) + { + sb.Append(","); + sb.Append(string.Join(",", classSource.GenericArguments.Select(x => $"\"{x}\""))); + } + sb.Append(")"); + break; + case ShaderArraySource arraySource: + sb.AppendLine($"new ShaderArraySource"); + sb.AppendLine($"{{"); + foreach (var x in arraySource.Values) + { + ToCode(x, sb); + sb.AppendLine(","); + } + sb.Append($"}}"); + break; + case ShaderMixinSource mixinSource: + sb.Append($"new ShaderMixinSource\n{{\n"); + + if (mixinSource.Mixins != null && mixinSource.Mixins.Count > 0) + { + bool appendLine = mixinSource.Mixins.Count > 1 || mixinSource.Mixins[0] is not ShaderClassSource; + sb.Append($"Mixins ="); + if (appendLine) + sb.AppendLine(); + sb.Append($"{{"); + if (appendLine) + sb.AppendLine(); + for (int i = 0; i < mixinSource.Mixins.Count; i++) + { + ToCode(mixinSource.Mixins[i], sb); + if (appendLine) + sb.AppendLine(","); + } + sb.AppendLine($"}},"); + } + + if (mixinSource.Compositions != null && mixinSource.Compositions.Count > 0) + { + bool appendLine = mixinSource.Compositions.Count > 1 || mixinSource.Compositions.First().Value is not ShaderClassSource; + sb.Append($"Compositions ="); + if (appendLine) + sb.AppendLine(); + sb.Append($"{{"); + if (appendLine) + sb.AppendLine(); + var keys = mixinSource.Compositions.Keys.ToList(); + keys.Sort(); + for (int i = 0; i < keys.Count; i++) + { + var key = keys[i]; + sb.Append($"[\"{key}\"] = "); + ToCode(mixinSource.Compositions[key], sb); + if (appendLine) + sb.AppendLine(","); + } + sb.AppendLine($"}},"); + } + + if (mixinSource.Macros != null && mixinSource.Macros.Count > 0) + { + sb.AppendLine($"Macros ="); + sb.AppendLine($"{{"); + for (int i = 0; i < mixinSource.Macros.Count; i++) + { + sb.AppendLine($"new ShaderMacro(\"{mixinSource.Macros[i].Name}\", \"{mixinSource.Macros[i].Definition}\"),"); + } + sb.AppendLine($"}},"); + } + + sb.Append($"}}"); + break; + default: + throw new NotImplementedException(); + } + } + } +} From 122cee2bd69081f9ff35ffa9d8a079a556bd1f83 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:17:38 +0900 Subject: [PATCH 0807/1182] ShaderBytecode: added stage to the constructor --- .../engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs | 2 +- .../engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs | 3 +-- sources/engine/Stride.Shaders/ShaderBytecode.cs | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs index 38671a98eb..1fb85f45e7 100644 --- a/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs @@ -114,7 +114,7 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad var bytecodeId = ObjectId.FromBytes(strippedBytecode.Handle->Buffer); var bytecodeBuffer = bytecode.Handle->Buffer; - bytecodeResult.Bytecode = new ShaderBytecode(bytecodeId, bytecodeBuffer.ToArray()) { Stage = stage }; + bytecodeResult.Bytecode = new ShaderBytecode(stage, bytecodeId, bytecodeBuffer.ToArray()); // If compilation succeeded, then we can update reflection UpdateReflection(bytecodeResult.Bytecode, reflection, bytecodeResult); diff --git a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs index c6625e6db3..6b84a71601 100644 --- a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs @@ -126,8 +126,7 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad } var bytecodeId = ObjectId.FromBytes(rawData); - var bytecode = new ShaderBytecode(bytecodeId, rawData); - bytecode.Stage = stage; + var bytecode = new ShaderBytecode(stage, bytecodeId, rawData); shaderBytecodeResult.Bytecode = bytecode; diff --git a/sources/engine/Stride.Shaders/ShaderBytecode.cs b/sources/engine/Stride.Shaders/ShaderBytecode.cs index 880780295f..1a1a8f3a02 100644 --- a/sources/engine/Stride.Shaders/ShaderBytecode.cs +++ b/sources/engine/Stride.Shaders/ShaderBytecode.cs @@ -42,8 +42,9 @@ public ShaderBytecode() { } /// /// An unique identifier for the compiled Shader bytecode data. /// The compiled Shader bytecode data. - public ShaderBytecode(ObjectId id, byte[] data) + public ShaderBytecode(ShaderStage stage, ObjectId id, byte[] data) { + Stage = stage; Id = id; Data = data; } From 80c971ea3041df31eb9e3bf9f6f4241745065f01 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 7 Jan 2026 23:03:10 +0900 Subject: [PATCH 0808/1182] SDSL: Preliminary implementation for D3D11 SDSL and Stride need to be checked-out in the same parent folder. SDSL need to have StrideDirectory defined in src\Directory.Build.props --- sources/Directory.Packages.props | 2 + .../ServiceWireSyncInfoSerializer.cs} | 7 +- sources/core/Stride.Core/Stride.Core.csproj | 1 - .../GraphicTestGameBase.cs | 2 +- .../Direct3D/ShaderCompiler.cs | 54 ++++--- .../Stride.Shaders.Compiler/EffectCompiler.cs | 135 +++++++++++++++--- .../OpenGL/ShaderCompiler.cs | 2 +- .../Stride.Shaders.Compiler.csproj | 13 ++ .../Compiler/EffectCompilerCache.cs | 2 +- 9 files changed, 165 insertions(+), 53 deletions(-) rename sources/{core/Stride.Core/Serialization/Serializers/ServiceWireSerializer.cs => buildengine/Stride.Core.BuildEngine.Common/ServiceWireSyncInfoSerializer.cs} (90%) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index 91c3815857..ab2928e54f 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -5,6 +5,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/sources/core/Stride.Core/Serialization/Serializers/ServiceWireSerializer.cs b/sources/buildengine/Stride.Core.BuildEngine.Common/ServiceWireSyncInfoSerializer.cs similarity index 90% rename from sources/core/Stride.Core/Serialization/Serializers/ServiceWireSerializer.cs rename to sources/buildengine/Stride.Core.BuildEngine.Common/ServiceWireSyncInfoSerializer.cs index 73c42a59eb..30c75a185c 100644 --- a/sources/core/Stride.Core/Serialization/Serializers/ServiceWireSerializer.cs +++ b/sources/buildengine/Stride.Core.BuildEngine.Common/ServiceWireSyncInfoSerializer.cs @@ -1,9 +1,10 @@ using ServiceWire; +using Stride.Core.Serialization; -namespace Stride.Core.Serialization.Serializers; +namespace Stride.Core.BuildEngine; -[DataSerializerGlobal(typeof(ServiceWireSerializer))] -public class ServiceWireSerializer : DataSerializer +[DataSerializerGlobal(typeof(ServiceWireSyncInfoSerializer))] +public class ServiceWireSyncInfoSerializer : DataSerializer { public override void PreSerialize(ref ServiceSyncInfo obj, ArchiveMode mode, SerializationStream stream) { diff --git a/sources/core/Stride.Core/Stride.Core.csproj b/sources/core/Stride.Core/Stride.Core.csproj index cd34afb0d1..b6b2b87ae3 100644 --- a/sources/core/Stride.Core/Stride.Core.csproj +++ b/sources/core/Stride.Core/Stride.Core.csproj @@ -22,7 +22,6 @@ - diff --git a/sources/engine/Stride.Graphics.Tests/GraphicTestGameBase.cs b/sources/engine/Stride.Graphics.Tests/GraphicTestGameBase.cs index 78092e5ada..0673a954a7 100644 --- a/sources/engine/Stride.Graphics.Tests/GraphicTestGameBase.cs +++ b/sources/engine/Stride.Graphics.Tests/GraphicTestGameBase.cs @@ -31,7 +31,7 @@ public GraphicTestGameBase() GraphicsDeviceManager.PreferredBackBufferHeight = 480; GraphicsDeviceManager.DeviceCreationFlags = DeviceCreationFlags.Debug; GraphicsDeviceManager.PreferredDepthStencilFormat = PixelFormat.D24_UNorm_S8_UInt; - GraphicsDeviceManager.PreferredGraphicsProfile = [ GraphicsProfile.Level_9_1 ]; + GraphicsDeviceManager.PreferredGraphicsProfile = [ GraphicsProfile.Level_11_0 ]; } diff --git a/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs index 1fb85f45e7..7aa36c61c2 100644 --- a/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/Direct3D/ShaderCompiler.cs @@ -410,36 +410,34 @@ void ValidateConstantBufferReflection(ComPtr mixinSource, + // Parsing.SDSL.ShaderClassSource classSource => new Parsing.SDSL.ShaderMixinSource { Mixins = { classSource } }, + // }; + //} + + //Parsing.SDSL.ShaderSource Convert(ShaderSource shaderSource) + //{ + // return shaderSource switch + // { + // ShaderClassSource classSource => new Parsing.SDSL.ShaderClassSource(classSource.ClassName) { GenericArguments = classSource.GenericArguments }, + // ShaderMixinSource mixinSource => new Parsing.SDSL.ShaderMixinSource { Compositions = new Dictionary(mixinSource.Compositions.Select(x => KeyValuePair.Create(x.Key, ConvertAndEnsureMixin(x.Value)))) }, + // }; + //} + + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters) { var log = new LoggerResult(); @@ -137,7 +204,13 @@ public override TaskOrResult Compile(ShaderMixinSo // In .sdsl, class has been renamed to shader to avoid ambiguities with HLSL shaderMixinSource.AddMacro("class", "shader"); - var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); + var shaderMixer = new ShaderMixer(new ShaderLoader(FileProvider)); + shaderMixer.MergeSDSL(shaderMixinSource, out var spirvBytecode, out var effectReflection, out var usedHashSources); + + var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); + var entryPoints = translator.GetEntryPoints(); + + /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); // Copy log from parser results to output CopyLogs(parsingResult, log); @@ -160,13 +233,13 @@ public override TaskOrResult Compile(ShaderMixinSo { log.Error($"No code generated for effect [{fullEffectName}]"); return new EffectBytecodeCompilerResult(null, log); - } + }*/ // ------------------------------------------------------- // Save shader log // TODO: TEMP code to allow debugging generated shaders on Windows Desktop #if STRIDE_PLATFORM_DESKTOP - var shaderId = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderSourceText)); + var shaderId = ObjectId.FromBytes(spirvBytecode); var logDir = Path.Combine(PlatformFolders.ApplicationBinaryDirectory, "log"); if (!Directory.Exists(logDir)) @@ -179,15 +252,13 @@ public override TaskOrResult Compile(ShaderMixinSo // Write shader before generating to make sure that we are having a trace before compiling it (compiler may crash...etc.) if (!File.Exists(shaderSourceFilename)) { - File.WriteAllText(shaderSourceFilename, shaderSourceText); + File.WriteAllBytes(Path.ChangeExtension(shaderSourceFilename, ".spv"), spirvBytecode); + File.WriteAllText(Path.ChangeExtension(shaderSourceFilename, ".spvdis"), Spirv.Tools.Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); } } #else string shaderSourceFilename = null; #endif - // ------------------------------------------------------- - - var bytecode = new EffectBytecode { Reflection = parsingResult.Reflection, HashSources = parsingResult.HashSources }; // Select the correct backend compiler IShaderCompiler compiler; @@ -213,13 +284,40 @@ public override TaskOrResult Compile(ShaderMixinSo #if STRIDE_PLATFORM_DESKTOP var stageStringBuilder = new StringBuilder(); #endif - foreach (var stageBinding in parsingResult.EntryPoints) + + var bytecode = new EffectBytecode { Reflection = effectReflection, HashSources = usedHashSources }; + + var shaderSourceText = new StringBuilder(); + foreach (var stageBinding in entryPoints) { + var code = translator.Translate(Backend.Hlsl, stageBinding); + // Compile // TODO: We could compile stages in different threads to improve compiler throughput? - var result = compiler.Compile(shaderSourceText, stageBinding.Value, stageBinding.Key, effectParameters, bytecode.Reflection, shaderSourceFilename); + var shaderStage = stageBinding.ExecutionModel switch + { + ExecutionModel.Vertex => ShaderStage.Vertex, + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + ExecutionModel.Fragment => ShaderStage.Pixel, + ExecutionModel.GLCompute => ShaderStage.Compute, + }; + var result = compiler.Compile(code, stageBinding.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, shaderSourceFilename); result.CopyTo(log); + shaderSourceText.AppendLine("// =========================================="); + shaderSourceText.AppendLine($"// {shaderStage} shader"); + shaderSourceText.AppendLine(code); + shaderSourceText.AppendLine(); + + shaderSourceText.AppendLine($"// {result.Messages.Count} errors & messages:"); + foreach (var message in result.Messages) + { + shaderSourceText.AppendLine($"[{message.Type}] {message.Text}"); + shaderSourceText.AppendLine(); + } + if (result.HasErrors) { continue; @@ -228,7 +326,7 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------- // Append bytecode id to shader log #if STRIDE_PLATFORM_DESKTOP - stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(stageBinding.Key, result.Bytecode.Id)); + stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); if (result.DisassembleText != null) { stageStringBuilder.Append(result.DisassembleText); @@ -239,7 +337,7 @@ public override TaskOrResult Compile(ShaderMixinSo shaderStageBytecodes.Add(result.Bytecode); // When this is a compute shader, there is no need to scan other stages - if (stageBinding.Key == ShaderStage.Compute) + if (shaderStage == ShaderStage.Compute) break; } @@ -272,7 +370,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendFormat("cbuffer {0} [Size: {1}]", cBuffer.Name, cBuffer.Size).AppendLine(); foreach (var parameter in cBuffer.Members) { - builder.AppendFormat("@C {0} => {1}", parameter.RawName, parameter.KeyInfo.KeyName).AppendLine(); + builder.AppendFormat("@C {0} => {1} [LogicalGroup: {2}]", parameter.RawName, parameter.KeyInfo.KeyName, parameter.LogicalGroup).AppendLine(); } } builder.AppendLine("***************************"); @@ -284,7 +382,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine("***************************"); foreach (var resource in bytecode.Reflection.ResourceBindings) { - builder.AppendFormat("@R {0} => {1} [Stage: {2}, Slot: ({3}-{4})]", resource.RawName, resource.KeyInfo.KeyName, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine(); + builder.AppendFormat("@R {0} => {1} [LogicalGroup: {2} Stage: {3}, Slot: ({4}-{5})]", resource.RawName, resource.KeyInfo.KeyName, resource.LogicalGroup, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine(); } builder.AppendLine("***************************"); } @@ -315,6 +413,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.Append(shaderSourceText); outputShaderLog = builder.ToString(); + File.WriteAllText(shaderSourceFilename, outputShaderLog); } @@ -409,7 +508,7 @@ private static void CleanupReflection(EffectReflection reflection) || resourceBinding.Class == EffectParameterClass.TextureBuffer) { // Mark associated cbuffer/tbuffer as used - usedConstantBuffers.Add(resourceBinding.KeyInfo.KeyName); + usedConstantBuffers.Add(resourceBinding.RawName); } } diff --git a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs index 6b84a71601..ad9c8bb359 100644 --- a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs @@ -91,7 +91,7 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad File.WriteAllBytes(inputFileName, Encoding.ASCII.GetBytes(shader)); // Run shader compiler - string glslangValidatorPath = Core.NativeLibraryHelper.LocateExecutable(Platform.Type == PlatformType.Windows ? "glslangValidator.exe" : "glslangValidator.bin", typeof(ShaderCompiler)); + string glslangValidatorPath = NativeLibraryHelper.LocateExecutable(Platform.Type == PlatformType.Windows ? "glslangValidator.exe" : "glslangValidator.bin", typeof(ShaderCompiler)); ShellHelper.RunProcessAndRedirectToLogger(glslangValidatorPath, $"-V -o {outputFileName} {inputFileName}", null, shaderBytecodeResult); if (!File.Exists(outputFileName)) diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index 8f720c7b27..bc4dbc47d1 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -19,6 +19,8 @@ + + @@ -34,6 +36,17 @@ PreserveNewest + + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders.Compilers2.dll + + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders.Spirv.Core.dll + + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders2.dll + + \ No newline at end of file diff --git a/sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs index d1ac942159..ac638718fb 100644 --- a/sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -46,7 +46,7 @@ public class EffectCompilerCache : EffectCompilerChain public EffectCompilerCache(EffectCompilerBase compiler, DatabaseFileProvider database, TaskSchedulerSelector taskSchedulerSelector = null) : base(compiler) { - CompileEffectAsynchronously = true; + CompileEffectAsynchronously = false; this.database = database ?? throw new ArgumentNullException(nameof(database), "Using the cache requires a database."); this.taskSchedulerSelector = taskSchedulerSelector; } From 9b0ba345e4a31089d73ca03644cd1462da018a0d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 22 Jan 2026 19:25:35 +0900 Subject: [PATCH 0809/1182] SDSL: added support for Vulkan --- .../Vulkan/CommandList.Vulkan.cs | 17 ++- .../Vulkan/GraphicsDevice.Vulkan.cs | 7 + .../Vulkan/PipelineState.Vulkan.cs | 61 ++++----- .../Stride.Shaders.Compiler/EffectCompiler.cs | 123 +++++++++++------- .../engine/Stride.Shaders/ShaderBytecode.cs | 5 + .../ShaderInputAttributeDescription.cs | 2 + 6 files changed, 124 insertions(+), 91 deletions(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index a30f53bf40..68f2217854 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -209,12 +209,6 @@ private unsafe void SetViewportImpl() //// TODO D3D12 Hardcoded for one viewport var viewportCopy = Viewport; - if (viewportDirty) - { - GraphicsDevice.NativeDeviceApi.vkCmdSetViewport(currentCommandList.NativeCommandBuffer, firstViewport: 0, viewportCount: 1, (VkViewport*) &viewportCopy); - viewportDirty = false; - } - if (activePipeline?.Description.RasterizerState.ScissorTestEnable ?? false) { if (scissorsDirty) @@ -232,8 +226,17 @@ private unsafe void SetViewportImpl() var scissor = new VkRect2D((int) viewportCopy.X, (int) viewportCopy.Y, (uint) viewportCopy.Width, (uint) viewportCopy.Height); GraphicsDevice.NativeDeviceApi.vkCmdSetScissor(currentCommandList.NativeCommandBuffer, firstScissor: 0, scissorCount: 1, &scissor); } - scissorsDirty = false; + + // Since Vulkan 1.1, we can use negative viewport instead of doing gl_Position.y = -gl_Position.y in the shader + // Note: we mutate viewportCopy _after_ vkCmdSetScissor has been called + viewportCopy.Y = viewportCopy.Height - viewportCopy.Y; + viewportCopy.Height = -viewportCopy.Height; + if (viewportDirty) + { + GraphicsDevice.NativeDeviceApi.vkCmdSetViewport(currentCommandList.NativeCommandBuffer, firstViewport: 0, viewportCount: 1, (VkViewport*)&viewportCopy); + viewportDirty = false; + } } /// diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index 793a26b1f7..a9da96914f 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -409,9 +409,16 @@ void SetMaxDescriptorTypeCount(VkDescriptorType type, uint limit) IsProfilingSupported = true; } + // Activate VK_KHR_uniform_buffer_standard_layout (promoted Vulkan 1.2) + var uniformBufferStandardLayoutFeature = new VkPhysicalDeviceUniformBufferStandardLayoutFeatures(); + uniformBufferStandardLayoutFeature.sType = VkStructureType.PhysicalDeviceUniformBufferStandardLayoutFeatures; + uniformBufferStandardLayoutFeature.uniformBufferStandardLayout = VkBool32.True; + + // Activate VK_KHR_timeline_semaphore (promoted Vulkan 1.2) var timelineSemaphoreFeatures = new VkPhysicalDeviceTimelineSemaphoreFeatures(); timelineSemaphoreFeatures.sType = VkStructureType.PhysicalDeviceTimelineSemaphoreFeatures; timelineSemaphoreFeatures.timelineSemaphore = VkBool32.True; + timelineSemaphoreFeatures.pNext = &uniformBufferStandardLayoutFeature; using VkStringArray ppEnabledExtensionNames = new(desiredExtensionProperties); var deviceCreateInfo = new VkDeviceCreateInfo diff --git a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs index dba294121a..5e1285aa66 100644 --- a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs @@ -61,7 +61,7 @@ private unsafe void RecreateInner() CreatePipelineLayout(Description); // Create shader stages - var stages = CreateShaderStages(Description, out var inputAttributeNames); + var stages = CreateShaderStages(Description); if (IsCompute) { @@ -98,15 +98,15 @@ private unsafe void RecreateInner() VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out var format, out var size, out var isCompressed); - var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex); - if (location.Value != null) + var inputAttribute = Description.EffectBytecode.Reflection.InputAttributes.FirstOrDefault(x => x.SemanticName == inputElement.SemanticName && x.SemanticIndex == inputElement.SemanticIndex); + if (inputAttribute.SemanticName != null) { inputAttributes[inputAttributeCount++] = new VkVertexInputAttributeDescription { format = format, offset = (uint)inputElement.AlignedByteOffset, binding = (uint)inputElement.InputSlot, - location = (uint)location.Key + location = (uint)inputAttribute.Location }; } @@ -229,11 +229,8 @@ private unsafe void RecreateInner() } } - // Cleanup shader modules - foreach (var stage in stages) - { - GraphicsDevice.NativeDeviceApi.vkDestroyShaderModule(GraphicsDevice.NativeDevice, stage.module, allocator: null); - } + // Cleanup shader modules (since module is shared between each stage, cleaning first stage is enough) + GraphicsDevice.NativeDeviceApi.vkDestroyShaderModule(GraphicsDevice.NativeDevice, stages[0].module, allocator: null); } /// @@ -364,13 +361,11 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD var layouts = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts; // Get binding indices used by the shader - var destinationBindings = pipelineStateDescription.EffectBytecode.Stages - .SelectMany(x => ReadShaderBytecode(x.Data).ResourceBindings) - .GroupBy(x => x.Key, x => x.Value) - .ToDictionary(x => x.Key, x => x.First()); + var destinationBindings = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings + .ToDictionary(x => x.KeyInfo.KeyName, x => x); - var maxBindingIndex = destinationBindings.Max(x => x.Value); - var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1]; + var maxBindingIndex = destinationBindings.Max(x => x.Value.SlotStart + x.Value.SlotCount); + var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex]; DescriptorBindingMapping = new List(); @@ -391,7 +386,9 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out var destinationBinding)) { - destinationEntries[destinationBinding] = sourceEntry; + if (destinationBinding.SlotCount != 1) + throw new NotImplementedException(); + destinationEntries[destinationBinding.SlotStart] = sourceEntry; // No need to umpdate immutable samplers if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null) @@ -403,7 +400,7 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD { SourceSet = layoutIndex, SourceBinding = sourceBinding, - DestinationBinding = destinationBinding, + DestinationBinding = destinationBinding.SlotStart, DescriptorType = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type), ResourceElementIsInteger = sourceEntry.ElementType != EffectParameterType.Float && sourceEntry.ElementType != EffectParameterType.Double }); @@ -411,15 +408,6 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD } } - // Create default sampler, used by texture and buffer loads - destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry - { - Class = EffectParameterClass.Sampler, - Type = EffectParameterType.Sampler, - ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap, - ArraySize = 1 - }; - // Create descriptor set layout NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts); @@ -434,33 +422,36 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreatePipelineLayout(GraphicsDevice.NativeDevice, &pipelineLayoutCreateInfo, allocator: null, out NativeLayout)); } - private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStateDescription pipelineStateDescription, out Dictionary inputAttributeNames) + private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStateDescription pipelineStateDescription) { var stages = pipelineStateDescription.EffectBytecode.Stages; var nativeStages = new VkPipelineShaderStageCreateInfo[stages.Length]; IsCompute = false; - inputAttributeNames = null; + // Create shader module (shared by all stages) + var shaderBytecode = stages[0].Data; + GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateShaderModule(GraphicsDevice.NativeDevice, shaderBytecode, allocator: null, out var shaderModule)); for (int i = 0; i < stages.Length; i++) { - var shaderBytecode = ReadShaderBytecode(stages[i].Data); - if (stages[i].Stage == ShaderStage.Vertex) - inputAttributeNames = shaderBytecode.InputAttributeNames; - if (stages[i].Stage == ShaderStage.Compute) + var stage = stages[i]; + if (stage.Data != shaderBytecode) + throw new InvalidOperationException("Vulkan: bytecode is expected to be the same for all stages"); + + if (stage.Stage == ShaderStage.Compute) IsCompute = true; - fixed (byte* entryPointPointer = &defaultEntryPoint[0]) + fixed (byte* entryPointPointer = &stage.EntryPoint[0]) { // Create stage nativeStages[i] = new VkPipelineShaderStageCreateInfo { sType = VkStructureType.PipelineShaderStageCreateInfo, stage = VulkanConvertExtensions.Convert(stages[i].Stage), - pName = entryPointPointer + pName = entryPointPointer, + module = shaderModule, }; - GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateShaderModule(GraphicsDevice.NativeDevice, shaderBytecode.Data, allocator: null, out nativeStages[i].module)); } } diff --git a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs index 0e2e443514..485617bdc0 100644 --- a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs @@ -205,10 +205,7 @@ public override TaskOrResult Compile(ShaderMixinSo shaderMixinSource.AddMacro("class", "shader"); var shaderMixer = new ShaderMixer(new ShaderLoader(FileProvider)); - shaderMixer.MergeSDSL(shaderMixinSource, out var spirvBytecode, out var effectReflection, out var usedHashSources); - - var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); - var entryPoints = translator.GetEntryPoints(); + shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); @@ -262,6 +259,8 @@ public override TaskOrResult Compile(ShaderMixinSo // Select the correct backend compiler IShaderCompiler compiler; + // Set to null if translator is not needed + Backend? translatorBackend = null; switch (effectParameters.Platform) { #if STRIDE_PLATFORM_DESKTOP @@ -270,10 +269,11 @@ public override TaskOrResult Compile(ShaderMixinSo if (Platform.Type != PlatformType.Windows && Platform.Type != PlatformType.UWP) throw new NotSupportedException(); compiler = new Direct3D.ShaderCompiler(); + translatorBackend = Backend.Hlsl; break; #endif case GraphicsPlatform.Vulkan: - compiler = new OpenGL.ShaderCompiler(); + compiler = null; break; default: throw new NotSupportedException(); @@ -288,61 +288,86 @@ public override TaskOrResult Compile(ShaderMixinSo var bytecode = new EffectBytecode { Reflection = effectReflection, HashSources = usedHashSources }; var shaderSourceText = new StringBuilder(); - foreach (var stageBinding in entryPoints) - { - var code = translator.Translate(Backend.Hlsl, stageBinding); - // Compile - // TODO: We could compile stages in different threads to improve compiler throughput? - var shaderStage = stageBinding.ExecutionModel switch - { - ExecutionModel.Vertex => ShaderStage.Vertex, - ExecutionModel.TessellationControl => ShaderStage.Hull, - ExecutionModel.TessellationEvaluation => ShaderStage.Domain, - ExecutionModel.Geometry => ShaderStage.Geometry, - ExecutionModel.Fragment => ShaderStage.Pixel, - ExecutionModel.GLCompute => ShaderStage.Compute, - }; - var result = compiler.Compile(code, stageBinding.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, shaderSourceFilename); - result.CopyTo(log); - - shaderSourceText.AppendLine("// =========================================="); - shaderSourceText.AppendLine($"// {shaderStage} shader"); - shaderSourceText.AppendLine(code); - shaderSourceText.AppendLine(); - - shaderSourceText.AppendLine($"// {result.Messages.Count} errors & messages:"); - foreach (var message in result.Messages) + if (translatorBackend != null) + { + var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); + var translatorEntryPoints = translator.GetEntryPoints(); + foreach (var entryPoint in translatorEntryPoints) { - shaderSourceText.AppendLine($"[{message.Type}] {message.Text}"); + var code = translator.Translate(Backend.Hlsl, entryPoint); + + // Compile + // TODO: We could compile stages in different threads to improve compiler throughput? + var shaderStage = entryPoint.ExecutionModel switch + { + ExecutionModel.Vertex => ShaderStage.Vertex, + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + ExecutionModel.Fragment => ShaderStage.Pixel, + ExecutionModel.GLCompute => ShaderStage.Compute, + }; + var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, shaderSourceFilename); + result.CopyTo(log); + + shaderSourceText.AppendLine("// =========================================="); + shaderSourceText.AppendLine($"// {shaderStage} shader"); + shaderSourceText.AppendLine(code); shaderSourceText.AppendLine(); - } - if (result.HasErrors) - { - continue; - } + shaderSourceText.AppendLine($"// {result.Messages.Count} errors & messages:"); + foreach (var message in result.Messages) + { + shaderSourceText.AppendLine($"[{message.Type}] {message.Text}"); + shaderSourceText.AppendLine(); + } + + if (result.HasErrors) + { + continue; + } - // ------------------------------------------------------- - // Append bytecode id to shader log + // ------------------------------------------------------- + // Append bytecode id to shader log #if STRIDE_PLATFORM_DESKTOP - stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); - if (result.DisassembleText != null) - { - stageStringBuilder.Append(result.DisassembleText); - } + stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); + if (result.DisassembleText != null) + { + stageStringBuilder.Append(result.DisassembleText); + } #endif - // ------------------------------------------------------- + // ------------------------------------------------------- - shaderStageBytecodes.Add(result.Bytecode); + shaderStageBytecodes.Add(result.Bytecode); - // When this is a compute shader, there is no need to scan other stages - if (shaderStage == ShaderStage.Compute) - break; + // When this is a compute shader, there is no need to scan other stages + if (shaderStage == ShaderStage.Compute) + break; + } + + // Remove unused reflection data, as it is entirely resolved at compile time. + CleanupReflection(bytecode.Reflection); } + else + { + var spirvBytecodeArray = spirvBytecode.ToArray(); + var spirvBytecodeId = ObjectId.FromBytes(spirvBytecode); + foreach (var entryPoint in entryPoints) + { + var entryPointName = new byte[Encoding.UTF8.GetByteCount(entryPoint.Name) + 1]; + entryPointName[^1] = 0; + Encoding.UTF8.GetBytes(entryPoint.Name.AsSpan(), entryPointName); - // Remove unused reflection data, as it is entirely resolved at compile time. - CleanupReflection(bytecode.Reflection); + shaderStageBytecodes.Add(new ShaderBytecode + { + Stage = entryPoint.Stage, + Data = spirvBytecodeArray, + Id = spirvBytecodeId, + EntryPoint = entryPointName, + }); + } + } bytecode.Stages = shaderStageBytecodes.ToArray(); diff --git a/sources/engine/Stride.Shaders/ShaderBytecode.cs b/sources/engine/Stride.Shaders/ShaderBytecode.cs index 1a1a8f3a02..c88066ca2c 100644 --- a/sources/engine/Stride.Shaders/ShaderBytecode.cs +++ b/sources/engine/Stride.Shaders/ShaderBytecode.cs @@ -31,6 +31,11 @@ public partial class ShaderBytecode /// public byte[] Data { get; set; } + /// + /// Entry point name, stored as UTF8 null terminated string. + /// + public byte[] EntryPoint { get; set; } + /// /// Initializes a new instance of the class. diff --git a/sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs b/sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs index b6b0cb3635..ee01c1c813 100644 --- a/sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs +++ b/sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs @@ -8,6 +8,8 @@ namespace Stride.Shaders [DataContract] public struct ShaderInputAttributeDescription { + public int Location; + public string SemanticName; public int SemanticIndex; From 994b00a373501c5c0fb5650692e24717cefda090 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 14:35:12 +0900 Subject: [PATCH 0810/1182] SDSL: added support for D3D12 --- .../Direct3D12/PipelineState.Direct3D12.cs | 48 ++-- .../Direct3D/DxilHash.cs | 211 ++++++++++++++++++ .../Stride.Shaders.Compiler/EffectCompiler.cs | 51 ++++- 3 files changed, 290 insertions(+), 20 deletions(-) create mode 100644 sources/engine/Stride.Shaders.Compiler/Direct3D/DxilHash.cs diff --git a/sources/engine/Stride.Graphics/Direct3D12/PipelineState.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/PipelineState.Direct3D12.cs index b4d0e37326..4949738562 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/PipelineState.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/PipelineState.Direct3D12.cs @@ -215,7 +215,7 @@ internal PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription p { var nativePipelineStateDescription = new GraphicsPipelineStateDesc { - InputLayout = PrepareInputLayout(pipelineStateDescription.InputElements), + InputLayout = PrepareInputLayout(pipelineStateDescription.InputElements, effectReflection.InputAttributes), PRootSignature = rootSignature, RasterizerState = CreateRasterizerState(pipelineStateDescription.RasterizerState), BlendState = CreateBlendState(pipelineStateDescription.BlendState), @@ -281,7 +281,7 @@ void FindMatchingResourceBindings(DescriptorSetLayoutBuilder.Entry layoutBuilder { foreach (var binding in effectReflection.ResourceBindings) { - if (binding.Stage == ShaderStage.None || binding.KeyInfo.Key != layoutBuilderEntry.Key) + if (binding.KeyInfo.Key != layoutBuilderEntry.Key) continue; var descriptorRangesDictionary = isSampler ? samplerDescriptorRanges : srvDescriptorRanges; @@ -297,7 +297,8 @@ void FindMatchingResourceBindings(DescriptorSetLayoutBuilder.Entry layoutBuilder StaticSamplerDesc samplerDesc = new() { // TODO: D3D12: ImmutableSampler should only be a state description instead of a GPU object? - ShaderVisibility = GetShaderVisibilityForStage(binding.Stage), + // Note: Until we process reflection on the spirv_to_dxil bytecode, we don't know which stage use what so make it visible to all stage for now + ShaderVisibility = ShaderVisibility.All, //GetShaderVisibilityForStage(binding.Stage), ShaderRegister = (uint) binding.SlotStart, RegisterSpace = 0, Filter = (Filter) layoutBuilderEntry.ImmutableSampler.Description.Filter, @@ -373,7 +374,8 @@ void PrepareDescriptorRanges(DescriptorRangesByShaderStageMap descriptionRangesT // Create a Root Parameter to reference the Descriptor Table var rootParam = new RootParameter { - ShaderVisibility = GetShaderVisibilityForStage(stage), + // Note: Until we process reflection on the spirv_to_dxil bytecode, we don't know which stage use what so make it visible to all stage for now + ShaderVisibility = ShaderVisibility.All, //GetShaderVisibilityForStage(stage), ParameterType = RootParameterType.TypeDescriptorTable, DescriptorTable = new() { @@ -507,7 +509,7 @@ PrimitiveType.TriangleListWithAdjacency or // // Prepares the input layout description from the input elements. // - InputLayoutDesc PrepareInputLayout(InputElementDescription[] inputElements) + InputLayoutDesc PrepareInputLayout(InputElementDescription[] inputElements, List inputAttributes) { if (inputElements is null || inputElements.Length == 0) { @@ -519,28 +521,40 @@ InputLayoutDesc PrepareInputLayout(InputElementDescription[] inputElements) var dstInputElements = (InputElementDesc*) inputElementsBuffer; + var pTexCoordSemantic = SilkMarshal.StringToPtr("TEXCOORD"); + + var dstInputElementsCount = 0; for (int i = 0; i < inputElements.Length; ++i) { ref var srcInputElement = ref pipelineStateDescription.InputElements[i]; - var pSemanticName = SilkMarshal.StringToPtr(srcInputElement.SemanticName); - tempMemoryAllocations.Add(pSemanticName); + tempMemoryAllocations.Add(pTexCoordSemantic); - dstInputElements[i] = new InputElementDesc + // Find matching element in input attributes + // Note: in our shader generated by spirv_to_dxil, semantic info is gone + // and locations will be renamed TEXCOORDX with X being the inputAttribute.Location + foreach (var inputAttribute in inputAttributes) { - Format = (Format) srcInputElement.Format, - AlignedByteOffset = (uint) srcInputElement.AlignedByteOffset, - SemanticName = (byte*) pSemanticName, - SemanticIndex = (uint) srcInputElement.SemanticIndex, - InputSlot = (uint) srcInputElement.InputSlot, - InputSlotClass = (Silk.NET.Direct3D12.InputClassification) srcInputElement.InputSlotClass, - InstanceDataStepRate = (uint) srcInputElement.InstanceDataStepRate - }; + if (inputAttribute.SemanticName == srcInputElement.SemanticName && inputAttribute.SemanticIndex == srcInputElement.SemanticIndex) + { + dstInputElements[dstInputElementsCount++] = new InputElementDesc + { + Format = (Format)srcInputElement.Format, + AlignedByteOffset = (uint)srcInputElement.AlignedByteOffset, + SemanticName = (byte*)pTexCoordSemantic, + SemanticIndex = (uint)inputAttribute.Location, + InputSlot = (uint)srcInputElement.InputSlot, + InputSlotClass = (Silk.NET.Direct3D12.InputClassification)srcInputElement.InputSlotClass, + InstanceDataStepRate = (uint)srcInputElement.InstanceDataStepRate + }; + break; + } + } } return new InputLayoutDesc { - NumElements = (uint) inputElements.Length, + NumElements = (uint)dstInputElementsCount, PInputElementDescs = dstInputElements }; } diff --git a/sources/engine/Stride.Shaders.Compiler/Direct3D/DxilHash.cs b/sources/engine/Stride.Shaders.Compiler/Direct3D/DxilHash.cs new file mode 100644 index 0000000000..6ef84337fe --- /dev/null +++ b/sources/engine/Stride.Shaders.Compiler/Direct3D/DxilHash.cs @@ -0,0 +1,211 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using Stride.Core; + +namespace Stride.Shaders.Compiler.Direct3D +{ + // Source: https://github.com/microsoft/hlsl-specs/blob/main/proposals/infra/INF-0004-validator-hashing.md + internal static class DxilHash + { + const byte S11 = 7; + const byte S12 = 12; + const byte S13 = 17; + const byte S14 = 22; + const byte S21 = 5; + const byte S22 = 9; + const byte S23 = 14; + const byte S24 = 20; + const byte S31 = 4; + const byte S32 = 11; + const byte S33 = 16; + const byte S34 = 23; + const byte S41 = 6; + const byte S42 = 10; + const byte S43 = 15; + const byte S44 = 21; + + static void FF(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac) + { + a += ((b & c) | (~b & d)) + x + ac; + a = ((a << s) | (a >> (32 - s))) + b; + } + + static void GG(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac) + { + a += ((b & d) | (c & ~d)) + x + ac; + a = ((a << s) | (a >> (32 - s))) + b; + } + + static void HH(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac) + { + a += (b ^ c ^ d) + x + ac; + a = ((a << s) | (a >> (32 - s))) + b; + } + + static void II(ref uint a, uint b, uint c, uint d, uint x, byte s, uint ac) + { + a += (c ^ (b | ~d)) + x + ac; + a = ((a << s) | (a >> (32 - s))) + b; + } + + public static unsafe void ComputeHashRetail(byte* pData, uint byteCount, byte* pOutHash) + { + var padding = stackalloc byte[] { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + uint leftOver = byteCount & 0x3f; + uint padAmount; + bool bTwoRowsPadding = false; + if( leftOver < 56 ) + { + padAmount = 56 - leftOver; + } + else + { + padAmount = 120 - leftOver; + bTwoRowsPadding = true; + } + uint padAmountPlusSize = padAmount + 8; + var state = stackalloc uint[] {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; + uint N = (byteCount + padAmountPlusSize) >> 6; + uint offset = 0; + uint NextEndState = bTwoRowsPadding ? N-2 : N-1; + byte* pCurrData = pData; + var x = stackalloc uint[16]; + for (uint i = 0; i < N; i++, offset+=64, pCurrData+=64) + { + uint* pX; + if( i == NextEndState ) + { + if( !bTwoRowsPadding && i == N-1 ) + { + uint remainder = byteCount - offset; + x[0] = byteCount << 3; + + Debug.Assert(byteCount - offset <= byteCount); // check for underflow + Debug.Assert(pCurrData + remainder == pData + byteCount); + Buffer.MemoryCopy(pCurrData, (byte*)x + 4, remainder, remainder); // could copy nothing + Buffer.MemoryCopy(padding, (byte*)x + 4 + remainder, padAmount, padAmount); + x[15] = 1 | (byteCount << 1); + } + else if( bTwoRowsPadding ) + { + if( i == N-2 ) + { + uint remainder = byteCount - offset; + + Debug.Assert(byteCount - offset <= byteCount); // check for underflow + Debug.Assert(pCurrData + remainder == pData + byteCount); + Buffer.MemoryCopy(pCurrData, x, remainder, remainder); + Buffer.MemoryCopy(padding, (byte*)x + remainder, padAmount-56, padAmount - 56); + NextEndState = N-1; + } + else if( i == N-1 ) + { + x[0] = byteCount << 3; + Buffer.MemoryCopy(padding + padAmount - 56, (byte*)x + 4, 56, 56); + x[15] = 1 | (byteCount << 1); + } + } + pX = x; + } + else + { + Debug.Assert(pCurrData + 64 <= pData + byteCount); + pX = (uint*)pCurrData; + } + + uint a = state[0]; + uint b = state[1]; + uint c = state[2]; + uint d = state[3]; + + /* Round 1 */ + FF(ref a, b, c, d, pX[ 0], S11, 0xd76aa478 ); /* 1 */ + FF(ref d, a, b, c, pX[ 1], S12, 0xe8c7b756 ); /* 2 */ + FF(ref c, d, a, b, pX[ 2], S13, 0x242070db ); /* 3 */ + FF(ref b, c, d, a, pX[ 3], S14, 0xc1bdceee ); /* 4 */ + FF(ref a, b, c, d, pX[ 4], S11, 0xf57c0faf ); /* 5 */ + FF(ref d, a, b, c, pX[ 5], S12, 0x4787c62a ); /* 6 */ + FF(ref c, d, a, b, pX[ 6], S13, 0xa8304613 ); /* 7 */ + FF(ref b, c, d, a, pX[ 7], S14, 0xfd469501 ); /* 8 */ + FF(ref a, b, c, d, pX[ 8], S11, 0x698098d8 ); /* 9 */ + FF(ref d, a, b, c, pX[ 9], S12, 0x8b44f7af ); /* 10 */ + FF(ref c, d, a, b, pX[10], S13, 0xffff5bb1 ); /* 11 */ + FF(ref b, c, d, a, pX[11], S14, 0x895cd7be ); /* 12 */ + FF(ref a, b, c, d, pX[12], S11, 0x6b901122 ); /* 13 */ + FF(ref d, a, b, c, pX[13], S12, 0xfd987193 ); /* 14 */ + FF(ref c, d, a, b, pX[14], S13, 0xa679438e ); /* 15 */ + FF(ref b, c, d, a, pX[15], S14, 0x49b40821 ); /* 16 */ + + /* Round 2 */ + GG(ref a, b, c, d, pX[ 1], S21, 0xf61e2562 ); /* 17 */ + GG(ref d, a, b, c, pX[ 6], S22, 0xc040b340 ); /* 18 */ + GG(ref c, d, a, b, pX[11], S23, 0x265e5a51 ); /* 19 */ + GG(ref b, c, d, a, pX[ 0], S24, 0xe9b6c7aa ); /* 20 */ + GG(ref a, b, c, d, pX[ 5], S21, 0xd62f105d ); /* 21 */ + GG(ref d, a, b, c, pX[10], S22, 0x2441453 ); /* 22 */ + GG(ref c, d, a, b, pX[15], S23, 0xd8a1e681 ); /* 23 */ + GG(ref b, c, d, a, pX[ 4], S24, 0xe7d3fbc8 ); /* 24 */ + GG(ref a, b, c, d, pX[ 9], S21, 0x21e1cde6 ); /* 25 */ + GG(ref d, a, b, c, pX[14], S22, 0xc33707d6 ); /* 26 */ + GG(ref c, d, a, b, pX[ 3], S23, 0xf4d50d87 ); /* 27 */ + GG(ref b, c, d, a, pX[ 8], S24, 0x455a14ed ); /* 28 */ + GG(ref a, b, c, d, pX[13], S21, 0xa9e3e905 ); /* 29 */ + GG(ref d, a, b, c, pX[ 2], S22, 0xfcefa3f8 ); /* 30 */ + GG(ref c, d, a, b, pX[ 7], S23, 0x676f02d9 ); /* 31 */ + GG(ref b, c, d, a, pX[12], S24, 0x8d2a4c8a ); /* 32 */ + + /* Round 3 */ + HH(ref a, b, c, d, pX[ 5], S31, 0xfffa3942 ); /* 33 */ + HH(ref d, a, b, c, pX[ 8], S32, 0x8771f681 ); /* 34 */ + HH(ref c, d, a, b, pX[11], S33, 0x6d9d6122 ); /* 35 */ + HH(ref b, c, d, a, pX[14], S34, 0xfde5380c ); /* 36 */ + HH(ref a, b, c, d, pX[ 1], S31, 0xa4beea44 ); /* 37 */ + HH(ref d, a, b, c, pX[ 4], S32, 0x4bdecfa9 ); /* 38 */ + HH(ref c, d, a, b, pX[ 7], S33, 0xf6bb4b60 ); /* 39 */ + HH(ref b, c, d, a, pX[10], S34, 0xbebfbc70 ); /* 40 */ + HH(ref a, b, c, d, pX[13], S31, 0x289b7ec6 ); /* 41 */ + HH(ref d, a, b, c, pX[ 0], S32, 0xeaa127fa ); /* 42 */ + HH(ref c, d, a, b, pX[ 3], S33, 0xd4ef3085 ); /* 43 */ + HH(ref b, c, d, a, pX[ 6], S34, 0x4881d05 ); /* 44 */ + HH(ref a, b, c, d, pX[ 9], S31, 0xd9d4d039 ); /* 45 */ + HH(ref d, a, b, c, pX[12], S32, 0xe6db99e5 ); /* 46 */ + HH(ref c, d, a, b, pX[15], S33, 0x1fa27cf8 ); /* 47 */ + HH(ref b, c, d, a, pX[ 2], S34, 0xc4ac5665 ); /* 48 */ + + /* Round 4 */ + II(ref a, b, c, d, pX[ 0], S41, 0xf4292244 ); /* 49 */ + II(ref d, a, b, c, pX[ 7], S42, 0x432aff97 ); /* 50 */ + II(ref c, d, a, b, pX[14], S43, 0xab9423a7 ); /* 51 */ + II(ref b, c, d, a, pX[ 5], S44, 0xfc93a039 ); /* 52 */ + II(ref a, b, c, d, pX[12], S41, 0x655b59c3 ); /* 53 */ + II(ref d, a, b, c, pX[ 3], S42, 0x8f0ccc92 ); /* 54 */ + II(ref c, d, a, b, pX[10], S43, 0xffeff47d ); /* 55 */ + II(ref b, c, d, a, pX[ 1], S44, 0x85845dd1 ); /* 56 */ + II(ref a, b, c, d, pX[ 8], S41, 0x6fa87e4f ); /* 57 */ + II(ref d, a, b, c, pX[15], S42, 0xfe2ce6e0 ); /* 58 */ + II(ref c, d, a, b, pX[ 6], S43, 0xa3014314 ); /* 59 */ + II(ref b, c, d, a, pX[13], S44, 0x4e0811a1 ); /* 60 */ + II(ref a, b, c, d, pX[ 4], S41, 0xf7537e82 ); /* 61 */ + II(ref d, a, b, c, pX[11], S42, 0xbd3af235 ); /* 62 */ + II(ref c, d, a, b, pX[ 2], S43, 0x2ad7d2bb ); /* 63 */ + II(ref b, c, d, a, pX[ 9], S44, 0xeb86d391 ); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + } + + Buffer.MemoryCopy(&state[0], pOutHash, 16, 16); + } + } +} diff --git a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs index 485617bdc0..9087dad6b9 100644 --- a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs @@ -22,7 +22,9 @@ using Stride.Core.Storage; using Stride.Graphics; using Stride.Rendering; +using Stride.Shaders.Compiler.Direct3D; using Stride.Shaders.Compilers; +using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parser; using Stride.Shaders.Parser.Mixins; @@ -80,7 +82,7 @@ public override void ResetCache(HashSet modifiedShaders) GetMixinParser().DeleteObsoleteCache(modifiedShaders); } - private ShaderMixinParser GetMixinParser() + public ShaderMixinParser GetMixinParser() { lock (shaderMixinParserLock) { @@ -96,7 +98,7 @@ private ShaderMixinParser GetMixinParser() } } - class ShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new ShaderCache()) + public class ShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new ShaderCache()) { protected override bool ExternalFileExists(string name) { @@ -265,7 +267,6 @@ public override TaskOrResult Compile(ShaderMixinSo { #if STRIDE_PLATFORM_DESKTOP case GraphicsPlatform.Direct3D11: - case GraphicsPlatform.Direct3D12: if (Platform.Type != PlatformType.Windows && Platform.Type != PlatformType.UWP) throw new NotSupportedException(); compiler = new Direct3D.ShaderCompiler(); @@ -273,6 +274,7 @@ public override TaskOrResult Compile(ShaderMixinSo break; #endif case GraphicsPlatform.Vulkan: + case GraphicsPlatform.Direct3D12: compiler = null; break; default: @@ -349,6 +351,49 @@ public override TaskOrResult Compile(ShaderMixinSo // Remove unused reflection data, as it is entirely resolved at compile time. CleanupReflection(bytecode.Reflection); } + // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) + else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) + { + // Check API + Spv2DXIL.spirv_to_dxil_get_version(); + foreach (var entryPoint in entryPoints) + { + unsafe + { + fixed (byte* shaderData = spirvBytecode) + { + var debugOptions = new DebugOptions(); + var runtimeConf = new RuntimeConf + { + runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, + //first_vertex_and_base_instance_mode = SysvalType.Zero, + yzflip_mode = FlipMode.YZFlipNone, + shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, + }; + var logger = new DXILSpirvLogger(); + var result = Spv2DXIL.spirv_to_dxil((uint*)shaderData, spirvBytecode.Length / 4, + null, 0, + entryPoint.Stage switch + { + ShaderStage.Vertex => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_VERTEX, + ShaderStage.Hull => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, + ShaderStage.Domain => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, + ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, + ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, + ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, + }, + entryPoint.Name, + ValidatorVersion.DXIL_VALIDATOR_1_4, + ref debugOptions, ref runtimeConf, ref logger, out var dxil); + + Span dxilSpan = new(dxil.buffer, (int)dxil.size); + fixed (byte* dxilSpanPtr = dxilSpan) + DxilHash.ComputeHashRetail(&dxilSpanPtr[20], (uint)(dxilSpan.Length - 20), &dxilSpanPtr[4]); + shaderStageBytecodes.Add(new ShaderBytecode(entryPoint.Stage, ObjectId.FromBytes(dxilSpan), dxilSpan.ToArray())); + } + } + } + } else { var spirvBytecodeArray = spirvBytecode.ToArray(); From 3326c38f11ae6c20d89e351c19d41f6b41b1e01c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 15:20:55 +0900 Subject: [PATCH 0811/1182] Graphics: CompileShaders now separate D3D11 from D3D12 bytecodes --- .../Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs | 4 ++-- .../Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd | 1 + .../Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd | 1 + sources/engine/Stride.Shaders/EffectBytecode.cs | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs b/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs index 88772de4f0..bcce217b49 100644 --- a/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs +++ b/sources/engine/Stride.Assets/Effect/EffectBytecodeToSourceCodeWriter.cs @@ -63,8 +63,8 @@ public static void Write(string name, CompilerParameters parameters, EffectBytec string strideDefine = graphicsPlatform switch { - GraphicsPlatform.Direct3D11 or - GraphicsPlatform.Direct3D12 => "STRIDE_GRAPHICS_API_DIRECT3D", + GraphicsPlatform.Direct3D11 => "STRIDE_GRAPHICS_API_DIRECT3D11", + GraphicsPlatform.Direct3D12 => "STRIDE_GRAPHICS_API_DIRECT3D12", GraphicsPlatform.Vulkan => "STRIDE_GRAPHICS_API_VULKAN", _ => "undefined" diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index 5af33d8787..dda37a3dec 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -4,4 +4,5 @@ set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe rmdir /s %~dp0obj\ %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd index 0adc57e98a..693774cb9e 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd @@ -4,4 +4,5 @@ set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe rmdir /s %~dp0obj\ %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Shaders/EffectBytecode.cs b/sources/engine/Stride.Shaders/EffectBytecode.cs index 2935f5aabd..2b343fcd70 100644 --- a/sources/engine/Stride.Shaders/EffectBytecode.cs +++ b/sources/engine/Stride.Shaders/EffectBytecode.cs @@ -22,7 +22,7 @@ public sealed class EffectBytecode /// A constant value representing the magic header stored in front of an Effect bytecode /// to avoid reading old versions. /// - public const uint MagicHeader = 0xEFFEC007; // NOTE: If EffectBytecode is changed, this number must be changed manually + public const uint MagicHeader = 0xEFFEC008; // NOTE: If EffectBytecode is changed, this number must be changed manually /// From 92f16ec2a6943d221c1f8442ccc6c3d17967253d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 23 Jan 2026 15:24:39 +0900 Subject: [PATCH 0812/1182] SDSL: Added benchmark (WIP) --- sources/Directory.Packages.props | 1 + .../Stride.Shaders.Compiler.csproj | 6 +- .../BenchmarkShaderSystems.cs | 157 ++++++++++++++++++ .../Stride.Shaders.Tests.Windows.csproj | 7 + .../Stride.Shaders.Tests/TestMixinCompiler.cs | 6 +- sources/targets/Stride.UnitTests.targets | 2 +- 6 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index ab2928e54f..59efc0f696 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -90,6 +90,7 @@ + diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index bc4dbc47d1..a91da7b80a 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -38,13 +38,13 @@ - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders.Compilers2.dll + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders.Spirv.Core.dll + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Spirv.Core.dll - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\Debug\net10.0\Stride.Shaders2.dll + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll diff --git a/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs b/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs new file mode 100644 index 0000000000..cb7d67872e --- /dev/null +++ b/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs @@ -0,0 +1,157 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; +using Stride.Core.IO; +using Stride.Core.Storage; +using Stride.Core.Serialization.Contents; +using Stride.Shaders.Compiler; +using Stride.Shaders.Compilers.SDSL; +using Xunit; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Engines; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Running; +using BenchmarkDotNet.Validators; + +namespace Stride.Shaders.Tests +{ + // Temporary test for old vs new shader system + public class BenchmarkShaderSystems + { + EffectCompiler compiler; + ShaderMixinSource shaderMixinSource; + + public BenchmarkShaderSystems() + { + var objDatabase = ObjectDatabase.CreateDefaultDatabase(); + var database = new DatabaseFileProvider(objDatabase); + compiler = new EffectCompiler(database); + compiler.SourceDirectories.Add(EffectCompilerBase.DefaultSourceShaderFolder); + + shaderMixinSource = new ShaderMixinSource + { + Mixins = + { + new ShaderClassSource("ShaderBase"), + new ShaderClassSource("ShadingBase"), + new ShaderClassSource("TransformationBase"), + new ShaderClassSource("NormalStream"), + new ShaderClassSource("TransformationWAndVP"), + new ShaderClassSource("NormalFromMesh"), + new ShaderClassSource("MaterialSurfacePixelStageCompositor"), + }, + Compositions = + { + ["directLightGroups"] = new ShaderArraySource + { + new ShaderMixinSource + { + Mixins = + { + new ShaderClassSource("LightDirectionalGroup", "1"), + new ShaderClassSource("ShadowMapReceiverDirectional", "1", "1", "true", "true", "false", "false"), + new ShaderClassSource("ShadowMapFilterDefault", "PerView.Lighting"), + }, + }, + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("LightClusteredPointGroup") }, + }, + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("LightClusteredSpotGroup") }, + }, + }, + ["environmentLights"] = new ShaderArraySource + { + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("LightSimpleAmbient") }, + }, + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("EnvironmentLight") }, + }, + }, + ["materialPixelStage"] = new ShaderMixinSource + { + Mixins = { new ShaderClassSource("MaterialSurfaceArray") }, + Compositions = + { + ["layers"] = new ShaderArraySource + { + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("MaterialSurfaceDiffuse") }, + Compositions = { ["diffuseMap"] = new ShaderClassSource("ComputeColorConstantColorLink", "Material.DiffuseValue") }, + }, + new ShaderMixinSource + { + Mixins = { new ShaderClassSource("MaterialSurfaceLightingAndShading") }, + Compositions = + { + ["surfaces"] = new ShaderArraySource + { + new ShaderClassSource("MaterialSurfaceShadingDiffuseLambert", "false"), + }, + }, + }, + }, + }, + }, + ["streamInitializerPixelStage"] = new ShaderMixinSource + { + Mixins = + { + new ShaderClassSource("MaterialStream"), + new ShaderClassSource("MaterialPixelShadingStream"), + }, + }, + }, + }; + } + + [Benchmark] + public void OldSystem() + { + // Old system + var parsingResult = compiler.GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); + } + + [Benchmark] + public void NewSystem() + { + // New system + var shaderMixer = new ShaderMixer(new EffectCompiler.ShaderLoader(compiler.FileProvider)); + shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(false), out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); + } + } + + public class BenchmarkProgram + { + public static void Main(string[] args) + { + /*var test = new TestShaderSystems(); + for (int i = 0; i < 5; ++i) + test.OldSystem(); + for (int i = 0; i < 5; ++i) + test.NewSystem(); + + return;*/ + // TODO: somehow iteration count is not respected, need to review that + var config = new DebugInProcessConfig() + // Enable for debug mode + //.WithOptions(ConfigOptions.DisableOptimizationsValidator) + .AddJob(Job.Default + .WithWarmupCount(0) + .WithIterationCount(1) + .WithInvocationCount(1) + .WithUnrollFactor(1) + .AsDefault()); + + var summary = BenchmarkRunner.Run(typeof(BenchmarkProgram).Assembly, config); + } + } +} diff --git a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj index 53052129d3..4679d2b67c 100644 --- a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj +++ b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj @@ -27,6 +27,13 @@ + + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll + diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs b/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs index d118800e1a..ce85bb3142 100644 --- a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs +++ b/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs @@ -36,7 +36,7 @@ public partial class TestMixinCompiler public void TestMaterial() { var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Core.PlatformFolders.ApplicationBinaryDirectory; + var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shaders")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Core")); @@ -102,7 +102,7 @@ public void TestMaterial() public void TestStream() { var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Core.PlatformFolders.ApplicationBinaryDirectory; + var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Shaders.Tests\GameAssets\Compiler")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shaders")); @@ -129,7 +129,7 @@ public void TestStream() public void TestMixinAndComposeKeys() { var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Core.PlatformFolders.ApplicationBinaryDirectory; + var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Shaders.Tests\GameAssets\Mixins")); diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index ebbc034e8c..a046258e02 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -50,7 +50,7 @@ - xunit.runner.stride.Program + xunit.runner.stride.Program From 7545a5686cff83031c56bb142a88b6fe1548f35f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 14:22:02 +0900 Subject: [PATCH 0813/1182] Graphics: Regenerated precompiled shaders --- ...riteBatch.bytecode.Direct3D11.Level_9_1.cs | 1326 ++++++++-------- ...riteBatch.bytecode.Direct3D12.Level_9_1.cs | 143 ++ ...Batch.bytecodeSRgb.Direct3D11.Level_9_1.cs | 1348 ++++++++--------- ...Batch.bytecodeSRgb.Direct3D12.Level_9_1.cs | 144 ++ ...iteEffect.bytecode.Direct3D11.Level_9_1.cs | 943 +++++------- ...iteEffect.bytecode.Direct3D12.Level_9_1.cs | 117 ++ .../UIEffect.bytecode.Direct3D11.Level_9_1.cs | 1031 ++++++------- .../UIEffect.bytecode.Direct3D12.Level_9_1.cs | 116 ++ ...ffect.bytecodeSRgb.Direct3D11.Level_9_1.cs | 1115 ++++++-------- ...ffect.bytecodeSRgb.Direct3D12.Level_9_1.cs | 118 ++ ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 1155 ++++++-------- ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 116 ++ ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 439 ++++-- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 1236 +++++++-------- ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 129 ++ ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 458 ++++-- 16 files changed, 5050 insertions(+), 4884 deletions(-) create mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs create mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs create mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs create mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs create mode 100644 sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs create mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs create mode 100644 sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs index 599d187966..622e06a3b4 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs @@ -1,77 +1,80 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-d3d11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { public partial class SpriteBatch { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 70, 208, 120, 0, 77, -76, 56, 64, 150, 215, 0, 116, 16, 135, 99, 140, 0, 28, 111, 0, 0, 68, 88, 66, 67, 96, 133, 59, 13, 128, 183, 89, 112, 15, 81, 192, 84, 6, 125, 18, 66, 1, 0, 0, 0, 28, 111, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 248, 4, 0, 0, 104, 6, 0, 0, 112, 108, 0, 0, -236, 108, 0, 0, 184, 109, 0, 0, 104, 110, 0, 0, 65, 111, 110, 57, 180, 4, 0, 0, 180, 4, 0, 0, 0, 2, 254, 255, 128, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 234, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 15, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 64, 3, 0, 0, 44, 1, 0, 0, 67, 58, 92, 100, -101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, -110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, -108, 115, 108, 0, 40, 0, 0, 0, 0, 0, 255, 255, 176, 3, 0, 0, 0, 0, 255, 255, 188, 3, 0, 0, 0, 0, 255, 255, 200, 3, 0, 0, 0, 0, 255, 255, 212, 3, 0, 0, 0, 0, 255, 255, 224, 3, 0, 0, 172, 0, 0, 0, 236, 3, 0, 0, 172, 0, 0, 0, 252, 3, 0, 0, -172, 0, 0, 0, 12, 4, 0, 0, 172, 0, 0, 0, 28, 4, 0, 0, 186, 0, 0, 0, 44, 4, 0, 0, 186, 0, 0, 0, 64, 4, 0, 0, 190, 0, 0, 0, 76, 4, 0, 0, 191, 0, 0, 0, 88, 4, 0, 0, 191, 0, 0, 0, 100, 4, 0, 0, 193, 0, 0, 0, 112, 4, 0, 0, -86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 55, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, -54, 0, 171, 171, 51, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 72, 1, 0, 0, 99, 1, 0, 0, 112, 1, 0, 0, 128, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 176, 1, 0, 0, 5, 0, 0, 0, -255, 255, 255, 255, 2, 0, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 11, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 12, 0, 0, 0, 8, 0, 255, 255, 255, 255, 255, 255, 13, 0, 0, 0, 255, 255, 9, 0, -10, 0, 255, 255, 14, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 70, 2, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 72, 1, 0, 0, 99, 1, 0, 0, 112, 1, 0, 0, -128, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 84, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 1, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 2, 0, 0, 0, 8, 0, 255, 255, -255, 255, 255, 255, 3, 0, 0, 0, 9, 0, 10, 0, 255, 255, 255, 255, 4, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 115, 116, 114, 101, 97, 109, 115, 0, 171, 70, 2, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 72, 1, 0, 0, -99, 1, 0, 0, 112, 1, 0, 0, 128, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, 72, 1, 0, 0, 51, 1, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 220, 2, 0, 0, 6, 0, 0, 0, 15, 0, 255, 255, 255, 255, 255, 255, 7, 0, 0, 0, -255, 255, 16, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 18, 0, 255, 255, 0, 0, 0, 0, 44, 1, 0, 0, 216, 1, 0, 0, 7, 0, 0, 0, 232, 1, 0, 0, 44, 1, 0, 0, 60, 2, 0, 0, 124, 2, 0, 0, 5, 0, 0, 0, 140, 2, 0, 0, 200, 2, 0, 0, -211, 2, 0, 0, 12, 3, 0, 0, 3, 0, 0, 0, 28, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, -0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 0, 0, 228, 144, -3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 0, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 0, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 0, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, -0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 15, 224, 1, 0, 228, 144, 1, 0, 0, 2, 1, 0, 1, 224, 2, 0, 0, 144, 1, 0, 0, 2, 1, 0, 6, 224, 3, 0, 208, 144, 1, 0, 0, 2, 2, 0, 15, 224, -4, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, -95, 0, 0, 3, 18, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 4, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, -101, 0, 0, 3, 18, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 98, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, -0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, -2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 18, 32, 16, 0, -2, 0, 0, 0, 10, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 98, 32, 16, 0, 2, 0, 0, 0, 6, 17, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 4, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 102, 0, 0, -77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, +114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, +1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, +88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, +140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, +105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 34, 78, 1, 177, 202, 75, 102, 209, 209, 54, 26, 46, 94, 167, 243, 149, 0, 212, 97, 0, 0, 68, 88, 66, 67, 231, 186, 219, 190, 149, 2, +188, 135, 14, 184, 254, 149, 79, 237, 192, 131, 1, 0, 0, 0, 212, 97, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 95, 0, 0, 112, 96, 0, 0, 36, 97, 0, 0, 160, 97, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, +255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, +0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, +255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 91, 0, 0, 0, 220, 4, 0, 0, 106, 0, 0, 0, 236, 4, 0, 0, 106, 0, 0, 0, 252, 4, 0, 0, 97, 0, +0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 36, 5, 0, 0, 104, 0, 0, 0, 52, 5, 0, 0, 109, 0, 0, 0, 72, 5, 0, 0, 111, 0, 0, 0, 92, 5, 0, 0, 108, 0, 0, 0, 108, 5, 0, 0, 111, 0, 0, 0, 128, 5, 0, 0, 111, 0, +0, 0, 148, 5, 0, 0, 111, 0, 0, 0, 160, 5, 0, 0, 111, 0, 0, 0, 172, 5, 0, 0, 112, 0, 0, 0, 188, 5, 0, 0, 113, 0, 0, 0, 208, 5, 0, 0, 113, 0, 0, 0, 220, 5, 0, 0, 113, 0, 0, 0, 240, 5, 0, 0, 114, 0, 0, 0, 4, 6, 0, 0, 114, 0, +0, 0, 20, 6, 0, 0, 114, 0, 0, 0, 32, 6, 0, 0, 118, 0, 0, 0, 48, 6, 0, 0, 118, 0, 0, 0, 60, 6, 0, 0, 118, 0, 0, 0, 72, 6, 0, 0, 118, 0, 0, 0, 84, 6, 0, 0, 118, 0, 0, 0, 104, 6, 0, 0, 119, 0, 0, 0, 124, 6, 0, 0, 119, 0, +0, 0, 136, 6, 0, 0, 119, 0, 0, 0, 148, 6, 0, 0, 119, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 95, 52, 53, 52, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, +3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, +0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, +4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, +111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, +3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, +0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, +0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, +40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, +0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, +0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, +2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, +0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, +85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, +0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, +255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, +255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, +228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, +0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, +0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, +0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, +16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, +0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, +0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, +16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, +0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, +128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, +16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, +48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -79,7 +82,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -56, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -87,311 +90,183 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, +0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 12, 211, 32, 152, 191, 21, 148, 68, 180, 22, +79, 226, 163, 237, 224, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 212, 72, 224, 22, 97, 249, 243, 78, 155, 195, 138, 141, 105, 13, 64, 61, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, -53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, -125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, -13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, -198, 90, 0, 0, 117, 131, 1, 0, 5, 254, 3, 0, 156, 202, 1, 0, 38, 247, 2, 0, 190, 254, 0, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 168, 74, 1, 0, 172, 19, 0, 0, 94, 184, 2, 0, 80, 133, 1, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, -125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, -83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, -32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, -10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, -76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, -105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, -115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, -122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, -101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, -100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, -95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, -101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, -101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, -117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, -100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, -109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, -109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, -109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, -80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, -108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, -95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, -105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, -109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, -111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, -88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, -10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, -32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, -97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, -10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, -49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, -85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, -117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, -65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, -32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, -86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, -61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, -105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, -55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -254, 239, 254, 239, 1, 0, 0, 0, 97, 23, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, -108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, -99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, -101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, -97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 102, 97, 108, -115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -27, 226, 48, 1, 128, 0, 0, 0, 168, 242, 77, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 178, 73, 61, 255, 78, 22, 0, 0, 1, 0, 0, 0, 137, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, -32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, -116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 44, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, -3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, -1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, -12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, -22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, -1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, -44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 68, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 72, 0, 0, 0, -22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 76, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, -1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, -32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, -22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, -1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, -4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 12, 0, 0, 0, -38, 0, 77, 17, 140, 0, 0, 0, 40, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 83, 11, 32, 4, 128, 128, 8, 0, 9, 35, 13, 82, 1, 128, 148, 12, 128, 128, 0, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 104, 234, -249, 150, 59, 95, 0, 189, 242, 186, 3, 14, 191, 211, 7, 240, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 194, 0, 0, 128, 148, 0, 0, 0, 194, 0, 0, 0, -180, 0, 0, 0, 194, 0, 0, 128, 180, 0, 0, 0, 194, 0, 0, 0, 212, 0, 0, 0, 194, 0, 0, 128, 212, 0, 0, 0, 194, 0, 0, 0, 244, 0, 0, 0, 194, 0, 0, 128, 244, 0, 0, 0, 194, 0, 0, 0, 20, 1, 0, 0, 201, 0, 0, 128, 20, 1, 0, 0, 201, 0, 0, 0, -40, 1, 0, 0, 201, 0, 0, 128, 40, 1, 0, 0, 201, 0, 0, 0, 60, 1, 0, 0, 201, 0, 0, 128, 60, 1, 0, 0, 201, 0, 0, 0, 80, 1, 0, 0, 201, 0, 0, 128, 80, 1, 0, 0, 201, 0, 0, 0, 100, 1, 0, 0, 201, 0, 0, 128, 100, 1, 0, 0, 201, 0, 0, 0, -5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, -5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, -108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 13, 21, 3, 0, 0, 16, 0, 0, 60, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 34, 0, 5, 21, 6, 0, 0, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -76, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, -4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 184, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 8, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, -4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 122, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 55, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 86, 83, 95, 73, 78, 80, -85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 130, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, -108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, -0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, -14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 154, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, -60, 118, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, -66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, -119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, -83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, -95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, -101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, -84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, -84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, -120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, -95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, -78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, -65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, -32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, -115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, -109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, -82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, -61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, -79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, -82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, -97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, -111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, -83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, -51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, -123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, -61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, -108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, -114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, -32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, -40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, -10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, -41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, -80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, -95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, -95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, -108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, -95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, -32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 137, 0, 0, 0, 18, 1, 0, 0, 1, 0, 0, -0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 1, 16, 0, 0, 24, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, -13, 16, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, +3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 33, 155, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 37, 52, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, -13, 16, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, +125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, +32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, +54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, +32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, +32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, +108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, +46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, +32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, +32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, +49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, +114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, +101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, +32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, +41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, +46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, +32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, +95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 214, 14, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, +97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 57, 53, 98, 52, 55, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 66, 76, 11, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, +0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 125, 141, 252, 0, 33, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, +10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, +0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, +0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, +88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, +0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 62, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 61, 1, +104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, +3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, +6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, +13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 53, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, +152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, +0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, +4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, +110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, +0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, +114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, +20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, +78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 121, 191, 162, 18, 168, 171, 123, 217, 104, 0, 57, 20, 109, 234, 68, 168, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, +0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 144, 0, 0, 128, 104, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 128, 144, 0, 0, 0, 144, 0, 0, 0, 188, 0, 0, 0, 144, 0, 0, 128, 188, 0, 0, 0, 144, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 128, 200, 0, +0, 0, 144, 0, 0, 0, 236, 0, 0, 0, 144, 0, 0, 128, 236, 0, 0, 0, 144, 0, 0, 0, 0, 1, 0, 0, 144, 0, 0, 128, 0, 1, 0, 0, 144, 0, 0, 0, 4, 1, 0, 0, 144, 0, 0, 128, 4, 1, 0, 0, 144, 0, 0, 0, 40, 1, 0, 0, 144, 0, 0, 128, 40, 1, +0, 0, 144, 0, 0, 0, 44, 1, 0, 0, 144, 0, 0, 128, 44, 1, 0, 0, 144, 0, 0, 0, 104, 1, 0, 0, 144, 0, 0, 128, 104, 1, 0, 0, 144, 0, 0, 0, 132, 1, 0, 0, 144, 0, 0, 128, 132, 1, 0, 0, 144, 0, 0, 0, 160, 1, 0, 0, 144, 0, 0, 128, 160, 1, +0, 0, 144, 0, 0, 0, 188, 1, 0, 0, 144, 0, 0, 128, 188, 1, 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 144, 0, 0, 128, 208, 1, 0, 0, 144, 0, 0, 0, 240, 1, 0, 0, 144, 0, 0, 128, 240, 1, 0, 0, 144, 0, 0, 0, 20, 2, 0, 0, 144, 0, 0, 128, 20, 2, +0, 0, 144, 0, 0, 0, 40, 2, 0, 0, 144, 0, 0, 128, 40, 2, 0, 0, 144, 0, 0, 0, 76, 2, 0, 0, 144, 0, 0, 128, 76, 2, 0, 0, 144, 0, 0, 0, 96, 2, 0, 0, 144, 0, 0, 128, 96, 2, 0, 0, 144, 0, 0, 0, 116, 2, 0, 0, 144, 0, 0, 128, 116, 2, +0, 0, 144, 0, 0, 0, 152, 2, 0, 0, 144, 0, 0, 128, 152, 2, 0, 0, 144, 0, 0, 0, 188, 2, 0, 0, 147, 0, 0, 128, 188, 2, 0, 0, 147, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 95, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, +0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, +83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, +5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, +111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, +242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, +0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, +1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -399,65 +274,127 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 42, 0, 81, 17, 16, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, +125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, +32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, +54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, +32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, +32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, +108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, +46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, +32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, +32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, +49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, +114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, +101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, +32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, +41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, +46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, +32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, +95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, +0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, +97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 48, 0, 48, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, +0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, +97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 212, 72, 224, 22, 97, 249, 243, 78, 155, 195, 138, 141, 105, 13, 64, 61, 181, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, -107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, -108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, -99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, -0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 48, 4, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, -104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, -88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -16, 0, 0, 0, 32, 0, 0, 0, 17, 1, 0, 0, 240, 2, 0, 0, 155, 1, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 145, 23, 0, 0, 128, 0, 0, 0, 78, 22, 0, 0, 108, 5, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, -68, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 45, 0, 0, 0, 38, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, -35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 21, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, -22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 39, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, +81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, +1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, +0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, +255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, +114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 12, 211, 32, 152, 191, 21, 148, 68, 180, 22, +79, 226, 163, 237, 224, 240, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 102, 54, 57, 53, 98, 52, 55, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, +8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, +0, 0, 0, 0, 0, 0, 6, 15, 0, 0, 128, 0, 0, 0, 33, 14, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 38, 0, +0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, +0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -471,66 +408,52 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, -196, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 156, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 171, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, -101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 15, 15, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 79, 83, 71, 78, 172, 0, 0, 0, -5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 9, 0, 0, 140, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, -83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 0, 5, 0, 0, 0, 1, 32, 156, 251, 229, 51, 168, 143, 203, 145, 22, 194, 13, 112, 83, -117, 0, 0, 12, 114, 0, 0, 68, 88, 66, 67, 86, 40, 86, 76, 35, 58, 186, 134, 62, 228, 70, 32, 248, 68, 199, 154, 1, 0, 0, 0, 12, 114, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 88, 7, 0, 0, 248, 9, 0, 0, 0, 112, 0, 0, 124, 112, 0, 0, 36, 113, 0, 0, 216, -113, 0, 0, 65, 111, 110, 57, 20, 7, 0, 0, 20, 7, 0, 0, 0, 2, 255, 255, 236, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 39, 1, 68, 66, 85, 71, 40, -0, 0, 0, 112, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 37, 0, 0, 0, 180, 0, 0, 0, 8, 0, 0, 0, 208, 3, 0, 0, 220, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, -116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, -105, 116, 101, 66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 40, 0, 0, 0, 0, 0, 255, 255, 164, 4, 0, 0, 0, 0, 255, 255, 188, -4, 0, 0, 0, 0, 255, 255, 212, 4, 0, 0, 0, 0, 255, 255, 224, 4, 0, 0, 0, 0, 255, 255, 236, 4, 0, 0, 0, 0, 255, 255, 248, 4, 0, 0, 149, 0, 0, 0, 4, 5, 0, 0, 149, 0, 0, 0, 20, 5, 0, 0, 148, 0, 0, 0, 32, 5, 0, 0, 148, 0, 0, 0, 48, -5, 0, 0, 149, 0, 0, 0, 60, 5, 0, 0, 144, 0, 0, 0, 76, 5, 0, 0, 144, 0, 0, 0, 88, 5, 0, 0, 148, 0, 0, 0, 104, 5, 0, 0, 152, 0, 0, 0, 124, 5, 0, 0, 154, 0, 0, 0, 144, 5, 0, 0, 151, 0, 0, 0, 160, 5, 0, 0, 154, 0, 0, 0, 180, -5, 0, 0, 154, 0, 0, 0, 200, 5, 0, 0, 154, 0, 0, 0, 212, 5, 0, 0, 154, 0, 0, 0, 224, 5, 0, 0, 155, 0, 0, 0, 240, 5, 0, 0, 156, 0, 0, 0, 4, 6, 0, 0, 156, 0, 0, 0, 16, 6, 0, 0, 156, 0, 0, 0, 36, 6, 0, 0, 157, 0, 0, 0, 56, -6, 0, 0, 157, 0, 0, 0, 72, 6, 0, 0, 157, 0, 0, 0, 84, 6, 0, 0, 161, 0, 0, 0, 100, 6, 0, 0, 161, 0, 0, 0, 112, 6, 0, 0, 161, 0, 0, 0, 124, 6, 0, 0, 161, 0, 0, 0, 136, 6, 0, 0, 161, 0, 0, 0, 156, 6, 0, 0, 162, 0, 0, 0, 176, -6, 0, 0, 162, 0, 0, 0, 188, 6, 0, 0, 162, 0, 0, 0, 200, 6, 0, 0, 162, 0, 0, 0, 220, 6, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, -0, 0, 0, 227, 1, 0, 0, 244, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 4, 2, 0, 0, 36, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, -0, 0, 0, 12, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 55, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, -105, 100, 55, 54, 0, 171, 171, 90, 2, 0, 0, 244, 1, 0, 0, 110, 2, 0, 0, 244, 1, 0, 0, 121, 2, 0, 0, 136, 2, 0, 0, 152, 2, 0, 0, 168, 2, 0, 0, 184, 2, 0, 0, 244, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 200, 2, 0, 0, 2, -0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 3, 0, 0, 0, 8, 0, 9, 0, 10, 0, 255, 255, 4, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 0, 34, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 35, 0, 0, 0, 0, -0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 16, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 14, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 20, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 119, 105, 122, 122, 108, 101, 67, 111, -108, 111, 114, 0, 171, 171, 171, 13, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 21, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 24, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 31, 0, 0, 0, 255, 255, 1, 0, 2, -0, 255, 255, 32, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 220, 1, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 28, 2, 0, 0, 0, 0, 0, 0, 40, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 220, 1, 0, 0, 80, 2, 0, 0, 240, -2, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 244, 1, 0, 0, 1, 0, 0, 0, 60, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 136, 2, 0, 0, 1, 0, 0, 0, 76, 3, 0, 0, 0, 0, 0, 0, 88, 3, 0, 0, 136, 2, 0, 0, 1, -0, 0, 0, 92, 3, 0, 0, 0, 0, 0, 0, 104, 3, 0, 0, 136, 2, 0, 0, 1, 0, 0, 0, 108, 3, 0, 0, 0, 0, 0, 0, 120, 3, 0, 0, 244, 1, 0, 0, 6, 0, 0, 0, 136, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, -76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, -0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 2, 0, 0, 3, 0, 0, 8, 128, 1, -0, 0, 176, 0, 0, 170, 160, 35, 0, 0, 2, 0, 0, 1, 128, 0, 0, 255, 128, 2, 0, 0, 3, 0, 0, 2, 128, 1, 0, 0, 176, 0, 0, 0, 160, 35, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 2, 0, 0, 3, 0, 0, 3, 128, 0, 0, 228, 129, 0, 0, 85, 160, 1, -0, 0, 2, 1, 0, 3, 128, 1, 0, 201, 176, 66, 0, 0, 3, 1, 0, 15, 128, 1, 0, 228, 128, 0, 8, 228, 160, 88, 0, 0, 4, 1, 0, 15, 128, 0, 0, 85, 128, 1, 0, 0, 128, 1, 0, 228, 128, 4, 0, 0, 4, 0, 0, 2, 128, 1, 0, 85, 128, 0, 0, 255, 160, 0, -0, 0, 160, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 4, 128, 1, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 0, 0, 18, 128, 0, 0, 170, 128, 0, 0, 170, 128, 0, 0, 85, 128, 7, 0, 0, 2, 0, -0, 2, 128, 0, 0, 85, 128, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 0, 0, 4, 128, 0, -0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 0, 0, 0, 128, 0, 0, 85, 128, 1, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 0, 0, 0, 128, 0, 0, 170, 128, 1, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 1, 0, 0, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, -0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 0, 0, 3, 128, 1, 0, 0, 128, 88, 0, 0, 4, 1, -0, 6, 128, 2, 0, 255, 128, 0, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 1, 0, 8, 128, 2, 0, 255, 128, 0, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 1, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 0, 0, 15, 128, 0, 0, 228, 176, 4, 0, 0, 4, 0, -0, 15, 128, 1, 0, 228, 128, 0, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 152, 2, 0, 0, 64, 0, 0, 0, 166, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, -112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 18, 16, 16, 0, 2, 0, 0, 0, 98, 16, 0, 3, 98, 16, 16, 0, 2, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, -32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 150, 21, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 6, -16, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, -0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 50, 0, 0, 15, 146, 0, 16, 0, 1, 0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, -64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, -0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, -0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, -0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 86, 5, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, -0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 0, 0, 0, 0, 166, -10, 16, 0, 1, 0, 0, 0, 6, 8, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, -80, 68, 66, 0, 102, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, +0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, +255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, +0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, +76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, +0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, +95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 121, 92, 177, 92, 119, 169, 150, 232, 100, 221, 122, 148, 57, 180, 151, 104, 0, 76, 95, 0, 0, 68, 88, 66, 67, 128, 39, 109, 146, 27, 67, 146, 146, 146, 240, 79, 33, 157, 227, 169, 170, 1, 0, 0, 0, 76, 95, +0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, 0, 0, 168, 6, 0, 0, 176, 92, 0, 0, 44, 93, 0, 0, 252, 93, 0, 0, 172, 94, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, +48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, +0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, 0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, +104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, +0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, 0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 104, 0, 0, 0, 44, 4, 0, 0, 104, 0, 0, 0, 60, 4, 0, 0, 104, 0, 0, 0, 76, 4, 0, 0, 104, 0, 0, 0, 92, 4, 0, 0, 138, 0, 0, 0, 108, 4, +0, 0, 138, 0, 0, 0, 128, 4, 0, 0, 140, 0, 0, 0, 140, 4, 0, 0, 140, 0, 0, 0, 152, 4, 0, 0, 142, 0, 0, 0, 164, 4, 0, 0, 143, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, +171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, +100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 5, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, +0, 0, 56, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 120, 1, 0, 0, 56, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 132, 1, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 10, 0, +0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 11, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 13, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 14, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 28, 2, 0, 0, 24, 1, 0, 0, 43, 2, 0, 0, 56, 1, 0, 0, 58, 2, 0, 0, 56, 1, 0, 0, 70, 2, 0, 0, 56, 1, 0, 0, 85, 2, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, +5, 0, 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 4, 0, 0, 0, 14, 0, 255, 255, 255, 255, +255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, +122, 122, 108, 101, 0, 171, 226, 2, 0, 0, 56, 1, 0, 0, 242, 2, 0, 0, 24, 1, 0, 0, 251, 2, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 56, 1, 0, 0, 10, 3, 0, 0, 56, 1, 0, 0, 19, 3, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, +6, 0, 28, 3, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 172, 1, 0, 0, 7, 0, 0, 0, 188, 1, 0, 0, 0, 1, +0, 0, 16, 2, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 76, 3, 0, 0, 3, 0, 0, 0, 92, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, +67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, +0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, +4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, +0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, +0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, +16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, +16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, +0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, +32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, +32, 0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, +0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -538,7 +461,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -546,379 +469,295 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 78, 77, 192, 50, 130, 227, 146, 69, 191, 245, 179, 238, 225, 101, 249, 176, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, +102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, +112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, +0, 0, 103, 159, 1, 0, 193, 33, 3, 0, 65, 185, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 198, 75, 121, 48, 58, 194, 126, 72, 145, 3, 199, 133, 150, 54, 69, 187, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, -81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, -76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, -83, 86, 95, 80, 111, 115, 105, 198, 90, 0, 0, 117, 131, 1, 0, 190, 254, 0, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 31, 155, 2, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 203, -103, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 193, 228, 0, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, -83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, -119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, -100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, -49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, -114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, -116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, -59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, -114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, -101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, -105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, -95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, -108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, -78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, -114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, -97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, -13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, -32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, -115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, -119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, -49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, -117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, -32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, -97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, -10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, -97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, -46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, -86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, -114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, -40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, -61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, -95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, -97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, -55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, -79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 97, 23, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, -115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, -52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, -111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 53, -54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, -52, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, -100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 75, 187, 85, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 178, 73, 61, 255, 78, 22, 0, 0, 1, 0, 0, 0, 137, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, -111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, -0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 204, 5, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, -0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, -0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 8, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, -0, 48, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, -0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 40, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 104, 0, 0, 0, 1, -0, 48, 2, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 60, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, -0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 12, 0, 0, 0, 174, -0, 77, 17, 140, 0, 0, 0, 200, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 116, 11, 32, 13, 45, 6, 18, 3, 36, 13, 116, 6, 19, 3, 84, 9, 9, 13, 42, 6, 8, 3, 36, 13, 57, 6, 4, 3, 60, 13, 42, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, -6, 10, 3, 56, 13, 82, 6, 2, 12, 36, 76, 8, 0, 9, 68, 13, 87, 1, 104, 6, 29, 3, 0, 9, 13, 13, 36, 6, 18, 3, 36, 9, 9, 13, 44, 3, 40, 9, 27, 13, 115, 6, 19, 3, 44, 9, 20, 13, 41, 6, 8, 3, 36, 9, 48, 13, 54, 6, 4, 3, 60, 9, 38, 3, -28, 9, 29, 13, 55, 3, 28, 9, 24, 13, 56, 3, 28, 9, 20, 3, 20, 9, 26, 13, 41, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 81, 6, 2, 12, 36, 76, 0, 50, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 0, 0, 0, 0, 22, 0, 80, 17, 0, -0, 5, 0, 4, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 4, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 232, 0, 132, 0, 8, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 4, 1, 0, 0, 1, -0, 148, 1, 32, 1, 76, 0, 12, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 236, 1, 0, 0, 1, 0, 132, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 36, 2, 0, 0, 1, 0, 76, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, -0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 64, 1, 0, 0, 1, 0, 28, 0, 16, 0, 0, 0, 42, -0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 64, 1, 0, 0, 1, 0, 28, 0, 28, -0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 1, 0, 0, 1, -0, 208, 0, 16, 0, 0, 0, 38, 0, 77, 17, 248, 2, 0, 0, 196, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 69, 11, 32, 4, 36, 8, 0, 9, 12, 13, 68, 1, 104, 12, 36, 0, 0, 0, 0, 66, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 104, 97, 100, 105, 110, -103, 95, 105, 100, 51, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 140, -0, 0, 0, 1, 0, 40, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 104, 234, 249, 150, 59, 95, 0, 189, 242, 186, 3, 14, 191, 211, 7, 240, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, -0, 0, 0, 1, 0, 1, 0, 152, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 104, 0, 0, 0, 181, 0, 0, 128, 104, 0, 0, 0, 181, 0, 0, 0, 140, 0, 0, 0, 181, 0, 0, 128, 140, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 181, 0, 0, 128, 180, -0, 0, 0, 181, 0, 0, 0, 224, 0, 0, 0, 181, 0, 0, 128, 224, 0, 0, 0, 181, 0, 0, 0, 4, 1, 0, 0, 181, 0, 0, 128, 4, 1, 0, 0, 181, 0, 0, 0, 64, 1, 0, 0, 181, 0, 0, 128, 64, 1, 0, 0, 181, 0, 0, 0, 92, 1, 0, 0, 181, 0, 0, 128, 92, -1, 0, 0, 181, 0, 0, 0, 120, 1, 0, 0, 181, 0, 0, 128, 120, 1, 0, 0, 181, 0, 0, 0, 148, 1, 0, 0, 181, 0, 0, 128, 148, 1, 0, 0, 181, 0, 0, 0, 168, 1, 0, 0, 181, 0, 0, 128, 168, 1, 0, 0, 181, 0, 0, 0, 200, 1, 0, 0, 181, 0, 0, 128, 200, -1, 0, 0, 181, 0, 0, 0, 236, 1, 0, 0, 181, 0, 0, 128, 236, 1, 0, 0, 181, 0, 0, 0, 0, 2, 0, 0, 181, 0, 0, 128, 0, 2, 0, 0, 181, 0, 0, 0, 36, 2, 0, 0, 181, 0, 0, 128, 36, 2, 0, 0, 181, 0, 0, 0, 56, 2, 0, 0, 181, 0, 0, 128, 56, -2, 0, 0, 181, 0, 0, 0, 76, 2, 0, 0, 181, 0, 0, 128, 76, 2, 0, 0, 181, 0, 0, 0, 112, 2, 0, 0, 181, 0, 0, 128, 112, 2, 0, 0, 181, 0, 0, 0, 148, 2, 0, 0, 184, 0, 0, 128, 148, 2, 0, 0, 184, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, -0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, -0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, -0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, -0, 1, 0, 11, 16, 0, 0, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 234, 0, 0, 242, 241, 10, -0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 88, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, -0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 130, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, -55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 60, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, -0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 126, 0, 3, 18, 13, -21, 3, 0, 64, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 4, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 12, 0, 67, 111, 108, 111, 114, 95, 105, -100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 28, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 5, -0, 0, 0, 9, 16, 0, 0, 136, 48, 2, 0, 151, 210, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, -32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, -111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, -105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, -120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, -49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, -105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, -116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, -61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, -109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, -76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, -10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, -109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, -71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, -53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, -95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, -108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, -105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, -100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, -41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, -46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, -110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, -105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, -66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, -115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, -97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, -114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, -95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, -55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, -40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, -95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, -100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, -95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, -32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, -10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 137, 0, 0, 0, -18, 1, 0, 0, 1, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 48, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, -0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, +102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, +112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, +49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, +111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, +40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, +107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, +116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, +105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, +72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, +83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, +82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, +51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, +50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, +32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, +111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, +109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, +83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 131, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 0, 99, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 97, 55, 54, 53, 100, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 17, 53, 13, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 143, 177, 143, 206, 14, 0, 0, 1, 0, +0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, +41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, +95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 124, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, +0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, +117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 120, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 37, 6, 12, 12, 128, 128, 80, 8, 0, 13, 36, 1, 128, 228, 12, 128, 128, 0, 0, 38, 0, 77, 17, 244, 3, 0, 0, 116, 4, 0, 0, 1, 16, +0, 0, 7, 0, 9, 5, 13, 24, 6, 2, 12, 128, 128, 80, 8, 0, 13, 23, 1, 128, 228, 12, 128, 128, 0, 0, 42, 0, 77, 17, 28, 4, 0, 0, 112, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 80, 8, 0, 9, 33, 13, 82, 1, 128, 228, 12, +128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 161, 123, 228, 163, 123, 235, 180, 4, 152, 115, 14, 39, 91, 198, 127, 247, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, +0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, 128, 148, 0, 0, 0, 152, 0, 0, 0, 168, 0, 0, 0, 152, 0, 0, 128, 168, 0, 0, 0, 152, 0, 0, 0, 188, 0, 0, 0, 152, 0, 0, 128, 188, 0, +0, 0, 152, 0, 0, 0, 208, 0, 0, 0, 152, 0, 0, 128, 208, 0, 0, 0, 152, 0, 0, 0, 228, 0, 0, 0, 145, 0, 0, 128, 228, 0, 0, 0, 145, 0, 0, 0, 4, 1, 0, 0, 145, 0, 0, 128, 4, 1, 0, 0, 145, 0, 0, 0, 36, 1, 0, 0, 145, 0, 0, 128, 36, 1, +0, 0, 145, 0, 0, 0, 68, 1, 0, 0, 145, 0, 0, 128, 68, 1, 0, 0, 145, 0, 0, 0, 100, 1, 0, 0, 152, 0, 0, 128, 100, 1, 0, 0, 152, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, +0, 0, 124, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, +97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 11, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 16, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, +0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, +3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, +0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, +105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, +3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, +242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, +0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 18, 216, 0, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, -0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, +49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, +111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, +40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, +107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, +116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, +105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, +72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, +83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, +82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, +51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, +50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, +32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, +111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, +109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, +83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, +0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, +0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 34, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, -0, 0, 0, 34, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 13, 16, 0, 0, 8, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, +114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 198, 75, 121, 48, 58, 194, 126, 72, 145, 3, 199, 133, 150, 54, 69, 187, 181, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, -100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, -115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, -52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, -0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 5, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 255, 255, 0, 0, 0, 0, 152, 2, 0, 0, 32, 0, 0, 96, 0, 0, 116, 105, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, -255, 255, 255, 0, 0, 0, 0, 152, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, -97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, -95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 53, 54, 51, 98, 56, 101, 52, 57, 97, 57, 52, 56, 49, 98, 57, 54, 57, 99, 97, 102, 52, 97, 100, 52, 56, 57, 57, 97, 54, 55, 48, 48, 46, 104, 108, 115, 108, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 17, 1, 0, 0, 144, 2, 0, 0, 155, 1, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 145, 23, 0, 0, 128, 0, 0, 0, 78, 22, 0, 0, 244, 7, 0, 0, 88, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 56, -2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 46, 0, 0, 0, 39, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, -0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 21, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, -0, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 42, 0, 0, 0, 44, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, +0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, +48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 78, 77, 192, 50, 130, 227, 146, 69, 191, 245, 179, 238, 225, 101, 249, 176, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, +47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 97, 55, 54, 53, 100, 56, 0, 4, 0, 0, 0, +6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 72, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 179, 15, 0, 0, 128, 0, 0, 0, 206, 14, 0, 0, 212, 5, +0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 36, 0, 0, 0, 30, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, +0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, +0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -930,16 +769,39 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 119, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, -52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 172, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, -1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 6, 0, 0, 140, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, -79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, +111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, +82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, +0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs new file mode 100644 index 0000000000..542a9c4142 --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs @@ -0,0 +1,143 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [SpriteBatch] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + public partial class SpriteBatch + { + private static readonly byte[] binaryBytecode = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, +0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, +2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 205, 110, 243, 195, 215, 68, 58, 136, 133, 123, 105, 157, 89, 65, 222, 57, 0, 74, 11, 0, 0, 68, 88, 66, 67, 42, 181, 74, 147, 170, 152, 11, 218, 117, 228, 22, 161, 9, 159, 40, 250, 1, 0, 0, 0, 74, 11, 0, 0, 5, 0, 0, 0, 52, +0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 110, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, +240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 52, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, +0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 212, 8, 0, 0, 96, 0, 0, 0, 53, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 188, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 44, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, +0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, +36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, +0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 95, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, +49, 65, 128, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, +140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, +40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 128, 50, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 80, 3, 0, 0, 192, 61, 195, 229, 79, 216, 67, 72, 126, 8, 52, 195, 66, +160, 0, 2, 0, 0, 160, 24, 17, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 55, 13, 151, 63, 97, 15, 33, 249, 43, 33, 173, 196, 228, 23, 183, 141, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +2, 0, 0, 128, 194, 76, 0, 0, 0, 16, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 128, 0, +0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 128, 24, 0, 0, 0, 6, 2, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, +109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, +32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, +0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 36, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 50, 0, 0, +0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, +40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 3, 2, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 8, 0, 0, 0, 138, 129, 0, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 8, 0, 0, 0, 74, 142, 0, 0, 0, 0, 102, 0, 136, 0, +0, 0, 160, 240, 8, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 136, 0, 0, 0, 160, 28, 10, 134, 0, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 2, 0, 0, 128, 82, 160, 6, 0, +0, 128, 146, 40, 132, 2, 1, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, +151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, +84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 184, 54, +12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 4, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 12, 38, 8, 77, 180, 33, 8, 38, 8, 205, 180, 97, 9, 196, 96, 12, 200, 160, 12, +204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 202, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 2, 102, 195, 194, 136, 193, 24, 144, 193, 26, 152, 1, 145, 6, 12, 25, 0, 19, 4, 162, 218, 16, 180, 193, 4, 161, 145, 54, 44, 109, 32, 6, 99, 64, +6, 110, 96, 6, 196, 27, 180, 1, 25, 0, 27, 136, 51, 80, 3, 54, 128, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 198, 12, 54, 44, 129, 28, 140, 193, 28, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 160, 131, 13, 67, 28, 212, 1, 192, 51, 152, 130, 147, 75, 163, 43, +19, 10, 163, 27, 67, 155, 66, 11, 35, 43, 147, 227, 49, 11, 99, 155, 43, 243, 113, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 119, 96, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, +115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, +163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 193, 29, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 232, 180, +25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 158, 225, 242, 157, 199, 167, 26, 32, 194, 252, 226, 182, 109, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 35, 128, 134, 203, 119, 30, 95, 2, +152, 103, 33, 252, 226, 182, 173, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 97, 32, 0, 0, 145, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 56, 102, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 103, 144, 133, 65, 24, 88, 216, +136, 65, 2, 128, 32, 24, 56, 104, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 105, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 106, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 107, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 56, 108, +224, 133, 129, 25, 112, 221, 136, 65, 2, 128, 32, 24, 56, 109, 240, 137, 193, 25, 112, 222, 136, 65, 2, 128, 32, 24, 56, 110, 0, 6, 99, 128, 6, 220, 55, 98, 144, 0, 32, 8, 6, 206, 27, 132, 1, 25, 164, 1, 7, 6, 35, 6, 9, 0, 130, 96, 224, 192, 129, 24, 112, 106, 0, 6, +97, 96, 1, 7, 129, 17, 3, 3, 0, 65, 48, 120, 226, 128, 11, 134, 27, 184, 96, 152, 101, 8, 132, 96, 196, 32, 1, 64, 16, 12, 36, 57, 224, 194, 192, 13, 220, 0, 13, 70, 12, 18, 0, 4, 193, 64, 154, 131, 174, 12, 222, 224, 13, 210, 96, 196, 224, 1, 64, 16, 12, 168, 57, 224, +2, 1, 122, 186, 238, 12, 206, 224, 12, 186, 209, 132, 0, 24, 77, 16, 130, 209, 132, 65, 24, 77, 32, 134, 89, 130, 97, 196, 32, 1, 64, 16, 12, 164, 60, 24, 3, 52, 168, 131, 58, 120, 131, 17, 131, 4, 0, 65, 48, 144, 244, 128, 12, 216, 192, 14, 236, 0, 14, 70, 12, 30, 0, 4, +193, 128, 210, 131, 49, 8, 132, 203, 34, 3, 50, 112, 3, 55, 112, 3, 50, 24, 77, 8, 128, 209, 4, 33, 24, 77, 24, 132, 209, 4, 98, 152, 37, 24, 6, 42, 0, 43, 64, 132, 129, 10, 0, 11, 16, 97, 160, 2, 208, 2, 68, 24, 168, 0, 184, 0, 17, 204, 90, 3, 8, 140, 24, 24, +0, 8, 130, 193, 99, 10, 113, 16, 12, 55, 196, 65, 48, 204, 50, 16, 69, 96, 71, 27, 72, 192, 130, 58, 128, 128, 33, 111, 32, 1, 11, 238, 0, 2, 54, 12, 18, 48, 65, 144, 128, 9, 1, 4, 70, 12, 12, 0, 4, 193, 224, 121, 133, 57, 8, 70, 12, 12, 0, 4, 193, 224, 129, 133, +57, 8, 108, 14, 130, 8, 88, 48, 7, 18, 176, 128, 14, 32, 48, 75, 96, 204, 18, 24, 3, 21, 128, 64, 136, 65, 49, 80, 1, 184, 3, 33, 6, 133, 157, 129, 29, 64, 96, 196, 192, 0, 64, 16, 12, 158, 91, 16, 133, 96, 184, 65, 20, 130, 97, 186, 1, 187, 130, 233, 134, 204, 16, 166, +27, 250, 192, 24, 108, 171, 3, 9, 24, 81, 7, 18, 48, 162, 14, 36, 96, 68, 29, 72, 192, 136, 58, 128, 128, 17, 117, 0, 1, 35, 234, 0, 2, 70, 212, 1, 4, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 168, 5, 98, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, +248, 5, 90, 24, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 152, 5, 97, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, 248, 5, 89, 8, 16, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 59, 95, 18, 105, 199, 9, 209, 190, 45, 143, 233, 76, 24, 234, 125, 51, +0, 25, 12, 0, 0, 68, 88, 66, 67, 178, 22, 21, 40, 224, 54, 248, 92, 5, 21, 208, 206, 31, 171, 253, 36, 1, 0, 0, 0, 25, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 189, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, +0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, +105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 180, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, +0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, +0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 68, 88, 73, 76, 84, 8, 0, 0, 96, 0, 1, 0, 21, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 60, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 12, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, +4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, +24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, +96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, +29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, +212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, +2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, +113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, +48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, +0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 25, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, +67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 50, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, +0, 128, 178, 43, 144, 2, 42, 176, 82, 40, 6, 82, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, +1, 81, 0, 19, 132, 35, 225, 1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, +44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 180, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, +80, 182, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 133, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 9, 2, 33, 109, 8, +204, 96, 195, 98, 6, 218, 198, 157, 1, 71, 132, 129, 25, 112, 192, 134, 192, 153, 32, 40, 206, 134, 197, 209, 54, 46, 13, 56, 66, 13, 28, 14, 216, 80, 124, 98, 80, 6, 104, 176, 6, 27, 150, 64, 219, 184, 206, 35, 188, 128, 3, 54, 44, 132, 182, 113, 96, 224, 17, 97, 64, 112, 192, 134, +101, 12, 180, 141, 35, 3, 143, 8, 131, 49, 224, 128, 13, 139, 25, 104, 27, 119, 6, 30, 161, 6, 102, 192, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 10, 180, 97, 113, 226, 96, 147, 131, 46, 12, 136, 48, 112, 56, 96, 67, 209, 6, 110, 240, 6, 112, 48, 7, 27, +6, 54, 160, 3, 128, 103, 48, 5, 39, 151, 70, 87, 38, 20, 70, 55, 134, 54, 133, 22, 70, 86, 38, 199, 99, 22, 198, 54, 87, 230, 227, 98, 53, 213, 20, 150, 230, 246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 236, 160, 14, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, +148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, +134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 236, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, +14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 235, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 164, 225, 242, 157, 199, 23, 34, 2, 152, 136, 16, 104, 134, 133, 176, 129, 109, 184, 124, 231, 241, 133, 128, +42, 10, 34, 42, 29, 96, 40, 9, 3, 16, 48, 191, 184, 109, 35, 168, 134, 203, 119, 30, 95, 154, 156, 136, 64, 169, 233, 161, 38, 191, 184, 109, 0, 0, 97, 32, 0, 0, 172, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 156, 116, 93, 80, 52, 98, 144, 0, 32, 8, 6, 75, +55, 97, 24, 36, 141, 24, 36, 0, 8, 130, 193, 226, 81, 88, 38, 77, 35, 6, 9, 0, 130, 96, 176, 124, 85, 166, 73, 212, 136, 65, 2, 128, 32, 24, 44, 96, 96, 105, 155, 84, 141, 24, 36, 0, 8, 130, 193, 18, 6, 215, 198, 73, 214, 136, 65, 2, 128, 32, 24, 44, 98, 128, 73, 157, +117, 141, 24, 36, 0, 8, 130, 193, 50, 6, 217, 228, 89, 216, 136, 65, 2, 128, 32, 24, 44, 100, 160, 81, 159, 149, 141, 24, 36, 0, 8, 130, 193, 82, 6, 91, 5, 6, 150, 54, 98, 144, 0, 32, 8, 6, 139, 25, 112, 85, 24, 104, 219, 136, 65, 2, 128, 32, 24, 44, 103, 208, 89, 98, +160, 113, 35, 6, 9, 0, 130, 96, 176, 160, 129, 119, 141, 129, 214, 141, 24, 36, 0, 8, 130, 193, 146, 6, 31, 70, 6, 154, 55, 98, 144, 0, 32, 8, 6, 139, 26, 128, 1, 24, 148, 129, 247, 141, 24, 36, 0, 8, 130, 193, 163, 6, 89, 87, 6, 101, 128, 213, 25, 136, 1, 142, 24, 28, +0, 8, 130, 65, 180, 6, 153, 16, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 84, 27, 116, 80, 65, 26, 224, 136, 193, 1, 128, 32, 24, 68, 114, 0, 6, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 116, 48, 6, 80, 1, 28, 224, 136, 193, +1, 128, 32, 24, 68, 121, 112, 6, 80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 123, 144, 6, 80, 193, 29, 224, 136, 193, 1, 128, 32, 24, 68, 160, 224, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 96, 150, 25, 72, 192, 160, 51, 144, +128, 41, 104, 32, 1, 35, 210, 64, 2, 182, 173, 129, 4, 44, 40, 32, 96, 86, 27, 72, 192, 2, 3, 2, 22, 189, 129, 4, 44, 56, 32, 96, 76, 28, 72, 192, 2, 4, 2, 70, 6, 116, 32, 1, 11, 16, 8, 216, 103, 7, 18, 176, 0, 129, 128, 105, 120, 32, 1, 11, 16, 8, 88, 165, +7, 18, 176, 0, 129, 128, 181, 65, 31, 72, 192, 2, 4, 2, 134, 6, 127, 32, 1, 11, 16, 8, 216, 24, 132, 130, 4, 44, 64, 32, 96, 222, 40, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 228, 130, 47, 220, 194, 49, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, +46, 248, 130, 45, 20, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 228, 130, 47, 212, 194, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, 46, 248, 2, 45, 4, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 248, 130, 47, 220, 194, 41, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, 224, 11, +190, 96, 11, 166, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, 47, 248, 194, 45, 132, 194, 136, 65, 2, 128, 32, 24, 72, 224, 176, 10, 189, 224, 11, 182, 0, 10, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 244, 130, 47, 212, 194, 31, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, 208, +11, 190, 64, 11, 126, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 194, 44, 248, 194, 45, 244, 193, 136, 65, 2, 128, 32, 24, 72, 224, 176, 10, 179, 224, 11, 182, 192, 7, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 204, 130, 47, 212, 194, 30, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, +48, 11, 190, 64, 11, 122, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 130, 44, 248, 194, 45, 228, 1, 2, 0, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs index 244ae25de2..2feb0a7d1a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -1,81 +1,80 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-d3d11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { public partial class SpriteBatch { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, -67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, -103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 68, 4, 71, 244, 184, -181, 240, 124, 216, 8, 124, 143, 206, 144, 169, 245, 0, 40, 112, 0, 0, 68, 88, 66, 67, 231, 8, 38, 111, 217, 222, 172, 38, 118, 193, 193, 232, 186, 253, 101, 161, 1, 0, 0, 0, 40, 112, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 116, 5, 0, 0, 116, 7, 0, 0, 124, 109, 0, 0, -248, 109, 0, 0, 196, 110, 0, 0, 116, 111, 0, 0, 65, 111, 110, 57, 48, 5, 0, 0, 48, 5, 0, 0, 0, 2, 254, 255, 252, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 245, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 19, 0, 0, 0, 180, 0, 0, 0, 3, 0, 0, 0, 108, 3, 0, 0, 76, 1, 0, 0, 67, 58, 92, 100, -101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, -110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, -108, 115, 108, 0, 40, 0, 0, 0, 0, 0, 255, 255, 220, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, 255, 0, 4, 0, 0, 0, 0, 255, 255, 12, 4, 0, 0, 0, 0, 255, 255, 24, 4, 0, 0, 0, 0, 255, 255, 36, 4, 0, 0, 172, 0, 0, 0, 48, 4, 0, 0, -168, 0, 0, 0, 64, 4, 0, 0, 168, 0, 0, 0, 84, 4, 0, 0, 168, 0, 0, 0, 104, 4, 0, 0, 172, 0, 0, 0, 120, 4, 0, 0, 172, 0, 0, 0, 136, 4, 0, 0, 172, 0, 0, 0, 152, 4, 0, 0, 186, 0, 0, 0, 168, 4, 0, 0, 186, 0, 0, 0, 188, 4, 0, 0, -168, 0, 0, 0, 200, 4, 0, 0, 191, 0, 0, 0, 212, 4, 0, 0, 191, 0, 0, 0, 224, 4, 0, 0, 193, 0, 0, 0, 236, 4, 0, 0, 86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, 0, 3, 0, -1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 171, 171, 83, 1, 0, 0, 104, 1, 0, 0, 120, 1, 0, 0, 104, 1, 0, 0, 131, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, -176, 1, 0, 0, 192, 1, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 208, 1, 0, 0, 6, 0, 0, 0, 255, 255, 255, 255, 2, 0, 255, 255, 9, 0, 0, 0, 4, 0, 5, 0, 6, 0, 255, 255, 13, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, -14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 15, 0, 0, 0, 255, 255, 255, 255, 255, 255, 7, 0, 16, 0, 0, 0, 8, 0, 255, 255, 255, 255, 255, 255, 17, 0, 0, 0, 255, 255, 9, 0, 10, 0, 255, 255, 18, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 0, 95, 95, 105, 110, -112, 117, 116, 95, 95, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 114, 2, 0, 0, 104, 1, 0, 0, 120, 1, 0, 0, 104, 1, 0, 0, 131, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, 176, 1, 0, 0, 192, 1, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, -1, 0, 15, 0, 1, 0, 5, 0, 128, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 2, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 3, 0, 0, 0, 8, 0, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 9, 0, 10, 0, 255, 255, 255, 255, 5, 0, 0, 0, -11, 0, 12, 0, 13, 0, 14, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 115, 116, 114, 101, 97, 109, 115, 0, 171, 114, 2, 0, 0, 104, 1, 0, 0, 120, 1, 0, 0, 104, 1, 0, 0, 131, 1, 0, 0, 144, 1, 0, 0, 160, 1, 0, 0, 176, 1, 0, 0, 192, 1, 0, 0, -104, 1, 0, 0, 83, 1, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 8, 3, 0, 0, 10, 0, 0, 0, 15, 0, 255, 255, 255, 255, 255, 255, 11, 0, 0, 0, 255, 255, 16, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 18, 0, 255, 255, -0, 0, 0, 0, 76, 1, 0, 0, 248, 1, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0, 76, 1, 0, 0, 104, 2, 0, 0, 168, 2, 0, 0, 5, 0, 0, 0, 184, 2, 0, 0, 244, 2, 0, 0, 255, 2, 0, 0, 56, 3, 0, 0, 3, 0, 0, 0, 72, 3, 0, 0, 77, 105, 99, 114, -111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, -5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, -0, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 1, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 1, 0, 228, 144, 0, 0, 228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 0, 0, 7, 224, 0, 0, 228, 128, 1, 0, 228, 144, -9, 0, 0, 3, 0, 0, 1, 128, 0, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 0, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 0, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, -0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 8, 224, 1, 0, 255, 144, 1, 0, 0, 2, 1, 0, 1, 224, 2, 0, 0, 144, 1, 0, 0, 2, 1, 0, 6, 224, 3, 0, 208, 144, 1, 0, 0, 2, 2, 0, 15, 224, 4, 0, 228, 144, -255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, -18, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 4, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, -18, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 98, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 3, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, -0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, -0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, -18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, -2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, -1, 0, 0, 0, 54, 0, 0, 5, 18, 32, 16, 0, 2, 0, 0, 0, 10, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 98, 32, 16, 0, 2, 0, 0, 0, 6, 17, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 4, 0, 0, 0, -62, 0, 0, 1, 83, 80, 68, 66, 0, 102, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, -47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, +114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, +1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, +88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, +140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, +105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 39, 157, 68, 28, 42, 149, 249, 159, 238, 192, 103, 70, 40, 36, 244, 0, 212, 97, 0, 0, 68, 88, 66, 67, 220, 182, 27, 10, 229, 195, +112, 16, 142, 228, 195, 14, 178, 185, 52, 133, 1, 0, 0, 0, 212, 97, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 95, 0, 0, 112, 96, 0, 0, 36, 97, 0, 0, 160, 97, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, +255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, +0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, +255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 91, 0, 0, 0, 220, 4, 0, 0, 106, 0, 0, 0, 236, 4, 0, 0, 106, 0, 0, 0, 252, 4, 0, 0, 97, 0, +0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 36, 5, 0, 0, 104, 0, 0, 0, 52, 5, 0, 0, 109, 0, 0, 0, 72, 5, 0, 0, 111, 0, 0, 0, 92, 5, 0, 0, 108, 0, 0, 0, 108, 5, 0, 0, 111, 0, 0, 0, 128, 5, 0, 0, 111, 0, +0, 0, 148, 5, 0, 0, 111, 0, 0, 0, 160, 5, 0, 0, 111, 0, 0, 0, 172, 5, 0, 0, 112, 0, 0, 0, 188, 5, 0, 0, 113, 0, 0, 0, 208, 5, 0, 0, 113, 0, 0, 0, 220, 5, 0, 0, 113, 0, 0, 0, 240, 5, 0, 0, 114, 0, 0, 0, 4, 6, 0, 0, 114, 0, +0, 0, 20, 6, 0, 0, 114, 0, 0, 0, 32, 6, 0, 0, 118, 0, 0, 0, 48, 6, 0, 0, 118, 0, 0, 0, 60, 6, 0, 0, 118, 0, 0, 0, 72, 6, 0, 0, 118, 0, 0, 0, 84, 6, 0, 0, 118, 0, 0, 0, 104, 6, 0, 0, 119, 0, 0, 0, 124, 6, 0, 0, 119, 0, +0, 0, 136, 6, 0, 0, 119, 0, 0, 0, 148, 6, 0, 0, 119, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 95, 52, 53, 52, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, +3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, +0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, +4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, +111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, +3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, +0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, +0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, +40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, +0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, +0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, +2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, +0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, +85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, +0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, +255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, +255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, +228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, +0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, +0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, +0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, +16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, +0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, +0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, +16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, +0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, +128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, +16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, +48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -83,7 +82,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -91,377 +90,311 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, +0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 114, 78, 3, 249, 109, 197, 166, 74, 147, 45, +88, 122, 114, 201, 110, 163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 182, 129, 101, 77, 208, 30, 209, 73, 185, 9, 245, 65, 74, 202, 253, 227, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, -85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, -58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 198, 90, 0, 0, 117, 131, 1, 0, 5, 254, 3, 0, 156, 202, 1, 0, 38, 247, 2, 0, 190, 254, 0, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 168, 74, 1, 0, 172, 19, 0, 0, 94, 184, 2, 0, 80, 133, 1, 0, -116, 39, 1, 0, 25, 96, 3, 0, 65, 36, 1, 0, 194, 56, 1, 0, 103, 159, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, -50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, -100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, -79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, -84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, -66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, -32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, -50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, -105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, -95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, -69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, -105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, -48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, -32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, -32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, -50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, -40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, -53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, -111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, -115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, -32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, -111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, -108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, -77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, -112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, -115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, -112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, -95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, -100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 13, 10, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, -112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, -116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 176, 23, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, -65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, -49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, -110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, -116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, -98, 95, 105, 100, 55, 52, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 27, 226, 48, 1, 128, 0, 0, 0, 110, 125, 77, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 116, 14, 50, 26, 157, 22, 0, 0, 1, 0, 0, 0, 137, 0, 0, 0, 138, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, -100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, -108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 104, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, 0, 0, 1, 0, 160, 86, -83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, -1, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, -8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, -156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, -1, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, -52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 68, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, -156, 0, 0, 0, 1, 0, 92, 1, 72, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 76, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, -117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, -2, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, -60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, -156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, -2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, -0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, -156, 0, 0, 0, 1, 0, 92, 1, 12, 0, 0, 0, 38, 0, 77, 17, 140, 0, 0, 0, 40, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 83, 11, 32, 4, 128, 128, 8, 0, 9, 35, 13, 82, 1, 128, 156, 12, 128, 128, 0, 2, 0, 78, 17, 54, 0, 77, 17, 140, 0, 0, 0, -100, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 93, 6, 4, 12, 128, 136, 128, 128, 8, 0, 9, 35, 13, 66, 1, 129, 28, 3, 0, 9, 27, 13, 81, 3, 60, 9, 19, 13, 82, 12, 28, 48, 0, 0, 0, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, -1, 0, 0, 0, 16, 1, 72, 36, 132, 223, 221, 37, 35, 87, 150, 249, 16, 65, 145, 190, 186, 0, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 194, 0, 0, 128, -156, 0, 0, 0, 194, 0, 0, 0, 188, 0, 0, 0, 194, 0, 0, 128, 188, 0, 0, 0, 194, 0, 0, 0, 220, 0, 0, 0, 194, 0, 0, 128, 220, 0, 0, 0, 194, 0, 0, 0, 252, 0, 0, 0, 194, 0, 0, 128, 252, 0, 0, 0, 194, 0, 0, 0, 28, 1, 0, 0, 197, 0, 0, 128, -28, 1, 0, 0, 197, 0, 0, 0, 88, 1, 0, 0, 197, 0, 0, 128, 88, 1, 0, 0, 197, 0, 0, 0, 136, 1, 0, 0, 197, 0, 0, 128, 136, 1, 0, 0, 197, 0, 0, 0, 164, 1, 0, 0, 205, 0, 0, 128, 164, 1, 0, 0, 205, 0, 0, 0, 184, 1, 0, 0, 205, 0, 0, 128, -184, 1, 0, 0, 205, 0, 0, 0, 204, 1, 0, 0, 205, 0, 0, 128, 204, 1, 0, 0, 205, 0, 0, 0, 224, 1, 0, 0, 205, 0, 0, 128, 224, 1, 0, 0, 205, 0, 0, 0, 244, 1, 0, 0, 205, 0, 0, 128, 244, 1, 0, 0, 205, 0, 0, 0, 5, 0, 24, 0, 5, 0, 23, 0, -5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 24, 0, 5, 0, 23, 0, 5, 0, 24, 0, 5, 0, 23, 0, 9, 0, 62, 0, 30, 0, 61, 0, 9, 0, 62, 0, 30, 0, 61, 0, 9, 0, 62, 0, 30, 0, 61, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, -5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, 8, 0, 0, 0, -0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, -13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 13, 21, 3, 0, 0, 16, 0, 0, 60, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 34, 0, 5, 21, 6, 0, 0, 0, -9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, -11, 16, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 0, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 15, 16, 0, 0, 23, 0, 1, 0, 14, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, -0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 224, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, -0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 122, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, -0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, -13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 60, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 130, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, -13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, -10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 154, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, -16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 60, 118, 3, 0, 147, 79, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, -122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, -79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, -102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, -114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, -50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, -77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, -116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, -114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, -109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, -77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, -109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, -105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, -59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, -78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, -71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, -95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, -100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, -83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, -105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, -40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, -32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, -32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, -59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, -32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, -32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, -32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, -71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, -83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, -110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, -85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, -112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, -10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, -32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, -32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 18, 1, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 52, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, -0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 241, 26, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, +3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 33, 155, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 37, 52, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, -0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 0, 241, 26, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, +125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, 32, +32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, +53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, +32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, +48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, +101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, +48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, +61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, +32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, +32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, +41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, +83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, +32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, +123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, +111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, +32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, +116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 212, 14, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, +97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 57, 97, 56, 55, 52, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 89, 41, 1, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, +0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 14, 44, 175, 59, 31, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, +10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, +0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, +0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, +88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, +0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 61, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 60, 1, +104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, +3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, +6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, +13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 53, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, +152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, +0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, +4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, +110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, +0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, +114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, +20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, +78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 203, 39, 249, 232, 99, 206, 164, 195, 125, 69, 140, 61, 231, 249, 19, 238, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, +0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 144, 0, 0, 128, 104, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 128, 144, 0, 0, 0, 144, 0, 0, 0, 188, 0, 0, 0, 144, 0, 0, 128, 188, 0, 0, 0, 144, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 128, 200, 0, +0, 0, 144, 0, 0, 0, 236, 0, 0, 0, 144, 0, 0, 128, 236, 0, 0, 0, 144, 0, 0, 0, 0, 1, 0, 0, 144, 0, 0, 128, 0, 1, 0, 0, 144, 0, 0, 0, 4, 1, 0, 0, 144, 0, 0, 128, 4, 1, 0, 0, 144, 0, 0, 0, 40, 1, 0, 0, 144, 0, 0, 128, 40, 1, +0, 0, 144, 0, 0, 0, 44, 1, 0, 0, 144, 0, 0, 128, 44, 1, 0, 0, 144, 0, 0, 0, 104, 1, 0, 0, 144, 0, 0, 128, 104, 1, 0, 0, 144, 0, 0, 0, 132, 1, 0, 0, 144, 0, 0, 128, 132, 1, 0, 0, 144, 0, 0, 0, 160, 1, 0, 0, 144, 0, 0, 128, 160, 1, +0, 0, 144, 0, 0, 0, 188, 1, 0, 0, 144, 0, 0, 128, 188, 1, 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 144, 0, 0, 128, 208, 1, 0, 0, 144, 0, 0, 0, 240, 1, 0, 0, 144, 0, 0, 128, 240, 1, 0, 0, 144, 0, 0, 0, 20, 2, 0, 0, 144, 0, 0, 128, 20, 2, +0, 0, 144, 0, 0, 0, 40, 2, 0, 0, 144, 0, 0, 128, 40, 2, 0, 0, 144, 0, 0, 0, 76, 2, 0, 0, 144, 0, 0, 128, 76, 2, 0, 0, 144, 0, 0, 0, 96, 2, 0, 0, 144, 0, 0, 128, 96, 2, 0, 0, 144, 0, 0, 0, 116, 2, 0, 0, 144, 0, 0, 128, 116, 2, +0, 0, 144, 0, 0, 0, 152, 2, 0, 0, 144, 0, 0, 128, 152, 2, 0, 0, 144, 0, 0, 0, 188, 2, 0, 0, 147, 0, 0, 128, 188, 2, 0, 0, 147, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 95, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, +0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, +83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, +5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, +111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, +242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, +0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, +1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, +125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, 32, +32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, +53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, +32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, +48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, +101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, +48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, +61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, +32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, +32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, +41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, +83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, +65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, +32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, +123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, +111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, +32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, +116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 42, 0, 81, 17, 19, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, +0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, +100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 44, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, +0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, +100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 182, 129, 101, 77, 208, 30, 209, 73, 185, 9, 245, 65, 74, 202, 253, 227, 181, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, -99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, -97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, -49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, -0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, -25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 108, 4, 0, 0, 0, 0, 0, 0, 132, 1, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, -0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, -114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, -104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 254, 239, 254, 239, 1, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 17, 1, 0, 0, 24, 3, 0, 0, 155, 1, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 224, 23, 0, 0, 128, 0, 0, 0, 157, 22, 0, 0, 252, 5, 0, 0, 88, 0, 0, 0, 16, 0, 0, 0, -40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 45, 0, 0, 0, 38, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, -32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 21, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, -17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 39, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, +81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, +1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, +0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, +255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, +114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 114, 78, 3, 249, 109, 197, 166, 74, 147, 45, +88, 122, 114, 201, 110, 163, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 102, 53, 57, 97, 56, 55, 52, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, +8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, +0, 0, 0, 0, 0, 0, 4, 15, 0, 0, 128, 0, 0, 0, 31, 14, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 38, 0, +0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, +0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -475,66 +408,56 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 196, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 156, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, -0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 171, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, -104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 137, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -3, 3, 0, 0, 137, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 171, 171, 79, 83, 71, 78, 172, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -15, 0, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 14, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 9, 0, 0, 140, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 0, 5, 0, 0, 0, 1, 216, 41, -110, 103, 215, 201, 63, 8, 179, 181, 66, 234, 90, 159, 181, 48, 0, 12, 114, 0, 0, 68, 88, 66, 67, 164, 92, 147, 167, 119, 171, 205, 186, 120, 246, 47, 59, 128, 56, 93, 24, 1, 0, 0, 0, 12, 114, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 88, 7, 0, 0, 248, 9, 0, 0, 0, -112, 0, 0, 124, 112, 0, 0, 36, 113, 0, 0, 216, 113, 0, 0, 65, 111, 110, 57, 20, 7, 0, 0, 20, 7, 0, 0, 0, 2, 255, 255, 236, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, -2, 255, 255, 254, 255, 39, 1, 68, 66, 85, 71, 40, 0, 0, 0, 112, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 37, 0, 0, 0, 180, 0, 0, 0, 8, 0, 0, 0, 208, 3, 0, 0, 220, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, -115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, -103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 40, 0, 0, 0, 0, -0, 255, 255, 164, 4, 0, 0, 0, 0, 255, 255, 188, 4, 0, 0, 0, 0, 255, 255, 212, 4, 0, 0, 0, 0, 255, 255, 224, 4, 0, 0, 0, 0, 255, 255, 236, 4, 0, 0, 0, 0, 255, 255, 248, 4, 0, 0, 149, 0, 0, 0, 4, 5, 0, 0, 149, 0, 0, 0, 20, 5, 0, 0, 148, -0, 0, 0, 32, 5, 0, 0, 148, 0, 0, 0, 48, 5, 0, 0, 149, 0, 0, 0, 60, 5, 0, 0, 144, 0, 0, 0, 76, 5, 0, 0, 144, 0, 0, 0, 88, 5, 0, 0, 148, 0, 0, 0, 104, 5, 0, 0, 152, 0, 0, 0, 124, 5, 0, 0, 154, 0, 0, 0, 144, 5, 0, 0, 151, -0, 0, 0, 160, 5, 0, 0, 154, 0, 0, 0, 180, 5, 0, 0, 154, 0, 0, 0, 200, 5, 0, 0, 154, 0, 0, 0, 212, 5, 0, 0, 154, 0, 0, 0, 224, 5, 0, 0, 155, 0, 0, 0, 240, 5, 0, 0, 156, 0, 0, 0, 4, 6, 0, 0, 156, 0, 0, 0, 16, 6, 0, 0, 156, -0, 0, 0, 36, 6, 0, 0, 157, 0, 0, 0, 56, 6, 0, 0, 157, 0, 0, 0, 72, 6, 0, 0, 157, 0, 0, 0, 84, 6, 0, 0, 161, 0, 0, 0, 100, 6, 0, 0, 161, 0, 0, 0, 112, 6, 0, 0, 161, 0, 0, 0, 124, 6, 0, 0, 161, 0, 0, 0, 136, 6, 0, 0, 161, -0, 0, 0, 156, 6, 0, 0, 162, 0, 0, 0, 176, 6, 0, 0, 162, 0, 0, 0, 188, 6, 0, 0, 162, 0, 0, 0, 200, 6, 0, 0, 162, 0, 0, 0, 220, 6, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, -0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 227, 1, 0, 0, 244, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 4, 2, 0, 0, 36, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 1, -0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 67, 111, 108, 111, 114, 95, 105, -100, 55, 53, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, -0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 171, 171, 90, 2, 0, 0, 244, 1, 0, 0, 110, 2, 0, 0, 244, 1, 0, 0, 121, 2, 0, 0, 136, 2, 0, 0, 152, 2, 0, 0, 168, 2, 0, 0, 184, 2, 0, 0, 244, 1, 0, 0, 5, 0, 0, 0, 1, -0, 15, 0, 1, 0, 5, 0, 200, 2, 0, 0, 2, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 3, 0, 0, 0, 8, 0, 9, 0, 10, 0, 255, 255, 4, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 0, 34, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 102, 105, 110, 97, 108, -67, 111, 108, 111, 114, 0, 171, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 16, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 14, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 20, 0, 0, 0, 255, 255, 0, 0, 255, -255, 255, 255, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 13, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 21, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 24, 0, 0, 0, 255, 255, 255, 255, 3, -0, 255, 255, 31, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 32, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 220, 1, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 28, 2, 0, 0, 0, 0, 0, 0, 40, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, -2, 0, 0, 220, 1, 0, 0, 80, 2, 0, 0, 240, 2, 0, 0, 4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 48, 3, 0, 0, 244, 1, 0, 0, 1, 0, 0, 0, 60, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 136, 2, 0, 0, 1, 0, 0, 0, 76, 3, 0, 0, 0, -0, 0, 0, 88, 3, 0, 0, 136, 2, 0, 0, 1, 0, 0, 0, 92, 3, 0, 0, 0, 0, 0, 0, 104, 3, 0, 0, 136, 2, 0, 0, 1, 0, 0, 0, 108, 3, 0, 0, 0, 0, 0, 0, 120, 3, 0, 0, 244, 1, 0, 0, 6, 0, 0, 0, 136, 3, 0, 0, 77, 105, 99, 114, 111, -115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, -0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, -8, 15, 160, 2, 0, 0, 3, 0, 0, 8, 128, 1, 0, 0, 176, 0, 0, 170, 160, 35, 0, 0, 2, 0, 0, 1, 128, 0, 0, 255, 128, 2, 0, 0, 3, 0, 0, 2, 128, 1, 0, 0, 176, 0, 0, 0, 160, 35, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 2, 0, 0, 3, 0, -0, 3, 128, 0, 0, 228, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 3, 128, 1, 0, 201, 176, 66, 0, 0, 3, 1, 0, 15, 128, 1, 0, 228, 128, 0, 8, 228, 160, 88, 0, 0, 4, 1, 0, 15, 128, 0, 0, 85, 128, 1, 0, 0, 128, 1, 0, 228, 128, 4, 0, 0, 4, 0, -0, 2, 128, 1, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 4, 128, 1, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 0, 0, 18, 128, 0, 0, 170, 128, 0, -0, 170, 128, 0, 0, 85, 128, 7, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 85, 128, 1, 0, 0, 160, 1, -0, 0, 160, 1, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 0, 0, 0, 128, 0, 0, 85, 128, 1, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 0, 0, 0, 128, 0, 0, 170, 128, 1, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 1, -0, 0, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 0, -0, 3, 128, 1, 0, 0, 128, 88, 0, 0, 4, 1, 0, 6, 128, 2, 0, 255, 128, 0, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 1, 0, 8, 128, 2, 0, 255, 128, 0, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 1, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 0, -0, 15, 128, 0, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 1, 0, 228, 128, 0, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 152, 2, 0, 0, 64, 0, 0, 0, 166, 0, 0, 0, 90, 0, 0, 3, 0, -96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 18, 16, 16, 0, 2, 0, 0, 0, 98, 16, 0, 3, 98, 16, 16, 0, 2, 0, 0, 0, 98, 16, 0, 3, 242, -16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 150, 21, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 0, -0, 0, 10, 114, 0, 16, 0, 1, 0, 0, 0, 6, 16, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, -204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 1, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 50, 0, 0, 15, 146, 0, 16, 0, 1, -0, 0, 0, 6, 4, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 1, 0, 0, 0, 6, -12, 16, 0, 1, 0, 0, 0, 6, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 58, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, -64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, -0, 16, 0, 2, 0, 0, 0, 10, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 2, 0, 0, 0, 86, -5, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 166, 14, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 2, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, -0, 0, 9, 226, 0, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, 6, 8, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 2, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, -30, 16, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 102, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 236, -0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, +0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, +255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, +0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, +76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, +0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, +95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 53, 138, 11, 189, 15, 213, 198, 220, 176, 48, 42, 17, 37, 88, 61, 33, 0, 88, 96, 0, 0, 68, 88, 66, 67, 126, 178, 213, 92, 34, 254, 209, 162, 226, 133, 21, 210, 21, 107, 78, 46, 1, 0, 0, 0, 88, 96, +0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 180, 7, 0, 0, 188, 93, 0, 0, 56, 94, 0, 0, 8, 95, 0, 0, 184, 95, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, +48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, +0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, 0, 0, 32, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, +104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 65, 67, 51, 56, 55, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, +0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, 255, 255, 76, 4, 0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 104, 0, 0, 0, 112, 4, 0, 0, 110, 0, 0, 0, 128, 4, 0, 0, 110, 0, 0, 0, 148, 4, 0, 0, 110, 0, 0, 0, 168, 4, +0, 0, 104, 0, 0, 0, 184, 4, 0, 0, 104, 0, 0, 0, 200, 4, 0, 0, 104, 0, 0, 0, 216, 4, 0, 0, 138, 0, 0, 0, 232, 4, 0, 0, 138, 0, 0, 0, 252, 4, 0, 0, 140, 0, 0, 0, 8, 5, 0, 0, 140, 0, 0, 0, 20, 5, 0, 0, 110, 0, 0, 0, 32, 5, +0, 0, 143, 0, 0, 0, 44, 5, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, +171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, +0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 37, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 88, 1, 0, 0, 120, 1, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 88, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, +5, 0, 164, 1, 0, 0, 6, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 13, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 15, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 16, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 18, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 72, 2, 0, 0, 56, 1, +0, 0, 87, 2, 0, 0, 88, 1, 0, 0, 102, 2, 0, 0, 88, 1, 0, 0, 114, 2, 0, 0, 88, 1, 0, 0, 129, 2, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 144, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, +0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 5, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 14, 3, 0, 0, 88, 1, 0, 0, 30, 3, 0, 0, 56, 1, +0, 0, 39, 3, 0, 0, 88, 1, 0, 0, 48, 3, 0, 0, 88, 1, 0, 0, 54, 3, 0, 0, 88, 1, 0, 0, 63, 3, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 72, 3, 0, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 11, 0, +0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 32, 1, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 220, 1, 0, 0, 32, 1, 0, 0, 60, 2, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 200, 2, 0, 0, 0, 0, +0, 0, 4, 3, 0, 0, 120, 3, 0, 0, 3, 0, 0, 0, 136, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, +15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, +15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, +228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, +228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, +0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, +16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, +0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, +0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, +156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, +0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, +0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, +0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, +0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, +0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -542,7 +465,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -550,400 +473,339 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 234, 91, 179, 188, 144, 174, 196, 79, 183, 227, 77, 92, 243, 113, 4, 160, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, -90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, -100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 198, 90, 0, 0, 117, 131, 1, 0, 190, 254, 0, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 31, 155, 2, 0, 170, 19, 0, 0, 94, -184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 203, 103, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 193, 228, 0, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, -79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, -69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, -100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, -32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, -95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, -95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, -95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, -56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, -82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, -101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, -101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, -32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, -114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, -110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, -112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, -101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, -101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, -95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, -114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, -114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, -32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, -10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, -32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, -110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, -60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, -111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, -105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, -115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, -53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, -95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, -84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, -32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, -110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, -83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, -95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, -41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, -32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, -10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, -46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, -101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 176, 23, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, -111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, -104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, -115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, -112, 114, 105, 116, 101, 98, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, -111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 52, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, -79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 27, 226, 48, 1, 128, 0, 0, 0, 75, 187, 85, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 116, 14, 50, 26, 157, 22, 0, 0, 1, 0, 0, 0, 137, -0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, -76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, -95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 204, 5, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 8, 16, 0, 0, 104, -0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, -0, 0, 0, 1, 0, 48, 2, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, -0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 28, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, -0, 0, 0, 1, 0, 48, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 52, 0, 0, 0, 22, 0, 80, 17, 1, -0, 5, 0, 52, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 60, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, 101, 116, -117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 0, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 48, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, -0, 0, 0, 1, 0, 48, 2, 12, 0, 0, 0, 174, 0, 77, 17, 140, 0, 0, 0, 200, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 116, 11, 32, 13, 45, 6, 18, 3, 36, 13, 116, 6, 19, 3, 84, 9, 9, 13, 42, 6, 8, 3, 36, 13, 57, 6, 4, 3, 60, 13, 42, 6, -2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 82, 6, 2, 12, 36, 76, 8, 0, 9, 68, 13, 87, 1, 104, 6, 29, 3, 0, 9, 13, 13, 36, 6, 18, 3, 36, 9, 9, 13, 44, 3, 40, 9, 27, 13, 115, 6, 19, 3, 44, 9, 20, 13, 41, 6, 8, 3, -36, 9, 48, 13, 54, 6, 4, 3, 60, 9, 38, 3, 28, 9, 29, 13, 55, 3, 28, 9, 24, 13, 56, 3, 28, 9, 20, 3, 20, 9, 26, 13, 41, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 81, 6, 2, 12, 36, 76, 0, 50, 0, 62, 17, 0, -16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 4, 1, 0, 0, 1, -0, 148, 1, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 4, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 232, 0, 132, 0, 8, 0, 0, 0, 26, 0, 80, 17, 0, -0, 5, 0, 12, 0, 4, 0, 4, 1, 0, 0, 1, 0, 148, 1, 32, 1, 76, 0, 12, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 236, 1, 0, 0, 1, 0, 132, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 36, 2, 0, 0, 1, -0, 76, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 64, -1, 0, 0, 1, 0, 28, 0, 16, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, -0, 4, 0, 64, 1, 0, 0, 1, 0, 28, 0, 28, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, -0, 1, 0, 0, 0, 4, 0, 200, 1, 0, 0, 1, 0, 208, 0, 16, 0, 0, 0, 38, 0, 77, 17, 248, 2, 0, 0, 196, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 69, 11, 32, 4, 36, 8, 0, 9, 12, 13, 68, 1, 104, 12, 36, 0, 0, 0, 0, 66, 0, 62, 17, 12, -16, 0, 0, 136, 0, 60, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, -0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 140, 0, 0, 0, 1, 0, 40, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 72, 36, 132, 223, 221, 37, 35, 87, 150, 249, 16, 65, 145, 190, 186, -0, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 152, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 104, 0, 0, 0, 181, 0, 0, 128, 104, 0, 0, 0, 181, 0, 0, 0, 140, 0, 0, 0, 181, 0, 0, 128, 140, 0, 0, 0, 181, -0, 0, 0, 180, 0, 0, 0, 181, 0, 0, 128, 180, 0, 0, 0, 181, 0, 0, 0, 224, 0, 0, 0, 181, 0, 0, 128, 224, 0, 0, 0, 181, 0, 0, 0, 4, 1, 0, 0, 181, 0, 0, 128, 4, 1, 0, 0, 181, 0, 0, 0, 64, 1, 0, 0, 181, 0, 0, 128, 64, 1, 0, 0, 181, -0, 0, 0, 92, 1, 0, 0, 181, 0, 0, 128, 92, 1, 0, 0, 181, 0, 0, 0, 120, 1, 0, 0, 181, 0, 0, 128, 120, 1, 0, 0, 181, 0, 0, 0, 148, 1, 0, 0, 181, 0, 0, 128, 148, 1, 0, 0, 181, 0, 0, 0, 168, 1, 0, 0, 181, 0, 0, 128, 168, 1, 0, 0, 181, -0, 0, 0, 200, 1, 0, 0, 181, 0, 0, 128, 200, 1, 0, 0, 181, 0, 0, 0, 236, 1, 0, 0, 181, 0, 0, 128, 236, 1, 0, 0, 181, 0, 0, 0, 0, 2, 0, 0, 181, 0, 0, 128, 0, 2, 0, 0, 181, 0, 0, 0, 36, 2, 0, 0, 181, 0, 0, 128, 36, 2, 0, 0, 181, -0, 0, 0, 56, 2, 0, 0, 181, 0, 0, 128, 56, 2, 0, 0, 181, 0, 0, 0, 76, 2, 0, 0, 181, 0, 0, 128, 76, 2, 0, 0, 181, 0, 0, 0, 112, 2, 0, 0, 181, 0, 0, 128, 112, 2, 0, 0, 181, 0, 0, 0, 148, 2, 0, 0, 184, 0, 0, 128, 148, 2, 0, 0, 184, -0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, -0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, -0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 143, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, -0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, -0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, -0, 0, 0, 10, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 88, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, -0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 130, 0, 3, 18, 13, -21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 32, -0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 36, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 30, -0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, -0, 1, 0, 4, 16, 0, 0, 126, 0, 3, 18, 13, 21, 3, 0, 64, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 4, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, -16, 0, 0, 12, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 28, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 13, 21, 3, 0, 0, 16, 0, 0, 44, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 5, 0, 0, 0, 9, 16, 0, 0, 136, 48, 2, 0, 151, 210, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, -53, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, 10, -125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, -10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, -122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, -50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, -68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, -100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, -100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, -100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, -61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, -110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, -79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, -105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, -73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, -112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, -101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, -97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, -13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, -97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, -32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, -46, 114, 114, 114, 114, 32, 58, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, -45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, -114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, -41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, -97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 43, 32, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, -40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, -116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, -55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, -13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, -53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, -83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, -40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, -32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, -95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, -95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -95, 105, 100, 55, 53, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, -55, 55, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 18, 1, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 48, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, -0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 182, 45, 33, 236, 64, 67, 241, 65, 131, 147, 147, 152, 230, 208, 31, 20, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 152, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, -0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, +77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, +122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, +84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, +3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, 3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, +101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, +78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, +77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, +122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, +84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, +112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, +50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, +111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, +119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, +110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, +102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, +108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, +105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, +105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, +110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, +120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, +112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, +32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, +97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, +110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, +32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, +61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 128, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, +53, 65, 67, 51, 56, 55, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, +116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 97, 99, 51, 56, 55, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, +101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, +78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 122, 223, 2, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, +48, 1, 43, 208, 170, 75, 203, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, +77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, +108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, +0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, +0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, +110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 8, 0, 0, 0, 50, 0, 77, 17, 136, 0, 0, 0, 220, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 36, 6, 12, 12, 128, 136, 40, 12, 128, 128, 128, 176, 8, 0, 13, 35, 1, 128, 196, 12, 128, +136, 0, 12, 128, 128, 128, 176, 0, 0, 0, 66, 0, 77, 17, 244, 3, 0, 0, 216, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 9, 5, 13, 24, 6, 9, 12, 128, 128, 128, 176, 8, 0, 9, 27, 13, 53, 1, 128, 196, 6, 8, 12, 128, 136, 0, +9, 5, 13, 23, 6, 9, 12, 128, 128, 128, 176, 0, 0, 0, 54, 0, 77, 17, 40, 4, 0, 0, 164, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 196, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, +128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 42, 0, 77, 17, 40, 4, 0, 0, 212, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 128, 216, 8, 0, 9, 33, 13, 82, 1, 129, 116, 12, 128, 128, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, +78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 182, 141, 131, 252, 216, 47, 208, 169, 159, 118, 77, 56, 148, 24, 182, 145, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, +0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 152, 0, 0, 128, 156, 0, 0, 0, 152, 0, 0, 0, 176, 0, 0, 0, 152, 0, 0, 128, 176, 0, 0, 0, 152, 0, 0, 0, 196, 0, 0, 0, 145, 0, 0, 128, 196, 0, 0, 0, 145, 0, 0, 0, 0, 1, 0, 0, 145, 0, 0, 128, 0, 1, +0, 0, 145, 0, 0, 0, 48, 1, 0, 0, 145, 0, 0, 128, 48, 1, 0, 0, 145, 0, 0, 0, 76, 1, 0, 0, 152, 0, 0, 128, 76, 1, 0, 0, 152, 0, 0, 0, 96, 1, 0, 0, 152, 0, 0, 128, 96, 1, 0, 0, 152, 0, 0, 0, 116, 1, 0, 0, 145, 0, 0, 128, 116, 1, +0, 0, 145, 0, 0, 0, 148, 1, 0, 0, 145, 0, 0, 128, 148, 1, 0, 0, 145, 0, 0, 0, 180, 1, 0, 0, 145, 0, 0, 128, 180, 1, 0, 0, 145, 0, 0, 0, 212, 1, 0, 0, 145, 0, 0, 128, 212, 1, 0, 0, 145, 0, 0, 0, 244, 1, 0, 0, 152, 0, 0, 128, 244, 1, +0, 0, 152, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 1, 16, +0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, +24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, +0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 56, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, +3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 8, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, +102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, +0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, +0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, +3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, +0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 181, 177, 2, 0, 64, 168, 2, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 34, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, -101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, +112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, +50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, +111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, +119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, +110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, +102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, +108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, +105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, +105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, +110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, +120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, +112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, +32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, +97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, +110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, +32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, +61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, +3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, +242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, +242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 135, 140, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 234, 91, 179, 188, 144, 174, 196, 79, 183, 227, 77, 92, 243, 113, 4, 160, 181, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, -109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, -111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 98, 97, 116, 99, -104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, -7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 5, 0, 0, 0, 0, 0, 0, 20, -2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 152, 2, 0, 0, 32, 0, 0, 96, 0, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 152, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, -110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, -50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 95, 57, 98, 55, 100, 52, 49, 99, 97, 53, 54, 102, 54, 50, 49, 50, 55, 98, 53, 55, 51, 50, 97, 102, 55, 52, 101, 51, 102, 53, 54, 97, 57, 46, 104, 108, 115, 108, 0, 254, -239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 17, 1, 0, 0, 144, 2, 0, 0, 155, 1, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 224, 23, 0, 0, 128, 0, 0, 0, 157, 22, 0, 0, 244, 7, 0, 0, 88, -0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 45, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 46, 0, 0, 0, 39, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, -0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 21, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, -0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 7, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 42, 0, 0, 0, 44, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 16, 16, 0, 0, 8, 0, +1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, +0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 9, 0, 228, 4, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, +0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, +1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 65, 67, 51, 56, 55, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 182, 45, 33, 236, 64, 67, 241, 65, 131, 147, 147, 152, 230, 208, 31, 20, 134, 0, +0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, +53, 97, 99, 51, 56, 55, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, +220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 112, 2, 0, 0, 111, 1, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 176, 15, +0, 0, 128, 0, 0, 0, 203, 14, 0, 0, 140, 6, 0, 0, 76, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 16, 0, +0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, +0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 119, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, -84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 172, 0, 0, 0, 5, -0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 6, 6, 0, 0, 140, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 83, -86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, +0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, +0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, +0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, +79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs new file mode 100644 index 0000000000..cac4b1af4f --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [SpriteBatch] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + public partial class SpriteBatch + { + private static readonly byte[] binaryBytecodeSRgb = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, +0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, +2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 88, 175, 127, 150, 28, 106, 83, 42, 77, 34, 205, 184, 82, 111, 42, 178, 0, 74, 11, 0, 0, 68, 88, 66, 67, 39, 222, 121, 150, 118, 100, 3, 3, 84, 220, 56, 253, 11, 63, 194, 79, 1, 0, 0, 0, 74, 11, 0, 0, 5, 0, 0, 0, 52, +0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 110, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, +240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 52, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, +0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 212, 8, 0, 0, 96, 0, 0, 0, 53, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 188, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 44, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, +0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, +36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, +0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 95, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, +49, 65, 128, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, +140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, +40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 128, 50, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 80, 3, 0, 0, 192, 61, 195, 229, 79, 216, 67, 72, 126, 8, 52, 195, 66, +160, 0, 2, 0, 0, 160, 24, 17, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 55, 13, 151, 63, 97, 15, 33, 249, 43, 33, 173, 196, 228, 23, 183, 141, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +2, 0, 0, 128, 194, 76, 0, 0, 0, 16, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 128, 0, +0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 128, 24, 0, 0, 0, 6, 2, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, +109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, +32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, +0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 36, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 50, 0, 0, +0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, +40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 3, 2, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 8, 0, 0, 0, 138, 129, 0, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 8, 0, 0, 0, 74, 142, 0, 0, 0, 0, 102, 0, 136, 0, +0, 0, 160, 240, 8, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 136, 0, 0, 0, 160, 28, 10, 134, 0, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 2, 0, 0, 128, 82, 160, 6, 0, +0, 128, 146, 40, 132, 2, 1, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, +151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, +84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 184, 54, +12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 4, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 12, 38, 8, 77, 180, 33, 8, 38, 8, 205, 180, 97, 9, 196, 96, 12, 200, 160, 12, +204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 202, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 2, 102, 195, 194, 136, 193, 24, 144, 193, 26, 152, 1, 145, 6, 12, 25, 0, 19, 4, 162, 218, 16, 180, 193, 4, 161, 145, 54, 44, 109, 32, 6, 99, 64, +6, 110, 96, 6, 196, 27, 180, 1, 25, 0, 27, 136, 51, 80, 3, 54, 128, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 198, 12, 54, 44, 129, 28, 140, 193, 28, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 160, 131, 13, 67, 28, 212, 1, 64, 51, 152, 130, 147, 75, 163, 43, +19, 10, 163, 27, 67, 155, 66, 11, 35, 43, 147, 227, 161, 147, 171, 43, 243, 113, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 119, 96, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, +155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, +75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 193, 29, 0, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 208, 105, 51, +156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 219, 128, 52, 92, 190, 243, 248, 66, 68, 0, 19, 17, 2, 205, 176, 16, 70, 0, 13, 151, 239, 60, 190, 4, 48, +207, 66, 248, 197, 109, 91, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 97, 32, 0, 0, 145, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 56, 102, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 103, 144, 133, 65, 24, 88, 216, +136, 65, 2, 128, 32, 24, 56, 104, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 105, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 106, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 107, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 56, 108, +224, 133, 129, 25, 112, 221, 136, 65, 2, 128, 32, 24, 56, 109, 240, 137, 193, 25, 112, 222, 136, 65, 2, 128, 32, 24, 56, 110, 0, 6, 99, 128, 6, 220, 55, 98, 144, 0, 32, 8, 6, 206, 27, 132, 1, 25, 164, 1, 7, 6, 35, 6, 9, 0, 130, 96, 224, 192, 129, 24, 112, 106, 0, 6, +97, 96, 1, 7, 129, 17, 3, 3, 0, 65, 48, 120, 226, 128, 11, 134, 27, 184, 96, 152, 101, 8, 132, 96, 196, 32, 1, 64, 16, 12, 36, 57, 224, 194, 192, 13, 220, 0, 13, 70, 12, 18, 0, 4, 193, 64, 154, 131, 174, 12, 222, 224, 13, 210, 96, 196, 224, 1, 64, 16, 12, 168, 57, 224, +2, 1, 122, 186, 238, 12, 206, 224, 12, 186, 209, 132, 0, 24, 77, 16, 130, 209, 132, 65, 24, 77, 32, 134, 89, 130, 97, 196, 32, 1, 64, 16, 12, 164, 60, 24, 3, 52, 168, 131, 58, 120, 131, 17, 131, 4, 0, 65, 48, 144, 244, 128, 12, 216, 192, 14, 236, 0, 14, 70, 12, 30, 0, 4, +193, 128, 210, 131, 49, 8, 132, 203, 34, 3, 50, 112, 3, 55, 112, 3, 50, 24, 77, 8, 128, 209, 4, 33, 24, 77, 24, 132, 209, 4, 98, 152, 37, 24, 6, 42, 0, 43, 64, 132, 129, 10, 0, 11, 16, 97, 160, 2, 208, 2, 68, 24, 168, 0, 184, 0, 17, 204, 90, 3, 8, 140, 24, 24, +0, 8, 130, 193, 99, 10, 113, 16, 12, 55, 196, 65, 48, 204, 50, 16, 69, 96, 71, 27, 72, 192, 130, 58, 128, 128, 33, 111, 32, 1, 11, 238, 0, 2, 54, 12, 18, 48, 65, 144, 128, 9, 1, 4, 70, 12, 12, 0, 4, 193, 224, 121, 133, 57, 8, 70, 12, 12, 0, 4, 193, 224, 129, 133, +57, 8, 108, 14, 130, 8, 88, 48, 7, 18, 176, 128, 14, 32, 48, 75, 96, 204, 18, 24, 3, 21, 128, 64, 136, 65, 49, 80, 1, 184, 3, 33, 6, 133, 157, 129, 29, 64, 96, 196, 192, 0, 64, 16, 12, 158, 91, 16, 133, 96, 184, 65, 20, 130, 97, 186, 1, 187, 130, 233, 134, 204, 16, 166, +27, 250, 192, 24, 108, 171, 3, 9, 24, 81, 7, 18, 48, 162, 14, 36, 96, 68, 29, 72, 192, 136, 58, 128, 128, 17, 117, 0, 1, 35, 234, 0, 2, 70, 212, 1, 4, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 168, 5, 98, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, +248, 5, 90, 24, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 152, 5, 97, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, 248, 5, 89, 8, 16, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 7, 201, 65, 51, 97, 119, 186, 124, 172, 222, 35, 223, 38, 225, 71, 50, +0, 121, 12, 0, 0, 68, 88, 66, 67, 28, 55, 175, 87, 179, 24, 200, 28, 226, 197, 227, 151, 15, 77, 194, 191, 1, 0, 0, 0, 121, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 189, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, +0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, +105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 180, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, +0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, +0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 68, 88, 73, 76, 180, 8, 0, 0, 96, 0, 1, 0, 45, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 156, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 36, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, +4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, +24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, +96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, +29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, +212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, +2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, +113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, +48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, +0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 32, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, +67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 50, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, +0, 128, 178, 43, 144, 2, 42, 48, 2, 0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, 16, 205, 85, 39, 61, 34, 0, 0, 0, 40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 130, 0, 0, 0, 26, 3, 76, 144, 70, 2, +19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, +46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 186, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, +4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 188, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 229, 219, 176, 16, 218, 198, 129, 1, 71, 132, +1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 9, 2, 33, 109, 8, 204, 96, 195, 98, 6, 218, 198, 157, 1, 71, 132, 129, 25, 112, 192, 134, 192, 153, 32, 40, 206, 134, 197, 209, 54, 46, 13, 56, 66, 13, 28, 14, 216, 80, 124, 98, +80, 6, 104, 176, 6, 27, 150, 64, 219, 184, 206, 35, 188, 128, 3, 54, 44, 132, 182, 113, 96, 224, 17, 97, 64, 112, 192, 134, 101, 12, 180, 141, 35, 3, 143, 8, 131, 49, 224, 128, 13, 139, 25, 104, 27, 119, 6, 30, 161, 6, 102, 192, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, +220, 38, 8, 10, 180, 97, 113, 226, 96, 147, 131, 46, 12, 136, 48, 112, 56, 96, 67, 209, 6, 110, 240, 6, 112, 48, 7, 27, 6, 54, 160, 3, 128, 102, 48, 5, 39, 151, 70, 87, 38, 20, 70, 55, 134, 54, 133, 22, 70, 86, 38, 199, 67, 39, 87, 87, 230, 227, 98, 53, 213, 20, 150, 230, +246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 236, 160, 14, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, +101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, +236, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 214, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, +72, 195, 229, 59, 143, 47, 68, 4, 48, 17, 33, 208, 12, 11, 97, 3, 219, 112, 249, 206, 227, 11, 1, 85, 20, 68, 84, 58, 192, 80, 18, 6, 32, 96, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 190, 0, +0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 95, 165, 105, 19, 53, 98, 144, 0, 32, 8, 6, 11, 24, 88, 219, 54, 85, 35, 6, 9, 0, 130, 96, 176, 132, 193, 181, 113, 149, 53, 98, 144, 0, 32, 8, 6, 139, 24, 96, 92, 87, 93, 35, 6, 9, 0, 130, 96, 176, 140, 65, 214, +121, 21, 54, 98, 144, 0, 32, 8, 6, 11, 25, 104, 222, 87, 101, 35, 6, 9, 0, 130, 96, 176, 148, 193, 86, 129, 65, 166, 141, 24, 36, 0, 8, 130, 193, 98, 6, 156, 21, 6, 217, 54, 98, 144, 0, 32, 8, 6, 203, 25, 116, 151, 24, 100, 220, 136, 65, 2, 128, 32, 24, 44, 104, 224, +97, 99, 144, 117, 35, 6, 9, 0, 130, 96, 176, 164, 193, 135, 145, 65, 231, 141, 24, 36, 0, 8, 130, 193, 162, 6, 96, 144, 149, 65, 247, 141, 24, 36, 0, 8, 130, 193, 178, 6, 97, 160, 153, 65, 7, 6, 35, 6, 9, 0, 130, 96, 176, 176, 129, 24, 108, 103, 208, 133, 193, 136, 65, 2, +128, 32, 24, 44, 109, 48, 6, 99, 128, 6, 97, 32, 6, 35, 6, 9, 0, 130, 96, 240, 180, 1, 7, 6, 104, 128, 6, 91, 169, 65, 25, 224, 136, 193, 1, 128, 32, 24, 68, 110, 192, 9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 193, 1, 24, 64, 5, 108, 128, +35, 6, 7, 0, 130, 96, 16, 213, 193, 24, 36, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 221, 129, 25, 64, 5, 115, 128, 35, 6, 7, 0, 130, 96, 16, 241, 129, 26, 64, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 249, 1, 27, 64, 5, +122, 128, 35, 6, 7, 0, 130, 96, 16, 141, 66, 28, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 102, 32, 1, 131, 206, 64, 2, 166, 160, 129, 4, 140, 72, 3, 9, 216, 182, 6, 18, 176, 160, 128, 128, 89, 109, 32, 1, 11, 12, 8, 88, 244, 6, 18, 176, +224, 128, 128, 49, 113, 32, 1, 11, 16, 8, 24, 25, 208, 129, 4, 44, 64, 32, 96, 159, 29, 72, 192, 2, 4, 2, 166, 225, 129, 4, 44, 64, 32, 96, 149, 30, 72, 192, 2, 4, 2, 214, 6, 125, 32, 1, 11, 16, 8, 24, 26, 252, 129, 4, 44, 64, 32, 96, 99, 16, 10, 18, 176, 0, +129, 128, 121, 163, 32, 1, 11, 16, 8, 88, 40, 184, 130, 4, 44, 20, 94, 65, 2, 22, 10, 176, 32, 1, 27, 96, 1, 2, 54, 196, 2, 4, 108, 144, 5, 8, 216, 41, 12, 18, 176, 83, 24, 36, 96, 167, 48, 72, 192, 134, 90, 128, 128, 13, 182, 0, 1, 27, 110, 1, 2, 214, 10, 131, +4, 172, 21, 6, 9, 88, 43, 12, 18, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 97, 29, 224, 33, 29, 172, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 214, 1, 30, 208, 129, 26, 49, 72, 0, 16, 4, 3, 73, 30, 116, 97, 29, 224, 225, 28, 164, 17, 131, 4, 0, 65, 48, 144, 228, +65, 23, 214, 1, 30, 204, 1, 26, 49, 72, 0, 16, 4, 3, 73, 30, 116, 1, 30, 224, 33, 29, 108, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 5, 120, 128, 7, 116, 168, 133, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 222, 1, 30, 210, 97, 24, 49, 72, 0, 16, 4, 3, 73, 30, +116, 225, 29, 224, 1, 29, 132, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 222, 1, 30, 206, 33, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 225, 29, 224, 193, 28, 90, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 133, 114, 128, 135, 116, 96, 133, 17, 131, 4, 0, 65, 48, 144, 228, 65, +23, 202, 1, 30, 208, 97, 21, 70, 12, 18, 0, 4, 193, 64, 146, 7, 93, 40, 7, 120, 56, 7, 85, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 161, 28, 224, 193, 28, 82, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 5, 114, 128, 135, 116, 64, 5, 4, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs index 548dae453f..dfdf4567d6 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs @@ -1,85 +1,69 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-d3d11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { public partial class SpriteEffect { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, -7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, -105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, -114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 49, 57, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 53, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, -120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, -56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 10, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 197, 28, -71, 53, 50, 246, 70, 142, 27, 184, 231, 50, 114, 52, 51, 181, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, -17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, -30, 97, 165, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 140, 240, 88, 194, 120, 57, 159, 211, 119, 136, 246, 134, 182, 66, 23, 49, 0, 152, 84, 0, 0, 68, 88, 66, 67, 204, 160, 41, 69, 15, 115, 98, 231, 58, 242, 15, 49, 216, 108, 62, 90, 1, 0, 0, 0, 152, 84, 0, 0, 7, -0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 82, 0, 0, 32, 83, 0, 0, 236, 83, 0, 0, 64, 84, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, -0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 9, 0, 0, 0, 184, -0, 0, 0, 3, 0, 0, 0, 64, 2, 0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, -112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, -54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 149, 0, 0, 0, 200, 2, 0, 0, 149, 0, 0, 0, 216, 2, 0, 0, 149, -0, 0, 0, 232, 2, 0, 0, 149, 0, 0, 0, 248, 2, 0, 0, 144, 0, 0, 0, 8, 3, 0, 0, 144, 0, 0, 0, 28, 3, 0, 0, 148, 0, 0, 0, 40, 3, 0, 0, 86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 28, 1, 0, 0, 44, 1, 0, 0, 60, -1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 76, 1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 2, 0, 255, 255, 6, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 8, 0, 0, 0, 4, 0, 5, 0, 255, -255, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 166, 1, 0, 0, 28, 1, 0, 0, 44, 1, 0, 0, 60, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 180, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 2, 0, 3, 0, 1, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 0, 166, 1, 0, 0, 28, 1, 0, 0, 44, 1, 0, 0, 60, 1, 0, 0, 7, 1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, -1, 0, 0, 3, 0, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, 7, 0, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 9, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 92, 1, 0, 0, 4, 0, 0, 0, 108, 1, 0, 0, 0, 1, 0, 0, 156, -1, 0, 0, 196, 1, 0, 0, 2, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 236, 1, 0, 0, 12, 2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, -112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 0, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 0, 0, 228, 144, 1, -0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 0, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 0, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, -0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, -0, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, -0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, -0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, -80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, +111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, +64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, +71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, +101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, +122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, +0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, +102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, +0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, +28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 19, 251, 146, 209, 31, 5, 162, 164, 79, 143, 65, 252, 225, 224, 252, +247, 0, 184, 77, 0, 0, 68, 88, 66, 67, 129, 194, 17, 166, 133, 94, 240, 180, 4, 42, 106, 110, 2, 202, 253, 177, 1, 0, 0, 0, 184, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, 73, 0, 0, 12, 74, 0, 0, 80, 77, 0, 0, 132, 77, +0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, +255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, +115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, +57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 71, 0, 0, 0, 60, 2, 0, 0, 76, 0, 0, 0, 76, 2, 0, 0, 76, 0, 0, 0, 92, 2, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, +171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 28, 1, 0, 0, 5, 0, +0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, +0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 108, 1, 0, 0, 5, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 212, 0, 0, 0, 0, 0, +0, 0, 224, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 4, 1, 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 1, 0, 0, 0, 148, 1, 0, 0, 77, 105, 99, 114, 111, 115, +111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, +15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 89, 0, 0, 4, 70, 142, +32, 0, 1, 0, 0, 0, 6, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, +0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 142, +32, 0, 1, 0, 0, 0, 5, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, +0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -87,7 +71,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -95,7 +79,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -103,7 +87,7 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -111,268 +95,215 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 171, 208, 231, 254, 81, 141, 16, 69, 154, 183, 127, 105, 136, 235, 55, 234, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, -81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 152, 234, 110, 94, 183, 179, 219, 72, 183, 85, 123, 159, 38, 144, 9, 75, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, -79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, -68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, -115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, -120, 101, 108, 83, 105, 122, 101, 198, 90, 0, 0, 117, 131, 1, 0, 136, 240, 1, 0, 156, 202, 1, 0, 38, 247, 2, 0, 122, 152, 2, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 103, 159, 1, 0, 206, 55, 0, 0, 57, 206, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, +52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, 251, 3, 0, 138, 183, 3, 0, 80, 133, 1, 0, 211, 99, +0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 9, 36, 3, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, +83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, +78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, +85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, +52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, +99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, +52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, +112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, +101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, +116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, +95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, +61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, +112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, -110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, -105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, -105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, -120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 32, 49, 44, 32, 49, 44, 32, 49, 41, 59, 13, 10, 125, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, -50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, -53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, -55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, -97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, -95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, -61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, -32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, -59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, -73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, -125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, -105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, -52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, -105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, -100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, -114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, -13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, -104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, -32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, -50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, -116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, -115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 118, 16, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, -115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, -52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, -99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 101, 102, 102, 101, 99, 116, -95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, -13, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 110, 125, 77, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 201, 245, 73, 187, 97, 15, 0, 0, 1, 0, 0, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, -111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, -0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 80, 2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, -0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, -0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 8, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, -0, 152, 0, 20, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, -0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 8, 0, 0, 0, 22, -0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 12, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 87, 184, 241, 100, 15, 100, 181, 218, 43, 27, 222, 104, 162, 10, 186, 204, 0, 0, 242, 0, 0, 0, 168, -0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 228, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 149, 0, 0, 128, 76, 0, 0, 0, 149, 0, 0, 0, 108, 0, 0, 0, 149, 0, 0, 128, 108, 0, 0, 0, 149, 0, 0, 0, 140, 0, 0, 0, 149, -0, 0, 128, 140, 0, 0, 0, 149, 0, 0, 0, 172, 0, 0, 0, 149, 0, 0, 128, 172, 0, 0, 0, 149, 0, 0, 0, 204, 0, 0, 0, 153, 0, 0, 128, 204, 0, 0, 0, 153, 0, 0, 0, 224, 0, 0, 0, 153, 0, 0, 128, 224, 0, 0, 0, 153, 0, 0, 0, 5, 0, 83, 0, 35, -0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 12, 16, 0, 0, 64, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 22, -0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 50, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 30, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 86, 83, 95, 73, 78, 80, 85, -84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 30, 0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, -0, 1, 0, 4, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 9, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 10, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 185, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 0, 99, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 102, 97, 100, 50, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, +83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, +78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, +85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 72, 160, 229, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 159, 13, 21, 94, 4, 8, 0, 0, 1, 0, +0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, +41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, +95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 8, 16, 0, 0, 84, 0, +0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 2, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, +116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, +0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 34, 0, 77, 17, 136, 0, 0, 0, 12, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 64, 4, 68, 8, 0, 13, 23, 1, 84, 12, 68, 0, 0, 38, 0, 77, 17, 180, 1, 0, 0, 8, 3, 0, 0, 1, 16, 0, 0, 7, 0, +9, 5, 13, 51, 11, 32, 4, 68, 8, 0, 9, 29, 13, 50, 1, 84, 12, 68, 0, 0, 0, 0, 42, 0, 77, 17, 216, 1, 0, 0, 4, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 50, 11, 32, 4, 68, 8, 0, 9, 12, 13, 31, 1, 84, 3, 0, 13, 49, 12, 32, 36, 0, +0, 0, 38, 0, 77, 17, 0, 2, 0, 0, 0, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 84, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, +83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, +4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 28, 55, 102, 214, 79, 109, 121, 103, +244, 240, 146, 115, 125, 252, 244, 232, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 94, 0, 0, 128, 84, 0, 0, 0, 94, 0, 0, 0, 120, 0, 0, 0, 94, 0, +0, 128, 120, 0, 0, 0, 94, 0, 0, 0, 152, 0, 0, 0, 97, 0, 0, 128, 152, 0, 0, 0, 97, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, +0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 56, 0, 0, 0, 96, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 148, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 84, 0, 0, 0, 84, 0, +0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 243, 242, 241, 38, 0, 5, 21, 1, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 2, 16, 0, 0, 22, 0, 27, 21, 64, 0, +0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 3, 16, 0, 0, 10, 0, +24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, +0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, +0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, -105, 100, 55, 52, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 32, 49, 44, 32, 49, 44, 32, 49, 41, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, -95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, -101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, -52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, -54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, -68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, -110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, -125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, -77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, -10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, -101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, -116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, -112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, -83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, -56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, -115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, -115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, -85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, -80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, -86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, -95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, -117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, -95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, +99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, +52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, +112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, +101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, +116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, +95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, +61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, +112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 124, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, +0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, +97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, +0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, +97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 97, 0, 0, 0, 1, 0, 0, 0, 57, 0, 0, 0, 1, 0, 0, 0, 21, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 42, 0, 81, 17, 11, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, -114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 34, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 80, 0, 255, 255, 255, 255, 255, 255, 71, 108, +111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 38, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 20, 16, 0, 0, 6, 0, +255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 171, 208, 231, 254, 81, 141, 16, 69, 154, 183, 127, 105, 136, 235, 55, 234, 182, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, -100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, -115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 101, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, -52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, -0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 84, 2, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, -255, 255, 255, 0, 0, 0, 0, 228, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, -97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, -95, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 3, 0, 0, 0, 0, +0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, +48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 18, 1, 0, 0, 120, 1, 0, 0, 159, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 166, 16, 0, 0, 128, 0, 0, 0, 97, 15, 0, 0, 60, 3, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 44, -2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, -0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 33, -0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 152, 234, 110, 94, 183, 179, 219, 72, 183, 85, 123, 159, 38, 144, 9, 75, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, +47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 102, 97, 100, 50, 99, 48, 0, 4, 0, 0, 0, +6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 204, 1, 0, 0, 111, 1, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 233, 8, 0, 0, 128, 0, 0, 0, 4, 8, 0, 0, 236, 3, +0, 0, 92, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, +0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -383,351 +314,311 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 82, 68, 69, 70, 196, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 156, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 77, -97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 171, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, -32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, -0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 12, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 0, 5, 0, 0, 0, -1, 52, 139, 160, 23, 5, 154, 169, 116, 62, 15, 1, 217, 177, 220, 111, 209, 0, 224, 93, 0, 0, 68, 88, 66, 67, 178, 214, 228, 71, 151, 11, 30, 58, 188, 73, 184, 142, 15, 128, 60, 215, 1, 0, 0, 0, 224, 93, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 188, 3, -0, 0, 196, 89, 0, 0, 64, 90, 0, 0, 84, 93, 0, 0, 172, 93, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 255, 255, 160, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, -0, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 148, 0, 68, 66, 85, 71, 40, 0, 0, 0, 36, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 5, 0, 0, 0, 184, 0, 0, 0, 4, 0, 0, 0, 212, 1, 0, 0, 224, 0, -0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, -68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, -49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 129, 0, 0, 0, 112, 2, 0, 0, 133, 0, 0, 0, 128, 2, 0, 0, 133, 0, 0, 0, 144, 2, 0, 0, 80, 83, 77, 97, 105, 110, -0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 8, 1, 0, 0, 4, 0, 0, 0, 0, 0, -1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 3, 0, 0, 0, 0, 0, -1, 0, 2, 0, 3, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -0, 0, 118, 1, 0, 0, 248, 0, 0, 0, 138, 1, 0, 0, 152, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 168, 1, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 16, 1, 0, 0, 1, 0, 0, 0, 32, 1, -0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 56, 1, 0, 0, 1, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 84, 1, 0, 0, 56, 1, 0, 0, 1, 0, 0, 0, 96, 1, 0, 0, 224, 0, 0, 0, 108, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 200, 1, 0, 0, 77, 105, -99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, -0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 89, 0, -0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 6, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, -0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, -0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 5, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, -0, 0, 43, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 60, 3, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 20, 3, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 71, 108, 111, 98, 97, +108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 11, 0, 0, 0, 196, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 8, 0, 0, 0, 8, 0, +0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 76, 2, +0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 104, 2, 0, 0, 40, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 132, 2, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, +0, 0, 0, 0, 0, 0, 160, 2, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 188, 2, 0, 0, 64, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 72, 0, 0, 0, 8, 0, +0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 244, 2, 0, 0, 80, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, +84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, +115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, +32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, +1, 0, 0, 0, 1, 179, 101, 129, 18, 6, 48, 240, 95, 15, 168, 51, 209, 234, 251, 219, 6, 0, 156, 76, 0, 0, 68, 88, 66, 67, 2, 182, 28, 15, 167, 158, 21, 225, 198, 254, 189, 79, 165, 68, 11, 139, 1, 0, 0, 0, 156, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, +0, 0, 156, 4, 0, 0, 164, 74, 0, 0, 32, 75, 0, 0, 240, 75, 0, 0, 68, 76, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, +48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, +0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 78, 0, 0, 0, 200, 2, 0, 0, 78, 0, +0, 0, 216, 2, 0, 0, 78, 0, 0, 0, 232, 2, 0, 0, 78, 0, 0, 0, 248, 2, 0, 0, 90, 0, 0, 0, 8, 3, 0, 0, 90, 0, 0, 0, 28, 3, 0, 0, 92, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, +0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 20, 1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 112, 1, 0, 0, 232, 0, 0, 0, 127, 1, 0, 0, 4, 1, 0, 0, 5, 0, +0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 210, 1, 0, 0, 4, 1, 0, 0, 226, 1, 0, 0, 232, 0, 0, 0, 235, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, 1, 0, 0, 3, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 36, 1, 0, 0, 4, 0, 0, 0, 52, 1, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 160, 1, 0, 0, 2, 0, +0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 12, 2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, +49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, +2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, +3, 224, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, +0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 1, 0, 0, 0, 70, 30, +16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 1, 0, 0, 0, 70, 30, +16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, +99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, +0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, +0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, +49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 198, 226, 161, 7, 188, 94, 11, 79, 175, 235, 198, 193, 0, 120, 144, 250, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 89, 159, 2, 242, 85, 35, 109, 77, 173, 208, 155, 169, 149, 91, 218, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, -115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, -85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, -48, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, -10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 198, 90, 0, 0, 117, 131, 1, 0, 122, 152, 2, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 160, 254, -1, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 65, 185, 2, 0, 203, 103, 1, 0, 213, 255, 0, 0, 98, 163, 2, 0, 193, 228, 0, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, +114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, +114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, +101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, +41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 117, 131, +1, 0, 198, 90, 0, 0, 125, 123, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 118, 42, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, -123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, -13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, -122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 102, 108, 111, 97, 116, 52, -40, 49, 44, 32, 49, 44, 32, 49, 44, 32, 49, 41, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, -105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, -54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, -116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, -105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, -51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, -82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, -111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, -97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, -79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, -13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, -73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, -85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, -86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 118, 16, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, -116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, -105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, -117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, -115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 101, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, -83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 36, 35, 83, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 201, 245, 73, 187, 97, 15, -0, 0, 1, 0, 0, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, -116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, -101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 32, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 72, 0, -0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 16, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 20, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, -0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 42, 0, 77, 17, 140, 0, -0, 0, 28, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 45, 11, 32, 4, 68, 8, 0, 9, 12, 13, 31, 1, 84, 3, 0, 13, 44, 12, 32, 36, 0, 0, 0, 38, 0, 77, 17, 32, 2, 0, 0, 24, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 69, 11, 32, 4, 36, -8, 0, 9, 12, 13, 68, 1, 84, 12, 36, 0, 0, 0, 0, 66, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, -0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, -0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 87, 184, 241, 100, 15, 100, 181, 218, 43, 27, 222, 104, 162, 10, 186, 204, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, -0, 0, 139, 0, 0, 128, 84, 0, 0, 0, 139, 0, 0, 0, 120, 0, 0, 0, 139, 0, 0, 128, 120, 0, 0, 0, 139, 0, 0, 0, 152, 0, 0, 0, 142, 0, 0, 128, 152, 0, 0, 0, 142, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, -22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 56, 0, 0, 0, 92, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 84, 0, -0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, -242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 30, 0, -5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, -1, 0, 4, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 8, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, -5, 21, 2, 0, 0, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, -0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, 0, 0, 2, 14, 0, -23, 21, 0, 0, 0, 0, 10, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 151, 210, 3, 0, 148, 225, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 32, 49, 44, 32, 49, 44, 32, 49, 41, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, -116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, -59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, -51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, -80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, -78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, -101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, -65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, -32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, -114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, -112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, -78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, -100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, -40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 105, 110, 111, 117, -116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 32, 42, 32, 67, 111, 108, 111, -114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, -116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, -114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, -32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, -46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, -84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, -32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, +114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, +114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, +101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, +41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, +55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, +125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, +97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, +116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, +73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 48, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, -0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, -50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, +254, 239, 1, 0, 0, 0, 65, 9, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, +66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, +101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 99, 51, 55, 51, 48, 0, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, +48, 1, 128, 0, 0, 0, 241, 191, 231, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 218, 110, 132, 136, 140, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, -0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, -50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, +48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, +97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, +152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, +60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, +0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, +0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 152, 2, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 6, 12, 128, 128, 20, 8, 0, 13, 23, 1, 96, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 68, 2, 0, 0, 148, 2, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, +6, 2, 12, 128, 128, 20, 8, 0, 9, 33, 13, 82, 1, 96, 12, 128, 128, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 80, 9, 255, 202, 160, 101, 211, 131, 82, 235, 207, 84, 203, 121, 74, 200, 0, 0, 242, 0, +0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 228, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 98, 0, 0, 128, 76, 0, 0, 0, 98, 0, 0, 0, 96, 0, 0, 0, 94, 0, 0, 128, 96, 0, 0, 0, 94, 0, 0, 0, 128, 0, +0, 0, 94, 0, 0, 128, 128, 0, 0, 0, 94, 0, 0, 0, 160, 0, 0, 0, 94, 0, 0, 128, 160, 0, 0, 0, 94, 0, 0, 0, 192, 0, 0, 0, 94, 0, 0, 128, 192, 0, 0, 0, 94, 0, 0, 0, 224, 0, 0, 0, 98, 0, 0, 128, 224, 0, 0, 0, 98, 0, 0, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, +0, 0, 82, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, +49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, +0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, +0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, +0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, +1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 57, 0, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 1, 0, -0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, +55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, +125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, +97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, +116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, +73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, +49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, +0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, +68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, +0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 30, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 80, 0, -255, 255, 255, 255, 255, 255, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 34, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 20, 16, 0, 0, 6, 0, -255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, +37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 89, 159, 2, 242, 85, 35, 109, 77, 173, 208, 155, 169, 149, 91, 218, 9, 182, 0, 0, 0, 47, 76, 105, 110, 107, 73, -110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, -116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, -105, 116, 101, 101, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, 101, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, -0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 152, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 36, 3, -0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, -92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, -103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 97, 97, 52, 57, 99, 55, 48, 56, 98, 52, 50, 57, 102, 52, 54, 102, 48, 56, 52, 98, 53, 51, 100, 99, 100, 102, 52, 49, 101, 57, 53, -101, 46, 104, 108, 115, 108, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 18, 1, 0, 0, 12, 2, 0, 0, 159, 1, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 166, 16, 0, 0, 128, 0, 0, 0, 97, 15, -0, 0, 228, 3, 0, 0, 92, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 37, 0, 0, 0, 30, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 23, 0, -0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, -0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 22, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, +105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, +0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 0, 0, 0, 254, 239, +254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, +49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 198, 226, 161, 7, 188, 94, 11, 79, 175, 235, 198, 193, 0, 120, 144, 250, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, +47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, +98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 99, 51, 55, 51, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, +10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, +0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 113, 9, 0, 0, 128, 0, 0, 0, 140, 8, 0, 0, 160, 3, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, +0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, +0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -750,24 +641,26 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 12, 3, 0, 0, 1, 0, 0, 0, 160, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 228, 2, 0, 0, 124, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 137, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 151, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 71, 108, 111, 98, 97, 108, 115, 0, 171, 151, 0, -0, 0, 11, 0, 0, 0, 184, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, -0, 0, 0, 0, 0, 0, 255, 1, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 22, 2, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 45, 2, 0, 0, 32, 0, 0, 0, 8, 0, -0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 40, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 91, 2, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 114, 2, -0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 137, 2, 0, 0, 64, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 160, 2, 0, 0, 72, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 216, 1, -0, 0, 0, 0, 0, 0, 183, 2, 0, 0, 80, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 196, 2, 0, 0, 212, 2, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 0, 84, 101, 120, 116, 117, 114, 101, -54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 0, 84, 101, -120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, -128, 63, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, -171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, +65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, +0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, +114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, +77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, +105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 12, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs new file mode 100644 index 0000000000..3bec61cd7b --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [SpriteEffect] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + public partial class SpriteEffect + { + private static readonly byte[] binaryBytecode = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, +114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, +97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, +71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, +101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, +122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, +0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, +102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, +0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, +28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 198, 150, 117, 170, 158, 22, 104, 190, 201, 199, 121, 23, 219, 13, 154, +239, 0, 83, 8, 0, 0, 68, 88, 66, 67, 101, 18, 21, 195, 25, 249, 112, 84, 60, 65, 28, 162, 142, 107, 178, 76, 1, 0, 0, 0, 83, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 125, 0, 0, 0, 183, 0, 0, 0, 107, 1, 0, 0, 83, 70, 73, 48, 8, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 49, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, +48, 172, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 224, 6, 0, 0, 96, 0, 0, 0, 184, 1, 0, +0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 200, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 175, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, +98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, +0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 104, 0, 0, +0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 6, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, +8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, +3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, +0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, +149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, +2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 163, 134, 203, 159, 176, 135, 144, 124, 110, 163, 138, 149, 152, 252, 226, 182, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 8, 10, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 128, 98, +44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, +48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, +7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 84, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 177, 128, 0, 24, 0, 0, 0, 0, 0, +0, 0, 32, 11, 4, 32, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 224, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, +24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 1, 34, 0, 0, 0, 40, 57, 106, 0, 0, 0, 40, 3, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 163, 6, 0, 0, 128, 34, 32, 2, 0, 0, 128, 2, 13, 40, 187, 82, 40, 6, 106, 0, +0, 0, 40, 137, 2, 41, 4, 0, 0, 121, 24, 0, 0, 111, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 4, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, +151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, +84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 216, 54, +12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 155, 32, 52, 209, 134, 32, 152, 32, 52, 215, 134, 37, 16, 131, 49, 32, 131, 50, 48, +3, 194, 12, 2, 50, 0, 54, 4, 103, 192, 100, 202, 234, 139, 42, 76, 238, 172, 140, 110, 130, 208, 116, 19, 132, 198, 219, 176, 4, 105, 48, 6, 106, 80, 6, 100, 64, 172, 65, 64, 6, 192, 134, 128, 13, 54, 12, 104, 208, 6, 0, 183, 41, 56, 185, 52, 186, 178, 34, 51, 179, 178, 49, 58, +23, 168, 169, 166, 176, 52, 183, 175, 43, 185, 48, 56, 184, 50, 185, 13, 69, 247, 6, 110, 192, 1, 85, 216, 216, 236, 218, 92, 210, 200, 202, 220, 232, 166, 4, 81, 21, 50, 60, 23, 187, 50, 185, 185, 180, 55, 183, 41, 129, 212, 132, 12, 207, 197, 46, 140, 205, 174, 76, 110, 74, 64, 213, 33, +195, 115, 153, 67, 11, 35, 43, 147, 107, 122, 35, 43, 99, 155, 18, 92, 101, 200, 240, 92, 228, 202, 230, 222, 234, 228, 198, 202, 230, 166, 4, 91, 37, 50, 60, 23, 186, 60, 184, 178, 32, 55, 183, 55, 186, 48, 186, 180, 55, 183, 185, 41, 1, 24, 212, 33, 195, 115, 41, 115, 163, 147, 203, 131, +122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, +239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 176, 13, 151, 239, 60, 190, 16, 80, 69, 65, 68, 165, 3, 12, 37, 97, 0, 2, 230, 23, 183, 109, 5, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, +23, 183, 13, 0, 0, 97, 32, 0, 0, 50, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 30, 132, 97, 206, 51, 98, 144, 0, 32, 8, 6, 206, 23, 101, 153, 3, 141, 24, 36, 0, 8, 130, 65, 244, 57, 141, 166, 81, 35, 6, 9, 0, 130, 96, 16, 129, 193, 19, 109, 91, 53, +98, 240, 0, 32, 8, 6, 19, 24, 52, 129, 64, 12, 142, 51, 77, 147, 51, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 144, 0, 32, 8, 6, 145, 25, 84, 81, 24, 128, 193, 86, 98, 16, 65, 5, 27, 142, 24, 28, 0, 8, 130, 65, 117, 6, 210, 16, 140, 38, 4, +192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 24, 67, 72, 192, 24, 66, 2, 198, 16, 18, 48, 134, 144, 192, 136, 65, 2, 128, 32, 24, 88, 111, 160, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 214, 27, 104, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 129, 245, 6, 90, +27, 180, 65, 39, 140, 24, 36, 0, 8, 130, 129, 245, 6, 90, 27, 180, 1, 24, 4, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 155, 20, 167, 12, 233, 81, 79, 86, 205, 130, 34, 164, 247, 63, 64, 1, 0, 175, 8, 0, 0, 68, 88, 66, 67, 168, 48, 106, 90, 28, 212, 221, +191, 233, 113, 183, 216, 17, 215, 210, 235, 1, 0, 0, 0, 175, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 11, 1, 0, 0, 243, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, +0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, +0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 93, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, +0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, +80, 83, 86, 48, 224, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 1, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 180, 6, 0, 0, 96, 0, 1, 0, 173, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, +16, 0, 0, 0, 156, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 164, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, +136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, +64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, +96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 49, 0, 0, 0, 0, 238, +0, 23, 39, 0, 22, 9, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, +132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, +135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, +6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, +114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, +0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 0, 58, 0, 0, 0, 152, 1, 32, 2, +0, 0, 128, 2, 14, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, 43, 144, 2, 42, 176, 82, 40, 6, 82, 0, 0, 0, 40, 137, 66, 0, 0, 0, 121, 24, 0, 0, 101, 0, 0, 0, +26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 113, 196, 246, 38, 22, 198, 54, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, +46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 176, 13, 3, 20, 5, 27, +4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 178, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 69, 219, 176, 16, +218, 198, 129, 1, 71, 132, 1, 193, 1, 27, 132, 79, 12, 54, 44, 129, 182, 113, 157, 71, 120, 1, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 133, 40, 131, 205, 12, 186, 48, 32, 194, 128, 224, 128, 13, 2, 25, 156, 193, 134, 97, 12, 208, 0, 224, 54, +5, 39, 151, 70, 87, 86, 100, 102, 86, 54, 70, 231, 98, 53, 213, 20, 150, 230, 246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 212, 32, 13, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, +185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, +192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 212, 0, 113, 32, 0, 0, 24, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, +126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 97, 32, 0, 0, +103, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 26, 84, 85, 206, 51, 98, 144, 0, 32, 8, 6, 203, 22, 89, 150, 3, 141, 24, 36, 0, 8, 130, 193, 194, 73, 214, 5, 69, 35, 6, 9, 0, 130, 96, 176, 116, 211, 133, 65, 210, 136, 65, 2, 128, 32, 24, 44, 30, 133, 101, +208, 52, 98, 144, 0, 32, 8, 6, 203, 87, 101, 26, 68, 141, 24, 36, 0, 8, 130, 193, 243, 65, 210, 182, 61, 197, 93, 56, 98, 112, 0, 32, 8, 6, 17, 24, 64, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 98, 64, 65, 5, 30, 142, 24, 28, 0, 8, 130, +65, 116, 6, 87, 18, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 84, 26, 104, 80, 65, 25, 224, 136, 193, 1, 128, 32, 24, 68, 110, 224, 65, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 193, 1, 24, 64, 5, 108, 128, 35, 6, 7, 0, 130, 96, +16, 213, 65, 25, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 157, 4, 12, 242, 36, 96, 202, 39, 1, 35, 192, 64, 2, 182, 137, 129, 4, 44, 40, 32, 96, 22, 25, 72, 192, 2, 3, 2, 22, 153, 129, 4, 44, 56, 32, 96, 12, 26, 72, 192, 2, 4, 2, +70, 6, 107, 32, 1, 11, 16, 8, 216, 215, 6, 18, 176, 0, 129, 128, 105, 111, 32, 1, 11, 16, 8, 88, 21, 7, 18, 176, 0, 129, 128, 181, 1, 29, 72, 192, 2, 4, 2, 134, 6, 118, 32, 1, 11, 16, 8, 216, 24, 224, 129, 4, 44, 64, 32, 96, 158, 30, 72, 192, 2, 4, 2, 35, +6, 9, 0, 130, 96, 32, 213, 130, 40, 200, 194, 44, 176, 194, 49, 98, 144, 0, 32, 8, 6, 82, 45, 136, 130, 44, 204, 194, 42, 20, 35, 6, 9, 0, 130, 96, 32, 213, 130, 40, 200, 194, 44, 168, 194, 48, 98, 144, 0, 32, 8, 6, 82, 45, 136, 130, 44, 204, 66, 42, 4, 35, 6, 9, +0, 130, 96, 32, 213, 130, 40, 204, 194, 44, 176, 130, 31, 140, 24, 36, 0, 8, 130, 129, 84, 11, 162, 48, 11, 179, 176, 10, 125, 128, 0, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs index 227293f6e0..0490cba4f2 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs @@ -1,65 +1,55 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-d3d11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { internal partial class UIEffect { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 142, 253, 190, 220, 182, 142, 192, 252, 75, 89, 143, 139, 49, 178, 147, 67, 0, 100, 92, 0, 0, 68, 88, 66, 67, 45, 53, 58, 0, 0, 216, 152, 233, 141, 137, 6, 224, 98, -80, 1, 54, 1, 0, 0, 0, 100, 92, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 152, 3, 0, 0, 96, 4, 0, 0, 104, 90, 0, 0, 228, 90, 0, 0, 48, 91, 0, 0, 200, 91, 0, 0, 65, 111, 110, 57, 84, 3, 0, 0, 84, 3, 0, 0, 0, 2, 254, 255, 44, 3, 0, 0, 40, -0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 171, 0, 68, 66, 85, 71, 40, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 9, 0, 0, 0, 180, -0, 0, 0, 2, 0, 0, 0, 88, 2, 0, 0, 252, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, -112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, -98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 180, 2, 0, 0, 0, 0, 255, 255, 192, 2, 0, 0, 0, 0, 255, 255, 204, 2, 0, 0, 0, 0, 255, 255, 216, 2, 0, 0, 155, 0, 0, 0, 228, -2, 0, 0, 155, 0, 0, 0, 248, 2, 0, 0, 159, 0, 0, 0, 4, 3, 0, 0, 160, 0, 0, 0, 16, 3, 0, 0, 160, 0, 0, 0, 28, 3, 0, 0, 86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, -0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, -108, 101, 95, 105, 100, 55, 53, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 24, 1, 0, 0, 51, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 100, 1, 0, 0, 5, 0, 0, 0, 1, -0, 11, 0, 1, 0, 4, 0, 116, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 2, 0, 3, 0, 6, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 7, 0, 0, 0, 8, 0, 9, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, -255, 255, 255, 10, 0, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 234, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 24, 1, 0, 0, 51, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 100, 1, 0, 0, 5, -0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 1, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 2, 0, 0, 0, 8, 0, 9, 0, 255, 255, 255, 255, 3, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, -0, 0, 0, 252, 0, 0, 0, 148, 1, 0, 0, 5, 0, 0, 0, 164, 1, 0, 0, 252, 0, 0, 0, 224, 1, 0, 0, 24, 2, 0, 0, 4, 0, 0, 0, 40, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, -32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, -0, 0, 4, 0, 0, 3, 192, 0, 0, 255, 144, 0, 0, 228, 160, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 15, 224, 1, 0, 228, 144, 1, 0, 0, 2, 1, 0, 3, 224, 2, 0, 228, 144, 1, 0, 0, 2, 1, 0, 4, 224, 3, -0, 0, 144, 255, 255, 0, 0, 83, 72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, -16, 16, 0, 3, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, -32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 2, -0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, -0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, +0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, +1, 157, 169, 222, 211, 157, 227, 183, 129, 47, 12, 215, 103, 164, 27, 71, 160, 0, 76, 76, 0, 0, 68, 88, 66, 67, 202, 185, 245, 184, 166, 29, 241, 92, 53, 186, 50, 135, 98, 216, 123, 59, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, +0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, 76, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, +48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 84, 0, 0, 0, 212, 2, 0, 0, 86, 0, 0, 0, 228, 2, 0, 0, 93, 0, +0, 0, 244, 2, 0, 0, 95, 0, 0, 0, 8, 3, 0, 0, 95, 0, 0, 0, 24, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, +0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 49, 55, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, 1, 0, 0, 12, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 64, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, +171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, +67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 156, 1, 0, 0, 172, 1, 0, 0, 12, 1, 0, 0, 184, 1, 0, 0, 200, 1, 0, 0, 5, 0, +0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, +0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 116, 1, 0, 0, 40, 1, 0, 0, 128, 1, 0, 0, 240, 1, +0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, +0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, +255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, +16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, +16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, +16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, +16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, +0, 0, 35, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -67,7 +57,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -75,362 +65,296 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 130, 106, 175, 65, 189, 22, 7, 71, 169, 90, 99, 76, 192, 226, 98, 206, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 18, 56, 121, 208, 121, 225, 7, 70, 185, 242, 73, 245, 27, 52, 147, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, +49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, +1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 6, 212, 2, 0, 149, 49, 3, 0, 125, 218, 1, 0, 16, 77, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, -58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, -86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 198, 90, 0, 0, 117, 131, 1, 0, 119, 220, 0, 0, 156, 202, 1, 0, 38, 247, 2, 0, 90, 201, 1, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, +98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, +49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, +120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, +99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, +112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, +105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, +10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, +101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, +111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, -13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, -111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, -76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, -111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, -76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, -122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, -101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, -101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, -100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, -114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, -83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, -78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, -65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, -61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, -101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, -54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, -32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, -32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, -82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, -83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, -32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, -85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, -100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, -116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, -32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, -86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 87, 19, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, -88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, -99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, -115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, -117, 105, 101, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, -32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 27, 226, 48, 1, 128, 0, 0, 0, 110, 125, 77, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 240, 191, 121, 0, 74, 18, 0, 0, 1, -0, 0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, -82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, -118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 64, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 8, -16, 0, 0, 108, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, -0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, -0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, -0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, -0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, -0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, -0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, 0, 0, 0, 22, -0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 12, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 232, 21, 75, 17, 100, 0, 71, 25, 218, 48, 133, 132, 66, 162, 175, 97, 0, 0, 242, 0, 0, 0, 144, -0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 168, 0, 0, 128, 108, 0, 0, 0, 168, 0, 0, 0, 128, 0, 0, 0, 168, 0, 0, 128, 128, 0, 0, 0, 168, 0, 0, 0, 148, 0, 0, 0, 168, -0, 0, 128, 148, 0, 0, 0, 168, 0, 0, 0, 168, 0, 0, 0, 168, 0, 0, 128, 168, 0, 0, 0, 168, 0, 0, 0, 188, 0, 0, 0, 168, 0, 0, 128, 188, 0, 0, 0, 168, 0, 0, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, -0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 104, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, -0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 98, -0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 30, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 86, 83, 95, 73, 78, 80, 85, -84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, -111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 30, 0, 5, 21, 4, -0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 41, 11, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, +0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, +115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 102, 50, 51, 48, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 194, 222, 244, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 22, 1, 88, 250, 116, 10, +0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, +116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, +112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, +0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, +0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, +32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, +132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 34, 6, 8, 12, 128, 128, 0, 8, 0, 13, 33, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, +9, 5, 13, 59, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 58, 1, 92, 12, 128, 128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, +36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, +0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, +0, 0, 8, 0, 95, 52, 49, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, +0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 167, 105, 80, 131, 81, 219, 190, 226, 110, 156, 131, 210, 74, 33, 25, 216, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, +0, 0, 117, 0, 0, 128, 92, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 128, 120, 0, 0, 0, 117, 0, 0, 0, 156, 0, 0, 0, 117, 0, 0, 128, 156, 0, 0, 0, 117, 0, 0, 0, 192, 0, 0, 0, 117, 0, 0, 128, 192, 0, 0, 0, 117, 0, 0, 0, 220, 0, +0, 0, 120, 0, 0, 128, 220, 0, 0, 0, 120, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, +0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, -84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, -101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, -101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, -100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, -100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, -111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, -13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, -78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, -59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, -32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, -82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, -97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, -108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, -100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, -32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, -95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, -53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, -32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, -61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, -101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, -85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, -84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, -82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, -32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, -32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, -10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 12, 1, -0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, +0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, +242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, +0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, +0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, +8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, +0, 0, 3, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, +24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 170, 243, 1, 0, 72, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, +120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, +99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, +112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, +105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, +10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, +101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, +111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 108, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, +0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, +0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, +255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 18, 56, 121, 208, 121, 225, 7, 70, 185, 242, 73, 245, 27, 52, 147, 47, 178, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, -0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, -120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, -99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, -0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 68, 3, 0, 0, 0, -0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 53, 0, 0, 0, 0, 0, 0, -0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, -118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, -101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, -0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 14, 1, 0, 0, 160, 1, 0, 0, 155, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 135, 19, 0, 0, 128, 0, 0, 0, 74, 18, 0, 0, 16, -4, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 24, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 23, 0, 0, 0, 39, 0, 0, 0, 24, 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, -0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, -0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, +0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, +100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 130, 106, 175, 65, 189, 22, 7, 71, 169, 90, 99, 76, 192, 226, 98, 206, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, +110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 102, 50, 51, 48, 56, 0, +4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 89, 11, 0, 0, 128, 0, 0, 0, 116, 10, +0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, 0, +0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, +0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, -32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 15, 15, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 3, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 148, 0, 0, 0, 4, -0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 12, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 11, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 171, 0, 5, 0, 0, 0, 1, 248, 181, 21, 65, 136, 19, 152, 173, 139, 183, 12, 196, 166, 103, 125, 225, 0, 176, 100, 0, 0, 68, 88, 66, 67, 243, 154, 0, 145, 147, 235, 101, 35, 182, 163, 212, 17, 99, 74, -112, 199, 1, 0, 0, 0, 176, 100, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 204, 3, 0, 0, 180, 4, 0, 0, 188, 98, 0, 0, 56, 99, 0, 0, 224, 99, 0, 0, 124, 100, 0, 0, 65, 111, 110, 57, 136, 3, 0, 0, 136, 3, 0, 0, 0, 2, 255, 255, 96, 3, 0, 0, 40, 0, -0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 184, 0, 68, 66, 85, 71, 40, 0, 0, 0, 180, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 8, 0, 0, 0, 180, 0, -0, 0, 5, 0, 0, 0, 80, 2, 0, 0, 244, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, -105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, -53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 232, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 135, 0, 0, 0, 12, 3, 0, 0, 136, 0, 0, 0, 28, 3, -0, 0, 136, 0, 0, 0, 44, 3, 0, 0, 137, 0, 0, 0, 64, 3, 0, 0, 137, 0, 0, 0, 80, 3, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, -0, 0, 251, 0, 0, 0, 12, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 28, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, -0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 114, 1, 0, 0, 12, 1, 0, 0, 134, 1, -0, 0, 12, 1, 0, 0, 145, 1, 0, 0, 160, 1, 0, 0, 176, 1, 0, 0, 192, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 208, 1, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 1, 0, 0, 0, 8, 0, 9, 0, 10, 0, 255, 255, 115, 97, -109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 0, 0, 0, 0, 244, 0, 0, 0, 36, 1, -0, 0, 1, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 92, 1, 0, 0, 244, 0, 0, 0, 104, 1, 0, 0, 240, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 24, 2, 0, 0, 12, 1, 0, 0, 1, 0, -0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 52, 2, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, -49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 1, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 1, 0, -170, 176, 1, 0, 170, 176, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, -0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 98, 16, -0, 3, 66, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, -0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 16, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, -0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 94, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, -48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 47, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, +114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 189, 216, 4, 4, 9, 10, 95, 53, 20, 49, 237, 127, 37, 201, 233, 45, 0, 76, 84, 0, 0, 68, 88, +66, 67, 126, 152, 11, 173, 26, 190, 123, 51, 53, 207, 60, 121, 110, 166, 76, 229, 1, 0, 0, 0, 76, 84, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 82, 0, 0, 224, 82, 0, 0, 44, 83, 0, 0, 196, 83, 0, 0, 65, 111, 110, 57, 80, 3, +0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 55, 48, 56, 56, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, +255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 117, 0, 0, 0, 224, 2, 0, 0, 119, 0, 0, 0, 244, 2, 0, 0, 119, 0, 0, 0, 0, 3, 0, 0, 121, 0, 0, 0, 12, 3, 0, 0, 117, 0, +0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, +3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, +0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 68, 1, 0, 0, 4, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 5, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 8, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 188, 1, 0, 0, 232, 0, 0, 0, 203, 1, 0, 0, 8, 1, 0, 0, 218, 1, 0, 0, 8, 1, +0, 0, 230, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, +0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 5, 0, 0, 0, 116, 1, 0, 0, 208, 0, 0, 0, 176, 1, 0, 0, 20, 2, 0, 0, 4, 0, 0, 0, 36, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, +72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, +0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, +228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, +16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, +0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, +0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, +0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -438,7 +362,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -446,350 +370,263 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 219, 11, 160, 241, 120, 159, 145, 64, 163, 147, 96, 41, 93, 101, 168, 9, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 35, 9, 77, 137, 162, 222, 109, 66, 145, 37, -214, 195, 44, 104, 168, 225, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, +3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, -32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 198, 90, 0, 0, 117, 131, 1, 0, 90, 201, 1, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, -0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 122, 67, 2, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 203, 103, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 193, 228, 0, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, -98, 95, 105, 100, 55, 50, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, -67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, -84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, -67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, -50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, -105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, -10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, -95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, -69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, -105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, -102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, -52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, -56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, -83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, -110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, -32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, -114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, -97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, -41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, -105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, -112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, -117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, -111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 87, 19, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, -110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, -50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, -100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, -92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, -108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 102, 97, 108, 115, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, -123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 27, 226, 48, 1, 128, 0, 0, 0, 193, 95, 82, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 135, 0, -0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 240, 191, 121, 0, 74, 18, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, -10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, -0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 12, 4, -0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, -0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 92, 0, -0, 0, 1, 0, 132, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 40, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, -62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, -0, 0, 66, 0, 77, 17, 140, 0, 0, 0, 8, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 84, 11, 32, 13, 88, 6, 2, 3, 36, 13, 46, 6, 2, 12, 28, 64, 8, 0, 9, 27, 13, 83, 1, 92, 11, 80, 9, 28, 13, 52, 6, 2, 3, 36, 13, 87, 3, 28, 9, 12, 13, -45, 6, 2, 12, 28, 36, 50, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, -5, 0, 0, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 8, 0, -0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 12, 0, 0, 0, 54, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 4, 0, -0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, -0, 0, 1, 0, 0, 0, 16, 1, 232, 21, 75, 17, 100, 0, 71, 25, 218, 48, 133, 132, 66, 162, 175, 97, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 150, 0, -0, 128, 92, 0, 0, 0, 150, 0, 0, 0, 128, 0, 0, 0, 150, 0, 0, 128, 128, 0, 0, 0, 150, 0, 0, 0, 156, 0, 0, 0, 150, 0, 0, 128, 156, 0, 0, 0, 150, 0, 0, 0, 192, 0, 0, 0, 150, 0, 0, 128, 192, 0, 0, 0, 150, 0, 0, 0, 220, 0, 0, 0, 153, 0, -0, 128, 220, 0, 0, 0, 153, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, -0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 14, 0, 23, 21, 0, 16, -0, 0, 3, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, -24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 40, 2, 0, 0, 10, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, -0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 30, 0, -5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, -1, 0, 4, 16, 0, 0, 102, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 8, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 13, 21, 3, 0, 0, 16, -0, 0, 12, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 28, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 4, 0, 0, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 44, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 148, 225, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, +85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, +105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, +101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, +97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, +46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, +111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, +97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, +56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, +55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, +97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, +118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, +32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, -97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, -59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, -50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, -114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, -97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, -78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, -32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, -114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, -101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, -76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, -95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, -100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, -114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, -112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, -10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, -97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, -46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, -80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, -110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, -115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, -112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, -95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, -61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, -116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 12, 1, 0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 1, 16, 0, 0, 24, 0, 0, 0, 11, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 17, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, +53, 55, 48, 56, 56, 69, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, +116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 55, 48, 56, 56, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, +85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, +105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 1, 29, 248, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, +48, 1, 166, 181, 185, 5, 92, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, +77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, +108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, +0, 0, 84, 0, 0, 0, 8, 16, 0, 0, 108, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, +0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, +84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, +4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 148, 126, 56, 207, 51, 152, 48, 72, 119, 243, 162, 56, 200, 164, 98, 39, 0, 0, 242, 0, 0, 0, 144, 0, +0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 129, 0, 0, 128, 108, 0, 0, 0, 129, 0, 0, 0, 128, 0, 0, 0, 129, 0, 0, 128, 128, 0, 0, 0, 129, 0, 0, 0, 148, 0, 0, 0, 129, 0, +0, 128, 148, 0, 0, 0, 129, 0, 0, 0, 168, 0, 0, 0, 129, 0, 0, 128, 168, 0, 0, 0, 129, 0, 0, 0, 188, 0, 0, 0, 129, 0, 0, 128, 188, 0, 0, 0, 129, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, +3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, +102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, +3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, +242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, +3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, +101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, +97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, +46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, +111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, +97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, +56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, +55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, +97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, +118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, +32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, +0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, -0, 0, 34, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, -114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 135, 140, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 35, 9, 77, 137, 162, 222, 109, 66, 145, 37, -214, 195, 44, 104, 168, 225, 178, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, -110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, -50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, 53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, -6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, -0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 16, 4, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, -0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, -255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, -105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 48, 53, 101, 57, 49, 100, 101, 102, 101, 53, 97, 97, 55, 56, 97, 49, 101, 49, 98, -53, 51, 51, 50, 102, 57, 99, 56, 52, 97, 97, 101, 51, 46, 104, 108, 115, 108, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 14, 1, 0, 0, 96, 2, 0, 0, 155, 1, 0, 0, 80, 0, -0, 0, 0, 0, 0, 0, 135, 19, 0, 0, 128, 0, 0, 0, 74, 18, 0, 0, 240, 4, 0, 0, 88, 0, 0, 0, 12, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 41, 0, -0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 19, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, -0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, +0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 9, 0, 56, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, +0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, +1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 55, 48, 56, 56, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 219, 11, 160, 241, 120, 159, 145, 64, 163, 147, 96, 41, 93, 101, 168, 9, 134, 0, +0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, +53, 55, 48, 56, 56, 101, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, +220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 65, 13, +0, 0, 128, 0, 0, 0, 92, 12, 0, 0, 4, 4, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 20, 0, 0, 0, 32, 0, 0, 0, 21, 0, 0, 0, 15, 0, 0, 0, 6, 0, +0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, +0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 31, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -798,16 +635,40 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, -255, 255, 1, 65, 0, 0, 119, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, -111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 148, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 3, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 4, 0, 0, 83, 86, -95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, +0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, +0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, +0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, +115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs new file mode 100644 index 0000000000..4ea052e473 --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs @@ -0,0 +1,116 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [UIEffect] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + internal partial class UIEffect + { + private static readonly byte[] binaryBytecode = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, +93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, +24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 189, 77, 21, 155, 216, 171, 235, 220, 33, 193, 255, 51, 72, 41, 141, 73, 0, 1, 9, 0, 0, 68, +88, 66, 67, 67, 204, 72, 195, 110, 94, 19, 63, 70, 215, 205, 102, 206, 115, 208, 221, 1, 0, 0, 0, 1, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 9, 1, 0, 0, 21, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, +95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, +3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 228, 6, 0, 0, 96, 0, 0, 0, 185, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 204, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 176, 1, 0, 0, +11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, +196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, +255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 91, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, +72, 160, 144, 145, 129, 144, 64, 49, 65, 112, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, +0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, +0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, +3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, +0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, +52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, +109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, +96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, +16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 30, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, +1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, +2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 35, 0, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 133, 98, 160, 6, 0, 0, 128, 146, 40, 132, 2, 1, 121, 24, 0, 0, 124, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, +99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 35, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 10, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, +186, 58, 185, 50, 152, 9, 2, 177, 76, 16, 20, 102, 130, 64, 52, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, +152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 225, 108, 16, 8, 138, 2, 220, 220, 4, 129, 200, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 10, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, +67, 79, 79, 82, 68, 19, 132, 70, 155, 32, 52, 208, 134, 32, 152, 32, 52, 210, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, 2, 50, 0, 54, 4, 196, 4, 161, 217, 54, 44, 132, 24, 140, 1, 25, 160, 129, 25, 16, 105, 64, 144, 1, 176, 33, 96, 38, 8, 77, 180, 97, 97, 196, +96, 12, 200, 96, 13, 204, 128, 96, 3, 134, 12, 128, 13, 195, 25, 168, 65, 27, 48, 153, 178, 250, 162, 10, 147, 59, 43, 163, 155, 32, 52, 220, 134, 37, 120, 131, 49, 128, 131, 50, 32, 3, 34, 13, 2, 50, 0, 54, 4, 113, 176, 97, 112, 3, 57, 0, 72, 6, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 142, 14, 230, 128, 3, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 162, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, +169, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 128, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 184, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 182, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, +110, 115, 83, 2, 48, 168, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 160, 3, 0, 0, 0, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 65, 167, 205, 112, 218, 253, +189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, +82, 211, 67, 77, 126, 113, 219, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 220, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 78, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 129, 227, 69, 88, 246, 64, 35, 6, 9, 0, 130, 96, 224, 124, 82, 166, +61, 209, 136, 65, 2, 128, 32, 24, 56, 96, 48, 105, 219, 35, 141, 24, 36, 0, 8, 130, 129, 19, 6, 212, 198, 61, 211, 136, 65, 2, 128, 32, 24, 56, 98, 80, 97, 221, 68, 141, 24, 36, 0, 8, 130, 65, 36, 6, 80, 228, 121, 216, 136, 65, 2, 128, 32, 24, 68, 99, 16, 85, 223, 151, +141, 24, 60, 0, 8, 130, 193, 52, 6, 80, 32, 36, 72, 20, 93, 215, 21, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 12, 55, 32, 84, 48, 221, 64, 20, 193, 116, 3, 97, 8, 211, 13, 196, 49, 24, 2, 73, 192, 8, 72, 2, 70, 64, 18, 48, 2, 146, 192, 136, 65, +2, 128, 32, 24, 80, 111, 176, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 212, 27, 108, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 1, 245, 6, 91, 27, 180, 65, 24, 8, 35, 6, 9, 0, 130, 96, 64, 189, 193, 214, 6, 109, 0, 6, 1, 2, 0, 0, 0, 0, 0, 0, +1, 0, 1, 0, 0, 0, 1, 59, 75, 78, 219, 93, 253, 16, 21, 103, 178, 237, 164, 19, 53, 47, 154, 0, 151, 8, 0, 0, 68, 88, 66, 67, 200, 4, 86, 72, 77, 165, 5, 2, 24, 188, 255, 202, 137, 38, 9, 225, 1, 0, 0, 0, 151, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, +68, 0, 0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 19, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, +86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 92, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 16, +0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, +0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, +0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 124, 5, 0, 0, 96, 0, 1, 0, 95, 1, 0, 0, 68, +88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 100, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 86, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, +64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, +140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, +113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, +8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, +104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, +160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, +7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 17, 0, 0, 0, 50, 30, 152, 20, 25, +17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, +24, 0, 0, 114, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, 54, 32, 129, 48, 4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, +152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, 133, 130, 221, 220, 4, 129, 128, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, +54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 35, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 164, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, +186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 225, 108, 8, 196, 96, 130, 112, 40, 27, 22, 49, 176, 46, 108, 12, 48, 130, 12, 196, 0, 3, 54, 16, 155, 23, 6, 101, 176, 97, 9, 172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, +52, 130, 12, 62, 12, 224, 50, 101, 245, 5, 245, 54, 151, 70, 151, 246, 230, 54, 65, 56, 152, 13, 139, 24, 168, 193, 181, 6, 89, 71, 116, 98, 128, 1, 27, 136, 51, 64, 131, 52, 96, 131, 13, 131, 25, 180, 1, 64, 50, 168, 74, 42, 50, 51, 43, 27, 163, 155, 66, 11, 35, 43, 147, 227, +49, 11, 99, 155, 43, 243, 113, 177, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 68, 111, 224, 6, 16, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 112, 84, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 32, 77, 200, 240, 92, 236, 194, 216, 236, +202, 228, 166, 4, 74, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 65, 83, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 240, 84, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 80, 117, 200, 240, 92, +202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 111, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 89, 167, 205, 112, 218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, +47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 66, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 18, 243, 60, 202, 50, 98, 144, 0, 32, 8, 6, 200, 212, 64, 144, +194, 140, 24, 36, 0, 8, 130, 1, 66, 57, 80, 196, 52, 35, 6, 9, 0, 130, 96, 128, 84, 79, 36, 49, 206, 136, 65, 2, 128, 32, 24, 32, 22, 36, 77, 204, 51, 98, 144, 0, 32, 8, 6, 200, 21, 77, 20, 3, 141, 24, 36, 0, 8, 130, 1, 130, 73, 76, 5, 69, 35, 6, 9, 0, +130, 96, 128, 100, 83, 99, 65, 210, 136, 65, 2, 128, 32, 24, 32, 26, 229, 92, 208, 52, 98, 144, 0, 32, 8, 6, 200, 86, 61, 24, 68, 141, 24, 36, 0, 8, 130, 1, 194, 89, 79, 70, 85, 35, 6, 9, 0, 130, 96, 144, 112, 15, 164, 85, 201, 136, 65, 2, 128, 32, 24, 36, 220, 3, +105, 20, 50, 98, 144, 0, 32, 8, 6, 9, 247, 64, 218, 116, 140, 24, 36, 0, 8, 130, 65, 194, 61, 144, 38, 25, 35, 6, 9, 0, 130, 96, 144, 112, 143, 166, 85, 203, 136, 65, 2, 128, 32, 24, 36, 220, 163, 105, 148, 50, 98, 144, 0, 32, 8, 6, 9, 247, 100, 90, 85, 140, 24, 36, +0, 8, 130, 65, 194, 61, 153, 70, 17, 35, 6, 9, 0, 130, 96, 144, 112, 79, 166, 77, 195, 136, 65, 2, 128, 32, 24, 36, 220, 147, 105, 146, 48, 98, 144, 0, 32, 8, 6, 9, 247, 68, 90, 21, 32, 0, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs index fc4c50a99b..d508d15bf9 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -1,69 +1,55 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-d3d11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { internal partial class UIEffect { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, -200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 28, 78, 182, 82, 201, 142, 159, 152, 95, 229, 212, 37, 219, 107, 242, 194, 0, 112, 93, 0, 0, 68, 88, 66, 67, 185, 120, 144, 228, 20, 89, 152, 37, 44, 66, 55, 250, 66, -13, 114, 145, 1, 0, 0, 0, 112, 93, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 20, 4, 0, 0, 108, 5, 0, 0, 116, 91, 0, 0, 240, 91, 0, 0, 60, 92, 0, 0, 212, 92, 0, 0, 65, 111, 110, 57, 208, 3, 0, 0, 208, 3, 0, 0, 0, 2, 254, 255, 168, 3, 0, 0, 40, -0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 182, 0, 68, 66, 85, 71, 40, 0, 0, 0, 172, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 176, 0, 0, 0, 13, 0, 0, 0, 180, -0, 0, 0, 2, 0, 0, 0, 132, 2, 0, 0, 28, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, -112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, -48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 224, 2, 0, 0, 0, 0, 255, 255, 248, 2, 0, 0, 0, 0, 255, 255, 4, 3, 0, 0, 0, 0, 255, 255, 16, 3, 0, 0, 0, 0, 255, 255, 28, -3, 0, 0, 142, 0, 0, 0, 40, 3, 0, 0, 142, 0, 0, 0, 60, 3, 0, 0, 142, 0, 0, 0, 80, 3, 0, 0, 155, 0, 0, 0, 96, 3, 0, 0, 155, 0, 0, 0, 116, 3, 0, 0, 142, 0, 0, 0, 128, 3, 0, 0, 160, 0, 0, 0, 140, 3, 0, 0, 160, 0, 0, 0, 152, -3, 0, 0, 86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 35, 1, 0, 0, 56, -1, 0, 0, 72, 1, 0, 0, 56, 1, 0, 0, 83, 1, 0, 0, 100, 1, 0, 0, 116, 1, 0, 0, 132, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 148, 1, 0, 0, 7, 0, 0, 0, 4, 0, 5, 0, 6, 0, 255, 255, 8, 0, 0, 0, 0, 0, 1, 0, 255, -255, 255, 255, 9, 0, 0, 0, 255, 255, 255, 255, 2, 0, 3, 0, 10, 0, 0, 0, 255, 255, 255, 255, 255, 255, 7, 0, 11, 0, 0, 0, 8, 0, 9, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 22, 2, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 56, 1, 0, 0, 83, 1, 0, 0, 100, 1, 0, 0, 116, 1, 0, 0, 132, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 36, 2, 0, 0, 1, 0, 0, 0, 0, -0, 1, 0, 2, 0, 3, 0, 2, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 3, 0, 0, 0, 8, 0, 9, 0, 255, 255, 255, 255, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 28, 1, 0, 0, 180, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 28, -1, 0, 0, 12, 2, 0, 0, 68, 2, 0, 0, 4, 0, 0, 0, 84, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 1, -0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, -0, 15, 144, 4, 0, 0, 4, 0, 0, 7, 128, 1, 0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 1, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 0, 0, 7, 224, 0, 0, 228, 128, 1, 0, 228, 144, 4, 0, 0, 4, 0, -0, 3, 192, 0, 0, 255, 144, 0, 0, 228, 160, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 8, 224, 1, 0, 255, 144, 1, 0, 0, 2, 1, 0, 3, 224, 2, 0, 228, 144, 1, 0, 0, 2, 1, 0, 4, 224, 3, 0, 0, 144, 255, -255, 0, 0, 83, 72, 68, 82, 80, 1, 0, 0, 64, 0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, -0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 2, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, -0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, -162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, -0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 2, -0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 2, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, -0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, +0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, +1, 154, 189, 83, 121, 135, 82, 163, 70, 23, 190, 123, 153, 33, 15, 144, 64, 0, 72, 76, 0, 0, 68, 88, 66, 67, 242, 226, 198, 214, 21, 161, 113, 224, 244, 54, 44, 73, 216, 80, 228, 185, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, +0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, 76, 0, 0, 65, 111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, +48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 84, 0, 0, 0, 208, 2, 0, 0, 86, 0, 0, 0, 224, 2, 0, 0, 93, 0, +0, 0, 240, 2, 0, 0, 95, 0, 0, 0, 4, 3, 0, 0, 95, 0, 0, 0, 20, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, +0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 49, 55, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 60, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, +0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 168, 1, 0, 0, 8, 1, 0, 0, 180, 1, 0, 0, 196, 1, 0, 0, 5, 0, 0, 0, 1, 0, +7, 0, 1, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 1, +0, 0, 1, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 36, 1, 0, 0, 68, 1, 0, 0, 1, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 112, 1, 0, 0, 36, 1, 0, 0, 124, 1, 0, 0, 236, 1, 0, 0, 2, 0, +0, 0, 252, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, +0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, +228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, +0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, +0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, +0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, +0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, +0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -71,7 +57,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -79,362 +65,300 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 4, 46, 216, 174, 161, 45, 122, 65, 183, 32, 96, 199, 233, 143, 10, 227, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, +101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, +0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 6, 212, 2, 0, 149, 49, 3, 0, 125, 218, 1, 0, 16, 77, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 215, 19, 2, 14, 102, 18, 29, 78, 175, 194, 17, 160, 199, 231, 117, 50, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, +101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, +97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, +46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, +116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, +101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, +117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, +32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, +111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, +67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, +116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, +40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, +114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, +117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, -125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 198, 90, 0, 0, 117, 131, 1, 0, 119, 220, 0, 0, 156, 202, 1, 0, 38, 247, 2, 0, 90, 201, 1, 0, 69, 103, 0, 0, 49, -251, 3, 0, 168, 209, 0, 0, 25, 96, 3, 0, 65, 36, 1, 0, 68, 117, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, -61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, -83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, -76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, -114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, -66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, -49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, -51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, -100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, -114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, -69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, -125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, -84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, -112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, -13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, -48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, -101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, -53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, -114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, -122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, -82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, -32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, -97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, -78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, -95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, -10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, -116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, -108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 19, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, -114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, -104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, -107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, -92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, -32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, -52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 27, 226, 48, 1, 128, 0, 0, 0, 129, 164, 77, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 40, 0, 0, 0, 27, -226, 48, 1, 222, 0, 75, 111, 153, 18, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, -71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, -0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 120, 3, 0, 0, 0, 0, 0, 0, 220, -0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, 16, 0, 0, 116, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, -0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, -0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 48, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 116, -0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 116, -0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 12, 0, 0, 0, 50, 0, 77, 17, 140, 0, 0, 0, 116, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 93, 6, 4, 12, 128, 136, 20, 8, -0, 9, 35, 13, 66, 1, 128, 136, 3, 0, 9, 27, 13, 81, 3, 60, 9, 19, 13, 82, 12, 28, 48, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 61, 116, 74, 10, 131, 149, 241, 67, 19, 93, 0, 13, 93, 154, 31, 20, 0, 0, 242, -0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 172, 0, 0, 128, 116, 0, 0, 0, 172, 0, 0, 0, 136, 0, 0, 0, 165, 0, 0, 128, 136, 0, 0, 0, 165, 0, 0, 0, 196, -0, 0, 0, 165, 0, 0, 128, 196, 0, 0, 0, 165, 0, 0, 0, 244, 0, 0, 0, 165, 0, 0, 128, 244, 0, 0, 0, 165, 0, 0, 0, 16, 1, 0, 0, 172, 0, 0, 128, 16, 1, 0, 0, 172, 0, 0, 0, 36, 1, 0, 0, 172, 0, 0, 128, 36, 1, 0, 0, 172, 0, 0, 0, 56, -1, 0, 0, 172, 0, 0, 128, 56, 1, 0, 0, 172, 0, 0, 0, 76, 1, 0, 0, 172, 0, 0, 128, 76, 1, 0, 0, 172, 0, 0, 0, 5, 0, 22, 0, 5, 0, 22, 0, 9, 0, 62, 0, 30, 0, 61, 0, 9, 0, 62, 0, 30, 0, 61, 0, 9, 0, 62, 0, 30, 0, 61, 0, 5, -0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 140, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 12, 16, 0, 0, 144, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, -255, 3, 0, 0, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, -0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 98, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, -21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 30, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 44, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, -21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 0, 241, 30, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, -16, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 0, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 10, 16, 0, 0, 23, 0, 1, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 235, 253, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 37, 11, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 0, 99, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 56, 56, 49, 54, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 229, 68, 21, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 234, 207, 16, 230, 112, 10, 0, 0, 1, 0, +0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, -105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, -53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, -114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, -52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, -13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, -113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, -95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, -114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, -101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, -114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, -84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, -10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, -112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, -13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, -101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, -32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, -46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, -101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, -114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, -116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, -32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, -49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, -112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, -95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, -119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, -59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, -125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, -109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, -117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, -114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 1, 16, 0, 0, 28, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, -255, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 26, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, +41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, +95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, +0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, +132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, +4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, +117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, +0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 8, 12, 128, 128, 0, 8, 0, 13, 32, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 58, +11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 57, 1, 92, 12, 128, 128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, +9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, +36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, +95, 52, 49, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, +5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, +0, 0, 1, 0, 0, 0, 16, 1, 61, 27, 161, 135, 201, 0, 224, 65, 85, 2, 199, 236, 7, 73, 45, 219, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 117, 0, +0, 128, 92, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 128, 120, 0, 0, 0, 117, 0, 0, 0, 156, 0, 0, 0, 117, 0, 0, 128, 156, 0, 0, 0, 117, 0, 0, 0, 192, 0, 0, 0, 117, 0, 0, 128, 192, 0, 0, 0, 117, 0, 0, 0, 220, 0, 0, 0, 120, 0, +0, 128, 220, 0, 0, 0, 120, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, +0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 26, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, +0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, +3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, +105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, +0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, +0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, +0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, +0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 20, 209, 2, 0, 170, 56, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, +105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, +97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, +46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, +116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, +101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, +117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, +32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, +111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, +67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, +116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, +40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, +114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, +117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 104, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, +0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, +95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, +0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, +95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 48, 0, 48, 0, 255, -255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 48, 0, 48, 0, 255, -255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, 0, 0, 215, 19, 2, 14, 102, 18, 29, 78, 175, 194, 17, 160, 199, 231, 117, 50, 178, -0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, -114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, -104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, -0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, -0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 2, 0, 9, 0, 124, 3, 0, 0, 0, 0, 0, 0, 24, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, -0, 0, 96, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, -0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, -92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, -98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 14, 1, 0, 0, 200, 1, 0, 0, 155, 1, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 214, -19, 0, 0, 128, 0, 0, 0, 153, 18, 0, 0, 156, 4, 0, 0, 56, 0, 0, 0, 12, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 24, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 23, 0, 0, 0, 40, 0, 0, 0, 33, 0, 0, 0, 18, 0, 0, 0, 6, -0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, -0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 38, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, +0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, +48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 4, 46, 216, 174, 161, 45, 122, 65, 183, 32, 96, 199, 233, 143, 10, 227, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, +47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 56, 56, 49, 54, 56, 0, 4, 0, 0, 0, +6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 28, -0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, -3, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -0, 171, 171, 79, 83, 71, 78, 148, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, -0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 12, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 4, 11, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, -79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 171, 0, 5, 0, 0, 0, 1, 252, 83, 232, 88, 177, 131, 84, 139, 219, 25, 250, 176, 149, 18, 50, 52, 0, 176, 100, 0, 0, 68, 88, 66, 67, 101, 110, -141, 65, 8, 63, 214, 34, 68, 13, 158, 130, 208, 149, 225, 203, 1, 0, 0, 0, 176, 100, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 204, 3, 0, 0, 180, 4, 0, 0, 188, 98, 0, 0, 56, 99, 0, 0, 224, 99, 0, 0, 124, 100, 0, 0, 65, 111, 110, 57, 136, 3, 0, 0, 136, 3, -0, 0, 0, 2, 255, 255, 96, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 184, 0, 68, 66, 85, 71, 40, 0, 0, 0, 180, 2, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 176, 0, 0, 0, 8, 0, 0, 0, 180, 0, 0, 0, 5, 0, 0, 0, 80, 2, 0, 0, 244, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, -46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, -56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 232, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 135, 0, -0, 0, 12, 3, 0, 0, 136, 0, 0, 0, 28, 3, 0, 0, 136, 0, 0, 0, 44, 3, 0, 0, 137, 0, 0, 0, 64, 3, 0, 0, 137, 0, 0, 0, 80, 3, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, -3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 251, 0, 0, 0, 12, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 28, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 1, 0, -3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, -0, 0, 114, 1, 0, 0, 12, 1, 0, 0, 134, 1, 0, 0, 12, 1, 0, 0, 145, 1, 0, 0, 160, 1, 0, 0, 176, 1, 0, 0, 192, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 208, 1, 0, 0, 0, 0, 0, 0, 4, 0, 5, 0, 6, 0, 7, 0, 1, 0, -0, 0, 8, 0, 9, 0, 10, 0, 255, 255, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, -3, 0, 0, 0, 0, 0, 244, 0, 0, 0, 36, 1, 0, 0, 1, 0, 0, 0, 52, 1, 0, 0, 0, 0, 0, 0, 64, 1, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 92, 1, 0, 0, 244, 0, 0, 0, 104, 1, 0, 0, 240, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 24, 2, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 52, 2, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, -67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 1, 0, 228, 176, 0, 8, -228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 1, 0, 170, 176, 1, 0, 170, 176, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, -228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, -0, 3, 50, 16, 16, 0, 2, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 2, 0, 0, 0, 70, 126, -16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 42, 16, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 55, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 70, 14, -16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 94, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, -67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 47, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 85, 11, 0, 0, 128, 0, 0, 0, 112, 10, 0, 0, 220, 4, +0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, +0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, +0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, +46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 85, 241, 60, 24, 232, 10, 79, 78, 78, 208, 4, 40, 89, 149, 176, 122, 0, 88, 85, 0, 0, 68, 88, 66, 67, 232, 180, +97, 71, 2, 247, 132, 76, 220, 220, 206, 167, 20, 185, 16, 241, 1, 0, 0, 0, 88, 85, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 83, 0, 0, 236, 83, 0, 0, 56, 84, 0, 0, 208, 84, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, +0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 128, 2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, +97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, +0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 0, 0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 91, 0, 0, 0, 36, 3, 0, 0, 91, 0, 0, 0, 56, 3, 0, 0, 91, 0, 0, 0, 76, 3, 0, 0, 117, 0, 0, 0, 92, 3, +0, 0, 119, 0, 0, 0, 112, 3, 0, 0, 119, 0, 0, 0, 124, 3, 0, 0, 91, 0, 0, 0, 136, 3, 0, 0, 117, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, +2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, +1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 245, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, +4, 0, 100, 1, 0, 0, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 8, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, +5, 0, 12, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 232, 1, 0, 0, 8, 1, 0, 0, 247, 1, 0, 0, 40, 1, 0, 0, 6, 2, 0, 0, 40, 1, 0, 0, 18, 2, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 32, 2, +0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 240, 0, 0, 0, 132, 1, 0, 0, 6, 0, +0, 0, 148, 1, 0, 0, 240, 0, 0, 0, 220, 1, 0, 0, 64, 2, 0, 0, 4, 0, 0, 0, 80, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, +49, 0, 81, 0, 0, 5, 1, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, +0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, +228, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 0, 0, +12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 80, 1, 0, 0, 64, 0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, +0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 104, 0, +0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, +0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, +16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, +0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, +48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -442,7 +366,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 240, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -450,335 +374,217 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, -0, 0, 11, 83, 250, 141, 157, 7, 75, 78, 176, 136, 51, 126, 218, 123, 205, 10, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, -99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, -82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 198, 90, 0, 0, 117, 131, 1, 0, 90, 201, -1, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 122, 67, 2, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 203, 103, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 193, 228, 0, 0, 184, 232, -1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, -105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, -67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, -110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, -55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, -83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, -52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, -68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, -117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, -117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, -95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, -73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, -114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, -66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, -84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, -70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, -109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, -97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, -108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, -100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, -108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, -111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, -114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, -76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, -32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, -41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, -117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, -32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, -95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, -40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, -84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, -95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, -95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 19, -0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, -92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, -56, 49, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, -112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, -49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 99, 111, 110, 115, 116, 32, 115, 116, 97, 116, 105, 99, 32, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 95, 105, 100, 55, 50, 32, 61, 32, 116, 114, 117, 101, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, -83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 27, 226, 48, 1, 128, 0, 0, 0, 206, 134, -82, 34, 72, 125, 213, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 222, 0, 75, 111, 153, 18, 0, 0, 1, 0, 0, 0, 134, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, -0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, -61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, -0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 12, 4, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, -112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, -132, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, -4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 32, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 40, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, -114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, -132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, -4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 66, 0, 77, 17, 140, 0, 0, 0, 8, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 84, 11, 32, 13, 88, 6, 2, 3, 36, 13, 46, 6, 2, 12, 28, 64, 8, 0, 9, 27, 13, 83, 1, 92, 11, 80, 9, 28, 13, -52, 6, 2, 3, 36, 13, 87, 3, 28, 9, 12, 13, 45, 6, 2, 12, 28, 36, 50, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, -4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 128, 0, 0, 0, 1, 0, 64, 0, 12, 0, 0, 0, 54, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, -4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, -78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 61, 116, 74, 10, 131, 149, 241, 67, 19, 93, 0, 13, 93, 154, 31, 20, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, -0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 150, 0, 0, 128, 92, 0, 0, 0, 150, 0, 0, 0, 128, 0, 0, 0, 150, 0, 0, 128, 128, 0, 0, 0, 150, 0, 0, 0, 156, 0, 0, 0, 150, 0, 0, 128, 156, 0, 0, 0, 150, 0, 0, 0, 192, 0, 0, 0, 150, 0, 0, 128, 192, 0, -0, 0, 150, 0, 0, 0, 220, 0, 0, 0, 153, 0, 0, 128, 220, 0, 0, 0, 153, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, -0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 134, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, -1, 0, 11, 16, 0, 0, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 16, 234, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 234, 0, 0, 242, 241, 10, 0, -24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, -0, 0, 20, 16, 0, 0, 40, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, -116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, -242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 16, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 32, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 83, 119, 105, 122, -122, 108, 101, 95, 105, 100, 55, 53, 0, 241, 30, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, -0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, -1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 102, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 64, 0, 0, 0, 8, 0, 83, 119, 105, 122, 122, 108, 101, 95, -105, 100, 55, 53, 0, 241, 13, 21, 3, 0, 0, 16, 0, 0, 12, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 28, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 4, 0, -0, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 148, 225, 0, 0, 0, 16, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 32, 58, 32, -80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 125, 59, 13, 10, 99, -98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, -95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, -101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, -50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, -53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, -55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, -32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, -97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, -95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, -61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, -32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, -59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, -73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, -125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, -105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, -52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 61, 32, 48, 32, 63, 32, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 32, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, -115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, -53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, -83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, -104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, -32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, -51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, -46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 41, 59, 13, 10, 32, 32, 32, 32, 125, -13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, -108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, -116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, -122, 122, 108, 101, 95, 105, 100, 55, 53, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -12, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, -0, 0, 1, 16, 0, 0, 24, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, -103, 95, 105, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, +0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 4, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, -103, 95, 105, 100, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 179, 154, 95, 31, 253, 5, 74, 76, 157, 242, +177, 234, 82, 163, 35, 186, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, -0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, +83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, +101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, +2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, 3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, -0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 34, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, -255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, +83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, +101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, +101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, +58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, +116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, +95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, +86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, +66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, +48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, +46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, +32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, +32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, +116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, +41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 14, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, +97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 97, 52, 101, 54, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 99, 220, 22, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, +0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 117, 192, 247, 227, 89, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 103, 92, 0, 0, 0, 0, 55, 50, 92, 108, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, +10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, +0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 204, 3, 0, 0, 0, 0, +0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, 16, 0, 0, 116, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, 0, +0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, +220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, +4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, +220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 200, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 10, 12, 128, 136, 40, 8, 0, 13, 32, 1, 128, +156, 12, 128, 136, 0, 0, 42, 0, 77, 17, 52, 3, 0, 0, 196, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 8, 0, 9, 27, 13, 53, 1, 128, 156, 12, 128, 136, 0, 0, 0, 0, 54, 0, 77, 17, 92, 3, 0, 0, 192, 3, 0, 0, 2, 16, +0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 156, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, +0, 0, 1, 0, 0, 0, 16, 1, 165, 95, 147, 40, 192, 223, 191, 125, 108, 82, 45, 147, 97, 56, 255, 117, 0, 0, 242, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 129, 0, +0, 128, 116, 0, 0, 0, 129, 0, 0, 0, 136, 0, 0, 0, 129, 0, 0, 128, 136, 0, 0, 0, 129, 0, 0, 0, 156, 0, 0, 0, 123, 0, 0, 128, 156, 0, 0, 0, 123, 0, 0, 0, 216, 0, 0, 0, 123, 0, 0, 128, 216, 0, 0, 0, 123, 0, 0, 0, 8, 1, 0, 0, 123, 0, +0, 128, 8, 1, 0, 0, 123, 0, 0, 0, 36, 1, 0, 0, 129, 0, 0, 128, 36, 1, 0, 0, 129, 0, 0, 0, 56, 1, 0, 0, 129, 0, 0, 128, 56, 1, 0, 0, 129, 0, 0, 0, 76, 1, 0, 0, 129, 0, 0, 128, 76, 1, 0, 0, 129, 0, 0, 0, 5, 0, 24, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, +0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 200, 1, 0, 0, 10, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, +0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, +83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, +5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, +0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 148, 128, 1, 0, 138, 207, 3, 0, 64, 168, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 116, 150, 155, 93, 1, 0, -0, 0, 11, 83, 250, 141, 157, 7, 75, 78, 176, 136, 51, 126, 218, 123, 205, 10, 178, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, -101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 120, 101, 110, 107, 111, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, -92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 117, 105, 101, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, 56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, -56, 49, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, -220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, -0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 16, 4, 0, 0, 0, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, -101, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, -0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 120, 101, 110, 107, 111, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 88, 101, 110, 107, 111, 46, 67, 111, 114, 101, -46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 85, 73, 69, 102, 102, 101, 99, 116, 95, 54, 99, 54, 54, 52, 97, 52, -56, 48, 53, 57, 53, 53, 99, 50, 50, 100, 54, 48, 98, 98, 54, 100, 50, 49, 97, 98, 101, 99, 50, 56, 49, 46, 104, 108, 115, 108, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 14, 1, -0, 0, 96, 2, 0, 0, 155, 1, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 214, 19, 0, 0, 128, 0, 0, 0, 153, 18, 0, 0, 240, 4, 0, 0, 88, 0, 0, 0, 12, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 40, 0, -0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 41, 0, 0, 0, 34, 0, 0, 0, 18, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 19, 0, 0, 0, 8, 0, -0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 35, 0, 0, 0, 36, 0, -0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, +101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, +58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, +116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, +95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, +86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, +66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, +48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, +46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, +32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, +32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, +116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, +41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, +255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, +0, 0, 10, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, +101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, +0, 0, 10, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, +101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -792,26 +598,81 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 119, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, -0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, -76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 148, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, -0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 3, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 4, 4, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 79, 76, 79, 82, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, -0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, +1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 3, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, +0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, +255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, +114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 179, 154, 95, 31, 253, 5, 74, 76, 157, 242, +177, 234, 82, 163, 35, 186, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 97, 52, 101, 54, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, +5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 0, 2, 0, 0, 111, 1, 0, 0, 156, 0, +0, 0, 0, 0, 0, 0, 62, 13, 0, 0, 128, 0, 0, 0, 89, 12, 0, 0, 8, 5, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 33, 0, 0, 0, 27, 0, +0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, +0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 21, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, +254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, +0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs new file mode 100644 index 0000000000..74f5f2f41f --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -0,0 +1,118 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [UIEffect] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + internal partial class UIEffect + { + private static readonly byte[] binaryBytecodeSRgb = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, +93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, +24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 152, 125, 156, 155, 102, 27, 190, 176, 60, 205, 167, 118, 128, 139, 0, 83, 0, 253, 8, 0, 0, 68, +88, 66, 67, 105, 222, 61, 200, 62, 222, 130, 78, 218, 190, 85, 175, 241, 135, 121, 182, 1, 0, 0, 0, 253, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 9, 1, 0, 0, 21, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, +95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, +3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 224, 6, 0, 0, 96, 0, 0, 0, 184, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 200, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 175, 1, 0, 0, +11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, +196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, +255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 91, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, +72, 160, 144, 145, 129, 144, 64, 49, 65, 112, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, +0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, +0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, +3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, +0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, +52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, +109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, +96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, +16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 30, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, +1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, +2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 35, 0, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 133, 98, 160, 6, 0, 0, 128, 146, 40, 132, 2, 1, 121, 24, 0, 0, 123, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, +99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 35, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 10, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, +186, 58, 185, 50, 152, 9, 2, 177, 76, 16, 20, 102, 130, 64, 52, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, +152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 225, 108, 16, 8, 138, 2, 220, 220, 4, 129, 200, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 10, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, +67, 79, 79, 82, 68, 19, 132, 70, 155, 32, 52, 208, 134, 32, 152, 32, 52, 210, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, 2, 50, 0, 54, 4, 196, 4, 161, 217, 54, 44, 132, 24, 140, 1, 25, 160, 129, 25, 16, 105, 64, 144, 1, 176, 33, 96, 38, 8, 77, 180, 97, 97, 196, +96, 12, 200, 96, 13, 204, 128, 96, 3, 134, 12, 128, 13, 195, 25, 168, 65, 27, 48, 153, 178, 250, 162, 10, 147, 59, 43, 163, 155, 32, 52, 220, 134, 37, 120, 131, 49, 128, 131, 50, 32, 3, 34, 13, 2, 50, 0, 54, 4, 113, 176, 97, 112, 3, 57, 0, 56, 6, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 142, 14, 230, 128, 3, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 162, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 169, +9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 128, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 184, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 182, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, +115, 83, 2, 48, 168, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 160, 3, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 130, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, +178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 27, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 141, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, +226, 182, 1, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 220, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 78, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 129, 227, 69, 88, 246, 64, 35, 6, 9, 0, 130, 96, 224, 124, 82, 166, 61, 209, 136, 65, +2, 128, 32, 24, 56, 96, 48, 105, 219, 35, 141, 24, 36, 0, 8, 130, 129, 19, 6, 212, 198, 61, 211, 136, 65, 2, 128, 32, 24, 56, 98, 80, 97, 221, 68, 141, 24, 36, 0, 8, 130, 65, 36, 6, 80, 228, 121, 216, 136, 65, 2, 128, 32, 24, 68, 99, 16, 85, 223, 151, 141, 24, 60, 0, +8, 130, 193, 52, 6, 80, 32, 36, 72, 20, 93, 215, 21, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 12, 55, 32, 84, 48, 221, 64, 20, 193, 116, 3, 97, 8, 211, 13, 196, 49, 24, 2, 73, 192, 8, 72, 2, 70, 64, 18, 48, 2, 146, 192, 136, 65, 2, 128, 32, 24, +80, 111, 176, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 212, 27, 108, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 1, 245, 6, 91, 27, 180, 65, 24, 8, 35, 6, 9, 0, 130, 96, 64, 189, 193, 214, 6, 109, 0, 6, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, +0, 0, 1, 14, 70, 255, 142, 29, 31, 250, 44, 38, 196, 28, 169, 108, 101, 160, 81, 0, 7, 9, 0, 0, 68, 88, 66, 67, 54, 36, 105, 211, 102, 104, 128, 1, 45, 38, 214, 138, 212, 77, 103, 176, 1, 0, 0, 0, 7, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, +248, 0, 0, 0, 175, 1, 0, 0, 19, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, +0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, +2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, +115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 92, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, +0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, +0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 236, 5, 0, 0, 96, 0, 1, 0, 123, 1, 0, 0, 68, 88, 73, 76, 0, +1, 0, 0, 16, 0, 0, 0, 212, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 114, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, +72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, +255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, +10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, +8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, +3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, +7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, +144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, +9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 3, 2, 0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, +16, 205, 85, 39, 61, 34, 0, 0, 0, 40, 133, 98, 160, 3, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 114, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, 54, 32, 129, 48, +4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, 133, 130, 221, 220, +4, 129, 152, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 131, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, +1, 49, 65, 56, 170, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 225, 108, 8, 196, 96, 130, 112, 40, 27, 22, 49, 176, 46, 108, 12, 48, 130, 12, 196, 0, 3, 54, 16, 155, 23, 6, 101, 176, 97, 9, +172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 130, 12, 62, 12, 224, 50, 101, 245, 5, 245, 54, 151, 70, 151, 246, 230, 54, 65, 56, 152, 13, 139, 24, 168, 193, 181, 6, 89, 71, 116, 98, 128, 1, 27, 136, 51, 64, 131, 52, +96, 131, 13, 131, 25, 180, 1, 192, 49, 168, 74, 42, 50, 51, 43, 27, 163, 155, 66, 11, 35, 43, 147, 227, 161, 147, 171, 43, 243, 113, 177, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 68, 111, 224, 6, 16, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, +112, 84, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 32, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 74, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 65, 83, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 240, 84, 34, 195, +115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 80, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 111, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, +242, 122, 217, 231, 178, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 0, 0, 0, 97, 32, 0, 0, 87, 0, 0, 0, 19, +4, 193, 136, 65, 2, 128, 32, 24, 32, 213, 35, 73, 141, 51, 98, 144, 0, 32, 8, 6, 136, 5, 77, 83, 243, 140, 24, 36, 0, 8, 130, 1, 114, 69, 19, 245, 64, 35, 6, 9, 0, 130, 96, 128, 96, 18, 85, 61, 209, 136, 65, 2, 128, 32, 24, 32, 217, 84, 89, 143, 52, 98, 144, 0, +32, 8, 6, 136, 70, 89, 215, 51, 141, 24, 36, 0, 8, 130, 1, 178, 85, 15, 54, 81, 35, 6, 9, 0, 130, 96, 128, 112, 22, 148, 77, 213, 136, 65, 2, 128, 32, 24, 32, 221, 21, 105, 147, 53, 98, 144, 0, 32, 8, 6, 136, 135, 73, 219, 116, 141, 24, 36, 0, 8, 130, 1, 242, 101, +18, 119, 97, 86, 72, 18, 176, 98, 146, 128, 21, 148, 4, 108, 160, 32, 96, 67, 5, 1, 27, 44, 8, 216, 50, 72, 192, 150, 65, 2, 182, 12, 18, 176, 33, 131, 128, 13, 26, 4, 108, 216, 32, 96, 209, 32, 1, 139, 6, 9, 88, 52, 72, 96, 196, 32, 1, 64, 16, 12, 18, 55, 240, 196, +128, 13, 206, 0, 27, 49, 72, 0, 16, 4, 131, 196, 13, 60, 49, 96, 3, 51, 184, 70, 12, 18, 0, 4, 193, 32, 113, 3, 79, 12, 216, 160, 12, 172, 17, 131, 4, 0, 65, 48, 72, 220, 192, 19, 3, 54, 32, 131, 106, 196, 32, 1, 64, 16, 12, 18, 55, 240, 216, 128, 13, 206, 64, 27, +49, 72, 0, 16, 4, 131, 196, 13, 60, 54, 96, 3, 51, 200, 70, 12, 18, 0, 4, 193, 32, 113, 3, 111, 13, 216, 224, 12, 134, 17, 131, 4, 0, 65, 48, 72, 220, 192, 91, 3, 54, 48, 3, 97, 196, 32, 1, 64, 16, 12, 18, 55, 240, 214, 128, 13, 202, 32, 24, 49, 72, 0, 16, 4, +131, 196, 13, 188, 53, 96, 3, 50, 136, 70, 12, 18, 0, 4, 193, 32, 113, 3, 111, 12, 216, 224, 12, 32, 4, 0, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index 50e03e74e4..089ea0062b 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -1,63 +1,69 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SignedDistanceFieldFontShader] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { internal partial class SignedDistanceFieldFontShader { private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, -73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, -100, 101, 114, 1, 42, 59, 59, 143, 216, 91, 194, 71, 107, 170, 157, 209, 113, 123, 223, 11, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, 110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 9, 84, 101, 120, 116, -117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, 180, 232, 16, 46, 222, 107, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 91, 230, 250, 131, 2, 86, 142, 103, 210, 136, 121, 250, 235, 91, 222, 6, 0, 140, 99, 0, 0, 68, 88, 66, 67, 235, 155, 72, 142, 190, 31, -234, 28, 240, 181, 229, 167, 120, 130, 77, 56, 1, 0, 0, 0, 140, 99, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 60, 3, 0, 0, 216, 3, 0, 0, 224, 97, 0, 0, 92, 98, 0, 0, 168, 98, 0, 0, 24, 99, 0, 0, 65, 111, 110, 57, 248, 2, 0, 0, 248, 2, 0, 0, 0, 2, -254, 255, 208, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 154, 0, 68, 66, 85, 71, 40, 0, 0, 0, 60, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 196, 0, -0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 2, 0, 0, 0, 20, 2, 0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, -115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, -100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 40, 0, 0, 0, 0, 0, 255, 255, 112, 2, 0, 0, 0, 0, -255, 255, 124, 2, 0, 0, 0, 0, 255, 255, 136, 2, 0, 0, 169, 0, 0, 0, 148, 2, 0, 0, 169, 0, 0, 0, 168, 2, 0, 0, 173, 0, 0, 0, 180, 2, 0, 0, 174, 0, 0, 0, 192, 2, 0, 0, 86, 83, 77, 97, 105, 110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, -105, 100, 55, 51, 0, 171, 7, 1, 0, 0, 28, 1, 0, 0, 44, 1, 0, 0, 60, 1, 0, 0, 76, 1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 88, 1, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, -255, 255, 2, 0, 3, 0, 5, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 6, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 186, 1, 0, 0, 28, 1, 0, 0, 44, 1, -0, 0, 60, 1, 0, 0, 76, 1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 200, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 1, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, -9, 0, 0, 0, 0, 0, 0, 1, 0, 0, 112, 1, 0, 0, 4, 0, 0, 0, 128, 1, 0, 0, 0, 1, 0, 0, 176, 1, 0, 0, 224, 1, 0, 0, 3, 0, 0, 0, 240, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, -100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, -255, 144, 0, 0, 228, 160, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 1, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, -0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, -0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, -0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 94, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 47, 0, -0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, +0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, +115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, +145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, +0, 0, 0, 1, 125, 88, 83, 2, 94, 238, 0, 19, 148, 66, 98, 180, 14, 94, 118, 244, 0, 176, 95, 0, 0, 68, 88, 66, 67, 234, 61, 7, 31, 101, 34, 14, 190, 178, 159, 132, 236, 216, 125, 176, 95, 1, 0, 0, 0, 176, 95, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, +0, 248, 7, 0, 0, 0, 94, 0, 0, 124, 94, 0, 0, 48, 95, 0, 0, 124, 95, 0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, +0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, 85, 71, 40, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, +115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, +114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, +0, 107, 0, 0, 0, 252, 3, 0, 0, 77, 0, 0, 0, 12, 4, 0, 0, 77, 0, 0, 0, 28, 4, 0, 0, 77, 0, 0, 0, 48, 4, 0, 0, 77, 0, 0, 0, 64, 4, 0, 0, 89, 0, 0, 0, 80, 4, 0, 0, 90, 0, 0, 0, 96, 4, 0, 0, 90, 0, 0, 0, 108, 4, 0, +0, 90, 0, 0, 0, 120, 4, 0, 0, 90, 0, 0, 0, 132, 4, 0, 0, 91, 0, 0, 0, 148, 4, 0, 0, 91, 0, 0, 0, 168, 4, 0, 0, 91, 0, 0, 0, 184, 4, 0, 0, 91, 0, 0, 0, 196, 4, 0, 0, 91, 0, 0, 0, 212, 4, 0, 0, 91, 0, 0, 0, 232, 4, 0, +0, 91, 0, 0, 0, 248, 4, 0, 0, 92, 0, 0, 0, 8, 5, 0, 0, 101, 0, 0, 0, 24, 5, 0, 0, 101, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, +171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, +0, 0, 0, 0, 0, 145, 1, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 180, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, +0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, +101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, +0, 0, 0, 1, 0, 2, 0, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +0, 132, 2, 0, 0, 148, 2, 0, 0, 164, 2, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 176, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, +0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 8, 2, 0, 0, 42, 2, 0, 0, 164, 1, 0, +0, 1, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 108, 2, 0, 0, 140, 1, 0, 0, 120, 2, 0, 0, 192, 2, 0, 0, 2, 0, 0, +0, 208, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, +63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, +160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, +128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, +2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, +2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, +3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, +82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, +0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, +0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, +5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, +0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, +0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, +0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, +0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -65,7 +71,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -73,327 +79,279 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 201, 144, 255, 52, 225, 214, 242, 71, 168, 224, 31, 151, 213, 50, 202, 193, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, -32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, -116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, -80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 198, 90, 0, 0, 117, 131, 1, 0, 124, 40, 0, 0, 156, 202, 1, 0, 38, 247, 2, 0, 178, 79, 1, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, -10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, -123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, -97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, -59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, -50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, -114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, -97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, -78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, -32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, -114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, -101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, -76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, -95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, -40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, -120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, -116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, -32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, -97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, -104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, -32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, -116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, -48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, -105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, -115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, -110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, -100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, -79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, -112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, -111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, -44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, -108, 111, 114, 95, 105, 100, 51, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, -114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, -32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, -61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, -111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, -10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, -10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 254, 21, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, -83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, -100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 0, -99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, -100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, -57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, -103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 27, 226, 48, 1, 128, 0, 0, 0, 195, 21, 147, 25, 57, 45, 214, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 140, 39, 197, 54, 195, 20, 0, 0, 1, 0, -0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, -41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, -115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 8, 16, -0, 0, 84, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, -4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, -64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, -60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, -4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, -64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, -4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 12, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 190, 216, 5, 31, 174, 95, 163, 28, -119, 180, 114, 162, 34, 3, 190, 178, 0, 0, 242, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 180, 0, 0, 128, 84, 0, 0, 0, 180, 0, 0, 0, 104, 0, 0, 0, 180, 0, -0, 128, 104, 0, 0, 0, 180, 0, 0, 0, 124, 0, 0, 0, 180, 0, 0, 128, 124, 0, 0, 0, 180, 0, 0, 0, 144, 0, 0, 0, 180, 0, 0, 128, 144, 0, 0, 0, 180, 0, 0, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, -22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 56, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, -0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 74, 0, -3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, -114, 95, 105, 100, 55, 51, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, -0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, -114, 95, 105, 100, 55, 51, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, -1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, -114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, -50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, -77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, -116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, -114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, -109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, -77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, -109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, -105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, -59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, -78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, -71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, -95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, -97, 110, 95, 105, 100, 50, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, -109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, -44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, -123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, -111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, -105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, -115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, -105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, -32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, -104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, -114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, -105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, -32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, -108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, -109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, -109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, -111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, -111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, -123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, -117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, -97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, -116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, -117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, -114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, -51, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 6, 110, 186, 185, 67, 77, 136, 76, 150, 95, 43, 175, 255, 79, 135, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, +117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, +99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, +0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 20, 41, 3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 113, 232, 0, 0, 118, 213, 0, 0, 118, 199, 0, 0, 101, 128, 0, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, +71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, +58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, +40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, +95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, +120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, +101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, +116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, +115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, +101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, +114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, +101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, +108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, +101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, +50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, +105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, +100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 51, 44, 32, 95, 49, 52, 54, 44, 32, 95, 49, 53, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, +32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, +103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, +116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, +32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, +32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, +111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, +32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, +43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, +44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, +101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, +102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, +111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, +77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 48, 32, 61, 32, 115, +105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 95, 50, 57, 54, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 57, 56, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 48, 44, 32, 95, 50, 57, 50, 44, 32, 95, 50, 57, 54, 44, 32, 95, 50, +57, 56, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, +105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, +70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, +95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, +116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 15, 16, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, +110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, +56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, +111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 55, 57, 100, 57, 56, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, +84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 197, 91, 71, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 49, 91, 79, 162, 84, 15, 0, +0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, +32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, +115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 216, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, +0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, +0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, +0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, +17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 212, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, +5, 13, 43, 11, 96, 4, 129, 248, 8, 0, 13, 42, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 208, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 68, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 67, 1, 80, 12, 129, 248, 0, 0, 54, 0, 77, +17, 60, 2, 0, 0, 204, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 98, 11, 32, 13, 76, 6, 14, 12, 129, 212, 36, 8, 0, 9, 34, 13, 97, 1, 80, 6, 15, 3, 0, 9, 19, 13, 75, 6, 14, 12, 129, 212, 36, 0, 0, 58, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, +105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, +0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 8, 0, 0, 0, 110, 0, 77, 17, 100, 2, 0, +0, 200, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, +21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, +116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, +0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, +0, 16, 1, 157, 6, 247, 135, 167, 84, 62, 45, 200, 204, 20, 87, 58, 78, 147, 156, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 135, 0, 0, 128, 80, 0, 0, +0, 135, 0, 0, 0, 116, 0, 0, 0, 135, 0, 0, 128, 116, 0, 0, 0, 135, 0, 0, 0, 144, 0, 0, 0, 135, 0, 0, 128, 144, 0, 0, 0, 135, 0, 0, 0, 172, 0, 0, 0, 135, 0, 0, 128, 172, 0, 0, 0, 135, 0, 0, 0, 200, 0, 0, 0, 135, 0, 0, 128, 200, 0, 0, +0, 135, 0, 0, 0, 228, 0, 0, 0, 135, 0, 0, 128, 228, 0, 0, 0, 135, 0, 0, 0, 248, 0, 0, 0, 135, 0, 0, 128, 248, 0, 0, 0, 135, 0, 0, 0, 12, 1, 0, 0, 135, 0, 0, 128, 12, 1, 0, 0, 135, 0, 0, 0, 48, 1, 0, 0, 135, 0, 0, 128, 48, 1, 0, +0, 135, 0, 0, 0, 84, 1, 0, 0, 135, 0, 0, 128, 84, 1, 0, 0, 135, 0, 0, 0, 112, 1, 0, 0, 135, 0, 0, 128, 112, 1, 0, 0, 135, 0, 0, 0, 152, 1, 0, 0, 135, 0, 0, 128, 152, 1, 0, 0, 135, 0, 0, 0, 180, 1, 0, 0, 135, 0, 0, 128, 180, 1, 0, +0, 135, 0, 0, 0, 216, 1, 0, 0, 135, 0, 0, 128, 216, 1, 0, 0, 135, 0, 0, 0, 244, 1, 0, 0, 135, 0, 0, 128, 244, 1, 0, 0, 135, 0, 0, 0, 16, 2, 0, 0, 135, 0, 0, 128, 16, 2, 0, 0, 135, 0, 0, 0, 44, 2, 0, 0, 135, 0, 0, 128, 44, 2, 0, +0, 135, 0, 0, 0, 72, 2, 0, 0, 138, 0, 0, 128, 72, 2, 0, 0, 138, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, +0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, +0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 1, 16, 0, +0, 0, 0, 0, 0, 119, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, +21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 248, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, +0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, +241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, +0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, +21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, +0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, +0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, +0, 3, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, +108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, +115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, +116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, +105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, +116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, +97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, +116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, +32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, +57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, +115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, +114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, +32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 51, 44, 32, 95, 49, 52, 54, 44, 32, 95, 49, 53, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, +68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, +100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, +109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, +105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, +97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, +103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, +76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, +100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, +111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, +108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, +114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, +10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, +114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, +57, 48, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 54, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 57, 56, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 48, 44, 32, 95, 50, 57, 50, 44, 32, 95, 50, +57, 54, 44, 32, 95, 50, 57, 56, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, +32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, +94, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, +0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, +241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, +96, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, +241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 201, 144, 255, 52, 225, 214, 242, 71, 168, 224, 31, 151, 213, 50, 202, 193, 201, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, -47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, -115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 105, 103, 110, 101, -100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 4, -0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, +255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 168, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 3, 0, 0, 0, 0, -0, 0, 172, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, -110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, -102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 37, 1, 0, 0, 112, 1, 0, 0, 175, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 46, 22, 0, 0, 128, 0, 0, 0, 195, 20, 0, 0, 200, 3, -0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 24, 0, 0, 0, 3, 0, 0, 0, 40, 0, 0, 0, 23, 0, 0, 0, 41, 0, 0, 0, 24, 0, 0, 0, 19, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, -0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, -0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -401,15 +359,31 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, +0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 6, 110, 186, 185, 67, 77, 136, 76, 150, 95, 43, 175, 255, 79, 135, 4, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, +102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, +110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 55, 57, 100, 57, 56, +56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 48, 2, 0, 0, 111, 1, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 63, 16, 0, 0, 128, 0, 0, 0, 84, 15, 0, +0, 36, 7, 0, 0, 108, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 38, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, +0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, +0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -425,55 +399,37 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, -40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 15, 15, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, -69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 108, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 12, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, -0, 171, 0, 5, 0, 0, 0, 1, 224, 146, 157, 113, 139, 33, 158, 204, 73, 128, 26, 26, 152, 124, 215, 1, 0, 252, 111, 0, 0, 68, 88, 66, 67, 26, 32, 207, 129, 175, 157, 19, 81, 5, 117, 2, 65, 219, 255, 205, 159, 1, 0, 0, 0, 252, 111, 0, 0, 7, 0, 0, 0, 60, 0, 0, -0, 212, 5, 0, 0, 40, 8, 0, 0, 48, 110, 0, 0, 172, 110, 0, 0, 84, 111, 0, 0, 200, 111, 0, 0, 65, 111, 110, 57, 144, 5, 0, 0, 144, 5, 0, 0, 0, 2, 255, 255, 104, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, -0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 244, 0, 68, 66, 85, 71, 40, 0, 0, 0, 164, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 196, 0, 0, 0, 25, 0, 0, 0, 200, 0, 0, 0, 7, 0, 0, 0, 24, 3, 0, 0, 144, 1, 0, 0, 67, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, -117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, -102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 40, 0, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, 0, 0, 0, 0, 255, -255, 32, 4, 0, 0, 154, 0, 0, 0, 44, 4, 0, 0, 129, 0, 0, 0, 60, 4, 0, 0, 129, 0, 0, 0, 76, 4, 0, 0, 129, 0, 0, 0, 96, 4, 0, 0, 129, 0, 0, 0, 112, 4, 0, 0, 137, 0, 0, 0, 128, 4, 0, 0, 138, 0, 0, 0, 144, 4, 0, 0, 138, 0, 0, -0, 156, 4, 0, 0, 138, 0, 0, 0, 168, 4, 0, 0, 138, 0, 0, 0, 180, 4, 0, 0, 139, 0, 0, 0, 196, 4, 0, 0, 139, 0, 0, 0, 216, 4, 0, 0, 139, 0, 0, 0, 232, 4, 0, 0, 139, 0, 0, 0, 244, 4, 0, 0, 139, 0, 0, 0, 4, 5, 0, 0, 139, 0, 0, -0, 24, 5, 0, 0, 139, 0, 0, 0, 40, 5, 0, 0, 140, 0, 0, 0, 56, 5, 0, 0, 149, 0, 0, 0, 72, 5, 0, 0, 149, 0, 0, 0, 88, 5, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, 3, -0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 151, 1, 0, 0, 168, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 184, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 171, 230, 1, 0, 0, 168, 1, 0, -0, 250, 1, 0, 0, 8, 2, 0, 0, 24, 2, 0, 0, 168, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 36, 2, 0, 0, 2, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 109, 101, 100, 105, 97, 110, 95, -105, 100, 50, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, -255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, -0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 0, 0, 0, 0, 144, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 208, 1, 0, -0, 144, 1, 0, 0, 220, 1, 0, 0, 60, 2, 0, 0, 2, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 100, 2, 0, 0, 112, 2, 0, 0, 1, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 140, 2, 0, 0, 148, 2, 0, 0, 2, 0, 0, 0, 164, 2, 0, 0, 188, 2, 0, -0, 202, 2, 0, 0, 168, 1, 0, 0, 1, 0, 0, 0, 216, 2, 0, 0, 0, 0, 0, 0, 228, 2, 0, 0, 148, 2, 0, 0, 1, 0, 0, 0, 236, 2, 0, 0, 0, 0, 0, 0, 248, 2, 0, 0, 168, 1, 0, 0, 1, 0, 0, 0, 12, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, -102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, -160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, -176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, -128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, -3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, -3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, -128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, -0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, -0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, -0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, -0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, -0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, -0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, -63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, -0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, -0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, -0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 102, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, -0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, +32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, +84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 123, 111, 206, 225, 51, 58, 230, 97, 249, 76, 255, 62, 18, 93, 50, 252, 0, 100, 75, 0, 0, 68, 88, 66, 67, 56, 98, 251, 155, 244, 209, 89, 251, 28, 236, 68, 226, 166, 43, 88, 150, 1, 0, 0, 0, 100, 75, 0, +0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 73, 0, 0, 56, 74, 0, 0, 132, 74, 0, 0, 244, 74, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, +0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, +0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, +101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 95, 0, 0, +0, 112, 2, 0, 0, 97, 0, 0, 0, 132, 2, 0, 0, 99, 0, 0, 0, 144, 2, 0, 0, 95, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, +0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, +0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, +0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, +171, 120, 1, 0, 0, 216, 0, 0, 0, 135, 1, 0, 0, 248, 0, 0, 0, 150, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, +0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 0, 0, 0, 0, 192, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 1, 0, 0, 192, 0, 0, 0, 108, 1, 0, 0, 188, 1, 0, 0, 3, 0, 0, 0, 204, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, +82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, +144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, +82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, +3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, +0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, +0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -481,7 +437,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -489,327 +445,178 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 107, 188, 61, 33, 59, 10, 94, 66, 176, 171, 178, 210, 106, 247, 64, 6, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, +117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, +107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, +101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, +0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 190, 123, 189, 255, 234, 34, 251, 71, 176, 83, 153, 89, 116, 5, 26, 134, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, -105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, -59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 198, 90, 0, 0, 117, 131, 1, 0, 178, 79, 1, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 31, 219, 2, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, -0, 116, 39, 1, 0, 13, 58, 1, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 31, 72, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 110, 4, 0, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, -83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, -99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, -79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, -101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, -49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, -100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, -95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, -117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, -117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, -117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, -101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, -48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, -10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, -73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, -117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, -80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, -105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, -13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, -97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, -97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, -101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 102, 108, 111, 97, 116, 32, 114, 44, -32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, -98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, -108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, -105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, -103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, -111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, -120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, -10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, -100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, -32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, -111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, -40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, -111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, -101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, -41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 115, -105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, -110, 101, 115, 115, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, -95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, -59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, -85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, -84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, -82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, -85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 254, 21, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, -114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, -52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, -102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, -54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, -13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 27, 226, 48, 1, 128, 0, 0, 0, 159, 104, 151, 25, 57, 45, 214, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 158, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 140, 39, 197, 54, 195, 20, 0, 0, 1, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, -97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, -101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 212, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, -80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, -1, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, -0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 36, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 32, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 44, 0, 0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, -101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, -1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, -0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 50, 0, 77, 17, 140, 0, 0, 0, 208, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 91, 11, 32, 13, 96, 6, 6, 12, 129, 212, 36, 8, 0, 9, 34, 13, 90, 1, 80, 11, 112, 9, 12, 13, 95, 6, 6, 12, 129, 212, -36, 58, 0, 62, 17, 0, 16, 0, 0, 8, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, -17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, -0, 8, 0, 0, 0, 110, 0, 77, 17, 128, 2, 0, 0, 204, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 86, 6, 8, 3, 36, 13, 50, 6, 2, 3, 84, 13, 46, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 64, 6, 18, 12, 28, 28, 8, -0, 9, 28, 13, 85, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 63, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, -105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, -17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, -0, 0, 0, 0, 0, 50, 0, 77, 17, 56, 3, 0, 0, 200, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 66, 0, 62, 17, 17, 16, 0, -0, 128, 0, 60, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, -17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 190, 216, 5, 31, 174, 95, 163, 28, 119, 180, 114, 162, 34, -3, 190, 178, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 164, 0, 0, 128, 80, 0, 0, 0, 164, 0, 0, 0, 116, 0, 0, 0, 164, 0, 0, 128, 116, 0, 0, -0, 164, 0, 0, 0, 144, 0, 0, 0, 164, 0, 0, 128, 144, 0, 0, 0, 164, 0, 0, 0, 172, 0, 0, 0, 164, 0, 0, 128, 172, 0, 0, 0, 164, 0, 0, 0, 200, 0, 0, 0, 164, 0, 0, 128, 200, 0, 0, 0, 164, 0, 0, 0, 228, 0, 0, 0, 164, 0, 0, 128, 228, 0, 0, -0, 164, 0, 0, 0, 248, 0, 0, 0, 164, 0, 0, 128, 248, 0, 0, 0, 164, 0, 0, 0, 12, 1, 0, 0, 164, 0, 0, 128, 12, 1, 0, 0, 164, 0, 0, 0, 48, 1, 0, 0, 164, 0, 0, 128, 48, 1, 0, 0, 164, 0, 0, 0, 84, 1, 0, 0, 164, 0, 0, 128, 84, 1, 0, -0, 164, 0, 0, 0, 112, 1, 0, 0, 164, 0, 0, 128, 112, 1, 0, 0, 164, 0, 0, 0, 152, 1, 0, 0, 164, 0, 0, 128, 152, 1, 0, 0, 164, 0, 0, 0, 180, 1, 0, 0, 164, 0, 0, 128, 180, 1, 0, 0, 164, 0, 0, 0, 216, 1, 0, 0, 164, 0, 0, 128, 216, 1, 0, -0, 164, 0, 0, 0, 244, 1, 0, 0, 164, 0, 0, 128, 244, 1, 0, 0, 164, 0, 0, 0, 16, 2, 0, 0, 164, 0, 0, 128, 16, 2, 0, 0, 164, 0, 0, 0, 44, 2, 0, 0, 164, 0, 0, 128, 44, 2, 0, 0, 164, 0, 0, 0, 72, 2, 0, 0, 167, 0, 0, 128, 72, 2, 0, -0, 167, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, -0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, -0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, -0, 128, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, -0, 16, 16, 0, 0, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 224, 51, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 224, 51, 0, 0, 242, 241, 10, 0, 24, -21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 80, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, -0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, -0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, 114, -95, 105, 100, 55, 51, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, -0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, -0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 8, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, -51, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 3, 0, 0, 0, 9, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, -0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 136, 48, 2, 0, 20, 156, 2, 0, 51, 184, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, -101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, -122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, -101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, -101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, -84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, -68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, -79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, -95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, -10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, -76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, -82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, -67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, -95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, -105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, -95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, -69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, -87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, -53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 102, 108, -111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, -44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, -116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, -114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, -110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, -107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, -109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, -99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, -53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, -105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, -42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, -59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, -32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, -99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, -111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, -61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, -108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, -50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, -44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, -95, 105, 100, 51, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, -114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, -95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, -114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, -32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, -95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, -40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, -100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, -32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 59, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 157, 0, 0, 0, 158, 0, 0, 0, 58, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, +79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, +99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, +120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, +99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, +99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, +10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, +101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, +97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, +41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 43, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, +52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, +57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 48, 98, 55, 48, 50, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 212, 5, 75, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, +1, 191, 137, 74, 219, 112, 9, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 76, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, -0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 26, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 0, 242, 241, 22, 0, 1, 22, 0, 0, 0, -0, 18, 16, 0, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, +105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, +84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, +0, 64, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, +0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, +0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, +0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, +0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, +0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, +17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, +0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, +0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 133, 63, 204, 184, 201, 98, 73, 178, 223, +206, 130, 141, 56, 171, 235, 204, 0, 0, 242, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 105, 0, 0, 128, 84, 0, 0, 0, 105, 0, 0, 0, 104, 0, 0, 0, 105, 0, 0, +128, 104, 0, 0, 0, 105, 0, 0, 0, 124, 0, 0, 0, 105, 0, 0, 128, 124, 0, 0, 0, 105, 0, 0, 0, 144, 0, 0, 0, 105, 0, 0, 128, 144, 0, 0, 0, 105, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, +0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 80, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, +0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, +108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, +110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, +110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, +83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, -0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 0, 26, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 0, 242, 241, 22, 0, 1, 22, 0, 0, 0, -0, 18, 16, 0, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, +41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, +84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, +112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, +116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, +77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, +118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, +105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, +86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, +95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, +108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, -0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 34, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -817,48 +624,52 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 190, 123, 189, 255, 234, 34, 251, 71, 176, 83, 153, 89, 116, 5, 26, 134, 201, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, -114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, -114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, -102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, 51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, -0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, -0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 216, 4, 0, 0, 0, 0, 0, 0, 32, 2, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, -0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, -111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, -103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 56, 53, 51, 56, 49, 48, 102, 52, 54, 100, 57, 49, 98, 102, 57, 53, 102, 48, 53, 102, 100, 55, 49, 50, 98, -51, 54, 97, 54, 55, 98, 57, 46, 104, 108, 115, 108, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 37, 1, 0, 0, 136, 2, 0, 0, 175, 1, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 46, 22, 0, 0, 128, 0, 0, 0, 195, 20, 0, 0, 8, 7, 0, 0, 108, 0, 0, 0, 20, 0, 0, -0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 45, 0, 0, 0, 38, 0, 0, 0, 19, 0, 0, 0, 6, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, -0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, -0, 17, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 39, 0, 0, 0, 40, 0, 0, 0, 41, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, +0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 2, 0, 9, 0, 8, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, +96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, +0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, +101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 107, 188, 61, 33, 59, 10, 94, 66, 176, 171, 178, 210, 106, 247, 64, 6, 137, 0, 0, +0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, +52, 50, 97, 48, 98, 55, 48, 50, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, +0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 136, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 91, 10, 0, +0, 128, 0, 0, 0, 112, 9, 0, 0, 188, 3, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 18, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, +0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, +0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -873,15 +684,33 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 119, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, -101, 48, 95, 105, 100, 49, 52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 108, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, -0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -0, 2, 0, 0, 0, 15, 15, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, +0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, +0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, +105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs new file mode 100644 index 0000000000..4311a428cf --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -0,0 +1,116 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [SignedDistanceFieldFontShader] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + internal partial class SignedDistanceFieldFontShader + { + private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, +70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, +57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 155, 120, 66, 107, 24, 37, 183, 215, 254, 65, 187, 5, 119, 92, 146, 66, 0, 180, 9, +0, 0, 68, 88, 66, 67, 231, 29, 8, 161, 222, 96, 65, 162, 167, 250, 97, 230, 191, 32, 140, 110, 1, 0, 0, 0, 180, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 192, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 216, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, +0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 68, 88, 73, 76, 236, 7, 0, 0, 96, 0, 0, 0, 251, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 212, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 242, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, +4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, +24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, +96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 99, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 5, 0, 0, 0, 192, +29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, +57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, +0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, +0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 66, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 1, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 160, 24, 11, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 48, 16, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, +160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, +7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, +7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, +200, 99, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 46, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, +128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 43, 164, 50, 34, 0, 0, 0, 128, 49, 130, +214, 156, 115, 246, 23, 136, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 8, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 34, 0, 0, 0, 40, 7, 2, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 8, 0, 0, 0, 74, +129, 26, 0, 0, 0, 74, 162, 16, 10, 4, 0, 0, 0, 0, 121, 24, 0, 0, 120, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 144, 9, 194, 112, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 201, 4, 129, 80, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 99, 97, 68, +85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 12, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 209, 76, 16, 20, 103, 130, 64, 60, 27, 132, 192, 217, 144, 4, 202, +18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 1, 109, 16, 8, 138, 2, 220, +220, 4, 129, 232, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 166, 12, 38, 8, 141, 180, 33, 8, 38, 8, 13, 181, 97, 9, 196, +96, 12, 200, 160, 12, 204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 204, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 132, 51, 80, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 230, 12, 54, 44, 1, 27, 140, 65, 27, 148, 1, 25, 16, +105, 16, 144, 1, 176, 33, 112, 131, 13, 195, 26, 188, 1, 64, 54, 152, 74, 59, 115, 43, 35, 35, 74, 155, 163, 11, 115, 27, 43, 51, 74, 43, 99, 35, 51, 122, 115, 163, 155, 66, 11, 35, 43, 147, 115, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 113, 0, +7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, +69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 65, 28, 0, 113, 32, 0, 0, 33, 0, 0, 0, 6, 192, +6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 159, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 210, 112, 249, 206, 227, 11, 17, 1, 76, 68, 8, 52, +195, 66, 216, 0, 52, 92, 190, 243, 248, 18, 192, 60, 11, 225, 23, 183, 109, 4, 208, 112, 249, 206, 227, 7, 72, 3, 68, 152, 95, 220, 182, 21, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 155, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, +0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 103, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 104, 144, 133, 65, 24, 88, 216, 136, 65, 2, 128, 32, 24, 56, 105, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 106, 176, +137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 107, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 108, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 68, 108, 128, 101, 102, 96, 6, 96, 48, 98, 144, 0, 32, 8, 6, 81, 27, 100, 221, 25, 156, 65, 24, 140, 24, +60, 0, 8, 130, 193, 212, 6, 88, 32, 32, 71, 150, 125, 223, 151, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 140, 24, 28, 0, 8, 130, 1, 21, 7, 28, 49, 140, 24, 28, 0, 8, 130, 1, 37, 7, 92, 65, 140, 24, 28, 0, 8, 130, 1, 53, 7, 94, 64, 140, 24, +28, 0, 8, 130, 1, 69, 7, 222, 16, 88, 224, 65, 96, 196, 192, 0, 64, 16, 12, 170, 58, 240, 130, 17, 3, 3, 0, 65, 48, 168, 236, 192, 11, 70, 12, 12, 0, 4, 193, 160, 186, 3, 111, 24, 49, 48, 0, 16, 4, 131, 10, 15, 192, 32, 176, 96, 128, 128, 5, 96, 32, 1, 19, 62, +9, 24, 34, 64, 192, 2, 129, 2, 35, 6, 6, 0, 130, 96, 80, 249, 65, 24, 4, 22, 6, 129, 4, 44, 40, 3, 8, 216, 16, 72, 192, 136, 64, 2, 22, 4, 18, 176, 47, 144, 128, 125, 130, 4, 236, 27, 36, 96, 31, 33, 129, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, +246, 128, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 65, 15, 134, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 242, 64, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 1, 15, 2, 4, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 88, 60, 223, +63, 124, 199, 114, 208, 220, 100, 142, 71, 141, 94, 33, 63, 0, 201, 7, 0, 0, 68, 88, 66, 67, 232, 45, 32, 27, 33, 167, 79, 198, 224, 161, 134, 23, 150, 228, 74, 190, 1, 0, 0, 0, 201, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, +0, 0, 125, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, +0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 24, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, +0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 68, 5, 0, 0, 96, 0, 1, 0, 81, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 44, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 72, 1, 0, 0, 11, 130, 32, 0, 2, +0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, +33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, +130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, +4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, +0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, +14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, +122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, +0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 16, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, +0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 133, 98, 160, 3, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 107, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, +54, 32, 129, 48, 4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, +133, 130, 221, 220, 4, 129, 120, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 3, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, +45, 192, 128, 13, 1, 49, 65, 56, 162, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 13, 195, 230, 133, 193, 134, 37, 176, 46, 44, 211, 8, 45, 192, 128, 13, 11, 97, 93, 24, 167, 17, 29, 129, 1, 92, 166, 172, +190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 7, 179, 97, 249, 202, 224, 50, 131, 172, 35, 186, 15, 3, 54, 12, 99, 64, 6, 103, 176, 97, 16, 3, 52, 0, 200, 6, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, +100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 72, 13, 210, 0, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 142, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 164, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, +64, 169, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 104, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 158, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 2, 170, 14, 25, 158, 75, 153, 27, 157, +92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 13, 0, 0, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 255, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, +60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 97, 32, 0, 0, 60, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 209, 226, 56, 137, 50, 98, 144, 0, 32, 8, 6, 136, 196, 60, 79, +178, 140, 24, 36, 0, 8, 130, 1, 50, 53, 15, 180, 48, 35, 6, 9, 0, 130, 96, 128, 80, 14, 20, 45, 205, 136, 65, 2, 128, 32, 24, 32, 213, 19, 73, 139, 51, 98, 144, 0, 32, 8, 6, 136, 5, 73, 211, 242, 140, 24, 36, 0, 8, 130, 1, 114, 69, 11, 245, 64, 35, 6, 9, 0, +130, 96, 128, 96, 18, 83, 61, 209, 136, 65, 2, 128, 32, 24, 32, 217, 212, 88, 143, 52, 98, 144, 0, 32, 8, 6, 136, 70, 57, 215, 51, 141, 24, 36, 0, 8, 130, 65, 162, 57, 15, 54, 33, 35, 6, 9, 0, 130, 96, 144, 104, 206, 131, 73, 199, 136, 65, 2, 128, 32, 24, 36, 154, 243, +96, 145, 49, 98, 144, 0, 32, 8, 6, 137, 230, 60, 24, 84, 140, 24, 36, 0, 8, 130, 65, 162, 57, 24, 54, 41, 35, 6, 9, 0, 130, 96, 144, 104, 14, 134, 73, 201, 136, 65, 2, 128, 32, 24, 36, 154, 115, 97, 19, 49, 98, 144, 0, 32, 8, 6, 137, 230, 92, 152, 52, 140, 24, 36, +0, 8, 130, 65, 162, 57, 23, 22, 9, 35, 6, 9, 0, 130, 96, 144, 104, 206, 133, 65, 1, 2, 0, 0, 0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 666965306e..9e788c21cf 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -1,166 +1,307 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SignedDistanceFieldFontShader] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { internal partial class SignedDistanceFieldFontShader { private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 42, 59, 59, 143, 216, 91, 194, 71, 107, 170, 157, 209, 113, 123, 223, 11, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, 110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, -101, 83, 116, 114, 101, 97, 109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, -42, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, 180, 232, 16, 46, 222, 107, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 63, 133, 151, 47, 3, 65, 90, 2, 168, 95, 98, 69, 79, 229, 207, 223, 0, 57, 10, 0, 0, 0, 3, 0, 0, -0, 0, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 40, 0, 0, 0, 0, 244, 9, 0, -0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 82, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, -0, 15, 0, 11, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 15, 0, 0, 0, 21, 0, 0, 0, 26, 0, 0, 0, 62, 0, 0, 0, 68, 0, 0, 0, 71, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, -0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, -0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 0, 5, 0, 5, 0, 11, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, -0, 5, 0, 5, 0, 15, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 21, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 26, 0, 0, 0, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 0, 5, 0, 5, -0, 29, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 29, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 29, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 29, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 0, 6, 0, 8, 0, 29, 0, 0, 0, 3, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, -0, 5, 0, 4, 0, 31, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 5, 0, 45, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 45, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 0, 6, 0, 7, 0, 45, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 45, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 0, 5, 0, 5, 0, 47, 0, 0, -0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 60, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 60, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 7, -0, 60, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 60, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, 101, 0, 6, 0, 7, 0, 60, 0, 0, 0, 3, 0, 0, -0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 62, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 68, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 71, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, -48, 0, 0, 0, 0, 5, 0, 5, 0, 81, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 15, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 21, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 26, 0, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 60, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 60, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 60, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, -0, 3, 0, 0, 0, 72, 0, 5, 0, 60, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 60, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 68, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 71, 0, 0, 0, 30, 0, 0, -0, 1, 0, 0, 0, 71, 0, 4, 0, 81, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 81, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, -0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 5, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, -0, 7, 0, 0, 0, 9, 0, 0, 0, 21, 0, 4, 0, 12, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 14, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 14, 0, 0, -0, 15, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 19, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 20, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 20, 0, 0, -0, 21, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 14, 0, 0, 0, 26, 0, 0, 0, 1, 0, 0, 0, 30, 0, 6, 0, 29, 0, 0, -0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 30, 0, 0, 0, 7, 0, 0, 0, 29, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 41, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 45, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, -0, 7, 0, 0, 0, 32, 0, 4, 0, 46, 0, 0, 0, 7, 0, 0, 0, 45, 0, 0, 0, 21, 0, 4, 0, 57, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 57, 0, 0, 0, 58, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, 0, 59, 0, 0, 0, 6, 0, 0, -0, 58, 0, 0, 0, 30, 0, 6, 0, 60, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 59, 0, 0, 0, 59, 0, 0, 0, 32, 0, 4, 0, 61, 0, 0, 0, 3, 0, 0, 0, 60, 0, 0, 0, 59, 0, 4, 0, 61, 0, 0, 0, 62, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, -0, 65, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 67, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 67, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 65, 0, 0, 0, 71, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, -0, 74, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 26, 0, 2, 0, 79, 0, 0, 0, 32, 0, 4, 0, 80, 0, 0, 0, 0, 0, 0, 0, 79, 0, 0, 0, 59, 0, 4, 0, 80, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 30, 0, 0, 0, 31, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 46, 0, 0, 0, 47, 0, 0, 0, 7, 0, 0, -0, 61, 0, 4, 0, 7, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 18, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 18, 0, 0, 0, 16, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, -0, 65, 0, 5, 0, 23, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 24, 0, 0, 0, 22, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, -0, 25, 0, 0, 0, 62, 0, 3, 0, 28, 0, 0, 0, 27, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 32, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 33, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 34, 0, 0, -0, 31, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 34, 0, 0, 0, 33, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, -0, 37, 0, 0, 0, 31, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 36, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 38, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 65, 0, 5, -0, 17, 0, 0, 0, 40, 0, 0, 0, 31, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 40, 0, 0, 0, 39, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 42, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, -0, 65, 0, 5, 0, 17, 0, 0, 0, 44, 0, 0, 0, 31, 0, 0, 0, 41, 0, 0, 0, 62, 0, 3, 0, 44, 0, 0, 0, 43, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 48, 0, 0, 0, 31, 0, 0, 0, 41, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 49, 0, 0, -0, 48, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 50, 0, 0, 0, 47, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 50, 0, 0, 0, 49, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 51, 0, 0, 0, 31, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, -0, 52, 0, 0, 0, 51, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 53, 0, 0, 0, 47, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 53, 0, 0, 0, 52, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 0, 0, 0, 31, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, -0, 7, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 56, 0, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 56, 0, 0, 0, 55, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 63, 0, 0, 0, 47, 0, 0, 0, 25, 0, 0, -0, 61, 0, 4, 0, 7, 0, 0, 0, 64, 0, 0, 0, 63, 0, 0, 0, 65, 0, 5, 0, 65, 0, 0, 0, 66, 0, 0, 0, 62, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 64, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 69, 0, 0, 0, 47, 0, 0, -0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 62, 0, 3, 0, 68, 0, 0, 0, 70, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 72, 0, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 73, 0, 0, -0, 72, 0, 0, 0, 62, 0, 3, 0, 71, 0, 0, 0, 73, 0, 0, 0, 65, 0, 6, 0, 74, 0, 0, 0, 75, 0, 0, 0, 62, 0, 0, 0, 25, 0, 0, 0, 58, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 76, 0, 0, 0, 75, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, -0, 77, 0, 0, 0, 76, 0, 0, 0, 65, 0, 6, 0, 74, 0, 0, 0, 78, 0, 0, 0, 62, 0, 0, 0, 25, 0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 78, 0, 0, 0, 77, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 67, 112, 80, 10, 24, -224, 99, 199, 22, 44, 52, 16, 154, 121, 88, 32, 0, 178, 20, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 2, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 20, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 40, 0, 0, 0, 0, 104, 20, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 196, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, -83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 9, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 163, 0, 0, 0, 167, 0, 0, 0, 170, 0, 0, 0, 192, 0, 0, 0, 16, 0, -3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 8, 0, 12, 0, 0, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 50, 40, 102, 49, 59, 102, 49, 59, 102, -49, 59, 0, 0, 0, 0, 5, 0, 3, 0, 9, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 10, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 11, 0, 0, 0, 98, 0, 0, 0, 5, 0, 10, 0, 21, 0, 0, 0, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 51, 40, -118, 102, 52, 59, 118, 102, 52, 59, 118, 102, 52, 59, 102, 49, 59, 0, 0, 0, 5, 0, 6, 0, 17, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 18, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, -5, 0, 19, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 20, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 5, 0, 24, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, -7, 0, 24, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 24, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 0, 6, 0, 7, 0, 24, 0, 0, 0, 2, 0, 0, 0, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 13, 0, 28, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 49, -59, 0, 5, 0, 4, 0, 27, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 7, 0, 45, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 6, 0, 47, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, -99, 101, 0, 0, 0, 0, 5, 0, 6, 0, 51, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 52, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 57, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, -4, 0, 61, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 66, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 70, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 4, 0, 75, 0, 0, 0, 111, 112, 97, 99, 105, 116, -121, 0, 5, 0, 5, 0, 89, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 6, 0, 95, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 99, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, -0, 0, 5, 0, 6, 0, 108, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 7, 0, 125, 0, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 6, 0, 128, 0, 0, 0, 84, 101, -120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 132, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, 5, 0, 142, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 144, 0, -0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 146, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 148, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 112, 97, 114, 97, 109, 0, -0, 0, 5, 0, 4, 0, 153, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 158, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 8, 0, 158, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 0, 6, 0, 7, 0, 158, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 158, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 51, 0, 0, 5, 0, 5, 0, 160, 0, -0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 163, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 167, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 6, 0, 170, 0, 0, 0, 103, 108, -95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 180, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, -0, 0, 6, 0, 7, 0, 185, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 187, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 192, 0, 0, 0, 111, 117, 116, 95, 103, 108, -95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 195, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 128, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 128, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 132, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 132, 0, 0, 0, 33, 0, 0, 0, 20, 0, 0, 0, 71, 0, 4, 0, 163, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, -4, 0, 167, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 170, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 192, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 195, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 195, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 33, 0, -6, 0, 8, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 23, 0, 4, 0, 14, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 15, 0, 0, 0, 7, 0, 0, 0, 14, 0, 0, 0, 33, 0, 7, 0, 16, 0, 0, 0, 14, 0, -0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 23, 0, 4, 0, 23, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 5, 0, 24, 0, 0, 0, 23, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 25, 0, 0, 0, 7, 0, -0, 0, 24, 0, 0, 0, 33, 0, 4, 0, 26, 0, 0, 0, 14, 0, 0, 0, 25, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 43, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 6, 0, 0, 0, 46, 0, -0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 6, 0, 0, 0, 48, 0, 0, 0, 205, 204, 204, 62, 21, 0, 4, 0, 53, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 53, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 53, 0, 0, 0, 58, 0, -0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 53, 0, 0, 0, 62, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 73, 0, 0, 0, 154, 153, 89, 63, 20, 0, 2, 0, 85, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 64, 43, 0, -4, 0, 6, 0, 0, 0, 109, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 14, 0, 0, 0, 117, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 126, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 127, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 59, 0, 4, 0, 127, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 130, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 0, 0, -0, 0, 130, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 134, 0, 0, 0, 126, 0, 0, 0, 21, 0, 4, 0, 136, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 136, 0, 0, 0, 137, 0, 0, 0, 0, 0, -0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 44, 0, 7, 0, 14, 0, 0, 0, 143, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 42, 0, 0, 0, 109, 0, 0, 0, 43, 0, 4, 0, 136, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 30, 0, -5, 0, 158, 0, 0, 0, 14, 0, 0, 0, 23, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 159, 0, 0, 0, 7, 0, 0, 0, 158, 0, 0, 0, 43, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 162, 0, 0, 0, 1, 0, 0, 0, 14, 0, -0, 0, 59, 0, 4, 0, 162, 0, 0, 0, 163, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 166, 0, 0, 0, 1, 0, 0, 0, 23, 0, 0, 0, 59, 0, 4, 0, 166, 0, 0, 0, 167, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 162, 0, 0, 0, 170, 0, 0, 0, 1, 0, -0, 0, 30, 0, 3, 0, 185, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 191, 0, 0, 0, 3, 0, 0, 0, 14, 0, 0, 0, 59, 0, 4, 0, 191, 0, 0, 0, 192, 0, 0, 0, 3, 0, 0, 0, 59, 0, -4, 0, 131, 0, 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 159, 0, 0, 0, 160, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 25, 0, -0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 25, 0, 0, 0, 180, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 187, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 164, 0, 0, 0, 163, 0, 0, 0, 65, 0, 5, 0, 15, 0, -0, 0, 165, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, 0, 62, 0, 3, 0, 165, 0, 0, 0, 164, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 145, 0, 0, 0, 62, 0, -3, 0, 169, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 172, 0, 0, 0, 160, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 172, 0, 0, 0, 171, 0, 0, 0, 65, 0, 5, 0, 138, 0, -0, 0, 174, 0, 0, 0, 160, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 176, 0, 0, 0, 175, 0, 0, 0, 65, 0, -5, 0, 15, 0, 0, 0, 177, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 145, 0, 0, 0, 62, 0, 3, 0, 179, 0, 0, 0, 178, 0, -0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 181, 0, 0, 0, 173, 0, 0, 0, 62, 0, 3, 0, 180, 0, 0, 0, 181, 0, 0, 0, 57, 0, 5, 0, 14, 0, 0, 0, 182, 0, 0, 0, 28, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 183, 0, 0, 0, 180, 0, -0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 183, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 184, 0, 0, 0, 173, 0, 0, 0, 161, 0, 0, 0, 62, 0, 3, 0, 184, 0, 0, 0, 182, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 188, 0, 0, 0, 173, 0, 0, 0, 161, 0, -0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 189, 0, 0, 0, 188, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 190, 0, 0, 0, 187, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 190, 0, 0, 0, 189, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 193, 0, 0, 0, 187, 0, -0, 0, 137, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 194, 0, 0, 0, 193, 0, 0, 0, 62, 0, 3, 0, 192, 0, 0, 0, 194, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 6, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 55, 0, -3, 0, 7, 0, 0, 0, 9, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 10, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 11, 0, 0, 0, 248, 0, 2, 0, 13, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 6, 0, -0, 0, 31, 0, 0, 0, 10, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 34, 0, -0, 0, 10, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 36, 0, 0, 0, 11, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 37, 0, 0, 0, 1, 0, -0, 0, 37, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 38, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 32, 0, 0, 0, 37, 0, 0, 0, 254, 0, 2, 0, 38, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 14, 0, 0, 0, 21, 0, -0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 17, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 18, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 19, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 20, 0, 0, 0, 248, 0, 2, 0, 22, 0, -0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 45, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 47, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 52, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 57, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 61, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 66, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 70, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 75, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 89, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 95, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 99, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 108, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 41, 0, 0, 0, 20, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 44, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 42, 0, 0, 0, 43, 0, -0, 0, 62, 0, 3, 0, 20, 0, 0, 0, 44, 0, 0, 0, 62, 0, 3, 0, 45, 0, 0, 0, 46, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 49, 0, 0, 0, 20, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 50, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 62, 0, -3, 0, 47, 0, 0, 0, 50, 0, 0, 0, 65, 0, 5, 0, 7, 0, 0, 0, 55, 0, 0, 0, 17, 0, 0, 0, 54, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 56, 0, 0, 0, 55, 0, 0, 0, 62, 0, 3, 0, 52, 0, 0, 0, 56, 0, 0, 0, 65, 0, 5, 0, 7, 0, -0, 0, 59, 0, 0, 0, 17, 0, 0, 0, 58, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 62, 0, 3, 0, 57, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 7, 0, 0, 0, 63, 0, 0, 0, 17, 0, 0, 0, 62, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 64, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 61, 0, 0, 0, 64, 0, 0, 0, 57, 0, 7, 0, 6, 0, 0, 0, 65, 0, 0, 0, 12, 0, 0, 0, 52, 0, 0, 0, 57, 0, 0, 0, 61, 0, 0, 0, 62, 0, 3, 0, 51, 0, 0, 0, 65, 0, -0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 67, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 68, 0, 0, 0, 47, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 69, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 69, 0, -0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 71, 0, 0, 0, 66, 0, 0, 0, 209, 0, 4, 0, 6, 0, 0, 0, 72, 0, 0, 0, 71, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 74, 0, 0, 0, 72, 0, 0, 0, 73, 0, 0, 0, 62, 0, 3, 0, 70, 0, 0, 0, 74, 0, -0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 76, 0, 0, 0, 70, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 77, 0, 0, 0, 76, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 78, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 79, 0, 0, 0, 66, 0, -0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 49, 0, 0, 0, 77, 0, 0, 0, 78, 0, 0, 0, 79, 0, 0, 0, 62, 0, 3, 0, 75, 0, 0, 0, 80, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 81, 0, 0, 0, 75, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 82, 0, 0, 0, 75, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 83, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 62, 0, 3, 0, 75, 0, 0, 0, 83, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 84, 0, 0, 0, 20, 0, 0, 0, 186, 0, -5, 0, 85, 0, 0, 0, 86, 0, 0, 0, 84, 0, 0, 0, 42, 0, 0, 0, 247, 0, 3, 0, 88, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 86, 0, 0, 0, 87, 0, 0, 0, 88, 0, 0, 0, 248, 0, 2, 0, 87, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 90, 0, -0, 0, 47, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 91, 0, 0, 0, 20, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 93, 0, 0, 0, 91, 0, 0, 0, 92, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 94, 0, 0, 0, 90, 0, 0, 0, 93, 0, 0, 0, 62, 0, -3, 0, 89, 0, 0, 0, 94, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 96, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 97, 0, 0, 0, 89, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 98, 0, 0, 0, 96, 0, 0, 0, 97, 0, 0, 0, 62, 0, -3, 0, 95, 0, 0, 0, 98, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 100, 0, 0, 0, 45, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 101, 0, 0, 0, 95, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 102, 0, 0, 0, 100, 0, 0, 0, 101, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 103, 0, 0, 0, 95, 0, 0, 0, 209, 0, 4, 0, 6, 0, 0, 0, 104, 0, 0, 0, 103, 0, 0, 0, 136, 0, 5, 0, 6, 0, 0, 0, 105, 0, 0, 0, 102, 0, 0, 0, 104, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 106, 0, 0, 0, 89, 0, -0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 107, 0, 0, 0, 105, 0, 0, 0, 106, 0, 0, 0, 62, 0, 3, 0, 99, 0, 0, 0, 107, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 110, 0, 0, 0, 99, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 111, 0, 0, 0, 1, 0, -0, 0, 49, 0, 0, 0, 42, 0, 0, 0, 109, 0, 0, 0, 110, 0, 0, 0, 62, 0, 3, 0, 108, 0, 0, 0, 111, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 112, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 113, 0, 0, 0, 18, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 114, 0, 0, 0, 108, 0, 0, 0, 80, 0, 7, 0, 14, 0, 0, 0, 115, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 12, 0, 8, 0, 14, 0, 0, 0, 116, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 112, 0, -0, 0, 113, 0, 0, 0, 115, 0, 0, 0, 62, 0, 3, 0, 18, 0, 0, 0, 116, 0, 0, 0, 249, 0, 2, 0, 88, 0, 0, 0, 248, 0, 2, 0, 88, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 118, 0, 0, 0, 18, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 119, 0, -0, 0, 75, 0, 0, 0, 80, 0, 7, 0, 14, 0, 0, 0, 120, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 119, 0, 0, 0, 12, 0, 8, 0, 14, 0, 0, 0, 121, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 117, 0, 0, 0, 118, 0, 0, 0, 120, 0, -0, 0, 62, 0, 3, 0, 17, 0, 0, 0, 121, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 122, 0, 0, 0, 17, 0, 0, 0, 254, 0, 2, 0, 122, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 14, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 55, 0, -3, 0, 25, 0, 0, 0, 27, 0, 0, 0, 248, 0, 2, 0, 29, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 125, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 142, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 144, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 148, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 153, 0, 0, 0, 7, 0, -0, 0, 61, 0, 4, 0, 126, 0, 0, 0, 129, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 133, 0, 0, 0, 132, 0, 0, 0, 86, 0, 5, 0, 134, 0, 0, 0, 135, 0, 0, 0, 129, 0, 0, 0, 133, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 139, 0, -0, 0, 27, 0, 0, 0, 137, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 87, 0, 5, 0, 14, 0, 0, 0, 141, 0, 0, 0, 135, 0, 0, 0, 140, 0, 0, 0, 62, 0, 3, 0, 125, 0, 0, 0, 141, 0, 0, 0, 62, 0, 3, 0, 142, 0, -0, 0, 143, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 42, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 147, 0, 0, 0, 125, 0, 0, 0, 62, 0, 3, 0, 146, 0, 0, 0, 147, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 149, 0, 0, 0, 27, 0, 0, 0, 145, 0, -0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 150, 0, 0, 0, 149, 0, 0, 0, 62, 0, 3, 0, 148, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 152, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 152, 0, 0, 0, 61, 0, 4, 0, 6, 0, -0, 0, 154, 0, 0, 0, 144, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 57, 0, 8, 0, 14, 0, 0, 0, 155, 0, 0, 0, 21, 0, 0, 0, 146, 0, 0, 0, 148, 0, 0, 0, 151, 0, 0, 0, 153, 0, 0, 0, 254, 0, 2, 0, 155, 0, 0, 0, 56, 0, -1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, +70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, +57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 106, 241, 116, 115, 62, 248, 116, 0, 146, 201, 139, 213, 179, 227, 100, 215, 0, 128, 32, +0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 117, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, +0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 63, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 51, 1, 0, 0, 53, 1, 0, 0, 49, 1, 0, 0, 59, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 102, 1, 0, 0, 15, 0, 15, 0, 0, 0, +0, 0, 84, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 73, 1, 0, 0, 76, 1, 0, 0, 77, 1, 0, 0, 72, 1, 0, 0, 74, 1, 0, 0, 78, 1, 0, 0, 83, 1, 0, 0, 102, 1, 0, 0, 16, 0, 3, 0, 63, 1, 0, 0, 7, 0, +0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, +105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, +0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 105, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 106, 0, +0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 109, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +0, 0, 5, 0, 3, 0, 110, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 111, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 112, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 126, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +52, 0, 5, 0, 6, 0, 127, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 128, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, +114, 0, 5, 0, 6, 0, 130, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 136, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, +7, 0, 138, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 139, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 140, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, +99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 144, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 149, 0, 0, 0, 105, 110, 116, 95, 49, 0, +0, 0, 5, 0, 4, 0, 153, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 163, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 166, 0, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 168, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 180, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 177, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, +5, 0, 183, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 189, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 193, 0, +0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 178, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 223, 0, +0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 224, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, +70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 225, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, +83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 28, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 29, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 30, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 32, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 50, 1, 0, 0, 112, 116, 114, 95, 79, 117, +116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 49, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 52, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, +116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 51, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 54, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 53, 1, +0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 55, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 55, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 1, +0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 56, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 56, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 57, 1, +0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 57, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 57, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, +5, 0, 57, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 58, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 115, 116, 114, 101, 97, 109, +115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 60, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 61, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 62, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 14, 0, 63, 1, 0, 0, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 8, 0, 72, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 73, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 75, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, +0, 0, 5, 0, 6, 0, 74, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 76, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 77, 1, 0, 0, 105, 110, 95, 86, 83, 95, +67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 0, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 79, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 86, 83, +95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 80, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 80, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, +5, 0, 80, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 81, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 81, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, +110, 0, 6, 0, 6, 0, 81, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 81, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 81, 1, 0, 0, 3, 0, 0, 0, 67, 111, +108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 82, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 84, 1, +0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 91, 1, 0, 0, 105, 110, 116, 95, 51, 0, +0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, +0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 101, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, +4, 0, 102, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 49, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 51, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 51, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 53, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 53, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 72, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 73, 1, +0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 73, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 74, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 74, 1, 0, 0, 3, 22, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 76, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 77, 1, 0, 0, 30, 0, 0, 0, 2, 0, +0, 0, 0, 22, 5, 0, 77, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 78, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 100, 1, +0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, +0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, +5, 0, 100, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 100, 1, +0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 102, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, +0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, +0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, +0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, +9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, +0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 32, 0, 4, 0, 109, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 108, 0, 0, 0, 4, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 109, 0, +0, 0, 32, 0, 4, 0, 126, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 7, 0, 125, 0, 0, 0, 3, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 109, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, +4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 141, 0, 0, 0, 205, 204, 204, 62, 43, 0, +4, 0, 133, 0, 0, 0, 149, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 153, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 166, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 43, 0, +4, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 255, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 25, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 30, 1, +0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 50, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 52, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 54, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 55, 1, 0, 0, 38, 0, +0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 56, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 57, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 6, 0, 0, 0, 57, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 60, 1, +0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 61, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 62, 1, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 75, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 79, 1, 0, 0, 38, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 80, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 81, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 1, 0, 0, 6, 0, +0, 0, 81, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 91, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 100, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, +0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 101, 1, 0, 0, 2, 0, 0, 0, 100, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 101, 1, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, +0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 49, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 51, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 53, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 59, 1, +0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 72, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 75, 1, 0, 0, 74, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 76, 1, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 77, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 82, 1, 0, 0, 83, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 105, 0, +0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 110, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 112, 0, 0, 0, 248, 0, 2, 0, 113, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 0, +0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 0, 0, 0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 116, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 114, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 118, 0, 0, 0, 110, 0, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 0, 0, 0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 121, 0, 0, 0, 112, 0, 0, 0, 12, 0, +7, 0, 4, 0, 0, 0, 122, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 123, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 116, 0, 0, 0, 122, 0, 0, 0, 254, 0, 2, 0, 123, 0, 0, 0, 56, 0, +1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 127, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 128, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 129, 0, 0, 0, 55, 0, 3, 0, 109, 0, +0, 0, 130, 0, 0, 0, 248, 0, 2, 0, 131, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 138, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 140, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 144, 0, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 109, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 148, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 152, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 159, 0, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 109, 0, 0, 0, 163, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 183, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 109, 0, 0, 0, 193, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 202, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 0, 0, 0, 130, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 12, 0, +8, 0, 4, 0, 0, 0, 137, 0, 0, 0, 117, 0, 0, 0, 43, 0, 0, 0, 132, 0, 0, 0, 135, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 130, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 138, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 142, 0, +0, 0, 130, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 141, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 143, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 146, 0, 0, 0, 127, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 147, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 147, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 150, 0, 0, 0, 127, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 151, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 148, 0, +0, 0, 151, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 154, 0, 0, 0, 127, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 155, 0, 0, 0, 154, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 155, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 158, 0, +0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 161, 0, 0, 0, 140, 0, 0, 0, 131, 0, +5, 0, 4, 0, 0, 0, 162, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, 0, 62, 0, 3, 0, 159, 0, 0, 0, 162, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 164, 0, 0, 0, 159, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 133, 0, +5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 163, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 169, 0, 0, 0, 163, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 163, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 172, 0, 0, 0, 159, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 173, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, +3, 0, 168, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 62, 0, +3, 0, 168, 0, 0, 0, 176, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 130, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 182, 0, 0, 0, 179, 0, 0, 0, 180, 0, 0, 0, 247, 0, 3, 0, 178, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 182, 0, +0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 248, 0, 2, 0, 177, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 130, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 187, 0, 0, 0, 185, 0, +0, 0, 186, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 184, 0, 0, 0, 187, 0, 0, 0, 62, 0, 3, 0, 183, 0, 0, 0, 188, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 190, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, +0, 0, 183, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 62, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 138, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 0, +0, 0, 189, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 196, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 197, 0, 0, 0, 136, 0, 5, 0, 4, 0, +0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, 0, 183, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 62, 0, 3, 0, 193, 0, 0, 0, 201, 0, 0, 0, 111, 0, +4, 0, 4, 0, 0, 0, 203, 0, 0, 0, 134, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 204, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 193, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 206, 0, 0, 0, 117, 0, 0, 0, 49, 0, +0, 0, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 202, 0, 0, 0, 206, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 207, 0, 0, 0, 129, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 208, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 209, 0, 0, 0, 202, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 210, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 207, 0, 0, 0, 208, 0, +0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 211, 0, 0, 0, 249, 0, 2, 0, 178, 0, 0, 0, 248, 0, 2, 0, 178, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 212, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 168, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 3, 0, +0, 0, 216, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 127, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 217, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 217, 0, 0, 0, 56, 0, +1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 236, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 243, 0, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 245, 0, 0, 0, 83, 1, +0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 246, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, +2, 0, 248, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 253, 0, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 1, 1, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 1, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, +5, 0, 3, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 248, 0, 2, 0, 2, 1, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 28, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, +0, 0, 32, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, +0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 15, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 22, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 23, 1, 0, 0, 22, 1, 0, 0, 61, 0, +4, 0, 34, 0, 0, 0, 24, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 25, 1, 0, 0, 26, 1, 0, 0, 24, 1, 0, 0, 15, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 27, 1, 0, 0, 26, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 3, 1, +0, 0, 27, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 31, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 28, 1, 0, 0, 31, 1, 0, 0, 62, 0, 3, 0, 32, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 3, 0, +0, 0, 37, 1, 0, 0, 3, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 37, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 40, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 41, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 38, 1, +0, 0, 41, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 43, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 32, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 57, 0, +8, 0, 3, 0, 0, 0, 48, 1, 0, 0, 106, 0, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 254, 0, 2, 0, 48, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, +2, 0, 64, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 65, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 66, 1, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 67, 1, +0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 68, 1, 0, 0, 53, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 68, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 69, 1, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 70, 1, +0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 49, 1, 0, 0, 71, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 29, 0, +0, 0, 248, 0, 2, 0, 85, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 86, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 87, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 2, 0, +0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 88, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 92, 1, 0, 0, 77, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 92, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 93, 1, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 94, 1, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 95, 1, 0, 0, 94, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 96, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 97, 1, 0, 0, 96, 1, 0, 0, 62, 0, +3, 0, 74, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 1, 0, 0, 98, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 99, 1, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 106, 241, 116, 115, 62, 248, 116, 0, 146, 201, 139, 213, 179, 227, 100, 215, 0, 128, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 103, 1, 0, +0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 117, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 63, 1, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 51, 1, 0, 0, 53, 1, 0, 0, 49, 1, 0, 0, 59, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 102, 1, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 84, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 73, 1, 0, 0, 76, 1, 0, 0, 77, 1, 0, 0, 72, 1, 0, 0, 74, 1, 0, 0, 78, 1, 0, 0, 83, 1, 0, 0, 102, 1, 0, 0, 16, 0, 3, 0, 63, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, +97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, +0, 5, 0, 10, 0, 105, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 106, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 109, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 110, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, +0, 111, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 112, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 126, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 127, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, +67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 128, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 130, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, +104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 136, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, +103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 139, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 140, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 144, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 149, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 153, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, +0, 5, 0, 4, 0, 159, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 163, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 166, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 168, 0, 0, +0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 180, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 177, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, +0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 189, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 193, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, +0, 202, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 178, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 223, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 224, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, +83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 225, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, +0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 28, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 29, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 30, 1, 0, +0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 32, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 50, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, +0, 49, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 52, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 51, 1, 0, 0, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 54, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 53, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, +0, 55, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 55, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, +0, 56, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 56, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 57, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, +0, 57, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 57, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 57, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 5, 0, 8, 0, 58, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 60, 1, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 4, 0, 61, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 62, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 14, 0, 63, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, +70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 8, 0, 72, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, +0, 73, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 75, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 74, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 76, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 77, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 78, 1, 0, 0, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, +0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 79, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 80, 1, 0, +0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 80, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 5, 0, 5, 0, 81, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 81, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 81, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 81, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 82, 1, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 84, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 91, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, +111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, +101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 101, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, +0, 49, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 51, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 51, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 53, 1, 0, 0, 30, 0, 0, +0, 1, 0, 0, 0, 0, 22, 5, 0, 53, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 72, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 73, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 73, 1, 0, +0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 74, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 74, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, +0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 76, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 77, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 77, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 78, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 100, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 0, 0, 0, +0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, +0, 24, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, +0, 72, 0, 5, 0, 100, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, +0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, +0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, +0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, +0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, +0, 0, 0, 0, 0, 82, 0, 0, 0, 32, 0, 4, 0, 109, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 108, 0, 0, 0, 4, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 32, 0, 4, 0, 126, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, +0, 33, 0, 7, 0, 125, 0, 0, 0, 3, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 109, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, +0, 4, 0, 0, 0, 136, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 141, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 149, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 133, 0, 0, 0, 153, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 166, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, +0, 255, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 25, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 30, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 50, 1, 0, 0, 3, 0, 0, +0, 3, 0, 0, 0, 32, 0, 4, 0, 52, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 54, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 55, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 56, 1, 0, 0, 3, 0, 0, +0, 30, 0, 5, 0, 57, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 6, 0, 0, 0, 57, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 61, 1, 0, +0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 62, 1, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 75, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 79, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 80, 1, 0, +0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 81, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 1, 0, 0, 6, 0, 0, 0, 81, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 91, 1, 0, +0, 3, 0, 0, 0, 30, 0, 12, 0, 100, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 101, 1, 0, 0, 2, 0, 0, +0, 100, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 101, 1, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 49, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 51, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 53, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 59, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 72, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 75, 1, 0, 0, 74, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 77, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 82, 1, 0, 0, 83, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, +0, 110, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 112, 0, 0, 0, 248, 0, 2, 0, 113, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 0, 0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 0, 0, +0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 116, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 114, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 118, 0, 0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 0, 0, 0, 111, 0, 0, +0, 12, 0, 7, 0, 4, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 121, 0, 0, 0, 112, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 122, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, +0, 120, 0, 0, 0, 121, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 123, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 116, 0, 0, 0, 122, 0, 0, 0, 254, 0, 2, 0, 123, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, +0, 125, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 127, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 128, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 129, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 130, 0, 0, 0, 248, 0, 2, 0, 131, 0, 0, 0, 59, 0, 4, +0, 109, 0, 0, 0, 138, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 140, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 144, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 109, 0, 0, 0, 148, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 152, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 159, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 163, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 109, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 183, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 193, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 109, 0, 0, 0, 202, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 0, 0, 0, 130, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 137, 0, 0, 0, 117, 0, 0, 0, 43, 0, 0, +0, 132, 0, 0, 0, 135, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 130, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 138, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 142, 0, 0, 0, 130, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, +0, 141, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 143, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 146, 0, 0, 0, 127, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 147, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, +0, 147, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 150, 0, 0, 0, 127, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 151, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 148, 0, 0, 0, 151, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 154, 0, 0, +0, 127, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 155, 0, 0, 0, 154, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 155, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 158, 0, 0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, +0, 62, 0, 3, 0, 144, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 161, 0, 0, 0, 140, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 162, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, +0, 62, 0, 3, 0, 159, 0, 0, 0, 162, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 164, 0, 0, 0, 159, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, +0, 62, 0, 3, 0, 163, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 169, 0, 0, 0, 163, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 163, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 172, 0, 0, 0, 159, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 173, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 174, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 176, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 179, 0, 0, 0, 130, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 182, 0, 0, 0, 179, 0, 0, 0, 180, 0, 0, 0, 247, 0, 3, 0, 178, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 182, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 248, 0, 2, 0, 177, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 130, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, +0, 184, 0, 0, 0, 187, 0, 0, 0, 62, 0, 3, 0, 183, 0, 0, 0, 188, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 190, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 183, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 192, 0, 0, +0, 190, 0, 0, 0, 191, 0, 0, 0, 62, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 138, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 0, 0, 0, 189, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 196, 0, 0, +0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 197, 0, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 200, 0, 0, 0, 183, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 62, 0, 3, 0, 193, 0, 0, 0, 201, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 203, 0, 0, 0, 134, 0, 0, 0, 111, 0, 4, +0, 4, 0, 0, 0, 204, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 193, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 206, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, +0, 202, 0, 0, 0, 206, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 207, 0, 0, 0, 129, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 208, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 0, 0, 0, 202, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, +0, 210, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 207, 0, 0, 0, 208, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 211, 0, 0, +0, 249, 0, 2, 0, 178, 0, 0, 0, 248, 0, 2, 0, 178, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 212, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 214, 0, 0, 0, 168, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 216, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, +0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 127, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 217, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 217, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, +0, 29, 0, 0, 0, 248, 0, 2, 0, 236, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 243, 0, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 245, 0, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 246, 0, 0, +0, 245, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 246, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 248, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 253, 0, 0, +0, 59, 1, 0, 0, 60, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 1, 1, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 1, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, +0, 248, 0, 2, 0, 2, 1, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 28, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 32, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, +0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, +0, 15, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 22, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 23, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 24, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, +0, 25, 1, 0, 0, 26, 1, 0, 0, 24, 1, 0, 0, 15, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 27, 1, 0, 0, 26, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 27, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 31, 1, 0, +0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 28, 1, 0, 0, 31, 1, 0, 0, 62, 0, 3, 0, 32, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 37, 1, 0, 0, 3, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, +0, 37, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 40, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 41, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 38, 1, 0, 0, 41, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 43, 1, 0, +0, 28, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 32, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 57, 0, 8, 0, 3, 0, 0, 0, 48, 1, 0, 0, 106, 0, 0, 0, 36, 1, 0, +0, 38, 1, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 254, 0, 2, 0, 48, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 64, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 65, 1, 0, +0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 66, 1, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 67, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, +0, 68, 1, 0, 0, 53, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 68, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 69, 1, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 70, 1, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, +0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 49, 1, 0, 0, 71, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 85, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, +0, 86, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 87, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, +0, 3, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 88, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 92, 1, 0, 0, 77, 1, 0, 0, 62, 0, 3, +0, 90, 1, 0, 0, 92, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 93, 1, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 94, 1, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 95, 1, 0, 0, 94, 1, 0, 0, 62, 0, 3, +0, 72, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 96, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 97, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, +0, 98, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 1, 0, 0, 98, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 99, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index b23922f49d..143e883f51 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -1,416 +1,385 @@ -#if STRIDE_GRAPHICS_API_DIRECT3D -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteSignedDistanceFieldFontShader] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_DIRECT3D11 + +namespace Stride.Graphics { internal partial class SpriteSignedDistanceFieldFontShader { private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -1, 182, 30, 36, 111, 246, 180, 175, 213, 1, 191, 88, 116, 137, 233, 235, 105, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 103, 177, 47, 3, 221, 157, 52, 231, 107, 111, 207, 181, 23, 175, 186, 140, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, 227, 114, 5, 111, 246, 192, -110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 102, 5, 246, 130, 48, 38, 110, 255, 43, 200, -180, 232, 16, 46, 222, 107, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 198, 112, 202, 96, 191, 123, -88, 116, 59, 14, 179, 198, 198, 31, 42, 99, 0, 120, 101, 0, 0, 68, 88, 66, 67, 174, 157, 199, 7, 246, 52, 62, 172, 2, 159, 231, 250, 23, 117, 88, 220, 1, 0, 0, 0, 120, 101, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 99, 0, 0, 200, -99, 0, 0, 148, 100, 0, 0, 4, 101, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, 0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, 0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 204, 0, 0, 0, 11, 0, 0, 0, 208, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, -118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, -92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, -53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 180, 0, 0, 0, 56, -3, 0, 0, 180, 0, 0, 0, 72, 3, 0, 0, 180, 0, 0, 0, 88, 3, 0, 0, 180, 0, 0, 0, 104, 3, 0, 0, 174, 0, 0, 0, 120, 3, 0, 0, 174, 0, 0, 0, 140, 3, 0, 0, 178, 0, 0, 0, 152, 3, 0, 0, 179, 0, 0, 0, 164, 3, 0, 0, 86, 83, 77, 97, 105, -110, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, -0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 171, 47, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 100, 1, 0, 0, 116, 1, 0, 0, 68, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 128, 1, 0, 0, 3, 0, 0, 0, 255, -255, 255, 255, 2, 0, 255, 255, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 9, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 10, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, -0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 238, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 100, 1, 0, 0, 116, 1, 0, 0, 68, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 252, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, -0, 3, 0, 1, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 0, 238, 1, 0, 0, 68, 1, 0, 0, 84, 1, 0, 0, 100, 1, 0, 0, 116, 1, 0, 0, 68, 1, 0, 0, 47, 1, 0, 0, 68, -1, 0, 0, 5, 0, 0, 0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 11, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 0, 0, 0, 0, 40, 1, 0, 0, 152, -1, 0, 0, 5, 0, 0, 0, 168, 1, 0, 0, 40, 1, 0, 0, 228, 1, 0, 0, 20, 2, 0, 0, 3, 0, 0, 0, 36, 2, 0, 0, 0, 0, 0, 0, 72, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, -32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, -0, 0, 3, 0, 0, 4, 192, 0, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 0, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 0, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 0, 0, 228, 144, 4, 0, 228, 160, 4, -0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 1, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, -1, 0, 0, 64, 0, 1, 0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 103, -0, 0, 4, 242, 32, 16, 0, 0, 0, 0, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, -0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, -0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 5, 242, -32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 94, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, -0, 0, 0, 47, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, +114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, +101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, +1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, +93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, +194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 42, 221, 214, 87, 40, 204, 27, 223, 36, 113, 16, 94, 252, 222, 94, 128, 0, 192, 95, 0, 0, 68, 88, 66, 67, 63, 195, 153, 107, 204, 58, 8, 205, 203, 164, 112, 73, 93, 251, 97, +115, 1, 0, 0, 0, 192, 95, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 94, 0, 0, 140, 94, 0, 0, 64, 95, 0, 0, 140, 95, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, +0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, +0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, +115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, +255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, 255, 0, 4, 0, 0, 77, 0, 0, 0, 12, 4, 0, 0, 82, 0, 0, 0, 28, 4, 0, 0, 82, 0, 0, 0, 44, 4, 0, 0, 82, 0, 0, 0, 64, 4, 0, 0, 82, 0, 0, 0, 80, 4, 0, 0, 94, 0, 0, +0, 96, 4, 0, 0, 95, 0, 0, 0, 112, 4, 0, 0, 95, 0, 0, 0, 124, 4, 0, 0, 95, 0, 0, 0, 136, 4, 0, 0, 95, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 164, 4, 0, 0, 96, 0, 0, 0, 184, 4, 0, 0, 96, 0, 0, 0, 200, 4, 0, 0, 96, 0, 0, +0, 212, 4, 0, 0, 96, 0, 0, 0, 228, 4, 0, 0, 96, 0, 0, 0, 248, 4, 0, 0, 96, 0, 0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 40, 5, 0, 0, 106, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, +105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, +0, 1, 0, 0, 0, 0, 0, 0, 0, 193, 1, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 228, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, +0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, +97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 148, 2, 0, 0, 164, 2, 0, 0, 180, 2, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, +0, 192, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 160, 1, 0, 0, 1, 0, 0, +0, 176, 1, 0, 0, 0, 0, 0, 0, 188, 1, 0, 0, 236, 1, 0, 0, 1, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 16, 2, 0, 0, 2, 0, 0, 0, 32, 2, 0, 0, 56, 2, 0, 0, 90, 2, 0, 0, 212, 1, 0, 0, 1, 0, 0, 0, 104, 2, 0, +0, 0, 0, 0, 0, 116, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 124, 2, 0, 0, 188, 1, 0, 0, 136, 2, 0, 0, 208, 2, 0, 0, 2, 0, 0, 0, 224, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, +101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, +0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, +129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, +128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, +4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, +4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, +128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, +4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, +0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, +0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, +0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, +0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, +7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, +0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, +64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, +114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, +0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, +0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 90, 85, 68, 56, 43, 218, 165, 69, 163, 53, 231, 174, 59, 69, 2, 17, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, -85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, -10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 198, 90, 0, 0, 117, 131, 1, 0, 3, 72, 3, 0, 156, 202, 1, 0, 38, 247, 2, 0, 26, 32, 2, 0, 69, 103, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 103, -159, 1, 0, 206, 55, 0, 0, 57, 206, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, -13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, -83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, -85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, -32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, -111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, -105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, -120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, -32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, -49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, -50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, -105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, -114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, -116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, -105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, -61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, -109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, -76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, -10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, -109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, -59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, -71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, -53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, -100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, -109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, -111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, -114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, -114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, -105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, -42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, -32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, -41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, -110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, -116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, -111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, -101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, -101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, -111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, -32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, -10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, -116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, -32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, -53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, -112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, -117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, -69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, -117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, -111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, -111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, -32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, -95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 44, 22, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, -115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, -83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, -97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, -108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, -115, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 27, 226, 48, 1, 128, 0, 0, 0, 195, 21, 147, 25, 57, 45, 214, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 104, 43, 135, 54, 229, -20, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, 77, 105, 99, 114, 111, 115, 111, -102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, 104, 108, 115, 108, 84, 97, 114, -103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 86, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, -0, 0, 0, 8, 16, 0, 0, 100, 0, 0, 0, 1, 0, 160, 86, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, -0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, -0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 62, 0, 62, 17, 7, -16, 0, 0, 136, 0, 60, 86, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, -0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 12, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 115, 38, 165, -252, 141, 197, 252, 40, 66, 140, 67, 235, 165, 151, 219, 186, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 180, 0, 0, 128, 100, 0, 0, 0, 180, 0, 0, 0, 132, -0, 0, 0, 180, 0, 0, 128, 132, 0, 0, 0, 180, 0, 0, 0, 164, 0, 0, 0, 180, 0, 0, 128, 164, 0, 0, 0, 180, 0, 0, 0, 196, 0, 0, 0, 180, 0, 0, 128, 196, 0, 0, 0, 180, 0, 0, 0, 228, 0, 0, 0, 185, 0, 0, 128, 228, 0, 0, 0, 185, 0, 0, 0, 248, -0, 0, 0, 185, 0, 0, 128, 248, 0, 0, 0, 185, 0, 0, 0, 12, 1, 0, 0, 185, 0, 0, 128, 12, 1, 0, 0, 185, 0, 0, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, 0, 83, 0, 35, 0, 82, 0, 5, -0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 12, 16, 0, 0, 112, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 48, -0, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, -243, 242, 241, 74, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, -0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 82, 0, 3, 18, 13, -21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, -0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, -16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 9, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 10, 16, 0, 0, 1, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, -79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, -51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, -101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, -116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, -51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, -32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, -52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, -66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, -116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, -79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, -73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, -110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, -32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, -61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, -49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, -97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 102, 108, 111, 97, 116, -52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, -101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, -32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, -97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, -95, 105, 100, 51, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, -61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, -105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, -111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, -97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, -110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, -103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, -32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, -99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, -52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 44, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, -105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, -48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, -84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, -50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, -95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, -67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, -105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, -95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, -0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, +1, 204, 180, 142, 105, 1, 0, 0, 0, 166, 252, 70, 235, 64, 149, 14, 77, 164, 61, 105, 101, 153, 85, 245, 94, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, +0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, +0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 113, 232, 0, 0, 28, 221, 1, 0, 214, 154, 2, 0, 101, 128, 0, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, +117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, +101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, +58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, +40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, +105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, +114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, +114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, +108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, +52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, +110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, +99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, +32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, +48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, +114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 54, 32, 61, +32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, +97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 51, 44, 32, 95, 50, 49, 54, 44, 32, 95, 50, 50, 48, 41, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, +115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, +99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, +104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, +109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, +101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, +101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, +97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, +110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 53, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 53, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, +102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 49, 57, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, +70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 48, 53, 44, 32, 95, 51, 48, 57, 44, 32, 95, 51, 49, 53, 44, 32, 95, 51, 49, 57, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, +32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, +111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, +67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, +32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, +239, 1, 0, 0, 0, 174, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, +51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, +97, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, +1, 128, 0, 0, 0, 108, 90, 59, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 86, 98, 187, 113, 243, 14, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, +0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, +46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, +105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 5, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, +17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, +1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, +109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, +0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, +0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 12, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 96, 4, 129, 248, 8, 0, 13, 23, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, +0, 8, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 74, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 73, 1, 80, 12, 129, 248, 0, 0, 50, 0, 77, 17, 60, 2, 0, 0, 4, 5, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 39, 11, 32, 13, 76, 6, 8, 12, 129, 212, +36, 8, 0, 9, 19, 13, 38, 1, 80, 6, 9, 3, 0, 13, 75, 6, 8, 12, 129, 212, 36, 38, 0, 77, 17, 100, 2, 0, 0, 84, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 80, 12, 36, 0, 0, 0, 0, 74, 0, 62, +17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, +0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 8, 0, 0, 0, 2, 0, 78, 17, 110, 0, 77, 17, 100, 2, 0, 0, 0, 5, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, +76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, +6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, +0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, +17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, +9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 18, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, +17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 146, 224, 37, 145, 93, 203, 233, 81, 174, 233, 104, 45, 135, 143, 95, 34, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, +0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 137, 0, 0, 128, 80, 0, 0, 0, 137, 0, 0, 0, 116, 0, 0, 0, 137, 0, 0, 128, 116, 0, 0, 0, 137, 0, 0, 0, 144, 0, 0, 0, 137, 0, 0, 128, 144, 0, 0, 0, 137, 0, 0, +0, 172, 0, 0, 0, 137, 0, 0, 128, 172, 0, 0, 0, 137, 0, 0, 0, 200, 0, 0, 0, 137, 0, 0, 128, 200, 0, 0, 0, 137, 0, 0, 0, 228, 0, 0, 0, 137, 0, 0, 128, 228, 0, 0, 0, 137, 0, 0, 0, 248, 0, 0, 0, 137, 0, 0, 128, 248, 0, 0, 0, 137, 0, 0, +0, 12, 1, 0, 0, 137, 0, 0, 128, 12, 1, 0, 0, 137, 0, 0, 0, 48, 1, 0, 0, 137, 0, 0, 128, 48, 1, 0, 0, 137, 0, 0, 0, 84, 1, 0, 0, 137, 0, 0, 128, 84, 1, 0, 0, 137, 0, 0, 0, 112, 1, 0, 0, 137, 0, 0, 128, 112, 1, 0, 0, 137, 0, 0, +0, 152, 1, 0, 0, 137, 0, 0, 128, 152, 1, 0, 0, 137, 0, 0, 0, 180, 1, 0, 0, 137, 0, 0, 128, 180, 1, 0, 0, 137, 0, 0, 0, 216, 1, 0, 0, 137, 0, 0, 128, 216, 1, 0, 0, 137, 0, 0, 0, 244, 1, 0, 0, 137, 0, 0, 128, 244, 1, 0, 0, 137, 0, 0, +0, 16, 2, 0, 0, 137, 0, 0, 128, 16, 2, 0, 0, 137, 0, 0, 0, 44, 2, 0, 0, 137, 0, 0, 128, 44, 2, 0, 0, 137, 0, 0, 0, 72, 2, 0, 0, 140, 0, 0, 128, 72, 2, 0, 0, 140, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, +0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, +0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, +0, 246, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 4, 16, 0, +0, 0, 0, 0, 0, 86, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, +21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 21, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, +1, 56, 0, 0, 0, 0, 16, 0, 0, 26, 16, 0, 0, 8, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 8, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, +0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, +110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, +21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, +0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, +18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 32, 106, 0, 0, 242, 241, 41, 75, 0, +0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, 0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, +53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, +108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, +111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, +99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, +116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, +10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, +116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, +10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, +108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, +100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, +97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, +117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, +102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +95, 50, 49, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 51, 44, 32, 95, 50, 49, 54, 44, 32, 95, 50, +50, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, +32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, +59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, +32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, +116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, +111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, +32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 53, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +95, 51, 48, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 53, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, +102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 49, 57, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, +101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 48, 53, 44, 32, 95, 51, 48, 57, 44, 32, 95, 51, 49, 53, 44, 32, 95, 51, 49, 57, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 50, 59, 10, 125, +10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 186, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, +1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, 0, 236, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, +0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, +105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, +0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, +83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, +0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, +105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, +0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 42, 0, 81, 17, 11, 16, 0, 0, 8, 0, 0, 0, 0, -0, 255, 255, 255, 255, 255, 255, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, +17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 22, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 25, 16, 0, +0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 48, 0, 48, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, +110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, +0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 254, 239, 254, +239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, +1, 204, 180, 142, 105, 1, 0, 0, 0, 166, 252, 70, 235, 64, 149, 14, 77, 164, 61, 105, 101, 153, 85, 245, 94, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, +115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, +51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 97, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, +0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 90, 85, 68, 56, 43, 218, 165, 69, 163, 53, 231, 174, 59, 69, 2, 17, 207, 0, 0, 0, 47, 76, 105, 110, 107, -73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, -115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, -115, 112, 114, 105, 116, 101, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, -97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, -0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 176, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, -3, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 81, 62, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 81, 62, 0, -0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, -58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, -101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, -99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 43, 1, 0, 0, 168, 1, 0, 0, 183, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 92, 22, 0, 0, 128, 0, 0, 0, 229, -20, 0, 0, 20, 4, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 41, 0, 0, 0, 24, 0, 0, 0, 42, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, -0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, -0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 7, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 40, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, +0, 32, 0, 0, 0, 229, 0, 0, 0, 64, 2, 0, 0, 111, 1, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 222, 15, 0, 0, 128, 0, 0, 0, 243, 14, 0, 0, 104, 7, 0, 0, 112, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, +0, 3, 0, 0, 0, 38, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, +0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, +0, 36, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -433,58 +402,44 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, +84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, +0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, +48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, +0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 88, 84, 127, 211, 244, 81, 196, 106, 171, 92, 171, 170, +219, 201, 197, 206, 0, 120, 77, 0, 0, 68, 88, 66, 67, 204, 198, 217, 28, 190, 139, 216, 132, 209, 169, 155, 35, 3, 58, 149, 247, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, +0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, 0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, 0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, +100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, +48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 86, 0, 0, 0, 56, 3, 0, 0, 86, 0, 0, 0, 72, 3, 0, 0, 86, 0, 0, +0, 88, 3, 0, 0, 86, 0, 0, 0, 104, 3, 0, 0, 100, 0, 0, 0, 120, 3, 0, 0, 100, 0, 0, 0, 140, 3, 0, 0, 102, 0, 0, 0, 152, 3, 0, 0, 104, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, +0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 52, 1, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 8, 0, 255, 255, 7, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, +255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 9, 0, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 164, 1, 0, 0, 248, 0, 0, 0, 179, 1, 0, 0, 24, 1, 0, 0, 194, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, +0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 171, 171, 38, 2, 0, 0, 24, 1, 0, 0, 54, 2, 0, 0, 248, 0, 0, 0, 63, 2, 0, 0, 24, 1, 0, 0, 72, 2, 0, 0, 24, 1, 0, 0, 5, 0, 0, +0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, 0, 4, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 76, 1, 0, 0, 5, 0, 0, +0, 92, 1, 0, 0, 224, 0, 0, 0, 152, 1, 0, 0, 232, 1, 0, 0, 3, 0, 0, 0, 248, 1, 0, 0, 0, 0, 0, 0, 28, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, +83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, +192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, +192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 1, +0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, +0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, +0, 70, 30, 16, 0, 2, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, +0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, +0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, +0, 176, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 196, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 65, 0, 0, 156, 0, 0, 0, 60, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, -0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 171, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, -115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 80, 79, 83, 73, 84, -73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 108, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 12, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, -67, 79, 76, 79, 82, 0, 171, 0, 5, 0, 0, 0, 1, 7, 196, 188, 150, 129, 186, 119, 153, 26, 137, 4, 217, 125, 227, 55, 148, 0, 12, 112, 0, 0, 68, 88, 66, 67, 255, 101, 22, 113, 48, 91, 10, 77, 190, 28, 202, 252, 57, 123, 48, 157, 1, 0, 0, 0, 12, 112, 0, 0, 7, 0, -0, 0, 60, 0, 0, 0, 228, 5, 0, 0, 56, 8, 0, 0, 64, 110, 0, 0, 188, 110, 0, 0, 100, 111, 0, 0, 216, 111, 0, 0, 65, 111, 110, 57, 160, 5, 0, 0, 160, 5, 0, 0, 0, 2, 255, 255, 120, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, -40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 248, 0, 68, 66, 85, 71, 40, 0, 0, 0, 180, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 204, 0, 0, 0, 25, 0, 0, 0, 208, 0, 0, 0, 7, 0, 0, 0, 40, 3, 0, 0, 152, 1, -0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, -110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 98, 57, -52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 0, 4, 0, 0, 0, 0, 255, 255, 24, 4, -0, 0, 0, 0, 255, 255, 36, 4, 0, 0, 0, 0, 255, 255, 48, 4, 0, 0, 158, 0, 0, 0, 60, 4, 0, 0, 133, 0, 0, 0, 76, 4, 0, 0, 133, 0, 0, 0, 92, 4, 0, 0, 133, 0, 0, 0, 112, 4, 0, 0, 133, 0, 0, 0, 128, 4, 0, 0, 141, 0, 0, 0, 144, 4, -0, 0, 142, 0, 0, 0, 160, 4, 0, 0, 142, 0, 0, 0, 172, 4, 0, 0, 142, 0, 0, 0, 184, 4, 0, 0, 142, 0, 0, 0, 196, 4, 0, 0, 143, 0, 0, 0, 212, 4, 0, 0, 143, 0, 0, 0, 232, 4, 0, 0, 143, 0, 0, 0, 248, 4, 0, 0, 143, 0, 0, 0, 4, 5, -0, 0, 143, 0, 0, 0, 20, 5, 0, 0, 143, 0, 0, 0, 40, 5, 0, 0, 143, 0, 0, 0, 56, 5, 0, 0, 144, 0, 0, 0, 72, 5, 0, 0, 153, 0, 0, 0, 88, 5, 0, 0, 153, 0, 0, 0, 104, 5, 0, 0, 80, 83, 77, 97, 105, 110, 0, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 159, 1, 0, 0, 176, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 192, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 104, -97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, -105, 100, 48, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 171, 22, 2, 0, 0, 176, 1, 0, 0, 42, 2, 0, 0, 56, 2, 0, 0, 72, 2, -0, 0, 176, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 84, 2, 0, 0, 2, 0, 0, 0, 4, 0, 5, 0, 255, 255, 255, 255, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 0, 171, 0, 0, 3, 0, 1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, -255, 255, 255, 255, 255, 255, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, -255, 255, 0, 0, 0, 0, 152, 1, 0, 0, 200, 1, 0, 0, 1, 0, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 228, 1, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 152, 1, 0, 0, 12, 2, 0, 0, 108, 2, 0, 0, 2, 0, 0, 0, 124, 2, 0, 0, 0, 0, -0, 0, 148, 2, 0, 0, 160, 2, 0, 0, 1, 0, 0, 0, 176, 2, 0, 0, 0, 0, 0, 0, 188, 2, 0, 0, 196, 2, 0, 0, 2, 0, 0, 0, 212, 2, 0, 0, 236, 2, 0, 0, 250, 2, 0, 0, 176, 1, 0, 0, 1, 0, 0, 0, 8, 3, 0, 0, 0, 0, 0, 0, 20, 3, -0, 0, 196, 2, 0, 0, 1, 0, 0, 0, 28, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, -204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, -0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, -0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, -4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, -85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, -0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, -228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 98, 16, -0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, -0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, -16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, -16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, -0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, -0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, -0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, -0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, -16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 102, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, -0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 51, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -492,7 +447,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -500,363 +455,199 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 204, 180, 142, 105, 1, 0, 0, 0, 165, 1, 241, 92, 160, 53, 1, 76, 186, 205, 211, 92, 206, 95, 190, 22, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 130, 226, 135, 64, 223, 172, 72, 66, 178, 126, 195, 54, 114, 89, 128, 215, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, -58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, -99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, -67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, -84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 198, 90, 0, 0, 117, 131, 1, 0, 26, 32, 2, 0, 162, 202, 1, 0, 38, 247, 2, 0, 92, 248, 0, 0, 71, 103, 0, 0, 49, 251, -3, 0, 168, 209, 0, 0, 57, 140, 3, 0, 170, 19, 0, 0, 94, 184, 2, 0, 65, 36, 1, 0, 116, 39, 1, 0, 13, 58, 1, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 31, 72, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 110, 4, 0, 0, 50, 237, -0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, -83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, -55, 52, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, -32, 86, 83, 95, 73, 78, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, -99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, -102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, -100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, -101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, 100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, -120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, -13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, 49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, -97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, -73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, -101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, -114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, -67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, -73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, -67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, -114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, -10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, -32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, -95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, -13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, 100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, -101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, -53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, -101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, -41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, -41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, -45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 115, 97, 109, 112, 108, 101, -100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, -109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, -103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, -115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, -101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, -101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, -32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, -105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, -108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, -32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, -114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, -46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 101, 97, 109, 115, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 95, 105, 100, 55, 52, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, -32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, -95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, -100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, -32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, -32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, -61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, -95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, -13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, -97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, -10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, -48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, -95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 59, 13, 10, 125, 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 44, 22, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, 112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, -115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, -49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, -115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, -101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 125, 59, 13, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 125, 59, 13, 27, 226, 48, 1, 128, 0, 0, 0, 111, 39, 152, 25, 57, 45, 214, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 40, 0, 0, 0, 27, 226, -48, 1, 104, 43, 135, 54, 229, 20, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 1, 0, 186, 71, 10, 0, 1, 0, 1, 0, 186, 71, -77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 66, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 52, 48, 48, 49, 0, -104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 80, 83, 77, 97, 105, 110, 0, 0, 46, 0, 16, 17, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 0, 0, 252, 1, -0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 80, 83, 77, 97, 105, 110, 0, 0, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 95, 95, 105, 110, 112, 117, 116, 95, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, -0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 28, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 44, 0, -0, 0, 62, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 80, 83, 77, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, -0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 46, 0, 77, 17, 140, 0, 0, 0, 0, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 92, 11, 32, 4, 129, 248, 8, 0, 9, -26, 13, 45, 1, 80, 3, 0, 9, 12, 13, 91, 12, 129, 212, 36, 0, 0, 0, 38, 0, 77, 17, 128, 2, 0, 0, 100, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 69, 11, 32, 4, 36, 8, 0, 9, 12, 13, 68, 1, 80, 12, 36, 0, 0, 0, 0, 66, 0, 62, 17, 12, 16, -0, 0, 136, 0, 60, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, -28, 0, 8, 0, 0, 0, 2, 0, 78, 17, 110, 0, 77, 17, 128, 2, 0, 0, 252, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 86, 6, 8, 3, 36, 13, 50, 6, 2, 3, 84, 13, 46, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 64, 6, -18, 12, 28, 28, 8, 0, 9, 28, 13, 85, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 63, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, -0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, -0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, -0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 104, 3, 0, 0, 248, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 66, 0, -62, 17, 17, 16, 0, 0, 128, 0, 60, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 115, 38, 165, 252, 141, 197, 252, 40, -66, 140, 67, 235, 165, 151, 219, 186, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 169, 0, 0, 128, 80, 0, 0, 0, 169, 0, 0, 0, 116, 0, 0, 0, 169, 0, -0, 128, 116, 0, 0, 0, 169, 0, 0, 0, 144, 0, 0, 0, 169, 0, 0, 128, 144, 0, 0, 0, 169, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 128, 172, 0, 0, 0, 169, 0, 0, 0, 200, 0, 0, 0, 169, 0, 0, 128, 200, 0, 0, 0, 169, 0, 0, 0, 228, 0, 0, 0, 169, 0, -0, 128, 228, 0, 0, 0, 169, 0, 0, 0, 248, 0, 0, 0, 169, 0, 0, 128, 248, 0, 0, 0, 169, 0, 0, 0, 12, 1, 0, 0, 169, 0, 0, 128, 12, 1, 0, 0, 169, 0, 0, 0, 48, 1, 0, 0, 169, 0, 0, 128, 48, 1, 0, 0, 169, 0, 0, 0, 84, 1, 0, 0, 169, 0, -0, 128, 84, 1, 0, 0, 169, 0, 0, 0, 112, 1, 0, 0, 169, 0, 0, 128, 112, 1, 0, 0, 169, 0, 0, 0, 152, 1, 0, 0, 169, 0, 0, 128, 152, 1, 0, 0, 169, 0, 0, 0, 180, 1, 0, 0, 169, 0, 0, 128, 180, 1, 0, 0, 169, 0, 0, 0, 216, 1, 0, 0, 169, 0, -0, 128, 216, 1, 0, 0, 169, 0, 0, 0, 244, 1, 0, 0, 169, 0, 0, 128, 244, 1, 0, 0, 169, 0, 0, 0, 16, 2, 0, 0, 169, 0, 0, 128, 16, 2, 0, 0, 169, 0, 0, 0, 44, 2, 0, 0, 169, 0, 0, 128, 44, 2, 0, 0, 169, 0, 0, 0, 72, 2, 0, 0, 172, 0, -0, 128, 72, 2, 0, 0, 172, 0, 0, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, -50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, -50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 51, 0, 31, 0, 50, 0, 5, 0, 22, 0, 5, 0, 22, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 161, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 157, 0, 0, 0, 2, 16, -0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, -24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 0, 16, 0, 0, 3, 2, 224, 51, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, -0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 224, 51, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 80, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, -102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 16, 0, 84, 101, 120, 67, 111, 111, 114, 100, -95, 105, 100, 54, 50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 30, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 241, 10, 0, -1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 30, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, -80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, -50, 0, 13, 21, 3, 0, 0, 16, 0, 0, 8, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 243, 242, 241, 13, 21, 3, 0, 0, 16, 0, 0, 24, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 242, 241, 34, 0, 5, 21, 3, 0, 0, 0, 9, 16, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 243, 242, 241, 10, 0, 1, 18, 1, 0, 0, 0, 10, 16, 0, 0, 10, 0, 24, 21, 0, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, -0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 135, 91, 1, 0, 148, 225, 0, 0, 42, 235, 1, 0, 12, 226, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 95, 105, -100, 55, 52, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, -111, 114, 109, 95, 105, 100, 55, 51, 59, 13, 10, 125, 59, 13, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, -95, 105, 100, 49, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, -101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 59, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, -57, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, -83, 105, 122, 101, 95, 105, 100, 51, 51, 59, 13, 10, 125, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 95, 105, 100, 49, -54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 95, 105, 100, 49, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 95, 105, 100, 50, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, -68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 95, 105, 100, 50, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 95, 105, 100, 50, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 95, 105, -100, 50, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 95, 105, 100, 50, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 95, 105, 100, 51, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 95, 105, 100, 51, 50, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 95, 105, 100, 51, 52, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, -84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 95, 105, 100, 51, 53, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 95, 105, 100, 51, 54, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, -84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 95, 105, 100, 51, 55, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 95, 105, 100, 51, 56, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, -101, 51, 68, 49, 95, 105, 100, 51, 57, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 95, 105, 100, 52, 48, 59, 13, 10, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 95, 105, 100, 52, -49, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 51, 32, 13, -10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, -108, 101, 114, 95, 105, 100, 52, 52, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 53, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, -10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, -97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 54, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, -116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, -59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 125, 59, 13, 10, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 55, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, -67, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 56, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, -101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 57, -32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 48, 32, 13, 10, 123, -13, 10, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 53, 49, 32, 13, 10, 123, 13, 10, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 125, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 95, 105, -100, 53, 50, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 95, 105, 100, 53, 51, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 95, 105, 100, 53, 52, 59, 13, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 95, 105, 100, 53, 53, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 95, 105, 100, 53, 54, 59, 13, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 95, 105, 100, 53, 55, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 95, 105, 100, 53, 56, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 55, 95, 105, 100, 53, 57, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 95, 105, 100, 54, 48, 59, 13, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, -101, 114, 57, 95, 105, 100, 54, 49, 59, 13, 10, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, -52, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, -97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, -101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, -120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, -32, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, -115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, -40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 32, 32, -32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, -120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, -61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, -112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, -97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, -116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, -111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 105, -110, 111, 117, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, -112, 108, 101, 114, 95, 105, 100, 52, 50, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 41, 59, 13, 10, 125, 13, 10, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 105, 110, 111, 117, 116, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, -101, 97, 109, 115, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 125, 13, 10, 80, 83, 95, 79, 85, 84, 80, -85, 84, 32, 80, 83, 77, 97, 105, 110, 40, 80, 83, 95, 73, 78, 80, 85, 84, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, -10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 101, 97, 109, 115, 41, 59, 13, 10, 32, 32, 32, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 32, 61, -32, 40, 80, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 95, 105, 100, 50, 59, 13, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 86, 83, 77, 97, 105, 110, 40, 86, 83, 95, 73, 78, 80, 85, 84, 32, -95, 95, 105, 110, 112, 117, 116, 95, 95, 41, 13, 10, 123, 13, 10, 32, 32, 32, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 32, 61, 32, 40, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 41, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 95, 95, 105, 110, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 95, 95, 105, -110, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, -115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 41, 59, 13, 10, 32, 32, 32, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, -95, 32, 61, 32, 40, 86, 83, 95, 79, 85, 84, 80, 85, 84, 41, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, -67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 59, 13, 10, 32, 32, 32, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 59, 13, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 95, 111, 117, 116, 112, 117, 116, 95, 95, 59, 13, 10, 125, 13, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, +114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, +101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, +107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, +101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, +41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, +0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, -97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 26, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 0, 242, 241, 22, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 0, 22, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 104, -97, 100, 105, 110, 103, 95, 105, 100, 50, 0, 26, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 70, 111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 0, 242, 241, 22, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 109, 101, 100, 105, 97, 110, 95, 105, 100, 51, 0, 241, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, +97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, +99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, +116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, +101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, +101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, +83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, +32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, +48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, +116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, +73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, +97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, +59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, +32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, +110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, +32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 144, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 0, 99, +58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, +92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 207, 223, 61, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 39, 5, 143, 25, 213, 9, 0, 0, 1, 0, 0, +0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 25, 0, 0, 0, 1, 0, -0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, +32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, +48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 96, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 8, 16, 0, 0, 100, 0, 0, +0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, +17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, +0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, +0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, +17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, +117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, +0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, +0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, +0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, +0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 92, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 8, 12, 128, 128, 40, 8, 0, 13, 23, 1, 128, 140, 12, 128, 128, 0, +0, 42, 0, 77, 17, 4, 3, 0, 0, 88, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 40, 8, 0, 9, 33, 13, 82, 1, 128, 140, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, +0, 1, 0, 0, 0, 16, 1, 70, 50, 7, 101, 25, 7, 89, 250, 189, 40, 242, 8, 125, 92, 183, 48, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 110, 0, 0, +128, 100, 0, 0, 0, 110, 0, 0, 0, 120, 0, 0, 0, 110, 0, 0, 128, 120, 0, 0, 0, 110, 0, 0, 0, 140, 0, 0, 0, 105, 0, 0, 128, 140, 0, 0, 0, 105, 0, 0, 0, 172, 0, 0, 0, 105, 0, 0, 128, 172, 0, 0, 0, 105, 0, 0, 0, 204, 0, 0, 0, 105, 0, 0, +128, 204, 0, 0, 0, 105, 0, 0, 0, 236, 0, 0, 0, 105, 0, 0, 128, 236, 0, 0, 0, 105, 0, 0, 0, 12, 1, 0, 0, 110, 0, 0, 128, 12, 1, 0, 0, 110, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, +0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, +0, 85, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 180, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, +0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, +18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, +0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, +0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, +0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, +241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, +0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 37, 17, 0, 0, 0, 0, 140, 0, 0, 0, 1, 0, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 34, 0, 81, 17, 21, 16, -0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 34, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, +108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, +84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, +57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, +41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, +102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, +76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, +86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, +32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, +41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, +112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, +0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 99, 0, 108, 0, 255, 255, -255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, +0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, +105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, +0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, +105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 167, 196, 194, 94, 1, 0, 0, 0, 130, 226, 135, 64, 223, 172, 72, 66, 178, 126, 195, 54, 114, 89, 128, 215, 207, 0, -0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 115, 116, 114, 105, 100, 101, 46, 99, 111, 114, 101, 46, 97, 115, 115, 101, 116, 115, 46, 99, 111, 109, 112, 105, 108, 101, 114, 97, 112, 112, 92, 98, 105, 110, 92, 100, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, -115, 104, 97, 100, 101, 114, 95, 115, 112, 114, 105, 116, 101, 115, 105, 103, 110, 101, 100, 100, 105, 115, 116, 97, 110, 99, 101, 102, 105, 101, 108, 100, 102, 111, 110, 116, 115, 104, 97, 100, 101, 114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, -49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, -0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 0, 142, 14, 0, 63, 92, 15, 0, 0, 0, 76, 0, 0, 0, 32, 0, -0, 0, 44, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 9, 0, 8, 5, 0, 0, 0, 0, 0, 0, 44, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 83, 77, 97, 105, 110, 0, 110, 111, 110, 101, 0, 45, 186, 46, 241, 1, 0, 99, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, -0, 96, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 97, 115, 115, 101, 116, 115, 92, 83, 116, 114, 105, 100, 101, 46, 67, 111, 114, 101, 46, 65, 115, 115, 101, 116, 115, 46, 67, 111, 109, 112, 105, 108, 101, 114, 65, 112, -112, 92, 98, 105, 110, 92, 68, 101, 98, 117, 103, 92, 110, 101, 116, 52, 55, 50, 92, 108, 111, 103, 92, 115, 104, 97, 100, 101, 114, 95, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, -114, 95, 98, 57, 52, 56, 57, 99, 55, 102, 101, 53, 54, 52, 57, 48, 100, 54, 52, 49, 55, 56, 49, 49, 100, 98, 51, 49, 54, 57, 97, 56, 57, 57, 46, 104, 108, 115, 108, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 43, 1, 0, 0, 136, 2, 0, 0, 183, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 92, 22, -0, 0, 128, 0, 0, 0, 229, 20, 0, 0, 68, 7, 0, 0, 108, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 96, 0, 0, 0, 3, 0, 0, 0, 44, 0, 0, 0, 26, 0, 0, 0, 25, 0, 0, 0, 45, 0, 0, 0, 38, 0, 0, 0, 19, 0, -0, 0, 6, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, -0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 39, 0, 0, 0, 40, 0, 0, 0, 41, 0, -0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -864,12 +655,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, +68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -877,22 +671,58 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, +0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, +115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, +114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 204, 180, 142, 105, 1, 0, 0, 0, 165, 1, 241, 92, 160, 53, 1, 76, 186, 205, 211, 92, 206, 95, 190, 22, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, +110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, +116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 4, 0, +0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 236, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 192, 10, 0, 0, 128, 0, 0, 0, 213, 9, 0, 0, 124, 4, 0, +0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 0, 18, 0, 0, 0, 30, 0, 0, 0, 24, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, +0, 23, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, +0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 65, 0, 0, 119, 0, -0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 12, 0, -0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, -49, 48, 46, 49, 0, 171, 73, 83, 71, 78, 108, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 3, 3, 0, 0, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 67, 79, 76, 79, 82, 0, 171, 79, 83, 71, 78, 44, 0, -0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, +0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, +102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, +171, 1, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs new file mode 100644 index 0000000000..61d175a8fb --- /dev/null +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -0,0 +1,129 @@ +//------------------------------------------------------------------------------ +// +// Stride Effect Compiler File Generated: +// Effect [SpriteSignedDistanceFieldFontShader] +// +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +#if STRIDE_GRAPHICS_API_DIRECT3D12 + +namespace Stride.Graphics +{ + internal partial class SpriteSignedDistanceFieldFontShader + { + private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, +116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, +114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, +223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, +1, 75, 232, 212, 98, 177, 92, 143, 80, 82, 224, 27, 220, 221, 195, 119, 120, 0, 192, 9, 0, 0, 68, 88, 66, 67, 8, 194, 56, 206, 130, 168, 158, 248, 193, 94, 8, 161, 221, 107, 150, 96, 1, 0, 0, 0, 192, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, +0, 0, 224, 0, 0, 0, 192, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, +50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 216, 0, 0, 0, 36, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 248, 7, 0, 0, 96, 0, 0, 0, 254, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 224, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 245, 1, +0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, +33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, +255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 99, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, +184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, +0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, +8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, +0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, +24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 66, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 148, 1, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 160, 24, 11, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 48, 16, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, +114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, +109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, +33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 4, 0, +0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, 99, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 46, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, +2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 2, 0, +0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 43, 164, 50, 34, 0, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 136, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 8, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 34, 0, 0, +0, 40, 7, 2, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 8, 0, 0, 0, 74, 129, 26, 0, 0, 0, 74, 162, 16, 10, 4, 0, 0, 0, 0, 121, 24, 0, 0, 122, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 144, 9, 194, 112, 240, 56, 98, 123, 19, 11, 99, 155, +155, 32, 16, 201, 4, 129, 80, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 99, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 12, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, +185, 50, 152, 9, 2, 209, 76, 16, 20, 103, 130, 64, 60, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, +152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 1, 109, 16, 8, 138, 2, 220, 220, 4, 129, 232, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, +79, 82, 68, 19, 132, 166, 12, 38, 8, 141, 180, 33, 8, 38, 8, 13, 181, 97, 9, 196, 96, 12, 200, 160, 12, 204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 204, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 132, 51, 80, 3, 38, 83, 86, 95, 84, +97, 114, 103, 101, 116, 19, 132, 230, 12, 54, 44, 1, 27, 140, 65, 27, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 112, 131, 13, 195, 26, 188, 1, 64, 57, 152, 130, 147, 75, 163, 43, 155, 74, 59, 115, 43, 35, 35, 74, 155, 163, 11, 115, 27, 43, 51, 74, 43, 99, 35, 51, 122, 115, 163, +155, 66, 11, 35, 43, 147, 115, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 113, 0, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, +202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, +151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 65, 28, 0, 0, 0, 113, 32, 0, 0, 34, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 41, 107, 2, 72, 243, 195, 17, 240, +60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 0, 13, 151, 239, 60, 126, 128, 52, 64, 132, 249, 197, 109, 91, +193, 51, 92, 190, 243, 248, 84, 3, 68, 152, 95, 220, 182, 25, 84, 195, 229, 59, 143, 47, 77, 78, 68, 160, 212, 244, 80, 147, 95, 220, 54, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 103, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, +24, 56, 104, 144, 133, 65, 24, 88, 216, 136, 65, 2, 128, 32, 24, 56, 105, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 106, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 107, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 108, 208, 145, 65, 25, 96, +220, 136, 65, 2, 128, 32, 24, 68, 108, 128, 101, 102, 96, 6, 96, 48, 98, 144, 0, 32, 8, 6, 81, 27, 100, 221, 25, 156, 65, 24, 140, 24, 60, 0, 8, 130, 193, 212, 6, 88, 32, 32, 71, 150, 125, 223, 151, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 140, 24, 28, +0, 8, 130, 1, 21, 7, 28, 49, 140, 24, 28, 0, 8, 130, 1, 37, 7, 92, 65, 140, 24, 28, 0, 8, 130, 1, 53, 7, 94, 64, 140, 24, 28, 0, 8, 130, 1, 69, 7, 222, 16, 88, 224, 65, 96, 196, 192, 0, 64, 16, 12, 170, 58, 240, 130, 17, 3, 3, 0, 65, 48, 168, 236, 192, +11, 70, 12, 12, 0, 4, 193, 160, 186, 3, 111, 24, 49, 48, 0, 16, 4, 131, 10, 15, 192, 32, 176, 96, 128, 128, 5, 96, 32, 1, 19, 62, 9, 24, 34, 64, 192, 2, 129, 2, 35, 6, 6, 0, 130, 96, 80, 249, 65, 24, 4, 22, 6, 129, 4, 44, 40, 3, 8, 216, 16, 72, 192, 136, +64, 2, 22, 4, 18, 176, 47, 144, 128, 125, 130, 4, 236, 27, 36, 96, 31, 33, 129, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 246, 128, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 65, 15, 134, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 242, +64, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 1, 15, 2, 4, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 136, 128, 103, 144, 24, 53, 93, 2, 142, 232, 27, 153, 37, 11, 4, 182, 0, 17, 10, 0, 0, 68, 88, 66, 67, 143, 14, 115, 78, 42, 197, 186, 101, 82, 45, +55, 134, 208, 14, 83, 50, 1, 0, 0, 0, 17, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, 141, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, +0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 40, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 2, +0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, +0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, +88, 73, 76, 124, 7, 0, 0, 96, 0, 1, 0, 223, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 100, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 214, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, +16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, +174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, +76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, +4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, +0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, +19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, +0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, +115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, +208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, +134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, +0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 146, 35, 6, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, +41, 160, 2, 43, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 116, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, +1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, +176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 178, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 180, 9, 130, 210, 108, 8, +130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 101, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 13, 195, 39, 6, 101, 176, 97, 9, 180, 141, 235, 60, +194, 11, 56, 96, 195, 66, 104, 27, 7, 6, 30, 17, 6, 4, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 101, 12, 210, 96, 83, 131, 46, 12, 136, 48, 24, 3, 14, 216, 48, 156, 1, 26, 172, 193, 134, 193, 12, 216, 0, 160, 28, 76, 193, 201, 165, 209, +149, 77, 165, 157, 185, 149, 145, 17, 165, 205, 209, 133, 185, 141, 149, 25, 165, 149, 177, 145, 25, 189, 185, 209, 77, 161, 133, 145, 149, 201, 185, 88, 77, 53, 133, 165, 185, 125, 93, 201, 133, 193, 193, 149, 201, 109, 40, 42, 55, 104, 3, 10, 168, 194, 198, 102, 215, 230, 146, 70, 86, 230, 70, 55, +37, 88, 170, 144, 225, 185, 216, 149, 201, 205, 165, 189, 185, 77, 9, 152, 38, 100, 120, 46, 118, 97, 108, 118, 101, 114, 83, 2, 167, 14, 25, 158, 203, 28, 90, 24, 89, 153, 92, 211, 27, 89, 25, 219, 148, 32, 42, 67, 134, 231, 34, 87, 54, 247, 86, 39, 55, 86, 54, 55, 37, 152, 42, 145, +225, 185, 208, 229, 193, 149, 5, 185, 185, 189, 209, 133, 209, 165, 189, 185, 205, 77, 9, 176, 58, 100, 120, 46, 101, 110, 116, 114, 121, 80, 111, 105, 110, 116, 115, 83, 2, 55, 0, 113, 32, 0, 0, 29, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, +16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, +84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 0, 97, 32, 0, 0, 133, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 91, 100, 89, 15, 52, 98, 144, 0, 32, 8, 6, +11, 39, 93, 215, 19, 141, 24, 36, 0, 8, 130, 193, 210, 77, 23, 22, 73, 35, 6, 9, 0, 130, 96, 176, 120, 20, 150, 69, 211, 136, 65, 2, 128, 32, 24, 44, 95, 149, 105, 17, 53, 98, 144, 0, 32, 8, 6, 11, 24, 88, 218, 22, 85, 35, 6, 9, 0, 130, 96, 176, 132, 193, 21, 113, +149, 53, 98, 144, 0, 32, 8, 6, 139, 24, 96, 82, 87, 93, 35, 6, 9, 0, 130, 96, 176, 140, 65, 54, 121, 21, 54, 98, 144, 0, 32, 8, 6, 11, 25, 104, 212, 87, 101, 35, 6, 9, 0, 130, 96, 240, 144, 1, 117, 125, 223, 84, 97, 192, 225, 136, 193, 1, 128, 32, 24, 68, 101, 64, +9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 157, 1, 6, 21, 140, 1, 142, 24, 28, 0, 8, 130, 65, 196, 6, 91, 18, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 148, 27, 120, 80, 129, 26, 224, 136, 193, 1, 128, 32, 24, 68, 115, 32, 6, +80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 117, 64, 6, 80, 65, 28, 224, 136, 193, 1, 128, 32, 24, 68, 122, 144, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 96, 86, 24, 72, 192, 32, 49, 144, 128, 41, 99, 32, 1, 35, 200, 64, +2, 182, 153, 129, 4, 44, 40, 32, 96, 22, 26, 72, 192, 2, 3, 2, 22, 169, 129, 4, 44, 56, 32, 96, 12, 27, 72, 192, 2, 4, 2, 70, 6, 111, 32, 1, 11, 16, 8, 216, 23, 7, 18, 176, 0, 129, 128, 105, 115, 32, 1, 11, 16, 8, 88, 85, 7, 18, 176, 0, 129, 128, 181, 1, +30, 72, 192, 2, 4, 2, 134, 6, 122, 32, 1, 11, 16, 8, 216, 24, 240, 129, 4, 44, 64, 32, 96, 158, 31, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 180, 2, 46, 196, 194, 49, 98, 144, 0, 32, 8, 6, 146, 46, 152, 66, 43, 224, 2, 44, 20, 35, 6, 9, +0, 130, 96, 32, 233, 130, 41, 180, 2, 46, 188, 194, 48, 98, 144, 0, 32, 8, 6, 146, 46, 152, 66, 43, 224, 130, 43, 4, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 224, 2, 46, 196, 130, 40, 140, 24, 36, 0, 8, 130, 129, 164, 11, 166, 128, 11, 184, 0, 11, 161, 48, 98, 144, 0, +32, 8, 6, 146, 46, 152, 194, 45, 224, 66, 44, 240, 193, 136, 65, 2, 128, 32, 24, 72, 186, 96, 10, 183, 128, 11, 176, 176, 7, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 220, 2, 46, 188, 130, 30, 140, 24, 36, 0, 8, 130, 129, 164, 11, 166, 112, 11, 184, 224, 10, 121, 128, 0, 0, +0, 0, 0, 1, + }; + } +} + +#endif diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 529581b831..dfa477b04b 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -1,174 +1,318 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteSignedDistanceFieldFontShader] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders093.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { internal partial class SpriteSignedDistanceFieldFontShader { private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, -68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, -0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, -83, 104, 97, 100, 101, 114, 1, 182, 30, 36, 111, 246, 180, 175, 213, 1, 191, 88, 116, 137, 233, 235, 105, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 103, 177, 47, 3, 221, 157, 52, 231, 107, 111, 207, 181, 23, 175, 186, 140, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 1, -227, 114, 5, 111, 246, 192, 110, 218, 184, 233, 136, 65, 74, 143, 117, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 145, 192, 234, 138, 174, 10, 69, 202, 0, 87, 138, 64, 132, 250, 54, 7, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 102, 5, 246, 130, -48, 38, 110, 255, 43, 200, 180, 232, 16, 46, 222, 107, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 172, 15, 189, 95, 73, 121, 86, 178, 142, 238, 98, 20, 99, 98, 230, 42, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, -57, 250, 187, 65, 84, 15, 206, 146, 247, 11, 72, 105, 103, 49, 132, 30, 0, 109, 11, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 2, 0, 0, 0, 0, 5, 67, 79, 76, -79, 82, 0, 2, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 28, 11, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 90, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, -0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 11, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 15, 0, 0, 0, 21, 0, -0, 0, 26, 0, 0, 0, 70, 0, 0, 0, 76, 0, 0, 0, 79, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, -0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 9, 0, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 5, 0, 5, 0, 11, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 15, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 21, 0, -0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 26, 0, 0, 0, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 0, 5, 0, 5, 0, 29, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 29, 0, 0, 0, 0, 0, -0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 29, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 29, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, -105, 100, 55, 52, 0, 0, 6, 0, 8, 0, 29, 0, 0, 0, 3, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 5, 0, 4, 0, 31, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 45, 0, 0, 0, 80, 101, -114, 68, 114, 97, 119, 0, 6, 0, 9, 0, 45, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 5, 0, 3, 0, 47, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 53, 0, 0, 0, 86, 83, -95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 53, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 7, 0, 53, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, -100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 53, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 5, 0, 5, 0, 55, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 68, 0, 0, 0, 103, 108, 95, 80, 101, 114, -86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 68, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 7, 0, 68, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, -7, 0, 68, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, 101, 0, 6, 0, 7, 0, 68, 0, 0, 0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 70, 0, 0, 0, 0, 0, -0, 0, 5, 0, 5, 0, 76, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 79, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 89, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, -4, 0, 15, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 21, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 26, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 45, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 72, 0, -5, 0, 45, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 45, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 3, 0, 45, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 47, 0, 0, 0, 34, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 47, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 68, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 68, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 68, 0, -0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 72, 0, 5, 0, 68, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 68, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 76, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 79, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 89, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 89, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, -0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 5, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, -0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 21, 0, 4, 0, 12, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 14, 0, 0, 0, 1, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 14, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 19, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 20, 0, 0, 0, 1, 0, 0, 0, 8, 0, -0, 0, 59, 0, 4, 0, 20, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 14, 0, 0, 0, 26, 0, 0, 0, 1, 0, -0, 0, 30, 0, 6, 0, 29, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 30, 0, 0, 0, 7, 0, 0, 0, 29, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 41, 0, 0, 0, 3, 0, 0, 0, 24, 0, 4, 0, 44, 0, -0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 45, 0, 0, 0, 44, 0, 0, 0, 32, 0, 4, 0, 46, 0, 0, 0, 2, 0, 0, 0, 45, 0, 0, 0, 59, 0, 4, 0, 46, 0, 0, 0, 47, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 48, 0, 0, 0, 2, 0, -0, 0, 44, 0, 0, 0, 30, 0, 5, 0, 53, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 54, 0, 0, 0, 7, 0, 0, 0, 53, 0, 0, 0, 21, 0, 4, 0, 65, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 65, 0, -0, 0, 66, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, 0, 67, 0, 0, 0, 6, 0, 0, 0, 66, 0, 0, 0, 30, 0, 6, 0, 68, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 3, 0, 0, 0, 68, 0, -0, 0, 59, 0, 4, 0, 69, 0, 0, 0, 70, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 73, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 75, 0, 0, 0, 76, 0, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 73, 0, 0, 0, 79, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 88, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 59, 0, 4, 0, 88, 0, -0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 30, 0, 0, 0, 31, 0, -0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 54, 0, 0, 0, 55, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 18, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 18, 0, -0, 0, 16, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 24, 0, 0, 0, 22, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 27, 0, -0, 0, 26, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 28, 0, 0, 0, 27, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 32, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, -0, 0, 33, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 34, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 34, 0, 0, 0, 33, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 35, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 61, 0, -4, 0, 8, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 36, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 38, 0, 0, 0, 11, 0, 0, 0, 13, 0, -0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 40, 0, 0, 0, 31, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 40, 0, 0, 0, 39, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 42, 0, 0, 0, 31, 0, -0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 65, 0, 5, 0, 48, 0, 0, 0, 49, 0, 0, 0, 47, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 44, 0, 0, 0, 50, 0, 0, 0, 49, 0, 0, 0, 144, 0, 5, 0, 7, 0, -0, 0, 51, 0, 0, 0, 43, 0, 0, 0, 50, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 52, 0, 0, 0, 31, 0, 0, 0, 41, 0, 0, 0, 62, 0, 3, 0, 52, 0, 0, 0, 51, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 56, 0, 0, 0, 31, 0, 0, 0, 41, 0, -0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 57, 0, 0, 0, 56, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 58, 0, 0, 0, 55, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 58, 0, 0, 0, 57, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 59, 0, 0, 0, 31, 0, -0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 61, 0, 0, 0, 55, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 61, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 62, 0, -0, 0, 31, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 64, 0, 0, 0, 55, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 64, 0, 0, 0, 63, 0, 0, 0, 65, 0, 5, 0, 17, 0, -0, 0, 71, 0, 0, 0, 55, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 72, 0, 0, 0, 71, 0, 0, 0, 65, 0, 5, 0, 73, 0, 0, 0, 74, 0, 0, 0, 70, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 74, 0, 0, 0, 72, 0, 0, 0, 65, 0, -5, 0, 23, 0, 0, 0, 77, 0, 0, 0, 55, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 78, 0, 0, 0, 77, 0, 0, 0, 62, 0, 3, 0, 76, 0, 0, 0, 78, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 80, 0, 0, 0, 55, 0, 0, 0, 13, 0, -0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 62, 0, 3, 0, 79, 0, 0, 0, 81, 0, 0, 0, 65, 0, 6, 0, 82, 0, 0, 0, 83, 0, 0, 0, 70, 0, 0, 0, 25, 0, 0, 0, 66, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 84, 0, -0, 0, 83, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 85, 0, 0, 0, 84, 0, 0, 0, 65, 0, 6, 0, 82, 0, 0, 0, 86, 0, 0, 0, 70, 0, 0, 0, 25, 0, 0, 0, 66, 0, 0, 0, 62, 0, 3, 0, 86, 0, 0, 0, 85, 0, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 0, 5, 0, 0, 0, 1, 178, 190, 96, 131, 135, 43, 6, 26, 12, 218, 201, 50, 186, 217, 159, 118, 0, 202, 20, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 3, 0, 0, 0, 17, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 128, 20, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 199, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, -0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 9, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 166, 0, 0, 0, 170, -0, 0, 0, 173, 0, 0, 0, 195, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 8, 0, 12, 0, 0, 0, 109, 101, 100, 105, 97, -110, 95, 105, 100, 51, 40, 102, 49, 59, 102, 49, 59, 102, 49, 59, 0, 0, 0, 0, 5, 0, 3, 0, 9, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 10, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 11, 0, 0, 0, 98, 0, 0, 0, 5, 0, 10, 0, 21, 0, 0, 0, 70, -111, 110, 116, 67, 111, 108, 111, 114, 95, 105, 100, 52, 40, 118, 102, 52, 59, 118, 102, 52, 59, 118, 102, 52, 59, 102, 49, 59, 0, 0, 0, 5, 0, 6, 0, 17, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 18, 0, 0, 0, 116, -101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 19, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 20, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 5, 0, 24, 0, 0, 0, 80, -83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 24, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 24, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, -0, 7, 0, 24, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 13, 0, 28, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, -45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 5, 0, 4, 0, 27, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 13, 0, 31, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 53, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, -69, 65, 77, 83, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 5, 0, 4, 0, 30, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 7, 0, 48, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, -0, 6, 0, 50, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 6, 0, 54, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 55, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, -0, 4, 0, 60, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 64, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 69, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 73, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, -110, 0, 0, 5, 0, 4, 0, 78, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 5, 0, 92, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 6, 0, 98, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, -0, 5, 0, 102, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 111, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 6, 0, 130, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, -0, 0, 0, 5, 0, 6, 0, 134, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, 4, 0, 146, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 152, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 153, -0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 161, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, -0, 8, 0, 161, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 7, 0, 161, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 161, -0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 5, 0, 5, 0, 163, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 166, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 170, -0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 6, 0, 173, 0, 0, 0, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 4, 0, 176, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 183, 0, 0, 0, 112, -97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 188, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 190, 0, 0, 0, 95, -48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 195, 0, 0, 0, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 198, 0, 0, 0, 78, 111, 83, 97, 109, -112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 130, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 130, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 134, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 134, 0, 0, 0, 33, -0, 0, 0, 21, 0, 0, 0, 71, 0, 4, 0, 166, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 170, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 173, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 195, 0, 0, 0, 30, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 198, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 198, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, -0, 0, 0, 32, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 33, 0, 6, 0, 8, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 23, 0, 4, 0, 14, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 32, -0, 4, 0, 15, 0, 0, 0, 7, 0, 0, 0, 14, 0, 0, 0, 33, 0, 7, 0, 16, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 23, 0, 4, 0, 23, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 5, 0, 24, -0, 0, 0, 23, 0, 0, 0, 14, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 25, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 33, 0, 4, 0, 26, 0, 0, 0, 14, 0, 0, 0, 25, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 43, -0, 4, 0, 6, 0, 0, 0, 46, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 6, 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 6, 0, 0, 0, 51, 0, 0, 0, 205, 204, 204, 62, 21, 0, 4, 0, 56, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, -0, 4, 0, 56, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 56, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 56, 0, 0, 0, 65, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 76, 0, 0, 0, 154, 153, 89, 63, 20, -0, 2, 0, 88, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 6, 0, 0, 0, 112, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 14, 0, 0, 0, 120, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, -0, 0, 0, 25, 0, 9, 0, 128, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 129, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 59, 0, 4, 0, 129, 0, 0, 0, 130, -0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 132, 0, 0, 0, 32, 0, 4, 0, 133, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 136, 0, 0, 0, 128, 0, 0, 0, 21, 0, 4, 0, 138, -0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 140, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 150, 0, 0, 0, 1, 0, 0, 0, 44, 0, 7, 0, 14, -0, 0, 0, 151, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 45, 0, 0, 0, 112, 0, 0, 0, 30, 0, 5, 0, 161, 0, 0, 0, 14, 0, 0, 0, 23, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 162, 0, 0, 0, 7, 0, 0, 0, 161, 0, 0, 0, 43, 0, 4, 0, 138, -0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 165, 0, 0, 0, 1, 0, 0, 0, 14, 0, 0, 0, 59, 0, 4, 0, 165, 0, 0, 0, 166, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 169, 0, 0, 0, 1, 0, 0, 0, 23, 0, 0, 0, 59, 0, 4, 0, 169, -0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 165, 0, 0, 0, 173, 0, 0, 0, 1, 0, 0, 0, 30, 0, 3, 0, 188, 0, 0, 0, 14, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 7, 0, 0, 0, 188, 0, 0, 0, 32, 0, 4, 0, 194, 0, 0, 0, 3, -0, 0, 0, 14, 0, 0, 0, 59, 0, 4, 0, 194, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 198, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, -0, 0, 0, 59, 0, 4, 0, 162, 0, 0, 0, 163, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 25, 0, 0, 0, 176, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 25, 0, 0, 0, 183, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 190, 0, 0, 0, 7, -0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 168, 0, 0, 0, 163, 0, 0, 0, 164, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 171, 0, 0, 0, 170, -0, 0, 0, 65, 0, 5, 0, 140, 0, 0, 0, 172, 0, 0, 0, 163, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 172, 0, 0, 0, 171, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 175, 0, 0, 0, 163, -0, 0, 0, 139, 0, 0, 0, 62, 0, 3, 0, 175, 0, 0, 0, 174, 0, 0, 0, 65, 0, 5, 0, 140, 0, 0, 0, 177, 0, 0, 0, 163, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 65, 0, 5, 0, 140, 0, 0, 0, 179, -0, 0, 0, 176, 0, 0, 0, 139, 0, 0, 0, 62, 0, 3, 0, 179, 0, 0, 0, 178, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 180, 0, 0, 0, 163, 0, 0, 0, 164, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 65, 0, 5, 0, 15, -0, 0, 0, 182, 0, 0, 0, 176, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 182, 0, 0, 0, 181, 0, 0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 184, 0, 0, 0, 176, 0, 0, 0, 62, 0, 3, 0, 183, 0, 0, 0, 184, 0, 0, 0, 57, 0, 5, 0, 14, 0, 0, 0, 185, -0, 0, 0, 31, 0, 0, 0, 183, 0, 0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 186, 0, 0, 0, 183, 0, 0, 0, 62, 0, 3, 0, 176, 0, 0, 0, 186, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 187, 0, 0, 0, 176, 0, 0, 0, 164, 0, 0, 0, 62, 0, 3, 0, 187, -0, 0, 0, 185, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 191, 0, 0, 0, 176, 0, 0, 0, 164, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 192, 0, 0, 0, 191, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 193, 0, 0, 0, 190, 0, 0, 0, 139, 0, 0, 0, 62, -0, 3, 0, 193, 0, 0, 0, 192, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 196, 0, 0, 0, 190, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 197, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 195, 0, 0, 0, 197, 0, 0, 0, 253, 0, 1, 0, 56, -0, 1, 0, 54, 0, 5, 0, 6, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 9, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 10, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 11, 0, 0, 0, 248, 0, 2, 0, 13, -0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 61, -0, 4, 0, 6, 0, 0, 0, 36, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 37, 0, 0, 0, 10, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 38, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 61, 0, 4, 0, 6, -0, 0, 0, 39, 0, 0, 0, 11, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 40, 0, 0, 0, 1, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 39, 0, 0, 0, 12, 0, 7, 0, 6, 0, 0, 0, 41, 0, 0, 0, 1, 0, 0, 0, 40, 0, 0, 0, 35, 0, 0, 0, 40, -0, 0, 0, 254, 0, 2, 0, 41, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 14, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 17, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 18, 0, 0, 0, 55, 0, 3, 0, 15, -0, 0, 0, 19, 0, 0, 0, 55, 0, 3, 0, 7, 0, 0, 0, 20, 0, 0, 0, 248, 0, 2, 0, 22, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 48, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 50, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, -0, 0, 0, 54, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 55, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 60, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 64, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, -0, 0, 0, 69, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 73, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 78, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 92, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, -0, 0, 0, 98, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 102, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 111, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 12, 0, 8, 0, 6, -0, 0, 0, 47, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 46, 0, 0, 0, 62, 0, 3, 0, 20, 0, 0, 0, 47, 0, 0, 0, 62, 0, 3, 0, 48, 0, 0, 0, 49, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 52, 0, 0, 0, 20, -0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 53, 0, 0, 0, 51, 0, 0, 0, 52, 0, 0, 0, 62, 0, 3, 0, 50, 0, 0, 0, 53, 0, 0, 0, 65, 0, 5, 0, 7, 0, 0, 0, 58, 0, 0, 0, 17, 0, 0, 0, 57, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 59, -0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 55, 0, 0, 0, 59, 0, 0, 0, 65, 0, 5, 0, 7, 0, 0, 0, 62, 0, 0, 0, 17, 0, 0, 0, 61, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 62, 0, 3, 0, 60, 0, 0, 0, 63, -0, 0, 0, 65, 0, 5, 0, 7, 0, 0, 0, 66, 0, 0, 0, 17, 0, 0, 0, 65, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 67, 0, 0, 0, 66, 0, 0, 0, 62, 0, 3, 0, 64, 0, 0, 0, 67, 0, 0, 0, 57, 0, 7, 0, 6, 0, 0, 0, 68, 0, 0, 0, 12, -0, 0, 0, 55, 0, 0, 0, 60, 0, 0, 0, 64, 0, 0, 0, 62, 0, 3, 0, 54, 0, 0, 0, 68, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 70, 0, 0, 0, 54, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 71, 0, 0, 0, 50, 0, 0, 0, 131, 0, 5, 0, 6, -0, 0, 0, 72, 0, 0, 0, 70, 0, 0, 0, 71, 0, 0, 0, 62, 0, 3, 0, 69, 0, 0, 0, 72, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 74, 0, 0, 0, 69, 0, 0, 0, 209, 0, 4, 0, 6, 0, 0, 0, 75, 0, 0, 0, 74, 0, 0, 0, 133, 0, 5, 0, 6, -0, 0, 0, 77, 0, 0, 0, 75, 0, 0, 0, 76, 0, 0, 0, 62, 0, 3, 0, 73, 0, 0, 0, 77, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 79, 0, 0, 0, 73, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 61, 0, 4, 0, 6, -0, 0, 0, 81, 0, 0, 0, 73, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 82, 0, 0, 0, 69, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 83, 0, 0, 0, 1, 0, 0, 0, 49, 0, 0, 0, 80, 0, 0, 0, 81, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 78, -0, 0, 0, 83, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 84, 0, 0, 0, 78, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 85, 0, 0, 0, 78, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 86, 0, 0, 0, 85, 0, 0, 0, 84, 0, 0, 0, 62, 0, 3, 0, 78, -0, 0, 0, 86, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 87, 0, 0, 0, 20, 0, 0, 0, 186, 0, 5, 0, 88, 0, 0, 0, 89, 0, 0, 0, 87, 0, 0, 0, 45, 0, 0, 0, 247, 0, 3, 0, 91, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 89, 0, 0, 0, 90, -0, 0, 0, 91, 0, 0, 0, 248, 0, 2, 0, 90, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 93, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 94, 0, 0, 0, 20, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 96, 0, 0, 0, 94, 0, 0, 0, 95, -0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 97, 0, 0, 0, 93, 0, 0, 0, 96, 0, 0, 0, 62, 0, 3, 0, 92, 0, 0, 0, 97, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 99, 0, 0, 0, 54, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 100, 0, 0, 0, 92, -0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 101, 0, 0, 0, 99, 0, 0, 0, 100, 0, 0, 0, 62, 0, 3, 0, 98, 0, 0, 0, 101, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 103, 0, 0, 0, 48, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 104, 0, 0, 0, 98, -0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 105, 0, 0, 0, 103, 0, 0, 0, 104, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 106, 0, 0, 0, 98, 0, 0, 0, 209, 0, 4, 0, 6, 0, 0, 0, 107, 0, 0, 0, 106, 0, 0, 0, 136, 0, 5, 0, 6, 0, 0, 0, 108, -0, 0, 0, 105, 0, 0, 0, 107, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 109, 0, 0, 0, 92, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 110, 0, 0, 0, 108, 0, 0, 0, 109, 0, 0, 0, 62, 0, 3, 0, 102, 0, 0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 6, -0, 0, 0, 113, 0, 0, 0, 102, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 114, 0, 0, 0, 1, 0, 0, 0, 49, 0, 0, 0, 45, 0, 0, 0, 112, 0, 0, 0, 113, 0, 0, 0, 62, 0, 3, 0, 111, 0, 0, 0, 114, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 115, -0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 116, 0, 0, 0, 18, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 117, 0, 0, 0, 111, 0, 0, 0, 80, 0, 7, 0, 14, 0, 0, 0, 118, 0, 0, 0, 117, 0, 0, 0, 117, 0, 0, 0, 117, 0, 0, 0, 117, -0, 0, 0, 12, 0, 8, 0, 14, 0, 0, 0, 119, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 115, 0, 0, 0, 116, 0, 0, 0, 118, 0, 0, 0, 62, 0, 3, 0, 18, 0, 0, 0, 119, 0, 0, 0, 249, 0, 2, 0, 91, 0, 0, 0, 248, 0, 2, 0, 91, 0, 0, 0, 61, -0, 4, 0, 14, 0, 0, 0, 121, 0, 0, 0, 18, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 122, 0, 0, 0, 78, 0, 0, 0, 80, 0, 7, 0, 14, 0, 0, 0, 123, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 12, 0, 8, 0, 14, -0, 0, 0, 124, 0, 0, 0, 1, 0, 0, 0, 46, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 123, 0, 0, 0, 62, 0, 3, 0, 17, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 125, 0, 0, 0, 17, 0, 0, 0, 254, 0, 2, 0, 125, 0, 0, 0, 56, -0, 1, 0, 54, 0, 5, 0, 14, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 55, 0, 3, 0, 25, 0, 0, 0, 27, 0, 0, 0, 248, 0, 2, 0, 29, 0, 0, 0, 61, 0, 4, 0, 128, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 61, 0, 4, 0, 132, -0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 86, 0, 5, 0, 136, 0, 0, 0, 137, 0, 0, 0, 131, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 140, 0, 0, 0, 141, 0, 0, 0, 27, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 23, 0, 0, 0, 142, 0, 0, 0, 141, -0, 0, 0, 87, 0, 5, 0, 14, 0, 0, 0, 143, 0, 0, 0, 137, 0, 0, 0, 142, 0, 0, 0, 254, 0, 2, 0, 143, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 14, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 55, 0, 3, 0, 25, 0, 0, 0, 30, -0, 0, 0, 248, 0, 2, 0, 32, 0, 0, 0, 59, 0, 4, 0, 25, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 152, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, -0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 7, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 147, 0, 0, 0, 30, 0, 0, 0, 62, 0, 3, 0, 146, 0, 0, 0, 147, 0, 0, 0, 57, 0, 5, 0, 14, 0, 0, 0, 148, -0, 0, 0, 28, 0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 24, 0, 0, 0, 149, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 30, 0, 0, 0, 149, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 154, 0, 0, 0, 30, -0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 155, 0, 0, 0, 154, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 45, 0, 0, 0, 57, 0, 8, 0, 14, -0, 0, 0, 158, 0, 0, 0, 21, 0, 0, 0, 152, 0, 0, 0, 153, 0, 0, 0, 156, 0, 0, 0, 157, 0, 0, 0, 254, 0, 2, 0, 158, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, +116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, +114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, +223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, +1, 131, 237, 166, 246, 238, 248, 125, 128, 31, 77, 41, 72, 186, 209, 157, 207, 0, 128, 33, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 187, 0, 0, 0, 71, 76, 83, 76, 46, 115, +116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 83, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 71, 1, 0, 0, 73, 1, 0, 0, 69, 1, 0, 0, 79, 1, +0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 122, 1, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 104, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 93, 1, 0, 0, 96, 1, 0, 0, 97, 1, 0, 0, 92, 1, 0, 0, 94, 1, 0, 0, 98, 1, +0, 0, 103, 1, 0, 0, 111, 0, 0, 0, 122, 1, 0, 0, 16, 0, 3, 0, 83, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, +112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, +0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, +119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, +120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 175, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, +11, 0, 176, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 179, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 180, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 181, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 182, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 197, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, +67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 200, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 204, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, +0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 97, 120, 105, 115, 68, 105, +115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 214, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, +116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 233, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 236, 0, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 250, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 247, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, +0, 0, 5, 0, 5, 0, 253, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 3, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, +5, 0, 7, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 248, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, +13, 0, 39, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 0, 5, 0, 4, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 70, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 69, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 71, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, +7, 0, 74, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 73, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 75, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, +0, 0, 6, 0, 6, 0, 75, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 76, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, +0, 0, 6, 0, 6, 0, 76, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 77, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 77, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 77, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 77, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 80, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, +116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 15, 0, 83, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 8, 0, 92, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 93, 1, 0, 0, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 95, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 94, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, +6, 0, 96, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 97, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 98, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, +0, 0, 5, 0, 5, 0, 99, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 99, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 100, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 100, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 86, 83, +95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 101, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 101, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, +6, 0, 101, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 101, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 102, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, +95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 103, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 104, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 111, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 120, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 5, 0, 9, 0, 121, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 122, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, +0, 0, 71, 0, 4, 0, 69, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 71, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 71, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 73, 1, +0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 73, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 92, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 93, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, +6, 0, 93, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 94, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 94, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, +4, 0, 96, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 96, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 97, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 97, 1, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 98, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 98, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 120, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 120, 1, +0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 3, 0, +0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 6, 0, 0, 0, 35, 0, +0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, +0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, +0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, +4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, +0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, +0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, +0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, +4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, +0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, +0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 179, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 178, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 179, 0, +0, 0, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 7, 0, 195, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 179, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 43, 0, +4, 0, 4, 0, 0, 0, 206, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 211, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, +4, 0, 133, 0, 0, 0, 223, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 236, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 64, 43, 0, +4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 70, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 72, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, +4, 0, 74, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 75, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 76, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 77, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, +4, 0, 78, 1, 0, 0, 6, 0, 0, 0, 77, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 81, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 32, 0, +4, 0, 95, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 99, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 101, 1, 0, 0, 3, 0, +0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 6, 0, 0, 0, 101, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 120, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, +0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 121, 1, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, +4, 0, 121, 1, 0, 0, 122, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 69, 1, 0, 0, 3, 0, 0, 0, 59, 0, +4, 0, 72, 1, 0, 0, 71, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 78, 1, 0, 0, 79, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 92, 1, 0, 0, 3, 0, 0, 0, 59, 0, +4, 0, 72, 1, 0, 0, 93, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 94, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 96, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 97, 1, 0, 0, 1, 0, 0, 0, 59, 0, +4, 0, 70, 1, 0, 0, 98, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 103, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, +0, 0, 128, 0, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, +0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, +5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 39, 1, 0, 0, 62, 0, +3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, +5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, +0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 55, 0, +3, 0, 179, 0, 0, 0, 180, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 181, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 182, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 185, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 186, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 188, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 189, 0, +0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 190, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 188, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 182, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 192, 0, 0, 0, 187, 0, +0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 193, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 186, 0, 0, 0, 192, 0, 0, 0, 254, 0, 2, 0, 193, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, +0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 197, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 198, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 199, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 200, 0, 0, 0, 248, 0, 2, 0, 201, 0, +0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 208, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 210, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 215, 0, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 222, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 229, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 233, 0, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 253, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 7, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 204, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 207, 0, 0, 0, 187, 0, +0, 0, 43, 0, 0, 0, 202, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 207, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 200, 0, 0, 0, 131, 0, 5, 0, 4, 0, +0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, 0, 210, 0, 0, 0, 213, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 216, 0, 0, 0, 62, 0, +3, 0, 215, 0, 0, 0, 217, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 220, 0, 0, 0, 197, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 221, 0, 0, 0, 65, 0, 5, 0, 179, 0, +0, 0, 224, 0, 0, 0, 197, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, 0, 224, 0, 0, 0, 62, 0, 3, 0, 222, 0, 0, 0, 225, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 228, 0, 0, 0, 175, 0, 0, 0, 215, 0, 0, 0, 218, 0, +0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 230, 0, +0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 0, 0, 0, 229, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 235, 0, +0, 0, 236, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 237, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 233, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 233, 0, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 243, 0, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 243, 0, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 244, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 245, 0, 0, 0, 238, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 246, 0, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 249, 0, 0, 0, 200, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 247, 0, 3, 0, 248, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 252, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 248, 0, +2, 0, 247, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 255, 0, 0, 0, 200, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 129, 0, 5, 0, 4, 0, +0, 0, 2, 1, 0, 0, 254, 0, 0, 0, 1, 1, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 2, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 5, 1, 0, 0, 253, 0, 0, 0, 131, 0, 5, 0, 4, 0, +0, 0, 6, 1, 0, 0, 4, 1, 0, 0, 5, 1, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 6, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 3, 1, 0, 0, 133, 0, 5, 0, 4, 0, +0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 12, 1, 0, 0, 11, 1, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 13, 1, 0, 0, 10, 1, 0, 0, 12, 1, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 253, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 15, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 1, 0, 0, 204, 0, +0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 18, 1, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 1, 0, 0, 7, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 20, 1, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 19, 1, +0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 20, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 21, 1, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 1, 0, 0, 16, 1, 0, 0, 80, 0, +7, 0, 3, 0, 0, 0, 24, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 25, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 198, 0, +0, 0, 25, 1, 0, 0, 249, 0, 2, 0, 248, 0, 0, 0, 248, 0, 2, 0, 248, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 26, 1, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 27, 1, 0, 0, 198, 0, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 238, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 30, 1, 0, 0, 187, 0, 0, 0, 46, 0, +0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 197, 0, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 31, 1, 0, 0, 197, 0, 0, 0, 254, 0, 2, 0, 31, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 39, 1, +0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 46, 1, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 55, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 61, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 65, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 54, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 54, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 59, 1, 0, 0, 79, 1, 0, 0, 81, 1, +0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, 60, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 64, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 61, 1, +0, 0, 64, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 62, 1, 0, 0, 57, 0, 8, 0, 3, 0, 0, 0, 68, 1, 0, 0, 176, 0, 0, 0, 51, 1, 0, 0, 55, 1, 0, 0, 61, 1, 0, 0, 65, 1, 0, 0, 254, 0, 2, 0, 68, 1, 0, 0, 56, 0, 1, 0, 54, 0, +5, 0, 28, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 84, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 85, 1, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 86, 1, 0, 0, 71, 1, 0, 0, 62, 0, +3, 0, 85, 1, 0, 0, 86, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 87, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 88, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 87, 1, 0, 0, 88, 1, 0, 0, 57, 0, 4, 0, 28, 0, +0, 0, 89, 1, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 91, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 69, 1, 0, 0, 91, 1, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 104, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 105, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 106, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 107, 1, 0, 0, 93, 1, +0, 0, 62, 0, 3, 0, 106, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 108, 1, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 109, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 109, 1, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 110, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 112, 1, 0, 0, 97, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 112, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 113, 1, 0, 0, 112, 0, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 114, 1, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 115, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 115, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 82, 1, +0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 117, 1, 0, 0, 116, 1, 0, 0, 62, 0, 3, 0, 94, 1, 0, 0, 117, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 118, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 119, 1, 0, 0, 118, 1, +0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 119, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 131, 237, 166, 246, 238, 248, 125, 128, 31, 77, 41, 72, 186, 209, 157, 207, +0, 128, 33, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 187, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, +0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 83, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 71, 1, 0, 0, 73, 1, 0, 0, 69, 1, 0, 0, 79, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 122, 1, 0, 0, 15, 0, 16, +0, 0, 0, 0, 0, 104, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 93, 1, 0, 0, 96, 1, 0, 0, 97, 1, 0, 0, 92, 1, 0, 0, 94, 1, 0, 0, 98, 1, 0, 0, 103, 1, 0, 0, 111, 0, 0, 0, 122, 1, 0, 0, 16, 0, 3, +0, 83, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, +0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, +0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, +0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, +105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 10, 0, 175, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 176, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 179, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 180, 0, 0, 0, 114, 0, 0, +0, 5, 0, 3, 0, 181, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 182, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 197, 0, 0, 0, 115, 97, 109, +112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 200, 0, 0, 0, 98, 111, 114, +100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 204, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, +115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 211, 0, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 214, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, +95, 50, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 233, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, +0, 238, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 250, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 247, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 253, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, +97, 110, 99, 101, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 3, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 7, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, +0, 5, 0, 6, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 248, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 39, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, +100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, +0, 5, 0, 7, 0, 70, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 69, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 72, 1, 0, +0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 71, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 74, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, +108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 73, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 75, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 75, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 76, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 76, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 77, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 77, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 77, 1, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 77, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 5, 0, 5, 0, 79, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 80, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, +95, 49, 0, 0, 0, 5, 0, 15, 0, 83, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 5, 0, 8, 0, 92, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 93, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 95, 1, 0, +0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 94, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 96, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, +105, 111, 110, 0, 0, 5, 0, 5, 0, 97, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 98, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 99, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, +84, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 99, 1, 0, 0, 2, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 100, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 100, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 100, 1, 0, +0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 101, 1, 0, +0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 101, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 101, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 0, 0, 6, 0, 5, 0, 101, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 102, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 103, 1, 0, +0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 104, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 111, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 120, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, +116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 121, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 122, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 69, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 71, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 71, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 73, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 73, 1, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 92, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 93, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 93, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 94, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 94, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 96, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, +0, 96, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 97, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 97, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 98, 1, 0, +0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 98, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 120, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, +0, 120, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, +0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 7, 0, 0, +0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, +0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, +0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, +0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, +0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, +0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, +0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, +0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, +0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, +0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 179, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 178, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, +0, 33, 0, 7, 0, 195, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 179, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 206, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, +0, 4, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 211, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 223, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, +0, 4, 0, 0, 0, 236, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, +0, 4, 0, 0, 0, 63, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 70, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 72, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 74, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, +0, 75, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 76, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 77, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 78, 1, 0, 0, 6, 0, 0, 0, 77, 1, 0, 0, 43, 0, 4, +0, 133, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 81, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 95, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, +0, 99, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 101, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, +0, 102, 1, 0, 0, 6, 0, 0, 0, 101, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 120, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, +0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 121, 1, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 121, 1, 0, 0, 122, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, +0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 69, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 72, 1, 0, 0, 71, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 74, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 78, 1, 0, 0, 79, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 92, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 72, 1, 0, 0, 93, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 95, 1, 0, 0, 94, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 96, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 97, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 98, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 102, 1, 0, 0, 103, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 65, 0, 5, +0, 2, 0, 0, 0, 130, 0, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, +0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, +0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 79, 1, 0, 0, 82, 1, 0, +0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, +0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 180, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, +0, 181, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 182, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, +0, 186, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 188, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 189, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 190, 0, 0, +0, 187, 0, 0, 0, 40, 0, 0, 0, 188, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 182, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 192, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, +0, 4, 0, 0, 0, 193, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 186, 0, 0, 0, 192, 0, 0, 0, 254, 0, 2, 0, 193, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, +0, 197, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 198, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 199, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 200, 0, 0, 0, 248, 0, 2, 0, 201, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 208, 0, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 179, 0, 0, 0, 210, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 215, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 179, 0, 0, 0, 222, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 229, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 233, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 179, 0, 0, 0, 253, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 204, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 207, 0, 0, 0, 187, 0, 0, 0, 43, 0, 0, 0, 202, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, +0, 62, 0, 3, 0, 200, 0, 0, 0, 207, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 200, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, +0, 210, 0, 0, 0, 213, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 215, 0, 0, 0, 217, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, +0, 220, 0, 0, 0, 197, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 221, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 224, 0, 0, 0, 197, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 225, 0, 0, 0, 224, 0, 0, 0, 62, 0, 3, 0, 222, 0, 0, 0, 225, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 228, 0, 0, 0, 175, 0, 0, 0, 215, 0, 0, 0, 218, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 228, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 230, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 232, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 0, 0, 0, 229, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 237, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 233, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, +0, 12, 0, 8, 0, 4, 0, 0, 0, 243, 0, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 244, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 245, 0, 0, 0, 238, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 246, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 249, 0, 0, 0, 200, 0, 0, 0, 186, 0, 5, +0, 7, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 247, 0, 3, 0, 248, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 252, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 248, 0, 2, 0, 247, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, +0, 210, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 255, 0, 0, 0, 200, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 2, 1, 0, 0, 254, 0, 0, 0, 1, 1, 0, 0, 62, 0, 3, +0, 253, 0, 0, 0, 2, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 5, 1, 0, 0, 253, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 1, 0, 0, 4, 1, 0, 0, 5, 1, 0, 0, 62, 0, 3, +0, 3, 1, 0, 0, 6, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 3, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 12, 1, 0, 0, 11, 1, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 13, 1, 0, 0, 10, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 253, 0, 0, +0, 129, 0, 5, 0, 4, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 15, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 1, 0, 0, 204, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 18, 1, 0, 0, 219, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 1, 0, 0, 7, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 20, 1, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 20, 1, 0, 0, 61, 0, 4, +0, 3, 0, 0, 0, 21, 1, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 1, 0, 0, 16, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 24, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, +0, 23, 1, 0, 0, 23, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 25, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 25, 1, 0, 0, 249, 0, 2, 0, 248, 0, 0, 0, 248, 0, 2, +0, 248, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 26, 1, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 27, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 238, 0, 0, +0, 80, 0, 7, 0, 3, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 30, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, +0, 197, 0, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 31, 1, 0, 0, 197, 0, 0, 0, 254, 0, 2, 0, 31, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 46, 1, 0, +0, 59, 0, 4, 0, 196, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 55, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 61, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 65, 1, 0, 0, 7, 0, 0, +0, 57, 0, 4, 0, 3, 0, 0, 0, 54, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 54, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 59, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 1, 0, 0, 59, 1, 0, +0, 62, 0, 3, 0, 55, 1, 0, 0, 60, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 64, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 61, 1, 0, 0, 64, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 62, 1, 0, +0, 57, 0, 8, 0, 3, 0, 0, 0, 68, 1, 0, 0, 176, 0, 0, 0, 51, 1, 0, 0, 55, 1, 0, 0, 61, 1, 0, 0, 65, 1, 0, 0, 254, 0, 2, 0, 68, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, +0, 248, 0, 2, 0, 84, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 85, 1, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 86, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 86, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, +0, 87, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 88, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 87, 1, 0, 0, 88, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 89, 1, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, +0, 90, 1, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 91, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 69, 1, 0, 0, 91, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 104, 1, 0, 0, 0, 0, 0, +0, 29, 0, 0, 0, 248, 0, 2, 0, 105, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 106, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 107, 1, 0, 0, 93, 1, 0, 0, 62, 0, 3, 0, 106, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, +0, 2, 0, 0, 0, 108, 1, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 109, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 110, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, +0, 61, 0, 4, 0, 3, 0, 0, 0, 112, 1, 0, 0, 97, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 112, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 113, 1, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 114, 1, 0, 0, 103, 1, 0, 0, 80, 1, 0, +0, 61, 0, 4, 0, 3, 0, 0, 0, 115, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 115, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 117, 1, 0, 0, 116, 1, 0, +0, 62, 0, 3, 0, 94, 1, 0, 0, 117, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 118, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 119, 1, 0, 0, 118, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 119, 1, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } + #endif From 36d88d3cfac2a5ec587ef4578db89b047108b299 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 14:24:20 +0900 Subject: [PATCH 0814/1182] Shaders: various fixes to be more compliant with new SDSL/SDFX shader compiler --- .../Effects/StrideSinglePassWireframeShader.sdfx | 2 +- .../ColorTransforms/ColorTransformGroupEffect.sdfx | 2 +- .../Hexagonal/McIntoshOptimizedShader.sdsl | 2 -- .../Rendering/Images/Fog/FogEffect.sdsl | 13 +++++++------ .../LightProbes/StrideBakeLightProbeEffect.sdfx | 2 +- ....sdsl.cs => IMaterialCelShadingLightFunction.cs} | 0 ...lt.sdsl.cs => MaterialCelShadingLightDefault.cs} | 0 .../Attributes/Shaders/VoxelAttribute.sdsl | 2 +- .../Shaders/VoxelStorageTextureShader.sdsl | 2 +- 9 files changed, 12 insertions(+), 13 deletions(-) rename sources/engine/Stride.Rendering/Rendering/Materials/CelShading/{IMaterialCelShadingLightFunction.sdsl.cs => IMaterialCelShadingLightFunction.cs} (100%) rename sources/engine/Stride.Rendering/Rendering/Materials/CelShading/{MaterialCelShadingLightDefault.sdsl.cs => MaterialCelShadingLightDefault.cs} (100%) diff --git a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx index 488759635c..39dadfac0f 100644 --- a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx +++ b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx @@ -5,7 +5,7 @@ using Stride.Rendering.Materials; namespace Stride.BepuPhysics.Debug { - partial shader StrideSinglePassWireframeShader + partial effect StrideSinglePassWireframeShader { mixin SinglePassWireframeShader; } diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx index a9971567bb..31e7995459 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx @@ -9,7 +9,7 @@ namespace Stride.Rendering.Images { using params ColorTransformKeys; - mixin ColorTransformKeys.Shader, ColorTransformKeys.GenericArguments; + mixin ColorTransformKeys.Shader; }; effect ColorTransformGroupEffect diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl index 6b8c6c7b28..e27d734e7f 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl @@ -3,8 +3,6 @@ namespace Stride.Rendering.Images { - compose DepthAwareDirectionalBlurShader blurShader; - /// /// Optimized version of the McIntosh bokeh effect. /// Based on a first blur pass, computes the 2 diagonal blurs and keeps the minimum. diff --git a/sources/engine/Stride.Rendering/Rendering/Images/Fog/FogEffect.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/Fog/FogEffect.sdsl index 927b5319f4..bfbeeb63f3 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/Fog/FogEffect.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Images/Fog/FogEffect.sdsl @@ -8,13 +8,14 @@ namespace Stride.Rendering.Images /// internal shader FogEffect : ImageEffectShader { - stage float FogStart; - stage float Density; - stage float zFar; - stage float zNear; - stage bool skipBG; + stage float FogStart = 0.0f; + stage float Density = 1.0f; + stage float zFar = 1000.0f; + stage float zNear = 0.1f; + stage bool skipBG = false; - stage float3 FogColor; + [Color] + stage float3 FogColor = float3(1.0, 1.0, 1.0); stage Texture2D DepthTexture; stage override float4 Shading() diff --git a/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx b/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx index 9d45809246..46076fb12e 100644 --- a/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx +++ b/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx @@ -5,7 +5,7 @@ using Stride.Rendering.Materials; namespace Stride.Rendering.LightProbes { - partial shader StrideBakeLightProbeEffect + partial effect StrideBakeLightProbeEffect { mixin BakeLightProbeShader; } diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/IMaterialCelShadingLightFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/IMaterialCelShadingLightFunction.cs similarity index 100% rename from sources/engine/Stride.Rendering/Rendering/Materials/CelShading/IMaterialCelShadingLightFunction.sdsl.cs rename to sources/engine/Stride.Rendering/Rendering/Materials/CelShading/IMaterialCelShadingLightFunction.cs diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightDefault.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightDefault.cs similarity index 100% rename from sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightDefault.sdsl.cs rename to sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightDefault.cs diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl index 091060470e..0464c4b1db 100644 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl +++ b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl @@ -7,5 +7,5 @@ shader VoxelAttribute void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride){} void IndirectWrite(RWBuffer buffer, uint address){} void DirectWrite(uint3 address, uint strideIndex, uint stride){} - float4 SampleLocal(){return float4(0,0,0,1);}; + float4 SampleLocal(){return float4(0,0,0,1);} }; diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl index f5a2ee0801..d1d86dd1dd 100644 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl +++ b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl @@ -6,5 +6,5 @@ shader VoxelStorageTextureShader float4 SampleNearestMip(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis){ return float4(0, 1, 0, 0); } float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis){ return float4(1, 0, 0, 0); } - float VoxelSize(){ return 1.0; }; + float VoxelSize(){ return 1.0; } }; From f5cf85e129de147ab9745ea5d8c775d5767fc789 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 14:47:54 +0900 Subject: [PATCH 0815/1182] Shader compiler: use new SDSL/SDFX generator instead of custom tool --- .../Stride.Core.Assets.CompilerApp.targets | 17 ----------------- sources/assets/Stride.Core.Assets/Package.cs | 4 ++-- .../assets/Stride.Core.Assets/PackageSession.cs | 4 ++-- .../Effect/EffectCompositorAsset.cs | 11 +---------- .../Stride.Assets/Effect/EffectShaderAsset.cs | 11 +---------- .../Stride.Assets/StridePackageUpgrader.cs | 2 +- .../engine/Stride.Shaders/ShaderClassSource.cs | 5 +++++ .../engine/Stride.Shaders/Stride.Shaders.csproj | 3 +++ .../Stride.Shaders/build/Stride.Shaders.targets | 15 +++++++++++++++ sources/targets/Stride.UnitTests.targets | 12 ++++++++---- sources/targets/Stride.targets | 12 ++++++++---- 11 files changed, 46 insertions(+), 50 deletions(-) create mode 100644 sources/engine/Stride.Shaders/build/Stride.Shaders.targets diff --git a/sources/assets/Stride.Core.Assets.CompilerApp/build/Stride.Core.Assets.CompilerApp.targets b/sources/assets/Stride.Core.Assets.CompilerApp/build/Stride.Core.Assets.CompilerApp.targets index 178d0aede5..d54fc51a6c 100644 --- a/sources/assets/Stride.Core.Assets.CompilerApp/build/Stride.Core.Assets.CompilerApp.targets +++ b/sources/assets/Stride.Core.Assets.CompilerApp/build/Stride.Core.Assets.CompilerApp.targets @@ -243,21 +243,4 @@ - - - - - - - - - - - - - diff --git a/sources/assets/Stride.Core.Assets/Package.cs b/sources/assets/Stride.Core.Assets/Package.cs index 232ae88118..6827549540 100644 --- a/sources/assets/Stride.Core.Assets/Package.cs +++ b/sources/assets/Stride.Core.Assets/Package.cs @@ -1205,7 +1205,7 @@ public static List ListAssetFiles(Package package, bool ext = ext?.Replace(".xk", ".sd"); //make sure to add default shaders in this case, since we don't have a csproj for them - if (AssetRegistry.IsProjectCodeGeneratorAssetFileExtension(ext) && (package.Container is not SolutionProject || package.IsSystem)) + if (AssetRegistry.IsProjectAssetFileExtension(ext) && (package.Container is not SolutionProject || package.IsSystem)) { listFiles.Add(new PackageLoadingAssetFile(fileUPath, sourceFolder) { CachedFileSize = filePath.Length }); continue; @@ -1256,7 +1256,7 @@ public static List ListAssetFiles(Package package, bool if (nameSpace?.Length == 0) nameSpace = null; - var result = project.Items.Where(x => (x.ItemType == "Compile" || x.ItemType == "None") && string.IsNullOrEmpty(x.GetMetadataValue("AutoGen"))) + var result = project.Items.Where(x => (x.ItemType == "Compile" || x.ItemType == "None" || x.ItemType == "AdditionalFiles") && string.IsNullOrEmpty(x.GetMetadataValue("AutoGen"))) // Build full path for Include and Link .Select(x => (FilePath: UPath.Combine(dir, new UFile(x.EvaluatedInclude)), Link: x.HasMetadata("Link") ? UPath.Combine(dir, new UFile(x.GetMetadataValue("Link"))) : null)) // For items outside project, let's pretend they are link diff --git a/sources/assets/Stride.Core.Assets/PackageSession.cs b/sources/assets/Stride.Core.Assets/PackageSession.cs index ee463ff82a..ccfb15f1c1 100644 --- a/sources/assets/Stride.Core.Assets/PackageSession.cs +++ b/sources/assets/Stride.Core.Assets/PackageSession.cs @@ -1042,7 +1042,7 @@ public void Save(ILogger log, PackageSaveParameters? saveParameters = null) project = VSProjectHelper.LoadProject(projectFullPath.ToOSPath()); vsProjs.Add(projectFullPath, project); } - var projectItem = project.Items.FirstOrDefault(x => (x.ItemType == "Compile" || x.ItemType == "None") && x.EvaluatedInclude == projectInclude); + var projectItem = project.Items.FirstOrDefault(x => (x.ItemType == "Compile" || x.ItemType == "None" || x.ItemType == "AdditionalFiles") && x.EvaluatedInclude == projectInclude); if (projectItem?.IsImported == false) { project.RemoveItem(projectItem); @@ -1056,7 +1056,7 @@ public void Save(ILogger log, PackageSaveParameters? saveParameters = null) File.Delete(generatedAbsolutePath); var generatedInclude = assetItem.GetGeneratedInclude(); - var generatedItem = project.Items.FirstOrDefault(x => (x.ItemType == "Compile" || x.ItemType == "None") && x.EvaluatedInclude == generatedInclude); + var generatedItem = project.Items.FirstOrDefault(x => (x.ItemType == "Compile" || x.ItemType == "None" || x.ItemType == "AdditionalFiles") && x.EvaluatedInclude == generatedInclude); if (generatedItem is not null) { project.RemoveItem(generatedItem); diff --git a/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs b/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs index 90f035b6df..013fcacaba 100644 --- a/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs +++ b/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs @@ -12,20 +12,11 @@ namespace Stride.Assets.Effect /// [DataContract("EffectCompositorAsset")] [AssetDescription(FileExtension, AlwaysMarkAsRoot = true, AllowArchetype = false)] - public sealed partial class EffectCompositorAsset : ProjectSourceCodeWithFileGeneratorAsset + public sealed partial class EffectCompositorAsset : ProjectSourceCodeAsset { /// /// The default file extension used by the . /// public const string FileExtension = ".sdfx"; - - public override string Generator => "StrideEffectCodeGenerator"; - - public override void SaveGeneratedAsset(AssetItem assetItem) - { - var generatedFileData = ShaderKeyFileHelper.GenerateCode(assetItem.FullPath, Text); - //generate the .sdfx.cs files - File.WriteAllBytes(assetItem.GetGeneratedAbsolutePath(), generatedFileData); - } } } diff --git a/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs b/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs index 669237fde0..cc50e22b29 100644 --- a/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs +++ b/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs @@ -17,7 +17,7 @@ namespace Stride.Assets.Effect /// [DataContract("EffectShader")] [AssetDescription(FileExtension, AlwaysMarkAsRoot = true, AllowArchetype = false)] - public sealed partial class EffectShaderAsset : ProjectSourceCodeWithFileGeneratorAsset + public sealed partial class EffectShaderAsset : ProjectSourceCodeAsset { /// /// The default file extension used by the . @@ -26,8 +26,6 @@ public sealed partial class EffectShaderAsset : ProjectSourceCodeWithFileGenerat public static Regex Regex = new Regex(@"(^|\s)(class)($|\s)"); - public override string Generator => "StrideShaderKeyGenerator"; - public override void Save(Stream stream) { //regex the shader name if it has changed @@ -35,12 +33,5 @@ public override void Save(Stream stream) base.Save(stream); } - - public override void SaveGeneratedAsset(AssetItem assetItem) - { - var generatedFileData = ShaderKeyFileHelper.GenerateCode(assetItem.FullPath, Text); - //generate the .sdsl.cs files - File.WriteAllBytes(assetItem.GetGeneratedAbsolutePath(), generatedFileData); - } } } diff --git a/sources/engine/Stride.Assets/StridePackageUpgrader.cs b/sources/engine/Stride.Assets/StridePackageUpgrader.cs index e7abad145d..7343e8c57a 100644 --- a/sources/engine/Stride.Assets/StridePackageUpgrader.cs +++ b/sources/engine/Stride.Assets/StridePackageUpgrader.cs @@ -27,7 +27,7 @@ namespace Stride.Assets { - [PackageUpgrader(new[] { StrideConfig.PackageName, "Stride.Core", "Stride.Engine", "Xenko", "Xenko.Core", "Xenko.Engine" }, "3.1.0.0", CurrentVersion)] + [PackageUpgrader(new[] { StrideConfig.PackageName, "Stride.Core", "Stride.Engine" }, "4.0.0.0", CurrentVersion)] public partial class StridePackageUpgrader : PackageUpgrader { // Should match Stride.nupkg diff --git a/sources/engine/Stride.Shaders/ShaderClassSource.cs b/sources/engine/Stride.Shaders/ShaderClassSource.cs index 1cbf20cafb..63571907b3 100644 --- a/sources/engine/Stride.Shaders/ShaderClassSource.cs +++ b/sources/engine/Stride.Shaders/ShaderClassSource.cs @@ -8,6 +8,7 @@ using System.Text; using Stride.Core; +using Stride.Core.Mathematics; using Stride.Core.Serialization; namespace Stride.Shaders @@ -62,6 +63,10 @@ public ShaderClassSource(string className, params object[] genericArguments) var genArg = genericArguments[i]; if (genArg is bool) GenericArguments[i] = ((bool)genArg) ? "true" : "false"; + else if (genArg is Vector4 v) + GenericArguments[i] = $"float4({v.X}, {v.Y}, {v.Z}, {v.W})"; + else if (genArg is Vector3 v2) + GenericArguments[i] = $"float3({v2.X}, {v2.Y}, {v2.Z})"; else GenericArguments[i] = genArg == null ? "null" : Convert.ToString(genArg, CultureInfo.InvariantCulture); } diff --git a/sources/engine/Stride.Shaders/Stride.Shaders.csproj b/sources/engine/Stride.Shaders/Stride.Shaders.csproj index 03ff9ce9db..95c2664e08 100644 --- a/sources/engine/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/engine/Stride.Shaders/Stride.Shaders.csproj @@ -17,6 +17,9 @@ + + + diff --git a/sources/engine/Stride.Shaders/build/Stride.Shaders.targets b/sources/engine/Stride.Shaders/build/Stride.Shaders.targets new file mode 100644 index 0000000000..2ba67558dd --- /dev/null +++ b/sources/engine/Stride.Shaders/build/Stride.Shaders.targets @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index a046258e02..e3cfd9fdd2 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -72,10 +72,14 @@ - - - - + + + + + + + + diff --git a/sources/targets/Stride.targets b/sources/targets/Stride.targets index 90b29bb075..1a8b90a44e 100644 --- a/sources/targets/Stride.targets +++ b/sources/targets/Stride.targets @@ -55,10 +55,14 @@ - - - - + + + + + + + + From bb2868d2f814e79255c98f0bda77377b30cc58db Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 10:56:51 +0900 Subject: [PATCH 0816/1182] Fetch DirectXShaderCompiler/gen_intrin_main.txt as a single file rather than full submodule --- .gitmodules | 3 - src/Stride.Shaders/Stride.Shaders.csproj | 5 +- src/Stride.Shaders/gen_intrin_README.md | 3 + src/Stride.Shaders/gen_intrin_main.txt | 1242 ++++++++++++++++++++++ submodules/DirectXShaderCompiler | 1 - 5 files changed, 1247 insertions(+), 7 deletions(-) create mode 100644 src/Stride.Shaders/gen_intrin_README.md create mode 100644 src/Stride.Shaders/gen_intrin_main.txt delete mode 160000 submodules/DirectXShaderCompiler diff --git a/.gitmodules b/.gitmodules index 69d3201fa8..6b8d134039 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,3 @@ [submodule "submodules/SpirvRegistry"] path = submodules/SpirvRegistry url = https://github.com/KhronosGroup/Registry-Root-SPIR-V -[submodule "submodules/DirectXShaderCompiler"] - path = submodules/DirectXShaderCompiler - url = https://github.com/microsoft/DirectXShaderCompiler diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 78ac76af05..433a8a7da0 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -10,9 +10,8 @@ - - - + + diff --git a/src/Stride.Shaders/gen_intrin_README.md b/src/Stride.Shaders/gen_intrin_README.md new file mode 100644 index 0000000000..7b9d306999 --- /dev/null +++ b/src/Stride.Shaders/gen_intrin_README.md @@ -0,0 +1,3 @@ +Here is how to get latest gen_intrin_main.txt: + +curl -fsSL "https://raw.githubusercontent.com/microsoft/DirectXShaderCompiler/main/utils/hct/gen_intrin_main.txt" -o gen_intrin_main.txt \ No newline at end of file diff --git a/src/Stride.Shaders/gen_intrin_main.txt b/src/Stride.Shaders/gen_intrin_main.txt new file mode 100644 index 0000000000..1a0d3b7a3b --- /dev/null +++ b/src/Stride.Shaders/gen_intrin_main.txt @@ -0,0 +1,1242 @@ +// Copyright (C) Microsoft Corporation. All rights reserved. +// This file is distributed under the University of Illinois Open Source License. See LICENSE.TXT for details. +// +// See hctdb.py for the implementation of intrinsic file processing. +// +// Intrinsic declarations are grouped into namespaces that +// turn into qualifiers for the generated names. This lets +// intrinsics be grouped into sets such as base function-style +// intrinsics, Texture1D intrinsics, etc. +// +// Intrinsic declarations are a line of the form: +// +// \[\[[attr]\]\] ([ [, ... ]]) [ : ] +// +// is a C++ identifier for the intrinsic or argument name. +// +// is the D3DIOP_* (or D3DMOP_* if the namespace has "Method" +// in the name) enumerant. By default it's the same as the intrinsic +// name, but can be given to set it arbitrarily. +// +// is one of "in", "out" or "inout" plus optional qualifiers +// "col_major", "row_major". +// variadic functions assume of "in" for any arguments that are not +// explicitly specified. +// +// is where most of the work goes. lets you +// specify particular types and layouts for arguments and +// also lets you indicate which types must share characteristics +// with other types. can be a simple scalar like "bool" +// or it can require an N-vector with "bool" or an N-by-M +// matrix with "bool". You can refer to input columns +// and rows with r, c, r2 and c2, so "float" means a +// float matrix with the same number of rows and columns and +// the size comes from the parse input. "<>" means any kind +// of layout is acceptable. +// +// Basic types are bool, int, uint, u64, float, sampler1d, sampler2d, +// sampler3d, sampler_cube, sampler_cmp, sampler, wave and void. +// There are meta-types too: any_int, uint_only, numeric and any. +// +// Along with a type and layout you can also give relations +// between types in an intrinsic. The types of an intrinsic +// are indexed start with 0 at the return type and increasing +// left to right (first argument is 1, second is 2, etc.). +// $match says that the template type (layout) of +// a particular type must match the template type of the X'th +// type and that the component type (base type) of a particular +// type must match the component type of the Y'th type. +// For example, in "float<> acos(in $match<0, 0> float<> x)" the +// $match<0, 0> means that both the template and component type +// of the argument must match that of the return type (index 0). +// The float<> means that any layout (scalar/vector/matrix) of +// floats is acceptable, and then the parameter and return +// type must match. +// +// A value of -1 for X in $match is a special marker for +// object method intrinsics meaning that the type is taken +// from the object's template type. +// +// A value of -1 for Y in $match is a special marker for +// object method intrinsics meaning that the component type +// of the type is taken from the first subelement of the +// object's template type. +// +// Certain $match situations are aliased for readability +// and conciseness. +// +// $classT - This equates to $match<-1, 0> void and is +// used for method return types that are set from +// the object template type. +// +// $funcT - This equates to $match<-3, 0> void and is +// used for method return types that are set from +// the function template type. +// +// $typeN - This equates to $match and is +// shorthand for a direct match of another type. +// For example, in "$type1 abs(in numeric<> x)" the +// $type means that the return type is a direct match +// of the argument type ($type cannot be used on the +// first argument since there's nothing to match at +// that point and can't refer to the return type as +// it is matched after the inputs). +// + +namespace Intrinsics { + +int<4> [[rn]] D3DCOLORtoUBYTE4(in $match<0, 1> float<4> x) : d3dcolortoubyte4; +uint [[rn]] GetRenderTargetSampleCount() : rtsampleinfo; +float<2> [[rn]] GetRenderTargetSamplePosition(in int s) : rtsamplepos; +void [[]] abort(); +$type1 [[rn,unsigned_op=uabs]] abs(in numeric<> x); +$type1 [[rn]] acos(in float_like<> x); +bool [[rn]] all(in any<> x); +void [[]] AllMemoryBarrier() : syncallmemory_ug; +void [[]] AllMemoryBarrierWithGroupSync() : syncgroupandallmemory_ug; +bool [[rn]] any(in any<> x); +double<> [[rn]] asdouble(in $match<0, 1> uint<> x, in $match<0, 2> uint<> y) : reinterpret_fuse_double; +float<> [[rn]] asfloat(in $match<0, 1> numeric32_only<> x) : reinterpret_float; +float16_t<> [[rn]] asfloat16(in $match<0,1> numeric16_only<> x) : reinterpret_float16; +int16_t<> [[rn]] asint16(in $match<0,1> numeric16_only<> x) : reinterpret_int16; +$type1 [[rn]] asin(in float_like<> x); +int<> [[rn]] asint(in $match<0, 1> numeric32_only<> x) : reinterpret_int; +void [[]] asuint(in double<> d, out $match<1, 2> uint<> x, out $match<1, 3> uint<> y) : reinterpret_split_double_uint; +uint<> [[rn]] asuint(in $match<0, 1> numeric32_only<> x) : reinterpret_uint; +uint16_t<> [[rn]] asuint16(in $match<0,1> numeric16_only<> x) : reinterpret_uint16; +$type1 [[rn]] atan(in float_like<> x); +$type1 [[rn]] atan2(in float_like<> x, in $type1 y); +$type1 [[rn]] ceil(in float_like<> x); +$type1 [[rn,unsigned_op=uclamp]] clamp(in numeric<> x, in $type1 min, in $type1 max); +void [[]] clip(in float<> x); +$type1 [[rn]] cos(in float_like<> x); +$type1 [[rn]] cosh(in float_like<> x); +$match<1, 0> uint<> [[rn]] countbits(in any_int<> x); +$type1 [[rn]] cross(in float_like<3> a, in $type1 b); +$type1 [[rn]] ddx(in float_like<> x); +$type1 [[rn]] ddx_coarse(in float_like<> x); +$type1 [[rn]] ddx_fine(in float_like<> x); +$type1 [[rn]] ddy(in float_like<> x); +$type1 [[rn]] ddy_coarse(in float_like<> x); +$type1 [[rn]] ddy_fine(in float_like<> x); +void [[min_sm=6.10]] DebugBreak(); +$type1 [[rn]] degrees(in float_like<> x); +$match<0, 1> float_like [[rn]] determinant(in float_like x); +void [[]] DeviceMemoryBarrier() : syncdevicememory_ug; +void [[]] DeviceMemoryBarrierWithGroupSync() : syncgroupanddevicememory_ug; +$match<0, 1> float_like [[rn]] distance(in float_like a, in $type1 b); +$match<0, 1> numeric [[rn,unsigned_op=udot]] dot(in numeric a, in $type1 b); +$type1 [[rn]] dst(in numeric<4> a, in $type1 b); +// void errorf(in string Format, ...); +$type1 [[rn]] EvaluateAttributeAtSample(in numeric<> value, in uint index); +$type1 [[rn]] EvaluateAttributeCentroid(in numeric<> value); +$type1 [[rn]] EvaluateAttributeSnapped(in numeric<> value, in int<2> offset); +$type1 [[rn]] GetAttributeAtVertex(in numeric<> value, in uint VertexID); +$type1 [[rn]] exp(in float_like<> x); +$type1 [[rn]] exp2(in float_like<> x); +float<> [[rn]] f16tof32(in uint<> x); +// Use float for DXIL don't support f16 on f32tof16. +uint<> [[rn]] f32tof16(in float<> x); +$type1 [[rn]] faceforward(in float_like N, in $type1 I, in $type1 Ng); +$match<1, 0> uint<> [[rn,unsigned_op=ufirstbithigh,overload=0]] firstbithigh(in any_int<> x); +$match<1, 0> uint<> [[rn]] firstbitlow(in any_int<> x); +$type1 [[rn]] floor(in float_like<> x); +$type1 [[rn]] fma(in double_only<> a, in $type1 b, in $type1 c); +$type1 [[rn]] fmod(in float_like<> a, in $type1 b); +$type1 [[rn]] frac(in float_like<> x); +$type1 [[]] frexp(in float<> x, out $type1 exp); +$type1 [[rn]] fwidth(in float_like<> x); +void [[]] GroupMemoryBarrier() : syncsharedmemory; +void [[]] GroupMemoryBarrierWithGroupSync() : syncgroupandsharedmemory; +// 64-bit integers interlocks +void [[]] InterlockedAdd(ref int64_only result, in u64 value); +void [[]] InterlockedAdd(ref int64_only result, in u64 value, out any_int64 original) : interlockedadd_immediate; +void [[unsigned_op=InterlockedUMin,overload=0]] InterlockedMin(ref int64_only result, in any_int64 value) : interlockedmin; +void [[unsigned_op=InterlockedUMin,overload=0]] InterlockedMin(ref int64_only result, in any_int64 value, out any_int64 original) : interlockedmin_immediate; +void [[unsigned_op=InterlockedUMax,overload=0]] InterlockedMax(ref int64_only result, in any_int64 value) : interlockedmax; +void [[unsigned_op=InterlockedUMax,overload=0]] InterlockedMax(ref int64_only result, in any_int64 value, out any_int64 original) : interlockedmax_immediate; +void [[]] InterlockedAnd(ref int64_only result, in u64 value); +void [[]] InterlockedAnd(ref int64_only result, in u64 value, out any_int64 original) : interlockedand_immediate; +void [[]] InterlockedOr(ref int64_only result, in u64 value); +void [[]] InterlockedOr(ref int64_only result, in u64 value, out any_int64 original) : interlockedor_immediate; +void [[]] InterlockedXor(ref int64_only result, in u64 value); +void [[]] InterlockedXor(ref int64_only result, in u64 value, out any_int64 original) : interlockedxor_immediate; +void [[]] InterlockedCompareStore(ref int64_only result, in u64 compare, in u64 value); +void [[]] InterlockedExchange(ref int64_only result, in any_int64 value, out any_int64 original); +void [[]] InterlockedCompareExchange(ref int64_only result, in u64 compare, in u64 value, out any_int64 original); +// floating point interlocks +void [[]] InterlockedExchange(ref float32_only result, in float value, out float original); +void [[]] InterlockedCompareStoreFloatBitwise(ref float32_only result, in float compare, in float value); +void [[]] InterlockedCompareExchangeFloatBitwise(ref float32_only result, in float compare, in float value, out float original); +// 32-bit integer interlocks +void [[]] InterlockedAdd(ref int32_only result, in uint value); +void [[]] InterlockedAdd(ref int32_only result, in uint value, out any_int32 original) : interlockedadd_immediate; +void [[unsigned_op=InterlockedUMin,overload=0]] InterlockedMin(ref int32_only result, in any_int32 value) : interlockedmin; +void [[unsigned_op=InterlockedUMin,overload=0]] InterlockedMin(ref int32_only result, in any_int32 value, out any_int32 original) : interlockedmin_immediate; +void [[unsigned_op=InterlockedUMax,overload=0]] InterlockedMax(ref int32_only result, in any_int32 value) : interlockedmax; +void [[unsigned_op=InterlockedUMax,overload=0]] InterlockedMax(ref int32_only result, in any_int32 value, out any_int32 original) : interlockedmax_immediate; +void [[]] InterlockedAnd(ref int32_only result, in uint value); +void [[]] InterlockedAnd(ref int32_only result, in uint value, out any_int32 original) : interlockedand_immediate; +void [[]] InterlockedOr(ref int32_only result, in uint value); +void [[]] InterlockedOr(ref int32_only result, in uint value, out any_int32 original) : interlockedor_immediate; +void [[]] InterlockedXor(ref int32_only result, in uint value); +void [[]] InterlockedXor(ref int32_only result, in uint value, out any_int32 original) : interlockedxor_immediate; +void [[]] InterlockedCompareStore(ref int32_only result, in uint compare, in uint value); +void [[]] InterlockedExchange(ref int32_only result, in uint value, out any_int32 original); +void [[]] InterlockedCompareExchange(ref int32_only result, in uint compare, in uint value, out any_int32 original); +$match<1, 0> bool<> [[rn]] isfinite(in float_like<> x); +$match<1, 0> bool<> [[rn]] isinf(in float_like<> x); +$match<1, 0> bool<> [[rn]] isnan(in float_like<> x); +$match<1, 0> bool<> [[rn]] isnormal(in float_like<> x); +$type1 [[rn]] ldexp(in float_like<> x, in $type1 exp); +$match<0, 1> float_like [[rn]] length(in float_like x); +$type1 [[rn]] lerp(in float_like<> a, in $type1 b, in $type1 s); +$match<0, 1> float_like<4> [[rn]] lit(in float_like l, in $match<2, 1> float_like h, in $match<3, 1> float_like m); +$type1 [[rn]] log(in float_like<> x); +$type1 [[rn]] log10(in float_like<> x); +$type1 [[rn]] log2(in float_like<> x); +$type1 [[rn,unsigned_op=umad]] mad(in numeric<> a, in $type1 b, in $type1 c); +$type1 [[rn,unsigned_op=umax]] max(in numeric<> a, in $type1 b); +$type1 [[rn,unsigned_op=umin]] min(in numeric<> a, in $type1 b); +$type1 [[]] modf(in float_like<> x, out $type1 ip); +uint<4> [[rn]] msad4(in uint reference, in uint<2> source, in uint<4> accum); +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_ss; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_sv; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_sm; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_vs; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_vv; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in col_major $match<2, 0> numeric b) : mul_vm; +numeric [[rn,unsigned_op=umul]] mul(in $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_ms; +numeric [[rn,unsigned_op=umul]] mul(in row_major $match<1, 0> numeric a, in $match<2, 0> numeric b) : mul_mv; +numeric [[rn,unsigned_op=umul]] mul(in row_major $match<1, 0> numeric a, in col_major $match<2, 0> numeric b) : mul_mm; +$type1 [[rn]] normalize(in float_like x); +$type1 [[rn]] pow(in float_like<> x, in $type1 y); +void [[]] printf(in string Format, ...); +void [[]] Process2DQuadTessFactorsAvg(in float<4> RawEdgeFactors, in float<2> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_2dqavg; +void [[]] Process2DQuadTessFactorsMax(in float<4> RawEdgeFactors, in float<2> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_2dqmax; +void [[]] Process2DQuadTessFactorsMin(in float<4> RawEdgeFactors, in float<2> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_2dqmin; +void [[]] ProcessIsolineTessFactors(in float<1> RawDetailFactor, in float<1> RawDensityFactor, out float<1> RoundedDetailFactorr, out float<1> RoundedDensityFactor) : ptf_i; +void [[]] ProcessQuadTessFactorsAvg(in float<4> RawEdgeFactors, in float<1> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_qavg; +void [[]] ProcessQuadTessFactorsMax(in float<4> RawEdgeFactors, in float<1> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_qmax; +void [[]] ProcessQuadTessFactorsMin(in float<4> RawEdgeFactors, in float<1> InsideScale, out float<4> RoundedEdgeFactors, out float<2> RoundedInsideFactors, out float<2> UnroundedInsideFactors) : ptf_qmin; +void [[]] ProcessTriTessFactorsAvg(in float<3> RawEdgeFactors, in float<1> InsideScale, out float<3> RoundedEdgeFactors, out float<1> RoundedInsideFactor, out float<1> UnroundedInsideFactor) : ptf_tmin; +void [[]] ProcessTriTessFactorsMax(in float<3> RawEdgeFactors, in float<1> InsideScale, out float<3> RoundedEdgeFactors, out float<1> RoundedInsideFactor, out float<1> UnroundedInsideFactor) : ptf_tmax; +void [[]] ProcessTriTessFactorsMin(in float<3> RawEdgeFactors, in float<1> InsideScale, out float<3> RoundedEdgeFactors, out float<1> RoundedInsideFactor, out float<1> UnroundedInsideFactor) : ptf_tavg; +$type1 [[rn]] radians(in float_like<> x); +$type1 [[rn]] rcp(in any_float<> x) : rcp_approx; +$type1 [[rn]] reflect(in float_like i, in $type1 n); +$type1 [[rn]] refract(in float_like i, in $type1 n, in $match<3, 1> float_like ri); +$type1 [[rn]] reversebits(in any_int<> x); +$type1 [[rn]] round(in float_like<> x); +$type1 [[rn]] rsqrt(in float_like<> x); +$type1 [[rn]] saturate(in any_float<> x); +$match<1, 0> int<> [[rn,unsigned_op=usign,overload=0]] sign(in numeric<> x); +$type1 [[rn]] sin(in float_like<> x); +void [[]] sincos(in float_like<> x, out $type1 s, out $type1 c); +$type1 [[rn]] sinh(in float_like<> x); +$type1 [[rn]] smoothstep(in float_like<> a, in $type1 b, in $type1 x); +void [[]] source_mark(); +$type1 [[rn]] sqrt(in float_like<> x); +$type1 [[rn]] step(in float_like<> a, in $type1 x); +$type1 [[rn]] tan(in float_like<> x); +$type1 [[rn]] tanh(in float_like<> x); +float_like<4> [[ro]] tex1D(in sampler1d s, in float_like x) : tex1d; +float_like<4> [[ro]] tex1D(in sampler1d s, in float_like<1> x, in $type2 ddx, in $type2 ddy) : tex1d_dd; +float_like<4> [[ro]] tex1Dbias(in sampler1d s, in float_like<4> x) : tex1d_bias; +float_like<4> [[ro]] tex1Dgrad(in sampler1d s, in float_like<1> x, in $type2 ddx, in $type2 ddy) : tex1d_dd; +float_like<4> [[ro]] tex1Dlod(in sampler1d s, in float_like<4> x) : tex1d_lod; +float_like<4> [[ro]] tex1Dproj(in sampler1d s, in float_like<4> x) : tex1d_proj; +float_like<4> [[ro]] tex2D(in sampler2d s, in float_like<2> x) : tex2d; +float_like<4> [[ro]] tex2D(in sampler2d s, in float_like<2> x, in $type2 ddx, in $type2 ddy) : tex2d_dd; +float_like<4> [[ro]] tex2Dbias(in sampler2d s, in float_like<4> x) : tex2d_bias; +float_like<4> [[ro]] tex2Dgrad(in sampler2d s, in float_like<2> x, in $type2 ddx, in $type2 ddy) : tex2d_dd; +float_like<4> [[ro]] tex2Dlod(in sampler2d s, in float_like<4> x) : tex2d_lod; +float_like<4> [[ro]] tex2Dproj(in sampler2d s, in float_like<4> x) : tex2d_proj; +float_like<4> [[ro]] tex3D(in sampler3d s, in float_like<3> x) : tex3d; +float_like<4> [[ro]] tex3D(in sampler3d s, in float_like<3> x, in $type2 ddx, in $type2 ddy) : tex3d_dd; +float_like<4> [[ro]] tex3Dbias(in sampler3d s, in float_like<4> x) : tex3d_bias; +float_like<4> [[ro]] tex3Dgrad(in sampler3d s, in float_like<3> x, in $type2 ddx, in $type2 ddy) : tex3d_dd; +float_like<4> [[ro]] tex3Dlod(in sampler3d s, in float_like<4> x) : tex3d_lod; +float_like<4> [[ro]] tex3Dproj(in sampler3d s, in float_like<4> x) : tex3d_proj; +float_like<4> [[ro]] texCUBE(in sampler_cube s, in float_like<3> x) : texcube; +float_like<4> [[ro]] texCUBE(in sampler_cube s, in float_like<3> x, in $type2 ddx, in $type2 ddy) : texcube_dd; +float_like<4> [[ro]] texCUBEbias(in sampler_cube s, in float_like<4> x) : texcube_bias; +float_like<4> [[ro]] texCUBEgrad(in sampler_cube s, in float_like<3> x, in $type2 ddx, in $type2 ddy) : texcube_dd; +float_like<4> [[ro]] texCUBElod(in sampler_cube s, in float_like<4> x) : texcube_lod; +float_like<4> [[ro]] texCUBEproj(in sampler_cube s, in float_like<4> x) : texcube_proj; +$match<1, 1> any [[rn]] transpose(in any x); +$type1 [[rn]] trunc(in float_like<> x); +bool [[rn]] CheckAccessFullyMapped(in uint_only status) : check_access_fully_mapped; +uint [[rn]] AddUint64(in $match<1, 0> uint a, in $match<2, 0> uint b) : adduint64; +$type1 [[rn]] NonUniformResourceIndex(in any<> index) : nonuniform_resource_index; + +// Wave intrinsics. Only those that depend on the exec mask are marked as wave-sensitive +bool [[wv]] WaveIsFirstLane(); +uint [[ro]] WaveGetLaneIndex(); +uint [[rn]] WaveGetLaneCount(); +bool [[wv]] WaveActiveAnyTrue(in bool cond); +bool [[wv]] WaveActiveAllTrue(in bool cond); +$match<1, 0> bool<> [[wv]] WaveActiveAllEqual(in any<> value); +uint<4> [[wv]] WaveActiveBallot(in bool cond); +$type1 [[]] WaveReadLaneAt(in any<> value, in uint lane); +$type1 [[wv]] WaveReadLaneFirst(in any<> value); +uint [[wv]] WaveActiveCountBits(in bool value); +$type1 [[unsigned_op=WaveActiveUSum,wv]] WaveActiveSum(in numeric<> value); +$type1 [[unsigned_op=WaveActiveUProduct,wv]] WaveActiveProduct(in numeric<> value); +$type1 [[wv]] WaveActiveBitAnd(in uint_only<> value); +$type1 [[wv]] WaveActiveBitOr(in uint_only<> value); +$type1 [[wv]] WaveActiveBitXor(in uint_only<> value); +$type1 [[unsigned_op=WaveActiveUMin,wv]] WaveActiveMin(in numeric<> value); +$type1 [[unsigned_op=WaveActiveUMax,wv]] WaveActiveMax(in numeric<> value); +uint [[wv]] WavePrefixCountBits(in bool value); +$type1 [[unsigned_op=WavePrefixUSum,wv]] WavePrefixSum(in numeric<> value); +$type1 [[unsigned_op=WavePrefixUProduct,wv]] WavePrefixProduct(in numeric<> value); +uint<4> [[wv]] WaveMatch(in numeric<> value); +$type1 [[wv]] WaveMultiPrefixBitAnd(in any_int<> value, in uint<4> mask); +$type1 [[wv]] WaveMultiPrefixBitOr(in any_int<> value, in uint<4> mask); +$type1 [[wv]] WaveMultiPrefixBitXor(in any_int<> value, in uint<4> mask); +uint [[wv]] WaveMultiPrefixCountBits(in bool value, in uint<4> mask); +$type1 [[unsigned_op=WaveMultiPrefixUProduct,wv]] WaveMultiPrefixProduct(in numeric<> value, in uint<4> mask); +$type1 [[unsigned_op=WaveMultiPrefixUSum,wv]] WaveMultiPrefixSum(in numeric<> value, in uint<4> mask); +$type1 [[]] QuadReadLaneAt(in numeric<> value, in uint quadLane); +$type1 [[]] QuadReadAcrossX(in numeric<> value); +$type1 [[]] QuadReadAcrossY(in numeric<> value); +$type1 [[]] QuadReadAcrossDiagonal(in numeric<> value); +bool [[]] QuadAny(in bool cond); +bool [[]] QuadAll(in bool cond); +uint [[rn,min_sm=6.10]] GetGroupWaveIndex(); +uint [[rn,min_sm=6.10]] GetGroupWaveCount(); + +// Raytracing +void [[]] TraceRay(in acceleration_struct AccelerationStructure, in uint RayFlags, in uint InstanceInclusionMask, in uint RayContributionToHitGroupIndex, in uint MultiplierForGeometryContributionToHitGroupIndex, in uint MissShaderIndex, in ray_desc Ray, inout udt Payload); + +bool [[]] ReportHit(in float THit, in uint HitKind, in udt Attributes); +void [[]] CallShader(in uint ShaderIndex, inout udt Parameter); +void [[]] IgnoreHit(); +void [[]] AcceptHitAndEndSearch(); +uint<3> [[rn]] DispatchRaysIndex(); +uint<3> [[rn]] DispatchRaysDimensions(); +// group: Ray Vectors +float<3> [[rn]] WorldRayOrigin(); +float<3> [[rn]] WorldRayDirection(); +float<3> [[rn]] ObjectRayOrigin(); +float<3> [[rn]] ObjectRayDirection(); +// group: RayT +float [[rn]] RayTMin(); +float [[rn]] RayTCurrent(); +// group: Raytracing uint System Values +uint [[rn]] PrimitiveIndex(); +uint [[rn]] InstanceID(); +uint [[rn]] InstanceIndex(); +uint [[rn]] GeometryIndex(); +uint [[rn]] HitKind(); +uint [[rn]] RayFlags(); +// group: Ray Transforms +float<3,4> [[rn]] ObjectToWorld(); +float<3,4> [[rn]] WorldToObject(); +float<3,4> [[rn]] ObjectToWorld3x4(); +float<3,4> [[rn]] WorldToObject3x4(); +float<4,3> [[rn]] ObjectToWorld4x3(); +float<4,3> [[rn]] WorldToObject4x3(); + +uint [[rn,min_sm=6.10]] ClusterID(); +triangle_positions [[rn,min_sm=6.10]] TriangleObjectPositions(); + +// Packed dot products with accumulate: +uint [[rn]] dot4add_u8packed(in uint a, in $type1 b, in uint c); +int [[rn]] dot4add_i8packed(in uint a, in $type1 b, in int c); +float [[rn]] dot2add(in float16_t<2> a, in $type1 b, in float c); + +// Unpacking intrinsics +int16_t<4> [[rn]] unpack_s8s16(in p32i8 pk); +uint16_t<4> [[rn]] unpack_u8u16(in p32u8 pk); +int<4> [[rn]] unpack_s8s32(in p32i8 pk); +uint<4> [[rn]] unpack_u8u32(in p32u8 pk); + +// Packing intrinsics +p32i8 [[rn]] pack_s8(in any_int16or32<4> v); +p32u8 [[rn]] pack_u8(in any_int16or32<4> v); +p32i8 [[rn]] pack_clamp_s8(in sint16or32_only<4> v); +p32u8 [[rn]] pack_clamp_u8(in sint16or32_only<4> v); + +// Mesh shader intrinsics: +void [[]] SetMeshOutputCounts(in uint numVertices, in uint numPrimitives); + +// Amplification shader intrinsics: +void [[]] DispatchMesh(in uint threadGroupCountX, in uint threadGroupCountY, in uint threadGroupCountZ, in udt meshPayload); + +// Return true if the current lane is a helper lane +bool [[ro]] IsHelperLane(); + +// HL Op for allocating ray query object +uint [[hidden]] AllocateRayQuery(in uint flags, in uint rayqueryflags); + +resource [[hidden]] CreateResourceFromHeap(in uint index); + +// Replacement for vector logical &&, ||, and ternary conditional operators, +// For use when HLSL changes to support short-circuiting and only scalar +// conditions to maintain clarity. +$match<1, 0> bool<> [[rn]] and(in bool<> x, in $type1 y); +$match<1, 0> bool<> [[rn]] or(in bool<> x, in $type1 y); +$type2 [[rn]] select(in bool<> cond, in $match<1, 2> any<> t, in $type2 f); +$type2 [[rn]] select(in bool cond, in any_sampler t, in $type2 f); + +// Work Graph intrinsics +void [[]] Barrier(in uint MemoryTypeFlags, in uint SemanticFlags); +void [[]] Barrier(in NodeRecordOrUAV o, in uint SemanticFlags); + +uint [[]] GetRemainingRecursionLevels(); + +void [[min_sm=6.10]] __builtin_MatVecMul(out LinAlg OutputVector, in bool OutputIsUnsigned, in LinAlg InputVector, in bool InputIsUnsigned, in uint InputInterpretation, in ByteAddressBuffer MatrixBuffer, in uint MatrixOffset, in uint MatrixInterpretation, in uint M, in uint K, in uint MatrixLayout, in bool MatrixIsTransposed, in uint MatrixStride); + +void [[min_sm=6.10]] __builtin_MatVecMulAdd(out LinAlg OutputVector, in bool OutputIsUnsigned, in LinAlg InputVector, in bool InputIsUnsigned, in uint InputInterpretation, in ByteAddressBuffer MatrixBuffer, in uint MatrixOffset, in uint MatrixInterpretation, in uint M, in uint K, in uint MatrixLayout, in bool MatrixIsTransposed, in uint MatrixStride, in ByteAddressBuffer BiasVector, in uint BiasOffset, in uint BiasInterpretation); + +void [[min_sm=6.10]] __builtin_OuterProductAccumulate(in LinAlg InputVector1, in LinAlg InputVector2, in RWByteAddressBuffer MatrixBuffer, in uint MatrixOffset, in uint MatrixInterpretation, in uint MatrixLayout, in uint MatrixStride); + +void [[min_sm=6.10]] __builtin_VectorAccumulate(in LinAlg InputVector, in RWByteAddressBuffer MatrixBuffer, in uint MatrixOffset); + +// LinAlg intrinsics + +// TODO: Replace all int MatrixRef with MatrixRef type +// TODO: Replace all int GroupSharedMem with groupshared memory +void [[min_sm=6.10]] __builtin_LinAlg_FillMatrix(int MatrixRef, numeric value); +void [[min_sm=6.10]] __builtin_LinAlg_CopyConvertMatrix(int MatrixRefDest, int MatrixRefSrc, bool transpose); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixLoadFromDescriptor(int MatrixRef, resource buf, int32_only offset, int32_only stride, int32_only layout); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixLoadFromMemory(int MatrixRef, int GroupSharedMem, int32_only offset, int32_only stride, int32_only layout); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixLength(int MatrixRef); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixGetCoordinate(int MatrixRef, int32_only threadLocalIndex); +numeric [[min_sm=6.10]] __builtin_LinAlg_MatrixGetElement(int MatrixRef, int32_only threadLocalIndex); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixSetElement(int MatrixRef, int32_only threadLocalIndex, numeric value); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixStoreToDescriptor(int MatrixRef, resource buf, int32_only offset, int32_only stride, int32_only layout); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixStoreToMemory(int MatrixRef, int GroupSharedMem, int32_only offset, int32_only stride, int32_only layout); +int32_only [[min_sm=6.10]] __builtin_LinAlg_MatrixQueryAccumulatorLayout(); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixMatrixMultiply(int MatrixRefA, int MatrixRefB, int MatrixRefC); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixMatrixMultiplyAccumulate(int MatrixRefA, int MatrixRefB, int MatrixRefC); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixAccumulate(int MatrixRefRHS, int MatrixRefLHS); + +// TODO: Fix vector types +void [[min_sm=6.10]] __builtin_LinAlg_MatrixVectorMultiply(int MatrixRef); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixVectorMultiplyAdd(int MatrixRef); + +void [[min_sm=6.10]] __builtin_LinAlg_MatrixAccumulateToDescriptor(int MatrixRef, resource buf, int32_only offset, int32_only stride, int32_only layout); +void [[min_sm=6.10]] __builtin_LinAlg_MatrixAccumulateToMemory(int MatrixRef, int GroupSharedMem, int32_only offset, int32_only stride, int32_only layout); + +// TODO: Fix vector types +void [[min_sm=6.10]] __builtin_LinAlg_MatrixOuterProduct(int MatrixRef); + +} namespace + + +// SPIRV Change Starts +namespace VkIntrinsics { + +u64 [[]] ReadClock(in uint scope); +$funcT [[ro]] RawBufferLoad(in u64 addr); +$funcT [[ro]] RawBufferLoad(in u64 addr, in uint alignment); +void [[]] RawBufferStore(in u64 addr, in $funcT value); +void [[]] RawBufferStore(in u64 addr, in $funcT value, in uint alignment); +void [[]] ext_execution_mode(in uint mode, ...); +void [[]] ext_execution_mode_id(in uint mode, ...); +$funcT2 [[]] static_pointer_cast(in VkBufferPointer ptr); +$funcT2 [[]] reinterpret_pointer_cast(in VkBufferPointer ptr); + +} namespace + +namespace BufferPointerMethods { +$classT [[ro]] GetBufferContents(); +} namespace +// SPIRV Change Ends + +namespace StreamMethods { + +void [[]] Append(in $match<-1, 1> void x) : stream_append; +void [[]] RestartStrip() : stream_restart; + +} namespace + +namespace Texture1DMethods { +// Use float for DXIL don't support f16 on CalcLOD. +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<1> x) : tex1d_t_calc_lod; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<1> x) : tex1d_t_calc_lod_unclamped; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width) : resinfo_o; +void [[]] GetDimensions(out float_like width) : resinfo_o; +$classT [[ro]] Load(in int<2> x) : tex1d_t_load; +$classT [[ro]] Load(in int<2> x, in int<1> o) : tex1d_t_load_o; +$classT [[]] Load(in int<2> x, in int<1> o, out uint_only status) : tex1d_t_load_o_s; +$classT [[ro]] Sample(in sampler s, in float<1> x) : tex1d_t; +$classT [[ro]] Sample(in sampler s, in float<1> x, in int<1> o) : tex1d_t_o; +$classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias) : tex1d_t_bias; +$classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias, in int<1> o) : tex1d_t_bias_o; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue) : tex1d_t_comp; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o) : tex1d_t_comp_o; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<1> x, in float compareValue, in float bias) : tex1d_t_comp_bias; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<1> x, in float compareValue, in float bias, in int<1> o) : tex1d_t_comp_bias_o; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<1> x, in float compareValue, in $type2 ddx, in $type2 ddy) : tex1d_t_comp_dd; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<1> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<1> o) : tex1d_t_comp_dd_o; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod); +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod, in int<1> o); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue) : tex1d_t_comp_lz; +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o) : tex1d_t_comp_lz_o; +$classT [[ro]] SampleGrad(in sampler s, in float<1> x, in $type2 ddx, in $type2 ddy) : tex1d_t_dd; +$classT [[ro]] SampleGrad(in sampler s, in float<1> x, in $type2 ddx, in $type2 ddy, in int<1> o) : tex1d_t_dd_o; +$classT [[ro]] SampleLevel(in sampler s, in float<1> x, in float lod) : tex1d_t_lod; +$classT [[ro]] SampleLevel(in sampler s, in float<1> x, in float lod, in int<1> o) : tex1d_t_lod_o; +$classT [[ro]] Sample(in sampler s, in float<1> x, in int<1> o, in float clamp) : tex1d_t_o_cl; +$classT [[]] Sample(in sampler s, in float<1> x, in int<1> o, in float clamp, out uint_only status) : tex1d_t_o_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, in float clamp) : tex1d_t_comp_o_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_o_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<1> x, in float compareValue, in float bias, in int<1> o, in float clamp) : tex1d_t_comp_bias_o_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<1> x, in float compareValue, in float bias, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_bias_o_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<1> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<1> o, in float clamp) : tex1d_t_comp_dd_o_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<1> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_dd_o_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<1> x, in float compareValue, in float lod, in int<1> o, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<1> x, in float compareValue, in int<1> o, out uint_only status) : tex1d_t_comp_o_s; +$classT [[]] SampleLevel(in sampler s, in float<1> x, in float lod, in int<1> o, out uint_only status) : tex1d_t_lod_o_s; +$classT [[ro]] SampleBias(in sampler s, in float<1> x, in float bias, in int<1> o, in float clamp) : tex1d_t_bias_o_cl; +$classT [[]] SampleBias(in sampler s, in float<1> x, in float bias, in int<1> o, in float clamp, out uint_only status) : tex1d_t_bias_o_cl_s; +$classT [[]] SampleGrad(in sampler s, in float<1> x, in $type2 ddx, in $type2 ddy, in int<1> o, in float clamp) : tex1d_t_dd_o_cl; +$classT [[]] SampleGrad(in sampler s, in float<1> x, in $type2 ddx, in $type2 ddy, in int<1> o, in float clamp, out uint_only status) : tex1d_t_dd_o_cl_s; +} namespace + +namespace Texture1DArrayMethods { + +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<1> x) : tex1d_t_calc_lod_array; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<1> x) : tex1d_t_calc_lod_unclamped_array; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 elements, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 elements, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 elements) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 elements) : resinfo_o; +$classT [[ro]] Load(in int<3> x) : tex1d_t_load_array; +$classT [[ro]] Load(in int<3> x, in int<1> o) : tex1d_t_load_array_o; +$classT [[]] Load(in int<3> x, in int<1> o, out uint_only status) : tex1d_t_load_array_o_s; +$classT [[ro]] Sample(in sampler s, in float<2> x) : tex1d_t_array; +$classT [[ro]] Sample(in sampler s, in float<2> x, in int<1> o) : tex1d_t_array_o; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias) : tex1d_t_bias_array; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<1> o) : tex1d_t_bias_array_o; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue) : tex1d_t_comp_array; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o) : tex1d_t_comp_array_o; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias) : tex1d_t_comp_bias_array; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<1> o) : tex1d_t_comp_bias_array_o; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy) : tex1d_t_comp_dd_array; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o) : tex1d_t_comp_dd_array_o; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod); +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<1> o); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue) : tex1d_t_comp_lz_array; +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o) : tex1d_t_comp_lz_array_o; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy) : tex1d_t_dd_array; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o) : tex1d_t_dd_array_o; +$classT [[ro]] SampleLevel(in sampler s, in float<2> x, in float lod) : tex1d_t_lod_array; +$classT [[ro]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<1> o) : tex1d_t_lod_array_o; +$classT [[ro]] Sample(in sampler s, in float<2> x, in int<1> o, in float clamp) : tex1d_t_array_o_cl; +$classT [[]] Sample(in sampler s, in float<2> x, in int<1> o, in float clamp, out uint_only status) : tex1d_t_array_o_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, in float clamp) : tex1d_t_comp_array_o_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_array_o_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<1> o, in float clamp) : tex1d_t_comp_bias_array_o_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_bias_array_o_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o, in float clamp) : tex1d_t_comp_dd_array_o_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o, in float clamp, out uint_only status) : tex1d_t_comp_dd_array_o_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<1> o, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<1> o, out uint_only status) : tex1d_t_comp_array_o_s; +$classT [[]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<1> o, out uint_only status) : tex1d_t_lod_array_o_s; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<1> o, in float clamp) : tex1d_t_bias_array_o_cl; +$classT [[]] SampleBias(in sampler s, in float<2> x, in float bias, in int<1> o, in float clamp, out uint_only status) : tex1d_t_bias_array_o_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o, in float clamp) : tex1d_t_dd_array_o_cl; +$classT [[]] SampleGrad(in sampler s, in float<2> x, in $match<2, 2> float<1> ddx, in $match<2, 2> float<1> ddy, in int<1> o, in float clamp, out uint_only status) : tex1d_t_dd_array_o_cl_s; +} namespace + +namespace Texture2DMethods { + +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<2> x) : tex2d_t_calc_lod; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<2> x) : tex2d_t_calc_lod_unclamped; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<2> x) : tex2d_t_gather; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<2> x, in int<2> o) : tex2d_t_gather_o; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<2> x) : tex2d_t_gather_alpha; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<2> x, in int<2> o) : tex2d_t_gather_alpha_o; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_alpha_o4; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<2> x) : tex2d_t_gather_blue; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<2> x, in int<2> o) : tex2d_t_gather_blue_o; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_blue_o4; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_gather_comp; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_o; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_gather_comp_alpha; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_alpha_o; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_alpha_o4; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_gather_comp_blue; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_blue_o; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_blue_o4; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_gather_comp_green; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_green_o; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_green_o4; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_gather_comp_red; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_red_o; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_red_o4; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<2> x) : tex2d_t_gather_green; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<2> x, in int<2> o) : tex2d_t_gather_green_o; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_green_o4; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<2> x) : tex2d_t_gather_red; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<2> x, in int<2> o) : tex2d_t_gather_red_o; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_red_o4; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 height, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 height) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height) : resinfo_o; +$classT [[ro]] Load(in int<3> x) : tex2d_t_load; +$classT [[ro]] Load(in int<3> x, in int<2> o) : tex2d_t_load_o; +$classT [[]] Load(in int<3> x, in int<2> o, out uint_only status) : tex2d_t_load_o_s; +$classT [[ro]] Sample(in sampler s, in float<2> x) : tex2d_t; +$classT [[ro]] Sample(in sampler s, in float<2> x, in int<2> o) : tex2d_t_o; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias) : tex2d_t_bias; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<2> o) : tex2d_t_bias_o; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_comp; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_comp_o; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias) : tex2d_t_comp_bias; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<2> o) : tex2d_t_comp_bias_o; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $type2 ddx, in $type2 ddy) : tex2d_t_comp_dd; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<2> o) : tex2d_t_comp_dd_o; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod); +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<2> o); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue) : tex2d_t_comp_lz; +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o) : tex2d_t_comp_lz_o; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $type2 ddx, in $type2 ddy) : tex2d_t_dd; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $type2 ddx, in $type2 ddy, in int<2> o) : tex2d_t_dd_o; +$classT [[ro]] SampleLevel(in sampler s, in float<2> x, in float lod) : tex2d_t_lod; +$classT [[ro]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<2> o) : tex2d_t_lod_o; +$classT [[ro]] Sample(in sampler s, in float<2> x, in int<2> o, in float clamp) : tex2d_t_o_cl; +$classT [[]] Sample(in sampler s, in float<2> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_o_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, in float clamp) : tex2d_t_comp_o_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_o_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<2> o, in float clamp) : tex2d_t_comp_bias_o_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<2> x, in float compareValue, in float bias, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_bias_o_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<2> o, in float clamp) : tex2d_t_comp_dd_o_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<2> x, in float compareValue, in $type2 ddx, in $type2 ddy, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_dd_o_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<2> x, in float compareValue, in float lod, in int<2> o, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_comp_o_s; +$classT [[]] SampleLevel(in sampler s, in float<2> x, in float lod, in int<2> o, out uint_only status) : tex2d_t_lod_o_s; +$classT [[ro]] SampleBias(in sampler s, in float<2> x, in float bias, in int<2> o, in float clamp) : tex2d_t_bias_o_cl; +$classT [[]] SampleBias(in sampler s, in float<2> x, in float bias, in int<2> o, in float clamp, out uint_only status) : tex2d_t_bias_o_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<2> x, in $type2 ddx, in $type2 ddy, in int<2> o, in float clamp) : tex2d_t_dd_o_cl; +$classT [[]] SampleGrad(in sampler s, in float<2> x, in $type2 ddx, in $type2 ddy, in int<2> o, in float clamp, out uint_only status) : tex2d_t_dd_o_cl_s; +$match<0, -1> void<4> [[]] Gather(in sampler s, in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_o_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_red_o_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_red_o4_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_green_o_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_green_o4_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_blue_o_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_blue_o4_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<2> x, in int<2> o, out uint_only status) : tex2d_t_gather_alpha_o_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<2> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_alpha_o4_s; + +$match<0, -1> void<4> [[]] GatherCmp(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_o_s; +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_red_o_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_green_o_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_blue_o_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_alpha_o_s; + +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_red_o4_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_green_o4_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_blue_o4_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<2> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_alpha_o4_s; +$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<2> x); +$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<2> x, in int<2> o); +$match<0, -1> void<4> [[]] GatherRaw(in sampler s, in float<2> x, in int<2> o, out uint_only status); +} namespace + +namespace Texture2DMSMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type2 samples) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type2 samples) : resinfo_o; +float_like<2> [[ro]] GetSamplePosition(in int s) : samplepos; +$classT [[]] Load(in int<2> x, in int s) : texture2d_ms; +$classT [[]] Load(in int<2> x, in int s, in int<2> o) : texture2d_ms_o; +$classT [[]] Load(in int<2> x, in int s, in int<2> o, out uint_only status) : texture2d_ms_o_s; + +} namespace + +namespace Texture2DArrayMethods { + +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<2> x) : tex2d_t_calc_lod_array; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<2> x) : tex2d_t_calc_lod_unclamped_array; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<3> x) : tex2d_t_gather_array; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<3> x, in int<2> o) : tex2d_t_gather_array_o; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<3> x) : tex2d_t_gather_alpha_array; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<3> x, in int<2> o) : tex2d_t_gather_alpha_array_o; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_alpha_array_o4; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<3> x) : tex2d_t_gather_blue_array; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<3> x, in int<2> o) : tex2d_t_gather_blue_array_o; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_blue_array_o4; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_gather_comp_array; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_array_o; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_gather_comp_alpha_array; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_alpha_array_o; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_alpha_array_o4; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_gather_comp_blue_array; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_blue_array_o; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_blue_array_o4; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_gather_comp_green_array; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_green_array_o; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_green_array_o4; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_gather_comp_red_array; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_gather_comp_red_array_o; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_comp_red_array_o4; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<3> x) : tex2d_t_gather_green_array; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<3> x, in int<2> o) : tex2d_t_gather_green_array_o; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_green_array_o4; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<3> x) : tex2d_t_gather_red_array; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<3> x, in int<2> o) : tex2d_t_gather_red_array_o; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4) : tex2d_t_gather_red_array_o4; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 height, out $type2 elements, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 elements, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements) : resinfo_o; +$classT [[ro]] Load(in int<4> x) : tex2d_t_load_array; +$classT [[ro]] Load(in int<4> x, in int<2> o) : tex2d_t_load_array_o; +$classT [[]] Load(in int<4> x, in int<2> o, out uint_only status) : tex2d_t_load_array_o_s; +$classT [[ro]] Sample(in sampler s, in float<3> x) : tex2d_t_array; +$classT [[ro]] Sample(in sampler s, in float<3> x, in int<2> o) : tex2d_t_array_o; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias) : tex2d_t_bias_array; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<2> o) : tex2d_t_bias_array_o; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_comp_array; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_comp_array_o; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias) : tex2d_t_comp_bias_array; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias, in int<2> o) : tex2d_t_comp_bias_array_o; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy) : tex2d_t_comp_dd_array; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o) : tex2d_t_comp_dd_array_o; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod); +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, in int<2> o); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue) : tex2d_t_comp_lz_array; +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o) : tex2d_t_comp_lz_array_o; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy) : tex2d_t_dd_array; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o) : tex2d_t_dd_array_o; +$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod) : tex2d_t_lod_array; +$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod, in int<2> o) : tex2d_t_lod_array_o; +$classT [[ro]] Sample(in sampler s, in float<3> x, in int<2> o, in float clamp) : tex2d_t_array_o_cl; +$classT [[]] Sample(in sampler s, in float<3> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_array_o_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, in float clamp) : tex2d_t_comp_array_o_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_array_o_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias, in int<2> o, in float clamp) : tex2d_t_comp_bias_array_o_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_bias_array_o_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o, in float clamp) : tex2d_t_comp_dd_array_o_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o, in float clamp, out uint_only status) : tex2d_t_comp_dd_array_o_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, in int<2> o, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_comp_array_o_s; +$classT [[]] SampleLevel(in sampler s, in float<3> x, in float lod, in int<2> o, out uint_only status) : tex2d_t_lod_array_o_s; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<2> o, in float clamp) : tex2d_t_bias_array_o_cl; +$classT [[]] SampleBias(in sampler s, in float<3> x, in float bias, in int<2> o, in float clamp, out uint_only status) : tex2d_t_bias_array_o_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o, in float clamp) : tex2d_t_dd_array_o_cl; +$classT [[]] SampleGrad(in sampler s, in float<3> x, in $match<2, 2> float<2> ddx, in $match<2, 2> float<2> ddy, in int<2> o, in float clamp, out uint_only status) : tex2d_t_dd_array_o_cl_s; +$match<0, -1> void<4> [[]] Gather(in sampler s, in float<3> x, in int<2> o, out uint_only status) : tex2d_t_gather_array_o_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<3> x, in int<2> o, out uint_only status) : tex2d_t_gather_red_array_o_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_red_array_o4_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<3> x, in int<2> o, out uint_only status) : tex2d_t_gather_green_array_o_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_green_array_o4_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<3> x, in int<2> o, out uint_only status) : tex2d_t_gather_blue_array_o_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_blue_array_o4_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<3> x, in int<2> o, out uint_only status) : tex2d_t_gather_alpha_array_o_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<3> x, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_alpha_array_o4_s; +$match<0, -1> void<4> [[]] GatherCmp(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_array_o_s; +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_red_array_o_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_green_array_o_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_blue_array_o_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o, out uint_only status) : tex2d_t_gather_comp_alpha_array_o_s; +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_red_array_o4_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_green_array_o4_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_blue_array_o4_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, in int<2> o1, in int<2> o2, in int<2> o3, in int<2> o4, out uint_only status) : tex2d_t_gather_comp_alpha_array_o4_s; +$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<3> x); +$match<0, -1> void<4> [[ro]] GatherRaw(in sampler s, in float<3> x, in int<2> o); +$match<0, -1> void<4> [[]] GatherRaw(in sampler s, in float<3> x, in int<2> o, out uint_only status); +} namespace + +namespace Texture2DArrayMSMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements, out $type1 samples) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements, out $type1 samples) : resinfo_o; +float_like<2> [[ro]] GetSamplePosition(in int s) : samplepos; +$classT [[ro]] Load(in int<3> x, in int s) : texture2darray_ms; +$classT [[ro]] Load(in int<3> x, in int s, in int<2> o) : texture2darray_ms_o; +$classT [[]] Load(in int<3> x, in int s, in int<2> o, out uint_only status) : texture2darray_ms_o_s; + +} namespace + +namespace Texture3DMethods { + +float [[ro]] CalculateLevelOfDetail(in sampler s, in float<3> x) : tex3d_t_calc_lod; +float [[ro]] CalculateLevelOfDetailUnclamped(in sampler s, in float<3> x) : tex3d_t_calc_lod_unclamped; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 height, out $type2 depth, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 depth, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 depth) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 depth) : resinfo_o; +$classT [[ro]] Load(in int<4> x) : tex3d_t_load; +$classT [[ro]] Load(in int<4> x, in int<3> o) : tex3d_t_load_o; +$classT [[]] Load(in int<4> x, in int<3> o, out uint_only status) : tex3d_t_load_o_s; +$classT [[ro]] Sample(in sampler s, in float<3> x) : tex3d_t; +$classT [[ro]] Sample(in sampler s, in float<3> x, in int<3> o) : tex3d_t_o; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias) : tex3d_t_bias; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<3> o) : tex3d_t_bias_o; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy) : tex3d_t_dd; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy, in int<3> o) : tex3d_t_dd_o; +$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod) : tex3d_t_lod; +$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod, in int<3> o) : tex3d_t_lod_o; +$classT [[ro]] Sample(in sampler s, in float<3> x, in int<3> o, in float clamp) : tex3d_t_o_cl; +$classT [[]] Sample(in sampler s, in float<3> x, in int<3> o, in float clamp, out uint_only status) : tex3d_t_o_cl_s; +$classT [[]] SampleLevel(in sampler s, in float<3> x, in float lod, in int<3> o, out uint_only status) : tex3d_t_lod_o_s; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in int<3> o, in float clamp) : tex3d_t_bias_o_cl; +$classT [[]] SampleBias(in sampler s, in float<3> x, in float bias, in int<3> o, in float clamp, out uint_only status) : tex3d_t_bias_o_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy, in int<3> o, in float clamp) : tex3d_t_dd_o_cl; +$classT [[]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy, in int<3> o, in float clamp, out uint_only status) : tex3d_t_dd_o_cl_s; +} namespace + +namespace TextureCUBEMethods { + +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<3> x) : texcube_t_calc_lod; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<3> x) : texcube_t_calc_lod_unclamped; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<3> x) : texcube_t_gather; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<3> x) : texcube_t_gather_alpha; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<3> x) : texcube_t_gather_blue; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<3> x, in float compareValue) : texcube_t_gather_comp; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue) : texcube_t_gather_comp_alpha; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue) : texcube_t_gather_comp_blue; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue) : texcube_t_gather_comp_green; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue) : texcube_t_gather_comp_red; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<3> x) : texcube_t_gather_green; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<3> x) : texcube_t_gather_red; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 height, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 height) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height) : resinfo_o; +$classT [[ro]] Sample(in sampler s, in float<3> x) : texcube_t; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias) : texcube_t_bias; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float c) : texcube_t_comp; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias) : texcube_t_comp_bias; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $type2 ddx, in $type2 ddy) : texcube_t_comp_dd; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float c, in float lod); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float c) : texcube_t_comp_lz; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy) : texcube_t_dd; +$classT [[ro]] SampleLevel(in sampler s, in float<3> x, in float lod) : texcube_t_lod; +$classT [[ro]] Sample(in sampler s, in float<3> x, in float clamp) : texcube_t_cl; +$classT [[]] Sample(in sampler s, in float<3> x, in float clamp, out uint_only status) : texcube_t_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in float clamp) : texcube_t_comp_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<3> x, in float compareValue, in float clamp, out uint_only status) : texcube_t_comp_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias, in float clamp) : texcube_t_comp_bias_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<3> x, in float compareValue, in float bias, in float clamp, out uint_only status) : texcube_t_comp_bias_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $type2 ddx, in $type2 ddy, in float clamp) : texcube_t_comp_dd_o_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<3> x, in float compareValue, in $type2 ddx, in $type2 ddy, in float clamp, out uint_only status) : texcube_t_comp_dd_o_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<3> x, in float compareValue, in float lod, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_comp_s; +$classT [[]] SampleLevel(in sampler s, in float<3> x, in float lod, out uint_only status) : texcube_t_lod_s; +$classT [[ro]] SampleBias(in sampler s, in float<3> x, in float bias, in float clamp) : texcube_t_bias_cl; +$classT [[]] SampleBias(in sampler s, in float<3> x, in float bias, in float clamp, out uint_only status) : texcube_t_bias_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy, in float clamp) : texcube_t_dd_cl; +$classT [[]] SampleGrad(in sampler s, in float<3> x, in $type2 ddx, in $type2 ddy, in float clamp, out uint_only status) : texcube_t_dd_cl_s; +$match<0, -1> void<4> [[]] Gather(in sampler s, in float<3> x, out uint_only status) : texcube_t_gather_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<3> x, out uint_only status) : texcube_t_gather_red_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<3> x, out uint_only status) : texcube_t_gather_green_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<3> x, out uint_only status) : texcube_t_gather_blue_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<3> x, out uint_only status) : texcube_t_gather_alpha_s; +$match<0, -1> void<4> [[]] GatherCmp(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_s; +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_red_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_green_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_blue_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<3> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_alpha_s; +} namespace + +namespace TextureCUBEArrayMethods { + +float [[ro]] CalculateLevelOfDetail(in any_sampler s, in float<3> x) : texcube_t_calc_lod_array; +float [[ro]] CalculateLevelOfDetailUnclamped(in any_sampler s, in float<3> x) : texcube_t_calc_lod_unclamped_array; +$match<0, -1> void<4> [[ro]] Gather(in sampler s, in float<4> x) : texcube_t_gather_array; +$match<0, -1> void<4> [[ro]] GatherAlpha(in sampler s, in float<4> x) : texcube_t_gather_alpha_array; +$match<0, -1> void<4> [[ro]] GatherBlue(in sampler s, in float<4> x) : texcube_t_gather_blue_array; +$match<0, -1> void<4> [[ro]] GatherCmp(in sampler_cmp s, in float<4> x, in float compareValue) : texcube_t_gather_comp_array; +$match<0, -1> void<4> [[ro]] GatherCmpAlpha(in sampler_cmp s, in float<4> x, in float compareValue) : texcube_t_gather_comp_alpha_array; +$match<0, -1> void<4> [[ro]] GatherCmpBlue(in sampler_cmp s, in float<4> x, in float compareValue) : texcube_t_gather_comp_blue_array; +$match<0, -1> void<4> [[ro]] GatherCmpGreen(in sampler_cmp s, in float<4> x, in float compareValue) : texcube_t_gather_comp_green_array; +$match<0, -1> void<4> [[ro]] GatherCmpRed(in sampler_cmp s, in float<4> x, in float compareValue) : texcube_t_gather_comp_red_array; +$match<0, -1> void<4> [[ro]] GatherGreen(in sampler s, in float<4> x) : texcube_t_gather_green_array; +$match<0, -1> void<4> [[ro]] GatherRed(in sampler s, in float<4> x) : texcube_t_gather_red_array; +void [[]] GetDimensions(in uint x, out uint_only width, out $type2 height, out $type2 elements, out $type2 levels) : resinfo_uint; +void [[]] GetDimensions(in uint x, out float_like width, out $type2 height, out $type2 elements, out $type2 levels) : resinfo; +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements) : resinfo_o; +$classT [[ro]] Sample(in sampler s, in float<4> x) : texcube_t_array; +$classT [[ro]] SampleBias(in sampler s, in float<4> x, in float bias) : texcube_t_bias_array; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<4> x, in float c) : texcube_t_comp_array; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<4> x, in float compareValue, in float bias) : texcube_t_comp_bias_array; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<4> x, in float compareValue, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy) : texcube_t_comp_dd_array; +float_like [[ro]] SampleCmpLevel(in sampler_cmp s, in float<4> x, in float c, in float lod); +float_like [[ro]] SampleCmpLevelZero(in sampler_cmp s, in float<4> x, in float c) : texcube_t_comp_lz_array; +$classT [[ro]] SampleGrad(in sampler s, in float<4> x, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy) : texcube_t_dd_array; +$classT [[ro]] SampleLevel(in sampler s, in float<4> x, in float lod) : texcube_t_lod_array; +$classT [[ro]] Sample(in sampler s, in float<4> x, in float clamp) : texcube_t_array_cl; +$classT [[]] Sample(in sampler s, in float<4> x, in float clamp, out uint_only status) : texcube_t_array_cl_s; +float_like [[ro]] SampleCmp(in sampler_cmp s, in float<4> x, in float compareValue, in float clamp) : texcube_t_comp_array_cl; +float_like [[]] SampleCmp(in sampler_cmp s, in float<4> x, in float compareValue, in float clamp, out uint_only status) : texcube_t_comp_array_cl_s; +float_like [[ro]] SampleCmpBias(in sampler_cmp s, in float<4> x, in float compareValue, in float bias, in float clamp) : texcube_t_comp_bias_array_cl; +float_like [[]] SampleCmpBias(in sampler_cmp s, in float<4> x, in float compareValue, in float bias, in float clamp, out uint_only status) : texcube_t_comp_bias_array_cl_s; +float_like [[ro]] SampleCmpGrad(in sampler_cmp s, in float<4> x, in float compareValue, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy, in float clamp) : texcube_t_comp_dd_array_cl; +float_like [[]] SampleCmpGrad(in sampler_cmp s, in float<4> x, in float compareValue, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy, in float clamp, out uint_only status) : texcube_t_comp_dd_array_cl_s; +float_like [[]] SampleCmpLevel(in sampler_cmp s, in float<4> x, in float compareValue, in float lod, out uint_only status); +float_like [[]] SampleCmpLevelZero(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_comp_array_s; +$classT [[]] SampleLevel(in sampler s, in float<4> x, in float lod, out uint_only status) : texcube_t_lod_array_s; +$classT [[ro]] SampleBias(in sampler s, in float<4> x, in float bias, in float clamp) : texcube_t_bias_array_cl; +$classT [[]] SampleBias(in sampler s, in float<4> x, in float bias, in float clamp, out uint_only status) : texcube_t_bias_array_cl_s; +$classT [[ro]] SampleGrad(in sampler s, in float<4> x, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy, in float clamp) : texcube_t_dd_array_cl; +$classT [[]] SampleGrad(in sampler s, in float<4> x, in $match<2, 2> float<3> ddx, in $match<2, 2> float<3> ddy, in float clamp, out uint_only status) : texcube_t_dd_array_cl_s; +$match<0, -1> void<4> [[]] Gather(in sampler s, in float<4> x, out uint_only status) : texcube_t_gather_array_s; +$match<0, -1> void<4> [[]] GatherRed(in sampler s, in float<4> x, out uint_only status) : texcube_t_gather_red_array_s; +$match<0, -1> void<4> [[]] GatherGreen(in sampler s, in float<4> x, out uint_only status) : texcube_t_gather_green_array_s; +$match<0, -1> void<4> [[]] GatherBlue(in sampler s, in float<4> x, out uint_only status) : texcube_t_gather_blue_array_s; +$match<0, -1> void<4> [[]] GatherAlpha(in sampler s, in float<4> x, out uint_only status) : texcube_t_gather_alpha_array_s; +$match<0, -1> void<4> [[]] GatherCmp(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_array_s; +$match<0, -1> void<4> [[]] GatherCmpRed(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_red_array_s; +$match<0, -1> void<4> [[]] GatherCmpGreen(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_green_array_s; +$match<0, -1> void<4> [[]] GatherCmpBlue(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_blue_array_s; +$match<0, -1> void<4> [[]] GatherCmpAlpha(in sampler_cmp s, in float<4> x, in float compareValue, out uint_only status) : texcube_t_gather_comp_alpha_array_s; +} namespace + +namespace BufferMethods { + +void [[]] GetDimensions(out uint_only width) : bufinfo; +$classT [[ro]] Load(in int<1> x) : buffer_load; +$classT [[]] Load(in int<1> x, out uint_only status) : buffer_load_s; + +} namespace + +namespace RWTexture1DMethods { + +void [[]] GetDimensions(out uint_only width) : resinfo_o; +void [[]] GetDimensions(out float_like width) : resinfo_o; +$classT [[ro]] Load(in int<1> x) : rwtex1d_load; +$classT [[]] Load(in int<1> x, out uint_only status) : rwtex1d_load_s; +} namespace + +namespace RWTexture1DArrayMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 elements) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 elements) : resinfo_o; +$classT [[ro]] Load(in int<2> x) : rwtex1d_load_array; +$classT [[]] Load(in int<2> x, out uint_only status) : rwtex1d_load_array_s; +} namespace + +namespace RWTexture2DMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height) : resinfo_o; +$classT [[ro]] Load(in int<2> x) : rwtex2d_load; +$classT [[]] Load(in int<2> x, out uint_only status) : rwtex2d_load_s; +} namespace + +namespace RWTexture2DArrayMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements) : resinfo_o; +$classT [[ro]] Load(in int<3> x) : rwtex2d_load_array; +$classT [[]] Load(in int<3> x, out uint_only status) : rwtex2d_load_array_s; +} namespace + +namespace RWTexture2DMSMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type2 samples); +void [[]] GetDimensions(out float_like width, out $type1 height, out $type2 samples); +float_like<2> [[ro]] GetSamplePosition(in int s); +$classT [[ro]] Load(in int<2> x, in int s); +$classT [[]] Load(in int<2> x, in int s, out uint_only status); +} namespace + +namespace RWTexture2DMSArrayMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 elements, out $type1 samples); +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 elements, out $type1 samples); +float_like<2> [[ro]] GetSamplePosition(in int s); +$classT [[ro]] Load(in int<3> x, in int s); +$classT [[]] Load(in int<3> x, in int s, out uint_only status); +} namespace + +namespace RWTexture3DMethods { + +void [[]] GetDimensions(out uint_only width, out $type1 height, out $type1 depth) : resinfo_uint_o; +void [[]] GetDimensions(out float_like width, out $type1 height, out $type1 depth) : resinfo_o; +$classT [[ro]] Load(in int<3> x) : rwtex3d_load; +$classT [[]] Load(in int<3> x, out uint_only status) : rwtex3d_load_s; +} namespace + +namespace RWBufferMethods { + +void [[]] GetDimensions(out uint_only width) : bufinfo; +$classT [[ro]] Load(in int x) : rwbuffer_load; +$classT [[]] Load(in int x, out uint_only status) : rwbuffer_load_s; + +} namespace + +namespace ByteAddressBufferMethods { + +void [[]] GetDimensions(out uint_only width) : bufinfo; +$funcT [[ro]] Load(in uint byteOffset) : byteaddress_load; +uint<2> [[ro]] Load2(in uint byteOffset) : byteaddress_load; +uint<3> [[ro]] Load3(in uint byteOffset) : byteaddress_load; +uint<4> [[ro]] Load4(in uint byteOffset) : byteaddress_load; +$funcT [[]] Load(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<2> [[]] Load2(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<3> [[]] Load3(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<4> [[]] Load4(in uint byteOffset, out uint_only status) : byteaddress_load_s; + +} namespace + +namespace RWByteAddressBufferMethods { + +void [[]] GetDimensions(out uint_only width) : bufinfo; +$funcT [[ro]] Load(in uint byteOffset) : byteaddress_load; +uint<2> [[ro]] Load2(in uint byteOffset) : byteaddress_load; +uint<3> [[ro]] Load3(in uint byteOffset) : byteaddress_load; +uint<4> [[ro]] Load4(in uint byteOffset) : byteaddress_load; +$funcT [[]] Load(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<2> [[]] Load2(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<3> [[]] Load3(in uint byteOffset, out uint_only status) : byteaddress_load_s; +uint<4> [[]] Load4(in uint byteOffset, out uint_only status) : byteaddress_load_s; +void [[]] Store(in uint byteOffset, in $funcT value) : byteaddress_store; +void [[]] Store2(in uint byteOffset, in uint<2> value) : byteaddress_store; +void [[]] Store3(in uint byteOffset, in uint<3> value) : byteaddress_store; +void [[]] Store4(in uint byteOffset, in uint<4> value) : byteaddress_store; +// 64-bit integer interlocks +void [[]] InterlockedAdd64(in uint byteOffset, in u64 value); +void [[]] InterlockedAdd64(in uint byteOffset, in u64 value, out any_int64 original) : interlockedadd_immediate; +void [[unsigned_op=InterlockedUMin,overload=1]] InterlockedMin64(in uint byteOffset, in any_int64 value) : interlockedmin; +void [[unsigned_op=InterlockedUMin,overload=1]] InterlockedMin64(in uint byteOffset, in any_int64 value, out any_int64 original) : interlockedmin_immediate; +void [[unsigned_op=InterlockedUMax,overload=1]] InterlockedMax64(in uint byteOffset, in any_int64 value) : interlockedmax; +void [[unsigned_op=InterlockedUMax,overload=1]] InterlockedMax64(in uint byteOffset, in any_int64 value, out any_int64 original) : interlockedmax_immediate; +void [[]] InterlockedAnd64(in uint byteOffset, in u64 value); +void [[]] InterlockedAnd64(in uint byteOffset, in u64 value, out any_int64 original) : interlockedand_immediate; +void [[]] InterlockedOr64(in uint byteOffset, in u64 value); +void [[]] InterlockedOr64(in uint byteOffset, in u64 value, out any_int64 original) : interlockedor_immediate; +void [[]] InterlockedXor64(in uint byteOffset, in u64 value); +void [[]] InterlockedXor64(in uint byteOffset, in u64 value, out any_int64 original) : interlockedxor_immediate; +void [[]] InterlockedCompareStore64(in uint byteOffset, in u64 compare, in u64 value); +void [[]] InterlockedExchange64(in uint byteOffset, in any_int64 value, out any_int64 original); +void [[]] InterlockedCompareExchange64(in uint byteOffset, in u64 compare, in u64 value, out any_int64 original); +// floating point interlocks +void [[]] InterlockedExchangeFloat(in uint byteOffest, in float value, out float original); +void [[]] InterlockedCompareStoreFloatBitwise(in uint byteOffest, in float compare, in float value); +void [[]] InterlockedCompareExchangeFloatBitwise(in uint byteOffest, in float compare, in float value, out float original); +// 32-bit integer interlocks +void [[]] InterlockedAdd(in uint byteOffset, in uint value); +void [[]] InterlockedAdd(in uint byteOffset, in uint value, out uint original) : interlockedadd_immediate; +void [[unsigned_op=InterlockedUMin,overload=1]] InterlockedMin(in uint byteOffset, in any_int32 value) : interlockedmin; +void [[unsigned_op=InterlockedUMin,overload=1]] InterlockedMin(in uint byteOffset, in any_int32 value, out uint original) : interlockedmin_immediate; +void [[unsigned_op=InterlockedUMax,overload=1]] InterlockedMax(in uint byteOffset, in any_int32 value) : interlockedmax; +void [[unsigned_op=InterlockedUMax,overload=1]] InterlockedMax(in uint byteOffset, in any_int32 value, out uint original) : interlockedmax_immediate; +void [[]] InterlockedAnd(in uint byteOffset, in uint value); +void [[]] InterlockedAnd(in uint byteOffset, in uint value, out uint original) : interlockedand_immediate; +void [[]] InterlockedOr(in uint byteOffset, in uint value); +void [[]] InterlockedOr(in uint byteOffset, in uint value, out uint original) : interlockedor_immediate; +void [[]] InterlockedXor(in uint byteOffset, in uint value); +void [[]] InterlockedXor(in uint byteOffset, in uint value, out uint original) : interlockedxor_immediate; +void [[]] InterlockedCompareStore(in uint byteOffset, in uint compare, in uint value); +void [[]] InterlockedExchange(in uint byteOffset, in uint value, out uint original); +void [[]] InterlockedCompareExchange(in uint byteOffset, in uint compare, in uint value, out uint original); + +} namespace + +namespace StructuredBufferMethods { + +void [[]] GetDimensions(out uint_only count, out uint_only stride) : bufinfo; +$classT [[ro]] Load(in int x) : structured_buffer_load; +$classT [[]] Load(in int x, out uint_only status) : structured_buffer_load_s; + +} namespace + +namespace RWStructuredBufferMethods { + +void [[]] GetDimensions(out uint_only count, out uint_only stride) : bufinfo; +uint [[]] IncrementCounter() : structuredbuffer_inc; +uint [[]] DecrementCounter() : structuredbuffer_dec; +$classT [[ro]] Load(in int x) : rwstructured_buffer_load; +$classT [[]] Load(in int x, out uint_only status) : rwstructured_buffer_load_s; + +} namespace + +namespace AppendStructuredBufferMethods { + +void [[]] GetDimensions(out uint_only count, out uint_only stride) : bufinfo; +void [[]] Append(in $match<-1,0> void value ) : structuredbuffer_append; + +} namespace + +namespace ConsumeStructuredBufferMethods { + +void [[]] GetDimensions(out uint_only count, out uint_only stride) : bufinfo; +$classT [[]] Consume() : structuredbuffer_consume; + +} namespace + +namespace FeedbackTexture2DMethods { + +void [[]] WriteSamplerFeedback(in Texture2D t, in sampler s, in float<2> x); +void [[]] WriteSamplerFeedback(in Texture2D t, in sampler s, in float<2> x, in float clamp); +void [[]] WriteSamplerFeedbackBias(in Texture2D t, in sampler s, in float<2> x, in float bias); +void [[]] WriteSamplerFeedbackBias(in Texture2D t, in sampler s, in float<2> x, in float bias, in float clamp); +void [[]] WriteSamplerFeedbackGrad(in Texture2D t, in sampler s, in float<2> x, in float<2> ddx, in float<2> ddy); +void [[]] WriteSamplerFeedbackGrad(in Texture2D t, in sampler s, in float<2> x, in float<2> ddx, in float<2> ddy, in float clamp); +void [[]] WriteSamplerFeedbackLevel(in Texture2D t, in sampler s, in float<2> x, in float lod); + +} namespace + +namespace FeedbackTexture2DArrayMethods { + +void [[]] WriteSamplerFeedback(in Texture2DArray t, in sampler s, in float<3> x); +void [[]] WriteSamplerFeedback(in Texture2DArray t, in sampler s, in float<3> x, in float clamp); +void [[]] WriteSamplerFeedbackBias(in Texture2DArray t, in sampler s, in float<3> x, in float bias); +void [[]] WriteSamplerFeedbackBias(in Texture2DArray t, in sampler s, in float<3> x, in float bias, in float clamp); +void [[]] WriteSamplerFeedbackGrad(in Texture2DArray t, in sampler s, in float<3> x, in float<2> ddx, in float<2> ddy); +void [[]] WriteSamplerFeedbackGrad(in Texture2DArray t, in sampler s, in float<3> x, in float<2> ddx, in float<2> ddy, in float clamp); +void [[]] WriteSamplerFeedbackLevel(in Texture2DArray t, in sampler s, in float<3> x, in float lod); + +} namespace + +namespace RayQueryMethods { + +void [[]] TraceRayInline(in acceleration_struct AccelerationStructure, in uint RayFlags, in uint InstanceInclusionMask, in ray_desc Ray); +bool [[]] Proceed(); +void [[]] Abort(); +void [[]] CommitNonOpaqueTriangleHit(); +void [[]] CommitProceduralPrimitiveHit(in float t); +uint [[ro]] CommittedStatus(); +uint [[ro]] CandidateType(); +float<3,4> [[ro]] CandidateObjectToWorld3x4(); +float<4,3> [[ro]] CandidateObjectToWorld4x3(); +float<3,4> [[ro]] CandidateWorldToObject3x4(); +float<4,3> [[ro]] CandidateWorldToObject4x3(); +float<3,4> [[ro]] CommittedObjectToWorld3x4(); +float<4,3> [[ro]] CommittedObjectToWorld4x3(); +float<3,4> [[ro]] CommittedWorldToObject3x4(); +float<4,3> [[ro]] CommittedWorldToObject4x3(); +bool [[ro]] CandidateProceduralPrimitiveNonOpaque(); +bool [[ro]] CandidateTriangleFrontFace(); +bool [[ro]] CommittedTriangleFrontFace(); +float<2> [[ro]] CandidateTriangleBarycentrics(); +float<2> [[ro]] CommittedTriangleBarycentrics(); +uint [[ro]] RayFlags(); +float<3> [[ro]] WorldRayOrigin(); +float<3> [[ro]] WorldRayDirection(); +float [[ro]] RayTMin(); +float [[ro]] CandidateTriangleRayT(); +float [[ro]] CommittedRayT(); +uint [[ro]] CandidateInstanceIndex(); +uint [[ro]] CandidateInstanceID(); +uint [[ro]] CandidateGeometryIndex(); +uint [[ro]] CandidatePrimitiveIndex(); +float<3> [[ro]] CandidateObjectRayOrigin(); +float<3> [[ro]] CandidateObjectRayDirection(); +uint [[ro]] CommittedInstanceIndex(); +uint [[ro]] CommittedInstanceID(); +uint [[ro]] CommittedGeometryIndex(); +uint [[ro]] CommittedPrimitiveIndex(); +float<3> [[ro]] CommittedObjectRayOrigin(); +float<3> [[ro]] CommittedObjectRayDirection(); +uint [[ro]] CandidateInstanceContributionToHitGroupIndex(); +uint [[ro]] CommittedInstanceContributionToHitGroupIndex(); +uint [[ro,min_sm=6.10]] CandidateClusterID(); +uint [[ro,min_sm=6.10]] CommittedClusterID(); +triangle_positions [[ro,min_sm=6.10]] CandidateTriangleObjectPositions(); +triangle_positions [[ro,min_sm=6.10]] CommittedTriangleObjectPositions(); + +} namespace + +// Shader Execution Reordering +namespace DxHitObjectMethods { + DxHitObject [[static,class_prefix,min_sm=6.9]] MakeNop(); + DxHitObject [[static,class_prefix,min_sm=6.9]] MakeMiss(in uint RayFlags, in uint MissShaderIndex, in ray_desc Ray); + DxHitObject [[static,class_prefix,min_sm=6.9]] FromRayQuery(in RayQuery rq); + DxHitObject [[static,class_prefix,min_sm=6.9]] FromRayQuery(in RayQuery rq, in uint HitKind, in udt Attributes); + DxHitObject [[static,class_prefix,min_sm=6.9]] TraceRay(in acceleration_struct AccelerationStructure, in uint RayFlags, in uint InstanceInclusionMask, in uint RayContributionToHitGroupIndex, in uint MultiplierForGeometryContributionToHitGroupIndex, in uint MissShaderIndex, in ray_desc Ray, inout udt Payload); + void [[static,class_prefix,min_sm=6.9]] Invoke(in DxHitObject ho, inout udt Payload); + bool [[rn,class_prefix,min_sm=6.9]] IsMiss(); + bool [[rn,class_prefix,min_sm=6.9]] IsHit(); + bool [[rn,class_prefix,min_sm=6.9]] IsNop(); + uint [[rn,class_prefix,min_sm=6.9]] GetRayFlags(); + float [[rn,class_prefix,min_sm=6.9]] GetRayTMin(); + float [[rn,class_prefix,min_sm=6.9]] GetRayTCurrent(); + float<3> [[rn,class_prefix,min_sm=6.9]] GetWorldRayOrigin(); + float<3> [[rn,class_prefix,min_sm=6.9]] GetWorldRayDirection(); + float<3> [[rn,class_prefix,min_sm=6.9]] GetObjectRayOrigin(); + float<3> [[rn,class_prefix,min_sm=6.9]] GetObjectRayDirection(); + float<3,4> [[rn,class_prefix,min_sm=6.9]] GetObjectToWorld3x4(); + float<4,3> [[rn,class_prefix,min_sm=6.9]] GetObjectToWorld4x3(); + float<3,4> [[rn,class_prefix,min_sm=6.9]] GetWorldToObject3x4(); + float<4,3> [[rn,class_prefix,min_sm=6.9]] GetWorldToObject4x3(); + uint [[rn,class_prefix,min_sm=6.9]] GetGeometryIndex(); + uint [[rn,class_prefix,min_sm=6.9]] GetInstanceIndex(); + uint [[rn,class_prefix,min_sm=6.9]] GetInstanceID(); + uint [[rn,class_prefix,min_sm=6.9]] GetPrimitiveIndex(); + uint [[rn,class_prefix,min_sm=6.9]] GetHitKind(); + uint [[rn,class_prefix,min_sm=6.9]] GetShaderTableIndex(); + void [[class_prefix,min_sm=6.9]] GetAttributes(out udt Attributes); + void [[class_prefix,min_sm=6.9]] SetShaderTableIndex(in uint RecordIndex); + uint [[ro,class_prefix,min_sm=6.9]] LoadLocalRootTableConstant(in uint RootConstantOffsetInBytes); + uint [[rn,class_prefix,min_sm=6.10]] GetClusterID(); + triangle_positions [[rn,class_prefix,min_sm=6.10]] TriangleObjectPositions(); +} namespace + +namespace DxIntrinsics { +bool [[ro,min_sm=6.10]] IsDebuggerPresent(); +void [[min_sm=6.9]] MaybeReorderThread(in DxHitObject HitObject); +void [[min_sm=6.9]] MaybeReorderThread(in uint CoherenceHint, in uint NumCoherenceHintBitsFromLSB); +void [[min_sm=6.9]] MaybeReorderThread(in DxHitObject HitObject, in uint CoherenceHint, in uint NumCoherenceHintBitsFromLSB); +} namespace + +// Work Graphs objects and methods + +// EmptyNodeInput +namespace EmptyNodeInputMethods { + uint [[ro]] Count(); +} namespace + +// RWDispatchNodeInputRecord methods (in addition to Get) +namespace RWDispatchNodeInputRecordMethods { + bool [[]] FinishedCrossGroupSharing(); +} namespace + +// GroupNodeInputRecords methods (in addition to Get and array access subscript) +namespace GroupNodeInputRecordsMethods { + uint [[ro]] Count(); +} namespace + +// NodeOutput +namespace NodeOutputMethods { + $match<0,-2> ThreadNodeOutputRecords [[]] GetThreadNodeOutputRecords(in uint numRecords); + $match<0,-2> GroupNodeOutputRecords [[]] GetGroupNodeOutputRecords(in uint numRecords); + bool [[]] IsValid(); +} namespace + +// EmptyNodeOutput +namespace EmptyNodeOutputMethods { + void [[]] GroupIncrementOutputCount(in uint count); + void [[]] ThreadIncrementOutputCount(in uint count); + bool [[]] IsValid(); +} namespace + +// ThreadNodeOutputRecords, GroupNodeOutputRecords +namespace GroupOrThreadNodeOutputRecordsMethods { + void [[]] OutputComplete(); +} namespace + +// SPIRV Change Starts + +namespace VkSubpassInputMethods { +$classT [[]] SubpassLoad() : subpassinput_load; +} namespace + +namespace VkSubpassInputMSMethods { +$classT [[]] SubpassLoad(in int sample) : subpassinputms_load; +} namespace + +// SPIRV Change Ends + +namespace VkSampledTexture2DMethods { + $classT [[ro]] Sample(in float<2> x) : tex2d_t; + $classT [[ro]] Sample(in float<2> x, in int<2> o) : tex2d_t_o; + $classT [[ro]] Sample(in float<2> x, in int<2> o, in float clamp) : tex2d_t_o_cl; + $classT [[]] Sample(in float<2> x, in int<2> o, in float clamp, out uint_only status) : tex2d_t_o_cl_s; + float [[ro]] CalculateLevelOfDetail(in float<2> x) : tex2d_t_calc_lod; +} namespace diff --git a/submodules/DirectXShaderCompiler b/submodules/DirectXShaderCompiler deleted file mode 160000 index 83e35657fb..0000000000 --- a/submodules/DirectXShaderCompiler +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83e35657fb2c606e1c60ba0c741e5b60913b6735 From b607468c5616c74754b6323204b7e01a41b981fd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 11:01:10 +0900 Subject: [PATCH 0817/1182] Renamed test project --- SDSL.sln | 2 +- ...Shaders.Parsing.Tests.csproj => Stride.Shaders.Tests.csproj} | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) rename src/Stride.Shaders.Tests/{Stride.Shaders.Parsing.Tests.csproj => Stride.Shaders.Tests.csproj} (98%) diff --git a/SDSL.sln b/SDSL.sln index d638f6cf7c..c2229b6baf 100644 --- a/SDSL.sln +++ b/SDSL.sln @@ -11,7 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders", "src\Stride.Shaders\Stride.Shaders.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsing.Tests", "src\Stride.Shaders.Tests\Stride.Shaders.Parsing.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "src\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}" EndProject diff --git a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj b/src/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj similarity index 98% rename from src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj rename to src/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index 6bef03184e..c05a78d1ce 100644 --- a/src/Stride.Shaders.Tests/Stride.Shaders.Parsing.Tests.csproj +++ b/src/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -11,6 +11,7 @@ true + Stride.Shaders.Parsing.Tests From 24c63816f05a8f8260d7c37e5dd68a3247736ad7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Feb 2026 15:13:02 +0900 Subject: [PATCH 0818/1182] Removed obsolete sdsl.cs and sdfx.cs files --- .../Effects/CustomFogEffect.sdsl.cs | 27 --- .../Effects/SpaceEscapeEffectMain.sdfx.cs | 48 ----- .../Effects/TransformationBendWorld.sdsl.cs | 24 --- .../Effects/TransformationTextureUV.sdsl.cs | 23 --- .../CustomEffect.Game/Effects/Effect.sdsl.cs | 28 --- .../Effects/ComputeColorWave.sdsl.cs | 9 - .../Effects/ComputeColorWaveNormal.sdsl.cs | 9 - .../Effects/ComputeColorRadial.sdsl.cs | 9 - .../Effects/ComputeColorRed.sdsl.cs | 9 - .../Effects/ComputeColorTextureScroll.sdsl.cs | 9 - .../Effects/ParticleCustomEffect.sdfx.cs | 59 ------ .../Effects/ParticleCustomShader.sdsl.cs | 9 - .../Shaders/PreviewTexture.sdfx.cs | 46 ----- .../Shaders/SceneEditorParameters.sdfx.cs | 26 --- .../Shaders/SelectedSprite.sdfx.cs | 37 ---- .../StrideEditorForwardShadingEffect.sdfx.cs | 101 ---------- .../StrideEditorHighlightingEffect.sdfx.cs | 38 ---- .../StrideEditorMaterialPreviewEffect.sdfx.cs | 39 ---- .../Effect/EffectCompositorAsset.cs | 2 - .../Stride.Assets/Effect/EffectShaderAsset.cs | 2 - .../Effects/SinglePassWireframeShader.sdsl.cs | 25 --- .../StrideSinglePassWireframeShader.sdfx.cs | 37 ---- .../Assets/LightTiling.sdsl.cs | 25 --- .../MultipleRenderTargetsEffect.sdfx.cs | 37 ---- .../MultipleRenderTargetsEffectShader.sdsl.cs | 9 - .../Assets/ComputeShaderTest.sdsl.cs | 24 --- .../Assets/ComputeShaderTestEffect.sdfx.cs | 40 ---- .../Assets/CubemapSprite.sdsl.cs | 23 --- .../Assets/HammersleyTest.sdsl.cs | 24 --- .../Compiler/CubemapEffect.sdfx.cs | 135 ------------- .../Compiler/CustomEffect.sdfx.cs | 65 ------- .../Compiler/CustomShader.sdsl.cs | 23 --- .../MultiTexturesSpriteEffect.sdfx.cs | 36 ---- .../MultiTexturesSpriteShader.sdsl.cs | 9 - .../Compiler/SimpleEffect.sdfx.cs | 36 ---- .../Compiler/SimpleShader.sdsl.cs | 23 --- .../Compiler/ToGlslEffect.sdfx.cs | 36 ---- .../Compiler/ToGlslShader.sdsl.cs | 25 --- .../Shaders/ColorUtility.sdsl.cs | 9 - .../Shaders/ShaderBase.sdsl.cs | 9 - .../Shaders/ShaderBaseStream.sdsl.cs | 9 - .../Shaders/SignedDistanceFieldFont.sdsl.cs | 9 - .../SignedDistanceFieldFontShader.sdsl.cs | 9 - .../Shaders/SpriteAlphaCutoff.sdsl.cs | 42 ---- .../Shaders/SpriteBase.sdsl.cs | 23 --- .../Shaders/SpriteBatch.sdfx.cs | 36 ---- .../Shaders/SpriteBatchShader.sdsl.cs | 9 - .../Shaders/SpriteEffect.sdsl.cs | 23 --- .../Shaders/SpriteEffectExtTexture.sdsl.cs | 26 --- .../SpriteEffectExtTextureRegular.sdsl.cs | 25 --- ...priteSignedDistanceFieldFontShader.sdsl.cs | 23 --- .../Shaders/SpriteSuperSampler.sdsl.cs | 9 - .../Stride.Graphics/Shaders/Texturing.sdsl.cs | 70 ------- .../Stride.Graphics/Shaders/UIEffect.sdfx.cs | 36 ---- .../Shaders/UIEffectShader.sdsl.cs | 9 - .../Shaders/ComputeColorWhite.sdsl.cs | 9 - .../Shaders/ParticleBase.sdsl.cs | 26 --- .../Shaders/ParticleBaseEffect.sdfx.cs | 37 ---- .../Shaders/ParticleColor.sdsl.cs | 9 - .../Shaders/ParticleColorStream.sdsl.cs | 9 - .../ParticleComputeColorShader.sdsl.cs | 9 - .../Shaders/ParticleEffect.sdfx.cs | 48 ----- .../Shaders/ParticleUtilities.sdsl.cs | 27 --- .../Rendering/BRDF/BRDFMicrofacet.sdsl.cs | 9 - .../BackgroundCubemapShader.sdsl.cs | 23 --- .../Background/BackgroundShader.sdsl.cs | 23 --- .../MSAADepthResolverShader.sdsl.cs | 25 --- .../Compositing/MSAAResolverEffect.sdfx.cs | 61 ------ .../Compositing/MSAAResolverShader.sdsl.cs | 25 --- .../ComputeEffect/ComputeEffectShader.sdfx.cs | 40 ---- .../ComputeEffect/ComputeShaderBase.sdsl.cs | 9 - .../GGXPrefiltering/Hammersley.sdsl.cs | 9 - .../ImportanceSamplingGGX.sdsl.cs | 9 - .../RadiancePrefilteringGGXEffect.sdfx.cs | 40 ---- ...ancePrefilteringGGXNoComputeEffect.sdfx.cs | 40 ---- ...ancePrefilteringGGXNoComputeShader.sdsl.cs | 27 --- .../RadiancePrefilteringGGXShader.sdsl.cs | 27 --- .../LambertianPrefilteringSH.sdfx.cs | 57 ------ ...rtianPrefilteringSHNoComputeEffect.sdfx.cs | 36 ---- ...ertianPrefilteringSHNoComputePass1.sdsl.cs | 24 --- ...ertianPrefilteringSHNoComputePass2.sdsl.cs | 9 - .../LambertianPrefilteringSHPass1.sdsl.cs | 24 --- .../LambertianPrefilteringSHPass2.sdsl.cs | 24 --- .../Rendering/Core/BackgroundVelocity.sdsl.cs | 23 --- .../Core/BackgroundVelocityEffect.sdfx.cs | 40 ---- .../Rendering/Core/ColorBase.sdsl.cs | 9 - .../Rendering/Core/DynamicSampler.sdsl.cs | 9 - .../Rendering/Core/DynamicTexture.sdsl.cs | 9 - .../Rendering/Core/DynamicTextureCube.sdsl.cs | 9 - .../Core/DynamicTextureStream.sdsl.cs | 9 - .../Rendering/Core/MeshVelocity.sdsl.cs | 23 --- .../Rendering/Core/NormalBase.sdsl.cs | 9 - .../Rendering/Core/NormalFromMesh.sdsl.cs | 9 - .../Core/NormalFromMeshInstanced.sdsl.cs | 9 - .../Core/NormalFromNormalMapping.sdsl.cs | 9 - .../NormalFromNormalMappingInstanced.sdsl.cs | 9 - ...ormalFromNormalMappingTessellation.sdsl.cs | 9 - ...NormalMappingTessellationInstanced.sdsl.cs | 9 - .../Rendering/Core/NormalStream.sdsl.cs | 9 - .../Rendering/Core/NormalUpdate.sdsl.cs | 9 - .../Rendering/Core/PositionHStream4.sdsl.cs | 9 - .../Rendering/Core/PositionStream.sdsl.cs | 9 - .../Rendering/Core/PositionStream4.sdsl.cs | 9 - .../Core/PositionVertexTransform.sdsl.cs | 9 - .../Rendering/Core/ScreenPositionBase.sdsl.cs | 9 - .../Rendering/Core/ShadingBase.sdsl.cs | 9 - .../Rendering/Core/ShadingColor.sdsl.cs | 9 - .../Rendering/Core/VelocityOutput.sdsl.cs | 9 - .../Rendering/Core/VelocityStream.sdsl.cs | 9 - .../Rendering/Deferred/GBuffer.sdsl.cs | 9 - .../Editor/CompilationErrorShader.sdsl.cs | 9 - .../Rendering/Editor/EffectCompiling.sdsl.cs | 9 - .../Editor/LightConstantWhite.sdsl.cs | 9 - .../Editor/SelectedSpriteShader.sdsl.cs | 23 --- .../Editor/SharedTextureCoordinate.sdsl.cs | 9 - .../Rendering/Editor/Sprite3DBase.sdsl.cs | 23 --- .../Rendering/Editor/SpritePicking.sdsl.cs | 9 - .../AmbientOcclusionBlurEffect.sdfx.cs | 36 ---- .../AmbientOcclusionBlurShader.sdsl.cs | 23 --- .../AmbientOcclusionRawAOEffect.sdfx.cs | 36 ---- .../AmbientOcclusionRawAOShader.sdsl.cs | 29 --- .../ApplyAmbientOcclusionShader.sdsl.cs | 9 - .../Images/AntiAliasing/FXAAShader.sdsl.cs | 9 - .../AntiAliasing/FXAAShaderEffect.sdfx.cs | 38 ---- .../TemporalAntiAliasShader.sdsl.cs | 33 ---- .../BloomAfterimageCombineShader.sdsl.cs | 9 - .../Bloom/BloomAfterimageShader.sdsl.cs | 24 --- .../BrightFilter/BrightFilterShader.sdsl.cs | 25 --- .../ColorCombiner/ColorCombinerEffect.sdfx.cs | 36 ---- .../ColorCombiner/ColorCombinerShader.sdsl.cs | 24 --- .../ColorTransformGroupEffect.sdfx.cs | 67 ------- .../ColorTransformGroupShader.sdsl.cs | 9 - .../ColorTransformShader.sdsl.cs | 9 - .../LuminanceToChannelShader.sdsl.cs | 9 - .../Noise/FilmGrainShader.sdsl.cs | 26 --- .../ToneMap/ToneMapACESOperatorShader.sdsl.cs | 9 - .../ToneMapCommonOperatorShader.sdsl.cs | 24 --- .../ToneMapDragoOperatorShader.sdsl.cs | 23 --- .../ToneMap/ToneMapEffect.sdfx.cs | 46 ----- .../ToneMapExponentialOperatorShader.sdsl.cs | 9 - .../ToneMapHejl2OperatorShader.sdsl.cs | 23 --- .../ToneMapHejlDawsonOperatorShader.sdsl.cs | 9 - .../ToneMapLogarithmicOperatorShader.sdsl.cs | 9 - .../ToneMapMikeDayOperatorShader.sdsl.cs | 25 --- .../ToneMap/ToneMapOperatorShader.sdsl.cs | 9 - .../ToneMapReinhardOperatorShader.sdsl.cs | 9 - .../ToneMap/ToneMapShader.sdsl.cs | 29 --- .../ToneMapU2FilmicOperatorShader.sdsl.cs | 29 --- .../Vignetting/VignettingShader.sdsl.cs | 25 --- .../DepthMinMax/DepthMinMaxEffect.sdfx.cs | 36 ---- .../DepthMinMax/DepthMinMaxShader.sdsl.cs | 24 --- .../Hexagonal/McIntoshCombineShader.sdsl.cs | 9 - .../Hexagonal/McIntoshOptimizedEffect.sdfx.cs | 52 ----- .../Hexagonal/McIntoshOptimizedShader.sdsl.cs | 9 - .../TripleRhombiCombineShader.sdsl.cs | 23 --- .../DepthOfField/CircleOfConfusion.sdsl.cs | 23 --- .../DepthOfField/CoCLinearDepthShader.sdsl.cs | 9 - .../DepthOfField/CoCMapBlurEffect.sdfx.cs | 36 ---- .../DepthOfField/CoCMapBlurShader.sdsl.cs | 25 --- .../CombineFrontCoCEffect.sdfx.cs | 36 ---- .../CombineFrontCoCShader.sdsl.cs | 9 - .../CombineLevelsFromCoCEffect.sdfx.cs | 36 ---- .../CombineLevelsFromCoCShader.sdsl.cs | 23 --- .../DepthAwareDirectionalBlurEffect.sdfx.cs | 36 ---- .../DepthAwareDirectionalBlurShader.sdsl.cs | 9 - .../DepthAwareDirectionalBlurUtil.sdsl.cs | 26 --- .../Images/DepthOfField/PointDepth.sdsl.cs | 23 --- .../DepthOfField/ThresholdAlphaCoC.sdsl.cs | 24 --- .../ThresholdAlphaCoCFront.sdsl.cs | 24 --- .../Rendering/Images/Dither/Dither.sdsl.cs | 23 --- .../GaussianBlur/GaussianBlurEffect.sdfx.cs | 36 ---- .../GaussianBlur/GaussianBlurShader.sdsl.cs | 23 --- .../Images/ImageEffectShader.sdsl.cs | 9 - .../ImageScaler/ImageScalerEffect.sdfx.cs | 54 ------ .../ImageScaler/ImageScalerShader.sdsl.cs | 24 --- .../LensFlare/FlareArtifactEffect.sdfx.cs | 36 ---- .../LensFlare/FlareArtifactShader.sdsl.cs | 26 --- .../Images/LensFlare/FlareReplicate.sdsl.cs | 24 --- .../LightShafts/AdditiveLightEffect.sdsl.cs | 36 ---- .../LightShafts/AdditiveLightShader.sdsl.cs | 23 --- .../LightShafts/LightShaftsEffect.sdfx.cs | 44 ----- .../LightShafts/LightShaftsShader.sdsl.cs | 23 --- .../LightShafts/PostEffectBoundingRay.sdsl.cs | 9 - .../LightShafts/VolumeMinMaxShader.sdsl.cs | 23 --- .../LightStreak/LightStreakEffect.sdfx.cs | 36 ---- .../LightStreak/LightStreakShader.sdsl.cs | 26 --- .../LocalReflections/SSLRBlurPass.sdsl.cs | 58 ------ .../LocalReflections/SSLRCombinePass.sdsl.cs | 9 - .../LocalReflections/SSLRCommon.sdsl.cs | 34 ---- .../LocalReflections/SSLRDepthPass.sdsl.cs | 9 - .../LocalReflections/SSLRRayTracePass.sdsl.cs | 24 --- .../LocalReflections/SSLRResolvePass.sdsl.cs | 39 ---- .../LocalReflections/SSLRTemporalPass.sdsl.cs | 26 --- .../LuminanceLogShader.sdsl.cs | 9 - .../LuminanceEffect/LuminanceUtils.sdsl.cs | 9 - .../RangeCompressorShader.sdsl.cs | 9 - .../RangeDecompressorShader.sdsl.cs | 9 - .../SphericalHarmonicsBase.sdsl.cs | 9 - .../SphericalHarmonicsParameters.sdfx.cs | 23 --- .../SphericalHarmonicsRenderer.sdsl.cs | 23 --- .../SphericalHarmonicsRendererEffect.sdfx.cs | 36 ---- .../SphericalHarmonicsUtils.sdsl.cs | 9 - .../SubsurfaceScatteringBlurEffect.sdfx.cs | 37 ---- .../SubsurfaceScatteringBlurShader.sdsl.cs | 27 --- .../LightProbes/BakeLightProbeShader.sdsl.cs | 23 --- .../ComputeSphericalHarmonics.sdsl.cs | 23 --- .../LightProbes/LightProbeShader.sdsl.cs | 27 --- .../StrideBakeLightProbeEffect.sdfx.cs | 38 ---- .../Rendering/Lights/DirectLightGroup.sdsl.cs | 9 - .../Lights/DirectLightGroupArray.sdsl.cs | 9 - .../Lights/DirectLightGroupFixed.sdsl.cs | 9 - .../Lights/DirectLightGroupPerDraw.sdsl.cs | 23 --- .../Lights/DirectLightGroupPerView.sdsl.cs | 23 --- .../Rendering/Lights/EnvironmentLight.sdsl.cs | 9 - .../Lights/EnvironmentLightArray.sdsl.cs | 9 - .../Rendering/Lights/LightClustered.sdsl.cs | 27 --- .../Lights/LightClusteredPointGroup.sdsl.cs | 23 --- .../Lights/LightClusteredSpotGroup.sdsl.cs | 23 --- .../Rendering/Lights/LightDirectional.sdsl.cs | 9 - .../Lights/LightDirectionalGroup.sdsl.cs | 23 --- .../Rendering/Lights/LightPoint.sdsl.cs | 9 - .../Rendering/Lights/LightPointGroup.sdsl.cs | 23 --- .../Lights/LightSimpleAmbient.sdsl.cs | 23 --- .../Lights/LightSkyboxEffect.sdfx.cs | 59 ------ .../Lights/LightSkyboxShader.sdsl.cs | 24 --- .../Rendering/Lights/LightSpot.sdsl.cs | 9 - .../LightSpotAttenuationDefault.sdsl.cs | 9 - .../LightSpotAttenuationRectangular.sdsl.cs | 9 - .../Rendering/Lights/LightSpotGroup.sdsl.cs | 23 --- .../Rendering/Lights/LightStream.sdsl.cs | 9 - .../Rendering/Lights/LightUtil.sdsl.cs | 9 - .../SpotLightDataInternalShader.sdsl.cs | 9 - .../TextureProjectionCommon.sdsl.cs | 9 - .../TextureProjectionFilterDefault.sdsl.cs | 9 - .../TextureProjectionGroup.sdsl.cs | 9 - .../TextureProjectionReceiverBase.sdsl.cs | 26 --- .../TextureProjectionReceiverSpot.sdsl.cs | 9 - .../MaterialCelShadingLightRamp.sdsl.cs | 23 --- .../Shaders/3dsMax/ComputeColorAdd3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorDarken3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorDifference3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorLighten3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorMask3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorMultiply3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorOver3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorOverlay3ds.sdsl.cs | 9 - .../3dsMax/ComputeColorSubtract3ds.sdsl.cs | 9 - .../Shaders/ComputeColor.sdsl.cs | 9 - .../Shaders/ComputeColor3.sdsl.cs | 9 - .../Shaders/ComputeColorAdd.sdsl.cs | 9 - .../Shaders/ComputeColorAdd3.sdsl.cs | 9 - .../Shaders/ComputeColorAverage.sdsl.cs | 9 - .../Shaders/ComputeColorCave.sdsl.cs | 9 - .../Shaders/ComputeColorColor.sdsl.cs | 9 - .../Shaders/ComputeColorColorBurn.sdsl.cs | 9 - .../Shaders/ComputeColorColorDodge.sdsl.cs | 9 - .../ComputeColorConstantColor3Link.sdsl.cs | 9 - .../ComputeColorConstantColorLink.sdsl.cs | 9 - .../ComputeColorConstantFloatLink.sdsl.cs | 9 - .../Shaders/ComputeColorConstantLink.sdsl.cs | 9 - .../Shaders/ComputeColorDesaturate.sdsl.cs | 9 - .../Shaders/ComputeColorDivide.sdsl.cs | 9 - .../Shaders/ComputeColorExclusion.sdsl.cs | 9 - .../Shaders/ComputeColorFixed.sdsl.cs | 9 - .../Shaders/ComputeColorFromStream.sdsl.cs | 9 - .../Shaders/ComputeColorHardLight.sdsl.cs | 9 - .../Shaders/ComputeColorHardMix.sdsl.cs | 9 - .../Shaders/ComputeColorHue.sdsl.cs | 9 - .../Shaders/ComputeColorIlluminate.sdsl.cs | 9 - .../Shaders/ComputeColorIn.sdsl.cs | 9 - .../Shaders/ComputeColorLerpAlpha.sdsl.cs | 9 - .../Shaders/ComputeColorLinearBurn.sdsl.cs | 9 - .../Shaders/ComputeColorLinearDodge.sdsl.cs | 9 - .../Shaders/ComputeColorMask.sdsl.cs | 9 - .../Shaders/ComputeColorMultiply.sdsl.cs | 9 - .../Shaders/ComputeColorOne.sdsl.cs | 9 - .../Shaders/ComputeColorOut.sdsl.cs | 9 - .../Shaders/ComputeColorOutdoor.sdsl.cs | 9 - .../Shaders/ComputeColorOverlay.sdsl.cs | 9 - .../Shaders/ComputeColorParameter.sdsl.cs | 23 --- .../Shaders/ComputeColorPinLight.sdsl.cs | 9 - .../Shaders/ComputeColorSaturate.sdsl.cs | 9 - .../Shaders/ComputeColorSaturation.sdsl.cs | 9 - .../Shaders/ComputeColorScaler.sdsl.cs | 9 - .../Shaders/ComputeColorScreen.sdsl.cs | 9 - .../Shaders/ComputeColorSoftLight.sdsl.cs | 9 - .../Shaders/ComputeColorStream.sdsl.cs | 9 - .../ComputeColorSubstituteAlpha.sdsl.cs | 9 - ...mputeColorSubstituteAlphaWithColor.sdsl.cs | 9 - .../Shaders/ComputeColorSubtract.sdsl.cs | 9 - .../Shaders/ComputeColorSynthetic.sdsl.cs | 9 - .../Shaders/ComputeColorTexture.sdsl.cs | 9 - ...uteColorTextureDynamicScaledOffset.sdsl.cs | 24 --- .../ComputeColorTextureLodSampler.sdsl.cs | 9 - ...xtureLodScaledOffsetDynamicSampler.sdsl.cs | 9 - ...ColorTextureLodScaledOffsetSampler.sdsl.cs | 9 - ...omputeColorTextureLodScaledSampler.sdsl.cs | 9 - .../Shaders/ComputeColorTextureRepeat.sdsl.cs | 9 - .../ComputeColorTextureSampler.sdsl.cs | 9 - .../Shaders/ComputeColorTextureScaled.sdsl.cs | 9 - .../ComputeColorTextureScaledOffset.sdsl.cs | 9 - ...rTextureScaledOffsetDynamicSampler.sdsl.cs | 9 - ...ScaledOffsetDynamicSamplerRandomUV.sdsl.cs | 9 - ...uteColorTextureScaledOffsetSampler.sdsl.cs | 9 - .../ComputeColorTextureScaledSampler.sdsl.cs | 9 - .../Shaders/ComputeColorThreshold.sdsl.cs | 9 - .../Shaders/ComputeColorValue.sdsl.cs | 9 - .../Shaders/Maya/ComputeColorAddMaya.sdsl.cs | 9 - .../Maya/ComputeColorDarkenMaya.sdsl.cs | 9 - .../Maya/ComputeColorDifferenceMaya.sdsl.cs | 9 - .../Maya/ComputeColorLightenMaya.sdsl.cs | 9 - .../Maya/ComputeColorMultiplyMaya.sdsl.cs | 9 - .../Shaders/Maya/ComputeColorOverMaya.sdsl.cs | 9 - .../Maya/ComputeColorSubtractMaya.sdsl.cs | 9 - .../IMaterialHairDirectionFunction.sdsl.cs | 9 - ...rialHairDirectionFunctionBitangent.sdsl.cs | 9 - ...terialHairDirectionFunctionTangent.sdsl.cs | 9 - .../IMaterialHairDiscardFunction.sdsl.cs | 9 - ...erialHairDiscardFunctionOpaquePass.sdsl.cs | 9 - ...HairDiscardFunctionTransparentPass.sdsl.cs | 9 - ...terialHairLightAttenuationFunction.sdsl.cs | 9 - ...ightAttenuationFunctionDirectional.sdsl.cs | 9 - ...alHairLightAttenuationFunctionNone.sdsl.cs | 9 - .../Materials/Hair/MaterialHairShared.sdsl.cs | 23 --- .../MaterialSurfaceShadingDiffuseHair.sdsl.cs | 9 - ...MaterialSurfaceShadingSpecularHair.sdsl.cs | 33 ---- .../IMaterialHairShadowingFunction.sdsl.cs | 9 - ...ialHairShadowingFunctionScattering.sdsl.cs | 9 - ...rialHairShadowingFunctionShadowing.sdsl.cs | 9 - .../Materials/IMaterialSurfaceDomain.sdsl.cs | 9 - .../Materials/IStreamInitializer.sdsl.cs | 9 - .../MaterialDisplacementStream.sdsl.cs | 9 - .../Materials/MaterialDomainStream.sdsl.cs | 9 - .../MaterialStreamAdditiveBlend.sdsl.cs | 9 - .../MaterialSurfaceDisplacement.sdsl.cs | 9 - ...terialSurfaceDomainStageCompositor.sdsl.cs | 9 - .../MaterialTessellationStream.sdsl.cs | 9 - .../ComputeColorMaterialAlphaBlend.sdsl.cs | 9 - .../Shaders/GBufferOutputNormals.sdsl.cs | 9 - ...BufferOutputSpecularColorRoughness.sdsl.cs | 9 - ...tSubsurfaceScatteringMaterialIndex.sdsl.cs | 23 --- ...cularMicrofacetEnvironmentFunction.sdsl.cs | 9 - ...lSpecularMicrofacetFresnelFunction.sdsl.cs | 9 - ...crofacetNormalDistributionFunction.sdsl.cs | 9 - ...ecularMicrofacetVisibilityFunction.sdsl.cs | 9 - .../Shaders/IMaterialStreamBlend.sdsl.cs | 9 - .../Shaders/IMaterialSurface.sdsl.cs | 9 - .../Shaders/IMaterialSurfacePixel.sdsl.cs | 9 - .../Shaders/IMaterialSurfaceShading.sdsl.cs | 9 - .../Shaders/IMaterialSurfaceVertex.sdsl.cs | 9 - .../MaterialFrontBackBlendShader.sdsl.cs | 26 --- .../MaterialPixelShadingStream.sdsl.cs | 9 - .../Shaders/MaterialPixelStream.sdsl.cs | 9 - ...pecularMicrofacetEnvironmentGGXLUT.sdsl.cs | 23 --- ...MicrofacetEnvironmentGGXPolynomial.sdsl.cs | 9 - ...ularMicrofacetEnvironmentThinGlass.sdsl.cs | 9 - ...erialSpecularMicrofacetFresnelNone.sdsl.cs | 9 - ...alSpecularMicrofacetFresnelSchlick.sdsl.cs | 9 - ...SpecularMicrofacetFresnelThinGlass.sdsl.cs | 9 - ...crofacetNormalDistributionBeckmann.sdsl.cs | 9 - ...ofacetNormalDistributionBlinnPhong.sdsl.cs | 9 - ...larMicrofacetNormalDistributionGGX.sdsl.cs | 9 - ...arMicrofacetVisibilityCookTorrance.sdsl.cs | 9 - ...ecularMicrofacetVisibilityImplicit.sdsl.cs | 9 - ...pecularMicrofacetVisibilityKelemen.sdsl.cs | 9 - ...pecularMicrofacetVisibilityNeumann.sdsl.cs | 9 - ...rMicrofacetVisibilitySmithBeckmann.sdsl.cs | 9 - ...ofacetVisibilitySmithGGXCorrelated.sdsl.cs | 9 - ...acetVisibilitySmithSchlickBeckmann.sdsl.cs | 9 - ...icrofacetVisibilitySmithSchlickGGX.sdsl.cs | 9 - .../Materials/Shaders/MaterialStream.sdsl.cs | 9 - .../Shaders/MaterialStreamLinearBlend.sdsl.cs | 9 - .../Shaders/MaterialStreamNormalBlend.sdsl.cs | 9 - .../Shaders/MaterialSurfaceArray.sdsl.cs | 9 - .../Shaders/MaterialSurfaceDiffuse.sdsl.cs | 9 - .../MaterialSurfaceDiffuseMetalFlakes.sdsl.cs | 9 - ...faceDiffuseSpecularAlphaBlendColor.sdsl.cs | 9 - .../MaterialSurfaceEmissiveShading.sdsl.cs | 9 - .../MaterialSurfaceGlossinessMap.sdsl.cs | 9 - ...ialSurfaceGlossinessMapMetalFlakes.sdsl.cs | 9 - .../MaterialSurfaceLightingAndShading.sdsl.cs | 9 - .../Shaders/MaterialSurfaceMetalness.sdsl.cs | 9 - .../Shaders/MaterialSurfaceNormalMap.sdsl.cs | 9 - ...MaterialSurfaceNormalStreamShading.sdsl.cs | 9 - ...aterialSurfacePixelStageCompositor.sdsl.cs | 9 - ...alSurfaceSetStreamFromComputeColor.sdsl.cs | 9 - .../MaterialSurfaceShadingBlend.sdsl.cs | 9 - ...terialSurfaceShadingDiffuseLambert.sdsl.cs | 9 - ...alSurfaceShadingSpecularBlinnPhong.sdsl.cs | 9 - ...alSurfaceShadingSpecularMicrofacet.sdsl.cs | 9 - .../MaterialSurfaceStreamShading.sdsl.cs | 9 - .../MaterialSurfaceStreamsBlend.sdsl.cs | 9 - ...aterialSurfaceTransmittanceShading.sdsl.cs | 9 - ...rialSurfaceTransparentAlphaDiscard.sdsl.cs | 9 - .../MaterialSurfaceVertexDisplacement.sdsl.cs | 9 - ...terialSurfaceVertexStageCompositor.sdsl.cs | 9 - ...rialTransmittanceReflectanceStream.sdsl.cs | 23 --- .../Shaders/MaterialVertexStream.sdsl.cs | 9 - ...SurfaceSubsurfaceScatteringShading.sdsl.cs | 24 --- ...surfaceScatteringScatteringProfile.sdsl.cs | 9 - ...ringScatteringProfileCustomUniform.sdsl.cs | 23 --- ...ringScatteringProfileCustomVarying.sdsl.cs | 9 - ...aceScatteringScatteringProfileSkin.sdsl.cs | 9 - .../ProceduralModels/CameraCube.sdsl.cs | 24 --- .../Rendering/Shaders/Camera.sdsl.cs | 27 --- .../Rendering/Shaders/Global.sdsl.cs | 24 --- .../Rendering/Shaders/GlobalVR.sdsl.cs | 24 --- .../Rendering/Shaders/Transformation.sdsl.cs | 37 ---- .../Rendering/Shadows/ShadowGroup.sdsl.cs | 9 - .../Rendering/Shadows/ShadowMapCaster.sdfx.cs | 48 ----- .../ShadowMapCasterAlphaDiscard.sdsl.cs | 9 - .../ShadowMapCasterAlphaDithered.sdsl.cs | 9 - .../Shadows/ShadowMapCasterCubeMap.sdfx.cs | 49 ----- .../ShadowMapCasterCubeMapProjection.sdsl.cs | 9 - .../ShadowMapCasterNoPixelShader.sdsl.cs | 9 - .../Shadows/ShadowMapCasterParaboloid.sdfx.cs | 49 ----- ...hadowMapCasterParaboloidProjection.sdsl.cs | 23 --- .../Shadows/ShadowMapCasterVsm.sdsl.cs | 9 - .../Rendering/Shadows/ShadowMapCommon.sdsl.cs | 9 - .../Shadows/ShadowMapFilterBase.sdsl.cs | 9 - .../Shadows/ShadowMapFilterDefault.sdsl.cs | 9 - .../Shadows/ShadowMapFilterPcf.sdsl.cs | 9 - .../Shadows/ShadowMapFilterVsm.sdsl.cs | 24 --- .../Rendering/Shadows/ShadowMapGroup.sdsl.cs | 9 - .../Shadows/ShadowMapReceiverBase.sdsl.cs | 28 --- .../ShadowMapReceiverDirectional.sdsl.cs | 23 --- .../ShadowMapReceiverPointCubeMap.sdsl.cs | 27 --- .../ShadowMapReceiverPointParaboloid.sdsl.cs | 28 --- .../Shadows/ShadowMapReceiverSpot.sdsl.cs | 9 - .../Rendering/Shadows/ShadowStream.sdsl.cs | 9 - .../Skinning/NormalMeshSkinning.sdsl.cs | 9 - .../Skinning/NormalVSSkinningFromMesh.sdsl.cs | 9 - .../NormalVSSkinningNormalMapping.sdsl.cs | 9 - ...SSkinningNormalMappingTessellation.sdsl.cs | 9 - .../Skinning/TangentMeshSkinning.sdsl.cs | 9 - .../Skinning/TransformationSkinning.sdsl.cs | 23 --- .../TransformationSkinningInstanced.sdsl.cs | 9 - .../Rendering/Skyboxes/CubemapUtils.sdsl.cs | 9 - .../Skyboxes/IComputeEnvironmentColor.sdsl.cs | 9 - .../LevelCubeMapEnvironmentColor.sdsl.cs | 24 --- .../RoughnessCubeMapEnvironmentColor.sdsl.cs | 24 --- .../Skyboxes/SkyboxShaderBase.sdsl.cs | 26 --- .../Skyboxes/SkyboxShaderCubemap.sdsl.cs | 23 --- .../Skyboxes/SkyboxShaderTexture.sdsl.cs | 23 --- .../Rendering/Skyboxes/SkyboxStream.sdsl.cs | 9 - ...SphericalHarmonicsEnvironmentColor.sdsl.cs | 23 --- .../Rendering/StrideEffectBase.sdfx.cs | 180 ------------------ .../StrideForwardShadingEffect.sdfx.cs | 133 ------------- .../StrideWireframeShadingEffect.sdfx.cs | 39 ---- .../Tessellation/TessellationAE2.sdsl.cs | 9 - .../Tessellation/TessellationAE3.sdsl.cs | 9 - .../Tessellation/TessellationAE4.sdsl.cs | 9 - .../Tessellation/TessellationBase.sdsl.cs | 9 - .../Tessellation/TessellationFlat.sdsl.cs | 9 - .../Tessellation/TessellationPN.sdsl.cs | 9 - .../Transformation/TransformationBase.sdsl.cs | 9 - .../TransformationInstancing.sdsl.cs | 24 --- .../TransformationMatrix.sdsl.cs | 9 - .../TransformationWAndVP.sdsl.cs | 9 - .../TransformationWAndVPInstanced.sdsl.cs | 9 - .../Transformation/TransformationWVP.sdsl.cs | 9 - .../Transformation/TransformationZero.sdsl.cs | 9 - .../Rendering/Utils/BlendUtils.sdsl.cs | 9 - .../Rendering/Utils/DepthBase.sdsl.cs | 23 --- .../Rendering/Utils/FlattenLayers.sdsl.cs | 9 - .../Rendering/Utils/HSVUtils.sdsl.cs | 9 - .../Rendering/Utils/HighlightShader.sdsl.cs | 23 --- .../Rendering/Utils/Math.sdsl.cs | 9 - .../Utils/ModelComponentPickingEffect.sdfx.cs | 37 ---- .../Utils/ModelComponentPickingShader.sdsl.cs | 25 --- .../Rendering/Utils/NormalPack.sdsl.cs | 9 - .../Rendering/Utils/NormalUtil.sdsl.cs | 9 - .../Rendering/Utils/Picking.sdfx.cs | 36 ---- .../Rendering/Utils/PickingShader.sdsl.cs | 23 --- .../Rendering/Utils/SwapUV.sdsl.cs | 9 - .../Rendering/Utils/Utilities.sdsl.cs | 9 - .../GameAssets/Compiler/SimpleEffect.sdfx.cs | 36 ---- .../GameAssets/Compiler/SimpleShader.sdsl.cs | 23 --- .../GameAssets/Compiler/TestStream.sdsl.cs | 9 - .../GameAssets/Compiler/ToGlslEffect.sdfx.cs | 36 ---- .../GameAssets/Compiler/ToGlslShader.sdsl.cs | 24 --- .../GameAssets/Mixins/A.sdsl.cs | 9 - .../GameAssets/Mixins/B.sdsl.cs | 9 - .../GameAssets/Mixins/C.sdsl.cs | 9 - .../GameAssets/Mixins/C1.sdsl.cs | 9 - .../Mixins/TestComputeColor.sdsl.cs | 9 - .../Mixins/TestComputeColor2.sdsl.cs | 23 --- .../Mixins/TestComputeColorRedirect.sdsl.cs | 9 - .../Mixins/test_mixin_complex_params.sdfx.cs | 70 ------- .../Mixins/test_mixin_compose_keys.sdfx.cs | 101 ---------- .../Mixins/test_mixin_simple.sdfx.cs | 38 ---- .../Mixins/test_mixin_simple_child.sdfx.cs | 57 ------ .../test_mixin_simple_child_params.sdfx.cs | 69 ------- .../Mixins/test_mixin_simple_clone.sdfx.cs | 61 ------ .../Mixins/test_mixin_simple_compose.sdfx.cs | 46 ----- .../Mixins/test_mixin_simple_params.sdfx.cs | 69 ------- .../GameAssets/Shaders/BaseTestChild.sdsl.cs | 9 - .../GameAssets/Shaders/BaseTestInter.sdsl.cs | 9 - .../GameAssets/Shaders/BaseTestParent.sdsl.cs | 9 - .../GameAssets/Shaders/BasicMixin.sdsl.cs | 24 --- .../GameAssets/Shaders/BasicMixin2.sdsl.cs | 23 --- .../GameAssets/Shaders/Child.sdsl.cs | 24 --- .../GameAssets/Shaders/ChildError.sdsl.cs | 9 - .../GameAssets/Shaders/CloneTestBase.sdsl.cs | 9 - .../Shaders/CloneTestExtern.sdsl.cs | 9 - .../GameAssets/Shaders/CloneTestRoot.sdsl.cs | 9 - .../Shaders/ConstantBufferTest.sdsl.cs | 27 --- .../GameAssets/Shaders/CyclicTest.sdsl.cs | 9 - .../GameAssets/Shaders/DeepExtern.sdsl.cs | 9 - .../GameAssets/Shaders/DeepExternTest.sdsl.cs | 9 - .../GameAssets/Shaders/ExternClone.sdsl.cs | 9 - .../Shaders/ExternCloneTest.sdsl.cs | 9 - .../GameAssets/Shaders/ExternMixin.sdsl.cs | 23 --- .../GameAssets/Shaders/ExternTest.sdsl.cs | 9 - .../GameAssets/Shaders/ForEachTest.sdsl.cs | 23 --- .../GameAssets/Shaders/GenericCall.sdsl.cs | 9 - .../GameAssets/Shaders/GenericClass.sdsl.cs | 9 - .../GameAssets/Shaders/GenericClass2.sdsl.cs | 23 --- .../GameAssets/Shaders/GenericExtern.sdsl.cs | 9 - .../Shaders/GenericTexcoord.sdsl.cs | 23 --- .../Shaders/GeometryShaderTest.sdsl.cs | 9 - .../GameAssets/Shaders/InterfaceTest.sdsl.cs | 9 - .../Shaders/InternalReferenceMixin.sdsl.cs | 23 --- .../GameAssets/Shaders/MacroTest.sdsl.cs | 23 --- .../GameAssets/Shaders/MacroTestBase.sdsl.cs | 9 - .../GameAssets/Shaders/MacroTestChild.sdsl.cs | 9 - .../MixinFunctionParamaterTest.sdsl.cs | 9 - .../GameAssets/Shaders/MixinNameClash.sdsl.cs | 9 - .../Shaders/MixinNoNameClash.sdsl.cs | 9 - .../Shaders/NonStageStreamTest.sdsl.cs | 9 - .../GameAssets/Shaders/Parent.sdsl.cs | 24 --- .../GameAssets/Shaders/SemanticTest.sdsl.cs | 24 --- .../GameAssets/Shaders/Simple.sdsl.cs | 23 --- .../GameAssets/Shaders/StageBase.sdsl.cs | 23 --- .../Shaders/StageCallExtern.sdsl.cs | 9 - .../GameAssets/Shaders/StageDecl.sdsl.cs | 23 --- .../Shaders/StageValueReference.sdsl.cs | 9 - .../GameAssets/Shaders/StageValueTest.sdsl.cs | 23 --- .../Shaders/StaticCallMixin.sdsl.cs | 9 - .../GameAssets/Shaders/StaticMixin.sdsl.cs | 23 --- .../Shaders/StaticStageCallTest.sdsl.cs | 9 - .../GameAssets/Shaders/StreamChild.sdsl.cs | 9 - .../GameAssets/Shaders/StreamError.sdsl.cs | 9 - .../GameAssets/Shaders/StreamParent0.sdsl.cs | 9 - .../GameAssets/Shaders/StreamParent1.sdsl.cs | 9 - .../GameAssets/Shaders/StreamParent2.sdsl.cs | 9 - .../Shaders/StreamSolverExternTest.sdsl.cs | 9 - .../GameAssets/Shaders/StreamTest.sdsl.cs | 9 - .../Shaders/StructuredBufferTest.sdsl.cs | 24 --- .../Shaders/TessellationTest.sdsl.cs | 9 - .../Shaders/TestComputeShader.sdsl.cs | 26 --- .../GameAssets/Shaders/TestErrors.sdsl.cs | 23 --- .../Shaders/TestExternArray.sdsl.cs | 9 - .../Shaders/TestGenericComplex.sdsl.cs | 9 - .../Shaders/TestGenericMacro.sdsl.cs | 9 - .../GameAssets/Shaders/TestGenerics.sdsl.cs | 23 --- .../GameAssets/Shaders/TestMacros.sdsl.cs | 9 - .../Shaders/TestMacrosArray.sdsl.cs | 9 - .../Shaders/TestMultipleStatic.sdsl.cs | 9 - .../Shaders/TestPixelStream.sdsl.cs | 9 - .../Shaders/TestScreenPosition.sdsl.cs | 9 - .../GameAssets/Shaders/TestStreams.sdsl.cs | 9 - .../Shaders/TestStructInheritance.sdsl.cs | 23 --- .../GameAssets/Shaders/TestStructure.sdsl.cs | 9 - .../Shaders/TestVertexStream.sdsl.cs | 9 - .../Stride.Video/Shaders/VideoShader.sdsl.cs | 9 - .../VoxelVisualizationRawEffect.sdsl.cs | 47 ----- .../VoxelVisualizationRawShader.sdsl.cs | 25 --- .../VoxelVisualizationViewEffect.sdsl.cs | 62 ------ .../VoxelVisualizationViewShader.sdsl.cs | 25 --- .../StrideForwardShadingEffectVXGI.sdsl.cs | 118 ------------ .../Voxels/Light/LightVoxelEffect.sdsl.cs | 75 -------- .../Voxels/Light/LightVoxelShader.sdsl.cs | 25 --- .../Voxels/Marching/IVoxelSampler.sdsl.cs | 9 - .../MarchSets/Shaders/VoxelMarchSet.sdsl.cs | 9 - .../Shaders/VoxelMarchSetHemisphere12.sdsl.cs | 23 --- .../Shaders/VoxelMarchSetHemisphere6.sdsl.cs | 23 --- .../VoxelMarchSetRandomHemisphere.sdsl.cs | 24 --- .../Marching/Shaders/MarchAttributes.sdsl.cs | 9 - .../Shaders/MarchAttributesEffect.sdsl.cs | 51 ----- .../Marching/Shaders/VoxelMarchBeam.sdsl.cs | 9 - .../Marching/Shaders/VoxelMarchCone.sdsl.cs | 9 - .../Shaders/VoxelMarchConeEditMode.sdsl.cs | 27 --- .../Shaders/VoxelMarchConePerMipmap.sdsl.cs | 24 --- .../Marching/Shaders/VoxelMarchMethod.sdsl.cs | 9 - .../Shaders/VoxelRadiusMarchMethod.sdsl.cs | 9 - .../Attributes/Shaders/VoxelAttribute.sdsl.cs | 9 - ...ttributeDirectionalCoverageSampler.sdsl.cs | 9 - ...AttributeDirectionalCoverageShader.sdsl.cs | 23 --- ...oxelAttributeEmissionOpacityShader.sdsl.cs | 9 - .../VoxelAttributeSoliditySampler.sdsl.cs | 9 - .../VoxelAttributeSolidityShader.sdsl.cs | 23 --- .../Shaders/VoxelBufferWriteAssign.sdsl.cs | 9 - .../Shaders/VoxelBufferWriteMax.sdsl.cs | 9 - .../Shaders/VoxelBufferWriter.sdsl.cs | 9 - .../Shaders/DataPacking.sdsl.cs | 9 - .../Shaders/VoxelFragmentPackFloat16.sdsl.cs | 9 - .../Shaders/VoxelFragmentPackFloat32.sdsl.cs | 9 - .../VoxelFragmentPackFloatR11G11B10.sdsl.cs | 9 - .../Shaders/VoxelFragmentPacker.sdsl.cs | 9 - .../VoxelAnisotropicPairedSampler.sdsl.cs | 23 --- ...oxelAnisotropicPairedWriter_Float4.sdsl.cs | 24 --- .../Shaders/VoxelAnisotropicSampler.sdsl.cs | 23 --- .../VoxelAnisotropicWriter_Float4.sdsl.cs | 24 --- .../Shaders/VoxelIsotropicSampler.sdsl.cs | 23 --- .../VoxelIsotropicWriter_Float4.sdsl.cs | 24 --- .../Layout/Shaders/VoxelLayout_Float4.sdsl.cs | 9 - .../VoxelModifierApplierAnisotropic.sdsl.cs | 9 - ...fierApplierAntiAliasingAnisotropic.sdsl.cs | 9 - ...lModifierApplierOpacifyAnisotropic.sdsl.cs | 9 - ...ModifierApplierSolidifyAnisotropic.sdsl.cs | 9 - ...elModifierApplierAnisotropicPaired.sdsl.cs | 9 - ...plierAntiAliasingAnisotropicPaired.sdsl.cs | 9 - ...ierApplierOpacifyAnisotropicPaired.sdsl.cs | 9 - ...erApplierSolidifyAnisotropicPaired.sdsl.cs | 9 - ...difierApplierAntiAliasingIsotropic.sdsl.cs | 9 - .../VoxelModifierApplierIsotropic.sdsl.cs | 9 - ...xelModifierApplierOpacifyIsotropic.sdsl.cs | 23 --- ...elModifierApplierSolidifyIsotropic.sdsl.cs | 9 - .../Voxelization/VoxelPositionStream.sdsl.cs | 9 - .../VoxelStorage/LocalSamples.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoXN.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoXP.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoYN.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoYP.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoZN.sdsl.cs | 9 - .../Voxel2x2x2Mipmapper_AnisoZP.sdsl.cs | 9 - .../Mipmapping/Voxel2x2x2Mipmap.sdsl.cs | 26 --- .../Mipmapping/Voxel2x2x2MipmapEffect.sdsl.cs | 47 ----- .../Mipmapping/Voxel2x2x2Mipmapper.sdsl.cs | 9 - .../Voxel2x2x2MipmapperHeuristic.sdsl.cs | 9 - ...Voxel2x2x2MipmapperPhysicallyBased.sdsl.cs | 9 - .../Voxel2x2x2MipmapperSimple.sdsl.cs | 9 - .../Processing/BufferToTexture.sdsl.cs | 26 --- .../Processing/BufferToTextureColumns.sdsl.cs | 9 - .../BufferToTextureColumnsEffect.sdsl.cs | 68 ------- .../Processing/BufferToTextureEffect.sdsl.cs | 68 ------- .../Processing/ClearBuffer.sdsl.cs | 24 --- .../Shaders/VoxelStorageClipmapShader.sdsl.cs | 30 --- .../Shaders/VoxelStorageShader.sdsl.cs | 9 - .../VoxelStorageTextureClipmapShader.sdsl.cs | 27 --- .../Shaders/VoxelStorageTextureShader.sdsl.cs | 9 - .../Shader/VoxelizationMethod.sdsl.cs | 9 - .../VoxelizationMethodDominantAxis.sdsl.cs | 9 - .../VoxelizationMethodSingleAxis.sdsl.cs | 9 - .../Voxelization/VoxelizeToFragments.sdsl.cs | 9 - .../VoxelizeToFragmentsEffect.sdsl.cs | 54 ------ sources/targets/Stride.UnitTests.targets | 2 - sources/targets/Stride.targets | 2 - 649 files changed, 11783 deletions(-) delete mode 100644 samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs delete mode 100644 samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs delete mode 100644 samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs delete mode 100644 samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs delete mode 100644 samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs delete mode 100644 samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWave.sdsl.cs delete mode 100644 samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWaveNormal.sdsl.cs delete mode 100644 samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRadial.sdsl.cs delete mode 100644 samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRed.sdsl.cs delete mode 100644 samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorTextureScroll.sdsl.cs delete mode 100644 samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs delete mode 100644 samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomShader.sdsl.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/PreviewTexture.sdfx.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/SceneEditorParameters.sdfx.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/SelectedSprite.sdfx.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorForwardShadingEffect.sdfx.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorHighlightingEffect.sdfx.cs delete mode 100644 sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorMaterialPreviewEffect.sdfx.cs delete mode 100644 sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/SinglePassWireframeShader.sdsl.cs delete mode 100644 sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.10_0/Assets/LightTiling.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffectShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTest.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTestEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.11_0/Assets/CubemapSprite.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests.11_0/Assets/HammersleyTest.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/SimpleEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/SimpleShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/ToGlslEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/ToGlslShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/ColorUtility.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/ShaderBase.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/ShaderBaseStream.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFont.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFontShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteAlphaCutoff.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteBase.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteBatch.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteBatchShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTexture.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTextureRegular.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteSignedDistanceFieldFontShader.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/SpriteSuperSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/Texturing.sdsl.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/UIEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Graphics/Shaders/UIEffectShader.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ComputeColorWhite.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleBase.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleBaseEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleColor.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleColorStream.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleComputeColorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Particles/Shaders/ParticleUtilities.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/BRDF/BRDFMicrofacet.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Background/BackgroundCubemapShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Background/BackgroundShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Compositing/MSAADepthResolverShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeEffectShader.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeShaderBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/Hammersley.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/ImportanceSamplingGGX.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputeEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass1.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass2.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass1.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass2.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocity.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocityEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/ColorBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/DynamicSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/DynamicTexture.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureCube.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/MeshVelocity.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromMesh.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromMeshInstanced.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMapping.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingInstanced.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellation.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellationInstanced.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/NormalUpdate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/PositionHStream4.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/PositionStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/PositionStream4.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/PositionVertexTransform.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/ScreenPositionBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/ShadingBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/ShadingColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/VelocityOutput.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Core/VelocityStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Deferred/GBuffer.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/CompilationErrorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/EffectCompiling.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/LightConstantWhite.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/SelectedSpriteShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/SharedTextureCoordinate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/Sprite3DBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Editor/SpritePicking.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShaderEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/TemporalAntiAliasShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageCombineShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/BrightFilter/BrightFilterShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Noise/FilmGrainShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapACESOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapCommonOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapDragoOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapExponentialOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejl2OperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejlDawsonOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapLogarithmicOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapMikeDayOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapReinhardOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapU2FilmicOperatorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Vignetting/VignettingShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshCombineShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/TripleRhombiCombineShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CircleOfConfusion.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCLinearDepthShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurUtil.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/PointDepth.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoC.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoCFront.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/Dither/Dither.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ImageEffectShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareReplicate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/PostEffectBoundingRay.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightShafts/VolumeMinMaxShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRBlurPass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCombinePass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCommon.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRDepthPass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRRayTracePass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRResolvePass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRTemporalPass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceLogShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceUtils.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsParameters.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRenderer.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRendererEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsUtils.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/LightProbes/BakeLightProbeShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/LightProbes/ComputeSphericalHarmonics.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/LightProbes/LightProbeShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupArray.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupFixed.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerDraw.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerView.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLight.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLightArray.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightClustered.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredSpotGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightDirectionalGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightPointGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSimpleAmbient.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationDefault.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationRectangular.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightSpotGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/LightUtil.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/SpotLightDataInternalShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionCommon.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionFilterDefault.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverSpot.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightRamp.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorAdd3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDarken3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDifference3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorLighten3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMask3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMultiply3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOver3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOverlay3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorSubtract3ds.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor3.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd3.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAverage.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorCave.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorBurn.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorDodge.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColor3Link.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColorLink.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantFloatLink.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantLink.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDesaturate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDivide.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorExclusion.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFixed.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFromStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardLight.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardMix.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHue.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIlluminate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIn.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLerpAlpha.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearBurn.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearDodge.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMask.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMultiply.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOne.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOut.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOutdoor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOverlay.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorParameter.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorPinLight.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturate.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturation.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScaler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScreen.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSoftLight.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlpha.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlphaWithColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubtract.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTexture.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureDynamicScaledOffset.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureRepeat.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaled.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffset.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorThreshold.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorValue.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorAddMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDarkenMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDifferenceMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorLightenMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorMultiplyMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorOverMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorSubtractMaya.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/IMaterialHairDirectionFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionBitangent.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionTangent.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/IMaterialHairDiscardFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionOpaquePass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionTransparentPass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/IMaterialHairLightAttenuationFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionDirectional.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionNone.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialHairShared.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingDiffuseHair.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingSpecularHair.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/IMaterialHairShadowingFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionScattering.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionShadowing.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/IMaterialSurfaceDomain.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/IStreamInitializer.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialDisplacementStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialDomainStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialStreamAdditiveBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDisplacement.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDomainStageCompositor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/MaterialTessellationStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/ComputeColorMaterialAlphaBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputNormals.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSpecularColorRoughness.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetFresnelFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetVisibilityFunction.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialStreamBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurface.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfacePixel.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceVertex.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialFrontBackBlendShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelShadingStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelNone.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelSchlick.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelThinGlass.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityImplicit.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityKelemen.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityNeumann.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamLinearBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamNormalBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceArray.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuse.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseMetalFlakes.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceEmissiveShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMap.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMapMetalFlakes.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceLightingAndShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceMetalness.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalMap.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalStreamShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfacePixelStageCompositor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceSetStreamFromComputeColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingDiffuseLambert.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularMicrofacet.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamsBlend.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransmittanceShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransparentAlphaDiscard.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexStageCompositor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialTransmittanceReflectanceStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialVertexStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/MaterialSurfaceSubsurfaceScatteringShading.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/IMaterialSubsurfaceScatteringScatteringProfile.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/ProceduralModels/CameraCube.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shaders/Camera.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shaders/Global.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shaders/GlobalVR.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shaders/Transformation.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCaster.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMap.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMapProjection.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterNoPixelShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloid.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloidProjection.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCommon.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterDefault.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterPcf.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterVsm.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapGroup.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverDirectional.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointCubeMap.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointParaboloid.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverSpot.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Shadows/ShadowStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/NormalMeshSkinning.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningFromMesh.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMapping.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMappingTessellation.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/TangentMeshSkinning.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinning.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinningInstanced.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/CubemapUtils.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/IComputeEnvironmentColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/LevelCubeMapEnvironmentColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/RoughnessCubeMapEnvironmentColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderCubemap.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderTexture.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxStream.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Skyboxes/SphericalHarmonicsEnvironmentColor.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/StrideEffectBase.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/StrideWireframeShadingEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE2.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE3.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE4.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationFlat.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationPN.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationInstancing.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVP.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVPInstanced.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWVP.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/BlendUtils.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/DepthBase.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/FlattenLayers.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/HSVUtils.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/HighlightShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/NormalPack.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/NormalUtil.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/Picking.sdfx.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/PickingShader.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/SwapUV.sdsl.cs delete mode 100644 sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl.cs delete mode 100644 sources/engine/Stride.Video/Shaders/VideoShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/StrideForwardShadingEffectVXGI.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Light/LightVoxelEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Light/LightVoxelShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/IVoxelSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSet.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere12.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere6.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetRandomHemisphere.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributes.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributesEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchBeam.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchCone.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConeEditMode.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConePerMipmap.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchMethod.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelRadiusMarchMethod.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeEmissionOpacityShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSoliditySampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSolidityShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteAssign.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteMax.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriter.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/DataPacking.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat16.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat32.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloatR11G11B10.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPacker.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedWriter_Float4.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicWriter_Float4.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicSampler.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicWriter_Float4.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelLayout_Float4.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAnisotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAntiAliasingAnisotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierOpacifyAnisotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierSolidifyAnisotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAnisotropicPaired.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierAntiAliasingIsotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierIsotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierOpacifyIsotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierSolidifyIsotropic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelPositionStream.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/LocalSamples.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXN.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXP.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYN.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYP.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZN.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZP.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmap.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmapper.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperHeuristic.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperPhysicallyBased.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperSimple.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTexture.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumns.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumnsEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureEffect.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/ClearBuffer.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageClipmapShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureClipmapShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethod.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodDominantAxis.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodSingleAxis.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragments.sdsl.cs delete mode 100644 sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragmentsEffect.sdsl.cs diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs deleted file mode 100644 index dacdbdaad0..0000000000 --- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/CustomFogEffect.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class CustomFogEffectKeys - { - public static readonly ValueParameterKey FogColor = ParameterKeys.NewValue(new Color4(1,1,1,1)); - public static readonly ValueParameterKey fogNearPlaneZ = ParameterKeys.NewValue(80.0f); - public static readonly ValueParameterKey fogFarPlaneZ = ParameterKeys.NewValue(250.0f); - public static readonly ValueParameterKey fogNearPlaneY = ParameterKeys.NewValue(0.0f); - public static readonly ValueParameterKey fogFarPlaneY = ParameterKeys.NewValue(120.0f); - } -} diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs deleted file mode 100644 index e27e736cc5..0000000000 --- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/SpaceEscapeEffectMain.sdfx.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace SpaceEscape.Effects -{ - [DataContract]public partial class GameParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey EnableFog = ParameterKeys.NewPermutation(true); - public static readonly PermutationParameterKey EnableBend = ParameterKeys.NewPermutation(true); - public static readonly PermutationParameterKey EnableOnflyTextureUVChange = ParameterKeys.NewPermutation(false); - }; - internal static partial class ShaderMixins - { - internal partial class SpaceEscapeEffectMain : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideForwardShadingEffect"); - if (context.GetParam(GameParameters.EnableOnflyTextureUVChange)) - context.Mixin(mixin, "TransformationTextureUV"); - if (context.GetParam(GameParameters.EnableBend)) - context.Mixin(mixin, "TransformationBendWorld"); - if (context.GetParam(GameParameters.EnableFog)) - context.Mixin(mixin, "CustomFogEffect"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SpaceEscapeEffectMain", new SpaceEscapeEffectMain()); - } - } - } -} diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs deleted file mode 100644 index a101da0495..0000000000 --- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationBendWorld.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TransformationBendWorldKeys - { - public static readonly ValueParameterKey DeformFactorX = ParameterKeys.NewValue(-0.001f); - public static readonly ValueParameterKey DeformFactorY = ParameterKeys.NewValue(-0.0006f); - } -} diff --git a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs b/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs deleted file mode 100644 index 8a174442f7..0000000000 --- a/samples/Games/SpaceEscape/SpaceEscape.Game/Effects/TransformationTextureUV.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TransformationTextureUVKeys - { - public static readonly ValueParameterKey TextureRegion = ParameterKeys.NewValue(new Vector4(0,0,1,1)); - } -} diff --git a/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs b/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs deleted file mode 100644 index 356722c0d5..0000000000 --- a/samples/Graphics/CustomEffect/CustomEffect.Game/Effects/Effect.sdsl.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class EffectKeys - { - public static readonly ValueParameterKey Center = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Frequency = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Phase = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Spread = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Amplitude = ParameterKeys.NewValue(); - public static readonly ValueParameterKey InvAspectRatio = ParameterKeys.NewValue(); - } -} diff --git a/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWave.sdsl.cs b/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWave.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWave.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWaveNormal.sdsl.cs b/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWaveNormal.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Graphics/MaterialShader/MaterialShader.Game/Effects/ComputeColorWaveNormal.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRadial.sdsl.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRadial.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRadial.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRed.sdsl.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRed.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorRed.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorTextureScroll.sdsl.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorTextureScroll.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ComputeColorTextureScroll.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs deleted file mode 100644 index 1c23837570..0000000000 --- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomEffect.sdfx.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class ParticleCustomEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ParticleBaseEffect"); - context.Mixin(mixin, "ParticleCustomShader"); - if (context.GetParam(ParticleCustomShaderKeys.BaseColor) != null) - { - - { - var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseColor); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "baseColor", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(ParticleCustomShaderKeys.BaseIntensity) != null) - { - - { - var __mixinToCompose__ = context.GetParam(ParticleCustomShaderKeys.BaseIntensity); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "baseIntensity", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ParticleCustomEffect", new ParticleCustomEffect()); - } - } - } -} diff --git a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomShader.sdsl.cs b/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/samples/Particles/ParticlesSample/ParticlesSample.Game/Effects/ParticleCustomShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/PreviewTexture.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/PreviewTexture.sdfx.cs deleted file mode 100644 index 2cda3407e1..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/PreviewTexture.sdfx.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace StrideEffects -{ - [DataContract]public partial class PreviewTextureParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey Is3D = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class PreviewTexture : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(PreviewTextureParameters.Is3D)) - { - context.Mixin(mixin, "Sprite3DBase"); - } - context.Mixin(mixin, "SpriteBatch"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("PreviewTexture", new PreviewTexture()); - } - } - } -} diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/SceneEditorParameters.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/SceneEditorParameters.sdfx.cs deleted file mode 100644 index 4c3fd42923..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/SceneEditorParameters.sdfx.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace StrideEffects -{ - [DataContract]public partial class SceneEditorParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey IsEffectCompiling = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey IsEffectError = ParameterKeys.NewPermutation(); - }; -} diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/SelectedSprite.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/SelectedSprite.sdfx.cs deleted file mode 100644 index 2488a0401d..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/SelectedSprite.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace StrideEffects -{ - internal static partial class ShaderMixins - { - internal partial class SelectedSprite : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SpriteBatchShader", context.GetParam(SpriteBaseKeys.ColorIsSRgb)); - context.Mixin(mixin, "SelectedSpriteShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SelectedSprite", new SelectedSprite()); - } - } - } -} diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorForwardShadingEffect.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorForwardShadingEffect.sdfx.cs deleted file mode 100644 index 68b28e3927..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorForwardShadingEffect.sdfx.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace StrideEffects -{ - internal static partial class ShaderMixins - { - internal partial class StrideEditorForwardShadingEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(SceneEditorParameters.IsEffectError)) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "ShadingBase"); - context.Mixin(mixin, "TransformationBase"); - context.Mixin(mixin, "TransformationWAndVP"); - context.Mixin(mixin, "CompilationErrorShader"); - context.Discard(); - ; - } - context.Mixin(mixin, "StrideForwardShadingEffect"); - if (context.ChildEffectName == "Picking") - { - context.Mixin(mixin, "Picking"); - return; - } - if (context.ChildEffectName == "Wireframe") - { - context.Mixin(mixin, "Wireframe"); - return; - } - if (context.ChildEffectName == "Highlight") - { - context.Mixin(mixin, "Highlight"); - return; - } - if (context.GetParam(SceneEditorParameters.IsEffectCompiling)) - { - context.Mixin(mixin, "EffectCompiling"); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideEditorForwardShadingEffect", new StrideEditorForwardShadingEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class Wireframe : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "MaterialFrontBackBlendShader", context.GetParam(MaterialFrontBackBlendShaderKeys.UseNormalBackFace)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("Wireframe", new Wireframe()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class Highlight : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "HighlightShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("Highlight", new Highlight()); - } - } - } -} diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorHighlightingEffect.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorHighlightingEffect.sdfx.cs deleted file mode 100644 index a30b8d8731..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorHighlightingEffect.sdfx.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace StrideEffects -{ - internal static partial class ShaderMixins - { - internal partial class StrideEditorHighlightingEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideForwardShadingEffect"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideEditorHighlightingEffect", new StrideEditorHighlightingEffect()); - } - } - } -} diff --git a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorMaterialPreviewEffect.sdfx.cs b/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorMaterialPreviewEffect.sdfx.cs deleted file mode 100644 index 95cbfdec77..0000000000 --- a/sources/editor/Stride.Assets.Presentation/Shaders/StrideEditorMaterialPreviewEffect.sdfx.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace StrideEffects -{ - internal static partial class ShaderMixins - { - internal partial class StrideEditorMaterialPreviewEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideEditorForwardShadingEffect"); - context.Mixin(mixin, "SharedTextureCoordinate"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideEditorMaterialPreviewEffect", new StrideEditorMaterialPreviewEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs b/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs index 013fcacaba..51d915e0ab 100644 --- a/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs +++ b/sources/engine/Stride.Assets/Effect/EffectCompositorAsset.cs @@ -2,8 +2,6 @@ // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using Stride.Core.Assets; using Stride.Core; -using Stride.Shaders.Parser.Mixins; -using System.IO; namespace Stride.Assets.Effect { diff --git a/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs b/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs index cc50e22b29..84c9e746a4 100644 --- a/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs +++ b/sources/engine/Stride.Assets/Effect/EffectShaderAsset.cs @@ -7,8 +7,6 @@ using System.Text.RegularExpressions; using Stride.Core.Assets; using Stride.Core; -using Stride.Shaders.Parser; -using Stride.Shaders.Parser.Mixins; namespace Stride.Assets.Effect { diff --git a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/SinglePassWireframeShader.sdsl.cs b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/SinglePassWireframeShader.sdsl.cs deleted file mode 100644 index 64ca0d7cc5..0000000000 --- a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/SinglePassWireframeShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SinglePassWireframeShaderKeys - { - public static readonly ValueParameterKey LineWidth = ParameterKeys.NewValue(); - public static readonly ValueParameterKey LineColor = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Viewport = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx.cs b/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx.cs deleted file mode 100644 index 2ae8f5543c..0000000000 --- a/sources/engine/Stride.BepuPhysics/Stride.BepuPhysics.Debug/Effects/StrideSinglePassWireframeShader.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Materials; -namespace Stride.BepuPhysics.Debug -{ - internal static partial class ShaderMixins - { - internal partial class StrideSinglePassWireframeShader : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SinglePassWireframeShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - { - ShaderMixinManager.Register("StrideSinglePassWireframeShader", new StrideSinglePassWireframeShader()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests.10_0/Assets/LightTiling.sdsl.cs b/sources/engine/Stride.Graphics.Tests.10_0/Assets/LightTiling.sdsl.cs deleted file mode 100644 index 9f2c152425..0000000000 --- a/sources/engine/Stride.Graphics.Tests.10_0/Assets/LightTiling.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightTilingKeys - { - public static readonly ValueParameterKey PointLightCount = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey PointLights = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey FilteredLightIndicesBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffect.sdfx.cs deleted file mode 100644 index 69ff9c1124..0000000000 --- a/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffect.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Graphics.Tests -{ - internal static partial class ShaderMixins - { - internal partial class MultipleRenderTargetsEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideForwardShadingEffect"); - context.Mixin(mixin, "MultipleRenderTargetsEffectShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("MultipleRenderTargetsEffect", new MultipleRenderTargetsEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffectShader.sdsl.cs b/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffectShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics.Tests.10_0/Assets/MultipleRenderTargetsEffectShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTest.sdsl.cs b/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTest.sdsl.cs deleted file mode 100644 index 72b38ebc03..0000000000 --- a/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTest.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Graphics.Tests -{ - internal static partial class ComputeShaderTestKeys - { - public static readonly ObjectParameterKey input = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey output = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTestEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTestEffect.sdfx.cs deleted file mode 100644 index df0f944508..0000000000 --- a/sources/engine/Stride.Graphics.Tests.11_0/Assets/ComputeShaderTestEffect.sdfx.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Graphics.Tests -{ - [DataContract]public partial class ComputeShaderTestParams : ShaderMixinParameters - { - public static readonly PermutationParameterKey NbOfIterations = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class ComputeShaderTestEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ComputeShaderTest", context.GetParam(ComputeShaderTestParams.NbOfIterations)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ComputeShaderTestEffect", new ComputeShaderTestEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests.11_0/Assets/CubemapSprite.sdsl.cs b/sources/engine/Stride.Graphics.Tests.11_0/Assets/CubemapSprite.sdsl.cs deleted file mode 100644 index caa8cf63e1..0000000000 --- a/sources/engine/Stride.Graphics.Tests.11_0/Assets/CubemapSprite.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class CubemapSpriteKeys - { - public static readonly ValueParameterKey ViewIndex = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests.11_0/Assets/HammersleyTest.sdsl.cs b/sources/engine/Stride.Graphics.Tests.11_0/Assets/HammersleyTest.sdsl.cs deleted file mode 100644 index 2f1dec39b8..0000000000 --- a/sources/engine/Stride.Graphics.Tests.11_0/Assets/HammersleyTest.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class HammersleyTestKeys - { - public static readonly ValueParameterKey SamplesCount = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey OutputTexture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx.cs deleted file mode 100644 index c38f56ccd7..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx.cs +++ /dev/null @@ -1,135 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class CubemapDisplayEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "TransformationWAndVP"); - context.Mixin(mixin, "AlbedoFlatShading"); - - { - var __mixinToCompose__ = "ComputeColorTextureCubeBasic"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "albedoDiffuse", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__, TexturingKeys.TextureCube0); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CubemapDisplayEffect", new CubemapDisplayEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class CubemapEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "TransformationWAndVP"); - context.Mixin(mixin, "AlbedoFlatShading"); - if (context.GetParam(MaterialParameters.AlbedoDiffuse) != null) - - { - var __mixinToCompose__ = context.GetParam(MaterialParameters.AlbedoDiffuse); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "albedoDiffuse", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - else - - { - var __mixinToCompose__ = "ComputeColorTextureCubeReflect"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "albedoDiffuse", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__, TexturingKeys.TextureCube0); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CubemapEffect", new CubemapEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class CubemapGeomEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "TransformationWAndVP"); - mixin.AddMacro("MAX_VERTEX_COUNT", 9); - context.Mixin(mixin, "CameraCube"); - context.Mixin(mixin, "AlbedoFlatShading"); - if (context.GetParam(MaterialParameters.AlbedoDiffuse) != null) - - { - var __mixinToCompose__ = context.GetParam(MaterialParameters.AlbedoDiffuse); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "albedoDiffuse", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CubemapGeomEffect", new CubemapGeomEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class CubemapIBLEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideBaseShader"); - if (context.ChildEffectName == "StrideGBufferShaderPass") - { - context.Mixin(mixin, "StrideGBufferShaderPass"); - return; - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CubemapIBLEffect", new CubemapIBLEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx.cs deleted file mode 100644 index c6e5b68ae0..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Graphics.Tests -{ - internal static partial class ShaderMixins - { - internal partial class CustomSubEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(CustomShaderKeys.SwitchEffectLevel) < 10) - { - context.Mixin(mixin, "CustomShader"); - } - else - { - context.Mixin(mixin, "CustomShader2"); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CustomSubEffect", new CustomSubEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class CustomEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "CustomShader"); - if (context.ChildEffectName == "CustomSubEffect") - { - context.Mixin(mixin, "CustomSubEffect"); - return; - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CustomEffect", new CustomEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl.cs b/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl.cs deleted file mode 100644 index 86e287ec18..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Graphics.Tests -{ - public static partial class CustomShaderKeys - { - public static readonly PermutationParameterKey SwitchEffectLevel = ParameterKeys.NewPermutation(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteEffect.sdfx.cs deleted file mode 100644 index a3b35477bf..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class MultiTexturesSpriteEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "MultiTexturesSpriteShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("MultiTexturesSpriteEffect", new MultiTexturesSpriteEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteShader.sdsl.cs b/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/MultiTexturesSpriteShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/SimpleEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests/Compiler/SimpleEffect.sdfx.cs deleted file mode 100644 index b3a0fa0993..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/SimpleEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class SimpleEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SimpleShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SimpleEffect", new SimpleEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/SimpleShader.sdsl.cs b/sources/engine/Stride.Graphics.Tests/Compiler/SimpleShader.sdsl.cs deleted file mode 100644 index f0451ce9f2..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/SimpleShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SimpleShaderKeys - { - public static readonly ValueParameterKey TestColor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslEffect.sdfx.cs b/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslEffect.sdfx.cs deleted file mode 100644 index da958e69a5..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class ToGlslEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ToGlslShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ToGlslEffect", new ToGlslEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslShader.sdsl.cs b/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslShader.sdsl.cs deleted file mode 100644 index e3d29bc8a7..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/ToGlslShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ToGlslShaderKeys - { - public static readonly ValueParameterKey BaseColor = ParameterKeys.NewValue(new Vector4(2,1,5,9)); - public static readonly ValueParameterKey myMatrix = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TestArray = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/ColorUtility.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/ColorUtility.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/ColorUtility.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/ShaderBase.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/ShaderBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/ShaderBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/ShaderBaseStream.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/ShaderBaseStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/ShaderBaseStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFont.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFont.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFont.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFontShader.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFontShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SignedDistanceFieldFontShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteAlphaCutoff.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteAlphaCutoff.sdsl.cs deleted file mode 100644 index 473649cb37..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteAlphaCutoff.sdsl.cs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteAlphaCutoffKeys - { - } -} -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class SpriteAlphaCutoffEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SpriteAlphaCutoff", context.GetParam(SpriteBaseKeys.ColorIsSRgb)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SpriteAlphaCutoffEffect", new SpriteAlphaCutoffEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteBase.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteBase.sdsl.cs deleted file mode 100644 index 81438c3285..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteBase.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteBaseKeys - { - public static readonly ValueParameterKey MatrixTransform = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteBatch.sdfx.cs b/sources/engine/Stride.Graphics/Shaders/SpriteBatch.sdfx.cs deleted file mode 100644 index d271a042ba..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteBatch.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class SpriteBatch : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SpriteBatchShader", context.GetParam(SpriteBaseKeys.ColorIsSRgb)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SpriteBatch", new SpriteBatch()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteBatchShader.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteBatchShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteBatchShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteEffect.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteEffect.sdsl.cs deleted file mode 100644 index 0459ebebdf..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteEffect.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteEffectKeys - { - public static readonly ValueParameterKey Color = ParameterKeys.NewValue(new Color4(1,1,1,1)); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTexture.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTexture.sdsl.cs deleted file mode 100644 index 2ebfa87259..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTexture.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteEffectExtTextureKeys - { - public static readonly ObjectParameterKey StrideInternal_TextureExt0 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey MipLevel = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Gamma = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Sampler = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTextureRegular.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTextureRegular.sdsl.cs deleted file mode 100644 index cc3d064ad8..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteEffectExtTextureRegular.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteEffectExtTextureRegularKeys - { - public static readonly ObjectParameterKey TextureRegular = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler = ParameterKeys.NewObject(); - public static readonly ValueParameterKey MipLevel = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteSignedDistanceFieldFontShader.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteSignedDistanceFieldFontShader.sdsl.cs deleted file mode 100644 index 7b3564993c..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteSignedDistanceFieldFontShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SpriteSignedDistanceFieldFontShaderKeys - { - public static readonly ValueParameterKey Color = ParameterKeys.NewValue(new Color4(1,1,1,1)); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/SpriteSuperSampler.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/SpriteSuperSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/SpriteSuperSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Graphics/Shaders/Texturing.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/Texturing.sdsl.cs deleted file mode 100644 index 780a549f61..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/Texturing.sdsl.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TexturingKeys - { - public static readonly ObjectParameterKey Texture0 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture0TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture1 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture1TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture2 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture2TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture3 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture3TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture4 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture4TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture5 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture5TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture6 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture6TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture7 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture7TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture8 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture8TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey Texture9 = ParameterKeys.NewObject(); - public static readonly ValueParameterKey Texture9TexelSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey TextureCube0 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey TextureCube1 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey TextureCube2 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey TextureCube3 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Texture3D0 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Texture3D1 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Texture3D2 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Texture3D3 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey PointSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearBorderSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearClampCompareLessEqualSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey AnisotropicSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey AnisotropicRepeatSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey PointRepeatSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearRepeatSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey RepeatSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler0 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler1 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler2 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler3 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler4 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler5 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler6 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler7 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler8 = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey Sampler9 = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/UIEffect.sdfx.cs b/sources/engine/Stride.Graphics/Shaders/UIEffect.sdfx.cs deleted file mode 100644 index 4ddf3b6d91..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/UIEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class UIEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "UIEffectShader", context.GetParam(SpriteBaseKeys.ColorIsSRgb)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("UIEffect", new UIEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Graphics/Shaders/UIEffectShader.sdsl.cs b/sources/engine/Stride.Graphics/Shaders/UIEffectShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Graphics/Shaders/UIEffectShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Particles/Shaders/ComputeColorWhite.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ComputeColorWhite.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ComputeColorWhite.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Particles/Shaders/ParticleBase.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ParticleBase.sdsl.cs deleted file mode 100644 index ce87865506..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleBase.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ParticleBaseKeys - { - public static readonly ValueParameterKey ColorScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey AlphaAdditive = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ZOffset = ParameterKeys.NewValue(); - public static readonly ValueParameterKey SoftEdgeInverseDistance = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Particles/Shaders/ParticleBaseEffect.sdfx.cs b/sources/engine/Stride.Particles/Shaders/ParticleBaseEffect.sdfx.cs deleted file mode 100644 index 58c1e9afed..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleBaseEffect.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class ParticleBaseEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("UsesSoftEdge", context.GetParam(ParticleBaseKeys.UsesSoftEdge)); - context.Mixin(mixin, "ParticleBase"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ParticleBaseEffect", new ParticleBaseEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Particles/Shaders/ParticleColor.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ParticleColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Particles/Shaders/ParticleColorStream.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ParticleColorStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleColorStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Particles/Shaders/ParticleComputeColorShader.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ParticleComputeColorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleComputeColorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Particles/Shaders/ParticleEffect.sdfx.cs b/sources/engine/Stride.Particles/Shaders/ParticleEffect.sdfx.cs deleted file mode 100644 index 6fa91016c3..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleEffect.sdfx.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class ParticleEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ParticleBaseEffect"); - context.Mixin(mixin, "ParticleComputeColorShader"); - if (context.GetParam(ParticleBaseKeys.BaseColor) != null) - { - - { - var __mixinToCompose__ = context.GetParam(ParticleBaseKeys.BaseColor); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "baseColor", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ParticleEffect", new ParticleEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Particles/Shaders/ParticleUtilities.sdsl.cs b/sources/engine/Stride.Particles/Shaders/ParticleUtilities.sdsl.cs deleted file mode 100644 index d0a47b41bf..0000000000 --- a/sources/engine/Stride.Particles/Shaders/ParticleUtilities.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ParticleUtilitiesKeys - { - public static readonly ValueParameterKey ViewMatrix = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjectionMatrix = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewProjectionMatrix = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewFrustum = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Viewport = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/BRDF/BRDFMicrofacet.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/BRDF/BRDFMicrofacet.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/BRDF/BRDFMicrofacet.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Background/BackgroundCubemapShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Background/BackgroundCubemapShader.sdsl.cs deleted file mode 100644 index 0b2112303c..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Background/BackgroundCubemapShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class BackgroundCubemapShaderKeys - { - public static readonly ObjectParameterKey Cubemap = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Background/BackgroundShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Background/BackgroundShader.sdsl.cs deleted file mode 100644 index 2529425931..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Background/BackgroundShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class BackgroundShaderKeys - { - public static readonly ValueParameterKey Intensity = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAADepthResolverShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Compositing/MSAADepthResolverShader.sdsl.cs deleted file mode 100644 index f2c984a9c8..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAADepthResolverShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Compositing -{ - internal static partial class MSAADepthResolverShaderKeys - { - public static readonly ValueParameterKey SvPosUnpack = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TextureSizeLess1 = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey InputTexture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverEffect.sdfx.cs deleted file mode 100644 index 2a860e2684..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverEffect.sdfx.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Compositing -{ - [DataContract]public partial class MSAAResolverParams : ShaderMixinParameters - { - public static readonly PermutationParameterKey MSAASamples = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey ResolveFilterType = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey ResolveFilterDiameter = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class MSAAResolverEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("INPUT_MSAA_SAMPLES", context.GetParam(MSAAResolverParams.MSAASamples)); - context.Mixin(mixin, "MSAAResolverShader", context.GetParam(MSAAResolverParams.MSAASamples), context.GetParam(MSAAResolverParams.ResolveFilterType), context.GetParam(MSAAResolverParams.ResolveFilterDiameter)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("MSAAResolverEffect", new MSAAResolverEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class MSAADepthResolverEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("INPUT_MSAA_SAMPLES", context.GetParam(MSAAResolverParams.MSAASamples)); - context.Mixin(mixin, "MSAADepthResolverShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("MSAADepthResolverEffect", new MSAADepthResolverEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverShader.sdsl.cs deleted file mode 100644 index 096ea6af50..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Compositing/MSAAResolverShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Compositing -{ - internal static partial class MSAAResolverShaderKeys - { - public static readonly ValueParameterKey SvPosUnpack = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TextureSizeLess1 = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey InputTexture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeEffectShader.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeEffectShader.sdfx.cs deleted file mode 100644 index b773055437..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeEffectShader.sdfx.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.ComputeEffect -{ - internal static partial class ShaderMixins - { - internal partial class ComputeEffectShader : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("ThreadNumberX", context.GetParam(ComputeEffectShaderKeys.ThreadNumbers).X); - mixin.AddMacro("ThreadNumberY", context.GetParam(ComputeEffectShaderKeys.ThreadNumbers).Y); - mixin.AddMacro("ThreadNumberZ", context.GetParam(ComputeEffectShaderKeys.ThreadNumbers).Z); - context.Mixin(mixin, "ComputeShaderBase"); - context.Mixin(mixin, context.GetParam(ComputeEffectShaderKeys.ComputeShaderName)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ComputeEffectShader", new ComputeEffectShader()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeShaderBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeShaderBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/ComputeShaderBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/Hammersley.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/Hammersley.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/Hammersley.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/ImportanceSamplingGGX.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/ImportanceSamplingGGX.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/ImportanceSamplingGGX.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXEffect.sdfx.cs deleted file mode 100644 index 154d9c8c84..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXEffect.sdfx.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - [DataContract]public partial class RadiancePrefilteringGGXParams : ShaderMixinParameters - { - public static readonly PermutationParameterKey NbOfSamplings = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class RadiancePrefilteringGGXEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "RadiancePrefilteringGGXShader", context.GetParam(RadiancePrefilteringGGXParams.NbOfSamplings)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("RadiancePrefilteringGGXEffect", new RadiancePrefilteringGGXEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeEffect.sdfx.cs deleted file mode 100644 index 1b2f49c1e9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeEffect.sdfx.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - [DataContract]public partial class RadiancePrefilteringGGXNoComputeParams : ShaderMixinParameters - { - public static readonly PermutationParameterKey NbOfSamplings = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class RadiancePrefilteringGGXNoComputeEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "RadiancePrefilteringGGXNoComputeShader", context.GetParam(RadiancePrefilteringGGXNoComputeParams.NbOfSamplings)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("RadiancePrefilteringGGXNoComputeEffect", new RadiancePrefilteringGGXNoComputeEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeShader.sdsl.cs deleted file mode 100644 index 65b75ee519..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXNoComputeShader.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class RadiancePrefilteringGGXNoComputeShaderKeys - { - public static readonly ValueParameterKey RadianceMapSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey RadianceMap = ParameterKeys.NewObject(); - public static readonly ValueParameterKey MipmapCount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Roughness = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Face = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXShader.sdsl.cs deleted file mode 100644 index 61ba28218c..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGXShader.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class RadiancePrefilteringGGXShaderKeys - { - public static readonly ValueParameterKey RadianceMapSize = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey RadianceMap = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey FilteredRadiance = ParameterKeys.NewObject(); - public static readonly ValueParameterKey MipmapCount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Roughness = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.sdfx.cs deleted file mode 100644 index c9cdd38563..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSH.sdfx.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - [DataContract]public partial class LambertianPrefilteringSHParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey BlockSize = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class LambertianPrefilteringSHEffectPass1 : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LambertianPrefilteringSHPass1", context.GetParam(LambertianPrefilteringSHParameters.BlockSize), context.GetParam(SphericalHarmonicsParameters.HarmonicsOrder)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LambertianPrefilteringSHEffectPass1", new LambertianPrefilteringSHEffectPass1()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class LambertianPrefilteringSHEffectPass2 : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LambertianPrefilteringSHPass2", context.GetParam(LambertianPrefilteringSHParameters.BlockSize), context.GetParam(SphericalHarmonicsParameters.HarmonicsOrder)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LambertianPrefilteringSHEffectPass2", new LambertianPrefilteringSHEffectPass2()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputeEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputeEffect.sdfx.cs deleted file mode 100644 index d9e517b90e..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputeEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class LambertianPrefilteringSHNoComputeEffectPass1 : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LambertianPrefilteringSHNoComputePass1", context.GetParam(SphericalHarmonicsParameters.HarmonicsOrder)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LambertianPrefilteringSHNoComputeEffectPass1", new LambertianPrefilteringSHNoComputeEffectPass1()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass1.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass1.sdsl.cs deleted file mode 100644 index c152ee8530..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass1.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class LambertianPrefilteringSHNoComputePass1Keys - { - public static readonly ObjectParameterKey RadianceMap = ParameterKeys.NewObject(); - public static readonly ValueParameterKey CoefficientIndex = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass2.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass2.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHNoComputePass2.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass1.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass1.sdsl.cs deleted file mode 100644 index 0a147d64aa..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass1.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class LambertianPrefilteringSHPass1Keys - { - public static readonly ObjectParameterKey RadianceMap = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey OutputBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass2.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass2.sdsl.cs deleted file mode 100644 index 9fdf2fddbb..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ComputeEffect/LambertianPrefiltering/LambertianPrefilteringSHPass2.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class LambertianPrefilteringSHPass2Keys - { - public static readonly ObjectParameterKey InputBuffer = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey OutputBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocity.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocity.sdsl.cs deleted file mode 100644 index 749d57c8a5..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocity.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class BackgroundVelocityKeys - { - public static readonly ValueParameterKey DeltaMatrix = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocityEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocityEffect.sdfx.cs deleted file mode 100644 index 1342294f42..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/BackgroundVelocityEffect.sdfx.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -internal static partial class ShaderMixins -{ - internal partial class BackgroundVelocityEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "ShadingBase"); - context.Mixin(mixin, "BackgroundVelocity"); - var targetExtensions = context.GetParam(StrideEffectBaseKeys.RenderTargetExtensions); - if (targetExtensions != null) - { - context.Mixin(mixin, (targetExtensions)); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("BackgroundVelocityEffect", new BackgroundVelocityEffect()); - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Core/ColorBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/ColorBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/ColorBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/DynamicSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/DynamicSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/DynamicSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTexture.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/DynamicTexture.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTexture.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureCube.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureCube.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureCube.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/DynamicTextureStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/MeshVelocity.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/MeshVelocity.sdsl.cs deleted file mode 100644 index b51ca178fe..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/MeshVelocity.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class MeshVelocityKeys - { - public static readonly ValueParameterKey PreviousWorldViewProjection = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMesh.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMesh.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMesh.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMeshInstanced.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMeshInstanced.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromMeshInstanced.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMapping.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMapping.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMapping.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingInstanced.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingInstanced.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingInstanced.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellation.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellation.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellation.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellationInstanced.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellationInstanced.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalFromNormalMappingTessellationInstanced.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/NormalUpdate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/NormalUpdate.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/NormalUpdate.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/PositionHStream4.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/PositionHStream4.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/PositionHStream4.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/PositionStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/PositionStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/PositionStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/PositionStream4.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/PositionStream4.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/PositionStream4.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/PositionVertexTransform.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/PositionVertexTransform.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/PositionVertexTransform.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/ScreenPositionBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/ScreenPositionBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/ScreenPositionBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/ShadingBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/ShadingBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/ShadingBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/ShadingColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/ShadingColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/ShadingColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/VelocityOutput.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/VelocityOutput.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/VelocityOutput.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Core/VelocityStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Core/VelocityStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Core/VelocityStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Deferred/GBuffer.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Deferred/GBuffer.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Deferred/GBuffer.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/CompilationErrorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/CompilationErrorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/CompilationErrorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/EffectCompiling.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/EffectCompiling.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/EffectCompiling.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/LightConstantWhite.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/LightConstantWhite.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/LightConstantWhite.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/SelectedSpriteShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/SelectedSpriteShader.sdsl.cs deleted file mode 100644 index 9709408769..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/SelectedSpriteShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SelectedSpriteShaderKeys - { - public static readonly ValueParameterKey Blend = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/SharedTextureCoordinate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/SharedTextureCoordinate.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/SharedTextureCoordinate.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/Sprite3DBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/Sprite3DBase.sdsl.cs deleted file mode 100644 index 2b6bdf8b67..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/Sprite3DBase.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class Sprite3DBaseKeys - { - public static readonly ValueParameterKey SliceCoordinate = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Editor/SpritePicking.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Editor/SpritePicking.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Editor/SpritePicking.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurEffect.sdfx.cs deleted file mode 100644 index 3c6e7bcd00..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class AmbientOcclusionBlurEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "AmbientOcclusionBlurShader", context.GetParam(AmbientOcclusionBlurKeys.Count), context.GetParam(AmbientOcclusionBlurKeys.VerticalBlur), context.GetParam(AmbientOcclusionBlurKeys.BlurScale), context.GetParam(AmbientOcclusionBlurKeys.EdgeSharpness), context.GetParam(AmbientOcclusionBlurKeys.IsOrthographic)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("AmbientOcclusionBlurEffect", new AmbientOcclusionBlurEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurShader.sdsl.cs deleted file mode 100644 index e476e71b38..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionBlurShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class AmbientOcclusionBlurShaderKeys - { - public static readonly ValueParameterKey Weights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOEffect.sdfx.cs deleted file mode 100644 index b445853eff..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class AmbientOcclusionRawAOEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "AmbientOcclusionRawAOShader", context.GetParam(AmbientOcclusionRawAOKeys.Count), context.GetParam(AmbientOcclusionRawAOKeys.IsOrthographic)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("AmbientOcclusionRawAOEffect", new AmbientOcclusionRawAOEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOShader.sdsl.cs deleted file mode 100644 index 37508455b8..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/AmbientOcclusionRawAOShader.sdsl.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class AmbientOcclusionRawAOShaderKeys - { - public static readonly ValueParameterKey ProjInfo = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ScreenInfo = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ParamProjScale = ParameterKeys.NewValue(1); - public static readonly ValueParameterKey ParamIntensity = ParameterKeys.NewValue(1); - public static readonly ValueParameterKey ParamBias = ParameterKeys.NewValue(0.01f); - public static readonly ValueParameterKey ParamRadius = ParameterKeys.NewValue(1); - public static readonly ValueParameterKey ParamRadiusSquared = ParameterKeys.NewValue(1); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShaderEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShaderEffect.sdfx.cs deleted file mode 100644 index 9c083e307a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/FXAAShaderEffect.sdfx.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class FXAAShaderEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("FXAA_GREEN_AS_LUMA", context.GetParam(FXAAEffect.GreenAsLumaKey)); - mixin.AddMacro("FXAA_QUALITY__PRESET", context.GetParam(FXAAEffect.QualityKey)); - context.Mixin(mixin, "FXAAShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("FXAAShaderEffect", new FXAAShaderEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/TemporalAntiAliasShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/TemporalAntiAliasShader.sdsl.cs deleted file mode 100644 index 57231fa835..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/AntiAliasing/TemporalAntiAliasShader.sdsl.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TemporalAntiAliasShaderKeys - { - public static readonly ValueParameterKey u_BlendWeightMin = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_BlendWeightMax = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_HistoryBlurAmp = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_LumaContrastFactor = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_VelocityDecay = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_WeightCenter = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_WeightLowCenter = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_Weight1 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_Weight2 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_WeightLow1 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey u_WeightLow2 = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageCombineShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageCombineShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageCombineShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageShader.sdsl.cs deleted file mode 100644 index cbbb37eb53..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/Bloom/BloomAfterimageShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class BloomAfterimageShaderKeys - { - public static readonly ValueParameterKey FadeOutSpeed = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Sensitivity = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/BrightFilter/BrightFilterShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/BrightFilter/BrightFilterShader.sdsl.cs deleted file mode 100644 index d15a6c062d..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/BrightFilter/BrightFilterShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class BrightFilterShaderKeys - { - public static readonly ValueParameterKey ColorModulator = ParameterKeys.NewValue(); - public static readonly ValueParameterKey BrightPassSteepness = ParameterKeys.NewValue(2.0f); - public static readonly ValueParameterKey ThresholdOffset = ParameterKeys.NewValue(0.2f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerEffect.sdfx.cs deleted file mode 100644 index bf994e8425..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class ColorCombinerEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ColorCombinerShader", context.GetParam(ColorCombiner.FactorCount)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ColorCombinerEffect", new ColorCombinerEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerShader.sdsl.cs deleted file mode 100644 index ff883a7974..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorCombiner/ColorCombinerShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ColorCombinerShaderKeys - { - public static readonly ValueParameterKey Factors = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ModulateRGB = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx.cs deleted file mode 100644 index 69cccd6e06..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx.cs +++ /dev/null @@ -1,67 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class ColorTransformCompose : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, context.GetParam(ColorTransformKeys.Shader), context.GetParam(ColorTransformKeys.GenericArguments)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ColorTransformCompose", new ColorTransformCompose()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class ColorTransformGroupEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ColorTransformGroupShader"); - foreach(var colorTransform in context.GetParam(ColorTransformGroupKeys.Transforms)) - - { - context.PushParameters(colorTransform.Parameters); - - { - var __mixinToCompose__ = "ColorTransformCompose"; - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "Transforms", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - context.PopParameters(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ColorTransformGroupEffect", new ColorTransformGroupEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Noise/FilmGrainShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Noise/FilmGrainShader.sdsl.cs deleted file mode 100644 index e0104e2e64..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Noise/FilmGrainShader.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class FilmGrainShaderKeys - { - public static readonly ValueParameterKey Amount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Time = ParameterKeys.NewValue(); - public static readonly ValueParameterKey GrainSize = ParameterKeys.NewValue(); - public static readonly ValueParameterKey LuminanceFactor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapACESOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapACESOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapACESOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapCommonOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapCommonOperatorShader.sdsl.cs deleted file mode 100644 index 3212564d14..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapCommonOperatorShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapCommonOperatorShaderKeys - { - public static readonly ValueParameterKey LuminanceSaturation = ParameterKeys.NewValue(1.0f); - public static readonly ValueParameterKey WhiteLevel = ParameterKeys.NewValue(5.0f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapDragoOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapDragoOperatorShader.sdsl.cs deleted file mode 100644 index d0f53ff9cd..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapDragoOperatorShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapDragoOperatorShaderKeys - { - public static readonly ValueParameterKey DragoBias = ParameterKeys.NewValue(0.5f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapEffect.sdfx.cs deleted file mode 100644 index 746aa58d54..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapEffect.sdfx.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class ToneMapEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ToneMapShader", context.GetParam(ToneMapKeys.AutoKey), context.GetParam(ToneMapKeys.AutoExposure), context.GetParam(ToneMapKeys.UseLocalLuminance)); - context.PushParameters(context.GetParam(ToneMapKeys.Operator).Parameters); - - { - var __mixinToCompose__ = context.GetParam(ColorTransformKeys.Shader); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "ToneMapOperator", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - context.PopParameters(); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ToneMapEffect", new ToneMapEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapExponentialOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapExponentialOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapExponentialOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejl2OperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejl2OperatorShader.sdsl.cs deleted file mode 100644 index 077706021d..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejl2OperatorShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapHejl2OperatorShaderKeys - { - public static readonly ValueParameterKey WhitePoint = ParameterKeys.NewValue(5.0f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejlDawsonOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejlDawsonOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapHejlDawsonOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapLogarithmicOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapLogarithmicOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapLogarithmicOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapMikeDayOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapMikeDayOperatorShader.sdsl.cs deleted file mode 100644 index abaa012a78..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapMikeDayOperatorShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapMikeDayOperatorShaderKeys - { - public static readonly ValueParameterKey ToeCoeffs = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ShoulderCoeffs = ParameterKeys.NewValue(); - public static readonly ValueParameterKey MiddleCrossOver = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapReinhardOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapReinhardOperatorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapReinhardOperatorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapShader.sdsl.cs deleted file mode 100644 index 226be520f0..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapShader.sdsl.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapShaderKeys - { - public static readonly ObjectParameterKey LuminanceTexture = ParameterKeys.NewObject(); - public static readonly ValueParameterKey KeyValue = ParameterKeys.NewValue(0.18f); - public static readonly ValueParameterKey LuminanceLocalFactor = ParameterKeys.NewValue(0.0f); - public static readonly ValueParameterKey LuminanceAverageGlobal = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Contrast = ParameterKeys.NewValue(0.0f); - public static readonly ValueParameterKey Brightness = ParameterKeys.NewValue(0.0f); - public static readonly ValueParameterKey Exposure = ParameterKeys.NewValue(1.0f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapU2FilmicOperatorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapU2FilmicOperatorShader.sdsl.cs deleted file mode 100644 index ee53c982d9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ToneMap/ToneMapU2FilmicOperatorShader.sdsl.cs +++ /dev/null @@ -1,29 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ToneMapU2FilmicOperatorShaderKeys - { - public static readonly ValueParameterKey ShoulderStrength = ParameterKeys.NewValue(0.22f); - public static readonly ValueParameterKey LinearStrength = ParameterKeys.NewValue(0.25f); - public static readonly ValueParameterKey LinearAngle = ParameterKeys.NewValue(0.1f); - public static readonly ValueParameterKey ToeStrength = ParameterKeys.NewValue(0.2f); - public static readonly ValueParameterKey ToeNumerator = ParameterKeys.NewValue(0.01f); - public static readonly ValueParameterKey ToeDenominator = ParameterKeys.NewValue(0.3f); - public static readonly ValueParameterKey LinearWhite = ParameterKeys.NewValue(11.2f); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Vignetting/VignettingShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Vignetting/VignettingShader.sdsl.cs deleted file mode 100644 index df4c4e1070..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/Vignetting/VignettingShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class VignettingShaderKeys - { - public static readonly ValueParameterKey Amount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey RadiusBegin = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Color = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxEffect.sdfx.cs deleted file mode 100644 index d262be11d5..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class DepthMinMaxEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "DepthMinMaxShader", context.GetParam(DepthMinMax.IsFirstPassKey)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DepthMinMaxEffect", new DepthMinMaxEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxShader.sdsl.cs deleted file mode 100644 index 1d5c58ddf7..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthMinMax/DepthMinMaxShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class DepthMinMaxShaderKeys - { - public static readonly ObjectParameterKey TextureMap = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey TextureReduction = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshCombineShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshCombineShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshCombineShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedEffect.sdfx.cs deleted file mode 100644 index 9f07eebbc3..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedEffect.sdfx.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class McIntoshOptimizedEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "McIntoshOptimizedShader"); - - { - var __mixinToCompose__ = "DepthAwareDirectionalBlurUtil"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "directionalBlurA", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__, context.GetParam(DepthAwareDirectionalBlurKeys.Count), context.GetParam(DepthAwareDirectionalBlurKeys.TotalTap)); - context.PopComposition(); - } - - { - var __mixinToCompose__ = "DepthAwareDirectionalBlurUtil"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "directionalBlurB", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__, context.GetParam(DepthAwareDirectionalBlurKeys.Count), context.GetParam(DepthAwareDirectionalBlurKeys.TotalTap)); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("McIntoshOptimizedEffect", new McIntoshOptimizedEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/McIntoshOptimizedShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/TripleRhombiCombineShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/TripleRhombiCombineShader.sdsl.cs deleted file mode 100644 index 513d9ee4c6..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/BokehTechnique/Hexagonal/TripleRhombiCombineShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class TripleRhombiCombineShaderKeys - { - public static readonly ValueParameterKey RhombiTapOffsets = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CircleOfConfusion.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CircleOfConfusion.sdsl.cs deleted file mode 100644 index dce070808a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CircleOfConfusion.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class CircleOfConfusionKeys - { - public static readonly ValueParameterKey depthAreas = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCLinearDepthShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCLinearDepthShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCLinearDepthShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurEffect.sdfx.cs deleted file mode 100644 index 4c01beef2b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class CoCMapBlurEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "CoCMapBlurShader", context.GetParam(DepthAwareDirectionalBlurKeys.Count)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CoCMapBlurEffect", new CoCMapBlurEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurShader.sdsl.cs deleted file mode 100644 index 42266eb9a6..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CoCMapBlurShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class CoCMapBlurShaderKeys - { - public static readonly ValueParameterKey Direction = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Radius = ParameterKeys.NewValue(); - public static readonly ValueParameterKey OffsetsWeights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCEffect.sdfx.cs deleted file mode 100644 index dc132938a0..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class CombineFrontCoCEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "CombineFrontCoCShader", context.GetParam(CombineLevelsFromCoCKeys.LevelCount)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CombineFrontCoCEffect", new CombineFrontCoCEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineFrontCoCShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCEffect.sdfx.cs deleted file mode 100644 index 04a316d84a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class CombineLevelsFromCoCEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "CombineLevelsFromCoCShader", context.GetParam(CombineLevelsFromCoCKeys.LevelCount)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("CombineLevelsFromCoCEffect", new CombineLevelsFromCoCEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCShader.sdsl.cs deleted file mode 100644 index 8d95b033c2..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/CombineLevelsFromCoCShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class CombineLevelsFromCoCShaderKeys - { - public static readonly ValueParameterKey CoCLevelValues = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurEffect.sdfx.cs deleted file mode 100644 index 6a8de1ce99..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class DepthAwareDirectionalBlurEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "DepthAwareDirectionalBlurShader", context.GetParam(DepthAwareDirectionalBlurKeys.Count), context.GetParam(DepthAwareDirectionalBlurKeys.TotalTap)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DepthAwareDirectionalBlurEffect", new DepthAwareDirectionalBlurEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurUtil.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurUtil.sdsl.cs deleted file mode 100644 index 165e5b1789..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/DepthAwareDirectionalBlurUtil.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class DepthAwareDirectionalBlurUtilKeys - { - public static readonly ValueParameterKey Direction = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Radius = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TapWeights = ParameterKeys.NewValue(); - public static readonly ValueParameterKey CoCReference = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/PointDepth.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/PointDepth.sdsl.cs deleted file mode 100644 index 8e8610503f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/PointDepth.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class PointDepthKeys - { - public static readonly ValueParameterKey Coordinate = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoC.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoC.sdsl.cs deleted file mode 100644 index d22f882c9a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoC.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class ThresholdAlphaCoCKeys - { - public static readonly ValueParameterKey CoCReference = ParameterKeys.NewValue(); - public static readonly ValueParameterKey CoCCurrent = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoCFront.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoCFront.sdsl.cs deleted file mode 100644 index 5f8e8f2011..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/DepthOfField/ThresholdAlphaCoCFront.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class ThresholdAlphaCoCFrontKeys - { - public static readonly ValueParameterKey CoCReference = ParameterKeys.NewValue(); - public static readonly ValueParameterKey CoCCurrent = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/Dither/Dither.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/Dither/Dither.sdsl.cs deleted file mode 100644 index e89821d70a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/Dither/Dither.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class DitherKeys - { - public static readonly ValueParameterKey Time = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurEffect.sdfx.cs deleted file mode 100644 index f1328689f0..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class GaussianBlurEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "GaussianBlurShader", context.GetParam(GaussianBlurKeys.Count), context.GetParam(GaussianBlurKeys.VerticalBlur)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("GaussianBlurEffect", new GaussianBlurEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurShader.sdsl.cs deleted file mode 100644 index 1a7f56d0fa..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/GaussianBlur/GaussianBlurShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class GaussianBlurShaderKeys - { - public static readonly ValueParameterKey OffsetsWeights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ImageEffectShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ImageEffectShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ImageEffectShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerEffect.sdfx.cs deleted file mode 100644 index c9028b9740..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerEffect.sdfx.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class ImageScalerEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ImageScalerShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ImageScalerEffect", new ImageScalerEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class ImageSuperSamplerScalerEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ImageScalerShader"); - context.Mixin(mixin, "SpriteSuperSampler"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ImageSuperSamplerScalerEffect", new ImageSuperSamplerScalerEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerShader.sdsl.cs deleted file mode 100644 index fded8d5e87..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/ImageScaler/ImageScalerShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ImageScalerShaderKeys - { - public static readonly ValueParameterKey Color = ParameterKeys.NewValue(); - public static readonly ValueParameterKey IsOnlyChannelRed = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactEffect.sdfx.cs deleted file mode 100644 index 69fc346cd5..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class FlareArtifactEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "FlareArtifactShader", context.GetParam(FlareArtifactKeys.Count)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("FlareArtifactEffect", new FlareArtifactEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactShader.sdsl.cs deleted file mode 100644 index 7bd7717521..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareArtifactShader.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class FlareArtifactShaderKeys - { - public static readonly ValueParameterKey Amount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ZoomOffsetsDistortions = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ColorAberrations = ParameterKeys.NewValue(); - public static readonly ValueParameterKey AberrationStrength = ParameterKeys.NewValue(0); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareReplicate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareReplicate.sdsl.cs deleted file mode 100644 index fc3d99dbbf..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LensFlare/FlareReplicate.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class FlareReplicateKeys - { - public static readonly ValueParameterKey Amount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HaloFactor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl.cs deleted file mode 100644 index e8fc33a113..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class AdditiveLightEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "AdditiveLightShader", context.GetParam(AdditiveLightEffectKeys.Color)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("AdditiveLightEffect", new AdditiveLightEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightShader.sdsl.cs deleted file mode 100644 index 7a133c5c3f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class AdditiveLightShaderKeys - { - public static readonly ValueParameterKey LightColor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsEffect.sdfx.cs deleted file mode 100644 index deabad8eed..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsEffect.sdfx.cs +++ /dev/null @@ -1,44 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class LightShaftsEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - - { - var __mixinToCompose__ = (context.GetParam(LightShaftsEffectKeys.LightGroup)); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "lightGroup", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - context.Mixin(mixin, "LightShaftsShader", context.GetParam(LightShaftsEffectKeys.SampleCount)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LightShaftsEffect", new LightShaftsEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsShader.sdsl.cs deleted file mode 100644 index 3144defe2e..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/LightShaftsShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class LightShaftsShaderKeys - { - public static readonly ValueParameterKey DensityFactor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/PostEffectBoundingRay.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/PostEffectBoundingRay.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/PostEffectBoundingRay.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/VolumeMinMaxShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/VolumeMinMaxShader.sdsl.cs deleted file mode 100644 index 4ce46908ed..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/VolumeMinMaxShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VolumeMinMaxShaderKeys - { - public static readonly ValueParameterKey WorldViewProjection = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakEffect.sdfx.cs deleted file mode 100644 index fcecb62f2b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class LightStreakEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LightStreakShader", context.GetParam(LightStreakKeys.Count), context.GetParam(LightStreakKeys.AnamorphicCount)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LightStreakEffect", new LightStreakEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakShader.sdsl.cs deleted file mode 100644 index debc5a2176..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LightStreak/LightStreakShader.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class LightStreakShaderKeys - { - public static readonly ValueParameterKey TapOffsetsWeights = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Direction = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ColorAberrationCoefficients = ParameterKeys.NewValue(); - public static readonly ValueParameterKey AnamorphicOffsetsWeight = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRBlurPass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRBlurPass.sdsl.cs deleted file mode 100644 index 011f3fe304..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRBlurPass.sdsl.cs +++ /dev/null @@ -1,58 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class SSLRBlurPassKeys - { - } - internal static partial class ShaderMixins - { - internal partial class SSLRBlurPassEffectH : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("CONVOLVE_VERTICAL", 0); - context.Mixin(mixin, "SSLRBlurPass"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SSLRBlurPassEffectH", new SSLRBlurPassEffectH()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class SSLRBlurPassEffectV : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("CONVOLVE_VERTICAL", 1); - context.Mixin(mixin, "SSLRBlurPass"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SSLRBlurPassEffectV", new SSLRBlurPassEffectV()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCombinePass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCombinePass.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCombinePass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCommon.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCommon.sdsl.cs deleted file mode 100644 index d490c924d8..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRCommon.sdsl.cs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class SSLRCommonKeys - { - public static readonly ValueParameterKey MaxColorMiplevel = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TraceSizeMax = ParameterKeys.NewValue(); - public static readonly ValueParameterKey MaxTraceSamples = ParameterKeys.NewValue(); - public static readonly ValueParameterKey RoughnessFade = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TemporalTime = ParameterKeys.NewValue(); - public static readonly ValueParameterKey BRDFBias = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewFarPlane = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewInfo = ParameterKeys.NewValue(); - public static readonly ValueParameterKey CameraPosWS = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldAntiSelfOcclusionBias = ParameterKeys.NewValue(); - public static readonly ValueParameterKey V = ParameterKeys.NewValue(); - public static readonly ValueParameterKey IVP = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRDepthPass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRDepthPass.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRDepthPass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRRayTracePass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRRayTracePass.sdsl.cs deleted file mode 100644 index f751ec63ee..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRRayTracePass.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class SSLRRayTracePassKeys - { - public static readonly ValueParameterKey EdgeFadeFactor = ParameterKeys.NewValue(); - public static readonly ValueParameterKey VP = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRResolvePass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRResolvePass.sdsl.cs deleted file mode 100644 index 2712d1f0ef..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRResolvePass.sdsl.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class SSLRResolvePassKeys - { - } - internal static partial class ShaderMixins - { - internal partial class SSLRResolvePassEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SSLRResolvePass", context.GetParam(SSLRKeys.ResolveSamples), context.GetParam(SSLRKeys.ReduceHighlights)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SSLRResolvePassEffect", new SSLRResolvePassEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRTemporalPass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRTemporalPass.sdsl.cs deleted file mode 100644 index 388ee10bde..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LocalReflections/SSLRTemporalPass.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - public static partial class SSLRTemporalPassKeys - { - public static readonly ValueParameterKey TemporalResponse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TemporalScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey IVP = ParameterKeys.NewValue(); - public static readonly ValueParameterKey prevVP = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceLogShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceLogShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceLogShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceUtils.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceUtils.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/LuminanceEffect/LuminanceUtils.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsParameters.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsParameters.sdfx.cs deleted file mode 100644 index 266f003971..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsParameters.sdfx.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - [DataContract]public partial class SphericalHarmonicsParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey HarmonicsOrder = ParameterKeys.NewPermutation(); - }; -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRenderer.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRenderer.sdsl.cs deleted file mode 100644 index 459341937f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRenderer.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class SphericalHarmonicsRendererKeys - { - public static readonly ValueParameterKey SHCoefficients = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRendererEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRendererEffect.sdfx.cs deleted file mode 100644 index 633857a0ab..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsRendererEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Images -{ - internal static partial class ShaderMixins - { - internal partial class SphericalHarmonicsRendererEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SphericalHarmonicsRenderer", context.GetParam(SphericalHarmonicsParameters.HarmonicsOrder)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SphericalHarmonicsRendererEffect", new SphericalHarmonicsRendererEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsUtils.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsUtils.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SphericalHarmonics/SphericalHarmonicsUtils.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurEffect.sdfx.cs deleted file mode 100644 index ca4899ef32..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurEffect.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.SubsurfaceScattering -{ - internal static partial class ShaderMixins - { - internal partial class SubsurfaceScatteringBlurEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - mixin.AddMacro("SSSS_FOLLOW_SURFACE", context.GetParam(SubsurfaceScatteringKeys.FollowSurface)); - context.Mixin(mixin, "SubsurfaceScatteringBlurShader", context.GetParam(SubsurfaceScatteringKeys.BlurHorizontally), context.GetParam(SubsurfaceScatteringKeys.KernelSizeJittering), context.GetParam(SubsurfaceScatteringKeys.OrthographicProjection), context.GetParam(SubsurfaceScatteringKeys.MaxMaterialCount), context.GetParam(SubsurfaceScatteringKeys.KernelLength), context.GetParam(SubsurfaceScatteringKeys.RenderMode)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SubsurfaceScatteringBlurEffect", new SubsurfaceScatteringBlurEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurShader.sdsl.cs deleted file mode 100644 index edd3bb6683..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Images/SubsurfaceScattering/SubsurfaceScatteringBlurShader.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.SubsurfaceScattering -{ - public static partial class SubsurfaceScatteringBlurShaderKeys - { - public static readonly ValueParameterKey ProjectionSizeOnUnitPlaneInClipSpace = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ScatteringWidths = ParameterKeys.NewValue(); - public static readonly ValueParameterKey IterationNumber = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewProjectionMatrix = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey KernelBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/LightProbes/BakeLightProbeShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/LightProbes/BakeLightProbeShader.sdsl.cs deleted file mode 100644 index 62cedd8be9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/LightProbes/BakeLightProbeShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.LightProbes -{ - public static partial class BakeLightProbeShaderKeys - { - public static readonly ValueParameterKey MatrixTransform = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/LightProbes/ComputeSphericalHarmonics.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/LightProbes/ComputeSphericalHarmonics.sdsl.cs deleted file mode 100644 index 775b7f8c29..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/LightProbes/ComputeSphericalHarmonics.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.LightProbes -{ - public static partial class ComputeSphericalHarmonicsKeys - { - public static readonly ValueParameterKey SphericalColors = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/LightProbes/LightProbeShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/LightProbes/LightProbeShader.sdsl.cs deleted file mode 100644 index 0d65a58026..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/LightProbes/LightProbeShader.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.LightProbes -{ - public static partial class LightProbeShaderKeys - { - public static readonly ValueParameterKey IgnoredProbeStart = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey LightProbeTetrahedronIds = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LightProbeTetrahedronProbeIndices = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LightProbeTetrahedronMatrices = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LightProbeCoefficients = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx.cs deleted file mode 100644 index 7780787c8a..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/LightProbes/StrideBakeLightProbeEffect.sdfx.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Materials; -namespace Stride.Rendering.LightProbes -{ - internal static partial class ShaderMixins - { - internal partial class StrideBakeLightProbeEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "BakeLightProbeShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideBakeLightProbeEffect", new StrideBakeLightProbeEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroup.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroup.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupArray.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupArray.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupArray.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupFixed.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupFixed.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupFixed.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerDraw.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerDraw.sdsl.cs deleted file mode 100644 index 37efb2f2e7..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerDraw.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class DirectLightGroupPerDrawKeys - { - public static readonly ValueParameterKey LightCount = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerView.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerView.sdsl.cs deleted file mode 100644 index 6ffa2a9566..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/DirectLightGroupPerView.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class DirectLightGroupPerViewKeys - { - public static readonly ValueParameterKey LightCount = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLight.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLight.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLight.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLightArray.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLightArray.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/EnvironmentLightArray.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightClustered.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightClustered.sdsl.cs deleted file mode 100644 index 50a2df2aae..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightClustered.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightClusteredKeys - { - public static readonly ObjectParameterKey LightClusters = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LightIndices = ParameterKeys.NewObject(); - public static readonly ValueParameterKey ClusterDepthScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ClusterDepthBias = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ClusterStride = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointGroup.sdsl.cs deleted file mode 100644 index e462c29ccc..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointGroup.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightClusteredPointGroupKeys - { - public static readonly ObjectParameterKey PointLights = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredSpotGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredSpotGroup.sdsl.cs deleted file mode 100644 index 0724f051e6..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredSpotGroup.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightClusteredSpotGroupKeys - { - public static readonly ObjectParameterKey SpotLights = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectional.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectionalGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectionalGroup.sdsl.cs deleted file mode 100644 index de7fe17ec7..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightDirectionalGroup.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightDirectionalGroupKeys - { - public static readonly ValueParameterKey Lights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightPoint.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightPointGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightPointGroup.sdsl.cs deleted file mode 100644 index e48f482a82..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightPointGroup.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightPointGroupKeys - { - public static readonly ValueParameterKey Lights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSimpleAmbient.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSimpleAmbient.sdsl.cs deleted file mode 100644 index 630132f4f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSimpleAmbient.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightSimpleAmbientKeys - { - public static readonly ValueParameterKey AmbientLight = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxEffect.sdfx.cs deleted file mode 100644 index 6fe10bba46..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxEffect.sdfx.cs +++ /dev/null @@ -1,59 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -namespace Stride.Rendering.Lights -{ - internal static partial class ShaderMixins - { - internal partial class LightSkyboxEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LightSkyboxShader"); - if (context.GetParam(LightSkyboxShaderKeys.LightDiffuseColor) != null) - { - - { - var __mixinToCompose__ = context.GetParam(LightSkyboxShaderKeys.LightDiffuseColor); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "lightDiffuseColor", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(LightSkyboxShaderKeys.LightSpecularColor) != null) - { - - { - var __mixinToCompose__ = context.GetParam(LightSkyboxShaderKeys.LightSpecularColor); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "lightSpecularColor", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LightSkyboxEffect", new LightSkyboxEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxShader.sdsl.cs deleted file mode 100644 index 6461870fe7..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSkyboxShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightSkyboxShaderKeys - { - public static readonly ValueParameterKey SkyMatrix = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Intensity = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpot.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationDefault.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationDefault.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationDefault.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationRectangular.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationRectangular.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotAttenuationRectangular.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotGroup.sdsl.cs deleted file mode 100644 index 87bafb6f13..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightSpotGroup.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - public static partial class LightSpotGroupKeys - { - public static readonly ValueParameterKey Lights = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightUtil.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightUtil.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightUtil.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/SpotLightDataInternalShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/SpotLightDataInternalShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/SpotLightDataInternalShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionCommon.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionCommon.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionCommon.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionFilterDefault.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionFilterDefault.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionFilterDefault.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionGroup.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionGroup.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverBase.sdsl.cs deleted file mode 100644 index a07f5571a8..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverBase.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Lights -{ - internal static partial class TextureProjectionReceiverBaseKeys - { - public static readonly ValueParameterKey WorldToProjectiveTextureUV = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjectorPlaneMatrices = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjectionTextureMipMapLevels = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TransitionAreas = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverSpot.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverSpot.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Lights/TextureProjection/TextureProjectionReceiverSpot.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightRamp.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightRamp.sdsl.cs deleted file mode 100644 index 150f9f3d24..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/CelShading/MaterialCelShadingLightRamp.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialCelShadingLightRampKeys - { - public static readonly ObjectParameterKey CelShaderRamp = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorAdd3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorAdd3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorAdd3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDarken3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDarken3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDarken3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDifference3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDifference3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorDifference3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorLighten3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorLighten3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorLighten3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMask3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMask3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMask3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMultiply3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMultiply3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorMultiply3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOver3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOver3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOver3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOverlay3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOverlay3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorOverlay3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorSubtract3ds.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorSubtract3ds.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/3dsMax/ComputeColorSubtract3ds.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor3.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor3.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColor3.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd3.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd3.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAdd3.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAverage.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAverage.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorAverage.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorCave.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorCave.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorCave.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorBurn.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorBurn.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorBurn.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorDodge.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorDodge.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorColorDodge.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColor3Link.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColor3Link.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColor3Link.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColorLink.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColorLink.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantColorLink.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantFloatLink.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantFloatLink.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantFloatLink.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantLink.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantLink.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorConstantLink.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDesaturate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDesaturate.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDesaturate.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDivide.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDivide.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorDivide.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorExclusion.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorExclusion.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorExclusion.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFixed.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFixed.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFixed.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFromStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFromStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorFromStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardLight.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardLight.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardLight.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardMix.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardMix.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHardMix.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHue.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHue.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorHue.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIlluminate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIlluminate.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIlluminate.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIn.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIn.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorIn.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLerpAlpha.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLerpAlpha.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLerpAlpha.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearBurn.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearBurn.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearBurn.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearDodge.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearDodge.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorLinearDodge.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMask.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMask.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMask.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMultiply.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMultiply.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorMultiply.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOne.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOne.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOne.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOut.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOut.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOut.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOutdoor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOutdoor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOutdoor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOverlay.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOverlay.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorOverlay.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorParameter.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorParameter.sdsl.cs deleted file mode 100644 index 0bac90e390..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorParameter.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ComputeColorParameterKeys - { - public static readonly ValueParameterKey ColorParameter = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorPinLight.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorPinLight.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorPinLight.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturate.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturate.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturate.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturation.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturation.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSaturation.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScaler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScaler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScaler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScreen.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScreen.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorScreen.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSoftLight.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSoftLight.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSoftLight.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlpha.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlpha.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlpha.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlphaWithColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlphaWithColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubstituteAlphaWithColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubtract.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubtract.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSubtract.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTexture.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTexture.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTexture.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureDynamicScaledOffset.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureDynamicScaledOffset.sdsl.cs deleted file mode 100644 index 4d10e8c721..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureDynamicScaledOffset.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ComputeColorTextureDynamicScaledOffsetKeys - { - public static readonly ValueParameterKey Offset = ParameterKeys.NewValue(new Vector2(0,0)); - public static readonly ValueParameterKey Scale = ParameterKeys.NewValue(new Vector2(1,1)); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledOffsetSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureLodScaledSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureRepeat.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureRepeat.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureRepeat.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaled.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaled.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaled.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffset.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffset.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffset.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledOffsetSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledSampler.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorTextureScaledSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorThreshold.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorThreshold.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorThreshold.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorValue.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorValue.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorValue.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorAddMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorAddMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorAddMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDarkenMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDarkenMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDarkenMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDifferenceMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDifferenceMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorDifferenceMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorLightenMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorLightenMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorLightenMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorMultiplyMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorMultiplyMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorMultiplyMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorOverMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorOverMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorOverMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorSubtractMaya.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorSubtractMaya.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/Maya/ComputeColorSubtractMaya.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/IMaterialHairDirectionFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/IMaterialHairDirectionFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/IMaterialHairDirectionFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionBitangent.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionBitangent.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionBitangent.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionTangent.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionTangent.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DirectionFunction/MaterialHairDirectionFunctionTangent.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/IMaterialHairDiscardFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/IMaterialHairDiscardFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/IMaterialHairDiscardFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionOpaquePass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionOpaquePass.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionOpaquePass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionTransparentPass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionTransparentPass.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/DiscardFunction/MaterialHairDiscardFunctionTransparentPass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/IMaterialHairLightAttenuationFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/IMaterialHairLightAttenuationFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/IMaterialHairLightAttenuationFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionDirectional.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionDirectional.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionDirectional.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionNone.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionNone.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/LightAttenuationFunction/MaterialHairLightAttenuationFunctionNone.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialHairShared.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialHairShared.sdsl.cs deleted file mode 100644 index 40f45dbd44..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialHairShared.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialHairSharedKeys - { - public static readonly ValueParameterKey PassID = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingDiffuseHair.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingDiffuseHair.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingDiffuseHair.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingSpecularHair.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingSpecularHair.sdsl.cs deleted file mode 100644 index e3c870361f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/MaterialSurfaceShadingSpecularHair.sdsl.cs +++ /dev/null @@ -1,33 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialSurfaceShadingSpecularHairKeys - { - public static readonly ValueParameterKey HairSpecularColor1 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularColor2 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairScalesAngle = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularShiftRatio = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularExponent1 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularExponent2 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularScale1 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairSpecularScale2 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairShiftNoiseScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey HairGlintsNoiseStrength = ParameterKeys.NewValue(); - public static readonly ValueParameterKey surfaceData = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/IMaterialHairShadowingFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/IMaterialHairShadowingFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/IMaterialHairShadowingFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionScattering.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionScattering.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionScattering.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionShadowing.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionShadowing.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Hair/ShadowingFunction/MaterialHairShadowingFunctionShadowing.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/IMaterialSurfaceDomain.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/IMaterialSurfaceDomain.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/IMaterialSurfaceDomain.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/IStreamInitializer.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/IStreamInitializer.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/IStreamInitializer.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDisplacementStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDisplacementStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDisplacementStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDomainStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDomainStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialDomainStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialStreamAdditiveBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialStreamAdditiveBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialStreamAdditiveBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDisplacement.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDisplacement.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDisplacement.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDomainStageCompositor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDomainStageCompositor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialSurfaceDomainStageCompositor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialTessellationStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialTessellationStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialTessellationStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/ComputeColorMaterialAlphaBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/ComputeColorMaterialAlphaBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/ComputeColorMaterialAlphaBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputNormals.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputNormals.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputNormals.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSpecularColorRoughness.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSpecularColorRoughness.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSpecularColorRoughness.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl.cs deleted file mode 100644 index 76d91011e2..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class GBufferOutputSubsurfaceScatteringMaterialIndexKeys - { - public static readonly ValueParameterKey MaterialIndex = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetFresnelFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetFresnelFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetFresnelFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetVisibilityFunction.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetVisibilityFunction.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSpecularMicrofacetVisibilityFunction.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialStreamBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialStreamBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialStreamBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurface.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurface.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurface.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfacePixel.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfacePixel.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfacePixel.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceVertex.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceVertex.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/IMaterialSurfaceVertex.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialFrontBackBlendShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialFrontBackBlendShader.sdsl.cs deleted file mode 100644 index 9001324647..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialFrontBackBlendShader.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class MaterialFrontBackBlendShaderKeys - { - public static readonly ValueParameterKey ColorFront = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ColorBlend = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ColorBack = ParameterKeys.NewValue(); - public static readonly ValueParameterKey AlphaBlend = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelShadingStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelShadingStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelShadingStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialPixelStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl.cs deleted file mode 100644 index 353dd05a99..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialSpecularMicrofacetEnvironmentGGXLUTKeys - { - public static readonly ObjectParameterKey EnvironmentLightingDFG_LUT = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelNone.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelNone.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelNone.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelSchlick.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelSchlick.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelSchlick.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelThinGlass.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelThinGlass.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetFresnelThinGlass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityImplicit.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityImplicit.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityImplicit.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityKelemen.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityKelemen.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityKelemen.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityNeumann.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityNeumann.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilityNeumann.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamLinearBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamLinearBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamLinearBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamNormalBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamNormalBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialStreamNormalBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceArray.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceArray.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceArray.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuse.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuse.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuse.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseMetalFlakes.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseMetalFlakes.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseMetalFlakes.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceEmissiveShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceEmissiveShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceEmissiveShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMap.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMap.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMap.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMapMetalFlakes.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMapMetalFlakes.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceGlossinessMapMetalFlakes.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceLightingAndShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceLightingAndShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceLightingAndShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceMetalness.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceMetalness.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceMetalness.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalMap.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalMap.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalMap.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalStreamShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalStreamShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceNormalStreamShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfacePixelStageCompositor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfacePixelStageCompositor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfacePixelStageCompositor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceSetStreamFromComputeColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceSetStreamFromComputeColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceSetStreamFromComputeColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingDiffuseLambert.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingDiffuseLambert.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingDiffuseLambert.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularMicrofacet.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularMicrofacet.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularMicrofacet.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamsBlend.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamsBlend.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceStreamsBlend.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransmittanceShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransmittanceShading.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransmittanceShading.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransparentAlphaDiscard.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransparentAlphaDiscard.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceTransparentAlphaDiscard.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexStageCompositor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexStageCompositor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexStageCompositor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialTransmittanceReflectanceStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialTransmittanceReflectanceStream.sdsl.cs deleted file mode 100644 index a741795d03..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialTransmittanceReflectanceStream.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialTransmittanceReflectanceStreamKeys - { - public static readonly ValueParameterKey RefractiveIndex = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialVertexStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialVertexStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialVertexStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/MaterialSurfaceSubsurfaceScatteringShading.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/MaterialSurfaceSubsurfaceScatteringShading.sdsl.cs deleted file mode 100644 index b2c479131f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/MaterialSurfaceSubsurfaceScatteringShading.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialSurfaceSubsurfaceScatteringShadingKeys - { - public static readonly ValueParameterKey Translucency = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ScatteringWidth = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/IMaterialSubsurfaceScatteringScatteringProfile.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/IMaterialSubsurfaceScatteringScatteringProfile.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/IMaterialSubsurfaceScatteringScatteringProfile.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl.cs deleted file mode 100644 index f43e9f09dc..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Materials -{ - public static partial class MaterialSubsurfaceScatteringScatteringProfileCustomUniformKeys - { - public static readonly ValueParameterKey ScatteringProfile = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/SubsurfaceScattering/ScatteringProfileFunction/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/ProceduralModels/CameraCube.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/ProceduralModels/CameraCube.sdsl.cs deleted file mode 100644 index 0e597726b1..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/ProceduralModels/CameraCube.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class CameraCubeKeys - { - public static readonly ValueParameterKey CameraWorldPosition = ParameterKeys.NewValue(); - public static readonly ValueParameterKey CameraViewProjectionMatrices = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shaders/Camera.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shaders/Camera.sdsl.cs deleted file mode 100644 index 2c54341ed0..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shaders/Camera.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class CameraKeys - { - public static readonly ValueParameterKey NearClipPlane = ParameterKeys.NewValue(1.0f); - public static readonly ValueParameterKey FarClipPlane = ParameterKeys.NewValue(100.0f); - public static readonly ValueParameterKey ZProjection = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewSize = ParameterKeys.NewValue(); - public static readonly ValueParameterKey AspectRatio = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shaders/Global.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shaders/Global.sdsl.cs deleted file mode 100644 index a77b6ac175..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shaders/Global.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class GlobalKeys - { - public static readonly ValueParameterKey Time = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TimeStep = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shaders/GlobalVR.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shaders/GlobalVR.sdsl.cs deleted file mode 100644 index 17ca0d69b4..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shaders/GlobalVR.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class GlobalVRKeys - { - public static readonly ValueParameterKey EyeIndex = ParameterKeys.NewValue(); - public static readonly ValueParameterKey EyeCount = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shaders/Transformation.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shaders/Transformation.sdsl.cs deleted file mode 100644 index cd63e89f3f..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shaders/Transformation.sdsl.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TransformationKeys - { - public static readonly ValueParameterKey View = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Projection = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjectionInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewProjection = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjScreenRay = ParameterKeys.NewValue(); - public static readonly ValueParameterKey Eye = ParameterKeys.NewValue(); - public static readonly ValueParameterKey World = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldInverseTranspose = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldView = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldViewInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldViewProjection = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WorldScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey EyeMS = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowGroup.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowGroup.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCaster.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCaster.sdfx.cs deleted file mode 100644 index 12bb7cc267..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCaster.sdfx.cs +++ /dev/null @@ -1,48 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Materials; -namespace Stride.Rendering.Shadows -{ - internal static partial class ShaderMixins - { - internal partial class ShadowMapCaster : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(MaterialKeys.UseDitheredShadows)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDithered"); - } - else if (context.GetParam(MaterialKeys.UsePixelShaderWithDepthPass)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDiscard"); - } - else - { - context.Mixin(mixin, "ShadowMapCasterNoPixelShader"); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ShadowMapCaster", new ShadowMapCaster()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMap.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMap.sdfx.cs deleted file mode 100644 index 91569872c5..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMap.sdfx.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Materials; -namespace Stride.Rendering.Shadows -{ - internal static partial class ShaderMixins - { - internal partial class ShadowMapCasterCubeMap : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(MaterialKeys.UseDitheredShadows)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDithered"); - } - else if (context.GetParam(MaterialKeys.UsePixelShaderWithDepthPass)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDiscard"); - } - else - { - context.Mixin(mixin, "ShadowMapCasterNoPixelShader"); - } - context.Mixin(mixin, "ShadowMapCasterCubeMapProjection"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ShadowMapCasterCubeMap", new ShadowMapCasterCubeMap()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMapProjection.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMapProjection.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterCubeMapProjection.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterNoPixelShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterNoPixelShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterNoPixelShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloid.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloid.sdfx.cs deleted file mode 100644 index 07a56bddf9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloid.sdfx.cs +++ /dev/null @@ -1,49 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Materials; -namespace Stride.Rendering.Shadows -{ - internal static partial class ShaderMixins - { - internal partial class ShadowMapCasterParaboloid : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(MaterialKeys.UseDitheredShadows)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDithered"); - } - else if (context.GetParam(MaterialKeys.UsePixelShaderWithDepthPass)) - { - context.Mixin(mixin, "ShadowMapCasterAlphaDiscard"); - } - else - { - context.Mixin(mixin, "ShadowMapCasterNoPixelShader"); - } - context.Mixin(mixin, "ShadowMapCasterParaboloidProjection"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ShadowMapCasterParaboloid", new ShadowMapCasterParaboloid()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloidProjection.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloidProjection.sdsl.cs deleted file mode 100644 index 549a3a4954..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterParaboloidProjection.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - public static partial class ShadowMapCasterParaboloidProjectionKeys - { - public static readonly ValueParameterKey DepthParameters = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCommon.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCommon.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCommon.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterDefault.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterDefault.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterDefault.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterPcf.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterPcf.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterPcf.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterVsm.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterVsm.sdsl.cs deleted file mode 100644 index 15fc84c6d8..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapFilterVsm.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - public static partial class ShadowMapFilterVsmKeys - { - public static readonly ValueParameterKey BleedingFactor = ParameterKeys.NewValue(); - public static readonly ValueParameterKey MinVariance = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapGroup.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapGroup.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapGroup.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverBase.sdsl.cs deleted file mode 100644 index 1a12fd564c..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverBase.sdsl.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - internal static partial class ShadowMapReceiverBaseKeys - { - public static readonly ValueParameterKey WorldToShadowCascadeUV = ParameterKeys.NewValue(); - public static readonly ValueParameterKey InverseWorldToShadowCascadeUV = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewMatrices = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthRanges = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthBiases = ParameterKeys.NewValue(); - public static readonly ValueParameterKey OffsetScales = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverDirectional.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverDirectional.sdsl.cs deleted file mode 100644 index 8e85e3d7e0..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverDirectional.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - internal static partial class ShadowMapReceiverDirectionalKeys - { - public static readonly ValueParameterKey CascadeDepthSplits = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointCubeMap.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointCubeMap.sdsl.cs deleted file mode 100644 index ade838a060..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointCubeMap.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - internal static partial class ShadowMapReceiverPointCubeMapKeys - { - public static readonly ValueParameterKey WorldToShadow = ParameterKeys.NewValue(); - public static readonly ValueParameterKey InverseWorldToShadow = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthBiases = ParameterKeys.NewValue(); - public static readonly ValueParameterKey OffsetScales = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthParameters = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointParaboloid.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointParaboloid.sdsl.cs deleted file mode 100644 index 0a8f014b94..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverPointParaboloid.sdsl.cs +++ /dev/null @@ -1,28 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Shadows -{ - internal static partial class ShadowMapReceiverPointParaboloidKeys - { - public static readonly ValueParameterKey View = ParameterKeys.NewValue(); - public static readonly ValueParameterKey FaceOffsets = ParameterKeys.NewValue(); - public static readonly ValueParameterKey BackfaceOffsets = ParameterKeys.NewValue(); - public static readonly ValueParameterKey FaceSizes = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthBiases = ParameterKeys.NewValue(); - public static readonly ValueParameterKey DepthParameters = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverSpot.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverSpot.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapReceiverSpot.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalMeshSkinning.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/NormalMeshSkinning.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalMeshSkinning.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningFromMesh.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningFromMesh.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningFromMesh.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMapping.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMapping.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMapping.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMappingTessellation.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMappingTessellation.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/NormalVSSkinningNormalMappingTessellation.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/TangentMeshSkinning.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/TangentMeshSkinning.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/TangentMeshSkinning.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinning.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinning.sdsl.cs deleted file mode 100644 index dbccd88527..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinning.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TransformationSkinningKeys - { - public static readonly ValueParameterKey BlendMatrixArray = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinningInstanced.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinningInstanced.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skinning/TransformationSkinningInstanced.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/CubemapUtils.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/CubemapUtils.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/CubemapUtils.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/IComputeEnvironmentColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/IComputeEnvironmentColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/IComputeEnvironmentColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/LevelCubeMapEnvironmentColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/LevelCubeMapEnvironmentColor.sdsl.cs deleted file mode 100644 index 8bfa783eb7..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/LevelCubeMapEnvironmentColor.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class LevelCubeMapEnvironmentColorKeys - { - public static readonly ObjectParameterKey CubeMap = ParameterKeys.NewObject(); - public static readonly ValueParameterKey MipLevel = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/RoughnessCubeMapEnvironmentColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/RoughnessCubeMapEnvironmentColor.sdsl.cs deleted file mode 100644 index cdd4e508b9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/RoughnessCubeMapEnvironmentColor.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class RoughnessCubeMapEnvironmentColorKeys - { - public static readonly ValueParameterKey MipCount = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey CubeMap = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderBase.sdsl.cs deleted file mode 100644 index b1cae718aa..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderBase.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class SkyboxShaderBaseKeys - { - public static readonly ValueParameterKey Intensity = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ProjectionInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ViewInverse = ParameterKeys.NewValue(); - public static readonly ValueParameterKey SkyMatrix = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderCubemap.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderCubemap.sdsl.cs deleted file mode 100644 index b841376fda..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderCubemap.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class SkyboxShaderCubemapKeys - { - public static readonly ObjectParameterKey CubeMap = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderTexture.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderTexture.sdsl.cs deleted file mode 100644 index 437e2fa715..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxShaderTexture.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class SkyboxShaderTextureKeys - { - public static readonly ObjectParameterKey Texture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxStream.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SkyboxStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SphericalHarmonicsEnvironmentColor.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Skyboxes/SphericalHarmonicsEnvironmentColor.sdsl.cs deleted file mode 100644 index 05847d8db1..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Skyboxes/SphericalHarmonicsEnvironmentColor.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Skyboxes -{ - public static partial class SphericalHarmonicsEnvironmentColorKeys - { - public static readonly ValueParameterKey SphericalColors = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/StrideEffectBase.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/StrideEffectBase.sdfx.cs deleted file mode 100644 index f36c51b60d..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/StrideEffectBase.sdfx.cs +++ /dev/null @@ -1,180 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Materials; -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class StrideEffectBase : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ShaderBase"); - context.Mixin(mixin, "ShadingBase"); - var extensionPreVertexStageSurfaceShaders = context.GetParam(MaterialKeys.VertexStageSurfaceShaders); - if (extensionPreVertexStageSurfaceShaders != null) - { - context.Mixin(mixin, "MaterialSurfaceVertexStageCompositor"); - - { - var __mixinToCompose__ = (extensionPreVertexStageSurfaceShaders); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "materialVertexStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = context.GetParam(MaterialKeys.VertexStageStreamInitializer); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "streamInitializerVertexStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - context.Mixin(mixin, "TransformationBase"); - context.Mixin(mixin, "NormalStream"); - var extensionTessellationShader = context.GetParam(MaterialKeys.TessellationShader); - if (context.GetParam(StrideEffectBaseKeys.HasInstancing)) - { - mixin.AddMacro("ModelTransformUsage", context.GetParam(StrideEffectBaseKeys.ModelTransformUsage)); - context.Mixin(mixin, "TransformationWAndVPInstanced"); - if (context.GetParam(MaterialKeys.HasNormalMap)) - { - if (extensionTessellationShader != null) - { - context.Mixin(mixin, "NormalFromNormalMappingTessellationInstanced"); - } - else - { - context.Mixin(mixin, "NormalFromNormalMappingInstanced"); - } - } - else - { - context.Mixin(mixin, "NormalFromMeshInstanced"); - } - } - else - { - context.Mixin(mixin, "TransformationWAndVP"); - if (context.GetParam(MaterialKeys.HasNormalMap)) - { - if (extensionTessellationShader != null) - { - context.Mixin(mixin, "NormalFromNormalMappingTessellation"); - } - else - { - context.Mixin(mixin, "NormalFromNormalMapping"); - } - } - else - { - context.Mixin(mixin, "NormalFromMesh"); - } - } - if (context.GetParam(MaterialKeys.HasSkinningPosition)) - { - mixin.AddMacro("SkinningMaxBones", context.GetParam(MaterialKeys.SkinningMaxBones)); - if (context.GetParam(StrideEffectBaseKeys.HasInstancing)) - { - context.Mixin(mixin, "TransformationSkinningInstanced"); - } - else - { - context.Mixin(mixin, "TransformationSkinning"); - } - if (context.GetParam(MaterialKeys.HasSkinningNormal)) - { - context.Mixin(mixin, "NormalMeshSkinning"); - } - if (context.GetParam(MaterialKeys.HasSkinningTangent)) - { - context.Mixin(mixin, "TangentMeshSkinning"); - } - if (context.GetParam(MaterialKeys.HasSkinningNormal)) - { - if (context.GetParam(MaterialKeys.HasNormalMap)) - { - if (extensionTessellationShader != null) - { - context.Mixin(mixin, "NormalVSSkinningNormalMappingTessellation"); - } - else - { - context.Mixin(mixin, "NormalVSSkinningNormalMapping"); - } - } - else - { - context.Mixin(mixin, "NormalVSSkinningFromMesh"); - } - } - } - if (extensionTessellationShader != null) - { - context.Mixin(mixin, (extensionTessellationShader)); - var extensionDomainStageSurfaceShaders = context.GetParam(MaterialKeys.DomainStageSurfaceShaders); - if (extensionDomainStageSurfaceShaders != null) - { - context.Mixin(mixin, "MaterialSurfaceDomainStageCompositor"); - - { - var __mixinToCompose__ = (extensionDomainStageSurfaceShaders); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "materialDomainStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = context.GetParam(MaterialKeys.DomainStageStreamInitializer); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "streamInitializerDomainStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - var computeVelocityShader = context.GetParam(StrideEffectBaseKeys.ComputeVelocityShader); - if (computeVelocityShader != null) - { - context.Mixin(mixin, (computeVelocityShader)); - } - var extensionPostVertexStage = context.GetParam(StrideEffectBaseKeys.ExtensionPostVertexStageShader); - if (extensionPostVertexStage != null) - { - context.Mixin(mixin, (extensionPostVertexStage)); - } - var targetExtensions = context.GetParam(StrideEffectBaseKeys.RenderTargetExtensions); - if (targetExtensions != null) - { - context.Mixin(mixin, (targetExtensions)); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideEffectBase", new StrideEffectBase()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx.cs deleted file mode 100644 index 0552629164..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx.cs +++ /dev/null @@ -1,133 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Materials; -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class StrideLighting : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - ShaderSourceCollection directLightGroups = context.GetParam(LightingKeys.DirectLightGroups); - if (directLightGroups != null) - { - foreach(ShaderSource directLightGroup in directLightGroups) - - { - - { - var __mixinToCompose__ = (directLightGroup); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "directLightGroups", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - ShaderSourceCollection environmentLights = context.GetParam(LightingKeys.EnvironmentLights); - if (environmentLights != null) - { - foreach(ShaderSource environmentLight in environmentLights) - - { - - { - var __mixinToCompose__ = (environmentLight); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "environmentLights", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideLighting", new StrideLighting()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class StrideForwardShadingEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideEffectBase"); - ShaderSource extensionPixelStageSurfaceShaders = context.GetParam(MaterialKeys.PixelStageSurfaceShaders); - if (extensionPixelStageSurfaceShaders != null) - { - context.Mixin(mixin, "MaterialSurfacePixelStageCompositor"); - - { - var __mixinToCompose__ = (extensionPixelStageSurfaceShaders); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "materialPixelStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = context.GetParam(MaterialKeys.PixelStageStreamInitializer); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "streamInitializerPixelStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - ShaderSource extensionPixelStageSurfaceFilter = context.GetParam(MaterialKeys.PixelStageSurfaceFilter); - if (extensionPixelStageSurfaceFilter != null) - { - context.Mixin(mixin, (extensionPixelStageSurfaceFilter)); - } - if (context.ChildEffectName == "GBuffer") - { - context.Mixin(mixin, "GBuffer"); - return; - } - } - context.Mixin(mixin, "StrideLighting"); - if (context.ChildEffectName == "ShadowMapCaster") - { - context.Mixin(mixin, "ShadowMapCaster"); - return; - } - if (context.ChildEffectName == "ShadowMapCasterParaboloid") - { - context.Mixin(mixin, "ShadowMapCasterParaboloid"); - return; - } - if (context.ChildEffectName == "ShadowMapCasterCubeMap") - { - context.Mixin(mixin, "ShadowMapCasterCubeMap"); - return; - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideForwardShadingEffect", new StrideForwardShadingEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/StrideWireframeShadingEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/StrideWireframeShadingEffect.sdfx.cs deleted file mode 100644 index 3ffe981f6d..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/StrideWireframeShadingEffect.sdfx.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class StrideWireframeShadingEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideEffectBase"); - context.Mixin(mixin, "MaterialFrontBackBlendShader", context.GetParam(MaterialFrontBackBlendShaderKeys.UseNormalBackFace)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideWireframeShadingEffect", new StrideWireframeShadingEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE2.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE2.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE2.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE3.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE3.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE3.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE4.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE4.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationAE4.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationFlat.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationFlat.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationFlat.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationPN.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationPN.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationPN.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationInstancing.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationInstancing.sdsl.cs deleted file mode 100644 index b21aadbbd2..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationInstancing.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TransformationInstancingKeys - { - public static readonly ObjectParameterKey InstanceWorld = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey InstanceWorldInverse = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVP.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVP.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVP.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVPInstanced.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVPInstanced.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWAndVPInstanced.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWVP.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWVP.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationWVP.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/BlendUtils.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/BlendUtils.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/BlendUtils.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/DepthBase.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/DepthBase.sdsl.cs deleted file mode 100644 index 0fe2186c14..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/DepthBase.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class DepthBaseKeys - { - public static readonly ObjectParameterKey DepthStencil = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/FlattenLayers.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/FlattenLayers.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/FlattenLayers.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/HSVUtils.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/HSVUtils.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/HSVUtils.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/HighlightShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/HighlightShader.sdsl.cs deleted file mode 100644 index 610d9f23d1..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/HighlightShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class HighlightShaderKeys - { - public static readonly ValueParameterKey HighlightColor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingEffect.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingEffect.sdfx.cs deleted file mode 100644 index 04dcba9c00..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingEffect.sdfx.cs +++ /dev/null @@ -1,37 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -namespace Stride.Rendering.Utils -{ - internal static partial class ShaderMixins - { - internal partial class ModelComponentPickingEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ModelComponentPickingShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ModelComponentPickingEffect", new ModelComponentPickingEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingShader.sdsl.cs deleted file mode 100644 index fbd26b59f3..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/ModelComponentPickingShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Utils -{ - public static partial class ModelComponentPickingShaderKeys - { - public static readonly ValueParameterKey ModelComponentId = ParameterKeys.NewValue(); - public static readonly ValueParameterKey MeshId = ParameterKeys.NewValue(); - public static readonly ValueParameterKey MaterialId = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/NormalPack.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/NormalPack.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/NormalPack.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/NormalUtil.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/NormalUtil.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/NormalUtil.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Picking.sdfx.cs b/sources/engine/Stride.Rendering/Rendering/Utils/Picking.sdfx.cs deleted file mode 100644 index b267043da9..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Picking.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - internal static partial class ShaderMixins - { - internal partial class Picking : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "PickingShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("Picking", new Picking()); - } - } - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/PickingShader.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/PickingShader.sdsl.cs deleted file mode 100644 index bbd1446c50..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/PickingShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class PickingShaderKeys - { - public static readonly ValueParameterKey PickingData = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/SwapUV.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/SwapUV.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/SwapUV.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl.cs b/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx.cs deleted file mode 100644 index b3a0fa0993..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class SimpleEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "SimpleShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("SimpleEffect", new SimpleEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl.cs deleted file mode 100644 index 9cd9329e65..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SimpleShaderKeys - { - public static readonly ValueParameterKey BaseColor = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx.cs deleted file mode 100644 index da958e69a5..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx.cs +++ /dev/null @@ -1,36 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test -{ - internal static partial class ShaderMixins - { - internal partial class ToGlslEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "ToGlslShader"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ToGlslEffect", new ToGlslEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl.cs deleted file mode 100644 index 0285c8370d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ToGlslShaderKeys - { - public static readonly ValueParameterKey BaseColor = ParameterKeys.NewValue(); - public static readonly ValueParameterKey TestArray = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl.cs deleted file mode 100644 index 00afac3a1f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ComputeColor2Keys - { - public static readonly ValueParameterKey Color = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx.cs deleted file mode 100644 index f0d0f1547c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx.cs +++ /dev/null @@ -1,70 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test1 -{ - [DataContract]public partial class SubParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey param1 = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey param2 = ParameterKeys.NewPermutation(1); - public static readonly PermutationParameterKey param3 = ParameterKeys.NewPermutation("ok"); - }; - [DataContract]public partial class TestParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey subParam1 = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey subParameters = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class DefaultComplexParams : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - context.Mixin(mixin, "C"); - int x = 1; - foreach(var ____1 in context.GetParam(TestParameters.subParameters)) - - { - context.PushParameters(____1); - if (context.GetParam(SubParameters.param1)) - { - context.Mixin(mixin, "C" + x); - } - x++; - context.PopParameters(); - } - - { - context.PushParameters(context.GetParam(TestParameters.subParam1)); - if (context.GetParam(SubParameters.param2) == 1) - { - context.Mixin(mixin, "D"); - } - context.PopParameters(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultComplexParams", new DefaultComplexParams()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx.cs deleted file mode 100644 index 6c98aca4b8..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace TestABC -{ - [DataContract]public partial class TestParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey UseComputeColor2 = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey UseComputeColorRedirect = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class ABCSubEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - if (context.GetParam(TestParameters.UseComputeColor2)) - { - context.Mixin(mixin, "TestComputeColor2"); - } - else if (context.GetParam(TestParameters.UseComputeColorRedirect)) - { - context.Mixin(mixin, "TestComputeColorRedirect"); - - { - var __mixinToCompose__ = "TestComputeColor2"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "ColorRedirect", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - else - { - context.Mixin(mixin, "TestComputeColor"); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ABCSubEffect", new ABCSubEffect()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class test_mixin_compose_keys : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - - { - var __mixinToCompose__ = "ABCSubEffect"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "SubCompute1", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = "ABCSubEffect"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "SubCompute2", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = "ABCSubEffect"; - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "SubComputes", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("test_mixin_compose_keys", new test_mixin_compose_keys()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx.cs deleted file mode 100644 index a873847df6..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test2 -{ - internal static partial class ShaderMixins - { - internal partial class DefaultSimple : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - context.Mixin(mixin, "C"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimple", new DefaultSimple()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx.cs deleted file mode 100644 index 05fa3c5c7a..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx.cs +++ /dev/null @@ -1,57 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test3 -{ - internal static partial class ShaderMixins - { - internal partial class ChildMixin : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "C1"); - context.Mixin(mixin, "C2"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ChildMixin", new ChildMixin()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class DefaultSimpleChild : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - context.Mixin(mixin, "C"); - context.Mixin(mixin, "ChildMixin"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimpleChild", new DefaultSimpleChild()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx.cs deleted file mode 100644 index 50141f7e80..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test4 -{ - [DataContract]public partial class TestParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey TestCount = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey UseComputeColorEffect = ParameterKeys.NewPermutation(); - }; - internal static partial class ShaderMixins - { - internal partial class ChildParamsMixin : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.SetParam(TestParameters.TestCount, 1); - if (context.GetParam(TestParameters.TestCount) == 1) - context.Mixin(mixin, "C1"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ChildParamsMixin", new ChildParamsMixin()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class DefaultSimpleChildParams : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - if (context.GetParam(TestParameters.TestCount) == 0) - context.Mixin(mixin, "B"); - if (context.ChildEffectName == "ChildParamsMixin") - { - context.Mixin(mixin, "ChildParamsMixin"); - return; - } - if (context.GetParam(TestParameters.TestCount) == 0) - context.Mixin(mixin, "C"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimpleChildParams", new DefaultSimpleChildParams()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx.cs deleted file mode 100644 index fcb091105c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx.cs +++ /dev/null @@ -1,61 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test5 -{ - internal static partial class ShaderMixins - { - internal partial class ChildClone : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "C1"); - context.Mixin(mixin, "C2"); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("ChildClone", new ChildClone()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class DefaultSimpleClone : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - context.Mixin(mixin, "C"); - if (context.ChildEffectName == "Test") - { - context.Mixin(mixin, "ChildClone"); - return; - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimpleClone", new DefaultSimpleClone()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx.cs deleted file mode 100644 index 400e3aa7fb..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test6 -{ - internal static partial class ShaderMixins - { - internal partial class DefaultSimpleCompose : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - context.Mixin(mixin, "C"); - - { - var __mixinToCompose__ = "X"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "x", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimpleCompose", new DefaultSimpleCompose()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx.cs deleted file mode 100644 index 3b69f48b39..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx.cs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Test7 -{ - [DataContract]public partial class TestParameters : ShaderMixinParameters - { - public static readonly PermutationParameterKey param1 = ParameterKeys.NewPermutation(); - public static readonly PermutationParameterKey param2 = ParameterKeys.NewPermutation(1); - public static readonly PermutationParameterKey param3 = ParameterKeys.NewPermutation("ok"); - }; - internal static partial class ShaderMixins - { - internal partial class DefaultSimpleParams : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "A"); - context.Mixin(mixin, "B"); - if (context.GetParam(TestParameters.param1)) - { - context.Mixin(mixin, "C"); - mixin.AddMacro("param2", context.GetParam(TestParameters.param2)); - - { - var __mixinToCompose__ = "X"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "x", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - else - { - context.Mixin(mixin, "D"); - mixin.AddMacro("Test", context.GetParam(TestParameters.param3)); - - { - var __mixinToCompose__ = "Y"; - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "y", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("DefaultSimpleParams", new DefaultSimpleParams()); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl.cs deleted file mode 100644 index 259492a449..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class BasicMixinKeys - { - public static readonly ValueParameterKey myFloat = ParameterKeys.NewValue(0.2f); - public static readonly ValueParameterKey myPosition = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl.cs deleted file mode 100644 index 81b831f867..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class BasicMixin2Keys - { - public static readonly ValueParameterKey myFloat = ParameterKeys.NewValue(0.2f); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl.cs deleted file mode 100644 index f1ecff7c77..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ChildKeys - { - public static readonly ObjectParameterKey childSampler = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey childTexture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl.cs deleted file mode 100644 index fdca8c2d20..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ConstantBufferTestKeys - { - public static readonly ValueParameterKey a = ParameterKeys.NewValue(); - public static readonly ValueParameterKey c = ParameterKeys.NewValue(); - public static readonly ValueParameterKey b = ParameterKeys.NewValue(); - public static readonly ValueParameterKey d = ParameterKeys.NewValue(); - public static readonly ValueParameterKey e = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl.cs deleted file mode 100644 index 874cb2eb80..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ExternMixinKeys - { - public static readonly ValueParameterKey externMember = ParameterKeys.NewValue(1.0f); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl.cs deleted file mode 100644 index cac53580cf..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ForEachTestKeys - { - public static readonly ValueParameterKey collec = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl.cs deleted file mode 100644 index e9f3af945f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class GenericClass2Keys - { - public static readonly ObjectParameterKey TextureAll = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl.cs deleted file mode 100644 index 61eee3ed7c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class GenericTexcoordKeys - { - public static readonly ValueParameterKey coords = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl.cs deleted file mode 100644 index 35aa0151cc..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class InternalReferenceMixinKeys - { - public static readonly ValueParameterKey myValue = ParameterKeys.NewValue(2.0f); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl.cs deleted file mode 100644 index 74d6a4b163..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class MacroTestKeys - { - public static readonly ValueParameterKey u = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl.cs deleted file mode 100644 index 1989f3ac70..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class ParentKeys - { - public static readonly ValueParameterKey baseValue = ParameterKeys.NewValue(2.0f); - public static readonly ObjectParameterKey parentTexture = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl.cs deleted file mode 100644 index 2699ba7ccf..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SemanticTestKeys - { - public static readonly ValueParameterKey sem0 = ParameterKeys.NewValue(); - public static readonly ValueParameterKey sem1 = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl.cs deleted file mode 100644 index b857f2d9a5..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class SimpleKeys - { - public static readonly ValueParameterKey test = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl.cs deleted file mode 100644 index f73d1352cf..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class StageBaseKeys - { - public static readonly ValueParameterKey stageMember = ParameterKeys.NewValue(1.0f); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl.cs deleted file mode 100644 index 4fa19c3551..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class StageDeclKeys - { - public static readonly ValueParameterKey myStageVar = ParameterKeys.NewValue(1); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl.cs deleted file mode 100644 index a8cb33a17c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class StageValueTestKeys - { - public static readonly ValueParameterKey testFloat = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl.cs deleted file mode 100644 index ea496e9d7c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class StaticMixinKeys - { - public static readonly ValueParameterKey staticMember = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl.cs deleted file mode 100644 index b5399d842f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class StructuredBufferTestKeys - { - public static readonly ObjectParameterKey sbtest = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey rwsbtest = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl.cs deleted file mode 100644 index d27571b349..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TestComputeShaderKeys - { - public static readonly ValueParameterKey ThreadGroupCountGlobal = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ParticleCount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey ParticleStartIndex = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey ParticleSortBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl.cs deleted file mode 100644 index 75c131ab78..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TestErrorsKeys - { - public static readonly ValueParameterKey nonStream = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl.cs deleted file mode 100644 index e5a20950eb..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TestGenericsKeys - { - public static readonly ValueParameterKey myMember = ParameterKeys.NewValue(2.0f); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl.cs deleted file mode 100644 index 47a282bcfd..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class TestStructInheritanceKeys - { - public static readonly ValueParameterKey member = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Video/Shaders/VideoShader.sdsl.cs b/sources/engine/Stride.Video/Shaders/VideoShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Video/Shaders/VideoShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawEffect.sdsl.cs deleted file mode 100644 index 1dba20190b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawEffect.sdsl.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels.Debug -{ - internal static partial class ShaderMixins - { - internal partial class VoxelVisualizationRawEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "VoxelVisualizationRawShader"); - if (context.GetParam(VoxelVisualizationRawShaderKeys.Attribute) != null) - { - - { - var __mixinToCompose__ = context.GetParam(VoxelVisualizationRawShaderKeys.Attribute); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "Attribute", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("VoxelVisualizationRawEffect", new VoxelVisualizationRawEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawShader.sdsl.cs deleted file mode 100644 index 16495311d8..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationRawShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels.Debug -{ - public static partial class VoxelVisualizationRawShaderKeys - { - public static readonly ValueParameterKey range = ParameterKeys.NewValue(); - public static readonly ValueParameterKey rangeOffset = ParameterKeys.NewValue(); - public static readonly ValueParameterKey mip = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewEffect.sdsl.cs deleted file mode 100644 index 1d9ed792b8..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewEffect.sdsl.cs +++ /dev/null @@ -1,62 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels.Debug -{ - internal static partial class ShaderMixins - { - internal partial class VoxelVisualizationViewEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "VoxelVisualizationViewShader"); - if (context.GetParam(VoxelVisualizationViewShaderKeys.marcher) != null) - { - - { - var __mixinToCompose__ = context.GetParam(VoxelVisualizationViewShaderKeys.marcher); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "marcher", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(MarchAttributesKeys.AttributeSamplers) != null) - { - foreach(var attr in context.GetParam(MarchAttributesKeys.AttributeSamplers)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributeSamplers", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("VoxelVisualizationViewEffect", new VoxelVisualizationViewEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewShader.sdsl.cs deleted file mode 100644 index bcf1b44b9c..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/DebugVisualizations/Shaders/VoxelVisualizationViewShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels.Debug -{ - public static partial class VoxelVisualizationViewShaderKeys - { - public static readonly ValueParameterKey background = ParameterKeys.NewValue(); - public static readonly ValueParameterKey view = ParameterKeys.NewValue(); - public static readonly ValueParameterKey viewInv = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/StrideForwardShadingEffectVXGI.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/StrideForwardShadingEffectVXGI.sdsl.cs deleted file mode 100644 index 90c3a87a1d..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/GraphicsCompositor/StrideForwardShadingEffectVXGI.sdsl.cs +++ /dev/null @@ -1,118 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Materials; -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class StrideLightingVXGI : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - ShaderSourceCollection directLightGroups = context.GetParam(LightingKeys.DirectLightGroups); - if (directLightGroups != null) - { - foreach(ShaderSource directLightGroup in directLightGroups) - - { - - { - var __mixinToCompose__ = (directLightGroup); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "directLightGroups", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - ShaderSourceCollection environmentLights = context.GetParam(LightingKeys.EnvironmentLights); - if (environmentLights != null) - { - foreach(ShaderSource environmentLight in environmentLights) - - { - - { - var __mixinToCompose__ = (environmentLight); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "environmentLights", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideLightingVXGI", new StrideLightingVXGI()); - } - } - } - internal static partial class ShaderMixins - { - internal partial class StrideForwardShadingEffectVXGI : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "StrideEffectBase"); - ShaderSource extensionPixelStageSurfaceShaders = context.GetParam(MaterialKeys.PixelStageSurfaceShaders); - if (extensionPixelStageSurfaceShaders != null) - { - context.Mixin(mixin, "MaterialSurfacePixelStageCompositor"); - - { - var __mixinToCompose__ = (extensionPixelStageSurfaceShaders); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "materialPixelStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - - { - var __mixinToCompose__ = context.GetParam(MaterialKeys.PixelStageStreamInitializer); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "streamInitializerPixelStage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - ShaderSource extensionPixelStageSurfaceFilter = context.GetParam(MaterialKeys.PixelStageSurfaceFilter); - if (extensionPixelStageSurfaceFilter != null) - { - context.Mixin(mixin, (extensionPixelStageSurfaceFilter)); - } - } - context.Mixin(mixin, "StrideLightingVXGI"); - if (context.ChildEffectName == "VoxelizeToFragmentsEffect") - { - context.Mixin(mixin, "VoxelizeToFragmentsEffect"); - return; - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("StrideForwardShadingEffectVXGI", new StrideForwardShadingEffectVXGI()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelEffect.sdsl.cs deleted file mode 100644 index 347821754a..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelEffect.sdsl.cs +++ /dev/null @@ -1,75 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Data; -using Stride.Rendering.Lights; -namespace Stride.Rendering.Voxels.VoxelGI -{ - internal static partial class ShaderMixins - { - internal partial class LightVoxelEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "LightVoxelShader"); - if (context.GetParam(LightVoxelShaderKeys.diffuseMarcher) != null) - { - - { - var __mixinToCompose__ = context.GetParam(LightVoxelShaderKeys.diffuseMarcher); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "diffuseMarcher", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(LightVoxelShaderKeys.specularMarcher) != null) - { - - { - var __mixinToCompose__ = context.GetParam(LightVoxelShaderKeys.specularMarcher); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "specularMarcher", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(MarchAttributesKeys.AttributeSamplers) != null) - { - foreach(var attr in context.GetParam(MarchAttributesKeys.AttributeSamplers)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributeSamplers", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("LightVoxelEffect", new LightVoxelEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelShader.sdsl.cs deleted file mode 100644 index 2cc695af78..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Light/LightVoxelShader.sdsl.cs +++ /dev/null @@ -1,25 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Lights; -namespace Stride.Rendering.Voxels.VoxelGI -{ - public static partial class LightVoxelShaderKeys - { - public static readonly ValueParameterKey Intensity = ParameterKeys.NewValue(); - public static readonly ValueParameterKey SpecularIntensity = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/IVoxelSampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/IVoxelSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/IVoxelSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSet.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSet.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSet.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere12.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere12.sdsl.cs deleted file mode 100644 index a3d10d6571..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere12.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelMarchSetHemisphere12Keys - { - public static readonly ValueParameterKey offset = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere6.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere6.sdsl.cs deleted file mode 100644 index 1431ae78da..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetHemisphere6.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelMarchSetHemisphere6Keys - { - public static readonly ValueParameterKey offset = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetRandomHemisphere.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetRandomHemisphere.sdsl.cs deleted file mode 100644 index c77c97a040..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/MarchSets/Shaders/VoxelMarchSetRandomHemisphere.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelMarchSetRandomHemisphereKeys - { - public static readonly ValueParameterKey marchCount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey time = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributes.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributes.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributes.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributesEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributesEffect.sdsl.cs deleted file mode 100644 index 1917d8d081..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/MarchAttributesEffect.sdsl.cs +++ /dev/null @@ -1,51 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class MarchAttributesEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "MarchAttributes"); - if (context.GetParam(MarchAttributesKeys.AttributeSamplers) != null) - { - foreach(var attr in context.GetParam(MarchAttributesKeys.AttributeSamplers)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributeSamplers", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("MarchAttributesEffect", new MarchAttributesEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchBeam.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchBeam.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchBeam.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchCone.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchCone.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchCone.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConeEditMode.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConeEditMode.sdsl.cs deleted file mode 100644 index d92397f271..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConeEditMode.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelMarchConeEditModeKeys - { - public static readonly ValueParameterKey steps = ParameterKeys.NewValue(); - public static readonly ValueParameterKey stepScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey coneRatio = ParameterKeys.NewValue(); - public static readonly ValueParameterKey fast = ParameterKeys.NewValue(); - public static readonly ValueParameterKey offset = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConePerMipmap.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConePerMipmap.sdsl.cs deleted file mode 100644 index d511a55e64..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchConePerMipmap.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelMarchConePerMipmapKeys - { - public static readonly ValueParameterKey offset = ParameterKeys.NewValue(); - public static readonly ValueParameterKey coneRatioInv = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchMethod.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchMethod.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelMarchMethod.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelRadiusMarchMethod.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelRadiusMarchMethod.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Marching/Shaders/VoxelRadiusMarchMethod.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttribute.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageSampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageSampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageSampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageShader.sdsl.cs deleted file mode 100644 index fd99cd8bbb..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeDirectionalCoverageShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelAttributeDirectionalCoverageShaderKeys - { - public static readonly ObjectParameterKey DirectOutput = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeEmissionOpacityShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeEmissionOpacityShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeEmissionOpacityShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSoliditySampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSoliditySampler.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSoliditySampler.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSolidityShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSolidityShader.sdsl.cs deleted file mode 100644 index 303dc19316..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Attributes/Shaders/VoxelAttributeSolidityShader.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelAttributeSolidityShaderKeys - { - public static readonly ObjectParameterKey DirectOutput = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteAssign.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteAssign.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteAssign.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteMax.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteMax.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriteMax.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriter.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriter.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/BufferWriters/Shaders/VoxelBufferWriter.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/DataPacking.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/DataPacking.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/DataPacking.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat16.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat16.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat16.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat32.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat32.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloat32.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloatR11G11B10.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloatR11G11B10.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPackFloatR11G11B10.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPacker.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPacker.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/FragmentPackers/Shaders/VoxelFragmentPacker.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedSampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedSampler.sdsl.cs deleted file mode 100644 index a8ebd378cb..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedSampler.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class VoxelAnisotropicPairedSamplerKeys - { - public static readonly ValueParameterKey maxBrightness = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedWriter_Float4.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedWriter_Float4.sdsl.cs deleted file mode 100644 index 60f04608c4..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicPairedWriter_Float4.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelAnisotropicPairedWriter_Float4Keys - { - public static readonly ObjectParameterKey DirectOutput = ParameterKeys.NewObject(); - public static readonly ValueParameterKey maxBrightnessInv = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicSampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicSampler.sdsl.cs deleted file mode 100644 index 549735674a..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicSampler.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class VoxelAnisotropicSamplerKeys - { - public static readonly ValueParameterKey maxBrightness = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicWriter_Float4.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicWriter_Float4.sdsl.cs deleted file mode 100644 index 7f11b97521..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelAnisotropicWriter_Float4.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelAnisotropicWriter_Float4Keys - { - public static readonly ObjectParameterKey DirectOutput = ParameterKeys.NewObject(); - public static readonly ValueParameterKey maxBrightnessInv = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicSampler.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicSampler.sdsl.cs deleted file mode 100644 index 079d349560..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicSampler.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class VoxelIsotropicSamplerKeys - { - public static readonly ValueParameterKey maxBrightness = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicWriter_Float4.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicWriter_Float4.sdsl.cs deleted file mode 100644 index efe5fd9dd0..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelIsotropicWriter_Float4.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelIsotropicWriter_Float4Keys - { - public static readonly ObjectParameterKey DirectOutput = ParameterKeys.NewObject(); - public static readonly ValueParameterKey maxBrightnessInv = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelLayout_Float4.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelLayout_Float4.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Layout/Shaders/VoxelLayout_Float4.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAnisotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAnisotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAnisotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAntiAliasingAnisotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAntiAliasingAnisotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierAntiAliasingAnisotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierOpacifyAnisotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierOpacifyAnisotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierOpacifyAnisotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierSolidifyAnisotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierSolidifyAnisotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Anisotropic/VoxelModifierApplierSolidifyAnisotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAnisotropicPaired.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAnisotropicPaired.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAnisotropicPaired.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/AnisotropicPaired/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierAntiAliasingIsotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierAntiAliasingIsotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierAntiAliasingIsotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierIsotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierIsotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierIsotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierOpacifyIsotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierOpacifyIsotropic.sdsl.cs deleted file mode 100644 index b590592143..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierOpacifyIsotropic.sdsl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelModifierApplierOpacifyIsotropicKeys - { - public static readonly ValueParameterKey Amount = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierSolidifyIsotropic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierSolidifyIsotropic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/Modifiers/Appliers/Isotropic/VoxelModifierApplierSolidifyIsotropic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelPositionStream.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelPositionStream.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelPositionStream.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/LocalSamples.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/LocalSamples.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/LocalSamples.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXN.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXN.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXN.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXP.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXP.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoXP.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYN.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYN.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYN.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYP.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYP.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoYP.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZN.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZN.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZN.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZP.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZP.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Anisotropic/Voxel2x2x2Mipmapper_AnisoZP.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmap.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmap.sdsl.cs deleted file mode 100644 index 4fa11c541f..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmap.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class Voxel2x2x2MipmapKeys - { - public static readonly ValueParameterKey ReadOffset = ParameterKeys.NewValue(); - public static readonly ValueParameterKey WriteOffset = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey ReadTex = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey WriteTex = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapEffect.sdsl.cs deleted file mode 100644 index 0948922416..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapEffect.sdsl.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class Voxel2x2x2MipmapEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "Voxel2x2x2Mipmap"); - if (context.GetParam(Voxel2x2x2MipmapKeys.mipmapper) != null) - { - - { - var __mixinToCompose__ = context.GetParam(Voxel2x2x2MipmapKeys.mipmapper); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "mipmapper", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("Voxel2x2x2MipmapEffect", new Voxel2x2x2MipmapEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmapper.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmapper.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2Mipmapper.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperHeuristic.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperHeuristic.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperHeuristic.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperPhysicallyBased.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperPhysicallyBased.sdsl.cs deleted file mode 100644 index a4e3ce20f9..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperPhysicallyBased.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperSimple.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperSimple.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Mipmapping/Voxel2x2x2MipmapperSimple.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTexture.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTexture.sdsl.cs deleted file mode 100644 index 88dd6bb5c5..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTexture.sdsl.cs +++ /dev/null @@ -1,26 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class BufferToTextureKeys - { - public static readonly ObjectParameterKey VoxelFragments = ParameterKeys.NewObject(); - public static readonly ValueParameterKey clipMapResolution = ParameterKeys.NewValue(); - public static readonly ValueParameterKey storageUints = ParameterKeys.NewValue(); - public static readonly ValueParameterKey clipOffset = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumns.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumns.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumns.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumnsEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumnsEffect.sdsl.cs deleted file mode 100644 index 6f28f13fcd..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureColumnsEffect.sdsl.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class BufferToTextureColumnsEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "BufferToTextureColumns"); - if (context.GetParam(BufferToTextureKeys.AttributesIndirect) != null) - { - foreach(var attr in context.GetParam(BufferToTextureKeys.AttributesIndirect)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributesIndirect", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - if (context.GetParam(BufferToTextureKeys.AttributesTemp) != null) - { - foreach(var attr in context.GetParam(BufferToTextureKeys.AttributesTemp)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributesTemp", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - mixin.AddMacro("IndirectReadAndStoreMacro", context.GetParam(BufferToTextureKeys.IndirectReadAndStoreMacro)); - mixin.AddMacro("IndirectStoreMacro", context.GetParam(BufferToTextureKeys.IndirectStoreMacro)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("BufferToTextureColumnsEffect", new BufferToTextureColumnsEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureEffect.sdsl.cs deleted file mode 100644 index db08d79c32..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/BufferToTextureEffect.sdsl.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class BufferToTextureEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "BufferToTexture"); - if (context.GetParam(BufferToTextureKeys.AttributesIndirect) != null) - { - foreach(var attr in context.GetParam(BufferToTextureKeys.AttributesIndirect)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributesIndirect", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - if (context.GetParam(BufferToTextureKeys.AttributesTemp) != null) - { - foreach(var attr in context.GetParam(BufferToTextureKeys.AttributesTemp)) - - { - - { - var __mixinToCompose__ = (attr); - var __subMixin = new ShaderMixinSource(); - context.PushCompositionArray(mixin, "AttributesTemp", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - } - mixin.AddMacro("IndirectReadAndStoreMacro", context.GetParam(BufferToTextureKeys.IndirectReadAndStoreMacro)); - mixin.AddMacro("IndirectStoreMacro", context.GetParam(BufferToTextureKeys.IndirectStoreMacro)); - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("BufferToTextureEffect", new BufferToTextureEffect()); - } - } - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/ClearBuffer.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/ClearBuffer.sdsl.cs deleted file mode 100644 index c21a57c45a..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Processing/ClearBuffer.sdsl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering.Voxels -{ - public static partial class ClearBufferKeys - { - public static readonly ObjectParameterKey buffer = ParameterKeys.NewObject(); - public static readonly ValueParameterKey offset = ParameterKeys.NewValue(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageClipmapShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageClipmapShader.sdsl.cs deleted file mode 100644 index 5efc926a59..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageClipmapShader.sdsl.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelStorageClipmapShaderKeys - { - public static readonly ValueParameterKey clipMapResolution = ParameterKeys.NewValue(); - public static readonly ValueParameterKey clipPos = ParameterKeys.NewValue(); - public static readonly ValueParameterKey clipScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey clipOffset = ParameterKeys.NewValue(); - public static readonly ValueParameterKey clipMapCount = ParameterKeys.NewValue(); - public static readonly ValueParameterKey perClipMapOffsetScale = ParameterKeys.NewValue(); - public static readonly ValueParameterKey storageUints = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey fragmentsBuffer = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureClipmapShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureClipmapShader.sdsl.cs deleted file mode 100644 index 061106bf7d..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureClipmapShader.sdsl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -namespace Stride.Rendering -{ - public static partial class VoxelStorageTextureClipmapShaderKeys - { - public static readonly ValueParameterKey perMapOffsetScale = ParameterKeys.NewValue(); - public static readonly ObjectParameterKey clipMaps = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey mipMaps = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearBorderSampler3D = ParameterKeys.NewObject(); - public static readonly ObjectParameterKey LinearBorderSampler3D_NearestMip = ParameterKeys.NewObject(); - } -} diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelStorage/Shaders/VoxelStorageTextureShader.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethod.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethod.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethod.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodDominantAxis.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodDominantAxis.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodDominantAxis.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodSingleAxis.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodSingleAxis.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizationMethod/Shader/VoxelizationMethodSingleAxis.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragments.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragments.sdsl.cs deleted file mode 100644 index c076333a9b..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragments.sdsl.cs +++ /dev/null @@ -1,9 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -// Nothing to generate diff --git a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragmentsEffect.sdsl.cs b/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragmentsEffect.sdsl.cs deleted file mode 100644 index 2fb4c168d6..0000000000 --- a/sources/engine/Stride.Voxels/Voxels/Voxelization/VoxelizeToFragmentsEffect.sdsl.cs +++ /dev/null @@ -1,54 +0,0 @@ -// -// Do not edit this file yourself! -// -// This code was generated by Stride Shader Mixin Code Generator. -// To generate it yourself, please install Stride.VisualStudio.Package .vsix -// and re-save the associated .sdfx. -// - -using System; -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; -using Stride.Shaders; -using Stride.Core.Mathematics; -using Buffer = Stride.Graphics.Buffer; - -using Stride.Rendering.Materials; -using Stride.Rendering.Voxels; -namespace Stride.Rendering.Voxels -{ - internal static partial class ShaderMixins - { - internal partial class VoxelizeToFragmentsEffect : IShaderMixinBuilder - { - public void Generate(ShaderMixinSource mixin, ShaderMixinContext context) - { - context.Mixin(mixin, "VoxelizeToFragments"); - if (context.GetParam(VoxelizeToFragmentsKeys.Storage) != null) - { - - { - var __mixinToCompose__ = (context.GetParam(VoxelizeToFragmentsKeys.Storage)); - var __subMixin = new ShaderMixinSource(); - context.PushComposition(mixin, "Storage", __subMixin); - context.Mixin(__subMixin, __mixinToCompose__); - context.PopComposition(); - } - } - if (context.GetParam(VoxelizeToFragmentsKeys.RequireGeometryShader) == true) - { - mixin.AddMacro("RequireGeometryShader", true); - mixin.AddMacro("GeometryShaderMaxVertexCount", context.GetParam(VoxelizeToFragmentsKeys.GeometryShaderMaxVertexCount)); - } - } - - [ModuleInitializer] - internal static void __Initialize__() - - { - ShaderMixinManager.Register("VoxelizeToFragmentsEffect", new VoxelizeToFragmentsEffect()); - } - } - } -} diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index e3cfd9fdd2..6517931e39 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -74,8 +74,6 @@ - - diff --git a/sources/targets/Stride.targets b/sources/targets/Stride.targets index 1a8b90a44e..cf8398b9d3 100644 --- a/sources/targets/Stride.targets +++ b/sources/targets/Stride.targets @@ -57,8 +57,6 @@ - - From 20e37fb258c5920c0a9bf94fc205ca0237ec8895 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 23:48:34 +0900 Subject: [PATCH 0819/1182] Editor: use new Shader system for ComputeColor in Material --- .../Stride.Assets.Presentation.csproj | 3 +++ .../ViewModel/MaterialViewModel.cs | 26 +++++++++---------- .../Materials/ComputeShaderClassHelper.cs | 24 ++++++++--------- .../engine/Stride.Assets/Stride.Assets.csproj | 3 +++ 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj index 12f9e3a69e..cc42937383 100644 --- a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj +++ b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj @@ -70,6 +70,9 @@ + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + diff --git a/sources/editor/Stride.Assets.Presentation/ViewModel/MaterialViewModel.cs b/sources/editor/Stride.Assets.Presentation/ViewModel/MaterialViewModel.cs index de11c3e89a..1624e4ba79 100644 --- a/sources/editor/Stride.Assets.Presentation/ViewModel/MaterialViewModel.cs +++ b/sources/editor/Stride.Assets.Presentation/ViewModel/MaterialViewModel.cs @@ -10,10 +10,9 @@ using Stride.Core.Assets.Editor.ViewModel; using Stride.Core.Extensions; using Stride.Core.Quantum; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Stride; using Stride.Rendering.Materials; using Stride.Rendering.Materials.ComputeColors; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Assets.Presentation.ViewModel { @@ -93,27 +92,27 @@ private void UpdateNode(ComputeShaderClassBase node, IObjectNode ownerNode UpdateCompositionNodes(shader, node, ownerNode); } - private void UpdateGenerics(ShaderClassType shader, ComputeShaderClassBase node, IObjectNode ownerNode) + private void UpdateGenerics(ShaderClass shader, ComputeShaderClassBase node, IObjectNode ownerNode) where T : class, IComputeNode { var genericsNode = ownerNode[nameof(ComputeShaderClassBase.Generics)].Target; var keysToRemove = new List(node.Generics.Keys); - if (shader != null) + if (shader != null && shader.Generics != null) { - foreach (var generic in shader.ShaderGenerics) + foreach (var generic in shader.Generics.Parameters) { - var parameterType = ComputeShaderClassHelper.GetComputeColorParameterType(generic.Type.Name.Text); + var parameterType = ComputeShaderClassHelper.GetComputeColorParameterType(generic.TypeName.Name); if (parameterType == null) continue; - var index = new NodeIndex(generic.Name.Text); + var index = new NodeIndex(generic.Name.Name); if (genericsNode.Indices.Any(x => Equals(x, index))) { var value = genericsNode.Retrieve(index); if (parameterType.IsInstanceOfType(value)) { // This generic already exists and has the correct type, keep it in the list - keysToRemove.Remove(generic.Name); + keysToRemove.Remove(generic.Name.Name); } else { @@ -139,24 +138,23 @@ private void UpdateGenerics(ShaderClassType shader, ComputeShaderClassBase } } - private void UpdateCompositionNodes(ShaderClassType shader, ComputeShaderClassBase node, IObjectNode ownerNode) + private void UpdateCompositionNodes(ShaderClass shader, ComputeShaderClassBase node, IObjectNode ownerNode) where T : class, IComputeNode { var keysToRemove = new List(node.CompositionNodes.Keys); var compositionNodesNode = ownerNode[nameof(ComputeShaderClassBase.CompositionNodes)].Target; if (shader != null) { - // TODO: is it enough detect compositions? - foreach (var member in shader.Members.OfType().Where(x => x.Type is TypeName && x.Type.TypeInference?.TargetType == null)) + foreach (var member in shader.Elements.OfType().Where(x => x.IsCompose)) { // ComputeColor only - if (member.Type.Name.Text == "ComputeColor") + if (member.TypeName.Name == "ComputeColor") { - var index = new NodeIndex(member.Name.Text); + var index = new NodeIndex(member.Name.Name); if (compositionNodesNode.Indices.Any(x => Equals(x, index))) { // This composition node already exists, keep it in the list - keysToRemove.Remove(member.Name.Text); + keysToRemove.Remove(member.Name.Name); } else { diff --git a/sources/engine/Stride.Assets/Materials/ComputeShaderClassHelper.cs b/sources/engine/Stride.Assets/Materials/ComputeShaderClassHelper.cs index e9eb5640cf..74514ea2f8 100644 --- a/sources/engine/Stride.Assets/Materials/ComputeShaderClassHelper.cs +++ b/sources/engine/Stride.Assets/Materials/ComputeShaderClassHelper.cs @@ -3,11 +3,12 @@ using System; using System.Collections.Generic; +using System.Linq; using Stride.Rendering.Materials; using Stride.Rendering.Materials.ComputeColors; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Mixins; -using Stride.Core.Shaders.Utility; +using Stride.Shaders.Core; +using Stride.Shaders.Parsing; +using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Assets.Materials { @@ -32,22 +33,21 @@ public static Type GetComputeColorParameterType(string typeName) return type; } - public static ShaderClassType ParseReferencedShader(this ComputeShaderClassBase node, IDictionary projectShaders) + public static ShaderClass ParseReferencedShader(this ComputeShaderClassBase node, IDictionary projectShaders) where T : class, IComputeNode { - ShaderClassType shader = null; - string source; if (projectShaders.TryGetValue(node.MixinReference, out source)) { - var logger = new LoggerResult(); try { - shader = ShaderLoader.ParseSource(source, logger); - if (logger.HasErrors) - { + var parsed = SDSLParser.Parse(source); + if (parsed.Errors.Count > 0) + return null; + if (parsed.AST is not ShaderFile sf) return null; - } + + return sf.RootDeclarations.Concat(sf.Namespaces.SelectMany(x => x.Declarations)).OfType().SingleOrDefault(); } catch { @@ -56,7 +56,7 @@ public static ShaderClassType ParseReferencedShader(this ComputeShaderClassBa } } - return shader; + return null; } } } diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index 010a176fd2..7499c4376b 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -35,6 +35,9 @@ + + ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + From 74399a357a1aee45a5db7603f06ecb9c4473381a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Feb 2026 20:06:07 +0900 Subject: [PATCH 0820/1182] Shader: removed old ShaderMixer and HLSL to GLSL system --- build/Stride.sln | 43 +- .../AssetEditors/Gizmos/PhysicsGizmo.cs | 1 - .../ProjectTemplateGeneratorHelper.cs | 17 - .../Stride.Shaders.Compiler/EffectCompiler.cs | 107 +- .../OpenGL/ShaderCompiler.cs | 481 -- .../OpenGL/ShaderConverter.cs | 158 - .../ShaderSourceManager.cs | 2 +- .../Stride.Shaders.Compiler.csproj | 4 +- .../Analysis/AssignmentOperatorStatus.cs | 15 - .../Analysis/ExpressionNodeCouple.cs | 23 - .../MemberReferenceExpressionNodeCouple.cs | 20 - .../Analysis/StatementNodeCouple.cs | 23 - .../Analysis/StrideParsingInfo.cs | 94 - .../Analysis/StrideSemanticAnalysis.cs | 1178 ---- .../Analysis/StrideTypeAnalysis.cs | 26 - .../Mixins/CompositionDictionary.cs | 186 - .../Mixins/ExpressionSimplifierVisitor.cs | 50 - .../Mixins/MethodDeclarationShaderCouple.cs | 24 - .../Mixins/MixinVirtualTable.cs | 116 - .../Mixins/ModuleMixin.cs | 287 - .../Mixins/ModuleMixinInfo.cs | 171 - .../Mixins/ReferencesPool.cs | 102 - .../Mixins/ShaderCompilationContext.cs | 557 -- .../Mixins/ShaderDependencyVisitor.cs | 86 - .../Mixins/ShaderKeyFileHelper.cs | 63 - .../Mixins/ShaderKeyGeneratorBase.cs | 336 -- .../Mixins/ShaderLoader.cs | 472 -- .../Mixins/ShaderMixinCodeGen.cs | 856 --- .../Mixins/ShaderVirtualTable.cs | 189 - .../Mixins/StreamFieldVisitor.cs | 62 - .../Mixins/StreamOutputParser.cs | 107 - .../Mixins/StrideAssignmentCloner.cs | 139 - .../Mixins/StrideClassInstantiator.cs | 206 - .../Mixins/StrideReplaceAppend.cs | 73 - .../Mixins/StrideReplaceExtern.cs | 58 - .../Mixins/StrideReplaceVisitor.cs | 68 - .../Mixins/StrideShaderLibrary.cs | 457 -- .../Mixins/StrideShaderMixer.cs | 1683 ------ .../Mixins/StrideStreamAnalyzer.cs | 303 -- .../Mixins/StrideStreamCreator.cs | 1263 ----- .../Mixins/StrideTagCleaner.cs | 36 - .../Mixins/StrideTypeCleaner.cs | 35 - .../Mixins/StrideVariableUsageVisitor.cs | 50 - .../Mixins/VariableShaderCouple.cs | 24 - .../engine/Stride.Shaders.Parser/Parser.cs | 182 - .../Performance/GenerateShaderPerformance.cs | 92 - .../Performance/MixPerformance.cs | 182 - .../Performance/PerformanceLogger.cs | 205 - .../Performance/SemanticPerformance.cs | 168 - .../Performance/StreamCreatorPerformance.cs | 207 - .../Properties/AssemblyInfo.cs | 11 - .../Stride.Shaders.Parser/ShaderExtensions.cs | 104 - .../Stride.Shaders.Parser/ShaderLinker.cs | 1057 ---- .../ShaderMixinParser.cs | 487 -- .../ShaderMixinParsingResult.cs | 24 - .../Stride.Shaders.Parser/ShaderNavigation.cs | 190 - .../ShaderNavigationResult.cs | 30 - .../Stride.Shaders.Parser.csproj | 28 - .../StrideShaderCleaner.cs | 56 - .../Utility/StrideMessageCode.cs | 114 - .../BenchmarkShaderSystems.cs | 7 - .../Stride.Shaders.Tests/TestMixinMacros.cs | 139 - .../Irony.GrammarExplorer/GrammarItemList.cs | 124 - .../Irony.GrammarExplorer/GrammarLoader.cs | 215 - .../Highlighter/AboutCodeHighlighter.txt | 1 - .../Highlighter/EditorAdapter.cs | 168 - .../Highlighter/EditorViewAdapter.cs | 261 - .../Highlighter/RichTextBoxHighlighter.cs | 271 - .../Irony.GrammarExplorer.csproj | 66 - .../shaders/Irony.GrammarExplorer/Program.cs | 57 - .../Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 63 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 110 - .../Properties/Settings.settings | 27 - .../shaders/Irony.GrammarExplorer/app.config | 34 - .../fmGrammarExplorer.Designer.cs | 1347 ----- .../fmGrammarExplorer.cs | 661 --- .../fmGrammarExplorer.resx | 162 - .../fmSelectGrammars.Designer.cs | 129 - .../Irony.GrammarExplorer/fmSelectGrammars.cs | 111 - .../fmSelectGrammars.resx | 120 - .../fmShowException.Designer.cs | 63 - .../Irony.GrammarExplorer/fmShowException.cs | 37 - .../fmShowException.resx | 120 - sources/shaders/Irony/Common/StringUtils.cs | 77 - .../Interpreter/Ast/Base/AstException.cs | 26 - .../Interpreter/Ast/Base/AstInterfaces.cs | 47 - .../Irony/Interpreter/Ast/Base/AstNode.cs | 164 - .../Ast/Expressions/BinaryOperationNode.cs | 46 - .../Ast/Expressions/ExpressionListNode.cs | 45 - .../Interpreter/Ast/Expressions/IncDecNode.cs | 62 - .../Ast/Expressions/UnaryOperationNode.cs | 65 - .../Ast/Functions/FunctionCallNode.cs | 47 - .../Ast/Functions/FunctionDefNode.cs | 56 - .../Ast/Functions/ParamListNode.cs | 48 - .../Ast/PrimitiveNodes/IdentifierNode.cs | 51 - .../Ast/PrimitiveNodes/LiteralValueNode.cs | 32 - .../Ast/PrimitiveNodes/StringTemplateNode.cs | 143 - .../Ast/SpecialNodes/EmptyStatementNode.cs | 14 - .../Ast/SpecialNodes/NotSupportedNode.cs | 24 - .../Interpreter/Ast/SpecialNodes/NullNode.cs | 21 - .../Ast/Statements/AssignmentNode.cs | 62 - .../Interpreter/Ast/Statements/BlockNode.cs | 31 - .../Interpreter/Ast/Statements/IfNode.cs | 46 - .../Ast/Statements/StatementListNode.cs | 49 - .../shaders/Irony/Interpreter/CommandLine.cs | 184 - .../shaders/Irony/Interpreter/DataStack.cs | 70 - .../Interpreter/DynamicCallDispatcher.cs | 240 - .../Irony/Interpreter/EvaluationContext.cs | 114 - .../Irony/Interpreter/LanguageRuntime.cs | 256 - .../Irony/Interpreter/LanguageRuntime_Init.cs | 350 -- .../Irony/Interpreter/RuntimeException.cs | 29 - .../Irony/Interpreter/ScriptInterpreter.cs | 242 - .../shaders/Irony/Interpreter/StackFrame.cs | 44 - .../shaders/Irony/Interpreter/ValuesTable.cs | 13 - sources/shaders/Irony/Irony.csproj | 77 - sources/shaders/Irony/MS-PubLicense.Rtf | 177 - .../shaders/Irony/Parsing/AstInterfaces.cs | 40 - .../Data/Construction/GrammarDataBuilder.cs | 315 -- .../Data/Construction/LanguageDataBuilder.cs | 64 - .../Data/Construction/ParserDataBuilder.cs | 462 -- .../ParserDataBuilder_HelperClasses.cs | 275 - .../_about_parser_construction.txt | 44 - .../shaders/Irony/Parsing/Data/GrammarData.cs | 76 - .../Irony/Parsing/Data/LanguageData.cs | 104 - .../shaders/Irony/Parsing/Data/ParserData.cs | 196 - .../Diagnostics/ParseTreeExtensions.cs | 64 - .../Parsing/Diagnostics/ParserDataPrinter.cs | 93 - .../Parsing/Diagnostics/ParserMessage.cs | 50 - .../Irony/Parsing/Diagnostics/ParserTrace.cs | 51 - .../Irony/Parsing/Grammar/BnfExpression.cs | 73 - .../shaders/Irony/Parsing/Grammar/BnfTerm.cs | 256 - .../shaders/Irony/Parsing/Grammar/Grammar.cs | 497 -- .../Irony/Parsing/Grammar/GrammarError.cs | 70 - .../Irony/Parsing/Grammar/GrammarHint.cs | 156 - .../Parsing/Grammar/LanguageAttribute.cs | 49 - .../Irony/Parsing/Grammar/NonTerminal.cs | 154 - .../Irony/Parsing/Grammar/TermReportGroups.cs | 50 - .../Irony/Parsing/Parser/CoreParser.cs | 384 -- .../Parser/CoreParser_ErrorHandling.cs | 286 - .../shaders/Irony/Parsing/Parser/ParseTree.cs | 151 - .../shaders/Irony/Parsing/Parser/Parser.cs | 220 - .../Irony/Parsing/Parser/ParserStack.cs | 47 - .../Irony/Parsing/Parser/ParsingContext.cs | 245 - .../Irony/Parsing/Parser/ParsingEventArgs.cs | 13 - .../Irony/Parsing/Parser/SyntaxError.cs | 42 - .../Irony/Parsing/Scanner/DefaultScanner.cs | 271 - .../shaders/Irony/Parsing/Scanner/Scanner.cs | 241 - .../Irony/Parsing/Scanner/SourceLocation.cs | 77 - .../Irony/Parsing/Scanner/SourceStream.cs | 192 - .../shaders/Irony/Parsing/Scanner/Token.cs | 280 - .../Irony/Parsing/Scanner/TokenEditorInfo.cs | 108 - sources/shaders/Irony/Parsing/SymbolTable.cs | 100 - .../Parsing/Terminals/CommentTerminal.cs | 119 - .../Parsing/Terminals/CompoundTerminalBase.cs | 255 - .../Parsing/Terminals/ConstantTerminal.cs | 61 - .../Irony/Parsing/Terminals/CustomTerminal.cs | 45 - .../Parsing/Terminals/DataLiteralBase.cs | 58 - .../Irony/Parsing/Terminals/DsvLiteral.cs | 105 - .../Parsing/Terminals/FixedLengthLiteral.cs | 39 - .../Parsing/Terminals/FreeTextLiteral.cs | 111 - .../Parsing/Terminals/IdentifierTerminal.cs | 281 - .../Terminals/ImpliedSymbolTerminal.cs | 37 - .../Irony/Parsing/Terminals/KeyTerm.cs | 114 - .../Terminals/LineContinuationTerminal.cs | 117 - .../Parsing/Terminals/NewLineTerminal.cs | 58 - .../Parsing/Terminals/QuotedValueLiteral.cs | 33 - .../Parsing/Terminals/RegExBasedTerminal.cs | 72 - .../Irony/Parsing/Terminals/RegExLiteral.cs | 142 - .../Irony/Parsing/Terminals/StringLiteral.cs | 401 -- .../WikiTerminals/WikiBlockTerminal.cs | 44 - .../WikiTerminals/WikiTagTerminal.cs | 36 - .../WikiTerminals/WikiTextTerminal.cs | 54 - .../WikiTerminals/_WikiTerminalBase.cs | 52 - .../Irony/Parsing/Terminals/_ISourceStream.cs | 91 - .../Irony/Parsing/Terminals/_Terminal.cs | 140 - .../Parsing/TokenFilters/CodeOutlineFilter.cs | 200 - .../Irony/Parsing/TokenFilters/TokenFilter.cs | 55 - .../shaders/Irony/Properties/AssemblyInfo.cs | 42 - sources/shaders/Irony/Resources.Designer.cs | 1027 ---- sources/shaders/Irony/Resources.resx | 442 -- .../ShaderES/UnrollBreak.hlsl | 63 - .../ShaderES/UnrollTest.hlsl | 75 - .../Stride.Core.Shaders.Tests/TestOpenGLES.cs | 56 - .../Analysis/AnalysisBase.cs | 170 - .../Analysis/CastAnalysis.cs | 232 - .../Analysis/CastHelper.cs | 232 - .../Analysis/Hlsl/HlslDeclarations.h | 670 --- .../Analysis/Hlsl/HlslSemanticAnalysis.cs | 1027 ---- .../Analysis/SemanticAnalysis.cs | 853 --- .../Ast/ArrayInitializerExpression.cs | 42 - .../Stride.Core.Shaders/Ast/ArrayType.cs | 134 - .../Ast/AssignmentExpression.cs | 81 - .../Ast/AssignmentOperator.cs | 189 - .../Stride.Core.Shaders/Ast/AttributeBase.cs | 20 - .../Ast/BinaryExpression.cs | 81 - .../Stride.Core.Shaders/Ast/BinaryOperator.cs | 278 - .../Stride.Core.Shaders/Ast/BlockStatement.cs | 63 - .../Stride.Core.Shaders/Ast/CaseStatement.cs | 73 - .../Stride.Core.Shaders/Ast/CompositeEnum.cs | 422 -- .../Ast/ConditionalExpression.cs | 82 - .../Ast/DeclarationStatement.cs | 66 - .../Ast/EmptyExpression.cs | 16 - .../Stride.Core.Shaders/Ast/EmptyStatement.cs | 30 - .../Stride.Core.Shaders/Ast/Expression.cs | 64 - .../Stride.Core.Shaders/Ast/ExpressionList.cs | 193 - .../Ast/ExpressionStatement.cs | 66 - .../Stride.Core.Shaders/Ast/ForStatement.cs | 101 - .../Ast/GenericBaseType.cs | 206 - .../Ast/GenericDeclaration.cs | 93 - .../Ast/GenericParameterConstraint.cs | 52 - .../Ast/GenericParameterType.cs | 39 - .../Stride.Core.Shaders/Ast/GenericType.cs | 30 - .../Ast/Glsl/InterfaceType.cs | 19 - .../Ast/Glsl/LayoutKeyValue.cs | 79 - .../Ast/Glsl/LayoutQualifier.cs | 76 - .../Ast/Glsl/ParameterQualifier.cs | 42 - .../Ast/Glsl/StorageQualifier.cs | 68 - .../Ast/Hlsl/Annotations.cs | 30 - .../Ast/Hlsl/AsmExpression.cs | 29 - .../Ast/Hlsl/AttributeDeclaration.cs | 62 - .../Ast/Hlsl/ByteAddressBufferType.cs | 39 - .../Ast/Hlsl/CastExpression.cs | 53 - .../Ast/Hlsl/ClassType.Helpers.cs | 20 - .../Stride.Core.Shaders/Ast/Hlsl/ClassType.cs | 158 - .../Ast/Hlsl/CompileExpression.cs | 79 - .../Ast/Hlsl/CompositeIdentifier.cs | 94 - .../Ast/Hlsl/ConstantBuffer.cs | 102 - .../Ast/Hlsl/ConstantBufferType.cs | 67 - .../Ast/Hlsl/FloatQualifier.cs | 49 - .../Ast/Hlsl/GenericType.Extensions.cs | 59 - .../Ast/Hlsl/IdentifierDot.cs | 21 - .../Ast/Hlsl/IdentifierGeneric.cs | 42 - .../Ast/Hlsl/IdentifierNs.cs | 21 - .../Ast/Hlsl/InterfaceType.cs | 129 - .../Ast/Hlsl/InterpolationQualifier.cs | 88 - .../Ast/Hlsl/PackOffset.cs | 176 - .../Ast/Hlsl/ParameterQualifier.cs | 64 - .../Stride.Core.Shaders/Ast/Hlsl/Pass.cs | 78 - .../Ast/Hlsl/RegisterLocation.cs | 189 - .../Ast/Hlsl/SamplerType.cs | 62 - .../Stride.Core.Shaders/Ast/Hlsl/Semantic.cs | 191 - .../Ast/Hlsl/StateExpression.cs | 79 - .../Ast/Hlsl/StateInitializer.cs | 54 - .../Stride.Core.Shaders/Ast/Hlsl/StateType.cs | 83 - .../Ast/Hlsl/StorageQualifier.cs | 103 - .../Ast/Hlsl/StreamTypeName.cs | 49 - .../Stride.Core.Shaders/Ast/Hlsl/Technique.cs | 83 - .../Ast/Hlsl/TextureType.cs | 139 - .../Stride.Core.Shaders/Ast/Hlsl/Typedef.cs | 116 - .../Stride.Core.Shaders/Ast/IAttributes.cs | 11 - .../Stride.Core.Shaders/Ast/IDeclaration.cs | 18 - .../Stride.Core.Shaders/Ast/IGenerics.cs | 23 - .../Stride.Core.Shaders/Ast/IQualifiers.cs | 18 - .../Ast/IScopeContainer.cs | 11 - .../Ast/ITypeInferencer.cs | 18 - .../Stride.Core.Shaders/Ast/Identifier.cs | 211 - .../Stride.Core.Shaders/Ast/IfStatement.cs | 62 - .../Ast/IndexerExpression.cs | 79 - .../Ast/IronyBrowsableNode.cs | 60 - .../Ast/KeywordExpression.cs | 66 - .../Stride.Core.Shaders/Ast/Literal.cs | 194 - .../Ast/LiteralExpression.cs | 154 - .../Stride.Core.Shaders/Ast/MatrixType.cs | 204 - .../Ast/MemberReferenceExpression.cs | 87 - .../Ast/MethodDeclaration.cs | 246 - .../Ast/MethodDefinition.cs | 75 - .../Ast/MethodInvocationExpression.cs | 80 - .../Ast/Node.Clone.Extension.cs | 125 - .../Ast/Node.Extensions.cs | 56 - .../shaders/Stride.Core.Shaders/Ast/Node.cs | 152 - .../Ast/NodeProcessorContext.cs | 49 - .../Stride.Core.Shaders/Ast/ObjectType.cs | 104 - .../Stride.Core.Shaders/Ast/Parameter.cs | 55 - .../Ast/ParameterQualifier.cs | 63 - .../Ast/ParenthesizedExpression.cs | 66 - .../Stride.Core.Shaders/Ast/Qualifier.cs | 83 - .../Ast/ReturnStatement.cs | 63 - .../Stride.Core.Shaders/Ast/ScalarType.cs | 213 - .../shaders/Stride.Core.Shaders/Ast/Shader.cs | 48 - .../Stride.Core.Shaders/Ast/SourceLocation.cs | 83 - .../Stride.Core.Shaders/Ast/SourceSpan.cs | 53 - .../Stride.Core.Shaders/Ast/Statement.cs | 29 - .../Stride.Core.Shaders/Ast/StatementList.cs | 191 - .../Ast/StorageQualifier.cs | 57 - .../Ast/Stride/ClassIdentifierGeneric.cs | 95 - .../Ast/Stride/EffectBlock.cs | 49 - .../Ast/Stride/EnumType.cs | 93 - .../Ast/Stride/ForEachStatement.cs | 84 - .../Ast/Stride/IGenericStringArgument.cs | 11 - .../Ast/Stride/ImportBlockStatement.cs | 11 - .../Ast/Stride/LinkType.cs | 20 - .../Ast/Stride/LiteralIdentifier.cs | 22 - .../Ast/Stride/MemberName.cs | 20 - .../Ast/Stride/MixinStatement.cs | 70 - .../Ast/Stride/MixinStatementType.cs | 40 - .../Ast/Stride/NamespaceBlock.cs | 57 - .../Ast/Stride/ParametersBlock.cs | 63 - .../Ast/Stride/SemanticType.cs | 19 - .../Ast/Stride/ShaderClassType.cs | 46 - .../Ast/Stride/ShaderRootClassType.cs | 26 - .../Ast/Stride/ShaderTypeName.cs | 36 - .../Ast/Stride/StreamsType.cs | 88 - .../Ast/Stride/StrideAttributes.cs | 11 - .../Ast/Stride/StrideConstantBufferType.cs | 49 - .../Ast/Stride/StrideStorageQualifier.cs | 101 - .../Ast/Stride/StrideTags.cs | 32 - .../Ast/Stride/TypelIdentifier.cs | 21 - .../Ast/Stride/UsingParametersStatement.cs | 45 - .../Ast/Stride/UsingStatement.cs | 45 - .../Stride.Core.Shaders/Ast/Stride/VarType.cs | 22 - .../Stride.Core.Shaders/Ast/StructType.cs | 93 - .../Ast/SwitchCaseGroup.cs | 63 - .../Ast/SwitchStatement.cs | 61 - .../Stride.Core.Shaders/Ast/TypeBase.cs | 274 - .../Stride.Core.Shaders/Ast/TypeInference.cs | 44 - .../Stride.Core.Shaders/Ast/TypeName.cs | 37 - .../Ast/TypeReferenceExpression.cs | 59 - .../Ast/UnaryExpression.cs | 64 - .../Stride.Core.Shaders/Ast/UnaryOperator.cs | 122 - .../Stride.Core.Shaders/Ast/Variable.cs | 169 - .../Ast/VariableReferenceExpression.cs | 91 - .../Stride.Core.Shaders/Ast/VectorType.cs | 232 - .../Ast/VisitorIgnoreAttribute.cs | 15 - .../Stride.Core.Shaders/Ast/WhileStatement.cs | 66 - .../Convertor/Ast.Extensions.cs | 33 - .../Convertor/BreakContinueVisitor.cs | 144 - .../Convertor/CallstackVisitor.cs | 46 - .../Convertor/ConstantBufferLayoutRule.cs | 32 - .../Convertor/GlobalUniformVisitor.cs | 218 - .../Convertor/GlslKeywords.cs | 90 - .../Convertor/GlslShaderPlatform.cs | 22 - .../Convertor/HlslToGlslConvertor.cs | 4768 ----------------- .../Convertor/HlslToGlslWriter.cs | 332 -- .../Convertor/HlslTypes.cs | 71 - .../Convertor/Keywords.glsl | 70 - .../Stride.Core.Shaders/Convertor/MapRule.cs | 32 - .../Convertor/PipelineStage.cs | 50 - .../Convertor/SamplerMappingVisitor.cs | 649 --- .../Convertor/SamplerTextureKey.cs | 43 - .../Convertor/ShaderModel.cs | 111 - .../Convertor/VariableLayoutRule.cs | 48 - .../GoldParser/DfaState.cs | 64 - .../GoldParser/GoldParserException.cs | 26 - .../Stride.Core.Shaders/GoldParser/Grammar.cs | 611 --- .../GoldParser/LRAction.cs | 59 - .../Stride.Core.Shaders/GoldParser/LRState.cs | 82 - .../GoldParser/LRStateAction.cs | 81 - .../GoldParser/License.txt | 22 - .../GoldParser/ObjectMap.cs | 446 -- .../GoldParser/ParseMessage.cs | 106 - .../Stride.Core.Shaders/GoldParser/Parser.cs | 687 --- .../Stride.Core.Shaders/GoldParser/Rule.cs | 130 - .../Stride.Core.Shaders/GoldParser/SR.cs | 99 - .../GoldParser/SourceLineReadCallback.cs | 29 - .../Stride.Core.Shaders/GoldParser/Symbol.cs | 140 - .../GoldParser/SymbolType.cs | 79 - .../Grammar/BnfTermExtensions.Helpers.cs | 48 - .../Grammar/CustomScanner.cs | 54 - .../Grammar/DynamicKeyTerm.cs | 16 - .../Grammar/Hlsl/HlslGrammar.Ast.cs | 908 ---- .../Grammar/Hlsl/HlslGrammar.Helpers.cs | 49 - .../Grammar/Hlsl/HlslGrammar.cs | 581 -- .../Grammar/IdentifierResolverHint.cs | 171 - .../Grammar/NamedBlockKeyTerm.cs | 57 - .../Grammar/ShaderGrammar.Ast.cs | 1255 ----- .../Grammar/ShaderGrammar.Helpers.cs | 167 - .../Grammar/ShaderGrammar.cs | 661 --- .../Grammar/ShaderLanguageData.cs | 83 - .../Grammar/Stride/StrideGrammar.Ast.cs | 311 -- .../Grammar/Stride/StrideGrammar.cs | 161 - .../Grammar/TokenCategory.cs | 19 - .../Stride.Core.Shaders/Grammar/TokenInfo.cs | 43 - .../Stride.Core.Shaders/Grammar/TokenType.cs | 81 - .../Stride.Core.Shaders/Grammar/Tokenizer.cgt | Bin 51255 -> 0 bytes .../Stride.Core.Shaders/Grammar/Tokenizer.cs | 168 - .../Stride.Core.Shaders/Grammar/Tokenizer.grm | 162 - .../Parser/Hlsl/HlslParser.cs | 60 - .../Parser/ParsingResult.cs | 45 - .../Parser/PreProcessor.cs | 103 - .../Stride.Core.Shaders/Parser/ShaderMacro.cs | 80 - .../Parser/ShaderParser.cs | 248 - .../Properties/AssemblyInfo.cs | 9 - .../Properties/Resources.cs | 1385 ----- .../Properties/Resources.resx | 130 - .../Properties/Resources.tt | 338 -- sources/shaders/Stride.Core.Shaders/README.md | 66 - .../Stride.Core.Shaders.csproj | 75 - .../Utility/Hlsl/MessageCode.Hlsl.cs | 11 - .../Utility/LoggerResult.cs | 175 - .../Utility/MessageCode.cs | 53 - .../Utility/OrderedHashSet.cs | 333 -- .../Utility/ReferenceEqualityComparer.cs | 41 - .../Utility/ReportMessage.cs | 72 - .../Utility/ReportMessageLevel.cs | 25 - .../Utility/SpanConverter.cs | 25 - .../Visitor/ExpressionEvaluator.cs | 269 - .../Visitor/ExpressionResult.cs | 20 - .../Visitor/ScopeDeclaration.cs | 163 - .../Visitor/SearchVisitor.cs | 60 - .../Visitor/ShaderVisitor.cs | 88 - .../Visitor/StripVisitor.cs | 254 - .../Visitor/VisitorBase.cs | 249 - .../Visitor/VisitorGenerated.cs | 4655 ---------------- .../Visitor/VisitorGenerated.tt | 298 -- .../Writer/Hlsl/HlslWriter.cs | 421 -- .../Writer/ShaderWriter.cs | 1046 ---- .../tests/xunit/LauncherSimple.Desktop.cs | 4 +- .../Stride.VisualStudio.Commands.csproj | 1 - .../StrideCommands.cs | 2 +- 411 files changed, 27 insertions(+), 70369 deletions(-) delete mode 100644 sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs delete mode 100644 sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderConverter.cs rename sources/engine/{Stride.Shaders.Parser/Mixins => Stride.Shaders.Compiler}/ShaderSourceManager.cs (99%) delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/AssignmentOperatorStatus.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/ExpressionNodeCouple.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/MemberReferenceExpressionNodeCouple.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/StatementNodeCouple.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/StrideParsingInfo.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/StrideSemanticAnalysis.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Analysis/StrideTypeAnalysis.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/CompositionDictionary.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ExpressionSimplifierVisitor.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/MethodDeclarationShaderCouple.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/MixinVirtualTable.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixin.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixinInfo.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ReferencesPool.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderCompilationContext.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderDependencyVisitor.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyFileHelper.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyGeneratorBase.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderLoader.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderMixinCodeGen.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/ShaderVirtualTable.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StreamFieldVisitor.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StreamOutputParser.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideAssignmentCloner.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideClassInstantiator.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceAppend.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceExtern.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceVisitor.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderLibrary.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderMixer.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamAnalyzer.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamCreator.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideTagCleaner.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideTypeCleaner.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/StrideVariableUsageVisitor.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Mixins/VariableShaderCouple.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Parser.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Performance/GenerateShaderPerformance.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Performance/MixPerformance.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Performance/PerformanceLogger.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Performance/SemanticPerformance.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Performance/StreamCreatorPerformance.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Properties/AssemblyInfo.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderExtensions.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderLinker.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderMixinParser.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderMixinParsingResult.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderNavigation.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/ShaderNavigationResult.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Stride.Shaders.Parser.csproj delete mode 100644 sources/engine/Stride.Shaders.Parser/StrideShaderCleaner.cs delete mode 100644 sources/engine/Stride.Shaders.Parser/Utility/StrideMessageCode.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestMixinMacros.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/GrammarItemList.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/GrammarLoader.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Highlighter/AboutCodeHighlighter.txt delete mode 100644 sources/shaders/Irony.GrammarExplorer/Highlighter/EditorAdapter.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Highlighter/EditorViewAdapter.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Highlighter/RichTextBoxHighlighter.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Irony.GrammarExplorer.csproj delete mode 100644 sources/shaders/Irony.GrammarExplorer/Program.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Properties/AssemblyInfo.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Properties/Resources.Designer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Properties/Resources.resx delete mode 100644 sources/shaders/Irony.GrammarExplorer/Properties/Settings.Designer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/Properties/Settings.settings delete mode 100644 sources/shaders/Irony.GrammarExplorer/app.config delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.Designer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.resx delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.Designer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.resx delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmShowException.Designer.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmShowException.cs delete mode 100644 sources/shaders/Irony.GrammarExplorer/fmShowException.resx delete mode 100644 sources/shaders/Irony/Common/StringUtils.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Base/AstException.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Base/AstInterfaces.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Base/AstNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Expressions/BinaryOperationNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Expressions/ExpressionListNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Expressions/IncDecNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Expressions/UnaryOperationNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Functions/FunctionCallNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Functions/FunctionDefNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Functions/ParamListNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/IdentifierNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/LiteralValueNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/StringTemplateNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/SpecialNodes/EmptyStatementNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NotSupportedNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NullNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Statements/AssignmentNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Statements/BlockNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Statements/IfNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/Ast/Statements/StatementListNode.cs delete mode 100644 sources/shaders/Irony/Interpreter/CommandLine.cs delete mode 100644 sources/shaders/Irony/Interpreter/DataStack.cs delete mode 100644 sources/shaders/Irony/Interpreter/DynamicCallDispatcher.cs delete mode 100644 sources/shaders/Irony/Interpreter/EvaluationContext.cs delete mode 100644 sources/shaders/Irony/Interpreter/LanguageRuntime.cs delete mode 100644 sources/shaders/Irony/Interpreter/LanguageRuntime_Init.cs delete mode 100644 sources/shaders/Irony/Interpreter/RuntimeException.cs delete mode 100644 sources/shaders/Irony/Interpreter/ScriptInterpreter.cs delete mode 100644 sources/shaders/Irony/Interpreter/StackFrame.cs delete mode 100644 sources/shaders/Irony/Interpreter/ValuesTable.cs delete mode 100644 sources/shaders/Irony/Irony.csproj delete mode 100644 sources/shaders/Irony/MS-PubLicense.Rtf delete mode 100644 sources/shaders/Irony/Parsing/AstInterfaces.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/Construction/GrammarDataBuilder.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/Construction/LanguageDataBuilder.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder_HelperClasses.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/Construction/_about_parser_construction.txt delete mode 100644 sources/shaders/Irony/Parsing/Data/GrammarData.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/LanguageData.cs delete mode 100644 sources/shaders/Irony/Parsing/Data/ParserData.cs delete mode 100644 sources/shaders/Irony/Parsing/Diagnostics/ParseTreeExtensions.cs delete mode 100644 sources/shaders/Irony/Parsing/Diagnostics/ParserDataPrinter.cs delete mode 100644 sources/shaders/Irony/Parsing/Diagnostics/ParserMessage.cs delete mode 100644 sources/shaders/Irony/Parsing/Diagnostics/ParserTrace.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/BnfExpression.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/BnfTerm.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/Grammar.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/GrammarError.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/GrammarHint.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/LanguageAttribute.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/NonTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Grammar/TermReportGroups.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/CoreParser.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/CoreParser_ErrorHandling.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/ParseTree.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/Parser.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/ParserStack.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/ParsingContext.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/ParsingEventArgs.cs delete mode 100644 sources/shaders/Irony/Parsing/Parser/SyntaxError.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/DefaultScanner.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/Scanner.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/SourceLocation.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/SourceStream.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/Token.cs delete mode 100644 sources/shaders/Irony/Parsing/Scanner/TokenEditorInfo.cs delete mode 100644 sources/shaders/Irony/Parsing/SymbolTable.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/CommentTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/CompoundTerminalBase.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/ConstantTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/CustomTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/DataLiteralBase.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/DsvLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/FixedLengthLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/FreeTextLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/IdentifierTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/ImpliedSymbolTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/KeyTerm.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/LineContinuationTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/NewLineTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/QuotedValueLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/RegExBasedTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/RegExLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/StringLiteral.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiBlockTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTagTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTextTerminal.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/WikiTerminals/_WikiTerminalBase.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/_ISourceStream.cs delete mode 100644 sources/shaders/Irony/Parsing/Terminals/_Terminal.cs delete mode 100644 sources/shaders/Irony/Parsing/TokenFilters/CodeOutlineFilter.cs delete mode 100644 sources/shaders/Irony/Parsing/TokenFilters/TokenFilter.cs delete mode 100644 sources/shaders/Irony/Properties/AssemblyInfo.cs delete mode 100644 sources/shaders/Irony/Resources.Designer.cs delete mode 100644 sources/shaders/Irony/Resources.resx delete mode 100644 sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollBreak.hlsl delete mode 100644 sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollTest.hlsl delete mode 100644 sources/shaders/Stride.Core.Shaders.Tests/TestOpenGLES.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/AnalysisBase.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/CastAnalysis.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/CastHelper.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslDeclarations.h delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslSemanticAnalysis.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Analysis/SemanticAnalysis.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ArrayInitializerExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ArrayType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/AssignmentExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/AssignmentOperator.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/AttributeBase.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/BinaryExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/BinaryOperator.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/BlockStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/CaseStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/CompositeEnum.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ConditionalExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/DeclarationStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/EmptyExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/EmptyStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Expression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ExpressionList.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ExpressionStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ForStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/GenericBaseType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/GenericDeclaration.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/GenericParameterConstraint.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/GenericParameterType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/GenericType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Glsl/InterfaceType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutKeyValue.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Glsl/ParameterQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Glsl/StorageQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Annotations.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AsmExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AttributeDeclaration.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ByteAddressBufferType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CastExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.Helpers.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompileExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompositeIdentifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBuffer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBufferType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/FloatQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/GenericType.Extensions.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierDot.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierGeneric.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierNs.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterfaceType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterpolationQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/PackOffset.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ParameterQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Pass.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/RegisterLocation.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/SamplerType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Semantic.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateInitializer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StorageQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StreamTypeName.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Technique.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/TextureType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Typedef.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IAttributes.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IDeclaration.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IGenerics.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IQualifiers.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IScopeContainer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ITypeInferencer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Identifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IfStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IndexerExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/IronyBrowsableNode.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/KeywordExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Literal.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/LiteralExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/MatrixType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/MemberReferenceExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/MethodDeclaration.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/MethodDefinition.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/MethodInvocationExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Node.Clone.Extension.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Node.Extensions.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Node.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/NodeProcessorContext.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ObjectType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Parameter.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ParameterQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ParenthesizedExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Qualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ReturnStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/ScalarType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Shader.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/SourceLocation.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/SourceSpan.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Statement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/StatementList.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/StorageQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ClassIdentifierGeneric.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/EffectBlock.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/EnumType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ForEachStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/IGenericStringArgument.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ImportBlockStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/LinkType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/LiteralIdentifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/MemberName.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatementType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/NamespaceBlock.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ParametersBlock.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/SemanticType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderClassType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderRootClassType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderTypeName.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/StreamsType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideAttributes.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideConstantBufferType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideStorageQualifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideTags.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/TypelIdentifier.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingParametersStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Stride/VarType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/StructType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/SwitchCaseGroup.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/SwitchStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/TypeBase.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/TypeInference.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/TypeName.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/TypeReferenceExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/UnaryExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/UnaryOperator.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/Variable.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/VariableReferenceExpression.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/VectorType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/VisitorIgnoreAttribute.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Ast/WhileStatement.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/Ast.Extensions.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/BreakContinueVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/CallstackVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/ConstantBufferLayoutRule.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/GlobalUniformVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/GlslKeywords.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/GlslShaderPlatform.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslConvertor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslWriter.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/HlslTypes.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/Keywords.glsl delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/MapRule.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/PipelineStage.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/SamplerMappingVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/SamplerTextureKey.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/ShaderModel.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Convertor/VariableLayoutRule.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/DfaState.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/GoldParserException.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/Grammar.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/LRAction.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/LRState.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/LRStateAction.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/License.txt delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/ObjectMap.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/ParseMessage.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/Parser.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/Rule.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/SR.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/SourceLineReadCallback.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/Symbol.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/GoldParser/SymbolType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/BnfTermExtensions.Helpers.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/CustomScanner.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/DynamicKeyTerm.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Ast.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Helpers.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/IdentifierResolverHint.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/NamedBlockKeyTerm.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Ast.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Helpers.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/ShaderLanguageData.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.Ast.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/TokenCategory.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/TokenInfo.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/TokenType.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cgt delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.grm delete mode 100644 sources/shaders/Stride.Core.Shaders/Parser/Hlsl/HlslParser.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Parser/ParsingResult.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Parser/PreProcessor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Parser/ShaderMacro.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Parser/ShaderParser.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Properties/AssemblyInfo.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Properties/Resources.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Properties/Resources.resx delete mode 100644 sources/shaders/Stride.Core.Shaders/Properties/Resources.tt delete mode 100644 sources/shaders/Stride.Core.Shaders/README.md delete mode 100644 sources/shaders/Stride.Core.Shaders/Stride.Core.Shaders.csproj delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/Hlsl/MessageCode.Hlsl.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/LoggerResult.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/MessageCode.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/OrderedHashSet.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/ReferenceEqualityComparer.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/ReportMessage.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/ReportMessageLevel.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Utility/SpanConverter.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/ExpressionEvaluator.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/ExpressionResult.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/ScopeDeclaration.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/SearchVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/ShaderVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/StripVisitor.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/VisitorBase.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.tt delete mode 100644 sources/shaders/Stride.Core.Shaders/Writer/Hlsl/HlslWriter.cs delete mode 100644 sources/shaders/Stride.Core.Shaders/Writer/ShaderWriter.cs diff --git a/build/Stride.sln b/build/Stride.sln index b28c99bc22..2db63de0c7 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.0.11205.157 d18.0 +VisualStudioVersion = 18.0.11205.157 MinimumVisualStudioVersion = 18.0 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "90-Tools", "90-Tools", "{1AE1AC60-5D2F-4CA7-AE20-888F44551185}" EndProject @@ -29,8 +29,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Private", "00-Ta ..\sources\targets\Stride.UnitTests.targets = ..\sources\targets\Stride.UnitTests.targets EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "80-Shaders", "80-Shaders", "{10D145AF-C8AE-428F-A80F-CA1B591D0DB2}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "50-Presentation", "50-Presentation", "{75A820AB-0F21-40F2-9448-5D7F495B97A0}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internals", "Internals", "{860946E4-CC77-4FDA-A4FD-3DB2A502A696}" @@ -90,14 +88,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input.Tests.Windows" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Tests", "..\sources\core\Stride.Core.Tests\Stride.Core.Tests.csproj", "{5AA408BA-E766-453E-B661-E3D7EC46E2A6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Shaders", "..\sources\shaders\Stride.Core.Shaders\Stride.Core.Shaders.csproj", "{F2D52EDB-BC17-4243-B06D-33CD20F87A7F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Presentation.Wpf", "..\sources\presentation\Stride.Core.Presentation.Wpf\Stride.Core.Presentation.Wpf.csproj", "{47AFCC2E-E9F0-47D6-9D75-9E646546A92B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Presentation.Tests", "..\sources\presentation\Stride.Core.Presentation.Tests\Stride.Core.Presentation.Tests.csproj", "{C223FCD7-CDCC-4943-9E11-9C2CC8FA9FC4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Irony", "..\sources\shaders\Irony\Irony.csproj", "{D81F5C91-D7DB-46E5-BC99-49488FB6814C}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Games", "..\sources\engine\Stride.Games\Stride.Games.csproj", "{42780CBD-3FE7-48E3-BD5B-59945EA20137}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.TextureConverter", "..\sources\tools\Stride.TextureConverter\Stride.TextureConverter.csproj", "{7F7BFF79-C400-435F-B359-56A2EF8956E0}" @@ -126,8 +120,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.MicroThreading" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\sources\core\Stride.Core.IO\Stride.Core.IO.csproj", "{1DE01410-22C9-489B-9796-1ADDAB1F64E5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\engine\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" @@ -407,16 +399,6 @@ Global {5AA408BA-E766-453E-B661-E3D7EC46E2A6}.Release|Mixed Platforms.Build.0 = Debug|Any CPU {5AA408BA-E766-453E-B661-E3D7EC46E2A6}.Release|Win32.ActiveCfg = Debug|Any CPU {5AA408BA-E766-453E-B661-E3D7EC46E2A6}.Release|Win32.Build.0 = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Win32.ActiveCfg = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Any CPU.Build.0 = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Win32.ActiveCfg = Release|Any CPU {47AFCC2E-E9F0-47D6-9D75-9E646546A92B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {47AFCC2E-E9F0-47D6-9D75-9E646546A92B}.Debug|Any CPU.Build.0 = Debug|Any CPU {47AFCC2E-E9F0-47D6-9D75-9E646546A92B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -437,16 +419,6 @@ Global {C223FCD7-CDCC-4943-9E11-9C2CC8FA9FC4}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C223FCD7-CDCC-4943-9E11-9C2CC8FA9FC4}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C223FCD7-CDCC-4943-9E11-9C2CC8FA9FC4}.Release|Win32.ActiveCfg = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Win32.ActiveCfg = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Any CPU.Build.0 = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Win32.ActiveCfg = Release|Any CPU {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|Any CPU.Build.0 = Debug|Any CPU {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -581,16 +553,6 @@ Global {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|Win32.ActiveCfg = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Win32.ActiveCfg = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Any CPU.Build.0 = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Win32.ActiveCfg = Release|Any CPU {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|Any CPU.Build.0 = Debug|Any CPU {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -1538,10 +1500,8 @@ Global {A8F8D125-7A22-489F-99BC-9A02F545A17F} = {A7ED9F01-7D78-4381-90A6-D50E51C17250} {01700344-CF44-482C-BEBC-60213B0F844C} = {A7ED9F01-7D78-4381-90A6-D50E51C17250} {5AA408BA-E766-453E-B661-E3D7EC46E2A6} = {22ADD4CD-092E-4ADC-A21E-64CF42230152} - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} {47AFCC2E-E9F0-47D6-9D75-9E646546A92B} = {75A820AB-0F21-40F2-9448-5D7F495B97A0} {C223FCD7-CDCC-4943-9E11-9C2CC8FA9FC4} = {52AE329E-B588-40D0-A578-8D0DB1BD83E5} - {D81F5C91-D7DB-46E5-BC99-49488FB6814C} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} {42780CBD-3FE7-48E3-BD5B-59945EA20137} = {4C142567-C42B-40F5-B092-798882190209} {7F7BFF79-C400-435F-B359-56A2EF8956E0} = {4A15BAAD-AA37-4754-A2BF-8D4049211E36} {C485CE61-3006-4C99-ACB3-A737F5CEBAE7} = {4A15BAAD-AA37-4754-A2BF-8D4049211E36} @@ -1556,7 +1516,6 @@ Global {CB6C4D8B-906E-4120-8146-09261B8D2885} = {75A820AB-0F21-40F2-9448-5D7F495B97A0} {1320F627-EE43-4115-8E89-19D1753E51F2} = {2E93E2B5-4500-4E47-9B65-E705218AB578} {1DE01410-22C9-489B-9796-1ADDAB1F64E5} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {14A47447-2A24-4ECD-B24D-6571499DCD4C} = {4C142567-C42B-40F5-B092-798882190209} {273BDD15-7392-4078-91F0-AF23594A3D7B} = {4C142567-C42B-40F5-B092-798882190209} {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} diff --git a/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/PhysicsGizmo.cs b/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/PhysicsGizmo.cs index 4ad0066999..79487f6125 100644 --- a/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/PhysicsGizmo.cs +++ b/sources/editor/Stride.Assets.Presentation/AssetEditors/Gizmos/PhysicsGizmo.cs @@ -4,7 +4,6 @@ using Stride.Core; using Stride.Core.Extensions; using Stride.Core.Mathematics; -using Stride.Core.Shaders.Ast; using Stride.Engine; using Stride.Engine.Gizmos; using Stride.Extensions; diff --git a/sources/engine/Stride.Assets/Templates/ProjectTemplateGeneratorHelper.cs b/sources/engine/Stride.Assets/Templates/ProjectTemplateGeneratorHelper.cs index 78a9740fe9..d9009d8e17 100644 --- a/sources/engine/Stride.Assets/Templates/ProjectTemplateGeneratorHelper.cs +++ b/sources/engine/Stride.Assets/Templates/ProjectTemplateGeneratorHelper.cs @@ -12,7 +12,6 @@ using Stride.Core.IO; using Stride.Core.ProjectTemplating; using Stride.Graphics; -using Stride.Shaders.Parser.Mixins; using Stride.Core.Extensions; namespace Stride.Assets.Templates @@ -191,15 +190,6 @@ public static SolutionProject GenerateTemplate(TemplateGeneratorParameters param List generatedFiles; var project = GenerateTemplate(parameters, templateRelativePath, projectName, platformType, graphicsPlatform, projectType, out generatedFiles, projectGuid); - // Special case for sdfx files - foreach (var file in generatedFiles) - { - if (file.EndsWith(".sdfx", StringComparison.OrdinalIgnoreCase)) - { - ConvertXkfxToCSharp(file); - } - } - return project; } @@ -286,13 +276,6 @@ public static void Progress(ILogger log, string message, int stepIndex, int step progress?.OnProgressChanged(new ProgressStatusEventArgs(message, stepIndex, stepCount)); } - private static void ConvertXkfxToCSharp(string sdfxfile) - { - var sdfileContent = File.ReadAllText(sdfxfile); - var result = ShaderMixinCodeGen.GenerateCsharp(sdfileContent, sdfxfile); - File.WriteAllText(Path.ChangeExtension(sdfxfile, ".cs"), result, Encoding.UTF8); - } - private static void RemoveProject(ProjectReference projectReference, ILogger logger) { var projectFullPath = projectReference.Location.FullPath; diff --git a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs index 9087dad6b9..69170303e8 100644 --- a/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs +++ b/sources/engine/Stride.Shaders.Compiler/EffectCompiler.cs @@ -15,10 +15,6 @@ using Stride.Core; using Stride.Core.Diagnostics; using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; using Stride.Core.Storage; using Stride.Graphics; using Stride.Rendering; @@ -26,9 +22,6 @@ using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.Direct3D; using Stride.Shaders.Compilers.SDSL; -using Stride.Shaders.Parser; -using Stride.Shaders.Parser.Mixins; -using Stride.Shaders.Parsing; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; @@ -45,7 +38,7 @@ public class EffectCompiler : EffectCompilerBase private bool d3dCompilerLoaded = false; private static readonly Object WriterLock = new Object(); - private ShaderMixinParser shaderMixinParser; + private ShaderLoader shaderLoader; private readonly object shaderMixinParserLock = new object(); @@ -70,7 +63,7 @@ public EffectCompiler(IVirtualFileProvider fileProvider) public override ObjectId GetShaderSourceHash(string type) { - return GetMixinParser().SourceManager.GetShaderSourceHash(type); + return GetShaderLoader().SourceManager.GetShaderSourceHash(type); } /// @@ -79,81 +72,42 @@ public override ObjectId GetShaderSourceHash(string type) /// public override void ResetCache(HashSet modifiedShaders) { - GetMixinParser().DeleteObsoleteCache(modifiedShaders); + GetShaderLoader().SourceManager.DeleteObsoleteCache(modifiedShaders); } - public ShaderMixinParser GetMixinParser() + public ShaderLoader GetShaderLoader() { lock (shaderMixinParserLock) { - // Generate the AST from the mixin description - if (shaderMixinParser == null) + if (shaderLoader == null) { - shaderMixinParser = new ShaderMixinParser(FileProvider); - shaderMixinParser.SourceManager.LookupDirectoryList.AddRange(SourceDirectories); // TODO: temp - shaderMixinParser.SourceManager.UseFileSystem = UseFileSystem; - shaderMixinParser.SourceManager.UrlToFilePath = UrlToFilePath; // TODO: temp + shaderLoader = new ShaderLoader(FileProvider); + shaderLoader.SourceManager.LookupDirectoryList.AddRange(SourceDirectories); // TODO: temp + shaderLoader.SourceManager.UseFileSystem = UseFileSystem; + shaderLoader.SourceManager.UrlToFilePath = UrlToFilePath; // TODO: temp } - return shaderMixinParser; + + return shaderLoader; } } public class ShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new ShaderCache()) { - protected override bool ExternalFileExists(string name) - { - var path = $"shaders/{name}.sdsl"; - return FileProvider.FileExists(path); - } + public ShaderSourceManager SourceManager { get; } = new(FileProvider); + + protected override bool ExternalFileExists(string name) => SourceManager.IsClassExists(name); public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { - var path = $"shaders/{name}.sdsl"; - - using var sourceStream = FileProvider.OpenStream(path, VirtualFileMode.Open, VirtualFileAccess.Read); - using var reader = new StreamReader(sourceStream); - code = reader.ReadToEnd(); - - var databaseStream = sourceStream as IDatabaseStream; - if (databaseStream == null) - { - sourceStream.Position = 0; - var data = new byte[sourceStream.Length]; - var readBytes = sourceStream.Read(data, 0, (int)sourceStream.Length); - if (readBytes != sourceStream.Length) - throw new InvalidOperationException(); - hash = ObjectId.FromBytes(data); - } - else - { - hash = databaseStream.ObjectId; - } + var result = SourceManager.LoadShaderSource(name); + filename = result.Path; + code = result.Source; + hash = result.Hash; - filename = path; return true; } } - //Parsing.SDSL.ShaderMixinSource ConvertAndEnsureMixin(ShaderSource shaderSource) - //{ - // var result = Convert(shaderSource); - // return result switch - // { - // Parsing.SDSL.ShaderMixinSource mixinSource => mixinSource, - // Parsing.SDSL.ShaderClassSource classSource => new Parsing.SDSL.ShaderMixinSource { Mixins = { classSource } }, - // }; - //} - - //Parsing.SDSL.ShaderSource Convert(ShaderSource shaderSource) - //{ - // return shaderSource switch - // { - // ShaderClassSource classSource => new Parsing.SDSL.ShaderClassSource(classSource.ClassName) { GenericArguments = classSource.GenericArguments }, - // ShaderMixinSource mixinSource => new Parsing.SDSL.ShaderMixinSource { Compositions = new Dictionary(mixinSource.Compositions.Select(x => KeyValuePair.Create(x.Key, ConvertAndEnsureMixin(x.Value)))) }, - // }; - //} - - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters) { var log = new LoggerResult(); @@ -206,7 +160,7 @@ public override TaskOrResult Compile(ShaderMixinSo // In .sdsl, class has been renamed to shader to avoid ambiguities with HLSL shaderMixinSource.AddMacro("class", "shader"); - var shaderMixer = new ShaderMixer(new ShaderLoader(FileProvider)); + var shaderMixer = new ShaderMixer(GetShaderLoader()); shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); @@ -518,29 +472,6 @@ public override TaskOrResult Compile(ShaderMixinSo return new EffectBytecodeCompilerResult(bytecode, log); } - private static void CopyLogs(Stride.Core.Shaders.Utility.LoggerResult inputLog, LoggerResult outputLog) - { - foreach (var inputMessage in inputLog.Messages) - { - var logType = LogMessageType.Info; - switch (inputMessage.Level) - { - case ReportMessageLevel.Error: - logType = LogMessageType.Error; - break; - case ReportMessageLevel.Info: - logType = LogMessageType.Info; - break; - case ReportMessageLevel.Warning: - logType = LogMessageType.Warning; - break; - } - var outputMessage = new LogMessage(inputMessage.Span.ToString(), logType, string.Format(" {0}: {1}", inputMessage.Code, inputMessage.Text)); - outputLog.Log(outputMessage); - } - outputLog.HasErrors = inputLog.HasErrors; - } - private static void CleanupReflection(EffectReflection reflection) { // TODO GRAPHICS REFACTOR we hardcode several resource group we want to preserve or optimize completly diff --git a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs deleted file mode 100644 index ad9c8bb359..0000000000 --- a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs +++ /dev/null @@ -1,481 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; - -using Stride.Core; -using Stride.Core.Extensions; -using Stride.Core.Serialization; -using Stride.Core.Storage; -using Stride.Graphics; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Glsl; -using Stride.Core.Shaders.Convertor; - -using ConstantBuffer = Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer; -using GlslStorageQualifier = Stride.Core.Shaders.Ast.Glsl.StorageQualifier; -using System.Runtime.InteropServices; - -namespace Stride.Shaders.Compiler.OpenGL -{ - internal partial class ShaderCompiler : IShaderCompiler - { - /// - /// The constructor. - /// - /// The number of render targets - public ShaderCompiler() - { - } - - /// - /// Converts the hlsl code into glsl and stores the result as plain text - /// - /// the hlsl shader - /// the entrypoint function name - /// the shader pipeline stage - /// - /// the reflection gathered from the hlsl analysis - /// the name of the source file - /// - public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, ShaderStage stage, EffectCompilerParameters effectParameters, EffectReflection reflection, string sourceFilename = null) - { - var shaderBytecodeResult = new ShaderBytecodeResult(); - byte[] rawData; - - var inputAttributeNames = new Dictionary(); - var resourceBindings = new Dictionary(); - - GlslShaderPlatform shaderPlatform; - int shaderVersion; - - switch (effectParameters.Platform) - { - case GraphicsPlatform.Vulkan: - shaderPlatform = GlslShaderPlatform.Vulkan; - shaderVersion = 450; - break; - default: - throw new ArgumentOutOfRangeException("effectParameters.Platform"); - } - - var shader = Compile(shaderSource, entryPoint, stage, shaderPlatform, shaderVersion, shaderBytecodeResult, reflection, inputAttributeNames, resourceBindings, sourceFilename); - - if (shader == null) - return shaderBytecodeResult; - - if (effectParameters.Platform == GraphicsPlatform.Vulkan) - { - string inputFileExtension; - switch (stage) - { - case ShaderStage.Vertex: inputFileExtension = ".vert"; break; - case ShaderStage.Pixel: inputFileExtension = ".frag"; break; - case ShaderStage.Geometry: inputFileExtension = ".geom"; break; - case ShaderStage.Domain: inputFileExtension = ".tese"; break; - case ShaderStage.Hull: inputFileExtension = ".tesc"; break; - case ShaderStage.Compute: inputFileExtension = ".comp"; break; - default: - shaderBytecodeResult.Error("Unknown shader profile"); - return shaderBytecodeResult; - } - - var inputFileName = Path.ChangeExtension(Path.GetTempFileName(), inputFileExtension); - var outputFileName = Path.ChangeExtension(inputFileName, ".spv"); - - // Write shader source to disk - File.WriteAllBytes(inputFileName, Encoding.ASCII.GetBytes(shader)); - - // Run shader compiler - string glslangValidatorPath = NativeLibraryHelper.LocateExecutable(Platform.Type == PlatformType.Windows ? "glslangValidator.exe" : "glslangValidator.bin", typeof(ShaderCompiler)); - ShellHelper.RunProcessAndRedirectToLogger(glslangValidatorPath, $"-V -o {outputFileName} {inputFileName}", null, shaderBytecodeResult); - - if (!File.Exists(outputFileName)) - { - shaderBytecodeResult.Error("Failed to generate SPIR-V from GLSL"); - return shaderBytecodeResult; - } - - // Read compiled shader - var shaderBytecodes = new ShaderInputBytecode - { - InputAttributeNames = inputAttributeNames, - ResourceBindings = resourceBindings, - Data = File.ReadAllBytes(outputFileName), - }; - - using (var stream = new MemoryStream()) - { - var writer = new BinarySerializationWriter(stream); - writer.Write(shaderBytecodes); - rawData = stream.ToArray(); - } - - // Cleanup temp files - File.Delete(inputFileName); - File.Delete(outputFileName); - } - else - { - // store string on OpenGL platforms - rawData = Encoding.UTF8.GetBytes(shader); - } - - var bytecodeId = ObjectId.FromBytes(rawData); - var bytecode = new ShaderBytecode(stage, bytecodeId, rawData); - - shaderBytecodeResult.Bytecode = bytecode; - - return shaderBytecodeResult; - } - - private string Compile(string shaderSource, string entryPoint, ShaderStage stage, GlslShaderPlatform shaderPlatform, int shaderVersion, ShaderBytecodeResult shaderBytecodeResult, EffectReflection reflection, IDictionary inputAttributeNames, Dictionary resourceBindings, string sourceFilename = null) - { - PipelineStage pipelineStage = PipelineStage.None; - switch (stage) - { - case ShaderStage.Vertex: - pipelineStage = PipelineStage.Vertex; - break; - case ShaderStage.Pixel: - pipelineStage = PipelineStage.Pixel; - break; - case ShaderStage.Geometry: - shaderBytecodeResult.Error("Geometry stage can't be converted to OpenGL. Only Vertex and Pixel shaders are supported"); - break; - case ShaderStage.Hull: - shaderBytecodeResult.Error("Hull stage can't be converted to OpenGL. Only Vertex and Pixel shaders are supported"); - break; - case ShaderStage.Domain: - shaderBytecodeResult.Error("Domain stage can't be converted to OpenGL. Only Vertex and Pixel shaders are supported"); - break; - case ShaderStage.Compute when shaderPlatform == GlslShaderPlatform.Vulkan: - pipelineStage = PipelineStage.Compute; - break; - case ShaderStage.Compute: - shaderBytecodeResult.Error("Compute stage can't be converted to OpenGL. Only Vertex and Pixel shaders are supported"); - break; - default: - shaderBytecodeResult.Error("Unknown shader profile."); - break; - } - - if (shaderBytecodeResult.HasErrors) - return null; - - Shader glslShader; - - // null entry point means no shader. In that case, we return a default function in HlslToGlslWriter - // TODO: support that directly in HlslToGlslConvertor? - if (entryPoint == null) - { - glslShader = null; - } - else - { - // Convert from HLSL to GLSL - // Note that for now we parse from shader as a string, but we could simply clone effectPass.Shader to avoid multiple parsing. - var glslConvertor = new ShaderConverter(shaderPlatform, shaderVersion); - glslShader = glslConvertor.Convert(shaderSource, entryPoint, pipelineStage, sourceFilename, inputAttributeNames, shaderBytecodeResult); - - if (glslShader == null || shaderBytecodeResult.HasErrors) - return null; - - foreach (var constantBuffer in glslShader.Declarations.OfType()) - { - // Update constant buffer itself (first time only) - var reflectionConstantBuffer = reflection.ConstantBuffers.FirstOrDefault(x => x.Name == constantBuffer.Name && x.Size == 0); - if (reflectionConstantBuffer != null) - { - // Used to compute constant buffer size and member offsets (std140 rule) - int constantBufferOffset = 0; - - // Fill members - for (int index = 0; index < reflectionConstantBuffer.Members.Length; index++) - { - var member = reflectionConstantBuffer.Members[index]; - - // Properly compute size and offset according to std140 rules - var memberSize = ComputeMemberSize(ref member.Type, ref constantBufferOffset); - - // Store size/offset info - member.Offset = constantBufferOffset; - member.Size = memberSize; - - // Adjust offset for next item - constantBufferOffset += memberSize; - - reflectionConstantBuffer.Members[index] = member; - } - - reflectionConstantBuffer.Size = constantBufferOffset; - } - - // Find binding - var resourceBindingIndex = reflection.ResourceBindings.IndexOf(x => x.RawName == constantBuffer.Name); - if (resourceBindingIndex != -1) - { - MarkResourceBindingAsUsed(reflection, resourceBindingIndex, stage); - } - } - - foreach (var variable in glslShader.Declarations.OfType().Where(x => (x.Qualifiers.Contains(GlslStorageQualifier.Uniform)))) - { - // Check if we have a variable that starts or ends with this name (in case of samplers) - // TODO: Have real AST support for all the list in Keywords.glsl - if (variable.Type.Name.Text.Contains("sampler1D") || - variable.Type.Name.Text.Contains("sampler2D") || - variable.Type.Name.Text.Contains("sampler3D") || - variable.Type.Name.Text.Contains("samplerCube") || - variable.Type.Name.Text.Contains("samplerBuffer")) - { - // TODO: Make more robust - var textureBindingIndex = reflection.ResourceBindings.IndexOf(x => variable.Name.ToString().StartsWith(x.RawName, StringComparison.Ordinal)); - var samplerBindingIndex = reflection.ResourceBindings.IndexOf(x => variable.Name.ToString().EndsWith(x.RawName, StringComparison.Ordinal)); - - if (textureBindingIndex != -1) - MarkResourceBindingAsUsed(reflection, textureBindingIndex, stage); - - if (samplerBindingIndex != -1) - MarkResourceBindingAsUsed(reflection, samplerBindingIndex, stage); - } - else - { - var resourceBindingIndex = reflection.ResourceBindings.IndexOf(x => x.RawName == variable.Name); - if (resourceBindingIndex != -1) - { - MarkResourceBindingAsUsed(reflection, resourceBindingIndex, stage); - } - } - } - - if (shaderPlatform == GlslShaderPlatform.Vulkan) - { - // Defines the ordering of resource groups in Vulkan. This is mirrored in the PipelineState - var resourceGroups = reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); - - var bindings = resourceGroups.SelectMany(resourceGroup => reflection.ResourceBindings - .Where(x => x.ResourceGroup == resourceGroup || (x.ResourceGroup == null && resourceGroup == "Globals")) - .GroupBy(x => new { KeyName = x.KeyInfo.KeyName, RawName = x.RawName, Class = x.Class, Type = x.Type, ElementType = x.ElementType.Type, SlotCount = x.SlotCount, LogicalGroup = x.LogicalGroup }) - .OrderBy(x => x.Key.Class == EffectParameterClass.ConstantBuffer ? 0 : 1)) - .ToList(); - - // Add layout(set, bindings) qualifier to all constant buffers - foreach (var constantBuffer in glslShader.Declarations.OfType()) - { - var layoutBindingIndex = bindings.IndexOf(x => x.Key.RawName == constantBuffer.Name); - if (layoutBindingIndex != -1) - { - var layoutQualifier = constantBuffer.Qualifiers.OfType().FirstOrDefault(); - if (layoutQualifier == null) - { - layoutQualifier = new Stride.Core.Shaders.Ast.Glsl.LayoutQualifier(); - constantBuffer.Qualifiers |= layoutQualifier; - } - - //layoutQualifier.Layouts.Add(new LayoutKeyValue("set", resourceGroups.IndexOf(resourceGroup))); - layoutQualifier.Layouts.Add(new LayoutKeyValue("set", 0)); - layoutQualifier.Layouts.Add(new LayoutKeyValue("binding", layoutBindingIndex + 1)); - - resourceBindings.Add(bindings[layoutBindingIndex].Key.KeyName, layoutBindingIndex + 1); - } - } - - // Add layout(set, bindings) qualifier to all other uniforms - foreach (var variable in glslShader.Declarations.OfType().Where(x => (x.Qualifiers.Contains(GlslStorageQualifier.Uniform)))) - { - var layoutBindingIndex = bindings.IndexOf(x => variable.Name.Text.StartsWith(x.Key.RawName, StringComparison.Ordinal)); - - if (layoutBindingIndex != -1) - { - var layoutQualifier = variable.Qualifiers.OfType().FirstOrDefault(); - if (layoutQualifier == null) - { - layoutQualifier = new Stride.Core.Shaders.Ast.Glsl.LayoutQualifier(); - variable.Qualifiers |= layoutQualifier; - } - - //layoutQualifier.Layouts.Add(new LayoutKeyValue("set", resourceGroups.IndexOf(resourceGroup))); - layoutQualifier.Layouts.Add(new LayoutKeyValue("set", 0)); - layoutQualifier.Layouts.Add(new LayoutKeyValue("binding", layoutBindingIndex + 1)); - - resourceBindings.Add(bindings[layoutBindingIndex].Key.KeyName, layoutBindingIndex + 1); - - // Buffer should not be marked with uniform, this probably should not be here but it works and does not mess anything up. - if (variable.Type.Qualifiers.Contains(GlslStorageQualifier.Buffer)) - { - variable.Qualifiers.Values.Remove(GlslStorageQualifier.Uniform); - } - } - } - } - - } - - // Output the result - var glslShaderWriter = new HlslToGlslWriter(shaderPlatform, shaderVersion, pipelineStage); - - if (shaderPlatform == GlslShaderPlatform.OpenGLES && shaderVersion < 320) - { - glslShaderWriter.ExtraHeaders = "#define texelFetchBufferPlaceholder"; - } - - if (shaderPlatform == GlslShaderPlatform.Vulkan && pipelineStage == PipelineStage.Compute) - { - glslShaderWriter.Extensions.Add("GL_EXT_shader_image_load_formatted"); - } - - glslShaderWriter.Extensions.Add("GL_EXT_samplerless_texture_functions"); - - // Write shader - glslShaderWriter.Visit(glslShader); - - var shaderString = glslShaderWriter.Text; - - // Build shader source - var glslShaderCode = new StringBuilder(); - - // Append some header depending on target - //if (isOpenGLES) - //{ - // if (isOpenGLES3) - // { - // glslShaderCode - // .AppendLine("#version 300 es") // TODO: 310 version? - // .AppendLine(); - // } - // - // if (pipelineStage == PipelineStage.Pixel) - // glslShaderCode - // .AppendLine("precision highp float;") - // .AppendLine(); - //} - //else - //{ - // glslShaderCode - // .AppendLine("#version 420") - // .AppendLine() - // .AppendLine("#define samplerBuffer sampler2D") - // .AppendLine("#define isamplerBuffer isampler2D") - // .AppendLine("#define usamplerBuffer usampler2D") - // .AppendLine("#define texelFetchBuffer(sampler, P) texelFetch(sampler, ivec2((P) & 0xFFF, (P) >> 12), 0)"); - // //.AppendLine("#define texelFetchBuffer(sampler, P) texelFetch(sampler, P)"); - //} - - glslShaderCode.Append(shaderString); - - var realShaderSource = glslShaderCode.ToString(); - - return realShaderSource; - } - - private static void MarkResourceBindingAsUsed(EffectReflection reflection, int resourceBindingIndex, ShaderStage stage) - { - var resourceBinding = reflection.ResourceBindings[resourceBindingIndex]; - if (resourceBinding.Stage == ShaderStage.None) - { - resourceBinding.Stage = stage; - reflection.ResourceBindings[resourceBindingIndex] = resourceBinding; - } - } - - private static int ComputeMemberSize(ref EffectTypeDescription memberType, ref int constantBufferOffset) - { - var elementSize = ComputeTypeSize(memberType.Type); - int size; - int alignment; - - switch (memberType.Class) - { - case EffectParameterClass.Struct: - { - // Fill members - size = 0; - for (int index = 0; index < memberType.Members.Length; index++) - { - // Properly compute size and offset according to DX rules - var memberSize = ComputeMemberSize(ref memberType.Members[index].Type, ref size); - - // Align offset and store it as member offset - memberType.Members[index].Offset = size; - - // Adjust offset for next item - size += memberSize; - } - - alignment = size; - break; - } - case EffectParameterClass.Scalar: - { - size = elementSize; - alignment = size; - break; - } - case EffectParameterClass.Color: - case EffectParameterClass.Vector: - { - size = elementSize * memberType.ColumnCount; - alignment = (memberType.ColumnCount == 3 ? 4 : memberType.ColumnCount) * elementSize; // vec3 uses alignment of vec4 - break; - } - case EffectParameterClass.MatrixColumns: - { - size = elementSize * 4 * memberType.ColumnCount; - alignment = size; - break; - } - case EffectParameterClass.MatrixRows: - { - size = elementSize * 4 * memberType.RowCount; - alignment = size; - break; - } - default: - throw new NotImplementedException(); - } - - // Update element size - memberType.ElementSize = size; - - // Array - if (memberType.Elements > 0) - { - var roundedSize = (size + 15) / 16 * 16; // Round up to vec4 - size = roundedSize * memberType.Elements; - alignment = roundedSize * memberType.Elements; - } - - // Alignment is maxed up to vec4 - if (alignment > 16) - alignment = 16; - - // Align offset and store it as member offset - constantBufferOffset = (constantBufferOffset + alignment - 1) / alignment * alignment; - - return size; - } - - private static int ComputeTypeSize(EffectParameterType type) - { - switch (type) - { - case EffectParameterType.Bool: - case EffectParameterType.Float: - case EffectParameterType.Int: - case EffectParameterType.UInt: - return 4; - case EffectParameterType.Double: - return 8; - case EffectParameterType.Void: - return 0; - default: - throw new NotImplementedException(); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderConverter.cs b/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderConverter.cs deleted file mode 100644 index 5dde34abc4..0000000000 --- a/sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderConverter.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Stride.Core.Diagnostics; -using Stride.Core.Shaders.Analysis.Hlsl; -using Stride.Core.Shaders.Convertor; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Parser.Hlsl; -using ShaderMacro = Stride.Shaders.ShaderMacro; - -namespace Stride.Shaders.Compiler.OpenGL -{ - /// - /// Converts from HLSL shader sourcecode to a GLSL sourcecode. - /// - internal class ShaderConverter - { - private GlslShaderPlatform shaderPlatform; - private int shaderVersion; - - /// - /// Initializes a new instance of the class. - /// - public ShaderConverter(GlslShaderPlatform shaderPlatform, int shaderVersion) - { - this.shaderPlatform = shaderPlatform; - this.shaderVersion = shaderVersion; - - IsVerboseLog = true; - Macros = new List(); - } - - /// - /// Gets or sets a value indicating whether this instance is producing a verbose log. - /// - /// - /// true if this instance is producing a verbose log; otherwise, false. - /// - public bool IsVerboseLog { get; set; } - - /// - /// Gets or sets the include directories. - /// - /// - /// The include directories. - /// - public string[] IncludeDirectories { get; set; } - - - /// - /// Gets or sets the macros. - /// - /// - /// The macros. - /// - public List Macros { get; set; } - - /// - /// Converts the specified hlsl source code to glsl. - /// - /// The HLSL source code. - /// The HLSL entry point. - /// The stage to convert. - /// The shader. - /// The input HLSL filepath. - /// - /// The resulting glsl AST tree. - /// - public global::Stride.Core.Shaders.Ast.Shader Convert(string hlslSourcecode, string hlslEntryPoint, PipelineStage stage, string inputHlslFilepath, IDictionary inputAttributeNames, LoggerResult log) - { - try - { - // Convert from Framework.Graphics ShaderMacro to Framework.Shaders ShaderMacro - var macros = new global::Stride.Core.Shaders.Parser.ShaderMacro[Macros.Count]; - for (int index = 0; index < Macros.Count; index++) - macros[index] = new global::Stride.Core.Shaders.Parser.ShaderMacro(Macros[index].Name, Macros[index].Definition); - - var result = HlslParser.TryPreProcessAndParse(hlslSourcecode, inputHlslFilepath, macros, IncludeDirectories); - - if (result.HasErrors) - { - log.Error(result.ToString()); - return null; - } - - // Prepare the shader before type inference analysis - HlslToGlslConvertor.Prepare(result.Shader); - - HlslSemanticAnalysis.Run(result); - - // If there are any type inference analysis, just display all errors but ytu - if (result.HasErrors) - { - log.Error(result.ToString()); - return null; - } - - return Convert(result, hlslEntryPoint, stage, inputHlslFilepath, inputAttributeNames, log); - } - catch (Exception ex) - { - log.Error($"Unexpected error while converting file [{inputHlslFilepath}] with entry point [{hlslEntryPoint}]", ex); - } - return null; - } - - /// - /// Converts the specified hlsl source code to glsl. - /// - /// The HLSL entry point. - /// The stage to convert. - /// The shader. - /// The input HLSL filepath. - /// - /// The resulting glsl AST tree. - /// - private global::Stride.Core.Shaders.Ast.Shader Convert(ParsingResult result, string hlslEntryPoint, PipelineStage stage, string inputHlslFilepath, IDictionary inputAttributeNames, LoggerResult log) - { - try - { - var convertor = new HlslToGlslConvertor(shaderPlatform, shaderVersion, hlslEntryPoint, stage, ShaderModel.Model40) // TODO HARDCODED VALUE to change - { - // Those settings are now default values - //NoSwapForBinaryMatrixOperation = true, - //UnrollForLoops = true, - //ViewFrustumRemap = true, - //FlipRenderTarget = true, - //KeepConstantBuffer = !isOpenGLES || isOpenGLES3, - //TextureFunctionsCompatibilityProfile = isOpenGLES && !isOpenGLES3, - //KeepNonUniformArrayInitializers = !isOpenGLES, - - UseBindingLayout = false, - UseSemanticForVariable = true, - IsPointSpriteShader = false, - InputAttributeNames = inputAttributeNames - }; - convertor.Run(result); - - // After the converter we display the errors but we don't stop writing output glsl - if (result.HasErrors) - { - //DisplayError(log, result, "Error while converting file:"); - } - - - return result.Shader; - } - catch (Exception ex) - { - log.Error($"Unexpected error while converting file [{inputHlslFilepath}] with entry point [{hlslEntryPoint}]", ex); - return null; - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderSourceManager.cs b/sources/engine/Stride.Shaders.Compiler/ShaderSourceManager.cs similarity index 99% rename from sources/engine/Stride.Shaders.Parser/Mixins/ShaderSourceManager.cs rename to sources/engine/Stride.Shaders.Compiler/ShaderSourceManager.cs index d922be2387..c810017dc3 100644 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderSourceManager.cs +++ b/sources/engine/Stride.Shaders.Compiler/ShaderSourceManager.cs @@ -12,7 +12,7 @@ using Stride.Core.Serialization.Contents; using Stride.Core.Storage; -namespace Stride.Shaders.Parser.Mixins +namespace Stride.Shaders.Compilers { /// /// Class ShaderSourceManager diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index a91da7b80a..9f81afe8d9 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -1,4 +1,4 @@ - + true @@ -18,7 +18,7 @@ - + diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/AssignmentOperatorStatus.cs b/sources/engine/Stride.Shaders.Parser/Analysis/AssignmentOperatorStatus.cs deleted file mode 100644 index 5f10abba28..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/AssignmentOperatorStatus.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Shaders.Parser.Analysis -{ - [Flags] - internal enum AssignmentOperatorStatus - { - None = 0, - Read = 1, - Write = 2, - ReadWrite = Read | Write, - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/ExpressionNodeCouple.cs b/sources/engine/Stride.Shaders.Parser/Analysis/ExpressionNodeCouple.cs deleted file mode 100644 index 048b231dd0..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/ExpressionNodeCouple.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Analysis -{ - [DataContract] - internal class ExpressionNodeCouple - { - public Expression Expression; - public Node Node; - - public ExpressionNodeCouple() : this(null, null) {} - - public ExpressionNodeCouple(Expression expression, Node node) - { - Expression = expression; - Node = node; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/MemberReferenceExpressionNodeCouple.cs b/sources/engine/Stride.Shaders.Parser/Analysis/MemberReferenceExpressionNodeCouple.cs deleted file mode 100644 index 920cd84b87..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/MemberReferenceExpressionNodeCouple.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Analysis -{ - public class MemberReferenceExpressionNodeCouple - { - public MemberReferenceExpression Member; - public Node Node; - - public MemberReferenceExpressionNodeCouple() : this(null, null) { } - - public MemberReferenceExpressionNodeCouple(MemberReferenceExpression member, Node node) - { - Member = member; - Node = node; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/StatementNodeCouple.cs b/sources/engine/Stride.Shaders.Parser/Analysis/StatementNodeCouple.cs deleted file mode 100644 index 327e82779b..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/StatementNodeCouple.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Analysis -{ - [DataContract] - internal class StatementNodeCouple - { - public Statement Statement; - public Node Node; - - public StatementNodeCouple() : this(null, null) { } - - public StatementNodeCouple(Statement statement, Node node) - { - Statement = statement; - Node = node; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/StrideParsingInfo.cs b/sources/engine/Stride.Shaders.Parser/Analysis/StrideParsingInfo.cs deleted file mode 100644 index 6078960d56..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/StrideParsingInfo.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using Stride.Core; -using Stride.Shaders.Parser.Mixins; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; - -namespace Stride.Shaders.Parser.Analysis -{ - [DataContract] - internal class StrideParsingInfo - { - #region Public properties - - /// - /// Variables that referenced the stage class ( "= stage" ) - /// - public HashSet StageInitializedVariables { get; } = new(); - - /// - /// All typedefs - /// - public List Typedefs { get; } = new(); - - /// - /// All structure definitions - /// - public List StructureDefinitions { get; } = new(); - - /// - /// All the base method calls (base.xxx) - /// - public HashSet BaseMethodCalls { get; } = new(); - - /// - /// All the method calls that are not base - /// - public HashSet ThisMethodCalls { get; } = new(); - - /// - /// All the method calls to stage methods - /// - public HashSet StageMethodCalls { get; } = new(); - - /// - /// All foreach statements - /// - public HashSet ForEachStatements { get; } = new(); - - /// - /// References to members of the current shader - /// - public ReferencesPool ClassReferences { get; } = new(); - - /// - /// Static references to class members - /// - public ReferencesPool StaticReferences { get; } = new(); - - /// - /// References to extern members - /// - public ReferencesPool ExternReferences { get; } = new(); - - /// - /// References to stage initialized variables and methods - /// - public ReferencesPool StageInitReferences { get; } = new(); - - /// - /// Gets navigable nodes (local variables, base class...etc.) - /// - /// The navigable nodes. - public List NavigableNodes { get; } = new(); - - /// - /// List of the static classes - /// - public HashSet StaticClasses { get; } = new(); - - #endregion - - #region Public members - - /// - /// Error logger - /// - public ParsingResult ErrorsWarnings = null; - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/StrideSemanticAnalysis.cs b/sources/engine/Stride.Shaders.Parser/Analysis/StrideSemanticAnalysis.cs deleted file mode 100644 index d7a7eb94d9..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/StrideSemanticAnalysis.cs +++ /dev/null @@ -1,1178 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Linq; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Mixins; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Visitor; - -using StorageQualifier = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; - -namespace Stride.Shaders.Parser.Analysis -{ - internal class StrideSemanticAnalysis : StrideTypeAnalysis - { - #region Static members - - /// - /// List of useful language keywords - /// - private static readonly string[] StrideKeywords = { "base", "streams", "this" }; - - #endregion - - #region Private members - - /// - /// The structure that will store all the information - /// - private StrideParsingInfo parsingInfo; - - /// - /// List of all the mixins inside the module - /// - private readonly HashSet moduleMixins = new HashSet(); - - /// - /// The module that is the context of the analysis - /// - private readonly ModuleMixin analyzedModuleMixin = null; - - /// - /// The method currently visited - /// - private MethodDeclaration currentVisitedMethod = null; - - /// - /// a flag stating if the visitor visits a sampler - /// - private bool inSampler = false; - - /// - /// Status of the assignment - /// - private AssignmentOperatorStatus currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read; - - /// - /// A flag for expanding foreach statements - /// - private bool expandForEachStatements; - - #endregion - - #region Constructor and helpers - - /// - /// Initializes a new instance of the class. - /// - /// The result - /// the context in which the analysis is set - /// the list of all the modules that are not in the inheritance hierarchy of the context - public StrideSemanticAnalysis(ParsingResult result, ModuleMixin analyzedMixin, List moduleMixinsInCompilationGroup) - : base(result) - { - analyzedModuleMixin = analyzedMixin; - - ScopeStack.First().AddDeclaration(StreamsType.ThisStreams); - - var currentScope = new ScopeDeclaration(analyzedMixin.Shader); - ScopeStack.Push(currentScope); - - currentScope.AddDeclarations(analyzedMixin.VirtualTable.Typedefs); - currentScope.AddDeclarations(analyzedMixin.VirtualTable.StructureTypes); - currentScope.AddDeclarations(analyzedMixin.VirtualTable.Variables.Select(x => x.Variable)); - currentScope.AddDeclarations(analyzedMixin.VirtualTable.Methods.Select(x => x.Method)); - currentScope.AddDeclarations(analyzedMixin.InheritanceList.Select(x => x.Shader)); - - // add the mixins in the compilation group - var sd = new ScopeDeclaration(); - ScopeStack.Push(sd); - foreach (var mixin in moduleMixinsInCompilationGroup) - { - moduleMixins.Add(mixin); - sd.AddDeclaration(mixin.Shader); - } - } - - #endregion - - #region Public static methods - - /// - /// Run the analysis - /// - /// the current context (virtual table) from mixin inheritance - /// List of all the mixin in the compilation context - /// true if the shader is correct, false otherwise - public static StrideParsingInfo RunAnalysis(ModuleMixin mixinToAnalyze, List compilationContext, bool transformForEach = false) - { - var shader = new Shader(); - shader.Declarations.Add(mixinToAnalyze.Shader); - var toParse = new ParsingResult { Shader = shader }; - var analysis = new StrideSemanticAnalysis(toParse, mixinToAnalyze, compilationContext) { parsingInfo = new StrideParsingInfo() }; - analysis.expandForEachStatements = transformForEach; - analysis.Run(); - - // look at the static classes - analysis.parsingInfo.StaticClasses.UnionWith(analysis.parsingInfo.StaticReferences.VariablesReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - analysis.parsingInfo.StaticClasses.UnionWith(analysis.parsingInfo.StaticReferences.MethodsReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - analysis.parsingInfo.StaticClasses.Remove(mixinToAnalyze); - analysis.parsingInfo.ErrorsWarnings = analysis.ParsingResult; - - return analysis.parsingInfo; - } - - #endregion - - #region Private and protected methods - - /// - /// Visits the specified shader type name. - /// - /// Name of the type. - public override Node Visit(ShaderTypeName shaderTypeName) - { - // just here to prevent a problem when a mixin class is called Texture (that creates an hlsl typename instead) - // grammar was changed accordingly - base.Visit(shaderTypeName); - return shaderTypeName; - } - - /// - /// Store the method in the correct list - /// - /// - private void StoreMethod(MethodDeclaration methodDeclaration) - { - if (!parsingInfo.ClassReferences.MethodsReferences.ContainsKey(methodDeclaration)) - parsingInfo.ClassReferences.MethodsReferences.Add(methodDeclaration, new HashSet()); - } - - /// - /// Checks that the method does not have mixin as parameter or return type - /// - /// the method. - private void CheckParamatersAndReturnType(MethodDeclaration methodDeclaration) - { - foreach (var parameter in methodDeclaration.Parameters) - { - if (parameter.Type.TypeInference.Declaration is ShaderClassType) - Error(StrideMessageCode.ErrorShaderClassTypeParameter, methodDeclaration.Span, methodDeclaration, parameter, analyzedModuleMixin.MixinName); - } - - if (methodDeclaration.ReturnType.TypeInference.Declaration is ShaderClassType) - Error(StrideMessageCode.ErrorShaderClassReturnType, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName); - } - - /// - /// Analyse the method declaration and store it in the correct list - /// - /// The MethodDeclaration - public override Node Visit(MethodDeclaration methodDeclaration) - { - currentVisitedMethod = methodDeclaration; - - if (!methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Abstract)) - Error(StrideMessageCode.ErrorMissingAbstract, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName); - if (methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Override)) - Error(StrideMessageCode.ErrorUnnecessaryOverride, methodDeclaration.Span, methodDeclaration, analyzedModuleMixin.MixinName); - - base.Visit(methodDeclaration); - PostMethodDeclarationVisit(methodDeclaration); - - return methodDeclaration; - } - - /// - /// Analyse the method definition and store it in the correct lists (based on storage and stream usage) - /// - /// the MethodDefinition - /// the input method definition - public override Node Visit(MethodDefinition methodDefinition) - { - currentVisitedMethod = methodDefinition; - - if (methodDefinition.Qualifiers.Contains(StrideStorageQualifier.Abstract)) - Error(StrideMessageCode.ErrorUnnecessaryAbstract, methodDefinition.Span, methodDefinition, analyzedModuleMixin.MixinName); - - var ret = base.Visit(methodDefinition); - - PostMethodDeclarationVisit(methodDefinition); - - return ret; - } - - /// - /// Performs operations applicable for MethodDefinition & MethodDeclaration nodes - /// - /// the method declaration or definition - private void PostMethodDeclarationVisit(MethodDeclaration methodDeclaration) - { - currentVisitedMethod = null; - StoreMethod(methodDeclaration); - CheckParamatersAndReturnType(methodDeclaration); - } - - /// - /// Visits the specified variable - /// - /// The variable - public override Node Visit(Variable variable) - { - if (inSampler) - return variable; - - if (variable.Type.IsSamplerStateType()) - inSampler = true; - - // type inference for variable - if (ParentNode is ForEachStatement) - { - var forEachStatement = ParentNode as ForEachStatement; - if (variable == forEachStatement.Variable) - { - var finalType = forEachStatement.Collection.TypeInference.TargetType; - if (finalType is ArrayType) - finalType = (finalType as ArrayType).Type; - variable.Type = finalType; - if ((forEachStatement.Collection.TypeInference.Declaration as Variable).Qualifiers.Contains(StorageQualifier.Extern)) - variable.Qualifiers |= StorageQualifier.Extern; - } - } - - base.Visit(variable); - - inSampler = false; - - if (currentVisitedMethod == null) - { - if (variable.InitialValue is VariableReferenceExpression) - { - var vre = variable.InitialValue as VariableReferenceExpression; - if (vre.Name.Text == "stage") - { - if (variable.Qualifiers.Contains(StorageQualifier.Extern) && variable.Type.TypeInference.Declaration is ClassType) - parsingInfo.StageInitializedVariables.Add(variable); - else - Error(StrideMessageCode.ErrorStageInitNotClassType, variable.Span, variable, analyzedModuleMixin.MixinName); - } - } - - if (variable.Qualifiers.Contains(StorageQualifier.Extern)) - { - var varType = variable.Type; - if (varType is ArrayType) - varType = (varType as ArrayType).Type; - - if (!(varType.TypeInference.Declaration is ClassType)) - Error(StrideMessageCode.ErrorExternNotClassType, variable.Span, variable, analyzedModuleMixin.MixinName); - } - - // should not happen because extern keyword is set in the ShaderCompilationContext - if (!variable.Qualifiers.Contains(StorageQualifier.Extern) && variable.Type.TypeInference.Declaration is ClassType) - Error(StrideMessageCode.ErrorMissingExtern, variable.Span, variable, analyzedModuleMixin.MixinName); - } - - // check var type - if (variable.Type is VarType) - { - if (variable.InitialValue == null) - Error(StrideMessageCode.ErrorVarNoInitialValue, variable.Span, variable, analyzedModuleMixin.MixinName); - else if (variable.InitialValue.TypeInference.TargetType == null) - Error(StrideMessageCode.ErrorVarNoTypeFound, variable.Span, variable, analyzedModuleMixin.MixinName); - else - { - variable.Type = variable.InitialValue.TypeInference.TargetType.ResolveType(); - // If we have a var type referencing a generic type, try to use the non-generic version of it - if (variable.Type is GenericBaseType) - { - variable.Type = ((GenericBaseType)variable.Type).ToNonGenericType(); - } - } - } - - if (variable.ContainsTag(StrideTags.ShaderScope)) - { - if (!parsingInfo.ClassReferences.VariablesReferences.ContainsKey(variable)) - parsingInfo.ClassReferences.VariablesReferences.Add(variable, new HashSet()); - } - - if (currentVisitedMethod != null && !(ParentNode is ForEachStatement)) - { - if (FindFinalType(variable.Type) is ShaderClassType) - Error(StrideMessageCode.ErrorShaderVariable, variable.Span, variable, analyzedModuleMixin.MixinName); - } - - return variable; - } - - /// - /// Find the base type in case of array - /// - /// the type to explore - /// the base type - private static TypeBase FindFinalType(TypeBase typeBase) - { - if (typeBase is ArrayType) - return FindFinalType((typeBase as ArrayType).Type); - return typeBase.ResolveType(); - } - - /// - /// store the Typedef - /// - /// the Typedef - public override Node Visit(Typedef typedef) - { - base.Visit(typedef); - - if (currentVisitedMethod != null) - Error(StrideMessageCode.ErrorTypedefInMethod, typedef.Span, typedef, currentVisitedMethod, analyzedModuleMixin.MixinName); - - parsingInfo.Typedefs.Add(typedef); - - return typedef; - } - - /// - /// Visit a technique, store an error - /// - /// the technique - public override Node Visit(Technique technique) - { - Error(StrideMessageCode.ErrorTechniqueFound, technique.Span, technique, analyzedModuleMixin.MixinName); // TODO: remove because parsing may fail before - - return technique; - } - - /// - /// Visits the specified member reference. - /// - /// The member reference. - protected override void CommonVisit(MemberReferenceExpression memberReference) - { - var targetDecl = memberReference.Target.TypeInference.Declaration; - var variableTargetDecl = targetDecl as Variable; - - if (memberReference.Target is IndexerExpression) - variableTargetDecl = (memberReference.Target as IndexerExpression).Target.TypeInference.Declaration as Variable; - - if (variableTargetDecl != null && memberReference.TypeInference.Declaration == null && variableTargetDecl.Qualifiers.Contains(StorageQualifier.Extern)) // from composition - { - var varType = variableTargetDecl.Type; - if (varType is ArrayType) - varType = (varType as ArrayType).Type; - - var matchingDecls = FindDeclarationsFromObject(varType, memberReference.Member.Text).ToList(); - var varDecl = matchingDecls.OfType().FirstOrDefault(); - var methodDecl = matchingDecls.OfType().FirstOrDefault(); - var shaderDecl = matchingDecls.OfType().FirstOrDefault(); - - if (varDecl != null) - { - memberReference.TypeInference.Declaration = varDecl; - memberReference.TypeInference.TargetType = varDecl.Type.ResolveType(); - - if (!(ParentNode is MemberReferenceExpression) || varType is VectorType) // do not store the intermediate references, only the last one - except for vector types - { - if (IsStageInitMember(memberReference)) - memberReference.SetTag(StrideTags.StageInitRef, null); - else - memberReference.SetTag(StrideTags.ExternRef, null); - } - } - else if (shaderDecl != null) - { - memberReference.TypeInference.Declaration = shaderDecl; - memberReference.TypeInference.TargetType = shaderDecl.ResolveType(); - } - else if (methodDecl == null) - { - Error(StrideMessageCode.ErrorExternMemberNotFound, memberReference.Span, memberReference, variableTargetDecl.Type, analyzedModuleMixin.MixinName); - } - } - else if (targetDecl is ShaderClassType) - FindMemberTypeReference(targetDecl as ShaderClassType, memberReference); - else - base.CommonVisit(memberReference); - - if (IsStreamMember(memberReference)) - { - if (!(memberReference.Target.TypeInference.TargetType is VectorType - || memberReference.Target.TypeInference.TargetType != null && memberReference.Target.TypeInference.TargetType.TypeInference.TargetType is VectorType)) // do not look deeper in vector types - CheckStreamMemberReference(memberReference); - - if (memberReference.TypeInference.Declaration is Variable) - { - var refAsVariable = memberReference.TypeInference.Declaration as Variable; - if (!(refAsVariable.Type is MemberName) && !refAsVariable.Qualifiers.Contains(StrideStorageQualifier.Stream) && !refAsVariable.Qualifiers.Contains(StrideStorageQualifier.PatchStream)) - Error(StrideMessageCode.ErrorExtraStreamsPrefix, memberReference.Span, memberReference, refAsVariable, analyzedModuleMixin.MixinName); - } - } - else if (IsMutableMember(memberReference)) - { - CheckStreamMemberReference(memberReference); - } - else if (memberReference.TypeInference.Declaration is Variable) - { - var variableDecl = (Variable)memberReference.TypeInference.Declaration; - if (variableDecl.Qualifiers.Contains(StrideStorageQualifier.Stream) || variableDecl.Qualifiers.Contains(StrideStorageQualifier.PatchStream)) - Error(StrideMessageCode.ErrorMissingStreamsStruct, memberReference.Span, memberReference, analyzedModuleMixin.MixinName); - } - - if (memberReference.TypeInference.Declaration is Variable) // TODO: check if it is a variable whose scope is inside the hierarchy - { - var isExtern = HasExternQualifier(memberReference); - var shouldStoreExpression = !(ParentNode is MemberReferenceExpression) ^ (memberReference.TypeInference.TargetType is VectorType || memberReference.TypeInference.TargetType is MatrixType); - if (shouldStoreExpression && isExtern) - memberReference.SetTag(StrideTags.ExternRef, null); - - if (!isExtern && memberReference.Target.TypeInference.Declaration is ShaderClassType && !ReferenceEquals(analyzedModuleMixin.Shader, memberReference.Target.TypeInference.Declaration) && analyzedModuleMixin.InheritanceList.All(x => !ReferenceEquals(x.Shader, memberReference.Target.TypeInference.Declaration))) - memberReference.SetTag(StrideTags.StaticRef, null); - - var varDecl = (Variable)memberReference.TypeInference.Declaration; - if (currentVisitedMethod != null && currentVisitedMethod.Qualifiers.Contains(StorageQualifier.Static) && varDecl != null && varDecl.GetTag(StrideTags.BaseDeclarationMixin) != null) - Error(StrideMessageCode.ErrorNonStaticReferenceInStaticMethod, memberReference.Span, currentVisitedMethod, varDecl, analyzedModuleMixin.MixinName); - } - - // Add to variable references list - AddToVariablesReference(memberReference); - } - - /// - /// Analyze the stream and store the datas - /// - /// the MemberReferenceExpression - private void CheckStreamMemberReference(MemberReferenceExpression memberReference) - { - // search the reference variable that should be stream - var decl = memberReference.TypeInference.Declaration ?? FindDeclarations(memberReference.Member.Text).FirstOrDefault(); - var variableDecl = decl as Variable; - var mixinDecl = decl as ShaderClassType; - - if (variableDecl != null) - { - memberReference.TypeInference.Declaration = variableDecl; - memberReference.TypeInference.TargetType = variableDecl.Type.ResolveType(); - } - else if (mixinDecl != null) - { - memberReference.TypeInference.Declaration = mixinDecl; - memberReference.TypeInference.TargetType = mixinDecl.ResolveType(); - } - else - { - Error(StrideMessageCode.ErrorStreamNotFound, memberReference.Span, memberReference.Member.Text, analyzedModuleMixin.MixinName); - } - } - - /// - /// Finds the member type reference. - /// - /// Type of the shader - /// The member reference. - protected void FindMemberTypeReference(ShaderClassType shaderDecl, MemberReferenceExpression memberReference) - { - var mixin = moduleMixins.FirstOrDefault(x => x.Shader == shaderDecl); - if (mixin != null) - { - var shader = mixin.InheritanceList.FirstOrDefault(x => x.MixinName == memberReference.Member.Text); - if (shader != null) - { - memberReference.TypeInference.Declaration = shader.Shader; - memberReference.TypeInference.TargetType = shader.Shader; - return; - } - - var variableDecl = mixin.VirtualTable.Variables.FirstOrDefault(x => x.Variable.Name.Text == memberReference.Member.Text); - if (variableDecl != null) - { - var isStream = IsStreamMember(memberReference); - if (!isStream || variableDecl.Variable.Qualifiers.Contains(StrideStorageQualifier.Stream)) - { - memberReference.TypeInference.Declaration = variableDecl.Variable; - memberReference.TypeInference.TargetType = variableDecl.Variable.Type.ResolveType(); - return; - } - } - - if (ParentNode is MethodInvocationExpression) - { - var invocationExpression = ParentNode as MethodInvocationExpression; - if (ReferenceEquals(invocationExpression.Target, memberReference)) - { - var methodDecl = mixin.VirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(invocationExpression)); - if (methodDecl != null) - { - memberReference.TypeInference.Declaration = methodDecl; - invocationExpression.TypeInference.TargetType = methodDecl.ReturnType.ResolveType(); - return; - } - } - } - } - } - - /// - /// Finds the declaration inside the compositions and calls the base method too - /// - /// the type of the object - /// the name of its member - /// a collection of all possible members - protected override IEnumerable FindDeclarationsFromObject(TypeBase typeBase, string memberName) - { - if (typeBase == null) - { - yield break; - } - - // look if it is a composition - // the typebase is unique for each extern so there is no need to look for the right class - //var mixin = compositionsVirtualTables.FirstOrDefault(x => ReferenceEquals(x.Key.ResolveType(), typeBase.ResolveType())).Value; - - var mixin = moduleMixins.FirstOrDefault(x => x.MixinName == typeBase.Name.Text); - - if (mixin != null) - { - foreach (var member in mixin.VirtualTable.Variables.Where(x => x.Variable.Name.Text == memberName)) - yield return member.Variable; - - foreach (var member in mixin.VirtualTable.Methods.Where(x => x.Method.Name.Text == memberName)) - yield return member.Method; - - if (mixin.MixinName == memberName) - yield return mixin.Shader; - - foreach (var dep in mixin.InheritanceList.Where(x => x.MixinName == memberName).Select(x => x.Shader)) - yield return dep; - } - else - { - foreach (var item in base.FindDeclarationsFromObject(typeBase.ResolveType(), memberName)) - yield return item; - } - } - - - /// - /// Finds a list of declaration by its name. - /// - /// The name. - /// A list of declaration - protected override IEnumerable FindDeclarations(string name) - { - var res = base.FindDeclarations(name); - - if (res.OfType().Any(x => analyzedModuleMixin.PotentialConflictingVariables.Contains(x))) - Error(StrideMessageCode.ErrorVariableNameAmbiguity, new SourceSpan(), name, analyzedModuleMixin.MixinName); - if (res.OfType().Any(x => analyzedModuleMixin.PotentialConflictingMethods.Contains(x))) - Error(StrideMessageCode.ErrorMethodNameAmbiguity, new SourceSpan(), name, analyzedModuleMixin.MixinName); - - return res; - } - - /// - /// Calls the base method but modify the stream usage beforehand - /// - /// the method expression - public override Node Visit(MethodInvocationExpression expression) - { - expression.SetTag(StrideTags.CurrentShader, analyzedModuleMixin); - - base.Visit(expression); - - if (expression.TypeInference.TargetType == null && expression.Target.TypeInference.Declaration == null) - Error(StrideMessageCode.ErrorMissingMethod, expression.Span, expression, analyzedModuleMixin.MixinName); - else if (!Equals(expression.TypeInference.Declaration, expression.Target.TypeInference.Declaration)) - expression.TypeInference.Declaration = expression.Target.TypeInference.Declaration; - - var methodDecl = expression.Target.TypeInference.Declaration as MethodDeclaration; - - if (methodDecl != null) - { - expression.Target.TypeInference.TargetType = (expression.Target.TypeInference.Declaration as MethodDeclaration).ReturnType.ResolveType(); - expression.TypeInference.TargetType = expression.Target.TypeInference.TargetType.ResolveType(); - - if (currentVisitedMethod.Qualifiers.Contains(StorageQualifier.Static) - && !methodDecl.Qualifiers.Contains(StorageQualifier.Static) - && methodDecl.GetTag(StrideTags.BaseDeclarationMixin) != null) - { - Error(StrideMessageCode.ErrorNonStaticCallInStaticMethod, expression.Span, currentVisitedMethod, methodDecl, analyzedModuleMixin.MixinName); - } - } - - // add to the reference list - AddToMethodsReferences(expression); - - if (methodDecl != null) - expression.Target.SetTag(StrideTags.VirtualTableReference, methodDecl.GetTag(StrideTags.VirtualTableReference)); - - return expression; - } - - /// - /// Analyse the MethodInvocationExpression, link to the base calls, remove "this" from virtual calls, store in the correct list for later analysis - /// - /// the method expression - /// the method name - /// the special declarations - protected override void ProcessMethodInvocation(MethodInvocationExpression expression, string methodName, List declarations) - { - bool callBaseProcessMethodInvocation = true; - bool isNotBaseCall = true; - - // check if it is a base/this invocation - var memberReferenceExpression = expression.Target as MemberReferenceExpression; - if (memberReferenceExpression != null) - { - var variableReferenceExpression = memberReferenceExpression.Target as VariableReferenceExpression; - if (variableReferenceExpression != null) - { - switch (variableReferenceExpression.Name.Text) - { - case "base": - { - parsingInfo.BaseMethodCalls.Add(expression); - isNotBaseCall = false; - callBaseProcessMethodInvocation = false; - - // get a base method declaration - MethodDeclaration baseMethod = null; - foreach (var mixin in analyzedModuleMixin.InheritanceList) - { - baseMethod = mixin.LocalVirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression)); - if (baseMethod != null) - break; - } - if (baseMethod == null) - baseMethod = analyzedModuleMixin.LocalVirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression)); - - if (baseMethod != null) - { - expression.TypeInference.TargetType = baseMethod.ReturnType.ResolveType(); - expression.Target.TypeInference.Declaration = baseMethod; - } - else - Error(StrideMessageCode.ErrorImpossibleBaseCall, memberReferenceExpression.Span, expression, analyzedModuleMixin.MixinName); - break; - } - case "this": - { - // remove "this" keyword - var vre = new VariableReferenceExpression(memberReferenceExpression.Member); - expression.Target = vre; - - callBaseProcessMethodInvocation = false; - - // get top method declaration - var topMethod = analyzedModuleMixin.VirtualTable.Methods.Select(x => x.Method).FirstOrDefault(x => x.IsSameSignature(expression)); - if (topMethod != null) - { - expression.TypeInference.TargetType = topMethod.ReturnType.ResolveType(); - expression.Target.TypeInference.Declaration = topMethod; - } - else - Error(StrideMessageCode.ErrorImpossibleVirtualCall, memberReferenceExpression.Span, expression, analyzedModuleMixin.MixinName, analyzedModuleMixin.MixinName); - - memberReferenceExpression = null; - - break; - } - } - - } - - if (expression.Target is MemberReferenceExpression) - { - var typeCall = (expression.Target as MemberReferenceExpression).Target.TypeInference.TargetType; - if (typeCall is ShaderClassType) - declarations.AddRange(FindDeclarationsFromObject(typeCall, memberReferenceExpression.Member)); - } - } - - // call base - if (callBaseProcessMethodInvocation) - base.ProcessMethodInvocation(expression, methodName, declarations); - - var methodDecl = expression.Target.TypeInference.Declaration as MethodDeclaration; - var isBuiltIn = true; - - if (methodDecl != null) - { - // check if it is a recursive call - if (ReferenceEquals(currentVisitedMethod, expression.Target.TypeInference.Declaration)) // How to handle "this" keyword? - Error(StrideMessageCode.ErrorCyclicMethod, currentVisitedMethod.Span, currentVisitedMethod, analyzedModuleMixin.MixinName); - - // check if it is a build-in method - isBuiltIn = !methodDecl.ContainsTag(StrideTags.ShaderScope); - - if (memberReferenceExpression != null) - { - var varDecl = memberReferenceExpression.Target.TypeInference.Declaration as Variable; - if (memberReferenceExpression.Target is IndexerExpression) - varDecl = (memberReferenceExpression.Target as IndexerExpression).Target.TypeInference.Declaration as Variable; - - if (varDecl != null && varDecl.Qualifiers.Contains(StorageQualifier.Extern)) - { - if (IsStageInitMember(memberReferenceExpression)) - expression.SetTag(StrideTags.StageInitRef, null); - else - expression.SetTag(StrideTags.ExternRef, null); - } - - var shaderDecl = memberReferenceExpression.Target.TypeInference.Declaration as ShaderClassType; - if (shaderDecl != null && shaderDecl != analyzedModuleMixin.Shader && analyzedModuleMixin.InheritanceList.All(x => x.Shader != shaderDecl)) - expression.SetTag(StrideTags.StaticRef, null); - } - - if (!isBuiltIn) - { - // store if not a base call - if (isNotBaseCall && !expression.ContainsTag(StrideTags.ExternRef) && !expression.ContainsTag(StrideTags.StageInitRef) && !expression.ContainsTag(StrideTags.StaticRef)) - parsingInfo.ThisMethodCalls.Add(expression); - - if (methodDecl.Qualifiers.Contains(StrideStorageQualifier.Stage)) - parsingInfo.StageMethodCalls.Add(expression); - } - } - } - - /// - /// Tests the arguments of the method - check streams type here - /// - /// the argument typebase - /// the expected typebase - /// the argument type - /// the expected type - /// the score of the overload - /// true if the overload is correct, false otherwise - protected override bool TestMethodInvocationArgument(TypeBase argTypeBase, TypeBase expectedTypeBase, TypeBase argType, TypeBase expectedType, ref int score) - { - if (argTypeBase == StreamsType.Streams && expectedTypeBase == StreamsType.Output) // streams and output are the same - return true; - if (argTypeBase.IsStreamsType() && expectedType.IsStreamsType()) - return argTypeBase == expectedType; - - return base.TestMethodInvocationArgument(argTypeBase, expectedTypeBase, argType, expectedType, ref score); - } - - /// - /// Analyse the AssignmentExpression to correctly infer the potential stream usage - /// - /// the AssignmentExpression - public override Node Visit(AssignmentExpression assignmentExpression) - { - if (currentAssignmentOperatorStatus != AssignmentOperatorStatus.Read) - Error(StrideMessageCode.ErrorNestedAssignment, assignmentExpression.Span, assignmentExpression, analyzedModuleMixin.MixinName); - - assignmentExpression.Value = (Expression)VisitDynamic(assignmentExpression.Value); - currentAssignmentOperatorStatus = (assignmentExpression.Operator != AssignmentOperator.Default) ? AssignmentOperatorStatus.ReadWrite : AssignmentOperatorStatus.Write; - - assignmentExpression.Target = (Expression)VisitDynamic(assignmentExpression.Target); - - currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read; - - return assignmentExpression; - } - - /// - /// Checks that the name does not bear many meanings - /// - /// the variable reference expression to check to check - private void CheckNameConflict(VariableReferenceExpression variableReferenceExpression) - { - var name = variableReferenceExpression.Name.Text; - - // First, check in the local virtual table (which we assume is resolved first) - var varCount = analyzedModuleMixin.LocalVirtualTable.Variables.Count(x => x.Variable.Name.Text == name); - if (varCount == 1) - return; - - // NOTE: a VariableReferenceExpression means that we are in the context of the currently analyzed mixin - // we need to check that a variable does not appear twice - varCount = analyzedModuleMixin.VirtualTable.Variables.Count(x => x.Variable.Name.Text == name); - - if (varCount > 1) - Error(StrideMessageCode.ErrorVariableNameAmbiguity, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName); - } - - /// - /// Analyse the VariableReferenceExpression, detects streams, propagate type inference, get stored in the correct list for later analysis - /// - /// the VariableReferenceExpression - public override Node Visit(VariableReferenceExpression variableReferenceExpression) - { - // HACK: force types on base, this and stream keyword to eliminate errors in the log and use the standard type inference - var name = variableReferenceExpression.Name.Text; - if (name == "base") - { - variableReferenceExpression.TypeInference.Declaration = analyzedModuleMixin.Shader; - variableReferenceExpression.TypeInference.TargetType = analyzedModuleMixin.Shader; - return variableReferenceExpression; - } - if (name == "this") - { - variableReferenceExpression.TypeInference.Declaration = analyzedModuleMixin.Shader; - variableReferenceExpression.TypeInference.TargetType = analyzedModuleMixin.Shader; - return variableReferenceExpression; - } - if (name == "stage") - { - if (!(ParentNode is Variable && (ParentNode as Variable).InitialValue == variableReferenceExpression)) - Error(StrideMessageCode.ErrorStageOutsideVariable, ParentNode.Span, ParentNode, analyzedModuleMixin.MixinName); - - return variableReferenceExpression; - } - if (name == StreamsType.ThisStreams.Name.Text) - { - variableReferenceExpression.TypeInference.Declaration = StreamsType.ThisStreams; - variableReferenceExpression.TypeInference.TargetType = StreamsType.ThisStreams.Type; - } - - // check if the variable is double-defined - if (!StrideKeywords.Contains(variableReferenceExpression.Name.Text)) - CheckNameConflict(variableReferenceExpression); - - base.Visit(variableReferenceExpression); - - var varDecl = variableReferenceExpression.TypeInference.Declaration as Variable; - - if (varDecl != null) - { - // because the parent classes do not do this all the time - if (variableReferenceExpression.TypeInference.TargetType == null) - variableReferenceExpression.TypeInference.TargetType = (variableReferenceExpression.TypeInference.Declaration as Variable).Type.ResolveType(); - - if (varDecl.ContainsTag(StrideTags.ShaderScope)) - { - // stream variable should be called within the streams scope - if (varDecl.Qualifiers.Contains(StrideStorageQualifier.Stream) || varDecl.Qualifiers.Contains(StrideStorageQualifier.PatchStream)) - Error(StrideMessageCode.ErrorMissingStreamsStruct, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName); - } - } - - var isMethodName = defaultDeclarations.Any(x => x.Name.Text == variableReferenceExpression.Name.Text); - - if (!StrideKeywords.Contains(variableReferenceExpression.Name.Text) && variableReferenceExpression.TypeInference.Declaration == null && !inSampler && !isMethodName) - Error(StrideMessageCode.ErrorMissingVariable, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName); - - // update function static status - if (!inSampler && !isMethodName && variableReferenceExpression.TypeInference.Declaration == null) - Error(StrideMessageCode.ErrorNoTypeInference, variableReferenceExpression.Span, variableReferenceExpression, analyzedModuleMixin.MixinName); - - if (currentVisitedMethod != null && currentVisitedMethod.Qualifiers.Contains(StorageQualifier.Static) && varDecl != null && varDecl.GetTag(StrideTags.BaseDeclarationMixin) != null) - Error(StrideMessageCode.ErrorNonStaticReferenceInStaticMethod, variableReferenceExpression.Span, currentVisitedMethod, varDecl, analyzedModuleMixin.MixinName); - - // Add to the variables references list - AddToVariablesReference(variableReferenceExpression); - - return variableReferenceExpression; - } - - /// - /// Find the type of the expression - /// - /// the indexer expression - public override void ProcessIndexerExpression(IndexerExpression indexerExpression) - { - var targetType = indexerExpression.Target.TypeInference.TargetType; - - if (targetType is ClassType && (targetType.Name.Text == "InputPatch" || targetType.Name.Text == "OutputPatch" || targetType.Name.Text == "PointStream" || targetType.Name.Text == "StructuredBuffer" || targetType.Name.Text == "RWStructuredBuffer")) - indexerExpression.TypeInference.TargetType = (targetType as ClassType).GenericArguments[0].ResolveType(); - else - base.ProcessIndexerExpression(indexerExpression); - - if (!(indexerExpression.Index is LiteralExpression) && indexerExpression.Target.TypeInference.Declaration is Variable) - { - var varDecl = indexerExpression.Target.TypeInference.Declaration as Variable; - if (varDecl.Qualifiers.Contains(StorageQualifier.Extern)) - Error(StrideMessageCode.ErrorIndexerNotLiteral, indexerExpression.Span, indexerExpression, analyzedModuleMixin.MixinName); - } - } - - /// - /// Visit an interface to send an error - /// - /// the interface. - public override Node Visit(InterfaceType interfaceType) - { - Error(StrideMessageCode.ErrorInterfaceFound, interfaceType.Span, interfaceType, analyzedModuleMixin.MixinName); - return interfaceType; - } - - /// - /// Visit a structure and store its definition - /// - /// the structure definition - public override Node Visit(StructType structType) - { - if (structType.ContainsTag(StrideTags.ShaderScope)) - parsingInfo.StructureDefinitions.Add(structType); - - return base.Visit(structType); - } - - /// - /// Visit a generic type and test that it has no shader class type - /// - /// the generic type - public override Node Visit(GenericType genericType) - { - base.Visit(genericType); - - foreach (var param in genericType.Parameters.OfType()) - { - if (param.TypeInference.TargetType is ShaderClassType) - Error(StrideMessageCode.ErrorMixinAsGeneric, param.Span, param, genericType, analyzedModuleMixin.MixinName); - } - - return genericType; - } - - /// - /// Adds the expression to the reference list of the variable - /// - /// the Expression - private void AddToVariablesReference(Expression expression) - { - var variable = expression.TypeInference.Declaration as Variable; - if (variable != null && variable.ContainsTag(StrideTags.ShaderScope)) - { - if (expression.ContainsTag(StrideTags.StaticRef) || variable.Qualifiers.Contains(StorageQualifier.Static)) - parsingInfo.StaticReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); - else if (expression.ContainsTag(StrideTags.ExternRef)) - parsingInfo.ExternReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); - else if (expression.ContainsTag(StrideTags.StageInitRef)) - parsingInfo.StageInitReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); - else - parsingInfo.ClassReferences.InsertVariable(variable, new ExpressionNodeCouple(expression, ParentNode)); - } - else - { - parsingInfo.NavigableNodes.Add(expression); - } - } - - /// - /// Adds the method reference to the list of methods references - /// - /// the method reference expression - private void AddToMethodsReferences(MethodInvocationExpression expression) - { - var methodDecl = expression.Target.TypeInference.Declaration as MethodDeclaration; - if (methodDecl != null && methodDecl.ContainsTag(StrideTags.ShaderScope)) - { - if (expression.ContainsTag(StrideTags.StaticRef) || methodDecl.Qualifiers.Contains(StorageQualifier.Static)) - parsingInfo.StaticReferences.InsertMethod(methodDecl, expression); - else if (expression.ContainsTag(StrideTags.ExternRef)) - parsingInfo.ExternReferences.InsertMethod(methodDecl, expression); - else if (expression.ContainsTag(StrideTags.StageInitRef)) - parsingInfo.StageInitReferences.InsertMethod(methodDecl, expression); - else - parsingInfo.ClassReferences.InsertMethod(methodDecl, expression); - } - else - { - parsingInfo.NavigableNodes.Add(expression); - } - } - - public override Node Visit(ShaderClassType shaderClassType) - { - base.Visit(shaderClassType); - - // Allow to navigate to base classes - foreach (var baseClass in shaderClassType.BaseClasses) - { - var firstOrDefault = analyzedModuleMixin.InheritanceList.FirstOrDefault(moduleMixin => moduleMixin.Shader.Name.Text == baseClass.Name.Text); - if (firstOrDefault != null) - { - var declaration = firstOrDefault.Shader; - baseClass.TypeInference.Declaration = declaration; - } - - parsingInfo.NavigableNodes.Add(baseClass); - } - - return shaderClassType; - } - - public override Node Visit(TypeName typeName) - { - var newTypeName = (TypeBase)base.Visit(typeName); - - if (newTypeName.TypeInference.Declaration != null) - { - parsingInfo.NavigableNodes.Add(typeName); - } - return newTypeName; - } - - /// - /// Visits the ForEachStatement Node and collects information from it. - /// - /// The ForEachStatement - public override Node Visit(ForEachStatement forEachStatement) - { - if (expandForEachStatements) - { - // run analysis on collection - VisitDynamic(forEachStatement.Collection); - - var inference = forEachStatement.Collection.TypeInference.Declaration as Variable; - if (!(inference != null && inference.Type is ArrayType)) - return forEachStatement; - - if ((inference.Type as ArrayType).Dimensions.Count > 1) - { - Error(StrideMessageCode.ErrorMultiDimArray, forEachStatement.Span, inference, forEachStatement, analyzedModuleMixin.MixinName); - return forEachStatement; - } - - var dim = (int)((inference.Type as ArrayType).Dimensions.FirstOrDefault() as LiteralExpression).Value; - - var result = new StatementList(); - for (int i = 0; i < dim; ++i) - { - var cloned = forEachStatement.DeepClone(); - var replace = new StrideReplaceExtern(cloned.Variable, new IndexerExpression(cloned.Collection, new LiteralExpression(i))); - replace.Run(cloned.Body); - result.Add(cloned.Body); - } - - VisitDynamic(result); - return result; - } - else - { - base.Visit(forEachStatement); - parsingInfo.ForEachStatements.Add(new StatementNodeCouple(forEachStatement, ParentNode)); - return forEachStatement; - } - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// if set to true [is binary operator]. - /// - /// The implicit conversion between between to two types - /// - protected override TypeBase GetBinaryImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right, bool isBinaryOperator) - { - if (left.ResolveType().IsStreamsType() || right.ResolveType().IsStreamsType()) - return StreamsType.Streams; - - return base.GetBinaryImplicitConversionType(span, left, right, isBinaryOperator); - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// The implicit conversion between between to two types - protected override TypeBase GetMultiplyImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right) - { - if (left.ResolveType().IsStreamsType() || right.ResolveType().IsStreamsType()) - return StreamsType.Streams; - - return base.GetMultiplyImplicitConversionType(span, left, right); - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// The implicit conversion between between to two types - protected override TypeBase GetDivideImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right) - { - if (left.ResolveType().IsStreamsType() || right.ResolveType().IsStreamsType()) - return StreamsType.Streams; - - return base.GetDivideImplicitConversionType(span, left, right); - } - - /// - /// Test if the expression is from a stage nitialized one - /// - /// the expression - /// true if it is the case, false otherwise - private bool IsStageInitMember(Expression expression) - { - if (expression != null) - return parsingInfo.StageInitializedVariables.Contains(expression.TypeInference.Declaration) || (expression is MemberReferenceExpression && IsStageInitMember((expression as MemberReferenceExpression).Target)); - - return false; - } - - #endregion - - #region Private static helper functions - - - /// - /// Look for extern qualifier in expression typeinference - /// - /// the expression - /// true if there is a reference to an extern variable - private static bool HasExternQualifier(Expression expression) - { - var varDecl = expression.TypeInference.Declaration as Variable; - if (varDecl != null && varDecl.Qualifiers.Contains(StorageQualifier.Extern)) - return !(varDecl.InitialValue is VariableReferenceExpression) || (varDecl.InitialValue as VariableReferenceExpression).Name.Text != "stage"; - - if (expression is MemberReferenceExpression) - return HasExternQualifier((expression as MemberReferenceExpression).Target); - return false; - } - - /// - /// Checks if expression is a stream - /// - /// the Expression - /// true if it is a stream, false otherwise - private static bool IsStreamMember(MemberReferenceExpression expression) - { - if (expression != null) - { - var targetType = expression.Target.TypeInference.TargetType; - if (targetType != null && targetType.IsStreamsType()) - return true; - - // iterate until the base "class" is found and compare it to "streams" - var target = expression.Target; - while (target is MemberReferenceExpression) - target = (target as MemberReferenceExpression).Target; - - var variableReferenceExpression = target as VariableReferenceExpression; - return variableReferenceExpression != null && (variableReferenceExpression.Name == StreamsType.ThisStreams.Name || (variableReferenceExpression.TypeInference.TargetType != null && variableReferenceExpression.TypeInference.TargetType.IsStreamsType())); - } - return false; - } - - /// - /// Tests if a MemberReferenceExpression is a reference to a stream from an Input/Output type - /// - /// the expression to analyze - /// true if it is a member of an Input/Output type - private static bool IsMutableMember(MemberReferenceExpression expression) - { - var targetType = expression.Target.TypeInference.TargetType as ObjectType; - return targetType != null && targetType.IsStreamsType() && targetType.IsStreamsMutable(); - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Analysis/StrideTypeAnalysis.cs b/sources/engine/Stride.Shaders.Parser/Analysis/StrideTypeAnalysis.cs deleted file mode 100644 index 68e934791a..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Analysis/StrideTypeAnalysis.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Analysis.Hlsl; -using Stride.Core.Shaders.Parser; - -namespace Stride.Shaders.Parser.Analysis -{ - internal class StrideTypeAnalysis : HlslSemanticAnalysis - { - #region Contructor - - public StrideTypeAnalysis(ParsingResult result) - : base(result) - { - SetupHlslAnalyzer(); - } - - #endregion - - public void Run(ShaderClassType shaderClassType) - { - Visit(shaderClassType); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/CompositionDictionary.cs b/sources/engine/Stride.Shaders.Parser/Mixins/CompositionDictionary.cs deleted file mode 100644 index f6cdb549e9..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/CompositionDictionary.cs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections; -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class CompositionDictionary : IDictionary> - { - private Dictionary Variables; - - private List> Compositions; - - public CompositionDictionary() - { - Variables = new Dictionary(); - Compositions = new List>(); - } - - public IEnumerator>> GetEnumerator() - { - return new Enumerator(this); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public void Add(KeyValuePair> item) - { - Add(item.Key, item.Value); - } - - public void Clear() - { - Variables.Clear(); - Compositions.Clear(); - } - - public bool Contains(KeyValuePair> item) - { - var index = Variables[item.Key]; - return ReferenceEquals(Compositions[index], item.Value); - } - - public void CopyTo(KeyValuePair>[] array, int arrayIndex) - { - for (var i = arrayIndex; i < array.Length; ++i) - Add(array[i].Key, array[i].Value); - } - - public bool Remove(KeyValuePair> item) - { - // no need to implement that - throw new NotImplementedException(); - } - - public int Count - { - get - { - return Variables.Count; - } - } - - public bool IsReadOnly - { - get - { - return false; - } - } - - public bool ContainsKey(Variable key) - { - return Variables.ContainsKey(key); - } - - public void Add(Variable key, List value) - { - var newIndex = Compositions.Count; - Compositions.Add(value); - Variables.Add(key, newIndex); - } - - public bool Remove(Variable key) - { - throw new NotImplementedException(); - } - - public bool TryGetValue(Variable key, out List value) - { - int index; - if (Variables.TryGetValue(key, out index) && index < Compositions.Count) - { - value = Compositions[index]; - return true; - } - value = null; - return false; - } - - public List this[Variable key] - { - get - { - var index = Variables[key]; - return Compositions[index]; - } - set - { - int index; - if (Variables.TryGetValue(key, out index)) - Compositions[index] = value; - else - Add(key, value); - } - } - - public ICollection Keys - { - get - { - return Variables.Keys; - } - } - - public ICollection> Values - { - get - { - return Compositions; - } - } - - class Enumerator : IEnumerator>> - { - private CompositionDictionary compositionDictionary; - private IEnumerator> enumerator; - - public Enumerator(CompositionDictionary dict) - { - compositionDictionary = dict; - enumerator = compositionDictionary.Variables.GetEnumerator(); - } - - public void Dispose() - { - enumerator.Dispose(); - compositionDictionary = null; - } - - public bool MoveNext() - { - return enumerator.MoveNext(); - } - - public void Reset() - { - enumerator.Reset(); - } - - public KeyValuePair> Current - { - get - { - var cur = enumerator.Current; - return new KeyValuePair>(cur.Key, compositionDictionary[cur.Key]); - } - } - - object IEnumerator.Current - { - get - { - return Current; - } - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ExpressionSimplifierVisitor.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ExpressionSimplifierVisitor.cs deleted file mode 100644 index ad72359297..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ExpressionSimplifierVisitor.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class ExpressionSimplifierVisitor : ShaderWalker - { - private readonly ExpressionEvaluator evaluator; - - public ExpressionSimplifierVisitor() - : base(true, true) - { - evaluator = new ExpressionEvaluator(); - } - - public void Run(Shader shader) - { - Visit(shader); - } - - public override void Visit(StatementList statementList) - { - for (int i = 0; i < statementList.Count; i++) - { - var statement = statementList[i]; - var ifStatement = statement as IfStatement; - if (ifStatement != null) - { - var result = evaluator.Evaluate(ifStatement.Condition); - if (result.HasErrors) - { - continue; - } - statementList[i] = result.Value == 1.0 ? ifStatement.Then : ifStatement.Else; - if (statementList[i] == null) - { - statementList.RemoveAt(i); - } - i--; - } - } - - base.Visit(statementList); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/MethodDeclarationShaderCouple.cs b/sources/engine/Stride.Shaders.Parser/Mixins/MethodDeclarationShaderCouple.cs deleted file mode 100644 index 9978170363..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/MethodDeclarationShaderCouple.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Mixins -{ - [DataContract] - internal class MethodDeclarationShaderCouple - { - public MethodDeclaration Method; - public ShaderClassType Shader; - - public MethodDeclarationShaderCouple() : this(null, null){} - - public MethodDeclarationShaderCouple(MethodDeclaration method, ShaderClassType shader) - { - Method = method; - Shader = shader; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/MixinVirtualTable.cs b/sources/engine/Stride.Shaders.Parser/Mixins/MixinVirtualTable.cs deleted file mode 100644 index aab02d79d5..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/MixinVirtualTable.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class MixinVirtualTable : ShaderVirtualTable - { - #region Public properties - - /// - /// List of all declared methods - /// - public HashSet Methods { get; } = new(); - - /// - /// List of all declared Variables - /// - public HashSet Variables { get; } = new(); - - /// - /// List of all the structure definitions - /// - public List StructureTypes { get; } = new(); // list instead of hashset because order can be important - - /// - /// List of all the Typedefs - /// - public List Typedefs { get; } = new(); // list instead of hashset because order can be important - - #endregion - - #region Public methods - - /// - /// Merge with a local virtual table = need to check override keywords - /// - /// the virtual table to add - /// the name of the mixin - /// the error logger - public void MergeWithLocalVirtualTable(MixinVirtualTable virtualTable, string mixinName, LoggerResult log) - { - foreach (var method in virtualTable.Methods) - { - var methodDecl = Methods.LastOrDefault(x => x.Method.IsSameSignature(method.Method)); - if (methodDecl != null) - { - var isBaseMethod = method.Shader.BaseClasses.Any(x => x.Name.Text == methodDecl.Shader.Name.Text); - - if (isBaseMethod) - { - if (methodDecl.Method is MethodDefinition) - { - if (!method.Method.Qualifiers.Contains(StrideStorageQualifier.Override)) - { - log.Error(StrideMessageCode.ErrorMissingOverride, method.Method.Span, method.Method, mixinName); - continue; - } - } - // Require override on method implementing abstract definition - // We explicitly disallowed this in the past ("override" keyword forbidden when implementing abstract methods) - // but we actually want it to better follow standard C# abstract/override - else if (!method.Method.Qualifiers.Contains(StrideStorageQualifier.Override)) - { - log.Warning(StrideMessageCode.WarningMissingOverrideKeyword, method.Method.Span, method.Method, mixinName); - continue; - } - } - - Methods.Remove(methodDecl); - } - else - { - if (method.Method.Qualifiers.Contains(StrideStorageQualifier.Override)) - { - log.Error(StrideMessageCode.ErrorNoMethodToOverride, method.Method.Span, method.Method, mixinName); - continue; - } - } - - Methods.Add(method); - - // TODO: handle declarations vs definitions - } - - Variables.UnionWith(virtualTable.Variables.Where(x => !Variables.Contains(x))); - StructureTypes.AddRange(virtualTable.StructureTypes.Where(x => !StructureTypes.Contains(x))); - Typedefs.AddRange(virtualTable.Typedefs.Where(x => !Typedefs.Contains(x))); - } - - /// - /// Check the name conflict between the two virtual tables - /// - public bool CheckNameConflict(MixinVirtualTable virtualTable, LoggerResult log) - { - var conflict = false; - - // Note: we allow conflicts for static variables - foreach (var variable in virtualTable.Variables.Where(variable => !variable.Variable.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Static) && Variables.Any(x => x.Variable.Name.Text == variable.Variable.Name.Text))) - { - log.Error(StrideMessageCode.ErrorVariableNameConflict, variable.Variable.Span, variable.Variable, ""); - conflict = true; - } - - return conflict; - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixin.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixin.cs deleted file mode 100644 index 4215c91abb..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixin.cs +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Stride.Core; -using Stride.Shaders.Parser.Analysis; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Mixins -{ - [DebuggerDisplay("ModuleMixin {MixinName}")] - [DataContract] - internal class ModuleMixin - { - #region Public members - - /// - /// The name of the mixin - /// - public string MixinName; - - /// - /// The name of the mixin - /// - public string MixinGenericName; - - /// - /// The shader AST - /// - public ShaderClassType Shader = null; - - /// - /// the virtual table before inheritance - /// - public MixinVirtualTable LocalVirtualTable = new MixinVirtualTable(); - - /// - /// the virtual table after inheritance - /// - public MixinVirtualTable VirtualTable = new MixinVirtualTable(); - - /// - /// List of all the other declarations - /// - public List RemainingNodes = new List(); - - /// - /// List of all the base mixins - /// - public List BaseMixins = new List(); - - /// - /// List of all the classes dependencies - /// - public List InheritanceList = new List(); - - /// - /// List of all the needed mixins to perform semantic analysis - /// - public HashSet MinimalContext = null; - - /// - /// List of all the variables dependencies - /// - public Dictionary VariableDependencies = new Dictionary(); - - /// - /// List of all the variable that are initialized at "stage" - /// - public Dictionary StageInitVariableDependencies = new Dictionary(); - - /// - /// Current class member references - /// - public ReferencesPool ClassReferences = new ReferencesPool(); - - /// - /// Static references - /// - public ReferencesPool StaticReferences = new ReferencesPool(); - - /// - /// Static references - /// - public ReferencesPool ExternReferences = new ReferencesPool(); - - /// - /// References through stage init variables - /// - public ReferencesPool StageInitReferences = new ReferencesPool(); - - /// - /// The result of the parsing - /// - public StrideParsingInfo ParsingInfo { get; set; } - - /// - /// Occurrence ID in the inheritance tree - /// - public int OccurrenceId = 0; - - /// - /// List of variables that share their name i.e. potential conflicting variables - /// - public HashSet PotentialConflictingVariables = new HashSet(); - - /// - /// List of methods that share their signature i.e. potential conflicting methods - /// - public HashSet PotentialConflictingMethods = new HashSet(); - - /// - /// A boolean stating that all the members are stage - /// - public bool StageOnlyClass = false; - - /// - /// A flag to state if the mixin dependencies has been analyzed yet - /// - public AnalysisStatus DependenciesStatus = AnalysisStatus.None; - - /// - /// A flag to state if the mixin type analysis was performed. - /// - public AnalysisStatus TypeAnalysisStatus = AnalysisStatus.None; - - /// - /// A flag to state if the module mixin was built. - /// - public AnalysisStatus ModuleMixinBuildStatus = AnalysisStatus.None; - - /// - /// A flag to state if the mixin virtual table was created - /// - public AnalysisStatus VirtualTableStatus = AnalysisStatus.None; - - /// - /// A flag to state if the mixin semantic analysis was performed - /// - public AnalysisStatus SemanticAnalysisStatus = AnalysisStatus.None; - - #endregion - - #region Constructors - - /// - /// Constructor - /// - /// the shader AST - public void SetShaderAst(ShaderClassType shader) - { - if (Shader != null) - throw new Exception("[ModuleMixin.SetShaderAst] Shader has already been set"); - Shader = shader; - MixinName = shader.Name.Text; - } - - #endregion - - #region Public methods - - /// - /// Finds the method in the mixin - /// - /// >The expression of the method reference - /// a collection of the base methods if found - public IEnumerable FindMethod(MethodInvocationExpression expression) - { - foreach (var method in LocalVirtualTable.Methods) - { - if (method.Method.IsSameSignature(expression) && method.Method is MethodDefinition) - yield return method; - } - } - - /// - /// Finds the top method - /!\ this is a hack because the mixin may not be analyzed yet /!\ - /// - /// The expression of the method reference - /// The base method if found - public IEnumerable FindTopThisFunction(MethodInvocationExpression expression) - { - foreach (var method in FindMethod(expression)) - yield return method; - - for (int i = InheritanceList.Count - 1; i >= 0; --i) - { - foreach (var method in InheritanceList[i].FindMethod(expression)) - yield return method; - } - } - - /// - /// Finds the same variable in the ModuleMixin - /// - /// the variable name - /// the variable declaration if found - public IEnumerable FindVariableByName(string variableName) - { - return LocalVirtualTable.Variables.Where(x => x.Variable.Name.Text == variableName); - } - - /// - /// Find all the variables with this name - /// - /// the name of the variable - /// A list of all the variables - public List FindAllVariablesByName(string variableName) - { - var resList = FindVariableByName(variableName).ToList(); - - for (int i = InheritanceList.Count - 1; i >= 0; --i) - resList.AddRange(InheritanceList[i].FindVariableByName(variableName)); - - return resList; - } - - /// - /// Get the overloaded method from one of its base declaration - /// - /// the MethodDeclaration - /// the overloaded MethodDeclaration - public MethodDeclaration GetMethodFromDeclaration(MethodDeclaration methodDeclaration) - { - var info = (VTableReference)methodDeclaration.GetTag(StrideTags.VirtualTableReference); - return VirtualTable.GetMethod(info.Shader, info.Slot); - } - - /// - /// Get the overloaded method from its call - /// - /// the calling Expression - /// the overloaded MethodDeclaration - public MethodDeclaration GetMethodFromExpression(Expression expression) - { - var info = (VTableReference)expression.GetTag(StrideTags.VirtualTableReference); - return VirtualTable.GetMethod(info.Shader, info.Slot); - } - - /// - /// Get the base MethodDeclaration from its call and the mixin where the call is performed - /// - /// the calling expression - /// the mixin where the call is performed - /// the base MethodDeclaration - public MethodDeclaration GetBaseMethodFromExpression(Expression expression, ModuleMixin mixin) - { - var info = (VTableReference)expression.GetTag(StrideTags.VirtualTableReference); - var thisMethod = VirtualTable.GetMethod(info.Shader, info.Slot); - - if (thisMethod == null) - return null; - - var startIndex = mixin == this ? InheritanceList.Count : InheritanceList.IndexOf(mixin); - - for (int i = startIndex - 1; i >= 0; --i) - { - var dep = InheritanceList[i]; - var array = VirtualTable.VirtualTableGroup[dep.MixinName]; - for (int j = 0; j < array.Length; ++j) - { - var method = array[j]; - if (method == thisMethod) - return dep.VirtualTable.VirtualTableGroup[dep.MixinName][j]; - } - } - return null; - } - - #endregion - } - - /// - /// A status needed to analyze the mixin in the correct order within a compilation module - /// - public enum AnalysisStatus - { - None, - InProgress, - Cyclic, - Error, - Complete - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixinInfo.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixinInfo.cs deleted file mode 100644 index a70241db4d..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ModuleMixinInfo.cs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; - -using Stride.Core.Storage; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - [DebuggerDisplay("Mixin: {mixinName}")] - internal class ModuleMixinInfo - { - #region Private members - - /// - /// The name of the mixin - /// - private string mixinName = ""; - - /// - /// The ShaderClassType - /// - private ShaderClassType mixinAst; - - #endregion - - #region Public members and properties - - /// - /// The ShaderClassSource to load - /// - public ShaderSource ShaderSource { get; set; } - - /// - /// The name of the mixin (property) - /// - public string MixinName { get { return mixinName; } } - - /// - /// The name of the mixin with its hashed code (property) - /// - public string MixinGenericName; - - /// - /// The log stored by this mixin info. - /// - public readonly LoggerResult Log; - - /// - /// The ShaderClassType (property) - /// - public ShaderClassType MixinAst - { - get - { - return mixinAst; - } - set - { - mixinAst = value; - mixinName = mixinAst.Name.Text; - } - } - - /// - /// Tests if this instance is a of the specified type name - /// - /// The type name to test - /// true if same type name - public bool IsShaderClass(string typeName) - { - var classSource = ShaderSource as ShaderClassCode; - if (classSource == null) - { - return false; - } - return classSource.ClassName == typeName; - } - - /// - /// The ModuleMixin - /// - public ModuleMixin Mixin = new ModuleMixin(); - - /// - /// A flag stating that the mixin is instanciated - /// - public bool Instanciated { get; set; } - - /// - /// a flag checking that the check for replacement has be done - /// - public bool ReplacementChecked = false; - - /// - /// the source hash - /// - public ObjectId SourceHash; - - /// - /// the SHA1 hash of the source - /// - public ObjectId HashPreprocessSource; - - /// - /// The macros used for this mixin - /// - public Stride.Core.Shaders.Parser.ShaderMacro[] Macros = new Stride.Core.Shaders.Parser.ShaderMacro[0]; - - /// - /// the list of all the necessary MixinInfos to compile the shader - /// - public HashSet MinimalContext = new HashSet(); - - /// - /// The referenced shaders. Used to invalidate shaders. - /// - public HashSet ReferencedShaders = new HashSet(); - - #endregion - - public ModuleMixinInfo() - { - Log = new LoggerResult(); - Instanciated = true; - } - - #region Public methods - - public ModuleMixinInfo Copy(Stride.Core.Shaders.Parser.ShaderMacro[] macros) - { - var mixinInfo = new ModuleMixinInfo(); - mixinInfo.ShaderSource = ShaderSource; - mixinInfo.MixinAst = MixinAst; - mixinInfo.MixinGenericName = MixinGenericName; - mixinInfo.Mixin = Mixin; - mixinInfo.Instanciated = Instanciated; - mixinInfo.HashPreprocessSource = HashPreprocessSource; - mixinInfo.Macros = macros; - - return mixinInfo; - } - - public bool AreEqual(ShaderSource shaderSource, Stride.Core.Shaders.Parser.ShaderMacro[] macros) - { - return ShaderSource.Equals(shaderSource) && macros.All(macro => Macros.Any(x => x.Name == macro.Name && x.Definition == macro.Definition)) && Macros.All(macro => macros.Any(x => x.Name == macro.Name && x.Definition == macro.Definition)); - } - - #endregion - - #region Static members - - /// - /// Cleans the identifiers (i.e. make them use the minimal string) - /// - /// The list of identifier - public static void CleanIdentifiers(List genList) - { - foreach (var gen in genList.OfType()) - { - gen.Text = gen.Value.Value.ToString(); - } - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ReferencesPool.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ReferencesPool.cs deleted file mode 100644 index d5136d6d55..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ReferencesPool.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Stride.Core; -using Stride.Shaders.Parser.Analysis; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Ast.Stride; - -namespace Stride.Shaders.Parser.Mixins -{ - [DebuggerDisplay("Variables[{VariablesReferences.Count}] Methods[{MethodsReferences.Count}]")] - [DataContract] - internal class ReferencesPool - { - private Dictionary> variablesReferences = new(); - private Dictionary> methodsReferences = new(); - - /// - /// List of all the variable references - /// - [DataMember] - public Dictionary> VariablesReferences => variablesReferences; - - /// - /// List of all the variable references - /// - [DataMember] - public Dictionary> MethodsReferences => methodsReferences; - - /// - /// Merge the argument references into this one - /// - /// the ReferencePool - public void Merge(ReferencesPool pool) - { - // merge the VariablesReferences - foreach (var variableReference in pool.VariablesReferences) - { - if (!VariablesReferences.ContainsKey(variableReference.Key)) - VariablesReferences.Add(variableReference.Key, new HashSet()); - - VariablesReferences[variableReference.Key].UnionWith(variableReference.Value); - } - // merge the MethodsReferences - foreach (var methodReference in pool.MethodsReferences) - { - if (!MethodsReferences.ContainsKey(methodReference.Key)) - MethodsReferences.Add(methodReference.Key, new HashSet()); - - MethodsReferences[methodReference.Key].UnionWith(methodReference.Value); - } - } - - /// - /// Regen the keys because they could have been modified - /// - public void RegenKeys() - { - variablesReferences = VariablesReferences.ToDictionary(variable => variable.Key, variable => variable.Value); - methodsReferences = MethodsReferences.ToDictionary(method => method.Key, variable => variable.Value); - } - - /// - /// Insert a variable reference - /// - /// the variable - /// the reference - public void InsertVariable(Variable variable, ExpressionNodeCouple expression) - { - if (!VariablesReferences.ContainsKey(variable)) - VariablesReferences.Add(variable, new HashSet()); - - // Also add all the variables in that buffer so that they are not removed - var cbuffer = (ConstantBuffer)variable.GetTag(StrideTags.ConstantBuffer); - if (cbuffer != null) - { - foreach (var otherVariable in cbuffer.Members.OfType()) - { - if (!VariablesReferences.ContainsKey(otherVariable)) - VariablesReferences.Add(otherVariable, new HashSet()); - } - } - - VariablesReferences[variable].Add(expression); - } - - /// - /// Insert a method reference - /// - /// the method - /// the reference - public void InsertMethod(MethodDeclaration methodDeclaration, MethodInvocationExpression expression) - { - if (!MethodsReferences.ContainsKey(methodDeclaration)) - MethodsReferences.Add(methodDeclaration, new HashSet()); - MethodsReferences[methodDeclaration].Add(expression); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderCompilationContext.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderCompilationContext.cs deleted file mode 100644 index a5b4fbe359..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderCompilationContext.cs +++ /dev/null @@ -1,557 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core; -using Stride.Core.Extensions; -using Stride.Shaders.Parser.Analysis; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class ShaderCompilationContext - { - #region Private static members - - /// - /// A lock to perform a thread safe analysis of the mixins. - /// - private static readonly Object AnalysisLock = new Object(); - - #endregion - - #region Public members - - /// - /// List of all the mixins - /// - public HashSet MixinInfos = new HashSet(); - - /// - /// Log of all the warnings and errors - /// - private LoggerResult ErrorWarningLog; - - #endregion - - #region Constructor - - /// - /// Default constructor for cloning - /// - public ShaderCompilationContext(LoggerResult log) - { - if (log == null) throw new ArgumentNullException("log"); - - ErrorWarningLog = log; - } - - #endregion - - #region Public methods - - public void Run(){} - - /// - /// Runs the first step of the analysis on the context - /// - /// the context - public void Preprocess(HashSet mixinInfos) - { - MixinInfos = mixinInfos; - - BuildModuleMixins(MixinInfos); - } - - /// - /// Specifically analyze a module - /// - /// the ModuleMixinInfo - public void Analyze(ModuleMixinInfo mixinInfo) - { - ModuleSemanticAnalysisPerMixin(mixinInfo); - } - - /// - /// Get the module mixin based on the ShaderSource - /// - /// the ShaderSource - /// the ModuleMixin - public ModuleMixin GetModuleMixinFromShaderSource(ShaderSource shaderSource) - { - var found = MixinInfos.FirstOrDefault(x => x.ShaderSource.Equals(shaderSource)); - return found == null ? null : found.Mixin; - } - - #endregion - - #region Private methods - - /// - /// Get all the declarations of all the mixins - /// - /// list of ModuleMixinInfo - private void BuildModuleMixins(HashSet mixinInfos) - { - // type analysis - foreach (var mixinInfo in mixinInfos) - PerformTypeAnalysis(mixinInfo); - foreach (var mixinInfo in mixinInfos) - BuildModuleMixin(mixinInfo); - - lock (AnalysisLock) - { - // reset error status of mixins so we get the same error messages for each compilation - foreach (var mixinInfo in mixinInfos) - { - var mixin = mixinInfo.Mixin; - if (mixin.DependenciesStatus == AnalysisStatus.Error || mixin.DependenciesStatus == AnalysisStatus.Cyclic) - mixin.DependenciesStatus = AnalysisStatus.None; - } - - foreach (var mixinInfo in mixinInfos) - BuildMixinDependencies(mixinInfo); - - // build Virtual tables - foreach (var mixinInfo in mixinInfos) - BuildVirtualTables(mixinInfo); - } - } - - /// - /// Get all the declarations in the mixin - /// - /// The mixin info - private void BuildModuleMixin(ModuleMixinInfo mixinInfo) - { - lock (mixinInfo) - { - if (mixinInfo.Mixin.ModuleMixinBuildStatus == AnalysisStatus.Complete) - return; - - if (mixinInfo.Mixin.ModuleMixinBuildStatus != AnalysisStatus.None) - throw new Exception("BuildModuleMixin failed for mixin " + mixinInfo.MixinName); - - mixinInfo.Mixin.ModuleMixinBuildStatus = AnalysisStatus.InProgress; - - var mixinAst = mixinInfo.MixinAst; - - var moduleMixin = mixinInfo.Mixin; - moduleMixin.SetShaderAst(mixinAst); - moduleMixin.MixinGenericName = mixinInfo.MixinGenericName; - - if (mixinAst != null && mixinInfo.Instanciated) - { - var vtindex = 0; - foreach (var member in mixinAst.Members) - { - if (member is MethodDeclaration) - { - moduleMixin.LocalVirtualTable.Methods.Add(new MethodDeclarationShaderCouple(member as MethodDeclaration, mixinAst)); - member.SetTag(StrideTags.VirtualTableReference, new VTableReference { Shader = mixinInfo.MixinName, Slot = vtindex++ }); - } - else if (member is Variable) - { - var variable = member as Variable; - moduleMixin.LocalVirtualTable.Variables.Add(new VariableShaderCouple(variable, mixinAst)); - // remove null initial values - var initValue = variable.InitialValue as VariableReferenceExpression; - if (initValue != null && initValue.Name.Text == "null") - variable.InitialValue = null; - - } - else if (member is Typedef) - moduleMixin.LocalVirtualTable.Typedefs.Add(member as Typedef); - else if (member is StructType) - moduleMixin.LocalVirtualTable.StructureTypes.Add(member as StructType); - else - moduleMixin.RemainingNodes.Add(member); - - // set a tag on the members to easily recognize them from the local declarations/definitions - member.SetTag(StrideTags.ShaderScope, moduleMixin); - member.SetTag(StrideTags.BaseDeclarationMixin, mixinInfo.MixinName); - } - - // Check name conflicts - foreach (var method in moduleMixin.LocalVirtualTable.Methods) - { - if (moduleMixin.LocalVirtualTable.Methods.Count(x => x.Method.IsSameSignature(method.Method)) > 1) // 1 because the function is in the list - ErrorWarningLog.Error(StrideMessageCode.ErrorFunctionRedefined, method.Method.Span, method.Method, mixinInfo.MixinName); - - if (moduleMixin.LocalVirtualTable.Variables.Any(x => x.Variable.Name.Text == method.Method.Name.Text)) - ErrorWarningLog.Error(StrideMessageCode.ErrorFunctionVariableNameConflict, method.Method.Span, method.Method, mixinInfo.MixinName); - } - foreach (var variable in moduleMixin.LocalVirtualTable.Variables) - { - if (moduleMixin.LocalVirtualTable.Variables.Count(x => x.Variable.Name.Text == variable.Variable.Name.Text) > 1) // 1 because the function is in the list - ErrorWarningLog.Error(StrideMessageCode.ErrorFunctionVariableNameConflict, variable.Variable.Span, variable.Variable, mixinInfo.MixinName); - - if (moduleMixin.LocalVirtualTable.Methods.Any(x => x.Method.Name.Text == variable.Variable.Name.Text)) - ErrorWarningLog.Error(StrideMessageCode.ErrorVariableNameConflict, variable.Variable.Span, variable.Variable, mixinInfo.MixinName); - } - } - - moduleMixin.MinimalContext = new HashSet(mixinInfo.MinimalContext.Select(x => x.Mixin)); - - mixinInfo.Mixin.ModuleMixinBuildStatus = AnalysisStatus.Complete; - } - } - - /// - /// Get the list of dependencies for the mixin (base classes only) - /// - /// the mixin info - /// A collection of class names - private void BuildMixinDependencies(ModuleMixinInfo mixinInfo) - { - var mixin = mixinInfo.Mixin; - - if (mixin.DependenciesStatus == AnalysisStatus.Cyclic || mixin.DependenciesStatus == AnalysisStatus.Error || mixinInfo.Mixin.DependenciesStatus == AnalysisStatus.Complete) - return; - if (mixin.DependenciesStatus == AnalysisStatus.InProgress) - { - ErrorWarningLog.Error(StrideMessageCode.ErrorCyclicDependency, mixin.Shader.Span, mixin.Shader); - mixin.DependenciesStatus = AnalysisStatus.Cyclic; - return; - } - if (mixin.DependenciesStatus == AnalysisStatus.None) - { - mixin.DependenciesStatus = AnalysisStatus.InProgress; - - foreach (var baseClass in mixin.Shader.BaseClasses) - { - // search based on class name and macros. It is enough since a ShaderMixinSource only have ShaderClassSource as base mixin (and no ShaderMixinSource that may redefine the macros) - var bcInfo = MixinInfos.FirstOrDefault(x => x.MixinName == baseClass.Name.Text && AreMacrosEqual(x.Macros, mixinInfo.Macros)); - - if (bcInfo == null) - { - ErrorWarningLog.Error(StrideMessageCode.ErrorDependencyNotInModule, baseClass.Span, baseClass, mixin.MixinName); - mixin.DependenciesStatus = AnalysisStatus.Error; - return; - } - - var bc = bcInfo.Mixin; - - BuildMixinDependencies(bcInfo); - if (bc.DependenciesStatus == AnalysisStatus.Error || bc.DependenciesStatus == AnalysisStatus.Cyclic) - { - mixin.DependenciesStatus = AnalysisStatus.Error; - return; - } - - foreach (var dependency in bc.InheritanceList) - { - if (!mixin.InheritanceList.Contains(dependency)) - mixin.InheritanceList.Add(dependency); - } - - if (!mixin.InheritanceList.Contains(bc)) - mixin.InheritanceList.Add(bc); - - mixin.BaseMixins.Add(bc); - - if (!bcInfo.Instanciated) - mixinInfo.Instanciated = false; - } - - // do not look for extern keyword but for type name - foreach (var variable in mixin.LocalVirtualTable.Variables) - { - var variableTypeName = variable.Variable.Type.Name.Text; - if (variable.Variable.Type is ArrayType) // support for array of externs - variableTypeName = (variable.Variable.Type as ArrayType).Type.Name.Text; - - var baseClassInfo = MixinInfos.FirstOrDefault(x => x.MixinName == variableTypeName); - if (baseClassInfo != null) - { - variable.Variable.Qualifiers |= Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern; // add the extern keyword but simpler analysis in the future - if (variable.Variable.InitialValue is VariableReferenceExpression && (variable.Variable.InitialValue as VariableReferenceExpression).Name.Text == "stage") - mixin.StageInitVariableDependencies.Add(variable.Variable, baseClassInfo.Mixin); - else - mixin.VariableDependencies.Add(variable.Variable, baseClassInfo.Mixin); - - if (variable.Variable.Type is ArrayType) - { - var typeArray = variable.Variable.Type as ArrayType; - typeArray.Type.TypeInference.Declaration = baseClassInfo.MixinAst; - } - else - { - variable.Variable.Type.TypeInference.Declaration = baseClassInfo.MixinAst; - } - } - } - - mixin.DependenciesStatus = AnalysisStatus.Complete; - } - } - - /// - /// Performs type analysis for each mixin - /// - /// the ModuleMixinInfo - private void PerformTypeAnalysis(ModuleMixinInfo mixinInfo) - { - lock (mixinInfo) - { - if (mixinInfo.Mixin.TypeAnalysisStatus == AnalysisStatus.None) - { - mixinInfo.Mixin.TypeAnalysisStatus = AnalysisStatus.InProgress; - - // TODO: order + typedef - var typeAnalyzer = new StrideTypeAnalysis(new ParsingResult()); - typeAnalyzer.Run(mixinInfo.MixinAst); - mixinInfo.Mixin.TypeAnalysisStatus = AnalysisStatus.Complete; - } - else if (mixinInfo.Mixin.TypeAnalysisStatus != AnalysisStatus.Complete) - { - throw new Exception("Type analysis failed for mixin " + mixinInfo.MixinName); - } - } - } - - /// - /// Build the virtual table for the specified mixin - /// - /// the mixin - private void BuildVirtualTables(ModuleMixinInfo mixinInfo) - { - var mixin = mixinInfo.Mixin; - - if (mixin.VirtualTableStatus == AnalysisStatus.Error || mixin.VirtualTableStatus == AnalysisStatus.Cyclic || mixin.VirtualTableStatus == AnalysisStatus.Complete) - return; - - if (!mixinInfo.Instanciated) - return; - - foreach (var dep in mixin.InheritanceList) - { - var depInfo = MixinInfos.FirstOrDefault(x => x.Mixin == dep); - BuildVirtualTables(depInfo); - } - - // merge the virtual tables - foreach (var dep in mixin.InheritanceList) - mixin.VirtualTable.MergeWithLocalVirtualTable(dep.LocalVirtualTable, mixin.MixinName, ErrorWarningLog); - - mixin.VirtualTable.MergeWithLocalVirtualTable(mixin.LocalVirtualTable, mixin.MixinName, ErrorWarningLog); - - foreach (var dep in mixin.InheritanceList) - mixin.VirtualTable.AddVirtualTable(dep.VirtualTable, dep.MixinName, ErrorWarningLog); - mixin.VirtualTable.AddFinalDeclarations(mixin.LocalVirtualTable.Methods.Select(x => x.Method).ToList(), mixin.MixinName, ErrorWarningLog); - - foreach (var variable in mixin.VirtualTable.Variables) - { - // Compare local against local and inherited against inherited - var local = variable.Shader == mixin.Shader; - - if (mixin.VirtualTable.Variables.Any(x => (x.Shader == mixin.Shader) == local && x.Variable != variable.Variable && x.Variable.Name.Text == variable.Variable.Name.Text)) - mixin.PotentialConflictingVariables.Add(variable.Variable); - } - foreach (var method in mixin.VirtualTable.Methods) - { - // Compare local against local and inherited against inherited - var local = method.Shader == mixin.Shader; - - if (mixin.VirtualTable.Methods.Any(x => (x.Shader == mixin.Shader) == local && x.Method != method.Method && x.Method.IsSameSignature(method.Method))) - mixin.PotentialConflictingMethods.Add(method.Method); - } - - CheckStageClass(mixin); - - mixin.VirtualTableStatus = AnalysisStatus.Complete; - } - - /// - /// Check if the class is stage - /// - /// the ModuleMixin to check - private void CheckStageClass(ModuleMixin mixin) - { - mixin.StageOnlyClass = mixin.VirtualTable.Variables.All(x => x.Variable.Qualifiers.Contains(StrideStorageQualifier.Stage) - && !x.Variable.Qualifiers.Contains(StrideStorageQualifier.Compose)) // composition variable can be stage but the classes behind may not be. - && mixin.VirtualTable.Methods.All(x => x.Method.Qualifiers.Contains(StrideStorageQualifier.Stage) - && !x.Method.Qualifiers.Contains(StrideStorageQualifier.Clone)); - } - - /// - /// Performs an semantic analysis of the mixin inside its own context - /// - /// The mixin to analyze - private void ModuleSemanticAnalysisPerMixin(ModuleMixinInfo mixinInfo) - { - if (mixinInfo == null) - return; - - var mixin = mixinInfo.Mixin; - - if (mixin.DependenciesStatus != AnalysisStatus.Complete || mixin.VirtualTableStatus != AnalysisStatus.Complete) - return; - - if (mixin.SemanticAnalysisStatus == AnalysisStatus.Complete) - return; - if (mixin.SemanticAnalysisStatus == AnalysisStatus.InProgress) - { - ErrorWarningLog.Error(StrideMessageCode.ErrorCyclicDependency, mixin.Shader.Span, mixin.Shader); - return; - } - if (!mixinInfo.Instanciated) - return; - - mixin.SemanticAnalysisStatus = AnalysisStatus.InProgress; - - // analyze the base mixins - foreach (var baseClass in mixin.BaseMixins) - { - var baseClassInfo = MixinInfos.FirstOrDefault(x => x.Mixin == baseClass); - ModuleSemanticAnalysisPerMixin(baseClassInfo); - - if (baseClassInfo.Mixin.SemanticAnalysisStatus == AnalysisStatus.Error || baseClassInfo.Mixin.SemanticAnalysisStatus == AnalysisStatus.Cyclic) - { - mixin.SemanticAnalysisStatus = AnalysisStatus.Error; - return; - } - - if (!baseClassInfo.Instanciated) - { - mixinInfo.Instanciated = false; - mixin.SemanticAnalysisStatus = AnalysisStatus.None; - return; - } - - if (mixin.LocalVirtualTable.CheckNameConflict(baseClass.VirtualTable, ErrorWarningLog)) - { - mixin.SemanticAnalysisStatus = AnalysisStatus.Error; - return; - } - } - - // analyze the extern mixins - foreach (var externMixin in mixin.VariableDependencies) - { - var externMixinInfo = MixinInfos.FirstOrDefault(x => x.Mixin == externMixin.Value); - ModuleSemanticAnalysisPerMixin(externMixinInfo); - if (externMixinInfo.Mixin.SemanticAnalysisStatus == AnalysisStatus.Error || externMixinInfo.Mixin.SemanticAnalysisStatus == AnalysisStatus.Cyclic) - { - mixin.SemanticAnalysisStatus = AnalysisStatus.Error; - return; - } - } - - var compilationContext = MixinInfos.Select(x => x.Mixin).ToList(); - - mixin.ParsingInfo = StrideSemanticAnalysis.RunAnalysis(mixin, compilationContext); - - var staticStageMixins = new List(); - staticStageMixins.AddRange(mixin.ParsingInfo.StaticReferences.VariablesReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - staticStageMixins.AddRange(mixin.ParsingInfo.StaticReferences.MethodsReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - staticStageMixins.AddRange(mixin.ParsingInfo.StageInitReferences.VariablesReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - staticStageMixins.AddRange(mixin.ParsingInfo.StageInitReferences.MethodsReferences.Select(x => x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin)); - staticStageMixins.RemoveAll(x => x == mixin); - - foreach (var dep in staticStageMixins) - { - var depInfo = MixinInfos.FirstOrDefault(x => x.Mixin == dep); - ModuleSemanticAnalysisPerMixin(depInfo); - if (dep.SemanticAnalysisStatus == AnalysisStatus.Error || dep.SemanticAnalysisStatus == AnalysisStatus.Cyclic) - { - mixin.SemanticAnalysisStatus = AnalysisStatus.Error; - return; - } - } - - // check the extern stage references (but do not change the type inference) - var externList = new List(); - - // NOTE: we cannot use the members .Values of .Keys because it internally modifies the dictionary, creating a Dictionary.ValueCollection which cannot be cloned (no default constructor). - // This results in a exception in the DeepClone code. - mixin.InheritanceList.ForEach(dep => externList.AddRange(dep.VariableDependencies.Select(x => x.Value))); - externList.AddRange(mixin.VariableDependencies.Select(x => x.Value)); - externList.ForEach(ext => CheckReferencesFromExternMixin(ext, mixin)); - - mixin.ParsingInfo.ErrorsWarnings.CopyTo(ErrorWarningLog); - - mixin.SemanticAnalysisStatus = AnalysisStatus.Complete; - } - - /// - /// Check that the stage function calls are possible and that the stage declared variable have a correct type - /// - /// the mixin to look into - /// the root mixin - private void CheckReferencesFromExternMixin(ModuleMixin externMixin, ModuleMixin contextMixin) - { - // test that the root mixin has the correct type - foreach (var variable in externMixin.ParsingInfo.StageInitializedVariables) - { - if (variable.Type.Name.Text != contextMixin.MixinName && contextMixin.InheritanceList.All(x => x.MixinName == variable.Type.Name.Text)) // since it is the same AST, compare the object? - ErrorWarningLog.Error(StrideMessageCode.ErrorExternStageVariableNotFound, variable.Span, variable, externMixin.MixinName); - } - - foreach (var stageCall in externMixin.ParsingInfo.StageMethodCalls) - { - var decl = contextMixin.FindTopThisFunction(stageCall).FirstOrDefault(); - if (decl == null) - ErrorWarningLog.Error(StrideMessageCode.ErrorExternStageFunctionNotFound, stageCall.Span, stageCall, externMixin.MixinName, contextMixin.MixinName); - } - - // recursive calls - foreach (var mixin in externMixin.InheritanceList) - { - CheckReferencesFromExternMixin(mixin, contextMixin); - - foreach (var externModule in mixin.VariableDependencies) - CheckReferencesFromExternMixin(externModule.Value, contextMixin); - } - - foreach (var externModule in externMixin.VariableDependencies) - CheckReferencesFromExternMixin(externModule.Value, contextMixin); - } - - #endregion - - #region Private static methods - - /// - /// Tests the equality of the macro sets. - /// - /// The first set of macros. - /// The second set of macros. - /// True if the sets match, false otherwise. - private static bool AreMacrosEqual(Stride.Core.Shaders.Parser.ShaderMacro[] macros0, Stride.Core.Shaders.Parser.ShaderMacro[] macros1) - { - return macros0.All(macro => macros1.Any(x => x.Name == macro.Name && x.Definition == macro.Definition)) && macros1.All(macro => macros0.Any(x => x.Name == macro.Name && x.Definition == macro.Definition)); - } - - #endregion - } - - [DataContract] - internal class VTableReference - { - public string Shader = ""; - - public int Slot = -1; - - public override bool Equals(object obj) - { - var vtr = obj as VTableReference; - if (vtr == null) - return false; - - return Slot == vtr.Slot && Shader == vtr.Shader; - } - - public override int GetHashCode() - { - return Slot; - //return (Shader.GetHashCode() * 397) ^ (Slot + 2); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderDependencyVisitor.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderDependencyVisitor.cs deleted file mode 100644 index 827e3130c5..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderDependencyVisitor.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - class ShaderDependencyVisitor : ShaderWalker - { - public HashSet> FoundIdentifiers = new HashSet>(); - - public HashSet FoundClasses = new HashSet(); - - private readonly LoggerResult log; - - /// - /// Name of the classes - /// - //private HashSet shaderClassNames; - private readonly ShaderSourceManager sourceManager; - - public ShaderDependencyVisitor(LoggerResult log, ShaderSourceManager sourceManager) - : base(false, true) - { - if (log == null) throw new ArgumentNullException("log"); - if (sourceManager == null) throw new ArgumentNullException("sourceManager"); - - this.log = log; - this.sourceManager = sourceManager; - } - - public void Run(ShaderClassType shaderClassType) - { - Visit(shaderClassType); - } - - public override void Visit(IdentifierGeneric identifier) - { - base.Visit(identifier); - - FoundIdentifiers.Add(Tuple.Create(identifier, ParentNode)); - } - - public override void Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - - if (sourceManager.IsClassExists(variableReferenceExpression.Name.Text)) - FoundClasses.Add(variableReferenceExpression.Name.Text); - } - - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - base.Visit(memberReferenceExpression); - - if (sourceManager.IsClassExists(memberReferenceExpression.Member.Text)) - FoundClasses.Add(memberReferenceExpression.Member.Text); - } - - public override void DefaultVisit(Node node) - { - base.DefaultVisit(node); - - var typeBase = node as TypeBase; - if (typeBase != null) - { - if (sourceManager.IsClassExists(typeBase.Name.Text)) - { - FoundClasses.Add(typeBase.Name.Text); - } - else if (typeBase is ShaderTypeName) - { - // Special case for ShaderTypeName as we must generate an error if it is not found - log.Error(StrideMessageCode.ErrorClassNotFound, typeBase.Span, typeBase.Name.Text); - } - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyFileHelper.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyFileHelper.cs deleted file mode 100644 index 4be683a976..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyFileHelper.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace Stride.Shaders.Parser.Mixins -{ - public class ShaderKeyFileHelper - { - public static byte[] GenerateCode(string inputFileName, string inputFileContent) - { - // Always output a result into the file - string result; - try - { - Stride.Core.Shaders.Parser.ShaderMacro[] macros; - - // Changed some keywords to avoid ambiguities with HLSL and improve consistency - if (inputFileName != null && Path.GetExtension(inputFileName).ToLowerInvariant() == ".sdfx") - { - // XKFX - macros = new[] - { - new Core.Shaders.Parser.ShaderMacro("shader", "effect") - }; - } - else - { - // XKSL - macros = new[] - { - new Core.Shaders.Parser.ShaderMacro("class", "shader") - }; - } - - var parsingResult = StrideShaderParser.TryPreProcessAndParse(inputFileContent, inputFileName, macros); - - if (parsingResult.HasErrors) - { - result = "// Failed to parse the shader:\n" + parsingResult; - } - else - { - // Try to generate a mixin code. - var shaderKeyGenerator = new ShaderMixinCodeGen(parsingResult.Shader, parsingResult); - - shaderKeyGenerator.Run(); - result = shaderKeyGenerator.Text ?? string.Empty; - } - } - catch (Exception ex) - { - result = "// Unexpected exceptions occurred while generating the file\n" + ex; - } - - // We force the UTF8 to include the BOM to match VS default - var data = Encoding.UTF8.GetBytes(result); - return Encoding.UTF8.GetPreamble().Concat(data).ToArray(); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyGeneratorBase.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyGeneratorBase.cs deleted file mode 100644 index d9b726a4a5..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderKeyGeneratorBase.cs +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Linq; -using System.Globalization; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Writer; - -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; -using HlslStorageQualifier = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; - -namespace Stride.Shaders.Parser.Mixins -{ - public class ShaderKeyGeneratorBase : ShaderWriter - { - /// - /// A flag stating if the currently visited variable is a Color. - /// - protected bool IsColorStatus = false; - - /// - /// A flag stating if the currently visited variable is an array. - /// - protected bool IsArrayStatus = false; - - /// - /// A flag stating if the initial value of the variable should be processed. - /// - protected bool ProcessInitialValueStatus = false; - - /// - /// A flag indicating whether a variable must be transformed to a parameter key - /// - protected bool VariableAsParameterKey = true; - - protected bool IsSdfx = false; - - /// - /// Runs the code generation. Results is accessible from property. - /// - public virtual bool Run() - { - return true; - } - - /// - public override void Visit(Variable variable) - { - if (VariableAsParameterKey) - { - WriteVariableAsParameterKey(variable); - } - else - { - if (IsSdfx) - { - base.Visit(variable); - } - } - } - - /// - /// Visits the specified namespace block. - /// - /// The namespace block. - public override void Visit(NamespaceBlock namespaceBlock) - { - WriteLinkLine(namespaceBlock); - Write("namespace ").Write(namespaceBlock.Name); - OpenBrace(); - foreach (Node node in namespaceBlock.Body) - { - VisitDynamic(node); - } - CloseBrace(); - } - - //public override void Visit(ConstantBuffer constantBuffer) - //{ - // VisitDynamic(constantBuffer); - //} - - internal bool IsParameterKey(Variable variable) - { - // Don't generate a parameter key for variable stored storage qualifier: extern, const, compose, stream - if (variable.Qualifiers.Contains(HlslStorageQualifier.Extern) || - variable.Qualifiers.Contains(StorageQualifier.Const) || - variable.Qualifiers.Contains(StrideStorageQualifier.Compose) || - variable.Qualifiers.Contains(StrideStorageQualifier.PatchStream) || - variable.Qualifiers.Contains(StorageQualifier.GroupShared) || - variable.Qualifiers.Contains(StrideStorageQualifier.Stream)) - return false; - - // Don't generate a parameter key for [Link] or [RenameLink] - if (variable.Attributes.OfType().Any(x => x.Name == "RenameLink" || x.Name == "Link")) - return false; - - return true; - } - - protected void WriteVariableAsParameterKey(Variable variable) - { - if (!IsParameterKey(variable)) - { - return; - } - - IsColorStatus = variable.Attributes.OfType().Any(x => x.Name == "Color"); - ProcessInitialValueStatus = false; - IsArrayStatus = false; - - var variableType = variable.Attributes.OfType().Where(x => x.Name == "Type").Select(x => (string)x.Parameters[0].Value).FirstOrDefault(); - var variableMap = variable.Attributes.OfType().Where(x => x.Name == "Map").Select(x => (string)x.Parameters[0].Value).FirstOrDefault(); - - // ParameterKey shouldn't contain only the underlying type in case of arrays (we use slots) - var parameterType = variable.Type; - - string parameterKeyType; - if (IsSdfx) - { - parameterKeyType = "Permutation"; - } - else - { - while (parameterType is ArrayType) - { - parameterType = ((ArrayType)parameterType).Type; - } - - if (parameterType is ObjectType || IsTextureType(parameterType) || IsBufferType(parameterType)) - { - parameterKeyType = "Object"; - } - else - { - parameterKeyType = "Value"; - } - } - - Write($"public static readonly {parameterKeyType}ParameterKey<"); - if (variableType == null) - VisitDynamic(parameterType); - else - Write(variableType); - Write("> "); - Write(variable.Name); - Write(" = "); - if (variableMap == null) - { - Write($"ParameterKeys.New{parameterKeyType}<"); - if (variableType == null) - VisitDynamic(parameterType); - else - Write(variableType); - Write(">("); - if (ProcessInitialValueStatus && variable.InitialValue != null) - { - var initialValueString = variable.InitialValue.ToString(); - - if (initialValueString != "null") - { - if (IsArrayStatus) - { - initialValueString = variable.Type.ToString() + initialValueString; - } - - // Rename float2/3/4 to Vector2/3/4 - if (initialValueString.StartsWith("float2", StringComparison.Ordinal) || - initialValueString.StartsWith("float3", StringComparison.Ordinal) || - initialValueString.StartsWith("float4", StringComparison.Ordinal)) - { - initialValueString = initialValueString.Replace("float", "new Vector"); - } - else if (IsArrayStatus) - { - initialValueString = "new " + initialValueString; - } - - if (IsColorStatus) - { - initialValueString = initialValueString.Replace("Vector3", "Color3"); - initialValueString = initialValueString.Replace("Vector4", "Color4"); - } - } - Write(initialValueString); - } - Write(")"); - } - else - { - Write(variableMap); - } - WriteLine(";"); - - IsColorStatus = false; - IsArrayStatus = false; - ProcessInitialValueStatus = false; - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(TypeName typeName) - { - var type = typeName.ResolveType(); - if (ReferenceEquals(typeName, type)) - { - base.Visit(typeName); - ProcessInitialValueStatus = true; - } - else - { - VisitDynamic(type); - } - } - - /// - public override void Visit(ScalarType scalarType) - { - base.Visit(scalarType); - ProcessInitialValueStatus = true; - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(VectorType type) - { - var finalTypeName = "Vector" + type.Dimension; - if (IsColorStatus) - { - if (type.Dimension == 3) - finalTypeName = "Color3"; - else if (type.Dimension == 4) - finalTypeName = "Color4"; - else - throw new NotSupportedException("Color attribute is only valid for float3/float4."); - } - Write(finalTypeName); - ProcessInitialValueStatus = true; - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(MatrixType type) - { - Write("Matrix"); - ProcessInitialValueStatus = true; - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(TextureType type) - { - Write("Texture"); - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(ObjectType type) - { - if (type.IsSamplerStateType()) - Write("SamplerState"); - } - - /// - /// Visits the specified type. - /// - /// the type. - public override void Visit(ArrayType type) - { - var dimensions = type.Dimensions; - if (dimensions.Count != 1) - throw new NotSupportedException(); - /* - var expressionEvaluator = new ExpressionEvaluator(); - if (dimensions.All(x => !(x is EmptyExpression))) - { - var expressionResult = expressionEvaluator.Evaluate(dimensions[0]); - if (expressionResult.HasErrors) - throw new InvalidOperationException(); - Write(expressionResult.Value.ToString()); - } - */ - VisitDynamic(type.Type); - Write("[]"); - ProcessInitialValueStatus = true; - IsArrayStatus = true; - } - - public override void DefaultVisit(Node node) - { - base.DefaultVisit(node); - - var typeBase = node as TypeBase; - if (typeBase != null) - { - // Unhandled types only - if (!(typeBase is TypeName or ScalarType or MatrixType or TextureType or ArrayType or VarType || typeBase.IsStateType())) - { - Write(typeBase.Name); - ProcessInitialValueStatus = true; - } - } - } - - protected static bool IsStringInList(string value, params string[] list) - { - return list.Any(str => CultureInfo.InvariantCulture.CompareInfo.Compare(value, str, CompareOptions.IgnoreCase) == 0); - } - - protected static bool IsTextureType(TypeBase type) - { - // TODO we should improve AST type system - return type is TextureType || (type is GenericBaseType && type.Name.Text.Contains("Texture")); - } - - protected static bool IsBufferType(TypeBase type) - { - // TODO we should improve AST type system - return (type is GenericBaseType && type.Name.Text.Contains("Buffer")) || type.IsByteAddressBufferType(); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderLoader.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderLoader.cs deleted file mode 100644 index fe9b454e7e..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderLoader.cs +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -using Stride.Core.Extensions; -using Stride.Core.Storage; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Grammar.Stride; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - /// - /// Provides methods for loading a . - /// - public class ShaderLoader - { - private readonly Dictionary loadedShaders = new Dictionary(); - - /// - /// Gets the source manager. - /// - /// The source manager. - public ShaderSourceManager SourceManager { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The source manager. - /// sourceManager - public ShaderLoader(ShaderSourceManager sourceManager) - { - if (sourceManager == null) - throw new ArgumentNullException("sourceManager"); - - SourceManager = sourceManager; - } - - /// - /// Deletes the shader cache for the specified shaders. - /// - /// The modified shaders. - public void DeleteObsoleteCache(HashSet modifiedShaders) - { - var keysToRemove = new HashSet(); - foreach (var shaderName in modifiedShaders) - { - foreach (var key in loadedShaders.Keys) - { - if (key.TypeName == shaderName) - keysToRemove.Add(key); - } - } - - foreach (var key in keysToRemove) - loadedShaders.Remove(key); - - keysToRemove.Clear(); - - SourceManager.DeleteObsoleteCache(modifiedShaders); - } - - public class LoadedShaderClassType - { - public ShaderClassType Type; - - public string SourcePath; - - public ObjectId SourceHash; - - public ObjectId PreprocessedSourceHash; - - public bool IsInstanciated; - } - - /// - /// Loads the . - /// - /// The shader class source. - /// The shader macros. - /// The log to output error logs. - /// - /// A ShaderClassType or null if there was some errors. - /// shaderClassSource - public LoadedShaderClassType LoadClassSource(ShaderClassCode shaderClassSource, Stride.Core.Shaders.Parser.ShaderMacro[] shaderMacros, LoggerResult log, bool autoGenericInstances) - { - if (shaderClassSource == null) throw new ArgumentNullException("shaderClassSource"); - - string generics = null; - if (shaderClassSource.GenericArguments != null) - { - generics = ""; - foreach (var gen in shaderClassSource.GenericArguments) - generics += "___" + gen; - } - var shaderClassType = LoadShaderClass(shaderClassSource, generics, log, shaderMacros); - - if (shaderClassType == null) - return null; - - // Instantiate generic class - if (shaderClassSource.GenericArguments != null || (shaderClassType.Type.ShaderGenerics.Count > 0 && autoGenericInstances)) - { - if (shaderClassType.IsInstanciated) - return shaderClassType; - - // If we want to automatically generate a generic instance (in case we just want to parse and verify the generic) - if (autoGenericInstances) - { - shaderClassSource.GenericArguments = new string[shaderClassType.Type.ShaderGenerics.Count]; - for (int i = 0; i < shaderClassSource.GenericArguments.Length; i++) - { - var variableGeneric = shaderClassType.Type.ShaderGenerics[i]; - shaderClassSource.GenericArguments[i] = GetDefaultConstValue(variableGeneric); - } - } - - if (shaderClassSource.GenericArguments.Length != shaderClassType.Type.ShaderGenerics.Count) - { - log.Error(StrideMessageCode.WrongGenericNumber, shaderClassType.Type.Span, shaderClassSource.ClassName); - return null; - } - - // check the name of the generics - foreach (var generic in shaderClassType.Type.ShaderGenerics) - { - foreach (var genericCompare in shaderClassType.Type.ShaderGenerics.Where(x => x != generic)) - { - if (generic.Name.Text == genericCompare.Name.Text) - log.Error(StrideMessageCode.SameNameGenerics, generic.Span, generic, genericCompare, shaderClassSource.ClassName); - } - } - - if (log.HasErrors) - return null; - - // When we use an actual generic instance, we replace the name with the name of the class + a hash of the generic parameters - if (!autoGenericInstances) - { - var className = GenerateGenericClassName(shaderClassSource); - shaderClassType.Type.Name = new Identifier(className); - } - - var genericAssociation = CreateGenericAssociation(shaderClassType.Type.ShaderGenerics, shaderClassSource.GenericArguments); - var identifierGenerics = GenerateIdentifierFromGenerics(genericAssociation); - var expressionGenerics = GenerateGenericsExpressionValues(shaderClassType.Type.ShaderGenerics, shaderClassSource.GenericArguments); - StrideClassInstantiator.Instantiate(shaderClassType.Type, expressionGenerics, identifierGenerics, autoGenericInstances, log); - shaderClassType.Type.ShaderGenerics.Clear(); - shaderClassType.IsInstanciated = true; - } - return shaderClassType; - } - - private static string GetDefaultConstValue(Variable variable) - { - var variableType = variable.Type; - if (variableType == ScalarType.Bool) - { - return "false"; - } - else if (variableType is IGenericStringArgument) - { - return "\"\""; // to allow parsing of string - } - return "0"; - } - - - Dictionary CreateGenericAssociation(List genericParameters, object[] genericArguments) - { - var result = new Dictionary(); - for (var i = 0; i < genericParameters.Count; ++i) - { - result.Add(genericParameters[i].Name.Text, genericArguments[i]); - } - return result; - } - - Dictionary GenerateIdentifierFromGenerics(Dictionary generics) - { - var result = new Dictionary(); - foreach (var genericPair in generics) - { - var generic = genericPair.Value; - if (generic is Identifier) - result.Add(genericPair.Key, (Identifier)generic); - else //if (generic is string) - { - var stringGeneric = generic.ToString();// generic as string; - var stringParts = stringGeneric.Split('.'); - if (stringParts.Length == 1) - result.Add(genericPair.Key, new Identifier(stringGeneric)); - else - { - var dotIdentifier = new IdentifierDot(); - dotIdentifier.Identifiers = stringParts.Select(x => new Identifier(x)).ToList(); - result.Add(genericPair.Key, dotIdentifier); - } - } - //else - // throw new Exception("Unsupported generic."); - } - return result; - } - - private Dictionary GenerateGenericsExpressionValues(List genericParameters, object[] genericArguments) - { - var result = new Dictionary(); - - if (genericArguments.Length > 0) - { - var allGenerics = new StringBuilder(); - bool allEmpty = true; - for (int i = 0; i < genericArguments.Length; i++) - { - var generic = genericArguments[i]; - var genericText = generic.ToString(); - - if (!string.IsNullOrWhiteSpace(genericText)) - { - allEmpty = false; - } - if (i > 0) - { - allGenerics.Append(','); - } - - // TODO: If a generic is empty, we should throw an error - allGenerics.Append(genericText); - } - - if (allEmpty) - { - for (var i = 0; i < genericArguments.Length; ++i) - result.Add(genericParameters[i].Name.Text, null); - } - else - { - var node = CreateExpressionFromString(allGenerics.ToString()); - - if (node is ExpressionList) - { - var nodeList = (ExpressionList)node; - if (nodeList.Count != genericArguments.Length) - throw new Exception("mismatch generic length after parsing"); - - for (var i = 0; i < genericArguments.Length; ++i) - result.Add(genericParameters[i].Name.Text, nodeList[i]); - } - else - { - if (genericArguments.Length != 1) - throw new Exception("mismatch generic length after parsing"); - result.Add(genericParameters[0].Name.Text, node); - } - } - } - return result; - } - - Expression CreateExpressionFromString(string name) - { - // TODO: catch errors - var result = ShaderParser.GetParser(ShaderParser.GetGrammar().ExpressionNonTerminal).Parser.Parse(name, ""); - return (Expression)result.Root.AstNode; - } - - private LoadedShaderClassType LoadShaderClass(ShaderClassCode classSource, string generics, LoggerResult log, Stride.Core.Shaders.Parser.ShaderMacro[] macros = null) - { - var type = classSource.ClassName; - if (type == null) throw new ArgumentNullException("type"); - var shaderSourceKey = new ShaderSourceKey(type, generics, macros); - - lock (loadedShaders) - { - // Already instantiated - LoadedShaderClassType shaderClass; - - if (loadedShaders.TryGetValue(shaderSourceKey, out shaderClass)) - { - return shaderClass; - } - - ShaderSourceManager.ShaderSourceWithHash shaderSource; - - // Load shader source code - if (classSource is ShaderClassString shaderClassString) - shaderSource = SourceManager.LoadShaderSource(type, shaderClassString.ShaderSourceCode); - else - shaderSource = SourceManager.LoadShaderSource(type); - - string preprocessedSource; - try - { - preprocessedSource = PreProcessor.Run(shaderSource.Source, shaderSource.Path, macros); - } - catch (Exception ex) - { - log.Error(MessageCode.ErrorUnexpectedException, new SourceSpan(new SourceLocation(shaderSource.Path, 0, 1, 1),1), ex); - return null; - } - - byte[] byteArray = Encoding.UTF8.GetBytes(preprocessedSource); - var hashPreprocessSource = ObjectId.FromBytes(byteArray); - - // Compile - var parsingResult = StrideShaderParser.TryParse(preprocessedSource, shaderSource.Path); - parsingResult.CopyTo(log); - - if (parsingResult.HasErrors) - { - return null; - } - - var shader = parsingResult.Shader; - - // As shaders can be embedded in namespaces, get only the shader class and make sure there is only one in a sdsl. - var shaderClassTypes = StrideShaderParser.GetShaderClassTypes(shader.Declarations).ToList(); - if (shaderClassTypes.Count != 1) - { - var sourceSpan = new SourceSpan(new SourceLocation(shaderSource.Path, 0, 0, 0), 1); - if (shaderClassTypes.Count > 1) - { - sourceSpan = shaderClassTypes[1].Span; - } - log.Error(StrideMessageCode.ShaderMustContainSingleClassDeclaration, sourceSpan, type); - return null; - } - - shaderClass = new LoadedShaderClassType(); - shaderClass.Type = shaderClassTypes.First(); - shaderClass.SourcePath = shaderSource.Path; - shaderClass.SourceHash = shaderSource.Hash; - shaderClass.PreprocessedSourceHash = hashPreprocessSource; - shaderClass.IsInstanciated = false; - - // TODO: We should not use Console. Change the way we log things here - // Console.WriteLine("Loading Shader {0}{1}", type, macros != null && macros.Length > 0 ? String.Format("<{0}>", string.Join(", ", macros)) : string.Empty); - - // If the file name is not matching the class name, provide an error - if (shaderClass.Type.Name.Text != type) - { - log.Error(StrideMessageCode.FileNameNotMatchingClassName, shaderClass.Type.Name.Span, type, shaderClass.Type.Name.Text); - return null; - } - - loadedShaders.Add(shaderSourceKey, shaderClass); - - return shaderClass; - } - } - - public static ShaderClassType ParseSource(string shaderSource, LoggerResult log) - { - var parsingResult = StrideShaderParser.TryParse(shaderSource, null); - parsingResult.CopyTo(log); - - if (parsingResult.HasErrors) - { - return null; - } - - var shader = parsingResult.Shader; - var shaderClass = shader.Declarations.OfType().SingleOrDefault(); - if (shaderClass == null) - { - var queue = new Queue(shader.Declarations.OfType()); - while (queue.Count > 0 && shaderClass == null) - { - var namespaceNode = queue.Dequeue(); - shaderClass = namespaceNode.Body.OfType().SingleOrDefault(); - foreach (var subNamespace in namespaceNode.Body.OfType()) - { - queue.Enqueue(subNamespace); - } - } - } - return shaderClass; - } - - public bool ClassExists(string className) - { - return SourceManager.IsClassExists(className); - } - - private static Dictionary GenerateGenericMapping(ShaderClassType shaderClassType, IList genericParameters) - { - var identifierGenericClass = shaderClassType.GenericParameters; - if (identifierGenericClass.Count != genericParameters.Count) - throw new InvalidOperationException("Number of parameters in this generic instantiation doesn't match."); - - // Build generic mapping (i.e. T => RealType, U => RealType2) - return identifierGenericClass - .Select((value, index) => new { value, index }) - .ToDictionary(x => x.value.Name.Text, x => genericParameters[x.index].ToString()); - } - - private static string GenerateGenericClassName(ShaderClassType shaderClassType) - { - // Generate class name - return shaderClassType.Name.Text + (shaderClassType.GenericParameters == null ? string.Empty : "_" + string.Join("_", shaderClassType.GenericParameters.Select(x => x.ToString().Replace('.', '_')))); - } - - private static string GenerateGenericClassName(ShaderClassCode source) - { - // Generate class name - if (source.GenericArguments != null && source.GenericArguments.Length > 0) - { - var hash = source.GenericArguments[0].ToString().GetHashCode(); - for (var i = 0; i < source.GenericArguments.Length; ++i) - { - hash = (hash * 397) ^ source.GenericArguments[i].ToString().GetHashCode(); - } - - if (hash < 0) - { - hash = -hash; - return source.ClassName + "_Min" + hash.ToString(); - } - - return source.ClassName + "_" + hash.ToString(); - } - return source.ClassName; - } - - private class ShaderSourceKey : IEquatable - { - public readonly string TypeName; - private readonly string generics; - private readonly Stride.Core.Shaders.Parser.ShaderMacro[] shaderMacros; - private readonly int hashCode; - - public ShaderSourceKey(string typeName, string generics, Stride.Core.Shaders.Parser.ShaderMacro[] shaderMacros) - { - this.TypeName = typeName; - this.generics = generics; - this.shaderMacros = shaderMacros; - unchecked - { - hashCode = ((typeName != null ? typeName.GetHashCode() : 0) * 397) ^ (generics != null ? generics.GetHashCode() : 0); - hashCode = (hashCode * 397) ^ (this.shaderMacros != null ? this.shaderMacros.ComputeHash() : 0); - } - } - - public bool Equals(ShaderSourceKey other) - { - return Equals(other.TypeName, TypeName) && Equals(other.generics, generics) && ArrayExtensions.ArraysEqual(other.shaderMacros, shaderMacros); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (obj.GetType() != typeof(ShaderSourceKey)) return false; - return Equals((ShaderSourceKey)obj); - } - - public override int GetHashCode() - { - return hashCode; - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderMixinCodeGen.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderMixinCodeGen.cs deleted file mode 100644 index 27156affc3..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderMixinCodeGen.cs +++ /dev/null @@ -1,856 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; -using Stride.Core.Shaders.Writer; - -namespace Stride.Shaders.Parser.Mixins -{ - /// - /// This class is responsible to generate associated C# code from an effect file (extension: sdfx). - /// - public class ShaderMixinCodeGen : ShaderKeyGeneratorBase//ShaderWriter - { - private const string DefaultNameSpace = "Stride.Rendering"; - - private const string BlockContextTag = "BlockContextTag"; - private readonly LoggerResult logging; - private readonly Shader shader; - private EffectBlock currentBlock; - private int localVariableCount; - private readonly HashSet parameterKeysReferenced = new HashSet(); - private readonly HashSet mixinsReferenced = new HashSet(); - - - /// - /// Initializes a new instance of the class. - /// - /// The shader. - /// The logging. - /// shader or logging - /// Cannot process shaders having already parsing errors - public ShaderMixinCodeGen(Shader shader, LoggerResult logging) - { - if (shader == null) - throw new ArgumentNullException("shader"); - - if (logging == null) - throw new ArgumentNullException("logging"); - - this.shader = shader; - this.logging = logging; - EnablePreprocessorLine = false; - } - - /// - /// Generates the csharp code from a sdfx file. - /// - /// The PDXFX shader code. - /// The file path. - /// System.String. - /// - public static string GenerateCsharp(string sdfxShaderCode, string filePath) - { - // In .sdfx, shader has been renamed to effect, in order to avoid ambiguities with HLSL and .sdsl - var macros = new [] - { - new Stride.Core.Shaders.Parser.ShaderMacro("shader", "effect") - }; - - // Compile - var shader = StrideShaderParser.PreProcessAndParse(sdfxShaderCode, filePath, macros); - - // Try to generate a mixin code. - var loggerResult = new LoggerResult(); - var shaderKeyGenerator = new ShaderMixinCodeGen(shader, loggerResult); - - if (shaderKeyGenerator.Run()) - { - return shaderKeyGenerator.Text; - } - throw new InvalidOperationException(loggerResult.ToString()); - } - - /// - /// Runs the code generation. Results is accessible from property. - /// - public override bool Run() - { - // If there are any errors, report them in the file as well - // but return immediately as we can't really process the shader object - if (logging.HasErrors) - { - LogErrors(); - return false; - } - - // Add namespace for shader class type - FixShaderClassTypeWithNoNameSpace(); - - var blockVisitor = new ShaderBlockVisitor(this, logging); - blockVisitor.Run(shader); - - // If there are any errors, generated by the visitor report them immediately - if (logging.HasErrors) - { - LogErrors(); - return false; - } - - WriteLine("// "); - WriteLine("// Do not edit this file yourself!"); - WriteLine("//"); - WriteLine("// This code was generated by Stride Shader Mixin Code Generator."); - WriteLine("// To generate it yourself, please install Stride.VisualStudio.Package .vsix"); - WriteLine("// and re-save the associated .sdfx."); - WriteLine("// "); - WriteLine(); - - // No mixin found, just return - if (!blockVisitor.HasMixin && !blockVisitor.HasShaderClassType) - { - WriteLine("// Nothing to generate"); - return true; - } - - IsSdfx = blockVisitor.HasMixin; - - // Header of usings declaration - // TODO: Should probably be better to use fully qualified name of types to avoid conflicts. - - WriteLine("using System;"); - WriteLine("using Stride.Core;"); - WriteLine("using Stride.Rendering;"); - WriteLine("using Stride.Graphics;"); - WriteLine("using Stride.Shaders;"); - WriteLine("using Stride.Core.Mathematics;"); - WriteLine("using Buffer = Stride.Graphics.Buffer;"); - WriteLine(); - - // Visit the shader and generate the code - VisitDynamic(shader); - - // If there are any errors log them into the shader - if (logging.HasErrors) - { - LogErrors(); - return false; - } - - return true; - } - - public override void Visit(AssignmentExpression assignmentExpression) - { - Identifier typeTarget; - Identifier typeMember; - if (TryParameters(assignmentExpression.Target, out typeTarget, out typeMember)) - { - Write("context.SetParam(").Write(typeTarget).Write(".").Write(typeMember).Write(", "); - VisitDynamic(assignmentExpression.Value); - Write(")"); - } - else - { - base.Visit(assignmentExpression); - } - } - - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - Identifier typeTarget; - Identifier typeMember; - if (TryParameters(memberReferenceExpression, out typeTarget, out typeMember)) - { - var key = typeTarget + "." + typeMember; - parameterKeysReferenced.Add(key); - Write("context.GetParam(").Write(typeTarget).Write(".").Write(typeMember).Write(")"); - } - else - { - base.Visit(memberReferenceExpression); - } - } - - /// - /// Visits the specified enum type. - /// - /// Type of the enum. - public override void Visit(EnumType enumType) - { - Write("[DataContract]"); - WriteLinkLine(enumType); - Write("public enum"); - Write(" "); - Write(enumType.Name); - WriteSpace(); - { - OpenBrace(); - foreach (Expression fieldDeclaration in enumType.Values) - { - WriteLinkLine(fieldDeclaration); - VisitDynamic(fieldDeclaration); - WriteLine(","); - } - CloseBrace(false).Write(";").WriteLine(); - } - } - - /// - /// Visits the specified params block. - /// - /// The params block. - public override void Visit(ParametersBlock paramsBlock) - { - Write("[DataContract]"); - WriteLinkLine(paramsBlock); - Write("public partial class"); - Write(" "); - Write(paramsBlock.Name); - WriteSpace(); - Write(": ShaderMixinParameters"); - { - OpenBrace(); - - foreach (DeclarationStatement parameter in paramsBlock.Body.Statements.OfType()) - { - var variable = parameter.Content as Variable; - if (variable == null) - continue; - - WriteLinkLine(parameter); - VisitDynamic(variable); - } - - CloseBrace(false).Write(";").WriteLine(); - } - } - - /// - /// Visits the specified keyword expression. - /// - /// The keyword expression. - public override void Visit(KeywordExpression keywordExpression) - { - // A discard will be transformed to 'return' - if (keywordExpression.Name.Text == "discard") - { - WriteLinkLine(keywordExpression); - WriteLine("context.Discard();"); - } - else - { - base.Visit(keywordExpression); - } - } - - public override void Visit(ShaderClassType shader) - { - Write(shader.Qualifiers.Any(qualifier => qualifier == StrideStorageQualifier.Internal) ? "internal " : "public "); - Write("static partial class "); - Write(shader.Name); - Write("Keys"); - { - OpenBrace(); - foreach (var decl in shader.Members) - { - if (decl is Variable) - { - VisitDynamic(decl); - } - else if (decl is ConstantBuffer) - { - foreach (var subDecl in ((ConstantBuffer)decl).Members.OfType()) - { - VisitDynamic(subDecl); - } - } - } - CloseBrace(); - } - } - - public override void Visit(GenericType type) - { - if (IsTextureType(type)) - { - Write("Texture"); - } - else if (IsBufferType(type)) - { - Write("Buffer"); - } - else - { - base.Visit(type); - } - ProcessInitialValueStatus = false; - } - - public override void Visit(TypeName typeName) - { - if (typeName.IsByteAddressBufferType()) - { - Write("Buffer"); - ProcessInitialValueStatus = false; - } - else - { - base.Visit(typeName); - } - } - - /// - /// Visits the specified for each statement. - /// - /// For each statement. - public override void Visit(ForEachStatement forEachStatement) - { - WriteLinkLine(forEachStatement); - - if (forEachStatement.Variable == null) - { - localVariableCount++; - - Identifier parameterType; - Identifier parameterMember; - if (!TryParameters(forEachStatement.Collection, out parameterType, out parameterMember)) - { - Write(@"#error ""Unexpected parameter for 'foreach params' ["); - VisitDynamic(forEachStatement.Collection); - WriteLine(@"]. Expecting single property access"""); - return; - } - - string variable = "____" + localVariableCount; - Write("foreach(").Write("var ").Write(variable).Write(" in "); - VisitDynamic(forEachStatement.Collection); - WriteLine(")"); - - var statement = forEachStatement.Body as BlockStatement; - if (statement == null) - { - statement = new BlockStatement {Span = forEachStatement.Body.Span}; - statement.Statements.Add(forEachStatement.Body); - } - AddPushPopParameters(statement, parameterType, parameterMember, new VariableReferenceExpression(variable), forEachStatement.Span); - - VisitDynamic(statement); - - localVariableCount--; - } - else - { - Write("foreach("); - IsVisitingVariableInlines = true; - VisitDynamic(forEachStatement.Variable); - IsVisitingVariableInlines = false; - Write(" in "); - VisitDynamic(forEachStatement.Collection); - Write(")"); - WriteLine(); - VisitDynamic(forEachStatement.Body); - } - } - - /// - /// Visits the specified shader block. - /// - /// The shader block. - public override void Visit(EffectBlock effectBlock) - { - WriteLinkLine(effectBlock); - currentBlock = effectBlock; - - VariableAsParameterKey = false; - - // Clear ParameterKey and Mixin references - parameterKeysReferenced.Clear(); - mixinsReferenced.Clear(); - - // Use a single internal class for all shader mixins - Write("internal static partial class ShaderMixins"); - { - OpenBrace(); - Write("internal partial class"); - Write(" "); - Write(effectBlock.Name); - WriteSpace(); - Write(" : IShaderMixinBuilder"); - { - OpenBrace(); - // Generate the main generate method for each shader block - Write("public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)"); - { - OpenBrace(); - // Create a context associated with ShaderBlock - foreach (Statement statement in effectBlock.Body.Statements) - { - VisitDynamic(statement); - } - CloseBrace(); - } - - WriteLine(); - WriteLine("[System.Runtime.CompilerServices.ModuleInitializer]"); - WriteLine("internal static void __Initialize__()"); - { - OpenBrace(); - Write("ShaderMixinManager.Register(\"").Write(effectBlock.Name).Write("\", new ").Write(effectBlock.Name).WriteLine("());"); - CloseBrace(); - } - CloseBrace(); - } - CloseBrace(); - } - - VariableAsParameterKey = true; - currentBlock = null; - } - - /// - /// Visits the specified mixin statement. - /// - /// The mixin statement. - public override void Visit(MixinStatement mixinStatement) - { - Expression mixinName; - AssignmentExpression assignExpression; - var genericParameters = new List(); - - switch (mixinStatement.Type) - { - case MixinStatementType.Default: - ExtractGenericParameters(mixinStatement.Value, out mixinName, genericParameters); - - WriteLinkLine(mixinStatement); - Write("context.Mixin(mixin, "); - WriteMixinName(mixinName); - WriteGenericParameters(genericParameters); - WriteLine(");"); - break; - - case MixinStatementType.Child: - - // mixin child can come in 2 flavour: - // 1) mixin child MyEffect => equivalent to mixin child MyEffect = MyEffect - // 2) mixin child MyGenericEffectName = MyEffect - var targetExpression = mixinStatement.Value; - assignExpression = mixinStatement.Value as AssignmentExpression; - if (assignExpression != null) - { - targetExpression = assignExpression.Value; - } - - ExtractGenericParameters(targetExpression, out mixinName, genericParameters); - var childName = assignExpression != null ? assignExpression.Target : mixinName; - { - WriteLinkLine(mixinStatement); - Write("if (context.ChildEffectName == "); - WriteMixinName(childName); - Write(")"); - OpenBrace(); - - WriteLinkLine(mixinStatement); - Write("context.Mixin(mixin, "); - WriteMixinName(mixinName); - WriteGenericParameters(genericParameters); - WriteLine(");"); - WriteLine("return;"); - - CloseBrace(); - } - break; - - case MixinStatementType.Remove: - ExtractGenericParameters(mixinStatement.Value, out mixinName, genericParameters); - - WriteLinkLine(mixinStatement); - Write("context.RemoveMixin(mixin, "); - WriteMixinName(mixinName); - if (genericParameters.Count > 0) - { - logging.Error("Removing with generic parameters is not supported", mixinStatement.Span); - } - WriteLine(");"); - break; - - case MixinStatementType.Macro: - WriteLinkLine(mixinStatement); - var context = (ShaderBlockContext)currentBlock.GetTag(BlockContextTag); - assignExpression = mixinStatement.Value as AssignmentExpression; - Expression macroName; - Expression macroValue; - - if (assignExpression != null) - { - macroName = assignExpression.Target; - if (macroName is VariableReferenceExpression) - { - macroName = new LiteralExpression(macroName.ToString()); - } - macroValue = assignExpression.Value; - } - else - { - var variableReference = mixinStatement.Value as MemberReferenceExpression; - if (variableReference == null || !(variableReference.Target is VariableReferenceExpression) || !context.DeclaredParameters.Contains((((VariableReferenceExpression)variableReference.Target).Name.Text))) - { - logging.Error("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Span); - macroName = new LiteralExpression("#INVALID_MACRO_NAME"); - macroValue = mixinStatement.Value; - } - else - { - macroName = new LiteralExpression(variableReference.Member.Text); - macroValue = mixinStatement.Value; - } - } - - Write("mixin.AddMacro("); - VisitDynamic(macroName); - Write(", "); - VisitDynamic(macroValue); - WriteLine(");"); - break; - - case MixinStatementType.Compose: - assignExpression = mixinStatement.Value as AssignmentExpression; - if (assignExpression == null) - { - logging.Error("Expecting assign expression for composition", mixinStatement.Value.Span); - return; - } - - var addCompositionFunction = "PushComposition"; - - // If it's a +=, let's create or complete a ShaderArraySource - if (assignExpression.Operator == AssignmentOperator.Addition) - { - addCompositionFunction = "PushCompositionArray"; - } - - ExtractGenericParameters(assignExpression.Value, out mixinName, genericParameters); - - { - OpenBrace(); - WriteLinkLine(mixinStatement); - Write("var __mixinToCompose__ = "); - WriteMixinName(mixinName); - WriteLine(";"); - WriteLine("var __subMixin = new ShaderMixinSource();"); - - WriteLinkLine(mixinStatement); - Write("context.").Write(addCompositionFunction).Write("(mixin, "); - WriteStringOrExpression(assignExpression.Target); - WriteLine(", __subMixin);"); - - WriteLinkLine(mixinStatement); - Write("context.Mixin(__subMixin, __mixinToCompose__"); - WriteGenericParameters(genericParameters); - WriteLine(");"); - - WriteLinkLine(mixinStatement); - WriteLine("context.PopComposition();"); - CloseBrace(); - } - break; - } - } - - /// - /// Visits the specified using statement. - /// - /// The using statement. - public override void Visit(UsingStatement usingStatement) - { - WriteLinkLine(usingStatement); - Write("using ").Write(usingStatement.Name).WriteLine(";"); - } - - /// - /// Visits the specified using parameters statement. - /// - /// The using parameters statement. - public override void Visit(UsingParametersStatement usingParametersStatement) - { - if (usingParametersStatement.Body == null) - return; - - Identifier parameterType; - Identifier parameterMember; - if (!TryParameters(usingParametersStatement.Name, out parameterType, out parameterMember)) - { - Write(@"#error ""Unexpected parameter for 'using params' ["); - VisitDynamic(usingParametersStatement.Name); - WriteLine(@"]. Expecting single property access"""); - return; - } - - AddPushPopParameters(usingParametersStatement.Body, parameterType, parameterMember, usingParametersStatement.Name, usingParametersStatement.Span); - - Visit(usingParametersStatement.Body); - } - - private void AddPushPopParameters(BlockStatement blockStatement, Identifier parameterType, Identifier parameterMember, Expression paramValue, SourceSpan span) - { - var pushStatement = new ExpressionStatement(new MethodInvocationExpression(new MemberReferenceExpression(new VariableReferenceExpression("context"), "PushParameters"), paramValue)) {Span = span}; - var popStatement = new ExpressionStatement(new MethodInvocationExpression(new MemberReferenceExpression(new VariableReferenceExpression("context"), "PopParameters"))) {Span = span}; - blockStatement.Statements.Insert(0, pushStatement); - ; - blockStatement.Statements.Add(popStatement); - } - - private bool TryParameters(Expression expression, out Identifier type, out Identifier member) - { - type = null; - member = null; - var memberReferenceExpression = expression as MemberReferenceExpression; - if (memberReferenceExpression == null) - return false; - - var name = memberReferenceExpression.Target as VariableReferenceExpression; - - bool foundDeclaredParameters = false; - if (currentBlock != null) - { - var context = (ShaderBlockContext)currentBlock.GetTag(BlockContextTag); - HashSet usings = context.DeclaredParameters; - - if (name != null && usings.Contains(name.Name)) - { - type = name.Name; - member = memberReferenceExpression.Member; - foundDeclaredParameters = true; - } - } - - return foundDeclaredParameters; - } - - private void ExtractGenericParameters(Expression expression, out Expression mixinName, List genericParametersOut) - { - if (genericParametersOut == null) - { - throw new ArgumentNullException("genericParametersOut"); - } - - mixinName = expression; - genericParametersOut.Clear(); - - var varExp = expression as VariableReferenceExpression; - if (varExp != null) - { - Identifier identifier = varExp.Name; - var identifierGeneric = identifier as IdentifierGeneric; - if (identifierGeneric != null) - { - mixinName = new VariableReferenceExpression(identifierGeneric.Text); - - foreach (Identifier subIdentifier in identifierGeneric.Identifiers) - { - var identifierDot = subIdentifier as IdentifierDot; - if (identifierDot != null) - { - if (identifierDot.Identifiers.Count == 2) - { - genericParametersOut.Add(new MemberReferenceExpression(new VariableReferenceExpression(identifierDot.Identifiers[0]), identifierDot.Identifiers[1])); - } - else - { - logging.Error("Unsupported identifier in generic used for mixin", identifierDot.Span); - } - } - else if (subIdentifier is LiteralIdentifier) - { - var literalIdentifier = (LiteralIdentifier)subIdentifier; - - genericParametersOut.Add(new LiteralExpression(literalIdentifier.Value)); - } - else if (subIdentifier.GetType() == typeof(Identifier)) - { - genericParametersOut.Add(new VariableReferenceExpression(subIdentifier)); - } - else - { - logging.Error("Unsupported identifier in generic used for mixin", subIdentifier.Span); - } - } - } - } - } - - private void WriteGenericParameters(IEnumerable genericParameters) - { - foreach (Expression genericParameter in genericParameters) - { - Write(", "); - VisitDynamic(genericParameter); - } - } - - private void WriteMixinName(Expression mixinName) - { - // Output between "" only if the mixin name is only a variable - if (mixinName is VariableReferenceExpression) - { - mixinsReferenced.Add(mixinName.ToString()); - } - WriteStringOrExpression(mixinName); - } - - private void WriteStringOrExpression(Expression expr) - { - if (expr is VariableReferenceExpression) - { - Write("\""); - } - VisitDynamic(expr); - if (expr is VariableReferenceExpression) - { - Write("\""); - } - } - - - private void LogErrors() - { - foreach (var reportMessage in logging.Messages) - { - if (reportMessage.Level == ReportMessageLevel.Error) - { - Write("#error ").WriteLine(reportMessage.ToString()); - } - } - } - - private class ShaderBlockContext - { - public readonly HashSet DeclaredParameters = new HashSet(); - } - - private void FixShaderClassTypeWithNoNameSpace() - { - for (int i = 0; i < shader.Declarations.Count; i++) - { - var node = shader.Declarations[i]; - if (node is ShaderClassType) - { - var nameSpaceBlock = new NamespaceBlock(DefaultNameSpace); - nameSpaceBlock.Body.Add(node); - shader.Declarations[i] = nameSpaceBlock; - } - } - } - - /// - /// Internal visitor to precalculate all available Parameters in the context - /// - private sealed class ShaderBlockVisitor : ShaderWalker - { - private readonly LoggerResult logging; - private ShaderBlockContext currentContext; - - private readonly ShaderKeyGeneratorBase parent; - - public ShaderBlockVisitor(ShaderKeyGeneratorBase parent, LoggerResult logging) - : base(false, false) - { - this.parent = parent; - this.logging = logging; - } - - public bool HasMixin { get; private set; } - - public bool HasShaderClassType { get; private set; } - - public void Run(Shader shader) - { - VisitDynamic(shader); - } - - public override void Visit(ParametersBlock paramsBlock) - { - HasMixin = true; - } - - public override void Visit(ShaderClassType shaderClassType) - { - // Check if there are any parameter keys in ShaderClassType and ConstantBuffer - CheckParameterKeys(shaderClassType.Members.OfType()); - CheckParameterKeys(shaderClassType.Members.OfType().SelectMany(cbuffer => cbuffer.Members).OfType()); - } - - private void CheckParameterKeys(IEnumerable variables) - { - foreach (var variable in variables) - { - if (!HasShaderClassType) - { - if (parent.IsParameterKey(variable)) - { - HasShaderClassType = true; - } - } - } - } - - - public override void Visit(EffectBlock effectBlock) - { - HasMixin = true; - - // Create a context associated with ShaderBlock - currentContext = new ShaderBlockContext(); - effectBlock.SetTag(BlockContextTag, currentContext); - - foreach (Statement statement in effectBlock.Body.Statements) - { - VisitDynamic(statement); - } - currentContext = null; - } - - public override void Visit(UsingParametersStatement usingParametersStatement) - { - if (currentContext == null) - { - logging.Error("Unexpected 'using params' outside of shader block declaration", usingParametersStatement.Span); - return; - } - - HashSet usings = currentContext.DeclaredParameters; - - // If this is a using params without a body, it is a simple reference of a ParameterBlock - if (usingParametersStatement.Body == null) - { - var simpleName = usingParametersStatement.Name as VariableReferenceExpression; - if (simpleName != null) - { - string typeName = simpleName.Name.Text; - - if (usings.Contains(typeName)) - { - logging.Error("Unexpected declaration of using params. This variable is already declared in this scope", usingParametersStatement.Span); - return; - } - - usings.Add(typeName); - } - } - else - { - // using params with a body is to enter the context of the parameters passed to the using statements - VisitDynamic(usingParametersStatement.Body); - } - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderVirtualTable.cs b/sources/engine/Stride.Shaders.Parser/Mixins/ShaderVirtualTable.cs deleted file mode 100644 index 07bdda3871..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/ShaderVirtualTable.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Linq; -using Stride.Core; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - [DataContract(Inherited = true)] - internal class ShaderVirtualTable - { - #region Public member - - public Dictionary VirtualTableGroup = new Dictionary(); - - #endregion - - #region Constructor - - public ShaderVirtualTable() {} - - #endregion - - #region Public methods - - /// - /// Adds the virtual table of the mixin - /// - /// - /// - /// - public void AddVirtualTable(ShaderVirtualTable shaderVirtualTable, string className, LoggerResult errorLogger) - { - var newVT = shaderVirtualTable.VirtualTableGroup[className].ToArray(); - VirtualTableGroup.Add(className, newVT); - - foreach (var methodDecl in newVT) - ReplaceVirtualMethod(methodDecl, errorLogger); - } - - /// - /// Replace the method occurrence with its last definition - /// - /// the overriding method - /// - public void ReplaceVirtualMethod(MethodDeclaration methodDeclaration, LoggerResult errorLogger) - { - var baseDeclarationMixin = (string)methodDeclaration.GetTag(StrideTags.BaseDeclarationMixin); - foreach (var dict in VirtualTableGroup.Select(x => x.Value)) - { - for (int i = 0; i < dict.Length; ++i) - { - var method = dict[i]; - var originalDecl = (string)method.GetTag(StrideTags.BaseDeclarationMixin); - - // TODO: take typedefs into account... - if (originalDecl == baseDeclarationMixin && method.IsSameSignature(methodDeclaration)) - { - if (method.Qualifiers.Contains(StrideStorageQualifier.Stage) && !methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - errorLogger.Warning(StrideMessageCode.WarningMissingStageKeyword, methodDeclaration.Span, methodDeclaration, (methodDeclaration.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName); - methodDeclaration.Qualifiers |= StrideStorageQualifier.Stage; - } - else if (!method.Qualifiers.Contains(StrideStorageQualifier.Stage) && methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - errorLogger.Error(StrideMessageCode.ErrorExtraStageKeyword, methodDeclaration.Span, methodDeclaration, method, (methodDeclaration.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName); - methodDeclaration.Qualifiers.Values.Remove(StrideStorageQualifier.Stage); - } - - dict[i] = methodDeclaration; - } - } - } - } - - /// - /// Adds the methods defined in the final mixin - /// - /// a list of MethodDeclaration - /// the name of the class - /// the logger for errors and warnings - public void AddFinalDeclarations(List methodDeclarations, string className, LoggerResult errorLogger) - { - var finalDict = new MethodDeclaration[methodDeclarations.Count]; - foreach (var methodDecl in methodDeclarations) - { - var vtableReference = (VTableReference)methodDecl.GetTag(StrideTags.VirtualTableReference); - finalDict[vtableReference.Slot] = methodDecl; - - // TODO: override/abstract behavior - //if (methodDecl.Qualifiers.Contains(StrideStorageQualifier.Override)) - LookForBaseDeclarationMixin(methodDecl, errorLogger); - } - - VirtualTableGroup.Add(className, finalDict); - } - - /// - /// Finds the location of the method in the virtual table of its definition mixin - /// - /// - /// - public VTableReference GetBaseDeclaration(MethodDeclaration methodDeclaration) - { - var baseMethodDeclMixin = methodDeclaration.GetTag(StrideTags.BaseDeclarationMixin) as string; - var slot = -1; - var vt = VirtualTableGroup[baseMethodDeclMixin]; - for (int i = 0; i < vt.Length; ++i) - { - if (methodDeclaration.IsSameSignature(vt[i])) - { - slot = i; - break; - } - } - return new VTableReference { Shader = baseMethodDeclMixin, Slot = slot }; - } - - /// - /// Returns the method at the specified location - /// - /// the sub virtual table - /// the slot index - /// the method in the specified location - public MethodDeclaration GetMethod(string mixinName, int slot) - { - MethodDeclaration[] decls; - if (VirtualTableGroup.TryGetValue(mixinName, out decls)) - { - if (decls.Length > slot) - return VirtualTableGroup[mixinName][slot]; - } - return null; - } - - #endregion - - #region Private methods - - /// - /// Find the base definition of the method and override its occurrence - /// - /// - /// - private void LookForBaseDeclarationMixin(MethodDeclaration methodDeclaration, LoggerResult errorLogger) - { - foreach (var dict in VirtualTableGroup.Select(x => x.Value)) - { - for (int i = 0; i < dict.Length; ++i) - { - var method = dict[i]; - var baseDeclarationMixin = (string)method.GetTag(StrideTags.BaseDeclarationMixin); - - // TODO: take typedefs into account... - if (method.IsSameSignature(methodDeclaration)) - { - var sourceShader = ((ModuleMixin)methodDeclaration.GetTag(StrideTags.ShaderScope)).MixinName; - - // test override - if (methodDeclaration is MethodDefinition && method is MethodDefinition && !methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Override)) - errorLogger.Error(StrideMessageCode.ErrorMissingOverride, method.Span, methodDeclaration, sourceShader); - if (!(methodDeclaration is MethodDefinition)) - errorLogger.Error(StrideMessageCode.ErrorOverrindingDeclaration, method.Span, methodDeclaration, sourceShader); - - if (method.Qualifiers.Contains(StrideStorageQualifier.Stage) && !methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - errorLogger.Warning(StrideMessageCode.WarningMissingStageKeyword, methodDeclaration.Span, methodDeclaration, (methodDeclaration.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName); - methodDeclaration.Qualifiers |= StrideStorageQualifier.Stage; - } - else if (!method.Qualifiers.Contains(StrideStorageQualifier.Stage) && methodDeclaration.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - errorLogger.Error(StrideMessageCode.ErrorExtraStageKeyword, methodDeclaration.Span, methodDeclaration, method, (methodDeclaration.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName); - methodDeclaration.Qualifiers.Values.Remove(StrideStorageQualifier.Stage); - } - - dict[i] = methodDeclaration; - methodDeclaration.SetTag(StrideTags.BaseDeclarationMixin, baseDeclarationMixin); - } - } - } - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StreamFieldVisitor.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StreamFieldVisitor.cs deleted file mode 100644 index 602978d6ac..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StreamFieldVisitor.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StreamFieldVisitor : ShaderRewriter - { - private Variable typeInference = null; - - private Expression arrayIndex; - - public StreamFieldVisitor(Variable variable, Expression index = null) - : base(false, false) - { - typeInference = variable; - arrayIndex = index; - } - - public Expression Run(Expression expression) - { - return (Expression)VisitDynamic(expression); - } - - private Expression ProcessExpression(Expression expression) - { - if (expression.TypeInference.TargetType != null && expression.TypeInference.TargetType.IsStreamsType()) - { - var mre = new MemberReferenceExpression(expression, typeInference.Name) { TypeInference = { Declaration = typeInference, TargetType = typeInference.Type.ResolveType() } }; - if (arrayIndex == null) - return mre; - else - { - var ire = new IndexerExpression(mre, arrayIndex); - return ire; - } - } - - return expression; - } - - public override Node Visit(VariableReferenceExpression variableReferenceExpression) - { - var expression = (Expression)base.Visit(variableReferenceExpression); - return ProcessExpression(expression); - } - - public override Node Visit(MemberReferenceExpression memberReferenceExpression) - { - var expression = (Expression)base.Visit(memberReferenceExpression); - return ProcessExpression(expression); - } - - public override Node Visit(IndexerExpression indexerExpression) - { - var expression = (Expression)base.Visit(indexerExpression); - return ProcessExpression(expression); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StreamOutputParser.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StreamOutputParser.cs deleted file mode 100644 index 3cc91e8928..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StreamOutputParser.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Graphics; - -namespace Stride.Shaders.Parser.Mixins -{ - internal static class StreamOutputParser - { - private static Regex streamOutputRegex = new Regex(@"(([0-9]*)\s*:\s*)?(\w+)(.(\w+))?"); - private static readonly string[] masks = new[] { "xyzw", "rgba", "stuv" }; - - public static void Parse(IList entries, out int[] strides, AttributeDeclaration streamOutputAttribute, IList fields) - { - var streamStrings = streamOutputAttribute.Parameters - .TakeWhile(x => x.Value is string) - .Select(x => x.Value as string) - .ToArray(); - - Parse(entries, out strides, streamStrings, fields); - } - - /// - /// Parse stream output declarations. - /// Format is "[slot :] semantic[index][.mask] ; ...". - /// - /// The parsed entries. - /// The output strides. - /// The output declarations to parse. - public static void Parse(IList entries, out int[] strides, string[] streams, IList fields) - { - strides = new int[4]; - - var fieldsBySemantic = fields.ToDictionary(x => Semantic.Parse(x.Qualifiers.OfType().Single().Name)); - - for (int streamIndex = 0; streamIndex < streams.Length; ++streamIndex) - { - // Parse multiple declarations separated by semicolon - var stream = streams[streamIndex]; - foreach (var streamOutput in stream.Split(';')) - { - // Parse a single declaration: "[slot :] semantic[index][.mask]" - var match = streamOutputRegex.Match(streamOutput); - if (!match.Success) - throw new InvalidOperationException("Could not parse stream output."); - - var streamOutputDecl = new ShaderStreamOutputDeclarationEntry(); - - // Split semantic into (name, index) - var semantic = Semantic.Parse(match.Groups[3].Value); - - streamOutputDecl.SemanticName = semantic.Key; - streamOutputDecl.SemanticIndex = semantic.Value; - //if (streamOutputDecl.SemanticName == "$SKIP") - // streamOutputDecl.SemanticName = null; - - var matchingField = fieldsBySemantic[semantic]; - var matchingFieldType = matchingField.Type.TypeInference.TargetType ?? matchingField.Type; - - if (matchingFieldType is VectorType) - streamOutputDecl.ComponentCount = (byte)((VectorType)matchingFieldType).Dimension; - else if (matchingFieldType is ScalarType) - streamOutputDecl.ComponentCount = 1; - else - throw new InvalidOperationException(string.Format("Could not recognize type of stream output for {0}.", matchingField)); - - var mask = match.Groups[5].Value; - ParseMask(mask, ref streamOutputDecl.StartComponent, ref streamOutputDecl.ComponentCount); - - byte.TryParse(match.Groups[2].Value, out streamOutputDecl.OutputSlot); - - streamOutputDecl.Stream = streamIndex; - - strides[streamOutputDecl.OutputSlot] += streamOutputDecl.ComponentCount * sizeof(float); - entries.Add(streamOutputDecl); - } - } - } - - private static bool ParseMask(string mask, ref byte startComponent, ref byte componentCount) - { - if (mask == string.Empty) - { - return false; - } - - foreach (var maskRef in masks) - { - var index = maskRef.IndexOf(mask, StringComparison.Ordinal); - if (index != -1) - { - componentCount = (byte)mask.Length; - startComponent = (byte)index; - return true; - } - } - - throw new InvalidOperationException("Could not parse stream output mask."); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideAssignmentCloner.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideAssignmentCloner.cs deleted file mode 100644 index dab27d9c55..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideAssignmentCloner.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Mixins -{ - /// - /// Class used to clone an expression without the references it may contain - /// - internal static class StrideAssignmentCloner - { - public static Expression Run(Expression expression) - { - return Clone(expression); - } - - private static Expression Clone(Expression expression) - { - if (expression is ArrayInitializerExpression) - return Clone((ArrayInitializerExpression)expression); - if (expression is BinaryExpression) - return Clone((BinaryExpression)expression); - if (expression is ConditionalExpression) - return Clone((ConditionalExpression)expression); - if (expression is EmptyExpression) - return Clone((EmptyExpression)expression); - if (expression is ExpressionList) - return Clone((ExpressionList)expression); - if (expression is IndexerExpression) - return Clone((IndexerExpression)expression); - if (expression is KeywordExpression) - return Clone((KeywordExpression)expression); - if (expression is LiteralExpression) - return Clone((LiteralExpression)expression); - if (expression is MemberReferenceExpression) - return Clone((MemberReferenceExpression)expression); - if (expression is MethodInvocationExpression) - return Clone((MethodInvocationExpression)expression); - if (expression is ParenthesizedExpression) - return Clone((ParenthesizedExpression)expression); - if (expression is TypeReferenceExpression) - return Clone((TypeReferenceExpression)expression); - if (expression is UnaryExpression) - return Clone((UnaryExpression)expression); - if (expression is VariableReferenceExpression) - return Clone((VariableReferenceExpression)expression); - return null; - } - - private static ArrayInitializerExpression Clone(ArrayInitializerExpression expression) - { - var aie = new ArrayInitializerExpression(); - foreach (var item in expression.Items) - aie.Items.Add(Clone(item)); - return aie; - } - - private static BinaryExpression Clone(BinaryExpression expression) - { - return new BinaryExpression(expression.Operator, Clone(expression.Left), Clone(expression.Right)); - } - - private static ConditionalExpression Clone(ConditionalExpression expression) - { - return new ConditionalExpression(Clone(expression.Condition), Clone(expression.Left), Clone(expression.Right)); - } - - private static EmptyExpression Clone(EmptyExpression expression) - { - return expression; - } - - private static ExpressionList Clone(ExpressionList expression) - { - var parameters = new Expression[expression.Count]; - for (int i = 0; i < expression.Count; ++i) - parameters[i] = Clone(expression[i]); - return new ExpressionList(parameters); - } - - private static IndexerExpression Clone(IndexerExpression expression) - { - var ire = new IndexerExpression(Clone(expression.Target), Clone(expression.Index)); - if (expression.TypeInference.TargetType != null && expression.TypeInference.TargetType.IsStreamsType()) - ire.TypeInference.TargetType = expression.TypeInference.TargetType; - return ire; - } - - private static KeywordExpression Clone(KeywordExpression expression) - { - return expression; - } - - private static LiteralExpression Clone(LiteralExpression expression) - { - return expression; - } - - private static MemberReferenceExpression Clone(MemberReferenceExpression expression) - { - var mre = new MemberReferenceExpression(Clone(expression.Target), expression.Member); - if (expression.TypeInference.TargetType != null && expression.TypeInference.TargetType.IsStreamsType()) - mre.TypeInference.TargetType = expression.TypeInference.TargetType; - return mre; - } - - private static MethodInvocationExpression Clone(MethodInvocationExpression expression) - { - var parameters = new Expression[expression.Arguments.Count]; - for (int i = 0; i < expression.Arguments.Count; ++i) - parameters[i] = Clone(expression.Arguments[i]); - return new MethodInvocationExpression(Clone(expression.Target), parameters); - } - - private static ParenthesizedExpression Clone(ParenthesizedExpression expression) - { - return new ParenthesizedExpression(Clone(expression.Content)); - } - - private static TypeReferenceExpression Clone(TypeReferenceExpression expression) - { - return expression; - } - - private static UnaryExpression Clone(UnaryExpression expression) - { - return new UnaryExpression(expression.Operator, Clone(expression.Expression)); - } - - private static VariableReferenceExpression Clone(VariableReferenceExpression expression) - { - var vre = new VariableReferenceExpression(expression.Name); - if (expression.TypeInference.TargetType != null && expression.TypeInference.TargetType.IsStreamsType()) - vre.TypeInference.TargetType = expression.TypeInference.TargetType; - return vre; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideClassInstantiator.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideClassInstantiator.cs deleted file mode 100644 index 50c6bdb60b..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideClassInstantiator.cs +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; - -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideClassInstantiator : ShaderWalker - { - private ShaderClassType shaderClassType; - - private LoggerResult logger; - - private bool autoGenericInstances; - - private Dictionary variableGenerics; - - private Dictionary expressionGenerics; - - private Dictionary identifiersGenerics; - - private Dictionary stringGenerics; - - private StrideClassInstantiator(ShaderClassType classType, Dictionary expressions, Dictionary identifiers, bool autoGenericInstances, LoggerResult log) - : base(false, false) - { - shaderClassType = classType; - expressionGenerics = expressions; - identifiersGenerics = identifiers; - this.autoGenericInstances = autoGenericInstances; - logger = log; - variableGenerics = shaderClassType.ShaderGenerics.ToDictionary(x => x.Name.Text, x => x); - } - - public static void Instantiate(ShaderClassType classType, Dictionary expressions, Dictionary identifiers, bool autoGenericInstances, LoggerResult log) - { - var instantiator = new StrideClassInstantiator(classType, expressions, identifiers, autoGenericInstances, log); - instantiator.Run(); - } - - private void Run() - { - stringGenerics = identifiersGenerics.ToDictionary(x => x.Key, x => x.Value.ToString()); - - foreach (var baseClass in shaderClassType.BaseClasses) - VisitDynamic(baseClass); // look for IdentifierGeneric - - foreach (var member in shaderClassType.Members) - VisitDynamic(member); // look for IdentifierGeneric and Variable - - // Process each constant buffer encoded as tag - foreach (var constantBuffer in shaderClassType.Members.OfType().Select(x => (ConstantBuffer)x.GetTag(StrideTags.ConstantBuffer)).Where(x => x != null).Distinct()) - VisitDynamic(constantBuffer); - - int insertIndex = 0; - foreach (var variable in shaderClassType.ShaderGenerics) - { - // For all string generic argument, don't try to assign an initial value as they are replaced directly at visit time. - if (variable.Type is IGenericStringArgument) - continue; - - variable.InitialValue = expressionGenerics[variable.Name.Text]; - - // TODO: be more precise - - if (!(variable.InitialValue is VariableReferenceExpression || variable.InitialValue is MemberReferenceExpression)) - { - variable.Qualifiers |= StorageQualifier.Const; - variable.Qualifiers |= Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Static; - } - // Because FindDeclaration is broken for variable declared at the scope of the class, make sure to - // put const at the beginning of the class to allow further usage of the variable to work - shaderClassType.Members.Insert(insertIndex++, variable); - } - } - - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - base.Visit(memberReferenceExpression); - - // Try to find usage of all MemberName 'yyy' in reference expressions like "xxx.yyy" and replace by their - // generic instantiation - var memberVariableName = memberReferenceExpression.Member.Text; - if (variableGenerics.TryGetValue(memberVariableName, out var memberVariable) && memberVariable.Type is MemberName) - { - string memberName; - if (stringGenerics.TryGetValue(memberVariableName, out memberName) && !autoGenericInstances) - { - memberReferenceExpression.Member = new Identifier(memberName); - } - else - { - memberReferenceExpression.TypeInference.Declaration = memberVariable; - } - } - } - - public override void Visit(ConstantBuffer constantBuffer) - { - string remappedConstantBufferName; - if (stringGenerics.TryGetValue(constantBuffer.Name.Text, out remappedConstantBufferName)) - constantBuffer.Name = new Identifier(remappedConstantBufferName); - - base.Visit(constantBuffer); - } - - public override void Visit(Variable variable) - { - base.Visit(variable); - //TODO: check types - - // Don't perform any replacement if we are just auto instancing shaders - if (autoGenericInstances) - { - return; - } - - if (variable.IsGroup) - return; - - // no call on base - // Semantic keyword: replace semantics - foreach (var sem in variable.Qualifiers.Values.OfType()) - { - string replacementSemantic; - if (stringGenerics.TryGetValue(sem.Name, out replacementSemantic)) - { - if (logger != null && !(variableGenerics[sem.Name].Type is SemanticType)) - logger.Warning(StrideMessageCode.WarningUseSemanticType, variable.Span, variableGenerics[sem.Name]); - sem.Name = replacementSemantic; - } - } - - // MemberName keyword: replace variable names - if (variableGenerics.TryGetValue(variable.Name, out var genVariable) && genVariable.Type is MemberName) - { - string memberName; - if (stringGenerics.TryGetValue(variable.Name, out memberName)) - { - variable.Name = new Identifier(memberName); - } - } - - foreach (var annotation in variable.Attributes.OfType().Where(x => x.Name == "Link" && x.Parameters.Count > 0)) - { - var linkName = (string)annotation.Parameters[0].Value; - - if (String.IsNullOrEmpty(linkName)) - continue; - - var replacements = new List>(); - - foreach (var generic in variableGenerics.Where(x => x.Value.Type is LinkType)) - { - var index = linkName.IndexOf(generic.Key, 0); - if (index >= 0) - replacements.Add(Tuple.Create(generic.Key, index)); - } - - if (replacements.Count > 0) - { - var finalString = ""; - var currentIndex = 0; - foreach (var replacement in replacements.OrderBy(x => x.Item2)) - { - var replacementIndex = replacement.Item2; - var stringToReplace = replacement.Item1; - - if (replacementIndex - currentIndex > 0) - finalString += linkName.Substring(currentIndex, replacementIndex - currentIndex); - finalString += stringGenerics[stringToReplace]; - currentIndex = replacementIndex + stringToReplace.Length; - } - - if (currentIndex < linkName.Length) - finalString += linkName.Substring(currentIndex); - - annotation.Parameters[0] = new Literal(finalString); - } - } - } - - public override void Visit(IdentifierGeneric identifierGeneric) - { - base.Visit(identifierGeneric); - - for (var i = 0; i < identifierGeneric.Identifiers.Count; ++i) - { - Identifier replacement; - if (identifiersGenerics.TryGetValue(identifierGeneric.Identifiers[i].ToString(), out replacement)) - identifierGeneric.Identifiers[i] = replacement; - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceAppend.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceAppend.cs deleted file mode 100644 index 3f589b6e77..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceAppend.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Linq; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideReplaceAppend : ShaderRewriter - { - #region Private members - - /// - /// List of append methods - /// - private HashSet appendMethodsList; - - /// - /// List of output statements replacing the append method - /// - private List outputStatements; - - /// - /// Variable replacing the stream in the append function - /// - private VariableReferenceExpression outputVre; - - #endregion - - #region Constructor - - public StrideReplaceAppend(HashSet appendList, List output, VariableReferenceExpression vre) - : base(false, false) - { - appendMethodsList = appendList; - outputStatements = output; - outputVre = vre; - } - - #endregion - - #region Public method - - public void Run(Node startNode) - { - VisitDynamic(startNode); - } - - #endregion - - #region Protected method - - public override Node Visit(ExpressionStatement expressionStatement) - { - base.Visit(expressionStatement); - - if (appendMethodsList.Contains(expressionStatement.Expression)) - { - var appendMethodCall = expressionStatement.Expression as MethodInvocationExpression; - var blockStatement = new BlockStatement(); - blockStatement.Statements.AddRange(outputStatements); - appendMethodCall.Arguments[0] = outputVre; - blockStatement.Statements.Add(expressionStatement); - return blockStatement; - } - return expressionStatement; - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceExtern.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceExtern.cs deleted file mode 100644 index bb913148d8..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceExtern.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideReplaceExtern : ShaderRewriter - { - #region Private members - - /// - /// The variable to replace - /// - private Variable VariableToReplace = null; - - /// - /// the expression that will replace the variable - /// - private IndexerExpression IndexerReplacement = null; - - #endregion - - #region Constructor - - public StrideReplaceExtern(Variable variable, IndexerExpression expression) - : base(false, true) - { - VariableToReplace = variable; - IndexerReplacement = expression; - } - - public void Run(Node initialNode) - { - VisitDynamic(initialNode); - } - - #endregion - - public override Node Visit(MemberReferenceExpression expression) - { - base.Visit(expression); - if (expression.Member.Text == VariableToReplace.Name.Text) - return new IndexerExpression(new MemberReferenceExpression(expression.Target, (IndexerReplacement.Target as VariableReferenceExpression).Name.Text), IndexerReplacement.Index); - - return expression; - } - - public override Node Visit(VariableReferenceExpression expression) - { - base.Visit(expression); - if (expression.Name.Text == VariableToReplace.Name.Text) - return IndexerReplacement; - - return expression; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceVisitor.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceVisitor.cs deleted file mode 100644 index 3ebb3312ab..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideReplaceVisitor.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - /// - /// Class to replace a node by another in an AST - /// - internal class StrideReplaceVisitor : ShaderRewriter - { - #region Private members - - /// - /// The node to replace - /// - protected Node nodeToReplace; - - /// - /// the replacement node - /// - protected Node replacementNode; - - /// - /// a boolean stating that the operation is complete - /// - protected bool complete = false; - - #endregion - - #region Constructor - - public StrideReplaceVisitor(Node toReplace, Node replacement) : base(false, false) - { - nodeToReplace = toReplace; - replacementNode = replacement; - } - - #endregion - - #region Public method - - public bool Run(Node startNode) - { - VisitDynamic(startNode); - - return complete; - } - - #endregion - - #region Protected method - - public override Node DefaultVisit(Node node) - { - if (node == nodeToReplace) - { - complete = true; - return replacementNode; - } - - return base.DefaultVisit(node); - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderLibrary.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderLibrary.cs deleted file mode 100644 index d8cc8b4ba9..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderLibrary.cs +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Stride.Core.Extensions; -using Stride.Core.Storage; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideShaderLibrary - { - #region Delegate - - public delegate ShaderClassType LoadClassSourceDelegate(ShaderClassSource shaderClassSource, Stride.Core.Shaders.Parser.ShaderMacro[] shaderMacros, out ObjectId hash, out ObjectId hashPreprocessSource); - - #endregion - - #region Public members - - /// - /// List of all the mixin infos - /// - public HashSet MixinInfos = new HashSet(); - - /// - /// Load function - /// - public ShaderLoader ShaderLoader { get; private set; } - - /// - /// The source hashes - /// - public HashSourceCollection SourceHashes = new HashSourceCollection(); - - #endregion - - #region Private members - - private int lastMixIndex = 0; - - /// - /// List of contexts per macros - /// - private readonly Dictionary> mapMacrosToMixins = new Dictionary>(); - - #endregion - - #region Constructor - - public StrideShaderLibrary(ShaderLoader loader) - { - ShaderLoader = loader; - } - - #endregion - - #region Public methods - - - public bool AllowNonInstantiatedGenerics { get; set; } - - /// - /// Explore the ShaderSource and add the necessary shaders - /// - /// the ShaderSource to explore - /// the macros used - /// - public HashSet LoadShaderSource(ShaderSource shaderSource, Stride.Core.Shaders.Parser.ShaderMacro[] macros) - { - var mixinsToAnalyze = new HashSet(); - ExtendLibrary(shaderSource, macros, mixinsToAnalyze); - ReplaceMixins(mixinsToAnalyze); // no longer replace mixin, redo analysis everytime since there is no way to correctly detect something changed - return mixinsToAnalyze; - } - - /// - /// Deletes the shader cache for the specified shaders. - /// - /// The modified shaders. - public void DeleteObsoleteCache(HashSet modifiedShaders) - { - var mixinsToDelete = new HashSet(); - - foreach (var shaderName in modifiedShaders) - { - // find the mixin that depends on this shader - foreach (var mixin in MixinInfos) - if (mixin.ReferencedShaders.Contains(shaderName)) - mixinsToDelete.Add(mixin); - - // remove the source hash - SourceHashes.Remove(shaderName); - } - - // delete the mixins - foreach (var mixin in mixinsToDelete) - { - MixinInfos.Remove(mixin); - - // delete the mixin from the map - foreach (var macroMap in mapMacrosToMixins) - macroMap.Value.Remove(mixin); - } - - mixinsToDelete.Clear(); - - ShaderLoader.DeleteObsoleteCache(modifiedShaders); - } - - #endregion - - #region Private methods - - /// - /// Explore the ShaderSource and add the necessary shaders - /// - /// the ShaderSource to explore - /// the macros used - private void ExtendLibrary(ShaderSource shaderSource, Stride.Core.Shaders.Parser.ShaderMacro[] macros, HashSet mixinToAnalyze) - { - if (shaderSource is ShaderMixinSource) - { - var newMacros = MergeMacroSets((ShaderMixinSource)shaderSource, macros); - mixinToAnalyze.Add(GetModuleMixinInfo(shaderSource, newMacros)); - foreach (var composition in ((ShaderMixinSource)shaderSource).Compositions) - ExtendLibrary(composition.Value, newMacros, mixinToAnalyze); - } - else if (shaderSource is ShaderClassCode) - mixinToAnalyze.Add(GetModuleMixinInfo(shaderSource, macros)); - else if (shaderSource is ShaderArraySource) - { - foreach (var shader in ((ShaderArraySource)shaderSource).Values) - ExtendLibrary(shader, macros, mixinToAnalyze); - } - } - - /// - /// Get the ModuleMixinInfo based on the ShaderSource and the macros. Creates the needed shader if necessary - /// - /// the ShaderSource - /// the macros - /// the name of the macros - /// ModuleMixinInfo. - private ModuleMixinInfo GetModuleMixinInfo(ShaderSource shaderSource, Stride.Core.Shaders.Parser.ShaderMacro[] macros, string macrosString = null) - { - if (macros == null) - macros = new Stride.Core.Shaders.Parser.ShaderMacro[0]; - - if (macrosString == null) - { - macrosString = string.Join(",", macros.OrderBy(x => x.Name)); - } - - List context; - if (!mapMacrosToMixins.TryGetValue(macrosString, out context)) - { - context = new List(); - mapMacrosToMixins.Add(macrosString, context); - } - - var mixinInfo = context.FirstOrDefault(x => x.AreEqual(shaderSource, macros)); - if (mixinInfo == null) - { - mixinInfo = BuildMixinInfo(shaderSource, macros); - - if (mixinInfo.Instanciated) - { - MixinInfos.Add(mixinInfo); - context.Add(mixinInfo); - - mixinInfo.MinimalContext.Add(mixinInfo); - - if (!mixinInfo.Log.HasErrors) - { - LoadNecessaryShaders(mixinInfo, macros, macrosString); - } - } - } - - return mixinInfo; - } - - /// - /// Replace the mixins - /// - /// the mixins to verify - private void ReplaceMixins(HashSet mixinInfos) - { - foreach (var mixinInfo in mixinInfos) - CheckMixinForReplacement(mixinInfo); - } - - /// - /// Check if a previously analyzed instance of the shader can be used - /// - /// the ModuleMixinInfo - private void CheckMixinForReplacement(ModuleMixinInfo mixinInfo) - { - // TODO: infinite loop when cross reference (composition & =stage for example) - // TODO: change ReplacementChecked to enum None/InProgress/Done - if (mixinInfo.ReplacementChecked) - return; - - // Check parents and dependencies - mixinInfo.MinimalContext.Where(x => x != mixinInfo).ForEach(CheckMixinForReplacement); - - foreach (var replaceCandidateMixinInfo in MixinInfos.Where(x => x != mixinInfo && x.ShaderSource.Equals(mixinInfo.ShaderSource) && x.HashPreprocessSource == mixinInfo.HashPreprocessSource)) - { - if (replaceCandidateMixinInfo.Mixin.DependenciesStatus != AnalysisStatus.None) - { - if (replaceCandidateMixinInfo.Mixin.MinimalContext != null) - { - var noNeedToReplaced = replaceCandidateMixinInfo.Mixin.MinimalContext - .Where(dep => dep != replaceCandidateMixinInfo.Mixin) - .All(dep => mixinInfo.MinimalContext.FirstOrDefault(x => x.Mixin == dep) != null); - if (noNeedToReplaced) - { - mixinInfo.Mixin = replaceCandidateMixinInfo.Mixin; - mixinInfo.MixinAst = replaceCandidateMixinInfo.MixinAst; - mixinInfo.MixinGenericName = replaceCandidateMixinInfo.MixinGenericName; - break; - } - } - } - } - - mixinInfo.ReplacementChecked = true; - } - - /// - /// Build the ModuleMixinInfo class - /// - /// the ShaderSource to load - /// the macros applied on the source - /// the ModuleMixinInfo - private ModuleMixinInfo BuildMixinInfo(ShaderSource shaderSource, Stride.Core.Shaders.Parser.ShaderMacro[] macros) - { - ModuleMixinInfo mixinInfo = null; - - if (shaderSource is ShaderClassCode) - { - var shaderClassSource = shaderSource as ShaderClassCode; - mixinInfo = new ModuleMixinInfo - { - ShaderSource = shaderClassSource, - Macros = macros, - ReferencedShaders = { shaderClassSource.ClassName } - }; - LoadMixinFromClassSource(mixinInfo); - } - else if (shaderSource is ShaderMixinSource) - { - var shaderMixinSource = shaderSource as ShaderMixinSource; - - var shaderName = "Mix" + lastMixIndex; - ++lastMixIndex; - var fakeAst = new ShaderClassType(shaderName); - foreach (var classSource in shaderMixinSource.Mixins) - { - Identifier name; - if (classSource.GenericArguments != null && classSource.GenericArguments.Length > 0) - name = new IdentifierGeneric(classSource.ClassName, classSource.GenericArguments.Select(x => new Identifier(x.ToString())).ToArray()); - else - name = new Identifier(classSource.ClassName); - - fakeAst.BaseClasses.Add(new TypeName(name)); - } - - mixinInfo = new ModuleMixinInfo - { - MixinGenericName = shaderName, - Macros = macros, - MixinAst = fakeAst, - ShaderSource = shaderSource, - SourceHash = ObjectId.FromBytes(Encoding.UTF8.GetBytes(shaderName)), - Instanciated = true - }; - } - - return mixinInfo; - } - - /// - /// Loads the mixin based on its ShaderSource - /// - /// the ModuleMixinInfo - private void LoadMixinFromClassSource(ModuleMixinInfo mixinInfo) - { - var classSource = (ShaderClassCode)mixinInfo.ShaderSource; - - // If we allow to parse non instantiated generics, put empty generic arguments to let the ShaderLoader correctly expand the class - var shaderClass = ShaderLoader.LoadClassSource(classSource, mixinInfo.Macros, mixinInfo.Log, AllowNonInstantiatedGenerics); - - // If result is null, there was some errors while parsing. - if (shaderClass == null) - return; - - var shaderType = shaderClass.Type.DeepClone(); - - if (shaderType.ShaderGenerics.Count > 0) - mixinInfo.Instanciated = false; - - mixinInfo.HashPreprocessSource = shaderClass.PreprocessedSourceHash; - mixinInfo.SourceHash = shaderClass.SourceHash; - - if (!SourceHashes.ContainsKey(classSource.ClassName)) - SourceHashes.Add(classSource.ClassName, shaderClass.SourceHash); - - // check if it was a generic class and find out if the instantiation was correct - var genCount = Math.Max(shaderType.GenericParameters.Count, shaderType.ShaderGenerics.Count); - var argCount = classSource.GenericArguments?.Length ?? 0; - if (genCount > argCount) - { - mixinInfo.Instanciated = false; - mixinInfo.Log.Error(StrideMessageCode.ErrorClassSourceNotInstantiated, shaderType.Span, classSource.ClassName, argCount, genCount); - } - else if (shaderType.GenericParameters.Count > 0) - { - ModuleMixinInfo.CleanIdentifiers(shaderType.GenericParameters.Select(x => x.Name).ToList()); - } - - mixinInfo.MixinAst = shaderType; - mixinInfo.MixinGenericName = classSource.ClassName; - } - - /// - /// Loads generic classes that may appear in the mixin - /// - /// The mixin to investigate - /// The macros. - /// The macros string. - private void LoadNecessaryShaders(ModuleMixinInfo mixinInfo, Stride.Core.Shaders.Parser.ShaderMacro[] macros, string macrosString) - { - if (!mixinInfo.Instanciated) - return; - - // Look for all the generic calls - var shaderDependencyVisitor = new ShaderDependencyVisitor(mixinInfo.Log, ShaderLoader.SourceManager); - shaderDependencyVisitor.Run(mixinInfo.MixinAst); - - foreach (var foundClass in shaderDependencyVisitor.FoundClasses) - { - var classSource = new ShaderClassSource(foundClass, null); - var foundMixinInfo = GetModuleMixinInfo(classSource, macros, macrosString); - mixinInfo.MinimalContext.UnionWith(foundMixinInfo.MinimalContext); - mixinInfo.ReferencedShaders.UnionWith(foundMixinInfo.ReferencedShaders); - } - - foreach (var id in shaderDependencyVisitor.FoundIdentifiers) - { - var genericClass = id.Item1; - ModuleMixinInfo.CleanIdentifiers(genericClass.Identifiers); - var genericParams = BuildShaderGenericParameters(genericClass); - var classSource = new ShaderClassSource(genericClass.Text, genericParams); - - var instanciatedClassInfo = GetModuleMixinInfo(classSource, macros, macrosString); - mixinInfo.MinimalContext.UnionWith(instanciatedClassInfo.MinimalContext); - mixinInfo.ReferencedShaders.UnionWith(instanciatedClassInfo.ReferencedShaders); - - var newId = new Identifier(instanciatedClassInfo.MixinName); - if (id.Item2 is TypeName) // in the baseclass list or in a variable declaration - (id.Item2 as TypeName).Name = newId; - else if (id.Item2 is VariableReferenceExpression) - (id.Item2 as VariableReferenceExpression).Name = newId; - else if (id.Item2 is MemberReferenceExpression) - (id.Item2 as MemberReferenceExpression).Member = newId; - } - } - - #endregion - - #region Private static methods - - /// - /// Build the array of generic parameters - /// - /// the shader with its generics - /// the array of generic parameters - private static string[] BuildShaderGenericParameters(IdentifierGeneric genericClass) - { - var genericParameters = new List(); - - for (int i = 0; i < genericClass.Identifiers.Count; ++i) - { - var genericName = GetIdentifierName(genericClass.Identifiers[i]); - genericParameters.Add(genericName); - } - - return genericParameters.ToArray(); - } - - /// - /// Helper function to get the complete name of an identifier - /// - /// the identifier - /// the identifier name - private static string GetIdentifierName(Identifier identifier) - { - string genericName; - if (identifier is LiteralIdentifier) - genericName = (identifier as LiteralIdentifier).Value.Value.ToString(); - else if (identifier is IdentifierDot) - { - var idDot = identifier as IdentifierDot; - genericName = idDot.Identifiers.Aggregate("", (current, id) => current + (GetIdentifierName(id) + idDot.Separator)); - genericName = genericName.Substring(0, genericName.Length - idDot.Separator.Length); - } - else - genericName = identifier.Text; - - if (genericName == null) - throw new Exception(string.Format("Unable to find the name of the generic [{0}]", identifier)); - - return genericName; - } - - /// - /// Merge the set of macros in the mixin. The top level macros are always overidden by the child's ones (the one defined in the current ShaderMixinSource). - /// Also update the macros of the mixin. - /// - /// The mixin that will be looked at with the macros. - /// The external macros. - /// An array with all the macros - private Stride.Core.Shaders.Parser.ShaderMacro[] MergeMacroSets(ShaderMixinSource mixin, Stride.Core.Shaders.Parser.ShaderMacro[] macros) - { - var newMacros = new List(); - - // get the parent macros - foreach (var macro in macros) - { - newMacros.RemoveAll(x => x.Name == macro.Name); - newMacros.Add(macro); - } - - // override with child macros, the mixin's ones - foreach (var macro in mixin.Macros) - { - newMacros.RemoveAll(x => x.Name == macro.Name); - var tempMacro = new Stride.Core.Shaders.Parser.ShaderMacro(macro.Name, macro.Definition); - newMacros.Add(tempMacro); - } - - mixin.Macros = newMacros.Select(x => new ShaderMacro(x.Name, x.Definition)).ToList(); - return newMacros.ToArray(); - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderMixer.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderMixer.cs deleted file mode 100644 index 2d1bdb6223..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideShaderMixer.cs +++ /dev/null @@ -1,1683 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Extensions; -using Stride.Shaders.Parser.Analysis; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; - -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideShaderMixer - { - #region Public members - - /// - /// The final shader - /// - public ShaderClassType MixedShader = null; - - /// - /// Log of all the warnings and errors - /// - private readonly ShaderMixinParsingResult log; - - #endregion - - #region Private members - - /// - /// the module to generate - /// - private ModuleMixin mainModuleMixin = null; - - /// - /// the extern modules - /// - private CompositionDictionary CompositionsPerVariable; - - /// - /// List of all the method Declaration - /// - private HashSet> StageMethodInheritance = new HashSet>(); - - /// - /// Ordered list of all the mixin in their appearance order - /// - private List MixinInheritance = new List(); - - /// - /// Dictionary of all the mixins used for this compilation - /// - private Dictionary mixContext; - - /// - /// The default clone context - /// - private CloneContext defaultCloneContext; - - #endregion - - #region Constructor - - /// - /// Constructor - /// - /// the final shader information - /// The log. - /// all the mixins in the context - /// The compositions per variable. - /// The clone context. - /// - /// moduleMixin - /// or - /// log - /// or - /// context - /// - public StrideShaderMixer(ModuleMixin moduleMixin, ShaderMixinParsingResult log, Dictionary context, CompositionDictionary compositionsPerVariable, CloneContext cloneContext = null) - { - if (moduleMixin == null) - throw new ArgumentNullException("moduleMixin"); - - if (log == null) - throw new ArgumentNullException("log"); - - if (context == null) - throw new ArgumentNullException("context"); - - this.log = log; - - mixContext = context; - mainModuleMixin = moduleMixin; - defaultCloneContext = cloneContext; - - if (compositionsPerVariable != null) - CompositionsPerVariable = compositionsPerVariable; - else - CompositionsPerVariable = new CompositionDictionary(); - - var mixinsToAnalyze = new Stack(CompositionsPerVariable.Values.SelectMany(x => x)); - mixinsToAnalyze.Push(mainModuleMixin); - - while (mixinsToAnalyze.Count > 0) - AddDefaultCompositions(mixinsToAnalyze); - } - - #endregion - - #region Public methods - -/// - /// Performs the mix - /// - public void Mix() - { - CreateReferencesStructures(); - - mainModuleMixin.ClassReferences.RegenKeys(); - mainModuleMixin.ExternReferences.RegenKeys(); - mainModuleMixin.StaticReferences.RegenKeys(); - mainModuleMixin.StageInitReferences.RegenKeys(); - - foreach (var externMix in CompositionsPerVariable.Values.SelectMany(externMixes => externMixes)) - { - externMix.ClassReferences.RegenKeys(); - externMix.ExternReferences.RegenKeys(); - externMix.StaticReferences.RegenKeys(); - externMix.StageInitReferences.RegenKeys(); - } - - BuildMixinInheritance(mainModuleMixin); - MixinInheritance = MixinInheritance.Distinct().ToList(); - - ComputeMixinOccurrence(); - BuildStageInheritance(); - - LinkVariables(mainModuleMixin, "", new List()); - ProcessExterns(); - - // patch the base/this functions - PatchAllMethodInferences(mainModuleMixin); - - MergeReferences(); - - // then everything in the inheritance - RenameAllVariables(); - RenameAllMethods(); - - // group into one AST - GenerateShader(); - } - - public Shader GetMixedShader() - { - var shader = new Shader(); - shader.Declarations.AddRange(MixedShader.Members); - - return shader; - } - - #endregion - - #region Private methods - - /// - /// Add default compositions if no already present - /// - /// the remaining mixins to analyzez - private void AddDefaultCompositions(Stack mixinsToAnalyze) - { - var nextMixin = mixinsToAnalyze.Pop(); - - foreach (var externVar in nextMixin.VariableDependencies) - { - if (!CompositionsPerVariable.ContainsKey(externVar.Key)) - { - if (externVar.Key.Type is ArrayType) - { - // Empty compositions for ArrayType - CompositionsPerVariable.Add(externVar.Key, new List()); - } - else - { - var newComp = externVar.Value.DeepClone(defaultCloneContext); - mixinsToAnalyze.Push(newComp); - CompositionsPerVariable.Add(externVar.Key, new List { newComp }); - } - } - } - foreach (var dep in nextMixin.InheritanceList) - mixinsToAnalyze.Push(dep); - } - - /// - /// performs semantic analysis on mixin that have composition arrays - /// - private void RedoSematicAnalysis() - { - // first: assign the size of the array - foreach (var composition in CompositionsPerVariable.Where(x => x.Key.Type is ArrayType)) - { - var arrayType = composition.Key.Type as ArrayType; - if (arrayType.Dimensions.Count > 1) - { - log.Error(StrideMessageCode.ErrorMultidimensionalCompositionArray, arrayType.Span, arrayType, composition.Value.First().MixinName); - return; - } - arrayType.Dimensions[0] = new LiteralExpression(composition.Value.Count); - } - - // then rerun the semantic analysis - foreach (var composition in CompositionsPerVariable.Where(x => x.Key.Type is ArrayType)) - { - var moduleMixin = GetTopMixin(composition.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin); - var compilationContext = moduleMixin.MinimalContext.Where(x => !(moduleMixin.InheritanceList.Contains(x) || x == moduleMixin)).ToList(); - - // rerun the semantic analysis in all the shader that inherits from the one where the composition was declared. - foreach (var inheritedMixin in moduleMixin.InheritanceList) - inheritedMixin.ParsingInfo = StrideSemanticAnalysis.RunAnalysis(inheritedMixin, compilationContext, true); - moduleMixin.ParsingInfo = StrideSemanticAnalysis.RunAnalysis(moduleMixin, compilationContext, true); - - if (moduleMixin.ParsingInfo.ErrorsWarnings.HasErrors) - return; - //throw new Exception("Semantic analysis failed in StrideShaderMixer"); - } - } - - /// - /// Create the references for each top mixin - /// - private void CreateReferencesStructures() - { - RedoSematicAnalysis(); - CreateReferencesStructures(mainModuleMixin); - foreach (var compositions in CompositionsPerVariable.Values) - { - foreach (var comp in compositions) - CreateReferencesStructures(comp); - } - } - - /// - /// Merge reference from mixin dependencies - /// - /// - private void CreateReferencesStructures(ModuleMixin mixin) - { - GetStaticReferences(mixin, mixin); - - // merge class reference - mixin.ClassReferences.Merge(mixin.ParsingInfo.ClassReferences); - foreach (var dep in mixin.InheritanceList) - mixin.ClassReferences.Merge(dep.ParsingInfo.ClassReferences); - // merge static references - mixin.StaticReferences.Merge(mixin.ParsingInfo.StaticReferences); - foreach (var dep in mixin.InheritanceList) - mixin.StaticReferences.Merge(dep.ParsingInfo.StaticReferences); - // merge extern references - mixin.ExternReferences.Merge(mixin.ParsingInfo.ExternReferences); - foreach (var dep in mixin.InheritanceList) - mixin.ExternReferences.Merge(dep.ParsingInfo.ExternReferences); - // merge stage init references - mixin.StageInitReferences.Merge(mixin.ParsingInfo.StageInitReferences); - foreach (var dep in mixin.InheritanceList) - mixin.StageInitReferences.Merge(dep.ParsingInfo.StageInitReferences); - } - - /// - /// bubble up the static references in the mixin dependency tree - /// - /// the top mixin - /// the mixin to look into - private void GetStaticReferences(ModuleMixin topMixin, ModuleMixin staticMixin) - { - foreach (var staticDep in staticMixin.ParsingInfo.StaticClasses) - GetStaticReferences(topMixin, staticDep); - foreach (var staticDep in staticMixin.InheritanceList) - GetStaticReferences(topMixin, staticDep); - - topMixin.StaticReferences.Merge(staticMixin.ParsingInfo.StaticReferences); - } - - /// - /// Rename the links of the variables - /// - /// the current mixin - /// the string to append - /// list of already visited mixin - private void LinkVariables(ModuleMixin mixin, string context, List visitedMixins) - { - if (visitedMixins.Contains(mixin)) - return; - - visitedMixins.Add(mixin); - - foreach (var variable in mixin.LocalVirtualTable.Variables.Select(x => x.Variable)) - { - if (variable.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern)) - { - List mixins; - if (CompositionsPerVariable.TryGetValue(variable, out mixins)) - { - if (variable.Type is ArrayType) - { - for (var i = 0; i < mixins.Count; ++i) - { - var baselink = "." + variable.Name.Text + "[" + i + "]" + context; - LinkVariables(mixins[i], baselink, visitedMixins); - } - } - else - { - var baselink = "." + variable.Name.Text + context; - LinkVariables(mixins[0], baselink, visitedMixins); - } - } - } - - if (!(variable.Qualifiers.Values.Contains(StrideStorageQualifier.Stream) - || variable.Qualifiers.Values.Contains(StrideStorageQualifier.PatchStream) - || variable.Qualifiers.Values.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern))) - { - var attribute = variable.Attributes.OfType().FirstOrDefault(x => x.Name == "Link"); - if (attribute == null) - { - // Try to get class name before generics - //string baseClassName; - //if (!genericTypeDefinitions.TryGetValue(baseClass, out baseClassName)) - // baseClassName = baseClass.Name; - - // TODO: class name before renaming if generics - string linkName; - - // Use Map attribute (if it exists) - var mapAttribute = variable.Attributes.OfType().FirstOrDefault(x => x.Name == "Map"); - if (mapAttribute != null) - { - linkName = (string)mapAttribute.Parameters[0].Value; - // Remove "Keys" from class name (or maybe we should just include it in key name to avoid issues?) - linkName = linkName.Replace("Keys.", "."); - } - else - { - linkName = mixin.MixinGenericName + "." + variable.Name.Text; - } - - attribute = new AttributeDeclaration { Name = new Identifier("Link"), Parameters = new List { new Literal(linkName) } }; - variable.Attributes.Add(attribute); - } - - // Append location to key in case it is a local variable - if (!variable.Qualifiers.Values.Contains(StrideStorageQualifier.Stage)) - { - attribute.Parameters[0].SubLiterals = null; // set to null to avoid conflict with the member Value - attribute.Parameters[0].Value = (string)attribute.Parameters[0].Value + context; - } - } - } - - foreach (var variable in mixin.StaticReferences.VariablesReferences.Select(x => x.Key)) - { - var attribute = variable.Attributes.OfType().FirstOrDefault(x => x.Name == "Link"); - if (attribute == null) - { - var baseClassName = (variable.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinGenericName; - - attribute = new AttributeDeclaration { Name = new Identifier("Link"), Parameters = new List { new Literal(baseClassName + "." + variable.Name.Text) } }; - variable.Attributes.Add(attribute); - } - } - - mixin.InheritanceList.ForEach(x => LinkVariables(x, context, visitedMixins)); - } - - /// - /// Merge the class references of the externs to the main class, and the static calls too - /// - private void MergeReferences() - { - foreach (var externMixes in CompositionsPerVariable.Values) - { - foreach (var externMix in externMixes) - mainModuleMixin.ClassReferences.Merge(externMix.ClassReferences); - } - - mainModuleMixin.ClassReferences.Merge(mainModuleMixin.StaticReferences); - } - - /// - /// Add the stage variables from the mixin to the main one - /// - /// the ModuleMixin - private void AddStageVariables(ModuleMixin mixin) - { - mixin.InheritanceList.ForEach(AddStageVariables); - CompositionsPerVariable.Where(x => mixin.LocalVirtualTable.Variables.Any(y => y.Variable == x.Key)).ToList().ForEach(externMixes => externMixes.Value.ForEach(AddStageVariables)); - - foreach (var variable in mixin.LocalVirtualTable.Variables) - { - if (variable.Variable.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - var shaderName = variable.Shader.Name.Text; - var sameVar = mainModuleMixin.ClassReferences.VariablesReferences.FirstOrDefault(x => x.Key.Name.Text == variable.Variable.Name.Text && (x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName == shaderName).Key; - if (sameVar != null) - continue; - } - if (!mainModuleMixin.ClassReferences.VariablesReferences.ContainsKey(variable.Variable)) - mainModuleMixin.ClassReferences.VariablesReferences.Add(variable.Variable, new HashSet()); - } - } - - /// - /// Build an ordered list of mixin defining the inheritance for stage values - /// - /// the mixin to add - private void BuildMixinInheritance(ModuleMixin mixin) - { - mixin.InheritanceList.ForEach(BuildMixinInheritance); - MixinInheritance.Add(mixin); - CompositionsPerVariable.Where(x => mixin.LocalVirtualTable.Variables.Any(y => y.Variable == x.Key)).ToList().ForEach(externMixes => externMixes.Value.ForEach(BuildMixinInheritance)); - } - - /// - /// Compute the occurrence Id of each mixin - /// - private void ComputeMixinOccurrence() - { - foreach (var mixin in MixinInheritance) - { - foreach (var mixin2 in MixinInheritance) - { - if (mixin.MixinName == mixin2.MixinName) - ++(mixin.OccurrenceId); - if (mixin == mixin2) - break; - } - } - } - - /// - /// Find the correct variable inference - /// - /// - /// - /// - private Variable FindVariable(Expression expression, ref ModuleMixin mixin) - { - Variable result = null; - var index = 0; - if (expression is VariableReferenceExpression) - { - result = FindVariableInMixin((expression as VariableReferenceExpression).Name.Text, mixin); - } - else if (expression is MemberReferenceExpression) - { - var memberExpression = expression as MemberReferenceExpression; - var target = memberExpression.Target; - - if (target.TypeInference.Declaration is Variable) - FindVariable(target, ref mixin); - else if (target.TypeInference.Declaration is ShaderClassType || target.TypeInference.TargetType is ShaderClassType) - FindShader(target, ref mixin); - - result = FindVariableInMixin(memberExpression.Member.Text, mixin); - } - else if (expression is IndexerExpression) - { - var indexerExpression = expression as IndexerExpression; - var target = indexerExpression.Target; - - if (target.TypeInference.Declaration is Variable) - result = FindVariable(target, ref mixin); - - index = (int)(indexerExpression.Index as LiteralExpression).Value; - } - - if (result != null && result.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern) && !(result.Type is ArrayType)) - mixin = CompositionsPerVariable[result][index]; - - return result; - } - - private Variable FindVariableInMixin(string varName, ModuleMixin mixin) - { - if (varName == "streams") - return null; - - var foundVar = mixin.VirtualTable.Variables.FirstOrDefault(x => x.Variable.Name.Text == varName); - if (foundVar != null) - return foundVar.Variable; - - log.Error(StrideMessageCode.ErrorVariableNotFound, new SourceSpan(), varName, mixin.MixinName); - return null; - } - - private MethodDeclaration FindMethod(Expression expression, ref ModuleMixin mixin) - { - if (expression is MemberReferenceExpression) - { - var memberExpression = expression as MemberReferenceExpression; - var target = memberExpression.Target; - - if (target.TypeInference.Declaration is Variable) - FindVariable(target, ref mixin); - else if (target.TypeInference.Declaration is ShaderClassType || target.TypeInference.TargetType is ShaderClassType) - FindShader(target, ref mixin); - } - - var topMixin = GetTopMixin(mixin); - if (topMixin == null) - { - log.Error(StrideMessageCode.ErrorTopMixinNotFound, expression.Span, expression); - return null; - } - var foundMethod = topMixin.GetMethodFromExpression(expression); - if (foundMethod == null) - { - log.Error(StrideMessageCode.ErrorCallNotFound, expression.Span, expression); - return null; - } - if (foundMethod.Qualifiers.Contains(StrideStorageQualifier.Abstract)) - { - log.Error(StrideMessageCode.ErrorCallToAbstractMethod, expression.Span, expression, foundMethod); - return null; - } - return foundMethod; - } - - private void FindShader(Expression expression, ref ModuleMixin mixin) - { - if (expression is MemberReferenceExpression) - { - var memberExpression = expression as MemberReferenceExpression; - var target = memberExpression.Target; - - if (target.TypeInference.Declaration is Variable) - FindVariable(target, ref mixin); - - var mixinName = (expression.TypeInference.Declaration as ShaderClassType).Name.Text; - mixin = mixin.MixinName == mixinName ? mixin : mixin.InheritanceList.FirstOrDefault(x => x.MixinName == mixinName); - } - else if (expression is IndexerExpression) - { - var indexerExpression = expression as IndexerExpression; - var target = indexerExpression.Target; - - Variable result = null; - - if (target.TypeInference.Declaration is Variable) - result = FindVariable(target, ref mixin); - - var index = (int)(indexerExpression.Index as LiteralExpression).Value; - if (result != null && result.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern)) - mixin = CompositionsPerVariable[result][index]; - } - } - - /// - /// Build inheritance list for methods - /// - private void BuildStageInheritance() - { - foreach (var mixin in MixinInheritance) - InsertStageMethods(mixin.LocalVirtualTable.Methods.Select(x => x.Method).Where(x => x.Qualifiers.Values.Contains(StrideStorageQualifier.Stage)).ToList(), GetTopMixin(mixin)); - } - - /// - /// Adds le methods in the list to the inheritance list - /// - /// the list of methods - /// the mixin in which the methods are defined - public void InsertStageMethods(List extMethodList, ModuleMixin mixin) - { - foreach (var extMethod in extMethodList) - { - if (extMethod is MethodDefinition) - { - var isClone = extMethod.Qualifiers.Values.Contains(StrideStorageQualifier.Clone); - var newEntry = true; - - // find a corresponding method - var vtReference = mixin.VirtualTable.GetBaseDeclaration(extMethod); - foreach (var stageMethodList in StageMethodInheritance) - { - if (!newEntry) - break; - - if (stageMethodList == null || stageMethodList.Count == 0) - continue; - - var firstOccurrence = stageMethodList.First(); - var occurrenceMixin = firstOccurrence.GetTag(StrideTags.ShaderScope) as ModuleMixin; - var listVTReference = occurrenceMixin.VirtualTable.GetBaseDeclaration(firstOccurrence); - - if (vtReference.Slot != listVTReference.Slot || vtReference.Shader != listVTReference.Shader) - continue; - - newEntry = false; - var extMixin = extMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin; - if (isClone || extMixin.OccurrenceId == 1) - stageMethodList.Add(extMethod); - } - - if (newEntry) - { - var list = new List(); - list.Add(extMethod); - StageMethodInheritance.Add(list); - } - - var externClassRef = GetTopMixin(mixin).ClassReferences; - if (externClassRef != null && !mainModuleMixin.ClassReferences.MethodsReferences.ContainsKey(extMethod)) - { - externClassRef.RegenKeys(); - mainModuleMixin.ClassReferences.MethodsReferences.Add(extMethod, externClassRef.MethodsReferences[extMethod]); - externClassRef.MethodsReferences.Remove(extMethod); - } - } - } - } - - /// - /// Add the method to its correct dictionary - /// - /// - private void AddToMethodsReferences(MethodInvocationExpression expression) - { - var decl = expression.Target.TypeInference.Declaration as MethodDeclaration; - if (decl != null) - { - if (!mainModuleMixin.ClassReferences.MethodsReferences.ContainsKey(decl)) - mainModuleMixin.ClassReferences.MethodsReferences.Add(decl, new HashSet()); - mainModuleMixin.ClassReferences.MethodsReferences[decl].Add(expression); - } - } - - /// - /// Remove the method from the correctdictionary - /// - /// - private void RemoveFromMethodsReferences(MethodInvocationExpression expression, ModuleMixin mixin) - { - foreach (var refList in mixin.ClassReferences.MethodsReferences) - refList.Value.RemoveWhere(x => x == expression); - - foreach (var refList in mainModuleMixin.ClassReferences.MethodsReferences) - refList.Value.RemoveWhere(x => x == expression); - } - - /// - /// Find the mixin in which the parameter is a dependency - /// - /// the mixin - /// the mixin that depends on the parameter - private ModuleMixin GetTopMixin(ModuleMixin mixin) - { - var topMixin = mainModuleMixin == mixin || mainModuleMixin.InheritanceList.Any(x => x == mixin) ? mainModuleMixin : null; - if (topMixin == null) - { - foreach (var externMixes in CompositionsPerVariable.Values) - { - foreach (var externMix in externMixes) - { - topMixin = externMix == mixin || externMix.InheritanceList.Any(x => x == mixin) ? externMix : null; - if (topMixin != null) - break; - } - if (topMixin != null) - break; - } - } - return topMixin; - } - - /// - /// Find a static method - /// - /// the calling expression - /// the correct called method - private MethodDeclaration FindStaticMethod(MethodInvocationExpression expression) - { - var defMixin = (expression.Target.TypeInference.Declaration as MethodDeclaration).GetTag(StrideTags.ShaderScope) as ModuleMixin; - defMixin = mixContext[defMixin.MixinName]; - return defMixin.GetMethodFromExpression(expression.Target); - } - - /// - /// Gets the base stage method - /// - /// the reference expression - /// the base declaration - private MethodDeclaration GetBaseStageMethod(MethodInvocationExpression methodCall) - { - var mixin = methodCall.GetTag(StrideTags.CurrentShader) as ModuleMixin; - var vtReference = mixin.VirtualTable.GetBaseDeclaration(methodCall.Target.TypeInference.Declaration as MethodDeclaration); - foreach (var stageMethodList in StageMethodInheritance) - { - if (stageMethodList == null || stageMethodList.Count == 0) - continue; - - var firstOccurrence = stageMethodList.First(); - var occurrenceMixin = firstOccurrence.GetTag(StrideTags.ShaderScope) as ModuleMixin; - var listVTReference = occurrenceMixin.VirtualTable.GetBaseDeclaration(firstOccurrence); - - if (vtReference.Slot != listVTReference.Slot || vtReference.Shader != listVTReference.Shader) - continue; - - //TODO: can we call a base without overriding ? - for (int j = stageMethodList.Count - 1; j > 0; --j) - { - var decl = stageMethodList[j]; - if (decl.GetTag(StrideTags.ShaderScope) as ModuleMixin == mixin) - return stageMethodList[j - 1]; - } - //for (int j = stageMethodList.Count - 1; j >= 0; --j) - //{ - // var decl = stageMethodList[j]; - // if (decl.GetTag(StrideTags.ShaderScope) as ModuleMixin == mixin) - // { - // if (j == 0) - // return stageMethodList[0]; - // return stageMethodList[j - 1]; - // } - //} - } - return null; - } - - /// - /// Gets the last override of the method - /// - /// the method call - /// the declaration - private MethodDeclaration GetThisStageMethod(MethodInvocationExpression methodCall) - { - var mixin = methodCall.GetTag(StrideTags.CurrentShader) as ModuleMixin; - var vtReference = mixin.VirtualTable.GetBaseDeclaration(methodCall.Target.TypeInference.Declaration as MethodDeclaration); - foreach (var stageMethodList in StageMethodInheritance) - { - if (stageMethodList == null || stageMethodList.Count == 0) - continue; - - var firstOccurrence = stageMethodList.First(); - var occurrenceMixin = firstOccurrence.GetTag(StrideTags.ShaderScope) as ModuleMixin; - var listVTReference = occurrenceMixin.VirtualTable.GetBaseDeclaration(firstOccurrence); - - if (vtReference.Slot != listVTReference.Slot || vtReference.Shader != listVTReference.Shader) - continue; - - return stageMethodList.Last(); - } - return null; - } - - /// - /// Solves both base and direct method calls - /// - /// - private void PatchAllMethodInferences(ModuleMixin mixin) - { - mixin.InheritanceList.ForEach(PatchAllMethodInferences); - CompositionsPerVariable.Where(x => mixin.LocalVirtualTable.Variables.Any(y => y.Variable == x.Key)).ToList().ForEach(externMixes => externMixes.Value.ForEach(PatchAllMethodInferences)); - - var topMixin = GetTopMixin(mixin); - - foreach (var baseCall in mixin.ParsingInfo.BaseMethodCalls) - { - MethodDeclaration decl = null; - if ((baseCall.Target.TypeInference.Declaration as MethodDeclaration).Qualifiers.Contains(StrideStorageQualifier.Stage)) - decl = GetBaseStageMethod(baseCall); - else - decl = topMixin.GetBaseMethodFromExpression(baseCall.Target, mixin); - - if (decl != null) - { - RemoveFromMethodsReferences(baseCall, topMixin); - - baseCall.TypeInference.TargetType = decl.ReturnType; - baseCall.Target.TypeInference.Declaration = decl; - - AddToMethodsReferences(baseCall); - } - else - log.Error(StrideMessageCode.ErrorImpossibleBaseCall, baseCall.Span, baseCall, mixin.MixinName); - } - - // resolve this calls - foreach (var thisCall in mixin.ParsingInfo.ThisMethodCalls) - { - MethodDeclaration decl = null; - if ((thisCall.Target.TypeInference.Declaration as MethodDeclaration).Qualifiers.Contains(StrideStorageQualifier.Stage)) - decl = GetThisStageMethod(thisCall); - else if (thisCall.ContainsTag(StrideTags.StaticRef)) - decl = FindStaticMethod(thisCall); - else - decl = topMixin.GetMethodFromExpression(thisCall.Target); - - if (decl != null) - { - RemoveFromMethodsReferences(thisCall, topMixin); - - thisCall.TypeInference.TargetType = decl.ReturnType; - thisCall.Target.TypeInference.Declaration = decl; - - if (!thisCall.ContainsTag(StrideTags.StaticRef)) - AddToMethodsReferences(thisCall); - } - else - log.Error(StrideMessageCode.ErrorImpossibleVirtualCall, thisCall.Span, thisCall, mixin.MixinName, mainModuleMixin.MixinName); - } - } - - /// - /// Rebranch the type inference for the stage variable reference in the extern - /// - /// - private void InferStageVariables(ModuleMixin externMix) - { - var stageDict = externMix.ClassReferences.VariablesReferences.Where(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Stage)).ToDictionary(x => x.Key, x => x.Value); - foreach (var variable in stageDict) - { - var shaderName = (variable.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName; - var foundDeclaration = mainModuleMixin.ClassReferences.VariablesReferences.FirstOrDefault(x => x.Key.Name.Text == variable.Key.Name.Text && (x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName == shaderName).Key; - if (foundDeclaration == null)// get by semantics if necessary - { - var semantic = variable.Key.Qualifiers.Values.OfType().FirstOrDefault(); - if (semantic != null) - { - foundDeclaration = mainModuleMixin.ClassReferences.VariablesReferences.FirstOrDefault( - x => - { - var varSemantic = x.Key.Qualifiers.Values.OfType().FirstOrDefault(); - if (varSemantic != null && semantic.Name.Text == varSemantic.Name.Text) - return true; - return false; - }).Key; - } - } - - if (foundDeclaration != null) - { - mainModuleMixin.ClassReferences.VariablesReferences[foundDeclaration].UnionWith(variable.Value); - foreach (var varRef in variable.Value) - { - varRef.Expression.TypeInference.Declaration = foundDeclaration; - varRef.Expression.TypeInference.TargetType = foundDeclaration.Type; - } - } - else - { - log.Error(StrideMessageCode.ErrorMissingStageVariable, variable.Key.Span, variable, externMix.MixinName); - return; - } - } - - foreach (var key in stageDict.Keys) - externMix.ClassReferences.VariablesReferences.Remove(key); - } - - /// - /// Inference for extern calls - /// - /// - private void ProcessExternReferences(ModuleMixin mixin) - { - mixin.InheritanceList.ForEach(ProcessExternReferences); - CompositionsPerVariable.Where(x => mixin.LocalVirtualTable.Variables.Any(y => y.Variable == x.Key)).ToList().ForEach(externMixes => externMixes.Value.ForEach(ProcessExternReferences)); - - foreach (var externReferences in mixin.ExternReferences.VariablesReferences) - { - foreach (var expression in externReferences.Value) - { - var searchMixin = mixin; - var foundDefinition = FindVariable(expression.Expression, ref searchMixin); - if (foundDefinition != null) // should be always true - { - if (foundDefinition.Qualifiers.Contains(StrideStorageQualifier.Stage)) - { - - var sameVar = - mixin.ClassReferences.VariablesReferences.FirstOrDefault( - x => x.Key.Name.Text == foundDefinition.Name.Text && (x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName == (foundDefinition.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName).Key; - if (sameVar == null) - { - mixin.ClassReferences.VariablesReferences.Add(foundDefinition, new HashSet()); - sameVar = foundDefinition; - } - mixin.ClassReferences.VariablesReferences[sameVar].Add(expression); - expression.Expression.TypeInference.Declaration = sameVar; - expression.Expression.TypeInference.TargetType = sameVar.Type.ResolveType(); - } - else - { - if (!mixin.ClassReferences.VariablesReferences.ContainsKey(foundDefinition)) - mixin.ClassReferences.VariablesReferences.Add(foundDefinition, new HashSet()); - mixin.ClassReferences.VariablesReferences[foundDefinition].Add(expression); - expression.Expression.TypeInference.Declaration = foundDefinition; - expression.Expression.TypeInference.TargetType = foundDefinition.Type.ResolveType(); - } - } - else - log.Error(StrideMessageCode.ErrorExternReferenceNotFound, expression.Expression.Span, expression, mixin.MixinName); - } - } - mixin.ExternReferences.VariablesReferences.Clear(); - - foreach (var externReferences in mixin.ExternReferences.MethodsReferences) - { - foreach (var methodInvoc in externReferences.Value) - { - var searchMixin = mixin; - var foundDefinition = FindMethod(methodInvoc.Target, ref searchMixin); - if (foundDefinition != null) // should be always true - { - if (!mixin.ClassReferences.MethodsReferences.ContainsKey(foundDefinition)) - mixin.ClassReferences.MethodsReferences.Add(foundDefinition, new HashSet()); - mixin.ClassReferences.MethodsReferences[foundDefinition].Add(methodInvoc); - methodInvoc.Target.TypeInference.Declaration = foundDefinition; - } - else - log.Error(StrideMessageCode.ErrorExternReferenceNotFound, methodInvoc.Span, methodInvoc, mixin.MixinName); - } - } - mixin.ExternReferences.MethodsReferences.Clear(); - } - - /// - /// Redo type inference for stage init variables - /// - /// the module mixin to analyze - private void ProcessStageInitReferences(ModuleMixin moduleMixin) - { - foreach (var variable in moduleMixin.StageInitReferences.VariablesReferences) - { - var varMixinName = ((ModuleMixin)variable.Key.GetTag(StrideTags.ShaderScope)).MixinName; - var mixin = MixinInheritance.FirstOrDefault(x => x.MixinName == varMixinName); - if (mixin == null) - { - log.Error(StrideMessageCode.ErrorStageMixinNotFound, new SourceSpan(), varMixinName, moduleMixin.MixinName); - return; - } - - var trueVar = mixin.ClassReferences.VariablesReferences.FirstOrDefault(x => x.Key.Name.Text == variable.Key.Name.Text).Key; - if (trueVar == null) - { - var sourceShader = ((ModuleMixin)variable.Key.GetTag(StrideTags.ShaderScope)).MixinName; - log.Error(StrideMessageCode.ErrorStageMixinVariableNotFound, new SourceSpan(), varMixinName, sourceShader, moduleMixin.MixinName); - return; - } - - foreach (var varRef in variable.Value) - { - varRef.Expression.TypeInference.Declaration = trueVar; - varRef.Expression.TypeInference.TargetType = trueVar.Type.ResolveType(); - } - - mainModuleMixin.ClassReferences.VariablesReferences[trueVar].UnionWith(variable.Value); - } - foreach (var method in moduleMixin.StageInitReferences.MethodsReferences) - { - var varMixinName = ((ModuleMixin)method.Key.GetTag(StrideTags.ShaderScope)).MixinName; - var mixin = MixinInheritance.FirstOrDefault(x => x.MixinName == varMixinName); - if (mixin == null) - { - log.Error(StrideMessageCode.ErrorStageMixinNotFound, new SourceSpan(), varMixinName, moduleMixin.MixinName); - return; - } - - var trueVar = GetTopMixin(mixin).GetMethodFromDeclaration(method.Key); - if (trueVar == null) - { - log.Error(StrideMessageCode.ErrorStageMixinMethodNotFound, new SourceSpan(), varMixinName, method, moduleMixin.MixinName); - return; - } - - foreach (var varRef in method.Value) - { - varRef.Target.TypeInference.Declaration = trueVar; - varRef.Target.SetTag(StrideTags.VirtualTableReference, trueVar.GetTag(StrideTags.VirtualTableReference)); - } - - mainModuleMixin.ClassReferences.MethodsReferences[trueVar].UnionWith(method.Value); - } - } - - /// - /// Relink stage references, extern references, merge static references from externs - /// - private void ProcessExterns() - { - ProcessExternReferences(mainModuleMixin); - - AddStageVariables(mainModuleMixin); - foreach (var externMix in CompositionsPerVariable.Values.SelectMany(externMixes => externMixes)) - InferStageVariables(externMix); - - ProcessStageInitReferences(mainModuleMixin); - CompositionsPerVariable.Values.SelectMany(externMixes => externMixes).ToList().ForEach(ProcessStageInitReferences); - - foreach (var externMix in CompositionsPerVariable.Values.SelectMany(externMixes => externMixes)) - { - foreach (var variable in externMix.StaticReferences.VariablesReferences) - { - var varMixinName = (variable.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName; - var staticVars = mainModuleMixin.StaticReferences.VariablesReferences.Where(x => (x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName == varMixinName && x.Key.Name.Text == variable.Key.Name.Text).ToDictionary(x => x.Key, x => x.Value); - - // if the entry already exists, append to it - if (staticVars.Count > 0) - { - var staticVar = staticVars.FirstOrDefault(); - foreach (var varRef in variable.Value) - { - varRef.Expression.TypeInference.Declaration = staticVar.Key; - varRef.Expression.TypeInference.TargetType = staticVar.Key.Type.ResolveType(); - } - staticVar.Value.UnionWith(variable.Value); - } - else // create the entry - mainModuleMixin.StaticReferences.VariablesReferences.Add(variable.Key, variable.Value); - } - foreach (var method in externMix.StaticReferences.MethodsReferences) - { - var methodMixinName = (method.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName; - var staticMethods = mainModuleMixin.StaticReferences.MethodsReferences.Where(x => (x.Key.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName == methodMixinName && x.Key.IsSameSignature(method.Key)).ToDictionary(x => x.Key, x => x.Value); - - // if the entry already exists, append to it - if (staticMethods.Count > 0) - { - var staticMethod = staticMethods.FirstOrDefault(); - foreach (var methodRef in method.Value) - methodRef.Target.TypeInference.Declaration = staticMethod.Key; - - staticMethod.Value.UnionWith(method.Value); - } - else // create the entry - mainModuleMixin.StaticReferences.MethodsReferences.Add(method.Key, method.Value); - } - } - } - - /// - /// Rename all the variables - /// - private void RenameAllVariables() - { - int id = 0; - RenameAllVariables(mainModuleMixin.ClassReferences, ref id); - } - - /// - /// Rename all the variables and their references based on the id - /// - /// the pool to rename - /// the id used to build the new name - private void RenameAllVariables(ReferencesPool references, ref int id) - { - foreach (var variable in references.VariablesReferences) - { - foreach (var varRef in variable.Value) - { - var memberReferenceExpression = varRef.Expression as MemberReferenceExpression; - if (memberReferenceExpression != null) - { - if (variable.Key.Qualifiers.Contains(StrideStorageQualifier.Stream)) // TODO: change test - { - memberReferenceExpression.Member = variable.Key.Name; - - var type = memberReferenceExpression.Target.TypeInference.TargetType; - if (type == null || !type.IsStreamsType() || !type.IsStreamsMutable()) - memberReferenceExpression.Target = new VariableReferenceExpression(StreamsType.ThisStreams); - } - else if (variable.Key.Qualifiers.Contains(StrideStorageQualifier.PatchStream)) - { - memberReferenceExpression.Member = variable.Key.Name; - } - else - { - var vre = new VariableReferenceExpression(variable.Key.Name); - vre.TypeInference.Declaration = variable.Key; - vre.TypeInference.TargetType = variable.Key.Type.ResolveType(); - ReplaceMemberReferenceExpressionByVariableReferenceExpression(memberReferenceExpression, vre, varRef.Node); - varRef.Expression = vre; - } - } - else - ((VariableReferenceExpression)varRef.Expression).Name = variable.Key.Name; - } - - variable.Key.Name.Text += "_id" + id; - ++id; - } - } - - /// - /// Rename the methods and their references - /// - /// the pool to rename - /// the id used to build the new name - private void RenameAllMethods(ReferencesPool references, HashSet renameFreeMethods, ref int id) - { - foreach (var method in references.MethodsReferences) - { - if (renameFreeMethods.Contains(method.Key) || !(method.Key is MethodDefinition)) - continue; - - foreach (var methodRef in method.Value) - { - var targetMre = methodRef.Target as MemberReferenceExpression; - if (targetMre != null) - { - var vre = new VariableReferenceExpression(); - methodRef.Target = vre; - vre.TypeInference.Declaration = targetMre.TypeInference.Declaration; - vre.TypeInference.TargetType = targetMre.TypeInference.TargetType; - } - - var targetVre = methodRef.Target as VariableReferenceExpression; - targetVre.Name = method.Key.Name; - } - - method.Key.Name.Text += "_id" + id; - ++id; - } - references.RegenKeys(); - } - - /// - /// Rename all the methods - /// - private void RenameAllMethods() - { - // Find entry points - var vertexShaderMethod = FindEntryPoint("VSMain"); - var hullShaderMethod = FindEntryPoint("HSMain"); - var hullConstantShaderMethod = FindEntryPoint("HSConstantMain"); - var domainShaderMethod = FindEntryPoint("DSMain"); - var geometryShaderMethod = FindEntryPoint("GSMain"); - var pixelShaderMethod = FindEntryPoint("PSMain"); - var computeShaderMethod = FindEntryPoint("CSMain"); - - if (pixelShaderMethod != null && pixelShaderMethod.Body.Count == 0) - pixelShaderMethod = null; - - var renameFreeMethods = new HashSet(); - - // store these methods to prevent their renaming - if (vertexShaderMethod != null) - renameFreeMethods.Add(vertexShaderMethod); - if (hullShaderMethod != null) - renameFreeMethods.Add(hullShaderMethod); - if (hullConstantShaderMethod != null) - renameFreeMethods.Add(hullConstantShaderMethod); - if (domainShaderMethod != null) - renameFreeMethods.Add(domainShaderMethod); - if (geometryShaderMethod != null) - renameFreeMethods.Add(geometryShaderMethod); - if (pixelShaderMethod != null) - renameFreeMethods.Add(pixelShaderMethod); - if (computeShaderMethod != null) - renameFreeMethods.Add(computeShaderMethod); - - int id = 0; - - RenameAllMethods(mainModuleMixin.ClassReferences, renameFreeMethods, ref id); - } - - /// - /// Finds all the function with the name - /// - /// the name of the function - /// a collection of all the functions with that name, correctly ordered - private MethodDefinition FindEntryPoint(string name) - { - for (int i = MixinInheritance.Count - 1; i >= 0; --i) - { - var mixin = MixinInheritance[i]; - var count = 0; - for (int j = 0; j < i; ++j) - { - count += mixin.MixinName == MixinInheritance[j].MixinName ? 1 : 0; - } - - var method = mixin.LocalVirtualTable.Methods.FirstOrDefault(x => x.Method.Name.Text == name && x.Method is MethodDefinition); - if (method != null && (count == 0 || method.Method.Qualifiers.Contains(StrideStorageQualifier.Clone))) - return method.Method as MethodDefinition; - } - return null; - } - - /// - /// Creates a new AST with all the definitions - /// - private void GenerateShader() - { - MixedShader = new ShaderClassType(mainModuleMixin.MixinName); - - // add constants - var constants = mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).Where(x => x.Qualifiers.Contains(StorageQualifier.Const)).ToList(); - MixedShader.Members.AddRange(constants); - - // Add structures, typedefs - foreach (var mixin in MixinInheritance.Where(x => x.OccurrenceId == 1)) - MixedShader.Members.AddRange(mixin.ParsingInfo.Typedefs); - foreach (var mixin in MixinInheritance.Where(x => x.OccurrenceId == 1)) - MixedShader.Members.AddRange(mixin.ParsingInfo.StructureDefinitions); - - var sortedNodes = SortNodes(MixedShader.Members); - MixedShader.Members.Clear(); - MixedShader.Members.AddRange(sortedNodes); - - // Create constant buffer - GroupByConstantBuffer(); - - // add the methods - MixedShader.Members.AddRange(mainModuleMixin.ClassReferences.MethodsReferences.Select(x => x.Key).Where(x => x is MethodDefinition)); - - // remove duplicates - MixedShader.Members = MixedShader.Members.Distinct().ToList(); - - // Create streams - StrideStreamCreator.Run(MixedShader, mainModuleMixin, MixinInheritance, log); - - if (log.HasErrors) - return; - - // deal with foreach statements - ExpandForEachStatements(mainModuleMixin); - foreach (var externMixList in CompositionsPerVariable.Values) - { - foreach (var externMix in externMixList) - ExpandForEachStatements(externMix); - } - - // remove useless variables - RemoveUselessVariables(); - - // Add padding to constant buffers to align logical groups - AlignLogicalGroups(); - } - - private List SortNodes(List nodes) - { - var weights = new Dictionary(); - foreach (var node in nodes) - { - var weight = -1; - var classSource = node.GetTag(StrideTags.ShaderScope) as ModuleMixin; - if (classSource == null) - throw new Exception("Node has no class source"); - - for (var i = 0; i < MixinInheritance.Count; ++i) - { - if (MixinInheritance[i] == classSource) - { - weight = i; - break; - } - } - - if (weight == -1) - throw new Exception("constant mixin not found"); - - weights.Add(node, weight); - } - - return nodes.OrderBy(x => weights[x]).ToList(); - } - - /// - /// Remove useless variables - /// - private void RemoveUselessVariables() - { - var variablesUsages = MixedShader.Members.OfType().ToDictionary(variable => variable, variable => false); - - // Scan cbuffer - foreach (var constantBuffer in MixedShader.Members.OfType()) - { - foreach (var variable in constantBuffer.Members.OfType().ToList()) - variablesUsages.Add(variable, false); - } - - // Remove "extern" variables - MixedShader.Members.RemoveAll(x => x is Variable && (x as Variable).Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern)); - - var variableUsageVisitor = new StrideVariableUsageVisitor(variablesUsages); - variableUsageVisitor.Run(MixedShader); - - foreach (var variable in MixedShader.Members.OfType().ToList()) - { - // Ignore variable with logical groups - if (variable.GetTag(StrideTags.LogicalGroup) != null) - continue; - - // Don't remove resources since they need to consistent between resource group layouts. The EffectCompiler will clean up reflection if possible - if (variable.Type.IsSamplerType() || variable.Type is TextureType || variable.Type.ResolveType() is ObjectType) - continue; - - bool used; - if (variablesUsages.TryGetValue(variable, out used)) - { - if (!used) - MixedShader.Members.Remove(variable); - } - } - } - - /// - /// Test if the variable should be in a constant buffer - /// - /// the variable - /// true/false - private bool IsOutOfCBufferVariable(Variable variable) - { - return variable.Type.IsSamplerType() - || variable.Type is TextureType - || variable.Type.IsStateType() - || variable.Type.ResolveType() is ObjectType - || variable.Qualifiers.Contains(StorageQualifier.Shared) - || variable.Qualifiers.Contains(StorageQualifier.GroupShared); - } - - /// - /// Test if the variable should be in a constant buffer - /// - /// the variable - /// true/false - private bool KeepVariableInCBuffer(Variable variable) - { - return !(variable.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern) - || variable.Qualifiers.Contains(StrideStorageQualifier.Stream) - || variable.Qualifiers.Contains(StrideStorageQualifier.PatchStream) - || IsOutOfCBufferVariable(variable) - || variable.Qualifiers.Contains(StorageQualifier.Const) - || variable.Qualifiers.Contains(StorageQualifier.Shared) - || variable.Qualifiers.Contains(StorageQualifier.GroupShared)); - } - - // Group everything by constant buffers - private void GroupByConstantBuffer() - { - MergeSameSemanticVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); - MergeReferenceVariables(mainModuleMixin.ClassReferences.VariablesReferences.Select(x => x.Key).ToList()); - - // Order variables by cbuffer/rgroup (which still include logical group) - var variables = mainModuleMixin.ClassReferences.VariablesReferences.OrderBy(x => ((ConstantBuffer)x.Key.GetTag(StrideTags.ConstantBuffer))?.Name.Text).ToList(); - - // Recreate cbuffer with proper logical groups - var constantBuffers = new Dictionary(); - foreach (var variable in variables) - { - var cbuffer = (ConstantBuffer)variable.Key.GetTag(StrideTags.ConstantBuffer); - if (cbuffer == null) - continue; - - // Find logical group - var cbufferNameSplit = cbuffer.Name.Text.IndexOf('.'); - if (cbufferNameSplit == -1) - continue; - - var cbufferName = cbuffer.Name.Text.Substring(0, cbufferNameSplit); - var cbufferLogicalGroupName = cbufferNameSplit != -1 ? cbuffer.Name.Text.Substring(cbufferNameSplit + 1) : null; - - // Find or create a matching cbuffer - ConstantBuffer realCBuffer; - constantBuffers.TryGetValue(cbuffer, out realCBuffer); - if (realCBuffer == null) - { - // First time, let's create it - realCBuffer = new ConstantBuffer { Name = cbufferName, Type = cbuffer.Type }; - constantBuffers.Add(cbuffer, realCBuffer); - } - - realCBuffer.Members.Add(variable.Key); - - // Set cbuffer and logical groups - variable.Key.SetTag(StrideTags.ConstantBuffer, realCBuffer); - variable.Key.SetTag(StrideTags.ConstantBufferIndex, realCBuffer.Members.Count - 1); - variable.Key.SetTag(StrideTags.LogicalGroup, cbufferLogicalGroupName); - } - - var usefulVars = variables.Select(x => x.Key).Where(KeepVariableInCBuffer).ToList(); - var varList = usefulVars.Where(x => x.ContainsTag(StrideTags.ConstantBuffer)).ToList(); - var groupedVarList = varList.GroupBy(x => (ConstantBuffer)x.GetTag(StrideTags.ConstantBuffer)).Select(cbuffer => new - { - Buffer = cbuffer.Key, - Members = cbuffer.OrderBy(x => (int)x.GetTag(StrideTags.ConstantBufferIndex)).ToList(), - } - ).GroupBy(cbuffer => cbuffer.Buffer.Name.Text); - - // For each cbuffer name - foreach (var group in groupedVarList) - { - var originalCbuffer = group.First().Buffer; - var cbuffer = new ConstantBuffer { Type = originalCbuffer.Type, Name = group.Key }; - - // For each cbuffer group that will be merged - foreach (var groupVariables in group) - { - cbuffer.Members.AddRange(groupVariables.Members); - } - - MixedShader.Members.Add(cbuffer); - } - - var remainingVars = usefulVars.Where(x => !x.ContainsTag(StrideTags.ConstantBuffer)).ToList(); - var globalBuffer = new ConstantBuffer { Type = Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType.Constant, Name = "Globals" }; - if (remainingVars.Count > 0) - { - globalBuffer.Members.AddRange(remainingVars); - MixedShader.Members.Add(globalBuffer); - } - - // add textures, samplers etc. - MixedShader.Members.AddRange(variables.Select(x => x.Key).Where(IsOutOfCBufferVariable)); - } - - private void AlignLogicalGroups() - { - foreach (var constantBuffer in MixedShader.Members.OfType()) - { - string currentLogicalGroupName = null; - - var members = constantBuffer.Members; - constantBuffer.Members = new List(); - - foreach (var member in members.OfType()) - { - // Add padding if the logical group changes - var logicalGroupName = (string)member.GetTag(StrideTags.LogicalGroup); - if (logicalGroupName != currentLogicalGroupName) - { - AddLogicalGroupPadding(constantBuffer, currentLogicalGroupName); - currentLogicalGroupName = logicalGroupName; - } - - // Add the original member - constantBuffer.Members.Add(member); - } - - // Pad the last logical group, so it always has the same size - if (currentLogicalGroupName != null) - { - AddLogicalGroupPadding(constantBuffer, currentLogicalGroupName); - } - } - } - - private static void AddLogicalGroupPadding(ConstantBuffer constantBuffer, string logicaGroupName) - { - if (logicaGroupName == null) - logicaGroupName = "Default"; - - // Pad with float4, so we align to 16 bytes, independent of the packing rules of the shader compiler - // This is not optimal. Ideally we would define all layouts manually. - var paddingVariable = new Variable(VectorType.Float4.ToNonGenericType(), $"_padding_{constantBuffer.Name}_{logicaGroupName}"); - - paddingVariable.SetTag(StrideTags.ConstantBuffer, constantBuffer); - paddingVariable.SetTag(StrideTags.LogicalGroup, logicaGroupName); - - // Satisfy the ShaderLinker. The link name needs to be well defined as it is used for hashing - paddingVariable.Attributes.Add(new AttributeDeclaration { Name = new Identifier("Link"), Parameters = new List { new Literal(paddingVariable.Name.Text) } }); - - constantBuffer.Members.Add(paddingVariable); - } - - /// - /// Merge all the variables with the same semantic and rename them (but typeinference is not correct) - /// - private void MergeSameSemanticVariables(List variables) - { - var duplicateVariables = new List(); // list of variables that will be removed - var allVariablesWithSemantic = variables.Where(x => x.Qualifiers.Values.Any(y => y is Semantic)).ToList(); - foreach (var variable in allVariablesWithSemantic) - { - if (!duplicateVariables.Contains(variable)) - { - var sourceMixinName = (variable.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName; - - var semantic = variable.Qualifiers.OfType().First(); - - var sameSemanticVariables = allVariablesWithSemantic.Where(x => x != variable && x.Qualifiers.Values.OfType().Any(y => AreSameSemantics(y.Name.Text, semantic.Name.Text))).ToList(); - - foreach (var sameSemVar in sameSemanticVariables) - { - var newMixinName = (sameSemVar.GetTag(StrideTags.ShaderScope) as ModuleMixin).MixinName; - - // Check if declared in the same constant buffer - var cbuffer = variable.ContainsTag(StrideTags.ConstantBuffer) ? variable.GetTag(StrideTags.ConstantBuffer) as ConstantBuffer : null; - var newcbuffer = sameSemVar.ContainsTag(StrideTags.ConstantBuffer) ? sameSemVar.GetTag(StrideTags.ConstantBuffer) as ConstantBuffer : null; - if (cbuffer != null ^ newcbuffer != null) - { - variable.SetTag(StrideTags.ConstantBuffer, cbuffer ?? newcbuffer); - variable.SetTag(StrideTags.ConstantBufferIndex, (cbuffer != null ? variable : sameSemVar).GetTag(StrideTags.ConstantBufferIndex)); - } - else if (cbuffer != null && cbuffer != newcbuffer) - { - log.Error(StrideMessageCode.ErrorSemanticCbufferConflict, variable.Span, variable, sourceMixinName, sameSemVar, newMixinName, semantic, cbuffer, newcbuffer); - } - - // Check if declared as the same type - if (variable.Type != sameSemVar.Type) - { - log.Error(StrideMessageCode.ErrorSemanticTypeConflict, variable.Span, variable, sourceMixinName, sameSemVar, newMixinName, semantic, variable.Type, sameSemVar.Type); - } - - // Rewrite references - foreach (var exp in mainModuleMixin.ClassReferences.VariablesReferences[sameSemVar]) - { - if (exp.Expression is VariableReferenceExpression) - (exp.Expression as VariableReferenceExpression).Name = variable.Name; - else if (exp.Expression is MemberReferenceExpression) - (exp.Expression as MemberReferenceExpression).Member = variable.Name; - - exp.Expression.TypeInference.Declaration = variable; - } - mainModuleMixin.ClassReferences.VariablesReferences[variable].UnionWith(mainModuleMixin.ClassReferences.VariablesReferences[sameSemVar]); - sameSemVar.Name = variable.Name; - } - - duplicateVariables.AddRange(sameSemanticVariables); - } - } - - mainModuleMixin.ClassReferences.RegenKeys(); - duplicateVariables.ForEach(variable => mainModuleMixin.ClassReferences.VariablesReferences.Remove(variable)); - } - - /// - /// Merge variables that are references of another one - /// - /// - private void MergeReferenceVariables(List variables) - { - var duplicateVariables = new List(); - foreach (var variable in variables.Where(x => x.InitialValue is MemberReferenceExpression || x.InitialValue is VariableReferenceExpression)) - { - //find reference - var target = variable.InitialValue.TypeInference.Declaration as Variable; - if (target != null) - { - foreach (var exp in mainModuleMixin.ClassReferences.VariablesReferences[variable]) - { - if (exp.Expression is VariableReferenceExpression) - (exp.Expression as VariableReferenceExpression).Name = target.Name; - else if (exp.Expression is MemberReferenceExpression) - (exp.Expression as MemberReferenceExpression).Member = target.Name; - - exp.Expression.TypeInference.Declaration = target; - } - mainModuleMixin.ClassReferences.VariablesReferences[target].UnionWith(mainModuleMixin.ClassReferences.VariablesReferences[variable]); - variable.Name = target.Name; - duplicateVariables.Add(variable); - } - } - - mainModuleMixin.ClassReferences.RegenKeys(); - duplicateVariables.ForEach(variable => mainModuleMixin.ClassReferences.VariablesReferences.Remove(variable)); - } - - #endregion - - #region Static helpers - - /// - /// Replaces the ForEachStatements in the mixin by ForStatements - /// - /// the mixin - private static void ExpandForEachStatements(ModuleMixin mixin) - { - foreach (var statementNodeCouple in mixin.ParsingInfo.ForEachStatements.Where(x => !(x.Statement as ForEachStatement).Variable.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Extern))) - { - var newStatement = ExpandForEachStatement(statementNodeCouple.Statement as ForEachStatement); - if (newStatement != null) - { - var replace = new StrideReplaceVisitor(statementNodeCouple.Statement, newStatement); - replace.Run(statementNodeCouple.Node); - } - } - - mixin.InheritanceList.ForEach(ExpandForEachStatements); - } - - /// - /// Creates a ForStatement with the same behavior - /// - /// the ForEachStatement - /// the ForStatement - private static ForStatement ExpandForEachStatement(ForEachStatement forEachStatement) - { - if (forEachStatement != null) - { - var collec = forEachStatement.Collection.TypeInference.Declaration as Variable; - LiteralExpression dimLit = null; - if (collec.Type is ArrayType) - { - if ((collec.Type as ArrayType).Dimensions.Count == 1) - { - dimLit = (collec.Type as ArrayType).Dimensions[0] as LiteralExpression; - } - } - - if (dimLit != null) - { - var initializer = new Variable(ScalarType.Int, forEachStatement.Variable.Name.Text + "Iter", new LiteralExpression(0)); - var vre = new VariableReferenceExpression(initializer.Name); - var condition = new BinaryExpression(BinaryOperator.Less, vre, dimLit); - var next = new UnaryExpression(UnaryOperator.PreIncrement, vre); - ForStatement forStatement = new ForStatement(new DeclarationStatement(initializer), condition, next); - var body = new BlockStatement(); - - var variable = forEachStatement.Variable; - variable.InitialValue = new IndexerExpression(forEachStatement.Collection, new VariableReferenceExpression(initializer)); - body.Statements.Add(new DeclarationStatement(variable)); - - if (forEachStatement.Body is BlockStatement) - body.Statements.AddRange((forEachStatement.Body as BlockStatement).Statements); - else - body.Statements.Add(forEachStatement.Body); - - forStatement.Body = body; - - return forStatement; - } - - // TODO: multidimension-array? - // TODO: unroll? - // TODO: multiple foreach? - } - return null; - } - - /// - /// Replace a MemberReferenceExpression by a VariableReferenceExpression in the AST - /// - /// the member reference expression. - /// the variable reference expression. - /// the parent node. - private static void ReplaceMemberReferenceExpressionByVariableReferenceExpression(MemberReferenceExpression memberReferenceExpression, VariableReferenceExpression variableReferenceExpression, Node parentNode) - { - var replacor = new StrideReplaceVisitor(memberReferenceExpression, variableReferenceExpression); - replacor.Run(parentNode); - } - - /// - /// Compare the semantics - /// - /// - /// - /// - private static bool AreSameSemantics(string sem0, string sem1) - { - var upperSem0 = sem0.ToUpperInvariant(); - var upperSem1 = sem1.ToUpperInvariant(); - - if (upperSem0 == upperSem1) - return true; - - var i = upperSem0.Length - 1; - while (i > 0 && char.IsDigit(upperSem0[i])) - --i; - string trimSem0 = upperSem0.Substring(0, i + 1); - int sem0Index = i == upperSem0.Length - 1 ? 0 : Int32.Parse(upperSem0.Substring(i + 1, upperSem0.Length - i - 1)); - - i = upperSem1.Length - 1; - while (i > 0 && char.IsDigit(upperSem1[i])) - --i; - string trimSem1 = upperSem1.Substring(0, i + 1); - int sem1Index = i == upperSem1.Length - 1 ? 0 : Int32.Parse(upperSem1.Substring(i + 1, upperSem1.Length - i - 1)); - - return trimSem0 == trimSem1 && sem0Index == sem1Index; - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamAnalyzer.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamAnalyzer.cs deleted file mode 100644 index 14583115c0..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamAnalyzer.cs +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; - -using Stride.Shaders.Parser.Analysis; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideStreamAnalyzer : ShaderWalker - { - #region Private members - - /// - /// Current stream usage - /// - private StreamUsage currentStreamUsage = StreamUsage.Read; - - /// - /// List of stream usage - /// - private List currentStreamUsageList = null; - - /// - /// List of already added methods. - /// - private List alreadyAddedMethodsList = null; - - /// - /// Status of the assignment - /// - private AssignmentOperatorStatus currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read; - - /// - /// Log of all the warnings and errors - /// - private LoggerResult errorWarningLog; - - /// - /// Name of the shader - /// - private string shaderName = "Mix"; - - #endregion - - #region Public members - - /// - /// List of assignations in the form of "streams = ...;" - /// - public Dictionary StreamAssignations = new Dictionary(); - - /// - /// List of assignations in the form of "... = streams;" - /// - public Dictionary AssignationsToStream = new Dictionary(); - - /// - /// List of assignations in the form of "StreamType backup = streams;" - /// - public Dictionary VariableStreamsAssignment = new Dictionary(); - - /// - /// streams usage by method - /// - public Dictionary> StreamsUsageByMethodDefinition = new Dictionary>(); - - /// - /// A list containing all the "streams" Variable references - /// - public HashSet AppendMethodCalls = new HashSet(); - - #endregion - - #region Constructor - - public StrideStreamAnalyzer(LoggerResult errorLog) - : base(false, true) - { - errorWarningLog = errorLog ?? new LoggerResult(); - } - - #endregion - - public void Run(ShaderClassType shaderClassType) - { - shaderName = shaderClassType.Name.Text; - Visit(shaderClassType); - } - - #region Private methods - - /// - /// Analyse the method definition and store it in the correct lists (based on storage and stream usage) - /// - /// the MethodDefinition - public override void Visit(MethodDefinition methodDefinition) - { - currentStreamUsageList = new List(); - alreadyAddedMethodsList = new List(); - - base.Visit(methodDefinition); - - if (currentStreamUsageList.Count > 0) - StreamsUsageByMethodDefinition.Add(methodDefinition, currentStreamUsageList); - } - - /// - /// Calls the base method but modify the stream usage beforehand - /// - /// the method expression - public override void Visit(MethodInvocationExpression expression) - { - base.Visit(expression); - - var methodDecl = expression.Target.TypeInference.Declaration as MethodDeclaration; - - if (methodDecl != null) - { - // Stream analysis - if (methodDecl.ContainsTag(StrideTags.ShaderScope)) // this will prevent built-in function to appear in the list - { - // test if the method was previously added - if (!alreadyAddedMethodsList.Contains(methodDecl)) - { - currentStreamUsageList.Add(new StreamUsageInfo { CallType = StreamCallType.Method, MethodDeclaration = methodDecl, Expression = expression }); - alreadyAddedMethodsList.Add(methodDecl); - } - } - for (int i = 0; i < expression.Arguments.Count; ++i) - { - var arg = expression.Arguments[i] as MemberReferenceExpression; // TODO: - - if (arg != null && IsStreamMember(arg)) - { - var isOut = methodDecl.Parameters[i].Qualifiers.Contains(Stride.Core.Shaders.Ast.ParameterQualifier.Out); - - //if (methodDecl.Parameters[i].Qualifiers.Contains(Ast.ParameterQualifier.InOut)) - // Error(MessageCode.ErrorInOutStream, expression.Span, arg, methodDecl, contextModuleMixin.MixinName); - - var usage = methodDecl.Parameters[i].Qualifiers.Contains(Stride.Core.Shaders.Ast.ParameterQualifier.Out) ? StreamUsage.Write : StreamUsage.Read; - AddStreamUsage(arg.TypeInference.Declaration as Variable, arg, usage); - } - } - } - - // TODO: .Append should be avoided - if (expression.Target is MemberReferenceExpression && (expression.Target as MemberReferenceExpression).Target.TypeInference.TargetType is ClassType && (expression.Target as MemberReferenceExpression).Member.Text == "Append") - AppendMethodCalls.Add(expression); - } - - private static bool IsStreamMember(MemberReferenceExpression expression) - { - if (expression.TypeInference.Declaration is Variable) - { - return (expression.TypeInference.Declaration as Variable).Qualifiers.Contains(StrideStorageQualifier.Stream); - } - return false; - } - - /// - /// Analyse the VariableReferenceExpression, detects streams, propagate type inference, get stored in the correct list for later analysis - /// - /// the VariableReferenceExpression - public override void Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - // HACK: force types on base, this and stream keyword to eliminate errors in the log an use the standard type inference - if (variableReferenceExpression.Name == StreamsType.ThisStreams.Name) - { - if (!(ParentNode is MemberReferenceExpression)) // streams is alone - currentStreamUsageList.Add(new StreamUsageInfo { CallType = StreamCallType.Direct, Variable = StreamsType.ThisStreams, Expression = variableReferenceExpression, Usage = currentStreamUsage }); - } - } - - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - var usageCopy = currentStreamUsage; - currentStreamUsage |= StreamUsage.Partial; - base.Visit(memberReferenceExpression); - currentStreamUsage = usageCopy; - - // check if it is a stream - if (IsStreamMember(memberReferenceExpression)) - AddStreamUsage(memberReferenceExpression.TypeInference.Declaration as Variable, memberReferenceExpression, currentStreamUsage); - } - - public override void Visit(BinaryExpression expression) - { - var prevStreamUsage = currentStreamUsage; - currentStreamUsage = StreamUsage.Read; - base.Visit(expression); - currentStreamUsage = prevStreamUsage; - } - - public override void Visit(UnaryExpression expression) - { - var prevStreamUsage = currentStreamUsage; - currentStreamUsage = StreamUsage.Read; - base.Visit(expression); - currentStreamUsage = prevStreamUsage; - } - - /// - /// Analyse the AssignmentExpression to correctly infer the potential stream usage - /// - /// the AssignmentExpression - public override void Visit(AssignmentExpression assignmentExpression) - { - if (currentAssignmentOperatorStatus != AssignmentOperatorStatus.Read) - errorWarningLog.Error(StrideMessageCode.ErrorNestedAssignment, assignmentExpression.Span, assignmentExpression, shaderName); - - var prevStreamUsage = currentStreamUsage; - currentStreamUsage = StreamUsage.Read; - assignmentExpression.Value = (Expression)VisitDynamic(assignmentExpression.Value); - currentAssignmentOperatorStatus = (assignmentExpression.Operator != AssignmentOperator.Default) ? AssignmentOperatorStatus.ReadWrite : AssignmentOperatorStatus.Write; - - currentStreamUsage = StreamUsage.Write; - assignmentExpression.Target = (Expression)VisitDynamic(assignmentExpression.Target); - - currentAssignmentOperatorStatus = AssignmentOperatorStatus.Read; - currentStreamUsage = prevStreamUsage; - - var parentBlock = this.NodeStack.OfType().LastOrDefault(); - - if (assignmentExpression.Operator == AssignmentOperator.Default && parentBlock != null) - { - if (assignmentExpression.Target is VariableReferenceExpression && (assignmentExpression.Target as VariableReferenceExpression).Name == StreamsType.ThisStreams.Name) // "streams = ...;" - StreamAssignations.Add(assignmentExpression, parentBlock); - else if (assignmentExpression.Value is VariableReferenceExpression && (assignmentExpression.Value as VariableReferenceExpression).Name == StreamsType.ThisStreams.Name) // "... = streams;" - AssignationsToStream.Add(assignmentExpression, parentBlock); - } - } - - public override void Visit(Variable variableStatement) - { - base.Visit(variableStatement); - - var parentBlock = this.NodeStack.OfType().LastOrDefault(); - if (parentBlock != null && variableStatement.Type == StreamsType.Streams && variableStatement.InitialValue is VariableReferenceExpression && ((VariableReferenceExpression)(variableStatement.InitialValue)).TypeInference.TargetType.IsStreamsType()) - { - VariableStreamsAssignment.Add(variableStatement, parentBlock); - } - } - - /// - /// Adds a stream usage to the current method - /// - /// the stream Variable - /// the calling expression - /// the encountered usage - private void AddStreamUsage(Variable variable, Stride.Core.Shaders.Ast.Expression expression, StreamUsage usage) - { - currentStreamUsageList.Add(new StreamUsageInfo { CallType = StreamCallType.Member, Variable = variable, Expression = expression, Usage = usage }); - } - - #endregion - } - - [Flags] - internal enum StreamUsage - { - Unknown = 0, - Read = 1, - Write = 2, - - /// - /// Not all the components of the variable have been read/written - /// - Partial = 4, - } - - internal static class StreamUsageExtensions - { - public static bool IsRead(this StreamUsage usage) { return (usage & StreamUsage.Read) != 0; } - public static bool IsWrite(this StreamUsage usage) { return (usage & StreamUsage.Write) != 0; } - public static bool IsPartial(this StreamUsage usage) { return (usage & StreamUsage.Partial) != 0; } - } - - internal enum StreamCallType - { - Unknown = 0, - Member = 1, - Method = 2, - Direct = 3 - } - - internal class StreamUsageInfo - { - public StreamUsage Usage = StreamUsage.Unknown; - public StreamCallType CallType = StreamCallType.Unknown; - public Variable Variable = null; - public MethodDeclaration MethodDeclaration = null; - public Expression Expression; - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamCreator.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamCreator.cs deleted file mode 100644 index f5820fd38f..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideStreamCreator.cs +++ /dev/null @@ -1,1263 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Extensions; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Visitor; -using Stride.Shaders.Parser.Utility; - -using ParameterQualifier = Stride.Core.Shaders.Ast.ParameterQualifier; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideStreamCreator - { - #region private static members - - private static readonly string[] GeometryShaderUnOptimizedSemantics = { "SV_RenderTargetArrayIndex" }; - - #endregion - - #region Private members - - /// - /// The shader - /// - private ShaderClassType shader; - - /// - /// the main ModuleMixin corresonding to the shader - /// - private ModuleMixin mainModuleMixin; - - /// - /// Ordered list of all the mixin in their appearance order - /// - private List mixinInheritance = new List(); - - /// - /// the entry points of the shader - /// - private HashSet entryPointMethods = new HashSet(); - - /// - /// All the streams usages - /// - private Dictionary> streamsUsages = new Dictionary>(); - - /// - /// List of methods that need streams structure. - /// - private Dictionary> methodsPerShaderStage = new Dictionary>(); - - /// - /// Stream analyzer - /// - private StrideStreamAnalyzer streamAnalyzer; - - /// - /// the error logger - /// - private ShaderMixinParsingResult parsingResult; - - #endregion - - #region Constructor - - private StrideStreamCreator(ShaderClassType shaderClassType, ModuleMixin mixin, List mixins, ShaderMixinParsingResult result) - { - shader = shaderClassType; - mainModuleMixin = mixin; - mixinInheritance = mixins; - parsingResult = result ?? new ShaderMixinParsingResult(); - } - - public static void Run(ShaderClassType shaderClassType, ModuleMixin mixin, List mixins, ShaderMixinParsingResult result) - { - var streamCreator = new StrideStreamCreator(shaderClassType, mixin, mixins, result); - streamCreator.Run(); - } - - #endregion - - #region Public method - - public void Run() - { - streamAnalyzer = new StrideStreamAnalyzer(this.parsingResult); - streamAnalyzer.Run(shader); - - if (this.parsingResult.HasErrors) - return; - - streamsUsages = streamAnalyzer.StreamsUsageByMethodDefinition; - - // Find entry points - var vertexShaderMethod = FindEntryPoint("VSMain"); - var hullShaderMethod = FindEntryPoint("HSMain"); - var hullConstantShaderMethod = FindEntryPoint("HSConstantMain"); - var domainShaderMethod = FindEntryPoint("DSMain"); - var geometryShaderMethod = FindEntryPoint("GSMain"); - var pixelShaderMethod = FindEntryPoint("PSMain"); - var computeShaderMethod = FindEntryPoint("CSMain"); - - if (vertexShaderMethod != null) - vertexShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Vertex") } }); - if (pixelShaderMethod != null) - pixelShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Pixel") } }); - if (geometryShaderMethod != null) - geometryShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Geometry") } }); - if (hullShaderMethod != null) - hullShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Hull") } }); - if (domainShaderMethod != null) - domainShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Domain") } }); - if (computeShaderMethod != null) - computeShaderMethod.Attributes.Add(new AttributeDeclaration { Name = new Identifier("EntryPoint"), Parameters = new List { new Literal("Compute") } }); - - if (!(hullShaderMethod == null && hullConstantShaderMethod == null && domainShaderMethod == null) && (hullShaderMethod == null || hullConstantShaderMethod == null || domainShaderMethod == null)) - { - this.parsingResult.Error(StrideMessageCode.ErrorIncompleteTesselationShader, new SourceSpan()); - return; - } - - StreamStageUsage streamStageUsageVS = vertexShaderMethod == null ? null : StreamAnalysisPerShader(vertexShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, vertexShaderMethod, XkShaderStage.Vertex); - StreamStageUsage streamStageUsageHS = hullShaderMethod == null ? null : StreamAnalysisPerShader(hullShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, hullShaderMethod, XkShaderStage.Hull); - StreamStageUsage streamStageUsageHSCS = hullConstantShaderMethod == null ? null : StreamAnalysisPerShader(hullConstantShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, hullConstantShaderMethod, XkShaderStage.Constant); - StreamStageUsage streamStageUsageDS = domainShaderMethod == null ? null : StreamAnalysisPerShader(domainShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, domainShaderMethod, XkShaderStage.Domain); - StreamStageUsage streamStageUsageGS = geometryShaderMethod == null ? null : StreamAnalysisPerShader(geometryShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, geometryShaderMethod, XkShaderStage.Geometry); - StreamStageUsage streamStageUsagePS = pixelShaderMethod == null ? null : StreamAnalysisPerShader(pixelShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, pixelShaderMethod, XkShaderStage.Pixel); - StreamStageUsage streamStageUsageCS = computeShaderMethod == null ? null : StreamAnalysisPerShader(computeShaderMethod.GetTag(StrideTags.ShaderScope) as ModuleMixin, computeShaderMethod, XkShaderStage.Compute); - - // pathc some usage so that variables are correctly passed even if they are not explicitely used. - if (streamStageUsageGS != null && streamStageUsageVS != null) - { - var needToAdd = true; - foreach (var variable in streamStageUsageGS.OutStreamList.OfType()) - { - var sem = variable.Qualifiers.OfType().FirstOrDefault(); - if (sem != null && sem.Name.Text == "SV_Position") - { - needToAdd = false; - break; - } - } - - if (needToAdd) - { - // get the ShadingPosition variable - foreach (var variable in streamStageUsageVS.OutStreamList.OfType()) - { - var sem = variable.Qualifiers.OfType().FirstOrDefault(); - if (sem != null && sem.Name.Text == "SV_Position") - { - streamStageUsageGS.OutStreamList.Add(variable); - break; - } - - } - } - // TODO: it may have more variables like this one. - } - - var shaderStreamsUsage = new List(); - - // store these methods to prevent their renaming - if (vertexShaderMethod != null) - { - entryPointMethods.Add(vertexShaderMethod); - shaderStreamsUsage.Add(streamStageUsageVS); - } - if (hullShaderMethod != null) - { - entryPointMethods.Add(hullShaderMethod); - shaderStreamsUsage.Add(streamStageUsageHS); - } - if (hullConstantShaderMethod != null) - { - entryPointMethods.Add(hullConstantShaderMethod); - shaderStreamsUsage.Add(streamStageUsageHSCS); - } - if (domainShaderMethod != null) - { - entryPointMethods.Add(domainShaderMethod); - shaderStreamsUsage.Add(streamStageUsageDS); - } - if (geometryShaderMethod != null) - { - entryPointMethods.Add(geometryShaderMethod); - shaderStreamsUsage.Add(streamStageUsageGS); - } - if (pixelShaderMethod != null) - { - entryPointMethods.Add(pixelShaderMethod); - shaderStreamsUsage.Add(streamStageUsagePS); - } - if (computeShaderMethod != null) - { - entryPointMethods.Add(computeShaderMethod); - } - - BubbleUpStreamUsages(shaderStreamsUsage); - - if (computeShaderMethod != null) - ComputeShaderStreamAnalysis(streamStageUsageCS); - - StructType outputStructure = null; - - // remove the now useless tags and typeinferences to accelerate cloning - var tagCleaner = new StrideTagCleaner(); - tagCleaner.Run(shader); - - outputStructure = GenerateStreams(vertexShaderMethod, streamStageUsageVS, "VS", outputStructure); - outputStructure = GenerateStreamsForHullShader(hullShaderMethod, hullConstantShaderMethod, streamStageUsageHS, "HS", outputStructure); - outputStructure = GenerateStreamsForDomainShader(domainShaderMethod, streamStageUsageDS, "DS", outputStructure); - outputStructure = GenerateStreamsWithSpecialDataInput(geometryShaderMethod, streamStageUsageGS, "GS", outputStructure); - outputStructure = GenerateStreams(pixelShaderMethod, streamStageUsagePS, "PS", outputStructure, false); - - outputStructure = GenerateStreams(computeShaderMethod, streamStageUsageCS, "CS", null); - - // reflect the input layout - // FirstOrDefault : because the first stage that exists is the entry point in the pipeline for the streams. - var semanticList = shaderStreamsUsage.FirstOrDefault()?.InStreamList?.OfType().Select(v => v.Qualifiers.Values.OfType())?.SelectMany(x => x); - if (semanticList != null) - { - foreach (var semantic in semanticList) - { - var parsed = Semantic.Parse(semantic.Name); - parsingResult.Reflection.InputAttributes.Add( - new ShaderInputAttributeDescription - { - SemanticName = parsed.Key, - SemanticIndex = parsed.Value - }); - } - } - - RemoveUselessAndSortMethods(); - } - - private static int ParseSemanticIndex(string semantic) - { - if (string.IsNullOrEmpty(semantic)) - return 0; - // semantics are simple digits, let's analyze the last character: - char last = semantic.Last(); - return char.IsNumber(last) ? last - '0' : 0; - } - - private static string StripStringOfSemanticIndex(string semantic) - { - if (string.IsNullOrEmpty(semantic)) - return semantic; - return char.IsNumber(semantic.Last()) ? semantic.Substring(0, semantic.Length - 1): semantic; - } - - #endregion - - #region Private methods - - /// - /// Sort the methods based on their calls - /// - private void RemoveUselessAndSortMethods() - { - var methods = shader.Members.OfType().ToList(); - shader.Members.RemoveAll(methods.Contains); - - var zeroCalledMethods = new HashSet(); - var methodReferenceCounter = methods.ToDictionary(x => x, x => 0); - - foreach (var reference in streamsUsages) - { - foreach (var usage in reference.Value.Where(x => x.CallType == StreamCallType.Method)) - { - int value; - if (methodReferenceCounter.TryGetValue(usage.MethodDeclaration, out value)) - methodReferenceCounter[usage.MethodDeclaration] = value + 1; - else if (!entryPointMethods.Contains(usage.MethodDeclaration)) - zeroCalledMethods.Add(usage.MethodDeclaration); - } - } - - - zeroCalledMethods.UnionWith(methodReferenceCounter.Where(x => x.Value == 0 && !entryPointMethods.Contains(x.Key)).Select(x => x.Key)); - BuildOrderedMethodUsageList(zeroCalledMethods, methodReferenceCounter); - - var finalMethodsList = BuildOrderedMethodUsageList(new HashSet(entryPointMethods), methodReferenceCounter); - finalMethodsList.Reverse(); - shader.Members.AddRange(finalMethodsList); - } - - /// - /// Recursively create a list of all the methods that are exclusively used from the start ones - /// - /// the list of starting methods - /// all the methods - /// - private List BuildOrderedMethodUsageList(HashSet startList, Dictionary methodReferenceCounter) - { - var finalMethodsList = new List(); - while (startList.Count > 0) - { - var newZeroCalledMethods = new List(); - - foreach (var method in startList) - { - finalMethodsList.Add(method); - - List reference; - if (streamsUsages.TryGetValue(method, out reference)) - { - foreach (var usage in reference.Where(x => x.CallType == StreamCallType.Method)) - { - int value; - if (methodReferenceCounter.TryGetValue(usage.MethodDeclaration, out value)) - { - methodReferenceCounter[usage.MethodDeclaration] = value - 1; - if (value == 1) - newZeroCalledMethods.Add(usage.MethodDeclaration); - } - } - } - } - - startList.Clear(); - startList.UnionWith(newZeroCalledMethods); - } - - return finalMethodsList; - } - - /// - /// Finds all the function with the name - /// - /// the name of the function - /// a collection of all the functions with that name, correctly ordered - private MethodDefinition FindEntryPoint(string name) - { - for (int i = mixinInheritance.Count - 1; i >= 0; --i) - { - var mixin = mixinInheritance[i]; - var count = 0; - for (int j = 0; j < i; ++j) - { - count += mixin.MixinName == mixinInheritance[j].MixinName ? 1 : 0; - } - - var method = mixin.LocalVirtualTable.Methods.FirstOrDefault(x => x.Method.Name.Text == name && x.Method is MethodDefinition); - if (method is not null && (count == 0 || method.Method.Qualifiers.Contains(StrideStorageQualifier.Clone))) - return method.Method as MethodDefinition; - } - return null; - } - - /// - /// Get the streams usage for this entrypoint - /// - /// the current module mixin - /// the entrypoint method - /// a StreamStageUsage containing the streams usages - private StreamStageUsage StreamAnalysisPerShader(ModuleMixin moduleMixin, MethodDeclaration entryPoint, XkShaderStage shaderStage) - { - var visitedMethods = new List(); - var streamStageUsage = new StreamStageUsage { ShaderStage = shaderStage }; - FindStreamsUsage(entryPoint, streamStageUsage.InStreamList, streamStageUsage.OutStreamList, visitedMethods); - visitedMethods.Clear(); - - return streamStageUsage; - } - - /// - /// Finds the usage of the streams - /// - /// the current method - /// list of in-streams - /// list of out-streams - /// list of already visited methods - private void FindStreamsUsage(MethodDeclaration currentMethod, List inStreamList, List outStreamList, List visitedMethods) - { - if (visitedMethods.Contains(currentMethod)) - { - parsingResult.Error(StrideMessageCode.ErrorRecursiveCall, currentMethod.Span, currentMethod); - return; - } - - if (currentMethod != null) - { - var newListVisitedMethods = new List(); - newListVisitedMethods.AddRange(visitedMethods); - newListVisitedMethods.Add(currentMethod); - - List streamUsageList; - if (streamsUsages.TryGetValue(currentMethod, out streamUsageList)) - { - // look for stream usage inside the function - foreach (var streamUsage in streamUsageList) - { - if (streamUsage.CallType == StreamCallType.Member) - { - var isOutStream = outStreamList.Contains(streamUsage.Variable); - var isInStream = inStreamList.Contains(streamUsage.Variable); - - if (streamUsage.Usage.IsWrite() && !isOutStream) - { - outStreamList.Add(streamUsage.Variable); - if (streamUsage.Usage.IsPartial() && !isInStream) // force variable to be passed from previous stages when affectation is only partial. - inStreamList.Add(streamUsage.Variable); - } - else if (streamUsage.Usage.IsRead() && !isOutStream && !isInStream) // first read - inStreamList.Add(streamUsage.Variable); - } - else if (streamUsage.CallType == StreamCallType.Method) - { - if (streamUsage.MethodDeclaration != null) // way to check the built-in functions (could be improved?) - FindStreamsUsage(streamUsage.MethodDeclaration, inStreamList, outStreamList, newListVisitedMethods); - } - else if (streamUsage.CallType != StreamCallType.Direct) // should not happen - parsingResult.Error(StrideMessageCode.ErrorStreamUsageInitialization, streamUsage.Expression.Span, streamUsage.Expression); - } - } - } - } - - /// - /// Pass the stream usage accros the stages. - /// - /// the ordered stream usage list - private void BubbleUpStreamUsages(List streamStageUsages) - { - for (int i = streamStageUsages.Count - 1; i > 0; --i) - { - var nextStreamUsage = streamStageUsages[i]; - var prevStreamUsage = streamStageUsages[i - 1]; - - // pixel output is only SV_Targetx and SV_Depth, everything else intermediate variable - if (nextStreamUsage.ShaderStage == XkShaderStage.Pixel) - { - var semVar = new List(); - var nonSemVar = new List(); - foreach (var variable in nextStreamUsage.OutStreamList) - { - var sem = ((Variable)variable).Qualifiers.OfType().FirstOrDefault(); - if (sem != null && (sem.Name.Text.StartsWith("SV_Target", StringComparison.Ordinal) || sem.Name.Text == "SV_Depth")) - semVar.Add(variable); - else - nonSemVar.Add(variable); - } - nextStreamUsage.InterStreamList.AddRange(nonSemVar); - nextStreamUsage.OutStreamList = semVar; - } - - // NOTE: from this point, nextStreamUsage.OutStreamList is correct. - - List stageExclusiveInputStreams = new List(); - - // add necessary variables to output and input of previous stage - foreach (var variable in nextStreamUsage.InStreamList) - { - if (!prevStreamUsage.OutStreamList.Contains(variable)) - { - var sem = ((Variable)variable).Qualifiers.OfType().FirstOrDefault(); - if (sem != null && (sem.Name.Text == "SV_Coverage" || sem.Name.Text == "SV_IsFrontFace" || sem.Name.Text == "VFACE")) // PS input only - { - stageExclusiveInputStreams.Add(variable); - continue; - } - - prevStreamUsage.OutStreamList.Add(variable); - - if (!prevStreamUsage.InStreamList.Contains(variable)) - prevStreamUsage.InStreamList.Add(variable); - } - } - - // Move stage exclusive input streams to the end of the declaration list - foreach (var variable in stageExclusiveInputStreams) - { - nextStreamUsage.InStreamList.Remove(variable); - nextStreamUsage.InStreamList.Add(variable); - } - - // keep variable from prev output only if they are necessary to next stage OR their semantics force them to be in it - var toKeep = new List(); - foreach (var variable in prevStreamUsage.OutStreamList) - { - var sem = (variable as Variable).Qualifiers.OfType().FirstOrDefault(); - if (nextStreamUsage.InStreamList.Contains(variable) - || ((nextStreamUsage.ShaderStage == XkShaderStage.Pixel || nextStreamUsage.ShaderStage == XkShaderStage.Geometry) && sem != null && sem.Name.Text == "SV_Position")) - toKeep.Add(variable); - else if (nextStreamUsage.ShaderStage == XkShaderStage.Pixel && prevStreamUsage.ShaderStage == XkShaderStage.Geometry && sem != null && sem.Name.Text == "SV_RenderTargetArrayIndex") - { - toKeep.Add(variable); - nextStreamUsage.InStreamList.Add(variable); - } - else - prevStreamUsage.InterStreamList.Add(variable); - } - - prevStreamUsage.OutStreamList.Clear(); - prevStreamUsage.OutStreamList.AddRange(toKeep); - } - } - - /// - /// Organize the streams for the compute shader - /// - /// the StreamStageUsage of the compute stage - private void ComputeShaderStreamAnalysis(StreamStageUsage streamStageUsage) - { - if (streamStageUsage.ShaderStage == XkShaderStage.Compute) - { - streamStageUsage.InterStreamList.AddRange(streamStageUsage.OutStreamList); - streamStageUsage.OutStreamList.Clear(); - } - } - - /// - /// Generates a stream structure and add them to the Ast - /// - /// the entrypoint function - /// the stream usage in this stage - /// the name of the stage - /// the output structutre from the previous stage - /// the new output structure - private StructType GenerateStreams(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOutputStructure /* FIXME */, bool autoGenSem = true) - { - if (entryPoint != null) - { - // create the stream structures - var inStreamStruct = CreateInputStreamStructure(prevOutputStructure, streamStageUsage.InStreamList, stageName + "_INPUT"); - var outStreamStruct = CreateStreamStructure(streamStageUsage.OutStreamList, stageName + "_OUTPUT", true, autoGenSem); - - var intermediateStreamStruct = CreateIntermediateStructType(streamStageUsage, stageName); - - // modify the entrypoint - if (inStreamStruct.Fields.Count != 0) - { - entryPoint.Parameters.Add(new Parameter(new TypeName(inStreamStruct.Name), "__input__")); - entryPoint.Parameters[0].Qualifiers.Values.Remove(ParameterQualifier.InOut); - } - - // add the declaration statements to the entrypoint and fill with the values - entryPoint.Body.InsertRange(0, CreateStreamFromInput(intermediateStreamStruct, "streams", inStreamStruct, new VariableReferenceExpression("__input__"))); - if (outStreamStruct.Fields.Count != 0) - { - entryPoint.Body.AddRange(CreateOutputFromStream(outStreamStruct, "__output__", intermediateStreamStruct, "streams")); - entryPoint.Body.Add(new ReturnStatement { Value = new VariableReferenceExpression("__output__") }); - entryPoint.ReturnType = new TypeName(outStreamStruct.Name); - } - - // explore all the called functions - var visitedMethods = new HashSet(); - var methodsWithStreams = new List(); - PropagateStreamsParameter(entryPoint, inStreamStruct, intermediateStreamStruct, outStreamStruct, visitedMethods, methodsWithStreams); - - CheckCrossStageMethodCall(streamStageUsage.ShaderStage, methodsWithStreams); - - shader.Members.Insert(0, inStreamStruct); - if (outStreamStruct.Fields.Count != 0) - shader.Members.Insert(0, outStreamStruct); - shader.Members.Insert(0, intermediateStreamStruct); - - return outStreamStruct; - } - - return prevOutputStructure; - } - - /// - /// Generates a stream structure and add them to the Ast - for the geometry shader - /// - /// the entrypoint function - /// the stream usage in this stage - /// the name of the stage - /// the output structutre from the previous stage - /// the new output structure - private StructType GenerateStreamsWithSpecialDataInput(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOutputStructure) - { - if (entryPoint != null) - { - var inStreamStruct = CreateInputStreamStructure(prevOutputStructure, streamStageUsage.InStreamList, stageName + "_INPUT"); - var outStreamStruct = CreateStreamStructure(streamStageUsage.OutStreamList, stageName + "_OUTPUT"); - - var mixin = entryPoint.GetTag(StrideTags.ShaderScope) as ModuleMixin; - - var intermediateStreamStruct = CreateIntermediateStructType(streamStageUsage, stageName); - - // put the streams declaration at the beginning of the method body - var streamsDeclaration = new DeclarationStatement(new Variable(new TypeName(intermediateStreamStruct.Name), "streams") { InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(intermediateStreamStruct.Name) } }); - entryPoint.Body.Insert(0, streamsDeclaration); - - // add the declaration statements to the entrypoint and fill with the values - var outputStatements = CreateOutputFromStream(outStreamStruct, "output", intermediateStreamStruct, "streams").ToList(); - var outputVre = new VariableReferenceExpression(((outputStatements.First() as DeclarationStatement).Content as Variable).Name); - - var replacor = new StrideReplaceAppend(streamAnalyzer.AppendMethodCalls, outputStatements, outputVre); - ReplaceAppendMethod(entryPoint, replacor); - - var visitedMethods = new Stack(); - var inStructType = new TypeName(inStreamStruct.Name); - var outStructType = new TypeName(outStreamStruct.Name); - RecursiveRename(entryPoint, inStructType, null, outStructType, null, visitedMethods); - - // explore all the called functions - var streamsVisitedMethods = new HashSet(); - var methodsWithStreams = new List(); - PropagateStreamsParameter(entryPoint, inStreamStruct, intermediateStreamStruct, outStreamStruct, streamsVisitedMethods, methodsWithStreams); - - CheckCrossStageMethodCall(streamStageUsage.ShaderStage, methodsWithStreams); - - shader.Members.Insert(0, inStreamStruct); - shader.Members.Insert(0, outStreamStruct); - shader.Members.Insert(0, intermediateStreamStruct); - - return outStreamStruct; - } - - return prevOutputStructure; - } - - /// - /// Replace the append methods - /// - /// the entrypoint method - /// the visitor - private void ReplaceAppendMethod(MethodDefinition entryPoint, StrideReplaceAppend replacor) - { - replacor.Run(entryPoint); - - List nextMethods; - if (streamsUsages.TryGetValue(entryPoint, out nextMethods)) - nextMethods.Where(x => x.CallType == StreamCallType.Method).Select(x => x.MethodDeclaration as MethodDefinition).Where(x => x != null).ToList().ForEach(x => ReplaceAppendMethod(x, replacor)); - } - - - - /// - /// Generates a stream structure and add them to the Ast - for the hull shader and hull shader constant - /// - /// the entrypoint function - /// entrypoint for the hull shader constant - /// the stream usage in this stage - /// the name of the stage - /// the output structutre from the previous stage - /// the new output structure - private StructType GenerateStreamsForHullShader(MethodDefinition entryPoint, MethodDefinition entryPointHSConstant, StreamStageUsage streamStageUsage, string stageName, StructType prevOutputStructure) - { - if (entryPoint != null) - { - // same behavior as geometry shader - var outStreamStruct = GenerateStreamsWithSpecialDataInput(entryPoint, streamStageUsage, stageName, prevOutputStructure); - var inStreamStruct = shader.Members.OfType().FirstOrDefault(x => x.Name.Text == stageName + "_INPUT"); - var intermediateStreamStruct = shader.Members.OfType().FirstOrDefault(x => x.Name.Text == stageName + "_STREAMS"); - - if (inStreamStruct == null) - throw new Exception("inStreamStruct cannot be null"); - - var inStructType = new TypeName(inStreamStruct.Name); - var outStructType = new TypeName(outStreamStruct.Name); - - // get the Output parameter, its name and remove it - var outputName = "output"; - var outputParam = entryPoint.Parameters.FirstOrDefault(x => x.Type.Name.Text == outStreamStruct.Name.Text); - if (outputParam != null) - { - outputName = outputParam.Name.Text; // get the name of the parameter - entryPoint.Parameters.Remove(outputParam); // remove the parameter - } - - entryPoint.Body.Add(new ReturnStatement { Value = new VariableReferenceExpression(outputName) }); - entryPoint.Body.Insert(0, CreateStructInit(outStreamStruct, outputName)); - entryPoint.ReturnType = outStructType; - - if (entryPointHSConstant != null) - GenerateStreamsForHullShaderConstant(entryPointHSConstant, inStructType, outStructType); - - return outStreamStruct; - } - - return prevOutputStructure; - } - - /// - /// Modify the Hull shader constant - /// - /// the entrypoint method - /// the input structure of the Hull shader - /// the output structure of the Hull shader - private void GenerateStreamsForHullShaderConstant(MethodDefinition entryPoint, TypeName inStreamStructTypeName, TypeName outStreamStructTypeName) - { - if (entryPoint != null) - { - var constStreamStruct = CreateStreamStructure(mainModuleMixin.VirtualTable.Variables.Select(x => x.Variable).Where(x => x.Qualifiers.Contains(StrideStorageQualifier.PatchStream)).Distinct().ToList(), "HS_CONSTANTS"); - var typeConst = new TypeName(constStreamStruct.Name); - - var visitedMethods = new Stack(); - RecursiveRename(entryPoint, inStreamStructTypeName, outStreamStructTypeName, outStreamStructTypeName, typeConst, visitedMethods); - - // get the Constants parameter, its name and remove it - var constParamName = "constants"; - var constParam = entryPoint.Parameters.FirstOrDefault(x => x.Type.Name.Text == constStreamStruct.Name.Text); - if (constParam != null) - { - constParamName = constParam.Name.Text; - entryPoint.Parameters.Remove(constParam); // remove the parameter - } - - var constDecl = new DeclarationStatement( - new Variable(typeConst, constParamName) - { - InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(constStreamStruct.Name) } - }); - - entryPoint.Body.Insert(0, constDecl); // insert structure instance declaration - entryPoint.Body.Add(new ReturnStatement(new VariableReferenceExpression(constParamName))); // add a return statement - - entryPoint.ReturnType = typeConst; // change the return type - - shader.Members.Insert(0, constStreamStruct); - } - } - - /// - /// Generates a stream structure and add them to the Ast - for the domain shader - /// - /// the entrypoint function - /// the stream usage in this stage - /// the name of the stage - /// the output structutre from the previous stage - /// the new output structure - private StructType GenerateStreamsForDomainShader(MethodDefinition entryPoint, StreamStageUsage streamStageUsage, string stageName, StructType prevOutputStructure) - { - if (entryPoint != null) - { - var outStreamStruct = GenerateStreamsForHullShader(entryPoint, null, streamStageUsage, stageName, prevOutputStructure); - - var visitedMethods = new Stack(); - RecursiveRename(entryPoint, null, null, null, new TypeName("HS_CONSTANTS"), visitedMethods); - - return outStreamStruct; - } - - return prevOutputStructure; - } - - /// - /// Checks if a function needs to have a stream strucutre added in its declaration - /// - /// the method definition - /// The stage input structure stream. - /// the stream structure - /// The stage output stream structure. - /// the list of already visited methods - /// The list of methods that have a streams argument. - /// true if needed, false otherwise - private bool PropagateStreamsParameter(MethodDefinition methodDefinition, StructType inputStream, StructType intermediateStream, StructType outputStream, HashSet visitedMethods, List methodsWithStreams) - { - var needStream = false; - - if (methodDefinition != null) - { - if (visitedMethods.Contains(methodDefinition)) - return methodDefinition.Parameters.Count > 0 && methodDefinition.Parameters[0].Type == intermediateStream; - - List streamUsageInfos; - if (streamsUsages.TryGetValue(methodDefinition, out streamUsageInfos)) - { - needStream = streamUsageInfos.Any(x => x.CallType == StreamCallType.Member || x.CallType == StreamCallType.Direct); - visitedMethods.Add(methodDefinition); - - List calls; - if (TryGetMethodCalls(methodDefinition, out calls)) - needStream = calls.Aggregate(needStream, (res, calledmethod) => res | PropagateStreamsParameter(calledmethod as MethodDefinition, inputStream, intermediateStream, outputStream, visitedMethods, methodsWithStreams)); - - if (needStream && !entryPointMethods.Contains(methodDefinition)) - { - var param = new Parameter(new TypeName(intermediateStream.Name), "streams"); - - foreach (var methodRef in mainModuleMixin.ClassReferences.MethodsReferences[methodDefinition]) - { - var vre = new VariableReferenceExpression(param.Name) { TypeInference = { Declaration = param, TargetType = param.Type } }; - methodRef.Arguments.Insert(0, vre); - } - - param.Qualifiers |= ParameterQualifier.InOut; - methodDefinition.Parameters.Insert(0, param); - - // If any parameters in the method are streams, then replace by using the intermediate stream - foreach (var parameter in methodDefinition.Parameters) - { - if (parameter.Type == StreamsType.Streams) - { - parameter.Type = new TypeName(intermediateStream.Name); - } - } - - methodsWithStreams.Add(methodDefinition); - } - } - - TransformStreamsAssignments(methodDefinition, inputStream, intermediateStream, outputStream); - } - return needStream; - } - - - /// - /// Transform stream assignments with correct input/ouput structures - /// - /// the current method - /// the input structure of the stage - /// the intermediate structure of the stage - /// the output structure of the stage - private void TransformStreamsAssignments(MethodDefinition methodDefinition, StructType inputStreamStruct, StructType intermediateStreamStruct, StructType outputStreamStruct) - { - var statementLists = new List(); - SearchVisitor.Run( - methodDefinition, - node => - { - if (node is StatementList) - { - statementLists.Add((StatementList)node); - } - return node; - }); - - // replace stream assignement with field values assignements - foreach (var assignmentKeyBlock in streamAnalyzer.AssignationsToStream) - { - var assignment = assignmentKeyBlock.Key; - var parent = assignmentKeyBlock.Value; - if (!statementLists.Contains(parent)) - { - continue; - } - var index = SearchExpressionStatement(parent, assignment); - - // TODO: check that it is "output = streams" - var statementList = CreateOutputFromStream(outputStreamStruct, (assignment.Target as VariableReferenceExpression).Name.Text, intermediateStreamStruct, "streams").ToList(); - statementList.RemoveAt(0); // do not keep the variable declaration - methodDefinition.Body.RemoveAt(index); - methodDefinition.Body.InsertRange(index, statementList); - } - - // replace stream assignement with field values assignements - foreach (var assignmentKeyBlock in streamAnalyzer.StreamAssignations) - { - var assignment = assignmentKeyBlock.Key; - var parent = assignmentKeyBlock.Value; - if (!statementLists.Contains(parent)) - { - continue; - } - var index = SearchExpressionStatement(parent, assignment); - - var statementList = CreateStreamFromInput(intermediateStreamStruct, "streams", inputStreamStruct, assignment.Value, false).ToList(); - statementList.RemoveAt(0); // do not keep the variable declaration - parent.RemoveAt(index); - parent.InsertRange(index, statementList); - } - - foreach (var variableAndParent in streamAnalyzer.VariableStreamsAssignment) - { - var variable = variableAndParent.Key; - var parent = variableAndParent.Value; - - if (!statementLists.Contains(parent)) - { - continue; - } - - variable.Type = new TypeName(intermediateStreamStruct.Name); - } - } - - /// - /// Search a statement in method. - /// - /// The statement list. - /// The expression. - /// The index of the statement in the statement list. - private int SearchExpressionStatement(StatementList statementList, Expression expression) - { - return statementList.IndexOf(statementList.OfType().FirstOrDefault(x => x.Expression == expression)); - } - - /// - /// Recursively rename the input/output types - /// - /// the method to explore - /// the TypeName for Input - /// the TypeName for Input2 - /// the TypeName for Output - /// the TypeName for Constants - /// the already visited methods - private void RecursiveRename(MethodDeclaration methodDeclaration, TypeName inputName, TypeName input2Name, TypeName outputName, TypeName constantsName, Stack visitedMethods) - { - if (methodDeclaration == null || visitedMethods.Contains(methodDeclaration)) - return; - - RenameInputOutput(methodDeclaration, inputName, input2Name, outputName, constantsName); - visitedMethods.Push(methodDeclaration); - - List calls; - if (TryGetMethodCalls(methodDeclaration, out calls)) - { - foreach (var calledmethod in calls) - RecursiveRename(calledmethod, inputName, input2Name, outputName, constantsName, visitedMethods); - } - } - - /// - /// Get all the calls from the current method - /// - /// the current method - /// list of method called - /// true if calls were found - //private bool TryGetMethodCalls(MethodDeclaration currentMethod, out List calledMethods) - private bool TryGetMethodCalls(MethodDeclaration currentMethod, out List calledMethods) - { - List streamUsageInfos; - if (streamsUsages.TryGetValue(currentMethod, out streamUsageInfos)) - { - //calledMethods = streamUsageInfos.Where(x => x.CallType == StreamCallType.Method).Select(x => x.MethodReference).ToList(); - calledMethods = streamUsageInfos.Where(x => x.CallType == StreamCallType.Method).Select(x => x.MethodDeclaration).ToList(); - return true; - } - - calledMethods = null; - return false; - } - - /// - /// rename the input/ouput of a method - /// - /// the method - /// the type replacement for Input - /// the type replacement for Input2 - /// the type replacement for Output - /// the type replacement for Constants - private void RenameInputOutput(MethodDeclaration methodDeclaration, TypeName inputName, TypeName input2Name, TypeName outputName, TypeName constantsName) - { - if (inputName != null) - { - var replacor = new StrideReplaceVisitor(StreamsType.Input, inputName); - replacor.Run(methodDeclaration); - } - if (input2Name != null) - { - var replacor = new StrideReplaceVisitor(StreamsType.Input2, input2Name); - replacor.Run(methodDeclaration); - } - if (outputName != null) - { - var replacor = new StrideReplaceVisitor(StreamsType.Output, outputName); - replacor.Run(methodDeclaration); - } - if (constantsName != null) - { - var replacor = new StrideReplaceVisitor(StreamsType.Constants, constantsName); - replacor.Run(methodDeclaration); - } - } - - /// - /// Check that methods with streams are not called across several stages. - /// - /// The current shader stage to check. - /// The list of methods that need streams in that stage. - private void CheckCrossStageMethodCall(XkShaderStage shaderStage, List methodsWithStreams) - { - foreach (var stageList in methodsPerShaderStage) - { - var stage = stageList.Key; - if (stage != shaderStage) // should always be true - { - foreach (var method in methodsWithStreams) - { - if (stageList.Value.Contains(method)) - { - parsingResult.Error(StrideMessageCode.ErrorCrossStageMethodCall, method.Span, method, stage, shaderStage); - } - } - } - } - methodsPerShaderStage.Add(shaderStage, methodsWithStreams); - } - - #endregion - - #region Private static methods - - /// - /// Creates assignement statements with its default value - /// - /// the stream structure - /// the name of the stream - /// the input structure - /// the initial value - /// ??? - /// A collection of statements - private static IEnumerable AssignStreamFromInput(StructType streamStruct, string streamName, StructType inputStruct, Expression initialValue, bool basicTransformation) - { - foreach (var currentField in inputStruct.Fields) - { - // Ignore fields that don't exist in Streams. - // It could happen if HSConstantMain references a stream (gets added to HS_OUTPUT), - // and in HSMain CreateStreamFromInput() is called (this stream doesn't exist in DS_STREAMS). - if (streamStruct.Fields.All(x => x.Name != currentField.Name)) - continue; - - // If we have a scope stack (advanced analysis), then convert expression by appending - // field to each reference to a variable of inputStruct type - // i.e. "output = input1 * 3 + input2 * 5" will become "output.A = input1.A * 3 + input2.A * 5" - // Otherwise consider it is as a simple a variable reference and directly append field. - if (basicTransformation) - { - yield return new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), - new MemberReferenceExpression(initialValue, currentField.Name))); - } - else - { - //yield return AssignStreamFieldFromInput(streamName, inputStruct, initialValue, scopeStack, currentField); - foreach (var field in streamStruct.Fields.Where(x => x.Name == currentField.Name)) // TODO: where might be useless - { - if (field.Type is ArrayType) - { - //create a for loop - - var iteratorName = field.Name.Text + "_Iter"; - var iterator = new Variable(ScalarType.Int, iteratorName, new LiteralExpression(0)); - var start = new DeclarationStatement(iterator); - var condition = new BinaryExpression(BinaryOperator.Less, new VariableReferenceExpression(iterator), (field.Type as ArrayType).Dimensions[0]); - var next = new UnaryExpression(UnaryOperator.PreIncrement, new VariableReferenceExpression(iterator)); - var forLoop = new ForStatement(start, condition, next); - - var fieldAssigner = new StreamFieldVisitor(field, new VariableReferenceExpression(iterator)); - var clonedExpression = fieldAssigner.Run(StrideAssignmentCloner.Run(initialValue)); - - forLoop.Body = new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new IndexerExpression(new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), new VariableReferenceExpression(iterator)), - clonedExpression)); - - yield return forLoop; - } - else - { - var fieldAssigner = new StreamFieldVisitor(field); - //var clonedExpression = fieldAssigner.Run(initialValue.DeepClone()); - var clonedExpression = fieldAssigner.Run(StrideAssignmentCloner.Run(initialValue)); - - yield return new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name), - clonedExpression)); - } - } - } - } - } - - /// - /// Creates assignement statements with its default value - /// - /// the output structure - /// the name of the output stream - /// the stream structure - /// the name of the stream - /// a collection of statements - private static IEnumerable AssignOutputFromStream(StructType outputStruct, string outputName, StructType streamStruct, string streamName) - { - foreach (var currentField in outputStruct.Fields) - { - yield return new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new MemberReferenceExpression(new VariableReferenceExpression(outputName), currentField.Name), - new MemberReferenceExpression(new VariableReferenceExpression(streamName), currentField.Name))); - } - } - - /// - /// Creates a stream structure and assign its default values - /// - /// the structure - /// the name of the stream - /// the inputStructure - /// the initial value of the struture - /// ??? - /// a collection of statements to insert in the body of a method - private static IEnumerable CreateStreamFromInput(StructType streamStruct, string streamName, StructType inputStruct, Expression initialValue, bool basicTransformation = true) - { - yield return CreateStructInit(streamStruct, streamName); - - foreach (var statement in AssignStreamFromInput(streamStruct, streamName, inputStruct, initialValue, basicTransformation)) - { - yield return statement; - } - } - - /// - /// Creates an output stream structure and assign its default values - /// - /// the structuer - /// the name of the structure - /// >the initial value of the struture - /// the name of the stream - /// a collection of statements to insert in the body of a method - private static IEnumerable CreateOutputFromStream(StructType outputStruct, string outputName, StructType streamStruct, string streamName) - { - yield return CreateStructInit(outputStruct, outputName); - - foreach (var statement in AssignOutputFromStream(outputStruct, outputName, streamStruct, streamName)) - { - yield return statement; - } - } - - /// - /// Generate a stream structure - /// - /// the list of the declarations - /// the name of the structure - /// the structure - private static StructType CreateStreamStructure(List streamsDeclarationList, string structName, bool useSem = true, bool addAutoSem = true) - { - var tempStruct = new StructType { Name = new Identifier(structName) }; - foreach (var streamDecl in streamsDeclarationList) - { - var streamVar = streamDecl as Variable; - if (streamVar != null) - { - var variable = new Variable(streamVar.Type, streamVar.Name) { Span = streamVar.Span }; - if (useSem) - { - foreach (var qualifier in streamVar.Qualifiers.OfType()) - variable.Qualifiers |= qualifier; - } - - foreach (var qualifier in streamVar.Qualifiers.OfType()) - variable.Qualifiers |= qualifier; - - if (useSem && addAutoSem) - { - var semantic = variable.Qualifiers.Values.OfType().FirstOrDefault(); - if (semantic == null) - variable.Qualifiers |= new Semantic(variable.Name.Text.ToUpperInvariant() + "_SEM"); - } - - tempStruct.Fields.Add(variable); - } - } - return tempStruct; - } - - /// - /// Generate a stream structure from a previous output structure if specified - /// - /// The previous stream stage to match the new structure's layout to (optional) - /// the list of the declarations - /// the name of the structure - /// the structure - private static StructType CreateInputStreamStructure(StructType prevOutputStructure, List streamsDeclarationList, string structName, bool useSem = true, - bool autoAddSem = true) - { - var declarations = new List(); - var semanticNames = new HashSet(); - var fieldNames = new HashSet(); - - if (prevOutputStructure != null) - { - foreach (var variable in prevOutputStructure.Fields) - { - var sem = variable.Qualifiers.OfType().FirstOrDefault(); - declarations.Add(variable); - fieldNames.Add(variable.Name); - if (sem != null) - { - semanticNames.Add(sem.Name); - } - } - } - - foreach (var decl in streamsDeclarationList) - { - var variable = (Variable)decl; - var sem = variable.Qualifiers.OfType().FirstOrDefault(); - if (!fieldNames.Contains(variable.Name) && (sem == null || !semanticNames.Contains(sem.Name))) - { - declarations.Add(decl); - if (sem != null) semanticNames.Add(sem.Name); - fieldNames.Add(variable.Name); - } - } - return CreateStreamStructure(declarations, structName, useSem, autoAddSem); - } - - /// - /// Creates an intermediate structure given the stream usage - /// - /// the StreamStageUsage - /// the name of the stage - /// the intermediate stream structure - private static StructType CreateIntermediateStructType(StreamStageUsage streamStageUsage, string stageName) - { - var tempList = new List(); - tempList.AddRange(streamStageUsage.InStreamList); - tempList.AddRange(streamStageUsage.InterStreamList); - tempList.AddRange(streamStageUsage.OutStreamList); - return CreateStreamStructure(tempList.Distinct().ToList(), stageName + "_STREAMS", false, false); - } - - /// - /// Creates an declaration for this structure - /// - /// the structure - /// the name of the variable - /// the declaration statement - private static DeclarationStatement CreateStructInit(StructType structType, string structVarName) - { - return new DeclarationStatement( - new Variable(new TypeName(structType.Name), structVarName) - { - InitialValue = new CastExpression { From = new LiteralExpression(0), Target = new TypeName(structType.Name) } - }); - } - - #endregion - } - - enum XkShaderStage - { - Vertex, - Hull, - Constant, - Domain, - Geometry, - Pixel, - Compute, - None - } - - class StreamStageUsage - { - public XkShaderStage ShaderStage = XkShaderStage.None; - public List InStreamList = new List(); - public List InterStreamList = new List(); - public List OutStreamList = new List(); - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideTagCleaner.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideTagCleaner.cs deleted file mode 100644 index 40aa1762e5..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideTagCleaner.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideTagCleaner : ShaderWalker - { - public StrideTagCleaner() - : base(false, false) - { - } - - public void Run(ShaderClassType shader) - { - Visit(shader); - } - - public override void DefaultVisit(Node node) - { - // Keeping it for ShaderLinker (removed by StrideShaderCleaner) - //node.RemoveTag(StrideTags.ConstantBuffer); - node.RemoveTag(StrideTags.ShaderScope); - node.RemoveTag(StrideTags.StaticRef); - node.RemoveTag(StrideTags.ExternRef); - node.RemoveTag(StrideTags.StageInitRef); - node.RemoveTag(StrideTags.CurrentShader); - node.RemoveTag(StrideTags.VirtualTableReference); - node.RemoveTag(StrideTags.BaseDeclarationMixin); - node.RemoveTag(StrideTags.ShaderScope); - base.DefaultVisit(node); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideTypeCleaner.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideTypeCleaner.cs deleted file mode 100644 index 80e404ef6b..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideTypeCleaner.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideTypeCleaner : ShaderWalker - { - public StrideTypeCleaner() - : base(false, false) - { - } - - public void Run(Shader shader) - { - Visit(shader); - } - - public override void DefaultVisit(Node node) - { - if (node is Expression || node is TypeBase) - VisitTypeInferencer((ITypeInferencer)node); - - base.DefaultVisit(node); - } - - private void VisitTypeInferencer(ITypeInferencer expression) - { - expression.TypeInference.Declaration = null; - expression.TypeInference.TargetType = null; - expression.TypeInference.ExpectedType = null; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/StrideVariableUsageVisitor.cs b/sources/engine/Stride.Shaders.Parser/Mixins/StrideVariableUsageVisitor.cs deleted file mode 100644 index adc7a50821..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/StrideVariableUsageVisitor.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser.Mixins -{ - internal class StrideVariableUsageVisitor : ShaderWalker - { - private Dictionary VariablesUsages; - - public StrideVariableUsageVisitor(Dictionary variablesUsages) - : base(false, false) - { - if (variablesUsages == null) - VariablesUsages = new Dictionary(); - else - VariablesUsages = variablesUsages; - } - - public void Run(ShaderClassType shaderClassType) - { - Visit(shaderClassType); - } - - public override void Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - CheckUsage(variableReferenceExpression.TypeInference.Declaration as Variable); - } - - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - base.Visit(memberReferenceExpression); - CheckUsage(memberReferenceExpression.TypeInference.Declaration as Variable); - } - - private void CheckUsage(Variable variable) - { - if (variable == null) - return; - - if (VariablesUsages.ContainsKey(variable)) - VariablesUsages[variable] = true; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Mixins/VariableShaderCouple.cs b/sources/engine/Stride.Shaders.Parser/Mixins/VariableShaderCouple.cs deleted file mode 100644 index 6795359967..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Mixins/VariableShaderCouple.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; - -namespace Stride.Shaders.Parser.Mixins -{ - [DataContract] - internal class VariableShaderCouple - { - public Variable Variable; - public ShaderClassType Shader; - - public VariableShaderCouple() : this(null, null) { } - - public VariableShaderCouple(Variable variable, ShaderClassType shader) - { - Variable = variable; - Shader = shader; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Parser.cs b/sources/engine/Stride.Shaders.Parser/Parser.cs deleted file mode 100644 index e7f1adc098..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Parser.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Grammar.Stride; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser -{ - /// - /// Main class for parsing Stride HLSL grammar. - /// - public static class StrideShaderParser - { - /// - /// Preinitialize the parser. - /// - public static void Initialize() - { - ShaderParser.GetParser(); - } - - /// - /// Preprocesses and parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static ParsingResult TryPreProcessAndParse(string source, string sourceFileName, Stride.Core.Shaders.Parser.ShaderMacro[] macros = null, params string[] includeDirectories) - { - - var result = ShaderParser.GetParser().TryPreProcessAndParse(source, sourceFileName, macros, includeDirectories); - PrepareShader(result.Shader); - return result; - } - - /// - /// Preprocesses and parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static Shader PreProcessAndParse(string source, string sourceFileName, Stride.Core.Shaders.Parser.ShaderMacro[] macros = null, params string[] includeDirectories) - { - return PrepareShader(ShaderParser.GetParser().PreProcessAndParse(source, sourceFileName, macros, includeDirectories)); - } - - /// - /// Preprocesses and parses the specified source. - /// - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static ParsingResult TryPreProcessAndParse(string sourceFileName, Stride.Core.Shaders.Parser.ShaderMacro[] macros = null, params string[] includeDirectories) - { - var result = TryPreProcessAndParse(File.ReadAllText(sourceFileName), sourceFileName, macros, includeDirectories); - return result; - } - - /// - /// Preprocesses and parses the specified source. - /// - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static Shader PreProcessAndParse(string sourceFileName, Stride.Core.Shaders.Parser.ShaderMacro[] macros = null, params string[] includeDirectories) - { - return PreProcessAndParse(File.ReadAllText(sourceFileName), sourceFileName, macros, includeDirectories); - } - - /// - /// Parses the specified source code. - /// - /// The source code. - /// Name of the source file. - /// - public static Shader Parse(string sourceCode, string sourceFileName) - { - return PrepareShader(ShaderParser.GetParser().ParseAndCheck(sourceCode, sourceFileName)); - } - - /// - /// Parses the specified source code. - /// - /// The source code. - /// Name of the source file. - /// - public static ParsingResult TryParse(string sourceCode, string sourceFileName) - { - var parsingResult = ShaderParser.GetParser().Parse(sourceCode, sourceFileName); - PrepareShader(parsingResult.Shader); - return parsingResult; - } - - private static Shader PrepareShader(Shader shader) - { - if (shader == null) - { - return null; - } - - // Replace all variable in constant buffers by single variable with a constant buffer tag - foreach (var classType in GetShaderClassTypes(shader.Declarations)) - { - var members = new List(); - foreach (var member in classType.Members) - { - var constantBuffer = member as ConstantBuffer; - if (constantBuffer != null) - { - var variables = new List(); - for (var index = 0; index < constantBuffer.Members.Count; index++) - { - var variable = constantBuffer.Members[index] as Variable; - if (variable != null) - { - foreach (var subVariable in variable.Instances()) - { - subVariable.SetTag(StrideTags.ConstantBuffer, constantBuffer); - subVariable.SetTag(StrideTags.ConstantBufferIndex, index); - if (variable.IsGroup && !ReferenceEquals(variable, subVariable)) - { - subVariable.Qualifiers |= variable.Qualifiers; - subVariable.Attributes.AddRange(variable.Attributes); - } - - variables.Add(subVariable); - } - } - } - - members.AddRange(variables); - } - else - { - members.Add(member); - } - } - - classType.Members = members; - } - return shader; - } - - internal static IEnumerable GetShaderClassTypes(IEnumerable nodes) - { - foreach (var node in nodes) - { - var namespaceBlock = node as NamespaceBlock; - if (namespaceBlock != null) - { - foreach (var type in GetShaderClassTypes(namespaceBlock.Body)) - { - yield return type; - } - } - else - { - var shaderClass = node as ShaderClassType; - if (shaderClass != null) - { - yield return shaderClass; - } - } - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Performance/GenerateShaderPerformance.cs b/sources/engine/Stride.Shaders.Parser/Performance/GenerateShaderPerformance.cs deleted file mode 100644 index b4c7e79d2d..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Performance/GenerateShaderPerformance.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Diagnostics; -using Stride.Core.Diagnostics; - -namespace Stride.Shaders.Parser.Performance -{ - public static class GenerateShaderPerformance - { - internal static Logger Logger = GlobalLogger.GetLogger("StrideShaderPerformance"); // Global logger for shader profiling - - private static Stopwatch Global = new Stopwatch(); - private static Stopwatch GroupByConstantBuffer = new Stopwatch(); - private static Stopwatch StreamCreator = new Stopwatch(); - private static Stopwatch ExpandForEachStatements = new Stopwatch(); - private static Stopwatch RemoveUselessVariables = new Stopwatch(); - - public static void Start(GenerateShaderStage stage) - { - switch (stage) - { - case GenerateShaderStage.Global: - Global.Start(); - break; - case GenerateShaderStage.GroupByConstantBuffer: - GroupByConstantBuffer.Start(); - break; - case GenerateShaderStage.StreamCreator: - StreamCreator.Start(); - break; - case GenerateShaderStage.ExpandForEachStatements: - ExpandForEachStatements.Start(); - break; - case GenerateShaderStage.RemoveUselessVariables: - RemoveUselessVariables.Start(); - break; - } - } - - public static void Pause(GenerateShaderStage stage) - { - switch (stage) - { - case GenerateShaderStage.Global: - Global.Stop(); - break; - case GenerateShaderStage.GroupByConstantBuffer: - GroupByConstantBuffer.Stop(); - break; - case GenerateShaderStage.StreamCreator: - StreamCreator.Stop(); - break; - case GenerateShaderStage.ExpandForEachStatements: - ExpandForEachStatements.Stop(); - break; - case GenerateShaderStage.RemoveUselessVariables: - RemoveUselessVariables.Start(); - break; - } - } - - public static void Reset() - { - Global.Reset(); - GroupByConstantBuffer.Reset(); - StreamCreator.Reset(); - ExpandForEachStatements.Reset(); - RemoveUselessVariables.Reset(); - } - - public static void PrintResult() - { - Logger.Info(@"----------------------------GENERATE SHADER ANALYZER-----------------------------"); - Logger.Info($"Whole generation took {Global.ElapsedMilliseconds} ms"); - Logger.Info($"GroupByConstantBuffer took {GroupByConstantBuffer.ElapsedMilliseconds} ms"); - Logger.Info($"StreamCreator took {StreamCreator.ElapsedMilliseconds} ms"); - Logger.Info($"ExpandForEachStatements took {ExpandForEachStatements.ElapsedMilliseconds} ms"); - Logger.Info($"RemoveUselessVariables took {RemoveUselessVariables.ElapsedMilliseconds} ms"); - Logger.Info(@"-------------------------------------------------------------------------------"); - } - } - - public enum GenerateShaderStage - { - Global, - GroupByConstantBuffer, - StreamCreator, - ExpandForEachStatements, - RemoveUselessVariables - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Performance/MixPerformance.cs b/sources/engine/Stride.Shaders.Parser/Performance/MixPerformance.cs deleted file mode 100644 index 5ca59ffbaf..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Performance/MixPerformance.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Diagnostics; -using Stride.Core.Diagnostics; - -namespace Stride.Shaders.Parser.Performance -{ - public static class MixPerformance - { - internal static Logger Logger = GlobalLogger.GetLogger("StrideShaderPerformance"); // Global logger for shader profiling - - private static Stopwatch Global = new Stopwatch(); - private static Stopwatch AddDefaultCompositions = new Stopwatch(); - private static Stopwatch CreateReferencesStructures = new Stopwatch(); - private static Stopwatch RegenKeys = new Stopwatch(); - private static Stopwatch BuildMixinInheritance = new Stopwatch(); - private static Stopwatch ComputeMixinOccurrence = new Stopwatch(); - private static Stopwatch BuildStageInheritance = new Stopwatch(); - private static Stopwatch LinkVariables = new Stopwatch(); - private static Stopwatch ProcessExterns = new Stopwatch(); - private static Stopwatch PatchAllMethodInferences = new Stopwatch(); - private static Stopwatch MergeReferences = new Stopwatch(); - private static Stopwatch RenameAllVariables = new Stopwatch(); - private static Stopwatch RenameAllMethods = new Stopwatch(); - private static Stopwatch GenerateShader = new Stopwatch(); - - public static void Start(MixStage stage) - { - switch (stage) - { - case MixStage.Global: - Global.Start(); - break; - case MixStage.AddDefaultCompositions: - AddDefaultCompositions.Start(); - break; - case MixStage.CreateReferencesStructures: - CreateReferencesStructures.Start(); - break; - case MixStage.RegenKeys: - RegenKeys.Start(); - break; - case MixStage.BuildMixinInheritance: - BuildMixinInheritance.Start(); - break; - case MixStage.ComputeMixinOccurrence: - ComputeMixinOccurrence.Start(); - break; - case MixStage.BuildStageInheritance: - BuildStageInheritance.Start(); - break; - case MixStage.LinkVariables: - LinkVariables.Start(); - break; - case MixStage.ProcessExterns: - ProcessExterns.Start(); - break; - case MixStage.PatchAllMethodInferences: - PatchAllMethodInferences.Start(); - break; - case MixStage.MergeReferences: - MergeReferences.Start(); - break; - case MixStage.RenameAllVariables: - RenameAllVariables.Start(); - break; - case MixStage.RenameAllMethods: - RenameAllMethods.Start(); - break; - case MixStage.GenerateShader: - GenerateShader.Start(); - break; - } - } - - public static void Pause(MixStage stage) - { - switch (stage) - { - case MixStage.Global: - Global.Stop(); - break; - case MixStage.AddDefaultCompositions: - AddDefaultCompositions.Stop(); - break; - case MixStage.CreateReferencesStructures: - CreateReferencesStructures.Stop(); - break; - case MixStage.RegenKeys: - RegenKeys.Stop(); - break; - case MixStage.BuildMixinInheritance: - BuildMixinInheritance.Stop(); - break; - case MixStage.ComputeMixinOccurrence: - ComputeMixinOccurrence.Stop(); - break; - case MixStage.BuildStageInheritance: - BuildStageInheritance.Stop(); - break; - case MixStage.LinkVariables: - LinkVariables.Stop(); - break; - case MixStage.ProcessExterns: - ProcessExterns.Stop(); - break; - case MixStage.PatchAllMethodInferences: - PatchAllMethodInferences.Stop(); - break; - case MixStage.MergeReferences: - MergeReferences.Stop(); - break; - case MixStage.RenameAllVariables: - RenameAllVariables.Stop(); - break; - case MixStage.RenameAllMethods: - RenameAllMethods.Stop(); - break; - case MixStage.GenerateShader: - GenerateShader.Stop(); - break; - } - } - - public static void Reset() - { - Global.Reset(); - AddDefaultCompositions.Reset(); - CreateReferencesStructures.Reset(); - RegenKeys.Reset(); - BuildMixinInheritance.Reset(); - ComputeMixinOccurrence.Reset(); - BuildStageInheritance.Reset(); - LinkVariables.Reset(); - ProcessExterns.Reset(); - PatchAllMethodInferences.Reset(); - MergeReferences.Reset(); - RenameAllVariables.Reset(); - RenameAllMethods.Reset(); - GenerateShader.Reset(); - } - - public static void PrintResult() - { - Logger.Info(@"---------------------------------MIX ANALYZER-----------------------------------"); - Logger.Info($"Whole mix took {Global.ElapsedMilliseconds} ms"); - Logger.Info($"AddDefaultCompositions took {AddDefaultCompositions.ElapsedMilliseconds} ms"); - Logger.Info($"CreateReferencesStructures took {CreateReferencesStructures.ElapsedMilliseconds} ms"); - Logger.Info($"RegenKeys took {RegenKeys.ElapsedMilliseconds} ms"); - Logger.Info($"BuildMixinInheritance took {BuildMixinInheritance.ElapsedMilliseconds} ms"); - Logger.Info($"ComputeMixinOccurrence took {ComputeMixinOccurrence.ElapsedMilliseconds} ms"); - Logger.Info($"BuildStageInheritance took {BuildStageInheritance.ElapsedMilliseconds} ms"); - Logger.Info($"LinkVariables took {LinkVariables.ElapsedMilliseconds} ms"); - Logger.Info($"ProcessExterns took {ProcessExterns.ElapsedMilliseconds} ms"); - Logger.Info($"PatchAllMethodInferences took {PatchAllMethodInferences.ElapsedMilliseconds} ms"); - Logger.Info($"MergeReferences took {MergeReferences.ElapsedMilliseconds} ms"); - Logger.Info($"RenameAllVariables took {RenameAllVariables.ElapsedMilliseconds} ms"); - Logger.Info($"RenameAllMethods took {RenameAllMethods.ElapsedMilliseconds} ms"); - Logger.Info($"GenerateShader took {GenerateShader.ElapsedMilliseconds} ms"); - Logger.Info(@"-------------------------------------------------------------------------------"); - } - } - - public enum MixStage - { - Global, - AddDefaultCompositions, - CreateReferencesStructures, - RegenKeys, - BuildMixinInheritance, - ComputeMixinOccurrence, - BuildStageInheritance, - LinkVariables, - ProcessExterns, - PatchAllMethodInferences, - MergeReferences, - RenameAllVariables, - RenameAllMethods, - GenerateShader - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Performance/PerformanceLogger.cs b/sources/engine/Stride.Shaders.Parser/Performance/PerformanceLogger.cs deleted file mode 100644 index 13a78c7fef..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Performance/PerformanceLogger.cs +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using Stride.Core.Diagnostics; -using Stride.Core.IO; - -namespace Stride.Shaders.Parser.Performance -{ - public static class PerformanceLogger - { - internal static Logger Logger = GlobalLogger.GetLogger("StrideShaderPerformance"); // Global logger for shader profiling - - private static int globalCount; - private static int loadingCount; - private static int typeAnalysisCount; - private static int semanticAnalysisCount; - private static int mixCount; - private static int deepCloneCount; - private static int astParsingCount; - - private static readonly List GlobalTimes = new List(); - private static readonly List LoadingTimes = new List(); - private static readonly List TypeAnalysisTimes = new List(); - private static readonly List SemanticAnalysisTimes = new List(); - private static readonly List MixTimes = new List(); - private static readonly List DeepcloneTimes = new List(); - private static readonly List AstParsingTimes = new List(); - - private static Stopwatch globalWatch = new Stopwatch(); - private static Stopwatch loadingWatch = new Stopwatch(); - private static Stopwatch typeAnalysisWatch = new Stopwatch(); - private static Stopwatch semanticAnalysisWatch = new Stopwatch(); - private static Stopwatch mixWatch = new Stopwatch(); - private static Stopwatch deepCloneWatch = new Stopwatch(); - private static Stopwatch astParsingWatch = new Stopwatch(); - - public static void Start(PerformanceStage stage) - { - switch (stage) - { - case PerformanceStage.Global: - globalWatch.Start(); - break; - case PerformanceStage.Loading: - loadingWatch.Start(); - break; - case PerformanceStage.TypeAnalysis: - typeAnalysisWatch.Start(); - break; - case PerformanceStage.SemanticAnalysis: - semanticAnalysisWatch.Start(); - break; - case PerformanceStage.Mix: - mixWatch.Start(); - break; - case PerformanceStage.DeepClone: - deepCloneWatch.Start(); - break; - case PerformanceStage.AstParsing: - astParsingWatch.Start(); - break; - } - } - - public static void Pause(PerformanceStage stage) - { - switch (stage) - { - case PerformanceStage.Global: - globalWatch.Stop(); - break; - case PerformanceStage.Loading: - loadingWatch.Stop(); - break; - case PerformanceStage.TypeAnalysis: - typeAnalysisWatch.Stop(); - break; - case PerformanceStage.SemanticAnalysis: - semanticAnalysisWatch.Stop(); - break; - case PerformanceStage.Mix: - mixWatch.Stop(); - break; - case PerformanceStage.DeepClone: - deepCloneWatch.Stop(); - break; - case PerformanceStage.AstParsing: - astParsingWatch.Stop(); - break; - } - } - - public static void Stop(PerformanceStage stage) - { - switch (stage) - { - case PerformanceStage.Global: - globalWatch.Stop(); - GlobalTimes.Add(globalWatch.ElapsedMilliseconds); - ++globalCount; - break; - case PerformanceStage.Loading: - loadingWatch.Stop(); - LoadingTimes.Add(loadingWatch.ElapsedMilliseconds); - ++loadingCount; - break; - case PerformanceStage.TypeAnalysis: - typeAnalysisWatch.Stop(); - TypeAnalysisTimes.Add(typeAnalysisWatch.ElapsedMilliseconds); - ++typeAnalysisCount; - break; - case PerformanceStage.SemanticAnalysis: - semanticAnalysisWatch.Stop(); - SemanticAnalysisTimes.Add(semanticAnalysisWatch.ElapsedMilliseconds); - ++semanticAnalysisCount; - break; - case PerformanceStage.Mix: - mixWatch.Stop(); - MixTimes.Add(mixWatch.ElapsedMilliseconds); - ++mixCount; - break; - case PerformanceStage.DeepClone: - deepCloneWatch.Stop(); - DeepcloneTimes.Add(deepCloneWatch.ElapsedMilliseconds); - ++deepCloneCount; - break; - case PerformanceStage.AstParsing: - astParsingWatch.Stop(); - AstParsingTimes.Add(astParsingWatch.ElapsedMilliseconds); - ++astParsingCount; - break; - } - } - - public static void Reset() - { - globalWatch.Reset(); - loadingWatch.Reset(); - typeAnalysisWatch.Reset(); - semanticAnalysisWatch.Reset(); - mixWatch.Reset(); - deepCloneWatch.Reset(); - astParsingWatch.Reset(); - } - - public static void PrintResult() - { - Logger.Info(@"--------------------------TOTAL PERFORMANCE ANALYZER---------------------------"); - Logger.Info($"Loading took {LoadingTimes.Sum()} ms for {loadingCount} shader(s)"); - Logger.Info($"Type analysis took {TypeAnalysisTimes.Sum()} ms for {typeAnalysisCount} shader(s)"); - Logger.Info($"Semantic analysis took {SemanticAnalysisTimes.Sum()} ms for {semanticAnalysisCount} shader(s)"); - Logger.Info($"Mix took {MixTimes.Sum()} ms for {mixCount} shader(s)"); - Logger.Info($"DeepClone took {DeepcloneTimes.Sum()} ms for {deepCloneCount} shader(s)"); - Logger.Info($"Ast parsing took {AstParsingTimes.Sum()} ms for {astParsingCount} shader(s)"); - Logger.Info(@"-------------------------------------------------------------------------------"); - - } - public static void PrintLastResult() - { - - Logger.Info(@"--------------------------LAST PERFORMANCE ANALYZER---------------------------"); - Logger.Info($"Process took {globalWatch.ElapsedMilliseconds} ms"); - Logger.Info($"Loading took {loadingWatch.ElapsedMilliseconds} ms"); - Logger.Info($"Type analysis took {typeAnalysisWatch.ElapsedMilliseconds} ms"); - Logger.Info($"Semantic analysis took {semanticAnalysisWatch.ElapsedMilliseconds} ms"); - Logger.Info($"Mix took {mixWatch.ElapsedMilliseconds} ms"); - Logger.Info($"DeepClone took {deepCloneWatch.ElapsedMilliseconds} ms"); - Logger.Info($"Ast parsing took {astParsingWatch.ElapsedMilliseconds} ms"); - Logger.Info(@"------------------------------------------------------------------------------"); - - } - - - public static void WriteOut(int limit) - { - if (globalCount == limit) - { - PrintResult(); - TextWriter tw = new StreamWriter(VirtualFileSystem.ApplicationLocal.OpenStream("performance.csv", VirtualFileMode.Append, VirtualFileAccess.Write)); - tw.WriteLine("loading,type,semantic,mix,deepclone,global"); - - for (var i = 0; i < limit; ++i) - { - tw.WriteLine("{0},{1},{2},{3},{4},{5}", LoadingTimes[i], TypeAnalysisTimes[i], SemanticAnalysisTimes[i], MixTimes[i], DeepcloneTimes[i], GlobalTimes[i]); - } - tw.Dispose(); - } - } - } - - public enum PerformanceStage - { - Global, - Loading, - TypeAnalysis, - SemanticAnalysis, - Mix, - DeepClone, - AstParsing - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Performance/SemanticPerformance.cs b/sources/engine/Stride.Shaders.Parser/Performance/SemanticPerformance.cs deleted file mode 100644 index d3e48ecace..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Performance/SemanticPerformance.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Diagnostics; -using Stride.Core.Diagnostics; - -namespace Stride.Shaders.Parser.Performance -{ - public static class SemanticPerformance - { - internal static Logger Logger = GlobalLogger.GetLogger("StrideShaderPerformance"); // Global logger for shader profiling - - private static Stopwatch TotalTime = new Stopwatch(); - - private static Stopwatch VisitVariable = new Stopwatch(); - private static Stopwatch CommonVisit = new Stopwatch(); - private static Stopwatch FindDeclarationScope = new Stopwatch(); - private static Stopwatch FindDeclarationsFromObject = new Stopwatch(); - private static Stopwatch FindDeclarations = new Stopwatch(); - private static Stopwatch ProcessMethodInvocation = new Stopwatch(); - private static Stopwatch CheckNameConflict = new Stopwatch(); - private static Stopwatch HasExternQualifier = new Stopwatch(); - - private static int VisitVariableCount = 0; - private static int CommonVisitCount = 0; - private static int FindDeclarationScopeCount = 0; - private static int FindDeclarationsFromObjectCount = 0; - private static int FindDeclarationsCount = 0; - private static int ProcessMethodInvocationCount = 0; - private static int CheckNameConflictCount = 0; - private static int HasExternQualifierCount = 0; - - private static int nbShaders = 0; - - public static void Start(SemanticStage stage) - { - switch (stage) - { - case SemanticStage.Global: - TotalTime.Start(); - break; - case SemanticStage.VisitVariable: - VisitVariable.Start(); - ++VisitVariableCount; - break; - case SemanticStage.CommonVisit: - CommonVisit.Start(); - ++CommonVisitCount; - break; - case SemanticStage.FindDeclarationScope: - FindDeclarationScope.Start(); - ++FindDeclarationScopeCount; - break; - case SemanticStage.FindDeclarationsFromObject: - FindDeclarationsFromObject.Start(); - ++FindDeclarationsFromObjectCount; - break; - case SemanticStage.FindDeclarations: - FindDeclarations.Start(); - ++FindDeclarationsCount; - break; - case SemanticStage.ProcessMethodInvocation: - ProcessMethodInvocation.Start(); - ++ProcessMethodInvocationCount; - break; - case SemanticStage.CheckNameConflict: - CheckNameConflict.Start(); - ++CheckNameConflictCount; - break; - case SemanticStage.HasExternQualifier: - HasExternQualifier.Start(); - ++HasExternQualifierCount; - break; - } - } - - public static void Pause(SemanticStage stage) - { - switch (stage) - { - case SemanticStage.Global: - TotalTime.Stop(); - break; - case SemanticStage.VisitVariable: - VisitVariable.Stop(); - break; - case SemanticStage.CommonVisit: - CommonVisit.Stop(); - break; - case SemanticStage.FindDeclarationScope: - FindDeclarationScope.Stop(); - break; - case SemanticStage.FindDeclarationsFromObject: - FindDeclarationsFromObject.Stop(); - break; - case SemanticStage.FindDeclarations: - FindDeclarations.Stop(); - break; - case SemanticStage.ProcessMethodInvocation: - ProcessMethodInvocation.Stop(); - break; - case SemanticStage.CheckNameConflict: - CheckNameConflict.Stop(); - break; - case SemanticStage.HasExternQualifier: - HasExternQualifier.Stop(); - break; - } - } - - public static void IncrShader() - { - ++nbShaders; - } - - public static void Reset() - { - nbShaders = 0; - - TotalTime.Reset(); - VisitVariable.Reset(); - CommonVisit.Reset(); - FindDeclarationScope.Reset(); - FindDeclarationsFromObject.Reset(); - FindDeclarations.Reset(); - ProcessMethodInvocation.Reset(); - CheckNameConflict.Reset(); - HasExternQualifier.Reset(); - - VisitVariableCount = 0; - CommonVisitCount = 0; - FindDeclarationScopeCount = 0; - FindDeclarationsFromObjectCount = 0; - FindDeclarationsCount = 0; - ProcessMethodInvocationCount = 0; - CheckNameConflictCount = 0; - HasExternQualifierCount = 0; - } - - public static void PrintResult() - { - Logger.Info(@"--------------------------TOTAL SEMANTIC ANALYZER---------------------------"); - Logger.Info($"{nbShaders} shader(s) analyzed in {TotalTime.ElapsedMilliseconds} ms, {(nbShaders == 0 ? 0 : TotalTime.ElapsedMilliseconds / nbShaders)} ms per shader"); - Logger.Info($"VisitVariable {VisitVariable.ElapsedMilliseconds} ms for {VisitVariableCount} calls"); - Logger.Info($"CommonVisit took {CommonVisit.ElapsedMilliseconds} ms for {CommonVisitCount} calls"); - Logger.Info($"FindDeclarationScope took {FindDeclarationScope.ElapsedMilliseconds} ms for {FindDeclarationScopeCount} calls"); - Logger.Info($"FindDeclarationsFromObject took {FindDeclarationsFromObject.ElapsedMilliseconds} ms for {FindDeclarationsFromObjectCount} calls"); - Logger.Info($"FindDeclarations took {FindDeclarations.ElapsedMilliseconds} ms for {FindDeclarationsCount} calls"); - Logger.Info($"ProcessMethodInvocation took {ProcessMethodInvocation.ElapsedMilliseconds} ms for {ProcessMethodInvocationCount} calls"); - Logger.Info($"CheckNameConflict took {CheckNameConflict.ElapsedMilliseconds} ms for {CheckNameConflictCount} calls"); - Logger.Info($"HasExternQualifier took {HasExternQualifier.ElapsedMilliseconds} ms for {HasExternQualifierCount} calls"); - Logger.Info(@"-------------------------------------------------------------------------------"); - } - } - - public enum SemanticStage - { - Global, - VisitVariable, - CommonVisit, - FindDeclarationScope, - FindDeclarationsFromObject, - FindDeclarations, - ProcessMethodInvocation, - CheckNameConflict, - HasExternQualifier - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Performance/StreamCreatorPerformance.cs b/sources/engine/Stride.Shaders.Parser/Performance/StreamCreatorPerformance.cs deleted file mode 100644 index 6a7c77e075..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Performance/StreamCreatorPerformance.cs +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Diagnostics; -using Stride.Core.Diagnostics; - -namespace Stride.Shaders.Parser.Performance -{ - public static class StreamCreatorPerformance - { - internal static Logger Logger = GlobalLogger.GetLogger("StrideShaderPerformance"); // Global logger for shader profiling - - private static Stopwatch Global = new Stopwatch(); - private static Stopwatch StreamAnalyzer = new Stopwatch(); - private static Stopwatch FindEntryPoint = new Stopwatch(); - private static Stopwatch StreamAnalysisPerShader = new Stopwatch(); - private static Stopwatch BubbleUpStreamUsages = new Stopwatch(); - private static Stopwatch ComputeShaderStreamAnalysis = new Stopwatch(); - private static Stopwatch TagCleaner = new Stopwatch(); - private static Stopwatch GenerateStreams = new Stopwatch(); - private static Stopwatch RemoveUselessAndSortMethods = new Stopwatch(); - private static Stopwatch PropagateStreamsParameter = new Stopwatch(); - private static Stopwatch TransformStreamsAssignments = new Stopwatch(); - private static Stopwatch AssignSearch = new Stopwatch(); - private static Stopwatch CreateOutputFromStream = new Stopwatch(); - private static Stopwatch CreateStreamFromInput = new Stopwatch(); - private static Stopwatch StreamFieldVisitor = new Stopwatch(); - private static Stopwatch StreamFieldVisitorClone = new Stopwatch(); - - private static int StreamFieldVisitorCount; - - public static void Start(StreamCreatorStage stage) - { - switch (stage) - { - case StreamCreatorStage.Global: - Global.Start(); - break; - case StreamCreatorStage.StreamAnalyzer: - StreamAnalyzer.Start(); - break; - case StreamCreatorStage.FindEntryPoint: - FindEntryPoint.Start(); - break; - case StreamCreatorStage.StreamAnalysisPerShader: - StreamAnalysisPerShader.Start(); - break; - case StreamCreatorStage.BubbleUpStreamUsages: - BubbleUpStreamUsages.Start(); - break; - case StreamCreatorStage.ComputeShaderStreamAnalysis: - ComputeShaderStreamAnalysis.Start(); - break; - case StreamCreatorStage.TagCleaner: - TagCleaner.Start(); - break; - case StreamCreatorStage.GenerateStreams: - GenerateStreams.Start(); - break; - case StreamCreatorStage.RemoveUselessAndSortMethods: - RemoveUselessAndSortMethods.Start(); - break; - case StreamCreatorStage.PropagateStreamsParameter: - PropagateStreamsParameter.Start(); - break; - case StreamCreatorStage.TransformStreamsAssignments: - TransformStreamsAssignments.Start(); - break; - case StreamCreatorStage.AssignSearch: - AssignSearch.Start(); - break; - case StreamCreatorStage.CreateOutputFromStream: - CreateOutputFromStream.Start(); - break; - case StreamCreatorStage.CreateStreamFromInput: - CreateStreamFromInput.Start(); - break; - case StreamCreatorStage.StreamFieldVisitor: - StreamFieldVisitor.Start(); - ++StreamFieldVisitorCount; - break; - case StreamCreatorStage.StreamFieldVisitorClone: - StreamFieldVisitorClone.Start(); - break; - } - } - - public static void Pause(StreamCreatorStage stage) - { - switch (stage) - { - case StreamCreatorStage.Global: - Global.Stop(); - break; - case StreamCreatorStage.StreamAnalyzer: - StreamAnalyzer.Stop(); - break; - case StreamCreatorStage.FindEntryPoint: - FindEntryPoint.Stop(); - break; - case StreamCreatorStage.StreamAnalysisPerShader: - StreamAnalysisPerShader.Stop(); - break; - case StreamCreatorStage.BubbleUpStreamUsages: - BubbleUpStreamUsages.Stop(); - break; - case StreamCreatorStage.ComputeShaderStreamAnalysis: - ComputeShaderStreamAnalysis.Stop(); - break; - case StreamCreatorStage.TagCleaner: - TagCleaner.Stop(); - break; - case StreamCreatorStage.GenerateStreams: - GenerateStreams.Stop(); - break; - case StreamCreatorStage.RemoveUselessAndSortMethods: - RemoveUselessAndSortMethods.Stop(); - break; - case StreamCreatorStage.PropagateStreamsParameter: - PropagateStreamsParameter.Stop(); - break; - case StreamCreatorStage.TransformStreamsAssignments: - TransformStreamsAssignments.Stop(); - break; - case StreamCreatorStage.AssignSearch: - AssignSearch.Stop(); - break; - case StreamCreatorStage.CreateOutputFromStream: - CreateOutputFromStream.Stop(); - break; - case StreamCreatorStage.CreateStreamFromInput: - CreateStreamFromInput.Stop(); - break; - case StreamCreatorStage.StreamFieldVisitor: - StreamFieldVisitor.Stop(); - break; - case StreamCreatorStage.StreamFieldVisitorClone: - StreamFieldVisitorClone.Stop(); - break; - } - } - - public static void Reset() - { - Global.Reset(); - StreamAnalyzer.Reset(); - FindEntryPoint.Reset(); - StreamAnalysisPerShader.Reset(); - BubbleUpStreamUsages.Reset(); - ComputeShaderStreamAnalysis.Reset(); - TagCleaner.Reset(); - GenerateStreams.Reset(); - RemoveUselessAndSortMethods.Reset(); - PropagateStreamsParameter.Reset(); - TransformStreamsAssignments.Reset(); - AssignSearch.Reset(); - CreateOutputFromStream.Reset(); - CreateStreamFromInput.Reset(); - StreamFieldVisitor.Reset(); - StreamFieldVisitorClone.Reset(); - - StreamFieldVisitorCount = 0; - } - - public static void PrintResult() - { - Logger.Info(@"----------------------------STREAM CREATOR ANALYZER-----------------------------"); - Logger.Info($"Stream creation took {Global.ElapsedMilliseconds} ms"); - Logger.Info($"StreamAnalyzer took {StreamAnalyzer.ElapsedMilliseconds} ms"); - Logger.Info($"FindEntryPoint took {FindEntryPoint.ElapsedMilliseconds} ms"); - Logger.Info($"StreamAnalysisPerShader took {StreamAnalysisPerShader.ElapsedMilliseconds} ms"); - Logger.Info($"BubbleUpStreamUsages took {BubbleUpStreamUsages.ElapsedMilliseconds} ms"); - Logger.Info($"ComputeShaderStreamAnalysis took {ComputeShaderStreamAnalysis.ElapsedMilliseconds} ms"); - Logger.Info($"TagCleaner took {TagCleaner.ElapsedMilliseconds} ms"); - Logger.Info($"GenerateStreams took {GenerateStreams.ElapsedMilliseconds} ms"); - Logger.Info($"RemoveUselessAndSortMethods took {RemoveUselessAndSortMethods.ElapsedMilliseconds} ms"); - Logger.Info($"PropagateStreamsParameter took {PropagateStreamsParameter.ElapsedMilliseconds} ms"); - Logger.Info($"TransformStreamsAssignments took {TransformStreamsAssignments.ElapsedMilliseconds} ms"); - Logger.Info($"AssignSearch took {AssignSearch.ElapsedMilliseconds} ms"); - Logger.Info($"CreateOutputFromStream took {CreateOutputFromStream.ElapsedMilliseconds} ms"); - Logger.Info($"CreateStreamFromInput took {CreateStreamFromInput.ElapsedMilliseconds} ms"); - Logger.Info($"StreamFieldVisitor took {StreamFieldVisitor.ElapsedMilliseconds} ms for {StreamFieldVisitorCount} calls"); - Logger.Info($"StreamFieldVisitorClone took {StreamFieldVisitorClone.ElapsedMilliseconds} ms"); - Logger.Info(@"-------------------------------------------------------------------------------"); - } - } - - public enum StreamCreatorStage - { - Global, - StreamAnalyzer, - FindEntryPoint, - StreamAnalysisPerShader, - BubbleUpStreamUsages, - ComputeShaderStreamAnalysis, - TagCleaner, - GenerateStreams, - RemoveUselessAndSortMethods, - PropagateStreamsParameter, - TransformStreamsAssignments, - AssignSearch, - CreateOutputFromStream, - CreateStreamFromInput, - StreamFieldVisitor, - StreamFieldVisitorClone - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Properties/AssemblyInfo.cs b/sources/engine/Stride.Shaders.Parser/Properties/AssemblyInfo.cs deleted file mode 100644 index 07ffef6d0f..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Reflection; -using System.Runtime.CompilerServices; - - -#pragma warning disable 436 // Stride.PublicKeys is defined in multiple assemblies - -[assembly: InternalsVisibleTo("Stride.Shaders.Parser.Serializers" + Stride.PublicKeys.Default)] -//[assembly: InternalsVisibleTo("Stride.Shaders.Tests" + Stride.PublicKeys.Default)] -[assembly: InternalsVisibleTo("Stride.Engine" + Stride.PublicKeys.Default)] diff --git a/sources/engine/Stride.Shaders.Parser/ShaderExtensions.cs b/sources/engine/Stride.Shaders.Parser/ShaderExtensions.cs deleted file mode 100644 index 776414247f..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderExtensions.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; - -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Convertor; - -namespace Stride.Shaders.Parser -{ - public static class ShaderExtensions - { - // Used as key tag on TypeBase to link it to its actual ShaderClassType (if specified by user) - internal static string associatedClass = "AssociatedClass"; - // Used as key tag on ShaderRootClassType to define its composition types - internal static string associatedCompositions = "AssociatedCompositions"; - // Used as key tag on TypeBase to link it to its actual ShaderClassType (if specified by user) - public static readonly string AssociatedMacrosTag = "AssociatedMacros"; - - public static void ReplaceAnnotation(this IAttributes node, string name, params object[] values) - { - foreach (var annotation in node.Attributes.OfType()) - { - if (annotation.Name == name && annotation.Parameters.Count >= 1) - { - annotation.Parameters = values.Select(x => new Literal(x)).ToList(); - return; - } - } - node.Attributes.Add(new AttributeDeclaration { Name = new Identifier(name), Parameters = values.Select(x => new Literal(x)).ToList() }); - } - - public static ShaderRootClassType GetMainShaderClass(this Shader shader) - { - var defaultShader = shader.Declarations.OfType().FirstOrDefault(x => x.Name == "Shader"); - if (defaultShader == null) - { - defaultShader = new ShaderRootClassType("Shader"); - shader.Declarations.Add(defaultShader); - } - return defaultShader; - } - - public static ShaderRootClassType StartMix() - { - // TODO: Rename during Shader mixing - return new ShaderRootClassType("Mix"); - } - - public static ShaderRootClassType Mix(this Shader shader, TypeBase mixinClass) - { - // Find the shader class which will drive compilation and add this new mixinClass in the list. - var mainShaderClass = shader.GetMainShaderClass(); - mainShaderClass.Mix(mixinClass); - - return mainShaderClass; - } - - public static ShaderRootClassType Mix(this ShaderRootClassType target, TypeBase mixinClass) - { - var typeName = new TypeName(mixinClass.Name); - if (mixinClass is ShaderClassType) - typeName.SetTag(associatedClass, mixinClass); - target.BaseClasses.Add(typeName); - - return target; - } - - public static ShaderRootClassType Compose(this ShaderRootClassType sourceClass, string variableName, params ShaderClassType[] variableTypes) - { - var currentVariableTypes = (Dictionary)sourceClass.GetTag(associatedCompositions); - if (currentVariableTypes == null) - { - currentVariableTypes = new Dictionary(); - sourceClass.SetTag(associatedCompositions, currentVariableTypes); - } - - currentVariableTypes[variableName] = variableTypes; - - return sourceClass; - } - - private class NameEqualityComparer : IEqualityComparer - { - public bool Equals(IDeclaration x, IDeclaration y) - { - return x.Name == y.Name; - } - - public int GetHashCode(IDeclaration obj) - { - return obj.Name.GetHashCode(); - } - } - - public static MethodDefinition GetEntryPoint(this Shader shader, ShaderStage type) - { - return shader.Declarations.OfType().FirstOrDefault(f => f.Attributes.OfType().Any(a => a.Name == "EntryPoint" && (string)a.Parameters[0].Value == type.ToString())); - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/ShaderLinker.cs b/sources/engine/Stride.Shaders.Parser/ShaderLinker.cs deleted file mode 100644 index da40a601fb..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderLinker.cs +++ /dev/null @@ -1,1057 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; - -using Stride.Core.Mathematics; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Mixins; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Visitor; -using Stride.Graphics; - -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; -using HlslStorageQualifier = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; -using Half = Stride.Core.Mathematics.Half; - -namespace Stride.Shaders.Parser -{ - /// - /// This AST Visitor will look for any "Link" annotation in order to bind EffectVariable to their associated HLSL variables. - /// - internal class ShaderLinker : ShaderWalker - { - private readonly Dictionary samplers = new Dictionary(); - private readonly EffectReflection effectReflection; - private readonly Dictionary> valueBindings = new Dictionary>(); - private readonly ShaderMixinParsingResult parsingResult; - - /// - /// Initializes a new instance of the class. - /// - /// The parsing result. - public ShaderLinker(ShaderMixinParsingResult parsingResult) - : base(true, false) - { - this.parsingResult = parsingResult; - this.effectReflection = parsingResult.Reflection; - } - - /// - /// Gets the samplers. - /// - public IDictionary Samplers - { - get - { - return samplers; - } - } - - /// - /// Runs the linker on the specified Shader. - /// - /// The shader. - public void Run(Shader shader) - { - PrepareConstantBuffers(shader); - Visit(shader); - foreach (var valueBinding in valueBindings) - { - valueBinding.Key.Members = valueBinding.Value.ToArray(); - } - } - - private void PrepareConstantBuffers(Shader shader) - { - var otherNodes = shader.Declarations.Where(declaration => !(declaration is MethodDeclaration) && !(declaration is Variable)); - // Note: flattening variables - var variables = shader.Declarations.OfType().SelectMany(x => x.Instances()).ToList(); - - var declarations = new List(); - - // Reorder: - // - Constants (might be needed by struct/typedef) - declarations.AddRange(variables.Where(x => x.Qualifiers.Contains(StorageQualifier.Const))); - // - Non variable/methods (i.e. struct, typedef, cbuffer, etc...) - declarations.AddRange(otherNodes); - // - Variables (textures, samplers, etc...) - declarations.AddRange(variables.Where(x => !x.Qualifiers.Contains(StorageQualifier.Const))); - // - Method declarations - declarations.AddRange(shader.Declarations.OfType()); - - shader.Declarations = declarations; - } - - - /// - /// Visits the specified variable. - /// - /// The variable. - /// The variable visited - public override void Visit(Variable variable) - { - var parameterKey = GetLinkParameterKey(variable); - if (parameterKey == null) return; - - var resolvedType = variable.Type.ResolveType(); - var slotCount = 1; - if (resolvedType is ArrayType) - { - // TODO: Use evaluator? - slotCount = (int)((LiteralExpression)((ArrayType)resolvedType).Dimensions[0]).Literal.Value; - resolvedType = ((ArrayType)resolvedType).Type; - } - if (resolvedType.IsStateType()) - { - var samplerState = SamplerStateDescription.Default; - - var stateInitializer = variable.InitialValue as StateInitializer; - if (stateInitializer != null) - { - foreach (var samplerField in stateInitializer.Items.OfType()) - { - string key = samplerField.Target.ToString(); - string value = samplerField.Value.ToString(); - - if (key == "Filter") - { - switch (value) - { - case "COMPARISON_MIN_MAG_LINEAR_MIP_POINT": - samplerState.Filter = TextureFilter.ComparisonMinMagLinearMipPoint; - break; - case "COMPARISON_MIN_MAG_MIP_POINT": - samplerState.Filter = TextureFilter.ComparisonPoint; - break; - case "MIN_MAG_LINEAR_MIP_POINT": - samplerState.Filter = TextureFilter.MinMagLinearMipPoint; - break; - case "MIN_MAG_MIP_LINEAR": - samplerState.Filter = TextureFilter.Linear; - break; - case "ANISOTROPIC": - samplerState.Filter = TextureFilter.Anisotropic; - break; - case "MIN_MAG_MIP_POINT": - samplerState.Filter = TextureFilter.Point; - break; - default: - parsingResult.Error(StrideMessageCode.SamplerFilterNotSupported, variable.Span, value); - break; - } - } - else if (key == "ComparisonFunc") - { - CompareFunction compareFunction; - Enum.TryParse(value, true, out compareFunction); - samplerState.CompareFunction = compareFunction; - } - else if (key == "AddressU" || key == "AddressV" || key == "AddressW") - { - TextureAddressMode textureAddressMode; - Enum.TryParse(value, true, out textureAddressMode); - switch (key) - { - case "AddressU": - samplerState.AddressU = textureAddressMode; - break; - case "AddressV": - samplerState.AddressV = textureAddressMode; - break; - case "AddressW": - samplerState.AddressW = textureAddressMode; - break; - default: - parsingResult.Error(StrideMessageCode.SamplerAddressModeNotSupported, variable.Span, key); - break; - } - } - else if (key == "BorderColor") - { - var borderColor = samplerField.Value as MethodInvocationExpression; - if (borderColor != null) - { - var targetType = borderColor.Target as TypeReferenceExpression; - if (targetType != null && targetType.Type.ResolveType() == VectorType.Float4 && borderColor.Arguments.Count == 4) - { - var values = new float[4]; - for (int i = 0; i < 4; i++) - { - var argValue = borderColor.Arguments[i] as LiteralExpression; - if (argValue != null) - { - values[i] = (float)Convert.ChangeType(argValue.Value, typeof(float)); - } - else - { - parsingResult.Error(StrideMessageCode.SamplerBorderColorNotSupported, variable.Span, borderColor.Arguments[i]); - } - } - - samplerState.BorderColor = new Color4(values); - } - else - { - parsingResult.Error(StrideMessageCode.SamplerBorderColorNotSupported, variable.Span, variable); - } - } - else - { - parsingResult.Error(StrideMessageCode.SamplerBorderColorNotSupported, variable.Span, variable); - } - } - else if (key == "MinLOD") - { - samplerState.MinMipLevel = float.Parse(value); - } - else if (key == "MaxLOD") - { - samplerState.MaxMipLevel = float.Parse(value); - } - else if (key == "MaxAnisotropy") - { - samplerState.MaxAnisotropy = int.Parse(value); - } - else - { - parsingResult.Error(StrideMessageCode.SamplerFieldNotSupported, variable.Span, variable); - } - } - - effectReflection.SamplerStates.Add(new EffectSamplerStateBinding(parameterKey.Name, samplerState)); - } - - LinkVariable(effectReflection, variable.Name, parameterKey, slotCount); - } - else if (variable.Type is TextureType || variable.Type is GenericBaseType || variable.Type.IsByteAddressBufferType()) - { - LinkVariable(effectReflection, variable.Name, parameterKey, slotCount); - } - else - { - ParseConstantBufferVariable("$Globals", variable); - } - } - - /// - /// Visits the specified constant buffer. - /// - /// The constant buffer. - /// - public override void Visit(ConstantBuffer constantBuffer) - { - foreach (var variable in constantBuffer.Members.OfType().SelectMany(x => x.Instances())) - { - ParseConstantBufferVariable(constantBuffer.Name, variable); - } - } - - public override void Visit(MethodDefinition method) - { - // Parse stream output declarations (if any) - // TODO: Currently done twice, one time in ShaderMixer, one time in ShaderLinker - var streamOutputAttribute = method.Attributes.OfType().FirstOrDefault(x => x.Name == "StreamOutput"); - if (streamOutputAttribute != null) - { - var rasterizedStream = streamOutputAttribute.Parameters.LastOrDefault(); - - // Ignore last parameter if it's not an integer (it means there is no rasterized stream info) - // We should make a new StreamOutputRasterizedStream attribute instead maybe? - if (rasterizedStream != null && !(rasterizedStream.Value is int)) - rasterizedStream = null; - - int[] streamOutputStrides; - - // Parse declarations - // Everything should be registered in GS_OUTPUT (previous pass in ShaderMixer). - StreamOutputParser.Parse(effectReflection.ShaderStreamOutputDeclarations, out streamOutputStrides, streamOutputAttribute, ((StructType)FindDeclaration("GS_OUTPUT")).Fields); - - effectReflection.StreamOutputStrides = streamOutputStrides; - effectReflection.StreamOutputRasterizedStream = rasterizedStream != null ? (int)rasterizedStream.Value : -1; - } - } - - /// - public override void VisitNode(Node node) - { - if (node is IDeclaration) - { - var parameterKey = this.GetLinkParameterKey(node); - if (parameterKey != null) - LinkVariable(effectReflection, ((IDeclaration)node).Name, parameterKey, parameterKey.Type.Elements); - } - - base.VisitNode(node); - } - - private LocalParameterKey GetLinkParameterKey(Node node) - { - var qualifiers = node as IQualifiers; - - if ((qualifiers is not null && - (qualifiers.Qualifiers.Contains(HlslStorageQualifier.Static) || - qualifiers.Qualifiers.Contains(StorageQualifier.Const) || - qualifiers.Qualifiers.Contains(StorageQualifier.GroupShared))) || - node is not IAttributes attributable) - { - return null; - } - - foreach (var annotation in attributable.Attributes.OfType()) - { - if (annotation.Name != "Link" || annotation.Parameters.Count < 1) - { - continue; - } - - var variableName = (string)annotation.Parameters[0].Value; - var parameterKey = new LocalParameterKey() {Name = variableName}; - var variable = node as Variable; - if (variable != null) - { - var cbuffer = (ConstantBuffer)variable.GetTag(StrideTags.ConstantBuffer); - if (cbuffer != null && cbuffer.Type == StrideConstantBufferType.ResourceGroup) - { - parameterKey.ResourceGroup = cbuffer.Name; - } - - parameterKey.LogicalGroup = (string)variable.GetTag(StrideTags.LogicalGroup); - - var variableType = variable.Type; - - parameterKey.Type = CreateTypeInfo(variableType, attributable.Attributes, out parameterKey.ElementType); - } - - return parameterKey; - } - - return null; - } - - private static EffectTypeDescription CreateTypeInfo(TypeBase variableType, List attributes, out EffectTypeDescription elementType) - { - elementType = default; - - var parameterTypeInfo = new EffectTypeDescription(); - - if (variableType.TypeInference.TargetType != null) - variableType = variableType.TypeInference.TargetType; - - if (variableType is ArrayType) - { - var arrayType = (ArrayType)variableType; - variableType = arrayType.Type; - parameterTypeInfo.Elements = (int)((LiteralExpression)arrayType.Dimensions[0]).Literal.Value; - - if (variableType.TypeInference.TargetType != null) - variableType = variableType.TypeInference.TargetType; - } - - if (variableType is ScalarType) - { - if (variableType == ScalarType.Int) - { - parameterTypeInfo.Class = EffectParameterClass.Scalar; - parameterTypeInfo.Type = EffectParameterType.Int; - } - else if (variableType == ScalarType.UInt) - { - parameterTypeInfo.Class = EffectParameterClass.Scalar; - parameterTypeInfo.Type = EffectParameterType.UInt; - } - else if (variableType == ScalarType.Float) - { - parameterTypeInfo.Class = EffectParameterClass.Scalar; - parameterTypeInfo.Type = EffectParameterType.Float; - } - else if (variableType == ScalarType.Double) - { - parameterTypeInfo.Class = EffectParameterClass.Scalar; - parameterTypeInfo.Type = EffectParameterType.Double; - } - else if (variableType == ScalarType.Bool) - { - parameterTypeInfo.Class = EffectParameterClass.Scalar; - parameterTypeInfo.Type = EffectParameterType.Bool; - } - - parameterTypeInfo.RowCount = 1; - parameterTypeInfo.ColumnCount = 1; - } - else if (variableType is VectorType vectorType) - { - if (vectorType.Type == ScalarType.Float) - { - bool isColor = attributes.OfType().Any(x => x.Name == "Color"); - parameterTypeInfo.Class = isColor ? EffectParameterClass.Color : EffectParameterClass.Vector; - parameterTypeInfo.Type = EffectParameterType.Float; - } - else if (vectorType.Type == ScalarType.Double) - { - parameterTypeInfo.Class = EffectParameterClass.Vector; - parameterTypeInfo.Type = EffectParameterType.Double; - } - else if (vectorType.Type == ScalarType.Int) - { - parameterTypeInfo.Class = EffectParameterClass.Vector; - parameterTypeInfo.Type = EffectParameterType.Int; - } - else if (vectorType.Type == ScalarType.UInt) - { - parameterTypeInfo.Class = EffectParameterClass.Vector; - parameterTypeInfo.Type = EffectParameterType.UInt; - } - - parameterTypeInfo.RowCount = 1; - parameterTypeInfo.ColumnCount = ((VectorType)variableType).Dimension; - } - else if (variableType is MatrixType) - { - parameterTypeInfo.Class = EffectParameterClass.MatrixColumns; - parameterTypeInfo.Type = EffectParameterType.Float; - parameterTypeInfo.RowCount = ((MatrixType)variableType).RowCount; - parameterTypeInfo.ColumnCount = ((MatrixType)variableType).ColumnCount; - } - else if (variableType is StructType) - { - var structType = (StructType)variableType; - - parameterTypeInfo.Class = EffectParameterClass.Struct; - parameterTypeInfo.RowCount = 1; - parameterTypeInfo.ColumnCount = 1; - parameterTypeInfo.Name = structType.Name.Text; - - var members = new List(); - foreach (var field in structType.Fields) - { - var memberInfo = new EffectTypeMemberDescription - { - Name = field.Name.Text, - Type = CreateTypeInfo(field.Type, field.Attributes, out var _), - }; - members.Add(memberInfo); - } - - parameterTypeInfo.Members = members.ToArray(); - } - else - { - var variableTypeName = variableType.Name.Text.ToLowerInvariant(); - - if (variableType is ClassType classType && classType.GenericArguments.Count == 1) - { - elementType = CreateTypeInfo(classType.GenericArguments[0], new List(), out var _); - } - - switch (variableTypeName) - { - case "cbuffer": - parameterTypeInfo.Class = EffectParameterClass.ConstantBuffer; - parameterTypeInfo.Type = EffectParameterType.ConstantBuffer; - break; - - case "tbuffer": - parameterTypeInfo.Class = EffectParameterClass.TextureBuffer; - parameterTypeInfo.Type = EffectParameterType.TextureBuffer; - break; - - case "structuredbuffer": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.StructuredBuffer; - break; - case "rwstructuredbuffer": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWStructuredBuffer; - break; - case "consumestructuredbuffer": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.ConsumeStructuredBuffer; - break; - case "appendstructuredbuffer": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.AppendStructuredBuffer; - break; - case "buffer": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Buffer; - break; - case "rwbuffer": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWBuffer; - break; - case "byteaddressbuffer": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.ByteAddressBuffer; - break; - case "rwbyteaddressbuffer": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWByteAddressBuffer; - break; - - case "texture1d": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture1D; - break; - - case "texturecube": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.TextureCube; - break; - - case "texture2d": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture2D; - break; - - case "texture2dms": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture2DMultisampled; - break; - - case "texture3d": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture3D; - break; - - case "texture1darray": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture1DArray; - break; - - case "texturecubearray": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.TextureCubeArray; - break; - - case "texture2darray": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture2DArray; - break; - - case "texture2dmsarray": - parameterTypeInfo.Class = EffectParameterClass.ShaderResourceView; - parameterTypeInfo.Type = EffectParameterType.Texture2DMultisampledArray; - break; - - case "rwtexture1d": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWTexture1D; - break; - - case "rwtexture2d": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWTexture2D; - break; - - case "rwtexture3d": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWTexture3D; - break; - - case "rwtexture1darray": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWTexture1DArray; - break; - - case "rwtexture2darray": - parameterTypeInfo.Class = EffectParameterClass.UnorderedAccessView; - parameterTypeInfo.Type = EffectParameterType.RWTexture2DArray; - break; - - case "samplerstate": - case "samplercomparisonstate": - parameterTypeInfo.Class = EffectParameterClass.Sampler; - parameterTypeInfo.Type = EffectParameterType.Sampler; - break; - } - } - - return parameterTypeInfo; - } - - private int ComputeSize(TypeBase type) - { - if (type.TypeInference.TargetType != null) - type = type.TypeInference.TargetType; - - var structType = type as StructType; - if (structType != null) - { - var structSize = 0; - foreach (var field in structType.Fields) - { - var memberSize = ComputeSize(field.Type); - - // Seems like this element needs to be split accross multiple lines, - if ((structSize + memberSize - 1) / 16 != structSize / 16) - structSize = (structSize + 16 - 1) / 16 * 16; - - structSize += memberSize; - } - return structSize; - } - - if (type is ScalarType) - { - // Uint and int are collapsed to int - if (type == ScalarType.Int || type == ScalarType.UInt - || type == ScalarType.Float || type == ScalarType.Bool) - { - return 4; - } - else if (type == ScalarType.Double) - { - return 8; - } - else - { - throw new NotImplementedException(); - } - } - - var vectorType = type as VectorType; - if (vectorType != null) - { - return ComputeSize(vectorType.Type) * vectorType.Dimension; - } - - var matrixType = type as MatrixType; - if (matrixType is MatrixType) - { - return (4 * (matrixType.ColumnCount - 1) + matrixType.RowCount); - } - - throw new NotImplementedException(); - } - - private void ParseConstantBufferVariable(string cbName, Variable variable) - { - if (variable.Qualifiers.Contains(HlslStorageQualifier.Static) || - variable.Qualifiers.Contains(StorageQualifier.Const) || - variable.Qualifiers.Contains(StorageQualifier.GroupShared)) - { - return; - } - - if (variable.Qualifiers.Contains(StrideStorageQualifier.Stream)) - { - parsingResult.Error(StrideMessageCode.StreamVariableWithoutPrefix, variable.Span, variable); - return; - } - - foreach (var attribute in variable.Attributes.OfType()) - { - if (attribute.Name == "Link") - { - if (attribute.Parameters.Count != 1) - { - parsingResult.Error(StrideMessageCode.LinkArgumentsError, variable.Span); - } - } - } - - //// Try to resolve key - var parameterKey = GetLinkParameterKey(variable); - - if (parameterKey != null) - { - LinkConstant(cbName, variable, parameterKey); - } - else - { - parsingResult.Error(StrideMessageCode.LinkError, variable.Span, variable); - } - } - - private static void LinkVariable(EffectReflection reflection, string variableName, LocalParameterKey parameterKey, int slotCount) - { - var binding = new EffectResourceBindingDescription { KeyInfo = { KeyName = parameterKey.Name }, Class = parameterKey.Type.Class, Type = parameterKey.Type.Type, ElementType = parameterKey.ElementType, RawName = variableName, SlotStart = -1, SlotCount = slotCount > 0 ? slotCount : 1, ResourceGroup = parameterKey.ResourceGroup, LogicalGroup = parameterKey.LogicalGroup }; - reflection.ResourceBindings.Add(binding); - } - - private void LinkConstant(string cbName, Variable variable, LocalParameterKey parameterKey) - { - // If the constant buffer is not present, add it - var constantBuffer = effectReflection.ConstantBuffers.FirstOrDefault(buffer => buffer.Name == cbName); - if (constantBuffer == null) - { - constantBuffer = new EffectConstantBufferDescription() {Name = cbName, Type = ConstantBufferType.ConstantBuffer}; - effectReflection.ConstantBuffers.Add(constantBuffer); - var constantBufferBinding = new EffectResourceBindingDescription { KeyInfo = { KeyName = cbName }, Class = EffectParameterClass.ConstantBuffer, Type = EffectParameterType.ConstantBuffer, RawName = cbName, SlotStart = -1, SlotCount = 1, ResourceGroup = cbName }; - effectReflection.ResourceBindings.Add(constantBufferBinding); - valueBindings.Add(constantBuffer, new List()); - } - - // Get the list of members of this constant buffer - var members = valueBindings[constantBuffer]; - - var binding = new EffectValueDescription - { - KeyInfo = - { - KeyName = parameterKey.Name, - }, - LogicalGroup = (string)variable.GetTag(StrideTags.LogicalGroup), - Type = parameterKey.Type, - RawName = variable.Name, - DefaultValue = ParseDefaultValue(variable), - }; - - members.Add(binding); - } - - private object ParseDefaultValue(Variable variable) - { - var initialValue = variable.InitialValue; - if (initialValue is null) - return default; - - var parameterType = variable.Type.ResolveType(); - if (parameterType is ScalarType scalarType) - { - if (scalarType == ScalarType.Bool) - return ValueParsing.ToScalar(initialValue); - else if (scalarType == ScalarType.Float) - return ValueParsing.ToScalar(initialValue); - else if (scalarType == ScalarType.Double) - return ValueParsing.ToScalar(initialValue); - else if (scalarType == ScalarType.Half) - return ValueParsing.ToScalar(initialValue); - else if (scalarType == ScalarType.Int) - return ValueParsing.ToScalar(initialValue); - else if (scalarType == ScalarType.UInt) - return ValueParsing.ToScalar(initialValue); - } - else if (parameterType is VectorType vectorType) - { - var componentType = vectorType.Type; - if (componentType == ScalarType.Float) - { - var isColor = variable.Attributes.OfType().Any(x => x.Name == "Color"); - if (isColor) - return ValueParsing.ToColor(initialValue, vectorType.Dimension); - else - return ValueParsing.ToFloatVector(initialValue, vectorType.Dimension); - } - else if (componentType == ScalarType.Double) - return ValueParsing.ToDoubleVector(initialValue, vectorType.Dimension); - else if (componentType == ScalarType.Half) - return ValueParsing.ToHalfVector(initialValue, vectorType.Dimension); - else if (componentType == ScalarType.Int) - return ValueParsing.ToIntVector(initialValue, vectorType.Dimension); - else if (componentType == ScalarType.UInt) - return ValueParsing.ToUIntVector(initialValue, vectorType.Dimension); - } - else if (parameterType is MatrixType matrixType) - { - var componentType = matrixType.Type; - if (componentType == ScalarType.Float) - { - if (matrixType.RowCount == 4 && matrixType.ColumnCount == 4) - return ValueParsing.ToVector(initialValue, (float[] args) => new Matrix(args)); - } - } - else if (parameterType is ArrayType arrayType) - { - if (initialValue is ArrayInitializerExpression arrayInitializer) - return ValueParsing.ToArray(arrayInitializer.Items, arrayType.Type); - } - - return default; - } - - private class LocalParameterKey - { - public string Name; - - public string ResourceGroup; - - public string LogicalGroup; - - public EffectTypeDescription Type; - - /// - /// The element type (for buffers or textures). - /// - public EffectTypeDescription ElementType; - - /*public EffectParameterClass Class; - - public EffectParameterType Type; - - public int RowCount; - - public int ColumnCount; - - public int Elements; - - public string TypeName; - public EffectParameterTypeInfo[] Members;*/ - } - - private static class ValueParsing - { - public static Array ToArray(List v, TypeBase elementType) - { - if (elementType == ScalarType.Float) - return ToArray(v); - if (elementType == ScalarType.Double) - return ToArray(v); - if (elementType == ScalarType.Half) - return ToArray(v); - if (elementType == ScalarType.Int) - return ToArray(v); - if (elementType == ScalarType.UInt) - return ToArray(v); - if (elementType == ScalarType.Bool) - return ToArray(v); - if (elementType == VectorType.Float2) - return ToArray(v, ToVector2); - if (elementType == VectorType.Float3) - return ToArray(v, ToVector3); - if (elementType == VectorType.Float4) - return ToArray(v, ToVector4); - if (elementType == VectorType.Double2) - return ToArray(v, ToDouble2); - if (elementType == VectorType.Double3) - return ToArray(v, ToDouble3); - if (elementType == VectorType.Double4) - return ToArray(v, ToDouble4); - if (elementType == VectorType.Half2) - return ToArray(v, ToHalf2); - if (elementType == VectorType.Half3) - return ToArray(v, ToHalf3); - if (elementType == VectorType.Half4) - return ToArray(v, ToHalf4); - if (elementType == VectorType.Int2) - return ToArray(v, ToInt2); - if (elementType == VectorType.Int3) - return ToArray(v, ToInt3); - if (elementType == VectorType.Int4) - return ToArray(v, ToInt4); - if (elementType == VectorType.UInt4) - return ToArray(v, ToUInt4); - return default; - } - - static T[] ToArray(List v) - where T : unmanaged - { - var a = new T[v.Count]; - for (int i = 0; i < a.Length; i++) - { - var c = ToScalar(v[i]); - if (c.HasValue) - a[i] = c.Value; - else - return null; - } - return a; - } - - static T[] ToArray(List v, Func factory) - { - var a = new T[v.Count]; - for (int i = 0; i < a.Length; i++) - a[i] = factory(v[i]); - return a; - } - - public static object ToColor(Expression e, int dimension) - { - switch (dimension) - { - case 3: - { - var v = ToVector(e, (float[] args) => new Vector3(args)); - return v.HasValue ? new Color3(v.Value) : null; - } - case 4: - { - var v = ToVector(e, (float[] args) => new Vector4(args)); - return v.HasValue ? new Color4(v.Value) : null; - } - } - return null; - } - - public static object ToFloatVector(Expression e, int dimension) - { - switch (dimension) - { - case 2: - return ToVector2(e); - case 3: - return ToVector3(e); - case 4: - return ToVector4(e); - } - return null; - } - - public static object ToDoubleVector(Expression e, int dimension) - { - switch (dimension) - { - case 2: - return ToDouble2(e); - case 3: - return ToDouble3(e); - case 4: - return ToDouble4(e); - } - return null; - } - - public static object ToHalfVector(Expression e, int dimension) - { - switch (dimension) - { - case 2: - return ToHalf2(e); - case 3: - return ToHalf3(e); - case 4: - return ToHalf4(e); - } - return null; - } - - public static object ToIntVector(Expression e, int dimension) - { - switch (dimension) - { - case 2: - return ToInt2(e); - case 3: - return ToInt3(e); - case 4: - return ToInt4(e); - } - return null; - } - - public static object ToUIntVector(Expression e, int dimension) - { - switch (dimension) - { - case 4: - return ToUInt4(e); - } - return null; - } - - static Vector2? ToVector2(Expression e) => ToVector(e, (float[] args) => new Vector2(args)); - - static Vector3? ToVector3(Expression e) => ToVector(e, (float[] args) => new Vector3(args)); - - static Vector4? ToVector4(Expression e) => ToVector(e, (float[] args) => new Vector4(args)); - - static Double2? ToDouble2(Expression e) => ToVector(e, (double[] args) => new Double2(args)); - - static Double3? ToDouble3(Expression e) => ToVector(e, (double[] args) => new Double3(args)); - - static Double4? ToDouble4(Expression e) => ToVector(e, (double[] args) => new Double4(args)); - - static Half2? ToHalf2(Expression e) => ToVector(e, (Half[] args) => new Half2(args)); - - static Half3? ToHalf3(Expression e) => ToVector(e, (Half[] args) => new Half3(args)); - - static Half4? ToHalf4(Expression e) => ToVector(e, (Half[] args) => new Half4(args)); - - static Int2? ToInt2(Expression e) => ToVector(e, (int[] args) => new Int2(args)); - - static Int3? ToInt3(Expression e) => ToVector(e, (int[] args) => new Int3(args)); - - static Int4? ToInt4(Expression e) => ToVector(e, (int[] args) => new Int4(args)); - - static UInt4? ToUInt4(Expression e) => ToVector(e, (uint[] args) => new UInt4(args)); - - public static TVector? ToVector(Expression e, Func factory) - where TVector : unmanaged - where TComponent : unmanaged - { - if (e is LiteralExpression || e is UnaryExpression) - return ToVector(new List(1) { e }, factory); - else if (e is MethodInvocationExpression m) - return ToVector(m.Arguments, factory); - else if (e is ArrayInitializerExpression a) - return ToVector(a.Items, factory); - return default; - } - - static unsafe TVector? ToVector(List args, Func factory) - where TVector : unmanaged - where TComponent : unmanaged - { - var dimension = sizeof(TVector) / sizeof(TComponent); - if (args.Count == 1) - { - var v = ToScalar(args[0]); - if (v.HasValue) - return factory(Enumerable.Repeat(v.Value, dimension).ToArray()); - else - return default; - } - else if (args.Count == dimension) - return factory(ToArray(args)); - return default; - } - - public static T? ToScalar(Expression e) - where T : unmanaged - { - if (e is LiteralExpression l) - return ToScalar(l.Literal); - else if (e is UnaryExpression u) - return ToScalar(u); - else - return default; - } - - static T? ToScalar(Literal l) - where T : unmanaged - { - if (l.Value is T t) - return t; - else - return ChangeType(l.Value); - } - - static T? ToScalar(UnaryExpression unary) - where T : unmanaged - { - var e = unary.Expression; - return unary.Operator switch - { - UnaryOperator.LogicalNot => ChangeType(!ToScalar(e)), - UnaryOperator.BitwiseNot when typeof(T) == typeof(int) => ChangeType(~ToScalar(e)), - UnaryOperator.BitwiseNot when typeof(T) == typeof(uint) => ChangeType(~ToScalar(e)), - UnaryOperator.Minus when typeof(T) == typeof(int) => ChangeType(-ToScalar(e)), - UnaryOperator.Minus when typeof(T) == typeof(float) => ChangeType(-ToScalar(e)), - UnaryOperator.Minus when typeof(T) == typeof(double) => ChangeType(-ToScalar(e)), - UnaryOperator.Plus => ToScalar(e), - _ => default - }; - } - - static T? ChangeType(object value) - where T : unmanaged - { - try - { - return (T)Convert.ChangeType(value, typeof(T)); - } - catch - { - return default; - } - - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/ShaderMixinParser.cs b/sources/engine/Stride.Shaders.Parser/ShaderMixinParser.cs deleted file mode 100644 index c2b1285bdd..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderMixinParser.cs +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.IO; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Shaders.Parser.Mixins; -using Stride.Shaders.Parser.Utility; -using Stride.Core.Shaders.Analysis.Hlsl; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser -{ - /// - /// Parser for mixin. - /// - public class ShaderMixinParser - { - #region Private members - - /// - /// An Objbect to lock the preprocess step (virtual tables building etc.). - /// - private static readonly Object PreprocessLock = new Object(); - - /// - /// An Objbect to lock the semantic analysis step. - /// - private static readonly Object SemanticAnalyzerLock = new Object(); - - /// - /// The CloneContext with the Hlsl classes and types - /// - private CloneContext hlslCloneContext; - private object hlslCloneContextLock = new object(); - - /// - /// The library containing all the shaders - /// - private readonly StrideShaderLibrary shaderLibrary; - - #endregion - - #region Public members - - /// - /// The shader source manager. - /// - public readonly ShaderSourceManager SourceManager; - - #endregion - - #region Constructor - - /// - /// Initializes a new instance of the class. - /// - public ShaderMixinParser(IVirtualFileProvider fileProvider) - { - SourceManager = new ShaderSourceManager(fileProvider); - var shaderLoader = new ShaderLoader(SourceManager); - - if (shaderLibrary == null) - { - shaderLibrary = new StrideShaderLibrary(shaderLoader); - } - } - - #endregion - - #region Public method - - /// - /// Deletes the shader cache for the specified shaders. - /// - /// The modified shaders. - public void DeleteObsoleteCache(HashSet modifiedShaders) - { - lock (shaderLibrary) - { - shaderLibrary.DeleteObsoleteCache(modifiedShaders); - } - } - public bool AllowNonInstantiatedGenerics - { - get - { - return shaderLibrary.AllowNonInstantiatedGenerics; - } - set - { - shaderLibrary.AllowNonInstantiatedGenerics = value; - } - } - - internal ShaderCompilationContext ParseAndAnalyze(ShaderMixinSource shaderMixinSource, Stride.Shaders.ShaderMacro[] macros, out ShaderMixinParsingResult parsingResult, out HashSet mixinsToAnalyze) - { - // Creates a parsing result - parsingResult = new ShaderMixinParsingResult(); - - Stride.Core.Shaders.Parser.ShaderMacro[] macrosParser; - if (macros == null) - { - macrosParser = new Stride.Core.Shaders.Parser.ShaderMacro[0]; - } - else - { - macrosParser = new Stride.Core.Shaders.Parser.ShaderMacro[macros.Length]; - for (var i = 0; i < macros.Length; ++i) - macrosParser[i] = new Stride.Core.Shaders.Parser.ShaderMacro(macros[i].Name, macros[i].Definition); - } - //PerformanceLogger.Start(PerformanceStage.Global); - - // ---------------------------------------------------------- - // Load all shaders - // ---------------------------------------------------------- - lock (shaderLibrary) - { - //PerformanceLogger.Start(PerformanceStage.Loading); - mixinsToAnalyze = shaderLibrary.LoadShaderSource(shaderMixinSource, macrosParser); - //PerformanceLogger.Stop(PerformanceStage.Loading); - } - - // Extract all ModuleMixinInfo and check for any errors - var allMixinInfos = new HashSet(); - foreach (var moduleMixinInfo in mixinsToAnalyze) - { - allMixinInfos.UnionWith(moduleMixinInfo.MinimalContext); - moduleMixinInfo.Log.CopyTo(parsingResult); - } - foreach (var moduleMixinInfo in allMixinInfos) - { - moduleMixinInfo.Log.CopyTo(parsingResult); - - var ast = moduleMixinInfo.MixinAst; - var shaderClassSource = moduleMixinInfo.ShaderSource as ShaderClassCode; - // If we have a ShaderClassSource and it is not an inline one, then we can store the hash sources - if (ast != null && shaderClassSource != null) - { - parsingResult.HashSources[shaderClassSource.ClassName] = moduleMixinInfo.SourceHash; - } - } - - // Return directly if there was any errors - if (parsingResult.HasErrors) - return null; - - // ---------------------------------------------------------- - // Perform Type Analysis - // ---------------------------------------------------------- - //PerformanceLogger.Start(PerformanceStage.TypeAnalysis); - var context = GetCompilationContext(mixinsToAnalyze, parsingResult); - //PerformanceLogger.Stop(PerformanceStage.TypeAnalysis); - - // Return directly if there was any errors - if (parsingResult.HasErrors) - return context; - - lock (SemanticAnalyzerLock) - { - //PerformanceLogger.Start(PerformanceStage.SemanticAnalysis); - //SemanticPerformance.Start(SemanticStage.Global); - foreach (var mixin in mixinsToAnalyze) - context.Analyze(mixin); - //SemanticPerformance.Pause(SemanticStage.Global); - //PerformanceLogger.Stop(PerformanceStage.SemanticAnalysis); - } - - return context; - } - - /// - /// Mixes shader parts to produces a single HLSL file shader. - /// - /// The shader source. - /// The shader perprocessor macros. - /// The list of modified shaders. - /// The combined shader in AST form. - public ShaderMixinParsingResult Parse(ShaderMixinSource shaderMixinSource, Stride.Shaders.ShaderMacro[] macros = null) - { - // Make in-memory shader classes known to the source manager - foreach (var x in shaderMixinSource.Mixins.OfType()) - SourceManager.AddShaderSource(x.ClassName, x.ShaderSourceCode, x.ClassName); - - // Creates a parsing result - HashSet mixinsToAnalyze; - ShaderMixinParsingResult parsingResult; - var context = ParseAndAnalyze(shaderMixinSource, macros, out parsingResult, out mixinsToAnalyze); - - // Return directly if there was any errors - if (parsingResult.HasErrors) - return parsingResult; - - // Update the clone context in case new instances of classes are created - CloneContext mixCloneContext; - - lock (hlslCloneContextLock) - { - if (hlslCloneContext == null) - { - hlslCloneContext = new CloneContext(); - - // Create the clone context with the instances of Hlsl classes - HlslSemanticAnalysis.FillCloneContext(hlslCloneContext); - } - - HlslSemanticAnalysis.UpdateCloneContext(hlslCloneContext); - mixCloneContext = new CloneContext(hlslCloneContext); - } - - // only clone once the stage classes - foreach (var mixinInfo in mixinsToAnalyze) - { - foreach (var mixin in mixinInfo.Mixin.MinimalContext.Where(x => x.StageOnlyClass)) - { - mixin.DeepClone(mixCloneContext); - } - } - - // ---------------------------------------------------------- - // Perform Shader Mixer - // ---------------------------------------------------------- - var externDict = new CompositionDictionary(); - var finalModuleList = BuildCompositionsDictionary(shaderMixinSource, externDict, context, mixCloneContext, parsingResult); - //PerformanceLogger.Stop(PerformanceStage.DeepClone); - - if (parsingResult.HasErrors) - return parsingResult; - - // look for stage compositions and add the links between variables and compositions when necessary - var extraExternDict = new Dictionary>(); - foreach (var item in externDict) - { - if (item.Key.Qualifiers.Contains(StrideStorageQualifier.Stage)) - FullLinkStageCompositions(item.Key, item.Value, externDict, extraExternDict, parsingResult); - } - foreach (var item in extraExternDict) - externDict.Add(item.Key, item.Value); - - var mixinDictionary = BuildMixinDictionary(finalModuleList); - - if (finalModuleList != null) - { - var finalModule = finalModuleList[0]; - //PerformanceLogger.Start(PerformanceStage.Mix); - parsingResult.Reflection = new EffectReflection(); - var mixer = new StrideShaderMixer(finalModule, parsingResult, mixinDictionary, externDict, new CloneContext(mixCloneContext)); - mixer.Mix(); - //PerformanceLogger.Stop(PerformanceStage.Mix); - - // Return directly if there was any errors - if (parsingResult.HasErrors) - return parsingResult; - - var finalShader = mixer.GetMixedShader(); - - // Simplifies the shader by removing dead code - var simplifier = new ExpressionSimplifierVisitor(); - simplifier.Run(finalShader); - - var sdShaderLinker = new ShaderLinker(parsingResult); - sdShaderLinker.Run(finalShader); - - // Return directly if there was any errors - if (parsingResult.HasErrors) - return parsingResult; - - // Find all entry points - // TODO: make this configurable by CompileParameters - foreach (var stage in new[] {ShaderStage.Compute, ShaderStage.Vertex, ShaderStage.Hull, ShaderStage.Domain, ShaderStage.Geometry, ShaderStage.Pixel}) - { - var entryPoint = finalShader.Declarations.OfType().FirstOrDefault(f => f.Attributes.OfType().Any(a => a.Name == "EntryPoint" && (string)a.Parameters[0].Value == stage.ToString())); - - if (entryPoint == null) - { - continue; - } - - parsingResult.EntryPoints[stage] = entryPoint.Name.Text; - - // When this is a compute shader, there is no need to scan other stages - if (stage == ShaderStage.Compute) - break; - } - - var typeCleaner = new StrideShaderCleaner(); - typeCleaner.Run(finalShader); - - //PerformanceLogger.Stop(PerformanceStage.Global); - - //PerformanceLogger.PrintLastResult(); - //SemanticPerformance.PrintResult(); - //MixPerformance.PrintResult(); - //GenerateShaderPerformance.PrintResult(); - //StreamCreatorPerformance.PrintResult(); - //ShaderLoader.PrintTime(); - - //PerformanceLogger.WriteOut(52); - - parsingResult.Shader = finalShader; - } - - return parsingResult; - } - - #endregion - - #region Internal methods - - internal ModuleMixinInfo GetMixin(string mixinName) - { - return shaderLibrary.MixinInfos.FirstOrDefault(x => x.MixinGenericName == mixinName); - } - - #endregion - - #region Private methods - - /// - /// create the context for each composition by cloning their dependencies - /// - /// the entry ShaderSource (root) - /// the ouputed compositions - /// the compilation context - /// The clone context. - /// a list of all the needed mixins - private static List BuildCompositionsDictionary(ShaderSource shaderSource, CompositionDictionary dictionary, ShaderCompilationContext compilationContext, CloneContext cloneContext, LoggerResult log) - { - if (shaderSource is ShaderMixinSource) - { - var shaderMixinSource = shaderSource as ShaderMixinSource; - - var finalModule = compilationContext.GetModuleMixinFromShaderSource(shaderSource); - - //PerformanceLogger.Start(PerformanceStage.DeepClone); - finalModule = finalModule.DeepClone(new CloneContext(cloneContext)); - //PerformanceLogger.Pause(PerformanceStage.DeepClone); - - foreach (var composition in shaderMixinSource.Compositions) - { - //look for the key - var foundVars = finalModule.FindAllVariablesByName(composition.Key).Where(value => value.Variable.Qualifiers.Contains(StrideStorageQualifier.Compose)).ToList(); - - if (foundVars.Count > 1) - { - log.Error(StrideMessageCode.ErrorAmbiguousComposition, new SourceSpan(), composition.Key); - } - else if (foundVars.Count > 0) - { - Variable foundVar = foundVars[0].Variable; - var moduleMixins = BuildCompositionsDictionary(composition.Value, dictionary, compilationContext, cloneContext, log); - if (moduleMixins == null) - return null; - - dictionary.Add(foundVar, moduleMixins); - } - else - { - // No matching variable was found - // TODO: log a message? - } - } - return new List { finalModule }; - } - - - if (shaderSource is ShaderClassCode) - { - var finalModule = compilationContext.GetModuleMixinFromShaderSource(shaderSource); - - //PerformanceLogger.Start(PerformanceStage.DeepClone); - finalModule = finalModule.DeepClone(new CloneContext(cloneContext)); - //PerformanceLogger.Pause(PerformanceStage.DeepClone); - - return new List { finalModule }; - } - - if (shaderSource is ShaderArraySource) - { - var shaderArraySource = shaderSource as ShaderArraySource; - var compositionArray = new List(); - foreach (var shader in shaderArraySource.Values) - { - var mixin = BuildCompositionsDictionary(shader, dictionary, compilationContext, cloneContext, log); - if (mixin == null) - return null; - compositionArray.AddRange(mixin); - } - return compositionArray; - } - - return null; - } - - /// - /// Link all the stage compositions in case it is referenced at several places. - /// - /// The variable of the composition. - /// The composition. - /// The already registered compositions. - /// The new compositions. - /// The logger. - private static void FullLinkStageCompositions(Variable variable, List composition, CompositionDictionary dictionary, Dictionary> extraDictionary, LoggerResult log) - { - var mixin = variable.GetTag(StrideTags.ShaderScope) as ModuleMixin; - if (mixin != null) - { - var className = mixin.MixinName; - foreach (var item in dictionary) - { - if (item.Key == variable) - continue; - - foreach (var module in item.Value) - { - if (module.MixinName == className || module.InheritanceList.Any(x => x.MixinName == className)) - { - // add reference - var foundVars = module.FindAllVariablesByName(variable.Name).Where(value => value.Variable.Qualifiers.Contains(StrideStorageQualifier.Compose)).ToList(); - if (foundVars.Count > 1) - { - log.Error(StrideMessageCode.ErrorAmbiguousComposition, new SourceSpan(), variable.Name); - } - else if (foundVars.Count > 0) - { - // if there is already a filled composition, it means that the ShaderMixinSource filled the composition information at two different places - // TODO: verify that - var foundVar = foundVars[0].Variable; - List previousList; - if (dictionary.TryGetValue(foundVar, out previousList)) - { - previousList.AddRange(composition); - } - else - extraDictionary.Add(foundVars[0].Variable, composition); - } - else - { - // No matching variable was found - // TODO: log a message? - } - } - } - } - } - } - - /// - /// Get a compilation context based on the macros - /// - /// List of mixin to analyze - /// The log. - /// the correct compilation context - private ShaderCompilationContext GetCompilationContext(IEnumerable mixinToAnalyze, LoggerResult log) - { - var mixinInfos = new HashSet(); - foreach (var mixin in mixinToAnalyze) - mixinInfos.UnionWith(mixin.MinimalContext); - - var context = new ShaderCompilationContext(log); - context.Preprocess(mixinInfos); - return context; - } - - /// - /// Build a dictionary of mixins - /// - /// a list of mixins - /// a dictionary of all the necessary mixins - private Dictionary BuildMixinDictionary(IEnumerable finalMixins) - { - var allMixins = new HashSet(); - foreach (var mixin in finalMixins) - { - if (allMixins.All(x => x.MixinName != mixin.MixinName)) - allMixins.Add(mixin); - } - - return allMixins.ToDictionary(x => x.MixinName, x => x); - } - - #endregion - } -} diff --git a/sources/engine/Stride.Shaders.Parser/ShaderMixinParsingResult.cs b/sources/engine/Stride.Shaders.Parser/ShaderMixinParsingResult.cs deleted file mode 100644 index f0c2589123..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderMixinParsingResult.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using Stride.Core.Storage; -using Stride.Graphics; -using Stride.Core.Shaders.Parser; - -namespace Stride.Shaders.Parser -{ - public class ShaderMixinParsingResult : ParsingResult - { - public ShaderMixinParsingResult() - { - EntryPoints = new Dictionary(); - HashSources = new HashSourceCollection(); - } - - public EffectReflection Reflection { get; set; } - - public Dictionary EntryPoints; - - public HashSourceCollection HashSources { get; set; } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/ShaderNavigation.cs b/sources/engine/Stride.Shaders.Parser/ShaderNavigation.cs deleted file mode 100644 index a46d2774bd..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderNavigation.cs +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using Stride.Shaders.Parser.Mixins; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser -{ - /// - /// This class helps to navigate from a text location and try to find the associated definition location - /// (local variables, stage variables, class sdsl, shaders sdfx...etc.) - /// - public class ShaderNavigation - { - private static readonly MessageCode ErrorMixinNotFound = new MessageCode("E900", "Mixin [{0}] not found from results"); - - /// - /// Analyzes the shader source code and go to definition. - /// - /// The shader source. - /// The location. - /// The shader directories. - /// ShaderNavigationResult. - /// shaderSource - /// Expecting a FileSource location;location - public ShaderNavigationResult AnalyzeAndGoToDefinition(string shaderSource, Stride.Core.Shaders.Ast.SourceLocation location, List shaderDirectories) - { - if (shaderSource == null) throw new ArgumentNullException("shaderSource"); - var navigationResult = new ShaderNavigationResult(); - if (location.FileSource == null) - { - throw new ArgumentException("Expecting a FileSource location", "location"); - } - - try - { - if (location.FileSource.EndsWith(".sdsl", StringComparison.CurrentCultureIgnoreCase)) - { - AnalyzeAndGoToDefinition(shaderSource, location, shaderDirectories, navigationResult); - } - - // If any of the messages have empty filesource, add a default filesource - foreach (var message in navigationResult.Messages.Messages) - { - if (string.IsNullOrWhiteSpace(message.Span.Location.FileSource)) - { - message.Span.Location.FileSource = location.FileSource; - } - } - } - catch (Exception ex) - { - navigationResult.Messages.Error(MessageCode.ErrorUnexpectedException, GetSpan(location), ex); - } - - return navigationResult; - } - - private static SourceSpan GetSpan(SourceLocation location) - { - return new SourceSpan(new SourceLocation(location.FileSource, 0, 1, 1), 1); - } - - private void AnalyzeAndGoToDefinition(string shaderSource, Stride.Core.Shaders.Ast.SourceLocation location, List shaderDirectories, ShaderNavigationResult result) - { - // We are not using the storage when loading shaders from VS but directly the filesystem - var mixer = new ShaderMixinParser(null); - mixer.SourceManager.UseFileSystem = true; - mixer.AllowNonInstantiatedGenerics = true; - mixer.SourceManager.LookupDirectoryList.AddRange(shaderDirectories); - - var shaderSourceName = Path.GetFileNameWithoutExtension(location.FileSource); - mixer.SourceManager.AddShaderSource(shaderSourceName, shaderSource, location.FileSource); - - var mixinSource = new ShaderMixinSource(); - mixinSource.Mixins.Add(new ShaderClassSource(shaderSourceName)); - - ShaderMixinParsingResult parsingResult; - HashSet moduleMixins; - var mixerResult = mixer.ParseAndAnalyze(mixinSource, null, out parsingResult, out moduleMixins); - - // Copy shader analysis to result - parsingResult.CopyTo(result.Messages); - - if (mixerResult == null) - { - return; - } - - var mixin = mixerResult.MixinInfos.FirstOrDefault(item => item.MixinName == shaderSourceName); - - if (mixin == null) - { - result.Messages.Error(ErrorMixinNotFound, GetSpan(location), shaderSourceName); - return; - } - - // If first line, first column, this is not a go to definition but only parsing request, so return directly - if (location.Line == 1 && location.Column == 1) - { - return; - } - - // var ast = mixin.MixinAst; - - var parsingInfo = mixin.Mixin.ParsingInfo; - - var pools = new List - { - parsingInfo.ClassReferences, - parsingInfo.StaticReferences, - parsingInfo.ExternReferences, - parsingInfo.StageInitReferences, - }; - - foreach (var pool in pools) - { - var span = Find(pool, location); - if (span.HasValue) - { - result.DefinitionLocation = span.Value; - return; - } - } - - // Else Try to find from remaining navigable nodes - foreach (var node in parsingInfo.NavigableNodes) - { - if (IsExpressionMatching(node, location)) - { - var typeReferencer = node as ITypeInferencer; - if (typeReferencer != null && typeReferencer.TypeInference != null && typeReferencer.TypeInference.Declaration != null) - { - var declarationNode = (Node)typeReferencer.TypeInference.Declaration; - result.DefinitionLocation = declarationNode.Span; - break; - } - } - } - } - - private SourceSpan? Find(ReferencesPool pool, Stride.Core.Shaders.Ast.SourceLocation location) - { - foreach (var methodRef in pool.MethodsReferences) - { - foreach (var expression in methodRef.Value) - { - if (IsExpressionMatching(expression, location)) - { - return methodRef.Key.Span; - } - } - } - - foreach (var variableRef in pool.VariablesReferences) - { - foreach (var expression in variableRef.Value) - { - if (IsExpressionMatching(expression.Expression, location)) - { - return variableRef.Key.Span; - } - } - } - return null; - } - - private bool IsExpressionMatching(Node astNode, Stride.Core.Shaders.Ast.SourceLocation location) - { - var span = astNode.Span; - var startColumn = span.Location.Column; - var endColumn = startColumn + span.Length; - if (astNode.Span.Location.Line == location.Line && location.Column >= startColumn) - { - if (location.Column >= startColumn && location.Column <= endColumn) - { - return true; - } - } - return false; - } - - } -} diff --git a/sources/engine/Stride.Shaders.Parser/ShaderNavigationResult.cs b/sources/engine/Stride.Shaders.Parser/ShaderNavigationResult.cs deleted file mode 100644 index af16141293..0000000000 --- a/sources/engine/Stride.Shaders.Parser/ShaderNavigationResult.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser -{ - /// - /// Results of a - /// - public class ShaderNavigationResult - { - public ShaderNavigationResult() - { - Messages = new LoggerResult(); - } - - /// - /// Gets or sets the definition location. - /// - /// The definition location. - public Stride.Core.Shaders.Ast.SourceSpan DefinitionLocation { get; set; } - - /// - /// Gets the parsing messages. - /// - /// The messages. - public LoggerResult Messages { get; set; } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Stride.Shaders.Parser.csproj b/sources/engine/Stride.Shaders.Parser/Stride.Shaders.Parser.csproj deleted file mode 100644 index 4a18b4188a..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Stride.Shaders.Parser.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - true - - - - 8.0.30703 - 2.0 - true - true - --auto-module-initializer --serialization - * - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - \ No newline at end of file diff --git a/sources/engine/Stride.Shaders.Parser/StrideShaderCleaner.cs b/sources/engine/Stride.Shaders.Parser/StrideShaderCleaner.cs deleted file mode 100644 index 326809010a..0000000000 --- a/sources/engine/Stride.Shaders.Parser/StrideShaderCleaner.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Shaders.Parser -{ - internal class StrideShaderCleaner : ShaderRewriter - { - public StrideShaderCleaner() : base(false, false) - { - } - - /// - /// Runs this instance on the specified node. - /// - /// The shader. - public void Run(Shader shader) - { - Visit(shader); - } - - public void Run(ShaderClassType shaderClassType) - { - var shader = new Shader(); - shader.Declarations.Add(shaderClassType); - Run(shader); - } - - public override Node DefaultVisit(Node node) - { - var qualifierNode = node as IQualifiers; - if (qualifierNode != null) - { - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.Stream); - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.Stage); - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.PatchStream); - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.Override); - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.Clone); - qualifierNode.Qualifiers.Values.Remove(StrideStorageQualifier.Stage); - } - - return base.DefaultVisit(node); - } - - public override Node Visit(AttributeDeclaration attribute) - { - if (StrideAttributes.AvailableAttributes.Contains(attribute.Name)) - return null; - - return attribute; - } - } -} diff --git a/sources/engine/Stride.Shaders.Parser/Utility/StrideMessageCode.cs b/sources/engine/Stride.Shaders.Parser/Utility/StrideMessageCode.cs deleted file mode 100644 index 9bc02ab686..0000000000 --- a/sources/engine/Stride.Shaders.Parser/Utility/StrideMessageCode.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Utility; - -namespace Stride.Shaders.Parser.Utility -{ - static public class StrideMessageCode - { - // analysis warning: W0### - public static readonly MessageCode WarningDeclarationCall = new MessageCode("W0201", "The method invocation [{0}] calls the method [{1}] which is only declared, and not defined in class [{2}]"); - public static readonly MessageCode WarningMissingStageKeyword = new MessageCode("W0202", "The stage keyword is missing in The method declaration [{0}] in class [{1}]"); - public static readonly MessageCode WarningUseSemanticType = new MessageCode("W0203", "The generic [{0}] is not of Semantic type but was used as semantic. Change the type or change name of the generic if there is a conflict."); - public static readonly MessageCode WarningMissingOverrideKeyword = new MessageCode("W0204", "Override keyword should be used when overriding the method declaration [{0}] in class [{1}]"); - - // analysis errors: E0### - public static readonly MessageCode ErrorCyclicDependency = new MessageCode("E0201", "Cyclic mixin [{0}] dependency"); - public static readonly MessageCode ErrorFunctionRedefined = new MessageCode("E0202", "There is already a function with the same signature as [{0}] in class [{1}]"); - public static readonly MessageCode ErrorFunctionVariableNameConflict = new MessageCode("E0203", "The function [{0}] has the same name as a variable in class [{1}]"); - public static readonly MessageCode ErrorVariableNameConflict = new MessageCode("E0204", "The variable [{0}] has the same name as another variable in class [{1}]"); - public static readonly MessageCode ErrorVariableFunctionNameConflict = new MessageCode("E0205", "The variable [{0}] has the same name as a method in class [{1}]"); - public static readonly MessageCode ErrorVreNoTypeInference = new MessageCode("E0206", "VariableReferenceExpression [{0}] has no type inference in class [{1}]"); - public static readonly MessageCode ErrorStageVariableTypeConflict = new MessageCode("E0207", "Stage variable declaration [{0}] has not the same type as the actual definition [{1}] in class [{2}]"); - public static readonly MessageCode ErrorImpossibleBaseCall = new MessageCode("E0208", "Unable to find the base call [{0}] of class [{1}]"); - public static readonly MessageCode ErrorImpossibleVirtualCall = new MessageCode("E0209", "Unable to find the virtual call [{0}] of class [{1}] in context [{2}]"); - public static readonly MessageCode ErrorExternStageVariableNotFound = new MessageCode("E0210", "There is no matching instance for variable [{0}] in class [{1}]"); - public static readonly MessageCode ErrorExternStageFunctionNotFound = new MessageCode("E0211", "Unable to find the virtual call [{0}] of extern class [{1}] in context [{2}]"); - public static readonly MessageCode ErrorMissingOverride = new MessageCode("E0212", "There is already a method with the same signature as [{0}] in class [{1}]. Missing override keyword?"); - public static readonly MessageCode ErrorNoMethodToOverride = new MessageCode("E0214", "There is no method [{0}] to override in class [{1}]"); - public static readonly MessageCode ErrorShaderClassTypeParameter = new MessageCode("E0215", "The function [{0}] has a paramater [{1}] of shader class type which is not allowed in class [{2}]"); - public static readonly MessageCode ErrorShaderClassReturnType = new MessageCode("E0216", "The function [{0}] is not allowed to return a class in class [{1}]"); - public static readonly MessageCode ErrorMissingAbstract = new MessageCode("E0217", "The method [{0}] is only declared, so it should have the abstract keyword in class [{1}]"); - public static readonly MessageCode ErrorUnnecessaryOverride = new MessageCode("E0218", "The method [{0}] is only declared, so it cannot have the override keyword in class [{1}]"); - public static readonly MessageCode ErrorUnnecessaryAbstract = new MessageCode("E0219", "The method [{0}] is defined, so it cannot have the abstract keyword in clas [{1}]"); - public static readonly MessageCode ErrorStageInitNotClassType = new MessageCode("E0220", "The variable [{0}] is initialized at stage and should be of class type in class [{1}]"); - public static readonly MessageCode ErrorExternNotClassType = new MessageCode("E0221", "The extern variable [{0}] should be of class type in class [{1}]"); - public static readonly MessageCode ErrorMissingExtern = new MessageCode("E0222", "The variable [{0}] is of class type and should have the extern keyword in class [{1}]"); - public static readonly MessageCode ErrorVarNoInitialValue = new MessageCode("E0223", "The variable [{0}] should have an initial value to guess its type in class [{1}]"); - public static readonly MessageCode ErrorVarNoTypeFound = new MessageCode("E0224", "Unable to guess the type of the variable [{0}] in class [{1}]"); - public static readonly MessageCode ErrorTechniqueFound = new MessageCode("E0225", "Techniques like [{0}] are not allowed in the Stride shading language in class [{1}]"); - public static readonly MessageCode ErrorExternMemberNotFound = new MessageCode("E0226", "There is no member [{0}] for the type [{1}] in class [{2}]"); - public static readonly MessageCode ErrorStreamNotFound = new MessageCode("E0227", "Unable to find stream variable [{0}] in class [{1}]"); - public static readonly MessageCode ErrorStreamUsage = new MessageCode("E0228", "the stream [{0}] was read first THEN written in class [{1}]"); - public static readonly MessageCode ErrorVariableNameAmbiguity = new MessageCode("E0229", "The name [{0}] is ambiguous within variables in class [{1}]"); - public static readonly MessageCode ErrorMethodNameAmbiguity = new MessageCode("E0230", "The name [{0}] is ambiguous within methods in class [{1}]"); - public static readonly MessageCode ErrorMissingMethod = new MessageCode("E0231", "The method [{0}] in class [{1}] is not defined"); - public static readonly MessageCode ErrorCyclicMethod = new MessageCode("E0232", "Method [{0}] performs a cyclic call, which is not allowed in class [{1}]"); - public static readonly MessageCode ErrorDeclarationCall = new MessageCode("E0233", "The method invocation [{0}] calls the method [{1}] which is only declared, and not defined in class [{2}]"); - public static readonly MessageCode ErrorNoBaseMixin = new MessageCode("E0234", "base call [{0}] without any base class in class [{1}]"); - public static readonly MessageCode ErrorStageOutsideVariable = new MessageCode("E0235", "Use of the stage keyword in [{0}] which is outside a variable in class [{1}]"); - public static readonly MessageCode ErrorMissingStreamsStruct = new MessageCode("E0236", "The variable [{0}] is a stream/patchstream and should be called this way [streams/constants.{0}] in class [{1}]"); - public static readonly MessageCode ErrorMissingVariable = new MessageCode("E0237", "The variable [{0}] in class [{1}] is not defined"); - public static readonly MessageCode ErrorNoTypeInference = new MessageCode("E0238", "Unable to infer type for [{0}] in class [{1}]"); - public static readonly MessageCode ErrorShaderVariable = new MessageCode("E0239", "It is forbidden to create Shader variables like [{0}] in class [{1}]"); - public static readonly MessageCode ErrorInterfaceFound = new MessageCode("E0240", "Hlsl interfaces like [{0}] are not allowed in Stride. Use classes instead. In class [{1}]"); - public static readonly MessageCode ErrorMixinAsGeneric = new MessageCode("E0241", "A class like [{0}] cannot be used as a generic parameter for [{1}] in class [{2}]"); - public static readonly MessageCode ErrorInOutStream = new MessageCode("E0242", "The stream [{0}] is used as an inout parameter in method [{1}] in class [{2}]"); - public static readonly MessageCode ErrorIndexerNotLiteral = new MessageCode("E0243", "The IndexerExpression [{0}] of a composition have to be used with a literal index in class [{1}]"); - public static readonly MessageCode ErrorMultiDimArray = new MessageCode("E0244", "Multi-dimentional arrays [{0}] are not supported in foreach statement [{1}] in class [{2}]"); - public static readonly MessageCode ErrorExtraStageKeyword = new MessageCode("E0245", "The overriding method [{0}] have a stage keyword whereas its base doesn't [{1}], in class [{2}]"); - public static readonly MessageCode ErrorTypedefInMethod = new MessageCode("E0246", "The typedef [{0}] is defined a method ([{1}]) which is not allowed, in class [{2}]"); - public static readonly MessageCode ErrorNestedAssignment = new MessageCode("E0247", "Nested target assignment on the left like [{0}] are not supported, in shader [{1}]"); - public static readonly MessageCode ErrorMultidimensionalCompositionArray = new MessageCode("E0248", "Multidimentional conposition arrays (type [{0}]) are not supported, in class [{1}]"); - public static readonly MessageCode ErrorOverrindingDeclaration = new MessageCode("E0249", "Method [{0}] is an overriding declaration, this is not allowed"); - public static readonly MessageCode ErrorNullKeyword = new MessageCode("E0250", "Keyword null is used outside of variable initialization in [{0}] in class [{1}]"); - public static readonly MessageCode ErrorExtraStreamsPrefix = new MessageCode("E0251", "The variable [{0}] has the stream prefix but its declaration [{1}] is not a stream variable, in class [{2}]"); - public static readonly MessageCode ErrorNonStaticCallInStaticMethod = new MessageCode("E0252", "The static method [{0}] performs a non-static call to [{1}], in class [{2}]"); - public static readonly MessageCode ErrorNonStaticReferenceInStaticMethod = new MessageCode("E0253", "The static method [{0}] contains a reference to a non-static member [{1}], in class [{2}]"); - - // module errors: E1### - public static readonly MessageCode UnknownModuleError = new MessageCode("E1200", "Unknown module error"); - public static readonly MessageCode ErrorClassNotFound = new MessageCode("E1201", "The class [{0}] was not found from the include path"); - public static readonly MessageCode ErrorDependencyNotInModule = new MessageCode("E1202", "The mixin [{0}] in [{1}] dependency is not in the module"); - public static readonly MessageCode ErrorClassSourceNotInstantiated = new MessageCode("E1203", "The type [{0}] has generic parameters defined but only {1}/{2} arguments were passed when creating its instance"); - public static readonly MessageCode ErrorAmbiguousComposition = new MessageCode("E1204", "The composition behind the variable [{0}] is ambiguous. Several matching variables were found."); - - // mix errors: E2### - public static readonly MessageCode UnknownMixError = new MessageCode("E2200", "Unknown mix error"); - public static readonly MessageCode ErrorVariableNotFound = new MessageCode("E2201", "Variable [{0}] not found in class [{1}]"); - public static readonly MessageCode ErrorMissingStageVariable = new MessageCode("E2202", "Missing stage variable [{0}] from class [{1}]"); - public static readonly MessageCode ErrorExternReferenceNotFound = new MessageCode("E2203", "Extern reference [{0}] not found from class [{1}]"); - public static readonly MessageCode ErrorStageMixinNotFound = new MessageCode("E2204", "Stage mixin [{0}] not found from class [{1}] through stage initialized variable"); - public static readonly MessageCode ErrorStageMixinVariableNotFound = new MessageCode("E2205", "Stage mixin [{0}] variable [{1}] not found from class [{1}]"); - public static readonly MessageCode ErrorStageMixinMethodNotFound = new MessageCode("E2206", "Stage mixin [{0}] method [{1}] not found from class [{1}]"); - public static readonly MessageCode ErrorIncompleteTesselationShader = new MessageCode("E2207", "Tessellation Shader is not compete, one stage is missing"); - public static readonly MessageCode ErrorSemanticCbufferConflict = new MessageCode("E2208", "Variables [{0}] from [{1}] and [{2}] from [{3}] share the same semantic [{4}] but have distinct cbuffers ([{5}] and [{6}])"); - public static readonly MessageCode ErrorRecursiveCall = new MessageCode("E2209", "Method [{0}] performs a recursive call which is not supported in shader language"); - public static readonly MessageCode ErrorStreamUsageInitialization = new MessageCode("E2210", "A stream usage was added but not correctly initialized"); - public static readonly MessageCode ErrorCrossStageMethodCall = new MessageCode("E2211", "Method [{0}] that uses streams is called in both [{1}] and [{2}] shader stages"); - public static readonly MessageCode ErrorCallToAbstractMethod = new MessageCode("E2212", "The method invocation [{0}] calls the abstract method [{1}]"); - public static readonly MessageCode ErrorCallNotFound = new MessageCode("E2213", "The method invocation [{0}] target could not be found"); - public static readonly MessageCode ErrorTopMixinNotFound = new MessageCode("E2214", "The top mixin of [{0}] could not be found"); - public static readonly MessageCode ErrorSemanticTypeConflict = new MessageCode("E2215", "Variables [{0}] from [{1}] and [{2}] from [{3}] share the same semantic [{4}] but have distinct types ([{5}] and [{6}])"); - - // linker errors: E3### - public static readonly MessageCode SamplerFilterNotSupported = new MessageCode("E3000", "The sampler filter [{0}] is not supported"); - public static readonly MessageCode SamplerAddressModeNotSupported = new MessageCode("E3001", "The sampler address mode [{0}] is not supported. Expecting AddressV, AddressU, AddressW"); - public static readonly MessageCode SamplerBorderColorNotSupported = new MessageCode("E3002", "The sampler color component [{0}] is not supported. Expecting a float"); - - // loading errors - public static readonly MessageCode ErrorUninstanciatedClass = new MessageCode("E3202", "The class [{0}] is not correctly instanciated with the current set of generics"); - public static readonly MessageCode SamplerFieldNotSupported = new MessageCode("E3003", "The sampler field [{0}] is not supported"); - public static readonly MessageCode LinkError = new MessageCode("E3004", "HLSL Link error: Could not find variable {0} in the shader"); - public static readonly MessageCode LinkArgumentsError = new MessageCode("E3005", "HLSL Link error: Invalid number of arguments. Expecting only name of the linked variable"); - public static readonly MessageCode VariableTypeNotSupported = new MessageCode("E3006", "The type of the variable [{0}] is not supported"); - public static readonly MessageCode StreamVariableWithoutPrefix = new MessageCode("E3007", "Stream variable [{0}] is used without 'streams'. prefix"); - public static readonly MessageCode WrongGenericNumber = new MessageCode("E3008", "The class [{0}] could not be instanciated because the number of required generics does not match the number of passed generics."); - public static readonly MessageCode SameNameGenerics = new MessageCode("E3009", "The generic [{0}] has the same name as [{1}]. Class [{2}] couldn't be instanciated."); - public static readonly MessageCode FileNameNotMatchingClassName = new MessageCode("E3010", "The shader file name [{0}] is not matching the shader class name [{1}]"); - public static readonly MessageCode ShaderMustContainSingleClassDeclaration = new MessageCode("E3011", "The shader [{0}] must contain only a single shader class declaration"); - - // compiler errors: E4### - public static readonly MessageCode EntryPointNotFound = new MessageCode("E4000", "Entrypoint [{0}] was not found for stage [{1}] in Shader [{2}]"); - } -} diff --git a/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs b/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs index cb7d67872e..7192dc107d 100644 --- a/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs +++ b/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs @@ -113,13 +113,6 @@ public BenchmarkShaderSystems() }; } - [Benchmark] - public void OldSystem() - { - // Old system - var parsingResult = compiler.GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); - } - [Benchmark] public void NewSystem() { diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinMacros.cs b/sources/engine/Stride.Shaders.Tests/TestMixinMacros.cs deleted file mode 100644 index fb1f328626..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestMixinMacros.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using Xunit; - -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Shaders.Parser; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Shaders.Tests -{ - public class TestMixinMacros - { - private ShaderMixinParser shaderMixinParser; - - private void Init() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - shaderMixinParser = new ShaderMixinParser(databaseFileProvider); - shaderMixinParser.SourceManager.LookupDirectoryList.Add("/shaders"); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestMacros() - { - Init(); - - // test that macros are correctly used - var baseMixin = new ShaderMixinSource(); - baseMixin.AddMacro("STRIDE_GRAPHICS_API_DIRECT3D", 1); - baseMixin.Macros.Add(new ShaderMacro("MACRO_TEST", "int")); - baseMixin.Mixins.Add(new ShaderClassSource("TestMacros")); - - var macros0 = new ShaderMixinSource(); - macros0.Mixins.Add(new ShaderClassSource("MacroTest")); - baseMixin.Compositions.Add("macros0", macros0); - - var macros1 = new ShaderMixinSource(); - macros1.Mixins.Add(new ShaderClassSource("MacroTest")); - macros1.Macros.Add(new ShaderMacro("MACRO_TEST", "float")); - baseMixin.Compositions.Add("macros1", macros1); - - var macros2 = new ShaderMixinSource(); - macros2.Mixins.Add(new ShaderClassSource("MacroTest")); - macros2.Macros.Add(new ShaderMacro("MACRO_TEST", "float4")); - baseMixin.Compositions.Add("macros2", macros2); - - var parsingResult = shaderMixinParser.Parse(baseMixin, baseMixin.Macros.ToArray()); - - Assert.False(parsingResult.HasErrors); - var cBufferVar = parsingResult.Shader.Declarations.OfType().First(x => x.Name == "Globals").Members.OfType().ToList(); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "int")); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "float")); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "float4")); - - // test clash when reloading - var baseMixin2 = new ShaderMixinSource(); - baseMixin2.AddMacro("STRIDE_GRAPHICS_API_DIRECT3D", 1); - baseMixin2.Macros.Add(new ShaderMacro("MACRO_TEST", "int")); - baseMixin2.Mixins.Add(new ShaderClassSource("TestMacros")); - - var macros3 = new ShaderMixinSource(); - macros3.Mixins.Add(new ShaderClassSource("MacroTest")); - baseMixin2.Compositions.Add("macros0", macros3); - - var macros4 = new ShaderMixinSource(); - macros4.Mixins.Add(new ShaderClassSource("MacroTest")); - macros4.Macros.Add(new ShaderMacro("MACRO_TEST", "uint4")); - baseMixin2.Compositions.Add("macros1", macros4); - - var macros5 = new ShaderMixinSource(); - macros5.Mixins.Add(new ShaderClassSource("MacroTest")); - macros5.Macros.Add(new ShaderMacro("MACRO_TEST", "float4")); - baseMixin2.Compositions.Add("macros2", macros5); - - var parsingResult2 = shaderMixinParser.Parse(baseMixin2, baseMixin2.Macros.ToArray()); - - Assert.False(parsingResult.HasErrors); - var cBufferVar2 = parsingResult2.Shader.Declarations.OfType().First(x => x.Name == "Globals").Members.OfType().ToList(); - Assert.Equal(1, cBufferVar2.Count(x => x.Type.Name.Text == "int")); - Assert.Equal(1, cBufferVar2.Count(x => x.Type.Name.Text == "uint4")); - Assert.Equal(1, cBufferVar2.Count(x => x.Type.Name.Text == "float4")); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestMacrosArray() - { - Init(); - - // test that macros are correctly used through an array - var baseMixin = new ShaderMixinSource(); - baseMixin.AddMacro("STRIDE_GRAPHICS_API_DIRECT3D", 1); - baseMixin.Macros.Add(new ShaderMacro("MACRO_TEST", "int")); - baseMixin.Mixins.Add(new ShaderClassSource("TestMacrosArray")); - - var compositionArray = new ShaderArraySource(); - - var macros0 = new ShaderMixinSource(); - macros0.Mixins.Add(new ShaderClassSource("MacroTest")); - compositionArray.Add(macros0); - - var macros1 = new ShaderMixinSource(); - macros1.Mixins.Add(new ShaderClassSource("MacroTest")); - macros1.Macros.Add(new ShaderMacro("MACRO_TEST", "float")); - compositionArray.Add(macros1); - - var macros2 = new ShaderMixinSource(); - macros2.Mixins.Add(new ShaderClassSource("MacroTest")); - macros2.Macros.Add(new ShaderMacro("MACRO_TEST", "float4")); - compositionArray.Add(macros2); - - baseMixin.Compositions.Add("macrosArray", compositionArray); - - var parsingResult = shaderMixinParser.Parse(baseMixin, baseMixin.Macros.ToArray()); - - Assert.False(parsingResult.HasErrors); - var cBufferVar = parsingResult.Shader.Declarations.OfType().First(x => x.Name == "Globals").Members.OfType().ToList(); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "int")); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "float")); - Assert.Equal(1, cBufferVar.Count(x => x.Type.Name.Text == "float4")); - } - - - private void Run() - { - //TestMacros(); - TestMacrosArray(); - } - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/GrammarItemList.cs b/sources/shaders/Irony.GrammarExplorer/GrammarItemList.cs deleted file mode 100644 index 59df869224..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/GrammarItemList.cs +++ /dev/null @@ -1,124 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading; -using System.Windows.Forms; -using System.Xml; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - - //Helper classes for supporting showing grammar list in top combo, saving list on exit and loading on start - public class GrammarItem - { - public readonly string Caption; - public readonly string LongCaption; - public readonly string Location; //location of assembly containing the grammar - public readonly string TypeName; //full type name - internal bool _loading; - public GrammarItem(string caption, string location, string typeName) - { - Caption = caption; - Location = location; - TypeName = typeName; - } - public GrammarItem(Type grammarClass, string assemblyLocation) - { - _loading = true; - Location = assemblyLocation; - TypeName = grammarClass.FullName; - //Get language name from Language attribute - Caption = grammarClass.Name; //default caption - LongCaption = Caption; - var langAttr = LanguageAttribute.GetValue(grammarClass); - if (langAttr != null) - { - Caption = langAttr.LanguageName; - if (!string.IsNullOrEmpty(langAttr.Version)) - Caption += ", version " + langAttr.Version; - LongCaption = Caption; - if (!string.IsNullOrEmpty(langAttr.Description)) - LongCaption += ": " + langAttr.Description; - } - } - public GrammarItem(XmlElement element) - { - Caption = element.GetAttribute("Caption"); - Location = element.GetAttribute("Location"); - TypeName = element.GetAttribute("TypeName"); - } - public void Save(XmlElement toElement) - { - toElement.SetAttribute("Caption", Caption); - toElement.SetAttribute("Location", Location); - toElement.SetAttribute("TypeName", TypeName); - } - public override string ToString() - { - return _loading ? LongCaption : Caption; - } - - }//class - - public class GrammarItemList : List - { - public static GrammarItemList FromXml(string xml) - { - GrammarItemList list = new GrammarItemList(); - XmlDocument xdoc = new XmlDocument(); - xdoc.LoadXml(xml); - XmlNodeList xlist = xdoc.SelectNodes("//Grammar"); - foreach (XmlElement xitem in xlist) - { - GrammarItem item = new GrammarItem(xitem); - list.Add(item); - } - return list; - } - public static GrammarItemList FromCombo(ComboBox combo) - { - GrammarItemList list = new GrammarItemList(); - foreach (GrammarItem item in combo.Items) - list.Add(item); - return list; - } - - public string ToXml() - { - XmlDocument xdoc = new XmlDocument(); - XmlElement xlist = xdoc.CreateElement("Grammars"); - xdoc.AppendChild(xlist); - foreach (GrammarItem item in this) - { - XmlElement xitem = xdoc.CreateElement("Grammar"); - xlist.AppendChild(xitem); - item.Save(xitem); - } //foreach - return xdoc.OuterXml; - }//method - - public void ShowIn(ComboBox combo) - { - combo.Items.Clear(); - foreach (GrammarItem item in this) - combo.Items.Add(item); - } - - }//class -} diff --git a/sources/shaders/Irony.GrammarExplorer/GrammarLoader.cs b/sources/shaders/Irony.GrammarExplorer/GrammarLoader.cs deleted file mode 100644 index 6f9804d360..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/GrammarLoader.cs +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Threading; -using System.Windows.Forms; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - /// - /// Maintains grammar assemblies, reloads updated files automatically. - /// - class GrammarLoader - { - private TimeSpan _autoRefreshDelay = TimeSpan.FromMilliseconds(1000); - private static HashSet _probingPaths = new HashSet(); - private readonly Dictionary _cachedGrammarAssemblies = new(); - private static Dictionary _loadedAssembliesByNames = new(); - private static HashSet _loadedAssemblies = new HashSet(); - private static bool _enableBrowsingForAssemblyResolution = false; - - static GrammarLoader() - { - AppDomain.CurrentDomain.AssemblyLoad += (sender, args) => _loadedAssembliesByNames[args.LoadedAssembly.FullName] = args.LoadedAssembly; - AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => FindAssembly(args.Name); - } - - static Assembly FindAssembly(string assemblyName) - { - if (_loadedAssembliesByNames.ContainsKey(assemblyName)) - return _loadedAssembliesByNames[assemblyName]; - // ignore resource assemblies - if (assemblyName.ToLower().Contains(".resources, version=")) - return _loadedAssembliesByNames[assemblyName] = null; - // use probing paths to look for dependency assemblies - var fileName = assemblyName.Split(',')[0] + ".dll"; - foreach (var path in _probingPaths) - { - var fullName = Path.Combine(path, fileName); - if (File.Exists(fullName)) - { - try - { - return LoadAssembly(fullName); - } - catch - { - // the file seems to be bad, let's try to find another one - } - } - } - // the last chance: try asking user to locate the assembly - if (_enableBrowsingForAssemblyResolution) - { - fileName = BrowseFor(assemblyName); - if (!string.IsNullOrWhiteSpace(fileName)) - return LoadAssembly(fileName); - } - // assembly not found, don't search for it again - return _loadedAssembliesByNames[assemblyName] = null; - } - - static string BrowseFor(string assemblyName) - { - var fileDialog = new OpenFileDialog - { - Title = "Please locate assembly: " + assemblyName, - Filter = "Assemblies (*.dll)|*.dll|All files (*.*)|*.*" - }; - using (fileDialog) - { - if (fileDialog.ShowDialog() == DialogResult.OK) - return fileDialog.FileName; - } - return null; - } - - class CachedAssembly - { - public long FileSize; - public DateTime LastWriteTime; - public FileSystemWatcher Watcher; - public Assembly Assembly; - public bool UpdateScheduled; - } - - public event EventHandler AssemblyUpdated; - - public GrammarItem SelectedGrammar { get; set; } - - public Grammar CreateGrammar() - { - if (SelectedGrammar == null) - return null; - - // resolve dependencies while loading and creating grammars - _enableBrowsingForAssemblyResolution = true; - try - { - var type = SelectedGrammarAssembly.GetType(SelectedGrammar.TypeName, true, true); - return Activator.CreateInstance(type) as Grammar; - } - finally - { - _enableBrowsingForAssemblyResolution = false; - } - } - - private Assembly SelectedGrammarAssembly - { - get - { - if (SelectedGrammar == null) - return null; - - // create assembly cache entry as needed - var location = SelectedGrammar.Location; - if (!_cachedGrammarAssemblies.ContainsKey(location)) - { - var fileInfo = new FileInfo(location); - _cachedGrammarAssemblies[location] = - new CachedAssembly - { - LastWriteTime = fileInfo.LastWriteTime, - FileSize = fileInfo.Length, - Assembly = null - }; - - // set up file system watcher - _cachedGrammarAssemblies[location].Watcher = CreateFileWatcher(location); - } - - // get loaded assembly from cache if possible - var assembly = _cachedGrammarAssemblies[location].Assembly; - if (assembly == null) - { - assembly = LoadAssembly(location); - _cachedGrammarAssemblies[location].Assembly = assembly; - } - - return assembly; - } - } - - private FileSystemWatcher CreateFileWatcher(string location) - { - var folder = Path.GetDirectoryName(location); - var watcher = new FileSystemWatcher(folder); - watcher.Filter = Path.GetFileName(location); - - watcher.Changed += (s, args) => { - if (args.ChangeType != WatcherChangeTypes.Changed) - return; - - lock (this) - { - // check if assembly file was changed indeed since the last event - var cacheEntry = _cachedGrammarAssemblies[location]; - var fileInfo = new FileInfo(location); - if (cacheEntry.LastWriteTime == fileInfo.LastWriteTime && cacheEntry.FileSize == fileInfo.Length) - return; - - // reset cached assembly and save last file update time - cacheEntry.LastWriteTime = fileInfo.LastWriteTime; - cacheEntry.FileSize = fileInfo.Length; - cacheEntry.Assembly = null; - - // check if file update is already scheduled (work around multiple FileSystemWatcher event firing) - if (!cacheEntry.UpdateScheduled) - { - cacheEntry.UpdateScheduled = true; - // delay auto-refresh to make sure the file is closed by the writer - ThreadPool.QueueUserWorkItem(_ => { - Thread.Sleep(_autoRefreshDelay); - cacheEntry.UpdateScheduled = false; - OnAssemblyUpdated(location); - }); - } - } - }; - - watcher.EnableRaisingEvents = true; - return watcher; - } - - private void OnAssemblyUpdated(string location) - { - if (AssemblyUpdated == null || SelectedGrammar == null || SelectedGrammar.Location != location) - return; - AssemblyUpdated(this, EventArgs.Empty); - } - - public static Assembly LoadAssembly(string fileName) - { - // normalize the filename - fileName = new FileInfo(fileName).FullName; - // save assembly path for dependent assemblies probing - var path = Path.GetDirectoryName(fileName); - _probingPaths.Add(path); - // try to load assembly using the standard policy - var assembly = Assembly.LoadFrom(fileName); - // if the standard policy returned the old version, force reload - if (_loadedAssemblies.Contains(assembly)) - { - assembly = Assembly.Load(File.ReadAllBytes(fileName)); - } - // cache the loaded assembly by its location - _loadedAssemblies.Add(assembly); - return assembly; - } - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/Highlighter/AboutCodeHighlighter.txt b/sources/shaders/Irony.GrammarExplorer/Highlighter/AboutCodeHighlighter.txt deleted file mode 100644 index 0563f4695a..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Highlighter/AboutCodeHighlighter.txt +++ /dev/null @@ -1 +0,0 @@ -This highlighter is not a real thing, just a sketch - good enough to highlight samples in Grammar Explorer \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorAdapter.cs b/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorAdapter.cs deleted file mode 100644 index 3b792ce89e..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorAdapter.cs +++ /dev/null @@ -1,168 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Diagnostics; -using System.Threading; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - - public class EditorAdapter - { - readonly Parser _parser; - readonly Scanner _scanner; - ParseTree _parseTree; - string _newText; - readonly EditorViewAdapterList _views = new EditorViewAdapterList(); - EditorViewAdapterList _viewsCopy; //copy used in refresh loop; set to null when views are added/removed - readonly Thread _parserThread; - readonly Thread _colorizerThread; - bool _stopped; - - public EditorAdapter(LanguageData language) - { - _parser = new Parser(language); - _scanner = _parser.Scanner; - _colorizerThread = new Thread(ColorizerLoop); - _colorizerThread.IsBackground = true; - _parserThread = new Thread(ParserLoop); - _parserThread.IsBackground = true; - } - public void Activate() - { - if ((_colorizerThread.ThreadState & System.Threading.ThreadState.Running) == 0) - { - _parserThread.Start(); - _colorizerThread.Start(); - } - } - - public void Stop() - { - try - { - _stopped = true; - _parserThread.Join(500); - if (_parserThread.IsAlive) - _parserThread.Interrupt(); - _colorizerThread.Join(500); - if (_colorizerThread.IsAlive) - _colorizerThread.Interrupt(); - } - catch (Exception ex) - { - Debug.WriteLine("Error when stopping EditorAdapter: " + ex.Message); - } - } - - public void SetNewText(string text) - { - text ??= string.Empty; //force it to become not null; null is special value meaning "no changes" - _newText = text; - } - - public ParseTree ParseTree - { - get { return _parseTree; } - } - - //Note: we don't actually parse in current version, only scan. Will implement full parsing in the future, - // to support all intellisense operations - private void ParseSource(string newText) - { - //Explicitly catch the case when new text is empty - if (newText != string.Empty) - { - _parseTree = _parser.Parse(newText);// .ScanOnly(newText, "Source"); - } - //notify views - var views = GetViews(); - foreach (var view in views) - view.UpdateParsedSource(_parseTree); - } - - - #region Views manipulation: AddView, RemoveView, GetViews - public void AddView(EditorViewAdapter view) - { - lock (this) - { - _views.Add(view); - _viewsCopy = null; - } - } - public void RemoveView(EditorViewAdapter view) - { - lock (this) - { - _views.Remove(view); - _viewsCopy = null; - } - } - private EditorViewAdapterList GetViews() - { - EditorViewAdapterList result = _viewsCopy; - if (result == null) - { - lock (this) - { - _viewsCopy = new EditorViewAdapterList(); - _viewsCopy.AddRange(_views); - result = _viewsCopy; - }//lock - } - return result; - } - #endregion - - private void ParserLoop() - { - while (!_stopped) - { - try - { - string newtext = Interlocked.Exchange(ref _newText, null); - if (newtext != null) - { - ParseSource(newtext); - } - Thread.Sleep(10); - } - catch (Exception ex) - { - fmShowException.ShowException(ex); - System.Windows.Forms.MessageBox.Show("Fatal error in code colorizer. Colorizing had been disabled."); - _stopped = true; - } - }//while - } - - private void ColorizerLoop() - { - while (!_stopped) - { - EditorViewAdapterList views = GetViews(); - //Go through views and invoke refresh - foreach (EditorViewAdapter view in views) - { - if (_stopped) break; - if (view.WantsColorize) - view.TryInvokeColorize(); - }//foreach - Thread.Sleep(10); - }// while !_stopped - }//method - - }//class -}//namespace diff --git a/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorViewAdapter.cs b/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorViewAdapter.cs deleted file mode 100644 index 829699c02b..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Highlighter/EditorViewAdapter.cs +++ /dev/null @@ -1,261 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Threading; - -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - public delegate void ColorizeMethod(); - public interface IUIThreadInvoker - { - void InvokeOnUIThread(ColorizeMethod colorize); - } - - public class ColorizeEventArgs : EventArgs - { - public readonly TokenList Tokens; - public ColorizeEventArgs(TokenList tokens) - { - Tokens = tokens; - } - } - - //Container for two numbers representing visible range of the source text (min...max) - // we use it to allow replacing two numbers in atomic operation - public class ViewRange - { - public readonly int Min, Max; - public ViewRange(int min, int max) - { - Min = min; - Max = max; - } - public bool Equals(ViewRange other) - { - return other.Min == Min && other.Max == Max; - } - } - - public class ViewData - { - // ColoredTokens + NotColoredTokens == Source.Tokens - public readonly TokenList ColoredTokens = new TokenList(); - public readonly TokenList NotColoredTokens = new TokenList(); //tokens not colored yet - public ParseTree Tree; - public ViewData(ParseTree tree) - { - Tree = tree; - if (tree == null) return; - NotColoredTokens.AddRange(tree.Tokens); - } - } - - //Two scenarios: - // 1. Colorizing in current view range. We colorize only those tokens in current view range that were not colorized yet. - // For this we keep two lists (colorized and not colorized) tokens, and move tokens from one list to another when - // we actually colorize them. - // 2. Typing/Editing - new editor content is being pushed from EditorAdapter. We try to avoid recoloring all visible tokens, when - // user just typed a single char. What we do is try to identify "already-colored" tokens in new token list by matching - // old viewData.ColoredTokens to newly scanned token list - initially in new-viewData.NonColoredTokens. If we find a "match", - // we move the token from NonColored to Colored in new viewData. This all happens on background thread. - - public class EditorViewAdapterList : List { } - - public class EditorViewAdapter - { - public readonly EditorAdapter Adapter; - private IUIThreadInvoker _invoker; - //public readonly Control Control; - ViewData _data; - ViewRange _range; - bool _wantsColorize; - int _colorizing; - public event EventHandler ColorizeTokens; - - public EditorViewAdapter(EditorAdapter adapter, IUIThreadInvoker invoker) - { - Adapter = adapter; - _invoker = invoker; - Adapter.AddView(this); - _range = new ViewRange(-1, -1); - } - - //SetViewRange and SetNewText are called by text box's event handlers to notify adapter that user did something edit box - public void SetViewRange(int min, int max) - { - _range = new ViewRange(min, max); - _wantsColorize = true; - } - //The new text is passed directly to EditorAdapter instance (possibly shared by several view adapters). - // EditorAdapter parses the text on a separate background thread, and notifies back this and other - // view adapters and provides them with newly parsed source through UpdateParsedSource method (see below) - public void SetNewText(string newText) - { - //TODO: fix this - //hack, temp solution for more general problem - //When we load/replace/clear entire text, clear out colored tokens to force recoloring from scratch - if (string.IsNullOrEmpty(newText)) - _data = null; - Adapter.SetNewText(newText); - } - - //Called by EditorAdapter to provide the latest parsed source - public void UpdateParsedSource(ParseTree newTree) - { - lock (this) - { - var oldData = _data; - _data = new ViewData(newTree); - //Now try to figure out tokens that match old Colored tokens - if (oldData != null && oldData.Tree != null) - { - DetectAlreadyColoredTokens(oldData.ColoredTokens, _data.Tree.SourceText.Length - oldData.Tree.SourceText.Length); - } - _wantsColorize = true; - }//lock - } - - - #region Colorizing - public bool WantsColorize - { - get { return _wantsColorize; } - } - - public void TryInvokeColorize() - { - if (!_wantsColorize) return; - int colorizing = Interlocked.Exchange(ref _colorizing, 1); - if (colorizing != 0) return; - _invoker.InvokeOnUIThread(Colorize); - } - private void Colorize() - { - var range = _range; - var data = _data; - if (data != null) - { - TokenList tokensToColor; - lock (this) - { - tokensToColor = ExtractTokensInRange(data.NotColoredTokens, range.Min, range.Max); - } - if (ColorizeTokens != null && tokensToColor != null && tokensToColor.Count > 0) - { - data.ColoredTokens.AddRange(tokensToColor); - ColorizeEventArgs args = new ColorizeEventArgs(tokensToColor); - ColorizeTokens(this, args); - } - }//if data != null ... - _wantsColorize = false; - _colorizing = 0; - } - - private void DetectAlreadyColoredTokens(TokenList oldColoredTokens, int shift) - { - foreach (Token oldColored in oldColoredTokens) - { - if (FindMatchingToken(_data.NotColoredTokens, oldColored, 0, out var index, out var newColored) || - FindMatchingToken(_data.NotColoredTokens, oldColored, shift, out index, out newColored)) - { - _data.NotColoredTokens.RemoveAt(index); - _data.ColoredTokens.Add(newColored); - } - }//foreach - } - - #endregion - - #region token utilities - private bool FindMatchingToken(TokenList inTokens, Token token, int shift, out int index, out Token result) - { - index = LocateToken(inTokens, token.Location.Position + shift); - if (index >= 0) - { - result = inTokens[index]; - if (TokensMatch(token, result, shift)) return true; - } - index = -1; - result = null; - return false; - } - public bool TokensMatch(Token x, Token y, int shift) - { - if (x.Location.Position + shift != y.Location.Position) return false; - if (x.Terminal != y.Terminal) return false; - if (x.Text != y.Text) return false; - //Note: be careful comparing x.Value and y.Value - if value is "ValueType", it is boxed and erroneously reports non-equal - //if (x.ValueString != y.ValueString) return false; - return true; - } - public TokenList ExtractTokensInRange(TokenList tokens, int from, int until) - { - TokenList result = new TokenList(); - for (int i = tokens.Count - 1; i >= 0; i--) - { - var tkn = tokens[i]; - if (tkn.Location.Position > until || (tkn.Location.Position + tkn.Length < from)) continue; - result.Add(tkn); - tokens.RemoveAt(i); - } - return result; - } - - public TokenList GetTokensInRange(int from, int until) - { - ViewData data = _data; - if (data == null) return null; - return GetTokensInRange(data.Tree.Tokens, from, until); - } - public TokenList GetTokensInRange(TokenList tokens, int from, int until) - { - TokenList result = new TokenList(); - int fromIndex = LocateToken(tokens, from); - int untilIndex = LocateToken(tokens, until); - if (fromIndex < 0) fromIndex = 0; - if (untilIndex >= tokens.Count) untilIndex = tokens.Count - 1; - for (int i = fromIndex; i <= untilIndex; i++) - { - result.Add(tokens[i]); - } - return result; - } - - //TODO: find better place for these methods - public int LocateToken(TokenList tokens, int position) - { - if (tokens == null || tokens.Count == 0) return -1; - var lastToken = tokens[tokens.Count - 1]; - var lastTokenEnd = lastToken.Location.Position + lastToken.Length; - if (position < tokens[0].Location.Position || position > lastTokenEnd) return -1; - return LocateTokenExt(tokens, position, 0, tokens.Count - 1); - } - private int LocateTokenExt(TokenList tokens, int position, int fromIndex, int untilIndex) - { - if (fromIndex + 1 >= untilIndex) return fromIndex; - int midIndex = (fromIndex + untilIndex) / 2; - Token middleToken = tokens[midIndex]; - if (middleToken.Location.Position <= position) - return LocateTokenExt(tokens, position, midIndex, untilIndex); - else - return LocateTokenExt(tokens, position, fromIndex, midIndex); - } - #endregion - - - }//EditorViewAdapter class - -}//namespace diff --git a/sources/shaders/Irony.GrammarExplorer/Highlighter/RichTextBoxHighlighter.cs b/sources/shaders/Irony.GrammarExplorer/Highlighter/RichTextBoxHighlighter.cs deleted file mode 100644 index 22abe41055..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Highlighter/RichTextBoxHighlighter.cs +++ /dev/null @@ -1,271 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -// Aknowledgments -// This module borrows code and ideas from TinyPG framework by Herre Kuijpers, -// specifically TextMarker.cs and TextHighlighter.cs classes. -// http://www.codeproject.com/KB/recipes/TinyPG.aspx -// -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading; -using System.Windows.Forms; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - - public class TokenColorTable : Dictionary { } - - public class RichTextBoxHighlighter : NativeWindow, IDisposable, IUIThreadInvoker - { - public RichTextBox TextBox; - public readonly TokenColorTable TokenColors = new TokenColorTable(); - public readonly EditorAdapter Adapter; - public readonly EditorViewAdapter ViewAdapter; - - private IntPtr _savedEventMask = IntPtr.Zero; - bool _colorizing; - bool _disposed; - - #region constructor, initialization and disposing - public RichTextBoxHighlighter(RichTextBox textBox, LanguageData language) - { - TextBox = textBox; - Adapter = new EditorAdapter(language); - ViewAdapter = new EditorViewAdapter(Adapter, this); - InitColorTable(); - Connect(); - UpdateViewRange(); - ViewAdapter.SetNewText(TextBox.Text); - } - private void Connect() - { - TextBox.MouseMove += TextBox_MouseMove; - TextBox.TextChanged += TextBox_TextChanged; - TextBox.KeyDown += TextBox_KeyDown; - TextBox.VScroll += TextBox_ScrollResize; - TextBox.HScroll += TextBox_ScrollResize; - TextBox.SizeChanged += TextBox_ScrollResize; - TextBox.Disposed += TextBox_Disposed; - ViewAdapter.ColorizeTokens += Adapter_ColorizeTokens; - this.AssignHandle(TextBox.Handle); - } - - private void Disconnect() - { - if (TextBox != null) - { - TextBox.MouseMove -= TextBox_MouseMove; - TextBox.TextChanged -= TextBox_TextChanged; - TextBox.KeyDown -= TextBox_KeyDown; - TextBox.Disposed -= TextBox_Disposed; - TextBox.VScroll -= TextBox_ScrollResize; - TextBox.HScroll -= TextBox_ScrollResize; - TextBox.SizeChanged -= TextBox_ScrollResize; - } - TextBox = null; - } - - public void Dispose() - { - Adapter.Stop(); - _disposed = true; - Disconnect(); - this.ReleaseHandle(); - GC.SuppressFinalize(this); - - } - private void InitColorTable() - { - TokenColors[TokenColor.Comment] = Color.Green; - TokenColors[TokenColor.Identifier] = Color.Black; - TokenColors[TokenColor.Keyword] = Color.Blue; - TokenColors[TokenColor.Number] = Color.DarkRed; - TokenColors[TokenColor.String] = Color.DarkSlateGray; - TokenColors[TokenColor.Text] = Color.Black; - - } - #endregion - - #region TextBox event handlers - - void TextBox_MouseMove(object sender, MouseEventArgs e) - { - //TODO: implement showing tip - } - - void TextBox_KeyDown(object sender, KeyEventArgs e) - { - //TODO: implement showing intellisense hints or drop-downs - } - - void TextBox_TextChanged(object sender, EventArgs e) - { - //if we are here while colorizing, it means the "change" event is a result of our coloring action - if (_colorizing) return; - ViewAdapter.SetNewText(TextBox.Text); - } - void TextBox_ScrollResize(object sender, EventArgs e) - { - UpdateViewRange(); - } - - - void TextBox_Disposed(object sender, EventArgs e) - { - Dispose(); - } - private void UpdateViewRange() - { - int minpos = TextBox.GetCharIndexFromPosition(new Point(0, 0)); - int maxpos = TextBox.GetCharIndexFromPosition(new Point(TextBox.ClientSize.Width, TextBox.ClientSize.Height)); - ViewAdapter.SetViewRange(minpos, maxpos); - } - #endregion - - #region WinAPI - // some winapís required - [DllImport("user32", CharSet = CharSet.Auto)] - private extern static IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam); - - [DllImport("user32.dll")] - private static extern bool PostMessageA(IntPtr hWnd, int nBar, int wParam, int lParam); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - private static extern int GetScrollPos(int hWnd, int nBar); - - [DllImport("user32.dll")] - private static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); - - private const int WM_SETREDRAW = 0x000B; - private const int WM_USER = 0x400; - private const int EM_GETEVENTMASK = (WM_USER + 59); - private const int EM_SETEVENTMASK = (WM_USER + 69); - private const int SB_HORZ = 0x0; - private const int SB_VERT = 0x1; - private const int WM_HSCROLL = 0x114; - private const int WM_VSCROLL = 0x115; - private const int SB_THUMBPOSITION = 4; - const int WM_PAINT = 0x000F; - - private int HScrollPos - { - get - { - //sometimes explodes with null reference exception - return GetScrollPos((int)TextBox.Handle, SB_HORZ); - } - set - { - SetScrollPos((IntPtr)TextBox.Handle, SB_HORZ, value, true); - PostMessageA((IntPtr)TextBox.Handle, WM_HSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); - } - } - - private int VScrollPos - { - get - { - return GetScrollPos((int)TextBox.Handle, SB_VERT); - } - set - { - SetScrollPos((IntPtr)TextBox.Handle, SB_VERT, value, true); - PostMessageA((IntPtr)TextBox.Handle, WM_VSCROLL, SB_THUMBPOSITION + 0x10000 * value, 0); - } - } - #endregion - - #region Colorizing tokens - public void LockTextBox() - { - // Stop redrawing: - SendMessage(TextBox.Handle, WM_SETREDRAW, 0, IntPtr.Zero); - // Stop sending of events: - _savedEventMask = SendMessage(TextBox.Handle, EM_GETEVENTMASK, 0, IntPtr.Zero); - //SendMessage(TextBox.Handle, EM_SETEVENTMASK, 0, IntPtr.Zero); - } - - public void UnlockTextBox() - { - // turn on events - SendMessage(TextBox.Handle, EM_SETEVENTMASK, 0, _savedEventMask); - // turn on redrawing - SendMessage(TextBox.Handle, WM_SETREDRAW, 1, IntPtr.Zero); - } - - void Adapter_ColorizeTokens(object sender, ColorizeEventArgs args) - { - if (_disposed) return; - //Debug.WriteLine("Coloring " + args.Tokens.Count + " tokens."); - _colorizing = true; - - int hscroll = HScrollPos; - int vscroll = VScrollPos; - int selstart = TextBox.SelectionStart; - int selLength = TextBox.SelectionLength; - LockTextBox(); - try - { - foreach (Token tkn in args.Tokens) - { - Color color = GetTokenColor(tkn); - TextBox.Select(tkn.Location.Position, tkn.Length); - TextBox.SelectionColor = color; - } - } - finally - { - TextBox.Select(selstart, selLength); - HScrollPos = hscroll; - VScrollPos = vscroll; - UnlockTextBox(); - _colorizing = false; - } - TextBox.Invalidate(); - } - - private Color GetTokenColor(Token token) - { - if (token.EditorInfo == null) return Color.Black; - //Right now we scan source, not parse; initially all keywords are recognized as Identifiers; then they are "backpatched" - // by parser when it detects that it is in fact keyword from Grammar. So now this backpatching does not happen, - // so we have to detect keywords here - var colorIndex = token.EditorInfo.Color; - if (token.KeyTerm != null && token.KeyTerm.EditorInfo != null && token.KeyTerm.FlagIsSet(TermFlags.IsKeyword)) - { - colorIndex = token.KeyTerm.EditorInfo.Color; - }//if - Color result; - if (TokenColors.TryGetValue(colorIndex, out result)) return result; - return Color.Black; - } - #endregion - - - #region IUIThreadInvoker Members - - public void InvokeOnUIThread(ColorizeMethod colorize) - { - TextBox.BeginInvoke(new MethodInvoker(colorize)); - } - - #endregion - }//class - -}//namespace diff --git a/sources/shaders/Irony.GrammarExplorer/Irony.GrammarExplorer.csproj b/sources/shaders/Irony.GrammarExplorer/Irony.GrammarExplorer.csproj deleted file mode 100644 index eba71c608f..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Irony.GrammarExplorer.csproj +++ /dev/null @@ -1,66 +0,0 @@ - - - - WinExe - net10.0-windows - True - - - - Form - - - fmGrammarExplorer.cs - - - Form - - - fmSelectGrammars.cs - - - fmGrammarExplorer.cs - Designer - - - fmSelectGrammars.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - Designer - fmShowException.cs - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - Form - - - fmShowException.cs - - - - - - - - - - \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/Program.cs b/sources/shaders/Irony.GrammarExplorer/Program.cs deleted file mode 100644 index 3d75b5b6df..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Windows.Forms; - -namespace Irony.GrammarExplorer -{ - class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - Application.Run(new fmGrammarExplorer()); - } - - static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) - { - fmShowException.ShowException(e.Exception); - Debug.Write("Exception!: ############################################## \n" + e.Exception.ToString()); - } - - static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - Exception ex = e.ExceptionObject as Exception; - string message = (ex == null ? e.ExceptionObject.ToString() : ex.Message); - if (ex == null) - { - Debug.Write("Exception!: ############################################## \n" + e.ExceptionObject.ToString()); - MessageBox.Show(message, "Exception"); - } - else - { - fmShowException.ShowException(ex); - } - } - - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/Properties/AssemblyInfo.cs b/sources/shaders/Irony.GrammarExplorer/Properties/AssemblyInfo.cs deleted file mode 100644 index 80056da958..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("09b192b9-9b3a-470b-a753-9f9c32bd81bc")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/sources/shaders/Irony.GrammarExplorer/Properties/Resources.Designer.cs b/sources/shaders/Irony.GrammarExplorer/Properties/Resources.Designer.cs deleted file mode 100644 index 12850f9914..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18033 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Irony.GrammarExplorer.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Irony.GrammarExplorer.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/Properties/Resources.resx b/sources/shaders/Irony.GrammarExplorer/Properties/Resources.resx deleted file mode 100644 index af7dbebbac..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/Properties/Settings.Designer.cs b/sources/shaders/Irony.GrammarExplorer/Properties/Settings.Designer.cs deleted file mode 100644 index c009c7e4b2..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Properties/Settings.Designer.cs +++ /dev/null @@ -1,110 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.18033 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Irony.GrammarExplorer.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string SourceSample { - get { - return ((string)(this["SourceSample"])); - } - set { - this["SourceSample"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("0")] - public int LanguageIndex { - get { - return ((int)(this["LanguageIndex"])); - } - set { - this["LanguageIndex"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string SearchPattern { - get { - return ((string)(this["SearchPattern"])); - } - set { - this["SearchPattern"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string Grammars { - get { - return ((string)(this["Grammars"])); - } - set { - this["Grammars"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool EnableTrace { - get { - return ((bool)(this["EnableTrace"])); - } - set { - this["EnableTrace"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool DisableHili { - get { - return ((bool)(this["DisableHili"])); - } - set { - this["DisableHili"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("True")] - public bool AutoRefresh { - get { - return ((bool)(this["AutoRefresh"])); - } - set { - this["AutoRefresh"] = value; - } - } - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/Properties/Settings.settings b/sources/shaders/Irony.GrammarExplorer/Properties/Settings.settings deleted file mode 100644 index 803e72f038..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/Properties/Settings.settings +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - 0 - - - - - - - - - False - - - False - - - True - - - \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/app.config b/sources/shaders/Irony.GrammarExplorer/app.config deleted file mode 100644 index 9088f2a145..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/app.config +++ /dev/null @@ -1,34 +0,0 @@ - - - - -
- - - - - - - - - 0 - - - - - - - - - False - - - False - - - True - - - - - diff --git a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.Designer.cs b/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.Designer.cs deleted file mode 100644 index 01de925b3d..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.Designer.cs +++ /dev/null @@ -1,1347 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Irony.GrammarExplorer { - partial class fmGrammarExplorer { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle3 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle4 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle5 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle6 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle7 = new System.Windows.Forms.DataGridViewCellStyle(); - System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle8 = new System.Windows.Forms.DataGridViewCellStyle(); - this.tabGrammar = new System.Windows.Forms.TabControl(); - this.pageTerminals = new System.Windows.Forms.TabPage(); - this.txtTerms = new System.Windows.Forms.TextBox(); - this.pageNonTerms = new System.Windows.Forms.TabPage(); - this.txtNonTerms = new System.Windows.Forms.TextBox(); - this.pageParserStates = new System.Windows.Forms.TabPage(); - this.txtParserStates = new System.Windows.Forms.TextBox(); - this.pageTest = new System.Windows.Forms.TabPage(); - this.txtSource = new System.Windows.Forms.RichTextBox(); - this.panel1 = new System.Windows.Forms.Panel(); - this.chkDisableHili = new System.Windows.Forms.CheckBox(); - this.btnToXml = new System.Windows.Forms.Button(); - this.btnRun = new System.Windows.Forms.Button(); - this.btnFileOpen = new System.Windows.Forms.Button(); - this.btnParse = new System.Windows.Forms.Button(); - this.splitter3 = new System.Windows.Forms.Splitter(); - this.tabOutput = new System.Windows.Forms.TabControl(); - this.pageSyntaxTree = new System.Windows.Forms.TabPage(); - this.tvParseTree = new System.Windows.Forms.TreeView(); - this.pageAst = new System.Windows.Forms.TabPage(); - this.tvAst = new System.Windows.Forms.TreeView(); - this.chkParserTrace = new System.Windows.Forms.CheckBox(); - this.pnlLang = new System.Windows.Forms.Panel(); - this.chkAutoRefresh = new System.Windows.Forms.CheckBox(); - this.btnManageGrammars = new System.Windows.Forms.Button(); - this.lblSearchError = new System.Windows.Forms.Label(); - this.btnSearch = new System.Windows.Forms.Button(); - this.txtSearch = new System.Windows.Forms.TextBox(); - this.label2 = new System.Windows.Forms.Label(); - this.cboGrammars = new System.Windows.Forms.ComboBox(); - this.menuGrammars = new System.Windows.Forms.ContextMenuStrip(this.components); - this.miAdd = new System.Windows.Forms.ToolStripMenuItem(); - this.miRemove = new System.Windows.Forms.ToolStripMenuItem(); - this.miRemoveAll = new System.Windows.Forms.ToolStripMenuItem(); - this.dlgOpenFile = new System.Windows.Forms.OpenFileDialog(); - this.dlgSelectAssembly = new System.Windows.Forms.OpenFileDialog(); - this.splitBottom = new System.Windows.Forms.Splitter(); - this.tabBottom = new System.Windows.Forms.TabControl(); - this.pageLanguage = new System.Windows.Forms.TabPage(); - this.grpLanguageInfo = new System.Windows.Forms.GroupBox(); - this.label8 = new System.Windows.Forms.Label(); - this.lblParserStateCount = new System.Windows.Forms.Label(); - this.lblLanguageDescr = new System.Windows.Forms.Label(); - this.txtGrammarComments = new System.Windows.Forms.TextBox(); - this.label11 = new System.Windows.Forms.Label(); - this.label9 = new System.Windows.Forms.Label(); - this.lblLanguageVersion = new System.Windows.Forms.Label(); - this.label10 = new System.Windows.Forms.Label(); - this.lblLanguage = new System.Windows.Forms.Label(); - this.label4 = new System.Windows.Forms.Label(); - this.label6 = new System.Windows.Forms.Label(); - this.lblParserConstrTime = new System.Windows.Forms.Label(); - this.pageGrammarErrors = new System.Windows.Forms.TabPage(); - this.gridGrammarErrors = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn2 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn5 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn6 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.pageParserOutput = new System.Windows.Forms.TabPage(); - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.gridCompileErrors = new System.Windows.Forms.DataGridView(); - this.dataGridViewTextBoxColumn3 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn4 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.dataGridViewTextBoxColumn1 = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.grpCompileInfo = new System.Windows.Forms.GroupBox(); - this.label12 = new System.Windows.Forms.Label(); - this.lblParseErrorCount = new System.Windows.Forms.Label(); - this.label1 = new System.Windows.Forms.Label(); - this.lblParseTime = new System.Windows.Forms.Label(); - this.label7 = new System.Windows.Forms.Label(); - this.lblSrcLineCount = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.lblSrcTokenCount = new System.Windows.Forms.Label(); - this.pageParserTrace = new System.Windows.Forms.TabPage(); - this.grpParserActions = new System.Windows.Forms.GroupBox(); - this.gridParserTrace = new System.Windows.Forms.DataGridView(); - this.State = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Stack = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Input = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.Action = new System.Windows.Forms.DataGridViewTextBoxColumn(); - this.splitter1 = new System.Windows.Forms.Splitter(); - this.grpTokens = new System.Windows.Forms.GroupBox(); - this.lstTokens = new System.Windows.Forms.ListBox(); - this.pnlParserTraceTop = new System.Windows.Forms.Panel(); - this.chkExcludeComments = new System.Windows.Forms.CheckBox(); - this.lblTraceComment = new System.Windows.Forms.Label(); - this.pageOutput = new System.Windows.Forms.TabPage(); - this.txtOutput = new System.Windows.Forms.TextBox(); - this.pnlRuntimeInfo = new System.Windows.Forms.Panel(); - this.label13 = new System.Windows.Forms.Label(); - this.lnkShowErrStack = new System.Windows.Forms.LinkLabel(); - this.lnkShowErrLocation = new System.Windows.Forms.LinkLabel(); - this.label5 = new System.Windows.Forms.Label(); - this.lblRunTime = new System.Windows.Forms.Label(); - this.tabGrammar.SuspendLayout(); - this.pageTerminals.SuspendLayout(); - this.pageNonTerms.SuspendLayout(); - this.pageParserStates.SuspendLayout(); - this.pageTest.SuspendLayout(); - this.panel1.SuspendLayout(); - this.tabOutput.SuspendLayout(); - this.pageSyntaxTree.SuspendLayout(); - this.pageAst.SuspendLayout(); - this.pnlLang.SuspendLayout(); - this.menuGrammars.SuspendLayout(); - this.tabBottom.SuspendLayout(); - this.pageLanguage.SuspendLayout(); - this.grpLanguageInfo.SuspendLayout(); - this.pageGrammarErrors.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.gridGrammarErrors)).BeginInit(); - this.pageParserOutput.SuspendLayout(); - this.groupBox1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.gridCompileErrors)).BeginInit(); - this.grpCompileInfo.SuspendLayout(); - this.pageParserTrace.SuspendLayout(); - this.grpParserActions.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.gridParserTrace)).BeginInit(); - this.grpTokens.SuspendLayout(); - this.pnlParserTraceTop.SuspendLayout(); - this.pageOutput.SuspendLayout(); - this.pnlRuntimeInfo.SuspendLayout(); - this.SuspendLayout(); - // - // tabGrammar - // - this.tabGrammar.Controls.Add(this.pageTerminals); - this.tabGrammar.Controls.Add(this.pageNonTerms); - this.tabGrammar.Controls.Add(this.pageParserStates); - this.tabGrammar.Controls.Add(this.pageTest); - this.tabGrammar.Dock = System.Windows.Forms.DockStyle.Fill; - this.tabGrammar.Location = new System.Drawing.Point(0, 29); - this.tabGrammar.Name = "tabGrammar"; - this.tabGrammar.SelectedIndex = 0; - this.tabGrammar.Size = new System.Drawing.Size(1104, 464); - this.tabGrammar.TabIndex = 0; - // - // pageTerminals - // - this.pageTerminals.Controls.Add(this.txtTerms); - this.pageTerminals.Location = new System.Drawing.Point(4, 22); - this.pageTerminals.Name = "pageTerminals"; - this.pageTerminals.Padding = new System.Windows.Forms.Padding(3); - this.pageTerminals.Size = new System.Drawing.Size(1096, 438); - this.pageTerminals.TabIndex = 5; - this.pageTerminals.Text = "Terminals"; - this.pageTerminals.UseVisualStyleBackColor = true; - // - // txtTerms - // - this.txtTerms.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtTerms.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtTerms.HideSelection = false; - this.txtTerms.Location = new System.Drawing.Point(3, 3); - this.txtTerms.Multiline = true; - this.txtTerms.Name = "txtTerms"; - this.txtTerms.ReadOnly = true; - this.txtTerms.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.txtTerms.Size = new System.Drawing.Size(1090, 432); - this.txtTerms.TabIndex = 2; - // - // pageNonTerms - // - this.pageNonTerms.Controls.Add(this.txtNonTerms); - this.pageNonTerms.Location = new System.Drawing.Point(4, 22); - this.pageNonTerms.Name = "pageNonTerms"; - this.pageNonTerms.Padding = new System.Windows.Forms.Padding(3); - this.pageNonTerms.Size = new System.Drawing.Size(1096, 438); - this.pageNonTerms.TabIndex = 0; - this.pageNonTerms.Text = "Non-Terminals"; - this.pageNonTerms.UseVisualStyleBackColor = true; - // - // txtNonTerms - // - this.txtNonTerms.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtNonTerms.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtNonTerms.HideSelection = false; - this.txtNonTerms.Location = new System.Drawing.Point(3, 3); - this.txtNonTerms.Multiline = true; - this.txtNonTerms.Name = "txtNonTerms"; - this.txtNonTerms.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.txtNonTerms.Size = new System.Drawing.Size(1090, 432); - this.txtNonTerms.TabIndex = 1; - this.txtNonTerms.WordWrap = false; - // - // pageParserStates - // - this.pageParserStates.Controls.Add(this.txtParserStates); - this.pageParserStates.Location = new System.Drawing.Point(4, 22); - this.pageParserStates.Name = "pageParserStates"; - this.pageParserStates.Padding = new System.Windows.Forms.Padding(3); - this.pageParserStates.Size = new System.Drawing.Size(1096, 438); - this.pageParserStates.TabIndex = 1; - this.pageParserStates.Text = "Parser States"; - this.pageParserStates.UseVisualStyleBackColor = true; - // - // txtParserStates - // - this.txtParserStates.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtParserStates.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtParserStates.HideSelection = false; - this.txtParserStates.Location = new System.Drawing.Point(3, 3); - this.txtParserStates.Multiline = true; - this.txtParserStates.Name = "txtParserStates"; - this.txtParserStates.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.txtParserStates.Size = new System.Drawing.Size(1090, 432); - this.txtParserStates.TabIndex = 2; - this.txtParserStates.WordWrap = false; - // - // pageTest - // - this.pageTest.Controls.Add(this.txtSource); - this.pageTest.Controls.Add(this.panel1); - this.pageTest.Controls.Add(this.splitter3); - this.pageTest.Controls.Add(this.tabOutput); - this.pageTest.Location = new System.Drawing.Point(4, 22); - this.pageTest.Name = "pageTest"; - this.pageTest.Padding = new System.Windows.Forms.Padding(3); - this.pageTest.Size = new System.Drawing.Size(1096, 438); - this.pageTest.TabIndex = 4; - this.pageTest.Text = "Test"; - this.pageTest.UseVisualStyleBackColor = true; - // - // txtSource - // - this.txtSource.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtSource.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtSource.HideSelection = false; - this.txtSource.Location = new System.Drawing.Point(3, 33); - this.txtSource.Name = "txtSource"; - this.txtSource.Size = new System.Drawing.Size(734, 402); - this.txtSource.TabIndex = 22; - this.txtSource.Text = ""; - this.txtSource.TextChanged += new System.EventHandler(this.txtSource_TextChanged); - // - // panel1 - // - this.panel1.Controls.Add(this.chkDisableHili); - this.panel1.Controls.Add(this.btnToXml); - this.panel1.Controls.Add(this.btnRun); - this.panel1.Controls.Add(this.btnFileOpen); - this.panel1.Controls.Add(this.btnParse); - this.panel1.Dock = System.Windows.Forms.DockStyle.Top; - this.panel1.Location = new System.Drawing.Point(3, 3); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(734, 30); - this.panel1.TabIndex = 2; - // - // chkDisableHili - // - this.chkDisableHili.AutoSize = true; - this.chkDisableHili.Location = new System.Drawing.Point(5, 7); - this.chkDisableHili.Name = "chkDisableHili"; - this.chkDisableHili.Size = new System.Drawing.Size(150, 17); - this.chkDisableHili.TabIndex = 9; - this.chkDisableHili.Text = "Disable syntax highlighting"; - this.chkDisableHili.UseVisualStyleBackColor = true; - this.chkDisableHili.CheckedChanged += new System.EventHandler(this.chkDisableHili_CheckedChanged); - // - // btnToXml - // - this.btnToXml.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnToXml.Location = new System.Drawing.Point(655, 3); - this.btnToXml.Name = "btnToXml"; - this.btnToXml.Size = new System.Drawing.Size(65, 23); - this.btnToXml.TabIndex = 8; - this.btnToXml.Text = "->XML"; - this.btnToXml.UseVisualStyleBackColor = true; - this.btnToXml.Click += new System.EventHandler(this.btnToXml_Click); - // - // btnRun - // - this.btnRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnRun.Location = new System.Drawing.Point(584, 3); - this.btnRun.Name = "btnRun"; - this.btnRun.Size = new System.Drawing.Size(65, 23); - this.btnRun.TabIndex = 7; - this.btnRun.Text = "Run"; - this.btnRun.UseVisualStyleBackColor = true; - this.btnRun.Click += new System.EventHandler(this.btnRun_Click); - // - // btnFileOpen - // - this.btnFileOpen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnFileOpen.Location = new System.Drawing.Point(440, 3); - this.btnFileOpen.Name = "btnFileOpen"; - this.btnFileOpen.Size = new System.Drawing.Size(65, 23); - this.btnFileOpen.TabIndex = 6; - this.btnFileOpen.Text = "Load ..."; - this.btnFileOpen.UseVisualStyleBackColor = true; - this.btnFileOpen.Click += new System.EventHandler(this.btnFileOpen_Click); - // - // btnParse - // - this.btnParse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnParse.Location = new System.Drawing.Point(511, 3); - this.btnParse.Name = "btnParse"; - this.btnParse.Size = new System.Drawing.Size(67, 23); - this.btnParse.TabIndex = 1; - this.btnParse.Text = "Parse"; - this.btnParse.UseVisualStyleBackColor = true; - this.btnParse.Click += new System.EventHandler(this.btnParse_Click); - // - // splitter3 - // - this.splitter3.Dock = System.Windows.Forms.DockStyle.Right; - this.splitter3.Location = new System.Drawing.Point(737, 3); - this.splitter3.Name = "splitter3"; - this.splitter3.Size = new System.Drawing.Size(6, 432); - this.splitter3.TabIndex = 14; - this.splitter3.TabStop = false; - // - // tabOutput - // - this.tabOutput.Controls.Add(this.pageSyntaxTree); - this.tabOutput.Controls.Add(this.pageAst); - this.tabOutput.Dock = System.Windows.Forms.DockStyle.Right; - this.tabOutput.Location = new System.Drawing.Point(743, 3); - this.tabOutput.Name = "tabOutput"; - this.tabOutput.SelectedIndex = 0; - this.tabOutput.Size = new System.Drawing.Size(350, 432); - this.tabOutput.TabIndex = 13; - // - // pageSyntaxTree - // - this.pageSyntaxTree.Controls.Add(this.tvParseTree); - this.pageSyntaxTree.ForeColor = System.Drawing.SystemColors.ControlText; - this.pageSyntaxTree.Location = new System.Drawing.Point(4, 22); - this.pageSyntaxTree.Name = "pageSyntaxTree"; - this.pageSyntaxTree.Padding = new System.Windows.Forms.Padding(3); - this.pageSyntaxTree.Size = new System.Drawing.Size(342, 406); - this.pageSyntaxTree.TabIndex = 1; - this.pageSyntaxTree.Text = "Parse Tree"; - this.pageSyntaxTree.UseVisualStyleBackColor = true; - // - // tvParseTree - // - this.tvParseTree.Dock = System.Windows.Forms.DockStyle.Fill; - this.tvParseTree.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.tvParseTree.Indent = 16; - this.tvParseTree.Location = new System.Drawing.Point(3, 3); - this.tvParseTree.Name = "tvParseTree"; - this.tvParseTree.Size = new System.Drawing.Size(336, 400); - this.tvParseTree.TabIndex = 0; - this.tvParseTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvParseTree_AfterSelect); - // - // pageAst - // - this.pageAst.Controls.Add(this.tvAst); - this.pageAst.Location = new System.Drawing.Point(4, 22); - this.pageAst.Name = "pageAst"; - this.pageAst.Padding = new System.Windows.Forms.Padding(3); - this.pageAst.Size = new System.Drawing.Size(342, 406); - this.pageAst.TabIndex = 0; - this.pageAst.Text = "AST"; - this.pageAst.UseVisualStyleBackColor = true; - // - // tvAst - // - this.tvAst.Dock = System.Windows.Forms.DockStyle.Fill; - this.tvAst.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.tvAst.Indent = 16; - this.tvAst.Location = new System.Drawing.Point(3, 3); - this.tvAst.Name = "tvAst"; - this.tvAst.Size = new System.Drawing.Size(336, 400); - this.tvAst.TabIndex = 1; - this.tvAst.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.tvAst_AfterSelect); - // - // chkParserTrace - // - this.chkParserTrace.AutoSize = true; - this.chkParserTrace.Location = new System.Drawing.Point(3, 3); - this.chkParserTrace.Name = "chkParserTrace"; - this.chkParserTrace.Size = new System.Drawing.Size(90, 17); - this.chkParserTrace.TabIndex = 0; - this.chkParserTrace.Text = "Enable Trace"; - this.chkParserTrace.UseVisualStyleBackColor = true; - // - // pnlLang - // - this.pnlLang.Controls.Add(this.chkAutoRefresh); - this.pnlLang.Controls.Add(this.btnManageGrammars); - this.pnlLang.Controls.Add(this.lblSearchError); - this.pnlLang.Controls.Add(this.btnSearch); - this.pnlLang.Controls.Add(this.txtSearch); - this.pnlLang.Controls.Add(this.label2); - this.pnlLang.Controls.Add(this.cboGrammars); - this.pnlLang.Dock = System.Windows.Forms.DockStyle.Top; - this.pnlLang.Location = new System.Drawing.Point(0, 0); - this.pnlLang.Name = "pnlLang"; - this.pnlLang.Size = new System.Drawing.Size(1104, 29); - this.pnlLang.TabIndex = 13; - // - // chkAutoRefresh - // - this.chkAutoRefresh.AutoSize = true; - this.chkAutoRefresh.Checked = true; - this.chkAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkAutoRefresh.Location = new System.Drawing.Point(323, 5); - this.chkAutoRefresh.Name = "chkAutoRefresh"; - this.chkAutoRefresh.Size = new System.Drawing.Size(83, 17); - this.chkAutoRefresh.TabIndex = 13; - this.chkAutoRefresh.Text = "Auto-refresh"; - this.chkAutoRefresh.UseVisualStyleBackColor = true; - // - // btnManageGrammars - // - this.btnManageGrammars.Location = new System.Drawing.Point(281, 2); - this.btnManageGrammars.Margin = new System.Windows.Forms.Padding(2); - this.btnManageGrammars.Name = "btnManageGrammars"; - this.btnManageGrammars.Size = new System.Drawing.Size(28, 24); - this.btnManageGrammars.TabIndex = 12; - this.btnManageGrammars.Text = "..."; - this.btnManageGrammars.UseVisualStyleBackColor = true; - this.btnManageGrammars.Click += new System.EventHandler(this.btnManageGrammars_Click); - // - // lblSearchError - // - this.lblSearchError.AutoSize = true; - this.lblSearchError.ForeColor = System.Drawing.Color.Red; - this.lblSearchError.Location = new System.Drawing.Point(731, 9); - this.lblSearchError.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.lblSearchError.Name = "lblSearchError"; - this.lblSearchError.Size = new System.Drawing.Size(54, 13); - this.lblSearchError.TabIndex = 11; - this.lblSearchError.Text = "Not found"; - this.lblSearchError.Visible = false; - // - // btnSearch - // - this.btnSearch.Location = new System.Drawing.Point(672, 4); - this.btnSearch.Margin = new System.Windows.Forms.Padding(2); - this.btnSearch.Name = "btnSearch"; - this.btnSearch.Size = new System.Drawing.Size(55, 23); - this.btnSearch.TabIndex = 10; - this.btnSearch.Text = "Find"; - this.btnSearch.UseVisualStyleBackColor = true; - this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); - // - // txtSearch - // - this.txtSearch.AcceptsReturn = true; - this.txtSearch.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::Irony.GrammarExplorer.Properties.Settings.Default, "SearchPattern", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); - this.txtSearch.Location = new System.Drawing.Point(545, 4); - this.txtSearch.Margin = new System.Windows.Forms.Padding(2); - this.txtSearch.Name = "txtSearch"; - this.txtSearch.Size = new System.Drawing.Size(123, 20); - this.txtSearch.TabIndex = 8; - this.txtSearch.Text = global::Irony.GrammarExplorer.Properties.Settings.Default.SearchPattern; - this.txtSearch.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.txtSearch_KeyPress); - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(24, 6); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(52, 13); - this.label2.TabIndex = 4; - this.label2.Text = "Grammar:"; - // - // cboGrammars - // - this.cboGrammars.ContextMenuStrip = this.menuGrammars; - this.cboGrammars.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboGrammars.FormattingEnabled = true; - this.cboGrammars.Location = new System.Drawing.Point(90, 3); - this.cboGrammars.Name = "cboGrammars"; - this.cboGrammars.Size = new System.Drawing.Size(189, 21); - this.cboGrammars.TabIndex = 3; - this.cboGrammars.SelectedIndexChanged += new System.EventHandler(this.cboGrammars_SelectedIndexChanged); - // - // menuGrammars - // - this.menuGrammars.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.miAdd, - this.miRemove, - this.miRemoveAll}); - this.menuGrammars.Name = "menuGrammars"; - this.menuGrammars.Size = new System.Drawing.Size(164, 70); - this.menuGrammars.Opening += new System.ComponentModel.CancelEventHandler(this.menuGrammars_Opening); - // - // miAdd - // - this.miAdd.Name = "miAdd"; - this.miAdd.Size = new System.Drawing.Size(163, 22); - this.miAdd.Text = "Add grammar..."; - this.miAdd.Click += new System.EventHandler(this.miAdd_Click); - // - // miRemove - // - this.miRemove.Name = "miRemove"; - this.miRemove.Size = new System.Drawing.Size(163, 22); - this.miRemove.Text = "Remove selected"; - this.miRemove.Click += new System.EventHandler(this.miRemove_Click); - // - // miRemoveAll - // - this.miRemoveAll.Name = "miRemoveAll"; - this.miRemoveAll.Size = new System.Drawing.Size(163, 22); - this.miRemoveAll.Text = "Remove all"; - this.miRemoveAll.Click += new System.EventHandler(this.miRemoveAll_Click); - // - // dlgSelectAssembly - // - this.dlgSelectAssembly.DefaultExt = "dll"; - this.dlgSelectAssembly.Filter = "DLL files|*.dll|Exe files|*.exe"; - this.dlgSelectAssembly.Title = "Select Grammar Assembly "; - // - // splitBottom - // - this.splitBottom.BackColor = System.Drawing.SystemColors.Control; - this.splitBottom.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.splitBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.splitBottom.Location = new System.Drawing.Point(0, 493); - this.splitBottom.Name = "splitBottom"; - this.splitBottom.Size = new System.Drawing.Size(1104, 6); - this.splitBottom.TabIndex = 22; - this.splitBottom.TabStop = false; - // - // tabBottom - // - this.tabBottom.Controls.Add(this.pageLanguage); - this.tabBottom.Controls.Add(this.pageGrammarErrors); - this.tabBottom.Controls.Add(this.pageParserOutput); - this.tabBottom.Controls.Add(this.pageParserTrace); - this.tabBottom.Controls.Add(this.pageOutput); - this.tabBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.tabBottom.Location = new System.Drawing.Point(0, 499); - this.tabBottom.Name = "tabBottom"; - this.tabBottom.SelectedIndex = 0; - this.tabBottom.Size = new System.Drawing.Size(1104, 187); - this.tabBottom.TabIndex = 0; - // - // pageLanguage - // - this.pageLanguage.Controls.Add(this.grpLanguageInfo); - this.pageLanguage.Location = new System.Drawing.Point(4, 22); - this.pageLanguage.Name = "pageLanguage"; - this.pageLanguage.Padding = new System.Windows.Forms.Padding(3); - this.pageLanguage.Size = new System.Drawing.Size(1096, 161); - this.pageLanguage.TabIndex = 1; - this.pageLanguage.Text = "Grammar Info"; - this.pageLanguage.UseVisualStyleBackColor = true; - // - // grpLanguageInfo - // - this.grpLanguageInfo.Controls.Add(this.label8); - this.grpLanguageInfo.Controls.Add(this.lblParserStateCount); - this.grpLanguageInfo.Controls.Add(this.lblLanguageDescr); - this.grpLanguageInfo.Controls.Add(this.txtGrammarComments); - this.grpLanguageInfo.Controls.Add(this.label11); - this.grpLanguageInfo.Controls.Add(this.label9); - this.grpLanguageInfo.Controls.Add(this.lblLanguageVersion); - this.grpLanguageInfo.Controls.Add(this.label10); - this.grpLanguageInfo.Controls.Add(this.lblLanguage); - this.grpLanguageInfo.Controls.Add(this.label4); - this.grpLanguageInfo.Controls.Add(this.label6); - this.grpLanguageInfo.Controls.Add(this.lblParserConstrTime); - this.grpLanguageInfo.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpLanguageInfo.Location = new System.Drawing.Point(3, 3); - this.grpLanguageInfo.Name = "grpLanguageInfo"; - this.grpLanguageInfo.Size = new System.Drawing.Size(1090, 155); - this.grpLanguageInfo.TabIndex = 3; - this.grpLanguageInfo.TabStop = false; - // - // label8 - // - this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(6, 113); - this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(96, 13); - this.label8.TabIndex = 26; - this.label8.Text = "Parser state count:"; - // - // lblParserStateCount - // - this.lblParserStateCount.AutoSize = true; - this.lblParserStateCount.Location = new System.Drawing.Point(167, 113); - this.lblParserStateCount.Name = "lblParserStateCount"; - this.lblParserStateCount.Size = new System.Drawing.Size(13, 13); - this.lblParserStateCount.TabIndex = 25; - this.lblParserStateCount.Text = "0"; - // - // lblLanguageDescr - // - this.lblLanguageDescr.Location = new System.Drawing.Point(107, 38); - this.lblLanguageDescr.Name = "lblLanguageDescr"; - this.lblLanguageDescr.Size = new System.Drawing.Size(613, 22); - this.lblLanguageDescr.TabIndex = 24; - this.lblLanguageDescr.Text = "(description)"; - // - // txtGrammarComments - // - this.txtGrammarComments.BackColor = System.Drawing.SystemColors.Window; - this.txtGrammarComments.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.txtGrammarComments.Location = new System.Drawing.Point(111, 63); - this.txtGrammarComments.Multiline = true; - this.txtGrammarComments.Name = "txtGrammarComments"; - this.txtGrammarComments.ReadOnly = true; - this.txtGrammarComments.Size = new System.Drawing.Size(609, 47); - this.txtGrammarComments.TabIndex = 23; - // - // label11 - // - this.label11.AutoSize = true; - this.label11.Location = new System.Drawing.Point(6, 61); - this.label11.Name = "label11"; - this.label11.Size = new System.Drawing.Size(99, 13); - this.label11.TabIndex = 22; - this.label11.Text = "Grammar Comment:"; - // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(6, 38); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(63, 13); - this.label9.TabIndex = 20; - this.label9.Text = "Description:"; - // - // lblLanguageVersion - // - this.lblLanguageVersion.Location = new System.Drawing.Point(278, 16); - this.lblLanguageVersion.Name = "lblLanguageVersion"; - this.lblLanguageVersion.Size = new System.Drawing.Size(80, 17); - this.lblLanguageVersion.TabIndex = 19; - this.lblLanguageVersion.Text = "(Version)"; - // - // label10 - // - this.label10.AutoSize = true; - this.label10.Location = new System.Drawing.Point(227, 16); - this.label10.Name = "label10"; - this.label10.Size = new System.Drawing.Size(45, 13); - this.label10.TabIndex = 18; - this.label10.Text = "Version:"; - // - // lblLanguage - // - this.lblLanguage.Location = new System.Drawing.Point(107, 16); - this.lblLanguage.Name = "lblLanguage"; - this.lblLanguage.Size = new System.Drawing.Size(230, 17); - this.lblLanguage.TabIndex = 17; - this.lblLanguage.Text = "(Language name)"; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(6, 16); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(58, 13); - this.label4.TabIndex = 16; - this.label4.Text = "Language:"; - // - // label6 - // - this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(6, 132); - this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(142, 13); - this.label6.TabIndex = 15; - this.label6.Text = "Parser construction time, ms:"; - // - // lblParserConstrTime - // - this.lblParserConstrTime.AutoSize = true; - this.lblParserConstrTime.Location = new System.Drawing.Point(167, 132); - this.lblParserConstrTime.Name = "lblParserConstrTime"; - this.lblParserConstrTime.Size = new System.Drawing.Size(13, 13); - this.lblParserConstrTime.TabIndex = 14; - this.lblParserConstrTime.Text = "0"; - // - // pageGrammarErrors - // - this.pageGrammarErrors.Controls.Add(this.gridGrammarErrors); - this.pageGrammarErrors.Location = new System.Drawing.Point(4, 22); - this.pageGrammarErrors.Name = "pageGrammarErrors"; - this.pageGrammarErrors.Padding = new System.Windows.Forms.Padding(3); - this.pageGrammarErrors.Size = new System.Drawing.Size(1096, 161); - this.pageGrammarErrors.TabIndex = 4; - this.pageGrammarErrors.Text = "Grammar Errors"; - this.pageGrammarErrors.UseVisualStyleBackColor = true; - // - // gridGrammarErrors - // - this.gridGrammarErrors.AllowUserToAddRows = false; - this.gridGrammarErrors.AllowUserToDeleteRows = false; - this.gridGrammarErrors.ColumnHeadersHeight = 24; - this.gridGrammarErrors.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; - this.gridGrammarErrors.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn2, - this.dataGridViewTextBoxColumn5, - this.dataGridViewTextBoxColumn6}); - this.gridGrammarErrors.Dock = System.Windows.Forms.DockStyle.Fill; - this.gridGrammarErrors.Location = new System.Drawing.Point(3, 3); - this.gridGrammarErrors.MultiSelect = false; - this.gridGrammarErrors.Name = "gridGrammarErrors"; - this.gridGrammarErrors.ReadOnly = true; - this.gridGrammarErrors.RowHeadersVisible = false; - this.gridGrammarErrors.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.gridGrammarErrors.Size = new System.Drawing.Size(1090, 155); - this.gridGrammarErrors.TabIndex = 3; - this.gridGrammarErrors.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridGrammarErrors_CellDoubleClick); - // - // dataGridViewTextBoxColumn2 - // - dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - this.dataGridViewTextBoxColumn2.DefaultCellStyle = dataGridViewCellStyle1; - this.dataGridViewTextBoxColumn2.HeaderText = "Error Level"; - this.dataGridViewTextBoxColumn2.Name = "dataGridViewTextBoxColumn2"; - this.dataGridViewTextBoxColumn2.ReadOnly = true; - this.dataGridViewTextBoxColumn2.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn2.ToolTipText = "Double-click grid cell to locate in source code"; - // - // dataGridViewTextBoxColumn5 - // - dataGridViewCellStyle2.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.dataGridViewTextBoxColumn5.DefaultCellStyle = dataGridViewCellStyle2; - this.dataGridViewTextBoxColumn5.HeaderText = "Description"; - this.dataGridViewTextBoxColumn5.Name = "dataGridViewTextBoxColumn5"; - this.dataGridViewTextBoxColumn5.ReadOnly = true; - this.dataGridViewTextBoxColumn5.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn5.Width = 800; - // - // dataGridViewTextBoxColumn6 - // - this.dataGridViewTextBoxColumn6.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; - this.dataGridViewTextBoxColumn6.DataPropertyName = "State"; - dataGridViewCellStyle3.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - this.dataGridViewTextBoxColumn6.DefaultCellStyle = dataGridViewCellStyle3; - this.dataGridViewTextBoxColumn6.HeaderText = "Parser State"; - this.dataGridViewTextBoxColumn6.Name = "dataGridViewTextBoxColumn6"; - this.dataGridViewTextBoxColumn6.ReadOnly = true; - this.dataGridViewTextBoxColumn6.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.dataGridViewTextBoxColumn6.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn6.ToolTipText = "Double-click grid cell to navigate to state details"; - this.dataGridViewTextBoxColumn6.Width = 71; - // - // pageParserOutput - // - this.pageParserOutput.Controls.Add(this.groupBox1); - this.pageParserOutput.Controls.Add(this.grpCompileInfo); - this.pageParserOutput.Location = new System.Drawing.Point(4, 22); - this.pageParserOutput.Name = "pageParserOutput"; - this.pageParserOutput.Padding = new System.Windows.Forms.Padding(3); - this.pageParserOutput.Size = new System.Drawing.Size(1096, 161); - this.pageParserOutput.TabIndex = 2; - this.pageParserOutput.Text = "Parser Output"; - this.pageParserOutput.UseVisualStyleBackColor = true; - // - // groupBox1 - // - this.groupBox1.Controls.Add(this.gridCompileErrors); - this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill; - this.groupBox1.Location = new System.Drawing.Point(158, 3); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(935, 155); - this.groupBox1.TabIndex = 3; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Compile Errors"; - // - // gridCompileErrors - // - this.gridCompileErrors.AllowUserToAddRows = false; - this.gridCompileErrors.AllowUserToDeleteRows = false; - this.gridCompileErrors.ColumnHeadersHeight = 24; - this.gridCompileErrors.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; - this.gridCompileErrors.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.dataGridViewTextBoxColumn3, - this.dataGridViewTextBoxColumn4, - this.dataGridViewTextBoxColumn1}); - this.gridCompileErrors.Dock = System.Windows.Forms.DockStyle.Fill; - this.gridCompileErrors.Location = new System.Drawing.Point(3, 16); - this.gridCompileErrors.MultiSelect = false; - this.gridCompileErrors.Name = "gridCompileErrors"; - this.gridCompileErrors.ReadOnly = true; - this.gridCompileErrors.RowHeadersVisible = false; - this.gridCompileErrors.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.gridCompileErrors.Size = new System.Drawing.Size(929, 136); - this.gridCompileErrors.TabIndex = 2; - this.gridCompileErrors.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridCompileErrors_CellDoubleClick); - // - // dataGridViewTextBoxColumn3 - // - dataGridViewCellStyle4.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - this.dataGridViewTextBoxColumn3.DefaultCellStyle = dataGridViewCellStyle4; - this.dataGridViewTextBoxColumn3.HeaderText = "L, C"; - this.dataGridViewTextBoxColumn3.Name = "dataGridViewTextBoxColumn3"; - this.dataGridViewTextBoxColumn3.ReadOnly = true; - this.dataGridViewTextBoxColumn3.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn3.ToolTipText = "Double-click grid cell to locate in source code"; - this.dataGridViewTextBoxColumn3.Width = 50; - // - // dataGridViewTextBoxColumn4 - // - dataGridViewCellStyle5.WrapMode = System.Windows.Forms.DataGridViewTriState.True; - this.dataGridViewTextBoxColumn4.DefaultCellStyle = dataGridViewCellStyle5; - this.dataGridViewTextBoxColumn4.HeaderText = "Error Message"; - this.dataGridViewTextBoxColumn4.Name = "dataGridViewTextBoxColumn4"; - this.dataGridViewTextBoxColumn4.ReadOnly = true; - this.dataGridViewTextBoxColumn4.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn4.Width = 600; - // - // dataGridViewTextBoxColumn1 - // - this.dataGridViewTextBoxColumn1.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.AllCells; - this.dataGridViewTextBoxColumn1.DataPropertyName = "State"; - dataGridViewCellStyle6.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - this.dataGridViewTextBoxColumn1.DefaultCellStyle = dataGridViewCellStyle6; - this.dataGridViewTextBoxColumn1.HeaderText = "Parser State"; - this.dataGridViewTextBoxColumn1.Name = "dataGridViewTextBoxColumn1"; - this.dataGridViewTextBoxColumn1.ReadOnly = true; - this.dataGridViewTextBoxColumn1.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.dataGridViewTextBoxColumn1.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.dataGridViewTextBoxColumn1.ToolTipText = "Double-click grid cell to navigate to state details"; - this.dataGridViewTextBoxColumn1.Width = 71; - // - // grpCompileInfo - // - this.grpCompileInfo.Controls.Add(this.label12); - this.grpCompileInfo.Controls.Add(this.lblParseErrorCount); - this.grpCompileInfo.Controls.Add(this.label1); - this.grpCompileInfo.Controls.Add(this.lblParseTime); - this.grpCompileInfo.Controls.Add(this.label7); - this.grpCompileInfo.Controls.Add(this.lblSrcLineCount); - this.grpCompileInfo.Controls.Add(this.label3); - this.grpCompileInfo.Controls.Add(this.lblSrcTokenCount); - this.grpCompileInfo.Dock = System.Windows.Forms.DockStyle.Left; - this.grpCompileInfo.Location = new System.Drawing.Point(3, 3); - this.grpCompileInfo.Name = "grpCompileInfo"; - this.grpCompileInfo.Size = new System.Drawing.Size(155, 155); - this.grpCompileInfo.TabIndex = 5; - this.grpCompileInfo.TabStop = false; - this.grpCompileInfo.Text = "Statistics"; - // - // label12 - // - this.label12.AutoSize = true; - this.label12.Location = new System.Drawing.Point(12, 81); - this.label12.Name = "label12"; - this.label12.Size = new System.Drawing.Size(37, 13); - this.label12.TabIndex = 19; - this.label12.Text = "Errors:"; - // - // lblParseErrorCount - // - this.lblParseErrorCount.AutoSize = true; - this.lblParseErrorCount.Location = new System.Drawing.Point(108, 81); - this.lblParseErrorCount.Name = "lblParseErrorCount"; - this.lblParseErrorCount.Size = new System.Drawing.Size(13, 13); - this.lblParseErrorCount.TabIndex = 18; - this.lblParseErrorCount.Text = "0"; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 59); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(82, 13); - this.label1.TabIndex = 17; - this.label1.Text = "Parse Time, ms:"; - // - // lblParseTime - // - this.lblParseTime.AutoSize = true; - this.lblParseTime.Location = new System.Drawing.Point(108, 59); - this.lblParseTime.Name = "lblParseTime"; - this.lblParseTime.Size = new System.Drawing.Size(13, 13); - this.lblParseTime.TabIndex = 16; - this.lblParseTime.Text = "0"; - // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(12, 16); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(35, 13); - this.label7.TabIndex = 15; - this.label7.Text = "Lines:"; - // - // lblSrcLineCount - // - this.lblSrcLineCount.AutoSize = true; - this.lblSrcLineCount.Location = new System.Drawing.Point(108, 16); - this.lblSrcLineCount.Name = "lblSrcLineCount"; - this.lblSrcLineCount.Size = new System.Drawing.Size(13, 13); - this.lblSrcLineCount.TabIndex = 14; - this.lblSrcLineCount.Text = "0"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(12, 37); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(46, 13); - this.label3.TabIndex = 13; - this.label3.Text = "Tokens:"; - // - // lblSrcTokenCount - // - this.lblSrcTokenCount.AutoSize = true; - this.lblSrcTokenCount.Location = new System.Drawing.Point(108, 37); - this.lblSrcTokenCount.Name = "lblSrcTokenCount"; - this.lblSrcTokenCount.Size = new System.Drawing.Size(13, 13); - this.lblSrcTokenCount.TabIndex = 12; - this.lblSrcTokenCount.Text = "0"; - // - // pageParserTrace - // - this.pageParserTrace.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.pageParserTrace.Controls.Add(this.grpParserActions); - this.pageParserTrace.Controls.Add(this.splitter1); - this.pageParserTrace.Controls.Add(this.grpTokens); - this.pageParserTrace.Controls.Add(this.pnlParserTraceTop); - this.pageParserTrace.Location = new System.Drawing.Point(4, 22); - this.pageParserTrace.Name = "pageParserTrace"; - this.pageParserTrace.Padding = new System.Windows.Forms.Padding(3); - this.pageParserTrace.Size = new System.Drawing.Size(1096, 161); - this.pageParserTrace.TabIndex = 3; - this.pageParserTrace.Text = "Parser Trace"; - this.pageParserTrace.UseVisualStyleBackColor = true; - // - // grpParserActions - // - this.grpParserActions.Controls.Add(this.gridParserTrace); - this.grpParserActions.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpParserActions.Location = new System.Drawing.Point(3, 28); - this.grpParserActions.Name = "grpParserActions"; - this.grpParserActions.Size = new System.Drawing.Size(804, 128); - this.grpParserActions.TabIndex = 4; - this.grpParserActions.TabStop = false; - // - // gridParserTrace - // - this.gridParserTrace.AllowUserToAddRows = false; - this.gridParserTrace.AllowUserToDeleteRows = false; - this.gridParserTrace.AllowUserToResizeRows = false; - this.gridParserTrace.ColumnHeadersHeight = 24; - this.gridParserTrace.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing; - this.gridParserTrace.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { - this.State, - this.Stack, - this.Input, - this.Action}); - this.gridParserTrace.Dock = System.Windows.Forms.DockStyle.Fill; - this.gridParserTrace.Location = new System.Drawing.Point(3, 16); - this.gridParserTrace.MultiSelect = false; - this.gridParserTrace.Name = "gridParserTrace"; - this.gridParserTrace.ReadOnly = true; - this.gridParserTrace.RowHeadersVisible = false; - this.gridParserTrace.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect; - this.gridParserTrace.Size = new System.Drawing.Size(798, 109); - this.gridParserTrace.TabIndex = 0; - this.gridParserTrace.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridParserTrace_CellDoubleClick); - // - // State - // - this.State.DataPropertyName = "State"; - dataGridViewCellStyle7.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft; - this.State.DefaultCellStyle = dataGridViewCellStyle7; - this.State.HeaderText = "State"; - this.State.Name = "State"; - this.State.ReadOnly = true; - this.State.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.State.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.State.ToolTipText = "Double-click grid cell to navigate to state details"; - this.State.Width = 60; - // - // Stack - // - this.Stack.DataPropertyName = "StackTop"; - dataGridViewCellStyle8.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight; - this.Stack.DefaultCellStyle = dataGridViewCellStyle8; - this.Stack.HeaderText = "Stack Top"; - this.Stack.Name = "Stack"; - this.Stack.ReadOnly = true; - this.Stack.Resizable = System.Windows.Forms.DataGridViewTriState.True; - this.Stack.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.Stack.ToolTipText = "Double-click grid cell to locate node in source code"; - this.Stack.Width = 220; - // - // Input - // - this.Input.DataPropertyName = "Input"; - this.Input.HeaderText = "Input"; - this.Input.Name = "Input"; - this.Input.ReadOnly = true; - this.Input.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.Input.ToolTipText = "Double-click grid cell to locate in source code"; - this.Input.Width = 150; - // - // Action - // - this.Action.DataPropertyName = "Action"; - this.Action.HeaderText = "Action"; - this.Action.Name = "Action"; - this.Action.ReadOnly = true; - this.Action.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable; - this.Action.Width = 300; - // - // splitter1 - // - this.splitter1.BackColor = System.Drawing.SystemColors.Control; - this.splitter1.Dock = System.Windows.Forms.DockStyle.Right; - this.splitter1.Location = new System.Drawing.Point(807, 28); - this.splitter1.Name = "splitter1"; - this.splitter1.Size = new System.Drawing.Size(6, 128); - this.splitter1.TabIndex = 15; - this.splitter1.TabStop = false; - // - // grpTokens - // - this.grpTokens.Controls.Add(this.lstTokens); - this.grpTokens.Dock = System.Windows.Forms.DockStyle.Right; - this.grpTokens.Location = new System.Drawing.Point(813, 28); - this.grpTokens.Name = "grpTokens"; - this.grpTokens.Size = new System.Drawing.Size(278, 128); - this.grpTokens.TabIndex = 3; - this.grpTokens.TabStop = false; - this.grpTokens.Text = "Tokens"; - // - // lstTokens - // - this.lstTokens.Dock = System.Windows.Forms.DockStyle.Fill; - this.lstTokens.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lstTokens.FormattingEnabled = true; - this.lstTokens.ItemHeight = 14; - this.lstTokens.Location = new System.Drawing.Point(3, 16); - this.lstTokens.Name = "lstTokens"; - this.lstTokens.Size = new System.Drawing.Size(272, 109); - this.lstTokens.TabIndex = 2; - this.lstTokens.Click += new System.EventHandler(this.lstTokens_Click); - // - // pnlParserTraceTop - // - this.pnlParserTraceTop.BackColor = System.Drawing.SystemColors.Control; - this.pnlParserTraceTop.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.pnlParserTraceTop.Controls.Add(this.chkExcludeComments); - this.pnlParserTraceTop.Controls.Add(this.lblTraceComment); - this.pnlParserTraceTop.Controls.Add(this.chkParserTrace); - this.pnlParserTraceTop.Dock = System.Windows.Forms.DockStyle.Top; - this.pnlParserTraceTop.Location = new System.Drawing.Point(3, 3); - this.pnlParserTraceTop.Name = "pnlParserTraceTop"; - this.pnlParserTraceTop.Size = new System.Drawing.Size(1088, 25); - this.pnlParserTraceTop.TabIndex = 1; - // - // chkExcludeComments - // - this.chkExcludeComments.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.chkExcludeComments.AutoSize = true; - this.chkExcludeComments.Checked = true; - this.chkExcludeComments.CheckState = System.Windows.Forms.CheckState.Checked; - this.chkExcludeComments.Location = new System.Drawing.Point(929, 3); - this.chkExcludeComments.Name = "chkExcludeComments"; - this.chkExcludeComments.Size = new System.Drawing.Size(145, 17); - this.chkExcludeComments.TabIndex = 2; - this.chkExcludeComments.Text = "Exclude comment tokens"; - this.chkExcludeComments.UseVisualStyleBackColor = true; - // - // lblTraceComment - // - this.lblTraceComment.AutoSize = true; - this.lblTraceComment.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.lblTraceComment.ForeColor = System.Drawing.SystemColors.ControlDarkDark; - this.lblTraceComment.Location = new System.Drawing.Point(128, 3); - this.lblTraceComment.Name = "lblTraceComment"; - this.lblTraceComment.Size = new System.Drawing.Size(350, 13); - this.lblTraceComment.TabIndex = 1; - this.lblTraceComment.Text = "(Double-click grid cell to navigate to parser state or source code position)"; - // - // pageOutput - // - this.pageOutput.Controls.Add(this.txtOutput); - this.pageOutput.Controls.Add(this.pnlRuntimeInfo); - this.pageOutput.Location = new System.Drawing.Point(4, 22); - this.pageOutput.Name = "pageOutput"; - this.pageOutput.Padding = new System.Windows.Forms.Padding(3); - this.pageOutput.Size = new System.Drawing.Size(1096, 161); - this.pageOutput.TabIndex = 0; - this.pageOutput.Text = "Runtime Output"; - this.pageOutput.UseVisualStyleBackColor = true; - // - // txtOutput - // - this.txtOutput.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtOutput.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtOutput.Location = new System.Drawing.Point(3, 3); - this.txtOutput.Multiline = true; - this.txtOutput.Name = "txtOutput"; - this.txtOutput.ReadOnly = true; - this.txtOutput.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtOutput.Size = new System.Drawing.Size(939, 155); - this.txtOutput.TabIndex = 1; - // - // pnlRuntimeInfo - // - this.pnlRuntimeInfo.Controls.Add(this.label13); - this.pnlRuntimeInfo.Controls.Add(this.lnkShowErrStack); - this.pnlRuntimeInfo.Controls.Add(this.lnkShowErrLocation); - this.pnlRuntimeInfo.Controls.Add(this.label5); - this.pnlRuntimeInfo.Controls.Add(this.lblRunTime); - this.pnlRuntimeInfo.Dock = System.Windows.Forms.DockStyle.Right; - this.pnlRuntimeInfo.Location = new System.Drawing.Point(942, 3); - this.pnlRuntimeInfo.Name = "pnlRuntimeInfo"; - this.pnlRuntimeInfo.Size = new System.Drawing.Size(151, 155); - this.pnlRuntimeInfo.TabIndex = 2; - // - // label13 - // - this.label13.AutoSize = true; - this.label13.Location = new System.Drawing.Point(5, 24); - this.label13.Name = "label13"; - this.label13.Size = new System.Drawing.Size(73, 13); - this.label13.TabIndex = 22; - this.label13.Text = "Runtime error:"; - // - // lnkShowErrStack - // - this.lnkShowErrStack.AutoSize = true; - this.lnkShowErrStack.Enabled = false; - this.lnkShowErrStack.Location = new System.Drawing.Point(23, 69); - this.lnkShowErrStack.Name = "lnkShowErrStack"; - this.lnkShowErrStack.Size = new System.Drawing.Size(79, 13); - this.lnkShowErrStack.TabIndex = 21; - this.lnkShowErrStack.TabStop = true; - this.lnkShowErrStack.Text = "Show full stack"; - this.lnkShowErrStack.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkShowErrStack_LinkClicked); - // - // lnkShowErrLocation - // - this.lnkShowErrLocation.AutoSize = true; - this.lnkShowErrLocation.Enabled = false; - this.lnkShowErrLocation.Location = new System.Drawing.Point(23, 45); - this.lnkShowErrLocation.Name = "lnkShowErrLocation"; - this.lnkShowErrLocation.Size = new System.Drawing.Size(98, 13); - this.lnkShowErrLocation.TabIndex = 20; - this.lnkShowErrLocation.TabStop = true; - this.lnkShowErrLocation.Text = "Show error location"; - this.lnkShowErrLocation.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkShowErrLocation_LinkClicked); - // - // label5 - // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(5, 3); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(98, 13); - this.label5.TabIndex = 19; - this.label5.Text = "Execution time, ms:"; - // - // lblRunTime - // - this.lblRunTime.AutoSize = true; - this.lblRunTime.Location = new System.Drawing.Point(123, 3); - this.lblRunTime.Name = "lblRunTime"; - this.lblRunTime.Size = new System.Drawing.Size(13, 13); - this.lblRunTime.TabIndex = 18; - this.lblRunTime.Text = "0"; - // - // fmGrammarExplorer - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1104, 686); - this.Controls.Add(this.tabGrammar); - this.Controls.Add(this.splitBottom); - this.Controls.Add(this.pnlLang); - this.Controls.Add(this.tabBottom); - this.Name = "fmGrammarExplorer"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Irony Grammar Explorer"; - this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.fmExploreGrammar_FormClosing); - this.Load += new System.EventHandler(this.fmExploreGrammar_Load); - this.tabGrammar.ResumeLayout(false); - this.pageTerminals.ResumeLayout(false); - this.pageTerminals.PerformLayout(); - this.pageNonTerms.ResumeLayout(false); - this.pageNonTerms.PerformLayout(); - this.pageParserStates.ResumeLayout(false); - this.pageParserStates.PerformLayout(); - this.pageTest.ResumeLayout(false); - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); - this.tabOutput.ResumeLayout(false); - this.pageSyntaxTree.ResumeLayout(false); - this.pageAst.ResumeLayout(false); - this.pnlLang.ResumeLayout(false); - this.pnlLang.PerformLayout(); - this.menuGrammars.ResumeLayout(false); - this.tabBottom.ResumeLayout(false); - this.pageLanguage.ResumeLayout(false); - this.grpLanguageInfo.ResumeLayout(false); - this.grpLanguageInfo.PerformLayout(); - this.pageGrammarErrors.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.gridGrammarErrors)).EndInit(); - this.pageParserOutput.ResumeLayout(false); - this.groupBox1.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.gridCompileErrors)).EndInit(); - this.grpCompileInfo.ResumeLayout(false); - this.grpCompileInfo.PerformLayout(); - this.pageParserTrace.ResumeLayout(false); - this.grpParserActions.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.gridParserTrace)).EndInit(); - this.grpTokens.ResumeLayout(false); - this.pnlParserTraceTop.ResumeLayout(false); - this.pnlParserTraceTop.PerformLayout(); - this.pageOutput.ResumeLayout(false); - this.pageOutput.PerformLayout(); - this.pnlRuntimeInfo.ResumeLayout(false); - this.pnlRuntimeInfo.PerformLayout(); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.TabControl tabGrammar; - private System.Windows.Forms.TabPage pageNonTerms; - private System.Windows.Forms.TabPage pageParserStates; - private System.Windows.Forms.TextBox txtNonTerms; - private System.Windows.Forms.TextBox txtParserStates; - private System.Windows.Forms.Panel pnlLang; - private System.Windows.Forms.ComboBox cboGrammars; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TabPage pageTest; - private System.Windows.Forms.Splitter splitter3; - private System.Windows.Forms.TabControl tabOutput; - private System.Windows.Forms.TabPage pageAst; - private System.Windows.Forms.TabPage pageSyntaxTree; - private System.Windows.Forms.TreeView tvParseTree; - private System.Windows.Forms.OpenFileDialog dlgOpenFile; - private System.Windows.Forms.TabPage pageTerminals; - private System.Windows.Forms.TextBox txtTerms; - private System.Windows.Forms.Button btnSearch; - private System.Windows.Forms.TextBox txtSearch; - private System.Windows.Forms.Label lblSearchError; - private System.Windows.Forms.Panel panel1; - private System.Windows.Forms.Button btnRun; - private System.Windows.Forms.CheckBox chkParserTrace; - private System.Windows.Forms.Button btnFileOpen; - private System.Windows.Forms.Button btnParse; - private System.Windows.Forms.RichTextBox txtSource; - private System.Windows.Forms.Button btnManageGrammars; - private System.Windows.Forms.ContextMenuStrip menuGrammars; - private System.Windows.Forms.ToolStripMenuItem miAdd; - private System.Windows.Forms.ToolStripMenuItem miRemove; - private System.Windows.Forms.OpenFileDialog dlgSelectAssembly; - private System.Windows.Forms.ToolStripMenuItem miRemoveAll; - private System.Windows.Forms.Button btnToXml; - private System.Windows.Forms.TabControl tabBottom; - private System.Windows.Forms.TabPage pageOutput; - private System.Windows.Forms.TextBox txtOutput; - private System.Windows.Forms.TabPage pageLanguage; - private System.Windows.Forms.Splitter splitBottom; - private System.Windows.Forms.GroupBox grpLanguageInfo; - private System.Windows.Forms.Label label6; - private System.Windows.Forms.Label lblParserConstrTime; - private System.Windows.Forms.TabPage pageParserOutput; - private System.Windows.Forms.TabPage pageParserTrace; - private System.Windows.Forms.TreeView tvAst; - private System.Windows.Forms.DataGridView gridParserTrace; - private System.Windows.Forms.GroupBox grpTokens; - private System.Windows.Forms.Panel pnlParserTraceTop; - private System.Windows.Forms.GroupBox grpParserActions; - private System.Windows.Forms.Splitter splitter1; - private System.Windows.Forms.ListBox lstTokens; - private System.Windows.Forms.Label lblTraceComment; - private System.Windows.Forms.DataGridView gridCompileErrors; - private System.Windows.Forms.CheckBox chkExcludeComments; - private System.Windows.Forms.TabPage pageGrammarErrors; - private System.Windows.Forms.DataGridView gridGrammarErrors; - private System.Windows.Forms.GroupBox groupBox1; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label lblParseTime; - private System.Windows.Forms.Label label7; - private System.Windows.Forms.Label lblSrcLineCount; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Label lblSrcTokenCount; - private System.Windows.Forms.GroupBox grpCompileInfo; - private System.Windows.Forms.Label lblLanguage; - private System.Windows.Forms.Label label4; - private System.Windows.Forms.Panel pnlRuntimeInfo; - private System.Windows.Forms.Label label5; - private System.Windows.Forms.Label lblRunTime; - private System.Windows.Forms.TextBox txtGrammarComments; - private System.Windows.Forms.Label label11; - private System.Windows.Forms.Label label9; - private System.Windows.Forms.Label lblLanguageVersion; - private System.Windows.Forms.Label label10; - private System.Windows.Forms.Label label12; - private System.Windows.Forms.Label lblParseErrorCount; - private System.Windows.Forms.Label lblLanguageDescr; - private System.Windows.Forms.LinkLabel lnkShowErrLocation; - private System.Windows.Forms.CheckBox chkDisableHili; - private System.Windows.Forms.LinkLabel lnkShowErrStack; - private System.Windows.Forms.Label label13; - private System.Windows.Forms.DataGridViewTextBoxColumn State; - private System.Windows.Forms.DataGridViewTextBoxColumn Stack; - private System.Windows.Forms.DataGridViewTextBoxColumn Input; - private System.Windows.Forms.DataGridViewTextBoxColumn Action; - private System.Windows.Forms.Label label8; - private System.Windows.Forms.Label lblParserStateCount; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn2; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn5; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn6; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn3; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn4; - private System.Windows.Forms.DataGridViewTextBoxColumn dataGridViewTextBoxColumn1; - private System.Windows.Forms.CheckBox chkAutoRefresh; - - } -} - diff --git a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.cs b/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.cs deleted file mode 100644 index d320650ae2..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.cs +++ /dev/null @@ -1,661 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -//with contributions by Andrew Bradnan -#endregion -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Configuration; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Windows.Forms; -using System.Xml; -using Irony.GrammarExplorer.Properties; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - public partial class fmGrammarExplorer : Form - { - public fmGrammarExplorer() - { - InitializeComponent(); - _grammarLoader.AssemblyUpdated += GrammarAssemblyUpdated; - } - - //fields - Parsing.Grammar _grammar; - LanguageData _language; - Parsing.Parser _parser; - ParseTree _parseTree; - GrammarLoader _grammarLoader = new GrammarLoader(); - bool _loaded; - - #region Form load/unload events - private void fmExploreGrammar_Load(object sender, EventArgs e) - { - ClearLanguageInfo(); - try - { - txtSource.Text = Settings.Default.SourceSample; - txtSearch.Text = Settings.Default.SearchPattern; - GrammarItemList grammars = GrammarItemList.FromXml(Settings.Default.Grammars); - grammars.ShowIn(cboGrammars); - chkParserTrace.Checked = Settings.Default.EnableTrace; - chkDisableHili.Checked = Settings.Default.DisableHili; - chkAutoRefresh.Checked = Settings.Default.AutoRefresh; - cboGrammars.SelectedIndex = Settings.Default.LanguageIndex; //this will build parser and start colorizer - } - catch { } - _loaded = true; - } - - private void fmExploreGrammar_FormClosing(object sender, FormClosingEventArgs e) - { - Settings.Default.SourceSample = txtSource.Text; - Settings.Default.LanguageIndex = cboGrammars.SelectedIndex; - Settings.Default.SearchPattern = txtSearch.Text; - Settings.Default.EnableTrace = chkParserTrace.Checked; - Settings.Default.DisableHili = chkDisableHili.Checked; - Settings.Default.AutoRefresh = chkAutoRefresh.Checked; - var grammars = GrammarItemList.FromCombo(cboGrammars); - Settings.Default.Grammars = grammars.ToXml(); - Settings.Default.Save(); - }//method - #endregion - - #region Show... methods - //Show... methods ###################################################################################################################### - private void ClearLanguageInfo() - { - lblLanguage.Text = string.Empty; - lblLanguageVersion.Text = string.Empty; - lblLanguageDescr.Text = string.Empty; - txtGrammarComments.Text = string.Empty; - } - - private void ClearParserOutput() - { - lblSrcLineCount.Text = string.Empty; - lblSrcTokenCount.Text = ""; - lblParseTime.Text = ""; - lblParseErrorCount.Text = ""; - - lstTokens.Items.Clear(); - gridCompileErrors.Rows.Clear(); - gridParserTrace.Rows.Clear(); - lstTokens.Items.Clear(); - tvParseTree.Nodes.Clear(); - tvAst.Nodes.Clear(); - Application.DoEvents(); - } - - private void ShowLanguageInfo() - { - if (_grammar == null) return; - var langAttr = LanguageAttribute.GetValue(_grammar.GetType()); - if (langAttr == null) return; - lblLanguage.Text = langAttr.LanguageName; - lblLanguageVersion.Text = langAttr.Version; - lblLanguageDescr.Text = langAttr.Description; - txtGrammarComments.Text = _grammar.GrammarComments; - } - - private void ShowCompilerErrors() - { - gridCompileErrors.Rows.Clear(); - if (_parseTree == null || _parseTree.ParserMessages.Count == 0) return; - foreach (var err in _parseTree.ParserMessages) - gridCompileErrors.Rows.Add(err.Location, err, err.ParserState); - var needPageSwitch = tabBottom.SelectedTab != pageParserOutput && - !(tabBottom.SelectedTab == pageParserTrace && chkParserTrace.Checked); - if (needPageSwitch) - tabBottom.SelectedTab = pageParserOutput; - } - - private void ShowParseTrace() - { - gridParserTrace.Rows.Clear(); - foreach (var entry in _parser.Context.ParserTrace) - { - gridParserTrace.Rows.Add(entry.State, entry.StackTop, entry.Input, entry.Message); - if (entry.IsError) - gridParserTrace.Rows[gridParserTrace.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.Red; - } - //Show tokens - foreach (Token tkn in _parseTree.Tokens) - { - if (chkExcludeComments.Checked && tkn.Category == TokenCategory.Comment) continue; - lstTokens.Items.Add(tkn); - } - }//method - - private void ShowCompileStats() - { - if (_parseTree == null) return; - lblSrcLineCount.Text = string.Empty; - if (_parseTree.Tokens.Count > 0) - lblSrcLineCount.Text = (_parseTree.Tokens[_parseTree.Tokens.Count - 1].Location.Line + 1).ToString(); - lblSrcTokenCount.Text = _parseTree.Tokens.Count.ToString(); - lblParseTime.Text = _parseTree.ParseTime.ToString(); - lblParseErrorCount.Text = _parseTree.ParserMessages.Count.ToString(); - Application.DoEvents(); - //Note: this time is "pure" parse time; actual delay after cliking "Compile" includes time to fill ParseTree, AstTree controls - } - - private void ShowParseTree() - { - tvParseTree.Nodes.Clear(); - if (_parseTree == null) return; - AddParseNodeRec(null, _parseTree.Root); - } - private void AddParseNodeRec(TreeNode parent, ParseTreeNode node) - { - if (node == null) return; - string txt = node.ToString(); - TreeNode tvNode = (parent == null ? tvParseTree.Nodes.Add(txt) : parent.Nodes.Add(txt)); - tvNode.Tag = node; - foreach (var child in node.ChildNodes) - AddParseNodeRec(tvNode, child); - } - - private void ShowAstTree() - { - tvAst.Nodes.Clear(); - if (_parseTree == null || _parseTree.Root == null || _parseTree.Root.AstNode == null) return; - AddAstNodeRec(null, _parseTree.Root.AstNode); - } - - private void AddAstNodeRec(TreeNode parent, object astNode) - { - if (astNode == null) return; - string txt = astNode.ToString(); - TreeNode newNode = (parent == null ? - tvAst.Nodes.Add(txt) : parent.Nodes.Add(txt)); - newNode.Tag = astNode; - if (astNode is not IBrowsableAstNode iBrowsable) return; - var childList = iBrowsable.GetChildNodes(); - foreach (var child in childList) - AddAstNodeRec(newNode, child); - } - - private void ShowParserConstructionResults() - { - lblParserStateCount.Text = _language.ParserData.States.Count.ToString(); - lblParserConstrTime.Text = _language.ConstructionTime.ToString(); - txtParserStates.Text = string.Empty; - gridGrammarErrors.Rows.Clear(); - txtTerms.Text = string.Empty; - txtNonTerms.Text = string.Empty; - txtParserStates.Text = string.Empty; - tabBottom.SelectedTab = pageLanguage; - if (_parser == null) return; - txtTerms.Text = ParserDataPrinter.PrintTerminals(_parser.Language); - txtNonTerms.Text = ParserDataPrinter.PrintNonTerminals(_parser.Language); - txtParserStates.Text = ParserDataPrinter.PrintStateList(_parser.Language); - ShowGrammarErrors(); - }//method - - private void ShowGrammarErrors() - { - gridGrammarErrors.Rows.Clear(); - var errors = _parser.Language.Errors; - if (errors.Count == 0) return; - foreach (var err in errors) - gridGrammarErrors.Rows.Add(err.Level.ToString(), err.Message, err.State); - if (tabBottom.SelectedTab != pageGrammarErrors) - tabBottom.SelectedTab = pageGrammarErrors; - } - - private void ShowSourceLocation(SourceLocation location, int length) - { - if (location.Position < 0) return; - txtSource.SelectionStart = location.Position; - txtSource.SelectionLength = length; - txtSource.ScrollToCaret(); - if (tabGrammar.SelectedTab != pageTest) - tabGrammar.SelectedTab = pageTest; - txtSource.Focus(); - } - private void ShowSourceLocationAndTraceToken(SourceLocation location, int length) - { - ShowSourceLocation(location, length); - //find token in trace - for (int i = 0; i < lstTokens.Items.Count; i++) - { - var tkn = lstTokens.Items[i] as Token; - if (tkn.Location.Position == location.Position) - { - lstTokens.SelectedIndex = i; - return; - }//if - }//for i - } - private void LocateParserState(ParserState state) - { - if (state == null) return; - if (tabGrammar.SelectedTab != pageParserStates) - tabGrammar.SelectedTab = pageParserStates; - //first scroll to the bottom, so that scrolling to needed position brings it to top - txtParserStates.SelectionStart = txtParserStates.Text.Length - 1; - txtParserStates.ScrollToCaret(); - DoSearch(txtParserStates, "State " + state.Name, 0); - } - - private void ClearRuntimeInfo() - { - lnkShowErrLocation.Enabled = false; - lnkShowErrStack.Enabled = false; - txtOutput.Text = string.Empty; - } - - #endregion - - #region Grammar combo menu commands - private void menuGrammars_Opening(object sender, CancelEventArgs e) - { - miRemove.Enabled = cboGrammars.Items.Count > 0; - } - - private void miAdd_Click(object sender, EventArgs e) - { - if (dlgSelectAssembly.ShowDialog() != DialogResult.OK) return; - string location = dlgSelectAssembly.FileName; - if (string.IsNullOrEmpty(location)) return; - var oldGrammars = new GrammarItemList(); - foreach (var item in cboGrammars.Items) - oldGrammars.Add((GrammarItem)item); - var grammars = fmSelectGrammars.SelectGrammars(location, oldGrammars); - if (grammars == null) return; - foreach (GrammarItem item in grammars) - cboGrammars.Items.Add(item); - // auto-select the first grammar if no grammar currently selected - if (cboGrammars.SelectedIndex < 0 && grammars.Count > 0) - cboGrammars.SelectedIndex = 0; - } - - private void miRemove_Click(object sender, EventArgs e) - { - if (MessageBox.Show("Are you sure you want to remove grammmar " + cboGrammars.SelectedItem + "?", - "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) - { - cboGrammars.Items.RemoveAt(cboGrammars.SelectedIndex); - _parser = null; - if (cboGrammars.Items.Count > 0) - cboGrammars.SelectedIndex = 0; - } - } - - private void miRemoveAll_Click(object sender, EventArgs e) - { - if (MessageBox.Show("Are you sure you want to remove all grammmars in the list?", - "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes) - { - cboGrammars.Items.Clear(); - _parser = null; - } - } - #endregion - - #region Parsing and running - private void CreateGrammar() - { - _grammar = _grammarLoader.CreateGrammar(); - } - - private void CreateParser() - { - StopHighlighter(); - btnRun.Enabled = false; - txtOutput.Text = string.Empty; - _parseTree = null; - - btnRun.Enabled = _grammar.FlagIsSet(LanguageFlags.CanRunSample); - _language = _grammar.CreateLanguageData(); - _parser = new Parsing.Parser(_language); - ShowParserConstructionResults(); - StartHighlighter(); - } - - private void ParseSample() - { - ClearParserOutput(); - if (_parser == null || !_parser.Language.CanParse()) return; - _parseTree = null; - GC.Collect(); //to avoid disruption of perf times with occasional collections - _parser.Context.SetOption(ParseOptions.TraceParser, chkParserTrace.Checked); - try - { - _parser.Parse(txtSource.Text, ""); - } - catch (Exception ex) - { - gridCompileErrors.Rows.Add(null, ex.Message, null); - tabBottom.SelectedTab = pageParserOutput; - throw; - } - finally - { - _parseTree = _parser.Context.CurrentParseTree; - ShowCompilerErrors(); - if (chkParserTrace.Checked) - { - ShowParseTrace(); - } - ShowCompileStats(); - ShowParseTree(); - ShowAstTree(); - } - } - - private void WriteOutput(string text) - { - if (string.IsNullOrEmpty(text)) return; - txtOutput.Text += text + Environment.NewLine; - txtOutput.Select(txtOutput.Text.Length - 1, 0); - } - - #endregion - - #region miscellaneous: LoadSourceFile, Search, Source highlighting - private void LoadSourceFile(string path) - { - _parseTree = null; - StreamReader reader = null; - try - { - reader = new StreamReader(path); - txtSource.Text = null; //to clear any old formatting - txtSource.Text = reader.ReadToEnd(); - txtSource.Select(0, 0); - } - catch (Exception e) - { - MessageBox.Show(e.Message); - } - finally - { - reader?.Close(); - } - } - - //Source highlighting - RichTextBoxHighlighter _highlighter; - private void StartHighlighter() - { - if (_highlighter != null) - StopHighlighter(); - if (chkDisableHili.Checked) return; - if (!_parser.Language.CanParse()) return; - _highlighter = new RichTextBoxHighlighter(txtSource, _language); - _highlighter.Adapter.Activate(); - } - private void StopHighlighter() - { - if (_highlighter == null) return; - _highlighter.Dispose(); - _highlighter = null; - ClearHighlighting(); - } - private void ClearHighlighting() - { - var txt = txtSource.Text; - txtSource.Clear(); - txtSource.Text = txt; //remove all old highlighting - } - private void EnableHighlighter(bool enable) - { - if (_highlighter != null) - StopHighlighter(); - if (enable) - StartHighlighter(); - } - - //The following methods are contributed by Andrew Bradnan; pasted here with minor changes - private void DoSearch() - { - lblSearchError.Visible = false; - TextBoxBase textBox = GetSearchContentBox(); - if (textBox == null) return; - int idxStart = textBox.SelectionStart + textBox.SelectionLength; - if (!DoSearch(textBox, txtSearch.Text, idxStart)) - { - lblSearchError.Text = "Not found."; - lblSearchError.Visible = true; - } - }//method - - private bool DoSearch(TextBoxBase textBox, string fragment, int start) - { - textBox.SelectionLength = 0; - // Compile the regular expression. - Regex r = new Regex(fragment, RegexOptions.IgnoreCase); - // Match the regular expression pattern against a text string. - Match m = r.Match(textBox.Text.Substring(start)); - if (m.Success) - { - int i = 0; - Group g = m.Groups[i]; - CaptureCollection cc = g.Captures; - Capture c = cc[0]; - textBox.SelectionStart = c.Index + start; - textBox.SelectionLength = c.Length; - textBox.Focus(); - textBox.ScrollToCaret(); - return true; - } - return false; - }//method - - public TextBoxBase GetSearchContentBox() - { - return tabGrammar.SelectedIndex switch - { - 0 => txtTerms, - 1 => txtNonTerms, - 2 => txtParserStates, - 4 => txtSource, - _ => null, - }; - } - - #endregion - - #region Controls event handlers - //Controls event handlers ################################################################################################### - private void btnParse_Click(object sender, EventArgs e) - { - ParseSample(); - } - - private void btnRun_Click(object sender, EventArgs e) - { - MessageBox.Show(this, "No longer implemented"); - } - - private void tvParseTree_AfterSelect(object sender, TreeViewEventArgs e) - { - var vtreeNode = tvParseTree.SelectedNode; - if (vtreeNode == null) return; - if (vtreeNode.Tag is not ParseTreeNode parseNode) return; - ShowSourceLocation(parseNode.Span.Location, 1); - } - - private void tvAst_AfterSelect(object sender, TreeViewEventArgs e) - { - var treeNode = tvAst.SelectedNode; - if (treeNode == null) return; - if (treeNode.Tag is not IBrowsableAstNode iBrowsable) return; - ShowSourceLocation(iBrowsable.Location, 1); - } - - bool _changingGrammar; - private void LoadSelectedGrammar() - { - try - { - ClearLanguageInfo(); - ClearParserOutput(); - ClearRuntimeInfo(); - - _changingGrammar = true; - CreateGrammar(); - ShowLanguageInfo(); - CreateParser(); - } - finally - { - _changingGrammar = false; //in case of exception - } - } - - private void cboGrammars_SelectedIndexChanged(object sender, EventArgs e) - { - _grammarLoader.SelectedGrammar = cboGrammars.SelectedItem as GrammarItem; - LoadSelectedGrammar(); - } - - private void GrammarAssemblyUpdated(object sender, EventArgs args) - { - if (InvokeRequired) - { - Invoke(new EventHandler(GrammarAssemblyUpdated), sender, args); - return; - } - if (chkAutoRefresh.Checked) - { - LoadSelectedGrammar(); - txtGrammarComments.Text += String.Format("{0}Grammar assembly reloaded: {1:HH:mm:ss}", Environment.NewLine, DateTime.Now); - } - } - - private void btnFileOpen_Click(object sender, EventArgs e) - { - if (dlgOpenFile.ShowDialog() != DialogResult.OK) return; - LoadSourceFile(dlgOpenFile.FileName); - } - - private void txtSource_TextChanged(object sender, EventArgs e) - { - _parseTree = null; //force it to recompile on run - } - - private void btnManageGrammars_Click(object sender, EventArgs e) - { - menuGrammars.Show(btnManageGrammars, 0, btnManageGrammars.Height); - } - - private void btnToXml_Click(object sender, EventArgs e) - { - txtOutput.Text = string.Empty; - if (_parseTree == null) - ParseSample(); - if (_parseTree == null) return; - txtOutput.Text += _parseTree.ToXml(); - txtOutput.Select(0, 0); - tabBottom.SelectedTab = pageOutput; - } - - private void cboParseMethod_SelectedIndexChanged(object sender, EventArgs e) - { - //changing grammar causes setting of parse method combo, so to prevent double-call to ConstructParser - // we don't do it here if _changingGrammar is set - if (!_changingGrammar) - CreateParser(); - } - - private void gridParserTrace_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - if (_parser.Context == null || e.RowIndex < 0 || e.RowIndex >= _parser.Context.ParserTrace.Count) return; - var entry = _parser.Context.ParserTrace[e.RowIndex]; - switch (e.ColumnIndex) - { - case 0: //state - case 3: //action - LocateParserState(entry.State); - break; - case 1: //stack top - if (entry.StackTop != null) - ShowSourceLocationAndTraceToken(entry.StackTop.Span.Location, entry.StackTop.Span.Length); - break; - case 2: //input - if (entry.Input != null) - ShowSourceLocationAndTraceToken(entry.Input.Span.Location, entry.Input.Span.Length); - break; - }//switch - } - - private void lstTokens_Click(object sender, EventArgs e) - { - if (lstTokens.SelectedIndex < 0) - return; - Token token = (Token)lstTokens.SelectedItem; - ShowSourceLocation(token.Location, token.Length); - } - - private void gridCompileErrors_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - if (e.RowIndex < 0 || e.RowIndex >= gridCompileErrors.Rows.Count) return; - var err = gridCompileErrors.Rows[e.RowIndex].Cells[1].Value as ParserMessage; - switch (e.ColumnIndex) - { - case 0: //state - case 1: //stack top - ShowSourceLocation(err.Location, 1); - break; - case 2: //input - if (err.ParserState != null) - LocateParserState(err.ParserState); - break; - }//switch - } - - private void gridGrammarErrors_CellDoubleClick(object sender, DataGridViewCellEventArgs e) - { - if (e.RowIndex < 0 || e.RowIndex >= gridGrammarErrors.Rows.Count) return; - if (gridGrammarErrors.Rows[e.RowIndex].Cells[2].Value is ParserState state) - LocateParserState(state); - } - - private void btnSearch_Click(object sender, EventArgs e) - { - DoSearch(); - }//method - - private void txtSearch_KeyPress(object sender, KeyPressEventArgs e) - { - if (e.KeyChar == '\r') // key - DoSearch(); - } - - private void lnkShowErrLocation_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - MessageBox.Show(this, "No longer implemented"); - } - - private void lnkShowErrStack_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - MessageBox.Show(this, "No longer implemented"); - } - - #endregion - - private void chkDisableHili_CheckedChanged(object sender, EventArgs e) - { - if (!_loaded) return; - EnableHighlighter(!chkDisableHili.Checked); - } - - }//class -} diff --git a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.resx b/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.resx deleted file mode 100644 index 8421232e28..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmGrammarExplorer.resx +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 135, 17 - - - 17, 17 - - - 274, 17 - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - True - - - 45 - - \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.Designer.cs b/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.Designer.cs deleted file mode 100644 index 9b139b166d..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.Designer.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Irony.GrammarExplorer { - partial class fmSelectGrammars { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.pnlBottom = new System.Windows.Forms.Panel(); - this.btnUncheckAll = new System.Windows.Forms.Button(); - this.btnCheckAll = new System.Windows.Forms.Button(); - this.btnCancel = new System.Windows.Forms.Button(); - this.btnOK = new System.Windows.Forms.Button(); - this.lstGrammars = new System.Windows.Forms.CheckedListBox(); - this.pnlBottom.SuspendLayout(); - this.SuspendLayout(); - // - // pnlBottom - // - this.pnlBottom.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; - this.pnlBottom.Controls.Add(this.btnUncheckAll); - this.pnlBottom.Controls.Add(this.btnCheckAll); - this.pnlBottom.Controls.Add(this.btnCancel); - this.pnlBottom.Controls.Add(this.btnOK); - this.pnlBottom.Dock = System.Windows.Forms.DockStyle.Bottom; - this.pnlBottom.Location = new System.Drawing.Point(0, 245); - this.pnlBottom.Name = "pnlBottom"; - this.pnlBottom.Size = new System.Drawing.Size(451, 35); - this.pnlBottom.TabIndex = 1; - // - // btnUncheckAll - // - this.btnUncheckAll.Location = new System.Drawing.Point(75, 3); - this.btnUncheckAll.Name = "btnUncheckAll"; - this.btnUncheckAll.Size = new System.Drawing.Size(74, 24); - this.btnUncheckAll.TabIndex = 3; - this.btnUncheckAll.Text = "Uncheck All"; - this.btnUncheckAll.UseVisualStyleBackColor = true; - this.btnUncheckAll.Click += new System.EventHandler(this.btnCheckUncheck_Click); - // - // btnCheckAll - // - this.btnCheckAll.Location = new System.Drawing.Point(3, 3); - this.btnCheckAll.Name = "btnCheckAll"; - this.btnCheckAll.Size = new System.Drawing.Size(66, 24); - this.btnCheckAll.TabIndex = 2; - this.btnCheckAll.Text = "Check All"; - this.btnCheckAll.UseVisualStyleBackColor = true; - this.btnCheckAll.Click += new System.EventHandler(this.btnCheckUncheck_Click); - // - // btnCancel - // - this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(379, 3); - this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(66, 24); - this.btnCancel.TabIndex = 1; - this.btnCancel.Text = "Cancel"; - this.btnCancel.UseVisualStyleBackColor = true; - // - // btnOK - // - this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.btnOK.Location = new System.Drawing.Point(307, 3); - this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(66, 24); - this.btnOK.TabIndex = 0; - this.btnOK.Text = "OK"; - this.btnOK.UseVisualStyleBackColor = true; - // - // lstGrammars - // - this.lstGrammars.Dock = System.Windows.Forms.DockStyle.Fill; - this.lstGrammars.FormattingEnabled = true; - this.lstGrammars.Location = new System.Drawing.Point(0, 0); - this.lstGrammars.Name = "lstGrammars"; - this.lstGrammars.Size = new System.Drawing.Size(451, 244); - this.lstGrammars.Sorted = true; - this.lstGrammars.TabIndex = 2; - // - // fmSelectGrammars - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(451, 280); - this.Controls.Add(this.lstGrammars); - this.Controls.Add(this.pnlBottom); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "fmSelectGrammars"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Select Grammars"; - this.pnlBottom.ResumeLayout(false); - this.ResumeLayout(false); - - } - - #endregion - - private System.Windows.Forms.Panel pnlBottom; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.Button btnOK; - private System.Windows.Forms.CheckedListBox lstGrammars; - private System.Windows.Forms.Button btnUncheckAll; - private System.Windows.Forms.Button btnCheckAll; - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.cs b/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.cs deleted file mode 100644 index 6b15abdc70..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.cs +++ /dev/null @@ -1,111 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Windows.Forms; -using Irony.Parsing; - -namespace Irony.GrammarExplorer -{ - public partial class fmSelectGrammars : Form - { - public fmSelectGrammars() - { - InitializeComponent(); - } - - public static GrammarItemList SelectGrammars(string assemblyPath, GrammarItemList loadedGrammars) - { - var fromGrammars = LoadGrammars(assemblyPath); - if (fromGrammars == null) - return null; - //fill the listbox and show the form - fmSelectGrammars form = new fmSelectGrammars(); - var listbox = form.lstGrammars; - listbox.Sorted = false; - foreach (GrammarItem item in fromGrammars) - { - listbox.Items.Add(item); - if (!ContainsGrammar(loadedGrammars, item)) - listbox.SetItemChecked(listbox.Items.Count - 1, true); - } - listbox.Sorted = true; - - if (form.ShowDialog() != DialogResult.OK) return null; - GrammarItemList result = new GrammarItemList(); - for (int i = 0; i < listbox.Items.Count; i++) - { - if (listbox.GetItemChecked(i)) - { - var item = listbox.Items[i] as GrammarItem; - item._loading = false; - result.Add(item); - } - } - return result; - } - - private static GrammarItemList LoadGrammars(string assemblyPath) - { - Assembly asm = null; - try - { - asm = GrammarLoader.LoadAssembly(assemblyPath); - // enforce loading every time, even if assembly name is not changed - //asm = Assembly.Load(File.ReadAllBytes(assemblyPath)); - } - catch (Exception ex) - { - MessageBox.Show("Failed to load assembly: " + ex.Message); - return null; - } - var types = asm.GetTypes(); - var grammars = new GrammarItemList(); - foreach (Type t in types) - { - if (t.IsAbstract) continue; - if (!t.IsSubclassOf(typeof(Grammar))) continue; - grammars.Add(new GrammarItem(t, assemblyPath)); - } - if (grammars.Count == 0) - { - MessageBox.Show("No classes derived from Irony.Grammar were found in the assembly."); - return null; - } - return grammars; - } - - private static bool ContainsGrammar(GrammarItemList items, GrammarItem item) - { - foreach (var listItem in items) - if (listItem.TypeName == item.TypeName && listItem.Location == item.Location) - return true; - return false; - } - - private void btnCheckUncheck_Click(object sender, EventArgs e) - { - bool check = sender == btnCheckAll; - for (int i = 0; i < lstGrammars.Items.Count; i++) - lstGrammars.SetItemChecked(i, check); - } - - }//class -} diff --git a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.resx b/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.resx deleted file mode 100644 index 19dc0dd8b3..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmSelectGrammars.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/sources/shaders/Irony.GrammarExplorer/fmShowException.Designer.cs b/sources/shaders/Irony.GrammarExplorer/fmShowException.Designer.cs deleted file mode 100644 index 4d315c47d9..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmShowException.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Irony.GrammarExplorer { - partial class fmShowException { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) { - if (disposing && (components != null)) { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() { - this.txtException = new System.Windows.Forms.TextBox(); - this.SuspendLayout(); - // - // txtException - // - this.txtException.AcceptsReturn = true; - this.txtException.AcceptsTab = true; - this.txtException.Dock = System.Windows.Forms.DockStyle.Fill; - this.txtException.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.txtException.HideSelection = false; - this.txtException.Location = new System.Drawing.Point(0, 0); - this.txtException.Multiline = true; - this.txtException.Name = "txtException"; - this.txtException.ReadOnly = true; - this.txtException.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.txtException.Size = new System.Drawing.Size(764, 334); - this.txtException.TabIndex = 1; - // - // fmShowException - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(764, 334); - this.Controls.Add(this.txtException); - this.Name = "fmShowException"; - this.Text = "Exception"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox txtException; - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/fmShowException.cs b/sources/shaders/Irony.GrammarExplorer/fmShowException.cs deleted file mode 100644 index 486a87e0d8..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmShowException.cs +++ /dev/null @@ -1,37 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; - -namespace Irony.GrammarExplorer -{ - public partial class fmShowException : Form - { - public fmShowException() - { - InitializeComponent(); - } - public static void ShowException(Exception ex) - { - fmShowException fm = new fmShowException(); - fm.txtException.Text = ex.ToString(); - fm.txtException.Select(0, 0); - fm.Show(); - } - } -} diff --git a/sources/shaders/Irony.GrammarExplorer/fmShowException.resx b/sources/shaders/Irony.GrammarExplorer/fmShowException.resx deleted file mode 100644 index 19dc0dd8b3..0000000000 --- a/sources/shaders/Irony.GrammarExplorer/fmShowException.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/sources/shaders/Irony/Common/StringUtils.cs b/sources/shaders/Irony/Common/StringUtils.cs deleted file mode 100644 index 45f16e8660..0000000000 --- a/sources/shaders/Irony/Common/StringUtils.cs +++ /dev/null @@ -1,77 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public static class Strings { - public const string AllLatinLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - public const string DecimalDigits = "1234567890"; - public const string OctalDigits = "12345670"; - public const string HexDigits = "1234567890aAbBcCdDeEfF"; - public const string BinaryDigits = "01"; - - public static string JoinStrings(string separator, IEnumerable values) { - StringList list = new StringList(); - list.AddRange(values); - string[] arr = new string[list.Count]; - list.CopyTo(arr, 0); - return string.Join(separator, arr); - } - - }//class - - public class StringDictionary : Dictionary { } - public class CharList : List { } - public class CharHashSet : HashSet { } //adding Hash to the name to avoid confusion with System.Runtime.Interoperability.CharSet - - public class StringSet : HashSet { - public StringSet() { } - public StringSet(StringComparer comparer) : base(comparer) { } - public override string ToString() { - return ToString(" "); - } - public void AddRange(params string[] items) { - base.UnionWith(items); - } - public string ToString(string separator) { - return Strings.JoinStrings(separator, this); - } - } - - public class StringList : List { - public StringList() { } - public StringList(params string[] args) { - AddRange(args); - } - public override string ToString() { - return ToString(" "); - } - public string ToString(string separator) { - return Strings.JoinStrings(separator, this); - } - //Used in sorting suffixes and prefixes; longer strings must come first in sort order - public static int LongerFirst(string x, string y) { - try {//in case any of them is null - if (x.Length > y.Length) return -1; - } catch { } - if (x == y) return 0; - return 1; - } - - }//class - - -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Base/AstException.cs b/sources/shaders/Irony/Interpreter/Ast/Base/AstException.cs deleted file mode 100644 index 66034c50a7..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Base/AstException.cs +++ /dev/null @@ -1,26 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Interpreter.Ast { - public class AstException : Exception { - public object AstNode; - public AstException(object astNode, string message) : base(message) { - AstNode = astNode; - } - - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Base/AstInterfaces.cs b/sources/shaders/Irony/Interpreter/Ast/Base/AstInterfaces.cs deleted file mode 100644 index 7ff2ca28d1..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Base/AstInterfaces.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - - - [Flags] - public enum AstMode { - None = 0, - Read = 0x01, - Write = 0x02, - } - - //This interface is expected by Irony's ScriptInterpreter when it evaluates AST nodes in the AST tree. - public interface IInterpretedAstNode { - void Evaluate(EvaluationContext context, AstMode mode); - //Used for pointing to error location. For most nodes it would be the location of the node itself. - // One exception is BinExprNode: when we get "Division by zero" error evaluating - // x = (5 + 3) / (2 - 2) - // it is better to point to "/" as error location, rather than the first "(" - which is the start - // location of binary expression. - SourceLocation GetErrorAnchor(); - } - - public interface ICallTarget { - void Call(EvaluationContext context); - } - - -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Base/AstNode.cs b/sources/shaders/Irony/Interpreter/Ast/Base/AstNode.cs deleted file mode 100644 index 80d3c2de59..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Base/AstNode.cs +++ /dev/null @@ -1,164 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.CodeDom; -using System.Xml; -using System.IO; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - - public delegate void NodeEvaluate(EvaluationContext context, AstMode mode); - - [Flags] - public enum AstNodeFlags { - None = 0x0, - IsTail = 0x01, //the node is in tail position - IsScope = 0x10, //node defines scope for local variables - } - - public class AstNodeList : List { } - - //Base AST node class - public partial class AstNode : IAstNodeInit, IBrowsableAstNode, IVisitableNode, IInterpretedAstNode { - protected NodeEvaluate EvaluateRef; - - public AstNode() { - EvaluateRef = this.EvaluateNode; - } - - - #region IAstNodeInit Members - public virtual void Init(ParsingContext context, ParseTreeNode treeNode) { - this.Term = treeNode.Term; - Span = treeNode.Span; - ErrorAnchor = this.Location; - treeNode.AstNode = this; - AsString = (Term == null ? this.GetType().Name : Term.Name); - } - #endregion - - #region IInterpretedAstNode Members - //Important: normally you don't need to override this method - you should override EvaluateNode instead - // You should have strong reasons to override it - for example, if you want to change - // exception handling implementation in base method. Otherwise, put all derived functionality - // in EvaluateNode, or create other method(s) and set reference to it in EvaluateRef - public virtual void Evaluate(EvaluationContext context, AstMode mode) { - try { - EvaluateRef(context, mode); - } catch (RuntimeException) { - throw; - } catch (Exception ex) { - throw new RuntimeException(ex.Message, ex, this.GetErrorAnchor()); - } - } - - public virtual SourceLocation GetErrorAnchor() { - return ErrorAnchor; - } - #endregion - - public virtual void EvaluateNode(EvaluationContext context, AstMode mode) { - } - - #region IBrowsableAstNode Members - public virtual System.Collections.IEnumerable GetChildNodes() { - return ChildNodes; - } - public SourceLocation Location { - get { return Span.Location; } - } - #endregion - - #region properties: Parent, Term, Span, Caption, Role, Flags, ChildNodes, Attributes - public AstNode Parent; - public BnfTerm Term; - public SourceSpan Span; - public AstNodeFlags Flags; - //Used for pointing to error location. For most nodes it would be the location of the node itself. - // One exception is BinExprNode: when we get "Division by zero" error evaluating - // x = (5 + 3) / (2 - 2) - // it is better to point to "/" as error location, rather than the first "(" - which is the start - // location of binary expression. - protected SourceLocation ErrorAnchor; - // Role is a free-form string used as prefix in ToString() representation of the node. - // Node's parent can set it to "property name" or role of the child node in parent's node context. - public string Role; - // node.ToString() returns 'Role: AsString', which is used for showing node in AST tree. - public string AsString { get; protected set; } - - //List of child nodes - public readonly AstNodeList ChildNodes = new AstNodeList(); - - #endregion - - - #region Utility methods: AddChild, SetParent, FlagIsSet ... - protected AstNode AddChild(string role, ParseTreeNode childParseNode) { - var child = (AstNode)childParseNode.AstNode; - if (child == null) - child = new NullNode(childParseNode.Term); //put a stub to throw an exception with clear message on attempt to evaluate. - child.Role = role; - child.SetParent(this); - ChildNodes.Add(child); - return child; - } - - public void SetParent(AstNode parent) { - Parent = parent; - } - - public bool FlagIsSet(AstNodeFlags flag) { - return (Flags & flag) != 0; - } - #endregion - - - public override string ToString() { - return string.IsNullOrEmpty(Role) ? AsString : Role + ": " + AsString; - } - - protected void InvalidAstMode(string mode) { - throw new Exception(string.Format(Resources.ErrInvalidAstMode, this.ToString(), mode)); - } - - #region Visitors, Iterators - //the first primitive Visitor facility - public virtual void AcceptVisitor(IAstVisitor visitor) { - visitor.BeginVisit(this); - if (ChildNodes.Count > 0) - foreach(AstNode node in ChildNodes) - node.AcceptVisitor(visitor); - visitor.EndVisit(this); - } - - //Node traversal - public IEnumerable GetAll() { - AstNodeList result = new AstNodeList(); - AddAll(result); - return result; - } - private void AddAll(AstNodeList list) { - list.Add(this); - foreach (AstNode child in this.ChildNodes) - if (child != null) - child.AddAll(list); - } - #endregion - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Expressions/BinaryOperationNode.cs b/sources/shaders/Irony/Interpreter/Ast/Expressions/BinaryOperationNode.cs deleted file mode 100644 index d71de3c512..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Expressions/BinaryOperationNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - public class BinaryOperationNode : AstNode { - public AstNode Left; - public string Op; - public AstNode Right; - - public BinaryOperationNode() { } - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Left = AddChild("Arg", treeNode.ChildNodes[0]); - Right = AddChild("Arg", treeNode.ChildNodes[2]); - var opToken = treeNode.ChildNodes[1].FindToken(); - Op = opToken.Text; - //Set error anchor to operator, so on error (Division by zero) the explorer will point to - // operator node as location, not to the very beginning of the first operand. - ErrorAnchor = opToken.Location; - AsString = Op + "(operator)"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - Left.Evaluate(context, AstMode.Read); - Right.Evaluate(context, AstMode.Read); - context.CallDispatcher.ExecuteBinaryOperator(this.Op); - }//method - - }//class -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Expressions/ExpressionListNode.cs b/sources/shaders/Irony/Interpreter/Ast/Expressions/ExpressionListNode.cs deleted file mode 100644 index 6eec966d18..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Expressions/ExpressionListNode.cs +++ /dev/null @@ -1,45 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - - //A node representing expression list - for example, list of argument expressions in function call - public class ExpressionListNode : AstNode { - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - foreach (var child in treeNode.ChildNodes) { - AddChild("expr", child); - } - AsString = "Expression list"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - var result = new ValuesList(); - foreach (var expr in ChildNodes) { - expr.Evaluate(context, AstMode.Read); - result.Add(context.Data.Pop()); - } - //Push list on the stack - context.Data.Push(result); - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Expressions/IncDecNode.cs b/sources/shaders/Irony/Interpreter/Ast/Expressions/IncDecNode.cs deleted file mode 100644 index d82895ac1b..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Expressions/IncDecNode.cs +++ /dev/null @@ -1,62 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - - public class IncDecNode : AstNode { - public string Op; - public string BinaryOp; //corresponding binary operation: + for ++, - for -- - public AstNode Argument; - public bool IsPostfix; - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - FindOpAndDetectPostfix(context, treeNode); - int argIndex = IsPostfix? 0 : 1; - Argument = AddChild("Arg", treeNode.ChildNodes[argIndex]); - BinaryOp = Op[0].ToString(); //take a single char out of ++ or -- - base.AsString = Op + (IsPostfix ? "(postfix)" : "(prefix)"); - } - - private void FindOpAndDetectPostfix(ParsingContext context, ParseTreeNode treeNode) { - IsPostfix = false; //assume it - Op = treeNode.ChildNodes[0].FindTokenAndGetText(); - if (Op == "--" || Op == "++") return; - IsPostfix = true; - Op = treeNode.ChildNodes[1].FindTokenAndGetText(); - if (Op == "--" || Op == "++") return; - //report error - throw new AstException(this, Resources.ErrInvalidArgsForIncDec); - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - Argument.Evaluate(context, AstMode.Read); - var result = context.LastResult; - context.Data.Push(1); - context.CallDispatcher.ExecuteBinaryOperator(BinaryOp); - //prefix op: result of operation is the value AFTER inc/dec; so overwrite the result value - if (!IsPostfix) - result = context.LastResult; - Argument.Evaluate(context, AstMode.Write); //write value into variable - context.Data.Push(result); - } - - }//class - -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Expressions/UnaryOperationNode.cs b/sources/shaders/Irony/Interpreter/Ast/Expressions/UnaryOperationNode.cs deleted file mode 100644 index a6e33c3b06..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Expressions/UnaryOperationNode.cs +++ /dev/null @@ -1,65 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - - public class UnaryOperationNode : AstNode { - public string Op; - public string UnaryOp; - public AstNode Argument; - - public UnaryOperationNode() { } - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Op = treeNode.ChildNodes[0].FindTokenAndGetText(); - Argument = AddChild("Arg", treeNode.ChildNodes[1]); - base.AsString = Op + "(unary op)"; - // setup evaluation method; - switch (Op) { - case "+": EvaluateRef = EvaluatePlus; break; - case "-": EvaluateRef = EvaluateMinus; break; - case "!": EvaluateRef = EvaluateNot; break; - default: - string msg = string.Format(Resources.ErrNoImplForUnaryOp, Op); - throw new AstException(this, msg); - }//switch - } - - #region Evaluation methods - - private void EvaluatePlus(EvaluationContext context, AstMode mode) { - Argument.Evaluate(context, AstMode.Read); - } - - private void EvaluateMinus(EvaluationContext context, AstMode mode) { - context.Data.Push((byte)0); - Argument.Evaluate(context, AstMode.Read); - context.CallDispatcher.ExecuteBinaryOperator("-"); - } - - private void EvaluateNot(EvaluationContext context, AstMode mode) { - Argument.Evaluate(context, AstMode.Read); - var value = context.Data.Pop(); - var bValue = (bool) context.Runtime.BoolResultConverter(value); - context.Data.Push(!bValue); - } - #endregion - - }//class -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionCallNode.cs b/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionCallNode.cs deleted file mode 100644 index b1477017d2..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionCallNode.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - - //A node representing function call - public class FunctionCallNode : AstNode { - AstNode TargetRef; - AstNode Arguments; - string _targetName; - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - TargetRef = AddChild("Target", treeNode.ChildNodes[0]); - _targetName = treeNode.ChildNodes[0].FindTokenAndGetText(); - Arguments = AddChild("Args", treeNode.ChildNodes[1]); - AsString = "Call " + _targetName; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - TargetRef.Evaluate(context, AstMode.Read); - var target = context.Data.Pop() as ICallTarget; - if (target == null) - context.ThrowError(Resources.ErrVarIsNotCallable, _targetName); - Arguments.Evaluate(context, AstMode.Read); - target.Call(context); - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionDefNode.cs b/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionDefNode.cs deleted file mode 100644 index 266780aa9e..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Functions/FunctionDefNode.cs +++ /dev/null @@ -1,56 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - - //A node representing function definition - public class FunctionDefNode : AstNode, ICallTarget { - AstNode NameNode; - AstNode Parameters; - AstNode Body; - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - //child #0 is usually a keyword like "def" - NameNode = AddChild("Name", treeNode.ChildNodes[1]); - Parameters = AddChild("Parameters", treeNode.ChildNodes[2]); - Body = AddChild("Body", treeNode.ChildNodes[3]); - AsString = ""; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - //push the function into the stack - context.Data.Push(this); - NameNode.Evaluate(context, AstMode.Write); - } - - - #region ICallTarget Members - - public void Call(EvaluationContext context) { - context.PushFrame(this.NameNode.ToString(), this, context.CurrentFrame); - Parameters.Evaluate(context, AstMode.None); - Body.Evaluate(context, AstMode.None); - context.PopFrame(); - } - - #endregion - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Functions/ParamListNode.cs b/sources/shaders/Irony/Interpreter/Ast/Functions/ParamListNode.cs deleted file mode 100644 index 1aea99c840..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Functions/ParamListNode.cs +++ /dev/null @@ -1,48 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - - public class ParamListNode : AstNode { - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - foreach (var child in treeNode.ChildNodes) { - AddChild("parameter", child); - } - AsString = "Param list"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - var argsObj = context.Data.Pop(); - var args = argsObj as ValuesList; - if (args == null) - context.ThrowError(Resources.ErrArgListNotFound, argsObj); - if (args.Count != ChildNodes.Count) - context.ThrowError(Resources.ErrWrongArgCount, ChildNodes.Count, args.Count); - - for(int i = 0; i < ChildNodes.Count; i++) { - context.Data.Push(args[i]); - ChildNodes[i].Evaluate(context, AstMode.Write); - } - }//method - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/IdentifierNode.cs b/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/IdentifierNode.cs deleted file mode 100644 index 3830c09d4f..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/IdentifierNode.cs +++ /dev/null @@ -1,51 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Xml; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - - public class IdentifierNode : AstNode { - public string Symbol; - - public IdentifierNode() { } - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Symbol = treeNode.Token.ValueString; - AsString = Symbol; - } - - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - switch (mode) { - case AstMode.Read: - object value; - if (context.TryGetValue(Symbol, out value)) - context.Data.Push(value); - else - context.ThrowError(Resources.ErrVarNotDefined, Symbol); - break; - case AstMode.Write: - context.SetValue(Symbol, context.Data.Pop()); - break; - } - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/LiteralValueNode.cs b/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/LiteralValueNode.cs deleted file mode 100644 index 1f96b24ed2..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/LiteralValueNode.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - public class LiteralValueNode : AstNode { - public object Value; - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Value = treeNode.Token.Value; - AsString = Value == null ? "null" : Value.ToString(); - if (Value is string) - AsString = "\"" + AsString + "\""; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - switch (mode) { - case AstMode.Read: - context.Data.Push(Value); - break; - case AstMode.Write: - context.ThrowError(Resources.ErrAssignLiteralValue); - break; - } - } - - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/StringTemplateNode.cs b/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/StringTemplateNode.cs deleted file mode 100644 index dc018f8806..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/PrimitiveNodes/StringTemplateNode.cs +++ /dev/null @@ -1,143 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - public class StringTemplateNode : AstNode { - #region embedded classes - enum SegmentType { - Text, - Expression - } - class TemplateSegment { - public SegmentType Type; - public string Text; - public AstNode ExpressionNode; - public int Position; //Position in raw text of the token for error reporting - public TemplateSegment(string text, AstNode node, int position) { - Type = node == null? SegmentType.Text : SegmentType.Expression; - Text = text; - ExpressionNode = node; - Position = position; - } - } - class SegmentList : List { } - #endregion - - string _template; - string _tokenText; //used for locating error - StringTemplateSettings _templateSettings; //copied from Terminal.AstNodeConfig - SegmentList _segments = new SegmentList(); - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - _template = treeNode.Token.ValueString; - _tokenText = treeNode.Token.Text; - _templateSettings = treeNode.Term.AstNodeConfig as StringTemplateSettings; - ParseSegments(context); - AsString = "\"" + _template + "\" (templated string)"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - switch (mode) { - case AstMode.Read: - var value = BuildString(context); - context.Data.Push(value); - break; - case AstMode.Write: - context.ThrowError(Resources.ErrAssignLiteralValue); - break; - } - } - - private void ParseSegments(ParsingContext context) { - var exprParser = new Parser(context.Language, _templateSettings.ExpressionRoot); - // As we go along the "value text" (that has all escapes done), we track the position in raw token text in the variable exprPosInTokenText. - // This position is position in original text in source code, including original escaping sequences and open/close quotes. - // It will be passed to segment constructor, and maybe used later to compute the exact position of runtime error when it occurs. - int currentPos = 0, exprPosInTokenText = 0; - while(true) { - var startTagPos = _template.IndexOf(_templateSettings.StartTag, currentPos); - if (startTagPos < 0) startTagPos = _template.Length; - var text = _template.Substring(currentPos, startTagPos - currentPos); - if (!string.IsNullOrEmpty(text)) - _segments.Add(new TemplateSegment(text, null, 0)); //for text segments position is not used - if (startTagPos >= _template.Length) - break; //from while - //We have a real start tag, grab the expression - currentPos = startTagPos + _templateSettings.StartTag.Length; - var endTagPos = _template.IndexOf(_templateSettings.EndTag, currentPos); - if (endTagPos < 0) { - context.AddParserError(Resources.ErrNoEndTagInEmbExpr, _templateSettings.EndTag);//"No ending tag '{0}' found in embedded expression." - return; - } - var exprText = _template.Substring(currentPos, endTagPos - currentPos); - if(!string.IsNullOrEmpty(exprText)) { - //parse the expression - //_expressionParser.Context.Reset(); - - var exprTree = exprParser.Parse(exprText); - if(exprTree.HasErrors()) { - //we use original search in token text instead of currentPos in template to avoid distortions caused by opening quote and escaped sequences - var baseLocation = this.Location + _tokenText.IndexOf(exprText); - context.CurrentParseTree.CopyMessages(exprTree.ParserMessages, baseLocation, Resources.ErrInvalidEmbeddedPrefix); - return; - } - //add the expression segment - exprPosInTokenText = _tokenText.IndexOf(_templateSettings.StartTag, exprPosInTokenText) + _templateSettings.StartTag.Length; - _segments.Add(new TemplateSegment(null, exprTree.Root.AstNode as AstNode, exprPosInTokenText)); - //advance position beyond the expression - exprPosInTokenText += exprText.Length + _templateSettings.EndTag.Length; - - }//if - currentPos = endTagPos + _templateSettings.EndTag.Length; - }//while - } - - private object BuildString(EvaluationContext context) { - var initialStackCount = context.Data.Count; - string[] values = new string[_segments.Count]; - for(int i = 0; i < _segments.Count; i++) { - var segment = _segments[i]; - switch(segment.Type) { - case SegmentType.Text: - values[i] = segment.Text; - break; - case SegmentType.Expression: - values[i] = EvaluateExpression(context, segment); - context.Data.PopUntil(initialStackCount); - break; - }//else - }//for i - var result = string.Join(string.Empty, values); - return result; - }//method - - private string EvaluateExpression(EvaluationContext context, TemplateSegment segment) { - try { - segment.ExpressionNode.Evaluate(context, AstMode.Read); - var value = context.LastResult; - return value == null ? string.Empty : value.ToString(); - } catch(RuntimeException ex) { - this.ErrorAnchor = this.Location + segment.Position + ex.Location; - throw ex.InnerException; - } - - } - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/EmptyStatementNode.cs b/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/EmptyStatementNode.cs deleted file mode 100644 index 0bf4a435d0..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/EmptyStatementNode.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - //A statement that does nothing, like "pass" command in Python. - public class EmptyStatementNode : AstNode { - - - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NotSupportedNode.cs b/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NotSupportedNode.cs deleted file mode 100644 index 18f03b226a..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NotSupportedNode.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - //A substitute node to use on constructs that are not yet supported by language implementation. - // The script would compile Ok but on attempt to evaluate the node would throw a runtime exception - public class NotSupportedNode : AstNode { - string Name; - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Name = treeNode.Term.ToString(); - AsString = Name + " (not supported)"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - context.ThrowError(Resources.ErrConstructNotSupported, Name); - } - - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NullNode.cs b/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NullNode.cs deleted file mode 100644 index cd12b0a18f..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/SpecialNodes/NullNode.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter; - -namespace Irony.Interpreter.Ast { - //A stub to use when AST node was not created (type not specified on NonTerminal, or error on creation) - // The purpose of the stub is to throw a meaningful message when interpreter tries to evaluate null node. - public class NullNode : AstNode { - - public NullNode(BnfTerm term) { - this.Term = term; - } - - public override void Evaluate(EvaluationContext context, AstMode mode) { - context.ThrowError(Resources.ErrNullNodeEval, this.Term); - } - }//class -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Statements/AssignmentNode.cs b/sources/shaders/Irony/Interpreter/Ast/Statements/AssignmentNode.cs deleted file mode 100644 index aed00c6b5d..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Statements/AssignmentNode.cs +++ /dev/null @@ -1,62 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - public class AssignmentNode : AstNode { - public AstNode Target; - public string AssignmentOp; - public string BaseOp; //base arithm operation (+) for augmented assignment like "+=" - public AstNode Expression; - - public AssignmentNode() {} - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Target = AddChild("To", treeNode.ChildNodes[0]); - //Get Op and baseOp if it is combined assignment - AssignmentOp = treeNode.ChildNodes[1].FindTokenAndGetText(); - if (string.IsNullOrEmpty(AssignmentOp)) - AssignmentOp = "="; - if (AssignmentOp.Length > 1) { - //it is combined op - BaseOp = AssignmentOp.Replace("=", string.Empty); - } - //There maybe an "=" sign in the middle, or not - if it is marked as punctuation; so we just take the last node in child list - var lastIndex = treeNode.ChildNodes.Count - 1; - Expression = AddChild("Expr", treeNode.ChildNodes[lastIndex]); - AsString = AssignmentOp + " (assignment)"; - if (string.IsNullOrEmpty(BaseOp)) - EvaluateRef = EvaluateSimple; - else - EvaluateRef = EvaluateCombined; - } - - private void EvaluateSimple(EvaluationContext context, AstMode mode) { - Expression.Evaluate(context, AstMode.Read); - Target.Evaluate(context, AstMode.Write); //writes the value into the slot - } - private void EvaluateCombined(EvaluationContext context, AstMode mode) { - Target.Evaluate(context, AstMode.Read); - Expression.Evaluate(context, AstMode.Read); - context.CallDispatcher.ExecuteBinaryOperator(BaseOp); - Target.Evaluate(context, AstMode.Write); //writes the value into the slot - } - - } -} diff --git a/sources/shaders/Irony/Interpreter/Ast/Statements/BlockNode.cs b/sources/shaders/Irony/Interpreter/Ast/Statements/BlockNode.cs deleted file mode 100644 index 1e0bf94de1..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Statements/BlockNode.cs +++ /dev/null @@ -1,31 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - public class BlockNode : StatementListNode { - - public BlockNode() { } - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode.ChildNodes[0]); - AsString = "Block"; - } - - - }//class -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Statements/IfNode.cs b/sources/shaders/Irony/Interpreter/Ast/Statements/IfNode.cs deleted file mode 100644 index fa409eae23..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Statements/IfNode.cs +++ /dev/null @@ -1,46 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - public class IfNode : AstNode { - public AstNode Test; - public AstNode IfTrue; - public AstNode IfFalse; - - public IfNode() { } - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - Test = AddChild("Test", treeNode.ChildNodes[0]); - IfTrue = AddChild("IfTrue", treeNode.ChildNodes[1]); - if (treeNode.ChildNodes.Count > 2) - IfFalse = AddChild("IfFalse", treeNode.ChildNodes[2]); - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - Test.Evaluate(context, AstMode.Write); - var result = context.Data.Pop(); - if (context.Runtime.IsTrue(result)) { - if (IfTrue != null) IfTrue.Evaluate(context, AstMode.Read); - } else { - if (IfFalse != null) IfFalse.Evaluate(context, AstMode.Read); - } - } - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/Ast/Statements/StatementListNode.cs b/sources/shaders/Irony/Interpreter/Ast/Statements/StatementListNode.cs deleted file mode 100644 index 81d31833de..0000000000 --- a/sources/shaders/Irony/Interpreter/Ast/Statements/StatementListNode.cs +++ /dev/null @@ -1,49 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Interpreter; -using Irony.Parsing; - -namespace Irony.Interpreter.Ast { - - public class StatementListNode : AstNode { - - public override void Init(ParsingContext context, ParseTreeNode treeNode) { - base.Init(context, treeNode); - foreach (var child in treeNode.ChildNodes) { - //don't add if it is null; it can happen that "statement" is a comment line and statement's node is null. - // So to make life easier for language creator, we just skip if it is null - if (child.AstNode != null) - AddChild(string.Empty, child); - } - AsString = "Statement List"; - } - - public override void EvaluateNode(EvaluationContext context, AstMode mode) { - if (ChildNodes.Count == 0) return; - ChildNodes[ChildNodes.Count - 1].Flags |= AstNodeFlags.IsTail; - int iniCount = context.Data.Count; - foreach(var stmt in ChildNodes) { - stmt.Evaluate(context, AstMode.Read); - //restore position, in case a statement left something (like standalone expression vs assignment) - context.Data.PopUntil(iniCount); - } - context.Data.Push(context.LastResult); //push it back again - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/CommandLine.cs b/sources/shaders/Irony/Interpreter/CommandLine.cs deleted file mode 100644 index d219480f12..0000000000 --- a/sources/shaders/Irony/Interpreter/CommandLine.cs +++ /dev/null @@ -1,184 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using Irony.Parsing; - -namespace Irony.Interpreter { - - public class CommandLine { - #region Fields and properties - public readonly Grammar Grammar; - //Initialized from grammar - public string Title; - public string Greeting; - public string Prompt; //default prompt - public string PromptMoreInput; //prompt to show when more input is expected - - public readonly ScriptInterpreter Interpreter; - private bool _ctrlCPressed; - #endregion - - public CommandLine(Grammar grammar) { - Grammar = grammar; - Title = grammar.ConsoleTitle; - Greeting = grammar.ConsoleGreeting; - Prompt = grammar.ConsolePrompt; - PromptMoreInput = grammar.ConsolePromptMoreInput; - - Interpreter = new ScriptInterpreter(grammar); - Interpreter.RethrowExceptions = false; - Interpreter.ParseMode = ParseMode.CommandLine; - Interpreter.PrintParseErrors = false; - } - - public void Run() { - try { - RunImpl(); - } catch (Exception ex) { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(Resources.ErrConsoleFatalError); - Console.WriteLine(ex.ToString()); - Console.ForegroundColor = ConsoleColor.White; - Console.WriteLine(Resources.MsgPressAnyKeyToExit); - Console.Read(); - } - - } - - - private void RunImpl() { - - Console.Title = Title; - Console.CancelKeyPress += OnCancelKeyPress; - Console.WriteLine(Greeting); - - string input; - while (true) { - Console.ForegroundColor = ConsoleColor.White; - string prompt = (Interpreter.Status == InterpreterStatus.WaitingMoreInput ? PromptMoreInput : Prompt); - Console.Write(prompt); - var result = ReadInput(out input); - //Check the result type - it may be the response to "Abort?" question, not a script to execute. - switch (result) { - case ReadResult.AbortYes: return; //exit - case ReadResult.AbortNo: continue; //while loop - case ReadResult.Script: break; //do nothing, continue to evaluate script - } - Interpreter.ClearOutputBuffer(); - Interpreter.EvaluateAsync(input); - while (Interpreter.IsBusy()) - Thread.Sleep(50); - switch (Interpreter.Status) { - case InterpreterStatus.Ready: //success - Console.WriteLine(Interpreter.GetOutput()); - break; - case InterpreterStatus.SyntaxError: - Console.WriteLine(Interpreter.GetOutput()); //write all output we have - Console.ForegroundColor = ConsoleColor.Red; - foreach (var err in Interpreter.ParsedScript.ParserMessages) { - Console.WriteLine(string.Empty.PadRight(prompt.Length + err.Location.Column) + "^"); //show err location - Console.WriteLine(err.Message); //print message - } - break; - case InterpreterStatus.RuntimeError: - ReportException(); - break; - default: break; - }//switch - } - - }//Run method - - private void ReportException() { - Console.ForegroundColor = ConsoleColor.Red; - var ex = Interpreter.LastException; - var runtimeEx = ex as RuntimeException; - if (runtimeEx != null) - Console.WriteLine(runtimeEx.Message + " " + Resources.LabelLocation + " " + runtimeEx.Location.ToUiString()); - else - Console.WriteLine(ex.Message); - //Console.WriteLine(ex.ToString()); //Uncomment to see the full stack when debugging your language - } - - #region Reading input methods - private enum ReadResult { - Script, - AbortYes, - AbortNo, - } - - private ReadResult ReadInput(out string input) { - //When user presses Ctrl-C system sends null as input immediately, then fires Ctrl-C event - do { - input = Console.ReadLine(); - } while (input == null); - if (!_ctrlCPressed) return ReadResult.Script; - _ctrlCPressed = false; - if (Resources.ConsoleYesChars.Contains(input)) - return ReadResult.AbortYes; - if (Resources.ConsoleNoChars.Contains(input)) - return ReadResult.AbortNo; - //anything else return NO - return ReadResult.AbortNo; - } - #endregion - - #region Ctrl-C handling - //It might seem that we can do all here: ask the question "Abort?", get the answer and abort the app (by setting e.Cancel flag) - // It is possible when the interpreter is busy, and we do it all here. But when system waits for - // user input, it is not so straightforward. Here's what would happen if we did this. - // When the app is waiting for user input, and user presses the Ctrl-C, the currently waiting "ReadLine()" call in the main loop - // returns null; this will cause main loop in RunImpl run once again and one more prompt (>>>) will be printed; - // ReadLine will be called again from main loop. Only then this CancelKeyPress event is fired. - // Now, if we try to print question and read the answer in the event handler, the answer will go to the still waiting ReadLine - // call in the main loop, and event handler's ReadLine call for the answer will be blocked until NEXT user input. - // So we cannot do this. - // The solution is the following. First, the main loop uses ReadInput wrapper method to read console input - this method takes into - // account the internal flag _ctrlCPressed which is set by the Cancel event handler. The event handler, when it is invoked - // simply prints the question, sets the _ctrlCPressed flag and returns. When user answers the question (Y/N), - // the answer will be returned to ReadInput method which in turn will check the _ctrlCPressed flag. - // If this flag is set, it will return the appropriate result value indicating to the main loop - // that user input is in fact not a script but an answer to abort-yes/no question. - // The main loop will then either exit the app or continue running, without trying to evaluate the input value as script. - public virtual void OnCancelKeyPress(object sender, ConsoleCancelEventArgs e) { - e.Cancel = true; //do not abort Console here. - _ctrlCPressed = true; - if (Interpreter.IsBusy()) { - //This is interpreter-busy situation, we do all here. - Console.Write(Resources.MsgAbortScriptYN); - string input; - var result = ReadInput(out input); - switch (result) { - case ReadResult.AbortYes: - Interpreter.Abort(); - return; - default: - return; - } - } else { - //Ask the question and return; - //ReadInput is currently waiting for ReadLine return; it will get the answer (Y/N), and because - // _ctrlCPressed flag is set, ReadInput will return the answer as AbortYes/AbortNo to the main loop in RunImpl method - // The _crtlCPressed flag is already set. - Console.WriteLine(); - Console.Write(Resources.MsgExitConsoleYN); - } - }//method - #endregion - - }//class -} diff --git a/sources/shaders/Irony/Interpreter/DataStack.cs b/sources/shaders/Irony/Interpreter/DataStack.cs deleted file mode 100644 index 4c5e1bb050..0000000000 --- a/sources/shaders/Irony/Interpreter/DataStack.cs +++ /dev/null @@ -1,70 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Interpreter { - public class DataStack { - - List _data = new List(16); - object _lastPushedItem; - object _unassigned; //Unassigned singleton value - - public void Init(object unassigned) { - _unassigned = unassigned; - _lastPushedItem = unassigned; - _data.Clear(); - } - - public int Count { - get {return _data.Count;} - } - public object this[int index] { - get {return _data[_data.Count - 1 - index]; } - } - public object Top { - get { return _data[_data.Count - 1]; } - } - public object Pop() { - if (Count == 0) - throw new Exception(Resources.ErrInternalErrDataPopFailed); - var result = Top; - _data.RemoveAt(_data.Count - 1); - return result; - } - public void Pop(int count) { - _data.RemoveRange(_data.Count - count, count); - } - public void PopUntil(int toCount) { - if (toCount >= _data.Count) return; - Pop(_data.Count - toCount); - } - public void Push(object item) { - _lastPushedItem = item; - _data.Add(item); - } - public void Replace(int removeCount, object item) { - Pop(removeCount); - Push(item); - } - public object LastPushedItem { - get { return _lastPushedItem; } - } - public override string ToString() { - return this.GetType().Name + "(Count=" + Count + ")"; - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Interpreter/DynamicCallDispatcher.cs b/sources/shaders/Irony/Interpreter/DynamicCallDispatcher.cs deleted file mode 100644 index 851be6f649..0000000000 --- a/sources/shaders/Irony/Interpreter/DynamicCallDispatcher.cs +++ /dev/null @@ -1,240 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; - -namespace Irony.Interpreter { - - #region OperatorDispatchKey class - /// - /// The struct is used as a key for the dictionary of operator implementations. - /// Contains types of arguments for a method or operator implementation. - /// - public struct OperatorDispatchKey : IEquatable { - public string OpSymbol; - public Type Arg1Type; - public Type Arg2Type; - public int HashCode; - private OperatorDispatchKey(string opSymbol, Type arg1Type, Type arg2Type) { - OpSymbol = opSymbol; - Arg1Type = arg1Type; - Arg2Type = arg2Type; - int h1 = (arg1Type == null ? 0 : arg1Type.GetHashCode()); - int h2 = (arg2Type == null ? 0 : arg2Type.GetHashCode()); - //shift is for assymetry - HashCode = unchecked((h1 << 1) + h2 + opSymbol.GetHashCode()); - }//OpKey - - public override int GetHashCode() { - return HashCode; - } - public override string ToString() { - return "(" + Arg1Type + " " + OpSymbol + " " + Arg2Type + ")"; - } - - public static OperatorDispatchKey CreateFromTypes(string opSymbol, Type arg1Type, Type arg2Type) { - return new OperatorDispatchKey(opSymbol, arg1Type, arg2Type); - } - public static OperatorDispatchKey CreateFromArgs(string opSymbol, object arg1, object arg2) { - return new OperatorDispatchKey(opSymbol, (arg1 == null ? null : arg1.GetType()), (arg2 == null ? null : arg2.GetType())); - } - public static OperatorDispatchKey CreateForTypeConverter(Type fromType, Type toType) { - return new OperatorDispatchKey(string.Empty, fromType, toType); - } - - #region IEquatable Members - public bool Equals(OperatorDispatchKey other) { - return HashCode == other.HashCode && OpSymbol == other.OpSymbol && Arg1Type == other.Arg1Type && Arg2Type == other.Arg2Type; - } - #endregion - }//class - #endregion - - #region TypeConverter - public delegate object TypeConverter(object arg); - public class TypeConverterTable : Dictionary { - public void Add(Type fromType, Type toType, TypeConverter converter) { - OperatorDispatchKey key = OperatorDispatchKey.CreateForTypeConverter(fromType, toType); - this[key] = converter; - } - public TypeConverter Find(Type fromType, Type toType) { - OperatorDispatchKey key = OperatorDispatchKey.CreateForTypeConverter(fromType, toType); - TypeConverter result; - TryGetValue(key, out result); - return result; - } - } - #endregion - - #region OperatorImplementation - public delegate object BinaryOperatorMethod(object arg1, object arg2); - public delegate object UnaryOperatorMethod(object arg1, object arg2); - - /// - ///The OperatorImplementation class represents an implementation of an operator or method with specific argument types. - /// - /// - /// The OperatorImplementation holds 4 method execution components, which are simply delegate references: - /// converters for both arguments, implementation method and converter for the result. - /// - public sealed class OperatorImplementation { - public readonly OperatorDispatchKey Key; - // The type to which arguments are converted and no-conversion method for this type. - public readonly Type BaseType; - public readonly BinaryOperatorMethod BaseMethod; - //converters - internal TypeConverter Arg1Converter; - internal TypeConverter Arg2Converter; - internal TypeConverter ResultConverter; - //A reference to the actual method - one of EvaluateConvXXX - public BinaryOperatorMethod Evaluate; - - public OperatorImplementation(OperatorDispatchKey key, Type baseType, BinaryOperatorMethod baseMethod, - TypeConverter arg1Converter, TypeConverter arg2Converter, TypeConverter resultConverter) { - Key = key; - BaseType = baseType; - Arg1Converter = arg1Converter; - Arg2Converter = arg2Converter; - ResultConverter = resultConverter; - BaseMethod = baseMethod; - SetupEvaluationMethod(); - } - - public void SetupEvaluationMethod() { - if (ResultConverter == null) { - //without ResultConverter - if (Arg1Converter == null && Arg2Converter == null) - Evaluate = EvaluateConvNone; - else if (Arg1Converter != null && Arg2Converter == null) - Evaluate = EvaluateConvLeft; - else if (Arg1Converter == null && Arg2Converter != null) - Evaluate = EvaluateConvRight; - else // if (Arg1Converter != null && arg2Converter != null) - Evaluate = EvaluateConvBoth; - } else { - //with result converter - if (Arg1Converter == null && Arg2Converter == null) - Evaluate = EvaluateConvNoneConvResult; - else if (Arg1Converter != null && Arg2Converter == null) - Evaluate = EvaluateConvLeftConvResult; - else if (Arg1Converter == null && Arg2Converter != null) - Evaluate = EvaluateConvRightConvResult; - else // if (Arg1Converter != null && Arg2Converter != null) - Evaluate = EvaluateConvBothConvResult; - } - } - - private object EvaluateConvNone(object arg1, object arg2) { - return BaseMethod(arg1, arg2); - } - private object EvaluateConvLeft(object arg1, object arg2) { - return BaseMethod(Arg1Converter(arg1), arg2); - } - private object EvaluateConvRight(object arg1, object arg2) { - return BaseMethod(arg1, Arg2Converter(arg2)); - } - private object EvaluateConvBoth(object arg1, object arg2) { - return BaseMethod(Arg1Converter(arg1), Arg2Converter(arg2)); - } - - private object EvaluateConvNoneConvResult(object arg1, object arg2) { - return ResultConverter(BaseMethod(arg1, arg2)); - } - private object EvaluateConvLeftConvResult(object arg1, object arg2) { - return ResultConverter(BaseMethod(Arg1Converter(arg1), arg2)); - } - private object EvaluateConvRightConvResult(object arg1, object arg2) { - return ResultConverter(BaseMethod(arg1, Arg2Converter(arg2))); - } - private object EvaluateConvBothConvResult(object arg1, object arg2) { - return ResultConverter(BaseMethod(Arg1Converter(arg1), Arg2Converter(arg2))); - } - }//class - - public class OperatorImplementationTable : Dictionary { } - #endregion - - #region OperatorDispatcher - /// - /// The DynamicCallDispatcher class is responsible for fast dispatching to the implementation based on argument types - /// It is one per context which is one per thread. - /// - public class DynamicCallDispatcher { - EvaluationContext _context; - LanguageRuntime _runtime; - public readonly OperatorImplementationTable OperatorImplementations; - - public DynamicCallDispatcher(EvaluationContext context) { - _context = context; - _runtime = _context.Runtime; - OperatorImplementations = _runtime.CreateOperatorImplementationsTable(); - } - - public void ExecuteBinaryOperator(string op) { - var arg1 = _context.Data[1]; - var arg2 = _context.Data[0]; - var key = OperatorDispatchKey.CreateFromArgs(op, arg1, arg2); - OperatorImplementation opImpl; - if (!OperatorImplementations.TryGetValue(key, out opImpl)) - opImpl = _runtime.AddOperatorImplementation(OperatorImplementations, key); - if (opImpl != null) { - try { - var result = opImpl.Evaluate(arg1, arg2); - _context.Data.Replace(2, result); - return; - } catch (OverflowException) { - if (TryConvertArgsOnOverflow(opImpl.BaseType)) { - ExecuteBinaryOperator(op); //call self recursively, now with new arg types - return; - } - throw; - }//catch - }//if - - //Treating as normal call - first comes implementor (arg1), then argument (ag2); something like: - // a + b => a._add(b) - //ExecuteMethod(arg1, op, 1); - _context.ThrowError(Resources.ErrOpNotImplemented, op); - }//method - - private bool TryConvertArgsOnOverflow(Type baseType) { - //get the up-type - Type upType = _runtime.GetUpType(baseType); - if (upType == null) - return false; - var arg2 = _context.Data.Pop(); - var arg1 = _context.Data.Pop(); - var arg1Conv = ConvertValue(arg1, upType); - var arg2Conv = ConvertValue(arg2, upType); - _context.Data.Push(arg1Conv); - _context.Data.Push(arg2Conv); - return true; - } - - private object ConvertValue(object value, Type toType) { - var key = OperatorDispatchKey.CreateForTypeConverter(value.GetType(), toType); - TypeConverter converter; - if (_runtime.TypeConverters.TryGetValue(key, out converter)) { - var result = converter.Invoke(value); - return result; - } - throw new Exception(string.Format("Failed to convert value '%1' to type %2.", value, toType)); - } - - }//class - #endregion - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/EvaluationContext.cs b/sources/shaders/Irony/Interpreter/EvaluationContext.cs deleted file mode 100644 index 5db905a748..0000000000 --- a/sources/shaders/Irony/Interpreter/EvaluationContext.cs +++ /dev/null @@ -1,114 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading; -using Irony.Parsing; -using Irony.Interpreter.Ast; - -namespace Irony.Interpreter { - - enum EvaluationStatus { - Ready, - Evaluating, - RuntimeError, - Aborted, - } - - public enum JumpType { - None = 0, - Break, - Continue, - Return, - Goto, - Exception, - } - - public partial class EvaluationContext { - public readonly int ThreadId; - public LanguageRuntime Runtime; - public readonly bool LanguageCaseSensitive; - public readonly ValuesTable Globals; - public DataStack Data; - public DynamicCallDispatcher CallDispatcher; - public JumpType Jump = JumpType.None; - public AstNode GotoTarget; - //public Closure Tail; - public StackFrame TopFrame, CurrentFrame; - public StringBuilder OutputBuffer = new StringBuilder(); - public int EvaluationTime; - - public EvaluationContext(LanguageRuntime runtime) { - Runtime = runtime; - LanguageCaseSensitive = Runtime.Language.Grammar.CaseSensitive; - //Globals = new GlobalValuesTable(100, Symbols, LanguageCaseSensitive); - Globals = new ValuesTable(100); - CallDispatcher = new DynamicCallDispatcher(this); - ThreadId = Thread.CurrentThread.ManagedThreadId; - TopFrame = new StackFrame(this, Globals); - CurrentFrame = TopFrame; - Data = new DataStack(); - Data.Init(runtime.Unassigned); //set LastPushedItem to unassigned - } - - public object LastResult { - get { return Data.LastPushedItem; } - } - public void ClearLastResult() { - Data.Init(Runtime.Unassigned); - } - public bool HasLastResult { - get { return LastResult != Runtime.Unassigned; } - } - - public void PushFrame(string methodName, AstNode node, StackFrame parent) { - CurrentFrame = new StackFrame(this, methodName, CurrentFrame, parent); - } - public void PopFrame() { - CurrentFrame = CurrentFrame.Caller; - } - - public bool TryGetValue(string name, out object value) { - if (CurrentFrame.Values.TryGetValue(name, out value)) return true; - var frame = CurrentFrame.Parent; - while (frame != null) { - if (frame.Values.TryGetValue(name, out value)) return true; - frame = frame.Parent; - } - value = null; - return false; - } - - public void SetValue(string name, object value) { - CurrentFrame.Values[name] = value; - } - - public void Write(string text) { - OutputBuffer.Append(text); - } - public void WriteLine(string text) { - OutputBuffer.AppendLine(text); - } - - //Throws generic exception; it supposed to be caught in AstNode.Evaluate method and it will wrap it into RuntimeException - // with node location added - public void ThrowError(string message, params object[] args) { - if (args != null && args.Length > 0) - message = string.Format(message, args); - throw new Exception(message); - } - - }//class - -} diff --git a/sources/shaders/Irony/Interpreter/LanguageRuntime.cs b/sources/shaders/Irony/Interpreter/LanguageRuntime.cs deleted file mode 100644 index 8da2d491e4..0000000000 --- a/sources/shaders/Irony/Interpreter/LanguageRuntime.cs +++ /dev/null @@ -1,256 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter.Ast; - -namespace Irony.Interpreter { - using BigInteger = Microsoft.Scripting.Math.BigInteger; - using Complex = Microsoft.Scripting.Math.Complex64; - - public class ConsoleWriteEventArgs : EventArgs { - public string Text; - public ConsoleWriteEventArgs(string text) { - Text = text; - } - } - - public class TypeList : List { } - - public class Unassigned { - string _toString; - - public Unassigned() { - _toString = Resources.LabelUnassigned; - } - public Unassigned(string toString) { - _toString = toString; - } - - public override string ToString() { - return _toString; - } - } - - - //Note: mark the derived language-specific class as sealed - important for JIT optimizations - // details here: http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx - public partial class LanguageRuntime { - - public LanguageRuntime(LanguageData language) { - Language = language; - Init(); - } - - public readonly LanguageData Language; - public readonly TypeList BaseTypeSequence = new TypeList(); - public readonly TypeConverterTable TypeConverters = new TypeConverterTable(); - // This is the original operator implementations table containing implementations for base type - // pairs without arg converters. Each Evaluation context has its own - // implementation table which is initialized from this original copy. - // During execution the copied table in context can be extended on the fly - // to include extra implementations with arg conversions. If we used one shared table this - // will lead to the need to syncronize the access in multi-threading environment. Instead, - // each context (associated with its own thread) has its own instance. This instance is initialized - // from this original table in method CreateOperatorImplementationsTable(). - private OperatorImplementationTable _baseOperatorImplementations; - - - //public readonly MetaObjectTable MetaObjects = new MetaObjectTable(); - //public readonly FunctionBindingTable FunctionBindings = new FunctionBindingTable(); - //Converter of the result for comparison operation; converts bool value to values - // specific for the language - public TypeConverter BoolResultConverter = null; - //An unassigned reserved object for a language implementation - public Unassigned Unassigned = new Unassigned(); - - public bool IsAssigned(object value) { - return value != Unassigned; - } - - public virtual bool IsTrue(object value) { - return value != NullObject; - } - - public virtual object NullObject { - get { return null; } - } - public OperatorImplementationTable CreateOperatorImplementationsTable() { - var table = new OperatorImplementationTable(); - foreach (var entry in _baseOperatorImplementations) - table.Add(entry.Key, entry.Value); - return table; - } -/* - public virtual FunctionBindingInfo GetFunctionBindingInfo(string name, AstNodeList parameters) { - return FunctionBindings.Find(name, parameters.Count); - } - //Utility methods for adding library functions - public FunctionBindingInfo AddFunction(string name, int paramCount) { - return null; - } - public FunctionBindingInfo AddFunction(string name, int paramCount, FunctionFlags flags) { - FunctionBindingInfo info = new FunctionBindingInfo(name, paramCount, null, flags); - FunctionBindings.Add(name, info); - return info; - } - */ - - #region Operator implementations - // When an implementation for exact type pair is not found, we find implementation for base type and create - // implementation for exact types using type converters - public virtual OperatorImplementation AddOperatorImplementation(OperatorImplementationTable implementations, OperatorDispatchKey forKey) { - Type baseType = GetBaseTypeForExpression(forKey.OpSymbol, forKey.Arg1Type, forKey.Arg2Type); - if (baseType == null) return null; - TypeConverter arg1Converter = GetConverter(forKey.Arg1Type, baseType); - TypeConverter arg2Converter = GetConverter(forKey.Arg2Type, baseType); - //Get base method for the operator and common type - var baseKey = OperatorDispatchKey.CreateFromTypes(forKey.OpSymbol, baseType, baseType); - OperatorImplementation baseImpl; - if (! _baseOperatorImplementations.TryGetValue(baseKey, out baseImpl)) - throw new Exception(string.Format(Resources.ErrOpNotDefinedForTypes, forKey.OpSymbol, forKey.Arg1Type, forKey.Arg2Type)); - var impl = new OperatorImplementation(forKey, baseType, baseImpl.BaseMethod, arg1Converter, arg2Converter, baseImpl.ResultConverter); - implementations[forKey] = impl; - return impl; - } - - /// - /// Returns the type to which arguments should be converted to perform the operation - /// for a given operator and arguments type. - /// - /// Operator - /// The type of the first argument. - /// The type of the second argument - /// - protected virtual Type GetBaseTypeForExpression(string op, Type type1, Type type2) { - //TODO: implement ability to customize in particular language - var allowSwitchToSigned = op == "-"; - var isBoolOp = op == "&" || op == "|"; - Type t; - //First check for boolean op; some languages allow ints to be interpreted as bools in expressions - t = typeof(bool); - if (isBoolOp || IsOneOf(t, type1, type2)) return t; - //Check implicit conversion to string - t = typeof(string); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(Complex); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(double); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(float); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(BigInteger); - if (IsOneOf(t, type1, type2)) return t; - - t = typeof(Int64); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(UInt64); - if (IsOneOf(t, type1, type2)) - //If we have "-" operation then the result can be negative, so we must do operation on signed type - return allowSwitchToSigned ? typeof(Int64) : t; - - t = typeof(Int32); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(UInt32); - if (IsOneOf(t, type1, type2)) - //If we have "-" operation then the result can be negative, so we must do operation on signed type - return allowSwitchToSigned ? typeof(Int32) : t; - - t = typeof(Int16); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(UInt16); - if (IsOneOf(t, type1, type2)) - //If we have "-" operation then the result can be negative, so we must do operation on signed type - return allowSwitchToSigned ? typeof(Int16) : t; - - t = typeof(sbyte); - if (IsOneOf(t, type1, type2)) return t; - t = typeof(byte); - if (IsOneOf(t, type1, type2)) - //If we have "-" operation then the result can be negative, so we must do operation on signed type - return allowSwitchToSigned ? typeof(sbyte) : t; - - return null; - }//method - - private static bool IsOneOf(Type type, Type type1, Type type2) { - return type == type1 || type == type2; - } - - /// - /// Returns the "up-type" to use in operation instead of the type that caused overflow. - /// - /// The base type for operation that caused overflow. - /// The type to use for operation. - /// - /// Can be overwritten in language implementation to implement different type-conversion policy. - /// - public virtual Type GetUpType(Type type) { - switch (type.Name) { - case "Byte": - case "SByte": - case "Int16": - case "UInt16": - case "Int32": - case "UInt32": - return typeof(Int64); - case "Int64": - case "UInt64": - return typeof(BigInteger); - case "Single": - return typeof(double); - } - return null; - } - public virtual bool HandleException(Exception ex, DynamicCallDispatcher dispatcher, OperatorImplementation failedTarget, EvaluationContext context) { - return false; - } - #endregion - - #region Converters - protected virtual TypeConverter GetConverter(Type fromType, Type toType) { - if (fromType == toType) return null; - var result = TypeConverters.Find(fromType, toType); - if (result != null) return result; - string err = string.Format(Resources.ErrCannotConvertValue, fromType, toType); - throw new Exception(err); - } - #endregion - - - public event EventHandler ConsoleWrite; - protected void OnConsoleWrite(EvaluationContext context, string text) { - if (ConsoleWrite != null) { - ConsoleWriteEventArgs args = new ConsoleWriteEventArgs(text); - ConsoleWrite(this, args); - } - context.Write(text); - } - - //Temporarily put it here - public static void Check(bool condition, string message, params object[] args) { - if (condition) return; - if (args != null) - message = string.Format(message, args); - throw new RuntimeException(message); - } - - - - }//class - -}//namespace - diff --git a/sources/shaders/Irony/Interpreter/LanguageRuntime_Init.cs b/sources/shaders/Irony/Interpreter/LanguageRuntime_Init.cs deleted file mode 100644 index 831287d19d..0000000000 --- a/sources/shaders/Irony/Interpreter/LanguageRuntime_Init.cs +++ /dev/null @@ -1,350 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -//using Irony.Compiler; - -namespace Irony.Interpreter { - using BigInteger = Microsoft.Scripting.Math.BigInteger; - using Complex = Microsoft.Scripting.Math.Complex64; - - //Initialization of Runtime - public partial class LanguageRuntime { - - public virtual void Init() { - InitBaseTypeList(); - InitTypeConverters(); - InitOperatorImplementations(); - } - - public virtual void InitBaseTypeList() { - BaseTypeSequence.Clear(); - BaseTypeSequence.AddRange(new Type[] { - typeof(string), typeof(Complex), typeof(Double), typeof(Single), typeof(Decimal), - typeof(BigInteger), - typeof(UInt64), typeof(Int64), typeof(UInt32), typeof(Int32), typeof(UInt16), typeof(Int16), typeof(byte), typeof(sbyte), typeof(bool) - }); - } - - public virtual void InitTypeConverters() { - bool useComplex = BaseTypeSequence.Contains(typeof(Complex)); - bool useBigInt = BaseTypeSequence.Contains(typeof(BigInteger)); - //->string - Type T = typeof(string); - foreach (Type t in BaseTypeSequence) - if (t != T) - TypeConverters.Add(t, T, ConvertAnyToString); - //->Complex - if (useComplex) { - TypeConverters.Add(typeof(sbyte), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(byte), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(Int16), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(UInt16), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(Int32), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(UInt32), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(Int64), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(UInt64), typeof(Complex), ConvertAnyToComplex); - TypeConverters.Add(typeof(Single), typeof(Complex), ConvertAnyToComplex); - if (useBigInt) - TypeConverters.Add(typeof(BigInteger), typeof(Complex), ConvertBigIntToComplex); - } - //->BigInteger - if (useBigInt) { - TypeConverters.Add(typeof(sbyte), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(byte), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(Int16), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(UInt16), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(Int32), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(UInt32), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(Int64), typeof(BigInteger), ConvertAnyIntToBigInteger); - TypeConverters.Add(typeof(UInt64), typeof(BigInteger), ConvertAnyIntToBigInteger); - } - - //->Double - TypeConverters.Add(typeof(sbyte), typeof(double), value => (double)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(double), value => (double)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(double), value => (double)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(double), value => (double)(UInt16)value); - TypeConverters.Add(typeof(Int32), typeof(double), value => (double)(Int32)value); - TypeConverters.Add(typeof(UInt32), typeof(double), value => (double)(UInt32)value); - TypeConverters.Add(typeof(Int64), typeof(double), value => (double)(Int64)value); - TypeConverters.Add(typeof(UInt64), typeof(double), value => (double)(UInt64)value); - TypeConverters.Add(typeof(Single), typeof(double), value => (double)(Single)value); - if (useBigInt) - TypeConverters.Add(typeof(BigInteger), typeof(double), value => ((BigInteger)value).ToDouble(null)); - //->Single - TypeConverters.Add(typeof(sbyte), typeof(Single), value => (Single)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(Single), value => (Single)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(Single), value => (Single)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(Single), value => (Single)(UInt16)value); - TypeConverters.Add(typeof(Int32), typeof(Single), value => (Single)(Int32)value); - TypeConverters.Add(typeof(UInt32), typeof(Single), value => (Single)(UInt32)value); - TypeConverters.Add(typeof(Int64), typeof(Single), value => (Single)(Int64)value); - TypeConverters.Add(typeof(UInt64), typeof(Single), value => (Single)(UInt64)value); - if (useBigInt) - TypeConverters.Add(typeof(BigInteger), typeof(Single), value => (Single)((BigInteger)value).ToDouble(null)); - - //->UInt64 - TypeConverters.Add(typeof(sbyte), typeof(UInt64), value => (UInt64)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(UInt64), value => (UInt64)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(UInt64), value => (UInt64)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(UInt64), value => (UInt64)(UInt16)value); - TypeConverters.Add(typeof(Int32), typeof(UInt64), value => (UInt64)(Int32)value); - TypeConverters.Add(typeof(UInt32), typeof(UInt64), value => (UInt64)(UInt32)value); - TypeConverters.Add(typeof(Int64), typeof(UInt64), value => (UInt64)(Int64)value); - //->Int64 - TypeConverters.Add(typeof(sbyte), typeof(Int64), value => (Int64)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(Int64), value => (Int64)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(Int64), value => (Int64)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(Int64), value => (Int64)(UInt16)value); - TypeConverters.Add(typeof(Int32), typeof(Int64), value => (Int64)(Int32)value); - TypeConverters.Add(typeof(UInt32), typeof(Int64), value => (Int64)(UInt32)value); - //->UInt32 - TypeConverters.Add(typeof(sbyte), typeof(UInt32), value => (UInt32)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(UInt32), value => (UInt32)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(UInt32), value => (UInt32)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(UInt32), value => (UInt32)(UInt16)value); - TypeConverters.Add(typeof(Int32), typeof(UInt32), value => (UInt32)(Int32)value); - //->Int32 - TypeConverters.Add(typeof(sbyte), typeof(Int32), value => (Int32)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(Int32), value => (Int32)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(Int32), value => (Int32)(Int16)value); - TypeConverters.Add(typeof(UInt16), typeof(Int32), value => (Int32)(UInt16)value); - //->UInt16 - TypeConverters.Add(typeof(sbyte), typeof(UInt16), value => (UInt16)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(UInt16), value => (UInt16)(byte)value); - TypeConverters.Add(typeof(Int16), typeof(UInt16), value => (UInt16)(Int16)value); - //->Int16 - TypeConverters.Add(typeof(sbyte), typeof(Int16), value => (Int16)(sbyte)value); - TypeConverters.Add(typeof(byte), typeof(Int16), value => (Int16)(byte)value); - //->byte - TypeConverters.Add(typeof(sbyte), typeof(byte), value => (byte)(sbyte)value); - } - - public static object ConvertAnyToString(object value) { - return value == null ? string.Empty : value.ToString(); - } - - public static object ConvertBigIntToComplex(object value) { - BigInteger bi = (BigInteger) value; - return new Complex(bi.ToFloat64()); - } - - public static object ConvertAnyToComplex(object value) { - double d = Convert.ToDouble(value); - return new Complex(d); - } - public static object ConvertAnyIntToBigInteger(object value) { - long l = Convert.ToInt64(value); - return BigInteger.Create(l); - } - - public virtual void InitOperatorImplementations() { - _baseOperatorImplementations = new OperatorImplementationTable(); - - // note that arithmetics on byte, sbyte, int16, uint16 are performed in Int32 format (the way it's done in c# I guess) - // so the result is always Int32 - // we don't force the result back to original type - I don't think it's necessary - // For each operator, we add a series of implementation methods for same-type operands. They are saved as DispatchRecords in - // operator dispatchers. This happens at initialization time. Dispatch records for mismatched argument types (ex: int + double) - // are created on-the-fly at execution time. - string op; - - op = "+"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x + (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x + (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x + (Int16)y); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x + (UInt16)y); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x + (Int32)y)); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x + (UInt32)y)); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x + (Int64)y)); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x + (UInt64)y)); - AddImplementation(op, typeof(Single), (x, y) => (Single)x + (Single)y); - AddImplementation(op, typeof(double), (x, y) => (double)x + (double)y); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x + (BigInteger)y); - AddImplementation(op, typeof(Complex), (x, y) => (Complex)x + (Complex)y); - AddImplementation(op, typeof(string), (x, y) => (string)x + (string)y); - - op = "-"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x - (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x - (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x - (Int16)y); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x - (UInt16)y); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x - (Int32)y)); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x - (UInt32)y)); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x - (Int64)y)); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x - (UInt64)y)); - AddImplementation(op, typeof(Single), (x, y) => (Single)x - (Single)y); - AddImplementation(op, typeof(double), (x, y) => (double)x - (double)y); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x - (BigInteger)y); - AddImplementation(op, typeof(Complex), (x, y) => (Complex)x - (Complex)y); - - op = "*"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x * (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x * (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => checked((Int16)x * (Int16)y)); - AddImplementation(op, typeof(UInt16), (x, y) => checked((UInt16)x * (UInt16)y)); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x * (Int32)y)); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x * (UInt32)y)); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x * (Int64)y)); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x * (UInt64)y)); - AddImplementation(op, typeof(Single), (x, y) => (Single)x * (Single)y); - AddImplementation(op, typeof(double), (x, y) => (double)x * (double)y); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x * (BigInteger)y); - AddImplementation(op, typeof(Complex), (x, y) => (Complex)x * (Complex)y); - - op = "/"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x / (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x / (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => checked((Int16)x / (Int16)y)); - AddImplementation(op, typeof(UInt16), (x, y) => checked((UInt16)x / (UInt16)y)); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x / (Int32)y)); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x / (UInt32)y)); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x / (Int64)y)); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x / (UInt64)y)); - AddImplementation(op, typeof(Single), (x, y) => (Single)x / (Single)y); - AddImplementation(op, typeof(double), (x, y) => (double)x / (double)y); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x / (BigInteger)y); - AddImplementation(op, typeof(Complex), (x, y) => (Complex)x / (Complex)y); - - op = "&"; - AddImplementation(op, typeof(bool), (x, y) => (bool)x & (bool)y); - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x & (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x & (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x & (Int16)y); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x & (UInt16)y); - AddImplementation(op, typeof(Int32), (x, y) => (Int32)x & (Int32)y); - AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x & (UInt32)y); - AddImplementation(op, typeof(Int64), (x, y) => (Int64)x & (Int64)y); - AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x & (UInt64)y); - - op = "|"; - AddImplementation(op, typeof(bool), (x, y) => (bool)x | (bool)y); - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x | (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x | (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x | (Int16)y); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x | (UInt16)y); - AddImplementation(op, typeof(Int32), (x, y) => (Int32)x | (Int32)y); - AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x | (UInt32)y); - AddImplementation(op, typeof(Int64), (x, y) => (Int64)x | (Int64)y); - AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x | (UInt64)y); - - op = "^"; //XOR - AddImplementation(op, typeof(bool), (x, y) => (bool)x ^ (bool)y); - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x ^ (sbyte)y); - AddImplementation(op, typeof(byte), (x, y) => (byte)x ^ (byte)y); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x ^ (Int16)y); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x ^ (UInt16)y); - AddImplementation(op, typeof(Int32), (x, y) => (Int32)x ^ (Int32)y); - AddImplementation(op, typeof(UInt32), (x, y) => (UInt32)x ^ (UInt32)y); - AddImplementation(op, typeof(Int64), (x, y) => (Int64)x ^ (Int64)y); - AddImplementation(op, typeof(UInt64), (x, y) => (UInt64)x ^ (UInt64)y); - - //Note that && and || are special forms, not binary operators - - op = "<"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x < (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x < (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x < (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x < (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x < (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x < (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x < (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x < (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x < (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x < (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x < (BigInteger)y, BoolResultConverter); - - op = ">"; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x > (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x > (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x > (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x > (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x > (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x > (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x > (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x > (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x > (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x > (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x > (BigInteger)y, BoolResultConverter); - - op = "<="; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x <= (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x <= (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x <= (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x <= (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x <= (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x <= (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x <= (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x <= (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x <= (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x <= (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x <= (BigInteger)y, BoolResultConverter); - - op = ">="; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x >= (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x >= (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x >= (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x >= (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x >= (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x >= (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x >= (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x >= (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x >= (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x >= (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x >= (BigInteger)y, BoolResultConverter); - - op = "=="; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x == (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x == (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x == (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x == (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x == (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x == (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x == (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x == (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x == (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x == (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x == (BigInteger)y, BoolResultConverter); - - op = "!="; - AddImplementation(op, typeof(sbyte), (x, y) => (sbyte)x != (sbyte)y, BoolResultConverter); - AddImplementation(op, typeof(byte), (x, y) => (byte)x != (byte)y, BoolResultConverter); - AddImplementation(op, typeof(Int16), (x, y) => (Int16)x != (Int16)y, BoolResultConverter); - AddImplementation(op, typeof(UInt16), (x, y) => (UInt16)x != (UInt16)y, BoolResultConverter); - AddImplementation(op, typeof(Int32), (x, y) => checked((Int32)x != (Int32)y), BoolResultConverter); - AddImplementation(op, typeof(UInt32), (x, y) => checked((UInt32)x != (UInt32)y), BoolResultConverter); - AddImplementation(op, typeof(Int64), (x, y) => checked((Int64)x != (Int64)y), BoolResultConverter); - AddImplementation(op, typeof(UInt64), (x, y) => checked((UInt64)x != (UInt64)y), BoolResultConverter); - AddImplementation(op, typeof(Single), (x, y) => (Single)x != (Single)y, BoolResultConverter); - AddImplementation(op, typeof(double), (x, y) => (double)x != (double)y, BoolResultConverter); - AddImplementation(op, typeof(BigInteger), (x, y) => (BigInteger)x != (BigInteger)y, BoolResultConverter); - - }//method - - protected void AddImplementation(string op, Type baseType, BinaryOperatorMethod baseMethod) { - AddImplementation(op, baseType, baseMethod, null); - } - protected void AddImplementation(string op, Type baseType, BinaryOperatorMethod baseMethod, TypeConverter resultConverter) { - var key = OperatorDispatchKey.CreateFromTypes(op, baseType, baseType); - var imp = new OperatorImplementation(key, baseType, baseMethod, null, null, resultConverter); - _baseOperatorImplementations.Add(key, imp); - } - - }//class - - - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/RuntimeException.cs b/sources/shaders/Irony/Interpreter/RuntimeException.cs deleted file mode 100644 index e378881b4d..0000000000 --- a/sources/shaders/Irony/Interpreter/RuntimeException.cs +++ /dev/null @@ -1,29 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; - -namespace Irony.Interpreter { - public class RuntimeException : Exception { - public SourceLocation Location; - public RuntimeException(string message) : base(message) { } - public RuntimeException(string message, Exception inner) : base(message, inner) { } - public RuntimeException(string message, Exception inner, SourceLocation location) : base(message, inner) { - Location = location; - } - - } -} diff --git a/sources/shaders/Irony/Interpreter/ScriptInterpreter.cs b/sources/shaders/Irony/Interpreter/ScriptInterpreter.cs deleted file mode 100644 index 53eec9ca02..0000000000 --- a/sources/shaders/Irony/Interpreter/ScriptInterpreter.cs +++ /dev/null @@ -1,242 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using Irony.Interpreter.Ast; -using Irony.Parsing; - -namespace Irony.Interpreter { - - public enum InterpreterStatus { - Ready, - Evaluating, - WaitingMoreInput, //command line only - SyntaxError, - RuntimeError, - Aborted - } - - public class ScriptInterpreter { - #region Fields and properties - public readonly LanguageData Language; - public readonly LanguageRuntime Runtime; - public readonly EvaluationContext EvaluationContext; - public readonly Parser Parser; - - public Thread WorkerThread { get; private set; } - public Exception LastException {get; private set;} - - public InterpreterStatus Status { get; private set; } - - public bool RethrowExceptions = true; - public bool PrintParseErrors = true; - public ParseMode ParseMode { - get { return Parser.Context.Mode; } - set { Parser.Context.Mode = value; } - } - public ValuesTable Globals { - get { return EvaluationContext.TopFrame.Values; } - } - //internal, real status of interpreter. The public Status field gets updated only on exit from public methods - // We want to make sure external code sees interpeter as BUSY until we actually completed operation internally - private InterpreterStatus _internalStatus; - #endregion - - #region constructors - public ScriptInterpreter(Grammar grammar) : this(new LanguageData(grammar)) { } - - public ScriptInterpreter(LanguageData language) { - Language = language; - Runtime = Language.Grammar.CreateRuntime(Language); - Parser = new Parser(Language); - EvaluationContext = new EvaluationContext(Runtime); - Status = _internalStatus = InterpreterStatus.Ready; - } - #endregion - - #region Evaluate overloads - public void Evaluate(string script) { - Script = script; - Evaluate(); - } - public void Evaluate(ParseTree parsedScript) { - ParsedScript = parsedScript; - Evaluate(); - } - public void Evaluate() { - try { - _internalStatus = Status = InterpreterStatus.Evaluating; - ParseAndEvaluate(); - } finally { - Status = _internalStatus; - } - } - - public void EvaluateAsync(string script) { - Script = script; - EvaluateAsync(); - } - public void EvaluateAsync(ParseTree parsedScript) { - ParsedScript = parsedScript; - EvaluateAsync(); - } - public void EvaluateAsync() { - CheckNotBusy(); - Status = _internalStatus = InterpreterStatus.Evaluating; - WorkerThread = new Thread(AsyncThreadStart); - WorkerThread.Start(null); - } - #endregion - - #region Other public members: Script, ParsedScript, IsBusy(), GetOutput() - public string Script { - get { return _script; } - set { - CheckNotBusy(); - _script = value; - _parsedScript = null; - } - } string _script; - - public ParseTree ParsedScript { - get { return _parsedScript; } - set { - _parsedScript = value; - _script = (_parsedScript == null ? null : _parsedScript.SourceText); - } - } ParseTree _parsedScript; - - public bool IsBusy() { - return Status == InterpreterStatus.Evaluating; - } - - public string GetOutput() { - return EvaluationContext.OutputBuffer.ToString(); - } - public void ClearOutputBuffer() { - EvaluationContext.OutputBuffer.Length = 0; - } - - public ParserMessageList GetParserMessages() { - if (ParsedScript == null) - return new ParserMessageList(); - else - return ParsedScript.ParserMessages; - } - - public void Abort() { - try { - if (WorkerThread == null) return; - WorkerThread.Abort(); - WorkerThread.Join(50); - } catch { } - WorkerThread = null; - } - #endregion - - #region private implementations ------------------------------------------------------------------------------- - private void AsyncThreadStart(object data) { - try { - ParseAndEvaluate(); - } finally { - Status = _internalStatus; - } - } - private void CheckNotBusy() { - if (IsBusy()) - throw new Exception(Resources.ErrInterpreterIsBusy); - } - - private void ParseAndEvaluate() { - EvaluationContext.EvaluationTime = 0; - try { - LastException = null; - if(ParsedScript == null) { - //don't evaluate empty strings, just return - if (Script == null || Script.Trim() == string.Empty && Status == InterpreterStatus.Ready) return; - ParsedScript = this.Parser.Parse(Script, "source"); - CheckParseStatus(); - if(_internalStatus != InterpreterStatus.Evaluating) return; - } - if(ParsedScript == null) - return; - EvaluateParsedScript(); - _internalStatus = InterpreterStatus.Ready; - } catch (Exception ex) { - LastException = ex; - _internalStatus = InterpreterStatus.RuntimeError; - if (LastException != null && RethrowExceptions) - throw; - } - } - - private void EvaluateParsedScript() { - var iRoot = GetAstInterface(); - if (iRoot == null) return; - EvaluationContext.ClearLastResult(); - var start = Environment.TickCount; - iRoot.Evaluate(EvaluationContext, AstMode.Read); - EvaluationContext.EvaluationTime = Environment.TickCount - start; - if (EvaluationContext.HasLastResult) - EvaluationContext.Write(EvaluationContext.LastResult + Environment.NewLine); - } - - private IInterpretedAstNode GetAstInterface() { - Check(ParsedScript != null, Resources.ErrParseTreeNull); - Check(ParsedScript.Root != null, Resources.ErrParseTreeRootNull); - var astNode = ParsedScript.Root.AstNode; - Check(astNode != null, Resources.ErrRootAstNodeNull); - var iInterpNode = astNode as IInterpretedAstNode; - Check(iInterpNode != null, Resources.ErrRootAstNoInterface); - return iInterpNode; - } - - private bool CheckParseStatus() { - if (ParsedScript == null) return false; - if (ParsedScript.HasErrors()) { - _internalStatus = InterpreterStatus.SyntaxError; - if (PrintParseErrors) { - foreach(var err in ParsedScript.ParserMessages) { - var msg = string.Format(Resources.ErrOutErrorPrintFormat, err.Location.ToUiString(), err.Message); - this.EvaluationContext.OutputBuffer.AppendLine(msg); - }//foreach - }//if - return false; - } - switch (ParsedScript.Status) { - case ParseTreeStatus.Error: - _internalStatus = InterpreterStatus.SyntaxError; - return false; - case ParseTreeStatus.Partial: - _internalStatus = InterpreterStatus.WaitingMoreInput; - return false; - default: - _internalStatus = InterpreterStatus.Evaluating; - return true; - } - } - - private static void Check(bool condition, string message) { - if (!condition) - throw new Exception(message); - } - - #endregion - - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/StackFrame.cs b/sources/shaders/Irony/Interpreter/StackFrame.cs deleted file mode 100644 index e512acf1a1..0000000000 --- a/sources/shaders/Irony/Interpreter/StackFrame.cs +++ /dev/null @@ -1,44 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using Irony.Parsing; -using Irony.Interpreter.Ast; - -namespace Irony.Interpreter { - - public class StackFrame { - public readonly EvaluationContext Context; - public string MethodName; //for debugging purposes - public StackFrame Parent; //Lexical parent - not the same as the caller - public StackFrame Caller; - internal ValuesTable Values; //global values for top frame; parameters and local variables for method frame - - public StackFrame(EvaluationContext context, ValuesTable globals) { - Context = context; - Values = globals; - if (Values == null) - Values = new ValuesTable(100); - } - - public StackFrame(EvaluationContext context, string methodName, StackFrame caller, StackFrame parent) { - MethodName = methodName; - Caller = caller; - Parent = parent; - Values = new ValuesTable(8); - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Interpreter/ValuesTable.cs b/sources/shaders/Irony/Interpreter/ValuesTable.cs deleted file mode 100644 index 4e76437866..0000000000 --- a/sources/shaders/Irony/Interpreter/ValuesTable.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; - -namespace Irony.Interpreter { - public class ValuesTable : Dictionary { - public ValuesTable(int capacity) : base(capacity) { } - }//class - - public class ValuesList : List { } -} diff --git a/sources/shaders/Irony/Irony.csproj b/sources/shaders/Irony/Irony.csproj deleted file mode 100644 index 31764b0a99..0000000000 --- a/sources/shaders/Irony/Irony.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - true - - - - - - false - false - * - Stride.Irony - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - MSBuild:Compile - True - True - Resources.resx - - - - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - - - - - - - - \ No newline at end of file diff --git a/sources/shaders/Irony/MS-PubLicense.Rtf b/sources/shaders/Irony/MS-PubLicense.Rtf deleted file mode 100644 index b623377bd0..0000000000 --- a/sources/shaders/Irony/MS-PubLicense.Rtf +++ /dev/null @@ -1,177 +0,0 @@ -{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi31507\deflang1033\deflangfe1033\themelang1033\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset1\fprq2{\*\panose 02040503050406030204}Cambria Math;} -{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;}{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} -{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f39\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\f40\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f44\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\f45\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;} -{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} -{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} -{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} -{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} -{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} -{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} -{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} -{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;}{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;} -{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} -{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} -{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} -{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; -\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\*\defchp \fs22\loch\af31506\hich\af31506\dbch\af31505 }{\*\defpap \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 -\ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* -\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\sa200\sl276\slmult1 -\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 \fs22\lang1033\langfe1033\loch\f31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 -\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}}{\*\rsidtbl \rsid11612883}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info{\author dinov}{\operator dinov} -{\creatim\yr2007\mo10\dy30\hr14\min43}{\revtim\yr2007\mo10\dy30\hr14\min43}{\version2}{\edmins1}{\nofpages2}{\nofwords404}{\nofchars2212}{\*\company Microsoft}{\nofcharsws2611}{\vern32893}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/office/word/200 -3/wordml}}\paperw12240\paperh15840\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect -\widowctrl\ftnbj\aenddoc\trackmoves1\trackformatting1\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors0\horzdoc\dghspace120\dgvspace120\dghorigin1701 -\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\rsidroot11612883 \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0\ltrpar \sectd \ltrsect\linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2 -\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6 -\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang -{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\ql \li0\ri0\sb100\sa100\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 \rtlch\fcs1 \af31507\afs22\alang1025 \ltrch\fcs0 -\fs22\lang1033\langfe1033\loch\af31506\hich\af31506\dbch\af31505\cgrid\langnp1033\langfenp1033 {\rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f0\fs28\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 Microsoft }{\rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 -\b\f0\fs28\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 Public }{\rtlch\fcs1 \ab\af0\afs28 \ltrch\fcs0 \b\f0\fs28\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 License (Ms-PL) -\par }{\rtlch\fcs1 \ab\af0\afs24 \ltrch\fcs0 \b\f0\fs24\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 -This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.}{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid11612883 -\par }{\rtlch\fcs1 \ab\af0\afs36 \ltrch\fcs0 \b\f0\fs36\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 1. Definitions -\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 \hich\f0 The terms \'93\loch\f0 \hich\f0 reproduce,\'94\loch\f0 \hich\f0 \'93\loch\f0 \hich\f0 reproduction,\'94\loch\f0 \hich\f0 \'93 -\hich\af0\dbch\af31505\loch\f0 \hich\f0 derivative works,\'94\loch\f0 \hich\f0 and \'93\loch\f0 \hich\f0 distribution\'94\loch\f0 have the same meaning here as under U.S. copyright law. -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 A \'93\loch\f0 \hich\f0 contribution\'94\loch\f0 is the original software, or any additions or changes to the software. -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 A \'93\loch\f0 \hich\f0 contributor\'94\loch\f0 is any person that distributes its contribution under this\hich\af0\dbch\af31505\loch\f0 license. -\par \loch\af0\dbch\af31505\hich\f0 \'93\loch\f0 \hich\f0 Licensed patents\'94\loch\f0 are a contributor\hich\f0 \rquote \loch\f0 s patent claims that read directly on its contribution. -\par }{\rtlch\fcs1 \ab\af0\afs36 \ltrch\fcs0 \b\f0\fs36\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 2. Grant of Rights -\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contrib -\hich\af0\dbch\af31505\loch\f0 utor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. - -\par \hich\af0\dbch\af31505\loch\f0 (B) Patent Grant- Subject to th\hich\af0\dbch\af31505\loch\f0 -e terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or o -\hich\af0\dbch\af31505\loch\f0 t\hich\af0\dbch\af31505\loch\f0 herwise dispose of its contribution in the software or derivative works of the contribution in the software. -\par }{\rtlch\fcs1 \ab\af0\afs36 \ltrch\fcs0 \b\f0\fs36\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 3. Conditions and Limitations -\par }{\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid11612883 \hich\af0\dbch\af31505\loch\f0 (A) No Trademark License- This license does not grant you rights to use any contributors\hich\f0 \rquote \loch\f0 name, logo, or trademarks. -\par \hich\af0\dbch\af31505\loch\f0 (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. -\par \hich\af0\dbch\af31505\loch\f0 (C) If you distribute any portion of the software, you must ret\hich\af0\dbch\af31505\loch\f0 ain all copyright, patent, trademark, and attribution notices that are present in the software. -\par \hich\af0\dbch\af31505\loch\f0 (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with y\hich\af0\dbch\af31505\loch\f0 -our distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. -\par \hich\af0\dbch\af31505\loch\f0 \hich\f0 (E) The software is licensed \'93\loch\f0 \hich\f0 as-is.\'94\loch\f0 You bear the risk of using it. The contributors give \hich\af0\dbch\af31505\loch\f0 -no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantabil -\hich\af0\dbch\af31505\loch\f0 i\hich\af0\dbch\af31505\loch\f0 ty, fitness for a particular purpose and non-infringement. -\par }\pard \ltrpar\ql \li0\ri0\nowidctlpar\wrapdefault\faauto\rin0\lin0\itap0 {\rtlch\fcs1 \af0\afs24 \ltrch\fcs0 \f0\fs24\insrsid11612883 -\par }{\*\themedata 504b030414000600080000002100828abc13fa0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb6ac3301045f785fe83d0b6d8 -72ba28a5d8cea249777d2cd20f18e4b12d6a8f843409c9df77ecb850ba082d74231062ce997b55ae8fe3a00e1893f354e9555e6885647de3a8abf4fbee29bbd7 -2a3150038327acf409935ed7d757e5ee14302999a654e99e393c18936c8f23a4dc072479697d1c81e51a3b13c07e4087e6b628ee8cf5c4489cf1c4d075f92a0b -44d7a07a83c82f308ac7b0a0f0fbf90c2480980b58abc733615aa2d210c2e02cb04430076a7ee833dfb6ce62e3ed7e14693e8317d8cd0433bf5c60f53fea2fe7 -065bd80facb647e9e25c7fc421fd2ddb526b2e9373fed4bb902e182e97b7b461e6bfad3f010000ffff0300504b030414000600080000002100a5d6a7e7c00000 -00360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4fc7060abb08 -84a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b63095120f88d94fbc -52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462a1a82fe353 -bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f7468656d652f7468 -656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b4b0d592c9c -070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b4757e8d3f7 -29e245eb2b260a0238fd010000ffff0300504b03041400060008000000210096b5ade296060000501b0000160000007468656d652f7468656d652f7468656d65 -312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87615b8116d8 -a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad79482a9c04 -98f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b5d8a314d3c -94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab999fb7b471 -7509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9699640f671 -9e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd5868b37a088d1 -e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d60cf03ac1a5 -193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f9e7ef3f2d1 -17d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be15c308d3f2 -8acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a99793849c26ae6 -6252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d32a423279a -668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2af074481847 -bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86e877f0034e -16bafb0e258ebb4faf06b769e888340b103d3311da9750aa9d0a1cd3e4efca31a3508f6d0c5c5c398602f8e2ebc71591f5b616e24dd893aa3261fb44f95d843b -5974bb5c04f4edafb95b7892ec1108f3f98de75dc97d5772bdff7cc95d94cf672db4b3da0a6557f70db629362d72bcb0431e53c6066acac80d699a6409fb44d0 -8741bdce9c0e4971624a2378cceaba830b05366b90e0ea23aaa241845368b0eb9e2612ca8c742851ca251ceccc70256d8d87265dd96361531f186c3d9058edf2 -c00eafe8e1fc5c509031bb4d680e9f39a3154de0accc56ae644441edd76156d7429d995bdd88664a9dc3ad50197c38af1a0c16d684060441db02565e85f3b966 -0d0713cc48a0ed6ef7dedc2dc60b17e92219e180643ed27acffba86e9c94c78ab90980d8a9f0913ee49d62b512b79626fb06dccee2a432bbc60276b9f7dec44b -7904cfbca4f3f6443ab2a49c9c2c41476dafd55c6e7ac8c769db1bc399161ee314bc2e75cf8759081743be1236ec4f4d6693e5336fb672c5dc24a8c33585b5fb -9cc24e1d4885545b58463634cc5416022cd19cacfccb4d30eb45296023fd35a458598360f8d7a4003bbaae25e331f155d9d9a5116d3bfb9a95523e51440ca2e0 -088dd844ec6370bf0e55d027a012ae264c45d02f708fa6ad6da6dce29c255df9f6cae0ec38666984b372ab5334cf640b37795cc860de4ae2816e95b21be5ceaf -8a49f90b52a51cc6ff3355f47e0237052b81f6800fd7b802239daf6d8f0b1571a8426944fdbe80c6c1d40e8816b88b8569082ab84c36ff0539d4ff6dce591a26 -ade1c0a7f669880485fd484582903d284b26fa4e2156cff62e4b9265844c4495c495a9157b440e091bea1ab8aaf7760f4510eaa69a6465c0e04ec69ffb9e65d0 -28d44d4e39df9c1a52ecbd3607fee9cec7263328e5d661d3d0e4f62f44acd855ed7ab33cdf7bcb8ae889599bd5c8b3029895b6825696f6af29c239b75a5bb1e6 -345e6ee6c28117e73586c1a2214ae1be07e93fb0ff51e133fb65426fa843be0fb515c187064d0cc206a2fa926d3c902e907670048d931db4c1a44959d366ad93 -b65abe595f70a75bf03d616c2dd959fc7d4e6317cd99cbcec9c58b34766661c7d6766ca1a9c1b327531486c6f941c638c67cd22a7f75e2a37be0e82db8df9f30 -254d30c1372581a1f51c983c80e4b71ccdd28dbf000000ffff0300504b0304140006000800000021000dd1909fb60000001b010000270000007468656d652f74 -68656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f78277086f6fd3ba109126dd88d0add40384e4350d363f24 -51eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89d93b64b060828e6f37ed1567914b284d262452282e3198 -720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd5001996509affb3fd381a89672f1f165dfe514173d9850528 -a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100828abc13fa0000001c0200001300000000000000000000000000 -000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6a7e7c0000000360100000b000000000000000000000000 -002b0100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a0000001c00000000000000000000000000140200007468 -656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d001400060008000000210096b5ade296060000501b000016000000000000000000 -00000000d10200007468656d652f7468656d652f7468656d65312e786d6c504b01022d00140006000800000021000dd1909fb60000001b010000270000000000 -00000000000000009b0900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000960a00000000} -{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d -617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 -6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 -656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} -{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; -\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; -\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; -\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid;\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference; -\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography;\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 010500000200000018000000 -4d73786d6c322e534158584d4c5265616465722e352e3000000000000000000000060000 -d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff090006000000000000000000000001000000010000000000000000100000feffffff00000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -fffffffffffffffffdfffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffffffffffffec69d9888b8b3d4c859eaf6cd158be0f0000000000000000000000009055 -58f93d1bc801feffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 -000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000105000000000000}} \ No newline at end of file diff --git a/sources/shaders/Irony/Parsing/AstInterfaces.cs b/sources/shaders/Irony/Parsing/AstInterfaces.cs deleted file mode 100644 index 7fca31f1ac..0000000000 --- a/sources/shaders/Irony/Parsing/AstInterfaces.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - // These are generic interfaces for AST implementors. They define some basic interface that Parser needs to - // construct AST tree. Note that we expect more than one interpreter/AST implementation: Irony.Interpreter.Ast - // namespace provides just one of them. That's why these AST interfaces are here, and not in Interpreter.Ast namespace. - // In the future, I plan to introduce advanced interpreter, with its own set of AST classes - it will probably live - // in a separate assembly Irony.Interpreter2.dll. - - // Basic interface for AST nodes; Init method is the chance for AST node to get references to its child nodes, and all - // related information gathered during parsing - // Implementing this interface is a minimum required from custom AST node class to enable its creation by Irony - // parser. Alternatively, if your custom AST node class does not implement this interface then you can create - // and initialize node instances using AstNodeCreator delegate attached to corresponding non-terminal in your grammar. - public interface IAstNodeInit { - void Init(ParsingContext context, ParseTreeNode parseNode); - } - - // Grammar explorer uses this interface to discover and display the AST tree after parsing the input - // (Grammar Explorer additionally uses ToString method of the node to get the text representation of the node) - public interface IBrowsableAstNode { - SourceLocation Location { get; } - IEnumerable GetChildNodes(); - } - - //Simple visitor interface - public interface IAstVisitor { - void BeginVisit(IVisitableNode node); - void EndVisit(IVisitableNode node); - } - - public interface IVisitableNode { - void AcceptVisitor(IAstVisitor visitor); - } - - -} diff --git a/sources/shaders/Irony/Parsing/Data/Construction/GrammarDataBuilder.cs b/sources/shaders/Irony/Parsing/Data/Construction/GrammarDataBuilder.cs deleted file mode 100644 index ee0efb0758..0000000000 --- a/sources/shaders/Irony/Parsing/Data/Construction/GrammarDataBuilder.cs +++ /dev/null @@ -1,315 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing.Construction { - - internal class GrammarDataBuilder { - LanguageData _language; - Grammar _grammar; - GrammarData _grammarData; - int _unnamedCount; //internal counter for generating names for unnamed non-terminals - internal int _lastItemId; //each LR0Item gets its unique ID, last assigned (max) Id is kept in this field - - internal GrammarDataBuilder(LanguageData language) { - _language = language; - _grammar = _language.Grammar; - } - - internal void Build() { - _grammarData = _language.GrammarData; - CreateAugmentedRoots(); - CollectTermsFromGrammar(); - AssignWhitespaceAndDelimiters(); - InitTermLists(); - FillOperatorReportGroup(); - FindClosingBraces(); - CreateProductions(); - ComputeNonTerminalsNullability(_grammarData); - ComputeTailsNullability(_grammarData); - ValidateGrammar(); - } - - private void CreateAugmentedRoots() { - _grammarData.AugmentedRoot = CreateAugmentedRoot(_grammar.Root); - foreach(var snippetRoot in _grammar.SnippetRoots) - _grammarData.AugmentedSnippetRoots.Add(CreateAugmentedRoot(snippetRoot)); - } - - private NonTerminal CreateAugmentedRoot(NonTerminal root) { - var result = new NonTerminal(root.Name + "'", root + _grammar.Eof); - result.SetFlag(TermFlags.NoAstNode); //mark that we don't need AST node here - return result; - } - - private void CollectTermsFromGrammar() { - _unnamedCount = 0; - _grammarData.AllTerms.Clear(); - //Start with NonGrammarTerminals, and set IsNonGrammar flag - foreach (Terminal t in _grammarData.Grammar.NonGrammarTerminals) { - t.SetFlag(TermFlags.IsNonGrammar); - _grammarData.AllTerms.Add(t); - } - //Add main root - CollectTermsRecursive(_grammarData.AugmentedRoot); - foreach(var augmRoot in _grammarData.AugmentedSnippetRoots) - CollectTermsRecursive(augmRoot); - //Add syntax error explicitly - _grammarData.AllTerms.Add(_grammar.SyntaxError); - } - - private void CollectTermsRecursive(BnfTerm term) { - if (_grammarData.AllTerms.Contains(term)) return; - _grammarData.AllTerms.Add(term); - NonTerminal nt = term as NonTerminal; - if (nt == null) return; - - if (string.IsNullOrEmpty(nt.Name)) { - if (nt.Rule != null && !string.IsNullOrEmpty(nt.Rule.Name)) - nt.Name = nt.Rule.Name; - else - nt.Name = "Unnamed" + (_unnamedCount++); - } - if (nt.Rule == null) - _language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrNtRuleIsNull, nt.Name); - //check all child elements - foreach (BnfTermList elemList in nt.Rule.Data) - for (int i = 0; i < elemList.Count; i++) { - BnfTerm child = elemList[i]; - if (child == null) { - _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrRuleContainsNull, nt.Name, i); - continue; //for i loop - } - //Check for nested expression - convert to non-terminal - BnfExpression expr = child as BnfExpression; - if (expr != null) { - child = new NonTerminal(null, expr); - elemList[i] = child; - } - CollectTermsRecursive(child); - }//for i - }//method - - private void FillOperatorReportGroup() { - foreach(var group in _grammar.TermReportGroups) - if (group.GroupType == TermReportGroupType.Operator) { - foreach(var term in _grammarData.Terminals) - if (term.FlagIsSet(TermFlags.IsOperator)) - group.Terminals.Add(term); - return; - } - } - - private void FindClosingBraces() { - foreach(var term in _grammar.KeyTerms.Values) { - if (term.FlagIsSet(TermFlags.IsCloseBrace)) - _grammarData.ClosingBraces.Add(term.Text); - } - } - - private void AssignWhitespaceAndDelimiters() { - var delims = _grammar.Delimiters; - //if it was not assigned by language creator, let's guess them - if (delims == null) { - delims = string.Empty; - var commonDelims = ",;[](){}"; //chars usually used as delimiters in programming languages - foreach(var delim in commonDelims) - if (_grammar.KeyTerms.ContainsKey(delim.ToString())) //if language uses this char as a Term, then include it - delims += delim; - }//if - _grammarData.WhitespaceAndDelimiters = _grammar.WhitespaceChars + delims - + "\n" //in case if it is removed from whitespace chars by NewLineTerminal - + "\0"; //EOF: SourceStream returns this char when we reach end of file - } - - - private void InitTermLists() { - //Collect terminals and NonTerminals - foreach (BnfTerm term in _grammarData.AllTerms) { //remember - we may have hints, so it's not only terminals and non-terminals - if (term is NonTerminal) _grammarData.NonTerminals.Add((NonTerminal)term); - if (term is Terminal) _grammarData.Terminals.Add((Terminal)term); - } - _grammarData.Terminals.Sort(Terminal.ByName); - //Mark keywords - any "word" symbol directly mentioned in the grammar - foreach (var term in _grammarData.Terminals) { - var symTerm = term as KeyTerm; - if (symTerm == null) continue; - if (!string.IsNullOrEmpty(symTerm.Text) && char.IsLetter(symTerm.Text[0])) - symTerm.SetFlag(TermFlags.IsKeyword); - }//foreach term - //Init all terms - foreach (var term in _grammarData.AllTerms) - term.Init(_grammarData); - }//method - - private void CreateProductions() { - _lastItemId = 0; - //CheckWrapTailHints() method may add non-terminals on the fly, so we have to use for loop here (not foreach) - for (int i = 0; i < _grammarData.NonTerminals.Count; i++) { - var nt = _grammarData.NonTerminals[i]; - nt.Productions.Clear(); - //Get data (sequences) from both Rule and ErrorRule - BnfExpressionData allData = new BnfExpressionData(); - allData.AddRange(nt.Rule.Data); - if (nt.ErrorRule != null) - allData.AddRange(nt.ErrorRule.Data); - //actually create productions for each sequence - foreach (BnfTermList prodOperands in allData) { - Production prod = CreateProduction(nt, prodOperands); - nt.Productions.Add(prod); - } //foreach prodOperands - // insert pending custom hints in all productions - nt.InsertCustomHints(); - } - } - - private Production CreateProduction(NonTerminal lvalue, BnfTermList operands) { - Production prod = new Production(lvalue); - GrammarHintList hints = null; - //create RValues list skipping Empty terminal and collecting grammar hints - foreach (BnfTerm operand in operands) { - if (operand == _grammar.Empty) - continue; - //Collect hints as we go - they will be added to the next non-hint element - GrammarHint hint = operand as GrammarHint; - if (hint != null) { - if (hints == null) hints = new GrammarHintList(); - hints.Add(hint); - continue; - } - //Add the operand and create LR0 Item - prod.RValues.Add(operand); - prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count - 1, hints)); - hints = null; - }//foreach operand - //set the flags - if (prod.RValues.Count == 0) - prod.Flags |= ProductionFlags.IsEmpty; - //Add final LRItem - ComputeProductionFlags(prod); - prod.LR0Items.Add(new LR0Item(_lastItemId++, prod, prod.RValues.Count, hints)); - return prod; - } - - private void ComputeProductionFlags(Production production) { - production.Flags = ProductionFlags.None; - foreach (var rv in production.RValues) { - //Check if it is a Terminal or Error element - var t = rv as Terminal; - if (t != null) { - production.Flags |= ProductionFlags.HasTerminals; - if (t.Category == TokenCategory.Error) production.Flags |= ProductionFlags.IsError; - } - if (rv.FlagIsSet(TermFlags.IsPunctuation)) continue; - }//foreach - var lvalue = production.LValue; - //Set IsListBuilder flag - if (production.RValues.Count > 0 && production.RValues[0] == production.LValue - && lvalue.FlagIsSet(TermFlags.IsList)) - production.Flags |= ProductionFlags.IsListBuilder; - }//method - - private static void ComputeNonTerminalsNullability(GrammarData data) { - NonTerminalList undecided = data.NonTerminals; - while (undecided.Count > 0) { - NonTerminalList newUndecided = new NonTerminalList(); - foreach (NonTerminal nt in undecided) - if (!ComputeNullability(nt)) - newUndecided.Add(nt); - if (undecided.Count == newUndecided.Count) return; //we didn't decide on any new, so we're done - undecided = newUndecided; - }//while - } - - private static bool ComputeNullability(NonTerminal nonTerminal) { - foreach (Production prod in nonTerminal.Productions) { - if (prod.RValues.Count == 0) { - nonTerminal.SetFlag(TermFlags.IsNullable); - return true; //decided, Nullable - }//if - //If production has terminals, it is not nullable and cannot contribute to nullability - if (prod.IsSet(ProductionFlags.HasTerminals)) continue; - //Go thru all elements of production and check nullability - bool allNullable = true; - foreach (BnfTerm child in prod.RValues) { - allNullable &= child.FlagIsSet(TermFlags.IsNullable); - }//foreach child - if (allNullable) { - nonTerminal.SetFlag(TermFlags.IsNullable); - return true; - } - }//foreach prod - return false; //cannot decide - } - - private static void ComputeTailsNullability(GrammarData data) { - foreach (var nt in data.NonTerminals) { - foreach (var prod in nt.Productions) { - var count = prod.LR0Items.Count; - for (int i = count - 1; i >= 0; i--) { - var item = prod.LR0Items[i]; - item.TailIsNullable = true; - if (item.Current == null) continue; - if (!item.Current.FlagIsSet(TermFlags.IsNullable)) - break; //for i - }//for i - }//foreach prod - } - } - - #region Grammar Validation - private void ValidateGrammar() { - var createAst = _grammar.FlagIsSet(LanguageFlags.CreateAst); - var missingAstTypeSet = new NonTerminalSet(); - var invalidTransSet = new NonTerminalSet(); - foreach(var nt in _grammarData.NonTerminals) { - //Check that if CreateAst flag is set then AstNodeType or AstNodeCreator is assigned on all non-transient nodes. - if (createAst && nt.AstNodeCreator == null && nt.AstNodeType == null && !nt.FlagIsSet(TermFlags.NoAstNode)) - missingAstTypeSet.Add(nt); - if (nt.FlagIsSet(TermFlags.IsTransient)) { - //List non-terminals cannot be marked transient - otherwise there may be some ambiguities and inconsistencies - if (nt.FlagIsSet(TermFlags.IsList)) - _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrListCannotBeTransient, nt.Name); - //Count number of non-punctuation child nodes in each production - foreach(var prod in nt.Productions) - if (CountNonPunctuationTerms(prod) > 1) invalidTransSet.Add(nt); - }//if transient - //Validate error productions - foreach(var prod in nt.Productions) - if (prod.IsSet(ProductionFlags.IsError)) { - var lastTerm = prod.RValues[prod.RValues.Count -1]; - if (!(lastTerm is Terminal) || lastTerm == _grammar.SyntaxError) - _language.Errors.Add(GrammarErrorLevel.Warning, null, Resources.ErrLastTermOfErrorProd, nt.Name); - // "The last term of error production must be a terminal. NonTerminal: {0}" - }//foreach prod - }//foreac nt - - if (missingAstTypeSet.Count > 0) - _language.Errors.Add(GrammarErrorLevel.Warning, null, Resources.ErrNodeTypeNotSetOn, missingAstTypeSet.ToString()); - if (invalidTransSet.Count > 0) - _language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrTransientNtMustHaveOneTerm,invalidTransSet.ToString()); - }//method - - private int CountNonPunctuationTerms(Production production) { - int count = 0; - foreach(var rvalue in production.RValues) - if (!rvalue.FlagIsSet(TermFlags.IsPunctuation)) count++; - return count; - } - #endregion - - }//class -} diff --git a/sources/shaders/Irony/Parsing/Data/Construction/LanguageDataBuilder.cs b/sources/shaders/Irony/Parsing/Data/Construction/LanguageDataBuilder.cs deleted file mode 100644 index 349453ccd5..0000000000 --- a/sources/shaders/Irony/Parsing/Data/Construction/LanguageDataBuilder.cs +++ /dev/null @@ -1,64 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; - -namespace Irony.Parsing.Construction { - internal class LanguageDataBuilder { - - internal LanguageData Language; - Grammar _grammar; - - public LanguageDataBuilder(LanguageData language) { - Language = language; - _grammar = Language.Grammar; - } - - public bool Build() { - var sw = new Stopwatch(); - try { - if (_grammar.Root == null) - Language.Errors.AddAndThrow(GrammarErrorLevel.Error, null, Resources.ErrRootNotSet); - sw.Start(); - var gbld = new GrammarDataBuilder(Language); - gbld.Build(); - //Just in case grammar author wants to customize something... - _grammar.OnGrammarDataConstructed(Language); - var pbld = new ParserDataBuilder(Language); - pbld.Build(); - Validate(); - //call grammar method, a chance to tweak the automaton - _grammar.OnLanguageDataConstructed(Language); - return true; - } catch (GrammarErrorException) { - return false; //grammar error should be already added to Language.Errors collection - } finally { - Language.ErrorLevel = Language.Errors.GetMaxLevel(); - sw.Stop(); - Language.ConstructionTime = sw.ElapsedMilliseconds; - } - - } - - #region Language Data Validation - private void Validate() { - - }//method - #endregion - - - }//class -} diff --git a/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder.cs b/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder.cs deleted file mode 100644 index d2e3ed749f..0000000000 --- a/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder.cs +++ /dev/null @@ -1,462 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Diagnostics; - -namespace Irony.Parsing.Construction { - - // Methods constructing LALR automaton. - // See _about_parser_construction.txt file in this folder for important comments - - internal partial class ParserDataBuilder { - LanguageData _language; - internal ParserData Data; - Grammar _grammar; - ParserStateHash _stateHash = new ParserStateHash(); - - internal ParserDataBuilder(LanguageData language) { - _language = language; - _grammar = _language.Grammar; - } - - public void Build() { - _stateHash.Clear(); - Data = _language.ParserData; - CreateParserStates(); - var itemsNeedLookaheads = GetReduceItemsInInadequateState(); - ComputeTransitions(itemsNeedLookaheads); - ComputeLookaheads(itemsNeedLookaheads); - ComputeAndResolveConflicts(); - CreateRemainingReduceActions(); - ComputeStatesExpectedTerminals(); - }//method - - #region Creating parser states - private void CreateParserStates() { - var grammarData = _language.GrammarData; - - //1. Base automaton: create states for main augmented root for the grammar - Data.InitialState = CreateInitialState(grammarData.AugmentedRoot); - ExpandParserStateList(0); - CreateAcceptAction(Data.InitialState, grammarData.AugmentedRoot); - - //2. Expand automaton: add parser states from additional roots - foreach(var augmRoot in grammarData.AugmentedSnippetRoots) { - var initialState = CreateInitialState(augmRoot); - ExpandParserStateList(Data.States.Count - 1); //start with just added state - it is the last state in the list - CreateAcceptAction(initialState, augmRoot); - } - } - - private void CreateAcceptAction(ParserState initialState, NonTerminal augmentedRoot) { - var root = augmentedRoot.Productions[0].RValues[0]; - var shiftOverRootState = initialState.Actions[root].NewState; - shiftOverRootState.Actions[_grammar.Eof] = new ParserAction(ParserActionType.Accept, null, null); - } - - - private ParserState CreateInitialState(NonTerminal augmentedRoot) { - //for an augmented root there is an initial production "Root' -> .Root"; so we need the LR0 item at 0 index - var iniItemSet = new LR0ItemSet(); - iniItemSet.Add(augmentedRoot.Productions[0].LR0Items[0]); - var initialState = FindOrCreateState(iniItemSet); - var rootNt = augmentedRoot.Productions[0].RValues[0] as NonTerminal; - Data.InitialStates[rootNt] = initialState; - return initialState; - } - - private void ExpandParserStateList(int initialIndex) { - // Iterate through states (while new ones are created) and create shift transitions and new states - for (int index = initialIndex; index < Data.States.Count; index++) { - var state = Data.States[index]; - //Get all possible shifts - foreach (var term in state.BuilderData.ShiftTerms) { - var shiftItems = state.BuilderData.ShiftItems.SelectByCurrent(term); - //Get set of shifted cores and find/create target state - var shiftedCoreItems = shiftItems.GetShiftedCores(); - var newState = FindOrCreateState(shiftedCoreItems); - //Create shift action - var newAction = new ParserAction(ParserActionType.Shift, newState, null); - state.Actions[term] = newAction; - //Link items in old/new states - foreach (var shiftItem in shiftItems) { - shiftItem.ShiftedItem = newState.BuilderData.AllItems.FindByCore(shiftItem.Core.ShiftedItem); - }//foreach shiftItem - }//foreach term - } //for index - }//method - - private ParserState FindOrCreateState(LR0ItemSet coreItems) { - string key = ComputeLR0ItemSetKey(coreItems); - ParserState state; - if (_stateHash.TryGetValue(key, out state)) - return state; - //create new state - state = new ParserState("S" + Data.States.Count); - state.BuilderData = new ParserStateData(state, coreItems); - Data.States.Add(state); - _stateHash[key] = state; - return state; - } - - #endregion - - #region Compute transitions, lookbacks, lookaheads - //We compute only transitions that are really needed to compute lookaheads in inadequate states. - // We start with reduce items in inadequate state and find their lookbacks - this is initial list of transitions. - // Then for each transition in the list we check if it has items with nullable tails; for those items we compute - // lookbacks - these are new or already existing transitons - and so on, we repeat the operation until no new transitions - // are created. - private void ComputeTransitions(LRItemSet forItems) { - var newItemsNeedLookbacks = forItems; - while(newItemsNeedLookbacks.Count > 0) { - var newTransitions = CreateLookbackTransitions(newItemsNeedLookbacks); - newItemsNeedLookbacks = SelectNewItemsThatNeedLookback(newTransitions); - } - } - - private LRItemSet SelectNewItemsThatNeedLookback(TransitionList transitions) { - //Select items with nullable tails that don't have lookbacks yet - var items = new LRItemSet(); - foreach(var trans in transitions) - foreach(var item in trans.Items) - if (item.Core.TailIsNullable && item.Lookbacks.Count == 0) //only if it does not have lookbacks yet - items.Add(item); - return items; - } - - private LRItemSet GetReduceItemsInInadequateState() { - var result = new LRItemSet(); - foreach(var state in Data.States) { - if (state.BuilderData.IsInadequate) - result.UnionWith(state.BuilderData.ReduceItems); - } - return result; - } - - private TransitionList CreateLookbackTransitions(LRItemSet sourceItems) { - var newTransitions = new TransitionList(); - //Build set of initial cores - this is optimization for performance - //We need to find all initial items in all states that shift into one of sourceItems - // Each such initial item would have the core from the "initial" cores set that we build from source items. - var iniCores = new LR0ItemSet(); - foreach(var sourceItem in sourceItems) - iniCores.Add(sourceItem.Core.Production.LR0Items[0]); - //find - foreach(var state in Data.States) { - foreach(var iniItem in state.BuilderData.InitialItems) { - if (!iniCores.Contains(iniItem.Core)) continue; - var iniItemNt = iniItem.Core.Production.LValue; // iniItem's non-terminal (left side of production) - Transition lookback = null; // local var for lookback - transition over iniItemNt - var currItem = iniItem; // iniItem is initial item for all currItem's in the shift chain. - while (currItem != null) { - if (sourceItems.Contains(currItem)) { - // We create transitions lazily, only when we actually need them. Check if we have iniItem's transition - // in local variable; if not, get it from state's transitions table; if not found, create it. - if (lookback == null && !state.BuilderData.Transitions.TryGetValue(iniItemNt, out lookback)) { - lookback = new Transition(state, iniItemNt); - newTransitions.Add(lookback); - } - //Now for currItem, either add trans to Lookbacks, or "include" it into currItem.Transition - // We need lookbacks ONLY for final items; for non-Final items we need proper Include lists on transitions - if (currItem.Core.IsFinal) - currItem.Lookbacks.Add(lookback); - else // if (currItem.Transition != null) - // Note: looks like checking for currItem.Transition is redundant - currItem is either: - // - Final - always the case for the first run of this method; - // - it has a transition after the first run, due to the way we select sourceItems list - // in SelectNewItemsThatNeedLookback (by transitions) - currItem.Transition.Include(lookback); - }//if - //move to next item - currItem = currItem.ShiftedItem; - }//while - }//foreach iniItem - }//foreach state - return newTransitions; - } - - private void ComputeLookaheads(LRItemSet forItems) { - foreach(var reduceItem in forItems) { - // Find all source states - those that contribute lookaheads - var sourceStates = new ParserStateSet(); - foreach(var lookbackTrans in reduceItem.Lookbacks) { - sourceStates.Add(lookbackTrans.ToState); - sourceStates.UnionWith(lookbackTrans.ToState.BuilderData.ReadStateSet); - foreach(var includeTrans in lookbackTrans.Includes) { - sourceStates.Add(includeTrans.ToState); - sourceStates.UnionWith(includeTrans.ToState.BuilderData.ReadStateSet); - }//foreach includeTrans - }//foreach lookbackTrans - //Now merge all shift terminals from all source states - foreach(var state in sourceStates) - reduceItem.Lookaheads.UnionWith(state.BuilderData.ShiftTerminals); - //Remove SyntaxError - it is pseudo terminal - if (reduceItem.Lookaheads.Contains(_grammar.SyntaxError)) - reduceItem.Lookaheads.Remove(_grammar.SyntaxError); - //Sanity check - if (reduceItem.Lookaheads.Count == 0) - _language.Errors.Add(GrammarErrorLevel.InternalError, reduceItem.State, "Reduce item '{0}' in state {1} has no lookaheads.", reduceItem.Core, reduceItem.State); - }//foreach reduceItem - }//method - - #endregion - - #region Analyzing and resolving conflicts - private void ComputeAndResolveConflicts() { - foreach(var state in Data.States) { - if (!state.BuilderData.IsInadequate) - continue; - //first detect conflicts - var stateData = state.BuilderData; - stateData.Conflicts.Clear(); - var allLkhds = new BnfTermSet(); - //reduce/reduce -------------------------------------------------------------------------------------- - foreach(var item in stateData.ReduceItems) { - foreach(var lkh in item.Lookaheads) { - if (allLkhds.Contains(lkh)) { - state.BuilderData.Conflicts.Add(lkh); - } - allLkhds.Add(lkh); - }//foreach lkh - }//foreach item - //shift/reduce --------------------------------------------------------------------------------------- - foreach(var term in stateData.ShiftTerminals) - if (allLkhds.Contains(term)) { - stateData.Conflicts.Add(term); - } - - //Now resolve conflicts by hints and precedence ------------------------------------------------------- - if (stateData.Conflicts.Count > 0) { - //Hints - foreach (var conflict in stateData.Conflicts) - ResolveConflictByHints(state, conflict); - stateData.Conflicts.ExceptWith(state.BuilderData.ResolvedConflicts); - //Precedence - foreach (var conflict in stateData.Conflicts) - ResolveConflictByPrecedence(state, conflict); - stateData.Conflicts.ExceptWith(state.BuilderData.ResolvedConflicts); - //if we still have conflicts, report and assign default action - if (stateData.Conflicts.Count > 0) - ReportAndCreateDefaultActionsForConflicts(state); - }//if Conflicts.Count > 0 - } - }//method - - private void ResolveConflictByHints(ParserState state, Terminal conflict) { - var stateData = state.BuilderData; - - //reduce hints - var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict); - foreach(var reduceItem in reduceItems) - if (reduceItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToReduce) != null) { - state.Actions[conflict] = new ParserAction(ParserActionType.Reduce, null, reduceItem.Core.Production); - state.BuilderData.ResolvedConflicts.Add(conflict); - return; - } - - //shift hints - var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict); - foreach (var shiftItem in shiftItems) - if (shiftItem.Core.Hints.Find(h => h.HintType == HintType.ResolveToShift) != null) { - //shift action is already there - state.BuilderData.ResolvedConflicts.Add(conflict); - return; - } - - //code hints - // first prepare data for conflict action: reduceProduction (for possible reduce) and newState (for possible shift) - var reduceProduction = reduceItems.First().Core.Production; //take first of reduce productions - ParserState newState = (state.Actions.ContainsKey(conflict) ? state.Actions[conflict].NewState : null); - // Get all items that might contain hints; - var allItems = new LRItemList(); - allItems.AddRange(state.BuilderData.ShiftItems.SelectByCurrent(conflict)); - allItems.AddRange(state.BuilderData.ReduceItems.SelectByLookahead(conflict)); - // Scan all items and try to find hint with resolution type Code - foreach (var item in allItems) { - if (item.Core.Hints.Find(h => h.HintType == HintType.ResolveInCode) != null) { - state.Actions[conflict] = new ParserAction(ParserActionType.Code, newState, reduceProduction); - state.BuilderData.ResolvedConflicts.Add(conflict); - return; - } - } - - //custom hints - // find custom grammar hints and build custom conflict resolver - var customHints = new List(); - var hintItems = new Dictionary(); - LRItem defaultItem = null; // the first item with no hints - foreach (var item in allItems) { - var hints = item.Core.Hints.OfType(); - foreach (var hint in hints) { - customHints.Add(hint); - hintItems[hint] = item; - } - if (defaultItem == null && !hints.Any()) - defaultItem = item; - } - // if there are custom hints, build conflict resolver - if (customHints.Count > 0) { - state.Actions[conflict] = new ParserAction(newState, reduceProduction, args => { - // examine all custom hints and select the first production that matched - foreach (var customHint in customHints) { - if (customHint.Match(args)) { - var item = hintItems[customHint]; - // If the ReduceProduction was clear, then use the default production following the hints - if (args.ReduceProduction == null) - args.ReduceProduction = item.Core.Production; - return; - } - } - // no hints matched, select default LRItem - if (defaultItem != null) { - args.ReduceProduction = defaultItem.Core.Production; - args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce; - return; - } - // prefer Reduce if Shift operation is not available - args.Result = args.NewShiftState != null ? ParserActionType.Shift : ParserActionType.Reduce; - // TODO: figure out what to do next - }); - state.BuilderData.ResolvedConflicts.Add(conflict); - return; - } - } - - private void ResolveConflictByPrecedence(ParserState state, Terminal conflict) { - if (!conflict.FlagIsSet(TermFlags.IsOperator)) return; - var stateData = state.BuilderData; - if (!stateData.ShiftTerminals.Contains(conflict)) return; //it is not shift-reduce - var shiftAction = state.Actions[conflict]; - //now get shift items for the conflict - var shiftItems = stateData.ShiftItems.SelectByCurrent(conflict); - //get reduce item - var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict); - if (reduceItems.Count > 1) return; // if it is reduce-reduce conflict, we cannot fix it by precedence - var reduceItem = reduceItems.First(); - shiftAction.ChangeToOperatorAction(reduceItem.Core.Production); - stateData.ResolvedConflicts.Add(conflict); - }//method - - //Resolve to default actions - private void ReportAndCreateDefaultActionsForConflicts(ParserState state) { - var shiftReduceConflicts = state.BuilderData.GetShiftReduceConflicts(); - var reduceReduceConflicts = state.BuilderData.GetReduceReduceConflicts(); - var stateData = state.BuilderData; - if (shiftReduceConflicts.Count > 0) - _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrSRConflict, state, shiftReduceConflicts.ToString()); - if (reduceReduceConflicts.Count > 0) - _language.Errors.Add(GrammarErrorLevel.Conflict, state, Resources.ErrRRConflict, state, reduceReduceConflicts.ToString()); - //Create default actions for these conflicts. For shift-reduce, default action is shift, and shift action already - // exist for all shifts from the state, so we don't need to do anything, only report it - //For reduce-reduce create reduce actions for the first reduce item (whatever comes first in the set). - foreach (var conflict in reduceReduceConflicts) { - var reduceItems = stateData.ReduceItems.SelectByLookahead(conflict); - var firstProd = reduceItems.First().Core.Production; - var action = new ParserAction(ParserActionType.Reduce, null, firstProd); - state.Actions[conflict] = action; - } - //Update ResolvedConflicts and Conflicts sets - stateData.ResolvedConflicts.UnionWith(shiftReduceConflicts); - stateData.ResolvedConflicts.UnionWith(reduceReduceConflicts); - stateData.Conflicts.ExceptWith(stateData.ResolvedConflicts); - } - - #endregion - - #region final actions: creating remaining reduce actions, computing expected terminals, cleaning up state data - private void CreateRemainingReduceActions() { - foreach (var state in Data.States) { - var stateData = state.BuilderData; - if (stateData.ShiftItems.Count == 0 && stateData.ReduceItems.Count == 1) { - state.DefaultAction = new ParserAction(ParserActionType.Reduce, null, stateData.ReduceItems.First().Core.Production); - continue; - } - //now create actions - foreach (var item in state.BuilderData.ReduceItems) { - var action = new ParserAction(ParserActionType.Reduce, null, item.Core.Production); - foreach (var lkh in item.Lookaheads) { - if (state.Actions.ContainsKey(lkh)) continue; - state.Actions[lkh] = action; - } - }//foreach item - }//foreach state - } - - //Note that for states with a single reduce item the result is empty - private void ComputeStatesExpectedTerminals() { - foreach (var state in Data.States) { - state.ExpectedTerminals.UnionWith(state.BuilderData.ShiftTerminals); - //Add lookaheads from reduce items - foreach (var reduceItem in state.BuilderData.ReduceItems) - state.ExpectedTerminals.UnionWith(reduceItem.Lookaheads); - RemoveTerminals(state.ExpectedTerminals, _grammar.SyntaxError, _grammar.Eof); - }//foreach state - } - - private void RemoveTerminals(TerminalSet terms, params Terminal[] termsToRemove) { - foreach(var termToRemove in termsToRemove) - if (terms.Contains(termToRemove)) terms.Remove(termToRemove); - } - - public void CleanupStateData() { - foreach (var state in Data.States) - state.ClearData(); - } - #endregion - - #region Utilities: ComputeLR0ItemSetKey - //Parser states are distinguished by the subset of kernel LR0 items. - // So when we derive new LR0-item list by shift operation, - // we need to find out if we have already a state with the same LR0Item list. - // We do it by looking up in a state hash by a key - [LR0 item list key]. - // Each list's key is a concatenation of items' IDs separated by ','. - // Before producing the key for a list, the list must be sorted; - // thus we garantee one-to-one correspondence between LR0Item sets and keys. - // And of course, we count only kernel items (with dot NOT in the first position). - public static string ComputeLR0ItemSetKey(LR0ItemSet items) { - if (items.Count == 0) return string.Empty; - //Copy non-initial items to separate list, and then sort it - LR0ItemList itemList = new LR0ItemList(); - foreach (var item in items) - itemList.Add(item); - //quick shortcut - if (itemList.Count == 1) - return itemList[0].ID.ToString(); - itemList.Sort(CompareLR0Items); //Sort by ID - //now build the key - StringBuilder sb = new StringBuilder(100); - foreach (LR0Item item in itemList) { - sb.Append(item.ID); - sb.Append(","); - }//foreach - return sb.ToString(); - } - - private static int CompareLR0Items(LR0Item x, LR0Item y) { - if (x.ID < y.ID) return -1; - if (x.ID == y.ID) return 0; - return 1; - } - #endregion - - }//class - - -}//namespace - - diff --git a/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder_HelperClasses.cs b/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder_HelperClasses.cs deleted file mode 100644 index 9d2260d48d..0000000000 --- a/sources/shaders/Irony/Parsing/Data/Construction/ParserDataBuilder_HelperClasses.cs +++ /dev/null @@ -1,275 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -//Helper data classes for ParserDataBuilder -// Note about using LRItemSet vs LRItemList. -// It appears that in many places the LRItemList would be a better (and faster) choice than LRItemSet. -// Many of the sets are actually lists and don't require hashset's functionality. -// But surprisingly, using LRItemSet proved to have much better performance (twice faster for lookbacks/lookaheads computation), so LRItemSet -// is used everywhere. -namespace Irony.Parsing.Construction { - - internal class ParserStateData { - public readonly ParserState State; - public readonly LRItemSet AllItems = new LRItemSet(); - public readonly LRItemSet ShiftItems = new LRItemSet(); - public readonly LRItemSet ReduceItems = new LRItemSet(); - public readonly LRItemSet InitialItems = new LRItemSet(); - public readonly BnfTermSet ShiftTerms = new BnfTermSet(); - public readonly TerminalSet ShiftTerminals = new TerminalSet(); - public readonly TerminalSet Conflicts = new TerminalSet(); - public readonly TerminalSet ResolvedConflicts = new TerminalSet(); - public readonly bool IsInadequate; - public LR0ItemSet AllCores = new LR0ItemSet(); - - //used for creating canonical states from core set - public ParserStateData(ParserState state, LR0ItemSet kernelCores) { - State = state; - foreach (var core in kernelCores) - AddItem(core); - IsInadequate = ReduceItems.Count > 1 || ReduceItems.Count == 1 && ShiftItems.Count > 0; - } - - public void AddItem(LR0Item core) { - //Check if a core had been already added. If yes, simply return - if (!AllCores.Add(core))return ; - //Create new item, add it to AllItems, InitialItems, ReduceItems or ShiftItems - var item = new LRItem(State, core); - AllItems.Add(item); - if (item.Core.IsFinal) - ReduceItems.Add(item); - else - ShiftItems.Add(item); - if (item.Core.IsInitial) - InitialItems.Add(item); - if (core.IsFinal) return; - //Add current term to ShiftTerms - if (!ShiftTerms.Add(core.Current)) return; - if (core.Current is Terminal) - ShiftTerminals.Add(core.Current as Terminal); - //If current term (core.Current) is a new non-terminal, expand it - var currNt = core.Current as NonTerminal; - if (currNt == null) return; - foreach(var prod in currNt.Productions) - AddItem(prod.LR0Items[0]); - }//method - - public TransitionTable Transitions { - get { - if (_transitions == null) - _transitions = new TransitionTable(); - return _transitions; - } - } TransitionTable _transitions; - - //A set of states reachable through shifts over nullable non-terminals. Computed on demand - public ParserStateSet ReadStateSet { - get { - if (_readStateSet == null) { - _readStateSet = new ParserStateSet(); - foreach(var shiftTerm in State.BuilderData.ShiftTerms) - if (shiftTerm.FlagIsSet(TermFlags.IsNullable)) { - var targetState = State.Actions[shiftTerm].NewState; - _readStateSet.Add(targetState); - _readStateSet.UnionWith(targetState.BuilderData.ReadStateSet); //we shouldn't get into loop here, the chain of reads is finite - } - }//if - return _readStateSet; - } - } ParserStateSet _readStateSet; - - - public TerminalSet GetShiftReduceConflicts() { - var result = new TerminalSet(); - result.UnionWith(Conflicts); - result.IntersectWith(ShiftTerminals); - return result; - } - public TerminalSet GetReduceReduceConflicts() { - var result = new TerminalSet(); - result.UnionWith(Conflicts); - result.ExceptWith(ShiftTerminals); - return result; - } - - }//class - - //An object representing inter-state transitions. Defines Includes, IncludedBy that are used for efficient lookahead computation - internal class Transition { - public readonly ParserState FromState; - public readonly ParserState ToState; - public readonly NonTerminal OverNonTerminal; - public readonly LRItemSet Items; - public readonly TransitionSet Includes = new TransitionSet(); - public readonly TransitionSet IncludedBy = new TransitionSet(); - int _hashCode; - - public Transition(ParserState fromState, NonTerminal overNonTerminal) { - FromState = fromState; - OverNonTerminal = overNonTerminal; - ToState = FromState.Actions[overNonTerminal].NewState; - _hashCode = unchecked(FromState.GetHashCode() - overNonTerminal.GetHashCode()); - FromState.BuilderData.Transitions.Add(overNonTerminal, this); - Items = FromState.BuilderData.ShiftItems.SelectByCurrent(overNonTerminal); - foreach(var item in Items) { - item.Transition = this; - } - - }//constructor - - public void Include(Transition other) { - if (other == this) return; - if (!IncludeTransition(other)) return; - //include children - foreach(var child in other.Includes) { - IncludeTransition(child); - } - } - private bool IncludeTransition(Transition other) { - if (!Includes.Add(other)) return false; - other.IncludedBy.Add(this); - //propagate "up" - foreach(var incBy in IncludedBy) - incBy.IncludeTransition(other); - return true; - } - - public override string ToString() { - return FromState.Name + " -> (over " + OverNonTerminal.Name + ") -> " + ToState.Name; - } - public override int GetHashCode() { - return _hashCode; - } - }//class - - internal class TransitionSet : HashSet { } - internal class TransitionList : List { } - internal class TransitionTable : Dictionary { } - - internal class LRItem { - public readonly ParserState State; - public readonly LR0Item Core; - //these properties are used in lookahead computations - public LRItem ShiftedItem; - public Transition Transition; - int _hashCode; - - //Lookahead info for reduce items - public TransitionSet Lookbacks = new TransitionSet(); - public TerminalSet Lookaheads = new TerminalSet(); - - public LRItem(ParserState state, LR0Item core) { - State = state; - Core = core; - _hashCode = unchecked(state.GetHashCode() + core.GetHashCode()); - } - public override string ToString() { - return Core.ToString(); - } - public override int GetHashCode() { - return _hashCode; - } - - }//LRItem class - - internal class LRItemList : List {} - - internal class LRItemSet : HashSet { - - public LRItem FindByCore(LR0Item core) { - foreach (LRItem item in this) - if (item.Core == core) return item; - return null; - } - public LRItemSet SelectByCurrent(BnfTerm current) { - var result = new LRItemSet(); - foreach (var item in this) - if (item.Core.Current == current) - result.Add(item); - return result; - } - - public LR0ItemSet GetShiftedCores() { - var result = new LR0ItemSet(); - foreach (var item in this) - if (item.Core.ShiftedItem != null) - result.Add(item.Core.ShiftedItem); - return result; - } - public LRItemSet SelectByLookahead(Terminal lookahead) { - var result = new LRItemSet(); - foreach (var item in this) - if (item.Lookaheads.Contains(lookahead)) - result.Add(item); - return result; - } - - }//class - - public partial class LR0Item { - public readonly Production Production; - public readonly int Position; - public readonly BnfTerm Current; - public bool TailIsNullable; - public GrammarHintList Hints = new GrammarHintList(); - - //automatically generated IDs - used for building keys for lists of kernel LR0Items - // which in turn are used to quickly lookup parser states in hash - internal readonly int ID; - - public LR0Item(int id, Production production, int position, GrammarHintList hints) { - ID = id; - Production = production; - Position = position; - Current = (Position < Production.RValues.Count) ? Production.RValues[Position] : null; - if (hints != null) - Hints.AddRange(hints); - _hashCode = ID.ToString().GetHashCode(); - }//method - - public LR0Item ShiftedItem { - get { - if (Position >= Production.LR0Items.Count - 1) - return null; - else - return Production.LR0Items[Position + 1]; - } - } - public bool IsKernel { - get { return Position > 0; } - } - public bool IsInitial { - get { return Position == 0; } - } - public bool IsFinal { - get { return Position == Production.RValues.Count; } - } - public override string ToString() { - return Production.ProductionToString(Production, Position); - } - public override int GetHashCode() { - return _hashCode; - } int _hashCode; - - }//LR0Item - - internal class LR0ItemList : List { } - internal class LR0ItemSet : HashSet { } - - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Data/Construction/_about_parser_construction.txt b/sources/shaders/Irony/Parsing/Data/Construction/_about_parser_construction.txt deleted file mode 100644 index c3390f3fcd..0000000000 --- a/sources/shaders/Irony/Parsing/Data/Construction/_about_parser_construction.txt +++ /dev/null @@ -1,44 +0,0 @@ - About parser construction algorithm in general - We follow DeRemer-Penello's algorithm, as it is described in Grune, Jacobs "Parsing Techniques" 2nd ed, section 9.7, p. 309. - There are a few differences: - 1. We compute lookbacks and transitions "on-demand" - only those that are actually needed for computing lookaheads in - reduce items in inadequate states. We start with reduce items in inadequate states - those are the only items that need lookaheads. - We then find all lookbacks (transitions) for these items. Then for each transition we find which ones need to "include" other parent - transitions - and compute this. And so on, until all transitions are created and linked through Include relationships - 2. We propagate Include relation between transitions immediately, when we add an include relation of one transition to another. See - Transition.Include method. Thus we avoid an extra step of "Transitive closure" of Include relation. See note about efficiency below. - 3. We don't use Reads and DirectRead relation between transitions. "Reads" relation - between transitions is replaced by Reads relation between states. So state A READS state B if you can move from state A to state B - using shifts over nullable terminals. ParserStateData.ReadStateSet contains all states that current state Reads. ReadStateSet - is computed on-demand, and all reads are immediately propagated through transitive chain - see source code of the method. - For DirectReads set for a transition in DeRemer-Penello - we use a state.ShiftTerminals set of the target state of the transition - - obviously this is the same set. - - Note about immediate Include propagation - I think that the method with immediate Includes propagation is as efficient as it can be, and using Transitive Closure optimization - through Srongly-Connected Components (SCC) algorithm would not be much faster. With immediate propagation we attempt to add - a transition to Includes set of another transition only once and stop propagation of the transition further down the chain if it is - already there. Essentially, we don't waste time propagating sets of transitions through chains of Includes if the transitions are - alredy there, propagated through different route. This is what SCC method is trying to mitigate - repeated propagation of transitions - - but this is not happening in our implementation. Maybe I'm mistaken, this is a guess, not a formal proof - let me know if you see - any flaws in my reasoning. - - About computing ExpectedTerminals set for parser states. - ExpectedTerms is a property of ParserState and contains all Terminals that parser expects in this state. This set is used by Scanner - which Terminal to use for recongizing next token when it has a choice of more than one. (This is called Scanner-Parser link facility). - The question now is how to compute this set. There are are several kinds of Parser states: - 1. Containing shift items only. The ExpectedSet is a union of all "current" terms of all shift items. State.BuilderData.ShiftTerms - already contains this set - easy case. - 2. Containing shift AND reduce items. This is inadequate set. The expected set is a union of all current terms of shift items - (like in previous case) plus all lookaheads of reduce items. Reduce items have lookaheads computed, because it is inadequate state. - 3. Containing 2 or more reduce items - this is again an inadequate state, each reduce items has lookaheads computed, so expected set - is a union of lookaheads of reduce items. - 4. Containing a single reduce item. This is a troubled case. The state is not inadequate, so we don't compute lookaheads for a single - reduce items - there is no need for them, only a single action is possible. - The solution for the last case with a single reduce item is the following: we do not compute ExpectedSet for such states, but make sure - that scanner-parser link is never activated in this case. We do it in Parser code by NOT reading the next token from Scanner when - current state has a single reduce action (DefaultReduceAction property is not null). We do not read next token because it is not needed - for finding an action - there is one single possible action anyway. As a result the Scanner would never start scanning a new token - when parser in this single-reduce state - and therefore scanner would not invoke the parser-scanner link. - See CoreParser.ExecuteAction method for details. - diff --git a/sources/shaders/Irony/Parsing/Data/GrammarData.cs b/sources/shaders/Irony/Parsing/Data/GrammarData.cs deleted file mode 100644 index 6642780dbf..0000000000 --- a/sources/shaders/Irony/Parsing/Data/GrammarData.cs +++ /dev/null @@ -1,76 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - //GrammarData is a container for all basic info about the grammar - // GrammarData is a field in LanguageData object. - public class GrammarData { - public readonly LanguageData Language; - public readonly Grammar Grammar; - public NonTerminal AugmentedRoot; - public NonTerminalSet AugmentedSnippetRoots = new NonTerminalSet(); - public readonly BnfTermSet AllTerms = new BnfTermSet(); - public readonly TerminalList Terminals = new TerminalList(); - public readonly NonTerminalList NonTerminals = new NonTerminalList(); - public readonly StringSet ClosingBraces = new StringSet(); - public string WhitespaceAndDelimiters { get; internal set; } - - public GrammarData(LanguageData language) { - Language = language; - Grammar = language.Grammar; - } - - }//class - - - [Flags] - public enum LanguageFlags { - None = 0, - - //Compilation options - //Be careful - use this flag ONLY if you use NewLine terminal in grammar explicitly! - // - it happens only in line-based languages like Basic. - NewLineBeforeEOF = 0x01, - //Emit LineStart token - EmitLineStartToken = 0x02, - DisableScannerParserLink = 0x04, //in grammars that define TokenFilters (like Python) this flag should be set - CreateAst = 0x08, //create AST nodes - - //Runtime - CanRunSample = 0x0100, - SupportsCommandLine = 0x0200, - TailRecursive = 0x0400, //Tail-recursive language - Scheme is one example - - //Default value - Default = None, - } - - //Operator associativity types - public enum Associativity { - Left, - Right, - Neutral //don't know what that means - } - - [Flags] - public enum TermListOptions { - None = 0, - AllowTrailingDelimiter = 0x01, - } - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Data/LanguageData.cs b/sources/shaders/Irony/Parsing/Data/LanguageData.cs deleted file mode 100644 index 17b22ec04b..0000000000 --- a/sources/shaders/Irony/Parsing/Data/LanguageData.cs +++ /dev/null @@ -1,104 +0,0 @@ -#region License - -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; - -using Irony.Parsing.Construction; - -namespace Irony.Parsing -{ - /// - /// Describes a language. - /// - public class LanguageData - { - #region Constants and Fields - - /// - /// Grammar errors. - /// - public readonly GrammarErrorList Errors = new GrammarErrorList(); - - /// - /// The linked Grammar - /// - public Grammar Grammar { get; private set; } - - /// - /// Raw data extracted from the grammar. - /// - public GrammarData GrammarData { get; private set; } - - /// - /// Data for the parser. - /// - public ParserData ParserData { get; private set; } - - /// - /// Time in ms to build a scanner. - /// - public long ConstructionTime; - - /// - /// Error level. - /// - public GrammarErrorLevel ErrorLevel = GrammarErrorLevel.NoError; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes the specified grammar. - /// - /// The grammar. - public LanguageData(Grammar grammar) - { - Grammar = grammar; - GrammarData = new GrammarData(this); - ParserData = new ParserData(this); - ConstructAll(); - } - - public virtual Scanner CreateScanner() - { - return null; - } - - #endregion - - #region Public Methods - - /// - /// Determines whether this instance can parse. - /// - /// - /// true if this instance can parse; otherwise, false. - /// - public bool CanParse() - { - return ErrorLevel < GrammarErrorLevel.Error; - } - - /// - /// Constructs all. - /// - public void ConstructAll() - { - var builder = new LanguageDataBuilder(this); - builder.Build(); - } - - #endregion - } -} diff --git a/sources/shaders/Irony/Parsing/Data/ParserData.cs b/sources/shaders/Irony/Parsing/Data/ParserData.cs deleted file mode 100644 index 665e4cbc42..0000000000 --- a/sources/shaders/Irony/Parsing/Data/ParserData.cs +++ /dev/null @@ -1,196 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - - -namespace Irony.Parsing { - // ParserData is a container for all information used by CoreParser in input processing. - // ParserData is a field in LanguageData structure and is used by CoreParser when parsing intput. - // The state graph entry is InitialState state; the state graph encodes information usually contained - // in what is known in literature as transiton/goto tables. - // The graph is built from the language grammar by ParserBuilder. - // See "Parsing Techniques", 2nd edition for introduction to non-canonical parsing algorithms - using Irony.Parsing.Construction; - public class ParserData { - public readonly LanguageData Language; - public ParserState InitialState; - public ParserStateTable InitialStates = new ParserStateTable(); //extra entries into automaton - public ParserState FinalState; - public readonly ParserStateList States = new ParserStateList(); - public ParserData(LanguageData language) { - Language = language; - } - } - - public class ParserState { - public readonly string Name; - public readonly ParserActionTable Actions = new ParserActionTable(); - //Defined for states with a single reduce item; Parser.GetAction returns this action if it is not null. - public ParserAction DefaultAction; - //Expected terms contains terminals is to be used in - //Parser-advise-to-Scanner facility would use it to filter current terminals when Scanner has more than one terminal for current char, - // it can ask Parser to filter the list using the ExpectedTerminals in current Parser state. - public readonly TerminalSet ExpectedTerminals = new TerminalSet(); - //Used for error reporting, we would use it to include list of expected terms in error message - // It is reduced compared to ExpectedTerms - some terms are "merged" into other non-terminals (with non-empty DisplayName) - // to make message shorter and cleaner. It is computed on-demand in CoreParser - public StringSet ReportedExpectedSet; - internal ParserStateData BuilderData; //transient, used only during automaton construction and may be cleared after that - - public ParserState(string name) { - Name = name; - } - public void ClearData() { - BuilderData = null; - } - public override string ToString() { - return Name; - } - public override int GetHashCode() { - return Name.GetHashCode(); - } - - }//class - - public class ParserStateList : List { } - public class ParserStateSet : HashSet { } - public class ParserStateHash : Dictionary { } - public class ParserStateTable : Dictionary { } - - public enum ParserActionType { - Shift, - Reduce, - Operator, //shift or reduce depending on operator associativity and precedence - Code, //conflict resolution made in resolution method in grammar or in custom grammar hint; - Accept, - } - - public class ParserAction { - public ParserActionType ActionType {get;private set;} - public ParserState NewState {get;private set;} // for Shift action - public Production ReduceProduction {get;private set;} // for Reduce action - private Action ConflictResolver {get;set;} - - internal ParserAction(ParserActionType actionType, ParserState newState, Production reduceProduction) { - this.ActionType = actionType; - this.NewState = newState; - this.ReduceProduction = reduceProduction; - this.ConflictResolver = null; - } - - internal ParserAction(ParserState newState, Production reduceProduction, Action conflictResolver) - : this(ParserActionType.Code, newState, reduceProduction) { - ConflictResolver = conflictResolver; - } - - internal void ChangeToOperatorAction(Production reduceProduction) { - ActionType = ParserActionType.Operator; - ReduceProduction = reduceProduction; - } - - public virtual ConflictResolutionArgs ResolveConflict(Grammar grammar, ParsingContext context) { - var args = new ConflictResolutionArgs(context, this); - // custom conflict resolver such as custom grammar hint has a higher priority than OnResolvingConflict handler - var resolver = ConflictResolver ?? grammar.OnResolvingConflict; - resolver(args); - return args; - } - - public override string ToString() { - switch (this.ActionType) { - case ParserActionType.Shift: return string.Format(Resources.LabelActionShift, NewState.Name); - case ParserActionType.Reduce: return string.Format(Resources.LabelActionReduce, ReduceProduction.ToStringQuoted()); - case ParserActionType.Operator: return string.Format(Resources.LabelActionOp, NewState.Name, ReduceProduction.ToStringQuoted()); - case ParserActionType.Accept: return Resources.LabelActionAccept; - } - return Resources.LabelActionUnknown; //should never happen - } - }//class ParserAction - - public class ParserActionTable : Dictionary { } - - [Flags] - public enum ProductionFlags { - None = 0, - HasTerminals = 0x02, //contains terminal - IsError = 0x04, //contains Error terminal - IsEmpty = 0x08, - //Indicates that it is a main production for list formation, in the form: "list->list+delim?+elem" - IsListBuilder = 0x10, - } - - public class Production { - public ProductionFlags Flags; - public readonly NonTerminal LValue; // left-side element - public readonly BnfTermList RValues = new BnfTermList(); //the right-side elements sequence - internal readonly Construction.LR0ItemList LR0Items = new Construction.LR0ItemList(); //LR0 items based on this production - - public Production(NonTerminal lvalue) { - LValue = lvalue; - }//constructor - - public bool IsSet(ProductionFlags flag) { - return (Flags & flag) != ProductionFlags.None; - } - - public string ToStringQuoted() { - return "'" + ToString() + "'"; - } - public override string ToString() { - return ProductionToString(this, -1); //no dot - } - public static string ProductionToString(Production production, int dotPosition) { - char dotChar = '\u00B7'; //dot in the middle of the line - StringBuilder bld = new StringBuilder(); - bld.Append(production.LValue.Name); - bld.Append(" -> "); - for (int i = 0; i < production.RValues.Count; i++) { - if (i == dotPosition) - bld.Append(dotChar); - bld.Append(production.RValues[i].Name); - bld.Append(" "); - }//for i - if (dotPosition == production.RValues.Count) - bld.Append(dotChar); - return bld.ToString(); - } - - }//Production class - - public class ProductionList : List { } - - /// - /// The class provides arguments for custom conflict resolution grammar method. - /// - public class ConflictResolutionArgs : EventArgs { - public readonly ParsingContext Context; - public readonly Scanner Scanner; - public readonly ParserState NewShiftState; - //Results - public ParserActionType Result; //shift, reduce or operator - public Production ReduceProduction; //defaulted to - //constructor - internal ConflictResolutionArgs(ParsingContext context, ParserAction conflictAction) { - Context = context; - Scanner = Context.Parser.Scanner; - NewShiftState = conflictAction.NewState; - ReduceProduction = conflictAction.ReduceProduction; - Result = ParserActionType.Shift; //make shift by default - } - }//class - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Diagnostics/ParseTreeExtensions.cs b/sources/shaders/Irony/Parsing/Diagnostics/ParseTreeExtensions.cs deleted file mode 100644 index ad739a8d07..0000000000 --- a/sources/shaders/Irony/Parsing/Diagnostics/ParseTreeExtensions.cs +++ /dev/null @@ -1,64 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; -using System.Xml; - -namespace Irony.Parsing { - public static class ParseTreeExtensions { - - public static string ToXml(this ParseTree parseTree) { - if (parseTree == null || parseTree.Root == null) return string.Empty; - var xdoc = ToXmlDocument(parseTree); - StringWriter sw = new StringWriter(); - XmlWriterSettings xs = new XmlWriterSettings(); - xs.Indent = true; - XmlWriter xw = XmlWriter.Create(sw, xs); - xdoc.WriteTo(xw); - xw.Flush(); - return sw.ToString(); - } - - public static XmlDocument ToXmlDocument(this ParseTree parseTree) { - var xdoc = new XmlDocument(); - if (parseTree == null || parseTree.Root == null) return xdoc; - var xTree = xdoc.CreateElement("ParseTree"); - xdoc.AppendChild(xTree); - var xRoot = parseTree.Root.ToXmlElement(xdoc); - xTree.AppendChild(xRoot); - return xdoc; - } - - public static XmlElement ToXmlElement(this ParseTreeNode node, XmlDocument ownerDocument) { - var xElem = ownerDocument.CreateElement("Node"); - xElem.SetAttribute("Term", node.Term.Name); - if (node.Term.AstNodeType != null) - xElem.SetAttribute("AstNodeType", node.Term.AstNodeType.Name); - if (node.Token != null) { - xElem.SetAttribute("Terminal", node.Term.GetType().Name); - //xElem.SetAttribute("Text", node.Token.Text); - if (node.Token.Value != null) - xElem.SetAttribute("Value", node.Token.Value.ToString()); - } else - foreach (var child in node.ChildNodes) { - var xChild = child.ToXmlElement(ownerDocument); - xElem.AppendChild(xChild); - } - return xElem; - }//method - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Diagnostics/ParserDataPrinter.cs b/sources/shaders/Irony/Parsing/Diagnostics/ParserDataPrinter.cs deleted file mode 100644 index 53b2410168..0000000000 --- a/sources/shaders/Irony/Parsing/Diagnostics/ParserDataPrinter.cs +++ /dev/null @@ -1,93 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Irony.Parsing; -using Irony.Parsing.Construction; - -namespace Irony.Parsing { - public static class ParserDataPrinter { - - public static string PrintStateList(LanguageData language) { - StringBuilder sb = new StringBuilder(); - foreach (ParserState state in language.ParserData.States) { - sb.Append("State " + state.Name); - if (state.BuilderData.IsInadequate) sb.Append(" (Inadequate)"); - sb.AppendLine(); - var srConflicts = state.BuilderData.GetShiftReduceConflicts(); - if (srConflicts.Count > 0) - sb.AppendLine(" Shift-reduce conflicts on inputs: " + srConflicts.ToString()); - var ssConflicts = state.BuilderData.GetReduceReduceConflicts(); - if (ssConflicts.Count > 0) - sb.AppendLine(" Reduce-reduce conflicts on inputs: " + ssConflicts.ToString()); - //LRItems - if (state.BuilderData.ShiftItems.Count > 0) { - sb.AppendLine(" Shift items:"); - foreach (var item in state.BuilderData.ShiftItems) - sb.AppendLine(" " + item.ToString()); - } - if (state.BuilderData.ReduceItems.Count > 0) { - sb.AppendLine(" Reduce items:"); - foreach(LRItem item in state.BuilderData.ReduceItems) { - var sItem = item.ToString(); - if (item.Lookaheads.Count > 0) - sItem += " [" + item.Lookaheads.ToString() + "]"; - sb.AppendLine(" " + sItem); - } - } - sb.Append(" Transitions: "); - bool atFirst = true; - foreach (BnfTerm key in state.Actions.Keys) { - ParserAction action = state.Actions[key]; - var hasTransitions = action.ActionType == ParserActionType.Shift || action.ActionType == ParserActionType.Operator; - if (!hasTransitions) - continue; - if (!atFirst) sb.Append(", "); - atFirst = false; - sb.Append(key.ToString()); - sb.Append("->"); - sb.Append(action.NewState.Name); - } - sb.AppendLine(); - sb.AppendLine(); - }//foreach - return sb.ToString(); - } - - public static string PrintTerminals(LanguageData language) { - StringBuilder sb = new StringBuilder(); - foreach (Terminal term in language.GrammarData.Terminals) { - sb.Append(term.ToString()); - sb.AppendLine(); - } - return sb.ToString(); - } - - public static string PrintNonTerminals(LanguageData language) { - StringBuilder sb = new StringBuilder(); - foreach (NonTerminal nt in language.GrammarData.NonTerminals) { - sb.Append(nt.Name); - sb.Append(nt.FlagIsSet(TermFlags.IsNullable) ? " (Nullable) " : string.Empty); - sb.AppendLine(); - foreach (Production pr in nt.Productions) { - sb.Append(" "); - sb.AppendLine(pr.ToString()); - } - }//foreachc nt - return sb.ToString(); - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Diagnostics/ParserMessage.cs b/sources/shaders/Irony/Parsing/Diagnostics/ParserMessage.cs deleted file mode 100644 index d98e12f1a7..0000000000 --- a/sources/shaders/Irony/Parsing/Diagnostics/ParserMessage.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public enum ParserErrorLevel { - Info = 0, - Warning = 1, - Error = 2, - } - - //Container for syntax errors and warnings - public class ParserMessage { - public ParserMessage(ParserErrorLevel level, SourceLocation location, string message, ParserState parserState) { - Level = level; - Location = location; - Message = message; - ParserState = parserState; - } - - public readonly ParserErrorLevel Level; - public readonly ParserState ParserState; - public readonly SourceLocation Location; - public readonly string Message; - - public override string ToString() { - return Message; - } - }//class - - public class ParserMessageList : List { - public static int ByLocation(ParserMessage x, ParserMessage y) { - return SourceLocation.Compare(x.Location, y.Location); - } - } - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Diagnostics/ParserTrace.cs b/sources/shaders/Irony/Parsing/Diagnostics/ParserTrace.cs deleted file mode 100644 index a91904463b..0000000000 --- a/sources/shaders/Irony/Parsing/Diagnostics/ParserTrace.cs +++ /dev/null @@ -1,51 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - public class ParserTraceEntry { - public ParserState State; - public ParseTreeNode StackTop; - public ParseTreeNode Input; - public string Message; - public bool IsError; - - public ParserTraceEntry(ParserState state, ParseTreeNode stackTop, ParseTreeNode input, string message, bool isError) { - State = state; - StackTop = stackTop; - Input = input; - Message = message; - IsError = isError; - } - }//class - - public class ParserTrace : List { } - - public class ParserTraceEventArgs : EventArgs { - public ParserTraceEventArgs(ParserTraceEntry entry) { - Entry = entry; - } - - public readonly ParserTraceEntry Entry; - - public override string ToString() { - return Entry.ToString(); - } - }//class - - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Grammar/BnfExpression.cs b/sources/shaders/Irony/Parsing/Grammar/BnfExpression.cs deleted file mode 100644 index 4d0a269d1f..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/BnfExpression.cs +++ /dev/null @@ -1,73 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -namespace Irony.Parsing { - - //BNF expressions are represented as OR-list of Plus-lists of BNF terms - internal class BnfExpressionData : List { - public override string ToString() { - try { - string[] pipeArr = new string[this.Count]; - for (int i = 0; i < this.Count; i++) { - BnfTermList seq = this[i]; - string[] seqArr = new string[seq.Count]; - for (int j = 0; j < seq.Count; j++) - seqArr[j] = seq[j].ToString(); - pipeArr[i] = String.Join("+", seqArr); - } - return String.Join("|", pipeArr); - } catch(Exception e) { - return "(error: " + e.Message + ")"; - } - - } - } - - public class BnfExpression : BnfTerm { - - public BnfExpression(BnfTerm element): this() { - Data[0].Add(element); - } - public BnfExpression() : base(null) { - Data = new BnfExpressionData(); - Data.Add(new BnfTermList()); - } - - internal BnfExpressionData Data; - public override string ToString() { - return Data.ToString(); - } - - #region Implicit cast operators - public static implicit operator BnfExpression(string symbol) { - return new BnfExpression(Grammar.CurrentGrammar.ToTerm(symbol)); - } - //It seems better to define one method instead of the following two, with parameter of type BnfTerm - - // but that's not possible - it would be a conversion from base type of BnfExpression itself, which - // is not allowed in c# - public static implicit operator BnfExpression(Terminal term) { - return new BnfExpression(term); - } - public static implicit operator BnfExpression(NonTerminal nonTerminal) { - return new BnfExpression(nonTerminal); - } - #endregion - - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Grammar/BnfTerm.cs b/sources/shaders/Irony/Parsing/Grammar/BnfTerm.cs deleted file mode 100644 index 484f6c4e69..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/BnfTerm.cs +++ /dev/null @@ -1,256 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.Reflection; - -namespace Irony.Parsing { - [Flags] - public enum TermFlags { - None = 0, - IsOperator = 0x01, - IsOpenBrace = 0x02, - IsCloseBrace = 0x04, - IsBrace = IsOpenBrace | IsCloseBrace, - IsLiteral = 0x08, - - IsConstant = 0x10, - IsPunctuation = 0x20, - IsDelimiter = 0x40, - IsReservedWord = 0x080, - IsMemberSelect = 0x100, - - IsNonScanner = 0x01000, // indicates that tokens for this terminal are NOT produced by scanner - IsNonGrammar = 0x02000, // if set, parser would eliminate the token from the input stream; terms in Grammar.NonGrammarTerminals have this flag set - IsTransient = 0x04000, // Transient non-terminal - should be replaced by it's child in the AST tree. - IsNotReported = 0x08000, // Exclude from expected terminals list on syntax error - - //calculated flags - IsNullable = 0x010000, - IsVisible = 0x020000, - IsKeyword = 0x040000, - IsMultiline = 0x100000, - //internal flags - IsList = 0x200000, - IsListContainer = 0x400000, - //Indicates not to create AST node; mainly to suppress warning message on some special nodes that AST node type is not specified - //Automatically set by MarkTransient method - NoAstNode = 0x800000, - } - - public delegate void AstNodeCreator(ParsingContext context, ParseTreeNode parseNode); - - //Basic Backus-Naur Form element. Base class for Terminal, NonTerminal, BnfExpression, GrammarHint - public abstract class BnfTerm { - #region consructors - public BnfTerm(string name) : this(name, name) { } - public BnfTerm(string name, string errorAlias) { - Name = name; - ErrorAlias = errorAlias; - } - public BnfTerm(string name, string errorAlias, Type nodeType) : this(name, errorAlias) { - AstNodeType = nodeType; - } - public BnfTerm(string name, string errorAlias, AstNodeCreator nodeCreator) : this(name, errorAlias) { - AstNodeCreator = nodeCreator; - } - #endregion - - - #region virtuals and overrides - public virtual void Init(GrammarData grammarData) { - GrammarData = grammarData; - } - - public virtual string GetParseNodeCaption(ParseTreeNode node) { - if (GrammarData != null) - return GrammarData.Grammar.GetParseNodeCaption(node); - else - return Name; - } - - public override string ToString() { - return Name; - } - - public override int GetHashCode() { - if (Name == null) return 0; - return Name.GetHashCode(); - } - #endregion - - public const int NoPrecedence = 0; - - #region properties: Name, DisplayName, Key, Options - public string Name; - - //ErrorAlias is used in error reporting, e.g. "Syntax error, expected ". - public string ErrorAlias; - public TermFlags Flags; - protected GrammarData GrammarData; - public int Precedence = NoPrecedence; - public Associativity Associativity = Associativity.Neutral; - - public Grammar Grammar { - get { return GrammarData.Grammar; } - } - public bool FlagIsSet(TermFlags flag) { - return (Flags & flag) != 0; - } - public void SetFlag(TermFlags flag) { - SetFlag(flag, true); - } - public void SetFlag(TermFlags flag, bool value) { - if (value) - Flags |= flag; - else - Flags &= ~flag; - } - - #endregion - - #region AST node creations: AstNodeType, AstNodeCreator, AstNodeCreated - public Type AstNodeType; - public object AstNodeConfig; //config data passed to AstNode - public AstNodeCreator AstNodeCreator; - public event EventHandler AstNodeCreated; - - public virtual void CreateAstNode(ParsingContext context, ParseTreeNode nodeInfo) { - if (AstNodeCreator != null) { - AstNodeCreator(context, nodeInfo); - //We assume that Node creator method creates node and initializes it, so parser does not need to call - // IAstNodeInit.InitNode() method on node object. - return; - } - Type nodeType = GetAstNodeType(context, nodeInfo); - if (nodeType == null) - return; //we give a warning on grammar validation about this situation - nodeInfo.AstNode = Activator.CreateInstance(nodeType); - //Initialize node - var iInit = nodeInfo.AstNode as IAstNodeInit; - if (iInit != null) - iInit.Init(context, nodeInfo); - } - - //method may be overriden to provide node type different from this.AstNodeType. StringLiteral is overriding this method - // to use different node type for template strings - protected virtual Type GetAstNodeType(ParsingContext context, ParseTreeNode nodeInfo) { - return AstNodeType ?? Grammar.DefaultNodeType; - } - - protected internal void OnAstNodeCreated(ParseTreeNode parseNode) { - if (this.AstNodeCreated == null || parseNode.AstNode == null) return; - AstNodeEventArgs args = new AstNodeEventArgs(parseNode); - AstNodeCreated(this, args); - } - #endregion - - - #region Kleene operators: Q(), Plus(), Star() - NonTerminal _q, _plus, _star; //cash them - public NonTerminal Q() - { - if (_q != null) - return _q; - _q = new NonTerminal(this.Name + "?"); - _q.Rule = this | Grammar.CurrentGrammar.Empty; - return _q; - } - - public NonTerminal Plus() { - if (_plus != null) - return _plus; - _plus = new NonTerminal(this.Name + "+"); - _plus.Rule = Grammar.MakePlusRule(_plus, this); - return _plus; - } - - public NonTerminal Star() - { - if (_star != null) return _star; - _star = new NonTerminal(this.Name + "*"); - _star.Rule = Grammar.MakeStarRule(_star, this); - return _star; - } - #endregion - - #region Operators: +, |, implicit - public static BnfExpression operator +(BnfTerm term1, BnfTerm term2) { - return Op_Plus(term1, term2); - } - public static BnfExpression operator +(BnfTerm term1, string symbol2) { - return Op_Plus(term1, Grammar.CurrentGrammar.ToTerm(symbol2)); - } - public static BnfExpression operator +( string symbol1, BnfTerm term2) { - return Op_Plus(Grammar.CurrentGrammar.ToTerm(symbol1), term2); - } - - //Alternative - public static BnfExpression operator |(BnfTerm term1, BnfTerm term2) { - return Op_Pipe(term1, term2); - } - public static BnfExpression operator |(BnfTerm term1, string symbol2) { - return Op_Pipe(term1, Grammar.CurrentGrammar.ToTerm(symbol2)); - } - public static BnfExpression operator |(string symbol1, BnfTerm term2) { - return Op_Pipe(Grammar.CurrentGrammar.ToTerm(symbol1), term2); - } - - //BNF operations implementation ----------------------- - // Plus/sequence - internal static BnfExpression Op_Plus(BnfTerm term1, BnfTerm term2) { - //Check term1 and see if we can use it as result, simply adding term2 as operand - BnfExpression expr1 = term1 as BnfExpression; - if (expr1 == null || expr1.Data.Count > 1) //either not expression at all, or Pipe-type expression (count > 1) - expr1 = new BnfExpression(term1); - expr1.Data[expr1.Data.Count - 1].Add(term2); - return expr1; - } - - //Pipe/Alternative - //New version proposed by the codeplex user bdaugherty - internal static BnfExpression Op_Pipe(BnfTerm term1, BnfTerm term2) { - BnfExpression expr1 = term1 as BnfExpression; - if (expr1 == null) - expr1 = new BnfExpression(term1); - BnfExpression expr2 = term2 as BnfExpression; - if (expr2 == null) - expr2 = new BnfExpression(term2); - expr1.Data.AddRange(expr2.Data); - return expr1; - } - - - #endregion - - }//class - - public class BnfTermList : List { } - public class BnfTermSet : HashSet { } - - public class AstNodeEventArgs : EventArgs { - public AstNodeEventArgs(ParseTreeNode parseTreeNode) { - ParseTreeNode = parseTreeNode; - } - public readonly ParseTreeNode ParseTreeNode; - public object AstNode { - get { return ParseTreeNode.AstNode; } - } - } - - - -}//namespace - diff --git a/sources/shaders/Irony/Parsing/Grammar/Grammar.cs b/sources/shaders/Irony/Parsing/Grammar/Grammar.cs deleted file mode 100644 index 28a8b2e58e..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/Grammar.cs +++ /dev/null @@ -1,497 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace Irony.Parsing { - - public partial class Grammar { - - #region properties - /// - /// Gets case sensitivity of the grammar. Read-only, true by default. - /// Can be set to false only through a parameter to grammar constructor. - /// - public readonly bool CaseSensitive = true; - public readonly StringComparer LanguageStringComparer; - - //List of chars that unambigously identify the start of new token. - //used in scanner error recovery, and in quick parse path in NumberLiterals, Identifiers - public string Delimiters = null; - - public string WhitespaceChars = " \t\r\n\v"; - - //Used for line counting in source file - public string LineTerminators = "\n\r\v"; - - #region Language Flags - public LanguageFlags LanguageFlags = LanguageFlags.Default; - - public bool FlagIsSet(LanguageFlags flag) { - return (LanguageFlags & flag) != 0; - } - - public TermReportGroupList TermReportGroups = new TermReportGroupList(); - #endregion - - //Terminals not present in grammar expressions and not reachable from the Root - // (Comment terminal is usually one of them) - // Tokens produced by these terminals will be ignored by parser input. - public readonly TerminalSet NonGrammarTerminals = new TerminalSet(); - - //Terminals that either don't have explicitly declared Firsts symbols, or can start with chars not covered by these Firsts - // For ex., identifier in c# can start with a Unicode char in one of several Unicode classes, not necessarily latin letter. - // Whenever terminals with explicit Firsts() cannot produce a token, the Scanner would call terminals from this fallback - // collection to see if they can produce it. - // Note that IdentifierTerminal automatically add itself to this collection if its StartCharCategories list is not empty, - // so programmer does not need to do this explicitly - public readonly TerminalSet FallbackTerminals = new TerminalSet(); - - public Type DefaultNodeType; - - - /// - /// The main root entry for the grammar. - /// - public NonTerminal Root; - - public Func ScannerBuilder; - - /// - /// Alternative roots for parsing code snippets. - /// - public NonTerminalSet SnippetRoots = new NonTerminalSet(); - - public string GrammarComments; //shown in Grammar info tab - - public CultureInfo DefaultCulture = CultureInfo.InvariantCulture; - - //Console-related properties, initialized in grammar constructor - public string ConsoleTitle; - public string ConsoleGreeting; - public string ConsolePrompt; //default prompt - public string ConsolePromptMoreInput; //prompt to show when more input is expected - - #endregion - - #region constructors - - public virtual LanguageData CreateLanguageData() - { - return new LanguageData(this); - } - - public Grammar() : this(true) { } //case sensitive by default - - public Grammar(bool caseSensitive) { - _currentGrammar = this; - this.CaseSensitive = caseSensitive; - LanguageStringComparer = caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; - KeyTerms = new KeyTermTable(LanguageStringComparer); - //Initialize console attributes - ConsoleTitle = Resources.MsgDefaultConsoleTitle; - ConsoleGreeting = string.Format(Resources.MsgDefaultConsoleGreeting, this.GetType().Name); - ConsolePrompt = ">"; - ConsolePromptMoreInput = "."; - } - #endregion - - #region Reserved words handling - //Reserved words handling - public void MarkReservedWords(params string[] reservedWords) { - foreach (var word in reservedWords) { - var wdTerm = ToTerm(word); - wdTerm.SetFlag(TermFlags.IsReservedWord); - } - } - #endregion - - #region Register/Mark methods - public void RegisterOperators(int precedence, params string[] opSymbols) { - RegisterOperators(precedence, Associativity.Left, opSymbols); - } - - public void RegisterOperators(int precedence, Associativity associativity, params string[] opSymbols) { - foreach (string op in opSymbols) { - KeyTerm opSymbol = ToTerm(op); - opSymbol.SetFlag(TermFlags.IsOperator); - opSymbol.Precedence = precedence; - opSymbol.Associativity = associativity; - } - }//method - - public void RegisterOperators(int precedence, params BnfTerm[] opTerms) { - RegisterOperators(precedence, Associativity.Left, opTerms); - } - public void RegisterOperators(int precedence, Associativity associativity, params BnfTerm[] opTerms) { - foreach (var term in opTerms) { - term.SetFlag(TermFlags.IsOperator); - term.Precedence = precedence; - term.Associativity = associativity; - } - } - - public void RegisterBracePair(string openBrace, string closeBrace) { - KeyTerm openS = ToTerm(openBrace); - KeyTerm closeS = ToTerm(closeBrace); - openS.SetFlag(TermFlags.IsOpenBrace); - openS.IsPairFor = closeS; - closeS.SetFlag(TermFlags.IsCloseBrace); - closeS.IsPairFor = openS; - } - - public void MarkPunctuation(params string[] symbols) { - foreach (string symbol in symbols) { - KeyTerm term = ToTerm(symbol); - term.SetFlag(TermFlags.IsPunctuation|TermFlags.NoAstNode); - } - } - - public void MarkPunctuation(params BnfTerm[] terms) { - foreach (BnfTerm term in terms) - term.SetFlag(TermFlags.IsPunctuation|TermFlags.NoAstNode); - } - - - public void MarkTransient(params NonTerminal[] nonTerminals) { - foreach (NonTerminal nt in nonTerminals) - nt.Flags |= TermFlags.IsTransient | TermFlags.NoAstNode; - } - //MemberSelect are symbols invoking member list dropdowns in editor; for ex: . (dot), :: - public void MarkMemberSelect(params string[] symbols) { - foreach (var symbol in symbols) - ToTerm(symbol).SetFlag(TermFlags.IsMemberSelect); - } - //Sets IsNotReported flag on terminals. As a result the terminal wouldn't appear in expected terminal list - // in syntax error messages - public void MarkNotReported(params BnfTerm[] terms) { - foreach (var term in terms) - term.SetFlag(TermFlags.IsNotReported); - } - public void MarkNotReported(params string[] symbols) { - foreach (var symbol in symbols) - ToTerm(symbol).SetFlag(TermFlags.IsNotReported); - } - - #endregion - - #region virtual methods: TryMatch, CreateNode, CreateRuntime, RunSample - public virtual void CreateTokenFilters(LanguageData language, TokenFilterList filters) { - } - - //This method is called if Scanner fails to produce a token; it offers custom method a chance to produce the token - public virtual Token TryMatch(ParsingContext context, ISourceStream source) { - return null; - } - - //Gives a way to customize parse tree nodes captions in the tree view. - public virtual string GetParseNodeCaption(ParseTreeNode node) { - if (node.IsError) - return node.Term.Name + " (Syntax error)"; - if (node.Token != null) - return node.Token.ToString(); - if (node.Term == null) //special case for initial node pushed into the stack at parser start - return node.State != null ? "(State " + node.State.Name + ")" : string.Empty; // Resources.LabelInitialState; - var ntTerm = node.Term as NonTerminal; - if (ntTerm != null && !string.IsNullOrEmpty(ntTerm.NodeCaptionTemplate)) - return ntTerm.GetNodeCaption(node); - return node.Term.Name; - } - - //Gives a chance of custom AST node creation at Grammar level - // by default calls Term's method - public virtual void CreateAstNode(ParsingContext context, ParseTreeNode nodeInfo) { - nodeInfo.Term.CreateAstNode(context, nodeInfo); - } - - /// - /// Override this method to help scanner select a terminal to create token when there are more than one candidates - /// for an input char. Context.CurrentTerminals contains candidate terminals; leave a single terminal in this list - /// as the one to use. - /// - public virtual void OnScannerSelectTerminal(ParsingContext context) { } - - /// - /// Override this method to provide custom conflict resolution; for example, custom code may decide proper shift or reduce - /// action based on preview of tokens ahead. - /// - public virtual void OnResolvingConflict(ConflictResolutionArgs args) { - //args.Result is Shift by default - } - - //The method is called after GrammarData is constructed - public virtual void OnGrammarDataConstructed(LanguageData language) { - } - - public virtual void OnLanguageDataConstructed(LanguageData language) { - } - - - //Constructs the error message in situation when parser has no available action for current input. - // override this method if you want to change this message - public virtual string ConstructParserErrorMessage(ParsingContext context, StringSet expectedTerms) { - return string.Format(Resources.ErrParserUnexpInput, expectedTerms.ToString(" ")); - } - - // Override this method to perform custom error processing - public virtual void ReportParseError(ParsingContext context) { - string error = null; - if (context.CurrentParserInput.Term == this.SyntaxError) - error = context.CurrentParserInput.Token.Value as string; //scanner error - else if (context.CurrentParserInput.Term == this.Indent) - error = Resources.ErrUnexpIndent; - else if (context.CurrentParserInput.Term == this.Eof && context.OpenBraces.Count > 0) { - //report unclosed braces/parenthesis - var openBrace = context.OpenBraces.Peek(); - error = string.Format(Resources.ErrNoClosingBrace, openBrace.Text); - } else { - var expectedTerms = context.GetExpectedTermSet(); - if (expectedTerms.Count > 0) - error = ConstructParserErrorMessage(context, expectedTerms); - //error = string.Format(Resources.ErrParserUnexpInput, expectedTerms.ToString(" ") - else - error = Resources.ErrUnexpEof; - } - context.AddParserError(error); - }//method - - #endregion - - #region MakePlusRule, MakeStarRule methods - public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm listMember) { - return MakePlusRule(listNonTerminal, null, listMember); - } - - public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { - bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0; - if (delimiter == null || !allowTrailingDelimiter) - return MakePlusRule(listNonTerminal, delimiter, listMember); - //create plus list - var plusList = new NonTerminal(listMember.Name + "+"); - plusList.Rule = MakePlusRule(listNonTerminal, delimiter, listMember); - listNonTerminal.Rule = plusList | plusList + delimiter; - listNonTerminal.SetFlag(TermFlags.IsListContainer); - return listNonTerminal.Rule; - } - - public static BnfExpression MakePlusRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { - if (delimiter == null) - listNonTerminal.Rule = listMember | listNonTerminal + listMember; - else - listNonTerminal.Rule = listMember | listNonTerminal + delimiter + listMember; - listNonTerminal.SetFlag(TermFlags.IsList); - return listNonTerminal.Rule; - } - - public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm listMember) { - return MakeStarRule(listNonTerminal, null, listMember, TermListOptions.None); - } - - public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember) { - return MakeStarRule(listNonTerminal, delimiter, listMember, TermListOptions.None); - } - - public static BnfExpression MakeStarRule(NonTerminal listNonTerminal, BnfTerm delimiter, BnfTerm listMember, TermListOptions options) { - bool allowTrailingDelimiter = (options & TermListOptions.AllowTrailingDelimiter) != 0; - if (delimiter == null) { - //it is much simpler case - listNonTerminal.SetFlag(TermFlags.IsList); - listNonTerminal.Rule = _currentGrammar.Empty | listNonTerminal + listMember; - return listNonTerminal.Rule; - } - //Note that deceptively simple version of the star-rule - // Elem* -> Empty | Elem | Elem* + delim + Elem - // does not work when you have delimiters. This simple version allows lists starting with delimiters - - // which is wrong. The correct formula is to first define "Elem+"-list, and then define "Elem*" list - // as "Elem* -> Empty|Elem+" - NonTerminal plusList = new NonTerminal(listMember.Name + "+"); - plusList.Rule = MakePlusRule(plusList, delimiter, listMember); - plusList.SetFlag(TermFlags.NoAstNode); //to allow it to have AstNodeType not assigned - if (allowTrailingDelimiter) - listNonTerminal.Rule = _currentGrammar.Empty | plusList | plusList + delimiter; - else - listNonTerminal.Rule = _currentGrammar.Empty | plusList; - listNonTerminal.SetFlag(TermFlags.IsListContainer); - return listNonTerminal.Rule; - } - #endregion - - #region Hint utilities - protected GrammarHint PreferShiftHere() { - return new GrammarHint(HintType.ResolveToShift, null); - } - protected GrammarHint ReduceHere() { - return new GrammarHint(HintType.ResolveToReduce, null); - } - protected GrammarHint ResolveInCode() { - return new GrammarHint(HintType.ResolveInCode, null); - } - protected TokenPreviewHint Reduceif (string symbol) { - return new TokenPreviewHint(ParserActionType.Reduce, symbol); - } - protected TokenPreviewHint Shiftif (string symbol) { - return new TokenPreviewHint(ParserActionType.Shift, symbol); - } - protected GrammarHint ImplyPrecedenceHere(int precedence) { - return ImplyPrecedenceHere(precedence, Associativity.Left); - } - protected GrammarHint ImplyPrecedenceHere(int precedence, Associativity associativity) { - var hint = new GrammarHint(HintType.Precedence, null); - hint.Precedence = precedence; - hint.Associativity = associativity; - return hint; - } - - #endregion - - #region Term report group methods - /// - /// Creates a terminal reporting group, so all terminals in the group will be reported as a single "alias" in syntex error messages like - /// "Syntax error, expected: [list of terms]" - /// - /// An alias for all terminals in the group. - /// Symbols to be included into the group. - protected void AddTermsReportGroup(string alias, params string[] symbols) { - TermReportGroups.Add(new TermReportGroup(alias, TermReportGroupType.Normal, SymbolsToTerms(symbols))); - } - /// - /// Creates a terminal reporting group, so all terminals in the group will be reported as a single "alias" in syntex error messages like - /// "Syntax error, expected: [list of terms]" - /// - /// An alias for all terminals in the group. - /// Terminals to be included into the group. - protected void AddTermsReportGroup(string alias, params Terminal[] terminals) { - TermReportGroups.Add(new TermReportGroup(alias, TermReportGroupType.Normal, terminals)); - } - /// - /// Adds symbols to a group with no-report type, so symbols will not be shown in expected lists in syntax error messages. - /// - /// Symbols to exclude. - protected void AddToNoReportGroup(params string[] symbols) { - TermReportGroups.Add(new TermReportGroup(string.Empty, TermReportGroupType.Normal, SymbolsToTerms(symbols))); - } - /// - /// Adds symbols to a group with no-report type, so symbols will not be shown in expected lists in syntax error messages. - /// - /// Symbols to exclude. - protected void AddToNoReportGroup(params Terminal[] terminals) { - TermReportGroups.Add(new TermReportGroup(string.Empty, TermReportGroupType.Normal, terminals)); - } - /// - /// Adds a group and an alias for all operator symbols used in the grammar. - /// - /// An alias for operator symbols. - protected void AddOperatorReportGroup(string alias) { - TermReportGroups.Add(new TermReportGroup(alias, TermReportGroupType.Operator, null)); //operators will be filled later - } - - private IEnumerable SymbolsToTerms(IEnumerable symbols) { - var termList = new TerminalList(); - foreach(var symbol in symbols) - termList.Add(ToTerm(symbol)); - return termList; - } - #endregion - - #region Standard terminals: EOF, Empty, NewLine, Indent, Dedent - // Empty object is used to identify optional element: - // term.Rule = term1 | Empty; - public readonly Terminal Empty = new Terminal("EMPTY"); - // The following terminals are used in indent-sensitive languages like Python; - // they are not produced by scanner but are produced by CodeOutlineFilter after scanning - public readonly Terminal NewLine = new Terminal("LF"); - public readonly Terminal Indent = new Terminal("INDENT", TokenCategory.Outline, TermFlags.IsNonScanner); - public readonly Terminal Dedent = new Terminal("DEDENT", TokenCategory.Outline, TermFlags.IsNonScanner); - //End-of-Statement terminal - used in indentation-sensitive language to signal end-of-statement; - // it is not always synced with CRLF chars, and CodeOutlineFilter carefully produces Eos tokens - // (as well as Indent and Dedent) based on line/col information in incoming content tokens. - public readonly Terminal Eos = new Terminal("EOS", Resources.LabelEosLabel, TokenCategory.Outline, TermFlags.IsNonScanner); - // Identifies end of file - // Note: using Eof in grammar rules is optional. Parser automatically adds this symbol - // as a lookahead to Root non-terminal - public readonly Terminal Eof = new Terminal("EOF", TokenCategory.Outline); - - //Used for error tokens - public readonly Terminal LineStartTerminal = new Terminal("LINE_START", TokenCategory.Outline); - - //Used for error tokens - public readonly Terminal SyntaxError = new Terminal("SYNTAX_ERROR", TokenCategory.Error, TermFlags.IsNonScanner); - - public NonTerminal NewLinePlus { - get { - if (_newLinePlus == null) { - _newLinePlus = new NonTerminal("LF+"); - MarkPunctuation(_newLinePlus); - _newLinePlus.Rule = MakePlusRule(_newLinePlus, NewLine); - } - return _newLinePlus; - } - } NonTerminal _newLinePlus; - - public NonTerminal NewLineStar { - get { - if (_newLineStar == null) { - _newLineStar = new NonTerminal("LF*"); - MarkPunctuation(_newLineStar); - _newLineStar.Rule = MakeStarRule(_newLineStar, NewLine); - } - return _newLineStar; - } - } NonTerminal _newLineStar; - - #endregion - - #region KeyTerms (keywords + special symbols) - public KeyTermTable KeyTerms; - - public KeyTerm ToTerm(string text) { - return ToTerm(text, text); - } - public KeyTerm ToTerm(string text, string name) { - KeyTerm term; - if (KeyTerms.TryGetValue(text, out term)) { - //update name if it was specified now and not before - if (string.IsNullOrEmpty(term.Name) && !string.IsNullOrEmpty(name)) - term.Name = name; - return term; - } - //create new term - if (!CaseSensitive) - text = text.ToLowerInvariant(); - text = string.Intern(text); - term = new KeyTerm(text, name); - KeyTerms[text] = term; - return term; - } - - #endregion - - #region CurrentGrammar static field - //Static per-thread instance; Grammar constructor sets it to self (this). - // This field/property is used by operator overloads (which are static) to access Grammar's predefined terminals like Empty, - // and SymbolTerms dictionary to convert string literals to symbol terminals and add them to the SymbolTerms dictionary - [ThreadStatic] - private static Grammar _currentGrammar; - public static Grammar CurrentGrammar { - get { return _currentGrammar; } - } - internal static void ClearCurrentGrammar() { - _currentGrammar = null; - } - #endregion - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Grammar/GrammarError.cs b/sources/shaders/Irony/Parsing/Grammar/GrammarError.cs deleted file mode 100644 index eae6005dda..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/GrammarError.cs +++ /dev/null @@ -1,70 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - public enum GrammarErrorLevel { - NoError, //used only for max error level when there are no errors - Info, - Warning, - Conflict, //shift-reduce or reduce-reduce conflict - Error, //severe grammar error, parser construction cannot continue - InternalError, //internal Irony error - } - - public class GrammarError { - public readonly GrammarErrorLevel Level; - public readonly string Message; - public readonly ParserState State; //can be null! - public GrammarError(GrammarErrorLevel level, ParserState state, string message) { - Level = level; - State = state; - Message = message; - } - }//class - - public class GrammarErrorList : List { - public void Add(GrammarErrorLevel level, ParserState state, string message, params object[] args) { - if (args != null && args.Length > 0) - message = String.Format(message, args); - base.Add(new GrammarError(level, state, message)); - } - public void AddAndThrow(GrammarErrorLevel level, ParserState state, string message, params object[] args) { - Add(level, state, message, args); - var error = this[this.Count - 1]; - var exc = new GrammarErrorException(error.Message, error); - throw exc; - } - public GrammarErrorLevel GetMaxLevel() { - var max = GrammarErrorLevel.NoError; - foreach (var err in this) - if (max < err.Level) - max = err.Level; - return max; - } - } - - //Used to cancel parser construction when fatal error is found - public class GrammarErrorException : Exception { - public readonly GrammarError Error; - public GrammarErrorException(string message, GrammarError error) : base(message) { - Error = error; - } - - }//class - - -} diff --git a/sources/shaders/Irony/Parsing/Grammar/GrammarHint.cs b/sources/shaders/Irony/Parsing/Grammar/GrammarHint.cs deleted file mode 100644 index 4ba1945f11..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/GrammarHint.cs +++ /dev/null @@ -1,156 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - public enum HintType { - /// - /// Instruction to resolve conflict to shift - /// - ResolveToShift, - /// - /// Instruction to resolve conflict to reduce - /// - ResolveToReduce, - /// - /// Instruction to resolve the conflict using special code in grammar in OnResolvingConflict method. - /// - ResolveInCode, - /// - /// Currently ignored by Parser, may be used in the future to set specific precedence value of the following terminal operator. - /// One example where it can be used is setting higher precedence value for unary + or - operators. This hint would override - /// precedence set for these operators for cases when they are used as unary operators. (YACC has this feature). - /// - Precedence, - /// - /// Provided for all custom hints that derived solutions may introduce - /// - Custom - } - - - public class GrammarHintList : List { - } - - //Hints are additional instructions for parser added inside BNF expressions. - // Hint refers to specific position inside the expression (production), so hints are associated with LR0Item object - // One example is a conflict-resolution hint produced by the Grammar.PreferShiftHere() method. It tells parser to perform - // shift in case of a shift/reduce conflict. It is in fact the default action of LALR parser, so the hint simply suppresses the error - // message about the shift/reduce conflict in the grammar. - public class GrammarHint : BnfTerm { - public readonly HintType HintType; - public readonly object Data; - - public GrammarHint(HintType hintType, object data) : base("HINT") { - HintType = hintType; - Data = data; - } - } //class - - // Base class for custom grammar hints - public abstract class CustomGrammarHint : GrammarHint { - public ParserActionType Action { get; private set; } - public CustomGrammarHint(ParserActionType action) : base(HintType.Custom, null) { - Action = action; - } - public abstract bool Match(ConflictResolutionArgs args); - } - - // Semi-automatic conflict resolution hint - public class TokenPreviewHint : CustomGrammarHint { - public int MaxPreviewTokens { get; set; } // preview limit - private string FirstString { get; set; } - private ICollection OtherStrings { get; set; } - private Terminal FirstTerminal { get; set; } - private ICollection OtherTerminals { get; set; } - - private TokenPreviewHint(ParserActionType action) : base(action) { - FirstString = String.Empty; - OtherStrings = new HashSet(); - FirstTerminal = null; - OtherTerminals = new HashSet(); - MaxPreviewTokens = 0; - } - - public TokenPreviewHint(ParserActionType action, string first) : this(action) { - FirstString = first; - } - - public TokenPreviewHint(ParserActionType action, Terminal first) : this(action) { - FirstTerminal = first; - } - - public TokenPreviewHint ComesBefore(params string[] others) { - foreach (string term in others) - { - OtherStrings.Add(term); - } - return this; - } - - public TokenPreviewHint ComesBefore(params Terminal[] others) { - foreach (Terminal term in others) - { - OtherTerminals.Add(term); - } - return this; - } - - public TokenPreviewHint SetMaxPreview(int max) { - MaxPreviewTokens = max; - return this; - } - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - // convert strings to terminals, if needed - FirstTerminal = FirstTerminal ?? Grammar.ToTerm(FirstString); - if (OtherTerminals.Count == 0 && OtherStrings.Count > 0) - { - foreach (Terminal term in OtherStrings.Select(s => Grammar.ToTerm(s)).ToArray()) - { - OtherTerminals.Add(term); - } - } - } - - public override bool Match(ConflictResolutionArgs args) { - try { - args.Scanner.BeginPreview(); - - var count = 0; - var token = args.Scanner.GetToken(); - while (token != null && token.Terminal != args.Context.Language.Grammar.Eof) { - if (token.Terminal == FirstTerminal) - { - args.Result = Action; - return true; - } - if (OtherTerminals.Contains(token.Terminal)) - return false; - if (++count > MaxPreviewTokens && MaxPreviewTokens > 0) - return false; - token = args.Scanner.GetToken(); - } - return false; - } - finally { - args.Scanner.EndPreview(true); - } - } - } -} diff --git a/sources/shaders/Irony/Parsing/Grammar/LanguageAttribute.cs b/sources/shaders/Irony/Parsing/Grammar/LanguageAttribute.cs deleted file mode 100644 index be051545ff..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/LanguageAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Reflection; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - [AttributeUsage(AttributeTargets.Class)] - public class LanguageAttribute : Attribute { - public LanguageAttribute() : this(null) { } - public LanguageAttribute(string languageName) : this(languageName, "1.0", string.Empty) { } - - public LanguageAttribute(string languageName, string version, string description) { - _languageName = languageName; - _version = version; - _description = description; - } - - public string LanguageName { - get { return _languageName; } - } string _languageName; - - public string Version { - get { return _version; } - } string _version; - - public string Description { - get { return _description; } - } string _description; - - public static LanguageAttribute GetValue(Type grammarClass) { - return grammarClass.GetTypeInfo().GetCustomAttribute(true); - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Grammar/NonTerminal.cs b/sources/shaders/Irony/Parsing/Grammar/NonTerminal.cs deleted file mode 100644 index 70012c8eb8..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/NonTerminal.cs +++ /dev/null @@ -1,154 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Reflection; - -namespace Irony.Parsing { - - internal class IntList : List { } - - public class NonTerminal : BnfTerm { - - #region constructors - public NonTerminal(string name) : base(name, null) { } //by default display name is null - public NonTerminal(string name, string errorAlias) : base(name, errorAlias) { } - public NonTerminal(string name, string errorAlias, Type nodeType) : base(name, errorAlias, nodeType ) { } - public NonTerminal(string name, string errorAlias, AstNodeCreator nodeCreator) : base(name, errorAlias, nodeCreator) {} - public NonTerminal(string name, Type nodeType) : base(name, null, nodeType) { } - public NonTerminal(string name, AstNodeCreator nodeCreator) : base(name, null, nodeCreator) { } - public NonTerminal(string name, BnfExpression expression) - : this(name) { - Rule = expression; - } - #endregion - - #region properties/fields: Rule, ErrorRule - - public BnfExpression Rule; - //Separate property for specifying error expressions. This allows putting all such expressions in a separate section - // in grammar for all non-terminals. However you can still put error expressions in the main Rule property, just like - // in YACC - public BnfExpression ErrorRule; - - //A template for representing ParseTreeNode in the parse tree. Can contain '#{i}' fragments referencing - // child nodes by index - public string NodeCaptionTemplate; - //Converted template with index list - private string _convertedTemplate; - private IntList _captionParameters; - #endregion - - #region overrides: ToString, Init - public override string ToString() { - return Name; - } - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - if (!string.IsNullOrEmpty(NodeCaptionTemplate)) - ConvertNodeCaptionTemplate(); - if (TokenPreviewHint != null) - TokenPreviewHint.Init(grammarData); - } - #endregion - - #region data used by Parser builder - public readonly ProductionList Productions = new ProductionList(); - #endregion - - #region custom grammar hints - TokenPreviewHint TokenPreviewHint { get; set; } - internal void InsertCustomHints() { - if (TokenPreviewHint != null && Productions.Count > 0) { - foreach (var production in Productions) { - foreach (var lr0item in production.LR0Items) { - lr0item.Hints.Add(TokenPreviewHint); - } - } - } - } - public TokenPreviewHint Reduceif (string first) { - return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Reduce, first); - } - public TokenPreviewHint Reduceif (Terminal first) { - return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Reduce, first); - } - public TokenPreviewHint Shiftif (string first) { - return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Shift, first); - } - public TokenPreviewHint Shiftif (Terminal first) { - return TokenPreviewHint = new TokenPreviewHint(ParserActionType.Shift, first); - } - #endregion - - public static string NonTerminalsToString(IEnumerable terms, string separator) { - var sb = new StringBuilder(); - foreach (var term in terms) { - sb.Append(term.ToString()); - sb.Append(separator); - } - return sb.ToString().Trim(); - } - - #region NodeCaptionTemplate utilities - //We replace original tag '#{i}' (where i is the index of the child node to put here) - // with the tag '{k}', where k is the number of the parameter. So after conversion the template can - // be used in string.Format() call, with parameters set to child nodes captions - private void ConvertNodeCaptionTemplate() { - _captionParameters = new IntList(); - _convertedTemplate = NodeCaptionTemplate; - var index = 0; - while(index < 100) { - var strParam = "#{" + index + "}"; - if (_convertedTemplate.Contains(strParam)) { - _convertedTemplate = _convertedTemplate.Replace(strParam, "{" + _captionParameters.Count + "}"); - _captionParameters.Add(index); - } - if (!_convertedTemplate.Contains("#{")) return; - index++; - }//while - }//method - - public string GetNodeCaption(ParseTreeNode node) { - var paramValues = new string[_captionParameters.Count]; - for(int i = 0; i < _captionParameters.Count; i++) { - var childIndex = _captionParameters[i]; - if (childIndex < node.ChildNodes.Count) { - var child = node.ChildNodes[childIndex]; - //if child is a token, then child.ToString returns token.ToString which contains Value + Term; - // in this case we prefer to have Value only - paramValues[i] = (child.Token != null? child.Token.ValueString : child.ToString()); - } - } - var result = string.Format(_convertedTemplate, paramValues); - return result; - } - #endregion - - }//class - - public class NonTerminalList : List { - public override string ToString() { - return NonTerminal.NonTerminalsToString(this, " "); - } - } - - public class NonTerminalSet : HashSet { - public override string ToString() { - return NonTerminal.NonTerminalsToString(this, " "); - } - } - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Grammar/TermReportGroups.cs b/sources/shaders/Irony/Parsing/Grammar/TermReportGroups.cs deleted file mode 100644 index be9345b986..0000000000 --- a/sources/shaders/Irony/Parsing/Grammar/TermReportGroups.cs +++ /dev/null @@ -1,50 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - //Terminal report group is a facility for improving syntax error messages. - // Irony parser/scanner reports an error like "Syntax error, invalid character. Expected: ." - // The is a list of all terminals (symbols) that are expected in current position. - // This list might quite long and quite difficult to look through. The solution is to provide Group names for - // groups of terminals - Group of type Normal. - // Some terminals might be excluded from showing in expected list by including them into group of type Exclude. - // Finally, Operator group allows you to specify group name for all operator symbols without listing operators - - // Irony will collect all operator symbols registered with RegisterOperator method automatically. - - public enum TermReportGroupType { - Normal, - Exclude, - Operator - } - public class TermReportGroup { - public string Alias; - public TermReportGroupType GroupType; - public TerminalSet Terminals = new TerminalSet(); - - public TermReportGroup(string alias, TermReportGroupType groupType, IEnumerable terminals) { - Alias = alias; - GroupType = groupType; - if (terminals != null) - Terminals.UnionWith(terminals); - } - - }//class - - public class TermReportGroupList : List { } - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Parser/CoreParser.cs b/sources/shaders/Irony/Parsing/Parser/CoreParser.cs deleted file mode 100644 index 163a408d8c..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/CoreParser.cs +++ /dev/null @@ -1,384 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; -using System.Diagnostics; - - -namespace Irony.Parsing { - // CoreParser class implements NLALR parser automaton. Its behavior is controlled by the state transition graph - // with root in Data.InitialState. Each state contains a dictionary of parser actions indexed by input - // element (terminal or non-terminal). - public partial class CoreParser { - - #region Constructors - public CoreParser(Parser parser) { - Parser = parser; - Data = parser.Language.ParserData; - _grammar = Data.Language.Grammar; - } - #endregion - - #region Properties and fields: Parser, Data, _grammar - public readonly Parser Parser; - public readonly ParserData Data; - Grammar _grammar; - bool _traceEnabled; - - private ParsingContext Context { - get { return Parser.Context; } - } - #endregion - - internal void Reset() { - } - - #region Parse method - public void Parse() { - //main loop - Context.Status = ParserStatus.Parsing; - while(Context.Status == ParserStatus.Parsing) { - ExecuteAction(); - } - }//Parse - - #endregion - - #region reading input - private void ReadInput() { - if (Context.ParserInputStack.Count > 0) - Context.ParserInputStack.Pop(); - if (Context.ParserInputStack.Count > 0) { - Context.CurrentParserInput = Context.ParserInputStack.Top; - return; - } - FetchToken(); - } - - private void FetchToken() { - Token token; - //First skip all non-grammar tokens - do { - token = Parser.Scanner.GetToken(); - } while (token.Terminal.FlagIsSet(TermFlags.IsNonGrammar) && token.Terminal != _grammar.Eof); - if (token.Terminal.FlagIsSet(TermFlags.IsBrace)) - token = CheckBraceToken(token); - Context.CurrentParserInput = new ParseTreeNode(token); - Context.ParserInputStack.Push(Context.CurrentParserInput); - } - #endregion - - #region execute actions - private void ExecuteAction() { - _traceEnabled = Context.OptionIsSet(ParseOptions.TraceParser); - //Read input only if DefaultReduceAction is null - in this case the state does not contain ExpectedSet, - // so parser cannot assist scanner when it needs to select terminal and therefore can fail - if (Context.CurrentParserInput == null && Context.CurrentParserState.DefaultAction == null) - ReadInput(); - //Check scanner error - if (Context.CurrentParserInput != null && Context.CurrentParserInput.IsError) { - ProcessParserError(); - return; - } - //Try getting action - var action = FindActionForStateAndInput(); - if (action == null) { - if (CheckPartialInputCompleted()) - return; - ProcessParserError(); - return; - } - //We have action. First, write trace - if (_traceEnabled) Context.AddTrace("{0}", action); - //Execute it - switch (action.ActionType) { - case ParserActionType.Shift: ExecuteShift(action); break; - case ParserActionType.Operator: ExecuteOperatorAction(action); break; - case ParserActionType.Reduce: ExecuteReduce(action); break; - case ParserActionType.Code: ExecuteConflictAction(action); break; - case ParserActionType.Accept: ExecuteAccept(action); break; - } - } - - private bool CheckPartialInputCompleted() { - bool partialCompleted = (Context.Mode == ParseMode.CommandLine && Context.CurrentParserInput.Term == _grammar.Eof); - if (!partialCompleted) return false; - Context.Status = ParserStatus.AcceptedPartial; - // clean up EOF in input so we can continue parsing next line - Context.CurrentParserInput = null; - Context.ParserInputStack.Pop(); - return true; - } - - - private ParserAction FindActionForStateAndInput() { - if (Context.CurrentParserState.DefaultAction != null) - return Context.CurrentParserState.DefaultAction; - ParserAction action; - //First try as keyterm/key symbol; for example if token text = "while", then first try it as a keyword "while"; - // if this does not work, try as an identifier that happens to match a keyword but is in fact identifier - Token inputToken = Context.CurrentParserInput.Token; - if (inputToken != null && inputToken.KeyTerm != null) { - var keyTerm = inputToken.KeyTerm; - if (Context.CurrentParserState.Actions.TryGetValue(keyTerm, out action)) { - #region comments - // Ok, we found match as a key term (keyword or special symbol) - // Backpatch the token's term. For example in most cases keywords would be recognized as Identifiers by Scanner. - // Identifier would also check with SymbolTerms table and set AsSymbol field to SymbolTerminal if there exist - // one for token content. So we first find action by Symbol if there is one; if we find action, then we - // patch token's main terminal to AsSymbol value. This is important for recognizing keywords (for colorizing), - // and for operator precedence algorithm to work when grammar uses operators like "AND", "OR", etc. - //TODO: This might be not quite correct action, and we can run into trouble with some languages that have keywords that - // are not reserved words. But proper implementation would require substantial addition to parser code: - // when running into errors, we need to check the stack for places where we made this "interpret as Symbol" - // decision, roll back the stack and try to reinterpret as identifier - #endregion - inputToken.SetTerminal(keyTerm); - Context.CurrentParserInput.Term = keyTerm; - Context.CurrentParserInput.Precedence = keyTerm.Precedence; - Context.CurrentParserInput.Associativity = keyTerm.Associativity; - return action; - } - } - //Try to get by main Terminal, only if it is not the same as symbol - if (Context.CurrentParserState.Actions.TryGetValue(Context.CurrentParserInput.Term, out action)) - return action; - //If input is EOF and NewLineBeforeEof flag is set, try injecting NewLine into input - if (Context.CurrentParserInput.Term == _grammar.Eof && _grammar.FlagIsSet(LanguageFlags.NewLineBeforeEOF) && - Context.CurrentParserState.Actions.TryGetValue(_grammar.NewLine, out action)) { - InjectNewLineToken(); - return action; - }//if - return null; - } - - private void InjectNewLineToken() { - var newLineToken = new Token(_grammar.NewLine, Context.CurrentParserInput.Token.Location, "\r\n", null); - var newLineNode = new ParseTreeNode(newLineToken); - Context.ParserInputStack.Push(newLineNode); - Context.CurrentParserInput = newLineNode; - } - - - private void ExecuteShift(ParserAction action) { - Context.ParserStack.Push(Context.CurrentParserInput, action.NewState); - Context.CurrentParserState = action.NewState; - Context.CurrentParserInput = null; - if (action.NewState.DefaultAction == null) //read only if new state is NOT single-reduce state - ReadInput(); - } - - #region ExecuteReduce - private void ExecuteReduce(ParserAction action) { - var reduceProduction = action.ReduceProduction; - ParseTreeNode newNode; - if (reduceProduction.IsSet(ProductionFlags.IsListBuilder)) - newNode = ReduceExistingList(action); - else if (reduceProduction.LValue.FlagIsSet(TermFlags.IsListContainer)) - newNode = ReduceListContainer(action); - else if (reduceProduction.LValue.FlagIsSet(TermFlags.IsTransient)) - newNode = ReduceTransientNonTerminal(action); - else - newNode = ReduceRegularNode(action); - //final reduce actions ---------------------------------------------------------- - Context.ParserStack.Pop(reduceProduction.RValues.Count); - //Push new node into stack and move to new state - //First read the state from top of the stack - Context.CurrentParserState = Context.ParserStack.Top.State; - if (_traceEnabled) Context.AddTrace(Resources.MsgTracePoppedState, reduceProduction.LValue.Name); - // Shift to new state (LALR) - execute shift over non-terminal - var shift = Context.CurrentParserState.Actions[reduceProduction.LValue]; - Context.ParserStack.Push(newNode, shift.NewState); - Context.CurrentParserState = shift.NewState; - } - - private ParseTreeNode ReduceExistingList(ParserAction action) { - int childCount = action.ReduceProduction.RValues.Count; - int firstChildIndex = Context.ParserStack.Count - childCount; - var listNode = Context.ParserStack[firstChildIndex]; //get the list already created - it is the first child node - listNode.Span = ComputeNewNodeSpan(childCount); - var listMember = Context.ParserStack.Top; //next list member is the last child - at the top of the stack - if (ShouldSkipChildNode(listMember)) - return listNode; - CheckCreateAstNode(listMember); - listNode.ChildNodes.Add(listMember); - return listNode; - } - - private bool ShouldSkipChildNode(ParseTreeNode childNode) { - if (childNode.Term.FlagIsSet(TermFlags.IsPunctuation)) - return true; - if (childNode.Term.FlagIsSet(TermFlags.IsTransient) && childNode.ChildNodes.Count == 0) - return true; - return false; - } - - //List container is created by MakePlusRule, MakeStarRule with allowTrailingDelimiter = true - // it is a special case for parser. The "real" list in grammar is the "container", but list members had been accumulated under - // the transient "plus-list" which is a child of this container. So we need to copy all "grandchildren" from child to parent. - private ParseTreeNode ReduceListContainer(ParserAction action) { - int childCount = action.ReduceProduction.RValues.Count; - int firstChildIndex = Context.ParserStack.Count - childCount; - var span = ComputeNewNodeSpan(childCount); - var newNode = new ParseTreeNode(action.ReduceProduction, span); - if (childCount > 0) { //if it is not empty production - might happen for MakeStarRule - var listNode = Context.ParserStack[firstChildIndex]; //get the transient list with all members - it is the first child node - newNode.ChildNodes.AddRange(listNode.ChildNodes); //copy all list members - } - return newNode; - } - - private ParseTreeNode ReduceTransientNonTerminal(ParserAction action) { - var topIndex = Context.ParserStack.Count - 1; - var childCount = action.ReduceProduction.RValues.Count; - for(int i = 0; i < childCount; i++) { - var child = Context.ParserStack[topIndex - i]; - if (ShouldSkipChildNode(child)) continue; - CheckCreateAstNode(child); - return child; - } - //Otherwise return an empty transient node; if it is part of the list, the list will skip it - var span = ComputeNewNodeSpan(childCount); - return new ParseTreeNode(action.ReduceProduction, span); - } - - private ParseTreeNode ReduceRegularNode(ParserAction action) { - var childCount = action.ReduceProduction.RValues.Count; - int firstChildIndex = Context.ParserStack.Count - childCount; - var span = ComputeNewNodeSpan(childCount); - var newNode = new ParseTreeNode(action.ReduceProduction, span); - for(int i = 0; i < childCount; i++) { - var childNode = Context.ParserStack[firstChildIndex + i]; - if (ShouldSkipChildNode(childNode)) - continue; //skip punctuation or empty transient nodes - CheckCreateAstNode(childNode); //AST nodes for lists and for terminals are created here - //For single-child reduces inherit precedence and associativity, to cover a standard case: BinOp->+|-|*|/; - // BinOp node should inherit precedence from underlying operator symbol - if (childCount == 1 && childNode.Precedence != BnfTerm.NoPrecedence) { - newNode.Precedence = childNode.Precedence; - newNode.Associativity = childNode.Associativity; - } - newNode.ChildNodes.Add(childNode); - }//for i - return newNode; - } - - private SourceSpan ComputeNewNodeSpan(int childCount) { - if (childCount == 0) - return new SourceSpan(Context.CurrentParserInput.Span.Location, 0); - var first = Context.ParserStack[Context.ParserStack.Count - childCount]; - var last = Context.ParserStack.Top; - return new SourceSpan(first.Span.Location, last.Span.EndPosition - first.Span.Location.Position); - } - - private void CheckCreateAstNode(ParseTreeNode parseNode) { - try { - //Check preconditions - if ( !_grammar.FlagIsSet(LanguageFlags.CreateAst)) return; - if (parseNode.AstNode != null || parseNode.Term.FlagIsSet(TermFlags.IsTransient | TermFlags.NoAstNode)) return; - //if (Context.Status != ParserStatus.Parsing || Context.HasErrors) return; - if (Context.Status != ParserStatus.Parsing) return; - //Actually create node - _grammar.CreateAstNode(Context, parseNode); - if (parseNode.AstNode != null) - parseNode.Term.OnAstNodeCreated(parseNode); - } catch (Exception ex) { - Context.AddParserMessage(ParserErrorLevel.Error, parseNode.Span.Location, Resources.ErrFailedCreateNode, parseNode.Term.Name, ex.Message); - } - } - #endregion - - private void ExecuteConflictAction(ParserAction action) { - var args = action.ResolveConflict(_grammar, Context); - switch(args.Result) { - case ParserActionType.Reduce: - ExecuteReduce(new ParserAction(ParserActionType.Reduce, null, args.ReduceProduction)); - break; - case ParserActionType.Operator: - ExecuteOperatorAction(new ParserAction(ParserActionType.Operator, action.NewState, args.ReduceProduction)); - break; - case ParserActionType.Shift: - default: - ExecuteShift(action); - break; - } - if (_traceEnabled) Context.AddTrace(Resources.MsgTraceConflictResolved); - } - - private void ExecuteAccept(ParserAction action) { - var root = Context.ParserStack.Pop(); //Pop root - CheckCreateAstNode(root); - Context.CurrentParseTree.Root = root; - Context.Status = ParserStatus.Accepted; - } - - private void ExecuteOperatorAction(ParserAction action) { - var realActionType = GetActionTypeForOperation(action); - if (_traceEnabled) Context.AddTrace(Resources.MsgTraceOpResolved, realActionType); - switch (realActionType) { - case ParserActionType.Shift: ExecuteShift(action); break; - case ParserActionType.Reduce: ExecuteReduce(action); break; - }//switch - } - - private ParserActionType GetActionTypeForOperation(ParserAction action) { - for (int i = Context.ParserStack.Count - 1; i >= 0; i--) { - var prevNode = Context.ParserStack[i]; - if (prevNode == null) continue; - if (prevNode.Precedence == BnfTerm.NoPrecedence) continue; - ParserActionType result; - //if previous operator has the same precedence then use associativity - var input = Context.CurrentParserInput; - if (prevNode.Precedence == input.Precedence) - result = input.Associativity == Associativity.Left ? ParserActionType.Reduce : ParserActionType.Shift; - else - result = prevNode.Precedence > input.Precedence ? ParserActionType.Reduce : ParserActionType.Shift; - return result; - } - //If no operators found on the stack, do simple shift - return ParserActionType.Shift; - } - #endregion - - #region Braces handling - private Token CheckBraceToken(Token token) { - if (token.Terminal.FlagIsSet(TermFlags.IsOpenBrace)) { - Context.OpenBraces.Push(token); - return token; - } - //it is closing brace; check if we have opening brace - if (Context.OpenBraces.Count == 0) - return CreateBraceMismatchErrorToken(token); - //check that braces match - var lastBrace = Context.OpenBraces.Peek(); - if (lastBrace.Terminal.IsPairFor != token.Terminal) - return CreateBraceMismatchErrorToken(token); - //Link both tokens, pop the stack and return true - Token.LinkMatchingBraces(lastBrace, token); - Context.OpenBraces.Pop(); - return token; - } - - private Token CreateBraceMismatchErrorToken(Token closingBrace) { - return new Token(_grammar.SyntaxError, closingBrace.Location, closingBrace.Text, - string.Format(Resources.ErrUnmatchedCloseBrace, closingBrace.Text)); - } - #endregion - - }//class - - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Parser/CoreParser_ErrorHandling.cs b/sources/shaders/Irony/Parsing/Parser/CoreParser_ErrorHandling.cs deleted file mode 100644 index b781a95365..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/CoreParser_ErrorHandling.cs +++ /dev/null @@ -1,286 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -//Error handling methods of CoreParser class -namespace Irony.Parsing { - public partial class CoreParser { - - private void ProcessParserError() { - Context.Status = ParserStatus.Error; - _grammar.ReportParseError(this.Context); - if (Context.Mode != ParseMode.CommandLine) - TryRecoverFromError(); - } - - - private bool TryRecoverFromError() { - if (Context.CurrentParserInput.Term == _grammar.Eof) - return false; //do not recover if we're already at EOF - Context.Status = ParserStatus.Recovering; - Context.AddTrace(Resources.MsgTraceRecovering); // *** RECOVERING - searching for state with error shift *** - var recovered = TryRecoverImpl(); - string msg = (recovered ? Resources.MsgTraceRecoverSuccess : Resources.MsgTraceRecoverFailed); - Context.AddTrace(msg); //add new trace entry - Context.Status = recovered? ParserStatus.Parsing : ParserStatus.Error; - return recovered; - } - - private bool TryRecoverImpl() { - //1. We need to find a state in the stack that has a shift item based on error production (with error token), - // and error terminal is current. This state would have a shift action on error token. - ParserAction nextAction = FindErrorShiftActionInStackTemp(); - - if (nextAction == null) return false; - - var firstBnfTerm = nextAction.NewState.Actions.Keys.FirstOrDefault(); - - Context.AddTrace(Resources.MsgTraceRecoverReducing); - Context.AddTrace(Resources.MsgTraceRecoverAction, nextAction); - - // Inject faked node - var newLineNode = new ParseTreeNode(firstBnfTerm); - Context.ParserInputStack.Insert(0, newLineNode); - var saveParserInput = Context.CurrentParserInput; - Context.CurrentParserInput = newLineNode; - - nextAction = FindActionForStateAndInput(); - - while (nextAction != null && Context.CurrentParserInput != null) - { - switch (nextAction.ActionType) - { - case ParserActionType.Shift: - ExecuteShift(nextAction); - break; - case ParserActionType.Operator: - ExecuteOperatorAction(nextAction); - break; - case ParserActionType.Reduce: - ExecuteReduce(nextAction); - break; - case ParserActionType.Code: - ExecuteConflictAction(nextAction); - break; - case ParserActionType.Accept: - ExecuteAccept(nextAction); - break; - } - nextAction = FindActionForStateAndInput(); - } - - Context.ParserInputStack.RemoveAt(0); - Context.CurrentParserInput = saveParserInput; - - if (!Context.CurrentParserState.Actions.TryGetValue(Context.CurrentParserInput.Term, out nextAction)) - { - Context.ParserInputStack.Clear(); - Context.CurrentParserInput = null; - } - - return true; - //ExecuteShiftTemp(firstBnfTerm, nextAction); - -/* - var action = GetReduceActionInCurrentState(); - if (action != null) - { - //Clear all input token queues and buffered input, reset location back to input position token queues; - //Reduce error production - it creates parent non-terminal that "hides" error inside - ExecuteReduce(action); - return true; //we recovered - } - return true; - - ParserAction errorShiftAction = FindErrorShiftActionInStack(); - if (errorShiftAction == null) return false; //we failed to recover - Context.AddTrace(Resources.MsgTraceRecoverFoundState, Context.CurrentParserState); - //2. Shift error token - execute shift action - Context.AddTrace(Resources.MsgTraceRecoverShiftError, errorShiftAction); - ExecuteShift(errorShiftAction); - //4. Now we need to go along error production until the end, shifting tokens that CAN be shifted and ignoring others. - // We shift until we can reduce - Context.AddTrace(Resources.MsgTraceRecoverShiftTillEnd); - while (true) { - if (Context.CurrentParserInput == null) - ReadInput(); - if (Context.CurrentParserInput.Term == _grammar.Eof) - return false; - //Check if we can reduce - action = GetReduceActionInCurrentState(); - if (action != null) { - //Clear all input token queues and buffered input, reset location back to input position token queues; - Context.SetSourceLocation(Context.CurrentParserInput.Span.Location); - Context.ParserInputStack.Clear(); - Context.CurrentParserInput = null; - - //Reduce error production - it creates parent non-terminal that "hides" error inside - Context.AddTrace(Resources.MsgTraceRecoverReducing); - Context.AddTrace(Resources.MsgTraceRecoverAction, action); - ExecuteReduceOnError(action); - return true; //we recovered - } - //No reduce action in current state. Try to shift current token or throw it away or reduce - action = GetShiftActionInCurrentState(); - if (action != null) - ExecuteShift(action); //shift input token - else //simply read input - ReadInput(); - } - */ - }//method - - private void ExecuteShiftTemp(BnfTerm term, ParserAction action) - { - Context.ParserStack.Push(new ParseTreeNode(term), action.NewState); - Context.CurrentParserState = action.NewState; - } - - - // --> START EDIT ALEX - private void ExecuteReduceOnError(ParserAction action) - { - var reduceProduction = action.ReduceProduction; - //final reduce actions ---------------------------------------------------------- - Context.ParserStack.Pop(1); - //Push new node into stack and move to new state - //First read the state from top of the stack - Context.CurrentParserState = Context.ParserStack.Top.State; - if (_traceEnabled) Context.AddTrace(Resources.MsgTracePoppedState, reduceProduction.LValue.Name); - // Shift to new state (LALR) - execute shift over non-terminal - var shift = Context.CurrentParserState.Actions[reduceProduction.LValue]; - Context.ParserStack.Push(new ParseTreeNode(action.ReduceProduction.LValue), shift.NewState); - Context.CurrentParserState = shift.NewState; - } - // --> END EDIT ALEX - - public void ResetLocationAndClearInput(SourceLocation location, int position) { - Context.CurrentParserInput = null; - Context.ParserInputStack.Clear(); - Context.SetSourceLocation(location); - } - - private ParserAction FindErrorShiftActionInStack() { - while (Context.ParserStack.Count >= 1) { - ParserAction errorShiftAction; - if (Context.CurrentParserState.Actions.TryGetValue(_grammar.SyntaxError, out errorShiftAction) && errorShiftAction.ActionType == ParserActionType.Shift) - return errorShiftAction; - //pop next state from stack - if (Context.ParserStack.Count == 1) - return null; //don't pop the initial state - Context.ParserStack.Pop(); - Context.CurrentParserState = Context.ParserStack.Top.State; - } - return null; - } - - private ParserAction FindErrorShiftActionInStackTemp() - { - for (int i = Context.ParserStack.Count - 1; i >= 0; i--) - { - ParserAction errorShiftAction; - var currentState = Context.ParserStack[i].State; - - if (currentState.Actions.TryGetValue(_grammar.SyntaxError, out errorShiftAction) && errorShiftAction.ActionType == ParserActionType.Shift) - { - return errorShiftAction; - } - } - return null; - } - - private ParserAction FindErrorShiftActionInStack(BnfTerm exitTerm) - { - while (Context.ParserStack.Count >= 1) - { - ParserAction errorShiftAction; - if (Context.CurrentParserState.Actions.TryGetValue(exitTerm, out errorShiftAction)) - return errorShiftAction; - //pop next state from stack - if (Context.ParserStack.Count == 1) - return null; //don't pop the initial state - Context.ParserStack.Pop(); - Context.CurrentParserState = Context.ParserStack.Top.State; - } - return null; - } - - - - private ParserAction GetReduceActionInCurrentState() { - if (Context.CurrentParserState.DefaultAction != null) return Context.CurrentParserState.DefaultAction; - foreach (var action in Context.CurrentParserState.Actions.Values) - { - // --> START EDIT ALEX. Force to reduce - if (action.NewState.DefaultAction != null && (action.NewState.DefaultAction.ActionType == ParserActionType.Reduce)) - return action.NewState.DefaultAction; - // --> END EDIT ALEX - if (action.ActionType == ParserActionType.Reduce) return action; - - } - return null; - } - - private ParserAction GetShiftActionInCurrentState() { - ParserAction result = null; - if (Context.CurrentParserState.Actions.TryGetValue(Context.CurrentParserInput.Term, out result) || - Context.CurrentParserInput.Token != null && Context.CurrentParserInput.Token.KeyTerm != null && - Context.CurrentParserState.Actions.TryGetValue(Context.CurrentParserInput.Token.KeyTerm, out result)) - if (result.ActionType == ParserActionType.Shift) - return result; - return null; - } - - #region comments - // Computes set of expected terms in a parser state. While there may be extended list of symbols expected at some point, - // we want to reorganize and reduce it. For example, if the current state expects all arithmetic operators as an input, - // it would be better to not list all operators (+, -, *, /, etc) but simply put "operator" covering them all. - // To achieve this grammar writer can group operators (or any other terminals) into named groups using Grammar's methods - // AddTermReportGroup, AddNoReportGroup etc. Then instead of reporting each operator separately, Irony would include - // a single "group name" to represent them all. - // The "expected report set" is not computed during parser construction (it would bite considerable time), but on demand during parsing, - // when error is detected and the expected set is actually needed for error message. - // Multi-threading concerns. When used in multi-threaded environment (web server), the LanguageData would be shared in - // application-wide cache to avoid rebuilding the parser data on every request. The LanguageData is immutable, except - // this one case - the expected sets are constructed late by CoreParser on the when-needed basis. - // We don't do any locking here, just compute the set and on return from this function the state field is assigned. - // We assume that this field assignment is an atomic, concurrency-safe operation. The worst thing that might happen - // is "double-effort" when two threads start computing the same set around the same time, and the last one to finish would - // leave its result in the state field. - #endregion - internal static StringSet ComputeGroupedExpectedSetForState(Grammar grammar, ParserState state) { - var terms = new TerminalSet(); - terms.UnionWith(state.ExpectedTerminals); - var result = new StringSet(); - //Eliminate no-report terminals - foreach(var group in grammar.TermReportGroups) - if (group.GroupType == TermReportGroupType.Exclude) - terms.ExceptWith(group.Terminals); - //Add normal and operator groups - foreach(var group in grammar.TermReportGroups) - if (group.GroupType == TermReportGroupType.Normal || group.GroupType == TermReportGroupType.Operator && terms.Overlaps(group.Terminals)) { - result.Add(group.Alias); - terms.ExceptWith(group.Terminals); - } - //Add remaining terminals "as is" - foreach(var terminal in terms) - result.Add(terminal.ErrorAlias); - return result; - } - - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Parser/ParseTree.cs b/sources/shaders/Irony/Parsing/Parser/ParseTree.cs deleted file mode 100644 index 2fe9c50500..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/ParseTree.cs +++ /dev/null @@ -1,151 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - - /* - A node for a parse tree (concrete syntax tree) - an initial syntax representation produced by parser. - It contains all syntax elements of the input text, each element represented by a generic node ParseTreeNode. - The parse tree is converted into abstract syntax tree (AST) which contains custom nodes. The conversion might - happen on-the-fly: as parser creates the parse tree nodes it can create the AST nodes and puts them into AstNode field. - Alternatively it might happen as a separate step, after completing the parse tree. - AST node might optinally implement IAstNodeInit interface, so Irony parser can initialize the node providing it - with all relevant information. - The ParseTreeNode also works as a stack element in the parser stack, so it has the State property to carry - the pushed parser state while it is in the stack. - */ - public class ParseTreeNode { - public object AstNode; - public Token Token; - public BnfTerm Term; - public int Precedence; - public Associativity Associativity; - public SourceSpan Span; - public Production ReduceProduction; - //Making ChildNodes property (not field) following request by Matt K, Bill H - public ParseTreeNodeList ChildNodes {get; private set;} - public bool IsError; - internal ParserState State; //used by parser to store current state when node is pushed into the parser stack - public object Tag; //for use by custom parsers, Irony does not use it - - private ParseTreeNode(){ - ChildNodes = new ParseTreeNodeList(); - } - public ParseTreeNode(BnfTerm term) : this() { - Term = term; - } - - public ParseTreeNode(Token token) : this() { - Token = token; - Term = token.Terminal; - Precedence = Term.Precedence; - Associativity = token.Terminal.Associativity; - Span = new SourceSpan(token.Location, token.Length); - IsError = token.IsError(); - } - - public ParseTreeNode(ParserState initialState) : this() { - State = initialState; - } - - public ParseTreeNode(Production reduceProduction, SourceSpan span) : this(){ - ReduceProduction = reduceProduction; - Span = span; - Term = ReduceProduction.LValue; - Precedence = Term.Precedence; - } - - public ParseTreeNode(object node, BnfTerm term, int precedence, Associativity associativity, SourceSpan span) - : this() { - AstNode = node; - Term = term; - Precedence = precedence; - Associativity = associativity; - } - - public override string ToString() { - if (Term == null) - return "(S0)"; //initial state node - else - return Term.GetParseNodeCaption(this); - }//method - - public string FindTokenAndGetText() { - var tkn = FindToken(); - return tkn == null ? null : tkn.Text; - } - public Token FindToken() { - return FindFirstChildTokenRec(this); - } - private static Token FindFirstChildTokenRec(ParseTreeNode node) { - if (node.Token != null) return node.Token; - foreach (var child in node.ChildNodes) { - var tkn = FindFirstChildTokenRec(child); - if (tkn != null) return tkn; - } - return null; - } - public ParseTreeNode FirstChild { - get { return ChildNodes[0]; } - } - public ParseTreeNode LastChild { - get { return ChildNodes[ChildNodes.Count -1]; } - } - - }//class - - public class ParseTreeNodeList : List { } - - public enum ParseTreeStatus { - Parsing, - Partial, - Parsed, - Error, - } - - public class ParseTree { - public ParseTreeStatus Status {get; internal set;} - public readonly string SourceText; - public readonly string FileName; - public readonly TokenList Tokens = new TokenList(); - public readonly TokenList OpenBraces = new TokenList(); - public ParseTreeNode Root; - public readonly ParserMessageList ParserMessages = new ParserMessageList(); - public int ParseTime; - - public ParseTree(string sourceText, string fileName) { - SourceText = sourceText; - FileName = fileName; - Status = ParseTreeStatus.Parsing; - } - - public bool HasErrors() { - if (ParserMessages.Count == 0) return false; - foreach (var err in ParserMessages) - if (err.Level == ParserErrorLevel.Error) return true; - return false; - }//method - - public void CopyMessages(ParserMessageList others, SourceLocation baseLocation, string messagePrefix) { - foreach(var other in others) - this.ParserMessages.Add(new ParserMessage(other.Level, baseLocation + other.Location, messagePrefix + other.Message, other.ParserState)); - }// - - }//class - -} diff --git a/sources/shaders/Irony/Parsing/Parser/Parser.cs b/sources/shaders/Irony/Parsing/Parser/Parser.cs deleted file mode 100644 index fa5afff299..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/Parser.cs +++ /dev/null @@ -1,220 +0,0 @@ -#region License - -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; - -namespace Irony.Parsing -{ - // Parser class represents combination of scanner and LALR parser (CoreParser) - /// - /// - public class Parser - { - #region Constants and Fields - - /// - /// - public readonly CoreParser CoreParser; - - /// - /// - public readonly LanguageData Language; - - /// - /// - public readonly NonTerminal Root; - - /// - /// - public readonly Scanner Scanner; - - internal readonly ParserState InitialState; - - #endregion - - #region Constructors and Destructors - - /// - /// - /// - /// - public Parser(Grammar grammar) - : this(new LanguageData(grammar)) - { - } - - /// - /// - /// - /// - public Parser(LanguageData language) - : this(language, null, null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The language. - /// The scanner. - /// The root. - /// - /// - public Parser(LanguageData language, Scanner scanner, NonTerminal root) - { - Language = language; - Context = new ParsingContext(this); - Scanner = scanner ?? language.CreateScanner(); - - if (Scanner != null) - { - Scanner.Initialize(this); - } - else - { - Language.Errors.Add(GrammarErrorLevel.Error, null, "Scanner is not initialized for this grammar"); - } - CoreParser = new CoreParser(this); - Root = root; - if (Root == null) - { - Root = Language.Grammar.Root; - InitialState = Language.ParserData.InitialState; - } - else - { - if (Root != Language.Grammar.Root && !Language.Grammar.SnippetRoots.Contains(Root)) - { - throw new Exception(string.Format(Resources.ErrRootNotRegistered, root.Name)); - } - - InitialState = Language.ParserData.InitialStates[Root]; - } - } - - #endregion - - #region Public Properties - - /// - /// - public ParsingContext Context { get; internal set; } - - #endregion - - #region Public Methods - - /// - /// - /// - /// - /// - /// - public ParseTree Parse(string sourceText) - { - return Parse(sourceText, ""); - } - - /// - /// - /// - /// - /// - /// - /// - /// - public ParseTree Parse(string sourceText, string fileName) - { - if (Context.Status != ParserStatus.AcceptedPartial) - { - Reset(); - } - - // TODO Set SourceStream on Scanner - // Context.SourceStream.SetText(sourceText, 0, Context.Status == ParserStatus.AcceptedPartial); - Scanner.SetSourceText(sourceText, fileName); - - Context.CurrentParseTree = new ParseTree(sourceText, fileName); - Context.Status = ParserStatus.Parsing; - int start = Environment.TickCount; - CoreParser.Parse(); - Context.CurrentParseTree.ParseTime = Environment.TickCount - start; - UpdateParseTreeStatus(); - return Context.CurrentParseTree; - } - - /// - /// - /// - /// - /// - /// - /// - /// - public ParseTree ScanOnly(string sourceText, string fileName) - { - Context.CurrentParseTree = new ParseTree(sourceText, fileName); - // TODO Set SourceStream on Scanner - // Context.SourceStream.SetText(sourceText, 0, false); - while (true) - { - var token = Scanner.GetToken(); - if (token == null || token.Terminal == Language.Grammar.Eof) - { - break; - } - } - - return Context.CurrentParseTree; - } - - #endregion - - #region Methods - - internal void Reset() - { - Context.Reset(); - CoreParser.Reset(); - Scanner.Reset(); - } - - private void UpdateParseTreeStatus() - { - var parseTree = Context.CurrentParseTree; - if (parseTree.ParserMessages.Count > 0) - { - parseTree.ParserMessages.Sort(ParserMessageList.ByLocation); - } - - if (parseTree.HasErrors()) - { - parseTree.Status = ParseTreeStatus.Error; - } - else if (Context.Status == ParserStatus.AcceptedPartial) - { - parseTree.Status = ParseTreeStatus.Partial; - } - else - { - parseTree.Status = ParseTreeStatus.Parsed; - } - } - - #endregion - } - - // class -} - -//namespace \ No newline at end of file diff --git a/sources/shaders/Irony/Parsing/Parser/ParserStack.cs b/sources/shaders/Irony/Parsing/Parser/ParserStack.cs deleted file mode 100644 index c3065c5728..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/ParserStack.cs +++ /dev/null @@ -1,47 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class ParserStack : List { - public ParserStack() : base(200) { } - public void Push(ParseTreeNode nodeInfo) { - base.Add(nodeInfo); - } - public void Push(ParseTreeNode nodeInfo, ParserState state) { - nodeInfo.State = state; - base.Add(nodeInfo); - } - public ParseTreeNode Pop() { - var top = Top; - base.RemoveAt(Count - 1); - return top; - } - public void Pop(int count) { - base.RemoveRange(Count - count, count); - } - public void PopUntil(int finalCount) { - if (finalCount < Count) - Pop(Count - finalCount); - } - public ParseTreeNode Top { - get { - if (Count == 0) return null; - return base[Count - 1]; - } - } - } -} diff --git a/sources/shaders/Irony/Parsing/Parser/ParsingContext.cs b/sources/shaders/Irony/Parsing/Parser/ParsingContext.cs deleted file mode 100644 index 145261d585..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/ParsingContext.cs +++ /dev/null @@ -1,245 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -using System.Diagnostics; -using System.Globalization; - -namespace Irony.Parsing { - - [Flags] - public enum ParseOptions { - GrammarDebugging = 0x01, - TraceParser = 0x02, - AnalyzeCode = 0x10, //run code analysis; effective only in Module mode - } - - public enum ParseMode { - File, //default, continuous input file - VsLineScan, // line-by-line scanning in VS integration for syntax highlighting - CommandLine, //line-by-line from console - } - - public enum ParserStatus { - Init, //initial state - Parsing, - Previewing, //previewing tokens - Recovering, //recovering from error - Accepted, - AcceptedPartial, - Error, - } - - // The purpose of this class is to provide a container for information shared - // between parser, scanner and token filters. - public class ParsingContext { - public readonly Parser Parser; - public readonly LanguageData Language; - - //Parser settings - public ParseOptions Options; - public ParseMode Mode = ParseMode.File; - public int MaxErrors = 20; //maximum error count to report - public CultureInfo Culture; //defaults to Grammar.DefaultCulture, might be changed by app code - - #region properties and fields - //Parser fields - public ParserState CurrentParserState { get; internal set; } - public ParseTreeNode CurrentParserInput { get; internal set; } - public readonly ParserStack ParserStack = new ParserStack(); - internal readonly ParserStack ParserInputStack = new ParserStack(); - - public ParseTree CurrentParseTree { get; internal set; } - public readonly TokenStack OpenBraces = new TokenStack(); - public ParserTrace ParserTrace = new ParserTrace(); - //public ISourceStream Source { get { return SourceStream; } } - //list for terminals - for current parser state and current input char - public TerminalList CurrentTerminals = new TerminalList(); - public Token CurrentToken; //The token just scanned by Scanner - public Token PreviousToken; - public SourceLocation PreviousLineStart; //Location of last line start - - //Internal fields - //internal SourceStream SourceStream; - internal TokenFilterList TokenFilters = new TokenFilterList(); - internal ParsingEventArgs SharedParsingEventArgs; - - public VsScannerStateMap VsLineScanState; //State variable used in line scanning mode for VS integration - - public ParserStatus Status {get; internal set;} - public bool HasErrors; //error flag, once set remains set - - //values dictionary to use by custom language implementations to save some temporary values in parse process - public readonly Dictionary Values = new Dictionary(); - - public int TabWidth - { - get { return _tabWidth; } - set - { - _tabWidth = value; - } - } - int _tabWidth = 8; - - #endregion - - - #region constructors - public ParsingContext(Parser parser) { - this.Parser = parser; - Language = Parser.Language; - Culture = Language.Grammar.DefaultCulture; - //This might be a problem for multi-threading - if we have several contexts on parallel threads with different culture. - //Resources.Culture is static property (this is not Irony's fault, this is auto-generated file). - Resources.Culture = Culture; - //We assume that if Irony is compiled in Debug mode, then developer is debugging his grammar/language implementation -#if DEBUG - Options |= ParseOptions.GrammarDebugging; -#endif - SharedParsingEventArgs = new ParsingEventArgs(this); - } - #endregion - - - #region Events: TokenCreated - public event EventHandler TokenCreated; - - internal void OnTokenCreated() { - TokenCreated?.Invoke(this, SharedParsingEventArgs); - } - #endregion - - #region Options helper methods - public bool OptionIsSet(ParseOptions option) { - return (Options & option) != 0; - } - public void SetOption(ParseOptions option, bool value) { - if (value) - Options |= option; - else - Options &= ~option; - } - #endregion - - #region Error handling and tracing - public void AddParserError(string message, params object[] args) { - var location = CurrentParserInput == null? Parser.Scanner.Location : CurrentParserInput.Span.Location; - HasErrors = true; - AddParserMessage(ParserErrorLevel.Error, location, message, args); - } - public void AddParserMessage(ParserErrorLevel level, SourceLocation location, string message, params object[] args) { - if (CurrentParseTree == null) return; - if (CurrentParseTree.ParserMessages.Count >= MaxErrors) return; - if (args != null && args.Length > 0) - message = string.Format(message, args); - CurrentParseTree.ParserMessages.Add(new ParserMessage(level, location, message, CurrentParserState)); - if (OptionIsSet(ParseOptions.TraceParser)) - ParserTrace.Add( new ParserTraceEntry(CurrentParserState, ParserStack.Top, CurrentParserInput, message, true)); - } - - public void AddTrace(string message, params object[] args) { - if (!OptionIsSet(ParseOptions.TraceParser)) return; - if (args != null && args.Length > 0) - message = string.Format(message, args); - ParserTrace.Add(new ParserTraceEntry(CurrentParserState, ParserStack.Top, CurrentParserInput, message, false)); - } - - #endregion - - internal void Reset() { - CurrentParserState = Parser.InitialState; - CurrentParserInput = null; - ParserStack.Clear(); - HasErrors = false; - ParserStack.Push(new ParseTreeNode(CurrentParserState)); - ParserInputStack.Clear(); - CurrentParseTree = null; - OpenBraces.Clear(); - ParserTrace.Clear(); - CurrentTerminals.Clear(); - CurrentToken = null; - PreviousToken = null; - PreviousLineStart = new SourceLocation(0, -1, 0); - Values.Clear(); - foreach (var filter in TokenFilters) - filter.Reset(); - } - - public void SetSourceLocation(SourceLocation location) { - foreach (var filter in TokenFilters) - filter.OnSetSourceLocation(location); - Parser.Scanner.Location = location; - } - - #region Expected term set computations - public StringSet GetExpectedTermSet() { - if (CurrentParserState == null) - return new StringSet(); - //See note about multi-threading issues in ComputeReportedExpectedSet comments. - if (CurrentParserState.ReportedExpectedSet == null) - CurrentParserState.ReportedExpectedSet = CoreParser.ComputeGroupedExpectedSetForState(Language.Grammar, CurrentParserState); - //Filter out closing braces which are not expected based on previous input. - // While the closing parenthesis ")" might be expected term in a state in general, - // if there was no opening parenthesis in preceding input then we would not - // expect a closing one. - var expectedSet = FilterBracesInExpectedSet(CurrentParserState.ReportedExpectedSet); - return expectedSet; - } - - private StringSet FilterBracesInExpectedSet(StringSet stateExpectedSet) { - var result = new StringSet(); - result.UnionWith(stateExpectedSet); - //Find what brace we expect - var nextClosingBrace = string.Empty; - if (OpenBraces.Count > 0) { - var lastOpenBraceTerm = OpenBraces.Peek().KeyTerm; - var nextClosingBraceTerm = lastOpenBraceTerm.IsPairFor as KeyTerm; - if (nextClosingBraceTerm != null) - nextClosingBrace = nextClosingBraceTerm.Text; - } - //Now check all closing braces in result set, and leave only nextClosingBrace - foreach(var closingBrace in Language.GrammarData.ClosingBraces) { - if (result.Contains(closingBrace) && closingBrace != nextClosingBrace) - result.Remove(closingBrace); - - } - return result; - } - - #endregion - - - }//class - - // A struct used for packing/unpacking ScannerState int value; used for VS integration. - // When Terminal produces incomplete token, it sets - // this state to non-zero value; this value identifies this terminal as the one who will continue scanning when - // it resumes, and the terminal's internal state when there may be several types of multi-line tokens for one terminal. - // For ex., there maybe several types of string literal like in Python. - [StructLayout(LayoutKind.Explicit)] - public struct VsScannerStateMap { - [FieldOffset(0)] - public int Value; - [FieldOffset(0)] - public byte TerminalIndex; //1-based index of active multiline term in MultilineTerminals - [FieldOffset(1)] - public byte TokenSubType; //terminal subtype (used in StringLiteral to identify string kind) - [FieldOffset(2)] - public short TerminalFlags; //Terminal flags - }//struct - - -} diff --git a/sources/shaders/Irony/Parsing/Parser/ParsingEventArgs.cs b/sources/shaders/Irony/Parsing/Parser/ParsingEventArgs.cs deleted file mode 100644 index b0f836f7c2..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/ParsingEventArgs.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - public class ParsingEventArgs : EventArgs { - public readonly ParsingContext Context; - public ParsingEventArgs(ParsingContext context) { - Context = context; - } - } -} diff --git a/sources/shaders/Irony/Parsing/Parser/SyntaxError.cs b/sources/shaders/Irony/Parsing/Parser/SyntaxError.cs deleted file mode 100644 index e44f3d1a84..0000000000 --- a/sources/shaders/Irony/Parsing/Parser/SyntaxError.cs +++ /dev/null @@ -1,42 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - //Container for syntax error - public class SyntaxError { - public SyntaxError(SourceLocation location, string message, ParserState parserState) { - Location = location; - Message = message; - ParserState = parserState; - } - - public readonly SourceLocation Location; - public readonly string Message; - public ParserState ParserState; - - public override string ToString() { - return Message; - } - }//class - - public class SyntaxErrorList : List { - public static int ByLocation(SyntaxError x, SyntaxError y) { - return SourceLocation.Compare(x.Location, y.Location); - } - } - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Scanner/DefaultScanner.cs b/sources/shaders/Irony/Parsing/Scanner/DefaultScanner.cs deleted file mode 100644 index 7ab9a8919c..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/DefaultScanner.cs +++ /dev/null @@ -1,271 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace Irony.Parsing { - - //Scanner class. The Scanner's function is to transform a stream of characters into aggregates/words or lexemes, - // like identifier, number, literal, etc. - - public class DefaultScanner : Scanner - { - #region Properties and Fields: Data, _source - - //buffered tokens can come from expanding a multi-token, when Terminal.TryMatch() returns several tokens packed into one token - - #endregion - - private SourceStream SourceStream; - - - protected override void PrepareInput() - { - SourceStream = new SourceStream(this.Data, Context.TabWidth); - } - - #region Scanning tokens - protected override void NextToken() { - //1. Check if there are buffered tokens - if(Context.BufferedTokens.Count > 0) { - Context.CurrentToken = Context.BufferedTokens.Pop(); - return; - } - //2. Skip whitespace. We don't need to check for EOF: at EOF we start getting 0-char, so we'll get out automatically - while (Grammar.WhitespaceChars.IndexOf(SourceStream.PreviewChar) >= 0) - SourceStream.PreviewPosition++; - //3. That's the token start, calc location (line and column) - SourceStream.MoveLocationToPreviewPosition(); - //4. Check for EOF - if (SourceStream.EOF()) { - Context.CurrentToken = new Token(Grammar.Eof, SourceStream.Location, string.Empty, Grammar.Eof.Name);; - return; - } - //5. Actually scan the source text and construct a new token - ScanToken(); - }//method - - //Scans the source text and constructs a new token - private void ScanToken() { - if (!MatchNonGrammarTerminals() && !MatchRegularTerminals()) { - //we are in error already; try to match ANY terminal and let the parser report an error - MatchAllTerminals(); //try to match any terminal out there - } - var token = Context.CurrentToken; - //If we have normal token then return it - if (token != null && !token.IsError()) { - //set position to point after the result token - SourceStream.PreviewPosition = SourceStream.Location.Position + token.Length; - SourceStream.MoveLocationToPreviewPosition(); - return; - } - //we have an error: either error token or no token at all - if (token == null) //if no token then create error token - Context.CurrentToken = SourceStream.CreateErrorToken(Resources.ErrInvalidChar, SourceStream.PreviewChar); - Recover(); - } - - private bool MatchNonGrammarTerminals() { - TerminalList terms; - if (!Data.NonGrammarTerminalsLookup.TryGetValue(SourceStream.PreviewChar, out terms)) - return false; - foreach(var term in terms) { - SourceStream.ResetPreviewPosition(); - Context.CurrentToken = term.TryMatch(Context, SourceStream); - if (Context.CurrentToken != null) - term.InvokeValidateToken(Context); - if (Context.CurrentToken != null) { - //check if we need to fire LineStart token before this token; - // we do it only if the token is not a comment; comments should be ignored by the outline logic - var token = Context.CurrentToken; - if (token.Category == TokenCategory.Content && NeedLineStartToken(token.Location)) { - Context.BufferedTokens.Push(token); //buffer current token; we'll eject LineStart instead - SourceStream.Location = token.Location; //set it back to the start of the token - Context.CurrentToken = SourceStream.CreateToken(Grammar.LineStartTerminal); //generate LineStart - Context.PreviousLineStart = SourceStream.Location; //update LineStart - } - return true; - }//if - }//foreach term - SourceStream.ResetPreviewPosition(); - return false; - } - - private bool NeedLineStartToken(SourceLocation forLocation) { - return Grammar.FlagIsSet(LanguageFlags.EmitLineStartToken) && forLocation.Line > Context.PreviousLineStart.Line; - } - - private bool MatchRegularTerminals() { - //We need to eject LineStart BEFORE we try to produce a real token; this LineStart token should reach - // the parser, make it change the state and with it to change the set of expected tokens. So when we - // finally move to scan the real token, the expected terminal set is correct. - if (NeedLineStartToken(SourceStream.Location)) { - Context.CurrentToken = SourceStream.CreateToken(Grammar.LineStartTerminal); - Context.PreviousLineStart = SourceStream.Location; - return true; - } - //Find matching terminal - // First, try terminals with explicit "first-char" prefixes, selected by current char in source - ComputeCurrentTerminals(); - //If we have more than one candidate; let grammar method select - if (Context.CurrentTerminals.Count > 1) - Grammar.OnScannerSelectTerminal(Context); - - MatchTerminals(); - //If we don't have a token from terminals, try Grammar's method - if (Context.CurrentToken == null) - Context.CurrentToken = Grammar.TryMatch(Context, SourceStream); - if (Context.CurrentToken is MultiToken) - UnpackMultiToken(); - return Context.CurrentToken != null; - }//method - - // This method is a last attempt by scanner to match ANY terminal, after regular matching (by input char) had failed. - // Likely this will produce some token which is invalid for current parser state (for ex, identifier where a number - // is expected); in this case the parser will report an error as "Error: expected number". - // if this matching fails, the scanner will produce an error as "unexpected character." - private bool MatchAllTerminals() { - Context.CurrentTerminals.Clear(); - Context.CurrentTerminals.AddRange(Data.Language.GrammarData.Terminals); - MatchTerminals(); - if (Context.CurrentToken is MultiToken) - UnpackMultiToken(); - return Context.CurrentToken != null; - } - - //If token is MultiToken then push all its child tokens into _bufferdTokens and return the first token in buffer - private void UnpackMultiToken() { - var mtoken = Context.CurrentToken as MultiToken; - if (mtoken == null) return; - for (int i = mtoken.ChildTokens.Count-1; i >= 0; i--) - Context.BufferedTokens.Push(mtoken.ChildTokens[i]); - Context.CurrentToken = Context.BufferedTokens.Pop(); - } - - private void ComputeCurrentTerminals() { - Context.CurrentTerminals.Clear(); - TerminalList termsForCurrentChar; - if(!Data.TerminalsLookup.TryGetValue(SourceStream.PreviewChar, out termsForCurrentChar)) - termsForCurrentChar = Data.FallbackTerminals; - //if we are recovering, previewing or there's no parser state, then return list as is - if(Context.Status == ParserStatus.Recovering || Context.Status == ParserStatus.Previewing - || Context.CurrentParserState == null || Grammar.FlagIsSet(LanguageFlags.DisableScannerParserLink) - || Context.Mode == ParseMode.VsLineScan) { - Context.CurrentTerminals.AddRange(termsForCurrentChar); - return; - } - // Try filtering terms by checking with parser which terms it expects; - var parserState = Context.CurrentParserState; - foreach(var term in termsForCurrentChar) { - //Note that we check the OutputTerminal with parser, not the term itself; - //in most cases it is the same as term, but not always - if (parserState.ExpectedTerminals.Contains(term.OutputTerminal) || Grammar.NonGrammarTerminals.Contains(term)) - Context.CurrentTerminals.Add(term); - } - - }//method - - private void MatchTerminals() { - Token priorToken = null; - foreach (Terminal term in Context.CurrentTerminals) { - // If we have priorToken from prior term in the list, check if prior term has higher priority than this term; - // if term.Priority is lower then we don't need to check anymore, higher priority (in prior token) wins - // Note that terminals in the list are sorted in descending priority order - if (priorToken != null && priorToken.Terminal.Priority > term.Priority) - return; - //Reset source position and try to match - SourceStream.ResetPreviewPosition(); - var token = term.TryMatch(Context, SourceStream); - if (token == null) continue; - //skip it if it is shorter than previous token - if (priorToken != null && !priorToken.IsError() && (token.Length < priorToken.Length)) - continue; - Context.CurrentToken = token; //now it becomes current token - term.InvokeValidateToken(Context); //validate it - if (Context.CurrentToken != null) - priorToken = Context.CurrentToken; - } - }//method - - #endregion - - #region VS Integration methods - //Use this method for VS integration; VS language package requires scanner that returns tokens one-by-one. - // Start and End positions required by this scanner may be derived from Token : - // start=token.Location.Position; end=start + token.Length; - public Token VsReadToken(ref int state) { - Context.VsLineScanState.Value = state; - if (SourceStream.EOF()) return null; - if (state == 0) - NextToken(); - else { - Terminal term = Data.MultilineTerminals[Context.VsLineScanState.TerminalIndex - 1]; - Context.CurrentToken = term.TryMatch(Context, SourceStream); - } - //set state value from context - state = Context.VsLineScanState.Value; - if (Context.CurrentToken != null && Context.CurrentToken.Terminal == Grammar.Eof) - return null; - return Context.CurrentToken; - } - public void VsSetSource(string text, int offset) { - SourceStream.SetText(text, offset, true); - } - #endregion - - #region Error recovery - private bool Recover() { - SourceStream.PreviewPosition++; - var wsd = Data.Language.GrammarData.WhitespaceAndDelimiters; - while (!SourceStream.EOF()) { - if(wsd.IndexOf(SourceStream.PreviewChar) >= 0) { - SourceStream.MoveLocationToPreviewPosition(); - return true; - } - SourceStream.PreviewPosition++; - } - return false; - } - #endregion - - #region TokenPreview - //Preview mode allows custom code in grammar to help parser decide on appropriate action in case of conflict - // Preview process is simply searching for particular tokens in "preview set", and finding out which of the - // tokens will come first. - // In preview mode, tokens returned by FetchToken are collected in _previewTokens list; after finishing preview - // the scanner "rolls back" to original position - either by directly restoring the position, or moving the preview - // tokens into _bufferedTokens list, so that they will read again by parser in normal mode. - // See c# grammar sample for an example of using preview methods - SourceLocation _previewStartLocation; - - //Switches Scanner into preview mode - public override void BeginPreview() { - base.BeginPreview(); - _previewStartLocation = SourceStream.Location; - } - - //Ends preview mode - public override void EndPreview(bool keepPreviewTokens) { - base.EndPreview(keepPreviewTokens); - if (!keepPreviewTokens) { - Context.SetSourceLocation(_previewStartLocation); - } - } - #endregion - - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Scanner/Scanner.cs b/sources/shaders/Irony/Parsing/Scanner/Scanner.cs deleted file mode 100644 index 2498dd89fd..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/Scanner.cs +++ /dev/null @@ -1,241 +0,0 @@ -#region License - -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System.Collections.Generic; - -namespace Irony.Parsing -{ - /// - /// Scanner base class. The Scanner's function is to transform a stream of characters into aggregates/words or lexemes, - /// like identifier, number, literal, etc. - /// - public abstract class Scanner - { - #region Constants and Fields - - private readonly TokenStack bufferedTokens = new TokenStack(); - - private readonly TokenStack previewTokens = new TokenStack(); - - private IEnumerator filteredTokens; // stream of tokens after filter - - private SourceLocation previewStartLocation; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Scanner() - { - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the location. - /// - /// - /// The location. - /// - public abstract SourceLocation Location { get; set; } - - /// - /// Gets the parser. - /// - public Parser Parser { get; private set; } - - #endregion - - #region Properties - - /// - /// Gets the context. - /// - protected ParsingContext Context - { - get - { - return Parser.Context; - } - } - - /// - /// Gets or sets the grammar. - /// - /// - /// The grammar. - /// - protected Grammar Grammar { get; set; } - - #endregion - - #region Public Methods - - /// - /// Begins the preview. - /// - public virtual void BeginPreview() - { - Context.Status = ParserStatus.Previewing; - previewTokens.Clear(); - previewStartLocation = Location; - } - - // Ends preview mode - - /// - /// Ends the preview. - /// - /// - /// if set to true [keep preview tokens]. - /// - public virtual void EndPreview(bool keepPreviewTokens) - { - if (keepPreviewTokens) - { - // insert previewed tokens into buffered list, so we don't recreate them again - while (previewTokens.Count > 0) - { - bufferedTokens.Push(previewTokens.Pop()); - } - } - else - { - Context.SetSourceLocation(previewStartLocation); - } - - previewTokens.Clear(); - Context.Status = ParserStatus.Parsing; - } - - /// - /// Gets the next token. - /// - /// - /// A Token - /// - public Token GetToken() - { - // get new token from pipeline - if (!filteredTokens.MoveNext()) - { - return null; - } - - var token = filteredTokens.Current; - if (Context.Status == ParserStatus.Previewing) - { - previewTokens.Push(token); - } - else - { - Context.CurrentParseTree.Tokens.Add(token); - } - - return token; - } - - /// - /// Initializes this instance. - /// - /// - /// The Parser. - /// - public void Initialize(Parser parser) - { - Parser = parser; - Grammar = parser.Language.Grammar; - - PrepareInput(); - - // create token streams - var tokenStream = GetUnfilteredTokens(); - - // chain all token filters - Context.TokenFilters.Clear(); - Grammar.CreateTokenFilters(Parser.Language, Context.TokenFilters); - foreach (var filter in Context.TokenFilters) - { - tokenStream = filter.BeginFiltering(Context, tokenStream); - } - - filteredTokens = tokenStream.GetEnumerator(); - } - - /// - /// Resets this instance. - /// - public virtual void Reset() - { - } - - /// - /// Sets the source text for this scanner. - /// - /// The source text. - public abstract void SetSourceText(string sourceText, string sourceFileName); - - #endregion - - #region Methods - - /// - /// Gets the unfiltered tokens. - /// - /// - /// An enumeration on the token - /// - protected IEnumerable GetUnfilteredTokens() - { - // This is iterator method, so it returns immediately when called directly - // returns unfiltered, "raw" token stream - // We don't do "while(!_source.EOF())... because on EOF() we need to continue and produce EOF token - while (true) - { - Context.PreviousToken = Context.CurrentToken; - Context.CurrentToken = null; - - if (bufferedTokens.Count > 0) - { - Context.CurrentToken = bufferedTokens.Pop(); - } - else - { - NextToken(); - } - - Context.OnTokenCreated(); - - // Don't yield break, continue returning EOF - yield return Context.CurrentToken; - } - } - - /// - /// Retrieves the next token. - /// - protected abstract void NextToken(); - - /// - /// Prepares the input. - /// - protected abstract void PrepareInput(); - - #endregion - } -} \ No newline at end of file diff --git a/sources/shaders/Irony/Parsing/Scanner/SourceLocation.cs b/sources/shaders/Irony/Parsing/Scanner/SourceLocation.cs deleted file mode 100644 index 994d716259..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/SourceLocation.cs +++ /dev/null @@ -1,77 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - public struct SourceLocation - { - public string SourceFilename; - public int Position; - public int Line; - public int Column; - public SourceLocation(int position, int line, int column, string sourceFilename = null) - { - SourceFilename = sourceFilename; - Position = position; - Line = line; - Column = column; - } - //Line/col are zero-based internally - public override string ToString() - { - return string.Format(Resources.FmtRowCol, SourceFilename == null ? "" : SourceFilename + " ", Line, Column); - } - //Line and Column displayed to user should be 1-based - public string ToUiString() - { - return string.Format(Resources.FmtRowCol, SourceFilename == null ? "" : SourceFilename + " ", Line + 1, Column + 1); - } - public static int Compare(SourceLocation x, SourceLocation y) - { - if (x.Position < y.Position) return -1; - if (x.Position == y.Position) return 0; - return 1; - } - public static SourceLocation Empty - { - get { return _empty; } - } static SourceLocation _empty = new SourceLocation(); - - public static SourceLocation operator +(SourceLocation x, SourceLocation y) - { - return new SourceLocation(x.Position + y.Position, x.Line + y.Line, x.Column + y.Column); - } - public static SourceLocation operator +(SourceLocation x, int offset) - { - return new SourceLocation(x.Position + offset, x.Line, x.Column + offset); - } - }//SourceLocation - - public struct SourceSpan { - public readonly SourceLocation Location; - public readonly int Length; - public SourceSpan(SourceLocation location, int length) { - Location = location; - Length = length; - } - public int EndPosition { - get { return Location.Position + Length; } - } - } - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Scanner/SourceStream.cs b/sources/shaders/Irony/Parsing/Scanner/SourceStream.cs deleted file mode 100644 index ab68a61012..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/SourceStream.cs +++ /dev/null @@ -1,192 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class SourceStream : ISourceStream { - ScannerData _scannerData; - public const int DefaultTabWidth = 8; - private int _nextNewLinePosition = -1; //private field to cache position of next \n character - - public SourceStream(ScannerData scannerData, int tabWidth) { - _scannerData = scannerData; - TabWidth = tabWidth; - } - - public void SetText(string text, int offset, bool keepLineNumbering) { - Text = text; - //For line-by-line input, automatically increment line# for every new line - var line = keepLineNumbering ? _location.Line + 1 : 0; - Location = new SourceLocation(offset, line, 0); - _nextNewLinePosition = text.IndexOfAny(_scannerData.LineTerminatorsArray, offset); - } - - #region ISourceStream Members - public string Text {get; internal set;} - - public SourceLocation Location { - [System.Diagnostics.DebuggerStepThrough] - get { return _location; } - set { - _location = value; - PreviewPosition = _location.Position; - } - } SourceLocation _location; - - public int PreviewPosition {get; set; } - - public int TabWidth { get; set; } - - public char PreviewChar { - [System.Diagnostics.DebuggerStepThrough] - get { - if (PreviewPosition >= Text.Length) return '\0'; - return Text[PreviewPosition]; - } - } - - public char NextPreviewChar { - [System.Diagnostics.DebuggerStepThrough] - get { - if (PreviewPosition + 1 >= Text.Length) return '\0'; - return Text[PreviewPosition + 1]; - } - } - - public void ResetPreviewPosition() { - PreviewPosition = Location.Position; - } - - public bool MatchSymbol(string symbol, bool ignoreCase) { - try { - var compType = ignoreCase ? StringComparison.InvariantCultureIgnoreCase : StringComparison.InvariantCulture; - int cmp = string.Compare(Text, PreviewPosition, symbol, 0, symbol.Length, compType); - return cmp == 0; - } catch { - //exception may be thrown if Position + symbol.length > text.Length; - // this happens not often, only at the very end of the file, so we don't check this explicitly - //but simply catch the exception and return false. Again, try/catch block has no overhead - // if exception is not thrown. - return false; - } - } - - public Token CreateToken(Terminal terminal) { - var tokenText = GetPreviewText(); - return new Token(terminal, this.Location, tokenText, tokenText); - } - public Token CreateToken(Terminal terminal, object value) { - var tokenText = GetPreviewText(); - return new Token(terminal, this.Location, tokenText, value); - } - public Token CreateErrorToken(string message, params object[] args) { - if (args != null && args.Length > 0) - message = string.Format(message, args); - return new Token(_scannerData.Language.Grammar.SyntaxError, Location, GetPreviewText(), message); - } - - - [System.Diagnostics.DebuggerStepThrough] - public bool EOF() { - return PreviewPosition >= Text.Length; - } - #endregion - - //returns substring from Location.Position till (PreviewPosition - 1) - private string GetPreviewText() { - var until = PreviewPosition; - - if (until > Text.Length) until = Text.Length; - string text = Text.Substring(_location.Position, until - _location.Position); - return text; - } - - public override string ToString() { - string result; - try { - //show just 20 chars from current position - if (Location.Position + 20 < Text.Length) - result = Text.Substring(Location.Position, 20) + Resources.LabelSrcHaveMore;// " ..." - else - result = Text.Substring(Location.Position) + Resources.LabelEofMark; //"(EOF)" - } catch (Exception) { - result = PreviewChar + Resources.LabelSrcHaveMore; - } - return string.Format(Resources.MsgSrcPosToString , result, Location); //"[{0}], at {1}" - } - - #region Location calculations - private static char[] _tab_arr = { '\t' }; - //Calculates Location (row/column/position) to PreviewPosition. - public void MoveLocationToPreviewPosition() { - if (_location.Position == PreviewPosition) return; - if (PreviewPosition > Text.Length) - PreviewPosition = Text.Length; - // First, check if preview position is in the same line; if so, just adjust column and return - // Note that this case is not line start, so we do not need to check tab chars (and adjust column) - if (PreviewPosition <= _nextNewLinePosition || _nextNewLinePosition < 0) { - _location.Column += PreviewPosition - _location.Position; - _location.Position = PreviewPosition; - return; - } - //So new position is on new line (beyond _nextNewLinePosition) - //First count \n chars in the string fragment - int lineStart = _nextNewLinePosition; - int nlCount = 1; //we start after old _nextNewLinePosition, so we count one NewLine char - CountCharsInText(Text, _scannerData.LineTerminatorsArray, lineStart + 1, PreviewPosition - 1, ref nlCount, ref lineStart); - _location.Line += nlCount; - //at this moment lineStart is at start of line where newPosition is located - //Calc # of tab chars from lineStart to newPosition to adjust column# - int tabCount = 0; - int dummy = 0; - if (TabWidth > 1) - CountCharsInText(Text, _tab_arr, lineStart, PreviewPosition - 1, ref tabCount, ref dummy); - - //adjust TokenStart with calculated information - _location.Position = PreviewPosition; - _location.Column = PreviewPosition - lineStart - 1; - if (tabCount > 0) - _location.Column += (TabWidth - 1) * tabCount; // "-1" to count for tab char itself - - //finally cache new line and assign TokenStart - _nextNewLinePosition = Text.IndexOfAny(_scannerData.LineTerminatorsArray, PreviewPosition); - } - - private static void CountCharsInText(string text, char[] chars, int from, int until, ref int count, ref int lastCharOccurrencePosition) { -// if (from >= until) return; - if (from > until) return; - if (until >= text.Length) until = text.Length - 1; - while (true) { - int next = text.IndexOfAny(chars, from, until - from + 1); - if (next < 0) return; - //CR followed by LF is one line terminator, not two; we put it here, just to cover for special case; it wouldn't break - // the case when this function is called to count tabs - bool isCRLF = (text[next] == '\n' && next > 0 && text[next - 1] == '\r'); - if (!isCRLF) - count++; //count - lastCharOccurrencePosition = next; - from = next + 1; - } - - } - #endregion - - - - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Scanner/Token.cs b/sources/shaders/Irony/Parsing/Scanner/Token.cs deleted file mode 100644 index 6d637b68d3..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/Token.cs +++ /dev/null @@ -1,280 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System.Collections.Generic; - -namespace Irony.Parsing -{ - - /// - /// Token flags. - /// - public enum TokenFlags - { - IsIncomplete = 0x01, - } - - /// - /// Token category. - /// - public enum TokenCategory - { - /// - /// Content category. - /// - Content, - - /// - /// newLine, indent, dedent - /// - Outline, - - /// - /// Comment category. - /// - Comment, - - /// - /// Directive category. - /// - Directive, - - /// - /// Error category. - /// - Error, - } - - /// - /// A List of tokens. - /// - public class TokenList : List - { - } - - /// - /// A Stack of tokens. - /// - public class TokenStack : Stack - { - } - - /// - /// Tokens are produced by scanner and fed to parser, optionally passing through Token filters in between. - /// - public class Token - { - private string text; - - /// - /// Initializes a new instance of the class. - /// - /// The term. - /// The location. - /// The text. - /// The value. - public Token(Terminal term, SourceLocation location, string text, object value) - { - SetTerminal(term); - KeyTerm = term as KeyTerm; - Location = location; - Length = text.Length; - this.text = text; - Value = value; - } - - /// - /// Initializes a new instance of the class. - /// - /// The term. - /// The location. - /// The length. - /// The source. - /// The value. - public Token(Terminal term, SourceLocation location, int length, string source, object value) - { - SetTerminal(term); - KeyTerm = term as KeyTerm; - Location = location; - Length = length; - SourceCode = source; - Value = value; - } - - /// - /// Location in the source code. - /// - public readonly SourceLocation Location; - - /// - /// Gets the terminal. - /// - public Terminal Terminal { get; private set; } - - /// - /// Gets the Key terminal if any. - /// - public KeyTerm KeyTerm { get; private set; } - - /// - /// Gets the length. - /// - public int Length { get; private set; } - - /// - /// Gets the source code. - /// - /// - /// The source code. - /// - public string SourceCode { get; private set; } - - /// - /// Gets the text associated with this token. - /// - public string Text - { - get - { - if (text == null) - { - text = SourceCode.Substring(Location.Position, Length); - } - return text; - } - } - - /// - /// Get the Value associated with this token. - /// - public object Value; - - /// - /// Gets the value as a string. - /// - public string ValueString - { - get - { - return Value == null ? string.Empty : Value.ToString(); - } - } - - /// - /// Get the flags - /// - public TokenFlags Flags; - - /// - /// Gets the Editor info. - /// - public TokenEditorInfo EditorInfo; - - /// - /// Gets the category. - /// - public TokenCategory Category - { - get { return Terminal.Category; } - } - - /// - /// Gets the matching opening/closing brace - /// - public Token OtherBrace - { - get; - private set; - } - - /// - /// Scanner state after producing token - /// - public short ScannerState; - - /// - /// Sets the terminal. - /// - /// The terminal. - public void SetTerminal(Terminal terminal) - { - Terminal = terminal; - - // Set to term's EditorInfo by default - EditorInfo = Terminal.EditorInfo; - } - - /// - /// Determines whether the specified flag is set. - /// - /// The flag. - /// - /// true if the specified flag is set; otherwise, false. - /// - public bool IsSet(TokenFlags flag) - { - return (Flags & flag) != 0; - } - - - /// - /// Determines whether this instance is error. - /// - /// - /// true if this instance is error; otherwise, false. - /// - public bool IsError() - { - return Category == TokenCategory.Error; - } - - /// - /// Links the matching braces. - /// - /// The opening brace. - /// The closing brace. - public static void LinkMatchingBraces(Token openingBrace, Token closingBrace) - { - openingBrace.OtherBrace = closingBrace; - closingBrace.OtherBrace = openingBrace; - } - - /// - [System.Diagnostics.DebuggerStepThrough] - public override string ToString() - { - return Terminal.TokenToString(this); - } - } - - /// - /// Some terminals may need to return a bunch of tokens in one call to TryMatch; MultiToken is a container for these tokens - /// - public class MultiToken : Token - { - /// - /// List of child tokens - /// - public TokenList ChildTokens; - - /// - /// Initializes a new instance of the class. - /// - /// The term. - /// The location. - /// The child tokens. - public MultiToken(Terminal term, SourceLocation location, TokenList childTokens) : base(term, location, string.Empty, null) - { - ChildTokens = childTokens; - } - } -} diff --git a/sources/shaders/Irony/Parsing/Scanner/TokenEditorInfo.cs b/sources/shaders/Irony/Parsing/Scanner/TokenEditorInfo.cs deleted file mode 100644 index 0f0b6f2490..0000000000 --- a/sources/shaders/Irony/Parsing/Scanner/TokenEditorInfo.cs +++ /dev/null @@ -1,108 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - // Helper classes for information used by syntax highlighters and editors - // TokenColor, TokenTriggers and TokenType are copied from the Visual studio integration assemblies. - // Each terminal/token would have its TokenEditorInfo that can be used either by VS integration package - // or any editor for syntax highligting. - - public class TokenEditorInfo { - public readonly TokenType Type; - public readonly TokenColor Color; - public readonly TokenTriggers Triggers; - public string ToolTip; - public int UnderlineType; - public TokenEditorInfo(TokenType type, TokenColor color, TokenTriggers triggers) { - Type = type; - Color = color; - Triggers = triggers; - } - - }//class - - public enum TokenColor { - Text = 0, - Keyword = 1, - Comment = 2, - Identifier = 3, - String = 4, - Number = 5, - } - - // (Comments are coming from visual studio integration package) - // Specifies a set of triggers that can be fired from an Microsoft.VisualStudio.Package.IScanner - // language parser. - [Flags] - public enum TokenTriggers { - // Summary: - // Used when no triggers are set. This is the default. - None = 0, - // - // Summary: - // A character that indicates that the start of a member selection has been - // parsed. In C#, this could be a period following a class name. In XML, this - // could be a < (the member select is a list of possible tags). - MemberSelect = 1, - // - // Summary: - // The opening or closing part of a language pair has been parsed. For example, - // in C#, a { or } has been parsed. In XML, a < or > has been parsed. - MatchBraces = 2, - // - // Summary: - // A character that marks the start of a parameter list has been parsed. For - // example, in C#, this could be an open parenthesis, "(". - ParameterStart = 16, - // - // Summary: - // A character that separates parameters in a list has been parsed. For example, - // in C#, this could be a comma, ",". - ParameterNext = 32, - // - // Summary: - // A character that marks the end of a parameter list has been parsed. For example, - // in C#, this could be a close parenthesis, ")". - ParameterEnd = 64, - // - // Summary: - // A parameter in a method's parameter list has been parsed. - Parameter = 128, - // - // Summary: - // This is a mask for the flags used to govern the IntelliSense Method Tip operation. - // This mask is used to isolate the values Microsoft.VisualStudio.Package.TokenTriggers.Parameter, - // Microsoft.VisualStudio.Package.TokenTriggers.ParameterStart, Microsoft.VisualStudio.Package.TokenTriggers.ParameterNext, - // and Microsoft.VisualStudio.Package.TokenTriggers.ParameterEnd. - MethodTip = 240, - } - - public enum TokenType { - Unknown = 0, - Text = 1, - Keyword = 2, - Identifier = 3, - String = 4, - Literal = 5, - Operator = 6, - Delimiter = 7, - WhiteSpace = 8, - LineComment = 9, - Comment = 10, - } - -} diff --git a/sources/shaders/Irony/Parsing/SymbolTable.cs b/sources/shaders/Irony/Parsing/SymbolTable.cs deleted file mode 100644 index be212e781c..0000000000 --- a/sources/shaders/Irony/Parsing/SymbolTable.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; - -namespace Irony.Parsing { - //First sketch of Symbol object and Symbol table - public class Symbol { - public readonly string Text; - //used for symbol comparison in case-insensitive environments - public readonly Symbol LowerSymbol; - private int _hashCode; - - internal Symbol(string text, Symbol lowerSymbol) { - Text = text; - LowerSymbol = lowerSymbol?? this; //lowerSymbol == null means "text is all lowercase, so use 'this' as LowerSymbol" - _hashCode = Text.GetHashCode(); - } - - public override int GetHashCode() { - return _hashCode; - } - public override string ToString() { - return Text; - } - - public static bool AreEqual(Symbol first, Symbol second, bool caseSensitive) { - return (caseSensitive ? first == second : first.LowerSymbol == second.LowerSymbol); - } - - }//Symbol class - - public class SymbolSet : HashSet { } - public class SymbolList : List { } - - internal class SymbolDictionary : Dictionary { - internal SymbolDictionary() : base(1000) { } - } - - public class SymbolTable { - SymbolDictionary _dictionary = new SymbolDictionary(); - object _lockObject = new object(); - - public static SymbolTable Symbols = new SymbolTable(); - - private SymbolTable() { } - - public int Count { - get { return _dictionary.Count; } - } - - public Symbol this[string text] { - get { - lock(_lockObject) { - return _dictionary[text]; - } - } - } - - public Symbol FindSymbol(string text) { - Symbol symbol; - lock(_lockObject) { - _dictionary.TryGetValue(text, out symbol); - } - return symbol; - } - - public Symbol TextToSymbol(string text) { - Symbol symbol, lowerSymbol; - lock(_lockObject) { - if(_dictionary.TryGetValue(text, out symbol)) - return symbol; - //Create symbol; first find/create lower symbol - var lowerText = text.ToLowerInvariant(); - if(!_dictionary.TryGetValue(lowerText, out lowerSymbol)) - lowerSymbol = NewSymbol(lowerText, null); - //if the text is all lower, return lowerSymbol as result - if(lowerText == text) - return lowerSymbol; - //otherwise create new symbol - return NewSymbol(text, lowerSymbol); - } - }//method - - private Symbol NewSymbol(string text, Symbol lowerSymbol) { - var result = new Symbol(text, lowerSymbol); - _dictionary.Add(text, result); - return result; - } - - }//class - - public class CaseSensitiveSymbolComparer : IComparer { - public int Compare(Symbol x, Symbol y) { - return x == y ? 0 : 1; - } - } - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/CommentTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/CommentTerminal.cs deleted file mode 100644 index 7a618c226f..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/CommentTerminal.cs +++ /dev/null @@ -1,119 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class CommentTerminal : Terminal { - public CommentTerminal(string name, string startSymbol, params string[] endSymbols) : base(name, TokenCategory.Comment) { - this.StartSymbol = startSymbol; - this.EndSymbols = new StringList(); - EndSymbols.AddRange(endSymbols); - Priority = Terminal.HighestPriority; //assign max priority - } - - public string StartSymbol; - public StringList EndSymbols; - private char[] _endSymbolsFirsts; - private bool _isLineComment; //true if NewLine is one of EndSymbols; if yes, EOF is also considered a valid end symbol - - - #region overrides - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - //_endSymbolsFirsts char array is used for fast search for end symbols using String's method IndexOfAny(...) - _endSymbolsFirsts = new char[EndSymbols.Count]; - for (int i = 0; i < EndSymbols.Count; i++) { - string sym = EndSymbols[i]; - _endSymbolsFirsts[i] = sym[0]; - _isLineComment |= sym.Contains("\n"); - if (!_isLineComment) - SetFlag(TermFlags.IsMultiline); - } - if (this.EditorInfo == null) { - TokenType ttype = _isLineComment ? TokenType.LineComment : TokenType.Comment; - this.EditorInfo = new TokenEditorInfo(ttype, TokenColor.Comment, TokenTriggers.None); - } - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - Token result; - if (context.VsLineScanState.Value != 0) { - // we are continuing in line mode - restore internal env (none in this case) - context.VsLineScanState.Value = 0; - } else { - //we are starting from scratch - if (!BeginMatch(context, source)) return null; - } - result = CompleteMatch(context, source); - if (result != null) return result; - //if it is LineComment, it is ok to hit EOF without final line-break; just return all until end. - if (_isLineComment) - return source.CreateToken(this.OutputTerminal); - if (context.Mode == ParseMode.VsLineScan) - return CreateIncompleteToken(context, source); - return source.CreateErrorToken(Resources.ErrUnclosedComment); - } - - private Token CreateIncompleteToken(ParsingContext context, ISourceStream source) { - source.PreviewPosition = source.Text.Length; - Token result = source.CreateToken(this.OutputTerminal); - result.Flags |= TokenFlags.IsIncomplete; - context.VsLineScanState.TerminalIndex = this.MultilineIndex; - return result; - } - - private bool BeginMatch(ParsingContext context, ISourceStream source) { - //Check starting symbol - if (!source.MatchSymbol(StartSymbol, !Grammar.CaseSensitive)) return false; - source.PreviewPosition += StartSymbol.Length; - return true; - } - private Token CompleteMatch(ParsingContext context, ISourceStream source) { - //Find end symbol - while (!source.EOF()) { - int firstCharPos; - if (EndSymbols.Count == 1) - firstCharPos = source.Text.IndexOf(EndSymbols[0], source.PreviewPosition); - else - firstCharPos = source.Text.IndexOfAny(_endSymbolsFirsts, source.PreviewPosition); - if (firstCharPos < 0) { - source.PreviewPosition = source.Text.Length; - return null; //indicating error - } - //We found a character that might start an end symbol; let's see if it is true. - source.PreviewPosition = firstCharPos; - foreach (string endSymbol in EndSymbols) { - if (source.MatchSymbol(endSymbol, !Grammar.CaseSensitive)) { - //We found end symbol; eat end symbol only if it is not line comment. - // For line comment, leave LF symbol there, it might be important to have a separate LF token - if (!_isLineComment) - source.PreviewPosition += endSymbol.Length; - return source.CreateToken(this.OutputTerminal); - }//if - }//foreach endSymbol - source.PreviewPosition++; //move to the next char and try again - }//while - return null; //might happen if we found a start char of end symbol, but not the full endSymbol - }//method - - public override IList GetFirsts() { - return new string[] { StartSymbol }; - } - #endregion - }//CommentTerminal class - - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/CompoundTerminalBase.cs b/sources/shaders/Irony/Parsing/Terminals/CompoundTerminalBase.cs deleted file mode 100644 index 92da571647..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/CompoundTerminalBase.cs +++ /dev/null @@ -1,255 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - #region About compound terminals - /* - As it turns out, many terminal types in real-world languages have 3-part structure: prefix-body-suffix - The body is essentially the terminal "value", while prefix and suffix are used to specify additional - information (options), while not being a part of the terminal itself. - For example: - 1. c# numbers, may have 0x prefix for hex representation, and suffixes specifying - the exact data type of the literal (f, l, m, etc) - 2. c# string may have "@" prefix which disables escaping inside the string - 3. c# identifiers may have "@" prefix and escape sequences inside - just like strings - 4. Python string may have "u" and "r" prefixes, "r" working the same way as @ in c# strings - 5. VB string literals may have "c" suffix identifying that the literal is a character, not a string - 6. VB number literals and identifiers may have suffixes identifying data type - - So it seems like all these terminals have the format "prefix-body-suffix". - The CompoundTerminalBase base class implements base functionality supporting this multi-part structure. - The IdentifierTerminal, NumberLiteral and StringLiteral classes inherit from this base class. - The methods in TerminalFactory static class demonstrate that with this architecture we can define the whole - variety of terminals for c#, Python and VB.NET languages. -*/ - #endregion - - - public class EscapeTable : Dictionary { } - - public abstract class CompoundTerminalBase : Terminal { - - #region Nested classes - protected class ScanFlagTable : Dictionary { } - protected class TypeCodeTable : Dictionary { } - - public class CompoundTokenDetails { - public string Prefix; - public string Body; - public string Suffix; - public string Sign; - public short Flags; //need to be short, because we need to save it in Scanner state for Vs integration - public string Error; - public TypeCode[] TypeCodes; - public string ExponentSymbol; //exponent symbol for Number literal - public string StartSymbol; //string start and end symbols - public string EndSymbol; - public object Value; - //partial token info, used by VS integration - public bool PartialOk; - public bool IsPartial; - public bool PartialContinues; - public byte SubTypeIndex; //used for string literal kind - //Flags helper method - public bool IsSet(short flag) { - return (Flags & flag) != 0; - } - public string Text { get { return Prefix + Body + Suffix; } } - } - - #endregion - - #region constructors and initialization - public CompoundTerminalBase(string name) : this(name, TermFlags.None) { } - public CompoundTerminalBase(string name, TermFlags flags) : base(name) { - SetFlag(flags); - Escapes = GetDefaultEscapes(); - } - - protected void AddPrefixFlag(string prefix, short flags) { - PrefixFlags.Add(prefix, flags); - Prefixes.Add(prefix); - } - public void AddSuffix(string suffix, params TypeCode[] typeCodes) { - SuffixTypeCodes.Add(suffix, typeCodes); - Suffixes.Add(suffix); - } - #endregion - - #region public Properties/Fields - public Char EscapeChar = '\\'; - public EscapeTable Escapes = new EscapeTable(); - #endregion - - - #region private fields - protected readonly ScanFlagTable PrefixFlags = new ScanFlagTable(); - protected readonly TypeCodeTable SuffixTypeCodes = new TypeCodeTable(); - protected StringList Prefixes = new StringList(); - protected StringList Suffixes = new StringList(); - protected bool CaseSensitive; //case sensitivity for prefixes and suffixes - string _prefixesFirsts; //first chars of all prefixes, for fast prefix detection - string _suffixesFirsts; //first chars of all suffixes, for fast suffix detection - #endregion - - - #region overrides: Init, TryMatch - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - //collect all suffixes, prefixes in lists and create strings of first chars for both - Prefixes.Sort(StringList.LongerFirst); - _prefixesFirsts = string.Empty; - foreach (string pfx in Prefixes) - _prefixesFirsts += pfx[0]; - - Suffixes.Sort(StringList.LongerFirst); - _suffixesFirsts = string.Empty; - foreach (string sfx in Suffixes) - _suffixesFirsts += sfx[0]; //we don't care if there are repetitions - if (!CaseSensitive) { - _prefixesFirsts = _prefixesFirsts.ToLower() + _prefixesFirsts.ToUpper(); - _suffixesFirsts = _suffixesFirsts.ToLower() + _suffixesFirsts.ToUpper(); - } - }//method - - public override IList GetFirsts() { - return Prefixes; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - Token token; - //Try quick parse first, but only if we're not continuing - if (context.VsLineScanState.Value == 0) { - token = QuickParse(context, source); - if (token != null) return token; - source.PreviewPosition = source.Location.Position; //revert the position - } - - CompoundTokenDetails details = new CompoundTokenDetails(); - InitDetails(context, details); - - if (context.VsLineScanState.Value == 0) - ReadPrefix(source, details); - if (!ReadBody(source, details)) - return null; - if (details.Error != null) - return source.CreateErrorToken(details.Error); - if (details.IsPartial) { - details.Value = details.Body; - } else { - ReadSuffix(source, details); - - if(!ConvertValue(details)) { - if (string.IsNullOrEmpty(details.Error)) - details.Error = Resources.ErrInvNumber; - return source.CreateErrorToken(details.Error); // "Failed to convert the value: {0}" - } - } - token = CreateToken(context, source, details); - - if (details.IsPartial) { - //Save terminal state so we can continue - context.VsLineScanState.TokenSubType = (byte)details.SubTypeIndex; - context.VsLineScanState.TerminalFlags = (short)details.Flags; - context.VsLineScanState.TerminalIndex = this.MultilineIndex; - } else - context.VsLineScanState.Value = 0; - return token; - } - - protected virtual Token CreateToken(ParsingContext context, ISourceStream source, CompoundTokenDetails details) { - var token = source.CreateToken(this.OutputTerminal, details.Value); - token.Details = details; - if (details.IsPartial) - token.Flags |= TokenFlags.IsIncomplete; - return token; - } - - protected virtual void InitDetails(ParsingContext context, CompoundTokenDetails details) { - details.PartialOk = (context.Mode == ParseMode.VsLineScan); - details.PartialContinues = (context.VsLineScanState.Value != 0); - } - - protected virtual Token QuickParse(ParsingContext context, ISourceStream source) { - return null; - } - - protected virtual void ReadPrefix(ISourceStream source, CompoundTokenDetails details) { - if (_prefixesFirsts.IndexOf(source.PreviewChar) < 0) - return; - foreach (string pfx in Prefixes) { - if (!source.MatchSymbol(pfx, !CaseSensitive)) continue; - //We found prefix - details.Prefix = pfx; - source.PreviewPosition += pfx.Length; - //Set flag from prefix - short pfxFlags; - if (!string.IsNullOrEmpty(details.Prefix) && PrefixFlags.TryGetValue(details.Prefix, out pfxFlags)) - details.Flags |= (short) pfxFlags; - return; - }//foreach - }//method - - protected virtual bool ReadBody(ISourceStream source, CompoundTokenDetails details) { - return false; - } - - protected virtual void ReadSuffix(ISourceStream source, CompoundTokenDetails details) { - if (_suffixesFirsts.IndexOf(source.PreviewChar) < 0) return; - foreach (string sfx in Suffixes) { - if (!source.MatchSymbol(sfx, !CaseSensitive)) continue; - //We found suffix - details.Suffix = sfx; - source.PreviewPosition += sfx.Length; - //Set TypeCode from suffix - TypeCode[] codes; - if (!string.IsNullOrEmpty(details.Suffix) && SuffixTypeCodes.TryGetValue(details.Suffix, out codes)) - details.TypeCodes = codes; - return; - }//foreach - }//method - - protected virtual bool ConvertValue(CompoundTokenDetails details) { - details.Value = details.Body; - return false; - } - - - #endregion - - #region utils: GetDefaultEscapes - public static EscapeTable GetDefaultEscapes() { - EscapeTable escapes = new EscapeTable(); - escapes.Add('a', "\u0007"); - escapes.Add('b', "\b"); - escapes.Add('t', "\t"); - escapes.Add('n', "\n"); - escapes.Add('v', "\v"); - escapes.Add('f', "\f"); - escapes.Add('r', "\r"); - escapes.Add('"', "\""); - escapes.Add('\'', "\'"); - escapes.Add('\\', "\\"); - escapes.Add(' ', " "); - escapes.Add('\n', "\n"); //this is a special escape of the linebreak itself, - // when string ends with "\" char and continues on the next line - return escapes; - } - #endregion - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/ConstantTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/ConstantTerminal.cs deleted file mode 100644 index 7917084f65..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/ConstantTerminal.cs +++ /dev/null @@ -1,61 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - //This terminal allows to declare a set of constants in the input language - // It should be used when constant symbols do not look like normal identifiers; e.g. in Scheme, #t, #f are true/false - // constants, and they don't fit into Scheme identifier pattern. - public class ConstantsTable : Dictionary { } - public class ConstantTerminal : Terminal { - public readonly ConstantsTable Constants = new ConstantsTable(); - public ConstantTerminal(string name, Type nodeType) : base(name) { - base.SetFlag(TermFlags.IsConstant); - AstNodeType = nodeType; - } - - public void Add(string lexeme, object value) { - this.Constants[lexeme] = value; - } - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - if (this.EditorInfo == null) - this.EditorInfo = new TokenEditorInfo(TokenType.Unknown, TokenColor.Text, TokenTriggers.None); - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - string text = source.Text; - foreach (var entry in Constants) { - var constant = entry.Key; - if (source.PreviewPosition + constant.Length > text.Length) continue; - if (source.MatchSymbol(constant, !Grammar.CaseSensitive)) { - source.PreviewPosition += constant.Length; - return source.CreateToken(this.OutputTerminal, entry.Value); - } - } - return null; - } - public override IList GetFirsts() { - string[] array = new string[Constants.Count]; - Constants.Keys.CopyTo(array, 0); - return array; - } - - }//class - - - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/CustomTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/CustomTerminal.cs deleted file mode 100644 index 7b21a103bc..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/CustomTerminal.cs +++ /dev/null @@ -1,45 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - //Terminal based on custom method; allows creating custom match without creating new class derived from Terminal - public delegate Token MatchHandler(Terminal terminal, ParsingContext context, ISourceStream source); - public class CustomTerminal : Terminal { - public CustomTerminal(string name, MatchHandler handler, params string[] prefixes) : base(name) { - _handler = handler; - if (prefixes != null) - Prefixes.AddRange(prefixes); - this.EditorInfo = new TokenEditorInfo(TokenType.Unknown, TokenColor.Text, TokenTriggers.None); - } - - public readonly StringList Prefixes = new StringList(); - - public MatchHandler Handler { - [System.Diagnostics.DebuggerStepThrough] - get {return _handler;} - } MatchHandler _handler; - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - return _handler(this, context, source); - } - [System.Diagnostics.DebuggerStepThrough] - public override IList GetFirsts() { - return Prefixes; - } - }//class - - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/DataLiteralBase.cs b/sources/shaders/Irony/Parsing/Terminals/DataLiteralBase.cs deleted file mode 100644 index f90b579ab6..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/DataLiteralBase.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; - -namespace Irony.Parsing { - - //DataLiteralBase is a base class for a set of specialized terminals with a primary purpose of building data readers - // DsvLiteral is used for reading delimiter-separated values (DSV), comma-separated format is a specific case of DSV - // FixedLengthLiteral may be used to read values of fixed length - public class DataLiteralBase : Terminal { - public TypeCode DataType; - //For date format strings see MSDN help for "Custom format strings", available through help for DateTime.ParseExact(...) method - public string DateTimeFormat = "d"; //standard format, identifies MM/dd/yyyy for invariant culture. - public int IntRadix = 10; //Radix (base) for numeric numbers - - public DataLiteralBase(string name, TypeCode dataType) : base(name) { - DataType = dataType; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - try { - var textValue = ReadBody(context, source); - if (textValue == null) return null; - var value = ConvertValue(context, textValue); - return source.CreateToken(this.OutputTerminal, value); - } catch(Exception ex) { - //we throw exception in DsvLiteral when we cannot find a closing quote for quoted value - return source.CreateErrorToken(ex.Message); - } - }//method - - - protected virtual string ReadBody(ParsingContext context, ISourceStream source) { - return null; - } - - protected virtual object ConvertValue(ParsingContext context, string textValue) { - switch(DataType) { - case TypeCode.String: return textValue; - case TypeCode.DateTime: return DateTime.ParseExact(textValue, DateTimeFormat, context.Culture); - case TypeCode.Single: - case TypeCode.Double: - var dValue = Convert.ToDouble(textValue, context.Culture); - if (DataType == TypeCode.Double) return dValue; - return Convert.ChangeType(dValue, DataType, context.Culture); - - default: //integer types - var iValue = (IntRadix == 10)? Convert.ToInt64(textValue, context.Culture) : Convert.ToInt64(textValue, IntRadix); - if (DataType == TypeCode.Int64) return iValue; - return Convert.ChangeType(iValue, DataType, context.Culture); - } - }//method - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/DsvLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/DsvLiteral.cs deleted file mode 100644 index 872f5dfcfa..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/DsvLiteral.cs +++ /dev/null @@ -1,105 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - //A terminal for DSV-formatted files (Delimiter-Separated Values), a generalization of CSV (comma-separated values) format. - // See http://en.wikipedia.org/wiki/Delimiter-separated_values - // For CSV format, there's a recommendation RFC4180 (http://tools.ietf.org/html/rfc4180) - // It might seem that this terminal is not that useful and it is easy enough to create a custom CSV reader for a particular data format - // format. However, if you consider all escaping and double-quote enclosing rules, then a custom reader solution would not seem so trivial. - // So DsvLiteral can simplify this task. - public class DsvLiteral : DataLiteralBase { - public string Terminator = ","; - public bool ConsumeTerminator = true; //if true, the source pointer moves after the separator - private char[] _terminators; - - //For last value on the line specify terminator = null; the DsvLiteral will then look for NewLine as terminator - public DsvLiteral(string name, TypeCode dataType, string terminator) : this(name, dataType) { - Terminator = terminator; - } - public DsvLiteral(string name, TypeCode dataType) : base(name, dataType) { } - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - if (Terminator == null) - _terminators = new char[] { '\n', '\r'}; - else - _terminators = new char[] { Terminator[0]}; - } - - protected override string ReadBody(ParsingContext context, ISourceStream source) { - string body; - if (source.PreviewChar == '"') - body = ReadQuotedBody(context, source); - else - body = ReadNotQuotedBody(context, source); - if (ConsumeTerminator && Terminator != null) - MoveSourcePositionAfterTerminator(source); - return body; - } - - private string ReadQuotedBody(ParsingContext context, ISourceStream source) { - const char dQuoute = '"'; - StringBuilder sb = null; - var from = source.Location.Position + 1; //skip initial double quote - while(true) { - var until = source.Text.IndexOf(dQuoute, from); - if (until < 0) - throw new Exception(Resources.ErrDsvNoClosingQuote); // "Could not find a closing quote for quoted value." - source.PreviewPosition = until; //now points at double-quote - var piece = source.Text.Substring(from, until - from); - source.PreviewPosition++; //move after double quote - if (source.PreviewChar != dQuoute && sb == null) - return piece; //quick path - if sb (string builder) was not created yet, we are looking at the very first segment; - // and if we found a standalone dquote, then we are done - the "piece" is the result. - if (sb == null) - sb = new StringBuilder(100); - sb.Append(piece); - if (source.PreviewChar != dQuoute) - return sb.ToString(); - //we have doubled double-quote; add a single double-quoute char to the result and move over both symbols - sb.Append(dQuoute); - from = source.PreviewPosition + 1; - } - } - - private string ReadNotQuotedBody(ParsingContext context, ISourceStream source) { - var startPos = source.Location.Position; - var sepPos = source.Text.IndexOfAny(_terminators, startPos); - if (sepPos < 0) - sepPos = source.Text.Length; - source.PreviewPosition = sepPos; - var valueText = source.Text.Substring(startPos, sepPos - startPos); - return valueText; - } - - private void MoveSourcePositionAfterTerminator(ISourceStream source) { - while(!source.EOF()) { - while(source.PreviewChar != Terminator[0]) - source.PreviewPosition++; - if(source.MatchSymbol(Terminator, !Grammar.CaseSensitive)) { - source.PreviewPosition += Terminator.Length; - return; - }//if - }//while - }//method - - }//class - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/FixedLengthLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/FixedLengthLiteral.cs deleted file mode 100644 index 48bf793f7b..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/FixedLengthLiteral.cs +++ /dev/null @@ -1,39 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Globalization; - -namespace Irony.Parsing { - - //A terminal for representing fixed-length lexemes coming up sometimes in programming language - // (in Fortran for ex, every line starts with 5-char label, followed by a single continuation char) - // It may be also used to create grammar/parser for reading data files with fixed length fields - public class FixedLengthLiteral : DataLiteralBase { - public int Length; - - public FixedLengthLiteral(string name, int length, TypeCode dataType) : base(name, dataType) { - Length = length; - } - - protected override string ReadBody(ParsingContext context, ISourceStream source) { - source.PreviewPosition = source.Location.Position + Length; - var body = source.Text.Substring(source.Location.Position, Length); - return body; - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/FreeTextLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/FreeTextLiteral.cs deleted file mode 100644 index e55248014f..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/FreeTextLiteral.cs +++ /dev/null @@ -1,111 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - // Sometimes language definition includes tokens that have no specific format, but are just "all text until some terminator character(s)"; - // FreeTextTerminal allows easy implementation of such language element. - - [Flags] - public enum FreeTextOptions { - None = 0x0, - ConsumeTerminator = 0x01, //move source pointer beyond terminator (so token "consumes" it from input), but don't include it in token text - IncludeTerminator = 0x02, // include terminator into token text/value - AllowEof = 0x04, // treat EOF as legitimate terminator - } - - public class FreeTextLiteral : Terminal { - public StringSet Terminators = new StringSet(); - public StringSet Firsts = new StringSet(); - public StringDictionary Escapes = new StringDictionary(); - public FreeTextOptions FreeTextOptions; - private char[] _stopChars; - - public FreeTextLiteral(string name, params string[] terminators) : this(name, FreeTextOptions.None, terminators) { } - public FreeTextLiteral(string name, FreeTextOptions freeTextOptions, params string[] terminators) : base(name) { - FreeTextOptions = freeTextOptions; - Terminators.UnionWith(terminators); - base.SetFlag(TermFlags.IsLiteral); - }//constructor - - public override IList GetFirsts() { - var result = new StringList(); - result.AddRange(Firsts); - return result; - } - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - var stopChars = new CharHashSet(); - foreach (var key in Escapes.Keys) - stopChars.Add(key[0]); - foreach (var t in Terminators) - stopChars.Add(t[0]); - _stopChars = stopChars.ToArray(); - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - string tokenText = string.Empty; - while (true) { - //Find next position - var newPos = source.Text.IndexOfAny(_stopChars, source.PreviewPosition); - if(newPos == -1) { - if(IsSet(FreeTextOptions.AllowEof)) { - source.PreviewPosition = source.Text.Length; - return source.CreateToken(this.OutputTerminal); - } else - return null; - } - tokenText += source.Text.Substring(source.PreviewPosition, newPos - source.PreviewPosition); - source.PreviewPosition = newPos; - //if it is escape, add escaped text and continue search - if (CheckEscape(source, ref tokenText)) - continue; - //check terminators - if (CheckTerminators(source, ref tokenText)) - break; //from while (true) - } - return source.CreateToken(this.OutputTerminal, tokenText); - } - - private bool CheckEscape(ISourceStream source, ref string tokenText) { - foreach (var dictEntry in Escapes) { - if (source.MatchSymbol(dictEntry.Key, !Grammar.CaseSensitive)) { - source.PreviewPosition += dictEntry.Key.Length; - tokenText += dictEntry.Value; - return true; - } - }//foreach - return false; - } - - private bool CheckTerminators(ISourceStream source, ref string tokenText) { - foreach(var term in Terminators) - if(source.MatchSymbol(term, !Grammar.CaseSensitive)) { - if (IsSet(FreeTextOptions.IncludeTerminator)) - tokenText += term; - if (IsSet(FreeTextOptions.ConsumeTerminator | FreeTextOptions.IncludeTerminator)) - source.PreviewPosition += term.Length; - return true; - } - return false; - } - - private bool IsSet(FreeTextOptions option) { - return (this.FreeTextOptions & option) != 0; - } - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/IdentifierTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/IdentifierTerminal.cs deleted file mode 100644 index b10b335606..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/IdentifierTerminal.cs +++ /dev/null @@ -1,281 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Globalization; - -namespace Irony.Parsing { - #region notes - //Identifier terminal. Matches alpha-numeric sequences that usually represent identifiers and keywords. - // c#: @ prefix signals to not interpret as a keyword; allows \u escapes - // - - #endregion - - [Flags] - public enum IdOptions : short { - None = 0, - AllowsEscapes = 0x01, - CanStartWithEscape = 0x03, //bit 2 with bit 1 together - - IsNotKeyword = 0x10, - NameIncludesPrefix = 0x20, - } - - public enum CaseRestriction { - None, - FirstUpper, - FirstLower, - AllUpper, - AllLower - } - - public class UnicodeCategoryList : List { } - - public class IdentifierTerminal : CompoundTerminalBase { - - //Id flags for internal use - internal enum IdFlagsInternal : short { - HasEscapes = 0x100, - } - - - //Note that extraChars, extraFirstChars are used to form AllFirstChars and AllChars fields, which in turn - // are used in QuickParse. Only if QuickParse fails, the process switches to full version with checking every - // char's category - #region constructors and initialization - public IdentifierTerminal(string name) : this(name, IdOptions.None) { - } - public IdentifierTerminal(string name, IdOptions options) : this(name, "_", "_") { - Options = options; - } - public IdentifierTerminal(string name, string extraChars, string extraFirstChars): base(name) { - AllFirstChars = Strings.AllLatinLetters + extraFirstChars; - AllChars = Strings.AllLatinLetters + Strings.DecimalDigits + extraChars; - } - - public void AddPrefix(string prefix, IdOptions options) { - base.AddPrefixFlag(prefix, (short)options); - } - #endregion - - #region properties: AllChars, AllFirstChars - //Used in QuickParse only! - public string AllChars; - public string AllFirstChars; - public TokenEditorInfo KeywordEditorInfo = new TokenEditorInfo(TokenType.Keyword, TokenColor.Keyword, TokenTriggers.None); - public IdOptions Options; //flags for the case when there are no prefixes - public CaseRestriction CaseRestriction; - - public readonly UnicodeCategoryList StartCharCategories = new UnicodeCategoryList(); //categories of first char - public readonly UnicodeCategoryList CharCategories = new UnicodeCategoryList(); //categories of all other chars - public readonly UnicodeCategoryList CharsToRemoveCategories = new UnicodeCategoryList(); //categories of chars to remove from final id, usually formatting category - #endregion - - #region overrides - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - AllChars = AllChars?? String.Empty; - AllFirstChars = AllFirstChars ?? string.Empty; - //Adjust case restriction. We adjust only first chars; if first char is ok, we will scan the rest without restriction - // and then check casing for entire identifier - switch(CaseRestriction) { - case CaseRestriction.AllLower: - case CaseRestriction.FirstLower: - AllFirstChars = AllFirstChars.ToLower(); - break; - case CaseRestriction.AllUpper: - case CaseRestriction.FirstUpper: - AllFirstChars = AllFirstChars.ToUpper(); - break; - } - //if there are "first" chars defined by categories, add the terminal to FallbackTerminals - if (this.StartCharCategories.Count > 0) - Grammar.FallbackTerminals.Add(this); - if (this.EditorInfo == null) - this.EditorInfo = new TokenEditorInfo(TokenType.Identifier, TokenColor.Identifier, TokenTriggers.None); - if (this.AstNodeType == null && this.AstNodeCreator == null && grammarData.Grammar.FlagIsSet(LanguageFlags.CreateAst)) - this.AstNodeType = typeof(Irony.Interpreter.Ast.IdentifierNode); - } - - //TODO: put into account non-Ascii aplhabets specified by means of Unicode categories! - public override IList GetFirsts() { - StringList list = new StringList(); - list.AddRange(Prefixes); - if (string.IsNullOrEmpty(AllFirstChars)) - return list; - char[] chars = AllFirstChars.ToCharArray(); - foreach (char ch in chars) - list.Add(ch.ToString()); - if ((Options & IdOptions.CanStartWithEscape) != 0) - list.Add(this.EscapeChar.ToString()); - return list; - } - - private void AdjustCasing() { - switch(CaseRestriction) { - case CaseRestriction.None: break; - case CaseRestriction.FirstLower: - AllFirstChars = AllFirstChars.ToLower(); - break; - case CaseRestriction.FirstUpper: - AllFirstChars = AllFirstChars.ToUpper(); - break; - case CaseRestriction.AllLower: - AllFirstChars = AllFirstChars.ToLower(); - AllChars = AllChars.ToLower(); - break; - case CaseRestriction.AllUpper: - AllFirstChars = AllFirstChars.ToUpper(); - AllChars = AllChars.ToUpper(); - break; - }//switch - }//method - - protected override void InitDetails(ParsingContext context, CompoundTokenDetails details) { - base.InitDetails(context, details); - details.Flags = (short)Options; - } - - //Override to assign IsKeyword flag to keyword tokens - protected override Token CreateToken(ParsingContext context, ISourceStream source, CompoundTokenDetails details) { - Token token = base.CreateToken(context, source, details); - if (details.IsSet((short)IdOptions.IsNotKeyword)) - return token; - //check if it is keyword - CheckReservedWord(token); - return token; - } - private void CheckReservedWord(Token token) { - KeyTerm keyTerm; - if (Grammar.KeyTerms.TryGetValue(token.Text, out keyTerm)) { - token.KeyTerm = keyTerm; - //if it is reserved word, then overwrite terminal - if (keyTerm.FlagIsSet(TermFlags.IsReservedWord)) - token.SetTerminal(keyTerm); - } - } - - protected override Token QuickParse(ParsingContext context, ISourceStream source) { - if (AllFirstChars.IndexOf(source.PreviewChar) < 0) - return null; - source.PreviewPosition++; - while (AllChars.IndexOf(source.PreviewChar) >= 0 && !source.EOF()) - source.PreviewPosition++; - //if it is not a terminator then cancel; we need to go through full algorithm - if (GrammarData.WhitespaceAndDelimiters.IndexOf(source.PreviewChar) < 0) return null; - var token = source.CreateToken(this.OutputTerminal); - if(CaseRestriction != CaseRestriction.None && !CheckCaseRestriction(token.ValueString)) - return null; - //!!! Do not convert to common case (all-lower) for case-insensitive grammar. Let identifiers remain as is, - // it is responsibility of interpreter to provide case-insensitive read/write operations for identifiers - // if (!this.GrammarData.Grammar.CaseSensitive) - // token.Value = token.Text.ToLower(CultureInfo.InvariantCulture); - CheckReservedWord(token); - return token; - } - - protected override bool ReadBody(ISourceStream source, CompoundTokenDetails details) { - int start = source.PreviewPosition; - bool allowEscapes = details.IsSet((short)IdOptions.AllowsEscapes); - CharList outputChars = new CharList(); - while (!source.EOF()) { - char current = source.PreviewChar; - if (GrammarData.WhitespaceAndDelimiters.IndexOf(current) >= 0) break; - if (allowEscapes && current == this.EscapeChar) { - current = ReadUnicodeEscape(source, details); - //We need to back off the position. ReadUnicodeEscape sets the position to symbol right after escape digits. - //This is the char that we should process in next iteration, so we must backup one char, to pretend the escaped - // char is at position of last digit of escape sequence. - source.PreviewPosition--; - if (details.Error != null) - return false; - } - //Check if current character is OK - if (!CharOk(current, source.PreviewPosition == start)) - break; - //Check if we need to skip this char - UnicodeCategory currCat = char.GetUnicodeCategory(current); //I know, it suxx, we do it twice, fix it later - if (!this.CharsToRemoveCategories.Contains(currCat)) - outputChars.Add(current); //add it to output (identifier) - source.PreviewPosition++; - }//while - if (outputChars.Count == 0) - return false; - //Convert collected chars to string - details.Body = new string(outputChars.ToArray()); - if (!CheckCaseRestriction(details.Body)) - return false; - return !string.IsNullOrEmpty(details.Body); - } - - private bool CharOk(char ch, bool first) { - //first check char lists, then categories - string all = first? AllFirstChars : AllChars; - if(all.IndexOf(ch) >= 0) return true; - //check categories - UnicodeCategory chCat = char.GetUnicodeCategory(ch); - UnicodeCategoryList catList = first ? StartCharCategories : CharCategories; - if (catList.Contains(chCat)) return true; - return false; - } - - private bool CheckCaseRestriction(string body) { - switch(CaseRestriction) { - case CaseRestriction.FirstLower: return Char.IsLower(body, 0); - case CaseRestriction.FirstUpper: return Char.IsUpper(body, 0); - case CaseRestriction.AllLower: return body.ToLower() == body; - case CaseRestriction.AllUpper: return body.ToUpper() == body; - default : return true; - } - }//method - - - private char ReadUnicodeEscape(ISourceStream source, CompoundTokenDetails details) { - //Position is currently at "\" symbol - source.PreviewPosition++; //move to U/u char - int len; - switch (source.PreviewChar) { - case 'u': len = 4; break; - case 'U': len = 8; break; - default: - details.Error = Resources.ErrInvEscSymbol; // "Invalid escape symbol, expected 'u' or 'U' only." - return '\0'; - } - if (source.PreviewPosition + len > source.Text.Length) { - details.Error = Resources.ErrInvEscSeq; // "Invalid escape sequence"; - return '\0'; - } - source.PreviewPosition++; //move to the first digit - string digits = source.Text.Substring(source.PreviewPosition, len); - char result = (char)Convert.ToUInt32(digits, 16); - source.PreviewPosition += len; - details.Flags |= (int) IdFlagsInternal.HasEscapes; - return result; - } - - protected override bool ConvertValue(CompoundTokenDetails details) { - if (details.IsSet((short)IdOptions.NameIncludesPrefix)) - details.Value = details.Prefix + details.Body; - else - details.Value = details.Body; - return true; - } - - #endregion - - }//class - - -} //namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/ImpliedSymbolTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/ImpliedSymbolTerminal.cs deleted file mode 100644 index ac4d1f642e..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/ImpliedSymbolTerminal.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - //In some grammars there is a situation when some operator symbol can be skipped in source text and should be implied by parser. - // In arithmetics, we often imply "*" operator in formulas: - // x y => x * y. - // The SearchGrammar in Samples provides another example: two consequtive terms imply "and" operator and should be treated as such: - // x y => x AND y - // We could use a simple nullable Non-terminal terminal in this case, but the problem is that we cannot associate precedence - // and associativity with non-terminal, only with terminals. Precedence is important here because the implied symbol identifies binary - // operation, so parser should be able to use precedence value(s) when resolving shift/reduce ambiguity. - // So here comes ImpliedSymbolTerminal - it is a terminal that produces a token with empty text. - // It relies on scanner-parser link enabled - so the implied symbol token is created ONLY - // when the current parser state allows it and there are no other alternatives (hence lowest priority value). - // See SearchGrammar as an example of use of this terminal. - public class ImpliedSymbolTerminal : Terminal { - public ImpliedSymbolTerminal(string name) : base(name) { - this.Priority = Terminal.LowestPriority; //This terminal should be tried after all candidate terminals failed. - } - - public override void Init(Irony.Parsing.GrammarData grammarData) { - base.Init(grammarData); - //Check that Parser-scanner link is enabled - this terminal can be used only if this link is enabled - if (Grammar.FlagIsSet(LanguageFlags.DisableScannerParserLink)) - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrImpliedOpUseParserLink, this.Name); - //"ImpliedSymbolTerminal cannot be used in grammar with DisableScannerParserLink flag set" - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - return source.CreateToken(this); //Create an empty token representing an implied symbol. - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/KeyTerm.cs b/sources/shaders/Irony/Parsing/Terminals/KeyTerm.cs deleted file mode 100644 index dfc5494751..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/KeyTerm.cs +++ /dev/null @@ -1,114 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class KeyTermTable : Dictionary { - public KeyTermTable(StringComparer comparer) : base(100, comparer) {} - } - public class KeyTermList : List { } - - //Keyterm is a keyword or a special symbol used in grammar rules, for example: begin, end, while, =, *, etc. - // So "key" comes from the Keyword. - public class KeyTerm : Terminal { - public KeyTerm(string text, string name) : base(name) { - Text = text; - base.ErrorAlias = name; - - } - - public string Text {get; private set;} - - //Normally false, meaning keywords (symbols in grammar consisting of letters) cannot be followed by a letter or digit - public bool AllowAlphaAfterKeyword = false; - - #region overrides: TryMatch, Init, GetPrefixes(), ToString() - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - - #region comments about keyterms priority - // Priority - determines the order in which multiple terminals try to match input for a given current char in the input. - // For a given input char the scanner looks up the collection of terminals that may match this input symbol. It is the order - // in this collection that is determined by Priority value - the higher the priority, the earlier the terminal gets a chance - // to check the input. - // Keywords found in grammar by default have lowest priority to allow other terminals (like identifiers)to check the input first. - // Additionally, longer symbols have higher priority, so symbols like "+=" should have higher priority value than "+" symbol. - // As a result, Scanner would first try to match "+=", longer symbol, and if it fails, it will try "+". - // Reserved words are the opposite - they have the highest priority - #endregion - if (FlagIsSet(TermFlags.IsReservedWord)) - base.Priority = ReservedWordsPriority + Text.Length; - else - base.Priority = LowestPriority + Text.Length; - //Setup editor info - if (this.EditorInfo != null) return; - TokenType tknType = TokenType.Identifier; - if (FlagIsSet(TermFlags.IsOperator)) - tknType |= TokenType.Operator; - else if (FlagIsSet(TermFlags.IsDelimiter | TermFlags.IsPunctuation)) - tknType |= TokenType.Delimiter; - TokenTriggers triggers = TokenTriggers.None; - if (this.FlagIsSet(TermFlags.IsBrace)) - triggers |= TokenTriggers.MatchBraces; - if (this.FlagIsSet(TermFlags.IsMemberSelect)) - triggers |= TokenTriggers.MemberSelect; - TokenColor color = TokenColor.Text; - if (FlagIsSet(TermFlags.IsKeyword)) - color = TokenColor.Keyword; - this.EditorInfo = new TokenEditorInfo(tknType, color, triggers); - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - if (!source.MatchSymbol(Text, !Grammar.CaseSensitive)) - return null; - source.PreviewPosition += Text.Length; - //In case of keywords, check that it is not followed by letter or digit - if (this.FlagIsSet(TermFlags.IsKeyword) && !AllowAlphaAfterKeyword) { - var previewChar = source.PreviewChar; - if (char.IsLetterOrDigit(previewChar) || previewChar == '_') return null; //reject - } - var token = source.CreateToken(this.OutputTerminal, Text); - return token; - } - - public override IList GetFirsts() { - return new string[] { Text }; - } - public override string ToString() { - if (Name != Text) return Name; - return Text; - } - public override string TokenToString(Token token) { - var keyw = FlagIsSet(TermFlags.IsKeyword)? Resources.LabelKeyword : Resources.LabelKeySymbol ; //"(Keyword)" : "(Key symbol)" - var result = (token.ValueString ?? token.Text) + " " + keyw; - return result; - } - #endregion - - [System.Diagnostics.DebuggerStepThrough] - public override bool Equals(object obj) { - return base.Equals(obj); - } - - [System.Diagnostics.DebuggerStepThrough] - public override int GetHashCode() { - return Text.GetHashCode(); - } - - }//class - - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/LineContinuationTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/LineContinuationTerminal.cs deleted file mode 100644 index cce12fad6a..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/LineContinuationTerminal.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class LineContinuationTerminal : Terminal { - - public LineContinuationTerminal(string name, params string[] startSymbols) : base(name, TokenCategory.Outline) { - var symbols = startSymbols.Where(s => !IsNullOrWhiteSpace(s)).ToArray(); - StartSymbols = new StringList(symbols); - if (StartSymbols.Count == 0) - StartSymbols.AddRange(_defaultStartSymbols); - Priority = Terminal.HighestPriority; - } - - public StringList StartSymbols; - private string _startSymbolsFirsts = String.Concat(_defaultStartSymbols); - static string[] _defaultStartSymbols = new[] { "\\", "_" }; - public string LineTerminators = "\n\r\v"; - - #region overrides - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - - // initialize string of start characters for fast lookup - _startSymbolsFirsts = new String(StartSymbols.Select(s => s.First()).ToArray()); - - if (this.EditorInfo == null) { - this.EditorInfo = new TokenEditorInfo(TokenType.Delimiter, TokenColor.Comment, TokenTriggers.None); - } - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - // Quick check - var lookAhead = source.PreviewChar; - var startIndex = _startSymbolsFirsts.IndexOf(lookAhead); - if (startIndex < 0) - return null; - - // Match start symbols - if (!BeginMatch(source, startIndex, lookAhead)) - return null; - - // Match NewLine - var result = CompleteMatch(source); - if (result != null) - return result; - - // Report an error - return source.CreateErrorToken(Resources.ErrNewLineExpected); - } - - private bool BeginMatch(ISourceStream source, int startFrom, char lookAhead) { - foreach (var startSymbol in StartSymbols.Skip(startFrom)) { - if (startSymbol[0] != lookAhead) - continue; - if (source.MatchSymbol(startSymbol, !Grammar.CaseSensitive)) { - source.PreviewPosition += startSymbol.Length; - return true; - } - } - return false; - } - - private Token CompleteMatch(ISourceStream source) { - if (source.EOF()) - return null; - - do { - // Match NewLine - var lookAhead = source.PreviewChar; - if (LineTerminators.IndexOf(lookAhead) >= 0) - { - source.PreviewPosition++; - // Treat \r\n as single NewLine - if (!source.EOF() && lookAhead == '\r' && source.PreviewChar == '\n') - source.PreviewPosition++; - break; - } - - // Eat up whitespace - if (GrammarData.Grammar.WhitespaceChars.IndexOf(lookAhead) >= 0) - { - source.PreviewPosition++; - continue; - } - - // Fail on anything else - return null; - } - while (!source.EOF()); - - // Create output token - return source.CreateToken(this.OutputTerminal); - } - - public override IList GetFirsts() { - return StartSymbols; - } - - #endregion - - private static bool IsNullOrWhiteSpace(string s) { -#if VS2008 - if (String.IsNullOrEmpty(s)) - return true; - return s.Trim().Length == 0; -#else - return String.IsNullOrWhiteSpace(s); -#endif - } - - } // LineContinuationTerminal class -} diff --git a/sources/shaders/Irony/Parsing/Terminals/NewLineTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/NewLineTerminal.cs deleted file mode 100644 index 7d9ed07588..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/NewLineTerminal.cs +++ /dev/null @@ -1,58 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - //This is a simple NewLine terminal recognizing line terminators for use in grammars for line-based languages like VB - // instead of more complex alternative of using CodeOutlineFilter. - public class NewLineTerminal : Terminal { - public NewLineTerminal(string name) : base(name, TokenCategory.Outline) { - base.ErrorAlias = Resources.LabelLineBreak; // "[line break]"; - this.Flags |= TermFlags.IsPunctuation; - } - - public string LineTerminators = "\n\r\v"; - - #region overrides: Init, GetFirsts, TryMatch - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - //Remove new line chars from whitespace - foreach(char t in LineTerminators) - grammarData.Grammar.WhitespaceChars = grammarData.Grammar.WhitespaceChars.Replace(t.ToString(), string.Empty); - } - public override IList GetFirsts() { - StringList firsts = new StringList(); - foreach(char t in LineTerminators) - firsts.Add(t.ToString()); - return firsts; - } - public override Token TryMatch(ParsingContext context, ISourceStream source) { - char current = source.PreviewChar; - if (!LineTerminators.Contains(current)) return null; - //Treat \r\n as a single terminator - bool doExtraShift = (current == '\r' && source.NextPreviewChar == '\n'); - source.PreviewPosition++; //main shift - if (doExtraShift) - source.PreviewPosition++; - Token result = source.CreateToken(this.OutputTerminal); - return result; - } - - #endregion - - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/QuotedValueLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/QuotedValueLiteral.cs deleted file mode 100644 index 8a2acc8685..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/QuotedValueLiteral.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - //Terminal for reading values enclosed in a pair of start/end characters. For ex, date literal #15/10/2009# in VB - public class QuotedValueLiteral : DataLiteralBase { - public string StartSymbol; - public string EndSymbol; - - public QuotedValueLiteral(string name, string startEndSymbol, TypeCode dataType) : this(name, startEndSymbol, startEndSymbol, dataType) {} - - public QuotedValueLiteral(string name, string startSymbol, string endSymbol, TypeCode dataType) : base(name, dataType) { - StartSymbol = startSymbol; - EndSymbol = endSymbol; - } - - public override IList GetFirsts() { - return new string[] {StartSymbol}; - } - protected override string ReadBody(ParsingContext context, ISourceStream source) { - if (!source.MatchSymbol(StartSymbol, !Grammar.CaseSensitive)) return null; //this will result in null returned from TryMatch, no token - var start = source.Location.Position + StartSymbol.Length; - var end = source.Text.IndexOf(EndSymbol, start); - if (end < 0) return null; - var body = source.Text.Substring(start, end - start); - source.PreviewPosition = end + EndSymbol.Length; //move beyond the end of EndSymbol - return body; - } - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/RegExBasedTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/RegExBasedTerminal.cs deleted file mode 100644 index 2d527a7ff6..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/RegExBasedTerminal.cs +++ /dev/null @@ -1,72 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using System.Text.RegularExpressions; - -namespace Irony.Parsing { - - //Note: this class was not tested at all - // Based on contributions by CodePlex user sakana280 - // 12.09.2008 - breaking change! added "name" parameter to the constructor - public class RegexBasedTerminal : Terminal { - public RegexBasedTerminal(string pattern, params string[] prefixes) - : base("name") { - Pattern = pattern; - if (prefixes != null) - Prefixes.AddRange(prefixes); - } - public RegexBasedTerminal(string name, string pattern, params string[] prefixes) : base(name) { - Pattern = pattern; - if (prefixes != null) - Prefixes.AddRange(prefixes); - } - - #region public properties - public readonly string Pattern; - public readonly StringList Prefixes = new StringList(); - - public Regex Expression { - get { return _expression; } - } Regex _expression; - #endregion - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - string workPattern = @"\G(" + Pattern + ")"; - RegexOptions options = (Grammar.CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase); - _expression = new Regex(workPattern, options); - if (this.EditorInfo == null) - this.EditorInfo = new TokenEditorInfo(TokenType.Unknown, TokenColor.Text, TokenTriggers.None); - } - - public override IList GetFirsts() { - return Prefixes; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - Match m = _expression.Match(source.Text, source.PreviewPosition); - if (!m.Success || m.Index != source.PreviewPosition) - return null; - source.PreviewPosition += m.Length; - return source.CreateToken(this.OutputTerminal); - } - - }//class - - - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/RegExLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/RegExLiteral.cs deleted file mode 100644 index 4245419e30..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/RegExLiteral.cs +++ /dev/null @@ -1,142 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace Irony.Parsing { - // Regular expression literal, like javascript literal: /abc?/i - // Allows optional switches - // example: - // regex = /abc\\\/de/ - // matches fragments like "abc\/de" - // Note: switches are returned in token.Details field. Unlike in StringLiteral, we don't need to unescape the escaped chars, - // (this is the job of regex engine), we only need to correctly recognize the end of expression - - [Flags] - public enum RegexTermOptions { - None = 0, - AllowLetterAfter = 0x01, //if not set (default) then any following letter (after legal switches) is reported as invalid switch - CreateRegExObject = 0x02, //if set, token.Value contains Regex object; otherwise, it contains a pattern (string) - UniqueSwitches = 0x04, //require unique switches - - Default = CreateRegExObject | UniqueSwitches, - } - - public class RegExLiteral : Terminal { - public class RegexSwitchTable : Dictionary { } - - public Char StartSymbol = '/'; - public Char EndSymbol='/'; - public Char EscapeSymbol='\\'; - public RegexSwitchTable Switches = new RegexSwitchTable(); - public RegexOptions DefaultOptions = RegexOptions.None; - public RegexTermOptions Options = RegexTermOptions.Default; - - private char[] _stopChars; - - public RegExLiteral(string name) : base(name) { - Switches.Add('i', RegexOptions.IgnoreCase); - Switches.Add('g', RegexOptions.None); //not sure what to do with this flag? anybody, any advice? - Switches.Add('m', RegexOptions.Multiline); - base.SetFlag(TermFlags.IsLiteral); - } - - public RegExLiteral(string name, char startEndSymbol, char escapeSymbol) : base(name) { - StartSymbol = startEndSymbol; - EndSymbol = startEndSymbol; - EscapeSymbol = escapeSymbol; - }//constructor - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - _stopChars = new char[] { EndSymbol, '\r', '\n' }; - } - public override IList GetFirsts() { - var result = new StringList(); - result.Add(StartSymbol.ToString()); - return result; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - while (true) { - //Find next position - var newPos = source.Text.IndexOfAny(_stopChars, source.PreviewPosition + 1); - //we either didn't find it - if (newPos == -1) - return source.CreateErrorToken(Resources.ErrNoEndForRegex);// "No end symbol for regex literal." - source.PreviewPosition = newPos; - if (source.PreviewChar != EndSymbol) - //we hit CR or LF, this is an error - return source.CreateErrorToken(Resources.ErrNoEndForRegex); - if (!CheckEscaped(source)) - break; - } - source.PreviewPosition++; //move after end symbol - //save pattern length, we will need it - var patternLen = source.PreviewPosition - source.Location.Position - 2; //exclude start and end symbol - //read switches and turn them into options - RegexOptions options = RegexOptions.None; - var switches = string.Empty; - while(ReadSwitch(source, ref options)) { - if (IsSet(RegexTermOptions.UniqueSwitches) && switches.Contains(source.PreviewChar)) - return source.CreateErrorToken(Resources.ErrDupRegexSwitch, source.PreviewChar); // "Duplicate switch '{0}' for regular expression" - switches += source.PreviewChar.ToString(); - source.PreviewPosition++; - } - //check following symbol - if (!IsSet(RegexTermOptions.AllowLetterAfter)) { - var currChar = source.PreviewChar; - if (char.IsLetter(currChar) || currChar == '_') - return source.CreateErrorToken(Resources.ErrInvRegexSwitch, currChar); // "Invalid switch '{0}' for regular expression" - } - var token = source.CreateToken(this.OutputTerminal); - //we have token, now what's left is to set its Value field. It is either pattern itself, or Regex instance - string pattern = token.Text.Substring(1, patternLen); //exclude start and end symbol - object value = pattern; - if (IsSet(RegexTermOptions.CreateRegExObject)) { - value = new Regex(pattern, options); - } - token.Value = value; - token.Details = switches; //save switches in token.Details - return token; - } - - private bool CheckEscaped(ISourceStream source) { - var savePos = source.PreviewPosition; - bool escaped = false; - source.PreviewPosition--; - while (source.PreviewChar == EscapeSymbol){ - escaped = !escaped; - source.PreviewPosition--; - } - source.PreviewPosition = savePos; - return escaped; - } - private bool ReadSwitch(ISourceStream source, ref RegexOptions options) { - RegexOptions option; - var result = Switches.TryGetValue(source.PreviewChar, out option); - if (result) - options |= option; - return result; - } - - public bool IsSet(RegexTermOptions option) { - return (Options & option) != 0; - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/StringLiteral.cs b/sources/shaders/Irony/Parsing/Terminals/StringLiteral.cs deleted file mode 100644 index 357ecef737..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/StringLiteral.cs +++ /dev/null @@ -1,401 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -namespace Irony.Parsing { - - [Flags] - public enum StringOptions : short { - None = 0, - IsChar = 0x01, - AllowsDoubledQuote = 0x02, //Convert doubled start/end symbol to a single symbol; for ex. in SQL, '' -> ' - AllowsLineBreak = 0x04, - IsTemplate = 0x08, //Can include embedded expressions that should be evaluated on the fly; ex in Ruby: "hello #{name}" - NoEscapes = 0x10, - AllowsUEscapes = 0x20, - AllowsXEscapes = 0x40, - AllowsOctalEscapes = 0x80, - AllowsAllEscapes = AllowsUEscapes | AllowsXEscapes | AllowsOctalEscapes, - - } - - //Container for settings of tempate string parser, to interpet strings having embedded values or expressions - // like in Ruby: - // "Hello, #{name}" - // Default values match settings for Ruby strings - public class StringTemplateSettings { - public string StartTag = "#{"; - public string EndTag = "}"; - public NonTerminal ExpressionRoot; - } - - public class StringLiteral : CompoundTerminalBase { - - public enum StringFlagsInternal : short { - HasEscapes = 0x100, - } - - #region StringSubType - class StringSubType { - internal readonly string Start, End; - internal readonly StringOptions Flags; - internal readonly byte Index; - internal StringSubType(string start, string end, StringOptions flags, byte index) { - Start = start; - End = end; - Flags = flags; - Index = index; - } - - internal static int LongerStartFirst(StringSubType x, StringSubType y) { - try {//in case any of them is null - if (x.Start.Length > y.Start.Length) return -1; - } catch { } - return 0; - } - } - class StringSubTypeList : List { - internal void Add(string start, string end, StringOptions flags) { - base.Add(new StringSubType(start, end, flags, (byte) this.Count)); - } - } - #endregion - - #region constructors and initialization - public StringLiteral(string name): base(name) { - base.SetFlag(TermFlags.IsLiteral); - base.AstNodeType = typeof(Irony.Interpreter.Ast.LiteralValueNode); - } - - public StringLiteral(string name, string startEndSymbol, StringOptions options) : this(name) { - _subtypes.Add(startEndSymbol, startEndSymbol, options); - } - - public StringLiteral(string name, string startEndSymbol) : this(name, startEndSymbol, StringOptions.None) { } - - public StringLiteral(string name, string startEndSymbol, StringOptions options, Type astNodeType) - : this(name, startEndSymbol, options) { - base.AstNodeType = astNodeType; - } - public StringLiteral(string name, string startEndSymbol, StringOptions options, AstNodeCreator astNodeCreator) - : this(name, startEndSymbol, options) { - base.AstNodeCreator = astNodeCreator; - } - - public void AddStartEnd(string startEndSymbol, StringOptions stringOptions) { - AddStartEnd(startEndSymbol, startEndSymbol, stringOptions); - } - public void AddStartEnd(string startSymbol, string endSymbol, StringOptions stringOptions) { - _subtypes.Add(startSymbol, endSymbol, stringOptions); - } - public void AddPrefix(string prefix, StringOptions flags) { - base.AddPrefixFlag(prefix, (short)flags); - } - - #endregion - - #region Properties/Fields - private readonly StringSubTypeList _subtypes = new StringSubTypeList(); - string _startSymbolsFirsts; //first chars of start-end symbols - #endregion - - #region overrides: Init, GetFirsts, ReadBody, etc... - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - _startSymbolsFirsts = string.Empty; - if (_subtypes.Count == 0) { - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrInvStrDef, this.Name); //"Error in string literal [{0}]: No start/end symbols specified." - return; - } - //collect all start-end symbols in lists and create strings of first chars - var allStartSymbols = new StringSet(); //to detect duplicate start symbols - _subtypes.Sort(StringSubType.LongerStartFirst); - bool isTemplate = false; - foreach (StringSubType subType in _subtypes) { - if (allStartSymbols.Contains(subType.Start)) - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, - Resources.ErrDupStartSymbolStr, subType.Start, this.Name); //"Duplicate start symbol {0} in string literal [{1}]." - allStartSymbols.Add(subType.Start); - _startSymbolsFirsts += subType.Start[0].ToString(); - if ((subType.Flags & StringOptions.IsTemplate) != 0) isTemplate = true; - } - if (!CaseSensitive) - _startSymbolsFirsts = _startSymbolsFirsts.ToLower() + _startSymbolsFirsts.ToUpper(); - //Set multiline flag - foreach (StringSubType info in _subtypes) { - if ((info.Flags & StringOptions.AllowsLineBreak) != 0) { - SetFlag(TermFlags.IsMultiline); - break; - } - } - //For templates only - if(isTemplate) { - //Check that template settings object is provided - var templateSettings = this.AstNodeConfig as StringTemplateSettings; - if(templateSettings == null) - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrTemplNoSettings, this.Name); //"Error in string literal [{0}]: IsTemplate flag is set, but TemplateSettings is not provided." - else if (templateSettings.ExpressionRoot == null) - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrTemplMissingExprRoot, this.Name); //"" - else if(!Grammar.SnippetRoots.Contains(templateSettings.ExpressionRoot)) - grammarData.Language.Errors.Add(GrammarErrorLevel.Error, null, Resources.ErrTemplExprNotRoot, this.Name); //"" - }//if - //Create editor info - if (this.EditorInfo == null) - this.EditorInfo = new TokenEditorInfo(TokenType.String, TokenColor.String, TokenTriggers.None); - }//method - - public override IList GetFirsts() { - StringList result = new StringList(); - result.AddRange(Prefixes); - //we assume that prefix is always optional, so string can start with start-end symbol - foreach (char ch in _startSymbolsFirsts) - result.Add(ch.ToString()); - return result; - } - - protected override bool ReadBody(ISourceStream source, CompoundTokenDetails details) { - if (!details.PartialContinues) { - if (!ReadStartSymbol(source, details)) return false; - } - return CompleteReadBody(source, details); - } - - private bool CompleteReadBody(ISourceStream source, CompoundTokenDetails details) { - bool escapeEnabled = !details.IsSet((short) StringOptions.NoEscapes); - int start = source.PreviewPosition; - string endQuoteSymbol = details.EndSymbol; - string endQuoteDoubled = endQuoteSymbol + endQuoteSymbol; //doubled quote symbol - bool lineBreakAllowed = details.IsSet((short) StringOptions.AllowsLineBreak); - //1. Find the string end - // first get the position of the next line break; we are interested in it to detect malformed string, - // therefore do it only if linebreak is NOT allowed; if linebreak is allowed, set it to -1 (we don't care). - int nlPos = lineBreakAllowed ? -1 : source.Text.IndexOf('\n', source.PreviewPosition); - //fix by ashmind for EOF right after opening symbol - while (true) { - int endPos = source.Text.IndexOf(endQuoteSymbol, source.PreviewPosition); - //Check for partial token in line-scanning mode - if (endPos < 0 && details.PartialOk && lineBreakAllowed) { - ProcessPartialBody(source, details); - return true; - } - //Check for malformed string: either EndSymbol not found, or LineBreak is found before EndSymbol - bool malformed = endPos < 0 || nlPos >= 0 && nlPos < endPos; - if (malformed) { - //Set source position for recovery: move to the next line if linebreak is not allowed. - if (nlPos > 0) endPos = nlPos; - if (endPos > 0) source.PreviewPosition = endPos + 1; - details.Error = Resources.ErrBadStrLiteral;// "Mal-formed string literal - cannot find termination symbol."; - return true; //we did find start symbol, so it is definitely string, only malformed - }//if malformed - - if (source.EOF()) - return true; - - //We found EndSymbol - check if it is escaped; if yes, skip it and continue search - if (escapeEnabled && IsEndQuoteEscaped(source.Text, endPos)) { - source.PreviewPosition = endPos + endQuoteSymbol.Length; - continue; //searching for end symbol - } - - //Check if it is doubled end symbol - source.PreviewPosition = endPos; - if (details.IsSet((short)StringOptions.AllowsDoubledQuote) && source.MatchSymbol(endQuoteDoubled, !CaseSensitive)) { - source.PreviewPosition = endPos + endQuoteDoubled.Length; - continue; - }//checking for doubled end symbol - - //Ok, this is normal endSymbol that terminates the string. - // Advance source position and get out from the loop - details.Body = source.Text.Substring(start, endPos - start); - source.PreviewPosition = endPos + endQuoteSymbol.Length; - return true; //if we come here it means we're done - we found string end. - } //end of loop to find string end; - } - private void ProcessPartialBody(ISourceStream source, CompoundTokenDetails details) { - int from = source.PreviewPosition; - source.PreviewPosition = source.Text.Length; - details.Body = source.Text.Substring(from, source.PreviewPosition - from); - details.IsPartial = true; - } - - protected override void InitDetails(ParsingContext context, CompoundTerminalBase.CompoundTokenDetails details) { - base.InitDetails(context, details); - if (context.VsLineScanState.Value != 0) { - //we are continuing partial string on the next line - details.Flags = context.VsLineScanState.TerminalFlags; - details.SubTypeIndex = context.VsLineScanState.TokenSubType; - var stringInfo = _subtypes[context.VsLineScanState.TokenSubType]; - details.StartSymbol = stringInfo.Start; - details.EndSymbol = stringInfo.End; - } - } - - protected override void ReadSuffix(ISourceStream source, CompoundTerminalBase.CompoundTokenDetails details) { - base.ReadSuffix(source, details); - //"char" type can be identified by suffix (like VB where c suffix identifies char) - // in this case we have details.TypeCodes[0] == char and we need to set the IsChar flag - if (details.TypeCodes != null && details.TypeCodes[0] == TypeCode.Char) - details.Flags |= (int)StringOptions.IsChar; - else - //we may have IsChar flag set (from startEndSymbol, like in c# single quote identifies char) - // in this case set type code - if (details.IsSet((short) StringOptions.IsChar)) - details.TypeCodes = new TypeCode[] { TypeCode.Char }; - } - - private bool IsEndQuoteEscaped(string text, int quotePosition) { - bool escaped = false; - int p = quotePosition - 1; - while (p > 0 && text[p] == EscapeChar) { - escaped = !escaped; - p--; - } - return escaped; - } - - private bool ReadStartSymbol(ISourceStream source, CompoundTokenDetails details) { - if (_startSymbolsFirsts.IndexOf(source.PreviewChar) < 0) - return false; - foreach (StringSubType subType in _subtypes) { - if (!source.MatchSymbol(subType.Start, !CaseSensitive)) - continue; - //We found start symbol - details.StartSymbol = subType.Start; - details.EndSymbol = subType.End; - details.Flags |= (short) subType.Flags; - details.SubTypeIndex = subType.Index; - source.PreviewPosition += subType.Start.Length; - return true; - }//foreach - return false; - }//method - - - //Extract the string content from lexeme, adjusts the escaped and double-end symbols - protected override bool ConvertValue(CompoundTokenDetails details) { - string value = details.Body; - bool escapeEnabled = !details.IsSet((short)StringOptions.NoEscapes); - //Fix all escapes - if (escapeEnabled && value.IndexOf(EscapeChar) >= 0) { - details.Flags |= (int) StringFlagsInternal.HasEscapes; - string[] arr = value.Split(EscapeChar); - bool ignoreNext = false; - //we skip the 0 element as it is not preceeded by "\" - for (int i = 1; i < arr.Length; i++) { - if (ignoreNext) { - ignoreNext = false; - continue; - } - string s = arr[i]; - if (string.IsNullOrEmpty(s)) { - //it is "\\" - escaped escape symbol. - arr[i] = @"\"; - ignoreNext = true; - continue; - } - //The char is being escaped is the first one; replace it with char in Escapes table - char first = s[0]; - string newFirst; - if (Escapes.TryGetValue(first, out newFirst)) - arr[i] = newFirst + s.Substring(1); - else { - arr[i] = HandleSpecialEscape(arr[i], details); - }//else - }//for i - value = string.Join(string.Empty, arr); - }// if EscapeEnabled - - //Check for doubled end symbol - string endSymbol = details.EndSymbol; - if (details.IsSet((short)StringOptions.AllowsDoubledQuote) && value.IndexOf(endSymbol) >= 0) - value = value.Replace(endSymbol + endSymbol, endSymbol); - - if (details.IsSet((short)StringOptions.IsChar)) { - if (value.Length != 1) { - details.Error = Resources.ErrBadChar; //"Invalid length of char literal - should be a single character."; - return false; - } - details.Value = value[0]; - } else { - details.TypeCodes = new TypeCode[] { TypeCode.String }; - details.Value = value; - } - return true; - } - - //Should support: \Udddddddd, \udddd, \xdddd, \N{name}, \0, \ddd (octal), - protected virtual string HandleSpecialEscape(string segment, CompoundTokenDetails details) { - if (string.IsNullOrEmpty(segment)) return string.Empty; - int len, p; string digits; char ch; string result; - char first = segment[0]; - switch (first) { - case 'u': - case 'U': - if (details.IsSet((short)StringOptions.AllowsUEscapes)) { - len = (first == 'u' ? 4 : 8); - if (segment.Length < len + 1) { - details.Error = string.Format(Resources.ErrBadUnEscape, segment.Substring(len + 1), len);// "Invalid unicode escape ({0}), expected {1} hex digits." - return segment; - } - digits = segment.Substring(1, len); - ch = (char) Convert.ToUInt32(digits, 16); - result = ch + segment.Substring(len + 1); - return result; - }//if - break; - case 'x': - if (details.IsSet((short)StringOptions.AllowsXEscapes)) { - //x-escape allows variable number of digits, from one to 4; let's count them - p = 1; //current position - while (p < 5 && p < segment.Length) { - if (Strings.HexDigits.IndexOf(segment[p]) < 0) break; - p++; - } - //p now point to char right after the last digit - if (p <= 1) { - details.Error = Resources.ErrBadXEscape; // @"Invalid \x escape, at least one digit expected."; - return segment; - } - digits = segment.Substring(1, p - 1); - ch = (char) Convert.ToUInt32(digits, 16); - result = ch + segment.Substring(p); - return result; - }//if - break; - case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - if (details.IsSet((short)StringOptions.AllowsOctalEscapes)) { - //octal escape allows variable number of digits, from one to 3; let's count them - p = 0; //current position - while (p < 3 && p < segment.Length) { - if (Strings.OctalDigits.IndexOf(segment[p]) < 0) break; - p++; - } - //p now point to char right after the last digit - digits = segment.Substring(0, p); - ch = (char)Convert.ToUInt32(digits, 8); - result = ch + segment.Substring(p); - return result; - }//if - break; - }//switch - details.Error = string.Format(Resources.ErrInvEscape, segment); //"Invalid escape sequence: \{0}" - return segment; - }//method - #endregion - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiBlockTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiBlockTerminal.cs deleted file mode 100644 index 7bdb2e5b49..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiBlockTerminal.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - public enum WikiBlockType { - EscapedText, - CodeBlock, - Anchor, - LinkToAnchor, - Url, - FileLink, //looks like it is the same as Url - Image, - } - - public class WikiBlockTerminal : WikiTerminalBase { - public readonly WikiBlockType BlockType; - - public WikiBlockTerminal(string name, WikiBlockType blockType, string openTag, string closeTag, string htmlElementName) - : base(name, WikiTermType.Block, openTag, closeTag, htmlElementName) { - BlockType = blockType; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - if (!source.MatchSymbol(OpenTag, true)) return null; - source.PreviewPosition += OpenTag.Length; - var endPos = source.Text.IndexOf(CloseTag, source.PreviewPosition); - string content; - if(endPos > 0) { - content = source.Text.Substring(source.PreviewPosition, endPos - source.PreviewPosition); - source.PreviewPosition = endPos + CloseTag.Length; - } else { - content = source.Text.Substring(source.PreviewPosition, source.Text.Length - source.PreviewPosition); - source.PreviewPosition = source.Text.Length; - } - var token = source.CreateToken(this.OutputTerminal, content); - return token; - } - - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTagTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTagTerminal.cs deleted file mode 100644 index ab4319506f..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTagTerminal.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - - //Handles formatting tags like *bold*, _italic_; also handles headings and lists - public class WikiTagTerminal : WikiTerminalBase { - - public WikiTagTerminal(string name, WikiTermType termType, string tag, string htmlElementName) - : this (name, termType, tag, string.Empty, htmlElementName) { } - - public WikiTagTerminal(string name, WikiTermType termType, string openTag, string closeTag, string htmlElementName) - : base (name, termType, openTag, closeTag, htmlElementName) { } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - bool isHeadingOrList = TermType == WikiTermType.Heading || TermType == WikiTermType.List; - if(isHeadingOrList) { - bool isAfterNewLine = (context.PreviousToken == null || context.PreviousToken.Terminal == Grammar.NewLine); - if(!isAfterNewLine) return null; - } - if(!source.MatchSymbol(OpenTag, true)) return null; - source.PreviewPosition += OpenTag.Length; - //For headings and lists require space after - if(TermType == WikiTermType.Heading || TermType == WikiTermType.List) { - const string whitespaces = " \t\r\n\v"; - if (!whitespaces.Contains(source.PreviewChar)) return null; - } - var token = source.CreateToken(this.OutputTerminal); - return token; - } - - }//class - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTextTerminal.cs b/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTextTerminal.cs deleted file mode 100644 index a4a70b0668..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/WikiTextTerminal.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - //Handles plain text - public class WikiTextTerminal : WikiTerminalBase { - public const char NoEscape = '\0'; - public char EscapeChar = NoEscape; - private char[] _stopChars; - - public WikiTextTerminal(string name) : base(name, WikiTermType.Text, string.Empty, string.Empty, string.Empty) { - this.Priority = Terminal.LowestPriority; - } - - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - var stopCharSet = new CharHashSet(); - foreach(var term in grammarData.Terminals) { - var firsts = term.GetFirsts(); - if (firsts == null) continue; - foreach (var first in firsts) - if (!string.IsNullOrEmpty(first)) - stopCharSet.Add(first[0]); - }//foreach term - if (EscapeChar != NoEscape) - stopCharSet.Add(EscapeChar); - _stopChars = stopCharSet.ToArray(); - } - - //override to WikiTerminalBase's method to return null, indicating there are no firsts, so it is a fallback terminal - public override IList GetFirsts() { - return null; - } - - public override Token TryMatch(ParsingContext context, ISourceStream source) { - bool isEscape = source.PreviewChar == EscapeChar && EscapeChar != NoEscape; - if(isEscape) { - //return a token containing only escaped char - var value = source.NextPreviewChar.ToString(); - source.PreviewPosition += 2; - return source.CreateToken(this.OutputTerminal, value); - } - var stopIndex = source.Text.IndexOfAny(_stopChars, source.Location.Position + 1); - if (stopIndex == source.Location.Position) return null; - if (stopIndex < 0) stopIndex = source.Text.Length; - source.PreviewPosition = stopIndex; - return source.CreateToken(this.OutputTerminal); - }//method - - }//class - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/_WikiTerminalBase.cs b/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/_WikiTerminalBase.cs deleted file mode 100644 index 6fd529b507..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/WikiTerminals/_WikiTerminalBase.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - public enum WikiTermType { - Text, - Element, - Format, - Heading, - List, - Block, - Table - } - - public abstract class WikiTerminalBase : Terminal { - public readonly WikiTermType TermType; - public readonly string OpenTag, CloseTag; - public string HtmlElementName, ContainerHtmlElementName; - public string OpenHtmlTag, CloseHtmlTag; - public string ContainerOpenHtmlTag, ContainerCloseHtmlTag; - - public WikiTerminalBase(string name, WikiTermType termType, string openTag, string closeTag, string htmlElementName) : base(name) { - TermType = termType; - OpenTag = openTag; - CloseTag = closeTag; - HtmlElementName = htmlElementName; - this.Priority = OpenTag.Length; //longer tags have higher priority - } - - public override IList GetFirsts() { - return new string[] {OpenTag}; - } - public override void Init(GrammarData grammarData) { - base.Init(grammarData); - if (!string.IsNullOrEmpty(HtmlElementName)) { - if (string.IsNullOrEmpty(OpenHtmlTag)) OpenHtmlTag = "<" + HtmlElementName + ">"; - if (string.IsNullOrEmpty(CloseHtmlTag)) CloseHtmlTag = ""; - } - if (!string.IsNullOrEmpty(ContainerHtmlElementName)) { - if (string.IsNullOrEmpty(ContainerOpenHtmlTag)) ContainerOpenHtmlTag = "<" + ContainerHtmlElementName + ">"; - if (string.IsNullOrEmpty(ContainerCloseHtmlTag)) ContainerCloseHtmlTag = ""; - } - - } - - }//class - - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/Terminals/_ISourceStream.cs b/sources/shaders/Irony/Parsing/Terminals/_ISourceStream.cs deleted file mode 100644 index b0b59e8911..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/_ISourceStream.cs +++ /dev/null @@ -1,91 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - // - /// - /// Interface for Terminals to access the source stream and produce tokens. - /// - public interface ISourceStream { - - /// - /// Returns the source text - /// - string Text { get; } - /// - /// Current start location (position, row, column) of the new token - /// - SourceLocation Location { get; set; } - - /// - /// Gets or sets the current preview position in the source file. Must be greater or equal to Location.Position - /// - int PreviewPosition { get; set; } - /// - /// Gets a char at preview position - /// - char PreviewChar { get; } - /// - /// Gets the char at position next after the PrevewPosition - /// - char NextPreviewChar { get; } //char at PreviewPosition+1 - - /// - /// Creates a new token based on current preview position. - /// - /// A terminal associated with the token. - /// New token. - Token CreateToken(Terminal terminal); - - /// - /// Creates a new token based on current preview position and sets its Value field. - /// - /// A terminal associated with the token. - /// The value associated with the token. - /// New token. - Token CreateToken(Terminal terminal, object value); - - /// - /// Creates error token with custom error message as its Value. - /// - /// Message template, can contain placeholder like {0} to be filled by values from args. - /// A list of message arguments - /// An error token. - Token CreateErrorToken(string message, params object[] args); - - /// - /// Tries to match the symbol with the text at current preview position. - /// - /// A symbol to match - /// True if char casing should be ignored. - /// True if there is a match; otherwise, false. - bool MatchSymbol(string symbol, bool ignoreCase); - - int TabWidth { get; set;} - bool EOF(); - - /* - //This member is intentionally removed from ISourceStream and made private in SourceStream class. The purpose is to discourage - its use or imitation - it produces a new string object which means new garbage for GC. All Irony-defined Terminal classes - are implemented without it, but you can always reproduce the implementation in your custom code if you really need it - string GetPreviewText(); - */ - - }//interface - - -} diff --git a/sources/shaders/Irony/Parsing/Terminals/_Terminal.cs b/sources/shaders/Irony/Parsing/Terminals/_Terminal.cs deleted file mode 100644 index ec27cc3da5..0000000000 --- a/sources/shaders/Irony/Parsing/Terminals/_Terminal.cs +++ /dev/null @@ -1,140 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - public class Terminal : BnfTerm { - #region Constructors - public Terminal(string name) : this(name, TokenCategory.Content, TermFlags.None) { } - public Terminal(string name, TokenCategory category) : this(name, category, TermFlags.None) { } - public Terminal(string name, string errorAlias, TokenCategory category, TermFlags flags) : this(name, category, flags) { - this.ErrorAlias = errorAlias; - } - public Terminal(string name, TokenCategory category, TermFlags flags) : base(name) { - Category = category; - this.Flags |= flags; - if (Category == TokenCategory.Outline) - this.SetFlag(TermFlags.IsPunctuation); - OutputTerminal = this; - } - #endregion - - #region fields and properties - public TokenCategory Category = TokenCategory.Content; - // Priority is used when more than one terminal may match the input char. - // It determines the order in which terminals will try to match input for a given char in the input. - // For a given input char the scanner uses the hash table to look up the collection of terminals that may match this input symbol. - // It is the order in this collection that is determined by Priority property - the higher the priority, - // the earlier the terminal gets a chance to check the input. - public int Priority; //default is 0 - - //Terminal to attach to the output token. By default is set to the Terminal itself - // Use SetOutputTerminal method to change it. For example of use see TerminalFactory.CreateSqlIdentifier and sample SQL grammar - public Terminal OutputTerminal { get; private set; } - - public TokenEditorInfo EditorInfo; - public byte MultilineIndex; - public Terminal IsPairFor; - #endregion - - #region virtual methods: GetFirsts(), TryMatch, Init, TokenToString - - //"Firsts" (chars) collections are used for quick search for possible matching terminal(s) using current character in the input stream. - // A terminal might declare no firsts. In this case, the terminal is tried for match for any current input character. - public virtual IList GetFirsts() { - return null; - } - - public virtual Token TryMatch(ParsingContext context, ISourceStream source) { - return null; - } - - public virtual string TokenToString(Token token) { - if (token.ValueString == this.Name) - return token.ValueString; - else - return (token.ValueString ?? token.Text) + " (" + Name + ")"; - } - - - #endregion - - #region Events: ValidateToken - public event EventHandler ValidateToken; - protected internal virtual void InvokeValidateToken(ParsingContext context) { - ValidateToken?.Invoke(this, context.SharedParsingEventArgs); - } - #endregion - - #region static comparison methods - public static int ByName(Terminal x, Terminal y) { - return string.Compare(x.ToString(), y.ToString()); - } - public static int ByPriorityReverse(Terminal x, Terminal y) { - if (x.Priority > y.Priority) - return -1; - if (x.Priority == y.Priority) - return 0; - return 1; - } - #endregion - - #region Miscellaneous: SetOutputTerminal - public void SetOutputTerminal(Grammar grammar, Terminal outputTerminal) { - OutputTerminal = outputTerminal; - grammar.NonGrammarTerminals.Add(this); - } - - #endregion - //Priority constants - public const int LowestPriority = -1000; - public const int HighestPriority = 1000; - public const int ReservedWordsPriority = 900; //almost top one - - public static string TerminalsToString(IEnumerable terminals, string separator) { - var sb = new StringBuilder(); - foreach (var term in terminals) { - sb.Append(term.ToString()); - sb.Append(separator); - } - return sb.ToString().Trim(); - } - - }//class - - public class TerminalSet : HashSet { - public override string ToString() { - return Terminal.TerminalsToString(this, " "); - } - } - - //No-duplicates list of terminals - public class TerminalList : List { - public new void Add(Terminal terminal) { - if (!Contains(terminal)) - base.Add(terminal); - } - public new void AddRange(IEnumerable terminals) { - foreach(var terminal in terminals) - Add(terminal); - } - public override string ToString() { - return Terminal.TerminalsToString(this, " "); - } - } - - -}//namespace diff --git a/sources/shaders/Irony/Parsing/TokenFilters/CodeOutlineFilter.cs b/sources/shaders/Irony/Parsing/TokenFilters/CodeOutlineFilter.cs deleted file mode 100644 index 5897a44210..0000000000 --- a/sources/shaders/Irony/Parsing/TokenFilters/CodeOutlineFilter.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Irony.Parsing { - [Flags] - public enum OutlineOptions { - None = 0, - ProduceIndents = 0x01, - CheckBraces = 0x02, - CheckOperator = 0x04, //to implement, auto line joining if line ends with operator - } - - public class CodeOutlineFilter : TokenFilter { - - public readonly OutlineOptions Options; - public readonly KeyTerm ContinuationTerminal; //Terminal - - GrammarData _grammarData; - Grammar _grammar; - ParsingContext _context; - bool _produceIndents; - bool _checkBraces, _checkOperator; - - public Stack Indents = new Stack(); - public Token CurrentToken; - public Token PreviousToken; - public SourceLocation PreviousTokenLocation; - public TokenStack OutputTokens = new TokenStack(); - bool _isContinuation, _prevIsContinuation; - bool _isOperator, _prevIsOperator; - bool _doubleEof; - - #region constructor - public CodeOutlineFilter(GrammarData grammarData, OutlineOptions options, KeyTerm continuationTerminal) { - _grammarData = grammarData; - _grammar = grammarData.Grammar; - _grammar.LanguageFlags |= LanguageFlags.EmitLineStartToken; - Options = options; - ContinuationTerminal = continuationTerminal; - if (ContinuationTerminal != null) - if (!_grammar.NonGrammarTerminals.Contains(ContinuationTerminal)) - _grammarData.Language.Errors.Add(GrammarErrorLevel.Warning, null, Resources.ErrOutlineFilterContSymbol, ContinuationTerminal.Name); - //"CodeOutlineFilter: line continuation symbol '{0}' should be added to Grammar.NonGrammarTerminals list.", - _produceIndents = OptionIsSet(OutlineOptions.ProduceIndents); - _checkBraces = OptionIsSet(OutlineOptions.CheckBraces); - _checkOperator = OptionIsSet(OutlineOptions.CheckOperator); - Reset(); - } - #endregion - - public override void Reset() { - base.Reset(); - Indents.Clear(); - Indents.Push(0); - OutputTokens.Clear(); - PreviousToken = null; - CurrentToken = null; - PreviousTokenLocation = new SourceLocation(); - } - - public bool OptionIsSet(OutlineOptions option) { - return (Options & option) != 0; - } - - public override IEnumerable BeginFiltering(ParsingContext context, IEnumerable tokens) { - _context = context; - foreach (Token token in tokens) { - ProcessToken(token); - while (OutputTokens.Count > 0) - yield return OutputTokens.Pop(); - }//foreach - }//method - - public void ProcessToken(Token token) { - SetCurrentToken(token); - //Quick checks - if (_isContinuation) - return; - var tokenTerm = token.Terminal; - - //check EOF - if (tokenTerm == _grammar.Eof) { - ProcessEofToken(); - return; - } - - if (tokenTerm != _grammar.LineStartTerminal) return; - //if we are here, we have LineStart token on new line; first remove it from stream, it should not go to parser - OutputTokens.Pop(); - - if (PreviousToken == null) return; - - - // first check if there was continuation symbol before - // or - if checkBraces flag is set - check if there were open braces - if (_prevIsContinuation || _checkBraces && _context.OpenBraces.Count > 0) - return; //no Eos token in this case - if (_prevIsOperator && _checkOperator) - return; //no Eos token in this case - - //We need to produce Eos token and indents (if _produceIndents is set). - // First check indents - they go first into OutputTokens stack, so they will be popped out last - if (_produceIndents) { - var currIndent = token.Location.Column; - var prevIndent = Indents.Peek(); - if (currIndent > prevIndent) { - Indents.Push(currIndent); - PushOutlineToken(_grammar.Indent, token.Location); - } else if (currIndent < prevIndent) { - PushDedents(currIndent); - //check that current indent exactly matches the previous indent - if (Indents.Peek() != currIndent) { - //fire error - OutputTokens.Push(new Token(_grammar.SyntaxError, token.Location, string.Empty, Resources.ErrInvDedent)); - // "Invalid dedent level, no previous matching indent found." - } - } - }//if _produceIndents - //Finally produce Eos token, but not in command line mode. In command line mode the Eos was already produced - // when we encountered Eof on previous line - if (_context.Mode != ParseMode.CommandLine) { - var eosLocation = ComputeEosLocation(); - PushOutlineToken(_grammar.Eos, eosLocation); - } - - }//method - - private void SetCurrentToken(Token token) { - _doubleEof = CurrentToken != null && CurrentToken.Terminal == _grammar.Eof - && token.Terminal == _grammar.Eof; - //Copy CurrentToken to PreviousToken - if (CurrentToken != null && CurrentToken.Category == TokenCategory.Content) { //remember only content tokens - PreviousToken = CurrentToken; - _prevIsContinuation = _isContinuation; - _prevIsOperator = _isOperator; - if (PreviousToken != null) - PreviousTokenLocation = PreviousToken.Location; - } - CurrentToken = token; - _isContinuation = (token.Terminal == ContinuationTerminal && ContinuationTerminal != null); - _isOperator = token.Terminal.FlagIsSet(TermFlags.IsOperator); - if (!_isContinuation) - OutputTokens.Push(token); //by default input token goes to output, except continuation symbol - } - - //Processes Eof token. We should take into account the special case of processing command line input. - // In this case we should not automatically dedent all stacked indents if we get EOF. - // Note that tokens will be popped from the OutputTokens stack and sent to parser in the reverse order compared to - // the order we pushed them into OutputTokens stack. We have Eof already in stack; we first push dedents, then Eos - // They will come out to parser in the following order: Eos, Dedents, Eof. - private void ProcessEofToken() { - //First decide whether we need to produce dedents and Eos symbol - bool pushDedents = false; - bool pushEos = true; - switch (_context.Mode) { - case ParseMode.File: - pushDedents = _produceIndents; //Do dedents if token filter tracks indents - break; - case ParseMode.CommandLine: - //only if user entered empty line, we dedent all - pushDedents = _produceIndents && _doubleEof; - pushEos = !_prevIsContinuation && !_doubleEof; //if previous symbol is continuation symbol then don't push Eos - break; - case ParseMode.VsLineScan: - pushDedents = false; //Do not dedent at all on every line end - break; - } - //unindent all buffered indents; - if (pushDedents) PushDedents(0); - //now push Eos token - it will be popped first, then dedents, then EOF token - if (pushEos) { - var eosLocation = ComputeEosLocation(); - PushOutlineToken(_grammar.Eos, eosLocation); - } - } - - private void PushDedents(int untilPosition) { - while (Indents.Peek() > untilPosition) { - Indents.Pop(); - PushOutlineToken(_grammar.Dedent, CurrentToken.Location); - } - } - - private SourceLocation ComputeEosLocation() { - if (PreviousToken == null) - return new SourceLocation(); - //Return position at the end of previous token - var loc = PreviousToken.Location; - var len = PreviousToken.Length; - return new SourceLocation(loc.Position + len, loc.Line, loc.Column + len); - } - - private void PushOutlineToken(Terminal term, SourceLocation location) { - OutputTokens.Push(new Token(term, location, string.Empty, null)); - } - - }//class -}//namespace diff --git a/sources/shaders/Irony/Parsing/TokenFilters/TokenFilter.cs b/sources/shaders/Irony/Parsing/TokenFilters/TokenFilter.cs deleted file mode 100644 index 567d9c94eb..0000000000 --- a/sources/shaders/Irony/Parsing/TokenFilters/TokenFilter.cs +++ /dev/null @@ -1,55 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace Irony.Parsing { - - #region Comments - // Token filter is a token preprocessor that operates on a token stream between scanner and parser: - // scanner -> (token filters)-> parser - // Token stream from scanner output is fed into a chain of token filters that add/remove/modify tokens - // in the stream before it gets to the parser. Some tasks that come up in scanning and parsing are best - // handled by such an intermediate processor. Examples: - // * Macro expansion - // * Conditional compilation clauses - // * Handling commented-out blocks. Scheme allows commenting out entire blocks of code using "#;" prefix followed by - // well-formed datum. This type of comments cannot be handled by scanner as it requires parser-like processing - // of the stream to locate the end of the block. At the same time parser is not a good place to handle this either, - // as it would require defining optional "commented block" element everywhere in the grammar. - // Token filter is an ideal place for implementing this task - after scanning but before parsing. - // * Assembling doc-comment blocks (XML doc lines in c#) from individual comment lines - // and attaching it to the next content token, and later sticking it to the parsed node. - // * Handling newlines, indents and unindents for languages like Python. - // Tracking this information directly in the scanner makes things really messy, and it does not fit well - // into general-purpose scanner. Token filter can handle it easily. In this case the scanner - // handles the new-line character and indentations as whitespace and simply ignores it. - // The CodeOutlineFilter re-creates new-line and indent tokens by analyzing - // the line/column properties of the incoming tokens, and inserts them into its output. - #endregion - public class TokenFilter { - - public virtual IEnumerable BeginFiltering(ParsingContext context, IEnumerable tokens) { - yield break; - } - - public virtual void Reset() { - } - protected internal virtual void OnSetSourceLocation(SourceLocation location) { - } - }//class - - public class TokenFilterList : List { } - -}//namespace diff --git a/sources/shaders/Irony/Properties/AssemblyInfo.cs b/sources/shaders/Irony/Properties/AssemblyInfo.cs deleted file mode 100644 index 8a648a61cf..0000000000 --- a/sources/shaders/Irony/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,42 +0,0 @@ -#region License -/* ********************************************************************************** - * Copyright (c) Roman Ivantsov - * This source code is subject to terms and conditions of the MIT License - * for Irony. A copy of the license can be found in the License.txt file - * at the root of this distribution. - * By using this source code in any fashion, you are agreeing to be bound by the terms of the - * MIT License. - * You must not remove this notice from this software. - * **********************************************************************************/ -#endregion - -using System; -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("44015759-db10-4a6f-8251-d1d18599b60f")] -[assembly: CLSCompliant(true)] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -//[assembly: AssemblyFileVersion("1.0.0.0")] - -[assembly: NeutralResourcesLanguage("en")] diff --git a/sources/shaders/Irony/Resources.Designer.cs b/sources/shaders/Irony/Resources.Designer.cs deleted file mode 100644 index 43c35e8139..0000000000 --- a/sources/shaders/Irony/Resources.Designer.cs +++ /dev/null @@ -1,1027 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Irony { - using System; - using System.Reflection; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Irony.Resources", typeof(Resources).GetTypeInfo().Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to Nn. - /// - internal static string ConsoleNoChars { - get { - return ResourceManager.GetString("ConsoleNoChars", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Yy. - /// - internal static string ConsoleYesChars { - get { - return ResourceManager.GetString("ConsoleYesChars", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Ambiguous grammar, unresolvable reduce-reduce conflicts. State {0}, lookaheads [{1}]. - /// - internal static string ErrAmbigGrammarRR { - get { - return ResourceManager.GetString("ErrAmbigGrammarRR", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Ambiguous grammar, unresolvable shift-reduce conflicts. State {0}, lookaheads [{1}]. - /// - internal static string ErrAmbigGrammarSR { - get { - return ResourceManager.GetString("ErrAmbigGrammarSR", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Argument list not found in the stack. Expected: ValueList, found: {0}.. - /// - internal static string ErrArgListNotFound { - get { - return ResourceManager.GetString("ErrArgListNotFound", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalide operation, attempt to assign constant or literal value.. - /// - internal static string ErrAssignLiteralValue { - get { - return ResourceManager.GetString("ErrAssignLiteralValue", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid length of char literal - should be a single character.. - /// - internal static string ErrBadChar { - get { - return ResourceManager.GetString("ErrBadChar", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Mal-formed string literal - cannot find termination symbol.. - /// - internal static string ErrBadStrLiteral { - get { - return ResourceManager.GetString("ErrBadStrLiteral", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid unicode escape ({0}), expected {1} hex digits.. - /// - internal static string ErrBadUnEscape { - get { - return ResourceManager.GetString("ErrBadUnEscape", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid \x escape, at least one digit expected.. - /// - internal static string ErrBadXEscape { - get { - return ResourceManager.GetString("ErrBadXEscape", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot convert value from type {0} to type {1}, type converter not defined.. - /// - internal static string ErrCannotConvertValue { - get { - return ResourceManager.GetString("ErrCannotConvertValue", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Cannot convert literal {0} to type {1}.. - /// - internal static string ErrCannotConvertValueToType { - get { - return ResourceManager.GetString("ErrCannotConvertValueToType", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} State {1} on inputs: {2}. - /// - internal static string ErrConflictMsgTemplate { - get { - return ResourceManager.GetString("ErrConflictMsgTemplate", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Fatal error:. - /// - internal static string ErrConsoleFatalError { - get { - return ResourceManager.GetString("ErrConsoleFatalError", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Construct '{0}' is not supported (yet) by language implementation.. - /// - internal static string ErrConstructNotSupported { - get { - return ResourceManager.GetString("ErrConstructNotSupported", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Could not find a closing quote for quoted value.. - /// - internal static string ErrDsvNoClosingQuote { - get { - return ResourceManager.GetString("ErrDsvNoClosingQuote", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Duplicate switch '{0}' for regular expression.. - /// - internal static string ErrDupRegexSwitch { - get { - return ResourceManager.GetString("ErrDupRegexSwitch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Duplicate start symbol {0} in string literal [{1}].. - /// - internal static string ErrDupStartSymbolStr { - get { - return ResourceManager.GetString("ErrDupStartSymbolStr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Failed to create AST node for non-terminal [{0}], error: {1}. - /// - internal static string ErrFailedCreateNode { - get { - return ResourceManager.GetString("ErrFailedCreateNode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ImpliedSymbolTerminal cannot be used in grammar with DisableScannerParserLink flag set. - /// - internal static string ErrImpliedOpUseParserLink { - get { - return ResourceManager.GetString("ErrImpliedOpUseParserLink", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Interpreter error, DataStack.Pop() operation failed - stack is empty.. - /// - internal static string ErrInternalErrDataPopFailed { - get { - return ResourceManager.GetString("ErrInternalErrDataPopFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Interpreter is busy.. - /// - internal static string ErrInterpreterIsBusy { - get { - return ResourceManager.GetString("ErrInterpreterIsBusy", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid arguments for IncDecNode AST node: either first or second argument should be '--' or '++'.. - /// - internal static string ErrInvalidArgsForIncDec { - get { - return ResourceManager.GetString("ErrInvalidArgsForIncDec", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid AstMode value in call to Evaluate method. Node: {0}, mode: {1}.. - /// - internal static string ErrInvalidAstMode { - get { - return ResourceManager.GetString("ErrInvalidAstMode", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid character: '{0}'.. - /// - internal static string ErrInvalidChar { - get { - return ResourceManager.GetString("ErrInvalidChar", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid embedded expression. . - /// - internal static string ErrInvalidEmbeddedPrefix { - get { - return ResourceManager.GetString("ErrInvalidEmbeddedPrefix", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid dedent level, no previous matching indent found.. - /// - internal static string ErrInvDedent { - get { - return ResourceManager.GetString("ErrInvDedent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid escape sequence: \{0}.. - /// - internal static string ErrInvEscape { - get { - return ResourceManager.GetString("ErrInvEscape", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid escape sequence.. - /// - internal static string ErrInvEscSeq { - get { - return ResourceManager.GetString("ErrInvEscSeq", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid escape symbol, expected 'u' or 'U' only.. - /// - internal static string ErrInvEscSymbol { - get { - return ResourceManager.GetString("ErrInvEscSymbol", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid number.. - /// - internal static string ErrInvNumber { - get { - return ResourceManager.GetString("ErrInvNumber", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid switch '{0}' for regular expression. - /// - internal static string ErrInvRegexSwitch { - get { - return ResourceManager.GetString("ErrInvRegexSwitch", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Error in string literal [{0}]: No start/end symbols specified.. - /// - internal static string ErrInvStrDef { - get { - return ResourceManager.GetString("ErrInvStrDef", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to The last term of production containing SyntaxError must be a terminal. NonTerminal: {0}. - /// - internal static string ErrLastTermOfErrorProd { - get { - return ResourceManager.GetString("ErrLastTermOfErrorProd", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to List non-terminals cannot be marked transient; list: ({0}). - /// - internal static string ErrListCannotBeTransient { - get { - return ResourceManager.GetString("ErrListCannotBeTransient", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to NewLine expected.. - /// - internal static string ErrNewLineExpected { - get { - return ResourceManager.GetString("ErrNewLineExpected", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to NLALR process is in indefinite loop, number of states exceeded 3000.. - /// - internal static string ErrNLALRhang { - get { - return ResourceManager.GetString("ErrNLALRhang", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No closing pair for opening symbol {0}. - /// - internal static string ErrNoClosingBrace { - get { - return ResourceManager.GetString("ErrNoClosingBrace", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Warning: AstNodeType or AstNodeCreator is not set on non-terminals: {0}.. - /// - internal static string ErrNodeTypeNotSetOn { - get { - return ResourceManager.GetString("ErrNodeTypeNotSetOn", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No end symbol for regex literal.. - /// - internal static string ErrNoEndForRegex { - get { - return ResourceManager.GetString("ErrNoEndForRegex", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to No ending tag '{0}' found in embedded expression.. - /// - internal static string ErrNoEndTagInEmbExpr { - get { - return ResourceManager.GetString("ErrNoEndTagInEmbExpr", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to UnExprNode: no implementation for unary operator '{0}'.. - /// - internal static string ErrNoImplForUnaryOp { - get { - return ResourceManager.GetString("ErrNoImplForUnaryOp", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Number cannot be followed by a letter.. - /// - internal static string ErrNoLetterAfterNum { - get { - return ResourceManager.GetString("ErrNoLetterAfterNum", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ParserDataBuilder error: inadequate state {0}, reduce item '{1}' has no lookaheads.. - /// - internal static string ErrNoLkhds { - get { - return ResourceManager.GetString("ErrNoLkhds", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Non-terminal {0} has uninitialized Rule property.. - /// - internal static string ErrNtRuleIsNull { - get { - return ResourceManager.GetString("ErrNtRuleIsNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Attempt to evaluate NULL AST node. The AST node for term '{0}' was not created during parsing.. - /// - internal static string ErrNullNodeEval { - get { - return ResourceManager.GetString("ErrNullNodeEval", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Operator '{0}' is not defined for types {1} and {2}.. - /// - internal static string ErrOpNotDefinedForTypes { - get { - return ResourceManager.GetString("ErrOpNotDefinedForTypes", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Operator '{0} not imlemented.. - /// - internal static string ErrOpNotImplemented { - get { - return ResourceManager.GetString("ErrOpNotImplemented", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0}: {1}. - /// - internal static string ErrOutErrorPrintFormat { - get { - return ResourceManager.GetString("ErrOutErrorPrintFormat", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to CodeOutlineFilter: line continuation symbol '{0}' should be added to Grammar.NonGrammarTerminals list.. - /// - internal static string ErrOutlineFilterContSymbol { - get { - return ResourceManager.GetString("ErrOutlineFilterContSymbol", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Syntax error, expected: {0}. - /// - internal static string ErrParserUnexpInput { - get { - return ResourceManager.GetString("ErrParserUnexpInput", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Parsed tree is null, cannot evaluate.. - /// - internal static string ErrParseTreeNull { - get { - return ResourceManager.GetString("ErrParseTreeNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Parse tree root is null, cannot evaluate.. - /// - internal static string ErrParseTreeRootNull { - get { - return ResourceManager.GetString("ErrParseTreeRootNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Root AST node is null, cannot evaluate.. - /// - internal static string ErrRootAstNodeNull { - get { - return ResourceManager.GetString("ErrRootAstNodeNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Root AST node does not implement IInterpretedAstNode interface, cannot evaluate.. - /// - internal static string ErrRootAstNoInterface { - get { - return ResourceManager.GetString("ErrRootAstNoInterface", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to ({0}) term passed as 'root' paramater to parserr is not Root or snippet root of the grammar. Add it to SnippetRoots set in grammar constructor.. - /// - internal static string ErrRootNotRegistered { - get { - return ResourceManager.GetString("ErrRootNotRegistered", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Root property of the grammar is not set.. - /// - internal static string ErrRootNotSet { - get { - return ResourceManager.GetString("ErrRootNotSet", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Reduce-reduce conflict. State {0}, lookaheads: {1}. Selected reduce on first production in conflict set.. - /// - internal static string ErrRRConflict { - get { - return ResourceManager.GetString("ErrRRConflict", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Rule for NonTerminal {0} contains null as an operand in position {1} in one of productions.. - /// - internal static string ErrRuleContainsNull { - get { - return ResourceManager.GetString("ErrRuleContainsNull", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Shift-reduce conflict. State {0}, lookaheads [{1}]. Selected shift as preferred action.. - /// - internal static string ErrSRConflict { - get { - return ResourceManager.GetString("ErrSRConflict", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Syntax error.. - /// - internal static string ErrSyntaxErrorNoInfo { - get { - return ResourceManager.GetString("ErrSyntaxErrorNoInfo", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Expression root non-terminal in template settings (AstNodeConfig property) in templated string literal [{0}] is not added to Roots set. Add it to SnippetRoots in grammar constructor.. - /// - internal static string ErrTemplExprNotRoot { - get { - return ResourceManager.GetString("ErrTemplExprNotRoot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Expression root is not specified in template settings (AstNodeConfig property) in templated string literal [{0}]. . - /// - internal static string ErrTemplMissingExprRoot { - get { - return ResourceManager.GetString("ErrTemplMissingExprRoot", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Error in string literal [{0}]: IsTemplate flag is set, but TemplateSettings is not provided in AstNodeConfig property.. - /// - internal static string ErrTemplNoSettings { - get { - return ResourceManager.GetString("ErrTemplNoSettings", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to A terminal {0} has empty prefix.. - /// - internal static string ErrTerminalHasEmptyPrefix { - get { - return ResourceManager.GetString("ErrTerminalHasEmptyPrefix", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Transient non-terminal must have zero or one non-punctuation child nodes; non-terminals: {0}.. - /// - internal static string ErrTransientNtMustHaveOneTerm { - get { - return ResourceManager.GetString("ErrTransientNtMustHaveOneTerm", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unclosed comment block. - /// - internal static string ErrUnclosedComment { - get { - return ResourceManager.GetString("ErrUnclosedComment", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unexpected end of file.. - /// - internal static string ErrUnexpEof { - get { - return ResourceManager.GetString("ErrUnexpEof", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unexpected indentation.. - /// - internal static string ErrUnexpIndent { - get { - return ResourceManager.GetString("ErrUnexpIndent", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Unmatched closing brace '{0}'.. - /// - internal static string ErrUnmatchedCloseBrace { - get { - return ResourceManager.GetString("ErrUnmatchedCloseBrace", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Variable {0} is not a callable function.. - /// - internal static string ErrVarIsNotCallable { - get { - return ResourceManager.GetString("ErrVarIsNotCallable", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Variable {0} not defined.. - /// - internal static string ErrVarNotDefined { - get { - return ResourceManager.GetString("ErrVarNotDefined", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Invalid number of arguments. Expected {0}, found {1}.. - /// - internal static string ErrWrongArgCount { - get { - return ResourceManager.GetString("ErrWrongArgCount", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0}({1}:{2}). - /// - internal static string FmtRowCol { - get { - return ResourceManager.GetString("FmtRowCol", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Accept. - /// - internal static string LabelActionAccept { - get { - return ResourceManager.GetString("LabelActionAccept", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Operator, shift to {0}/reduce on {1}.. - /// - internal static string LabelActionOp { - get { - return ResourceManager.GetString("LabelActionOp", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Reduce on {0}. - /// - internal static string LabelActionReduce { - get { - return ResourceManager.GetString("LabelActionReduce", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Shift to {0}. - /// - internal static string LabelActionShift { - get { - return ResourceManager.GetString("LabelActionShift", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (Unknown action type). - /// - internal static string LabelActionUnknown { - get { - return ResourceManager.GetString("LabelActionUnknown", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (EOF). - /// - internal static string LabelEofMark { - get { - return ResourceManager.GetString("LabelEofMark", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to [end-of-statement]. - /// - internal static string LabelEosLabel { - get { - return ResourceManager.GetString("LabelEosLabel", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (INITIAL STATE). - /// - internal static string LabelInitialState { - get { - return ResourceManager.GetString("LabelInitialState", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (Key symbol). - /// - internal static string LabelKeySymbol { - get { - return ResourceManager.GetString("LabelKeySymbol", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (Keyword). - /// - internal static string LabelKeyword { - get { - return ResourceManager.GetString("LabelKeyword", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to [line break]. - /// - internal static string LabelLineBreak { - get { - return ResourceManager.GetString("LabelLineBreak", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Location:. - /// - internal static string LabelLocation { - get { - return ResourceManager.GetString("LabelLocation", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to .... - /// - internal static string LabelSrcHaveMore { - get { - return ResourceManager.GetString("LabelSrcHaveMore", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (unassigned). - /// - internal static string LabelUnassigned { - get { - return ResourceManager.GetString("LabelUnassigned", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to (unnamed). - /// - internal static string LabelUnnamed { - get { - return ResourceManager.GetString("LabelUnnamed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Abort script(y/n)?. - /// - internal static string MsgAbortScriptYN { - get { - return ResourceManager.GetString("MsgAbortScriptYN", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to {0} Console.\r\nPress Ctrl-C to exit the program.\r\n. - /// - internal static string MsgDefaultConsoleGreeting { - get { - return ResourceManager.GetString("MsgDefaultConsoleGreeting", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Console. - /// - internal static string MsgDefaultConsoleTitle { - get { - return ResourceManager.GetString("MsgDefaultConsoleTitle", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Exit console (y/n)?. - /// - internal static string MsgExitConsoleYN { - get { - return ResourceManager.GetString("MsgExitConsoleYN", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to NLALR transform: Add WrapTail() in '.' position to [{0}].. - /// - internal static string MsgNLALRAdvice { - get { - return ResourceManager.GetString("MsgNLALRAdvice", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Press any key to end the program.. - /// - internal static string MsgPressAnyKeyToExit { - get { - return ResourceManager.GetString("MsgPressAnyKeyToExit", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to "[{0}], at {1}. - /// - internal static string MsgSrcPosToString { - get { - return ResourceManager.GetString("MsgSrcPosToString", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Parsing conflict resolved in code.. - /// - internal static string MsgTraceConflictResolved { - get { - return ResourceManager.GetString("MsgTraceConflictResolved", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Operator - resolved to {0}. - /// - internal static string MsgTraceOpResolved { - get { - return ResourceManager.GetString("MsgTraceOpResolved", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to Popped state from stack, pushing {0}. - /// - internal static string MsgTracePoppedState { - get { - return ResourceManager.GetString("MsgTracePoppedState", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: {0}. - /// - internal static string MsgTraceRecoverAction { - get { - return ResourceManager.GetString("MsgTraceRecoverAction", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to FAILED TO RECOVER. - /// - internal static string MsgTraceRecoverFailed { - get { - return ResourceManager.GetString("MsgTraceRecoverFailed", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: Found state with shift on error : {0}. - /// - internal static string MsgTraceRecoverFoundState { - get { - return ResourceManager.GetString("MsgTraceRecoverFoundState", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: popping stack, looking for state with error shift. - /// - internal static string MsgTraceRecovering { - get { - return ResourceManager.GetString("MsgTraceRecovering", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: Reached end of error production, reducing.. - /// - internal static string MsgTraceRecoverReducing { - get { - return ResourceManager.GetString("MsgTraceRecoverReducing", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: Shifting Error term, {0}. - /// - internal static string MsgTraceRecoverShiftError { - get { - return ResourceManager.GetString("MsgTraceRecoverShiftError", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERING: shifting until the end of error production.. - /// - internal static string MsgTraceRecoverShiftTillEnd { - get { - return ResourceManager.GetString("MsgTraceRecoverShiftTillEnd", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to RECOVERED. - /// - internal static string MsgTraceRecoverSuccess { - get { - return ResourceManager.GetString("MsgTraceRecoverSuccess", resourceCulture); - } - } - } -} diff --git a/sources/shaders/Irony/Resources.resx b/sources/shaders/Irony/Resources.resx deleted file mode 100644 index 3ab10011ec..0000000000 --- a/sources/shaders/Irony/Resources.resx +++ /dev/null @@ -1,442 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Nn - - - Yy - - - Argument list not found in the stack. Expected: ValueList, found: {0}. - - - Cannot convert value from type {0} to type {1}, type converter not defined. - - - Fatal error: - - - Construct '{0}' is not supported (yet) by language implementation. - - - Interpreter error, DataStack.Pop() operation failed - stack is empty. - - - Interpreter is busy. - - - Invalid AstMode value in call to Evaluate method. Node: {0}, mode: {1}. - - - Invalid character: '{0}'. - - - UnExprNode: no implementation for unary operator '{0}'. - - - Attempt to evaluate NULL AST node. The AST node for term '{0}' was not created during parsing. - - - Operator '{0}' is not defined for types {1} and {2}. - - - Operator '{0} not imlemented. - - - {0}: {1} - Location: ErrorMessage - - - Parsed tree is null, cannot evaluate. - - - Parse tree root is null, cannot evaluate. - - - Root AST node is null, cannot evaluate. - - - Root AST node does not implement IInterpretedAstNode interface, cannot evaluate. - - - Variable {0} is not a callable function. - - - Variable {0} not defined. - - - Invalid number of arguments. Expected {0}, found {1}. - - - {0}({1}:{2}) - - - Location: - - - (unassigned) - - - Abort script(y/n)? - - - Exit console (y/n)? - - - Press any key to end the program. - - - Ambiguous grammar, unresolvable reduce-reduce conflicts. State {0}, lookaheads [{1}] - - - Ambiguous grammar, unresolvable shift-reduce conflicts. State {0}, lookaheads [{1}] - - - {0} State {1} on inputs: {2} - - - NLALR process is in indefinite loop, number of states exceeded 3000. - - - Warning: AstNodeType or AstNodeCreator is not set on non-terminals: {0}. - - - ParserDataBuilder error: inadequate state {0}, reduce item '{1}' has no lookaheads. - - - Non-terminal {0} has uninitialized Rule property. - - - Root property of the grammar is not set. - - - Reduce-reduce conflict. State {0}, lookaheads: {1}. Selected reduce on first production in conflict set. - - - Rule for NonTerminal {0} contains null as an operand in position {1} in one of productions. - - - Shift-reduce conflict. State {0}, lookaheads [{1}]. Selected shift as preferred action. - - - NLALR transform: Add WrapTail() in '.' position to [{0}]. - - - Syntax error, expected: {0} - - - [end-of-statement] - - - (unnamed) - - - {0} Console.\r\nPress Ctrl-C to exit the program.\r\n - - - Console - - - Failed to create AST node for non-terminal [{0}], error: {1} - - - Syntax error. - - - Unexpected end of file. - - - Unexpected indentation. - - - Unmatched closing brace '{0}'. - - - Accept - - - Operator, shift to {0}/reduce on {1}. - - - Reduce on {0} - - - Shift to {0} - - - (Unknown action type) - - - (INITIAL STATE) - - - Parsing conflict resolved in code. - - - Operator - resolved to {0} - - - Popped state from stack, pushing {0} - - - FAILED TO RECOVER - - - RECOVERING: popping stack, looking for state with error shift - - - RECOVERED - - - (EOF) - - - ... - - - "[{0}], at {1} - - - Invalid length of char literal - should be a single character. - - - Mal-formed string literal - cannot find termination symbol. - - - Invalid unicode escape ({0}), expected {1} hex digits. - - - Invalid \x escape, at least one digit expected. - - - Duplicate switch '{0}' for regular expression. - - - Cannot convert literal {0} to type {1}. - - - Invalid escape sequence: \{0}. - - - Invalid escape sequence. - - - Invalid escape symbol, expected 'u' or 'U' only. - - - Invalid number. - - - Invalid switch '{0}' for regular expression - - - Error in string literal [{0}]: No start/end symbols specified. - - - No end symbol for regex literal. - - - Number cannot be followed by a letter. - - - Unclosed comment block - - - (Key symbol) - - - (Keyword) - - - [line break] - - - Invalid dedent level, no previous matching indent found. - - - CodeOutlineFilter: line continuation symbol '{0}' should be added to Grammar.NonGrammarTerminals list. - - - RECOVERING: {0} - - - RECOVERING: Found state with shift on error : {0} - - - RECOVERING: Reached end of error production, reducing. - - - RECOVERING: Shifting Error term, {0} - - - RECOVERING: shifting until the end of error production. - - - Could not find a closing quote for quoted value. - - - Invalid arguments for IncDecNode AST node: either first or second argument should be '--' or '++'. - - - Invalide operation, attempt to assign constant or literal value. - - - Error in string literal [{0}]: IsTemplate flag is set, but TemplateSettings is not provided in AstNodeConfig property. - - - Duplicate start symbol {0} in string literal [{1}]. - - - Invalid embedded expression. - - - No ending tag '{0}' found in embedded expression. - - - Expression root non-terminal in template settings (AstNodeConfig property) in templated string literal [{0}] is not added to Roots set. Add it to SnippetRoots in grammar constructor. - - - Expression root is not specified in template settings (AstNodeConfig property) in templated string literal [{0}]. - - - ({0}) term passed as 'root' paramater to parserr is not Root or snippet root of the grammar. Add it to SnippetRoots set in grammar constructor. - - - ImpliedSymbolTerminal cannot be used in grammar with DisableScannerParserLink flag set - - - List non-terminals cannot be marked transient; list: ({0}) - - - Transient non-terminal must have zero or one non-punctuation child nodes; non-terminals: {0}. - - - The last term of production containing SyntaxError must be a terminal. NonTerminal: {0} - - - A terminal {0} has empty prefix. - - - No closing pair for opening symbol {0} - - - NewLine expected. - - \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollBreak.hlsl b/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollBreak.hlsl deleted file mode 100644 index d158b905ca..0000000000 --- a/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollBreak.hlsl +++ /dev/null @@ -1,63 +0,0 @@ -void VSMain(int start2) -{ - float var = 0.0; - - [unroll] - for (int i = 0; i < 7; ++i) - { - var += 1.0; - if (var > 5.5) - { - break; - var += 2.0; - } - } - - [unroll] - for (int i = 0; i < 7; ++i) - { - var += 1.0; - if (var > 5.5) - break; - var += 2.0; - - if (var > 0.3) - break; - var -= 1.0; - } - - [unroll] - for (int i = 0; i < 7; ++i) - { - var += 1.0; - if (var > 5.5) - break; - var += 2.0; - - [unroll] - for (int j = 0; j < 7; ++j) - { - var += 1.0; - if (var > 5.5) - break; - var += 2.0; - } - - if (var > 0.3) - break; - var -= 1.0; - } - - [unroll] - for (int i = 0; i < 7; ++i) - { - var += 1.0; - if (var > 5.5) - continue; - var += 2.0; - - if (var > 0.3) - break; - var -= 1.0; - } -} diff --git a/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollTest.hlsl b/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollTest.hlsl deleted file mode 100644 index 20114e0e5e..0000000000 --- a/sources/shaders/Stride.Core.Shaders.Tests/ShaderES/UnrollTest.hlsl +++ /dev/null @@ -1,75 +0,0 @@ -const float nonUnroll[3] = { 0.01, 0.01, 0.01 }; - -void VSMain(int start2) -{ - float filter[7] = { 0.03007832, 0.10498366, 0.22225042, 0.28537519, 0.22225042, 0.10498366, 0.03007832 }; - - float res = nonUnroll[0]; - - [unroll] - for (int i = 0; i < 7; ++i) - { - res += filter[i]; - } - - [unroll] - for (int i = 0; i < 7; i = i+1) - { - res += filter[i]; - } - - [unroll] - for (int i = 0; i < 7; i += 1) - { - res += filter[i]; - } - - [unroll] - for (int i = 0; i < 7; i += 2) - { - res += filter[i]; - } - - [unroll] - for (int i = 0; i < 7; i += 3) - { - res += filter[i]; - } - - [unroll] - for (int i = 6; i >= 0; i -= 1) - { - res += filter[i]; - } - - [unroll] - for (int i = 4; i == 4; i -= 1) - { - res += filter[i]; - } - - [unroll] - for (int i = 3; i == 4; i -= 1) - { - res += filter[i]; - } - - [unroll] - for (int i = 6; i >= 0; ++i) // produces an error - { - res += filter[i]; - } - - int start = 0; - [unroll] - for (int i = start; i < 7; i = i+1) - { - res += filter[i]; - } - - [unroll] - for (int i = start2; i < 7; i = i+1) - { - res += filter[i]; - } -} diff --git a/sources/shaders/Stride.Core.Shaders.Tests/TestOpenGLES.cs b/sources/shaders/Stride.Core.Shaders.Tests/TestOpenGLES.cs deleted file mode 100644 index 09c5cd251a..0000000000 --- a/sources/shaders/Stride.Core.Shaders.Tests/TestOpenGLES.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Xunit; - -using Stride.Core.IO; -using Stride.Effects; -using Stride.Core.Shaders.Utilities; - -namespace Stride.Core.Shaders.Tests -{ - class TestOpenGLES - { - private void Mount() - { - VirtualFileSystem.MountFileSystem("/assets/shaders", "../../ShaderES"); - } - - [Fact] - public void TestUnroll() - { - Mount(); - - var fileStream = VirtualFileSystem.OpenStream("/assets/shaders/UnrollTest.hlsl", VirtualFileMode.Open, VirtualFileAccess.Read); - var sr = new StreamReader(fileStream); - string source = sr.ReadToEnd(); - fileStream.Close(); - - var compilerES = new Stride.Graphics.ShaderCompiler.OpenGL.ShaderCompiler(true); - compilerES.Compile(source, "VSMain", "vs"); - - var compiler = new Stride.Graphics.ShaderCompiler.OpenGL.ShaderCompiler(); - compiler.Compile(source, "VSMain", "vs"); - } - - [Fact] - public void TestBreak() - { - Mount(); - - var fileStream = VirtualFileSystem.OpenStream("/assets/shaders/UnrollBreak.hlsl", VirtualFileMode.Open, VirtualFileAccess.Read); - var sr = new StreamReader(fileStream); - string source = sr.ReadToEnd(); - fileStream.Close(); - - var compiler = new Stride.Graphics.ShaderCompiler.OpenGL.ShaderCompiler(true); - compiler.Compile(source, "VSMain", "vs"); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/AnalysisBase.cs b/sources/shaders/Stride.Core.Shaders/Analysis/AnalysisBase.cs deleted file mode 100644 index f10f85deeb..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/AnalysisBase.cs +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Analysis -{ - /// - /// Base class for analysis. - /// - public abstract class AnalysisBase : ShaderRewriter - { - /// - /// Initializes a new instance of the class. - /// - /// The result. - protected AnalysisBase(ParsingResult result) : base(true, true) - { - ParsingResult = result; - } - - /// - /// Gets the parsing result. - /// - public ParsingResult ParsingResult { get; private set; } - - /// - /// Runs this instance. - /// - public abstract void Run(); - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - protected void Error(MessageCode message, SourceSpan span) - { - ParsingResult.Error(message, span); - } - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - protected void Error(MessageCode message, SourceSpan span, params object[] parameters) - { - ParsingResult.Error(message, span, parameters); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - protected void Info(string message, SourceSpan span) - { - ParsingResult.Info(message, span); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - protected void Info(string message, SourceSpan span, params object[] parameters) - { - ParsingResult.Info(message, span, parameters); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - protected void Warning(MessageCode message, SourceSpan span) - { - ParsingResult.Warning(message, span); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - protected void Warning(MessageCode message, SourceSpan span, params object[] parameters) - { - ParsingResult.Warning(message, span, parameters); - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// if set to true [is binary operator]. - /// - /// The implicit conversion between between to two types - /// - protected virtual TypeBase GetBinaryImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right, bool isBinaryOperator) - { - var result = CastHelper.GetBinaryImplicitConversionType(left, right, isBinaryOperator); - - if (result == null) - Error(MessageCode.ErrorBinaryTypeDeduction, span, left, right); - - return result; - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// The implicit conversion between between to two types - protected virtual TypeBase GetMultiplyImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right) - { - var result = CastHelper.GetMultiplyImplicitConversionType(left.ResolveType(), right.ResolveType()); - - if (result == null) - Error(MessageCode.ErrorBinaryTypeDeduction, span, left, right); - - return result; - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The span. - /// The left. - /// The right. - /// The implicit conversion between between to two types - protected virtual TypeBase GetDivideImplicitConversionType(SourceSpan span, TypeBase left, TypeBase right) - { - var result = CastHelper.GetDivideImplicitConversionType(left.ResolveType(), right.ResolveType()); - - if (result == null) - Error(MessageCode.ErrorBinaryTypeDeduction, span, left, right); - - return result; - } - - /// - /// Gets the type of the binary implicit scalar conversion. - /// - /// The span. - /// The left. - /// The right. - /// - /// The implicit conversion between the two scalar types - /// - protected ScalarType GetBinaryImplicitScalarConversionType(SourceSpan span, TypeBase left, TypeBase right) - { - var result = CastHelper.GetBinaryImplicitScalarConversionType(left, right); - - if (result == null) - Error(MessageCode.ErrorScalarTypeConversion, span, left, right); - return result; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/CastAnalysis.cs b/sources/shaders/Stride.Core.Shaders/Analysis/CastAnalysis.cs deleted file mode 100644 index 807e890e35..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/CastAnalysis.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Parser; - -namespace Stride.Core.Shaders.Analysis -{ - public class CastAnalysis : Analysis.AnalysisBase - { - public CastAnalysis(ParsingResult result) : base(result) - { - } - - public override Node Visit(UnaryExpression expression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(expression); - - var unaryType = expression.TypeInference.TargetType; - var inputType = expression.Expression.TypeInference.TargetType; - if (unaryType == null || inputType == null) - return expression; - - if (unaryType == ScalarType.Bool && inputType != ScalarType.Bool && expression.Operator == UnaryOperator.LogicalNot) - expression.Expression = new MethodInvocationExpression(new TypeReferenceExpression(ScalarType.Bool), expression.Expression) { TypeInference = { TargetType = ScalarType.Bool } }; - return expression; - } - - public override Node Visit(BinaryExpression expression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(expression); - - var leftType = expression.Left.TypeInference.TargetType; - var rightType = expression.Right.TypeInference.TargetType; - var returnType = expression.TypeInference.ExpectedType ?? expression.TypeInference.TargetType; - - bool isNumericOperator = true; - - switch (expression.Operator) - { - case BinaryOperator.LogicalAnd: - case BinaryOperator.LogicalOr: - isNumericOperator = false; - returnType = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, true); - expression.TypeInference.TargetType = returnType; - break; - case BinaryOperator.Less: - case BinaryOperator.LessEqual: - case BinaryOperator.Greater: - case BinaryOperator.GreaterEqual: - case BinaryOperator.Equality: - case BinaryOperator.Inequality: - isNumericOperator = false; - returnType = GetBinaryImplicitConversionType(expression.Span, leftType, rightType, false); - - TypeBase resultType = ScalarType.Bool; - if (returnType is VectorType) - { - resultType = new VectorType(ScalarType.Bool, ((VectorType)returnType).Dimension); - } - else if (returnType is MatrixType) - { - var matrixType = (MatrixType)returnType; - resultType = new MatrixType(ScalarType.Bool, matrixType.RowCount, matrixType.ColumnCount); - } - expression.TypeInference.TargetType = resultType; - break; - } - - if (returnType != null) - { - if (returnType == ScalarType.Bool && isNumericOperator) - { - var typeToCheck = leftType ?? rightType; - if (typeToCheck != null) - return ConvertExpressionToBool(expression, typeToCheck); - } - } - - if (!isNumericOperator || CastHelper.NeedConvertForBinary(leftType, returnType)) - expression.Left = Cast(leftType, returnType, expression.Left); - if (!isNumericOperator || CastHelper.NeedConvertForBinary(rightType, returnType)) - expression.Right = Cast(rightType, returnType, expression.Right); - - return expression; - } - - private Expression ConvertExpressionToBool(Expression expression, TypeBase typeToCheck) - { - if (typeToCheck != ScalarType.Bool) - return new MethodInvocationExpression(new TypeReferenceExpression(ScalarType.Bool), expression); - return expression; - } - - - public override Node Visit(IfStatement ifStatement) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(ifStatement); - - var conditionType = ifStatement.Condition.TypeInference.TargetType; - if (!(ifStatement.Condition is BinaryExpression || ifStatement.Condition is UnaryExpression)) - { - ifStatement.Condition = ConvertExpressionToBool(ifStatement.Condition, conditionType); - } - - return ifStatement; - } - - public override Node Visit(ConditionalExpression conditionalExpression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(conditionalExpression); - - var leftType = conditionalExpression.Left.TypeInference.TargetType; - var rightType = conditionalExpression.Right.TypeInference.TargetType; - - if (leftType == null || (leftType is ScalarType && !(rightType is ScalarType))) - { - conditionalExpression.Left = Cast(leftType, rightType, conditionalExpression.Left); - } - else - { - conditionalExpression.Right = Cast(rightType, leftType, conditionalExpression.Right); - } - - return conditionalExpression; - } - - - private Expression Cast(TypeBase fromType, TypeBase toType, Expression expression) - { - if (fromType != null && toType != null) - { - if (fromType != toType) - { - var castMethod = new MethodInvocationExpression(new TypeReferenceExpression(toType)); - castMethod.Arguments.Add(expression); - expression = castMethod; - expression.TypeInference.TargetType = toType; - } - } - - return expression; - } - - public override Node Visit(ReturnStatement returnStatement) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(returnStatement); - - if (returnStatement.Value != null) - { - var expressionType = returnStatement.Value.TypeInference.TargetType; - if (expressionType != null) - returnStatement.Value = Cast(expressionType, returnStatement.Value.TypeInference.ExpectedType ?? expressionType, returnStatement.Value); - } - - return returnStatement; - } - - public override Node Visit(Variable variable) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(variable); - - if (variable.InitialValue != null) - { - var expressionType = variable.InitialValue.TypeInference.TargetType; - if (!(expressionType is ObjectType)) - { - variable.InitialValue = Cast(expressionType, variable.Type.ResolveType(), variable.InitialValue); - } - } - - return variable; - } - - public override Node Visit(AssignmentExpression expression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(expression); - - var expressionType = expression.Target.TypeInference.TargetType; - var targetType = expression.Target.TypeInference.ExpectedType ?? expressionType; - expression.Value = Cast(expression.Value.TypeInference.TargetType, targetType, expression.Value); - - return expression; - } - - public override Node Visit(IndexerExpression expression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(expression); - - var indexerType = expression.Index.TypeInference.TargetType; - if (indexerType != null) - { - var baseType = TypeBase.GetBaseType(indexerType); - if (baseType == ScalarType.Float || baseType == ScalarType.Double) - expression.Index = Cast(indexerType, ScalarType.Int, expression.Index); - } - - return expression; - } - - public override Node Visit(MethodInvocationExpression expression) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(expression); - - // Add appropriate cast for all arguments - for (int i = 0; i < expression.Arguments.Count; ++i) - { - var argument = expression.Arguments[i]; - var targetType = argument.TypeInference.TargetType; - if (targetType != null && !(targetType is ObjectType)) - expression.Arguments[i] = Cast(targetType, argument.TypeInference.ExpectedType ?? targetType, argument); - } - - return expression; - } - - /// - public override void Run() - { - Visit(ParsingResult.Shader); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/CastHelper.cs b/sources/shaders/Stride.Core.Shaders/Analysis/CastHelper.cs deleted file mode 100644 index c99644738a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/CastHelper.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Analysis -{ - internal class CastHelper - { - /// - /// Check if convert is necessary - /// - /// Type of the left. - /// Type of the right. - /// True if a cast is necessary between this two types - public static bool NeedConvertForBinary(TypeBase leftType, TypeBase rightType) - { - return leftType != null && rightType != null && leftType != rightType - && - !((leftType is ScalarType && (rightType is VectorType || rightType is MatrixType) && TypeBase.GetBaseType(rightType) == leftType) - || (rightType is ScalarType && (leftType is VectorType || leftType is MatrixType) && TypeBase.GetBaseType(leftType) == rightType)); - } - - /// - /// Gets the type of the binary implicit conversion. - /// - /// The left. - /// The right. - /// if set to true [is boolean operator]. - /// - /// The implicit conversion between between to two types - /// - public static TypeBase GetBinaryImplicitConversionType(TypeBase left, TypeBase right, bool isBooleanOperator) - { - if (left is MatrixType && right is MatrixType) - { - var leftMatrix = (MatrixType)left; - var rightMatrix = (MatrixType)right; - - var leftDimension1 = leftMatrix.RowCount; - var leftDimension2 = leftMatrix.ColumnCount; - var rightDimension1 = rightMatrix.RowCount; - var rightDimension2 = rightMatrix.ColumnCount; - - if (!((leftDimension1 >= rightDimension1 && leftDimension2 >= rightDimension2) || (leftDimension1 <= rightDimension1 && leftDimension2 <= rightDimension2))) - { - return null; - } - - var type = isBooleanOperator ? ScalarType.Bool : GetBinaryImplicitScalarConversionType(leftMatrix.Type.ResolveType(), rightMatrix.Type.ResolveType()); - if (type != null) - return new MatrixType(type, Math.Min(leftDimension1, rightDimension1), Math.Min(leftDimension2, rightDimension2)); - - return null; - } - - // Swap to handle next case with same code (always put bigger type on the left) - // Works for Vector*Matrix, Scalar*Matrix and Scalar*Vector - if (right is MatrixType || (!(left is MatrixType) && !(left is VectorType))) - { - var temp = left; - left = right; - right = temp; - } - - if (left is MatrixType && right is VectorType) - { - var leftMatrix = (MatrixType)left; - var rightVector = (VectorType)right; - - var leftDimension1 = leftMatrix.RowCount; - var leftDimension2 = leftMatrix.ColumnCount; - var rightDimension1 = rightVector.Dimension; - - // Matrix must have at least one dimension (row or column count == 1) - if (leftDimension1 != 1 && leftDimension2 != 1) - { - return null; - } - - var type = isBooleanOperator ? ScalarType.Bool : GetBinaryImplicitScalarConversionType(leftMatrix.Type.ResolveType(), rightVector.Type.ResolveType()); - if (type != null) - return new VectorType(type, Math.Min(Math.Max(leftDimension1, leftDimension2), rightDimension1)); - return null; - } - - if (left is MatrixType) - { - var leftMatrix = (MatrixType)left; - - var leftDimension1 = leftMatrix.RowCount; - var leftDimension2 = leftMatrix.ColumnCount; - - var type = isBooleanOperator ? ScalarType.Bool : GetBinaryImplicitScalarConversionType(leftMatrix.Type.ResolveType(), right); - if (type != null) - return new MatrixType(type, leftDimension1, leftDimension2); - return null; - } - - if (left is VectorType) - { - var leftVector = (VectorType)left; - var leftDimension1 = leftVector.Dimension; - - var rightDimension1 = right is VectorType ? ((VectorType)right).Dimension : 1; - - var rightBaseType = right is VectorType ? ((VectorType)right).Type.ResolveType() : right; - - int dimension = Math.Min(leftDimension1, rightDimension1); - if (rightDimension1 == 1 || leftDimension1 == 1) - dimension = Math.Max(leftDimension1, rightDimension1); - - var type = isBooleanOperator ? ScalarType.Bool : GetBinaryImplicitScalarConversionType(leftVector.Type.ResolveType(), rightBaseType); - if (type != null) return new VectorType(type, dimension); - return null; - } - - return (isBooleanOperator) ? ScalarType.Bool : GetBinaryImplicitScalarConversionType(left, right); - } - - /// - /// Gets the type of the binary implicit conversion in case of a multiplication. - /// - /// the left. - /// the right. - /// The implicit conversion between between to two types - public static TypeBase GetMultiplyImplicitConversionType(TypeBase left, TypeBase right) - { - if ((left is VectorType || left is MatrixType) && right is ScalarType) - return GetMultiplyImplicitConversionType(right, left); - - if (left is ScalarType) - { - TypeBase componentType = null; - if (right is VectorType) { componentType = (right as VectorType).Type; } - else if (right is MatrixType) { componentType = (right as MatrixType).Type; } - - if (componentType != null) - { - ScalarType resultComponentType = null; - if (left == ScalarType.Double || componentType == ScalarType.Double) - resultComponentType = ScalarType.Double; - else if (left == ScalarType.Float || componentType == ScalarType.Float) - resultComponentType = ScalarType.Float; - else if (left == ScalarType.Half || componentType == ScalarType.Half) - resultComponentType = ScalarType.Half; - else if (left == ScalarType.Int || componentType == ScalarType.Int) - resultComponentType = ScalarType.Int; - else if (left == ScalarType.UInt || componentType == ScalarType.UInt) - resultComponentType = ScalarType.UInt; - - if (resultComponentType != null) - { - if (right is VectorType) - return new VectorType(resultComponentType, (right as VectorType).Dimension); - - if (right is MatrixType) - return new MatrixType(resultComponentType, (right as MatrixType).RowCount, (right as MatrixType).ColumnCount); - } - } - } - - return GetBinaryImplicitConversionType(left, right, false); - } - - /// - /// Gets the type of the binary implicit conversion in case of a division - /// - /// the left. - /// the right. - /// The implicit conversion between between to two types - public static TypeBase GetDivideImplicitConversionType(TypeBase left, TypeBase right) - { - if (right is ScalarType) - { - TypeBase componentType = null; - if (left is VectorType) { componentType = (left as VectorType).Type; } - else if (left is MatrixType) { componentType = (left as MatrixType).Type; } - - if (componentType != null) - { - ScalarType resultComponentType = null; - if (left == ScalarType.Double || componentType == ScalarType.Double) - resultComponentType = ScalarType.Double; - else if (left == ScalarType.Float || componentType == ScalarType.Float) - resultComponentType = ScalarType.Float; - else if (left == ScalarType.Half || componentType == ScalarType.Half) - resultComponentType = ScalarType.Half; - else if (left == ScalarType.Int || componentType == ScalarType.Int) - resultComponentType = ScalarType.Int; - else if (left == ScalarType.UInt || componentType == ScalarType.UInt) - resultComponentType = ScalarType.UInt; - - if (resultComponentType != null) - { - if (left is VectorType) - return new VectorType(resultComponentType, (left as VectorType).Dimension); - - if (left is MatrixType) - return new MatrixType(resultComponentType, (left as MatrixType).RowCount, (left as MatrixType).ColumnCount); - } - } - } - - return GetBinaryImplicitConversionType(left, right, false); - } - - /// - /// Gets the type of the binary implicit scalar conversion. - /// - /// The left. - /// The right. - /// - /// The implicit conversion between the two scalar types - /// - public static ScalarType GetBinaryImplicitScalarConversionType(TypeBase left, TypeBase right) - { - if (left is ScalarType && right is ScalarType) - { - if (left == right) - return (ScalarType)left; - - foreach (var type in new[] { ScalarType.Double, ScalarType.Float, ScalarType.Half, ScalarType.UInt, ScalarType.Int, ScalarType.Bool }) - { - if (left == type || right == type) - return type; - } - } - return null; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslDeclarations.h b/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslDeclarations.h deleted file mode 100644 index fe7b2913b4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslDeclarations.h +++ /dev/null @@ -1,670 +0,0 @@ -// --------------------------------------------------------------------------------------- -// Shader Model 4.0 / 4.1 -// --------------------------------------------------------------------------------------- - -// CalculateLevelOfDetail (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/windows/desktop/bb944001%28v=vs.85%29.aspx - -// Gather (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/windows/desktop/bb944003%28v=VS.85%29.aspx - -// GetDimensions (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509693%28v=VS.85%29.aspx - -// GetSamplePosition (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb944004%28v=VS.85%29.aspx - -// Load (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509694%28v=VS.85%29.aspx - -// Sample (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509695%28v=VS.85%29.aspx - -// SampleBias (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb944005%28v=VS.85%29.aspx - -// SampleCmp (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509696%28v=VS.85%29.aspx - -// SampleGrad (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509698%28v=VS.85%29.aspx - -// SampleLevel (DirectX HLSL Texture Object) -// http://msdn.microsoft.com/en-us/library/bb509699%28v=VS.85%29.aspx - -void GroupMemoryBarrierWithGroupSync(); - -class __Texture1D { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float1 x); - void GetDimensions( uint MipLevel, out uint Width, out uint NumberOfLevels); - void GetDimensions( out uint Width); - void GetDimensions( uint MipLevel, out float Width, out float NumberOfLevels); - void GetDimensions( out float Width); - T Load(int2 Location); - T Load(int2 Location, int Offset); - float4 Sample(sampler_state S, float Location); - float4 Sample(sampler_state S, float Location, int Offset); - float4 SampleBias(sampler_state S, float Location, float Bias); - float4 SampleBias(sampler_state S, float Location, float Bias, int Offset); - float SampleCmp(sampler_state S, float Location, float CompareValue); - float SampleCmp(sampler_state S, float Location, float CompareValue, int Offset); - float SampleCmpLevelZero(sampler_state S, float Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float Location, float CompareValue, int Offset); - float4 SampleGrad(sampler_state S, float Location, float DDX, float DDY); - float4 SampleGrad(sampler_state S, float Location, float DDX, float DDY, int Offset); - float4 SampleLevel( sampler_state S, float Location, float LOD); - float4 SampleLevel( sampler_state S, float Location, float LOD, int Offset); - - // SM 5.0 - T mips.operator[][](in uint mipSlice,in uint pos); - - T operator[](in uint pos); -}; - -class __Texture1DArray { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float1 x); - void GetDimensions( uint MipLevel, out uint Width, out uint Elements, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Elements); - void GetDimensions( uint MipLevel, out float Width, out float Elements, out float NumberOfLevels); - void GetDimensions( out float Width, out float Elements); - T Load(int3 Location); - T Load(int3 Location, int Offset); - float4 Sample(sampler_state S, float2 Location); - float4 Sample(sampler_state S, float2 Location, int Offset); - float4 SampleBias(sampler_state S, float2 Location, float Bias); - float4 SampleBias(sampler_state S, float2 Location, float Bias, int Offset); - float SampleCmp(sampler_state S, float2 Location, float CompareValue); - float SampleCmp(sampler_state S, float2 Location, float CompareValue, int Offset); - float SampleCmpLevelZero(sampler_state S, float2 Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float2 Location, float CompareValue, int Offset); - float4 SampleGrad(sampler_state S, float2 Location, float DDX, float DDY); - float4 SampleGrad(sampler_state S, float2 Location, float DDX, float DDY, int Offset); - float4 SampleLevel( sampler_state S, float2 Location, float LOD); - float4 SampleLevel( sampler_state S, float2 Location, float LOD, int Offset); - - // SM 5.0 - T mips.operator[][](in uint mipSlice,in uint2 pos); - - T operator[](in uint2 pos); -}; - -class __Texture2D { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float2 x); - vector<__T_base,4> Gather( sampler_state S, float2 Location); - vector<__T_base,4> Gather( sampler_state S, float2 Location, int2 Offset ); - void GetDimensions( uint MipLevel, out uint Width, out uint Height, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Height); - void GetDimensions( uint MipLevel, out float Width, out float Height, out float NumberOfLevels); - void GetDimensions( out float Width, out float Height); - T Load(int3 Location); - T Load(int3 Location, int2 Offset); - float4 Sample(sampler_state S, float2 Location); - float4 Sample(sampler_state S, float2 Location, int2 Offset); - float4 SampleBias(sampler_state S, float2 Location, float Bias); - float4 SampleBias(sampler_state S, float2 Location, float Bias, int2 Offset); - float SampleCmp(sampler_state S, float2 Location, float CompareValue); - float SampleCmp(sampler_state S, float2 Location, float CompareValue, int2 Offset); - float SampleCmpLevelZero(sampler_state S, float2 Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float2 Location, float CompareValue, int2 Offset); - float4 SampleGrad(sampler_state S, float2 Location, float2 DDX, float2 DDY); - float4 SampleGrad(sampler_state S, float2 Location, float2 DDX, float2 DDY, int2 Offset); - float4 SampleLevel( sampler_state S, float2 Location, float LOD); - float4 SampleLevel( sampler_state S, float2 Location, float LOD, int2 Offset); - - // SM 5.0 - T Gather( - in sampler s, - in float2 location, - in int2 offset - ); - - T GatherRed( - in sampler s, - in float2 location - ); - - T GatherGreen( - in sampler s, - in float2 location - ); - - T GatherBlue( - in sampler s, - in float2 location - ); - - T GatherRed( - in sampler s, - in float2 location, - in int2 offset - ); - - T GatherGreen( - in sampler s, - in float2 location, - in int2 offset - ); - - T GatherBlue( - in sampler s, - in float2 location, - in int2 offset - ); - - T GatherAlpha( - in sampler s, - in float2 location, - in int2 offset - ); - - T GatherRed( - in sampler s, - in float2 location, - in int2 offset1, - in int2 offset2, - in int2 offset3, - in int2 offset4 - ); - - T GatherGreen( - in sampler s, - in float2 location, - in int2 offset1, - in int2 offset2, - in int2 offset3, - in int2 offset4 - ); - - T GatherBlue( - in sampler s, - in float2 location, - in int2 offset1, - in int2 offset2, - in int2 offset3, - in int2 offset4 - ); - - T GatherAlpha( - in sampler s, - in float2 location, - in int2 offset1, - in int2 offset2, - in int2 offset3, - in int2 offset4 - ); - - float4 GatherCmp( - in SamplerComparisonState s, - in float2 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpRed( - in SamplerComparisonState s, - in float2 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpGreen( - in SamplerComparisonState s, - in float2 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpBlue( - in SamplerComparisonState s, - in float2 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpAlpha( - in SamplerComparisonState s, - in float2 location, - in float compare_value, - in int2 offset - ); - - T mips.operator[][](in uint mipSlice, in uint2 pos); - - T operator[](in uint2 pos); -}; - -class __Texture2DArray { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float2 x); - vector<__T_base,4> Gather( sampler_state S, float3 Location, int2 Offset ); - void GetDimensions( uint MipLevel, out uint Width, out uint Height, out uint Elements, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Height, out uint Elements); - void GetDimensions( uint MipLevel, out float Width, out float Height, out float Elements, out float NumberOfLevels); - void GetDimensions( out float Width, out float Height, out float Elements); - T Load(int4 Location); - T Load(int4 Location, int2 Offset); - T Load(int4 Location, int3 Offset); - float4 Sample(sampler_state S, float3 Location); - float4 Sample(sampler_state S, float3 Location, int2 Offset); - float4 SampleBias(sampler_state S, float3 Location, float Bias); - float4 SampleBias(sampler_state S, float3 Location, float Bias, int2 Offset); - float SampleCmp(sampler_state S, float3 Location, float CompareValue); - float SampleCmp(sampler_state S, float3 Location, float CompareValue, int2 Offset); - float SampleCmpLevelZero(sampler_state S, float3 Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float3 Location, float CompareValue, int2 Offset); - float4 SampleGrad(sampler_state S, float3 Location, float2 DDX, float2 DDY); - float4 SampleGrad(sampler_state S, float3 Location, float2 DDX, float2 DDY, int2 Offset); - float4 SampleLevel( sampler_state S, float3 Location, float LOD); - float4 SampleLevel( sampler_state S, float3 Location, float LOD, int2 Offset); - - // SM 5.0 - T Gather( - in sampler s, - in float3 location, - in int2 offset - ); - - T GatherRed( - in sampler s, - in float3 location, - in int2 offset - ); - - T GatherGreen( - in sampler s, - in float3 location, - in int2 offset - ); - - T GatherBlue( - in sampler s, - in float3 location, - in int2 offset - ); - - T GatherAlpha( - in sampler s, - in float3 location, - in int2 offset - ); - - float4 GatherCmp( - in SamplerComparisonState s, - in float3 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpRed( - in SamplerComparisonState s, - in float3 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpGreen( - in SamplerComparisonState s, - in float3 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpBlue( - in SamplerComparisonState s, - in float3 location, - in float compare_value, - in int2 offset - ); - - float4 GatherCmpAlpha( - in SamplerComparisonState s, - in float3 location, - in float compare_value, - in int2 offset - ); - - T mips.operator[][](in uint mipSlice, in uint3 pos); - - T operator[](in uint3 pos); -}; - - -class __Texture3D { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float3 x); - void GetDimensions( uint MipLevel, out uint Width, out uint Height, out uint Depth, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Height, out uint Depth); - void GetDimensions( uint MipLevel, out float Width, out float Height, out float Depth, out float NumberOfLevels); - void GetDimensions( out float Width, out float Height, out float Depth); - T Load(int4 Location); - T Load(int4 Location, int3 Offset); - float4 Sample(sampler_state S, float3 Location); - float4 Sample(sampler_state S, float3 Location, int3 Offset); - float4 SampleBias(sampler_state S, float3 Location, float Bias); - float4 SampleBias(sampler_state S, float3 Location, float Bias, int3 Offset); - float SampleCmp(sampler_state S, float3 Location, float CompareValue); - float SampleCmp(sampler_state S, float3 Location, float CompareValue, int3 Offset); - float4 SampleGrad(sampler_state S, float3 Location, float3 DDX, float3 DDY); - float4 SampleGrad(sampler_state S, float3 Location, float3 DDX, float3 DDY, int3 Offset); - float4 SampleLevel( sampler_state S, float3 Location, float LOD); - float4 SampleLevel( sampler_state S, float3 Location, float LOD, int3 Offset); - - // SM 5.0 - T mips.operator[][](in uint mipSlice,in uint3 pos); - - T operator[](in uint3 pos); -}; - -class __TextureCube { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float3 x); - vector<__T_base,4> Gather( sampler_state S, float3 Location); - void GetDimensions( uint MipLevel, out uint Width, out uint Height, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Height); - void GetDimensions( uint MipLevel, out float Width, out float Height, out uint NumberOfLevels); - void GetDimensions( out float Width, out float Height); - float4 Sample(sampler_state S, float3 Location); - float4 SampleBias(sampler_state S, float3 Location, float Bias); - float SampleCmp(sampler_state S, float3 Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float3 Location, float CompareValue); - float4 SampleGrad(sampler_state S, float3 Location, float3 DDX, float3 DDY); - float4 SampleLevel( sampler_state S, float3 Location, float LOD); -}; - -class __TextureCubeArray { - // SM 4.0 - float CalculateLevelOfDetail( sampler_state s, float3 x); - vector<__T_base,4> Gather( sampler_state S, float4 Location); - void GetDimensions( uint MipLevel, out uint Width, out uint Height, out uint Elements, out uint NumberOfLevels); - void GetDimensions( out uint Width, out uint Height, out uint Elements); - void GetDimensions( uint MipLevel, out float Width, out float Height, out float Elements, out float NumberOfLevels); - void GetDimensions( out float Width, out float Height, out float Elements); - float4 Sample(sampler_state S, float4 Location); - float4 SampleBias(sampler_state S, float4 Location, float Bias); - float SampleCmp(sampler_state S, float4 Location, float CompareValue); - float SampleCmpLevelZero(sampler_state S, float4 Location, float CompareValue); - float4 SampleGrad(sampler_state S, float4 Location, float3 DDX, float3 DDY); - float4 SampleLevel( sampler_state S, float4 Location, float LOD); -}; - -class __Texture2DMS { - // SM 4.0 - void GetDimensions( out uint Width, out uint Height, out uint Samples); - void GetDimensions( out float Width, out float Height, out float Samples); - float2 GetSamplePosition(int s); - T Load(int2 Location); - T Load(int2 Location, int2 Offset); - T Load(int2 Location, int2 Offset, int SampleIndex); - - - // SM 5.0 - float2 GetSamplePosition( - in int sampleindex - ); - - T Load( - in int2 coord, - in int sampleindex - ); - - T sample.operator[][]( in uint sampleSlice, in uint3 pos); -}; - -class __Texture2DMSArray { - // SM 4.0 - void GetDimensions( out uint Width, out uint Height, out uint Elements, out uint Samples); - void GetDimensions( out float Width, out float Height, out float Elements, out float Samples); - float2 GetSamplePosition(int s); - T Load(int3 Location); - T Load(int3 Location, int2 Offset); - T Load(int3 Location, int2 Offset, int SampleIndex); - - // SM 5.0 - float2 GetSamplePosition( - in int sampleindex - ); - - T Load( - in int3 coord, - in int sampleindex - ); - - T sample.operator[][]( in uint sampleSlice, in uint3 pos); -}; - -class __Buffer { - // SM 4.0 - T Load(int Location); - - void GetDimensions(out uint dim); - - T operator[](in uint pos); -}; - -// Stream-Output Object (DirectX HLSL) -// http://msdn.microsoft.com/en-us/library/bb509661%28v=VS.85%29.aspx -// StreamOutputObject Name -// StreamOutputObject: PointStream, LineStream, TriangleStream -class __PointStream { - void Append(T StreamDataType); - void RestartStrip(); -}; - -class __LineStream { - void Append(T StreamDataType); - void RestartStrip(); -}; - -class __TriangleStream { - void Append(T StreamDataType); - void RestartStrip(); -}; - -// --------------------------------------------------------------------------------------- -// Shader Model 5.0 -// --------------------------------------------------------------------------------------- - -// AppendStructuredBuffer -// http://msdn.microsoft.com/en-us/library/ff471448%28v=VS.85%29.aspx -class __AppendStructuredBuffer { - void Append(T value); - void GetDimensions(out uint numStructs, out uint stride); -}; - -// ByteAddressBuffer -// http://msdn.microsoft.com/en-us/library/ff471453%28v=VS.85%29.aspx -class __ByteAddressBuffer { - void GetDimensions(out uint dim); - uint Load(in uint address); - uint2 Load2(in uint address); - uint3 Load3(in uint address); - uint4 Load4(in uint address); -}; - -// ConsumeStructuredBuffer -// http://msdn.microsoft.com/en-us/library/ff471459%28v=VS.85%29.aspx -class __ConsumeStructuredBuffer { - T Consume(void); - void GetDimensions(out uint numStructs, out uint stride); -}; - -// InputPatch -// http://msdn.microsoft.com/en-us/library/ff471462%28v=VS.85%29.aspx -class __InputPatch { - uint Length; - T operator[](in uint n); -}; - -// OutputPatch -// http://msdn.microsoft.com/en-us/library/ff471464%28v=VS.85%29.aspx -class __OutputPatch { - uint Length; - T operator[](in uint n); -}; - -// RWBuffer -// http://msdn.microsoft.com/en-us/library/ff471472%28v=VS.85%29.aspx -class __RWBuffer { - void GetDimensions(out uint dim); - T operator[](in uint pos); -}; - -// RWByteAddressBuffer -// http://msdn.microsoft.com/en-us/library/ff471475%28v=VS.85%29.aspx -class __RWByteAddressBuffer { - void GetDimensions(out uint dim); - void InterlockedAdd(in uint dest, in uint value, out uint original_value); - void InterlockedAnd( - in uint dest, - in uint value, - out uint original_value - ); - void InterlockedCompareExchange( - in uint dest, - in uint compare_value, - in uint value, - out uint original_value - ); - void InterlockedCompareStore( - in uint dest, - in uint compare_value, - in uint value - ); - void InterlockedExchange( - in uint dest, - in uint value, - out uint original_value - ); - void InterlockedMax( - in uint dest, - in uint value, - out uint original_value - ); - void InterlockedMin( - in uint dest, - in uint value, - out uint original_value - ); - void InterlockedOr( - in uint dest, - in uint value, - out uint original_value - ); - void InterlockedXor( - in uint dest, - in uint value, - out uint original_value - ); - uint Load( - in uint address - ); - uint2 Load2( - in uint address - ); - uint3 Load3( - in uint address - ); - uint4 Load4( - in uint address - ); - void Store( - in uint address, - in uint value - ); - void Store2( - in uint address, - in uint2 values - ); - void Store3( - in uint address, - in uint3 values - ); - void Store4( - in uint address, - in uint4 values - ); -}; - -// RWStructuredBuffer -// http://msdn.microsoft.com/en-us/library/ff471494%28v=VS.85%29.aspx -class __RWStructuredBuffer { - - uint DecrementCounter(void); - - void GetDimensions( - out uint numStructs, - out uint stride - ); - - uint IncrementCounter(void); - - T operator[](in uint pos); -}; - -// RWTexture1D -// http://msdn.microsoft.com/en-us/library/ff471499%28v=VS.85%29.aspx -class __RWTexture1D { - void GetDimensions( - out uint Width - ); - T operator[](in uint pos); -}; - -// RWTexture1DArray -// http://msdn.microsoft.com/en-us/library/ff471500%28v=VS.85%29.aspx -class __RWTexture1DArray { - void GetDimensions( - out uint Width, - out uint Elements - ); - - T operator[](in uint2 pos); -}; - -// RWTexture2D -// http://msdn.microsoft.com/en-us/library/ff471505%28v=VS.85%29.aspx -class __RWTexture2D { - void GetDimensions( - out uint Width, - out uint Height - ); - - T operator[](in uint2 pos); -}; - -// RWTexture2DArray -// http://msdn.microsoft.com/en-us/library/ff471506%28v=VS.85%29.aspx -class __RWTexture2DArray { - void GetDimensions( - out uint Width, - out uint Height, - out uint Elements - ); - T operator[](in uint3 pos); -}; - -// RWTexture3D -// http://msdn.microsoft.com/en-us/library/ff471511%28v=VS.85%29.aspx -class __RWTexture3D { - void GetDimensions( - out uint Width, - out uint Height, - out uint Depth - ); - - T operator[](in uint3 pos); -}; - -// StructuredBuffer -// http://msdn.microsoft.com/en-us/library/ff471514%28v=VS.85%29.aspx -class __StructuredBuffer { - void GetDimensions( - out uint numStructs, - out uint stride - ); - - T operator[](in uint pos); -}; \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslSemanticAnalysis.cs b/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslSemanticAnalysis.cs deleted file mode 100644 index a8d45b8d39..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/Hlsl/HlslSemanticAnalysis.cs +++ /dev/null @@ -1,1027 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Stride.Core.Serialization; -using Stride.Core.Shaders.Grammar.Hlsl; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Parser.Hlsl; -using Stride.Core.Shaders.Properties; -using Stride.Core.Shaders.Utility; -using ParameterQualifier = Stride.Core.Shaders.Ast.ParameterQualifier; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Analysis.Hlsl -{ - /// - /// A Type reference analysis is building type references. - /// - [DataSerializerGlobal(null, typeof(List))] - public class HlslSemanticAnalysis : SemanticAnalysis - { - private static readonly Object lockInit = new Object(); - private static bool builtinsInitialized = false; - protected static readonly List defaultDeclarations = new List(); - private static readonly Dictionary BuiltinObjects = new Dictionary(); - private static readonly Dictionary InstanciatedTypes = new Dictionary(); - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The result. - /// - protected HlslSemanticAnalysis(ParsingResult result) : base(result) - { - } - - #endregion - - #region Public Methods - - private static readonly string SwizzleTag = "MatrixSwizzleDecode"; - - - /// - /// Decodes the swizzle. - /// - /// The member reference. - /// The result. - /// - public static List MatrixSwizzleDecode(MemberReferenceExpression memberReference, ParsingResult result = null) - { - string components = memberReference.Member.Text; - - var matrixDecl = (MatrixType)(memberReference.Target.TypeInference.TargetType); - - var span = matrixDecl.Span; - - var swizzles = (List)memberReference.GetTag(SwizzleTag); - if (swizzles != null) - return swizzles; - - swizzles = new List(); - - if (components.StartsWith("_", StringComparison.Ordinal)) - { - string[] splitComponents; - int indexOffset = 0; - if (components.StartsWith("_m", StringComparison.Ordinal)) - { - splitComponents = components.Split(new[] { "_m" }, StringSplitOptions.RemoveEmptyEntries); - } - else - { - splitComponents = components.Split(new[] { "_" }, StringSplitOptions.RemoveEmptyEntries); - indexOffset = 1; - } - - int dimension = 0; - - if (splitComponents.Length == 0 && result != null) - { - result.Error(MessageCode.ErrorMatrixInvalidMemberReference, span, components); - } - - foreach (var splitComponent in splitComponents) - { - if (splitComponent.Length != 2 || !IsValidIndex(span, splitComponent[0], indexOffset, indexOffset + 3) || !IsValidIndex(span, splitComponent[1], indexOffset, indexOffset + 3)) - { - swizzles.Clear(); - break; - } - - swizzles.Add(new MatrixType.Indexer(int.Parse(splitComponent[0].ToString()) - indexOffset, int.Parse(splitComponent[1].ToString()) - indexOffset)); - dimension++; - } - } - - memberReference.SetTag(SwizzleTag, swizzles); - return swizzles; - } - - public override Node Visit(AsmExpression asmExpression) - { - return asmExpression; - } - - public override Node Visit(Ast.Hlsl.Annotations annotations) - { - return annotations; - } - - public override Node Visit(CastExpression castExpression) - { - base.Visit(castExpression); - - var targetType = castExpression.Target.ResolveType(); - castExpression.TypeInference = (TypeInference)castExpression.Target.TypeInference.Clone(); - if (castExpression.TypeInference.TargetType == null) - castExpression.TypeInference.TargetType = targetType; - - return castExpression; - } - - public override Node Visit(MethodInvocationExpression expression) - { - var methodAsVariable = expression.Target as VariableReferenceExpression; - - // We are not parsing CompileShader methods - if (methodAsVariable != null) - { - switch (methodAsVariable.Name.Text) - { - case "ConstructGSWithSO": - case "CompileShader": - return expression; - } - } - - return base.Visit(expression); - } - - - public override Node Visit(CompileExpression compileExpression) - { - // base.Visit(compileExpression); - //Warning("TypeInference on CompileExpression is not handled", compileExpression.Span); - return compileExpression; - } - - public override Node Visit(StateExpression stateExpression) - { - // base.Visit(stateExpression); - // Warning("TypeInference on StateExpression is not handled", stateExpression.Span); - return stateExpression; - } - - public override Node Visit(Technique technique) - { - // Force to not visit a techniques - return technique; - } - - - /// - /// Visits the specified type name. - /// - /// Name of the type. - public override Node Visit(GenericType genericType) - { - base.Visit(genericType); - - string genericName = genericType.Name.Text; - - // Get the case insenti - var value = TextureType.Parse(genericName); - if (value != null) - genericName = value.Name.Text; - - TypeBase typeBase; - if (BuiltinObjects.TryGetValue(genericName, out typeBase)) - { - genericType.TypeInference.TargetType = GetGenericInstance(genericName, genericType, typeBase); - } - - return genericType; - } - - protected override IEnumerable FindDeclarationsFromObject(TypeBase typeBase, string memberName) - { - if (typeBase is ClassType) - { - var classType = (ClassType)typeBase; - - foreach (var declaration in classType.Members.OfType().Where(node => node.Name == memberName)) - yield return declaration; - - foreach (var baseType in classType.BaseClasses) - foreach (var baseDeclaration in FindDeclarationsFromObject(baseType.ResolveType(), memberName)) - yield return baseDeclaration; - } - else if (typeBase is InterfaceType) - { - var interfaceType = (InterfaceType)typeBase; - - foreach (var declaration in interfaceType.Methods.OfType().Where(node => node.Name == memberName)) - yield return declaration; - } - /*else if (typeBase is StructType) - { - var structType = (StructType)typeBase; - foreach (var declaration in structType.Fields.Where(node => node.Name == memberName)) - yield return declaration; - }*/ - } - - protected override void ProcessMethodInvocation(MethodInvocationExpression expression, string methodName, List declarations) - { - // Check for typedef method - if (methodName != null) - { - var varExp = expression.Target as VariableReferenceExpression; - - if (varExp != null) - { - var typeDefDeclarator = declarations.OfType().FirstOrDefault(); - if (typeDefDeclarator != null) - { - varExp.TypeInference.Declaration = typeDefDeclarator; - varExp.TypeInference.TargetType = typeDefDeclarator.ResolveType(); - - expression.TypeInference.Declaration = typeDefDeclarator; - expression.TypeInference.TargetType = typeDefDeclarator.ResolveType(); - return; - } - - //var builtInFunction = defaultDeclarations.FirstOrDefault(x => x.Name.Text == varExp.Name.Text && TestParametersType(expression, x)) as MethodDeclaration; - var builtInFunction = defaultDeclarations.FirstOrDefault(x => (x as MethodDeclaration != null) && (x as MethodDeclaration).IsSameSignature(expression)) as MethodDeclaration; - if (builtInFunction != null) - { - varExp.TypeInference.Declaration = builtInFunction; - varExp.TypeInference.TargetType = builtInFunction.ReturnType.ResolveType(); - - expression.TypeInference.Declaration = builtInFunction; - expression.TypeInference.TargetType = builtInFunction.ReturnType.ResolveType(); - return; - } - } - } - - base.ProcessMethodInvocation(expression, methodName, declarations); - } - - public override Node Visit(TextureType textureType) - { - base.Visit(textureType); - - AssociatePredefinedObjects(textureType); - - return textureType; - } - - private void AssociatePredefinedObjects(TypeBase typebase) - { - // Use the returned name in order to support case insensitive names - TypeBase predefinedType; - if (typebase.TypeInference.TargetType == null && BuiltinObjects.TryGetValue(typebase.Name.Text, out predefinedType)) - { - var textureType = new GenericType(null, 1); - textureType.Parameters[0] = VectorType.Float4; - - typebase.TypeInference.TargetType = GetGenericInstance(typebase.Name.Text, textureType, predefinedType); - } - } - - /// - /// Visits the specified type name. - /// - /// Name of the type. - public override Node Visit(TypeName typeName) - { - base.Visit(typeName); - - var name = typeName.Name.Text; - - // Substitute case insensitive types to case sensitive types - // TODO this is temporary. We need to found a better workaround. - TypeBase value = TextureType.Parse(name); - if (value != null) - { - AssociatePredefinedObjects(value); - return value; - } - - value = StreamTypeName.Parse(name); - if (value != null) - { - AssociatePredefinedObjects(value); - return value; - } - - value = SamplerType.Parse(name); - if (value != null) - return value; - - value = StateType.Parse(name); - if (value != null) - return value; - - value = ByteAddressBufferType.Parse(name); - if (value != null) - { - if (value.TypeInference.TargetType == null && BuiltinObjects.TryGetValue(value.Name, out var predefinedType)) - { - value.TypeInference.TargetType = predefinedType; - } - - return value; - } - - // Replace shader objects - if (name == "VertexShader" || name == "GeometryShader" || name == "PixelShader") - return new ObjectType(name); - - // Else call the base - return base.Visit(typeName); - } - - private static bool IsValidIndex(SourceSpan span, char valueChar, int min, int max, ParsingResult result = null) - { - int value; - var isParseOk = int.TryParse(valueChar.ToString(), out value); - - if (!isParseOk || value < min || value > max) - { - if (result != null) - result.Error(MessageCode.ErrorMatrixInvalidIndex, span, valueChar, min, max); - return false; - } - - return true; - } - - /// - /// Visits the specified member reference. - /// - /// The member reference. - protected override void CommonVisit(MemberReferenceExpression memberReference) - { - var thisType = memberReference.Target.TypeInference.TargetType; - - if (thisType is MatrixType) - { - FindMemberTypeReference((MatrixType)thisType, memberReference); - } - else - { - base.CommonVisit(memberReference); - } - } - - /// - /// Finds the member type reference. - /// - /// Type of the matrix. - /// The member reference. - protected virtual void FindMemberTypeReference(MatrixType matrixType, MemberReferenceExpression memberReference) - { - var components = memberReference.Member.Text; - var span = memberReference.Span; - - // A matrix contains values organized in rows and columns, which can be accessed using the structure operator "." followed by one of two naming sets: - // The zero-based row-column position: - // _m00, _m01, _m02, _m03 - // _m10, _m11, _m12, _m13 - // _m20, _m21, _m22, _m23 - // _m30, _m31, _m32, _m33 - // The one-based row-column position: - // _11, _12, _13, _14 - // _21, _22, _23, _24 - // _31, _32, _33, _34 - // _41, _42, _43, _44 - var swizzles = MatrixSwizzleDecode(memberReference, ParsingResult); - - if (swizzles.Count > 0) - { - var itemType = matrixType.Type.ResolveType(); - memberReference.TypeInference.TargetType = swizzles.Count == 1 ? itemType : new VectorType((ScalarType)itemType, swizzles.Count); - } - } - - #endregion - - #region Methods - - private static TypeBase GetGenericInstance(string typename, GenericBaseType genericType, TypeBase predefinedType) - { - var key = new GenericInstanceKey(typename, genericType.Parameters); - - TypeBase instanciatedType; - lock (InstanciatedTypes) - { - if (!InstanciatedTypes.TryGetValue(key, out instanciatedType)) - { - instanciatedType = genericType.MakeGenericInstance(predefinedType); - InstanciatedTypes.Add(key, instanciatedType); - } - } - return instanciatedType; - } - - protected static void InitializeBuiltins() - { - foreach (var function in Function.Functions) - { - foreach (var p in EnumerateParameters(function.Parameters[0])) - { - var returnType = function.Return(function, new[] { p }); - var parameterTypes = function.ParamList(function, new[] { p }); - - var methodDeclaration = new MethodDeclaration(); - methodDeclaration.IsBuiltin = true; - methodDeclaration.Name = new Identifier(function.Name); - methodDeclaration.ReturnType = returnType; - - foreach (var parameterType in parameterTypes) - methodDeclaration.Parameters.Add( new Ast.Parameter { DeclaringMethod = methodDeclaration, Type = parameterType } ); - - defaultDeclarations.Add(methodDeclaration); - } - } - - defaultDeclarations.AddRange(declaredMethods); - - foreach (var methodDeclaration in declaredMethods) - { - var newMethodDeclaration = new MethodDeclaration(); - newMethodDeclaration.IsBuiltin = true; - newMethodDeclaration.Name = new Identifier(methodDeclaration.Name); - newMethodDeclaration.ReturnType = methodDeclaration.ReturnType; - - foreach (var parameter in methodDeclaration.Parameters) - { - var parameterType = parameter.Type; - if (parameterType.IsSamplerType()) - { - parameterType = SamplerType.Sampler; - } - - newMethodDeclaration.Parameters.Add(new Ast.Parameter { DeclaringMethod = newMethodDeclaration, Type = parameterType }); - } - defaultDeclarations.Add(newMethodDeclaration); - } - - // adding remaining functions that doesn't have multiple versions - defaultDeclarations.Add(GenericMethod("AllMemoryBarrier", TypeBase.Void)); - defaultDeclarations.Add(GenericMethod("AllMemoryBarrierWithGroupSync", TypeBase.Void)); - defaultDeclarations.Add(GenericMethod("D3DCOLORtoUBYTE4", VectorType.Int4, GenericParam("x", VectorType.Float4))); - defaultDeclarations.Add(GenericMethod("DeviceMemoryBarrier", TypeBase.Void)); - defaultDeclarations.Add(GenericMethod("DeviceMemoryBarrierWithGroupSync", TypeBase.Void)); - defaultDeclarations.Add(GenericMethod("GetRenderTargetSampleCount", ScalarType.UInt)); - defaultDeclarations.Add(GenericMethod("GetRenderTargetSamplePosition", ScalarType.UInt, GenericParam("x", ScalarType.Int))); - defaultDeclarations.Add(GenericMethod("GroupMemoryBarrier", TypeBase.Void)); - } - - public static List ParseBuiltin(string builtins, string fileName) - { - var builtinDeclarations = new List(); - - var result = HlslParser.TryPreProcessAndParse(builtins, fileName); - - // Check that we parse builtins successfully. - var shader = ShaderParser.Check(result, fileName); - - foreach (var declaration in shader.Declarations) - { - var classType = declaration as ClassType; - if (classType != null) - { - classType.Name.Text = classType.Name.Text.Trim('_'); - BuiltinObjects.Add(classType.Name.Text, classType); - classType.IsBuiltIn = true; - } - else if (declaration is IDeclaration) - { - var methodDeclaration = declaration as MethodDeclaration; - if (methodDeclaration != null) - methodDeclaration.IsBuiltin = true; - builtinDeclarations.Add((IDeclaration)declaration); - } - } - - var tempAnalysis = new HlslSemanticAnalysis(result); - tempAnalysis.Run(); - - return builtinDeclarations; - } - - /// - /// Create the required declarations for hlsl parsing - /// - /// the list of declarations - protected void SetupHlslAnalyzer(List builtinDeclarations = null) - { - StaticInitializeBuiltins(); - - // Add all default declarations - ScopeStack.Peek().AddDeclarations(defaultDeclarations); - - if (builtinDeclarations != null) - { - this.ScopeStack.Peek().AddDeclarations(builtinDeclarations); - - // Tag all method declared as user defined - foreach (var builtinDeclaration in builtinDeclarations) - { - var methodDeclaration = builtinDeclaration as MethodDeclaration; - if (methodDeclaration != null) - methodDeclaration.SetTag(TagBuiltinUserDefined, true); - } - } - } - - /// - /// Fill the clone context with the elements of the default declarations - /// - /// the CloneContext - public static void FillCloneContext(CloneContext cloneContext) - { - StaticInitializeBuiltins(); - - foreach (var decl in defaultDeclarations) - DeepCloner.DeepCollect(decl, cloneContext); - - foreach (var bInObj in BuiltinObjects) - DeepCloner.DeepCollect(bInObj.Value, cloneContext); - - UpdateCloneContext(cloneContext); - } - - /// - /// Update the clone context with the new instanciated classes - /// - /// the CloneContext - public static void UpdateCloneContext(CloneContext cloneContext) - { - lock (InstanciatedTypes) - { - foreach (var instType in InstanciatedTypes) - { - if (instType.Key.GenericParameters.Any(x => x is TypeName)) - continue; - DeepCloner.DeepCollect(instType.Value, cloneContext); - } - } - } - - public static void Run(ParsingResult toParse, List builtinDeclarations = null) - { - var analysis = new HlslSemanticAnalysis(toParse); - analysis.SetupHlslAnalyzer(builtinDeclarations); - analysis.Run(); - } - - private static void StaticInitializeBuiltins() - { - lock (lockInit) - { - if (!builtinsInitialized) - { - // Add builtins - defaultDeclarations.AddRange(ParseBuiltin(Resources.HlslDeclarations, "internal_hlsl_declarations.hlsl")); - InitializeBuiltins(); - builtinsInitialized = true; - } - } - } - - private static MethodDeclaration[] declaredMethods = new MethodDeclaration[] - { - // ----------------------------------------- - // tex1D functions - // ----------------------------------------- - - // ret tex1D(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509672%28v=VS.85%29.aspx - GenericMethod("tex1D", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", ScalarType.Float)), - - // ret tex1D(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/ff471388%28v=VS.85%29.aspx - GenericMethod("tex1D", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", ScalarType.Float), GenericParam("ddx", ScalarType.Float), GenericParam("ddy", ScalarType.Float)), - - // ret tex1Dbias(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509673%28v=VS.85%29.aspx - GenericMethod("tex1Dbias", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", VectorType.Float4)), - - // ret tex1Dgrad(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509674%28v=VS.85%29.aspx - GenericMethod("tex1Dgrad", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", ScalarType.Float), GenericParam("ddx", ScalarType.Float), GenericParam("ddy", ScalarType.Float)), - - // ret tex1Dlod(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509675%28v=VS.85%29.aspx - GenericMethod("tex1Dlod", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", VectorType.Float4)), - - // ret tex1Dproj(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509676%28v=VS.85%29.aspx - GenericMethod("tex1Dproj", VectorType.Float4, GenericParam("s", SamplerType.Sampler1D), GenericParam("t", VectorType.Float4)), - - // ----------------------------------------- - // tex2D functions - // ----------------------------------------- - - // ret tex2D(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509677%28v=VS.85%29.aspx - GenericMethod("tex2D", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float2)), - - // ret tex2D(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/ff471389%28v=VS.85%29.aspx - GenericMethod("tex2D", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float2), GenericParam("ddx", VectorType.Float2), GenericParam("ddy", VectorType.Float2)), - - // ret tex2Dbias(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509678%28v=VS.85%29.aspx - GenericMethod("tex2Dbias", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float4)), - - // ret tex2Dgrad(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509679%28v=VS.85%29.aspx - GenericMethod("tex2Dgrad", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float2), GenericParam("ddx", VectorType.Float2), GenericParam("ddy", VectorType.Float2)), - - // ret tex2Dlod(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509680%28v=VS.85%29.aspx - GenericMethod("tex2Dlod", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float4)), - - // ret tex2Dproj(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509681%28v=VS.85%29.aspx - GenericMethod("tex2Dproj", VectorType.Float4, GenericParam("s", SamplerType.Sampler2D), GenericParam("t", VectorType.Float4)), - - // ----------------------------------------- - // tex3D functions - // ----------------------------------------- - - // ret tex3D(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509682%28v=VS.85%29.aspx - GenericMethod("tex3D", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float3)), - - // ret tex3D(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/ff471391%28v=VS.85%29.aspx - GenericMethod("tex3D", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float3), GenericParam("ddx", VectorType.Float3), GenericParam("ddy", VectorType.Float3)), - - // ret tex3Dbias(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509683%28v=VS.85%29.aspx - GenericMethod("tex3Dbias", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float4)), - - // ret tex3Dgrad(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509684%28v=VS.85%29.aspx - GenericMethod("tex3Dgrad", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float3), GenericParam("ddx", VectorType.Float3), GenericParam("ddy", VectorType.Float3)), - - // ret tex3Dlod(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509685%28v=VS.85%29.aspx - GenericMethod("tex3Dlod", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float4)), - - // ret tex3Dproj(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509686%28v=VS.85%29.aspx - GenericMethod("tex3Dproj", VectorType.Float4, GenericParam("s", SamplerType.Sampler3D), GenericParam("t", VectorType.Float4)), - - // ----------------------------------------- - // texCUBE functions - // ----------------------------------------- - - // ret texCUBE(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509687%28v=VS.85%29.aspx - GenericMethod("texCUBE", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float3)), - - // ret texCUBE(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/ff471392%28v=VS.85%29.aspx - GenericMethod("texCUBE", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float3), GenericParam("ddx", VectorType.Float3), GenericParam("ddy", VectorType.Float3)), - - // ret texCUBEbias(s, t) : http://msdn.microsoft.com/en-us/library/windows/desktop/bb509688%28v=VS.85%29.aspx - GenericMethod("texCUBEbias", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float4)), - - // ret texCUBEgrad(s, t, ddx, ddy) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509689%28v=VS.85%29.aspx - GenericMethod("texCUBEgrad", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float3), GenericParam("ddx", VectorType.Float3), GenericParam("ddy", VectorType.Float3)), - - // ret texCUBElod(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509690%28v=VS.85%29.aspx - GenericMethod("texCUBElod", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float4)), - - // ret texCUBEproj(s, t) http://msdn.microsoft.com/en-us/library/windows/desktop/bb509691%28v=VS.85%29.aspx - GenericMethod("texCUBEproj", VectorType.Float4, GenericParam("s", SamplerType.SamplerCube), GenericParam("t", VectorType.Float4)), - - //// tex2Dlod(s, t) - //GenericMethod("tex2Dlod", VectorType.Float4, GenericContraint("SamplerState", type => type == StateType.SamplerState || type == StateType.SamplerStateOld), - // GenericParam("s", "SamplerState"), GenericParam("t", VectorType.Float4)), - }; - - private static List GenericContraint(string genericT1, Func checkT1) - { - return new List() { new GenericParameterConstraint(genericT1, checkT1) }; - } - - private static List GenericContraint(string genericT1, Func checkT1, string genericT2, Func checkT2) - { - return new List() { new GenericParameterConstraint(genericT1, checkT1), new GenericParameterConstraint(genericT2, checkT2), }; - } - - private static Ast.Parameter GenericParam(string paramName, string genericTypeName) - { - return new Ast.Parameter() { Name = new Identifier(paramName), Type = new GenericParameterType(genericTypeName) }; - } - - private static Ast.Parameter GenericParam(string paramName, TypeBase type) - { - return new Ast.Parameter() { Name = new Identifier(paramName), Type = type }; - } - - private static Ast.Parameter GenericParam(string paramName, TypeBase type, Qualifier qualifier) - { - return new Ast.Parameter() { Name = new Identifier(paramName), Type = type, Qualifiers = qualifier }; - } - - private static MethodDeclaration GenericMethod(string methodName, TypeBase returnType, params Ast.Parameter[] parameters) - { - return GenericMethod(methodName, returnType, null, parameters); - } - - private static MethodDeclaration GenericMethod(string methodName, TypeBase returnType, List constraints, params Ast.Parameter[] parameters) - { - var methodDeclaration = new MethodDeclaration() { Name = new Identifier(methodName), ReturnType = returnType }; - methodDeclaration.IsBuiltin = true; - if (constraints != null) - methodDeclaration.ParameterConstraints = constraints; - methodDeclaration.Parameters.AddRange(parameters); - return methodDeclaration; - } - - - static TypeBase[] FloatTargets = new[] { ScalarType.Float, ScalarType.Double }; - static TypeBase[] NumericTargets = new[] { ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt }; - static TypeBase[] NumericAndBoolTargets = new[] { ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Bool }; - - class ParamDef - { - public string Name { get; set; } - public Func ParamDecl { get; set; } - public bool Out { get; set; } - } - class Function - { - public static ParamDef Param(int index) - { - return new ParamDef { Name = "ret", ParamDecl = (f, p) => p[index].GenerateType() }; - } - - public static ParamDef ParamVoid() - { - return new ParamDef { Name = "ret", ParamDecl = (f, p) => TypeBase.Void }; - } - - public static ParamDef Param(string name, int index, bool outParam = false) - { - return new ParamDef { Name = name, ParamDecl = (f, p) => p[index].GenerateType(), Out = outParam }; - } - public static ParamDef Param(Func paramDecl) - { - return new ParamDef { Name = "ret", ParamDecl = paramDecl }; - } - public static ParamDef Param(string name, Func paramDecl) - { - return new ParamDef { Name = name, ParamDecl = paramDecl }; - } - public string Name { get; set; } - public ParameterInfo[] Parameters { get; set; } - public Func ParamList { get; set; } - public Func Return { get; set; } - public static Function Template1(string name, Target[] targets, TypeBase[] targetTypes, ParamDef ret, params ParamDef[] args) - { - var p = new ParameterInfo { Targets = targets, TargetTypes = targetTypes, SizeFlags = SizeFlags.None }; - return new Function { Name = name, Parameters = new[] { p }, ParamList = (f, p2) => args.Select(arg => arg.ParamDecl(f, p2)).ToArray(), Return = (f, p2) => ret.ParamDecl(f, p2) }; - } - public static Function[] Functions = new[] - { - // Missing5: dst EvaluateAttribute - Template1("InterlockedAdd", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedAdd", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("InterlockedAnd", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedAnd", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("InterlockedCompareExchange", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("compare_value", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedCompareStore", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("compare_value", 0), Param("value", 0)), - Template1("InterlockedExchange", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedMax", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedMax", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("InterlockedMin", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedMin", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("InterlockedOr", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedOr", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("InterlockedXor", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0), Param("original_value", 0, outParam: true)), - Template1("InterlockedXor", new[] { Target.Scalar }, new[] {ScalarType.Int, ScalarType.UInt }, Param((f, p) => TypeBase.Void), Param("dest", 0), Param("value", 0)), - Template1("abs", AllTargets, NumericTargets, Param(0), Param("x", 0)), - Template1("acos", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("all", AllTargets, NumericAndBoolTargets, Param((f, p) => ScalarType.Bool), Param("x", 0)), - //Template1("AllMemoryBarrier", new[] { Target.Scalar }, new TypeBase[] { ScalarType.Float }, ParamVoid()), - //Template1("AllMemoryBarrierWithGroupSync", new[] { Target.Scalar }, new TypeBase[] { ScalarType.Float }, ParamVoid()), - Template1("any", AllTargets, NumericAndBoolTargets, Param((f, p) => ScalarType.Bool), Param("x", 0)), - Template1("asdouble", new[] { Target.Scalar, Target.Vector2 }, new TypeBase[] { ScalarType.UInt }, Param((f,p) => p[0].ChangeTargetType(ScalarType.Double).GenerateType()), Param("l",0), Param("h",0)), - Template1("asfloat", AllTargets, new TypeBase[] { ScalarType.Bool, ScalarType.Float, ScalarType.Int, ScalarType.UInt }, Param((f,p) => p[0].ChangeTargetType(ScalarType.Float).GenerateType()), Param("x", 0)), - Template1("asin", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("asint", AllTargets, new TypeBase[] { ScalarType.Float, ScalarType.UInt }, Param((f,p) => p[0].ChangeTargetType(ScalarType.Int).GenerateType()), Param("x", 0)), - Template1("asuint", AllTargets, new TypeBase[] { ScalarType.Float, ScalarType.Int }, Param((f,p) => p[0].ChangeTargetType(ScalarType.UInt).GenerateType()), Param("x", 0)), - Template1("asuint", new[] { Target.Scalar }, new TypeBase[] { ScalarType.UInt }, ParamVoid(), Param("x", (f,p)=> p[0].ChangeTargetType(ScalarType.Double).GenerateType()), Param("y", 0, true), Param("z", 0, true)), - Template1("atan", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("atan2", AllTargets, FloatTargets, Param(0), Param("y", 0), Param("x", 0)), - Template1("ceil", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("clamp", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("min", 0), Param("max", 0)), - Template1("clip", AllTargets, NumericTargets, ParamVoid(), Param("x", 0)), - Template1("cos", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("cosh", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("countbits", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.UInt }, Param(0), Param("x", 0)), - Template1("cross", new[] { Target.Vector3 }, FloatTargets, Param(0), Param("x", 0), Param("y", 0)), - //Template1("D3DCOLORtoUBYTE4", new[] { Target.Vector4 }, new TypeBase[] { ScalarType.Float }, Param((f,p) => VectorType.Int4), Param("x", 0)), - Template1("ddx", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("ddx_coarse", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Float }, Param(0), Param("x", 0)), - Template1("ddx_fine", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Float }, Param(0), Param("x", 0)), - Template1("ddy", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("ddy_coarse", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Float }, Param(0), Param("x", 0)), - Template1("ddy_fine", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Float }, Param(0), Param("x", 0)), - Template1("degrees", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("determinant", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("x", 0)), - Template1("distance", new[] { Target.Vector }, FloatTargets, Param((f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("x", 0), Param("y", 0)), - Template1("dot", new[] { Target.Vector }, NumericTargets, Param((f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("x", 0), Param("y", 0)), - Template1("EvaluateAttributeAtCentroid", AllTargets, NumericTargets, Param(0), Param("x", 0)), - Template1("EvaluateAttributeAtSample", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("s", (f,p) => ScalarType.UInt)), - Template1("EvaluateAttributeSnapped", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("s", (f,p) => VectorType.Int2)), - Template1("exp", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("exp2", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("f16tof32", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.UInt }, Param((f,p) => p[0].ChangeTargetType(ScalarType.Float).GenerateType()), Param("x",0)), - Template1("f32tof16", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Float }, Param((f,p) => p[0].ChangeTargetType(ScalarType.UInt).GenerateType()), Param("x",0)), - Template1("faceforward", new[] { Target.Vector }, FloatTargets, Param(0), Param("n", 0), Param("i", 0), Param("ng", 0)), - Template1("firstbithigh", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.Int, ScalarType.UInt }, Param(0), Param("x", 0)), - Template1("firstbitlow", new[] { Target.Scalar }, new TypeBase[] { ScalarType.Int }, Param(0), Param("x", 0)), - Template1("firstbitlow", new[] { Target.Vector2, Target.Vector3, Target.Vector4 }, new TypeBase[] { ScalarType.UInt }, Param(0), Param("x", 0)), - Template1("floor", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("fmod", AllTargets, FloatTargets, Param(0), Param("x", 0), Param("y", 0)), - Template1("frac", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("frexp", AllTargets, FloatTargets, Param(0), Param("x", 0), Param("exp", 0)), - Template1("fwidth", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("isfinite", AllTargets, FloatTargets, Param((f, p) => p[0].ChangeTargetType(ScalarType.Bool).GenerateType()), Param("x", 0)), - Template1("isinf", AllTargets, FloatTargets, Param((f, p) => p[0].ChangeTargetType(ScalarType.Bool).GenerateType()), Param("x", 0)), - Template1("isnan", AllTargets, FloatTargets, Param((f, p) => p[0].ChangeTargetType(ScalarType.Bool).GenerateType()), Param("x", 0)), - Template1("ldexp", AllTargets, FloatTargets, Param(0), Param("x", 0), Param("exp", 0)), - Template1("length", new[] { Target.Vector }, FloatTargets, Param((f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("x", 0)), - Template1("lerp", AllTargets, FloatTargets, Param(0), Param("x", 0), Param("y", 0), Param("s", 0)), - Template1("lit", new[] { Target.Scalar }, FloatTargets, Param((f, p) => VectorType.Float4), Param("n_dot_l", 0), Param("n_dot_h", 0), Param("m", 0)), - Template1("log", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("log10", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("log2", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("mad", new[] { Target.Scalar, Target.Vector }, NumericTargets, Param(0), Param("x", 0), Param("y", 0), Param("z", 0)), - Template1("max", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("y", 0)), - Template1("min", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("y", 0)), - Template1("modf", AllTargets, NumericTargets, Param(0), Param("x", 0), Param("ip", 0, outParam: true)), - Template1("mul", new[] { Target.Scalar }, FloatTargets, Param(0), Param("x", 0), Param("y", 0)), // Group 1 - Template1("mul", new[] { Target.Vector }, FloatTargets, Param(0), Param("x", (f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("y", 0)), // Group 2 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param(0), Param("x", (f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("y", 0)), // Group 3 - Template1("mul", new[] { Target.Vector }, FloatTargets, Param(0), Param("x", 0), Param("y", (f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType())), // Group 4 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param(0), Param("x", 0), Param("y", (f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType())), // Group 7 - Template1("mul", new[] { Target.Vector }, FloatTargets, Param((f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType()), Param("x", 0), Param("y", 0)), // Group 5 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].ReduceFromMatrixColumn().GenerateType()), Param("x", (f, p) => p[0].ReduceFromMatrixRow().GenerateType()), Param("y", 0)), // Group 6 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].ReduceFromMatrixRow().GenerateType()), Param("x", 0), Param("y", (f, p) => p[0].ReduceFromMatrixColumn().GenerateType())), // Group 8 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].MakeMatrix(p[0].RowCount, 1).GenerateType()), Param("x", 0), Param("y", (f, p) => p[0].MakeMatrix(p[0].ColumnCount, 1).GenerateType())), // Group 9 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].MakeMatrix(p[0].RowCount, 2).GenerateType()), Param("x", 0), Param("y", (f, p) => p[0].MakeMatrix(p[0].ColumnCount, 2).GenerateType())), // Group 9 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].MakeMatrix(p[0].RowCount, 3).GenerateType()), Param("x", 0), Param("y", (f, p) => p[0].MakeMatrix(p[0].ColumnCount, 3).GenerateType())), // Group 9 - Template1("mul", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].MakeMatrix(p[0].RowCount, 4).GenerateType()), Param("x", 0), Param("y", (f, p) => p[0].MakeMatrix(p[0].ColumnCount, 4).GenerateType())), // Group 9 - Template1("normalize", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("pow", AllTargets, FloatTargets, Param(0), Param("x", 0), Param("y", 0)), - Template1("radians", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("rcp", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("reflect", new[] { Target.Vector }, FloatTargets, Param(0), Param("i", 0), Param("n", 0)), - Template1("refract", new[] { Target.Vector }, FloatTargets, Param(0), Param("i", 0), Param("n", 0), Param("index", (f, p) => p[0].ChangeTarget(Target.Scalar).GenerateType())), - Template1("reversebits", new[] { Target.Scalar, Target.Vector }, new TypeBase[] { ScalarType.UInt }, Param(0), Param("x", 0)), - Template1("round", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("rsqrt", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("saturate", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("sign", AllTargets, NumericTargets, Param((f, p) => p[0].ChangeTargetType(ScalarType.Int).GenerateType()), Param("x", 0)), - Template1("sin", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("sincos", AllTargets, FloatTargets, Param((f, p) => TypeBase.Void), Param("x", 0), Param("s", 0, outParam: true), Param("c", 0, outParam: true)), - Template1("sinh", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("smoothstep", AllTargets, FloatTargets, Param(0), Param("min", 0), Param("max", 0), Param("x", 0)), - Template1("sqrt", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("step", AllTargets, FloatTargets, Param(0), Param("y", 0), Param("x", 0)), - Template1("tan", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("tanh", AllTargets, FloatTargets, Param(0), Param("x", 0)), - Template1("transpose", new[] { Target.Matrix }, FloatTargets, Param((f, p) => p[0].Transpose().GenerateType()), Param("x", 0)), - Template1("trunc", AllTargets, FloatTargets, Param(0), Param("x", 0)), - }; - } - static Target[] AllTargets = new[] { Target.Scalar, Target.Vector, Target.Matrix }; - enum Target - { - Scalar = 1, - Vector = 2, - SquareMatrix = 3, - Matrix = 4, - Vector2 = 5, - Vector3 = 6, - Vector4 = 7, - } - [Flags] - enum SizeFlags - { - None = 0, - AllMatrix = 1, - } - class ParameterInfo - { - public IList Targets; - public IList TargetTypes; - public SizeFlags SizeFlags; - } - class Parameter - { - public Parameter ChangeTarget(Target target) - { - return new Parameter { Target = target, TargetType = TargetType, TargetSize = TargetSize }; - } - public Parameter ChangeTargetType(TypeBase targetType) - { - return new Parameter { Target = Target, TargetType = targetType, TargetSize = TargetSize }; - } - public Parameter MakeMatrix(int rowCount, int columnCount) - { - return new Parameter { Target = Target.Matrix, TargetType = TargetType, TargetSize = (columnCount - 1) * 4 + rowCount - 1 }; - } - public Parameter ReduceFromMatrixRow() - { - return new Parameter { Target = Target.Vector, TargetType = TargetType, TargetSize = TargetSize % 4 }; - } - public Parameter ReduceFromMatrixColumn() - { - return new Parameter { Target = Target.Vector, TargetType = TargetType, TargetSize = TargetSize / 4 }; - } - public Parameter Transpose() - { - int row = TargetSize % 4; - int column = TargetSize / 4; - return new Parameter { Target = Target, TargetType = TargetType, TargetSize = row * 4 + column }; - } - public int RowCount { get { return (TargetSize % 4) + 1; } } - public int ColumnCount { get { return (TargetSize / 4) + 1; } } - public Target Target { get; set; } - public TypeBase TargetType { get; set; } - public int TargetSize { get; set; } - - public TypeBase GenerateType() - { - if (Target == Target.Matrix) - return new MatrixType((ScalarType)TargetType, RowCount, ColumnCount); - if (Target == Target.Vector) - return new VectorType((ScalarType)TargetType, RowCount); - if (Target == Target.Vector2) - return new VectorType((ScalarType)TargetType, 2); - if (Target == Target.Vector3) - return new VectorType((ScalarType)TargetType, 3); - if (Target == Target.Vector4) - return new VectorType((ScalarType)TargetType, 4); - return TargetType; - } - } - - static IEnumerable EnumerateParameters(ParameterInfo p) - { - for (int target = 0; target < p.Targets.Count(); ++target) - { - for (int targetType = 0; targetType < p.TargetTypes.Count(); ++targetType) - { - switch (p.Targets[target]) - { - case Target.Scalar: - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = 1 }; - break; - case Target.Vector: - case Target.SquareMatrix: - for (int i = 0; i < 4; ++i) - { - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = i }; - } - break; - case Target.Vector2: - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = 1 }; - break; - case Target.Vector3: - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = 2 }; - break; - case Target.Vector4: - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = 3 }; - break; - case Target.Matrix: - for (int i = 0; i < 16; ++i) - { - yield return new Parameter { Target = p.Targets[target], TargetType = p.TargetTypes[targetType], TargetSize = i }; - } - break; - } - } - } - } - - #endregion - } - - - internal class GenericInstanceKey - { - public string GenericName; - - public List GenericParameters; - - public GenericInstanceKey(string genericName, List genericParams) - { - GenericName = genericName; - GenericParameters = genericParams; - } - - public override bool Equals(object obj) - { - var genInstKey = obj as GenericInstanceKey; - if (genInstKey == null) - return false; - - if (GenericParameters.Count != genInstKey.GenericParameters.Count) - return false; - - bool res = true; - for (int i = 0; i < GenericParameters.Count; ++i) - res &= GenericParameters[i] == genInstKey.GenericParameters[i]; - - return res; - } - - public override int GetHashCode() - { - return (GenericName.GetHashCode() * 397);// ^ ; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Analysis/SemanticAnalysis.cs b/sources/shaders/Stride.Core.Shaders/Analysis/SemanticAnalysis.cs deleted file mode 100644 index 2b4527316c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Analysis/SemanticAnalysis.cs +++ /dev/null @@ -1,853 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Analysis -{ - /// - /// A Type reference analysis is building type references. - /// - public class SemanticAnalysis : AnalysisBase - { - protected static string TagBuiltinUserDefined = "TagBuiltinUserDefined"; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// The result. - /// - public SemanticAnalysis(ParsingResult result) - : base(result) - { - } - #endregion - - /// - /// Gets or sets a value indicating whether the analysis is in skipping mode. - /// - /// - /// true if the analysis is in skipping mode; otherwise, false. - /// - protected bool IsSkippingMode { get; set; } - - #region Public Methods - - /// - public override void Run() - { - Visit(ParsingResult.Shader); - } - - /// - /// Visits the specified assignement expression. - /// - /// The assignement expression. - public override Node Visit(AssignmentExpression assignmentExpression) - { - base.Visit(assignmentExpression); - - // An assignment expression get the - assignmentExpression.TypeInference = (TypeInference)assignmentExpression.Target.TypeInference.Clone(); - - // TODO: check if types are compatible? - return assignmentExpression; - } - - /// - /// Visits the specified binary expression. - /// - /// The binary expression. - public override Node Visit(BinaryExpression binaryExpression) - { - base.Visit(binaryExpression); - - var leftType = binaryExpression.Left.TypeInference.TargetType; - var rightType = binaryExpression.Right.TypeInference.TargetType; - - // No need to log an error as it has been done by the initial base.Visit( - if (leftType == null || rightType == null) return binaryExpression; - - switch (binaryExpression.Operator) - { - case BinaryOperator.Multiply: - binaryExpression.TypeInference.TargetType = GetMultiplyImplicitConversionType(binaryExpression.Span, leftType, rightType); - break; - case BinaryOperator.Divide: - binaryExpression.TypeInference.TargetType = GetDivideImplicitConversionType(binaryExpression.Span, leftType, rightType); - break; - case BinaryOperator.Minus: - case BinaryOperator.Plus: - case BinaryOperator.Modulo: - case BinaryOperator.LogicalAnd: - case BinaryOperator.LogicalOr: - case BinaryOperator.BitwiseOr: - case BinaryOperator.BitwiseAnd: - case BinaryOperator.BitwiseXor: - case BinaryOperator.RightShift: - case BinaryOperator.LeftShift: - binaryExpression.TypeInference.TargetType = GetBinaryImplicitConversionType(binaryExpression.Span, leftType, rightType, false); - break; - case BinaryOperator.Less: - case BinaryOperator.LessEqual: - case BinaryOperator.Greater: - case BinaryOperator.GreaterEqual: - case BinaryOperator.Equality: - case BinaryOperator.Inequality: - var returnType = GetBinaryImplicitConversionType(binaryExpression.Span, leftType, rightType, true); - binaryExpression.TypeInference.TargetType = TypeBase.CreateWithBaseType(returnType, ScalarType.Bool); - break; - } - - return binaryExpression; - } - - /// - /// Visits the specified conditional expression. - /// - /// The conditional expression. - public override Node Visit(ConditionalExpression conditionalExpression) - { - base.Visit(conditionalExpression); - - // Type inference for conditional expression is using the left result - var leftType = conditionalExpression.Left.TypeInference.TargetType; - var rightType = conditionalExpression.Right.TypeInference.TargetType; - - conditionalExpression.TypeInference.TargetType = leftType; - - if (leftType == null || (leftType is ScalarType && !(rightType is ScalarType))) - { - conditionalExpression.TypeInference.TargetType = rightType; - } - - return conditionalExpression; - } - - /// - /// Visits the specified indexer expression. - /// - /// The indexer expression. - public override Node Visit(IndexerExpression indexerExpression) - { - base.Visit(indexerExpression); - - ProcessIndexerExpression(indexerExpression); - - return indexerExpression; - } - - /// - /// Find the type of the expression - /// - /// the indexer expression - public virtual void ProcessIndexerExpression(IndexerExpression indexerExpression) - { - TypeBase type = null; - var targetType = indexerExpression.Target.TypeInference.TargetType; - - if (targetType is ArrayType) - { - var arrayType = (ArrayType)targetType; - if (arrayType.Dimensions.Count == 1) - { - type = arrayType.Type.ResolveType(); - } - else - { - var dimensions = new List(arrayType.Dimensions); - dimensions.RemoveAt(0); - type = new ArrayType(arrayType.Type, dimensions.ToArray()); - } - } - else if (targetType is VectorType) - { - type = ((VectorType)targetType).Type.ResolveType(); - } - else if (targetType is MatrixType) - { - type = new VectorType((ScalarType)((MatrixType)targetType).Type.ResolveType(), ((MatrixType)targetType).ColumnCount); - } - else if (targetType is ClassType) - { - // This is for buffers, especially in compute shaders - // TODO: check all the cases - var classType = (ClassType)targetType; - if (classType.GenericArguments.Count > 0) - type = classType.GenericArguments[0]; - } - - indexerExpression.TypeInference.TargetType = type; - if (type == null) - Error(MessageCode.ErrorIndexerType, indexerExpression.Span, indexerExpression); - } - - /// - /// Visits the specified literal expression. - /// - /// The literal expression. - public override Node Visit(LiteralExpression literalExpression) - { - base.Visit(literalExpression); - - if (literalExpression.Value is int) - literalExpression.TypeInference.TargetType = ScalarType.Int; - if (literalExpression.Value is uint) - literalExpression.TypeInference.TargetType = ScalarType.UInt; - if (literalExpression.Value is float) - literalExpression.TypeInference.TargetType = ScalarType.Float; - if (literalExpression.Value is double) - literalExpression.TypeInference.TargetType = ScalarType.Double; - if (literalExpression.Value is bool) - literalExpression.TypeInference.TargetType = ScalarType.Bool; - if (literalExpression.Value is string) - literalExpression.TypeInference.TargetType = TypeBase.String; - - if (literalExpression.TypeInference.TargetType == null) - { - Error(MessageCode.ErrorLiteralType, literalExpression.Span, literalExpression.Text); - } - - return literalExpression; - } - - public override Node Visit(ReturnStatement returnStatement) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(returnStatement); - - if (returnStatement.Value != null) - { - var function = NodeStack.OfType().Last(); - returnStatement.Value.TypeInference.ExpectedType = function.ReturnType.ResolveType(); - } - - return returnStatement; - } - - public override Node Visit(IfStatement ifStatement) - { - // First, dispatch to resolve type of node at deeper level - base.Visit(ifStatement); - - ifStatement.Condition.TypeInference.ExpectedType = ScalarType.Bool; - - return ifStatement; - } - - /// - /// Pres the process method invocation. - /// - /// The expression. - /// Name of the method. - /// The declarations. - /// - protected virtual void ProcessMethodInvocation(MethodInvocationExpression expression, string methodName, List declarations) - { - // Get all arguments types infered - var argumentTypeInferences = expression.Arguments.Select(x => x.TypeInference).ToArray(); - var argumentTypes = expression.Arguments.Select(x => x.TypeInference.TargetType).ToArray(); - - // If any type could not be resolved previously, there is already an error, so return immediately - if (argumentTypes.Any(x => x == null)) - return; - - var overloads = new List(); - - // Use the most overriden method - // TODO: Temporary workaround for user methods overriding builtin methods - // Remove the builtin methods if there is any overriding - var methodsDeclared = declarations.OfType().ToList(); - for (int i = 0; i < methodsDeclared.Count - 1; i++) - { - var leftMethod = methodsDeclared[i]; - for (int j = i + 1; j < methodsDeclared.Count; j++) - { - if (leftMethod.IsSameSignature(methodsDeclared[j])) - { - methodsDeclared.RemoveAt(i); - i--; - break; - } - } - } - - // Try to match the function arguments with every overload - foreach (var methodDeclaration in methodsDeclared) - { - var returnType = methodDeclaration.ReturnType.ResolveType(); - var parameterTypes = methodDeclaration.Parameters.Select(x => x.Type.ResolveType()).ToArray(); - - // Number of parameters doesn't match - if (argumentTypes.Length > parameterTypes.Length) continue; - - // Check for method calls that is using implicit parameter value - if (argumentTypes.Length < parameterTypes.Length) - { - bool allRemainingParametersHaveDefaultValues = true; - // Check for default values - for (int i = argumentTypes.Length; i < parameterTypes.Length; i++) - { - if (methodDeclaration.Parameters[i].InitialValue == null) - { - allRemainingParametersHaveDefaultValues = false; - break; - } - } - - // If remaining parameters doesn't have any default values, then continue - if (!allRemainingParametersHaveDefaultValues) continue; - } - - // Higher score = more conversion (score == 0 is perfect match) - int score = 0; - bool validOverload = true; - - // Check parameters - for (int i = 0; i < argumentTypes.Length && validOverload; ++i) - { - var argType = argumentTypes[i]; - var expectedType = parameterTypes[i]; - - var argTypeBase = TypeBase.GetBaseType(argType); - var expectedTypeBase = TypeBase.GetBaseType(expectedType); - - if (expectedTypeBase is GenericParameterType) - { - var genericParameterType = (GenericParameterType)expectedTypeBase; - - // TODO handle dynamic score from constraint. - if (methodDeclaration.CheckConstraint(genericParameterType, argType)) - { - score++; - } - else - { - validOverload = false; - } - } - else - { - // TODO, improve the whole test by using TypeBase equality when possible - - // Then work on scalar type conversion ( float to int, signed to unsigned, different type) - var fromScalarType = argTypeBase as ScalarType; - var toScalarType = expectedTypeBase as ScalarType; - - if (fromScalarType != null && toScalarType != null) - { - if (ScalarType.IsFloat(fromScalarType) && !ScalarType.IsFloat(toScalarType)) - { - // Truncation from float to int - score += 7; - } - else if (fromScalarType != toScalarType) - { - // else different type (implicit cast is usually working) - score += 1; - } - - if (!fromScalarType.IsUnsigned && toScalarType.IsUnsigned) - { - // int to unsigned - score += 2; - } - } - - // First, try to fix the base type (i.e. the "float" of float3x1) - if (argTypeBase != expectedTypeBase && expectedTypeBase is ScalarType) - { - if (!(argTypeBase is ScalarType)) - { - score++; // +1 for type conversion - } - argType = TypeBase.CreateWithBaseType(argType, (ScalarType)expectedTypeBase); - } - - validOverload = TestMethodInvocationArgument(argTypeBase, expectedTypeBase, argType, expectedType, ref score); - } - } - - if (validOverload) - overloads.Add( - new FunctionOverloadScore { Declaration = methodDeclaration, ParameterTypes = parameterTypes, ReturnType = returnType, Score = score }); - } - - // In-place sort using List.Sort would be lighter - var bestOverload = overloads.OrderBy(x => x.Score).FirstOrDefault(); - - if (bestOverload != null) - { - expression.TypeInference.TargetType = bestOverload.ReturnType.ResolveType(); - - // Override declaration to match exactly the declaration found by method overloaded resolution - expression.Target.TypeInference.Declaration = bestOverload.Declaration; - - // Add appropriate cast - for (int i = 0; i < argumentTypes.Length; ++i) - { - argumentTypeInferences[i].ExpectedType = (bestOverload.ParameterTypes[i] is GenericParameterType) - ? argumentTypes[i] - : bestOverload.ParameterTypes[i].ResolveType(); - } - } - else - { - Error(MessageCode.ErrorNoOverloadedMethod, expression.Span, methodName); - } - } - - /// - /// Tests the arguments of the method - /// - /// the argument typebase - /// the expected typebase - /// the argument type - /// the expected type - /// the score of the overload - /// true if the overload is correct, false otherwise - protected virtual bool TestMethodInvocationArgument(TypeBase argTypeBase, TypeBase expectedTypeBase, TypeBase argType, TypeBase expectedType, ref int score) - { - var validOverload = true; - - // If Scalar, Vector or Matrix, check types - if (TypeBase.HasDimensions(argType) && TypeBase.HasDimensions(expectedType)) - { - if (argType != expectedType) - { - int argDim1 = TypeBase.GetDimensionSize(argType, 0); - int argDim2 = TypeBase.GetDimensionSize(argType, 1); - int expectedDim1 = TypeBase.GetDimensionSize(expectedType, 0); - int expectedDim2 = TypeBase.GetDimensionSize(expectedType, 1); - - // float3<=>float1x3 and float3<=>float3x1 implicit conversion are allowed, - // but float3x1<=>float1x3 should not be allowed - // float3<=>float1x3 and float1x1<=>float1<=>float - if (argDim1 == expectedDim1 && argDim2 == expectedDim2) - { - score++; - } - else if (((argType is VectorType && expectedType is MatrixType) || (argType is MatrixType && expectedType is VectorType)) - && (argDim1 == expectedDim2 && argDim2 == expectedDim1)) - { - // float3<=>float3x1 - score++; - } - else if (argDim1 == 1 && argDim2 == 1) - { - // allow float=>float3x2 and float=>float3 - score += 10; // +10 for scalar=>vector or scalar=>matrix expansion - } - else if (argDim1 >= expectedDim1 && argDim2 >= expectedDim2) - { - // Truncation - // +100 for truncation (by rank difference) - score += 100 * (argDim1 + argDim2 - expectedDim1 - expectedDim2); - } - else - { - // Could not find any matching implicit conversion - validOverload = false; - } - } - } - else if (argType is ArrayType && expectedType is ArrayType) - { - var argArrayType = (ArrayType)argType; - var expectedArrayType = (ArrayType)expectedType; - - if (argArrayType != expectedArrayType) - validOverload = false; - } - else if (argType is StructType && expectedType is StructType) - { - var argStructType = (StructType)argType; - var expectedStructType = (StructType)expectedType; - - if (argStructType.Name != expectedStructType.Name) - validOverload = false; - } - else if (!((argType is ObjectType && expectedType is ObjectType) || (argType is StructType && expectedType is StructType))) - { - // Could not find any matching implicit conversion - validOverload = false; - } - - return validOverload; - } - - /// - /// Visits the specified method invocation expression. - /// - /// The method invocation expression. - public override Node Visit(MethodInvocationExpression expression) - { - base.Visit(expression); - - var methodAsVariable = expression.Target as VariableReferenceExpression; - var methodAsType = expression.Target as TypeReferenceExpression; - - IEnumerable declarationsIterator = null; - - string methodName; - - // Check if this is a Variable or Typename - if (methodAsVariable != null) - { - methodName = methodAsVariable.Name.Text; - declarationsIterator = FindDeclarations(methodAsVariable.Name); - } - else if (methodAsType != null) - { - var returnType = methodAsType.Type.ResolveType(); - expression.TypeInference.TargetType = returnType; - - if (!(returnType is ScalarType || returnType is VectorType || returnType is MatrixType)) - Warning(MessageCode.WarningTypeAsConstructor, expression.Span, expression.Target); - - return expression; - } - else - { - var target = expression.Target as MemberReferenceExpression; - if (target != null) - { - var memberReferenceExpression = target; - - declarationsIterator = FindDeclarationsFromObject(memberReferenceExpression.Target.TypeInference.TargetType, memberReferenceExpression.Member.Text); - methodName = string.Format("{0}", target); - } - else - { - Warning(MessageCode.WarningTypeInferenceUnknownExpression, expression.Span, expression.Target); - methodName = string.Format("{0}", expression.Target); - } - } - - // If no declarations were found, this is an error - if (declarationsIterator == null) - { - Error(MessageCode.ErrorNoReferencedMethod, expression.Span, methodName); - return expression; - } - - // Grab the declarations - var declarations = declarationsIterator.ToList(); - ProcessMethodInvocation(expression, methodName, declarations); - - return expression; - } - - protected virtual IEnumerable FindDeclarationsFromObject(TypeBase typeBase, string memberName) - { - return null; - } - - /// - /// Visits the specified member reference. - /// - /// The member reference. - public override Node Visit(MemberReferenceExpression memberReference) - { - base.Visit(memberReference); - - CommonVisit(memberReference); - - // If member reference is used from method invocation expression, let the method invocation resolve the type - if (!(ParentNode is MethodInvocationExpression) && memberReference.TypeInference.TargetType == null) - Warning(MessageCode.WarningNoTypeReferenceMember, memberReference.Span, memberReference); - - return memberReference; - } - - /// - /// Visits the specified member reference. - /// - /// The member reference. - public override Node Visit(MethodDefinition methodDefinition) - { - base.Visit(methodDefinition); - - // Check that this method definition doesn't have a method declaration before - foreach (var declaration in FindDeclarations(methodDefinition.Name)) - { - var methodDeclaration = declaration as MethodDeclaration; - if (methodDeclaration != null && !ReferenceEquals(declaration, methodDefinition)) - { - if (methodDeclaration.IsSameSignature(methodDefinition)) - { - methodDefinition.Declaration = methodDeclaration; - // Remove the definition if the declaration is tagged as builtin special (user defined) - if (methodDeclaration.GetTag(TagBuiltinUserDefined) != null) - return null; - break; - } - } - } - return methodDefinition; - } - - /// - /// Visits the specified member reference. - /// - /// The member reference. - protected virtual void CommonVisit(MemberReferenceExpression memberReference) - { - var thisType = memberReference.Target.TypeInference.TargetType; - - if (thisType is StructType) - FindMemberTypeReference((StructType)thisType, memberReference); - else if (thisType is ScalarType) - FindMemberTypeReference((ScalarType)thisType, memberReference); - else if (thisType is VectorType) - FindMemberTypeReference((VectorType)thisType, memberReference); - } - - /// - /// Visits the specified parenthesized expression. - /// - /// The parenthesized expression. - public override Node Visit(ParenthesizedExpression parenthesizedExpression) - { - base.Visit(parenthesizedExpression); - - // Get the type from the last item - parenthesizedExpression.TypeInference = (TypeInference)parenthesizedExpression.Content.TypeInference.Clone(); - return parenthesizedExpression; - } - - /// - /// Visits the specified expression list. - /// - /// The expression list. - public override Node Visit(ExpressionList expressionList) - { - base.Visit(expressionList); - - // Get the type from the last item - expressionList.TypeInference = (TypeInference)expressionList[expressionList.Count - 1].TypeInference.Clone(); - return expressionList; - } - - /// - /// Visits the specified array type. - /// - /// Array type. - public override Node Visit(ArrayType arrayType) - { - base.Visit(arrayType); - - // Process only if there is non-literal expressions - if (arrayType.TypeInference.TargetType == null - && arrayType.Dimensions.Any(x => !(x is LiteralExpression || x is EmptyExpression))) - { - // Try to evaluate each dimension into a Literal expression (i.e. float4[3 * 2] should become float4[6]) - var evaluator = new ExpressionEvaluator(); - var results = arrayType.Dimensions.Select(evaluator.Evaluate).ToArray(); - - if (results.Any(x => x.HasErrors)) - { - foreach (var result in results.Where(x => x.HasErrors)) - result.CopyTo(ParsingResult); - } - else - { - arrayType.TypeInference.TargetType = new ArrayType(arrayType.Type, results.Select(x => new LiteralExpression(Convert.ToInt32(x.Value))).ToArray()); - } - } - - return arrayType; - } - - /// - /// Visits the specified type name. - /// - /// Name of the type. - public override Node Visit(TypeName typeName) - { - base.Visit(typeName); - - if (typeName.TypeInference.TargetType == null) - { - if (typeName.Name.Text == "void") - { - typeName.TypeInference.TargetType = TypeBase.Void; - } - else if (typeName.Name.Text == "string") - { - typeName.TypeInference.TargetType = TypeBase.String; - } - else - { - var declaration = FindDeclaration(typeName.Name); - if (declaration != null) - { - // Setup a type reference for this typeName - var typeReference = typeName.TypeInference; - typeReference.Declaration = declaration; - typeReference.TargetType = ResolveTypeFromDeclaration(typeReference.Declaration); - } - else - { - Error(MessageCode.ErrorNoTypeReferenceTypename, typeName.Span, typeName); - } - } - } - return typeName; - } - - /// - /// Visits the specified variable reference expression. - /// - /// The variable reference expression. - public override Node Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - - var typeReference = variableReferenceExpression.TypeInference; - typeReference.Declaration = FindDeclaration(variableReferenceExpression.Name); - typeReference.TargetType = ResolveTypeFromDeclaration(typeReference.Declaration); - return variableReferenceExpression; - } - - /// - /// Visits the specified unary expression. - /// - /// The unary expression. - public override Node Visit(UnaryExpression unaryExpression) - { - base.Visit(unaryExpression); - - // TODO check for - unaryExpression.TypeInference = (TypeInference)unaryExpression.Expression.TypeInference.Clone(); - - // If this is a logical not, transform the value to a bool (bool2 bool3 bool4 / matrix matrix ..etc. - var subType = unaryExpression.Expression.TypeInference.TargetType; - if (subType != null && unaryExpression.Operator == UnaryOperator.LogicalNot) - unaryExpression.TypeInference.TargetType = TypeBase.CreateWithBaseType(subType, ScalarType.Bool); - - return unaryExpression; - } - - #endregion - - #region Methods - - /// - /// Finds the member type reference. - /// - /// Type of the struct. - /// The member reference. - protected virtual void FindMemberTypeReference(StructType structType, MemberReferenceExpression memberReference) - { - foreach (var field in structType.Fields) - { - foreach (var variableDeclarator in field.Instances()) - { - if (variableDeclarator.Name == memberReference.Member) - { - memberReference.TypeInference.Declaration = variableDeclarator; - memberReference.TypeInference.TargetType = variableDeclarator.Type.ResolveType(); - return; - } - } - } - } - - /// - /// Finds the member type reference. - /// - /// Type of the vector. - /// The member reference. - protected virtual void FindMemberTypeReference(VectorType vectorType, MemberReferenceExpression memberReference) - { - var scalarType = vectorType.Type.ResolveType(); - - var components = memberReference.Member.Text; - if (components.Length <= 4 && ( - components.All(x => x == 'x' || x == 'y' || x == 'z' || x == 'w') || - components.All(x => x == 'r' || x == 'g' || x == 'b' || x == 'a') || - components.All(x => x == 's' || x == 't' || x == 'u' || x == 'v') - )) - { - memberReference.TypeInference.TargetType = components.Length == 1 ? scalarType : new VectorType((ScalarType)scalarType, components.Length); - } - } - - /// - /// Finds the member type reference. - /// - /// Type of the scalar. - /// The member reference. - protected virtual void FindMemberTypeReference(ScalarType scalarType, MemberReferenceExpression memberReference) - { - var components = memberReference.Member.Text; - if (components.Length <= 4 && ( - components.All(x => x == 'x' || x == 'y' || x == 'z' || x == 'w') || - components.All(x => x == 'r' || x == 'g' || x == 'b' || x == 'a') || - components.All(x => x == 's' || x == 't' || x == 'u' || x == 'v') - )) - { - memberReference.TypeInference.TargetType = components.Length == 1 ? (TypeBase)scalarType : new VectorType(scalarType, components.Length); - } - } - - /// - /// Resolves the type from declaration. - /// - /// The declaration. - /// - /// A type - /// - protected TypeBase ResolveTypeFromDeclaration(IDeclaration declaration) - { - TypeBase type = null; - - if (declaration is Variable) - { - var variableDeclaration = (Variable)declaration; - type = variableDeclaration.Type.ResolveType(); - } - else if (declaration is TypeBase) - { - type = ((TypeBase)declaration).ResolveType(); - } - else if (declaration is GenericDeclaration) - { - var genericDeclaration = (GenericDeclaration)declaration; - type = genericDeclaration.Holder.GenericParameters[genericDeclaration.Index].ResolveType(); - } - - if (type is TypeName) - { - type = ResolveTypeFromDeclaration(type.TypeInference.Declaration); - } - - return type; - } - - class FunctionOverloadScore - { - public MethodDeclaration Declaration { get; set; } - public TypeBase ReturnType { get; set; } - public TypeBase[] ParameterTypes { get; set; } - public int Score { get; set; } - - public override string ToString() - { - return string.Format("#{0} {1}", Score, Declaration); - } - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ArrayInitializerExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/ArrayInitializerExpression.cs deleted file mode 100644 index fa6c9bb35c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ArrayInitializerExpression.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Expression used to initliaze an array {...expressions,} - /// - public partial class ArrayInitializerExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public ArrayInitializerExpression() - { - Items = new List(); - } - - /// - /// Gets or sets the items. - /// - /// - /// The items. - /// - public List Items { get; set; } - - /// - public override IEnumerable Childrens() - { - return Items; - } - - /// - public override string ToString() - { - return string.Format("{{{0}}}", string.Join(",", Items)); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ArrayType.cs b/sources/shaders/Stride.Core.Shaders/Ast/ArrayType.cs deleted file mode 100644 index b8d9818156..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ArrayType.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Array type. - /// - public partial class ArrayType : TypeBase - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ArrayType() : base("$array") - { - Dimensions = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The dimensions. - public ArrayType(TypeBase type, params Expression[] dimensions) : base("$array") - { - Type = type; - Dimensions = new List(); - Dimensions.AddRange(dimensions); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the dimensions. - /// - /// - /// The dimensions. - /// - public List Dimensions { get; set; } - - /// - public override string ToString() - { - var indices = new StringBuilder(); - foreach (var index in Dimensions) - { - indices.Append("[").Append(index).Append("]"); - } - - return string.Format("{0}{1}", Type, indices); - } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type { get; set; } - - /// - /// Gets a value indicating whether this instance is dimension empty. - /// - /// - /// true if this instance is dimension empty; otherwise, false. - /// - public bool IsDimensionEmpty - { - get { return Dimensions.Count == 1 && Dimensions[0] is EmptyExpression; } - } - - #endregion - - #region Public Methods - - public bool Equals(ArrayType other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - if ( !base.Equals(other) || !Equals(other.Type.ResolveType(), Type.ResolveType()) || other.Dimensions.Count != Dimensions.Count) return false; - - // Check that dimensions are all equals - return !Dimensions.Where((t, i) => t != other.Dimensions[i]).Any(); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return Equals(obj as ArrayType); - } - - public override int GetHashCode() - { - unchecked - { - int result = base.GetHashCode(); - result = (result * 397) ^ (Dimensions != null ? Dimensions.GetHashCode() : 0); - result = (result * 397) ^ (Type != null ? Type.GetHashCode() : 0); - return result; - } - } - - public static bool operator ==(ArrayType left, ArrayType right) - { - return Equals(left, right); - } - - public static bool operator !=(ArrayType left, ArrayType right) - { - return !Equals(left, right); - } - - /// - public override IEnumerable Childrens() - { - return Dimensions; - } - - // TODO Implements equals for array types - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/AssignmentExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/AssignmentExpression.cs deleted file mode 100644 index bb21e16fb0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/AssignmentExpression.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An assignment expression - /// - public partial class AssignmentExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public AssignmentExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The @operator. - /// The target. - /// The value. - public AssignmentExpression(AssignmentOperator @operator, Expression target, Expression value) - { - Operator = @operator; - Target = target; - Value = value; - } - - #region Public Properties - - /// - /// Gets or sets the operator. - /// - /// - /// The operator. - /// - public AssignmentOperator Operator { get; set; } - - /// - /// Gets or sets the target receving the assigment. - /// - /// - /// The target. - /// - public Expression Target { get; set; } - - /// - /// Gets or sets the value of the assigment.. - /// - /// - /// The value. - /// - public Expression Value { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Target); - ChildrenList.Add(Value); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} {1} {2}", Target, Operator.ConvertToString(), Value); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/AssignmentOperator.cs b/sources/shaders/Stride.Core.Shaders/Ast/AssignmentOperator.cs deleted file mode 100644 index 6705abfcb6..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/AssignmentOperator.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Assignment operator used in assignment expression (a = b) or statements (a = b;) - /// - public enum AssignmentOperator - { - /// - /// Operator = - /// - Default, - - /// - /// Operator += - /// - Addition, - - /// - /// Operator -= - /// - Subtraction, - - /// - /// Operator *= - /// - Multiplication, - - /// - /// Operator /= - /// - Division, - - /// - /// Operator %= - /// - Modulo, - - /// - /// Operator &= - /// - BitwiseAnd, - - /// - /// Operator |= - /// - BitwiseOr, - - /// - /// Operator ^= - /// - BitwiseXor, - - /// - /// Operator <<= - /// - BitwiseShiftLeft, - - /// - /// Operator >>= - /// - BitwiseShiftRight - } - - /// - /// Helper for . - /// - public static class AssignmentOperatorHelper - { - #region Public Methods - - /// - /// Converts from operator to string - /// - /// - /// The assignment operator. - /// - /// - /// A string representation of an assignment operator - /// - public static string ConvertToString(this AssignmentOperator assignmentOperator) - { - switch (assignmentOperator) - { - case AssignmentOperator.Default: - return "="; - case AssignmentOperator.Addition: - return "+="; - case AssignmentOperator.Subtraction: - return "-="; - case AssignmentOperator.Multiplication: - return "*="; - case AssignmentOperator.Division: - return "/="; - case AssignmentOperator.Modulo: - return "%="; - case AssignmentOperator.BitwiseAnd: - return "&="; - case AssignmentOperator.BitwiseOr: - return "|="; - case AssignmentOperator.BitwiseXor: - return "^="; - case AssignmentOperator.BitwiseShiftLeft: - return "<<="; - case AssignmentOperator.BitwiseShiftRight: - return ">>="; - } - - return string.Empty; - } - - /// - /// Converts from string an operator. - /// - /// - /// The operator text. - /// - /// - /// If operatorStr is invalid - /// - /// - /// An assignment operator - /// - public static AssignmentOperator FromString(string operatorStr) - { - if (operatorStr == "=") - { - return AssignmentOperator.Default; - } - - if (operatorStr == "+=") - { - return AssignmentOperator.Addition; - } - - if (operatorStr == "-=") - { - return AssignmentOperator.Subtraction; - } - - if (operatorStr == "*=") - { - return AssignmentOperator.Multiplication; - } - - if (operatorStr == "/=") - { - return AssignmentOperator.Division; - } - - if (operatorStr == "%=") - { - return AssignmentOperator.Modulo; - } - - if (operatorStr == "&=") - { - return AssignmentOperator.BitwiseAnd; - } - - if (operatorStr == "|=") - { - return AssignmentOperator.BitwiseOr; - } - - if (operatorStr == "^=") - { - return AssignmentOperator.BitwiseXor; - } - - if (operatorStr == "<<=") - { - return AssignmentOperator.BitwiseShiftLeft; - } - - if (operatorStr == ">>=") - { - return AssignmentOperator.BitwiseShiftRight; - } - - throw new ArgumentException(string.Format("Invalid assigment operator [{0}]", operatorStr)); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/AttributeBase.cs b/sources/shaders/Stride.Core.Shaders/Ast/AttributeBase.cs deleted file mode 100644 index 609b18c3d6..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/AttributeBase.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An abstract class for attribute definition. - /// - public abstract partial class AttributeBase : Node - { - } - - /// - /// An abstract class for a post attribute definition. - /// - public abstract partial class PostAttributeBase : AttributeBase - { - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/BinaryExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/BinaryExpression.cs deleted file mode 100644 index 6c1575f8f0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/BinaryExpression.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Describes a binary expression. - /// - public partial class BinaryExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public BinaryExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The @operator. - /// The left. - /// The right. - public BinaryExpression(BinaryOperator @operator, Expression left, Expression right) - { - Left = left; - Operator = @operator; - Right = right; - } - - #region Public Properties - - /// - /// Gets or sets the left expression. - /// - /// - /// The left expression. - /// - public Expression Left { get; set; } - - /// - /// Gets or sets the binary operator. - /// - /// - /// The binary operator. - /// - public BinaryOperator Operator { get; set; } - - /// - /// Gets or sets the right expression. - /// - /// - /// The right expression. - /// - public Expression Right { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Left); - ChildrenList.Add(Right); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} {1} {2}", Left, Operator.ConvertToString(), Right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/BinaryOperator.cs b/sources/shaders/Stride.Core.Shaders/Ast/BinaryOperator.cs deleted file mode 100644 index cf7e10ac0b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/BinaryOperator.cs +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Binary operator used in all binary expressions (except assignment expression). - /// - public enum BinaryOperator - { - /// - /// No operator defined. - /// - None, - - /// - /// Logical And operator "&&" - /// - LogicalAnd, - - /// - /// Logical Or operator "||" - /// - LogicalOr, - - /// - /// Bitwise And operator "&" - /// - BitwiseAnd, - - /// - /// Bitwise Or operator "|" - /// - BitwiseOr, - - /// - /// Bitwise Xor operator "^" - /// - BitwiseXor, - - /// - /// Left shift operator "<<" - /// - LeftShift, - - /// - /// Right shift operator ">>" - /// - RightShift, - - /// - /// Minus operator "-" - /// - Minus, - - /// - /// Plus operator "+" - /// - Plus, - - /// - /// Multiply operator "*" - /// - Multiply, - - /// - /// Divide operator "/" - /// - Divide, - - /// - /// Modulo operator "%" - /// - Modulo, - - /// - /// Less than operator "<" - /// - Less, - - /// - /// Less or equal operator "<=" - /// - LessEqual, - - /// - /// Greater operator ">" - /// - Greater, - - /// - /// Greater or equal operator ">=" - /// - GreaterEqual, - - /// - /// Equality operator "==" - /// - Equality, - - /// - /// Inequality operator "!=" - /// - Inequality, - } - - /// - /// Helper for . - /// - public static class BinaryOperatorHelper - { - #region Public Methods - - /// - /// Converts from operator to string - /// - /// - /// The binary operator. - /// - /// - /// A string representation of an binary operator - /// - public static string ConvertToString(this BinaryOperator binaryOperator) - { - switch (binaryOperator) - { - case BinaryOperator.LogicalAnd: - return "&&"; - case BinaryOperator.LogicalOr: - return "||"; - case BinaryOperator.BitwiseAnd: - return "&"; - case BinaryOperator.BitwiseOr: - return "|"; - case BinaryOperator.BitwiseXor: - return "^"; - case BinaryOperator.LeftShift: - return "<<"; - case BinaryOperator.RightShift: - return ">>"; - case BinaryOperator.Minus: - return "-"; - case BinaryOperator.Plus: - return "+"; - case BinaryOperator.Multiply: - return "*"; - case BinaryOperator.Divide: - return "/"; - case BinaryOperator.Modulo: - return "%"; - case BinaryOperator.Less: - return "<"; - case BinaryOperator.LessEqual: - return "<="; - case BinaryOperator.Greater: - return ">"; - case BinaryOperator.GreaterEqual: - return ">="; - case BinaryOperator.Equality: - return "=="; - case BinaryOperator.Inequality: - return "!="; - } - - return string.Empty; - } - - /// - /// Converts from string an operator. - /// - /// - /// The operator text. - /// - /// - /// If operatorStr is invalid - /// - /// - /// An binary operator - /// - public static BinaryOperator FromString(string operatorStr) - { - if (operatorStr == "&&") - { - return BinaryOperator.LogicalAnd; - } - - if (operatorStr == "||") - { - return BinaryOperator.LogicalOr; - } - - if (operatorStr == "&") - { - return BinaryOperator.BitwiseAnd; - } - - if (operatorStr == "|") - { - return BinaryOperator.BitwiseOr; - } - - if (operatorStr == "^") - { - return BinaryOperator.BitwiseXor; - } - - if (operatorStr == "<<") - { - return BinaryOperator.LeftShift; - } - - if (operatorStr == ">>") - { - return BinaryOperator.RightShift; - } - - if (operatorStr == "-") - { - return BinaryOperator.Minus; - } - - if (operatorStr == "+") - { - return BinaryOperator.Plus; - } - - if (operatorStr == "*") - { - return BinaryOperator.Multiply; - } - - if (operatorStr == "/") - { - return BinaryOperator.Divide; - } - - if (operatorStr == "%") - { - return BinaryOperator.Modulo; - } - - if (operatorStr == "<") - { - return BinaryOperator.Less; - } - - if (operatorStr == "<=") - { - return BinaryOperator.LessEqual; - } - - if (operatorStr == ">") - { - return BinaryOperator.Greater; - } - - if (operatorStr == ">=") - { - return BinaryOperator.GreaterEqual; - } - - if (operatorStr == "==") - { - return BinaryOperator.Equality; - } - - if (operatorStr == "!=") - { - return BinaryOperator.Inequality; - } - - throw new ArgumentException(string.Format("Invalid binary operator [{0}]", operatorStr)); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/BlockStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/BlockStatement.cs deleted file mode 100644 index 67e9fdb8b2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/BlockStatement.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Block of statement. - /// - public partial class BlockStatement : Statement, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public BlockStatement() - { - Statements = new StatementList(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The statements. - public BlockStatement(StatementList statements) - { - Statements = statements; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the statements. - /// - /// - /// The statements. - /// - public StatementList Statements { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - return Statements; - } - - /// - public override string ToString() - { - return "{...}"; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/CaseStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/CaseStatement.cs deleted file mode 100644 index 5deea147f2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/CaseStatement.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A single case or default statement. - /// - public partial class CaseStatement : Statement - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public CaseStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The @case. - /// - public CaseStatement(Expression @case) - { - Case = @case; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the case. - /// - /// - /// The case. - /// - /// - /// If this property is null, this is a default statement. - /// - public Expression Case { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - if (Case != null) - { - ChildrenList.Add(Case); - } - - return ChildrenList; - } - - /// - public override string ToString() - { - return Case == null ? "default:" : string.Format("case {0}:", Case); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/CompositeEnum.cs b/sources/shaders/Stride.Core.Shaders/Ast/CompositeEnum.cs deleted file mode 100644 index fa4ef39f43..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/CompositeEnum.cs +++ /dev/null @@ -1,422 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A composite enum. - /// - public partial class CompositeEnum : Node, IEnumerable - { - private OrderedSet values; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public CompositeEnum() - { - Values = new OrderedSet(); - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// if set to true [is flag]. - /// - public CompositeEnum(bool isFlag) - : this() - { - IsFlag = isFlag; - } - - /// - /// Initializes a new instance of the class. - /// - /// The key. - /// if set to true [is flag]. - public CompositeEnum(object key, bool isFlag) - : this(isFlag) - { - Key = key; - Values.Add(this); - } - - #endregion - - #region Public Properties - - /// - /// Gets a value indicating whether this instance is a composition enum (a combination of enums). - /// - /// - /// true if this instance is a composition enum (a combination of enums); otherwise, false. - /// - public bool IsComposition - { - get - { - return Key == null; - } - } - - /// - /// Gets a value indicating whether this instance is an enum flag. - /// - /// - /// true if this instance is an enum flag; otherwise, false. - /// - public bool IsFlag { get; set; } - - /// - /// Gets or sets the key. - /// - /// - /// The key. - /// - public object Key { get; set; } - - - /// - /// Gets or sets the values. - /// - /// - /// The values. - /// - [VisitorIgnore] - public OrderedSet Values - { - get - { - return values; - } - set - { - values = value; - } - } - - /// - /// Gets the display name. - /// - public virtual string DisplayName - { - get - { - return Key != null ? Key.ToString() : "null"; - } - } - - #endregion - - #region Public Methods - - /// - /// Determines whether [contains] [the specified enum value]. - /// - /// - /// The enum value. - /// - /// - /// true if [contains] [the specified enum value]; otherwise, false. - /// - public bool Contains(CompositeEnum enumValue) - { - return enumValue.Values.IsSubsetOf(Values); - } - - /// - /// Determines whether [contains] [the specified enum values]. - /// - /// - /// The enum values. - /// - /// - /// true if [contains] [the specified enum values]; otherwise, false. - /// - public bool Contains(params CompositeEnum[] enumValues) - { - return enumValues.Any(Contains); - } - - /// - /// Determines whether the specified enum values contains all. - /// - /// - /// The enum values. - /// - /// - /// true if the specified enum values contains all; otherwise, false. - /// - public bool ContainsAll(params CompositeEnum[] enumValues) - { - return enumValues.All(Contains); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// - /// The to compare with this instance. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(CompositeEnum other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - if (other.IsFlag != IsFlag) - { - return false; - } - - if (Values.Count != other.Values.Count) - { - return false; - } - - if (Key != null && other.Key != null) - { - return Key.Equals(other.Key); - } - - // Optim to speed up comparison - if (ReferenceEquals(Values, other.Values)) - { - return true; - } - - return Values.SetEquals(other.Values); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (!(obj is CompositeEnum)) - { - return false; - } - - return Equals((CompositeEnum)obj); - } - - /// - public override int GetHashCode() - { - int hashCode = IsFlag.GetHashCode() * 397; - if (Key != null) - { - return hashCode ^ Key.GetHashCode() * 397; - } - - return Values.Aggregate(hashCode, (current, value) => current ^ value.GetHashCode() * 397); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public IEnumerator GetEnumerator() - { - return Values.GetEnumerator(); - } - - /// - public override string ToString() - { - return ToString(null); - } - - /// - public string ToString(Func filterEnum) where T : CompositeEnum - { - var builder = new StringBuilder(); - bool isNext = false; - var filteredValues = Values.OfType(); - if (filterEnum != null) - { - filteredValues = filteredValues.Where(filterEnum); - } - - foreach (var value in filteredValues) - { - if (isNext) - { - builder.Append(" "); - } - - if (value.Key != null) - { - if (string.Empty.Equals(value.Key)) - { - isNext = false; - } - else - { - builder.Append(value.DisplayName); - isNext = true; - } - } - else - { - builder.Append(value.ToString()); - isNext = true; - } - } - - return builder.ToString(); - } - - - #endregion - - #region Methods - - /// - /// Operators And. - /// - /// - /// The type of the 1. - /// - /// - /// The left. - /// - /// - /// The right. - /// - /// - /// Result of And operation - /// - public static T1 OperatorAnd(T1 left, T1 right) - where T1 : CompositeEnum, new() - { - var result = new T1 { IsFlag = left.IsFlag, Values = new OrderedSet(left.Values) }; - result.Values.IntersectWith(right.Values); - return result; - } - - /// - /// Operators Or. - /// - /// - /// The type of the 1. - /// - /// - /// The left. - /// - /// - /// The right. - /// - /// - /// Result of Or operation - /// - public static T1 OperatorOr(T1 left, T1 right) - where T1 : CompositeEnum, new() - { - var result = new T1 { IsFlag = left.IsFlag, Values = new OrderedSet(left.Values) }; - result.Values.UnionWith(right.Values); - return result; - } - - /// - /// Operators Xor. - /// - /// - /// The type of the 1. - /// - /// - /// The left. - /// - /// - /// The right. - /// - /// - /// Result of Xor operation - /// - public static T1 OperatorXor(T1 left, T1 right) - where T1 : CompositeEnum, new() - { - var result = new T1 { IsFlag = left.IsFlag, Values = new OrderedSet(left.Values) }; - result.Values.SymmetricExceptWith(right.Values); - return result; - } - - /// - public override IEnumerable Childrens() - { - if (Values.Count == 0) return ChildrenList; - - ChildrenList.Clear(); - foreach (var compositeEnum in Values) - { - if (!ReferenceEquals(this, compositeEnum) && !string.Empty.Equals(compositeEnum.Key)) - { - ChildrenList.Add(compositeEnum); - } - } - - return ChildrenList; - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(CompositeEnum left, CompositeEnum right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(CompositeEnum left, CompositeEnum right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ConditionalExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/ConditionalExpression.cs deleted file mode 100644 index 8a80923c47..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ConditionalExpression.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Conditional expression - /// - public partial class ConditionalExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public ConditionalExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The condition. - /// The left. - /// The right. - public ConditionalExpression(Expression condition, Expression left, Expression right) - { - Condition = new ParenthesizedExpression(condition); - Left = left; - Right = right; - } - - #region Public Properties - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Condition { get; set; } - - /// - /// Gets or sets the left. - /// - /// - /// The left. - /// - public Expression Left { get; set; } - - /// - /// Gets or sets the right. - /// - /// - /// The right. - /// - public Expression Right { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Condition); - ChildrenList.Add(Left); - ChildrenList.Add(Right); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} ? {1} : {2}", Condition, Left, Right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/DeclarationStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/DeclarationStatement.cs deleted file mode 100644 index 87a9346510..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/DeclarationStatement.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A declaration inside a statement. - /// - public partial class DeclarationStatement : Statement - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public DeclarationStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The content. - /// - public DeclarationStatement(Node content) - { - Content = content; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the content. - /// - /// - /// The content. - /// - public Node Content { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Content); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0};", Content == null ? string.Empty : Content.ToString()); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/EmptyExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/EmptyExpression.cs deleted file mode 100644 index db086de38f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/EmptyExpression.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Empty expression - /// - public partial class EmptyExpression : Expression - { - /// - public override string ToString() - { - return string.Empty; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/EmptyStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/EmptyStatement.cs deleted file mode 100644 index 7fb8d64f0e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/EmptyStatement.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Empty of statement. - /// - public partial class EmptyStatement : Statement - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public EmptyStatement() - { - } - - #endregion - - #region Public Methods - - /// - public override string ToString() - { - return string.Empty; - } - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Expression.cs b/sources/shaders/Stride.Core.Shaders/Ast/Expression.cs deleted file mode 100644 index a14f9bdc12..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Expression.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An expression. - /// - public abstract partial class Expression : Node, ITypeInferencer - { - /// - /// Initializes a new instance of the class. - /// - protected Expression() - { - TypeInference = new TypeInference(); - } - - /// - /// Gets or sets the type reference. - /// - /// - /// The type reference. - /// - public TypeInference TypeInference { get; set; } - - /// - public override string ToString() - { - return string.Empty; - } - - public bool Equals(Expression other) - { - return !ReferenceEquals(null, other); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof(Expression)) return false; - return Equals((Expression)obj); - } - - public override int GetHashCode() - { - return 0; - } - - public static bool operator ==(Expression left, Expression right) - { - return Equals(left, right); - } - - public static bool operator !=(Expression left, Expression right) - { - return !Equals(left, right); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ExpressionList.cs b/sources/shaders/Stride.Core.Shaders/Ast/ExpressionList.cs deleted file mode 100644 index f62c0e8a2a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ExpressionList.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A list of expression. - /// - public partial class ExpressionList : Expression, IList - { - /// - /// Initializes a new instance of the class. - /// - public ExpressionList() - { - Expressions = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The expressions. - public ExpressionList(params Expression [] expressions) - { - Expressions = new List(); - if (expressions != null) - Expressions.AddRange(expressions); - } - - /// - public int Count - { - get - { - return Expressions.Count; - } - } - - /// - public bool IsReadOnly - { - get - { - return false; - } - } - - /// - /// Gets or sets the expressions. - /// - /// - /// The expressions. - /// - public List Expressions { get; set; } - - /// - /// Adds a collection to this instance. - /// - /// The collection to add to this instance. - public void AddRange(IEnumerable collection) - { - Expressions.AddRange(collection); - } - - /// - /// Gets a subset of this instance - /// - /// The index. - /// The count. - /// A subset of this instance - public List GetRange(int index, int count) - { - return Expressions.GetRange(index, count); - } - - /// - /// Inserts a collection at the specified index. - /// - /// The index. - /// The collection. - public void InsertRange(int index, IEnumerable collection) - { - Expressions.InsertRange(index, collection); - } - - /// - /// Removes a range of elements. - /// - /// The index. - /// The count. - public void RemoveRange(int index, int count) - { - Expressions.RemoveRange(index, count); - } - - /// - /// Removes all elements with a predicate function. - /// - /// The match. - /// Number of elements removed - public int RemoveAll(Predicate match) - { - return Expressions.RemoveAll(match); - } - - /// - public Expression this[int index] - { - get - { - return Expressions[index]; - } - - set - { - Expressions[index] = value; - } - } - - /// - public void Add(Expression item) - { - Expressions.Add(item); - } - - public override IEnumerable Childrens() - { - return this; - } - - /// - public void Clear() - { - Expressions.Clear(); - } - - /// - public bool Contains(Expression item) - { - return Expressions.Contains(item); - } - - /// - public void CopyTo(Expression[] array, int arrayIndex) - { - Expressions.CopyTo(array, arrayIndex); - } - - /// - public IEnumerator GetEnumerator() - { - return Expressions.GetEnumerator(); - } - - /// - public int IndexOf(Expression item) - { - return Expressions.IndexOf(item); - } - - /// - public void Insert(int index, Expression item) - { - Expressions.Insert(index, item); - } - - /// - public bool Remove(Expression item) - { - return Expressions.Remove(item); - } - - /// - public void RemoveAt(int index) - { - Expressions.RemoveAt(index); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return string.Join(", ", this); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ExpressionStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/ExpressionStatement.cs deleted file mode 100644 index 0434436da6..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ExpressionStatement.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An expression statement. - /// - public partial class ExpressionStatement : Statement - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ExpressionStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The expression. - /// - public ExpressionStatement(Expression expression) - { - Expression = expression; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the expression. - /// - /// - /// The expression. - /// - public Expression Expression { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Expression); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0};", Expression); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ForStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/ForStatement.cs deleted file mode 100644 index fab9acf241..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ForStatement.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// For statement. - /// - public partial class ForStatement : Statement, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ForStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The start. - /// - /// - /// The condition. - /// - /// - /// The next. - /// - public ForStatement(Statement start, Expression condition, Expression next) - { - Start = start; - Condition = condition; - Next = next; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the initializer. - /// - /// - /// The initializer. - /// - public Statement Start { get; set; } - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Condition { get; set; } - - /// - /// Gets or sets the next. - /// - /// - /// The next. - /// - public Expression Next { get; set; } - - /// - /// Gets or sets the body. - /// - /// - /// The body. - /// - public Statement Body { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Start); - ChildrenList.Add(Condition); - ChildrenList.Add(Next); - ChildrenList.Add(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("for({0}{1};{2}) {{...}}", Start, Condition, Next); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/GenericBaseType.cs b/sources/shaders/Stride.Core.Shaders/Ast/GenericBaseType.cs deleted file mode 100644 index 4b87bffb65..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/GenericBaseType.cs +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Base class for all generic types. - /// - public abstract partial class GenericBaseType : TypeBase - { - #region Constructors and Destructors - - public GenericBaseType() : this(null, 0) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - /// - /// The parameter count. - /// - public GenericBaseType(string name, int parameterCount) - : base(name) - { - ParameterTypes = new List(); - Parameters = new List(); - for (int i = 0; i < parameterCount; i++) - { - Parameters.Add(null); - } - } - - #endregion - - #region Public Properties - - /// - /// Gets the full name. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - var builder = new StringBuilder(); - builder.Append(Name).Append("<"); - for (int i = 0; i < Parameters.Count; i++) - { - var parameter = Parameters[i]; - if (i > 0) - { - builder.Append(","); - } - - builder.Append(parameter is TypeBase ? ((TypeBase)parameter).Name : parameter); - } - - builder.Append(">"); - - return builder.ToString(); - } - - /// - /// Gets or sets the parameter types. - /// - /// - /// The parameter types. - /// - [DataMemberIgnore] // By default don't store it, unless derived class are overriding this member - [VisitorIgnore] - public virtual List ParameterTypes { get; set; } - - /// - /// Gets or sets the parameters. - /// - /// - /// The parameters. - /// - [DataMemberIgnore] // By default don't store it, unless derived class are overriding this member - [VisitorIgnore] - public virtual List Parameters { get; set; } - - public virtual TypeBase ToNonGenericType(SourceSpan? span = null) - { - return this; - } - - #endregion - - #region Public Methods - - /// - /// Equalses the specified other. - /// - /// - /// The other. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(GenericBaseType other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - //return base.Equals(other) && ParameterTypes.SequenceEqual(other.ParameterTypes) && Parameters.SequenceEqual(other.Parameters); - return base.Equals(other) && Parameters.SequenceEqual(other.Parameters); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return Equals(obj as GenericBaseType); - } - - /// - /// Gets the child nodes. - /// - /// - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - foreach (var parameter in Parameters) - { - if (parameter != null) - { - ChildrenList.Add(parameter); - } - } - - return ChildrenList; - } - - /// - public override int GetHashCode() - { - var hashCode = base.GetHashCode() * 397; - foreach (var parameter in Parameters) - { - hashCode = (hashCode * 397) ^ (parameter != null ? parameter.GetHashCode() : 0); - } - - return hashCode; - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(GenericBaseType left, GenericBaseType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(GenericBaseType left, GenericBaseType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/GenericDeclaration.cs b/sources/shaders/Stride.Core.Shaders/Ast/GenericDeclaration.cs deleted file mode 100644 index e77e842a1f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/GenericDeclaration.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A generic declaration. This is used internally to identify a generic declaration. - /// - public partial class GenericDeclaration : Node, IDeclaration - { - /// - /// Initializes a new instance of the class. - /// - public GenericDeclaration() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The holder. - /// The index. - /// if set to true [is using base]. - public GenericDeclaration(Identifier name, IGenerics holder, int index, bool isUsingBase) - { - Name = name; - Holder = holder; - Index = index; - IsUsingBase = isUsingBase; - } - - /// - /// Gets or sets the name of this declaration - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the holder. - /// - /// - /// The holder. - /// - public IGenerics Holder { get; set; } - - /// - /// Gets or sets the index. - /// - /// - /// The index. - /// - public int Index { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is using base. - /// - /// - /// true if this instance is using base; otherwise, false. - /// - public bool IsUsingBase { get; set; } - - public bool Equals(GenericDeclaration other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Equals(other.Name, Name) && Equals(other.Holder, Holder) && other.Index == Index && other.IsUsingBase.Equals(IsUsingBase); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof(GenericDeclaration)) return false; - return Equals((GenericDeclaration)obj); - } - - public override int GetHashCode() - { - unchecked - { - int result = Name.GetHashCode(); - result = (result * 397) ^ Holder.GetHashCode(); - result = (result * 397) ^ Index; - result = (result * 397) ^ IsUsingBase.GetHashCode(); - return result; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterConstraint.cs b/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterConstraint.cs deleted file mode 100644 index 07fe6a8270..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterConstraint.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Generic parameter for a method that provides a constraint resolver. - /// - [DataContract] - public class GenericParameterConstraint - { - /// - /// Initializes a new instance of the class. - /// - /// The name. - public GenericParameterConstraint(string name) - { - Name = name; - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The constraint. - public GenericParameterConstraint(string name, Func constraint) - { - Name = name; - Constraint = constraint; - } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public string Name { get; set; } - - - /// - /// Gets or sets the constraint match function. - /// - /// - /// The constraint match function. - /// - public Func Constraint { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterType.cs b/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterType.cs deleted file mode 100644 index 6b07451661..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/GenericParameterType.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Defines a generic parameter type. - /// - public partial class GenericParameterType : TypeBase - { - /// - /// Initializes a new instance of the class. - /// - public GenericParameterType() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public GenericParameterType(string name) - : base(name) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public GenericParameterType(Identifier name) - : base(name) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/GenericType.cs b/sources/shaders/Stride.Core.Shaders/Ast/GenericType.cs deleted file mode 100644 index 2388e2a9da..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/GenericType.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Custom generic type. - /// - public partial class GenericType : GenericBaseType - { - public GenericType() - { - } - - public GenericType(string name, int parameterCount) : base(name, parameterCount) - { - } - - /// - [DataMember] - public override List ParameterTypes { get; set; } - - /// - [DataMember] - public override List Parameters { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/InterfaceType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Glsl/InterfaceType.cs deleted file mode 100644 index 48b640e207..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/InterfaceType.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Glsl -{ - /// - /// An interface type. - /// - public partial class InterfaceType : StructType - { - public InterfaceType() - { - } - - public InterfaceType(string name) - { - Name = name; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutKeyValue.cs b/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutKeyValue.cs deleted file mode 100644 index d64cb91977..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutKeyValue.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Glsl -{ - /// - /// LayoutKey value node. - /// - public partial class LayoutKeyValue : Node - { - /// - /// Initializes a new instance of the class. - /// - public LayoutKeyValue() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public LayoutKeyValue(Identifier name) - { - Name = name; - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The value. - public LayoutKeyValue(Identifier name, LiteralExpression value) - { - Name = name; - Value = value; - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The value. - public LayoutKeyValue(Identifier name, object value) - { - Name = name; - Value = new LiteralExpression(value); - } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the value. - /// - /// - /// The value. - /// - public LiteralExpression Value { get; set; } - - /// - public override System.Collections.Generic.IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.Add(Value); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}{1}", Name, Value == null ? string.Empty : "=" + Value); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutQualifier.cs deleted file mode 100644 index 0867584592..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/LayoutQualifier.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast.Glsl -{ - /// - /// Describe a register location - /// - public partial class LayoutQualifier : Qualifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public LayoutQualifier() : base("layout") - { - Layouts = new List(); - IsPost = false; - } - - /// - /// Initializes a new instance of the class. - /// - /// The layouts. - public LayoutQualifier(params LayoutKeyValue[] layouts) : this() - { - Layouts.AddRange(layouts); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the profile. - /// - /// - /// The profile. - /// - public List Layouts { get; set; } - - #endregion - - #region Public Methods - - - - /// - public override IEnumerable Childrens() - { - return Layouts; - } - - /// - public override string DisplayName - { - get - { - var builder = new StringBuilder(); - builder.Append("layout("); - for (int i = 0; i < Layouts.Count; i++) - { - if (i > 0) builder.Append(", "); - builder.Append(Layouts[i]); - } - builder.Append(")"); - return builder.ToString(); - } - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/ParameterQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Glsl/ParameterQualifier.cs deleted file mode 100644 index c77579ccc0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/ParameterQualifier.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Glsl -{ - /// - /// Specialized ParameterQualifier for Hlsl. - /// - public static class ParameterQualifier - { - /// - /// Varying modifier, only for OpenGL ES 2.0. - /// - public static readonly Qualifier Varying = new Qualifier("varying"); - - /// - /// Attribute modifier, only for OpenGL ES 2.0. - /// - public static readonly Qualifier Attribute = new Qualifier("attribute"); - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A parameter qualifier - /// - public static Qualifier Parse(string enumName) - { - if (enumName == (string)Varying.Key) - return Varying; - if (enumName == (string)Attribute.Key) - return Attribute; - - // Fallback to shared parameter qualifiers - return Ast.ParameterQualifier.Parse(enumName); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/StorageQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Glsl/StorageQualifier.cs deleted file mode 100644 index 9d96837a62..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Glsl/StorageQualifier.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core.Shaders.Ast.Glsl; - -/// -/// Defines known GLSL storage qualifiers. -/// -public static class StorageQualifier -{ - #region Storage Qualifier keys - - private const string UniformKey = "uniform"; - private const string BufferKey = "buffer"; - private const string WriteOnlyKey = "writeonly"; - private const string ReadOnlyKey = "readonly"; - - #endregion - - /// - /// The "uniform" qualifier. - /// Specifies that the variable is a uniform parameter, typically set externally by the application - /// and shared across shader invocations. - /// - public static readonly Qualifier Uniform = new(UniformKey); - - /// - /// The "buffer" qualifier. - /// Specifies that the variable is associated with a shader storage buffer object (SSBO), - /// and can be used for read and write operations. - /// - public static readonly Qualifier Buffer = new(BufferKey); - - /// - /// The "writeonly" qualifier. - /// Specifies that the variable is write-only, meaning it can only be written - /// to within the shader and not read from. - /// - public static readonly Qualifier WriteOnly = new(WriteOnlyKey); - - /// - /// The "readonly" qualifier. - /// Specifies that the variable is read-only, meaning it can only be - /// read within the shader and not written to. - /// - public static readonly Qualifier ReadOnly = new(ReadOnlyKey); - - - /// - /// Parses the specified qualifier name into a storage qualifier. - /// - /// The name of the qualifier to parse. - /// - /// A storage , or if the qualifier name is not recognized. - /// - public static Qualifier Parse(string qualifierName) - { - return qualifierName switch - { - UniformKey => Uniform, - BufferKey => Buffer, - WriteOnlyKey => WriteOnly, - ReadOnlyKey => ReadOnly, - - _ => null - }; - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Annotations.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Annotations.cs deleted file mode 100644 index b0003b587a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Annotations.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// An Annotations. - /// - public partial class Annotations : PostAttributeBase - { - /// - /// Initializes a new instance of the class. - /// - public Annotations() - { - Variables = new List(); - } - - /// - /// Gets or sets the variable. - /// - /// - /// The variable. - /// - public List Variables { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AsmExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AsmExpression.cs deleted file mode 100644 index 3ef840b7b2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AsmExpression.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A raw asm expression. - /// - public partial class AsmExpression : Expression - { - #region Public Properties - - /// - /// Gets or sets the asm expression in raw text form. - /// - /// - /// The asm expression in raw text form. - /// - public string Text { get; set; } - - #endregion - - public override string ToString() - { - return "asm { ... }"; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AttributeDeclaration.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AttributeDeclaration.cs deleted file mode 100644 index 1036073ce6..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/AttributeDeclaration.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Describes an attribute. - /// - public partial class AttributeDeclaration : AttributeBase - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public AttributeDeclaration() - { - Parameters = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the parameters. - /// - /// - /// The parameters. - /// - public List Parameters { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - return Parameters; - } - - /// - public override string ToString() - { - return string.Format("[{0}({1})]", Name, string.Join(",", Parameters)); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ByteAddressBufferType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ByteAddressBufferType.cs deleted file mode 100644 index dea7e9fda7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ByteAddressBufferType.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public static class ByteAddressBufferType - { - public static readonly ObjectType ByteAddressBuffer = new ObjectType("ByteAddressBuffer"); - - public static readonly ObjectType RWByteAddressBuffer = new ObjectType("RWByteAddressBuffer"); - - private static readonly ObjectType[] ObjectTypes = new[] { ByteAddressBuffer, RWByteAddressBuffer }; - - public static bool IsByteAddressBufferType(this TypeBase type) - { - return Parse(type.Name) != null; - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static ObjectType Parse(string name) - { - foreach (var objectType in ObjectTypes) - { - if (string.Compare(name, objectType.Name.Text, StringComparison.OrdinalIgnoreCase) == 0) - return objectType; - } - return null; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CastExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CastExpression.cs deleted file mode 100644 index e07b8dc0bc..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CastExpression.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A cast expression. - /// - public partial class CastExpression : Expression - { - #region Public Properties - - /// - /// Gets or sets from. - /// - /// - /// From. - /// - public Expression From { get; set; } - - /// - /// Gets or sets the target. - /// - /// - /// The target. - /// - public TypeBase Target { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Target); - ChildrenList.Add(From); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("({0}){1}", Target, From); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.Helpers.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.Helpers.cs deleted file mode 100644 index 8efd54add1..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.Helpers.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Definition of a class. - /// - public partial class ClassType - { - /// - /// Determines whether the specified type is a a stream type. - /// - /// Type of the target. - /// true if [the specified target type] [is stream type] ; otherwise, false. - public static bool IsStreamOutputType(TypeBase targetType) - { - return targetType is ClassType && ((ClassType)targetType).GenericArguments.Count > 0 && targetType.IsStreamTypeName(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.cs deleted file mode 100644 index 3f8289ef0b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ClassType.cs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Definition of a class. - /// - public partial class ClassType : ObjectType, IDeclaration, IScopeContainer, IGenerics - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ClassType() - : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public ClassType(string name) - : base(name) - { - BaseClasses = new List(); - Members = new List(); - GenericParameters = new List(); - GenericArguments = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the base classes. - /// - /// - /// The base classes. - /// - public List BaseClasses { get; set; } - - /// - public List GenericParameters { get; set; } - - /// - public List GenericArguments { get; set; } - - /// - /// Gets or sets the members. - /// - /// - /// The members. - /// - public List Members { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(BaseClasses); - ChildrenList.AddRange(Members); - return ChildrenList; - } - - /// - public override string ToString() - { - var bases = new StringBuilder(); - foreach (var baseClass in BaseClasses) - { - bases.Append(" : ").Append(baseClass); - } - var generics = new StringBuilder(); - if (GenericParameters.Count > 0) - { - generics.Append("<"); - for (int i = 0; i < GenericParameters.Count; i++) - { - var genericArgument = GenericArguments.Count == GenericParameters.Count ? GenericArguments[i] : GenericParameters[i]; - if (i > 0) generics.Append(", "); - generics.Append(genericArgument); - } - generics.Append(">"); - } - - return string.Format("class {0}{1}{2} {{...}}", Name, generics, bases); - } - - /// - public bool Equals(ClassType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as ClassType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(ClassType left, ClassType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(ClassType left, ClassType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompileExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompileExpression.cs deleted file mode 100644 index 29e16d9d46..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompileExpression.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A Compile expression. - /// - public partial class CompileExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public CompileExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The profile. - /// - /// - /// The function. - /// - public CompileExpression(string profile, MethodInvocationExpression function) - { - Profile = new Identifier(profile); - Function = function; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the function. - /// - /// - /// The function. - /// - public Expression Function { get; set; } - - /// - /// Gets or sets the profile. - /// - /// - /// The profile. - /// - public Identifier Profile { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Profile); - ChildrenList.Add(Function); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("compile {0} {1}", Profile, Function); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompositeIdentifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompositeIdentifier.cs deleted file mode 100644 index c5f8d296ac..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/CompositeIdentifier.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A composite identifier. - /// - public abstract partial class CompositeIdentifier : Identifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public CompositeIdentifier() - { - Identifiers = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the path. - /// - /// - /// The path. - /// - public List Identifiers { get; set; } - - #endregion - - #region Public Methods - - /// - /// Gets the separator. - /// - public abstract string Separator { get; } - - public bool Equals(CompositeIdentifier other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return base.Equals(other) && (Identifiers.Count != other.Identifiers.Count); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return Equals(obj as CompositeIdentifier); - } - - /// - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ Identifiers.GetHashCode(); - } - } - - /// - public override IEnumerable Childrens() - { - return Identifiers; - } - - /// - public override string ToString() - { - var ranks = new StringBuilder(); - if (Indices != null) - { - foreach (var expression in Indices) - { - ranks.Append("[").Append(expression).Append("]"); - } - } - - return string.Format(IsSpecialReference ? "<{0}{1}>" : "{0}{1}", string.Join(Separator, Identifiers), ranks); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBuffer.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBuffer.cs deleted file mode 100644 index b7b8dcf847..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBuffer.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Declaration of a constant buffer. - /// - public partial class ConstantBuffer : Node, IAttributes - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ConstantBuffer() - { - Members = new List(); - Attributes = new List(); - Qualifiers = Qualifier.None; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - public List Attributes { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is texture buffer. - /// - /// - /// true if this instance is texture buffer; otherwise, false. - /// - public ConstantBufferType Type { get; set; } - - /// - /// Gets or sets the members. - /// - /// - /// The members. - /// - public List Members { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the register. - /// - /// - /// The register. - /// - public RegisterLocation Register { get; set; } - - /// - /// Gets or sets the qualifiers. - /// - /// - /// The qualifiers. - /// - public Qualifier Qualifiers { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.AddRange(Attributes); - ChildrenList.Add(Type); - if (Name != null) ChildrenList.Add(Name); - if (Register != null) ChildrenList.Add(Register); - ChildrenList.AddRange(Members); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} {1} {{...}}", Type, Name); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBufferType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBufferType.cs deleted file mode 100644 index 69833b1e9f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ConstantBufferType.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Type of constant buffer. - /// - public partial class ConstantBufferType : CompositeEnum - { - #region Constants and Fields - - /// - /// Constant buffer (cbuffer). - /// - public static readonly ConstantBufferType Constant = new ConstantBufferType("cbuffer"); - - /// - /// Texture buffer (tbuffer). - /// - public static readonly ConstantBufferType Texture = new ConstantBufferType("tbuffer"); - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ConstantBufferType() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The key. - /// - public ConstantBufferType(string key) - : base(key, false) - { - } - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A qualifier - /// - public static ConstantBufferType Parse(string enumName) - { - if (enumName == (string)Constant.Key) - return Constant; - if (enumName == (string)Texture.Key) - return Texture; - - throw new ArgumentException(string.Format("Unable to convert [{0}] to constant buffer type", enumName), "key"); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/FloatQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/FloatQualifier.cs deleted file mode 100644 index 151010f818..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/FloatQualifier.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Value range for a float - /// - public partial class FloatQualifier - { - #region Constants and Fields - - /// - /// IEEE 32-bit signed-normalized float in range -1 to 1 inclusive. - /// - public static readonly Qualifier SNorm = new Qualifier("snorm"); - - /// - /// IEEE 32-bit unsigned-normalized float in range 0 to 1 inclusive. - /// - public static readonly Qualifier UNorm = new Qualifier("unorm"); - - #endregion - - #region Public Methods - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A qualifier - /// - public static Qualifier Parse(string enumName) - { - if (enumName == (string)SNorm.Key) - return SNorm; - if (enumName == (string)UNorm.Key) - return UNorm; - - throw new ArgumentException(string.Format("Unable to convert [{0}] to qualifier", enumName), "key"); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/GenericType.Extensions.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/GenericType.Extensions.cs deleted file mode 100644 index 76fee579ef..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/GenericType.Extensions.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public static class GenericTypeExtensions - { - - public static TypeBase MakeGenericInstance(this GenericBaseType genericType, TypeBase genericTemplateType) - { - // TODO cache generic instance that are using predefined hlsl types - var newType = genericTemplateType.DeepClone(); - - var genericParameters = ((IGenerics)newType).GenericParameters; - var genericArguments = ((IGenerics)newType).GenericArguments; - var genericInstanceParameters = genericType.Parameters; - - var genericParameterTypes = new TypeBase[genericParameters.Count]; - var genericBaseParameterTypes = new TypeBase[genericParameters.Count]; - - // Look for parameter instance types - for (int i = 0; i < genericInstanceParameters.Count; i++) - { - var genericInstanceParameter = genericInstanceParameters[i]; - if (genericInstanceParameter is TypeBase) - { - var genericInstanceParameterType = (TypeBase)genericInstanceParameter; - genericParameterTypes[i] = genericInstanceParameterType; - genericBaseParameterTypes[i] = TypeBase.GetBaseType(genericInstanceParameterType); - genericParameters[i] = genericParameterTypes[i]; - genericArguments.Add(genericInstanceParameterType); - } - } - - // Replace all references to template arguments to their respective generic instance types - SearchVisitor.Run( - newType, - node => - { - var typeInferencer = node as ITypeInferencer; - if (typeInferencer != null && typeInferencer.TypeInference.Declaration is GenericDeclaration) - { - var genericDeclaration = (GenericDeclaration)typeInferencer.TypeInference.Declaration; - var i = genericDeclaration.Index; - var targeType = genericDeclaration.IsUsingBase ? genericBaseParameterTypes[i] : genericParameterTypes[i]; - - if (node is TypeBase) - return targeType.ResolveType(); - } - - return node; - }); - - - return newType; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierDot.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierDot.cs deleted file mode 100644 index 61f2c66bd5..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierDot.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// C# namespace or class. - /// - public partial class IdentifierDot : CompositeIdentifier - { - /// - public override string Separator - { - get - { - return "."; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierGeneric.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierGeneric.cs deleted file mode 100644 index 3678260b90..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierGeneric.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Linq; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A generic identifier in the form Typename<identifier1,..., identifiern> - /// - public partial class IdentifierGeneric : CompositeIdentifier - { - /// - /// Initializes a new instance of the class. - /// - public IdentifierGeneric() - { - IsSpecialReference = true; - } - - public IdentifierGeneric(string name, params Identifier[] composites) - : this() - { - Text = name; - Identifiers = composites.ToList(); - } - - /// - public override string Separator - { - get - { - return ","; - } - } - - /// - public override string ToString() - { - return string.Format("{0}{1}", Text, Identifiers.Count == 0 ? string.Empty : base.ToString()); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierNs.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierNs.cs deleted file mode 100644 index d7f55cef5a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/IdentifierNs.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A C++ identifier with namespaces "::" separator - /// - public partial class IdentifierNs : CompositeIdentifier - { - /// - public override string Separator - { - get - { - return "::"; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterfaceType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterfaceType.cs deleted file mode 100644 index fc84bfa4d7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterfaceType.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Definition of a class. - /// - public partial class InterfaceType : ObjectType, IDeclaration, IGenerics - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public InterfaceType() - : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public InterfaceType(string name) - : base(name) - { - Methods = new List(); - GenericParameters = new List(); - GenericArguments = new List(); - } - - #endregion - - #region Public Properties - - /// - public List GenericParameters { get; set; } - - /// - public List GenericArguments { get; set; } - - /// - /// Gets or sets the methods. - /// - /// - /// The methods. - /// - public List Methods { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(Methods); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("interface {0} {{...}}", Name); - } - - /// - public bool Equals(InterfaceType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as InterfaceType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(InterfaceType left, InterfaceType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(InterfaceType left, InterfaceType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterpolationQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterpolationQualifier.cs deleted file mode 100644 index efa6389673..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/InterpolationQualifier.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core.Shaders.Ast.Hlsl; - -/// -/// A syntax node representing a HLSL interpolation qualifier. -/// -/// -public class InterpolationQualifier : Qualifier -{ - #region Interpolation Qualifier Keys - - private const string CentroidKey = "centroid"; - private const string LinearKey = "linear"; - private const string NoPerspectiveKey = "noperspective"; - private const string NointerpolationKey = "nointerpolation"; - private const string SampleKey = "sample"; - - #endregion - - /// - /// The "centroid" modifier, only valid for structure fields. - /// Indicates that interpolation should be performed at the centroid of the covered fragments, - /// which can help avoid artifacts at triangle edges. - /// - public static readonly InterpolationQualifier Centroid = new(CentroidKey); - - /// - /// The "linear" modifier, only valid for structure fields. - /// Specifies that interpolation should be linear in screen space. - /// - public static readonly InterpolationQualifier Linear = new(LinearKey); - - /// - /// The "noperspective" modifier, only valid for structure fields. - /// Indicates that interpolation should be performed without perspective correction, - /// useful for certain graphical effects. - /// - public static readonly InterpolationQualifier NoPerspective = new(NoPerspectiveKey); - - /// - /// The "nointerpolation" modifier. - /// Specifies that no interpolation should be performed; the value is copied directly from the corresponding vertex. - /// - public static readonly InterpolationQualifier Nointerpolation = new(NointerpolationKey); - - /// - /// The "sample" modifier, only valid for structure fields. - /// Indicates that interpolation should be performed at the exact sample location, - /// useful for multi-sample techniques (MSAA). - /// - public static readonly InterpolationQualifier Sample = new(SampleKey); - - - /// - /// Initializes a new instance of the class. - /// - public InterpolationQualifier() : base() { } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the interpolation qualifier. - public InterpolationQualifier(object key) : base(key) { } - - - /// - /// Parses the specified qualifier name into an interpolation qualifier. - /// - /// The name of the qualifier to parse. - /// - /// An interpolation , or if the qualifier name is not recognized. - /// - public static Qualifier? Parse(string qualifierName) - { - return qualifierName switch - { - CentroidKey => Centroid, - LinearKey => Linear, - NoPerspectiveKey => NoPerspective, - NointerpolationKey => Nointerpolation, - SampleKey => Sample, - - _ => null - }; - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/PackOffset.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/PackOffset.cs deleted file mode 100644 index d81d450570..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/PackOffset.cs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text.RegularExpressions; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Describes a packoffset(value). - /// - public partial class PackOffset : Qualifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public PackOffset() - : base("packoffset") - { - IsPost = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The value. - /// - public PackOffset(string value) - : base("packoffset") - { - var identifier = new IdentifierDot(); - identifier.Identifiers.Add(new Identifier(value)); - Value = identifier; - IsPost = true; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the value. - /// - /// - /// The value. - /// - public Identifier Value { get; set; } - - #endregion - - #region Public Methods - - - private static readonly Regex matchComponent = new Regex(@"^c(\d+)(\.[xyzw])?$"); - - /// - /// Converts this packoffset to a register index based on float size. - /// - /// An offset - public int ToFloat4SlotIndex() - { - var match = matchComponent.Match(Value.ToString()); - if (!match.Success) - return -1; - var index = int.Parse(match.Groups[1].Value) * 16; - if (match.Groups[2].Success) - { - var subComponentChar = match.Groups[2].Value[1]; - index += "xyzw".IndexOf(subComponentChar)* 4; - } - return index; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// - /// The to compare with this instance. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(PackOffset other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return base.Equals(other) && Equals(other.Value, Value); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return Equals(obj as PackOffset); - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Value); - return ChildrenList; - } - - /// - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ (Value != null ? Value.GetHashCode() : 0); - } - } - - /// - public override string DisplayName - { - get - { - return string.Format(": packoffset({0})", Value); - } - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(PackOffset left, PackOffset right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(PackOffset left, PackOffset right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ParameterQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ParameterQualifier.cs deleted file mode 100644 index 0b69d99423..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/ParameterQualifier.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Specialized ParameterQualifier for Hlsl. - /// - public static class ParameterQualifier - { - - /// - /// Point modifier, only for method parameters in Geometry Shader. - /// - public static readonly Qualifier Point = new Qualifier("point"); - - /// - /// Line modifier, only for method parameters in Geometry Shader. - /// - public static readonly Qualifier Line = new Qualifier("line"); - - /// - /// LineAdjacent modifier, only for method parameters in Geometry Shader. - /// - public static readonly Qualifier LineAdj = new Qualifier("lineadj"); - - /// - /// Triangle modifier, only for method parameters in Geometry Shader. - /// - public static readonly Qualifier Triangle = new Qualifier("triangle"); - - /// - /// TriangleAdjacent modifier, only for method parameters in Geometry Shader. - /// - public static readonly Qualifier TriangleAdj = new Qualifier("triangleadj"); - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A parameter qualifier - /// - public static Qualifier Parse(string enumName) - { - if (enumName == (string)Point.Key) - return Point; - if (enumName == (string)Line.Key) - return Line; - if (enumName == (string)LineAdj.Key) - return LineAdj; - if (enumName == (string)Triangle.Key) - return Triangle; - if (enumName == (string)TriangleAdj.Key) - return TriangleAdj; - - // Fallback to shared parameter qualifiers - return Ast.ParameterQualifier.Parse(enumName); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Pass.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Pass.cs deleted file mode 100644 index 975293f4a2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Pass.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A technique pass. - /// - public partial class Pass : Node, IAttributes - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Pass() - { - Attributes = new List(); - Items = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - public List Attributes { get; set; } - - /// - /// Gets or sets the items. - /// - /// - /// The items. - /// - /// - /// An item is either a or a . - /// - public List Items { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(Attributes); - ChildrenList.AddRange(Items); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("pass {0}{{...}}", Name != null ? Name + " " : string.Empty); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/RegisterLocation.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/RegisterLocation.cs deleted file mode 100644 index bd18612997..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/RegisterLocation.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Describe a register location - /// - public partial class RegisterLocation : Qualifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public RegisterLocation() - : base("register") - { - IsPost = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The profile. - /// - /// - /// The idenfitier. - /// - public RegisterLocation(Identifier profile, Identifier idenfitier) - : base("register") - { - Profile = profile; - Register = idenfitier; - IsPost = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The profile. - /// - /// - /// The idenfitier. - /// - public RegisterLocation(string profile, Identifier idenfitier) - : base("register") - { - Profile = new Identifier(profile); - Register = idenfitier; - IsPost = true; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the profile. - /// - /// - /// The profile. - /// - public Identifier Profile { get; set; } - - /// - /// Gets or sets the register. - /// - /// - /// The register. - /// - public Identifier Register { get; set; } - - #endregion - - #region Public Methods - - /// - /// Determines whether the specified is equal to this instance. - /// - /// - /// The to compare with this instance. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(RegisterLocation other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return base.Equals(other) && Equals(other.Profile, Profile) && Equals(other.Register, Register); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return Equals(obj as RegisterLocation); - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - if (Profile != null) - { - ChildrenList.Add(Profile); - } - - ChildrenList.Add(Register); - return ChildrenList; - } - - /// - public override int GetHashCode() - { - unchecked - { - int result = base.GetHashCode(); - result = (result * 397) ^ (Profile != null ? Profile.GetHashCode() : 0); - result = (result * 397) ^ (Register != null ? Register.GetHashCode() : 0); - return result; - } - } - - /// - public override string DisplayName - { - get - { - return Profile == null ? string.Format(": register({0})", Register) : string.Format(": register({0},{1})", Profile, Register); - } - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(RegisterLocation left, RegisterLocation right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(RegisterLocation left, RegisterLocation right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/SamplerType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/SamplerType.cs deleted file mode 100644 index f477a60256..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/SamplerType.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A State type. - /// - public static class SamplerType - { - /// - /// A sampler. - /// - public static readonly ObjectType Sampler = new ObjectType("sampler"); - - /// - /// A sampler1D. - /// - public static readonly ObjectType Sampler1D = new ObjectType("sampler1D"); - - /// - /// A sampler2D - /// - public static readonly ObjectType Sampler2D = new ObjectType("sampler2D"); - - /// - /// A sampler3D. - /// - public static readonly ObjectType Sampler3D = new ObjectType("sampler3D"); - - /// - /// A samplerCUBE. - /// - public static readonly ObjectType SamplerCube = new ObjectType("samplerCUBE"); - - - private static readonly ObjectType[] ObjectTypes = new[] { Sampler, Sampler1D, Sampler2D, Sampler3D, SamplerCube }; - - public static bool IsSamplerType(this TypeBase type) - { - return Parse(type.Name) != null; - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static ObjectType Parse(string name) - { - foreach (var stateType in ObjectTypes) - { - if (string.Compare(name, stateType.Name.Text, StringComparison.OrdinalIgnoreCase) == 0) - return stateType; - } - return null; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Semantic.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Semantic.cs deleted file mode 100644 index 28f847380b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Semantic.cs +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - using System.Text.RegularExpressions; - - /// - /// Describes a semantic. - /// - public partial class Semantic : Qualifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Semantic() - : base("semantic") - { - IsPost = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public Semantic(string name) - : base("semantic") - { - Name = new Identifier(name); - IsPost = true; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets the base name of a semantic (COLOR1 -> COLOR) - /// - /// - /// The base name of sematnic. - /// - public string BaseName - { - get - { - var match = MatchSemanticName.Match(Name.Text); - return match.Groups[1].Value; - } - } - - /// - /// Parses the specified semantic. - /// - /// The semantic. - /// The base name and index. COLOR1 -> {COLOR, 1} - public static KeyValuePair Parse(string text) - { - var match = MatchSemanticName.Match(text); - if (!match.Success) - return new KeyValuePair(text, 0); - - string baseName = match.Groups[1].Value; - int value = 0; - if (!string.IsNullOrEmpty(match.Groups[2].Value)) - { - value = int.Parse(match.Groups[2].Value); - } - - return new KeyValuePair(baseName, value); - } - - #endregion - - #region Public Methods - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - /// - public bool Equals(Semantic other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return base.Equals(other) && Equals(other.Name, Name); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return Equals(obj as Semantic); - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - return ChildrenList; - } - - /// - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ (Name != null ? Name.GetHashCode() : 0); - } - } - - /// - public override string DisplayName - { - get - { - return string.Format(": {0}", Name); - } - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(Semantic left, Semantic right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(Semantic left, Semantic right) - { - return !Equals(left, right); - } - - private static readonly Regex MatchSemanticName = new Regex(@"([A-Za-z_]+)(\d*)"); - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateExpression.cs deleted file mode 100644 index 4739e51753..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateExpression.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A state expresion in the form: sampler {...}. - /// - public partial class StateExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public StateExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// Type of the state. - /// - /// - /// The initializer. - /// - public StateExpression(TypeName stateType, StateInitializer initializer) - { - this.StateType = stateType; - this.Initializer = initializer; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the initializer. - /// - /// - /// The initializer. - /// - public StateInitializer Initializer { get; set; } - - /// - /// Gets or sets the type of the sampler. - /// - /// - /// The type of the sampler. - /// - public TypeBase StateType { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(StateType); - ChildrenList.Add(Initializer); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} {1}", StateType, Initializer); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateInitializer.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateInitializer.cs deleted file mode 100644 index 97181e0512..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateInitializer.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A set of state values. - /// - public partial class StateInitializer : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public StateInitializer() - { - Items = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the fields. - /// - /// - /// The fields. - /// - public List Items { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - return Items; - } - - /// - public override string ToString() - { - return "{...}"; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateType.cs deleted file mode 100644 index 2929662b01..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StateType.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Linq; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A State type. - /// - public static class StateType - { - #region Constants and Fields - - /// - /// A BlendState. - /// - public static readonly ObjectType BlendState = new ObjectType("BlendState"); - - /// - /// A DepthStencilState. - /// - public static readonly ObjectType DepthStencilState = new ObjectType("DepthStencilState"); - - /// - /// A RasterizerState - /// - public static readonly ObjectType RasterizerState = new ObjectType("RasterizerState"); - - /// - /// A SamplerState. - /// - public static readonly ObjectType SamplerState = new ObjectType("SamplerState"); - - /// - /// An old sampler_state declaration. - /// - public static readonly ObjectType SamplerStateOld = new ObjectType("sampler_state"); - - /// - /// A SamplerComparisonState. - /// - public static readonly ObjectType SamplerComparisonState = new ObjectType("SamplerComparisonState"); - - private static readonly ObjectType[] ObjectTypes = new[] { BlendState, DepthStencilState, RasterizerState, SamplerState, SamplerStateOld, SamplerComparisonState }; - private static readonly ObjectType[] SamplerStateTypes = new[] { SamplerState, SamplerStateOld, SamplerComparisonState }; - - #endregion - - public static bool IsStateType(this TypeBase type) - { - return type != null && Parse(type.Name) != null; - } - - public static bool IsSamplerStateType(this TypeBase type) - { - if (type == null) - return false; - - foreach (var objectType in SamplerStateTypes) - { - if (string.Compare(type.Name.Text, objectType.Name.Text, StringComparison.OrdinalIgnoreCase) == 0) - return true; - } - return false; - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static ObjectType Parse(string name) - { - foreach (var objectType in ObjectTypes) - { - if (string.Compare(name, objectType.Name.Text, StringComparison.OrdinalIgnoreCase) == 0) - return objectType; - } - return null; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StorageQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StorageQualifier.cs deleted file mode 100644 index c4d6dd4f77..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StorageQualifier.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core.Shaders.Ast.Hlsl; - -/// -/// Defines known HLSL storage qualifiers. -/// -public static class StorageQualifier -{ - #region Storage Qualifier keys - - private const string ColumnMajorKey = "column_major"; - private const string ExternKey = "extern"; - private const string PreciseKey = "precise"; - private const string RowMajorKey = "row_major"; - private const string StaticKey = "static"; - private const string InlineKey = "inline"; - private const string UnsignedKey = "unsigned"; - private const string VolatileKey = "volatile"; - - #endregion - - /// - /// The "column_major" modifier. - /// Specifies that matrix data is stored in column-major order in memory. - /// - public static readonly Qualifier ColumnMajor = new(ColumnMajorKey); - - /// - /// The "extern" modifier. - /// Indicates that the variable is defined externally and not within the current scope. - /// - public static readonly Qualifier Extern = new(ExternKey); - - /// - /// The "precise" modifier. - /// Ensures that calculations involving this variable are performed with maximum precision. - /// - public static readonly Qualifier Precise = new(PreciseKey); - - /// - /// The "row_major" modifier. - /// Specifies that matrix data is stored in row-major order in memory. - /// - public static readonly Qualifier RowMajor = new(RowMajorKey); - - /// - /// The "static" modifier. - /// Indicates that the variable retains its value between function calls or shader invocations. - /// - public static readonly Qualifier Static = new(StaticKey); - - /// - /// The "inline" modifier. - /// Suggests that the function should be inlined, replacing the call with the function body. - /// - public static readonly Qualifier Inline = new(InlineKey); - - /// - /// The "unsigned" modifier. - /// Specifies that the variable or type is unsigned. - /// - public static readonly Qualifier Unsigned = new(UnsignedKey); - - /// - /// The "volatile" modifier. - /// Indicates that the variable can be modified unexpectedly, such as by another thread or hardware. - /// - public static readonly Qualifier Volatile = new(VolatileKey); - - - /// - /// Parses the specified qualifier name into a storage qualifier. - /// - /// The name of the qualifier to parse. - /// A storage . - /// The qualifier name is not recognized. - public static Qualifier Parse(string qualifierName) - { - Qualifier? qualifier = qualifierName switch - { - ColumnMajorKey => ColumnMajor, - ExternKey => Extern, - PreciseKey => Precise, - RowMajorKey => RowMajor, - StaticKey => Static, - InlineKey => Inline, - UnsignedKey => Unsigned, - VolatileKey => Volatile, - - _ => null - }; - - return qualifier - // Fallback to parameter interpolation qualifiers - ?? InterpolationQualifier.Parse(qualifierName) - // Fallback to GLSL qualifiers - ?? Glsl.StorageQualifier.Parse(qualifierName) - // Fallback to common parameter qualifiers - ?? Ast.StorageQualifier.Parse(qualifierName); - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StreamTypeName.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StreamTypeName.cs deleted file mode 100644 index 2f45109e1c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/StreamTypeName.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Globalization; -using System.Linq; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A State type. - /// - public static class StreamTypeName - { - #region Constants and Fields - - /// - /// A PointStream - /// - public static readonly ObjectType PointStream = new ObjectType("PointStream"); - - /// - /// A LineStream. - /// - public static readonly ObjectType LineStream = new ObjectType("LineStream"); - - /// - /// A TriangleStream. - /// - public static readonly ObjectType TriangleStream = new ObjectType("TriangleStream"); - - private static readonly ObjectType[] StreamTypesName = new[] { PointStream, LineStream, TriangleStream }; - - #endregion - - public static bool IsStreamTypeName(this TypeBase type) - { - return Parse(type.Name) != null; - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static ObjectType Parse(string name) - { - return StreamTypesName.FirstOrDefault(streamType => CultureInfo.InvariantCulture.CompareInfo.Compare(name, streamType.Name.Text, CompareOptions.None) == 0); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Technique.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Technique.cs deleted file mode 100644 index 959531c554..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Technique.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Technique description. - /// - public partial class Technique : Node, IDeclaration, IAttributes - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Technique() - { - Attributes = new List(); - Passes = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public Identifier Type { get; set; } - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - public List Attributes { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the passes. - /// - /// - /// The passes. - /// - public List Passes { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.AddRange(Attributes); - ChildrenList.Add(Name); - ChildrenList.AddRange(Passes); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("technique {0}{{...}}", Name != null ? Name + " " : string.Empty); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/TextureType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/TextureType.cs deleted file mode 100644 index c62a7706d4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/TextureType.cs +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Globalization; -using System.Linq; - -using Irony.Parsing; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// A State type. - /// - public partial class TextureType : ObjectType - { - #region Constants and Fields - - /// - /// A Texture - /// - public static readonly TextureType Texture = new TextureType("texture"); - - /// - /// A Texture1D. - /// - public static readonly TextureType Texture1D = new TextureType("Texture1D", "texture1D"); - - /// - /// A Texture1DArray. - /// - public static readonly TextureType Texture1DArray = new TextureType("Texture1DArray", "texture1DArray"); - - /// - /// A Texture2D - /// - public static readonly TextureType Texture2D = new TextureType("Texture2D", "texture2D"); - - /// - /// A Texture2DArray. - /// - public static readonly TextureType Texture2DArray = new TextureType("Texture2DArray", "texture2DArray"); - - /// - /// A Texture3D. - /// - public static readonly TextureType Texture3D = new TextureType("Texture3D", "texture3D"); - - /// - /// An TextureCube. - /// - public static readonly TextureType TextureCube = new TextureType("TextureCube", "textureCube"); - - private static readonly TextureType[] TextureTypes = new[] { Texture, Texture1D, Texture1DArray, Texture2D, Texture2DArray, Texture3D, TextureCube }; - - #endregion - - /// - /// Initializes a new instance of the class. - /// - public TextureType() - { - IsBuiltIn = true; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public TextureType(string name, params string[] altNames) - : base(name, altNames) - { - IsBuiltIn = true; - } - - /// - public bool Equals(TextureType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as TextureType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(TextureType left, TextureType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(TextureType left, TextureType right) - { - return !Equals(left, right); - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static TextureType Parse(string name) - { - return TextureTypes.FirstOrDefault(textureType => CultureInfo.InvariantCulture.CompareInfo.Compare(name, textureType.Name.Text, CompareOptions.None) == 0); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Typedef.cs b/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Typedef.cs deleted file mode 100644 index 878ff2201a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Hlsl/Typedef.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast.Hlsl -{ - /// - /// Typedef declaration. - /// - public partial class Typedef : TypeBase, IDeclaration - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Typedef() : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The type base. - /// - public Typedef(TypeBase typeBase) - { - Type = typeBase; - Qualifiers = Qualifier.None; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the names. - /// - /// - /// The names. - /// - public List SubDeclarators { get; set; } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type { get; set; } - - /// - /// Gets a value indicating whether this instance is group. - /// - /// - /// true if this instance is group; otherwise, false. - /// - public bool IsGroup - { - get - { - return SubDeclarators != null && SubDeclarators.Count > 0; - } - } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Type); - if (IsGroup) - ChildrenList.AddRange(SubDeclarators); - return ChildrenList; - } - - /// - public override TypeBase ResolveType() - { - var type = TypeInference.TargetType ?? Type; - return type.ResolveType(); - } - - /// - public override string ToString() - { - var builder = new StringBuilder(); - if (IsGroup) - { - for (int i = 0; i < SubDeclarators.Count; i++) - { - var typedefDeclarator = SubDeclarators[i]; - if (i > 0) - builder.Append(", "); - builder.Append(typedefDeclarator.Name); - } - } - else - { - builder.Append(Name); - } - - return string.Format("typedef{0} {1} {2}", Qualifiers, Type, builder); - } - - #endregion - - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IAttributes.cs b/sources/shaders/Stride.Core.Shaders/Ast/IAttributes.cs deleted file mode 100644 index c37f53f560..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IAttributes.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - public interface IAttributes - { - List Attributes { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IDeclaration.cs b/sources/shaders/Stride.Core.Shaders/Ast/IDeclaration.cs deleted file mode 100644 index b3fa64c25c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IDeclaration.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// Toplevel interface for a declaration. - /// - public interface IDeclaration - { - /// - /// Gets or sets the name of this declaration - /// - /// - /// The name. - /// - Identifier Name { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IGenerics.cs b/sources/shaders/Stride.Core.Shaders/Ast/IGenerics.cs deleted file mode 100644 index 36c0f58a5b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IGenerics.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An interface used by generic definitions and instance. - /// - public interface IGenerics - { - /// - /// Gets or sets the generic arguments. - /// - /// - /// The generic arguments. - /// - List GenericParameters { get; set; } - - /// - List GenericArguments { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IQualifiers.cs b/sources/shaders/Stride.Core.Shaders/Ast/IQualifiers.cs deleted file mode 100644 index 5f85a4e9cd..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IQualifiers.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// Base interface for all node providing qualifiers. - /// - public interface IQualifiers - { - /// - /// Gets or sets the qualifiers. - /// - /// - /// The qualifiers. - /// - Qualifier Qualifiers { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IScopeContainer.cs b/sources/shaders/Stride.Core.Shaders/Ast/IScopeContainer.cs deleted file mode 100644 index 08cceffa19..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IScopeContainer.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// A tag interface to identify a container for scope declarations. - /// - public interface IScopeContainer - { - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ITypeInferencer.cs b/sources/shaders/Stride.Core.Shaders/Ast/ITypeInferencer.cs deleted file mode 100644 index f22e02018f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ITypeInferencer.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast -{ - /// - /// A tag interface for an object referencing a type. - /// - public interface ITypeInferencer - { - /// - /// Gets or sets the reference. - /// - /// - /// The reference. - /// - TypeInference TypeInference { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Identifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Identifier.cs deleted file mode 100644 index b3ab44eb9f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Identifier.cs +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An identifier. - /// - public partial class Identifier : Node - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Identifier() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public Identifier(string name) - { - Text = name; - } - - #endregion - - #region Public Properties - - /// - /// Gets a value indicating whether this instance has indices. - /// - /// - /// true if this instance has indices; otherwise, false. - /// - public bool HasIndices - { - get - { - return Indices != null && Indices.Count > 0; - } - } - - /// - /// Gets or sets the indices. - /// - /// - /// The indices. - /// - /// - /// This property can be null. - /// - public List Indices { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is a special reference using < > - /// - /// - /// true if this instance is special reference; otherwise, false. - /// - public bool IsSpecialReference { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public string Text { get; set; } - - #endregion - - #region Public Methods - - /// - /// Equalses the specified other. - /// - /// - /// The other. - /// - /// - /// true if equals to other. - /// - public bool Equals(Identifier other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - if (ReferenceEquals(this, other)) - { - return true; - } - return Equals(other.Text, this.Text) && other.IsSpecialReference.Equals(this.IsSpecialReference); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - var other = obj as Identifier; - if (other == null) - return false; - - return Equals(other.Text, Text) && other.IsSpecialReference == IsSpecialReference; - } - - /// - public override int GetHashCode() - { - unchecked - { - int result = this.Text != null ? this.Text.GetHashCode() : 0; - result = (result * 397) ^ this.IsSpecialReference.GetHashCode(); - return result; - } - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - /// - public override string ToString() - { - var ranks = new StringBuilder(); - if (Indices != null) - { - foreach (var expression in Indices) - { - ranks.Append("[").Append(expression).Append("]"); - } - } - - return string.Format(IsSpecialReference ? "<{0}{1}>" : "{0}{1}", this.Text, ranks); - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(Identifier left, Identifier right) - { - return Equals(left, right); - } - - /// - /// Performs an implicit conversion from to . - /// - /// The identifier. - /// - /// The result of the conversion. - /// - public static implicit operator string(Identifier identifier) - { - return identifier.ToString(); - } - - /// - /// Performs an implicit conversion from to . - /// - /// Name of the identifier. - /// - /// The result of the conversion. - /// - public static implicit operator Identifier(string identifierName) - { - return new Identifier(identifierName); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(Identifier left, Identifier right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IfStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/IfStatement.cs deleted file mode 100644 index d280b97fd6..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IfStatement.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// If statement. - /// - public partial class IfStatement : Statement - { - #region Public Properties - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Condition { get; set; } - - /// - /// Gets or sets the else. - /// - /// - /// The else. - /// - public Statement Else { get; set; } - - /// - /// Gets or sets the then. - /// - /// - /// The then. - /// - public Statement Then { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Condition); - ChildrenList.Add(Then); - ChildrenList.Add(Else); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("if ({0}) then {{...}}{1}", Condition, Else == null ? string.Empty : "..."); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IndexerExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/IndexerExpression.cs deleted file mode 100644 index efc53f1d12..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IndexerExpression.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Indexer expression. - /// - public partial class IndexerExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public IndexerExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The target. - /// - /// - /// The index. - /// - public IndexerExpression(Expression target, Expression index) - { - this.Target = target; - this.Index = index; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the index. - /// - /// - /// The index. - /// - public Expression Index { get; set; } - - /// - /// Gets or sets the target. - /// - /// - /// The target. - /// - public Expression Target { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Target); - ChildrenList.Add(Index); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}[{1}]", Target, Index); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/IronyBrowsableNode.cs b/sources/shaders/Stride.Core.Shaders/Ast/IronyBrowsableNode.cs deleted file mode 100644 index b3e2ca5f00..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/IronyBrowsableNode.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Linq; - -using Irony.Parsing; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Internal class to provides class browsable by Irony. - /// - internal class IronyBrowsableNode : IBrowsableAstNode - { - /// - /// Initializes a new instance of the class. - /// - /// The node. - public IronyBrowsableNode(Node node) - { - Node = node; - } - - /// - public Irony.Parsing.SourceLocation Location - { - get - { - return new Irony.Parsing.SourceLocation - { - SourceFilename = Node.Span.Location.FileSource, - Position = Node.Span.Location.Position, - Line = Node.Span.Location.Line, - Column = Node.Span.Location.Column - }; - } - } - - /// - /// Gets or sets the node. - /// - /// - /// The node. - /// - public Node Node { get; set; } - - /// - public IEnumerable GetChildNodes() - { - return from children in Node.Childrens() where children != null select new IronyBrowsableNode(children); - } - - /// - public override string ToString() - { - return Node.ToString(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/KeywordExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/KeywordExpression.cs deleted file mode 100644 index 2abb15fd11..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/KeywordExpression.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Keyword expression statement like continue; break; discard; - /// - public partial class KeywordExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public KeywordExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public KeywordExpression(Identifier name) - { - Name = name; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - return ChildrenList; - } - - /// - public override string ToString() - { - return Name; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Literal.cs b/sources/shaders/Stride.Core.Shaders/Ast/Literal.cs deleted file mode 100644 index 2cd4d69ed9..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Literal.cs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Text; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A field of a struct. - /// - public sealed partial class Literal : Node - { - private object value; - - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Literal() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The value. - /// - public Literal(object value) - { - Value = value; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the value. - /// - /// - /// The value. - /// - public object Value - { - get - { - return value; - } - - set - { - this.value = value; - Text = ConvertValueToString(value); - } - } - - /// - /// Gets or sets the text. - /// - /// - /// The text. - /// - public string Text { get; set; } - - - /// - /// Gets or sets the sub literals. - /// - /// - /// The sub literals. - /// - /// - /// This value can be null. - /// - public List SubLiterals { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - if (SubLiterals != null) ChildrenList.AddRange(SubLiterals); - return ChildrenList; - } - - /// - public override string ToString() - { - var str = Text; - if (SubLiterals != null) str = string.Join(" ", SubLiterals); - return string.Format("{0}", str); - } - - private static string ConvertValueToString(object value) - { - if (value is float) - { - string defaultString = ((float)value).ToString("g", CultureInfo.InvariantCulture); - if (!defaultString.Contains(".") && !defaultString.Contains("e")) - defaultString += ".0"; - return defaultString; - } - if (value is double) - { - string defaultString = ((double)value).ToString("g", CultureInfo.InvariantCulture); - if (!defaultString.Contains(".") && !defaultString.Contains("e")) - defaultString += ".0"; - return defaultString; - } - if (value is int) - return ((int)value).ToString(CultureInfo.InvariantCulture); - if (value is uint) - return ((uint)value).ToString(CultureInfo.InvariantCulture); - if (value is bool) - return (bool)value ? "true" : "false"; - - return value.ToString(); - } - - /// - public bool Equals(Literal other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - if (ReferenceEquals(this, other)) - { - return true; - } - return Equals(other.value, value); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - if (obj.GetType() != typeof(Literal)) - { - return false; - } - return Equals((Literal)obj); - } - - /// - public override int GetHashCode() - { - return (value != null ? value.GetHashCode() : 0); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(Literal left, Literal right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(Literal left, Literal right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/LiteralExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/LiteralExpression.cs deleted file mode 100644 index a94bbcc3b1..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/LiteralExpression.cs +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A literal expression. - /// - public partial class LiteralExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public LiteralExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The literal. - /// - public LiteralExpression(Literal literal) - { - Literal = literal; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The value. - /// - public LiteralExpression(object value) - { - Literal = new Literal(value); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the literal. - /// - /// - /// The literal. - /// - public Literal Literal { get; set; } - - /// - /// Gets or sets the text. - /// - /// - /// The text. - /// - [DataMemberIgnore] - public string Text - { - get { return Literal != null ? Literal.Text : null; } - set - { - if (Literal != null) - { - Literal.Text = value; - } - else - { - Literal = value == null ? null : new Literal() {Text = value}; - } - } - } - - /// - /// Gets or sets the value. - /// - /// - /// The value. - /// - [DataMemberIgnore] - public object Value - { - get { return Literal != null ? Literal.Value : null; } - set - { - if (Literal != null) - { - Literal.Value = value; - } - else - { - Literal = value == null ? null : new Literal(value); - } - } - } - - #endregion - - #region Public Methods - - public bool Equals(LiteralExpression other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Equals(other.Literal, Literal); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != typeof(LiteralExpression)) return false; - return Equals((LiteralExpression)obj); - } - - public override int GetHashCode() - { - return (Literal != null ? Literal.GetHashCode() : 0); - } - - public static bool operator ==(LiteralExpression left, LiteralExpression right) - { - return Equals(left, right); - } - - public static bool operator !=(LiteralExpression left, LiteralExpression right) - { - return !Equals(left, right); - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Literal); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}", Literal); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/MatrixType.cs b/sources/shaders/Stride.Core.Shaders/Ast/MatrixType.cs deleted file mode 100644 index 4bfa4f2b97..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/MatrixType.cs +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Matrix type. - /// - public partial class MatrixType : GenericBaseType - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public MatrixType() - : base("matrix", 3) - { - ParameterTypes.Add(typeof(TypeBase)); - ParameterTypes.Add(typeof(Literal)); - ParameterTypes.Add(typeof(Literal)); - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The type. - /// - /// - /// The row count. - /// - /// - /// The column count. - /// - public MatrixType(ScalarType type, int rowCount, int columnCount) - : this() - { - Type = type; - RowCount = rowCount; - ColumnCount = columnCount; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the row count. - /// - /// - /// The row count. - /// - public int RowCount - { - get - { - return (int)((Literal)Parameters[1]).Value; - } - - set - { - Parameters[1] = new Literal(value); - } - } - - /// - /// Gets or sets the column count. - /// - /// - /// The column count. - /// - public int ColumnCount - { - get - { - return (int)((Literal)Parameters[2]).Value; - } - - set - { - Parameters[2] = new Literal(value); - } - } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type - { - get - { - return (TypeBase)Parameters[0]; - } - - set - { - Parameters[0] = value; - } - } - - #endregion - - public override TypeBase ToNonGenericType(SourceSpan? span = null) - { - var typeName = new TypeName(); - var name = string.Format("{0}{1}x{2}", Type.Name, RowCount, ColumnCount); - typeName.Name = new Identifier(name); - if (span.HasValue) - { - typeName.Span = span.Value; - typeName.Name.Span = span.Value; - }; - typeName.TypeInference.TargetType = this; - return typeName; - } - - /// - public bool Equals(MatrixType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as MatrixType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(MatrixType left, MatrixType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(MatrixType left, MatrixType right) - { - return !Equals(left, right); - } - - /// - /// Index information. - /// - [DataContract] - public struct Indexer - { - /// - /// Initializes a new instance of the struct. - /// - /// The row. - /// The column. - public Indexer(int row, int column) - { - Row = row; - Column = column; - } - - /// - /// The row number, zero-based index. - /// - public int Row; - - /// - /// The column number, zero-based index. - /// - public int Column; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/MemberReferenceExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/MemberReferenceExpression.cs deleted file mode 100644 index 96540eebf5..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/MemberReferenceExpression.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A member reference in the form {this}.{Name} - /// - public partial class MemberReferenceExpression : Expression - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public MemberReferenceExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The @this. - /// The member. - public MemberReferenceExpression(Expression @this, Identifier member) - { - Target = @this; - Member = member; - } - - /// - /// Initializes a new instance of the class. - /// - /// The @this. - /// The member. - public MemberReferenceExpression(Expression @this, string member) - { - Target = @this; - Member = new Identifier(member); - } - - - #endregion - - #region Public Properties - - /// - /// Gets or sets the member. - /// - /// - /// The member. - /// - public Identifier Member { get; set; } - - /// - /// Gets or sets the this. - /// - /// - /// The this. - /// - public Expression Target { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Target); - ChildrenList.Add(Member); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}.{1}", Target, Member); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/MethodDeclaration.cs b/sources/shaders/Stride.Core.Shaders/Ast/MethodDeclaration.cs deleted file mode 100644 index 9749d367c1..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/MethodDeclaration.cs +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Declaration of a method. - /// - public partial class MethodDeclaration : Node, IDeclaration, IAttributes, IQualifiers, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public MethodDeclaration() - { - Attributes = new List(); - Parameters = new List(); - Qualifiers = Qualifier.None; - ParameterConstraints = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - /// - public List Attributes { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the parameter constraints. - /// - /// - /// The parameter constraints. - /// - public List ParameterConstraints { get; set; } - - /// - /// Gets or sets the parameters. - /// - /// - /// The parameters. - /// - public List Parameters { get; set; } - - /// - /// Gets or sets the storage class. - /// - /// - /// The storage class. - /// - public Qualifier Qualifiers { get; set; } - - /// - /// Gets or sets the type of the return. - /// - /// - /// The type of the return. - /// - public TypeBase ReturnType { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is builtin. - /// - /// - /// true if this instance is builtin; otherwise, false. - /// - public bool IsBuiltin { get; set; } - - #endregion - - #region Public Methods - - /// - /// Checks the constraint. - /// - /// Type of the parameter. - /// The type to check. - /// - public bool CheckConstraint(GenericParameterType parameterType, TypeBase typeToCheck) - { - foreach (var genericParameterConstraint in ParameterConstraints) - { - if (genericParameterConstraint.Name == parameterType.Name) - { - return genericParameterConstraint.Constraint(typeToCheck); - } - } - return false; - } - - /// - /// Test if a method declaration has the same signature. - /// - /// The method declaration. - /// True if the method passed has the same signature - public bool IsSameSignature(MethodDeclaration methodDeclaration) - { - if (methodDeclaration == null) - return false; - - if (Name != methodDeclaration.Name) - return false; - if (Parameters.Count != methodDeclaration.Parameters.Count) - return false; - for (int i = 0; i < Parameters.Count; i++) - { - var parameter = Parameters[i]; - var parameterAgainst = methodDeclaration.Parameters[i]; - var parameterType = parameter.Type.ResolveType(); - var parameterAgainstType = parameterAgainst.Type.ResolveType(); - if (parameterType != parameterAgainstType) - { - return false; - } - } - return true; - } - - /// - /// Test if a method invocation expression has the same signature. - /// - /// The method invocation expression. - /// True if the method passed has the same signature - public bool IsSameSignature(MethodInvocationExpression methodInvocationExpression) - { - if (methodInvocationExpression == null) - return false; - - Identifier methodName; - var target = methodInvocationExpression.Target as MemberReferenceExpression; - if (target != null) - methodName = target.Member; - else - { - var vre = methodInvocationExpression.Target as VariableReferenceExpression; - if (vre == null) - return false; - methodName = vre.Name; - } - - if (Name != methodName) - return false; - if (Parameters.Count != methodInvocationExpression.Arguments.Count) - return false; - for (int i = 0; i < Parameters.Count; i++) - { - var parameter = Parameters[i]; - var parameterAgainst = methodInvocationExpression.Arguments[i]; - var parameterType = parameter.Type.ResolveType(); - - if (parameterAgainst.TypeInference.TargetType == null) - return false; - - var parameterAgainstType = parameterAgainst.TypeInference.TargetType.ResolveType(); - if (parameterType != parameterAgainstType) - return false; - } - return true; - } - - /// - /// Copies declartion to another instance. - /// - /// The target instance. - public void CopyTo(MethodDeclaration target) - { - target.Attributes = Attributes; - target.Name = Name; - target.Parameters = Parameters; - target.Qualifiers = Qualifiers; - target.ReturnType = ReturnType; - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(ReturnType); - ChildrenList.Add(Name); - foreach (var variableDeclarator in Parameters) - { - ChildrenList.Add(variableDeclarator); - } - if (Qualifiers != Qualifier.None) - { - ChildrenList.Add(Qualifiers); - } - - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format( - "{0}{1} {2}({3}){4}", - Qualifiers == Qualifier.None ? string.Empty : Qualifiers + " ", - ReturnType, - Name, - string.Join(",", Parameters), - GetType() == typeof(MethodDeclaration) ? ";" : " {...}"); - } - - /// - /*public override int GetHashCode() - { - unchecked - { - return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (ReturnType != null ? ReturnType.GetHashCode() : 0); - } - }*/ - - #endregion - - #region Methods - - internal void UpdateParameters() - { - foreach (var parameter in Parameters) - { - parameter.DeclaringMethod = this; - } - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/MethodDefinition.cs b/sources/shaders/Stride.Core.Shaders/Ast/MethodDefinition.cs deleted file mode 100644 index a7bafdfa40..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/MethodDefinition.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A method definition with a body of statements. - /// - public partial class MethodDefinition : MethodDeclaration, IScopeContainer - { - private MethodDeclaration declaration; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public MethodDefinition() - { - Body = new StatementList(); - declaration = this; - } - - /// - /// Initializes a new instance of the class. - /// - /// The returntype. - /// The name. - public MethodDefinition(TypeBase returntype, string name) : this() - { - ReturnType = returntype; - Name = new Identifier(name); - declaration = this; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the declaration. - /// - /// - /// The declaration. - /// - [VisitorIgnore] - public MethodDeclaration Declaration { get { return declaration; } set { declaration = value; } } - - /// - /// Gets or sets the list of statements. - /// - /// - /// The list of statements. - /// - public StatementList Body { get; set; } - - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - base.Childrens(); - ChildrenList.Add(Body); - return ChildrenList; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/MethodInvocationExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/MethodInvocationExpression.cs deleted file mode 100644 index bc40ab034d..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/MethodInvocationExpression.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A method invocation. - /// - public partial class MethodInvocationExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public MethodInvocationExpression() - { - Initialize(null); - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The arguments. - public MethodInvocationExpression(string name, params Expression[] arguments) - { - Initialize(new VariableReferenceExpression(name), arguments); - } - - /// - /// Initializes a new instance of the class. - /// - /// The target. - /// The arguments. - public MethodInvocationExpression(Expression target, params Expression[] arguments) - { - Initialize(target, arguments); - } - - private void Initialize(Expression target, params Expression[] arguments) - { - Target = target; - Arguments = new List(); - if (arguments != null) - Arguments.AddRange(arguments); - } - - /// - /// Gets or sets the target. - /// - /// - /// The target. - /// - public Expression Target { get; set; } - - /// - /// Gets or sets the arguments. - /// - /// - /// The arguments. - /// - public List Arguments { get; set; } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.AddRange(Arguments); - ChildrenList.Add(Target); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}({1})", Target, string.Join(",", Arguments)); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Node.Clone.Extension.cs b/sources/shaders/Stride.Core.Shaders/Ast/Node.Clone.Extension.cs deleted file mode 100644 index 68ead3d6e9..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Node.Clone.Extension.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using Stride.Core.Serialization; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Ast -{ - public class CloneContext - { - private MemoryStream memoryStream; - private BinarySerializationWriter writer; - private BinarySerializationReader reader; - private Dictionary serializeReferences; - private List deserializeReferences; - - public CloneContext(CloneContext parent = null) - { - // Setup - memoryStream = new MemoryStream(4096); - writer = new BinarySerializationWriter(memoryStream); - reader = new BinarySerializationReader(memoryStream); - - writer.Context.SerializerSelector = SerializerSelector.AssetWithReuse; - reader.Context.SerializerSelector = SerializerSelector.AssetWithReuse; - - serializeReferences = writer.Context.Tags.Get(MemberSerializer.ObjectSerializeReferences); - deserializeReferences = reader.Context.Tags.Get(MemberSerializer.ObjectDeserializeReferences); - - if (parent != null) - { - foreach (var item in parent.serializeReferences) - serializeReferences.Add(item.Key, item.Value); - foreach (var item in parent.deserializeReferences) - deserializeReferences.Add(item); - } - } - - public void Add(object key, object value) - { - serializeReferences.Add(key, deserializeReferences.Count); - deserializeReferences.Add(value); - } - - public void Remove(object key) - { - // Swap remove with last one - int index; - if (serializeReferences.TryGetValue(key, out index)) - { - serializeReferences.Remove(key); - - // Swap remove - if (index < deserializeReferences.Count - 1) - { - deserializeReferences[index] = deserializeReferences[deserializeReferences.Count - 1]; - - // Update new object => index mapping - // Note: quite slow because we have to scan full dictionnary - foreach (var item in serializeReferences) - { - if (item.Value == deserializeReferences.Count - 1) - { - serializeReferences[item.Key] = index; - break; - } - } - } - - deserializeReferences.RemoveAt(deserializeReferences.Count - 1); - } - } - - internal void DeepCollect(T obj) - { - // Collect - writer.SerializeExtended(obj, ArchiveMode.Serialize); - - // Reset stream and references - memoryStream.Seek(0, SeekOrigin.Begin); - memoryStream.SetLength(0); - - serializeReferences.Clear(); - } - - internal T DeepClone(T obj) - { - // Serialize - writer.SerializeExtended(obj, ArchiveMode.Serialize); - - // Deserialize - obj = default(T); - memoryStream.Seek(0, SeekOrigin.Begin); - reader.SerializeExtended(ref obj, ArchiveMode.Deserialize); - - // Reset stream and references - memoryStream.Seek(0, SeekOrigin.Begin); - memoryStream.SetLength(0); - - return obj; - } - } - - public static class DeepCloner - { - public static void DeepCollect(T obj, CloneContext context) - { - context.DeepCollect(obj); - } - - public static T DeepClone(this T obj, CloneContext context = null) - { - // Setup contexts - if (context == null) - context = new CloneContext(); - - return context.DeepClone(obj); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Node.Extensions.cs b/sources/shaders/Stride.Core.Shaders/Ast/Node.Extensions.cs deleted file mode 100644 index c72ddd1e52..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Node.Extensions.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Extensions for . - /// - public static class NodeExtensions - { - /// - /// Get descendants for the specified node. - /// - /// The node. - /// An enumeration of descendants - private static IEnumerable DescendantsImpl(this Node node) - { - if (node != null) - { - yield return node; - - foreach (var children in node.Childrens()) - { - if (children != null) - foreach (var descendant in children.Descendants()) - { - yield return descendant; - } - } - } - } - - /// - /// Get descendants for the specified node. - /// - /// The node. - /// An enumeration of descendants - public static IEnumerable Descendants(this Node node) - { - if (node != null) - { - foreach (var children in node.Childrens()) - { - if (children != null) - foreach (var descendant in children.DescendantsImpl()) - { - yield return descendant; - } - } - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Node.cs b/sources/shaders/Stride.Core.Shaders/Ast/Node.cs deleted file mode 100644 index 4254117632..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Node.cs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Threading; -using Stride.Core; -using Stride.Core.Shaders.Visitor; -using SourceSpan = Stride.Core.Shaders.Ast.SourceSpan; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Abstract node. - /// - [DataContract(Inherited = true)] - public abstract class Node - { - /// - /// list of childrens for ast navigation. - /// - private List childrenList = null; - private Dictionary tags; - - /// - /// Initializes a new instance of the class. - /// - protected Node() - { - } - - /// - /// Gets or sets the source span. - /// - /// - /// The source span. - /// - public SourceSpan Span { get; set; } - - - public override bool Equals(object against) - { - return base.Equals(against); - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public static bool operator ==(Node left, Node right) - { - return Equals(left, right); - } - - public static bool operator !=(Node left, Node right) - { - return !Equals(left, right); - } - - /// - /// Gets the childrens. - /// - [DataMemberIgnore] - [VisitorIgnore] - protected List ChildrenList - { - get - { - if (childrenList == null) - childrenList = new List(); - return childrenList; - } - } - - /// - /// Gets or sets tags collection. - /// - public Dictionary Tags - { - get { return tags; } - set { tags = value; } - } - - /// - /// Gets a tag value associated to this node.. - /// - /// The tag key. - /// The tag value - public object GetTag(string tagKey) - { - if (tags == null) return null; - object result; - tags.TryGetValue(tagKey, out result); - return result; - } - - /// - /// Gets a tag value associated to this node.. - /// - /// The tag key. - /// The tag value - public bool RemoveTag(string tagKey) - { - if (tags == null) return true; - return tags.Remove(tagKey); - } - - /// - /// Determines whether the specified instance contains this tag. - /// - /// The tag key. - /// - /// true if the specified instance contains this tag; otherwise, false. - /// - public bool ContainsTag(string tagKey) - { - if (tags == null) return false; - return tags.ContainsKey(tagKey); - } - - /// - /// Sets a tag value associated to this node. - /// - /// The tag key. - /// The tag value. - public void SetTag(string tagKey, object tagValue) - { - if (tags == null) tags = new Dictionary(); - tags.Remove(tagKey); - tags.Add(tagKey, tagValue); - } - - /// - /// Gets the child nodes. - /// - /// An enumeration of child nodes - public virtual IEnumerable Childrens() - { - return ChildrenList; - } - - /// - public override string ToString() - { - return GetType().Name; - } - - public abstract void Accept(ShaderVisitor visitor); - - public abstract TResult Accept(ShaderVisitor visitor); - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/NodeProcessorContext.cs b/sources/shaders/Stride.Core.Shaders/Ast/NodeProcessorContext.cs deleted file mode 100644 index f13e72104f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/NodeProcessorContext.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections; -using System.Reflection; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Processor for a single node. - /// - /// The node. - /// The node processor context. - /// The node transformed - public delegate Node NodeProcessor(Node node, ref NodeProcessorContext nodeProcessorContext); - - /// - /// Processor for a list of node. - /// - /// The list. - /// The node processor context. - public delegate void NodeListProcessor(IList list, ref NodeProcessorContext nodeProcessorContext); - - /// - /// Node explorer. - /// - public struct NodeProcessorContext - { - /// - /// Gets or sets the node processor. - /// - public NodeProcessor NodeProcessor; - - /// - /// Gets or sets the list processor. - /// - public NodeListProcessor ListProcessor; - - /// - /// Initializes a new instance of the class. - /// - /// The node processor. - /// The list processor. - public NodeProcessorContext(NodeProcessor nodeProcessor, NodeListProcessor listProcessor) - { - NodeProcessor = nodeProcessor; - ListProcessor = listProcessor; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ObjectType.cs b/sources/shaders/Stride.Core.Shaders/Ast/ObjectType.cs deleted file mode 100644 index 7fa9947f22..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ObjectType.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An Object Type. - /// - public partial class ObjectType : TypeBase - { - /// - /// Initializes a new instance of the class. - /// - public ObjectType() - { - AlternativeNames = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The atl names. - public ObjectType(string name, params string[] atlNames) - : base(name) - { - AlternativeNames = new List(); - if (atlNames != null) - AlternativeNames.AddRange(atlNames); - } - - /// - /// Gets or sets the alternatives. - /// - /// - /// The alternatives. - /// - public List AlternativeNames { get; set; } - - /// - public bool Equals(ObjectType other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return Equals(other.Name, Name) || AlternativeNames.Contains(other.Name); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as ObjectType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(ObjectType left, ObjectType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(ObjectType left, ObjectType right) - { - return !Equals(left, right); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Parameter.cs b/sources/shaders/Stride.Core.Shaders/Ast/Parameter.cs deleted file mode 100644 index 183e0dc5ca..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Parameter.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A single parameter declaration. - /// - public partial class Parameter : Variable - { - private MethodDeclaration declaringMethod; - - /// - /// Initializes a new instance of the class. - /// - public Parameter() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The name. - /// The initial value. - public Parameter(TypeBase type, string name = null, Expression initialValue = null) - : base(type, name, initialValue) - { - } - - #region Public Properties - - /// - /// Gets or sets the declaring method. - /// - /// - /// The declaring method. - /// - [VisitorIgnore] - public MethodDeclaration DeclaringMethod - { - get - { - return declaringMethod; - } - set - { - declaringMethod = value; - } - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ParameterQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/ParameterQualifier.cs deleted file mode 100644 index 4e61242bab..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ParameterQualifier.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Storage qualifier. - /// - public static class ParameterQualifier - { - #region Constants and Fields - - /// - /// In modifier, only for method parameters. - /// - public static readonly Qualifier In = new Qualifier("in"); - - /// - /// InOut Modifier, only for method parameters. - /// - public static readonly Qualifier InOut = new Qualifier("inout"); - - /// - /// Out modifier, only for method parameters. - /// - public static readonly Qualifier Out = new Qualifier("out"); - - /// - /// Flat modifier, only for inputs or outputs. - /// - public static readonly Qualifier Flat = new Qualifier("flat"); - - #endregion - - #region Public Methods - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A parameter qualifier - /// - public static Qualifier Parse(string enumName) - { - if (enumName == (string)In.Key) - return In; - if (enumName == (string)InOut.Key) - return InOut; - if (enumName == (string)Out.Key) - return Out; - if (enumName == (string)Flat.Key) - return Flat; - - throw new ArgumentException(string.Format("Unable to convert [{0}] to qualifier", enumName), "key"); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ParenthesizedExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/ParenthesizedExpression.cs deleted file mode 100644 index 2f38f3e36a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ParenthesizedExpression.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// An expression surrounded by parenthesis. - /// - public partial class ParenthesizedExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public ParenthesizedExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The content. - public ParenthesizedExpression(params Expression[] content) - { - if (content != null) - { - if (content.Length == 1) - Content = content[0]; - else - Content = new ExpressionList(content); - } - } - - #region Public Properties - - /// - /// Gets or sets the expression. - /// - /// - /// The expression. - /// - public Expression Content { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Content); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("({0})", string.Join(",", Content)); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Qualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Qualifier.cs deleted file mode 100644 index 00fe9782af..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Qualifier.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core.Shaders.Ast; - -/// -/// A syntax node that represent one or more storage qualifiers. -/// -/// -/// Storage qualifiers are used to qualify types or variables in Shader code, -/// like const, in, out, uniform, etc. -/// -public partial class Qualifier : CompositeEnum -{ - /// - /// An empty qualifier. - /// - public static readonly Qualifier None = new(key: string.Empty); - - - /// - /// Gets or sets a value indicating whether the syntax node is a post qualifier, - /// i.e. appears after the type it qualifies (e.g. like semantics or register qualifiers). - /// - public bool IsPost { get; set; } - - - /// - /// Initializes a new instance of the class. - /// - public Qualifier() : base(isFlag: true) { } - - /// - /// Initializes a new instance of the class. - /// - /// The name of the qualifier. - public Qualifier(object key) : base(key, isFlag: true) { } - - - /// - /// Returns a string representation of the qualifier, filtering by whether they are post or pre qualifiers. - /// - /// - /// A value indicating whether to return post qualifiers (if ), - /// or pre qualifiers (if ). - /// - /// A string representation of the qualifier. - public string ToString(bool isPost) - { - var str = ToString(qualifier => qualifier.IsPost == isPost); - - if (!string.IsNullOrEmpty(str)) - { - return isPost ? $" {str}" : $"{str} "; - } - return string.Empty; - } - - /// - public override string ToString() - { - return ToString(qualifier => true); - } - - #region Operators - - public static Qualifier operator &(Qualifier left, Qualifier right) - { - return OperatorAnd(left, right); - } - - public static Qualifier operator |(Qualifier left, Qualifier right) - { - return OperatorOr(left, right); - } - - public static Qualifier operator ^(Qualifier left, Qualifier right) - { - return OperatorXor(left, right); - } - - #endregion -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ReturnStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/ReturnStatement.cs deleted file mode 100644 index 7331d16575..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ReturnStatement.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A return statement. - /// - public partial class ReturnStatement : Statement - { - /// - /// Initializes a new instance of the class. - /// - public ReturnStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public ReturnStatement(Expression value) - { - Value = value; - } - - #region Public Properties - - /// - /// Gets or sets the value. - /// - /// - /// The value. - /// - /// - /// If this value is null, return without any expression. - /// - public Expression Value { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Value); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("return{0};", Value != null ? " " + Value : string.Empty); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/ScalarType.cs b/sources/shaders/Stride.Core.Shaders/Ast/ScalarType.cs deleted file mode 100644 index dcc0d9aa2c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/ScalarType.cs +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Scalar type - /// - public partial class ScalarType : TypeBase - { - #region Constants and Fields - - /// - /// Scalar bool. - /// - public static readonly ScalarType Bool = new ScalarType("bool", typeof(bool)); - - /// - /// Scalar double. - /// - public static readonly ScalarType Double = new ScalarType("double", typeof(double)); - - /// - /// Sclar float. - /// - public static readonly ScalarType Float = new ScalarType("float", typeof(float)); - - /// - /// Scalar half. - /// - public static readonly ScalarType Half = new ScalarType("half"); - - /// - /// Scalar int. - /// - public static readonly ScalarType Int = new ScalarType("int", typeof(int)); - - /// - /// Scalar unsigned int. - /// - public static readonly ScalarType UInt = new ScalarType("uint", typeof(uint)); - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ScalarType() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - public ScalarType(string name) - : base(name) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - /// - /// The type. - /// - public ScalarType(string name, Type type) - : base(name) - { - Type = type; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public Type Type { get; set; } - - /// - /// Gets a boolean indicating if this scalar is an unsigned type. - /// - public bool IsUnsigned - { - get - { - return Type == typeof(uint); - } - } - - #endregion - - #region Public Methods - - /// - /// Equalses the specified other. - /// - /// - /// The other. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(ScalarType other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return base.Equals(other) && Equals(other.Type, Type); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - return Equals(obj as ScalarType); - } - - /// - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ (Type != null ? Type.GetHashCode() : 0); - } - } - - #endregion - - #region Operators - - /// - /// Determines whether the specified type is a float/half/double. - /// - /// The type. - /// - /// true if the specified type is float/half/double; otherwise, false. - /// - public static bool IsFloat(TypeBase type) - { - return type == Float || type == Double || type == Half; - } - - /// - /// Determines whether the specified type is an integer. - /// - /// The type. - /// - /// true if the specified type is an integer; otherwise, false. - /// - public static bool IsInteger(TypeBase type) - { - return type == Int || type == UInt; - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(ScalarType left, ScalarType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(ScalarType left, ScalarType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Shader.cs b/sources/shaders/Stride.Core.Shaders/Ast/Shader.cs deleted file mode 100644 index 1aab9c3926..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Shader.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Toplevel container of a shader parsing result. - /// - public partial class Shader : Node - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Shader() - { - Declarations = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the declarations. - /// - /// - /// The declarations. - /// - public List Declarations { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - return Declarations; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/SourceLocation.cs b/sources/shaders/Stride.Core.Shaders/Ast/SourceLocation.cs deleted file mode 100644 index dfb884ec41..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/SourceLocation.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.IO; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A Source location. - /// - [DataContract] - public struct SourceLocation - { - #region Constants and Fields - - /// - /// Filename source. - /// - public string FileSource; - - /// - /// Absolute position in the file. - /// - public int Position; - - /// - /// Line in the file (1-based). - /// - public int Line; - - /// - /// Column in the file (1-based). - /// - public int Column; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the struct. - /// - /// The file source. - /// The position. - /// The line. - /// The column. - public SourceLocation(string fileSource, int position, int line, int column) - { - FileSource = fileSource; - Position = position; - Line = line; - Column = column; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The position. - /// The line. - /// The column. - public SourceLocation(int position, int line, int column) - : this() - { - Position = position; - Line = line; - Column = column; - } - - /// - public override string ToString() - { - return this.ToString(false); - } - - public string ToString(bool useShortFileName) - { - return string.Format("{0}({1},{2})", FileSource ?? string.Empty, Line, Column); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/SourceSpan.cs b/sources/shaders/Stride.Core.Shaders/Ast/SourceSpan.cs deleted file mode 100644 index 4d23383a66..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/SourceSpan.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A SourceSpan. - /// - [DataContract] - public struct SourceSpan - { - #region Constants and Fields - - /// - /// Location of this span. - /// - public SourceLocation Location; - - /// - /// Length of this span. - /// - public int Length; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The location. - /// - /// - /// The length. - /// - public SourceSpan(SourceLocation location, int length) - { - Location = location; - Length = length; - } - - /// - public override string ToString() - { - return string.Format("{0}", Location); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Statement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Statement.cs deleted file mode 100644 index f3942bb7ce..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Statement.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Base root class for all statements. - /// - public abstract partial class Statement : Node, IAttributes - { - /// - /// Initializes a new instance of the class. - /// - protected Statement() - { - Attributes = new List(); - } - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - public List Attributes { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/StatementList.cs b/sources/shaders/Stride.Core.Shaders/Ast/StatementList.cs deleted file mode 100644 index ef412aa683..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/StatementList.cs +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A list of statement. - /// - /// - /// This class can be use to expand codes as a replacement in visitors. - /// - public partial class StatementList : Statement, IList - { - /// - /// Initializes a new instance of the class. - /// - public StatementList() - { - Statements = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The statements. - public StatementList(params Statement [] statements) - { - Statements = new List(); - if (statements != null) - Statements.AddRange(statements); - } - - /// - public int Count - { - get - { - return Statements.Count; - } - } - - /// - public bool IsReadOnly - { - get - { - return false; - } - } - - /// - /// Gets or sets the statements. - /// - /// - /// The statements. - /// - public List Statements { get; set; } - - /// - /// Adds a collection to this instance. - /// - /// The collection to add to this instance. - public void AddRange(IEnumerable collection) - { - Statements.AddRange(collection); - } - - /// - /// Gets a subset of this instance - /// - /// The index. - /// The count. - /// A subset of this instance - public List GetRange(int index, int count) - { - return Statements.GetRange(index, count); - } - - /// - /// Inserts a collection at the specified index. - /// - /// The index. - /// The collection. - public void InsertRange(int index, IEnumerable collection) - { - Statements.InsertRange(index, collection); - } - - /// - /// Removes a range of elements. - /// - /// The index. - /// The count. - public void RemoveRange(int index, int count) - { - Statements.RemoveRange(index, count); - } - - /// - /// Removes all elements with a predicate function. - /// - /// The match. - /// Number of elements removed - public int RemoveAll(Predicate match) - { - return Statements.RemoveAll(match); - } - - /// - public Statement this[int index] - { - get - { - return Statements[index]; - } - - set - { - Statements[index] = value; - } - } - - /// - public void Add(Statement item) - { - Statements.Add(item); - } - - public override IEnumerable Childrens() - { - return this; - } - - /// - public void Clear() - { - Statements.Clear(); - } - - /// - public bool Contains(Statement item) - { - return Statements.Contains(item); - } - - /// - public void CopyTo(Statement[] array, int arrayIndex) - { - Statements.CopyTo(array, arrayIndex); - } - - /// - public IEnumerator GetEnumerator() - { - return Statements.GetEnumerator(); - } - - /// - public int IndexOf(Statement item) - { - return Statements.IndexOf(item); - } - - /// - public void Insert(int index, Statement item) - { - Statements.Insert(index, item); - } - - /// - public bool Remove(Statement item) - { - return Statements.Remove(item); - } - - /// - public void RemoveAt(int index) - { - Statements.RemoveAt(index); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/StorageQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/StorageQualifier.cs deleted file mode 100644 index c59b120dd2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/StorageQualifier.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; - -namespace Stride.Core.Shaders.Ast; - -/// -/// Defines common Shader storage qualifiers. -/// -public partial class StorageQualifier -{ - #region Storage Qualifier keys - - private const string ConstKey = "const"; - private const string GroupSharedKey = "groupshared"; - private const string SharedKey = "shared"; - - #endregion - - /// - /// The "const" qualifier. - /// Indicates that the variable is a compile-time constant. Its value cannot be changed after initialization. - /// - public static readonly Qualifier Const = new(ConstKey); - - /// - /// The "groupshared" modifier. - /// Declares a variable that is shared among all threads in a thread group. - /// - public static readonly Qualifier GroupShared = new(GroupSharedKey); - - /// - /// The "shared" modifier. - /// Declares a variable that is shared between multiple shader stages or invocations. - /// - public static readonly Qualifier Shared = new(SharedKey); - - - /// - /// Parses the specified qualifier name into a storage qualifier. - /// - /// The name of the qualifier to parse. - /// A storage - /// The qualifier name is not recognized. - public static Qualifier Parse(string qualifierName) - { - return qualifierName switch - { - ConstKey => Const, - GroupSharedKey => GroupShared, - SharedKey => Shared, - - _ => throw new ArgumentException($"Unable to parse [{qualifierName}] to a qualifier", nameof(qualifierName)) - }; - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ClassIdentifierGeneric.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ClassIdentifierGeneric.cs deleted file mode 100644 index 047894e659..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ClassIdentifierGeneric.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Text; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ClassIdentifierGeneric : Identifier - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ClassIdentifierGeneric() - { - Generics = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the path. - /// - /// - /// The path. - /// - public List Generics { get; set; } - - #endregion - - #region Public Methods - - /// - /// Gets the separator. - /// - public string Separator - { - get - { - return ","; - } - } - - public bool Equals(ClassIdentifierGeneric other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - return base.Equals(other) && (Generics.Count != other.Generics.Count); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return Equals(obj as ClassIdentifierGeneric); - } - - /// - public override int GetHashCode() - { - unchecked - { - return (base.GetHashCode() * 397) ^ Generics.GetHashCode(); - } - } - - /// - public override IEnumerable Childrens() - { - return Generics; - } - - /// - public override string ToString() - { - var ranks = new StringBuilder(); - if (Indices != null) - { - foreach (var expression in Indices) - { - ranks.Append("[").Append(expression).Append("]"); - } - } - - return string.Format(IsSpecialReference ? "{0}<{1}{2}>" : "{0}{1}{2}", Text, string.Join(Separator, Generics), ranks); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/EffectBlock.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/EffectBlock.cs deleted file mode 100644 index e1e3219994..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/EffectBlock.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A Shader block. - /// - public partial class EffectBlock : TypeBase, IScopeContainer - { - #region Public Properties - - /// - /// Gets or sets a value indicating whether this instance is partial. - /// - /// true if this instance is partial; otherwise, false. - public bool IsPartial { get; set; } - - /// - /// Gets or sets the body. - /// - /// The body. - public BlockStatement Body { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.Add(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0}shader {1} {{...}}", IsPartial ? "partial " : string.Empty, Name); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/EnumType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/EnumType.cs deleted file mode 100644 index 00a91e1596..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/EnumType.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// An enum. - /// - public partial class EnumType : TypeBase, IDeclaration, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public EnumType() - { - Values = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the fields. - /// - /// - /// The fields. - /// - public List Values { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(Values); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("enum {0} {{...}}", Name); - } - - /// - public bool Equals(EnumType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as EnumType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public static bool operator ==(EnumType left, EnumType right) - { - return Equals(left, right); - } - - public static bool operator !=(EnumType left, EnumType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ForEachStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ForEachStatement.cs deleted file mode 100644 index 49e712e061..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ForEachStatement.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// For statement. - /// - public partial class ForEachStatement : Statement, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ForEachStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The variable. - /// The collection. - public ForEachStatement(Variable variable, Expression collection) - { - Variable = variable; - Collection = collection; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Collection { get; set; } - - /// - /// Gets or sets the initializer. - /// - /// - /// The initializer. - /// - public Variable Variable { get; set; } - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Statement Body { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Collection); - ChildrenList.Add(Variable); - ChildrenList.Add(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("foreach({0} in {1}) {{...}}", Variable, Collection); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/IGenericStringArgument.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/IGenericStringArgument.cs deleted file mode 100644 index 8eb2455225..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/IGenericStringArgument.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// Interface used to tag generic parameters used as string replacement. - /// - public interface IGenericStringArgument - { - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ImportBlockStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ImportBlockStatement.cs deleted file mode 100644 index 917378b3e0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ImportBlockStatement.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ImportBlockStatement : BlockStatement - { - public string Name { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/LinkType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/LinkType.cs deleted file mode 100644 index 6793b2ea34..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/LinkType.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class LinkType : TypeBase, IDeclaration, IScopeContainer, IGenericStringArgument - { - #region Constructors and Destructors - /// - /// Initializes a new instance of the class. - /// - public LinkType() - : base("LinkType") - { - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/LiteralIdentifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/LiteralIdentifier.cs deleted file mode 100644 index e08481f263..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/LiteralIdentifier.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class LiteralIdentifier : Identifier - { - public LiteralIdentifier() - { - } - - public LiteralIdentifier(Literal valueName) - : base(valueName.ToString()) - { - Value = valueName; - } - - - public Literal Value { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MemberName.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/MemberName.cs deleted file mode 100644 index ea2e6d5904..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MemberName.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class MemberName : TypeBase, IDeclaration, IScopeContainer, IGenericStringArgument - { - #region Constructors and Destructors - /// - /// Initializes a new instance of the class. - /// - public MemberName() - : base("MemberName") - { - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatement.cs deleted file mode 100644 index 6be325e33b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatement.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A mixin statement. - /// - public partial class MixinStatement : Statement, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public MixinStatement() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The mixin. - public MixinStatement(MixinStatementType type, Expression mixin) - { - Type = type; - Value = mixin; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the type. - /// - /// The type. - public MixinStatementType Type { get; set; } - - /// - /// Gets or sets the target of this mixin. - /// - /// The target. - public Expression Value { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Value); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("mixin {0}{1};", Type > 0 ? Type.ToString().ToLowerInvariant() + " " : string.Empty, Value); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatementType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatementType.cs deleted file mode 100644 index cb049727e4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/MixinStatementType.cs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// Type of a mixin. - /// - public enum MixinStatementType - { - /// - /// The default mixin (standard mixin). - /// - Default, - - /// - /// The compose mixin used to specifiy a composition. - /// - Compose, - - /// - /// The child mixin used to specifiy a children shader. - /// - Child, - - /// - /// The clone mixin to clone the current mixins where the clone is emitted. - /// - Clone, - - /// - /// The remove mixin to remove a mixin from current mixins. - /// - Remove, - - /// - /// The macro mixin to declare a variable to be exposed in the mixin - /// - Macro - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/NamespaceBlock.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/NamespaceBlock.cs deleted file mode 100644 index 9895f96cdf..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/NamespaceBlock.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class NamespaceBlock : TypeBase, IScopeContainer - { - #region Public Properties - - /// - /// Initializes a new instance of the class. - /// - public NamespaceBlock() : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public NamespaceBlock(string name) - : base(name) - { - Body = new List(); - } - - /// - /// Gets or sets the body. - /// - /// The body. - public List Body { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("namespace {0} {{...}}", Name); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ParametersBlock.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ParametersBlock.cs deleted file mode 100644 index f59ce40470..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ParametersBlock.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A params block. - /// - public partial class ParametersBlock : Node, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ParametersBlock() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The statements. - public ParametersBlock(Identifier name, BlockStatement statements) - { - Name = name; - Body = statements; - } - - #endregion - - #region Public Properties - - public Identifier Name { get; set; } - - public BlockStatement Body { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.Add(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("params {0} {{...}}", Name); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/SemanticType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/SemanticType.cs deleted file mode 100644 index 5be61d261e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/SemanticType.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class SemanticType : TypeBase, IDeclaration, IScopeContainer, IGenericStringArgument - { - #region Constructors and Destructors - /// - /// Initializes a new instance of the class. - /// - public SemanticType() : base("Semantic") - { - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderClassType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderClassType.cs deleted file mode 100644 index 721dd8cfc7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderClassType.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// Shader Class. - /// - public partial class ShaderClassType : ClassType - { - // temp - public List ShaderGenerics { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public ShaderClassType() - { - ShaderGenerics = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public ShaderClassType(string name) : base(name) - { - ShaderGenerics = new List(); - } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.AddRange(BaseClasses); - ChildrenList.AddRange(GenericParameters); - ChildrenList.AddRange(ShaderGenerics); - ChildrenList.AddRange(Members); - return ChildrenList; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderRootClassType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderRootClassType.cs deleted file mode 100644 index f5ed7e4cee..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderRootClassType.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// Shader Class that supports adding mixin class to its base classes. - /// - public partial class ShaderRootClassType : ShaderClassType - { - /// - /// Initializes a new instance of the class. - /// - public ShaderRootClassType() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public ShaderRootClassType(string name) - : base(name) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderTypeName.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderTypeName.cs deleted file mode 100644 index 0a6a63b258..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/ShaderTypeName.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A typeless reference. - /// - public partial class ShaderTypeName : TypeName - { - /// - /// Initializes a new instance of the class. - /// - public ShaderTypeName() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type base. - public ShaderTypeName(TypeBase typeBase) - : base(typeBase.Name) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public ShaderTypeName(Identifier name) : base(name) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StreamsType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/StreamsType.cs deleted file mode 100644 index 2b137b65e4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StreamsType.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.Collections.Generic; -using System.Globalization; -using System.Linq; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A State type. - /// - public static class StreamsType - { - #region Constants and Fields - - /// - /// The constants streams. - /// - public static readonly ObjectType Constants = new ObjectType("Constants"); - - /// - /// The Input streams. - /// - public static readonly ObjectType Input = new ObjectType("Input"); - - /// - /// The Input2 type streams. - /// - public static readonly ObjectType Input2 = new ObjectType("Input2"); - - /// - /// The output type streams. - /// - public static readonly ObjectType Output = new ObjectType("Output"); - - /// - /// The streams type streams. - /// - public static readonly ObjectType Streams = new ObjectType("Streams"); - - /// - /// A fake variable of custom type stream - /// - public static readonly Variable ThisStreams = new Variable(Streams, "streams"); - - - /// - /// Gets the streams. - /// - /// IEnumerable<ObjectType>. - public static IEnumerable GetStreams() - { - return AllTypes; - } - - private static readonly ObjectType[] AllTypes = new[] { Constants, Input, Input2, Output, Streams}; - - #endregion - - public static bool IsStreamsMutable(this TypeBase type) - { - return type != null && IsStreamsType(type) && type.Name != Constants; - } - - public static bool IsStreamsType(this TypeBase type) - { - return type != null && Parse(type.Name) != null; - } - - /// - /// Parses the specified name. - /// - /// The name. - /// - public static ObjectType Parse(string name) - { - foreach (var type in AllTypes) - { - if (CultureInfo.InvariantCulture.CompareInfo.Compare(name, type.Name.Text, CompareOptions.None) == 0) - return type; - } - return null; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideAttributes.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideAttributes.cs deleted file mode 100644 index cacd704fbf..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideAttributes.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public static class StrideAttributes - { - public static HashSet AvailableAttributes = new HashSet { "Link", "RenameLink", "EntryPoint", "StreamOutput", "Map", "Type", "Color" }; - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideConstantBufferType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideConstantBufferType.cs deleted file mode 100644 index eebc058a3e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideConstantBufferType.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class StrideConstantBufferType : ConstantBufferType - { - /// - /// Resource group keyword (rgroup). - /// - public static readonly StrideConstantBufferType ResourceGroup = new StrideConstantBufferType("rgroup"); - - /// - /// Initializes a new instance of the class. - /// - public StrideConstantBufferType() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The key. - /// - public StrideConstantBufferType(string key) - : base(key) - { - } - - /// - /// Parses the specified enum name. - /// - /// - /// Name of the enum. - /// - /// - /// A qualifier - /// - public static new ConstantBufferType Parse(string enumName) - { - if (enumName == (string)ResourceGroup.Key) - return ResourceGroup; - - return ConstantBufferType.Parse(enumName); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideStorageQualifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideStorageQualifier.cs deleted file mode 100644 index dec4653cf2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideStorageQualifier.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core.Shaders.Ast.Stride; - -/// -/// Defines Stride-specific storage qualifiers. -/// -public static class StrideStorageQualifier -{ - #region Storage Qualifier keys - - private const string StreamKey = "stream"; - private const string PatchStreamKey = "patchstream"; - private const string StageKey = "stage"; - private const string CloneKey = "clone"; - private const string OverrideKey = "override"; - private const string AbstractKey = "abstract"; - private const string ComposeKey = "compose"; - private const string InternalKey = "internal"; - - #endregion - - /// - /// The "stream" modifier. - /// Marks a variable as part of the vertex stream. - /// Typically used for vertex attributes passed from the CPU to the vertex Shader. - /// - public static readonly Qualifier Stream = new(StreamKey); - - /// - /// The "patchstream" modifier. - /// Used in tessellation Shaders. Indicates per-patch data passed between tessellation control - /// and evaluation stages. - /// - public static readonly Qualifier PatchStream = new(PatchStreamKey); - - /// - /// The "stage" modifier. - /// Marks a variable or function as belonging to a specific Shader stage (e.g., vertex, pixel, compute), - /// so it can be accessed from anywhere in the same stage. - /// - public static readonly Qualifier Stage = new(StageKey); - - /// - /// The "clone" modifier. - /// Creates a copy of a member or Shader fragment. - /// Useful when reusing logic with slight modifications without affecting the original. - /// - public static readonly Qualifier Clone = new(CloneKey); - - /// - /// The "override" modifier. - /// Overrides a member from a base Shader class. Used when customizing behavior in derived Shader classes. - /// - public static readonly Qualifier Override = new(OverrideKey); - - /// - /// The "abstract" modifier. - /// Declares a member that must be implemented by derived classes. - /// - public static readonly Qualifier Abstract = new(AbstractKey); - - /// - /// The "compose" modifier. - /// Combines multiple Shader fragments or mixins. Enables modular shader construction by merging logic - /// from different sources. - /// - public static readonly Qualifier Compose = new(ComposeKey); - - /// - /// The "internal" modifier. - /// Restricts visibility to the current Shader file or module. Prevents exposure to external Shader compositions. - /// - public static readonly Qualifier Internal = new(InternalKey); - - - /// - /// Parses the specified qualifier name into a storage qualifier. - /// - /// The name of the qualifier to parse. - /// A storage . - /// The qualifier name is not recognized. - public static Qualifier Parse(string qualifierName) - { - return qualifierName switch - { - StreamKey => Stream, - PatchStreamKey => PatchStream, - StageKey => Stage, - CloneKey => Clone, - OverrideKey => Override, - AbstractKey => Abstract, - ComposeKey => Compose, - InternalKey => Internal, - - // Fallback to shared parameter qualifiers - _ => Hlsl.StorageQualifier.Parse(qualifierName) - }; - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideTags.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideTags.cs deleted file mode 100644 index fadc769319..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/StrideTags.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Ast.Stride -{ - public static class StrideTags - { - public const string ConstantBuffer = "ConstantBuffer"; - - public const string ConstantBufferIndex = "ConstantBufferIndex"; - - public const string LogicalGroup = "LogicalGroup"; - - public const string ClassRef = "ClassReference"; - - public const string StaticRef = "StaticReference"; - - public const string ExternRef = "ExternReference"; - - public const string StageInitRef = "StageInitReference"; - - public const string CurrentShader = "CurrentShader"; - - public const string MixinDeclaration = "MixinDeclaration"; - - public const string VirtualTableReference = "VirtualTableReference"; - - public const string BaseDeclarationMixin = "BaseDeclarationMixin"; - - public const string ShaderScope = "ShaderScope"; - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/TypelIdentifier.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/TypelIdentifier.cs deleted file mode 100644 index 0a9e9aff4d..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/TypelIdentifier.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class TypeIdentifier : Identifier - { - public TypeIdentifier() - { - } - - public TypeIdentifier(TypeBase type) - : base(type.ToString()) - { - Type = type; - } - - public TypeBase Type { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingParametersStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingParametersStatement.cs deleted file mode 100644 index 3b22d2a0c9..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingParametersStatement.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A using params statement. - /// - public partial class UsingParametersStatement : Statement - { - /// - /// Gets or sets the name. - /// - /// The name. - public Expression Name { get; set; } - - /// - /// Gets or sets the body. - /// - /// The body. - public BlockStatement Body { get; set; } - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.Add(Body); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("using params {0}{1}", Name, Body != null ? " {...}" : string.Empty); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingStatement.cs deleted file mode 100644 index 1b770a89bc..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/UsingStatement.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A using statement. - /// - public partial class UsingStatement : Statement - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public UsingStatement() - { - } - - public Identifier Name; - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("using {0}", Name); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Stride/VarType.cs b/sources/shaders/Stride.Core.Shaders/Ast/Stride/VarType.cs deleted file mode 100644 index 51696b7b32..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Stride/VarType.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Ast.Stride -{ - /// - /// A structure. - /// - public partial class VarType : TypeBase, IDeclaration, IScopeContainer - { - #region Constructors and Destructors - /// - /// Initializes a new instance of the class. - /// - public VarType() : base("var") - { - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/StructType.cs b/sources/shaders/Stride.Core.Shaders/Ast/StructType.cs deleted file mode 100644 index b2a9ec231e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/StructType.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A structure. - /// - public partial class StructType : TypeBase, IDeclaration, IScopeContainer - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public StructType() - { - Fields = new List(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the fields. - /// - /// - /// The fields. - /// - public List Fields { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - ChildrenList.AddRange(Fields); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("struct {0} {{...}}", Name); - } - - /// - public bool Equals(StructType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as StructType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - public static bool operator ==(StructType left, StructType right) - { - return Equals(left, right); - } - - public static bool operator !=(StructType left, StructType right) - { - return !Equals(left, right); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/SwitchCaseGroup.cs b/sources/shaders/Stride.Core.Shaders/Ast/SwitchCaseGroup.cs deleted file mode 100644 index 2ece9aff79..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/SwitchCaseGroup.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - - /// - /// A group of cases and default attached to their statements. - /// - public partial class SwitchCaseGroup : Node - { - /// - /// Initializes a new instance of the class. - /// - public SwitchCaseGroup() - { - Cases = new List(); - Statements = new StatementList(); - } - - #region Public Properties - - /// - /// Gets or sets the cases. - /// - /// - /// The cases. - /// - public List Cases { get; set; } - - /// - /// Gets or sets the statements. - /// - /// - /// The statements. - /// - public StatementList Statements { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.AddRange(Cases); - ChildrenList.Add(Statements); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("{0} ...", string.Join("\n", Cases)); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/SwitchStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/SwitchStatement.cs deleted file mode 100644 index f39ac60480..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/SwitchStatement.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Switch statement. - /// - public partial class SwitchStatement : Statement - { - /// - /// Initializes a new instance of the class. - /// - public SwitchStatement() - { - Groups = new List(); - } - - #region Public Properties - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Condition { get; set; } - - /// - /// Gets or sets the cases. - /// - /// - /// The cases. - /// - public List Groups { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Condition); - ChildrenList.AddRange(Groups); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format("switch ({0}) {{...}}", Condition); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/TypeBase.cs b/sources/shaders/Stride.Core.Shaders/Ast/TypeBase.cs deleted file mode 100644 index 9f07921935..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/TypeBase.cs +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Reflection; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Base type for all types. - /// - public abstract partial class TypeBase : Node, IAttributes, ITypeInferencer, IQualifiers - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - protected TypeBase() : this((Identifier)null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - protected TypeBase(string name) - : this(name != null ? new Identifier(name) : null) - { - Name = name != null ? new Identifier(name) : null; - Attributes = new List(); - Qualifiers = Qualifier.None; - TypeInference = new TypeInference(); - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// - protected TypeBase(Identifier name) - { - Name = name; - Attributes = new List(); - Qualifiers = Qualifier.None; - TypeInference = new TypeInference(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the attributes. - /// - /// - /// The attributes. - /// - public List Attributes { get; set; } - - /// - /// Gets or sets the resolved reference. - /// - /// - /// The resolved reference. - /// - public TypeInference TypeInference { get; set; } - - /// - /// Gets or sets the type name. - /// - /// - /// The type name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the qualifiers. - /// - /// - /// The qualifiers. - /// - public Qualifier Qualifiers { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is built in. - /// - /// - /// true if this instance is built in; otherwise, false. - /// - public bool IsBuiltIn { get; set; } - - /// - /// Resolves the type. - /// - /// - /// The resolved type. - /// - public virtual TypeBase ResolveType() - { - return TypeInference.TargetType ?? this; - } - - #endregion - - #region Public Methods - - /// - /// Creates a type based on a new base type. If type is a matrix or vector, then the base type is changed to match the newBaseType. - /// - /// The type. - /// New type of the base. - /// A new type - public static TypeBase CreateWithBaseType(TypeBase type, ScalarType newBaseType) - { - if (type is MatrixType) - return new MatrixType(newBaseType, ((MatrixType)type).RowCount, ((MatrixType)type).ColumnCount); - - if (type is VectorType) - return new VectorType(newBaseType, ((VectorType)type).Dimension); - - return newBaseType; - } - - public static TypeBase GetBaseType(TypeBase type) - { - if (type is MatrixType) return ((MatrixType)type).Type; - if (type is VectorType) return ((VectorType)type).Type; - return type; - } - - public static bool HasDimensions(TypeBase typeDeclaration) - { - return (typeDeclaration is ScalarType) || (typeDeclaration is VectorType) || (typeDeclaration is MatrixType); - } - - public static int GetDimensionSize(TypeBase typeDeclaration, int dimension) - { - if (typeDeclaration is VectorType) - { - if (dimension != 1) return 1; - return ((VectorType)typeDeclaration).Dimension; - } - - if (typeDeclaration is MatrixType) - { - var matrixType = (MatrixType)typeDeclaration; - return dimension == 0 ? matrixType.RowCount : matrixType.ColumnCount; - } - - return 1; - } - - /// - /// Equalses the specified other. - /// - /// - /// The other. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public bool Equals(TypeBase other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return Equals(other.Name, Name); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// - /// The to compare with this instance. - /// - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (!typeof(TypeBase).GetTypeInfo().IsAssignableFrom(obj.GetType().GetTypeInfo())) - { - return false; - } - - return Equals((TypeBase)obj); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Name?.GetHashCode() ?? 0; - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Name?.ToString(); - } - - #endregion - - #region Operators - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(TypeBase left, TypeBase right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(TypeBase left, TypeBase right) - { - return !Equals(left, right); - } - - #endregion - - /// - /// Scalar void. TODO this is not a scalar! - /// - public static readonly ScalarType Void = new ScalarType("void", typeof(void)); - - /// - /// Scalar void. TODO this is not a scalar! - /// - public static readonly ScalarType String = new ScalarType("string", typeof(string)); - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/TypeInference.cs b/sources/shaders/Stride.Core.Shaders/Ast/TypeInference.cs deleted file mode 100644 index 526555a3ed..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/TypeInference.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A reference to a type. - /// - [DataContract] - public class TypeInference - { - /// - /// Gets or sets the declaration. - /// - /// - /// The declaration. - /// - public IDeclaration Declaration { get; set; } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase TargetType { get; set; } - - /// - /// Gets or sets the expected type. - /// - /// - /// The expected type. - /// - public TypeBase ExpectedType { get; set; } - - /// - public object Clone() - { - return MemberwiseClone(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/TypeName.cs b/sources/shaders/Stride.Core.Shaders/Ast/TypeName.cs deleted file mode 100644 index eadc7b75df..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/TypeName.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A typeless reference. - /// - public partial class TypeName : TypeBase - { - /// - /// Initializes a new instance of the class. - /// - public TypeName() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type base. - public TypeName(TypeBase typeBase) - : base(typeBase.Name) - { - TypeInference.TargetType = typeBase; - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public TypeName(Identifier name) : base(name) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/TypeReferenceExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/TypeReferenceExpression.cs deleted file mode 100644 index db19235a1e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/TypeReferenceExpression.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A reference to a variable. - /// - public partial class TypeReferenceExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public TypeReferenceExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - public TypeReferenceExpression(TypeBase type) - { - Type = type; - } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type { get; set; } - - /// - /// Gets or sets the declaration. - /// - /// - /// The declaration. - /// - public IDeclaration Declaration { get; set; } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Type); - return ChildrenList; - } - - /// - public override string ToString() - { - return Type.ToString(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/UnaryExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/UnaryExpression.cs deleted file mode 100644 index 5bb32356df..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/UnaryExpression.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A unary expression. - /// - public partial class UnaryExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public UnaryExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The @operator. - /// The expression. - public UnaryExpression(UnaryOperator @operator, Expression expression) - { - this.Operator = @operator; - this.Expression = expression; - } - - /// - /// Gets or sets the operator. - /// - /// - /// The operator. - /// - public UnaryOperator Operator { get; set; } - - /// - /// Gets or sets the expression. - /// - /// - /// The expression. - /// - public Expression Expression { get; set; } - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Expression); - return ChildrenList; - } - - /// - public override string ToString() - { - var isPostFix = Operator == UnaryOperator.PostIncrement || Operator == UnaryOperator.PostDecrement; - var left = isPostFix ? (object)Expression : Operator.ConvertToString(); - var right = isPostFix ? Operator.ConvertToString() : (object)Expression; - return string.Format("{0}{1}", left, right); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/UnaryOperator.cs b/sources/shaders/Stride.Core.Shaders/Ast/UnaryOperator.cs deleted file mode 100644 index b24055f2d9..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/UnaryOperator.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Unary operator used in all binary expressions (except assignment expression). - /// - public enum UnaryOperator - { - /// - /// Logical not operator "!" - /// - LogicalNot, - - /// - /// Bitwise not operator "~" - /// - BitwiseNot, - - /// - /// Minus operator "-" - /// - Minus, - - /// - /// Plus operator "+" - /// - Plus, - - /// - /// Pre-decrement operator "--" - /// - PreDecrement, - - /// - /// Pre-inscrment operator "++" - /// - PreIncrement, - - /// - /// Post-decrement operator "--" - /// - PostDecrement, - - /// - /// Post-increment operator "++" - /// - PostIncrement, - } - - /// - /// Helper for . - /// - public static class UnaryOperatorHelper - { - /// - /// Converts from string an operator. For post and pre operators, only working for pre. - /// - /// The operator text. - /// If operatorStr is invalid - /// An unary operator - public static UnaryOperator FromString(string operatorStr) - { - if (operatorStr == "!") - return UnaryOperator.LogicalNot; - if (operatorStr == "~") - return UnaryOperator.BitwiseNot; - if (operatorStr == "-") - return UnaryOperator.Minus; - if (operatorStr == "+") - return UnaryOperator.Plus; - if (operatorStr == "--") - return UnaryOperator.PreDecrement; - if (operatorStr == "++") - return UnaryOperator.PreIncrement; - throw new ArgumentException(string.Format("Invalid unary operator [{0}]", operatorStr)); - } - - /// - /// Determines whether [is post fix] [the specified unary operator]. - /// - /// The unary operator. - /// - /// true if [is post fix] [the specified unary operator]; otherwise, false. - /// - public static bool IsPostFix(this UnaryOperator unaryOperator) - { - return unaryOperator == UnaryOperator.PostIncrement || unaryOperator == UnaryOperator.PostDecrement; - } - - /// - /// Converts from operator to string - /// - /// The unary operator. - /// - /// A string representation of an unary operator - /// - public static string ConvertToString(this UnaryOperator unaryOperator) - { - switch (unaryOperator) - { - case UnaryOperator.LogicalNot: - return "!"; - case UnaryOperator.BitwiseNot: - return "~"; - case UnaryOperator.Minus: - return "-"; - case UnaryOperator.Plus: - return "+"; - case UnaryOperator.PreDecrement: - case UnaryOperator.PostDecrement: - return "--"; - case UnaryOperator.PreIncrement: - case UnaryOperator.PostIncrement: - return "++"; - } - return string.Empty; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/Variable.cs b/sources/shaders/Stride.Core.Shaders/Ast/Variable.cs deleted file mode 100644 index 359eeeb319..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/Variable.cs +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A variable declaration. - /// - public partial class Variable : Node, IAttributes, IDeclaration, IQualifiers - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public Variable() - { - Attributes = new List(); - Qualifiers = Qualifier.None; - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The name. - /// The initial value. - public Variable(TypeBase type, string name, Expression initialValue = null) - { - Type = type; - Name = new Identifier(name); - InitialValue = initialValue; - Attributes = new List(); - Qualifiers = Qualifier.None; - } - - #endregion - - #region Public Properties - - - /// - public List Attributes { get; set; } - - /// - /// Gets or sets the qualifiers. - /// - /// - /// The qualifiers. - /// - public Qualifier Qualifiers { get; set; } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type { get; set; } - - /// - /// Gets or sets the initial value. - /// - /// - /// The initial value. - /// - public Expression InitialValue { get; set; } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - /// - /// Gets or sets the sub variables (used only for variable group) - /// - /// - /// The sub variables inside this group. - /// - public List SubVariables { get; set; } - - /// - /// Gets a value indicating whether this instance is group. - /// - /// - /// true if this instance is group; otherwise, false. - /// - public bool IsGroup - { - get - { - return SubVariables != null && SubVariables.Count > 0; - } - } - - /// - /// Returns single variable instances. - /// - /// An enumeration of single variable instances - public IEnumerable Instances() - { - if (IsGroup) - { - foreach (var subVariable in SubVariables) - { - yield return subVariable; - } - } - else - { - yield return this; - } - } - - /// - /// Merges attributes and qualifiers from another variable. - /// - /// The variable to merge attribute from. - public void MergeFrom(Variable from) - { - Qualifiers |= from.Qualifiers; - Attributes.AddRange(from.Attributes); - } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Type); - ChildrenList.Add(Name); - if (Qualifiers != Qualifier.None) ChildrenList.Add(Qualifiers); - if (InitialValue != null) ChildrenList.Add(InitialValue); - if (SubVariables != null) - ChildrenList.AddRange(SubVariables); - return ChildrenList; - } - - /// - public override string ToString() - { - return string.Format( - "{0}{1} {2}{3}{4}", - Qualifiers.ToString(false), - Type, - Name, - Qualifiers.ToString(true), - InitialValue != null ? " = " + InitialValue : string.Empty); - } - - /// - public override int GetHashCode() - { - unchecked - { - return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (Type != null ? Type.GetHashCode() : 0); - } - } - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/VariableReferenceExpression.cs b/sources/shaders/Stride.Core.Shaders/Ast/VariableReferenceExpression.cs deleted file mode 100644 index 4977a90720..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/VariableReferenceExpression.cs +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// A reference to a variable. - /// - public partial class VariableReferenceExpression : Expression - { - /// - /// Initializes a new instance of the class. - /// - public VariableReferenceExpression() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The variable. - public VariableReferenceExpression(Variable variable) - { - Name = variable.Name; - TypeInference.TargetType = variable.Type.ResolveType(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public VariableReferenceExpression(Identifier name) - { - Name = name; - } - - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public Identifier Name { get; set; } - - ///// - ///// Gets or sets the variable. - ///// - ///// - ///// The variable. - ///// - //[VisitorIgnore] - //public Variable Variable - //{ - // get - // { - // return (Variable)TypeInference.Declaration; - // } - // set - // { - // TypeInference.Declaration = value; - // } - //} - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Name); - return ChildrenList; - } - - /// - /// Gets a name of the variable referenced by an expression. - /// - /// The expression. - /// Name of the variable referenced. If the expression is not a VariableReferenceExpression, returns null - public static string GetVariableName(Expression expression) - { - var variableReferenceExpression = expression as VariableReferenceExpression; - return variableReferenceExpression == null ? null : variableReferenceExpression.Name.Text; - } - - /// - public override string ToString() - { - return Name; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/VectorType.cs b/sources/shaders/Stride.Core.Shaders/Ast/VectorType.cs deleted file mode 100644 index 5b9fc90bbd..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/VectorType.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Base class for all vector types - /// - public partial class VectorType : GenericBaseType - { - #region Constants and Fields - - /// - /// A Int2 - /// - public static readonly VectorType Int2 = new VectorType(ScalarType.Int, 2); - - /// - /// A Int3 - /// - public static readonly VectorType Int3 = new VectorType(ScalarType.Int, 3); - - /// - /// A Int4 - /// - public static readonly VectorType Int4 = new VectorType(ScalarType.Int, 4); - - /// - /// A UInt2 - /// - public static readonly VectorType UInt2 = new VectorType(ScalarType.UInt, 2); - - /// - /// A UInt3 - /// - public static readonly VectorType UInt3 = new VectorType(ScalarType.UInt, 3); - - /// - /// A UInt4 - /// - public static readonly VectorType UInt4 = new VectorType(ScalarType.UInt, 4); - - /// - /// A Float2 - /// - public static readonly VectorType Float2 = new VectorType(ScalarType.Float, 2); - - /// - /// A Float3 - /// - public static readonly VectorType Float3 = new VectorType(ScalarType.Float, 3); - - /// - /// A Float4 - /// - public static readonly VectorType Float4 = new VectorType(ScalarType.Float, 4); - - /// - /// A Double2 - /// - public static readonly VectorType Double2 = new VectorType(ScalarType.Double, 2); - - /// - /// A Double3 - /// - public static readonly VectorType Double3 = new VectorType(ScalarType.Double, 3); - - /// - /// A Double4 - /// - public static readonly VectorType Double4 = new VectorType(ScalarType.Double, 4); - - /// - /// A Half2 - /// - public static readonly VectorType Half2 = new VectorType(ScalarType.Half, 2); - - /// - /// A Half3 - /// - public static readonly VectorType Half3 = new VectorType(ScalarType.Half, 3); - - /// - /// A Half4 - /// - public static readonly VectorType Half4 = new VectorType(ScalarType.Half, 4); - - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public VectorType() - : base("vector", 2) - { - ParameterTypes.Add(typeof(TypeBase)); - ParameterTypes.Add(typeof(Literal)); - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The type. - /// - /// - /// The dimension. - /// - public VectorType(ScalarType type, int dimension) - : this() - { - Type = type; - Dimension = dimension; - } - - public override TypeBase ToNonGenericType(SourceSpan? span = null) - { - var typeName = new TypeName(); - var name = string.Format("{0}{1}", Type.Name, Dimension); - typeName.Name = new Identifier(name); - if (span.HasValue) - { - typeName.Span = span.Value; - typeName.Name.Span = span.Value; - }; - typeName.TypeInference.TargetType = this; - return typeName; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the dimension. - /// - /// - /// The dimension. - /// - public int Dimension - { - get - { - return (int)((Literal)Parameters[1]).Value; - } - - set - { - Parameters[1] = new Literal(value); - } - } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public TypeBase Type - { - get - { - return (TypeBase)Parameters[0]; - } - - set - { - Parameters[0] = value; - } - } - - #endregion - - /// - public bool Equals(VectorType other) - { - return base.Equals(other); - } - - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - if (ReferenceEquals(this, obj)) - { - return true; - } - return Equals(obj as VectorType); - } - - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(VectorType left, VectorType right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(VectorType left, VectorType right) - { - return !Equals(left, right); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/VisitorIgnoreAttribute.cs b/sources/shaders/Stride.Core.Shaders/Ast/VisitorIgnoreAttribute.cs deleted file mode 100644 index d0edde09e8..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/VisitorIgnoreAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// Instruct a to ignore a field - /// - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public class VisitorIgnoreAttribute : Attribute - { - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Ast/WhileStatement.cs b/sources/shaders/Stride.Core.Shaders/Ast/WhileStatement.cs deleted file mode 100644 index 2c08988564..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Ast/WhileStatement.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; - -namespace Stride.Core.Shaders.Ast -{ - /// - /// While and Do-While statement. - /// - public partial class WhileStatement : Statement, IScopeContainer - { - #region Public Properties - - /// - /// Gets or sets the condition. - /// - /// - /// The condition. - /// - public Expression Condition { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is a do while. - /// - /// - /// true if this instance is a do while; otherwise, false. - /// - public bool IsDoWhile { get; set; } - - /// - /// Gets or sets the statement. - /// - /// - /// The statement. - /// - public Statement Statement { get; set; } - - #endregion - - #region Public Methods - - /// - public override IEnumerable Childrens() - { - ChildrenList.Clear(); - ChildrenList.Add(Condition); - ChildrenList.Add(Statement); - return ChildrenList; - } - - /// - public override string ToString() - { - if (IsDoWhile) - { - return string.Format("do {{...}} while ({0})", Condition); - } - - return string.Format("while ({0}) {{...}}", Condition); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/Ast.Extensions.cs b/sources/shaders/Stride.Core.Shaders/Convertor/Ast.Extensions.cs deleted file mode 100644 index f64860c12a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/Ast.Extensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Core.Shaders.Convertor -{ - - internal static class AstExtensions - { - public static Semantic Semantic(this Variable declarator) - { - return declarator.Qualifiers.OfType().LastOrDefault(); - } - - public static Semantic Semantic(this MethodDeclaration methodDeclaration) - { - return methodDeclaration.Qualifiers.OfType().LastOrDefault(); - } - - public static IEnumerable Attributes(this MethodDeclaration methodDeclaration) - { - return methodDeclaration.Attributes.OfType(); - } - - public static IEnumerable Fields(this StructType structType) - { - return structType.Fields.SelectMany(variable => variable.Instances()); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/BreakContinueVisitor.cs b/sources/shaders/Stride.Core.Shaders/Convertor/BreakContinueVisitor.cs deleted file mode 100644 index 8798178c31..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/BreakContinueVisitor.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Convertor -{ - internal class BreakContinueVisitor : ShaderWalker - { - /// - /// the logger - /// - private ParsingResult parserResult; - - /// - /// the keyword to look after - /// - private string keyword; - - /// - /// list of the "scopes" ie. where a break/continue test has to be performed - /// - private List> scopeList = new List>(); - - /// - /// current stack of "scopes" - /// - private Stack containerStack = new Stack(); - - public BreakContinueVisitor() - : base(false, true) - { - parserResult = new ParsingResult(); - } - - public bool Run(ForStatement forStatement, Variable breakFlag, string keywordName, ParsingResult logger) - { - keyword = keywordName; - - VisitDynamic(forStatement.Body); - - if (logger != null) - parserResult.CopyTo(logger); - - if (parserResult.HasErrors) - return false; - - TransformBreaks(breakFlag); - - return scopeList.Count > 0; - } - - public override void Visit(KeywordExpression expression) - { - if (expression.Name.Text == keyword) - { - var list = new List(containerStack); - list.Reverse(); - if (ParentNode is ExpressionStatement) - list.Add(ParentNode as ExpressionStatement); - else - parserResult.Error("{0} keyword detected, but outside of an ExpressionStatement. It is impossible to unroll the loop", expression.Span, keyword); - - scopeList.Add(list); - } - } - - public override void Visit(BlockStatement blockStatement) - { - containerStack.Push(blockStatement); - base.Visit(blockStatement); - containerStack.Pop(); - } - - public override void Visit(WhileStatement whileStatement) { } - - public override void Visit(ForStatement forStatement) { } - - public override void Visit(StatementList statementList) - { - containerStack.Push(statementList); - base.Visit(statementList); - containerStack.Pop(); - } - - public override void Visit(IfStatement ifStatement) - { - containerStack.Push(ifStatement); - base.Visit(ifStatement); - containerStack.Pop(); - } - - /// - /// Inserts the break variable in the flow of the loop - /// - /// the break variable - protected void TransformBreaks(Variable breakFlag) - { - var breakTest = new UnaryExpression(UnaryOperator.LogicalNot, new VariableReferenceExpression(breakFlag)); - scopeList.Reverse(); - foreach (var breakScope in scopeList) - { - for (int i = 0; i < breakScope.Count - 1; ++i) - { - var currentScope = breakScope[i]; - var nextScope = breakScope[i+1]; - - if (currentScope is StatementList) - { - var typedScope = currentScope as StatementList; - var index = typedScope.Statements.IndexOf(nextScope); - if (index == -1) - { - parserResult.Error("unable to find the next scope when replacing break/continue", nextScope.Span); - break; - } - - var testBlock = new IfStatement(); - testBlock.Condition = breakTest; - var thenBlock = new StatementList(); - for (int j = index + 1; j < typedScope.Statements.Count; ++j) - thenBlock.Add(typedScope.Statements[j]); - testBlock.Then = thenBlock; - - typedScope.Statements.RemoveRange(index + 1, typedScope.Statements.Count - index - 1); - if (typedScope.Statements.Count > 0 && i != breakScope.Count - 2) // do not add the statements behind the break/continue - typedScope.Statements.Add(testBlock); - } - } - - var last = breakScope.LastOrDefault() as ExpressionStatement; - if (last != null) - last.Expression = new AssignmentExpression(AssignmentOperator.Default, new VariableReferenceExpression(breakFlag), new LiteralExpression(true)); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/CallstackVisitor.cs b/sources/shaders/Stride.Core.Shaders/Convertor/CallstackVisitor.cs deleted file mode 100644 index 3d56f931ae..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/CallstackVisitor.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Convertor -{ - public class CallstackVisitor : ShaderRewriter - { - - public CallstackVisitor() : base(true, true) - { - } - - public virtual void Run(MethodDefinition methodEntry) - { - base.Visit(methodEntry); - } - - public override Node Visit(MethodInvocationExpression methodInvocationExpression) - { - // Visit childrens first - base.Visit(methodInvocationExpression); - - var nestedMethodRef = methodInvocationExpression.Target as VariableReferenceExpression; - - if (nestedMethodRef != null) - { - var nestedMethod = nestedMethodRef.TypeInference.Declaration as MethodDefinition; - if (nestedMethod != null && !nestedMethod.IsBuiltin) - { - this.ProcessMethodInvocation(methodInvocationExpression, nestedMethod); - } - } - - return methodInvocationExpression; - } - - protected virtual void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) - { - this.VisitDynamic(method); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/ConstantBufferLayoutRule.cs b/sources/shaders/Stride.Core.Shaders/Convertor/ConstantBufferLayoutRule.cs deleted file mode 100644 index 04af5e8b94..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/ConstantBufferLayoutRule.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Convertor -{ - /// - /// A single map rule. - /// - public class ConstantBufferLayoutRule - { - /// - /// Gets or sets from name. - /// - /// - /// From name. - /// - public string Register { get; set; } - - /// - /// Gets or sets the binding. - /// - /// - /// The location. - /// - public string Binding { get; set; } - - /// - public override string ToString() - { - return string.Format("Register: {0}, Binding: {1}", this.Register, this.Binding); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/GlobalUniformVisitor.cs b/sources/shaders/Stride.Core.Shaders/Convertor/GlobalUniformVisitor.cs deleted file mode 100644 index b2728aebc0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/GlobalUniformVisitor.cs +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; - -using Stride.Core.Shaders.Ast; - -using HlslStorageQualifiers = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// Collect a list of global uniforms that are used as global temporary variable. - /// - public class GlobalUniformVisitor : CallstackVisitor - { - private List uniformReadList; - - private Shader shader; - - /// - /// Initializes a new instance of the class. - /// - /// The shader. - public GlobalUniformVisitor(Shader shader) - { - this.shader = shader; - uniformReadList = new List(); - this.UniformUsedWriteFirstList = new List(); - this.UniformReadWriteList = new List(); - } - - /// - /// Gets a list of uniform that are used as "write" variable first. - /// - public List UniformUsedWriteFirstList { get; private set; } - - /// - /// Gets a list of uniform that are used as "read" and "write" variable. - /// - public List UniformReadWriteList { get; private set; } - - public bool IsVariableAsGlobalTemporary(Variable variable) - { - return UniformUsedWriteFirstList.Contains(variable); - } - - public bool IsVariableAsGlobalTemporary(Expression expression) - { - var variable = GetUniform(expression); - if (variable == null) - return false; - return IsVariableAsGlobalTemporary(variable); - } - - public bool IsUniformReadWrite(Variable variable) - { - return UniformReadWriteList.Contains(variable); - } - - public bool IsUniformReadWrite(Expression expression) - { - var variable = GetUniform(expression); - if (variable == null) - return false; - return IsUniformReadWrite(variable); - } - - public override Node Visit(VariableReferenceExpression variableRef) - { - var variable = GetUniform(variableRef); - - // If the variable is a global uniform, non static/const and is not already in the list used then - if (variable != null && !uniformReadList.Contains(variable)) - { - uniformReadList.Add(variable); - } - return variableRef; - } - - private Variable GetUniform(Expression expression) - { - VariableReferenceExpression variableRef = null; - while (expression != null) - { - if (expression is MemberReferenceExpression) - { - expression = ((MemberReferenceExpression)expression).Target; - } - else if (expression is IndexerExpression) - { - expression = ((IndexerExpression)expression).Target; - } - else - { - variableRef = expression as VariableReferenceExpression; - break; - } - } - - if (variableRef != null) - { - var variable = variableRef.TypeInference.Declaration as Variable; - - // If the variable is a global uniform, non static/const and is not already in the list used then - return (variable != null && shader.Declarations.Contains(variable) - && !variable.Qualifiers.Contains(HlslStorageQualifiers.Static) - && !variable.Qualifiers.Contains(StorageQualifier.Const) - && !variable.Qualifiers.Contains(StorageQualifier.Shared) - && !variable.Qualifiers.Contains(StorageQualifier.GroupShared)) - ? variable - : null; - } - return null; - } - - private int countReadBeforeInvoke; - - public override Node Visit(MethodInvocationExpression methodInvocationExpression) - { - // Save the number of variable in read-only mode - countReadBeforeInvoke = uniformReadList.Count; - return base.Visit(methodInvocationExpression); - } - - protected override void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) - { - - // Handle the case where a parameter can be out - // If this is the case, we need to check that - for (int i = 0; i < invoke.Arguments.Count; i++) - { - var arg = invoke.Arguments[i]; - var variable = this.GetUniform(arg); - var parameter = method.Parameters[i]; - if (variable != null && parameter.Qualifiers.Contains(ParameterQualifier.Out)) - { - bool isUniformWasAlreadyUsedAsRead = false; - for (int j = 0; j < countReadBeforeInvoke; j++) - { - if (ReferenceEquals(uniformReadList[i], variable)) - { - isUniformWasAlreadyUsedAsRead = true; - break; - } - } - - // If this is a out parameter, and the variable was not already used as a read, then - // we can remove it from the uniform read list - if (!isUniformWasAlreadyUsedAsRead) - { - uniformReadList.Remove(variable); - if (!UniformUsedWriteFirstList.Contains(variable)) - UniformUsedWriteFirstList.Add(variable); - } - } - } - - this.VisitDynamic(method); - } - - public override Node Visit(AssignmentExpression assignmentExpression) - { - var variable = GetUniform(assignmentExpression.Target); - bool isMemberExpression = assignmentExpression.Target is MemberReferenceExpression; - if (variable != null) - { - // Default == operator is the only write only operators - if (assignmentExpression.Operator == AssignmentOperator.Default && !uniformReadList.Contains(variable) && !this.UniformUsedWriteFirstList.Contains(variable)) - { - // Handle the case where the assignment operator is partial like vect.xy = 5; and later vect.zw += 6; - // In this case, the variable is considered as read and write (and not only write first) - if (isMemberExpression) - { - var variableType = variable.Type.ResolveType(); - - if (variableType is VectorType || variableType is MatrixType) - { - var dim = Math.Max(TypeBase.GetDimensionSize(variableType, 0), TypeBase.GetDimensionSize(variableType, 1)); - - var memberRef = assignmentExpression.Target as MemberReferenceExpression; - var numberOfMembers = memberRef.Member.Text.Length; - - // If the variable is a global uniform, non static/const and is not already in the list used then - if (numberOfMembers < dim) - { - if (!uniformReadList.Contains(variable)) - { - uniformReadList.Add(variable); - } - } - else - { - UniformUsedWriteFirstList.Add(variable); - } - } - } - else - { - var variableType = variable.Type.ResolveType(); - if (!variableType.Name.Text.StartsWith("RWTexture") && !variableType.Name.Text.StartsWith("RWBuffer")) - { - UniformUsedWriteFirstList.Add(variable); - } - } - } - if (assignmentExpression.Operator != AssignmentOperator.Default) - { - if (!UniformReadWriteList.Contains(variable)) - UniformReadWriteList.Add(variable); - } - } - - return assignmentExpression; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/GlslKeywords.cs b/sources/shaders/Stride.Core.Shaders/Convertor/GlslKeywords.cs deleted file mode 100644 index c75985d1dc..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/GlslKeywords.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Reflection; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text.RegularExpressions; -using Stride.Core.Shaders.Properties; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// GlslKeywords - /// - public class GlslKeywords - { - /// - /// Name of the default keywords.glsl file - /// - private const string KeywordsFileName = "keywords.glsl"; - - /// - /// Regex to remove pseudo C++ comments - /// - private static readonly Regex StripComments = new Regex("//.*"); - - /// - /// Regsitered tokens - /// - private static readonly HashSet Tokens = new HashSet(); - - /// - /// Initializes the class by loading the keywords file. - /// - /// - /// It loads it from an internal resource of this assembly. - /// - static GlslKeywords() - { - Stream stream = null; - try - { - stream = new MemoryStream(Resources.Keywords); - - InitializeFromStream(stream); - } - catch (Exception ex) - { - Debug.WriteLine("Unable to load keywords.glsl file. Reason: " + ex); - } finally - { - if (stream != null) - try { stream.Dispose(); } catch {} - } - } - - /// - /// Initializes the tokens from a stream. - /// - /// The stream. - private static void InitializeFromStream(Stream stream) - { - if (stream == null) - return; - - var reader = new StreamReader(stream); - string line; - while ( (line = reader.ReadLine()) != null) - { - var newTokens = StripComments.Replace(line, "").Trim().Split((string[])null, StringSplitOptions.RemoveEmptyEntries); - foreach (var newToken in newTokens) - Tokens.Add(newToken); - } - } - - /// - /// Determines whether the specified identifier is a glsl reserved keyword. - /// - /// A glsl identifier. - /// - /// true if the specified identifier is a glsl reserved keyword; otherwise, false. - /// - public static bool IsReserved(string identifier) - { - return Tokens.Contains(identifier); - - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/GlslShaderPlatform.cs b/sources/shaders/Stride.Core.Shaders/Convertor/GlslShaderPlatform.cs deleted file mode 100644 index 598f4a5cff..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/GlslShaderPlatform.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Convertor -{ - public enum GlslShaderPlatform - { - /// - /// GLSL OpenGL Shader. - /// - OpenGL, - - /// - /// GLSL OpenGL ES Shader. - /// - OpenGLES, - - /// - /// GLSL Vulkan Shader. - /// - Vulkan, - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslConvertor.cs b/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslConvertor.cs deleted file mode 100644 index 67c615eded..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslConvertor.cs +++ /dev/null @@ -1,4768 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; - -using Stride.Core.Shaders.Analysis; -using Stride.Core.Shaders.Analysis.Hlsl; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Glsl; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Utility; -using Stride.Core.Shaders.Visitor; -using Stride.Core.Shaders.Writer.Hlsl; - -using LayoutQualifier = Stride.Core.Shaders.Ast.Glsl.LayoutQualifier; -using ParameterQualifier = Stride.Core.Shaders.Ast.ParameterQualifier; -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; -using HlslStorageQualifier = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; -using GlslStorageQualifier = Stride.Core.Shaders.Ast.Glsl.StorageQualifier; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// A converter for transforming HLSL into GLSL. - /// - /// - /// HLSL to GLSL conversion requires several steps: - /// - /// Replace input/output structure access by varying variables. - /// Replace common types such as float4 => vec4. - /// Change main signature. - /// Convert return statements into GLSL out assignments. - /// - /// - public class HlslToGlslConvertor : ShaderRewriter - { - // Each sampler+texture pair will map to a GLSL sampler. - // KeyValuePair => Variable - #region Constants and Fields - - private const string TagLayoutKey = "LAYOUT"; - private const string VertexIOInterfaceName = "_VertexIO_"; - - private const string gl_FrontFacing = "gl_FrontFacing"; - - private static readonly List SemanticModifiers = new List { "_centroid", "_pp", "_sat" }; - - private readonly bool[] allocatedRegistersForSamplers = new bool[16]; - - private readonly bool[] allocatedRegistersForUniforms = new bool[256]; - - private readonly Dictionary builtinInputs; - - private readonly Dictionary builtinOutputs; - - private readonly Dictionary builtinGlslTypes; - - private readonly List declarationListToRemove = new List(); - - private readonly GlslShaderPlatform shaderPlatform; - - private readonly int shaderVersion; - - private readonly string entryPointName; - - private readonly Dictionary functionMapping; - - private readonly Dictionary inputAssignment = new Dictionary(new ReferenceEqualityComparer()); - - private readonly List listOfMultidimensionArrayVariable = new List(); - - private readonly Dictionary methodInvocationHandled = new Dictionary(new ReferenceEqualityComparer()); - - private readonly PipelineStage pipelineStage; - - private readonly ShaderModel shaderModel; - - private readonly Dictionary samplerMapping = new Dictionary(); - - private MethodDefinition entryPoint; - - private string geometryLayoutInput; - - private Parameter geometryInputParameter; - - private string geometryLayoutOutput; - - private List inputs = new List(); - - private bool isAssignmentTarget; - - private List outputs = new List(); - - private ParsingResult parserResult; - - private Shader shader; - - private GlobalUniformVisitor globalUniformVisitor; - - private bool needCustomFragData = true; - - private int breakIndex = 0; - - private int structedBufferCounter = 0; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// Name of the entry point. - /// The pipeline stage. - /// The shader model. - /// if set to true [use builtin semantic]. - public HlslToGlslConvertor(GlslShaderPlatform shaderPlatform, int shaderVersion, string entryPointName, PipelineStage pipelineStage, ShaderModel shaderModel, bool useBuiltinSemantic = true) - : base(true, true) - { - bool isVulkan = shaderPlatform == GlslShaderPlatform.Vulkan; - - this.shaderPlatform = shaderPlatform; - this.shaderVersion = shaderVersion; - this.entryPointName = entryPointName; - this.pipelineStage = pipelineStage; - this.shaderModel = shaderModel; - this.VariableLayouts = new Dictionary(); - this.ConstantBufferLayouts = new Dictionary(); - this.MapRules = new Dictionary(); - this.KeepConstantBuffer = true; - this.TextureFunctionsCompatibilityProfile = false; - this.KeepNonUniformArrayInitializers = shaderPlatform != GlslShaderPlatform.OpenGLES; - this.ViewFrustumRemap = !isVulkan; - this.KeepSamplers = isVulkan; - this.UseLocationLayout = isVulkan; - - if (useBuiltinSemantic) - { - builtinInputs = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - builtinOutputs = new Dictionary(StringComparer.CurrentCultureIgnoreCase); - - // Register defaults Semantics with ShaderModel - switch (pipelineStage) - { - case PipelineStage.Vertex: - builtinInputs.Add("SV_VertexID", isVulkan ? "gl_VertexIndex" : "gl_VertexID"); - builtinInputs.Add("SV_InstanceID", isVulkan ? "gl_InstanceIndex" : "gl_InstanceID"); - if (shaderModel < ShaderModel.Model40) - { - builtinOutputs.Add("POSITION", "gl_Position"); - builtinOutputs.Add("PSIZE", "gl_PointSize"); - } - else - { - builtinOutputs.Add("SV_Position", "gl_Position"); - builtinOutputs.Add("SV_ClipDistance", "gl_ClipDistance[]"); - } - break; - case PipelineStage.Geometry: - if (shaderModel < ShaderModel.Model40) - { - builtinInputs.Add("PSIZE", "gl_PointSize"); - builtinOutputs.Add("PSIZE", "gl_PointSize"); - } - else - { - builtinInputs.Add("SV_POSITION", "gl_Position"); - builtinInputs.Add("SV_ClipDistance", "gl_ClipDistance[]"); - builtinInputs.Add("SV_PrimitiveID", "gl_PrimitiveIDIn"); - builtinOutputs.Add("SV_POSITION", "gl_Position"); - builtinOutputs.Add("SV_ClipDistance", "gl_ClipDistance[]"); - builtinOutputs.Add("SV_RenderTargetArrayIndex", "gl_Layer"); - } - break; - case PipelineStage.Pixel: - if (shaderModel < ShaderModel.Model40) - { - builtinInputs.Add("VPOS", "gl_FragCoord"); - builtinInputs.Add("VFACE", gl_FrontFacing); - builtinInputs.Add("POSITION", "gl_FragCoord"); - builtinOutputs.Add("DEPTH", "gl_FragDepth"); - builtinOutputs.Add("COLOR", "gl_FragData[]"); - } - else - { - builtinInputs.Add("SV_Position", "gl_FragCoord"); - builtinInputs.Add("SV_IsFrontFace", "gl_FrontFacing"); - builtinInputs.Add("SV_ClipDistance", "gl_ClipDistance[]"); - builtinOutputs.Add("SV_Depth", "gl_FragDepth"); - builtinOutputs.Add("SV_Target", "gl_FragData[]"); - } - break; - case PipelineStage.Compute: - builtinInputs.Add("SV_DispatchThreadID", "gl_GlobalInvocationID"); - builtinInputs.Add("SV_GroupID", "gl_WorkGroupID"); - builtinInputs.Add("SV_GroupIndex", "gl_LocalInvocationIndex"); - builtinInputs.Add("SV_GroupThreadID", "gl_LocalInvocationID"); - break; - } - - builtinGlslTypes = new Dictionary(StringComparer.CurrentCultureIgnoreCase) - { - { "gl_ClipDistance", ScalarType.Float}, // array - { "gl_FragCoord", VectorType.Float4}, - { "gl_FragDepth", ScalarType.Float}, - { "gl_FragColor", VectorType.Float4}, - { "gl_FragData", VectorType.Float4}, // array - { "gl_FrontFacing", ScalarType.Bool}, - { "gl_InstanceID", ScalarType.Int }, - { "gl_InstanceIndex", ScalarType.Int }, - { "gl_InvocationID", ScalarType.Int}, - { "gl_Layer", ScalarType.Int}, - { "gl_NumSamples", ScalarType.Int}, - { "gl_PatchVerticesIn", ScalarType.Int}, - { "gl_PointCoord", VectorType.Float2}, - { "gl_PointSize", ScalarType.Float}, - { "gl_Position", VectorType.Float4}, - { "gl_PrimitiveID", ScalarType.Int}, - { "gl_PrimitiveIDIn", ScalarType.Int}, - { "gl_SampleID", ScalarType.Int}, - { "gl_SampleMask", ScalarType.Int}, // array - { "gl_SampleMaskIn", ScalarType.Int}, // array - { "gl_SamplePosition", VectorType.Float2}, - { "gl_TessCoord", VectorType.Float3}, - { "gl_VertexID", ScalarType.Int}, - { "gl_VertexIndex", ScalarType.Int}, - { "gl_ViewportIndex", ScalarType.Int}, - { "gl_GlobalInvocationID", VectorType.UInt3}, - { "gl_WorkGroupID", VectorType.UInt3}, - { "gl_LocalInvocationIndex", ScalarType.UInt}, - { "gl_LocalInvocationID", VectorType.UInt3}, - }; - } - - functionMapping = new Dictionary - { - { "ddx", "dFdx" }, - { "ddy", "dFdy" }, - { "fmod", "mod" }, - { "frac", "fract" }, - { "lerp", "mix" }, - { "rsqrt", "inversesqrt" }, - { "atan2", "atan" }, - { "saturate", "clamp" }, - { "GroupMemoryBarrier", "groupMemoryBarrier" }, - //{ "D3DCOLORtoUBYTE4", "ivec4" }, - }; - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets a value indicating wether Z projection coordinates will be remapped from [0;1] to [-1;1] at end of vertex shader. - /// - public bool ViewFrustumRemap { get; set; } = true; - - /// - /// Gets or sets a value indicating wether Y projection will be inverted at end of vertex shader. - /// - public bool FlipRenderTarget { get; set; } = true; - - /// - /// Gets or sets a value indicating whether this instance is point sprite shader. - /// - /// - /// true if this instance is point sprite shader; otherwise, false. - /// - public bool IsPointSpriteShader { get; set; } - - /// - /// Gets or sets a value indicating whether [no fix for mul for matrix]. - /// - /// - /// true if [no fix for mul for matrix]; otherwise, false. - /// - public bool NoSwapForBinaryMatrixOperation { get; set; } = true; - - /// - /// Gets or sets a value indicating whether [no implicit layout]. - /// - /// - /// true if [no implicit layout]; otherwise, false. - /// - public bool UseBindingLayout { get; set; } - - public bool KeepSamplers { get; set; } - - /// - /// Gets or sets a value indicating whether [use builtin semantic]. - /// - /// - /// true if [use builtin semantic]; otherwise, false. - /// - public bool UseBuiltinSemantic { get; set; } - - /// - /// Gets or sets a value indicating whether [use explicit layout position]. - /// - /// - /// true if [use explicit layout position]; otherwise, false. - /// - public bool UseLocationLayout { get; set; } - - public IDictionary InputAttributeNames { get; set; } - - /// - /// Gets or sets a value indicating whether texture name will be [texture] or [texture]_[sampler] for DX10 texture objects conversion. - /// - public bool UseOnlyTextureName { get; set; } - - /// - /// Gets or sets a value indicating whether [use semantic name]. - /// - /// - /// true if [use semantic name]; otherwise, false. - /// - public bool UseSemanticForVariable { get; set; } - - /// - /// Gets or sets a value indicating whether [use semantic for location]. - /// - /// - /// true if [use semantic for location]; otherwise, false. - /// - public bool UseSemanticForLocation { get; set; } - - /// - /// Gets or sets a value indicating whether [use interface for in out]. - /// - /// true if [use interface for in out]; otherwise, false. - public bool UseInterfaceForInOut { get; set; } - - /// - /// Gets the map config. - /// - /// - /// The map config. - /// - public Dictionary VariableLayouts { get; private set; } - - /// - /// Gets the constant buffer layouts. - /// - /// - /// The constant buffer layouts. - /// - public Dictionary ConstantBufferLayouts { get; private set; } - - /// - /// Gets or sets the map rules. - /// - /// - /// The map rules. - /// - public Dictionary MapRules { get; private set; } - - /// - /// Gets or sets a value indicating whether to keep array initializers for uniforms. - /// - /// - /// true if keep uniform array initializers, false if not. - /// - public bool KeepUniformArrayInitializers { get; set; } - - /// - /// Gets or sets a flag specifying whether compatibility profile is used for texture functions. - /// As an example, with compatibility on, texture() might become texture2D(). - /// - /// - /// true if texture compatibility profile is enabled, false if not. - /// - public bool TextureFunctionsCompatibilityProfile { get; set; } - - /// - /// - /// - public bool KeepConstantBuffer { get; set; } - - /// - /// Gets or sets a value indicating whether to keep array initializers. - /// - public bool KeepNonUniformArrayInitializers { get; set; } - - public GlslShaderPlatform Platform { get; set; } - - public int PlatformVersion { get; set; } - - /// - /// Gets or sets a value indicating whether to unroll the loops with the [unroll] annotation. - /// - public bool UnrollForLoops { get; set; } = true; - - #endregion - - #region Properties - - /// - /// Gets or sets the current function being parsed. - /// - /// - /// The current function. - /// - private MethodDeclaration CurrentFunction { get; set; } - - /// - /// Gets a value indicating whether this instance is in entry point. - /// - /// - /// true if this instance is in entry point; otherwise, false. - /// - private bool IsInEntryPoint { get { return CurrentFunction != null && CurrentFunction.Name.Text == entryPointName; } } - - #endregion - - #region Public Methods and Operators - - /// - /// Prepares the specified shader for glsl to hlsl conversion (before type inference analysis). - /// - /// - /// The shader. - /// - public static void Prepare(Shader shader) - { - // Replace all Half types to float, as there are no equivalent in glsl - // This will force the type inference analysis to use float instead of half - SearchVisitor.Run( - shader, - node => - { - if (node.Equals(ScalarType.Half)) - return ScalarType.Float; - - // Transform half vectors to float vectors - var typeBase = node as TypeBase; - if (typeBase != null) - { - var vectorType = typeBase.ResolveType() as VectorType; - if (vectorType != null) - { - var subType = vectorType.Type.ResolveType(); - if (subType == ScalarType.Half) - typeBase.TypeInference.TargetType = TypeBase.CreateWithBaseType(vectorType, ScalarType.Float); - } - } - - return node; - }); - } - - /// - /// Runs the convertor on the specified parser result. - /// - /// The parser result. - public void Run(ParsingResult parserResultIn) - { - parserResult = parserResultIn; - shader = parserResultIn.Shader; - - // Transform typedef with inline declaration to separate declaration + typedef - // in order for the strip visitor to work - SplitTypeDefs(); - - // Find entry point - entryPoint = shader.Declarations.OfType().FirstOrDefault(x => x.Name.Text == entryPointName); - - if (entryPoint == null) - throw new ArgumentException(string.Format("Could not find entry point named {0}", entryPointName)); - - // Transform multiple variable declaration to single - TransformGlobalMultipleVariableToSingleVariable(); - - // Gather all samplers and create new samplers - // Strips unused code - GenerateSamplerMappingAndStrip(); - - // Look for global uniforms used as global temp variable - globalUniformVisitor = new GlobalUniformVisitor(shader); - globalUniformVisitor.Run(entryPoint); - - var writer = new HlslWriter(); - writer.Visit(shader); - var text = writer.Text; - - var castVisitor = new CastAnalysis(parserResult); - castVisitor.Run(); - - // This the shader - Visit(shader); - - // Remove Default parameters for all function - RemoveDefaultParametersForMethods(); - - // Transform all types to glsl types - TranformToGlslTypes(); - - // Rename variable using a glsl keyword - RenameGlslKeywords(); - - // Rebind all renamed variables - RebindVariableReferenceExpressions(); - - // Order first all non-method declarations and then after method declarations - var declarations = shader.Declarations.Where(declaration => !(declaration is MethodDeclaration)).ToList(); - declarations.AddRange(shader.Declarations.OfType()); - shader.Declarations = declarations; - - // Add std140 layout - ApplyStd140Layout(); - - // Sort qualifiers in the order GLSL expects them - ReorderVariableQualifiers(); - } - - #endregion - - #region Methods - - /// - /// Visits the specified variable. - /// - /// - /// The variable. - /// - public override Node Visit(Variable variable) - { - // All variable arrays are processed later to simplify/unify their bounds - var variableType = variable != null ? variable.Type.ResolveType() : null; - var arrayType = variableType as ArrayType; - - if (arrayType != null) - { - if (!this.listOfMultidimensionArrayVariable.Contains(variable)) - this.listOfMultidimensionArrayVariable.Add(variable); - } - - var isInMethod = !shader.Declarations.Contains(variable); - - // Static variable are allowed inside HLSL functions - // but only at global scope for glsl - // TODO check if removing the static modifier is enough or we need to move the variable at the toplevel scope (a bit more harder to implement) - if (CurrentFunction != null && variable.Qualifiers.Contains(HlslStorageQualifier.Static)) - variable.Qualifiers.Values.Remove(HlslStorageQualifier.Static); - - // Because const qualifier in HLSL is way too permissive, we need to remove it for GLSL - // Remove only const qualifiers inside methods - if (isInMethod && variable.Qualifiers.Contains(StorageQualifier.Const)) - variable.Qualifiers.Values.Remove(StorageQualifier.Const); - - base.Visit(variable); - - // Set the Type of a variable by using the resolve type - if (variable.Type.TypeInference.Declaration is Typedef) - { - var typeDefType = variable.Type.ResolveType(); - if (typeDefType is StructType) - { - variable.Type = new TypeName(typeDefType.Name) { TypeInference = { Declaration = (IDeclaration)typeDefType, TargetType = typeDefType } }; - } - else - { - variable.Type = typeDefType; - } - } - - if (variable.Type is ArrayType) - { - if (variable.InitialValue is MethodInvocationExpression && !KeepNonUniformArrayInitializers) - { - if (isInMethod) // inside a method - { - var arrayInit = variable.InitialValue as MethodInvocationExpression; - if (arrayInit.Target is IndexerExpression) // HACK: this checks that it is an initialization. It is a hack because the GLSL grammar was mapped into the hlsl one - { - // build the statement list - var statements = new StatementList(); - statements.Add(new DeclarationStatement(variable)); - for (int i = 0; i < arrayInit.Arguments.Count; ++i) - { - var statement = new ExpressionStatement(new AssignmentExpression(AssignmentOperator.Default, new IndexerExpression(new VariableReferenceExpression(variable.Name), new LiteralExpression(i)), arrayInit.Arguments[i])); - statements.Add(statement); - } - - // patch the variable - variable.InitialValue = null; - - return statements; - } - } - else if (!isInMethod && !IsUniformLike(variable)) // non-uniform variable oustide a method - { - variable.InitialValue = null; - } - } - } - - return variable; - } - - /// - /// Visits the specified function. - /// - /// The function. - public override Node Visit(MethodDefinition function) - { - // Enter this function - CurrentFunction = function; - - - // Convert HLSL "in out" qualifier to "inout" qualifier - foreach (var arg in function.Parameters) - { - if (arg.Qualifiers.Contains(ParameterQualifier.Out) && arg.Qualifiers.Contains(ParameterQualifier.In)) - { - arg.Qualifiers.Values.Remove(ParameterQualifier.Out); - arg.Qualifiers.Values.Remove(ParameterQualifier.In); - arg.Qualifiers.Values.Add(ParameterQualifier.InOut); - } - } - - if (function == entryPoint) - PrepareVisitEntryPoint(function); // Prepare visit of entry point - else - function.Qualifiers.Values.Clear(); // Remove semantics from function indirectly used by entrypoint - - // Convert function return type - // Visit all subnodes of this function - base.Visit(function); - - // For entry point restore arguments/declcontext - if (function == entryPoint) - PostVisitEntryPoint(function); - - // Remove uniform parameters - foreach (var modifier in function.Parameters.Select(variable => variable.Qualifiers).Where(modifier => modifier.Contains(GlslStorageQualifier.Uniform))) - modifier.Values.Remove(GlslStorageQualifier.Uniform); - - // For GeometryShader, remove StreamType parameters - RemoveStreamTypeFromMethodDefinition(function); - - // Clear current function viside - CurrentFunction = null; - - return function; - } - - /// - /// Prepares the visit of entry point. - /// - /// The entry point function. - protected void PrepareVisitEntryPoint(MethodDefinition function) - { - inputs.Clear(); - outputs.Clear(); - - // Make a copy of arguments - // var savedDeclarationContext = function.Declarations.ToList(); - foreach (var arg in function.Parameters) - { - if (arg.Qualifiers.Contains(ParameterQualifier.Out) || arg.Qualifiers.Contains(ParameterQualifier.InOut)) - { - outputs.Add(arg); - } - else - { - inputs.Add(arg); - - // Process and convert GS input layout type - foreach (var qualifier in arg.Qualifiers) - { - switch ((string)qualifier.Key) - { - case "triangleadj": - geometryLayoutInput = "triangles_adjacency"; - break; - case "triangle": - geometryLayoutInput = "triangles"; - break; - case "lineadj": - geometryLayoutInput = "lines_adjacency"; - break; - case "line": - geometryLayoutInput = "lines"; - break; - case "point": - geometryLayoutInput = "points"; - break; - } - - if (geometryLayoutInput != null) - { - geometryInputParameter = arg; - } - } - } - } - - - // ------------------------------------------------ - // Check the type of the output for pixel shaders - // If glFragData has multiple types, than we need to output a - // new output type for glFragData. - // ------------------------------------------------ - - if (pipelineStage == PipelineStage.Pixel) - { - int countDifferentType = 0; - - foreach (var output in outputs) - { - var outputType = output.Type.ResolveType(); - if (outputType is StructType) - { - countDifferentType += GetMembers((StructType)outputType).Select(fieldRef => fieldRef.Field).Count(field => this.CheckFragDataOutputType(field.Semantic(), field.Type.ResolveType())); - } - else - { - if (CheckFragDataOutputType(output.Semantic(), outputType)) - countDifferentType++; - } - } - - var returnType = function.ReturnType.ResolveType(); - var returnStructType = returnType as StructType; - if (returnStructType != null) - { - countDifferentType += GetMembers(returnStructType).Select(fieldRef => fieldRef.Field).Count(field => this.CheckFragDataOutputType(field.Semantic(), field.Type.ResolveType())); - } - else if (function.Semantic() != null) - { - if (CheckFragDataOutputType(function.Semantic(), returnType)) - countDifferentType++; - } - - needCustomFragData |= countDifferentType > 0; - } - } - - private bool CheckFragDataOutputType(Semantic inputSemantic, TypeBase type) - { - if (inputSemantic == null) - return false; - - TypeBase newFieldType; - int semanticIndex = 0; - var semantic = ResolveSemantic(inputSemantic, type, false, "tmptmp", out newFieldType, out semanticIndex, inputSemantic.Span); - if (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(semantic.Name.Text, "gl_fragdata", CompareOptions.IgnoreCase) && (newFieldType != type || type is ArrayType)) - { - return true; - //// Generate only fragdata when whe basetype is completly changing - //// TODO: improve handling gl_fragdata: Current code is not robust. - //var baseElementType = type is ArrayType ? ((ArrayType)type).Type.ResolveType() : type; - //var baseNewElementType = newFieldType is ArrayType ? ((ArrayType)newFieldType).Type.ResolveType() : newFieldType; - - //// Get type of the element - //baseElementType = TypeBase.GetBaseType(baseElementType); - //baseNewElementType = TypeBase.GetBaseType(baseNewElementType); - - //return (baseElementType != baseNewElementType); - } - return false; - } - - /// - /// Visits the entry point. - /// - /// The entry point function. - protected void PostVisitEntryPoint(MethodDefinition function) - { - int inputSemanticLocation = 0; - int outputSemanticLocation = 0; - - // For structure in input, make a local copy - foreach (var variable in this.inputs) - { - var structType = variable.Type.ResolveType() as StructType; - if (structType != null) - { - bool semanticFound = false; - foreach (var fieldRef in GetMembers(structType)) - { - var field = fieldRef.Field; - - var semantic = field.Semantic(); - if (semantic != null) - { - var fieldType = field.Type.ResolveType(); - var variableFromSemantic = this.BindLocation(semantic, fieldType, true, fieldRef.FieldNamePath, ref inputSemanticLocation, variable.Span); - - // Link to the original variable - // var variableSemanticRef = new VariableReferenceExpression(variableFromSemantic.Name) { TypeInference = { Declaration = variableFromSemantic } }; - - function.Body.Insert( - 0, - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, fieldRef.GetMemberReference(new VariableReferenceExpression(variable.Name)), - this.CastSemanticToReferenceType(variableFromSemantic.Name, fieldType, variableFromSemantic))) - { Span = variable.Span }); - semanticFound = true; - } - } - - if (semanticFound) - { - // No modifiers for structure inlined in the code - variable.Qualifiers = Qualifier.None; - function.Body.Statements.Insert(0, new DeclarationStatement(variable) { Span = variable.Span }); - } - } - else - { - var semantic = variable.Semantic(); - if (semantic != null) - this.BindLocation(semantic, variable.Type.ResolveType(), true, variable.Name, ref inputSemanticLocation, variable.Span); - } - } - - // For structure in output, declare a local variable - foreach (var variable in this.outputs) - { - var structType = variable.Type.ResolveType() as StructType; - if (structType != null) - { - // No modifiers for structure inlined in the code - variable.Qualifiers = Qualifier.None; - function.Body.Statements.Insert(0, new DeclarationStatement(variable)); - - var statementList = new StatementList(); - - var lastStatement = function.Body.Statements.LastOrDefault(); - - ReturnStruct(structType, new VariableReferenceExpression(variable.Name) { Span = lastStatement != null ? lastStatement.Span : new SourceSpan() }, statementList); - - function.Body.Statements.Add(statementList); - } - } - - // Process return type - var returnType = function.ReturnType.ResolveType(); - var returnStructType = returnType as StructType; - if (returnStructType != null) - { - foreach (var fieldRef in GetMembers(returnStructType)) - { - var field = fieldRef.Field; - BindLocation(field.Semantic(), field.Type.ResolveType(), false, field.Name, ref outputSemanticLocation, function.ReturnType.Span); - } - } - else if (function.Semantic() != null) - { - var semantic = function.Semantic(); - BindLocation(semantic, returnType, false, null, ref outputSemanticLocation, semantic.Span); - } - - // Set Location for each output - if (pipelineStage == PipelineStage.Geometry) - { - foreach (var variable in shader.Declarations.OfType()) - { - if (variable.Qualifiers.Contains(ParameterQualifier.Out)) - { - BindLocation(variable.Semantic(), variable.Type.ResolveType(), false, variable.Name, ref outputSemanticLocation, variable.Span); - } - } - } - else - { - foreach (var outputVariable in outputs) - { - BindLocation(outputVariable.Semantic(), outputVariable.Type.ResolveType(), false, outputVariable.Name, ref outputSemanticLocation, outputVariable.Span); - } - } - - // Process parameters - for (int i = 0; i < function.Parameters.Count; ++i) - { - var variable = function.Parameters[i]; - var modifier = variable.Qualifiers; - if (modifier.Contains(GlslStorageQualifier.Uniform)) - { - function.Parameters.RemoveAt(i--); - ScopeStack.Peek().RemoveDeclaration(variable); - - if (!shader.Declarations.Contains(variable)) - { - // Generate name by appending _uniform and _1, _2 etc... if already existing - var variableNameBase = variable.Name; - variable.Name.Text += "_uniform"; - int variableNameIndex = 1; - while (FindDeclaration(variable.Name) != null) - variable.Name.Text = variableNameBase + "_" + variableNameIndex++; - - AddGlobalDeclaration(variable); - } - } - } - - // Fix variable references that were transform to local variable - // This is not ideal, as we should instead perform a pre-pass to detect these variables - // and patch them after the pre-pass - // The problem is that ConvertReferenceToSemantics is working only if a variable is modified - // first and then used, but if a variable is used, and then modified, ConvertReferenceToSemantics - // will not modify the previous 'local' variable. - // This code is a workaround. A refactoring of the whole process would be more adequate but requires - // more changes to the overall logic that we can't really afford now. - SearchVisitor.Run( - function, - node => - { - var varRefExpr = node as VariableReferenceExpression; - if (varRefExpr != null) - { - var variable = FindDeclaration(varRefExpr.Name) as Variable; - if (variable != null) - { - Variable newVariable; - inputAssignment.TryGetValue(variable, out newVariable); - - if (newVariable != null) - { - return new VariableReferenceExpression(newVariable); - } - } - } - return node; - }); - } - - - /// - /// Visits the specified cast expression. - /// - /// The cast expression. - /// A transformed cast expression - public override Node Visit(CastExpression castExpression) - { - base.Visit(castExpression); - - var targetType = castExpression.Target.TypeInference.TargetType; - - // If there is a cast from an integer 0 to a struct, than remove the cast for GLSL, as it is not supported - if (targetType is StructType && castExpression.From is LiteralExpression) - { - var literalExpression = (LiteralExpression)castExpression.From; - if (literalExpression.Value != null) - { - var toStringValue = literalExpression.Value.ToString().Trim(); - if (toStringValue == "0") - return null; - } - } - - // Remove cast for literal integer/float by generating a proper literal - if (targetType == ScalarType.Float && castExpression.From is LiteralExpression) - { - var literalExpression = (LiteralExpression)castExpression.From; - literalExpression.Value = Convert.ChangeType(literalExpression.Value, typeof(float)); - return literalExpression; - } - - var castByMethod = new MethodInvocationExpression(new TypeReferenceExpression(castExpression.Target), castExpression.From); - - targetType = castExpression.TypeInference.TargetType; - if (targetType != null) - castByMethod.TypeInference.TargetType = targetType; - - CheckCastMethod(castByMethod); - - return castByMethod; - } - - /// - /// Visits the specified statement. - /// - /// The statement. - /// A transformed statement - public override Node Visit(ExpressionStatement expressionStatement) - { - Statement newStatement = null; - - var methodInvocationExpression = expressionStatement.Expression as MethodInvocationExpression; - if (methodInvocationExpression != null) - { - var methodVar = methodInvocationExpression.Target as VariableReferenceExpression; - if (methodVar != null) - { - newStatement = VisitStatementAsFunctionInvocation(expressionStatement, methodInvocationExpression, methodVar); - } - else - { - var memberReferenceExpression = methodInvocationExpression.Target as MemberReferenceExpression; - if (memberReferenceExpression != null) - { - newStatement = VisitStatementAsMemberInvocation(expressionStatement, methodInvocationExpression, memberReferenceExpression); - } - } - } - else - { - var assignExpression = expressionStatement.Expression as AssignmentExpression; - if (assignExpression != null) - { - newStatement = VisitStatementAsAssignExpression(expressionStatement, assignExpression); - } - } - - return newStatement ?? base.Visit(expressionStatement); - } - - /// - /// Visits a statement that is a function invocation. - /// - /// The statement. - /// The function invocation expression. - /// The name of the function. - /// - protected Statement VisitStatementAsFunctionInvocation(ExpressionStatement statement, MethodInvocationExpression methodInvocationExpression, VariableReferenceExpression methodVar) - { - var methodName = methodVar.Name; - - switch (methodName) - { - case "clip": - if (methodInvocationExpression.Arguments.Count == 1) - { - Expression conditionExpression; - - methodInvocationHandled.TryAdd(methodInvocationExpression, true); - - base.Visit(statement); - - var clipArgType = methodInvocationExpression.Arguments[0].TypeInference.TargetType; - - bool isSingleValue = clipArgType is ScalarType; // || clipArgType.Generics == null); - if (isSingleValue) - conditionExpression = new BinaryExpression( - BinaryOperator.Less, ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[0]), new LiteralExpression(ScalarType.IsInteger(clipArgType) ? (object)0 : 0.0f)); - else - { - var castToZero = new MethodInvocationExpression(new TypeReferenceExpression(clipArgType), new LiteralExpression(0)); - var lessThan = new MethodInvocationExpression("lessThan", methodInvocationExpression.Arguments[0], castToZero); - var methodAll = new MethodInvocationExpression("all", lessThan); - conditionExpression = methodAll; - } - - return new IfStatement { Condition = conditionExpression, Then = new ExpressionStatement(new KeywordExpression("discard")) }; - } - - break; - case "sincos": - - if (methodInvocationExpression.Arguments.Count == 3) - { - methodInvocationHandled.TryAdd(methodInvocationExpression, true); - - base.Visit(statement); - - var sinAssign = - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, methodInvocationExpression.Arguments[1], new MethodInvocationExpression("sin", methodInvocationExpression.Arguments[0]))); - - var cosAssign = - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, methodInvocationExpression.Arguments[2], new MethodInvocationExpression("cos", methodInvocationExpression.Arguments[0]))); - - return new StatementList(sinAssign, cosAssign); - } - - break; - - case "GroupMemoryBarrierWithGroupSync": - // GroupMemoryBarrierWithGroupSync => groupMemoryBarrier(); barrier(); - return new StatementList( - new ExpressionStatement(new MethodInvocationExpression("groupMemoryBarrier")), - new ExpressionStatement(new MethodInvocationExpression("barrier"))); - } - - return null; - } - - /// - /// Visits a statement that is a member invocation. - /// - /// The statement. - /// The method invocation expression. - /// The member reference expression. - /// A new statement if handled, null otherwise - protected Statement VisitStatementAsMemberInvocation(Statement statement, MethodInvocationExpression methodInvocationExpression, MemberReferenceExpression memberReferenceExpression) - { - if (memberReferenceExpression.Member == "GetDimensions") - { - var textureRef = memberReferenceExpression.Target as VariableReferenceExpression; - var variableTexture = FindParameterOrGlobalVariableFromExpression(textureRef); - - if (variableTexture == null) - { - parserResult.Error("Unable to find target variable for expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - return null; - } - - var glslSampler = GetGLSampler(null, variableTexture, false); - - if (glslSampler == null) - { - parserResult.Error("Unable to find matching sampler for GetDimensions() for expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - return null; - } - - // Convert texture.GetDimensions(x, y) into - // { - // var texSize = textureSize(texture); - // x = texSize.x; - // y = texSize.y; - // } - var resultBlock = new BlockStatement(); - - var textureSizeCall = new MethodInvocationExpression(new VariableReferenceExpression("textureSize")); - textureSizeCall.Arguments.Add(glslSampler); - textureSizeCall.Arguments.Add(new LiteralExpression(0)); - - // TODO: Support all the versions of GetDimensions based on texture type and parameter count - // GetDimensions signature can be (uint mipLevel, uint width, uint height) or (uint width, uint height) - var startArgIndex = 0; - if (methodInvocationExpression.Arguments.Count > 2) - startArgIndex = 1; - - // TODO: Support for sampler size other than 2D - var textureSizeVariable = new Variable(VectorType.Int2, "tempTextureSize", textureSizeCall); - resultBlock.Statements.Add(new DeclarationStatement(textureSizeVariable)); - resultBlock.Statements.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - methodInvocationExpression.Arguments[startArgIndex], - new MemberReferenceExpression(new VariableReferenceExpression(textureSizeVariable.Name), "x")))); - resultBlock.Statements.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - methodInvocationExpression.Arguments[startArgIndex + 1], - new MemberReferenceExpression(new VariableReferenceExpression(textureSizeVariable.Name), "y")))); - - return resultBlock; - } - - return null; - } - - protected Statement VisitStatementAsAssignExpression(Statement statement, AssignmentExpression assignmentExpression) - { - var indexerExpression = assignmentExpression.Target as IndexerExpression; - if (NoSwapForBinaryMatrixOperation && indexerExpression != null) - { - // Collect all indices in the order of the declaration - var targetIterator = indexerExpression.Target; - var indices = new List { indexerExpression.Index }; - while (targetIterator is IndexerExpression) - { - indices.Add(((IndexerExpression)targetIterator).Index); - targetIterator = ((IndexerExpression)targetIterator).Target; - } - - // Check that index apply to an array variable - var variableReferenceExpression = targetIterator as VariableReferenceExpression; - if (variableReferenceExpression != null) - { - var variable = FindDeclaration(variableReferenceExpression.Name) as Variable; - - // If array is a multidimension array - var variableType = variable != null ? variable.Type.ResolveType() : null; - var matrixType = variableType as MatrixType; - - if (matrixType != null) - { - if (indices.Count == 2) - { - IndexerExpression nextExpression = null; - - // float4x3[0][1] -> mat4x3[1][0] - for (int i = 0; i < indices.Count; i++) - { - nextExpression = nextExpression == null ? new IndexerExpression(variableReferenceExpression, indices[i]) : new IndexerExpression(nextExpression, indices[i]); - } - - assignmentExpression.Target = nextExpression; - } - else - { - // matrixType.ColumnCount - var matrixElementType = matrixType.Type.ResolveType() as ScalarType; - var matrixRowType = new VectorType(matrixElementType, matrixType.ColumnCount); - - // Convert mat3x4[0] = ...; into - // { - // var local = ...; - // mat3x4[0][0] = local.x; - // mat3x4[0][1] = local.y; - // mat3x4[0][2] = local.z; - // mat3x4[0][3] = local.w; - // } - var resultBlock = new BlockStatement(); - - // need to call the visitor on the value here since Visit(AssignmentExpression ) won't be called afterwards (non null function's return). - assignmentExpression.Value = (Expression)VisitDynamic(assignmentExpression.Value); - - var localResult = new Variable(matrixRowType, "_localmat_", assignmentExpression.Value); - resultBlock.Statements.Add(new DeclarationStatement(localResult)); - - for (int i = 0; i < matrixType.ColumnCount; i++) - { - var targetExpression = new IndexerExpression(new IndexerExpression(indexerExpression.Target, new LiteralExpression(i)), indexerExpression.Index); - var valueExpression = new IndexerExpression(new VariableReferenceExpression("_localmat_"), new LiteralExpression(i)); - var assignRowCol = new AssignmentExpression(AssignmentOperator.Default, targetExpression, valueExpression); - resultBlock.Statements.Add(new ExpressionStatement(assignRowCol)); - } - return resultBlock; - } - } - else if ((variableType.Name.Text.StartsWith("RWTexture") || variableType.Name.Text.StartsWith("RWBuffer")) && variableType is ClassType classType) - { - // Manually visit all sub expressions. - indexerExpression.Target = (Expression)VisitDynamic(indexerExpression.Target); - indexerExpression.Index = (Expression)VisitDynamic(indexerExpression.Index); - assignmentExpression.Value = (Expression)VisitDynamic(assignmentExpression.Value); - - // Convert assignment to imageStore, and cast the indexer to an appropriate integer type. - TypeBase indexerType = variableType.Name.Text switch - { - "RWTexture" => ScalarType.Int, - "RWBuffer" => ScalarType.Int, - "RWTexture2D" => VectorType.Int2, - "RWTexture3D" => VectorType.Int3, - "RWTexture2DArray" => VectorType.Int3, - _ => throw new NotSupportedException($"imageStore not supported for {variable.Name.Text}") - }; - - var indexer = new MethodInvocationExpression(new TypeReferenceExpression(indexerType), indexerExpression.Index); - - // Assignemnt should be cast to gvec4 for all formats so we have to figure out target type. - var classTypeName = classType.GenericArguments[0].Name.Text; - VectorType assignemntTargetType; - if (classTypeName.StartsWith("float")) - assignemntTargetType = VectorType.Float4; - else if (classTypeName.StartsWith("int")) - assignemntTargetType = VectorType.Int4; - else if (classTypeName.StartsWith("uint")) - assignemntTargetType = VectorType.UInt4; - else - throw new NotSupportedException($"{classTypeName} not supported for imageStore"); - - var assignment = new MethodInvocationExpression(new TypeReferenceExpression(assignemntTargetType), assignmentExpression.Value); - - // Fill out any missing arguments for the constructor so that a gvec4 can successfully constructed. - var lastCharacter = assignmentExpression.TypeInference.TargetType.Name.Text.Last(); - var dimensions = char.IsNumber(lastCharacter) ? lastCharacter - 48 : 1; - for (var i = dimensions; i < 4; i++) - assignment.Arguments.Add(new LiteralExpression(new Literal(0))); - - return new ExpressionStatement(new MethodInvocationExpression("imageStore", indexerExpression.Target, indexer, assignment)); - } - } - } - - return null; - } - - - - /// - /// Visits the specified method invocation expression. - /// - /// The method invocation expression. - /// - /// A transformed method invocation expression. - /// - public override Node Visit(MethodInvocationExpression methodInvocationExpression) - { - base.Visit(methodInvocationExpression); - - // If method is already handled - if (methodInvocationHandled.ContainsKey(methodInvocationExpression)) - return methodInvocationExpression; - - MethodDeclaration methodDeclaration = null; - - // Transform various method calls to match OpenGL specs. - var methodVar = methodInvocationExpression.Target as VariableReferenceExpression; - if (methodVar != null) - { - var methodName = methodVar.Name; - methodDeclaration = methodVar.TypeInference.Declaration as MethodDeclaration; - - // When a method is calling a typedef, use the type of the type def as a TypeReference instead of a VariableReference - if (methodInvocationExpression.TypeInference.Declaration is Typedef) - { - methodInvocationExpression.Target = new TypeReferenceExpression(methodInvocationExpression.TypeInference.TargetType); - return methodInvocationExpression; - } - - if (methodName == "mul") - { - //// Swap all binary expressions in order for matrix multiplications to be compatible with matrix layout - var leftParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[NoSwapForBinaryMatrixOperation ? 0 : 1]); - var rightParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[NoSwapForBinaryMatrixOperation ? 1 : 0]); - return new ParenthesizedExpression(new BinaryExpression(BinaryOperator.Multiply, leftParameter, rightParameter)); - } - - if (methodName == "rcp") - { - var rightParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[0]); - return new ParenthesizedExpression(new BinaryExpression(BinaryOperator.Divide, new LiteralExpression(1.0f), rightParameter)); - } - - if (methodName == "mad") - { - var firstParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[0]); - var secondParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[1]); - var thirdParameter = ConvertToSafeExpressionForBinary(methodInvocationExpression.Arguments[2]); - - var multiply = new BinaryExpression(BinaryOperator.Multiply, firstParameter, secondParameter); - var add = new BinaryExpression(BinaryOperator.Plus, multiply, thirdParameter); - - return new ParenthesizedExpression(add); - } - - if (methodName == "lit") - { - // http://msdn.microsoft.com/en-us/library/bb509619%28v=vs.85%29.aspx - // ret lit(n_dot_l, n_dot_h, m) { - // ambient = 1. - // diffuse = ((n • l) < 0) ? 0 : n • l. - // specular = ((n • l) < 0) || ((n • h) < 0) ? 0 : ((n • h) ^ m). - // return float4((ambient, diffuse, specular, 1); - // } - var methodLit = new MethodInvocationExpression(new TypeReferenceExpression(VectorType.Float4)); - methodLit.Arguments.Add(new LiteralExpression(1.0f)); - - var diffuseArg = new ConditionalExpression( - new BinaryExpression(BinaryOperator.Less, methodInvocationExpression.Arguments[0], new LiteralExpression(0.0f)), - new LiteralExpression(0.0f), - methodInvocationExpression.Arguments[0]); - - methodLit.Arguments.Add(diffuseArg); - - var specularArg = - new ConditionalExpression( - new BinaryExpression( - BinaryOperator.LogicalOr, - new BinaryExpression(BinaryOperator.Less, methodInvocationExpression.Arguments[0], new LiteralExpression(0.0f)), - new BinaryExpression(BinaryOperator.Less, methodInvocationExpression.Arguments[1], new LiteralExpression(0.0f))), - new LiteralExpression(0.0f), - new MethodInvocationExpression("pow", methodInvocationExpression.Arguments[1], methodInvocationExpression.Arguments[2])); - - methodLit.Arguments.Add(specularArg); - methodLit.Arguments.Add(new LiteralExpression(1.0f)); - - //// Swap all binary expressions in order for matrix multiplications to be compatible with matrix layout - return methodLit; - } - - if (methodName == "isfinite") - { - methodVar.Name = "isinf"; - var result = new MethodInvocationExpression("not", methodInvocationExpression); - return result; - } - - if (methodName == "log10") - { - methodVar.Name = "log"; - var log10 = new MethodInvocationExpression("log", new LiteralExpression(10.0f)); - return new BinaryExpression(BinaryOperator.Divide, methodInvocationExpression, log10); - } - - if (methodName == "saturate") - { - methodVar.Name = "saturate"; - methodInvocationExpression.Arguments.Add(new LiteralExpression(0.0f)); - methodInvocationExpression.Arguments.Add(new LiteralExpression(1.0f)); - } - - // Transform all(x) into all(x != 0) because OpenGL expects only boolean - if (methodName == "all" || methodName == "any") - { - var argType = methodInvocationExpression.Arguments[0].TypeInference.TargetType; - if (argType == null || TypeBase.GetBaseType(argType) != ScalarType.Bool) - { - var castToZero = new MethodInvocationExpression(new TypeReferenceExpression(argType), new LiteralExpression(0)); - var notEqual = new MethodInvocationExpression("notEqual", methodInvocationExpression.Arguments[0], castToZero); - methodInvocationExpression.Arguments[0] = notEqual; - } - } - - if (string.Compare(methodName, "D3DCOLORtoUBYTE4", StringComparison.OrdinalIgnoreCase) == 0) - { - return new MethodInvocationExpression(new TypeReferenceExpression(VectorType.Int4), methodInvocationExpression.Arguments[0]) { TypeInference = { TargetType = VectorType.Int4 } }; - } - - string methodNameGl; - if (functionMapping.TryGetValue(methodName, out methodNameGl)) - methodVar.Name = methodNameGl; - } - - // Convert member expression - var memberReferenceExpression = methodInvocationExpression.Target as MemberReferenceExpression; - if (memberReferenceExpression != null) - { - var targetVariable = FindParameterOrGlobalVariableFromExpression(memberReferenceExpression.Target); - if (targetVariable == null) - { - parserResult.Error("Unable to find target variable for expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - return methodInvocationExpression; - } - var targetVariableType = targetVariable.Type.ResolveType(); - methodDeclaration = memberReferenceExpression.TypeInference.Declaration as MethodDeclaration; - - switch (memberReferenceExpression.Member) - { - // Geometry shader - case "RestartStrip": - methodInvocationExpression.Target = new VariableReferenceExpression("EndPrimitive"); - break; - - // Texture object - case "GetDimensions": - // We should not be here - parserResult.Error("GetDimensions should have been already preprocessed for expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - break; - case "Load": - case "Sample": - case "SampleBias": - case "SampleGrad": - case "SampleLevel": - case "SampleCmp": - case "SampleCmpLevelZero": - { - string methodName = "texture"; - - bool isLoad = memberReferenceExpression.Member == "Load"; - int baseParameterCount = isLoad ? 1 : 2; - - Variable sampler = null; - - // texture.Load() doesn't require a sampler - if (!isLoad) - { - sampler = FindParameterOrGlobalVariableFromExpression(methodInvocationExpression.Arguments[0]); - } - var glslSampler = GetGLSampler(sampler, targetVariable, true); - - if (TextureFunctionsCompatibilityProfile) - { - if (targetVariable.Type == TextureType.Texture1D) - methodName += "1D"; - else if (targetVariable.Type == TextureType.Texture2D) - methodName += "2D"; - else if (targetVariable.Type == TextureType.Texture3D) - methodName += "3D"; - else if (targetVariable.Type == TextureType.TextureCube) - methodName += "Cube"; - else - parserResult.Error("Unable to find texture profile in compatibility mode [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - } - - if (glslSampler == null) - { - parserResult.Error("Unable to find matching texture/sampler expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - return methodInvocationExpression; - } - - bool hasBias = memberReferenceExpression.Member == "SampleBias"; - if (hasBias) - baseParameterCount++; - - if (memberReferenceExpression.Member == "SampleGrad") - { - baseParameterCount += 2; - methodName += "Grad"; - } - - if (memberReferenceExpression.Member == "SampleLevel" || memberReferenceExpression.Member == "SampleCmpLevelZero") - { - baseParameterCount++; - methodName += "Lod"; - - if (memberReferenceExpression.Member == "SampleCmpLevelZero") - { - methodInvocationExpression.Arguments.Add(new LiteralExpression(0.0f)); - } - } - - if (isLoad) - { - methodName = "texelFetch"; - } - - if (memberReferenceExpression.Member == "SampleCmp" || memberReferenceExpression.Member == "SampleCmpLevelZero") - { - // Need to convert texture.SampleCmp(texcoord, compareValue) to texture(vec3(texcoord, compareValue)) - var texcoord = methodInvocationExpression.Arguments[1]; - methodInvocationExpression.Arguments[1] = new MethodInvocationExpression( - new TypeReferenceExpression(new VectorType(ScalarType.Float, TypeBase.GetDimensionSize(texcoord.TypeInference.TargetType, 1) + 1)), - methodInvocationExpression.Arguments[1], - methodInvocationExpression.Arguments[2] - ); - methodInvocationExpression.Arguments.RemoveAt(2); - } - - if (methodInvocationExpression.Arguments.Count == baseParameterCount + 1) - { - methodName += "Offset"; - } - else if (methodInvocationExpression.Arguments.Count != baseParameterCount) - { - parserResult.Error("Unable to match arguments count with expected parameters for expression [{0}]", methodInvocationExpression.Span, methodInvocationExpression); - return methodInvocationExpression; - } - - // texture.Sample has a sampler parameter but texture.Load doesn't, so replace/add accordingly - if (isLoad) - methodInvocationExpression.Arguments.Insert(0, glslSampler); - else - methodInvocationExpression.Arguments[0] = glslSampler; - - // SampleBias and textureOffset conversion requires a parameter swap between bias and offset. - if (hasBias && methodName == "textureOffset") - { - var temp = methodInvocationExpression.Arguments[2]; - methodInvocationExpression.Arguments[3] = methodInvocationExpression.Arguments[2]; - methodInvocationExpression.Arguments[2] = temp; - } - - // For OpenGL ES, texelFetch on Buffer might not be available, so we use a #define to easily convert it to a Texture instead - if (shaderPlatform == GlslShaderPlatform.OpenGLES && shaderVersion < 320 && isLoad && targetVariableType.Name.Text == "Buffer" && methodName == "texelFetch") - methodName = "texelFetchBuffer"; - - methodInvocationExpression.Target = new VariableReferenceExpression(methodName); - - if (isLoad) - { - // Since Texture.Load works with integer coordinates, need to convert texture.Load(coords, [offset]) to: - // - textureLod[Offset](texture_sampler, coords.xy / textureSize(texture_sampler), coords.z, [offset]) on OpenGL ES 2 - // - texelFetch[Offset](texture_sampler, coords.xy, coords.z, [offset]) on OpenGL and ES 3 - - string dimP = "??"; - string mipLevel = "?"; - - switch (targetVariableType.Name.Text) - { - case "Buffer": - dimP = "x"; - mipLevel = string.Empty; - break; - case "Texture1D": - dimP = "x"; - mipLevel = "y"; - break; - case "Texture2D": - case "Texture2DMS": - case "Texture1DArray": - dimP = "xy"; - mipLevel = "z"; - break; - case "Texture2DArray": - case "Texture2DArrayDMS": - case "Texture3D": - dimP = "xyz"; - mipLevel = "w"; - break; - default: - parserResult.Error("Unable to process texture coordinates for type [{0}] when processing expression [{1}]", methodInvocationExpression.Span, targetVariableType.Name.Text, methodInvocationExpression); - break; - } - - // Note: older GL versions don't allow scalar swizzle, so let's avoid them - var coordExpr = dimP == "x" ? NewCast(new VectorType(ScalarType.Int, dimP.Length), methodInvocationExpression.Arguments[1]) : new MemberReferenceExpression(new ParenthesizedExpression(methodInvocationExpression.Arguments[1]), dimP); - - if (mipLevel.Length > 0) - methodInvocationExpression.Arguments.Insert(2, NewCast(ScalarType.Int, new MemberReferenceExpression(new ParenthesizedExpression(methodInvocationExpression.Arguments[1].DeepClone()), mipLevel))); - - methodInvocationExpression.Arguments[1] = coordExpr; - - // D3D returns an object of type T, but OpenGL returns an object of type gvec4 - var expectedResultType = methodInvocationExpression.TypeInference.TargetType; - methodInvocationExpression.TypeInference.TargetType = new VectorType((ScalarType)TypeBase.GetBaseType(expectedResultType), 4); - methodInvocationExpression = (MethodInvocationExpression)NewCast(expectedResultType, methodInvocationExpression); - } - - // TODO: Check how many components are required - // methodInvocationExpression.Arguments[1] = new MemberReferenceExpression(new ParenthesizedExpression(methodInvocationExpression.Arguments[1]), "xy"); - } - - // Set methodDeclaration to null, so that "Add default parameters" doesn't do anything little bit further in this method - methodDeclaration = null; - - break; - } - } - - // Handle type reference expression - var typeReferenceExpression = methodInvocationExpression.Target as TypeReferenceExpression; - if (typeReferenceExpression != null) - { - // Convert matrix type initializers - var matrixType = typeReferenceExpression.Type.ResolveType() as MatrixType; - if (matrixType != null) - { - methodInvocationExpression.Arguments = this.ConvertMatrixInitializer(matrixType, methodInvocationExpression.Arguments); - } - } - - // Add default parameters - if (methodDeclaration != null) - { - for (int i = methodInvocationExpression.Arguments.Count; i < methodDeclaration.Parameters.Count; i++) - methodInvocationExpression.Arguments.Add(methodDeclaration.Parameters[i].InitialValue); - } - - CheckCastMethod(methodInvocationExpression); - - // For GeometryShader remove stream type method invocation - RemoveStreamTypeFromMethodInvocation(methodInvocationExpression); - - return methodInvocationExpression; - } - - private void RemoveStreamTypeFromMethodInvocation(MethodInvocationExpression expression) - { - // Remove parameters that are StreamType - for (int i = expression.Arguments.Count - 1; i >= 0; i--) - { - var argument = expression.Arguments[i]; - if (ClassType.IsStreamOutputType(argument.TypeInference.TargetType)) - { - expression.Arguments.RemoveAt(i); - } - } - } - - private void RemoveStreamTypeFromMethodDefinition(MethodDeclaration declaration) - { - // Remove parameters that are StreamType - for (int i = declaration.Parameters.Count - 1; i >= 0; i--) - { - var argument = declaration.Parameters[i]; - if (ClassType.IsStreamOutputType(argument.Type.TypeInference.TargetType)) - { - declaration.Parameters.RemoveAt(i); - } - } - } - - /// - /// Visits the specified conditional expression. - /// - /// The conditional expression. - public override Node Visit(ConditionalExpression conditionalExpression) - { - base.Visit(conditionalExpression); - - var conditionType = conditionalExpression.Condition.TypeInference.TargetType; - - // Convert float4(xxx) ? left : right to mix(left, right, float4(xxx) == 0); - if (conditionType is VectorType) - { - var methodInvocation = new MethodInvocationExpression("mix", conditionalExpression.Left, conditionalExpression.Right, - new MethodInvocationExpression("equal", conditionalExpression.Condition, new MethodInvocationExpression(new TypeReferenceExpression(conditionType), new LiteralExpression(0)))); - return methodInvocation; - } - else - { - conditionalExpression.Condition = ConvertCondition(conditionalExpression.Condition); - } - - return conditionalExpression; - } - - /// - /// Visits the specified constant buffer. - /// - /// The constant buffer. - public override Node Visit(ConstantBuffer constantBuffer) - { - base.Visit(constantBuffer); - - // Remove initializers from constant buffers - foreach (var variable in constantBuffer.Members.OfType()) - { - if (variable.InitialValue != null) - { - parserResult.Warning("Initializer in uniform block are not supported in glsl [{0}]", variable.Span, variable); - variable.InitialValue = null; - } - } - - return constantBuffer; - } - - /// - /// Visits the specified var ref expr. - /// - /// The var ref expr. - /// A transformed expression. - public override Node Visit(VariableReferenceExpression varRefExpr) - { - base.Visit(varRefExpr); - - // If this is a global variable used as a temporary, don't perform any transform on it - if (globalUniformVisitor.IsVariableAsGlobalTemporary(varRefExpr)) - { - return varRefExpr; - } - - // Use ConvertExpression on variable. - var variable = FindDeclaration(varRefExpr.Name) as Variable; - if (variable != null) - { - var result = this.ConvertReferenceToSemantics(varRefExpr, variable.Semantic(), variable.Type.ResolveType(), variable.Name, variable.Span); - if (result != null) - return result; - } - - return varRefExpr; - } - - /// - /// Visits the specified if statement. - /// - /// If statement. - public override Node Visit(IfStatement ifStatement) - { - base.Visit(ifStatement); - ifStatement.Condition = ConvertCondition(ifStatement.Condition); - - return ifStatement; - } - - /// - /// Visit the for statement and unroll it if necessary - /// - /// - /// - public override Node Visit(ForStatement forStatement) - { - base.Visit(forStatement); - - // unroll foreach if necessary - if (UnrollForLoops && forStatement.Attributes.OfType().Any(x => x.Name.Text == "unroll")) - { - var breakFlag = new Variable(ScalarType.Bool, "isBreak" + breakIndex, new LiteralExpression(false)); - ++breakIndex; - var breakVisitor = new BreakContinueVisitor(); - var hasBreak = breakVisitor.Run(forStatement, breakFlag, "break", parserResult); - - var continueFlag = new Variable(ScalarType.Bool, "isContinue" + breakIndex, new LiteralExpression(false)); - ++breakIndex; - var continueVisitor = new BreakContinueVisitor(); - var hasContinue = continueVisitor.Run(forStatement, continueFlag, "continue", parserResult); - - int startValue; - var varName = GetStartForStatement(forStatement, out startValue); - - if (varName != null) - { - var iterCount = GetIterCountForStatement(forStatement, varName, startValue); - - if (iterCount > 0) - { - var statements = new BlockStatement(new StatementList()); - statements.Statements.Add(forStatement.Start); - if (hasBreak) - statements.Statements.Add(new DeclarationStatement(breakFlag)); - if (hasContinue) - statements.Statements.Add(new DeclarationStatement(continueFlag)); - - var lastStatement = statements; - - for (int i = 0; i < iterCount; ++i) - { - var clonedBody = forStatement.Body.DeepClone(); - var blockStatement = clonedBody as BlockStatement ?? new BlockStatement(new StatementList(clonedBody)); - blockStatement.Statements.Add(new ExpressionStatement(forStatement.Next)); - - if (hasContinue) // reset the flag - blockStatement.Statements.Add(new ExpressionStatement(new AssignmentExpression(AssignmentOperator.Default, new VariableReferenceExpression(continueFlag), new LiteralExpression(false)))); - - if (hasBreak) - { - var ifStatement = new IfStatement(); - ifStatement.Condition = new UnaryExpression(UnaryOperator.LogicalNot, new VariableReferenceExpression(breakFlag)); - ifStatement.Then = blockStatement; - lastStatement.Statements.Add(ifStatement); - } - else - { - lastStatement.Statements.Add(blockStatement); - } - lastStatement = blockStatement; - } - return statements; - } - if (iterCount == 0) - { - return new EmptyStatement(); - } - } - parserResult.Error("Unable to unroll for statement [{0}]", forStatement.Span, forStatement); - } - - return forStatement; - } - - /// - /// Get the Variable used - /// - /// the for statement - /// the start value of the loop, to fill - /// the variable - private static string GetStartForStatement(ForStatement forStatement, out int startValue) - { - var startStatement = forStatement.Start as DeclarationStatement; - var startStatementAssign = forStatement.Start as ExpressionStatement; - startValue = 0; - - if (startStatement != null) - { - var variable = startStatement.Content as Variable; - if (variable != null) - { - var evaluatorStart = new ExpressionEvaluator(); - var resultStart = evaluatorStart.Evaluate(variable.InitialValue); - if (resultStart.HasErrors) - return null; - startValue = (int)((double)resultStart.Value); - - return variable.Name.Text; - } - } - else if (startStatementAssign != null) - { - var assign = startStatementAssign.Expression as AssignmentExpression; - if (assign != null && assign.Operator == AssignmentOperator.Default) - { - var vre = assign.Target as VariableReferenceExpression; - if (vre != null) - { - var evaluatorStart = new ExpressionEvaluator(); - var resultStart = evaluatorStart.Evaluate(assign.Value); - if (resultStart.HasErrors) - return null; - startValue = (int)((double)resultStart.Value); - - return vre.Name.Text; - } - } - } - - return null; - } - - /// - /// Get the number of loops - /// - /// the for statement - /// the name of the iterator variable - /// the start value of the iterator - /// the number of loops - private static int GetIterCountForStatement(ForStatement forStatement, string variableName, int startValue) - { - var condition = forStatement.Condition as BinaryExpression; - if (condition == null) - return -1; - - var evaluatorStop = new ExpressionEvaluator(); - var resultStop = evaluatorStop.Evaluate(condition.Right); - if (resultStop.HasErrors) - return -1; - - var stopValue = (int)((double)resultStop.Value); - var step = 1; - - var stepExpr = forStatement.Next as UnaryExpression; - if (stepExpr == null) - { - var stepAssign = forStatement.Next as AssignmentExpression; - if (stepAssign != null) - { - if (stepAssign.Operator == AssignmentOperator.Default) - { - var assignedVar = stepAssign.Target as VariableReferenceExpression; - var valueAssigned = stepAssign.Value as BinaryExpression; - if (assignedVar == null || valueAssigned == null) - return -1; - - var left = valueAssigned.Left as VariableReferenceExpression; - var right = valueAssigned.Right as VariableReferenceExpression; - - if (left != null && left.Name.Text == variableName && valueAssigned.Right is LiteralExpression) - { - step = (int)(valueAssigned.Right as LiteralExpression).Value; - } - else if (right != null && right.Name.Text == variableName && valueAssigned.Left is LiteralExpression) - { - step = (int)(valueAssigned.Left as LiteralExpression).Value; - } - else - return -1; - } - else if (stepAssign.Operator == AssignmentOperator.Addition || stepAssign.Operator == AssignmentOperator.Subtraction) - { - var assignedVar = stepAssign.Target as VariableReferenceExpression; - if (assignedVar == null || assignedVar.Name.Text != variableName) - return -1; - - var evaluatorValueAssigned = new ExpressionEvaluator(); - var resultValueAssigned = evaluatorValueAssigned.Evaluate(stepAssign.Value); - if (resultValueAssigned.HasErrors) - return -1; - - step = (int)((double)resultValueAssigned.Value); - if (stepAssign.Operator == AssignmentOperator.Subtraction) - step = -step; - } - } - else - return -1; - } - else - { - switch (stepExpr.Operator) - { - case UnaryOperator.PostDecrement: - case UnaryOperator.PreDecrement: - step = -1; - break; - case UnaryOperator.PostIncrement: - case UnaryOperator.PreIncrement: - step = 1; - break; - } - } - - switch (condition.Operator) - { - case BinaryOperator.Less: - return (stopValue - startValue - 1) / step + 1; - case BinaryOperator.Greater: - return (stopValue - startValue - 1) / step + 1; - case BinaryOperator.LessEqual: - return (stopValue - startValue) / step + 1; - case BinaryOperator.GreaterEqual: - return (stopValue - startValue) / step + 1; - case BinaryOperator.Equality: - { - if (startValue == stopValue) - return 1; - else - return 0; - } - default: - return -1; - } - } - - /// - /// Visits the specified expression. - /// - /// The expression. - /// A transformed expression - public override Node Visit(MemberReferenceExpression expression) - { - base.Visit(expression); - - // A matrix contains values organized in rows and columns, which can be accessed using the structure operator "." followed by one of two naming sets: - // The zero-based row-column position: - // _m00, _m01, _m02, _m03 - // _m10, _m11, _m12, _m13 - // _m20, _m21, _m22, _m23 - // _m30, _m31, _m32, _m33 - // The one-based row-column position: - // _11, _12, _13, _14 - // _21, _22, _23, _24 - // _31, _32, _33, _34 - // _41, _42, _43, _44 - var matrixType = expression.Target.TypeInference.TargetType as MatrixType; - if (matrixType != null) - { - var swizzles = HlslSemanticAnalysis.MatrixSwizzleDecode(expression); - - // When NoSwapForBinaryMatrixOperation, we need to transpose accessor - if (NoSwapForBinaryMatrixOperation) - { - for (int i = 0; i < swizzles.Count; ++i) - { - swizzles[i] = new MatrixType.Indexer(swizzles[i].Column, swizzles[i].Row); - } - } - - if (swizzles.Count == 1) - return new IndexerExpression(new IndexerExpression(expression.Target, new LiteralExpression(swizzles[0].Row)), new LiteralExpression(swizzles[0].Column)); - - if (swizzles.Count > 1 && swizzles.Count <= 4) - { - var swizzleVectorInvoke = new MethodInvocationExpression(new TypeReferenceExpression(expression.TypeInference.TargetType)); - - foreach (var swizzle in swizzles) - swizzleVectorInvoke.Arguments.Add(new IndexerExpression(new IndexerExpression(expression.Target, new LiteralExpression(swizzle.Row)), new LiteralExpression(swizzle.Column))); - return swizzleVectorInvoke; - } - } - - // Scalars can only be swizzled in OpenGL 4.2. Wrap in vector type. - var scalarType = expression.Target.TypeInference.TargetType as ScalarType; - if (scalarType != null && expression.Member.Text.All(x => x == 'x')) - { - var targetAsVector = new MethodInvocationExpression(new TypeReferenceExpression(new VectorType(scalarType, expression.Member.Text.Length))); - targetAsVector.Arguments.Add(expression.Target); - - return targetAsVector; - } - - return expression; - } - - /// - /// Visits the specified array creation expression. - /// - /// The array creation expression. - /// A transformed expression - public override Node Visit(ArrayInitializerExpression arrayCreationExpression) - { - var variable = ParentNode as Variable; - - var result = (Expression)base.Visit(arrayCreationExpression); - - // If there is a parent variable and no subscript, It is probably a cast to an implicit array type (float2,float3,float4...etc.) - if (variable != null) - { - var variableType = variable.Type.ResolveType(); - - var arrayType = variableType as ArrayType; - if (arrayType != null) - { - return this.ConvertArrayInitializer(arrayType, arrayCreationExpression); - } - else - { - // Transform array creation to an explicit cast - // HLSL => float4 toto = {1,2,3,4}; - // GLSL => vec4 toto = vec4(1,2,3,4); - var items = new List(); - FlattenArrayCreationExpression(arrayCreationExpression, items); - var castToType = new MethodInvocationExpression(new TypeReferenceExpression(variable.Type)); - - // If matrix type, then use common function to convert the initializer - var matrixType = variableType as MatrixType; - if (matrixType != null) - { - items = this.ConvertMatrixInitializer(matrixType, items); - } - - foreach (var expression in items) - castToType.Arguments.Add(expression); - - result = castToType; - } - } - - return result; - } - - /// - /// Visits the specified assign expression. - /// - /// The assign expression. - /// A transformed expression - public override Node Visit(AssignmentExpression assignExpression) - { - // Put a special flag while visiting assignment target for tracking assignment to input varying (not allowed in OpenGL) - // TODO: use stack of assignmentTarget instead, as it would not work with nested assignement - isAssignmentTarget = true; - assignExpression.Target = (Expression)VisitDynamic(assignExpression.Target); - isAssignmentTarget = false; - assignExpression.Value = (Expression)VisitDynamic(assignExpression.Value); - - // If right expression is null, we can assume that it was removed on the right side - // So we can safely remove the whole expression - if (assignExpression.Value == null) - return null; - - return assignExpression; - } - - /// - /// Visits the specified technique. - /// - /// The technique. - /// The technique - public override Node Visit(Technique technique) - { - // Skip all techniques while parsing - return technique; - } - - /// - /// Visits the specified binary expression. - /// - /// The binary expression. - /// A transformed binary expression. - public override Node Visit(BinaryExpression binaryExpression) - { - base.Visit(binaryExpression); - - // ----------------------------------------------------- - // Handle binary expression with gl_FrontFacing variable - // ----------------------------------------------------- - bool isLeftFrontFacing = string.Compare(VariableReferenceExpression.GetVariableName(binaryExpression.Left), gl_FrontFacing, StringComparison.OrdinalIgnoreCase) == 0; - bool isRightFrontFacing = string.Compare(VariableReferenceExpression.GetVariableName(binaryExpression.Right), gl_FrontFacing, StringComparison.OrdinalIgnoreCase) == 0; - if (isLeftFrontFacing || isRightFrontFacing) - { - bool isLessOperator = binaryExpression.Operator == BinaryOperator.Less || binaryExpression.Operator == BinaryOperator.LessEqual; - bool isGreaterOperator = binaryExpression.Operator == BinaryOperator.Greater || binaryExpression.Operator == BinaryOperator.GreaterEqual; - - // If the operator is supported, then return gl_FrontFacing or !glFrontFacing - var glFrontFacingVar = isLeftFrontFacing ? binaryExpression.Left : binaryExpression.Right; - glFrontFacingVar.TypeInference.TargetType = ScalarType.Bool; - if (isLessOperator || isGreaterOperator) - { - if ((isLessOperator && isLeftFrontFacing) || (isRightFrontFacing && isGreaterOperator)) - return new UnaryExpression(UnaryOperator.LogicalNot, glFrontFacingVar) { TypeInference = { TargetType = ScalarType.Bool } }; - - return glFrontFacingVar; - } - - // Else convert the glFrontFacing to a -1/1 variable - var newGlFrontFacing = new ParenthesizedExpression(new ConditionalExpression(glFrontFacingVar, new LiteralExpression(1), new LiteralExpression(-1))); - - if (isLeftFrontFacing) - binaryExpression.Left = newGlFrontFacing; - else - binaryExpression.Right = newGlFrontFacing; - } - - // ----------------------------------------------------- - // Handle conversion between types - // ----------------------------------------------------- - var leftType = binaryExpression.Left.TypeInference.TargetType; - var rightType = binaryExpression.Right.TypeInference.TargetType; - - Expression outputExpression = binaryExpression; - - if (leftType != null && rightType != null) - { - bool isOperationOnVectors = leftType is VectorType && rightType is VectorType && ((VectorType)leftType).Dimension > 1 && ((VectorType)rightType).Dimension > 1; - - if (binaryExpression.Operator == BinaryOperator.Multiply) - { - if (leftType is MatrixType && rightType is MatrixType) - { - var matrixMul = new MethodInvocationExpression(new VariableReferenceExpression(new Identifier("matrixCompMult"))); - matrixMul.Arguments.Add(binaryExpression.Left); - matrixMul.Arguments.Add(binaryExpression.Right); - - outputExpression = matrixMul; - } - } - else if (binaryExpression.Operator == BinaryOperator.Modulo) - { - if (!ScalarType.IsInteger(leftType) || !ScalarType.IsInteger(rightType)) - { - var matrixMul = new MethodInvocationExpression(new VariableReferenceExpression(new Identifier("mod"))); - matrixMul.Arguments.Add(binaryExpression.Left); - matrixMul.Arguments.Add(binaryExpression.Right); - - outputExpression = matrixMul; - } - } - else if (binaryExpression.Operator == BinaryOperator.Less || binaryExpression.Operator == BinaryOperator.Greater || binaryExpression.Operator == BinaryOperator.LessEqual - || binaryExpression.Operator == BinaryOperator.GreaterEqual || binaryExpression.Operator == BinaryOperator.Equality || binaryExpression.Operator == BinaryOperator.Inequality) - { - if (isOperationOnVectors) - { - string comparisonName; - switch (binaryExpression.Operator) - { - case BinaryOperator.Less: - comparisonName = "lessThan"; - break; - case BinaryOperator.LessEqual: - comparisonName = "lessThanEqual"; - break; - case BinaryOperator.Greater: - comparisonName = "greaterThan"; - break; - case BinaryOperator.GreaterEqual: - comparisonName = "greaterThanEqual"; - break; - case BinaryOperator.Equality: - comparisonName = "equal"; - break; - case BinaryOperator.Inequality: - comparisonName = "notEqual"; - break; - default: - parserResult.Error("Unsupported binary expression on vectors [{0}]", binaryExpression.Span, binaryExpression); - return binaryExpression; - } - - var comparisonExpr = new MethodInvocationExpression(new VariableReferenceExpression(new Identifier(comparisonName))); - comparisonExpr.Arguments.Add(binaryExpression.Left); - comparisonExpr.Arguments.Add(binaryExpression.Right); - - int dimension = ((VectorType)binaryExpression.TypeInference.TargetType).Dimension; - comparisonExpr.TypeInference.TargetType = new VectorType(ScalarType.Bool, dimension); - outputExpression = comparisonExpr; - } - } - else if (binaryExpression.Operator == BinaryOperator.LogicalOr || binaryExpression.Operator == BinaryOperator.LogicalAnd) - { - binaryExpression.Left = ConvertCondition(binaryExpression.Left); - binaryExpression.Right = ConvertCondition(binaryExpression.Right); - binaryExpression.TypeInference.TargetType = ScalarType.Bool; - - if (isOperationOnVectors) - { - parserResult.Error( - "Boolean operation && || on expression [{0}] cannot be converted safely to GLSL, as GLSL doesn't support boolean operators function on a per-component basis. Code is generated but invalid", - binaryExpression.Span, - binaryExpression); - } - } - } - - return outputExpression; - } - - /// - /// Visits the specified return statement. - /// - /// The return statement. - /// A transformed return statement. - public override Node Visit(ReturnStatement returnStatement) - { - base.Visit(returnStatement); - - // Only transform return in entry function - if (!IsInEntryPoint) - return returnStatement; - - // This should only process return statements with ConvertReturn which are not detected at the block level. - // As an example, a return statement which is not enclosed in a block, such as "if (X) return Y;", should be converted to if (X) { out_x = x; out_y = y; ... } - return ConvertReturn(returnStatement.Value, true, returnStatement.Span); - } - - /// - /// Visits the specified statement list. - /// - /// The statement list. - /// - /// A transformed statement list. - /// - public override Node Visit(StatementList statementList) - { - // Try to transform return statement with ConvertReturn at the block level first. - // As an example, { stmt1; return Y; } gets converted to { stmt1; out_x = x; out_y = y; ... } - var newStatementList = new StatementList(); - for (int i = 0; i < statementList.Statements.Count; i++) - { - var stmt = statementList.Statements[i]; - bool converted = false; - - if (stmt is ReturnStatement) - { - // Only transform return in entry function - if (IsInEntryPoint) - { - var returnValue = ((ReturnStatement)stmt).Value; - - // Don't emit return for last return of a function - bool emitReturn = !(ParentNode is MethodDefinition && (i + 1) == statementList.Statements.Count); - - // Return statements could not have a value - if (returnValue != null) - { - var subStatements = ConvertReturn(((ReturnStatement)stmt).Value, emitReturn, stmt.Span); - if (subStatements is StatementList) - newStatementList.AddRange((StatementList)subStatements); - else - newStatementList.Add(subStatements); - - converted = true; - } - else if (!emitReturn) - converted = true; - } - } - else if (stmt is DeclarationStatement) - { - var variable = ((DeclarationStatement)stmt).Content as Variable; - - // Remove register/semantics from local variable declaration - if (variable != null) - variable.Qualifiers.Values.RemoveAll(qualifierArg => qualifierArg is RegisterLocation || qualifierArg is Semantic); - } - else if (stmt is ExpressionStatement) - { - var exprStmt = (ExpressionStatement)stmt; - - // Handle tuple cast. Only support default scalars - if (exprStmt.Expression is AssignmentExpression) - { - var assignExpression = exprStmt.Expression as AssignmentExpression; - if (assignExpression.Target is MethodInvocationExpression && assignExpression.Operator == AssignmentOperator.Default) - { - var tupleExpression = (MethodInvocationExpression)assignExpression.Target; - var typeReferenceExpression = tupleExpression.Target as TypeReferenceExpression; - var tupleType = typeReferenceExpression != null ? typeReferenceExpression.Type.ResolveType() : null; - - if (typeReferenceExpression != null && tupleType != null && !(tupleType is MatrixType)) - { - var tupleBlock = new BlockStatement(); - const string TemporaryTupleName = "_tuple_temp_"; - var variableTuple = new Variable(VectorType.Float4, TemporaryTupleName, assignExpression.Target); - tupleBlock.Statements.Add(new DeclarationStatement(variableTuple)); - - int startMember = 0; - - const string SwizzleMembers = "xyzw"; - - bool hasError = false; - - foreach (var expression in tupleExpression.Arguments) - { - var argumentType = expression.TypeInference.TargetType; - if (argumentType != null) - { - var argumentDimension = (argumentType is VectorType) ? ((VectorType)argumentType).Dimension : 1; - - tupleBlock.Statements.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - expression, - new MemberReferenceExpression(new VariableReferenceExpression(TemporaryTupleName), SwizzleMembers.Substring(startMember, argumentDimension))))); - startMember += argumentDimension; - } - else - hasError = true; - } - - if (!hasError) - { - converted = true; - newStatementList.Add(tupleBlock); - } - } - } - } - else - { - var methodInvocationExpr = exprStmt.Expression as MethodInvocationExpression; - var method = methodInvocationExpr != null ? methodInvocationExpr.Target as MemberReferenceExpression : null; - - // Handle geometry shader vertex emit - if (method != null && method.Target is VariableReferenceExpression) - { - var targetVariable = (VariableReferenceExpression)method.Target; - var targetType = targetVariable.TypeInference.TargetType; - if (ClassType.IsStreamOutputType(targetType)) - { - if (method.Member == "Append") - { - //var globalVariable = shader.Declarations.Find(node => node is Variable && ((Variable) node).Name == targetVariable.Name); - //if (globalVariable == null) - //{ - // var streamType = ((ClassType) targetType).GenericArguments[0]; - // var streamOutVariable = new Variable(new ArrayType(streamType), targetVariable.Name); - // streamOutVariable.Qualifiers |= ParameterQualifier.Out; - // AddGlobalDeclaration(streamOutVariable); - //} - - if (targetType.Name == "TriangleStream") - geometryLayoutOutput = "triangle_strip"; - else if (targetType.Name == "LineStream") - geometryLayoutOutput = "line_strip"; - else if (targetType.Name == "PointStream") - geometryLayoutOutput = "points"; - else - { - parserResult.Error("Unknown OutputStream type [{0}] (should be TriangleStream, LineStream or PointStream", exprStmt.Span, targetType.Name); - return newStatementList; - } - - var returnStatement = ConvertReturn(methodInvocationExpr.Arguments[0], false, null); - if (returnStatement is StatementList) - newStatementList.AddRange((StatementList)returnStatement); - else - newStatementList.Add(returnStatement); - newStatementList.Add(new ExpressionStatement(new MethodInvocationExpression(new VariableReferenceExpression("EmitVertex")))); - converted = true; - } - else if (method.Member == "RestartStrip") - { - newStatementList.Add(new ExpressionStatement(new MethodInvocationExpression(new VariableReferenceExpression("EndPrimitive")))); - converted = true; - } - } - } - } - } - - if (!converted) - newStatementList.Add(stmt); - } - - base.Visit(newStatementList); - - return newStatementList; - } - - /// - /// Visits the specified indexer expression. - /// - /// The indexer expression. - /// A transformed indexer expression - public override Node Visit(IndexerExpression indexerExpression) - { - // Collect all indices in the order of the declaration - var targetIterator = indexerExpression.Target; - var indices = new List { indexerExpression.Index }; - while (targetIterator is IndexerExpression) - { - indices.Add(((IndexerExpression)targetIterator).Index); - targetIterator = ((IndexerExpression)targetIterator).Target; - } - - Variable variable = null; - Identifier varName = null; - // Check that index apply to an array variable - if (targetIterator is VariableReferenceExpression) - { - varName = ((VariableReferenceExpression)targetIterator).Name; - variable = FindDeclaration(varName) as Variable; - } - else if (targetIterator is MemberReferenceExpression) // Also check arrays inside structures - { - varName = ((MemberReferenceExpression)targetIterator).Member; - - var target = ((MemberReferenceExpression)targetIterator).Target; - var targetType = target.TypeInference.TargetType as StructType; - - if (targetType != null) - variable = targetType.Fields.FirstOrDefault(x => x.Name.Text == varName.Text); - } - - MatrixType matrixType = null; - if (varName != null) - { - // If array is a multidimension array - var variableType = variable != null ? variable.Type.ResolveType() : null; - var arrayType = variableType as ArrayType; - matrixType = variableType as MatrixType; - var classType = variableType as ClassType; - - if (arrayType != null && arrayType.Dimensions.Count == indices.Count) - { - // Transform multi-dimensionnal array to single dimension - // float myarray[s1][s2][s3]...[sn] = {{.{..{...}}}; - // float value = myarray[i1][i2][i3]...[in] => float value = myarray[(i1)*(s2)*(s3)*...*(sn) + (i2)*(s3)*...*(sn) + (i#)*(s#+1)*(s#+2)*...*(sn)]; - // The indice list is in reversed order => <[sn]...[s3][s2][s1]> - Expression finalIndex = null; - for (int i = 0; i < indices.Count; i++) - { - Expression indexExpression = indices[i]; - for (int j = indices.Count - i; j < indices.Count; ++j) - { - var nextExpression = arrayType.Dimensions[j]; - indexExpression = new BinaryExpression(BinaryOperator.Multiply, indexExpression, nextExpression); - } - - finalIndex = finalIndex == null ? indexExpression : new BinaryExpression(BinaryOperator.Plus, finalIndex, indexExpression); - } - - // Return a 1d indexer - indexerExpression = new IndexerExpression(targetIterator, finalIndex); - } - else if (classType != null && classType.Name.Text.StartsWith("RWTexture")) - { - // Convert assignment to imageLoad, and cast the indexer to an appropriate integer type. - TypeBase indexerType = variableType.Name.Text switch - { - "RWTexture" => ScalarType.Int, - "RWBuffer" => ScalarType.Int, - "RWTexture2D" => VectorType.Int2, - "RWTexture3D" => VectorType.Int3, - "RWTexture2DArray" => VectorType.Int3, - _ => throw new NotSupportedException($"imageLoad not supported for {variable.Name.Text}") - }; - - indexerExpression.Target = (Expression)VisitDynamic(indexerExpression.Target); - indexerExpression.Index = (Expression)VisitDynamic(indexerExpression.Index); - - return new MethodInvocationExpression("imageLoad", indexerExpression.Target, new MethodInvocationExpression(new TypeReferenceExpression(indexerType), indexerExpression.Index)); - } - else if (classType != null && (classType.Name.Text.StartsWith("StructuredBuffer") || classType.Name.Text.StartsWith("RWStructuredBuffer"))) - { - // Convert to TargetName.Buffer[index] - indexerExpression.Target = (Expression)VisitDynamic(indexerExpression.Target); - indexerExpression.Index = (Expression)VisitDynamic(indexerExpression.Index); - - indexerExpression.Target = new MemberReferenceExpression(indexerExpression.Target, "Buffer"); - - return indexerExpression; - } - } - - base.Visit(indexerExpression); - - // When NoSwapForBinaryMatrixOperation, we need to transpose accessor - // HLSL: float4x3[0] -> first row -> float4(...) - // GLSL: mat4x3[0] -> first column -> float4x3[0] = vec4(mat4x3[0][0], mat4x3[1][0], mat4x3[2][0], mat4x3[3][0]); - if (matrixType != null && NoSwapForBinaryMatrixOperation && !isAssignmentTarget) - { - if (indices.Count == 2) - { - IndexerExpression nextExpression = null; - - // float4x3[0][1] -> mat4x3[1][0] - for (int i = 0; i < indices.Count; i++) - { - nextExpression = nextExpression == null ? new IndexerExpression(targetIterator, indices[i]) : new IndexerExpression(nextExpression, indices[i]); - } - return nextExpression; - } - else - { - // matrixType.ColumnCount - var matrixElementType = matrixType.Type.ResolveType() as ScalarType; - var matrixRowType = new VectorType(matrixElementType, matrixType.ColumnCount); - - var convertRowToColumnMethod = new MethodInvocationExpression(new TypeReferenceExpression(matrixRowType)); - - for (int i = 0; i < matrixType.ColumnCount; i++) - { - convertRowToColumnMethod.Arguments.Add(new IndexerExpression(new IndexerExpression(indexerExpression.Target, new LiteralExpression(i)), indexerExpression.Index)); - } - return convertRowToColumnMethod; - } - } - - return indexerExpression; - } - - private void GenerateSamplerMappingAndStrip() - { - //var samplerMappingVisitor = new SamplerMappingVisitor(samplerMapping); - var samplerMappingVisitor = new SamplerMappingVisitor(shader, samplerMapping) - { - TextureFunctionsCompatibilityProfile = TextureFunctionsCompatibilityProfile - }; - samplerMappingVisitor.Run(entryPoint); - - // Use the strip visitor in order to remove unused functions/declaration - // from the entrypoint - var stripVisitor = new StripVisitor(entryPointName); - stripVisitor.KeepConstantBuffers = KeepConstantBuffer; - stripVisitor.Visit(shader); - - // Then add the newly created variable - if (!KeepSamplers) - { - foreach (var textureSampler in samplerMapping) - { - declarationListToRemove.Add(textureSampler.Key.Sampler); - declarationListToRemove.Add(textureSampler.Key.Texture); - AddGlobalDeclaration(textureSampler.Value); - } - } - } - - /// - /// Visits the specified shader. - /// - /// The shader. - public override Node Visit(Shader shader) - { - geometryLayoutInput = null; - geometryInputParameter = null; - geometryLayoutOutput = null; - - // Remove all texture and samplers. They will be added again as they are referenced (this is because sampler+texture becomes a sampler in OpenGL). - // shader.Declarations.RemoveAll(x => x is SamplerType); - // shader.Declarations.RemoveAll(x => x is TextureType); - - // Visit AST. - base.Visit(shader); - - // Post transform all array variable with multidimension - TransformArrayDimensions(); - - // Add explicit layout for ConstantBuffers - foreach (var cBuffer in shader.Declarations.OfType()) - { - AddExplicitLayout(cBuffer); - } - - // Add uniform keyword to variables. - foreach (var variable in shader.Declarations.OfType()) - { - var layoutRule = this.GetTagLayout(variable); - bool isUniform = IsUniformLike(variable); - - // Uniforms used as global temporary are not tagged as uniforms - if (!globalUniformVisitor.IsVariableAsGlobalTemporary(variable)) - { - if (isUniform) - { - variable.Qualifiers |= GlslStorageQualifier.Uniform; - - // For arrays, remove initializers if configured - var variableArrayType = variable.Type.ResolveType() as ArrayType; - if (variableArrayType != null && variable.InitialValue != null && !KeepUniformArrayInitializers) - { - variable.InitialValue = null; - } - } - else - { - if (UseLocationLayout && layoutRule.Location != null) - { - layoutRule.Qualifier.Layouts.Add(new LayoutKeyValue("location", layoutRule.Location)); - } - } - } - - // Remove HLSL Register - variable.Qualifiers.Values.RemoveAll(qualifierType => qualifierType is RegisterLocation); - variable.Qualifiers.Values.Remove(HlslStorageQualifier.Static); - variable.Qualifiers.Values.Remove(StorageQualifier.Shared); - - if (pipelineStage != PipelineStage.Compute) - { - variable.Qualifiers.Values.Remove(StorageQualifier.Shared); - } - // groupshared -> shared - else if (variable.Qualifiers.Values.Remove(StorageQualifier.GroupShared)) - { - variable.Qualifiers.Values.Add(StorageQualifier.Shared); - } - - // If variable is an object type, remove any initial values - var type = variable.Type.ResolveType(); - if (type is ObjectType) - variable.InitialValue = null; - } - - // Add implicit layout for uniforms - if (UseBindingLayout) - { - foreach (var variable in shader.Declarations.OfType()) - { - if (variable.Qualifiers.Contains(GlslStorageQualifier.Uniform)) - { - // GLSL doesn't support initial values for uniforms, so we are removing them - // Errata: A third party GLSL compiler is supporting initial values, so we don't need to remove them - // variable.InitialValue = null; - AddImplicitLayout(variable); - } - } - } - - // Add all defined layouts to the variable's qualifiers - foreach (var variable in shader.Declarations.OfType()) - { - var layoutRule = this.GetTagLayout(variable); - - // If there is any explicit layout, we have to add them to the variable - if (layoutRule.Qualifier.Layouts.Count > 0) - variable.Qualifiers.Values.Insert(0, layoutRule.Qualifier); - - // Replace type if needed - if (layoutRule.Type != null) - variable.Type = new TypeName(layoutRule.Type) { Span = variable.Type.Span }; - - if (layoutRule.Name != null && variable.Name.Text != layoutRule.Name) - variable.Name = new Identifier(layoutRule.Name); - } - - // Geometry shader specific analysis (in/out layouts). - if (pipelineStage == PipelineStage.Geometry) - { - if (geometryLayoutInput != null) - { - // Add layout(XXX) in; to the geometry shader - AddGeometryShaderInputDeclaration(); - AddGlobalDeclaration(new Variable(new TypeName(string.Format("layout({0})", geometryLayoutInput)), "in")); - } - - var maxVertexCount = entryPoint.Attributes().FirstOrDefault(x => x.Name == "maxvertexcount"); - if (maxVertexCount != null && geometryLayoutOutput != null) - { - entryPoint.Attributes.Remove(maxVertexCount); - - // Add layout(XXX, max_vertices=Y) out; to the geometry shader - AddGlobalDeclaration(new Variable(new TypeName(string.Format("layout({0}, max_vertices={1})", geometryLayoutOutput, maxVertexCount.Parameters[0])), "out")); - } - } - - // If there is any global uniforms used as local uniforms, we need to create locals - foreach (var globalToLocalVariable in inputAssignment) - { - var globalVariable = globalToLocalVariable.Key; - var localVariable = globalToLocalVariable.Value; - int indexOfVariable = shader.Declarations.IndexOf(globalVariable) + 1; - - entryPoint.Body.Statements.Insert(0, new ExpressionStatement(new AssignmentExpression(AssignmentOperator.Default, - new VariableReferenceExpression(localVariable), - localVariable.InitialValue as VariableReferenceExpression) - { Span = globalVariable.Span })); - - localVariable.InitialValue = null; - shader.Declarations.Insert(indexOfVariable, new DeclarationStatement(localVariable) { Span = globalVariable.Span }); - } - - // Remove all texture and sampler declarations - RemoveTextureAndSamplerDeclarations(); - - // Transform all input/output to interface block if enabled - TransformInputAndOutputToInterfaceBlock(); - - // Clear all semantic information. - foreach (var structureType in shader.Declarations.OfType()) - { - if (structureType is Ast.Glsl.InterfaceType) - continue; - - foreach (var fieldRef in GetMembers(structureType)) - { - var field = fieldRef.Field; - field.Qualifiers = Qualifier.None; - } - } - - // Remove all arguments from main. - entryPoint.Parameters.Clear(); - - // Change main definition to be void main() - entryPoint.Qualifiers = Qualifier.None; - entryPoint.ReturnType = TypeBase.Void; - entryPoint.Name = new Identifier("main"); - - return shader; - } - - private void TransformInputAndOutputToInterfaceBlock() - { - // Transform all variables with Interface block type if enabled - if (!UseInterfaceForInOut && pipelineStage != PipelineStage.Geometry) - return; - - var interfaceIn = new Ast.Glsl.InterfaceType(VertexIOInterfaceName) { Qualifiers = ParameterQualifier.In }; - - var interfaceOut = new Ast.Glsl.InterfaceType(VertexIOInterfaceName) { Qualifiers = ParameterQualifier.Out }; - - var isInAllowed = pipelineStage != PipelineStage.Vertex && pipelineStage != PipelineStage.Geometry; - var isOutAllowed = pipelineStage != PipelineStage.Pixel; - - for (int i = shader.Declarations.Count - 1; i >= 0; i--) - { - var variable = shader.Declarations[i] as Variable; - if (variable == null || variable.Type is Ast.Glsl.InterfaceType) - continue; - - if (isInAllowed && variable.Qualifiers.Contains(ParameterQualifier.In)) - { - variable.Qualifiers.Values.Remove(ParameterQualifier.In); - interfaceIn.Fields.Insert(0, variable); - shader.Declarations.RemoveAt(i); - } - else if (isOutAllowed && variable.Qualifiers.Contains(ParameterQualifier.Out)) - { - variable.Qualifiers.Values.Remove(ParameterQualifier.Out); - interfaceOut.Fields.Insert(0, variable); - shader.Declarations.RemoveAt(i); - } - } - - - var index = shader.Declarations.IndexOf(entryPoint); - if (interfaceOut.Fields.Count > 0) - shader.Declarations.Insert(index, interfaceOut); - - if (interfaceIn.Fields.Count > 0) - shader.Declarations.Insert(index, interfaceIn); - } - - - private void AddGeometryShaderInputDeclaration() - { - // Convert a HLSL struct like struct VertexData { float2 texCoord; float3 normal; } - // triangle VertexData input[3]; - - // in _VertexData_ { - // vec2 texCoord; - // vec3 normal; - // } input[]; - - // TODO ADD CHECKING - var arrayType = (ArrayType)geometryInputParameter.Type; - var structType = arrayType.Type.TypeInference.TargetType as StructType; - var interfaceType = new Ast.Glsl.InterfaceType { Name = VertexIOInterfaceName }; - int location = 0; - var evaluator = new ExpressionEvaluator(); - var result = evaluator.Evaluate(arrayType.Dimensions[0]); - - int arrayLength = 0; - if (result.HasErrors) - { - result.CopyTo(parserResult); - } - else - { - arrayLength = Convert.ToInt32(result.Value); - } - - if (structType != null) - { - int insertPosition = 0; - // Insert the variable to declare - geometryInputParameter.Qualifiers = Qualifier.None; - entryPoint.Body.Statements.Insert(insertPosition, new DeclarationStatement(geometryInputParameter)); - insertPosition++; - - const string GSInputName = "_gs_input_"; - - for (int i = 0; i < arrayLength; i++) - { - foreach (var field in structType.Fields) - { - var dest = new MemberReferenceExpression(new IndexerExpression(new VariableReferenceExpression(geometryInputParameter), new LiteralExpression(i)), field.Name); - - MemberReferenceExpression src; - - var glVariableName = GetGlVariableNameFromSemantic(field.Semantic(), true); - if (glVariableName != null && glVariableName.StartsWith("gl_", StringComparison.Ordinal)) - { - var newIndexerExpression = new IndexerExpression(new VariableReferenceExpression("gl_in"), new LiteralExpression(i)); - src = new MemberReferenceExpression(newIndexerExpression, glVariableName); - } - else - { - // For the first loop, generate the interface type - if (i == 0) - { - var variable = field.DeepClone(); - if (UseLocationLayout) - { - var variableTag = this.GetTagLayout(variable); - - if (variableTag.Location == null) - { - if (UseSemanticForLocation) - { - variableTag.Location = "S_" + variable.Semantic().Name.Text; - } - else - { - variableTag.Location = location; - } - - location++; - } - - variableTag.Qualifier.Layouts.Add(new LayoutKeyValue("location", variableTag.Location)); - - variable.Qualifiers = Qualifier.None; - variable.Qualifiers |= variableTag.Qualifier; - } - interfaceType.Fields.Add(variable); - } - - src = new MemberReferenceExpression(new IndexerExpression(new VariableReferenceExpression(GSInputName), new LiteralExpression(i)), field.Name); - } - - entryPoint.Body.Statements.Insert(insertPosition, new ExpressionStatement(new AssignmentExpression(AssignmentOperator.Default, dest, src))); - insertPosition++; - } - } - - var globalInterfaceType = new Variable(new ArrayType(interfaceType, new EmptyExpression()), GSInputName) { Qualifiers = ParameterQualifier.In }; - - AddGlobalDeclaration(globalInterfaceType); - } - } - - private void RemoveTextureAndSamplerDeclarations() - { - // Remove all texture declaration and sampler declaration - //shader.Declarations.RemoveAll(x => (x is Variable) && (((Variable)x).Type is TextureType)); - shader.Declarations.RemoveAll(declarationListToRemove.Contains); - - SearchVisitor.Run( - shader, - node => - { - var variable = node as Variable; - if (variable != null) - { - var variableRef = variable.InitialValue as VariableReferenceExpression; - if ((variable.Type is TextureType && samplerMapping.All(x => x.Key.Texture != variable)) || - (variableRef != null && declarationListToRemove.Contains(variableRef.TypeInference.Declaration))) - { - return null; - } - } - return node; - }); - } - - - - /// - /// Visits the specified parenthesized expression. - /// - /// The parenthesized expression. - /// A transformed expression. - public override Node Visit(ParenthesizedExpression parenthesizedExpression) - { - base.Visit(parenthesizedExpression); - - // Copy back type inference target type to parennthesized expression - parenthesizedExpression.TypeInference.TargetType = parenthesizedExpression.Content.TypeInference.TargetType; - - // As it is not supported by opengl, return the last element of the list for multiple arguments - // when cast expression is used with an expression list - if (parenthesizedExpression.Content is ExpressionList && ParentNode is CastExpression) - { - var expressionList = (ExpressionList)parenthesizedExpression.Content; - return ConvertToSafeExpressionForBinary(expressionList[expressionList.Count - 1]); - } - - // else return the parenthesized as-is - return parenthesizedExpression; - } - - /// - /// Splits typedefs declaration when a struct inline is used as the type - /// - private void SplitTypeDefs() - { - var newDeclarations = new List(); - foreach (var declaration in this.shader.Declarations) - { - var typedef = declaration as Typedef; - if (typedef != null && typedef.Type is StructType) - { - var structType = typedef.Type as StructType; - if (typedef.Type.Name == null) - { - typedef.Type.Name = (typedef.IsGroup ? typedef.SubDeclarators[0].Name : typedef.Name) + "_"; - } - newDeclarations.Add(typedef.Type); - - typedef.Type = new TypeName(typedef.Type.Name) { TypeInference = { Declaration = structType, TargetType = typedef.Type } }; - - if (typedef.IsGroup) - { - foreach (var typedefDeclarator in typedef.SubDeclarators) - { - typedefDeclarator.TypeInference.Declaration = structType; - typedefDeclarator.TypeInference.TargetType = structType; - } - } - else - { - typedef.TypeInference.Declaration = structType; - typedef.TypeInference.TargetType = structType; - } - - newDeclarations.Add(typedef); - } - else - { - newDeclarations.Add(declaration); - } - } - shader.Declarations = newDeclarations; - } - - /// - /// Allocates the new binding. - /// - /// - /// The allocated registers. - /// - /// - /// Index of the starting. - /// - /// - /// The size of allocation. - /// - private static void AllocateNewBinding(bool[] allocatedRegisters, int startingIndex, int sizeOfAllocation) - { - for (int i = 0; i < sizeOfAllocation; i++) - allocatedRegisters[startingIndex + i] = true; - } - - /// - /// Converts to specified expression to a safe expression for binary operation. - /// - /// - /// The expression. - /// - /// - /// If the expression was a binary expression, then it is embraced by a - /// - private static Expression ConvertToSafeExpressionForBinary(Expression expression) - { - if (expression is BinaryExpression || expression is ConditionalExpression) - return new ParenthesizedExpression(expression); - return expression; - } - - /// - /// Finds the available binding. - /// - /// - /// The allocated registers. - /// - /// - /// Index of the starting. - /// - /// - /// The size of allocation. - /// - /// - /// The find available binding. - /// - private static int FindAvailableBinding(bool[] allocatedRegisters, int startingIndex, int sizeOfAllocation) - { - int newIndex = -1; - int allocSize = sizeOfAllocation; - for (int i = startingIndex; i < allocatedRegisters.Length; i++) - { - if (allocatedRegisters[i]) - { - newIndex = -1; - allocSize = sizeOfAllocation; - } - else - { - if (newIndex < 0) - newIndex = i; - allocSize--; - if (allocSize == 0) - break; - } - } - - // Only return selected Index if we were able to allocate sizeOfAllocation - if (allocSize == 0) - return newIndex; - - return -1; - } - - /// - /// Determines whether the specified variable is an uniform like. - /// - /// - /// The variable. - /// - /// - /// true if the specified variable is an uniform like; otherwise, false. - /// - private static bool IsUniformLike(Variable variable) - { - return !variable.Qualifiers.Contains(ParameterQualifier.InOut) - && !variable.Qualifiers.Contains(ParameterQualifier.In) - && !variable.Qualifiers.Contains(ParameterQualifier.Out) - && !variable.Qualifiers.Contains(HlslStorageQualifier.Static) - && !variable.Qualifiers.Contains(StorageQualifier.Const) - && !variable.Qualifiers.Contains(StorageQualifier.Shared) - && !variable.Qualifiers.Contains(StorageQualifier.GroupShared); - } - - /// - /// Convert semantic string into a (semantic, semanticIndex) pair. - /// - /// - /// The semantic. - /// - /// - /// A KeyvalueParis semantic -> location - /// - private static KeyValuePair ParseSemantic(string semantic) - { - // A semantic can have a modifier. We parse it but we don't handle it - // http://msdn.microsoft.com/en-us/library/bb219850%28v=vs.85%29.aspx - foreach (var semanticModifier in SemanticModifiers) - { - if (semantic.EndsWith(semanticModifier, StringComparison.OrdinalIgnoreCase)) - { - // Console.WriteLine("Warning, unsupported semantic modifier [{0}] for semantic [{1}]", semanticModifier, semantic); - semantic = semantic[..^semanticModifier.Length]; - break; - } - } - - return Semantic.Parse(semantic); - } - - /// - /// Adds the explicit layout. - /// - /// - /// The variable. - /// - private void AddExplicitLayout(Variable variable) - { - var layout = this.GetTagLayout(variable); - var registerLocation = variable.Qualifiers.Values.OfType().FirstOrDefault(); - - if (registerLocation != null && layout.Binding == null) - { - int registerIndex; - var register = registerLocation.Register.Text; - - var allocatedRegister = register.StartsWith('s') ? allocatedRegistersForSamplers : allocatedRegistersForUniforms; - string registerIndexStr = register[1] != '[' ? register[1..] : register.Substring(2, register.Length - 3); - - if (!int.TryParse(registerIndexStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out registerIndex)) - { - parserResult.Error("Invalid layout binding for variable [{0}]", variable.Span, variable); - return; - } - - var size = GetNumberOfFloat4FromVariable(variable.Type); - - var newIndex = FindAvailableBinding(allocatedRegister, registerIndex, size); - - // If this register index was already allocated, try to allocate the new register as an implicit layout - if (newIndex != registerIndex) - { - parserResult.Warning("Unable to use explicit layout for variable {0} as the location is already used. Use of an implicit layout", variable.Span, variable); - AddImplicitLayout(variable); - } - else - { - AllocateNewBinding(allocatedRegister, registerIndex, size); - layout.Binding = registerIndex; - layout.Qualifier.Layouts.Add(new LayoutKeyValue("binding", registerIndex)); - } - } - } - - /// - /// Adds the explicit layout for a constant buffer. - /// - /// The variable. - private void AddExplicitLayout(ConstantBuffer cBuffer) - { - // Clear old register - var register = cBuffer.Register; - cBuffer.Register = null; - - // If a register was defined - if (register != null) - { - var registerStr = register.Register.Text; - - var layout = this.GetTagLayout(cBuffer, registerStr); - - if (registerStr.StartsWith('b')) - { - int registerIndex; - string registerIndexStr = registerStr[1..]; - - if (!int.TryParse(registerIndexStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out registerIndex)) - { - parserResult.Error("Invalid layout binding for Constant Buffer [{0}]", cBuffer.Span, cBuffer); - return; - } - - // A third party GLSL compiler requires layout binding to start at 1-15 - registerIndex++; - - if (layout.Binding == null) - layout.Binding = registerIndex; - } - - if (layout.Binding != null) - { - cBuffer.Register = new RegisterLocation(string.Empty, layout.Binding.ToString()); - } - } - - // Add Location layout from packoffset for constant buffers/uniform blocks - if (UseLocationLayout) - { - foreach (var variable in cBuffer.Members.OfType()) - { - var packOffset = variable.Qualifiers.OfType().FirstOrDefault(); - - if (packOffset != null) - { - variable.Qualifiers = Qualifier.None; - variable.Qualifiers |= new Ast.Glsl.LayoutQualifier(new LayoutKeyValue("location", packOffset.ToFloat4SlotIndex())); - } - } - } - } - - /// - /// Adds the global declaration. - /// - /// - /// Type of the declaration - /// - /// - /// The declaration. - /// - private void AddGlobalDeclaration(T declaration, bool forceToAdd = false) where T : Node, IDeclaration - { - // Don't add glsl variable - if (!declaration.Name.Text.StartsWith("gl_", StringComparison.Ordinal) || forceToAdd) - { - var index = shader.Declarations.IndexOf(entryPoint); - shader.Declarations.Insert(index, declaration); - } - - var topStack = ScopeStack.LastOrDefault(); - if (topStack != null) - topStack.AddDeclaration(declaration); - } - - /// - /// Adds the implicit layout. - /// - /// - /// The variable. - /// - private void AddImplicitLayout(Variable variable) - { - var registerLocation = variable.Qualifiers.Values.OfType().FirstOrDefault(); - var layout = this.GetTagLayout(variable); - - if (registerLocation == null && layout.Binding == null) - { - // Remove any kind of register location - // if (forceImplicitLayout) - // variable.Qualifiers.Values.RemoveAll((type) => type is RegisterLocation); - var allocatedRegister = variable.Type.IsSamplerType() ? allocatedRegistersForSamplers : allocatedRegistersForUniforms; - var size = GetNumberOfFloat4FromVariable(variable.Type); - - int registerIndex = FindAvailableBinding(allocatedRegister, 0, size); - - // if (layout.Layout.Binding.HasValue) - // registerIndex = layout.Layout.Binding.Value; - if (registerIndex < 0) - parserResult.Error("Unable to find a free slot for uniform {0}", variable.Span, variable); - else - { - AllocateNewBinding(allocatedRegister, registerIndex, size); - layout.Binding = registerIndex; - layout.Qualifier.Layouts.Add(new LayoutKeyValue("binding", registerIndex)); - } - } - } - - /// - /// Binds the location. - /// - /// The semantic. - /// The typebase. - /// if set to true [is input]. - /// The default name. - /// The location. - /// - /// A variable - /// - private Variable BindLocation(Semantic semantic, TypeBase typebase, bool isInput, string defaultName, ref int location, SourceSpan span) - { - var variableFromSemantic = GetVariableFromSemantic(semantic, typebase, isInput, defaultName, span); - if (!variableFromSemantic.Name.Text.StartsWith("gl_", StringComparison.Ordinal)) - { - var variableTag = this.GetTagLayout(variableFromSemantic); - - if (variableTag.Location == null) - { - if (UseSemanticForLocation) - { - variableTag.Location = "S_" + semantic.Name.Text; - } - else - { - variableTag.Location = location; - - if (InputAttributeNames != null && isInput && (pipelineStage == PipelineStage.Vertex || pipelineStage == PipelineStage.Geometry)) - InputAttributeNames[location] = semantic.Name.Text; - } - - var matrixType = typebase as MatrixType; - if (matrixType != null) - { - location += 4; // TODO: Pack - } - else if (typebase is ScalarType || typebase is VectorType) - { - location++; - } - else - { - throw new NotImplementedException(); - } - } - } - - return variableFromSemantic; - } - - /// - /// Calculates the GLSL prefix. - /// - /// - /// The type. - /// - /// - /// The prefix of the glsl variable - /// - private string CalculateGlslPrefix(ScalarType type) - { - string prefix = string.Empty; - if (type == ScalarType.Float || type == ScalarType.Half) - prefix = string.Empty; - else if (type == ScalarType.Bool) - prefix = "b"; - else if (type == ScalarType.Int) - prefix = "i"; - else if (type == ScalarType.UInt) - prefix = "u"; - else if (type == ScalarType.Double) - prefix = "d"; - return prefix; - } - - /// - /// Checks a cast method. - /// - /// - /// The method invocation expression. - /// - private void CheckCastMethod(MethodInvocationExpression methodInvocationExpression) - { - var typeReferenceExpression = methodInvocationExpression.Target as TypeReferenceExpression; - if (typeReferenceExpression != null) - { - // Transform vector to array initializer: - // float value[4] = float[4](myVectorFloat4); to => float value[4] = float[4](myVectorFloat4[0], myVectorFloat4[1], myVectorFloat4[2], myVectorFloat4[3]); - var arrayType = typeReferenceExpression.Type as ArrayType; - if (arrayType != null) - { - if (methodInvocationExpression.Arguments.Count == 1) - { - var argument = methodInvocationExpression.Arguments[0]; - methodInvocationExpression.Arguments.Clear(); - - var argType = argument.TypeInference.TargetType; - var arrayElementType = arrayType.Type.ResolveType(); - if (argType is VectorType && arrayElementType is ScalarType && arrayType.Dimensions.Count == 1) - { - var vectorType = (VectorType)argType; - - for (int i = 0; i < vectorType.Dimension; i++) - { - Expression indexerExpression = new IndexerExpression(argument, new LiteralExpression(i)) { TypeInference = { TargetType = arrayElementType } }; - - if (vectorType.Type != arrayElementType) - indexerExpression = new MethodInvocationExpression(new TypeReferenceExpression(arrayElementType), indexerExpression); - - methodInvocationExpression.Arguments.Add(indexerExpression); - } - } - } - } - } - } - - /// - /// Converts the condition. - /// - /// - /// The expression. - /// - /// - /// A converted expression - /// - private Expression ConvertCondition(Expression expression) - { - var expressionType = expression.TypeInference.TargetType; - // Convert !value, with value not bool to int(value) == 0 - if (expressionType != ScalarType.Bool) - { - expression = new MethodInvocationExpression(new TypeReferenceExpression(ScalarType.Bool), expression) { TypeInference = { TargetType = ScalarType.Bool } }; - } - return expression; - } - - - private Expression CastSemanticToReferenceType(Identifier name, TypeBase semanticType, Variable semanticAsVariable) - { - TypeBase glslType = semanticAsVariable.Type; - - var defaultGlslRef = new VariableReferenceExpression(name) { TypeInference = { Declaration = semanticAsVariable, TargetType = glslType } }; - - var semanticVectorType = semanticType as VectorType; - var glslVectorType = glslType as VectorType; - if (semanticVectorType != null && glslVectorType != null) - { - if (semanticVectorType.Dimension < glslVectorType.Dimension) - { - return new MemberReferenceExpression(defaultGlslRef, "xyzw".Substring(0, semanticVectorType.Dimension)) { TypeInference = { TargetType = semanticVectorType } }; - } - - if (semanticVectorType.Dimension > glslVectorType.Dimension) - { - // TODO: Is this case is relevant? - } - } - - return defaultGlslRef; - } - - private Expression ConvertReferenceToSemantics(VariableReferenceExpression varRefExpr, Semantic semantic, TypeBase type, string varName, SourceSpan span) - { - // Detect and transform input/output structure member reference. - // i.e. output.position should get transformed to gl_Position - if (varRefExpr != null) - { - bool isInputOrOutput = false; - - if (IsInEntryPoint && (semantic != null || (type != null && type is StructType))) - { - bool isInput = inputs.Any(x => x.Name == varRefExpr.Name); - bool isOutput = outputs.Any(x => x.Name == varRefExpr.Name); - - isInputOrOutput = isInput || isOutput; - - // if isInput and not StructType - // if isOutput and not structType - // if isOutput and structType && not assigntarget - if (((isInput || isOutput) && !(type is StructType)) || (isOutput && !isAssignmentTarget)) - { - var variable = GetVariableFromSemantic(semantic, type, isInput, varName, span); - Variable newVariable; - inputAssignment.TryGetValue(variable, out newVariable); - - if (isInput && isAssignmentTarget && newVariable == null) - { - newVariable = new Variable(variable.Type, "local_" + variable.Name.Text, CastSemanticToReferenceType(variable.Name, type, variable)); - inputAssignment.Add(variable, newVariable); - return new VariableReferenceExpression(newVariable); - } - - if (newVariable != null) - variable = newVariable; - - return this.CastSemanticToReferenceType(variable.Name, type, variable); - } - } - - // Some uniforms have semantics attached, so if this is not an input or output variable, this is more likely to be an uniform - if (!isInputOrOutput) - { - var variable = FindDeclaration(varRefExpr.Name) as Variable; - - if (variable != null && !variable.Type.ResolveType().Name.Text.StartsWith("RWTexture") && !variable.Type.ResolveType().Name.Text.StartsWith("RWBuffer")) - { - Variable newVariable; - inputAssignment.TryGetValue(variable, out newVariable); - if (isAssignmentTarget && IsUniformLike(variable) && shader.Declarations.Contains(variable) && newVariable == null) - { - newVariable = new Variable(variable.Type, "local_" + variable.Name.Text, new VariableReferenceExpression(variable.Name) { TypeInference = { TargetType = variable.Type } }); - inputAssignment.Add(variable, newVariable); - } - - if (newVariable != null) - return new VariableReferenceExpression(newVariable.Name) { TypeInference = { TargetType = newVariable.Type.ResolveType() } }; - } - } - } - - return null; - } - - private void ReturnStruct(StructType structType, Expression returnValueExpression, StatementList statementList) - { - var span = returnValueExpression.Span; - foreach (var fieldRef in GetMembers(structType)) - { - var field = fieldRef.Field; - - - // When a field is an array, we need to properly handle return values for semantics - var fieldType = field.Type.ResolveType(); - var fieldArrayType = fieldType as ArrayType; - - var semanticVariable = GetVariableFromSemantic(field.Semantic(), fieldType, false, fieldRef.FieldNamePath, span); - - // If this is a special semantic we need to convert each indices - if (fieldArrayType != null && semanticVariable.Name.Text.StartsWith("gl_", StringComparison.Ordinal)) - { - var arrayDimension = fieldArrayType.Dimensions[0] as LiteralExpression; - var arrayValue = arrayDimension != null ? Convert.ChangeType(arrayDimension.Literal.Value, typeof(int)) : null; - if (arrayDimension != null && arrayValue != null) - { - var count = (int)arrayValue; - for (int i = 0; i < count; i++) - { - var semantic = field.Semantic(); - var newSemantic = new Semantic(semantic.BaseName + i); - - statementList.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new VariableReferenceExpression(GetVariableFromSemantic(newSemantic, fieldArrayType, false, fieldRef.FieldNamePath, span).Name), - new IndexerExpression(fieldRef.GetMemberReference(returnValueExpression), new LiteralExpression(i)))) - { Span = span }); - } - - } - else - { - parserResult.Error("Unable to convert semantic expression [{0}]. Array dimension must be a literal expression", field.Span, field); - } - } - else - { - var semanticValue = (Expression)fieldRef.GetMemberReference(returnValueExpression); - if (fieldType != semanticVariable.Type) - { - semanticValue = NewCast(semanticVariable.Type, semanticValue); - } - - statementList.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, new VariableReferenceExpression(semanticVariable.Name) { TypeInference = { Declaration = semanticVariable } }, semanticValue)) - { Span = returnValueExpression.Span }); - } - } - } - - /// - /// This helper function will transform a "return X;" statement into a list of assignment for each semantic and a "return;". - /// - /// - /// The expression. - /// - /// - /// if set to true [emit return]. - /// - /// - /// A statement used to replace the return statement - /// - private Statement ConvertReturn(Expression returnValueExpression, bool emitReturn, SourceSpan? span) - { - var statementList = new StatementList(); - Statement result = statementList; - - StructType structType = null; - - // Handle structure returned by variable - if (returnValueExpression != null) - { - if (!span.HasValue) - span = returnValueExpression.Span; - - var varRefExpr = returnValueExpression as VariableReferenceExpression; - if (varRefExpr != null) - { - var variableDeclarator = varRefExpr.TypeInference.Declaration as Variable; - structType = variableDeclarator != null ? variableDeclarator.Type.ResolveType() as StructType : null; - - if (structType != null) - { - ReturnStruct(structType, returnValueExpression, statementList); - } - } - else - { - // Handle structure returned by method invocation - var methodRefExp = returnValueExpression as MethodInvocationExpression; - if (methodRefExp != null) - { - var variableDeclarator = methodRefExp.Target.TypeInference.Declaration as MethodDeclaration; - structType = variableDeclarator != null ? variableDeclarator.ReturnType.ResolveType() as StructType : null; - } - - if (structType != null) - { - // Replace plain statement list with a block statement - result = new BlockStatement(statementList); - - statementList.Add(new DeclarationStatement(new Variable(new TypeName(structType.Name), "_local_ret_", returnValueExpression))); - - var localRet = new VariableReferenceExpression("_local_ret_"); - - ReturnStruct(structType, localRet, statementList); - } - } - - // Note: if we return a struct but the method also has a semantic, it is ignored as the struct members should contain the semantic - if (structType == null && CurrentFunction.Semantic() != null) - { - var semantic = CurrentFunction.Semantic(); - statementList.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new VariableReferenceExpression(GetVariableFromSemantic(semantic, CurrentFunction.ReturnType.ResolveType(), false, null, semantic.Span).Name), - returnValueExpression)) - { Span = span.Value }); - } - } - - // For structure in output, declare a local variable - foreach (var variable in this.outputs) - { - structType = variable.Type.ResolveType() as StructType; - if (structType != null) - { - // No modifiers for structure inlined in the code - variable.Qualifiers = Qualifier.None; - ReturnStruct(structType, new VariableReferenceExpression(variable.Name), statementList); - } - } - - // Remap Z coordinates - this.RemapCoordinates(statementList); - - if (emitReturn) - statementList.Add(new ReturnStatement() { Span = span.HasValue ? span.Value : new SourceSpan() }); - - return result; - } - - /// - /// Finds the name of the type by its name. - /// - /// - /// The name. - /// - /// - /// A type - /// - private TypeBase FindTypeByName(string name) - { - return FindDeclaration(name) as TypeBase; - } - - /// - /// Finds the vertex layout rule by semantic name. - /// - /// - /// The name. - /// - /// - /// A - /// - private VariableLayoutRule FindVariableLayoutBySemantic(string name) - { - VariableLayoutRule rule; - this.VariableLayouts.TryGetValue(name, out rule); - return rule; - } - - /// - /// Finds the vertex layout rule by semantic name. - /// - /// - /// The name. - /// - /// - /// A - /// - private ConstantBufferLayoutRule FindConstantBufferLayoutByRegister(string name) - { - ConstantBufferLayoutRule rule; - this.ConstantBufferLayouts.TryGetValue(name, out rule); - return rule; - } - - - /// - /// Flattens the array creation expression. - /// - /// - /// The source array that could be composed of inner array creation expression. - /// - /// - /// The destination array that will receive all flattened values - /// - private void FlattenArrayCreationExpression(ArrayInitializerExpression from, List to) - { - foreach (var nextElement in from.Items) - { - // Recursive call if there is an array creation expression. - if (nextElement is ArrayInitializerExpression) - FlattenArrayCreationExpression((ArrayInitializerExpression)nextElement, to); - else - to.Add(nextElement); - } - } - - private Variable FindParameterOrGlobalVariableFromExpression(Expression expression) - { - var variableRef = expression as VariableReferenceExpression; - if (variableRef != null) - { - // Check if present in parameter list first. - var parameter = CurrentFunction.Parameters.FirstOrDefault(x => x is Stride.Core.Shaders.Ast.Parameter param && param.Name == variableRef.Name); - if (parameter != null) - { - return parameter; - } - - return FindGlobalVariableFromExpression(expression); - } - - return null; - } - - private Variable FindGlobalVariableFromExpression(Expression expression) - { - var variableRef = expression as VariableReferenceExpression; - if (variableRef != null) - { - var variable = variableRef.TypeInference.Declaration as Variable; - - if (variable != null) - { - // If a variable has an initial value, find the global variable - if (!shader.Declarations.Contains(variable) && variable.InitialValue != null) - { - return FindGlobalVariableFromExpression(variable.InitialValue); - } - - // Is this a global variable? - if (shader.Declarations.Contains(variable)) - { - return variable; - } - } - } - return null; - } - - /// - /// Gets the GL sampler associated with a sampler and a texture. - /// - /// The sampler. - /// The texture. - /// if set to true [force null sampler] to match. - /// - /// The variable associated with the sampler and the texture - /// - private Expression GetGLSampler(Variable sampler, Variable texture, bool forceNullSampler) - { - Variable glslSampler; - - if (sampler == null && !forceNullSampler) - { - // Access using only texture, any sampler/texture pair with matching texture is OK (in case forceNullSampler is not set) - var matchingTextureSampler = samplerMapping.Where(x => x.Key.Texture == texture); - if (!matchingTextureSampler.Any()) - { - return null; - } - - return new VariableReferenceExpression(matchingTextureSampler.First().Value.Name); - } - - var samplerKey = new SamplerTextureKey(sampler, texture); - if (!samplerMapping.TryGetValue(samplerKey, out glslSampler)) - { - return null; - } - - if (KeepSamplers) - { - if (sampler != null) - { - return new MethodInvocationExpression(new TypeReferenceExpression(glslSampler.Type), new VariableReferenceExpression(texture), new VariableReferenceExpression(sampler)); - } - else - { - return new VariableReferenceExpression(texture); - } - } - - return new VariableReferenceExpression(glslSampler.Name); - } - - /// - /// Gets the number of float4 from a type. - /// - /// - /// The type. - /// - /// - /// Number of float4 from a type - /// - private int GetNumberOfFloat4FromVariable(TypeBase typeOfVar) - { - var variableType = typeOfVar.ResolveType(); - - var matrixType = variableType as MatrixType; - if (matrixType != null) - return matrixType.RowCount * matrixType.ColumnCount / 4; - - var arrayType = variableType as ArrayType; - if (arrayType != null) - { - // var dimExpr = arrayType.Dimensions[0] as LiteralExpression; - var evaluator = new ExpressionEvaluator(); - var result = evaluator.Evaluate(arrayType.Dimensions[0]); - - if (result.HasErrors) - { - result.CopyTo(parserResult); - } - else - { - var dimValue = Convert.ToInt32(result.Value); - return dimValue * GetNumberOfFloat4FromVariable(arrayType.Type); - } - } - - var structType = variableType as StructType; - if (structType != null) - { - int structSize = 0; - foreach (var variable in structType.Fields) - { - structSize += GetNumberOfFloat4FromVariable(variable.Type.ResolveType()); - } - return structSize; - } - - // Else default is 1 float4 - return 1; - } - - /// - /// Gets the variable from semantic. - /// - /// - /// The semantic. - /// - /// - /// The type. - /// - /// - /// if set to true [is input]. - /// - /// - /// Name of the var. - /// - /// - /// The variable associated with a semantic - /// - private Variable GetVariableFromSemantic(Semantic semantic, TypeBase type, bool isInput, string varName, SourceSpan span) - { - type = type.ResolveType(); - - bool isArray = type is ArrayType; - TypeBase elementType = isArray ? ((ArrayType)type).Type.ResolveType() : type; - - TypeBase defaultType = type; - int semanticIndex = 0; - - var glSemantic = semantic; - - if (glSemantic != null) - { - glSemantic = ResolveSemantic(semantic, type, isInput, varName, out defaultType, out semanticIndex, span); - } - else - { - span = type.Span; - } - - string variableName = glSemantic == null ? varName : glSemantic.Name.Text; - - bool addGlslGlobalVariable = CultureInfo.InvariantCulture.CompareInfo.Compare(variableName, "gl_Position", CompareOptions.IgnoreCase) == 0 && defaultType != type; - - bool isFragData = CultureInfo.InvariantCulture.CompareInfo.IsPrefix(variableName, "gl_fragdata", CompareOptions.IgnoreCase); - if (isFragData && needCustomFragData) - { - // IF varName is null, this is a semantic from a returned function, so use a generic out_gl_fragdata name - // otherwise, use the original variable name. - variableName = varName != null ? "out_gl_fragdata_" + varName : "out_gl_fragdata"; - addGlslGlobalVariable = true; - } - - // var firstContext = DeclarationContexts.First(); - var variable = FindDeclaration(variableName) as Variable; - if (variable == null) - { - variable = new Variable(defaultType, variableName) { Span = span }; - - if (addGlslGlobalVariable) - { - variable.Type = type; - if (isInput) - { - variable.Qualifiers |= ParameterQualifier.In; - } - else - { - if (isFragData && needCustomFragData) - { - // Write location on outputs in case of MRT - variable.Qualifiers |= new LayoutQualifier { Layouts = { new LayoutKeyValue("location", semanticIndex) } }; - } - - variable.Qualifiers |= ParameterQualifier.Out; - } - } - - AddGlobalDeclaration(variable, addGlslGlobalVariable); - } - - return variable; - } - - /// - /// Gets the variable tag. - /// - /// The variable. - /// The alias name (semantic or register). - /// - /// The tag associated with a variable - /// - private TagLayout GetTagLayout(Node node, string alias = null) - { - var variable = node as Variable; - var constantBuffer = node as ConstantBuffer; - - var layoutTag = node.GetTag(TagLayoutKey) as TagLayout; - if (layoutTag == null) - { - layoutTag = new TagLayout(); - node.SetTag(TagLayoutKey, layoutTag); - - if (variable != null) - { - MapRule mapType; - if (MapRules.TryGetValue(variable.Name, out mapType)) - { - layoutTag.Type = mapType.Type; - } - } - - // Only for vertex shader input - if (alias != null) - { - if (variable != null) - { - var variableLayoutRule = this.FindVariableLayoutBySemantic(alias); - if (variableLayoutRule != null) - { - // Update location from external layout - if (variableLayoutRule.Location != null) - { - int locationIndex; - if (int.TryParse(variableLayoutRule.Location, out locationIndex)) - { - layoutTag.Location = locationIndex; - - if (InputAttributeNames != null) - InputAttributeNames[locationIndex] = alias; - } - else - { - layoutTag.Location = variableLayoutRule.Location; - } - } - - // Use output or input name - layoutTag.Name = variable.Qualifiers.Contains(ParameterQualifier.Out) ? variableLayoutRule.NameOutput : variableLayoutRule.Name; - } - } - else if (constantBuffer != null) - { - var cBufferLayoutRule = this.FindConstantBufferLayoutByRegister(alias); - if (cBufferLayoutRule != null) - { - if (cBufferLayoutRule.Binding != null) - { - int bindingIndex; - if (int.TryParse(cBufferLayoutRule.Binding, out bindingIndex)) - { - layoutTag.Binding = bindingIndex; - } - else - { - layoutTag.Binding = cBufferLayoutRule.Binding; - } - } - } - } - } - - if (variable != null && layoutTag.Name == null) - layoutTag.Name = variable.Name.Text; - - layoutTag.Qualifier = new LayoutQualifier(); - } - - return layoutTag; - } - - /// - /// Rebinds all VariableReferenceExpression to the final name. - /// - private void RebindVariableReferenceExpressions() - { - SearchVisitor.Run( - shader, - node => - { - if (node is VariableReferenceExpression) - { - var variableRef = (VariableReferenceExpression)node; - if (variableRef.TypeInference.Declaration is Variable) - variableRef.Name = variableRef.TypeInference.Declaration.Name; - } - else if (node is MethodInvocationExpression) - { - var methodRef = (MethodInvocationExpression)node; - var variableRef = methodRef.Target as VariableReferenceExpression; - var methodDeclaration = variableRef != null ? variableRef.TypeInference.Declaration as MethodDeclaration : null; - if (variableRef != null && methodDeclaration != null && !methodDeclaration.IsBuiltin) - variableRef.Name = methodDeclaration.Name; - } - - return node; - }); - } - - /// - /// Removes the default parameters for methods. - /// - private void RemoveDefaultParametersForMethods() - { - SearchVisitor.Run( - shader, - node => - { - var declaration = node as Parameter; - if (declaration != null && declaration.InitialValue != null) - declaration.InitialValue = null; - return node; - }); - } - - private static string RenameGlslKeyword(string name) - { - // Note: we try to avoid ending up with a _, since glsl_optimizer might add another _X, and GLSL doesn't like usage of double underscore - if (GlslKeywords.IsReserved(name)) - name = "_" + name; - - // Replace all variable using __ with _0 - return name.Replace("__", "_0"); - } - - /// - /// If requested, Z projection coordinates will be remapped from [0;1] to [-1;1] at end of vertex shader. - /// - private void RemapCoordinates(StatementList list) - { - if (pipelineStage == PipelineStage.Vertex && (entryPoint != null)) - { - if (ViewFrustumRemap) - { - // Add gl_Position.z = gl_Position.z * 2.0f - gl_Position.w - list.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new MemberReferenceExpression(new VariableReferenceExpression("gl_Position"), "z"), - new BinaryExpression( - BinaryOperator.Minus, - new BinaryExpression( - BinaryOperator.Multiply, - new MemberReferenceExpression(new VariableReferenceExpression("gl_Position"), "z"), - new LiteralExpression(2.0f)), - new MemberReferenceExpression(new VariableReferenceExpression("gl_Position"), "w")) - ))); - } - - if (FlipRenderTarget) - { - // Add gl_Position.y = -gl_Position.y - list.Add( - new ExpressionStatement( - new AssignmentExpression( - AssignmentOperator.Default, - new MemberReferenceExpression(new VariableReferenceExpression("gl_Position"), "y"), - new UnaryExpression( - UnaryOperator.Minus, - new MemberReferenceExpression(new VariableReferenceExpression("gl_Position"), "y")) - ))); - } - } - } - - /// - /// Renames all declaration that are using a GLSL keywords. - /// - private void RenameGlslKeywords() - { - SearchVisitor.Run( - shader, - node => - { - var declaration = node as IDeclaration; - var variableRef = node as VariableReferenceExpression; - if (declaration != null && declaration.Name != null) - { - if (!(declaration is Variable variable && variable.Type.Name.Text.StartsWith("layout", StringComparison.Ordinal))) - { - declaration.Name.Text = RenameGlslKeyword(declaration.Name.Text); - } - } - else if (variableRef != null) - { - variableRef.Name.Text = RenameGlslKeyword(variableRef.Name.Text); - } - - return node; - }); - } - - private KeyValuePair GetGlVariableFromSemantic(Semantic rawSemantic, bool isInput, out string semanticGl, out string semanticGlBase, out int semanticIndex) - { - var semanticName = rawSemantic.Name.Text; - var semantic = ParseSemantic(semanticName); - - var semanticMapping = isInput ? builtinInputs : builtinOutputs; - - semanticGl = null; - - if (semanticMapping != null && !semanticMapping.TryGetValue(semanticName, out semanticGl)) - semanticMapping.TryGetValue(semantic.Key, out semanticGl); - - // Special case for point sprite - if (semanticName != null && semanticName.Equals("TEXCOORD0") && IsPointSpriteShader && pipelineStage == PipelineStage.Pixel) - semanticGl = "gl_PointCoord"; - - // Set the semantic gl base name - semanticGlBase = semanticGl; - semanticIndex = semantic.Value; - - if (semanticGl != null && semanticGl.EndsWith("[]", StringComparison.Ordinal)) - { - semanticGlBase = semanticGl[..^2]; - - // If there is [] at the end of the string, insert semantic index within [] - semanticGl = $"{semanticGlBase}[{semantic.Value}]"; - } - - return semantic; - } - - private string GetGlVariableNameFromSemantic(Semantic rawSemantic, bool isInput) - { - string semanticGlBase = null; - string semanticGl = null; - int semanticIndex; - GetGlVariableFromSemantic(rawSemantic, isInput, out semanticGl, out semanticGlBase, out semanticIndex); - - return semanticGl; - } - - /// - /// Resolves the HLSL semantic into GLSL one for a given uniform. - /// It will also adds the varying to the GLSL shader the first time it is found. - /// - /// The raw semantic. - /// The type. - /// if set to true input, otherwise output. - /// Name of the var. - /// A semantic transformed - private Semantic ResolveSemantic(Semantic rawSemantic, TypeBase type, bool isInput, string varName, out TypeBase glslType, out int semanticIndex, SourceSpan span) - { - string semanticGlBase = null; - string semanticGl = null; - var semantic = GetGlVariableFromSemantic(rawSemantic, isInput, out semanticGl, out semanticGlBase, out semanticIndex); - - if (semanticGl == null) - { - // Prefix with a_ or v_ ( attribute or varying ) - if (isInput && (pipelineStage == PipelineStage.Vertex)) - semanticGl = "a_" + (this.UseSemanticForVariable ? semantic.Key + semantic.Value : varName); - else if ((isInput == false) && (pipelineStage == PipelineStage.Pixel)) - semanticGl = "vout_" + (this.UseSemanticForVariable ? semantic.Key + semantic.Value : varName); - else - semanticGl = "v_" + (this.UseSemanticForVariable ? semantic.Key + semantic.Value : varName); - - var variable = FindDeclaration(semanticGl) as Variable; - if (variable == null) - { - variable = new Variable(type, semanticGl) { Span = span }; - - // int must be "flat" between stages (everywhere except VS input) - if (!(isInput == true && pipelineStage == PipelineStage.Vertex)) - { - var baseType = TypeBase.GetBaseType(variable.Type); - // Note: not sure why, but it seems scalar are not properly resolved? - if (baseType.Name == ScalarType.Int.Name || baseType.Name == ScalarType.UInt.Name) - { - variable.Qualifiers |= ParameterQualifier.Flat; - } - } - - variable.Qualifiers |= isInput ? ParameterQualifier.In : ParameterQualifier.Out; - - // Setup Variable Tag for LayoutQualifiers - //GetTagLayout(variable, semanticName, isInput && pipelineStage == PipelineStage.Vertex); - this.GetTagLayout(variable, rawSemantic.Name.Text); - - AddGlobalDeclaration(variable); - } - glslType = type; - } - else - { - if (builtinGlslTypes.TryGetValue(semanticGlBase, out glslType)) - { - // If type is an array type, create the equivalent arrayType - var arrayType = type as ArrayType; - if (arrayType != null) - glslType = new ArrayType(glslType, arrayType.Dimensions.ToArray()); - } - else - { - parserResult.Warning("No default type defined for glsl semantic [{0}]. Use [{1}] implicit type instead.", rawSemantic.Span, semanticGlBase, type); - glslType = type; - } - } - - return new Semantic(semanticGl); - } - - /// - /// Tranforms to GLSL types. - /// - private void TranformToGlslTypes() - { - var mapToGlsl = new Dictionary(); - - // Add vector type conversion - foreach (var type in new[] { ScalarType.Bool, ScalarType.Int, ScalarType.UInt, ScalarType.Float, ScalarType.Double, ScalarType.Half }) - { - var targetSubType = type == ScalarType.Half ? ScalarType.Float : type; - var prefix = CalculateGlslPrefix(type); - - for (int i = 2; i <= 4; ++i) - mapToGlsl.Add(new VectorType(type, i), new TypeName(prefix + "vec" + i)); - - // Half are converted to float - mapToGlsl.Add(new VectorType(type, 1), targetSubType); - } - - // Add matrix type conversion - foreach (var type in new[] { ScalarType.Double, ScalarType.Float, ScalarType.Half }) - { - var prefix = CalculateGlslPrefix(type); - for (int i = 2; i <= 4; ++i) - { - for (int j = 2; j <= 4; ++j) - { - // Swap column/matrix if NoSwapForBinaryMatrixOperation is true - int column = NoSwapForBinaryMatrixOperation ? j : i; - int row = NoSwapForBinaryMatrixOperation ? i : j; - - string matrixName = i == j ? string.Format(prefix + "mat{0}", i) : string.Format(prefix + "mat{0}x{1}", column, row); - - mapToGlsl.Add(new MatrixType(type, i, j), new TypeName(matrixName)); - } - } - } - - mapToGlsl.Add(ScalarType.Half, ScalarType.Float); - mapToGlsl.Add(new MatrixType(ScalarType.Float, 1, 1), ScalarType.Float); - - // Sampler objects - mapToGlsl.Add(StateType.SamplerState, new TypeName("sampler")); - mapToGlsl.Add(StateType.SamplerComparisonState, new TypeName("samplerShadow")); - //mapToGlsl.Add(SamplerStateType.SamplerComparisonState, new TypeName("sampler")); - - // Texture objects - //mapToGlsl.Add(TextureType.Texture, new TextureType("texture2D")); - //mapToGlsl.Add(TextureType.Texture1D, new TextureType("texture1D")); - //mapToGlsl.Add(TextureType.Texture2D, new TextureType("texture2D")); - //mapToGlsl.Add(TextureType.Texture3D, new TextureType("texture3D")); - //mapToGlsl.Add(TextureType.TextureCube, new TextureType("textureCube")); - - // Replace all generic shader types to their glsl equivalent. - SearchVisitor.Run( - shader, - node => - { - if (node is TypeBase && !(node is Typedef) && !(node is ArrayType)) - { - var type = (TypeBase)node; - var targetType = type.ResolveType(); - - TypeBase outputType; - if (mapToGlsl.TryGetValue(targetType, out outputType)) - return outputType; - if (mapToGlsl.TryGetValue(type, out outputType)) - return outputType; - - outputType = ConvertType(targetType); - if (outputType != null) - return outputType; - } - - return node; - }); - } - - private TypeBase ConvertType(TypeBase targetType) - { - var targetTypeName = targetType.Name.Text; - - if ((targetTypeName.Equals("StructuredBuffer", StringComparison.Ordinal) || targetTypeName.Equals("RWStructuredBuffer", StringComparison.Ordinal)) - && targetType is IGenerics structuredBufferGenericType) - { - // Convert to "readonly buffer Name { GenericType Buffer; }; - var structuredBufferType = structuredBufferGenericType.GenericArguments[0]; - - var name = $"Stride_Internal_{structuredBufferType.Name.Text}_{++structedBufferCounter}"; - var bufferType = new Ast.Glsl.InterfaceType(name) - { - Qualifiers = Qualifier.None, // Assign buffer qualifier later as we want the ordering to be correct (readonly should come first) - Fields = [new Variable(new ArrayType(structuredBufferType, new EmptyExpression()), "Buffer")] - }; - - if (targetTypeName.Equals("StructuredBuffer", StringComparison.Ordinal)) - { - bufferType.Qualifiers |= GlslStorageQualifier.ReadOnly; - } - - bufferType.Qualifiers |= GlslStorageQualifier.Buffer; - - return bufferType; - } - - if (targetTypeName.StartsWith("Texture", StringComparison.Ordinal)) - targetTypeName = "texture" + targetTypeName["Texture".Length..]; - else if (targetTypeName.StartsWith("RWTexture", StringComparison.Ordinal)) - targetTypeName = "image" + targetTypeName["RWTexture".Length..]; - else if (targetTypeName.StartsWith("RWBuffer", StringComparison.Ordinal)) - targetTypeName = "imageBuffer"; - else if (targetTypeName.StartsWith("Buffer", StringComparison.Ordinal)) - targetTypeName = "textureBuffer"; - else return null; - - // TODO: How do we support this on OpenGL ES 2.0? Cast to int/uint on Load()/Sample()? - if (targetType is IGenerics genericSamplerType && genericSamplerType.GenericArguments.Count == 1) - { - var genericArgument = genericSamplerType.GenericArguments[0].ResolveType(); - if (TypeBase.GetBaseType(genericArgument) == ScalarType.UInt) - targetTypeName = "u" + targetTypeName; - else if (TypeBase.GetBaseType(genericArgument) == ScalarType.Int) - targetTypeName = "i" + targetTypeName; - } - - //// Handle comparison samplers - //if (needsComparison) - // targetTypeName += "Shadow"; - - return new TypeName(targetTypeName); - } - - /// - /// Transforms all variable declared with a multidimensional array to a single dimension. - /// - private void TransformArrayDimensions() - { - foreach (var variable in listOfMultidimensionArrayVariable) - { - Expression newSubscript = null; - - var arrayType = (ArrayType)variable.Type.ResolveType(); - var arrayElementType = arrayType.Type.ResolveType(); - - // float myarray[i1][i2][i3]...[in] => float myarray[(i1)*(i2)*(i3)*...*(in)] - foreach (var subscript in arrayType.Dimensions) - newSubscript = newSubscript == null ? subscript : new BinaryExpression(BinaryOperator.Multiply, newSubscript, subscript); - - // Set the new subscript - var newArrayType = new ArrayType { Type = new TypeName(arrayElementType) }; - newArrayType.Dimensions.Add(newSubscript); - variable.Type = newArrayType; - } - - // For arrays with dynamic dimension, we need to replace it with the actual number of initializers - foreach (var variable in shader.Declarations.OfType()) - { - var variableArrayType = variable.Type.ResolveType() as ArrayType; - if (variableArrayType != null) - { - if (variable.InitialValue != null) - { - var arrayInitializers = variable.InitialValue as MethodInvocationExpression; - if (arrayInitializers != null && variableArrayType.Dimensions.Count == 1) - { - var currentDimension = variableArrayType.Dimensions[0] as LiteralExpression; - if (currentDimension != null) - { - int currentDim = Convert.ToInt32(currentDimension.Literal.Value); - if (currentDim < arrayInitializers.Arguments.Count) - { - variableArrayType.Dimensions.Clear(); - variableArrayType.Dimensions.Add(new LiteralExpression(arrayInitializers.Arguments.Count)); - } - } - } - } - } - } - } - - /// - /// Converts an HLSL array initializer to a GLSL array initializer. - /// Example: - /// HLSL float[4] test = {1,2,3,4}; - /// GLSL float[4] test = float[](1,2,3,4); - /// - /// Type of the array. - /// The array initializer. - /// A converted array - private Expression ConvertArrayInitializer(ArrayType arrayType, ArrayInitializerExpression arrayInitializer) - { - var arrayElementType = arrayType.Type.ResolveType(); - - var newArrayExpression = new MethodInvocationExpression(new IndexerExpression(new TypeReferenceExpression(arrayType.Type), new LiteralExpression())); - var arrayItems = new List(); - FlattenArrayCreationExpression(arrayInitializer, arrayItems); - - // By default add array - newArrayExpression.Arguments.AddRange(arrayItems); - - // Convert array/vector initializer - // vec4 value[4] = vec4[4](0,0,0,0, 0,0,0,0, 0,0,0,0); to => vec4 value[4] = vec4[4](vec4(0,0,0,0), vec4(0,0,0,0), vec4(0,0,0,0)); - var vectorType = arrayElementType as VectorType; - if (vectorType != null) - { - // If there is exactly the same number of arguments and all arguments are primitives, then convert - if ((arrayItems.Count % vectorType.Dimension) == 0 && arrayItems.All(arg => (arg.TypeInference.TargetType is ScalarType))) - { - var arguments = new List(); - var vectorArgs = new List(); - foreach (var arg in arrayItems) - { - vectorArgs.Add(arg); - if (vectorArgs.Count == vectorType.Dimension) - { - arguments.Add(new MethodInvocationExpression(new TypeReferenceExpression(vectorType), vectorArgs.ToArray())); - vectorArgs.Clear(); - } - } - - newArrayExpression.Arguments = arguments; - } - } - - if (arrayType.IsDimensionEmpty) - { - arrayType.Dimensions.Clear(); - arrayType.Dimensions.Add(new LiteralExpression(newArrayExpression.Arguments.Count)); - } - - return newArrayExpression; - } - - /// - /// Converts an HLSL matrix initializer to a GLSL matrix initializer. - /// - /// Type of the matrix. - /// The initializers. - /// - /// A converted matrix - /// - private List ConvertMatrixInitializer(MatrixType matrixType, List initializers) - { - if (!NoSwapForBinaryMatrixOperation) - return initializers; - - var newInitializers = new List(); - - int columnCount = matrixType.ColumnCount; - int rowCount = matrixType.RowCount; - - // Initializers could be - // 1) matrix test = matrix( float4(row1), float4(row2), float4(row3), float4(row4) ); - // or - // 2) matrix test = matrix( 1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16); - if (rowCount == initializers.Count) - { - // Case 1) - // We need to transpose rows into columns - for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) - { - var columnInitializerType = new VectorType((ScalarType)matrixType.Type.ResolveType(), rowCount); - var columnInitializer = new MethodInvocationExpression(new TypeReferenceExpression(columnInitializerType)); - newInitializers.Add(columnInitializer); - - for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) - { - var elementIndexer = new IndexerExpression(initializers[rowIndex], new LiteralExpression(columnIndex)); - columnInitializer.Arguments.Add(elementIndexer); - } - } - } - else if ((rowCount * columnCount) == initializers.Count) - { - // Case 2) - // We need to transpose all the elements - for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) - { - for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) - { - newInitializers.Add(initializers[columnCount * rowIndex + columnIndex]); - } - } - } - else - { - newInitializers = initializers; - parserResult.Warning("Unable to convert matrix initializer [{0}] to matrix type [{1}]", matrixType.Span, string.Join(",", initializers), matrixType); - } - - return newInitializers; - } - - /// - /// Transforms the global multiple variable to single variable. - /// - private void TransformGlobalMultipleVariableToSingleVariable() - { - var declarations = new List(); - - foreach (var declaration in shader.Declarations) - { - var variable = declaration as Variable; - if (variable != null && variable.IsGroup) - { - foreach (var subVariable in variable.SubVariables) - { - // Copy Qualifiers - subVariable.Qualifiers = Qualifier.None; - subVariable.Qualifiers |= variable.Qualifiers; - declarations.Add(subVariable); - } - } - else - declarations.Add(declaration); - } - - shader.Declarations = declarations; - } - - - private static List GetMembers(StructType structType, List members = null, List fieldStack = null) - { - // Cache the members if they have been already calculated for a particular type - // Though, this is not realy efficient (should cache nested struct member reference...) - if (members == null) - { - members = (List)structType.GetTag("Members"); - if (members != null) - return members; - - members = new List(); - structType.SetTag("Members", members); - } - - if (fieldStack == null) - fieldStack = new List(); - - // Iterate on all fields to build the member references - foreach (var field in structType.Fields.SelectMany(item => item.Instances())) - { - var fieldType = field.Type.ResolveType(); - - // This is a "recursive" struct type - if (fieldType is StructType) - { - fieldStack.Add(field); - GetMembers((StructType)fieldType, members, fieldStack); - fieldStack.RemoveAt(fieldStack.Count - 1); - } - else - { - var structMember = new StructMemberReference(); - structMember.Field = field; - structMember.ParentFields.AddRange(fieldStack); - - var fieldPath = new StringBuilder(); - bool isFirst = true; - foreach (var parentField in Enumerable.Reverse(fieldStack)) - { - if (!isFirst) - fieldPath.Append("_"); - fieldPath.Append(parentField.Name); - isFirst = false; - } - - if (fieldPath.Length > 0) - fieldPath.Append("_"); - fieldPath.Append(field.Name); - - structMember.FieldNamePath = fieldPath.ToString(); - members.Add(structMember); - } - } - - return members; - } - - private static Expression NewCast(TypeBase type, Expression expression) - { - if (type != expression.TypeInference.TargetType) - { - var result = new MethodInvocationExpression(new TypeReferenceExpression(type), expression); - result.TypeInference.TargetType = type; - return result; - } - - return expression; - } - - private void ReorderVariableQualifiers() - { - foreach (var variable in shader.Declarations.OfType()) - { - variable.Qualifiers.Values.Sort(QualifierComparer.Default); - } - } - - /// - /// Apply std140 layout to all constant and storage buffers. - /// - private void ApplyStd140Layout() - { - foreach (var constantBuffer in shader.Declarations.OfType()) - { - var layoutQualifier = constantBuffer.Qualifiers.OfType().FirstOrDefault(); - if (layoutQualifier == null) - { - layoutQualifier = new LayoutQualifier(); - constantBuffer.Qualifiers |= layoutQualifier; - } - layoutQualifier.Layouts.Add(new LayoutKeyValue("std140")); - } - - foreach (var variable in shader.Declarations.OfType().Where(x => x.Type.Qualifiers.Contains(GlslStorageQualifier.Buffer))) - { - var layoutQualifier = variable.Qualifiers.OfType().FirstOrDefault(); - if (layoutQualifier == null) - { - layoutQualifier = new LayoutQualifier(); - variable.Qualifiers |= layoutQualifier; - } - layoutQualifier.Layouts.Add(new LayoutKeyValue("std430")); // But this is not std140? You are very much correct. - } - } - - private class StructMemberReference - { - public string FieldNamePath; - - public MemberReferenceExpression GetMemberReference(Expression target) - { - var currentMemberRef = new MemberReferenceExpression(target, Field.Name); - - foreach (var parentField in Enumerable.Reverse(ParentFields)) - { - currentMemberRef.Target = new MemberReferenceExpression(currentMemberRef.Target, parentField.Name); - } - return currentMemberRef; - } - - public List ParentFields = new List(); - - public Variable Field; - } - - class SemanticReference - { - public SemanticReference(string name, Expression variableReference) - { - this.Name = name; - this.VariableReference = variableReference; - } - - public string Name; - - public Expression VariableReference; - } - - #endregion - - /// - /// A Tag associated to a variable - /// - private class TagLayout - { - #region Constants and Fields - - public object Binding { get; set; } - - public object Location { get; set; } - - public string Name; - - public string Type; - - public Ast.Glsl.LayoutQualifier Qualifier; - - #endregion - } - - /// - /// Sort qualifiers: layout(xx) first, then others (out, int, etc...) - /// - class QualifierComparer : IComparer - { - public static readonly QualifierComparer Default = new QualifierComparer(); - - public int Compare(CompositeEnum x, CompositeEnum y) - { - int xOrder = x is LayoutQualifier ? 0 : 1; - int yOrder = y is LayoutQualifier ? 0 : 1; - - return xOrder.CompareTo(yOrder); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslWriter.cs b/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslWriter.cs deleted file mode 100644 index f0bf82160c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslWriter.cs +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Glsl; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Writer.Hlsl; -using InterfaceType = Stride.Core.Shaders.Ast.Hlsl.InterfaceType; -using LayoutQualifier = Stride.Core.Shaders.Ast.Glsl.LayoutQualifier; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// A writer for a shader. - /// - public class HlslToGlslWriter : HlslWriter - { - private readonly GlslShaderPlatform shaderPlatform; - private readonly int shaderVersion; - private readonly PipelineStage pipelineStage; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// if set to true [use node stack]. - /// - public HlslToGlslWriter(GlslShaderPlatform shaderPlatform, int shaderVersion, PipelineStage pipelineStage, bool useNodeStack = false) - : base(useNodeStack) - { - this.shaderPlatform = shaderPlatform; - this.shaderVersion = shaderVersion; - this.pipelineStage = pipelineStage; - - if (shaderPlatform == GlslShaderPlatform.OpenGLES) - { - TrimFloatSuffix = true; - - GenerateUniformBlocks = shaderVersion >= 300; - SupportsTextureBuffer = shaderVersion >= 320; - } - } - - #endregion - - public bool GenerateUniformBlocks { get; set; } = true; - - public bool TrimFloatSuffix { get; set; } = false; - - public bool SupportsTextureBuffer { get; set; } = true; - - public string ExtraHeaders { get; set; } - - public List Extensions { get; } = []; - - #region Public Methods - - /// - public override void Visit(Shader shader) - { - // #version - Write("#version "); - Write(shaderVersion.ToString()); - - // ES3+ expects "es" at the end of #version - if (shaderPlatform == GlslShaderPlatform.OpenGLES && shaderVersion >= 300) - Write(" es"); - - WriteLine(); - - foreach (var extension in Extensions) - { - WriteLine($"#extension {extension} : enable"); - } - - WriteLine(); - - if (shaderPlatform == GlslShaderPlatform.OpenGLES) - { - WriteLine("precision highp float;"); - WriteLine("precision highp int;"); - - if (shaderVersion >= 300) - { - WriteLine("precision lowp sampler3D;"); - WriteLine("precision lowp samplerCubeShadow;"); - WriteLine("precision lowp sampler2DShadow;"); - WriteLine("precision lowp sampler2DArray;"); - WriteLine("precision lowp sampler2DArrayShadow;"); - WriteLine("precision lowp isampler2D;"); - WriteLine("precision lowp isampler3D;"); - WriteLine("precision lowp isamplerCube;"); - WriteLine("precision lowp isampler2DArray;"); - WriteLine("precision lowp usampler2D;"); - WriteLine("precision lowp usampler3D;"); - WriteLine("precision lowp usamplerCube;"); - WriteLine("precision lowp usampler2DArray;"); - } - - if (shaderVersion >= 320 || SupportsTextureBuffer) - { - WriteLine("precision lowp samplerBuffer;"); - WriteLine("precision lowp isamplerBuffer;"); - WriteLine("precision lowp usamplerBuffer;"); - } - - WriteLine(); - - if (shaderVersion < 320 && SupportsTextureBuffer) - { - // In ES 3.1 and previous, we use texelFetchBuffer in case it needs to be remapped into something else by user - WriteLine("#define texelFetchBuffer(sampler, P) texelFetch(sampler, P)"); - } - } - - if (ExtraHeaders != null) - WriteLine(ExtraHeaders); - - if (shader == null) - { - // null entry point for pixel shader means no pixel shader. In that case, we return a default function. - // TODO: support that directly in HlslToGlslConvertor? - if (pipelineStage == PipelineStage.Pixel) - { - WriteLine("out float fragmentdepth; void main(){ fragmentdepth = gl_FragCoord.z; }"); - } - else - { - throw new NotSupportedException($"Can't output empty {pipelineStage} shader for platform {shaderPlatform} version {shaderVersion}."); - } - } - else - { - base.Visit(shader); - } - } - - /// - public override void Visit(Literal literal) - { - if (TrimFloatSuffix && literal.Value is float) - literal.Text = literal.Text.Trim('f', 'F', 'l', 'L'); - - base.Visit(literal); - } - - /// - public override void Visit(Ast.Glsl.InterfaceType interfaceType) - { - Write(interfaceType.Qualifiers, true); - - Write(" "); - Write(interfaceType.Name); - WriteSpace(); - - // Post Attributes - Write(interfaceType.Attributes, false); - - OpenBrace(); - - foreach (var variableDeclaration in interfaceType.Fields) - VisitDynamic(variableDeclaration); - - CloseBrace(false); - - if (IsDeclaratingVariable.Count == 0 || !IsDeclaratingVariable.Peek()) - { - Write(";").WriteLine(); - } - } - - /// - public override void Visit(Ast.Hlsl.Annotations annotations) - { - } - - /// - public override void Visit(ClassType classType) - { - } - - /// - public override void Visit(InterfaceType interfaceType) - { - } - - /// - public override void Visit(AsmExpression asmExpression) - { - } - - /// - public override void Visit(ConstantBuffer constantBuffer) - { - // Flatten the constant buffers - if (constantBuffer.Members.Count > 0) - { - if (GenerateUniformBlocks) - { - if (constantBuffer.Register != null) - { - var layoutQualifier = constantBuffer.Qualifiers.OfType().FirstOrDefault(); - if (layoutQualifier == null) - { - layoutQualifier = new Stride.Core.Shaders.Ast.Glsl.LayoutQualifier(); - constantBuffer.Qualifiers |= layoutQualifier; - } - - layoutQualifier.Layouts.Insert(0, new LayoutKeyValue("binding", constantBuffer.Register.Register)); - } - Write(constantBuffer.Qualifiers, true); - Write("uniform").Write(" ").Write(constantBuffer.Name).WriteSpace().Write("{").WriteLine(); - Indent(); - VisitList(constantBuffer.Members); - } - else - { - Write("// Begin cbuffer ").Write(constantBuffer.Name).WriteLine(); - foreach (var member in constantBuffer.Members) - { - // Prefix each variable with "uniform " - if (member is Variable) - { - Write("uniform"); - Write(" "); - } - VisitDynamic(member); - } - } - - if (GenerateUniformBlocks) - { - Outdent(); - Write("};").WriteLine(); - } - else - { - Write("// End buffer ").Write(constantBuffer.Name).WriteLine(); - } - } - } - - /// - public override void Visit(Typedef typedef) - { - } - - /// - public override void Visit(AttributeDeclaration attributeDeclaration) - { - if (pipelineStage == PipelineStage.Compute && attributeDeclaration.Name == "numthreads") - { - if (attributeDeclaration.Parameters.Count == 1) - { - WriteLine($"layout(local_size_x={attributeDeclaration.Parameters[0].Value}) in;"); - } - else if (attributeDeclaration.Parameters.Count == 2) - { - WriteLine($"layout(local_size_x={attributeDeclaration.Parameters[0].Value}, local_size_y={attributeDeclaration.Parameters[1].Value}) in;"); - } - else if (attributeDeclaration.Parameters.Count == 3) - { - WriteLine($"layout(local_size_x={attributeDeclaration.Parameters[0].Value}, local_size_y={attributeDeclaration.Parameters[1].Value}, local_size_z={attributeDeclaration.Parameters[2].Value}) in;"); - } - } - } - - /// - public override void Visit(CastExpression castExpression) - { - } - - /// - /// Visits the specified technique. - /// - /// The technique. - public override void Visit(Technique technique) - { - } - - /// - public override void Visit(StateInitializer stateInitializer) - { - } - - /// - public override void Visit(StateExpression stateExpression) - { - } - - /// - public override void Visit(Semantic semantic) - { - } - - /// - public override void Visit(PackOffset packOffset) - { - } - - /// - public override void Visit(RegisterLocation registerLocation) - { - } - - /// - public override void Visit(Ast.Glsl.LayoutQualifier layoutQualifier) - { - Write("layout("); - for (int i = 0; i < layoutQualifier.Layouts.Count; i++) - { - var layout = layoutQualifier.Layouts[i]; - if (i > 0) Write(",").WriteSpace(); - Write(layout.Name); - if (layout.Value != null) - { - WriteSpace().Write("=").WriteSpace(); - base.Visit(layout.Value); - } - } - Write(")"); - WriteSpace(); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/HlslTypes.cs b/sources/shaders/Stride.Core.Shaders/Convertor/HlslTypes.cs deleted file mode 100644 index 55a7109c8a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/HlslTypes.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Globalization; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Convertor -{ - public static class HlslTypes - { - /// - /// Gets the type. - /// - /// The type. - /// A Typedeclaration and dimensions - public static Tuple GetType(string type) - { - string prefix = null; - if (type.StartsWith("matrix", StringComparison.Ordinal)) - { - var dimStr = type["matrix".Length..]; - if (dimStr.Length == 0) - { - return new Tuple(new MatrixType(), 4, 4); - } - - return new Tuple(new MatrixType(), int.Parse(dimStr[0].ToString()), int.Parse(dimStr[2].ToString())); - } - - TypeBase declaration = null; - - if (type.StartsWith("float", StringComparison.Ordinal)) - { - prefix = "float"; - declaration = ScalarType.Float; - } - else if (type.StartsWith("int", StringComparison.Ordinal)) - { - prefix = "int"; - declaration = ScalarType.Int; - } - else if (type.StartsWith("half", StringComparison.Ordinal)) - { - prefix = "half"; - declaration = ScalarType.Half; - } - else if (type.StartsWith("uint", StringComparison.Ordinal)) - { - prefix = "uint"; - declaration = ScalarType.UInt; - } - else if (type.StartsWith("bool", StringComparison.Ordinal)) - { - prefix = "bool"; - declaration = ScalarType.Bool; - } - else if (type.StartsWith("double", StringComparison.Ordinal)) - { - prefix = "double"; - declaration = ScalarType.Double; - } - - if (prefix == null) - { - return null; - } - - return new Tuple(declaration, int.Parse(type.Substring(prefix.Length, 1)), 0); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/Keywords.glsl b/sources/shaders/Stride.Core.Shaders/Convertor/Keywords.glsl deleted file mode 100644 index abdec5cc47..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/Keywords.glsl +++ /dev/null @@ -1,70 +0,0 @@ -// --------------------------------------------------------------------------------------------------------------------------- -// List of GLSL keywords -// According to the spec http://www.opengl.org/registry/doc/GLSLangSpec.4.20.6.clean.pdf -// Section "3.6 Keywords", p16-18 -// --------------------------------------------------------------------------------------------------------------------------- -// The following are the keywords in the language, and cannot be used for any other purpose than that defined by this document: - -attribute const uniform varying -coherent volatile restrict readonly writeonly -atomic_uint -layout -centroid flat smooth noperspective -patch sample -break continue do for while switch case default -if else -subroutine -in out inout -float double int void bool true false -invariant -discard return -mat2 mat3 mat4 dmat2 dmat3 dmat4 -mat2x2 mat2x3 mat2x4 dmat2x2 dmat2x3 dmat2x4 -mat3x2 mat3x3 mat3x4 dmat3x2 dmat3x3 dmat3x4 -mat4x2 mat4x3 mat4x4 dmat4x2 dmat4x3 dmat4x4 -vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 dvec2 dvec3 dvec4 -uint uvec2 uvec3 uvec4 -lowp mediump highp precision -sampler1D sampler2D sampler3D samplerCube -sampler1DShadow sampler2DShadow samplerCubeShadow -sampler1DArray sampler2DArray -sampler1DArrayShadow sampler2DArrayShadow -isampler1D isampler2D isampler3D isamplerCube -isampler1DArray isampler2DArray -usampler1D usampler2D usampler3D usamplerCube -usampler1DArray usampler2DArray -sampler2DRect sampler2DRectShadow isampler2DRect usampler2DRect -samplerBuffer isamplerBuffer usamplerBuffer -sampler2DMS isampler2DMS usampler2DMS -sampler2DMSArray isampler2DMSArray usampler2DMSArray -samplerCubeArray samplerCubeArrayShadow isamplerCubeArray usamplerCubeArray -image1D iimage1D uimage1D -image2D iimage2D uimage2D -image3D iimage3D uimage3D -image2DRect iimage2DRect uimage2DRect -imageCube iimageCube uimageCube -imageBuffer iimageBuffer uimageBuffer -image1DArray iimage1DArray uimage1DArray -image2DArray iimage2DArray uimage2DArray -imageCubeArray iimageCubeArray uimageCubeArray -image2DMS iimage2DMS uimage2DMS -image2DMSArray iimage2DMSArray uimage2DMSArray -struct - -// The following are the keywords reserved for future use. Using them will result in an error: -common partition active -asm -class union enum typedef template this packed -resource -goto -inline noinline public static extern external interface -long short half fixed unsigned superp -input output -hvec2 hvec3 hvec4 fvec2 fvec3 fvec4 -sampler3DRect -filter -sizeof cast -namespace using -row_major - -//In addition, all identifiers containing two consecutive underscores (__) are reserved as possible future keywords. \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/MapRule.cs b/sources/shaders/Stride.Core.Shaders/Convertor/MapRule.cs deleted file mode 100644 index c5e8eaa95c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/MapRule.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Convertor -{ - /// - /// A map rule for types. - /// - public class MapRule - { - /// - /// Gets or sets the name. - /// - /// - /// The name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the type. - /// - /// - /// The type. - /// - public string Type { get; set; } - - /// - public override string ToString() - { - return string.Format("", this.Name, this.Type); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/PipelineStage.cs b/sources/shaders/Stride.Core.Shaders/Convertor/PipelineStage.cs deleted file mode 100644 index 3b40110a9f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/PipelineStage.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// Enum to specify pipeline stage. - /// - public enum PipelineStage - { - Vertex = 0, - Hull = 1, - Domain = 2, - Geometry = 3, - Pixel = 4, - Compute = 5, - None = 6, - } - - /// - /// Helper functions for . - /// - public static class PipelineStageHelper - { - /// - /// Parse a pipeline stage from string. - /// - /// The stage in string form. - /// If stage string is an invalid string. - /// A PipelineStage value. - public static PipelineStage FromString(string stage) - { - switch (stage.ToLowerInvariant()) - { - case "vs": - case "vertex": - return PipelineStage.Vertex; - case "ps": - case "pixel": - return PipelineStage.Pixel; - case "gs": - case "geometry": - return PipelineStage.Geometry; - } - - throw new ArgumentException("stage is invalid. Must be vs/vertex, ps/pixel, gs/geometry.", "stage"); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/SamplerMappingVisitor.cs b/sources/shaders/Stride.Core.Shaders/Convertor/SamplerMappingVisitor.cs deleted file mode 100644 index df60a525b8..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/SamplerMappingVisitor.cs +++ /dev/null @@ -1,649 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Globalization; -using System.Collections.Generic; -using System.Text; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// Collect the texture and sampler pair used in the HLSL shader. - /// - class SamplerMappingVisitor : CallstackVisitor - { - private Dictionary samplerMapping; - private HashSet textureAccesses; - private Shader shader; - private List textureSamplerMethods = new List(); - private static readonly string ScopeValueKey = "ScopeValue"; - private CloneContext cloneContext = new CloneContext(); - - public SamplerMappingVisitor(Shader shader, Dictionary samplerMapping) - { - this.shader = shader; - this.samplerMapping = samplerMapping; - textureAccesses = new HashSet(); - - // Add all global declarations for clone context in order to avoid any clone on this object - foreach (var variable in shader.Declarations) - { - cloneContext.Add(variable, variable); - } - } - - /// - /// Gets or sets a flag specifying whether compatibility profile is used for texture functions. - /// As an example, with compatibility on, texture() might become texture2D(). - /// - /// - /// true if texture compatibility profile is enabled, false if not. - /// - public bool TextureFunctionsCompatibilityProfile { get; set; } - - public override void Run(MethodDefinition methodEntry) - { - base.Run(methodEntry); - - var existingTextures = new HashSet(samplerMapping.Select(x => x.Key.Texture)); - foreach (var texture in textureAccesses) - { - if (!existingTextures.Contains(texture)) - GenerateGLSampler(null, texture); - } - - for (int i = this.textureSamplerMethods.Count - 1; i >= 0; i--) - { - var textureSamplerMethodKey = this.textureSamplerMethods[i]; - var entryIndex = shader.Declarations.IndexOf(textureSamplerMethodKey.Method); - this.shader.Declarations.Insert(entryIndex, textureSamplerMethodKey.NewMethod); - } - } - - private Variable FindParameterOrGlobalVariable(Expression expression) - { - var variableRef = expression as VariableReferenceExpression; - if (variableRef != null) - { - // Check if present in parameter list first. - MethodDeclaration currentFunction = null; - for (var i = NodeStack.Count - 1; i >= 0; i--) - { - if (NodeStack[i] is MethodDeclaration function) - { - currentFunction = function; - break; - } - } - if (currentFunction != null) - { - var parameter = currentFunction.Parameters.FirstOrDefault(x => x is Stride.Core.Shaders.Ast.Parameter param && param.Name == variableRef.Name); - if (parameter != null) - { - return parameter; - } - } - - return FindGlobalVariable(expression); - } - - return null; - } - - private Variable FindGlobalVariable(Expression expression) - { - var variableRef = expression as VariableReferenceExpression; - if (variableRef != null) - { - var variable = variableRef.TypeInference.Declaration as Variable; - - if (variable != null) - { - // If a variable has an initial value, find the global variable - if (!shader.Declarations.Contains(variable) && variable.InitialValue != null) - { - return this.FindGlobalVariable(variable.InitialValue); - } - - variable = (Variable)variable.GetTag(ScopeValueKey) ?? variable; - - // Is this a global variable? - if (shader.Declarations.Contains(variable)) - { - return variable; - } - } - } - return null; - } - - public override Node Visit(VariableReferenceExpression variableRef) - { - ((ScopeDeclarationWithRef)ScopeStack.Peek()).VariableReferences.Add(variableRef); - return variableRef; - } - - public override Node Visit(MethodInvocationExpression methodInvocationExpression) - { - // Visit first children - base.Visit(methodInvocationExpression); - - // Convert member expression - var variableRef = methodInvocationExpression.Target as VariableReferenceExpression; - var memberRef = methodInvocationExpression.Target as MemberReferenceExpression; - if (memberRef != null) - { - // TODO handle Texture2D - var textureVariable = FindParameterOrGlobalVariable(memberRef.Target); - - if (textureVariable != null) - { - var textureType = textureVariable.Type.ResolveType(); - - if (textureType is TextureType || (CultureInfo.InvariantCulture.CompareInfo.IsPrefix(textureType.Name.Text, "Texture", CompareOptions.IgnoreCase)) - || (textureType.IsBuiltIn && textureType.Name.Text.StartsWith("Buffer", StringComparison.Ordinal))) - { - switch (memberRef.Member) - { - case "Load": - { - GenerateGLSampler(null, textureVariable); - } - break; - case "GetDimensions": - { - textureAccesses.Add(textureVariable); - } - break; - case "Sample": - case "SampleBias": - case "SampleGrad": - case "SampleLevel": - case "SampleCmp": - case "SampleCmpLevelZero": - { - var sampler = this.FindGlobalVariable(methodInvocationExpression.Arguments[0]); - if (sampler == null) - throw new InvalidOperationException(string.Format("Unable to find sampler [{0}] as a global variable", - methodInvocationExpression.Arguments[0])); - - bool needsComparison = memberRef.Member == "SampleCmp" || memberRef.Member == "SampleCmpLevelZero"; - GenerateGLSampler(sampler, textureVariable, needsComparison); - } - break; - } - } - } - } - else if (variableRef != null) - { - string methodName = variableRef.Name.Text; - - // Transform texture fetch - var texFetchInfo = ParseTexFetch(methodName); - if (texFetchInfo != null) - { - var fetchInstructionSecondPart = string.Empty; - switch (texFetchInfo.Item2) - { - case TexFetchType.Default: - if (methodInvocationExpression.Arguments.Count == 4) - fetchInstructionSecondPart = "Grad"; - break; - case TexFetchType.Bias: - // Bias is encoded in w, so replicated argument and extract only w. Compiler/optimizer should do the rest of the job. - methodInvocationExpression.Arguments.Add(new MemberReferenceExpression(new ParenthesizedExpression(methodInvocationExpression.Arguments[1]), "w")); - break; - case TexFetchType.Grad: - fetchInstructionSecondPart = "Grad"; - break; - case TexFetchType.Proj: - fetchInstructionSecondPart = "Proj"; - break; - case TexFetchType.Lod: - fetchInstructionSecondPart = "Lod"; - - // LOD is encoded in w, so replicated argument and extract only w. Compiler/optimizer should do the rest of the job. - methodInvocationExpression.Arguments.Add(new MemberReferenceExpression(new ParenthesizedExpression(methodInvocationExpression.Arguments[1]), "w")); - break; - } - - if (TextureFunctionsCompatibilityProfile) - { - var stringBuilder = new StringBuilder("texture", 32); - if (texFetchInfo.Item1 == 4) - stringBuilder.Append("Cube"); - else - stringBuilder.Append(texFetchInfo.Item1).Append('D'); - stringBuilder.Append(fetchInstructionSecondPart); - variableRef.Name = stringBuilder.ToString(); - } - else - { - variableRef.Name = "texture" + fetchInstructionSecondPart; - } - - // TODO: Check how many components are required (for now it only do xy, but it might be x or xyz depending on texture dimension). - if (texFetchInfo.Item2 != TexFetchType.Proj) - { - var previousArgument = methodInvocationExpression.Arguments[1]; - var sizeOfArguments = texFetchInfo.Item1 == 4 ? 3 : texFetchInfo.Item1; - var vectorType = previousArgument.TypeInference.TargetType as VectorType; - - // If argument type is not the size of the expected argument, use explicit swizzle - if (vectorType == null || vectorType.Dimension != sizeOfArguments) - methodInvocationExpression.Arguments[1] = new MemberReferenceExpression(new ParenthesizedExpression(previousArgument), "xyzw".Substring(0, sizeOfArguments)); - } - - // Add the sampler - var samplerRefExpr = methodInvocationExpression.Arguments[0] as VariableReferenceExpression; - if (samplerRefExpr != null) - { - var samplerVariable = samplerRefExpr.TypeInference.Declaration as Variable; - var newSamplerType = texFetchInfo.Item1 < 4 ? new ObjectType("sampler" + texFetchInfo.Item1 + "D") : new ObjectType("samplerCube"); - this.ChangeVariableType(samplerVariable, newSamplerType); - } - } - } - - return methodInvocationExpression; - } - - private void ChangeVariableType(Variable samplerVariable, TypeBase newType) - { - if (samplerVariable != null) - { - samplerVariable.Type = newType; - if (samplerVariable is Parameter) - { - return; - } - - var variableInitialValue = samplerVariable.InitialValue as VariableReferenceExpression; - if (variableInitialValue != null) - { - this.ChangeVariableType(variableInitialValue.TypeInference.Declaration as Variable, newType); - } - } - } - - protected override void ProcessMethodInvocation(MethodInvocationExpression invoke, MethodDefinition method) - { - var textureParameters = new List(); - var parameterValues = new List(); - var parameterGlobalValues = new List(); - - var samplerTypes = new List(); - - for (int i = 0; i < method.Parameters.Count; i++) - { - var parameter = method.Parameters[i]; - if (parameter.Type is TextureType || parameter.Type.IsStateType()) - { - textureParameters.Add(parameter); - - // Find global variable - var parameterValue = this.FindGlobalVariable(invoke.Arguments[i]); - - // Set the tag ScopeValue for the current parameter - parameter.SetTag(ScopeValueKey, parameterValue); - - // Add only new variable - if (!parameterGlobalValues.Contains(parameterValue)) - parameterGlobalValues.Add(parameterValue); - } - else if ( i < invoke.Arguments.Count) - { - parameterValues.Add(invoke.Arguments[i]); - if (parameter.Type.IsSamplerType()) - { - samplerTypes.Add(i); - } - } - } - - // We have texture/sampler parameters. We need to generate a new specialized method - if (textureParameters.Count > 0) - { - // Order parameter values by name - parameterGlobalValues.Sort((left, right) => left.Name.Text.CompareTo(right.Name.Text)); - - var methodKey = new TextureSamplerMethodKey(method); - - int indexOf = textureSamplerMethods.IndexOf(methodKey); - - if (indexOf < 0) - { - methodKey.Initialize(cloneContext); - textureSamplerMethods.Add(methodKey); - } - else - { - // If a key is found again, add it as it was reused in order to keep usage in order - methodKey = textureSamplerMethods[indexOf]; - textureSamplerMethods.RemoveAt(indexOf); - textureSamplerMethods.Add(methodKey); - } - - methodKey.Invokers.Add(invoke); - - var newTarget = new VariableReferenceExpression(methodKey.NewMethod.Name) { TypeInference = { Declaration = methodKey.NewMethod, TargetType = invoke.TypeInference.TargetType } }; - invoke.Target = newTarget; - invoke.Arguments = parameterValues; - invoke.TypeInference.Declaration = methodKey.NewMethod; - invoke.TypeInference.TargetType = invoke.TypeInference.TargetType; - - this.VisitDynamic(methodKey.NewMethod); - } - else - { - // Visit the method callstack - this.VisitDynamic(method); - - // There is an anonymous sampler type - // We need to resolve its types after the method definition was processed - if (samplerTypes.Count > 0) - { - foreach (var samplerTypeIndex in samplerTypes) - { - var samplerRef = invoke.Arguments[samplerTypeIndex] as VariableReferenceExpression; - if (samplerRef != null) - { - var samplerDecl = samplerRef.TypeInference.Declaration as Variable; - ChangeVariableType(samplerDecl, method.Parameters[samplerTypeIndex].Type); - } - } - } - } - - // Remove temporary parameters - if (textureParameters.Count > 0) - { - foreach (var textureParameter in textureParameters) - { - textureParameter.RemoveTag(ScopeValueKey); - } - } - } - - /// - /// Generates a OpenGL sampler based on sampler/texture combination. - /// - /// The D3D sampler (can be null). - /// The D3D texture. - private void GenerateGLSampler(Variable sampler, Variable texture, bool needsComparison = false) - { - Variable glslSampler; - - if (texture == null) - throw new InvalidOperationException(); - - var samplerKey = new SamplerTextureKey(sampler, texture); - if (!samplerMapping.TryGetValue(samplerKey, out glslSampler)) - { - var samplerType = texture.Type.ResolveType(); - var samplerTypeName = samplerType.Name.Text; - - if (samplerTypeName.StartsWith("Texture", StringComparison.Ordinal)) - samplerTypeName = "sampler" + samplerTypeName["Texture".Length..]; - else if (samplerTypeName.StartsWith("Buffer", StringComparison.Ordinal)) - samplerTypeName = "samplerBuffer"; - - // TODO: How do we support this on OpenGL ES 2.0? Cast to int/uint on Load()/Sample()? - var genericSamplerType = samplerType as IGenerics; - if (genericSamplerType != null && genericSamplerType.GenericArguments.Count == 1) - { - var genericArgument = genericSamplerType.GenericArguments[0].ResolveType(); - if (TypeBase.GetBaseType(genericArgument) == ScalarType.UInt) - samplerTypeName = "u" + samplerTypeName; - else if (TypeBase.GetBaseType(genericArgument) == ScalarType.Int) - samplerTypeName = "i" + samplerTypeName; - } - - // Handle comparison samplers - if (needsComparison) - samplerTypeName += "Shadow"; - - glslSampler = new Variable(new TypeName(samplerTypeName), texture.Name + (sampler != null ? "_" + sampler.Name : "_NoSampler")) { Span = sampler == null ? texture.Span : sampler.Span }; - samplerMapping.Add(samplerKey, glslSampler); - } - } - - /// - /// Parses the texture fetch. - /// - /// - /// The name. - /// - /// - /// A tuple indicating the dimension and the - /// - private static Tuple ParseTexFetch(string name) - { - if (!name.StartsWith("tex", StringComparison.Ordinal)) - return null; - - name = name[3..]; - - int dimension; - - if (name.StartsWith("1D", StringComparison.Ordinal)) - dimension = 1; - else if (name.StartsWith("2D", StringComparison.Ordinal)) - dimension = 2; - else if (name.StartsWith("3D", StringComparison.Ordinal)) - dimension = 3; - else if (name.StartsWith("CUBE", StringComparison.Ordinal)) - dimension = 4; - else - return null; - - // Remove parsed size - name = name.Substring((dimension == 4) ? 4 : 2); - - TexFetchType fetchType; - switch (name) - { - case "": - fetchType = TexFetchType.Default; - break; - case "lod": - fetchType = TexFetchType.Lod; - break; - case "grad": - fetchType = TexFetchType.Grad; - break; - case "bias": - fetchType = TexFetchType.Bias; - break; - case "proj": - fetchType = TexFetchType.Proj; - break; - default: - return null; - } - - return new Tuple(dimension, fetchType); - } - - - /// - /// Texture fetch type. - /// - private enum TexFetchType - { - /// - /// Default fetch. - /// - Default, - - /// - /// Mipmap Lod fetch. - /// - Lod, - - /// - /// Gradient fetch. - /// - Grad, - - /// - /// Bias fetch. - /// - Bias, - - /// - /// Proj fetch. - /// - Proj, - } - - protected override ScopeDeclaration NewScope(IScopeContainer container = null) - { - return new ScopeDeclarationWithRef(container); - } - - private class ScopeDeclarationWithRef : ScopeDeclaration - { - public ScopeDeclarationWithRef() - : this(null) - { - } - - public ScopeDeclarationWithRef(IScopeContainer scopeContainer) - : base(scopeContainer) - { - VariableReferences = new List(); - } - - public List VariableReferences { get; private set; } - } - - - - private class TextureSamplerMethodKey - { - private string methodName; - - public TextureSamplerMethodKey(MethodDefinition method) - { - Invokers = new List(); - this.Method = method; - - Variables = new List(); - foreach (var parameter in Method.Parameters) - { - var variableValue = (Variable)parameter.GetTag(ScopeValueKey); - if (variableValue != null) - { - Variables.Add(variableValue); - } - } - } - - public List Invokers { get; set; } - - public void Initialize(CloneContext previousCloneContext) - { - // Clone original context - var cloneContext = new CloneContext(previousCloneContext); - - // Removes the method to clone - cloneContext.Remove(Method); - - // Clone the old method with the clone context - NewMethod = Method.DeepClone(cloneContext); - - var oldParameters = NewMethod.Parameters; - NewMethod.Parameters = new List(); - int j = 0; - for (int i = 0; i < oldParameters.Count; i++) - { - var parameter = oldParameters[i]; - var variableValue = (Variable)this.Method.Parameters[i].GetTag(ScopeValueKey); - if (variableValue != null) - { - this.NewMethod.Body.Insert(j, new DeclarationStatement(parameter)); - j++; - parameter.InitialValue = new VariableReferenceExpression(variableValue.Name) { TypeInference = { Declaration = variableValue, TargetType = variableValue.Type } }; - } - else - NewMethod.Parameters.Add(parameter); - } - - // Create new method with new method name - var methodNameBuild = new StringBuilder(); - methodNameBuild.Append(Method.Name); - foreach (var variable in Variables) - { - methodNameBuild.Append("_"); - methodNameBuild.Append(variable.Name); - } - methodName = methodNameBuild.ToString(); - NewMethod.Name = methodName; - } - - public MethodDefinition Method { get; private set; } - - public List Variables { get; private set; } - - public MethodDefinition NewMethod { get; private set; } - - public bool Equals(TextureSamplerMethodKey other) - { - if (ReferenceEquals(null, other)) - return false; - if (ReferenceEquals(this, other)) - return true; - - if (this.Variables.Count != other.Variables.Count) - return false; - - if (!ReferenceEquals(other.Method, this.Method)) - return false; - - for (int i = 0; i < this.Variables.Count; i++) - { - if (!ReferenceEquals(this.Variables[i], other.Variables[i])) - return false; - } - - return true; - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) - return false; - if (ReferenceEquals(this, obj)) - return true; - if (obj.GetType() != typeof(TextureSamplerMethodKey)) - return false; - return Equals((TextureSamplerMethodKey)obj); - } - - public override int GetHashCode() - { - unchecked - { - int result = 0; - foreach (var variable in Variables) - { - result = (result * 397) ^ variable.GetHashCode(); - } - result = (result * 397) ^ (this.Method != null ? this.Method.GetHashCode() : 0); - return result; - } - } - - public override string ToString() - { - return NewMethod == null ? "[" + Method.Name.Text + "]" : NewMethod.Name.Text; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/SamplerTextureKey.cs b/sources/shaders/Stride.Core.Shaders/Convertor/SamplerTextureKey.cs deleted file mode 100644 index a031b2ad78..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/SamplerTextureKey.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Convertor -{ - struct SamplerTextureKey : IEquatable - { - public Variable Sampler; - public Variable Texture; - - public SamplerTextureKey(Variable sampler, Variable texture) - { - Sampler = sampler; - Texture = texture; - } - - public bool Equals(SamplerTextureKey other) - { - if (Sampler == null && other.Sampler == null) - return Texture.Equals(other.Texture); - if (Sampler == null || other.Sampler == null) - return false; - return Sampler.Equals(other.Sampler) && Texture.Equals(other.Texture); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is SamplerTextureKey && Equals((SamplerTextureKey)obj); - } - - public override int GetHashCode() - { - unchecked - { - var hashcode = Sampler == null ? 1 : Sampler.GetHashCode(); - return (hashcode*397) ^ Texture.GetHashCode(); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/ShaderModel.cs b/sources/shaders/Stride.Core.Shaders/Convertor/ShaderModel.cs deleted file mode 100644 index deba58d1e3..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/ShaderModel.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Globalization; - -namespace Stride.Core.Shaders.Convertor -{ - /// - /// Describes a HLSL ShaderModel (SM2, SM3, SM4...etc.) - /// - public enum ShaderModel - { - /// - /// SM 1.1 - /// - Model11, - - /// - /// SM 2.0 - /// - Model20, - - /// - /// SM 3.0 - /// - Model30, - - /// - /// SM 4.0 - /// - Model40, - - /// - /// SM 4.1 - /// - Model41, - - /// - /// SM 5.0 - /// - Model50, - } - - internal class ShaderModelHelper - { - /// - /// Parses the specified short profile (4_0, 3_0, 5_0) - /// - /// The profile. - /// ShaderModel. - public static ShaderModel Parse(string profile) - { - var model = ShaderModel.Model30; - - switch (profile) - { - case "1_1": - model = ShaderModel.Model11; - break; - case "2_0": - model = ShaderModel.Model20; - break; - case "3_0": - model = ShaderModel.Model30; - break; - case "4_0": - model = ShaderModel.Model40; - break; - case "4_1": - model = ShaderModel.Model41; - break; - case "5_0": - model = ShaderModel.Model50; - break; - } - - return model; - } - - /// - /// Parses the specified full profile (vs_4_0) and output the stage as well. - /// - /// The profile. - /// The stage. - /// Return the ShaderModel default to 3.0 if not parsed correctly. - public static ShaderModel Parse(string profile, out PipelineStage stage) - { - profile = CultureInfo.InvariantCulture.TextInfo.ToLower(profile); - - if (profile.StartsWith("vs", StringComparison.Ordinal)) - stage = PipelineStage.Vertex; - else if (profile.StartsWith("ps", StringComparison.Ordinal)) - stage = PipelineStage.Pixel; - else if (profile.StartsWith("gs", StringComparison.Ordinal)) - stage = PipelineStage.Geometry; - else if (profile.StartsWith("cs", StringComparison.Ordinal)) - stage = PipelineStage.Compute; - else if (profile.StartsWith("hs", StringComparison.Ordinal)) - stage = PipelineStage.Hull; - else if (profile.StartsWith("ds", StringComparison.Ordinal)) - stage = PipelineStage.Domain; - else - { - stage = PipelineStage.None; - } - - return profile.Length > 4 ? Parse(profile[3..]) : ShaderModel.Model30; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Convertor/VariableLayoutRule.cs b/sources/shaders/Stride.Core.Shaders/Convertor/VariableLayoutRule.cs deleted file mode 100644 index b46a9df5be..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Convertor/VariableLayoutRule.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Convertor -{ - /// - /// A single map rule. - /// - public class VariableLayoutRule - { - /// - /// Gets or sets from name. - /// - /// - /// From name. - /// - public string Semantic { get; set; } - - /// - /// Gets or sets to name. - /// - /// - /// To name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the name output. - /// - /// - /// The name output. - /// - public string NameOutput { get; set; } - - /// - /// Gets or sets the location. - /// - /// - /// The location. - /// - public string Location { get; set; } - - /// - public override string ToString() - { - return string.Format("Semantic: {0}, Name: {1}, NameOutput: {2} Location: {3}", Semantic, Name, NameOutput, Location); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/DfaState.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/DfaState.cs deleted file mode 100644 index 8bed96fbd3..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/DfaState.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.Collections; - -#endregion - -namespace GoldParser -{ - /// - /// State in the Deterministic Finite Automata - /// which is used by the tokenizer. - /// - internal class DfaState - { - private int m_index; - internal Symbol m_acceptSymbol; - internal ObjectMap m_transitionVector; - - /// - /// Creates a new instance of the DfaState class. - /// - /// Index in the DFA state table. - /// Symbol to accept. - /// Transition vector. - public DfaState(int index, Symbol acceptSymbol, ObjectMap transitionVector) - { - m_index = index; - m_acceptSymbol = acceptSymbol; - m_transitionVector = transitionVector; - } - - /// - /// Gets index of the state in DFA state table. - /// - public int Index - { - get { return m_index; } - } - - /// - /// Gets the symbol which can be accepted in this DFA state. - /// - public Symbol AcceptSymbol - { - get { return m_acceptSymbol; } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/GoldParserException.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/GoldParserException.cs deleted file mode 100644 index 7545dfa8e8..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/GoldParserException.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -using System; - -namespace GoldParser -{ - public class GoldParserException : Exception - { - public GoldParserException(string message) : base(message) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/Grammar.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/Grammar.cs deleted file mode 100644 index 294ed65f77..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/Grammar.cs +++ /dev/null @@ -1,611 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.IO; -using System.Text; -using System.Collections; - -#endregion - -namespace GoldParser -{ - /// - /// Contains grammar tables required for parsing. - /// - internal class Grammar - { - #region Fields and constants - - /// - /// Identifies Gold parser grammar file. - /// - public const string FileHeader = "GOLD Parser Tables/v1.0"; - - // Grammar header information - private string m_name; // Name of the grammar - private string m_version; // Version of the grammar - private string m_author; // Author of the grammar - private string m_about; // Grammar description - private int m_startSymbolIndex; // Start symbol index - private bool m_caseSensitive; // Grammar is case sensitive or not - - // Tables read from the binary grammar file - private Symbol[] m_symbolTable; // Symbol table - private String[] m_charSetTable; // Charset table - internal Rule[] m_ruleTable; // Rule table - internal DfaState[] m_dfaStateTable; // DFA state table - internal LRState[] m_lrStateTable; // LR state table - - // Initial states - internal int m_dfaInitialStateIndex; // DFA initial state index - internal DfaState m_dfaInitialState; // DFA initial state - internal int m_lrInitialState; // LR initial state - - // Internal state of grammar parser - private BinaryReader m_reader; // Source of the grammar - private int m_entryCount; // Number of entries left - - internal Symbol m_errorSymbol; - internal Symbol m_endSymbol; - - #endregion - - #region Constructors - - /// - /// Creates a new instance of Grammar class - /// - /// - public Grammar(BinaryReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - m_reader = reader; - Load(); - } - - #endregion - - #region Public members - - /// - /// Gets the symbol table. - /// - public Symbol[] SymbolTable - { - get - { - return m_symbolTable; - } - } - - /// - /// Gets grammar name. - /// - public string Name - { - get { return m_name; } - } - - /// - /// Gets grammar version. - /// - public string Version - { - get { return m_version; } - } - - /// - /// Gets grammar author. - /// - public string Author - { - get { return m_author; } - } - - /// - /// Gets grammar description. - /// - public string About - { - get { return m_about; } - } - - /// - /// Gets the start symbol for the grammar. - /// - public Symbol StartSymbol - { - get { return m_symbolTable[m_startSymbolIndex]; } - } - - /// - /// Gets the value indicating if the grammar is case sensitive. - /// - public bool CaseSensitive - { - get { return m_caseSensitive; } - } - - /// - /// Gets initial DFA state. - /// - public DfaState DfaInitialState - { - get { return m_dfaInitialState; } - } - - /// - /// Gets initial LR state. - /// - public LRState InitialLRState - { - get { return m_lrStateTable[m_lrInitialState]; } - } - - /// - /// Gets a special symbol to designate last token in the input stream. - /// - public Symbol EndSymbol - { - get { return m_endSymbol; } - } - - #endregion - - #region Private members - - /// - /// Loads grammar from the binary reader. - /// - private void Load() - { - if (FileHeader != ReadString()) - { - throw new GoldParserException(SR.GetString(SR.Grammar_WrongFileHeader)); - } - while (m_reader.PeekChar() != -1) - { - RecordType recordType = ReadNextRecord(); - switch (recordType) - { - case RecordType.Parameters: - ReadHeader(); - break; - - case RecordType.TableCounts: - ReadTableCounts(); - break; - - case RecordType.Initial: - ReadInitialStates(); - break; - - case RecordType.Symbols: - ReadSymbols(); - break; - - case RecordType.CharSets: - ReadCharSets(); - break; - - case RecordType.Rules: - ReadRules(); - break; - - case RecordType.DfaStates: - ReadDfaStates(); - break; - - case RecordType.LRStates: - ReadLRStates(); - break; - - default: - throw new GoldParserException(SR.GetString(SR.Grammar_InvalidRecordType)); - } - } - m_dfaInitialState = m_dfaStateTable[m_dfaInitialStateIndex]; - OptimizeDfaTransitionVectors(); - } - - /// - /// Reads the next record in the binary grammar file. - /// - /// Read record type. - private RecordType ReadNextRecord() - { - char recordType = (char) ReadByte(); - //Structure below is ready for future expansion - switch (recordType) - { - case 'M': - //Read the number of entry's - m_entryCount = ReadInt16(); - return (RecordType) ReadByteEntry(); - - default: - throw new GoldParserException(SR.GetString(SR.Grammar_InvalidRecordHeader)); - } - } - - /// - /// Reads grammar header information. - /// - private void ReadHeader() - { - m_name = ReadStringEntry(); - m_version = ReadStringEntry(); - m_author = ReadStringEntry(); - m_about = ReadStringEntry(); - m_caseSensitive = ReadBoolEntry(); - m_startSymbolIndex = ReadInt16Entry(); - } - - /// - /// Reads table record counts and initializes tables. - /// - private void ReadTableCounts() - { - // Initialize tables - m_symbolTable = new Symbol [ReadInt16Entry()]; - m_charSetTable = new String [ReadInt16Entry()]; - m_ruleTable = new Rule [ReadInt16Entry()]; - m_dfaStateTable = new DfaState [ReadInt16Entry()]; - m_lrStateTable = new LRState [ReadInt16Entry()]; - } - - /// - /// Read initial DFA and LR states. - /// - private void ReadInitialStates() - { - m_dfaInitialStateIndex = ReadInt16Entry(); - m_lrInitialState = ReadInt16Entry(); - } - - /// - /// Read symbol information. - /// - private void ReadSymbols() - { - int index = ReadInt16Entry(); - string name = ReadStringEntry(); - SymbolType symbolType = (SymbolType) ReadInt16Entry(); - - Symbol symbol = new Symbol(index, name, symbolType); - switch (symbolType) - { - case SymbolType.Error: - m_errorSymbol = symbol; - break; - - case SymbolType.End: - m_endSymbol = symbol; - break; - } - m_symbolTable[index] = symbol; - } - - /// - /// Read char set information. - /// - private void ReadCharSets() - { - m_charSetTable[ReadInt16Entry()] = ReadStringEntry(); - } - - /// - /// Read rule information. - /// - private void ReadRules() - { - int index = ReadInt16Entry(); - Symbol nonTerminal = m_symbolTable[ReadInt16Entry()]; - ReadEmptyEntry(); - Symbol[] symbols = new Symbol[m_entryCount]; - for (int i = 0 ; i < symbols.Length; i++) - { - symbols[i] = m_symbolTable[ReadInt16Entry()]; - } - Rule rule = new Rule(index, nonTerminal, symbols); - m_ruleTable[index] = rule; - } - - /// - /// Read DFA state information. - /// - private void ReadDfaStates() - { - int index = ReadInt16Entry(); - Symbol acceptSymbol = null; - bool acceptState = ReadBoolEntry(); - if (acceptState) - { - acceptSymbol = m_symbolTable[ReadInt16Entry()]; - } - else - { - ReadInt16Entry(); // Skip the entry. - } - ReadEmptyEntry(); - - // Read DFA edges - DfaEdge[] edges = new DfaEdge[m_entryCount / 3]; - for (int i = 0; i < edges.Length; i++) - { - edges[i].CharSetIndex = ReadInt16Entry(); - edges[i].TargetIndex = ReadInt16Entry(); - ReadEmptyEntry(); - } - - // Create DFA state and store it in DFA state table - ObjectMap transitionVector = CreateDfaTransitionVector(edges); - DfaState dfaState = new DfaState(index, acceptSymbol, transitionVector); - m_dfaStateTable[index] = dfaState; - } - - /// - /// Read LR state information. - /// - private void ReadLRStates() - { - int index = ReadInt16Entry(); - ReadEmptyEntry(); - LRStateAction[] stateTable = new LRStateAction[m_entryCount / 4]; - for (int i = 0; i < stateTable.Length; i++) - { - Symbol symbol = m_symbolTable[ReadInt16Entry()]; - LRAction action = (LRAction) ReadInt16Entry(); - int targetIndex = ReadInt16Entry(); - ReadEmptyEntry(); - stateTable[i] = new LRStateAction(i, symbol, action, targetIndex); - } - - // Create the transition vector - LRStateAction[] transitionVector = new LRStateAction[m_symbolTable.Length]; - for (int i = 0; i < transitionVector.Length; i++) - { - transitionVector[i] = null; - } - for (int i = 0; i < stateTable.Length; i++) - { - transitionVector[stateTable[i].Symbol.Index] = stateTable[i]; - } - - LRState lrState = new LRState(index, stateTable, transitionVector); - m_lrStateTable[index] = lrState; - } - - /// - /// Creates the DFA state transition vector. - /// - /// Array of automata edges. - /// Hashtable with the transition information. - private ObjectMap CreateDfaTransitionVector(DfaEdge[] edges) - { - ObjectMap transitionVector = new ObjectMap(); - for (int i = edges.Length; --i >= 0;) - { - string charSet = m_charSetTable[edges[i].CharSetIndex]; - for (int j = 0; j < charSet.Length; j++) - { - transitionVector[charSet[j]] = edges[i].TargetIndex; - } - } - return transitionVector; - } - - /// - /// Reads empty entry from the grammar file. - /// - private void ReadEmptyEntry() - { - if (ReadEntryType() != EntryType.Empty) - { - throw new GoldParserException(SR.GetString(SR.Grammar_EmptyEntryExpected)); - } - m_entryCount--; - } - - /// - /// Reads string entry from the grammar file. - /// - /// String entry content. - private string ReadStringEntry() - { - if (ReadEntryType() != EntryType.String) - { - throw new GoldParserException(SR.GetString(SR.Grammar_StringEntryExpected)); - } - m_entryCount--; - return ReadString(); - } - - /// - /// Reads Int16 entry from the grammar file. - /// - /// Int16 entry content. - private int ReadInt16Entry() - { - if (ReadEntryType() != EntryType.Integer) - { - throw new GoldParserException(SR.GetString(SR.Grammar_IntegerEntryExpected)); - } - m_entryCount--; - return ReadInt16(); - } - - /// - /// Reads byte entry from the grammar file. - /// - /// Byte entry content. - private byte ReadByteEntry() - { - if (ReadEntryType() != EntryType.Byte) - { - throw new GoldParserException(SR.GetString(SR.Grammar_ByteEntryExpected)); - } - m_entryCount--; - return ReadByte(); - } - - /// - /// Reads boolean entry from the grammar file. - /// - /// Boolean entry content. - private bool ReadBoolEntry() - { - if (ReadEntryType() != EntryType.Boolean) - { - throw new GoldParserException(SR.GetString(SR.Grammar_BooleanEntryExpected)); - } - m_entryCount--; - return ReadBool(); - } - - /// - /// Reads entry type. - /// - /// Entry type. - private EntryType ReadEntryType() - { - if (m_entryCount == 0) - { - throw new GoldParserException(SR.GetString(SR.Grammar_NoEntry)); - } - return (EntryType) ReadByte(); - } - - /// - /// Reads string from the grammar file. - /// - /// String value. - private string ReadString() - { - StringBuilder result = new StringBuilder(); - char unicodeChar = (char) ReadInt16(); - while (unicodeChar != (char) 0) - { - result.Append(unicodeChar); - unicodeChar = (char) ReadInt16(); - } - return result.ToString(); - } - - /// - /// Reads two byte integer Int16 from the grammar file. - /// - /// Int16 value. - private int ReadInt16() - { - return m_reader.ReadUInt16(); - } - - /// - /// Reads byte from the grammar file. - /// - /// Byte value. - private byte ReadByte() - { - return m_reader.ReadByte(); - } - - /// - /// Reads boolean from the grammar file. - /// - /// Boolean value. - private bool ReadBool() - { - return (ReadByte() == 1); - } - - private void OptimizeDfaTransitionVectors() - { - DfaState[] dfaStates = m_dfaStateTable; - foreach (DfaState state in dfaStates) - { - ObjectMap transitions = state.m_transitionVector; - for (int i = transitions.Count; --i >= 0;) - { - int key = transitions.GetKey(i); - object transition = transitions[key]; - if (transition != null) - { - int transitionIndex = (int) transition; - if (transitionIndex >= 0) - { - transitions[key] = dfaStates[transitionIndex]; - } - else - { - transitions[key] = null; - } - } - } - transitions.ReadOnly = true; - } - } - - #endregion - - #region Private type definitions - - /// - /// Record type byte in the binary grammar file. - /// - private enum RecordType - { - Parameters = (int) 'P', // 80 - TableCounts = (int) 'T', // 84 - Initial = (int) 'I', // 73 - Symbols = (int) 'S', // 83 - CharSets = (int) 'C', // 67 - Rules = (int) 'R', // 82 - DfaStates = (int) 'D', // 68 - LRStates = (int) 'L', // 76 - Comment = (int) '!' // 33 - } - - /// - /// Entry type byte in the binary grammar file. - /// - private enum EntryType - { - Empty = (int) 'E', // 69 - Integer = (int) 'I', // 73 - String = (int) 'S', // 83 - Boolean = (int) 'B', // 66 - Byte = (int) 'b' // 98 - } - - /// - /// Edge between DFA states. - /// - private struct DfaEdge - { - public int CharSetIndex; - public int TargetIndex; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/LRAction.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/LRAction.cs deleted file mode 100644 index c80adbb178..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/LRAction.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// LR parser action type. - /// - internal enum LRAction - { - /// - /// No action. Not used. - /// - None = 0, - - /// - /// Shift a symbol and go to a state - /// - Shift = 1, - - /// - /// Reduce by a specified rule - /// - Reduce = 2, - - /// - /// Goto to a state on reduction - /// - Goto = 3, - - /// - /// Input successfully parsed - /// - Accept = 4, - - /// - /// Error - /// - Error = 5 - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/LRState.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/LRState.cs deleted file mode 100644 index 6c796e762c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/LRState.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// State of LR parser. - /// - internal class LRState - { - private int m_index; - private LRStateAction[] m_actions; - internal LRStateAction[] m_transitionVector; - - /// - /// Creates a new instance of the LRState class - /// - /// Index of the LR state in the LR state table. - /// List of all available LR actions in this state. - /// Transition vector which has symbol index as an index. - public LRState(int index, LRStateAction[] actions, LRStateAction[] transitionVector) - { - m_index = index; - m_actions = actions; - m_transitionVector = transitionVector; - } - - /// - /// Gets index of the LR state in LR state table. - /// - public int Index - { - get { return m_index; } - } - - /// - /// Gets LR state action count. - /// - public int ActionCount - { - get { return m_actions.Length; } - } - - /// - /// Returns state action by its index. - /// - /// State action index. - /// LR state action for the given index. - public LRStateAction GetAction(int index) - { - return m_actions[index]; - } - - /// - /// Returns LR state action by symbol index. - /// - /// Symbol Index to search for. - /// LR state action object. - public LRStateAction GetActionBySymbolIndex(int symbolIndex) - { - return m_transitionVector[symbolIndex]; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/LRStateAction.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/LRStateAction.cs deleted file mode 100644 index 598a5ac375..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/LRStateAction.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// Action in a LR State. - /// - internal class LRStateAction - { - private int m_index; - private Symbol m_symbol; - private LRAction m_action; - internal int m_value; - - /// - /// Creats a new instance of the LRStateAction class. - /// - /// Index of the LR state action. - /// Symbol associated with the action. - /// Action type. - /// Action value. - public LRStateAction(int index, Symbol symbol, LRAction action, int value) - { - m_index = index; - m_symbol = symbol; - m_action = action; - m_value = value; - } - - /// - /// Gets index of the LR state action. - /// - public int Index - { - get { return m_index; } - } - - /// - /// Gets symbol associated with the LR state action. - /// - public Symbol Symbol - { - get { return m_symbol; } - } - - /// - /// Gets action type. - /// - public LRAction Action - { - get { return m_action; } - } - - /// - /// Gets the action value. - /// - public int Value - { - get { return m_value; } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/License.txt b/sources/shaders/Stride.Core.Shaders/GoldParser/License.txt deleted file mode 100644 index 2dfc5b17c4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/License.txt +++ /dev/null @@ -1,22 +0,0 @@ - The GOLD Parser Freeware License Agreement - ========================================== - -This software is provided 'as-is', without any expressed or implied warranty. -In no event will the authors be held liable for any damages arising from the -use of this software. - -Permission is granted to anyone to use this software for any purpose. If you -use this software in a product, an acknowledgment in the product documentation -would be deeply appreciated but is not required. - -In the case of the GOLD Parser Engine source code, permission is granted to -anyone to alter it and redistribute it freely, subject to the following -restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. - - 2. Altered source versions must be plainly marked as such, and must not - be misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source distribution \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/ObjectMap.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/ObjectMap.cs deleted file mode 100644 index 72d28675b2..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/ObjectMap.cs +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// Maps integer values used for transition vectors to objects. - /// - internal class ObjectMap - { - #region Fields - - private bool m_readonly; - private MapProvider m_mapProvider; - - private const int MAXINDEX = 255; - private const int GROWTH = 32; - private const int MINSIZE = 32; - private const int MAXARRAYCOUNT = 12; - - private const int INVALIDKEY = Int32.MaxValue; - - #endregion - - #region Constructors - - /// - /// Creates new instance of class. - /// - public ObjectMap() - { - m_mapProvider = new SortedMapProvider(MINSIZE); - } - - #endregion - - #region Public members. - - /// - /// Gets number of entries in the map. - /// - public int Count - { - get { return m_mapProvider.m_count; } - } - - /// - /// Gets or sets read only flag. - /// - public bool ReadOnly - { - get { return m_readonly; } - set - { - if (m_readonly != value) - { - SetMapProvider(value); - m_readonly = value; - } - } - } - - /// - /// Gets or sets value by key. - /// - public object this[int key] - { - get { return m_mapProvider[key]; } - set { m_mapProvider.Add(key, value); } - } - - /// - /// Returns key by index. - /// - /// Zero based index of the requested key. - /// Returns key for the given index. - public int GetKey(int index) - { - return m_mapProvider.GetEntry(index).Key; - } - - /// - /// Removes entry by its key. - /// - /// - public void Remove(int key) - { - m_mapProvider.Remove(key); - } - - /// - /// Adds a new key and value pair. - /// If key exists then value is applied to existing key. - /// - /// New key to add. - /// Value for the key. - public void Add(int key, object value) - { - m_mapProvider.Add(key, value); - } - - #endregion - - #region Private members - - private void SetMapProvider(bool readOnly) - { - int count = m_mapProvider.m_count; - MapProvider provider = m_mapProvider; - if (readOnly) - { - SortedMapProvider pr = m_mapProvider as SortedMapProvider; - if (pr.m_lastKey <= MAXINDEX) - { - provider = new IndexMapProvider(); - } - else if (count <= MAXARRAYCOUNT) - { - provider = new ArrayMapProvider(m_mapProvider.m_count); - } - } - else - { - if (! (provider is SortedMapProvider)) - { - provider = new SortedMapProvider(m_mapProvider.m_count); - } - } - if (provider != m_mapProvider) - { - for (int i = 0; i < count; i++) - { - Entry entry = m_mapProvider.GetEntry(i); - provider.Add(entry.Key, entry.Value); - } - m_mapProvider = provider; - } - } - - #endregion - - #region Entry struct definition - - private struct Entry - { - internal int Key; - internal object Value; - - internal Entry(int key, object value) - { - Key = key; - Value = value; - } - } - - #endregion - - private abstract class MapProvider - { - internal int m_count; // Entry count in the collection. - - internal abstract object this[int key] - { - get; - } - - internal abstract Entry GetEntry(int index); - - internal abstract void Add(int key, object value); - - internal virtual void Remove(int key) - { - throw new InvalidOperationException(); - } - } - - private class SortedMapProvider : MapProvider - { - internal Entry[] m_entries; // Array of entries. - - internal int m_lastKey; // Bigest key number. - - internal SortedMapProvider(int capacity) - { - m_entries = new Entry[capacity]; - } - - internal override object this[int key] - { - get - { - int minIndex = 0; - int maxIndex = m_count - 1; - if (maxIndex >= 0 && key <= m_lastKey) - { - do - { - int midIndex = (maxIndex + minIndex) / 2; - if (key <= m_entries[midIndex].Key) - { - maxIndex = midIndex; - } - else - { - minIndex = midIndex + 1; - } - } while (minIndex < maxIndex); - if (key == m_entries[minIndex].Key) - { - return m_entries[minIndex].Value; - } - } - return null; - } - } - - internal override Entry GetEntry(int index) - { - return m_entries[index]; - } - - internal override void Add(int key, object value) - { - bool found; - int index = FindInsertIndex(key, out found); - if (found) - { - m_entries[index].Value = value; - return; - } - if (m_count >= m_entries.Length) - { - Entry[] entries = new Entry[m_entries.Length + GROWTH]; - Array.Copy(m_entries, 0, entries, 0, m_entries.Length); - m_entries = entries; - } - if (index < m_count) - { - Array.Copy(m_entries, index, m_entries, index + 1, m_count - index); - } - else - { - m_lastKey = key; - } - m_entries[index].Key = key; - m_entries[index].Value = value; - m_count++; - } - - internal override void Remove(int key) - { - int index = FindIndex(key); - if (index >= 0) - { - int tailSize = (m_count - 1) - index; - if (tailSize > 0) - { - Array.Copy(m_entries, index + 1, m_entries, index, tailSize); - } - else if (m_count > 1) - { - m_lastKey = m_entries[m_count - 2].Key; - } - else - { - m_lastKey = INVALIDKEY; - } - m_count--; - m_entries[m_count].Key = INVALIDKEY; - m_entries[m_count].Value = null; - } - } - - private int FindIndex(int key) - { - int minIndex = 0; - if (m_count > 0 && key <= m_lastKey) - { - int maxIndex = m_count - 1; - do - { - int midIndex = (maxIndex + minIndex) / 2; - if (key <= m_entries[midIndex].Key) - { - maxIndex = midIndex; - } - else - { - minIndex = midIndex + 1; - } - } while (minIndex < maxIndex); - if (key == m_entries[minIndex].Key) - { - return minIndex; - } - } - return -1; - } - - private int FindInsertIndex(int key, out bool found) - { - int minIndex = 0; - if (m_count > 0 && key <= m_lastKey) - { - int maxIndex = m_count - 1; - do - { - int midIndex = (maxIndex + minIndex) / 2; - if (key <= m_entries[midIndex].Key) - { - maxIndex = midIndex; - } - else - { - minIndex = midIndex + 1; - } - } while (minIndex < maxIndex); - found = (key == m_entries[minIndex].Key); - return minIndex; - } - found = false; - return m_count; - } - } - - private class IndexMapProvider : MapProvider - { - private object[] m_array; // Array of entries. - - internal IndexMapProvider() - { - m_array = new object[MAXINDEX + 1]; - for (int i = m_array.Length; --i >= 0; ) - { - m_array[i] = Unassigned.Value; - } - } - - internal override object this[int key] - { - get - { - if (key >= m_array.Length || key < 0) - { - return null; - } - return m_array[key]; - } - } - - internal override Entry GetEntry(int index) - { - int idx = -1; - for (int i = 0; i < m_array.Length; i++) - { - object value = m_array[i]; - if (value != Unassigned.Value) - { - idx++; - } - if (idx == index) - { - return new Entry(i, value); - } - } - return new Entry(); - } - - internal override void Add(int key, object value) - { - m_array[key] = value; - m_count++; - } - } - - private class ArrayMapProvider : MapProvider - { - private Entry[] m_entries; // Array of entries. - - internal ArrayMapProvider(int capacity) - { - m_entries = new Entry[capacity]; - } - - internal override object this[int key] - { - get - { - for (int i = m_count; --i >= 0;) - { - Entry entry = m_entries[i]; - int entryKey = entry.Key; - if (entryKey > key) - { - continue; - } - else if (entryKey == key) - { - return entry.Value; - } - else if (entryKey < key) - { - return null; - } - } - return null; - } - } - - internal override Entry GetEntry(int index) - { - return m_entries[index]; - } - - internal override void Add(int key, object value) - { - m_entries[m_count].Key = key; - m_entries[m_count].Value = value; - m_count++; - } - } - - private class Unassigned - { - internal static Unassigned Value = new Unassigned(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/ParseMessage.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/ParseMessage.cs deleted file mode 100644 index 585d4270dd..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/ParseMessage.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// Available parse messages. - /// - internal enum ParseMessage - { - /// - /// Nothing - /// - Empty = 0, - - /// - /// Each time a token is read, this message is generated. - /// - TokenRead = 1, - - /// - /// When the engine is able to reduce a rule, - /// this message is returned. The rule that was - /// reduced is set in the GOLDParser's ReduceRule property. - /// The tokens that are reduced and correspond the - /// rule's definition are stored in the Tokens() property. - /// - Reduction = 2, - - /// - /// The engine will returns this message when the source - /// text has been accepted as both complete and correct. - /// In other words, the source text was successfully analyzed. - /// - Accept = 3, - - /// - /// Before any parsing can take place, - /// a Compiled Grammar Table file must be loaded. - /// - NotLoadedError = 4, - - /// - /// The tokenizer will generate this message when - /// it is unable to recognize a series of characters - /// as a valid token. To recover, pop the invalid - /// token from the input queue. - /// - LexicalError = 5, - - /// - /// Often the parser will read a token that is not expected - /// in the grammar. When this happens, the Tokens() property - /// is filled with tokens the parsing engine expected to read. - /// To recover: push one of the expected tokens on the input queue. - /// - SyntaxError = 6, - - /// - /// The parser reached the end of the file while reading a comment. - /// This is caused when the source text contains a "run-away" - /// comment, or in other words, a block comment that lacks the - /// delimiter. - /// - CommentError = 7, - - /// - /// Something is wrong, very wrong. - /// - InternalError = 8, - - /// - /// A block comment is complete. - /// When this message is returned, the content of the CurrentComment - /// property is set to the comment text. The text includes starting and ending - /// block comment characters. - /// - CommentBlockRead = 9, - - /// - /// Line comment is read. - /// When this message is returned, the content of the CurrentComment - /// property is set to the comment text. The text includes starting - /// line comment characters. - /// - CommentLineRead = 10, - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/Parser.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/Parser.cs deleted file mode 100644 index c7ad657a4d..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/Parser.cs +++ /dev/null @@ -1,687 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.IO; -using System.Text; -using System.Collections; - -#endregion - -namespace GoldParser -{ - /// - /// Pull parser which uses Grammar table to parser input stream. - /// - internal sealed class Parser - { - #region Fields - - private Grammar m_grammar; // Grammar of parsed language. - private bool m_trimReductions = true; // Allowes to minimize reduction tree. - - private string m_buffer; // Buffer to keep current characters. - private int m_charIndex; // Index of character in the buffer. - private int m_preserveChars; // Number of characters to preserve when buffer is refilled. - private int m_lineStart; // Relative position of line start to the buffer beginning. - private int m_lineLength; // Length of current source line. - private int m_lineNumber = 1; // Current line number. - private int m_commentLevel; // Keeps stack level for embedded comments - - private SourceLineReadCallback m_sourceLineReadCallback; // Called when line reading finished. - - private Token m_token; // Current token - private Token[] m_inputTokens; // Stack of input tokens. - private int m_inputTokenCount; // How many tokens in the input. - - private LRStackItem[] m_lrStack; // Stack of LR states used for LR parsing. - private int m_lrStackIndex = 0; // Index of current LR state in the LR parsing stack. - private LRState m_lrState; // Current LR state. - private int m_reductionCount; // Number of items in reduction. It is Undefined if no reducton available. - private Symbol[] m_expectedTokens = null; // What tokens are expected in case of error? - - private const char EndOfString = (char) 0; // Designates last string terminator. - private const int MinimumInputTokenCount = 2; // Minimum input token stack size. - private const int MinimumLRStackSize = 256; // Minimum size of reduction stack. - private const int Undefined = -1; // Used for undefined int values. - - #endregion - - #region Constructors - - /// - /// Initializes new instance of Parser class. - /// - /// TextReader instance to read data from. - /// Grammar with parsing tables to parser input stream. - public Parser(Grammar grammar) - { - if (grammar == null) - { - throw new ArgumentNullException("grammar"); - } - - m_lineLength = Undefined; - - m_inputTokens = new Token[MinimumInputTokenCount]; - m_lrStack = new LRStackItem[MinimumLRStackSize]; - - m_grammar = grammar; - } - - public void SetSourceCode(string sourceCode) - { - m_buffer = sourceCode; - m_charIndex = 0; - m_lineStart = 0; - m_lineNumber = 1; - m_lineLength = Undefined; - // Put grammar start symbol into LR parsing stack. - m_lrState = m_grammar.InitialLRState; - m_lrStack[m_lrStackIndex] = new LRStackItem { m_token = { m_symbol = m_grammar.StartSymbol }}; - m_reductionCount = Undefined; // there are no reductions yet. - } - - #endregion - - #region Parser general properties - - /// - /// Gets the parser's grammar. - /// - public Grammar Grammar - { - get { return m_grammar; } - } - - /// - /// Gets or sets flag to trim reductions. - /// - public bool TrimReductions - { - get { return m_trimReductions; } - set { m_trimReductions = value; } - } - - #endregion - - #region Data Source properties and methods - - /// - /// Gets current char position. - /// - public int CharPosition - { - get { return m_charIndex; } - set { m_charIndex = value; } - } - - /// - /// Gets current line number. It is 1-based. - /// - public int LineNumber - { - get { return m_lineNumber; } - set { m_lineNumber = value; } - } - - /// - /// Gets current char position in the current source line. It is 1-based. - /// - public int LinePosition - { - get { return CharPosition - m_lineStart + 1; } - } - - public string TextBuffer - { - get - { - return m_buffer; - } - } - - /// - /// Gets current source line text. It can be truncated if line is longer than 2048 characters. - /// - public string LineText - { - get - { - int lineStart = Math.Max(m_lineStart, 0); - int lineLength; - if (m_lineLength == Undefined) - { - // Line was requested outside of SourceLineReadCallback call - lineLength = m_charIndex - lineStart; - } - else - { - lineLength = m_lineLength - (lineStart - m_lineStart); - } - if (lineLength > 0) - { - return m_buffer.Substring(lineStart, lineLength); - } - return string.Empty; - } - } - - /// - /// Gets or sets callback function to track source line text. - /// - public SourceLineReadCallback SourceLineReadCallback - { - get { return m_sourceLineReadCallback; } - set { m_sourceLineReadCallback = value; } - } - - /// - /// Increments current char index by delta character positions. - /// - /// Number to increment char index. - public void MoveBy(int delta) - { - for (int i = delta; --i >= 0;) - { - if (m_buffer[m_charIndex++] == '\n') - { - if (m_sourceLineReadCallback != null) - { - m_lineLength = m_charIndex - m_lineStart - 1; // Exclude '\n' - int lastIndex = m_lineStart + m_lineLength - 1; - if (lastIndex >= 0 && m_buffer[lastIndex] == '\r') - { - m_lineLength--; - } - if (m_lineLength < 0) - { - m_lineLength = 0; - } - m_sourceLineReadCallback(this, m_lineStart, m_lineLength); - } - m_lineNumber++; - m_lineStart = m_charIndex; - m_lineLength = Undefined; - } - if (m_buffer.Length == m_charIndex) - { - if (m_sourceLineReadCallback != null) - { - m_lineLength = m_charIndex - m_lineStart; - if (m_lineLength > 0) - { - m_sourceLineReadCallback(this, m_lineStart, m_lineLength); - } - m_lineLength = Undefined; - } - } - } - } - - /// - /// Moves current char pointer to the end of source line. - /// - private void MoveToLineEnd() - { - while (true) - { - if (m_buffer.Length == m_charIndex) return; - - char ch = m_buffer[m_charIndex]; - - if (ch == '\r' || ch == '\n') return; - - m_charIndex++; - } - } - - #endregion - - #region Tokenizer properties and methods - - /// - /// Gets or sets current token symbol. - /// - public Symbol TokenSymbol - { - get { return m_token.m_symbol; } - set { m_token.m_symbol = value; } - } - - /// - /// Gets or sets current token text. - /// - public string TokenText - { - get - { - if (m_token.m_text == null) - { - if (m_token.m_length > 0) - { - m_token.m_text = m_buffer.Substring(m_token.m_start, m_token.m_length); - } - else - { - m_token.m_text = string.Empty; - } - } - return m_token.m_text; - } - set { m_token.m_text = value; } - } - - /// - /// Gets or sets current token position relative to input stream beginning. - /// - public int TokenCharPosition - { - get { return m_token.m_start; } - set { m_token.m_start = value; } - } - - /// - /// Gets or sets current token text length. - /// - public int TokenLength - { - get { return m_token.m_length; } - set { m_token.m_length = value; } - } - - /// - /// Gets or sets current token line number. It is 1-based. - /// - public int TokenLineNumber - { - get { return m_token.m_lineNumber; } - set { m_token.m_lineNumber = value; } - } - - /// - /// Gets or sets current token position in current source line. It is 1-based. - /// - public int TokenLinePosition - { - get { return m_token.m_linePosition; } - set { m_token.m_linePosition = value; } - } - - /// - /// Gets or sets token syntax object associated with the current token or reduction. - /// - public object TokenSyntaxNode - { - get - { - if (m_reductionCount == Undefined) - { - return m_token.m_syntaxNode; - } - else - { - return m_lrStack[m_lrStackIndex].m_token.m_syntaxNode; - } - } - set - { - if (m_reductionCount == Undefined) - { - m_token.m_syntaxNode = value; - } - else - { - m_lrStack[m_lrStackIndex].m_token.m_syntaxNode = value; - } - } - } - - /// - /// Returns string representation of the token. - /// - /// String representation of the token. - public string TokenString - { - get - { - if (m_token.m_symbol.m_symbolType != SymbolType.Terminal) - { - return m_token.m_symbol.ToString(); - } - StringBuilder sb = new StringBuilder(m_token.m_length); - for (int i = 0; i < m_token.m_length; i++) - { - char ch = m_buffer[m_token.m_start + i]; - if (ch < ' ') - { - switch (ch) - { - case '\n': - sb.Append("{LF}"); - break; - case '\r': - sb.Append("{CR}"); - break; - case '\t': - sb.Append("{HT}"); - break; - } - } - else - { - sb.Append(ch); - } - } - return sb.ToString(); - } - } - - /// - /// Pushes a token to the input token stack. - /// - /// Token symbol. - /// Token text. - /// Syntax node associated with the token. - public void PushInputToken(Symbol symbol, string text, object syntaxNode) - { - if (m_token.m_symbol != null) - { - if (m_inputTokenCount == m_inputTokens.Length) - { - Token[] newTokenArray = new Token[m_inputTokenCount * 2]; - Array.Copy(m_inputTokens, newTokenArray, m_inputTokenCount); - m_inputTokens = newTokenArray; - } - m_inputTokens[m_inputTokenCount++] = m_token; - } - m_token = new Token(); - m_token.m_symbol = symbol; - m_token.m_text = text; - m_token.m_length = (text != null) ? text.Length : 0; - m_token.m_syntaxNode = syntaxNode; - } - - /// - /// Pops token from the input token stack. - /// - /// Token symbol from the top of input token stack. - public Symbol PopInputToken() - { - Symbol result = m_token.m_symbol; - if (m_inputTokenCount > 0) - { - m_token = m_inputTokens[--m_inputTokenCount]; - } - else - { - m_token.m_symbol = null; - m_token.m_text = null; - } - return result; - } - - /// - /// Reads next token from the input stream. - /// - /// Token symbol which was read. - public Symbol ReadToken() - { - m_token.m_text = null; - m_token.m_start = m_charIndex; - m_token.m_lineNumber = m_lineNumber; - m_token.m_linePosition = m_charIndex - m_lineStart + 1; - int lookahead = m_charIndex; // Next look ahead char in the input - int tokenLength = 0; - Symbol tokenSymbol = null; - DfaState[] dfaStateTable = m_grammar.m_dfaStateTable; - - // End of buffer - if (m_buffer.Length == lookahead) - { - m_token.m_symbol = m_grammar.m_endSymbol; - m_token.m_length = 0; - return m_token.m_symbol; - } - - char ch = m_buffer[lookahead]; - - DfaState dfaState = m_grammar.m_dfaInitialState; - while (true) - { - dfaState = dfaState.m_transitionVector[ch] as DfaState; - - // This block-if statement checks whether an edge was found from the current state. - // If so, the state and current position advance. Otherwise it is time to exit the main loop - // and report the token found (if there was it fact one). If the LastAcceptState is -1, - // then we never found a match and the Error Token is created. Otherwise, a new token - // is created using the Symbol in the Accept State and all the characters that - // comprise it. - if (dfaState != null) - { - // This code checks whether the target state accepts a token. If so, it sets the - // appropiate variables so when the algorithm in done, it can return the proper - // token and number of characters. - lookahead++; - if (dfaState.m_acceptSymbol != null) - { - tokenSymbol = dfaState.m_acceptSymbol; - tokenLength = lookahead - m_charIndex; - } - if (m_buffer.Length == lookahead) - { - ch = EndOfString; - m_preserveChars = lookahead - m_charIndex; - // Found end of of stream - lookahead = m_charIndex + m_preserveChars; - m_preserveChars = 0; - } - else - { - ch = m_buffer[lookahead]; - } - } - else - { - if (tokenSymbol != null) - { - m_token.m_symbol = tokenSymbol; - m_token.m_length = tokenLength; - MoveBy(tokenLength); - } - else - { - //Tokenizer cannot recognize symbol - m_token.m_symbol = m_grammar.m_errorSymbol; - m_token.m_length = 1; - MoveBy(1); - } - break; - } - } - return m_token.m_symbol; - } - - /// - /// Removes current token and pops next token from the input stack. - /// - private void DiscardInputToken() - { - if (m_inputTokenCount > 0) - { - m_token = m_inputTokens[--m_inputTokenCount]; - } - else - { - m_token.m_symbol = null; - m_token.m_text = null; - } - } - - #endregion - - #region LR parser properties and methods - - /// - /// Gets current LR state. - /// - public LRState CurrentLRState - { - get { return m_lrState; } - } - - /// - /// Gets number of items in the current reduction - /// - public int ReductionCount - { - get { return m_reductionCount; } - } - - /// - /// Gets reduction item syntax object by its index. - /// - /// Index of reduction item. - /// Syntax object attached to reduction item. - public object GetReductionSyntaxNode(int index) - { - if (index < 0 || index >= m_reductionCount) - { - throw new IndexOutOfRangeException(); - } - return m_lrStack[m_lrStackIndex - m_reductionCount + index].m_token.m_syntaxNode; - } - - /// - /// Gets array of expected token symbols. - /// - public Symbol[] GetExpectedTokens() - { - return m_expectedTokens; - } - - private void ProcessBlockComment() - { - if (m_commentLevel > 0) - { - DiscardInputToken(); - while (true) - { - SymbolType symbolType = ReadToken().SymbolType; - DiscardInputToken(); - switch (symbolType) - { - case SymbolType.CommentStart: - m_commentLevel++; - break; - - case SymbolType.CommentEnd: - m_commentLevel--; - if (m_commentLevel == 0) - { - // Done with comment. - return; - } - break; - - case SymbolType.End: - //TODO: replace with special exception. - throw new Exception("CommentError"); - - default: - //Do nothing, ignore - //The 'comment line' symbol is ignored as well - break; - } - } - } - } - - /// - /// Gets current comment text. - /// - public int CommentTextLength(int startPosition) - { - if (m_token.m_symbol != null) - { - switch (m_token.m_symbol.m_symbolType) - { - case SymbolType.CommentLine: - DiscardInputToken(); //Remove token - MoveToLineEnd(); - break; - - case SymbolType.CommentStart: - m_commentLevel = 1; - ProcessBlockComment(); - break; - } - } - return m_charIndex; - } - - #endregion - - #region TokenParseResult enumeration - - /// - /// Result of parsing token. - /// - private enum TokenParseResult - { - Empty = 0, - Accept = 1, - Shift = 2, - ReduceNormal = 3, - ReduceEliminated = 4, - SyntaxError = 5, - InternalError = 6 - } - - #endregion - - #region Token struct - - /// - /// Represents data about current token. - /// - private struct Token - { - internal Symbol m_symbol; // Token symbol. - internal string m_text; // Token text. - internal int m_start; // Token start stream start. - internal int m_length; // Token length. - internal int m_lineNumber; // Token source line number. (1-based). - internal int m_linePosition; // Token position in source line (1-based). - internal object m_syntaxNode; // Syntax node which can be attached to the token. - } - - #endregion - - #region LRStackItem struct - - /// - /// Represents item in the LR parsing stack. - /// - private struct LRStackItem - { - internal Token m_token; // Token in the LR stack item. - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/Rule.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/Rule.cs deleted file mode 100644 index 7f5f6f6890..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/Rule.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.Text; - -#endregion - -namespace GoldParser -{ - /// - /// Rule is the logical structures of the grammar. - /// - /// - /// Rules consist of a head containing a nonterminal - /// followed by a series of both nonterminals and terminals. - /// - internal class Rule - { - private int m_index; - internal Symbol m_nonTerminal; - internal Symbol[] m_symbols; - internal bool m_hasOneNonTerminal; - - /// - /// Creates a new instance of Rule class. - /// - /// Index of the rule in the grammar rule table. - /// Nonterminal of the rule. - /// Terminal and nonterminal symbols of the rule. - public Rule(int index, Symbol nonTerminal, Symbol[] symbols) - { - m_index = index; - m_nonTerminal = nonTerminal; - m_symbols = symbols; - m_hasOneNonTerminal = (symbols.Length == 1) - && (symbols[0].SymbolType == SymbolType.NonTerminal); - } - - /// - /// Gets index of the rule in the rule table. - /// - public int Index - { - get { return m_index; } - } - - /// - /// Gets the head symbol of the rule. - /// - public Symbol NonTerminal - { - get { return m_nonTerminal; } - } - - /// - /// Gets name of the rule. - /// - public string Name - { - get { return '<' + m_nonTerminal.Name + '>'; } - } - - /// - /// Gets number of symbols. - /// - public int Count - { - get { return m_symbols.Length; } - } - - /// - /// Gets symbol by its index. - /// - public Symbol this[int index] - { - get { return m_symbols[index]; } - } - - /// - /// Gets true if the rule contains exactly one symbol. - /// - /// Used by the Parser object to TrimReductions - public bool ContainsOneNonTerminal - { - get { return m_hasOneNonTerminal; } - } - - /// - /// Gets the rule definition. - /// - public string Definition - { - get - { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < m_symbols.Length; i++) - { - result.Append(m_symbols[i].ToString()); - if (i < m_symbols.Length - 1) - result.Append(' '); - } - return result.ToString(); - } - } - - /// - /// Returns the Backus-Noir representation of the rule. - /// - /// - public override string ToString() - { - return Name + " ::= " + Definition; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/SR.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/SR.cs deleted file mode 100644 index 8526483ad5..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/SR.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.Reflection; -using System.IO; -using System.Resources; -using System.Globalization; - -#endregion - -namespace GoldParser -{ - /// - /// Custom resource class. Usage: - /// string s = Res.GetString(Res.MyIdenfitier); - /// - internal sealed class SR - { - static SR ms_loader = new SR(); - - private ResourceManager m_resources; - - private SR() - { - m_resources = new ResourceManager("GoldParser", this.GetType().GetTypeInfo().Assembly); - } - - /* These function can be useful in other applications. - - public static string GetString(string name, params object[] args) - { - // null CultureInfo: let ResouceManager determine the culture - return GetString(null, name, args); - } - - public static string GetString(CultureInfo culture, string name, params object[] args) - { - string res = ms_loader.m_resources.GetString(name, culture); - - if (args != null && args.Length > 0) - { - return String.Format(culture, res, args); - } - else - { - return res; - } - } -*/ - public static string GetString(string name) - { - return GetString(null, name); - } - - public static string GetString(CultureInfo culture, string name) - { - return ms_loader.m_resources.GetString(name, culture); - } - - // Code below is automatically generated by GenResNm.exe. - // Do not modify it manually. - #region Resource String Names - - internal const string Grammar_WrongFileHeader = "Grammar_WrongFileHeader"; - - internal const string Grammar_InvalidRecordType = "Grammar_InvalidRecordType"; - - internal const string Grammar_NoEntry = "Grammar_NoEntry"; - - internal const string Grammar_EmptyEntryExpected = "Grammar_EmptyEntryExpected"; - - internal const string Grammar_StringEntryExpected = "Grammar_StringEntryExpected"; - - internal const string Grammar_IntegerEntryExpected = "Grammar_IntegerEntryExpected"; - - internal const string Grammar_ByteEntryExpected = "Grammar_ByteEntryExpected"; - - internal const string Grammar_BooleanEntryExpected = "Grammar_BooleanEntryExpected"; - - internal const string Grammar_InvalidRecordHeader = "Grammar_InvalidRecordHeader"; - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/SourceLineReadCallback.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/SourceLineReadCallback.cs deleted file mode 100644 index 232dda6667..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/SourceLineReadCallback.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// This callback is used by parser to notify read source line. - /// Use parser.LineText to get line source. - /// - internal delegate void SourceLineReadCallback(Parser parser, int lineStart, int lineLength); -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/Symbol.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/Symbol.cs deleted file mode 100644 index 1c8f48218e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/Symbol.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; -using System.Text; - -#endregion - -namespace GoldParser -{ - /// - /// Represents a terminal or nonterminal symbol used by the Deterministic - /// Finite Automata (DFA) and LR Parser. - /// - /// - /// Symbols can be either terminals (which represent a class of - /// tokens - such as identifiers) or nonterminals (which represent - /// the rules and structures of the grammar). Terminal symbols fall - /// into several categories for use by the GOLD Parser Engine - /// which are enumerated in SymbolType enumeration. - /// - internal class Symbol - { - internal int m_index; // symbol index in symbol table - private string m_name; // name of the symbol - internal SymbolType m_symbolType; // type of the symbol - private string m_text; // printable representation of symbol - - private const string m_quotedChars = "|-+*?()[]{}<>!"; - - /// - /// Creates a new instance of Symbol class. - /// - /// Symbol index in symbol table. - /// Name of the symbol. - /// Type of the symbol. - public Symbol(int index, string name, SymbolType symbolType) - { - m_index = index; - m_name = name; - m_symbolType = symbolType; - } - - /// - /// Returns the index of the symbol in the GOLDParser object's Symbol Table. - /// - public int Index - { - get { return m_index; } - } - - /// - /// Returns the name of the symbol. - /// - public string Name - { - get { return m_name; } - } - - /// - /// Returns an enumerated data type that denotes - /// the class of symbols that the object belongs to. - /// - public SymbolType SymbolType - { - get { return m_symbolType; } - } - - /// - /// Returns the text representation of the symbol. - /// In the case of nonterminals, the name is delimited by angle brackets, - /// special terminals are delimited by parenthesis - /// and terminals are delimited by single quotes - /// (if special characters are present). - /// - /// String representation of symbol. - public override string ToString() - { - if (m_text == null) - { - switch (SymbolType) - { - case SymbolType.NonTerminal: - m_text = '<' + Name + '>'; - break; - - case SymbolType.Terminal: - m_text = FormatTerminalSymbol(Name); - break; - - default: - m_text = '(' + Name + ')'; - break; - } - } - return m_text; - } - - private static string FormatTerminalSymbol(string source) - { - StringBuilder result = new StringBuilder(); - for (int i = 0; i < source.Length; i++) - { - char ch = source[i]; - if (ch == '\'') - { - result.Append("''"); - } - else if (IsQuotedChar(ch) || (ch == '"')) - { - result.Append(new Char[] {'\'', ch, '\''}); - } - else - { - result.Append(ch); - } - } - return result.ToString(); - } - - private static bool IsQuotedChar(char value) - { - return (m_quotedChars.IndexOf(value) >= 0); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/GoldParser/SymbolType.cs b/sources/shaders/Stride.Core.Shaders/GoldParser/SymbolType.cs deleted file mode 100644 index d540c3b529..0000000000 --- a/sources/shaders/Stride.Core.Shaders/GoldParser/SymbolType.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ---------------------------------------------------------------------- -// Gold Parser engine. -// See more details on http://www.devincook.com/goldparser/ -// -// Original code is written in VB by Devin Cook (GOLDParser@DevinCook.com) -// -// This translation is done by Vladimir Morozov (vmoroz@hotmail.com) -// -// The translation is based on the other engine translations: -// Delphi engine by Alexandre Rai (riccio@gmx.at) -// C# engine by Marcus Klimstra (klimstra@home.nl) -// ---------------------------------------------------------------------- -#region Using directives - -using System; - -#endregion - -namespace GoldParser -{ - /// - /// Type of symbol. - /// - internal enum SymbolType - { - /// - /// Normal nonterminal - /// - NonTerminal = 0, - - /// - /// Normal terminal - /// - Terminal = 1, - - /// - /// This Whitespace symbols is a special terminal - /// that is automatically ignored the the parsing engine. - /// Any text accepted as whitespace is considered - /// to be inconsequential and "meaningless". - /// - WhiteSpace = 2, - - /// - /// The End symbol is generated when the tokenizer - /// reaches the end of the source text. - /// - End = 3, - - /// - /// This type of symbol designates the start of a block quote. - /// - CommentStart = 4, - - /// - /// This type of symbol designates the end of a block quote. - /// - CommentEnd = 5, - - /// - /// When the engine reads a token that is recognized as - /// a line comment, the remaining characters on the line - /// are automatically ignored by the parser. - /// - CommentLine = 6, - - /// - /// The Error symbol is a general-purpose means - /// of representing characters that were not recognized - /// by the tokenizer. In other words, when the tokenizer - /// reads a series of characters that is not accepted - /// by the DFA engine, a token of this type is created. - /// - Error = 7 - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/BnfTermExtensions.Helpers.cs b/sources/shaders/Stride.Core.Shaders/Grammar/BnfTermExtensions.Helpers.cs deleted file mode 100644 index 9fbb6084ba..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/BnfTermExtensions.Helpers.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - /// - /// Extensions to BnfTerm. - /// - public static class BnfTermExtensions - { - /// - /// Makes a non terminal optional. - /// - /// The term. - /// An optional non terminal. - public static NonTerminal Opt(this BnfTerm term) - { - var nonTerminal = term.Q(); - nonTerminal.SetFlag(TermFlags.NoAstNode); - return nonTerminal; - } - - /// - /// Makes a list of non terminals. - /// - /// The term. - /// A list of non temrinal - public static NonTerminal List(this BnfTerm term) - { - var nonTerminal = term.Plus(); - nonTerminal.SetFlag(TermFlags.NoAstNode); - return nonTerminal; - } - - /// - /// Makes an optional list of non terminals. - /// - /// The term. - /// An optional list of non terminals. - public static NonTerminal ListOpt(this BnfTerm term) - { - var nonTerminal = term.Star(); - nonTerminal.SetFlag(TermFlags.NoAstNode); - return nonTerminal; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/CustomScanner.cs b/sources/shaders/Stride.Core.Shaders/Grammar/CustomScanner.cs deleted file mode 100644 index a2a6622ad4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/CustomScanner.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - /// - /// A Custom Scanner used for Irony - /// - internal class CustomScanner : Scanner - { - private Tokenizer tokenizer; - - /// - /// Initializes a new instance of the class. - /// - /// The tokenizer. - public CustomScanner(Tokenizer tokenizer) - { - this.tokenizer = tokenizer; - } - - /// - public override SourceLocation Location - { - get - { - return tokenizer.Location; - } - - set - { - tokenizer.Location = value; - } - } - - /// - public override void SetSourceText(string sourceText, string sourceFileName) - { - tokenizer.SetSourceText(sourceText, sourceFileName); - } - - /// - protected override void NextToken() - { - Context.CurrentToken = tokenizer.GetNextToken(); - } - - /// - protected override void PrepareInput() - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/DynamicKeyTerm.cs b/sources/shaders/Stride.Core.Shaders/Grammar/DynamicKeyTerm.cs deleted file mode 100644 index d6902b860f..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/DynamicKeyTerm.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - internal abstract class DynamicKeyTerm : KeyTerm - { - protected DynamicKeyTerm(string text, string name) - : base(text, name) - { - } - - public abstract void Match(Tokenizer toknizer, out Token token); - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Ast.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Ast.cs deleted file mode 100644 index a9ca704725..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Ast.cs +++ /dev/null @@ -1,908 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Text; - -using GoldParser; -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using ParameterQualifier = Stride.Core.Shaders.Ast.Hlsl.ParameterQualifier; -using StorageQualifier = Stride.Core.Shaders.Ast.Hlsl.StorageQualifier; - -namespace Stride.Core.Shaders.Grammar.Hlsl -{ - /// - /// Methods used to create the Abstract Syntax Tree.. - /// - public partial class HlslGrammar - { - /// - /// The create annotations ast. - /// - /// - /// - /// - /// - protected static void CreateAnnotationsAst(ParsingContext context, ParseTreeNode node) - { - var annotations = Ast(node); - - // [0] [1] [2] - // "<" + variable_declaration_raw.ListOpt() + ">"; - FillListFromNodes(node.ChildNodes[1].ChildNodes, annotations.Variables); - } - - /// - /// The create annotations opt ast. - /// - /// - /// - /// - /// - protected static void CreateAnnotationsOptAst(ParsingContext context, ParseTreeNode node) - { - var values = GetOptional(node); - node.AstNode = values; - if (values == null) - { - Ast(node); - } - } - - /// - /// The create asm ast. - /// - /// - /// - /// - /// - protected static void CreateAsmAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - // [0] - // asm_block - value.Text = node.ChildNodes[0].Token.Text; - } - - /// - /// The create attribute ast. - /// - /// - /// - /// - /// - protected static void CreateAttributeAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// [0] [1] [2] [3] - // "[" + identifier + "]" - // | "[" + identifier + "(" + literal_list.Q() + ")" + "]"; - value.Name = (Identifier)node.ChildNodes[1].AstNode; - - if (node.ChildNodes.Count > 3) - { - if (node.ChildNodes[3].ChildNodes.Count > 0) - { - FillListFromNodes(node.ChildNodes[3].ChildNodes[0].ChildNodes, value.Parameters); - } - } - } - - /// - /// The create cast expression ast. - /// - /// - /// - /// - /// - protected static void CreateCastExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // [0] [1] [2] [3] [4] - // "(" + type_for_cast + rank_specifier.Star() + ")" + cast_expression; - var value = Ast(node); - - var type = (TypeBase)node.ChildNodes[1].AstNode; - - if (node.ChildNodes[2].ChildNodes.Count > 0) - { - var arrayType = new ArrayType { Type = type, Span = SpanConverter.Convert(node.ChildNodes[2].Span) }; - FillListFromNodes(node.ChildNodes[2].ChildNodes, arrayType.Dimensions); - type = arrayType; - } - - value.Target = type; - value.From = (Expression)node.ChildNodes[4].AstNode; - } - - /// - /// The create class base type ast. - /// - /// - /// - /// - /// - protected static void CreateClassBaseTypeAst(ParsingContext context, ParseTreeNode node) - { - //// [0] - //// (":" + type_name).Q(); - if (node.ChildNodes[0].ChildNodes.Count == 1) - node.AstNode = node.ChildNodes[0].ChildNodes[0].AstNode; - else - node.AstNode = new List(); - } - - /// - /// The create class declaration ast. - /// - /// - /// - /// - /// - protected static void CreateClassDeclarationAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [2] [3] [4] [5] - // "class" + type_name + class_base_type.Star() + "{" + scope_declaration.Star() + "}"; - var value = Ast(node); - - // Parse generics - ParseGenerics((Identifier)node.ChildNodes[1].AstNode, value); - - //FillListFromNodes(node.ChildNodes[2].ChildNodes, value.BaseClasses); - value.BaseClasses.AddRange((List)node.ChildNodes[2].AstNode); - FillListFromNodes(node.ChildNodes[4].ChildNodes, value.Members); - } - - protected static void ParseGenerics(Identifier input, T dest) where T : TypeBase, IGenerics - { - // Parse generic identifier and convert it to simple identifier by adding contraint to the class type - var genericIdentifier = input as IdentifierGeneric; - if (genericIdentifier != null) - { - foreach (var genericIdentifierItem in genericIdentifier.Identifiers) - { - dest.GenericParameters.Add(new GenericParameterType(genericIdentifierItem)); - } - input = new Identifier(input.Text) { Span = genericIdentifier.Span }; - } - dest.Name = input; - } - - /// - /// The create compile expression ast. - /// - /// - /// - /// - /// - protected static void CreateCompileExpressionAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [2] - // "compile" + identifier + simple_method_invoke_expression; - var value = Ast(node); - - value.Profile = (Identifier)node.ChildNodes[1].AstNode; - value.Function = (MethodInvocationExpression)node.ChildNodes[2].AstNode; - } - - /// - /// The create constant buffer ast. - /// - /// - /// - /// - /// - protected static void CreateConstantBufferAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [2] [3] [4] [5] [6] - // attribute_list_opt + constant_buffer_resource_type + identifier.Q() + register.Q() + "{" + declaration.Star() + "}" + semi_opt; - var value = Ast(node); - value.Attributes = (List)node.ChildNodes[0].AstNode; - - value.Type = (ConstantBufferType)node.ChildNodes[1].AstNode; - - value.Name = GetOptional(node.ChildNodes[2]); - value.Register = GetOptional(node.ChildNodes[3]); - - FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Members); - } - - /// - /// The create generic type ast. - /// - /// - /// - /// - /// - /// - /// - protected static void CreateGenericTypeAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - value.ParameterTypes.Add(typeof(T1)); - - // [0] [1] [2] [3] - // keyword + "<" + type_name + ">" - Identifier identifier = null; - - if (node.ChildNodes[0].AstNode is TypeBase) - { - identifier = ((TypeBase)node.ChildNodes[0].AstNode).Name; - } - - if (identifier == null) - { - CreateIdentifierAst(parsingcontext, node.ChildNodes[0]); - identifier = (Identifier)node.ChildNodes[0].AstNode; - } - - value.Name = identifier; - value.Parameters.Add((Node)node.ChildNodes[2].AstNode); - } - - /// - /// The create generic type ast. - /// - /// - /// - /// - /// - /// - /// - /// - /// - protected static void CreateGenericTypeAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - value.ParameterTypes.Add(typeof(T1)); - value.ParameterTypes.Add(typeof(T2)); - - // [0] [1] [2] [3] - // identifier + "<" + type_name + "," + value ">" - Identifier identifier = null; - - if (node.ChildNodes[0].AstNode is TypeBase) - { - identifier = ((TypeBase)node.ChildNodes[0].AstNode).Name; - } - - if (identifier == null) - { - CreateIdentifierAst(parsingcontext, node.ChildNodes[0]); - identifier = (Identifier)node.ChildNodes[0].AstNode; - } - - value.Name = identifier; - - value.Parameters.Add((Node)node.ChildNodes[2].AstNode); - value.Parameters.Add((Node)node.ChildNodes[3].AstNode); - } - - /// - /// The create identifier composite list. - /// - /// - /// - /// - /// - protected static void CreateIdentifierCompositeList(ParsingContext context, ParseTreeNode node) - { - var values = Ast>(node); - foreach (var subNode in node.ChildNodes) - { - values.Add(new Identifier(subNode.Token.Text) { Span = SpanConverter.Convert(subNode.Span) }); - } - } - - /// - /// The create identifier ns ast. - /// - /// - /// - /// - /// - protected static void CreateIdentifierNsAst(ParsingContext context, ParseTreeNode node) - { - // identifier_ns.Rule = - // [0] [1] [2] - // identifier_raw + "::" + identifier_ns_list; - var value = Ast(node); - value.Identifiers = new List(); - value.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode); - value.Identifiers.AddRange((List)node.ChildNodes[2].AstNode); - } - - /// - /// The create identifier special reference ast. - /// - /// - /// - /// - /// - protected static void CreateIdentifierSpecialReferenceAst(ParsingContext context, ParseTreeNode node) - { - // "<" + identifier + ">" - CreateIdentifierAst(context, node.ChildNodes[1]); - var value = (Identifier)node.ChildNodes[1].AstNode; - value.IsSpecialReference = true; - node.AstNode = value; - } - - /// - /// The create interface ast. - /// - /// - /// - /// - /// - protected static void CreateInterfaceAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// interface_specifier.Rule = - //// [0] [1] [2] [3] - //// "interface" + identifier + "{" + method_declaration.Star() + "}"; - - // Parse generics - ParseGenerics((Identifier)node.ChildNodes[1].AstNode, value); - - FillListFromNodes(node.ChildNodes[3].ChildNodes, value.Methods); - } - - /// - /// Creates the matrix ast. - /// - /// - /// The parsing context. - /// - /// - /// The node. - /// - protected static void CreateMatrixAst(ParsingContext parsingContext, ParseTreeNode node) - { - var matrixType = Ast(node); - - //// [0] [1] [2] [3] [4] [5] - // _("matrix") + "<" + scalars + "," + number + "," + number + ">" - matrixType.Type = (TypeBase)node.ChildNodes[2].AstNode; - matrixType.Parameters[1] = (Literal)node.ChildNodes[3].AstNode; - matrixType.Parameters[2] = (Literal)node.ChildNodes[4].AstNode; - } - - /// - /// The create pack offset ast. - /// - /// - /// - /// - /// - protected static void CreatePackOffsetAst(ParsingContext context, ParseTreeNode node) - { - //// [0] [1] [2] [3] - // _(":") + "packoffset" + "(" + identifier + ")"; - node.AstNode = new PackOffset() - { - Value = (Identifier)node.ChildNodes[2].AstNode, Span = SpanConverter.Convert(node.Span) - }; - } - - /// - /// The create pass ast. - /// - /// - /// - /// - /// - protected static void CreatePassAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// pass_definition.Rule = - //// [0] [1] [2] [3] [4] [5] [6] [7] - //// attribute_list_opt + pass_keyword + identifier.Opt() + annotations.Opt() + "{" + pass_statement.ListOpt() + "}" + semi_opt; - value.Attributes = (List)node.ChildNodes[0].AstNode; - value.Name = GetOptional(node.ChildNodes[2]); - - // TODO HANDLE Annotations here - // value.Annotations = (List)node.ChildNodes[3].AstNode; - FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Items); - } - - /// - /// The create pass statement ast. - /// - /// - /// - /// - /// - protected static void CreatePassStatementAst(ParsingContext context, ParseTreeNode node) - { - //// pass_statement.Rule = - //// method_invoke_expression_simple + ";" - ////| simple_assignment_expression_statement; - node.AstNode = node.ChildNodes[0].AstNode; - } - - /// - /// The create register location ast. - /// - /// - /// - /// - /// - protected static void CreateRegisterLocationAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// [0] [1] [2] [3] [4] - // _(":") + "register" + "(" + indexable_identifier + ")" - // | _(":") + "register" + "(" + identifier + "," + indexable_identifier + ")"; - int index = 2; - if (node.ChildNodes.Count == 5) - { - value.Profile = (Identifier)node.ChildNodes[index].AstNode; - index++; - } - - value.Register = (Identifier)node.ChildNodes[index].AstNode; - } - - /// - /// The create semantic ast. - /// - /// - /// - /// - /// - protected static void CreateSemanticAst(ParsingContext context, ParseTreeNode node) - { - //// [0] - // ":" + identifier - node.AstNode = new Semantic() - { - Name = (Identifier)node.ChildNodes[0].AstNode, Span = SpanConverter.Convert(node.Span) - }; - } - - /// - /// The create state expression ast. - /// - /// - /// - /// - /// - protected static void CreateStateExpressionAst(ParsingContext context, ParseTreeNode node) - { - //// state_expression.Rule = - //// [0] [1] - //// state_type + state_initializer; - var value = Ast(node); - value.StateType = (TypeBase)node.ChildNodes[0].AstNode; - value.Initializer = (StateInitializer)node.ChildNodes[1].AstNode; - } - - /// - /// The create state values ast. - /// - /// - /// - /// - /// - protected static void CreateStateValuesAst(ParsingContext context, ParseTreeNode node) - { - //// state_initializer.Rule = "{" + simple_assignment_expression_statement.Star() + "}"; - var stateValues = Ast(node); - FillListFromNodes(node.ChildNodes[1].ChildNodes, stateValues.Items); - } - - /// - /// The create string literal ast. - /// - /// - /// - /// - /// - protected static void CreateStringLiteralAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - value.SubLiterals = new List(); - - //// string_literal.Rule = - //// string_literal_raw.List(); - var text = new StringBuilder(); - var textValue = new StringBuilder(); - foreach (var childNode in node.ChildNodes[0].ChildNodes) - { - var subLiteral = new Literal - { - Span = SpanConverter.Convert(childNode.Span), - Value = childNode.AstNode, - Text = childNode.Token.Text - }; - value.SubLiterals.Add(subLiteral); - textValue.Append(subLiteral.Value); - } - - text.Append("\"").Append(textValue).Append("\""); - - value.Value = textValue.ToString(); - value.Text = text.ToString(); - } - - /// - /// The create technique ast. - /// - /// - /// - /// - /// - protected static void CreateTechniqueAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// technique_definition.Rule = - //// [0] [1] [2] [3] [4] [5] [6] [7] - //// attribute_list_opt + technique_keyword + identifier.Opt() + annotations_opt + "{" + pass_definition.List() + "}" + semi_opt; - value.Type = (Identifier)node.ChildNodes[1].AstNode; - value.Attributes = (List)node.ChildNodes[0].AstNode; - value.Name = GetOptional(node.ChildNodes[2]); - - // TODO Handle annotations here - // value.Annotations = (List)node.ChildNodes[3].AstNode; - FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Passes); - } - - /// - /// The create texture dms ast. - /// - /// - /// - /// - /// - protected static void CreateTextureDMSAst(ParsingContext context, ParseTreeNode node) - { - //// texture_generic_dms_type.Rule = - //// [0] [1] [2] [3] [3] [4] - //// texture_dms_type_profile_5 + "<" + scalars_and_vectors + ">" - ////| texture_dms_type_profile_5 + "<" + scalars_and_vectors + "," + number + ">"; - if (node.ChildNodes.Count == 4) - { - CreateGenericTypeAst(context, node); - } - else - { - CreateGenericTypeAst(context, node); - } - } - - /// - /// The create typedef ast. - /// - /// - /// - /// - /// - protected static void CreateTypedefAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] [3] - // _("typedef") + typedefable_type + variable_declarator_list + ";" - // | _("typedef") + storage_class_specifier + typedefable_type + variable_declarator_list + ";"; - int indexType = 1; - if (node.ChildNodes.Count == 4) - { - value.Qualifiers = CreateEnumFlags(Qualifier.None, node.ChildNodes[0].ChildNodes); - indexType++; - } - - value.Type = (TypeBase)node.ChildNodes[indexType].AstNode; - var identifierList = (List)node.ChildNodes[indexType + 1].AstNode; - - var declarators = new List(identifierList.Count); - - // Create declarators for typedefs - foreach (var identifier in identifierList) - { - var declarator = new Typedef(value.Type) - { - Span = identifier.Span, - Name = identifier - }; - - if (identifier.HasIndices) - { - var arrayType = new ArrayType { Type = declarator.Type, Span = identifier.Span }; - arrayType.Dimensions.AddRange(identifier.Indices); - declarator.Type = arrayType; - identifier.Indices.Clear(); - } - - declarators.Add(declarator); - } - - if (declarators.Count == 1) - { - value.Type = declarators[0].Type; - value.Name = declarators[0].Name; - } - else - { - value.SubDeclarators = declarators; - } - } - - /// - /// The create variable declarator qualifier post ast. - /// - /// - /// - /// - /// - protected static void CreateVariableDeclaratorQualifierPostAst(ParsingContext context, ParseTreeNode node) - { - // Empty - // | semantic - // | semantic + packoffset + register.Star() - // | semantic + register.Plus() - // | packoffset + register.Star() - // | register.Plus(); - var qualifiers = AstCompositeEnum(node); - - foreach (var childNode in node.ChildNodes) - { - // semantic or packoffset - if (childNode.AstNode is Semantic) - { - qualifiers |= (Semantic)childNode.AstNode; - } - else if (childNode.AstNode is PackOffset) - { - qualifiers |= (PackOffset)childNode.AstNode; - } - else - { - qualifiers = CreateEnumFlags(qualifiers, childNode.ChildNodes); - } - } - - // Pass a local object to be used by the variable_declarator - node.AstNode = qualifiers; - } - - /// - /// Creates the vector ast. - /// - /// - /// The parsing context. - /// - /// - /// The node. - /// - protected static void CreateVectorAst(ParsingContext parsingContext, ParseTreeNode node) - { - var vectorType = Ast(node); - - //// [0] [1] [2] [3] [4] - // _("vector") + "<" + scalars + "," + number + ">" - vectorType.Type = (TypeBase)node.ChildNodes[2].AstNode; - vectorType.Parameters[1] = (Literal)node.ChildNodes[3].AstNode; - } - - /// - /// The create parameter ast. - /// - /// - /// - /// - /// - protected override void CreateParameterAst(ParsingContext context, ParseTreeNode node) - { - base.CreateParameterAst(context, node); - - //// parameter_declaration.Rule = - //// [0] [1] [2] [3] [4] - //// attribute_qualifier_pre + parameter_qualifier_pre + parameter_type + indexable_identifier.Opt() + parameter_qualifier_post; - var parameter = (Parameter)node.AstNode; - - parameter.Qualifiers = (Qualifier)node.ChildNodes[1].AstNode; - - var postQualifier = (Tuple)node.ChildNodes[4].AstNode; - parameter.InitialValue = postQualifier.Item1; - parameter.Qualifiers |= postQualifier.Item2; - } - - private void CreateParameterQualifierPost(ParsingContext context, ParseTreeNode node) - { - //// [0] [1] [2] - //// parameter_qualifier_post.Rule = semantic_list_opt - //// | "=" + initializer + semantic_list_opt; - - Tuple postQualifier; - - if (node.ChildNodes.Count == 3) - { - postQualifier = new Tuple((Expression)node.ChildNodes[1].AstNode, (Qualifier)node.ChildNodes[2].AstNode); - } - else - { - postQualifier = new Tuple(null, (Qualifier)node.ChildNodes[0].AstNode); - } - - node.AstNode = postQualifier; - } - - /// - /// The create parameter qualifier. - /// - /// - /// - /// - /// - protected virtual void CreateParameterQualifier(ParsingContext context, ParseTreeNode node) - { - //// [0] - //// storage_class_specifier | _("in") | "out" | "inout" | "point" | "line" | "triangle" | "triangleadj"; - if (node.ChildNodes[0].AstNode is Qualifier) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - else - { - var qualifier = Shaders.Ast.Hlsl.ParameterQualifier.Parse(node.ChildNodes[0].Token.Text); - qualifier.Span = SpanConverter.Convert(node.Span); - node.AstNode = qualifier; - } - } - - protected override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node) - { - var qualifier = AstCompositeEnum(node); - - if (node.ChildNodes.Count == 1) - { - qualifier = Shaders.Ast.Hlsl.StorageQualifier.Parse(node.ChildNodes[0].Token.Text); - qualifier.Span = SpanConverter.Convert(node.Span); - } - - // Use Hlsl Storage Qualifiers to parse the qualifier - node.AstNode = qualifier; - } - - /// - /// The create variable declarator ast. - /// - /// - /// - /// - /// - protected override void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // Create default declarator using the follozing inherited rule - //// - //// variable_declarator.Rule = - //// [0] [1] [2] - //// variable_declarator_raw - ////| variable_declarator_raw + "=" + initializer; - //// - //// Rules added by this override: - ////| variable_declarator_raw + state_initializer - ////| variable_declarator_raw + state_array_initializer; - base.CreateVariableDeclaratorAst(parsingcontext, node); - var value = (Variable)node.AstNode; - - // Get initial value - if (node.ChildNodes.Count == 2) - { - value.InitialValue = (Expression)node.ChildNodes[1].AstNode; - } - } - - protected override void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node) - { - //// Get base declaration: - //// variable_declarator_raw.Rule = - //// [0] [1] - //// indexable_identifier_declarator + variable_declarator_qualifier_post - base.CreateVariableDeclaratorRawAst(parsingcontext, node); - var value = (Variable)node.AstNode; - - //// Add annotations: - //// indexable_identifier_declarator + variable_declarator_qualifier_post + - value.Attributes.Add((Ast.Hlsl.Annotations)node.ChildNodes[2].AstNode); - } - - protected virtual void CreateConstantBufferTypeAst(ParsingContext context, ParseTreeNode node) - { - node.AstNode = ConstantBufferType.Parse(node.ChildNodes[0].Token.Text); - } - - private static void CreateFloatQualifier(ParsingContext context, ParseTreeNode node) - { - node.AstNode = FloatQualifier.Parse(node.ChildNodes[0].Token.Text); - } - - private static void CreateIdentifierDotAst(ParsingContext context, ParseTreeNode node) - { - // identifier_dot.Rule = - // [0] [1] [2] - // identifier_or_generic + "." + identifier_dot_list; - var value = Ast(node); - value.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode); - value.Identifiers.AddRange((List)node.ChildNodes[2].AstNode); - } - - private void CreateStringRawLiteral(ParsingContext context, ParseTreeNode node) - { - node.AstNode = node.Token.Text.Trim('"'); - } - - private static void CreateIdentifierGenericAst(ParsingContext context, ParseTreeNode node) - { - // identifier_generic.Rule = - // [0] [1] [2] [3] - // identifier - // | identifier + "<" + class_identifier_generic_parameter_list + ">"; - var identifier = (Identifier)node.ChildNodes[0].AstNode; - - if (node.ChildNodes.Count == 4) - { - var value = Ast(node); - value.Text = identifier.Text; - value.Identifiers.AddRange((List)node.ChildNodes[2].AstNode); - } - else - { - node.AstNode = identifier; - } - } - - private static void CreateTypeGenericAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - value.Name = (Identifier)node.ChildNodes[0].AstNode; - } - - private static void CreateMethodOperatorIdentifierAst(ParsingContext context, ParseTreeNode node) - { - // method_operator_identifier.Rule = - // _("operator") + "[" + "]" - // _("operator") + "+" - // ...etc. - // Get the deepest valid node (either an AstNode or a Token) - var value = Ast(node); - var text = new StringBuilder(); - foreach (var subNode in node.ChildNodes) - text.Append(subNode.Token.Text); - value.Text = text.ToString(); - } - - private static void CreateMethodSpecialIdentifierAst(ParsingContext context, ParseTreeNode node) - { - //// method_special_identifier.Rule = - //// [0] [1] [2] - //// identifier + "." + method_operator_identifier - //// | method_operator_identifier; - if (node.ChildNodes.Count == 1) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - else - { - var newnode = Ast(node); - newnode.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode); - newnode.Identifiers.Add((Identifier)node.ChildNodes[2].AstNode); - } - } - - protected virtual void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Helpers.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Helpers.cs deleted file mode 100644 index e5e7f0e9e7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.Helpers.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Grammar.Hlsl -{ - public partial class HlslGrammar - { - #region Public Methods - - #endregion - - #region Methods - - protected static void CreateListFromNode(ParsingContext context, ParseTreeNode node) - { - var list = new List(); - FillListFromNodes(node.ChildNodes, list); - node.AstNode = list; - } - - private static void FillListFromNodes(IEnumerable nodes, List items) - { - foreach (var childNode in nodes) - { - items.Add((TItem)childNode.AstNode); - } - } - - private NonTerminal CreateScalarTerminal(T scalarType) where T : ScalarType, new() - { - return new NonTerminal( - scalarType.Name, - (context, node) => - { - var value = Ast(node); - value.Name = new Identifier(scalarType.Name) { Span = SpanConverter.Convert(node.Span) }; - value.Type = scalarType.Type; - }) { Rule = Keyword(scalarType.Name) }; - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.cs deleted file mode 100644 index cb3937c4bb..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Hlsl/HlslGrammar.cs +++ /dev/null @@ -1,581 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Diagnostics.CodeAnalysis; -using System.Text.RegularExpressions; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Grammar.Hlsl -{ - /// - /// Grammar for Hlsl. - /// - [Language("hlsl", "5.0", "Sample hlsl grammar")] - public partial class HlslGrammar : ShaderGrammar - { - // ReSharper disable InconsistentNaming - // ------------------------------------------------------------------------------------ - // Literals - // ------------------------------------------------------------------------------------ - protected readonly Terminal string_literal_raw = new Terminal("string") { AstNodeConfig = new TokenInfo(TokenCategory.String) }; - protected readonly NonTerminal string_literal = T("string_literal", CreateStringLiteralAst); - - // ------------------------------------------------------------------------------------ - // NonTerminals - // ------------------------------------------------------------------------------------ - protected readonly NonTerminal annotations = T("annotations", CreateAnnotationsAst); - protected readonly NonTerminal annotations_opt = T("annotations_opt", CreateAnnotationsOptAst); - protected readonly NonTerminal asm_expression = T("asm_expression", CreateAsmAst); - private readonly NamedBlockKeyTerm asm_block = new NamedBlockKeyTerm("asm_block", "asm") { AstNodeConfig = new TokenInfo() { TokenCategory = TokenCategory.Keyword }}; - protected readonly NonTerminal attribute_list_opt = T("attribute_list_opt", CreateListFromNode); - protected readonly NonTerminal attribute_modifier = T("attribute_modifier", CreateAttributeAst); - protected readonly NonTerminal buffer_type = T("buffer_type", CreateGenericTypeAst); - protected readonly NonTerminal byte_address_buffer = T("byte_address_buffer", CreateTypeNameFromTokenAst); - protected readonly NonTerminal cast_expression_raw = T("cast_expression_raw", CreateCastExpressionAst); - protected readonly NonTerminal class_base_type = T("class_base_type", CreateClassBaseTypeAst); - protected readonly NonTerminal class_base_type_list = T("class_base_type_list", CreateListFromNode); - protected readonly NonTerminal class_specifier = T("class_specifier", CreateClassDeclarationAst); - protected readonly NonTerminal compile_expression = T("compile_expression", CreateCompileExpressionAst); - protected readonly NonTerminal constant_buffer_resource = T("constant_buffer_resource", CreateConstantBufferAst); - protected readonly NonTerminal constant_buffer_resource_type = T("constant_buffer_resource_type"); - protected readonly NonTerminal float_qualifier = T("float_qualifier", CreateFloatQualifier); - protected readonly NonTerminal geometry_stream = TT("geomery_stream"); - protected readonly NonTerminal identifier_dot = T("identifier_dot", CreateIdentifierDotAst); - protected readonly NonTerminal identifier_or_dot = TT("identifier_or_dot"); - protected readonly NonTerminal identifier_ns = T("identifier_ns", CreateIdentifierNsAst); - protected readonly NonTerminal identifier_ns_list = T("identifier_ns_list", CreateListFromNode); - protected readonly NonTerminal identifier_dot_list = T("identifier_dot_list", CreateListFromNode); - protected readonly NonTerminal identifier_generic_parameter_list = T("identifier_generic_parameter_list", CreateListFromNode); - protected readonly NonTerminal identifier_generic = T("identifier_generic", CreateIdentifierGenericAst); - protected readonly NonTerminal identifier_or_generic = TT("identifier_or_generic"); - protected readonly NonTerminal type_generic = T("type_generic", CreateTypeGenericAst); - protected readonly NonTerminal identifier_special_reference_expression = T("identifier_special_reference_expression", CreateIdentifierSpecialReferenceAst); - protected readonly NonTerminal identifier_keyword = T("identifier_keyword", CreateIdentifierAst); - protected readonly NonTerminal indexable_identifier_declarator_list = T("indexable_identifier_declarator_list", CreateIdentifierListAst); - protected readonly NonTerminal identifier_sub_generic = T("identifier_sub_generic"); - protected readonly NonTerminal interface_specifier = T("interface_specifier", CreateInterfaceAst); - protected readonly NonTerminal line_stream = T("line_strean", CreateGenericTypeAst); - protected readonly NonTerminal method_operator_identifier = T("method_operator_identifier", CreateMethodOperatorIdentifierAst); - protected readonly NonTerminal method_special_identifier = T("method_special_identifier", CreateMethodSpecialIdentifierAst); - protected readonly NonTerminal packoffset = T("packoffset", CreatePackOffsetAst); - protected readonly NonTerminal parameter_qualifier = T("parameter_qualifier"); - protected readonly NonTerminal parameter_qualifier_pre_list_opt = T("parameter_qualifier_pre_list_opt", CreateQualifiersAst); - protected readonly NonTerminal pass_definition = T("pass_definition", CreatePassAst); - protected readonly NonTerminal pass_keyword = TT("pass_keyword"); - protected readonly NonTerminal pass_statement = T("pass_statement", CreatePassStatementAst); - protected readonly NonTerminal patch_generic_type = T("patch_generic_type", CreateGenericTypeAst); - protected readonly NonTerminal patch_type = T("patch_type", CreateTypeNameFromTokenAst); - protected readonly NonTerminal point_stream = T("point_stream", CreateGenericTypeAst); - protected readonly NonTerminal register = T("register", CreateRegisterLocationAst); - protected readonly NonTerminal state_type = T("state_type", CreateTypeFromTokenAst); - protected readonly NonTerminal semantic = T("semantic", CreateSemanticAst); - protected readonly NonTerminal semantic_list_opt = T("semantic_list_opt", CreateQualifiersAst); - protected readonly NonTerminal shader_objects = T("shader_objects", CreateTypeNameFromTokenAst); - protected readonly NonTerminal state_expression = T("state_expression", CreateStateExpressionAst); - protected readonly NonTerminal state_initializer = T("state_initializer", CreateStateValuesAst); - protected readonly NonTerminal state_initializer_list = T("state_initializer", CreateListFromNode); - protected readonly NonTerminal state_array_initializer = T("state_array_initializer", CreateStateValuesAst); - protected readonly NonTerminal stream_output_object = T("stream_output_object", CreateGenericTypeAst); - protected readonly NonTerminal string_type = T("string_type", (context, node) => Ast(node).Name = new Identifier("string") { Span = SpanConverter.Convert(node.Span) }); - protected readonly NonTerminal structured_buffer = T("structured_buffer", CreateGenericTypeAst); - protected readonly NonTerminal structured_buffer_type = T("structured_buffer_type", CreateTypeNameFromTokenAst); - protected readonly NonTerminal technique_definition = T("technique_definition", CreateTechniqueAst); - protected readonly NonTerminal technique_keyword = T("technique_keyword", CreateIdentifierAst); - protected readonly NonTerminal texture_dms_type_profile_5 = T("texture_dms_type_profile_5", CreateTypeFromTokenAst); - protected readonly NonTerminal texture_generic_dms_type = T("texture_generic_dms_type", CreateTextureDMSAst); - protected readonly NonTerminal texture_generic_simple_type = T("texture_generic_simple_type", CreateGenericTypeAst); - protected readonly NonTerminal texture_generic_type = TT("texture_generic_type"); - protected readonly NonTerminal texture_type = T("texture_type", CreateTypeFromTokenAst); - protected readonly NonTerminal texture_type_list = TT("texture_type_list"); - protected readonly NonTerminal texture_type_profile_4 = T("texture_type_profile_4", CreateTypeFromTokenAst); - protected readonly NonTerminal texture_type_profile_5 = T("texture_type_profile_5", CreateTypeFromTokenAst); - protected readonly NonTerminal triangle_stream = T("triangle_stream", CreateGenericTypeAst); - protected readonly NonTerminal typedef_declaration = T("typedef_modifier", CreateTypedefAst); - - protected readonly NonTerminal variable_declarator_qualifier_post_hlsl = T("variable_declarator_qualifier_post_hlsl", CreateVariableDeclaratorQualifierPostAst); - protected readonly TerminalSet _skipTokensInPreview = new TerminalSet(); - // ReSharper restore InconsistentNaming - - - public override LanguageData CreateLanguageData() - { - return new ShaderLanguageData(this); - } - - /// - /// Initializes a new instance of the class. - /// - public HlslGrammar() - { - GrammarComments = "Hlsl version 5.0"; - - Term(string_literal_raw, TokenCategory.String, TokenType.StringLiteral); - Punc("::", TokenType.IdentifierSeparator); - - // ------------------------------------------------------------------------------------ - // Comments - // ------------------------------------------------------------------------------------ - - identifier_ns_list.Rule = MakePlusRule(identifier_ns_list, ToTerm("::"), identifier_raw); - identifier_dot_list.Rule = MakePlusRule(identifier_dot_list, ToTerm("."), identifier_raw); - identifier_ns.Rule = identifier_raw + "::" + identifier_ns_list; - identifier_dot.Rule = identifier_or_generic + ToTerm(".") + identifier_dot_list; - identifier_or_dot.Rule = identifier | identifier_dot; - - identifier.Rule |= identifier_ns; - - semi_opt.Rule = Empty | PreferShiftHere() + ";"; - - //Prepare term set for conflict resolution - _skipTokensInPreview.UnionWith(new[] { ToTerm("."), identifier_raw, ToTerm(","), ToTerm("::"), ToTerm("["), ToTerm("]"), float_literal, integer_literal }); - - - var genericResolverHint = new GenericResolverHint(_skipTokensInPreview); - less_than.Rule = genericResolverHint + "<"; - - // ------------------------------------------------------------------------------------ - // Types - // ------------------------------------------------------------------------------------ - - // String - string_literal.Rule = string_literal_raw.List(); - string_literal_raw.AstNodeCreator = CreateStringRawLiteral; - - // Add string to literals - literal.Rule |= string_literal; - - float_qualifier.Rule = Keyword("unorm") | Keyword("snorm"); - - // scalars - var scalarTypes = new[] { ScalarType.Bool, ScalarType.Int, ScalarType.UInt, ScalarType.Float, ScalarType.Half, ScalarType.Double }; - foreach (var scalarType in scalarTypes) - { - NonTerminal scalarTerm; - var localScalarType = scalarType; - - if (scalarType == ScalarType.Float) - { - scalarTerm = new NonTerminal( - "float", - (context, node) => - { - var dynamicFloatType = Ast(node); - dynamicFloatType.Name = new Identifier(localScalarType.Name) { Span = SpanConverter.Convert(node.Span) }; - dynamicFloatType.Type = localScalarType.Type; - dynamicFloatType.Qualifiers = Qualifier.None; - if (node.ChildNodes.Count == 2) - { - dynamicFloatType.Qualifiers = (Qualifier)node.ChildNodes[0].AstNode; - } - }) - { - Rule = Keyword("float", true) | float_qualifier + Keyword("float", true) - }; - - } - else - { - scalarTerm = CreateScalarTerminal(scalarType); - } - - if (scalars.Rule == null) scalars.Rule = scalarTerm; - else scalars.Rule |= scalarTerm; - } - - // Buffer Rules - buffer_type.Rule = TypeName("Buffer") + less_than + simple_type_or_type_name + ">"; - - // Vectors Rules - vector_type.AstNodeCreator = CreateVectorAst; - vector_type.Rule = Keyword("vector") + less_than + scalars_or_typename + "," + number + ">"; - vector_type_list.Rule = vector_type; - - // Add all vector int1 int2 int3 int4... float1 float2 float3 float4... etc. - foreach (var scalarTypeIt in scalarTypes) - { - var scalarType = scalarTypeIt; - for (var dim = 1; dim <= 4; dim++) - { - var vectorTypeInstance = new VectorType(scalarTypeIt, dim); - var nonGenericType = vectorTypeInstance.ToNonGenericType(); - var name = nonGenericType.Name.Text; - vector_type_list.Rule |= new NonTerminal(name, - (ctx, node) => - { - var typeName = vectorTypeInstance.ToNonGenericType(SpanConverter.Convert(node.Span)); - node.AstNode = typeName; - }) { Rule = Keyword(name) }; - } - } - - // Matrices - matrix_type_simple.Rule = Keyword("matrix"); - matrix_type_simple.AstNodeCreator = (ctx, node) => - { - var typeName = Ast(node); - typeName.Name = new Identifier("matrix") { Span = SpanConverter.Convert(node.Span) }; - typeName.TypeInference.TargetType = new MatrixType(ScalarType.Float, 4, 4); - }; - - matrix_type.Rule = Keyword("matrix") + less_than + scalars_or_typename + "," + number + "," + number + ">"; - matrix_type.AstNodeCreator = CreateMatrixAst; - matrix_type_list.Rule = matrix_type | matrix_type_simple; - - // Add all matrix typedefs: int1x1 int1x2... float1x1 float1x2 float1x3 float1x4... etc. - foreach (var scalarTypeIt in scalarTypes) - { - var scalarType = scalarTypeIt; - for (var dimX = 1; dimX <= 4; dimX++) - for (var dimY = 1; dimY <= 4; dimY++) - { - var matrixTypeInstance = new MatrixType(scalarTypeIt, dimX, dimY); - var nonGenericType = matrixTypeInstance.ToNonGenericType(); - var name = nonGenericType.Name.Text; - - // var typeName = new TypeName(name) { Alias = matrixTypeInstance }; - matrix_type_list.Rule |= new NonTerminal( - name, - (ctx, node) => - { - var typeName = matrixTypeInstance.ToNonGenericType(SpanConverter.Convert(node.Span)); - node.AstNode = typeName; - }) { Rule = Keyword(name) }; - } - } - - // Sampler types - state_type.Rule = CreateRuleFromObjectTypes( - StateType.BlendState, - StateType.DepthStencilState, - StateType.RasterizerState, - StateType.SamplerState, - StateType.SamplerStateOld, - StateType.SamplerComparisonState); - - sampler_type.Rule = CreateRuleFromObjectTypes( - SamplerType.Sampler, - SamplerType.Sampler1D, - SamplerType.Sampler2D, - SamplerType.Sampler3D, - SamplerType.SamplerCube); - - sampler_type.AstNodeCreator = CreateTypeFromTokenAst; - - // Texture types - texture_type_profile_4.Rule = CreateRuleFromObjectTypes( - TextureType.Texture1D, - TextureType.Texture1DArray, - TextureType.Texture2D, - TextureType.Texture2DArray, - TextureType.Texture3D, - TextureType.TextureCube); - - texture_type.Rule = Keyword("texture") | texture_type_profile_4; - - // ByteAddressBuffer - byte_address_buffer.Rule = TypeName("ByteAddressBuffer") | TypeName("RWByteAddressBuffer"); - - // StructuredBuffer - structured_buffer_type.Rule = TypeName("AppendStructuredBuffer") | TypeName("ConsumeStructuredBuffer") | TypeName("RWStructuredBuffer") | TypeName("StructuredBuffer"); - structured_buffer.Rule = structured_buffer_type + less_than + scalars_and_vectors + ">"; - - // RWTexture.* - texture_type_profile_5.Rule = TypeName("RWBuffer") | TypeName("RWTexture1D") | TypeName("RWTexture1DArray") | TypeName("RWTexture2D") | TypeName("RWTexture2DArray") | TypeName("RWTexture3D"); - - texture_generic_simple_type.Rule = texture_type_profile_4 + less_than + scalars_and_vectors + ">" - | texture_type_profile_5 + less_than + scalars_and_vectors + ">"; - - texture_dms_type_profile_5.Rule = TypeName("Texture2DMS") | TypeName("Texture2DMSArray"); - - texture_generic_dms_type.Rule = texture_dms_type_profile_5 + less_than + scalars_and_vectors + ">" - | texture_dms_type_profile_5 + less_than + scalars_and_vectors + "," + number + ">"; - - texture_generic_type.Rule = texture_generic_simple_type | texture_generic_dms_type; - - // HullShader/DomainShader InputPatch/OutputPatch - patch_type.Rule = TypeName("InputPatch") | TypeName("OutputPatch"); - - patch_generic_type.Rule = patch_type + less_than + type + "," + number + ">"; - - texture_type_list.Rule = texture_type | texture_generic_type; - - // Types used by the geometry shader - geometry_stream.Rule = line_stream | point_stream | triangle_stream | stream_output_object; - - triangle_stream.Rule = TypeName("TriangleStream") + less_than + type + ">"; - - point_stream.Rule = TypeName("PointStream") + less_than + type + ">"; - - line_stream.Rule = TypeName("LineStream") + less_than + type + ">"; - - stream_output_object.Rule = TypeName("StreamOutputObject") + less_than + type + ">"; - - //// Shader object - //// shader_objects.Rule = ToTerm("VertexShader") | "PixelShader" | "GeometryShader"; - - string_type.Rule = Keyword("string"); - - // Add string to simple types - simple_type.Rule |= string_type; - - // Add Object types - object_type.Rule |= buffer_type - | state_type - | texture_type_list - | byte_address_buffer - | structured_buffer - | patch_generic_type - | interface_specifier - | class_specifier - | geometry_stream; - ////| shader_objects; - - // Type name - typename_for_cast.Rule = identifier + new IdentifierResolverHint(true); - - identifier_generic_parameter_list.Rule = MakePlusRule(identifier_generic_parameter_list, ToTerm(","), identifier_sub_generic); - - identifier_sub_generic.Rule = identifier_or_generic; - identifier_sub_generic.AstNodeCreator = CreateIdentifierSubGenericAst; - - //identifier_generic.Rule = identifier + new IdentifierResolverHint(true) + "<" + identifier_generic_parameter_list + ">"; - identifier_generic.Rule = identifier + new GenericResolverHint(_skipTokensInPreview) + "<" + identifier_generic_parameter_list + ">"; - - identifier_or_generic.Rule = identifier + new IdentifierResolverHint(true) - | identifier_generic + this.ReduceHere(); - - type_generic.Rule = identifier_or_generic; - - // Type used for cast (use valuetype) - type_for_cast.Rule = typename_for_cast - | value_type; - - // ------------------------------------------------------------------------------------ - // Expressions - // ------------------------------------------------------------------------------------ - - // Add special variable allowed as variable name and keyword - identifier_extended.Rule |= Keyword("sample") | Keyword("point"); - - // postfix_expression - postfix_expression.Rule |= compile_expression - | asm_expression - | state_expression; - - compile_expression.Rule = Keyword("compile") + identifier + method_invoke_expression_simple; - - // Match an asm block: asm { ... } - asm_expression.Rule = asm_block; - KeyTerms.Add(asm_block.Name, asm_block); - - state_expression.Rule = state_type + state_initializer; - - // Add cast_expression - cast_expression_raw.Rule = "(" + type_for_cast + rank_specifier.ListOpt() + ")" + cast_expression; - - cast_expression.Rule |= cast_expression_raw; - - // Syntax is for example: texture = ; - identifier_special_reference_expression.Rule = less_than + indexable_identifier + ">"; - - identifier_keyword.Rule = Keyword("texture"); - - simple_assignment_expression_statement.Rule |= indexable_identifier + assignment_operator + identifier_special_reference_expression + ";" - | identifier_keyword + assignment_operator + identifier_special_reference_expression + ";" - | identifier_keyword + assignment_operator + expression + ";"; - - state_initializer.Rule = "{" + simple_assignment_expression_statement.ListOpt() + "}"; - - // ------------------------------------------------------------------------------------ - // Attribute modifiers - // ------------------------------------------------------------------------------------ - attribute_qualifier_pre.Rule = attribute_list_opt; - - attribute_list_opt.Rule = MakeStarRule(attribute_list_opt, null, attribute_modifier); - - attribute_modifier.Rule = "[" + identifier + "]" - | "[" + identifier + "(" + literal_list.Opt() + ")" + "]"; - - // ------------------------------------------------------------------------------------ - // Variable modifiers - // ------------------------------------------------------------------------------------ - // storageClass = Storage_Class + Type_Modifier - storage_qualifier.Rule |= Keyword("extern") | Keyword("nointerpolation") | Keyword("precise") | Keyword("shared") | Keyword("groupshared") | Keyword("static") | Keyword("volatile") - | Keyword("row_major") | Keyword("column_major") | Keyword("linear") | Keyword("centroid") | Keyword("noperspective") | Keyword("sample") | Keyword("unsigned") - | Keyword("inline"); - - semantic.Rule = ToTerm(":") + identifier; - - packoffset.Rule = ToTerm(":") + Keyword("packoffset") + "(" + identifier_or_dot + ")"; - - register.Rule = ToTerm(":") + Keyword("register") + "(" + indexable_identifier + ")" - | ToTerm(":") + Keyword("register") + "(" + identifier + "," + indexable_identifier + ")"; - - - variable_declarator_qualifier_post_hlsl.Rule = Empty - | semantic - | semantic + packoffset + register.ListOpt() - | semantic + register.List() - | packoffset + register.ListOpt() - | register.List(); - - variable_declarator_qualifier_post.Rule = variable_declarator_qualifier_post_hlsl; - - // ------------------------------------------------------------------------------------ - // Declarations - // ------------------------------------------------------------------------------------ - - // Add typedef and constant buffer resource - declaration.Rule |= typedef_declaration - | constant_buffer_resource; - - indexable_identifier_declarator_list.Rule = MakePlusRule(indexable_identifier_declarator_list, ToTerm(","), indexable_identifier_declarator); - - // typedef [const] Type Name[Index]; - typedef_declaration.Rule = Keyword("typedef") + type + indexable_identifier_declarator_list + ";" - | Keyword("typedef") + storage_qualifier + type + indexable_identifier_declarator_list + ";"; - - annotations.Rule = less_than + variable_declaration_raw.ListOpt() + ">"; - - annotations_opt.Rule = Empty | annotations; - - // todo: add annotations_opt to variable_declarator qualifier post - - // Add annotations to variable declarator - variable_declarator_raw.Rule += annotations_opt; - - // Add special - variable_declarator.Rule |= variable_declarator_raw + state_initializer - | variable_declarator_raw + state_array_initializer; - - state_initializer_list.Rule = MakePlusRule(state_initializer_list, ToTerm(","), state_initializer); - - state_array_initializer.Rule = "{" + state_initializer_list + "}" - | "{" + state_initializer_list + "," + "}"; - - // interface definition - interface_specifier.Rule = Keyword("interface") + identifier_or_generic + "{" + method_declaration.ListOpt() + "}"; - - // class definition - class_specifier.Rule = Keyword("class") + identifier_or_generic + class_base_type + "{" + scope_declaration.ListOpt() + "}"; - class_base_type_list.Rule = MakePlusRule(class_base_type_list, ToTerm(","), type_generic); - class_base_type.Rule = (ToTerm(":") + class_base_type_list).Opt(); - - // buffer definition - constant_buffer_resource_type.Rule = Keyword("cbuffer") | Keyword("tbuffer") | Keyword("rgroup"); - constant_buffer_resource_type.AstNodeCreator = CreateConstantBufferTypeAst; - - constant_buffer_resource.Rule = attribute_qualifier_pre + constant_buffer_resource_type + identifier.Opt() + register.Opt() + "{" + declaration.ListOpt() + "}" + semi_opt; - - semantic_list_opt.Rule = semantic.ListOpt(); - - // Method - method_qualifier_post.Rule = semantic_list_opt; - - method_operator_identifier.Rule = Keyword("operator") + "[" + "]" - | Keyword("operator") + "[" + "]" + "[" + "]"; - method_special_identifier.Rule = identifier_extended + "." + method_operator_identifier | method_operator_identifier; - - method_declarator.Rule |= method_special_identifier + "(" + parameter_list + ")"; - - parameter_qualifier.Rule = storage_qualifier | Keyword("in") | Keyword("out") | Keyword("inout") | Keyword("point") | Keyword("line") | Keyword("lineadj") | Keyword("triangle") | Keyword("triangleadj"); - parameter_qualifier.AstNodeCreator = CreateParameterQualifier; - - parameter_qualifier_pre_list_opt.Rule = parameter_qualifier.ListOpt(); - parameter_qualifier_pre.Rule = parameter_qualifier_pre_list_opt; - // Make parameter_qualifier_pre transient as there is nothing else to parse then parameter_qualifier_pre_list_opt - parameter_qualifier_pre.Flags = TermFlags.IsTransient | TermFlags.NoAstNode; - - parameter_qualifier_post.Rule = semantic_list_opt - | "=" + initializer + semantic_list_opt; - parameter_qualifier_post.AstNodeCreator = CreateParameterQualifierPost; - - // ------------------------------------------------------------------------------------ - // Technique/pass - // ------------------------------------------------------------------------------------ - - // technique - technique_keyword.Rule = Keyword("technique") | Keyword("Technique") | Keyword("technique10") | Keyword("Technique10") | Keyword("technique11") | Keyword("Technique11"); - - technique_definition.Rule = attribute_qualifier_pre + technique_keyword + identifier.Opt() + annotations_opt + "{" + pass_definition.List() + "}" + semi_opt; - - // pass - pass_keyword.Rule = Keyword("pass") | Keyword("Pass"); - - pass_statement.Rule = method_invoke_expression_simple + ";" - | simple_assignment_expression_statement; - - pass_definition.Rule = attribute_qualifier_pre + pass_keyword + identifier.Opt() + annotations_opt + "{" + pass_statement.ListOpt() + "}" + semi_opt; - - // ------------------------------------------------------------------------------------ - // Top Level - // ------------------------------------------------------------------------------------ - - // Add the technique to the top level - toplevel_declaration.Rule |= technique_definition; - - /* - //// ------------------------------------------------------------------------------------ - //// Stride Grammar - //// ------------------------------------------------------------------------------------ - //var identifier_csharp = new NonTerminal("identifier_csharp"); - //var group = new NonTerminal("group"); - //var using_statement = new NonTerminal("using_statement"); - //group.Rule = "group" + identifier + "{" + scope_declaration.ListOpt() + "}"; - //identifier_csharp.Rule = MakePlusRule(identifier_csharp, ToTerm("."), identifier); - //using_statement.Rule = "using" + identifier + "=" + identifier_csharp + ";" - // | "using" + identifier_csharp + ";"; - //scope_declaration.Rule |= using_statement; - //toplevel_declaration.Rule |= group; - */ - - // ------------------------------------------------------------------------------------ - // Globals - // ------------------------------------------------------------------------------------ - // LanguageFlags = LanguageFlags.NewLineBeforeEOF; - LanguageFlags |= LanguageFlags.CreateAst; - } - - //public override void OnResolvingConflict(ConflictResolutionArgs args) - //{ - // switch (args.Context.CurrentParserInput.Term.Name) - // { - // case "<": - // args.Scanner.BeginPreview(); - // int ltCount = 0; - // string previewSym; - // while (true) - // { - // //Find first token ahead (using preview mode) that is either end of generic parameter (">") or something else - // Token preview; - // do - // { - // preview = args.Scanner.GetToken(); - // } while (_skipTokensInPreview.Contains(preview.Terminal) && preview.Terminal != base.Eof); - // //See what did we find - // previewSym = preview.Terminal.Name; - // if (previewSym == "<") - // ltCount++; - // else if (previewSym == ">" && ltCount > 0) - // { - // ltCount--; - // continue; - // } - // else - // break; - // } - // //if we see ">", then it is type argument, not operator - // if (previewSym == ">") - // args.Result = ParserActionType.Shift; - // else - // args.Result = ParserActionType.Reduce; - // args.Scanner.EndPreview(true); - // return; - // } - //} - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/IdentifierResolverHint.cs b/sources/shaders/Stride.Core.Shaders/Grammar/IdentifierResolverHint.cs deleted file mode 100644 index 78607fc445..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/IdentifierResolverHint.cs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Text.RegularExpressions; - -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - - // Semi-automatic conflict resolution hint - public class ResolveInCode : CustomGrammarHint - { - private Func resolver; - - - public ResolveInCode(ParserActionType parserAction, Func resolver) - : base(parserAction) - { - this.resolver = resolver; - } - - public override bool Match(ConflictResolutionArgs args) - { - return resolver(args); - } - } - - - - // Semi-automatic conflict resolution hint - public class IdentifierResolverHint : CustomGrammarHint - { - private bool isExpectingType; - - private CustomGrammarHint nextGrammarHint; - - public IdentifierResolverHint(bool isExpectingType, CustomGrammarHint nextGrammarHint = null) - : base(ParserActionType.Reduce) - { - this.isExpectingType = isExpectingType; - this.nextGrammarHint = nextGrammarHint; - } - - private string[] identifierPostFix = new string[] { "_OUTPUT", "OUT", "_INPUT", "IN", "OUTPUT_SCENE", "OUTPUT_SCENEENV", "PSSceneIn" }; - - private Regex regex = new Regex("(.*\r?\n)"); - - public override void Init(GrammarData grammarData) - { - base.Init(grammarData); - if (nextGrammarHint != null) - nextGrammarHint.Init(grammarData); - } - - public override bool Match(ConflictResolutionArgs args) - { - string identifier = args.Context.PreviousToken.Text; - - //var type = DeclarationManager.Instance.Find(args.Context, identifier); - - bool result; - - //if (type == DeclarationType.NotFound) - //{ - result = false; - if (isExpectingType) - { - // We are probably in a type cast - if (args.Context.CurrentToken.Text == ")") - { - // Verify that next token is an identifier, a number or left parenthesis => Then the current expression is certainly a cast - args.Scanner.BeginPreview(); - Token nextToken; - do - { - nextToken = args.Scanner.GetToken(); - } - while (nextToken.Terminal.FlagIsSet(TermFlags.IsNonGrammar) && nextToken.Terminal != Grammar.Eof); - - var nextTokenName = nextToken.Terminal.Name; - - if (nextTokenName == "identifier" || nextTokenName == "integer_literal" || nextTokenName == "float_literal" || nextTokenName == "(") - result = true; - args.Scanner.EndPreview(true); - } - } - - if (!result && nextGrammarHint != null) - { - result = nextGrammarHint.Match(args); - } - - // In case that we found something, use the reduce production where this hint is used - if (result) - { - args.Result = ParserActionType.Reduce; - args.ReduceProduction = null; - } - - //} else if (isExpectingType) - // result = type == DeclarationType.TypeName; - //else - // result = type == DeclarationType.Variable; - return result; - - } - } - - // Semi-automatic conflict resolution hint - public class GenericResolverHint : CustomGrammarHint - { - private TerminalSet skipTokens; - public GenericResolverHint(TerminalSet skipTokens) : base(ParserActionType.Reduce) - { - this.skipTokens = skipTokens; - } - - public override bool Match(ConflictResolutionArgs args) - { - if (args.Context.CurrentParserInput.Term.Name == "<") - { - args.Scanner.BeginPreview(); - int ltCount = 0; - string previewSym; - bool isKeyword = false; - while (true) - { - // Find first token ahead (using preview mode) that is either end of generic parameter (">") or something else - Token preview; - do - { - preview = args.Scanner.GetToken(); - } - while ((preview.Terminal.FlagIsSet(TermFlags.IsNonGrammar) || skipTokens.Contains(preview.Terminal)) && preview.Terminal != Grammar.Eof); - - isKeyword = preview.EditorInfo.Color == TokenColor.Keyword; - - // See what did we find - previewSym = preview.Terminal.Name; - if (previewSym == "<") - { - ltCount++; - } - else if (previewSym == ">" && ltCount > 0) - { - ltCount--; - } - else - break; - } - args.Scanner.EndPreview(true); - - // if we see ">", then it is type argument, not operator - // if previewSym == ">" then shift else reduce - if (previewSym == ">" || isKeyword) - { - args.Result = ParserActionType.Shift; - return true; - } - else - { - args.Result = ParserActionType.Reduce; - return true; - } - } - return false; - } - - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/NamedBlockKeyTerm.cs b/sources/shaders/Stride.Core.Shaders/Grammar/NamedBlockKeyTerm.cs deleted file mode 100644 index 8d059cbdc5..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/NamedBlockKeyTerm.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using GoldParser; - -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - internal class NamedBlockKeyTerm : DynamicKeyTerm - { - public NamedBlockKeyTerm(string text, string name) - : base(text, name) - { - } - - public override void Match(Tokenizer toknizer, out Token token) - { - var parser = toknizer.GoldParser; - - var location = toknizer.Location; - var nextSymbol = parser.ReadToken(); - - while (nextSymbol.SymbolType == SymbolType.WhiteSpace || nextSymbol.Index == (int)TokenType.NewLine) - nextSymbol = parser.ReadToken(); - - if (nextSymbol.Index != (int)TokenType.LeftCurly) - { - token = new Token(Grammar.SyntaxError, location, parser.TokenText, "Expecting '{'"); - return; - } - - var startPosition = parser.CharPosition; - - bool rightCurlyFound = false; - int length = 0; - for (int i = parser.CharPosition; i < parser.TextBuffer.Length; i++, length++) - { - if (parser.TextBuffer[i] == '}') - { - rightCurlyFound = true; - break; - } - } - - if (!rightCurlyFound) - { - token = new Token(Grammar.SyntaxError, location, parser.TokenText, "Closing '}' not found"); - return; - } - - token = new Token(this, location, parser.TextBuffer.Substring(startPosition, length), null); - - // Move the parser - parser.MoveBy(length+1); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Ast.cs b/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Ast.cs deleted file mode 100644 index 68dc4d8287..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Ast.cs +++ /dev/null @@ -1,1255 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Utility; -using StorageQualifier = Stride.Core.Shaders.Ast.StorageQualifier; - -namespace Stride.Core.Shaders.Grammar -{ - /// - /// Methods used to create the Abstract Syntax Tree.. - /// - public abstract partial class ShaderGrammar - { - #region Methods - - /// - /// The ast. - /// - /// - /// - /// - /// - /// - /// - protected static T Ast(ParseTreeNode node) where T : class, new() - { - T value = new T(); - object obj = value; - node.AstNode = value; - if (value is Node) - { - ((Node)obj).Span = SpanConverter.Convert(node.Span); - } - - return value; - } - - /// - /// The ast composite enum. - /// - /// - /// - /// - /// - /// - /// - protected static T AstCompositeEnum(ParseTreeNode node) where T : CompositeEnum, new() - { - var value = Ast(node); - value.Key = string.Empty; - value.Values.Add(value); - return value; - } - - /// - /// The collect qualifiers. - /// - /// - /// - /// - /// - protected static Qualifier CollectQualifiers(ParseTreeNode node) - { - var value = Qualifier.None; - foreach (var subNode in node.ChildNodes) - { - value |= (Qualifier)subNode.AstNode; - } - - if (value != Qualifier.None) - { - value.Span = SpanConverter.Convert(node.Span); - } - - return value; - } - - /// - /// The create array initializer expression ast. - /// - /// - /// - /// - /// - protected static void CreateArrayInitializerExpressionAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [3] - // "{" + initializer_list + "}"; - var value = Ast(node); - value.Items = (List)node.ChildNodes[1].AstNode; - } - - /// - /// The create assignement expression ast. - /// - /// - /// - /// - /// - protected static void CreateAssignementExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // [0] [1] [2] - // expression + operator + expression - var value = Ast(node); - - value.Target = GetExpression(node.ChildNodes[0]); - value.Operator = (AssignmentOperator)node.ChildNodes[1].AstNode; - value.Value = GetExpression(node.ChildNodes[2]); - } - - /// - /// Gets the expression. - /// - /// The node. - /// An expression - protected static Expression GetExpression(ParseTreeNode node) - { - if (node.AstNode is Identifier) - { - return new VariableReferenceExpression((Identifier)node.AstNode) { Span = SpanConverter.Convert(node.Span) }; - } - - return (Expression)node.AstNode; - } - - /// - /// The create assignment operator. - /// - /// - /// - /// - /// - protected static void CreateAssignmentOperator(ParsingContext parsingContext, ParseTreeNode node) - { - node.AstNode = AssignmentOperatorHelper.FromString(node.ChildNodes[0].Token.Text); - } - - /// - /// The create binary expression ast. - /// - /// - /// - /// - /// - protected static void CreateBinaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // [0] [1] [2] - // expression + operator + expression - var value = Ast(node); - - value.Left = (Expression)node.ChildNodes[0].AstNode; - value.Operator = BinaryOperatorHelper.FromString(node.ChildNodes[1].Token.Text); - value.Right = (Expression)node.ChildNodes[2].AstNode; - } - - /// - /// The create block statement ast. - /// - /// - /// - /// - /// - protected static void CreateBlockStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] - // "{" + block_item.Star() + "}"; - FillListFromNodes(node.ChildNodes[1].ChildNodes, value.Statements); - } - - /// - /// The create case statement ast. - /// - /// - /// - /// - /// - protected static void CreateCaseStatementAst(ParsingContext context, ParseTreeNode node) - { - var caseStatement = Ast(node); - - //// switch_case_statement.Rule = - //// [0] [1] - //// "case" + constant_expression + ":" - //// | _("default") + ":"; - if (node.ChildNodes.Count == 2) - { - caseStatement.Case = (Expression)node.ChildNodes[1].AstNode; - } - } - - /// - /// The create conditional expression ast. - /// - /// - /// - /// - /// - protected static void CreateConditionalExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] [3] - // logical_or_expression + "?" + expression + ":" + conditional_expression; - value.Condition = (Expression)node.ChildNodes[0].AstNode; - value.Left = (Expression)node.ChildNodes[2].AstNode; - value.Right = (Expression)node.ChildNodes[3].AstNode; - } - - /// - /// The create declaration specifier. - /// - /// - /// - /// - /// - protected static void CreateDeclarationSpecifier(ParsingContext context, ParseTreeNode node) - { - // declaration_specifiers = - // type - // | storage_qualifier.Plus() + type; - var storageQualifier = Qualifier.None; - TypeBase typeBase; - var i = 0; - - if (node.ChildNodes.Count == 2) - { - storageQualifier = CollectQualifiers(node.ChildNodes[0]); - i++; - } - - typeBase = (TypeBase)node.ChildNodes[i].AstNode; - node.AstNode = new Tuple(storageQualifier, typeBase); - } - - /// - /// The create declaration statement ast. - /// - /// - /// - /// - /// - protected static void CreateDeclarationStatementAst(ParsingContext context, ParseTreeNode node) - { - var declarationStatement = Ast(node); - declarationStatement.Content = (Node)node.ChildNodes[0].AstNode; - } - - /// - /// The create do while statement ast. - /// - /// - /// - /// - /// - protected static void CreateDoWhileStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// do_switch_statement.Rule = - //// [0] [1] [2] [3] [4] - //// _("do") + statement + "while" + "(" + expression + ")" + ";"; - value.Condition = (Expression)node.ChildNodes[4].AstNode; - value.Statement = (Statement)node.ChildNodes[1].AstNode; - value.IsDoWhile = true; - } - - /// - /// The create expression or empty ast. - /// - /// - /// - /// - /// - protected static void CreateExpressionOrEmptyAst(ParsingContext context, ParseTreeNode node) - { - if (node.ChildNodes.Count == 1) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - - if (node.AstNode == null) - { - Ast(node); - } - } - - protected static void CreateEmptyStatementAst(ParsingContext context, ParseTreeNode node) - { - Ast(node); - } - - /// - /// The create expression statement ast. - /// - /// - /// - /// - /// - protected static void CreateExpressionStatementAst(ParsingContext context, ParseTreeNode node) - { - - //// expression_statement.Rule = - //// empty_statement - //// | expression + ";"; - if (node.ChildNodes[0].AstNode is EmptyStatement) - { - node.AstNode = node.ChildNodes[0].AstNode; - return; - } - - var expressionStatement = Ast(node); - if (node.ChildNodes[0].AstNode is Expression) - { - // Standard expression statement - expressionStatement.Expression = (Expression)node.ChildNodes[0].AstNode; - } - else - { - // Expression statement like "break;" "continue;" "discard;" - // Standard expression statement - CreateIdentifierAst(context, node.ChildNodes[0]); - expressionStatement.Expression = new KeywordExpression((Identifier)node.ChildNodes[0].AstNode) { Span = SpanConverter.Convert(node.Span) }; - } - } - - /// - /// The create for statement ast. - /// - /// - /// - /// - /// - protected static void CreateForStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// for_statement.Rule = _ - //// [0] [1] [2] [3] [4] [5] [6] - //// _("for") + "(" + expression_statement + expression.Q() + ";" + expression.Q() + ")" + statement - //// | _("for") + "(" + variable_declaration_raw + expression.Q() + ";" + expression.Q() + ")" + statement; - var start = (Node)node.ChildNodes[2].AstNode; - if (start is Variable) - { - value.Start = new DeclarationStatement { Content = start, Span = start.Span }; - } - else - { - value.Start = (Statement)start; - } - - value.Condition = GetOptional(node.ChildNodes[3]); - value.Next = GetOptional(node.ChildNodes[4]); - value.Body = (Statement)node.ChildNodes[6].AstNode; - } - - /// - /// The create identifier ast. - /// - /// - /// - /// - /// - protected static void CreateIdentifierAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var nextNode = node; - - // Get the deepest valid node (either an AstNode or a Token) - while (nextNode.AstNode == null && nextNode.ChildNodes.Count > 0) - { - nextNode = nextNode.ChildNodes[0]; - } - - node.AstNode = nextNode.AstNode as Identifier; - - // Handle special names (sample, point...) - if (node.AstNode == null) - { - var value = Ast(node); - value.Text = nextNode.Token.Text; - } - } - - /// - /// The create identifier indexable ast. - /// - /// - /// - /// - /// - protected static void CreateIdentifierIndexableAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // identifier + rankSpecifier.Star(); - var value = Ast(node); - var identifier = (Identifier)node.ChildNodes[0].AstNode; - value.Text = identifier.Text; - value.Indices = new List(); - FillListFromNodes(node.ChildNodes[1].ChildNodes, value.Indices); - } - - /// - /// The create identifier list ast. - /// - /// - /// - /// - /// - protected static void CreateIdentifierListAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var identifiers = Ast>(node); - FillListFromNodes(node.ChildNodes, identifiers); - } - - /// - /// The create if statement ast. - /// - /// - /// - /// - /// - protected static void CreateIfStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// if_statement.Rule = - //// [0] [1] [2] [3] [4] [5] [6] - //// _("if") + "(" + expression + ")" + statement - ////| _("if") + "(" + expression + ")" + statement + PreferShiftHere() + "else" + statement; - value.Condition = (Expression)node.ChildNodes[2].AstNode; - value.Then = (Statement)node.ChildNodes[4].AstNode; - if (node.ChildNodes.Count == 7) - { - value.Else = (Statement)node.ChildNodes[6].AstNode; - } - } - - /// - /// The create indexer expression ast. - /// - /// - /// - /// - /// - protected static void CreateIndexerExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] - // postfix_expression + array_indexer - value.Target = (Expression)node.ChildNodes[0].AstNode; - value.Index = (Expression)node.ChildNodes[1].AstNode; - } - - /// - /// The create literal ast. - /// - /// - /// - /// - /// - protected static void CreateLiteralAst(ParsingContext context, ParseTreeNode node) - { - var literalValueNode = node.ChildNodes[0].AstNode; - if (literalValueNode is Literal) - { - node.AstNode = literalValueNode; - } - else - { - var value = Ast(node); - value.Value = literalValueNode; - value.Text = GetTokenText(node.ChildNodes[0]); - } - } - - /// - /// The create literal expression ast. - /// - /// - /// - /// - /// - protected static void CreateLiteralExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - value.Literal = (Literal)node.ChildNodes[0].AstNode; - } - - /// - /// The create member reference expression ast. - /// - /// - /// - /// - /// - protected static void CreateMemberReferenceExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] - // postfix_expression + "." + identifier - value.Target = (Expression)node.ChildNodes[0].AstNode; - value.Member = (Identifier)node.ChildNodes[2].AstNode; - } - - /// - /// The create method declaration ast. - /// - /// - /// - /// - /// - protected static void CreateMethodDeclarationAst(ParsingContext context, ParseTreeNode node) - { - //// method_declaration_raw + ";"; - node.AstNode = node.ChildNodes[0].AstNode; - } - - /// - /// The create method declaration raw ast. - /// - /// - /// - /// - /// - protected static void CreateMethodDeclarationRawAst(ParsingContext context, ParseTreeNode node) - { - //// method_declaration_raw.Rule = - //// [0] [1] [2] [3] - //// attribute_qualifier_pre + declaration_specifiers + method_declarator + method_qualifier_post; - var methodDeclaration = (MethodDeclaration)node.ChildNodes[2].AstNode; - node.AstNode = methodDeclaration; - methodDeclaration.Span = SpanConverter.Convert(node.Span); - - methodDeclaration.Attributes.AddRange((List)node.ChildNodes[0].AstNode); - var declarationSpecifiers = (Tuple)node.ChildNodes[1].AstNode; - methodDeclaration.Qualifiers = declarationSpecifiers.Item1; - methodDeclaration.ReturnType = declarationSpecifiers.Item2; - methodDeclaration.Qualifiers |= (Qualifier)node.ChildNodes[3].AstNode; - - methodDeclaration.UpdateParameters(); - } - - /// - /// The create method declarator ast. - /// - /// - /// - /// - /// - protected static void CreateMethodDeclaratorAst(ParsingContext context, ParseTreeNode node) - { - var methodDeclaration = Ast(node); - - //// method_declarator.Rule = - //// [0] [1] [2] [3] - //// identifier + "(" + parameter_list + ")" - ////| identifier + "(" + identifier_list + ")" - ////| identifier + "(" + "void" + ")" - ////| identifier + "(" + ")"; - methodDeclaration.Name = (Identifier)node.ChildNodes[0].AstNode; - if (node.ChildNodes.Count == 4) - { - if (node.ChildNodes[2].AstNode is List) - { - methodDeclaration.Parameters = (List)node.ChildNodes[2].AstNode; - } - else if (node.ChildNodes[2].AstNode is List) - { - var identifiers = (List)node.ChildNodes[2].AstNode; - foreach (var identifier in identifiers) - { - methodDeclaration.Parameters.Add(new Parameter() { Name = identifier, Span = identifier.Span }); - } - } - } - } - - /// - /// The create method definition ast. - /// - /// - /// - /// - /// - protected static void CreateMethodDefinitionAst(ParsingContext context, ParseTreeNode node) - { - //// method_definition.Rule = - //// [0] [1] [2] [3] - //// method_declaration_raw + "{" + block_item.ListOpt() + "}" + semi_opt; - var methodDefinition = Ast(node); - - ((MethodDeclaration)node.ChildNodes[0].AstNode).CopyTo(methodDefinition); - methodDefinition.UpdateParameters(); - - // [0] [1] [2] - // "{" + block_item.Star() + "}"; - FillListFromNodes(node.ChildNodes[2].ChildNodes, methodDefinition.Body); - } - - /// - /// The create method invoke expression ast. - /// - /// - /// - /// - /// - protected static void CreateMethodInvokeExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - //// method_invoke_expression.Rule - // [0] [1] [2] - // = identifier + "(" + argument_expression_list.Q() + ")"; - value.Target = GetExpression(node.ChildNodes[0]); - - var arguments = GetOptional>(node.ChildNodes[2]); - if (arguments != null) - { - value.Arguments = arguments; - } - } - - /// - /// The create parameter ast. - /// - /// - /// - /// - /// - protected virtual void CreateParameterAst(ParsingContext context, ParseTreeNode node) - { - //// parameter_declaration.Rule = - //// [0] [1] [2] [3] [4] - //// attribute_qualifier_pre + parameter_qualifier_pre + parameter_type + indexable_identifier.Opt() + parameter_qualifier_post; - var parameter = Ast(node); - - parameter.Attributes.AddRange((List)node.ChildNodes[0].AstNode); - parameter.Type = (TypeBase)node.ChildNodes[2].AstNode; - parameter.Name = GetOptional(node.ChildNodes[3]); - - // If it is an identifier with indices, transform it to a plain identifier with an array type - if (parameter.Name != null && parameter.Name.HasIndices) - { - // base type of the array will be added by variable declaration - parameter.Type = new ArrayType { Dimensions = new List(parameter.Name.Indices), Type = parameter.Type, Span = parameter.Name.Span }; - - parameter.Name.Indices = null; - } - } - - /// - /// The create parenthesized expression ast. - /// - /// - /// - /// - /// - protected static void CreateParenthesizedExpressionAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] - // "(" + argument_expression_list + ")" - value.Content = (Expression)node.ChildNodes[1].AstNode; - } - - /// - /// The create postfix unary expression ast. - /// - /// - /// - /// - /// - protected static void CreatePostfixUnaryExpressionAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// post_incr_decr_expression.Rule = - //// [0] [1] - //// postfix_expression + incr_or_decr; - value.Expression = (Expression)node.ChildNodes[0].AstNode; - var operatorText = node.ChildNodes[1].Token.Text; - value.Operator = (operatorText == "++") ? UnaryOperator.PostIncrement : UnaryOperator.PostDecrement; - } - - /// - /// The create qualifiers. - /// - /// - /// - /// - /// - protected static void CreateQualifiers(ParsingContext context, ParseTreeNode node) - { - var qualifier = node.ChildNodes.Count == 0 ? Qualifier.None : CollectQualifiers(node.ChildNodes[0]); - if (qualifier != Qualifier.None) - { - qualifier.Span = SpanConverter.Convert(node.Span); - } - - node.AstNode = qualifier; - } - - protected static void CreateQualifiersAst(ParsingContext context, ParseTreeNode node) - { - node.AstNode = CollectQualifiers(node.ChildNodes[0]); - } - - /// - /// The create rank specifier ast. - /// - /// - /// - /// - /// - protected static void CreateRankSpecifierAst(ParsingContext parsingcontext, ParseTreeNode node) - { - // [0] [1] [2] - // "[" + expression + "]"; - node.AstNode = node.ChildNodes[1].AstNode; - } - - /// - /// The create return statement ast. - /// - /// - /// - /// - /// - protected static void CreateReturnStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// _("return") + ";" | _("return") + expression + ";"; - if (node.ChildNodes.Count == 2) - { - value.Value = (Expression)node.ChildNodes[1].AstNode; - } - } - - /// - /// The create shader ast. - /// - /// - /// - /// - /// - protected static void CreateShaderAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - // For top level node, embed it into a browsable node in order for Irony to browse it. - node.AstNode = new IronyBrowsableNode(value); - value.Declarations = (List)node.ChildNodes[0].AstNode; - } - - /// - /// The create statement ast. - /// - /// - /// - /// - /// - protected static void CreateStatementAst(ParsingContext context, ParseTreeNode node) - { - // statement.Rule = - // attribute_list_opt + statement_raw; - var value = (Statement)node.ChildNodes[1].AstNode; - node.AstNode = value; - value.Span = SpanConverter.Convert(node.Span); - value.Attributes = (List)node.ChildNodes[0].AstNode; - } - - /// - /// The create structure ast. - /// - /// - /// - /// - /// - protected static void CreateStructureAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - //// struct_specifier.Rule = - //// [0] [1] [2] [3] - //// "struct" + identifier.Q() + "{" + variable_declaration.ListOpt() + "}" - value.Name = GetOptional(node.ChildNodes[1]); - FillListFromNodes(node.ChildNodes[3].ChildNodes, value.Fields); - } - - /// - /// The create switch cast group ast. - /// - /// - /// - /// - /// - protected static void CreateSwitchCastGroupAst(ParsingContext context, ParseTreeNode node) - { - var group = Ast(node); - - //// switch_case_group.Rule = switch_case_statement.Plus() + statement.Plus(); - FillListFromNodes(node.ChildNodes[0].ChildNodes, group.Cases); - FillListFromNodes(node.ChildNodes[1].ChildNodes, group.Statements); - } - - /// - /// The create switch statement ast. - /// - /// - /// - /// - /// - protected static void CreateSwitchStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// switch_statement.Rule = - //// [0] [1] [2] [3] [4] [5] [6] - //// _("switch") + "(" + expression + ")" + "{" + switch_case_group.Star() + "}"; - value.Condition = (Expression)node.ChildNodes[2].AstNode; - FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Groups); - } - - /// - /// The create type name ast. - /// - /// - /// - /// - /// - protected static void CreateTypeNameAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - value.Name = (Identifier)node.ChildNodes[0].AstNode; - } - - /// - /// The create type name from token ast. - /// - /// - /// - /// - /// - protected static void CreateTypeNameFromTokenAst(ParsingContext parsingcontext, ParseTreeNode node) - { - CreateTypeFromTokenAst(parsingcontext, node); - } - - protected static void CreateTypeFromTokenAst(ParsingContext parsingcontext, ParseTreeNode node) where T : TypeBase, new() - { - if (node.ChildNodes.Count == 1 && node.ChildNodes[0].AstNode is T) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - else - { - var value = Ast(node); - var nextNode = node; - while (nextNode.Token == null) - { - nextNode = nextNode.ChildNodes[0]; - } - - value.Name = new Identifier(nextNode.Token.Text) { Span = SpanConverter.Convert(node.Span) }; - } - } - - /// - /// The create unary expression ast. - /// - /// - /// - /// - /// - protected static void CreateUnaryExpressionAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - //// unary_expression_raw.Rule = - //// [0] [1] [0] [1] - //// incr_or_decr + unary_expression | unary_operator + cast_expression; - value.Operator = UnaryOperatorHelper.FromString(node.ChildNodes[0].Token.Text); - value.Expression = (Expression)node.ChildNodes[1].AstNode; - } - - /// - /// Creates the variable group ast. - /// - /// - /// The parsing context. - /// - /// - /// The tree node. - /// - protected static void CreateVariableGroupAst(ParsingContext parsingContext, ParseTreeNode node) - { - // variable_group.Rule = - // [0] [1] - // attribute_qualifier_pre + variable_group_raw - - // This is a type declaration and not a variable - if (node.ChildNodes[1].AstNode is TypeBase) - { - var typeBase = (TypeBase)node.ChildNodes[1].AstNode; - var attributes = (List)node.ChildNodes[0].AstNode; - typeBase.Attributes = attributes; - node.AstNode = typeBase; - } - else - { - // else this is a standard variable declaration. - var var = (Variable)node.ChildNodes[1].AstNode; - var.Attributes.AddRange((List)node.ChildNodes[0].AstNode); - node.AstNode = var; - } - } - - /// - /// The create variable group raw ast. - /// - /// - /// - /// - /// - protected static void CreateVariableGroupRawAst(ParsingContext parsingContext, ParseTreeNode node) - { - var var = Ast(node); - - //// [0] [1] - // declaration_specifiers + variable_declarator_list.Q() + ";"; - var declarationSpecifiers = (Tuple)node.ChildNodes[0].AstNode; - var.Qualifiers = declarationSpecifiers.Item1; - var.Type = declarationSpecifiers.Item2; - - var declarators = GetOptional>(node.ChildNodes[1]); - - if (declarators != null) - { - var.SubVariables = declarators; - - // Update array type for sub variables - foreach(var subVariable in declarators) - { - if (subVariable.Type is ArrayType) - ((ArrayType)subVariable.Type).Type = var.Type; - else - subVariable.Type = var.Type; - } - } - - // If this is a variable group, check if we can transform it to a single variable declaration. - if (var.IsGroup) - { - // If the variable is a single variable declaration, replace the group - if (var.SubVariables.Count == 1) - { - var subVariable = var.SubVariables[0]; - subVariable.MergeFrom(var); - node.AstNode = subVariable; - } - } - else - { - // If variable declarators is 0, check if this is a named struct - var.Type.Qualifiers = var.Qualifiers; - if (var.Type is StructType) - { - node.AstNode = var.Type; - } - else if (var.Type is InterfaceType) - { - node.AstNode = var.Type; - } - else if (var.Type is ClassType) - { - node.AstNode = var.Type; - } - else - { - parsingContext.AddParserError("Expecting identifier for variable declaration [{0}]", var.Type); - } - - if (var.Type.Name == null) - { - parsingContext.AddParserError("Cannot declare anonymous type at the top level"); - } - } - } - - /// - /// The create while statement ast. - /// - /// - /// - /// - /// - protected static void CreateWhileStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// switch_statement.Rule = - //// [0] [1] [2] [3] [4] - //// _("while") + "(" + expression + ")" + statement; - value.Condition = (Expression)node.ChildNodes[2].AstNode; - value.Statement = (Statement)node.ChildNodes[4].AstNode; - } - - /// - /// The create float literal. - /// - /// - /// - /// - /// - protected void CreateFloatLiteral(ParsingContext context, ParseTreeNode node) - { - var literalFloat = Ast(node); - float value; - var floatStr = node.Token.Text; - bool isHalf = floatStr.EndsWith("h", StringComparison.CurrentCultureIgnoreCase); - - // Remove postfix - if (floatStr.EndsWith("d", StringComparison.CurrentCultureIgnoreCase) - || floatStr.EndsWith("f", StringComparison.CurrentCultureIgnoreCase) - || isHalf) - { - floatStr = floatStr.Substring(0, floatStr.Length - 1); - } - - if (!float.TryParse( - floatStr, - NumberStyles.Float, - CultureInfo.InvariantCulture, - out value)) - { - context.AddParserError("Unable to parse float [{0}]", node.Token.Text); - } - - literalFloat.Value = value; - literalFloat.Text = node.Token.Text; - - // Don't output half - // TODO MOVE THIS TO GLSL WRITER - if (isHalf) - { - literalFloat.Text = floatStr; - } - } - - /// - /// The create integer literal. - /// - /// - /// - /// - /// - protected void CreateIntegerLiteral(ParsingContext context, ParseTreeNode node) - { - var literalInt = Ast(node); - int value = 0; - bool isOctal = false; - var intStr = node.Token.Text; - var style = NumberStyles.Integer; - - // Remove post-fix - if (intStr.EndsWith("l", StringComparison.CurrentCultureIgnoreCase)) - { - intStr = intStr.Substring(0, intStr.Length - 1); - } - - // Check for Hexa decimal - if (intStr.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase)) - { - intStr = intStr[2..]; - style = NumberStyles.HexNumber; - } - else if (intStr.StartsWith('0') && intStr.Length > 1) - { - // Else parse Octal - isOctal = true; - try - { - value = Convert.ToInt32(intStr, 8); - } - catch (FormatException) - { - context.AddParserError("Unable to parse octal number [{0}]", node.Token.Text); - } - } - - // If on octal, parse regular hexa - if (!isOctal && !int.TryParse( - intStr, - style, - CultureInfo.InvariantCulture, - out value)) - { - context.AddParserError("Unable to parse integer [{0}]", node.Token.Text); - } - - literalInt.Value = value; - literalInt.Text = node.Token.Text; - } - - /// - /// The create storage qualifier. - /// - /// - /// - /// - /// - protected virtual void CreateStorageQualifier(ParsingContext context, ParseTreeNode node) - { - var qualifier = Qualifier.None; - if (node.ChildNodes.Count == 1) - { - qualifier = Shaders.Ast.StorageQualifier.Parse(node.ChildNodes[0].Token.Text); - qualifier.Span = SpanConverter.Convert(node.Span); - } - - node.AstNode = qualifier; - } - - /// - /// The create variable declarator ast. - /// - /// - /// - /// - /// - protected virtual void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = (Variable)node.ChildNodes[0].AstNode; - node.AstNode = value; - - //// variable_declarator.Rule = - //// [0] [1] [2] - //// variable_declarator_raw - ////| variable_declarator_raw + "=" + initializer; - - // Get initial value - if (node.ChildNodes.Count == 3) - { - value.InitialValue = (Expression)node.ChildNodes[2].AstNode; - } - } - - /// - /// The create variable declarator raw ast. - /// - /// - /// - /// - /// - protected virtual void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node) - { - var value = Ast(node); - - //// variable_declarator_raw.Rule = - //// [0] [1] - //// indexable_identifier_declarator + variable_declarator_qualifier_post - var identifier = (Identifier)node.ChildNodes[0].AstNode; - - // Get modifiers - value.Qualifiers = (Qualifier)node.ChildNodes[1].AstNode; - - value.Name = identifier; - - // If it is an identifier with indices, transform it to a plain identifier with an array type - if (identifier.HasIndices) - { - // base type of the array will be added by variable declaration - value.Type = new ArrayType { Dimensions = new List(identifier.Indices), Span = identifier.Span }; - identifier.Indices = null; - } - } - - private static void CheckFieldDeclarationAst(ParsingContext context, ParseTreeNode node) - { - //// field_declaration.Rule = - //// [0] [1] [2] - //// field_qualifier_pre + type + variable_declarator_list + ";"; - // Check that field has a declarator - - // If field declaration is a type, then this is an error - if (node.ChildNodes[0].AstNode is TypeBase) - { - var typeBase = (TypeBase)node.ChildNodes[0].AstNode; - var baseTypeSpan = typeBase.Span; - var location = ((Irony.Parsing.IBrowsableAstNode)typeBase).Location; - location.Position += baseTypeSpan.Length; - - context.AddParserMessage(ParserErrorLevel.Error, location, "Field declaration must contain an identifier"); - return; - } - - var var = (Variable)node.ChildNodes[0].AstNode; - node.AstNode = var; - - // Check that declarator doesn't contain initial values - foreach (var variableDeclarator in var.Instances()) - { - if (variableDeclarator.InitialValue != null) - { - context.AddParserMessage( - ParserErrorLevel.Error, ((Irony.Parsing.IBrowsableAstNode)variableDeclarator.InitialValue).Location, "Field declaration cannot contain an initial value"); - } - } - } - - private static void CreateVariableReferenceExpressionAst(ParsingContext context, ParseTreeNode node) - { - //// variable_identifier.Rule = identifier; - var value = Ast(node); - - value.Name = (Identifier)node.ChildNodes[0].AstNode; - } - #endregion - - private static void CreateTypeReferenceExpression(ParsingContext context, ParseTreeNode node) - { - //// variable_identifier.Rule = identifier; - var value = Ast(node); - - value.Type = (TypeBase)node.ChildNodes[0].AstNode; - } - - private static void CreateExpressionListAst(ParsingContext context, ParseTreeNode node) - { - //// expression.Rule = - //// [0] [1] [2] - //// assignment_expression - //// | expression + "," + assignment_expression; - - if (node.ChildNodes.Count == 1) - { - node.AstNode = node.ChildNodes[0].AstNode; - } - else - { - var value = Ast(node); - FillListFromNodes(node.ChildNodes, value); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Helpers.cs b/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Helpers.cs deleted file mode 100644 index 34bfb95be4..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.Helpers.cs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Grammar -{ - public abstract partial class ShaderGrammar - { - #region Public Methods - - protected KeyTerm Keyword(string term, bool isCaseInsensitive = false) - { - var keyTerm = ToTerm(term); - keyTerm.AstNodeConfig = new TokenInfo { TokenCategory = TokenCategory.Keyword, IsCaseInsensitive = isCaseInsensitive}; - return keyTerm; - } - - protected KeyTerm TypeName(string term) - { - var keyTerm = ToTerm(term); - keyTerm.AstNodeConfig = new TokenInfo { TokenCategory = TokenCategory.Typename}; - return keyTerm; - } - - protected void Term(Terminal terminal, TokenCategory category, TokenType type) - { - var config = (TokenInfo)terminal.AstNodeConfig; - if (config == null) - { - config = new TokenInfo { TokenCategory = category }; - terminal.AstNodeConfig = config; - } - TokenTypeToTerminals.Add(type, terminal); - } - - protected KeyTerm Op(string term, TokenType type) - { - var keyTerm = ToTerm(term); - keyTerm.AstNodeConfig = new TokenInfo { TokenCategory = TokenCategory.Operator}; - TokenTypeToTerminals.Add(type, keyTerm); - return keyTerm; - } - - protected KeyTerm Punc(string term, TokenType type) - { - var keyTerm = ToTerm(term); - keyTerm.AstNodeConfig = new TokenInfo { TokenCategory = TokenCategory.Puntuation }; - TokenTypeToTerminals.Add(type, keyTerm); - return keyTerm; - } - - #endregion - - #region Methods - - protected static T GetOptional(ParseTreeNode node) where T : class - { - if (node.ChildNodes.Count == 1) return (T)node.ChildNodes[0].AstNode; - return null; - } - - protected static T CreateEnumFlags(T initialValue, IEnumerable enumValues) where T : CompositeEnum, new() - { - T value = initialValue; - foreach (var storageClassItem in enumValues) - { - value = CompositeEnum.OperatorOr(value, (T)storageClassItem.AstNode); - } - - return value; - } - - protected BnfExpression CreateRuleFromObjectTypes(params ObjectType[] types) - { - return CreateRuleFromObjectTypes(types.AsEnumerable()); - } - - protected BnfExpression CreateRuleFromObjectTypes(IEnumerable types) where T : ObjectType - { - BnfExpression rule = null; - - foreach (var type in types) - { - if (rule == null) - { - rule = TypeName(type.Name); - } - else - { - rule |= TypeName(type.Name); - } - - // Add alternative names as well - foreach (var alternativeName in type.AlternativeNames) - rule |= TypeName(alternativeName); - } - return rule; - } - - private static void CreateListFromNode(ParsingContext context, ParseTreeNode node) - { - var list = new List(); - FillListFromNodes(node.ChildNodes, list); - node.AstNode = list; - } - - protected static void FillListFromNodes(IEnumerable nodes, IList items) - { - foreach (var childNode in nodes) - { - if (childNode.AstNode != null) - items.Add((TItem)childNode.AstNode); - } - } - - protected static void FillTokenText(ParseTreeNode node, StringBuilder builder) - { - if (node.Token != null) builder.Append(node.Token.Text); - - foreach (var subNode in node.ChildNodes) - { - FillTokenText(subNode, builder); - } - } - - protected static string GetTokenText(ParseTreeNode node) - { - var builder = new StringBuilder(); - FillTokenText(node, builder); - return builder.ToString(); - } - - protected static string ParseStringFromNode(ParseTreeNode node) - { - while (node.ChildNodes.Count == 1) - { - node = node.ChildNodes[0]; - } - - return (string)node.AstNode; - } - - protected static NonTerminal T(string name) - { - return new NonTerminal(name); - } - - protected static NonTerminal T(string name, AstNodeCreator nodeCreator) - { - return new NonTerminal(name, nodeCreator); - } - - protected static NonTerminal TT(string name) - { - var nonTerminal = T(name); - nonTerminal.Flags = TermFlags.IsTransient | TermFlags.NoAstNode; - return nonTerminal; - } - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.cs b/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.cs deleted file mode 100644 index 8b7aa01624..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderGrammar.cs +++ /dev/null @@ -1,661 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Grammar -{ - /// - /// Generic grammar for a shading language. - /// - /// - /// This grammar provides the core grammar for a shading language including expressions (binary, unary, methods...), statements (if, for, while...). - /// - public abstract partial class ShaderGrammar : Irony.Parsing.Grammar - { - // ReSharper disable InconsistentNaming - // ------------------------------------------------------------------------------------ - // Comments - // ------------------------------------------------------------------------------------ - public readonly Terminal single_line_comment = new Terminal("single_line_comment", Irony.Parsing.TokenCategory.Comment, TermFlags.IsNonGrammar) { AstNodeConfig = new TokenInfo(TokenCategory.Comment) }; - public readonly Terminal multi_line_comment = new Terminal("multi_line_comment", Irony.Parsing.TokenCategory.Comment, TermFlags.IsNonGrammar) { AstNodeConfig = new TokenInfo(TokenCategory.Comment) }; - - // ------------------------------------------------------------------------------------ - // Literals - // ------------------------------------------------------------------------------------ - public readonly Terminal float_literal = new Terminal("float_literal") { AstNodeConfig = new TokenInfo(TokenCategory.Number) }; - public readonly Terminal integer_literal = new Terminal("integer_literal") { AstNodeConfig = new TokenInfo(TokenCategory.Number) }; - public readonly NonTerminal number = TT("number"); - public readonly Terminal identifier_raw = new Terminal("identifier") { AstNodeConfig = new TokenInfo(TokenCategory.Identifier) }; - public readonly NonTerminal identifier = TT("identifier"); - public readonly NonTerminal boolean = T("boolean", (context, node) => node.AstNode = bool.Parse(node.ChildNodes[0].Token.Text)); - - // ------------------------------------------------------------------------------------ - // Terminals - // ------------------------------------------------------------------------------------ - public readonly Terminal unknown = new Terminal("unknown", Irony.Parsing.TokenCategory.Content); - - public readonly Terminal whitespace = new Terminal("whitespace", Irony.Parsing.TokenCategory.Content, TermFlags.IsNonGrammar) { AstNodeConfig = new TokenInfo(TokenCategory.WhiteSpace) }; - public readonly Terminal newline = new Terminal("newline", Irony.Parsing.TokenCategory.Content, TermFlags.IsNonGrammar) { AstNodeConfig = new TokenInfo(TokenCategory.WhiteSpace)}; - // Pseudo terminal - protected readonly NonTerminal semi_opt = TT("semi_opt"); - protected readonly NonTerminal less_than = TT("less_than"); - - // ------------------------------------------------------------------------------------ - // NonTerminals - // ------------------------------------------------------------------------------------ - protected readonly NonTerminal additive_expression = TT("additive_expression"); - protected readonly NonTerminal additive_expression_raw = T("additive_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal and_expression = TT("and_expression"); - protected readonly NonTerminal and_expression_raw = T("and_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal argument_expression_list = T("argument_expression_list", CreateListFromNode); - protected readonly NonTerminal array_initializer_expression = T("array_initializer_expression", CreateArrayInitializerExpressionAst); - protected readonly NonTerminal assignment_expression = TT("assignment_expression"); - protected readonly NonTerminal assignment_expression_raw = T("assignment_expression_raw", CreateAssignementExpressionAst); - protected readonly NonTerminal assignment_operator = T("assignment_operator", CreateAssignmentOperator); - protected readonly NonTerminal attribute_qualifier_pre = TT("attribute_qualifier_pre"); - protected readonly NonTerminal block_item = TT("block_item"); - protected readonly NonTerminal block_statement = T("block_statement", CreateBlockStatementAst); - protected readonly NonTerminal break_statement = T("break_statement", CreateExpressionStatementAst); - protected readonly NonTerminal cast_expression = TT("cast_expression"); - protected readonly NonTerminal conditional_expression = TT("conditional_expression"); - protected readonly NonTerminal conditional_expression_raw = T("conditional_expression_raw", CreateConditionalExpressionAst); - protected readonly NonTerminal constant_expression = TT("constant_expression"); - protected readonly NonTerminal continue_statement = T("continue_statement", CreateExpressionStatementAst); - protected readonly NonTerminal declaration = TT("declaration"); - protected readonly NonTerminal declaration_specifiers = T("declaration_specifiers", CreateDeclarationSpecifier); - protected readonly NonTerminal declaration_statement = T("declaration_statement", CreateDeclarationStatementAst); - protected readonly NonTerminal discard_statement = T("discard_statement", CreateExpressionStatementAst); - protected readonly NonTerminal do_while_statement = T("do_while_statement", CreateDoWhileStatementAst); - protected readonly NonTerminal empty_statement = T("empty_statement", CreateEmptyStatementAst); - protected readonly NonTerminal equality_expression = TT("equality_expression"); - protected readonly NonTerminal equality_expression_raw = T("equality_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal exclusive_or_expression = TT("exclusive_or_expression"); - protected readonly NonTerminal exclusive_or_expression_raw = T("exclusive_or_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal expression = TT("expression"); - protected readonly NonTerminal expression_list = T("expression_list", CreateExpressionListAst); - protected readonly NonTerminal expression_or_empty = T("expression_or_empty", CreateExpressionOrEmptyAst); - protected readonly NonTerminal expression_statement = T("expression_statement", CreateExpressionStatementAst); - protected readonly NonTerminal for_statement = T("for_statement", CreateForStatementAst); - protected readonly NonTerminal field_declaration = T("field_declaration", CheckFieldDeclarationAst); - protected readonly NonTerminal identifier_list = T("identifier_list", CreateIdentifierListAst); - protected readonly NonTerminal if_statement = T("if_terminal", CreateIfStatementAst); - protected readonly NonTerminal inclusive_or_expression = TT("inclusive_or_expression"); - protected readonly NonTerminal inclusive_or_expression_raw = T("inclusive_or_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal incr_or_decr = TT("incr_or_decr"); - protected readonly NonTerminal identifier_extended = T("identifier_extended", CreateIdentifierAst); - protected readonly NonTerminal indexable_identifier = T("identifier_indexable", CreateIdentifierIndexableAst); - protected readonly NonTerminal indexable_identifier_declarator = T("indexable_identifier_declarator", CreateIdentifierIndexableAst); - protected readonly NonTerminal indexer_expression = T("indexer-expression", CreateIndexerExpressionAst); - protected readonly NonTerminal initializer = TT("initializer"); - protected readonly NonTerminal initializer_list = T("initializer_list", CreateListFromNode); - protected readonly NonTerminal iteration_statement = TT("iteration_statement"); - protected readonly NonTerminal jump_statement = TT("jump_statement"); - protected readonly NonTerminal literal = T("literal", CreateLiteralAst); - protected readonly NonTerminal literal_expression = T("literal-expression", CreateLiteralExpressionAst); - protected readonly NonTerminal literal_list = T("literal_list", CreateListFromNode); - protected readonly NonTerminal logical_and_expression = TT("logical_and_expression"); - protected readonly NonTerminal logical_and_expression_raw = T("logical_and_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal logical_or_expression = TT("logical_or_expression"); - protected readonly NonTerminal logical_or_expression_raw = T("logical_or_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal matrix_type = T("matrix_type"); - protected readonly NonTerminal matrix_type_simple = T("matrix_type_simple"); - protected readonly NonTerminal matrix_type_list = TT("matricx_type_list"); - protected readonly NonTerminal member_reference_expression = T("member_reference_expression", CreateMemberReferenceExpressionAst); - protected readonly NonTerminal method_declaration = T("method_declaration", CreateMethodDeclarationAst); - protected readonly NonTerminal method_declaration_raw = T("method_declaration_raw", CreateMethodDeclarationRawAst); - protected readonly NonTerminal method_declarator = T("method_declarator", CreateMethodDeclaratorAst); - protected readonly NonTerminal method_definition = T("method_definition", CreateMethodDefinitionAst); - protected readonly NonTerminal method_definition_or_declaration = TT("method_definition_or_declaration"); - protected readonly NonTerminal method_invoke_expression = T("method_invoke_expression", CreateMethodInvokeExpressionAst); - protected readonly NonTerminal method_invoke_expression_simple = T("method_invoke_expression_simple", CreateMethodInvokeExpressionAst); - protected readonly NonTerminal method_qualifier_post = TT("method_qualifier_post"); - protected readonly NonTerminal multiplicative_expression = TT("multiplicative_expression"); - protected readonly NonTerminal multiplicative_expression_raw = T("multiplicative_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal object_type = TT("object_type"); - protected readonly NonTerminal parameter_declaration = T("parameter_declaration"); - protected readonly NonTerminal parameter_list = T("parameter_list", CreateListFromNode); - protected readonly NonTerminal parameter_qualifier_pre = T("parameter_qualifier_pre"); - protected readonly NonTerminal parameter_qualifier_post = T("parameter_qualifier_post"); - protected readonly NonTerminal parameter_type = TT("parameter_type"); - protected readonly NonTerminal parenthesized_expression = T("parenthesized_expression", CreateParenthesizedExpressionAst); - protected readonly NonTerminal post_incr_decr_expression = T("post_incr_decr_expression", CreatePostfixUnaryExpressionAst); - protected readonly NonTerminal postfix_expression = TT("postfix_expression"); - protected readonly NonTerminal primary_expression = TT("primary-expression"); - protected readonly NonTerminal rank_specifier = T("rank_specifier", CreateRankSpecifierAst); - protected readonly NonTerminal rank_specifier_empty = T("rank_specifier_empty", CreateRankSpecifierAst); - protected readonly NonTerminal relational_expression = TT("relational_expression"); - protected readonly NonTerminal relational_expression_raw = T("relational_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal return_statement = T("return_statement", CreateReturnStatementAst); - protected readonly NonTerminal sampler_type = T("sampler_type"); - protected readonly NonTerminal scalars = TT("scalars"); - protected readonly NonTerminal scalars_and_vectors = TT("scalars_and_vectors"); - protected readonly NonTerminal scalars_or_typename = TT("scalars_or_typename"); - protected readonly NonTerminal scope_declaration = TT("scope_declaration"); - protected readonly NonTerminal selection_statement = TT("selection_statement"); - protected readonly NonTerminal shader = T("shader", CreateShaderAst); - protected readonly NonTerminal shift_expression = TT("shift_expression"); - protected readonly NonTerminal shift_expression_raw = T("shift_expression_raw", CreateBinaryExpressionAst); - protected readonly NonTerminal simple_assignment_expression_statement = T("simple_assignment_expression_statement", CreateAssignementExpressionAst); - protected readonly NonTerminal simple_type = TT("simple_type"); - protected readonly NonTerminal simple_type_or_type_name = TT("simple_type_or_type_name"); - protected readonly NonTerminal statement = T("Statement", CreateStatementAst); - protected readonly NonTerminal statement_raw = TT("statement_raw"); - protected readonly NonTerminal storage_qualifier = T("storage_qualifier"); - protected readonly NonTerminal storage_qualifier_list_opt = T("storage_qualifier_list_opt", CreateQualifiers); - protected readonly NonTerminal struct_specifier = T("struct_specifier", CreateStructureAst); - protected readonly NonTerminal switch_case_group = T("switch_case_group", CreateSwitchCastGroupAst); - protected readonly NonTerminal switch_case_statement = T("switch_case_statement", CreateCaseStatementAst); - protected readonly NonTerminal switch_statement = T("switch_statement", CreateSwitchStatementAst); - protected readonly NonTerminal toplevel_declaration = TT("toplevel_declaration"); - protected readonly NonTerminal toplevel_declaration_list = T("toplevel_declaration_list", CreateListFromNode); - protected readonly NonTerminal type = TT("type"); - protected readonly NonTerminal type_for_cast = TT("type_for_cast"); - protected readonly NonTerminal type_name = T("type_name", CreateTypeNameAst); - protected readonly NonTerminal typename_for_cast = T("typename_for_cast", CreateTypeNameAst); - protected readonly NonTerminal unary_expression = TT("unary_expression"); - protected readonly NonTerminal unary_expression_raw = T("unary_expression_raw", CreateUnaryExpressionAst); - protected readonly NonTerminal unary_operator = TT("unary_operator"); - protected readonly NonTerminal value_type = TT("value-type"); - protected readonly NonTerminal type_reference_expression = T("type_reference_expression", CreateTypeReferenceExpression); - protected readonly NonTerminal variable_declaration = T("variable_declaration", CreateVariableGroupAst); - protected readonly NonTerminal variable_declaration_raw = T("variable_declaration_raw", CreateVariableGroupRawAst); - protected readonly NonTerminal variable_declarator = T("variable_declarator"); - protected readonly NonTerminal variable_declarator_raw = T("variable_declarator_raw"); - protected readonly NonTerminal variable_declarator_qualifier_post = TT("variable_declarator_qualifier_post"); - protected readonly NonTerminal variable_declarator_list = T("variable_declarator_list", CreateListFromNode); - protected readonly NonTerminal variable_identifier = T("variable_identifier", CreateVariableReferenceExpressionAst); - - ////protected readonly NonTerminal layout_qualifier_pre = T("layout_qualifier_pre"); - ////protected readonly NonTerminal layout_qualifier_post = T("layout_qualifier_post"); - - protected readonly NonTerminal vector_type = T("vector_type"); - protected readonly NonTerminal vector_type_list = TT("vector_type_list"); - protected readonly NonTerminal void_type = T("void_type", (context, node) => Ast(node).Name = new Identifier("void") { Span = SpanConverter.Convert(node.Span) }); - protected readonly NonTerminal while_statement = T("while_statement", CreateWhileStatementAst); - - // ReSharper restore InconsistentNaming - - internal Dictionary TokenTypeToTerminals = new Dictionary(); - - /// - /// Initializes a new instance of the class. - /// - protected ShaderGrammar() - { - GrammarComments = "Shader abstract"; - - // ------------------------------------------------------------------------------------ - // Prepare mapping for GoldScanner - // ------------------------------------------------------------------------------------ - - // Global mappings - Term(whitespace, TokenCategory.WhiteSpace, TokenType.Whitespace); - Term(newline, TokenCategory.WhiteSpace, TokenType.NewLine); - Term(single_line_comment, TokenCategory.Comment, TokenType.SingleLineComment); - Term(multi_line_comment, TokenCategory.MultilineComment, TokenType.MultiLineComment); - - // Special unknown terminal - Term(unknown, TokenCategory.Identifier, TokenType.Unknown); - - // Mapping for identifier, numbers - Term(identifier_raw, TokenCategory.Identifier, TokenType.Identifier); - Term(float_literal, TokenCategory.Number, TokenType.FloatingPointLiteral); - Term(float_literal, TokenCategory.Number, TokenType.FloatingPointLiteralExponent); - Term(integer_literal, TokenCategory.Number, TokenType.HexIntegerLiteral); - Term(integer_literal, TokenCategory.Number, TokenType.OctalIntegerLiteral); - Term(integer_literal, TokenCategory.Number, TokenType.StartWithNoZeroDecimalIntegerLiteral); - Term(integer_literal, TokenCategory.Number, TokenType.StartWithZeroDecimalIntegerLiteral); - - // Preprocessor terminals - Punc("\\", TokenType.LineContinuation); - Punc("#", TokenType.Preprocessor); - Punc("##", TokenType.TokenPasting); - - // Mapping for symbols, punctuation, delimiters... - Op("@", TokenType.Arrobas); - Op("!", TokenType.Not); - Op("!=", TokenType.NotEqual); - Op("&&", TokenType.And); - Punc("(", TokenType.LeftParen); - Punc(")", TokenType.RightParen); - Op("*", TokenType.Mul); - Op("*=", TokenType.MulAssign); - Op("+", TokenType.Plus); - Op("++", TokenType.PlusPlus); - Op("+=", TokenType.AddAssign); - Punc(",", TokenType.Comma); - Op("-", TokenType.Minus); - Op("--", TokenType.MinusMinus); - Op("-=", TokenType.SubAssign); - Op("/", TokenType.Div); - Op("/=", TokenType.DivAssign); - Op("%", TokenType.Mod); - Op("%=", TokenType.ModAssign); - Punc(":", TokenType.Colon); - Punc(";", TokenType.Semi); - Op("<", TokenType.LessThan); - Op("<=", TokenType.LessThanOrEqual); - Op("=", TokenType.Assign); - Op("==", TokenType.Equal); - Op(">", TokenType.GreaterThan); - Op(">=", TokenType.GreaterThanOrEqual); - Punc("?", TokenType.Question); - Punc("[", TokenType.LeftBracket); - Punc("]", TokenType.RightBracket); - Punc("{", TokenType.LeftCurly); - Op("||", TokenType.Or); - Punc("}", TokenType.RightCurly); - Punc(".", TokenType.Dot); - Op("~", TokenType.BitwiseNot); - Op("<<", TokenType.BitwiseShiftLeft); - Op(">>", TokenType.BitwiseShiftRight); - Op("&", TokenType.BitwiseAnd); - Op("|", TokenType.BitwiseOr); - Op("^", TokenType.BitwiseXor); - Op("<<=", TokenType.BitwiseShiftLeftAssign); - Op(">>=", TokenType.BitwiseShiftRightAssign); - Op("&=", TokenType.BitwiseAndAssign); - Op("|=", TokenType.BitwiseOrAssign); - Op("^=", TokenType.BitwiseXorAssign); - - // ------------------------------------------------------------------------------------ - // Comments - // ------------------------------------------------------------------------------------ - NonGrammarTerminals.Add(single_line_comment); - NonGrammarTerminals.Add(multi_line_comment); - - identifier.Rule = identifier_raw; - identifier_raw.AstNodeCreator = CreateIdentifierAst; - - semi_opt.Rule = Empty | PreferShiftHere() + ";"; - - less_than.Rule = "<"; - - // ------------------------------------------------------------------------------------ - // Types - // ------------------------------------------------------------------------------------ - - // Numnber rule - number.Rule = integer_literal | float_literal; - integer_literal.AstNodeCreator = CreateIntegerLiteral; - float_literal.AstNodeCreator = CreateFloatLiteral; - - // Boolean rule - boolean.Rule = Keyword("true") | Keyword("false"); - - // Literal rule (no strings!) - literal.Rule = number | boolean; - - // Predefined scalars and vectors - scalars_and_vectors.Rule = vector_type_list | scalars | type_name; - - scalars_or_typename.Rule = scalars | type_name; - - // Typename - type_name.Rule = identifier + new IdentifierResolverHint(true); - - // Simple types - simple_type.Rule = scalars - | vector_type_list - | matrix_type_list; - - // Value types - value_type.Rule = simple_type - | struct_specifier; - - // Object types - object_type.Rule = sampler_type; - - // Void type - void_type.Rule = Keyword("void"); - - // Main type - type.Rule = type_name - | value_type - | object_type - | void_type; - - // Parameter type doesn't have void because void can be used by a method without arguments - parameter_type.Rule = type_name - | value_type - | object_type; - - simple_type_or_type_name.Rule = type_name | simple_type; - - - // Special valuetype used for cast - type_reference_expression.Rule = simple_type; - - // ------------------------------------------------------------------------------------ - // Complex type - // ------------------------------------------------------------------------------------ - field_declaration.Rule = variable_declaration; - - struct_specifier.Rule = Keyword("struct") + identifier.Opt() + "{" + field_declaration.ListOpt() + "}"; - - // ------------------------------------------------------------------------------------ - // Expressions - // ------------------------------------------------------------------------------------ - - // primary expressions - primary_expression.Rule = variable_identifier | literal_expression | parenthesized_expression; - - identifier_extended.Rule = identifier; - - variable_identifier.Rule = identifier_extended; - - literal_expression.Rule = literal; - - parenthesized_expression.Rule = "(" + expression + ")"; - - // postfix_expression - postfix_expression.Rule = primary_expression - | indexer_expression - | method_invoke_expression - | member_reference_expression - | post_incr_decr_expression; - - indexer_expression.Rule = postfix_expression + rank_specifier; - - method_invoke_expression_simple.Rule = identifier + "(" + argument_expression_list.Opt() + ")"; - - // Force to add value type for cast in order to support construct like x = (int(5)); <= need to disambiguate with cast (int[5]) - method_invoke_expression.Rule = type_reference_expression + "(" + argument_expression_list.Opt() + ")" - | postfix_expression + "(" + argument_expression_list.Opt() + ")"; - - member_reference_expression.Rule = postfix_expression + "." + identifier; - - post_incr_decr_expression.Rule = postfix_expression + incr_or_decr; - - argument_expression_list.Rule = MakePlusRule(argument_expression_list, ToTerm(","), assignment_expression); - - // unary_expression - unary_expression_raw.Rule = incr_or_decr + unary_expression - | unary_operator + cast_expression; - - unary_expression.Rule = postfix_expression - | unary_expression_raw; - - incr_or_decr.Rule = ToTerm("++") | "--"; - - unary_operator.Rule = ToTerm("+") | "-" | "!" | "~" | "*"; - - cast_expression.Rule = unary_expression; - - // multiplicative_expression - multiplicative_expression_raw.Rule = multiplicative_expression + "*" + cast_expression - | multiplicative_expression + "/" + cast_expression - | multiplicative_expression + "%" + cast_expression; - - multiplicative_expression.Rule = cast_expression | multiplicative_expression_raw; - - // additive_expression - additive_expression_raw.Rule = additive_expression + "+" + multiplicative_expression | additive_expression + "-" + multiplicative_expression; - - additive_expression.Rule = multiplicative_expression | additive_expression_raw; - - // shift_expression - shift_expression_raw.Rule = shift_expression + "<<" + additive_expression | shift_expression + ">>" + additive_expression; - - shift_expression.Rule = additive_expression | shift_expression_raw; - - // relational_expression - relational_expression_raw.Rule = relational_expression + less_than + shift_expression | relational_expression + ">" + shift_expression - | relational_expression + "<=" + shift_expression | relational_expression + ">=" + shift_expression; - - relational_expression.Rule = shift_expression | relational_expression_raw; - - // equality_expression - equality_expression_raw.Rule = equality_expression + "==" + relational_expression | equality_expression + "!=" + relational_expression; - - equality_expression.Rule = relational_expression | equality_expression_raw; - - // and_expression - and_expression_raw.Rule = and_expression + "&" + equality_expression; - - and_expression.Rule = equality_expression - | and_expression_raw; - - // exclusive - exclusive_or_expression_raw.Rule = exclusive_or_expression + "^" + and_expression; - exclusive_or_expression.Rule = and_expression - | exclusive_or_expression_raw; - - // inclusive - inclusive_or_expression_raw.Rule = inclusive_or_expression + "|" + exclusive_or_expression; - - inclusive_or_expression.Rule = exclusive_or_expression | inclusive_or_expression_raw; - - // logical and - logical_and_expression_raw.Rule = logical_and_expression + "&&" + inclusive_or_expression; - - logical_and_expression.Rule = inclusive_or_expression | logical_and_expression_raw; - - // logical or - logical_or_expression_raw.Rule = logical_or_expression + "||" + logical_and_expression; - - logical_or_expression.Rule = logical_and_expression - | logical_or_expression_raw; - - // conditional - conditional_expression.Rule = logical_or_expression - | conditional_expression_raw; - - conditional_expression_raw.Rule = logical_or_expression + "?" + expression + ":" + conditional_expression; - - // assignment - assignment_expression.Rule = conditional_expression - | assignment_expression_raw; - - assignment_expression_raw.Rule = unary_expression + assignment_operator + assignment_expression; - - assignment_operator.Rule = ToTerm("=") | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>="; - - // expression - expression.Rule = expression_list; - - expression_list.Rule = MakePlusRule(expression_list, ToTerm(","), assignment_expression); - expression_list.ErrorRule = SyntaxError + ";"; - - expression_or_empty.Rule = Empty | expression; - - // rank_specifier - rank_specifier.Rule = "[" + expression + "]"; - rank_specifier_empty.Rule = "[" + expression_or_empty + "]"; - - simple_assignment_expression_statement.Rule = indexable_identifier + assignment_operator + expression + ";"; - - indexable_identifier.Rule = identifier_extended + rank_specifier.ListOpt(); - - indexable_identifier_declarator.Rule = identifier_extended + rank_specifier_empty.ListOpt(); - - // constant expression - used to plug builtin verification during Ast creation - constant_expression.Rule = conditional_expression; - - // ------------------------------------------------------------------------------------ - // Variable modifiers - // ------------------------------------------------------------------------------------ - // storageClass = Storage_Class + Type_Modifier - storage_qualifier.Rule = Keyword("const") | Keyword("uniform"); - storage_qualifier.AstNodeCreator = CreateStorageQualifier; - - storage_qualifier_list_opt.Rule = Empty | storage_qualifier.List(); - - // layout_qualifier_pre.Rule = null; - - // layout_qualifier_post.Rule = null; - - variable_declarator_qualifier_post.Rule = null; - - // ------------------------------------------------------------------------------------ - // Declarations - // ------------------------------------------------------------------------------------ - declaration.Rule = variable_declaration; - - variable_declaration.Rule = attribute_qualifier_pre + variable_declaration_raw; - - variable_declaration_raw.Rule = declaration_specifiers + variable_declarator_list.Opt() + ";"; - - declaration_specifiers.Rule = type - | storage_qualifier.List() + type; - - variable_declarator_list.Rule = MakePlusRule(variable_declarator_list, ToTerm(","), variable_declarator); - - variable_declarator_raw.Rule = indexable_identifier_declarator + variable_declarator_qualifier_post; - variable_declarator_raw.AstNodeCreator = CreateVariableDeclaratorRawAst; - - variable_declarator.Rule = variable_declarator_raw - | variable_declarator_raw + "=" + initializer; - variable_declarator.AstNodeCreator = CreateVariableDeclaratorAst; - - initializer.Rule = assignment_expression - | array_initializer_expression; - - array_initializer_expression.Rule = "{" + initializer_list + "}" - | "{" + initializer_list + "," + "}"; - - initializer_list.Rule = MakePlusRule(initializer_list, ToTerm(","), initializer); - - // Attribute qualifier pre - attribute_qualifier_pre.Rule = null; - - // Method - method_qualifier_post.Rule = null; - - method_declaration_raw.Rule = attribute_qualifier_pre + declaration_specifiers + method_declarator + method_qualifier_post; - - method_declaration.Rule = method_declaration_raw + ";"; - - var optional_block_statement_list = block_item.ListOpt(); - method_definition.Rule = method_declaration_raw + "{" + optional_block_statement_list + "}" + semi_opt; - - - method_definition_or_declaration.Rule = method_declaration | method_definition; - - method_declarator.Rule = identifier + "(" + parameter_list + ")" - | identifier + "(" + "void" + ")" - | identifier + "(" + ")"; - - parameter_list.Rule = MakePlusRule(parameter_list, ToTerm(","), parameter_declaration); - - // Need to be fill out woth pre qualifier - parameter_qualifier_pre.Rule = null; - parameter_qualifier_post.Rule = null; - - parameter_declaration.Rule = attribute_qualifier_pre + parameter_qualifier_pre + parameter_type + indexable_identifier.Opt() + parameter_qualifier_post; // +parameter_declaration_raw; - parameter_declaration.AstNodeCreator = CreateParameterAst; - - identifier_list.Rule = MakePlusRule(identifier_list, ToTerm(","), identifier); - - // ------------------------------------------------------------------------------------ - // Statements - // ------------------------------------------------------------------------------------ - statement.Rule = attribute_qualifier_pre + statement_raw; - - statement_raw.Rule = discard_statement - | block_statement - | expression_statement - | selection_statement - | iteration_statement - | jump_statement; - - discard_statement.Rule = Keyword("discard") + ";"; - - // skip all until semicolon - // statement.ErrorRule = SyntaxError + ";" | SyntaxError + "}"; - - block_statement.Rule = "{" + optional_block_statement_list + "}"; - - // Add an error rule at optional_block_statement_list - optional_block_statement_list.ErrorRule = SyntaxError + ";"; - - declaration_statement.Rule = declaration; - - block_item.Rule = declaration_statement - | statement; - - empty_statement.Rule = ";"; - - expression_statement.Rule = empty_statement - | expression + ";"; - - selection_statement.Rule = if_statement - | switch_statement; - - iteration_statement.Rule = while_statement - | do_while_statement - | for_statement; - - if_statement.Rule = Keyword("if") + "(" + expression + ")" + statement - | Keyword("if") + "(" + expression + ")" + statement + PreferShiftHere() + Keyword("else") + statement; - - - switch_statement.Rule = Keyword("switch") + "(" + expression + ")" + "{" + switch_case_group.ListOpt() + "}"; - - switch_case_group.Rule = switch_case_statement.List() + statement.List(); - - switch_case_statement.Rule = Keyword("case") + constant_expression + ":" - | Keyword("default") + ":"; - - while_statement.Rule = Keyword("while") + "(" + expression + ")" + statement; - - do_while_statement.Rule = Keyword("do") + statement + "while" + "(" + expression + ")" + ";"; - - for_statement.Rule = Keyword("for") + "(" + expression_statement + expression.Opt() + ";" + expression.Opt() + ")" + statement - | Keyword("for") + "(" + variable_declaration_raw + expression.Opt() + ";" + expression.Opt() + ")" + statement; - - break_statement.Rule = Keyword("break") + ";"; - continue_statement.Rule = Keyword("continue") + ";"; - return_statement.Rule = Keyword("return") + ";" | Keyword("return") + expression + ";"; - - jump_statement.Rule = continue_statement - | break_statement - | return_statement; - - literal_list.Rule = MakePlusRule(literal_list, ToTerm(","), literal); - - // ------------------------------------------------------------------------------------ - // Top Level - // ------------------------------------------------------------------------------------ - toplevel_declaration.Rule = scope_declaration; - - scope_declaration.Rule = method_definition_or_declaration | declaration | empty_statement; - - toplevel_declaration_list.Rule = MakeStarRule(toplevel_declaration_list, null, toplevel_declaration); - - shader.Rule = toplevel_declaration_list; - - shader.ErrorRule = SyntaxError + ";"; - - Root = shader; - - // ------------------------------------------------------------------------------------ - // Preprocessor declaration - // ------------------------------------------------------------------------------------ - - // Using a special terminal to match lines - //NonGrammarTerminals.Add(new PreprocessorLines()); - - // ------------------------------------------------------------------------------------ - // Globals - // ------------------------------------------------------------------------------------ - // MarkReservedWords("true", "false", "do", "while", "for", "if", "then", "else", "case", "switch", "continue", "break", "return"); - - Delimiters = "{}[](),:;+-*/%&|^!~<>="; - MarkPunctuation(";", ",", ":"); - - // CR, linefeed, nextLine, LineSeparator, paragraphSeparator - LineTerminators = "\r\n\u2085\u2028\u2029"; - - // Add extra line terminators - WhitespaceChars = " \t\r\n\v\u2085\u2028\u2029"; - - LanguageFlags = LanguageFlags.NewLineBeforeEOF; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderLanguageData.cs b/sources/shaders/Stride.Core.Shaders/Grammar/ShaderLanguageData.cs deleted file mode 100644 index a1763eff48..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/ShaderLanguageData.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Globalization; -using System.Collections.Generic; -using System.Linq; - -using Irony.Parsing; - -namespace Stride.Core.Shaders.Grammar -{ - public class ShaderLanguageData : LanguageData - { - private Dictionary keywordToTerminal = new Dictionary(); - private Dictionary caseInsensitiveKeywordToTerminal = new Dictionary(StringComparer.OrdinalIgnoreCase); - private Terminal[] SymbolToToken; - - /// - /// Initializes a new instance of the class. - /// - /// The grammar. - public ShaderLanguageData(Irony.Parsing.Grammar grammar) : base(grammar) - { - SymbolToToken = new Terminal[256]; - - // Add TokenType to terminals - foreach (var typeTerm in ((ShaderGrammar)grammar).TokenTypeToTerminals) - { - AddTerminal(typeTerm.Key, typeTerm.Value); - } - - - // Add Keywords - foreach (var term in Grammar.KeyTerms.Values.OfType()) - { - if (char.IsLetter(term.Name[0])) - AddTerminal(TokenType.Identifier, term); - } - } - - private void AddTerminal(TokenType type, Terminal term) - { - if (term == Grammar.Empty || term == Grammar.Eof || term == Grammar.SyntaxError) - return; - - var tokenInfo = (TokenInfo)term.AstNodeConfig; - - if (tokenInfo == null) - { - Errors.Add(GrammarErrorLevel.Error, null, "Terminal {0} is doesn't have associated TokenInfo", term.Name); - } - else if (tokenInfo.TokenCategory == TokenCategory.Typename || tokenInfo.TokenCategory == TokenCategory.Keyword) - { - var keyMap = (tokenInfo.IsCaseInsensitive) ? caseInsensitiveKeywordToTerminal : keywordToTerminal; - keyMap.TryAdd(term.Name, term); - } - else - { - SymbolToToken[(int)type] = term; - } - } - - - public override Scanner CreateScanner() - { - return new CustomScanner(new Tokenizer(this)); - } - - public Terminal FindTerminalByType(TokenType tokenType) - { - return SymbolToToken[(int)tokenType]; - } - - public Terminal FindTerminalByName(string name) - { - Terminal terminal; - // First try case insensitive keywords, else try case sensitive - if (!caseInsensitiveKeywordToTerminal.TryGetValue(name, out terminal)) - keywordToTerminal.TryGetValue(name, out terminal); - return terminal; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.Ast.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.Ast.cs deleted file mode 100644 index 2b3b0f5c37..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.Ast.cs +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Irony.Parsing; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Grammar.Stride -{ - public partial class StrideGrammar - { - private static void CreateStreamsType(ParsingContext context, ParseTreeNode parseNode) - { - var nextNode = parseNode; - while (nextNode.Token == null) - { - nextNode = nextNode.ChildNodes[0]; - } - - var value = StreamsType.Parse(nextNode.Token.Text); - parseNode.AstNode = value; - } - - private static void CreateShaderBlockAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [2] [3] [4] [5] - // "class" + type_name + shader_class_base_type.Star() + "{" + scope_declaration.Star() + "}"; - var value = Ast(node); - - ParseClassGenerics((Identifier)node.ChildNodes[1].AstNode, value); - value.BaseClasses.AddRange((List)node.ChildNodes[2].AstNode); - FillListFromNodes(node.ChildNodes[4].ChildNodes, value.Members); - } - - protected static void ParseClassGenerics(Identifier input, ShaderClassType dest) - { - // Parse generic identifier and convert it to simple identifier by adding contraint to the class type - var genericIdentifier = input as ClassIdentifierGeneric; - if (genericIdentifier != null) - { - foreach (var genericIdentifierItem in genericIdentifier.Generics) - { - dest.ShaderGenerics.Add(genericIdentifierItem); - } - input = new Identifier(input.Text) { Span = genericIdentifier.Span }; - } - dest.Name = input; - } - - private static void CreateClassIdentifierGenericAst(ParsingContext context, ParseTreeNode node) - { - // identifier_generic.Rule = - // [0] [1] [2] [3] - // identifier - // | identifier + "<" + class_identifier_generic_parameter_list + ">"; - var identifier = (Identifier)node.ChildNodes[0].AstNode; - - if (node.ChildNodes.Count == 4) - { - var value = Ast(node); - value.IsSpecialReference = true; - value.Text = identifier.Text; - value.Generics.AddRange((List)node.ChildNodes[2].AstNode); - } - else - { - node.AstNode = identifier; - } - } - - protected override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node) - { - var qualifier = AstCompositeEnum(node); - - if (node.ChildNodes.Count == 1) - { - qualifier = StrideStorageQualifier.Parse(node.ChildNodes[0].Token.Text); - qualifier.Span = SpanConverter.Convert(node.Span); - } - - // Use Hlsl Storage Qualifiers to parse the qualifier - node.AstNode = qualifier; - } - - private static void CreateSemanticTypeAst(ParsingContext context, ParseTreeNode node) - { - Ast(node); - } - - private static void CreateLinkTypeAst(ParsingContext context, ParseTreeNode node) - { - Ast(node); - } - - private static void CreateStreamNameAst(ParsingContext context, ParseTreeNode node) - { - Ast(node); - } - - private static void CreateVarTypeAst(ParsingContext context, ParseTreeNode node) - { - Ast(node); - } - - private static void CreateForEachStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// for_statement.Rule = _ - //// [0] [1] [2] [3] [4] [5] [6] [7] - //// Keyword("foreach") + "(" + type + identifier + Keyword("in") + expression + ")" + statement; - value.Variable = new Variable { Type = (TypeBase)node.ChildNodes[2].AstNode, Name = (Identifier)node.ChildNodes[3].AstNode }; - value.Collection = (Expression)node.ChildNodes[5].AstNode; - value.Body = (Statement)node.ChildNodes[7].AstNode; - } - - protected override void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node) - { - base.CreateIdentifierSubGenericAst(context, node); - if ( node.AstNode is Literal) - { - node.AstNode = new LiteralIdentifier((Literal)node.AstNode); - } - else if (node.AstNode is TypeBase) - { - node.AstNode = new TypeIdentifier((TypeBase)node.AstNode); - } - } - - protected override void CreateConstantBufferTypeAst(ParsingContext context, ParseTreeNode node) - { - node.AstNode = StrideConstantBufferType.Parse(node.ChildNodes[0].Token.Text); - } - - protected void CreateClassIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - //// class_identifier_sub_generic.Rule = - //// [0] [1] - //// type + identifier; - - value.Name = (Identifier)node.ChildNodes[1].AstNode; - value.Type = (TypeBase)node.ChildNodes[0].AstNode; - - /*base.CreateIdentifierSubGenericAst(context, node); - if (node.AstNode is Literal) - { - node.AstNode = new LiteralIdentifier((Literal)node.AstNode); - } - else if (node.AstNode is TypeBase) - { - node.AstNode = new TypeIdentifier((TypeBase)node.AstNode); - }*/ - } - - private static void CreateClassTypeAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - value.Name = (Identifier)node.ChildNodes[0].AstNode; - } - - protected static void CreateShaderClassBaseTypeAst(ParsingContext context, ParseTreeNode node) - { - //// [0] - //// (":" + shader_type_name).Q(); - if (node.ChildNodes[0].ChildNodes.Count == 1) - node.AstNode = node.ChildNodes[0].ChildNodes[0].AstNode; - else - node.AstNode = new List(); - } - - private static void CreateParametersAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - // [0] [1] [2] [3] - // params_block.Rule = attribute_qualifier_pre + Keyword("params") + identifier + block_statement; - - // value.Attributes = (List)node.ChildNodes[0].AstNode; - value.Name = (Identifier)node.ChildNodes[2].AstNode; - value.Body = (BlockStatement)node.ChildNodes[3].AstNode; - } - - private static void CreateEffectBlockAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - // [0] [1] [2] [3] [4] - // shader_block.Rule = attribute_qualifier_pre + Keyword("partial").Opt() + Keyword("shader") + identifier_raw + block_statement; - - // value.Attributes = (List)node.ChildNodes[0].AstNode; - value.IsPartial = node.ChildNodes[1].ChildNodes.Count == 1; - value.Name = (Identifier)node.ChildNodes[3].AstNode; - value.Body = (BlockStatement)node.ChildNodes[4].AstNode; - } - - private static void CreateMixinStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - // [0] [1] [2] [3] - //mixin_statement.Rule = Keyword("mixin") + Keyword("compose") + expression + ";" - // | Keyword("mixin") + Keyword("remove") + expression + ";" - // | Keyword("mixin") + Keyword("macro") + expression + ";" - // | Keyword("mixin") + Keyword("mixin") + expression + ";" - // | Keyword("mixin") + Keyword("clone") + ";" - // | Keyword("mixin") + expression + ";"; - - value.Value = (node.ChildNodes[1].AstNode as Expression); - if (value.Value == null) - { - var typeName = node.ChildNodes[1].Term.Name; - MixinStatementType type; - Enum.TryParse(typeName, true, out type); - value.Type = type; - - if (type != MixinStatementType.Clone) - { - value.Value = (Expression)node.ChildNodes[2].AstNode; - } - } - } - - private static void CreateUsingStatement(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] - //using_statement.Rule = Keyword("using") + identifier_or_dot + ";"; - value.Name = (Identifier)node.ChildNodes[1].AstNode; - } - - private static void CreateUsingParametersStatement(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - - // [0] [1] [2] [3] - //using_params_statement.Rule = Keyword("using") + Keyword("params") + expression + ";" - // | Keyword("using") + Keyword("params") + expression + block_statement; - value.Name = (Expression)node.ChildNodes[2].AstNode; - if (node.ChildNodes.Count == 4) - { - value.Body = (BlockStatement)node.ChildNodes[3].AstNode; - } - } - - private static void CreateEnumBlockAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - // [0] [1] [2] [3] [4] - //enum_block.Rule = attribute_qualifier_pre + Keyword("enum") + identifier_raw + "{" + enum_item_list + "}"; - value.Attributes = (List)node.ChildNodes[0].AstNode; - value.Name = (Identifier)node.ChildNodes[2].AstNode; - value.Values.AddRange((List)node.ChildNodes[4].AstNode); - } - - private static void CreateEnumItemAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] [2] - //enum_item.Rule = identifier + "=" + expression - // | identifier; - if (node.ChildNodes.Count == 1) - { - var value = Ast(node); - value.Name = (Identifier)node.ChildNodes[0].AstNode; - } - else - { - var value = Ast(node); - value.Target = new VariableReferenceExpression((Identifier)node.ChildNodes[0].AstNode); - value.Operator = AssignmentOperator.Default; - value.Value = (Expression)node.ChildNodes[2].AstNode; - } - } - - private static void CreateForEachParamsStatementAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - //// [0] [1] [2] [3] [4] [5] - //// foreach_params_statement.Rule = Keyword("foreach") + "(" + Keyword("params") + conditional_expression + ")" + statement; - value.Collection = (Expression)node.ChildNodes[3].AstNode; - value.Body = (Statement)node.ChildNodes[5].AstNode; - } - - private static void CreateNamespaceBlockAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - //// [0] [1] [2] - //// namespace_block.Rule = Keyword("namespace") + identifier_or_dot + toplevel_declaration_block; - value.Name = (Identifier)node.ChildNodes[1].AstNode; - value.Body = (List)node.ChildNodes[2].AstNode; - } - - private static void CreateDeclarationBlockAst(ParsingContext context, ParseTreeNode node) - { - // [0] [1] - // toplevel_declaration_block.Rule = "{" + toplevel_declaration_list + "}"; - node.AstNode = (List)node.ChildNodes[1].AstNode; - } - - private static void CreateConstantBufferNameAst(ParsingContext context, ParseTreeNode node) - { - var value = Ast(node); - value.Text = string.Join(".", node.ChildNodes.Select(x => ((Identifier)x.AstNode).Text)); - } - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.cs deleted file mode 100644 index 3147581511..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Stride/StrideGrammar.cs +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; - -using Irony.Parsing; - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Stride; -using Stride.Core.Shaders.Grammar.Hlsl; - -namespace Stride.Core.Shaders.Grammar.Stride -{ - [Language("hotei2", "5.0", "Stride2 hlsl grammar")] - public partial class StrideGrammar : HlslGrammar - { - protected readonly NonTerminal constant_buffer_name = T("constant_buffer_name", CreateConstantBufferNameAst); - protected readonly NonTerminal semantic_type = T("semantic_type", CreateSemanticTypeAst); - protected readonly NonTerminal link_type = T("link_type", CreateLinkTypeAst); - protected readonly NonTerminal member_name = T("member_name", CreateStreamNameAst); - protected readonly NonTerminal var_type = T("var_type", CreateVarTypeAst); - protected readonly NonTerminal streams_type = T("streams_type", CreateStreamsType); - protected readonly NonTerminal foreach_statement = T("foreach_statement", CreateForEachStatementAst); - protected readonly NonTerminal foreach_params_statement = T("foreach_params_statement", CreateForEachParamsStatementAst); - protected readonly NonTerminal params_block = T("params_block", CreateParametersAst); - protected readonly NonTerminal effect_block = T("effect_block", CreateEffectBlockAst); - protected readonly NonTerminal shader_block = T("shader_block", CreateShaderBlockAst); - protected readonly NonTerminal shader_base_type = T("shader_base_type", CreateClassBaseTypeAst); - protected readonly NonTerminal shader_base_type_list = T("shader_base_type_list", CreateListFromNode); - protected readonly NonTerminal shader_class_type = T("shader_class_type", CreateClassTypeAst); // TODO: look if really needed - protected readonly NonTerminal toplevel_declaration_block = T("toplevel_declaration_block", CreateDeclarationBlockAst); - protected readonly NonTerminal mixin_statement = T("mixin_statement", CreateMixinStatementAst); - protected readonly NonTerminal using_statement = T("using_statement", CreateUsingStatement); - protected readonly NonTerminal using_params_statement = T("using_params_statement", CreateUsingParametersStatement); - protected readonly NonTerminal enum_block = T("enum_block", CreateEnumBlockAst); - protected readonly NonTerminal enum_item = T("enum_item", CreateEnumItemAst); - protected readonly NonTerminal enum_item_list = T("enum_item_list", CreateListFromNode); - protected readonly NonTerminal namespace_block = T("namespace_block", CreateNamespaceBlockAst); - - protected readonly NonTerminal shader_identifier_or_generic = TT("shader_identifier_or_generic"); - protected readonly NonTerminal shader_identifier_generic = T("shader_identifier_generic", CreateClassIdentifierGenericAst); - protected readonly NonTerminal shader_identifier_generic_parameter_list = T("shader_identifier_generic_parameter_list", CreateListFromNode); - protected readonly NonTerminal shader_identifier_sub_generic = T("shader_identifier_sub_generic"); - - public NonTerminal ExpressionNonTerminal - { - get - { - return expression; - } - } - - /// - /// Initializes a new instance of the class. - /// - public StrideGrammar() - { - SnippetRoots.Add(expression); - - semantic_type.Rule = Keyword("Semantic"); - type.Rule |= semantic_type; - - link_type.Rule = Keyword("LinkType"); - type.Rule |= link_type; - - member_name.Rule = Keyword("MemberName"); - type.Rule |= member_name; - - var_type.Rule = Keyword("var"); - object_type.Rule |= var_type; - - // Add all Streams types - streams_type.Rule = CreateRuleFromObjectTypes(StreamsType.GetStreams()); - object_type.Rule |= streams_type; - - identifier_extended.Rule |= Keyword("stage"); - - // Allow simple types within generics (numbers, etc...) - //type_name.Rule = identifier_or_generic + new IdentifierResolverHint(true); - type_name.Rule = identifier_or_generic; - identifier_sub_generic.Rule |= number; - //identifier_sub_generic.Rule |= boolean; - identifier_sub_generic.Rule |= identifier_dot; - identifier_sub_generic.Rule |= simple_type; - - // Foreach statement - foreach_statement.Rule = Keyword("foreach") + "(" + type + identifier + Keyword("in") + expression + ")" + statement; - iteration_statement.Rule |= foreach_statement; - - // Add inheritance qualifiers - storage_qualifier.Rule |= Keyword("override") | Keyword("abstract") | Keyword("stream") | Keyword("patchstream") | Keyword("stage") | Keyword("clone") | Keyword("compose") | Keyword("internal"); - - // cbuffer can have . in their names (logical groups) - constant_buffer_name.Rule = MakePlusRule(constant_buffer_name, ToTerm("."), identifier_raw); - constant_buffer_resource.Rule = attribute_qualifier_pre + constant_buffer_resource_type + constant_buffer_name.Opt() + register.Opt() + "{" + declaration.ListOpt() + "}" + semi_opt; - - variable_identifier.Rule |= identifier_generic; - - // Allow generic identifier on member expressions - member_reference_expression.Rule = postfix_expression + "." + identifier_or_generic; - - // --------------------------------------------------- - // New Mixin System - // --------------------------------------------------- - params_block.Rule = attribute_qualifier_pre + Keyword("params") + identifier_raw + block_statement; - - effect_block.Rule = attribute_qualifier_pre + Keyword("partial").Opt() + Keyword("effect") + identifier_raw + block_statement; - - using_params_statement.Rule = Keyword("using") + Keyword("params") + expression + ";" - | Keyword("using") + Keyword("params") + expression + block_statement; - - - using_statement.Rule = Keyword("using") + identifier_or_dot + ";"; - - foreach_params_statement.Rule = Keyword("foreach") + "(" + Keyword("params") + conditional_expression + ")" + statement; - iteration_statement.Rule |= foreach_params_statement; - - mixin_statement.Rule = Keyword("mixin") + Keyword("compose") + expression + ";" - | Keyword("mixin") + Keyword("remove") + expression + ";" - | Keyword("mixin") + Keyword("macro") + expression + ";" - | Keyword("mixin") + Keyword("child") + expression + ";" - | Keyword("mixin") + Keyword("clone") + ";" - | Keyword("mixin") + expression + ";"; - - enum_item.Rule = identifier_raw + "=" + conditional_expression - | identifier_raw; - - enum_item_list.Rule = MakeStarRule(enum_item_list, ToTerm(","), enum_item); - - enum_block.Rule = attribute_qualifier_pre + Keyword("enum") + identifier_raw + "{" + enum_item_list + "}"; - - statement_raw.Rule |= mixin_statement | using_statement | using_params_statement; - - toplevel_declaration_block.Rule = "{" + toplevel_declaration_list + "}"; - - namespace_block.Rule = Keyword("namespace") + identifier_or_dot + toplevel_declaration_block; - - toplevel_declaration.Rule |= params_block | effect_block | enum_block | namespace_block | using_statement; - - object_type.Rule |= shader_block; - - // Shader class type & base - shader_class_type.Rule = identifier_or_generic; - shader_base_type.AstNodeCreator = CreateShaderClassBaseTypeAst; - shader_base_type.Rule = shader_base_type; - shader_base_type_list.Rule = MakePlusRule(shader_base_type_list, ToTerm(","), shader_class_type); - shader_base_type.Rule = (ToTerm(":") + shader_base_type_list).Opt(); - - // add shader class - shader_block.Rule = Keyword("shader") + shader_identifier_or_generic + shader_base_type + "{" + scope_declaration.ListOpt() + "}"; - - // shader identifiers (allow type + name inside generics) - shader_identifier_or_generic.Rule = identifier + new IdentifierResolverHint(true) - | shader_identifier_generic + this.ReduceHere(); - shader_identifier_generic.Rule = identifier + new GenericResolverHint(_skipTokensInPreview) + "<" + shader_identifier_generic_parameter_list + ">"; - shader_identifier_generic_parameter_list.Rule = MakePlusRule(shader_identifier_generic_parameter_list, ToTerm(","), shader_identifier_sub_generic); - shader_identifier_sub_generic.Rule = identifier_sub_generic | type + identifier; - shader_identifier_sub_generic.AstNodeCreator = CreateClassIdentifierSubGenericAst; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/TokenCategory.cs b/sources/shaders/Stride.Core.Shaders/Grammar/TokenCategory.cs deleted file mode 100644 index 66c6f34034..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/TokenCategory.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Grammar -{ - public enum TokenCategory - { - WhiteSpace, - Keyword, - Typename, - Number, - Comment, - MultilineComment, - Identifier, - String, - Puntuation, - Operator - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/TokenInfo.cs b/sources/shaders/Stride.Core.Shaders/Grammar/TokenInfo.cs deleted file mode 100644 index 434f7698be..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/TokenInfo.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Grammar -{ - /// - /// Key terminal - /// - public class TokenInfo - { - /// - /// Initializes a new instance of the class. - /// - public TokenInfo() - { - IsCaseInsensitive = false; - } - - /// - /// Initializes a new instance of the class. - /// - /// The token category. - public TokenInfo(TokenCategory tokenCategory) - { - TokenCategory = tokenCategory; - IsCaseInsensitive = false; - } - - /// - /// Gets or sets the token category. - /// - /// - /// The token category. - /// - public TokenCategory TokenCategory { get; set; } - - /// - /// Gets or sets if this token is case insensitive (default false). - /// - public bool IsCaseInsensitive { get; set; } - - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/TokenType.cs b/sources/shaders/Stride.Core.Shaders/Grammar/TokenType.cs deleted file mode 100644 index b42b013874..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/TokenType.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Grammar -{ - /// - /// Token type. - /// - public enum TokenType - { - Eof = 0, - Error = 1, - Whitespace = 2, - CommentEnd = 3, - SingleLineComment = 4, - MultiLineComment = 5, - AddAssign = 6, - And = 7, - Arrobas = 8, - Assign = 9, - BitwiseAnd = 10, - BitwiseAndAssign = 11, - BitwiseNot = 12, - BitwiseOr = 13, - BitwiseOrAssign = 14, - BitwiseShiftLeft = 15, - BitwiseShiftLeftAssign = 16, - BitwiseShiftRight = 17, - BitwiseShiftRightAssign = 18, - BitwiseXor = 19, - BitwiseXorAssign = 20, - Colon = 21, - Comma = 22, - Div = 23, - DivAssign = 24, - Dot = 25, - Equal = 26, - FloatingPointLiteral = 27, - FloatingPointLiteralExponent = 28, - GreaterThan = 29, - GreaterThanOrEqual = 30, - HexEscapeCharLiteral = 31, - HexIntegerLiteral = 32, - Identifier = 33, - IdentifierSeparator = 34, - IndirectCharLiteral = 35, - LeftBracket = 36, - LeftCurly = 37, - LeftParen = 38, - LessThan = 39, - LessThanOrEqual = 40, - LineContinuation = 41, - Minus = 42, - MinusMinus = 43, - Mod = 44, - ModAssign = 45, - Mul = 46, - MulAssign = 47, - NewLine = 48, - Not = 49, - NotEqual = 50, - OctalEscapeCharLiteral = 51, - OctalIntegerLiteral = 52, - Or = 53, - Plus = 54, - PlusPlus = 55, - Preprocessor = 56, - Question = 57, - RightBracket = 58, - RightCurly = 59, - RightParen = 60, - Semi = 61, - StandardEscapeCharLiteral = 62, - StartWithNoZeroDecimalIntegerLiteral = 63, - StartWithZeroDecimalIntegerLiteral = 64, - StringLiteral = 65, - SubAssign = 66, - TokenPasting = 67, - WS = 68, - Unknown = 69, - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cgt b/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cgt deleted file mode 100644 index 3b9bb81d293bf6bdbbcaa8a37fdb881102f8b938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51255 zcmc)T2bUb@d7#l^&N*j-Ip>@~0;EPFM2Ss_$`ZjO?JAj~EPEY(i~p(jz5P@-2NbXp zZJ)EpruzA+t5fx@uWDv`2JbBIE$=SJmOGd4EgvmkEPq-)o&UXa`CvvTm*39lPs`)W zKQ2!$k1bCu%W~p^<>dD^4=g`ee!qOV{AT{M&L_)*bKNZd?(&CObmy{J{y2+2o)tcu z{|>F-cK>_+`@`~=`QPoWmgUXm;O*ta`OC=<4&GS~o>>l#E(gC}4&GW$oU@!fI9QhX zfBDv2ZZ29bSuUN2_z%x!yYQ@K^TvK~_Oki+{otHs^T>X1?y|XOIXVya*1X>1%iGI4 z%eUs9zrB2Cw!n#b>hH}q`2O<#Joyji_5E=9(emTvC(AFlTjJw+ji1ho`F#2HyrBOz zui>}L@3ybwkIO%7x7(M?pJzM$)AG;D|Jgs}dCTUf`@#9k=3n-M3v8|33%GFE{A@qC zXxUu6A6&d_Uf&NcSvEi44=!Cc|F$1owrp(5Hpk`5=H>n1ie+=xesJZoxokhUYS|pw z53XJ|ckc(+ESr1xgKL+~efz<6%jW+5;QD3r(0*{kvUzwvxN+G$x*y!MY#!SWZeBKz z?+3Rmn=PsBn|SN8d2)Gbd3t$fd3Jejd473ed2zqyZOi7R{owXx^U8j3$Fg~KKNxqf z?FUDe&4+_*w^i<1How>p?p`+kx*y!b#SyQ3TtbF)i((;$DdAWDl+_@ZC?q2R$ z?p^L%?q435UF4zV;pLI#(b)kXKkd_eX?b~hWqEaZZFzlp;~N3rJ?Wn=KU;pj{9>s8 z>KkF-J^g=K{&o4c<=+qOlK1`pdLjR_FXR4Y^MiR~|2%Kg&d~$Vo@!-x)r0o6`?v4F z+cTZKKhwz1w%hZwnJB)Pd2zSmLw|iAv>*0n_T9}nyPG|H`kU>peq`Akn_2B!GgEyw zv(#?!qs!*_OkKO-V|LW9_Rhzb&AT&|?XG=d*&N>Qo?JFRI`rC~`tR&1&8a(bf8VUy zoVsJSdy-Eto6Q`SW_a#$a^skAeCF=AXTiZa>#{i{9G^}8#T;k8u>68``5YZS+|J-% z&L;WO9Hc&)t!(2QoV~6whm5!8R==D7`*hwm2eadI`H6MTTi2N*$=BC;ca93b@1D+I z*P6-y>uYW1{v2gdI5>A*Z;lH`=l(yL_y14xf4`Yy%;U4j^Z^r#YIuIrsnNOpCvn+k85YxW2O8{mvogbZea9{^l5T>e?Ot4?UMT zFrB)_d%YjK$D3o-UtfQQN1H?0sq1dG@8oCmdfuJa;_}cV&#~@rt$l{anFHgQZu$Q9 z-TC#Yk2J^5zrFq$9%~M@r{4BQJF&YhG{@i5t#O9?n*%g+zn%Y1F*L{OoyCt1Z>2eG zADh?okB67d(Ys}5c#JuqADjC>WoyrI{rH>*{dp{!O!gM%5dZe}*?ctX+e1E|bF4pX z%e%&+^Ubf_YR(1z-di1?>FJN#SKHot=&|Rd;hnkfPv_oyln=(sN2hL=IhQ#7I-H*N z70n69x8^?oX|Da#%pD(XPjuhf-t!k{enoR;(yb2W@jaW*x3Bw*TVPIJ4rWH^HSJEK zw=>z!#hlNaZjH^{#;j(WemUFal-tZ{kH`OHw!7`}@vQMTpZS~}?e?xWxA*$-ocn${ zw>-3^=d@+F&Rb*Pi+RWY`SA5~Hn6+CuQI%@L${y9tn1Bwr+JU&i2Lw+}rl3uzN@5K-;o2>^F1d zJu%PZl>K84zb!k%ZRU9V-PtmK*~(gvFT2N^gY#d_w{wJU*=g<0f%CoXyKaB`Mt+|; ze9OPn@Uw1niofTU&G+V!zqYlX|7z)Ju6@C^wEl7a_Yd2nH78$_{o=Cu{@gD^r+J@W zS~g$J+-Fq$^5L~k>-d$!Yn)c{t4>WmopXoZ9QO2@rH=geJ^SV--)!r@zPr6MhY#nz zznuBT`}~u6EL-K+T>4`BcXRK*ov&&Ct~ut7)7|TT>mHAGk6&!}sn5?m8@_41KhGKN z8PvbEY(AJ*WuE!{_WKgOtBxLr_Q7M$!zb3^*$wYrhvzhWZ5^K5@ac7UUc)=q;rR{UScexhe0?2W*zlHh zcu~V!*Wtwt?_7tMG<;?qUfS^JI=rmmk#%@^!w1*l6%AilhgUY7@2qTJ{#6YxT!&XT zd~zLL)9|Tvcx}TumEPX=x`y|y!|NNqvJP)(_}DtUvEk$E@TP{(t;3reKEDocX*lQ6 z+XuR};q~kAwuTR_!`mA^ybkYZ_~tsiv*8Wv@JPcO*Wq0aA6bWYH+*y*-qY~9b$D;X zSJ&Zv4ewuv_cwfC9X`H@tKm&iCEy3seBHMSkIxhJ?ZWpD-e~x?l}`M_ za`M>h(evHJ|NPJ6cI~rf&Do{To{QO)&zXzah0mRf*>%sGi`iu_n2Xs}FPw|nMK79* z*)=boi`gYFnTy#KFP)3o1uvV6+4U};i`nI_n2XufuAGb6#jcu**|n~ni`k{FpNrX* zZk&tRg>IgU*>!H6i`ixFn2Xs}9-52UMIN1t*)^V+i`gZfo{QNPUYd*91zwwrq5u9| z4EZ0-#ZdonE{6C|=VEC8d@hFcM{_ZhKc0&r{ONN1#D%uRS<9PeZC`s^!p?MT#b-Yq-X}9Gx|{o9wm*Nw<|i@W&|H@|yEm)nqc?N*tYZ5AHPj5crMym?dWz1+Q9W#%() z|Mm^I=hTJF?=jr#5oQl)&HHw1u6I3a-aprE-;VpOIr~FT_krD-v&vr2gI1ZHq&s`a z=&^Z%vjaUm7xS*nX6?=%cHKF<(IZBW?{4>~(R1Cv&1a`{-S$a5<~sDZqsNV&-`(yB zBYW}ezN-T7`*zJIT{lmn(Njim&S<;kpEeo{bN&3FW8K!zSU7M0JmrID=VGROPib9c zd!Ns)tMqE0+ij3J8q8C&<~ZvSp5I-!F5JE=FSxlWsD&PAzpK5tUf28nlF@*+A!m;> zSklMx}Ejch1(mv>E`Q;o;5uQ zJKpv+ytQ7}=-B!^+XTnghjoLu=XUd~-|6wbv%C4*>nc67cXp3H&+J>Rc`$2k-|%nk zuA66O;r5vwtdH(B%t8905PiCK8MjogbqvEJ^) zRqo}xyXSf8TeaSNp69$dy`uMaYtC-}z1=JNo;x$mw9s4p{oO12{(9YsYdz5WMlhWE zKy!o5S5J2y?}OdVH|q_$`3K+N=G!;m2W~KvxTEL~clY^23r&aHx8p;jnR_Vz(Ok@d z_Q$(5f8@ITl=ovJ$NpLKC%aXCV&RoD+CJV-jV@}HpY2xpnT2yE(Bu8wXr0S{F>B7D z{Fl2mf8jb4{Pxa%Y2@r;9`9GXReojR9NfCIkBl6r=j?7KtC=+qPVR1g(sg#V!^iNC zEu4d*`}|~gpPyJb=P%vor$$bAW|hz8VoobQ->vzX>n`7oJ~x^<>%;|ToqTuBxwdCh zbIx_v)SOVQXJ2#dnVKos0d;C74`)_WGjTY%n)2K)-PQ$DbBZ;~=0wF=)|3r8$MPwM z!a3KPnnRt_t*JSMagd$zr01k-YM!D)=9KqqjvQ0-CYjKtY}1+Rr<^6sBtB)EjQ6S8 z5az!raOPxeYEF!tk4>2!2h-F{bg)dB(r05$&AaRkoid{z*_KIY&d_F=cYU_z)V#;u zmZ>=+&M{Kif#z^MSam{HZx;%`rmF(P$!%!kj&92l zXeRhsHV2`Z#MK=7hqf}A9LH;WaG9?Krse=~;v6JFoD<-)dpqV-f33l}*5F)gaIQ5t z*BYE_4bHU&=URhvt--n0;9P5Pt~EH<8k}nl&b0>TT7z?~!MWDpTx)QyH8|HAoNEov zwFc)}gLAFHxz^xZ>&U+D+SlM*uN|Cg4bHU&=URhvt--n0;9P5Pt~EH<8k}nl&b0>T zT7z?~!MWDpTx)QyH8|HAoNEovwFc)}gLAFHxz^xZYjCbLIM*7SYYon|2IpFXbFIO- z*3o^vxv#;wUOPCeAfCO4Xm$yr3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43ZlAeyU|n-RS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS>6w=rFu&H?xCa z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5T}CZEHH@9Q-Y|1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDd~Z zL|=pi(Mf6$RS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWr-JBf;2`?iCx|MDDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu`1-^evbm`l3FFDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGQ$f6N76s9Fje@9xsDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDd~ZMBji8qHjh9Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2aVm&@{t?7y zrh=$~sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1sDh}1 zsDh}1sDh}1sDh}1sDh}1sDh}1sDd~ZL_dBDq95J_Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zaVm&@`Wr+)Z49Ccq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4 zq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4 zq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6*?v5PkR{h<=D2L={98L={98L={98 zL={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98 zL={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98 zL={98L={98#Hk?q>`M@R!Xk(&h$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IvLG;n9Ao}1=5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5T}CZlYc?<*|{L9AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$ zAgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$ zAgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUlv1<~gq zf_Upx5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5T}CZbI(EaspBB3AgUm$AgUm$AgUm$AgUm$ zAgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$ zAgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$AgUm$ zAgUlv1@W3$6ht3-526a93Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43gT1{ubo9f^g9hfR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhoC@M~vnYsuZ6}B-h$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IvLA-tz1<~hl zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f;bh#8)i`uFPaLX3Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?) zR1j~RMM3m?v_VusR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6(2y;!U$Ch<=Sbh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh*Lqlc@_oHuTce21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc2 z1yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc2 z1yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKc21yKcYDu}ntq99&86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86~w6^`e92DeIP7|Du^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGQ$f6K z76s8C%L$?iq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4 zq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6(r4 zq6(r4q6(r4q6(r4q6(r4q6(r4q6(r4q6*?v5O1GFLG)K}f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f;bgKe`+m=k4^0uTAo?@ALG*`ogQ$Y2f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf;bgKzdaB{zt0y$6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{)psUY4vi-PDoia}ICR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6(2yqN8;XeMd2fDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nG zDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGDu^nGQ$cjJ4x%qxf~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1f~bP1 zf~bP1f~bP1f~bP1f~bP1f;bh#2WC+aec2L36+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(8 z6+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{(86+{)psUSW$ zi-PF0+Cfx7R6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6(2y;zP42h(46w`0OkS zqHp8`Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2aVm)Z3FjdCvL%Qrh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IGh$@IG zh$@IvL41A|1<{}E45A963Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?4 z3Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43Ze?43gT1{UzkNf^h*OlR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhoC@NLvnYt?Oa)N|Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2 zQ3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3X*2Q3Y`-h%e2eAYL#P zL={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98 zL={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98L={98 zL={98L={98L={98L={98L={98#Hk>@Jd1*O{!|cE5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW z5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFOW5LFPT zg80fT3gV?xK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zCh zK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zCh zK~zChK~zChK~zChK~zChK~zChK~zChK~zChL7WQWtFtJG{w`P$RS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWr-Jy}EDGY4Q$bWgR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fh zR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6$fhR6(2y;_I_0h|5$ERS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DWRS;DW zRS;DWRS;DWRS;DWRS;DWr-Jy#ED9o$K~zChK~zChK~zChK~zChK~zChK~zChK~zCh zK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zCh zK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChK~zChL7X~q!C5EY zot3u`&s~P&7UEgUf#0zjh*M`z4a6zm`5A~)KIT0Tr_P%ih*Q1_8i-TAFdv9h{+X+R zIOX3N8i-T=n*2bV@)_NMIOW83AWmI2H4vvRpBji$KBqAdr%dMqaq6n6fjH%ta0cR( z-+~y3Q~sIDfjH%_@D0Q%-^m|{Q+}g%AWr#}#(_BH({TfF%Eyxi;*@`F;mEf9x%+`Q z%lyTbfjH$)W(>rsJEjKW)SXiUaq7s_K%DXy4F=-W-BSZ`>Yk~AIOW^A199rUsew3k z|I|R7@~005;*{S#ABaD@uSW*rloP^%IECbKyk?zsZk$->MzdsdqiSwc&5f$LQ8hQJ=0?@rsG1v9 zbE9f*RLza5xluJYs^&)3+^CuxRdb_iZdA>Us<}}$H>&1F)!e9>8&z|oYHn1`jp~Sf zayId9Zd5~ZT{a}wYHoCGbE9f*RLza5xluJYs^&)3+^CuxRdb_iZdA>Us<}}$H>&1F z)!e9>8&z|oYHn1`jjFj(H8-l}M%CP?nj2MfqiSwc&5i2lehUrBbz2R|wT5K%e*qNm BIW7PI diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cs b/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cs deleted file mode 100644 index 968295e9d8..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; - -using GoldParser; - -using Irony.Parsing; -using Stride.Core.Shaders.Properties; - -namespace Stride.Core.Shaders.Grammar -{ - public class Tokenizer - { - internal GoldParser.Parser GoldParser; - private static GoldParser.Grammar grammar; - private ShaderLanguageData languageData; - private string source; - - int previousLine = 0; - int newLine = 0; - private string sourceFileName = null; - - static Tokenizer() - { - var grammarStream = new MemoryStream(Resources.Tokenizer); // new FileStream("Preprocessor.cgt", FileMode.Open, FileAccess.Read); - grammar = new GoldParser.Grammar(new BinaryReader(grammarStream)); - grammarStream.Dispose(); - } - - public Tokenizer(ShaderLanguageData languageData) - { - GoldParser = new GoldParser.Parser(grammar); - this.languageData = languageData; - } - - public Irony.Parsing.SourceLocation Location - { - get - { - return new Irony.Parsing.SourceLocation(GoldParser.CharPosition, (GoldParser.LineNumber - previousLine) + newLine, GoldParser.LinePosition, sourceFileName); - } - set - { - int tempNewLine = (value.Line - newLine) + previousLine; - // Console.WriteLine("New source line location: {0} {1} {2} / Previous {3} {4} {5} / Preprocessor Line {6} {7} => NewLine {8}", value.Position, value.Line, value.Column, GoldParser.CharPosition, GoldParser.LineNumber, GoldParser.LinePosition, previousLine, newLine, tempNewLine); - GoldParser.CharPosition = value.Position; - GoldParser.LineNumber = tempNewLine; - } - } - - public void SetSourceText(string sourceText, string sourceFileName) - { - source = sourceText; - GoldParser.SetSourceCode(sourceText); - previousLine = 0; - newLine = 0; - this.sourceFileName = sourceFileName; - } - - public Token GetNextToken() - { - var location = Location; - var symbol = GoldParser.ReadToken(); - Token token = null; - - var tokenType = (TokenType)symbol.Index; - - // Else process the symbol as it should - switch (symbol.SymbolType) - { - case SymbolType.WhiteSpace: - token = new Token(languageData.FindTerminalByType(tokenType), location, GoldParser.TokenLength, source, null); - break; - - case SymbolType.CommentLine: - case SymbolType.CommentStart: - int length = GoldParser.CommentTextLength(location.Position) - location.Position; - token = new Token(languageData.FindTerminalByType(tokenType), location, length, source, null); - break; - case SymbolType.Error: - token = new Token(languageData.Grammar.SyntaxError, location, GoldParser.TokenLength, source, "Unexpected token"); - break; - case SymbolType.End: - token = new Token(languageData.Grammar.Eof, location, string.Empty, languageData.Grammar.Eof.Name); - break; - default: - - // Skip preprocessor line - // Update line number according to - if (symbol.Index == (int)TokenType.Preprocessor) - { - int tempPreviousLine = GoldParser.LineNumber; - bool isEndOfLine = false; - - bool preprocessorDecoded = false; - - while (!isEndOfLine) - { - symbol = GoldParser.ReadToken(); - tokenType = (TokenType)symbol.Index; - - switch ((TokenType)symbol.Index) - { - case TokenType.Eof: - case TokenType.NewLine: - isEndOfLine = true; - break; - case TokenType.Identifier: - if (!preprocessorDecoded) - preprocessorDecoded = GoldParser.TokenText != "line"; - - break; - case TokenType.StringLiteral: - if (preprocessorDecoded) - sourceFileName = GoldParser.TokenText.Trim('"').Replace(@"\\", @"\"); - break; - case TokenType.WS: - case TokenType.Whitespace: - break; - case TokenType.StartWithNoZeroDecimalIntegerLiteral: - if (!preprocessorDecoded) - { - previousLine = tempPreviousLine; - newLine = int.Parse(GoldParser.TokenText) - 1; - preprocessorDecoded = true; - } - break; - default: - preprocessorDecoded = true; - break; - } - } - - location = Location; - } - - - Terminal terminal = null; - if (tokenType == TokenType.Identifier) - terminal = languageData.FindTerminalByName(GoldParser.TokenText); - - if (terminal == null) - terminal = languageData.FindTerminalByType((TokenType)symbol.Index); - - if (terminal == null) - { - token = new Token(languageData.Grammar.SyntaxError, location, GoldParser.TokenText, string.Format("Unable to find terminal for token text [{0}]", GoldParser.TokenText)); - } - else - { - if (terminal is DynamicKeyTerm) - { - ((DynamicKeyTerm)terminal).Match(this, out token); - } - else - { - token = new Token(terminal, location, GoldParser.TokenLength, source, null); - } - } - break; - } - - return token; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.grm b/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.grm deleted file mode 100644 index 0b2e1581f7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Grammar/Tokenizer.grm +++ /dev/null @@ -1,162 +0,0 @@ -! "Name" = 'Tokenizer' -! "Version" = '1.0' -! "Author" = 'Alexandre Mutel' -! "About" = 'Based on partial conversion of Sun Java 1.0-2.0 specification' - -{String Char} = {Printable} - ["] -{Quote} = [''] -{IdLetter} = {Letter} + [_$] -{IdAlphaNumeric} = {Alphanumeric} + [_$] -{HexDigit} = {Digit} + [abcdefABCDEF] -{OctalCharSet} = [01234567] -{NoZeroDigit} = [123456789] -{LongTypeSuffix} =[lL] -{FloatTypeSuffix} =[hHdfDF] -{ExponentPartIndicator} = [eE] -{Sign} = [-+] -{CharSign} = [abtnfr"\] + {Quote} -{CharSign1} = {String Char} - [\] -{HexEscapeSign} =[uUxX] -{WS} = {Whitespace} - {CR} - {LF} - -Identifier = {IdLetter}{IdAlphaNumeric}* -StringLiteral = '"'{String Char}*'"' -FloatingPointLiteral = {Digit}+'.'{Digit}*{FloatTypeSuffix}? | {Digit}+{FloatTypeSuffix} | '.'{Digit}+{FloatTypeSuffix}? -FloatingPointLiteralExponent = {Digit}+'.'{Digit}*{ExponentPartIndicator}{Sign}?{Digit}+{FloatTypeSuffix}? | {Digit}+{ExponentPartIndicator}{Sign}?{Digit}+{FloatTypeSuffix}? | '.'{Digit}+{ExponentPartIndicator}{Sign}?{Digit}+{FloatTypeSuffix}? -IndirectCharLiteral = {Quote}{CharSign1}{Quote} -StandardEscapeCharLiteral = {Quote}'\'{CharSign}{Quote} -OctalEscapeCharLiteral ={Quote}'\'{OctalCharSet}+{Quote} -HexEscapeCharLiteral ={Quote}'\'{HexEscapeSign}{HexDigit}+{Quote} -StartWithNoZeroDecimalIntegerLiteral = {NoZeroDigit}{Digit}*{LongTypeSuffix}? -StartWithZeroDecimalIntegerLiteral = '0'{LongTypeSuffix}? -HexIntegerLiteral = '0'('x'|'X'){HexDigit}+{LongTypeSuffix}? -OctalIntegerLiteral = '0'{OctalCharSet}+{LongTypeSuffix}? - -!"Case Sensitive" = 'True' -Whitespace = {WS}+ -NewLine = {CR}{LF} | {CR} | {LF} - -LineContinuation = '\' -Preprocessor = '#' -TokenPasting = '##' -Arrobas = '@' -Not = '!' -NotEqual = '!=' -And = '&&' -LeftParen = '(' -RightParen = ')' -Mul = '*' -MulAssign = '*=' -Plus = '+' -PlusPlus = '++' -AddAssign = '+=' -Comma = ',' -Minus = '-' -MinusMinus = '--' -SubAssign = '-=' -Div = '/' -DivAssign = '/=' -Mod = '%' -ModAssign = '%=' -Colon = ':' -Semi = ';' -LessThan = '<' -LessThanOrEqual = '<=' -Assign = '=' -Equal = '==' -GreaterThan = '>' -GreaterThanOrEqual = '>=' -Question = '?' -LeftBracket = '[' -RightBracket = ']' -LeftCurly = '{' -Or = '||' -RightCurly = '}' -Dot = '.' -BitwiseNot = '~' -BitwiseShiftLeft ='<<' -BitwiseShiftRight='>>' -BitwiseAnd ='&' -BitwiseOr ='|' -BitwiseXor ='^' -BitwiseShiftLeftAssign='<<=' -BitwiseShiftRightAssign='>>=' -BitwiseAndAssign = '&=' -BitwiseOrAssign = '|=' -BitwiseXorAssign = '^=' -IdentifierSeparator = '::' - -Comment Start = '/*' -Comment End = '*/' -Comment Line = '//' - -"Start Symbol" = - - - ::= WS - | NewLine - | IndirectCharLiteral - | StandardEscapeCharLiteral - | OctalEscapeCharLiteral - | HexEscapeCharLiteral - | StartWithZeroDecimalIntegerLiteral - | StartWithNoZeroDecimalIntegerLiteral - | FloatingPointLiteral - | FloatingPointLiteralExponent - | HexIntegerLiteral - | OctalIntegerLiteral - | StringLiteral - | Identifier - | LineContinuation - | Preprocessor - | TokenPasting - | Arrobas - | Not - | NotEqual - | And - | LeftParen - | RightParen - | Mul - | MulAssign - | Plus - | PlusPlus - | AddAssign - | Comma - | Minus - | MinusMinus - | SubAssign - | Div - | DivAssign - | Mod - | ModAssign - | Colon - | Semi - | LessThan - | LessThanOrEqual - | Assign - | Equal - | GreaterThan - | GreaterThanOrEqual - | Question - | LeftBracket - | RightBracket - | LeftCurly - | Or - | RightCurly - | Dot - | BitwiseNot - | BitwiseShiftLeft - | BitwiseShiftRight - | BitwiseAnd - | BitwiseOr - | BitwiseXor - | BitwiseShiftLeftAssign - | BitwiseShiftRightAssign - | BitwiseAndAssign - | BitwiseOrAssign - | BitwiseXorAssign - | IdentifierSeparator - - - ::= - | diff --git a/sources/shaders/Stride.Core.Shaders/Parser/Hlsl/HlslParser.cs b/sources/shaders/Stride.Core.Shaders/Parser/Hlsl/HlslParser.cs deleted file mode 100644 index 054563f878..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Parser/Hlsl/HlslParser.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Grammar.Hlsl; - -// Use StrideGrammar (compatiable with HLSL), in order to avoid initializing both Stride and HLSL grammar -using HlslGrammar = Stride.Core.Shaders.Grammar.Stride.StrideGrammar; - -namespace Stride.Core.Shaders.Parser.Hlsl -{ - /// - /// HlslParser. - /// - public class HlslParser - { - /// - /// Initializes this instance. - /// - static HlslParser() - { - // Call get parser to force an initialization - ShaderParser.GetParser(); - } - - /// - /// Initializes this instance. - /// - public static void Initialize() - { - // Call get parser to force an initialization - ShaderParser.GetParser(); - } - - /// - /// Parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static ParsingResult TryPreProcessAndParse(string source, string sourceFileName, ShaderMacro[] macros = null, params string[] includeDirectories) - { - return ShaderParser.GetParser().TryPreProcessAndParse(source, sourceFileName, macros, includeDirectories); - } - - /// - /// Parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public static Shader Parse(string source, string sourceFileName, ShaderMacro[] macros = null, params string[] includeDirectories) - { - return ShaderParser.GetParser().PreProcessAndParse(source, sourceFileName, macros, includeDirectories); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Parser/ParsingResult.cs b/sources/shaders/Stride.Core.Shaders/Parser/ParsingResult.cs deleted file mode 100644 index a6cfda896a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Parser/ParsingResult.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Parser -{ - - /// - /// A Parsing result. - /// - [DataContract] - public class ParsingResult : LoggerResult - { - #region Public Properties - - /// - /// Gets or sets the shader. - /// - /// - /// The shader. - /// - public Shader Shader { get; set; } - - /// - /// Gets or sets the time to parse in ms. - /// - /// - /// The time to parse ms. - /// - public long TimeToParse { get; set; } - - /// - /// Gets or sets the token count. - /// - /// - /// The token count. - /// - public int TokenCount { get; set; } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Parser/PreProcessor.cs b/sources/shaders/Stride.Core.Shaders/Parser/PreProcessor.cs deleted file mode 100644 index 10e222d032..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Parser/PreProcessor.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.IO; -using System.Text; - -using CppNet; - -using Stride.Core.Shaders.Parser; - -namespace Stride.Core.Shaders -{ - /// - /// C++ preprocessor using D3DPreprocess method from d3dcompiler API. - /// - public partial class PreProcessor - { - /// - /// Preprocesses the provided shader or effect source. - /// - /// An array of bytes containing the raw source of the shader or effect to preprocess. - /// Name of the source file. - /// A set of macros to define during preprocessing. - /// The include directories used by the preprocessor. - /// - /// The preprocessed shader source. - /// - public static string Run(string shaderSource, string sourceFileName, ShaderMacro[] defines = null, params string[] includeDirectories) - { - var cpp = new Preprocessor(); - cpp.addFeature(Feature.DIGRAPHS); - cpp.addWarning(Warning.IMPORT); - cpp.addFeature(Feature.INCLUDENEXT); - cpp.addFeature(Feature.LINEMARKERS); - - // TODO: Handle warning and errors properly instead of relying only on exception - // Don't setup a listener and get any errors via exceptions - cpp.setListener(new ErrorListener()); - - // Pass defines - if (defines != null) - { - foreach (var define in defines) - { - if (!string.IsNullOrWhiteSpace(define.Name)) - { - cpp.addMacro(define.Name, define.Definition ?? string.Empty); - } - } - } - - // Setup input directories. - var tempDirectories = new List() { Path.GetDirectoryName(sourceFileName) }; - tempDirectories.AddRange(includeDirectories); - cpp.setQuoteIncludePath(tempDirectories); - - var inputSource = new StringLexerSource(shaderSource, true, sourceFileName); - - cpp.addInput(inputSource); - - var textBuilder = new StringBuilder(); - - var isEndOfStream = false; - while (!isEndOfStream) - { - Token tok = cpp.token(); - switch (tok.getType()) - { - case Token.EOF: - isEndOfStream = true; - break; - case Token.CCOMMENT: - var strComment = tok.getText() ?? string.Empty; - foreach (var commentChar in strComment) - { - textBuilder.Append(commentChar == '\n' ? '\n' : ' '); - } - break; - case Token.CPPCOMMENT: - break; - default: - var tokenText = tok.getText(); - if (tokenText != null) - { - textBuilder.Append(tokenText); - } - break; - } - } - - return textBuilder.ToString(); - } - - private class ErrorListener : CppNet.PreprocessorListenerBase - { - public override void handleError(Source source, int line, int column, string msg) - { - base.handleError(source, line, column, msg); - throw new LexerException("Error at " + line + ":" + column + ": " + msg); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Parser/ShaderMacro.cs b/sources/shaders/Stride.Core.Shaders/Parser/ShaderMacro.cs deleted file mode 100644 index e9e79028f9..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Parser/ShaderMacro.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; - -namespace Stride.Core.Shaders.Parser -{ - /// - /// Macro to be used with . - /// - public struct ShaderMacro : IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// The name. - /// The definition. - public ShaderMacro(string name, object definition) - { - if (name == null) throw new ArgumentNullException("name"); - - Name = name; - Definition = definition == null ? string.Empty : (definition is bool ? definition.ToString().ToLowerInvariant() : definition.ToString()); - } - - /// - /// Name of the macro to set. - /// - public readonly string Name; - - /// - /// Value of the macro to set. - /// - public readonly string Definition; - - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// An object to compare with this object. - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public bool Equals(ShaderMacro other) - { - return Equals(other.Name, Name) && Equals(other.Definition, Definition); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (obj.GetType() != typeof (ShaderMacro)) return false; - return Equals((ShaderMacro)obj); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - unchecked - { - return (Name.GetHashCode()* 397) ^ (Definition != null ? Definition.GetHashCode() : 0); - } - } - - public override string ToString() - { - return string.Format("{0}={1}", Name, Definition); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Parser/ShaderParser.cs b/sources/shaders/Stride.Core.Shaders/Parser/ShaderParser.cs deleted file mode 100644 index d30b575be0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Parser/ShaderParser.cs +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; - -using Irony.Parsing; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Grammar; -using Stride.Core.Shaders.Utility; - -using SourceLocation = Stride.Core.Shaders.Ast.SourceLocation; -using SourceSpan = Stride.Core.Shaders.Ast.SourceSpan; - -namespace Stride.Core.Shaders.Parser -{ - /// - /// Parser class. - /// - public class ShaderParser - { - private static readonly Dictionary LanguageDatas = new Dictionary(); - - /// - /// Gets or sets the parser. - /// - /// - /// The parser. - /// - public Irony.Parsing.Parser Parser { get; private set; } - - /// - /// Gets the grammar. - /// - public ShaderGrammar Grammar{ get; private set; } - - /// - /// Gets or sets the language data. - /// - /// - /// The language data. - /// - public ShaderLanguageData LanguageData { get; private set; } - - /// - /// Gets the tokenizer. - /// - public Tokenizer Tokenizer { get; private set; } - - /// - /// Prevents a default instance of the class from being created. - /// - /// The language data. - /// The root of the language. - private ShaderParser(ShaderLanguageData languageData, NonTerminal root) - { - LanguageData = languageData; - Grammar = (ShaderGrammar)languageData.Grammar; - Tokenizer = new Tokenizer(languageData); - Parser = new Irony.Parsing.Parser(languageData, null, root); - } - - /// - /// Preprocesses and parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public ParsingResult TryPreProcessAndParse(string source, string sourceFileName, ShaderMacro[] macros = null, params string[] includeDirectories) - { - - var allIncludeDirectories = new List(); - - if (includeDirectories != null) - allIncludeDirectories.AddRange(includeDirectories); - - var directoryName = Path.GetDirectoryName(sourceFileName); - if (!string.IsNullOrEmpty(directoryName)) - allIncludeDirectories.Add(directoryName); - - // Run the processor - string preprocessedSource; - - try - { - preprocessedSource = PreProcessor.Run(source, sourceFileName, macros, allIncludeDirectories.ToArray()); - } - catch (Exception ex) - { - var result = new ParsingResult(); - result.Error(MessageCode.ErrorUnexpectedException, new SourceSpan(new SourceLocation(sourceFileName, 0, 1, 1), 1), ex); - return result; - } - - // Parse the source - return Parse(preprocessedSource, sourceFileName); - } - - /// - /// Preprocesses and parses the specified source. - /// - /// The source. - /// Name of the source file. - /// The macros defined for the preprocessor. - /// The include directories used by the preprocessor.. - /// Result of parsing - public Shader PreProcessAndParse(string source, string sourceFileName, ShaderMacro[] macros = null, params string[] includeDirectories) - { - // Parse the source - var result = TryPreProcessAndParse(source, sourceFileName, macros, includeDirectories); - return Check(result, sourceFileName); - } - - /// - /// Gets the parser. - /// - /// - /// - public static ShaderParser GetParser(NonTerminal root = null) where T : ShaderGrammar, new() - { - ShaderLanguageData languageData; - lock (LanguageDatas) - { - if (!LanguageDatas.TryGetValue(typeof(T), out languageData)) - { - languageData = new ShaderLanguageData(new T()); - LanguageDatas.Add(typeof(T), languageData); - } - } - - return new ShaderParser(languageData, root); - } - - /// - /// Gets the language. - /// - /// - /// - public static T GetGrammar() where T : ShaderGrammar, new() - { - ShaderLanguageData languageData; - lock (LanguageDatas) - { - if (!LanguageDatas.TryGetValue(typeof(T), out languageData)) - { - languageData = new ShaderLanguageData(new T()); - LanguageDatas.Add(typeof(T), languageData); - } - - return (T)languageData.Grammar; - } - } - - /// - /// Parses the specified source code. - /// - /// Type of the grammar - /// The source code. - /// The file. - /// A parsing result - public ParsingResult Parse(string sourceCode, string file) - { - var clock = new Stopwatch(); - clock.Start(); - var parseTree = Parser.Parse(sourceCode, file); - clock.Stop(); - - var result = new ParsingResult - { - TimeToParse = clock.ElapsedMilliseconds, - TokenCount = parseTree.Tokens.Count, - }; - - // Get the parsed node - if (parseTree.Root != null && parseTree.Root.AstNode != null) - { - result.Shader = (Shader)((IronyBrowsableNode)parseTree.Root.AstNode).Node; - } - else - { - result.HasErrors = true; - } - - - // Add messages from Irony - HandleMessages(parseTree, file, result); - - return result; - } - - /// - /// Parse a source code file and check that the result is valid. - /// - /// - /// - /// - public Shader ParseAndCheck(string sourceCode, string file) - { - var result = Parse(sourceCode, file); - return Check(result, file); - } - - public static Shader Check(ParsingResult result, string sourceFileName) - { - // Throws an exception if there are any errors. - // Todo provide better handling - if (result.HasErrors) - { - var errorText = new StringBuilder(); - errorText.AppendFormat("Unable to parse file [{0}]", sourceFileName).AppendLine(); - foreach (var reportMessage in result.Messages) - { - errorText.AppendLine(reportMessage.ToString()); - } - throw new InvalidOperationException(errorText.ToString()); - } - return result.Shader; - } - - private static void HandleMessages(ParseTree parseTree, string file, ParsingResult result) - { - foreach (var parserMessage in parseTree.ParserMessages) - { - var level = new ReportMessageLevel(); - switch (parserMessage.Level) - { - case ParserErrorLevel.Info: - level = ReportMessageLevel.Info; - break; - case ParserErrorLevel.Error: - level = ReportMessageLevel.Error; - break; - case ParserErrorLevel.Warning: - level = ReportMessageLevel.Warning; - break; - } - - result.Messages.Add(new ReportMessage(level, "", parserMessage.Message, new Ast.SourceSpan(SpanConverter.Convert(parserMessage.Location), 0))); - - if (parserMessage.Level != ParserErrorLevel.Info) result.HasErrors = true; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Properties/AssemblyInfo.cs b/sources/shaders/Stride.Core.Shaders/Properties/AssemblyInfo.cs deleted file mode 100644 index ce30b0d038..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Reflection; -using System.Runtime.CompilerServices; - - -#pragma warning disable 436 // Stride.PublicKeys is defined in multiple assemblies - -[assembly: InternalsVisibleTo("Stride.Core.Shaders.Serializers" + Stride.PublicKeys.Default)] diff --git a/sources/shaders/Stride.Core.Shaders/Properties/Resources.cs b/sources/shaders/Stride.Core.Shaders/Properties/Resources.cs deleted file mode 100644 index 82af5f612a..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Properties/Resources.cs +++ /dev/null @@ -1,1385 +0,0 @@ -using System.Reflection; - -namespace Stride.Core.Shaders.Properties -{ - public class Resources - { - private static global::System.Resources.ResourceManager resourceMan; - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - private static global::System.Resources.ResourceManager ResourceManager - { - get - { - if (object.ReferenceEquals(resourceMan, null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Stride.Core.Shaders.Properties.Resources", typeof(Resources).GetTypeInfo().Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - public static System.String HlslDeclarations - { - get { - return "// ------------------------------------------------------------------------------" + - "---------\r\n// Shader Model 4.0 / 4.1\r\n// ---------------------------------------" + - "------------------------------------------------\r\n\r\n// CalculateLevelOfDetail (D" + - "irectX HLSL Texture Object) \r\n// http://msdn.microsoft.com/en-us/library/windows" + - "/desktop/bb944001%28v=vs.85%29.aspx\r\n\r\n// Gather (DirectX HLSL Texture Object) \r" + - "\n// http://msdn.microsoft.com/en-us/library/windows/desktop/bb944003%28v=VS.85%2" + - "9.aspx\r\n\r\n// GetDimensions (DirectX HLSL Texture Object)\r\n// http://msdn.microso" + - "ft.com/en-us/library/bb509693%28v=VS.85%29.aspx\r\n\r\n// GetSamplePosition (DirectX" + - " HLSL Texture Object)\r\n// http://msdn.microsoft.com/en-us/library/bb944004%28v=V" + - "S.85%29.aspx\r\n\r\n// Load (DirectX HLSL Texture Object)\r\n// http://msdn.microsoft." + - "com/en-us/library/bb509694%28v=VS.85%29.aspx\r\n\r\n// Sample (DirectX HLSL Texture " + - "Object)\r\n// http://msdn.microsoft.com/en-us/library/bb509695%28v=VS.85%29.aspx\r\n" + - "\r\n// SampleBias (DirectX HLSL Texture Object)\r\n// http://msdn.microsoft.com/en-u" + - "s/library/bb944005%28v=VS.85%29.aspx\r\n\r\n// SampleCmp (DirectX HLSL Texture Objec" + - "t)\r\n// http://msdn.microsoft.com/en-us/library/bb509696%28v=VS.85%29.aspx\r\n\r\n// " + - "SampleGrad (DirectX HLSL Texture Object)\r\n// http://msdn.microsoft.com/en-us/lib" + - "rary/bb509698%28v=VS.85%29.aspx\r\n\r\n// SampleLevel (DirectX HLSL Texture Object)\r" + - "\n// http://msdn.microsoft.com/en-us/library/bb509699%28v=VS.85%29.aspx\r\n\r\nvoid G" + - "roupMemoryBarrierWithGroupSync();\r\n\r\nclass __Texture1D {\r\n\t// SM 4.0\r\n\tfloat " + - "CalculateLevelOfDetail( sampler_state s, float1 x);\r\n\tvoid GetDimensions( uint M" + - "ipLevel, out uint Width, out uint NumberOfLevels);\r\n\tvoid GetDimensions( out uin" + - "t Width);\r\n\tvoid GetDimensions( uint MipLevel, out float Width, out float Number" + - "OfLevels);\r\n\tvoid GetDimensions( out float Width);\r\n\tT Load(int2 Location);\r\n\tT " + - "Load(int2 Location, int Offset);\r\n\tfloat4 Sample(sampler_state S, float Location" + - ");\r\n\tfloat4 Sample(sampler_state S, float Location, int Offset);\r\n\tfloat4 Sample" + - "Bias(sampler_state S, float Location, float Bias);\r\n\tfloat4 SampleBias(sampler_s" + - "tate S, float Location, float Bias, int Offset);\r\n\tfloat SampleCmp(sampler_state" + - " S, float Location, float CompareValue);\r\n\tfloat SampleCmp(sampler_state S, floa" + - "t Location, float CompareValue, int Offset);\r\n\tfloat SampleCmpLevelZero(sampler_" + - "state S, float Location, float CompareValue);\r\n\tfloat SampleCmpLevelZero(sampler" + - "_state S, float Location, float CompareValue, int Offset);\r\n\tfloat4 SampleGrad(s" + - "ampler_state S, float Location, float DDX, float DDY);\r\n\tfloat4 SampleGrad(sampl" + - "er_state S, float Location, float DDX, float DDY, int Offset);\r\n\tfloat4 SampleLe" + - "vel( sampler_state S, float Location, float LOD);\r\n\tfloat4 SampleLevel( sampler_" + - "state S, float Location, float LOD, int Offset);\r\n\r\n\t// SM 5.0\r\n\tT mips.operator" + - "[][](in uint mipSlice,in uint pos);\t\r\n\t\r\n\tT operator[](in uint pos);\r\n};\r\n\r\ncl" + - "ass __Texture1DArray {\r\n\t// SM 4.0\r\n\tfloat CalculateLevelOfDetail( sampler_st" + - "ate s, float1 x);\r\n\tvoid GetDimensions( uint MipLevel, out uint Width, out uint " + - "Elements, out uint NumberOfLevels);\r\n\tvoid GetDimensions( out uint Width, out ui" + - "nt Elements);\r\n\tvoid GetDimensions( uint MipLevel, out float Width, out float El" + - "ements, out float NumberOfLevels);\r\n\tvoid GetDimensions( out float Width, out fl" + - "oat Elements);\r\n\tT Load(int3 Location);\r\n\tT Load(int3 Location, int Offset);\r\n\tf" + - "loat4 Sample(sampler_state S, float2 Location);\r\n\tfloat4 Sample(sampler_state S," + - " float2 Location, int Offset);\r\n\tfloat4 SampleBias(sampler_state S, float2 Locat" + - "ion, float Bias);\r\n\tfloat4 SampleBias(sampler_state S, float2 Location, float Bi" + - "as, int Offset);\r\n\tfloat SampleCmp(sampler_state S, float2 Location, float Compa" + - "reValue);\r\n\tfloat SampleCmp(sampler_state S, float2 Location, float CompareValue" + - ", int Offset);\r\n\tfloat SampleCmpLevelZero(sampler_state S, float2 Location, floa" + - "t CompareValue);\r\n\tfloat SampleCmpLevelZero(sampler_state S, float2 Location, fl" + - "oat CompareValue, int Offset);\r\n\tfloat4 SampleGrad(sampler_state S, float2 Locat" + - "ion, float DDX, float DDY);\r\n\tfloat4 SampleGrad(sampler_state S, float2 Location" + - ", float DDX, float DDY, int Offset);\r\n\tfloat4 SampleLevel( sampler_state S, floa" + - "t2 Location, float LOD);\r\n\tfloat4 SampleLevel( sampler_state S, float2 Location," + - " float LOD, int Offset);\r\n\r\n\t// SM 5.0\r\n\tT mips.operator[][](in uint mipSlice,i" + - "n uint2 pos);\t\r\n\r\n T operator[](in uint2 pos);\r\n};\r\n\r\nclass __Texture2D " + - "{\r\n\t// SM 4.0\r\n\tfloat CalculateLevelOfDetail( sampler_state s, float2 x);\r\n\tvect" + - "or<__T_base,4> Gather( sampler_state S, float2 Location);\r\n\tvector<__T_base,4> G" + - "ather( sampler_state S, float2 Location, int2 Offset );\r\n\tvoid GetDimensions( ui" + - "nt MipLevel, out uint Width, out uint Height, out uint NumberOfLevels);\r\n\tvoid G" + - "etDimensions( out uint Width, out uint Height);\r\n\tvoid GetDimensions( uint MipLe" + - "vel, out float Width, out float Height, out float NumberOfLevels);\r\n\tvoid GetDim" + - "ensions( out float Width, out float Height);\r\n\tT Load(int3 Location);\r\n\tT Load(i" + - "nt3 Location, int2 Offset);\r\n\tfloat4 Sample(sampler_state S, float2 Location);\r\n" + - "\tfloat4 Sample(sampler_state S, float2 Location, int2 Offset);\r\n\tfloat4 SampleBi" + - "as(sampler_state S, float2 Location, float Bias);\r\n\tfloat4 SampleBias(sampler_st" + - "ate S, float2 Location, float Bias, int2 Offset);\r\n\tfloat SampleCmp(sampler_stat" + - "e S, float2 Location, float CompareValue);\r\n\tfloat SampleCmp(sampler_state S, fl" + - "oat2 Location, float CompareValue, int2 Offset);\r\n\tfloat SampleCmpLevelZero(samp" + - "ler_state S, float2 Location, float CompareValue);\r\n\tfloat SampleCmpLevelZero(sa" + - "mpler_state S, float2 Location, float CompareValue, int2 Offset);\r\n\tfloat4 Sampl" + - "eGrad(sampler_state S, float2 Location, float2 DDX, float2 DDY);\r\n\tfloat4 Sample" + - "Grad(sampler_state S, float2 Location, float2 DDX, float2 DDY, int2 Offset);\r\n\tf" + - "loat4 SampleLevel( sampler_state S, float2 Location, float LOD);\r\n\tfloat4 Sample" + - "Level( sampler_state S, float2 Location, float LOD, int2 Offset);\r\n\t\r\n\t// SM 5.0" + - "\r\n\tT Gather(\r\n\t in sampler s,\r\n\t in float2 location,\r\n\t in int2 offset\r\n\t)" + - ";\t\r\n\t\r\n\tT GatherRed(\r\n\t\tin sampler s,\r\n\t\tin float2 location\r\n\t\t);\r\n\r\n\tT Gather" + - "Green(\r\n\t\tin sampler s,\r\n\t\tin float2 location\r\n\t\t);\r\n\r\n\tT GatherBlue(\r\n\t\tin s" + - "ampler s,\r\n\t\tin float2 location\r\n\t\t);\r\n\r\n\tT GatherRed(\r\n\t in sampler s,\r\n\t i" + - "n float2 location,\r\n\t in int2 offset\r\n\t);\r\n\r\n\tT GatherGreen(\r\n\t in sampler " + - "s,\r\n\t in float2 location,\r\n\t in int2 offset\r\n\t);\r\n\t\r\n\tT GatherBlue(\r\n\t in " + - "sampler s,\r\n\t in float2 location,\r\n\t in int2 offset\r\n\t);\t\r\n\r\n\tT GatherAlpha(" + - "\r\n\t in sampler s,\r\n\t in float2 location,\r\n\t in int2 offset\r\n\t);\r\n\r\n\tT Gath" + - "erRed(\r\n\t in sampler s,\r\n\t in float2 location,\r\n\t in int2 offset1,\r\n\t in " + - " int2 offset2,\r\n\t in int2 offset3,\r\n\t in int2 offset4\r\n\t);\r\n\r\n\tT GatherGreen" + - "(\r\n\t in sampler s,\r\n\t in float2 location,\r\n\t in int2 offset1,\r\n\t in int2" + - " offset2,\r\n\t in int2 offset3,\r\n\t in int2 offset4\r\n\t);\r\n\t\r\n\tT GatherBlue(\r\n\t " + - " in sampler s,\r\n\t in float2 location,\r\n\t in int2 offset1,\r\n\t in int2 offs" + - "et2,\r\n\t in int2 offset3,\r\n\t in int2 offset4\r\n\t);\t\r\n\r\n\tT GatherAlpha(\r\n\t in " + - " sampler s,\r\n\t in float2 location,\r\n\t in int2 offset1,\r\n\t in int2 offset2," + - "\r\n\t in int2 offset3,\r\n\t in int2 offset4\r\n\t);\r\n\r\n\tfloat4 GatherCmp(\r\n\t in S" + - "amplerComparisonState s,\r\n\t in float2 location,\r\n\t in float compare_value,\r\n" + - "\t in int2 offset\r\n\t);\t\r\n\t\r\n\tfloat4 GatherCmpRed(\r\n\t in SamplerComparisonStat" + - "e s,\r\n\t in float2 location,\r\n\t in float compare_value,\r\n\t in int2 offset\r\n" + - "\t);\t\r\n\t\r\n\tfloat4 GatherCmpGreen(\r\n\t in SamplerComparisonState s,\r\n\t in float" + - "2 location,\r\n\t in float compare_value,\r\n\t in int2 offset\r\n\t);\t\r\n\t\r\n\tfloat4 G" + - "atherCmpBlue(\r\n\t in SamplerComparisonState s,\r\n\t in float2 location,\r\n\t in " + - " float compare_value,\r\n\t in int2 offset\r\n\t);\r\n\t\r\n\tfloat4 GatherCmpAlpha(\r\n\t i" + - "n SamplerComparisonState s,\r\n\t in float2 location,\r\n\t in float compare_valu" + - "e,\r\n\t in int2 offset\r\n\t);\r\n\t\r\n\tT mips.operator[][](in uint mipSlice, in uint2" + - " pos);\r\n\t\t\r\n\tT operator[](in uint2 pos);\r\n};\r\n\r\nclass __Texture2DArray {\r\n\t/" + - "/ SM 4.0\r\n\tfloat CalculateLevelOfDetail( sampler_state s, float2 x);\r\n\tvector<__" + - "T_base,4> Gather( sampler_state S, float3 Location, int2 Offset );\r\n\tvoid GetDim" + - "ensions( uint MipLevel, out uint Width, out uint Height, out uint Elements, out " + - "uint NumberOfLevels);\r\n\tvoid GetDimensions( out uint Width, out uint Height, out" + - " uint Elements);\r\n\tvoid GetDimensions( uint MipLevel, out float Width, out float" + - " Height, out float Elements, out float NumberOfLevels);\r\n\tvoid GetDimensions( ou" + - "t float Width, out float Height, out float Elements);\r\n\tT Load(int4 Location);\r\n" + - "\tT Load(int4 Location, int2 Offset);\r\n\tT Load(int4 Location, int3 Offset);\r\n\tflo" + - "at4 Sample(sampler_state S, float3 Location);\r\n\tfloat4 Sample(sampler_state S, f" + - "loat3 Location, int2 Offset);\r\n\tfloat4 SampleBias(sampler_state S, float3 Locati" + - "on, float Bias);\r\n\tfloat4 SampleBias(sampler_state S, float3 Location, float Bia" + - "s, int2 Offset);\r\n\tfloat SampleCmp(sampler_state S, float3 Location, float Compa" + - "reValue);\r\n\tfloat SampleCmp(sampler_state S, float3 Location, float CompareValue" + - ", int2 Offset);\r\n\tfloat SampleCmpLevelZero(sampler_state S, float3 Location, flo" + - "at CompareValue);\r\n\tfloat SampleCmpLevelZero(sampler_state S, float3 Location, f" + - "loat CompareValue, int2 Offset);\r\n\tfloat4 SampleGrad(sampler_state S, float3 Loc" + - "ation, float2 DDX, float2 DDY);\r\n\tfloat4 SampleGrad(sampler_state S, float3 Loca" + - "tion, float2 DDX, float2 DDY, int2 Offset);\r\n\tfloat4 SampleLevel( sampler_state " + - "S, float3 Location, float LOD);\r\n\tfloat4 SampleLevel( sampler_state S, float3 Lo" + - "cation, float LOD, int2 Offset);\r\n\r\n\t\t// SM 5.0\r\n\tT Gather(\r\n\t in sampler s,\r\n" + - "\t in float3 location,\r\n\t in int2 offset\r\n\t);\t\r\n\t\r\n\tT GatherRed(\r\n\t in samp" + - "ler s,\r\n\t in float3 location,\r\n\t in int2 offset\r\n\t);\r\n\r\n\tT GatherGreen(\r\n\t " + - "in sampler s,\r\n\t in float3 location,\r\n\t in int2 offset\r\n\t);\r\n\t\r\n\tT GatherBl" + - "ue(\r\n\t in sampler s,\r\n\t in float3 location,\r\n\t in int2 offset\r\n\t);\t\r\n\r\n\tT " + - "GatherAlpha(\r\n\t in sampler s,\r\n\t in float3 location,\r\n\t in int2 offset\r\n\t)" + - ";\r\n\r\n\tfloat4 GatherCmp(\r\n\t in SamplerComparisonState s,\r\n\t in float3 locatio" + - "n,\r\n\t in float compare_value,\r\n\t in int2 offset\r\n\t);\t\r\n\t\r\n\tfloat4 GatherCmpR" + - "ed(\r\n\t in SamplerComparisonState s,\r\n\t in float3 location,\r\n\t in float com" + - "pare_value,\r\n\t in int2 offset\r\n\t);\t\r\n\t\r\n\tfloat4 GatherCmpGreen(\r\n\t in Sample" + - "rComparisonState s,\r\n\t in float3 location,\r\n\t in float compare_value,\r\n\t in" + - " int2 offset\r\n\t);\t\r\n\t\r\n\tfloat4 GatherCmpBlue(\r\n\t in SamplerComparisonState s," + - "\r\n\t in float3 location,\r\n\t in float compare_value,\r\n\t in int2 offset\r\n\t);\r" + - "\n\t\r\n\tfloat4 GatherCmpAlpha(\r\n\t in SamplerComparisonState s,\r\n\t in float3 loc" + - "ation,\r\n\t in float compare_value,\r\n\t in int2 offset\r\n\t);\r\n\t\r\n\tT mips.operato" + - "r[][](in uint mipSlice, in uint3 pos);\r\n\t\t\r\n\tT operator[](in uint3 pos);\r\n};\r" + - "\n\r\n\r\nclass __Texture3D {\r\n\t// SM 4.0\r\n\tfloat CalculateLevelOfDetail( sampler_" + - "state s, float3 x);\r\n\tvoid GetDimensions( uint MipLevel, out uint Width, out uin" + - "t Height, out uint Depth, out uint NumberOfLevels);\r\n\tvoid GetDimensions( out ui" + - "nt Width, out uint Height, out uint Depth);\r\n\tvoid GetDimensions( uint MipLevel," + - " out float Width, out float Height, out float Depth, out float NumberOfLevels);\r" + - "\n\tvoid GetDimensions( out float Width, out float Height, out float Depth);\r\n\tT L" + - "oad(int4 Location);\r\n\tT Load(int4 Location, int3 Offset);\r\n\tfloat4 Sample(sample" + - "r_state S, float3 Location);\r\n\tfloat4 Sample(sampler_state S, float3 Location, i" + - "nt3 Offset);\r\n\tfloat4 SampleBias(sampler_state S, float3 Location, float Bias);\r" + - "\n\tfloat4 SampleBias(sampler_state S, float3 Location, float Bias, int3 Offset);\r" + - "\n\tfloat SampleCmp(sampler_state S, float3 Location, float CompareValue);\r\n\tfloat" + - " SampleCmp(sampler_state S, float3 Location, float CompareValue, int3 Offset);\r\n" + - "\tfloat4 SampleGrad(sampler_state S, float3 Location, float3 DDX, float3 DDY);\r\n\t" + - "float4 SampleGrad(sampler_state S, float3 Location, float3 DDX, float3 DDY, int3" + - " Offset);\r\n\tfloat4 SampleLevel( sampler_state S, float3 Location, float LOD);\r\n\t" + - "float4 SampleLevel( sampler_state S, float3 Location, float LOD, int3 Offset);\r\n" + - "\t\r\n\t// SM 5.0\r\n\tT mips.operator[][](in uint mipSlice,in uint3 pos);\r\n\t\t\r\n\tT ope" + - "rator[](in uint3 pos);\r\n};\r\n\r\nclass __TextureCube {\r\n\t// SM 4.0\r\n\tfloat Calc" + - "ulateLevelOfDetail( sampler_state s, float3 x);\r\n\tvector<__T_base,4> Gather( sam" + - "pler_state S, float3 Location);\r\n\tvoid GetDimensions( uint MipLevel, out uint Wi" + - "dth, out uint Height, out uint NumberOfLevels);\r\n\tvoid GetDimensions( out uint W" + - "idth, out uint Height);\r\n\tvoid GetDimensions( uint MipLevel, out float Width, ou" + - "t float Height, out uint NumberOfLevels);\r\n\tvoid GetDimensions( out float Width," + - " out float Height);\r\n\tfloat4 Sample(sampler_state S, float3 Location);\r\n\tfloat4 " + - "SampleBias(sampler_state S, float3 Location, float Bias);\r\n\tfloat SampleCmp(samp" + - "ler_state S, float3 Location, float CompareValue);\r\n\tfloat SampleCmpLevelZero(sa" + - "mpler_state S, float3 Location, float CompareValue);\r\n\tfloat4 SampleGrad(sampler" + - "_state S, float3 Location, float3 DDX, float3 DDY);\r\n\tfloat4 SampleLevel( sample" + - "r_state S, float3 Location, float LOD);\r\n};\r\n\r\nclass __TextureCubeArray {\r\n\t/" + - "/ SM 4.0\r\n\tfloat CalculateLevelOfDetail( sampler_state s, float3 x);\r\n\tvector<__" + - "T_base,4> Gather( sampler_state S, float4 Location);\r\n\tvoid GetDimensions( uint " + - "MipLevel, out uint Width, out uint Height, out uint Elements, out uint NumberOfL" + - "evels);\r\n\tvoid GetDimensions( out uint Width, out uint Height, out uint Elements" + - ");\r\n\tvoid GetDimensions( uint MipLevel, out float Width, out float Height, out f" + - "loat Elements, out float NumberOfLevels);\r\n\tvoid GetDimensions( out float Width," + - " out float Height, out float Elements);\r\n\tfloat4 Sample(sampler_state S, float4 " + - "Location);\r\n\tfloat4 SampleBias(sampler_state S, float4 Location, float Bias);\r\n\t" + - "float SampleCmp(sampler_state S, float4 Location, float CompareValue);\r\n\tfloat S" + - "ampleCmpLevelZero(sampler_state S, float4 Location, float CompareValue);\r\n\tfloat" + - "4 SampleGrad(sampler_state S, float4 Location, float3 DDX, float3 DDY);\r\n\tfloat4" + - " SampleLevel( sampler_state S, float4 Location, float LOD);\r\n};\r\n\r\nclass __Textu" + - "re2DMS {\r\n\t// SM 4.0\r\n\tvoid GetDimensions( out uint Width, out uint Height, o" + - "ut uint Samples);\r\n\tvoid GetDimensions( out float Width, out float Height, out f" + - "loat Samples);\r\n\tfloat2 GetSamplePosition(int s);\r\n\tT Load(int2 Location);\r\n\tT L" + - "oad(int2 Location, int2 Offset);\r\n\tT Load(int2 Location, int2 Offset, int Sample" + - "Index);\r\n\t\r\n\t\r\n\t// SM 5.0\r\n\tfloat2 GetSamplePosition(\r\n\t in int sampleindex\r\n\t" + - ");\t\r\n\t\r\n\tT Load(\r\n\t in int2 coord,\r\n\t in int sampleindex\r\n\t);\t\r\n\t\r\n\tT sample" + - ".operator[][]( in uint sampleSlice, in uint3 pos);\t\r\n};\r\n\r\nclass __Texture2DMS" + - "Array {\r\n\t// SM 4.0\r\n\tvoid GetDimensions( out uint Width, out uint Height, ou" + - "t uint Elements, out uint Samples);\r\n\tvoid GetDimensions( out float Width, out f" + - "loat Height, out float Elements, out float Samples);\r\n\tfloat2 GetSamplePosition(" + - "int s);\r\n\tT Load(int3 Location); \r\n\tT Load(int3 Location, int2 Offset); \r\n\tT Loa" + - "d(int3 Location, int2 Offset, int SampleIndex); \r\n\r\n\t// SM 5.0\r\n\tfloat2 GetSampl" + - "ePosition(\r\n\t in int sampleindex\r\n\t);\t\r\n\r\n\tT Load(\r\n\t in int3 coord,\r\n\t in " + - " int sampleindex\r\n\t);\t\r\n\r\n\tT sample.operator[][]( in uint sampleSlice, in uint" + - "3 pos);\r\n};\r\n\r\nclass __Buffer {\r\n\t// SM 4.0\r\n\tT Load(int Location);\r\n\r\n\tvoid " + - "GetDimensions(out uint dim);\t\r\n\t\r\n\tT operator[](in uint pos);\r\n};\r\n\r\n// Stream" + - "-Output Object (DirectX HLSL)\r\n// http://msdn.microsoft.com/en-us/library/bb5096" + - "61%28v=VS.85%29.aspx\r\n// StreamOutputObject Name\r\n// StreamOutputObject: P" + - "ointStream, LineStream, TriangleStream\r\nclass __PointStream {\r\n\tvoid Append(T" + - " StreamDataType);\r\n\tvoid RestartStrip();\r\n};\r\n\r\nclass __LineStream {\r\n\tvoid A" + - "ppend(T StreamDataType);\r\n\tvoid RestartStrip();\r\n};\r\n\r\nclass __TriangleStream" + - " {\r\n\tvoid Append(T StreamDataType);\r\n\tvoid RestartStrip();\r\n};\r\n\r\n// -----------" + - "----------------------------------------------------------------------------\r\n//" + - " Shader Model 5.0 \r\n// ---------------------------------------------------------" + - "------------------------------\r\n\r\n// AppendStructuredBuffer\r\n// http://msdn.m" + - "icrosoft.com/en-us/library/ff471448%28v=VS.85%29.aspx\r\nclass __AppendStructuredB" + - "uffer {\r\n\tvoid Append(T value);\r\n\tvoid GetDimensions(out uint numStructs, out" + - " uint stride);\r\n};\r\n\r\n// ByteAddressBuffer\r\n// http://msdn.microsoft.com/en-us/l" + - "ibrary/ff471453%28v=VS.85%29.aspx\r\nclass __ByteAddressBuffer {\r\n\tvoid GetDimensi" + - "ons(out uint dim);\r\n\tuint Load(in uint address);\r\n\tuint2 Load2(in uint addres" + - "s);\r\n\tuint3 Load3(in uint address);\r\n\tuint4 Load4(in uint address);\r\n};\r\n\r\n// " + - "ConsumeStructuredBuffer\r\n// http://msdn.microsoft.com/en-us/library/ff471459%" + - "28v=VS.85%29.aspx\r\nclass __ConsumeStructuredBuffer {\r\n\tT Consume(void);\r\n\tvoi" + - "d GetDimensions(out uint numStructs, out uint stride);\r\n};\r\n\r\n// InputPatch\r\n// http://msdn.microsoft.com/en-us/library/ff471462%28v=VS.85%29.aspx\r\nclass" + - " __InputPatch {\r\n\tuint Length;\r\n\tT operator[](in uint n);\r\n};\r\n\r\n// OutputP" + - "atch\r\n// http://msdn.microsoft.com/en-us/library/ff471464%28v=VS.85%29.aspx" + - "\r\nclass __OutputPatch {\r\n\tuint Length;\r\n\tT operator[](in uint n);\r\n};\r\n\r\n//" + - " RWBuffer\r\n// http://msdn.microsoft.com/en-us/library/ff471472%28v=VS.85%29.a" + - "spx\r\nclass __RWBuffer {\r\n\tvoid GetDimensions(out uint dim);\r\n\tT operator[](i" + - "n uint pos);\r\n};\r\n\r\n// RWByteAddressBuffer\r\n// http://msdn.microsoft.com/en-us/l" + - "ibrary/ff471475%28v=VS.85%29.aspx\r\nclass __RWByteAddressBuffer {\r\n\tvoid GetDimen" + - "sions(out uint dim);\r\n\tvoid InterlockedAdd(in uint dest, in uint value, out" + - " uint original_value);\r\n\tvoid InterlockedAnd(\r\n\t\tin uint dest,\r\n\t\tin uint v" + - "alue,\r\n\t\tout uint original_value\r\n\t);\r\n\tvoid InterlockedCompareExchange(\r\n\t\tin " + - " uint dest,\r\n\t\tin uint compare_value,\r\n\t\tin uint value,\r\n\t\tout uint origin" + - "al_value\r\n\t);\r\n\tvoid InterlockedCompareStore(\r\n\t in uint dest,\r\n\t in uint co" + - "mpare_value,\r\n\t in uint value\r\n\t);\r\n\tvoid InterlockedExchange(\r\n\t in uint d" + - "est,\r\n\t in uint value,\r\n\t out uint original_value\r\n\t);\r\n\tvoid InterlockedMa" + - "x(\r\n\t in uint dest,\r\n\t in uint value,\r\n\t out uint original_value\r\n\t);\t\r\n" + - "\tvoid InterlockedMin(\r\n\t in uint dest,\r\n\t in uint value,\r\n\t out uint ori" + - "ginal_value\r\n\t);\t\r\n\tvoid InterlockedOr(\r\n\t in uint dest,\r\n\t in uint value," + - "\r\n\t out uint original_value\r\n\t);\t\r\n\tvoid InterlockedXor(\r\n\t in uint dest,\r\n" + - "\t in uint value,\r\n\t out uint original_value\r\n\t);\t\r\n\tuint Load(\r\n\t in uint" + - " address\r\n\t);\t\r\n\tuint2 Load2(\r\n\t in uint address\r\n\t);\t\r\n\tuint3 Load3(\r\n\t in " + - "uint address\r\n\t);\t\r\n\tuint4 Load4(\r\n\t in uint address\r\n\t);\t\r\n\tvoid Store(\r\n\t i" + - "n uint address,\r\n\t in uint value\r\n\t);\t\r\n\tvoid Store2(\r\n\t in uint address,\r\n" + - "\t in uint2 values\r\n\t);\t\r\n\tvoid Store3(\r\n\t in uint address,\r\n\t in uint3 val" + - "ues\r\n\t);\t\r\n\tvoid Store4(\r\n\t in uint address,\r\n\t in uint4 values\r\n\t);\t\r\n};\r\n\r" + - "\n// RWStructuredBuffer\r\n// http://msdn.microsoft.com/en-us/library/ff471494%2" + - "8v=VS.85%29.aspx\r\nclass __RWStructuredBuffer {\r\n\r\n\tuint DecrementCounter(void" + - ");\r\n\r\n\tvoid GetDimensions(\r\n\t out uint numStructs,\r\n\t out uint stride\r\n\t);\r\n" + - "\r\n\tuint IncrementCounter(void);\r\n\r\n\tT operator[](in uint pos);\r\n};\r\n\r\n// RWTextu" + - "re1D\r\n// http://msdn.microsoft.com/en-us/library/ff471499%28v=VS.85%29.aspx\r\n" + - "class __RWTexture1D {\r\n\tvoid GetDimensions(\r\n\t out uint Width\r\n\t);\r\n\tT oper" + - "ator[](in uint pos);\r\n};\r\n\r\n// RWTexture1DArray\r\n// http://msdn.microsoft.co" + - "m/en-us/library/ff471500%28v=VS.85%29.aspx\r\nclass __RWTexture1DArray {\r\n\tvoid" + - " GetDimensions(\r\n\t out uint Width,\r\n\t out uint Elements\r\n\t);\r\n\r\n\tT operator[" + - "](in uint2 pos);\r\n};\r\n\r\n// RWTexture2D\r\n// http://msdn.microsoft.com/en-us/l" + - "ibrary/ff471505%28v=VS.85%29.aspx\r\nclass __RWTexture2D {\r\n\tvoid GetDimensions" + - "(\r\n\t out uint Width,\r\n\t out uint Height\r\n\t);\r\n\r\n T operator[](in uint2" + - " pos);\r\n};\r\n\r\n// RWTexture2DArray\r\n// http://msdn.microsoft.com/en-us/library" + - "/ff471506%28v=VS.85%29.aspx\r\nclass __RWTexture2DArray {\r\n\tvoid GetDimensions(" + - "\r\n\t out uint Width,\r\n\t out uint Height,\r\n\t out uint Elements\r\n\t);\r\n\tT oper" + - "ator[](in uint3 pos);\r\n};\r\n\r\n// RWTexture3D\r\n// http://msdn.microsoft.com/en" + - "-us/library/ff471511%28v=VS.85%29.aspx\r\nclass __RWTexture3D {\r\n\tvoid GetDimen" + - "sions(\r\n\t out uint Width,\r\n\t out uint Height,\r\n\t out uint Depth\r\n\t);\r\n\r\n\tT" + - " operator[](in uint3 pos);\r\n};\r\n\r\n// StructuredBuffer\r\n// http://msdn.micros" + - "oft.com/en-us/library/ff471514%28v=VS.85%29.aspx\r\nclass __StructuredBuffer {\r" + - "\n\tvoid GetDimensions(\r\n\t out uint numStructs,\r\n\t out uint stride\r\n\t);\r\n\r\n\tT " + - "operator[](in uint pos);\t\r\n};"; - } - } - - public static System.Byte[] Keywords - { - get { - return new byte [] { - 239, 187, 191, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 47, 47, 32, 76, 105, 115, 116, 32, 111, 102, 32, 71, 76, 83, 76, 32, 107, 101, 121, - 119, 111, 114, 100, 115, 13, 10, 47, 47, 32, 65, 99, 99, 111, 114, 100, 105, 110, 103, 32, 116, 111, 32, 116, 104, 101, 32, 115, 112, 101, 99, 32, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 111, 112, 101, 110, 103, 108, 46, - 111, 114, 103, 47, 114, 101, 103, 105, 115, 116, 114, 121, 47, 100, 111, 99, 47, 71, 76, 83, 76, 97, 110, 103, 83, 112, 101, 99, 46, 52, 46, 50, 48, 46, 54, 46, 99, 108, 101, 97, 110, 46, 112, 100, 102, 13, 10, 47, 47, 32, - 83, 101, 99, 116, 105, 111, 110, 32, 34, 51, 46, 54, 32, 75, 101, 121, 119, 111, 114, 100, 115, 34, 44, 32, 112, 49, 54, 45, 49, 56, 13, 10, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 47, 47, 32, 84, 104, 101, 32, 102, 111, 108, 108, 111, 119, 105, 110, 103, 32, 97, 114, 101, 32, 116, 104, 101, 32, 107, 101, 121, 119, 111, 114, 100, 115, 32, 105, 110, 32, 116, 104, 101, - 32, 108, 97, 110, 103, 117, 97, 103, 101, 44, 32, 97, 110, 100, 32, 99, 97, 110, 110, 111, 116, 32, 98, 101, 32, 117, 115, 101, 100, 32, 102, 111, 114, 32, 97, 110, 121, 32, 111, 116, 104, 101, 114, 32, 112, 117, 114, 112, 111, 115, - 101, 32, 116, 104, 97, 110, 32, 116, 104, 97, 116, 32, 100, 101, 102, 105, 110, 101, 100, 32, 98, 121, 32, 116, 104, 105, 115, 32, 100, 111, 99, 117, 109, 101, 110, 116, 58, 13, 10, 13, 10, 97, 116, 116, 114, 105, 98, 117, 116, 101, - 32, 99, 111, 110, 115, 116, 32, 117, 110, 105, 102, 111, 114, 109, 32, 118, 97, 114, 121, 105, 110, 103, 13, 10, 99, 111, 104, 101, 114, 101, 110, 116, 32, 118, 111, 108, 97, 116, 105, 108, 101, 32, 114, 101, 115, 116, 114, 105, 99, 116, - 32, 114, 101, 97, 100, 111, 110, 108, 121, 32, 119, 114, 105, 116, 101, 111, 110, 108, 121, 13, 10, 97, 116, 111, 109, 105, 99, 95, 117, 105, 110, 116, 13, 10, 108, 97, 121, 111, 117, 116, 13, 10, 99, 101, 110, 116, 114, 111, 105, 100, - 32, 102, 108, 97, 116, 32, 115, 109, 111, 111, 116, 104, 32, 110, 111, 112, 101, 114, 115, 112, 101, 99, 116, 105, 118, 101, 13, 10, 112, 97, 116, 99, 104, 32, 115, 97, 109, 112, 108, 101, 13, 10, 98, 114, 101, 97, 107, 32, 99, 111, - 110, 116, 105, 110, 117, 101, 32, 100, 111, 32, 102, 111, 114, 32, 119, 104, 105, 108, 101, 32, 115, 119, 105, 116, 99, 104, 32, 99, 97, 115, 101, 32, 100, 101, 102, 97, 117, 108, 116, 13, 10, 105, 102, 32, 101, 108, 115, 101, 13, 10, - 115, 117, 98, 114, 111, 117, 116, 105, 110, 101, 13, 10, 105, 110, 32, 111, 117, 116, 32, 105, 110, 111, 117, 116, 13, 10, 102, 108, 111, 97, 116, 32, 100, 111, 117, 98, 108, 101, 32, 105, 110, 116, 32, 118, 111, 105, 100, 32, 98, 111, - 111, 108, 32, 116, 114, 117, 101, 32, 102, 97, 108, 115, 101, 13, 10, 105, 110, 118, 97, 114, 105, 97, 110, 116, 13, 10, 100, 105, 115, 99, 97, 114, 100, 32, 114, 101, 116, 117, 114, 110, 13, 10, 109, 97, 116, 50, 32, 109, 97, 116, - 51, 32, 109, 97, 116, 52, 32, 100, 109, 97, 116, 50, 32, 100, 109, 97, 116, 51, 32, 100, 109, 97, 116, 52, 13, 10, 109, 97, 116, 50, 120, 50, 32, 109, 97, 116, 50, 120, 51, 32, 109, 97, 116, 50, 120, 52, 32, 100, 109, 97, - 116, 50, 120, 50, 32, 100, 109, 97, 116, 50, 120, 51, 32, 100, 109, 97, 116, 50, 120, 52, 13, 10, 109, 97, 116, 51, 120, 50, 32, 109, 97, 116, 51, 120, 51, 32, 109, 97, 116, 51, 120, 52, 32, 100, 109, 97, 116, 51, 120, 50, - 32, 100, 109, 97, 116, 51, 120, 51, 32, 100, 109, 97, 116, 51, 120, 52, 13, 10, 109, 97, 116, 52, 120, 50, 32, 109, 97, 116, 52, 120, 51, 32, 109, 97, 116, 52, 120, 52, 32, 100, 109, 97, 116, 52, 120, 50, 32, 100, 109, 97, - 116, 52, 120, 51, 32, 100, 109, 97, 116, 52, 120, 52, 13, 10, 118, 101, 99, 50, 32, 118, 101, 99, 51, 32, 118, 101, 99, 52, 32, 105, 118, 101, 99, 50, 32, 105, 118, 101, 99, 51, 32, 105, 118, 101, 99, 52, 32, 98, 118, 101, - 99, 50, 32, 98, 118, 101, 99, 51, 32, 98, 118, 101, 99, 52, 32, 100, 118, 101, 99, 50, 32, 100, 118, 101, 99, 51, 32, 100, 118, 101, 99, 52, 13, 10, 117, 105, 110, 116, 32, 117, 118, 101, 99, 50, 32, 117, 118, 101, 99, 51, - 32, 117, 118, 101, 99, 52, 13, 10, 108, 111, 119, 112, 32, 109, 101, 100, 105, 117, 109, 112, 32, 104, 105, 103, 104, 112, 32, 112, 114, 101, 99, 105, 115, 105, 111, 110, 13, 10, 115, 97, 109, 112, 108, 101, 114, 49, 68, 32, 115, 97, - 109, 112, 108, 101, 114, 50, 68, 32, 115, 97, 109, 112, 108, 101, 114, 51, 68, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 13, 10, 115, 97, 109, 112, 108, 101, 114, 49, 68, 83, 104, 97, 100, 111, 119, 32, 115, 97, 109, - 112, 108, 101, 114, 50, 68, 83, 104, 97, 100, 111, 119, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 83, 104, 97, 100, 111, 119, 13, 10, 115, 97, 109, 112, 108, 101, 114, 49, 68, 65, 114, 114, 97, 121, 32, 115, 97, 109, - 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 13, 10, 115, 97, 109, 112, 108, 101, 114, 49, 68, 65, 114, 114, 97, 121, 83, 104, 97, 100, 111, 119, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 83, 104, - 97, 100, 111, 119, 13, 10, 105, 115, 97, 109, 112, 108, 101, 114, 49, 68, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 32, 105, 115, 97, 109, 112, 108, 101, 114, 51, 68, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, - 101, 13, 10, 105, 115, 97, 109, 112, 108, 101, 114, 49, 68, 65, 114, 114, 97, 121, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 13, 10, 117, 115, 97, 109, 112, 108, 101, 114, 49, 68, 32, 117, 115, 97, - 109, 112, 108, 101, 114, 50, 68, 32, 117, 115, 97, 109, 112, 108, 101, 114, 51, 68, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 13, 10, 117, 115, 97, 109, 112, 108, 101, 114, 49, 68, 65, 114, 114, 97, 121, 32, 117, - 115, 97, 109, 112, 108, 101, 114, 50, 68, 65, 114, 114, 97, 121, 13, 10, 115, 97, 109, 112, 108, 101, 114, 50, 68, 82, 101, 99, 116, 32, 115, 97, 109, 112, 108, 101, 114, 50, 68, 82, 101, 99, 116, 83, 104, 97, 100, 111, 119, 32, - 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 82, 101, 99, 116, 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 82, 101, 99, 116, 13, 10, 115, 97, 109, 112, 108, 101, 114, 66, 117, 102, 102, 101, 114, 32, 105, 115, 97, 109, 112, - 108, 101, 114, 66, 117, 102, 102, 101, 114, 32, 117, 115, 97, 109, 112, 108, 101, 114, 66, 117, 102, 102, 101, 114, 13, 10, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, - 32, 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, 13, 10, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, 65, 114, 114, 97, 121, 32, 105, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, 65, 114, 114, 97, 121, 32, - 117, 115, 97, 109, 112, 108, 101, 114, 50, 68, 77, 83, 65, 114, 114, 97, 121, 13, 10, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 65, 114, 114, 97, 121, 32, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 65, 114, 114, - 97, 121, 83, 104, 97, 100, 111, 119, 32, 105, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 65, 114, 114, 97, 121, 32, 117, 115, 97, 109, 112, 108, 101, 114, 67, 117, 98, 101, 65, 114, 114, 97, 121, 13, 10, 105, 109, 97, 103, - 101, 49, 68, 32, 105, 105, 109, 97, 103, 101, 49, 68, 32, 117, 105, 109, 97, 103, 101, 49, 68, 13, 10, 105, 109, 97, 103, 101, 50, 68, 32, 105, 105, 109, 97, 103, 101, 50, 68, 32, 117, 105, 109, 97, 103, 101, 50, 68, 13, 10, - 105, 109, 97, 103, 101, 51, 68, 32, 105, 105, 109, 97, 103, 101, 51, 68, 32, 117, 105, 109, 97, 103, 101, 51, 68, 13, 10, 105, 109, 97, 103, 101, 50, 68, 82, 101, 99, 116, 32, 105, 105, 109, 97, 103, 101, 50, 68, 82, 101, 99, - 116, 32, 117, 105, 109, 97, 103, 101, 50, 68, 82, 101, 99, 116, 13, 10, 105, 109, 97, 103, 101, 67, 117, 98, 101, 32, 105, 105, 109, 97, 103, 101, 67, 117, 98, 101, 32, 117, 105, 109, 97, 103, 101, 67, 117, 98, 101, 13, 10, 105, - 109, 97, 103, 101, 66, 117, 102, 102, 101, 114, 32, 105, 105, 109, 97, 103, 101, 66, 117, 102, 102, 101, 114, 32, 117, 105, 109, 97, 103, 101, 66, 117, 102, 102, 101, 114, 13, 10, 105, 109, 97, 103, 101, 49, 68, 65, 114, 114, 97, 121, - 32, 105, 105, 109, 97, 103, 101, 49, 68, 65, 114, 114, 97, 121, 32, 117, 105, 109, 97, 103, 101, 49, 68, 65, 114, 114, 97, 121, 13, 10, 105, 109, 97, 103, 101, 50, 68, 65, 114, 114, 97, 121, 32, 105, 105, 109, 97, 103, 101, 50, - 68, 65, 114, 114, 97, 121, 32, 117, 105, 109, 97, 103, 101, 50, 68, 65, 114, 114, 97, 121, 13, 10, 105, 109, 97, 103, 101, 67, 117, 98, 101, 65, 114, 114, 97, 121, 32, 105, 105, 109, 97, 103, 101, 67, 117, 98, 101, 65, 114, 114, - 97, 121, 32, 117, 105, 109, 97, 103, 101, 67, 117, 98, 101, 65, 114, 114, 97, 121, 13, 10, 105, 109, 97, 103, 101, 50, 68, 77, 83, 32, 105, 105, 109, 97, 103, 101, 50, 68, 77, 83, 32, 117, 105, 109, 97, 103, 101, 50, 68, 77, - 83, 13, 10, 105, 109, 97, 103, 101, 50, 68, 77, 83, 65, 114, 114, 97, 121, 32, 105, 105, 109, 97, 103, 101, 50, 68, 77, 83, 65, 114, 114, 97, 121, 32, 117, 105, 109, 97, 103, 101, 50, 68, 77, 83, 65, 114, 114, 97, 121, 13, - 10, 115, 116, 114, 117, 99, 116, 13, 10, 13, 10, 47, 47, 32, 84, 104, 101, 32, 102, 111, 108, 108, 111, 119, 105, 110, 103, 32, 97, 114, 101, 32, 116, 104, 101, 32, 107, 101, 121, 119, 111, 114, 100, 115, 32, 114, 101, 115, 101, 114, - 118, 101, 100, 32, 102, 111, 114, 32, 102, 117, 116, 117, 114, 101, 32, 117, 115, 101, 46, 32, 85, 115, 105, 110, 103, 32, 116, 104, 101, 109, 32, 119, 105, 108, 108, 32, 114, 101, 115, 117, 108, 116, 32, 105, 110, 32, 97, 110, 32, 101, - 114, 114, 111, 114, 58, 13, 10, 99, 111, 109, 109, 111, 110, 32, 112, 97, 114, 116, 105, 116, 105, 111, 110, 32, 97, 99, 116, 105, 118, 101, 13, 10, 97, 115, 109, 13, 10, 99, 108, 97, 115, 115, 32, 117, 110, 105, 111, 110, 32, 101, - 110, 117, 109, 32, 116, 121, 112, 101, 100, 101, 102, 32, 116, 101, 109, 112, 108, 97, 116, 101, 32, 116, 104, 105, 115, 32, 112, 97, 99, 107, 101, 100, 13, 10, 114, 101, 115, 111, 117, 114, 99, 101, 13, 10, 103, 111, 116, 111, 13, 10, - 105, 110, 108, 105, 110, 101, 32, 110, 111, 105, 110, 108, 105, 110, 101, 32, 112, 117, 98, 108, 105, 99, 32, 115, 116, 97, 116, 105, 99, 32, 101, 120, 116, 101, 114, 110, 32, 101, 120, 116, 101, 114, 110, 97, 108, 32, 105, 110, 116, 101, - 114, 102, 97, 99, 101, 13, 10, 108, 111, 110, 103, 32, 115, 104, 111, 114, 116, 32, 104, 97, 108, 102, 32, 102, 105, 120, 101, 100, 32, 117, 110, 115, 105, 103, 110, 101, 100, 32, 115, 117, 112, 101, 114, 112, 13, 10, 105, 110, 112, 117, - 116, 32, 111, 117, 116, 112, 117, 116, 13, 10, 104, 118, 101, 99, 50, 32, 104, 118, 101, 99, 51, 32, 104, 118, 101, 99, 52, 32, 102, 118, 101, 99, 50, 32, 102, 118, 101, 99, 51, 32, 102, 118, 101, 99, 52, 13, 10, 115, 97, 109, - 112, 108, 101, 114, 51, 68, 82, 101, 99, 116, 13, 10, 102, 105, 108, 116, 101, 114, 13, 10, 115, 105, 122, 101, 111, 102, 32, 99, 97, 115, 116, 13, 10, 110, 97, 109, 101, 115, 112, 97, 99, 101, 32, 117, 115, 105, 110, 103, 13, 10, - 114, 111, 119, 95, 109, 97, 106, 111, 114, 13, 10, 13, 10, 47, 47, 73, 110, 32, 97, 100, 100, 105, 116, 105, 111, 110, 44, 32, 97, 108, 108, 32, 105, 100, 101, 110, 116, 105, 102, 105, 101, 114, 115, 32, 99, 111, 110, 116, 97, 105, - 110, 105, 110, 103, 32, 116, 119, 111, 32, 99, 111, 110, 115, 101, 99, 117, 116, 105, 118, 101, 32, 117, 110, 100, 101, 114, 115, 99, 111, 114, 101, 115, 32, 40, 95, 95, 41, 32, 97, 114, 101, 32, 114, 101, 115, 101, 114, 118, 101, 100, - 32, 97, 115, 32, 112, 111, 115, 115, 105, 98, 108, 101, 32, 102, 117, 116, 117, 114, 101, 32, 107, 101, 121, 119, 111, 114, 100, 115, 46 - }; - } - } - - public static System.Byte[] Tokenizer - { - get { - return new byte [] { - 71, 0, 79, 0, 76, 0, 68, 0, 32, 0, 80, 0, 97, 0, 114, 0, 115, 0, 101, 0, 114, 0, 32, 0, 84, 0, 97, 0, 98, 0, 108, 0, 101, 0, 115, 0, 47, 0, 118, 0, 49, 0, 46, 0, 48, 0, 0, 0, 77, 7, - 0, 98, 80, 83, 40, 0, 85, 0, 110, 0, 116, 0, 105, 0, 116, 0, 108, 0, 101, 0, 100, 0, 41, 0, 0, 0, 83, 40, 0, 78, 0, 111, 0, 116, 0, 32, 0, 83, 0, 112, 0, 101, 0, 99, 0, 105, 0, 102, 0, 105, - 0, 101, 0, 100, 0, 41, 0, 0, 0, 83, 40, 0, 85, 0, 110, 0, 107, 0, 110, 0, 111, 0, 119, 0, 110, 0, 41, 0, 0, 0, 83, 0, 0, 66, 0, 73, 70, 0, 77, 6, 0, 98, 84, 73, 71, 0, 73, 52, 0, 73, - 65, 0, 73, 104, 0, 73, 67, 0, 77, 3, 0, 98, 73, 73, 0, 0, 73, 0, 0, 77, 3, 0, 98, 67, 73, 0, 0, 83, 9, 0, 11, 0, 12, 0, 32, 0, 160, 0, 0, 0, 77, 3, 0, 98, 67, 73, 1, 0, 83, 64, - 0, 0, 0, 77, 3, 0, 98, 67, 73, 2, 0, 83, 126, 0, 0, 0, 77, 3, 0, 98, 67, 73, 3, 0, 83, 44, 0, 0, 0, 77, 3, 0, 98, 67, 73, 4, 0, 83, 36, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, - 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 88, 0, 89, 0, 90, 0, 95, 0, 97, 0, 98, 0, 99, 0, 100, 0, - 101, 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 120, 0, 121, 0, 122, 0, 0, 0, 77, 3, 0, 98, 67, 73, - 5, 0, 83, 91, 0, 0, 0, 77, 3, 0, 98, 67, 73, 6, 0, 83, 123, 0, 0, 0, 77, 3, 0, 98, 67, 73, 7, 0, 83, 40, 0, 0, 0, 77, 3, 0, 98, 67, 73, 8, 0, 83, 92, 0, 0, 0, 77, 3, 0, 98, - 67, 73, 9, 0, 83, 10, 0, 0, 0, 77, 3, 0, 98, 67, 73, 10, 0, 83, 63, 0, 0, 0, 77, 3, 0, 98, 67, 73, 11, 0, 83, 93, 0, 0, 0, 77, 3, 0, 98, 67, 73, 12, 0, 83, 125, 0, 0, 0, 77, 3, - 0, 98, 67, 73, 13, 0, 83, 41, 0, 0, 0, 77, 3, 0, 98, 67, 73, 14, 0, 83, 59, 0, 0, 0, 77, 3, 0, 98, 67, 73, 15, 0, 83, 34, 0, 0, 0, 77, 3, 0, 98, 67, 73, 16, 0, 83, 13, 0, 0, 0, - 77, 3, 0, 98, 67, 73, 17, 0, 83, 33, 0, 0, 0, 77, 3, 0, 98, 67, 73, 18, 0, 83, 35, 0, 0, 0, 77, 3, 0, 98, 67, 73, 19, 0, 83, 37, 0, 0, 0, 77, 3, 0, 98, 67, 73, 20, 0, 83, 38, 0, - 0, 0, 77, 3, 0, 98, 67, 73, 21, 0, 83, 39, 0, 0, 0, 77, 3, 0, 98, 67, 73, 22, 0, 83, 42, 0, 0, 0, 77, 3, 0, 98, 67, 73, 23, 0, 83, 43, 0, 0, 0, 77, 3, 0, 98, 67, 73, 24, 0, 83, - 45, 0, 0, 0, 77, 3, 0, 98, 67, 73, 25, 0, 83, 46, 0, 0, 0, 77, 3, 0, 98, 67, 73, 26, 0, 83, 47, 0, 0, 0, 77, 3, 0, 98, 67, 73, 27, 0, 83, 48, 0, 0, 0, 77, 3, 0, 98, 67, 73, 28, - 0, 83, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 0, 0, 77, 3, 0, 98, 67, 73, 29, 0, 83, 58, 0, 0, 0, 77, 3, 0, 98, 67, 73, 30, 0, 83, 60, 0, 0, 0, 77, 3, - 0, 98, 67, 73, 31, 0, 83, 61, 0, 0, 0, 77, 3, 0, 98, 67, 73, 32, 0, 83, 62, 0, 0, 0, 77, 3, 0, 98, 67, 73, 33, 0, 83, 87, 0, 119, 0, 0, 0, 77, 3, 0, 98, 67, 73, 34, 0, 83, 94, 0, - 0, 0, 77, 3, 0, 98, 67, 73, 35, 0, 83, 124, 0, 0, 0, 77, 3, 0, 98, 67, 73, 36, 0, 83, 36, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 65, 0, 66, 0, - 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0, 95, 0, - 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, 0, 121, 0, - 122, 0, 0, 0, 77, 3, 0, 98, 67, 73, 37, 0, 83, 32, 0, 33, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48, 0, 49, 0, 50, 0, 51, - 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, 76, - 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0, 91, 0, 92, 0, 93, 0, 94, 0, 95, 0, 96, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, - 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, 0, 121, 0, 122, 0, 123, 0, 124, 0, 125, 0, 126, - 0, 160, 0, 0, 0, 77, 3, 0, 98, 67, 73, 38, 0, 83, 32, 0, 33, 0, 35, 0, 36, 0, 37, 0, 38, 0, 39, 0, 40, 0, 41, 0, 42, 0, 43, 0, 44, 0, 45, 0, 46, 0, 47, 0, 48, 0, 49, 0, 50, 0, - 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 64, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, - 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 83, 0, 84, 0, 85, 0, 86, 0, 87, 0, 88, 0, 89, 0, 90, 0, 91, 0, 93, 0, 94, 0, 95, 0, 96, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, - 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 115, 0, 116, 0, 117, 0, 118, 0, 119, 0, 120, 0, 121, 0, 122, 0, 123, 0, 124, 0, 125, 0, 126, 0, - 160, 0, 0, 0, 77, 3, 0, 98, 67, 73, 39, 0, 83, 85, 0, 88, 0, 117, 0, 120, 0, 0, 0, 77, 3, 0, 98, 67, 73, 40, 0, 83, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 0, 0, - 77, 3, 0, 98, 67, 73, 41, 0, 83, 34, 0, 39, 0, 65, 0, 66, 0, 70, 0, 78, 0, 82, 0, 84, 0, 92, 0, 97, 0, 98, 0, 102, 0, 110, 0, 114, 0, 116, 0, 0, 0, 77, 3, 0, 98, 67, 73, 42, 0, 83, - 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 0, 0, 77, 3, 0, 98, - 67, 73, 43, 0, 83, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, 55, 0, 56, 0, 57, 0, 0, 0, 77, 3, 0, 98, 67, 73, 44, 0, 83, 68, 0, 70, 0, 72, 0, 100, 0, 102, 0, 104, 0, 0, 0, - 77, 3, 0, 98, 67, 73, 45, 0, 83, 69, 0, 101, 0, 0, 0, 77, 3, 0, 98, 67, 73, 46, 0, 83, 43, 0, 45, 0, 0, 0, 77, 3, 0, 98, 67, 73, 47, 0, 83, 76, 0, 108, 0, 0, 0, 77, 3, 0, 98, 67, - 73, 48, 0, 83, 56, 0, 57, 0, 0, 0, 77, 3, 0, 98, 67, 73, 49, 0, 83, 88, 0, 120, 0, 0, 0, 77, 3, 0, 98, 67, 73, 50, 0, 83, 36, 0, 48, 0, 49, 0, 50, 0, 51, 0, 52, 0, 53, 0, 54, 0, - 55, 0, 56, 0, 57, 0, 65, 0, 66, 0, 67, 0, 68, 0, 69, 0, 70, 0, 71, 0, 72, 0, 73, 0, 74, 0, 75, 0, 76, 0, 77, 0, 78, 0, 79, 0, 80, 0, 81, 0, 82, 0, 84, 0, 85, 0, 86, 0, 87, 0, - 88, 0, 89, 0, 90, 0, 95, 0, 97, 0, 98, 0, 99, 0, 100, 0, 101, 0, 102, 0, 103, 0, 104, 0, 105, 0, 106, 0, 107, 0, 108, 0, 109, 0, 110, 0, 111, 0, 112, 0, 113, 0, 114, 0, 116, 0, 117, 0, 118, 0, - 119, 0, 120, 0, 121, 0, 122, 0, 0, 0, 77, 3, 0, 98, 67, 73, 51, 0, 83, 83, 0, 115, 0, 0, 0, 77, 4, 0, 98, 83, 73, 0, 0, 83, 69, 0, 79, 0, 70, 0, 0, 0, 73, 3, 0, 77, 4, 0, 98, 83, - 73, 1, 0, 83, 69, 0, 114, 0, 114, 0, 111, 0, 114, 0, 0, 0, 73, 7, 0, 77, 4, 0, 98, 83, 73, 2, 0, 83, 87, 0, 104, 0, 105, 0, 116, 0, 101, 0, 115, 0, 112, 0, 97, 0, 99, 0, 101, 0, 0, 0, - 73, 2, 0, 77, 4, 0, 98, 83, 73, 3, 0, 83, 67, 0, 111, 0, 109, 0, 109, 0, 101, 0, 110, 0, 116, 0, 32, 0, 69, 0, 110, 0, 100, 0, 0, 0, 73, 5, 0, 77, 4, 0, 98, 83, 73, 4, 0, 83, 67, 0, - 111, 0, 109, 0, 109, 0, 101, 0, 110, 0, 116, 0, 32, 0, 76, 0, 105, 0, 110, 0, 101, 0, 0, 0, 73, 6, 0, 77, 4, 0, 98, 83, 73, 5, 0, 83, 67, 0, 111, 0, 109, 0, 109, 0, 101, 0, 110, 0, 116, 0, - 32, 0, 83, 0, 116, 0, 97, 0, 114, 0, 116, 0, 0, 0, 73, 4, 0, 77, 4, 0, 98, 83, 73, 6, 0, 83, 65, 0, 100, 0, 100, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 7, 0, 83, 65, 0, 110, 0, 100, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 8, 0, 83, 65, 0, 114, 0, 114, 0, 111, 0, 98, 0, 97, 0, 115, 0, 0, 0, 73, 1, 0, 77, 4, 0, - 98, 83, 73, 9, 0, 83, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 10, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 65, 0, 110, 0, - 100, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 11, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 65, 0, 110, 0, 100, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, - 73, 1, 0, 77, 4, 0, 98, 83, 73, 12, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 78, 0, 111, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 13, 0, 83, 66, 0, 105, 0, - 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 79, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 14, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 79, 0, 114, 0, 65, 0, 115, 0, - 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 15, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 83, 0, 104, 0, 105, 0, 102, 0, 116, 0, 76, 0, 101, 0, - 102, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 16, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 83, 0, 104, 0, 105, 0, 102, 0, 116, 0, 76, 0, 101, 0, 102, 0, 116, 0, - 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 17, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 83, 0, 104, 0, 105, 0, 102, 0, 116, 0, - 82, 0, 105, 0, 103, 0, 104, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 18, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 83, 0, 104, 0, 105, 0, 102, 0, 116, 0, 82, 0, - 105, 0, 103, 0, 104, 0, 116, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 19, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 88, 0, - 111, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 20, 0, 83, 66, 0, 105, 0, 116, 0, 119, 0, 105, 0, 115, 0, 101, 0, 88, 0, 111, 0, 114, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, - 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 21, 0, 83, 67, 0, 111, 0, 108, 0, 111, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 22, 0, 83, 67, 0, 111, 0, 109, 0, 109, 0, 97, 0, 0, 0, - 73, 1, 0, 77, 4, 0, 98, 83, 73, 23, 0, 83, 68, 0, 105, 0, 118, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 24, 0, 83, 68, 0, 105, 0, 118, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, - 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 25, 0, 83, 68, 0, 111, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 26, 0, 83, 69, 0, 113, 0, 117, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 27, 0, 83, 70, 0, 108, 0, 111, 0, 97, 0, 116, 0, 105, 0, 110, 0, 103, 0, 80, 0, 111, 0, 105, 0, 110, 0, 116, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, - 73, 1, 0, 77, 4, 0, 98, 83, 73, 28, 0, 83, 70, 0, 108, 0, 111, 0, 97, 0, 116, 0, 105, 0, 110, 0, 103, 0, 80, 0, 111, 0, 105, 0, 110, 0, 116, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, - 108, 0, 69, 0, 120, 0, 112, 0, 111, 0, 110, 0, 101, 0, 110, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 29, 0, 83, 71, 0, 114, 0, 101, 0, 97, 0, 116, 0, 101, 0, 114, 0, 84, 0, 104, 0, - 97, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 30, 0, 83, 71, 0, 114, 0, 101, 0, 97, 0, 116, 0, 101, 0, 114, 0, 84, 0, 104, 0, 97, 0, 110, 0, 79, 0, 114, 0, 69, 0, 113, 0, 117, 0, - 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 31, 0, 83, 72, 0, 101, 0, 120, 0, 69, 0, 115, 0, 99, 0, 97, 0, 112, 0, 101, 0, 67, 0, 104, 0, 97, 0, 114, 0, 76, 0, 105, 0, 116, 0, - 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 32, 0, 83, 72, 0, 101, 0, 120, 0, 73, 0, 110, 0, 116, 0, 101, 0, 103, 0, 101, 0, 114, 0, 76, 0, 105, 0, 116, 0, 101, 0, - 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 33, 0, 83, 73, 0, 100, 0, 101, 0, 110, 0, 116, 0, 105, 0, 102, 0, 105, 0, 101, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, - 73, 34, 0, 83, 73, 0, 100, 0, 101, 0, 110, 0, 116, 0, 105, 0, 102, 0, 105, 0, 101, 0, 114, 0, 83, 0, 101, 0, 112, 0, 97, 0, 114, 0, 97, 0, 116, 0, 111, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, - 98, 83, 73, 35, 0, 83, 73, 0, 110, 0, 100, 0, 105, 0, 114, 0, 101, 0, 99, 0, 116, 0, 67, 0, 104, 0, 97, 0, 114, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 36, 0, 83, 76, 0, 101, 0, 102, 0, 116, 0, 66, 0, 114, 0, 97, 0, 99, 0, 107, 0, 101, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 37, 0, 83, 76, 0, 101, 0, 102, 0, - 116, 0, 67, 0, 117, 0, 114, 0, 108, 0, 121, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 38, 0, 83, 76, 0, 101, 0, 102, 0, 116, 0, 80, 0, 97, 0, 114, 0, 101, 0, 110, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 39, 0, 83, 76, 0, 101, 0, 115, 0, 115, 0, 84, 0, 104, 0, 97, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 40, 0, 83, 76, 0, 101, 0, 115, 0, 115, 0, 84, 0, 104, 0, - 97, 0, 110, 0, 79, 0, 114, 0, 69, 0, 113, 0, 117, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 41, 0, 83, 76, 0, 105, 0, 110, 0, 101, 0, 67, 0, 111, 0, 110, 0, 116, 0, 105, 0, - 110, 0, 117, 0, 97, 0, 116, 0, 105, 0, 111, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 42, 0, 83, 77, 0, 105, 0, 110, 0, 117, 0, 115, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 43, - 0, 83, 77, 0, 105, 0, 110, 0, 117, 0, 115, 0, 77, 0, 105, 0, 110, 0, 117, 0, 115, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 44, 0, 83, 77, 0, 111, 0, 100, 0, 0, 0, 73, 1, 0, 77, 4, 0, - 98, 83, 73, 45, 0, 83, 77, 0, 111, 0, 100, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 46, 0, 83, 77, 0, 117, 0, 108, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 47, 0, 83, 77, 0, 117, 0, 108, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 48, 0, 83, 78, 0, 101, 0, 119, 0, 76, 0, 105, 0, - 110, 0, 101, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 49, 0, 83, 78, 0, 111, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 50, 0, 83, 78, 0, 111, 0, 116, 0, 69, 0, 113, 0, 117, 0, - 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 51, 0, 83, 79, 0, 99, 0, 116, 0, 97, 0, 108, 0, 69, 0, 115, 0, 99, 0, 97, 0, 112, 0, 101, 0, 67, 0, 104, 0, 97, 0, 114, 0, 76, 0, - 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 52, 0, 83, 79, 0, 99, 0, 116, 0, 97, 0, 108, 0, 73, 0, 110, 0, 116, 0, 101, 0, 103, 0, 101, 0, 114, 0, - 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 53, 0, 83, 79, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 54, 0, 83, 80, 0, 108, 0, - 117, 0, 115, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 55, 0, 83, 80, 0, 108, 0, 117, 0, 115, 0, 80, 0, 108, 0, 117, 0, 115, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 56, 0, 83, 80, 0, - 114, 0, 101, 0, 112, 0, 114, 0, 111, 0, 99, 0, 101, 0, 115, 0, 115, 0, 111, 0, 114, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 57, 0, 83, 81, 0, 117, 0, 101, 0, 115, 0, 116, 0, 105, 0, 111, 0, - 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 58, 0, 83, 82, 0, 105, 0, 103, 0, 104, 0, 116, 0, 66, 0, 114, 0, 97, 0, 99, 0, 107, 0, 101, 0, 116, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, - 73, 59, 0, 83, 82, 0, 105, 0, 103, 0, 104, 0, 116, 0, 67, 0, 117, 0, 114, 0, 108, 0, 121, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 60, 0, 83, 82, 0, 105, 0, 103, 0, 104, 0, 116, 0, 80, 0, - 97, 0, 114, 0, 101, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 61, 0, 83, 83, 0, 101, 0, 109, 0, 105, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 62, 0, 83, 83, 0, 116, 0, 97, 0, - 110, 0, 100, 0, 97, 0, 114, 0, 100, 0, 69, 0, 115, 0, 99, 0, 97, 0, 112, 0, 101, 0, 67, 0, 104, 0, 97, 0, 114, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, - 4, 0, 98, 83, 73, 63, 0, 83, 83, 0, 116, 0, 97, 0, 114, 0, 116, 0, 87, 0, 105, 0, 116, 0, 104, 0, 78, 0, 111, 0, 90, 0, 101, 0, 114, 0, 111, 0, 68, 0, 101, 0, 99, 0, 105, 0, 109, 0, 97, 0, - 108, 0, 73, 0, 110, 0, 116, 0, 101, 0, 103, 0, 101, 0, 114, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 64, 0, 83, 83, 0, 116, 0, 97, 0, - 114, 0, 116, 0, 87, 0, 105, 0, 116, 0, 104, 0, 90, 0, 101, 0, 114, 0, 111, 0, 68, 0, 101, 0, 99, 0, 105, 0, 109, 0, 97, 0, 108, 0, 73, 0, 110, 0, 116, 0, 101, 0, 103, 0, 101, 0, 114, 0, 76, 0, - 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 65, 0, 83, 83, 0, 116, 0, 114, 0, 105, 0, 110, 0, 103, 0, 76, 0, 105, 0, 116, 0, 101, 0, 114, 0, 97, 0, - 108, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 66, 0, 83, 83, 0, 117, 0, 98, 0, 65, 0, 115, 0, 115, 0, 105, 0, 103, 0, 110, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 67, 0, 83, 84, 0, - 111, 0, 107, 0, 101, 0, 110, 0, 80, 0, 97, 0, 115, 0, 116, 0, 105, 0, 110, 0, 103, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, 73, 68, 0, 83, 87, 0, 83, 0, 0, 0, 73, 1, 0, 77, 4, 0, 98, 83, - 73, 69, 0, 83, 86, 0, 97, 0, 108, 0, 117, 0, 101, 0, 0, 0, 73, 0, 0, 77, 4, 0, 98, 83, 73, 70, 0, 83, 86, 0, 97, 0, 108, 0, 117, 0, 101, 0, 115, 0, 0, 0, 73, 0, 0, 77, 5, 0, 98, 82, - 73, 0, 0, 73, 69, 0, 69, 73, 68, 0, 77, 5, 0, 98, 82, 73, 1, 0, 73, 69, 0, 69, 73, 48, 0, 77, 5, 0, 98, 82, 73, 2, 0, 73, 69, 0, 69, 73, 35, 0, 77, 5, 0, 98, 82, 73, 3, 0, 73, 69, - 0, 69, 73, 62, 0, 77, 5, 0, 98, 82, 73, 4, 0, 73, 69, 0, 69, 73, 51, 0, 77, 5, 0, 98, 82, 73, 5, 0, 73, 69, 0, 69, 73, 31, 0, 77, 5, 0, 98, 82, 73, 6, 0, 73, 69, 0, 69, 73, 64, 0, - 77, 5, 0, 98, 82, 73, 7, 0, 73, 69, 0, 69, 73, 63, 0, 77, 5, 0, 98, 82, 73, 8, 0, 73, 69, 0, 69, 73, 27, 0, 77, 5, 0, 98, 82, 73, 9, 0, 73, 69, 0, 69, 73, 28, 0, 77, 5, 0, 98, 82, - 73, 10, 0, 73, 69, 0, 69, 73, 32, 0, 77, 5, 0, 98, 82, 73, 11, 0, 73, 69, 0, 69, 73, 52, 0, 77, 5, 0, 98, 82, 73, 12, 0, 73, 69, 0, 69, 73, 65, 0, 77, 5, 0, 98, 82, 73, 13, 0, 73, 69, - 0, 69, 73, 33, 0, 77, 5, 0, 98, 82, 73, 14, 0, 73, 69, 0, 69, 73, 41, 0, 77, 5, 0, 98, 82, 73, 15, 0, 73, 69, 0, 69, 73, 56, 0, 77, 5, 0, 98, 82, 73, 16, 0, 73, 69, 0, 69, 73, 67, 0, - 77, 5, 0, 98, 82, 73, 17, 0, 73, 69, 0, 69, 73, 8, 0, 77, 5, 0, 98, 82, 73, 18, 0, 73, 69, 0, 69, 73, 49, 0, 77, 5, 0, 98, 82, 73, 19, 0, 73, 69, 0, 69, 73, 50, 0, 77, 5, 0, 98, 82, - 73, 20, 0, 73, 69, 0, 69, 73, 7, 0, 77, 5, 0, 98, 82, 73, 21, 0, 73, 69, 0, 69, 73, 38, 0, 77, 5, 0, 98, 82, 73, 22, 0, 73, 69, 0, 69, 73, 60, 0, 77, 5, 0, 98, 82, 73, 23, 0, 73, 69, - 0, 69, 73, 46, 0, 77, 5, 0, 98, 82, 73, 24, 0, 73, 69, 0, 69, 73, 47, 0, 77, 5, 0, 98, 82, 73, 25, 0, 73, 69, 0, 69, 73, 54, 0, 77, 5, 0, 98, 82, 73, 26, 0, 73, 69, 0, 69, 73, 55, 0, - 77, 5, 0, 98, 82, 73, 27, 0, 73, 69, 0, 69, 73, 6, 0, 77, 5, 0, 98, 82, 73, 28, 0, 73, 69, 0, 69, 73, 22, 0, 77, 5, 0, 98, 82, 73, 29, 0, 73, 69, 0, 69, 73, 42, 0, 77, 5, 0, 98, 82, - 73, 30, 0, 73, 69, 0, 69, 73, 43, 0, 77, 5, 0, 98, 82, 73, 31, 0, 73, 69, 0, 69, 73, 66, 0, 77, 5, 0, 98, 82, 73, 32, 0, 73, 69, 0, 69, 73, 23, 0, 77, 5, 0, 98, 82, 73, 33, 0, 73, 69, - 0, 69, 73, 24, 0, 77, 5, 0, 98, 82, 73, 34, 0, 73, 69, 0, 69, 73, 44, 0, 77, 5, 0, 98, 82, 73, 35, 0, 73, 69, 0, 69, 73, 45, 0, 77, 5, 0, 98, 82, 73, 36, 0, 73, 69, 0, 69, 73, 21, 0, - 77, 5, 0, 98, 82, 73, 37, 0, 73, 69, 0, 69, 73, 61, 0, 77, 5, 0, 98, 82, 73, 38, 0, 73, 69, 0, 69, 73, 39, 0, 77, 5, 0, 98, 82, 73, 39, 0, 73, 69, 0, 69, 73, 40, 0, 77, 5, 0, 98, 82, - 73, 40, 0, 73, 69, 0, 69, 73, 9, 0, 77, 5, 0, 98, 82, 73, 41, 0, 73, 69, 0, 69, 73, 26, 0, 77, 5, 0, 98, 82, 73, 42, 0, 73, 69, 0, 69, 73, 29, 0, 77, 5, 0, 98, 82, 73, 43, 0, 73, 69, - 0, 69, 73, 30, 0, 77, 5, 0, 98, 82, 73, 44, 0, 73, 69, 0, 69, 73, 57, 0, 77, 5, 0, 98, 82, 73, 45, 0, 73, 69, 0, 69, 73, 36, 0, 77, 5, 0, 98, 82, 73, 46, 0, 73, 69, 0, 69, 73, 58, 0, - 77, 5, 0, 98, 82, 73, 47, 0, 73, 69, 0, 69, 73, 37, 0, 77, 5, 0, 98, 82, 73, 48, 0, 73, 69, 0, 69, 73, 53, 0, 77, 5, 0, 98, 82, 73, 49, 0, 73, 69, 0, 69, 73, 59, 0, 77, 5, 0, 98, 82, - 73, 50, 0, 73, 69, 0, 69, 73, 25, 0, 77, 5, 0, 98, 82, 73, 51, 0, 73, 69, 0, 69, 73, 12, 0, 77, 5, 0, 98, 82, 73, 52, 0, 73, 69, 0, 69, 73, 15, 0, 77, 5, 0, 98, 82, 73, 53, 0, 73, 69, - 0, 69, 73, 17, 0, 77, 5, 0, 98, 82, 73, 54, 0, 73, 69, 0, 69, 73, 10, 0, 77, 5, 0, 98, 82, 73, 55, 0, 73, 69, 0, 69, 73, 13, 0, 77, 5, 0, 98, 82, 73, 56, 0, 73, 69, 0, 69, 73, 19, 0, - 77, 5, 0, 98, 82, 73, 57, 0, 73, 69, 0, 69, 73, 16, 0, 77, 5, 0, 98, 82, 73, 58, 0, 73, 69, 0, 69, 73, 18, 0, 77, 5, 0, 98, 82, 73, 59, 0, 73, 69, 0, 69, 73, 11, 0, 77, 5, 0, 98, 82, - 73, 60, 0, 73, 69, 0, 69, 73, 14, 0, 77, 5, 0, 98, 82, 73, 61, 0, 73, 69, 0, 69, 73, 20, 0, 77, 5, 0, 98, 82, 73, 62, 0, 73, 69, 0, 69, 73, 34, 0, 77, 5, 0, 98, 82, 73, 63, 0, 73, 70, - 0, 69, 73, 69, 0, 77, 6, 0, 98, 82, 73, 64, 0, 73, 70, 0, 69, 73, 70, 0, 73, 69, 0, 77, 113, 0, 98, 68, 73, 0, 0, 66, 0, 73, 255, 255, 69, 73, 0, 0, 73, 1, 0, 69, 73, 1, 0, 73, 2, 0, - 69, 73, 2, 0, 73, 3, 0, 69, 73, 3, 0, 73, 4, 0, 69, 73, 4, 0, 73, 5, 0, 69, 73, 5, 0, 73, 7, 0, 69, 73, 6, 0, 73, 8, 0, 69, 73, 7, 0, 73, 9, 0, 69, 73, 8, 0, 73, 10, 0, 69, - 73, 9, 0, 73, 11, 0, 69, 73, 10, 0, 73, 12, 0, 69, 73, 11, 0, 73, 13, 0, 69, 73, 12, 0, 73, 14, 0, 69, 73, 13, 0, 73, 15, 0, 69, 73, 14, 0, 73, 16, 0, 69, 73, 15, 0, 73, 17, 0, 69, 73, - 16, 0, 73, 20, 0, 69, 73, 17, 0, 73, 22, 0, 69, 73, 18, 0, 73, 24, 0, 69, 73, 19, 0, 73, 26, 0, 69, 73, 20, 0, 73, 28, 0, 69, 73, 21, 0, 73, 31, 0, 69, 73, 22, 0, 73, 42, 0, 69, 73, 23, - 0, 73, 45, 0, 69, 73, 24, 0, 73, 48, 0, 69, 73, 25, 0, 73, 51, 0, 69, 73, 26, 0, 73, 58, 0, 69, 73, 27, 0, 73, 62, 0, 69, 73, 28, 0, 73, 82, 0, 69, 73, 29, 0, 73, 85, 0, 69, 73, 30, 0, - 73, 87, 0, 69, 73, 31, 0, 73, 91, 0, 69, 73, 32, 0, 73, 93, 0, 69, 73, 33, 0, 73, 97, 0, 69, 73, 34, 0, 73, 99, 0, 69, 73, 35, 0, 73, 101, 0, 69, 77, 8, 0, 98, 68, 73, 1, 0, 66, 1, 73, - 2, 0, 69, 73, 0, 0, 73, 1, 0, 69, 77, 5, 0, 98, 68, 73, 2, 0, 66, 1, 73, 8, 0, 69, 77, 5, 0, 98, 68, 73, 3, 0, 66, 1, 73, 12, 0, 69, 77, 5, 0, 98, 68, 73, 4, 0, 66, 1, 73, 22, - 0, 69, 77, 8, 0, 98, 68, 73, 5, 0, 66, 1, 73, 33, 0, 69, 73, 36, 0, 73, 6, 0, 69, 77, 8, 0, 98, 68, 73, 6, 0, 66, 1, 73, 33, 0, 69, 73, 36, 0, 73, 6, 0, 69, 77, 5, 0, 98, 68, 73, - 7, 0, 66, 1, 73, 36, 0, 69, 77, 5, 0, 98, 68, 73, 8, 0, 66, 1, 73, 37, 0, 69, 77, 5, 0, 98, 68, 73, 9, 0, 66, 1, 73, 38, 0, 69, 77, 5, 0, 98, 68, 73, 10, 0, 66, 1, 73, 41, 0, 69, - 77, 5, 0, 98, 68, 73, 11, 0, 66, 1, 73, 48, 0, 69, 77, 5, 0, 98, 68, 73, 12, 0, 66, 1, 73, 57, 0, 69, 77, 5, 0, 98, 68, 73, 13, 0, 66, 1, 73, 58, 0, 69, 77, 5, 0, 98, 68, 73, 14, 0, - 66, 1, 73, 59, 0, 69, 77, 5, 0, 98, 68, 73, 15, 0, 66, 1, 73, 60, 0, 69, 77, 5, 0, 98, 68, 73, 16, 0, 66, 1, 73, 61, 0, 69, 77, 11, 0, 98, 68, 73, 17, 0, 66, 0, 73, 255, 255, 69, 73, 37, - 0, 73, 18, 0, 69, 73, 15, 0, 73, 19, 0, 69, 77, 11, 0, 98, 68, 73, 18, 0, 66, 0, 73, 255, 255, 69, 73, 37, 0, 73, 18, 0, 69, 73, 15, 0, 73, 19, 0, 69, 77, 5, 0, 98, 68, 73, 19, 0, 66, 1, - 73, 65, 0, 69, 77, 8, 0, 98, 68, 73, 20, 0, 66, 1, 73, 48, 0, 69, 73, 9, 0, 73, 21, 0, 69, 77, 5, 0, 98, 68, 73, 21, 0, 66, 1, 73, 48, 0, 69, 77, 8, 0, 98, 68, 73, 22, 0, 66, 1, 73, - 49, 0, 69, 73, 31, 0, 73, 23, 0, 69, 77, 5, 0, 98, 68, 73, 23, 0, 66, 1, 73, 50, 0, 69, 77, 8, 0, 98, 68, 73, 24, 0, 66, 1, 73, 56, 0, 69, 73, 18, 0, 73, 25, 0, 69, 77, 5, 0, 98, 68, - 73, 25, 0, 66, 1, 73, 67, 0, 69, 77, 8, 0, 98, 68, 73, 26, 0, 66, 1, 73, 44, 0, 69, 73, 31, 0, 73, 27, 0, 69, 77, 5, 0, 98, 68, 73, 27, 0, 66, 1, 73, 45, 0, 69, 77, 11, 0, 98, 68, 73, - 28, 0, 66, 1, 73, 10, 0, 69, 73, 20, 0, 73, 29, 0, 69, 73, 31, 0, 73, 30, 0, 69, 77, 5, 0, 98, 68, 73, 29, 0, 66, 1, 73, 7, 0, 69, 77, 5, 0, 98, 68, 73, 30, 0, 66, 1, 73, 11, 0, 69, - 77, 11, 0, 98, 68, 73, 31, 0, 66, 0, 73, 255, 255, 69, 73, 38, 0, 73, 32, 0, 69, 73, 8, 0, 73, 34, 0, 69, 77, 8, 0, 98, 68, 73, 32, 0, 66, 0, 73, 255, 255, 69, 73, 21, 0, 73, 33, 0, 69, 77, - 5, 0, 98, 68, 73, 33, 0, 66, 1, 73, 35, 0, 69, 77, 14, 0, 98, 68, 73, 34, 0, 66, 0, 73, 255, 255, 69, 73, 39, 0, 73, 35, 0, 69, 73, 40, 0, 73, 38, 0, 69, 73, 41, 0, 73, 40, 0, 69, 77, 8, - 0, 98, 68, 73, 35, 0, 66, 0, 73, 255, 255, 69, 73, 42, 0, 73, 36, 0, 69, 77, 11, 0, 98, 68, 73, 36, 0, 66, 0, 73, 255, 255, 69, 73, 42, 0, 73, 36, 0, 69, 73, 21, 0, 73, 37, 0, 69, 77, 5, 0, - 98, 68, 73, 37, 0, 66, 1, 73, 31, 0, 69, 77, 11, 0, 98, 68, 73, 38, 0, 66, 0, 73, 255, 255, 69, 73, 40, 0, 73, 38, 0, 69, 73, 21, 0, 73, 39, 0, 69, 77, 5, 0, 98, 68, 73, 39, 0, 66, 1, 73, - 51, 0, 69, 77, 8, 0, 98, 68, 73, 40, 0, 66, 0, 73, 255, 255, 69, 73, 21, 0, 73, 41, 0, 69, 77, 5, 0, 98, 68, 73, 41, 0, 66, 1, 73, 62, 0, 69, 77, 11, 0, 98, 68, 73, 42, 0, 66, 1, 73, 46, - 0, 69, 73, 26, 0, 73, 43, 0, 69, 73, 31, 0, 73, 44, 0, 69, 77, 5, 0, 98, 68, 73, 43, 0, 66, 1, 73, 3, 0, 69, 77, 5, 0, 98, 68, 73, 44, 0, 66, 1, 73, 47, 0, 69, 77, 11, 0, 98, 68, 73, - 45, 0, 66, 1, 73, 54, 0, 69, 73, 31, 0, 73, 46, 0, 69, 73, 23, 0, 73, 47, 0, 69, 77, 5, 0, 98, 68, 73, 46, 0, 66, 1, 73, 6, 0, 69, 77, 5, 0, 98, 68, 73, 47, 0, 66, 1, 73, 55, 0, 69, - 77, 11, 0, 98, 68, 73, 48, 0, 66, 1, 73, 42, 0, 69, 73, 24, 0, 73, 49, 0, 69, 73, 31, 0, 73, 50, 0, 69, 77, 5, 0, 98, 68, 73, 49, 0, 66, 1, 73, 43, 0, 69, 77, 5, 0, 98, 68, 73, 50, 0, - 66, 1, 73, 66, 0, 69, 77, 8, 0, 98, 68, 73, 51, 0, 66, 1, 73, 25, 0, 69, 73, 43, 0, 73, 52, 0, 69, 77, 14, 0, 98, 68, 73, 52, 0, 66, 1, 73, 27, 0, 69, 73, 44, 0, 73, 53, 0, 69, 73, 45, - 0, 73, 54, 0, 69, 73, 43, 0, 73, 52, 0, 69, 77, 5, 0, 98, 68, 73, 53, 0, 66, 1, 73, 27, 0, 69, 77, 11, 0, 98, 68, 73, 54, 0, 66, 0, 73, 255, 255, 69, 73, 46, 0, 73, 55, 0, 69, 73, 43, 0, - 73, 56, 0, 69, 77, 8, 0, 98, 68, 73, 55, 0, 66, 0, 73, 255, 255, 69, 73, 43, 0, 73, 56, 0, 69, 77, 11, 0, 98, 68, 73, 56, 0, 66, 1, 73, 28, 0, 69, 73, 43, 0, 73, 56, 0, 69, 73, 44, 0, 73, - 57, 0, 69, 77, 5, 0, 98, 68, 73, 57, 0, 66, 1, 73, 28, 0, 69, 77, 14, 0, 98, 68, 73, 58, 0, 66, 1, 73, 23, 0, 69, 73, 26, 0, 73, 59, 0, 69, 73, 22, 0, 73, 60, 0, 69, 73, 31, 0, 73, 61, - 0, 69, 77, 5, 0, 98, 68, 73, 59, 0, 66, 1, 73, 4, 0, 69, 77, 5, 0, 98, 68, 73, 60, 0, 66, 1, 73, 5, 0, 69, 77, 5, 0, 98, 68, 73, 61, 0, 66, 1, 73, 24, 0, 69, 77, 26, 0, 98, 68, 73, - 62, 0, 66, 1, 73, 64, 0, 69, 73, 44, 0, 73, 63, 0, 69, 73, 45, 0, 73, 64, 0, 69, 73, 47, 0, 73, 68, 0, 69, 73, 25, 0, 73, 69, 0, 69, 73, 40, 0, 73, 76, 0, 69, 73, 48, 0, 73, 78, 0, 69, - 73, 49, 0, 73, 79, 0, 69, 77, 5, 0, 98, 68, 73, 63, 0, 66, 1, 73, 27, 0, 69, 77, 11, 0, 98, 68, 73, 64, 0, 66, 0, 73, 255, 255, 69, 73, 46, 0, 73, 65, 0, 69, 73, 43, 0, 73, 66, 0, 69, 77, - 8, 0, 98, 68, 73, 65, 0, 66, 0, 73, 255, 255, 69, 73, 43, 0, 73, 66, 0, 69, 77, 11, 0, 98, 68, 73, 66, 0, 66, 1, 73, 28, 0, 69, 73, 43, 0, 73, 66, 0, 69, 73, 44, 0, 73, 67, 0, 69, 77, 5, - 0, 98, 68, 73, 67, 0, 66, 1, 73, 28, 0, 69, 77, 5, 0, 98, 68, 73, 68, 0, 66, 1, 73, 64, 0, 69, 77, 14, 0, 98, 68, 73, 69, 0, 66, 1, 73, 27, 0, 69, 73, 44, 0, 73, 70, 0, 69, 73, 45, 0, - 73, 71, 0, 69, 73, 43, 0, 73, 75, 0, 69, 77, 5, 0, 98, 68, 73, 70, 0, 66, 1, 73, 27, 0, 69, 77, 11, 0, 98, 68, 73, 71, 0, 66, 0, 73, 255, 255, 69, 73, 46, 0, 73, 72, 0, 69, 73, 43, 0, 73, - 73, 0, 69, 77, 8, 0, 98, 68, 73, 72, 0, 66, 0, 73, 255, 255, 69, 73, 43, 0, 73, 73, 0, 69, 77, 11, 0, 98, 68, 73, 73, 0, 66, 1, 73, 28, 0, 69, 73, 43, 0, 73, 73, 0, 69, 73, 44, 0, 73, 74, - 0, 69, 77, 5, 0, 98, 68, 73, 74, 0, 66, 1, 73, 28, 0, 69, 77, 14, 0, 98, 68, 73, 75, 0, 66, 1, 73, 27, 0, 69, 73, 44, 0, 73, 70, 0, 69, 73, 45, 0, 73, 71, 0, 69, 73, 43, 0, 73, 75, 0, - 69, 77, 23, 0, 98, 68, 73, 76, 0, 66, 1, 73, 52, 0, 69, 73, 44, 0, 73, 63, 0, 69, 73, 45, 0, 73, 64, 0, 69, 73, 47, 0, 73, 77, 0, 69, 73, 25, 0, 73, 69, 0, 69, 73, 40, 0, 73, 76, 0, 69, - 73, 48, 0, 73, 78, 0, 69, 77, 5, 0, 98, 68, 73, 77, 0, 66, 1, 73, 52, 0, 69, 77, 17, 0, 98, 68, 73, 78, 0, 66, 0, 73, 255, 255, 69, 73, 44, 0, 73, 63, 0, 69, 73, 45, 0, 73, 64, 0, 69, 73, - 25, 0, 73, 69, 0, 69, 73, 43, 0, 73, 78, 0, 69, 77, 8, 0, 98, 68, 73, 79, 0, 66, 0, 73, 255, 255, 69, 73, 42, 0, 73, 80, 0, 69, 77, 11, 0, 98, 68, 73, 80, 0, 66, 1, 73, 32, 0, 69, 73, 42, - 0, 73, 80, 0, 69, 73, 47, 0, 73, 81, 0, 69, 77, 5, 0, 98, 68, 73, 81, 0, 66, 1, 73, 32, 0, 69, 77, 20, 0, 98, 68, 73, 82, 0, 66, 1, 73, 63, 0, 69, 73, 44, 0, 73, 63, 0, 69, 73, 45, 0, - 73, 64, 0, 69, 73, 47, 0, 73, 83, 0, 69, 73, 25, 0, 73, 69, 0, 69, 73, 43, 0, 73, 84, 0, 69, 77, 5, 0, 98, 68, 73, 83, 0, 66, 1, 73, 63, 0, 69, 77, 20, 0, 98, 68, 73, 84, 0, 66, 1, 73, - 63, 0, 69, 73, 44, 0, 73, 63, 0, 69, 73, 45, 0, 73, 64, 0, 69, 73, 47, 0, 73, 83, 0, 69, 73, 25, 0, 73, 69, 0, 69, 73, 43, 0, 73, 84, 0, 69, 77, 8, 0, 98, 68, 73, 85, 0, 66, 1, 73, 21, - 0, 69, 73, 29, 0, 73, 86, 0, 69, 77, 5, 0, 98, 68, 73, 86, 0, 66, 1, 73, 34, 0, 69, 77, 11, 0, 98, 68, 73, 87, 0, 66, 1, 73, 39, 0, 69, 73, 31, 0, 73, 88, 0, 69, 73, 30, 0, 73, 89, 0, - 69, 77, 5, 0, 98, 68, 73, 88, 0, 66, 1, 73, 40, 0, 69, 77, 8, 0, 98, 68, 73, 89, 0, 66, 1, 73, 15, 0, 69, 73, 31, 0, 73, 90, 0, 69, 77, 5, 0, 98, 68, 73, 90, 0, 66, 1, 73, 16, 0, 69, - 77, 8, 0, 98, 68, 73, 91, 0, 66, 1, 73, 9, 0, 69, 73, 31, 0, 73, 92, 0, 69, 77, 5, 0, 98, 68, 73, 92, 0, 66, 1, 73, 26, 0, 69, 77, 11, 0, 98, 68, 73, 93, 0, 66, 1, 73, 29, 0, 69, 73, - 31, 0, 73, 94, 0, 69, 73, 32, 0, 73, 95, 0, 69, 77, 5, 0, 98, 68, 73, 94, 0, 66, 1, 73, 30, 0, 69, 77, 8, 0, 98, 68, 73, 95, 0, 66, 1, 73, 17, 0, 69, 73, 31, 0, 73, 96, 0, 69, 77, 5, - 0, 98, 68, 73, 96, 0, 66, 1, 73, 18, 0, 69, 77, 11, 0, 98, 68, 73, 97, 0, 66, 1, 73, 33, 0, 69, 73, 50, 0, 73, 6, 0, 69, 73, 51, 0, 73, 98, 0, 69, 77, 8, 0, 98, 68, 73, 98, 0, 66, 1, - 73, 68, 0, 69, 73, 36, 0, 73, 6, 0, 69, 77, 8, 0, 98, 68, 73, 99, 0, 66, 1, 73, 19, 0, 69, 73, 31, 0, 73, 100, 0, 69, 77, 5, 0, 98, 68, 73, 100, 0, 66, 1, 73, 20, 0, 69, 77, 11, 0, 98, - 68, 73, 101, 0, 66, 1, 73, 13, 0, 69, 73, 31, 0, 73, 102, 0, 69, 73, 35, 0, 73, 103, 0, 69, 77, 5, 0, 98, 68, 73, 102, 0, 66, 1, 73, 14, 0, 69, 77, 5, 0, 98, 68, 73, 103, 0, 66, 1, 73, 53, - 0, 69, 77, 7, 1, 98, 76, 73, 0, 0, 69, 73, 6, 0, 73, 1, 0, 73, 1, 0, 69, 73, 7, 0, 73, 1, 0, 73, 2, 0, 69, 73, 8, 0, 73, 1, 0, 73, 3, 0, 69, 73, 9, 0, 73, 1, 0, 73, 4, 0, - 69, 73, 10, 0, 73, 1, 0, 73, 5, 0, 69, 73, 11, 0, 73, 1, 0, 73, 6, 0, 69, 73, 12, 0, 73, 1, 0, 73, 7, 0, 69, 73, 13, 0, 73, 1, 0, 73, 8, 0, 69, 73, 14, 0, 73, 1, 0, 73, 9, 0, - 69, 73, 15, 0, 73, 1, 0, 73, 10, 0, 69, 73, 16, 0, 73, 1, 0, 73, 11, 0, 69, 73, 17, 0, 73, 1, 0, 73, 12, 0, 69, 73, 18, 0, 73, 1, 0, 73, 13, 0, 69, 73, 19, 0, 73, 1, 0, 73, 14, 0, - 69, 73, 20, 0, 73, 1, 0, 73, 15, 0, 69, 73, 21, 0, 73, 1, 0, 73, 16, 0, 69, 73, 22, 0, 73, 1, 0, 73, 17, 0, 69, 73, 23, 0, 73, 1, 0, 73, 18, 0, 69, 73, 24, 0, 73, 1, 0, 73, 19, 0, - 69, 73, 25, 0, 73, 1, 0, 73, 20, 0, 69, 73, 26, 0, 73, 1, 0, 73, 21, 0, 69, 73, 27, 0, 73, 1, 0, 73, 22, 0, 69, 73, 28, 0, 73, 1, 0, 73, 23, 0, 69, 73, 29, 0, 73, 1, 0, 73, 24, 0, - 69, 73, 30, 0, 73, 1, 0, 73, 25, 0, 69, 73, 31, 0, 73, 1, 0, 73, 26, 0, 69, 73, 32, 0, 73, 1, 0, 73, 27, 0, 69, 73, 33, 0, 73, 1, 0, 73, 28, 0, 69, 73, 34, 0, 73, 1, 0, 73, 29, 0, - 69, 73, 35, 0, 73, 1, 0, 73, 30, 0, 69, 73, 36, 0, 73, 1, 0, 73, 31, 0, 69, 73, 37, 0, 73, 1, 0, 73, 32, 0, 69, 73, 38, 0, 73, 1, 0, 73, 33, 0, 69, 73, 39, 0, 73, 1, 0, 73, 34, 0, - 69, 73, 40, 0, 73, 1, 0, 73, 35, 0, 69, 73, 41, 0, 73, 1, 0, 73, 36, 0, 69, 73, 42, 0, 73, 1, 0, 73, 37, 0, 69, 73, 43, 0, 73, 1, 0, 73, 38, 0, 69, 73, 44, 0, 73, 1, 0, 73, 39, 0, - 69, 73, 45, 0, 73, 1, 0, 73, 40, 0, 69, 73, 46, 0, 73, 1, 0, 73, 41, 0, 69, 73, 47, 0, 73, 1, 0, 73, 42, 0, 69, 73, 48, 0, 73, 1, 0, 73, 43, 0, 69, 73, 49, 0, 73, 1, 0, 73, 44, 0, - 69, 73, 50, 0, 73, 1, 0, 73, 45, 0, 69, 73, 51, 0, 73, 1, 0, 73, 46, 0, 69, 73, 52, 0, 73, 1, 0, 73, 47, 0, 69, 73, 53, 0, 73, 1, 0, 73, 48, 0, 69, 73, 54, 0, 73, 1, 0, 73, 49, 0, - 69, 73, 55, 0, 73, 1, 0, 73, 50, 0, 69, 73, 56, 0, 73, 1, 0, 73, 51, 0, 69, 73, 57, 0, 73, 1, 0, 73, 52, 0, 69, 73, 58, 0, 73, 1, 0, 73, 53, 0, 69, 73, 59, 0, 73, 1, 0, 73, 54, 0, - 69, 73, 60, 0, 73, 1, 0, 73, 55, 0, 69, 73, 61, 0, 73, 1, 0, 73, 56, 0, 69, 73, 62, 0, 73, 1, 0, 73, 57, 0, 69, 73, 63, 0, 73, 1, 0, 73, 58, 0, 69, 73, 64, 0, 73, 1, 0, 73, 59, 0, - 69, 73, 65, 0, 73, 1, 0, 73, 60, 0, 69, 73, 66, 0, 73, 1, 0, 73, 61, 0, 69, 73, 67, 0, 73, 1, 0, 73, 62, 0, 69, 73, 68, 0, 73, 1, 0, 73, 63, 0, 69, 73, 69, 0, 73, 3, 0, 73, 64, 0, - 69, 73, 70, 0, 73, 3, 0, 73, 65, 0, 69, 77, 3, 1, 98, 76, 73, 1, 0, 69, 73, 0, 0, 73, 2, 0, 73, 27, 0, 69, 73, 6, 0, 73, 2, 0, 73, 27, 0, 69, 73, 7, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 8, 0, 73, 2, 0, 73, 27, 0, 69, 73, 9, 0, 73, 2, 0, 73, 27, 0, 69, 73, 10, 0, 73, 2, 0, 73, 27, 0, 69, 73, 11, 0, 73, 2, 0, 73, 27, 0, 69, 73, 12, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 13, 0, 73, 2, 0, 73, 27, 0, 69, 73, 14, 0, 73, 2, 0, 73, 27, 0, 69, 73, 15, 0, 73, 2, 0, 73, 27, 0, 69, 73, 16, 0, 73, 2, 0, 73, 27, 0, 69, 73, 17, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 18, 0, 73, 2, 0, 73, 27, 0, 69, 73, 19, 0, 73, 2, 0, 73, 27, 0, 69, 73, 20, 0, 73, 2, 0, 73, 27, 0, 69, 73, 21, 0, 73, 2, 0, 73, 27, 0, 69, 73, 22, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 23, 0, 73, 2, 0, 73, 27, 0, 69, 73, 24, 0, 73, 2, 0, 73, 27, 0, 69, 73, 25, 0, 73, 2, 0, 73, 27, 0, 69, 73, 26, 0, 73, 2, 0, 73, 27, 0, 69, 73, 27, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 28, 0, 73, 2, 0, 73, 27, 0, 69, 73, 29, 0, 73, 2, 0, 73, 27, 0, 69, 73, 30, 0, 73, 2, 0, 73, 27, 0, 69, 73, 31, 0, 73, 2, 0, 73, 27, 0, 69, 73, 32, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 33, 0, 73, 2, 0, 73, 27, 0, 69, 73, 34, 0, 73, 2, 0, 73, 27, 0, 69, 73, 35, 0, 73, 2, 0, 73, 27, 0, 69, 73, 36, 0, 73, 2, 0, 73, 27, 0, 69, 73, 37, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 38, 0, 73, 2, 0, 73, 27, 0, 69, 73, 39, 0, 73, 2, 0, 73, 27, 0, 69, 73, 40, 0, 73, 2, 0, 73, 27, 0, 69, 73, 41, 0, 73, 2, 0, 73, 27, 0, 69, 73, 42, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 43, 0, 73, 2, 0, 73, 27, 0, 69, 73, 44, 0, 73, 2, 0, 73, 27, 0, 69, 73, 45, 0, 73, 2, 0, 73, 27, 0, 69, 73, 46, 0, 73, 2, 0, 73, 27, 0, 69, 73, 47, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 48, 0, 73, 2, 0, 73, 27, 0, 69, 73, 49, 0, 73, 2, 0, 73, 27, 0, 69, 73, 50, 0, 73, 2, 0, 73, 27, 0, 69, 73, 51, 0, 73, 2, 0, 73, 27, 0, 69, 73, 52, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 53, 0, 73, 2, 0, 73, 27, 0, 69, 73, 54, 0, 73, 2, 0, 73, 27, 0, 69, 73, 55, 0, 73, 2, 0, 73, 27, 0, 69, 73, 56, 0, 73, 2, 0, 73, 27, 0, 69, 73, 57, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 58, 0, 73, 2, 0, 73, 27, 0, 69, 73, 59, 0, 73, 2, 0, 73, 27, 0, 69, 73, 60, 0, 73, 2, 0, 73, 27, 0, 69, 73, 61, 0, 73, 2, 0, 73, 27, 0, 69, 73, 62, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 63, 0, 73, 2, 0, 73, 27, 0, 69, 73, 64, 0, 73, 2, 0, 73, 27, 0, 69, 73, 65, 0, 73, 2, 0, 73, 27, 0, 69, 73, 66, 0, 73, 2, 0, 73, 27, 0, 69, 73, 67, 0, 73, 2, 0, 73, 27, 0, 69, - 73, 68, 0, 73, 2, 0, 73, 27, 0, 69, 77, 3, 1, 98, 76, 73, 2, 0, 69, 73, 0, 0, 73, 2, 0, 73, 20, 0, 69, 73, 6, 0, 73, 2, 0, 73, 20, 0, 69, 73, 7, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 8, 0, 73, 2, 0, 73, 20, 0, 69, 73, 9, 0, 73, 2, 0, 73, 20, 0, 69, 73, 10, 0, 73, 2, 0, 73, 20, 0, 69, 73, 11, 0, 73, 2, 0, 73, 20, 0, 69, 73, 12, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 13, 0, 73, 2, 0, 73, 20, 0, 69, 73, 14, 0, 73, 2, 0, 73, 20, 0, 69, 73, 15, 0, 73, 2, 0, 73, 20, 0, 69, 73, 16, 0, 73, 2, 0, 73, 20, 0, 69, 73, 17, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 18, 0, 73, 2, 0, 73, 20, 0, 69, 73, 19, 0, 73, 2, 0, 73, 20, 0, 69, 73, 20, 0, 73, 2, 0, 73, 20, 0, 69, 73, 21, 0, 73, 2, 0, 73, 20, 0, 69, 73, 22, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 23, 0, 73, 2, 0, 73, 20, 0, 69, 73, 24, 0, 73, 2, 0, 73, 20, 0, 69, 73, 25, 0, 73, 2, 0, 73, 20, 0, 69, 73, 26, 0, 73, 2, 0, 73, 20, 0, 69, 73, 27, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 28, 0, 73, 2, 0, 73, 20, 0, 69, 73, 29, 0, 73, 2, 0, 73, 20, 0, 69, 73, 30, 0, 73, 2, 0, 73, 20, 0, 69, 73, 31, 0, 73, 2, 0, 73, 20, 0, 69, 73, 32, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 33, 0, 73, 2, 0, 73, 20, 0, 69, 73, 34, 0, 73, 2, 0, 73, 20, 0, 69, 73, 35, 0, 73, 2, 0, 73, 20, 0, 69, 73, 36, 0, 73, 2, 0, 73, 20, 0, 69, 73, 37, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 38, 0, 73, 2, 0, 73, 20, 0, 69, 73, 39, 0, 73, 2, 0, 73, 20, 0, 69, 73, 40, 0, 73, 2, 0, 73, 20, 0, 69, 73, 41, 0, 73, 2, 0, 73, 20, 0, 69, 73, 42, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 43, 0, 73, 2, 0, 73, 20, 0, 69, 73, 44, 0, 73, 2, 0, 73, 20, 0, 69, 73, 45, 0, 73, 2, 0, 73, 20, 0, 69, 73, 46, 0, 73, 2, 0, 73, 20, 0, 69, 73, 47, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 48, 0, 73, 2, 0, 73, 20, 0, 69, 73, 49, 0, 73, 2, 0, 73, 20, 0, 69, 73, 50, 0, 73, 2, 0, 73, 20, 0, 69, 73, 51, 0, 73, 2, 0, 73, 20, 0, 69, 73, 52, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 53, 0, 73, 2, 0, 73, 20, 0, 69, 73, 54, 0, 73, 2, 0, 73, 20, 0, 69, 73, 55, 0, 73, 2, 0, 73, 20, 0, 69, 73, 56, 0, 73, 2, 0, 73, 20, 0, 69, 73, 57, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 58, 0, 73, 2, 0, 73, 20, 0, 69, 73, 59, 0, 73, 2, 0, 73, 20, 0, 69, 73, 60, 0, 73, 2, 0, 73, 20, 0, 69, 73, 61, 0, 73, 2, 0, 73, 20, 0, 69, 73, 62, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 63, 0, 73, 2, 0, 73, 20, 0, 69, 73, 64, 0, 73, 2, 0, 73, 20, 0, 69, 73, 65, 0, 73, 2, 0, 73, 20, 0, 69, 73, 66, 0, 73, 2, 0, 73, 20, 0, 69, 73, 67, 0, 73, 2, 0, 73, 20, 0, 69, 73, - 68, 0, 73, 2, 0, 73, 20, 0, 69, 77, 3, 1, 98, 76, 73, 3, 0, 69, 73, 0, 0, 73, 2, 0, 73, 17, 0, 69, 73, 6, 0, 73, 2, 0, 73, 17, 0, 69, 73, 7, 0, 73, 2, 0, 73, 17, 0, 69, 73, 8, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 9, 0, 73, 2, 0, 73, 17, 0, 69, 73, 10, 0, 73, 2, 0, 73, 17, 0, 69, 73, 11, 0, 73, 2, 0, 73, 17, 0, 69, 73, 12, 0, 73, 2, 0, 73, 17, 0, 69, 73, 13, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 14, 0, 73, 2, 0, 73, 17, 0, 69, 73, 15, 0, 73, 2, 0, 73, 17, 0, 69, 73, 16, 0, 73, 2, 0, 73, 17, 0, 69, 73, 17, 0, 73, 2, 0, 73, 17, 0, 69, 73, 18, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 19, 0, 73, 2, 0, 73, 17, 0, 69, 73, 20, 0, 73, 2, 0, 73, 17, 0, 69, 73, 21, 0, 73, 2, 0, 73, 17, 0, 69, 73, 22, 0, 73, 2, 0, 73, 17, 0, 69, 73, 23, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 24, 0, 73, 2, 0, 73, 17, 0, 69, 73, 25, 0, 73, 2, 0, 73, 17, 0, 69, 73, 26, 0, 73, 2, 0, 73, 17, 0, 69, 73, 27, 0, 73, 2, 0, 73, 17, 0, 69, 73, 28, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 29, 0, 73, 2, 0, 73, 17, 0, 69, 73, 30, 0, 73, 2, 0, 73, 17, 0, 69, 73, 31, 0, 73, 2, 0, 73, 17, 0, 69, 73, 32, 0, 73, 2, 0, 73, 17, 0, 69, 73, 33, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 34, 0, 73, 2, 0, 73, 17, 0, 69, 73, 35, 0, 73, 2, 0, 73, 17, 0, 69, 73, 36, 0, 73, 2, 0, 73, 17, 0, 69, 73, 37, 0, 73, 2, 0, 73, 17, 0, 69, 73, 38, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 39, 0, 73, 2, 0, 73, 17, 0, 69, 73, 40, 0, 73, 2, 0, 73, 17, 0, 69, 73, 41, 0, 73, 2, 0, 73, 17, 0, 69, 73, 42, 0, 73, 2, 0, 73, 17, 0, 69, 73, 43, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 44, 0, 73, 2, 0, 73, 17, 0, 69, 73, 45, 0, 73, 2, 0, 73, 17, 0, 69, 73, 46, 0, 73, 2, 0, 73, 17, 0, 69, 73, 47, 0, 73, 2, 0, 73, 17, 0, 69, 73, 48, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 49, 0, 73, 2, 0, 73, 17, 0, 69, 73, 50, 0, 73, 2, 0, 73, 17, 0, 69, 73, 51, 0, 73, 2, 0, 73, 17, 0, 69, 73, 52, 0, 73, 2, 0, 73, 17, 0, 69, 73, 53, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 54, 0, 73, 2, 0, 73, 17, 0, 69, 73, 55, 0, 73, 2, 0, 73, 17, 0, 69, 73, 56, 0, 73, 2, 0, 73, 17, 0, 69, 73, 57, 0, 73, 2, 0, 73, 17, 0, 69, 73, 58, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 59, 0, 73, 2, 0, 73, 17, 0, 69, 73, 60, 0, 73, 2, 0, 73, 17, 0, 69, 73, 61, 0, 73, 2, 0, 73, 17, 0, 69, 73, 62, 0, 73, 2, 0, 73, 17, 0, 69, 73, 63, - 0, 73, 2, 0, 73, 17, 0, 69, 73, 64, 0, 73, 2, 0, 73, 17, 0, 69, 73, 65, 0, 73, 2, 0, 73, 17, 0, 69, 73, 66, 0, 73, 2, 0, 73, 17, 0, 69, 73, 67, 0, 73, 2, 0, 73, 17, 0, 69, 73, 68, - 0, 73, 2, 0, 73, 17, 0, 69, 77, 3, 1, 98, 76, 73, 4, 0, 69, 73, 0, 0, 73, 2, 0, 73, 40, 0, 69, 73, 6, 0, 73, 2, 0, 73, 40, 0, 69, 73, 7, 0, 73, 2, 0, 73, 40, 0, 69, 73, 8, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 9, 0, 73, 2, 0, 73, 40, 0, 69, 73, 10, 0, 73, 2, 0, 73, 40, 0, 69, 73, 11, 0, 73, 2, 0, 73, 40, 0, 69, 73, 12, 0, 73, 2, 0, 73, 40, 0, 69, 73, 13, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 14, 0, 73, 2, 0, 73, 40, 0, 69, 73, 15, 0, 73, 2, 0, 73, 40, 0, 69, 73, 16, 0, 73, 2, 0, 73, 40, 0, 69, 73, 17, 0, 73, 2, 0, 73, 40, 0, 69, 73, 18, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 19, 0, 73, 2, 0, 73, 40, 0, 69, 73, 20, 0, 73, 2, 0, 73, 40, 0, 69, 73, 21, 0, 73, 2, 0, 73, 40, 0, 69, 73, 22, 0, 73, 2, 0, 73, 40, 0, 69, 73, 23, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 24, 0, 73, 2, 0, 73, 40, 0, 69, 73, 25, 0, 73, 2, 0, 73, 40, 0, 69, 73, 26, 0, 73, 2, 0, 73, 40, 0, 69, 73, 27, 0, 73, 2, 0, 73, 40, 0, 69, 73, 28, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 29, 0, 73, 2, 0, 73, 40, 0, 69, 73, 30, 0, 73, 2, 0, 73, 40, 0, 69, 73, 31, 0, 73, 2, 0, 73, 40, 0, 69, 73, 32, 0, 73, 2, 0, 73, 40, 0, 69, 73, 33, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 34, 0, 73, 2, 0, 73, 40, 0, 69, 73, 35, 0, 73, 2, 0, 73, 40, 0, 69, 73, 36, 0, 73, 2, 0, 73, 40, 0, 69, 73, 37, 0, 73, 2, 0, 73, 40, 0, 69, 73, 38, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 39, 0, 73, 2, 0, 73, 40, 0, 69, 73, 40, 0, 73, 2, 0, 73, 40, 0, 69, 73, 41, 0, 73, 2, 0, 73, 40, 0, 69, 73, 42, 0, 73, 2, 0, 73, 40, 0, 69, 73, 43, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 44, 0, 73, 2, 0, 73, 40, 0, 69, 73, 45, 0, 73, 2, 0, 73, 40, 0, 69, 73, 46, 0, 73, 2, 0, 73, 40, 0, 69, 73, 47, 0, 73, 2, 0, 73, 40, 0, 69, 73, 48, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 49, 0, 73, 2, 0, 73, 40, 0, 69, 73, 50, 0, 73, 2, 0, 73, 40, 0, 69, 73, 51, 0, 73, 2, 0, 73, 40, 0, 69, 73, 52, 0, 73, 2, 0, 73, 40, 0, 69, 73, 53, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 54, 0, 73, 2, 0, 73, 40, 0, 69, 73, 55, 0, 73, 2, 0, 73, 40, 0, 69, 73, 56, 0, 73, 2, 0, 73, 40, 0, 69, 73, 57, 0, 73, 2, 0, 73, 40, 0, 69, 73, 58, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 59, 0, 73, 2, 0, 73, 40, 0, 69, 73, 60, 0, 73, 2, 0, 73, 40, 0, 69, 73, 61, 0, 73, 2, 0, 73, 40, 0, 69, 73, 62, 0, 73, 2, 0, 73, 40, 0, 69, 73, 63, 0, - 73, 2, 0, 73, 40, 0, 69, 73, 64, 0, 73, 2, 0, 73, 40, 0, 69, 73, 65, 0, 73, 2, 0, 73, 40, 0, 69, 73, 66, 0, 73, 2, 0, 73, 40, 0, 69, 73, 67, 0, 73, 2, 0, 73, 40, 0, 69, 73, 68, 0, - 73, 2, 0, 73, 40, 0, 69, 77, 3, 1, 98, 76, 73, 5, 0, 69, 73, 0, 0, 73, 2, 0, 73, 54, 0, 69, 73, 6, 0, 73, 2, 0, 73, 54, 0, 69, 73, 7, 0, 73, 2, 0, 73, 54, 0, 69, 73, 8, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 9, 0, 73, 2, 0, 73, 54, 0, 69, 73, 10, 0, 73, 2, 0, 73, 54, 0, 69, 73, 11, 0, 73, 2, 0, 73, 54, 0, 69, 73, 12, 0, 73, 2, 0, 73, 54, 0, 69, 73, 13, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 14, 0, 73, 2, 0, 73, 54, 0, 69, 73, 15, 0, 73, 2, 0, 73, 54, 0, 69, 73, 16, 0, 73, 2, 0, 73, 54, 0, 69, 73, 17, 0, 73, 2, 0, 73, 54, 0, 69, 73, 18, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 19, 0, 73, 2, 0, 73, 54, 0, 69, 73, 20, 0, 73, 2, 0, 73, 54, 0, 69, 73, 21, 0, 73, 2, 0, 73, 54, 0, 69, 73, 22, 0, 73, 2, 0, 73, 54, 0, 69, 73, 23, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 24, 0, 73, 2, 0, 73, 54, 0, 69, 73, 25, 0, 73, 2, 0, 73, 54, 0, 69, 73, 26, 0, 73, 2, 0, 73, 54, 0, 69, 73, 27, 0, 73, 2, 0, 73, 54, 0, 69, 73, 28, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 29, 0, 73, 2, 0, 73, 54, 0, 69, 73, 30, 0, 73, 2, 0, 73, 54, 0, 69, 73, 31, 0, 73, 2, 0, 73, 54, 0, 69, 73, 32, 0, 73, 2, 0, 73, 54, 0, 69, 73, 33, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 34, 0, 73, 2, 0, 73, 54, 0, 69, 73, 35, 0, 73, 2, 0, 73, 54, 0, 69, 73, 36, 0, 73, 2, 0, 73, 54, 0, 69, 73, 37, 0, 73, 2, 0, 73, 54, 0, 69, 73, 38, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 39, 0, 73, 2, 0, 73, 54, 0, 69, 73, 40, 0, 73, 2, 0, 73, 54, 0, 69, 73, 41, 0, 73, 2, 0, 73, 54, 0, 69, 73, 42, 0, 73, 2, 0, 73, 54, 0, 69, 73, 43, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 44, 0, 73, 2, 0, 73, 54, 0, 69, 73, 45, 0, 73, 2, 0, 73, 54, 0, 69, 73, 46, 0, 73, 2, 0, 73, 54, 0, 69, 73, 47, 0, 73, 2, 0, 73, 54, 0, 69, 73, 48, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 49, 0, 73, 2, 0, 73, 54, 0, 69, 73, 50, 0, 73, 2, 0, 73, 54, 0, 69, 73, 51, 0, 73, 2, 0, 73, 54, 0, 69, 73, 52, 0, 73, 2, 0, 73, 54, 0, 69, 73, 53, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 54, 0, 73, 2, 0, 73, 54, 0, 69, 73, 55, 0, 73, 2, 0, 73, 54, 0, 69, 73, 56, 0, 73, 2, 0, 73, 54, 0, 69, 73, 57, 0, 73, 2, 0, 73, 54, 0, 69, 73, 58, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 59, 0, 73, 2, 0, 73, 54, 0, 69, 73, 60, 0, 73, 2, 0, 73, 54, 0, 69, 73, 61, 0, 73, 2, 0, 73, 54, 0, 69, 73, 62, 0, 73, 2, 0, 73, 54, 0, 69, 73, 63, 0, 73, - 2, 0, 73, 54, 0, 69, 73, 64, 0, 73, 2, 0, 73, 54, 0, 69, 73, 65, 0, 73, 2, 0, 73, 54, 0, 69, 73, 66, 0, 73, 2, 0, 73, 54, 0, 69, 73, 67, 0, 73, 2, 0, 73, 54, 0, 69, 73, 68, 0, 73, - 2, 0, 73, 54, 0, 69, 77, 3, 1, 98, 76, 73, 6, 0, 69, 73, 0, 0, 73, 2, 0, 73, 59, 0, 69, 73, 6, 0, 73, 2, 0, 73, 59, 0, 69, 73, 7, 0, 73, 2, 0, 73, 59, 0, 69, 73, 8, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 9, 0, 73, 2, 0, 73, 59, 0, 69, 73, 10, 0, 73, 2, 0, 73, 59, 0, 69, 73, 11, 0, 73, 2, 0, 73, 59, 0, 69, 73, 12, 0, 73, 2, 0, 73, 59, 0, 69, 73, 13, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 14, 0, 73, 2, 0, 73, 59, 0, 69, 73, 15, 0, 73, 2, 0, 73, 59, 0, 69, 73, 16, 0, 73, 2, 0, 73, 59, 0, 69, 73, 17, 0, 73, 2, 0, 73, 59, 0, 69, 73, 18, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 19, 0, 73, 2, 0, 73, 59, 0, 69, 73, 20, 0, 73, 2, 0, 73, 59, 0, 69, 73, 21, 0, 73, 2, 0, 73, 59, 0, 69, 73, 22, 0, 73, 2, 0, 73, 59, 0, 69, 73, 23, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 24, 0, 73, 2, 0, 73, 59, 0, 69, 73, 25, 0, 73, 2, 0, 73, 59, 0, 69, 73, 26, 0, 73, 2, 0, 73, 59, 0, 69, 73, 27, 0, 73, 2, 0, 73, 59, 0, 69, 73, 28, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 29, 0, 73, 2, 0, 73, 59, 0, 69, 73, 30, 0, 73, 2, 0, 73, 59, 0, 69, 73, 31, 0, 73, 2, 0, 73, 59, 0, 69, 73, 32, 0, 73, 2, 0, 73, 59, 0, 69, 73, 33, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 34, 0, 73, 2, 0, 73, 59, 0, 69, 73, 35, 0, 73, 2, 0, 73, 59, 0, 69, 73, 36, 0, 73, 2, 0, 73, 59, 0, 69, 73, 37, 0, 73, 2, 0, 73, 59, 0, 69, 73, 38, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 39, 0, 73, 2, 0, 73, 59, 0, 69, 73, 40, 0, 73, 2, 0, 73, 59, 0, 69, 73, 41, 0, 73, 2, 0, 73, 59, 0, 69, 73, 42, 0, 73, 2, 0, 73, 59, 0, 69, 73, 43, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 44, 0, 73, 2, 0, 73, 59, 0, 69, 73, 45, 0, 73, 2, 0, 73, 59, 0, 69, 73, 46, 0, 73, 2, 0, 73, 59, 0, 69, 73, 47, 0, 73, 2, 0, 73, 59, 0, 69, 73, 48, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 49, 0, 73, 2, 0, 73, 59, 0, 69, 73, 50, 0, 73, 2, 0, 73, 59, 0, 69, 73, 51, 0, 73, 2, 0, 73, 59, 0, 69, 73, 52, 0, 73, 2, 0, 73, 59, 0, 69, 73, 53, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 54, 0, 73, 2, 0, 73, 59, 0, 69, 73, 55, 0, 73, 2, 0, 73, 59, 0, 69, 73, 56, 0, 73, 2, 0, 73, 59, 0, 69, 73, 57, 0, 73, 2, 0, 73, 59, 0, 69, 73, 58, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 59, 0, 73, 2, 0, 73, 59, 0, 69, 73, 60, 0, 73, 2, 0, 73, 59, 0, 69, 73, 61, 0, 73, 2, 0, 73, 59, 0, 69, 73, 62, 0, 73, 2, 0, 73, 59, 0, 69, 73, 63, 0, 73, 2, - 0, 73, 59, 0, 69, 73, 64, 0, 73, 2, 0, 73, 59, 0, 69, 73, 65, 0, 73, 2, 0, 73, 59, 0, 69, 73, 66, 0, 73, 2, 0, 73, 59, 0, 69, 73, 67, 0, 73, 2, 0, 73, 59, 0, 69, 73, 68, 0, 73, 2, - 0, 73, 59, 0, 69, 77, 3, 1, 98, 76, 73, 7, 0, 69, 73, 0, 0, 73, 2, 0, 73, 51, 0, 69, 73, 6, 0, 73, 2, 0, 73, 51, 0, 69, 73, 7, 0, 73, 2, 0, 73, 51, 0, 69, 73, 8, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 9, 0, 73, 2, 0, 73, 51, 0, 69, 73, 10, 0, 73, 2, 0, 73, 51, 0, 69, 73, 11, 0, 73, 2, 0, 73, 51, 0, 69, 73, 12, 0, 73, 2, 0, 73, 51, 0, 69, 73, 13, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 14, 0, 73, 2, 0, 73, 51, 0, 69, 73, 15, 0, 73, 2, 0, 73, 51, 0, 69, 73, 16, 0, 73, 2, 0, 73, 51, 0, 69, 73, 17, 0, 73, 2, 0, 73, 51, 0, 69, 73, 18, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 19, 0, 73, 2, 0, 73, 51, 0, 69, 73, 20, 0, 73, 2, 0, 73, 51, 0, 69, 73, 21, 0, 73, 2, 0, 73, 51, 0, 69, 73, 22, 0, 73, 2, 0, 73, 51, 0, 69, 73, 23, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 24, 0, 73, 2, 0, 73, 51, 0, 69, 73, 25, 0, 73, 2, 0, 73, 51, 0, 69, 73, 26, 0, 73, 2, 0, 73, 51, 0, 69, 73, 27, 0, 73, 2, 0, 73, 51, 0, 69, 73, 28, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 29, 0, 73, 2, 0, 73, 51, 0, 69, 73, 30, 0, 73, 2, 0, 73, 51, 0, 69, 73, 31, 0, 73, 2, 0, 73, 51, 0, 69, 73, 32, 0, 73, 2, 0, 73, 51, 0, 69, 73, 33, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 34, 0, 73, 2, 0, 73, 51, 0, 69, 73, 35, 0, 73, 2, 0, 73, 51, 0, 69, 73, 36, 0, 73, 2, 0, 73, 51, 0, 69, 73, 37, 0, 73, 2, 0, 73, 51, 0, 69, 73, 38, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 39, 0, 73, 2, 0, 73, 51, 0, 69, 73, 40, 0, 73, 2, 0, 73, 51, 0, 69, 73, 41, 0, 73, 2, 0, 73, 51, 0, 69, 73, 42, 0, 73, 2, 0, 73, 51, 0, 69, 73, 43, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 44, 0, 73, 2, 0, 73, 51, 0, 69, 73, 45, 0, 73, 2, 0, 73, 51, 0, 69, 73, 46, 0, 73, 2, 0, 73, 51, 0, 69, 73, 47, 0, 73, 2, 0, 73, 51, 0, 69, 73, 48, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 49, 0, 73, 2, 0, 73, 51, 0, 69, 73, 50, 0, 73, 2, 0, 73, 51, 0, 69, 73, 51, 0, 73, 2, 0, 73, 51, 0, 69, 73, 52, 0, 73, 2, 0, 73, 51, 0, 69, 73, 53, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 54, 0, 73, 2, 0, 73, 51, 0, 69, 73, 55, 0, 73, 2, 0, 73, 51, 0, 69, 73, 56, 0, 73, 2, 0, 73, 51, 0, 69, 73, 57, 0, 73, 2, 0, 73, 51, 0, 69, 73, 58, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 59, 0, 73, 2, 0, 73, 51, 0, 69, 73, 60, 0, 73, 2, 0, 73, 51, 0, 69, 73, 61, 0, 73, 2, 0, 73, 51, 0, 69, 73, 62, 0, 73, 2, 0, 73, 51, 0, 69, 73, 63, 0, 73, 2, 0, - 73, 51, 0, 69, 73, 64, 0, 73, 2, 0, 73, 51, 0, 69, 73, 65, 0, 73, 2, 0, 73, 51, 0, 69, 73, 66, 0, 73, 2, 0, 73, 51, 0, 69, 73, 67, 0, 73, 2, 0, 73, 51, 0, 69, 73, 68, 0, 73, 2, 0, - 73, 51, 0, 69, 77, 3, 1, 98, 76, 73, 8, 0, 69, 73, 0, 0, 73, 2, 0, 73, 55, 0, 69, 73, 6, 0, 73, 2, 0, 73, 55, 0, 69, 73, 7, 0, 73, 2, 0, 73, 55, 0, 69, 73, 8, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 9, 0, 73, 2, 0, 73, 55, 0, 69, 73, 10, 0, 73, 2, 0, 73, 55, 0, 69, 73, 11, 0, 73, 2, 0, 73, 55, 0, 69, 73, 12, 0, 73, 2, 0, 73, 55, 0, 69, 73, 13, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 14, 0, 73, 2, 0, 73, 55, 0, 69, 73, 15, 0, 73, 2, 0, 73, 55, 0, 69, 73, 16, 0, 73, 2, 0, 73, 55, 0, 69, 73, 17, 0, 73, 2, 0, 73, 55, 0, 69, 73, 18, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 19, 0, 73, 2, 0, 73, 55, 0, 69, 73, 20, 0, 73, 2, 0, 73, 55, 0, 69, 73, 21, 0, 73, 2, 0, 73, 55, 0, 69, 73, 22, 0, 73, 2, 0, 73, 55, 0, 69, 73, 23, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 24, 0, 73, 2, 0, 73, 55, 0, 69, 73, 25, 0, 73, 2, 0, 73, 55, 0, 69, 73, 26, 0, 73, 2, 0, 73, 55, 0, 69, 73, 27, 0, 73, 2, 0, 73, 55, 0, 69, 73, 28, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 29, 0, 73, 2, 0, 73, 55, 0, 69, 73, 30, 0, 73, 2, 0, 73, 55, 0, 69, 73, 31, 0, 73, 2, 0, 73, 55, 0, 69, 73, 32, 0, 73, 2, 0, 73, 55, 0, 69, 73, 33, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 34, 0, 73, 2, 0, 73, 55, 0, 69, 73, 35, 0, 73, 2, 0, 73, 55, 0, 69, 73, 36, 0, 73, 2, 0, 73, 55, 0, 69, 73, 37, 0, 73, 2, 0, 73, 55, 0, 69, 73, 38, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 39, 0, 73, 2, 0, 73, 55, 0, 69, 73, 40, 0, 73, 2, 0, 73, 55, 0, 69, 73, 41, 0, 73, 2, 0, 73, 55, 0, 69, 73, 42, 0, 73, 2, 0, 73, 55, 0, 69, 73, 43, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 44, 0, 73, 2, 0, 73, 55, 0, 69, 73, 45, 0, 73, 2, 0, 73, 55, 0, 69, 73, 46, 0, 73, 2, 0, 73, 55, 0, 69, 73, 47, 0, 73, 2, 0, 73, 55, 0, 69, 73, 48, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 49, 0, 73, 2, 0, 73, 55, 0, 69, 73, 50, 0, 73, 2, 0, 73, 55, 0, 69, 73, 51, 0, 73, 2, 0, 73, 55, 0, 69, 73, 52, 0, 73, 2, 0, 73, 55, 0, 69, 73, 53, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 54, 0, 73, 2, 0, 73, 55, 0, 69, 73, 55, 0, 73, 2, 0, 73, 55, 0, 69, 73, 56, 0, 73, 2, 0, 73, 55, 0, 69, 73, 57, 0, 73, 2, 0, 73, 55, 0, 69, 73, 58, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 59, 0, 73, 2, 0, 73, 55, 0, 69, 73, 60, 0, 73, 2, 0, 73, 55, 0, 69, 73, 61, 0, 73, 2, 0, 73, 55, 0, 69, 73, 62, 0, 73, 2, 0, 73, 55, 0, 69, 73, 63, 0, 73, 2, 0, 73, - 55, 0, 69, 73, 64, 0, 73, 2, 0, 73, 55, 0, 69, 73, 65, 0, 73, 2, 0, 73, 55, 0, 69, 73, 66, 0, 73, 2, 0, 73, 55, 0, 69, 73, 67, 0, 73, 2, 0, 73, 55, 0, 69, 73, 68, 0, 73, 2, 0, 73, - 55, 0, 69, 77, 3, 1, 98, 76, 73, 9, 0, 69, 73, 0, 0, 73, 2, 0, 73, 60, 0, 69, 73, 6, 0, 73, 2, 0, 73, 60, 0, 69, 73, 7, 0, 73, 2, 0, 73, 60, 0, 69, 73, 8, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 9, 0, 73, 2, 0, 73, 60, 0, 69, 73, 10, 0, 73, 2, 0, 73, 60, 0, 69, 73, 11, 0, 73, 2, 0, 73, 60, 0, 69, 73, 12, 0, 73, 2, 0, 73, 60, 0, 69, 73, 13, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 14, 0, 73, 2, 0, 73, 60, 0, 69, 73, 15, 0, 73, 2, 0, 73, 60, 0, 69, 73, 16, 0, 73, 2, 0, 73, 60, 0, 69, 73, 17, 0, 73, 2, 0, 73, 60, 0, 69, 73, 18, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 19, 0, 73, 2, 0, 73, 60, 0, 69, 73, 20, 0, 73, 2, 0, 73, 60, 0, 69, 73, 21, 0, 73, 2, 0, 73, 60, 0, 69, 73, 22, 0, 73, 2, 0, 73, 60, 0, 69, 73, 23, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 24, 0, 73, 2, 0, 73, 60, 0, 69, 73, 25, 0, 73, 2, 0, 73, 60, 0, 69, 73, 26, 0, 73, 2, 0, 73, 60, 0, 69, 73, 27, 0, 73, 2, 0, 73, 60, 0, 69, 73, 28, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 29, 0, 73, 2, 0, 73, 60, 0, 69, 73, 30, 0, 73, 2, 0, 73, 60, 0, 69, 73, 31, 0, 73, 2, 0, 73, 60, 0, 69, 73, 32, 0, 73, 2, 0, 73, 60, 0, 69, 73, 33, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 34, 0, 73, 2, 0, 73, 60, 0, 69, 73, 35, 0, 73, 2, 0, 73, 60, 0, 69, 73, 36, 0, 73, 2, 0, 73, 60, 0, 69, 73, 37, 0, 73, 2, 0, 73, 60, 0, 69, 73, 38, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 39, 0, 73, 2, 0, 73, 60, 0, 69, 73, 40, 0, 73, 2, 0, 73, 60, 0, 69, 73, 41, 0, 73, 2, 0, 73, 60, 0, 69, 73, 42, 0, 73, 2, 0, 73, 60, 0, 69, 73, 43, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 44, 0, 73, 2, 0, 73, 60, 0, 69, 73, 45, 0, 73, 2, 0, 73, 60, 0, 69, 73, 46, 0, 73, 2, 0, 73, 60, 0, 69, 73, 47, 0, 73, 2, 0, 73, 60, 0, 69, 73, 48, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 49, 0, 73, 2, 0, 73, 60, 0, 69, 73, 50, 0, 73, 2, 0, 73, 60, 0, 69, 73, 51, 0, 73, 2, 0, 73, 60, 0, 69, 73, 52, 0, 73, 2, 0, 73, 60, 0, 69, 73, 53, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 54, 0, 73, 2, 0, 73, 60, 0, 69, 73, 55, 0, 73, 2, 0, 73, 60, 0, 69, 73, 56, 0, 73, 2, 0, 73, 60, 0, 69, 73, 57, 0, 73, 2, 0, 73, 60, 0, 69, 73, 58, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 59, 0, 73, 2, 0, 73, 60, 0, 69, 73, 60, 0, 73, 2, 0, 73, 60, 0, 69, 73, 61, 0, 73, 2, 0, 73, 60, 0, 69, 73, 62, 0, 73, 2, 0, 73, 60, 0, 69, 73, 63, 0, 73, 2, 0, 73, 60, - 0, 69, 73, 64, 0, 73, 2, 0, 73, 60, 0, 69, 73, 65, 0, 73, 2, 0, 73, 60, 0, 69, 73, 66, 0, 73, 2, 0, 73, 60, 0, 69, 73, 67, 0, 73, 2, 0, 73, 60, 0, 69, 73, 68, 0, 73, 2, 0, 73, 60, - 0, 69, 77, 3, 1, 98, 76, 73, 10, 0, 69, 73, 0, 0, 73, 2, 0, 73, 52, 0, 69, 73, 6, 0, 73, 2, 0, 73, 52, 0, 69, 73, 7, 0, 73, 2, 0, 73, 52, 0, 69, 73, 8, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 9, 0, 73, 2, 0, 73, 52, 0, 69, 73, 10, 0, 73, 2, 0, 73, 52, 0, 69, 73, 11, 0, 73, 2, 0, 73, 52, 0, 69, 73, 12, 0, 73, 2, 0, 73, 52, 0, 69, 73, 13, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 14, 0, 73, 2, 0, 73, 52, 0, 69, 73, 15, 0, 73, 2, 0, 73, 52, 0, 69, 73, 16, 0, 73, 2, 0, 73, 52, 0, 69, 73, 17, 0, 73, 2, 0, 73, 52, 0, 69, 73, 18, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 19, 0, 73, 2, 0, 73, 52, 0, 69, 73, 20, 0, 73, 2, 0, 73, 52, 0, 69, 73, 21, 0, 73, 2, 0, 73, 52, 0, 69, 73, 22, 0, 73, 2, 0, 73, 52, 0, 69, 73, 23, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 24, 0, 73, 2, 0, 73, 52, 0, 69, 73, 25, 0, 73, 2, 0, 73, 52, 0, 69, 73, 26, 0, 73, 2, 0, 73, 52, 0, 69, 73, 27, 0, 73, 2, 0, 73, 52, 0, 69, 73, 28, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 29, 0, 73, 2, 0, 73, 52, 0, 69, 73, 30, 0, 73, 2, 0, 73, 52, 0, 69, 73, 31, 0, 73, 2, 0, 73, 52, 0, 69, 73, 32, 0, 73, 2, 0, 73, 52, 0, 69, 73, 33, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 34, 0, 73, 2, 0, 73, 52, 0, 69, 73, 35, 0, 73, 2, 0, 73, 52, 0, 69, 73, 36, 0, 73, 2, 0, 73, 52, 0, 69, 73, 37, 0, 73, 2, 0, 73, 52, 0, 69, 73, 38, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 39, 0, 73, 2, 0, 73, 52, 0, 69, 73, 40, 0, 73, 2, 0, 73, 52, 0, 69, 73, 41, 0, 73, 2, 0, 73, 52, 0, 69, 73, 42, 0, 73, 2, 0, 73, 52, 0, 69, 73, 43, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 44, 0, 73, 2, 0, 73, 52, 0, 69, 73, 45, 0, 73, 2, 0, 73, 52, 0, 69, 73, 46, 0, 73, 2, 0, 73, 52, 0, 69, 73, 47, 0, 73, 2, 0, 73, 52, 0, 69, 73, 48, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 49, 0, 73, 2, 0, 73, 52, 0, 69, 73, 50, 0, 73, 2, 0, 73, 52, 0, 69, 73, 51, 0, 73, 2, 0, 73, 52, 0, 69, 73, 52, 0, 73, 2, 0, 73, 52, 0, 69, 73, 53, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 54, 0, 73, 2, 0, 73, 52, 0, 69, 73, 55, 0, 73, 2, 0, 73, 52, 0, 69, 73, 56, 0, 73, 2, 0, 73, 52, 0, 69, 73, 57, 0, 73, 2, 0, 73, 52, 0, 69, 73, 58, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 59, 0, 73, 2, 0, 73, 52, 0, 69, 73, 60, 0, 73, 2, 0, 73, 52, 0, 69, 73, 61, 0, 73, 2, 0, 73, 52, 0, 69, 73, 62, 0, 73, 2, 0, 73, 52, 0, 69, 73, 63, 0, 73, 2, 0, 73, 52, 0, - 69, 73, 64, 0, 73, 2, 0, 73, 52, 0, 69, 73, 65, 0, 73, 2, 0, 73, 52, 0, 69, 73, 66, 0, 73, 2, 0, 73, 52, 0, 69, 73, 67, 0, 73, 2, 0, 73, 52, 0, 69, 73, 68, 0, 73, 2, 0, 73, 52, 0, - 69, 77, 3, 1, 98, 76, 73, 11, 0, 69, 73, 0, 0, 73, 2, 0, 73, 57, 0, 69, 73, 6, 0, 73, 2, 0, 73, 57, 0, 69, 73, 7, 0, 73, 2, 0, 73, 57, 0, 69, 73, 8, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 9, 0, 73, 2, 0, 73, 57, 0, 69, 73, 10, 0, 73, 2, 0, 73, 57, 0, 69, 73, 11, 0, 73, 2, 0, 73, 57, 0, 69, 73, 12, 0, 73, 2, 0, 73, 57, 0, 69, 73, 13, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 14, 0, 73, 2, 0, 73, 57, 0, 69, 73, 15, 0, 73, 2, 0, 73, 57, 0, 69, 73, 16, 0, 73, 2, 0, 73, 57, 0, 69, 73, 17, 0, 73, 2, 0, 73, 57, 0, 69, 73, 18, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 19, 0, 73, 2, 0, 73, 57, 0, 69, 73, 20, 0, 73, 2, 0, 73, 57, 0, 69, 73, 21, 0, 73, 2, 0, 73, 57, 0, 69, 73, 22, 0, 73, 2, 0, 73, 57, 0, 69, 73, 23, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 24, 0, 73, 2, 0, 73, 57, 0, 69, 73, 25, 0, 73, 2, 0, 73, 57, 0, 69, 73, 26, 0, 73, 2, 0, 73, 57, 0, 69, 73, 27, 0, 73, 2, 0, 73, 57, 0, 69, 73, 28, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 29, 0, 73, 2, 0, 73, 57, 0, 69, 73, 30, 0, 73, 2, 0, 73, 57, 0, 69, 73, 31, 0, 73, 2, 0, 73, 57, 0, 69, 73, 32, 0, 73, 2, 0, 73, 57, 0, 69, 73, 33, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 34, 0, 73, 2, 0, 73, 57, 0, 69, 73, 35, 0, 73, 2, 0, 73, 57, 0, 69, 73, 36, 0, 73, 2, 0, 73, 57, 0, 69, 73, 37, 0, 73, 2, 0, 73, 57, 0, 69, 73, 38, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 39, 0, 73, 2, 0, 73, 57, 0, 69, 73, 40, 0, 73, 2, 0, 73, 57, 0, 69, 73, 41, 0, 73, 2, 0, 73, 57, 0, 69, 73, 42, 0, 73, 2, 0, 73, 57, 0, 69, 73, 43, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 44, 0, 73, 2, 0, 73, 57, 0, 69, 73, 45, 0, 73, 2, 0, 73, 57, 0, 69, 73, 46, 0, 73, 2, 0, 73, 57, 0, 69, 73, 47, 0, 73, 2, 0, 73, 57, 0, 69, 73, 48, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 49, 0, 73, 2, 0, 73, 57, 0, 69, 73, 50, 0, 73, 2, 0, 73, 57, 0, 69, 73, 51, 0, 73, 2, 0, 73, 57, 0, 69, 73, 52, 0, 73, 2, 0, 73, 57, 0, 69, 73, 53, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 54, 0, 73, 2, 0, 73, 57, 0, 69, 73, 55, 0, 73, 2, 0, 73, 57, 0, 69, 73, 56, 0, 73, 2, 0, 73, 57, 0, 69, 73, 57, 0, 73, 2, 0, 73, 57, 0, 69, 73, 58, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 59, 0, 73, 2, 0, 73, 57, 0, 69, 73, 60, 0, 73, 2, 0, 73, 57, 0, 69, 73, 61, 0, 73, 2, 0, 73, 57, 0, 69, 73, 62, 0, 73, 2, 0, 73, 57, 0, 69, 73, 63, 0, 73, 2, 0, 73, 57, 0, 69, - 73, 64, 0, 73, 2, 0, 73, 57, 0, 69, 73, 65, 0, 73, 2, 0, 73, 57, 0, 69, 73, 66, 0, 73, 2, 0, 73, 57, 0, 69, 73, 67, 0, 73, 2, 0, 73, 57, 0, 69, 73, 68, 0, 73, 2, 0, 73, 57, 0, 69, - 77, 3, 1, 98, 76, 73, 12, 0, 69, 73, 0, 0, 73, 2, 0, 73, 53, 0, 69, 73, 6, 0, 73, 2, 0, 73, 53, 0, 69, 73, 7, 0, 73, 2, 0, 73, 53, 0, 69, 73, 8, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 9, 0, 73, 2, 0, 73, 53, 0, 69, 73, 10, 0, 73, 2, 0, 73, 53, 0, 69, 73, 11, 0, 73, 2, 0, 73, 53, 0, 69, 73, 12, 0, 73, 2, 0, 73, 53, 0, 69, 73, 13, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 14, 0, 73, 2, 0, 73, 53, 0, 69, 73, 15, 0, 73, 2, 0, 73, 53, 0, 69, 73, 16, 0, 73, 2, 0, 73, 53, 0, 69, 73, 17, 0, 73, 2, 0, 73, 53, 0, 69, 73, 18, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 19, 0, 73, 2, 0, 73, 53, 0, 69, 73, 20, 0, 73, 2, 0, 73, 53, 0, 69, 73, 21, 0, 73, 2, 0, 73, 53, 0, 69, 73, 22, 0, 73, 2, 0, 73, 53, 0, 69, 73, 23, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 24, 0, 73, 2, 0, 73, 53, 0, 69, 73, 25, 0, 73, 2, 0, 73, 53, 0, 69, 73, 26, 0, 73, 2, 0, 73, 53, 0, 69, 73, 27, 0, 73, 2, 0, 73, 53, 0, 69, 73, 28, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 29, 0, 73, 2, 0, 73, 53, 0, 69, 73, 30, 0, 73, 2, 0, 73, 53, 0, 69, 73, 31, 0, 73, 2, 0, 73, 53, 0, 69, 73, 32, 0, 73, 2, 0, 73, 53, 0, 69, 73, 33, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 34, 0, 73, 2, 0, 73, 53, 0, 69, 73, 35, 0, 73, 2, 0, 73, 53, 0, 69, 73, 36, 0, 73, 2, 0, 73, 53, 0, 69, 73, 37, 0, 73, 2, 0, 73, 53, 0, 69, 73, 38, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 39, 0, 73, 2, 0, 73, 53, 0, 69, 73, 40, 0, 73, 2, 0, 73, 53, 0, 69, 73, 41, 0, 73, 2, 0, 73, 53, 0, 69, 73, 42, 0, 73, 2, 0, 73, 53, 0, 69, 73, 43, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 44, 0, 73, 2, 0, 73, 53, 0, 69, 73, 45, 0, 73, 2, 0, 73, 53, 0, 69, 73, 46, 0, 73, 2, 0, 73, 53, 0, 69, 73, 47, 0, 73, 2, 0, 73, 53, 0, 69, 73, 48, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 49, 0, 73, 2, 0, 73, 53, 0, 69, 73, 50, 0, 73, 2, 0, 73, 53, 0, 69, 73, 51, 0, 73, 2, 0, 73, 53, 0, 69, 73, 52, 0, 73, 2, 0, 73, 53, 0, 69, 73, 53, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 54, 0, 73, 2, 0, 73, 53, 0, 69, 73, 55, 0, 73, 2, 0, 73, 53, 0, 69, 73, 56, 0, 73, 2, 0, 73, 53, 0, 69, 73, 57, 0, 73, 2, 0, 73, 53, 0, 69, 73, 58, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 59, 0, 73, 2, 0, 73, 53, 0, 69, 73, 60, 0, 73, 2, 0, 73, 53, 0, 69, 73, 61, 0, 73, 2, 0, 73, 53, 0, 69, 73, 62, 0, 73, 2, 0, 73, 53, 0, 69, 73, 63, 0, 73, 2, 0, 73, 53, 0, 69, 73, - 64, 0, 73, 2, 0, 73, 53, 0, 69, 73, 65, 0, 73, 2, 0, 73, 53, 0, 69, 73, 66, 0, 73, 2, 0, 73, 53, 0, 69, 73, 67, 0, 73, 2, 0, 73, 53, 0, 69, 73, 68, 0, 73, 2, 0, 73, 53, 0, 69, 77, - 3, 1, 98, 76, 73, 13, 0, 69, 73, 0, 0, 73, 2, 0, 73, 58, 0, 69, 73, 6, 0, 73, 2, 0, 73, 58, 0, 69, 73, 7, 0, 73, 2, 0, 73, 58, 0, 69, 73, 8, 0, 73, 2, 0, 73, 58, 0, 69, 73, 9, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 10, 0, 73, 2, 0, 73, 58, 0, 69, 73, 11, 0, 73, 2, 0, 73, 58, 0, 69, 73, 12, 0, 73, 2, 0, 73, 58, 0, 69, 73, 13, 0, 73, 2, 0, 73, 58, 0, 69, 73, 14, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 15, 0, 73, 2, 0, 73, 58, 0, 69, 73, 16, 0, 73, 2, 0, 73, 58, 0, 69, 73, 17, 0, 73, 2, 0, 73, 58, 0, 69, 73, 18, 0, 73, 2, 0, 73, 58, 0, 69, 73, 19, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 20, 0, 73, 2, 0, 73, 58, 0, 69, 73, 21, 0, 73, 2, 0, 73, 58, 0, 69, 73, 22, 0, 73, 2, 0, 73, 58, 0, 69, 73, 23, 0, 73, 2, 0, 73, 58, 0, 69, 73, 24, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 25, 0, 73, 2, 0, 73, 58, 0, 69, 73, 26, 0, 73, 2, 0, 73, 58, 0, 69, 73, 27, 0, 73, 2, 0, 73, 58, 0, 69, 73, 28, 0, 73, 2, 0, 73, 58, 0, 69, 73, 29, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 30, 0, 73, 2, 0, 73, 58, 0, 69, 73, 31, 0, 73, 2, 0, 73, 58, 0, 69, 73, 32, 0, 73, 2, 0, 73, 58, 0, 69, 73, 33, 0, 73, 2, 0, 73, 58, 0, 69, 73, 34, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 35, 0, 73, 2, 0, 73, 58, 0, 69, 73, 36, 0, 73, 2, 0, 73, 58, 0, 69, 73, 37, 0, 73, 2, 0, 73, 58, 0, 69, 73, 38, 0, 73, 2, 0, 73, 58, 0, 69, 73, 39, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 40, 0, 73, 2, 0, 73, 58, 0, 69, 73, 41, 0, 73, 2, 0, 73, 58, 0, 69, 73, 42, 0, 73, 2, 0, 73, 58, 0, 69, 73, 43, 0, 73, 2, 0, 73, 58, 0, 69, 73, 44, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 45, 0, 73, 2, 0, 73, 58, 0, 69, 73, 46, 0, 73, 2, 0, 73, 58, 0, 69, 73, 47, 0, 73, 2, 0, 73, 58, 0, 69, 73, 48, 0, 73, 2, 0, 73, 58, 0, 69, 73, 49, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 50, 0, 73, 2, 0, 73, 58, 0, 69, 73, 51, 0, 73, 2, 0, 73, 58, 0, 69, 73, 52, 0, 73, 2, 0, 73, 58, 0, 69, 73, 53, 0, 73, 2, 0, 73, 58, 0, 69, 73, 54, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 55, 0, 73, 2, 0, 73, 58, 0, 69, 73, 56, 0, 73, 2, 0, 73, 58, 0, 69, 73, 57, 0, 73, 2, 0, 73, 58, 0, 69, 73, 58, 0, 73, 2, 0, 73, 58, 0, 69, 73, 59, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 60, 0, 73, 2, 0, 73, 58, 0, 69, 73, 61, 0, 73, 2, 0, 73, 58, 0, 69, 73, 62, 0, 73, 2, 0, 73, 58, 0, 69, 73, 63, 0, 73, 2, 0, 73, 58, 0, 69, 73, 64, - 0, 73, 2, 0, 73, 58, 0, 69, 73, 65, 0, 73, 2, 0, 73, 58, 0, 69, 73, 66, 0, 73, 2, 0, 73, 58, 0, 69, 73, 67, 0, 73, 2, 0, 73, 58, 0, 69, 73, 68, 0, 73, 2, 0, 73, 58, 0, 69, 77, 3, - 1, 98, 76, 73, 14, 0, 69, 73, 0, 0, 73, 2, 0, 73, 56, 0, 69, 73, 6, 0, 73, 2, 0, 73, 56, 0, 69, 73, 7, 0, 73, 2, 0, 73, 56, 0, 69, 73, 8, 0, 73, 2, 0, 73, 56, 0, 69, 73, 9, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 10, 0, 73, 2, 0, 73, 56, 0, 69, 73, 11, 0, 73, 2, 0, 73, 56, 0, 69, 73, 12, 0, 73, 2, 0, 73, 56, 0, 69, 73, 13, 0, 73, 2, 0, 73, 56, 0, 69, 73, 14, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 15, 0, 73, 2, 0, 73, 56, 0, 69, 73, 16, 0, 73, 2, 0, 73, 56, 0, 69, 73, 17, 0, 73, 2, 0, 73, 56, 0, 69, 73, 18, 0, 73, 2, 0, 73, 56, 0, 69, 73, 19, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 20, 0, 73, 2, 0, 73, 56, 0, 69, 73, 21, 0, 73, 2, 0, 73, 56, 0, 69, 73, 22, 0, 73, 2, 0, 73, 56, 0, 69, 73, 23, 0, 73, 2, 0, 73, 56, 0, 69, 73, 24, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 25, 0, 73, 2, 0, 73, 56, 0, 69, 73, 26, 0, 73, 2, 0, 73, 56, 0, 69, 73, 27, 0, 73, 2, 0, 73, 56, 0, 69, 73, 28, 0, 73, 2, 0, 73, 56, 0, 69, 73, 29, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 30, 0, 73, 2, 0, 73, 56, 0, 69, 73, 31, 0, 73, 2, 0, 73, 56, 0, 69, 73, 32, 0, 73, 2, 0, 73, 56, 0, 69, 73, 33, 0, 73, 2, 0, 73, 56, 0, 69, 73, 34, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 35, 0, 73, 2, 0, 73, 56, 0, 69, 73, 36, 0, 73, 2, 0, 73, 56, 0, 69, 73, 37, 0, 73, 2, 0, 73, 56, 0, 69, 73, 38, 0, 73, 2, 0, 73, 56, 0, 69, 73, 39, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 40, 0, 73, 2, 0, 73, 56, 0, 69, 73, 41, 0, 73, 2, 0, 73, 56, 0, 69, 73, 42, 0, 73, 2, 0, 73, 56, 0, 69, 73, 43, 0, 73, 2, 0, 73, 56, 0, 69, 73, 44, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 45, 0, 73, 2, 0, 73, 56, 0, 69, 73, 46, 0, 73, 2, 0, 73, 56, 0, 69, 73, 47, 0, 73, 2, 0, 73, 56, 0, 69, 73, 48, 0, 73, 2, 0, 73, 56, 0, 69, 73, 49, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 50, 0, 73, 2, 0, 73, 56, 0, 69, 73, 51, 0, 73, 2, 0, 73, 56, 0, 69, 73, 52, 0, 73, 2, 0, 73, 56, 0, 69, 73, 53, 0, 73, 2, 0, 73, 56, 0, 69, 73, 54, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 55, 0, 73, 2, 0, 73, 56, 0, 69, 73, 56, 0, 73, 2, 0, 73, 56, 0, 69, 73, 57, 0, 73, 2, 0, 73, 56, 0, 69, 73, 58, 0, 73, 2, 0, 73, 56, 0, 69, 73, 59, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 60, 0, 73, 2, 0, 73, 56, 0, 69, 73, 61, 0, 73, 2, 0, 73, 56, 0, 69, 73, 62, 0, 73, 2, 0, 73, 56, 0, 69, 73, 63, 0, 73, 2, 0, 73, 56, 0, 69, 73, 64, 0, - 73, 2, 0, 73, 56, 0, 69, 73, 65, 0, 73, 2, 0, 73, 56, 0, 69, 73, 66, 0, 73, 2, 0, 73, 56, 0, 69, 73, 67, 0, 73, 2, 0, 73, 56, 0, 69, 73, 68, 0, 73, 2, 0, 73, 56, 0, 69, 77, 3, 1, - 98, 76, 73, 15, 0, 69, 73, 0, 0, 73, 2, 0, 73, 61, 0, 69, 73, 6, 0, 73, 2, 0, 73, 61, 0, 69, 73, 7, 0, 73, 2, 0, 73, 61, 0, 69, 73, 8, 0, 73, 2, 0, 73, 61, 0, 69, 73, 9, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 10, 0, 73, 2, 0, 73, 61, 0, 69, 73, 11, 0, 73, 2, 0, 73, 61, 0, 69, 73, 12, 0, 73, 2, 0, 73, 61, 0, 69, 73, 13, 0, 73, 2, 0, 73, 61, 0, 69, 73, 14, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 15, 0, 73, 2, 0, 73, 61, 0, 69, 73, 16, 0, 73, 2, 0, 73, 61, 0, 69, 73, 17, 0, 73, 2, 0, 73, 61, 0, 69, 73, 18, 0, 73, 2, 0, 73, 61, 0, 69, 73, 19, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 20, 0, 73, 2, 0, 73, 61, 0, 69, 73, 21, 0, 73, 2, 0, 73, 61, 0, 69, 73, 22, 0, 73, 2, 0, 73, 61, 0, 69, 73, 23, 0, 73, 2, 0, 73, 61, 0, 69, 73, 24, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 25, 0, 73, 2, 0, 73, 61, 0, 69, 73, 26, 0, 73, 2, 0, 73, 61, 0, 69, 73, 27, 0, 73, 2, 0, 73, 61, 0, 69, 73, 28, 0, 73, 2, 0, 73, 61, 0, 69, 73, 29, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 30, 0, 73, 2, 0, 73, 61, 0, 69, 73, 31, 0, 73, 2, 0, 73, 61, 0, 69, 73, 32, 0, 73, 2, 0, 73, 61, 0, 69, 73, 33, 0, 73, 2, 0, 73, 61, 0, 69, 73, 34, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 35, 0, 73, 2, 0, 73, 61, 0, 69, 73, 36, 0, 73, 2, 0, 73, 61, 0, 69, 73, 37, 0, 73, 2, 0, 73, 61, 0, 69, 73, 38, 0, 73, 2, 0, 73, 61, 0, 69, 73, 39, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 40, 0, 73, 2, 0, 73, 61, 0, 69, 73, 41, 0, 73, 2, 0, 73, 61, 0, 69, 73, 42, 0, 73, 2, 0, 73, 61, 0, 69, 73, 43, 0, 73, 2, 0, 73, 61, 0, 69, 73, 44, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 45, 0, 73, 2, 0, 73, 61, 0, 69, 73, 46, 0, 73, 2, 0, 73, 61, 0, 69, 73, 47, 0, 73, 2, 0, 73, 61, 0, 69, 73, 48, 0, 73, 2, 0, 73, 61, 0, 69, 73, 49, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 50, 0, 73, 2, 0, 73, 61, 0, 69, 73, 51, 0, 73, 2, 0, 73, 61, 0, 69, 73, 52, 0, 73, 2, 0, 73, 61, 0, 69, 73, 53, 0, 73, 2, 0, 73, 61, 0, 69, 73, 54, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 55, 0, 73, 2, 0, 73, 61, 0, 69, 73, 56, 0, 73, 2, 0, 73, 61, 0, 69, 73, 57, 0, 73, 2, 0, 73, 61, 0, 69, 73, 58, 0, 73, 2, 0, 73, 61, 0, 69, 73, 59, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 60, 0, 73, 2, 0, 73, 61, 0, 69, 73, 61, 0, 73, 2, 0, 73, 61, 0, 69, 73, 62, 0, 73, 2, 0, 73, 61, 0, 69, 73, 63, 0, 73, 2, 0, 73, 61, 0, 69, 73, 64, 0, 73, - 2, 0, 73, 61, 0, 69, 73, 65, 0, 73, 2, 0, 73, 61, 0, 69, 73, 66, 0, 73, 2, 0, 73, 61, 0, 69, 73, 67, 0, 73, 2, 0, 73, 61, 0, 69, 73, 68, 0, 73, 2, 0, 73, 61, 0, 69, 77, 3, 1, 98, - 76, 73, 16, 0, 69, 73, 0, 0, 73, 2, 0, 73, 36, 0, 69, 73, 6, 0, 73, 2, 0, 73, 36, 0, 69, 73, 7, 0, 73, 2, 0, 73, 36, 0, 69, 73, 8, 0, 73, 2, 0, 73, 36, 0, 69, 73, 9, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 10, 0, 73, 2, 0, 73, 36, 0, 69, 73, 11, 0, 73, 2, 0, 73, 36, 0, 69, 73, 12, 0, 73, 2, 0, 73, 36, 0, 69, 73, 13, 0, 73, 2, 0, 73, 36, 0, 69, 73, 14, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 15, 0, 73, 2, 0, 73, 36, 0, 69, 73, 16, 0, 73, 2, 0, 73, 36, 0, 69, 73, 17, 0, 73, 2, 0, 73, 36, 0, 69, 73, 18, 0, 73, 2, 0, 73, 36, 0, 69, 73, 19, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 20, 0, 73, 2, 0, 73, 36, 0, 69, 73, 21, 0, 73, 2, 0, 73, 36, 0, 69, 73, 22, 0, 73, 2, 0, 73, 36, 0, 69, 73, 23, 0, 73, 2, 0, 73, 36, 0, 69, 73, 24, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 25, 0, 73, 2, 0, 73, 36, 0, 69, 73, 26, 0, 73, 2, 0, 73, 36, 0, 69, 73, 27, 0, 73, 2, 0, 73, 36, 0, 69, 73, 28, 0, 73, 2, 0, 73, 36, 0, 69, 73, 29, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 30, 0, 73, 2, 0, 73, 36, 0, 69, 73, 31, 0, 73, 2, 0, 73, 36, 0, 69, 73, 32, 0, 73, 2, 0, 73, 36, 0, 69, 73, 33, 0, 73, 2, 0, 73, 36, 0, 69, 73, 34, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 35, 0, 73, 2, 0, 73, 36, 0, 69, 73, 36, 0, 73, 2, 0, 73, 36, 0, 69, 73, 37, 0, 73, 2, 0, 73, 36, 0, 69, 73, 38, 0, 73, 2, 0, 73, 36, 0, 69, 73, 39, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 40, 0, 73, 2, 0, 73, 36, 0, 69, 73, 41, 0, 73, 2, 0, 73, 36, 0, 69, 73, 42, 0, 73, 2, 0, 73, 36, 0, 69, 73, 43, 0, 73, 2, 0, 73, 36, 0, 69, 73, 44, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 45, 0, 73, 2, 0, 73, 36, 0, 69, 73, 46, 0, 73, 2, 0, 73, 36, 0, 69, 73, 47, 0, 73, 2, 0, 73, 36, 0, 69, 73, 48, 0, 73, 2, 0, 73, 36, 0, 69, 73, 49, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 50, 0, 73, 2, 0, 73, 36, 0, 69, 73, 51, 0, 73, 2, 0, 73, 36, 0, 69, 73, 52, 0, 73, 2, 0, 73, 36, 0, 69, 73, 53, 0, 73, 2, 0, 73, 36, 0, 69, 73, 54, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 55, 0, 73, 2, 0, 73, 36, 0, 69, 73, 56, 0, 73, 2, 0, 73, 36, 0, 69, 73, 57, 0, 73, 2, 0, 73, 36, 0, 69, 73, 58, 0, 73, 2, 0, 73, 36, 0, 69, 73, 59, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 60, 0, 73, 2, 0, 73, 36, 0, 69, 73, 61, 0, 73, 2, 0, 73, 36, 0, 69, 73, 62, 0, 73, 2, 0, 73, 36, 0, 69, 73, 63, 0, 73, 2, 0, 73, 36, 0, 69, 73, 64, 0, 73, 2, - 0, 73, 36, 0, 69, 73, 65, 0, 73, 2, 0, 73, 36, 0, 69, 73, 66, 0, 73, 2, 0, 73, 36, 0, 69, 73, 67, 0, 73, 2, 0, 73, 36, 0, 69, 73, 68, 0, 73, 2, 0, 73, 36, 0, 69, 77, 3, 1, 98, 76, - 73, 17, 0, 69, 73, 0, 0, 73, 2, 0, 73, 28, 0, 69, 73, 6, 0, 73, 2, 0, 73, 28, 0, 69, 73, 7, 0, 73, 2, 0, 73, 28, 0, 69, 73, 8, 0, 73, 2, 0, 73, 28, 0, 69, 73, 9, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 10, 0, 73, 2, 0, 73, 28, 0, 69, 73, 11, 0, 73, 2, 0, 73, 28, 0, 69, 73, 12, 0, 73, 2, 0, 73, 28, 0, 69, 73, 13, 0, 73, 2, 0, 73, 28, 0, 69, 73, 14, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 15, 0, 73, 2, 0, 73, 28, 0, 69, 73, 16, 0, 73, 2, 0, 73, 28, 0, 69, 73, 17, 0, 73, 2, 0, 73, 28, 0, 69, 73, 18, 0, 73, 2, 0, 73, 28, 0, 69, 73, 19, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 20, 0, 73, 2, 0, 73, 28, 0, 69, 73, 21, 0, 73, 2, 0, 73, 28, 0, 69, 73, 22, 0, 73, 2, 0, 73, 28, 0, 69, 73, 23, 0, 73, 2, 0, 73, 28, 0, 69, 73, 24, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 25, 0, 73, 2, 0, 73, 28, 0, 69, 73, 26, 0, 73, 2, 0, 73, 28, 0, 69, 73, 27, 0, 73, 2, 0, 73, 28, 0, 69, 73, 28, 0, 73, 2, 0, 73, 28, 0, 69, 73, 29, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 30, 0, 73, 2, 0, 73, 28, 0, 69, 73, 31, 0, 73, 2, 0, 73, 28, 0, 69, 73, 32, 0, 73, 2, 0, 73, 28, 0, 69, 73, 33, 0, 73, 2, 0, 73, 28, 0, 69, 73, 34, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 35, 0, 73, 2, 0, 73, 28, 0, 69, 73, 36, 0, 73, 2, 0, 73, 28, 0, 69, 73, 37, 0, 73, 2, 0, 73, 28, 0, 69, 73, 38, 0, 73, 2, 0, 73, 28, 0, 69, 73, 39, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 40, 0, 73, 2, 0, 73, 28, 0, 69, 73, 41, 0, 73, 2, 0, 73, 28, 0, 69, 73, 42, 0, 73, 2, 0, 73, 28, 0, 69, 73, 43, 0, 73, 2, 0, 73, 28, 0, 69, 73, 44, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 45, 0, 73, 2, 0, 73, 28, 0, 69, 73, 46, 0, 73, 2, 0, 73, 28, 0, 69, 73, 47, 0, 73, 2, 0, 73, 28, 0, 69, 73, 48, 0, 73, 2, 0, 73, 28, 0, 69, 73, 49, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 50, 0, 73, 2, 0, 73, 28, 0, 69, 73, 51, 0, 73, 2, 0, 73, 28, 0, 69, 73, 52, 0, 73, 2, 0, 73, 28, 0, 69, 73, 53, 0, 73, 2, 0, 73, 28, 0, 69, 73, 54, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 55, 0, 73, 2, 0, 73, 28, 0, 69, 73, 56, 0, 73, 2, 0, 73, 28, 0, 69, 73, 57, 0, 73, 2, 0, 73, 28, 0, 69, 73, 58, 0, 73, 2, 0, 73, 28, 0, 69, 73, 59, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 60, 0, 73, 2, 0, 73, 28, 0, 69, 73, 61, 0, 73, 2, 0, 73, 28, 0, 69, 73, 62, 0, 73, 2, 0, 73, 28, 0, 69, 73, 63, 0, 73, 2, 0, 73, 28, 0, 69, 73, 64, 0, 73, 2, 0, - 73, 28, 0, 69, 73, 65, 0, 73, 2, 0, 73, 28, 0, 69, 73, 66, 0, 73, 2, 0, 73, 28, 0, 69, 73, 67, 0, 73, 2, 0, 73, 28, 0, 69, 73, 68, 0, 73, 2, 0, 73, 28, 0, 69, 77, 3, 1, 98, 76, 73, - 18, 0, 69, 73, 0, 0, 73, 2, 0, 73, 32, 0, 69, 73, 6, 0, 73, 2, 0, 73, 32, 0, 69, 73, 7, 0, 73, 2, 0, 73, 32, 0, 69, 73, 8, 0, 73, 2, 0, 73, 32, 0, 69, 73, 9, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 10, 0, 73, 2, 0, 73, 32, 0, 69, 73, 11, 0, 73, 2, 0, 73, 32, 0, 69, 73, 12, 0, 73, 2, 0, 73, 32, 0, 69, 73, 13, 0, 73, 2, 0, 73, 32, 0, 69, 73, 14, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 15, 0, 73, 2, 0, 73, 32, 0, 69, 73, 16, 0, 73, 2, 0, 73, 32, 0, 69, 73, 17, 0, 73, 2, 0, 73, 32, 0, 69, 73, 18, 0, 73, 2, 0, 73, 32, 0, 69, 73, 19, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 20, 0, 73, 2, 0, 73, 32, 0, 69, 73, 21, 0, 73, 2, 0, 73, 32, 0, 69, 73, 22, 0, 73, 2, 0, 73, 32, 0, 69, 73, 23, 0, 73, 2, 0, 73, 32, 0, 69, 73, 24, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 25, 0, 73, 2, 0, 73, 32, 0, 69, 73, 26, 0, 73, 2, 0, 73, 32, 0, 69, 73, 27, 0, 73, 2, 0, 73, 32, 0, 69, 73, 28, 0, 73, 2, 0, 73, 32, 0, 69, 73, 29, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 30, 0, 73, 2, 0, 73, 32, 0, 69, 73, 31, 0, 73, 2, 0, 73, 32, 0, 69, 73, 32, 0, 73, 2, 0, 73, 32, 0, 69, 73, 33, 0, 73, 2, 0, 73, 32, 0, 69, 73, 34, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 35, 0, 73, 2, 0, 73, 32, 0, 69, 73, 36, 0, 73, 2, 0, 73, 32, 0, 69, 73, 37, 0, 73, 2, 0, 73, 32, 0, 69, 73, 38, 0, 73, 2, 0, 73, 32, 0, 69, 73, 39, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 40, 0, 73, 2, 0, 73, 32, 0, 69, 73, 41, 0, 73, 2, 0, 73, 32, 0, 69, 73, 42, 0, 73, 2, 0, 73, 32, 0, 69, 73, 43, 0, 73, 2, 0, 73, 32, 0, 69, 73, 44, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 45, 0, 73, 2, 0, 73, 32, 0, 69, 73, 46, 0, 73, 2, 0, 73, 32, 0, 69, 73, 47, 0, 73, 2, 0, 73, 32, 0, 69, 73, 48, 0, 73, 2, 0, 73, 32, 0, 69, 73, 49, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 50, 0, 73, 2, 0, 73, 32, 0, 69, 73, 51, 0, 73, 2, 0, 73, 32, 0, 69, 73, 52, 0, 73, 2, 0, 73, 32, 0, 69, 73, 53, 0, 73, 2, 0, 73, 32, 0, 69, 73, 54, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 55, 0, 73, 2, 0, 73, 32, 0, 69, 73, 56, 0, 73, 2, 0, 73, 32, 0, 69, 73, 57, 0, 73, 2, 0, 73, 32, 0, 69, 73, 58, 0, 73, 2, 0, 73, 32, 0, 69, 73, 59, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 60, 0, 73, 2, 0, 73, 32, 0, 69, 73, 61, 0, 73, 2, 0, 73, 32, 0, 69, 73, 62, 0, 73, 2, 0, 73, 32, 0, 69, 73, 63, 0, 73, 2, 0, 73, 32, 0, 69, 73, 64, 0, 73, 2, 0, 73, - 32, 0, 69, 73, 65, 0, 73, 2, 0, 73, 32, 0, 69, 73, 66, 0, 73, 2, 0, 73, 32, 0, 69, 73, 67, 0, 73, 2, 0, 73, 32, 0, 69, 73, 68, 0, 73, 2, 0, 73, 32, 0, 69, 77, 3, 1, 98, 76, 73, 19, - 0, 69, 73, 0, 0, 73, 2, 0, 73, 33, 0, 69, 73, 6, 0, 73, 2, 0, 73, 33, 0, 69, 73, 7, 0, 73, 2, 0, 73, 33, 0, 69, 73, 8, 0, 73, 2, 0, 73, 33, 0, 69, 73, 9, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 10, 0, 73, 2, 0, 73, 33, 0, 69, 73, 11, 0, 73, 2, 0, 73, 33, 0, 69, 73, 12, 0, 73, 2, 0, 73, 33, 0, 69, 73, 13, 0, 73, 2, 0, 73, 33, 0, 69, 73, 14, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 15, 0, 73, 2, 0, 73, 33, 0, 69, 73, 16, 0, 73, 2, 0, 73, 33, 0, 69, 73, 17, 0, 73, 2, 0, 73, 33, 0, 69, 73, 18, 0, 73, 2, 0, 73, 33, 0, 69, 73, 19, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 20, 0, 73, 2, 0, 73, 33, 0, 69, 73, 21, 0, 73, 2, 0, 73, 33, 0, 69, 73, 22, 0, 73, 2, 0, 73, 33, 0, 69, 73, 23, 0, 73, 2, 0, 73, 33, 0, 69, 73, 24, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 25, 0, 73, 2, 0, 73, 33, 0, 69, 73, 26, 0, 73, 2, 0, 73, 33, 0, 69, 73, 27, 0, 73, 2, 0, 73, 33, 0, 69, 73, 28, 0, 73, 2, 0, 73, 33, 0, 69, 73, 29, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 30, 0, 73, 2, 0, 73, 33, 0, 69, 73, 31, 0, 73, 2, 0, 73, 33, 0, 69, 73, 32, 0, 73, 2, 0, 73, 33, 0, 69, 73, 33, 0, 73, 2, 0, 73, 33, 0, 69, 73, 34, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 35, 0, 73, 2, 0, 73, 33, 0, 69, 73, 36, 0, 73, 2, 0, 73, 33, 0, 69, 73, 37, 0, 73, 2, 0, 73, 33, 0, 69, 73, 38, 0, 73, 2, 0, 73, 33, 0, 69, 73, 39, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 40, 0, 73, 2, 0, 73, 33, 0, 69, 73, 41, 0, 73, 2, 0, 73, 33, 0, 69, 73, 42, 0, 73, 2, 0, 73, 33, 0, 69, 73, 43, 0, 73, 2, 0, 73, 33, 0, 69, 73, 44, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 45, 0, 73, 2, 0, 73, 33, 0, 69, 73, 46, 0, 73, 2, 0, 73, 33, 0, 69, 73, 47, 0, 73, 2, 0, 73, 33, 0, 69, 73, 48, 0, 73, 2, 0, 73, 33, 0, 69, 73, 49, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 50, 0, 73, 2, 0, 73, 33, 0, 69, 73, 51, 0, 73, 2, 0, 73, 33, 0, 69, 73, 52, 0, 73, 2, 0, 73, 33, 0, 69, 73, 53, 0, 73, 2, 0, 73, 33, 0, 69, 73, 54, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 55, 0, 73, 2, 0, 73, 33, 0, 69, 73, 56, 0, 73, 2, 0, 73, 33, 0, 69, 73, 57, 0, 73, 2, 0, 73, 33, 0, 69, 73, 58, 0, 73, 2, 0, 73, 33, 0, 69, 73, 59, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 60, 0, 73, 2, 0, 73, 33, 0, 69, 73, 61, 0, 73, 2, 0, 73, 33, 0, 69, 73, 62, 0, 73, 2, 0, 73, 33, 0, 69, 73, 63, 0, 73, 2, 0, 73, 33, 0, 69, 73, 64, 0, 73, 2, 0, 73, 33, - 0, 69, 73, 65, 0, 73, 2, 0, 73, 33, 0, 69, 73, 66, 0, 73, 2, 0, 73, 33, 0, 69, 73, 67, 0, 73, 2, 0, 73, 33, 0, 69, 73, 68, 0, 73, 2, 0, 73, 33, 0, 69, 77, 3, 1, 98, 76, 73, 20, 0, - 69, 73, 0, 0, 73, 2, 0, 73, 50, 0, 69, 73, 6, 0, 73, 2, 0, 73, 50, 0, 69, 73, 7, 0, 73, 2, 0, 73, 50, 0, 69, 73, 8, 0, 73, 2, 0, 73, 50, 0, 69, 73, 9, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 10, 0, 73, 2, 0, 73, 50, 0, 69, 73, 11, 0, 73, 2, 0, 73, 50, 0, 69, 73, 12, 0, 73, 2, 0, 73, 50, 0, 69, 73, 13, 0, 73, 2, 0, 73, 50, 0, 69, 73, 14, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 15, 0, 73, 2, 0, 73, 50, 0, 69, 73, 16, 0, 73, 2, 0, 73, 50, 0, 69, 73, 17, 0, 73, 2, 0, 73, 50, 0, 69, 73, 18, 0, 73, 2, 0, 73, 50, 0, 69, 73, 19, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 20, 0, 73, 2, 0, 73, 50, 0, 69, 73, 21, 0, 73, 2, 0, 73, 50, 0, 69, 73, 22, 0, 73, 2, 0, 73, 50, 0, 69, 73, 23, 0, 73, 2, 0, 73, 50, 0, 69, 73, 24, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 25, 0, 73, 2, 0, 73, 50, 0, 69, 73, 26, 0, 73, 2, 0, 73, 50, 0, 69, 73, 27, 0, 73, 2, 0, 73, 50, 0, 69, 73, 28, 0, 73, 2, 0, 73, 50, 0, 69, 73, 29, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 30, 0, 73, 2, 0, 73, 50, 0, 69, 73, 31, 0, 73, 2, 0, 73, 50, 0, 69, 73, 32, 0, 73, 2, 0, 73, 50, 0, 69, 73, 33, 0, 73, 2, 0, 73, 50, 0, 69, 73, 34, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 35, 0, 73, 2, 0, 73, 50, 0, 69, 73, 36, 0, 73, 2, 0, 73, 50, 0, 69, 73, 37, 0, 73, 2, 0, 73, 50, 0, 69, 73, 38, 0, 73, 2, 0, 73, 50, 0, 69, 73, 39, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 40, 0, 73, 2, 0, 73, 50, 0, 69, 73, 41, 0, 73, 2, 0, 73, 50, 0, 69, 73, 42, 0, 73, 2, 0, 73, 50, 0, 69, 73, 43, 0, 73, 2, 0, 73, 50, 0, 69, 73, 44, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 45, 0, 73, 2, 0, 73, 50, 0, 69, 73, 46, 0, 73, 2, 0, 73, 50, 0, 69, 73, 47, 0, 73, 2, 0, 73, 50, 0, 69, 73, 48, 0, 73, 2, 0, 73, 50, 0, 69, 73, 49, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 50, 0, 73, 2, 0, 73, 50, 0, 69, 73, 51, 0, 73, 2, 0, 73, 50, 0, 69, 73, 52, 0, 73, 2, 0, 73, 50, 0, 69, 73, 53, 0, 73, 2, 0, 73, 50, 0, 69, 73, 54, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 55, 0, 73, 2, 0, 73, 50, 0, 69, 73, 56, 0, 73, 2, 0, 73, 50, 0, 69, 73, 57, 0, 73, 2, 0, 73, 50, 0, 69, 73, 58, 0, 73, 2, 0, 73, 50, 0, 69, 73, 59, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 60, 0, 73, 2, 0, 73, 50, 0, 69, 73, 61, 0, 73, 2, 0, 73, 50, 0, 69, 73, 62, 0, 73, 2, 0, 73, 50, 0, 69, 73, 63, 0, 73, 2, 0, 73, 50, 0, 69, 73, 64, 0, 73, 2, 0, 73, 50, 0, - 69, 73, 65, 0, 73, 2, 0, 73, 50, 0, 69, 73, 66, 0, 73, 2, 0, 73, 50, 0, 69, 73, 67, 0, 73, 2, 0, 73, 50, 0, 69, 73, 68, 0, 73, 2, 0, 73, 50, 0, 69, 77, 3, 1, 98, 76, 73, 21, 0, 69, - 73, 0, 0, 73, 2, 0, 73, 41, 0, 69, 73, 6, 0, 73, 2, 0, 73, 41, 0, 69, 73, 7, 0, 73, 2, 0, 73, 41, 0, 69, 73, 8, 0, 73, 2, 0, 73, 41, 0, 69, 73, 9, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 10, 0, 73, 2, 0, 73, 41, 0, 69, 73, 11, 0, 73, 2, 0, 73, 41, 0, 69, 73, 12, 0, 73, 2, 0, 73, 41, 0, 69, 73, 13, 0, 73, 2, 0, 73, 41, 0, 69, 73, 14, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 15, 0, 73, 2, 0, 73, 41, 0, 69, 73, 16, 0, 73, 2, 0, 73, 41, 0, 69, 73, 17, 0, 73, 2, 0, 73, 41, 0, 69, 73, 18, 0, 73, 2, 0, 73, 41, 0, 69, 73, 19, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 20, 0, 73, 2, 0, 73, 41, 0, 69, 73, 21, 0, 73, 2, 0, 73, 41, 0, 69, 73, 22, 0, 73, 2, 0, 73, 41, 0, 69, 73, 23, 0, 73, 2, 0, 73, 41, 0, 69, 73, 24, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 25, 0, 73, 2, 0, 73, 41, 0, 69, 73, 26, 0, 73, 2, 0, 73, 41, 0, 69, 73, 27, 0, 73, 2, 0, 73, 41, 0, 69, 73, 28, 0, 73, 2, 0, 73, 41, 0, 69, 73, 29, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 30, 0, 73, 2, 0, 73, 41, 0, 69, 73, 31, 0, 73, 2, 0, 73, 41, 0, 69, 73, 32, 0, 73, 2, 0, 73, 41, 0, 69, 73, 33, 0, 73, 2, 0, 73, 41, 0, 69, 73, 34, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 35, 0, 73, 2, 0, 73, 41, 0, 69, 73, 36, 0, 73, 2, 0, 73, 41, 0, 69, 73, 37, 0, 73, 2, 0, 73, 41, 0, 69, 73, 38, 0, 73, 2, 0, 73, 41, 0, 69, 73, 39, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 40, 0, 73, 2, 0, 73, 41, 0, 69, 73, 41, 0, 73, 2, 0, 73, 41, 0, 69, 73, 42, 0, 73, 2, 0, 73, 41, 0, 69, 73, 43, 0, 73, 2, 0, 73, 41, 0, 69, 73, 44, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 45, 0, 73, 2, 0, 73, 41, 0, 69, 73, 46, 0, 73, 2, 0, 73, 41, 0, 69, 73, 47, 0, 73, 2, 0, 73, 41, 0, 69, 73, 48, 0, 73, 2, 0, 73, 41, 0, 69, 73, 49, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 50, 0, 73, 2, 0, 73, 41, 0, 69, 73, 51, 0, 73, 2, 0, 73, 41, 0, 69, 73, 52, 0, 73, 2, 0, 73, 41, 0, 69, 73, 53, 0, 73, 2, 0, 73, 41, 0, 69, 73, 54, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 55, 0, 73, 2, 0, 73, 41, 0, 69, 73, 56, 0, 73, 2, 0, 73, 41, 0, 69, 73, 57, 0, 73, 2, 0, 73, 41, 0, 69, 73, 58, 0, 73, 2, 0, 73, 41, 0, 69, 73, 59, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 60, 0, 73, 2, 0, 73, 41, 0, 69, 73, 61, 0, 73, 2, 0, 73, 41, 0, 69, 73, 62, 0, 73, 2, 0, 73, 41, 0, 69, 73, 63, 0, 73, 2, 0, 73, 41, 0, 69, 73, 64, 0, 73, 2, 0, 73, 41, 0, 69, - 73, 65, 0, 73, 2, 0, 73, 41, 0, 69, 73, 66, 0, 73, 2, 0, 73, 41, 0, 69, 73, 67, 0, 73, 2, 0, 73, 41, 0, 69, 73, 68, 0, 73, 2, 0, 73, 41, 0, 69, 77, 3, 1, 98, 76, 73, 22, 0, 69, 73, - 0, 0, 73, 2, 0, 73, 8, 0, 69, 73, 6, 0, 73, 2, 0, 73, 8, 0, 69, 73, 7, 0, 73, 2, 0, 73, 8, 0, 69, 73, 8, 0, 73, 2, 0, 73, 8, 0, 69, 73, 9, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 10, 0, 73, 2, 0, 73, 8, 0, 69, 73, 11, 0, 73, 2, 0, 73, 8, 0, 69, 73, 12, 0, 73, 2, 0, 73, 8, 0, 69, 73, 13, 0, 73, 2, 0, 73, 8, 0, 69, 73, 14, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 15, 0, 73, 2, 0, 73, 8, 0, 69, 73, 16, 0, 73, 2, 0, 73, 8, 0, 69, 73, 17, 0, 73, 2, 0, 73, 8, 0, 69, 73, 18, 0, 73, 2, 0, 73, 8, 0, 69, 73, 19, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 20, 0, 73, 2, 0, 73, 8, 0, 69, 73, 21, 0, 73, 2, 0, 73, 8, 0, 69, 73, 22, 0, 73, 2, 0, 73, 8, 0, 69, 73, 23, 0, 73, 2, 0, 73, 8, 0, 69, 73, 24, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 25, 0, 73, 2, 0, 73, 8, 0, 69, 73, 26, 0, 73, 2, 0, 73, 8, 0, 69, 73, 27, 0, 73, 2, 0, 73, 8, 0, 69, 73, 28, 0, 73, 2, 0, 73, 8, 0, 69, 73, 29, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 30, 0, 73, 2, 0, 73, 8, 0, 69, 73, 31, 0, 73, 2, 0, 73, 8, 0, 69, 73, 32, 0, 73, 2, 0, 73, 8, 0, 69, 73, 33, 0, 73, 2, 0, 73, 8, 0, 69, 73, 34, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 35, 0, 73, 2, 0, 73, 8, 0, 69, 73, 36, 0, 73, 2, 0, 73, 8, 0, 69, 73, 37, 0, 73, 2, 0, 73, 8, 0, 69, 73, 38, 0, 73, 2, 0, 73, 8, 0, 69, 73, 39, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 40, 0, 73, 2, 0, 73, 8, 0, 69, 73, 41, 0, 73, 2, 0, 73, 8, 0, 69, 73, 42, 0, 73, 2, 0, 73, 8, 0, 69, 73, 43, 0, 73, 2, 0, 73, 8, 0, 69, 73, 44, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 45, 0, 73, 2, 0, 73, 8, 0, 69, 73, 46, 0, 73, 2, 0, 73, 8, 0, 69, 73, 47, 0, 73, 2, 0, 73, 8, 0, 69, 73, 48, 0, 73, 2, 0, 73, 8, 0, 69, 73, 49, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 50, 0, 73, 2, 0, 73, 8, 0, 69, 73, 51, 0, 73, 2, 0, 73, 8, 0, 69, 73, 52, 0, 73, 2, 0, 73, 8, 0, 69, 73, 53, 0, 73, 2, 0, 73, 8, 0, 69, 73, 54, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 55, 0, 73, 2, 0, 73, 8, 0, 69, 73, 56, 0, 73, 2, 0, 73, 8, 0, 69, 73, 57, 0, 73, 2, 0, 73, 8, 0, 69, 73, 58, 0, 73, 2, 0, 73, 8, 0, 69, 73, 59, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 60, 0, 73, 2, 0, 73, 8, 0, 69, 73, 61, 0, 73, 2, 0, 73, 8, 0, 69, 73, 62, 0, 73, 2, 0, 73, 8, 0, 69, 73, 63, 0, 73, 2, 0, 73, 8, 0, 69, 73, 64, 0, 73, 2, 0, 73, 8, 0, 69, 73, - 65, 0, 73, 2, 0, 73, 8, 0, 69, 73, 66, 0, 73, 2, 0, 73, 8, 0, 69, 73, 67, 0, 73, 2, 0, 73, 8, 0, 69, 73, 68, 0, 73, 2, 0, 73, 8, 0, 69, 77, 3, 1, 98, 76, 73, 23, 0, 69, 73, 0, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 6, 0, 73, 2, 0, 73, 9, 0, 69, 73, 7, 0, 73, 2, 0, 73, 9, 0, 69, 73, 8, 0, 73, 2, 0, 73, 9, 0, 69, 73, 9, 0, 73, 2, 0, 73, 9, 0, 69, 73, 10, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 11, 0, 73, 2, 0, 73, 9, 0, 69, 73, 12, 0, 73, 2, 0, 73, 9, 0, 69, 73, 13, 0, 73, 2, 0, 73, 9, 0, 69, 73, 14, 0, 73, 2, 0, 73, 9, 0, 69, 73, 15, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 16, 0, 73, 2, 0, 73, 9, 0, 69, 73, 17, 0, 73, 2, 0, 73, 9, 0, 69, 73, 18, 0, 73, 2, 0, 73, 9, 0, 69, 73, 19, 0, 73, 2, 0, 73, 9, 0, 69, 73, 20, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 21, 0, 73, 2, 0, 73, 9, 0, 69, 73, 22, 0, 73, 2, 0, 73, 9, 0, 69, 73, 23, 0, 73, 2, 0, 73, 9, 0, 69, 73, 24, 0, 73, 2, 0, 73, 9, 0, 69, 73, 25, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 26, 0, 73, 2, 0, 73, 9, 0, 69, 73, 27, 0, 73, 2, 0, 73, 9, 0, 69, 73, 28, 0, 73, 2, 0, 73, 9, 0, 69, 73, 29, 0, 73, 2, 0, 73, 9, 0, 69, 73, 30, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 31, 0, 73, 2, 0, 73, 9, 0, 69, 73, 32, 0, 73, 2, 0, 73, 9, 0, 69, 73, 33, 0, 73, 2, 0, 73, 9, 0, 69, 73, 34, 0, 73, 2, 0, 73, 9, 0, 69, 73, 35, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 36, 0, 73, 2, 0, 73, 9, 0, 69, 73, 37, 0, 73, 2, 0, 73, 9, 0, 69, 73, 38, 0, 73, 2, 0, 73, 9, 0, 69, 73, 39, 0, 73, 2, 0, 73, 9, 0, 69, 73, 40, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 41, 0, 73, 2, 0, 73, 9, 0, 69, 73, 42, 0, 73, 2, 0, 73, 9, 0, 69, 73, 43, 0, 73, 2, 0, 73, 9, 0, 69, 73, 44, 0, 73, 2, 0, 73, 9, 0, 69, 73, 45, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 46, 0, 73, 2, 0, 73, 9, 0, 69, 73, 47, 0, 73, 2, 0, 73, 9, 0, 69, 73, 48, 0, 73, 2, 0, 73, 9, 0, 69, 73, 49, 0, 73, 2, 0, 73, 9, 0, 69, 73, 50, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 51, 0, 73, 2, 0, 73, 9, 0, 69, 73, 52, 0, 73, 2, 0, 73, 9, 0, 69, 73, 53, 0, 73, 2, 0, 73, 9, 0, 69, 73, 54, 0, 73, 2, 0, 73, 9, 0, 69, 73, 55, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 56, 0, 73, 2, 0, 73, 9, 0, 69, 73, 57, 0, 73, 2, 0, 73, 9, 0, 69, 73, 58, 0, 73, 2, 0, 73, 9, 0, 69, 73, 59, 0, 73, 2, 0, 73, 9, 0, 69, 73, 60, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 61, 0, 73, 2, 0, 73, 9, 0, 69, 73, 62, 0, 73, 2, 0, 73, 9, 0, 69, 73, 63, 0, 73, 2, 0, 73, 9, 0, 69, 73, 64, 0, 73, 2, 0, 73, 9, 0, 69, 73, 65, - 0, 73, 2, 0, 73, 9, 0, 69, 73, 66, 0, 73, 2, 0, 73, 9, 0, 69, 73, 67, 0, 73, 2, 0, 73, 9, 0, 69, 73, 68, 0, 73, 2, 0, 73, 9, 0, 69, 77, 3, 1, 98, 76, 73, 24, 0, 69, 73, 0, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 6, 0, 73, 2, 0, 73, 42, 0, 69, 73, 7, 0, 73, 2, 0, 73, 42, 0, 69, 73, 8, 0, 73, 2, 0, 73, 42, 0, 69, 73, 9, 0, 73, 2, 0, 73, 42, 0, 69, 73, 10, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 11, 0, 73, 2, 0, 73, 42, 0, 69, 73, 12, 0, 73, 2, 0, 73, 42, 0, 69, 73, 13, 0, 73, 2, 0, 73, 42, 0, 69, 73, 14, 0, 73, 2, 0, 73, 42, 0, 69, 73, 15, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 16, 0, 73, 2, 0, 73, 42, 0, 69, 73, 17, 0, 73, 2, 0, 73, 42, 0, 69, 73, 18, 0, 73, 2, 0, 73, 42, 0, 69, 73, 19, 0, 73, 2, 0, 73, 42, 0, 69, 73, 20, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 21, 0, 73, 2, 0, 73, 42, 0, 69, 73, 22, 0, 73, 2, 0, 73, 42, 0, 69, 73, 23, 0, 73, 2, 0, 73, 42, 0, 69, 73, 24, 0, 73, 2, 0, 73, 42, 0, 69, 73, 25, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 26, 0, 73, 2, 0, 73, 42, 0, 69, 73, 27, 0, 73, 2, 0, 73, 42, 0, 69, 73, 28, 0, 73, 2, 0, 73, 42, 0, 69, 73, 29, 0, 73, 2, 0, 73, 42, 0, 69, 73, 30, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 31, 0, 73, 2, 0, 73, 42, 0, 69, 73, 32, 0, 73, 2, 0, 73, 42, 0, 69, 73, 33, 0, 73, 2, 0, 73, 42, 0, 69, 73, 34, 0, 73, 2, 0, 73, 42, 0, 69, 73, 35, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 36, 0, 73, 2, 0, 73, 42, 0, 69, 73, 37, 0, 73, 2, 0, 73, 42, 0, 69, 73, 38, 0, 73, 2, 0, 73, 42, 0, 69, 73, 39, 0, 73, 2, 0, 73, 42, 0, 69, 73, 40, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 41, 0, 73, 2, 0, 73, 42, 0, 69, 73, 42, 0, 73, 2, 0, 73, 42, 0, 69, 73, 43, 0, 73, 2, 0, 73, 42, 0, 69, 73, 44, 0, 73, 2, 0, 73, 42, 0, 69, 73, 45, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 46, 0, 73, 2, 0, 73, 42, 0, 69, 73, 47, 0, 73, 2, 0, 73, 42, 0, 69, 73, 48, 0, 73, 2, 0, 73, 42, 0, 69, 73, 49, 0, 73, 2, 0, 73, 42, 0, 69, 73, 50, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 51, 0, 73, 2, 0, 73, 42, 0, 69, 73, 52, 0, 73, 2, 0, 73, 42, 0, 69, 73, 53, 0, 73, 2, 0, 73, 42, 0, 69, 73, 54, 0, 73, 2, 0, 73, 42, 0, 69, 73, 55, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 56, 0, 73, 2, 0, 73, 42, 0, 69, 73, 57, 0, 73, 2, 0, 73, 42, 0, 69, 73, 58, 0, 73, 2, 0, 73, 42, 0, 69, 73, 59, 0, 73, 2, 0, 73, 42, 0, 69, 73, 60, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 61, 0, 73, 2, 0, 73, 42, 0, 69, 73, 62, 0, 73, 2, 0, 73, 42, 0, 69, 73, 63, 0, 73, 2, 0, 73, 42, 0, 69, 73, 64, 0, 73, 2, 0, 73, 42, 0, 69, 73, 65, 0, - 73, 2, 0, 73, 42, 0, 69, 73, 66, 0, 73, 2, 0, 73, 42, 0, 69, 73, 67, 0, 73, 2, 0, 73, 42, 0, 69, 73, 68, 0, 73, 2, 0, 73, 42, 0, 69, 77, 3, 1, 98, 76, 73, 25, 0, 69, 73, 0, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 6, 0, 73, 2, 0, 73, 43, 0, 69, 73, 7, 0, 73, 2, 0, 73, 43, 0, 69, 73, 8, 0, 73, 2, 0, 73, 43, 0, 69, 73, 9, 0, 73, 2, 0, 73, 43, 0, 69, 73, 10, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 11, 0, 73, 2, 0, 73, 43, 0, 69, 73, 12, 0, 73, 2, 0, 73, 43, 0, 69, 73, 13, 0, 73, 2, 0, 73, 43, 0, 69, 73, 14, 0, 73, 2, 0, 73, 43, 0, 69, 73, 15, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 16, 0, 73, 2, 0, 73, 43, 0, 69, 73, 17, 0, 73, 2, 0, 73, 43, 0, 69, 73, 18, 0, 73, 2, 0, 73, 43, 0, 69, 73, 19, 0, 73, 2, 0, 73, 43, 0, 69, 73, 20, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 21, 0, 73, 2, 0, 73, 43, 0, 69, 73, 22, 0, 73, 2, 0, 73, 43, 0, 69, 73, 23, 0, 73, 2, 0, 73, 43, 0, 69, 73, 24, 0, 73, 2, 0, 73, 43, 0, 69, 73, 25, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 26, 0, 73, 2, 0, 73, 43, 0, 69, 73, 27, 0, 73, 2, 0, 73, 43, 0, 69, 73, 28, 0, 73, 2, 0, 73, 43, 0, 69, 73, 29, 0, 73, 2, 0, 73, 43, 0, 69, 73, 30, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 31, 0, 73, 2, 0, 73, 43, 0, 69, 73, 32, 0, 73, 2, 0, 73, 43, 0, 69, 73, 33, 0, 73, 2, 0, 73, 43, 0, 69, 73, 34, 0, 73, 2, 0, 73, 43, 0, 69, 73, 35, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 36, 0, 73, 2, 0, 73, 43, 0, 69, 73, 37, 0, 73, 2, 0, 73, 43, 0, 69, 73, 38, 0, 73, 2, 0, 73, 43, 0, 69, 73, 39, 0, 73, 2, 0, 73, 43, 0, 69, 73, 40, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 41, 0, 73, 2, 0, 73, 43, 0, 69, 73, 42, 0, 73, 2, 0, 73, 43, 0, 69, 73, 43, 0, 73, 2, 0, 73, 43, 0, 69, 73, 44, 0, 73, 2, 0, 73, 43, 0, 69, 73, 45, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 46, 0, 73, 2, 0, 73, 43, 0, 69, 73, 47, 0, 73, 2, 0, 73, 43, 0, 69, 73, 48, 0, 73, 2, 0, 73, 43, 0, 69, 73, 49, 0, 73, 2, 0, 73, 43, 0, 69, 73, 50, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 51, 0, 73, 2, 0, 73, 43, 0, 69, 73, 52, 0, 73, 2, 0, 73, 43, 0, 69, 73, 53, 0, 73, 2, 0, 73, 43, 0, 69, 73, 54, 0, 73, 2, 0, 73, 43, 0, 69, 73, 55, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 56, 0, 73, 2, 0, 73, 43, 0, 69, 73, 57, 0, 73, 2, 0, 73, 43, 0, 69, 73, 58, 0, 73, 2, 0, 73, 43, 0, 69, 73, 59, 0, 73, 2, 0, 73, 43, 0, 69, 73, 60, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 61, 0, 73, 2, 0, 73, 43, 0, 69, 73, 62, 0, 73, 2, 0, 73, 43, 0, 69, 73, 63, 0, 73, 2, 0, 73, 43, 0, 69, 73, 64, 0, 73, 2, 0, 73, 43, 0, 69, 73, 65, 0, 73, - 2, 0, 73, 43, 0, 69, 73, 66, 0, 73, 2, 0, 73, 43, 0, 69, 73, 67, 0, 73, 2, 0, 73, 43, 0, 69, 73, 68, 0, 73, 2, 0, 73, 43, 0, 69, 77, 3, 1, 98, 76, 73, 26, 0, 69, 73, 0, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 6, 0, 73, 2, 0, 73, 5, 0, 69, 73, 7, 0, 73, 2, 0, 73, 5, 0, 69, 73, 8, 0, 73, 2, 0, 73, 5, 0, 69, 73, 9, 0, 73, 2, 0, 73, 5, 0, 69, 73, 10, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 11, 0, 73, 2, 0, 73, 5, 0, 69, 73, 12, 0, 73, 2, 0, 73, 5, 0, 69, 73, 13, 0, 73, 2, 0, 73, 5, 0, 69, 73, 14, 0, 73, 2, 0, 73, 5, 0, 69, 73, 15, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 16, 0, 73, 2, 0, 73, 5, 0, 69, 73, 17, 0, 73, 2, 0, 73, 5, 0, 69, 73, 18, 0, 73, 2, 0, 73, 5, 0, 69, 73, 19, 0, 73, 2, 0, 73, 5, 0, 69, 73, 20, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 21, 0, 73, 2, 0, 73, 5, 0, 69, 73, 22, 0, 73, 2, 0, 73, 5, 0, 69, 73, 23, 0, 73, 2, 0, 73, 5, 0, 69, 73, 24, 0, 73, 2, 0, 73, 5, 0, 69, 73, 25, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 26, 0, 73, 2, 0, 73, 5, 0, 69, 73, 27, 0, 73, 2, 0, 73, 5, 0, 69, 73, 28, 0, 73, 2, 0, 73, 5, 0, 69, 73, 29, 0, 73, 2, 0, 73, 5, 0, 69, 73, 30, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 31, 0, 73, 2, 0, 73, 5, 0, 69, 73, 32, 0, 73, 2, 0, 73, 5, 0, 69, 73, 33, 0, 73, 2, 0, 73, 5, 0, 69, 73, 34, 0, 73, 2, 0, 73, 5, 0, 69, 73, 35, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 36, 0, 73, 2, 0, 73, 5, 0, 69, 73, 37, 0, 73, 2, 0, 73, 5, 0, 69, 73, 38, 0, 73, 2, 0, 73, 5, 0, 69, 73, 39, 0, 73, 2, 0, 73, 5, 0, 69, 73, 40, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 41, 0, 73, 2, 0, 73, 5, 0, 69, 73, 42, 0, 73, 2, 0, 73, 5, 0, 69, 73, 43, 0, 73, 2, 0, 73, 5, 0, 69, 73, 44, 0, 73, 2, 0, 73, 5, 0, 69, 73, 45, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 46, 0, 73, 2, 0, 73, 5, 0, 69, 73, 47, 0, 73, 2, 0, 73, 5, 0, 69, 73, 48, 0, 73, 2, 0, 73, 5, 0, 69, 73, 49, 0, 73, 2, 0, 73, 5, 0, 69, 73, 50, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 51, 0, 73, 2, 0, 73, 5, 0, 69, 73, 52, 0, 73, 2, 0, 73, 5, 0, 69, 73, 53, 0, 73, 2, 0, 73, 5, 0, 69, 73, 54, 0, 73, 2, 0, 73, 5, 0, 69, 73, 55, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 56, 0, 73, 2, 0, 73, 5, 0, 69, 73, 57, 0, 73, 2, 0, 73, 5, 0, 69, 73, 58, 0, 73, 2, 0, 73, 5, 0, 69, 73, 59, 0, 73, 2, 0, 73, 5, 0, 69, 73, 60, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 61, 0, 73, 2, 0, 73, 5, 0, 69, 73, 62, 0, 73, 2, 0, 73, 5, 0, 69, 73, 63, 0, 73, 2, 0, 73, 5, 0, 69, 73, 64, 0, 73, 2, 0, 73, 5, 0, 69, 73, 65, 0, 73, 2, - 0, 73, 5, 0, 69, 73, 66, 0, 73, 2, 0, 73, 5, 0, 69, 73, 67, 0, 73, 2, 0, 73, 5, 0, 69, 73, 68, 0, 73, 2, 0, 73, 5, 0, 69, 77, 3, 1, 98, 76, 73, 27, 0, 69, 73, 0, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 6, 0, 73, 2, 0, 73, 10, 0, 69, 73, 7, 0, 73, 2, 0, 73, 10, 0, 69, 73, 8, 0, 73, 2, 0, 73, 10, 0, 69, 73, 9, 0, 73, 2, 0, 73, 10, 0, 69, 73, 10, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 11, 0, 73, 2, 0, 73, 10, 0, 69, 73, 12, 0, 73, 2, 0, 73, 10, 0, 69, 73, 13, 0, 73, 2, 0, 73, 10, 0, 69, 73, 14, 0, 73, 2, 0, 73, 10, 0, 69, 73, 15, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 16, 0, 73, 2, 0, 73, 10, 0, 69, 73, 17, 0, 73, 2, 0, 73, 10, 0, 69, 73, 18, 0, 73, 2, 0, 73, 10, 0, 69, 73, 19, 0, 73, 2, 0, 73, 10, 0, 69, 73, 20, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 21, 0, 73, 2, 0, 73, 10, 0, 69, 73, 22, 0, 73, 2, 0, 73, 10, 0, 69, 73, 23, 0, 73, 2, 0, 73, 10, 0, 69, 73, 24, 0, 73, 2, 0, 73, 10, 0, 69, 73, 25, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 26, 0, 73, 2, 0, 73, 10, 0, 69, 73, 27, 0, 73, 2, 0, 73, 10, 0, 69, 73, 28, 0, 73, 2, 0, 73, 10, 0, 69, 73, 29, 0, 73, 2, 0, 73, 10, 0, 69, 73, 30, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 31, 0, 73, 2, 0, 73, 10, 0, 69, 73, 32, 0, 73, 2, 0, 73, 10, 0, 69, 73, 33, 0, 73, 2, 0, 73, 10, 0, 69, 73, 34, 0, 73, 2, 0, 73, 10, 0, 69, 73, 35, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 36, 0, 73, 2, 0, 73, 10, 0, 69, 73, 37, 0, 73, 2, 0, 73, 10, 0, 69, 73, 38, 0, 73, 2, 0, 73, 10, 0, 69, 73, 39, 0, 73, 2, 0, 73, 10, 0, 69, 73, 40, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 41, 0, 73, 2, 0, 73, 10, 0, 69, 73, 42, 0, 73, 2, 0, 73, 10, 0, 69, 73, 43, 0, 73, 2, 0, 73, 10, 0, 69, 73, 44, 0, 73, 2, 0, 73, 10, 0, 69, 73, 45, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 46, 0, 73, 2, 0, 73, 10, 0, 69, 73, 47, 0, 73, 2, 0, 73, 10, 0, 69, 73, 48, 0, 73, 2, 0, 73, 10, 0, 69, 73, 49, 0, 73, 2, 0, 73, 10, 0, 69, 73, 50, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 51, 0, 73, 2, 0, 73, 10, 0, 69, 73, 52, 0, 73, 2, 0, 73, 10, 0, 69, 73, 53, 0, 73, 2, 0, 73, 10, 0, 69, 73, 54, 0, 73, 2, 0, 73, 10, 0, 69, 73, 55, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 56, 0, 73, 2, 0, 73, 10, 0, 69, 73, 57, 0, 73, 2, 0, 73, 10, 0, 69, 73, 58, 0, 73, 2, 0, 73, 10, 0, 69, 73, 59, 0, 73, 2, 0, 73, 10, 0, 69, 73, 60, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 61, 0, 73, 2, 0, 73, 10, 0, 69, 73, 62, 0, 73, 2, 0, 73, 10, 0, 69, 73, 63, 0, 73, 2, 0, 73, 10, 0, 69, 73, 64, 0, 73, 2, 0, 73, 10, 0, 69, 73, 65, 0, 73, 2, 0, - 73, 10, 0, 69, 73, 66, 0, 73, 2, 0, 73, 10, 0, 69, 73, 67, 0, 73, 2, 0, 73, 10, 0, 69, 73, 68, 0, 73, 2, 0, 73, 10, 0, 69, 77, 3, 1, 98, 76, 73, 28, 0, 69, 73, 0, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 6, 0, 73, 2, 0, 73, 13, 0, 69, 73, 7, 0, 73, 2, 0, 73, 13, 0, 69, 73, 8, 0, 73, 2, 0, 73, 13, 0, 69, 73, 9, 0, 73, 2, 0, 73, 13, 0, 69, 73, 10, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 11, 0, 73, 2, 0, 73, 13, 0, 69, 73, 12, 0, 73, 2, 0, 73, 13, 0, 69, 73, 13, 0, 73, 2, 0, 73, 13, 0, 69, 73, 14, 0, 73, 2, 0, 73, 13, 0, 69, 73, 15, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 16, 0, 73, 2, 0, 73, 13, 0, 69, 73, 17, 0, 73, 2, 0, 73, 13, 0, 69, 73, 18, 0, 73, 2, 0, 73, 13, 0, 69, 73, 19, 0, 73, 2, 0, 73, 13, 0, 69, 73, 20, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 21, 0, 73, 2, 0, 73, 13, 0, 69, 73, 22, 0, 73, 2, 0, 73, 13, 0, 69, 73, 23, 0, 73, 2, 0, 73, 13, 0, 69, 73, 24, 0, 73, 2, 0, 73, 13, 0, 69, 73, 25, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 26, 0, 73, 2, 0, 73, 13, 0, 69, 73, 27, 0, 73, 2, 0, 73, 13, 0, 69, 73, 28, 0, 73, 2, 0, 73, 13, 0, 69, 73, 29, 0, 73, 2, 0, 73, 13, 0, 69, 73, 30, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 31, 0, 73, 2, 0, 73, 13, 0, 69, 73, 32, 0, 73, 2, 0, 73, 13, 0, 69, 73, 33, 0, 73, 2, 0, 73, 13, 0, 69, 73, 34, 0, 73, 2, 0, 73, 13, 0, 69, 73, 35, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 36, 0, 73, 2, 0, 73, 13, 0, 69, 73, 37, 0, 73, 2, 0, 73, 13, 0, 69, 73, 38, 0, 73, 2, 0, 73, 13, 0, 69, 73, 39, 0, 73, 2, 0, 73, 13, 0, 69, 73, 40, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 41, 0, 73, 2, 0, 73, 13, 0, 69, 73, 42, 0, 73, 2, 0, 73, 13, 0, 69, 73, 43, 0, 73, 2, 0, 73, 13, 0, 69, 73, 44, 0, 73, 2, 0, 73, 13, 0, 69, 73, 45, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 46, 0, 73, 2, 0, 73, 13, 0, 69, 73, 47, 0, 73, 2, 0, 73, 13, 0, 69, 73, 48, 0, 73, 2, 0, 73, 13, 0, 69, 73, 49, 0, 73, 2, 0, 73, 13, 0, 69, 73, 50, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 51, 0, 73, 2, 0, 73, 13, 0, 69, 73, 52, 0, 73, 2, 0, 73, 13, 0, 69, 73, 53, 0, 73, 2, 0, 73, 13, 0, 69, 73, 54, 0, 73, 2, 0, 73, 13, 0, 69, 73, 55, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 56, 0, 73, 2, 0, 73, 13, 0, 69, 73, 57, 0, 73, 2, 0, 73, 13, 0, 69, 73, 58, 0, 73, 2, 0, 73, 13, 0, 69, 73, 59, 0, 73, 2, 0, 73, 13, 0, 69, 73, 60, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 61, 0, 73, 2, 0, 73, 13, 0, 69, 73, 62, 0, 73, 2, 0, 73, 13, 0, 69, 73, 63, 0, 73, 2, 0, 73, 13, 0, 69, 73, 64, 0, 73, 2, 0, 73, 13, 0, 69, 73, 65, 0, 73, 2, 0, 73, - 13, 0, 69, 73, 66, 0, 73, 2, 0, 73, 13, 0, 69, 73, 67, 0, 73, 2, 0, 73, 13, 0, 69, 73, 68, 0, 73, 2, 0, 73, 13, 0, 69, 77, 3, 1, 98, 76, 73, 29, 0, 69, 73, 0, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 6, 0, 73, 2, 0, 73, 62, 0, 69, 73, 7, 0, 73, 2, 0, 73, 62, 0, 69, 73, 8, 0, 73, 2, 0, 73, 62, 0, 69, 73, 9, 0, 73, 2, 0, 73, 62, 0, 69, 73, 10, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 11, 0, 73, 2, 0, 73, 62, 0, 69, 73, 12, 0, 73, 2, 0, 73, 62, 0, 69, 73, 13, 0, 73, 2, 0, 73, 62, 0, 69, 73, 14, 0, 73, 2, 0, 73, 62, 0, 69, 73, 15, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 16, 0, 73, 2, 0, 73, 62, 0, 69, 73, 17, 0, 73, 2, 0, 73, 62, 0, 69, 73, 18, 0, 73, 2, 0, 73, 62, 0, 69, 73, 19, 0, 73, 2, 0, 73, 62, 0, 69, 73, 20, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 21, 0, 73, 2, 0, 73, 62, 0, 69, 73, 22, 0, 73, 2, 0, 73, 62, 0, 69, 73, 23, 0, 73, 2, 0, 73, 62, 0, 69, 73, 24, 0, 73, 2, 0, 73, 62, 0, 69, 73, 25, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 26, 0, 73, 2, 0, 73, 62, 0, 69, 73, 27, 0, 73, 2, 0, 73, 62, 0, 69, 73, 28, 0, 73, 2, 0, 73, 62, 0, 69, 73, 29, 0, 73, 2, 0, 73, 62, 0, 69, 73, 30, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 31, 0, 73, 2, 0, 73, 62, 0, 69, 73, 32, 0, 73, 2, 0, 73, 62, 0, 69, 73, 33, 0, 73, 2, 0, 73, 62, 0, 69, 73, 34, 0, 73, 2, 0, 73, 62, 0, 69, 73, 35, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 36, 0, 73, 2, 0, 73, 62, 0, 69, 73, 37, 0, 73, 2, 0, 73, 62, 0, 69, 73, 38, 0, 73, 2, 0, 73, 62, 0, 69, 73, 39, 0, 73, 2, 0, 73, 62, 0, 69, 73, 40, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 41, 0, 73, 2, 0, 73, 62, 0, 69, 73, 42, 0, 73, 2, 0, 73, 62, 0, 69, 73, 43, 0, 73, 2, 0, 73, 62, 0, 69, 73, 44, 0, 73, 2, 0, 73, 62, 0, 69, 73, 45, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 46, 0, 73, 2, 0, 73, 62, 0, 69, 73, 47, 0, 73, 2, 0, 73, 62, 0, 69, 73, 48, 0, 73, 2, 0, 73, 62, 0, 69, 73, 49, 0, 73, 2, 0, 73, 62, 0, 69, 73, 50, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 51, 0, 73, 2, 0, 73, 62, 0, 69, 73, 52, 0, 73, 2, 0, 73, 62, 0, 69, 73, 53, 0, 73, 2, 0, 73, 62, 0, 69, 73, 54, 0, 73, 2, 0, 73, 62, 0, 69, 73, 55, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 56, 0, 73, 2, 0, 73, 62, 0, 69, 73, 57, 0, 73, 2, 0, 73, 62, 0, 69, 73, 58, 0, 73, 2, 0, 73, 62, 0, 69, 73, 59, 0, 73, 2, 0, 73, 62, 0, 69, 73, 60, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 61, 0, 73, 2, 0, 73, 62, 0, 69, 73, 62, 0, 73, 2, 0, 73, 62, 0, 69, 73, 63, 0, 73, 2, 0, 73, 62, 0, 69, 73, 64, 0, 73, 2, 0, 73, 62, 0, 69, 73, 65, 0, 73, 2, 0, 73, 62, - 0, 69, 73, 66, 0, 73, 2, 0, 73, 62, 0, 69, 73, 67, 0, 73, 2, 0, 73, 62, 0, 69, 73, 68, 0, 73, 2, 0, 73, 62, 0, 69, 77, 3, 1, 98, 76, 73, 30, 0, 69, 73, 0, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 6, 0, 73, 2, 0, 73, 2, 0, 69, 73, 7, 0, 73, 2, 0, 73, 2, 0, 69, 73, 8, 0, 73, 2, 0, 73, 2, 0, 69, 73, 9, 0, 73, 2, 0, 73, 2, 0, 69, 73, 10, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 11, 0, 73, 2, 0, 73, 2, 0, 69, 73, 12, 0, 73, 2, 0, 73, 2, 0, 69, 73, 13, 0, 73, 2, 0, 73, 2, 0, 69, 73, 14, 0, 73, 2, 0, 73, 2, 0, 69, 73, 15, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 16, 0, 73, 2, 0, 73, 2, 0, 69, 73, 17, 0, 73, 2, 0, 73, 2, 0, 69, 73, 18, 0, 73, 2, 0, 73, 2, 0, 69, 73, 19, 0, 73, 2, 0, 73, 2, 0, 69, 73, 20, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 21, 0, 73, 2, 0, 73, 2, 0, 69, 73, 22, 0, 73, 2, 0, 73, 2, 0, 69, 73, 23, 0, 73, 2, 0, 73, 2, 0, 69, 73, 24, 0, 73, 2, 0, 73, 2, 0, 69, 73, 25, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 26, 0, 73, 2, 0, 73, 2, 0, 69, 73, 27, 0, 73, 2, 0, 73, 2, 0, 69, 73, 28, 0, 73, 2, 0, 73, 2, 0, 69, 73, 29, 0, 73, 2, 0, 73, 2, 0, 69, 73, 30, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 31, 0, 73, 2, 0, 73, 2, 0, 69, 73, 32, 0, 73, 2, 0, 73, 2, 0, 69, 73, 33, 0, 73, 2, 0, 73, 2, 0, 69, 73, 34, 0, 73, 2, 0, 73, 2, 0, 69, 73, 35, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 36, 0, 73, 2, 0, 73, 2, 0, 69, 73, 37, 0, 73, 2, 0, 73, 2, 0, 69, 73, 38, 0, 73, 2, 0, 73, 2, 0, 69, 73, 39, 0, 73, 2, 0, 73, 2, 0, 69, 73, 40, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 41, 0, 73, 2, 0, 73, 2, 0, 69, 73, 42, 0, 73, 2, 0, 73, 2, 0, 69, 73, 43, 0, 73, 2, 0, 73, 2, 0, 69, 73, 44, 0, 73, 2, 0, 73, 2, 0, 69, 73, 45, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 46, 0, 73, 2, 0, 73, 2, 0, 69, 73, 47, 0, 73, 2, 0, 73, 2, 0, 69, 73, 48, 0, 73, 2, 0, 73, 2, 0, 69, 73, 49, 0, 73, 2, 0, 73, 2, 0, 69, 73, 50, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 51, 0, 73, 2, 0, 73, 2, 0, 69, 73, 52, 0, 73, 2, 0, 73, 2, 0, 69, 73, 53, 0, 73, 2, 0, 73, 2, 0, 69, 73, 54, 0, 73, 2, 0, 73, 2, 0, 69, 73, 55, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 56, 0, 73, 2, 0, 73, 2, 0, 69, 73, 57, 0, 73, 2, 0, 73, 2, 0, 69, 73, 58, 0, 73, 2, 0, 73, 2, 0, 69, 73, 59, 0, 73, 2, 0, 73, 2, 0, 69, 73, 60, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 61, 0, 73, 2, 0, 73, 2, 0, 69, 73, 62, 0, 73, 2, 0, 73, 2, 0, 69, 73, 63, 0, 73, 2, 0, 73, 2, 0, 69, 73, 64, 0, 73, 2, 0, 73, 2, 0, 69, 73, 65, 0, 73, 2, 0, 73, 2, 0, - 69, 73, 66, 0, 73, 2, 0, 73, 2, 0, 69, 73, 67, 0, 73, 2, 0, 73, 2, 0, 69, 73, 68, 0, 73, 2, 0, 73, 2, 0, 69, 77, 3, 1, 98, 76, 73, 31, 0, 69, 73, 0, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 6, 0, 73, 2, 0, 73, 45, 0, 69, 73, 7, 0, 73, 2, 0, 73, 45, 0, 69, 73, 8, 0, 73, 2, 0, 73, 45, 0, 69, 73, 9, 0, 73, 2, 0, 73, 45, 0, 69, 73, 10, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 11, 0, 73, 2, 0, 73, 45, 0, 69, 73, 12, 0, 73, 2, 0, 73, 45, 0, 69, 73, 13, 0, 73, 2, 0, 73, 45, 0, 69, 73, 14, 0, 73, 2, 0, 73, 45, 0, 69, 73, 15, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 16, 0, 73, 2, 0, 73, 45, 0, 69, 73, 17, 0, 73, 2, 0, 73, 45, 0, 69, 73, 18, 0, 73, 2, 0, 73, 45, 0, 69, 73, 19, 0, 73, 2, 0, 73, 45, 0, 69, 73, 20, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 21, 0, 73, 2, 0, 73, 45, 0, 69, 73, 22, 0, 73, 2, 0, 73, 45, 0, 69, 73, 23, 0, 73, 2, 0, 73, 45, 0, 69, 73, 24, 0, 73, 2, 0, 73, 45, 0, 69, 73, 25, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 26, 0, 73, 2, 0, 73, 45, 0, 69, 73, 27, 0, 73, 2, 0, 73, 45, 0, 69, 73, 28, 0, 73, 2, 0, 73, 45, 0, 69, 73, 29, 0, 73, 2, 0, 73, 45, 0, 69, 73, 30, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 31, 0, 73, 2, 0, 73, 45, 0, 69, 73, 32, 0, 73, 2, 0, 73, 45, 0, 69, 73, 33, 0, 73, 2, 0, 73, 45, 0, 69, 73, 34, 0, 73, 2, 0, 73, 45, 0, 69, 73, 35, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 36, 0, 73, 2, 0, 73, 45, 0, 69, 73, 37, 0, 73, 2, 0, 73, 45, 0, 69, 73, 38, 0, 73, 2, 0, 73, 45, 0, 69, 73, 39, 0, 73, 2, 0, 73, 45, 0, 69, 73, 40, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 41, 0, 73, 2, 0, 73, 45, 0, 69, 73, 42, 0, 73, 2, 0, 73, 45, 0, 69, 73, 43, 0, 73, 2, 0, 73, 45, 0, 69, 73, 44, 0, 73, 2, 0, 73, 45, 0, 69, 73, 45, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 46, 0, 73, 2, 0, 73, 45, 0, 69, 73, 47, 0, 73, 2, 0, 73, 45, 0, 69, 73, 48, 0, 73, 2, 0, 73, 45, 0, 69, 73, 49, 0, 73, 2, 0, 73, 45, 0, 69, 73, 50, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 51, 0, 73, 2, 0, 73, 45, 0, 69, 73, 52, 0, 73, 2, 0, 73, 45, 0, 69, 73, 53, 0, 73, 2, 0, 73, 45, 0, 69, 73, 54, 0, 73, 2, 0, 73, 45, 0, 69, 73, 55, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 56, 0, 73, 2, 0, 73, 45, 0, 69, 73, 57, 0, 73, 2, 0, 73, 45, 0, 69, 73, 58, 0, 73, 2, 0, 73, 45, 0, 69, 73, 59, 0, 73, 2, 0, 73, 45, 0, 69, 73, 60, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 61, 0, 73, 2, 0, 73, 45, 0, 69, 73, 62, 0, 73, 2, 0, 73, 45, 0, 69, 73, 63, 0, 73, 2, 0, 73, 45, 0, 69, 73, 64, 0, 73, 2, 0, 73, 45, 0, 69, 73, 65, 0, 73, 2, 0, 73, 45, 0, 69, - 73, 66, 0, 73, 2, 0, 73, 45, 0, 69, 73, 67, 0, 73, 2, 0, 73, 45, 0, 69, 73, 68, 0, 73, 2, 0, 73, 45, 0, 69, 77, 3, 1, 98, 76, 73, 32, 0, 69, 73, 0, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 6, 0, 73, 2, 0, 73, 47, 0, 69, 73, 7, 0, 73, 2, 0, 73, 47, 0, 69, 73, 8, 0, 73, 2, 0, 73, 47, 0, 69, 73, 9, 0, 73, 2, 0, 73, 47, 0, 69, 73, 10, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 11, 0, 73, 2, 0, 73, 47, 0, 69, 73, 12, 0, 73, 2, 0, 73, 47, 0, 69, 73, 13, 0, 73, 2, 0, 73, 47, 0, 69, 73, 14, 0, 73, 2, 0, 73, 47, 0, 69, 73, 15, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 16, 0, 73, 2, 0, 73, 47, 0, 69, 73, 17, 0, 73, 2, 0, 73, 47, 0, 69, 73, 18, 0, 73, 2, 0, 73, 47, 0, 69, 73, 19, 0, 73, 2, 0, 73, 47, 0, 69, 73, 20, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 21, 0, 73, 2, 0, 73, 47, 0, 69, 73, 22, 0, 73, 2, 0, 73, 47, 0, 69, 73, 23, 0, 73, 2, 0, 73, 47, 0, 69, 73, 24, 0, 73, 2, 0, 73, 47, 0, 69, 73, 25, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 26, 0, 73, 2, 0, 73, 47, 0, 69, 73, 27, 0, 73, 2, 0, 73, 47, 0, 69, 73, 28, 0, 73, 2, 0, 73, 47, 0, 69, 73, 29, 0, 73, 2, 0, 73, 47, 0, 69, 73, 30, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 31, 0, 73, 2, 0, 73, 47, 0, 69, 73, 32, 0, 73, 2, 0, 73, 47, 0, 69, 73, 33, 0, 73, 2, 0, 73, 47, 0, 69, 73, 34, 0, 73, 2, 0, 73, 47, 0, 69, 73, 35, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 36, 0, 73, 2, 0, 73, 47, 0, 69, 73, 37, 0, 73, 2, 0, 73, 47, 0, 69, 73, 38, 0, 73, 2, 0, 73, 47, 0, 69, 73, 39, 0, 73, 2, 0, 73, 47, 0, 69, 73, 40, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 41, 0, 73, 2, 0, 73, 47, 0, 69, 73, 42, 0, 73, 2, 0, 73, 47, 0, 69, 73, 43, 0, 73, 2, 0, 73, 47, 0, 69, 73, 44, 0, 73, 2, 0, 73, 47, 0, 69, 73, 45, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 46, 0, 73, 2, 0, 73, 47, 0, 69, 73, 47, 0, 73, 2, 0, 73, 47, 0, 69, 73, 48, 0, 73, 2, 0, 73, 47, 0, 69, 73, 49, 0, 73, 2, 0, 73, 47, 0, 69, 73, 50, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 51, 0, 73, 2, 0, 73, 47, 0, 69, 73, 52, 0, 73, 2, 0, 73, 47, 0, 69, 73, 53, 0, 73, 2, 0, 73, 47, 0, 69, 73, 54, 0, 73, 2, 0, 73, 47, 0, 69, 73, 55, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 56, 0, 73, 2, 0, 73, 47, 0, 69, 73, 57, 0, 73, 2, 0, 73, 47, 0, 69, 73, 58, 0, 73, 2, 0, 73, 47, 0, 69, 73, 59, 0, 73, 2, 0, 73, 47, 0, 69, 73, 60, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 61, 0, 73, 2, 0, 73, 47, 0, 69, 73, 62, 0, 73, 2, 0, 73, 47, 0, 69, 73, 63, 0, 73, 2, 0, 73, 47, 0, 69, 73, 64, 0, 73, 2, 0, 73, 47, 0, 69, 73, 65, 0, 73, 2, 0, 73, 47, 0, 69, 73, - 66, 0, 73, 2, 0, 73, 47, 0, 69, 73, 67, 0, 73, 2, 0, 73, 47, 0, 69, 73, 68, 0, 73, 2, 0, 73, 47, 0, 69, 77, 3, 1, 98, 76, 73, 33, 0, 69, 73, 0, 0, 73, 2, 0, 73, 21, 0, 69, 73, 6, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 7, 0, 73, 2, 0, 73, 21, 0, 69, 73, 8, 0, 73, 2, 0, 73, 21, 0, 69, 73, 9, 0, 73, 2, 0, 73, 21, 0, 69, 73, 10, 0, 73, 2, 0, 73, 21, 0, 69, 73, 11, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 12, 0, 73, 2, 0, 73, 21, 0, 69, 73, 13, 0, 73, 2, 0, 73, 21, 0, 69, 73, 14, 0, 73, 2, 0, 73, 21, 0, 69, 73, 15, 0, 73, 2, 0, 73, 21, 0, 69, 73, 16, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 17, 0, 73, 2, 0, 73, 21, 0, 69, 73, 18, 0, 73, 2, 0, 73, 21, 0, 69, 73, 19, 0, 73, 2, 0, 73, 21, 0, 69, 73, 20, 0, 73, 2, 0, 73, 21, 0, 69, 73, 21, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 22, 0, 73, 2, 0, 73, 21, 0, 69, 73, 23, 0, 73, 2, 0, 73, 21, 0, 69, 73, 24, 0, 73, 2, 0, 73, 21, 0, 69, 73, 25, 0, 73, 2, 0, 73, 21, 0, 69, 73, 26, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 27, 0, 73, 2, 0, 73, 21, 0, 69, 73, 28, 0, 73, 2, 0, 73, 21, 0, 69, 73, 29, 0, 73, 2, 0, 73, 21, 0, 69, 73, 30, 0, 73, 2, 0, 73, 21, 0, 69, 73, 31, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 32, 0, 73, 2, 0, 73, 21, 0, 69, 73, 33, 0, 73, 2, 0, 73, 21, 0, 69, 73, 34, 0, 73, 2, 0, 73, 21, 0, 69, 73, 35, 0, 73, 2, 0, 73, 21, 0, 69, 73, 36, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 37, 0, 73, 2, 0, 73, 21, 0, 69, 73, 38, 0, 73, 2, 0, 73, 21, 0, 69, 73, 39, 0, 73, 2, 0, 73, 21, 0, 69, 73, 40, 0, 73, 2, 0, 73, 21, 0, 69, 73, 41, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 42, 0, 73, 2, 0, 73, 21, 0, 69, 73, 43, 0, 73, 2, 0, 73, 21, 0, 69, 73, 44, 0, 73, 2, 0, 73, 21, 0, 69, 73, 45, 0, 73, 2, 0, 73, 21, 0, 69, 73, 46, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 47, 0, 73, 2, 0, 73, 21, 0, 69, 73, 48, 0, 73, 2, 0, 73, 21, 0, 69, 73, 49, 0, 73, 2, 0, 73, 21, 0, 69, 73, 50, 0, 73, 2, 0, 73, 21, 0, 69, 73, 51, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 52, 0, 73, 2, 0, 73, 21, 0, 69, 73, 53, 0, 73, 2, 0, 73, 21, 0, 69, 73, 54, 0, 73, 2, 0, 73, 21, 0, 69, 73, 55, 0, 73, 2, 0, 73, 21, 0, 69, 73, 56, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 57, 0, 73, 2, 0, 73, 21, 0, 69, 73, 58, 0, 73, 2, 0, 73, 21, 0, 69, 73, 59, 0, 73, 2, 0, 73, 21, 0, 69, 73, 60, 0, 73, 2, 0, 73, 21, 0, 69, 73, 61, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 62, 0, 73, 2, 0, 73, 21, 0, 69, 73, 63, 0, 73, 2, 0, 73, 21, 0, 69, 73, 64, 0, 73, 2, 0, 73, 21, 0, 69, 73, 65, 0, 73, 2, 0, 73, 21, 0, 69, 73, 66, - 0, 73, 2, 0, 73, 21, 0, 69, 73, 67, 0, 73, 2, 0, 73, 21, 0, 69, 73, 68, 0, 73, 2, 0, 73, 21, 0, 69, 77, 3, 1, 98, 76, 73, 34, 0, 69, 73, 0, 0, 73, 2, 0, 73, 38, 0, 69, 73, 6, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 7, 0, 73, 2, 0, 73, 38, 0, 69, 73, 8, 0, 73, 2, 0, 73, 38, 0, 69, 73, 9, 0, 73, 2, 0, 73, 38, 0, 69, 73, 10, 0, 73, 2, 0, 73, 38, 0, 69, 73, 11, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 12, 0, 73, 2, 0, 73, 38, 0, 69, 73, 13, 0, 73, 2, 0, 73, 38, 0, 69, 73, 14, 0, 73, 2, 0, 73, 38, 0, 69, 73, 15, 0, 73, 2, 0, 73, 38, 0, 69, 73, 16, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 17, 0, 73, 2, 0, 73, 38, 0, 69, 73, 18, 0, 73, 2, 0, 73, 38, 0, 69, 73, 19, 0, 73, 2, 0, 73, 38, 0, 69, 73, 20, 0, 73, 2, 0, 73, 38, 0, 69, 73, 21, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 22, 0, 73, 2, 0, 73, 38, 0, 69, 73, 23, 0, 73, 2, 0, 73, 38, 0, 69, 73, 24, 0, 73, 2, 0, 73, 38, 0, 69, 73, 25, 0, 73, 2, 0, 73, 38, 0, 69, 73, 26, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 27, 0, 73, 2, 0, 73, 38, 0, 69, 73, 28, 0, 73, 2, 0, 73, 38, 0, 69, 73, 29, 0, 73, 2, 0, 73, 38, 0, 69, 73, 30, 0, 73, 2, 0, 73, 38, 0, 69, 73, 31, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 32, 0, 73, 2, 0, 73, 38, 0, 69, 73, 33, 0, 73, 2, 0, 73, 38, 0, 69, 73, 34, 0, 73, 2, 0, 73, 38, 0, 69, 73, 35, 0, 73, 2, 0, 73, 38, 0, 69, 73, 36, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 37, 0, 73, 2, 0, 73, 38, 0, 69, 73, 38, 0, 73, 2, 0, 73, 38, 0, 69, 73, 39, 0, 73, 2, 0, 73, 38, 0, 69, 73, 40, 0, 73, 2, 0, 73, 38, 0, 69, 73, 41, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 42, 0, 73, 2, 0, 73, 38, 0, 69, 73, 43, 0, 73, 2, 0, 73, 38, 0, 69, 73, 44, 0, 73, 2, 0, 73, 38, 0, 69, 73, 45, 0, 73, 2, 0, 73, 38, 0, 69, 73, 46, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 47, 0, 73, 2, 0, 73, 38, 0, 69, 73, 48, 0, 73, 2, 0, 73, 38, 0, 69, 73, 49, 0, 73, 2, 0, 73, 38, 0, 69, 73, 50, 0, 73, 2, 0, 73, 38, 0, 69, 73, 51, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 52, 0, 73, 2, 0, 73, 38, 0, 69, 73, 53, 0, 73, 2, 0, 73, 38, 0, 69, 73, 54, 0, 73, 2, 0, 73, 38, 0, 69, 73, 55, 0, 73, 2, 0, 73, 38, 0, 69, 73, 56, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 57, 0, 73, 2, 0, 73, 38, 0, 69, 73, 58, 0, 73, 2, 0, 73, 38, 0, 69, 73, 59, 0, 73, 2, 0, 73, 38, 0, 69, 73, 60, 0, 73, 2, 0, 73, 38, 0, 69, 73, 61, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 62, 0, 73, 2, 0, 73, 38, 0, 69, 73, 63, 0, 73, 2, 0, 73, 38, 0, 69, 73, 64, 0, 73, 2, 0, 73, 38, 0, 69, 73, 65, 0, 73, 2, 0, 73, 38, 0, 69, 73, 66, 0, - 73, 2, 0, 73, 38, 0, 69, 73, 67, 0, 73, 2, 0, 73, 38, 0, 69, 73, 68, 0, 73, 2, 0, 73, 38, 0, 69, 77, 3, 1, 98, 76, 73, 35, 0, 69, 73, 0, 0, 73, 2, 0, 73, 39, 0, 69, 73, 6, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 7, 0, 73, 2, 0, 73, 39, 0, 69, 73, 8, 0, 73, 2, 0, 73, 39, 0, 69, 73, 9, 0, 73, 2, 0, 73, 39, 0, 69, 73, 10, 0, 73, 2, 0, 73, 39, 0, 69, 73, 11, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 12, 0, 73, 2, 0, 73, 39, 0, 69, 73, 13, 0, 73, 2, 0, 73, 39, 0, 69, 73, 14, 0, 73, 2, 0, 73, 39, 0, 69, 73, 15, 0, 73, 2, 0, 73, 39, 0, 69, 73, 16, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 17, 0, 73, 2, 0, 73, 39, 0, 69, 73, 18, 0, 73, 2, 0, 73, 39, 0, 69, 73, 19, 0, 73, 2, 0, 73, 39, 0, 69, 73, 20, 0, 73, 2, 0, 73, 39, 0, 69, 73, 21, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 22, 0, 73, 2, 0, 73, 39, 0, 69, 73, 23, 0, 73, 2, 0, 73, 39, 0, 69, 73, 24, 0, 73, 2, 0, 73, 39, 0, 69, 73, 25, 0, 73, 2, 0, 73, 39, 0, 69, 73, 26, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 27, 0, 73, 2, 0, 73, 39, 0, 69, 73, 28, 0, 73, 2, 0, 73, 39, 0, 69, 73, 29, 0, 73, 2, 0, 73, 39, 0, 69, 73, 30, 0, 73, 2, 0, 73, 39, 0, 69, 73, 31, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 32, 0, 73, 2, 0, 73, 39, 0, 69, 73, 33, 0, 73, 2, 0, 73, 39, 0, 69, 73, 34, 0, 73, 2, 0, 73, 39, 0, 69, 73, 35, 0, 73, 2, 0, 73, 39, 0, 69, 73, 36, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 37, 0, 73, 2, 0, 73, 39, 0, 69, 73, 38, 0, 73, 2, 0, 73, 39, 0, 69, 73, 39, 0, 73, 2, 0, 73, 39, 0, 69, 73, 40, 0, 73, 2, 0, 73, 39, 0, 69, 73, 41, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 42, 0, 73, 2, 0, 73, 39, 0, 69, 73, 43, 0, 73, 2, 0, 73, 39, 0, 69, 73, 44, 0, 73, 2, 0, 73, 39, 0, 69, 73, 45, 0, 73, 2, 0, 73, 39, 0, 69, 73, 46, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 47, 0, 73, 2, 0, 73, 39, 0, 69, 73, 48, 0, 73, 2, 0, 73, 39, 0, 69, 73, 49, 0, 73, 2, 0, 73, 39, 0, 69, 73, 50, 0, 73, 2, 0, 73, 39, 0, 69, 73, 51, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 52, 0, 73, 2, 0, 73, 39, 0, 69, 73, 53, 0, 73, 2, 0, 73, 39, 0, 69, 73, 54, 0, 73, 2, 0, 73, 39, 0, 69, 73, 55, 0, 73, 2, 0, 73, 39, 0, 69, 73, 56, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 57, 0, 73, 2, 0, 73, 39, 0, 69, 73, 58, 0, 73, 2, 0, 73, 39, 0, 69, 73, 59, 0, 73, 2, 0, 73, 39, 0, 69, 73, 60, 0, 73, 2, 0, 73, 39, 0, 69, 73, 61, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 62, 0, 73, 2, 0, 73, 39, 0, 69, 73, 63, 0, 73, 2, 0, 73, 39, 0, 69, 73, 64, 0, 73, 2, 0, 73, 39, 0, 69, 73, 65, 0, 73, 2, 0, 73, 39, 0, 69, 73, 66, 0, 73, - 2, 0, 73, 39, 0, 69, 73, 67, 0, 73, 2, 0, 73, 39, 0, 69, 73, 68, 0, 73, 2, 0, 73, 39, 0, 69, 77, 3, 1, 98, 76, 73, 36, 0, 69, 73, 0, 0, 73, 2, 0, 73, 14, 0, 69, 73, 6, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 7, 0, 73, 2, 0, 73, 14, 0, 69, 73, 8, 0, 73, 2, 0, 73, 14, 0, 69, 73, 9, 0, 73, 2, 0, 73, 14, 0, 69, 73, 10, 0, 73, 2, 0, 73, 14, 0, 69, 73, 11, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 12, 0, 73, 2, 0, 73, 14, 0, 69, 73, 13, 0, 73, 2, 0, 73, 14, 0, 69, 73, 14, 0, 73, 2, 0, 73, 14, 0, 69, 73, 15, 0, 73, 2, 0, 73, 14, 0, 69, 73, 16, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 17, 0, 73, 2, 0, 73, 14, 0, 69, 73, 18, 0, 73, 2, 0, 73, 14, 0, 69, 73, 19, 0, 73, 2, 0, 73, 14, 0, 69, 73, 20, 0, 73, 2, 0, 73, 14, 0, 69, 73, 21, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 22, 0, 73, 2, 0, 73, 14, 0, 69, 73, 23, 0, 73, 2, 0, 73, 14, 0, 69, 73, 24, 0, 73, 2, 0, 73, 14, 0, 69, 73, 25, 0, 73, 2, 0, 73, 14, 0, 69, 73, 26, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 27, 0, 73, 2, 0, 73, 14, 0, 69, 73, 28, 0, 73, 2, 0, 73, 14, 0, 69, 73, 29, 0, 73, 2, 0, 73, 14, 0, 69, 73, 30, 0, 73, 2, 0, 73, 14, 0, 69, 73, 31, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 32, 0, 73, 2, 0, 73, 14, 0, 69, 73, 33, 0, 73, 2, 0, 73, 14, 0, 69, 73, 34, 0, 73, 2, 0, 73, 14, 0, 69, 73, 35, 0, 73, 2, 0, 73, 14, 0, 69, 73, 36, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 37, 0, 73, 2, 0, 73, 14, 0, 69, 73, 38, 0, 73, 2, 0, 73, 14, 0, 69, 73, 39, 0, 73, 2, 0, 73, 14, 0, 69, 73, 40, 0, 73, 2, 0, 73, 14, 0, 69, 73, 41, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 42, 0, 73, 2, 0, 73, 14, 0, 69, 73, 43, 0, 73, 2, 0, 73, 14, 0, 69, 73, 44, 0, 73, 2, 0, 73, 14, 0, 69, 73, 45, 0, 73, 2, 0, 73, 14, 0, 69, 73, 46, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 47, 0, 73, 2, 0, 73, 14, 0, 69, 73, 48, 0, 73, 2, 0, 73, 14, 0, 69, 73, 49, 0, 73, 2, 0, 73, 14, 0, 69, 73, 50, 0, 73, 2, 0, 73, 14, 0, 69, 73, 51, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 52, 0, 73, 2, 0, 73, 14, 0, 69, 73, 53, 0, 73, 2, 0, 73, 14, 0, 69, 73, 54, 0, 73, 2, 0, 73, 14, 0, 69, 73, 55, 0, 73, 2, 0, 73, 14, 0, 69, 73, 56, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 57, 0, 73, 2, 0, 73, 14, 0, 69, 73, 58, 0, 73, 2, 0, 73, 14, 0, 69, 73, 59, 0, 73, 2, 0, 73, 14, 0, 69, 73, 60, 0, 73, 2, 0, 73, 14, 0, 69, 73, 61, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 62, 0, 73, 2, 0, 73, 14, 0, 69, 73, 63, 0, 73, 2, 0, 73, 14, 0, 69, 73, 64, 0, 73, 2, 0, 73, 14, 0, 69, 73, 65, 0, 73, 2, 0, 73, 14, 0, 69, 73, 66, 0, 73, 2, - 0, 73, 14, 0, 69, 73, 67, 0, 73, 2, 0, 73, 14, 0, 69, 73, 68, 0, 73, 2, 0, 73, 14, 0, 69, 77, 3, 1, 98, 76, 73, 37, 0, 69, 73, 0, 0, 73, 2, 0, 73, 29, 0, 69, 73, 6, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 7, 0, 73, 2, 0, 73, 29, 0, 69, 73, 8, 0, 73, 2, 0, 73, 29, 0, 69, 73, 9, 0, 73, 2, 0, 73, 29, 0, 69, 73, 10, 0, 73, 2, 0, 73, 29, 0, 69, 73, 11, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 12, 0, 73, 2, 0, 73, 29, 0, 69, 73, 13, 0, 73, 2, 0, 73, 29, 0, 69, 73, 14, 0, 73, 2, 0, 73, 29, 0, 69, 73, 15, 0, 73, 2, 0, 73, 29, 0, 69, 73, 16, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 17, 0, 73, 2, 0, 73, 29, 0, 69, 73, 18, 0, 73, 2, 0, 73, 29, 0, 69, 73, 19, 0, 73, 2, 0, 73, 29, 0, 69, 73, 20, 0, 73, 2, 0, 73, 29, 0, 69, 73, 21, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 22, 0, 73, 2, 0, 73, 29, 0, 69, 73, 23, 0, 73, 2, 0, 73, 29, 0, 69, 73, 24, 0, 73, 2, 0, 73, 29, 0, 69, 73, 25, 0, 73, 2, 0, 73, 29, 0, 69, 73, 26, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 27, 0, 73, 2, 0, 73, 29, 0, 69, 73, 28, 0, 73, 2, 0, 73, 29, 0, 69, 73, 29, 0, 73, 2, 0, 73, 29, 0, 69, 73, 30, 0, 73, 2, 0, 73, 29, 0, 69, 73, 31, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 32, 0, 73, 2, 0, 73, 29, 0, 69, 73, 33, 0, 73, 2, 0, 73, 29, 0, 69, 73, 34, 0, 73, 2, 0, 73, 29, 0, 69, 73, 35, 0, 73, 2, 0, 73, 29, 0, 69, 73, 36, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 37, 0, 73, 2, 0, 73, 29, 0, 69, 73, 38, 0, 73, 2, 0, 73, 29, 0, 69, 73, 39, 0, 73, 2, 0, 73, 29, 0, 69, 73, 40, 0, 73, 2, 0, 73, 29, 0, 69, 73, 41, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 42, 0, 73, 2, 0, 73, 29, 0, 69, 73, 43, 0, 73, 2, 0, 73, 29, 0, 69, 73, 44, 0, 73, 2, 0, 73, 29, 0, 69, 73, 45, 0, 73, 2, 0, 73, 29, 0, 69, 73, 46, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 47, 0, 73, 2, 0, 73, 29, 0, 69, 73, 48, 0, 73, 2, 0, 73, 29, 0, 69, 73, 49, 0, 73, 2, 0, 73, 29, 0, 69, 73, 50, 0, 73, 2, 0, 73, 29, 0, 69, 73, 51, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 52, 0, 73, 2, 0, 73, 29, 0, 69, 73, 53, 0, 73, 2, 0, 73, 29, 0, 69, 73, 54, 0, 73, 2, 0, 73, 29, 0, 69, 73, 55, 0, 73, 2, 0, 73, 29, 0, 69, 73, 56, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 57, 0, 73, 2, 0, 73, 29, 0, 69, 73, 58, 0, 73, 2, 0, 73, 29, 0, 69, 73, 59, 0, 73, 2, 0, 73, 29, 0, 69, 73, 60, 0, 73, 2, 0, 73, 29, 0, 69, 73, 61, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 62, 0, 73, 2, 0, 73, 29, 0, 69, 73, 63, 0, 73, 2, 0, 73, 29, 0, 69, 73, 64, 0, 73, 2, 0, 73, 29, 0, 69, 73, 65, 0, 73, 2, 0, 73, 29, 0, 69, 73, 66, 0, 73, 2, 0, - 73, 29, 0, 69, 73, 67, 0, 73, 2, 0, 73, 29, 0, 69, 73, 68, 0, 73, 2, 0, 73, 29, 0, 69, 77, 3, 1, 98, 76, 73, 38, 0, 69, 73, 0, 0, 73, 2, 0, 73, 30, 0, 69, 73, 6, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 7, 0, 73, 2, 0, 73, 30, 0, 69, 73, 8, 0, 73, 2, 0, 73, 30, 0, 69, 73, 9, 0, 73, 2, 0, 73, 30, 0, 69, 73, 10, 0, 73, 2, 0, 73, 30, 0, 69, 73, 11, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 12, 0, 73, 2, 0, 73, 30, 0, 69, 73, 13, 0, 73, 2, 0, 73, 30, 0, 69, 73, 14, 0, 73, 2, 0, 73, 30, 0, 69, 73, 15, 0, 73, 2, 0, 73, 30, 0, 69, 73, 16, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 17, 0, 73, 2, 0, 73, 30, 0, 69, 73, 18, 0, 73, 2, 0, 73, 30, 0, 69, 73, 19, 0, 73, 2, 0, 73, 30, 0, 69, 73, 20, 0, 73, 2, 0, 73, 30, 0, 69, 73, 21, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 22, 0, 73, 2, 0, 73, 30, 0, 69, 73, 23, 0, 73, 2, 0, 73, 30, 0, 69, 73, 24, 0, 73, 2, 0, 73, 30, 0, 69, 73, 25, 0, 73, 2, 0, 73, 30, 0, 69, 73, 26, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 27, 0, 73, 2, 0, 73, 30, 0, 69, 73, 28, 0, 73, 2, 0, 73, 30, 0, 69, 73, 29, 0, 73, 2, 0, 73, 30, 0, 69, 73, 30, 0, 73, 2, 0, 73, 30, 0, 69, 73, 31, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 32, 0, 73, 2, 0, 73, 30, 0, 69, 73, 33, 0, 73, 2, 0, 73, 30, 0, 69, 73, 34, 0, 73, 2, 0, 73, 30, 0, 69, 73, 35, 0, 73, 2, 0, 73, 30, 0, 69, 73, 36, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 37, 0, 73, 2, 0, 73, 30, 0, 69, 73, 38, 0, 73, 2, 0, 73, 30, 0, 69, 73, 39, 0, 73, 2, 0, 73, 30, 0, 69, 73, 40, 0, 73, 2, 0, 73, 30, 0, 69, 73, 41, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 42, 0, 73, 2, 0, 73, 30, 0, 69, 73, 43, 0, 73, 2, 0, 73, 30, 0, 69, 73, 44, 0, 73, 2, 0, 73, 30, 0, 69, 73, 45, 0, 73, 2, 0, 73, 30, 0, 69, 73, 46, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 47, 0, 73, 2, 0, 73, 30, 0, 69, 73, 48, 0, 73, 2, 0, 73, 30, 0, 69, 73, 49, 0, 73, 2, 0, 73, 30, 0, 69, 73, 50, 0, 73, 2, 0, 73, 30, 0, 69, 73, 51, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 52, 0, 73, 2, 0, 73, 30, 0, 69, 73, 53, 0, 73, 2, 0, 73, 30, 0, 69, 73, 54, 0, 73, 2, 0, 73, 30, 0, 69, 73, 55, 0, 73, 2, 0, 73, 30, 0, 69, 73, 56, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 57, 0, 73, 2, 0, 73, 30, 0, 69, 73, 58, 0, 73, 2, 0, 73, 30, 0, 69, 73, 59, 0, 73, 2, 0, 73, 30, 0, 69, 73, 60, 0, 73, 2, 0, 73, 30, 0, 69, 73, 61, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 62, 0, 73, 2, 0, 73, 30, 0, 69, 73, 63, 0, 73, 2, 0, 73, 30, 0, 69, 73, 64, 0, 73, 2, 0, 73, 30, 0, 69, 73, 65, 0, 73, 2, 0, 73, 30, 0, 69, 73, 66, 0, 73, 2, 0, 73, - 30, 0, 69, 73, 67, 0, 73, 2, 0, 73, 30, 0, 69, 73, 68, 0, 73, 2, 0, 73, 30, 0, 69, 77, 3, 1, 98, 76, 73, 39, 0, 69, 73, 0, 0, 73, 2, 0, 73, 34, 0, 69, 73, 6, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 7, 0, 73, 2, 0, 73, 34, 0, 69, 73, 8, 0, 73, 2, 0, 73, 34, 0, 69, 73, 9, 0, 73, 2, 0, 73, 34, 0, 69, 73, 10, 0, 73, 2, 0, 73, 34, 0, 69, 73, 11, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 12, 0, 73, 2, 0, 73, 34, 0, 69, 73, 13, 0, 73, 2, 0, 73, 34, 0, 69, 73, 14, 0, 73, 2, 0, 73, 34, 0, 69, 73, 15, 0, 73, 2, 0, 73, 34, 0, 69, 73, 16, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 17, 0, 73, 2, 0, 73, 34, 0, 69, 73, 18, 0, 73, 2, 0, 73, 34, 0, 69, 73, 19, 0, 73, 2, 0, 73, 34, 0, 69, 73, 20, 0, 73, 2, 0, 73, 34, 0, 69, 73, 21, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 22, 0, 73, 2, 0, 73, 34, 0, 69, 73, 23, 0, 73, 2, 0, 73, 34, 0, 69, 73, 24, 0, 73, 2, 0, 73, 34, 0, 69, 73, 25, 0, 73, 2, 0, 73, 34, 0, 69, 73, 26, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 27, 0, 73, 2, 0, 73, 34, 0, 69, 73, 28, 0, 73, 2, 0, 73, 34, 0, 69, 73, 29, 0, 73, 2, 0, 73, 34, 0, 69, 73, 30, 0, 73, 2, 0, 73, 34, 0, 69, 73, 31, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 32, 0, 73, 2, 0, 73, 34, 0, 69, 73, 33, 0, 73, 2, 0, 73, 34, 0, 69, 73, 34, 0, 73, 2, 0, 73, 34, 0, 69, 73, 35, 0, 73, 2, 0, 73, 34, 0, 69, 73, 36, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 37, 0, 73, 2, 0, 73, 34, 0, 69, 73, 38, 0, 73, 2, 0, 73, 34, 0, 69, 73, 39, 0, 73, 2, 0, 73, 34, 0, 69, 73, 40, 0, 73, 2, 0, 73, 34, 0, 69, 73, 41, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 42, 0, 73, 2, 0, 73, 34, 0, 69, 73, 43, 0, 73, 2, 0, 73, 34, 0, 69, 73, 44, 0, 73, 2, 0, 73, 34, 0, 69, 73, 45, 0, 73, 2, 0, 73, 34, 0, 69, 73, 46, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 47, 0, 73, 2, 0, 73, 34, 0, 69, 73, 48, 0, 73, 2, 0, 73, 34, 0, 69, 73, 49, 0, 73, 2, 0, 73, 34, 0, 69, 73, 50, 0, 73, 2, 0, 73, 34, 0, 69, 73, 51, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 52, 0, 73, 2, 0, 73, 34, 0, 69, 73, 53, 0, 73, 2, 0, 73, 34, 0, 69, 73, 54, 0, 73, 2, 0, 73, 34, 0, 69, 73, 55, 0, 73, 2, 0, 73, 34, 0, 69, 73, 56, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 57, 0, 73, 2, 0, 73, 34, 0, 69, 73, 58, 0, 73, 2, 0, 73, 34, 0, 69, 73, 59, 0, 73, 2, 0, 73, 34, 0, 69, 73, 60, 0, 73, 2, 0, 73, 34, 0, 69, 73, 61, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 62, 0, 73, 2, 0, 73, 34, 0, 69, 73, 63, 0, 73, 2, 0, 73, 34, 0, 69, 73, 64, 0, 73, 2, 0, 73, 34, 0, 69, 73, 65, 0, 73, 2, 0, 73, 34, 0, 69, 73, 66, 0, 73, 2, 0, 73, 34, - 0, 69, 73, 67, 0, 73, 2, 0, 73, 34, 0, 69, 73, 68, 0, 73, 2, 0, 73, 34, 0, 69, 77, 3, 1, 98, 76, 73, 40, 0, 69, 73, 0, 0, 73, 2, 0, 73, 35, 0, 69, 73, 6, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 7, 0, 73, 2, 0, 73, 35, 0, 69, 73, 8, 0, 73, 2, 0, 73, 35, 0, 69, 73, 9, 0, 73, 2, 0, 73, 35, 0, 69, 73, 10, 0, 73, 2, 0, 73, 35, 0, 69, 73, 11, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 12, 0, 73, 2, 0, 73, 35, 0, 69, 73, 13, 0, 73, 2, 0, 73, 35, 0, 69, 73, 14, 0, 73, 2, 0, 73, 35, 0, 69, 73, 15, 0, 73, 2, 0, 73, 35, 0, 69, 73, 16, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 17, 0, 73, 2, 0, 73, 35, 0, 69, 73, 18, 0, 73, 2, 0, 73, 35, 0, 69, 73, 19, 0, 73, 2, 0, 73, 35, 0, 69, 73, 20, 0, 73, 2, 0, 73, 35, 0, 69, 73, 21, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 22, 0, 73, 2, 0, 73, 35, 0, 69, 73, 23, 0, 73, 2, 0, 73, 35, 0, 69, 73, 24, 0, 73, 2, 0, 73, 35, 0, 69, 73, 25, 0, 73, 2, 0, 73, 35, 0, 69, 73, 26, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 27, 0, 73, 2, 0, 73, 35, 0, 69, 73, 28, 0, 73, 2, 0, 73, 35, 0, 69, 73, 29, 0, 73, 2, 0, 73, 35, 0, 69, 73, 30, 0, 73, 2, 0, 73, 35, 0, 69, 73, 31, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 32, 0, 73, 2, 0, 73, 35, 0, 69, 73, 33, 0, 73, 2, 0, 73, 35, 0, 69, 73, 34, 0, 73, 2, 0, 73, 35, 0, 69, 73, 35, 0, 73, 2, 0, 73, 35, 0, 69, 73, 36, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 37, 0, 73, 2, 0, 73, 35, 0, 69, 73, 38, 0, 73, 2, 0, 73, 35, 0, 69, 73, 39, 0, 73, 2, 0, 73, 35, 0, 69, 73, 40, 0, 73, 2, 0, 73, 35, 0, 69, 73, 41, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 42, 0, 73, 2, 0, 73, 35, 0, 69, 73, 43, 0, 73, 2, 0, 73, 35, 0, 69, 73, 44, 0, 73, 2, 0, 73, 35, 0, 69, 73, 45, 0, 73, 2, 0, 73, 35, 0, 69, 73, 46, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 47, 0, 73, 2, 0, 73, 35, 0, 69, 73, 48, 0, 73, 2, 0, 73, 35, 0, 69, 73, 49, 0, 73, 2, 0, 73, 35, 0, 69, 73, 50, 0, 73, 2, 0, 73, 35, 0, 69, 73, 51, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 52, 0, 73, 2, 0, 73, 35, 0, 69, 73, 53, 0, 73, 2, 0, 73, 35, 0, 69, 73, 54, 0, 73, 2, 0, 73, 35, 0, 69, 73, 55, 0, 73, 2, 0, 73, 35, 0, 69, 73, 56, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 57, 0, 73, 2, 0, 73, 35, 0, 69, 73, 58, 0, 73, 2, 0, 73, 35, 0, 69, 73, 59, 0, 73, 2, 0, 73, 35, 0, 69, 73, 60, 0, 73, 2, 0, 73, 35, 0, 69, 73, 61, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 62, 0, 73, 2, 0, 73, 35, 0, 69, 73, 63, 0, 73, 2, 0, 73, 35, 0, 69, 73, 64, 0, 73, 2, 0, 73, 35, 0, 69, 73, 65, 0, 73, 2, 0, 73, 35, 0, 69, 73, 66, 0, 73, 2, 0, 73, 35, 0, - 69, 73, 67, 0, 73, 2, 0, 73, 35, 0, 69, 73, 68, 0, 73, 2, 0, 73, 35, 0, 69, 77, 3, 1, 98, 76, 73, 41, 0, 69, 73, 0, 0, 73, 2, 0, 73, 23, 0, 69, 73, 6, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 7, 0, 73, 2, 0, 73, 23, 0, 69, 73, 8, 0, 73, 2, 0, 73, 23, 0, 69, 73, 9, 0, 73, 2, 0, 73, 23, 0, 69, 73, 10, 0, 73, 2, 0, 73, 23, 0, 69, 73, 11, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 12, 0, 73, 2, 0, 73, 23, 0, 69, 73, 13, 0, 73, 2, 0, 73, 23, 0, 69, 73, 14, 0, 73, 2, 0, 73, 23, 0, 69, 73, 15, 0, 73, 2, 0, 73, 23, 0, 69, 73, 16, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 17, 0, 73, 2, 0, 73, 23, 0, 69, 73, 18, 0, 73, 2, 0, 73, 23, 0, 69, 73, 19, 0, 73, 2, 0, 73, 23, 0, 69, 73, 20, 0, 73, 2, 0, 73, 23, 0, 69, 73, 21, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 22, 0, 73, 2, 0, 73, 23, 0, 69, 73, 23, 0, 73, 2, 0, 73, 23, 0, 69, 73, 24, 0, 73, 2, 0, 73, 23, 0, 69, 73, 25, 0, 73, 2, 0, 73, 23, 0, 69, 73, 26, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 27, 0, 73, 2, 0, 73, 23, 0, 69, 73, 28, 0, 73, 2, 0, 73, 23, 0, 69, 73, 29, 0, 73, 2, 0, 73, 23, 0, 69, 73, 30, 0, 73, 2, 0, 73, 23, 0, 69, 73, 31, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 32, 0, 73, 2, 0, 73, 23, 0, 69, 73, 33, 0, 73, 2, 0, 73, 23, 0, 69, 73, 34, 0, 73, 2, 0, 73, 23, 0, 69, 73, 35, 0, 73, 2, 0, 73, 23, 0, 69, 73, 36, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 37, 0, 73, 2, 0, 73, 23, 0, 69, 73, 38, 0, 73, 2, 0, 73, 23, 0, 69, 73, 39, 0, 73, 2, 0, 73, 23, 0, 69, 73, 40, 0, 73, 2, 0, 73, 23, 0, 69, 73, 41, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 42, 0, 73, 2, 0, 73, 23, 0, 69, 73, 43, 0, 73, 2, 0, 73, 23, 0, 69, 73, 44, 0, 73, 2, 0, 73, 23, 0, 69, 73, 45, 0, 73, 2, 0, 73, 23, 0, 69, 73, 46, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 47, 0, 73, 2, 0, 73, 23, 0, 69, 73, 48, 0, 73, 2, 0, 73, 23, 0, 69, 73, 49, 0, 73, 2, 0, 73, 23, 0, 69, 73, 50, 0, 73, 2, 0, 73, 23, 0, 69, 73, 51, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 52, 0, 73, 2, 0, 73, 23, 0, 69, 73, 53, 0, 73, 2, 0, 73, 23, 0, 69, 73, 54, 0, 73, 2, 0, 73, 23, 0, 69, 73, 55, 0, 73, 2, 0, 73, 23, 0, 69, 73, 56, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 57, 0, 73, 2, 0, 73, 23, 0, 69, 73, 58, 0, 73, 2, 0, 73, 23, 0, 69, 73, 59, 0, 73, 2, 0, 73, 23, 0, 69, 73, 60, 0, 73, 2, 0, 73, 23, 0, 69, 73, 61, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 62, 0, 73, 2, 0, 73, 23, 0, 69, 73, 63, 0, 73, 2, 0, 73, 23, 0, 69, 73, 64, 0, 73, 2, 0, 73, 23, 0, 69, 73, 65, 0, 73, 2, 0, 73, 23, 0, 69, 73, 66, 0, 73, 2, 0, 73, 23, 0, 69, - 73, 67, 0, 73, 2, 0, 73, 23, 0, 69, 73, 68, 0, 73, 2, 0, 73, 23, 0, 69, 77, 3, 1, 98, 76, 73, 42, 0, 69, 73, 0, 0, 73, 2, 0, 73, 24, 0, 69, 73, 6, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 7, 0, 73, 2, 0, 73, 24, 0, 69, 73, 8, 0, 73, 2, 0, 73, 24, 0, 69, 73, 9, 0, 73, 2, 0, 73, 24, 0, 69, 73, 10, 0, 73, 2, 0, 73, 24, 0, 69, 73, 11, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 12, 0, 73, 2, 0, 73, 24, 0, 69, 73, 13, 0, 73, 2, 0, 73, 24, 0, 69, 73, 14, 0, 73, 2, 0, 73, 24, 0, 69, 73, 15, 0, 73, 2, 0, 73, 24, 0, 69, 73, 16, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 17, 0, 73, 2, 0, 73, 24, 0, 69, 73, 18, 0, 73, 2, 0, 73, 24, 0, 69, 73, 19, 0, 73, 2, 0, 73, 24, 0, 69, 73, 20, 0, 73, 2, 0, 73, 24, 0, 69, 73, 21, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 22, 0, 73, 2, 0, 73, 24, 0, 69, 73, 23, 0, 73, 2, 0, 73, 24, 0, 69, 73, 24, 0, 73, 2, 0, 73, 24, 0, 69, 73, 25, 0, 73, 2, 0, 73, 24, 0, 69, 73, 26, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 27, 0, 73, 2, 0, 73, 24, 0, 69, 73, 28, 0, 73, 2, 0, 73, 24, 0, 69, 73, 29, 0, 73, 2, 0, 73, 24, 0, 69, 73, 30, 0, 73, 2, 0, 73, 24, 0, 69, 73, 31, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 32, 0, 73, 2, 0, 73, 24, 0, 69, 73, 33, 0, 73, 2, 0, 73, 24, 0, 69, 73, 34, 0, 73, 2, 0, 73, 24, 0, 69, 73, 35, 0, 73, 2, 0, 73, 24, 0, 69, 73, 36, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 37, 0, 73, 2, 0, 73, 24, 0, 69, 73, 38, 0, 73, 2, 0, 73, 24, 0, 69, 73, 39, 0, 73, 2, 0, 73, 24, 0, 69, 73, 40, 0, 73, 2, 0, 73, 24, 0, 69, 73, 41, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 42, 0, 73, 2, 0, 73, 24, 0, 69, 73, 43, 0, 73, 2, 0, 73, 24, 0, 69, 73, 44, 0, 73, 2, 0, 73, 24, 0, 69, 73, 45, 0, 73, 2, 0, 73, 24, 0, 69, 73, 46, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 47, 0, 73, 2, 0, 73, 24, 0, 69, 73, 48, 0, 73, 2, 0, 73, 24, 0, 69, 73, 49, 0, 73, 2, 0, 73, 24, 0, 69, 73, 50, 0, 73, 2, 0, 73, 24, 0, 69, 73, 51, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 52, 0, 73, 2, 0, 73, 24, 0, 69, 73, 53, 0, 73, 2, 0, 73, 24, 0, 69, 73, 54, 0, 73, 2, 0, 73, 24, 0, 69, 73, 55, 0, 73, 2, 0, 73, 24, 0, 69, 73, 56, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 57, 0, 73, 2, 0, 73, 24, 0, 69, 73, 58, 0, 73, 2, 0, 73, 24, 0, 69, 73, 59, 0, 73, 2, 0, 73, 24, 0, 69, 73, 60, 0, 73, 2, 0, 73, 24, 0, 69, 73, 61, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 62, 0, 73, 2, 0, 73, 24, 0, 69, 73, 63, 0, 73, 2, 0, 73, 24, 0, 69, 73, 64, 0, 73, 2, 0, 73, 24, 0, 69, 73, 65, 0, 73, 2, 0, 73, 24, 0, 69, 73, 66, 0, 73, 2, 0, 73, 24, 0, 69, 73, - 67, 0, 73, 2, 0, 73, 24, 0, 69, 73, 68, 0, 73, 2, 0, 73, 24, 0, 69, 77, 3, 1, 98, 76, 73, 43, 0, 69, 73, 0, 0, 73, 2, 0, 73, 1, 0, 69, 73, 6, 0, 73, 2, 0, 73, 1, 0, 69, 73, 7, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 8, 0, 73, 2, 0, 73, 1, 0, 69, 73, 9, 0, 73, 2, 0, 73, 1, 0, 69, 73, 10, 0, 73, 2, 0, 73, 1, 0, 69, 73, 11, 0, 73, 2, 0, 73, 1, 0, 69, 73, 12, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 13, 0, 73, 2, 0, 73, 1, 0, 69, 73, 14, 0, 73, 2, 0, 73, 1, 0, 69, 73, 15, 0, 73, 2, 0, 73, 1, 0, 69, 73, 16, 0, 73, 2, 0, 73, 1, 0, 69, 73, 17, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 18, 0, 73, 2, 0, 73, 1, 0, 69, 73, 19, 0, 73, 2, 0, 73, 1, 0, 69, 73, 20, 0, 73, 2, 0, 73, 1, 0, 69, 73, 21, 0, 73, 2, 0, 73, 1, 0, 69, 73, 22, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 23, 0, 73, 2, 0, 73, 1, 0, 69, 73, 24, 0, 73, 2, 0, 73, 1, 0, 69, 73, 25, 0, 73, 2, 0, 73, 1, 0, 69, 73, 26, 0, 73, 2, 0, 73, 1, 0, 69, 73, 27, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 28, 0, 73, 2, 0, 73, 1, 0, 69, 73, 29, 0, 73, 2, 0, 73, 1, 0, 69, 73, 30, 0, 73, 2, 0, 73, 1, 0, 69, 73, 31, 0, 73, 2, 0, 73, 1, 0, 69, 73, 32, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 33, 0, 73, 2, 0, 73, 1, 0, 69, 73, 34, 0, 73, 2, 0, 73, 1, 0, 69, 73, 35, 0, 73, 2, 0, 73, 1, 0, 69, 73, 36, 0, 73, 2, 0, 73, 1, 0, 69, 73, 37, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 38, 0, 73, 2, 0, 73, 1, 0, 69, 73, 39, 0, 73, 2, 0, 73, 1, 0, 69, 73, 40, 0, 73, 2, 0, 73, 1, 0, 69, 73, 41, 0, 73, 2, 0, 73, 1, 0, 69, 73, 42, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 43, 0, 73, 2, 0, 73, 1, 0, 69, 73, 44, 0, 73, 2, 0, 73, 1, 0, 69, 73, 45, 0, 73, 2, 0, 73, 1, 0, 69, 73, 46, 0, 73, 2, 0, 73, 1, 0, 69, 73, 47, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 48, 0, 73, 2, 0, 73, 1, 0, 69, 73, 49, 0, 73, 2, 0, 73, 1, 0, 69, 73, 50, 0, 73, 2, 0, 73, 1, 0, 69, 73, 51, 0, 73, 2, 0, 73, 1, 0, 69, 73, 52, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 53, 0, 73, 2, 0, 73, 1, 0, 69, 73, 54, 0, 73, 2, 0, 73, 1, 0, 69, 73, 55, 0, 73, 2, 0, 73, 1, 0, 69, 73, 56, 0, 73, 2, 0, 73, 1, 0, 69, 73, 57, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 58, 0, 73, 2, 0, 73, 1, 0, 69, 73, 59, 0, 73, 2, 0, 73, 1, 0, 69, 73, 60, 0, 73, 2, 0, 73, 1, 0, 69, 73, 61, 0, 73, 2, 0, 73, 1, 0, 69, 73, 62, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 63, 0, 73, 2, 0, 73, 1, 0, 69, 73, 64, 0, 73, 2, 0, 73, 1, 0, 69, 73, 65, 0, 73, 2, 0, 73, 1, 0, 69, 73, 66, 0, 73, 2, 0, 73, 1, 0, 69, 73, 67, - 0, 73, 2, 0, 73, 1, 0, 69, 73, 68, 0, 73, 2, 0, 73, 1, 0, 69, 77, 3, 1, 98, 76, 73, 44, 0, 69, 73, 0, 0, 73, 2, 0, 73, 18, 0, 69, 73, 6, 0, 73, 2, 0, 73, 18, 0, 69, 73, 7, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 8, 0, 73, 2, 0, 73, 18, 0, 69, 73, 9, 0, 73, 2, 0, 73, 18, 0, 69, 73, 10, 0, 73, 2, 0, 73, 18, 0, 69, 73, 11, 0, 73, 2, 0, 73, 18, 0, 69, 73, 12, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 13, 0, 73, 2, 0, 73, 18, 0, 69, 73, 14, 0, 73, 2, 0, 73, 18, 0, 69, 73, 15, 0, 73, 2, 0, 73, 18, 0, 69, 73, 16, 0, 73, 2, 0, 73, 18, 0, 69, 73, 17, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 18, 0, 73, 2, 0, 73, 18, 0, 69, 73, 19, 0, 73, 2, 0, 73, 18, 0, 69, 73, 20, 0, 73, 2, 0, 73, 18, 0, 69, 73, 21, 0, 73, 2, 0, 73, 18, 0, 69, 73, 22, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 23, 0, 73, 2, 0, 73, 18, 0, 69, 73, 24, 0, 73, 2, 0, 73, 18, 0, 69, 73, 25, 0, 73, 2, 0, 73, 18, 0, 69, 73, 26, 0, 73, 2, 0, 73, 18, 0, 69, 73, 27, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 28, 0, 73, 2, 0, 73, 18, 0, 69, 73, 29, 0, 73, 2, 0, 73, 18, 0, 69, 73, 30, 0, 73, 2, 0, 73, 18, 0, 69, 73, 31, 0, 73, 2, 0, 73, 18, 0, 69, 73, 32, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 33, 0, 73, 2, 0, 73, 18, 0, 69, 73, 34, 0, 73, 2, 0, 73, 18, 0, 69, 73, 35, 0, 73, 2, 0, 73, 18, 0, 69, 73, 36, 0, 73, 2, 0, 73, 18, 0, 69, 73, 37, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 38, 0, 73, 2, 0, 73, 18, 0, 69, 73, 39, 0, 73, 2, 0, 73, 18, 0, 69, 73, 40, 0, 73, 2, 0, 73, 18, 0, 69, 73, 41, 0, 73, 2, 0, 73, 18, 0, 69, 73, 42, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 43, 0, 73, 2, 0, 73, 18, 0, 69, 73, 44, 0, 73, 2, 0, 73, 18, 0, 69, 73, 45, 0, 73, 2, 0, 73, 18, 0, 69, 73, 46, 0, 73, 2, 0, 73, 18, 0, 69, 73, 47, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 48, 0, 73, 2, 0, 73, 18, 0, 69, 73, 49, 0, 73, 2, 0, 73, 18, 0, 69, 73, 50, 0, 73, 2, 0, 73, 18, 0, 69, 73, 51, 0, 73, 2, 0, 73, 18, 0, 69, 73, 52, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 53, 0, 73, 2, 0, 73, 18, 0, 69, 73, 54, 0, 73, 2, 0, 73, 18, 0, 69, 73, 55, 0, 73, 2, 0, 73, 18, 0, 69, 73, 56, 0, 73, 2, 0, 73, 18, 0, 69, 73, 57, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 58, 0, 73, 2, 0, 73, 18, 0, 69, 73, 59, 0, 73, 2, 0, 73, 18, 0, 69, 73, 60, 0, 73, 2, 0, 73, 18, 0, 69, 73, 61, 0, 73, 2, 0, 73, 18, 0, 69, 73, 62, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 63, 0, 73, 2, 0, 73, 18, 0, 69, 73, 64, 0, 73, 2, 0, 73, 18, 0, 69, 73, 65, 0, 73, 2, 0, 73, 18, 0, 69, 73, 66, 0, 73, 2, 0, 73, 18, 0, 69, 73, 67, 0, - 73, 2, 0, 73, 18, 0, 69, 73, 68, 0, 73, 2, 0, 73, 18, 0, 69, 77, 3, 1, 98, 76, 73, 45, 0, 69, 73, 0, 0, 73, 2, 0, 73, 19, 0, 69, 73, 6, 0, 73, 2, 0, 73, 19, 0, 69, 73, 7, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 8, 0, 73, 2, 0, 73, 19, 0, 69, 73, 9, 0, 73, 2, 0, 73, 19, 0, 69, 73, 10, 0, 73, 2, 0, 73, 19, 0, 69, 73, 11, 0, 73, 2, 0, 73, 19, 0, 69, 73, 12, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 13, 0, 73, 2, 0, 73, 19, 0, 69, 73, 14, 0, 73, 2, 0, 73, 19, 0, 69, 73, 15, 0, 73, 2, 0, 73, 19, 0, 69, 73, 16, 0, 73, 2, 0, 73, 19, 0, 69, 73, 17, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 18, 0, 73, 2, 0, 73, 19, 0, 69, 73, 19, 0, 73, 2, 0, 73, 19, 0, 69, 73, 20, 0, 73, 2, 0, 73, 19, 0, 69, 73, 21, 0, 73, 2, 0, 73, 19, 0, 69, 73, 22, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 23, 0, 73, 2, 0, 73, 19, 0, 69, 73, 24, 0, 73, 2, 0, 73, 19, 0, 69, 73, 25, 0, 73, 2, 0, 73, 19, 0, 69, 73, 26, 0, 73, 2, 0, 73, 19, 0, 69, 73, 27, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 28, 0, 73, 2, 0, 73, 19, 0, 69, 73, 29, 0, 73, 2, 0, 73, 19, 0, 69, 73, 30, 0, 73, 2, 0, 73, 19, 0, 69, 73, 31, 0, 73, 2, 0, 73, 19, 0, 69, 73, 32, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 33, 0, 73, 2, 0, 73, 19, 0, 69, 73, 34, 0, 73, 2, 0, 73, 19, 0, 69, 73, 35, 0, 73, 2, 0, 73, 19, 0, 69, 73, 36, 0, 73, 2, 0, 73, 19, 0, 69, 73, 37, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 38, 0, 73, 2, 0, 73, 19, 0, 69, 73, 39, 0, 73, 2, 0, 73, 19, 0, 69, 73, 40, 0, 73, 2, 0, 73, 19, 0, 69, 73, 41, 0, 73, 2, 0, 73, 19, 0, 69, 73, 42, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 43, 0, 73, 2, 0, 73, 19, 0, 69, 73, 44, 0, 73, 2, 0, 73, 19, 0, 69, 73, 45, 0, 73, 2, 0, 73, 19, 0, 69, 73, 46, 0, 73, 2, 0, 73, 19, 0, 69, 73, 47, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 48, 0, 73, 2, 0, 73, 19, 0, 69, 73, 49, 0, 73, 2, 0, 73, 19, 0, 69, 73, 50, 0, 73, 2, 0, 73, 19, 0, 69, 73, 51, 0, 73, 2, 0, 73, 19, 0, 69, 73, 52, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 53, 0, 73, 2, 0, 73, 19, 0, 69, 73, 54, 0, 73, 2, 0, 73, 19, 0, 69, 73, 55, 0, 73, 2, 0, 73, 19, 0, 69, 73, 56, 0, 73, 2, 0, 73, 19, 0, 69, 73, 57, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 58, 0, 73, 2, 0, 73, 19, 0, 69, 73, 59, 0, 73, 2, 0, 73, 19, 0, 69, 73, 60, 0, 73, 2, 0, 73, 19, 0, 69, 73, 61, 0, 73, 2, 0, 73, 19, 0, 69, 73, 62, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 63, 0, 73, 2, 0, 73, 19, 0, 69, 73, 64, 0, 73, 2, 0, 73, 19, 0, 69, 73, 65, 0, 73, 2, 0, 73, 19, 0, 69, 73, 66, 0, 73, 2, 0, 73, 19, 0, 69, 73, 67, 0, 73, - 2, 0, 73, 19, 0, 69, 73, 68, 0, 73, 2, 0, 73, 19, 0, 69, 77, 3, 1, 98, 76, 73, 46, 0, 69, 73, 0, 0, 73, 2, 0, 73, 4, 0, 69, 73, 6, 0, 73, 2, 0, 73, 4, 0, 69, 73, 7, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 8, 0, 73, 2, 0, 73, 4, 0, 69, 73, 9, 0, 73, 2, 0, 73, 4, 0, 69, 73, 10, 0, 73, 2, 0, 73, 4, 0, 69, 73, 11, 0, 73, 2, 0, 73, 4, 0, 69, 73, 12, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 13, 0, 73, 2, 0, 73, 4, 0, 69, 73, 14, 0, 73, 2, 0, 73, 4, 0, 69, 73, 15, 0, 73, 2, 0, 73, 4, 0, 69, 73, 16, 0, 73, 2, 0, 73, 4, 0, 69, 73, 17, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 18, 0, 73, 2, 0, 73, 4, 0, 69, 73, 19, 0, 73, 2, 0, 73, 4, 0, 69, 73, 20, 0, 73, 2, 0, 73, 4, 0, 69, 73, 21, 0, 73, 2, 0, 73, 4, 0, 69, 73, 22, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 23, 0, 73, 2, 0, 73, 4, 0, 69, 73, 24, 0, 73, 2, 0, 73, 4, 0, 69, 73, 25, 0, 73, 2, 0, 73, 4, 0, 69, 73, 26, 0, 73, 2, 0, 73, 4, 0, 69, 73, 27, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 28, 0, 73, 2, 0, 73, 4, 0, 69, 73, 29, 0, 73, 2, 0, 73, 4, 0, 69, 73, 30, 0, 73, 2, 0, 73, 4, 0, 69, 73, 31, 0, 73, 2, 0, 73, 4, 0, 69, 73, 32, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 33, 0, 73, 2, 0, 73, 4, 0, 69, 73, 34, 0, 73, 2, 0, 73, 4, 0, 69, 73, 35, 0, 73, 2, 0, 73, 4, 0, 69, 73, 36, 0, 73, 2, 0, 73, 4, 0, 69, 73, 37, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 38, 0, 73, 2, 0, 73, 4, 0, 69, 73, 39, 0, 73, 2, 0, 73, 4, 0, 69, 73, 40, 0, 73, 2, 0, 73, 4, 0, 69, 73, 41, 0, 73, 2, 0, 73, 4, 0, 69, 73, 42, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 43, 0, 73, 2, 0, 73, 4, 0, 69, 73, 44, 0, 73, 2, 0, 73, 4, 0, 69, 73, 45, 0, 73, 2, 0, 73, 4, 0, 69, 73, 46, 0, 73, 2, 0, 73, 4, 0, 69, 73, 47, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 48, 0, 73, 2, 0, 73, 4, 0, 69, 73, 49, 0, 73, 2, 0, 73, 4, 0, 69, 73, 50, 0, 73, 2, 0, 73, 4, 0, 69, 73, 51, 0, 73, 2, 0, 73, 4, 0, 69, 73, 52, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 53, 0, 73, 2, 0, 73, 4, 0, 69, 73, 54, 0, 73, 2, 0, 73, 4, 0, 69, 73, 55, 0, 73, 2, 0, 73, 4, 0, 69, 73, 56, 0, 73, 2, 0, 73, 4, 0, 69, 73, 57, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 58, 0, 73, 2, 0, 73, 4, 0, 69, 73, 59, 0, 73, 2, 0, 73, 4, 0, 69, 73, 60, 0, 73, 2, 0, 73, 4, 0, 69, 73, 61, 0, 73, 2, 0, 73, 4, 0, 69, 73, 62, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 63, 0, 73, 2, 0, 73, 4, 0, 69, 73, 64, 0, 73, 2, 0, 73, 4, 0, 69, 73, 65, 0, 73, 2, 0, 73, 4, 0, 69, 73, 66, 0, 73, 2, 0, 73, 4, 0, 69, 73, 67, 0, 73, 2, - 0, 73, 4, 0, 69, 73, 68, 0, 73, 2, 0, 73, 4, 0, 69, 77, 3, 1, 98, 76, 73, 47, 0, 69, 73, 0, 0, 73, 2, 0, 73, 11, 0, 69, 73, 6, 0, 73, 2, 0, 73, 11, 0, 69, 73, 7, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 8, 0, 73, 2, 0, 73, 11, 0, 69, 73, 9, 0, 73, 2, 0, 73, 11, 0, 69, 73, 10, 0, 73, 2, 0, 73, 11, 0, 69, 73, 11, 0, 73, 2, 0, 73, 11, 0, 69, 73, 12, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 13, 0, 73, 2, 0, 73, 11, 0, 69, 73, 14, 0, 73, 2, 0, 73, 11, 0, 69, 73, 15, 0, 73, 2, 0, 73, 11, 0, 69, 73, 16, 0, 73, 2, 0, 73, 11, 0, 69, 73, 17, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 18, 0, 73, 2, 0, 73, 11, 0, 69, 73, 19, 0, 73, 2, 0, 73, 11, 0, 69, 73, 20, 0, 73, 2, 0, 73, 11, 0, 69, 73, 21, 0, 73, 2, 0, 73, 11, 0, 69, 73, 22, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 23, 0, 73, 2, 0, 73, 11, 0, 69, 73, 24, 0, 73, 2, 0, 73, 11, 0, 69, 73, 25, 0, 73, 2, 0, 73, 11, 0, 69, 73, 26, 0, 73, 2, 0, 73, 11, 0, 69, 73, 27, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 28, 0, 73, 2, 0, 73, 11, 0, 69, 73, 29, 0, 73, 2, 0, 73, 11, 0, 69, 73, 30, 0, 73, 2, 0, 73, 11, 0, 69, 73, 31, 0, 73, 2, 0, 73, 11, 0, 69, 73, 32, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 33, 0, 73, 2, 0, 73, 11, 0, 69, 73, 34, 0, 73, 2, 0, 73, 11, 0, 69, 73, 35, 0, 73, 2, 0, 73, 11, 0, 69, 73, 36, 0, 73, 2, 0, 73, 11, 0, 69, 73, 37, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 38, 0, 73, 2, 0, 73, 11, 0, 69, 73, 39, 0, 73, 2, 0, 73, 11, 0, 69, 73, 40, 0, 73, 2, 0, 73, 11, 0, 69, 73, 41, 0, 73, 2, 0, 73, 11, 0, 69, 73, 42, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 43, 0, 73, 2, 0, 73, 11, 0, 69, 73, 44, 0, 73, 2, 0, 73, 11, 0, 69, 73, 45, 0, 73, 2, 0, 73, 11, 0, 69, 73, 46, 0, 73, 2, 0, 73, 11, 0, 69, 73, 47, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 48, 0, 73, 2, 0, 73, 11, 0, 69, 73, 49, 0, 73, 2, 0, 73, 11, 0, 69, 73, 50, 0, 73, 2, 0, 73, 11, 0, 69, 73, 51, 0, 73, 2, 0, 73, 11, 0, 69, 73, 52, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 53, 0, 73, 2, 0, 73, 11, 0, 69, 73, 54, 0, 73, 2, 0, 73, 11, 0, 69, 73, 55, 0, 73, 2, 0, 73, 11, 0, 69, 73, 56, 0, 73, 2, 0, 73, 11, 0, 69, 73, 57, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 58, 0, 73, 2, 0, 73, 11, 0, 69, 73, 59, 0, 73, 2, 0, 73, 11, 0, 69, 73, 60, 0, 73, 2, 0, 73, 11, 0, 69, 73, 61, 0, 73, 2, 0, 73, 11, 0, 69, 73, 62, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 63, 0, 73, 2, 0, 73, 11, 0, 69, 73, 64, 0, 73, 2, 0, 73, 11, 0, 69, 73, 65, 0, 73, 2, 0, 73, 11, 0, 69, 73, 66, 0, 73, 2, 0, 73, 11, 0, 69, 73, 67, 0, 73, 2, 0, - 73, 11, 0, 69, 73, 68, 0, 73, 2, 0, 73, 11, 0, 69, 77, 3, 1, 98, 76, 73, 48, 0, 69, 73, 0, 0, 73, 2, 0, 73, 48, 0, 69, 73, 6, 0, 73, 2, 0, 73, 48, 0, 69, 73, 7, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 8, 0, 73, 2, 0, 73, 48, 0, 69, 73, 9, 0, 73, 2, 0, 73, 48, 0, 69, 73, 10, 0, 73, 2, 0, 73, 48, 0, 69, 73, 11, 0, 73, 2, 0, 73, 48, 0, 69, 73, 12, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 13, 0, 73, 2, 0, 73, 48, 0, 69, 73, 14, 0, 73, 2, 0, 73, 48, 0, 69, 73, 15, 0, 73, 2, 0, 73, 48, 0, 69, 73, 16, 0, 73, 2, 0, 73, 48, 0, 69, 73, 17, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 18, 0, 73, 2, 0, 73, 48, 0, 69, 73, 19, 0, 73, 2, 0, 73, 48, 0, 69, 73, 20, 0, 73, 2, 0, 73, 48, 0, 69, 73, 21, 0, 73, 2, 0, 73, 48, 0, 69, 73, 22, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 23, 0, 73, 2, 0, 73, 48, 0, 69, 73, 24, 0, 73, 2, 0, 73, 48, 0, 69, 73, 25, 0, 73, 2, 0, 73, 48, 0, 69, 73, 26, 0, 73, 2, 0, 73, 48, 0, 69, 73, 27, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 28, 0, 73, 2, 0, 73, 48, 0, 69, 73, 29, 0, 73, 2, 0, 73, 48, 0, 69, 73, 30, 0, 73, 2, 0, 73, 48, 0, 69, 73, 31, 0, 73, 2, 0, 73, 48, 0, 69, 73, 32, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 33, 0, 73, 2, 0, 73, 48, 0, 69, 73, 34, 0, 73, 2, 0, 73, 48, 0, 69, 73, 35, 0, 73, 2, 0, 73, 48, 0, 69, 73, 36, 0, 73, 2, 0, 73, 48, 0, 69, 73, 37, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 38, 0, 73, 2, 0, 73, 48, 0, 69, 73, 39, 0, 73, 2, 0, 73, 48, 0, 69, 73, 40, 0, 73, 2, 0, 73, 48, 0, 69, 73, 41, 0, 73, 2, 0, 73, 48, 0, 69, 73, 42, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 43, 0, 73, 2, 0, 73, 48, 0, 69, 73, 44, 0, 73, 2, 0, 73, 48, 0, 69, 73, 45, 0, 73, 2, 0, 73, 48, 0, 69, 73, 46, 0, 73, 2, 0, 73, 48, 0, 69, 73, 47, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 48, 0, 73, 2, 0, 73, 48, 0, 69, 73, 49, 0, 73, 2, 0, 73, 48, 0, 69, 73, 50, 0, 73, 2, 0, 73, 48, 0, 69, 73, 51, 0, 73, 2, 0, 73, 48, 0, 69, 73, 52, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 53, 0, 73, 2, 0, 73, 48, 0, 69, 73, 54, 0, 73, 2, 0, 73, 48, 0, 69, 73, 55, 0, 73, 2, 0, 73, 48, 0, 69, 73, 56, 0, 73, 2, 0, 73, 48, 0, 69, 73, 57, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 58, 0, 73, 2, 0, 73, 48, 0, 69, 73, 59, 0, 73, 2, 0, 73, 48, 0, 69, 73, 60, 0, 73, 2, 0, 73, 48, 0, 69, 73, 61, 0, 73, 2, 0, 73, 48, 0, 69, 73, 62, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 63, 0, 73, 2, 0, 73, 48, 0, 69, 73, 64, 0, 73, 2, 0, 73, 48, 0, 69, 73, 65, 0, 73, 2, 0, 73, 48, 0, 69, 73, 66, 0, 73, 2, 0, 73, 48, 0, 69, 73, 67, 0, 73, 2, 0, 73, - 48, 0, 69, 73, 68, 0, 73, 2, 0, 73, 48, 0, 69, 77, 3, 1, 98, 76, 73, 49, 0, 69, 73, 0, 0, 73, 2, 0, 73, 25, 0, 69, 73, 6, 0, 73, 2, 0, 73, 25, 0, 69, 73, 7, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 8, 0, 73, 2, 0, 73, 25, 0, 69, 73, 9, 0, 73, 2, 0, 73, 25, 0, 69, 73, 10, 0, 73, 2, 0, 73, 25, 0, 69, 73, 11, 0, 73, 2, 0, 73, 25, 0, 69, 73, 12, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 13, 0, 73, 2, 0, 73, 25, 0, 69, 73, 14, 0, 73, 2, 0, 73, 25, 0, 69, 73, 15, 0, 73, 2, 0, 73, 25, 0, 69, 73, 16, 0, 73, 2, 0, 73, 25, 0, 69, 73, 17, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 18, 0, 73, 2, 0, 73, 25, 0, 69, 73, 19, 0, 73, 2, 0, 73, 25, 0, 69, 73, 20, 0, 73, 2, 0, 73, 25, 0, 69, 73, 21, 0, 73, 2, 0, 73, 25, 0, 69, 73, 22, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 23, 0, 73, 2, 0, 73, 25, 0, 69, 73, 24, 0, 73, 2, 0, 73, 25, 0, 69, 73, 25, 0, 73, 2, 0, 73, 25, 0, 69, 73, 26, 0, 73, 2, 0, 73, 25, 0, 69, 73, 27, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 28, 0, 73, 2, 0, 73, 25, 0, 69, 73, 29, 0, 73, 2, 0, 73, 25, 0, 69, 73, 30, 0, 73, 2, 0, 73, 25, 0, 69, 73, 31, 0, 73, 2, 0, 73, 25, 0, 69, 73, 32, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 33, 0, 73, 2, 0, 73, 25, 0, 69, 73, 34, 0, 73, 2, 0, 73, 25, 0, 69, 73, 35, 0, 73, 2, 0, 73, 25, 0, 69, 73, 36, 0, 73, 2, 0, 73, 25, 0, 69, 73, 37, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 38, 0, 73, 2, 0, 73, 25, 0, 69, 73, 39, 0, 73, 2, 0, 73, 25, 0, 69, 73, 40, 0, 73, 2, 0, 73, 25, 0, 69, 73, 41, 0, 73, 2, 0, 73, 25, 0, 69, 73, 42, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 43, 0, 73, 2, 0, 73, 25, 0, 69, 73, 44, 0, 73, 2, 0, 73, 25, 0, 69, 73, 45, 0, 73, 2, 0, 73, 25, 0, 69, 73, 46, 0, 73, 2, 0, 73, 25, 0, 69, 73, 47, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 48, 0, 73, 2, 0, 73, 25, 0, 69, 73, 49, 0, 73, 2, 0, 73, 25, 0, 69, 73, 50, 0, 73, 2, 0, 73, 25, 0, 69, 73, 51, 0, 73, 2, 0, 73, 25, 0, 69, 73, 52, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 53, 0, 73, 2, 0, 73, 25, 0, 69, 73, 54, 0, 73, 2, 0, 73, 25, 0, 69, 73, 55, 0, 73, 2, 0, 73, 25, 0, 69, 73, 56, 0, 73, 2, 0, 73, 25, 0, 69, 73, 57, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 58, 0, 73, 2, 0, 73, 25, 0, 69, 73, 59, 0, 73, 2, 0, 73, 25, 0, 69, 73, 60, 0, 73, 2, 0, 73, 25, 0, 69, 73, 61, 0, 73, 2, 0, 73, 25, 0, 69, 73, 62, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 63, 0, 73, 2, 0, 73, 25, 0, 69, 73, 64, 0, 73, 2, 0, 73, 25, 0, 69, 73, 65, 0, 73, 2, 0, 73, 25, 0, 69, 73, 66, 0, 73, 2, 0, 73, 25, 0, 69, 73, 67, 0, 73, 2, 0, 73, 25, - 0, 69, 73, 68, 0, 73, 2, 0, 73, 25, 0, 69, 77, 3, 1, 98, 76, 73, 50, 0, 69, 73, 0, 0, 73, 2, 0, 73, 26, 0, 69, 73, 6, 0, 73, 2, 0, 73, 26, 0, 69, 73, 7, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 8, 0, 73, 2, 0, 73, 26, 0, 69, 73, 9, 0, 73, 2, 0, 73, 26, 0, 69, 73, 10, 0, 73, 2, 0, 73, 26, 0, 69, 73, 11, 0, 73, 2, 0, 73, 26, 0, 69, 73, 12, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 13, 0, 73, 2, 0, 73, 26, 0, 69, 73, 14, 0, 73, 2, 0, 73, 26, 0, 69, 73, 15, 0, 73, 2, 0, 73, 26, 0, 69, 73, 16, 0, 73, 2, 0, 73, 26, 0, 69, 73, 17, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 18, 0, 73, 2, 0, 73, 26, 0, 69, 73, 19, 0, 73, 2, 0, 73, 26, 0, 69, 73, 20, 0, 73, 2, 0, 73, 26, 0, 69, 73, 21, 0, 73, 2, 0, 73, 26, 0, 69, 73, 22, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 23, 0, 73, 2, 0, 73, 26, 0, 69, 73, 24, 0, 73, 2, 0, 73, 26, 0, 69, 73, 25, 0, 73, 2, 0, 73, 26, 0, 69, 73, 26, 0, 73, 2, 0, 73, 26, 0, 69, 73, 27, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 28, 0, 73, 2, 0, 73, 26, 0, 69, 73, 29, 0, 73, 2, 0, 73, 26, 0, 69, 73, 30, 0, 73, 2, 0, 73, 26, 0, 69, 73, 31, 0, 73, 2, 0, 73, 26, 0, 69, 73, 32, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 33, 0, 73, 2, 0, 73, 26, 0, 69, 73, 34, 0, 73, 2, 0, 73, 26, 0, 69, 73, 35, 0, 73, 2, 0, 73, 26, 0, 69, 73, 36, 0, 73, 2, 0, 73, 26, 0, 69, 73, 37, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 38, 0, 73, 2, 0, 73, 26, 0, 69, 73, 39, 0, 73, 2, 0, 73, 26, 0, 69, 73, 40, 0, 73, 2, 0, 73, 26, 0, 69, 73, 41, 0, 73, 2, 0, 73, 26, 0, 69, 73, 42, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 43, 0, 73, 2, 0, 73, 26, 0, 69, 73, 44, 0, 73, 2, 0, 73, 26, 0, 69, 73, 45, 0, 73, 2, 0, 73, 26, 0, 69, 73, 46, 0, 73, 2, 0, 73, 26, 0, 69, 73, 47, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 48, 0, 73, 2, 0, 73, 26, 0, 69, 73, 49, 0, 73, 2, 0, 73, 26, 0, 69, 73, 50, 0, 73, 2, 0, 73, 26, 0, 69, 73, 51, 0, 73, 2, 0, 73, 26, 0, 69, 73, 52, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 53, 0, 73, 2, 0, 73, 26, 0, 69, 73, 54, 0, 73, 2, 0, 73, 26, 0, 69, 73, 55, 0, 73, 2, 0, 73, 26, 0, 69, 73, 56, 0, 73, 2, 0, 73, 26, 0, 69, 73, 57, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 58, 0, 73, 2, 0, 73, 26, 0, 69, 73, 59, 0, 73, 2, 0, 73, 26, 0, 69, 73, 60, 0, 73, 2, 0, 73, 26, 0, 69, 73, 61, 0, 73, 2, 0, 73, 26, 0, 69, 73, 62, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 63, 0, 73, 2, 0, 73, 26, 0, 69, 73, 64, 0, 73, 2, 0, 73, 26, 0, 69, 73, 65, 0, 73, 2, 0, 73, 26, 0, 69, 73, 66, 0, 73, 2, 0, 73, 26, 0, 69, 73, 67, 0, 73, 2, 0, 73, 26, 0, - 69, 73, 68, 0, 73, 2, 0, 73, 26, 0, 69, 77, 3, 1, 98, 76, 73, 51, 0, 69, 73, 0, 0, 73, 2, 0, 73, 15, 0, 69, 73, 6, 0, 73, 2, 0, 73, 15, 0, 69, 73, 7, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 8, 0, 73, 2, 0, 73, 15, 0, 69, 73, 9, 0, 73, 2, 0, 73, 15, 0, 69, 73, 10, 0, 73, 2, 0, 73, 15, 0, 69, 73, 11, 0, 73, 2, 0, 73, 15, 0, 69, 73, 12, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 13, 0, 73, 2, 0, 73, 15, 0, 69, 73, 14, 0, 73, 2, 0, 73, 15, 0, 69, 73, 15, 0, 73, 2, 0, 73, 15, 0, 69, 73, 16, 0, 73, 2, 0, 73, 15, 0, 69, 73, 17, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 18, 0, 73, 2, 0, 73, 15, 0, 69, 73, 19, 0, 73, 2, 0, 73, 15, 0, 69, 73, 20, 0, 73, 2, 0, 73, 15, 0, 69, 73, 21, 0, 73, 2, 0, 73, 15, 0, 69, 73, 22, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 23, 0, 73, 2, 0, 73, 15, 0, 69, 73, 24, 0, 73, 2, 0, 73, 15, 0, 69, 73, 25, 0, 73, 2, 0, 73, 15, 0, 69, 73, 26, 0, 73, 2, 0, 73, 15, 0, 69, 73, 27, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 28, 0, 73, 2, 0, 73, 15, 0, 69, 73, 29, 0, 73, 2, 0, 73, 15, 0, 69, 73, 30, 0, 73, 2, 0, 73, 15, 0, 69, 73, 31, 0, 73, 2, 0, 73, 15, 0, 69, 73, 32, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 33, 0, 73, 2, 0, 73, 15, 0, 69, 73, 34, 0, 73, 2, 0, 73, 15, 0, 69, 73, 35, 0, 73, 2, 0, 73, 15, 0, 69, 73, 36, 0, 73, 2, 0, 73, 15, 0, 69, 73, 37, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 38, 0, 73, 2, 0, 73, 15, 0, 69, 73, 39, 0, 73, 2, 0, 73, 15, 0, 69, 73, 40, 0, 73, 2, 0, 73, 15, 0, 69, 73, 41, 0, 73, 2, 0, 73, 15, 0, 69, 73, 42, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 43, 0, 73, 2, 0, 73, 15, 0, 69, 73, 44, 0, 73, 2, 0, 73, 15, 0, 69, 73, 45, 0, 73, 2, 0, 73, 15, 0, 69, 73, 46, 0, 73, 2, 0, 73, 15, 0, 69, 73, 47, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 48, 0, 73, 2, 0, 73, 15, 0, 69, 73, 49, 0, 73, 2, 0, 73, 15, 0, 69, 73, 50, 0, 73, 2, 0, 73, 15, 0, 69, 73, 51, 0, 73, 2, 0, 73, 15, 0, 69, 73, 52, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 53, 0, 73, 2, 0, 73, 15, 0, 69, 73, 54, 0, 73, 2, 0, 73, 15, 0, 69, 73, 55, 0, 73, 2, 0, 73, 15, 0, 69, 73, 56, 0, 73, 2, 0, 73, 15, 0, 69, 73, 57, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 58, 0, 73, 2, 0, 73, 15, 0, 69, 73, 59, 0, 73, 2, 0, 73, 15, 0, 69, 73, 60, 0, 73, 2, 0, 73, 15, 0, 69, 73, 61, 0, 73, 2, 0, 73, 15, 0, 69, 73, 62, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 63, 0, 73, 2, 0, 73, 15, 0, 69, 73, 64, 0, 73, 2, 0, 73, 15, 0, 69, 73, 65, 0, 73, 2, 0, 73, 15, 0, 69, 73, 66, 0, 73, 2, 0, 73, 15, 0, 69, 73, 67, 0, 73, 2, 0, 73, 15, 0, 69, - 73, 68, 0, 73, 2, 0, 73, 15, 0, 69, 77, 3, 1, 98, 76, 73, 52, 0, 69, 73, 0, 0, 73, 2, 0, 73, 44, 0, 69, 73, 6, 0, 73, 2, 0, 73, 44, 0, 69, 73, 7, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 8, 0, 73, 2, 0, 73, 44, 0, 69, 73, 9, 0, 73, 2, 0, 73, 44, 0, 69, 73, 10, 0, 73, 2, 0, 73, 44, 0, 69, 73, 11, 0, 73, 2, 0, 73, 44, 0, 69, 73, 12, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 13, 0, 73, 2, 0, 73, 44, 0, 69, 73, 14, 0, 73, 2, 0, 73, 44, 0, 69, 73, 15, 0, 73, 2, 0, 73, 44, 0, 69, 73, 16, 0, 73, 2, 0, 73, 44, 0, 69, 73, 17, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 18, 0, 73, 2, 0, 73, 44, 0, 69, 73, 19, 0, 73, 2, 0, 73, 44, 0, 69, 73, 20, 0, 73, 2, 0, 73, 44, 0, 69, 73, 21, 0, 73, 2, 0, 73, 44, 0, 69, 73, 22, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 23, 0, 73, 2, 0, 73, 44, 0, 69, 73, 24, 0, 73, 2, 0, 73, 44, 0, 69, 73, 25, 0, 73, 2, 0, 73, 44, 0, 69, 73, 26, 0, 73, 2, 0, 73, 44, 0, 69, 73, 27, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 28, 0, 73, 2, 0, 73, 44, 0, 69, 73, 29, 0, 73, 2, 0, 73, 44, 0, 69, 73, 30, 0, 73, 2, 0, 73, 44, 0, 69, 73, 31, 0, 73, 2, 0, 73, 44, 0, 69, 73, 32, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 33, 0, 73, 2, 0, 73, 44, 0, 69, 73, 34, 0, 73, 2, 0, 73, 44, 0, 69, 73, 35, 0, 73, 2, 0, 73, 44, 0, 69, 73, 36, 0, 73, 2, 0, 73, 44, 0, 69, 73, 37, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 38, 0, 73, 2, 0, 73, 44, 0, 69, 73, 39, 0, 73, 2, 0, 73, 44, 0, 69, 73, 40, 0, 73, 2, 0, 73, 44, 0, 69, 73, 41, 0, 73, 2, 0, 73, 44, 0, 69, 73, 42, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 43, 0, 73, 2, 0, 73, 44, 0, 69, 73, 44, 0, 73, 2, 0, 73, 44, 0, 69, 73, 45, 0, 73, 2, 0, 73, 44, 0, 69, 73, 46, 0, 73, 2, 0, 73, 44, 0, 69, 73, 47, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 48, 0, 73, 2, 0, 73, 44, 0, 69, 73, 49, 0, 73, 2, 0, 73, 44, 0, 69, 73, 50, 0, 73, 2, 0, 73, 44, 0, 69, 73, 51, 0, 73, 2, 0, 73, 44, 0, 69, 73, 52, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 53, 0, 73, 2, 0, 73, 44, 0, 69, 73, 54, 0, 73, 2, 0, 73, 44, 0, 69, 73, 55, 0, 73, 2, 0, 73, 44, 0, 69, 73, 56, 0, 73, 2, 0, 73, 44, 0, 69, 73, 57, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 58, 0, 73, 2, 0, 73, 44, 0, 69, 73, 59, 0, 73, 2, 0, 73, 44, 0, 69, 73, 60, 0, 73, 2, 0, 73, 44, 0, 69, 73, 61, 0, 73, 2, 0, 73, 44, 0, 69, 73, 62, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 63, 0, 73, 2, 0, 73, 44, 0, 69, 73, 64, 0, 73, 2, 0, 73, 44, 0, 69, 73, 65, 0, 73, 2, 0, 73, 44, 0, 69, 73, 66, 0, 73, 2, 0, 73, 44, 0, 69, 73, 67, 0, 73, 2, 0, 73, 44, 0, 69, 73, - 68, 0, 73, 2, 0, 73, 44, 0, 69, 77, 3, 1, 98, 76, 73, 53, 0, 69, 73, 0, 0, 73, 2, 0, 73, 46, 0, 69, 73, 6, 0, 73, 2, 0, 73, 46, 0, 69, 73, 7, 0, 73, 2, 0, 73, 46, 0, 69, 73, 8, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 9, 0, 73, 2, 0, 73, 46, 0, 69, 73, 10, 0, 73, 2, 0, 73, 46, 0, 69, 73, 11, 0, 73, 2, 0, 73, 46, 0, 69, 73, 12, 0, 73, 2, 0, 73, 46, 0, 69, 73, 13, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 14, 0, 73, 2, 0, 73, 46, 0, 69, 73, 15, 0, 73, 2, 0, 73, 46, 0, 69, 73, 16, 0, 73, 2, 0, 73, 46, 0, 69, 73, 17, 0, 73, 2, 0, 73, 46, 0, 69, 73, 18, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 19, 0, 73, 2, 0, 73, 46, 0, 69, 73, 20, 0, 73, 2, 0, 73, 46, 0, 69, 73, 21, 0, 73, 2, 0, 73, 46, 0, 69, 73, 22, 0, 73, 2, 0, 73, 46, 0, 69, 73, 23, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 24, 0, 73, 2, 0, 73, 46, 0, 69, 73, 25, 0, 73, 2, 0, 73, 46, 0, 69, 73, 26, 0, 73, 2, 0, 73, 46, 0, 69, 73, 27, 0, 73, 2, 0, 73, 46, 0, 69, 73, 28, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 29, 0, 73, 2, 0, 73, 46, 0, 69, 73, 30, 0, 73, 2, 0, 73, 46, 0, 69, 73, 31, 0, 73, 2, 0, 73, 46, 0, 69, 73, 32, 0, 73, 2, 0, 73, 46, 0, 69, 73, 33, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 34, 0, 73, 2, 0, 73, 46, 0, 69, 73, 35, 0, 73, 2, 0, 73, 46, 0, 69, 73, 36, 0, 73, 2, 0, 73, 46, 0, 69, 73, 37, 0, 73, 2, 0, 73, 46, 0, 69, 73, 38, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 39, 0, 73, 2, 0, 73, 46, 0, 69, 73, 40, 0, 73, 2, 0, 73, 46, 0, 69, 73, 41, 0, 73, 2, 0, 73, 46, 0, 69, 73, 42, 0, 73, 2, 0, 73, 46, 0, 69, 73, 43, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 44, 0, 73, 2, 0, 73, 46, 0, 69, 73, 45, 0, 73, 2, 0, 73, 46, 0, 69, 73, 46, 0, 73, 2, 0, 73, 46, 0, 69, 73, 47, 0, 73, 2, 0, 73, 46, 0, 69, 73, 48, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 49, 0, 73, 2, 0, 73, 46, 0, 69, 73, 50, 0, 73, 2, 0, 73, 46, 0, 69, 73, 51, 0, 73, 2, 0, 73, 46, 0, 69, 73, 52, 0, 73, 2, 0, 73, 46, 0, 69, 73, 53, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 54, 0, 73, 2, 0, 73, 46, 0, 69, 73, 55, 0, 73, 2, 0, 73, 46, 0, 69, 73, 56, 0, 73, 2, 0, 73, 46, 0, 69, 73, 57, 0, 73, 2, 0, 73, 46, 0, 69, 73, 58, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 59, 0, 73, 2, 0, 73, 46, 0, 69, 73, 60, 0, 73, 2, 0, 73, 46, 0, 69, 73, 61, 0, 73, 2, 0, 73, 46, 0, 69, 73, 62, 0, 73, 2, 0, 73, 46, 0, 69, 73, 63, - 0, 73, 2, 0, 73, 46, 0, 69, 73, 64, 0, 73, 2, 0, 73, 46, 0, 69, 73, 65, 0, 73, 2, 0, 73, 46, 0, 69, 73, 66, 0, 73, 2, 0, 73, 46, 0, 69, 73, 67, 0, 73, 2, 0, 73, 46, 0, 69, 73, 68, - 0, 73, 2, 0, 73, 46, 0, 69, 77, 3, 1, 98, 76, 73, 54, 0, 69, 73, 0, 0, 73, 2, 0, 73, 49, 0, 69, 73, 6, 0, 73, 2, 0, 73, 49, 0, 69, 73, 7, 0, 73, 2, 0, 73, 49, 0, 69, 73, 8, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 9, 0, 73, 2, 0, 73, 49, 0, 69, 73, 10, 0, 73, 2, 0, 73, 49, 0, 69, 73, 11, 0, 73, 2, 0, 73, 49, 0, 69, 73, 12, 0, 73, 2, 0, 73, 49, 0, 69, 73, 13, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 14, 0, 73, 2, 0, 73, 49, 0, 69, 73, 15, 0, 73, 2, 0, 73, 49, 0, 69, 73, 16, 0, 73, 2, 0, 73, 49, 0, 69, 73, 17, 0, 73, 2, 0, 73, 49, 0, 69, 73, 18, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 19, 0, 73, 2, 0, 73, 49, 0, 69, 73, 20, 0, 73, 2, 0, 73, 49, 0, 69, 73, 21, 0, 73, 2, 0, 73, 49, 0, 69, 73, 22, 0, 73, 2, 0, 73, 49, 0, 69, 73, 23, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 24, 0, 73, 2, 0, 73, 49, 0, 69, 73, 25, 0, 73, 2, 0, 73, 49, 0, 69, 73, 26, 0, 73, 2, 0, 73, 49, 0, 69, 73, 27, 0, 73, 2, 0, 73, 49, 0, 69, 73, 28, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 29, 0, 73, 2, 0, 73, 49, 0, 69, 73, 30, 0, 73, 2, 0, 73, 49, 0, 69, 73, 31, 0, 73, 2, 0, 73, 49, 0, 69, 73, 32, 0, 73, 2, 0, 73, 49, 0, 69, 73, 33, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 34, 0, 73, 2, 0, 73, 49, 0, 69, 73, 35, 0, 73, 2, 0, 73, 49, 0, 69, 73, 36, 0, 73, 2, 0, 73, 49, 0, 69, 73, 37, 0, 73, 2, 0, 73, 49, 0, 69, 73, 38, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 39, 0, 73, 2, 0, 73, 49, 0, 69, 73, 40, 0, 73, 2, 0, 73, 49, 0, 69, 73, 41, 0, 73, 2, 0, 73, 49, 0, 69, 73, 42, 0, 73, 2, 0, 73, 49, 0, 69, 73, 43, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 44, 0, 73, 2, 0, 73, 49, 0, 69, 73, 45, 0, 73, 2, 0, 73, 49, 0, 69, 73, 46, 0, 73, 2, 0, 73, 49, 0, 69, 73, 47, 0, 73, 2, 0, 73, 49, 0, 69, 73, 48, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 49, 0, 73, 2, 0, 73, 49, 0, 69, 73, 50, 0, 73, 2, 0, 73, 49, 0, 69, 73, 51, 0, 73, 2, 0, 73, 49, 0, 69, 73, 52, 0, 73, 2, 0, 73, 49, 0, 69, 73, 53, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 54, 0, 73, 2, 0, 73, 49, 0, 69, 73, 55, 0, 73, 2, 0, 73, 49, 0, 69, 73, 56, 0, 73, 2, 0, 73, 49, 0, 69, 73, 57, 0, 73, 2, 0, 73, 49, 0, 69, 73, 58, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 59, 0, 73, 2, 0, 73, 49, 0, 69, 73, 60, 0, 73, 2, 0, 73, 49, 0, 69, 73, 61, 0, 73, 2, 0, 73, 49, 0, 69, 73, 62, 0, 73, 2, 0, 73, 49, 0, 69, 73, 63, 0, - 73, 2, 0, 73, 49, 0, 69, 73, 64, 0, 73, 2, 0, 73, 49, 0, 69, 73, 65, 0, 73, 2, 0, 73, 49, 0, 69, 73, 66, 0, 73, 2, 0, 73, 49, 0, 69, 73, 67, 0, 73, 2, 0, 73, 49, 0, 69, 73, 68, 0, - 73, 2, 0, 73, 49, 0, 69, 77, 3, 1, 98, 76, 73, 55, 0, 69, 73, 0, 0, 73, 2, 0, 73, 22, 0, 69, 73, 6, 0, 73, 2, 0, 73, 22, 0, 69, 73, 7, 0, 73, 2, 0, 73, 22, 0, 69, 73, 8, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 9, 0, 73, 2, 0, 73, 22, 0, 69, 73, 10, 0, 73, 2, 0, 73, 22, 0, 69, 73, 11, 0, 73, 2, 0, 73, 22, 0, 69, 73, 12, 0, 73, 2, 0, 73, 22, 0, 69, 73, 13, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 14, 0, 73, 2, 0, 73, 22, 0, 69, 73, 15, 0, 73, 2, 0, 73, 22, 0, 69, 73, 16, 0, 73, 2, 0, 73, 22, 0, 69, 73, 17, 0, 73, 2, 0, 73, 22, 0, 69, 73, 18, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 19, 0, 73, 2, 0, 73, 22, 0, 69, 73, 20, 0, 73, 2, 0, 73, 22, 0, 69, 73, 21, 0, 73, 2, 0, 73, 22, 0, 69, 73, 22, 0, 73, 2, 0, 73, 22, 0, 69, 73, 23, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 24, 0, 73, 2, 0, 73, 22, 0, 69, 73, 25, 0, 73, 2, 0, 73, 22, 0, 69, 73, 26, 0, 73, 2, 0, 73, 22, 0, 69, 73, 27, 0, 73, 2, 0, 73, 22, 0, 69, 73, 28, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 29, 0, 73, 2, 0, 73, 22, 0, 69, 73, 30, 0, 73, 2, 0, 73, 22, 0, 69, 73, 31, 0, 73, 2, 0, 73, 22, 0, 69, 73, 32, 0, 73, 2, 0, 73, 22, 0, 69, 73, 33, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 34, 0, 73, 2, 0, 73, 22, 0, 69, 73, 35, 0, 73, 2, 0, 73, 22, 0, 69, 73, 36, 0, 73, 2, 0, 73, 22, 0, 69, 73, 37, 0, 73, 2, 0, 73, 22, 0, 69, 73, 38, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 39, 0, 73, 2, 0, 73, 22, 0, 69, 73, 40, 0, 73, 2, 0, 73, 22, 0, 69, 73, 41, 0, 73, 2, 0, 73, 22, 0, 69, 73, 42, 0, 73, 2, 0, 73, 22, 0, 69, 73, 43, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 44, 0, 73, 2, 0, 73, 22, 0, 69, 73, 45, 0, 73, 2, 0, 73, 22, 0, 69, 73, 46, 0, 73, 2, 0, 73, 22, 0, 69, 73, 47, 0, 73, 2, 0, 73, 22, 0, 69, 73, 48, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 49, 0, 73, 2, 0, 73, 22, 0, 69, 73, 50, 0, 73, 2, 0, 73, 22, 0, 69, 73, 51, 0, 73, 2, 0, 73, 22, 0, 69, 73, 52, 0, 73, 2, 0, 73, 22, 0, 69, 73, 53, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 54, 0, 73, 2, 0, 73, 22, 0, 69, 73, 55, 0, 73, 2, 0, 73, 22, 0, 69, 73, 56, 0, 73, 2, 0, 73, 22, 0, 69, 73, 57, 0, 73, 2, 0, 73, 22, 0, 69, 73, 58, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 59, 0, 73, 2, 0, 73, 22, 0, 69, 73, 60, 0, 73, 2, 0, 73, 22, 0, 69, 73, 61, 0, 73, 2, 0, 73, 22, 0, 69, 73, 62, 0, 73, 2, 0, 73, 22, 0, 69, 73, 63, 0, 73, - 2, 0, 73, 22, 0, 69, 73, 64, 0, 73, 2, 0, 73, 22, 0, 69, 73, 65, 0, 73, 2, 0, 73, 22, 0, 69, 73, 66, 0, 73, 2, 0, 73, 22, 0, 69, 73, 67, 0, 73, 2, 0, 73, 22, 0, 69, 73, 68, 0, 73, - 2, 0, 73, 22, 0, 69, 77, 3, 1, 98, 76, 73, 56, 0, 69, 73, 0, 0, 73, 2, 0, 73, 37, 0, 69, 73, 6, 0, 73, 2, 0, 73, 37, 0, 69, 73, 7, 0, 73, 2, 0, 73, 37, 0, 69, 73, 8, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 9, 0, 73, 2, 0, 73, 37, 0, 69, 73, 10, 0, 73, 2, 0, 73, 37, 0, 69, 73, 11, 0, 73, 2, 0, 73, 37, 0, 69, 73, 12, 0, 73, 2, 0, 73, 37, 0, 69, 73, 13, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 14, 0, 73, 2, 0, 73, 37, 0, 69, 73, 15, 0, 73, 2, 0, 73, 37, 0, 69, 73, 16, 0, 73, 2, 0, 73, 37, 0, 69, 73, 17, 0, 73, 2, 0, 73, 37, 0, 69, 73, 18, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 19, 0, 73, 2, 0, 73, 37, 0, 69, 73, 20, 0, 73, 2, 0, 73, 37, 0, 69, 73, 21, 0, 73, 2, 0, 73, 37, 0, 69, 73, 22, 0, 73, 2, 0, 73, 37, 0, 69, 73, 23, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 24, 0, 73, 2, 0, 73, 37, 0, 69, 73, 25, 0, 73, 2, 0, 73, 37, 0, 69, 73, 26, 0, 73, 2, 0, 73, 37, 0, 69, 73, 27, 0, 73, 2, 0, 73, 37, 0, 69, 73, 28, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 29, 0, 73, 2, 0, 73, 37, 0, 69, 73, 30, 0, 73, 2, 0, 73, 37, 0, 69, 73, 31, 0, 73, 2, 0, 73, 37, 0, 69, 73, 32, 0, 73, 2, 0, 73, 37, 0, 69, 73, 33, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 34, 0, 73, 2, 0, 73, 37, 0, 69, 73, 35, 0, 73, 2, 0, 73, 37, 0, 69, 73, 36, 0, 73, 2, 0, 73, 37, 0, 69, 73, 37, 0, 73, 2, 0, 73, 37, 0, 69, 73, 38, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 39, 0, 73, 2, 0, 73, 37, 0, 69, 73, 40, 0, 73, 2, 0, 73, 37, 0, 69, 73, 41, 0, 73, 2, 0, 73, 37, 0, 69, 73, 42, 0, 73, 2, 0, 73, 37, 0, 69, 73, 43, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 44, 0, 73, 2, 0, 73, 37, 0, 69, 73, 45, 0, 73, 2, 0, 73, 37, 0, 69, 73, 46, 0, 73, 2, 0, 73, 37, 0, 69, 73, 47, 0, 73, 2, 0, 73, 37, 0, 69, 73, 48, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 49, 0, 73, 2, 0, 73, 37, 0, 69, 73, 50, 0, 73, 2, 0, 73, 37, 0, 69, 73, 51, 0, 73, 2, 0, 73, 37, 0, 69, 73, 52, 0, 73, 2, 0, 73, 37, 0, 69, 73, 53, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 54, 0, 73, 2, 0, 73, 37, 0, 69, 73, 55, 0, 73, 2, 0, 73, 37, 0, 69, 73, 56, 0, 73, 2, 0, 73, 37, 0, 69, 73, 57, 0, 73, 2, 0, 73, 37, 0, 69, 73, 58, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 59, 0, 73, 2, 0, 73, 37, 0, 69, 73, 60, 0, 73, 2, 0, 73, 37, 0, 69, 73, 61, 0, 73, 2, 0, 73, 37, 0, 69, 73, 62, 0, 73, 2, 0, 73, 37, 0, 69, 73, 63, 0, 73, 2, - 0, 73, 37, 0, 69, 73, 64, 0, 73, 2, 0, 73, 37, 0, 69, 73, 65, 0, 73, 2, 0, 73, 37, 0, 69, 73, 66, 0, 73, 2, 0, 73, 37, 0, 69, 73, 67, 0, 73, 2, 0, 73, 37, 0, 69, 73, 68, 0, 73, 2, - 0, 73, 37, 0, 69, 77, 3, 1, 98, 76, 73, 57, 0, 69, 73, 0, 0, 73, 2, 0, 73, 3, 0, 69, 73, 6, 0, 73, 2, 0, 73, 3, 0, 69, 73, 7, 0, 73, 2, 0, 73, 3, 0, 69, 73, 8, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 9, 0, 73, 2, 0, 73, 3, 0, 69, 73, 10, 0, 73, 2, 0, 73, 3, 0, 69, 73, 11, 0, 73, 2, 0, 73, 3, 0, 69, 73, 12, 0, 73, 2, 0, 73, 3, 0, 69, 73, 13, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 14, 0, 73, 2, 0, 73, 3, 0, 69, 73, 15, 0, 73, 2, 0, 73, 3, 0, 69, 73, 16, 0, 73, 2, 0, 73, 3, 0, 69, 73, 17, 0, 73, 2, 0, 73, 3, 0, 69, 73, 18, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 19, 0, 73, 2, 0, 73, 3, 0, 69, 73, 20, 0, 73, 2, 0, 73, 3, 0, 69, 73, 21, 0, 73, 2, 0, 73, 3, 0, 69, 73, 22, 0, 73, 2, 0, 73, 3, 0, 69, 73, 23, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 24, 0, 73, 2, 0, 73, 3, 0, 69, 73, 25, 0, 73, 2, 0, 73, 3, 0, 69, 73, 26, 0, 73, 2, 0, 73, 3, 0, 69, 73, 27, 0, 73, 2, 0, 73, 3, 0, 69, 73, 28, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 29, 0, 73, 2, 0, 73, 3, 0, 69, 73, 30, 0, 73, 2, 0, 73, 3, 0, 69, 73, 31, 0, 73, 2, 0, 73, 3, 0, 69, 73, 32, 0, 73, 2, 0, 73, 3, 0, 69, 73, 33, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 34, 0, 73, 2, 0, 73, 3, 0, 69, 73, 35, 0, 73, 2, 0, 73, 3, 0, 69, 73, 36, 0, 73, 2, 0, 73, 3, 0, 69, 73, 37, 0, 73, 2, 0, 73, 3, 0, 69, 73, 38, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 39, 0, 73, 2, 0, 73, 3, 0, 69, 73, 40, 0, 73, 2, 0, 73, 3, 0, 69, 73, 41, 0, 73, 2, 0, 73, 3, 0, 69, 73, 42, 0, 73, 2, 0, 73, 3, 0, 69, 73, 43, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 44, 0, 73, 2, 0, 73, 3, 0, 69, 73, 45, 0, 73, 2, 0, 73, 3, 0, 69, 73, 46, 0, 73, 2, 0, 73, 3, 0, 69, 73, 47, 0, 73, 2, 0, 73, 3, 0, 69, 73, 48, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 49, 0, 73, 2, 0, 73, 3, 0, 69, 73, 50, 0, 73, 2, 0, 73, 3, 0, 69, 73, 51, 0, 73, 2, 0, 73, 3, 0, 69, 73, 52, 0, 73, 2, 0, 73, 3, 0, 69, 73, 53, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 54, 0, 73, 2, 0, 73, 3, 0, 69, 73, 55, 0, 73, 2, 0, 73, 3, 0, 69, 73, 56, 0, 73, 2, 0, 73, 3, 0, 69, 73, 57, 0, 73, 2, 0, 73, 3, 0, 69, 73, 58, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 59, 0, 73, 2, 0, 73, 3, 0, 69, 73, 60, 0, 73, 2, 0, 73, 3, 0, 69, 73, 61, 0, 73, 2, 0, 73, 3, 0, 69, 73, 62, 0, 73, 2, 0, 73, 3, 0, 69, 73, 63, 0, 73, 2, 0, - 73, 3, 0, 69, 73, 64, 0, 73, 2, 0, 73, 3, 0, 69, 73, 65, 0, 73, 2, 0, 73, 3, 0, 69, 73, 66, 0, 73, 2, 0, 73, 3, 0, 69, 73, 67, 0, 73, 2, 0, 73, 3, 0, 69, 73, 68, 0, 73, 2, 0, - 73, 3, 0, 69, 77, 3, 1, 98, 76, 73, 58, 0, 69, 73, 0, 0, 73, 2, 0, 73, 7, 0, 69, 73, 6, 0, 73, 2, 0, 73, 7, 0, 69, 73, 7, 0, 73, 2, 0, 73, 7, 0, 69, 73, 8, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 9, 0, 73, 2, 0, 73, 7, 0, 69, 73, 10, 0, 73, 2, 0, 73, 7, 0, 69, 73, 11, 0, 73, 2, 0, 73, 7, 0, 69, 73, 12, 0, 73, 2, 0, 73, 7, 0, 69, 73, 13, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 14, 0, 73, 2, 0, 73, 7, 0, 69, 73, 15, 0, 73, 2, 0, 73, 7, 0, 69, 73, 16, 0, 73, 2, 0, 73, 7, 0, 69, 73, 17, 0, 73, 2, 0, 73, 7, 0, 69, 73, 18, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 19, 0, 73, 2, 0, 73, 7, 0, 69, 73, 20, 0, 73, 2, 0, 73, 7, 0, 69, 73, 21, 0, 73, 2, 0, 73, 7, 0, 69, 73, 22, 0, 73, 2, 0, 73, 7, 0, 69, 73, 23, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 24, 0, 73, 2, 0, 73, 7, 0, 69, 73, 25, 0, 73, 2, 0, 73, 7, 0, 69, 73, 26, 0, 73, 2, 0, 73, 7, 0, 69, 73, 27, 0, 73, 2, 0, 73, 7, 0, 69, 73, 28, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 29, 0, 73, 2, 0, 73, 7, 0, 69, 73, 30, 0, 73, 2, 0, 73, 7, 0, 69, 73, 31, 0, 73, 2, 0, 73, 7, 0, 69, 73, 32, 0, 73, 2, 0, 73, 7, 0, 69, 73, 33, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 34, 0, 73, 2, 0, 73, 7, 0, 69, 73, 35, 0, 73, 2, 0, 73, 7, 0, 69, 73, 36, 0, 73, 2, 0, 73, 7, 0, 69, 73, 37, 0, 73, 2, 0, 73, 7, 0, 69, 73, 38, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 39, 0, 73, 2, 0, 73, 7, 0, 69, 73, 40, 0, 73, 2, 0, 73, 7, 0, 69, 73, 41, 0, 73, 2, 0, 73, 7, 0, 69, 73, 42, 0, 73, 2, 0, 73, 7, 0, 69, 73, 43, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 44, 0, 73, 2, 0, 73, 7, 0, 69, 73, 45, 0, 73, 2, 0, 73, 7, 0, 69, 73, 46, 0, 73, 2, 0, 73, 7, 0, 69, 73, 47, 0, 73, 2, 0, 73, 7, 0, 69, 73, 48, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 49, 0, 73, 2, 0, 73, 7, 0, 69, 73, 50, 0, 73, 2, 0, 73, 7, 0, 69, 73, 51, 0, 73, 2, 0, 73, 7, 0, 69, 73, 52, 0, 73, 2, 0, 73, 7, 0, 69, 73, 53, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 54, 0, 73, 2, 0, 73, 7, 0, 69, 73, 55, 0, 73, 2, 0, 73, 7, 0, 69, 73, 56, 0, 73, 2, 0, 73, 7, 0, 69, 73, 57, 0, 73, 2, 0, 73, 7, 0, 69, 73, 58, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 59, 0, 73, 2, 0, 73, 7, 0, 69, 73, 60, 0, 73, 2, 0, 73, 7, 0, 69, 73, 61, 0, 73, 2, 0, 73, 7, 0, 69, 73, 62, 0, 73, 2, 0, 73, 7, 0, 69, 73, 63, 0, 73, 2, 0, 73, - 7, 0, 69, 73, 64, 0, 73, 2, 0, 73, 7, 0, 69, 73, 65, 0, 73, 2, 0, 73, 7, 0, 69, 73, 66, 0, 73, 2, 0, 73, 7, 0, 69, 73, 67, 0, 73, 2, 0, 73, 7, 0, 69, 73, 68, 0, 73, 2, 0, 73, - 7, 0, 69, 77, 3, 1, 98, 76, 73, 59, 0, 69, 73, 0, 0, 73, 2, 0, 73, 6, 0, 69, 73, 6, 0, 73, 2, 0, 73, 6, 0, 69, 73, 7, 0, 73, 2, 0, 73, 6, 0, 69, 73, 8, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 9, 0, 73, 2, 0, 73, 6, 0, 69, 73, 10, 0, 73, 2, 0, 73, 6, 0, 69, 73, 11, 0, 73, 2, 0, 73, 6, 0, 69, 73, 12, 0, 73, 2, 0, 73, 6, 0, 69, 73, 13, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 14, 0, 73, 2, 0, 73, 6, 0, 69, 73, 15, 0, 73, 2, 0, 73, 6, 0, 69, 73, 16, 0, 73, 2, 0, 73, 6, 0, 69, 73, 17, 0, 73, 2, 0, 73, 6, 0, 69, 73, 18, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 19, 0, 73, 2, 0, 73, 6, 0, 69, 73, 20, 0, 73, 2, 0, 73, 6, 0, 69, 73, 21, 0, 73, 2, 0, 73, 6, 0, 69, 73, 22, 0, 73, 2, 0, 73, 6, 0, 69, 73, 23, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 24, 0, 73, 2, 0, 73, 6, 0, 69, 73, 25, 0, 73, 2, 0, 73, 6, 0, 69, 73, 26, 0, 73, 2, 0, 73, 6, 0, 69, 73, 27, 0, 73, 2, 0, 73, 6, 0, 69, 73, 28, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 29, 0, 73, 2, 0, 73, 6, 0, 69, 73, 30, 0, 73, 2, 0, 73, 6, 0, 69, 73, 31, 0, 73, 2, 0, 73, 6, 0, 69, 73, 32, 0, 73, 2, 0, 73, 6, 0, 69, 73, 33, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 34, 0, 73, 2, 0, 73, 6, 0, 69, 73, 35, 0, 73, 2, 0, 73, 6, 0, 69, 73, 36, 0, 73, 2, 0, 73, 6, 0, 69, 73, 37, 0, 73, 2, 0, 73, 6, 0, 69, 73, 38, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 39, 0, 73, 2, 0, 73, 6, 0, 69, 73, 40, 0, 73, 2, 0, 73, 6, 0, 69, 73, 41, 0, 73, 2, 0, 73, 6, 0, 69, 73, 42, 0, 73, 2, 0, 73, 6, 0, 69, 73, 43, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 44, 0, 73, 2, 0, 73, 6, 0, 69, 73, 45, 0, 73, 2, 0, 73, 6, 0, 69, 73, 46, 0, 73, 2, 0, 73, 6, 0, 69, 73, 47, 0, 73, 2, 0, 73, 6, 0, 69, 73, 48, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 49, 0, 73, 2, 0, 73, 6, 0, 69, 73, 50, 0, 73, 2, 0, 73, 6, 0, 69, 73, 51, 0, 73, 2, 0, 73, 6, 0, 69, 73, 52, 0, 73, 2, 0, 73, 6, 0, 69, 73, 53, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 54, 0, 73, 2, 0, 73, 6, 0, 69, 73, 55, 0, 73, 2, 0, 73, 6, 0, 69, 73, 56, 0, 73, 2, 0, 73, 6, 0, 69, 73, 57, 0, 73, 2, 0, 73, 6, 0, 69, 73, 58, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 59, 0, 73, 2, 0, 73, 6, 0, 69, 73, 60, 0, 73, 2, 0, 73, 6, 0, 69, 73, 61, 0, 73, 2, 0, 73, 6, 0, 69, 73, 62, 0, 73, 2, 0, 73, 6, 0, 69, 73, 63, 0, 73, 2, 0, 73, 6, - 0, 69, 73, 64, 0, 73, 2, 0, 73, 6, 0, 69, 73, 65, 0, 73, 2, 0, 73, 6, 0, 69, 73, 66, 0, 73, 2, 0, 73, 6, 0, 69, 73, 67, 0, 73, 2, 0, 73, 6, 0, 69, 73, 68, 0, 73, 2, 0, 73, 6, - 0, 69, 77, 3, 1, 98, 76, 73, 60, 0, 69, 73, 0, 0, 73, 2, 0, 73, 12, 0, 69, 73, 6, 0, 73, 2, 0, 73, 12, 0, 69, 73, 7, 0, 73, 2, 0, 73, 12, 0, 69, 73, 8, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 9, 0, 73, 2, 0, 73, 12, 0, 69, 73, 10, 0, 73, 2, 0, 73, 12, 0, 69, 73, 11, 0, 73, 2, 0, 73, 12, 0, 69, 73, 12, 0, 73, 2, 0, 73, 12, 0, 69, 73, 13, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 14, 0, 73, 2, 0, 73, 12, 0, 69, 73, 15, 0, 73, 2, 0, 73, 12, 0, 69, 73, 16, 0, 73, 2, 0, 73, 12, 0, 69, 73, 17, 0, 73, 2, 0, 73, 12, 0, 69, 73, 18, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 19, 0, 73, 2, 0, 73, 12, 0, 69, 73, 20, 0, 73, 2, 0, 73, 12, 0, 69, 73, 21, 0, 73, 2, 0, 73, 12, 0, 69, 73, 22, 0, 73, 2, 0, 73, 12, 0, 69, 73, 23, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 24, 0, 73, 2, 0, 73, 12, 0, 69, 73, 25, 0, 73, 2, 0, 73, 12, 0, 69, 73, 26, 0, 73, 2, 0, 73, 12, 0, 69, 73, 27, 0, 73, 2, 0, 73, 12, 0, 69, 73, 28, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 29, 0, 73, 2, 0, 73, 12, 0, 69, 73, 30, 0, 73, 2, 0, 73, 12, 0, 69, 73, 31, 0, 73, 2, 0, 73, 12, 0, 69, 73, 32, 0, 73, 2, 0, 73, 12, 0, 69, 73, 33, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 34, 0, 73, 2, 0, 73, 12, 0, 69, 73, 35, 0, 73, 2, 0, 73, 12, 0, 69, 73, 36, 0, 73, 2, 0, 73, 12, 0, 69, 73, 37, 0, 73, 2, 0, 73, 12, 0, 69, 73, 38, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 39, 0, 73, 2, 0, 73, 12, 0, 69, 73, 40, 0, 73, 2, 0, 73, 12, 0, 69, 73, 41, 0, 73, 2, 0, 73, 12, 0, 69, 73, 42, 0, 73, 2, 0, 73, 12, 0, 69, 73, 43, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 44, 0, 73, 2, 0, 73, 12, 0, 69, 73, 45, 0, 73, 2, 0, 73, 12, 0, 69, 73, 46, 0, 73, 2, 0, 73, 12, 0, 69, 73, 47, 0, 73, 2, 0, 73, 12, 0, 69, 73, 48, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 49, 0, 73, 2, 0, 73, 12, 0, 69, 73, 50, 0, 73, 2, 0, 73, 12, 0, 69, 73, 51, 0, 73, 2, 0, 73, 12, 0, 69, 73, 52, 0, 73, 2, 0, 73, 12, 0, 69, 73, 53, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 54, 0, 73, 2, 0, 73, 12, 0, 69, 73, 55, 0, 73, 2, 0, 73, 12, 0, 69, 73, 56, 0, 73, 2, 0, 73, 12, 0, 69, 73, 57, 0, 73, 2, 0, 73, 12, 0, 69, 73, 58, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 59, 0, 73, 2, 0, 73, 12, 0, 69, 73, 60, 0, 73, 2, 0, 73, 12, 0, 69, 73, 61, 0, 73, 2, 0, 73, 12, 0, 69, 73, 62, 0, 73, 2, 0, 73, 12, 0, 69, 73, 63, 0, 73, 2, 0, 73, 12, 0, - 69, 73, 64, 0, 73, 2, 0, 73, 12, 0, 69, 73, 65, 0, 73, 2, 0, 73, 12, 0, 69, 73, 66, 0, 73, 2, 0, 73, 12, 0, 69, 73, 67, 0, 73, 2, 0, 73, 12, 0, 69, 73, 68, 0, 73, 2, 0, 73, 12, 0, - 69, 77, 3, 1, 98, 76, 73, 61, 0, 69, 73, 0, 0, 73, 2, 0, 73, 31, 0, 69, 73, 6, 0, 73, 2, 0, 73, 31, 0, 69, 73, 7, 0, 73, 2, 0, 73, 31, 0, 69, 73, 8, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 9, 0, 73, 2, 0, 73, 31, 0, 69, 73, 10, 0, 73, 2, 0, 73, 31, 0, 69, 73, 11, 0, 73, 2, 0, 73, 31, 0, 69, 73, 12, 0, 73, 2, 0, 73, 31, 0, 69, 73, 13, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 14, 0, 73, 2, 0, 73, 31, 0, 69, 73, 15, 0, 73, 2, 0, 73, 31, 0, 69, 73, 16, 0, 73, 2, 0, 73, 31, 0, 69, 73, 17, 0, 73, 2, 0, 73, 31, 0, 69, 73, 18, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 19, 0, 73, 2, 0, 73, 31, 0, 69, 73, 20, 0, 73, 2, 0, 73, 31, 0, 69, 73, 21, 0, 73, 2, 0, 73, 31, 0, 69, 73, 22, 0, 73, 2, 0, 73, 31, 0, 69, 73, 23, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 24, 0, 73, 2, 0, 73, 31, 0, 69, 73, 25, 0, 73, 2, 0, 73, 31, 0, 69, 73, 26, 0, 73, 2, 0, 73, 31, 0, 69, 73, 27, 0, 73, 2, 0, 73, 31, 0, 69, 73, 28, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 29, 0, 73, 2, 0, 73, 31, 0, 69, 73, 30, 0, 73, 2, 0, 73, 31, 0, 69, 73, 31, 0, 73, 2, 0, 73, 31, 0, 69, 73, 32, 0, 73, 2, 0, 73, 31, 0, 69, 73, 33, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 34, 0, 73, 2, 0, 73, 31, 0, 69, 73, 35, 0, 73, 2, 0, 73, 31, 0, 69, 73, 36, 0, 73, 2, 0, 73, 31, 0, 69, 73, 37, 0, 73, 2, 0, 73, 31, 0, 69, 73, 38, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 39, 0, 73, 2, 0, 73, 31, 0, 69, 73, 40, 0, 73, 2, 0, 73, 31, 0, 69, 73, 41, 0, 73, 2, 0, 73, 31, 0, 69, 73, 42, 0, 73, 2, 0, 73, 31, 0, 69, 73, 43, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 44, 0, 73, 2, 0, 73, 31, 0, 69, 73, 45, 0, 73, 2, 0, 73, 31, 0, 69, 73, 46, 0, 73, 2, 0, 73, 31, 0, 69, 73, 47, 0, 73, 2, 0, 73, 31, 0, 69, 73, 48, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 49, 0, 73, 2, 0, 73, 31, 0, 69, 73, 50, 0, 73, 2, 0, 73, 31, 0, 69, 73, 51, 0, 73, 2, 0, 73, 31, 0, 69, 73, 52, 0, 73, 2, 0, 73, 31, 0, 69, 73, 53, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 54, 0, 73, 2, 0, 73, 31, 0, 69, 73, 55, 0, 73, 2, 0, 73, 31, 0, 69, 73, 56, 0, 73, 2, 0, 73, 31, 0, 69, 73, 57, 0, 73, 2, 0, 73, 31, 0, 69, 73, 58, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 59, 0, 73, 2, 0, 73, 31, 0, 69, 73, 60, 0, 73, 2, 0, 73, 31, 0, 69, 73, 61, 0, 73, 2, 0, 73, 31, 0, 69, 73, 62, 0, 73, 2, 0, 73, 31, 0, 69, 73, 63, 0, 73, 2, 0, 73, 31, 0, 69, - 73, 64, 0, 73, 2, 0, 73, 31, 0, 69, 73, 65, 0, 73, 2, 0, 73, 31, 0, 69, 73, 66, 0, 73, 2, 0, 73, 31, 0, 69, 73, 67, 0, 73, 2, 0, 73, 31, 0, 69, 73, 68, 0, 73, 2, 0, 73, 31, 0, 69, - 77, 3, 1, 98, 76, 73, 62, 0, 69, 73, 0, 0, 73, 2, 0, 73, 16, 0, 69, 73, 6, 0, 73, 2, 0, 73, 16, 0, 69, 73, 7, 0, 73, 2, 0, 73, 16, 0, 69, 73, 8, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 9, 0, 73, 2, 0, 73, 16, 0, 69, 73, 10, 0, 73, 2, 0, 73, 16, 0, 69, 73, 11, 0, 73, 2, 0, 73, 16, 0, 69, 73, 12, 0, 73, 2, 0, 73, 16, 0, 69, 73, 13, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 14, 0, 73, 2, 0, 73, 16, 0, 69, 73, 15, 0, 73, 2, 0, 73, 16, 0, 69, 73, 16, 0, 73, 2, 0, 73, 16, 0, 69, 73, 17, 0, 73, 2, 0, 73, 16, 0, 69, 73, 18, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 19, 0, 73, 2, 0, 73, 16, 0, 69, 73, 20, 0, 73, 2, 0, 73, 16, 0, 69, 73, 21, 0, 73, 2, 0, 73, 16, 0, 69, 73, 22, 0, 73, 2, 0, 73, 16, 0, 69, 73, 23, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 24, 0, 73, 2, 0, 73, 16, 0, 69, 73, 25, 0, 73, 2, 0, 73, 16, 0, 69, 73, 26, 0, 73, 2, 0, 73, 16, 0, 69, 73, 27, 0, 73, 2, 0, 73, 16, 0, 69, 73, 28, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 29, 0, 73, 2, 0, 73, 16, 0, 69, 73, 30, 0, 73, 2, 0, 73, 16, 0, 69, 73, 31, 0, 73, 2, 0, 73, 16, 0, 69, 73, 32, 0, 73, 2, 0, 73, 16, 0, 69, 73, 33, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 34, 0, 73, 2, 0, 73, 16, 0, 69, 73, 35, 0, 73, 2, 0, 73, 16, 0, 69, 73, 36, 0, 73, 2, 0, 73, 16, 0, 69, 73, 37, 0, 73, 2, 0, 73, 16, 0, 69, 73, 38, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 39, 0, 73, 2, 0, 73, 16, 0, 69, 73, 40, 0, 73, 2, 0, 73, 16, 0, 69, 73, 41, 0, 73, 2, 0, 73, 16, 0, 69, 73, 42, 0, 73, 2, 0, 73, 16, 0, 69, 73, 43, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 44, 0, 73, 2, 0, 73, 16, 0, 69, 73, 45, 0, 73, 2, 0, 73, 16, 0, 69, 73, 46, 0, 73, 2, 0, 73, 16, 0, 69, 73, 47, 0, 73, 2, 0, 73, 16, 0, 69, 73, 48, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 49, 0, 73, 2, 0, 73, 16, 0, 69, 73, 50, 0, 73, 2, 0, 73, 16, 0, 69, 73, 51, 0, 73, 2, 0, 73, 16, 0, 69, 73, 52, 0, 73, 2, 0, 73, 16, 0, 69, 73, 53, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 54, 0, 73, 2, 0, 73, 16, 0, 69, 73, 55, 0, 73, 2, 0, 73, 16, 0, 69, 73, 56, 0, 73, 2, 0, 73, 16, 0, 69, 73, 57, 0, 73, 2, 0, 73, 16, 0, 69, 73, 58, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 59, 0, 73, 2, 0, 73, 16, 0, 69, 73, 60, 0, 73, 2, 0, 73, 16, 0, 69, 73, 61, 0, 73, 2, 0, 73, 16, 0, 69, 73, 62, 0, 73, 2, 0, 73, 16, 0, 69, 73, 63, 0, 73, 2, 0, 73, 16, 0, 69, 73, - 64, 0, 73, 2, 0, 73, 16, 0, 69, 73, 65, 0, 73, 2, 0, 73, 16, 0, 69, 73, 66, 0, 73, 2, 0, 73, 16, 0, 69, 73, 67, 0, 73, 2, 0, 73, 16, 0, 69, 73, 68, 0, 73, 2, 0, 73, 16, 0, 69, 77, - 3, 1, 98, 76, 73, 63, 0, 69, 73, 0, 0, 73, 2, 0, 73, 0, 0, 69, 73, 6, 0, 73, 2, 0, 73, 0, 0, 69, 73, 7, 0, 73, 2, 0, 73, 0, 0, 69, 73, 8, 0, 73, 2, 0, 73, 0, 0, 69, 73, 9, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 10, 0, 73, 2, 0, 73, 0, 0, 69, 73, 11, 0, 73, 2, 0, 73, 0, 0, 69, 73, 12, 0, 73, 2, 0, 73, 0, 0, 69, 73, 13, 0, 73, 2, 0, 73, 0, 0, 69, 73, 14, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 15, 0, 73, 2, 0, 73, 0, 0, 69, 73, 16, 0, 73, 2, 0, 73, 0, 0, 69, 73, 17, 0, 73, 2, 0, 73, 0, 0, 69, 73, 18, 0, 73, 2, 0, 73, 0, 0, 69, 73, 19, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 20, 0, 73, 2, 0, 73, 0, 0, 69, 73, 21, 0, 73, 2, 0, 73, 0, 0, 69, 73, 22, 0, 73, 2, 0, 73, 0, 0, 69, 73, 23, 0, 73, 2, 0, 73, 0, 0, 69, 73, 24, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 25, 0, 73, 2, 0, 73, 0, 0, 69, 73, 26, 0, 73, 2, 0, 73, 0, 0, 69, 73, 27, 0, 73, 2, 0, 73, 0, 0, 69, 73, 28, 0, 73, 2, 0, 73, 0, 0, 69, 73, 29, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 30, 0, 73, 2, 0, 73, 0, 0, 69, 73, 31, 0, 73, 2, 0, 73, 0, 0, 69, 73, 32, 0, 73, 2, 0, 73, 0, 0, 69, 73, 33, 0, 73, 2, 0, 73, 0, 0, 69, 73, 34, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 35, 0, 73, 2, 0, 73, 0, 0, 69, 73, 36, 0, 73, 2, 0, 73, 0, 0, 69, 73, 37, 0, 73, 2, 0, 73, 0, 0, 69, 73, 38, 0, 73, 2, 0, 73, 0, 0, 69, 73, 39, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 40, 0, 73, 2, 0, 73, 0, 0, 69, 73, 41, 0, 73, 2, 0, 73, 0, 0, 69, 73, 42, 0, 73, 2, 0, 73, 0, 0, 69, 73, 43, 0, 73, 2, 0, 73, 0, 0, 69, 73, 44, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 45, 0, 73, 2, 0, 73, 0, 0, 69, 73, 46, 0, 73, 2, 0, 73, 0, 0, 69, 73, 47, 0, 73, 2, 0, 73, 0, 0, 69, 73, 48, 0, 73, 2, 0, 73, 0, 0, 69, 73, 49, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 50, 0, 73, 2, 0, 73, 0, 0, 69, 73, 51, 0, 73, 2, 0, 73, 0, 0, 69, 73, 52, 0, 73, 2, 0, 73, 0, 0, 69, 73, 53, 0, 73, 2, 0, 73, 0, 0, 69, 73, 54, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 55, 0, 73, 2, 0, 73, 0, 0, 69, 73, 56, 0, 73, 2, 0, 73, 0, 0, 69, 73, 57, 0, 73, 2, 0, 73, 0, 0, 69, 73, 58, 0, 73, 2, 0, 73, 0, 0, 69, 73, 59, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 60, 0, 73, 2, 0, 73, 0, 0, 69, 73, 61, 0, 73, 2, 0, 73, 0, 0, 69, 73, 62, 0, 73, 2, 0, 73, 0, 0, 69, 73, 63, 0, 73, 2, 0, 73, 0, 0, 69, 73, 64, - 0, 73, 2, 0, 73, 0, 0, 69, 73, 65, 0, 73, 2, 0, 73, 0, 0, 69, 73, 66, 0, 73, 2, 0, 73, 0, 0, 69, 73, 67, 0, 73, 2, 0, 73, 0, 0, 69, 73, 68, 0, 73, 2, 0, 73, 0, 0, 69, 77, 3, - 1, 98, 76, 73, 64, 0, 69, 73, 0, 0, 73, 2, 0, 73, 63, 0, 69, 73, 6, 0, 73, 2, 0, 73, 63, 0, 69, 73, 7, 0, 73, 2, 0, 73, 63, 0, 69, 73, 8, 0, 73, 2, 0, 73, 63, 0, 69, 73, 9, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 10, 0, 73, 2, 0, 73, 63, 0, 69, 73, 11, 0, 73, 2, 0, 73, 63, 0, 69, 73, 12, 0, 73, 2, 0, 73, 63, 0, 69, 73, 13, 0, 73, 2, 0, 73, 63, 0, 69, 73, 14, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 15, 0, 73, 2, 0, 73, 63, 0, 69, 73, 16, 0, 73, 2, 0, 73, 63, 0, 69, 73, 17, 0, 73, 2, 0, 73, 63, 0, 69, 73, 18, 0, 73, 2, 0, 73, 63, 0, 69, 73, 19, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 20, 0, 73, 2, 0, 73, 63, 0, 69, 73, 21, 0, 73, 2, 0, 73, 63, 0, 69, 73, 22, 0, 73, 2, 0, 73, 63, 0, 69, 73, 23, 0, 73, 2, 0, 73, 63, 0, 69, 73, 24, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 25, 0, 73, 2, 0, 73, 63, 0, 69, 73, 26, 0, 73, 2, 0, 73, 63, 0, 69, 73, 27, 0, 73, 2, 0, 73, 63, 0, 69, 73, 28, 0, 73, 2, 0, 73, 63, 0, 69, 73, 29, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 30, 0, 73, 2, 0, 73, 63, 0, 69, 73, 31, 0, 73, 2, 0, 73, 63, 0, 69, 73, 32, 0, 73, 2, 0, 73, 63, 0, 69, 73, 33, 0, 73, 2, 0, 73, 63, 0, 69, 73, 34, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 35, 0, 73, 2, 0, 73, 63, 0, 69, 73, 36, 0, 73, 2, 0, 73, 63, 0, 69, 73, 37, 0, 73, 2, 0, 73, 63, 0, 69, 73, 38, 0, 73, 2, 0, 73, 63, 0, 69, 73, 39, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 40, 0, 73, 2, 0, 73, 63, 0, 69, 73, 41, 0, 73, 2, 0, 73, 63, 0, 69, 73, 42, 0, 73, 2, 0, 73, 63, 0, 69, 73, 43, 0, 73, 2, 0, 73, 63, 0, 69, 73, 44, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 45, 0, 73, 2, 0, 73, 63, 0, 69, 73, 46, 0, 73, 2, 0, 73, 63, 0, 69, 73, 47, 0, 73, 2, 0, 73, 63, 0, 69, 73, 48, 0, 73, 2, 0, 73, 63, 0, 69, 73, 49, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 50, 0, 73, 2, 0, 73, 63, 0, 69, 73, 51, 0, 73, 2, 0, 73, 63, 0, 69, 73, 52, 0, 73, 2, 0, 73, 63, 0, 69, 73, 53, 0, 73, 2, 0, 73, 63, 0, 69, 73, 54, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 55, 0, 73, 2, 0, 73, 63, 0, 69, 73, 56, 0, 73, 2, 0, 73, 63, 0, 69, 73, 57, 0, 73, 2, 0, 73, 63, 0, 69, 73, 58, 0, 73, 2, 0, 73, 63, 0, 69, 73, 59, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 60, 0, 73, 2, 0, 73, 63, 0, 69, 73, 61, 0, 73, 2, 0, 73, 63, 0, 69, 73, 62, 0, 73, 2, 0, 73, 63, 0, 69, 73, 63, 0, 73, 2, 0, 73, 63, 0, 69, 73, 64, 0, - 73, 2, 0, 73, 63, 0, 69, 73, 65, 0, 73, 2, 0, 73, 63, 0, 69, 73, 66, 0, 73, 2, 0, 73, 63, 0, 69, 73, 67, 0, 73, 2, 0, 73, 63, 0, 69, 73, 68, 0, 73, 2, 0, 73, 63, 0, 69, 77, 7, 1, - 98, 76, 73, 65, 0, 69, 73, 0, 0, 73, 4, 0, 73, 0, 0, 69, 73, 6, 0, 73, 1, 0, 73, 1, 0, 69, 73, 7, 0, 73, 1, 0, 73, 2, 0, 69, 73, 8, 0, 73, 1, 0, 73, 3, 0, 69, 73, 9, 0, 73, - 1, 0, 73, 4, 0, 69, 73, 10, 0, 73, 1, 0, 73, 5, 0, 69, 73, 11, 0, 73, 1, 0, 73, 6, 0, 69, 73, 12, 0, 73, 1, 0, 73, 7, 0, 69, 73, 13, 0, 73, 1, 0, 73, 8, 0, 69, 73, 14, 0, 73, - 1, 0, 73, 9, 0, 69, 73, 15, 0, 73, 1, 0, 73, 10, 0, 69, 73, 16, 0, 73, 1, 0, 73, 11, 0, 69, 73, 17, 0, 73, 1, 0, 73, 12, 0, 69, 73, 18, 0, 73, 1, 0, 73, 13, 0, 69, 73, 19, 0, 73, - 1, 0, 73, 14, 0, 69, 73, 20, 0, 73, 1, 0, 73, 15, 0, 69, 73, 21, 0, 73, 1, 0, 73, 16, 0, 69, 73, 22, 0, 73, 1, 0, 73, 17, 0, 69, 73, 23, 0, 73, 1, 0, 73, 18, 0, 69, 73, 24, 0, 73, - 1, 0, 73, 19, 0, 69, 73, 25, 0, 73, 1, 0, 73, 20, 0, 69, 73, 26, 0, 73, 1, 0, 73, 21, 0, 69, 73, 27, 0, 73, 1, 0, 73, 22, 0, 69, 73, 28, 0, 73, 1, 0, 73, 23, 0, 69, 73, 29, 0, 73, - 1, 0, 73, 24, 0, 69, 73, 30, 0, 73, 1, 0, 73, 25, 0, 69, 73, 31, 0, 73, 1, 0, 73, 26, 0, 69, 73, 32, 0, 73, 1, 0, 73, 27, 0, 69, 73, 33, 0, 73, 1, 0, 73, 28, 0, 69, 73, 34, 0, 73, - 1, 0, 73, 29, 0, 69, 73, 35, 0, 73, 1, 0, 73, 30, 0, 69, 73, 36, 0, 73, 1, 0, 73, 31, 0, 69, 73, 37, 0, 73, 1, 0, 73, 32, 0, 69, 73, 38, 0, 73, 1, 0, 73, 33, 0, 69, 73, 39, 0, 73, - 1, 0, 73, 34, 0, 69, 73, 40, 0, 73, 1, 0, 73, 35, 0, 69, 73, 41, 0, 73, 1, 0, 73, 36, 0, 69, 73, 42, 0, 73, 1, 0, 73, 37, 0, 69, 73, 43, 0, 73, 1, 0, 73, 38, 0, 69, 73, 44, 0, 73, - 1, 0, 73, 39, 0, 69, 73, 45, 0, 73, 1, 0, 73, 40, 0, 69, 73, 46, 0, 73, 1, 0, 73, 41, 0, 69, 73, 47, 0, 73, 1, 0, 73, 42, 0, 69, 73, 48, 0, 73, 1, 0, 73, 43, 0, 69, 73, 49, 0, 73, - 1, 0, 73, 44, 0, 69, 73, 50, 0, 73, 1, 0, 73, 45, 0, 69, 73, 51, 0, 73, 1, 0, 73, 46, 0, 69, 73, 52, 0, 73, 1, 0, 73, 47, 0, 69, 73, 53, 0, 73, 1, 0, 73, 48, 0, 69, 73, 54, 0, 73, - 1, 0, 73, 49, 0, 69, 73, 55, 0, 73, 1, 0, 73, 50, 0, 69, 73, 56, 0, 73, 1, 0, 73, 51, 0, 69, 73, 57, 0, 73, 1, 0, 73, 52, 0, 69, 73, 58, 0, 73, 1, 0, 73, 53, 0, 69, 73, 59, 0, 73, - 1, 0, 73, 54, 0, 69, 73, 60, 0, 73, 1, 0, 73, 55, 0, 69, 73, 61, 0, 73, 1, 0, 73, 56, 0, 69, 73, 62, 0, 73, 1, 0, 73, 57, 0, 69, 73, 63, 0, 73, 1, 0, 73, 58, 0, 69, 73, 64, 0, 73, - 1, 0, 73, 59, 0, 69, 73, 65, 0, 73, 1, 0, 73, 60, 0, 69, 73, 66, 0, 73, 1, 0, 73, 61, 0, 69, 73, 67, 0, 73, 1, 0, 73, 62, 0, 69, 73, 68, 0, 73, 1, 0, 73, 63, 0, 69, 73, 69, 0, 73, - 3, 0, 73, 66, 0, 69, 77, 3, 1, 98, 76, 73, 66, 0, 69, 73, 0, 0, 73, 2, 0, 73, 64, 0, 69, 73, 6, 0, 73, 2, 0, 73, 64, 0, 69, 73, 7, 0, 73, 2, 0, 73, 64, 0, 69, 73, 8, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 9, 0, 73, 2, 0, 73, 64, 0, 69, 73, 10, 0, 73, 2, 0, 73, 64, 0, 69, 73, 11, 0, 73, 2, 0, 73, 64, 0, 69, 73, 12, 0, 73, 2, 0, 73, 64, 0, 69, 73, 13, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 14, 0, 73, 2, 0, 73, 64, 0, 69, 73, 15, 0, 73, 2, 0, 73, 64, 0, 69, 73, 16, 0, 73, 2, 0, 73, 64, 0, 69, 73, 17, 0, 73, 2, 0, 73, 64, 0, 69, 73, 18, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 19, 0, 73, 2, 0, 73, 64, 0, 69, 73, 20, 0, 73, 2, 0, 73, 64, 0, 69, 73, 21, 0, 73, 2, 0, 73, 64, 0, 69, 73, 22, 0, 73, 2, 0, 73, 64, 0, 69, 73, 23, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 24, 0, 73, 2, 0, 73, 64, 0, 69, 73, 25, 0, 73, 2, 0, 73, 64, 0, 69, 73, 26, 0, 73, 2, 0, 73, 64, 0, 69, 73, 27, 0, 73, 2, 0, 73, 64, 0, 69, 73, 28, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 29, 0, 73, 2, 0, 73, 64, 0, 69, 73, 30, 0, 73, 2, 0, 73, 64, 0, 69, 73, 31, 0, 73, 2, 0, 73, 64, 0, 69, 73, 32, 0, 73, 2, 0, 73, 64, 0, 69, 73, 33, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 34, 0, 73, 2, 0, 73, 64, 0, 69, 73, 35, 0, 73, 2, 0, 73, 64, 0, 69, 73, 36, 0, 73, 2, 0, 73, 64, 0, 69, 73, 37, 0, 73, 2, 0, 73, 64, 0, 69, 73, 38, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 39, 0, 73, 2, 0, 73, 64, 0, 69, 73, 40, 0, 73, 2, 0, 73, 64, 0, 69, 73, 41, 0, 73, 2, 0, 73, 64, 0, 69, 73, 42, 0, 73, 2, 0, 73, 64, 0, 69, 73, 43, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 44, 0, 73, 2, 0, 73, 64, 0, 69, 73, 45, 0, 73, 2, 0, 73, 64, 0, 69, 73, 46, 0, 73, 2, 0, 73, 64, 0, 69, 73, 47, 0, 73, 2, 0, 73, 64, 0, 69, 73, 48, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 49, 0, 73, 2, 0, 73, 64, 0, 69, 73, 50, 0, 73, 2, 0, 73, 64, 0, 69, 73, 51, 0, 73, 2, 0, 73, 64, 0, 69, 73, 52, 0, 73, 2, 0, 73, 64, 0, 69, 73, 53, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 54, 0, 73, 2, 0, 73, 64, 0, 69, 73, 55, 0, 73, 2, 0, 73, 64, 0, 69, 73, 56, 0, 73, 2, 0, 73, 64, 0, 69, 73, 57, 0, 73, 2, 0, 73, 64, 0, 69, 73, 58, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 59, 0, 73, 2, 0, 73, 64, 0, 69, 73, 60, 0, 73, 2, 0, 73, 64, 0, 69, 73, 61, 0, 73, 2, 0, 73, 64, 0, 69, 73, 62, 0, 73, 2, 0, 73, 64, 0, 69, 73, 63, 0, 73, 2, - 0, 73, 64, 0, 69, 73, 64, 0, 73, 2, 0, 73, 64, 0, 69, 73, 65, 0, 73, 2, 0, 73, 64, 0, 69, 73, 66, 0, 73, 2, 0, 73, 64, 0, 69, 73, 67, 0, 73, 2, 0, 73, 64, 0, 69, 73, 68, 0, 73, 2, - 0, 73, 64, 0, 69 - }; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Properties/Resources.resx b/sources/shaders/Stride.Core.Shaders/Properties/Resources.resx deleted file mode 100644 index 5551ef353e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Properties/Resources.resx +++ /dev/null @@ -1,130 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - ..\Analysis\Hlsl\HlslDeclarations.h;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - - - ..\Convertor\Keywords.glsl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ..\Grammar\Tokenizer.cgt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders/Properties/Resources.tt b/sources/shaders/Stride.Core.Shaders/Properties/Resources.tt deleted file mode 100644 index abe1428097..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Properties/Resources.tt +++ /dev/null @@ -1,338 +0,0 @@ -<# -/* -Resource file to CSharp converter. It replaces the one provided by Visual Studio to circumvent the lack -of ResourceManager.GetObject in CoreCLR. The current version only handles string, string file and binary file resources. For file references, they are embedded in the generated Csharp. - -This is taken from T4Resx written and maintained Kenneth Baltrinic -http://blog.baltrinic.com - -Related blog posts: http://blog.baltrinic.com/software-development/dotnet/t4-template-replace-resxfilecodegenerator - -The certain parts of this template were copied from the T4MVC template which is distributed under the MvcContrib license (http://mvccontrib.codeplex.com/license) - -This template if free for redistribution in accordance with the same license. -*/ -#> -<#@ template debug="true" hostspecific="true" #> -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Xml" #> -<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #> -<#@ assembly name="EnvDTE" #> -<#@ assembly name="EnvDTE80" #> -<#@ assembly name="VSLangProj" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="System.CodeDom" #> -<#@ import namespace="System.CodeDom.Compiler" #> -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Text.RegularExpressions" #> -<#@ import namespace="System.Xml" #> -<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #> -<#@ import namespace="EnvDTE" #> -<#@ import namespace="EnvDTE80" #> -<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> -using System.Reflection; - -<# - var serviceProvider = Host as IServiceProvider; - if (serviceProvider != null) { - Dte = serviceProvider.GetService(typeof(SDTE)) as DTE; - } - - // Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe - if (Dte == null) { - throw new Exception("T4MVC can only execute through the Visual Studio host"); - } - - Project = GetProjectContainingT4File(Dte); - - if (Project == null) { - Error("Could not find the VS Project containing the T4 file."); - return"XX"; - } - - AppRoot = Path.GetDirectoryName(Project.FullName) + '\\'; - RootNamespace = Project.Properties.Item("RootNamespace").Value.ToString(); - -try{ - AllEntries = new List(); - FindResourceFilesRecursivlyAndRecordEntries(Project.ProjectItems, ""); - AllEntries.Sort( new Comparison( (e1, e2) => (e1.Path + e1.File + e1.Name).CompareTo(e2.Path + e2.File + e2.Name))); - - var currentNamespace = ""; - var currentClass = ""; - var thisIsFirstEntryInClass = true; - var names = new List(); - foreach(var entry in AllEntries) - { - //WriteLine("//" + entry.Path + ":" + entry.File+ ":" + entry.Name); - - var newNamespace = RootNamespace + "." + entry.Path; - var newClass = entry.File; - - bool namesapceIsChanging = newNamespace != currentNamespace; - bool classIsChanging = namesapceIsChanging || newClass != currentClass; - - if(namesapceIsChanging) - { - //Close out current namespace if one exists - if( currentNamespace != "" ) - WriteLine("}"); - - currentNamespace = newNamespace; - - //open new namespace - WriteLine(string.Format("namespace {0}", currentNamespace)); - WriteLine("{"); - - } - - if(classIsChanging) - { - currentClass = newClass; - WriteLine(string.Format("\tpublic class {0}", currentClass)); - WriteLine("\t{"); - thisIsFirstEntryInClass = true; - - //Emit code for the ResourceManager property and GetResourceString method for the current class - #> - private static global::System.Resources.ResourceManager resourceMan; - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - private static global::System.Resources.ResourceManager ResourceManager - { - get - { - if (object.ReferenceEquals(resourceMan, null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("<#=string.Format("{0}.{1}{2}", RootNamespace, entry.Path + "." + entry.File, entry.Type) #>", typeof(<#=entry.File#>).GetTypeInfo().Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - <# - } - - //Emit the static resource string access method for the current entry - if(entry.Comment != null) - { - if(!thisIsFirstEntryInClass) WriteLine(""); - WriteLine(string.Format("\r\n\t\t///\r\n\t\t///{0}\r\n\t\t///", entry.Comment.Replace("\r\n", "\r\n\t\t///"))); - } - else - WriteLine(""); - - //Select all tokens between braces that constitute valid identifiers - var tokens = Regex.Matches(entry.Value, @"{(([A-Za-z]{1}\w*?)|([A-Za-z_]{1}\w+?))?}").Cast().Select(m => m.Value); - - if(tokens.Any()) - { - var inParams = tokens.Aggregate("", (list, value) => list += ", string " + value).Replace("{", "").Replace("}", ""); - if(inParams.Length > 0 ) inParams = inParams.Substring(1); - var outParams = tokens.Aggregate("", (list, value) => list += ", \"" + value +"\", " + value.Replace("{", "").Replace("}", "") ); - - WriteLine(string.Format("\t\tpublic static string {0}({1}) {{ return ResourceManager.GetString(\"{0}\"{2}); }}", entry.Name, inParams, outParams)); - } - else - { - if (!entry.IsFileRef) - { - WriteLine(string.Format("\t\tpublic static string {0} {{ get {{ return ResourceManager.GetString(\"{0}\"); }} }}", entry.Name)); - } else { - string returnType = entry.TypeRef.FullName; - WriteLine (string.Format ("\t\tpublic static {0} {1}", returnType, entry.Name)); - WriteLine ("\t\t{"); - WriteLine ("\t\t\tget {"); - if (entry.TypeRef == typeof(string)) - { - Write ("\t\t\t\t return "); - Write (ToLiteral(File.ReadAllText (AppRoot + "\\" + entry.Path + "\\" + entry.FileRef))); - WriteLine (";"); - } - else - { - byte [] byteArray = File.ReadAllBytes (AppRoot + "\\" + entry.Path + "\\" + entry.FileRef); - int counter = 0; - Write ("\t\t\t\t return new byte [] {"); - for (int i = 0, nb = byteArray.Length; i < nb; i++ ) { - // Limit ourself to 50 entries per line. - if (counter % 50 == 0) - { - WriteLine (""); - Write ("\t\t\t\t\t"); - } - Write (byteArray [i].ToString()); - if (i < nb - 1) { - Write (", "); - } - counter++; - } - WriteLine (""); - WriteLine ("\t\t\t\t};"); - } - WriteLine ("\t\t\t}"); - WriteLine ("\t\t}"); - } - } - names.Add(entry.Name); - - thisIsFirstEntryInClass = false; - - } // foreach(var entry in AllEntries) - - //close out the current class when done - if(currentClass != "") - { - WriteLine("\t}"); - } -} -catch(Exception ex) -{ - Error(ex.ToString()); -} -#> -} -<#+ - const string Kind_PhysicalFolder = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}"; - bool AlwaysKeepTemplateDirty = true; - static DTE Dte; - static Project Project; - static string AppRoot; - static string RootNamespace; - static List AllEntries; - -void FindResourceFilesRecursivlyAndRecordEntries(ProjectItems items, string path) -{ - foreach(ProjectItem item in items) - { - if(Path.GetExtension(item.Name) == ".resx") - RecordEntriesInResourceFile(item, path); - if(item.Kind == Kind_PhysicalFolder) - FindResourceFilesRecursivlyAndRecordEntries(item.ProjectItems, path+"."+item.Name); - } -} - -void RecordEntriesInResourceFile(ProjectItem item, string path) -{ - //skip resource files except those for the default culture - if(Regex.IsMatch(item.Name, @".*\.[a-zA-z]{2}(-[a-zA-z]{2})?\.resx")) - return; - - var filePath = (string)item.Properties.Item("FullPath").Value; - var xml = new XmlDocument(); - xml.Load(filePath); - var entries = xml.DocumentElement.SelectNodes("//data"); - - var parentFile = item.Name.Replace(".resx", ""); - var fileType = Path.GetExtension(parentFile); - if(fileType != null && fileType != "") - parentFile = parentFile.Replace(fileType, ""); - - foreach (XmlElement entryElement in entries) - { - var entry = new ResourceEntry - { - Path = path.Substring(1), - File = MakeIntoValidIdentifier(parentFile), - Type = fileType, - IsFileRef = entryElement.Attributes["type"].Value.IndexOf ("System.Resources.ResXFileRef") >= 0, - Name = MakeIntoValidIdentifier(entryElement.Attributes["name"].Value) - }; - - var valueElement = entryElement.SelectSingleNode("value"); - if(valueElement != null) { - entry.Value = valueElement.InnerText; - if (entry.IsFileRef) { - string[] l_entries = entry.Value.Split (new char [1] {';'}); - if (l_entries.Length > 0) { - entry.FileRef = l_entries [0]; - } - if (l_entries.Length > 1) { - entry.TypeRef = Type.GetType (l_entries [1]); - } - } - } - var commentElement = entryElement.SelectSingleNode("comment"); - if(commentElement != null) - entry.Comment = commentElement.InnerText; - - AllEntries.Add(entry); - } -} - -string MakeIntoValidIdentifier(string arbitraryString) -{ - var validIdentifier = Regex.Replace(arbitraryString, @"[^A-Za-z0-9-._]", " "); - validIdentifier = ConvertToPascalCase(validIdentifier); - if (Regex.IsMatch(validIdentifier, @"^\d")) validIdentifier = "_" + validIdentifier; - return validIdentifier; -} - -string ConvertToPascalCase(string phrase) -{ - string[] splittedPhrase = phrase.Split(' ', '-', '.'); - var sb = new StringBuilder(); - - sb = new StringBuilder(); - - foreach (String s in splittedPhrase) - { - char[] splittedPhraseChars = s.ToCharArray(); - if (splittedPhraseChars.Length > 0) - { - splittedPhraseChars[0] = ((new String(splittedPhraseChars[0], 1)).ToUpper().ToCharArray())[0]; - } - sb.Append(new String(splittedPhraseChars)); - } - return sb.ToString(); -} - -Project GetProjectContainingT4File(DTE dte) { - - // Find the .tt file's ProjectItem - ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile); - - // If the .tt file is not opened, open it - if (projectItem.Document == null) - projectItem.Open(Constants.vsViewKindCode); - - if (AlwaysKeepTemplateDirty) { - // Mark the .tt file as unsaved. This way it will be saved and update itself next time the - // project is built. Basically, it keeps marking itself as unsaved to make the next build work. - // Note: this is certainly hacky, but is the best I could come up with so far. - projectItem.Document.Saved = false; - } - - return projectItem.ContainingProject; -} - -struct ResourceEntry -{ - public string Path { get; set; } - public string File { get; set; } - public string Type { get; set; } - public bool IsFileRef { get; set; } - public string FileRef { get; set; } - public Type TypeRef { get; set; } - public string Name { get; set; } - public string Value { get; set; } - public string Comment { get; set; } -} - -private static string ToLiteral(string input) -{ - using (var writer = new StringWriter()) - { - using (var provider = CodeDomProvider.CreateProvider("CSharp")) - { - provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null); - return writer.ToString(); - } - } -} -#> diff --git a/sources/shaders/Stride.Core.Shaders/README.md b/sources/shaders/Stride.Core.Shaders/README.md deleted file mode 100644 index 75641cb61e..0000000000 --- a/sources/shaders/Stride.Core.Shaders/README.md +++ /dev/null @@ -1,66 +0,0 @@ -Stride.Core.Shader -==================== - -Shader source code manipulation library. -With it, you can: -* Parse HLSL and GLSL -* Implement custom AST visitors -* Semantic information: inferred type, etc... -* Transform HLSL into GLSL - -## HLSL to GLSL - -It can convert HLSL code to various GLSL dialect, including Core, ES 2.0, ES 3.0+ and Vulkan. - -### Intrisics - -| Feature | Status | -| ----------------------- | ------ | -| Vertex & Pixel Shaders | ✔ | -| Geometry Shaders | ✘ | -| Tessellation Shaders | ✘ | -| Compute Shaders | ✘ | -| Standard intrinsics | ✔ except: noise | -| SM5 intrinsics | ✘ missing: dst, ddx_coarse, ddx_fine, ddy_coarse, ddy_fine, firstbithigh, firstbitlow, countbits, f16tof32, f32tof16, fma, mad, msad4, rcp, reversebits | -| Registers | ✔ simple remapping | -| Constant Buffer Offsets & Packing | ✘ cbuffer follow GLSL rules | -| Barriers intrinsics | ✘ (no Compute Shaders) | -| Interlocked intrinsics | ✘ (no Compute Shaders) | -| Shared variables & memory | ✘ (no Compute Shaders) | -| Integer reinterpret intrinsics | ✘ asuint, asint | -| Flow statements | ✔ except: errorf, printf, abort | -| Texture objects | ✔ | -| Buffer objects | ✔ | -| Class/struct methods | ✘ | -| Preprocessor | ✔ | -| Remap VS projected coordinates | ✔ | -| Multiple Render Targets | ✔ | -| Constant Buffers | ✔ | -| StructuredBuffer and RWStructuredBuffer | ✘ | -| RWBuffer and RWTexture | ✘ | -| #extension directives | ✘ not generated | - -### Texture / samplers - -By default, it generates "combined" samplers: - -``` -Texture2D texture; -SamplerState sampler; - -texture.Sample(texture, sampler); -``` - -will generate a single `sampler2D texture_sampler` - -There is also a mode to generate separate texture/samplers for platforms that support it (i.e. Vulkan). - -### Known issues - -* Small type inference issue with Texture object, happens when doing texture.Sample().r, where it doesn't resolve generics type properly -* Preprocessor seems to first concat then replace defines, which makes such patterns fail: -``` -#define REGISTER_INDEX 1 -#define REGISTER_EXPR b ## REGISTER_INDEX -cbuffer A : register(REGISTER_EXPR) -``` diff --git a/sources/shaders/Stride.Core.Shaders/Stride.Core.Shaders.csproj b/sources/shaders/Stride.Core.Shaders/Stride.Core.Shaders.csproj deleted file mode 100644 index 4ed5d6350b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Stride.Core.Shaders.csproj +++ /dev/null @@ -1,75 +0,0 @@ - - - true - - - - 8.0.30703 - 2.0 - true - true - --serialization - * - - - - Properties\SharedAssemblyInfo.cs - - - True - True - Resources.tt - - - True - True - VisitorGenerated.tt - - - - - - - - - - Designer - - - - - - - - ..\..\..\deps\CppNet\netstandard1.3\CppNet.dll - - - - - - - TextTemplatingFileGenerator - Resources.cs - - - - - - - - TextTemplatingFileGenerator - VisitorGenerated.cs - - - - - - _StrideIncludeExtraAssemblies;$(TargetsForTfmSpecificBuildOutput) - - - - - - - - \ No newline at end of file diff --git a/sources/shaders/Stride.Core.Shaders/Utility/Hlsl/MessageCode.Hlsl.cs b/sources/shaders/Stride.Core.Shaders/Utility/Hlsl/MessageCode.Hlsl.cs deleted file mode 100644 index fb5cad7462..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/Hlsl/MessageCode.Hlsl.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Utility -{ - public partial class MessageCode - { - // Errors - public static readonly MessageCode ErrorMatrixInvalidMemberReference = new MessageCode("E0100", "Invalid member reference [{0}] for matrix type"); - public static readonly MessageCode ErrorMatrixInvalidIndex = new MessageCode("E0101", "Invalid index [{0}] for matrix type member access. Must be in the range [{1},{2}] member for array type"); - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/LoggerResult.cs b/sources/shaders/Stride.Core.Shaders/Utility/LoggerResult.cs deleted file mode 100644 index b1bf3a1eca..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/LoggerResult.cs +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.IO; -using System.Text; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// A class to collect parsing/expression messages. - /// - public class LoggerResult - { - /// - /// Initializes a new instance of the class. - /// - public LoggerResult() - { - this.Messages = new List(); - } - - /// - /// Gets or sets a value indicating whether this instance has errors. - /// - /// - /// true if this instance has errors; otherwise, false. - /// - public bool HasErrors { get; set; } - - /// - /// Gets or sets the messages. - /// - /// - /// The messages. - /// - public IList Messages { get; private set; } - - /// - /// Dumps the messages. - /// - /// The level. - /// The writer. - public void DumpMessages(ReportMessageLevel level, TextWriter writer) - { - foreach (var reportMessage in this.Messages) - { - if (reportMessage.Level >= level) - { - writer.WriteLine(reportMessage); - } - } - } - - /// - /// Copies all messages to another instance. - /// - /// The results. - public void CopyTo(LoggerResult results) - { - foreach (var reportMessage in this.Messages) - { - results.Messages.Add(reportMessage); - } - - if (HasErrors) - results.HasErrors = true; - } - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - public void Error(MessageCode message, SourceSpan span) - { - this.AddMessage(ReportMessageLevel.Error, message, span); - } - - /// - /// Logs an Error with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Error(MessageCode message, SourceSpan span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Error, message, span, parameters); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - public void Info(MessageCode message, SourceSpan span) - { - this.AddMessage(ReportMessageLevel.Info, message, span); - } - - /// - /// Logs an Info with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Info(MessageCode message, SourceSpan span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Info, message, span, parameters); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - public void Warning(MessageCode message, SourceSpan span) - { - this.AddMessage(ReportMessageLevel.Warning, message, span); - } - - /// - /// Logs an Warning with the specified message. - /// - /// The message. - /// The span. - /// The parameters. - public void Warning(MessageCode message, SourceSpan span, params object[] parameters) - { - this.AddMessage(ReportMessageLevel.Warning, message, span, parameters); - } - - /// - /// Adds the message. - /// - /// The type. - /// The message. - /// The span. - protected void AddMessage(ReportMessageLevel level, MessageCode message, SourceSpan span) - { - if (level == ReportMessageLevel.Error) this.HasErrors = true; - this.Messages.Add(new ReportMessage(level, message.Code, message.Text, span)); - } - - /// - /// Adds the message. - /// - /// The type. - /// The message. - /// The span. - /// The parameters. - protected void AddMessage(ReportMessageLevel level, MessageCode message, SourceSpan span, params object[] parameters) - { - if (level == ReportMessageLevel.Error) this.HasErrors = true; - this.Messages.Add(new ReportMessage(level, message.Code, string.Format(message.Text, parameters), span)); - } - - public override string ToString() - { - var text = new StringBuilder(); - if (HasErrors) - { - foreach (var reportMessage in Messages) - { - text.AppendLine(reportMessage.ToString()); - } - } - else - { - text.AppendLine("OK"); - } - return text.ToString(); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/MessageCode.cs b/sources/shaders/Stride.Core.Shaders/Utility/MessageCode.cs deleted file mode 100644 index ec8be6ab08..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/MessageCode.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Utility -{ - public partial class MessageCode - { - public readonly string Code; - - public readonly string Text; - - public MessageCode(string text) - { - Code = ""; - Text = text; - } - - public MessageCode(string code, string text) - { - Code = code; - Text = text; - } - - public static implicit operator MessageCode(string text) - { - return new MessageCode(text); - } - - #region Static members - - // Warnings - public static readonly MessageCode WarningUnknown = new MessageCode("W0000", "Unknown warning"); - - public static readonly MessageCode WarningTypeAsConstructor = new MessageCode("W0001", "Invalid type used as a constructor [{0}]"); - public static readonly MessageCode WarningTypeInferenceUnknownExpression = new MessageCode("W0002", "Type inference for unknown expression is supported [{0}]"); - public static readonly MessageCode WarningNoTypeReferenceMember = new MessageCode("W0003", "Unable to find type reference for member [{0}]"); - - // Error - public static readonly MessageCode ErrorAnalysisUnknown = new MessageCode("E0000", "Unknown analysis error"); - - public static readonly MessageCode ErrorBinaryTypeDeduction = new MessageCode("E0001", "Can't deduce type of binary operation between [{0}] and [{1}]"); - public static readonly MessageCode ErrorScalarTypeConversion = new MessageCode("E0002", "Unsupported scalar type conversion between [{0}] and [{1}]"); - public static readonly MessageCode ErrorIndexerType = new MessageCode("E0003", "Unable to find type for indexer: [{0}]"); - public static readonly MessageCode ErrorLiteralType = new MessageCode("E0004", "Unable to find type reference for literal value [{0}]"); - public static readonly MessageCode ErrorNoOverloadedMethod = new MessageCode("E0005", "Unable to find a suitable overloaded method [{0}]"); - public static readonly MessageCode ErrorNoReferencedMethod = new MessageCode("E0006", "Unable to find the referenced method [{0}]"); - public static readonly MessageCode ErrorNoTypeReferenceTypename = new MessageCode("E0008", "Unable to find type reference for typename [{0}]"); - - public static readonly MessageCode ErrorUnexpectedException = new MessageCode("E0009", "Unexpected exception: {0}"); - - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/OrderedHashSet.cs b/sources/shaders/Stride.Core.Shaders/Utility/OrderedHashSet.cs deleted file mode 100644 index 3354b2b2ed..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/OrderedHashSet.cs +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using Stride.Core.Serialization; -using Stride.Core.Serialization.Serializers; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// An ordered set - /// - /// Type of the element in the set - [DataSerializer(typeof(ListAllSerializer<,>), Mode = DataSerializerGenericMode.TypeAndGenericArguments)] - public class OrderedSet : ISet, IList - { - #region Constants and Fields - - private HashSet hashSet; - - private List listSet; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public OrderedSet() - { - hashSet = new HashSet(); - listSet = new List(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The items. - public OrderedSet(IEnumerable items) - { - hashSet = new HashSet(); - listSet = new List(); - UnionWith(items); - } - - #endregion - - #region Public Properties - - /// - public int Count - { - get - { - return hashSet.Count; - } - } - - /// - public bool IsReadOnly - { - get - { - return false; - } - } - - #endregion - - #region Public Methods - - /// - public bool Add(T item) - { - if (hashSet.Add(item)) - { - listSet.Add(item); - return true; - } - - return false; - } - - public int IndexOf(T item) - { - return listSet.IndexOf(item); - } - - public void Insert(int index, T item) - { - if (hashSet.Add(item)) - { - listSet.Insert(index, item); - } - } - - public void RemoveAll(Func filter) - { - var array = listSet.ToArray(); - foreach (var element in array) - { - if (filter(element)) - Remove(element); - } - } - - public void RemoveAt(int index) - { - var element = listSet[index]; - hashSet.Remove(element); - listSet.RemoveAt(index); - } - - public T this[int index] - { - get - { - return listSet[index]; - } - set - { - var element = listSet[index]; - hashSet.Remove(element); - listSet[index] = value; - if (!hashSet.Add(value)) - { - throw new InvalidOperationException("Value is already in the set"); - } - } - } - - /// - public void Clear() - { - hashSet.Clear(); - listSet.Clear(); - } - - /// - public bool Contains(T item) - { - return hashSet.Contains(item); - } - - /// - public void CopyTo(T[] array, int arrayIndex) - { - listSet.CopyTo(array, arrayIndex); - } - - /// - public void ExceptWith(IEnumerable other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (Count != 0) - { - if (other == this) - { - Clear(); - } - else - { - foreach (T local in other) - { - Remove(local); - } - } - } - } - - /// - public IEnumerator GetEnumerator() - { - return listSet.GetEnumerator(); - } - - /// - public void IntersectWith(IEnumerable other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - hashSet.IntersectWith(other); - - // Remove items from ordered list - for (int i = 0; i < listSet.Count && listSet.Count != hashSet.Count; i++) - { - var item = listSet[i]; - if (!hashSet.Contains(item)) - { - listSet.RemoveAt(i); - i--; - } - } - } - - /// - public bool IsProperSubsetOf(IEnumerable other) - { - return hashSet.IsProperSubsetOf(other); - } - - /// - public bool IsProperSupersetOf(IEnumerable other) - { - return hashSet.IsProperSupersetOf(other); - } - - /// - public bool IsSubsetOf(IEnumerable other) - { - return hashSet.IsSubsetOf(other); - } - - /// - public bool IsSupersetOf(IEnumerable other) - { - return hashSet.IsSupersetOf(other); - } - - /// - public bool Overlaps(IEnumerable other) - { - return hashSet.Overlaps(other); - } - - /// - public bool Remove(T item) - { - if (hashSet.Remove(item)) - { - listSet.Remove(item); - return true; - } - - return false; - } - - /// - public bool SetEquals(IEnumerable other) - { - return hashSet.SetEquals(other); - } - - /// - public void SymmetricExceptWith(IEnumerable other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - var temp = new List(other); - hashSet.SymmetricExceptWith(temp); - - // Remove items from ordered list - foreach (var item in temp) - { - int indexOf = listSet.IndexOf(item); - if (indexOf < 0) - { - listSet.Add(item); - } - } - - // Remove items from ordered list - for (int i = 0; i < listSet.Count && i != hashSet.Count; i++) - { - var item = listSet[i]; - if (!hashSet.Contains(item)) - { - listSet.RemoveAt(i); - i--; - } - } - } - - /// - public void UnionWith(IEnumerable other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - foreach (var item in other) - { - Add(item); - } - } - - #endregion - - #region Explicit Interface Methods - - /// - void ICollection.Add(T item) - { - Add(item); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - - public void Sort() - { - Sort(0, Count, null); - } - - public void Sort(IComparer comparer) - { - Sort(0, Count, comparer); - } - - public void Sort(int index, int count, IComparer comparer) - { - listSet.Sort(index, count, comparer); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/ReferenceEqualityComparer.cs b/sources/shaders/Stride.Core.Shaders/Utility/ReferenceEqualityComparer.cs deleted file mode 100644 index d4a8c93968..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/ReferenceEqualityComparer.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// A Comparator to use method. - /// - /// Type of the comparer - public class ReferenceEqualityComparer : EqualityComparer where T : class - { - private static IEqualityComparer _defaultComparer; - - /// - /// Gets the default. - /// - public new static IEqualityComparer Default - { - get { return _defaultComparer ?? (_defaultComparer = new ReferenceEqualityComparer()); } - } - - #region IEqualityComparer Members - - /// - public override bool Equals(T x, T y) - { - return ReferenceEquals(x, y); - } - - /// - public override int GetHashCode(T obj) - { - return RuntimeHelpers.GetHashCode(obj); - } - - #endregion - } - -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/ReportMessage.cs b/sources/shaders/Stride.Core.Shaders/Utility/ReportMessage.cs deleted file mode 100644 index 5214bcd2a0..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/ReportMessage.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Utility -{ - /// - /// A report message. - /// - public class ReportMessage - { - #region Constants and Fields - - /// - /// Type of the message. - /// - public ReportMessageLevel Level; - - /// - /// Span and location attached to this message. - /// - public SourceSpan Span; - - /// - /// The error code. - /// - public string Code; - - /// - /// Text of the message. - /// - public string Text; - - #endregion - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ReportMessage() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type. - /// The error code. - /// The text. - /// The span. - public ReportMessage(ReportMessageLevel level, string code, string text, SourceSpan span) - { - this.Level = level; - this.Code = code; - this.Text = text; - this.Span = span; - } - - #endregion - - #region Public Methods - - /// - public override string ToString() - { - return string.Format("{0}: {1} {2} : {3}", this.Span, this.Level.ToString().ToLowerInvariant(), this.Code, this.Text); - } - - #endregion - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/ReportMessageLevel.cs b/sources/shaders/Stride.Core.Shaders/Utility/ReportMessageLevel.cs deleted file mode 100644 index fcc722c8f7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/ReportMessageLevel.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core.Shaders.Utility -{ - /// - /// Level of a . - /// - public enum ReportMessageLevel - { - /// - /// An informative message. - /// - Info = 0, - - /// - /// A warning message. - /// - Warning = 1, - - /// - /// An error message. - /// - Error = 2, - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Utility/SpanConverter.cs b/sources/shaders/Stride.Core.Shaders/Utility/SpanConverter.cs deleted file mode 100644 index c9a6923cf7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Utility/SpanConverter.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Parser; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Utility -{ - public class SpanConverter - { - public static SourceLocation Convert(Irony.Parsing.SourceLocation sourceLocation) - { - return new SourceLocation(sourceLocation.SourceFilename, sourceLocation.Position, sourceLocation.Line, sourceLocation.Column); - } - - public static Irony.Parsing.SourceLocation Convert(SourceLocation sourceLocation) - { - return new Irony.Parsing.SourceLocation(sourceLocation.Position, sourceLocation.Line, sourceLocation.Column, sourceLocation.FileSource); - } - - public static SourceSpan Convert(Irony.Parsing.SourceSpan sourceSpan) - { - return new SourceSpan(Convert(sourceSpan.Location), sourceSpan.Length); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionEvaluator.cs b/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionEvaluator.cs deleted file mode 100644 index 7285b197e7..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionEvaluator.cs +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; - -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// An expression evaluator. - /// - public class ExpressionEvaluator : ShaderWalker - { - private static readonly List hlslScalarTypeNames = - new List - { - "bool", - "int", - "uint", - "dword", - "half", - "float", - "double", - "min16float", - "min10float", - "min16int", - "min12int", - "min16uint" - }; - - private readonly Stack values; - - private ExpressionResult result; - - /// - /// Initializes a new instance of the class. - /// - public ExpressionEvaluator() : base(false, false) - { - values = new Stack(); - } - - /// - /// Evaluates the specified expression. - /// - /// The expression. - /// Result of the expression evaluated - public ExpressionResult Evaluate(Expression expression) - { - values.Clear(); - result = new ExpressionResult(); - - // Small optim, if LiteralExpression, we perform a direct eval. - var literalExpression = expression as LiteralExpression; - if (literalExpression != null) - { - Visit(literalExpression); - } - else - { - VisitDynamic(expression); - } - - if (values.Count == 1) - result.Value = values.Pop(); - else - { - result.Error("Cannot evaluate expression {0}", expression.Span, expression); - } - return result; - } - - public override void DefaultVisit(Node node) - { - var expression = node as Expression; - if (expression != null) - { - if (!(expression is BinaryExpression || expression is MethodInvocationExpression || expression is VariableReferenceExpression || expression is LiteralExpression || expression is ParenthesizedExpression || expression is UnaryExpression)) - result.Error("Expression evaluation [{0}] is not supported", expression.Span, expression); - } - } - - /// - public override void Visit(BinaryExpression binaryExpression) - { - base.Visit( binaryExpression); - - if (values.Count < 2) - { - return; - } - - var rightValue = values.Pop(); - var leftValue = values.Pop(); - - var resultValue = 0.0; - - switch (binaryExpression.Operator) - { - case BinaryOperator.Plus: - resultValue = leftValue + rightValue; - break; - case BinaryOperator.Minus: - resultValue = leftValue - rightValue; - break; - case BinaryOperator.Multiply: - resultValue = leftValue*rightValue; - break; - case BinaryOperator.Divide: - resultValue = leftValue/rightValue; - break; - case BinaryOperator.Modulo: - resultValue = leftValue%rightValue; - break; - case BinaryOperator.LeftShift: - resultValue = (int) leftValue << (int) rightValue; - break; - case BinaryOperator.RightShift: - resultValue = (int) leftValue >> (int) rightValue; - break; - case BinaryOperator.BitwiseOr: - resultValue = ((int) leftValue) | ((int) rightValue); - break; - case BinaryOperator.BitwiseAnd: - resultValue = ((int) leftValue) & ((int) rightValue); - break; - case BinaryOperator.BitwiseXor: - resultValue = ((int) leftValue) ^ ((int) rightValue); - break; - case BinaryOperator.LogicalAnd: - resultValue = leftValue != 0.0 && rightValue != 0.0 ? 1.0 : 0.0; - break; - case BinaryOperator.LogicalOr: - resultValue = leftValue != 0.0 || rightValue != 0.0 ? 1.0 : 0.0; - break; - case BinaryOperator.GreaterEqual: - resultValue = leftValue >= rightValue ? 1.0 : 0.0; - break; - case BinaryOperator.Greater: - resultValue = leftValue > rightValue ? 1.0 : 0.0; - break; - case BinaryOperator.Less: - resultValue = leftValue < rightValue ? 1.0 : 0.0; - break; - case BinaryOperator.LessEqual: - resultValue = leftValue <= rightValue ? 1.0 : 0.0; - break; - case BinaryOperator.Equality: - resultValue = leftValue == rightValue ? 1.0 : 0.0; - break; - case BinaryOperator.Inequality: - resultValue = leftValue != rightValue ? 1.0 : 0.0; - break; - default: - result.Error("Binary operator [{0}] is not supported", binaryExpression.Span, binaryExpression); - break; - } - - values.Push(resultValue); - } - - /// - public override void Visit(MethodInvocationExpression methodInvocationExpression) - { - if (methodInvocationExpression.Target is TypeReferenceExpression) - { - var methodName = (methodInvocationExpression.Target as TypeReferenceExpression).Type.Name.Text; - if (hlslScalarTypeNames.Contains(methodName)) - { - var evaluator = new ExpressionEvaluator(); - var subResult = evaluator.Evaluate(methodInvocationExpression.Arguments[0]); - values.Push(subResult.Value); - return; - } - } - - result.Error("Method invocation expression evaluation [{0}] is not supported", methodInvocationExpression.Span, methodInvocationExpression); - } - - /// - public override void Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - - var variableDeclaration = variableReferenceExpression.TypeInference.Declaration as Variable; - if (variableDeclaration == null) - { - result.Error("Unable to find variable [{0}]", variableReferenceExpression.Span, variableReferenceExpression); - } - else if (variableDeclaration.InitialValue == null || !variableDeclaration.Qualifiers.Contains(StorageQualifier.Const)) - { - result.Error("Variable [{0}] used in expression is not constant", variableReferenceExpression.Span, variableDeclaration); - } - else - { - var evaluator = new ExpressionEvaluator(); - var subResult = evaluator.Evaluate(variableDeclaration.InitialValue); - subResult.CopyTo(result); - - if (subResult.HasErrors) - { - values.Push(0.0); - } - else - { - values.Push(subResult.Value); - } - } - } - - /// - public override void Visit(LiteralExpression literalExpression) - { - try - { - var value = Convert.ToDouble(literalExpression.Literal.Value, CultureInfo.InvariantCulture); - values.Push(value); - } - catch (Exception) - { - result.Error("Unable to convert value [{0}] to double", literalExpression.Span, literalExpression.Literal.Value); - } - } - - /// - public override void Visit(UnaryExpression unaryExpression) - { - base.Visit(unaryExpression); - - if (values.Count == 0) - { - return; - } - - var value = values.Pop(); - - switch (unaryExpression.Operator) - { - case UnaryOperator.Plus: - values.Push(value); - break; - case UnaryOperator.Minus: - values.Push(-value); - break; - case UnaryOperator.PreIncrement: - case UnaryOperator.PostIncrement: - // TODO Pre/Post increment/decrement are not correctly handled - value++; - values.Push(value); - break; - case UnaryOperator.PreDecrement: - case UnaryOperator.PostDecrement: - value--; - values.Push(value); - break; - case UnaryOperator.LogicalNot: - values.Push(value == 0.0 ? 1.0 : 0.0); - break; - default: - result.Error("Unary operator [{0}] is not supported", unaryExpression.Span, unaryExpression); - values.Push(0); - break; - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionResult.cs b/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionResult.cs deleted file mode 100644 index 0d05e19969..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/ExpressionResult.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// Result of an expression. - /// - public class ExpressionResult : LoggerResult - { - /// - /// Gets or sets the result of an expression. - /// - /// - /// The result of an expression. - /// - public double Value { get; set; } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/ScopeDeclaration.cs b/sources/shaders/Stride.Core.Shaders/Visitor/ScopeDeclaration.cs deleted file mode 100644 index 294568ee55..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/ScopeDeclaration.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using System.Linq; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// A Scope declaration provides a way to retrieve all scope declaration (variable, methods...etc.) - /// and attached nodes. - /// - public class ScopeDeclaration - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - public ScopeDeclaration() : this(null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The scope container. - public ScopeDeclaration(IScopeContainer scopeContainer) - { - ScopeContainer = scopeContainer; - Declarations = new Dictionary>(); - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the scope container. - /// - /// - /// The scope container. - /// - public IScopeContainer ScopeContainer { get; set; } - - /// - /// Gets or sets the declarations. - /// - /// - /// The declarations. - /// - public IDictionary> Declarations { get; private set; } - - public IEnumerable FindDeclaration(string name) - { - List declarationList; - if (Declarations.TryGetValue(name, out declarationList)) - return declarationList; - - return Enumerable.Empty(); - } - - public void AddDeclaration(IDeclaration declaration) - { - List declarations; - if (declaration.Name != null) - { - - string name = declaration.Name.Text; - if (string.IsNullOrEmpty(name)) - return; - - if (!Declarations.TryGetValue(name, out declarations)) - { - declarations = new List(); - Declarations.Add(name, declarations); - } - } - else - { - declarations = new List(); - } - - var genericsDeclarator = declaration as IGenerics; - if (genericsDeclarator != null) - { - for (int i = 0; i < genericsDeclarator.GenericParameters.Count; i++) - { - var genericArgument = genericsDeclarator.GenericParameters[i]; - var genericName = genericArgument.Name; - if (!Declarations.TryGetValue(genericName.Text, out declarations)) - { - declarations = new List(); - Declarations.Add(genericName, declarations); - } - - declarations.Add(new GenericDeclaration(genericName, genericsDeclarator, i, false) { Span = genericArgument.Span }); - - genericName = new Identifier($"__{genericArgument.Name}_base"); - if (!Declarations.TryGetValue(genericName.Text, out declarations)) - { - declarations = new List(); - Declarations.Add(genericName, declarations); - } - declarations.Add(new GenericDeclaration(genericName, genericsDeclarator, i, true) { Span = genericArgument.Span }); - } - } - - if (!declarations.Contains(declaration)) - declarations.Add(declaration); - } - - public void AddDeclarations(IEnumerable declarations) - { - foreach (var declaration in declarations) - AddDeclaration(declaration); - } - - public void RemoveDeclaration(IDeclaration declaration) - { - string name = declaration.Name.Text; - if (string.IsNullOrEmpty(name)) - return; - - List declarations; - if (Declarations.TryGetValue(name, out declarations)) - declarations.Remove(declaration); - } - - #endregion - - public class DeclarationList - { - public DeclarationList() - { - Standard = new List(); - Generics = new List(); - } - - public List Standard; - - public List Generics; - - public void Add(IDeclaration declaration) - { - Standard.Add(declaration); - var genDecl = declaration as IGenerics; - if (genDecl != null && genDecl.GenericParameters.Count > 0) - { - Generics.Add((IGenerics)declaration); - } - } - - public void Remove(IDeclaration declaration) - { - Standard.Remove(declaration); - if (declaration is IGenerics) - Generics.Remove((IGenerics)declaration); - } - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/SearchVisitor.cs b/sources/shaders/Stride.Core.Shaders/Visitor/SearchVisitor.cs deleted file mode 100644 index 1821cdb71c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/SearchVisitor.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// A visitor that takes a filter function to apply to each node. - /// - public class SearchVisitor : ShaderRewriter - { - /// - /// Initializes a new instance of the class. - /// - /// The filter function. - /// if set to true [build scope declaration]. - /// if set to true [use node stack]. - protected SearchVisitor(Func filterFunction, bool buildScopeDeclaration = false, bool useNodeStack = false) - : base(buildScopeDeclaration, useNodeStack) - { - FilterFunction = filterFunction; - } - - /// - /// Gets or sets the filter function. - /// - /// - /// The filter function. - /// - protected Func FilterFunction { get; set; } - - /// - /// Visits the specified node. - /// - /// The node. - /// The filtered node - public override Node DefaultVisit(Node node) - { - node = FilterFunction(node); - if (node != null) - node = base.DefaultVisit(node); - - return node; - } - - /// - /// Searches from the specified node. - /// - /// The node. - /// The filter function to apply to each node. - /// if set to true [build scope declaration]. - /// if set to true [use node stack]. - public static void Run(Node node, Func filter, bool buildScopeDeclaration = false, bool useNodeStack = false) - { - var visitor = new SearchVisitor(filter, buildScopeDeclaration, useNodeStack); - visitor.VisitDynamic(node); - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/ShaderVisitor.cs b/sources/shaders/Stride.Core.Shaders/Visitor/ShaderVisitor.cs deleted file mode 100644 index 58bf43b218..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/ShaderVisitor.cs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Visitor -{ - public abstract partial class ShaderVisitor : VisitorBase - { - protected ShaderVisitor(bool buildScopeDeclaration, bool useNodeStack) : base(buildScopeDeclaration, useNodeStack) - { - } - - public virtual TResult DefaultVisit(Node node) - { - return default(TResult); - } - - public virtual TResult VisitNode(Node node) - { - if (node != null) - return node.Accept(this); - - return default(TResult); - } - } - - public abstract partial class ShaderRewriter : ShaderVisitor - { - protected ShaderRewriter(bool buildScopeDeclaration, bool useNodeStack) : base(buildScopeDeclaration, useNodeStack) - { - } - - protected sealed override Node DoVisitNode(Node node) - { - return VisitNode(node); - } - - public override Node DefaultVisit(Node node) - { - return node; - } - } - - public partial class ShaderCloner : ShaderRewriter - { - public ShaderCloner() : base(false, false) - { - } - } - - /// - /// A Generic Visitor. - /// - /// - /// An derived classs need to set the Iterator with this instance. - /// - public abstract partial class ShaderVisitor : VisitorBase - { - protected ShaderVisitor(bool buildScopeDeclaration, bool useNodeStack) : base(buildScopeDeclaration, useNodeStack) - { - } - - protected sealed override Node DoVisitNode(Node node) - { - VisitNode(node); - return node; - } - - public virtual void VisitNode(Node node) - { - node?.Accept(this); - } - - public virtual void DefaultVisit(Node node) - { - } - } - - public abstract partial class ShaderWalker : ShaderVisitor - { - protected ShaderWalker(bool buildScopeDeclaration, bool useNodeStack) : base(buildScopeDeclaration, useNodeStack) - { - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/StripVisitor.cs b/sources/shaders/Stride.Core.Shaders/Visitor/StripVisitor.cs deleted file mode 100644 index 45871550ed..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/StripVisitor.cs +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// The strip visitor collects all function and declaration used by a set of entrypoints - /// and remove any unreferenced/unused declaration. - /// - public class StripVisitor : ShaderWalker - { - private Dictionary> indirectReferences; - private readonly string[] entryPoints; - - /// - /// Initializes a new instance of the class. - /// - /// The entry points to filter. - public StripVisitor(params string[] entryPoints) : base(true, true) - { - this.entryPoints = entryPoints; - this.StripUniforms = true; - this.KeepConstantBuffers = true; - } - - public bool StripUniforms { get; set; } - - public bool KeepConstantBuffers { get; set; } - - public override void Visit(MethodInvocationExpression methodInvocationExpression) - { - base.Visit(methodInvocationExpression); - AddReference(GetDeclarationContainer(), (Node)methodInvocationExpression.TypeInference.Declaration); - } - - public override void Visit(VariableReferenceExpression variableReferenceExpression) - { - base.Visit(variableReferenceExpression); - AddReference(GetDeclarationContainer(), (Node)variableReferenceExpression.TypeInference.Declaration); - } - - private ConstantBuffer currentConstantBuffer = null; - - public override void Visit(ConstantBuffer constantBuffer) - { - currentConstantBuffer = constantBuffer; - base.Visit(constantBuffer); - currentConstantBuffer = null; - } - - protected override bool PreVisitNode(Node node) - { - // Sometimes it is desirable that constant buffer are not modified so that - // they can be shared between different stages, even if some variables are unused. - // In this case, use symetric reference so that using a constant buffer will include all its variables. - if (KeepConstantBuffers && currentConstantBuffer != null && node is IDeclaration) - { - AddReference(node, currentConstantBuffer); - AddReference(currentConstantBuffer, node); - } - - return base.PreVisitNode(node); - - } - - public override void Visit(Parameter parameter) - { - base.Visit(parameter); - var containers = GetDeclarationContainers(); - var container = containers[containers.Count - 2]; - AddReference((Node)container, parameter); - } - - public override void DefaultVisit(Node node) - { - base.DefaultVisit(node); - - var typeBase = node as TypeBase; - if (typeBase != null) - AddReference(GetDeclarationContainer(), (Node)typeBase.TypeInference.Declaration); - } - - public override void Visit(MethodDefinition methodDefinition) - { - base.Visit(methodDefinition); - - // If a method definition has a method declaration, we must link them together - if (!ReferenceEquals(methodDefinition.Declaration, methodDefinition)) - { - AddReference(methodDefinition.Declaration, methodDefinition); - } - } - - public override void Visit(Variable variable) - { - base.Visit(variable); - var containers = GetDeclarationContainers(); - if (containers.Count > 1) - { - var container = containers[containers.Count - 2]; - AddReference((Node)container, variable); - } - } - - public override void Visit(Shader shader) - { - indirectReferences = new Dictionary>(); - - // Visit AST. - base.Visit( shader); - - // Get list of function referenced (directly or indirectly) by entry point. - // Using hashset and recursion to avoid cycle. - var collectedReferences = new List(); - foreach (var entryPointName in entryPoints) - { - // Find entry point - var entryPoint = shader.Declarations.OfType().FirstOrDefault(x => x.Name == entryPointName); - - if (entryPoint == null) - throw new ArgumentException(string.Format("Could not find entry point named {0}", entryPointName)); - - CollectReferences(collectedReferences, entryPoint); - } - - StripDeclarations(shader.Declarations, collectedReferences, StripUniforms); - } - - /// - /// Strips the declarations. - /// - /// The nodes. - /// The collected references. - private static void StripDeclarations(IList nodes, ICollection collectedReferences, bool stripUniforms) - { - // Remove all the unreferenced function amd types declaration from the shader. - for (int i = 0; i < nodes.Count; i++) - { - var declaration = nodes[i]; - - // Strip constant buffer elements by elements only if "stripUniforms" is active (useful for API without constant buffers like OpenGL ES 2.0) - if (stripUniforms && declaration is ConstantBuffer) - { - var constantBuffer = (ConstantBuffer)declaration; - StripDeclarations(constantBuffer.Members, collectedReferences, stripUniforms); - } - - if (CanStrip(declaration, collectedReferences, stripUniforms)) - { - nodes.RemoveAt(i--); - } - } - } - - private static bool CanStrip(Node declaration, ICollection collectedReferences, bool stripUniforms) - { - if (declaration is Variable) - { - var variableDeclaration = (Variable)declaration; - if ((!stripUniforms && variableDeclaration.Qualifiers.Contains(Ast.Glsl.StorageQualifier.Uniform))) - return false; - - if (variableDeclaration.IsGroup) - { - variableDeclaration.SubVariables.RemoveAll(x => !collectedReferences.Contains(x)); - if (variableDeclaration.SubVariables.Count == 0) - { - return true; - } - } - else if (!collectedReferences.Contains(declaration)) - { - return true; - } - } - else if (declaration is IDeclaration && !collectedReferences.Contains(declaration)) - { - return true; - } - else if (declaration is ConstantBuffer) - { - // Strip cbuffer only if all of its member can be - var constantBuffer = (ConstantBuffer)declaration; - foreach (var member in constantBuffer.Members) - { - if (!CanStrip(member, collectedReferences, stripUniforms)) - return false; - } - return true; - } - return false; - } - - /// - /// Helper to collects the referenced declarations recursively. - /// - /// The collected declarations. - /// The reference to collect. - private void CollectReferences(List collectedReferences, Node reference) - { - if (!collectedReferences.Contains(reference)) - { - // Collect reference (if not already added) - collectedReferences.Add(reference); - - // Collect recursively - HashSet referencedFunctions; - if (indirectReferences.TryGetValue((Node)reference, out referencedFunctions)) - { - foreach (var referencedFunction in referencedFunctions) - CollectReferences(collectedReferences, referencedFunction); - } - } - } - - private void AddReference(Node parent, Node declaration) - { - if (parent != null && declaration != null) - { - HashSet childReferences; - if (!indirectReferences.TryGetValue(parent, out childReferences)) - { - childReferences = new HashSet(); - indirectReferences[parent] = childReferences; - } - if (!childReferences.Contains(declaration)) - childReferences.Add(declaration); - } - } - - - private Node GetDeclarationContainer() - { - // By default use the method definition as the main declarator container - var methodDefinition = (Node)NodeStack.OfType().LastOrDefault(); - if (methodDefinition != null) - return methodDefinition; - - // Else use the IDeclaration - return (Node)NodeStack.OfType().LastOrDefault(); - } - - private List GetDeclarationContainers() - { - return NodeStack.OfType().ToList(); - } - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorBase.cs b/sources/shaders/Stride.Core.Shaders/Visitor/VisitorBase.cs deleted file mode 100644 index d67c0c7e9b..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorBase.cs +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Reflection; -using Stride.Core.Shaders.Ast; -using System.Linq; - -namespace Stride.Core.Shaders.Visitor -{ - /// - /// Visitor base. - /// - public abstract class VisitorBase - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// if set to true [use node stack]. - protected VisitorBase(bool useNodeStack = false) - { - if (useNodeStack) - { - NodeStack = new List(); - } - } - - #endregion - - #region Public Properties - - /// - /// Gets or sets the node stack. - /// - /// - /// The node stack. - /// - public List NodeStack { get; set; } - - #endregion - - #region Public Methods - - /// - /// Visits the list. - /// - /// Type of the item in the list - /// The list. - /// The function filter. - protected void VisitList(IList list, Func filter = null) where T : Node - { - if (list == null) - return; - - int i = 0; - while (i < list.Count) - { - var previousValue = (Node)list[i]; - var temp = VisitDynamic(previousValue); - - // Recover the position as the list can be modified while processing a node - for (i = 0; i < list.Count; i++) - { - if (ReferenceEquals(previousValue, list[i])) - break; - } - - if (temp == null) - { - list.RemoveAt(i); - } - else - { - if (!ReferenceEquals(previousValue, temp)) - list[i] = (T)temp; - i++; - } - } - } - - /// - /// Visits the node. - /// - /// Type of the node - /// The node. - /// if set to true [visit real type]. - /// - /// A node - /// - protected virtual Node VisitDynamic(Node node) - { - if (node == null) - { - return null; - } - - bool nodeStackAdded = false; - - if (NodeStack != null) - { - if (NodeStack.Count > 0 && ReferenceEquals(NodeStack[NodeStack.Count - 1], node)) - throw new InvalidOperationException(string.Format("Cannot visit recursively a node [{0}] already being visited", node)); - - NodeStack.Add(node); - nodeStackAdded = true; - } - - // Only Visit in the Iterator - bool doVisit = PreVisitNode(node); - - var result = (Node)node; - if (doVisit) - { - result = DoVisitNode(node); - } - - // Only Visit in the Iterator - PostVisitNode(node, doVisit); - - if (NodeStack != null && nodeStackAdded) - { - NodeStack.RemoveAt(NodeStack.Count - 1); - } - - return result; - } - - protected abstract Node DoVisitNode(Node node); - - #endregion - - protected readonly NodeProcessor nodeProcessor; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// if set to true [build scope declaration]. - /// if set to true [use node stack]. - protected VisitorBase(bool buildScopeDeclaration, bool useNodeStack) : this(useNodeStack) - { - if (buildScopeDeclaration) - { - ScopeStack = new Stack(); - ScopeStack.Push(this.NewScope()); - } - } - - #endregion - - #region Properties - - protected virtual ScopeDeclaration NewScope(IScopeContainer container = null) - { - return new ScopeDeclaration(container); - } - - /// - /// Gets the parent node or null if no parents - /// - public Node ParentNode - { - get - { - return NodeStack.Count > 1 ? NodeStack[NodeStack.Count - 2] : null; - } - } - - /// - /// Gets the scope stack. - /// - protected Stack ScopeStack { get; private set; } - - #endregion - - #region Public Methods - - /// - /// Finds a list of declaration by its name. - /// - /// The name. - /// A list of declaration - protected virtual IEnumerable FindDeclarations(string name) - { - return ScopeStack.SelectMany(scopeDecl => scopeDecl.FindDeclaration(name)); - } - - /// - /// Finds a declaration by its name. - /// - /// The name. - /// A declaration - protected IDeclaration FindDeclaration(string name) - { - return FindDeclarations(name).FirstOrDefault(); - } - - /// - /// Called before visiting the node. - /// - /// The node. - /// True to continue visiting the node; false to skip the visit - protected virtual bool PreVisitNode(Node node) - { - if (ScopeStack != null) - { - var declaration = node as IDeclaration; - if (declaration != null) - { - // If this is a variable, add only instance variables - if (declaration is Variable) - { - foreach (var variable in ((Variable)declaration).Instances()) - ScopeStack.Peek().AddDeclaration(variable); - } - else - { - ScopeStack.Peek().AddDeclaration(declaration); - } - } - - var scopeContainer = node as IScopeContainer; - if (scopeContainer != null) - { - ScopeStack.Push(this.NewScope(scopeContainer)); - } - } - return true; - } - - /// - /// Called after visiting the node. - /// - /// The node. - /// if set to true [node visited]. - protected virtual void PostVisitNode(Node node, bool nodeVisited) - { - if (ScopeStack != null && node is IScopeContainer) - ScopeStack.Pop(); - } - - #endregion - - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.cs b/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.cs deleted file mode 100644 index 3444ab4df1..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.cs +++ /dev/null @@ -1,4655 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - - - - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Visitor -{ - public partial class ShaderVisitor - { - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric classIdentifierGeneric) - { - return DefaultVisit(classIdentifierGeneric); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.EnumType enumType) - { - return DefaultVisit(enumType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ForEachStatement forEachStatement) - { - return DefaultVisit(forEachStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ImportBlockStatement importBlockStatement) - { - return DefaultVisit(importBlockStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.LinkType linkType) - { - return DefaultVisit(linkType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.LiteralIdentifier literalIdentifier) - { - return DefaultVisit(literalIdentifier); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.MemberName memberName) - { - return DefaultVisit(memberName); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.MixinStatement mixinStatement) - { - return DefaultVisit(mixinStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.NamespaceBlock namespaceBlock) - { - return DefaultVisit(namespaceBlock); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ParametersBlock parametersBlock) - { - return DefaultVisit(parametersBlock); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.SemanticType semanticType) - { - return DefaultVisit(semanticType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.EffectBlock effectBlock) - { - return DefaultVisit(effectBlock); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ShaderClassType shaderClassType) - { - return DefaultVisit(shaderClassType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ShaderRootClassType shaderRootClassType) - { - return DefaultVisit(shaderRootClassType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.ShaderTypeName shaderTypeName) - { - return DefaultVisit(shaderTypeName); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.TypeIdentifier typeIdentifier) - { - return DefaultVisit(typeIdentifier); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.UsingParametersStatement usingParametersStatement) - { - return DefaultVisit(usingParametersStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.UsingStatement usingStatement) - { - return DefaultVisit(usingStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.VarType varType) - { - return DefaultVisit(varType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType strideConstantBufferType) - { - return DefaultVisit(strideConstantBufferType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ArrayInitializerExpression arrayInitializerExpression) - { - return DefaultVisit(arrayInitializerExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ArrayType arrayType) - { - return DefaultVisit(arrayType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.AssignmentExpression assignmentExpression) - { - return DefaultVisit(assignmentExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.BinaryExpression binaryExpression) - { - return DefaultVisit(binaryExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.BlockStatement blockStatement) - { - return DefaultVisit(blockStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.CaseStatement caseStatement) - { - return DefaultVisit(caseStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.CompositeEnum compositeEnum) - { - return DefaultVisit(compositeEnum); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ConditionalExpression conditionalExpression) - { - return DefaultVisit(conditionalExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.EmptyStatement emptyStatement) - { - return DefaultVisit(emptyStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.EmptyExpression emptyExpression) - { - return DefaultVisit(emptyExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue layoutKeyValue) - { - return DefaultVisit(layoutKeyValue); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Glsl.LayoutQualifier layoutQualifier) - { - return DefaultVisit(layoutQualifier); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Glsl.InterfaceType interfaceType) - { - return DefaultVisit(interfaceType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.ClassType classType) - { - return DefaultVisit(classType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric identifierGeneric) - { - return DefaultVisit(identifierGeneric); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierNs identifierNs) - { - return DefaultVisit(identifierNs); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierDot identifierDot) - { - return DefaultVisit(identifierDot); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.TextureType textureType) - { - return DefaultVisit(textureType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.Annotations annotations) - { - return DefaultVisit(annotations); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.AsmExpression asmExpression) - { - return DefaultVisit(asmExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration attributeDeclaration) - { - return DefaultVisit(attributeDeclaration); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.CastExpression castExpression) - { - return DefaultVisit(castExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.CompileExpression compileExpression) - { - return DefaultVisit(compileExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer constantBuffer) - { - return DefaultVisit(constantBuffer); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType constantBufferType) - { - return DefaultVisit(constantBufferType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.InterfaceType interfaceType) - { - return DefaultVisit(interfaceType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.PackOffset packOffset) - { - return DefaultVisit(packOffset); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.Pass pass) - { - return DefaultVisit(pass); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.RegisterLocation registerLocation) - { - return DefaultVisit(registerLocation); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.Semantic semantic) - { - return DefaultVisit(semantic); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.StateExpression stateExpression) - { - return DefaultVisit(stateExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.StateInitializer stateInitializer) - { - return DefaultVisit(stateInitializer); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.Technique technique) - { - return DefaultVisit(technique); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Hlsl.Typedef typedef) - { - return DefaultVisit(typedef); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ExpressionList expressionList) - { - return DefaultVisit(expressionList); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.GenericDeclaration genericDeclaration) - { - return DefaultVisit(genericDeclaration); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.GenericParameterType genericParameterType) - { - return DefaultVisit(genericParameterType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.DeclarationStatement declarationStatement) - { - return DefaultVisit(declarationStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ExpressionStatement expressionStatement) - { - return DefaultVisit(expressionStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ForStatement forStatement) - { - return DefaultVisit(forStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.GenericType genericType) - { - return DefaultVisit(genericType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Identifier identifier) - { - return DefaultVisit(identifier); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.IfStatement ifStatement) - { - return DefaultVisit(ifStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.IndexerExpression indexerExpression) - { - return DefaultVisit(indexerExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.KeywordExpression keywordExpression) - { - return DefaultVisit(keywordExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Literal literal) - { - return DefaultVisit(literal); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.LiteralExpression literalExpression) - { - return DefaultVisit(literalExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.MatrixType matrixType) - { - return DefaultVisit(matrixType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.MemberReferenceExpression memberReferenceExpression) - { - return DefaultVisit(memberReferenceExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.MethodDeclaration methodDeclaration) - { - return DefaultVisit(methodDeclaration); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.MethodDefinition methodDefinition) - { - return DefaultVisit(methodDefinition); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.MethodInvocationExpression methodInvocationExpression) - { - return DefaultVisit(methodInvocationExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ObjectType objectType) - { - return DefaultVisit(objectType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Parameter parameter) - { - return DefaultVisit(parameter); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ParenthesizedExpression parenthesizedExpression) - { - return DefaultVisit(parenthesizedExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Qualifier qualifier) - { - return DefaultVisit(qualifier); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ReturnStatement returnStatement) - { - return DefaultVisit(returnStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.ScalarType scalarType) - { - return DefaultVisit(scalarType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Shader shader) - { - return DefaultVisit(shader); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.StatementList statementList) - { - return DefaultVisit(statementList); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.StructType structType) - { - return DefaultVisit(structType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.SwitchCaseGroup switchCaseGroup) - { - return DefaultVisit(switchCaseGroup); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.SwitchStatement switchStatement) - { - return DefaultVisit(switchStatement); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.TypeName typeName) - { - return DefaultVisit(typeName); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.TypeReferenceExpression typeReferenceExpression) - { - return DefaultVisit(typeReferenceExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.UnaryExpression unaryExpression) - { - return DefaultVisit(unaryExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.Variable variable) - { - return DefaultVisit(variable); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.VariableReferenceExpression variableReferenceExpression) - { - return DefaultVisit(variableReferenceExpression); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.VectorType vectorType) - { - return DefaultVisit(vectorType); - } - public virtual TResult Visit(Stride.Core.Shaders.Ast.WhileStatement whileStatement) - { - return DefaultVisit(whileStatement); - } - } - - public partial class ShaderRewriter - { - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric classIdentifierGeneric) - { - VisitList(classIdentifierGeneric.Indices); - VisitList(classIdentifierGeneric.Generics); - return base.Visit(classIdentifierGeneric); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.EnumType enumType) - { - VisitList(enumType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(enumType.Name); - if (!ReferenceEquals(nameTemp, enumType.Name)) - enumType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(enumType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, enumType.Qualifiers)) - enumType.Qualifiers = qualifiersTemp; - VisitList(enumType.Values); - return base.Visit(enumType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ForEachStatement forEachStatement) - { - VisitList(forEachStatement.Attributes); - var collectionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(forEachStatement.Collection); - if (!ReferenceEquals(collectionTemp, forEachStatement.Collection)) - forEachStatement.Collection = collectionTemp; - var variableTemp = (Stride.Core.Shaders.Ast.Variable)VisitDynamic(forEachStatement.Variable); - if (!ReferenceEquals(variableTemp, forEachStatement.Variable)) - forEachStatement.Variable = variableTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(forEachStatement.Body); - if (!ReferenceEquals(bodyTemp, forEachStatement.Body)) - forEachStatement.Body = bodyTemp; - return base.Visit(forEachStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ImportBlockStatement importBlockStatement) - { - VisitList(importBlockStatement.Attributes); - var statementsTemp = (Stride.Core.Shaders.Ast.StatementList)VisitDynamic(importBlockStatement.Statements); - if (!ReferenceEquals(statementsTemp, importBlockStatement.Statements)) - importBlockStatement.Statements = statementsTemp; - return base.Visit(importBlockStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.LinkType linkType) - { - VisitList(linkType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(linkType.Name); - if (!ReferenceEquals(nameTemp, linkType.Name)) - linkType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(linkType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, linkType.Qualifiers)) - linkType.Qualifiers = qualifiersTemp; - return base.Visit(linkType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.LiteralIdentifier literalIdentifier) - { - VisitList(literalIdentifier.Indices); - var valueTemp = (Stride.Core.Shaders.Ast.Literal)VisitDynamic(literalIdentifier.Value); - if (!ReferenceEquals(valueTemp, literalIdentifier.Value)) - literalIdentifier.Value = valueTemp; - return base.Visit(literalIdentifier); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.MemberName memberName) - { - VisitList(memberName.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(memberName.Name); - if (!ReferenceEquals(nameTemp, memberName.Name)) - memberName.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(memberName.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, memberName.Qualifiers)) - memberName.Qualifiers = qualifiersTemp; - return base.Visit(memberName); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.MixinStatement mixinStatement) - { - VisitList(mixinStatement.Attributes); - var valueTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(mixinStatement.Value); - if (!ReferenceEquals(valueTemp, mixinStatement.Value)) - mixinStatement.Value = valueTemp; - return base.Visit(mixinStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.NamespaceBlock namespaceBlock) - { - VisitList(namespaceBlock.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(namespaceBlock.Name); - if (!ReferenceEquals(nameTemp, namespaceBlock.Name)) - namespaceBlock.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(namespaceBlock.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, namespaceBlock.Qualifiers)) - namespaceBlock.Qualifiers = qualifiersTemp; - VisitList(namespaceBlock.Body); - return base.Visit(namespaceBlock); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ParametersBlock parametersBlock) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(parametersBlock.Name); - if (!ReferenceEquals(nameTemp, parametersBlock.Name)) - parametersBlock.Name = nameTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.BlockStatement)VisitDynamic(parametersBlock.Body); - if (!ReferenceEquals(bodyTemp, parametersBlock.Body)) - parametersBlock.Body = bodyTemp; - return base.Visit(parametersBlock); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.SemanticType semanticType) - { - VisitList(semanticType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(semanticType.Name); - if (!ReferenceEquals(nameTemp, semanticType.Name)) - semanticType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(semanticType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, semanticType.Qualifiers)) - semanticType.Qualifiers = qualifiersTemp; - return base.Visit(semanticType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.EffectBlock effectBlock) - { - VisitList(effectBlock.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(effectBlock.Name); - if (!ReferenceEquals(nameTemp, effectBlock.Name)) - effectBlock.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(effectBlock.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, effectBlock.Qualifiers)) - effectBlock.Qualifiers = qualifiersTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.BlockStatement)VisitDynamic(effectBlock.Body); - if (!ReferenceEquals(bodyTemp, effectBlock.Body)) - effectBlock.Body = bodyTemp; - return base.Visit(effectBlock); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderClassType shaderClassType) - { - VisitList(shaderClassType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(shaderClassType.Name); - if (!ReferenceEquals(nameTemp, shaderClassType.Name)) - shaderClassType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(shaderClassType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, shaderClassType.Qualifiers)) - shaderClassType.Qualifiers = qualifiersTemp; - VisitList(shaderClassType.BaseClasses); - VisitList(shaderClassType.GenericParameters); - VisitList(shaderClassType.GenericArguments); - VisitList(shaderClassType.Members); - VisitList(shaderClassType.ShaderGenerics); - return base.Visit(shaderClassType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderRootClassType shaderRootClassType) - { - VisitList(shaderRootClassType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(shaderRootClassType.Name); - if (!ReferenceEquals(nameTemp, shaderRootClassType.Name)) - shaderRootClassType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(shaderRootClassType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, shaderRootClassType.Qualifiers)) - shaderRootClassType.Qualifiers = qualifiersTemp; - VisitList(shaderRootClassType.BaseClasses); - VisitList(shaderRootClassType.GenericParameters); - VisitList(shaderRootClassType.GenericArguments); - VisitList(shaderRootClassType.Members); - VisitList(shaderRootClassType.ShaderGenerics); - return base.Visit(shaderRootClassType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderTypeName shaderTypeName) - { - VisitList(shaderTypeName.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(shaderTypeName.Name); - if (!ReferenceEquals(nameTemp, shaderTypeName.Name)) - shaderTypeName.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(shaderTypeName.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, shaderTypeName.Qualifiers)) - shaderTypeName.Qualifiers = qualifiersTemp; - return base.Visit(shaderTypeName); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.TypeIdentifier typeIdentifier) - { - VisitList(typeIdentifier.Indices); - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(typeIdentifier.Type); - if (!ReferenceEquals(typeTemp, typeIdentifier.Type)) - typeIdentifier.Type = typeTemp; - return base.Visit(typeIdentifier); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.UsingParametersStatement usingParametersStatement) - { - VisitList(usingParametersStatement.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(usingParametersStatement.Name); - if (!ReferenceEquals(nameTemp, usingParametersStatement.Name)) - usingParametersStatement.Name = nameTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.BlockStatement)VisitDynamic(usingParametersStatement.Body); - if (!ReferenceEquals(bodyTemp, usingParametersStatement.Body)) - usingParametersStatement.Body = bodyTemp; - return base.Visit(usingParametersStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.UsingStatement usingStatement) - { - VisitList(usingStatement.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(usingStatement.Name); - if (!ReferenceEquals(nameTemp, usingStatement.Name)) - usingStatement.Name = nameTemp; - return base.Visit(usingStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.VarType varType) - { - VisitList(varType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(varType.Name); - if (!ReferenceEquals(nameTemp, varType.Name)) - varType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(varType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, varType.Qualifiers)) - varType.Qualifiers = qualifiersTemp; - return base.Visit(varType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType strideConstantBufferType) - { - return base.Visit(strideConstantBufferType); - } - public override Node Visit(Stride.Core.Shaders.Ast.ArrayInitializerExpression arrayInitializerExpression) - { - VisitList(arrayInitializerExpression.Items); - return base.Visit(arrayInitializerExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.ArrayType arrayType) - { - VisitList(arrayType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(arrayType.Name); - if (!ReferenceEquals(nameTemp, arrayType.Name)) - arrayType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(arrayType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, arrayType.Qualifiers)) - arrayType.Qualifiers = qualifiersTemp; - VisitList(arrayType.Dimensions); - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(arrayType.Type); - if (!ReferenceEquals(typeTemp, arrayType.Type)) - arrayType.Type = typeTemp; - return base.Visit(arrayType); - } - public override Node Visit(Stride.Core.Shaders.Ast.AssignmentExpression assignmentExpression) - { - var targetTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(assignmentExpression.Target); - if (!ReferenceEquals(targetTemp, assignmentExpression.Target)) - assignmentExpression.Target = targetTemp; - var valueTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(assignmentExpression.Value); - if (!ReferenceEquals(valueTemp, assignmentExpression.Value)) - assignmentExpression.Value = valueTemp; - return base.Visit(assignmentExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.BinaryExpression binaryExpression) - { - var leftTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(binaryExpression.Left); - if (!ReferenceEquals(leftTemp, binaryExpression.Left)) - binaryExpression.Left = leftTemp; - var rightTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(binaryExpression.Right); - if (!ReferenceEquals(rightTemp, binaryExpression.Right)) - binaryExpression.Right = rightTemp; - return base.Visit(binaryExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.BlockStatement blockStatement) - { - VisitList(blockStatement.Attributes); - var statementsTemp = (Stride.Core.Shaders.Ast.StatementList)VisitDynamic(blockStatement.Statements); - if (!ReferenceEquals(statementsTemp, blockStatement.Statements)) - blockStatement.Statements = statementsTemp; - return base.Visit(blockStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.CaseStatement caseStatement) - { - VisitList(caseStatement.Attributes); - var caseTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(caseStatement.Case); - if (!ReferenceEquals(caseTemp, caseStatement.Case)) - caseStatement.Case = caseTemp; - return base.Visit(caseStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.CompositeEnum compositeEnum) - { - return base.Visit(compositeEnum); - } - public override Node Visit(Stride.Core.Shaders.Ast.ConditionalExpression conditionalExpression) - { - var conditionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(conditionalExpression.Condition); - if (!ReferenceEquals(conditionTemp, conditionalExpression.Condition)) - conditionalExpression.Condition = conditionTemp; - var leftTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(conditionalExpression.Left); - if (!ReferenceEquals(leftTemp, conditionalExpression.Left)) - conditionalExpression.Left = leftTemp; - var rightTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(conditionalExpression.Right); - if (!ReferenceEquals(rightTemp, conditionalExpression.Right)) - conditionalExpression.Right = rightTemp; - return base.Visit(conditionalExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.EmptyStatement emptyStatement) - { - VisitList(emptyStatement.Attributes); - return base.Visit(emptyStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.EmptyExpression emptyExpression) - { - return base.Visit(emptyExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue layoutKeyValue) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(layoutKeyValue.Name); - if (!ReferenceEquals(nameTemp, layoutKeyValue.Name)) - layoutKeyValue.Name = nameTemp; - var valueTemp = (Stride.Core.Shaders.Ast.LiteralExpression)VisitDynamic(layoutKeyValue.Value); - if (!ReferenceEquals(valueTemp, layoutKeyValue.Value)) - layoutKeyValue.Value = valueTemp; - return base.Visit(layoutKeyValue); - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.LayoutQualifier layoutQualifier) - { - VisitList(layoutQualifier.Layouts); - return base.Visit(layoutQualifier); - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.InterfaceType interfaceType) - { - VisitList(interfaceType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(interfaceType.Name); - if (!ReferenceEquals(nameTemp, interfaceType.Name)) - interfaceType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(interfaceType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, interfaceType.Qualifiers)) - interfaceType.Qualifiers = qualifiersTemp; - VisitList(interfaceType.Fields); - return base.Visit(interfaceType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ClassType classType) - { - VisitList(classType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(classType.Name); - if (!ReferenceEquals(nameTemp, classType.Name)) - classType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(classType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, classType.Qualifiers)) - classType.Qualifiers = qualifiersTemp; - VisitList(classType.BaseClasses); - VisitList(classType.GenericParameters); - VisitList(classType.GenericArguments); - VisitList(classType.Members); - return base.Visit(classType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric identifierGeneric) - { - VisitList(identifierGeneric.Indices); - VisitList(identifierGeneric.Identifiers); - return base.Visit(identifierGeneric); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierNs identifierNs) - { - VisitList(identifierNs.Indices); - VisitList(identifierNs.Identifiers); - return base.Visit(identifierNs); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierDot identifierDot) - { - VisitList(identifierDot.Indices); - VisitList(identifierDot.Identifiers); - return base.Visit(identifierDot); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.TextureType textureType) - { - VisitList(textureType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(textureType.Name); - if (!ReferenceEquals(nameTemp, textureType.Name)) - textureType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(textureType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, textureType.Qualifiers)) - textureType.Qualifiers = qualifiersTemp; - return base.Visit(textureType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Annotations annotations) - { - VisitList(annotations.Variables); - return base.Visit(annotations); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.AsmExpression asmExpression) - { - return base.Visit(asmExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration attributeDeclaration) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(attributeDeclaration.Name); - if (!ReferenceEquals(nameTemp, attributeDeclaration.Name)) - attributeDeclaration.Name = nameTemp; - VisitList(attributeDeclaration.Parameters); - return base.Visit(attributeDeclaration); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.CastExpression castExpression) - { - var fromTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(castExpression.From); - if (!ReferenceEquals(fromTemp, castExpression.From)) - castExpression.From = fromTemp; - var targetTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(castExpression.Target); - if (!ReferenceEquals(targetTemp, castExpression.Target)) - castExpression.Target = targetTemp; - return base.Visit(castExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.CompileExpression compileExpression) - { - var functionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(compileExpression.Function); - if (!ReferenceEquals(functionTemp, compileExpression.Function)) - compileExpression.Function = functionTemp; - var profileTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(compileExpression.Profile); - if (!ReferenceEquals(profileTemp, compileExpression.Profile)) - compileExpression.Profile = profileTemp; - return base.Visit(compileExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer constantBuffer) - { - VisitList(constantBuffer.Attributes); - var typeTemp = (Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType)VisitDynamic(constantBuffer.Type); - if (!ReferenceEquals(typeTemp, constantBuffer.Type)) - constantBuffer.Type = typeTemp; - VisitList(constantBuffer.Members); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(constantBuffer.Name); - if (!ReferenceEquals(nameTemp, constantBuffer.Name)) - constantBuffer.Name = nameTemp; - var registerTemp = (Stride.Core.Shaders.Ast.Hlsl.RegisterLocation)VisitDynamic(constantBuffer.Register); - if (!ReferenceEquals(registerTemp, constantBuffer.Register)) - constantBuffer.Register = registerTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(constantBuffer.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, constantBuffer.Qualifiers)) - constantBuffer.Qualifiers = qualifiersTemp; - return base.Visit(constantBuffer); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType constantBufferType) - { - return base.Visit(constantBufferType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.InterfaceType interfaceType) - { - VisitList(interfaceType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(interfaceType.Name); - if (!ReferenceEquals(nameTemp, interfaceType.Name)) - interfaceType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(interfaceType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, interfaceType.Qualifiers)) - interfaceType.Qualifiers = qualifiersTemp; - VisitList(interfaceType.GenericParameters); - VisitList(interfaceType.GenericArguments); - VisitList(interfaceType.Methods); - return base.Visit(interfaceType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.PackOffset packOffset) - { - var valueTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(packOffset.Value); - if (!ReferenceEquals(valueTemp, packOffset.Value)) - packOffset.Value = valueTemp; - return base.Visit(packOffset); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Pass pass) - { - VisitList(pass.Attributes); - VisitList(pass.Items); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(pass.Name); - if (!ReferenceEquals(nameTemp, pass.Name)) - pass.Name = nameTemp; - return base.Visit(pass); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.RegisterLocation registerLocation) - { - var profileTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(registerLocation.Profile); - if (!ReferenceEquals(profileTemp, registerLocation.Profile)) - registerLocation.Profile = profileTemp; - var registerTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(registerLocation.Register); - if (!ReferenceEquals(registerTemp, registerLocation.Register)) - registerLocation.Register = registerTemp; - return base.Visit(registerLocation); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Semantic semantic) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(semantic.Name); - if (!ReferenceEquals(nameTemp, semantic.Name)) - semantic.Name = nameTemp; - return base.Visit(semantic); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.StateExpression stateExpression) - { - var initializerTemp = (Stride.Core.Shaders.Ast.Hlsl.StateInitializer)VisitDynamic(stateExpression.Initializer); - if (!ReferenceEquals(initializerTemp, stateExpression.Initializer)) - stateExpression.Initializer = initializerTemp; - var stateTypeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(stateExpression.StateType); - if (!ReferenceEquals(stateTypeTemp, stateExpression.StateType)) - stateExpression.StateType = stateTypeTemp; - return base.Visit(stateExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.StateInitializer stateInitializer) - { - VisitList(stateInitializer.Items); - return base.Visit(stateInitializer); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Technique technique) - { - var typeTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(technique.Type); - if (!ReferenceEquals(typeTemp, technique.Type)) - technique.Type = typeTemp; - VisitList(technique.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(technique.Name); - if (!ReferenceEquals(nameTemp, technique.Name)) - technique.Name = nameTemp; - VisitList(technique.Passes); - return base.Visit(technique); - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Typedef typedef) - { - VisitList(typedef.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(typedef.Name); - if (!ReferenceEquals(nameTemp, typedef.Name)) - typedef.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(typedef.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, typedef.Qualifiers)) - typedef.Qualifiers = qualifiersTemp; - VisitList(typedef.SubDeclarators); - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(typedef.Type); - if (!ReferenceEquals(typeTemp, typedef.Type)) - typedef.Type = typeTemp; - return base.Visit(typedef); - } - public override Node Visit(Stride.Core.Shaders.Ast.ExpressionList expressionList) - { - VisitList(expressionList.Expressions); - return base.Visit(expressionList); - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericDeclaration genericDeclaration) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(genericDeclaration.Name); - if (!ReferenceEquals(nameTemp, genericDeclaration.Name)) - genericDeclaration.Name = nameTemp; - return base.Visit(genericDeclaration); - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericParameterType genericParameterType) - { - VisitList(genericParameterType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(genericParameterType.Name); - if (!ReferenceEquals(nameTemp, genericParameterType.Name)) - genericParameterType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(genericParameterType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, genericParameterType.Qualifiers)) - genericParameterType.Qualifiers = qualifiersTemp; - return base.Visit(genericParameterType); - } - public override Node Visit(Stride.Core.Shaders.Ast.DeclarationStatement declarationStatement) - { - VisitList(declarationStatement.Attributes); - var contentTemp = (Stride.Core.Shaders.Ast.Node)VisitDynamic(declarationStatement.Content); - if (!ReferenceEquals(contentTemp, declarationStatement.Content)) - declarationStatement.Content = contentTemp; - return base.Visit(declarationStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.ExpressionStatement expressionStatement) - { - VisitList(expressionStatement.Attributes); - var expressionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(expressionStatement.Expression); - if (!ReferenceEquals(expressionTemp, expressionStatement.Expression)) - expressionStatement.Expression = expressionTemp; - return base.Visit(expressionStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.ForStatement forStatement) - { - VisitList(forStatement.Attributes); - var startTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(forStatement.Start); - if (!ReferenceEquals(startTemp, forStatement.Start)) - forStatement.Start = startTemp; - var conditionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(forStatement.Condition); - if (!ReferenceEquals(conditionTemp, forStatement.Condition)) - forStatement.Condition = conditionTemp; - var nextTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(forStatement.Next); - if (!ReferenceEquals(nextTemp, forStatement.Next)) - forStatement.Next = nextTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(forStatement.Body); - if (!ReferenceEquals(bodyTemp, forStatement.Body)) - forStatement.Body = bodyTemp; - return base.Visit(forStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericType genericType) - { - VisitList(genericType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(genericType.Name); - if (!ReferenceEquals(nameTemp, genericType.Name)) - genericType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(genericType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, genericType.Qualifiers)) - genericType.Qualifiers = qualifiersTemp; - VisitList(genericType.Parameters); - return base.Visit(genericType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Identifier identifier) - { - VisitList(identifier.Indices); - return base.Visit(identifier); - } - public override Node Visit(Stride.Core.Shaders.Ast.IfStatement ifStatement) - { - VisitList(ifStatement.Attributes); - var conditionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(ifStatement.Condition); - if (!ReferenceEquals(conditionTemp, ifStatement.Condition)) - ifStatement.Condition = conditionTemp; - var elseTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(ifStatement.Else); - if (!ReferenceEquals(elseTemp, ifStatement.Else)) - ifStatement.Else = elseTemp; - var thenTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(ifStatement.Then); - if (!ReferenceEquals(thenTemp, ifStatement.Then)) - ifStatement.Then = thenTemp; - return base.Visit(ifStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.IndexerExpression indexerExpression) - { - var indexTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(indexerExpression.Index); - if (!ReferenceEquals(indexTemp, indexerExpression.Index)) - indexerExpression.Index = indexTemp; - var targetTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(indexerExpression.Target); - if (!ReferenceEquals(targetTemp, indexerExpression.Target)) - indexerExpression.Target = targetTemp; - return base.Visit(indexerExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.KeywordExpression keywordExpression) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(keywordExpression.Name); - if (!ReferenceEquals(nameTemp, keywordExpression.Name)) - keywordExpression.Name = nameTemp; - return base.Visit(keywordExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Literal literal) - { - VisitList(literal.SubLiterals); - return base.Visit(literal); - } - public override Node Visit(Stride.Core.Shaders.Ast.LiteralExpression literalExpression) - { - var literalTemp = (Stride.Core.Shaders.Ast.Literal)VisitDynamic(literalExpression.Literal); - if (!ReferenceEquals(literalTemp, literalExpression.Literal)) - literalExpression.Literal = literalTemp; - return base.Visit(literalExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.MatrixType matrixType) - { - VisitList(matrixType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(matrixType.Name); - if (!ReferenceEquals(nameTemp, matrixType.Name)) - matrixType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(matrixType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, matrixType.Qualifiers)) - matrixType.Qualifiers = qualifiersTemp; - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(matrixType.Type); - if (!ReferenceEquals(typeTemp, matrixType.Type)) - matrixType.Type = typeTemp; - return base.Visit(matrixType); - } - public override Node Visit(Stride.Core.Shaders.Ast.MemberReferenceExpression memberReferenceExpression) - { - var memberTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(memberReferenceExpression.Member); - if (!ReferenceEquals(memberTemp, memberReferenceExpression.Member)) - memberReferenceExpression.Member = memberTemp; - var targetTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(memberReferenceExpression.Target); - if (!ReferenceEquals(targetTemp, memberReferenceExpression.Target)) - memberReferenceExpression.Target = targetTemp; - return base.Visit(memberReferenceExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodDeclaration methodDeclaration) - { - VisitList(methodDeclaration.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(methodDeclaration.Name); - if (!ReferenceEquals(nameTemp, methodDeclaration.Name)) - methodDeclaration.Name = nameTemp; - VisitList(methodDeclaration.Parameters); - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(methodDeclaration.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, methodDeclaration.Qualifiers)) - methodDeclaration.Qualifiers = qualifiersTemp; - var returnTypeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(methodDeclaration.ReturnType); - if (!ReferenceEquals(returnTypeTemp, methodDeclaration.ReturnType)) - methodDeclaration.ReturnType = returnTypeTemp; - return base.Visit(methodDeclaration); - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodDefinition methodDefinition) - { - VisitList(methodDefinition.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(methodDefinition.Name); - if (!ReferenceEquals(nameTemp, methodDefinition.Name)) - methodDefinition.Name = nameTemp; - VisitList(methodDefinition.Parameters); - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(methodDefinition.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, methodDefinition.Qualifiers)) - methodDefinition.Qualifiers = qualifiersTemp; - var returnTypeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(methodDefinition.ReturnType); - if (!ReferenceEquals(returnTypeTemp, methodDefinition.ReturnType)) - methodDefinition.ReturnType = returnTypeTemp; - var bodyTemp = (Stride.Core.Shaders.Ast.StatementList)VisitDynamic(methodDefinition.Body); - if (!ReferenceEquals(bodyTemp, methodDefinition.Body)) - methodDefinition.Body = bodyTemp; - return base.Visit(methodDefinition); - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodInvocationExpression methodInvocationExpression) - { - var targetTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(methodInvocationExpression.Target); - if (!ReferenceEquals(targetTemp, methodInvocationExpression.Target)) - methodInvocationExpression.Target = targetTemp; - VisitList(methodInvocationExpression.Arguments); - return base.Visit(methodInvocationExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.ObjectType objectType) - { - VisitList(objectType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(objectType.Name); - if (!ReferenceEquals(nameTemp, objectType.Name)) - objectType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(objectType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, objectType.Qualifiers)) - objectType.Qualifiers = qualifiersTemp; - return base.Visit(objectType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Parameter parameter) - { - VisitList(parameter.Attributes); - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(parameter.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, parameter.Qualifiers)) - parameter.Qualifiers = qualifiersTemp; - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(parameter.Type); - if (!ReferenceEquals(typeTemp, parameter.Type)) - parameter.Type = typeTemp; - var initialValueTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(parameter.InitialValue); - if (!ReferenceEquals(initialValueTemp, parameter.InitialValue)) - parameter.InitialValue = initialValueTemp; - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(parameter.Name); - if (!ReferenceEquals(nameTemp, parameter.Name)) - parameter.Name = nameTemp; - VisitList(parameter.SubVariables); - return base.Visit(parameter); - } - public override Node Visit(Stride.Core.Shaders.Ast.ParenthesizedExpression parenthesizedExpression) - { - var contentTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(parenthesizedExpression.Content); - if (!ReferenceEquals(contentTemp, parenthesizedExpression.Content)) - parenthesizedExpression.Content = contentTemp; - return base.Visit(parenthesizedExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Qualifier qualifier) - { - return base.Visit(qualifier); - } - public override Node Visit(Stride.Core.Shaders.Ast.ReturnStatement returnStatement) - { - VisitList(returnStatement.Attributes); - var valueTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(returnStatement.Value); - if (!ReferenceEquals(valueTemp, returnStatement.Value)) - returnStatement.Value = valueTemp; - return base.Visit(returnStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.ScalarType scalarType) - { - VisitList(scalarType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(scalarType.Name); - if (!ReferenceEquals(nameTemp, scalarType.Name)) - scalarType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(scalarType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, scalarType.Qualifiers)) - scalarType.Qualifiers = qualifiersTemp; - return base.Visit(scalarType); - } - public override Node Visit(Stride.Core.Shaders.Ast.Shader shader) - { - VisitList(shader.Declarations); - return base.Visit(shader); - } - public override Node Visit(Stride.Core.Shaders.Ast.StatementList statementList) - { - VisitList(statementList.Attributes); - VisitList(statementList.Statements); - return base.Visit(statementList); - } - public override Node Visit(Stride.Core.Shaders.Ast.StructType structType) - { - VisitList(structType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(structType.Name); - if (!ReferenceEquals(nameTemp, structType.Name)) - structType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(structType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, structType.Qualifiers)) - structType.Qualifiers = qualifiersTemp; - VisitList(structType.Fields); - return base.Visit(structType); - } - public override Node Visit(Stride.Core.Shaders.Ast.SwitchCaseGroup switchCaseGroup) - { - VisitList(switchCaseGroup.Cases); - var statementsTemp = (Stride.Core.Shaders.Ast.StatementList)VisitDynamic(switchCaseGroup.Statements); - if (!ReferenceEquals(statementsTemp, switchCaseGroup.Statements)) - switchCaseGroup.Statements = statementsTemp; - return base.Visit(switchCaseGroup); - } - public override Node Visit(Stride.Core.Shaders.Ast.SwitchStatement switchStatement) - { - VisitList(switchStatement.Attributes); - var conditionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(switchStatement.Condition); - if (!ReferenceEquals(conditionTemp, switchStatement.Condition)) - switchStatement.Condition = conditionTemp; - VisitList(switchStatement.Groups); - return base.Visit(switchStatement); - } - public override Node Visit(Stride.Core.Shaders.Ast.TypeName typeName) - { - VisitList(typeName.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(typeName.Name); - if (!ReferenceEquals(nameTemp, typeName.Name)) - typeName.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(typeName.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, typeName.Qualifiers)) - typeName.Qualifiers = qualifiersTemp; - return base.Visit(typeName); - } - public override Node Visit(Stride.Core.Shaders.Ast.TypeReferenceExpression typeReferenceExpression) - { - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(typeReferenceExpression.Type); - if (!ReferenceEquals(typeTemp, typeReferenceExpression.Type)) - typeReferenceExpression.Type = typeTemp; - return base.Visit(typeReferenceExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.UnaryExpression unaryExpression) - { - var expressionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(unaryExpression.Expression); - if (!ReferenceEquals(expressionTemp, unaryExpression.Expression)) - unaryExpression.Expression = expressionTemp; - return base.Visit(unaryExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.Variable variable) - { - VisitList(variable.Attributes); - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(variable.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, variable.Qualifiers)) - variable.Qualifiers = qualifiersTemp; - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(variable.Type); - if (!ReferenceEquals(typeTemp, variable.Type)) - variable.Type = typeTemp; - var initialValueTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(variable.InitialValue); - if (!ReferenceEquals(initialValueTemp, variable.InitialValue)) - variable.InitialValue = initialValueTemp; - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(variable.Name); - if (!ReferenceEquals(nameTemp, variable.Name)) - variable.Name = nameTemp; - VisitList(variable.SubVariables); - return base.Visit(variable); - } - public override Node Visit(Stride.Core.Shaders.Ast.VariableReferenceExpression variableReferenceExpression) - { - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(variableReferenceExpression.Name); - if (!ReferenceEquals(nameTemp, variableReferenceExpression.Name)) - variableReferenceExpression.Name = nameTemp; - return base.Visit(variableReferenceExpression); - } - public override Node Visit(Stride.Core.Shaders.Ast.VectorType vectorType) - { - VisitList(vectorType.Attributes); - var nameTemp = (Stride.Core.Shaders.Ast.Identifier)VisitDynamic(vectorType.Name); - if (!ReferenceEquals(nameTemp, vectorType.Name)) - vectorType.Name = nameTemp; - var qualifiersTemp = (Stride.Core.Shaders.Ast.Qualifier)VisitDynamic(vectorType.Qualifiers); - if (!ReferenceEquals(qualifiersTemp, vectorType.Qualifiers)) - vectorType.Qualifiers = qualifiersTemp; - var typeTemp = (Stride.Core.Shaders.Ast.TypeBase)VisitDynamic(vectorType.Type); - if (!ReferenceEquals(typeTemp, vectorType.Type)) - vectorType.Type = typeTemp; - return base.Visit(vectorType); - } - public override Node Visit(Stride.Core.Shaders.Ast.WhileStatement whileStatement) - { - VisitList(whileStatement.Attributes); - var conditionTemp = (Stride.Core.Shaders.Ast.Expression)VisitDynamic(whileStatement.Condition); - if (!ReferenceEquals(conditionTemp, whileStatement.Condition)) - whileStatement.Condition = conditionTemp; - var statementTemp = (Stride.Core.Shaders.Ast.Statement)VisitDynamic(whileStatement.Statement); - if (!ReferenceEquals(statementTemp, whileStatement.Statement)) - whileStatement.Statement = statementTemp; - return base.Visit(whileStatement); - } - } - - public partial class ShaderCloner - { - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric classIdentifierGeneric) - { - classIdentifierGeneric = (Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric)base.Visit(classIdentifierGeneric); - return new Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric - { - Span = classIdentifierGeneric.Span, - Tags = classIdentifierGeneric.Tags, - Indices = classIdentifierGeneric.Indices, - IsSpecialReference = classIdentifierGeneric.IsSpecialReference, - Text = classIdentifierGeneric.Text, - Generics = classIdentifierGeneric.Generics, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.EnumType enumType) - { - enumType = (Stride.Core.Shaders.Ast.Stride.EnumType)base.Visit(enumType); - return new Stride.Core.Shaders.Ast.Stride.EnumType - { - Span = enumType.Span, - Tags = enumType.Tags, - Attributes = enumType.Attributes, - TypeInference = enumType.TypeInference, - Name = enumType.Name, - Qualifiers = enumType.Qualifiers, - IsBuiltIn = enumType.IsBuiltIn, - Values = enumType.Values, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ForEachStatement forEachStatement) - { - forEachStatement = (Stride.Core.Shaders.Ast.Stride.ForEachStatement)base.Visit(forEachStatement); - return new Stride.Core.Shaders.Ast.Stride.ForEachStatement - { - Span = forEachStatement.Span, - Tags = forEachStatement.Tags, - Attributes = forEachStatement.Attributes, - Collection = forEachStatement.Collection, - Variable = forEachStatement.Variable, - Body = forEachStatement.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ImportBlockStatement importBlockStatement) - { - importBlockStatement = (Stride.Core.Shaders.Ast.Stride.ImportBlockStatement)base.Visit(importBlockStatement); - return new Stride.Core.Shaders.Ast.Stride.ImportBlockStatement - { - Span = importBlockStatement.Span, - Tags = importBlockStatement.Tags, - Attributes = importBlockStatement.Attributes, - Statements = importBlockStatement.Statements, - Name = importBlockStatement.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.LinkType linkType) - { - linkType = (Stride.Core.Shaders.Ast.Stride.LinkType)base.Visit(linkType); - return new Stride.Core.Shaders.Ast.Stride.LinkType - { - Span = linkType.Span, - Tags = linkType.Tags, - Attributes = linkType.Attributes, - TypeInference = linkType.TypeInference, - Name = linkType.Name, - Qualifiers = linkType.Qualifiers, - IsBuiltIn = linkType.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.LiteralIdentifier literalIdentifier) - { - literalIdentifier = (Stride.Core.Shaders.Ast.Stride.LiteralIdentifier)base.Visit(literalIdentifier); - return new Stride.Core.Shaders.Ast.Stride.LiteralIdentifier - { - Span = literalIdentifier.Span, - Tags = literalIdentifier.Tags, - Indices = literalIdentifier.Indices, - IsSpecialReference = literalIdentifier.IsSpecialReference, - Text = literalIdentifier.Text, - Value = literalIdentifier.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.MemberName memberName) - { - memberName = (Stride.Core.Shaders.Ast.Stride.MemberName)base.Visit(memberName); - return new Stride.Core.Shaders.Ast.Stride.MemberName - { - Span = memberName.Span, - Tags = memberName.Tags, - Attributes = memberName.Attributes, - TypeInference = memberName.TypeInference, - Name = memberName.Name, - Qualifiers = memberName.Qualifiers, - IsBuiltIn = memberName.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.MixinStatement mixinStatement) - { - mixinStatement = (Stride.Core.Shaders.Ast.Stride.MixinStatement)base.Visit(mixinStatement); - return new Stride.Core.Shaders.Ast.Stride.MixinStatement - { - Span = mixinStatement.Span, - Tags = mixinStatement.Tags, - Attributes = mixinStatement.Attributes, - Type = mixinStatement.Type, - Value = mixinStatement.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.NamespaceBlock namespaceBlock) - { - namespaceBlock = (Stride.Core.Shaders.Ast.Stride.NamespaceBlock)base.Visit(namespaceBlock); - return new Stride.Core.Shaders.Ast.Stride.NamespaceBlock - { - Span = namespaceBlock.Span, - Tags = namespaceBlock.Tags, - Attributes = namespaceBlock.Attributes, - TypeInference = namespaceBlock.TypeInference, - Name = namespaceBlock.Name, - Qualifiers = namespaceBlock.Qualifiers, - IsBuiltIn = namespaceBlock.IsBuiltIn, - Body = namespaceBlock.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ParametersBlock parametersBlock) - { - parametersBlock = (Stride.Core.Shaders.Ast.Stride.ParametersBlock)base.Visit(parametersBlock); - return new Stride.Core.Shaders.Ast.Stride.ParametersBlock - { - Span = parametersBlock.Span, - Tags = parametersBlock.Tags, - Name = parametersBlock.Name, - Body = parametersBlock.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.SemanticType semanticType) - { - semanticType = (Stride.Core.Shaders.Ast.Stride.SemanticType)base.Visit(semanticType); - return new Stride.Core.Shaders.Ast.Stride.SemanticType - { - Span = semanticType.Span, - Tags = semanticType.Tags, - Attributes = semanticType.Attributes, - TypeInference = semanticType.TypeInference, - Name = semanticType.Name, - Qualifiers = semanticType.Qualifiers, - IsBuiltIn = semanticType.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.EffectBlock effectBlock) - { - effectBlock = (Stride.Core.Shaders.Ast.Stride.EffectBlock)base.Visit(effectBlock); - return new Stride.Core.Shaders.Ast.Stride.EffectBlock - { - Span = effectBlock.Span, - Tags = effectBlock.Tags, - Attributes = effectBlock.Attributes, - TypeInference = effectBlock.TypeInference, - Name = effectBlock.Name, - Qualifiers = effectBlock.Qualifiers, - IsBuiltIn = effectBlock.IsBuiltIn, - IsPartial = effectBlock.IsPartial, - Body = effectBlock.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderClassType shaderClassType) - { - shaderClassType = (Stride.Core.Shaders.Ast.Stride.ShaderClassType)base.Visit(shaderClassType); - return new Stride.Core.Shaders.Ast.Stride.ShaderClassType - { - Span = shaderClassType.Span, - Tags = shaderClassType.Tags, - Attributes = shaderClassType.Attributes, - TypeInference = shaderClassType.TypeInference, - Name = shaderClassType.Name, - Qualifiers = shaderClassType.Qualifiers, - IsBuiltIn = shaderClassType.IsBuiltIn, - AlternativeNames = shaderClassType.AlternativeNames, - BaseClasses = shaderClassType.BaseClasses, - GenericParameters = shaderClassType.GenericParameters, - GenericArguments = shaderClassType.GenericArguments, - Members = shaderClassType.Members, - ShaderGenerics = shaderClassType.ShaderGenerics, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderRootClassType shaderRootClassType) - { - shaderRootClassType = (Stride.Core.Shaders.Ast.Stride.ShaderRootClassType)base.Visit(shaderRootClassType); - return new Stride.Core.Shaders.Ast.Stride.ShaderRootClassType - { - Span = shaderRootClassType.Span, - Tags = shaderRootClassType.Tags, - Attributes = shaderRootClassType.Attributes, - TypeInference = shaderRootClassType.TypeInference, - Name = shaderRootClassType.Name, - Qualifiers = shaderRootClassType.Qualifiers, - IsBuiltIn = shaderRootClassType.IsBuiltIn, - AlternativeNames = shaderRootClassType.AlternativeNames, - BaseClasses = shaderRootClassType.BaseClasses, - GenericParameters = shaderRootClassType.GenericParameters, - GenericArguments = shaderRootClassType.GenericArguments, - Members = shaderRootClassType.Members, - ShaderGenerics = shaderRootClassType.ShaderGenerics, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.ShaderTypeName shaderTypeName) - { - shaderTypeName = (Stride.Core.Shaders.Ast.Stride.ShaderTypeName)base.Visit(shaderTypeName); - return new Stride.Core.Shaders.Ast.Stride.ShaderTypeName - { - Span = shaderTypeName.Span, - Tags = shaderTypeName.Tags, - Attributes = shaderTypeName.Attributes, - TypeInference = shaderTypeName.TypeInference, - Name = shaderTypeName.Name, - Qualifiers = shaderTypeName.Qualifiers, - IsBuiltIn = shaderTypeName.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.TypeIdentifier typeIdentifier) - { - typeIdentifier = (Stride.Core.Shaders.Ast.Stride.TypeIdentifier)base.Visit(typeIdentifier); - return new Stride.Core.Shaders.Ast.Stride.TypeIdentifier - { - Span = typeIdentifier.Span, - Tags = typeIdentifier.Tags, - Indices = typeIdentifier.Indices, - IsSpecialReference = typeIdentifier.IsSpecialReference, - Text = typeIdentifier.Text, - Type = typeIdentifier.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.UsingParametersStatement usingParametersStatement) - { - usingParametersStatement = (Stride.Core.Shaders.Ast.Stride.UsingParametersStatement)base.Visit(usingParametersStatement); - return new Stride.Core.Shaders.Ast.Stride.UsingParametersStatement - { - Span = usingParametersStatement.Span, - Tags = usingParametersStatement.Tags, - Attributes = usingParametersStatement.Attributes, - Name = usingParametersStatement.Name, - Body = usingParametersStatement.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.UsingStatement usingStatement) - { - usingStatement = (Stride.Core.Shaders.Ast.Stride.UsingStatement)base.Visit(usingStatement); - return new Stride.Core.Shaders.Ast.Stride.UsingStatement - { - Span = usingStatement.Span, - Tags = usingStatement.Tags, - Attributes = usingStatement.Attributes, - Name = usingStatement.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.VarType varType) - { - varType = (Stride.Core.Shaders.Ast.Stride.VarType)base.Visit(varType); - return new Stride.Core.Shaders.Ast.Stride.VarType - { - Span = varType.Span, - Tags = varType.Tags, - Attributes = varType.Attributes, - TypeInference = varType.TypeInference, - Name = varType.Name, - Qualifiers = varType.Qualifiers, - IsBuiltIn = varType.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType strideConstantBufferType) - { - strideConstantBufferType = (Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType)base.Visit(strideConstantBufferType); - return new Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType - { - Span = strideConstantBufferType.Span, - Tags = strideConstantBufferType.Tags, - IsFlag = strideConstantBufferType.IsFlag, - Key = strideConstantBufferType.Key, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ArrayInitializerExpression arrayInitializerExpression) - { - arrayInitializerExpression = (Stride.Core.Shaders.Ast.ArrayInitializerExpression)base.Visit(arrayInitializerExpression); - return new Stride.Core.Shaders.Ast.ArrayInitializerExpression - { - Span = arrayInitializerExpression.Span, - Tags = arrayInitializerExpression.Tags, - TypeInference = arrayInitializerExpression.TypeInference, - Items = arrayInitializerExpression.Items, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ArrayType arrayType) - { - arrayType = (Stride.Core.Shaders.Ast.ArrayType)base.Visit(arrayType); - return new Stride.Core.Shaders.Ast.ArrayType - { - Span = arrayType.Span, - Tags = arrayType.Tags, - Attributes = arrayType.Attributes, - TypeInference = arrayType.TypeInference, - Name = arrayType.Name, - Qualifiers = arrayType.Qualifiers, - IsBuiltIn = arrayType.IsBuiltIn, - Dimensions = arrayType.Dimensions, - Type = arrayType.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.AssignmentExpression assignmentExpression) - { - assignmentExpression = (Stride.Core.Shaders.Ast.AssignmentExpression)base.Visit(assignmentExpression); - return new Stride.Core.Shaders.Ast.AssignmentExpression - { - Span = assignmentExpression.Span, - Tags = assignmentExpression.Tags, - TypeInference = assignmentExpression.TypeInference, - Operator = assignmentExpression.Operator, - Target = assignmentExpression.Target, - Value = assignmentExpression.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.BinaryExpression binaryExpression) - { - binaryExpression = (Stride.Core.Shaders.Ast.BinaryExpression)base.Visit(binaryExpression); - return new Stride.Core.Shaders.Ast.BinaryExpression - { - Span = binaryExpression.Span, - Tags = binaryExpression.Tags, - TypeInference = binaryExpression.TypeInference, - Left = binaryExpression.Left, - Operator = binaryExpression.Operator, - Right = binaryExpression.Right, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.BlockStatement blockStatement) - { - blockStatement = (Stride.Core.Shaders.Ast.BlockStatement)base.Visit(blockStatement); - return new Stride.Core.Shaders.Ast.BlockStatement - { - Span = blockStatement.Span, - Tags = blockStatement.Tags, - Attributes = blockStatement.Attributes, - Statements = blockStatement.Statements, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.CaseStatement caseStatement) - { - caseStatement = (Stride.Core.Shaders.Ast.CaseStatement)base.Visit(caseStatement); - return new Stride.Core.Shaders.Ast.CaseStatement - { - Span = caseStatement.Span, - Tags = caseStatement.Tags, - Attributes = caseStatement.Attributes, - Case = caseStatement.Case, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.CompositeEnum compositeEnum) - { - compositeEnum = (Stride.Core.Shaders.Ast.CompositeEnum)base.Visit(compositeEnum); - return new Stride.Core.Shaders.Ast.CompositeEnum - { - Span = compositeEnum.Span, - Tags = compositeEnum.Tags, - IsFlag = compositeEnum.IsFlag, - Key = compositeEnum.Key, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ConditionalExpression conditionalExpression) - { - conditionalExpression = (Stride.Core.Shaders.Ast.ConditionalExpression)base.Visit(conditionalExpression); - return new Stride.Core.Shaders.Ast.ConditionalExpression - { - Span = conditionalExpression.Span, - Tags = conditionalExpression.Tags, - TypeInference = conditionalExpression.TypeInference, - Condition = conditionalExpression.Condition, - Left = conditionalExpression.Left, - Right = conditionalExpression.Right, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.EmptyStatement emptyStatement) - { - emptyStatement = (Stride.Core.Shaders.Ast.EmptyStatement)base.Visit(emptyStatement); - return new Stride.Core.Shaders.Ast.EmptyStatement - { - Span = emptyStatement.Span, - Tags = emptyStatement.Tags, - Attributes = emptyStatement.Attributes, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.EmptyExpression emptyExpression) - { - emptyExpression = (Stride.Core.Shaders.Ast.EmptyExpression)base.Visit(emptyExpression); - return new Stride.Core.Shaders.Ast.EmptyExpression - { - Span = emptyExpression.Span, - Tags = emptyExpression.Tags, - TypeInference = emptyExpression.TypeInference, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue layoutKeyValue) - { - layoutKeyValue = (Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue)base.Visit(layoutKeyValue); - return new Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue - { - Span = layoutKeyValue.Span, - Tags = layoutKeyValue.Tags, - Name = layoutKeyValue.Name, - Value = layoutKeyValue.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.LayoutQualifier layoutQualifier) - { - layoutQualifier = (Stride.Core.Shaders.Ast.Glsl.LayoutQualifier)base.Visit(layoutQualifier); - return new Stride.Core.Shaders.Ast.Glsl.LayoutQualifier - { - Span = layoutQualifier.Span, - Tags = layoutQualifier.Tags, - IsFlag = layoutQualifier.IsFlag, - Key = layoutQualifier.Key, - IsPost = layoutQualifier.IsPost, - Layouts = layoutQualifier.Layouts, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Glsl.InterfaceType interfaceType) - { - interfaceType = (Stride.Core.Shaders.Ast.Glsl.InterfaceType)base.Visit(interfaceType); - return new Stride.Core.Shaders.Ast.Glsl.InterfaceType - { - Span = interfaceType.Span, - Tags = interfaceType.Tags, - Attributes = interfaceType.Attributes, - TypeInference = interfaceType.TypeInference, - Name = interfaceType.Name, - Qualifiers = interfaceType.Qualifiers, - IsBuiltIn = interfaceType.IsBuiltIn, - Fields = interfaceType.Fields, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ClassType classType) - { - classType = (Stride.Core.Shaders.Ast.Hlsl.ClassType)base.Visit(classType); - return new Stride.Core.Shaders.Ast.Hlsl.ClassType - { - Span = classType.Span, - Tags = classType.Tags, - Attributes = classType.Attributes, - TypeInference = classType.TypeInference, - Name = classType.Name, - Qualifiers = classType.Qualifiers, - IsBuiltIn = classType.IsBuiltIn, - AlternativeNames = classType.AlternativeNames, - BaseClasses = classType.BaseClasses, - GenericParameters = classType.GenericParameters, - GenericArguments = classType.GenericArguments, - Members = classType.Members, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric identifierGeneric) - { - identifierGeneric = (Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric)base.Visit(identifierGeneric); - return new Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric - { - Span = identifierGeneric.Span, - Tags = identifierGeneric.Tags, - Indices = identifierGeneric.Indices, - IsSpecialReference = identifierGeneric.IsSpecialReference, - Text = identifierGeneric.Text, - Identifiers = identifierGeneric.Identifiers, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierNs identifierNs) - { - identifierNs = (Stride.Core.Shaders.Ast.Hlsl.IdentifierNs)base.Visit(identifierNs); - return new Stride.Core.Shaders.Ast.Hlsl.IdentifierNs - { - Span = identifierNs.Span, - Tags = identifierNs.Tags, - Indices = identifierNs.Indices, - IsSpecialReference = identifierNs.IsSpecialReference, - Text = identifierNs.Text, - Identifiers = identifierNs.Identifiers, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierDot identifierDot) - { - identifierDot = (Stride.Core.Shaders.Ast.Hlsl.IdentifierDot)base.Visit(identifierDot); - return new Stride.Core.Shaders.Ast.Hlsl.IdentifierDot - { - Span = identifierDot.Span, - Tags = identifierDot.Tags, - Indices = identifierDot.Indices, - IsSpecialReference = identifierDot.IsSpecialReference, - Text = identifierDot.Text, - Identifiers = identifierDot.Identifiers, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.TextureType textureType) - { - textureType = (Stride.Core.Shaders.Ast.Hlsl.TextureType)base.Visit(textureType); - return new Stride.Core.Shaders.Ast.Hlsl.TextureType - { - Span = textureType.Span, - Tags = textureType.Tags, - Attributes = textureType.Attributes, - TypeInference = textureType.TypeInference, - Name = textureType.Name, - Qualifiers = textureType.Qualifiers, - IsBuiltIn = textureType.IsBuiltIn, - AlternativeNames = textureType.AlternativeNames, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Annotations annotations) - { - annotations = (Stride.Core.Shaders.Ast.Hlsl.Annotations)base.Visit(annotations); - return new Stride.Core.Shaders.Ast.Hlsl.Annotations - { - Span = annotations.Span, - Tags = annotations.Tags, - Variables = annotations.Variables, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.AsmExpression asmExpression) - { - asmExpression = (Stride.Core.Shaders.Ast.Hlsl.AsmExpression)base.Visit(asmExpression); - return new Stride.Core.Shaders.Ast.Hlsl.AsmExpression - { - Span = asmExpression.Span, - Tags = asmExpression.Tags, - TypeInference = asmExpression.TypeInference, - Text = asmExpression.Text, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration attributeDeclaration) - { - attributeDeclaration = (Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration)base.Visit(attributeDeclaration); - return new Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration - { - Span = attributeDeclaration.Span, - Tags = attributeDeclaration.Tags, - Name = attributeDeclaration.Name, - Parameters = attributeDeclaration.Parameters, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.CastExpression castExpression) - { - castExpression = (Stride.Core.Shaders.Ast.Hlsl.CastExpression)base.Visit(castExpression); - return new Stride.Core.Shaders.Ast.Hlsl.CastExpression - { - Span = castExpression.Span, - Tags = castExpression.Tags, - TypeInference = castExpression.TypeInference, - From = castExpression.From, - Target = castExpression.Target, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.CompileExpression compileExpression) - { - compileExpression = (Stride.Core.Shaders.Ast.Hlsl.CompileExpression)base.Visit(compileExpression); - return new Stride.Core.Shaders.Ast.Hlsl.CompileExpression - { - Span = compileExpression.Span, - Tags = compileExpression.Tags, - TypeInference = compileExpression.TypeInference, - Function = compileExpression.Function, - Profile = compileExpression.Profile, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer constantBuffer) - { - constantBuffer = (Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer)base.Visit(constantBuffer); - return new Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer - { - Span = constantBuffer.Span, - Tags = constantBuffer.Tags, - Attributes = constantBuffer.Attributes, - Type = constantBuffer.Type, - Members = constantBuffer.Members, - Name = constantBuffer.Name, - Register = constantBuffer.Register, - Qualifiers = constantBuffer.Qualifiers, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType constantBufferType) - { - constantBufferType = (Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType)base.Visit(constantBufferType); - return new Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType - { - Span = constantBufferType.Span, - Tags = constantBufferType.Tags, - IsFlag = constantBufferType.IsFlag, - Key = constantBufferType.Key, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.InterfaceType interfaceType) - { - interfaceType = (Stride.Core.Shaders.Ast.Hlsl.InterfaceType)base.Visit(interfaceType); - return new Stride.Core.Shaders.Ast.Hlsl.InterfaceType - { - Span = interfaceType.Span, - Tags = interfaceType.Tags, - Attributes = interfaceType.Attributes, - TypeInference = interfaceType.TypeInference, - Name = interfaceType.Name, - Qualifiers = interfaceType.Qualifiers, - IsBuiltIn = interfaceType.IsBuiltIn, - AlternativeNames = interfaceType.AlternativeNames, - GenericParameters = interfaceType.GenericParameters, - GenericArguments = interfaceType.GenericArguments, - Methods = interfaceType.Methods, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.PackOffset packOffset) - { - packOffset = (Stride.Core.Shaders.Ast.Hlsl.PackOffset)base.Visit(packOffset); - return new Stride.Core.Shaders.Ast.Hlsl.PackOffset - { - Span = packOffset.Span, - Tags = packOffset.Tags, - IsFlag = packOffset.IsFlag, - Key = packOffset.Key, - IsPost = packOffset.IsPost, - Value = packOffset.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Pass pass) - { - pass = (Stride.Core.Shaders.Ast.Hlsl.Pass)base.Visit(pass); - return new Stride.Core.Shaders.Ast.Hlsl.Pass - { - Span = pass.Span, - Tags = pass.Tags, - Attributes = pass.Attributes, - Items = pass.Items, - Name = pass.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.RegisterLocation registerLocation) - { - registerLocation = (Stride.Core.Shaders.Ast.Hlsl.RegisterLocation)base.Visit(registerLocation); - return new Stride.Core.Shaders.Ast.Hlsl.RegisterLocation - { - Span = registerLocation.Span, - Tags = registerLocation.Tags, - IsFlag = registerLocation.IsFlag, - Key = registerLocation.Key, - IsPost = registerLocation.IsPost, - Profile = registerLocation.Profile, - Register = registerLocation.Register, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Semantic semantic) - { - semantic = (Stride.Core.Shaders.Ast.Hlsl.Semantic)base.Visit(semantic); - return new Stride.Core.Shaders.Ast.Hlsl.Semantic - { - Span = semantic.Span, - Tags = semantic.Tags, - IsFlag = semantic.IsFlag, - Key = semantic.Key, - IsPost = semantic.IsPost, - Name = semantic.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.StateExpression stateExpression) - { - stateExpression = (Stride.Core.Shaders.Ast.Hlsl.StateExpression)base.Visit(stateExpression); - return new Stride.Core.Shaders.Ast.Hlsl.StateExpression - { - Span = stateExpression.Span, - Tags = stateExpression.Tags, - TypeInference = stateExpression.TypeInference, - Initializer = stateExpression.Initializer, - StateType = stateExpression.StateType, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.StateInitializer stateInitializer) - { - stateInitializer = (Stride.Core.Shaders.Ast.Hlsl.StateInitializer)base.Visit(stateInitializer); - return new Stride.Core.Shaders.Ast.Hlsl.StateInitializer - { - Span = stateInitializer.Span, - Tags = stateInitializer.Tags, - TypeInference = stateInitializer.TypeInference, - Items = stateInitializer.Items, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Technique technique) - { - technique = (Stride.Core.Shaders.Ast.Hlsl.Technique)base.Visit(technique); - return new Stride.Core.Shaders.Ast.Hlsl.Technique - { - Span = technique.Span, - Tags = technique.Tags, - Type = technique.Type, - Attributes = technique.Attributes, - Name = technique.Name, - Passes = technique.Passes, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Hlsl.Typedef typedef) - { - typedef = (Stride.Core.Shaders.Ast.Hlsl.Typedef)base.Visit(typedef); - return new Stride.Core.Shaders.Ast.Hlsl.Typedef - { - Span = typedef.Span, - Tags = typedef.Tags, - Attributes = typedef.Attributes, - TypeInference = typedef.TypeInference, - Name = typedef.Name, - Qualifiers = typedef.Qualifiers, - IsBuiltIn = typedef.IsBuiltIn, - SubDeclarators = typedef.SubDeclarators, - Type = typedef.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ExpressionList expressionList) - { - expressionList = (Stride.Core.Shaders.Ast.ExpressionList)base.Visit(expressionList); - return new Stride.Core.Shaders.Ast.ExpressionList - { - Span = expressionList.Span, - Tags = expressionList.Tags, - TypeInference = expressionList.TypeInference, - Expressions = expressionList.Expressions, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericDeclaration genericDeclaration) - { - genericDeclaration = (Stride.Core.Shaders.Ast.GenericDeclaration)base.Visit(genericDeclaration); - return new Stride.Core.Shaders.Ast.GenericDeclaration - { - Span = genericDeclaration.Span, - Tags = genericDeclaration.Tags, - Name = genericDeclaration.Name, - Holder = genericDeclaration.Holder, - Index = genericDeclaration.Index, - IsUsingBase = genericDeclaration.IsUsingBase, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericParameterType genericParameterType) - { - genericParameterType = (Stride.Core.Shaders.Ast.GenericParameterType)base.Visit(genericParameterType); - return new Stride.Core.Shaders.Ast.GenericParameterType - { - Span = genericParameterType.Span, - Tags = genericParameterType.Tags, - Attributes = genericParameterType.Attributes, - TypeInference = genericParameterType.TypeInference, - Name = genericParameterType.Name, - Qualifiers = genericParameterType.Qualifiers, - IsBuiltIn = genericParameterType.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.DeclarationStatement declarationStatement) - { - declarationStatement = (Stride.Core.Shaders.Ast.DeclarationStatement)base.Visit(declarationStatement); - return new Stride.Core.Shaders.Ast.DeclarationStatement - { - Span = declarationStatement.Span, - Tags = declarationStatement.Tags, - Attributes = declarationStatement.Attributes, - Content = declarationStatement.Content, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ExpressionStatement expressionStatement) - { - expressionStatement = (Stride.Core.Shaders.Ast.ExpressionStatement)base.Visit(expressionStatement); - return new Stride.Core.Shaders.Ast.ExpressionStatement - { - Span = expressionStatement.Span, - Tags = expressionStatement.Tags, - Attributes = expressionStatement.Attributes, - Expression = expressionStatement.Expression, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ForStatement forStatement) - { - forStatement = (Stride.Core.Shaders.Ast.ForStatement)base.Visit(forStatement); - return new Stride.Core.Shaders.Ast.ForStatement - { - Span = forStatement.Span, - Tags = forStatement.Tags, - Attributes = forStatement.Attributes, - Start = forStatement.Start, - Condition = forStatement.Condition, - Next = forStatement.Next, - Body = forStatement.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.GenericType genericType) - { - genericType = (Stride.Core.Shaders.Ast.GenericType)base.Visit(genericType); - return new Stride.Core.Shaders.Ast.GenericType - { - Span = genericType.Span, - Tags = genericType.Tags, - Attributes = genericType.Attributes, - TypeInference = genericType.TypeInference, - Name = genericType.Name, - Qualifiers = genericType.Qualifiers, - IsBuiltIn = genericType.IsBuiltIn, - ParameterTypes = genericType.ParameterTypes, - Parameters = genericType.Parameters, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Identifier identifier) - { - identifier = (Stride.Core.Shaders.Ast.Identifier)base.Visit(identifier); - return new Stride.Core.Shaders.Ast.Identifier - { - Span = identifier.Span, - Tags = identifier.Tags, - Indices = identifier.Indices, - IsSpecialReference = identifier.IsSpecialReference, - Text = identifier.Text, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.IfStatement ifStatement) - { - ifStatement = (Stride.Core.Shaders.Ast.IfStatement)base.Visit(ifStatement); - return new Stride.Core.Shaders.Ast.IfStatement - { - Span = ifStatement.Span, - Tags = ifStatement.Tags, - Attributes = ifStatement.Attributes, - Condition = ifStatement.Condition, - Else = ifStatement.Else, - Then = ifStatement.Then, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.IndexerExpression indexerExpression) - { - indexerExpression = (Stride.Core.Shaders.Ast.IndexerExpression)base.Visit(indexerExpression); - return new Stride.Core.Shaders.Ast.IndexerExpression - { - Span = indexerExpression.Span, - Tags = indexerExpression.Tags, - TypeInference = indexerExpression.TypeInference, - Index = indexerExpression.Index, - Target = indexerExpression.Target, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.KeywordExpression keywordExpression) - { - keywordExpression = (Stride.Core.Shaders.Ast.KeywordExpression)base.Visit(keywordExpression); - return new Stride.Core.Shaders.Ast.KeywordExpression - { - Span = keywordExpression.Span, - Tags = keywordExpression.Tags, - TypeInference = keywordExpression.TypeInference, - Name = keywordExpression.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Literal literal) - { - literal = (Stride.Core.Shaders.Ast.Literal)base.Visit(literal); - return new Stride.Core.Shaders.Ast.Literal - { - Span = literal.Span, - Tags = literal.Tags, - Value = literal.Value, - Text = literal.Text, - SubLiterals = literal.SubLiterals, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.LiteralExpression literalExpression) - { - literalExpression = (Stride.Core.Shaders.Ast.LiteralExpression)base.Visit(literalExpression); - return new Stride.Core.Shaders.Ast.LiteralExpression - { - Span = literalExpression.Span, - Tags = literalExpression.Tags, - TypeInference = literalExpression.TypeInference, - Literal = literalExpression.Literal, - Text = literalExpression.Text, - Value = literalExpression.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.MatrixType matrixType) - { - matrixType = (Stride.Core.Shaders.Ast.MatrixType)base.Visit(matrixType); - return new Stride.Core.Shaders.Ast.MatrixType - { - Span = matrixType.Span, - Tags = matrixType.Tags, - Attributes = matrixType.Attributes, - TypeInference = matrixType.TypeInference, - Name = matrixType.Name, - Qualifiers = matrixType.Qualifiers, - IsBuiltIn = matrixType.IsBuiltIn, - RowCount = matrixType.RowCount, - ColumnCount = matrixType.ColumnCount, - Type = matrixType.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.MemberReferenceExpression memberReferenceExpression) - { - memberReferenceExpression = (Stride.Core.Shaders.Ast.MemberReferenceExpression)base.Visit(memberReferenceExpression); - return new Stride.Core.Shaders.Ast.MemberReferenceExpression - { - Span = memberReferenceExpression.Span, - Tags = memberReferenceExpression.Tags, - TypeInference = memberReferenceExpression.TypeInference, - Member = memberReferenceExpression.Member, - Target = memberReferenceExpression.Target, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodDeclaration methodDeclaration) - { - methodDeclaration = (Stride.Core.Shaders.Ast.MethodDeclaration)base.Visit(methodDeclaration); - return new Stride.Core.Shaders.Ast.MethodDeclaration - { - Span = methodDeclaration.Span, - Tags = methodDeclaration.Tags, - Attributes = methodDeclaration.Attributes, - Name = methodDeclaration.Name, - ParameterConstraints = methodDeclaration.ParameterConstraints, - Parameters = methodDeclaration.Parameters, - Qualifiers = methodDeclaration.Qualifiers, - ReturnType = methodDeclaration.ReturnType, - IsBuiltin = methodDeclaration.IsBuiltin, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodDefinition methodDefinition) - { - methodDefinition = (Stride.Core.Shaders.Ast.MethodDefinition)base.Visit(methodDefinition); - return new Stride.Core.Shaders.Ast.MethodDefinition - { - Span = methodDefinition.Span, - Tags = methodDefinition.Tags, - Attributes = methodDefinition.Attributes, - Name = methodDefinition.Name, - ParameterConstraints = methodDefinition.ParameterConstraints, - Parameters = methodDefinition.Parameters, - Qualifiers = methodDefinition.Qualifiers, - ReturnType = methodDefinition.ReturnType, - IsBuiltin = methodDefinition.IsBuiltin, - Body = methodDefinition.Body, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.MethodInvocationExpression methodInvocationExpression) - { - methodInvocationExpression = (Stride.Core.Shaders.Ast.MethodInvocationExpression)base.Visit(methodInvocationExpression); - return new Stride.Core.Shaders.Ast.MethodInvocationExpression - { - Span = methodInvocationExpression.Span, - Tags = methodInvocationExpression.Tags, - TypeInference = methodInvocationExpression.TypeInference, - Target = methodInvocationExpression.Target, - Arguments = methodInvocationExpression.Arguments, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ObjectType objectType) - { - objectType = (Stride.Core.Shaders.Ast.ObjectType)base.Visit(objectType); - return new Stride.Core.Shaders.Ast.ObjectType - { - Span = objectType.Span, - Tags = objectType.Tags, - Attributes = objectType.Attributes, - TypeInference = objectType.TypeInference, - Name = objectType.Name, - Qualifiers = objectType.Qualifiers, - IsBuiltIn = objectType.IsBuiltIn, - AlternativeNames = objectType.AlternativeNames, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Parameter parameter) - { - parameter = (Stride.Core.Shaders.Ast.Parameter)base.Visit(parameter); - return new Stride.Core.Shaders.Ast.Parameter - { - Span = parameter.Span, - Tags = parameter.Tags, - Attributes = parameter.Attributes, - Qualifiers = parameter.Qualifiers, - Type = parameter.Type, - InitialValue = parameter.InitialValue, - Name = parameter.Name, - SubVariables = parameter.SubVariables, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ParenthesizedExpression parenthesizedExpression) - { - parenthesizedExpression = (Stride.Core.Shaders.Ast.ParenthesizedExpression)base.Visit(parenthesizedExpression); - return new Stride.Core.Shaders.Ast.ParenthesizedExpression - { - Span = parenthesizedExpression.Span, - Tags = parenthesizedExpression.Tags, - TypeInference = parenthesizedExpression.TypeInference, - Content = parenthesizedExpression.Content, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Qualifier qualifier) - { - qualifier = (Stride.Core.Shaders.Ast.Qualifier)base.Visit(qualifier); - return new Stride.Core.Shaders.Ast.Qualifier - { - Span = qualifier.Span, - Tags = qualifier.Tags, - IsFlag = qualifier.IsFlag, - Key = qualifier.Key, - IsPost = qualifier.IsPost, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ReturnStatement returnStatement) - { - returnStatement = (Stride.Core.Shaders.Ast.ReturnStatement)base.Visit(returnStatement); - return new Stride.Core.Shaders.Ast.ReturnStatement - { - Span = returnStatement.Span, - Tags = returnStatement.Tags, - Attributes = returnStatement.Attributes, - Value = returnStatement.Value, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.ScalarType scalarType) - { - scalarType = (Stride.Core.Shaders.Ast.ScalarType)base.Visit(scalarType); - return new Stride.Core.Shaders.Ast.ScalarType - { - Span = scalarType.Span, - Tags = scalarType.Tags, - Attributes = scalarType.Attributes, - TypeInference = scalarType.TypeInference, - Name = scalarType.Name, - Qualifiers = scalarType.Qualifiers, - IsBuiltIn = scalarType.IsBuiltIn, - Type = scalarType.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Shader shader) - { - shader = (Stride.Core.Shaders.Ast.Shader)base.Visit(shader); - return new Stride.Core.Shaders.Ast.Shader - { - Span = shader.Span, - Tags = shader.Tags, - Declarations = shader.Declarations, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.StatementList statementList) - { - statementList = (Stride.Core.Shaders.Ast.StatementList)base.Visit(statementList); - return new Stride.Core.Shaders.Ast.StatementList - { - Span = statementList.Span, - Tags = statementList.Tags, - Attributes = statementList.Attributes, - Statements = statementList.Statements, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.StructType structType) - { - structType = (Stride.Core.Shaders.Ast.StructType)base.Visit(structType); - return new Stride.Core.Shaders.Ast.StructType - { - Span = structType.Span, - Tags = structType.Tags, - Attributes = structType.Attributes, - TypeInference = structType.TypeInference, - Name = structType.Name, - Qualifiers = structType.Qualifiers, - IsBuiltIn = structType.IsBuiltIn, - Fields = structType.Fields, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.SwitchCaseGroup switchCaseGroup) - { - switchCaseGroup = (Stride.Core.Shaders.Ast.SwitchCaseGroup)base.Visit(switchCaseGroup); - return new Stride.Core.Shaders.Ast.SwitchCaseGroup - { - Span = switchCaseGroup.Span, - Tags = switchCaseGroup.Tags, - Cases = switchCaseGroup.Cases, - Statements = switchCaseGroup.Statements, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.SwitchStatement switchStatement) - { - switchStatement = (Stride.Core.Shaders.Ast.SwitchStatement)base.Visit(switchStatement); - return new Stride.Core.Shaders.Ast.SwitchStatement - { - Span = switchStatement.Span, - Tags = switchStatement.Tags, - Attributes = switchStatement.Attributes, - Condition = switchStatement.Condition, - Groups = switchStatement.Groups, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.TypeName typeName) - { - typeName = (Stride.Core.Shaders.Ast.TypeName)base.Visit(typeName); - return new Stride.Core.Shaders.Ast.TypeName - { - Span = typeName.Span, - Tags = typeName.Tags, - Attributes = typeName.Attributes, - TypeInference = typeName.TypeInference, - Name = typeName.Name, - Qualifiers = typeName.Qualifiers, - IsBuiltIn = typeName.IsBuiltIn, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.TypeReferenceExpression typeReferenceExpression) - { - typeReferenceExpression = (Stride.Core.Shaders.Ast.TypeReferenceExpression)base.Visit(typeReferenceExpression); - return new Stride.Core.Shaders.Ast.TypeReferenceExpression - { - Span = typeReferenceExpression.Span, - Tags = typeReferenceExpression.Tags, - TypeInference = typeReferenceExpression.TypeInference, - Type = typeReferenceExpression.Type, - Declaration = typeReferenceExpression.Declaration, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.UnaryExpression unaryExpression) - { - unaryExpression = (Stride.Core.Shaders.Ast.UnaryExpression)base.Visit(unaryExpression); - return new Stride.Core.Shaders.Ast.UnaryExpression - { - Span = unaryExpression.Span, - Tags = unaryExpression.Tags, - TypeInference = unaryExpression.TypeInference, - Operator = unaryExpression.Operator, - Expression = unaryExpression.Expression, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.Variable variable) - { - variable = (Stride.Core.Shaders.Ast.Variable)base.Visit(variable); - return new Stride.Core.Shaders.Ast.Variable - { - Span = variable.Span, - Tags = variable.Tags, - Attributes = variable.Attributes, - Qualifiers = variable.Qualifiers, - Type = variable.Type, - InitialValue = variable.InitialValue, - Name = variable.Name, - SubVariables = variable.SubVariables, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.VariableReferenceExpression variableReferenceExpression) - { - variableReferenceExpression = (Stride.Core.Shaders.Ast.VariableReferenceExpression)base.Visit(variableReferenceExpression); - return new Stride.Core.Shaders.Ast.VariableReferenceExpression - { - Span = variableReferenceExpression.Span, - Tags = variableReferenceExpression.Tags, - TypeInference = variableReferenceExpression.TypeInference, - Name = variableReferenceExpression.Name, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.VectorType vectorType) - { - vectorType = (Stride.Core.Shaders.Ast.VectorType)base.Visit(vectorType); - return new Stride.Core.Shaders.Ast.VectorType - { - Span = vectorType.Span, - Tags = vectorType.Tags, - Attributes = vectorType.Attributes, - TypeInference = vectorType.TypeInference, - Name = vectorType.Name, - Qualifiers = vectorType.Qualifiers, - IsBuiltIn = vectorType.IsBuiltIn, - Dimension = vectorType.Dimension, - Type = vectorType.Type, - }; - } - public override Node Visit(Stride.Core.Shaders.Ast.WhileStatement whileStatement) - { - whileStatement = (Stride.Core.Shaders.Ast.WhileStatement)base.Visit(whileStatement); - return new Stride.Core.Shaders.Ast.WhileStatement - { - Span = whileStatement.Span, - Tags = whileStatement.Tags, - Attributes = whileStatement.Attributes, - Condition = whileStatement.Condition, - IsDoWhile = whileStatement.IsDoWhile, - Statement = whileStatement.Statement, - }; - } - } - - public partial class ShaderVisitor - { - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric classIdentifierGeneric) - { - DefaultVisit(classIdentifierGeneric); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.EnumType enumType) - { - DefaultVisit(enumType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ForEachStatement forEachStatement) - { - DefaultVisit(forEachStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ImportBlockStatement importBlockStatement) - { - DefaultVisit(importBlockStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.LinkType linkType) - { - DefaultVisit(linkType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.LiteralIdentifier literalIdentifier) - { - DefaultVisit(literalIdentifier); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.MemberName memberName) - { - DefaultVisit(memberName); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.MixinStatement mixinStatement) - { - DefaultVisit(mixinStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.NamespaceBlock namespaceBlock) - { - DefaultVisit(namespaceBlock); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ParametersBlock parametersBlock) - { - DefaultVisit(parametersBlock); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.SemanticType semanticType) - { - DefaultVisit(semanticType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.EffectBlock effectBlock) - { - DefaultVisit(effectBlock); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ShaderClassType shaderClassType) - { - DefaultVisit(shaderClassType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ShaderRootClassType shaderRootClassType) - { - DefaultVisit(shaderRootClassType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.ShaderTypeName shaderTypeName) - { - DefaultVisit(shaderTypeName); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.TypeIdentifier typeIdentifier) - { - DefaultVisit(typeIdentifier); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.UsingParametersStatement usingParametersStatement) - { - DefaultVisit(usingParametersStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.UsingStatement usingStatement) - { - DefaultVisit(usingStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.VarType varType) - { - DefaultVisit(varType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType strideConstantBufferType) - { - DefaultVisit(strideConstantBufferType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ArrayInitializerExpression arrayInitializerExpression) - { - DefaultVisit(arrayInitializerExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ArrayType arrayType) - { - DefaultVisit(arrayType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.AssignmentExpression assignmentExpression) - { - DefaultVisit(assignmentExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.BinaryExpression binaryExpression) - { - DefaultVisit(binaryExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.BlockStatement blockStatement) - { - DefaultVisit(blockStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.CaseStatement caseStatement) - { - DefaultVisit(caseStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.CompositeEnum compositeEnum) - { - DefaultVisit(compositeEnum); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ConditionalExpression conditionalExpression) - { - DefaultVisit(conditionalExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.EmptyStatement emptyStatement) - { - DefaultVisit(emptyStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.EmptyExpression emptyExpression) - { - DefaultVisit(emptyExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue layoutKeyValue) - { - DefaultVisit(layoutKeyValue); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Glsl.LayoutQualifier layoutQualifier) - { - DefaultVisit(layoutQualifier); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Glsl.InterfaceType interfaceType) - { - DefaultVisit(interfaceType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.ClassType classType) - { - DefaultVisit(classType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric identifierGeneric) - { - DefaultVisit(identifierGeneric); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierNs identifierNs) - { - DefaultVisit(identifierNs); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierDot identifierDot) - { - DefaultVisit(identifierDot); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.TextureType textureType) - { - DefaultVisit(textureType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.Annotations annotations) - { - DefaultVisit(annotations); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.AsmExpression asmExpression) - { - DefaultVisit(asmExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration attributeDeclaration) - { - DefaultVisit(attributeDeclaration); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.CastExpression castExpression) - { - DefaultVisit(castExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.CompileExpression compileExpression) - { - DefaultVisit(compileExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer constantBuffer) - { - DefaultVisit(constantBuffer); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType constantBufferType) - { - DefaultVisit(constantBufferType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.InterfaceType interfaceType) - { - DefaultVisit(interfaceType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.PackOffset packOffset) - { - DefaultVisit(packOffset); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.Pass pass) - { - DefaultVisit(pass); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.RegisterLocation registerLocation) - { - DefaultVisit(registerLocation); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.Semantic semantic) - { - DefaultVisit(semantic); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.StateExpression stateExpression) - { - DefaultVisit(stateExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.StateInitializer stateInitializer) - { - DefaultVisit(stateInitializer); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.Technique technique) - { - DefaultVisit(technique); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Hlsl.Typedef typedef) - { - DefaultVisit(typedef); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ExpressionList expressionList) - { - DefaultVisit(expressionList); - } - public virtual void Visit(Stride.Core.Shaders.Ast.GenericDeclaration genericDeclaration) - { - DefaultVisit(genericDeclaration); - } - public virtual void Visit(Stride.Core.Shaders.Ast.GenericParameterType genericParameterType) - { - DefaultVisit(genericParameterType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.DeclarationStatement declarationStatement) - { - DefaultVisit(declarationStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ExpressionStatement expressionStatement) - { - DefaultVisit(expressionStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ForStatement forStatement) - { - DefaultVisit(forStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.GenericType genericType) - { - DefaultVisit(genericType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Identifier identifier) - { - DefaultVisit(identifier); - } - public virtual void Visit(Stride.Core.Shaders.Ast.IfStatement ifStatement) - { - DefaultVisit(ifStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.IndexerExpression indexerExpression) - { - DefaultVisit(indexerExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.KeywordExpression keywordExpression) - { - DefaultVisit(keywordExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Literal literal) - { - DefaultVisit(literal); - } - public virtual void Visit(Stride.Core.Shaders.Ast.LiteralExpression literalExpression) - { - DefaultVisit(literalExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.MatrixType matrixType) - { - DefaultVisit(matrixType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.MemberReferenceExpression memberReferenceExpression) - { - DefaultVisit(memberReferenceExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.MethodDeclaration methodDeclaration) - { - DefaultVisit(methodDeclaration); - } - public virtual void Visit(Stride.Core.Shaders.Ast.MethodDefinition methodDefinition) - { - DefaultVisit(methodDefinition); - } - public virtual void Visit(Stride.Core.Shaders.Ast.MethodInvocationExpression methodInvocationExpression) - { - DefaultVisit(methodInvocationExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ObjectType objectType) - { - DefaultVisit(objectType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Parameter parameter) - { - DefaultVisit(parameter); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ParenthesizedExpression parenthesizedExpression) - { - DefaultVisit(parenthesizedExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Qualifier qualifier) - { - DefaultVisit(qualifier); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ReturnStatement returnStatement) - { - DefaultVisit(returnStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.ScalarType scalarType) - { - DefaultVisit(scalarType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Shader shader) - { - DefaultVisit(shader); - } - public virtual void Visit(Stride.Core.Shaders.Ast.StatementList statementList) - { - DefaultVisit(statementList); - } - public virtual void Visit(Stride.Core.Shaders.Ast.StructType structType) - { - DefaultVisit(structType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.SwitchCaseGroup switchCaseGroup) - { - DefaultVisit(switchCaseGroup); - } - public virtual void Visit(Stride.Core.Shaders.Ast.SwitchStatement switchStatement) - { - DefaultVisit(switchStatement); - } - public virtual void Visit(Stride.Core.Shaders.Ast.TypeName typeName) - { - DefaultVisit(typeName); - } - public virtual void Visit(Stride.Core.Shaders.Ast.TypeReferenceExpression typeReferenceExpression) - { - DefaultVisit(typeReferenceExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.UnaryExpression unaryExpression) - { - DefaultVisit(unaryExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.Variable variable) - { - DefaultVisit(variable); - } - public virtual void Visit(Stride.Core.Shaders.Ast.VariableReferenceExpression variableReferenceExpression) - { - DefaultVisit(variableReferenceExpression); - } - public virtual void Visit(Stride.Core.Shaders.Ast.VectorType vectorType) - { - DefaultVisit(vectorType); - } - public virtual void Visit(Stride.Core.Shaders.Ast.WhileStatement whileStatement) - { - DefaultVisit(whileStatement); - } - } - - public partial class ShaderWalker - { - public override void Visit(Stride.Core.Shaders.Ast.Stride.ClassIdentifierGeneric classIdentifierGeneric) - { - VisitList(classIdentifierGeneric.Indices); - VisitList(classIdentifierGeneric.Generics); - base.Visit(classIdentifierGeneric); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.EnumType enumType) - { - VisitList(enumType.Attributes); - VisitDynamic(enumType.Name); - VisitDynamic(enumType.Qualifiers); - VisitList(enumType.Values); - base.Visit(enumType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ForEachStatement forEachStatement) - { - VisitList(forEachStatement.Attributes); - VisitDynamic(forEachStatement.Collection); - VisitDynamic(forEachStatement.Variable); - VisitDynamic(forEachStatement.Body); - base.Visit(forEachStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ImportBlockStatement importBlockStatement) - { - VisitList(importBlockStatement.Attributes); - VisitDynamic(importBlockStatement.Statements); - base.Visit(importBlockStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.LinkType linkType) - { - VisitList(linkType.Attributes); - VisitDynamic(linkType.Name); - VisitDynamic(linkType.Qualifiers); - base.Visit(linkType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.LiteralIdentifier literalIdentifier) - { - VisitList(literalIdentifier.Indices); - VisitDynamic(literalIdentifier.Value); - base.Visit(literalIdentifier); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.MemberName memberName) - { - VisitList(memberName.Attributes); - VisitDynamic(memberName.Name); - VisitDynamic(memberName.Qualifiers); - base.Visit(memberName); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.MixinStatement mixinStatement) - { - VisitList(mixinStatement.Attributes); - VisitDynamic(mixinStatement.Value); - base.Visit(mixinStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.NamespaceBlock namespaceBlock) - { - VisitList(namespaceBlock.Attributes); - VisitDynamic(namespaceBlock.Name); - VisitDynamic(namespaceBlock.Qualifiers); - VisitList(namespaceBlock.Body); - base.Visit(namespaceBlock); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ParametersBlock parametersBlock) - { - VisitDynamic(parametersBlock.Name); - VisitDynamic(parametersBlock.Body); - base.Visit(parametersBlock); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.SemanticType semanticType) - { - VisitList(semanticType.Attributes); - VisitDynamic(semanticType.Name); - VisitDynamic(semanticType.Qualifiers); - base.Visit(semanticType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.EffectBlock effectBlock) - { - VisitList(effectBlock.Attributes); - VisitDynamic(effectBlock.Name); - VisitDynamic(effectBlock.Qualifiers); - VisitDynamic(effectBlock.Body); - base.Visit(effectBlock); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ShaderClassType shaderClassType) - { - VisitList(shaderClassType.Attributes); - VisitDynamic(shaderClassType.Name); - VisitDynamic(shaderClassType.Qualifiers); - VisitList(shaderClassType.BaseClasses); - VisitList(shaderClassType.GenericParameters); - VisitList(shaderClassType.GenericArguments); - VisitList(shaderClassType.Members); - VisitList(shaderClassType.ShaderGenerics); - base.Visit(shaderClassType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ShaderRootClassType shaderRootClassType) - { - VisitList(shaderRootClassType.Attributes); - VisitDynamic(shaderRootClassType.Name); - VisitDynamic(shaderRootClassType.Qualifiers); - VisitList(shaderRootClassType.BaseClasses); - VisitList(shaderRootClassType.GenericParameters); - VisitList(shaderRootClassType.GenericArguments); - VisitList(shaderRootClassType.Members); - VisitList(shaderRootClassType.ShaderGenerics); - base.Visit(shaderRootClassType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.ShaderTypeName shaderTypeName) - { - VisitList(shaderTypeName.Attributes); - VisitDynamic(shaderTypeName.Name); - VisitDynamic(shaderTypeName.Qualifiers); - base.Visit(shaderTypeName); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.TypeIdentifier typeIdentifier) - { - VisitList(typeIdentifier.Indices); - VisitDynamic(typeIdentifier.Type); - base.Visit(typeIdentifier); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.UsingParametersStatement usingParametersStatement) - { - VisitList(usingParametersStatement.Attributes); - VisitDynamic(usingParametersStatement.Name); - VisitDynamic(usingParametersStatement.Body); - base.Visit(usingParametersStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.UsingStatement usingStatement) - { - VisitList(usingStatement.Attributes); - VisitDynamic(usingStatement.Name); - base.Visit(usingStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.VarType varType) - { - VisitList(varType.Attributes); - VisitDynamic(varType.Name); - VisitDynamic(varType.Qualifiers); - base.Visit(varType); - } - public override void Visit(Stride.Core.Shaders.Ast.Stride.StrideConstantBufferType strideConstantBufferType) - { - base.Visit(strideConstantBufferType); - } - public override void Visit(Stride.Core.Shaders.Ast.ArrayInitializerExpression arrayInitializerExpression) - { - VisitList(arrayInitializerExpression.Items); - base.Visit(arrayInitializerExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.ArrayType arrayType) - { - VisitList(arrayType.Attributes); - VisitDynamic(arrayType.Name); - VisitDynamic(arrayType.Qualifiers); - VisitList(arrayType.Dimensions); - VisitDynamic(arrayType.Type); - base.Visit(arrayType); - } - public override void Visit(Stride.Core.Shaders.Ast.AssignmentExpression assignmentExpression) - { - VisitDynamic(assignmentExpression.Target); - VisitDynamic(assignmentExpression.Value); - base.Visit(assignmentExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.BinaryExpression binaryExpression) - { - VisitDynamic(binaryExpression.Left); - VisitDynamic(binaryExpression.Right); - base.Visit(binaryExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.BlockStatement blockStatement) - { - VisitList(blockStatement.Attributes); - VisitDynamic(blockStatement.Statements); - base.Visit(blockStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.CaseStatement caseStatement) - { - VisitList(caseStatement.Attributes); - VisitDynamic(caseStatement.Case); - base.Visit(caseStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.CompositeEnum compositeEnum) - { - base.Visit(compositeEnum); - } - public override void Visit(Stride.Core.Shaders.Ast.ConditionalExpression conditionalExpression) - { - VisitDynamic(conditionalExpression.Condition); - VisitDynamic(conditionalExpression.Left); - VisitDynamic(conditionalExpression.Right); - base.Visit(conditionalExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.EmptyStatement emptyStatement) - { - VisitList(emptyStatement.Attributes); - base.Visit(emptyStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.EmptyExpression emptyExpression) - { - base.Visit(emptyExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Glsl.LayoutKeyValue layoutKeyValue) - { - VisitDynamic(layoutKeyValue.Name); - VisitDynamic(layoutKeyValue.Value); - base.Visit(layoutKeyValue); - } - public override void Visit(Stride.Core.Shaders.Ast.Glsl.LayoutQualifier layoutQualifier) - { - VisitList(layoutQualifier.Layouts); - base.Visit(layoutQualifier); - } - public override void Visit(Stride.Core.Shaders.Ast.Glsl.InterfaceType interfaceType) - { - VisitList(interfaceType.Attributes); - VisitDynamic(interfaceType.Name); - VisitDynamic(interfaceType.Qualifiers); - VisitList(interfaceType.Fields); - base.Visit(interfaceType); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.ClassType classType) - { - VisitList(classType.Attributes); - VisitDynamic(classType.Name); - VisitDynamic(classType.Qualifiers); - VisitList(classType.BaseClasses); - VisitList(classType.GenericParameters); - VisitList(classType.GenericArguments); - VisitList(classType.Members); - base.Visit(classType); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierGeneric identifierGeneric) - { - VisitList(identifierGeneric.Indices); - VisitList(identifierGeneric.Identifiers); - base.Visit(identifierGeneric); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierNs identifierNs) - { - VisitList(identifierNs.Indices); - VisitList(identifierNs.Identifiers); - base.Visit(identifierNs); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.IdentifierDot identifierDot) - { - VisitList(identifierDot.Indices); - VisitList(identifierDot.Identifiers); - base.Visit(identifierDot); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.TextureType textureType) - { - VisitList(textureType.Attributes); - VisitDynamic(textureType.Name); - VisitDynamic(textureType.Qualifiers); - base.Visit(textureType); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.Annotations annotations) - { - VisitList(annotations.Variables); - base.Visit(annotations); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.AsmExpression asmExpression) - { - base.Visit(asmExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.AttributeDeclaration attributeDeclaration) - { - VisitDynamic(attributeDeclaration.Name); - VisitList(attributeDeclaration.Parameters); - base.Visit(attributeDeclaration); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.CastExpression castExpression) - { - VisitDynamic(castExpression.From); - VisitDynamic(castExpression.Target); - base.Visit(castExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.CompileExpression compileExpression) - { - VisitDynamic(compileExpression.Function); - VisitDynamic(compileExpression.Profile); - base.Visit(compileExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBuffer constantBuffer) - { - VisitList(constantBuffer.Attributes); - VisitDynamic(constantBuffer.Type); - VisitList(constantBuffer.Members); - VisitDynamic(constantBuffer.Name); - VisitDynamic(constantBuffer.Register); - VisitDynamic(constantBuffer.Qualifiers); - base.Visit(constantBuffer); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.ConstantBufferType constantBufferType) - { - base.Visit(constantBufferType); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.InterfaceType interfaceType) - { - VisitList(interfaceType.Attributes); - VisitDynamic(interfaceType.Name); - VisitDynamic(interfaceType.Qualifiers); - VisitList(interfaceType.GenericParameters); - VisitList(interfaceType.GenericArguments); - VisitList(interfaceType.Methods); - base.Visit(interfaceType); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.PackOffset packOffset) - { - VisitDynamic(packOffset.Value); - base.Visit(packOffset); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.Pass pass) - { - VisitList(pass.Attributes); - VisitList(pass.Items); - VisitDynamic(pass.Name); - base.Visit(pass); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.RegisterLocation registerLocation) - { - VisitDynamic(registerLocation.Profile); - VisitDynamic(registerLocation.Register); - base.Visit(registerLocation); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.Semantic semantic) - { - VisitDynamic(semantic.Name); - base.Visit(semantic); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.StateExpression stateExpression) - { - VisitDynamic(stateExpression.Initializer); - VisitDynamic(stateExpression.StateType); - base.Visit(stateExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.StateInitializer stateInitializer) - { - VisitList(stateInitializer.Items); - base.Visit(stateInitializer); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.Technique technique) - { - VisitDynamic(technique.Type); - VisitList(technique.Attributes); - VisitDynamic(technique.Name); - VisitList(technique.Passes); - base.Visit(technique); - } - public override void Visit(Stride.Core.Shaders.Ast.Hlsl.Typedef typedef) - { - VisitList(typedef.Attributes); - VisitDynamic(typedef.Name); - VisitDynamic(typedef.Qualifiers); - VisitList(typedef.SubDeclarators); - VisitDynamic(typedef.Type); - base.Visit(typedef); - } - public override void Visit(Stride.Core.Shaders.Ast.ExpressionList expressionList) - { - VisitList(expressionList.Expressions); - base.Visit(expressionList); - } - public override void Visit(Stride.Core.Shaders.Ast.GenericDeclaration genericDeclaration) - { - VisitDynamic(genericDeclaration.Name); - base.Visit(genericDeclaration); - } - public override void Visit(Stride.Core.Shaders.Ast.GenericParameterType genericParameterType) - { - VisitList(genericParameterType.Attributes); - VisitDynamic(genericParameterType.Name); - VisitDynamic(genericParameterType.Qualifiers); - base.Visit(genericParameterType); - } - public override void Visit(Stride.Core.Shaders.Ast.DeclarationStatement declarationStatement) - { - VisitList(declarationStatement.Attributes); - VisitDynamic(declarationStatement.Content); - base.Visit(declarationStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.ExpressionStatement expressionStatement) - { - VisitList(expressionStatement.Attributes); - VisitDynamic(expressionStatement.Expression); - base.Visit(expressionStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.ForStatement forStatement) - { - VisitList(forStatement.Attributes); - VisitDynamic(forStatement.Start); - VisitDynamic(forStatement.Condition); - VisitDynamic(forStatement.Next); - VisitDynamic(forStatement.Body); - base.Visit(forStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.GenericType genericType) - { - VisitList(genericType.Attributes); - VisitDynamic(genericType.Name); - VisitDynamic(genericType.Qualifiers); - VisitList(genericType.Parameters); - base.Visit(genericType); - } - public override void Visit(Stride.Core.Shaders.Ast.Identifier identifier) - { - VisitList(identifier.Indices); - base.Visit(identifier); - } - public override void Visit(Stride.Core.Shaders.Ast.IfStatement ifStatement) - { - VisitList(ifStatement.Attributes); - VisitDynamic(ifStatement.Condition); - VisitDynamic(ifStatement.Else); - VisitDynamic(ifStatement.Then); - base.Visit(ifStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.IndexerExpression indexerExpression) - { - VisitDynamic(indexerExpression.Index); - VisitDynamic(indexerExpression.Target); - base.Visit(indexerExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.KeywordExpression keywordExpression) - { - VisitDynamic(keywordExpression.Name); - base.Visit(keywordExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Literal literal) - { - VisitList(literal.SubLiterals); - base.Visit(literal); - } - public override void Visit(Stride.Core.Shaders.Ast.LiteralExpression literalExpression) - { - VisitDynamic(literalExpression.Literal); - base.Visit(literalExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.MatrixType matrixType) - { - VisitList(matrixType.Attributes); - VisitDynamic(matrixType.Name); - VisitDynamic(matrixType.Qualifiers); - VisitDynamic(matrixType.Type); - base.Visit(matrixType); - } - public override void Visit(Stride.Core.Shaders.Ast.MemberReferenceExpression memberReferenceExpression) - { - VisitDynamic(memberReferenceExpression.Member); - VisitDynamic(memberReferenceExpression.Target); - base.Visit(memberReferenceExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.MethodDeclaration methodDeclaration) - { - VisitList(methodDeclaration.Attributes); - VisitDynamic(methodDeclaration.Name); - VisitList(methodDeclaration.Parameters); - VisitDynamic(methodDeclaration.Qualifiers); - VisitDynamic(methodDeclaration.ReturnType); - base.Visit(methodDeclaration); - } - public override void Visit(Stride.Core.Shaders.Ast.MethodDefinition methodDefinition) - { - VisitList(methodDefinition.Attributes); - VisitDynamic(methodDefinition.Name); - VisitList(methodDefinition.Parameters); - VisitDynamic(methodDefinition.Qualifiers); - VisitDynamic(methodDefinition.ReturnType); - VisitDynamic(methodDefinition.Body); - base.Visit(methodDefinition); - } - public override void Visit(Stride.Core.Shaders.Ast.MethodInvocationExpression methodInvocationExpression) - { - VisitDynamic(methodInvocationExpression.Target); - VisitList(methodInvocationExpression.Arguments); - base.Visit(methodInvocationExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.ObjectType objectType) - { - VisitList(objectType.Attributes); - VisitDynamic(objectType.Name); - VisitDynamic(objectType.Qualifiers); - base.Visit(objectType); - } - public override void Visit(Stride.Core.Shaders.Ast.Parameter parameter) - { - VisitList(parameter.Attributes); - VisitDynamic(parameter.Qualifiers); - VisitDynamic(parameter.Type); - VisitDynamic(parameter.InitialValue); - VisitDynamic(parameter.Name); - VisitList(parameter.SubVariables); - base.Visit(parameter); - } - public override void Visit(Stride.Core.Shaders.Ast.ParenthesizedExpression parenthesizedExpression) - { - VisitDynamic(parenthesizedExpression.Content); - base.Visit(parenthesizedExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Qualifier qualifier) - { - base.Visit(qualifier); - } - public override void Visit(Stride.Core.Shaders.Ast.ReturnStatement returnStatement) - { - VisitList(returnStatement.Attributes); - VisitDynamic(returnStatement.Value); - base.Visit(returnStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.ScalarType scalarType) - { - VisitList(scalarType.Attributes); - VisitDynamic(scalarType.Name); - VisitDynamic(scalarType.Qualifiers); - base.Visit(scalarType); - } - public override void Visit(Stride.Core.Shaders.Ast.Shader shader) - { - VisitList(shader.Declarations); - base.Visit(shader); - } - public override void Visit(Stride.Core.Shaders.Ast.StatementList statementList) - { - VisitList(statementList.Attributes); - VisitList(statementList.Statements); - base.Visit(statementList); - } - public override void Visit(Stride.Core.Shaders.Ast.StructType structType) - { - VisitList(structType.Attributes); - VisitDynamic(structType.Name); - VisitDynamic(structType.Qualifiers); - VisitList(structType.Fields); - base.Visit(structType); - } - public override void Visit(Stride.Core.Shaders.Ast.SwitchCaseGroup switchCaseGroup) - { - VisitList(switchCaseGroup.Cases); - VisitDynamic(switchCaseGroup.Statements); - base.Visit(switchCaseGroup); - } - public override void Visit(Stride.Core.Shaders.Ast.SwitchStatement switchStatement) - { - VisitList(switchStatement.Attributes); - VisitDynamic(switchStatement.Condition); - VisitList(switchStatement.Groups); - base.Visit(switchStatement); - } - public override void Visit(Stride.Core.Shaders.Ast.TypeName typeName) - { - VisitList(typeName.Attributes); - VisitDynamic(typeName.Name); - VisitDynamic(typeName.Qualifiers); - base.Visit(typeName); - } - public override void Visit(Stride.Core.Shaders.Ast.TypeReferenceExpression typeReferenceExpression) - { - VisitDynamic(typeReferenceExpression.Type); - base.Visit(typeReferenceExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.UnaryExpression unaryExpression) - { - VisitDynamic(unaryExpression.Expression); - base.Visit(unaryExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.Variable variable) - { - VisitList(variable.Attributes); - VisitDynamic(variable.Qualifiers); - VisitDynamic(variable.Type); - VisitDynamic(variable.InitialValue); - VisitDynamic(variable.Name); - VisitList(variable.SubVariables); - base.Visit(variable); - } - public override void Visit(Stride.Core.Shaders.Ast.VariableReferenceExpression variableReferenceExpression) - { - VisitDynamic(variableReferenceExpression.Name); - base.Visit(variableReferenceExpression); - } - public override void Visit(Stride.Core.Shaders.Ast.VectorType vectorType) - { - VisitList(vectorType.Attributes); - VisitDynamic(vectorType.Name); - VisitDynamic(vectorType.Qualifiers); - VisitDynamic(vectorType.Type); - base.Visit(vectorType); - } - public override void Visit(Stride.Core.Shaders.Ast.WhileStatement whileStatement) - { - VisitList(whileStatement.Attributes); - VisitDynamic(whileStatement.Condition); - VisitDynamic(whileStatement.Statement); - base.Visit(whileStatement); - } - } -} - -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ClassIdentifierGeneric - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class EnumType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ForEachStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ImportBlockStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class LinkType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class LiteralIdentifier - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class MemberName - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class MixinStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class NamespaceBlock - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ParametersBlock - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class SemanticType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class EffectBlock - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ShaderClassType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ShaderRootClassType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class ShaderTypeName - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class TypeIdentifier - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class UsingParametersStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class UsingStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class VarType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Stride -{ - public partial class StrideConstantBufferType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ArrayInitializerExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ArrayType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class AssignmentExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class BinaryExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class BlockStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class CaseStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class CompositeEnum - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ConditionalExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class EmptyStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class EmptyExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Glsl -{ - public partial class LayoutKeyValue - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Glsl -{ - public partial class LayoutQualifier - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Glsl -{ - public partial class InterfaceType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class ClassType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class IdentifierGeneric - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class IdentifierNs - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class IdentifierDot - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class TextureType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class Annotations - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class AsmExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class AttributeDeclaration - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class CastExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class CompileExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class ConstantBuffer - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class ConstantBufferType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class InterfaceType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class PackOffset - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class Pass - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class RegisterLocation - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class Semantic - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class StateExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class StateInitializer - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class Technique - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast.Hlsl -{ - public partial class Typedef - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ExpressionList - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class GenericDeclaration - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class GenericParameterType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class DeclarationStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ExpressionStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ForStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class GenericType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Identifier - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class IfStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class IndexerExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class KeywordExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Literal - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class LiteralExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class MatrixType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class MemberReferenceExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class MethodDeclaration - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class MethodDefinition - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class MethodInvocationExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ObjectType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Parameter - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ParenthesizedExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Qualifier - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ReturnStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class ScalarType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Shader - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class StatementList - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class StructType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class SwitchCaseGroup - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class SwitchStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class TypeName - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class TypeReferenceExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class UnaryExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class Variable - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class VariableReferenceExpression - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class VectorType - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -namespace Stride.Core.Shaders.Ast -{ - public partial class WhileStatement - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} - diff --git a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.tt b/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.tt deleted file mode 100644 index 5f64596b0c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Visitor/VisitorGenerated.tt +++ /dev/null @@ -1,298 +0,0 @@ -<#@ template debug="true" hostspecific="true" language="C#" #> -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Runtime" #> -<#@ assembly name="System.Threading.Tasks" #> -<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #> -<#@ assembly name="$(TargetDir)Microsoft.CodeAnalysis.dll" #> -<#@ assembly name="$(TargetDir)Microsoft.CodeAnalysis.CSharp.dll" #> -<#@ assembly name="$(TargetDir)Microsoft.CodeAnalysis.Workspaces.dll" #> -<#@ assembly name="$(TargetDir)Microsoft.CodeAnalysis.Workspaces.Desktop.dll" #> -<#@ assembly name="$(TargetDir)System.Collections.Immutable.dll" #> - -<#@ import namespace="System.IO" #> -<#@ import namespace="System.Linq" #> -<#@ import namespace="System.Text" #> -<#@ import namespace="System.Collections.Generic" #> -<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #> -<#@ import namespace="Microsoft.CodeAnalysis" #> -<#@ import namespace="Microsoft.CodeAnalysis.CSharp" #> -<#@ import namespace="Microsoft.CodeAnalysis.CSharp.Syntax" #> -<#@ import namespace="Microsoft.CodeAnalysis.MSBuild" #> - -<#@ output extension=".cs" #> - -<# - var path = Path.GetDirectoryName(Host.TemplateFile); - - var msWorkspace = MSBuildWorkspace.Create(); - var project = msWorkspace.OpenProjectAsync(path + "\\..\\Stride.Core.Shaders.csproj").Result; - var compilation = project.GetCompilationAsync().Result; - - var classVisitor = new NodeClassVisitor(); - classVisitor.Visit(compilation.GlobalNamespace); - - var visitorTypes = classVisitor.Classes; // list of classes in your solution - - var typeAndGenericFormat = new SymbolDisplayFormat(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameOnly, SymbolDisplayGenericsOptions.IncludeTypeParameters); -#> - -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Visitor -{ - public partial class ShaderVisitor - { -<# foreach (var type in visitorTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - #> - public virtual TResult Visit<#=genericParameters#>(<#=typeName#> <#=variableName#>) - { - return DefaultVisit(<#=variableName#>); - } -<# } #> - } - - public partial class ShaderRewriter - { -<# foreach (var type in visitorTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - #> - public override Node Visit<#=genericParameters#>(<#=typeName#> <#=variableName#>) - { -<# // Process public fields and properties (with getter+setter) - var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); - foreach (var member in GetNodeMembers(type)) { - var memberType = GetSymbolType(member); - var memberTypeName = memberType.ToDisplayString(); - var memberVariableName = member.Name.First().ToString().ToLower() + member.Name.Substring(1) + "Temp"; - var isNodeList = memberType.AllInterfaces.Any(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && InheritsFromNode(x.TypeArguments[0])); - var isNode = InheritsFromNode(memberType); - if (isNode) { #> - var <#=memberVariableName#> = (<#=memberTypeName#>)VisitDynamic(<#=variableName#>.<#=member.Name#>); - if (!ReferenceEquals(<#=memberVariableName#>, <#=variableName#>.<#=member.Name#>)) - <#=variableName#>.<#=member.Name#> = <#=memberVariableName#>; -<# } else if (isNodeList) { #> - VisitList(<#=variableName#>.<#=member.Name#>); -<# } - } #> - return base.Visit<#=genericParameters#>(<#=variableName#>); - } -<# } #> - } - - public partial class ShaderCloner - { -<# foreach (var type in visitorTypes.Where(x => !x.IsAbstract)) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - #> - public override Node Visit<#=genericParameters#>(<#=typeName#> <#=variableName#>) - { - <#=variableName#> = (<#=typeName#>)base.Visit<#=genericParameters#>(<#=variableName#>); - return new <#=typeName#> - { -<# foreach (var member in GetNodeMembers(type)) { #> - <#=member.Name#> = <#=variableName#>.<#=member.Name#>, -<# } #> - }; - } -<# } #> - } - - public partial class ShaderVisitor - { -<# foreach (var type in visitorTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - #> - public virtual void Visit<#=genericParameters#>(<#=typeName#> <#=variableName#>) - { - DefaultVisit(<#=variableName#>); - } -<# } #> - } - - public partial class ShaderWalker - { -<# foreach (var type in visitorTypes) - { - var typeName = type.ToDisplayString(); - var variableName = type.Name.First().ToString().ToLower() + type.Name.Substring(1); - var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - #> - public override void Visit<#=genericParameters#>(<#=typeName#> <#=variableName#>) - { -<# // Process public fields and properties (with getter+setter) - var ilistName = typeof(IList<>).FullName.Replace("`1", "<>"); - foreach (var member in GetNodeMembers(type)) { - var memberType = GetSymbolType(member); - var memberTypeName = memberType.ToDisplayString(); - var isNodeList = memberType.AllInterfaces.Any(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && InheritsFromNode(x.TypeArguments[0])); - var isNode = InheritsFromNode(memberType); - if (isNode) { #> - VisitDynamic(<#=variableName#>.<#=member.Name#>); -<# } else if (isNodeList) { #> - VisitList(<#=variableName#>.<#=member.Name#>); -<# } - } #> - base.Visit<#=genericParameters#>(<#=variableName#>); - } -<# } #> - } -} - -<# -foreach (var type in visitorTypes) { #> -namespace <#=type.ContainingNamespace.ToDisplayString()#> -{ - public partial class <#=type.ToDisplayString(typeAndGenericFormat)#> - { - public override void Accept(ShaderVisitor visitor) - { - visitor.Visit(this); - } - public override TResult Accept(ShaderVisitor visitor) - { - return visitor.Visit(this); - } - } -} -<# } #> - -<#+ - -class NodeClassVisitor : SymbolVisitor -{ - public List Classes = new List(); - - public override void VisitNamedType(INamedTypeSymbol symbol) - { - if (!InheritsFromNode(symbol.BaseType) || symbol.IsAbstract) - return; - - Classes.Add(symbol); // save your visited classes - } - - public override void VisitNamespace(INamespaceSymbol symbol) - { - foreach(var childSymbol in symbol.GetMembers()) - { - //We must implement the visitor pattern ourselves and - //accept the child symbols in order to visit their children - childSymbol.Accept(this); - } - } -} - -private static bool InheritsFromNode(ITypeSymbol type) -{ - return GetBaseTypesAndThis(type).Any(t => t.ToDisplayString() == "Stride.Core.Shaders.Ast.Node"); -} - -private static IEnumerable GetBaseTypesAndThis(ITypeSymbol type) -{ - var current = type; - while (current != null) - { - yield return current; - current = current.BaseType; - } -} - -private static bool CanVisitMember(ISymbol symbol) -{ - if (symbol.DeclaredAccessibility != Accessibility.Public || symbol.IsStatic) - return false; - - if (symbol.GetAttributes().Any(x => x.AttributeClass.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) - return false; - - if (symbol.Kind == SymbolKind.Field) - { - var field = (IFieldSymbol)symbol; - if (field.IsReadOnly) - return false; - - return true; - } - - if (symbol.Kind == SymbolKind.Property) - { - var property = (IPropertySymbol)symbol; - if (property.IsReadOnly || property.IsWriteOnly || property.IsIndexer) - return false; - - if (property.GetMethod.DeclaredAccessibility != Accessibility.Public - || property.SetMethod.DeclaredAccessibility != Accessibility.Public) - return false; - - return true; - } - - return false; -} - -private static IEnumerable GetNodeTypes(INamedTypeSymbol symbol) -{ - while (symbol != null && InheritsFromNode(symbol)) - { - yield return symbol; - symbol = symbol.BaseType; - } -} - -private static IEnumerable GetNodeMembers(INamedTypeSymbol nodeType) -{ - foreach (var currentNodeType in GetNodeTypes(nodeType).Reverse()) - { - foreach (var member in currentNodeType.GetMembers().Where(CanVisitMember)) - yield return member; - } -} - -private static ITypeSymbol GetSymbolType(ISymbol symbol) -{ - var localSymbol = symbol as ILocalSymbol; - if (localSymbol != null) - { - return localSymbol.Type; - } - - var fieldSymbol = symbol as IFieldSymbol; - if (fieldSymbol != null) - { - return fieldSymbol.Type; - } - - var propertySymbol = symbol as IPropertySymbol; - if (propertySymbol != null) - { - return propertySymbol.Type; - } - - var parameterSymbol = symbol as IParameterSymbol; - if (parameterSymbol != null) - { - return parameterSymbol.Type; - } - - var aliasSymbol = symbol as IAliasSymbol; - if (aliasSymbol != null) - { - return aliasSymbol.Target as ITypeSymbol; - } - - return symbol as ITypeSymbol; -} -#> diff --git a/sources/shaders/Stride.Core.Shaders/Writer/Hlsl/HlslWriter.cs b/sources/shaders/Stride.Core.Shaders/Writer/Hlsl/HlslWriter.cs deleted file mode 100644 index c0d29b94c1..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Writer/Hlsl/HlslWriter.cs +++ /dev/null @@ -1,421 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Core.Shaders.Writer.Hlsl -{ - /// - /// A writer for a shader. - /// - public class HlslWriter : ShaderWriter - { - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// - /// if set to true [use node stack]. - /// - public HlslWriter(bool useNodeStack = false) : base(useNodeStack) - { - } - - #endregion - - #region Public Methods - - /// - /// Visits the specified Annotations. - /// - /// The Annotations. - public override void Visit(Ast.Hlsl.Annotations annotations) - { - if (annotations.Variables.Count == 0) return; - - Write("<").WriteSpace(); - - foreach (var variable in annotations.Variables) - { - VisitDynamic(variable); - } - - WriteSpace().Write(">"); - } - - /// - /// Visits the specified class type. - /// - /// Type of the class. - public override void Visit(ClassType classType) - { - Write(classType.Attributes, true); - - Write("class").Write(" ").Write(classType.Name); - - if (classType.GenericParameters.Count > 0) - { - Write("<"); - for (int i = 0; i < classType.GenericParameters.Count; i++) - { - var genericArgument = classType.GenericParameters[i]; - if (i > 0) Write(", "); - Write(genericArgument.Name); - } - Write(">"); - } - - if (classType.BaseClasses.Count > 0) - { - WriteSpace().Write(":").WriteSpace(); - for (int i = 0; i < classType.BaseClasses.Count; i++) - { - var baseClass = classType.BaseClasses[i]; - if (i > 0) - { - Write(",").WriteSpace(); - } - - Write(baseClass.Name); - } - - WriteSpace(); - } - else - { - WriteSpace(); - } - - OpenBrace(); - - VisitList(classType.Members); - - CloseBrace(false).Write(";").WriteLine(); - } - - /// - /// Visits the specified interface type. - /// - /// Type of the interface. - public override void Visit(InterfaceType interfaceType) - { - Write(interfaceType.Attributes, true); - Write("interface").Write(" ").Write(interfaceType.Name); - WriteSpace(); - OpenBrace(); - VisitList(interfaceType.Methods); - CloseBrace(false).Write(";").WriteLine(); - } - - /// - /// Visits the specified asm expression. - /// - /// The asm expression. - public override void Visit(AsmExpression asmExpression) - { - WriteLine(); - Write("asm"); - OpenBrace(); - Write(asmExpression.Text); - CloseBrace(); - } - - /// - /// Visits the specified constant buffer. - /// - /// The constant buffer. - public override void Visit(ConstantBuffer constantBuffer) - { - Write(constantBuffer.Attributes, true); - - Write(constantBuffer.Type.Key.ToString()); - - if (constantBuffer.Name != null) - { - Write(" ").Write(constantBuffer.Name); - } - - WriteSpace(); - VisitDynamic(constantBuffer.Register); - OpenBrace(); - VisitList(constantBuffer.Members); - CloseBrace(false).Write(";").WriteLine(); - } - - /// - /// Visits the specified typedef. - /// - /// The typedef. - public override void Visit(Typedef typedef) - { - Write("typedef").Write(" "); - Write(typedef.Qualifiers, true); - VisitDynamic(typedef.Type); - Write(" "); - - if (typedef.IsGroup) - { - for (int i = 0; i < typedef.SubDeclarators.Count; i++) - { - var declarator = typedef.SubDeclarators[i]; - if (i > 0) - { - Write(",").WriteSpace(); - } - - Write(declarator.Name); - } - } - else - { - Write(typedef.Name); - } - - Write(";"); - WriteLine(); - } - - /// - /// Visits the specified attribute declaration. - /// - /// The attribute declaration. - public override void Visit(AttributeDeclaration attributeDeclaration) - { - Write("[").Write(attributeDeclaration.Name); - if (attributeDeclaration.Parameters.Count > 0) - { - Write("("); - for (int i = 0; i < attributeDeclaration.Parameters.Count; i++) - { - var parameter = attributeDeclaration.Parameters[i]; - if (i > 0) - { - Write(",").WriteSpace(); - } - - VisitDynamic(parameter); - } - - Write(")"); - } - - WriteLine("]"); - } - - /// - /// Visits the specified cast expression. - /// - /// The cast expression. - public override void Visit(CastExpression castExpression) - { - Write("("); - VisitDynamic(castExpression.Target); - Write(")"); - VisitDynamic(castExpression.From); - } - - /// - /// Visits the specified composite identifier. - /// - /// The composite identifier. - public override void Visit(IdentifierDot compositeIdentifier) - { - Write((Identifier)compositeIdentifier); - } - - /// - /// Visits the specified composite identifier. - /// - /// The composite identifier. - public override void Visit(IdentifierNs compositeIdentifier) - { - Write((Identifier)compositeIdentifier); - } - - /// - /// Visits the specified composite identifier. - /// - /// The composite identifier. - public override void Visit(IdentifierGeneric compositeIdentifier) - { - Write((Identifier)compositeIdentifier); - } - - /// - /// Visits the specified state expression. - /// - /// The state expression. - public override void Visit(StateExpression stateExpression) - { - VisitDynamic(stateExpression.StateType); - WriteSpace(); - VisitDynamic(stateExpression.Initializer); - } - - /// - /// Visits the specified compile expression. - /// - /// The compile expression. - public override void Visit(CompileExpression compileExpression) - { - Write("compile").Write(" "); - Write(compileExpression.Profile); - Write(" "); - VisitDynamic(compileExpression.Function); - } - - /// - /// Visits the specified technique. - /// - /// The technique. - public override void Visit(Technique technique) - { - Write(technique.Attributes, true); - Write(technique.Type); - if (technique.Name != null) - { - Write(" ").Write(technique.Name); - } - - WriteSpace(); - Write(technique.Attributes, false); - OpenBrace(); - VisitList(technique.Passes); - CloseBrace(); - } - - /// - /// Visits the specified pass. - /// - /// The pass. - public override void Visit(Pass pass) - { - Write(pass.Attributes, true); - Write("pass"); - if (pass.Name != null) - { - Write(" ").Write(pass.Name); - } - - WriteSpace(); - Write(pass.Attributes, false); - OpenBrace(); - foreach (var expression in pass.Items) - { - VisitDynamic(expression); - WriteLine(";"); - } - - CloseBrace(); - } - - /// - public override void Visit(StateInitializer stateInitializer) - { - OpenBrace(); - for (int i = 0; i < stateInitializer.Items.Count; i++) - { - var item = stateInitializer.Items[i]; - if (item is StateInitializer && i > 0) - { - WriteLine(","); - } - - VisitDynamic(item); - - if (!(item is StateInitializer)) - { - WriteLine(";"); - } - } - - CloseBrace(false); - } - - /// - public override void WriteInitializer(Expression expression) - { - if (expression == null) return; - - if (!(expression is StateInitializer)) - WriteSpace().Write("="); - WriteSpace(); - VisitDynamic(expression); - } - - /// - public override void Visit(Semantic semantic) - { - Write(":").WriteSpace(); - Write(semantic.Name); - } - - /// - public override void Visit(PackOffset packOffset) - { - Write(":").WriteSpace(); - Write("packoffset("); - Write((Identifier)packOffset.Value); - Write(")"); - } - - /// - public override void Visit(RegisterLocation registerLocation) - { - Write(":").WriteSpace(); - Write("register("); - if (registerLocation.Profile != null) - { - Write(registerLocation.Profile); - Write(",").WriteSpace(); - } - - Write(registerLocation.Register); - Write(")"); - } - - #endregion - - /// - /// Writes the specified identifier. - /// - /// The identifier. - /// - /// This instance - /// - protected override ShaderWriter Write(Identifier identifier) - { - Write(identifier.Text); - - if (identifier.IsSpecialReference) - { - Write("<"); - } - - if (identifier is CompositeIdentifier) - { - var compositeIdentifier = (CompositeIdentifier)identifier; - for (int i = 0; i < compositeIdentifier.Identifiers.Count; i++) - { - var subIdentifier = compositeIdentifier.Identifiers[i]; - if (i > 0) Write(compositeIdentifier.Separator); - Write(subIdentifier); - } - } - - if (identifier.HasIndices) - { - WriteRankSpecifiers(identifier.Indices); - } - - if (identifier.IsSpecialReference) - { - Write(">"); - } - - return this; - } - } -} diff --git a/sources/shaders/Stride.Core.Shaders/Writer/ShaderWriter.cs b/sources/shaders/Stride.Core.Shaders/Writer/ShaderWriter.cs deleted file mode 100644 index 5f81c1707c..0000000000 --- a/sources/shaders/Stride.Core.Shaders/Writer/ShaderWriter.cs +++ /dev/null @@ -1,1046 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; -using Stride.Core.Shaders.Visitor; - -namespace Stride.Core.Shaders.Writer -{ - /// - /// A writer for a shader. - /// - public class ShaderWriter : ShaderWalker - { - private bool isInVariableGroup; - private bool isVisitingVariableInlines; - - private int lineCount; - - #region Constructors and Destructors - - /// - /// Initializes a new instance of the class. - /// - /// if set to true [build scope declaration]. - /// if set to true [use node stack]. - public ShaderWriter(bool buildScopeDeclaration = false, bool useNodeStack = false) - : base(buildScopeDeclaration, useNodeStack) - { - StringBuilder = new StringBuilder(); - EnableNewLine = true; - lineCount = 1; - SourceLocations = new List(); - } - - #endregion - - #region Public Properties - - public List SourceLocations { get; set; } - - /// - /// Gets the text. - /// - public string Text - { - get - { - return StringBuilder.ToString(); - } - } - - #endregion - - #region Properties - - public bool EnablePreprocessorLine { get; set; } - - /// - /// Gets or sets a value indicating whether [enable new line]. - /// - /// - /// true if [enable new line]; otherwise, false. - /// - protected bool EnableNewLine { get; set; } - - /// - /// Gets or sets the indent level. - /// - /// - /// The indent level. - /// - private int IndentLevel { get; set; } - - /// - /// Gets or sets a value indicating whether [new line]. - /// - /// - /// true if [new line]; otherwise, false. - /// - private bool NewLine { get; set; } - - /// - /// Gets or sets the string builder. - /// - /// - /// The string builder. - /// - private StringBuilder StringBuilder { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is visiting variable inlines. - /// - /// true if this instance is visiting variable inlines; otherwise, false. - public bool IsVisitingVariableInlines - { - get - { - return isVisitingVariableInlines; - } - set - { - isVisitingVariableInlines = value; - } - } - - protected Stack IsDeclaratingVariable = new Stack(); - - #endregion - - #region Public Methods - - /// - /// Indents this instance. - /// - /// - /// this instance - /// - public ShaderWriter Indent() - { - IndentLevel++; - return this; - } - - /// - /// Outdents this instance. - /// - /// - /// this instance - /// - public ShaderWriter Outdent() - { - IndentLevel--; - return this; - } - - /// - /// Visits the specified shader. - /// - /// The shader. - /// - public override void Visit(Shader shader) - { - base.Visit(shader); - } - - /// - public override void Visit(StructType structType) - { - WriteLinkLine(structType); - - // Pre Attributes - Write(structType.Attributes, true); - - WriteLinkLine(structType); - Write("struct"); - if (structType.Name != null) - { - Write(" "); - Write(structType.Name); - WriteSpace(); - } - - // Post Attributes - Write(structType.Attributes, false); - - OpenBrace(); - - foreach (var variableDeclaration in structType.Fields) - VisitDynamic(variableDeclaration); - - CloseBrace(false).Write(";").WriteLine(); - } - - /// - public override void Visit(WhileStatement whileStatement) - { - WriteLinkLine(whileStatement); - VisitStatement(whileStatement); - - if (whileStatement.IsDoWhile) - { - Write("do").WriteSpace(); - WriteStatementContent(whileStatement.Statement); - Write("while").WriteSpace().Write("("); - VisitDynamic(whileStatement.Condition); - Write(")"); - Write(";"); - WriteLine(); - } - else - { - Write("while").WriteSpace().Write("("); - VisitDynamic(whileStatement.Condition); - Write(")"); - WriteStatementContent(whileStatement.Statement); - } - - WriteLine(); - } - - /// - public override void Visit(ArrayInitializerExpression arrayInitializerExpression) - { - Write("{").WriteSpace(); - for (int i = 0; i < arrayInitializerExpression.Items.Count; i++) - { - var expression = arrayInitializerExpression.Items[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(expression); - } - - Write("}"); - } - - /// - public override void Visit(BlockStatement blockStatement) - { - OpenBrace(); - foreach (var statement in blockStatement.Statements) - { - VisitDynamic(statement); - } - - CloseBrace(); - } - - /// - public override void Visit(AssignmentExpression assignmentExpression) - { - VisitDynamic(assignmentExpression.Target); - WriteSpace().Write(assignmentExpression.Operator.ConvertToString()).WriteSpace(); - VisitDynamic(assignmentExpression.Value); - } - - /// - public override void Visit(BinaryExpression binaryExpression) - { - VisitDynamic(binaryExpression.Left); - WriteSpace().Write(binaryExpression.Operator.ConvertToString()).WriteSpace(); - VisitDynamic(binaryExpression.Right); - } - - /// - public override void Visit(CaseStatement statement) - { - WriteLinkLine(statement); - if (statement.Case == null) WriteLine("default:"); - else - { - Write("case").Write(" "); - VisitDynamic(statement.Case); - WriteLine(":"); - } - } - - /// - public override void Visit(ArrayType arrayType) - { - VisitDynamic(arrayType.Type); - WriteRankSpecifiers(arrayType.Dimensions); - } - - /// - public override void Visit(ExpressionStatement expressionStatement) - { - WriteLinkLine(expressionStatement); - VisitDynamic(expressionStatement.Expression); - WriteLine(";"); - } - - /// - public override void Visit(ForStatement forStatement) - { - WriteLine(); - WriteLinkLine(forStatement); - VisitStatement(forStatement); - Write("for").WriteSpace().Write("("); - EnableNewLine = false; - VisitDynamic(forStatement.Start); - WriteSpace(); - VisitDynamic(forStatement.Condition); - Write(";"); - WriteSpace(); - VisitDynamic(forStatement.Next); - EnableNewLine = true; - Write(")"); - WriteStatementContent(forStatement.Body); - } - - /// - public override void Visit(Identifier identifier) - { - Write(identifier); - } - - /// - public void VisitStatement(Statement statement) - { - Write(statement.Attributes, true); - } - - /// - public override void Visit(StatementList statementList) - { - foreach (var statement in statementList) - VisitDynamic(statement); - } - - /// - public override void Visit(IfStatement ifStatement) - { - WriteLinkLine(ifStatement); - VisitStatement(ifStatement); - - Write("if").WriteSpace().Write("("); - VisitDynamic(ifStatement.Condition); - Write(")"); - WriteStatementContent(ifStatement.Then); - if (ifStatement.Else != null) - { - WriteLinkLine(ifStatement.Else); - Write("else"); - var nestedIfStatement = ifStatement.Else as IfStatement; - if (nestedIfStatement != null && nestedIfStatement.Attributes.Count == 0) - { - Write(" "); - Visit(nestedIfStatement); - } - else WriteStatementContent(ifStatement.Else); - } - } - - /// - public override void Visit(IndexerExpression indexerExpression) - { - VisitDynamic(indexerExpression.Target); - Write("["); - VisitDynamic(indexerExpression.Index); - Write("]"); - } - - /// - public override void Visit(MemberReferenceExpression memberReferenceExpression) - { - VisitDynamic(memberReferenceExpression.Target); - Write("."); - VisitDynamic(memberReferenceExpression.Member); - } - - /// - public override void Visit(MethodInvocationExpression methodInvocationExpression) - { - VisitDynamic(methodInvocationExpression.Target); - Write("("); - for (int i = 0; i < methodInvocationExpression.Arguments.Count; i++) - { - var expression = methodInvocationExpression.Arguments[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(expression); - } - - Write(")"); - } - - /// - public override void Visit(Parameter parameter) - { - WriteVariable(parameter); - } - - /// - public override void Visit(ParenthesizedExpression parenthesizedExpression) - { - Write("("); - VisitDynamic(parenthesizedExpression.Content); - Write(")"); - } - - /// - public override void Visit(ExpressionList expressionList) - { - for (int i = 0; i < expressionList.Count; i++) - { - var expression = expressionList[i]; - if (i > 0) Write(",").WriteSpace(); - VisitDynamic(expression); - } - } - - /// - public override void Visit(ReturnStatement returnStatement) - { - WriteLinkLine(returnStatement); - Write("return"); - if (returnStatement.Value != null) - { - Write(" "); - VisitDynamic(returnStatement.Value); - } - - WriteLine(";"); - } - - /// - public override void Visit(ConditionalExpression conditionalExpression) - { - VisitDynamic(conditionalExpression.Condition); - WriteSpace().Write("?").WriteSpace(); - VisitDynamic(conditionalExpression.Left); - WriteSpace().Write(":").WriteSpace(); - VisitDynamic(conditionalExpression.Right); - } - - /// - public override void Visit(UnaryExpression unaryExpression) - { - if (unaryExpression.Operator.IsPostFix()) - { - VisitDynamic(unaryExpression.Expression); - Write(unaryExpression.Operator.ConvertToString()); - } - else - { - Write(unaryExpression.Operator.ConvertToString()); - VisitDynamic(unaryExpression.Expression); - } - } - - /// - public override void Visit(SwitchStatement switchStatement) - { - WriteLinkLine(switchStatement); - Write("switch").WriteSpace().Write("("); - VisitDynamic(switchStatement.Condition); - Write(")"); - WriteLine(); - OpenBrace(); - - VisitList(switchStatement.Groups); - - CloseBrace(); - } - - /// - public override void Visit(SwitchCaseGroup switchCaseGroup) - { - VisitList(switchCaseGroup.Cases); - Indent(); - VisitDynamic(switchCaseGroup.Statements); - Outdent(); - } - - /// - public override void Visit(DeclarationStatement declarationStatement) - { - WriteLinkLine(declarationStatement); - VisitDynamic(declarationStatement.Content); - } - - /// - public override void Visit(MethodDeclaration methodDeclaration) - { - WriteLinkLine(methodDeclaration); - WriteMethodDeclaration(methodDeclaration).WriteLine(";"); - } - - /// - public override void Visit(MethodDefinition methodDefinition) - { - WriteLinkLine(methodDefinition); - WriteMethodDeclaration(methodDefinition); - - OpenBrace(); - foreach (var statement in methodDefinition.Body) - VisitDynamic(statement); - CloseBrace(); - } - - /// - public override void Visit(Variable variable) - { - WriteLinkLine(variable); - WriteVariable(variable); - } - - /// - public override void Visit(ObjectType typeBase) - { - Write(typeBase.Name); - } - - /// - public override void Visit(TypeName typeBase) - { - Write(typeBase.Name); - } - - /// - public override void Visit(ScalarType scalarType) - { - Write(scalarType.Qualifiers, true); - Write(scalarType.Name); - } - - /// - public override void Visit(GenericType genericType) - { - Write(genericType.Name).Write("<"); - for (int i = 0; i < genericType.Parameters.Count; i++) - { - var parameter = genericType.Parameters[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(parameter); - } - - Write(">"); - } - - /// - public override void Visit(VectorType vectorType) - { - Write(vectorType.Name).Write("<"); - for (int i = 0; i < vectorType.Parameters.Count; i++) - { - var parameter = vectorType.Parameters[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(parameter); - } - - Write(">"); - } - - /// - public override void Visit(MatrixType vectorType) - { - Write(vectorType.Name).Write("<"); - for (int i = 0; i < vectorType.Parameters.Count; i++) - { - var parameter = vectorType.Parameters[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(parameter); - } - - Write(">"); - } - - /// - public override void Visit(Literal literal) - { - if (literal == null) - { - return; - } - - var isStringLiteral = literal.Value is string && !literal.Text.StartsWith('\"'); - if (isStringLiteral) - { - Write("\""); - } - if (literal.SubLiterals != null && literal.SubLiterals.Count > 0) - { - foreach (var subLiteral in literal.SubLiterals) Write(subLiteral.Text); - } - else Write(literal.Text); - if (isStringLiteral) - { - Write("\""); - } - } - - /// - public override void Visit(Qualifier qualifier) - { - Write(qualifier.Key.ToString()); - } - - /// - public override void Visit(Ast.Glsl.LayoutQualifier layoutQualifier) - { - Write(layoutQualifier.Key.ToString()); - } - - /// - /// Writes the specified qualifier. - /// - /// - /// The qualifier. - /// - /// - /// if set to true [write pre qualifiers]. - /// - /// - /// This instance - /// - public ShaderWriter Write(Qualifier qualifiers, bool writePreQualifiers) - { - if (qualifiers == Qualifier.None) return this; - - foreach (var genericQualifier in qualifiers.Values) - { - var qualifier = (Qualifier)genericQualifier; - - if (qualifier == Qualifier.None || qualifier.IsPost == writePreQualifiers) - continue; - - if (qualifier.IsPost) - Write(" "); - - VisitDynamic(qualifier); - - if (!qualifier.IsPost) - Write(" "); - } - - return this; - } - - /// - /// Writes the specified attributes. - /// - /// - /// The attributes. - /// - /// - /// if set to true [write pre qualifiers]. - /// - /// - /// This instance - /// - public ShaderWriter Write(List attributes, bool writePreQualifiers) - { - if (attributes == null || attributes.Count == 0) return this; - - foreach (var attribute in attributes) - { - if (attribute is PostAttributeBase == writePreQualifiers) - continue; - - VisitDynamic(attribute); - } - - return this; - } - - /// - /// Writes the specified text. - /// - /// - /// The text. - /// - /// - /// this instance - /// - public ShaderWriter Write(string text) - { - PrefixIndent(); - Append(text); - return this; - } - - /// - /// Writes the initializer. - /// - /// - /// The expression. - /// - public virtual void WriteInitializer(Expression expression) - { - if (expression == null) return; - - WriteSpace().Write("="); - WriteSpace(); - VisitDynamic(expression); - } - - /// - /// Writes the line. - /// - /// - /// This instance - /// - public ShaderWriter WriteLine() - { - if (EnableNewLine) - { - StringBuilder.AppendLine(); - NewLine = true; - lineCount++; - } - - return this; - } - - /// - /// Writes the line. - /// - /// - /// The text. - /// - /// - /// this instance - /// - public ShaderWriter WriteLine(string text) - { - if (EnableNewLine) - { - PrefixIndent(); - StringBuilder.AppendLine(text); - NewLine = true; - lineCount++; - } - else StringBuilder.Append(text); - - return this; - } - - private string previousSourceFileName = null; - - /// - /// Writes a link line using #line preprocessing directive with the specified node - /// - /// The node to use the Span. - /// This instance - protected ShaderWriter WriteLinkLine(Node node) - { - if (!EnablePreprocessorLine || node.Span.Location.Line == 0) - return this; - - var newSourceFile = node.Span.Location.FileSource; - var sourceLocation = string.Empty; - if (previousSourceFileName != newSourceFile) - { - sourceLocation = string.Format(" \"{0}\"", newSourceFile); - previousSourceFileName = newSourceFile; - } - - Append(Environment.NewLine).Append("#line {0}{1}", node.Span.Location.Line, sourceLocation).Append(Environment.NewLine); - NewLine = true; - lineCount++; - return this; - } - - /// - /// Writes the space. - /// - /// - /// this instance - /// - public ShaderWriter WriteSpace() - { - Append(" "); - return this; - } - - #endregion - - #region Methods - - /// - /// Appends the specified text. - /// - /// - /// The text. - /// - /// - /// this instance - /// - protected ShaderWriter Append(string text) - { - StringBuilder.Append(text); - return this; - } - - /// - /// Appends the specified formatted text. - /// - /// The formatted text. - /// The args to apply to the formatted text. - /// This instance - protected ShaderWriter Append(string format, params object[] args) - { - PrefixIndent(); - StringBuilder.AppendFormat(format, args); - return this; - } - - /// - /// Closes the brace. - /// - /// - /// if set to true [new line]. - /// - /// - /// This instance - /// - protected ShaderWriter CloseBrace(bool newLine = true) - { - Outdent(); - Write("}"); - if (newLine) WriteLine(); - - return this; - } - - /// - /// Opens the brace. - /// - /// - /// This instance - /// - protected ShaderWriter OpenBrace() - { - WriteLine(); - Write("{"); - WriteLine(); - Indent(); - return this; - } - - /// - /// Writes the specified identifier. - /// - /// - /// The identifier. - /// - /// - /// This instance - /// - protected virtual ShaderWriter Write(Identifier identifier) - { - if (identifier.IsSpecialReference) - Write("<"); - - Write(identifier.Text); - - if (identifier.HasIndices) - WriteRankSpecifiers(identifier.Indices); - - if (identifier.IsSpecialReference) - Write(">"); - - return this; - } - - /// - /// Writes the specified method declaration. - /// - /// - /// The method declaration. - /// - /// - /// This instance - /// - protected virtual ShaderWriter WriteMethodDeclaration(MethodDeclaration methodDeclaration) - { - isVisitingVariableInlines = true; - - // Pre Attributes - Write(methodDeclaration.Attributes, true); - - // Pre Qualifiers - Write(methodDeclaration.Qualifiers, true); - - VisitDynamic(methodDeclaration.ReturnType); - - Write(" "); - Write(methodDeclaration.Name); - - Write("("); - - for (int i = 0; i < methodDeclaration.Parameters.Count; i++) - { - var parameter = methodDeclaration.Parameters[i]; - if (i > 0) Write(",").WriteSpace(); - - VisitDynamic(parameter); - } - - Write(")"); - - // Post Qualifiers - Write(methodDeclaration.Qualifiers, false); - - // Post Attributes - Write(methodDeclaration.Attributes, false); - - isVisitingVariableInlines = false; - return this; - } - - /// - /// Writes the rank specifiers. - /// - /// - /// The expression list. - /// - /// - /// This instance - /// - protected ShaderWriter WriteRankSpecifiers(IEnumerable expressionList) - { - foreach (var expression in expressionList) - { - Write("["); - VisitDynamic(expression); - Write("]"); - } - - return this; - } - - /// - /// Writes the content of the statement. - /// - /// - /// The statement. - /// - protected void WriteStatementContent(Statement statement) - { - if (statement is BlockStatement) - { - VisitDynamic(statement); - } - else - { - bool needBraces = (statement is StatementList && ((StatementList)statement).Count > 1); - - if (needBraces) - { - OpenBrace(); - VisitDynamic(statement); - CloseBrace(); - } - else - { - WriteLine(); - Indent(); - VisitDynamic(statement); - Outdent(); - } - } - } - - /// - /// Writes the variable. - /// - /// The variable. - protected void WriteVariable(Variable variable) - { - // Pre Attributes - Write(variable.Attributes, true); - - // Pre qualifiers - Write(variable.Qualifiers, true); - - var arrayType = variable.Type as ArrayType; - var baseType = arrayType == null ? variable.Type : arrayType.Type; - - // If this is a variable declarator not attached to a group, output the type - if (!isInVariableGroup) - { - IsDeclaratingVariable.Push(true); - VisitDynamic(baseType); - IsDeclaratingVariable.Pop(); - WriteSpace(); - } - - if (variable.IsGroup) - { - // Enter a variable group - isInVariableGroup = true; - - for (int i = 0; i < variable.SubVariables.Count; i++) - { - var subVariable = variable.SubVariables[i]; - if (i > 0) - Write(",").WriteSpace(); - VisitDynamic(subVariable); - } - - isInVariableGroup = false; - } - else - { - Write(variable.Name); - } - - if (arrayType != null) - { - WriteRankSpecifiers(arrayType.Dimensions); - } - - // Post qualifiers - Write(variable.Qualifiers, false); - - // Post Attributes - Write(variable.Attributes, false); - - WriteInitializer(variable.InitialValue); - - // A variable can be a parameter or a grouped variable. - // If this is a parameter and we are visiting a method declaration, don't output the ";" - // If we are inside a group variable, don't output ";" as the upper level will add "," to separate variables. - if (!isInVariableGroup && !isVisitingVariableInlines) - WriteLine(";"); - - } - - private void PrefixIndent() - { - if (NewLine) - { - for (int i = 0; i < IndentLevel; ++i) - Append(" "); - - NewLine = false; - } - } - - protected override bool PreVisitNode(Node node) - { - var fileSource = Path.GetFileName(node.Span.Location.FileSource); - - if (string.Compare(fileSource, "internal_hlsl_declarations.hlsl", StringComparison.OrdinalIgnoreCase) != 0 && node.Span.Length > 0) - { - while (SourceLocations.Count < lineCount) - { - SourceLocations.Add(new SourceLocation(node.Span.Location.FileSource, node.Span.Location.Position, node.Span.Location.Line, 1)); - } - } - - return base.PreVisitNode(node); - } - - #endregion - } -} diff --git a/sources/shared/tests/xunit/LauncherSimple.Desktop.cs b/sources/shared/tests/xunit/LauncherSimple.Desktop.cs index 13d32ace75..0b01f29cd1 100644 --- a/sources/shared/tests/xunit/LauncherSimple.Desktop.cs +++ b/sources/shared/tests/xunit/LauncherSimple.Desktop.cs @@ -1,7 +1,9 @@ +using Stride.Graphics.Tests; + namespace xunit.runner.stride { class Program { - public static void Main(string[] args) => StrideXunitRunner.Main(args); + public static void Main(string[] args) => new TestImageEffect().RunImageEffect(); } } diff --git a/sources/tools/Stride.VisualStudio.Commands/Stride.VisualStudio.Commands.csproj b/sources/tools/Stride.VisualStudio.Commands/Stride.VisualStudio.Commands.csproj index dd3d6697e4..c1ea7290f8 100644 --- a/sources/tools/Stride.VisualStudio.Commands/Stride.VisualStudio.Commands.csproj +++ b/sources/tools/Stride.VisualStudio.Commands/Stride.VisualStudio.Commands.csproj @@ -20,7 +20,6 @@ - diff --git a/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs b/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs index efc5fd1b24..9cf1f8e063 100644 --- a/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs +++ b/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs @@ -22,7 +22,7 @@ public StrideCommands() public byte[] GenerateShaderKeys(string inputFileName, string inputFileContent) { - return ShaderKeyFileHelper.GenerateCode(inputFileName, inputFileContent); + throw new NotSupportedException("ShaderKeyGenerator is not used in Stride 4.4+"); } public RawShaderNavigationResult AnalyzeAndGoToDefinition(string projectPath, string sourceCode, RawSourceSpan span) From 49d7e5b77d6a92812cd629d33ae6cab263358dae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 11:28:54 +0900 Subject: [PATCH 0821/1182] Removed generated files --- src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj | 2 -- src/Stride.Shaders/Stride.Shaders.csproj | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 2172d6c292..58bb299313 100644 --- a/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -5,12 +5,10 @@ enable enable true - Generated - diff --git a/src/Stride.Shaders/Stride.Shaders.csproj b/src/Stride.Shaders/Stride.Shaders.csproj index 433a8a7da0..823488d4e2 100644 --- a/src/Stride.Shaders/Stride.Shaders.csproj +++ b/src/Stride.Shaders/Stride.Shaders.csproj @@ -7,7 +7,6 @@ - @@ -39,7 +38,6 @@ $(MSBuildProjectName)2 CS8785;$(WarningsAsErrors) true - Generated From 8f85672a63fdc648a68eace42c672ad8310f01ae Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 12:14:31 +0900 Subject: [PATCH 0822/1182] Avoid switch/case collision in generated intrinsics code --- .../IntrinsicGenerator.cs | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index daa483f385..5c7a89be63 100644 --- a/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -257,18 +257,37 @@ static string NormalizeParameters(string @namespace, string methodName, string p foreach (var intrinsicOverloadsByParamCount in intrinsicGroup.Value.Overloads .GroupBy(x => x.Declaration.Parameters.Items.Count)) { - var intrinsicOverloadGroupsByParameters = intrinsicOverloadsByParamCount.GroupBy(x => GenerateParameters(x.Declaration.Parameters.Items)).ToList(); - foreach (var intrinsicOverloadGroups in intrinsicOverloadGroupsByParameters) + var intrinsics = intrinsicOverloadsByParamCount.Select(x => + ( + x.Declaration, + Namespace: x.DeclaringNamespace, + Signature: GenerateParameters(x.Declaration.Parameters.Items) + )).ToList(); + + var needNamespace = intrinsics.GroupBy(x => x.Signature).Count() > 1; + if (!needNamespace) + intrinsics = intrinsics.Select(x => x with { Namespace = string.Empty }).ToList(); + + foreach (var intrinsicsByNamespace in intrinsics.GroupBy(x => x.Namespace)) { - var optionalParameters = intrinsicOverloadGroups.First().Declaration.Parameters.Items.GetRange(mandatoryParameters.Count, intrinsicOverloadGroups.First().Declaration.Parameters.Items.Count - mandatoryParameters.Count); + var @namespace = intrinsicsByNamespace.Key == string.Empty ? "_" : $"\"{intrinsicsByNamespace.Key}\""; - // If only one parameter signature for all overloads with same number of parameters, skip namespace - var declaredInNamespaces = intrinsicOverloadGroupsByParameters.Count > 1 - ? intrinsicOverloadGroups.Select(x => $"\"{x.DeclaringNamespace}\"").Distinct().ToArray() - : ["_"]; - foreach (var @namespace in declaredInNamespaces) + var intrinsicsBySignatures = intrinsicsByNamespace.GroupBy(y => y.Signature); + foreach (var y in intrinsicsBySignatures) { - builder.AppendLine($"({@namespace}, \"{intrinsicGroup.Key}\", {intrinsicOverloadGroups.First().Declaration.Parameters.Items.Count}) => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}),"); + var optionalParameters = y.First().Declaration.Parameters.Items.GetRange(mandatoryParameters.Count, y.First().Declaration.Parameters.Items.Count - mandatoryParameters.Count); + builder.Append($"({@namespace}, \"{intrinsicGroup.Key}\", {y.First().Declaration.Parameters.Items.Count})"); + + // special switch/case (same number of parameters of different type) + if (intrinsicGroup.Key == "Barrier") + { + builder.Append(" when functionType.ParameterTypes[0].Type is"); + if (y.First().Declaration.Parameters.Items[0].Name.Name == "o") + builder.Append(" not"); + builder.Append(" ScalarType"); + } + + builder.AppendLine($" => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}),"); } } } From 0a00566775fc7c98d2db7f426b34e7858db77730 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 12:47:26 +0900 Subject: [PATCH 0823/1182] Renamed NewSpirvBuffer into SpirvBuffer --- .../SDSL/ShaderMixer.CBuffers.cs | 6 +- .../SDSL/ShaderMixer.Reflection.cs | 6 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 2 +- .../SDSL/ShaderMixer.cs | 20 +- .../Examples.Spirv.cs | 2 +- .../Buffers/IMemoryInstruction.cs | 11 + .../Buffers/IMutSpirvBuffer.cs | 44 -- .../Buffers/ISpirvBuffer.cs | 19 - .../Buffers/NewSpirvBuffer.cs | 514 ------------------ .../Buffers/OpData.cs | 161 ++++++ .../Buffers/OpDataIndex.cs | 7 + .../Buffers/SpirvBuffer.cs | 396 +++++++++----- .../Buffers/SpirvBytecode.cs | 90 +++ .../Parsing/OrderedEnumerator.cs | 79 --- src/Stride.Shaders/Core/SymbolTypes.cs | 4 +- .../Spirv/Building/Builder.Class.cs | 10 +- .../Spirv/Building/Builder.Functions.cs | 8 +- src/Stride.Shaders/Spirv/Building/Builder.cs | 12 +- .../Spirv/Building/CompilerUnit.cs | 4 +- .../Spirv/Building/Context.ExtractBuffers.cs | 8 +- src/Stride.Shaders/Spirv/Building/Context.cs | 8 +- .../Spirv/Processing/BoundReducer.cs | 4 +- .../Spirv/Processing/INanoPass.cs | 2 +- .../Spirv/Processing/IPostProcessorSubPass.cs | 2 +- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 2 +- .../Interfaces/Analysis/StreamAnalyzer.cs | 2 +- .../Interfaces/Cleanup/DeadCodeRemover.cs | 2 +- .../Interfaces/Cleanup/VariableMerger.cs | 2 +- .../Interfaces/Generation/BuiltinProcessor.cs | 2 +- .../Generation/EntryPointWrapperGenerator.cs | 2 +- .../Interfaces/InterfaceProcessor.cs | 4 +- .../Transformation/MethodDuplicator.cs | 2 +- .../Transformation/StreamAccessPatcher.cs | 2 +- .../Spirv/Processing/PostProcessor.cs | 4 +- .../Spirv/Processing/SDSLOpRemover.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 8 +- src/Stride.Shaders/Spirv/Tools/Dis.cs | 12 +- 37 files changed, 591 insertions(+), 874 deletions(-) create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs create mode 100644 src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs delete mode 100644 src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 14e9fc7c98..3be3a5bf5c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -16,7 +16,7 @@ namespace Stride.Shaders.Compilers.SDSL { partial class ShaderMixer { - private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer temp) { var members = new List(); // Remap from variable ID to member index in our new struct @@ -141,7 +141,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob } } - private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer) { // Collect Decorations Dictionary<(int StructType, int Member), (Dictionary StringDecorations, Dictionary> Decorations)> decorations = new(); @@ -384,7 +384,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo } } - private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer) + private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer) { var cbuffers = buffer .Where(x => x.Op == Op.OpVariableSDSL) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 8616b205e4..a3f735f6dd 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -21,7 +21,7 @@ private static bool IsResourceType(SymbolType type) => type is TextureType or SamplerType or BufferType or StructuredBufferType or ConstantBufferSymbol; // Process LinkSDSL, ResourceGroupSDSL and LogicalGroupSDSL; Info will be stored in resourceLinks and cbufferMemberLinks - private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) + private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) { // Link attribute: postfix with composition path string? compositionPath = null; @@ -146,7 +146,7 @@ private void ProcessLinks(SpirvContext context, NewSpirvBuffer buffer) } } - private void RenameVariables(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp) + private void RenameVariables(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer temp) { // Collect variables by names string? compositionPath = null; @@ -206,7 +206,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont } // Emit reflection (except ConstantBuffers which was emitted during ComputeCBufferReflection) - private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, Options options) + private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer, Options options) { Span slotCounts = stackalloc int[options.ResourcesRegisterSeparate ? 4 : 1]; slotCounts.Clear(); diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 351b1ba89e..c4b1aaf36c 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -58,7 +58,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio public override string ToString() => $"{ShaderName} ({(CompositionPath != null ? $" {CompositionPath} " : "")}{StartInstruction}..{EndInstruction})"; } - private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext context, int contextStart, int contextEnd, NewSpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) + private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext context, int contextStart, int contextEnd, SpirvBuffer buffer, int shaderStart, int shaderEnd, ShaderInfo shaderInfo, MixinNode mixinNode) { var removedIds = new HashSet(); for (var index = shaderStart; index < shaderEnd; index++) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 034813889a..24b6757ec1 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -44,7 +44,7 @@ public record struct Options(bool ResourcesRegisterSeparate); public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) { // Create new buffer for the merged result - var temp = new NewSpirvBuffer(); + var temp = new SpirvBuffer(); // This is the global context for this merge operation var context = new SpirvContext(); @@ -144,7 +144,7 @@ class MixinNodeContext public MixinNode? Result { get; } } - MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) + MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, SpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { // We emit OPSDSLEffect for any non-root composition if (currentCompositionPath != null) @@ -200,7 +200,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, return mixinNode; } - private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) + private void ProcessMixinClasses(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode mixinNode) { mixinNode.StartInstruction = buffer.Count; var typeDuplicateInserter = new TypeDuplicateHelper(context); @@ -237,7 +237,7 @@ private static string ComposeLinkName(string linkName, string? compositionPath = // Append CompositionPath to "Link" for any non-stage variable // Also force-emit the missing "Link" decorations - private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass, TypeDuplicateHelper typeDuplicateInserter) + private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer, MixinNode mixinNode, ShaderClassInstantiation shaderClass, TypeDuplicateHelper typeDuplicateInserter) { var isRootMixin = mixinNode.Stage == null; if (shaderClass.ImportStageOnly) @@ -496,7 +496,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS return shaderInfo; } - private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, NewSpirvBuffer temp, MixinNode mixinNode) + private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, SpirvBuffer temp, MixinNode mixinNode) { // Build method group info (override, etc.) ShaderInfo? currentShader = null; @@ -577,7 +577,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } } - private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) + private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer, MixinNode mixinNode, int index, OpForeachSDSL @foreach) { // Find matching ForeachEnd (taking into account nested foreach) var depth = 1; @@ -694,7 +694,7 @@ static void AdjustIndicesAfterAppendInstructionsInner(MixinNode mixinNode, int i } } - private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalContext, SpirvContext context, NewSpirvBuffer temp, MixinNode mixinNode) + private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer temp, MixinNode mixinNode) { var memberAccesses = new Dictionary(); var thisInstructions = new HashSet(); @@ -894,7 +894,7 @@ public static void OffsetIds(OpData inst, int offset) } } - private void SimplifyNotSupportedConstantsInShader(SpirvContext context, NewSpirvBuffer temp) + private void SimplifyNotSupportedConstantsInShader(SpirvContext context, SpirvBuffer temp) { foreach (var i in context) { @@ -909,7 +909,7 @@ private void SimplifyNotSupportedConstantsInShader(SpirvContext context, NewSpir } } - private static void RemoveInstructionWhere(NewSpirvBuffer buffer, Func match) + private static void RemoveInstructionWhere(SpirvBuffer buffer, Func match) { int insertIndex = 0; for (int sourceIndex = 0; sourceIndex < buffer.Count; sourceIndex++) @@ -933,7 +933,7 @@ private static void RemoveInstructionWhere(NewSpirvBuffer buffer, Func diff --git a/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/src/Stride.Shaders.Experiments/Examples.Spirv.cs index 31f903c61c..754adb3851 100644 --- a/src/Stride.Shaders.Experiments/Examples.Spirv.cs +++ b/src/Stride.Shaders.Experiments/Examples.Spirv.cs @@ -63,7 +63,7 @@ public static void CreateNewShader() int id = 1; // var bound = new Bound(); - var buffer = new NewSpirvBuffer(); + var buffer = new SpirvBuffer(); // Capabilities diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs b/src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs new file mode 100644 index 0000000000..06a159535b --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs @@ -0,0 +1,11 @@ +using CommunityToolkit.HighPerformance.Buffers; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +public interface IMemoryInstruction +{ + ref OpData OpData { get; } + void Attach(OpDataIndex dataIndex); + MemoryOwner InstructionMemory { get; } + public void UpdateInstructionMemory(); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs deleted file mode 100644 index 14a6c8f98f..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Buffers/IMutSpirvBuffer.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; - -namespace Stride.Shaders.Spirv.Core; - -/// -/// SPIR-V buffer that can add instructions to itself -/// -public interface IMutSpirvBuffer : ISpirvBuffer -{ - public Instruction Add(Span instruction); -} - -public static class IMutSpirvBufferExtensions -{ - internal static int GetWordLength(this TBuffer _, Span values) - where TBuffer : IMutSpirvBuffer - where TValue : ISpirvElement - { - int length = 0; - foreach (var value in values) - length += value.WordCount; - return length; - } - internal static int GetWordLength(this TBuffer _, TValue? value) - where TBuffer : IMutSpirvBuffer - { - if (value is null) return 0; - - return value switch - { - LiteralInteger i => i.WordCount, - LiteralFloat i => i.WordCount, - int _ => 1, - IdRef _ => 1, - IdResultType _ => 1, - IdResult _ => 1, - string v => new LiteralString(v).WordCount, - LiteralString v => v.WordCount, - int[] a => a.Length, - Enum _ => 1, - _ => throw new NotImplementedException() - }; - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs deleted file mode 100644 index ba21486094..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Buffers/ISpirvBuffer.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Stride.Shaders.Spirv.Core.Parsing; - -namespace Stride.Shaders.Spirv.Core.Buffers; - -/// -/// A SPIR-V buffer object -/// -public interface ISpirvBuffer -{ - public bool HasHeader { get; } - public ref SpirvHeader Header { get; } - - public Span InstructionsSpan { get; } - - /// - /// Get instruction from the instruction index - /// - public Instruction this[int index] { get; } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs deleted file mode 100644 index a59e341bb4..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Buffers/NewSpirvBuffer.cs +++ /dev/null @@ -1,514 +0,0 @@ -#pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. - -using System.Collections; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using CommunityToolkit.HighPerformance; -using CommunityToolkit.HighPerformance.Buffers; -using Stride.Shaders.Spirv.Core.Parsing; -using static Stride.Shaders.Spirv.Specification; - -namespace Stride.Shaders.Spirv.Core.Buffers; - - -public interface IMemoryInstruction -{ - ref OpData OpData { get; } - void Attach(OpDataIndex dataIndex); - MemoryOwner InstructionMemory { get; } - public void UpdateInstructionMemory(); -} - -public struct OpData : IDisposable, IComparable -{ - public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } - public readonly Op Op => (Op)(Memory.Span[0] & 0xFFFF); - - public readonly int? IdResult - { - get => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : null; - set - { - if (InstructionInfo.GetInfo(this).GetResultIndex(out var index) && value is not null) - Memory.Span[index + 1] = value ?? 0; - } - } - public readonly int? IdResultType - { - get => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; - set - { - if (InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) && value is not null) - Memory.Span[index + 1] = value ?? 0; - } - } - - public OpData() - { - Memory = MemoryOwner.Empty; - } - - public OpData(MemoryOwner memory) - { - Memory = memory; - } - public OpData(Span memory) - { - Memory = MemoryOwner.Allocate(memory.Length); - memory.CopyTo(Memory.Span); - } - - public readonly void Dispose() => Memory.Dispose(); - - public readonly SpvOperand Get(string name) - { - foreach (var o in this) - { - if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) - return o; - } - throw new Exception($"No operand '{name}' in op {Op}"); - } - - public readonly bool TryGet(string name, out T operand) - { - foreach (var o in this) - { - if (name == o.Name) - { - operand = o.To(); - return true; - } - } - operand = default!; - return false; - } - - public readonly T Get(string name) - { - foreach (var o in this) - { - if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) - return o.To(); - } - throw new Exception($"No operand '{name}' in op {Op}"); - } - public readonly T GetEnum(string name) - where T : Enum - { - foreach (var o in this) - { - if (name == o.Name && !o.Kind.ToString().Contains("Literal") && !o.Kind.ToString().Contains("Id")) - return o.ToEnum(); - } - throw new Exception($"No enum operand '{name}' in op {Op}"); - } - - public readonly OpDataEnumerator GetEnumerator() => new(Memory.Span); - - public readonly int CompareTo(OpData other) - { - var group = InstructionInfo.GetGroupOrder(this); - var otherGroup = InstructionInfo.GetGroupOrder(other); - return group.CompareTo(otherGroup); - } - - public override string ToString() - { - var sb = new StringBuilder(); - // Check for IdResult first - foreach (var op in this) - { - switch (op.Kind) - { - case OperandKind.IdResult: - sb.Append("%"); - sb.Append(op.Words[0]); - sb.Append(" = "); - break; - } - } - - sb.Append(Op); - foreach (var op in this) - { - if (op.Kind == OperandKind.IdResult) - continue; - sb.Append(" "); - switch (op.Kind) - { - case OperandKind.IdResultType: - case OperandKind.IdRef: - for (var index = 0; index < op.Words.Length; index++) - { - if (index > 0) - sb.Append(" "); - sb.Append("%"); - sb.Append(op.Words[index]); - } - break; - case OperandKind.LiteralInteger when op.Words.Length == 1: - foreach (var e in op.Words) - sb.Append(e); - break; - case OperandKind.LiteralString: - sb.Append('"'); - sb.Append(op.ToLiteral()); - sb.Append('"'); - break; - case OperandKind k when k.IsEnum(): - for (var index = 0; index < op.Words.Length; index++) - { - if (index > 0) - sb.Append(" "); - sb.Append(k.ConvertEnumValueToString(op.Words[index])); - } - break; - default: - sb.Append($"unknown_{op.Kind}"); - if (op.Words.Length != 1) - sb.Append($"_{op.Words.Length}"); - break; - } - } - return sb.ToString(); - } -} - - -public record struct OpDataIndex(int Index, NewSpirvBuffer Buffer) -{ - public readonly Op Op => Data.Op; - public readonly ref OpData Data => ref Buffer.GetRef(Index); -} - -public record SpirvBytecode(SpirvHeader Header, NewSpirvBuffer Buffer) : IDisposable -{ - public SpirvBytecode(NewSpirvBuffer buffer) : this(CreateHeader(buffer), buffer) - { - } - - public void Dispose() => Buffer.Dispose(); - - public static SpirvHeader CreateHeader(NewSpirvBuffer buffer) - { - var header = new SpirvHeader("1.4", 0, 1); - var bound = 1; - foreach (var i in buffer) - { - ref var data = ref i.Data; - if (data.IdResult is int index && index >= bound) - bound = index + 1; - } - return new SpirvHeader("1.4", 0, bound); - } - - public Span ToBytecode() - { - return CreateBytecodeFromBuffers(Header, false, Buffer); - } - - public static SpirvBytecode CreateBufferFromBytecode(Span span) - { - return CreateBufferFromBytecode(MemoryMarshal.Cast(span)); - } - - public static SpirvBytecode CreateBufferFromBytecode(Span span) - { - if (span[0] != MagicNumber) - throw new InvalidOperationException("SPIRV Magic number not found"); - - var header = SpirvHeader.Read(span); - - return new(header, new NewSpirvBuffer(span[SpirvHeader.IntSpanSize..])); - } - - public static SpanOwner CreateSpanFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) - { - int instructionsMemorySize = 0; - var bound = header.Bound; - foreach (var buffer in buffers) - { - foreach (var i in buffer) - { - ref var data = ref i.Data; - if (data.IdResult is int index && index >= bound) - bound = index + 1; - - instructionsMemorySize += data.Memory.Length; - } - } - - header = header with { Bound = bound }; - - var result = SpanOwner.Allocate(5 + instructionsMemorySize); - var span = result.Span; - header.WriteTo(span); - var offset = 5; - foreach (var buffer in buffers) - { - foreach (var i in buffer) - { - i.Data.Memory.Span.CopyTo(span[offset..]); - offset += i.Data.Memory.Length; - } - } - return result; - } - - public static Span CreateBytecodeFromBuffers(params Span buffers) - { - return CreateBytecodeFromBuffers(new("1.4", 0, 1), true, buffers); - } - - public static Span CreateBytecodeFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) - { - return MemoryMarshal.AsBytes(CreateSpanFromBuffers(header, computeBounds, buffers).Span); - } -} - -public sealed class NewSpirvBuffer() : IDisposable, IEnumerable -{ - List Instructions { get; set; } = []; - public int Count => Instructions.Count; - - // internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; - public OpDataIndex this[int index] => new(index, this); - - public List Slice(int start, int length) => Instructions.Slice(start, length); - - - public ref OpData GetRef(int index) => ref CollectionsMarshal.AsSpan(Instructions)[index]; - - public NewSpirvBuffer(Span instructions) : this() - { - if (instructions.Length > 0 && instructions[0] == MagicNumber) - throw new InvalidOperationException(); - - int wid = 0; - while (wid < instructions.Length) - { - Add(new(instructions.Slice(wid, instructions[wid] >> 16))); - wid += instructions[wid] >> 16; - } - } - - public OpDataIndex Add(OpData data) - { - Instructions.Add(data); - return new OpDataIndex(Instructions.Count - 1, this); - } - - public OpDataIndex Insert(int index, OpData data) - { - Instructions.Insert(index, data); - return new OpDataIndex(index, this); - } - - public T Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct - { - Instructions.Add(new(instruction.InstructionMemory)); - instruction.Attach(new(Instructions.Count - 1, this)); - return instruction; - } - - public OpData AddData(in T instruction) where T : struct, IMemoryInstruction, allows ref struct - { - Instructions.Add(new(instruction.InstructionMemory)); - return Instructions[^1]; - } - - public NewSpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction, allows ref struct - { - Instructions.Add(new(instruction.InstructionMemory)); - var tmp = instruction; - return this; - } - public NewSpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct - { - result = instruction; - Instructions.Add(new(instruction.InstructionMemory)); - instruction.Attach(new(Instructions.Count - 1, this)); - return this; - } - - public T Insert(int index, in T instruction) - where T : struct, IMemoryInstruction, allows ref struct - { - Instructions.Insert(index, new(instruction.InstructionMemory)); - instruction.Attach(new(index, this)); - return instruction; - } - public OpData InsertData(int index, in T instruction) - where T : struct, IMemoryInstruction, allows ref struct - { - var result = new OpData(instruction.InstructionMemory); - Instructions.Insert(index, result); - instruction.Attach(new(index, this)); - return result; - } - - /// - /// Removes an instruction at a certain index. - ///
Be careful when using this method, as it will invalidate any references to the removed instruction. - ///
- /// - /// true if the instruction was successfully removed - public void RemoveAt(int index, bool dispose = true) - { - if (index < 0 || index >= Instructions.Count) - throw new ArgumentOutOfRangeException(); - if (dispose) - Instructions[index].Dispose(); - Instructions.RemoveAt(index); - } - - public void RemoveRange(int index, int count, bool dispose = true) - { - if (dispose) - { - for (int i = index; i < index + count; ++i) - Instructions[i].Dispose(); - } - Instructions.RemoveRange(index, count); - } - - public void InsertRange(int index, params ReadOnlySpan source) - { - Instructions.InsertRange(index, source); - } - - public OpData Replace(int index, OpData i, bool dispose = true) - { - if (index < 0 || index >= Instructions.Count) - throw new InvalidOperationException(); - - if (dispose) - Instructions[index].Dispose(); - Instructions[index] = i; - return Instructions[index]; - } - - public OpData Replace(int index, in T instruction, bool dispose = true) where T : struct, IMemoryInstruction, allows ref struct - { - if (index < 0 || index >= Instructions.Count) - throw new InvalidOperationException(); - - if (dispose) - Instructions[index].Dispose(); - Instructions[index] = new(instruction.InstructionMemory); - return Instructions[index]; - } - - public NewSpirvBuffer FluentReplace(int index, in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct - { - Replace(index, instruction); - instruction.Attach(new(index, this)); - result = instruction; - return this; - } - - public Enumerator GetEnumerator() => new(this); - - public struct Enumerator(NewSpirvBuffer buffer) : IEnumerator - { - readonly NewSpirvBuffer buffer = buffer; - private readonly List list = buffer.Instructions; - private int index = -1; - - public readonly OpDataIndex Current => new(index, buffer); - - object IEnumerator.Current => Current; - - public void Dispose() - { - } - - public bool MoveNext() - { - if (index < list.Count - 1) - { - index++; - return true; - } - return false; - } - - public void Reset() - { - index = -1; - } - } - - public void Sort() - { - // Note: We don't use List.Sort because it's not stable. - // This is especially important for type depending on another type. - var sortedInstructions = Instructions.OrderBy(InstructionInfo.GetGroupOrder).ToList(); - Instructions.Clear(); - Instructions.AddRange(sortedInstructions); - } - - public Span ToBytecode() - { - return SpirvBytecode.CreateBytecodeFromBuffers(this); - } - - public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) - { - foreach (var op in this) - { - var info = InstructionInfo.GetInfo(op.Op); - if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == typeId) - { - instruction = op; - return true; - } - } - instruction = default; - return false; - } - - public void Dispose() - { - foreach (var instruction in Instructions) - instruction.Dispose(); - Instructions.Clear(); - } - - public static NewSpirvBuffer Merge(NewSpirvBuffer buffer1, NewSpirvBuffer buffer2) - { - var result = new NewSpirvBuffer(); - result.Instructions.AddRange(buffer1.Instructions); - result.Instructions.AddRange(buffer2.Instructions); - return result; - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } -} - -public static class IMemoryInstructionExtensions -{ - /// - /// Gets information for the instruction operation. - /// - /// - /// - public static LogicalOperandArray GetInfo(this T op) - where T : struct, IMemoryInstruction, allows ref struct - { - if (!Unsafe.IsNullRef(ref op.OpData)) - return InstructionInfo.GetInfo(op.OpData); - return InstructionInfo.GetInfo(op.InstructionMemory.Span); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs b/src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs new file mode 100644 index 0000000000..d3cda1a256 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs @@ -0,0 +1,161 @@ +using System.Text; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +public struct OpData : IDisposable, IComparable +{ + public MemoryOwner Memory { get; internal set { field?.Dispose(); field = value; } } + public readonly Specification.Op Op => (Specification.Op)(Memory.Span[0] & 0xFFFF); + + public readonly int? IdResult + { + get => InstructionInfo.GetInfo(this).GetResultIndex(out var index) ? Memory.Span[index + 1] : null; + set + { + if (InstructionInfo.GetInfo(this).GetResultIndex(out var index) && value is not null) + Memory.Span[index + 1] = value ?? 0; + } + } + public readonly int? IdResultType + { + get => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; + set + { + if (InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) && value is not null) + Memory.Span[index + 1] = value ?? 0; + } + } + + public OpData() + { + Memory = MemoryOwner.Empty; + } + + public OpData(MemoryOwner memory) + { + Memory = memory; + } + public OpData(Span memory) + { + Memory = MemoryOwner.Allocate(memory.Length); + memory.CopyTo(Memory.Span); + } + + public readonly void Dispose() => Memory.Dispose(); + + public readonly SpvOperand Get(string name) + { + foreach (var o in this) + { + if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) + return o; + } + throw new Exception($"No operand '{name}' in op {Op}"); + } + + public readonly bool TryGet(string name, out T operand) + { + foreach (var o in this) + { + if (name == o.Name) + { + operand = o.To(); + return true; + } + } + operand = default!; + return false; + } + + public readonly T Get(string name) + { + foreach (var o in this) + { + if (name == o.Name && (o.Kind.ToString().Contains("Literal") || o.Kind.ToString().Contains("Id"))) + return o.To(); + } + throw new Exception($"No operand '{name}' in op {Op}"); + } + public readonly T GetEnum(string name) + where T : Enum + { + foreach (var o in this) + { + if (name == o.Name && !o.Kind.ToString().Contains("Literal") && !o.Kind.ToString().Contains("Id")) + return o.ToEnum(); + } + throw new Exception($"No enum operand '{name}' in op {Op}"); + } + + public readonly OpDataEnumerator GetEnumerator() => new(Memory.Span); + + public readonly int CompareTo(OpData other) + { + var group = InstructionInfo.GetGroupOrder(this); + var otherGroup = InstructionInfo.GetGroupOrder(other); + return group.CompareTo(otherGroup); + } + + public override string ToString() + { + var sb = new StringBuilder(); + // Check for IdResult first + foreach (var op in this) + { + switch (op.Kind) + { + case OperandKind.IdResult: + sb.Append("%"); + sb.Append(op.Words[0]); + sb.Append(" = "); + break; + } + } + + sb.Append(Op); + foreach (var op in this) + { + if (op.Kind == OperandKind.IdResult) + continue; + sb.Append(" "); + switch (op.Kind) + { + case OperandKind.IdResultType: + case OperandKind.IdRef: + for (var index = 0; index < op.Words.Length; index++) + { + if (index > 0) + sb.Append(" "); + sb.Append("%"); + sb.Append(op.Words[index]); + } + break; + case OperandKind.LiteralInteger when op.Words.Length == 1: + foreach (var e in op.Words) + sb.Append(e); + break; + case OperandKind.LiteralString: + sb.Append('"'); + sb.Append(op.ToLiteral()); + sb.Append('"'); + break; + case OperandKind k when k.IsEnum(): + for (var index = 0; index < op.Words.Length; index++) + { + if (index > 0) + sb.Append(" "); + sb.Append(k.ConvertEnumValueToString(op.Words[index])); + } + break; + default: + sb.Append($"unknown_{op.Kind}"); + if (op.Words.Length != 1) + sb.Append($"_{op.Words.Length}"); + break; + } + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs b/src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs new file mode 100644 index 0000000000..be1b08777f --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs @@ -0,0 +1,7 @@ +namespace Stride.Shaders.Spirv.Core.Buffers; + +public record struct OpDataIndex(int Index, SpirvBuffer Buffer) +{ + public readonly Specification.Op Op => Data.Op; + public readonly ref OpData Data => ref Buffer.GetRef(Index); +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 5cd3998ba8..faf3afecf6 100644 --- a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -1,146 +1,250 @@ -// using CommunityToolkit.HighPerformance; -// using CommunityToolkit.HighPerformance.Buffers; -// using Stride.Shaders.Spirv.Core.Parsing; -// using System; -// using System.Buffers; -// using System.Numerics; - -// namespace Stride.Shaders.Spirv.Core.Buffers; - -// /// -// /// A common SPIR-V buffer containing a header. -// /// -// public class SpirvBuffer : IMutSpirvBuffer -// { -// private SpirvHeader header = new("1.3", 0, 0); -// private ArrayPool pool = ArrayPool.Shared; - -// public List Instructions { get; } = []; - -// public Span InstructionsSpan => Instructions.AsSpan(); - -// public bool HasHeader => true; -// public ref SpirvHeader Header => ref header; - -// public Instruction FindInstructionByResultId(int resultId) -// { -// foreach (var instruction in Instructions) -// { -// if (instruction.ResultId == resultId) -// return instruction; -// } - -// throw new InvalidOperationException(); -// } - -// public Instruction this[int index] => Instructions[index]; - -// public SpirvBuffer(int initialSize = 32) -// { -// } -// public SpirvBuffer(Memory memory) -// { -// Header = SpirvHeader.Read(memory.Span); -// var instructions = memory[5..]; - -// int wid = 0; -// while (wid < instructions.Length) -// { -// Instructions.Add(new Instruction(instructions.Slice(wid, instructions.Span[wid] >> 16))); -// wid += instructions.Span[wid] >> 16; -// } -// } - -// public SpirvBuffer(Span span) -// { -// Header = SpirvHeader.Read(span); -// var instructions = span[5..]; - -// int wid = 0; -// while (wid < instructions.Length) -// { -// Add(instructions.Slice(wid, instructions[wid] >> 16)); -// wid += instructions[wid] >> 16; -// } -// } - -// public int[] ToBuffer() -// { -// var offset = 5; -// foreach (var instruction in Instructions) -// offset += instruction.WordCount; -// var buffer = new int[offset]; - -// Header.WriteTo(buffer); -// offset = 5; -// foreach (var instruction in Instructions) -// { -// instruction.Words.CopyTo(buffer.AsSpan()[offset..]); -// offset += instruction.WordCount; -// } - -// return buffer; -// } - - -// public void Sort() -// { -// var sorted = new OrderedEnumerator(this); -// var newInstructions = new List(); -// while (sorted.MoveNext()) -// { -// newInstructions.Add(sorted.Current); -// } - -// Instructions.Clear(); -// Instructions.AddRange(newInstructions); -// } - -// private Instruction CreateInstruction(Span instructionData) -// { -// var instructionBuffer = pool.Rent(instructionData.Length).AsMemory(0, instructionData.Length); -// instructionData.CopyTo(instructionBuffer.Span); -// return new Instruction(instructionBuffer); -// } - -// public Instruction Add(Span instructionData) -// { -// var instruction = CreateInstruction(instructionData); - -// Instructions.Add(instruction); -// if (instruction.ResultId is int resultId && resultId >= Header.Bound) -// Header = Header with { Bound = resultId + 1 }; - -// return instruction; -// } - -// public Instruction Insert(int position, Span instructionData) -// { -// var instruction = CreateInstruction(instructionData); - -// Instructions.Insert(position, instruction); -// if (instruction.ResultId is int resultId && resultId >= Header.Bound) -// Header = Header with { Bound = resultId + 1 }; - -// return instruction; -// } - -// internal void Add(TBuff buffer) -// where TBuff : ISpirvBuffer -// { -// Instructions.AddRange(buffer.InstructionsSpan); -// } - -// public static SpirvBuffer Merge(T1 left, T2 right) -// where T1 : ISpirvBuffer -// where T2 : ISpirvBuffer -// { -// var buff = new SpirvBuffer(); -// buff.Add(left); -// buff.Add(right); -// foreach (var e in buff.Instructions) -// if (e.ResultId is int r && buff.Header.Bound < r + 1) -// buff.Header = buff.Header with { Bound = r + 1 }; -// return buff; -// } -// } +using System.Collections; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +public sealed class SpirvBuffer() : IDisposable, IEnumerable +{ + List Instructions { get; set; } = []; + public int Count => Instructions.Count; + + // internal ref OpData this[int index] => ref CollectionsMarshal.AsSpan(Instructions)[index]; + public OpDataIndex this[int index] => new(index, this); + + public List Slice(int start, int length) => Instructions.Slice(start, length); + + + public ref OpData GetRef(int index) => ref CollectionsMarshal.AsSpan(Instructions)[index]; + + public SpirvBuffer(Span instructions) : this() + { + if (instructions.Length > 0 && instructions[0] == MagicNumber) + throw new InvalidOperationException(); + + int wid = 0; + while (wid < instructions.Length) + { + Add(new(instructions.Slice(wid, instructions[wid] >> 16))); + wid += instructions[wid] >> 16; + } + } + + public OpDataIndex Add(OpData data) + { + Instructions.Add(data); + return new OpDataIndex(Instructions.Count - 1, this); + } + + public OpDataIndex Insert(int index, OpData data) + { + Instructions.Insert(index, data); + return new OpDataIndex(index, this); + } + + public T Add(in T instruction) where T : struct, IMemoryInstruction, allows ref struct + { + Instructions.Add(new(instruction.InstructionMemory)); + instruction.Attach(new(Instructions.Count - 1, this)); + return instruction; + } + + public OpData AddData(in T instruction) where T : struct, IMemoryInstruction, allows ref struct + { + Instructions.Add(new(instruction.InstructionMemory)); + return Instructions[^1]; + } + + public SpirvBuffer FluentAdd(in T instruction) where T : struct, IMemoryInstruction, allows ref struct + { + Instructions.Add(new(instruction.InstructionMemory)); + var tmp = instruction; + return this; + } + public SpirvBuffer FluentAdd(in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct + { + result = instruction; + Instructions.Add(new(instruction.InstructionMemory)); + instruction.Attach(new(Instructions.Count - 1, this)); + return this; + } + + public T Insert(int index, in T instruction) + where T : struct, IMemoryInstruction, allows ref struct + { + Instructions.Insert(index, new(instruction.InstructionMemory)); + instruction.Attach(new(index, this)); + return instruction; + } + public OpData InsertData(int index, in T instruction) + where T : struct, IMemoryInstruction, allows ref struct + { + var result = new OpData(instruction.InstructionMemory); + Instructions.Insert(index, result); + instruction.Attach(new(index, this)); + return result; + } + + /// + /// Removes an instruction at a certain index. + ///
Be careful when using this method, as it will invalidate any references to the removed instruction. + ///
+ /// + /// true if the instruction was successfully removed + public void RemoveAt(int index, bool dispose = true) + { + if (index < 0 || index >= Instructions.Count) + throw new ArgumentOutOfRangeException(); + if (dispose) + Instructions[index].Dispose(); + Instructions.RemoveAt(index); + } + + public void RemoveRange(int index, int count, bool dispose = true) + { + if (dispose) + { + for (int i = index; i < index + count; ++i) + Instructions[i].Dispose(); + } + Instructions.RemoveRange(index, count); + } + + public void InsertRange(int index, params ReadOnlySpan source) + { + Instructions.InsertRange(index, source); + } + + public OpData Replace(int index, OpData i, bool dispose = true) + { + if (index < 0 || index >= Instructions.Count) + throw new InvalidOperationException(); + + if (dispose) + Instructions[index].Dispose(); + Instructions[index] = i; + return Instructions[index]; + } + + public OpData Replace(int index, in T instruction, bool dispose = true) where T : struct, IMemoryInstruction, allows ref struct + { + if (index < 0 || index >= Instructions.Count) + throw new InvalidOperationException(); + + if (dispose) + Instructions[index].Dispose(); + Instructions[index] = new(instruction.InstructionMemory); + return Instructions[index]; + } + + public SpirvBuffer FluentReplace(int index, in T instruction, out T result) where T : struct, IMemoryInstruction, allows ref struct + { + Replace(index, instruction); + instruction.Attach(new(index, this)); + result = instruction; + return this; + } + + public Enumerator GetEnumerator() => new(this); + + public struct Enumerator(SpirvBuffer buffer) : IEnumerator + { + readonly SpirvBuffer buffer = buffer; + private readonly List list = buffer.Instructions; + private int index = -1; + + public readonly OpDataIndex Current => new(index, buffer); + + object IEnumerator.Current => Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + if (index < list.Count - 1) + { + index++; + return true; + } + return false; + } + + public void Reset() + { + index = -1; + } + } + + public void Sort() + { + // Note: We don't use List.Sort because it's not stable. + // This is especially important for type depending on another type. + var sortedInstructions = Instructions.OrderBy(InstructionInfo.GetGroupOrder).ToList(); + Instructions.Clear(); + Instructions.AddRange(sortedInstructions); + } + + public Span ToBytecode() + { + return SpirvBytecode.CreateBytecodeFromBuffers(this); + } + + public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) + { + foreach (var op in this) + { + var info = InstructionInfo.GetInfo(op.Op); + if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == typeId) + { + instruction = op; + return true; + } + } + instruction = default; + return false; + } + + public void Dispose() + { + foreach (var instruction in Instructions) + instruction.Dispose(); + Instructions.Clear(); + } + + public static SpirvBuffer Merge(SpirvBuffer buffer1, SpirvBuffer buffer2) + { + var result = new SpirvBuffer(); + result.Instructions.AddRange(buffer1.Instructions); + result.Instructions.AddRange(buffer2.Instructions); + return result; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } +} + +public static class IMemoryInstructionExtensions +{ + /// + /// Gets information for the instruction operation. + /// + /// + /// + public static LogicalOperandArray GetInfo(this T op) + where T : struct, IMemoryInstruction, allows ref struct + { + if (!Unsafe.IsNullRef(ref op.OpData)) + return InstructionInfo.GetInfo(op.OpData); + return InstructionInfo.GetInfo(op.InstructionMemory.Span); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs new file mode 100644 index 0000000000..b177a22012 --- /dev/null +++ b/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs @@ -0,0 +1,90 @@ +using System.Runtime.InteropServices; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Parsing; + +namespace Stride.Shaders.Spirv.Core.Buffers; + +public record SpirvBytecode(SpirvHeader Header, SpirvBuffer Buffer) : IDisposable +{ + public SpirvBytecode(SpirvBuffer buffer) : this(CreateHeader(buffer), buffer) + { + } + + public void Dispose() => Buffer.Dispose(); + + public static SpirvHeader CreateHeader(SpirvBuffer buffer) + { + var header = new SpirvHeader("1.4", 0, 1); + var bound = 1; + foreach (var i in buffer) + { + ref var data = ref i.Data; + if (data.IdResult is int index && index >= bound) + bound = index + 1; + } + return new SpirvHeader("1.4", 0, bound); + } + + public Span ToBytecode() + { + return CreateBytecodeFromBuffers(Header, false, Buffer); + } + + public static SpirvBytecode CreateBufferFromBytecode(Span span) + { + return CreateBufferFromBytecode(MemoryMarshal.Cast(span)); + } + + public static SpirvBytecode CreateBufferFromBytecode(Span span) + { + if (span[0] != Specification.MagicNumber) + throw new InvalidOperationException("SPIRV Magic number not found"); + + var header = SpirvHeader.Read(span); + + return new(header, new SpirvBuffer(span[SpirvHeader.IntSpanSize..])); + } + + public static SpanOwner CreateSpanFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) + { + int instructionsMemorySize = 0; + var bound = header.Bound; + foreach (var buffer in buffers) + { + foreach (var i in buffer) + { + ref var data = ref i.Data; + if (data.IdResult is int index && index >= bound) + bound = index + 1; + + instructionsMemorySize += data.Memory.Length; + } + } + + header = header with { Bound = bound }; + + var result = SpanOwner.Allocate(5 + instructionsMemorySize); + var span = result.Span; + header.WriteTo(span); + var offset = 5; + foreach (var buffer in buffers) + { + foreach (var i in buffer) + { + i.Data.Memory.Span.CopyTo(span[offset..]); + offset += i.Data.Memory.Length; + } + } + return result; + } + + public static Span CreateBytecodeFromBuffers(params Span buffers) + { + return CreateBytecodeFromBuffers(new("1.4", 0, 1), true, buffers); + } + + public static Span CreateBytecodeFromBuffers(SpirvHeader header, bool computeBounds, params Span buffers) + { + return MemoryMarshal.AsBytes(CreateSpanFromBuffers(header, computeBounds, buffers).Span); + } +} \ No newline at end of file diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs deleted file mode 100644 index a62d1299d5..0000000000 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OrderedEnumerator.cs +++ /dev/null @@ -1,79 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; -using static Stride.Shaders.Spirv.Specification; - -namespace Stride.Shaders.Spirv.Core.Parsing; - - -/// -/// An enumerator where each instructions is sorted -/// Instruction are grouped together in the InstructionInfo.Order file, and each groups are ordered based on the SPIR-V specification -/// -public ref struct OrderedEnumerator(ISpirvBuffer buffer) -{ - int currentPosition = 0; - bool started = false; - - - public readonly Instruction Current => buffer.InstructionsSpan[currentPosition]; - - public bool MoveNext() - { - // The first time find the lowest group and index - if (!started) - { - var firstGroup = int.MaxValue; - var firstPos = int.MaxValue; - for (var index = 0; index < buffer.InstructionsSpan.Length; index++) - { - var instruction = buffer.InstructionsSpan[index]; - var group = GetGroupOrder(instruction); - if (group < firstGroup) - { - firstGroup = group; - firstPos = index; - } - } - - currentPosition = firstPos; - started = true; - return true; - } - else - { - // We start from the current group since we've established there is no other below this one - var currentGroup = GetGroupOrder(buffer.InstructionsSpan[currentPosition]); - for (int group = currentGroup; group < 15; group += 1) - { - if(group == currentGroup) - { - for (int i = currentPosition + 1; i < buffer.InstructionsSpan.Length; ++i) - { - if (GetGroupOrder(buffer.InstructionsSpan[i]) == group) - { - currentPosition = i; - return true; - } - } - } - else - { - for (int i = 0; i < buffer.InstructionsSpan.Length; ++i) - { - if (GetGroupOrder(buffer.InstructionsSpan[i]) == group) - { - currentPosition = i; - return true; - } - } - } - } - return false; - } - - } - - readonly int GetGroupOrder(Instruction instruction) - { - return InstructionInfo.GetGroupOrder(instruction.OpCode, instruction.OpCode == Op.OpVariable || instruction.OpCode == Op.OpVariableSDSL ? (StorageClass)instruction.Words[3] : null); - } -} \ No newline at end of file diff --git a/src/Stride.Shaders/Core/SymbolTypes.cs b/src/Stride.Shaders/Core/SymbolTypes.cs index 014fcb0fd6..f5486a71fa 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.cs @@ -215,10 +215,10 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// /// The base type for the array. /// The size of the array. If -1, it means size is not defined, such as using []. -public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, NewSpirvBuffer Buffer)? SizeExpression = null) : SymbolType() +public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, SpirvBuffer Buffer)? SizeExpression = null) : SymbolType() { // We want this mutable for internal use - public (int Id, NewSpirvBuffer Buffer)? SizeExpression { get; set; } = SizeExpression; + public (int Id, SpirvBuffer Buffer)? SizeExpression { get; set; } = SizeExpression; public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs index 0ad2c66356..a187649dd6 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Class.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Class.cs @@ -24,7 +24,7 @@ namespace Stride.Shaders.Spirv.Building; public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); -public record struct ShaderBuffers(SpirvContext Context, NewSpirvBuffer Buffer); +public record struct ShaderBuffers(SpirvContext Context, SpirvBuffer Buffer); public enum ResolveStep { @@ -577,7 +577,7 @@ public static bool ContainIds(HashSet ids, OpData i) return false; } - public static void RemapIds(NewSpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) + public static void RemapIds(SpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) { for (var index = shaderStart; index < buffer.Count; index++) { @@ -742,9 +742,9 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, return shaderBuffers; } - public static NewSpirvBuffer CopyBuffer(NewSpirvBuffer shader) + public static SpirvBuffer CopyBuffer(SpirvBuffer shader) { - var copiedShader = new NewSpirvBuffer(); + var copiedShader = new SpirvBuffer(); foreach (var i in shader) { var i2 = new OpData(i.Data.Memory.Span); @@ -754,7 +754,7 @@ public static NewSpirvBuffer CopyBuffer(NewSpirvBuffer shader) return shader; } - public static List CollectGenerics(NewSpirvBuffer shader) + public static List CollectGenerics(SpirvBuffer shader) { // Collect OpSDSLGenericParameter List generics = new(); diff --git a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs index 5ed798cd76..468a53b952 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs @@ -50,7 +50,7 @@ public SpirvValue EmitFunctionParameter(SpirvContext context, string name, Symbo return value; } - public static OpFunctionParameter GetFunctionParameter(NewSpirvBuffer buffer, Symbol method, int functionParameterIndex) + public static OpFunctionParameter GetFunctionParameter(SpirvBuffer buffer, Symbol method, int functionParameterIndex) { // Find OpFunctionParameter var functionParameterCurrent = 0; @@ -67,7 +67,7 @@ public static OpFunctionParameter GetFunctionParameter(NewSpirvBuffer buffer, Sy throw new InvalidOperationException(); } - public static void FunctionRemoveArgument(SpirvContext context, NewSpirvBuffer buffer, Symbol method, int argIndex) + public static void FunctionRemoveArgument(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex) { var methodType = (FunctionType)method.Type; method.Type = methodType with { ParameterTypes = methodType.ParameterTypes[0..^1] }; @@ -77,7 +77,7 @@ public static void FunctionRemoveArgument(SpirvContext context, NewSpirvBuffer b SetOpNop(functionParameter.InstructionMemory.Span); } - public static void FunctionReplaceArgument(SpirvContext context, NewSpirvBuffer buffer, Symbol method, int argIndex, SymbolType newType) + public static void FunctionReplaceArgument(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex, SymbolType newType) { var methodType = (FunctionType)method.Type; var parameterTypes = new List(methodType.ParameterTypes); @@ -89,7 +89,7 @@ public static void FunctionReplaceArgument(SpirvContext context, NewSpirvBuffer functionParameter.ResultType = context.GetOrRegister(newType); } - public static (int Start, int End) FindMethodBounds(NewSpirvBuffer buffer, int functionId) + public static (int Start, int End) FindMethodBounds(SpirvBuffer buffer, int functionId) { int? start = null; for (var index = 0; index < buffer.Count; index++) diff --git a/src/Stride.Shaders/Spirv/Building/Builder.cs b/src/Stride.Shaders/Spirv/Building/Builder.cs index 40277c0e88..47d3f5134d 100644 --- a/src/Stride.Shaders/Spirv/Building/Builder.cs +++ b/src/Stride.Shaders/Spirv/Building/Builder.cs @@ -15,8 +15,8 @@ public partial class SpirvBuilder() { private int position; - NewSpirvBuffer buffer = new(); - NewSpirvBuffer Buffer { get => buffer; init => buffer = value; } + SpirvBuffer buffer = new(); + SpirvBuffer Buffer { get => buffer; init => buffer = value; } public SpirvFunction? CurrentFunction { get; internal set; } public SpirvBlock? CurrentBlock { get; internal set; } public ref int Position => ref position; @@ -98,7 +98,7 @@ public OpData InsertData(in T value) => Buffer.InsertData(Position++, value); [Obsolete("Use the insert method instead")] - public NewSpirvBuffer GetBuffer() => Buffer; + public SpirvBuffer GetBuffer() => Buffer; public Op GetLastInstructionType() { @@ -110,7 +110,7 @@ public override string ToString() return Spv.Dis(Buffer, writeToConsole: false); } - public UseTemporaryBufferHelper UseTemporaryBuffer(NewSpirvBuffer buffer, int? position = null) + public UseTemporaryBufferHelper UseTemporaryBuffer(SpirvBuffer buffer, int? position = null) { var result = new UseTemporaryBufferHelper(this, this.buffer, this.position); this.buffer = buffer; @@ -118,7 +118,7 @@ public UseTemporaryBufferHelper UseTemporaryBuffer(NewSpirvBuffer buffer, int? p return result; } - public void Merge(NewSpirvBuffer other) + public void Merge(SpirvBuffer other) { var instructions = new List(); foreach (var instruction in other) @@ -128,7 +128,7 @@ public void Merge(NewSpirvBuffer other) Position += other.Count; } - public struct UseTemporaryBufferHelper(SpirvBuilder builder, NewSpirvBuffer buffer, int position) : IDisposable + public struct UseTemporaryBufferHelper(SpirvBuilder builder, SpirvBuffer buffer, int position) : IDisposable { public void Dispose() { diff --git a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs index 76777d5bf4..96a178cccf 100644 --- a/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs +++ b/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs @@ -38,10 +38,10 @@ public void Deconstruct(out SpirvBuilder builder, out SpirvContext context) } #pragma warning disable CS0618 // Type or member is obsolete - public NewSpirvBuffer ToBuffer() + public SpirvBuffer ToBuffer() { Context.Sort(); - return NewSpirvBuffer.Merge(Context.GetBuffer(), Builder.GetBuffer()); + return SpirvBuffer.Merge(Context.GetBuffer(), Builder.GetBuffer()); } public ShaderBuffers ToShaderBuffers() diff --git a/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs index 0778693f89..fc51d23785 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs @@ -6,13 +6,13 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvContext { - public int InsertWithoutDuplicates(int? desiredResultId, NewSpirvBuffer source) + public int InsertWithoutDuplicates(int? desiredResultId, SpirvBuffer source) { var index = Buffer.Count; return InsertWithoutDuplicates(ref index, desiredResultId, source); } - public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, NewSpirvBuffer source) + public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, SpirvBuffer source) { // Import in current buffer (without duplicate) var typeDuplicateInserter = new TypeDuplicateHelper(this); @@ -90,14 +90,14 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI return lastResultId; } - public NewSpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) + public SpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) { // First, run a simplification pass // TODO: separate simplification from computing value? TryGetConstantValue(constantId, out _, out _, true); // Go backward and find any reference - var newBuffer = new NewSpirvBuffer(); + var newBuffer = new SpirvBuffer(); var referenced = new HashSet { constantId }; var instructions = new List(); for (int index = Buffer.Count - 1; index >= 0; --index) diff --git a/src/Stride.Shaders/Spirv/Building/Context.cs b/src/Stride.Shaders/Spirv/Building/Context.cs index c0cd0b2c58..318e992158 100644 --- a/src/Stride.Shaders/Spirv/Building/Context.cs +++ b/src/Stride.Shaders/Spirv/Building/Context.cs @@ -102,7 +102,7 @@ public partial class SpirvContext public int Count => Buffer.Count; - NewSpirvBuffer Buffer { get; init; } + SpirvBuffer Buffer { get; init; } public int? GLSLSet { get; private set; } @@ -111,7 +111,7 @@ public SpirvContext() Buffer = new(); } - public SpirvContext(NewSpirvBuffer buffer) + public SpirvContext(SpirvBuffer buffer) { Buffer = buffer; } @@ -247,9 +247,9 @@ public void RemoveNameAndDecorations(HashSet ids) public void Sort() => Buffer.Sort(); [Obsolete("Use the insert method instead")] - public NewSpirvBuffer GetBuffer() => Buffer; + public SpirvBuffer GetBuffer() => Buffer; - public NewSpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); + public SpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); public override string ToString() { diff --git a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs index fae58eeae9..0504c1396f 100644 --- a/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs +++ b/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs @@ -17,7 +17,7 @@ namespace Stride.Shaders.Spirv.Processing; public struct BoundReducer() : INanoPass { - public readonly void Apply(NewSpirvBuffer buffer) + public readonly void Apply(SpirvBuffer buffer) { // First step is to find the next idResult // If it's previous + 1 then it's okay, previous is now updated @@ -65,7 +65,7 @@ public readonly void Apply(NewSpirvBuffer buffer) } - static void ReplaceRefs(int from, int to, NewSpirvBuffer buffer) + static void ReplaceRefs(int from, int to, SpirvBuffer buffer) { foreach (var i in buffer) { diff --git a/src/Stride.Shaders/Spirv/Processing/INanoPass.cs b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs index 21847d3d68..46a116e959 100644 --- a/src/Stride.Shaders/Spirv/Processing/INanoPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/INanoPass.cs @@ -13,5 +13,5 @@ namespace Stride.Shaders.Spirv.Processing; /// public interface INanoPass { - void Apply(NewSpirvBuffer buffer); + void Apply(SpirvBuffer buffer); } diff --git a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs index 57ed81b258..5abc9b895f 100644 --- a/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs +++ b/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs @@ -10,5 +10,5 @@ namespace Stride.Shaders.Spirv.Processing; public interface IPostProcessorSubPass { - void Apply(NewSpirvBuffer buffer, Instruction instruction); + void Apply(SpirvBuffer buffer, Instruction instruction); } diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index d90a0c3064..cbd187e9a3 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -13,7 +13,7 @@ internal static class ReadWriteAnalyzer /// /// Figure out (recursively) which streams are being read from and written to. /// - public static bool AnalyzeStreamReadWrites(NewSpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { // Check if already processed var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index b507678a49..f5274f1b1a 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Spirv.Processing.Interfaces.Analysis; internal static class StreamAnalyzer { - public static AnalysisResult Analyze(NewSpirvBuffer buffer, SpirvContext context) + public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) { var streams = new Dictionary(); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 6c7264364a..4ca31898bf 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -36,7 +36,7 @@ public static void ResetUsedThisStage(AnalysisResult analysisResult, LiveAnalysi /// Removes unreferenced code including methods, variables, resources, cbuffers, and stream types. /// Preserves logical groups and resource groups where at least one member is used. /// - public static void RemoveUnreferencedCode(NewSpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) + public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext context, AnalysisResult analysisResult, LiveAnalysis liveAnalysis) { // Remove unreferenced code var removedIds = new HashSet(); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs index ff5a06f950..9621e944ac 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs @@ -16,7 +16,7 @@ internal static class VariableMerger /// /// Merges variables that have the same semantic into a single variable. /// - public static void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, NewSpirvBuffer buffer, AnalysisResult analysisResult) + public static void MergeSameSemanticVariables(SymbolTable table, SpirvContext context, SpirvBuffer buffer, AnalysisResult analysisResult) { Dictionary remapIds = new(); foreach (var streamWithSameSemantic in analysisResult.Streams.Where(x => x.Value.Semantic != null).GroupBy(x => x.Value.Semantic)) diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index 97f10a2592..f45bf82b41 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -37,7 +37,7 @@ public static bool AddLocation(SpirvContext context, int variable, string locati /// Used when builtin types have different sizes than shader types. /// public static int ConvertInterfaceVariable( - NewSpirvBuffer buffer, + SpirvBuffer buffer, SpirvContext context, SymbolType sourceType, SymbolType castType, diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 1e716b7e2a..b613a4811e 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Spirv.Processing.Interfaces.Generation; internal static class EntryPointWrapperGenerator { public static (int ResultId, string Name) GenerateWrapper(SpirvContext context, - NewSpirvBuffer buffer, + SpirvBuffer buffer, Symbol entryPoint, ExecutionModel executionModel, AnalysisResult analysisResult, diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 99b63e404e..ce011df1dc 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -37,7 +37,7 @@ public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, }; } - public Result Process(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context) + public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext context) { var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); @@ -205,7 +205,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); } - private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, NewSpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) + private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, SpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs index 6ad73478ad..6f595783b8 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs @@ -18,7 +18,7 @@ internal static class MethodDuplicator /// On first use, backs up the original method code. On subsequent uses, creates a copy with new IDs. /// public static void DuplicateMethodIfNecessary( - NewSpirvBuffer buffer, + SpirvBuffer buffer, SpirvContext context, int functionId, AnalysisResult analysisResult, diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 13568c9962..10637eb7e5 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -35,7 +35,7 @@ public override SymbolType VisitStreamsType(StreamsType streamsType) /// public static void PatchStreamsAccesses( SymbolTable table, - NewSpirvBuffer buffer, + SpirvBuffer buffer, SpirvContext context, int functionId, StructType streamsStructType, diff --git a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs index 7fff1e531d..1d5ec22c2d 100644 --- a/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs +++ b/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs @@ -9,14 +9,14 @@ namespace Stride.Shaders.Spirv.PostProcessing; /// public static class SpirvProcessor { - public static void Process(NewSpirvBuffer buffer) + public static void Process(SpirvBuffer buffer) { //Apply(buffer); //Apply(buffer); //Apply(buffer); } - static void Apply(NewSpirvBuffer buffer) + static void Apply(SpirvBuffer buffer) where T : struct, INanoPass { var p = new T(); diff --git a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs index 74cb96bc46..99f9c47cae 100644 --- a/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs @@ -9,7 +9,7 @@ namespace Stride.Shaders.Spirv.Processing; /// public struct NOPRemover : INanoPass { - public readonly void Apply(NewSpirvBuffer buffer) + public readonly void Apply(SpirvBuffer buffer) { for (int i = 0; i < buffer.Count; i++) if (buffer[i].Op == Op.OpNop) diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index 8fddb1f62c..ae06c408ce 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -22,7 +22,7 @@ namespace Stride.Shaders.Spirv.Processing; /// public class TypeDuplicateHelper { - public int[] FindItemsWithTypes(NewSpirvBuffer buffer, params Span ops) + public int[] FindItemsWithTypes(SpirvBuffer buffer, params Span ops) { var itemCount = 0; for (var index = 0; index < buffer.Count; index++) @@ -344,7 +344,7 @@ public void RemoveDuplicates() ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparerSort); } - private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer) + private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer) { var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }, comparer); var end = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = endOp, Index = int.MaxValue }, comparer); @@ -358,7 +358,7 @@ private static void ProcessInstructions(NewSpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer) + private static void ProcessSortedInstructions(SpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer) { for (var firstIndex = start; firstIndex < end; ) { @@ -399,7 +399,7 @@ private static void ProcessSortedInstructions(NewSpirvBuffer buffer, List from, int to, NewSpirvBuffer buffer) + static void ReplaceRefs(Span from, int to, SpirvBuffer buffer) { foreach (var i in buffer) { diff --git a/src/Stride.Shaders/Spirv/Tools/Dis.cs b/src/Stride.Shaders/Spirv/Tools/Dis.cs index 925d31b0aa..2643085b1e 100644 --- a/src/Stride.Shaders/Spirv/Tools/Dis.cs +++ b/src/Stride.Shaders/Spirv/Tools/Dis.cs @@ -10,7 +10,7 @@ using Stride.Shaders.Spirv.Building; using static Stride.Shaders.Spirv.Specification; -[assembly: DebuggerDisplay("{Stride.Shaders.Spirv.Tools.SpirvBufferExtensions.GetDebuggerDisplay(this)}", Target = typeof(NewSpirvBuffer))] +[assembly: DebuggerDisplay("{Stride.Shaders.Spirv.Tools.SpirvBufferExtensions.GetDebuggerDisplay(this)}", Target = typeof(SpirvBuffer))] namespace Stride.Shaders.Spirv.Tools; @@ -24,7 +24,7 @@ public enum DisassemblerFlags public static class SpirvBufferExtensions { - public static string GetDebuggerDisplay(this NewSpirvBuffer buffer) + public static string GetDebuggerDisplay(this SpirvBuffer buffer) { return Spv.Dis(buffer, DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex | DisassemblerFlags.Name); } @@ -38,11 +38,11 @@ public static partial class Spv { public static string Dis(ShaderBuffers buffers, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - var writer = new DisWriter(new(new("undefined", 0, 1), NewSpirvBuffer.Merge(buffers.Context.GetBuffer(), buffers.Buffer)), flags, writeToConsole); + var writer = new DisWriter(new(new("undefined", 0, 1), SpirvBuffer.Merge(buffers.Context.GetBuffer(), buffers.Buffer)), flags, writeToConsole); writer.Disassemble(); return writer.ToString(); } - public static string Dis(NewSpirvBuffer bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) + public static string Dis(SpirvBuffer bytecode, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { var writer = new DisWriter(new(new("undefined", 0, 1), bytecode), flags, writeToConsole); writer.Disassemble(); @@ -180,7 +180,7 @@ readonly DisWriter AppendLiteralString(string value) } - readonly DisWriter AppendContextDependentNumber(SpvOperand operand, OpData data, NewSpirvBuffer buffer) + readonly DisWriter AppendContextDependentNumber(SpvOperand operand, OpData data, SpirvBuffer buffer) { int typeId = data.Op switch { @@ -462,7 +462,7 @@ void ComputeIdOffset() } IdOffset = Math.Min(IdOffset, MAX_OFFSET); } - public readonly NewSpirvBuffer.Enumerator GetEnumerator() => Bytecode.Buffer.GetEnumerator(); + public readonly SpirvBuffer.Enumerator GetEnumerator() => Bytecode.Buffer.GetEnumerator(); public readonly void Dispose() { From c3b67acbce0823211e228ed63ff454d33e998157 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 12:49:31 +0900 Subject: [PATCH 0824/1182] Disable CS9264 in Instructions.gen.cs --- .../SPVGenerator.Instructions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 35844dad93..16f20d0796 100644 --- a/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -42,6 +42,8 @@ public static void GenerateInstructionStructs(SourceProductionContext spc, Spirv SourceText.From( SyntaxFactory .ParseCompilationUnit(@$" + #pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. + using static Stride.Shaders.Spirv.Specification; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; From ea933b48cff69254575ecfe27a917cba66c00fd9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 13:34:01 +0900 Subject: [PATCH 0825/1182] Removed some warnings --- .../SDSL/ShaderMixer.CBuffers.cs | 52 ++++++++++--------- .../IntrinsicGenerator.cs | 6 ++- .../VisitorGenerator.cs | 17 +++--- .../Parsing/OpDataEnumerator.cs | 3 +- .../Core/SymbolTypes.Visitors.cs | 7 +-- .../Parsing/SDSL/AST/Expression.cs | 52 +++++++++++++------ .../Interfaces/Cleanup/DeadCodeRemover.cs | 6 +-- .../Transformation/StreamAccessPatcher.cs | 10 ++-- .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- 9 files changed, 90 insertions(+), 65 deletions(-) diff --git a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 3be3a5bf5c..416c3c66a2 100644 --- a/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -184,19 +184,20 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x.Variable, + VariableId: x.Variable.Data.IdResult!.Value, CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, - StructTypePtrId: x.Variable.Data.IdResultType.Value, - StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is ConstantBufferSymbol s ? s : null, + StructTypePtrId: x.Variable.Data.IdResultType!.Value, + StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType { StorageClass: Specification.StorageClass.Uniform, BaseType: ConstantBufferSymbol s } ? s : null, MemberIndexOffset: 0, LogicalGroup: GetCBufferLogicalGroup(x.Variable.Data.IdResult.Value))) // TODO: Check Decoration.Block? .Where(x => x.StructType != null) - .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.Variable.Data.IdResult.Value])); + .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.VariableId])); // This helper method will transfer decorations from the old structure to the new merged structure // Also, it will add a default "Link" decoration if none was set - void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) + void ProcessDecorations(Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) { var cbufferStructId = context.Types[cbufferStruct]; int mergedMemberIndex = 0; @@ -220,7 +221,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, string CompositionPath, stri } // Transfer cbufferMemberLinks to new structure - CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) + CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) { int mergedMemberIndex = 0; var links = new CBufferMemberMetadata[cbufferStruct.Members.Count]; @@ -228,7 +229,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData { for (int memberIndex = 0; memberIndex < cbuffer.StructType.Members.Count; memberIndex++, mergedMemberIndex++) { - links[mergedMemberIndex] = cbufferMemberMetadata[cbuffer.Variable.Data.IdResult.Value][memberIndex]; + links[mergedMemberIndex] = cbufferMemberMetadata[cbuffer.VariableId][memberIndex]; } } @@ -244,7 +245,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData // In all cases, we update name to one without .0 .1 suffix // (we do it even for case count == 1 because all buffer except one might have been optimized away) - context.Names[cbuffersSpan[0].Variable.Data.IdResult.Value] = cbuffersEntry.Key; + context.Names[cbuffersSpan[0].VariableId] = cbuffersEntry.Key; if (cbuffersEntry.Count() == 1) { @@ -260,7 +261,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData cbuffer.MemberIndexOffset = offset; offset += cbuffer.StructType.Members.Count; } - var variables = cbuffers.ToDictionary(x => x.Variable.Data.IdResult.Value, x => x); + var variables = cbuffers.ToDictionary(x => x.VariableId, x => x); var structTypes = cbuffers.Select(x => x.StructType); var mergedCbufferStruct = new ConstantBufferSymbol(cbuffersEntry.Key, structTypes.SelectMany(x => x.Members).ToList()); @@ -302,18 +303,18 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData // Update first variable to use new type cbuffersSpan[0].Variable.Data.IdResultType = mergedCbufferPtrStructId; - cbufferMemberMetadata[cbuffersSpan[0].Variable.Data.IdResult.Value] = GenerateCBufferLinks(cbuffersSpan[0].Variable.Data.IdResult.Value, cbuffersSpan, mergedCbufferStruct); + cbufferMemberMetadata[cbuffersSpan[0].VariableId] = GenerateCBufferLinks(cbuffersSpan[0].VariableId, cbuffersSpan, mergedCbufferStruct); foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) { // Ensure cbuffer variable name is correct (it might still have a pending number such as Test.0 if there was multiple buffers with same name) - if (cbuffersSpan[0].Variable.Data.IdResult == name.Target) + if (cbuffersSpan[0].VariableId == name.Target) name.Name = cbuffersEntry.Key; // Remove any other OpName (after remapping they would all point to the merged variable) foreach (var cbuffer in cbuffersSpan[1..]) { - if (cbuffer.Variable.Data.IdResult == name.Target) + if (cbuffer.VariableId == name.Target) SetOpNop(i.Data.Memory.Span); } } @@ -322,8 +323,8 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData foreach (ref var cbuffer in cbuffersSpan.Slice(1)) { // Update all cbuffers access to be replaced with first variable (unified cbuffer) - idRemapping.Add(cbuffer.Variable.Data.IdResult.Value, cbuffersSpan[0].Variable.Data.IdResult.Value); - removedIds.Add(cbuffer.Variable.Data.IdResult.Value); + idRemapping.Add(cbuffer.VariableId, cbuffersSpan[0].VariableId); + removedIds.Add(cbuffer.VariableId); // Remove other cbuffer variables SetOpNop(cbuffer.Variable.Data.Memory.Span); // TODO: Do we want to remove unecessary types? @@ -353,7 +354,15 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s, Spir } return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = size }; } + + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) + { + EmitArrayStrideDecorations(context, a, typeModifier, alignmentRules, out var arrayStride); + var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); + return elementType with { Elements = a.Size }; + } + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { return symbolType switch @@ -374,14 +383,6 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, T MatrixType m when typeModifier == TypeModifier.RowMajor => ConvertType(context, m.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Columns, ColumnCount = m.Rows }, }; - - EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) - { - EmitArrayStrideDecorations(context, a, typeModifier, alignmentRules, out var arrayStride); - - var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); - return elementType with { Elements = a.Size }; - } } private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer) @@ -391,7 +392,8 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x, - StructTypePtrId: x.Data.IdResultType.Value, + VariableId: x.Data.IdResult!.Value, + StructTypePtrId: x.Data.IdResultType!.Value, StructType: context.ReverseTypes[x.Data.IdResultType.Value] is PointerType p && p.StorageClass == Specification.StorageClass.Uniform && p.BaseType is StructuredType s ? s : null, MemberIndexOffset: 0)) .Where(x => x.StructType != null) @@ -404,8 +406,8 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon var structTypeId = context.Types[cb]; var memberInfos = new EffectValueDescription[cb.Members.Count]; - if (!cbufferMemberMetadata.TryGetValue(cbuffer.Variable.Data.IdResult.Value, out var cbufferMetadata)) - throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.Variable.Data.IdResult.Value]}; it should have been generated during {MergeCBuffers}"); + if (!cbufferMemberMetadata.TryGetValue(cbuffer.VariableId, out var cbufferMetadata)) + throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.VariableId]}; it should have been generated during {nameof(MergeCBuffers)}"); for (var index = 0; index < cb.Members.Count; index++) { @@ -440,7 +442,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription { - Name = context.Names[cbuffer.Variable.Data.IdResult.Value], + Name = context.Names[cbuffer.VariableId], // Round buffer size to next multiple of 16 bytes Size = (constantBufferOffset + 15) / 16 * 16, diff --git a/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index 5c7a89be63..3af416257d 100644 --- a/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -35,6 +35,7 @@ static void GenerateIntrinsicsData(SourceProductionContext spc, EquatableList(); @@ -293,6 +295,8 @@ static string NormalizeParameters(string @namespace, string methodName, string p } } + builder.AppendLine("_ => throw new InvalidOperationException($\"Intrinsic {name} not found\"),"); + builder.AppendLine("};"); builder.AppendLine("}"); builder.AppendLine("}"); diff --git a/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs b/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs index 7edd43586a..0968b1277a 100644 --- a/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs +++ b/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs @@ -53,6 +53,8 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var typeAndGenericFormat = new SymbolDisplayFormat(SymbolDisplayGlobalNamespaceStyle.Omitted, SymbolDisplayTypeQualificationStyle.NameOnly, SymbolDisplayGenericsOptions.IncludeTypeParameters); // Source: Stride old shader system VisitorGenerated.tt preprocessed with RuntimeTextTemplate1.tt and linePragmas="false" + sb.AppendLine("// "); + sb.AppendLine("#nullable enable"); sb.AppendLine("using Stride.Shaders.Core;"); sb.AppendLine("namespace Stride.Shaders.Core"); sb.AppendLine("{"); @@ -247,10 +249,11 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c private static IEnumerable GetNodeTypes(INamedTypeSymbol symbol, Func isNodeType) { - while (symbol != null && isNodeType(symbol)) + INamedTypeSymbol? currentSymbol = symbol; + while (currentSymbol != null && isNodeType(currentSymbol)) { - yield return symbol; - symbol = symbol.BaseType; + yield return currentSymbol; + currentSymbol = currentSymbol.BaseType; } } @@ -268,7 +271,7 @@ private static bool CanVisitMember(ISymbol symbol) if (symbol.DeclaredAccessibility != Accessibility.Public || symbol.IsStatic) return false; - if (symbol.GetAttributes().Any(x => x.AttributeClass.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) + if (symbol.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == "Stride.Core.Shaders.Ast.VisitorIgnoreAttribute")) return false; if (symbol.Kind == SymbolKind.Field) @@ -355,12 +358,12 @@ private static ITypeSymbol GetSymbolType(ISymbol symbol) } var aliasSymbol = symbol as IAliasSymbol; - if (aliasSymbol != null) + if (aliasSymbol?.Target is ITypeSymbol typeSymbol) { - return aliasSymbol.Target as ITypeSymbol; + return typeSymbol; } - return symbol as ITypeSymbol; + return (ITypeSymbol)symbol; } diff --git a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index cc428a39d3..44393407d9 100644 --- a/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata.Ecma335; using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; @@ -44,7 +45,7 @@ public OpDataEnumerator(Span instruction) public SpvOperand Current => ParseCurrent(); - public bool FindOperandInfo(OperandParameters p, ParameterizedOperandKey key, out ParameterizedOperand[] operands) + private bool FindOperandInfo(OperandParameters p, ParameterizedOperandKey key, [MaybeNullWhen(false)] out ParameterizedOperand[] operands) { if (p.TryGetValue(key, out operands)) return true; diff --git a/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs index 4bcd2044bc..4a7870468a 100644 --- a/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs +++ b/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs @@ -61,7 +61,7 @@ public virtual bool VisitItem(ref T item) where T : struct, ISymbolTypeItem } -public abstract partial class TypeRewriter : TypeVisitor +public abstract partial class TypeRewriter : TypeVisitor { protected TypeRewriter() { @@ -85,10 +85,7 @@ protected List VisitTypeList(List list) where T : SymbolType newList = [.. list.Slice(0, i)]; if (newList != null) - { - if (temp != null) - newList.Add((T)temp); - } + newList.Add((T)temp); } return newList ?? list; diff --git a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs index b45ae36327..66de50c8dd 100644 --- a/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs +++ b/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs @@ -663,20 +663,18 @@ public SpirvValue CompileHelper(SymbolTable table, CompilerUnit? compiler = null intermediateValues = new SpirvValue[Accessors.Count + 1]; } - var context = compiler?.Context; - var builder = compiler?.Builder; SpirvValue result = default; - if (builder != null) + if (compiler != null) { - result = Source.Compile(table, compiler!); + result = Source.Compile(table, compiler); intermediateValues[0] = result; } else { Source.ProcessSymbol(table); } - var currentValueType = Source.Type; + var currentValueType = Source.Type!; int accessChainIdCount = 0; void PushAccessChainId(Span accessChainIds, int accessChainIndex) @@ -693,8 +691,8 @@ void EmitOpAccessChain(Span accessChainIds, int? intermediateValueIndex) // Do we need to issue an OpAccessChain? if (accessChainIdCount > 0) { - var resultType = context.GetOrRegister(currentValueType); - var accessChain = builder.Insert(new OpAccessChain(resultType, context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); + var resultType = compiler.Context.GetOrRegister(currentValueType); + var accessChain = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); result = new SpirvValue(accessChain.ResultId, resultType); if (intermediateValueIndex != null) @@ -770,8 +768,8 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Note: Texture.Load expects one more coordinate // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) var indexerType = pointerType.BaseType is TextureType - ? indexer.Index.ValueType.GetElementType().GetVectorOrScalar(indexer.Index.ValueType.GetElementCount() + 1) - : indexer.Index.ValueType; + ? indexer.Index.ValueType!.GetElementType().GetVectorOrScalar(indexer.Index.ValueType!.GetElementCount() + 1) + : indexer.Index.ValueType!; if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType], out var resolvedIntrinsic2)) throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); @@ -779,14 +777,16 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); // Note: Texture.Load expects one more coordinate // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) var indexerType2 = pointerType.BaseType is TextureType - ? indexer.Index.ValueType.GetElementType().GetVectorOrScalar(indexer.Index.ValueType.GetElementCount() + 1) - : indexer.Index.ValueType; + ? indexer.Index.ValueType!.GetElementType().GetVectorOrScalar(indexer.Index.ValueType!.GetElementCount() + 1) + : indexer.Index.ValueType!; if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType2], out var resolvedIntrinsic)) throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); @@ -827,7 +827,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // StructuredBuffer are declared as OpTypeStruct { OpTypeRuntimeArray } // so first, we push a 0 to access the OpTypeRuntimeArray - PushAccessChainId(accessChainIds, context.CompileConstant(0).Id); + PushAccessChainId(accessChainIds, compiler.Context.CompileConstant(0).Id); // Then we push the index inside the array var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); @@ -835,6 +835,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, MethodCall { Name.Name: "Append", Arguments.Values.Count: 1 } methodCall): + { if (compiler == null) { ((MethodCall)accessor).ProcessParameterSymbols(table, null); @@ -842,19 +843,22 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); var output = methodCall.Arguments.Values[0].CompileAsValue(table, compiler); - var streamsType = (StreamsType)methodCall.Arguments.Values[0].ValueType; + var streamsType = (StreamsType)methodCall.Arguments.Values[0].ValueType!; // Note: if it was a Streams, implicit cast it to Output if (streamsType.Kind == StreamsKindSDSL.Streams) - output = new (builder.InsertData(new OpCopyLogical(context.GetOrRegister(new StreamsType(StreamsKindSDSL.Output)), context.Bound++, output.Id))); + output = new(builder.InsertData(new OpCopyLogical(context.GetOrRegister(new StreamsType(StreamsKindSDSL.Output)), context.Bound++, output.Id))); else if (streamsType.Kind == StreamsKindSDSL.Input) throw new InvalidOperationException("StreamOutput.Append() only accepts Streams or Output objects"); builder.Insert(new OpEmitVertexSDSL(output.Id)); result = default; break; + } case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, MethodCall { Name.Name: "RestartStrip", Arguments.Values.Count: 0 }): if (compiler == null) @@ -867,7 +871,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); - builder.Insert(new OpEndPrimitive()); + compiler.Builder.Insert(new OpEndPrimitive()); result = default; break; case (_, MethodCall methodCall): @@ -884,6 +888,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso result = methodCall.Compile(table, compiler); break; case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): + { if (compiler == null) { if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) @@ -897,6 +902,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; var importedVariable = LoadedShaderSymbol.ImportSymbol(table, context, field.ResolvedSymbol); // Emit OpAccessChain with everything so far @@ -905,6 +911,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // TODO: figure out instance (this vs composition) result = IdentifierBase.EmitSymbol(builder, context, importedVariable, false, result.Id); break; + } case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): if (compiler == null) { @@ -935,7 +942,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } //indexes[i] = builder.CreateConstant(context, shader, new IntegerLiteral(new(32, false, true), index, new())).Id; - PushAccessChainId(accessChainIds, context.CompileConstant(index).Id); + PushAccessChainId(accessChainIds, compiler.Context.CompileConstant(index).Id); break; // Swizzles case (PointerType { BaseType: MatrixType m } p, Identifier id) when id.IsMatrixSwizzle(m, out var swizzles): @@ -954,6 +961,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; EmitOpAccessChain(accessChainIds, i - 1); (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); } @@ -965,7 +973,8 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso accessor.Type = new PointerType(m.BaseType, p.StorageClass); break; } - + + var (builder, context) = compiler; PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Column).Id); PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Row).Id); } @@ -985,6 +994,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); break; } @@ -998,6 +1008,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } // Load value + var (builder, context) = compiler; EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, []))); @@ -1020,6 +1031,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; PushAccessChainId(accessChainIds, context.CompileConstant(ConvertSwizzle(swizzle[0])).Id); } break; @@ -1039,6 +1051,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); } + var (builder, context) = compiler; (result, _) = builder.ApplyVectorSwizzles(context, result, v, swizzleIndices); break; @@ -1053,6 +1066,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } // Load value + var (builder, context) = compiler; EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null, []))); @@ -1096,6 +1110,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso throw new InvalidOperationException($"Swizzle {accessor} is out of bound for expression {ToString(i)} of type {currentValueType}"); } + var (builder, context) = compiler; (result, _) = builder.ApplyScalarSwizzles(context, result, s, swizzleIndices); } else @@ -1159,6 +1174,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } // We need to load as a variable to use OpAccessChain + var (builder, context) = compiler; var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(new PointerType(currentValueType, Specification.StorageClass.Function)), context.Bound++); builder.Insert(new OpStore(functionVariable, result.Id, null, [])); // Process again the same item with new type @@ -1186,6 +1202,8 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + var (builder, context) = compiler; + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 4ca31898bf..341683b198 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -57,7 +57,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{resourceGroup.Value.Name}.{resourceGroup.Value.LogicalGroup}", out var exists); if (!exists) logicalGroup = new(); - logicalGroup.Resources.Add(resourceGroup.Value); + logicalGroup!.Resources.Add(resourceGroup.Value); } } } @@ -69,7 +69,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte ref var logicalGroup = ref CollectionsMarshal.GetValueRefOrAddDefault(logicalGroups, $"{cbuffer.Value.Name}.{cbuffer.Value.LogicalGroup}", out var exists); if (!exists) logicalGroup = new(); - logicalGroup.CBuffers.Add(cbuffer.Value); + logicalGroup!.CBuffers.Add(cbuffer.Value); } } @@ -173,7 +173,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte { if (i.Op == Op.OpTypeStreamsSDSL || i.Op == Op.OpTypeGeometryStreamOutputSDSL || i.Op == Op.OpTypePatchSDSL || i.Op == Op.OpTypeFunctionSDSL || i.Op == Op.OpTypePointer || i.Op == Op.OpTypeArray) { - if (context.ReverseTypes.TryGetValue(i.Data.IdResult.Value, out var type)) + if (context.ReverseTypes.TryGetValue(i.Data.IdResult!.Value, out var type)) { var streamsTypeSearch = new ReadWriteAnalyzer.StreamsTypeSearch(); streamsTypeSearch.VisitType(type); diff --git a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 10637eb7e5..d2c0191ddd 100644 --- a/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -58,7 +58,7 @@ public static void PatchStreamsAccesses( var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); - var newMethodType = (FunctionType)streamTypeReplacer.VisitType(methodType); + var newMethodType = (FunctionType)streamTypeReplacer.VisitType(methodType)!; if (!ReferenceEquals(newMethodType, methodType)) { methodType = newMethodType; @@ -149,7 +149,7 @@ void CheckStreamTypes(int id) new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, copyLogical.Operand, - [stream.Value.InputStructFieldIndex.Value])).ResultId; + [stream.Value.InputStructFieldIndex!.Value])).ResultId; } else { @@ -171,7 +171,7 @@ void CheckStreamTypes(int id) if (!stream.Value.Patch && stream.Value.Output) { // Extract value from streams - tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex.Value] = buffer.Insert(index++, + tempIdsForStreamCopy[stream.Value.OutputStructFieldIndex!.Value] = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, copyLogical.Operand, @@ -191,8 +191,8 @@ void CheckStreamTypes(int id) { if (stream.Value.Output) { - var outputValue = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, output, [stream.Value.OutputStructFieldIndex.Value])).ResultId; - buffer.Insert(index++, new OpStore(stream.Value.OutputId.Value, outputValue, MemoryAccessMask.None, [])); + var outputValue = buffer.Insert(index++, new OpCompositeExtract(context.GetOrRegister(stream.Value.Type), context.Bound++, output, [stream.Value.OutputStructFieldIndex!.Value])).ResultId; + buffer.Insert(index++, new OpStore(stream.Value.OutputId!.Value, outputValue, MemoryAccessMask.None, [])); } } diff --git a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs index ae06c408ce..9d99027e35 100644 --- a/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs @@ -146,7 +146,7 @@ private static int CompareIntConstant(SpirvContext context, int id1, int id2) return (value1Success, value2Success) switch { // Both succeeds: compare values - (true, true) => ((int)value1).CompareTo((int)value2), + (true, true) => ((int)value1!).CompareTo((int)value2!), // Only one succeeds (use bool order) (true, false) or (false, true) => value1Success.CompareTo(value2Success), // Both fails: use ID From 58c548095fd2a105da486bdf64df58de856a6b50 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 14:33:19 +0900 Subject: [PATCH 0826/1182] Moved projects --- {sources/shaders => build}/submodules/CppNet8 | 0 .../shaders => build}/submodules/SpirvHeaders | 0 .../submodules/SpirvRegistry | 0 sources/shaders/SDSL.sln | 31 +- .../Stride.Shaders.Compilers/Direct3D/DXC.cs | 0 .../Stride.Shaders.Compilers/Direct3D/FXC.cs | 0 .../Direct3D/Spv2DXIL.cs | 0 .../Stride.Shaders.Compilers/ICompiler.cs | 0 .../Stride.Shaders.Compilers/MainMethod.cs | 0 .../SDSL/EffectEvaluator.cs | 0 .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 0 .../SDSL/ShaderMixer.CBuffers.cs | 0 .../SDSL/ShaderMixer.Decorations.cs | 0 .../SDSL/ShaderMixer.MixinNode.cs | 0 .../SDSL/ShaderMixer.Reflection.cs | 0 .../SDSL/ShaderMixer.ShaderInfo.cs | 0 .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 0 .../SDSL/ShaderMixer.cs | 0 .../ShaderLoaderBase.cs | 0 .../Stride.Shaders.Compilers/SpirvOpt.cs | 0 .../SpirvTranslator.cs | 0 .../Stride.Shaders.Compilers.csproj | 0 .../native/spirv_to_dxil.dll | 0 .../Examples.Effects.cs | 0 .../Examples.Spirv.cs | 0 .../Stride.Shaders.Experiments/Examples.cs | 0 .../Stride.Shaders.Experiments/Program.cs | 0 .../Stride.Shaders.Experiments.csproj | 0 .../Stride.Shaders.Experiments/test.spv | Bin .../IntrinsicGenerator.cs | 0 .../Intrinsics/Goal.md | 0 .../Intrinsics/IntrinAST.cs | 0 .../Intrinsics/Parser.cs | 0 .../Stride.Shaders.Generators.Internal.csproj | 0 .../VisitorGenerator.cs | 0 .../EffectCodeWriter.cs | 0 .../EffectGenerator.cs | 0 .../ILRepack.targets | 0 .../Stride.Shaders.Generators.csproj | 0 .../Buffers/IMemoryInstruction.cs | 0 .../Buffers/OpData.cs | 0 .../Buffers/OpDataIndex.cs | 0 .../Buffers/SpirvBuffer.cs | 0 .../Buffers/SpirvBytecode.cs | 0 .../Extensions/spirv.sdsl.grammar-ext.json | 0 .../ISpirvElement.cs | 0 .../IWrapperInstruction.cs | 0 .../Information/InstructionInfo.Order.cs | 0 .../Information/InstructionInfo.cs | 0 .../Information/LogicalOperand.Size.cs | 0 .../Information/LogicalOperand.cs | 0 .../Information/LogicalOperandArray.cs | 0 .../Literals/EnumerantParameters.cs | 0 .../Literals/IFromSpirv.cs | 0 .../Literals/ILiteralNumber.cs | 0 .../Literals/IdMemorySemantics.cs | 0 .../Literals/IdRef.cs | 0 .../Literals/IdResult.cs | 0 .../Literals/IdResultType.cs | 0 .../Literals/IdScope.cs | 0 .../Literals/LiteralArray.cs | 0 .../Literals/LiteralFloat.cs | 0 .../Literals/LiteralInteger.cs | 0 .../Literals/LiteralString.cs | 0 .../Literals/LiteralValue.cs | 0 .../Literals/PairIdRefIdRef.cs | 0 .../Literals/PairIdRefLiteralInteger.cs | 0 .../Literals/PairLiteralIntegerIdRef.cs | 0 .../Literals/ParameterizedFlag.cs | 0 .../Literals/SpvOp.cs | 0 .../MemoryInstruction.cs | 0 .../OperandQuantifier.cs | 0 .../Parsing/InstructionEnumerator.cs | 0 .../Parsing/OpDataEnumerator.cs | 0 .../Parsing/OperandEnumerator.cs | 0 .../Parsing/RefHeader.cs | 0 .../Parsing/SpirvHeader.cs | 0 .../Parsing/SpirvReader.cs | 0 .../Stride.Shaders.Spirv.Core/SpvLiteral.cs | 0 .../Stride.Shaders.Spirv.Core.csproj | 0 .../WordsExtensions.cs | 0 .../Stride.Shaders.Spirv.Generators/Data.cs | 0 .../EquatableArray.cs | 0 .../EquatableDictionary.cs | 0 .../EquatableList.cs | 0 .../SPVGenerator.Buffers.cs | 0 .../SPVGenerator.EnumerantParams.cs | 0 .../SPVGenerator.Extensions.cs | 0 .../SPVGenerator.Helpers.Naming.cs | 0 .../SPVGenerator.Helpers.Preprocessing.cs | 0 .../SPVGenerator.Info.cs | 0 .../SPVGenerator.Instructions.cs | 0 .../SPVGenerator.SDSLOp.cs | 0 .../SPVGenerator.Specification.cs | 0 .../SPVGenerator.cs | 0 .../Stride.Shaders.Spirv.Generators.csproj | 0 .../FrameRenderer.D3D11.cs | 0 .../FrameRenderer.OpenGL.cs | 0 .../Stride.Shaders.Tests/FrameRenderer.cs | 0 .../Stride.Shaders.Tests/ParsingTests.cs | 0 .../{src => }/Stride.Shaders.Tests/Program.cs | 0 .../Stride.Shaders.Tests/RenderingTests.cs | 0 .../Stride.Shaders.Tests.csproj | 0 .../Stride.Shaders.Tests/TestHeaderParser.cs | 0 .../Stride.Shaders/Core/AssignOperators.cs | 0 .../Stride.Shaders/Core/EntryPoints.cs | 0 .../Core/IntrinsicsParameters.cs | 0 .../Stride.Shaders/Core/Node.Visitors.cs | 0 .../Stride.Shaders/Core/Operators.cs | 0 .../{src => }/Stride.Shaders/Core/Symbol.cs | 0 .../Stride.Shaders/Core/SymbolFrame.cs | 0 .../Stride.Shaders/Core/SymbolProvider.cs | 0 .../Core/SymbolTypes.Globals.cs | 0 .../Core/SymbolTypes.Visitors.cs | 0 .../Stride.Shaders/Core/SymbolTypes.cs | 0 .../Stride.Shaders/Parsing/ASTNode.cs | 0 .../Stride.Shaders/Parsing/Analysis/CFG.cs | 0 .../Parsing/Analysis/IStreamChecker.cs | 0 .../Stride.Shaders/Parsing/Analysis/ReadMe.md | 0 .../Stride.Shaders/Parsing/Analysis/SDIR.cs | 0 .../Parsing/Analysis/SymbolTable.cs | 0 .../Parsing/Analysis/TypeNameExtensions.cs | 0 .../Stride.Shaders/Parsing/Grammar.cs | 0 .../Stride.Shaders/Parsing/IParser.cs | 0 .../Stride.Shaders/Parsing/ParseResult.cs | 0 .../PreProcessing/CMacros/CodeFrame.cs | 0 .../CMacros/CodeFrameSnippets.cs | 0 .../PreProcessing/CMacros/CodeProcessor.cs | 0 .../PreProcessing/CMacros/CommentPhase.cs | 0 .../CMacros/IPreProcessorPhase.cs | 0 .../CMacros/LocationTranslator.cs | 0 .../PreProcessing/CommentProcessedCode.cs | 0 .../PreProcessing/MacroPreProcessor.cs | 0 .../PreProcessing/MemoryOwnerExtensions.cs | 0 .../Parsing/PreProcessing/TextLink.cs | 0 .../PreProcessing/TextLinkExtensions.cs | 0 .../Parsing/SDFX/AST/Effect.Flow.cs | 0 .../Parsing/SDFX/AST/Effect.Parameters.cs | 0 .../Stride.Shaders/Parsing/SDFX/AST/Effect.cs | 0 .../Parsing/SDFX/Parsers/EffectFileParsers.cs | 0 .../Parsing/SDFX/Parsers/EffectParser.cs | 0 .../EffectStatementParsers.Conditional.cs | 0 .../Parsers/EffectStatementParsers.Flow.cs | 0 .../SDFX/Parsers/EffectStatementParsers.cs | 0 .../Parsing/SDFX/Parsers/ParamsParsers.cs | 0 .../Parsing/SDFX/ShaderWriter.cs | 0 .../Parsing/SDSL/AST/AssignOperator.cs | 0 .../SDSL/AST/BufferMethodsImplementations.cs | 0 .../Parsing/SDSL/AST/Directives.cs | 0 .../Parsing/SDSL/AST/Expression.cs | 0 .../Parsing/SDSL/AST/IntrinsicCall.cs | 0 .../SDSL/AST/IntrinsicImplementations.cs | 0 .../SDSL/AST/IntrinsicTemplateExpander.cs | 0 .../Parsing/SDSL/AST/Literals.cs | 0 .../Parsing/SDSL/AST/Operator.cs | 0 .../Stride.Shaders/Parsing/SDSL/AST/Shader.cs | 0 .../Parsing/SDSL/AST/ShaderAttributes.cs | 0 .../SDSL/AST/ShaderElements.MethodOrMember.cs | 0 .../Parsing/SDSL/AST/ShaderElements.cs | 0 .../Parsing/SDSL/AST/ShaderGenericsValues.cs | 0 .../Parsing/SDSL/AST/Statements.Control.cs | 0 .../Parsing/SDSL/AST/Statements.Flow.cs | 0 .../Parsing/SDSL/AST/Statements.cs | 0 .../SDSL/AST/TextureMethodsImplementations.cs | 0 .../SDSL/Parsers/Common/CommonParsers.cs | 0 .../Parsing/SDSL/Parsers/Common/Delegates.cs | 0 .../SDSL/Parsers/Common/OptionalParser.cs | 0 .../Parsing/SDSL/Parsers/Common/Spaces.cs | 0 .../DirectiveBinaryParsers.cs | 0 .../DirectiveExpressions/DirectiveParsers.cs | 0 .../DirectivePrimaryExpressionParsers.cs | 0 .../DirectiveUnaryParsers.Prefix.cs | 0 .../DirectiveUnaryParsers.cs | 0 .../ExpressionParsers/BinaryParsers.cs | 0 .../PrimaryExpressionParsers.cs | 0 .../ExpressionParsers/UnaryParsers.Postfix.cs | 0 .../ExpressionParsers/UnaryParsers.Prefix.cs | 0 .../Parsers/LiteralParsers/LiteralParsers.cs | 0 .../Parsers/LiteralParsers/NumberParsers.cs | 0 .../SDSL/Parsers/LiteralParsers/Reserved.cs | 0 .../ShaderParsers/CompositionParsers.cs | 0 .../ShaderParsers/ShaderAttributeParsers.cs | 0 .../ShaderParsers/ShaderBufferParsers.cs | 0 .../ShaderParsers/ShaderClassParser.cs | 0 .../ShaderParsers/ShaderDataParsers.cs | 0 .../ShaderParsers/ShaderElementParsers.cs | 0 .../ShaderParsers/ShaderFileParsers.cs | 0 .../ShaderParsers/ShaderMethodParsers.cs | 0 .../Parsers/ShaderParsers/ShaderParameters.cs | 0 .../StatementParsers.Control.cs | 0 .../StatementParsers/StatementParsers.Flow.cs | 0 .../StatementParsers/StatementParsers.cs | 0 .../SDSL/Parsers/Terminals/Terminals.cs | 0 .../Stride.Shaders/Parsing/SDSLERR.cs | 0 .../Stride.Shaders/Parsing/SDSLParser.cs | 0 .../Parsing/Scanners/ErrorLocation.cs | 0 .../Parsing/Scanners/IScannableCode.cs | 0 .../Parsing/Scanners/IScanner.cs | 0 .../Parsing/Scanners/ScannableString.cs | 0 .../Parsing/Scanners/Scanner.cs | 0 .../Parsing/Scanners/ScannerGeneric.cs | 0 .../Parsing/Scanners/TextLocation.cs | 0 .../Spirv/Building/BasicBlocks.cs | 0 .../Spirv/Building/Builder.CBuffer.cs | 0 .../Spirv/Building/Builder.Class.cs | 0 .../Spirv/Building/Builder.Expressions.cs | 0 .../Spirv/Building/Builder.Flow.cs | 0 .../Spirv/Building/Builder.Functions.cs | 0 .../Stride.Shaders/Spirv/Building/Builder.cs | 0 .../Spirv/Building/CompilerUnit.cs | 0 .../Spirv/Building/Context.Constants.cs | 0 .../Spirv/Building/Context.ExtractBuffers.cs | 0 .../Stride.Shaders/Spirv/Building/Context.cs | 0 .../Spirv/Building/DictionaryPool.cs | 0 .../Spirv/Building/ExpressionExtensions.cs | 0 .../Stride.Shaders/Spirv/Building/Module.cs | 0 .../Spirv/Building/SpirvContext.Types.cs | 0 .../Spirv/Processing/BoundReducer.cs | 0 .../Spirv/Processing/CapabilitiesCompute.cs | 0 .../Spirv/Processing/CompressBuffer.cs | 0 .../Processing/FunctionVariableOrderer.cs | 0 .../Spirv/Processing/INanoPass.cs | 0 .../Spirv/Processing/IOReplace.cs | 0 .../Spirv/Processing/IOVariableDecorator.cs | 0 .../Spirv/Processing/IPostProcessorSubPass.cs | 0 .../Spirv/Processing/IdRefOffsetter.cs | 0 .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 0 .../Interfaces/Analysis/SemanticAnalyzer.cs | 0 .../Interfaces/Analysis/StreamAnalyzer.cs | 0 .../Interfaces/Cleanup/DeadCodeRemover.cs | 0 .../Interfaces/Cleanup/VariableMerger.cs | 0 .../Interfaces/Generation/BuiltinProcessor.cs | 0 .../Generation/EntryPointWrapperGenerator.cs | 0 .../Interfaces/InterfaceProcessor.cs | 0 .../Interfaces/Models/AnalysisResult.cs | 0 .../Interfaces/Models/LiveAnalysis.cs | 0 .../Interfaces/Models/ResourceInfo.cs | 0 .../Interfaces/Models/StreamVariableInfo.cs | 0 .../Interfaces/Models/VariableInfo.cs | 0 .../Transformation/MethodDuplicator.cs | 0 .../Transformation/StreamAccessPatcher.cs | 0 .../MemoryModelDuplicatesRemover.cs | 0 .../Spirv/Processing/MixinMerger.cs | 0 .../Spirv/Processing/PostProcessor.cs | 0 .../Spirv/Processing/SDSLOpRemover.cs | 0 .../Spirv/Processing/TypeDuplicatesRemover.cs | 0 .../Stride.Shaders/Spirv/Tools/Dis.cs | 0 .../Stride.Shaders/Spirv/Tools/Validator.cs | 0 .../Stride.Shaders/Spirv/thinking.md | 0 .../Stride.Shaders/Stride.Shaders.csproj | 0 .../Core/DataContractAttribute.cs | 0 .../Core/DataMemberAttribute.cs | 0 .../Core/DataMemberIgnoreAttribute.cs | 0 .../StrideImported/Core/DataMemberMode.cs | 0 .../Core/EnumerableExtensions.cs | 0 .../StrideImported/Core/ParameterKey.cs | 0 .../StrideImported/Core/ParameterKeyInfo.cs | 0 .../StrideImported/Core/SortedList.cs | 0 .../Core/StrideCoreExtensions.cs | 0 .../StrideImported/Graphics/Buffer.cs | 0 .../Graphics/CompareFunction.cs | 0 .../Graphics/SamplerStateDescription.cs | 0 .../Graphics/TextureAddressMode.cs | 0 .../StrideImported/Graphics/TextureFilter.cs | 0 .../StrideImported/Mathematics/Color4.cs | 0 .../ShadersReflection/ConstantBufferType.cs | 0 .../EffectConstantBufferDescription.cs | 0 .../ShadersReflection/EffectParameterClass.cs | 0 .../EffectParameterKeyInfo.cs | 0 .../ShadersReflection/EffectParameterType.cs | 0 .../ShadersReflection/EffectReflection.cs | 0 .../EffectResourceBindingDescription.cs | 0 .../EffectSamplerStateBinding.cs | 0 .../EffectTypeDescription.cs | 0 .../EffectTypeMemberDescription.cs | 0 .../EffectValueDescription.cs | 0 .../ShaderInputAttributeDescription.cs | 0 .../ShadersReflection/ShaderStage.cs | 0 .../ShaderStreamOutputDeclarationEntry.cs | 0 .../ShadersSource/HashSourceCollection.cs | 0 .../StrideImported/ShadersSource/ObjectId.cs | 0 .../ShadersSource/ObjectIdBuilder.cs | 0 .../ShadersSource/ShaderArraySource.cs | 0 .../ShadersSource/ShaderClassCode.cs | 0 .../ShadersSource/ShaderClassSource.cs | 0 .../ShadersSource/ShaderMacro.cs | 0 .../ShadersSource/ShaderMixinSource.cs | 0 .../ShadersSource/ShaderSource.cs | 0 .../ShadersSource/ShaderSourceCollection.cs | 0 .../StrideImported/ShadersSource/Utilities.cs | 0 .../Stride.Shaders/gen_intrin_README.md | 0 .../Stride.Shaders/gen_intrin_main.txt | 0 sources/shaders/src/Directory.Build.props | 5 - .../.avalonia-build-tasks/id | 1 - .../Stride.Shaders.AvaloniaViewer/App.axaml | 11 - .../App.axaml.cs | 23 -- .../MainWindow.axaml | 35 --- .../MainWindow.axaml.cs | 85 ------ .../Stride.Shaders.AvaloniaViewer/Program.cs | 21 -- .../Stride.Shaders.AvaloniaViewer.csproj | 37 --- .../app.manifest | 18 -- sources/shaders/src/Stride.Shaders.LSP/Foo.cs | 14 - .../Handlers/DidChangeWatchedFilesHandler.cs | 18 -- .../Handlers/FoldingRangeHandler.cs | 48 --- .../Handlers/HoverHandler.cs | 149 ---------- .../Handlers/SemanticTokensHandler.cs | 114 ------- .../Handlers/TextDocumentHandler.cs | 278 ------------------ .../shaders/src/Stride.Shaders.LSP/Program.cs | 158 ---------- .../Stride.Shaders.LSP/SDSL/ASTExtensions.cs | 21 -- .../Stride.Shaders.LSP.csproj | 31 -- 310 files changed, 8 insertions(+), 1090 deletions(-) rename {sources/shaders => build}/submodules/CppNet8 (100%) rename {sources/shaders => build}/submodules/SpirvHeaders (100%) rename {sources/shaders => build}/submodules/SpirvRegistry (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/Direct3D/DXC.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/Direct3D/FXC.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/ICompiler.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/MainMethod.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/SDSLC.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/ShaderLoaderBase.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SpirvOpt.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/SpirvTranslator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Compilers/native/spirv_to_dxil.dll (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/Examples.Effects.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/Examples.Spirv.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/Examples.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/Program.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Experiments/test.spv (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators.Internal/VisitorGenerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators/EffectCodeWriter.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators/EffectGenerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators/ILRepack.targets (100%) rename sources/shaders/{src => }/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Buffers/OpData.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/ISpirvElement.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IdRef.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IdResult.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/IdScope.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/MemoryInstruction.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/OperandQuantifier.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/SpvLiteral.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Core/WordsExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/Data.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/EquatableArray.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/EquatableList.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/SPVGenerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/FrameRenderer.D3D11.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/FrameRenderer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/ParsingTests.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/Program.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/RenderingTests.cs (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders.Tests/TestHeaderParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/AssignOperators.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/EntryPoints.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/IntrinsicsParameters.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/Node.Visitors.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/Operators.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/Symbol.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/SymbolFrame.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/SymbolProvider.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/SymbolTypes.Globals.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/SymbolTypes.Visitors.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Core/SymbolTypes.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/ASTNode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/CFG.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/ReadMe.md (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/SDIR.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/SymbolTable.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Grammar.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/IParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/ParseResult.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/TextLink.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/AST/Effect.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Directives.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Expression.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Literals.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Operator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Shader.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/Statements.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSLERR.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/SDSLParser.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/IScannableCode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/IScanner.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/ScannableString.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/Scanner.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Parsing/Scanners/TextLocation.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/BasicBlocks.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.Class.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.Expressions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.Flow.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.Functions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Builder.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/CompilerUnit.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Context.Constants.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Context.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/DictionaryPool.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/Module.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/BoundReducer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/CompressBuffer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/INanoPass.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/IOReplace.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/MixinMerger.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/PostProcessor.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Tools/Dis.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/Tools/Validator.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/Spirv/thinking.md (100%) rename sources/shaders/{src => }/Stride.Shaders/Stride.Shaders.csproj (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/DataMemberMode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/ParameterKey.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/SortedList.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Graphics/Buffer.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/Mathematics/Color4.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs (100%) rename sources/shaders/{src => }/Stride.Shaders/gen_intrin_README.md (100%) rename sources/shaders/{src => }/Stride.Shaders/gen_intrin_main.txt (100%) delete mode 100644 sources/shaders/src/Directory.Build.props delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/Program.cs delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj delete mode 100644 sources/shaders/src/Stride.Shaders.AvaloniaViewer/app.manifest delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Foo.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Program.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs delete mode 100644 sources/shaders/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj diff --git a/sources/shaders/submodules/CppNet8 b/build/submodules/CppNet8 similarity index 100% rename from sources/shaders/submodules/CppNet8 rename to build/submodules/CppNet8 diff --git a/sources/shaders/submodules/SpirvHeaders b/build/submodules/SpirvHeaders similarity index 100% rename from sources/shaders/submodules/SpirvHeaders rename to build/submodules/SpirvHeaders diff --git a/sources/shaders/submodules/SpirvRegistry b/build/submodules/SpirvRegistry similarity index 100% rename from sources/shaders/submodules/SpirvRegistry rename to build/submodules/SpirvRegistry diff --git a/sources/shaders/SDSL.sln b/sources/shaders/SDSL.sln index c2229b6baf..d3e3570259 100644 --- a/sources/shaders/SDSL.sln +++ b/sources/shaders/SDSL.sln @@ -5,23 +5,21 @@ VisualStudioVersion = 18.0.11222.15 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9B25B78A-8418-4161-99D6-5E84611BDA59}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "src\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{C61EE276-91AA-4EDB-9E19-8BD8321FE13D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{C61EE276-91AA-4EDB-9E19-8BD8321FE13D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "src\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{C723E631-41D8-4797-86C3-9D52711CC849}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{C723E631-41D8-4797-86C3-9D52711CC849}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders", "src\Stride.Shaders\Stride.Shaders.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders", "Stride.Shaders\Stride.Shaders.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "src\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.LSP", "src\Stride.Shaders.LSP\Stride.Shaders.LSP.csproj", "{4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{32B1203D-8160-455A-9F00-8097119B7EB4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Compilers", "src\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{32B1203D-8160-455A-9F00-8097119B7EB4}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Experiments", "src\Stride.Shaders.Experiments\Stride.Shaders.Experiments.csproj", "{11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators.Internal", "Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators.Internal", "src\Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{33AF20B6-38AC-D0DE-2CAA-8B27560F84E6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators", "src\Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators", "Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{4EEDDA27-A63C-4D7C-907B-B95ECAED3B11}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -81,18 +79,6 @@ Global {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x64.Build.0 = Release|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x86.ActiveCfg = Release|Any CPU {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}.Release|x86.Build.0 = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x64.ActiveCfg = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x64.Build.0 = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x86.ActiveCfg = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Debug|x86.Build.0 = Debug|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|Any CPU.Build.0 = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x64.ActiveCfg = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x64.Build.0 = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x86.ActiveCfg = Release|Any CPU - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5}.Release|x86.Build.0 = Release|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|Any CPU.Build.0 = Debug|Any CPU {32B1203D-8160-455A-9F00-8097119B7EB4}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -150,7 +136,6 @@ Global {C723E631-41D8-4797-86C3-9D52711CC849} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {595979CB-8447-4EA0-9A9F-0CBD8B9442BB} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7} = {9B25B78A-8418-4161-99D6-5E84611BDA59} - {4F8838DA-16F0-4EC0-A0A4-8F89F47E35C5} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {32B1203D-8160-455A-9F00-8097119B7EB4} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {11FFBEAC-C3B8-49FA-9C6A-B0DDDA48EBE6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} {33AF20B6-38AC-D0DE-2CAA-8B27560F84E6} = {9B25B78A-8418-4161-99D6-5E84611BDA59} diff --git a/sources/shaders/src/Stride.Shaders.Compilers/Direct3D/DXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/Direct3D/DXC.cs rename to sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/Direct3D/FXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/Direct3D/FXC.cs rename to sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs rename to sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/ICompiler.cs b/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/ICompiler.cs rename to sources/shaders/Stride.Shaders.Compilers/ICompiler.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/MainMethod.cs b/sources/shaders/Stride.Shaders.Compilers/MainMethod.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/MainMethod.cs rename to sources/shaders/Stride.Shaders.Compilers/MainMethod.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/SDSLC.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs rename to sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/ShaderLoaderBase.cs rename to sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SpirvOpt.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SpirvOpt.cs rename to sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/SpirvTranslator.cs rename to sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs diff --git a/sources/shaders/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj rename to sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj diff --git a/sources/shaders/src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll similarity index 100% rename from sources/shaders/src/Stride.Shaders.Compilers/native/spirv_to_dxil.dll rename to sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll diff --git a/sources/shaders/src/Stride.Shaders.Experiments/Examples.Effects.cs b/sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/Examples.Effects.cs rename to sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs diff --git a/sources/shaders/src/Stride.Shaders.Experiments/Examples.Spirv.cs b/sources/shaders/Stride.Shaders.Experiments/Examples.Spirv.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/Examples.Spirv.cs rename to sources/shaders/Stride.Shaders.Experiments/Examples.Spirv.cs diff --git a/sources/shaders/src/Stride.Shaders.Experiments/Examples.cs b/sources/shaders/Stride.Shaders.Experiments/Examples.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/Examples.cs rename to sources/shaders/Stride.Shaders.Experiments/Examples.cs diff --git a/sources/shaders/src/Stride.Shaders.Experiments/Program.cs b/sources/shaders/Stride.Shaders.Experiments/Program.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/Program.cs rename to sources/shaders/Stride.Shaders.Experiments/Program.cs diff --git a/sources/shaders/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj rename to sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj diff --git a/sources/shaders/src/Stride.Shaders.Experiments/test.spv b/sources/shaders/Stride.Shaders.Experiments/test.spv similarity index 100% rename from sources/shaders/src/Stride.Shaders.Experiments/test.spv rename to sources/shaders/Stride.Shaders.Experiments/test.spv diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs rename to sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md rename to sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Goal.md diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs rename to sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs rename to sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj b/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj rename to sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj diff --git a/sources/shaders/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators.Internal/VisitorGenerator.cs rename to sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators/EffectCodeWriter.cs rename to sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators/EffectGenerator.cs b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators/EffectGenerator.cs rename to sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Generators/ILRepack.targets b/sources/shaders/Stride.Shaders.Generators/ILRepack.targets similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators/ILRepack.targets rename to sources/shaders/Stride.Shaders.Generators/ILRepack.targets diff --git a/sources/shaders/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj rename to sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/OpData.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json rename to sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/ISpirvElement.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.Size.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IFromSpirv.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/ILiteralNumber.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdRef.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdResult.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/IdScope.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralInteger.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/MemoryInstruction.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/OperandQuantifier.cs b/sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/OperandQuantifier.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/InstructionEnumerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/RefHeader.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/SpvLiteral.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj rename to sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs b/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Core/WordsExtensions.cs rename to sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/Data.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/Data.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableArray.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableList.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/EquatableList.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Specification.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/SPVGenerator.cs rename to sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs diff --git a/sources/shaders/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj rename to sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj diff --git a/sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.D3D11.cs rename to sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs rename to sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/FrameRenderer.cs rename to sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/ParsingTests.cs b/sources/shaders/Stride.Shaders.Tests/ParsingTests.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/ParsingTests.cs rename to sources/shaders/Stride.Shaders.Tests/ParsingTests.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/Program.cs b/sources/shaders/Stride.Shaders.Tests/Program.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/Program.cs rename to sources/shaders/Stride.Shaders.Tests/Program.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/RenderingTests.cs rename to sources/shaders/Stride.Shaders.Tests/RenderingTests.cs diff --git a/sources/shaders/src/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj rename to sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj diff --git a/sources/shaders/src/Stride.Shaders.Tests/TestHeaderParser.cs b/sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders.Tests/TestHeaderParser.cs rename to sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/AssignOperators.cs b/sources/shaders/Stride.Shaders/Core/AssignOperators.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/AssignOperators.cs rename to sources/shaders/Stride.Shaders/Core/AssignOperators.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/EntryPoints.cs b/sources/shaders/Stride.Shaders/Core/EntryPoints.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/EntryPoints.cs rename to sources/shaders/Stride.Shaders/Core/EntryPoints.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/IntrinsicsParameters.cs b/sources/shaders/Stride.Shaders/Core/IntrinsicsParameters.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/IntrinsicsParameters.cs rename to sources/shaders/Stride.Shaders/Core/IntrinsicsParameters.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/Node.Visitors.cs b/sources/shaders/Stride.Shaders/Core/Node.Visitors.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/Node.Visitors.cs rename to sources/shaders/Stride.Shaders/Core/Node.Visitors.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/Operators.cs b/sources/shaders/Stride.Shaders/Core/Operators.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/Operators.cs rename to sources/shaders/Stride.Shaders/Core/Operators.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/Symbol.cs b/sources/shaders/Stride.Shaders/Core/Symbol.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/Symbol.cs rename to sources/shaders/Stride.Shaders/Core/Symbol.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/SymbolFrame.cs b/sources/shaders/Stride.Shaders/Core/SymbolFrame.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/SymbolFrame.cs rename to sources/shaders/Stride.Shaders/Core/SymbolFrame.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/SymbolProvider.cs b/sources/shaders/Stride.Shaders/Core/SymbolProvider.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/SymbolProvider.cs rename to sources/shaders/Stride.Shaders/Core/SymbolProvider.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/SymbolTypes.Globals.cs b/sources/shaders/Stride.Shaders/Core/SymbolTypes.Globals.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/SymbolTypes.Globals.cs rename to sources/shaders/Stride.Shaders/Core/SymbolTypes.Globals.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs b/sources/shaders/Stride.Shaders/Core/SymbolTypes.Visitors.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/SymbolTypes.Visitors.cs rename to sources/shaders/Stride.Shaders/Core/SymbolTypes.Visitors.cs diff --git a/sources/shaders/src/Stride.Shaders/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders/Core/SymbolTypes.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Core/SymbolTypes.cs rename to sources/shaders/Stride.Shaders/Core/SymbolTypes.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/ASTNode.cs b/sources/shaders/Stride.Shaders/Parsing/ASTNode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/ASTNode.cs rename to sources/shaders/Stride.Shaders/Parsing/ASTNode.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/CFG.cs b/sources/shaders/Stride.Shaders/Parsing/Analysis/CFG.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/CFG.cs rename to sources/shaders/Stride.Shaders/Parsing/Analysis/CFG.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs b/sources/shaders/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs rename to sources/shaders/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/ReadMe.md b/sources/shaders/Stride.Shaders/Parsing/Analysis/ReadMe.md similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/ReadMe.md rename to sources/shaders/Stride.Shaders/Parsing/Analysis/ReadMe.md diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/SDIR.cs b/sources/shaders/Stride.Shaders/Parsing/Analysis/SDIR.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/SDIR.cs rename to sources/shaders/Stride.Shaders/Parsing/Analysis/SDIR.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders/Parsing/Analysis/SymbolTable.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/SymbolTable.cs rename to sources/shaders/Stride.Shaders/Parsing/Analysis/SymbolTable.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs b/sources/shaders/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs rename to sources/shaders/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Grammar.cs b/sources/shaders/Stride.Shaders/Parsing/Grammar.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Grammar.cs rename to sources/shaders/Stride.Shaders/Parsing/Grammar.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/IParser.cs b/sources/shaders/Stride.Shaders/Parsing/IParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/IParser.cs rename to sources/shaders/Stride.Shaders/Parsing/IParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/ParseResult.cs b/sources/shaders/Stride.Shaders/Parsing/ParseResult.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/ParseResult.cs rename to sources/shaders/Stride.Shaders/Parsing/ParseResult.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/TextLink.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLink.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/TextLink.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLink.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs b/sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs rename to sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/AST/Effect.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs b/sources/shaders/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs rename to sources/shaders/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Directives.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Directives.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Directives.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Expression.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Expression.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Expression.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Literals.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Literals.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Literals.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Operator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Operator.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Operator.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Shader.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Shader.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Shader.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/Statements.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs b/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSLERR.cs b/sources/shaders/Stride.Shaders/Parsing/SDSLERR.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSLERR.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSLERR.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/SDSLParser.cs b/sources/shaders/Stride.Shaders/Parsing/SDSLParser.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/SDSLParser.cs rename to sources/shaders/Stride.Shaders/Parsing/SDSLParser.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/IScannableCode.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/IScannableCode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/IScannableCode.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/IScannableCode.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/IScanner.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/IScanner.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/IScanner.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/IScanner.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/ScannableString.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/ScannableString.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/ScannableString.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/ScannableString.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/Scanner.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/Scanner.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/Scanner.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/Scanner.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs diff --git a/sources/shaders/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs b/sources/shaders/Stride.Shaders/Parsing/Scanners/TextLocation.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Parsing/Scanners/TextLocation.cs rename to sources/shaders/Stride.Shaders/Parsing/Scanners/TextLocation.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/sources/shaders/Stride.Shaders/Spirv/Building/BasicBlocks.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/BasicBlocks.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/BasicBlocks.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Class.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Class.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.Class.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Expressions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Expressions.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.Expressions.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Flow.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Flow.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.Flow.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Functions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.Functions.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.Functions.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Builder.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Builder.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Builder.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/sources/shaders/Stride.Shaders/Spirv/Building/CompilerUnit.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/CompilerUnit.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/CompilerUnit.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Context.Constants.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Context.Constants.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Context.Constants.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Context.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Context.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Context.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/DictionaryPool.cs b/sources/shaders/Stride.Shaders/Spirv/Building/DictionaryPool.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/DictionaryPool.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/DictionaryPool.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/sources/shaders/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/Module.cs b/sources/shaders/Stride.Shaders/Spirv/Building/Module.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/Module.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/Module.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs rename to sources/shaders/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/BoundReducer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/BoundReducer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/BoundReducer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/CompressBuffer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/CompressBuffer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/CompressBuffer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/INanoPass.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/INanoPass.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/INanoPass.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/INanoPass.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/IOReplace.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/IOReplace.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/IOReplace.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/IOReplace.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/MixinMerger.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/MixinMerger.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/MixinMerger.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/PostProcessor.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/PostProcessor.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/PostProcessor.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs rename to sources/shaders/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders/Spirv/Tools/Dis.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Tools/Dis.cs rename to sources/shaders/Stride.Shaders/Spirv/Tools/Dis.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders/Spirv/Tools/Validator.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/Tools/Validator.cs rename to sources/shaders/Stride.Shaders/Spirv/Tools/Validator.cs diff --git a/sources/shaders/src/Stride.Shaders/Spirv/thinking.md b/sources/shaders/Stride.Shaders/Spirv/thinking.md similarity index 100% rename from sources/shaders/src/Stride.Shaders/Spirv/thinking.md rename to sources/shaders/Stride.Shaders/Spirv/thinking.md diff --git a/sources/shaders/src/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj similarity index 100% rename from sources/shaders/src/Stride.Shaders/Stride.Shaders.csproj rename to sources/shaders/Stride.Shaders/Stride.Shaders.csproj diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/DataMemberMode.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/ParameterKey.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/ParameterKey.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/SortedList.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/SortedList.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs rename to sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Graphics/Buffer.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Graphics/Buffer.cs rename to sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs rename to sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs rename to sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs rename to sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/Mathematics/Color4.cs b/sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/Mathematics/Color4.cs rename to sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs diff --git a/sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs similarity index 100% rename from sources/shaders/src/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs rename to sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs diff --git a/sources/shaders/src/Stride.Shaders/gen_intrin_README.md b/sources/shaders/Stride.Shaders/gen_intrin_README.md similarity index 100% rename from sources/shaders/src/Stride.Shaders/gen_intrin_README.md rename to sources/shaders/Stride.Shaders/gen_intrin_README.md diff --git a/sources/shaders/src/Stride.Shaders/gen_intrin_main.txt b/sources/shaders/Stride.Shaders/gen_intrin_main.txt similarity index 100% rename from sources/shaders/src/Stride.Shaders/gen_intrin_main.txt rename to sources/shaders/Stride.Shaders/gen_intrin_main.txt diff --git a/sources/shaders/src/Directory.Build.props b/sources/shaders/src/Directory.Build.props deleted file mode 100644 index c1f59a0925..0000000000 --- a/sources/shaders/src/Directory.Build.props +++ /dev/null @@ -1,5 +0,0 @@ - - - $(MSBuildThisFileDirectory)\..\..\stride - - \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id deleted file mode 100644 index 343510a1ed..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/.avalonia-build-tasks/id +++ /dev/null @@ -1 +0,0 @@ -(q*KPE* \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml deleted file mode 100644 index d55859486d..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs deleted file mode 100644 index 772587a887..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/App.axaml.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Avalonia; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Markup.Xaml; - -namespace Stride.Shaders.AvaloniaViewer; - -public partial class App : Application -{ - public override void Initialize() - { - AvaloniaXamlLoader.Load(this); - } - - public override void OnFrameworkInitializationCompleted() - { - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) - { - desktop.MainWindow = new MainWindow(); - } - - base.OnFrameworkInitializationCompleted(); - } -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml deleted file mode 100644 index 9f959733fe..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs deleted file mode 100644 index 485b81f9eb..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/MainWindow.axaml.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.NetworkInformation; -using System.Reflection; -using System.Text.Json; -using Avalonia.Controls; -using Avalonia.Controls.Templates; -using Avalonia.Data; -using Avalonia.Interactivity; -using AvaloniaEdit; -using AvaloniaEdit.Document; -using AvaloniaEdit.TextMate; -using Silk.NET.Shaderc; -using Silk.NET.SPIRV.Cross; -using Stride.Shaders.Compilers; -using TextMateSharp.Grammars; -using TextMateSharp.Internal.Grammars.Parser; -using TextMateSharp.Internal.Types; -using TextMateSharp.Registry; -using TextMateSharp.Themes; - - - -namespace Stride.Shaders.AvaloniaViewer; - -public partial class MainWindow : Window -{ - public MainWindow() - { - InitializeComponent(); - var editor = this.FindControl("ShaderEditor") ?? throw new NotImplementedException(); - editor.Text = @"struct PSInput -{ - float4 color : COLOR; -}; - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} -"; - var options = new RegistryOptions(ThemeName.Dark); - //Initial setup of TextMate. - var textMateInstallation = editor.InstallTextMate(options); - - textMateInstallation.SetGrammar(options.GetScopeByLanguageId(options.GetLanguageByExtension(".hlsl").Id)); - - - - } - - public void Recompile(object source, EventArgs args) - { - var editor = this.FindControl("ShaderEditor") ?? throw new NotImplementedException(); - var other = this.FindControl("OutputEditor") ?? throw new NotImplementedException(); - if(string.IsNullOrEmpty(editor.Text)) - editor.Text = @"struct PSInput -{ - float4 color : COLOR; -}; - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} -"; - try - { - other.Text = SpirvOptimizer.Translate(editor.Text, "PSMain", SourceLanguage.Hlsl, Backend.Glsl); - } - catch(Exception e) - { - other.Text = e.Message; - } - finally - { - other.Text = ""; - } - - } - - -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Program.cs b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Program.cs deleted file mode 100644 index aef9dc2f27..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Avalonia; -using System; - -namespace Stride.Shaders.AvaloniaViewer; - -class Program -{ - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. - [STAThread] - public static void Main(string[] args) => BuildAvaloniaApp() - .StartWithClassicDesktopLifetime(args); - - // Avalonia configuration, don't remove; also used by visual designer. - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .UsePlatformDetect() - .WithInterFont() - .LogToTrace(); -} diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj deleted file mode 100644 index c8059d76d5..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/Stride.Shaders.AvaloniaViewer.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - WinExe - net9.0 - enable - true - app.manifest - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/app.manifest b/sources/shaders/src/Stride.Shaders.AvaloniaViewer/app.manifest deleted file mode 100644 index 0b64ebc7a9..0000000000 --- a/sources/shaders/src/Stride.Shaders.AvaloniaViewer/app.manifest +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - diff --git a/sources/shaders/src/Stride.Shaders.LSP/Foo.cs b/sources/shaders/src/Stride.Shaders.LSP/Foo.cs deleted file mode 100644 index 0437c8ce57..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Foo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.Extensions.Logging; - -namespace Stride.Shaders.Parsing.LSP; - - -internal class Foo(ILogger logger) -{ - private readonly ILogger _logger = logger; - - public void SayFoo() - { - _logger.LogInformation("Fooooo!"); - } -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs b/sources/shaders/src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs deleted file mode 100644 index ac6d667806..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Handlers/DidChangeWatchedFilesHandler.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using MediatR; -using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; - -namespace Stride.Shaders.Parsing.LSP; - - -internal class DidChangeWatchedFilesHandler : IDidChangeWatchedFilesHandler -{ - public DidChangeWatchedFilesRegistrationOptions GetRegistrationOptions() => new DidChangeWatchedFilesRegistrationOptions(); - - public Task Handle(DidChangeWatchedFilesParams request, CancellationToken cancellationToken) => Unit.Task; - - public DidChangeWatchedFilesRegistrationOptions GetRegistrationOptions(DidChangeWatchedFilesCapability capability, ClientCapabilities clientCapabilities) => new DidChangeWatchedFilesRegistrationOptions(); -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs b/sources/shaders/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs deleted file mode 100644 index bb07ec0395..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Handlers/FoldingRangeHandler.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Document; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; - - -namespace Stride.Shaders.Parsing.LSP; - -internal class FoldingRangeHandler : IFoldingRangeHandler -{ - public FoldingRangeRegistrationOptions GetRegistrationOptions() => - new FoldingRangeRegistrationOptions - { - DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") - }; - - public Task?> Handle( - FoldingRangeRequestParam request, - CancellationToken cancellationToken - ) - { - var result = SDSLParser.Parse(File.ReadAllText(request.TextDocument.Uri.GetFileSystemPath())); - if (result.AST is ShaderFile sf && sf.Namespaces.Count > 0) - { - var ns = sf.Namespaces.First(); - return Task.FromResult?>( - new Container( - new FoldingRange - { - StartLine = ns.Info.Line, - EndLine = ns.Info.EndLine, - StartCharacter = ns.Info.Column, - EndCharacter = ns.Info.EndColumn, - Kind = FoldingRangeKind.Region - } - ) - ); - } - - return Task.FromResult?>(null); - } - - public FoldingRangeRegistrationOptions GetRegistrationOptions(FoldingRangeCapability capability, ClientCapabilities clientCapabilities) => new FoldingRangeRegistrationOptions - { - DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") - }; -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs b/sources/shaders/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs deleted file mode 100644 index 6e0f621eeb..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Handlers/HoverHandler.cs +++ /dev/null @@ -1,149 +0,0 @@ -using Microsoft.Extensions.Logging; -using OmniSharp.Extensions.LanguageServer.Protocol; -using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Document; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.LSP; - - - -public class HoverHandler(ILogger logger) : HoverHandlerBase -{ - - ILogger _logger = logger; - public override async Task Handle(HoverParams request, CancellationToken cancellationToken) - { - var content = MonoGamePreProcessor.Run( - await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(request.TextDocument.Uri) ?? "", cancellationToken).ConfigureAwait(false), - Path.GetFileName(DocumentUri.GetFileSystemPath(request.TextDocument.Uri))! - ); - var result = SDSLParser.Parse(content); - if (result.AST is ShaderFile sf && sf.Namespaces.Count > 0) - { - if (ComputeIntersection(request.Position, sf, out var description)) - { - return new Hover - { - Contents = description - }; - } - else return new Hover - { - Contents = new($"Hovering at : {request.Position}") - }; - } - return null; - } - - protected override HoverRegistrationOptions CreateRegistrationOptions(HoverCapability capability, ClientCapabilities clientCapabilities) - { - return new HoverRegistrationOptions - { - DocumentSelector = TextDocumentSelector.ForLanguage("sdsl"), - WorkDoneProgress = true - }; - } - - bool ComputeIntersection(Position position, Node node, out MarkedStringsOrMarkupContent description) - { - description = null!; - if (node is ShaderFile sf) - { - foreach (var ns in sf.Namespaces) - if (ns.Intersects(position)) - return ComputeIntersection(position, ns, out description); - foreach (var e in sf.RootDeclarations) - if (e.Intersects(position)) - return ComputeIntersection(position, e, out description); - } - else if (node is ShaderNamespace sn) - { - if (sn.Namespace is not null && sn.Namespace.Intersects(position)) - { - description = new(sn.Namespace.ToString()); - return true; - } - foreach (var decl in sn.Declarations) - { - if (decl.Intersects(position)) - return ComputeIntersection(position, decl, out description); - } - } - else if (node is ShaderClass sc) - { - if (sc.Name.Intersects(position)) - { - description = new($"shader {sc.Name}"); - return true; - } - foreach (var parent in sc.Mixins) - if (parent.Intersects(position)) - { - description = new($"mixin {parent}"); - return true; - } - foreach (var e in sc.Elements) - if (e.Intersects(position)) - return ComputeIntersection(position, e, out description); - } - else if (node is ShaderMember member) - { - if (member.TypeName.Intersects(position)) - { - description = new($"{member.TypeName}"); - return true; - } - else - { - description = new( new MarkedString("SDSL", $"{member.Info.Text}")); - return true; - } - } - else if (node is ShaderMethod method) - { - if (method.Name.Intersects(position)) - { - description = new($"method {method.Name}"); - return true; - } - foreach (var arg in method.Parameters) - if (arg.Intersects(position)) - { - description = new($"argument {arg.Name}"); - return true; - } - if (method.Body is not null) - foreach (var s in method.Body.Statements) - if (s.Intersects(position)) - return ComputeIntersection(position, s, out description); - } - return false; - } - - //static bool ComputeIntersection(Position position, ShaderFile file, out string description) - //{ - // description = ""; - // foreach (var ns in file.Namespaces) - // { - // if (ns.Namespace is not null && ns.Namespace.Intersects(position)) - // { - // description = ns.Namespace.ToString(); - // return true; - // } - // else - // { - // foreach (var decl in ns.Declarations) - // { - // if (decl is ShaderClass sclass && sclass.Intersects(position)) - // { - // description = $"shader {sclass.Name}"; - // return true; - // } - // } - // } - // } - // return false; - //} -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs b/sources/shaders/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs deleted file mode 100644 index b3bd01f2fb..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Handlers/SemanticTokensHandler.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using OmniSharp.Extensions.LanguageServer.Protocol; -using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Document; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; - - -namespace Stride.Shaders.Parsing.LSP; - -public class SemanticTokensHandler(ILogger logger) : SemanticTokensHandlerBase -{ - private readonly ILogger _logger = logger; - - public override async Task Handle( - SemanticTokensParams request, CancellationToken cancellationToken - ) - { - var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); - return result; - } - - public override async Task Handle( - SemanticTokensRangeParams request, CancellationToken cancellationToken - ) - { - var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); - return result; - } - - public override async Task Handle( - SemanticTokensDeltaParams request, - CancellationToken cancellationToken - ) - { - var result = await base.Handle(request, cancellationToken).ConfigureAwait(false); - return result; - } - - protected override async Task Tokenize( - SemanticTokensBuilder builder, ITextDocumentIdentifierParams identifier, - CancellationToken cancellationToken - ) - { - using var typesEnumerator = RotateEnum(SemanticTokenType.Defaults).GetEnumerator(); - using var modifiersEnumerator = RotateEnum(SemanticTokenModifier.Defaults).GetEnumerator(); - // you would normally get this from a common source that is managed by current open editor, current active editor, etc. - var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(identifier), cancellationToken).ConfigureAwait(false); - await Task.Yield(); - - var result = SDSLParser.Parse(content); - if(result.AST is ShaderFile sf && sf.Namespaces.Count > 0) - { - var ns = sf.Namespaces[0]; - _logger.LogInformation($"Handling namespace : {ns.Namespace}"); - builder.Push(ns.Info.Line,ns.Info.Column, ns.Info.Length, SemanticTokenType.Namespace, SemanticTokenModifier.Declaration); - } - - // foreach (var (line, text) in content.Split('\n').Select((text, line) => (line, text))) - // { - // var parts = text.TrimEnd().Split(';', ' ', '.', '"', '(', ')'); - // var index = 0; - // foreach (var part in parts) - // { - // typesEnumerator.MoveNext(); - // modifiersEnumerator.MoveNext(); - // if (string.IsNullOrWhiteSpace(part)) continue; - // index = text.IndexOf(part, index, StringComparison.Ordinal); - // builder.Push(line, index, part.Length, typesEnumerator.Current, modifiersEnumerator.Current); - // } - // } - } - - protected override Task - GetSemanticTokensDocument(ITextDocumentIdentifierParams @params, CancellationToken cancellationToken) - { - return Task.FromResult(new SemanticTokensDocument(RegistrationOptions.Legend)); - } - - - private IEnumerable RotateEnum(IEnumerable values) - { - while (true) - { - foreach (var item in values) - yield return item; - } - } - - protected override SemanticTokensRegistrationOptions CreateRegistrationOptions( - SemanticTokensCapability capability, ClientCapabilities clientCapabilities - ) - { - return new SemanticTokensRegistrationOptions - { - DocumentSelector = TextDocumentSelector.ForLanguage("sdsl"), - Legend = new SemanticTokensLegend - { - TokenModifiers = capability.TokenModifiers, - TokenTypes = capability.TokenTypes - }, - Full = new SemanticTokensCapabilityRequestFull - { - Delta = true - }, - Range = true - }; - } -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs b/sources/shaders/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs deleted file mode 100644 index f12fe6669e..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Handlers/TextDocumentHandler.cs +++ /dev/null @@ -1,278 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using MediatR; -using Microsoft.Extensions.Logging; -using OmniSharp.Extensions.LanguageServer.Protocol; -using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Document; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using OmniSharp.Extensions.LanguageServer.Protocol.Progress; -using OmniSharp.Extensions.LanguageServer.Protocol.Server; -using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities; -using OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone; -using OmniSharp.Extensions.LanguageServer.Protocol.Workspace; -using Serilog; -using Range = OmniSharp.Extensions.LanguageServer.Protocol.Models.Range; - -namespace Stride.Shaders.Parsing.LSP; - -internal class TextDocumentHandler : TextDocumentSyncHandlerBase -{ - private readonly ILogger _logger; - private readonly ILanguageServerConfiguration _configuration; - - private readonly TextDocumentSelector _textDocumentSelector = new( - new TextDocumentFilter - { - Pattern = "**/*.sdsl" - } - ); - - public TextDocumentHandler(ILogger logger, Foo foo, ILanguageServerConfiguration configuration) - { - _logger = logger; - _configuration = configuration; - foo.SayFoo(); - } - - public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Full; - - public override Task Handle(DidChangeTextDocumentParams notification, CancellationToken token) - { - // _logger.LogCritical("Critical"); - // _logger.LogDebug("Debug"); - // _logger.LogTrace("Trace"); - // _logger.LogInformation("Hello world!"); - return Unit.Task; - } - - public override async Task Handle(DidOpenTextDocumentParams notification, CancellationToken token) - { - await Task.Yield(); - _logger.LogInformation("Hello world!"); - await _configuration.GetScopedConfiguration(notification.TextDocument.Uri, token).ConfigureAwait(false); - return Unit.Value; - } - - public override Task Handle(DidCloseTextDocumentParams notification, CancellationToken token) - { - if (_configuration.TryGetScopedConfiguration(notification.TextDocument.Uri, out var disposable)) - { - disposable.Dispose(); - } - - return Unit.Task; - } - - public override Task Handle(DidSaveTextDocumentParams notification, CancellationToken token) => Unit.Task; - - protected override TextDocumentSyncRegistrationOptions CreateRegistrationOptions(TextSynchronizationCapability capability, ClientCapabilities clientCapabilities) => new TextDocumentSyncRegistrationOptions() - { - DocumentSelector = _textDocumentSelector, - Change = Change, - Save = new SaveOptions() { IncludeText = true } - }; - - public override TextDocumentAttributes GetTextDocumentAttributes(DocumentUri uri) => new TextDocumentAttributes(uri, "csharp"); -} - -internal class MyDocumentSymbolHandler : IDocumentSymbolHandler -{ - public async Task Handle( - DocumentSymbolParams request, - CancellationToken cancellationToken - ) - { - // you would normally get this from a common source that is managed by current open editor, current active editor, etc. - var content = await File.ReadAllTextAsync(DocumentUri.GetFileSystemPath(request), cancellationToken).ConfigureAwait(false); - var lines = content.Split('\n'); - var symbols = new List(); - - var result = SDSLParser.Parse(content); - if (result.AST is ShaderNamespace nsp) - { - Log.Information($"{nsp.NamespacePath} is being treated"); - symbols.Add( - new DocumentSymbol() - { - Kind = SymbolKind.Namespace, - Name = string.Join(".", nsp.NamespacePath.Select(x => x.Name)), - Range = new Range(nsp.Info.Line, nsp.Info.Column, nsp.Info.EndLine, nsp.Info.EndColumn) - } - ); - } - - // for (var lineIndex = 0; lineIndex < lines.Length; lineIndex++) - // { - // var line = lines[lineIndex]; - // var parts = line.Split(' ', '.', '(', ')', '{', '}', '[', ']', ';'); - // var currentCharacter = 0; - // foreach (var part in parts) - // { - // if (string.IsNullOrWhiteSpace(part)) - // { - // currentCharacter += part.Length + 1; - // continue; - // } - - // symbols.Add( - // new DocumentSymbol - // { - // Detail = part, - // Deprecated = true, - // Kind = SymbolKind.Field, - // Tags = new[] { SymbolTag.Deprecated }, - // Range = new Range( - // new Position(lineIndex, currentCharacter), - // new Position(lineIndex, currentCharacter + part.Length) - // ), - // SelectionRange = - // new Range( - // new Position(lineIndex, currentCharacter), - // new Position(lineIndex, currentCharacter + part.Length) - // ), - // Name = part - // } - // ); - // currentCharacter += part.Length + 1; - // } - // } - - // await Task.Delay(2000, cancellationToken); - return symbols; - } - - public DocumentSymbolRegistrationOptions GetRegistrationOptions(DocumentSymbolCapability capability, ClientCapabilities clientCapabilities) => new DocumentSymbolRegistrationOptions - { - DocumentSelector = TextDocumentSelector.ForLanguage("sdsl") - }; -} - -internal class MyWorkspaceSymbolsHandler : IWorkspaceSymbolsHandler -{ - private readonly IServerWorkDoneManager _serverWorkDoneManager; - private readonly IProgressManager _progressManager; - private readonly ILogger _logger; - - public MyWorkspaceSymbolsHandler(IServerWorkDoneManager serverWorkDoneManager, IProgressManager progressManager, ILogger logger) - { - _serverWorkDoneManager = serverWorkDoneManager; - _progressManager = progressManager; - _logger = logger; - } - - public async Task> Handle( - WorkspaceSymbolParams request, - CancellationToken cancellationToken - ) - { - using var reporter = _serverWorkDoneManager.For( - request, new WorkDoneProgressBegin - { - Cancellable = true, - Message = "This might take a while...", - Title = "Some long task....", - Percentage = 0 - } - ); - using var partialResults = _progressManager.For(request, cancellationToken); - if (partialResults != null) - { - await Task.Delay(2000, cancellationToken).ConfigureAwait(false); - - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 20 - } - ); - await Task.Delay(500, cancellationToken).ConfigureAwait(false); - - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 40 - } - ); - await Task.Delay(500, cancellationToken).ConfigureAwait(false); - - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 50 - } - ); - await Task.Delay(500, cancellationToken).ConfigureAwait(false); - - partialResults.OnNext( - [ - new WorkspaceSymbol { - ContainerName = "Partial Container", - Kind = SymbolKind.Constant, - Location = new Location { - Range = new Range( - new Position(2, 1), - new Position(2, 10) - ) - }, - Name = "Partial name" - } - ] - ); - - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 70 - } - ); - await Task.Delay(500, cancellationToken).ConfigureAwait(false); - - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 90 - } - ); - - partialResults.OnCompleted(); - return Array.Empty(); - } - - try - { - return new[] { - new WorkspaceSymbol { - ContainerName = "Container", - Kind = SymbolKind.Constant, - Location = new Location { - Range = new Range( - new Position(1, 1), - new Position(1, 10) - ) - }, - Name = "name" - } - }; - } - finally - { - reporter.OnNext( - new WorkDoneProgressReport - { - Cancellable = true, - Percentage = 100 - } - ); - } - } - - public WorkspaceSymbolRegistrationOptions GetRegistrationOptions(WorkspaceSymbolCapability capability, ClientCapabilities clientCapabilities) => new(); -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Program.cs b/sources/shaders/src/Stride.Shaders.LSP/Program.cs deleted file mode 100644 index 41f51a2e19..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Program.cs +++ /dev/null @@ -1,158 +0,0 @@ -// See https://aka.ms/new-console-template for more information -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using OmniSharp.Extensions.LanguageServer.Protocol.Models; -using OmniSharp.Extensions.LanguageServer.Server; -using Serilog; -using Stride.Shaders.Parsing.LSP; - -await MainAsync(); - -static async Task MainAsync() -{ - Log.Logger = new LoggerConfiguration() - .Enrich.FromLogContext() - .WriteTo.File("log.txt", rollingInterval: RollingInterval.Minute) - .MinimumLevel.Verbose() - .CreateLogger(); - - IObserver workDone = null!; - - var server = await LanguageServer.From( - options => - options - .WithInput(Console.OpenStandardInput()) - .WithOutput(Console.OpenStandardOutput()) - .ConfigureLogging( - x => x - .AddSerilog(Log.Logger) - .AddLanguageProtocolLogging() - .SetMinimumLevel(LogLevel.Debug) - ) - .WithHandler() - .WithHandler() - // .WithHandler() - .WithHandler() - .WithHandler() - .WithHandler() - .WithHandler() - .WithServices(x => x.AddLogging(b => b.SetMinimumLevel(LogLevel.Trace))) - .WithServices( - services => - { - services.AddSingleton( - provider => - { - var loggerFactory = provider.GetService(); - var logger = loggerFactory!.CreateLogger(); - - logger.LogInformation("Configuring"); - - return new Foo(logger); - } - ); - services.AddSingleton( - new ConfigurationItem - { - Section = "typescript", - } - ).AddSingleton( - new ConfigurationItem - { - Section = "terminal", - } - ); - } - ) - .OnInitialize( - async (server, request, token) => - { - var manager = server.WorkDoneManager.For( - request, new WorkDoneProgressBegin - { - Title = "Server is starting...", - Percentage = 10, - } - ); - workDone = manager; - - await Task.Delay(2000).ConfigureAwait(false); - - manager.OnNext( - new WorkDoneProgressReport - { - Percentage = 20, - Message = "loading in progress" - } - ); - } - ) - .OnInitialized( - async (server, request, response, token) => - { - workDone.OnNext( - new WorkDoneProgressReport - { - Percentage = 40, - Message = "loading almost done", - } - ); - - await Task.Delay(2000).ConfigureAwait(false); - - workDone.OnNext( - new WorkDoneProgressReport - { - Message = "loading done", - Percentage = 100, - } - ); - workDone.OnCompleted(); - } - ) - .OnStarted( - async (languageServer, token) => - { - using var manager = await languageServer.WorkDoneManager.Create(new WorkDoneProgressBegin { Title = "Doing some work..." }) - .ConfigureAwait(false); - - manager.OnNext(new WorkDoneProgressReport { Message = "doing things..." }); - await Task.Delay(10000).ConfigureAwait(false); - manager.OnNext(new WorkDoneProgressReport { Message = "doing things... 1234" }); - await Task.Delay(10000).ConfigureAwait(false); - manager.OnNext(new WorkDoneProgressReport { Message = "doing things... 56789" }); - - var logger = languageServer.Services.GetService>(); - var configuration = await languageServer.Configuration.GetConfiguration( - new ConfigurationItem - { - Section = "typescript", - }, new ConfigurationItem - { - Section = "terminal", - } - ).ConfigureAwait(false); - - var baseConfig = new JObject(); - foreach (var config in languageServer.Configuration.AsEnumerable()) - { - baseConfig.Add(config.Key, config.Value); - } - - logger!.LogInformation("Base Config: {@Config}", baseConfig); - - var scopedConfig = new JObject(); - foreach (var config in configuration.AsEnumerable()) - { - scopedConfig.Add(config.Key, config.Value); - } - - logger!.LogInformation("Scoped Config: {@Config}", scopedConfig); - } - ) - ).ConfigureAwait(false); - - await server.WaitForExit.ConfigureAwait(false); -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs b/sources/shaders/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs deleted file mode 100644 index 8b30ca6759..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/SDSL/ASTExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using OmniSharp.Extensions.LanguageServer.Protocol.Models; - -namespace Stride.Shaders.Parsing.LSP; - -public static class ASTExtensions -{ - public static bool Intersects(this N node, Position position) - where N : Node - { - if ( - position.Line + 1 >= node.Info.Line - && position.Line + 1 <= node.Info.EndLine - && position.Character + 1 >= node.Info.Column - && position.Character + 1 < node.Info.Column + node.Info.Length - ) - { - return true; - } - return false; - } -} \ No newline at end of file diff --git a/sources/shaders/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj b/sources/shaders/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj deleted file mode 100644 index 6f1a2f6c9e..0000000000 --- a/sources/shaders/src/Stride.Shaders.LSP/Stride.Shaders.LSP.csproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - Exe - net10.0 - enable - enable - - - - - - - - - - - - - - - - - - - - ..\sdsl-language-support\bin\ - false - - - From 2faccb72ad6eb8d97615c7c403cacfb81ae37f6d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 14:48:32 +0900 Subject: [PATCH 0827/1182] Moved submodules to appropriate location --- sources/shaders/.gitmodules => .gitmodules | 6 +++--- .../Stride.Shaders.Spirv.Core.csproj | 20 +++++++++---------- .../Stride.Shaders/Stride.Shaders.csproj | 12 +++++------ 3 files changed, 19 insertions(+), 19 deletions(-) rename sources/shaders/.gitmodules => .gitmodules (70%) diff --git a/sources/shaders/.gitmodules b/.gitmodules similarity index 70% rename from sources/shaders/.gitmodules rename to .gitmodules index 6b8d134039..0fcbc01292 100644 --- a/sources/shaders/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "submodules/SpirvHeaders"] - path = submodules/SpirvHeaders + path = build/submodules/SpirvHeaders url = https://github.com/KhronosGroup/SPIRV-Headers [submodule "submodules/CppNet8"] - path = submodules/CppNet8 + path = build/submodules/CppNet8 url = https://github.com/ykafia/CppNet/ [submodule "submodules/SpirvRegistry"] - path = submodules/SpirvRegistry + path = build/submodules/SpirvRegistry url = https://github.com/KhronosGroup/Registry-Root-SPIR-V diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 58bb299313..3b8b8c4a08 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -15,16 +15,16 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj index 823488d4e2..c77769ceb3 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -1,12 +1,12 @@  - - - - - - + + + + + + From 866ec8a9b53fde2f823e792ab39a7cb817469ecf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 14:48:54 +0900 Subject: [PATCH 0828/1182] Use centralized package versions --- sources/Directory.Packages.props | 12 ++++++++++ .../Stride.Shaders.Compilers/SpirvOpt.cs | 1 - .../Stride.Shaders.Compilers.csproj | 11 +++++----- .../Stride.Shaders.Generators.Internal.csproj | 10 ++++----- .../Stride.Shaders.Generators.csproj | 9 ++++---- .../Stride.Shaders.Spirv.Core.csproj | 5 +++-- .../Stride.Shaders.Spirv.Generators.csproj | 20 ++++++++--------- .../Stride.Shaders.Tests.csproj | 22 ++++++++----------- .../Stride.Shaders/Stride.Shaders.csproj | 1 + 9 files changed, 49 insertions(+), 42 deletions(-) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index 59efc0f696..2eb5f5d85c 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -29,10 +29,13 @@ + + + @@ -44,9 +47,13 @@ + + + + @@ -66,6 +73,7 @@ + @@ -74,6 +82,9 @@ + + + @@ -90,6 +101,7 @@ + diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs index a3732a7950..8e538a91fb 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs @@ -1,6 +1,5 @@ using System.Runtime.InteropServices; using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; using Silk.NET.Shaderc; using Silk.NET.SPIRV.Cross; using Stride.Shaders.Spirv.Core; diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 3f0428b485..08457303b9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -5,12 +5,11 @@ - - - - - - + + + + + diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj b/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj index 59fc459c40..f1288c5cc2 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj @@ -10,15 +10,15 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + - \ No newline at end of file + diff --git a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index 89d3a8693b..9a733011e8 100644 --- a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -11,13 +11,12 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + @@ -35,4 +34,4 @@ - \ No newline at end of file + diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 3b8b8c4a08..b386d299de 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -5,11 +5,12 @@ enable enable true + CS8785 - + @@ -27,4 +28,4 @@ - \ No newline at end of file + diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 7e5adde62c..356816918e 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -13,18 +13,18 @@ - - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + @@ -44,4 +44,4 @@ - \ No newline at end of file + diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index c05a78d1ce..57b83e626b 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -15,22 +15,18 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + + + + + + $(StrideDirectory)\sources\core\Stride.Core.Mathematics\bin\Debug\net10.0\Stride.Core.Mathematics.dll diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj index c77769ceb3..e5ee4213ca 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -38,6 +38,7 @@ $(MSBuildProjectName)2 CS8785;$(WarningsAsErrors) true + CS8785 From 151fc1a261c789cec34b12a65301fe0bd08eab14 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 15:08:23 +0900 Subject: [PATCH 0829/1182] Further fixes so that the project properly compiles with new path against Stride --- .../Stride.Assets.Presentation.csproj | 2 +- .../engine/Stride.Assets/Stride.Assets.csproj | 2 +- .../Stride.Shaders.Compiler.csproj | 6 +- .../Stride.Shaders.Tests.Windows.csproj | 4 +- .../Stride.Shaders/Stride.Shaders.csproj | 2 +- .../Stride.Shaders.Compilers.csproj | 14 +- .../Stride.Shaders.Experiments.csproj | 14 +- .../Stride.Shaders.Generators.csproj | 8 +- .../FrameRenderer.OpenGL.cs | 333 ----- .../Stride.Shaders.Tests.csproj | 26 +- .../Stride.Shaders/Stride.Shaders.csproj | 16 +- .../Core/DataContractAttribute.cs | 44 - .../Core/DataMemberAttribute.cs | 117 -- .../Core/DataMemberIgnoreAttribute.cs | 9 - .../StrideImported/Core/DataMemberMode.cs | 35 - .../Core/EnumerableExtensions.cs | 168 --- .../StrideImported/Core/ParameterKey.cs | 126 -- .../StrideImported/Core/ParameterKeyInfo.cs | 57 - .../StrideImported/Core/SortedList.cs | 1159 ----------------- .../Core/StrideCoreExtensions.cs | 47 - .../StrideImported/Graphics/Buffer.cs | 6 - .../Graphics/CompareFunction.cs | 59 - .../Graphics/SamplerStateDescription.cs | 232 ---- .../Graphics/TextureAddressMode.cs | 46 - .../StrideImported/Graphics/TextureFilter.cs | 172 --- .../StrideImported/Mathematics/Color4.cs | 628 --------- .../ShadersReflection/ConstantBufferType.cs | 28 - .../EffectConstantBufferDescription.cs | 47 - .../ShadersReflection/EffectParameterClass.cs | 87 -- .../EffectParameterKeyInfo.cs | 28 - .../ShadersReflection/EffectParameterType.cs | 203 --- .../ShadersReflection/EffectReflection.cs | 64 - .../EffectResourceBindingDescription.cs | 51 - .../EffectSamplerStateBinding.cs | 38 - .../EffectTypeDescription.cs | 38 - .../EffectTypeMemberDescription.cs | 30 - .../EffectValueDescription.cs | 30 - .../ShaderInputAttributeDescription.cs | 17 - .../ShadersReflection/ShaderStage.cs | 48 - .../ShaderStreamOutputDeclarationEntry.cs | 43 - .../ShadersSource/HashSourceCollection.cs | 46 - .../StrideImported/ShadersSource/ObjectId.cs | 334 ----- .../ShadersSource/ObjectIdBuilder.cs | 437 ------- .../ShadersSource/ShaderArraySource.cs | 99 -- .../ShadersSource/ShaderClassCode.cs | 64 - .../ShadersSource/ShaderClassSource.cs | 122 -- .../ShadersSource/ShaderMacro.cs | 62 - .../ShadersSource/ShaderMixinSource.cs | 245 ---- .../ShadersSource/ShaderSource.cs | 37 - .../ShadersSource/ShaderSourceCollection.cs | 55 - .../StrideImported/ShadersSource/Utilities.cs | 205 --- 51 files changed, 47 insertions(+), 5743 deletions(-) delete mode 100644 sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs delete mode 100644 sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs diff --git a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj index cc42937383..c67536382b 100644 --- a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj +++ b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj @@ -71,7 +71,7 @@ - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index 7499c4376b..946e660aa1 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -36,7 +36,7 @@ - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + ..\..\shaders\Stride.Shaders\bin\$(Configuration)\net10.0\Stride.Shaders2.dll diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index 9f81afe8d9..cf517fd41b 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -38,13 +38,13 @@ - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll + ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Spirv.Core.dll + ..\..\shaders\Stride.Shaders.Spirv.Core\bin\$(Configuration)\net10.0\Stride.Shaders.Spirv.Core.dll - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + ..\..\shaders\Stride.Shaders\bin\$(Configuration)\net10.0\Stride.Shaders2.dll diff --git a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj index 4679d2b67c..ba5020d14d 100644 --- a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj +++ b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj @@ -29,10 +29,10 @@ - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll - ..\..\..\..\SDSL\src\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll + ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll diff --git a/sources/engine/Stride.Shaders/Stride.Shaders.csproj b/sources/engine/Stride.Shaders/Stride.Shaders.csproj index 95c2664e08..7a7e540b0d 100644 --- a/sources/engine/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/engine/Stride.Shaders/Stride.Shaders.csproj @@ -19,7 +19,7 @@ - + diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 08457303b9..5497f7f383 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -13,14 +13,14 @@ - - $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + ..\..\..\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.dll Always @@ -34,7 +34,7 @@ enable enable true - $(MSBuildProjectName)2 + $(MSBuildProjectName)2 diff --git a/sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj b/sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj index b7cc5f494e..a519e3b926 100644 --- a/sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj +++ b/sources/shaders/Stride.Shaders.Experiments/Stride.Shaders.Experiments.csproj @@ -12,19 +12,19 @@ - - $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + ..\..\..\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + + ..\..\..\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll - + diff --git a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index 9a733011e8..60a3cd65ec 100644 --- a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -24,11 +24,11 @@ - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + + ..\..\..\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs deleted file mode 100644 index 4ee2add02a..0000000000 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.OpenGL.cs +++ /dev/null @@ -1,333 +0,0 @@ -using Silk.NET.Core.Native; -using Silk.NET.Maths; -using Silk.NET.OpenGL; -using Silk.NET.Windowing; -using Stride.Shaders; -using System; -using System.Diagnostics; -using System.Drawing; -using System.Globalization; -using System.Text; - -namespace Stride.Shaders.Parsing.Tests; - - - -public class OpenGLFrameRenderer(uint width = 800, uint height = 600, byte[]? fragmentSpirv = null, byte[]? vertexSpirv = null) : FrameRenderer(width, height, vertexSpirv, fragmentSpirv) -{ - static IWindow? window; - static GL? Gl; - - uint width = width; - uint height = height; - - uint Fbo; - uint FboTex; - uint Vbo; - uint Ebo; - uint Vao; - uint Shader; - - byte[]? fragmentSpirv = fragmentSpirv; - - //Vertex shaders are run on each vertex. - public string VertexShaderSource = @" - #version 330 core //Using version GLSL version 3.3 - layout (location = 0) in vec4 vPos; - - void main() - { - gl_Position = vec4(vPos.x, vPos.y, vPos.z, 1.0); - } - "; - - //Fragment shaders are run on each fragment/pixel of the geometry. - public string PixelShaderSource = @" - #version 330 core - out vec4 FragColor; - - void main() - { - FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); - } - "; - - //Vertex data, uploaded to the VBO. - private static readonly float[] Vertices = - [ - //X Y Z - 1f, 1f, 0f, - 1f, -1f, 0f, - -1f,-1f, 0f, - -1f, 1f, 1f - ]; - - //Index data, uploaded to the EBO. - private static readonly uint[] Indices = - [ - 0, 1, 3, - 1, 2, 3 - ]; - - public EffectReflection EffectReflection { get; set; } - - static unsafe void DebugCallback(GLEnum source, GLEnum type, int id, GLEnum severity, int length, nint message, nint userParam) - { - var messageDecoded = Encoding.ASCII.GetString((byte*)message.ToPointer(), length); - Debug.WriteLine($"[{severity}] {messageDecoded}"); - } - - public unsafe void RenderFrame(Span result) - { - var options = WindowOptions.Default; - options.Size = new Vector2D((int)width, (int)height); - options.IsVisible = false; - options.ShouldSwapAutomatically = false; - window = Window.Create(options); - window.Initialize(); - //Getting the opengl api for drawing to the screen. - Gl = GL.GetApi(window); - - Gl.Enable(EnableCap.DebugOutput); - Gl.Enable(EnableCap.DebugOutputSynchronous); - Gl.DebugMessageCallback(DebugCallback, null); - - // Generate a FBO - Gl.GenFramebuffers(1, out Fbo); - Gl.BindFramebuffer(FramebufferTarget.Framebuffer, Fbo); - - Gl.GenTextures(1, out FboTex); - Gl.BindTexture(TextureTarget.Texture2D, FboTex); - Gl.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, null); - Gl.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, FboTex, 0); - - - - //Creating a vertex array. - Vao = Gl.GenVertexArray(); - Gl.BindVertexArray(Vao); - - //Initializing a vertex buffer that holds the vertex data. - Vbo = Gl.GenBuffer(); //Creating the buffer. - Gl.BindBuffer(BufferTargetARB.ArrayBuffer, Vbo); //Binding the buffer. - fixed (void* v = &Vertices[0]) - { - Gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(Vertices.Length * sizeof(float)), v, BufferUsageARB.StaticDraw); //Setting buffer data. - } - - //Initializing a element buffer that holds the index data. - Ebo = Gl.GenBuffer(); //Creating the buffer. - Gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, Ebo); //Binding the buffer. - fixed (void* i = &Indices[0]) - { - Gl.BufferData(BufferTargetARB.ElementArrayBuffer, (nuint)(Indices.Length * sizeof(uint)), i, BufferUsageARB.StaticDraw); //Setting buffer data. - } - - //Creating a vertex shader. - uint vertexShader = Gl.CreateShader(ShaderType.VertexShader); - Gl.ShaderSource(vertexShader, VertexShaderSource); - Gl.CompileShader(vertexShader); - - //Checking the shader for compilation errors. - string shaderLog = Gl.GetShaderInfoLog(vertexShader); - if (!string.IsNullOrWhiteSpace(shaderLog)) - { - Console.WriteLine($"Error compiling vertex shader {shaderLog}"); - throw new InvalidOperationException(shaderLog); - } - - //Creating a fragment shader. - uint fragmentShader = Gl.CreateShader(ShaderType.FragmentShader); - if (fragmentSpirv is not null) - { - unsafe - { - fixed (byte* spirv = fragmentSpirv) - Gl.ShaderBinary([fragmentShader], GLEnum.ShaderBinaryFormatSpirV, (void*)spirv, (uint)fragmentSpirv.Length); - - Gl.SpecializeShader(fragmentShader, "PSMain_wrapper", 0, null, null); - } - } - else - { - Gl.ShaderSource(fragmentShader, PixelShaderSource); - Gl.CompileShader(fragmentShader); - } - - //Checking the shader for compilation errors. - shaderLog = Gl.GetShaderInfoLog(fragmentShader); - if (!string.IsNullOrWhiteSpace(shaderLog)) - { - Console.WriteLine($"Error compiling fragment shader {shaderLog}"); - throw new InvalidOperationException(shaderLog); - } - - //Combining the shaders under one shader program. - Shader = Gl.CreateProgram(); - Gl.AttachShader(Shader, vertexShader); - Gl.AttachShader(Shader, fragmentShader); - Gl.LinkProgram(Shader); - - //Checking the linking for errors. - Gl.GetProgram(Shader, GLEnum.LinkStatus, out var status); - var programLog = Gl.GetProgramInfoLog(Shader); - if (status == 0) - { - Console.WriteLine($"Error linking shader {programLog}"); - } - - //Delete the no longer useful individual shaders; - Gl.DetachShader(Shader, vertexShader); - Gl.DetachShader(Shader, fragmentShader); - Gl.DeleteShader(vertexShader); - Gl.DeleteShader(fragmentShader); - - - Gl.GetProgram(Shader, GLEnum.ActiveAttributes, out var attributeCount); - for (uint i = 0; i < attributeCount; ++i) - { - Gl.GetActiveAttrib(Shader, i, 256, out _, out var attribSize, out AttributeType attribType, out string attribName); - var attribIndex = (uint)Gl.GetAttribLocation(Shader, attribName); - - if (attribName == "in_VS_Position" || attribName == "vPos") - { - //Tell opengl how to give the data to the shaders. - Gl.VertexAttribPointer(attribIndex, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), null); - Gl.EnableVertexAttribArray(attribIndex); - } - else - { - foreach (var param in Parameters) - { - if (!param.Key.StartsWith("stream.") || !attribName.StartsWith("in_VS_")) - continue; - - var paramName = param.Key.Substring("stream.".Length); - // TODO: need to scan for semantic name? - attribName = attribName.Substring("in_VS_".Length); - - if (paramName == attribName) - { - if (attribType == AttributeType.Float) - Gl.VertexAttrib1(attribIndex, float.Parse(param.Value)); - else if (attribType == AttributeType.Int) - Gl.VertexAttrib1(attribIndex, int.Parse(param.Value)); - else if (attribType == AttributeType.FloatVec4) - { - var values = param.Value.TrimStart('(').TrimEnd(')').Split(' ', StringSplitOptions.TrimEntries); - Gl.VertexAttrib4(attribIndex, float.Parse(values[0]), float.Parse(values[1]), float.Parse(values[2]), float.Parse(values[3])); - } - } - } - } - } - - // Just render once - Gl.Clear((uint)ClearBufferMask.ColorBufferBit); - - //Bind the geometry and shader. - Gl.BindVertexArray(Vao); - Gl.UseProgram(Shader); - - int bufferCount = 0; - foreach (var param in Parameters) - { - var dotIndex = param.Key.IndexOf("."); - if (dotIndex == -1) - continue; - - var resourceType = param.Key.Substring(0, dotIndex); - if (resourceType != "cbuffer" && resourceType != "texture" && resourceType != "buffer") - continue; - - var resourceName = param.Key.Substring(dotIndex + 1); - - if (resourceType == "cbuffer") - { - var blockIndex = Gl.GetUniformBlockIndex(Shader, $"type_{resourceName}"); - if ((GLEnum)blockIndex == GLEnum.InvalidIndex) - continue; - Gl.UniformBlockBinding(Shader, blockIndex, 0); - - var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == resourceName); - var cbufferData = new byte[cbReflection.Size]; - foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) - { - var cbMemberReflection = cbReflection.Members.Single(x => x.KeyInfo.KeyName.EndsWith(cbufferParameter.Key)); - - fixed (byte* cbufferDataPtr = cbufferData) - { - FillCBufferData(cbufferParameter.Value, cbMemberReflection.Type, cbMemberReflection.Offset, cbufferDataPtr); - } - } - - Gl.GenBuffers(1, out uint ubo); - Gl.BindBuffer(GLEnum.UniformBuffer, ubo); - Gl.BufferData(GLEnum.UniformBuffer, (nuint)cbReflection.Size, cbufferData, GLEnum.DynamicDraw); - Gl.BindBuffer(GLEnum.UniformBuffer, 0); // Unbind - - Gl.BindBufferRange(GLEnum.UniformBuffer, 0, ubo, 0, sizeof(uint)); - } - else if (resourceType == "texture") - { - var color = ParseColor(param.Value); - - var index = Gl.GetProgramResourceIndex(Shader, GLEnum.Uniform, resourceName); - GLEnum type; - var requestedProps = GLEnum.Type; - Gl.GetProgramResource(Shader, GLEnum.Uniform, 0, 1, &requestedProps, 1, null, (int*)&type); - - var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, resourceName); - if (location == -1) - throw new InvalidOperationException($"Could not find resource {resourceName}"); - - var texture = Gl.GenTexture(); - Gl.BindTexture(GLEnum.Texture2D, texture); - - Gl.TexImage2D(GLEnum.Texture2D, 0, (int)GLEnum.Rgba, 1, 1, 0, GLEnum.Rgba, GLEnum.UnsignedByte, (void*)&color); - - Gl.ProgramUniform1(Shader, location, texture); - } - else if (resourceType == "buffer") - { - var color = ParseColor(param.Value); - - var location = Gl.GetProgramResourceLocation(Shader, GLEnum.Uniform, resourceName); - if (location == -1) - throw new InvalidOperationException($"Could not find resource {resourceName}"); - - var buffer = Gl.GenBuffer(); - Gl.BindBuffer(BufferTargetARB.TextureBuffer, buffer); - - Gl.BufferData(BufferTargetARB.TextureBuffer, sizeof(uint), (void*)&color, BufferUsageARB.StaticDraw); - - var texture = Gl.GenTexture(); - Gl.ActiveTexture(GLEnum.Texture0 + bufferCount); - Gl.BindTexture(GLEnum.TextureBuffer, texture); - // TODO: Check if this is really valid to cast PixelInternalFormat to SizedInternalFormat in all cases? - Gl.TexBuffer(TextureTarget.TextureBuffer, GLEnum.Rgba8ui, buffer); - - Gl.ProgramUniform1(Shader, location, bufferCount); - - bufferCount++; - } - } - - Gl.ValidateProgram(Shader); - var validateStatus = Gl.GetProgram(Shader, GLEnum.ValidateStatus); - if (validateStatus != (int)GLEnum.True) - { - var validationLog = Gl.GetProgramInfoLog(Shader); - throw new InvalidOperationException($"Validation error: {validationLog}"); - } - - //Draw the geometry. - Gl.DrawElements(PrimitiveType.Triangles, (uint)Indices.Length, DrawElementsType.UnsignedInt, null); - - Gl.ReadPixels(0, 0, width, height, GLEnum.Rgba, GLEnum.UnsignedByte, result); - // Useful with RenderDoc - window.SwapBuffers(); - window.Close(); - window.Dispose(); - } -} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index 57b83e626b..7ef6c279f1 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -27,29 +27,31 @@ + + ..\..\..\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll - - $(StrideDirectory)\sources\core\Stride.Core.Mathematics\bin\Debug\net10.0\Stride.Core.Mathematics.dll + + ..\..\..\sources\core\Stride.Core.Mathematics\bin\Debug\net10.0\Stride.Core.Mathematics.dll - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - $(StrideDirectory)\sources\engine\Stride.Graphics\bin\Debug\net10.0\Direct3D11\Stride.Graphics.dll + + ..\..\..\sources\engine\Stride.Graphics\bin\Debug\net10.0\Direct3D11\Stride.Graphics.dll - - $(StrideDirectory)\sources\engine\Stride\bin\Debug\net10.0\Stride.dll + + ..\..\..\sources\engine\Stride\bin\Debug\net10.0\Stride.dll - - $(StrideDirectory)\sources\engine\Stride.Rendering\bin\Debug\net10.0\Stride.Rendering.dll + + ..\..\..\sources\engine\Stride.Rendering\bin\Debug\net10.0\Stride.Rendering.dll - - + + diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj index e5ee4213ca..5729043a66 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -7,8 +7,6 @@ - - @@ -19,14 +17,14 @@ - - $(StrideDirectory)\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll + + ..\..\..\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll - - $(StrideDirectory)\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll + + ..\..\..\sources\shaders\Stride.Core.Shaders\bin\Debug\net10.0\Stride.Core.Shaders.dll - - $(StrideDirectory)\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll + + ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll @@ -35,7 +33,7 @@ enable enable True - $(MSBuildProjectName)2 + $(MSBuildProjectName)2 CS8785;$(WarningsAsErrors) true CS8785 diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs deleted file mode 100644 index 69435e3ae8..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/DataContractAttribute.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core; - -/// -/// Indicates that a class can be serialized. -/// -[AttributeUsage(AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = false, Inherited = false)] -public class DataContractAttribute : Attribute -{ - /// - /// Initializes a new instance of the class. - /// - public DataContractAttribute() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The type alias name when serializing to a textual format. - public DataContractAttribute(string aliasName) - { - this.Alias = aliasName; - } - - /// - /// Gets or sets the alias name when serializing to a textual format. - /// - /// The alias name. - public string? Alias { get; } - - /// - /// Gets or sets a value indicating whether this is implicitly inherited by all its descendant classes. - /// - /// true if inherited; otherwise, false. - public bool Inherited { get; set; } - - /// - /// The default member mode. - /// - public DataMemberMode DefaultMemberMode { get; set; } = DataMemberMode.Default; -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs deleted file mode 100644 index fb472f83f3..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberAttribute.cs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core; - -/// -/// Specify the way to store a property or field of some class or structure. -/// -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] -public class DataMemberAttribute : Attribute -{ - public const uint DefaultMask = 1; - public const uint IgnoreMask = 0xF0000000; - - /// - /// Initializes a new instance of the class. - /// - public DataMemberAttribute() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The order. - public DataMemberAttribute(int order) - { - Order = order; - } - - /// - /// Initializes a new instance of the class. - /// - /// The name. - public DataMemberAttribute(string name) - { - Name = name; - } - - /// - /// Specify the way to store a property or field of some class or structure. - /// - /// The name. - /// The serialize method. - public DataMemberAttribute(string name, DataMemberMode mode) - { - Name = name; - Mode = mode; - } - - /// - /// Specify the way to store a property or field of some class or structure. - /// - /// The serialize method. - public DataMemberAttribute(DataMemberMode mode) - { - Mode = mode; - } - - /// - /// Initializes a new instance of the class. - /// - /// The order. - /// The mode. - public DataMemberAttribute(int order, DataMemberMode mode) - { - Order = order; - Mode = mode; - } - - /// - /// Initializes a new instance of the class. - /// - /// The order. - /// The name. - public DataMemberAttribute(int order, string name) - { - Order = order; - Name = name; - } - - /// - /// Initializes a new instance of the class. - /// - /// The order. - /// The name. - /// The mode. - public DataMemberAttribute(int order, string name, DataMemberMode mode) - { - Order = order; - Name = name; - Mode = mode; - } - - /// - /// Gets the name. - /// - /// The name. - public string? Name { get; } - - /// - /// Gets the serialize method1. - /// - /// The serialize method1. - public DataMemberMode Mode { get; } - - /// - /// Gets or sets the order. Default is -1 (default to alphabetical) - /// - /// The order. - public int? Order { get; set; } - - /// - /// Gets or sets the mask to filter out members. - /// - /// The mask. - public uint Mask { get; set; } = DefaultMask; -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs deleted file mode 100644 index d54b062c70..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberIgnoreAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Core; - -/// -/// When specified on a property or field, it will not be used when serializing/deserializing. -/// -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false)] -public class DataMemberIgnoreAttribute : Attribute; diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs deleted file mode 100644 index 721e314ec4..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/DataMemberMode.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Core; - -/// -/// Specify the way to store a property or field of some class or structure. -/// -public enum DataMemberMode -{ - /// - /// Use the default mode depending on the type of the field/property. - /// - Default = 0, - - /// - /// When restored, new object is created by using the parameters in - /// the YAML data and assigned to the property / field. When the - /// property / field is writeable, this is the default. - /// - Assign = 1, - - /// - /// Only valid for a property / field that return a class, no strings, primitives or value types. - /// When restored, instead of recreating the whole class, - /// the members are independently restored. When the property / field - /// is not writeable this is the default. - /// - Content = 2, - - /// - /// The property / field will not be stored. - /// - Never = 4, -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs deleted file mode 100644 index 5db8f6dfa6..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/EnumerableExtensions.cs +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.Collections; -using System.Diagnostics.Contracts; - -namespace Stride.Core.Extensions; - -public static class EnumerableExtensions -{ - /// - /// Tells whether a sequence is null or empty. - /// - /// The source sequence. - /// Returns true if the sequence is null or empty, false if it is not null and contains at least one element. - [Pure] - public static bool IsNullOrEmpty(this IEnumerable source) - { - if (source == null) - return true; - - var enumerator = source.GetEnumerator() ?? throw new ArgumentException("Invalid 'source' IEnumerable."); - return enumerator.MoveNext() == false; - } - - /// - /// Executes an action for each (casted) item of the given enumerable. - /// - /// Type of the item value in the enumerable. - /// Input enumerable to work on. - /// Action performed for each item in the enumerable. - /// This extension method do not yield. It acts just like a foreach statement, and performs a cast to a typed enumerable in the middle. - public static void ForEach(this IEnumerable source, Action action) - { - source.Cast().ForEach(action); - } - - /// - /// Executes an action for each item of the given enumerable. - /// - /// Type of the item value in the enumerable. - /// Input enumerable to work on. - /// Action performed for each item in the enumerable. - /// This extension method do not yield. It acts just like a foreach statement. - public static void ForEach(this IEnumerable source, Action action) - { - foreach (var item in source) - { - action(item); - } - } - - /// - /// An extension method that searches for the first match and returns its index. - /// - /// Generic type parameter. - /// Input enumerable to work on. - /// The predicate. - /// The index of the first element matching. - [Pure] - public static int IndexOf(this IEnumerable source, Func predicate) - { - var index = 0; - foreach (var item in source) - { - if (predicate(item)) - return index; - index++; - } - return -1; - } - - /// - /// An extension method that searches for the last match and returns its index. - /// - /// Generic type parameter. - /// Input enumerable to work on. - /// The predicate. - /// The index of the last element matching. - [Pure] - public static int LastIndexOf(this IEnumerable source, Func predicate) - { - if (source is IList list) - { - // Faster search for lists. - for (var i = list.Count - 1; i >= 0; --i) - { - if (predicate(list[i])) - return i; - } - return -1; - } - var index = 0; - var lastIndex = -1; - foreach (var item in source) - { - if (predicate(item)) - lastIndex = index; - index++; - } - return lastIndex; - } - - /// - /// Filters out null items from the enumerable. - /// - /// Generic type parameter. - /// Input enumerable to work on. - /// An enumeration of all items in that are not null. - [Pure] - public static IEnumerable NotNull(this IEnumerable source) where T : class - { - foreach (var item in source) - { - if (item is not null) - yield return item; - } - } - - /// - /// Filters out null items from the enumerable. - /// - /// Generic type parameter. - /// Input enumerable to work on. - /// An enumeration of all items in that are not null. - [Pure] - public static IEnumerable NotNull(this IEnumerable source) where T : struct - { - foreach (var item in source) - { - if (item.HasValue) - yield return item.Value; - } - } - - /// - /// Enumerates the linked list nodes. - /// - /// The linked list. - /// An enumeration of the linked list nodes. - [Pure] - internal static IEnumerable> EnumerateNodes(this LinkedList list) - { - var node = list.First; - while (node != null) - { - yield return node; - node = node.Next; - } - } - - /// - /// Calculates a combined hash code for items of the enumerbale. - /// - /// Generic type parameter. - /// Input enumerable to work on. - /// A combined hash code or 0 if the source is empty. - [Pure] - public static int ToHashCode(this IEnumerable source) where T : class - { - if (source.IsNullOrEmpty()) return 0; - - unchecked - { - return source.Aggregate(17, (hash, item) => hash * 23 + item.GetHashCode()); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs deleted file mode 100644 index f378616e24..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKey.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#pragma warning disable SA1402 // File may only contain a single type -using Stride.Core; -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Xml.Linq; - -namespace Stride.Rendering -{ - /// - /// Key of an effect parameter. - /// - public abstract class ParameterKey - { - protected string name; - - /// - /// Initializes a new instance of the class. - /// - /// Type of the property. - /// The name. - /// The length. - /// The metadatas. - protected ParameterKey(Type propertyType, string name, int length) - { - Length = length; - } - - public string Name { get => name; init => name = value; } - - /// - /// Gets the number of elements for this key. - /// - public int Length { get; private set; } - - public ParameterKeyType Type { get; protected set; } - - public abstract int Size { get; } - - internal void SetName(string nameParam) - { - if (nameParam == null) throw new ArgumentNullException(nameof(nameParam)); - - name = string.Intern(nameParam); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - //return ReferenceEquals(this, obj); - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - var against = obj as ParameterKey; - if (against == null) return false; - return (Equals(against.Name, Name)); - } - - /// - /// Implements the operator ==. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator ==(ParameterKey left, ParameterKey right) - { - return Equals(left, right); - } - - /// - /// Implements the operator !=. - /// - /// The left. - /// The right. - /// - /// The result of the operator. - /// - public static bool operator !=(ParameterKey left, ParameterKey right) - { - return !Equals(left, right); - } - } - - public enum ParameterKeyType - { - Value, - Object, - Permutation, - } - - /// - /// Key of an gereric effect parameter. - /// - /// Type of the parameter key. - public abstract class ParameterKey : ParameterKey - { - /// - /// Initializes a new instance of the class. - /// - /// - /// The name. - /// The length. - /// The metadatas. - protected ParameterKey(ParameterKeyType type, string name, int length = 1) - : base(typeof(T), name, length) - { - Type = type; - } - - public override int Size => Unsafe.SizeOf(); - - public override string ToString() - { - return string.Format("{0}", Name); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs deleted file mode 100644 index 91b3e46a8e..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/ParameterKeyInfo.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; - -using Stride.Core; - -namespace Stride.Rendering; - -[DataContract] -public record struct ParameterKeyInfo(ParameterKey Key, int Offset, int Count, int BindingSlot) : IEquatable -{ - public const int Invalid = -1; - #region Convenience properties - - public readonly bool IsValueParameter => Offset != Invalid; - - public readonly bool IsResourceParameter => BindingSlot != Invalid; - - #endregion - - - public ParameterKeyInfo(ParameterKey key, int offset, int count) : this(key, offset, count, Invalid) - { - } - - public ParameterKeyInfo(ParameterKey key, int bindingSlot) : this(key, Invalid, 1, bindingSlot) - { - Offset = Invalid; - Count = 1; - } - - - // internal readonly ParameterAccessor GetObjectAccessor() - // { - // return new ParameterAccessor(BindingSlot, Count); - // } - - // internal readonly ParameterAccessor GetValueAccessor() - // { - // return new ParameterAccessor(Offset, Count); - // } - - - /// - public override readonly string ToString() - { - if (Key is null) - return "Invalid Parameter Key"; - - return IsResourceParameter - ? $"Object \"{Key}\" at Binding Slot {BindingSlot}" - : $"Value \"{Key}\" at Offset {Offset}" + (Count > 1 - ? $" (Count {Count})" - : string.Empty); - } -} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs deleted file mode 100644 index 5860673080..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/SortedList.cs +++ /dev/null @@ -1,1159 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// (ignore analyzers) -// -// System.Collections.Generic.SortedList.cs -// -// Author: -// Sergey Chaban (serge@wildwestsoftware.com) -// Duncan Mak (duncan@ximian.com) -// Herve Poussineau (hpoussineau@fr.st -// Zoltan Varga (vargaz@gmail.com) -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Collections; -using System.Diagnostics; - -namespace Stride.Core.Collections; - -/// -/// Represents a collection of associated keys and values -/// that are sorted by the keys and are accessible by key -/// and by index. -/// -[DebuggerDisplay("Count = {" + nameof(Count) + "}")] -public class SortedList : IDictionary, IDictionary -{ - private static readonly int INITIAL_SIZE = 16; - - private enum EnumeratorMode : int { KEY_MODE = 0, VALUE_MODE, ENTRY_MODE } - - private int inUse; - private int modificationCount; - private KeyValuePair[] table; - private IComparer comparer; - private int defaultCapacity; - - // - // Constructors - // - public SortedList() - : this(INITIAL_SIZE, null) - { - } - - public SortedList(int capacity) - : this(capacity, null) - { - } - - public SortedList(int capacity, IComparer comparer) - { - if (capacity < 0) - throw new ArgumentOutOfRangeException(nameof(capacity)); - - defaultCapacity = capacity == 0 ? 0 : INITIAL_SIZE; - Init(comparer, capacity, true); - } - - public SortedList(IComparer comparer) - : this(INITIAL_SIZE, comparer) - { - } - - public SortedList(IDictionary dictionary) - : this(dictionary, null) - { - } - - public SortedList(IDictionary dictionary, IComparer comparer) - { - ArgumentNullException.ThrowIfNull(dictionary); - - Init(comparer, dictionary.Count, true); - - foreach (var kvp in dictionary) - Add(kvp.Key, kvp.Value); - } - - // - // Properties - // - - // ICollection - - public int Count => inUse; - - bool ICollection.IsSynchronized => false; - - object ICollection.SyncRoot => this; - - // IDictionary - - bool IDictionary.IsFixedSize => false; - - bool IDictionary.IsReadOnly => false; - - public TValue this[TKey key] - { - get - { - ArgumentNullException.ThrowIfNull(key); - - var i = Find(key); - - if (i >= 0) - return table[i].Value; - throw new KeyNotFoundException(); - } - set - { - ArgumentNullException.ThrowIfNull(key); - - PutImpl(key, value, true); - } - } - - object IDictionary.this[object key] - { - get - { - if (key is not TKey key1) - return null; - return this[key1]; - } - - set - { - this[ToKey(key)] = ToValue(value); - } - } - - public int Capacity - { - get - { - return table.Length; - } - - set - { - var current = this.table.Length; - - if (inUse > value) - { - throw new ArgumentOutOfRangeException("capacity too small"); - } - if (value == 0) - { - // return to default size - var newTable = new KeyValuePair[defaultCapacity]; - Array.Copy(table, newTable, inUse); - this.table = newTable; - } -#if NET_1_0 - else if (current > defaultCapacity && value < current) { - KeyValuePair [] newTable = new KeyValuePair [defaultCapacity]; - Array.Copy (table, newTable, inUse); - this.table = newTable; - } -#endif - else if (value > inUse) - { - var newTable = new KeyValuePair[value]; - Array.Copy(table, newTable, inUse); - this.table = newTable; - } - else if (value > current) - { - var newTable = new KeyValuePair[value]; - Array.Copy(table, newTable, current); - this.table = newTable; - } - } - } - - public IList Keys => new ListKeys(this); - - public IList Values => new ListValues(this); - - ICollection IDictionary.Keys => new ListKeys(this); - - ICollection IDictionary.Values => new ListValues(this); - - ICollection IDictionary.Keys => Keys; - - ICollection IDictionary.Values => Values; - - public IComparer Comparer => comparer; - - bool ICollection>.IsReadOnly => false; - - // - // Public instance methods. - // - - public void Add(TKey key, TValue value) - { - ArgumentNullException.ThrowIfNull(key); - - PutImpl(key, value, false); - } - - public bool ContainsKey(TKey key) - { - ArgumentNullException.ThrowIfNull(key); - - return (Find(key) >= 0); - } - - public bool Remove(TKey key) - { - ArgumentNullException.ThrowIfNull(key); - - var i = IndexOfKey(key); - if (i >= 0) - { - RemoveAt(i); - return true; - } - return false; - } - - // ICollection> - - void ICollection>.Clear() - { - defaultCapacity = INITIAL_SIZE; - this.table = new KeyValuePair[defaultCapacity]; - inUse = 0; - modificationCount++; - } - - public void Clear() - { - defaultCapacity = INITIAL_SIZE; - this.table = new KeyValuePair[defaultCapacity]; - inUse = 0; - modificationCount++; - } - - void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) - { - if (Count == 0) - return; - - ArgumentNullException.ThrowIfNull(array); - - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException(); - - if (arrayIndex >= array.Length) - throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length"); - if (Count > (array.Length - arrayIndex)) - throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array"); - - var i = arrayIndex; - foreach (var pair in this) - array[i++] = pair; - } - - void ICollection>.Add(KeyValuePair keyValuePair) - { - Add(keyValuePair.Key, keyValuePair.Value); - } - - bool ICollection>.Contains(KeyValuePair keyValuePair) - { - var i = Find(keyValuePair.Key); - - if (i >= 0) - return Comparer>.Default.Compare(table[i], keyValuePair) == 0; - return false; - } - - bool ICollection>.Remove(KeyValuePair keyValuePair) - { - var i = Find(keyValuePair.Key); - - if (i >= 0 && (Comparer>.Default.Compare(table[i], keyValuePair) == 0)) - { - RemoveAt(i); - return true; - } - return false; - } - - // IEnumerable> - - public Enumerator GetEnumerator() - { - return new Enumerator(this); - } - - IEnumerator> IEnumerable>.GetEnumerator() - { - return new Enumerator(this); - } - - // IEnumerable - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - // IDictionary - - void IDictionary.Add(object key, object value) - { - PutImpl(ToKey(key), ToValue(value), false); - } - - bool IDictionary.Contains(object key) - { - ArgumentNullException.ThrowIfNull(key); - if (key is not TKey key1) - return false; - - return (Find(key1) >= 0); - } - - IDictionaryEnumerator IDictionary.GetEnumerator() - { - return new DictionaryEnumerator(this, EnumeratorMode.ENTRY_MODE); - } - - void IDictionary.Remove(object key) - { - ArgumentNullException.ThrowIfNull(key); - if (key is not TKey key1) - return; - var i = IndexOfKey(key1); - if (i >= 0) RemoveAt(i); - } - - // ICollection - - void ICollection.CopyTo(Array array, int arrayIndex) - { - if (Count == 0) - return; - - ArgumentNullException.ThrowIfNull(array); - - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException(); - - if (array.Rank > 1) - throw new ArgumentException("array is multi-dimensional"); - if (arrayIndex >= array.Length) - throw new ArgumentNullException("arrayIndex is greater than or equal to array.Length"); - if (Count > (array.Length - arrayIndex)) - throw new ArgumentNullException("Not enough space in array from arrayIndex to end of array"); - - using var it = GetEnumerator(); - var i = arrayIndex; - - while (it.MoveNext()) - { - array.SetValue(it.Current, i++); - } - } - - // - // SortedList - // - - public void RemoveAt(int index) - { - var table = this.table; - var cnt = Count; - if (index >= 0 && index < cnt) - { - if (index != cnt - 1) - { - Array.Copy(table, index + 1, table, index, cnt - 1 - index); - } - else - { - table[index] = default(KeyValuePair); - } - --inUse; - ++modificationCount; - } - else - { - throw new ArgumentOutOfRangeException("index out of range"); - } - } - - public int IndexOfKey(TKey key) - { - ArgumentNullException.ThrowIfNull(key); - - var indx = 0; - try - { - indx = Find(key); - } - catch (Exception) - { - throw new InvalidOperationException(); - } - - return (indx | (indx >> 31)); - } - - public int IndexOfValue(TValue value) - { - if (inUse == 0) - return -1; - - for (var i = 0; i < inUse; i++) - { - var current = this.table[i]; - - if (Equals(value, current.Value)) - return i; - } - - return -1; - } - - public bool ContainsValue(TValue value) - { - return IndexOfValue(value) >= 0; - } - - public void TrimExcess() - { - if (inUse < table.Length * 0.9) - Capacity = inUse; - } - - public bool TryGetValue(TKey key, out TValue value) - { - ArgumentNullException.ThrowIfNull(key); - - var i = Find(key); - - if (i >= 0) - { - value = table[i].Value; - return true; - } - value = default(TValue); - return false; - } - - // - // Private methods - // - - private void EnsureCapacity(int n, int free) - { - var table = this.table; - KeyValuePair[] newTable = null; - var cap = Capacity; - var gap = (free >= 0 && free < Count); - - if (n > cap) - { - newTable = new KeyValuePair[n << 1]; - } - - if (newTable != null) - { - if (gap) - { - var copyLen = free; - if (copyLen > 0) - { - Array.Copy(table, 0, newTable, 0, copyLen); - } - copyLen = Count - free; - if (copyLen > 0) - { - Array.Copy(table, free, newTable, free + 1, copyLen); - } - } - else - { - // Just a resizing, copy the entire table. - Array.Copy(table, newTable, Count); - } - this.table = newTable; - } - else if (gap) - { - Array.Copy(table, free, table, free + 1, Count - free); - } - } - - private void PutImpl(TKey key, TValue value, bool overwrite) - { - ArgumentNullException.ThrowIfNull(key); - - var table = this.table; - - var freeIndx = -1; - - try - { - freeIndx = Find(key); - } - catch (Exception) - { - throw new InvalidOperationException(); - } - - if (freeIndx >= 0) - { - if (!overwrite) - throw new ArgumentException("element already exists"); - - table[freeIndx] = new KeyValuePair(key, value); - ++modificationCount; - return; - } - - freeIndx = ~freeIndx; - - if (freeIndx > Capacity + 1) - throw new Exception("SortedList::internal error (" + key + ", " + value + ") at [" + freeIndx + "]"); - - - EnsureCapacity(Count + 1, freeIndx); - - table = this.table; - table[freeIndx] = new KeyValuePair(key, value); - - ++inUse; - ++modificationCount; - - } - - private void Init(IComparer comparer, int capacity, bool forceSize) - { - if (comparer == null) - comparer = Comparer.Default; - this.comparer = comparer; - if (!forceSize && (capacity < defaultCapacity)) - capacity = defaultCapacity; - this.table = new KeyValuePair[capacity]; - this.inUse = 0; - this.modificationCount = 0; - } - - private void CopyToArray(Array arr, int i, EnumeratorMode mode) - { - ArgumentNullException.ThrowIfNull(arr); - - if (i < 0 || i + this.Count > arr.Length) - throw new ArgumentOutOfRangeException(nameof(i)); - - IEnumerator it = new DictionaryEnumerator(this, mode); - - while (it.MoveNext()) - { - arr.SetValue(it.Current, i++); - } - } - - private int Find(TKey key) - { - var table = this.table; - var len = Count; - - if (len == 0) return ~0; - - var left = 0; - var right = len - 1; - - while (left <= right) - { - var guess = (left + right) >> 1; - - var cmp = comparer.Compare(table[guess].Key, key); - if (cmp == 0) return guess; - - if (cmp < 0) left = guess + 1; - else right = guess - 1; - } - - return ~left; - } - - private TKey ToKey(object key) - { - ArgumentNullException.ThrowIfNull(key); - if (key is not TKey key1) - throw new ArgumentException("The value \"" + key + "\" isn't of type \"" + typeof(TKey) + "\" and can't be used in this generic collection.", nameof(key)); - return key1; - } - - private TValue ToValue(object value) - { - if (value is not TValue value1) - throw new ArgumentException("The value \"" + value + "\" isn't of type \"" + typeof(TValue) + "\" and can't be used in this generic collection.", nameof(value)); - return value1; - } - - internal TKey KeyAt(int index) - { - if (index >= 0 && index < Count) - return table[index].Key; - throw new ArgumentOutOfRangeException(nameof(index)); - } - - internal TValue ValueAt(int index) - { - if (index >= 0 && index < Count) - return table[index].Value; - throw new ArgumentOutOfRangeException(nameof(index)); - } - - // - // Inner classes - // - - public sealed class Enumerator : IEnumerator> - { - private SortedList host; - private int pos = -1; - - public Enumerator(SortedList host) - { - this.host = host; - } - - public void Dispose() - { - host = null; - } - - public bool MoveNext() - { - return ++pos < host.inUse; - } - - public void Reset() - { - throw new NotSupportedException(); - } - - object IEnumerator.Current => Current; - - public KeyValuePair Current => host.table[pos]; - } - - - private sealed class DictionaryEnumerator : IDictionaryEnumerator, IEnumerator - { - private readonly SortedList host; - private int stamp; - private int pos; - private int size; - private readonly EnumeratorMode mode; - - private object currentKey; - private object currentValue; - - bool invalid = false; - - private static readonly string xstr = "SortedList.Enumerator: snapshot out of sync."; - - public DictionaryEnumerator(SortedList host, EnumeratorMode mode) - { - this.host = host; - stamp = host.modificationCount; - size = host.Count; - this.mode = mode; - Reset(); - } - - public DictionaryEnumerator(SortedList host) - : this(host, EnumeratorMode.ENTRY_MODE) - { - } - - public void Reset() - { - if (host.modificationCount != stamp || invalid) - throw new InvalidOperationException(xstr); - - pos = -1; - currentKey = null; - currentValue = null; - } - - public bool MoveNext() - { - if (host.modificationCount != stamp || invalid) - throw new InvalidOperationException(xstr); - - var table = host.table; - - if (++pos < size) - { - var entry = table[pos]; - - currentKey = entry.Key; - currentValue = entry.Value; - return true; - } - - currentKey = null; - currentValue = null; - return false; - } - - public DictionaryEntry Entry - { - get - { - if (invalid || pos >= size || pos == -1) - throw new InvalidOperationException(xstr); - - return new DictionaryEntry(currentKey, - currentValue); - } - } - - public object Key - { - get - { - if (invalid || pos >= size || pos == -1) - throw new InvalidOperationException(xstr); - return currentKey; - } - } - - public object Value - { - get - { - if (invalid || pos >= size || pos == -1) - throw new InvalidOperationException(xstr); - return currentValue; - } - } - - public object Current - { - get - { - if (invalid || pos >= size || pos == -1) - throw new InvalidOperationException(xstr); - - switch (mode) - { - case EnumeratorMode.KEY_MODE: - return currentKey; - case EnumeratorMode.VALUE_MODE: - return currentValue; - case EnumeratorMode.ENTRY_MODE: - return this.Entry; - - default: - throw new NotSupportedException(mode + " is not a supported mode."); - } - } - } - - // ICloneable - - public object Clone() - { - var e = new DictionaryEnumerator(host, mode); - e.stamp = stamp; - e.pos = pos; - e.size = size; - e.currentKey = currentKey; - e.currentValue = currentValue; - e.invalid = invalid; - return e; - } - } - - struct KeyEnumerator : IEnumerator, IDisposable - { - const int NOT_STARTED = -2; - - // this MUST be -1, because we depend on it in move next. - // we just decr the size, so, 0 - 1 == FINISHED - const int FINISHED = -1; - - readonly SortedList l; - int idx; - readonly int ver; - - internal KeyEnumerator(SortedList l) - { - this.l = l; - idx = NOT_STARTED; - ver = l.modificationCount; - } - - public void Dispose() - { - idx = NOT_STARTED; - } - - public bool MoveNext() - { - if (ver != l.modificationCount) - throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); - - if (idx == NOT_STARTED) - idx = l.Count; - - return idx != FINISHED && --idx != FINISHED; - } - - public TKey Current - { - get - { - if (idx < 0) - throw new InvalidOperationException(); - - return l.KeyAt(l.Count - 1 - idx); - } - } - - void IEnumerator.Reset() - { - if (ver != l.modificationCount) - throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); - - idx = NOT_STARTED; - } - - object IEnumerator.Current => Current; - } - - struct ValueEnumerator : IEnumerator, IDisposable - { - const int NOT_STARTED = -2; - - // this MUST be -1, because we depend on it in move next. - // we just decr the size, so, 0 - 1 == FINISHED - const int FINISHED = -1; - - readonly SortedList l; - int idx; - readonly int ver; - - internal ValueEnumerator(SortedList l) - { - this.l = l; - idx = NOT_STARTED; - ver = l.modificationCount; - } - - public void Dispose() - { - idx = NOT_STARTED; - } - - public bool MoveNext() - { - if (ver != l.modificationCount) - throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); - - if (idx == NOT_STARTED) - idx = l.Count; - - return idx != FINISHED && --idx != FINISHED; - } - - public TValue Current - { - get - { - if (idx < 0) - throw new InvalidOperationException(); - - return l.ValueAt(l.Count - 1 - idx); - } - } - - void IEnumerator.Reset() - { - if (ver != l.modificationCount) - throw new InvalidOperationException("Collection was modified after the enumerator was instantiated."); - - idx = NOT_STARTED; - } - - object IEnumerator.Current => Current; - } - - private class ListKeys : IList, IReadOnlyList, ICollection, IEnumerable - { - - private readonly SortedList host; - - public ListKeys(SortedList host) - { - ArgumentNullException.ThrowIfNull(host); - - this.host = host; - } - - // ICollection - - public virtual void Add(TKey item) - { - throw new NotSupportedException(); - } - - public virtual bool Remove(TKey key) - { - throw new NotSupportedException(); - } - - public virtual void Clear() - { - throw new NotSupportedException(); - } - - public virtual void CopyTo(TKey[] array, int arrayIndex) - { - if (host.Count == 0) - return; - ArgumentNullException.ThrowIfNull(array); - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException(); - if (arrayIndex >= array.Length) - throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length"); - if (Count > (array.Length - arrayIndex)) - throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array"); - - var j = arrayIndex; - for (var i = 0; i < Count; ++i) - array[j++] = host.KeyAt(i); - } - - public virtual bool Contains(TKey item) - { - return host.IndexOfKey(item) > -1; - } - - // - // IList - // - public virtual int IndexOf(TKey item) - { - return host.IndexOfKey(item); - } - - public virtual void Insert(int index, TKey item) - { - throw new NotSupportedException(); - } - - public virtual void RemoveAt(int index) - { - throw new NotSupportedException(); - } - - public virtual TKey this[int index] - { - get - { - return host.KeyAt(index); - } - set - { - throw new NotSupportedException("attempt to modify a key"); - } - } - - // - // IEnumerable - // - - public virtual IEnumerator GetEnumerator() - { - /* We couldn't use yield as it does not support Reset () */ - return new KeyEnumerator(host); - } - - // - // ICollection - // - - public virtual int Count => host.Count; - - public virtual bool IsSynchronized => ((ICollection)host).IsSynchronized; - - public virtual bool IsReadOnly => true; - - public virtual object SyncRoot => ((ICollection)host).SyncRoot; - - public virtual void CopyTo(Array array, int arrayIndex) - { - host.CopyToArray(array, arrayIndex, EnumeratorMode.KEY_MODE); - } - - // - // IEnumerable - // - - IEnumerator IEnumerable.GetEnumerator() - { - for (var i = 0; i < host.Count; ++i) - yield return host.KeyAt(i); - } - } - - private class ListValues : IList, IReadOnlyList, ICollection, IEnumerable - { - - private readonly SortedList host; - - public ListValues(SortedList host) - { - ArgumentNullException.ThrowIfNull(host); - - this.host = host; - } - - // ICollection - - public virtual void Add(TValue item) - { - throw new NotSupportedException(); - } - - public virtual bool Remove(TValue value) - { - throw new NotSupportedException(); - } - - public virtual void Clear() - { - throw new NotSupportedException(); - } - - public virtual void CopyTo(TValue[] array, int arrayIndex) - { - if (host.Count == 0) - return; - ArgumentNullException.ThrowIfNull(array); - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException(); - if (arrayIndex >= array.Length) - throw new ArgumentOutOfRangeException("arrayIndex is greater than or equal to array.Length"); - if (Count > (array.Length - arrayIndex)) - throw new ArgumentOutOfRangeException("Not enough space in array from arrayIndex to end of array"); - - var j = arrayIndex; - for (var i = 0; i < Count; ++i) - array[j++] = host.ValueAt(i); - } - - public virtual bool Contains(TValue item) - { - return host.IndexOfValue(item) > -1; - } - - // - // IList - // - public virtual int IndexOf(TValue item) - { - return host.IndexOfValue(item); - } - - public virtual void Insert(int index, TValue item) - { - throw new NotSupportedException(); - } - - public virtual void RemoveAt(int index) - { - throw new NotSupportedException(); - } - - public virtual TValue this[int index] - { - get - { - return host.ValueAt(index); - } - set - { - throw new NotSupportedException("attempt to modify a key"); - } - } - - // - // IEnumerable - // - - public virtual IEnumerator GetEnumerator() - { - /* We couldn't use yield as it does not support Reset () */ - return new ValueEnumerator(host); - } - - // - // ICollection - // - - public virtual int Count => host.Count; - - public virtual bool IsSynchronized => ((ICollection)host).IsSynchronized; - - public virtual bool IsReadOnly => true; - - public virtual object SyncRoot => ((ICollection)host).SyncRoot; - - public virtual void CopyTo(Array array, int arrayIndex) - { - host.CopyToArray(array, arrayIndex, EnumeratorMode.VALUE_MODE); - } - - // - // IEnumerable - // - - IEnumerator IEnumerable.GetEnumerator() - { - for (var i = 0; i < host.Count; ++i) - yield return host.ValueAt(i); - } - } - -} // SortedList - -// System.Collections.Generic diff --git a/sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs b/sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs deleted file mode 100644 index 91a113ea9a..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Core/StrideCoreExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Runtime.InteropServices; - -namespace Stride.Core; - -internal static class StrideCoreExtensions -{ - /// Determines whether two sequences are equal. Comparing the elements is done using the default equality comparer for their type. - /// Allows either parameter to be null. - /// A thin wrapper around . - /// The type of the elements of the input sequences. - /// An enumerable to compare to . - /// An enumerable to compare to . - /// true if one of the following is true. - /// - /// and are the same object. - /// Neither enumerable is null and they have the same length and each of the elements in the enumerables compare equal pairwise. - /// - /// false otherwise. - public static bool SequenceEqualAllowNull(this IEnumerable first, IEnumerable second) - => SequenceEqualAllowNull(first, second, null); - - /// Determines whether two sequences are equal. Comparing the elements is done using the specified equality comparer. - /// Allows and/or to be null. - /// A thin wrapper around . - /// The type of the elements of the input sequences. - /// An enumerable to compare to . - /// An enumerable to compare to . - /// The equality comparer. - /// true if one of the following is true. - /// - /// and are the same object. - /// Neither enumerable is null and they have the same length and each of the elements in the enumerables compare equal pairwise. - /// - /// false otherwise. - public static bool SequenceEqualAllowNull(this IEnumerable first, IEnumerable second, IEqualityComparer? comparer) - { - if (ReferenceEquals(first, second)) return true; - if (first is null || second is null) return false; - if (first is List llist && second is List rlist) - { - var lhs = CollectionsMarshal.AsSpan(llist); - var rhs = CollectionsMarshal.AsSpan(rlist); - return lhs.SequenceEqual(rhs); - } - return first.SequenceEqual(second, comparer); - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs deleted file mode 100644 index 904fe5b2c5..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Graphics/Buffer.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Stride.Graphics; - -public class Buffer -{ - -} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs deleted file mode 100644 index 03a93a895d..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Graphics/CompareFunction.cs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Graphics; - -/// -/// Identifies comparison functions that can be used to determine how the runtime compares -/// source (new) data against destination (existing) data before storing the new data. -/// -/// -/// The comparison functions can be used for a Depth-Stencil Buffer (see ) -/// for depth comparisons or rejections, or for stencil operations, or for Texture sampling -/// (see ). -/// -[DataContract] -public enum CompareFunction -{ - /// - /// Never pass the comparison. - /// - Never = 1, - - /// - /// If the source data is less than the destination data, the comparison passes. - /// - Less = 2, - - /// - /// If the source data is equal to the destination data, the comparison passes. - /// - Equal = 3, - - /// - /// If the source data is less than or equal to the destination data, the comparison passes. - /// - LessEqual = 4, - - /// - /// If the source data is greater than the destination data, the comparison passes. - /// - Greater = 5, - - /// - /// If the source data is not equal to the destination data, the comparison passes. - /// - NotEqual = 6, - - /// - /// If the source data is greater than or equal to the destination data, the comparison passes. - /// - GreaterEqual = 7, - - /// - /// Always pass the comparison. - /// - Always = 8 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs deleted file mode 100644 index 251daf07ee..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Graphics/SamplerStateDescription.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Runtime.InteropServices; - -using Stride.Core; -using Stride.Core.Mathematics; - -namespace Stride.Graphics; - -/// -/// Describes a Sampler State object, which determines how to sample Texture data. -/// -/// -[DataContract] -[StructLayout(LayoutKind.Sequential)] -public struct SamplerStateDescription : IEquatable -{ - #region Default values - - /// - /// Default value for . - /// - public const TextureFilter DefaultFilter = TextureFilter.Linear; - /// - /// Default value for . - /// - public const TextureAddressMode DefaultAddressU = TextureAddressMode.Clamp; - /// - /// Default value for . - /// - public const TextureAddressMode DefaultAddressV = TextureAddressMode.Clamp; - /// - /// Default value for . - /// - public const TextureAddressMode DefaultAddressW = TextureAddressMode.Clamp; - - /// - /// Default value for (black). - /// - public static readonly Color4 DefaultBorderColor = default; // Black (0,0,0,0) - - /// - /// Default value for . - /// - public const int DefaultMaxAnisotropy = 16; - /// - /// Default value for . - /// - public const float DefaultMinMipLevel = -float.MaxValue; - /// - /// Default value for . - /// - public const float DefaultMaxMipLevel = float.MaxValue; - /// - /// Default value for . - /// - public const float DefaultMipMapLevelOfDetailBias = 0.0f; - - /// - /// Default value for . - /// - public const CompareFunction DefaultCompareFunction = CompareFunction.Never; - - #endregion - - /// - /// Initializes a new instance of the structure - /// with default values. - /// - /// - public SamplerStateDescription() - { - } - - /// - /// Initializes a new instance of the structure - /// with default values, and a specific Texture filtering and addressing mode. - /// - /// The Texture filtering mode. - /// The Texture addressing mode for U, V, and W coordinates. - /// - public SamplerStateDescription(TextureFilter filter, TextureAddressMode addressMode) : this() - { - Filter = filter; - AddressU = AddressV = AddressW = addressMode; - } - - - /// - /// The filtering method to use when sampling a Texture. - /// - public TextureFilter Filter = DefaultFilter; - - /// - /// The method to use for resolving a U texture coordinate that is outside the [0, 1] range. - /// - public TextureAddressMode AddressU = DefaultAddressU; - - /// - /// The method to use for resolving a V texture coordinate that is outside the [0, 1] range. - /// - public TextureAddressMode AddressV = DefaultAddressV; - - /// - /// The method to use for resolving a W texture coordinate that is outside the [0, 1] range. - /// - public TextureAddressMode AddressW = DefaultAddressW; - - /// - /// The offset to apply from the calculated mipmap level. - /// - /// - /// For example, if a Texture should be sampled at mipmap level 3 and - /// is 2, then the Texture will be sampled at mipmap level 5. - /// - public float MipMapLevelOfDetailBias = DefaultMipMapLevelOfDetailBias; - - /// - /// The clamping value used if or - /// is specified in . Valid values are between 1 and 16. - /// - public int MaxAnisotropy = DefaultMaxAnisotropy; - - /// - /// A function that compares sampled data against existing sampled data. - /// - /// - /// This function will be used when specifying one of the comparison filtering modes in - /// . - /// - public CompareFunction CompareFunction = DefaultCompareFunction; - - /// - /// The border color to use if is specified for - /// , , or . - /// - public Color4 BorderColor = DefaultBorderColor; - - /// - /// The lower end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap - /// level and any level higher than that is less detailed. - /// - public float MinMipLevel = DefaultMinMipLevel; - - /// - /// The upper end of the mipmap range to clamp access to, where 0 is the largest and most detailed mipmap - /// level and any level higher than that is less detailed. - /// - /// - /// This value must be greater than or equal to . - /// To have no upper limit set this to a large value such as . - /// - public float MaxMipLevel = DefaultMaxMipLevel; - - - /// - /// Returns a with default values. - /// - /// - /// The default values are: - /// - /// Linear filtering (). - /// for U, V, and W Texture coordinates. - /// No Mip LOD bias (0.0). - /// A default maximum anisotropy of 16x. - /// A comparison function that never passes (). - /// A border color of black ((0,0,0,0)). - /// - /// No clamping on Mip-levels ( is - and - /// is ). - /// - /// - /// - public static SamplerStateDescription Default => new(); - - - public static bool operator ==(SamplerStateDescription left, SamplerStateDescription right) - { - return left.Equals(right); - } - - public static bool operator !=(SamplerStateDescription left, SamplerStateDescription right) - { - return !(left == right); - } - - /// - public readonly bool Equals(SamplerStateDescription other) - { - return Filter == other.Filter - && AddressU == other.AddressU - && AddressV == other.AddressV - && AddressW == other.AddressW - && MipMapLevelOfDetailBias.Equals(other.MipMapLevelOfDetailBias) - && MaxAnisotropy == other.MaxAnisotropy - && CompareFunction == other.CompareFunction - && BorderColor.Equals(other.BorderColor) - && MinMipLevel.Equals(other.MinMipLevel) - && MaxMipLevel.Equals(other.MaxMipLevel); - } - - /// - public override readonly bool Equals(object obj) - { - return obj is SamplerStateDescription description && Equals(description); - } - - /// - public override readonly int GetHashCode() - { - var hash = new HashCode(); - hash.Add(Filter); - hash.Add(AddressU); - hash.Add(AddressV); - hash.Add(AddressW); - hash.Add(MipMapLevelOfDetailBias); - hash.Add(MaxAnisotropy); - hash.Add(CompareFunction); - hash.Add(BorderColor); - hash.Add(MinMipLevel); - hash.Add(MaxMipLevel); - return hash.ToHashCode(); - } - - /// - public override readonly string ToString() - { - return $"Sampler State {{Filter: {Filter}, Address UVW: {AddressU}, {AddressV}, {AddressW}, Mip LOD Bias: {MipMapLevelOfDetailBias}, Max Anisotropy: {MaxAnisotropy}, Compare Function: {CompareFunction}, Border Color: {BorderColor}, Min/Max MipLevel: {MinMipLevel} / {MaxMipLevel}}}"; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs deleted file mode 100644 index 24338655a3..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureAddressMode.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Graphics; - -/// -/// Identifies a technique for resolving Texture coordinates that are outside -/// of the boundaries of a Texture (outside the [0, 1] range). -/// -[DataContract("TextureAddressMode")] -public enum TextureAddressMode -{ - /// - /// Tile the Texture at every (u,v) integer junction. - /// For example, for u values between 0 and 3, the Texture is repeated three times. - /// - Wrap = 1, - - /// - /// Flip the Texture at every (u,v) integer junction. - /// For u values between 0 and 1, for example, the Texture is addressed normally; - /// between 1 and 2, the Texture is flipped (mirrored); - /// between 2 and 3, the Texture is normal again; and so on. - /// - Mirror = 2, - - /// - /// Texture coordinates outside the range [0, 1] are set to the Texture color at 0 or 1, respectively. - /// - Clamp = 3, - - /// - /// Texture coordinates outside the range [0, 1] are set to the border color specified in - /// or HLSL code. - /// - Border = 4, - - /// - /// Similar to and . - /// Takes the absolute value of the Texture coordinate (thus, mirroring around 0), and then - /// clamps to the maximum value. - /// - MirrorOnce = 5 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs b/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs deleted file mode 100644 index 7469d2e5aa..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Graphics/TextureFilter.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Graphics; - -/// -/// Identifies the filtering mode to use during Texture sampling. -/// -/// -/// During texture sampling, one or more texels are read and combined (this is called filtering) -/// to produce a single value. -/// -[DataContract("TextureFilter")] -public enum TextureFilter -{ - /// - /// Use point sampling for minification, magnification, and mip-level sampling. - /// - /// - /// Point sampling is the fastest texture filtering method. It is also the lowest quality, - /// because it just reads a single value and does not blend between texels. - /// - Point = 0, - - /// - /// Use point sampling for minification and magnification, and linear interpolation for mip-level sampling. - /// - /// - /// - MinMagPointMipLinear = 1, - - /// - /// Use point sampling for minification, linear interpolation for magnification, and point sampling for mip-level sampling. - /// - /// - /// - MinPointMagLinearMipPoint = 4, - - /// - /// Use point sampling for minification, linear interpolation for magnification and mip-level sampling. - /// - /// - /// - MinPointMagMipLinear = 5, - - /// - /// Use linear interpolation for minification, point sampling for magnification and mip-level sampling. - /// - /// - /// - MinLinearMagMipPoint = 16, - - /// - /// Use linear interpolation for minification, point sampling for magnification, and linear interpolation for mip-level sampling. - /// - /// - /// - MinLinearMagPointMipLinear = 17, - - /// - /// Use linear interpolation for minification and magnification, and point sampling for mip-level sampling. - /// - MinMagLinearMipPoint = 20, - - /// - /// Use linear interpolation for minification, magnification, and mip-level sampling. - /// - /// - /// Linear interpolation is slower than point sampling, but produces higher quality results. - /// Two samples are taken across the sampling direction, and a linearly interpolated value - /// is generated between those by blending them. - /// - Linear = 21, - - /// - /// Use anisotropic interpolation for minification, magnification, and mip-level sampling. - /// - /// - /// - /// When viewing a surface at a shallow angle, the Texture is stretched according to the perspective. - /// Point or linear interpolation sample in a circular area independent of the viewing angle, producing a - /// blurry or smeared appearance. - /// - /// - /// Anisotropic filtering addresses this by sampling Textures differently depending on the angle of the - /// surface relative to the viewer. - /// Instead of assuming a circular sampling footprint (as in isotropic methods like bilinear filtering), - /// it stretches the sampling region into an ellipse or more complex shapes that better fit the distorted - /// projection of the Texture, and takes more samples along that direction, depending on the anisotropy level. - /// - /// - /// It also interacts with mipmapping, selecting and interpolating from the appropriate mipmap levels, - /// to ensure that the correct Texture resolution is used, even when viewed at extreme angles. - /// - /// - Anisotropic = 85, - - /// - /// Use point sampling for minification, magnification, and mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - /// - /// Comparison filtering compares each sampled texel against a comparison value. - /// The boolean result is blended the same way that normal texture filtering is blended. - /// - /// - /// Comparison filters only work with textures that have the following formats: - /// , , - /// , and . - /// - /// - ComparisonPoint = 128, - - /// - /// Use point sampling for minification and magnification, and linear interpolation for mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinMagPointMipLinear = 129, - - /// - /// Use point sampling for minification, linear interpolation for magnification, and point sampling for mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinPointMagLinearMipPoint = 132, - - /// - /// Use point sampling for minification, and linear interpolation for magnification and mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinPointMagMipLinear = 133, - - /// - /// Use linear interpolation for minification, and point sampling for magnification and mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinLinearMagMipPoint = 144, - - /// - /// Use linear interpolation for minification, point sampling for magnification, and linear interpolation for mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinLinearMagPointMipLinear = 145, - - /// - /// Use linear interpolation for minification and magnification, and point sampling for mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonMinMagLinearMipPoint = 148, - - /// - /// Use linear interpolation for minification, magnification, and mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonLinear = 149, - - /// - /// Use anisotropic interpolation for minification, magnification, and mip-level sampling. - /// Compare the result to the comparison value. - /// - /// - ComparisonAnisotropic = 213 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs b/sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs deleted file mode 100644 index ba6377679a..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/Mathematics/Color4.cs +++ /dev/null @@ -1,628 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// ----------------------------------------------------------------------------- -// Original code from SlimMath project. http://code.google.com/p/slimmath/ -// Greetings to SlimDX Group. Original code published with the following license: -// ----------------------------------------------------------------------------- -/* -* Copyright (c) 2007-2011 SlimDX Group -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -* THE SOFTWARE. -*/ - -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Stride.Core.Mathematics; - -/// -/// A RGBA color value with 32-bit floating-point precision per channel. -/// -[DataContract("Color4")] -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public struct Color4 : IEquatable, ISpanFormattable -{ - /// - /// The Black color (0, 0, 0, 1). - /// - public static readonly Color4 Black = new(red: 0, green: 0, blue: 0); - - /// - /// The White color (1, 1, 1, 1). - /// - public static readonly Color4 White = new(red: 1, green: 1, blue: 1); - - /// - /// The transparent black color (0, 0, 0, 0). - /// - public static readonly Color4 TransparentBlack = default; - - /// - /// The red component of the color. - /// - public float R; - - /// - /// The green component of the color. - /// - public float G; - - /// - /// The blue component of the color. - /// - public float B; - - /// - /// The alpha component of the color. - /// - public float A; - - /// - /// Initializes a new instance of the struct. - /// - /// The value that will be assigned to all components. - public Color4(float value) - { - R = value; - G = value; - B = value; - A = value; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The red component of the color. - /// The green component of the color. - /// The blue component of the color. - /// The alpha component of the color. - public Color4(float red, float green, float blue, float alpha = 1f) - { - R = red; - G = green; - B = blue; - A = alpha; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all four color components in RGBA order. - public Color4(uint rgba) - { - A = ((rgba >> 24) & 255) / 255.0f; - B = ((rgba >> 16) & 255) / 255.0f; - G = ((rgba >> 8) & 255) / 255.0f; - R = (rgba & 255) / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// A packed integer containing all four color components in RGBA order. - public Color4(int rgba) - { - A = ((rgba >> 24) & 255) / 255.0f; - B = ((rgba >> 16) & 255) / 255.0f; - G = ((rgba >> 8) & 255) / 255.0f; - R = (rgba & 255) / 255.0f; - } - - /// - /// Initializes a new instance of the struct. - /// - /// The values to assign to the red, green, blue, and alpha components of the color. This must be an array with four elements. - /// Thrown when is null. - /// Thrown when contains more or less than four elements. - public Color4(float[] values) - { - ArgumentNullException.ThrowIfNull(values); - if (values.Length is not 3 and not 4) - throw new ArgumentOutOfRangeException(nameof(values), "There must be 3 or 4 float[] values for Color4."); - - R = values[0]; - G = values[1]; - B = values[2]; - A = values.Length >= 4 ? values[3] : 1f; - } - - /// - /// Gets or sets the component at the specified index. - /// - /// The value of the red, green, blue, and alpha components, depending on the index. - /// The index of the component to access. Use 0 for the alpha component, 1 for the red component, 2 for the green component, and 3 for the blue component. - /// The value of the component at the specified index. - /// Thrown when the is out of the range [0, 3]. - public float this[int index] - { - readonly get - { - return index switch - { - 0 => R, - 1 => G, - 2 => B, - 3 => A, - _ => throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive."), - }; - } - - set - { - switch (index) - { - case 0: R = value; break; - case 1: G = value; break; - case 2: B = value; break; - case 3: A = value; break; - default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive."); - } - } - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public readonly int ToBgra() - { - uint a = (uint)(A * 255.0f) & 255; - uint r = (uint)(R * 255.0f) & 255; - uint g = (uint)(G * 255.0f) & 255; - uint b = (uint)(B * 255.0f) & 255; - - uint value = b; - value |= g << 8; - value |= r << 16; - value |= a << 24; - - return (int)value; - } - - /// - /// Converts the color into a packed integer. - /// - public readonly void ToBgra(out byte r, out byte g, out byte b, out byte a) - { - a = (byte)(A * 255.0f); - r = (byte)(R * 255.0f); - g = (byte)(G * 255.0f); - b = (byte)(B * 255.0f); - } - - /// - /// Converts the color into a packed integer. - /// - /// A packed integer containing all four color components. - public readonly int ToRgba() - { - uint a = (uint)(A * 255.0f) & 255; - uint r = (uint)(R * 255.0f) & 255; - uint g = (uint)(G * 255.0f) & 255; - uint b = (uint)(B * 255.0f) & 255; - - uint value = r; - value |= g << 8; - value |= b << 16; - value |= a << 24; - - return (int)value; - } - - /// - /// Creates an array containing the elements of the color. - /// - /// A four-element array containing the components of the color. - public readonly float[] ToArray() - { - return [R, G, B, A]; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// When the method completes, completes the sum of the two colors. - public static void Add(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) - { - result.A = left.A + right.A; - result.R = left.R + right.R; - result.G = left.G + right.G; - result.B = left.B + right.B; - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color4 Add(Color4 left, Color4 right) - { - return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A); - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// WHen the method completes, contains the difference of the two colors. - public static void Subtract(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) - { - result.A = left.A - right.A; - result.R = left.R - right.R; - result.G = left.G - right.G; - result.B = left.B - right.B; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract - /// The difference of the two colors. - public static Color4 Subtract(Color4 left, Color4 right) - { - return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// When the method completes, contains the modulated color. - public static void Modulate(ref readonly Color4 left, ref readonly Color4 right, out Color4 result) - { - result.A = left.A * right.A; - result.R = left.R * right.R; - result.G = left.G * right.G; - result.B = left.B * right.B; - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color4 Modulate(Color4 left, Color4 right) - { - return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A); - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// When the method completes, contains the scaled color. - public static void Scale(ref readonly Color4 value, float scale, out Color4 result) - { - result.A = value.A * scale; - result.R = value.R * scale; - result.G = value.G * scale; - result.B = value.B * scale; - } - - /// - /// Scales a color. - /// - /// The color to scale. - /// The amount by which to scale. - /// The scaled color. - public static Color4 Scale(Color4 value, float scale) - { - return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// When the method completes, contains the negated color. - public static void Negate(ref readonly Color4 value, out Color4 result) - { - result.A = 1.0f - value.A; - result.R = 1.0f - value.R; - result.G = 1.0f - value.G; - result.B = 1.0f - value.B; - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// The negated color. - public static Color4 Negate(Color4 value) - { - return new Color4(1.0f - value.R, 1.0f - value.G, 1.0f - value.B, 1.0f - value.A); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// When the method completes, contains the clamped value. - public static void Clamp(ref readonly Color4 value, ref readonly Color4 min, ref readonly Color4 max, out Color4 result) - { - float alpha = value.A; - alpha = (alpha > max.A) ? max.A : alpha; - alpha = (alpha < min.A) ? min.A : alpha; - - float red = value.R; - red = (red > max.R) ? max.R : red; - red = (red < min.R) ? min.R : red; - - float green = value.G; - green = (green > max.G) ? max.G : green; - green = (green < min.G) ? min.G : green; - - float blue = value.B; - blue = (blue > max.B) ? max.B : blue; - blue = (blue < min.B) ? min.B : blue; - - result = new Color4(red, green, blue, alpha); - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. - /// The maximum value. - /// The clamped value. - public static Color4 Clamp(Color4 value, Color4 min, Color4 max) - { - Clamp(ref value, ref min, ref max, out var result); - return result; - } - - /// - /// Premultiplies the color components by the alpha value. - /// - /// The color to premultiply. - /// A color with premultiplied alpha. - public static Color4 PremultiplyAlpha(Color4 value) - { - return new Color4(value.R * value.A, value.G * value.A, value.B * value.A, value.A); - } - - /// - /// Adds two colors. - /// - /// The first color to add. - /// The second color to add. - /// The sum of the two colors. - public static Color4 operator +(Color4 left, Color4 right) - { - return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A); - } - - /// - /// Assert a color (return it unchanged). - /// - /// The color to assert (unchanged). - /// The asserted (unchanged) color. - public static Color4 operator +(Color4 value) - { - return value; - } - - /// - /// Subtracts two colors. - /// - /// The first color to subtract. - /// The second color to subtract. - /// The difference of the two colors. - public static Color4 operator -(Color4 left, Color4 right) - { - return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A); - } - - /// - /// Negates a color. - /// - /// The color to negate. - /// A negated color. - public static Color4 operator -(Color4 value) - { - return new Color4(-value.R, -value.G, -value.B, -value.A); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color4 operator *(float scale, Color4 value) - { - return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); - } - - /// - /// Scales a color. - /// - /// The factor by which to scale the color. - /// The color to scale. - /// The scaled color. - public static Color4 operator *(Color4 value, float scale) - { - return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale); - } - - /// - /// Modulates two colors. - /// - /// The first color to modulate. - /// The second color to modulate. - /// The modulated color. - public static Color4 operator *(Color4 left, Color4 right) - { - return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A); - } - - /// - /// Tests for equality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has the same value as ; otherwise, false. - public static bool operator ==(Color4 left, Color4 right) - { - return left.Equals(right); - } - - /// - /// Tests for inequality between two objects. - /// - /// The first value to compare. - /// The second value to compare. - /// true if has a different value than ; otherwise, false. - public static bool operator !=(Color4 left, Color4 right) - { - return !left.Equals(right); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// - /// The result of the conversion. - /// - public static explicit operator int(Color4 value) - { - return value.ToRgba(); - } - - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// - /// The result of the conversion. - /// - public static explicit operator Color4(int value) - { - return new Color4(value); - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override readonly string ToString() => $"{this}"; - - /// - /// Returns a that represents this instance. - /// - /// The format. - /// The format provider. - /// - /// A that represents this instance. - /// - public readonly string ToString([StringSyntax(StringSyntaxAttribute.NumericFormat)] string? format, IFormatProvider? formatProvider) - { - var handler = new DefaultInterpolatedStringHandler(11, 4, formatProvider); - handler.AppendLiteral("A:"); - handler.AppendFormatted(A, format); - handler.AppendLiteral(" R:"); - handler.AppendFormatted(R, format); - handler.AppendLiteral(" G:"); - handler.AppendFormatted(G, format); - handler.AppendLiteral(" B:"); - handler.AppendFormatted(B, format); - return handler.ToStringAndClear(); - } - - bool ISpanFormattable.TryFormat(Span destination, out int charsWritten, ReadOnlySpan format, IFormatProvider? provider) - { - var format1 = format.Length > 0 ? format.ToString() : null; - var handler = new MemoryExtensions.TryWriteInterpolatedStringHandler(11, 4, destination, provider, out _); - handler.AppendLiteral("A:"); - handler.AppendFormatted(A, format1); - handler.AppendLiteral(" R:"); - handler.AppendFormatted(R, format1); - handler.AppendLiteral(" G:"); - handler.AppendFormatted(G, format1); - handler.AppendLiteral(" B:"); - handler.AppendFormatted(B, format1); - return destination.TryWrite(ref handler, out charsWritten); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override readonly int GetHashCode() - { - return HashCode.Combine(A, R, G, B); - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public readonly bool Equals(Color4 other) - { - return A == other.A && R == other.R && G == other.G && B == other.B; - } - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override readonly bool Equals(object? value) - { - return value is Color4 color && Equals(color); - } - - /// - /// Deconstructs the vector's components into named variables. - /// - /// The R component - /// The G component - /// The B component - /// The A component - public readonly void Deconstruct(out float r, out float g, out float b, out float a) - { - r = R; - g = G; - b = B; - a = A; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs deleted file mode 100644 index 121e4f81aa..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ConstantBufferType.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// Describes the type of constant buffer. - /// - [DataContract] - public enum ConstantBufferType - { - /// - /// An unknown buffer. - /// - Unknown, - - /// - /// A standard constant buffer - /// - ConstantBuffer, - - /// - /// A texture buffer - /// - TextureBuffer, - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs deleted file mode 100644 index abfb9bf11f..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectConstantBufferDescription.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Diagnostics; -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// Description of a constant buffer. - /// - [DataContract] - [DebuggerDisplay("cbuffer {Name} : {Size} bytes")] - public class EffectConstantBufferDescription - { - /// - /// The name of this constant buffer. - /// - public string Name; - - /// - /// The size in bytes. - /// - public int Size; - - /// - /// The type of constant buffer. - /// - public ConstantBufferType Type; - - /// - /// The members of this constant buffer. - /// - public EffectValueDescription[] Members; - - //[DataMemberIgnore] - //public ObjectId Hash; - - /// - /// Clone the current instance of the constant buffer description. - /// - /// A clone copy of the description - public EffectConstantBufferDescription Clone() - { - return (EffectConstantBufferDescription)MemberwiseClone(); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs deleted file mode 100644 index 63ebb4a31a..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterClass.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders; - -/// -/// Defines the class of a Effect / Shader parameter. -/// -/// -/// The class of a Effect / Shader parameter is not a C# ; it identifies the kind of variable -/// such as scalar, vector, object, and so on. -/// -[DataContract] -public enum EffectParameterClass : byte -{ - /// - /// The Shader parameter is a scalar value. - /// - Scalar = 0, - - /// - /// The Shader parameter is a vector value. - /// - Vector = 1, - - /// - /// The Shader parameter is a row-major matrix. - /// - MatrixRows = 2, - - /// - /// The Shader parameter is a column-major matrix. - /// - MatrixColumns = 3, - - /// - /// The Shader parameter is an object. - /// - Object = 4, - - /// - /// The Shader parameter is a structure. - /// - Struct = 5, - - /// - /// The Shader parameter is a class. - /// - InterfaceClass = 6, - - /// - /// The Shader parameter is an interface. - /// - InterfacePointer = 7, - - /// - /// The Shader parameter is a Sampler State object. - /// - Sampler = 8, - - /// - /// The Shader parameter is a Shader Resource View. - /// - ShaderResourceView = 9, - - /// - /// The Shader parameter is a Constant Buffer. - /// - ConstantBuffer = 10, - - /// - /// The Shader parameter is a Texture. - /// - TextureBuffer = 11, - - /// - /// The Shader parameter is an Unordered Access View. - /// - UnorderedAccessView = 12, - - /// - /// The Shader parameter is a vector value that represents a color. - /// - Color = 13 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs deleted file mode 100644 index 530edb6953..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterKeyInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.Diagnostics; - -using Stride.Core; -using Stride.Rendering; - -namespace Stride.Shaders; - -/// -/// Contains information about a key identifying an Effect / Shader parameter. -/// -[DataContract] -[DebuggerDisplay("{Key} ({KeyName})")] -public struct EffectParameterKeyInfo -{ - /// - /// The key that identifies the Effect / Shader parameter. - /// - [DataMemberIgnore] - public ParameterKey Key; - - /// - /// The name of the Effect / Shader parameter. - /// - public string KeyName; -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs deleted file mode 100644 index 98daa0793b..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectParameterType.cs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders; - -/// -/// Values that identify various types of data, Textures, and Buffers that can be assigned to a Shader parameter. -/// -[DataContract] -public enum EffectParameterType : byte -{ - /// - /// The parameter is a reference. - /// - Void = 0, - - /// - /// The parameter is a boolean (i.e. ). - /// - Bool = 1, - - /// - /// The parameter is an integer (i.e. ). - /// - Int = 2, - - /// - /// The parameter is a single precision (32-bit) floating-point number (i.e. ). - /// - Float = 3, - - /// - /// The parameter is a . - /// - String = 4, - - /// - /// The parameter is a Texture. - /// - Texture = 5, - - /// - /// The parameter is a 1D Texture. - /// - Texture1D = 6, - - /// - /// The parameter is a 2D Texture. - /// - Texture2D = 7, - - /// - /// The parameter is a 3D Texture. - /// - Texture3D = 8, - - /// - /// The parameter is a Texture Cube. - /// - TextureCube = 9, - - /// - /// The parameter is a Sampler. - /// - Sampler = 10, - - /// - /// The parameter is a 1D Sampler. - /// - Sampler1D = 11, - - /// - /// The parameter is a 2D Sampler. - /// - Sampler2D = 12, - - /// - /// The parameter is a 3D Sampler. - /// - Sampler3D = 13, - - /// - /// The parameter is a Cube Sampler. - /// - SamplerCube = 14, - - /// - /// The parameter is an unsigned integer (i.e. ). - /// - UInt = 19, - - /// - /// The parameter is an 8-bit unsigned integer (i.e. ). - /// - UInt8 = 20, - - /// - /// The parameter is a Buffer. - /// - Buffer = 25, - - /// - /// The parameter is a Constant Buffer. - /// - ConstantBuffer = 26, - - /// - /// The parameter is a Texture. - /// - TextureBuffer = 27, - - /// - /// The parameter is a 1D Texture Array. - /// - Texture1DArray = 28, - - /// - /// The parameter is a 2D Texture Array. - /// - Texture2DArray = 29, - - /// - /// The parameter is a Multi-sampled 2D Texture. - /// - Texture2DMultisampled = 32, - - /// - /// The parameter is a Multi-sampled 2D Texture Array. - /// - Texture2DMultisampledArray = 33, - - /// - /// The parameter is a Cube Texture Array. - /// - TextureCubeArray = 34, - - /// - /// The parameter is a double precision (64-bit) floating-point number. - /// - Double = 39, - - /// - /// The parameter is a 1D Read-and-Write Texture. - /// - RWTexture1D = 40, - - /// - /// The parameter is an Array of 1D Read-and-Write Textures. - /// - RWTexture1DArray = 41, - - /// - /// The parameter is a 2D Read-and-Write Texture. - /// - RWTexture2D = 42, - - /// - /// The parameter is an Array of 2D Read-and-Write Textures. - /// - RWTexture2DArray = 43, - - /// - /// The parameter is a 3D Read-and-Write Texture. - /// - RWTexture3D = 44, - - /// - /// The parameter is a Read-and-Write Buffer. - /// - RWBuffer = 45, - - /// - /// The parameter is a Byte-Address Buffer. - /// - ByteAddressBuffer = 46, - - /// - /// The parameter is a Read-and-Write Byte-Address Buffer. - /// - RWByteAddressBuffer = 47, - - /// - /// The parameter is a Structured Buffer. - /// - StructuredBuffer = 48, - - /// - /// The parameter is a Read-and-Write Structured Buffer. - /// - RWStructuredBuffer = 49, - - /// - /// The parameter is an Append Structured Buffer. - /// - AppendStructuredBuffer = 50, - - /// - /// The parameter is a Consume Structured Buffer. - /// - ConsumeStructuredBuffer = 51 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs deleted file mode 100644 index 4aa0cd688d..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectReflection.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// The reflection data describing the parameters of a shader. - /// - [DataContract] - public class EffectReflection - { - /// - /// Initializes a new instance of the class. - /// - public EffectReflection() - { - SamplerStates = []; - ResourceBindings = []; - ConstantBuffers = []; - ShaderStreamOutputDeclarations = []; - InputAttributes = []; - } - - /// - /// Gets or sets the sampler states. - /// - /// The sampler states. - public List SamplerStates { get; set; } - - /// - /// Gets the parameter binding descriptions. - /// - /// The resource bindings. - public List ResourceBindings { get; set; } - - /// - /// Gets the constant buffer descriptions (if any). - /// - /// The constant buffers. - public List ConstantBuffers { get; set; } - - /// - /// Gets or sets the stream output declarations. - /// - /// The stream output declarations. - public List ShaderStreamOutputDeclarations { get; set; } - - /// - /// Gets or sets the stream output strides. - /// - /// The stream output strides. - public int[] StreamOutputStrides { get; set; } - - /// - /// Gets or sets the stream output rasterized stream. - /// - /// The stream output rasterized stream. - public int StreamOutputRasterizedStream { get; set; } - - public List InputAttributes { get; set; } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs deleted file mode 100644 index 8b59e6f8cc..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectResourceBindingDescription.cs +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders; - -[DataContract] -public struct EffectResourceBindingDescription -{ - /// - /// Describes a shader parameter for a resource type. - /// - public EffectParameterKeyInfo KeyInfo; - - public EffectParameterClass Class; - - public EffectParameterType Type; - - public EffectTypeDescription ElementType; - - public string RawName; - - public string ResourceGroup; - - public ShaderStage Stage; - - public int SlotStart; - - public int SlotCount; - - public string LogicalGroup; - - - /// - public override readonly string ToString() - { - if (SlotCount <= 0) - return $""; - - string stage = Stage != ShaderStage.None ? $"{Stage} " : ""; - string bindingName = KeyInfo.Key is not null && !string.IsNullOrEmpty(RawName) - ? $" {KeyInfo.Key} -> {RawName}" - : ""; - string slots = SlotCount == 1 - ? $"(Slot {SlotStart})" - : $"(Slots {SlotStart} to {SlotStart + SlotCount - 1})"; - - return $"Binding [{stage}{Class}{bindingName} {slots}]"; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs deleted file mode 100644 index da2bc2c51c..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectSamplerStateBinding.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; -using Stride.Rendering; -using Stride.Graphics; - -namespace Stride.Shaders; - -[DataContract] -public class EffectSamplerStateBinding -{ - /// - /// Binding to a sampler. - /// - [DataMemberIgnore] - public ParameterKey Key; - - public string KeyName; - - public SamplerStateDescription Description; - - - public EffectSamplerStateBinding() { } - - public EffectSamplerStateBinding(string keyName, SamplerStateDescription description) - { - KeyName = keyName; - Description = description; - } - - - /// - public override string ToString() - { - return $"SamplerState {Key?.Name ?? KeyName} ({Description.Filter})"; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs deleted file mode 100644 index 6db7e04129..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeDescription.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders; - -[DataContract] -public struct EffectTypeDescription -{ - /// - /// Describes a shader parameter type. - /// - public EffectParameterClass Class; - - public EffectParameterType Type; - - public int RowCount; - - public int ColumnCount; - - public int Elements; - - public int ElementSize; - - public string Name; - - public EffectTypeMemberDescription[] Members; - - - /// - public override readonly string ToString() - { - string name = Name is not null ? $" {Name}" : ""; - string rowsAndCols = RowCount > 1 || ColumnCount > 1 ? $" {RowCount}x{ColumnCount}" : ""; - return $"{Class}{rowsAndCols}{name}"; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs deleted file mode 100644 index 5b25edb05f..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectTypeMemberDescription.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Diagnostics; -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// Describes a shader parameter member. - /// - [DataContract] - [DebuggerDisplay("{Name}: {Type}")] - public struct EffectTypeMemberDescription - { - /// - /// The name of this member. - /// - public string Name; - - /// - /// Offset in bytes into the parent structure (0 if not a structure member). - /// - public int Offset; - - /// - /// The type of this member. - /// - public EffectTypeDescription Type; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs deleted file mode 100644 index 27d961a889..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/EffectValueDescription.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.Diagnostics; - -using Stride.Core; - -namespace Stride.Shaders; - -[DataContract] -[DebuggerDisplay("{Type.Class}{Type.RowCount}x{Type.ColumnCount} {KeyInfo.KeyName} -> {RawName}")] -public struct EffectValueDescription -{ - /// - /// Describes a shader parameter for a valuetype (usually stored in constant buffers). - /// - public EffectTypeDescription Type; - - public EffectParameterKeyInfo KeyInfo; - - public string RawName; - - public int Offset; - - public int Size; - - public object DefaultValue; - - public string LogicalGroup; -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs deleted file mode 100644 index 1aadbf6c2f..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderInputAttributeDescription.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders -{ - [DataContract] - public struct ShaderInputAttributeDescription - { - public int Location; - - public string SemanticName; - - public int SemanticIndex; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs deleted file mode 100644 index 0be41b5258..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStage.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core; - -namespace Stride.Shaders; - -/// -/// Specifies a particular shader stage. -/// -[DataContract] -public enum ShaderStage -{ - /// - /// No shader stage defined. - /// - None = 0, - - /// - /// The Vertex Shader stage. - /// - Vertex = 1, - - /// - /// The Hull Shader stage. - /// - Hull = 2, - - /// - /// The Domain Shader stage. - /// - Domain = 3, - - /// - /// The Geometry Shader stage. - /// - Geometry = 4, - - /// - /// The Pixel Shader stage. - /// - Pixel = 5, - - /// - /// The Compute Shader stage. - /// - Compute = 6 -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs deleted file mode 100644 index 91ea8365e3..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersReflection/ShaderStreamOutputDeclarationEntry.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// Description of a StreamOutput declaration entry. - /// - [DataContract] - public struct ShaderStreamOutputDeclarationEntry - { - /// - /// The stream index. - /// - public int Stream; - - /// - /// The semantic name. - /// - public string SemanticName; - - /// - /// The semantic index. - /// - public int SemanticIndex; - - /// - /// The start component - /// - public byte StartComponent; - - /// - /// The component count - /// - public byte ComponentCount; - - /// - /// The output slot - /// - public byte OutputSlot; - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs deleted file mode 100644 index 92a61ee993..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/HashSourceCollection.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; - -using Stride.Core; -using Stride.Core.Storage; - -namespace Stride.Shaders; - -/// -/// A collection associating the Shader source URLs and their corresponding s. -/// -[DataContract] -public sealed class HashSourceCollection : Dictionary, IEquatable -{ - /// - /// Initializes a new instance of the class. - /// - public HashSourceCollection() { } - - - /// - public bool Equals(HashSourceCollection other) - { - if (other is null) - return false; - if (ReferenceEquals(this, other)) - return true; - - return Utilities.Compare(this, other); - } - - /// - public override bool Equals(object obj) - { - return obj is HashSourceCollection other && Equals(other); - } - - /// - public override int GetHashCode() - { - return Utilities.GetHashCode(this); - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs deleted file mode 100644 index bbc591d2af..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectId.cs +++ /dev/null @@ -1,334 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Stride.Core.Storage; - -/// -/// A hash to uniquely identify data. -/// -[StructLayout(LayoutKind.Sequential, Pack = 4)] -#if !STRIDE_ASSEMBLY_PROCESSOR -[DataContract("ObjectId"),Serializable] -#endif -public unsafe partial struct ObjectId : IEquatable, IComparable -{ - // *************************************************************** - // NOTE: This file is shared with the AssemblyProcessor. - // If this file is modified, the AssemblyProcessor has to be - // recompiled separately. See build\Stride-AssemblyProcessor.sln - // *************************************************************** - - // Murmurshash3 ahsh size is 128 bits. - public const int HashSize = 16; - public const int HashStringLength = HashSize * 2; - private const int HashSizeInUInt = HashSize / sizeof(uint); - private const string HexDigits = "0123456789abcdef"; - - public static readonly ObjectId Empty = new(); - - private uint hash1; - private uint hash2; - private uint hash3; - private uint hash4; - - /// - /// Initializes a new instance of the struct. - /// - /// The hash. - /// hash - /// ObjectId value doesn't match expected size. - public ObjectId(byte[] hash) - { -#if NET7_0_OR_GREATER - ArgumentNullException.ThrowIfNull(hash); -#else - if (hash is null) throw new ArgumentNullException(nameof(hash)); -#endif // NET7_0_OR_GREATER - - if (hash.Length != HashSize) - throw new InvalidOperationException("ObjectId value doesn't match expected size."); - - fixed (byte* hashSource = hash) - { - var hashSourceCurrent = (uint*)hashSource; - hash1 = *hashSourceCurrent++; - hash2 = *hashSourceCurrent++; - hash3 = *hashSourceCurrent++; - hash4 = *hashSourceCurrent; - } - } - - public ObjectId(uint hash1, uint hash2, uint hash3, uint hash4) - { - this.hash1 = hash1; - this.hash2 = hash2; - this.hash3 = hash3; - this.hash4 = hash4; - } - - public static explicit operator ObjectId(Guid guid) - { - return Unsafe.As(ref guid); - } - - public static ObjectId Combine(ObjectId left, ObjectId right) - { - // Note: we don't carry (probably not worth the performance hit) - return new ObjectId - { - hash1 = left.hash1 * 3 + right.hash1, - hash2 = left.hash2 * 3 + right.hash2, - hash3 = left.hash3 * 3 + right.hash3, - hash4 = left.hash4 * 3 + right.hash4, - }; - } - - public static void Combine(ref ObjectId left, ref ObjectId right, out ObjectId result) - { - // Note: we don't carry (probably not worth the performance hit) - result = new ObjectId - { - hash1 = left.hash1 * 3 + right.hash1, - hash2 = left.hash2 * 3 + right.hash2, - hash3 = left.hash3 * 3 + right.hash3, - hash4 = left.hash4 * 3 + right.hash4, - }; - } - - /// - /// Performs an explicit conversion from to []. - /// - /// The object id. - /// The result of the conversion. - public static explicit operator byte[](ObjectId objectId) - { - var result = new byte[HashSize]; - var hashSource = &objectId.hash1; - fixed (byte* hashDest = result) - { - var hashSourceCurrent = (uint*)hashSource; - var hashDestCurrent = (uint*)hashDest; - for (var i = 0; i < HashSizeInUInt; ++i) - *hashDestCurrent++ = *hashSourceCurrent++; - } - return result; - } - - /// - /// Implements the ==. - /// - /// The left. - /// The right. - /// The result of the operator. - public static bool operator ==(ObjectId left, ObjectId right) - { - return left.Equals(right); - } - - /// - /// Implements the !=. - /// - /// The left. - /// The right. - /// The result of the operator. - public static bool operator !=(ObjectId left, ObjectId right) - { - return !left.Equals(right); - } - - /// - /// Tries to parse an from a string. - /// - /// The input hexa string. - /// The result ObjectId. - /// true if parsing was successfull, false otherwise - public static bool TryParse(string input, out ObjectId result) - { - if (input.Length != HashStringLength) - { - result = Empty; - return false; - } - - var hash = stackalloc byte[HashSize]; - for (var i = 0; i < HashStringLength; i += 2) - { - var c1 = input[i]; - var c2 = input[i + 1]; - - int digit1, digit2; - if (((digit1 = HexDigits.IndexOf(c1)) == -1) - || ((digit2 = HexDigits.IndexOf(c2)) == -1)) - { - result = Empty; - return false; - } - - hash[i >> 1] = (byte)((digit1 << 4) | digit2); - } - - var hashSpan = new Span(hash, HashSizeInUInt); - result = new ObjectId(hashSpan[0], hashSpan[1], hashSpan[2], hashSpan[3]); - return true; - } - - /// - public bool Equals(ObjectId other) - { - // Compare content - fixed (uint* xPtr = &hash1) - { - var x1 = xPtr; - var y1 = &other.hash1; - - for (var i = 0; i < HashSizeInUInt; ++i) - { - if (*x1++ != *y1++) - return false; - } - } - - return true; - } - - /// - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) return false; - return obj is ObjectId objectId && Equals(objectId); - } - - /// - public override readonly int GetHashCode() => (int)hash1; - - /// - public int CompareTo(ObjectId other) - { - // Compare content - fixed (uint* xPtr = &hash1) - { - var x1 = xPtr; - var y1 = &other.hash1; - - for (var i = 0; i < HashSizeInUInt; ++i) - { - var compareResult = (*x1++).CompareTo(*y1++); - if (compareResult != 0) - return compareResult; - } - } - - return 0; - } - - public override string ToString() - { -#if NET6_0_OR_GREATER - fixed (uint* hashStart = &hash1) - { - return string.Create(HashStringLength, (IntPtr)hashStart, (c, state) => - { - var hashBytes = (byte*)state; - for (var i = 0; i < HashStringLength; ++i) - { - var index0 = i >> 1; - var b = (byte)(hashBytes[index0] >> 4); - c[i++] = HexDigits[b]; - - b = (byte)(hashBytes[index0] & 0x0F); - c[i] = HexDigits[b]; - } - }); - } -#else - Span span = stackalloc char[HashStringLength]; - - fixed (uint* hashStart = &hash1) - { - var hashBytes = (byte*)hashStart; - for (var i = 0; i < HashStringLength; ++i) - { - var index0 = i >> 1; - var b = (byte)(hashBytes[index0] >> 4); - span[i++] = HexDigits[b]; - - b = (byte)(hashBytes[index0] & 0x0F); - span[i] = HexDigits[b]; - } - } - return ((ReadOnlySpan)span).ToString(); -#endif - } - - /// - /// Gets a from this object identifier. - /// - /// Guid. - public Guid ToGuid() - { - return Unsafe.As(ref this); - } - - /// - /// News this instance. - /// - /// ObjectId. - public static ObjectId New() - { - return FromBytes(Guid.NewGuid().ToByteArray()); - } - - /// - /// Computes a hash from a byte buffer. - /// - /// The byte buffer. - /// The hash of the object. - /// buffer - public static ObjectId FromBytes(ReadOnlySpan buffer) - { - var builder = new ObjectIdBuilder(); - builder.Write(buffer); - return builder.ComputeHash(); - } - - /// - /// Computes a hash from a byte buffer. - /// - /// The byte buffer. - /// The hash of the object. - /// buffer - public static ObjectId FromBytes(byte[] buffer) - { -#if NET7_0_OR_GREATER - ArgumentNullException.ThrowIfNull(buffer); -#else - if (buffer is null) throw new ArgumentNullException(nameof(buffer)); -#endif // NET7_0_OR_GREATER - - return FromBytes(buffer, 0, buffer.Length); - } - - /// - /// Computes a hash from a byte buffer. - /// - /// The byte buffer. - /// The offset into the buffer. - /// The number of bytes to read from the buffer starting at offset position. - /// The hash of the object. - /// buffer - public static ObjectId FromBytes(byte[] buffer, int offset, int count) - { -#if NET7_0_OR_GREATER - ArgumentNullException.ThrowIfNull(buffer); -#else - if (buffer is null) throw new ArgumentNullException(nameof(buffer)); -#endif // NET7_0_OR_GREATER - - var builder = new ObjectIdBuilder(); - builder.Write(buffer, offset, count); - return builder.ComputeHash(); - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs deleted file mode 100644 index 0f753dc6d9..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ObjectIdBuilder.cs +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// (ignore analyzers) -// -// Copyright 2012 Darren Kopp -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Stride.Core.Storage; - -/// -/// A builder for using Murmurshash3 128 bits -/// -[StructLayout(LayoutKind.Sequential, Pack = 4)] -public unsafe struct ObjectIdBuilder -{ - // *************************************************************** - // NOTE: This file is shared with the AssemblyProcessor. - // If this file is modified, the AssemblyProcessor has to be - // recompiled separately. See build\Stride-AssemblyProcessor.sln - // *************************************************************** - - private readonly uint seed; - const uint C1 = 0x239b961b; - const uint C2 = 0xab0e9789; - const uint C3 = 0x38b34ae5; - const uint C4 = 0xa1e38b93; - - public ObjectIdBuilder(uint seed = 0) - { - this.seed = seed; - - // initialize hash values to seed values - H1 = H2 = H3 = H4 = seed; - currentLength = 0; - - currentBlock1 = 0; - currentBlock2 = 0; - currentBlock3 = 0; - currentBlock4 = 0; - } - - public uint Seed => seed; - public int Length => currentLength; - - private uint H1; - private uint H2; - private uint H3; - private uint H4; - private int currentLength; - - private uint currentBlock1; - private uint currentBlock2; - private uint currentBlock3; - private uint currentBlock4; - - public void Reset() - { - // initialize hash values to seed values - H1 = H2 = H3 = H4 = Seed; - currentLength = 0; - } - - /// - /// Gets the current calculated hash. - /// - /// The current hash. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ObjectId ComputeHash() - { - ComputeHash(out var result); - return result; - } - - /// - /// Gets the current calculated hash. - /// - /// The current hash. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ComputeHash(out ObjectId result) - { - // create our keys and initialize to 0 - uint k1 = 0, k2 = 0, k3 = 0, k4 = 0; - - var remainder = currentLength % 16; - - fixed (uint* currentBlockStart = ¤tBlock1) - { - var tail = (byte*)currentBlockStart; - - // determine how many bytes we have left to work with based on length - switch (remainder) - { - case 15: k4 ^= (uint)tail[14] << 16; goto case 14; - case 14: k4 ^= (uint)tail[13] << 8; goto case 13; - case 13: k4 ^= (uint)tail[12] << 0; goto case 12; - case 12: k3 ^= (uint)tail[11] << 24; goto case 11; - case 11: k3 ^= (uint)tail[10] << 16; goto case 10; - case 10: k3 ^= (uint)tail[9] << 8; goto case 9; - case 9: k3 ^= (uint)tail[8] << 0; goto case 8; - case 8: k2 ^= (uint)tail[7] << 24; goto case 7; - case 7: k2 ^= (uint)tail[6] << 16; goto case 6; - case 6: k2 ^= (uint)tail[5] << 8; goto case 5; - case 5: k2 ^= (uint)tail[4] << 0; goto case 4; - case 4: k1 ^= (uint)tail[3] << 24; goto case 3; - case 3: k1 ^= (uint)tail[2] << 16; goto case 2; - case 2: k1 ^= (uint)tail[1] << 8; goto case 1; - case 1: k1 ^= (uint)tail[0] << 0; break; - } - } - - var h4 = H4 ^ RotateLeft((k4 * C4), 18) * C1; - var h3 = H3 ^ RotateLeft((k3 * C3), 17) * C4; - var h2 = H2 ^ RotateLeft((k2 * C2), 16) * C3; - var h1 = H1 ^ RotateLeft((k1 * C1), 15) * C2; - - var len = (uint)currentLength; - // pipelining friendly algorithm - h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; - - h1 += (h2 + h3 + h4); - h2 += h1; h3 += h1; h4 += h1; - - h1 = FMix(h1); - h2 = FMix(h2); - h3 = FMix(h3); - h4 = FMix(h4); - - h1 += (h2 + h3 + h4); - h2 += h1; h3 += h1; h4 += h1; - - fixed (void* ptr = &result) - { - var h = (uint*)ptr; - *h++ = h1; - *h++ = h2; - *h++ = h3; - *h = h4; - } - } - - /// - /// Writes a byte to the builder. - /// - /// The value. - public void WriteByte(byte value) - { - ref var currentBlock = ref Unsafe.As(ref currentBlock1); - - var position = currentLength++ & 15; - - Unsafe.Add(ref currentBlock, position) = value; - - if (position == 15) - { - BodyCore(ref currentBlock); - } - } - - - /// - /// Writes a buffer of byte to this builder. - /// - /// The buffer. - /// buffer - /// buffer - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(byte[] buffer) - { -#if NET7_0_OR_GREATER - ArgumentNullException.ThrowIfNull(buffer); -#else - if (buffer is null) throw new ArgumentNullException(nameof(buffer)); -#endif // NET7_0_OR_GREATER - - Write(buffer.AsSpan()); - } - - /// - /// Writes a buffer of byte to this builder. - /// - /// The buffer. - /// The offset. - /// The count. - /// buffer - /// count;Offset + Count is out of range - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(byte[] buffer, int offset, int count) - => Write(buffer.AsSpan(offset, count)); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(string str) - => Write(str.AsSpan()); - - /// - /// Writes the specified buffer to this instance. - /// - /// Type must be a struct - /// The data. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(T data) where T : unmanaged - { -#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1_OR_GREATER - Write(MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As(ref data), Unsafe.SizeOf())); -#else - fixed (byte* buffer = &Unsafe.As(ref data)) - Write(new ReadOnlySpan(buffer, Unsafe.SizeOf())); -#endif - } - - /// - /// Writes the specified buffer to this instance. - /// - /// Type must be a struct - /// The buffer. - /// The offset. - /// The count. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(T[] buffer, int offset, int count) where T : unmanaged - => Write(buffer.AsSpan(offset, count)); - - /// - /// Writes the specified buffer to this instance. - /// - /// Type must be a struct - /// The buffer. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ReadOnlySpan buffer) where T : unmanaged - => Write(MemoryMarshal.AsBytes(buffer)); - - /// - /// Writes a buffer of byte to this builder. - /// - /// The buffer. - /// The lenght. - /// buffer - /// count;Offset + Count is out of range - [Obsolete("Use Write(ReadOnlySpan)")] - public void Write(byte* buffer, int length) - { - fixed (uint* currentBlockStart = ¤tBlock1) - { - var currentBlock = (byte*)currentBlockStart; - var position = currentLength % 16; - - currentLength += length; - - // Partial block to continue? - if (position != 0) - { - var remainder = 16 - position; - - var partialLength = length; - if (partialLength > remainder) - partialLength = remainder; - - var dest = currentBlock + position; - for (var copyLength = partialLength; copyLength > 0; --copyLength) - *dest++ = *buffer++; - length -= partialLength; - - //Utilities.CopyMemory((IntPtr)currentBlock + position, (IntPtr)buffer, partialLength); - //buffer += partialLength; - //length -= partialLength; - - if (partialLength == remainder) - { - BodyCore(currentBlock); - } - } - - if (length > 0) - { - var blocks = length / 16; - length -= blocks * 16; - - // Main loop - while (blocks-- > 0) - { - BodyCore(buffer); - buffer += 16; - } - - // Start partial block - for (; length > 0; --length) - *currentBlock++ = *buffer++; - //if (length > 0) - //{ - // Utilities.CopyMemory((IntPtr)currentBlock, (IntPtr)buffer, length); - //} - } - } - } - - /// - /// Writes a buffer of byte to this builder. - /// - /// The readonly span. - /// buffer - /// count;Offset + Count is out of range - public void Write(ReadOnlySpan span) - { - ref var currentBlock = ref Unsafe.As(ref currentBlock1); - var position = currentLength % 16; - ref byte buffer = ref Unsafe.AsRef(in span.GetPinnableReference()); - int length = span.Length; - - currentLength += length; - - // Partial block to continue? - if (position != 0) - { - var remainder = 16 - position; - - var partialLength = length; - if (partialLength > remainder) - partialLength = remainder; - -#warning PERF: Do not copy byte-for-byte. - ref var dest = ref Unsafe.Add(ref currentBlock, position); - for (var copyLength = partialLength; copyLength > 0; --copyLength) - { - dest = buffer; - dest = ref Unsafe.Add(ref dest, 1); - buffer = ref Unsafe.Add(ref buffer, 1); - } - length -= partialLength; - - if (partialLength == remainder) - { - BodyCore(ref currentBlock); - } - } - - if (length > 0) - { - var blocks = length / 16; - length -= blocks * 16; - - // Main loop - while (blocks-- > 0) - { - BodyCore(ref buffer); - buffer = ref Unsafe.Add(ref buffer, 16); - } - - // Start partial block -#warning PERF: Do not copy byte-for-byte. - for (; length > 0; --length) - { - currentBlock = buffer; - currentBlock = ref Unsafe.Add(ref currentBlock, 1); - buffer = ref Unsafe.Add(ref buffer, 1); - } - } - } - [MethodImpl(MethodImplOptions.AggressiveInlining), Obsolete("Use BodyCore(ref byte)")] - private void BodyCore(byte* data) - { - var b = (uint*)data; - - // K1 - consume first integer - H1 ^= RotateLeft((*b++ * C1), 15) * C2; - H1 = (RotateLeft(H1, 19) + H2) * 5 + 0x561ccd1b; - - // K2 - consume second integer - H2 ^= RotateLeft((*b++ * C2), 16) * C3; - H2 = (RotateLeft(H2, 17) + H3) * 5 + 0x0bcaa747; - - // K3 - consume third integer - H3 ^= RotateLeft((*b++ * C3), 17) * C4; - H3 = (RotateLeft(H3, 15) + H4) * 5 + 0x96cd1c35; - - // K4 - consume fourth integer - H4 ^= RotateLeft((*b++ * C4), 18) * C1; - H4 = (RotateLeft(H4, 13) + H1) * 5 + 0x32ac3b17; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void BodyCore(ref byte data) - { - ref var b = ref Unsafe.As(ref data); - - // K1 - consume first integer - H1 ^= RotateLeft((b * C1), 15) * C2; - H1 = (RotateLeft(H1, 19) + H2) * 5 + 0x561ccd1b; - b = ref Unsafe.Add(ref b, 1); - - // K2 - consume second integer - H2 ^= RotateLeft((b * C2), 16) * C3; - H2 = (RotateLeft(H2, 17) + H3) * 5 + 0x0bcaa747; - b = ref Unsafe.Add(ref b, 1); - - // K3 - consume third integer - H3 ^= RotateLeft((b * C3), 17) * C4; - H3 = (RotateLeft(H3, 15) + H4) * 5 + 0x96cd1c35; - b = ref Unsafe.Add(ref b, 1); - - // K4 - consume fourth integer - H4 ^= RotateLeft((b * C4), 18) * C1; - H4 = (RotateLeft(H4, 13) + H1) * 5 + 0x32ac3b17; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - static uint RotateLeft(uint x, byte r) - { -#if NETCOREAPP3_0_OR_GREATER - return BitOperations.RotateLeft(x, r); -#else - return (x << r) | (x >> (32 - r)); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint FMix(uint h) - { - // pipelining friendly algorithm - h = (h ^ (h >> 16)) * 0x85ebca6b; - h = (h ^ (h >> 13)) * 0xc2b2ae35; - return h ^ (h >> 16); - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs deleted file mode 100644 index 1db96a0179..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderArraySource.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// An array of used only in shader mixin compositions. - /// - [DataContract("ShaderArraySource")] - public sealed class ShaderArraySource : ShaderSource, IEnumerable, IEquatable - { - /// - /// Initializes a new instance of the class. - /// - public ShaderArraySource() - { - Values = new ShaderSourceCollection(); - } - - /// - /// Gets or sets the values. - /// - /// The values. - public ShaderSourceCollection Values { get; set; } - - /// - /// Adds the specified composition. - /// - /// The composition. - public void Add(ShaderSource composition) - { - Values.Add(composition); - } - - public override object Clone() - { - return new ShaderArraySource { Values = new ShaderSourceCollection(Values.Select(x => (ShaderSource)x.Clone())) }; - } - - public IEnumerator GetEnumerator() - { - return Values.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - public override string ToString() - { - return string.Format("[{0}]", Values != null ? string.Join(", ", Values) : string.Empty); - } - - public bool Equals(ShaderArraySource other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - return Values.Equals(other.Values); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - return obj is ShaderArraySource && Equals((ShaderArraySource)obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = 0; - if (Values != null) - { - foreach (var current in Values) - hashCode = (hashCode*397) ^ (current?.GetHashCode() ?? 0); - } - return hashCode; - } - } - - public static bool operator ==(ShaderArraySource left, ShaderArraySource right) - { - return Equals(left, right); - } - - public static bool operator !=(ShaderArraySource left, ShaderArraySource right) - { - return !Equals(left, right); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs deleted file mode 100644 index 42bbc1586f..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassCode.cs +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Text; - -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// A common base class for shader classes with source code. - /// - [DataContract("ShaderClassCode")] - public abstract class ShaderClassCode : ShaderSource - { - /// - /// Gets the name of the class. - /// - /// The name of the class. - [DataMember(10)] - public string ClassName { get; set; } - - /// - /// Gets the generic parameters. - /// - /// The generic parameters. - [DataMember(20)] - public string[] GenericArguments { get; set; } - - [DefaultValue(null)] - [DataMember(30)] - public Dictionary GenericParametersArguments { get; set; } - - /// - /// Returns a class name as a that represents this instance. - /// - /// A class name as a that represents this instance. - public string ToClassName() - { - if (GenericArguments == null) - return ClassName; - - var result = new StringBuilder(); - result.Append(ClassName); - if (GenericArguments != null && GenericArguments.Length > 0) - { - result.Append('<'); - result.Append(string.Join(",", GenericArguments)); - result.Append('>'); - } - - return result.ToString(); - } - - public override string ToString() - { - return ToClassName(); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs deleted file mode 100644 index 9534f77b4d..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderClassSource.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Text; - -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// A shader class based on .sdsl file, used for mixin. - /// - [DataContract("ShaderClassSource")] - public sealed class ShaderClassSource : ShaderClassCode, IEquatable - { - - /// - /// Initializes a new instance of the class. - /// - public ShaderClassSource() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the class. - public ShaderClassSource(string className) - : this(className, null) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the class. - /// The generic parameters. - public ShaderClassSource(string className, params string[] genericArguments) - { - ClassName = className; - GenericArguments = genericArguments; - } - - /// - /// Initializes a new instance of the class. - /// - /// Name of the class. - /// The generic parameters. - public ShaderClassSource(string className, params object[] genericArguments) - { - ClassName = className; - if (genericArguments != null) - { - GenericArguments = new string[genericArguments.Length]; - for (int i = 0; i < genericArguments.Length; ++i) - { - var genArg = genericArguments[i]; - if (genArg is bool) - GenericArguments[i] = ((bool)genArg) ? "true" : "false"; - else - GenericArguments[i] = genArg == null ? "null" : Convert.ToString(genArg, CultureInfo.InvariantCulture); - } - } - } - - public bool Equals(ShaderClassSource shaderClassSource) - { - if (ReferenceEquals(null, shaderClassSource)) return false; - if (ReferenceEquals(this, shaderClassSource)) return true; - return - string.Equals(ClassName, shaderClassSource.ClassName) && - GenericArguments.SequenceEqualAllowNull(shaderClassSource.GenericArguments); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != GetType()) return false; - return Equals((ShaderClassSource)obj); - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = ClassName?.GetHashCode() ?? 0; - if (GenericArguments != null) - { - foreach (var current in GenericArguments) - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - } - - return hashCode; - } - } - - public override object Clone() - { - return new ShaderClassSource(ClassName, GenericArguments = GenericArguments != null ? GenericArguments.ToArray() : null); - } - - public override string ToString() - { - return ToClassName(); - } - - /// - /// Performs an implicit conversion from to . - /// - /// Name of the class. - /// The result of the conversion. - public static implicit operator ShaderClassSource(string className) - { - return new ShaderClassSource(className); - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs deleted file mode 100644 index 18b217ecbd..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMacro.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; - -using Stride.Core; - -namespace Stride.Shaders; - -[DataContract] -public readonly struct ShaderMacro(string name, object definition) : IEquatable -{ - /// - /// Preprocessor macro. - /// - public readonly string Name = name ?? throw new ArgumentNullException(nameof(name)); - - public readonly string Definition = definition is not null - ? definition is bool - ? definition.ToString().ToLowerInvariant() - : definition.ToString() - : string.Empty; - - - public readonly bool Equals(ShaderMacro other) - { - return Equals(other.Name, Name) - && Equals(other.Definition, Definition); - } - - public override readonly bool Equals(object obj) - { - if (obj is null) - return false; - - return obj is ShaderMacro other && Equals(other); - } - - public override readonly int GetHashCode() - { - return HashCode.Combine(Name, Definition); - } - - public override readonly string ToString() - { - return $"{Name} = {Definition}"; - } - - #region Operators - - public static bool operator ==(ShaderMacro left, ShaderMacro right) - { - return left.Equals(right); - } - - public static bool operator !=(ShaderMacro left, ShaderMacro right) - { - return !(left == right); - } - - #endregion -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs deleted file mode 100644 index 33aa927d8c..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderMixinSource.cs +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; - -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// A mixin performing a combination of and other mixins. - /// - [DataContract("ShaderMixinSource")] - public sealed class ShaderMixinSource : ShaderSource, IEquatable - { - /// - /// Initializes a new instance of the class. - /// - public ShaderMixinSource() - { - Mixins = new List(); - Compositions = new Stride.Core.Collections.SortedList(); - Macros = new List(); - } - - /// - /// Gets or sets the name of the sdfx effect linked to this node. - /// - /// The name of the sdfx effect. - [DataMember(0)] - [DefaultValue(null)] - public string Name { get; set; } - - [DataMemberIgnore] - public ShaderMixinSource Parent { get; set; } - - /// - /// Gets or sets the name of this mixin source (if this ShaderMixinSource was generated from a , - /// it contains the name of . - /// - /// The name. - //public string Name { get; set; } - - /// - /// Gets or sets the mixins. - /// - /// The mixins. - [DataMember(10)] - public List Mixins { get; set; } - - /// - /// Gets or sets the compositions. - /// - /// The compositions. - [DataMember(20)] - public Stride.Core.Collections.SortedList Compositions { get; set; } - - /// - /// Gets or sets the macros. - /// - /// The macros. - [DataMember(30)] - public List Macros { get; set; } - - /// - /// Adds a composition to this mixin. - /// - /// The name. - /// The shader source. - public void AddComposition(string name, ShaderSource shaderSource) - { - Compositions[name] = shaderSource; - } - - /// - /// Adds a composition to this mixin. - /// - /// The name. - /// The shader source element. - /// Returns the index of the composition in the array. - public int AddCompositionToArray(string name, ShaderSource shaderSourceElement) - { - ShaderSource shaderSource; - if (!Compositions.TryGetValue(name, out shaderSource)) - Compositions.Add(name, shaderSource = new ShaderArraySource()); - - var shaderArraySource = (ShaderArraySource)shaderSource; - shaderArraySource.Add(shaderSourceElement); - return shaderArraySource.Values.Count - 1; - } - - /// - /// Adds a macro to this mixin. - /// - /// The name. - /// The value. - public void AddMacro(string name, object value) - { - Macros.Add(new ShaderMacro(name, value)); - } - - /// - /// Clones from the specified . - /// - /// The parent mixin to clone from. - /// parent - public void CloneFrom(ShaderMixinSource parent) - { - if (parent == null) - throw new ArgumentNullException("parent", $"Cannot clone mixin [{Name}] from a null parent"); - - Mixins.AddRange(parent.Mixins); - Macros.AddRange(parent.Macros); - foreach (var shaderBasic in parent.Compositions) - { - Compositions[shaderBasic.Key] = shaderBasic.Value; - } - } - - /// - /// Clones from the specified . Clones members too. - /// - /// The parent mixin to clone from. - /// parent - public void DeepCloneFrom(ShaderMixinSource parent) - { - if (parent == null) - throw new ArgumentNullException("parent", $"Cannot deep clone mixin [{Name}] from a null parent"); - - foreach (var mixin in parent.Mixins) - Mixins.Add((ShaderClassCode)mixin.Clone()); - Macros.AddRange(parent.Macros); - foreach (var shaderBasic in parent.Compositions) - { - Compositions[shaderBasic.Key] = (ShaderSource)shaderBasic.Value.Clone(); - } - } - - public override bool Equals(object against) - { - if (ReferenceEquals(null, against)) return false; - if (ReferenceEquals(this, against)) return true; - if (against.GetType() != this.GetType()) return false; - return Equals((ShaderMixinSource)against); - } - - public bool Equals(ShaderMixinSource other) - { - if (other is null) return false; - if (ReferenceEquals(this, other)) return true; - - // Doesn't check for Parent for Children - return - Mixins.SequenceEqualAllowNull(other.Mixins) && - Macros.SequenceEqualAllowNull(other.Macros) && - Compositions.SequenceEqualAllowNull(other.Compositions); - } - public override int GetHashCode() - { - unchecked - { - int hashCode = 0; - foreach (var current in Mixins) - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - foreach (var current in Macros) - hashCode = (hashCode * 397) ^ current.GetHashCode(); - foreach (var current in Compositions) - hashCode = (hashCode * 397) ^ current.GetHashCode(); - return hashCode; - } - } - - public override object Clone() - { - var newMixin = (ShaderMixinSource)MemberwiseClone(); - newMixin.Compositions = Compositions == null ? null : ToSortedList(Compositions.Select(x => new KeyValuePair(x.Key, (ShaderSource)x.Value.Clone()))); - newMixin.Mixins = Mixins == null ? null : Mixins.Select(x => (ShaderClassCode)x.Clone()).ToList(); - newMixin.Macros = Macros == null ? null : new List(Macros.ToArray()); - return newMixin; - } - - private static Stride.Core.Collections.SortedList ToSortedList(IEnumerable> list) - { - var values = new Stride.Core.Collections.SortedList(); - foreach (var item in list) - values.Add(item.Key, item.Value); - return values; - } - - public override string ToString() - { - var result = new StringBuilder(); - - result.Append("mixin"); - - if (Mixins != null && Mixins.Count > 0) - { - result.Append(" "); - for (int i = 0; i < Mixins.Count; i++) - { - if (i > 0) - result.Append(", "); - result.Append(Mixins[i]); - } - } - - if (Compositions != null && Compositions.Count > 0) - { - result.Append(" ["); - var keys = Compositions.Keys.ToList(); - keys.Sort(); - for (int i = 0; i < keys.Count; i++) - { - var key = keys[i]; - if (i > 0) - result.Append(", "); - result.AppendFormat("{{{0} = {1}}}", key, Compositions[key]); - } - result.Append("]"); - } - return result.ToString(); - } - - internal bool ShouldSerializeMacros() - { - // If collection is non-null and empty, skip serialization - return Macros == null || Macros.Count != 0; - } - - internal bool ShouldSerializeMixins() - { - // If collection is non-null and empty, skip serialization - return Mixins == null || Mixins.Count != 0; - } - - internal bool ShouldSerializeCompositions() - { - // If collection is non-null and empty, skip serialization - return Compositions == null || Compositions.Count != 0; - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs deleted file mode 100644 index de0cb84007..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSource.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System.IO; -using Stride.Core; - -namespace Stride.Shaders -{ - /// - /// A shader source. - /// - [DataContract("ShaderSource")] - public abstract class ShaderSource - { - /// - /// Gets or sets a value indicating whether this is a discard shader after it has been mixed. - /// - /// true if discard; otherwise, false. - [DataMemberIgnore] - public bool Discard { get; set; } - - /// - /// Deep clones this instance. - /// - /// A new instance. - public abstract object Clone(); - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// true if the specified is equal to this instance; otherwise, false. - public abstract override bool Equals(object against); - - public abstract override int GetHashCode(); - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs deleted file mode 100644 index 42b1e483c6..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/ShaderSourceCollection.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; -using Stride.Core; - -namespace Stride.Shaders -{ - [DataContract] - public sealed class ShaderSourceCollection : List - { - public ShaderSourceCollection() - { - } - - public ShaderSourceCollection(IEnumerable collection) : base(collection) - { - } - - public override int GetHashCode() - { - unchecked - { - int hashCode = 0; - foreach (var current in this) - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - return hashCode; - } - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((ShaderSourceCollection)obj); - } - - public bool Equals(ShaderSourceCollection other) - { - if (ReferenceEquals(null, other)) return false; - if (ReferenceEquals(this, other)) return true; - - if (Count != other.Count) - return false; - - for (int i = 0; i < Count; ++i) - { - if (!this[i].Equals(other[i])) - return false; - } - - return true; - } - } -} diff --git a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs b/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs deleted file mode 100644 index 7577d3d099..0000000000 --- a/sources/shaders/Stride.Shaders/StrideImported/ShadersSource/Utilities.cs +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// -// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System.Collections; -using System.Diagnostics; - -namespace Stride.Core; - -/// -/// Provides a set of static utility methods for collection operations, and general-purpose helpers. -/// -public static class Utilities -{ - /// - /// Disposes an object if not , - /// and sets it to . - /// - /// The disposable object to dispose. - public static void Dispose(ref T? disposable) where T : class, IDisposable - { - disposable?.Dispose(); - disposable = null; - } - - /// - /// Read stream to a byte[] buffer - /// - /// input stream - /// a byte[] buffer - [Obsolete("Allocates. Read into the destination.")] - public static byte[] ReadStream(Stream stream) - { - Debug.Assert(stream != null); - Debug.Assert(stream.CanRead); - - var readLength = (int)(stream.Length - stream.Position); - - Debug.Assert(readLength <= (stream.Length - stream.Position)); - - if (readLength == 0) - { - return []; - } - - var buffer = new byte[readLength]; - var bytesRead = 0; - - while (bytesRead < readLength) - { - bytesRead += stream.Read(buffer, bytesRead, readLength - bytesRead); - } - - return buffer; - } - - /// - /// Computes a hashcode for a dictionary. - /// - /// Hashcode for the list. - public static int GetHashCode(IDictionary dict) - { - if (dict is null) - return 0; - - var hashCode = 0; - foreach (DictionaryEntry keyValue in dict) - { - hashCode = (hashCode * 397) ^ keyValue.Key.GetHashCode(); - hashCode = (hashCode * 397) ^ (keyValue.Value?.GetHashCode() ?? 0); - } - return hashCode; - } - - /// - /// Computes a hashcode for an enumeration - /// - /// An enumerator. - /// Hashcode for the list. - public static int GetHashCode(IEnumerable it) - { - if (it is null) - return 0; - - var hashCode = 0; - foreach (var current in it) - { - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - } - return hashCode; - } - - /// - /// Computes a hashcode for an enumeration - /// - /// An enumerator. - /// Hashcode for the list. - public static int GetHashCode(IEnumerator it) - { - if (it is null) - return 0; - - var hashCode = 0; - while (it.MoveNext()) - { - var current = it.Current; - hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); - } - return hashCode; - } - - /// - /// Compares two collection, element by elements. - /// - /// The collection to compare from. - /// The colllection to compare to. - /// True if lists are identical (but no necessarely of the same time). False otherwise. - public static bool Compare(IDictionary first, IDictionary second) - { - if (ReferenceEquals(first, second)) return true; - if (first is null || second is null) return false; - if (first.Count != second.Count) return false; - - var comparer = EqualityComparer.Default; - - foreach (var keyValue in first) - { - if (!second.TryGetValue(keyValue.Key, out var secondValue)) return false; - if (!comparer.Equals(keyValue.Value, secondValue)) return false; - } - - // Check that all keys in second are in first - return second.Keys.All(first.ContainsKey); - } - - /// - /// Compares two collection, element by elements. - /// - /// The collection to compare from. - /// The colllection to compare to. - /// True if lists are identical (but not necessarily in the same order). False otherwise. - /// Concrete SortedList is favored over interface to avoid enumerator object allocation. - public static bool Compare(Collections.SortedList first, Collections.SortedList second) - { - if (ReferenceEquals(first, second)) return true; - if (first is null || second is null) return false; - if (first.Count != second.Count) return false; - - var comparer = EqualityComparer.Default; - - foreach (var keyValue in first) - { - if (!second.TryGetValue(keyValue.Key, out var secondValue)) return false; - if (!comparer.Equals(keyValue.Value, secondValue)) return false; - } - - return true; - } - - /// - /// Linq assisted full tree iteration and collection in a single line. - /// Warning, could be slow. - /// - /// The type to iterate. - /// The root item - /// The function to retrieve a child - public static IEnumerable IterateTree(T root, Func> childrenF) - { - var q = new List { root }; - while (q.Count != 0) - { - var c = q[0]; - q.RemoveAt(0); - q.AddRange(childrenF(c) ?? []); - yield return c; - } - } - - /// - /// Converts a raw time to a . - /// - /// The delta. - /// The . - public static TimeSpan ConvertRawToTimestamp(long delta) - => delta == 0 ? default : TimeSpan.FromTicks(delta * TimeSpan.TicksPerSecond / Stopwatch.Frequency); -} From fad8082a7deb45d3c5f8836c4eb95ed28d85bc44 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 16:18:25 +0900 Subject: [PATCH 0830/1182] Renamed Stride.Shaders into Stride.Shaders.Parsers --- .../Stride.Assets.Presentation.csproj | 4 ++-- sources/engine/Stride.Assets/Stride.Assets.csproj | 4 ++-- .../Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj | 6 +++--- .../Stride.Shaders.Tests.Windows.csproj | 4 ++-- sources/shaders/SDSL.sln | 2 +- .../Stride.Shaders.Compilers.csproj | 2 +- .../Stride.Shaders.Generators.csproj | 2 +- .../Core/AssignOperators.cs | 0 .../Core/EntryPoints.cs | 0 .../Core/IntrinsicsParameters.cs | 0 .../Core/Node.Visitors.cs | 0 .../Core/Operators.cs | 0 .../Core/Symbol.cs | 0 .../Core/SymbolFrame.cs | 0 .../Core/SymbolProvider.cs | 0 .../Core/SymbolTypes.Globals.cs | 0 .../Core/SymbolTypes.Visitors.cs | 0 .../Core/SymbolTypes.cs | 0 .../Parsing/ASTNode.cs | 0 .../Parsing/Analysis/CFG.cs | 0 .../Parsing/Analysis/IStreamChecker.cs | 0 .../Parsing/Analysis/ReadMe.md | 0 .../Parsing/Analysis/SDIR.cs | 0 .../Parsing/Analysis/SymbolTable.cs | 0 .../Parsing/Analysis/TypeNameExtensions.cs | 0 .../Parsing/Grammar.cs | 0 .../Parsing/IParser.cs | 0 .../Parsing/ParseResult.cs | 0 .../Parsing/PreProcessing/CMacros/CodeFrame.cs | 0 .../Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs | 0 .../Parsing/PreProcessing/CMacros/CodeProcessor.cs | 0 .../Parsing/PreProcessing/CMacros/CommentPhase.cs | 0 .../Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs | 0 .../Parsing/PreProcessing/CMacros/LocationTranslator.cs | 0 .../Parsing/PreProcessing/CommentProcessedCode.cs | 0 .../Parsing/PreProcessing/MacroPreProcessor.cs | 0 .../Parsing/PreProcessing/MemoryOwnerExtensions.cs | 0 .../Parsing/PreProcessing/TextLink.cs | 0 .../Parsing/PreProcessing/TextLinkExtensions.cs | 0 .../Parsing/SDFX/AST/Effect.Flow.cs | 0 .../Parsing/SDFX/AST/Effect.Parameters.cs | 0 .../Parsing/SDFX/AST/Effect.cs | 0 .../Parsing/SDFX/Parsers/EffectFileParsers.cs | 0 .../Parsing/SDFX/Parsers/EffectParser.cs | 0 .../SDFX/Parsers/EffectStatementParsers.Conditional.cs | 0 .../Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs | 0 .../Parsing/SDFX/Parsers/EffectStatementParsers.cs | 0 .../Parsing/SDFX/Parsers/ParamsParsers.cs | 0 .../Parsing/SDFX/ShaderWriter.cs | 0 .../Parsing/SDSL/AST/AssignOperator.cs | 0 .../Parsing/SDSL/AST/BufferMethodsImplementations.cs | 0 .../Parsing/SDSL/AST/Directives.cs | 0 .../Parsing/SDSL/AST/Expression.cs | 0 .../Parsing/SDSL/AST/IntrinsicCall.cs | 0 .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 0 .../Parsing/SDSL/AST/IntrinsicTemplateExpander.cs | 0 .../Parsing/SDSL/AST/Literals.cs | 0 .../Parsing/SDSL/AST/Operator.cs | 0 .../Parsing/SDSL/AST/Shader.cs | 0 .../Parsing/SDSL/AST/ShaderAttributes.cs | 0 .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 0 .../Parsing/SDSL/AST/ShaderElements.cs | 0 .../Parsing/SDSL/AST/ShaderGenericsValues.cs | 0 .../Parsing/SDSL/AST/Statements.Control.cs | 0 .../Parsing/SDSL/AST/Statements.Flow.cs | 0 .../Parsing/SDSL/AST/Statements.cs | 0 .../Parsing/SDSL/AST/TextureMethodsImplementations.cs | 0 .../Parsing/SDSL/Parsers/Common/CommonParsers.cs | 0 .../Parsing/SDSL/Parsers/Common/Delegates.cs | 0 .../Parsing/SDSL/Parsers/Common/OptionalParser.cs | 0 .../Parsing/SDSL/Parsers/Common/Spaces.cs | 0 .../Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs | 0 .../SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs | 0 .../DirectivePrimaryExpressionParsers.cs | 0 .../DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs | 0 .../Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs | 0 .../Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs | 0 .../Parsers/ExpressionParsers/PrimaryExpressionParsers.cs | 0 .../SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs | 0 .../SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs | 0 .../Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs | 0 .../Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs | 0 .../Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs | 0 .../SDSL/Parsers/ShaderParsers/CompositionParsers.cs | 0 .../SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs | 0 .../SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs | 0 .../Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs | 0 .../Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs | 0 .../SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs | 0 .../Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs | 0 .../SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs | 0 .../Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs | 0 .../Parsers/StatementParsers/StatementParsers.Control.cs | 0 .../SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs | 0 .../SDSL/Parsers/StatementParsers/StatementParsers.cs | 0 .../Parsing/SDSL/Parsers/Terminals/Terminals.cs | 0 .../Parsing/SDSLERR.cs | 0 .../Parsing/SDSLParser.cs | 0 .../Parsing/Scanners/ErrorLocation.cs | 0 .../Parsing/Scanners/IScannableCode.cs | 0 .../Parsing/Scanners/IScanner.cs | 0 .../Parsing/Scanners/ScannableString.cs | 0 .../Parsing/Scanners/Scanner.cs | 0 .../Parsing/Scanners/ScannerGeneric.cs | 0 .../Parsing/Scanners/TextLocation.cs | 0 .../Spirv/Building/BasicBlocks.cs | 0 .../Spirv/Building/Builder.CBuffer.cs | 0 .../Spirv/Building/Builder.Class.cs | 0 .../Spirv/Building/Builder.Expressions.cs | 0 .../Spirv/Building/Builder.Flow.cs | 0 .../Spirv/Building/Builder.Functions.cs | 0 .../Spirv/Building/Builder.cs | 0 .../Spirv/Building/CompilerUnit.cs | 0 .../Spirv/Building/Context.Constants.cs | 0 .../Spirv/Building/Context.ExtractBuffers.cs | 0 .../Spirv/Building/Context.cs | 0 .../Spirv/Building/DictionaryPool.cs | 0 .../Spirv/Building/ExpressionExtensions.cs | 0 .../Spirv/Building/Module.cs | 0 .../Spirv/Building/SpirvContext.Types.cs | 0 .../Spirv/Processing/BoundReducer.cs | 0 .../Spirv/Processing/CapabilitiesCompute.cs | 0 .../Spirv/Processing/CompressBuffer.cs | 0 .../Spirv/Processing/FunctionVariableOrderer.cs | 0 .../Spirv/Processing/INanoPass.cs | 0 .../Spirv/Processing/IOReplace.cs | 0 .../Spirv/Processing/IOVariableDecorator.cs | 0 .../Spirv/Processing/IPostProcessorSubPass.cs | 0 .../Spirv/Processing/IdRefOffsetter.cs | 0 .../Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs | 0 .../Processing/Interfaces/Analysis/SemanticAnalyzer.cs | 0 .../Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs | 0 .../Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs | 0 .../Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs | 0 .../Processing/Interfaces/Generation/BuiltinProcessor.cs | 0 .../Interfaces/Generation/EntryPointWrapperGenerator.cs | 0 .../Spirv/Processing/Interfaces/InterfaceProcessor.cs | 0 .../Spirv/Processing/Interfaces/Models/AnalysisResult.cs | 0 .../Spirv/Processing/Interfaces/Models/LiveAnalysis.cs | 0 .../Spirv/Processing/Interfaces/Models/ResourceInfo.cs | 0 .../Processing/Interfaces/Models/StreamVariableInfo.cs | 0 .../Spirv/Processing/Interfaces/Models/VariableInfo.cs | 0 .../Interfaces/Transformation/MethodDuplicator.cs | 0 .../Interfaces/Transformation/StreamAccessPatcher.cs | 0 .../Spirv/Processing/MemoryModelDuplicatesRemover.cs | 0 .../Spirv/Processing/MixinMerger.cs | 0 .../Spirv/Processing/PostProcessor.cs | 0 .../Spirv/Processing/SDSLOpRemover.cs | 0 .../Spirv/Processing/TypeDuplicatesRemover.cs | 0 .../Spirv/Tools/Dis.cs | 0 .../Spirv/Tools/Validator.cs | 0 .../Spirv/thinking.md | 0 .../Stride.Shaders.Parsers.csproj} | 2 +- .../gen_intrin_README.md | 0 .../gen_intrin_main.txt | 0 .../Stride.Shaders.Tests/Stride.Shaders.Tests.csproj | 4 ++-- 156 files changed, 15 insertions(+), 15 deletions(-) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/AssignOperators.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/EntryPoints.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/IntrinsicsParameters.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/Node.Visitors.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/Operators.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/Symbol.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/SymbolFrame.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/SymbolProvider.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/SymbolTypes.Globals.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/SymbolTypes.Visitors.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Core/SymbolTypes.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/ASTNode.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/CFG.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/IStreamChecker.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/ReadMe.md (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/SDIR.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/SymbolTable.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Analysis/TypeNameExtensions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Grammar.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/IParser.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/ParseResult.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/CodeFrame.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/CodeProcessor.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/CommentPhase.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CMacros/LocationTranslator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/CommentProcessedCode.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/MacroPreProcessor.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/MemoryOwnerExtensions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/TextLink.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/PreProcessing/TextLinkExtensions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/AST/Effect.Flow.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/AST/Effect.Parameters.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/AST/Effect.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/EffectFileParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/EffectParser.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/EffectStatementParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/Parsers/ParamsParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDFX/ShaderWriter.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/AssignOperator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/BufferMethodsImplementations.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Directives.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Expression.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/IntrinsicCall.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/IntrinsicImplementations.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Literals.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Operator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Shader.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/ShaderAttributes.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/ShaderElements.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/ShaderGenericsValues.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Statements.Control.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Statements.Flow.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/Statements.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/AST/TextureMethodsImplementations.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/Common/CommonParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/Common/Delegates.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/Common/OptionalParser.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/Common/Spaces.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSL/Parsers/Terminals/Terminals.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSLERR.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/SDSLParser.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/ErrorLocation.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/IScannableCode.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/IScanner.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/ScannableString.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/Scanner.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/ScannerGeneric.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Parsing/Scanners/TextLocation.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/BasicBlocks.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.CBuffer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.Class.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.Expressions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.Flow.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.Functions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Builder.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/CompilerUnit.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Context.Constants.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Context.ExtractBuffers.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Context.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/DictionaryPool.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/ExpressionExtensions.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/Module.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Building/SpirvContext.Types.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/BoundReducer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/CapabilitiesCompute.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/CompressBuffer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/FunctionVariableOrderer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/INanoPass.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/IOReplace.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/IOVariableDecorator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/IPostProcessorSubPass.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/IdRefOffsetter.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/InterfaceProcessor.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Models/AnalysisResult.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Models/ResourceInfo.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Models/VariableInfo.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/MemoryModelDuplicatesRemover.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/MixinMerger.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/PostProcessor.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/SDSLOpRemover.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Processing/TypeDuplicatesRemover.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Tools/Dis.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/Tools/Validator.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/Spirv/thinking.md (100%) rename sources/shaders/{Stride.Shaders/Stride.Shaders.csproj => Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj} (97%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/gen_intrin_README.md (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Parsers}/gen_intrin_main.txt (100%) diff --git a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj index c67536382b..d1ae33d0d3 100644 --- a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj +++ b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj @@ -70,8 +70,8 @@ - - ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + + ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index 946e660aa1..a4d3dc4f6d 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -35,8 +35,8 @@ - - ..\..\shaders\Stride.Shaders\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + + ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index cf517fd41b..462bdce158 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -38,13 +38,13 @@ - ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll + ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll ..\..\shaders\Stride.Shaders.Spirv.Core\bin\$(Configuration)\net10.0\Stride.Shaders.Spirv.Core.dll - - ..\..\shaders\Stride.Shaders\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + + ..\..\shaders\Stride.Shaders\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll diff --git a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj index ba5020d14d..10c41a2aa4 100644 --- a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj +++ b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj @@ -28,8 +28,8 @@ - - ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders2.dll + + ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll ..\..\shaders\Stride.Shaders.Compilers\bin\$(Configuration)\net10.0\Stride.Shaders.Compilers2.dll diff --git a/sources/shaders/SDSL.sln b/sources/shaders/SDSL.sln index d3e3570259..97d8867cf6 100644 --- a/sources/shaders/SDSL.sln +++ b/sources/shaders/SDSL.sln @@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Genera EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{C723E631-41D8-4797-86C3-9D52711CC849}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders", "Stride.Shaders\Stride.Shaders.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsers", "Stride.Shaders.Parsers\Stride.Shaders.Parsers.csproj", "{595979CB-8447-4EA0-9A9F-0CBD8B9442BB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{35A9F4C4-F5C8-4D84-9688-6FAB30E49AC7}" EndProject diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 5497f7f383..a3a4169f6c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -1,7 +1,7 @@  - + diff --git a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index 60a3cd65ec..eead6540a4 100644 --- a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -20,7 +20,7 @@ - + diff --git a/sources/shaders/Stride.Shaders/Core/AssignOperators.cs b/sources/shaders/Stride.Shaders.Parsers/Core/AssignOperators.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/AssignOperators.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/AssignOperators.cs diff --git a/sources/shaders/Stride.Shaders/Core/EntryPoints.cs b/sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/EntryPoints.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs diff --git a/sources/shaders/Stride.Shaders/Core/IntrinsicsParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/IntrinsicsParameters.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs diff --git a/sources/shaders/Stride.Shaders/Core/Node.Visitors.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/Node.Visitors.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs diff --git a/sources/shaders/Stride.Shaders/Core/Operators.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Operators.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/Operators.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/Operators.cs diff --git a/sources/shaders/Stride.Shaders/Core/Symbol.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/Symbol.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs diff --git a/sources/shaders/Stride.Shaders/Core/SymbolFrame.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/SymbolFrame.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs diff --git a/sources/shaders/Stride.Shaders/Core/SymbolProvider.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolProvider.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/SymbolProvider.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/SymbolProvider.cs diff --git a/sources/shaders/Stride.Shaders/Core/SymbolTypes.Globals.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/SymbolTypes.Globals.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs diff --git a/sources/shaders/Stride.Shaders/Core/SymbolTypes.Visitors.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/SymbolTypes.Visitors.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs diff --git a/sources/shaders/Stride.Shaders/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Core/SymbolTypes.cs rename to sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/ASTNode.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/ASTNode.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/CFG.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/CFG.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/IStreamChecker.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/ReadMe.md b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/ReadMe.md similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/ReadMe.md rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/ReadMe.md diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/SDIR.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/SDIR.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/SymbolTable.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Analysis/TypeNameExtensions.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Grammar.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Grammar.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/IParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/IParser.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/ParseResult.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/ParseResult.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrame.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CodeProcessor.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/CommentPhase.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/IPreProcessorPhase.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/LocationTranslator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CMacros/LocationTranslator.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/LocationTranslator.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/CommentProcessedCode.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/MacroPreProcessor.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/MemoryOwnerExtensions.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLink.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLink.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLink.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLink.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/PreProcessing/TextLinkExtensions.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Flow.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Flow.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Flow.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.Parameters.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/AST/Effect.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectFileParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectParser.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/EffectStatementParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/Parsers/ParamsParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDFX/ShaderWriter.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/AssignOperator.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/BufferMethodsImplementations.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Directives.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Directives.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Directives.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Directives.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Expression.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicCall.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicImplementations.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Literals.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Operator.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Operator.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Shader.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderAttributes.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderElements.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/ShaderGenericsValues.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Control.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.Flow.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/Statements.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/AST/TextureMethodsImplementations.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/CommonParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Delegates.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/OptionalParser.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Common/Spaces.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSL/Parsers/Terminals/Terminals.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSLERR.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSLERR.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/SDSLParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/SDSLParser.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/ErrorLocation.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/IScannableCode.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/IScannableCode.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/IScannableCode.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/IScannableCode.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/IScanner.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/IScanner.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/IScanner.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/IScanner.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/ScannableString.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/ScannableString.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/Scanner.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/Scanner.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/Scanner.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/Scanner.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/ScannerGeneric.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs diff --git a/sources/shaders/Stride.Shaders/Parsing/Scanners/TextLocation.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Parsing/Scanners/TextLocation.cs rename to sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/BasicBlocks.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/BasicBlocks.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.CBuffer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.Class.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.Expressions.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.Flow.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.Functions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.Functions.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Builder.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Builder.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/CompilerUnit.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/CompilerUnit.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Context.Constants.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Context.ExtractBuffers.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Context.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/DictionaryPool.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/DictionaryPool.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/DictionaryPool.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/DictionaryPool.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/ExpressionExtensions.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/Module.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Module.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/Module.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Module.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Building/SpirvContext.Types.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/BoundReducer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/BoundReducer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/CapabilitiesCompute.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/CompressBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/CompressBuffer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/FunctionVariableOrderer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/INanoPass.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/INanoPass.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/IOReplace.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/IOReplace.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/IOVariableDecorator.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/IPostProcessorSubPass.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/IdRefOffsetter.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/SemanticAnalyzer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/InterfaceProcessor.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/AnalysisResult.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/AnalysisResult.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/AnalysisResult.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/ResourceInfo.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/VariableInfo.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Models/VariableInfo.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/VariableInfo.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/MemoryModelDuplicatesRemover.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/MixinMerger.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/MixinMerger.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/PostProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/PostProcessor.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/SDSLOpRemover.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Processing/TypeDuplicatesRemover.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Tools/Dis.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/Tools/Validator.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs diff --git a/sources/shaders/Stride.Shaders/Spirv/thinking.md b/sources/shaders/Stride.Shaders.Parsers/Spirv/thinking.md similarity index 100% rename from sources/shaders/Stride.Shaders/Spirv/thinking.md rename to sources/shaders/Stride.Shaders.Parsers/Spirv/thinking.md diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj similarity index 97% rename from sources/shaders/Stride.Shaders/Stride.Shaders.csproj rename to sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj index 5729043a66..5b3875b49f 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj @@ -33,10 +33,10 @@ enable enable True - $(MSBuildProjectName)2 CS8785;$(WarningsAsErrors) true CS8785 + Stride.Shaders diff --git a/sources/shaders/Stride.Shaders/gen_intrin_README.md b/sources/shaders/Stride.Shaders.Parsers/gen_intrin_README.md similarity index 100% rename from sources/shaders/Stride.Shaders/gen_intrin_README.md rename to sources/shaders/Stride.Shaders.Parsers/gen_intrin_README.md diff --git a/sources/shaders/Stride.Shaders/gen_intrin_main.txt b/sources/shaders/Stride.Shaders.Parsers/gen_intrin_main.txt similarity index 100% rename from sources/shaders/Stride.Shaders/gen_intrin_main.txt rename to sources/shaders/Stride.Shaders.Parsers/gen_intrin_main.txt diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index 7ef6c279f1..bc76a296c7 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -11,7 +11,7 @@ true - Stride.Shaders.Parsing.Tests + Stride.Shaders.Parsers.Tests @@ -56,7 +56,7 @@ - + From f9b0821fa57efda4576ef1464e30c06a59e5d97b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 17:07:57 +0900 Subject: [PATCH 0831/1182] Relinked runtime projects as Stride SDK project with proper ProjectReference --- build/Stride.Android.sln | 4 +- build/Stride.Runtime.sln | 4 +- build/Stride.iOS.sln | 4 +- build/Stride.sln | 87 ++++++++++- .../Stride.Assets.Presentation.csproj | 3 - .../engine/Stride.Assets/Stride.Assets.csproj | 3 - .../engine/Stride.Engine/Stride.Engine.csproj | 2 +- .../Stride.Graphics/Stride.Graphics.csproj | 2 +- .../Stride.Shaders.Compiler.csproj | 11 -- .../Stride.Shaders.Tests.Windows.csproj | 6 - sources/shaders/Readme.md | 4 +- sources/shaders/SDSL.sln | 144 ------------------ .../Direct3D/DxilHash.cs | 0 .../Direct3D/ShaderCompiler.cs | 0 .../EffectCompiler.cs | 0 .../IShaderCompiler.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../SDSL/ShaderMixer.cs | 20 +-- .../ShaderBytecodeResult.cs | 0 .../ShaderSourceComparer.cs | 0 .../ShaderSourceManager.cs | 0 .../Stride.Shaders.Compilers.csproj | 77 +++++----- .../Stride.Shaders.Experiments.csproj | 9 -- .../Stride.Shaders.Generators.csproj | 9 -- .../Stride.Shaders.Parsers.csproj | 25 +-- .../Stride.Shaders.Spirv.Core.csproj | 14 +- .../Stride.Shaders.Tests.csproj | 19 +-- .../Compiler/CompilerParameters.cs | 0 .../Compiler/CompilerResults.cs | 0 .../Compiler/EffectBytecodeCacheLoadSource.cs | 0 .../Compiler/EffectBytecodeCompilerResult.cs | 0 .../Compiler/EffectCompilerBase.cs | 0 .../Compiler/EffectCompilerCache.cs | 0 .../Compiler/EffectCompilerChain.cs | 0 .../Compiler/EffectCompilerParameters.cs | 0 .../Compiler/EffectPriorityScheduler.cs | 0 .../Compiler/IEffectCompiler.cs | 0 .../Compiler/NullEffectCompiler.cs | 0 .../Stride.Shaders/Compiler/TaskOrResult.cs | 0 .../Stride.Shaders/ConstantBufferType.cs | 0 .../Stride.Shaders/EffectBytecode.cs | 0 .../EffectConstantBufferDescription.cs | 0 .../Stride.Shaders/EffectParameterClass.cs | 0 .../Stride.Shaders/EffectParameterKeyInfo.cs | 0 .../Stride.Shaders/EffectParameterType.cs | 0 .../Stride.Shaders/EffectReflection.cs | 0 .../EffectResourceBindingDescription.cs | 0 .../EffectSamplerStateBinding.cs | 0 .../Stride.Shaders/EffectSourceCodeKeys.cs | 0 .../Stride.Shaders/EffectTypeDescription.cs | 0 .../EffectTypeMemberDescription.cs | 0 .../Stride.Shaders/EffectValueDescription.cs | 0 .../Stride.Shaders/HashSourceCollection.cs | 0 .../Stride.Shaders/IShaderMixinBuilder.cs | 0 .../IShaderMixinBuilderExtended.cs | 0 .../Stride.Shaders/NamespaceDoc.cs | 0 .../ParameterKeyHashSerializer.cs | 0 .../Stride.Shaders/Properties/AssemblyInfo.cs | 0 .../Stride.Shaders/ShaderArraySource.cs | 0 .../Stride.Shaders/ShaderBytecode.cs | 0 .../Stride.Shaders/ShaderClassCode.cs | 0 .../Stride.Shaders/ShaderClassSource.cs | 0 .../Stride.Shaders/ShaderClassString.cs | 0 .../ShaderInputAttributeDescription.cs | 0 .../Stride.Shaders/ShaderInputBytecode.cs | 0 .../Stride.Shaders/ShaderMacro.cs | 0 .../Stride.Shaders/ShaderMixinContext.cs | 0 .../ShaderMixinDiscardException.cs | 0 .../ShaderMixinGeneratorSource.cs | 0 .../Stride.Shaders/ShaderMixinManager.cs | 0 .../Stride.Shaders/ShaderMixinObjectId.cs | 0 .../Stride.Shaders/ShaderMixinParameters.cs | 0 .../Stride.Shaders/ShaderMixinSource.cs | 0 .../Stride.Shaders/ShaderSource.cs | 0 .../Stride.Shaders/ShaderSourceCollection.cs | 0 .../Stride.Shaders/ShaderSourceToCode.cs | 0 .../Stride.Shaders/ShaderStage.cs | 0 .../ShaderStreamOutputDeclarationEntry.cs | 0 .../Stride.Shaders/Stride.Shaders.csproj | 6 +- .../build/Stride.Shaders.targets | 0 sources/shaders/test.spv | Bin 996 -> 0 bytes 81 files changed, 157 insertions(+), 296 deletions(-) delete mode 100644 sources/shaders/SDSL.sln rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/Direct3D/DxilHash.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/Direct3D/ShaderCompiler.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/EffectCompiler.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/IShaderCompiler.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/Properties/AssemblyInfo.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/ShaderBytecodeResult.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/ShaderSourceComparer.cs (100%) rename sources/{engine/Stride.Shaders.Compiler => shaders/Stride.Shaders.Compilers}/ShaderSourceManager.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/CompilerParameters.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/CompilerResults.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectBytecodeCacheLoadSource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectBytecodeCompilerResult.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectCompilerBase.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectCompilerCache.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectCompilerChain.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectCompilerParameters.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/EffectPriorityScheduler.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/IEffectCompiler.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/NullEffectCompiler.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Compiler/TaskOrResult.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ConstantBufferType.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectBytecode.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectConstantBufferDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectParameterClass.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectParameterKeyInfo.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectParameterType.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectReflection.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectResourceBindingDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectSamplerStateBinding.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectSourceCodeKeys.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectTypeDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectTypeMemberDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/EffectValueDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/HashSourceCollection.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/IShaderMixinBuilder.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/IShaderMixinBuilderExtended.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/NamespaceDoc.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ParameterKeyHashSerializer.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Properties/AssemblyInfo.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderArraySource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderBytecode.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderClassCode.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderClassSource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderClassString.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderInputAttributeDescription.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderInputBytecode.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMacro.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinContext.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinDiscardException.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinGeneratorSource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinManager.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinObjectId.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinParameters.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderMixinSource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderSource.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderSourceCollection.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderSourceToCode.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderStage.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/ShaderStreamOutputDeclarationEntry.cs (100%) rename sources/{engine => shaders}/Stride.Shaders/Stride.Shaders.csproj (69%) rename sources/{engine => shaders}/Stride.Shaders/build/Stride.Shaders.targets (100%) delete mode 100644 sources/shaders/test.spv diff --git a/build/Stride.Android.sln b/build/Stride.Android.sln index fac9a110ba..fb07069452 100644 --- a/build/Stride.Android.sln +++ b/build/Stride.Android.sln @@ -73,13 +73,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\source EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\engine\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\engine\Stride.Shaders.Compiler\Stride.Shaders.Compiler.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" EndProject diff --git a/build/Stride.Runtime.sln b/build/Stride.Runtime.sln index 8171aceb06..8973d3ad2e 100644 --- a/build/Stride.Runtime.sln +++ b/build/Stride.Runtime.sln @@ -73,13 +73,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\source EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\engine\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\engine\Stride.Shaders.Compiler\Stride.Shaders.Compiler.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" EndProject diff --git a/build/Stride.iOS.sln b/build/Stride.iOS.sln index 9a513f760b..655dc39f22 100644 --- a/build/Stride.iOS.sln +++ b/build/Stride.iOS.sln @@ -73,13 +73,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\source EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\engine\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\engine\Stride.Shaders.Compiler\Stride.Shaders.Compiler.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" EndProject diff --git a/build/Stride.sln b/build/Stride.sln index 2db63de0c7..c7b7ccda59 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -48,7 +48,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Config", "00-Config", "{ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shared", "Stride.Shared", "{1AC70118-C90F-4EC6-9D8B-C628BDF900F7}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "21-StrideRuntime.Tests", "21-StrideRuntime.Tests", "{A7ED9F01-7D78-4381-90A6-D50E51C17250}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "25-StrideRuntime.Tests", "25-StrideRuntime.Tests", "{A7ED9F01-7D78-4381-90A6-D50E51C17250}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "11-CoreRuntime.Tests", "11-CoreRuntime.Tests", "{22ADD4CD-092E-4ADC-A21E-64CF42230152}" EndProject @@ -120,13 +120,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.MicroThreading" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\sources\core\Stride.Core.IO\Stride.Core.IO.csproj", "{1DE01410-22C9-489B-9796-1ADDAB1F64E5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\engine\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\engine\Stride.Shaders.Compiler\Stride.Shaders.Compiler.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Tests.Windows", "..\sources\engine\Stride.Shaders.Tests\Stride.Shaders.Tests.Windows.csproj", "{1BE90177-FE4D-4519-839E-7EB7D78AC973}" EndProject @@ -328,6 +328,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.FreeImage", "..\sour EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Editor.CrashReport", "..\sources\editor\Stride.Editor.CrashReport\Stride.Editor.CrashReport.csproj", "{35EC42D8-0A09-41AE-A918-B8C2796061B3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "22-StrideRuntime.Shaders", "22-StrideRuntime.Shaders", "{7E3ACF35-0CCA-4E88-866B-0F008C5A5580}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators.Internal", "..\sources\shaders\Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "..\sources\shaders\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{2618F6D9-685D-FDE1-B467-84BC8C858F51}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "..\sources\shaders\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "..\sources\shaders\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsers", "..\sources\shaders\Stride.Shaders.Parsers\Stride.Shaders.Parsers.csproj", "{CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1485,6 +1497,66 @@ Global {35EC42D8-0A09-41AE-A918-B8C2796061B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU {35EC42D8-0A09-41AE-A918-B8C2796061B3}.Release|Win32.ActiveCfg = Release|Any CPU {35EC42D8-0A09-41AE-A918-B8C2796061B3}.Release|Win32.Build.0 = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Debug|Win32.Build.0 = Debug|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Any CPU.Build.0 = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Win32.ActiveCfg = Release|Any CPU + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}.Release|Win32.Build.0 = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Win32.ActiveCfg = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Debug|Win32.Build.0 = Debug|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Any CPU.Build.0 = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Win32.ActiveCfg = Release|Any CPU + {2618F6D9-685D-FDE1-B467-84BC8C858F51}.Release|Win32.Build.0 = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Win32.ActiveCfg = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Debug|Win32.Build.0 = Debug|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Any CPU.Build.0 = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Win32.ActiveCfg = Release|Any CPU + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}.Release|Win32.Build.0 = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Debug|Win32.Build.0 = Debug|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Any CPU.Build.0 = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Win32.ActiveCfg = Release|Any CPU + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}.Release|Win32.Build.0 = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Debug|Win32.Build.0 = Debug|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Any CPU.Build.0 = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Win32.ActiveCfg = Release|Any CPU + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Win32.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1516,10 +1588,10 @@ Global {CB6C4D8B-906E-4120-8146-09261B8D2885} = {75A820AB-0F21-40F2-9448-5D7F495B97A0} {1320F627-EE43-4115-8E89-19D1753E51F2} = {2E93E2B5-4500-4E47-9B65-E705218AB578} {1DE01410-22C9-489B-9796-1ADDAB1F64E5} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {273BDD15-7392-4078-91F0-AF23594A3D7B} = {4C142567-C42B-40F5-B092-798882190209} + {273BDD15-7392-4078-91F0-AF23594A3D7B} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} - {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {4C142567-C42B-40F5-B092-798882190209} + {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} {1BE90177-FE4D-4519-839E-7EB7D78AC973} = {A7ED9F01-7D78-4381-90A6-D50E51C17250} {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E} = {4C142567-C42B-40F5-B092-798882190209} {1E54A9A2-4439-4444-AE57-6D2ED3C0DC47} = {A2A4342E-024B-4063-B10C-1DA96CA3046D} @@ -1609,6 +1681,11 @@ Global {7B70C783-4085-4702-B3C6-6570FD85CB8F} = {DE048114-9AE4-467E-A879-188DC0D88A59} {03695F9B-10E9-4A10-93AE-6402E46F10B5} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} {35EC42D8-0A09-41AE-A918-B8C2796061B3} = {5D2D3BE8-9910-45CA-8E45-95660DA4C563} + {B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {2618F6D9-685D-FDE1-B467-84BC8C858F51} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FF877973-604D-4EA7-B5F5-A129961F9EF2} diff --git a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj index d1ae33d0d3..12f9e3a69e 100644 --- a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj +++ b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj @@ -70,9 +70,6 @@ - - ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll - diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index a4d3dc4f6d..010a176fd2 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -35,9 +35,6 @@ - - ..\..\shaders\Stride.Shaders.Parsers\bin\$(Configuration)\net10.0\Stride.Shaders.Parsers.dll - diff --git a/sources/engine/Stride.Engine/Stride.Engine.csproj b/sources/engine/Stride.Engine/Stride.Engine.csproj index 7bded5b689..ae8c1bd4fd 100644 --- a/sources/engine/Stride.Engine/Stride.Engine.csproj +++ b/sources/engine/Stride.Engine/Stride.Engine.csproj @@ -31,7 +31,7 @@ - + @@ -28,4 +31,5 @@ + diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index bc76a296c7..be94136493 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -27,24 +27,7 @@ - - ..\..\..\sources\core\Stride.Core\bin\Debug\net10.0\Stride.Core.dll - - - ..\..\..\sources\core\Stride.Core.Mathematics\bin\Debug\net10.0\Stride.Core.Mathematics.dll - - - ..\..\..\sources\engine\Stride.Shaders\bin\Debug\net10.0\Stride.Shaders.dll - - - ..\..\..\sources\engine\Stride.Graphics\bin\Debug\net10.0\Direct3D11\Stride.Graphics.dll - - - ..\..\..\sources\engine\Stride\bin\Debug\net10.0\Stride.dll - - - ..\..\..\sources\engine\Stride.Rendering\bin\Debug\net10.0\Stride.Rendering.dll - + diff --git a/sources/engine/Stride.Shaders/Compiler/CompilerParameters.cs b/sources/shaders/Stride.Shaders/Compiler/CompilerParameters.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/CompilerParameters.cs rename to sources/shaders/Stride.Shaders/Compiler/CompilerParameters.cs diff --git a/sources/engine/Stride.Shaders/Compiler/CompilerResults.cs b/sources/shaders/Stride.Shaders/Compiler/CompilerResults.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/CompilerResults.cs rename to sources/shaders/Stride.Shaders/Compiler/CompilerResults.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectBytecodeCacheLoadSource.cs b/sources/shaders/Stride.Shaders/Compiler/EffectBytecodeCacheLoadSource.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectBytecodeCacheLoadSource.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectBytecodeCacheLoadSource.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectBytecodeCompilerResult.cs b/sources/shaders/Stride.Shaders/Compiler/EffectBytecodeCompilerResult.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectBytecodeCompilerResult.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectBytecodeCompilerResult.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectCompilerBase.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectCompilerBase.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectCompilerCache.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectCompilerChain.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectCompilerChain.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectCompilerParameters.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerParameters.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectCompilerParameters.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectCompilerParameters.cs diff --git a/sources/engine/Stride.Shaders/Compiler/EffectPriorityScheduler.cs b/sources/shaders/Stride.Shaders/Compiler/EffectPriorityScheduler.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/EffectPriorityScheduler.cs rename to sources/shaders/Stride.Shaders/Compiler/EffectPriorityScheduler.cs diff --git a/sources/engine/Stride.Shaders/Compiler/IEffectCompiler.cs b/sources/shaders/Stride.Shaders/Compiler/IEffectCompiler.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/IEffectCompiler.cs rename to sources/shaders/Stride.Shaders/Compiler/IEffectCompiler.cs diff --git a/sources/engine/Stride.Shaders/Compiler/NullEffectCompiler.cs b/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/NullEffectCompiler.cs rename to sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs diff --git a/sources/engine/Stride.Shaders/Compiler/TaskOrResult.cs b/sources/shaders/Stride.Shaders/Compiler/TaskOrResult.cs similarity index 100% rename from sources/engine/Stride.Shaders/Compiler/TaskOrResult.cs rename to sources/shaders/Stride.Shaders/Compiler/TaskOrResult.cs diff --git a/sources/engine/Stride.Shaders/ConstantBufferType.cs b/sources/shaders/Stride.Shaders/ConstantBufferType.cs similarity index 100% rename from sources/engine/Stride.Shaders/ConstantBufferType.cs rename to sources/shaders/Stride.Shaders/ConstantBufferType.cs diff --git a/sources/engine/Stride.Shaders/EffectBytecode.cs b/sources/shaders/Stride.Shaders/EffectBytecode.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectBytecode.cs rename to sources/shaders/Stride.Shaders/EffectBytecode.cs diff --git a/sources/engine/Stride.Shaders/EffectConstantBufferDescription.cs b/sources/shaders/Stride.Shaders/EffectConstantBufferDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectConstantBufferDescription.cs rename to sources/shaders/Stride.Shaders/EffectConstantBufferDescription.cs diff --git a/sources/engine/Stride.Shaders/EffectParameterClass.cs b/sources/shaders/Stride.Shaders/EffectParameterClass.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectParameterClass.cs rename to sources/shaders/Stride.Shaders/EffectParameterClass.cs diff --git a/sources/engine/Stride.Shaders/EffectParameterKeyInfo.cs b/sources/shaders/Stride.Shaders/EffectParameterKeyInfo.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectParameterKeyInfo.cs rename to sources/shaders/Stride.Shaders/EffectParameterKeyInfo.cs diff --git a/sources/engine/Stride.Shaders/EffectParameterType.cs b/sources/shaders/Stride.Shaders/EffectParameterType.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectParameterType.cs rename to sources/shaders/Stride.Shaders/EffectParameterType.cs diff --git a/sources/engine/Stride.Shaders/EffectReflection.cs b/sources/shaders/Stride.Shaders/EffectReflection.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectReflection.cs rename to sources/shaders/Stride.Shaders/EffectReflection.cs diff --git a/sources/engine/Stride.Shaders/EffectResourceBindingDescription.cs b/sources/shaders/Stride.Shaders/EffectResourceBindingDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectResourceBindingDescription.cs rename to sources/shaders/Stride.Shaders/EffectResourceBindingDescription.cs diff --git a/sources/engine/Stride.Shaders/EffectSamplerStateBinding.cs b/sources/shaders/Stride.Shaders/EffectSamplerStateBinding.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectSamplerStateBinding.cs rename to sources/shaders/Stride.Shaders/EffectSamplerStateBinding.cs diff --git a/sources/engine/Stride.Shaders/EffectSourceCodeKeys.cs b/sources/shaders/Stride.Shaders/EffectSourceCodeKeys.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectSourceCodeKeys.cs rename to sources/shaders/Stride.Shaders/EffectSourceCodeKeys.cs diff --git a/sources/engine/Stride.Shaders/EffectTypeDescription.cs b/sources/shaders/Stride.Shaders/EffectTypeDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectTypeDescription.cs rename to sources/shaders/Stride.Shaders/EffectTypeDescription.cs diff --git a/sources/engine/Stride.Shaders/EffectTypeMemberDescription.cs b/sources/shaders/Stride.Shaders/EffectTypeMemberDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectTypeMemberDescription.cs rename to sources/shaders/Stride.Shaders/EffectTypeMemberDescription.cs diff --git a/sources/engine/Stride.Shaders/EffectValueDescription.cs b/sources/shaders/Stride.Shaders/EffectValueDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/EffectValueDescription.cs rename to sources/shaders/Stride.Shaders/EffectValueDescription.cs diff --git a/sources/engine/Stride.Shaders/HashSourceCollection.cs b/sources/shaders/Stride.Shaders/HashSourceCollection.cs similarity index 100% rename from sources/engine/Stride.Shaders/HashSourceCollection.cs rename to sources/shaders/Stride.Shaders/HashSourceCollection.cs diff --git a/sources/engine/Stride.Shaders/IShaderMixinBuilder.cs b/sources/shaders/Stride.Shaders/IShaderMixinBuilder.cs similarity index 100% rename from sources/engine/Stride.Shaders/IShaderMixinBuilder.cs rename to sources/shaders/Stride.Shaders/IShaderMixinBuilder.cs diff --git a/sources/engine/Stride.Shaders/IShaderMixinBuilderExtended.cs b/sources/shaders/Stride.Shaders/IShaderMixinBuilderExtended.cs similarity index 100% rename from sources/engine/Stride.Shaders/IShaderMixinBuilderExtended.cs rename to sources/shaders/Stride.Shaders/IShaderMixinBuilderExtended.cs diff --git a/sources/engine/Stride.Shaders/NamespaceDoc.cs b/sources/shaders/Stride.Shaders/NamespaceDoc.cs similarity index 100% rename from sources/engine/Stride.Shaders/NamespaceDoc.cs rename to sources/shaders/Stride.Shaders/NamespaceDoc.cs diff --git a/sources/engine/Stride.Shaders/ParameterKeyHashSerializer.cs b/sources/shaders/Stride.Shaders/ParameterKeyHashSerializer.cs similarity index 100% rename from sources/engine/Stride.Shaders/ParameterKeyHashSerializer.cs rename to sources/shaders/Stride.Shaders/ParameterKeyHashSerializer.cs diff --git a/sources/engine/Stride.Shaders/Properties/AssemblyInfo.cs b/sources/shaders/Stride.Shaders/Properties/AssemblyInfo.cs similarity index 100% rename from sources/engine/Stride.Shaders/Properties/AssemblyInfo.cs rename to sources/shaders/Stride.Shaders/Properties/AssemblyInfo.cs diff --git a/sources/engine/Stride.Shaders/ShaderArraySource.cs b/sources/shaders/Stride.Shaders/ShaderArraySource.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderArraySource.cs rename to sources/shaders/Stride.Shaders/ShaderArraySource.cs diff --git a/sources/engine/Stride.Shaders/ShaderBytecode.cs b/sources/shaders/Stride.Shaders/ShaderBytecode.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderBytecode.cs rename to sources/shaders/Stride.Shaders/ShaderBytecode.cs diff --git a/sources/engine/Stride.Shaders/ShaderClassCode.cs b/sources/shaders/Stride.Shaders/ShaderClassCode.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderClassCode.cs rename to sources/shaders/Stride.Shaders/ShaderClassCode.cs diff --git a/sources/engine/Stride.Shaders/ShaderClassSource.cs b/sources/shaders/Stride.Shaders/ShaderClassSource.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderClassSource.cs rename to sources/shaders/Stride.Shaders/ShaderClassSource.cs diff --git a/sources/engine/Stride.Shaders/ShaderClassString.cs b/sources/shaders/Stride.Shaders/ShaderClassString.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderClassString.cs rename to sources/shaders/Stride.Shaders/ShaderClassString.cs diff --git a/sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs b/sources/shaders/Stride.Shaders/ShaderInputAttributeDescription.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderInputAttributeDescription.cs rename to sources/shaders/Stride.Shaders/ShaderInputAttributeDescription.cs diff --git a/sources/engine/Stride.Shaders/ShaderInputBytecode.cs b/sources/shaders/Stride.Shaders/ShaderInputBytecode.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderInputBytecode.cs rename to sources/shaders/Stride.Shaders/ShaderInputBytecode.cs diff --git a/sources/engine/Stride.Shaders/ShaderMacro.cs b/sources/shaders/Stride.Shaders/ShaderMacro.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMacro.cs rename to sources/shaders/Stride.Shaders/ShaderMacro.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinContext.cs b/sources/shaders/Stride.Shaders/ShaderMixinContext.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinContext.cs rename to sources/shaders/Stride.Shaders/ShaderMixinContext.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinDiscardException.cs b/sources/shaders/Stride.Shaders/ShaderMixinDiscardException.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinDiscardException.cs rename to sources/shaders/Stride.Shaders/ShaderMixinDiscardException.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinGeneratorSource.cs b/sources/shaders/Stride.Shaders/ShaderMixinGeneratorSource.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinGeneratorSource.cs rename to sources/shaders/Stride.Shaders/ShaderMixinGeneratorSource.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinManager.cs b/sources/shaders/Stride.Shaders/ShaderMixinManager.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinManager.cs rename to sources/shaders/Stride.Shaders/ShaderMixinManager.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinObjectId.cs b/sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinObjectId.cs rename to sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinParameters.cs b/sources/shaders/Stride.Shaders/ShaderMixinParameters.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinParameters.cs rename to sources/shaders/Stride.Shaders/ShaderMixinParameters.cs diff --git a/sources/engine/Stride.Shaders/ShaderMixinSource.cs b/sources/shaders/Stride.Shaders/ShaderMixinSource.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderMixinSource.cs rename to sources/shaders/Stride.Shaders/ShaderMixinSource.cs diff --git a/sources/engine/Stride.Shaders/ShaderSource.cs b/sources/shaders/Stride.Shaders/ShaderSource.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderSource.cs rename to sources/shaders/Stride.Shaders/ShaderSource.cs diff --git a/sources/engine/Stride.Shaders/ShaderSourceCollection.cs b/sources/shaders/Stride.Shaders/ShaderSourceCollection.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderSourceCollection.cs rename to sources/shaders/Stride.Shaders/ShaderSourceCollection.cs diff --git a/sources/engine/Stride.Shaders/ShaderSourceToCode.cs b/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderSourceToCode.cs rename to sources/shaders/Stride.Shaders/ShaderSourceToCode.cs diff --git a/sources/engine/Stride.Shaders/ShaderStage.cs b/sources/shaders/Stride.Shaders/ShaderStage.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderStage.cs rename to sources/shaders/Stride.Shaders/ShaderStage.cs diff --git a/sources/engine/Stride.Shaders/ShaderStreamOutputDeclarationEntry.cs b/sources/shaders/Stride.Shaders/ShaderStreamOutputDeclarationEntry.cs similarity index 100% rename from sources/engine/Stride.Shaders/ShaderStreamOutputDeclarationEntry.cs rename to sources/shaders/Stride.Shaders/ShaderStreamOutputDeclarationEntry.cs diff --git a/sources/engine/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj similarity index 69% rename from sources/engine/Stride.Shaders/Stride.Shaders.csproj rename to sources/shaders/Stride.Shaders/Stride.Shaders.csproj index 7a7e540b0d..327293ce0d 100644 --- a/sources/engine/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -4,8 +4,6 @@ - 8.0.30703 - 2.0 true true --serialization --parameter-key @@ -19,8 +17,8 @@ - - + + \ No newline at end of file diff --git a/sources/engine/Stride.Shaders/build/Stride.Shaders.targets b/sources/shaders/Stride.Shaders/build/Stride.Shaders.targets similarity index 100% rename from sources/engine/Stride.Shaders/build/Stride.Shaders.targets rename to sources/shaders/Stride.Shaders/build/Stride.Shaders.targets diff --git a/sources/shaders/test.spv b/sources/shaders/test.spv deleted file mode 100644 index 13083ba0bb816d7245b27b458f2e1b4518fc6829..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmYk4NlF7@5Jt@H}-ujg@RL|oA=)vw_z zDP|92WuASE-2-{!Xr)|hEY-eZx7pX2wa%YJuL8xK?>q`7VaS={nW0-ey_2yS>^^i8 zOcSjZHY)e~3*WgdnBL7;!Ynm|`1Y`8ljl&8H@=5&ZWu&-T_%47@9w*n`_6PvdHZy> zt_G|Ta@9-p^2X-nH>mK2)*E-H1{`ma;_fqn@4FhmD12{a%zdnz0=}dCX|y@}npe*N z#r!PVJGzJc^!?9_nV(17E9Le52aTn9i`Yu?m$02_{c>TK>;0D2oA;kh_fPdrV&30< zoYw;KPq>lXRiOC&PTAC$|5mcsv47ZL1N~XlY!)1If8_Mf=xR@Q-2#ept=&eSb1i%C N0B8DM;+HyW{{hzfBkKSF From 172043382ae536bdc04ed0b56a8fbd33f438faf9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Feb 2026 17:50:12 +0900 Subject: [PATCH 0832/1182] Shader tests: fix project so that they can run --- .../Stride.Shaders.Tests/Stride.Shaders.Tests.csproj | 12 +++++++----- sources/shared/tests/xunit/LauncherSimple.Desktop.cs | 4 +--- sources/targets/Stride.UnitTests.targets | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index be94136493..b2e467bf2f 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -1,13 +1,16 @@  - + - net10.0 + $(StrideEditorTargetFramework) + win-x64 + * enable enable false true True + false true @@ -28,18 +31,17 @@ - - + - + diff --git a/sources/shared/tests/xunit/LauncherSimple.Desktop.cs b/sources/shared/tests/xunit/LauncherSimple.Desktop.cs index 0b01f29cd1..13d32ace75 100644 --- a/sources/shared/tests/xunit/LauncherSimple.Desktop.cs +++ b/sources/shared/tests/xunit/LauncherSimple.Desktop.cs @@ -1,9 +1,7 @@ -using Stride.Graphics.Tests; - namespace xunit.runner.stride { class Program { - public static void Main(string[] args) => new TestImageEffect().RunImageEffect(); + public static void Main(string[] args) => StrideXunitRunner.Main(args); } } diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index 6517931e39..493ecbcb35 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -50,9 +50,12 @@ + true + + xunit.runner.stride.Program - + LauncherSimple.Desktop.cs From 58df966195dde91566c52586c308f13c1eade51e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Feb 2026 12:05:42 +0900 Subject: [PATCH 0833/1182] SDSL: fix build system and generators --- build/Stride.sln | 106 ++++++++++-------- .../Stride.Shaders.Compilers.csproj | 6 + .../build/Stride.Shaders.targets | 0 .../Stride.Shaders.Generators.csproj | 11 +- .../Stride.Shaders.Parsers.csproj | 4 +- .../Stride.Shaders.Spirv.Core.csproj | 49 ++++---- .../Stride.Shaders/Stride.Shaders.csproj | 5 +- sources/targets/Stride.UnitTests.targets | 15 ++- sources/targets/Stride.targets | 13 ++- 9 files changed, 114 insertions(+), 95 deletions(-) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Compilers}/build/Stride.Shaders.targets (100%) diff --git a/build/Stride.sln b/build/Stride.sln index c7b7ccda59..9376018efa 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -76,6 +76,40 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "31-CoreDesign.Tests", "31-C EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "71-StrideAssets.Tests", "71-StrideAssets.Tests", "{A47B451D-3162-410F-BAF7-C650C4B7A4B0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Localization", "00-Localization", "{FC791F56-C1F1-4C41-A193-868D8197F8E2}" + ProjectSection(SolutionItems) = preProject + ..\sources\localization\Stride.Assets.Presentation.pot = ..\sources\localization\Stride.Assets.Presentation.pot + ..\sources\localization\Stride.Core.Assets.Editor.pot = ..\sources\localization\Stride.Core.Assets.Editor.pot + ..\sources\localization\Stride.Core.Presentation.pot = ..\sources\localization\Stride.Core.Presentation.pot + ..\sources\localization\Stride.GameStudio.pot = ..\sources\localization\Stride.GameStudio.pot + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ja", "ja", "{B4EABB0D-E495-405C-B7B1-E2A7A3711AF5}" + ProjectSection(SolutionItems) = preProject + ..\sources\localization\ja\Stride.Assets.Presentation.ja.po = ..\sources\localization\ja\Stride.Assets.Presentation.ja.po + ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po = ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po + ..\sources\localization\ja\Stride.Core.Presentation.ja.po = ..\sources\localization\ja\Stride.Core.Presentation.ja.po + ..\sources\localization\ja\Stride.GameStudio.ja.po = ..\sources\localization\ja\Stride.GameStudio.ja.po + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "72-StrideSamples", "72-StrideSamples", "{75608B5C-1C03-4B38-810E-14EED5165E59}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fr", "fr", "{62E9A8E4-79AF-4081-84D5-FEC5A0B28598}" + ProjectSection(SolutionItems) = preProject + ..\sources\localization\fr\Stride.Assets.Presentation.fr.po = ..\sources\localization\fr\Stride.Assets.Presentation.fr.po + ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po = ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po + ..\sources\localization\fr\Stride.Core.Presentation.fr.po = ..\sources\localization\fr\Stride.Core.Presentation.fr.po + ..\sources\localization\fr\Stride.GameStudio.fr.po = ..\sources\localization\fr\Stride.GameStudio.fr.po + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VisualStudio", "VisualStudio", "{DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGetResolver", "NuGetResolver", "{158087CF-AF74-44E9-AA20-A6AEB1E398A9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Bepu", "Stride.Bepu", "{DE048114-9AE4-467E-A879-188DC0D88A59}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "22-StrideRuntime.Shaders", "22-StrideRuntime.Shaders", "{7E3ACF35-0CCA-4E88-866B-0F008C5A5580}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.GameStudio", "..\sources\editor\Stride.GameStudio\Stride.GameStudio.csproj", "{2FCA2D8B-B10F-4DCA-9847-4221F74BA586}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Engine", "..\sources\engine\Stride.Engine\Stride.Engine.csproj", "{C121A566-555E-42B9-9B0A-1696529A9088}" @@ -252,40 +286,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Translation.Pre EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Translation.Extractor", "..\sources\tools\Stride.Core.Translation.Extractor\Stride.Core.Translation.Extractor.csproj", "{164A5B9A-E684-4B3F-9EF4-B7765FC0A8A1}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Localization", "00-Localization", "{FC791F56-C1F1-4C41-A193-868D8197F8E2}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\Stride.Assets.Presentation.pot = ..\sources\localization\Stride.Assets.Presentation.pot - ..\sources\localization\Stride.Core.Assets.Editor.pot = ..\sources\localization\Stride.Core.Assets.Editor.pot - ..\sources\localization\Stride.Core.Presentation.pot = ..\sources\localization\Stride.Core.Presentation.pot - ..\sources\localization\Stride.GameStudio.pot = ..\sources\localization\Stride.GameStudio.pot - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ja", "ja", "{B4EABB0D-E495-405C-B7B1-E2A7A3711AF5}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\ja\Stride.Assets.Presentation.ja.po = ..\sources\localization\ja\Stride.Assets.Presentation.ja.po - ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po = ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po - ..\sources\localization\ja\Stride.Core.Presentation.ja.po = ..\sources\localization\ja\Stride.Core.Presentation.ja.po - ..\sources\localization\ja\Stride.GameStudio.ja.po = ..\sources\localization\ja\Stride.GameStudio.ja.po - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Video", "..\sources\engine\Stride.Video\Stride.Video.csproj", "{DA355C86-866F-4843-9B4D-63A173C750FB}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "72-StrideSamples", "72-StrideSamples", "{75608B5C-1C03-4B38-810E-14EED5165E59}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Samples.Tests", "..\samples\Tests\Stride.Samples.Tests.csproj", "{2FC40214-A4AA-45DC-9C93-72ED800C40B0}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Stride.NuGetResolver.Targets", "..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.shproj", "{00B72ED7-00E9-47F7-868D-8162027CD068}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Samples.Templates", "..\sources\editor\Stride.Samples.Templates\Stride.Samples.Templates.csproj", "{040F754C-17F4-4B5F-B974-93F1E39D107F}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fr", "fr", "{62E9A8E4-79AF-4081-84D5-FEC5A0B28598}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\fr\Stride.Assets.Presentation.fr.po = ..\sources\localization\fr\Stride.Assets.Presentation.fr.po - ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po = ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po - ..\sources\localization\fr\Stride.Core.Presentation.fr.po = ..\sources\localization\fr\Stride.Core.Presentation.fr.po - ..\sources\localization\fr\Stride.GameStudio.fr.po = ..\sources\localization\fr\Stride.GameStudio.fr.po - EndProjectSection -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Rendering", "..\sources\engine\Stride.Rendering\Stride.Rendering.csproj", "{AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Voxels", "..\sources\engine\Stride.Voxels\Stride.Voxels.csproj", "{66BE41FC-FC52-48D0-9C04-BCE8CC393020}" @@ -300,8 +308,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.CompilerService EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.CompilerServices.Tests", "..\sources\core\Stride.Core.CompilerServices.Tests\Stride.Core.CompilerServices.Tests.csproj", "{BACD76E5-35D0-4389-9BB9-8743AC4D89DE}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "VisualStudio", "VisualStudio", "{DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.VisualStudio.Commands.Interfaces", "..\sources\tools\Stride.VisualStudio.Commands.Interfaces\Stride.VisualStudio.Commands.Interfaces.csproj", "{09E29A89-A6D7-45C9-B7BA-CA6D643C246F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.VisualStudio.Commands", "..\sources\tools\Stride.VisualStudio.Commands\Stride.VisualStudio.Commands.csproj", "{A7FC60AE-BB54-47D3-8787-788EEC65AD45}" @@ -310,12 +316,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.NuGetResolver.UI", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.NuGetResolver", "..\sources\shared\Stride.NuGetResolver\Stride.NuGetResolver.csproj", "{02FD0BDE-4293-414F-97E6-69FF71105420}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuGetResolver", "NuGetResolver", "{158087CF-AF74-44E9-AA20-A6AEB1E398A9}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Presentation", "..\sources\presentation\Stride.Core.Presentation\Stride.Core.Presentation.csproj", "{0C63EF8B-26F9-4511-9FC5-7431DE9657D6}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Bepu", "Stride.Bepu", "{DE048114-9AE4-467E-A879-188DC0D88A59}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.BepuPhysics", "..\sources\engine\Stride.BepuPhysics\Stride.BepuPhysics\Stride.BepuPhysics.csproj", "{3E424688-EC44-4DFB-9FC0-4BB1F0683651}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.BepuPhysics.Debug", "..\sources\engine\Stride.BepuPhysics\Stride.BepuPhysics.Debug\Stride.BepuPhysics.Debug.csproj", "{7715D094-DF59-4D91-BC9A-9A5118039ECB}" @@ -326,19 +328,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.BepuPhysics.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.FreeImage", "..\sources\tools\Stride.FreeImage\Stride.FreeImage.csproj", "{03695F9B-10E9-4A10-93AE-6402E46F10B5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Editor.CrashReport", "..\sources\editor\Stride.Editor.CrashReport\Stride.Editor.CrashReport.csproj", "{35EC42D8-0A09-41AE-A918-B8C2796061B3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Editor.CrashReport", "..\sources\editor\Stride.Editor.CrashReport\Stride.Editor.CrashReport.csproj", "{35EC42D8-0A09-41AE-A918-B8C2796061B3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "22-StrideRuntime.Shaders", "22-StrideRuntime.Shaders", "{7E3ACF35-0CCA-4E88-866B-0F008C5A5580}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Generators.Internal", "..\sources\shaders\Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Generators.Internal", "..\sources\shaders\Stride.Shaders.Generators.Internal\Stride.Shaders.Generators.Internal.csproj", "{B8D08AF9-51D1-2B4A-C8CE-307D70E53CCB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Generators", "..\sources\shaders\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{2618F6D9-685D-FDE1-B467-84BC8C858F51}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Generators", "..\sources\shaders\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{2618F6D9-685D-FDE1-B467-84BC8C858F51}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core", "..\sources\shaders\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Spirv.Core", "..\sources\shaders\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Tests", "..\sources\shaders\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Tests", "..\sources\shaders\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parsers", "..\sources\shaders\Stride.Shaders.Parsers\Stride.Shaders.Parsers.csproj", "{CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.Shaders.Parsers", "..\sources\shaders\Stride.Shaders.Parsers\Stride.Shaders.Parsers.csproj", "{CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Generators", "..\sources\shaders\Stride.Shaders.Generators\Stride.Shaders.Generators.csproj", "{0920DA18-53C3-8DA4-8BC5-038735B96973}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1557,6 +1559,18 @@ Global {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Mixed Platforms.Build.0 = Release|Any CPU {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Win32.ActiveCfg = Release|Any CPU {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8}.Release|Win32.Build.0 = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Win32.ActiveCfg = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Debug|Win32.Build.0 = Debug|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Any CPU.Build.0 = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Win32.ActiveCfg = Release|Any CPU + {0920DA18-53C3-8DA4-8BC5-038735B96973}.Release|Win32.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1566,6 +1580,11 @@ Global {6F473FA6-4F8B-4FBA-AE33-EE5AF997D50C} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} {4A15BAAD-AA37-4754-A2BF-8D4049211E36} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} {1AC70118-C90F-4EC6-9D8B-C628BDF900F7} = {4C142567-C42B-40F5-B092-798882190209} + {B4EABB0D-E495-405C-B7B1-E2A7A3711AF5} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} + {62E9A8E4-79AF-4081-84D5-FEC5A0B28598} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} + {DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} + {158087CF-AF74-44E9-AA20-A6AEB1E398A9} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} + {DE048114-9AE4-467E-A879-188DC0D88A59} = {4C142567-C42B-40F5-B092-798882190209} {2FCA2D8B-B10F-4DCA-9847-4221F74BA586} = {5D2D3BE8-9910-45CA-8E45-95660DA4C563} {C121A566-555E-42B9-9B0A-1696529A9088} = {4C142567-C42B-40F5-B092-798882190209} {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5} = {4C142567-C42B-40F5-B092-798882190209} @@ -1654,12 +1673,10 @@ Global {6A7B231E-36AA-4647-8C1A-FB1540ABC813} = {25F10A0B-7259-404C-86BE-FD2363C92F72} {B686C194-D71D-4FF0-8B4F-F53AFBCD962F} = {75A820AB-0F21-40F2-9448-5D7F495B97A0} {164A5B9A-E684-4B3F-9EF4-B7765FC0A8A1} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} - {B4EABB0D-E495-405C-B7B1-E2A7A3711AF5} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} {DA355C86-866F-4843-9B4D-63A173C750FB} = {4C142567-C42B-40F5-B092-798882190209} {2FC40214-A4AA-45DC-9C93-72ED800C40B0} = {75608B5C-1C03-4B38-810E-14EED5165E59} {00B72ED7-00E9-47F7-868D-8162027CD068} = {158087CF-AF74-44E9-AA20-A6AEB1E398A9} {040F754C-17F4-4B5F-B974-93F1E39D107F} = {75608B5C-1C03-4B38-810E-14EED5165E59} - {62E9A8E4-79AF-4081-84D5-FEC5A0B28598} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4} = {4C142567-C42B-40F5-B092-798882190209} {66BE41FC-FC52-48D0-9C04-BCE8CC393020} = {4C142567-C42B-40F5-B092-798882190209} {D5B023BE-010F-44A8-ABF1-DB6F3BCEA392} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} @@ -1667,14 +1684,11 @@ Global {806AA078-6070-4BB6-B05B-6EE6B21B1CDE} = {6F473FA6-4F8B-4FBA-AE33-EE5AF997D50C} {D62BBD65-AB1C-41C7-8EC3-88949993C71E} = {2E93E2B5-4500-4E47-9B65-E705218AB578} {BACD76E5-35D0-4389-9BB9-8743AC4D89DE} = {22ADD4CD-092E-4ADC-A21E-64CF42230152} - {DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} {09E29A89-A6D7-45C9-B7BA-CA6D643C246F} = {DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD} {A7FC60AE-BB54-47D3-8787-788EEC65AD45} = {DF9172C0-DEA3-4DCE-8AF1-39439ACB4BCD} {79F7B3CE-A22F-426D-8DAB-2F692F167210} = {158087CF-AF74-44E9-AA20-A6AEB1E398A9} {02FD0BDE-4293-414F-97E6-69FF71105420} = {158087CF-AF74-44E9-AA20-A6AEB1E398A9} - {158087CF-AF74-44E9-AA20-A6AEB1E398A9} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185} {0C63EF8B-26F9-4511-9FC5-7431DE9657D6} = {75A820AB-0F21-40F2-9448-5D7F495B97A0} - {DE048114-9AE4-467E-A879-188DC0D88A59} = {4C142567-C42B-40F5-B092-798882190209} {3E424688-EC44-4DFB-9FC0-4BB1F0683651} = {DE048114-9AE4-467E-A879-188DC0D88A59} {7715D094-DF59-4D91-BC9A-9A5118039ECB} = {DE048114-9AE4-467E-A879-188DC0D88A59} {66EFFDE4-24F0-4E57-9618-0F5577E20A1E} = {6F473FA6-4F8B-4FBA-AE33-EE5AF997D50C} @@ -1686,6 +1700,7 @@ Global {7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} {137B0DE2-10F3-3496-6A5B-D3FE538BAA7B} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} {CF8F1CC5-22B2-FB1B-4D20-288E0A0057D8} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {0920DA18-53C3-8DA4-8BC5-038735B96973} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FF877973-604D-4EA7-B5F5-A129961F9EF2} @@ -1705,16 +1720,13 @@ Global ..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.projitems*{75d71310-ecf7-4592-9e35-3fe540040982}*SharedItemsImports = 5 ..\sources\shared\Stride.Core.ShellHelper\Stride.Core.ShellHelper.projitems*{77e2fcc0-4ca6-436c-be6f-9418cb807d45}*SharedItemsImports = 5 ..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.projitems*{77e2fcc0-4ca6-436c-be6f-9418cb807d45}*SharedItemsImports = 5 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{7af4b563-aad3-42ff-b91e-84b9d34d904a}*SharedItemsImports = 5 ..\sources\editor\Stride.PrivacyPolicy\Stride.PrivacyPolicy.projitems*{950badd0-ad5a-4f58-87ec-4adaecbea89b}*SharedItemsImports = 13 ..\sources\editor\Stride.Core.MostRecentlyUsedFiles\Stride.Core.MostRecentlyUsedFiles.projitems*{9ac6d791-811e-4d6a-b08e-93f0093ef268}*SharedItemsImports = 13 ..\sources\shared\Stride.Core.ShellHelper\Stride.Core.ShellHelper.projitems*{a5dc820b-9554-45b6-9677-6a2f902e7787}*SharedItemsImports = 5 ..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.projitems*{a5dc820b-9554-45b6-9677-6a2f902e7787}*SharedItemsImports = 5 ..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.projitems*{a7fc60ae-bb54-47d3-8787-788eec65ad45}*SharedItemsImports = 5 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{c121a566-555e-42b9-9b0a-1696529a9088}*SharedItemsImports = 5 ..\sources\shared\Stride.NuGetResolver.Targets\Stride.NuGetResolver.Targets.projitems*{e25e7778-0b2f-4a0b-bcd6-1de95320b531}*SharedItemsImports = 5 ..\sources\shared\Stride.Core.ShellHelper\Stride.Core.ShellHelper.projitems*{e8b3553f-a79f-4e50-b75b-acee771c320c}*SharedItemsImports = 5 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{fb06c76a-6bb7-40be-9afa-fec13b045fb5}*SharedItemsImports = 5 ..\sources\assets\Stride.Core.Assets.Yaml\Stride.Core.Assets.Yaml.projitems*{fb9ed2c4-94a0-4004-a498-3f29a9d5bb5d}*SharedItemsImports = 13 EndGlobalSection EndGlobal diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 1ba973082f..70d8d886e9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -21,6 +21,7 @@ + @@ -44,6 +45,11 @@ PreserveNewest + + + + + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders/build/Stride.Shaders.targets b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.targets similarity index 100% rename from sources/shaders/Stride.Shaders/build/Stride.Shaders.targets rename to sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.targets diff --git a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index 4db90db5a8..840af77942 100644 --- a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -8,10 +8,13 @@ true Stride.Shaders.Generators true - + true + false + - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -23,6 +26,4 @@ - - diff --git a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj index d8ce31631d..696fd1e7ab 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj +++ b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj @@ -21,13 +21,11 @@ + * enable enable True - CS8785;$(WarningsAsErrors) - true Stride.Shaders - * diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 7a94b0874f..2d690907fa 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,35 +1,30 @@ - + true - enable - enable - true - CS8785;$(WarningsAsErrors) + enable + enable * - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj index 327293ce0d..58592571d8 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -4,10 +4,10 @@ + * true true --serialization --parameter-key - * @@ -15,9 +15,6 @@ - - - diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index 493ecbcb35..d6f71575a6 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -75,14 +75,19 @@ - - - - - + + + + + + + true + CS8785;$(WarningsAsErrors) + + diff --git a/sources/targets/Stride.targets b/sources/targets/Stride.targets index cf8398b9d3..ba19de50c1 100644 --- a/sources/targets/Stride.targets +++ b/sources/targets/Stride.targets @@ -55,12 +55,17 @@ - - - - + + + + + + + true + CS8785;$(WarningsAsErrors) + From 706eb720f09e74dca37e1f85a00fbea76ddebc24 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Feb 2026 12:07:37 +0900 Subject: [PATCH 0834/1182] Bump Stride to 4.4 --- sources/shared/SharedAssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shared/SharedAssemblyInfo.cs b/sources/shared/SharedAssemblyInfo.cs index ffa13de9c5..93c766ce4d 100644 --- a/sources/shared/SharedAssemblyInfo.cs +++ b/sources/shared/SharedAssemblyInfo.cs @@ -25,7 +25,7 @@ internal class StrideVersion /// /// The version used by editor for display purpose. The 4th digit will automatically be replaced by the git height when building packages with Stride.Build. /// - public const string PublicVersion = "4.3.0.1"; + public const string PublicVersion = "4.4.0.1"; /// /// The current assembly version as text, currently same as . From b6467f66670f9b07f34274ecd19e9248cc1d57ef Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Feb 2026 12:52:56 +0900 Subject: [PATCH 0835/1182] Output #error if using old custom tool generator on shader files --- .../StrideCommands.cs | 111 ++---------------- 1 file changed, 11 insertions(+), 100 deletions(-) diff --git a/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs b/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs index 9cf1f8e063..b9b98856db 100644 --- a/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs +++ b/sources/tools/Stride.VisualStudio.Commands/StrideCommands.cs @@ -3,12 +3,9 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using Stride.Core; using Stride.Core.Assets; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Utility; -using Stride.Shaders.Parser; -using Stride.Shaders.Parser.Mixins; using Stride.VisualStudio.Commands.Shaders; namespace Stride.VisualStudio.Commands @@ -22,106 +19,20 @@ public StrideCommands() public byte[] GenerateShaderKeys(string inputFileName, string inputFileContent) { - throw new NotSupportedException("ShaderKeyGenerator is not used in Stride 4.4+"); + var data = Encoding.UTF8.GetBytes(""" + // New shader system use C# analyzer to generate code instead of custom tools. + // - If using Visual Studio: right-click file, Properties, set "Build Action" to "C# analyzer additional file" and clear value in "Custom Tool". + // Also delete the already generated .sdfx.cs and .sdfx.cs files + // - If editing .csproj manually: switch your .sdsl/.sdfx files in ItemGroup from None to AdditionalFiles in .csproj and remove CodeGenerator + // Also delete the already generated .sdfx.cs and .sdfx.cs files and remove them from the .csproj + #error Shader or Effect file is using old build system. Please use ItemType AdditionalFiles instead of None and remove the Generator metadata + """); + return [.. Encoding.UTF8.GetPreamble(), ..data]; } public RawShaderNavigationResult AnalyzeAndGoToDefinition(string projectPath, string sourceCode, RawSourceSpan span) { - var rawResult = new RawShaderNavigationResult(); - - var navigation = new ShaderNavigation(); - - var shaderDirectories = CollectShadersDirectories(projectPath); - - if (span.File != null) - { - var dirName = Path.GetDirectoryName(span.File); - if (dirName != null) - { - shaderDirectories.Add(dirName); - } - } - - var resultAnalysis = navigation.AnalyzeAndGoToDefinition(sourceCode, new Stride.Core.Shaders.Ast.SourceLocation(span.File, 0, span.Line, span.Column), shaderDirectories); - - if (resultAnalysis.DefinitionLocation.Location.FileSource != null) - { - rawResult.DefinitionSpan = ConvertToRawLocation(resultAnalysis.DefinitionLocation); - } - - foreach (var message in resultAnalysis.Messages.Messages) - { - rawResult.Messages.Add(ConvertToRawMessage(message)); - } - - return rawResult; - } - - private static RawSourceSpan ConvertToRawLocation(SourceSpan span) - { - return new RawSourceSpan() - { - File = span.Location.FileSource, - Line = span.Location.Line, - EndLine = span.Location.Line, - Column = span.Location.Column, - EndColumn = span.Location.Column + span.Length - }; - } - - private static RawShaderAnalysisMessage ConvertToRawMessage(ReportMessage message) - { - return new RawShaderAnalysisMessage() - { - Span = ConvertToRawLocation(message.Span), - Text = message.Text, - Code = message.Code, - Type = ConvertToStringLevel(message.Level) - }; - } - - private static string ConvertToStringLevel(ReportMessageLevel level) - { - return level.ToString().ToLowerInvariant(); - } - - private List CollectShadersDirectories(string packagePath) - { - if (packagePath == null) - { - packagePath = PackageStore.Instance.GetPackageFileName("Stride.Engine", new PackageVersionRange(new PackageVersion(StrideVersion.NuGetVersion))); - } - - var defaultLoad = PackageLoadParameters.Default(); - defaultLoad.AutoCompileProjects = false; - defaultLoad.AutoLoadTemporaryAssets = false; - defaultLoad.GenerateNewAssetIds = false; - defaultLoad.LoadAssemblyReferences = false; - - var sessionResult = PackageSession.Load(packagePath, defaultLoad); - - if (sessionResult.HasErrors) - { - // TODO: Throw an error - return null; - } - - var session = sessionResult.Session; - - var assetsPaths = new List(); - foreach (var package in session.Packages) - { - foreach (var assetFolder in package.AssetFolders) - { - var fullPath = assetFolder.Path.ToOSPath(); - if (Directory.Exists(fullPath)) - { - assetsPaths.Add(fullPath); - assetsPaths.AddRange(Directory.EnumerateDirectories(fullPath, "*.*", SearchOption.AllDirectories)); - } - } - } - return assetsPaths; + return new RawShaderNavigationResult(); } } } From 1661cb9d86171d7a20e5a4983bda3e965de35c71 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 11:30:38 +0900 Subject: [PATCH 0836/1182] SDSL: fix macros inheritance (in composition, etc.) --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 58 ++++++++++++++++--- .../SDSL/ShaderMixer.cs | 6 +- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 333bcec863..fe39709557 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -1,4 +1,4 @@ -using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; @@ -18,10 +18,17 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderSource shaderSource, Action? addToRoot = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderMixinSource? parent, ShaderSource shaderSource, Action? addToRoot = null) { var mixinList = new List(); + Span macros = (shaderSource, parent) switch + { + (ShaderMixinSource mixinSource, _) => mixinSource.Macros.AsSpan(), + (_, not null) => parent.Macros.AsSpan(), + _ => Span.Empty, + }; + var shaderMixinSource = shaderSource switch { ShaderMixinSource mixinSource2 => mixinSource2, @@ -33,7 +40,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha foreach (var mixinToMerge in shaderMixinSource.Mixins) { - var shaderBuffer = SpirvBuilder.GetOrLoadShader(shaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, shaderMixinSource.Macros.AsSpan()); + var shaderBuffer = SpirvBuilder.GetOrLoadShader(shaderLoader, mixinToMerge.ClassName, mixinToMerge.GenericArguments, macros); var mixinToMerge2 = new ShaderClassInstantiation(mixinToMerge.ClassName, []); mixinToMerge2.Buffer = shaderBuffer; @@ -47,7 +54,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha } } - SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, shaderMixinSource.Macros.AsSpan(), mixinList, ResolveStep.Mix); + SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, macros, mixinList, ResolveStep.Mix); } ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot); @@ -133,12 +140,12 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con { var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, value, addToRootRecursive)); + variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, addToRootRecursive)); compositions[variableName] = [..variableCompositions]; } else { - var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, compositionMixin, addToRootRecursive); + var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, compositionMixin, addToRootRecursive); compositions[variableName] = [variableComposition]; } } @@ -160,4 +167,41 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con result.Mixins.Add(shaderName); } } -} \ No newline at end of file + + private void PropagateMacrosRecursively(ShaderSource child, ShaderMixinSource? parent = null) + { + var existingMacros = new HashSet(); + if (child is ShaderMixinSource mixinChild) + { + foreach (var macro in mixinChild.Macros) + { + existingMacros.Add(macro.Name); + } + if (parent != null) + { + foreach (var macro in parent.Macros) + { + if (!existingMacros.Contains(macro.Name)) + mixinChild.AddMacro(macro.Name, macro.Definition); + } + } + + // Recurse + foreach (var mixin in mixinChild.Mixins) + { + PropagateMacrosRecursively(mixin, mixinChild); + } + foreach (var composition in mixinChild.Compositions) + { + PropagateMacrosRecursively(composition.Value, mixinChild); + } + } + else if (child is ShaderArraySource arrayChild) + { + foreach (var mixin in arrayChild) + { + PropagateMacrosRecursively(mixin, parent); + } + } + } +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index dafb7c11b6..c20b7d75f0 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -44,7 +44,11 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span if (shaderSource is ShaderMixinGeneratorSource mixinGeneratorSource) shaderSource = ShaderMixinManager.Generate(mixinGeneratorSource.Name, new()); - var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderSource); + // Propgate macros to child + if (shaderSource is ShaderMixinSource mixinSource) + PropagateMacrosRecursively(mixinSource, null); + + var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, null, shaderSource); // Root shader var globalContext = new MixinGlobalContext(); From 3faf25249a26c64616d01bb39395cac6642e1faa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 13:55:10 +0900 Subject: [PATCH 0837/1182] SDSL: Shader.Tests now use Stride shaders from Rendering/Engine projects instead of a copy --- .../FrameRenderer.D3D11.cs | 6 +- .../Stride.Shaders.Tests/FrameRenderer.cs | 4 +- .../Stride.Shaders.Tests/ParsingTests.cs | 4 +- .../shaders/Stride.Shaders.Tests/Program.cs | 8 +- .../Stride.Shaders.Tests/RenderingTests.cs | 50 +- .../Stride.Shaders.Tests/ShaderLoader.cs | 53 + .../Stride.Shaders.Tests.csproj | 7 +- .../Stride.Shaders.Tests/StrideShaderTests.cs | 178 ++ .../Stride.Shaders.Tests/TestHeaderParser.cs | 4 +- .../SDFX/AmbientOcclusionBlurEffect.sdfx | 15 - .../SDFX/AmbientOcclusionRawAOEffect.sdfx | 15 - .../Stride/SDFX/BackgroundVelocityEffect.sdfx | 21 - .../assets/Stride/SDFX/CoCMapBlurEffect.sdfx | 15 - .../Stride/SDFX/ColorCombinerEffect.sdfx | 12 - .../SDFX/ColorTransformGroupEffect.sdfx | 28 - .../Stride/SDFX/CombineFrontCoCEffect.sdfx | 16 - .../SDFX/CombineLevelsFromCoCEffect.sdfx | 15 - .../Stride/SDFX/ComputeEffectShader.sdfx | 23 - .../Stride/SDFX/ComputeShaderTestEffect.sdfx | 17 - .../assets/Stride/SDFX/CubemapEffect.sdfx | 50 - .../assets/Stride/SDFX/CustomEffect.sdfx | 27 - .../SDFX/DepthAwareDirectionalBlurEffect.sdfx | 16 - .../assets/Stride/SDFX/DepthMinMaxEffect.sdfx | 12 - .../assets/Stride/SDFX/FXAAShaderEffect.sdfx | 14 - .../Stride/SDFX/FlareArtifactEffect.sdfx | 15 - .../Stride/SDFX/GaussianBlurEffect.sdfx | 15 - .../assets/Stride/SDFX/ImageScalerEffect.sdfx | 18 - .../Stride/SDFX/LambertianPrefilteringSH.sdfx | 26 - ...mbertianPrefilteringSHNoComputeEffect.sdfx | 12 - .../assets/Stride/SDFX/LightShaftsEffect.sdfx | 14 - .../assets/Stride/SDFX/LightSkyboxEffect.sdfx | 26 - .../assets/Stride/SDFX/LightStreakEffect.sdfx | 15 - .../Stride/SDFX/MSAAResolverEffect.sdfx | 28 - .../Stride/SDFX/McIntoshOptimizedEffect.sdfx | 18 - .../SDFX/ModelComponentPickingEffect.sdfx | 11 - .../SDFX/MultiTexturesSpriteEffect.sdfx | 9 - .../SDFX/MultipleRenderTargetsEffect.sdfx | 11 - .../Stride/SDFX/ParticleBaseEffect.sdfx | 15 - .../Stride/SDFX/ParticleCustomEffect.sdfx | 32 - .../assets/Stride/SDFX/ParticleEffect.sdfx | 18 - .../shaders/assets/Stride/SDFX/Picking.sdfx | 10 - .../assets/Stride/SDFX/PreviewTexture.sdfx | 25 - .../SDFX/RadiancePrefilteringGGXEffect.sdfx | 17 - ...adiancePrefilteringGGXNoComputeEffect.sdfx | 17 - .../Stride/SDFX/SceneEditorParameters.sdfx | 16 - .../assets/Stride/SDFX/SelectedSprite.sdfx | 12 - .../assets/Stride/SDFX/ShadowMapCaster.sdfx | 26 - .../Stride/SDFX/ShadowMapCasterCubeMap.sdfx | 28 - .../SDFX/ShadowMapCasterParaboloid.sdfx | 28 - .../assets/Stride/SDFX/SimpleEffect.sdfx | 9 - .../Stride/SDFX/SpaceEscapeEffectMain.sdfx | 28 - .../SDFX/SphericalHarmonicsParameters.sdfx | 10 - .../SphericalHarmonicsRendererEffect.sdfx | 12 - .../assets/Stride/SDFX/SpriteBatch.sdfx | 13 - .../SDFX/StrideBakeLightProbeEffect.sdfx | 12 - .../StrideEditorForwardShadingEffect.sdfx | 54 - .../SDFX/StrideEditorHighlightingEffect.sdfx | 14 - .../StrideEditorMaterialPreviewEffect.sdfx | 14 - .../assets/Stride/SDFX/StrideEffectBase.sdfx | 181 -- .../SDFX/StrideForwardShadingEffect.sdfx | 77 - .../SDFX/StrideWireframeShadingEffect.sdfx | 17 - .../SDFX/SubsurfaceScatteringBlurEffect.sdfx | 17 - .../assets/Stride/SDFX/ToGlslEffect.sdfx | 9 - .../assets/Stride/SDFX/ToneMapEffect.sdfx | 19 - .../shaders/assets/Stride/SDFX/UIEffect.sdfx | 13 - .../SDFX/test_mixin_complex_params.sdfx | 47 - .../Stride/SDFX/test_mixin_compose_keys.sdfx | 37 - .../assets/Stride/SDFX/test_mixin_simple.sdfx | 11 - .../Stride/SDFX/test_mixin_simple_child.sdfx | 18 - .../SDFX/test_mixin_simple_child_params.sdfx | 33 - .../Stride/SDFX/test_mixin_simple_clone.sdfx | 19 - .../SDFX/test_mixin_simple_compose.sdfx | 12 - .../Stride/SDFX/test_mixin_simple_params.sdfx | 38 - sources/shaders/assets/Stride/SDSL/A.sdsl | 18 - .../Stride/SDSL/AdditiveLightEffect.sdsl | 11 - .../Stride/SDSL/AdditiveLightShader.sdsl | 22 - .../SDSL/AmbientOcclusionBlurShader.sdsl | 64 - .../SDSL/AmbientOcclusionRawAOShader.sdsl | 168 -- .../SDSL/ApplyAmbientOcclusionShader.sdsl | 30 - sources/shaders/assets/Stride/SDSL/B.sdsl | 5 - .../assets/Stride/SDSL/BRDFMicrofacet.sdsl | 227 -- .../Stride/SDSL/BackgroundCubemapShader.sdsl | 14 - .../assets/Stride/SDSL/BackgroundShader.sdsl | 13 - .../Stride/SDSL/BackgroundVelocity.sdsl | 28 - .../Stride/SDSL/BakeLightProbeShader.sdsl | 29 - .../assets/Stride/SDSL/BaseTestChild.sdsl | 15 - .../assets/Stride/SDSL/BaseTestInter.sdsl | 10 - .../assets/Stride/SDSL/BaseTestParent.sdsl | 8 - .../assets/Stride/SDSL/BasicMixin.sdsl | 16 - .../assets/Stride/SDSL/BasicMixin2.sdsl | 8 - .../assets/Stride/SDSL/BlendUtils.sdsl | 63 - .../SDSL/BloomAfterimageCombineShader.sdsl | 24 - .../Stride/SDSL/BloomAfterimageShader.sdsl | 32 - .../Stride/SDSL/BrightFilterShader.sdsl | 40 - .../assets/Stride/SDSL/BufferToTexture.sdsl | 54 - .../Stride/SDSL/BufferToTextureColumns.sdsl | 83 - .../SDSL/BufferToTextureColumnsEffect.sdsl | 28 - .../Stride/SDSL/BufferToTextureEffect.sdsl | 28 - sources/shaders/assets/Stride/SDSL/C.sdsl | 5 - sources/shaders/assets/Stride/SDSL/C1.sdsl | 5 - .../shaders/assets/Stride/SDSL/Camera.sdsl | 19 - .../assets/Stride/SDSL/CameraCube.sdsl | 33 - .../SDSL/CameraOrientationGizmoShader.sdsl | 11 - sources/shaders/assets/Stride/SDSL/Child.sdsl | 15 - .../assets/Stride/SDSL/ChildError.sdsl | 9 - .../assets/Stride/SDSL/CircleOfConfusion.sdsl | 35 - .../assets/Stride/SDSL/ClearBuffer.sdsl | 14 - .../assets/Stride/SDSL/CloneTestBase.sdsl | 6 - .../assets/Stride/SDSL/CloneTestExtern.sdsl | 9 - .../assets/Stride/SDSL/CloneTestRoot.sdsl | 12 - .../Stride/SDSL/CoCLinearDepthShader.sdsl | 29 - .../assets/Stride/SDSL/CoCMapBlurShader.sdsl | 70 - .../shaders/assets/Stride/SDSL/ColorBase.sdsl | 10 - .../Stride/SDSL/ColorCombinerShader.sdsl | 43 - .../SDSL/ColorTransformGroupShader.sdsl | 20 - .../Stride/SDSL/ColorTransformShader.sdsl | 16 - .../assets/Stride/SDSL/ColorUtility.sdsl | 82 - .../Stride/SDSL/CombineFrontCoCShader.sdsl | 68 - .../SDSL/CombineLevelsFromCoCShader.sdsl | 123 - .../Stride/SDSL/CompilationErrorShader.sdsl | 15 - .../assets/Stride/SDSL/ComputeColor.sdsl | 12 - .../assets/Stride/SDSL/ComputeColor3.sdsl | 12 - .../assets/Stride/SDSL/ComputeColorAdd.sdsl | 15 - .../assets/Stride/SDSL/ComputeColorAdd3.sdsl | 15 - .../Stride/SDSL/ComputeColorAdd3ds.sdsl | 27 - .../Stride/SDSL/ComputeColorAddMaya.sdsl | 25 - .../Stride/SDSL/ComputeColorAverage.sdsl | 27 - .../assets/Stride/SDSL/ComputeColorCave.sdsl | 20 - .../assets/Stride/SDSL/ComputeColorColor.sdsl | 35 - .../Stride/SDSL/ComputeColorColorBurn.sdsl | 17 - .../Stride/SDSL/ComputeColorColorDodge.sdsl | 30 - .../SDSL/ComputeColorConstantColorLink.sdsl | 22 - .../SDSL/ComputeColorConstantFloatLink.sdsl | 21 - .../Stride/SDSL/ComputeColorConstantLink.sdsl | 18 - .../Stride/SDSL/ComputeColorDarken3ds.sdsl | 24 - .../Stride/SDSL/ComputeColorDarkenMaya.sdsl | 27 - .../Stride/SDSL/ComputeColorDesaturate.sdsl | 24 - .../SDSL/ComputeColorDifference3ds.sdsl | 27 - .../SDSL/ComputeColorDifferenceMaya.sdsl | 26 - .../Stride/SDSL/ComputeColorDivide.sdsl | 31 - .../Stride/SDSL/ComputeColorExclusion.sdsl | 27 - .../assets/Stride/SDSL/ComputeColorFixed.sdsl | 15 - .../Stride/SDSL/ComputeColorFromStream.sdsl | 13 - .../Stride/SDSL/ComputeColorHardLight.sdsl | 30 - .../Stride/SDSL/ComputeColorHardMix.sdsl | 28 - .../assets/Stride/SDSL/ComputeColorHue.sdsl | 35 - .../Stride/SDSL/ComputeColorIlluminate.sdsl | 24 - .../assets/Stride/SDSL/ComputeColorIn.sdsl | 23 - .../Stride/SDSL/ComputeColorLerpAlpha.sdsl | 17 - .../Stride/SDSL/ComputeColorLighten3ds.sdsl | 24 - .../Stride/SDSL/ComputeColorLightenMaya.sdsl | 26 - .../Stride/SDSL/ComputeColorLinearBurn.sdsl | 32 - .../Stride/SDSL/ComputeColorLinearDodge.sdsl | 27 - .../assets/Stride/SDSL/ComputeColorMask.sdsl | 23 - .../Stride/SDSL/ComputeColorMask3ds.sdsl | 23 - .../SDSL/ComputeColorMaterialAlphaBlend.sdsl | 15 - .../Stride/SDSL/ComputeColorMultiply.sdsl | 17 - .../Stride/SDSL/ComputeColorMultiply3ds.sdsl | 27 - .../Stride/SDSL/ComputeColorMultiplyMaya.sdsl | 24 - .../assets/Stride/SDSL/ComputeColorOne.sdsl | 12 - .../assets/Stride/SDSL/ComputeColorOut.sdsl | 23 - .../Stride/SDSL/ComputeColorOutdoor.sdsl | 21 - .../Stride/SDSL/ComputeColorOver3ds.sdsl | 25 - .../Stride/SDSL/ComputeColorOverMaya.sdsl | 25 - .../Stride/SDSL/ComputeColorOverlay.sdsl | 20 - .../Stride/SDSL/ComputeColorOverlay3ds.sdsl | 30 - .../Stride/SDSL/ComputeColorParameter.sdsl | 15 - .../Stride/SDSL/ComputeColorPinLight.sdsl | 30 - .../Stride/SDSL/ComputeColorRadial.sdsl | 24 - .../assets/Stride/SDSL/ComputeColorRed.sdsl | 13 - .../Stride/SDSL/ComputeColorSaturate.sdsl | 24 - .../Stride/SDSL/ComputeColorSaturation.sdsl | 34 - .../Stride/SDSL/ComputeColorScaler.sdsl | 12 - .../Stride/SDSL/ComputeColorScreen.sdsl | 23 - .../Stride/SDSL/ComputeColorSoftLight.sdsl | 37 - .../Stride/SDSL/ComputeColorStream.sdsl | 11 - .../SDSL/ComputeColorSubstituteAlpha.sdsl | 15 - .../ComputeColorSubstituteAlphaWithColor.sdsl | 15 - .../Stride/SDSL/ComputeColorSubtract.sdsl | 15 - .../Stride/SDSL/ComputeColorSubtract3ds.sdsl | 27 - .../Stride/SDSL/ComputeColorSubtractMaya.sdsl | 24 - .../Stride/SDSL/ComputeColorSynthetic.sdsl | 9 - .../Stride/SDSL/ComputeColorTexture.sdsl | 18 - ...omputeColorTextureDynamicScaledOffset.sdsl | 24 - .../SDSL/ComputeColorTextureLodSampler.sdsl | 24 - ...rTextureLodScaledOffsetDynamicSampler.sdsl | 36 - ...uteColorTextureLodScaledOffsetSampler.sdsl | 27 - .../ComputeColorTextureLodScaledSampler.sdsl | 26 - .../SDSL/ComputeColorTextureRepeat.sdsl | 19 - .../SDSL/ComputeColorTextureSampler.sdsl | 23 - .../SDSL/ComputeColorTextureScaled.sdsl | 18 - .../SDSL/ComputeColorTextureScaledOffset.sdsl | 19 - ...olorTextureScaledOffsetDynamicSampler.sdsl | 35 - ...ureScaledOffsetDynamicSamplerRandomUV.sdsl | 89 - ...omputeColorTextureScaledOffsetSampler.sdsl | 26 - .../ComputeColorTextureScaledSampler.sdsl | 25 - .../SDSL/ComputeColorTextureScroll.sdsl | 23 - .../Stride/SDSL/ComputeColorThreshold.sdsl | 20 - .../assets/Stride/SDSL/ComputeColorValue.sdsl | 32 - .../assets/Stride/SDSL/ComputeColorWave.sdsl | 11 - .../Stride/SDSL/ComputeColorWaveNormal.sdsl | 26 - .../assets/Stride/SDSL/ComputeColorWhite.sdsl | 19 - .../assets/Stride/SDSL/ComputeShaderBase.sdsl | 69 - .../assets/Stride/SDSL/ComputeShaderTest.sdsl | 31 - .../SDSL/ComputeSphericalHarmonics.sdsl | 24 - .../Stride/SDSL/ConstantBufferTest.sdsl | 22 - .../assets/Stride/SDSL/CubemapSprite.sdsl | 13 - .../assets/Stride/SDSL/CubemapUtils.sdsl | 97 - .../assets/Stride/SDSL/CustomFogEffect.sdsl | 40 - .../assets/Stride/SDSL/CustomShader.sdsl | 22 - .../assets/Stride/SDSL/CyclicTest.sdsl | 6 - .../assets/Stride/SDSL/DataPacking.sdsl | 98 - .../assets/Stride/SDSL/DeepExtern.sdsl | 6 - .../assets/Stride/SDSL/DeepExternTest.sdsl | 12 - .../SDSL/DepthAwareDirectionalBlurShader.sdsl | 20 - .../SDSL/DepthAwareDirectionalBlurUtil.sdsl | 96 - .../shaders/assets/Stride/SDSL/DepthBase.sdsl | 39 - .../assets/Stride/SDSL/DepthMinMaxShader.sdsl | 69 - .../assets/Stride/SDSL/DirectLightGroup.sdsl | 70 - .../Stride/SDSL/DirectLightGroupArray.sdsl | 12 - .../Stride/SDSL/DirectLightGroupFixed.sdsl | 18 - .../Stride/SDSL/DirectLightGroupPerDraw.sdsl | 23 - .../Stride/SDSL/DirectLightGroupPerView.sdsl | 23 - .../shaders/assets/Stride/SDSL/Dither.sdsl | 37 - .../assets/Stride/SDSL/DynamicSampler.sdsl | 16 - .../assets/Stride/SDSL/DynamicTexture.sdsl | 16 - .../Stride/SDSL/DynamicTextureCube.sdsl | 16 - .../Stride/SDSL/DynamicTextureStream.sdsl | 12 - .../shaders/assets/Stride/SDSL/Effect.sdsl | 38 - .../assets/Stride/SDSL/EffectCompiling.sdsl | 15 - .../assets/Stride/SDSL/EnvironmentLight.sdsl | 16 - .../Stride/SDSL/EnvironmentLightArray.sdsl | 12 - .../assets/Stride/SDSL/ExternClone.sdsl | 8 - .../assets/Stride/SDSL/ExternCloneTest.sdsl | 15 - .../assets/Stride/SDSL/ExternMixin.sdsl | 11 - .../assets/Stride/SDSL/ExternTest.sdsl | 14 - .../assets/Stride/SDSL/FXAAShader.sdsl | 2067 ----------------- .../assets/Stride/SDSL/FilmGrainShader.sdsl | 123 - .../Stride/SDSL/FlareArtifactShader.sdsl | 72 - .../assets/Stride/SDSL/FlareReplicate.sdsl | 66 - .../assets/Stride/SDSL/FlattenLayers.sdsl | 21 - .../shaders/assets/Stride/SDSL/FogEffect.sdsl | 38 - .../assets/Stride/SDSL/ForEachTest.sdsl | 16 - .../shaders/assets/Stride/SDSL/GBuffer.sdsl | 17 - .../Stride/SDSL/GBufferOutputNormals.sdsl | 16 - .../GBufferOutputSpecularColorRoughness.sdsl | 16 - ...tputSubsurfaceScatteringMaterialIndex.sdsl | 20 - .../Stride/SDSL/GaussianBlurShader.sdsl | 32 - .../assets/Stride/SDSL/GenericCall.sdsl | 5 - .../assets/Stride/SDSL/GenericClass.sdsl | 25 - .../assets/Stride/SDSL/GenericClass2.sdsl | 23 - .../assets/Stride/SDSL/GenericExtern.sdsl | 6 - .../assets/Stride/SDSL/GenericTexcoord.sdsl | 6 - .../Stride/SDSL/GeometryShaderTest.sdsl | 8 - .../shaders/assets/Stride/SDSL/Global.sdsl | 9 - .../shaders/assets/Stride/SDSL/GlobalVR.sdsl | 9 - .../shaders/assets/Stride/SDSL/HSVUtils.sdsl | 103 - .../assets/Stride/SDSL/Hammersley.sdsl | 26 - .../assets/Stride/SDSL/HammersleyTest.sdsl | 20 - .../assets/Stride/SDSL/HighlightShader.sdsl | 19 - .../Stride/SDSL/IComputeEnvironmentColor.sdsl | 16 - .../IMaterialCelShadingLightFunction.sdsl | 12 - .../SDSL/IMaterialHairDirectionFunction.sdsl | 10 - .../SDSL/IMaterialHairDiscardFunction.sdsl | 14 - ...IMaterialHairLightAttenuationFunction.sdsl | 10 - .../SDSL/IMaterialHairShadowingFunction.sdsl | 10 - ...SpecularMicrofacetEnvironmentFunction.sdsl | 15 - ...rialSpecularMicrofacetFresnelFunction.sdsl | 16 - ...rMicrofacetNormalDistributionFunction.sdsl | 15 - ...lSpecularMicrofacetVisibilityFunction.sdsl | 15 - .../Stride/SDSL/IMaterialStreamBlend.sdsl | 14 - ...SubsurfaceScatteringScatteringProfile.sdsl | 14 - .../assets/Stride/SDSL/IMaterialSurface.sdsl | 14 - .../Stride/SDSL/IMaterialSurfaceDomain.sdsl | 11 - .../Stride/SDSL/IMaterialSurfacePixel.sdsl | 11 - .../Stride/SDSL/IMaterialSurfaceShading.sdsl | 28 - .../Stride/SDSL/IMaterialSurfaceVertex.sdsl | 11 - .../Stride/SDSL/IStreamInitializer.sdsl | 14 - .../assets/Stride/SDSL/IVoxelSampler.sdsl | 36 - .../assets/Stride/SDSL/ImageEffectShader.sdsl | 12 - .../assets/Stride/SDSL/ImageScalerShader.sdsl | 27 - .../Stride/SDSL/ImportanceSamplingGGX.sdsl | 31 - .../assets/Stride/SDSL/InterfaceTest.sdsl | 9 - .../Stride/SDSL/InternalReferenceMixin.sdsl | 11 - ...ambertianPrefilteringSHNoComputePass1.sdsl | 77 - ...ambertianPrefilteringSHNoComputePass2.sdsl | 23 - .../SDSL/LambertianPrefilteringSHPass1.sdsl | 125 - .../SDSL/LambertianPrefilteringSHPass2.sdsl | 47 - .../SDSL/LevelCubeMapEnvironmentColor.sdsl | 19 - .../assets/Stride/SDSL/LightClustered.sdsl | 34 - .../Stride/SDSL/LightClusteredPointGroup.sdsl | 52 - .../Stride/SDSL/LightClusteredSpotGroup.sdsl | 54 - .../Stride/SDSL/LightConstantWhite.sdsl | 18 - .../assets/Stride/SDSL/LightDirectional.sdsl | 17 - .../Stride/SDSL/LightDirectionalGroup.sdsl | 30 - .../assets/Stride/SDSL/LightPoint.sdsl | 47 - .../assets/Stride/SDSL/LightPointGroup.sdsl | 45 - .../assets/Stride/SDSL/LightProbeShader.sdsl | 99 - .../assets/Stride/SDSL/LightShaftsShader.sdsl | 35 - .../Stride/SDSL/LightSimpleAmbient.sdsl | 25 - .../assets/Stride/SDSL/LightSkyboxShader.sdsl | 49 - .../shaders/assets/Stride/SDSL/LightSpot.sdsl | 37 - .../SDSL/LightSpotAttenuationDefault.sdsl | 40 - .../SDSL/LightSpotAttenuationRectangular.sdsl | 40 - .../assets/Stride/SDSL/LightSpotGroup.sdsl | 54 - .../assets/Stride/SDSL/LightStreakShader.sdsl | 62 - .../assets/Stride/SDSL/LightStream.sdsl | 38 - .../assets/Stride/SDSL/LightTiling.sdsl | 71 - .../shaders/assets/Stride/SDSL/LightUtil.sdsl | 39 - .../assets/Stride/SDSL/LightVoxelEffect.sdsl | 34 - .../assets/Stride/SDSL/LightVoxelShader.sdsl | 45 - .../assets/Stride/SDSL/LocalSamples.sdsl | 6 - .../Stride/SDSL/LuminanceLogShader.sdsl | 26 - .../Stride/SDSL/LuminanceToChannelShader.sdsl | 18 - .../assets/Stride/SDSL/LuminanceUtils.sdsl | 23 - .../Stride/SDSL/MSAADepthResolverShader.sdsl | 63 - .../Stride/SDSL/MSAAResolverShader.sdsl | 224 -- .../shaders/assets/Stride/SDSL/MacroTest.sdsl | 9 - .../assets/Stride/SDSL/MacroTestBase.sdsl | 9 - .../assets/Stride/SDSL/MacroTestChild.sdsl | 6 - .../assets/Stride/SDSL/MarchAttributes.sdsl | 6 - .../Stride/SDSL/MarchAttributesEffect.sdsl | 18 - .../SDSL/MaterialCelShadingLightDefault.sdsl | 30 - .../SDSL/MaterialCelShadingLightRamp.sdsl | 20 - .../SDSL/MaterialDisplacementStream.sdsl | 19 - .../Stride/SDSL/MaterialDomainStream.sdsl | 12 - .../SDSL/MaterialFrontBackBlendShader.sdsl | 33 - ...aterialHairDirectionFunctionBitangent.sdsl | 18 - .../MaterialHairDirectionFunctionTangent.sdsl | 15 - ...MaterialHairDiscardFunctionOpaquePass.sdsl | 25 - ...ialHairDiscardFunctionTransparentPass.sdsl | 25 - ...irLightAttenuationFunctionDirectional.sdsl | 48 - ...erialHairLightAttenuationFunctionNone.sdsl | 13 - ...terialHairShadowingFunctionScattering.sdsl | 46 - ...aterialHairShadowingFunctionShadowing.sdsl | 13 - .../Stride/SDSL/MaterialHairShared.sdsl | 36 - .../SDSL/MaterialPixelShadingStream.sdsl | 43 - .../Stride/SDSL/MaterialPixelStream.sdsl | 116 - ...alSpecularMicrofacetEnvironmentGGXLUT.sdsl | 27 - ...larMicrofacetEnvironmentGGXPolynomial.sdsl | 15 - ...pecularMicrofacetEnvironmentThinGlass.sdsl | 15 - ...MaterialSpecularMicrofacetFresnelNone.sdsl | 15 - ...erialSpecularMicrofacetFresnelSchlick.sdsl | 15 - ...ialSpecularMicrofacetFresnelThinGlass.sdsl | 15 - ...rMicrofacetNormalDistributionBeckmann.sdsl | 15 - ...icrofacetNormalDistributionBlinnPhong.sdsl | 15 - ...ecularMicrofacetNormalDistributionGGX.sdsl | 15 - ...cularMicrofacetVisibilityCookTorrance.sdsl | 15 - ...lSpecularMicrofacetVisibilityImplicit.sdsl | 15 - ...alSpecularMicrofacetVisibilityKelemen.sdsl | 15 - ...alSpecularMicrofacetVisibilityNeumann.sdsl | 15 - ...ularMicrofacetVisibilitySmithBeckmann.sdsl | 15 - ...icrofacetVisibilitySmithGGXCorrelated.sdsl | 15 - ...rofacetVisibilitySmithSchlickBeckmann.sdsl | 15 - ...arMicrofacetVisibilitySmithSchlickGGX.sdsl | 15 - .../assets/Stride/SDSL/MaterialStream.sdsl | 22 - .../SDSL/MaterialStreamAdditiveBlend.sdsl | 16 - .../SDSL/MaterialStreamLinearBlend.sdsl | 15 - .../SDSL/MaterialStreamNormalBlend.sdsl | 24 - ...tteringScatteringProfileCustomUniform.sdsl | 27 - ...tteringScatteringProfileCustomVarying.sdsl | 51 - ...urfaceScatteringScatteringProfileSkin.sdsl | 19 - .../Stride/SDSL/MaterialSurfaceArray.sdsl | 17 - .../Stride/SDSL/MaterialSurfaceDiffuse.sdsl | 22 - .../MaterialSurfaceDiffuseMetalFlakes.sdsl | 31 - ...SurfaceDiffuseSpecularAlphaBlendColor.sdsl | 15 - .../SDSL/MaterialSurfaceDisplacement.sdsl | 22 - .../MaterialSurfaceDomainStageCompositor.sdsl | 22 - .../SDSL/MaterialSurfaceEmissiveShading.sdsl | 19 - .../SDSL/MaterialSurfaceGlossinessMap.sdsl | 23 - ...terialSurfaceGlossinessMapMetalFlakes.sdsl | 34 - .../MaterialSurfaceLightingAndShading.sdsl | 98 - .../Stride/SDSL/MaterialSurfaceMetalness.sdsl | 24 - .../Stride/SDSL/MaterialSurfaceNormalMap.sdsl | 33 - .../MaterialSurfaceNormalStreamShading.sdsl | 15 - .../MaterialSurfacePixelStageCompositor.sdsl | 28 - ...erialSurfaceSetStreamFromComputeColor.sdsl | 14 - .../SDSL/MaterialSurfaceShadingBlend.sdsl | 16 - ...terialSurfaceShadingDiffuseCelShading.sdsl | 51 - .../MaterialSurfaceShadingDiffuseHair.sdsl | 129 - .../MaterialSurfaceShadingDiffuseLambert.sdsl | 33 - ...erialSurfaceShadingSpecularBlinnPhong.sdsl | 21 - ...erialSurfaceShadingSpecularCelShading.sdsl | 42 - .../MaterialSurfaceShadingSpecularHair.sdsl | 374 --- ...erialSurfaceShadingSpecularMicrofacet.sdsl | 40 - .../SDSL/MaterialSurfaceStreamShading.sdsl | 18 - .../SDSL/MaterialSurfaceStreamsBlend.sdsl | 25 - ...ialSurfaceSubsurfaceScatteringShading.sdsl | 74 - .../MaterialSurfaceTransmittanceShading.sdsl | 18 - ...aterialSurfaceTransparentAlphaDiscard.sdsl | 16 - .../MaterialSurfaceVertexDisplacement.sdsl | 23 - .../MaterialSurfaceVertexStageCompositor.sdsl | 23 - .../SDSL/MaterialTessellationStream.sdsl | 22 - ...aterialTransmittanceReflectanceStream.sdsl | 67 - .../Stride/SDSL/MaterialVertexStream.sdsl | 12 - sources/shaders/assets/Stride/SDSL/Math.sdsl | 123 - .../Stride/SDSL/McIntoshCombineShader.sdsl | 22 - .../Stride/SDSL/McIntoshOptimizedShader.sdsl | 31 - .../assets/Stride/SDSL/MeshVelocity.sdsl | 37 - .../SDSL/MixinFunctionParamaterTest.sdsl | 8 - .../assets/Stride/SDSL/MixinNameClash.sdsl | 9 - .../assets/Stride/SDSL/MixinNoNameClash.sdsl | 9 - .../SDSL/ModelComponentPickingShader.sdsl | 26 - .../SDSL/MultiTexturesSpriteShader.sdsl | 9 - .../MultipleRenderTargetsEffectShader.sdsl | 16 - .../Stride/SDSL/NonStageStreamTest.sdsl | 12 - .../assets/Stride/SDSL/NormalBase.sdsl | 24 - .../assets/Stride/SDSL/NormalFromMesh.sdsl | 27 - .../Stride/SDSL/NormalFromMeshInstanced.sdsl | 14 - .../Stride/SDSL/NormalFromNormalMapping.sdsl | 20 - .../NormalFromNormalMappingInstanced.sdsl | 20 - .../NormalFromNormalMappingTessellation.sdsl | 14 - ...romNormalMappingTessellationInstanced.sdsl | 14 - .../Stride/SDSL/NormalMeshSkinning.sdsl | 13 - .../assets/Stride/SDSL/NormalPack.sdsl | 23 - .../assets/Stride/SDSL/NormalStream.sdsl | 22 - .../assets/Stride/SDSL/NormalUpdate.sdsl | 46 - .../assets/Stride/SDSL/NormalUtil.sdsl | 48 - .../Stride/SDSL/NormalVSSkinningFromMesh.sdsl | 13 - .../SDSL/NormalVSSkinningNormalMapping.sdsl | 13 - ...alVSSkinningNormalMappingTessellation.sdsl | 13 - .../assets/Stride/SDSL/OpaqueBase.sdsl | 21 - .../assets/Stride/SDSL/OutlineEffect.sdsl | 72 - .../shaders/assets/Stride/SDSL/Parent.sdsl | 14 - .../assets/Stride/SDSL/ParticleBase.sdsl | 132 -- .../assets/Stride/SDSL/ParticleColor.sdsl | 20 - .../Stride/SDSL/ParticleColorStream.sdsl | 25 - .../SDSL/ParticleComputeColorShader.sdsl | 26 - .../Stride/SDSL/ParticleCustomShader.sdsl | 37 - .../assets/Stride/SDSL/ParticleUtilities.sdsl | 59 - .../assets/Stride/SDSL/PickingShader.sdsl | 23 - .../assets/Stride/SDSL/PointDepth.sdsl | 18 - .../assets/Stride/SDSL/PositionHStream4.sdsl | 9 - .../assets/Stride/SDSL/PositionStream.sdsl | 17 - .../assets/Stride/SDSL/PositionStream2.sdsl | 19 - .../assets/Stride/SDSL/PositionStream4.sdsl | 16 - .../Stride/SDSL/PositionVertexTransform.sdsl | 13 - .../Stride/SDSL/PostEffectBoundingRay.sdsl | 98 - ...adiancePrefilteringGGXNoComputeShader.sdsl | 61 - .../SDSL/RadiancePrefilteringGGXShader.sdsl | 80 - .../Stride/SDSL/RangeCompressorShader.sdsl | 31 - .../Stride/SDSL/RangeDecompressorShader.sdsl | 24 - .../RoughnessCubeMapEnvironmentColor.sdsl | 29 - .../assets/Stride/SDSL/SSLRBlurPass.sdsl | 87 - .../assets/Stride/SDSL/SSLRCombinePass.sdsl | 75 - .../assets/Stride/SDSL/SSLRCommon.sdsl | 103 - .../assets/Stride/SDSL/SSLRDepthPass.sdsl | 17 - .../assets/Stride/SDSL/SSLRRayTracePass.sdsl | 191 -- .../assets/Stride/SDSL/SSLRResolvePass.sdsl | 108 - .../assets/Stride/SDSL/SSLRTemporalPass.sdsl | 87 - .../Stride/SDSL/ScreenPositionBase.sdsl | 23 - .../Stride/SDSL/SelectedSpriteShader.sdsl | 17 - .../assets/Stride/SDSL/SemanticTest.sdsl | 15 - .../assets/Stride/SDSL/ShaderBase.sdsl | 11 - .../assets/Stride/SDSL/ShaderBaseStream.sdsl | 35 - .../assets/Stride/SDSL/ShadingBase.sdsl | 73 - .../assets/Stride/SDSL/ShadingColor.sdsl | 15 - .../assets/Stride/SDSL/ShadowGroup.sdsl | 17 - .../SDSL/ShadowMapCasterAlphaDiscard.sdsl | 17 - .../SDSL/ShadowMapCasterAlphaDithered.sdsl | 39 - .../ShadowMapCasterCubeMapProjection.sdsl | 18 - .../SDSL/ShadowMapCasterNoPixelShader.sdsl | 15 - .../ShadowMapCasterParaboloidProjection.sdsl | 60 - .../Stride/SDSL/ShadowMapCasterVsm.sdsl | 24 - .../assets/Stride/SDSL/ShadowMapCommon.sdsl | 26 - .../Stride/SDSL/ShadowMapFilterBase.sdsl | 126 - .../Stride/SDSL/ShadowMapFilterDefault.sdsl | 45 - .../Stride/SDSL/ShadowMapFilterPcf.sdsl | 285 --- .../Stride/SDSL/ShadowMapFilterVsm.sdsl | 30 - .../assets/Stride/SDSL/ShadowMapGroup.sdsl | 11 - .../Stride/SDSL/ShadowMapReceiverBase.sdsl | 62 - .../SDSL/ShadowMapReceiverDirectional.sdsl | 118 - .../SDSL/ShadowMapReceiverPointCubeMap.sdsl | 113 - .../ShadowMapReceiverPointParaboloid.sdsl | 67 - .../Stride/SDSL/ShadowMapReceiverSpot.sdsl | 50 - .../assets/Stride/SDSL/ShadowStream.sdsl | 11 - .../Stride/SDSL/SharedTextureCoordinate.sdsl | 26 - .../Stride/SDSL/SignedDistanceFieldFont.sdsl | 48 - .../SDSL/SignedDistanceFieldFontShader.sdsl | 39 - .../shaders/assets/Stride/SDSL/Simple.sdsl | 6 - .../assets/Stride/SDSL/SimpleShader.sdsl | 20 - .../assets/Stride/SDSL/SkyboxShaderBase.sdsl | 23 - .../Stride/SDSL/SkyboxShaderCubemap.sdsl | 17 - .../Stride/SDSL/SkyboxShaderTexture.sdsl | 25 - .../assets/Stride/SDSL/SkyboxStream.sdsl | 10 - .../Stride/SDSL/SphericalHarmonicsBase.sdsl | 78 - .../SphericalHarmonicsEnvironmentColor.sdsl | 28 - .../SDSL/SphericalHarmonicsRenderer.sdsl | 36 - .../Stride/SDSL/SphericalHarmonicsUtils.sdsl | 70 - .../SDSL/SpotLightDataInternalShader.sdsl | 19 - .../assets/Stride/SDSL/Sprite3DBase.sdsl | 12 - .../assets/Stride/SDSL/SpriteAlphaCutoff.sdsl | 71 - .../assets/Stride/SDSL/SpriteBase.sdsl | 37 - .../assets/Stride/SDSL/SpriteBatchShader.sdsl | 55 - .../assets/Stride/SDSL/SpriteEffect.sdsl | 14 - .../Stride/SDSL/SpriteEffectExtTexture.sdsl | 102 - .../SDSL/SpriteEffectExtTextureRegular.sdsl | 27 - .../assets/Stride/SDSL/SpritePicking.sdsl | 18 - .../SpriteSignedDistanceFieldFontShader.sdsl | 12 - .../Stride/SDSL/SpriteSuperSampler.sdsl | 40 - .../shaders/assets/Stride/SDSL/StageBase.sdsl | 7 - .../assets/Stride/SDSL/StageCallExtern.sdsl | 10 - .../shaders/assets/Stride/SDSL/StageDecl.sdsl | 6 - .../Stride/SDSL/StageValueReference.sdsl | 12 - .../assets/Stride/SDSL/StageValueTest.sdsl | 11 - .../assets/Stride/SDSL/StaticCallMixin.sdsl | 10 - .../assets/Stride/SDSL/StaticMixin.sdsl | 10 - .../Stride/SDSL/StaticStageCallTest.sdsl | 10 - .../assets/Stride/SDSL/StreamChild.sdsl | 9 - .../assets/Stride/SDSL/StreamError.sdsl | 16 - .../assets/Stride/SDSL/StreamParent0.sdsl | 6 - .../assets/Stride/SDSL/StreamParent1.sdsl | 6 - .../assets/Stride/SDSL/StreamParent2.sdsl | 7 - .../Stride/SDSL/StreamSolverExternTest.sdsl | 10 - .../assets/Stride/SDSL/StreamTest.sdsl | 70 - .../SDSL/StrideForwardShadingEffectVXGI.sdsl | 73 - .../Stride/SDSL/StructuredBufferTest.sdsl | 14 - .../SDSL/SubsurfaceScatteringBlurShader.sdsl | 512 ---- .../shaders/assets/Stride/SDSL/SwapUV.sdsl | 18 - .../Stride/SDSL/TangentMeshSkinning.sdsl | 13 - .../Stride/SDSL/TemporalAntiAliasShader.sdsl | 275 --- .../assets/Stride/SDSL/TessellationAE2.sdsl | 50 - .../assets/Stride/SDSL/TessellationAE3.sdsl | 50 - .../assets/Stride/SDSL/TessellationAE4.sdsl | 50 - .../assets/Stride/SDSL/TessellationBase.sdsl | 127 - .../assets/Stride/SDSL/TessellationFlat.sdsl | 49 - .../assets/Stride/SDSL/TessellationPN.sdsl | 171 -- .../assets/Stride/SDSL/TessellationTest.sdsl | 22 - .../assets/Stride/SDSL/TestComputeColor.sdsl | 9 - .../assets/Stride/SDSL/TestComputeColor2.sdsl | 12 - .../Stride/SDSL/TestComputeColorRedirect.sdsl | 11 - .../assets/Stride/SDSL/TestComputeShader.sdsl | 56 - .../assets/Stride/SDSL/TestErrors.sdsl | 50 - .../assets/Stride/SDSL/TestExternArray.sdsl | 22 - .../assets/Stride/SDSL/TestGenerator.sdsl | 12 - .../Stride/SDSL/TestGenericComplex.sdsl | 9 - .../assets/Stride/SDSL/TestGenericMacro.sdsl | 9 - .../assets/Stride/SDSL/TestGenerics.sdsl | 11 - .../assets/Stride/SDSL/TestMacros.sdsl | 15 - .../assets/Stride/SDSL/TestMacrosArray.sdsl | 13 - .../Stride/SDSL/TestMultipleStatic.sdsl | 12 - .../assets/Stride/SDSL/TestPixelStream.sdsl | 11 - .../Stride/SDSL/TestScreenPosition.sdsl | 6 - .../assets/Stride/SDSL/TestStream.sdsl | 26 - .../assets/Stride/SDSL/TestStreams.sdsl | 10 - .../Stride/SDSL/TestStructInheritance.sdsl | 11 - .../assets/Stride/SDSL/TestStructure.sdsl | 14 - .../assets/Stride/SDSL/TestVertexStream.sdsl | 12 - .../Stride/SDSL/TextureProjectionCommon.sdsl | 25 - .../SDSL/TextureProjectionFilterDefault.sdsl | 21 - .../Stride/SDSL/TextureProjectionGroup.sdsl | 23 - .../SDSL/TextureProjectionReceiverBase.sdsl | 186 -- .../SDSL/TextureProjectionReceiverSpot.sdsl | 26 - .../shaders/assets/Stride/SDSL/Texturing.sdsl | 124 - .../assets/Stride/SDSL/ThresholdAlphaCoC.sdsl | 65 - .../Stride/SDSL/ThresholdAlphaCoCFront.sdsl | 53 - .../assets/Stride/SDSL/ToGlslShader.sdsl | 20 - .../SDSL/ToneMapACESOperatorShader.sdsl | 31 - .../SDSL/ToneMapCommonOperatorShader.sdsl | 14 - .../SDSL/ToneMapDragoOperatorShader.sdsl | 22 - .../ToneMapExponentialOperatorShader.sdsl | 18 - .../SDSL/ToneMapHejl2OperatorShader.sdsl | 28 - .../SDSL/ToneMapHejlDawsonOperatorShader.sdsl | 24 - .../ToneMapLogarithmicOperatorShader.sdsl | 18 - .../SDSL/ToneMapMikeDayOperatorShader.sdsl | 30 - .../Stride/SDSL/ToneMapOperatorShader.sdsl | 12 - .../SDSL/ToneMapReinhardOperatorShader.sdsl | 19 - .../assets/Stride/SDSL/ToneMapShader.sdsl | 91 - .../SDSL/ToneMapU2FilmicOperatorShader.sdsl | 40 - .../assets/Stride/SDSL/Transformation.sdsl | 42 - .../Stride/SDSL/TransformationBase.sdsl | 36 - .../Stride/SDSL/TransformationBendWorld.sdsl | 23 - .../Stride/SDSL/TransformationInstancing.sdsl | 41 - .../Stride/SDSL/TransformationMatrix.sdsl | 17 - .../Stride/SDSL/TransformationSkinning.sdsl | 43 - .../SDSL/TransformationSkinningInstanced.sdsl | 25 - .../Stride/SDSL/TransformationTextureUV.sdsl | 22 - .../Stride/SDSL/TransformationWAndVP.sdsl | 26 - .../SDSL/TransformationWAndVPInstanced.sdsl | 12 - .../assets/Stride/SDSL/TransformationWVP.sdsl | 8 - .../Stride/SDSL/TransformationZero.sdsl | 13 - .../SDSL/TripleRhombiCombineShader.sdsl | 42 - .../assets/Stride/SDSL/UIEffectShader.sdsl | 37 - .../shaders/assets/Stride/SDSL/Utilities.sdsl | 56 - .../assets/Stride/SDSL/VelocityOutput.sdsl | 11 - .../assets/Stride/SDSL/VelocityStream.sdsl | 14 - .../assets/Stride/SDSL/VideoShader.sdsl | 6 - .../assets/Stride/SDSL/VignettingShader.sdsl | 35 - .../Stride/SDSL/VolumeMinMaxShader.sdsl | 20 - .../assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl | 34 - .../Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl | 15 - .../Stride/SDSL/Voxel2x2x2Mipmapper.sdsl | 12 - .../SDSL/Voxel2x2x2MipmapperHeuristic.sdsl | 27 - .../Voxel2x2x2MipmapperPhysicallyBased.sdsl | 23 - .../SDSL/Voxel2x2x2MipmapperSimple.sdsl | 12 - .../SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl | 16 - .../SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl | 16 - .../SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl | 16 - .../SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl | 16 - .../SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl | 16 - .../SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl | 16 - .../SDSL/VoxelAnisotropicPairedSampler.sdsl | 50 - .../VoxelAnisotropicPairedWriter_Float4.sdsl | 64 - .../Stride/SDSL/VoxelAnisotropicSampler.sdsl | 56 - .../SDSL/VoxelAnisotropicWriter_Float4.sdsl | 100 - .../assets/Stride/SDSL/VoxelAttribute.sdsl | 11 - ...elAttributeDirectionalCoverageSampler.sdsl | 43 - ...xelAttributeDirectionalCoverageShader.sdsl | 56 - .../VoxelAttributeEmissionOpacityShader.sdsl | 31 - .../SDSL/VoxelAttributeSoliditySampler.sdsl | 39 - .../SDSL/VoxelAttributeSolidityShader.sdsl | 108 - .../Stride/SDSL/VoxelBufferWriteAssign.sdsl | 15 - .../Stride/SDSL/VoxelBufferWriteMax.sdsl | 16 - .../assets/Stride/SDSL/VoxelBufferWriter.sdsl | 29 - .../Stride/SDSL/VoxelFragmentPackFloat16.sdsl | 63 - .../Stride/SDSL/VoxelFragmentPackFloat32.sdsl | 61 - .../SDSL/VoxelFragmentPackFloatR11G11B10.sdsl | 66 - .../Stride/SDSL/VoxelFragmentPacker.sdsl | 21 - .../Stride/SDSL/VoxelIsotropicSampler.sdsl | 38 - .../SDSL/VoxelIsotropicWriter_Float4.sdsl | 44 - .../Stride/SDSL/VoxelLayout_Float4.sdsl | 14 - .../assets/Stride/SDSL/VoxelMarchBeam.sdsl | 32 - .../assets/Stride/SDSL/VoxelMarchCone.sdsl | 36 - .../Stride/SDSL/VoxelMarchConeEditMode.sdsl | 47 - .../Stride/SDSL/VoxelMarchConePerMipmap.sdsl | 33 - .../assets/Stride/SDSL/VoxelMarchMethod.sdsl | 7 - .../assets/Stride/SDSL/VoxelMarchSet.sdsl | 6 - .../SDSL/VoxelMarchSetHemisphere12.sdsl | 55 - .../Stride/SDSL/VoxelMarchSetHemisphere6.sdsl | 47 - .../SDSL/VoxelMarchSetRandomHemisphere.sdsl | 46 - .../SDSL/VoxelModifierApplierAnisotropic.sdsl | 9 - ...VoxelModifierApplierAnisotropicPaired.sdsl | 9 - ...odifierApplierAntiAliasingAnisotropic.sdsl | 15 - ...rApplierAntiAliasingAnisotropicPaired.sdsl | 12 - ...lModifierApplierAntiAliasingIsotropic.sdsl | 10 - .../SDSL/VoxelModifierApplierIsotropic.sdsl | 9 - ...oxelModifierApplierOpacifyAnisotropic.sdsl | 17 - ...difierApplierOpacifyAnisotropicPaired.sdsl | 14 - .../VoxelModifierApplierOpacifyIsotropic.sdsl | 10 - ...xelModifierApplierSolidifyAnisotropic.sdsl | 15 - ...ifierApplierSolidifyAnisotropicPaired.sdsl | 12 - ...VoxelModifierApplierSolidifyIsotropic.sdsl | 10 - .../Stride/SDSL/VoxelPositionStream.sdsl | 8 - .../Stride/SDSL/VoxelRadiusMarchMethod.sdsl | 7 - .../SDSL/VoxelStorageClipmapShader.sdsl | 107 - .../Stride/SDSL/VoxelStorageShader.sdsl | 21 - .../VoxelStorageTextureClipmapShader.sdsl | 181 -- .../SDSL/VoxelStorageTextureShader.sdsl | 10 - .../SDSL/VoxelVisualizationRawEffect.sdsl | 15 - .../SDSL/VoxelVisualizationRawShader.sdsl | 30 - .../SDSL/VoxelVisualizationViewEffect.sdsl | 23 - .../SDSL/VoxelVisualizationViewShader.sdsl | 30 - .../Stride/SDSL/VoxelizationMethod.sdsl | 19 - .../SDSL/VoxelizationMethodDominantAxis.sdsl | 48 - .../SDSL/VoxelizationMethodSingleAxis.sdsl | 20 - .../Stride/SDSL/VoxelizeToFragments.sdsl | 35 - .../SDSL/VoxelizeToFragmentsEffect.sdsl | 24 - sources/targets/Stride.UnitTests.targets | 2 - 658 files changed, 250 insertions(+), 23208 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs create mode 100644 sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs delete mode 100644 sources/shaders/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/CoCMapBlurEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ColorCombinerEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ComputeEffectShader.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/CubemapEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/CustomEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/DepthMinMaxEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/FXAAShaderEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/FlareArtifactEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/GaussianBlurEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ImageScalerEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/LightShaftsEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/LightSkyboxEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/LightStreakEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/MSAAResolverEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ParticleBaseEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ParticleCustomEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ParticleEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/Picking.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/PreviewTexture.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SceneEditorParameters.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SelectedSprite.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ShadowMapCaster.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SimpleEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SpriteBatch.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideEffectBase.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ToGlslEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/ToneMapEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/UIEffect.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_complex_params.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_compose_keys.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple_child.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple_clone.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple_compose.sdfx delete mode 100644 sources/shaders/assets/Stride/SDFX/test_mixin_simple_params.sdfx delete mode 100644 sources/shaders/assets/Stride/SDSL/A.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/AdditiveLightEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/AdditiveLightShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/B.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BRDFMicrofacet.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BackgroundCubemapShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BackgroundShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BackgroundVelocity.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BakeLightProbeShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BaseTestChild.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BaseTestInter.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BaseTestParent.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BasicMixin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BasicMixin2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BlendUtils.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BloomAfterimageShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BrightFilterShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BufferToTexture.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BufferToTextureColumns.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/BufferToTextureEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/C.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/C1.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Camera.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CameraCube.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Child.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ChildError.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CircleOfConfusion.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ClearBuffer.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CloneTestBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CloneTestExtern.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CloneTestRoot.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CoCLinearDepthShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CoCMapBlurShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ColorBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ColorCombinerShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ColorTransformGroupShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ColorTransformShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ColorUtility.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CombineFrontCoCShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CompilationErrorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColor3.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorAdd.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorAdd3.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorAddMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorAverage.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorCave.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorColorBurn.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorColorDodge.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorConstantLink.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDesaturate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorDivide.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorExclusion.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorFixed.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorFromStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorHardLight.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorHardMix.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorHue.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorIlluminate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorIn.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMask.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMask3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMultiply.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOne.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOut.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOutdoor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOver3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOverMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOverlay.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorParameter.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorPinLight.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorRadial.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorRed.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSaturate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSaturation.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorScaler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorScreen.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSoftLight.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSubtract.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorSynthetic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTexture.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorThreshold.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorValue.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorWave.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeColorWhite.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeShaderBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeShaderTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ComputeSphericalHarmonics.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ConstantBufferTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CubemapSprite.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CubemapUtils.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CustomFogEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CustomShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/CyclicTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DataPacking.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DeepExtern.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DeepExternTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DepthBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DepthMinMaxShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DirectLightGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DirectLightGroupArray.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DirectLightGroupFixed.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DirectLightGroupPerView.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Dither.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DynamicSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DynamicTexture.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DynamicTextureCube.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/DynamicTextureStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Effect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/EffectCompiling.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/EnvironmentLight.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/EnvironmentLightArray.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ExternClone.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ExternCloneTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ExternMixin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ExternTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FXAAShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FilmGrainShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FlareArtifactShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FlareReplicate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FlattenLayers.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/FogEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ForEachTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GBuffer.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GBufferOutputNormals.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GaussianBlurShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GenericCall.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GenericClass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GenericClass2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GenericExtern.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GenericTexcoord.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GeometryShaderTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Global.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/GlobalVR.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/HSVUtils.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Hammersley.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/HammersleyTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/HighlightShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialStreamBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSurface.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IStreamInitializer.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/IVoxelSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ImageEffectShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ImageScalerShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/InterfaceTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/InternalReferenceMixin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHPass2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightClustered.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightClusteredPointGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightConstantWhite.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightDirectional.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightDirectionalGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightPoint.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightPointGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightProbeShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightShaftsShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSimpleAmbient.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSkyboxShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSpot.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightSpotGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightStreakShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightTiling.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightUtil.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightVoxelEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LightVoxelShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LocalSamples.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LuminanceLogShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LuminanceToChannelShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/LuminanceUtils.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MSAADepthResolverShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MSAAResolverShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MacroTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MacroTestBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MacroTestChild.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MarchAttributes.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MarchAttributesEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialDisplacementStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialDomainStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialHairShared.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialPixelStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceArray.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialTessellationStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MaterialVertexStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Math.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/McIntoshCombineShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MeshVelocity.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MixinNameClash.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MixinNoNameClash.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ModelComponentPickingShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NonStageStreamTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromMesh.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromNormalMapping.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalMeshSkinning.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalPack.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalUpdate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalUtil.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/OpaqueBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/OutlineEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Parent.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleColorStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleComputeColorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleCustomShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ParticleUtilities.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PickingShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PointDepth.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PositionHStream4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PositionStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PositionStream2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PositionStream4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PositionVertexTransform.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/PostEffectBoundingRay.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/RangeCompressorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/RangeDecompressorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRBlurPass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRCombinePass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRCommon.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRDepthPass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRRayTracePass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRResolvePass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SSLRTemporalPass.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ScreenPositionBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SelectedSpriteShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SemanticTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShaderBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShaderBaseStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadingBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadingColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapCommon.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapFilterBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ShadowStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SharedTextureCoordinate.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Simple.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SimpleShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SkyboxShaderBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SkyboxShaderTexture.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SkyboxStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SphericalHarmonicsUtils.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Sprite3DBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteBatchShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpritePicking.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SpriteSuperSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StageBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StageCallExtern.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StageDecl.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StageValueReference.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StageValueTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StaticCallMixin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StaticMixin.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StaticStageCallTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamChild.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamError.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamParent0.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamParent1.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamParent2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamSolverExternTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StreamTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/StructuredBufferTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/SwapUV.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TangentMeshSkinning.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationAE2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationAE3.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationAE4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationFlat.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationPN.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TessellationTest.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestComputeColor.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestComputeColor2.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestComputeColorRedirect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestComputeShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestErrors.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestExternArray.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestGenerator.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestGenericComplex.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestGenericMacro.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestGenerics.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestMacros.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestMacrosArray.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestMultipleStatic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestPixelStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestScreenPosition.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestStreams.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestStructInheritance.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestStructure.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TestVertexStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TextureProjectionCommon.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TextureProjectionGroup.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Texturing.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToGlslShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Transformation.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationBase.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationBendWorld.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationInstancing.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationMatrix.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationSkinning.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationTextureUV.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationWAndVP.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationWVP.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TransformationZero.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/UIEffectShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Utilities.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VelocityOutput.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VelocityStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VideoShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VignettingShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VolumeMinMaxShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttribute.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelBufferWriteAssign.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelBufferWriter.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelFragmentPacker.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelLayout_Float4.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchBeam.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchCone.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchMethod.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchSet.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelPositionStream.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelStorageShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelizationMethod.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelizeToFragments.sdsl delete mode 100644 sources/shaders/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 85cd47ee43..4966fdd13a 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -1,4 +1,4 @@ -using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance; using Silk.NET.Core.Native; using Silk.NET.Direct3D.Compilers; using Silk.NET.Direct3D11; @@ -14,7 +14,7 @@ using System.Runtime.InteropServices; using System.Text; -namespace Stride.Shaders.Parsing.Tests; +namespace Stride.Shaders.Parsers.Tests; @@ -722,4 +722,4 @@ private static unsafe void FillData(string value, EffectTypeDescription type, in throw new NotImplementedException(); } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs index f3864d4cf3..9363eacb84 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.cs @@ -1,6 +1,6 @@ using System.Globalization; -namespace Stride.Shaders.Parsing.Tests; +namespace Stride.Shaders.Parsers.Tests; public abstract class FrameRenderer(uint width = 800, uint height = 600, byte[]? vertexSpirv = null, byte[]? fragmentSpirv = null) { @@ -56,4 +56,4 @@ protected static unsafe uint ParseColor(string value) ((color >> 24) & 0xff)); return color; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Tests/ParsingTests.cs b/sources/shaders/Stride.Shaders.Tests/ParsingTests.cs index 125acc8332..9328fb50f8 100644 --- a/sources/shaders/Stride.Shaders.Tests/ParsingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/ParsingTests.cs @@ -1,7 +1,7 @@ using Stride.Shaders.Parsing; using Stride.Shaders.Parsing.Analysis; -namespace Stride.Shaders.Parsing.Tests; +namespace Stride.Shaders.Parsers.Tests; public class ParsingTests1 { @@ -36,4 +36,4 @@ public void ParseFile(string path) // var result = SDSLParser.Parse(text); // Assert.True(result.Errors.Count == 0, path + string.Join("\n", result.Errors.Select(x => x.ToString()))); // } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Tests/Program.cs b/sources/shaders/Stride.Shaders.Tests/Program.cs index e827753caf..74983ab095 100644 --- a/sources/shaders/Stride.Shaders.Tests/Program.cs +++ b/sources/shaders/Stride.Shaders.Tests/Program.cs @@ -1,9 +1,5 @@ -using Stride.Shaders.Parsing.Tests; +using Stride.Shaders.Parsers.Tests; [assembly: CaptureConsole] -//new RenderingTests().RenderTest1("SimpleInheritance"); - -public struct myStruct -{ -} \ No newline at end of file +//new StrideShaderTests().Tessellation(); diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index fbd5b81789..07089d552b 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -17,62 +17,16 @@ using System.Globalization; using System.IO; using System.Runtime.InteropServices; -using System.Text; using Stride.Core.Storage; using Spv = Stride.Shaders.Spirv.Tools.Spv; -namespace Stride.Shaders.Parsing.Tests; +namespace Stride.Shaders.Parsers.Tests; -public class RenderingTests +public partial class RenderingTests { static int width = 1; static int height = 1; - class TestShaderCache : ShaderCache - { - public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) - { - base.RegisterShader(name, defines, bytecode, hash); - - Console.WriteLine($"Registering shader {name}"); - Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - } - } - - class ShaderLoader(string basePath) : ShaderLoaderBase(new TestShaderCache()) - { - protected override bool ExternalFileExists(string name) - { - var filename = $"{basePath}/{name}.sdsl"; - return File.Exists(filename); - } - - public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) - { - filename = $"{basePath}/{name}.sdsl"; - - var fileData = File.ReadAllBytes(filename); - hash = ObjectId.FromBytes(fileData); - - // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file - using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); - code = reader.ReadToEnd(); - - return true; - } - - protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) - { - var result = base.LoadFromCode(filename, code, hash, macros, out buffer); - if (result) - { - Console.WriteLine($"Loading shader {filename}"); - Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); - } - return result; - } - } - [Theory] [MemberData(nameof(GetComputeTestFiles))] public void ComputeTest1(string shaderName) diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs new file mode 100644 index 0000000000..bb60495791 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -0,0 +1,53 @@ +using Stride.Shaders.Compilers; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Tools; +using System.Text; +using Stride.Core.Storage; +using Spv = Stride.Shaders.Spirv.Tools.Spv; + +namespace Stride.Shaders.Parsers.Tests; + +class ShaderLoader(string basePath) : ShaderLoaderBase(new TestShaderCache()) +{ + protected override bool ExternalFileExists(string name) + { + var filename = $"{basePath}/{name}.sdsl"; + return File.Exists(filename); + } + + public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) + { + filename = $"{basePath}/{name}.sdsl"; + + var fileData = File.ReadAllBytes(filename); + hash = ObjectId.FromBytes(fileData); + + // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file + using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); + code = reader.ReadToEnd(); + + return true; + } + + protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) + { + var result = base.LoadFromCode(filename, code, hash, macros, out buffer); + if (result) + { + Console.WriteLine($"Loading shader {filename}"); + Spv.Dis(buffer, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } + return result; + } + + class TestShaderCache : ShaderCache + { + public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) + { + base.RegisterShader(name, defines, bytecode, hash); + + Console.WriteLine($"Registering shader {name}"); + Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); + } + } +} diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index b2e467bf2f..ae48ccb3f4 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -36,7 +36,12 @@ - + + + + + + diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs new file mode 100644 index 0000000000..e5110e38ce --- /dev/null +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Stride.Shaders.Compilers.SDSL; + +namespace Stride.Shaders.Parsers.Tests; + +public class StrideShaderTests +{ + [Fact] + public void Tessellation() + { + // Dumped from TessellationTest using ShaderSource.ToCode() + var shaderSource = new ShaderMixinSource + { + Mixins = +{ +new ShaderClassSource("ShaderBase"), +new ShaderClassSource("ShadingBase"), +new ShaderClassSource("TransformationBase"), +new ShaderClassSource("NormalStream"), +new ShaderClassSource("TransformationWAndVP"), +new ShaderClassSource("NormalFromMesh"), +new ShaderClassSource("TessellationFlat"), +new ShaderClassSource("MaterialSurfacePixelStageCompositor"), +}, + Compositions = +{ +["environmentLights"] = new ShaderArraySource +{ +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("LightSimpleAmbient")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +["materialPixelStage"] = new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceArray")}, +Compositions = +{ +["layers"] = new ShaderArraySource +{ +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceDiffuse")}, +Compositions ={["diffuseMap"] = new ShaderClassSource("ComputeColorConstantColorLink","Material.DiffuseValue")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceLightingAndShading")}, +Compositions = +{ +["surfaces"] = new ShaderArraySource +{ +new ShaderClassSource("MaterialSurfaceShadingDiffuseLambert","false"), +}, +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +["streamInitializerPixelStage"] = new ShaderMixinSource +{ +Mixins = +{ +new ShaderClassSource("MaterialStream"), +new ShaderClassSource("MaterialPixelShadingStream"), +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, + Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, + }; + + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + } +} diff --git a/sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs b/sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs index 0070a4032c..a1552a241a 100644 --- a/sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs +++ b/sources/shaders/Stride.Shaders.Tests/TestHeaderParser.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; -namespace Stride.Shaders.Parsing.Tests; +namespace Stride.Shaders.Parsers.Tests; // Note: generated with ChatGPT public sealed class TestHeader @@ -140,4 +140,4 @@ public static IEnumerable SplitArgs(string args) if (current.Count > 0) yield return new string(current.ToArray()).Trim(); } -} \ No newline at end of file +} diff --git a/sources/shaders/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx b/sources/shaders/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx deleted file mode 100644 index 13271d292a..0000000000 --- a/sources/shaders/assets/Stride/SDFX/AmbientOcclusionBlurEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A gaussian blur effect - /// - effect AmbientOcclusionBlurEffect - { - using params AmbientOcclusionBlurKeys; - - // Mixin - mixin AmbientOcclusionBlurShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx b/sources/shaders/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx deleted file mode 100644 index 71be5b39a4..0000000000 --- a/sources/shaders/assets/Stride/SDFX/AmbientOcclusionRawAOEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A gaussian blur effect - /// - effect AmbientOcclusionRawAOEffect - { - using params AmbientOcclusionRawAOKeys; - - // Mixin - mixin AmbientOcclusionRawAOShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx b/sources/shaders/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx deleted file mode 100644 index d80fd5a495..0000000000 --- a/sources/shaders/assets/Stride/SDFX/BackgroundVelocityEffect.sdfx +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Computes screen space velocity for backgrounds -effect BackgroundVelocityEffect -{ - using params StrideEffectBaseKeys; - - mixin ShaderBase; - mixin ShadingBase; - mixin BackgroundVelocity; - - // ----------------------------------------------- - // MRT output definitions (color0 excluded) - // ----------------------------------------------- - var targetExtensions = StrideEffectBaseKeys.RenderTargetExtensions; - if (targetExtensions != null) - { - mixin (targetExtensions); - } -}; diff --git a/sources/shaders/assets/Stride/SDFX/CoCMapBlurEffect.sdfx b/sources/shaders/assets/Stride/SDFX/CoCMapBlurEffect.sdfx deleted file mode 100644 index 7e1848424c..0000000000 --- a/sources/shaders/assets/Stride/SDFX/CoCMapBlurEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A directional, depth-aware and weighted-blur for a CoC map. - /// - effect CoCMapBlurEffect - { - using params DepthAwareDirectionalBlurKeys; - - // Mixin - mixin CoCMapBlurShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ColorCombinerEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ColorCombinerEffect.sdfx deleted file mode 100644 index 002d86bbca..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ColorCombinerEffect.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - effect ColorCombinerEffect - { - using params ColorCombiner; - - // Mixin - mixin ColorCombinerShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx deleted file mode 100644 index a9971567bb..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ColorTransformGroupEffect.sdfx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A Color transform group effect - /// - effect ColorTransformCompose - { - using params ColorTransformKeys; - - mixin ColorTransformKeys.Shader, ColorTransformKeys.GenericArguments; - }; - - effect ColorTransformGroupEffect - { - using params ColorTransformGroupKeys; - - // Mixin - mixin ColorTransformGroupShader; - foreach (var colorTransform in ColorTransformGroupKeys.Transforms) - { - context.PushParameters(colorTransform.Parameters); - mixin compose Transforms += ColorTransformCompose; - context.PopParameters(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx b/sources/shaders/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx deleted file mode 100644 index ed7cf2d8c3..0000000000 --- a/sources/shaders/assets/Stride/SDFX/CombineFrontCoCEffect.sdfx +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// Combines the different blur levels depending on the pixel's CoC. - /// Specific for the front out-of-focus objects. - /// - effect CombineFrontCoCEffect - { - using params CombineLevelsFromCoCKeys; - - // Mixin - mixin CombineFrontCoCShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx b/sources/shaders/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx deleted file mode 100644 index 48e68bd2c1..0000000000 --- a/sources/shaders/assets/Stride/SDFX/CombineLevelsFromCoCEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// Combines the different blur levels depending on the pixel's CoC. (Back area only.) - /// - effect CombineLevelsFromCoCEffect - { - using params CombineLevelsFromCoCKeys; - - // Mixin - mixin CombineLevelsFromCoCShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ComputeEffectShader.sdfx b/sources/shaders/assets/Stride/SDFX/ComputeEffectShader.sdfx deleted file mode 100644 index 7a270ae1d1..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ComputeEffectShader.sdfx +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.ComputeEffect -{ - /// - /// The effect for compute effect - /// - effect ComputeEffectShader - { - using params ComputeEffectShaderKeys; - - mixin macro ThreadNumberX = ComputeEffectShaderKeys.ThreadNumbers.X; - mixin macro ThreadNumberY = ComputeEffectShaderKeys.ThreadNumbers.Y; - mixin macro ThreadNumberZ = ComputeEffectShaderKeys.ThreadNumbers.Z; - - // base effect for computing - mixin ComputeShaderBase; - - // user computing effect - mixin ComputeEffectShaderKeys.ComputeShaderName; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx deleted file mode 100644 index 0d7d44b105..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ComputeShaderTestEffect.sdfx +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Graphics.Tests -{ - params ComputeShaderTestParams - { - int NbOfIterations; - } - - effect ComputeShaderTestEffect - { - using params ComputeShaderTestParams; - - mixin ComputeShaderTest; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/CubemapEffect.sdfx b/sources/shaders/assets/Stride/SDFX/CubemapEffect.sdfx deleted file mode 100644 index d21fb15817..0000000000 --- a/sources/shaders/assets/Stride/SDFX/CubemapEffect.sdfx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect CubemapDisplayEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - mixin AlbedoFlatShading; - mixin compose albedoDiffuse = ComputeColorTextureCubeBasic; - }; - - effect CubemapEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - mixin AlbedoFlatShading; - - if (MaterialParameters.AlbedoDiffuse != null) - mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; - else - mixin compose albedoDiffuse = ComputeColorTextureCubeReflect; - }; - - effect CubemapGeomEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - - mixin macro MAX_VERTEX_COUNT = 9; - mixin CameraCube; - - mixin AlbedoFlatShading; - - if (MaterialParameters.AlbedoDiffuse != null) - mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; - }; - - effect CubemapIBLEffect - { - mixin StrideBaseShader; - mixin child StrideGBufferShaderPass; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/CustomEffect.sdfx b/sources/shaders/assets/Stride/SDFX/CustomEffect.sdfx deleted file mode 100644 index e6b7acbdaa..0000000000 --- a/sources/shaders/assets/Stride/SDFX/CustomEffect.sdfx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Graphics.Tests -{ - partial effect CustomSubEffect - { - using params CustomShaderKeys; - - if (CustomShaderKeys.SwitchEffectLevel < 10) - { - mixin CustomShader; - } - else - { - mixin CustomShader2; - } - }; - - /// - /// A gaussian blur effect - /// - effect CustomEffect - { - mixin CustomShader; - mixin child CustomSubEffect; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx b/sources/shaders/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx deleted file mode 100644 index b5d1ec0ed8..0000000000 --- a/sources/shaders/assets/Stride/SDFX/DepthAwareDirectionalBlurEffect.sdfx +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A directional, depth-aware, uniform-weight blur. - /// - effect DepthAwareDirectionalBlurEffect - { - using params DepthAwareDirectionalBlurKeys; - - // Mixin - mixin DepthAwareDirectionalBlurShader< DepthAwareDirectionalBlurKeys.Count, - DepthAwareDirectionalBlurKeys.TotalTap>; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/DepthMinMaxEffect.sdfx b/sources/shaders/assets/Stride/SDFX/DepthMinMaxEffect.sdfx deleted file mode 100644 index 16b6fa420d..0000000000 --- a/sources/shaders/assets/Stride/SDFX/DepthMinMaxEffect.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - effect DepthMinMaxEffect - { - using params DepthMinMax; - - mixin DepthMinMaxShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/FXAAShaderEffect.sdfx b/sources/shaders/assets/Stride/SDFX/FXAAShaderEffect.sdfx deleted file mode 100644 index 7f1fa6d715..0000000000 --- a/sources/shaders/assets/Stride/SDFX/FXAAShaderEffect.sdfx +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - effect FXAAShaderEffect - { - using params FXAAEffect; - - // Mixin - mixin macro FXAA_GREEN_AS_LUMA = FXAAEffect.GreenAsLumaKey; - mixin macro FXAA_QUALITY__PRESET = FXAAEffect.QualityKey; - mixin FXAAShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/FlareArtifactEffect.sdfx b/sources/shaders/assets/Stride/SDFX/FlareArtifactEffect.sdfx deleted file mode 100644 index a72401b6bc..0000000000 --- a/sources/shaders/assets/Stride/SDFX/FlareArtifactEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A flare artifact effect - /// - effect FlareArtifactEffect - { - using params FlareArtifactKeys; - - // Mixin - mixin FlareArtifactShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/GaussianBlurEffect.sdfx b/sources/shaders/assets/Stride/SDFX/GaussianBlurEffect.sdfx deleted file mode 100644 index 0c95b95a36..0000000000 --- a/sources/shaders/assets/Stride/SDFX/GaussianBlurEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A gaussian blur effect - /// - effect GaussianBlurEffect - { - using params GaussianBlurKeys; - - // Mixin - mixin GaussianBlurShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ImageScalerEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ImageScalerEffect.sdfx deleted file mode 100644 index e0e0673f68..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ImageScalerEffect.sdfx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A copier effect - /// - effect ImageScalerEffect - { - mixin ImageScalerShader; - }; - - effect ImageSuperSamplerScalerEffect - { - mixin ImageScalerShader; - mixin SpriteSuperSampler; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx b/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx deleted file mode 100644 index 6018b180b4..0000000000 --- a/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSH.sdfx +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - params LambertianPrefilteringSHParameters - { - int BlockSize; - } - - effect LambertianPrefilteringSHEffectPass1 - { - using params SphericalHarmonicsParameters; - using params LambertianPrefilteringSHParameters; - - mixin LambertianPrefilteringSHPass1; - }; - - effect LambertianPrefilteringSHEffectPass2 - { - using params SphericalHarmonicsParameters; - using params LambertianPrefilteringSHParameters; - - mixin LambertianPrefilteringSHPass2; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx b/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx deleted file mode 100644 index 937d1cee91..0000000000 --- a/sources/shaders/assets/Stride/SDFX/LambertianPrefilteringSHNoComputeEffect.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - effect LambertianPrefilteringSHNoComputeEffectPass1 - { - using params SphericalHarmonicsParameters; - - mixin LambertianPrefilteringSHNoComputePass1; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/LightShaftsEffect.sdfx b/sources/shaders/assets/Stride/SDFX/LightShaftsEffect.sdfx deleted file mode 100644 index d8f04ee853..0000000000 --- a/sources/shaders/assets/Stride/SDFX/LightShaftsEffect.sdfx +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - effect LightShaftsEffect - { - // Use code from the shadow receiver appropriate for the light this lightshaft is rendered for - using params LightShaftsEffectKeys; - mixin compose lightGroup = (LightShaftsEffectKeys.LightGroup); - - mixin LightShaftsShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/LightSkyboxEffect.sdfx b/sources/shaders/assets/Stride/SDFX/LightSkyboxEffect.sdfx deleted file mode 100644 index 1295e11d55..0000000000 --- a/sources/shaders/assets/Stride/SDFX/LightSkyboxEffect.sdfx +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; - -namespace Stride.Rendering.Lights -{ - /// - /// Base effect - /// - effect LightSkyboxEffect - { - using params LightSkyboxShaderKeys; - - mixin LightSkyboxShader; - - if (LightSkyboxShaderKeys.LightDiffuseColor != null) - { - mixin compose lightDiffuseColor = LightSkyboxShaderKeys.LightDiffuseColor; - } - - if (LightSkyboxShaderKeys.LightSpecularColor != null) - { - mixin compose lightSpecularColor = LightSkyboxShaderKeys.LightSpecularColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/LightStreakEffect.sdfx b/sources/shaders/assets/Stride/SDFX/LightStreakEffect.sdfx deleted file mode 100644 index cf5ee265f7..0000000000 --- a/sources/shaders/assets/Stride/SDFX/LightStreakEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A light streak effect - /// - effect LightStreakEffect - { - using params LightStreakKeys; - - // Mixin - mixin LightStreakShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/MSAAResolverEffect.sdfx b/sources/shaders/assets/Stride/SDFX/MSAAResolverEffect.sdfx deleted file mode 100644 index b156fd5701..0000000000 --- a/sources/shaders/assets/Stride/SDFX/MSAAResolverEffect.sdfx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Compositing -{ - params MSAAResolverParams - { - int MSAASamples; - int ResolveFilterType; - float ResolveFilterDiameter; - } - - effect MSAAResolverEffect - { - using params MSAAResolverParams; - - mixin macro INPUT_MSAA_SAMPLES = MSAAResolverParams.MSAASamples; - mixin MSAAResolverShader; - }; - - effect MSAADepthResolverEffect - { - using params MSAAResolverParams; - - mixin macro INPUT_MSAA_SAMPLES = MSAAResolverParams.MSAASamples; - mixin MSAADepthResolverShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx b/sources/shaders/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx deleted file mode 100644 index 1482121421..0000000000 --- a/sources/shaders/assets/Stride/SDFX/McIntoshOptimizedEffect.sdfx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// Optimized version of the McIntosh blur. - /// Does the 2 final blur and keep the minimum in a single pass. - /// - partial effect McIntoshOptimizedEffect - { - using params DepthAwareDirectionalBlurKeys; - - // Mixin - mixin McIntoshOptimizedShader; - mixin compose directionalBlurA = DepthAwareDirectionalBlurUtil; - mixin compose directionalBlurB = DepthAwareDirectionalBlurUtil; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx deleted file mode 100644 index 83ea5f77af..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ModelComponentPickingEffect.sdfx +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; - -namespace Stride.Rendering.Utils -{ - effect ModelComponentPickingEffect - { - mixin ModelComponentPickingShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx b/sources/shaders/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx deleted file mode 100644 index bde2ba4838..0000000000 --- a/sources/shaders/assets/Stride/SDFX/MultiTexturesSpriteEffect.sdfx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect MultiTexturesSpriteEffect - { - mixin MultiTexturesSpriteShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx b/sources/shaders/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx deleted file mode 100644 index 481df35fde..0000000000 --- a/sources/shaders/assets/Stride/SDFX/MultipleRenderTargetsEffect.sdfx +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Graphics.Tests -{ - effect MultipleRenderTargetsEffect - { - mixin StrideForwardShadingEffect; - mixin MultipleRenderTargetsEffectShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ParticleBaseEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ParticleBaseEffect.sdfx deleted file mode 100644 index 1cc81875de..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ParticleBaseEffect.sdfx +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering -{ - partial effect ParticleBaseEffect - { - using params ParticleBaseKeys; - - using params ParticleUtilitiesKeys; - - mixin macro ParticleBaseKeys.UsesSoftEdge; - - mixin ParticleBase; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ParticleCustomEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ParticleCustomEffect.sdfx deleted file mode 100644 index 51ba4060f3..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ParticleCustomEffect.sdfx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering -{ - partial effect ParticleCustomEffect - { - // Use the ParticleBaseKeys for constant attributes, defined in the game engine - using params ParticleBaseKeys; - - // Use the ParticleCustomShaderKeys for constant attributes, defined in this project - using params ParticleCustomShaderKeys; - - // Inherit from the ParticleBaseEffect.sdfx, defined in the game engine - mixin ParticleBaseEffect; - - // Use the ParticleCustomShader.sdsl, defined in this project - mixin ParticleCustomShader; - - // If the user-defined effect for the baseColor is not null use it - if (ParticleCustomShaderKeys.BaseColor != null) - { - mixin compose baseColor = ParticleCustomShaderKeys.BaseColor; - } - - // If the user-defined effect for the baseIntensity (alpha) is not null use it - if (ParticleCustomShaderKeys.BaseIntensity != null) - { - mixin compose baseIntensity = ParticleCustomShaderKeys.BaseIntensity; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ParticleEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ParticleEffect.sdfx deleted file mode 100644 index 32308522d4..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ParticleEffect.sdfx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering -{ - partial effect ParticleEffect - { - using params ParticleBaseKeys; - - mixin ParticleBaseEffect; - - mixin ParticleComputeColorShader; - - if (ParticleBaseKeys.BaseColor != null) - { - mixin compose baseColor = ParticleBaseKeys.BaseColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/Picking.sdfx b/sources/shaders/assets/Stride/SDFX/Picking.sdfx deleted file mode 100644 index 7e10001d58..0000000000 --- a/sources/shaders/assets/Stride/SDFX/Picking.sdfx +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering -{ - partial effect Picking - { - mixin PickingShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/PreviewTexture.sdfx b/sources/shaders/assets/Stride/SDFX/PreviewTexture.sdfx deleted file mode 100644 index 66f32a74b6..0000000000 --- a/sources/shaders/assets/Stride/SDFX/PreviewTexture.sdfx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace StrideEffects -{ - params PreviewTextureParameters - { - bool Is3D; - }; - - effect PreviewTexture - { - using params PreviewTextureParameters; - - if(PreviewTextureParameters.Is3D) - { - mixin Sprite3DBase; - } - - mixin SpriteBatch; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx b/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx deleted file mode 100644 index c5fbbcb2cf..0000000000 --- a/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXEffect.sdfx +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - params RadiancePrefilteringGGXParams - { - int NbOfSamplings; - } - - effect RadiancePrefilteringGGXEffect - { - using params RadiancePrefilteringGGXParams; - - mixin RadiancePrefilteringGGXShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx b/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx deleted file mode 100644 index 4a228d9b55..0000000000 --- a/sources/shaders/assets/Stride/SDFX/RadiancePrefilteringGGXNoComputeEffect.sdfx +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - params RadiancePrefilteringGGXNoComputeParams - { - int NbOfSamplings; - } - - effect RadiancePrefilteringGGXNoComputeEffect - { - using params RadiancePrefilteringGGXNoComputeParams; - - mixin RadiancePrefilteringGGXNoComputeShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SceneEditorParameters.sdfx b/sources/shaders/assets/Stride/SDFX/SceneEditorParameters.sdfx deleted file mode 100644 index f6218fed35..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SceneEditorParameters.sdfx +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace StrideEffects -{ - params SceneEditorParameters - { - //bool IsSelected; - bool IsEffectCompiling; - bool IsEffectError; - //bool IsMetaEntity; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SelectedSprite.sdfx b/sources/shaders/assets/Stride/SDFX/SelectedSprite.sdfx deleted file mode 100644 index 995b2fce96..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SelectedSprite.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace StrideEffects -{ - effect SelectedSprite - { - using params SpriteBaseKeys; - - mixin SpriteBatchShader; - mixin SelectedSpriteShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ShadowMapCaster.sdfx b/sources/shaders/assets/Stride/SDFX/ShadowMapCaster.sdfx deleted file mode 100644 index daf419a64a..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ShadowMapCaster.sdfx +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Materials; - -namespace Stride.Rendering.Shadows -{ - // Spawn a sub-effect for the shadow map caster pass - partial effect ShadowMapCaster - { - using params MaterialKeys; - - // For cut off and blend materials we want to run pixel shader during rendering shadow maps - if(MaterialKeys.UseDitheredShadows) - { - mixin ShadowMapCasterAlphaDithered; - } - else if(MaterialKeys.UsePixelShaderWithDepthPass) - { - mixin ShadowMapCasterAlphaDiscard; - } - else - { - mixin ShadowMapCasterNoPixelShader; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx b/sources/shaders/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx deleted file mode 100644 index 3801d3f241..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ShadowMapCasterCubeMap.sdfx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Materials; - -namespace Stride.Rendering.Shadows -{ - // Spawn a sub-effect for the shadow map caster pass - partial effect ShadowMapCasterCubeMap - { - using params MaterialKeys; - - // For cut off and blend materials we want to run pixel shader during rendering shadow maps - if(MaterialKeys.UseDitheredShadows) - { - mixin ShadowMapCasterAlphaDithered; - } - else if(MaterialKeys.UsePixelShaderWithDepthPass) - { - mixin ShadowMapCasterAlphaDiscard; - } - else - { - mixin ShadowMapCasterNoPixelShader; - } - - mixin ShadowMapCasterCubeMapProjection; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx b/sources/shaders/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx deleted file mode 100644 index c17fb3688e..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ShadowMapCasterParaboloid.sdfx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Materials; - -namespace Stride.Rendering.Shadows -{ - // Spawn a sub-effect for the shadow map caster pass - partial effect ShadowMapCasterParaboloid - { - using params MaterialKeys; - - // For cut off and blend materials we want to run pixel shader during rendering shadow maps - if(MaterialKeys.UseDitheredShadows) - { - mixin ShadowMapCasterAlphaDithered; - } - else if(MaterialKeys.UsePixelShaderWithDepthPass) - { - mixin ShadowMapCasterAlphaDiscard; - } - else - { - mixin ShadowMapCasterNoPixelShader; - } - - mixin ShadowMapCasterParaboloidProjection; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SimpleEffect.sdfx b/sources/shaders/assets/Stride/SDFX/SimpleEffect.sdfx deleted file mode 100644 index 2d9b914c4f..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SimpleEffect.sdfx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect SimpleEffect - { - mixin SimpleShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx b/sources/shaders/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx deleted file mode 100644 index cfc0540575..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SpaceEscapeEffectMain.sdfx +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace SpaceEscape.Effects -{ - params GameParameters - { - bool EnableFog = true; - bool EnableBend = true; - bool EnableOnflyTextureUVChange = false; - } - - effect SpaceEscapeEffectMain - { - using params GameParameters; - - mixin StrideForwardShadingEffect; - - if(GameParameters.EnableOnflyTextureUVChange) - mixin TransformationTextureUV; - - if(GameParameters.EnableBend) - mixin TransformationBendWorld; - - if(GameParameters.EnableFog) - mixin CustomFogEffect; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx b/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx deleted file mode 100644 index 969136062a..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsParameters.sdfx +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - params SphericalHarmonicsParameters - { - int HarmonicsOrder; - } -} diff --git a/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx b/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx deleted file mode 100644 index 200b64c1c9..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SphericalHarmonicsRendererEffect.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - effect SphericalHarmonicsRendererEffect - { - using params SphericalHarmonicsParameters; - - mixin SphericalHarmonicsRenderer; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SpriteBatch.sdfx b/sources/shaders/assets/Stride/SDFX/SpriteBatch.sdfx deleted file mode 100644 index c7434466cc..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SpriteBatch.sdfx +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering -{ - /// - /// SpriteBatch effect - /// - partial effect SpriteBatch - { - using params SpriteBaseKeys; - mixin SpriteBatchShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx deleted file mode 100644 index 46076fb12e..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideBakeLightProbeEffect.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; -using Stride.Rendering.Materials; - -namespace Stride.Rendering.LightProbes -{ - partial effect StrideBakeLightProbeEffect - { - mixin BakeLightProbeShader; - } -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx deleted file mode 100644 index 1b7e509104..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideEditorForwardShadingEffect.sdfx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace StrideEffects -{ - effect StrideEditorForwardShadingEffect - { - using params SceneEditorParameters; - - // TODO: This file is similar to StrideEditorWireframeShadingEffect. We should try to look if we can merge them into a single one. - - // Early failover in case there was an effect compilation error - // We later could do a two level error detection: - // - first time at the end of effect (that is ran with nearly empty CompilerParameters) - // - if this one fails too, use this early failover which should have only very few basic shaders - if (SceneEditorParameters.IsEffectError) - { - mixin ShaderBase; - mixin ShadingBase; - mixin TransformationBase; - mixin TransformationWAndVP; - mixin CompilationErrorShader; - discard; - } - - // Include the standard forward shading effect - mixin StrideForwardShadingEffect; - - mixin child Picking; - mixin child Wireframe; - mixin child Highlight; - - // Add an effect compiling if it is not ready - if (SceneEditorParameters.IsEffectCompiling) - { - mixin EffectCompiling; - } - }; - - effect Wireframe - { - using params MaterialFrontBackBlendShaderKeys; - - mixin MaterialFrontBackBlendShader; - } - - effect Highlight - { - mixin HighlightShader; - } -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx deleted file mode 100644 index 6d699fc1be..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideEditorHighlightingEffect.sdfx +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace StrideEffects -{ - effect StrideEditorHighlightingEffect - { - mixin StrideForwardShadingEffect; - //mixin MaterialHighlightingShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx deleted file mode 100644 index 812d2fc7e6..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideEditorMaterialPreviewEffect.sdfx +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace StrideEffects -{ - effect StrideEditorMaterialPreviewEffect - { - mixin StrideEditorForwardShadingEffect; - mixin SharedTextureCoordinate; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideEffectBase.sdfx b/sources/shaders/assets/Stride/SDFX/StrideEffectBase.sdfx deleted file mode 100644 index e706737b01..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideEffectBase.sdfx +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; -using Stride.Rendering.Materials; - -namespace Stride.Rendering -{ - /// - /// Base effect - /// - partial effect StrideEffectBase - { - using params MaterialKeys; - using params StrideEffectBaseKeys; - - // ----------------------------------------------- - // Base shaders - // ----------------------------------------------- - mixin ShaderBase; - mixin ShadingBase; - - // ----------------------------------------------- - // Mix material per Vertex Shader - // ----------------------------------------------- - var extensionPreVertexStageSurfaceShaders = MaterialKeys.VertexStageSurfaceShaders; - if (extensionPreVertexStageSurfaceShaders != null) - { - // Must come before TransformationBase as this is responsible to modify the vertex input stream - mixin MaterialSurfaceVertexStageCompositor; - mixin compose materialVertexStage = (extensionPreVertexStageSurfaceShaders); - mixin compose streamInitializerVertexStage = MaterialKeys.VertexStageStreamInitializer; - } - - // ----------------------------------------------- - // Transform vertex stream - // ----------------------------------------------- - // Come after material surface per vertex - mixin TransformationBase; - mixin NormalStream; - - var extensionTessellationShader = MaterialKeys.TessellationShader; - - if (StrideEffectBaseKeys.HasInstancing) - { - mixin macro StrideEffectBaseKeys.ModelTransformUsage; - mixin TransformationWAndVPInstanced; - - // ----------------------------------------------- - // Performs normal mapping (in case of no-skinning, otherwise it is overloaded below) - // ----------------------------------------------- - if (MaterialKeys.HasNormalMap) - { - if (extensionTessellationShader != null) - { - mixin NormalFromNormalMappingTessellationInstanced; - } - else - { - mixin NormalFromNormalMappingInstanced; - } - } - else - { - mixin NormalFromMeshInstanced; - } - } - else - { - mixin TransformationWAndVP; - - // ----------------------------------------------- - // Performs normal mapping (in case of no-skinning, otherwise it is overloaded below) - // ----------------------------------------------- - if (MaterialKeys.HasNormalMap) - { - if (extensionTessellationShader != null) - { - mixin NormalFromNormalMappingTessellation; - } - else - { - mixin NormalFromNormalMapping; - } - } - else - { - mixin NormalFromMesh; - } - } - - - // ----------------------------------------------- - // Performs animation skinning (position, normal and tangent) - // ----------------------------------------------- - if (MaterialKeys.HasSkinningPosition) - { - mixin macro MaterialKeys.SkinningMaxBones; - - if (StrideEffectBaseKeys.HasInstancing) - { - mixin TransformationSkinningInstanced; - } - else - { - mixin TransformationSkinning; - } - - if (MaterialKeys.HasSkinningNormal) - { - mixin NormalMeshSkinning; - } - - if (MaterialKeys.HasSkinningTangent) - { - mixin TangentMeshSkinning; - } - - if (MaterialKeys.HasSkinningNormal) - { - if (MaterialKeys.HasNormalMap) - { - if (extensionTessellationShader != null) - { - mixin NormalVSSkinningNormalMappingTessellation; - } - else - { - mixin NormalVSSkinningNormalMapping; - } - } - else - { - mixin NormalVSSkinningFromMesh; - } - } - } - - // -------------------------------------------- - // Mix material tessellation for Domain effect - //--------------------------------------------- - if(extensionTessellationShader != null) - { - mixin (extensionTessellationShader); - - var extensionDomainStageSurfaceShaders = MaterialKeys.DomainStageSurfaceShaders; - if(extensionDomainStageSurfaceShaders != null) - { - mixin MaterialSurfaceDomainStageCompositor; - mixin compose materialDomainStage = (extensionDomainStageSurfaceShaders); - mixin compose streamInitializerDomainStage = MaterialKeys.DomainStageStreamInitializer; - } - } - - // ----------------------------------------------- - // Screen space velocity calculation - // ----------------------------------------------- - var computeVelocityShader = StrideEffectBaseKeys.ComputeVelocityShader; - if(computeVelocityShader != null) - { - mixin (computeVelocityShader); - } - - // ----------------------------------------------- - // Mix Extension after vertex stage - // ----------------------------------------------- - var extensionPostVertexStage = StrideEffectBaseKeys.ExtensionPostVertexStageShader; - if (extensionPostVertexStage != null) - { - mixin (extensionPostVertexStage); - } - - // ----------------------------------------------- - // MRT output definitions (color0 excluded) - // ----------------------------------------------- - var targetExtensions = StrideEffectBaseKeys.RenderTargetExtensions; - if (targetExtensions != null) - { - mixin (targetExtensions); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx deleted file mode 100644 index 662ebee230..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideForwardShadingEffect.sdfx +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; -using Stride.Rendering.Materials; - -namespace Stride.Rendering -{ - partial effect StrideLighting - { - using params LightingKeys; - - // ----------------------------------------------- - // Add light groups - // ----------------------------------------------- - ShaderSourceCollection directLightGroups = LightingKeys.DirectLightGroups; - if (directLightGroups != null) - { - foreach(ShaderSource directLightGroup in directLightGroups) - { - // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" - mixin compose directLightGroups += (directLightGroup); - } - } - - // ----------------------------------------------- - // Add environment light groups - // ----------------------------------------------- - ShaderSourceCollection environmentLights = LightingKeys.EnvironmentLights; - if (environmentLights != null) - { - foreach(ShaderSource environmentLight in environmentLights) - { - // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" - mixin compose environmentLights += (environmentLight); - } - } - } - - /// - /// Forward shading effect - /// - effect StrideForwardShadingEffect - { - using params MaterialKeys; - - // Derive from StrideEffectBase - mixin StrideEffectBase; - - // ----------------------------------------------- - // Mix material and lighting shading for Pixel Shader - // ----------------------------------------------- - ShaderSource extensionPixelStageSurfaceShaders = MaterialKeys.PixelStageSurfaceShaders; - if (extensionPixelStageSurfaceShaders != null) - { - mixin MaterialSurfacePixelStageCompositor; - mixin compose materialPixelStage = (extensionPixelStageSurfaceShaders); - mixin compose streamInitializerPixelStage = MaterialKeys.PixelStageStreamInitializer; - - ShaderSource extensionPixelStageSurfaceFilter = MaterialKeys.PixelStageSurfaceFilter; - if (extensionPixelStageSurfaceFilter != null) - { - mixin (extensionPixelStageSurfaceFilter); - } - - mixin child GBuffer; - } - - // ----------------------------------------------- - // Add direct and environment light groups - // ----------------------------------------------- - mixin StrideLighting; - - mixin child ShadowMapCaster; - mixin child ShadowMapCasterParaboloid; - mixin child ShadowMapCasterCubeMap; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx b/sources/shaders/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx deleted file mode 100644 index da7ebfbf27..0000000000 --- a/sources/shaders/assets/Stride/SDFX/StrideWireframeShadingEffect.sdfx +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Rendering.Data; -using Stride.Shaders.Compiler; - -namespace Stride.Rendering -{ - effect StrideWireframeShadingEffect - { - using params MaterialFrontBackBlendShaderKeys; - - mixin StrideEffectBase; - - mixin MaterialFrontBackBlendShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx b/sources/shaders/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx deleted file mode 100644 index c3cce2258a..0000000000 --- a/sources/shaders/assets/Stride/SDFX/SubsurfaceScatteringBlurEffect.sdfx +++ /dev/null @@ -1,17 +0,0 @@ -namespace Stride.Rendering.SubsurfaceScattering -{ - effect SubsurfaceScatteringBlurEffect - { - using params SubsurfaceScatteringKeys; // TODO: What does this do? - - // Mixin: - mixin macro SSSS_FOLLOW_SURFACE = SubsurfaceScatteringKeys.FollowSurface; - - mixin SubsurfaceScatteringBlurShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ToGlslEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ToGlslEffect.sdfx deleted file mode 100644 index 104a0887c4..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ToGlslEffect.sdfx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect ToGlslEffect - { - mixin ToGlslShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/ToneMapEffect.sdfx b/sources/shaders/assets/Stride/SDFX/ToneMapEffect.sdfx deleted file mode 100644 index 3a4fb3ce3a..0000000000 --- a/sources/shaders/assets/Stride/SDFX/ToneMapEffect.sdfx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Images -{ - /// - /// A Tonemap effect - /// - effect ToneMapEffect - { - using params ColorTransformKeys; - using params ToneMapKeys; - - // Mixin - mixin ToneMapShader; - context.PushParameters(ToneMapKeys.Operator.Parameters); - mixin compose ToneMapOperator = ColorTransformKeys.Shader; - context.PopParameters(); - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/UIEffect.sdfx b/sources/shaders/assets/Stride/SDFX/UIEffect.sdfx deleted file mode 100644 index 41a956639d..0000000000 --- a/sources/shaders/assets/Stride/SDFX/UIEffect.sdfx +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering -{ - /// - /// UIEffect effect - /// - partial effect UIEffect - { - using params SpriteBaseKeys; - mixin UIEffectShader; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_complex_params.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_complex_params.sdfx deleted file mode 100644 index fe2209c02e..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_complex_params.sdfx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test1 -{ - params SubParameters - { - bool param1; - int param2 = 1; - string param3 = "ok"; - }; - - params TestParameters - { - SubParameters subParam1; - SubParameters subParameters[]; - }; - - effect DefaultComplexParams - { - using params TestParameters; - using params SubParameters; - - mixin A; - mixin B; - mixin C; - - int x = 1; - foreach (params TestParameters.subParameters) - { - if (SubParameters.param1) - { - mixin "C" + x; - } - - x++; - } - - using params TestParameters.subParam1 - { - - if (SubParameters.param2 == 1) - { - mixin D; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_compose_keys.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_compose_keys.sdfx deleted file mode 100644 index 3a39780d00..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_compose_keys.sdfx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace TestABC -{ - params TestParameters - { - bool UseComputeColor2; - bool UseComputeColorRedirect; - }; - - partial effect ABCSubEffect - { - using params TestParameters; - - if (TestParameters.UseComputeColor2) - { - mixin TestComputeColor2; - } - else if (TestParameters.UseComputeColorRedirect) - { - mixin TestComputeColorRedirect; - mixin compose ColorRedirect = TestComputeColor2; - } - else - { - mixin TestComputeColor; - } - }; - - effect test_mixin_compose_keys - { - mixin A; - mixin compose SubCompute1 = ABCSubEffect; - mixin compose SubCompute2 = ABCSubEffect; - mixin compose SubComputes += ABCSubEffect; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple.sdfx deleted file mode 100644 index 30fb4c9eb3..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple.sdfx +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test2 -{ - effect DefaultSimple - { - mixin A; - mixin B; - mixin C; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child.sdfx deleted file mode 100644 index 28d5b83253..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child.sdfx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test3 -{ - partial effect ChildMixin - { - mixin C1; - mixin C2; - }; - - effect DefaultSimpleChild - { - mixin A; - mixin B; - mixin C; - mixin ChildMixin; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx deleted file mode 100644 index a52d477a80..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_child_params.sdfx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test4 -{ - params TestParameters - { - int TestCount; - bool UseComputeColorEffect; - }; - - partial effect ChildParamsMixin - { - using params TestParameters; - - TestParameters.TestCount = 1; - if (TestParameters.TestCount == 1) - mixin C1; - }; - - effect DefaultSimpleChildParams - { - using params TestParameters; - - mixin A; - if (TestParameters.TestCount == 0) - mixin B; - - mixin child ChildParamsMixin; - - if (TestParameters.TestCount == 0) - mixin C; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_clone.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple_clone.sdfx deleted file mode 100644 index 69b66d7057..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_clone.sdfx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test5 -{ - effect ChildClone - { - mixin C1; - mixin C2; - }; - - effect DefaultSimpleClone - { - mixin A; - mixin B; - mixin C; - // Rename the sub child as Test - mixin child Test = ChildClone; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_compose.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple_compose.sdfx deleted file mode 100644 index c740522705..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_compose.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test6 -{ - effect DefaultSimpleCompose - { - mixin A; - mixin B; - mixin C; - mixin compose x = X; - }; -} diff --git a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_params.sdfx b/sources/shaders/assets/Stride/SDFX/test_mixin_simple_params.sdfx deleted file mode 100644 index 140291221c..0000000000 --- a/sources/shaders/assets/Stride/SDFX/test_mixin_simple_params.sdfx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test7 -{ - params TestParameters - { - bool param1; - int param2 = 1; - string param3 = "ok"; - }; - - effect DefaultSimpleParams - { - using params TestParameters; - - mixin A; - mixin B; - - // Include a simple test of a boolean - if (TestParameters.param1) - { - // Conditional mixin - mixin C; - - // Simple test of macro - mixin macro TestParameters.param2; - - // Simple test of composition - mixin compose x = X; - } - else - { - mixin D; - mixin macro Test = TestParameters.param3; - mixin compose y = Y; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/A.sdsl b/sources/shaders/assets/Stride/SDSL/A.sdsl deleted file mode 100644 index 5a64860ce0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/A.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader A : ShaderBase -{ - compose ComputeColor SubCompute1; - compose ComputeColor SubCompute2; - compose ComputeColor SubComputes[]; - - override stage void PSMain() - { - streams.ColorTarget = SubCompute1.Compute(float4(1,1,1,1)) + SubCompute2.Compute(float4(1,1,1,1)); - - foreach(var subCompute in SubComputes) - { - streams.ColorTarget = subCompute.Compute(streams.ColorTarget); - } - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/AdditiveLightEffect.sdsl b/sources/shaders/assets/Stride/SDSL/AdditiveLightEffect.sdsl deleted file mode 100644 index e0ef17704e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/AdditiveLightEffect.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - effect AdditiveLightEffect - { - using params AdditiveLightEffectKeys; - mixin AdditiveLightShader; - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/AdditiveLightShader.sdsl b/sources/shaders/assets/Stride/SDSL/AdditiveLightShader.sdsl deleted file mode 100644 index a1376d29c9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/AdditiveLightShader.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - shader AdditiveLightShader : ImageEffectShader, Texturing - { - cbuffer PerFrame - { - [Color] - stage float3 LightColor; - } - - stage override float4 Shading() - { - float4 color = Texture0.Sample(LinearSampler, streams.TexCoord); - if(TColor) - return float4(color.rgb * LightColor, 1); - return float4(color.rrr * LightColor, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl b/sources/shaders/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl deleted file mode 100644 index eb9d9d7b50..0000000000 --- a/sources/shaders/assets/Stride/SDSL/AmbientOcclusionBlurShader.sdsl +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A gaussian blur shader - /// - internal shader AmbientOcclusionBlurShader : ImageEffectShader, Camera - { - stage float Weights[BlurCount]; - - stage float reconstructCSZ(float depth) - { - if (IsOrthographic) //near + z * (far - near) - return ZProjection.x + depth * ZProjection.y; - else - return ZProjection.y / (depth - ZProjection.x); - } - - stage override float4 Shading() - { - const float epsilon = 0.0001; - - // Direction in texel size: (float2(1,0) or float2(0,1)) * texel size - float2 direction = (IsVertical ? float2(0, 1) : float2(1, 0)) * Texture0TexelSize; - - // Add center - float totalWeight = Weights[0]; - float3 sum = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * totalWeight; - - float linearDepth = reconstructCSZ(Texture1.Sample(LinearSampler, streams.TexCoord).x); - if (linearDepth >= 300) - { - sum /= (totalWeight + epsilon); - return float4(sum, 1); - } - - // mirrored samples using bilinear filtering - [unroll] - for (int i = 1; i < BlurCount; i++) - { - // Handle both directions - [unroll] - for (int j = -1; j <= 1; j += 2) - { - float weight = 0.3 + Weights[i]; - - float value = Texture0.Sample(LinearSampler, streams.TexCoord + direction * j * i * BlurScale).rgb; - - float linearDepthOther = reconstructCSZ(Texture1.Sample(LinearSampler, streams.TexCoord + direction * j * i * BlurScale).x); - weight *= max(0.0, 1.0 - EdgeSharpness * abs(linearDepth - linearDepthOther)); - - sum += value * weight; - - totalWeight += weight; - } - } - - sum /= (totalWeight + epsilon); - return float4(sum, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl b/sources/shaders/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl deleted file mode 100644 index b62d0910ea..0000000000 --- a/sources/shaders/assets/Stride/SDSL/AmbientOcclusionRawAOShader.sdsl +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - shader AmbientOcclusionRawAOShader : ImageEffectShader, Camera - { - float4 ProjInfo; // .x = zN * zF, .y = zN - zF, .z = zF - float4 ScreenInfo; // .x = Width, .y = Height, .z = Aspect - - float ParamProjScale = 1; - float ParamIntensity = 1; - float ParamBias = 0.01f; - float ParamRadius = 1; - float ParamRadiusSquared = 1; - - stage float reconstructCSZ(float depth) - { - if (IsOrthographic) //near + z * (far - near) - return ZProjection.x + depth * ZProjection.y; - else - return ZProjection.y / (depth - ZProjection.x); - } - - stage float3 reconstructCSPosition(float2 S, float z) - { - if (IsOrthographic) - { - float2 uv = S.xy / ScreenInfo.xy; - uv = uv * 2 - 1; - return float3(uv * ProjInfo.xy, z); - } - else - { - return float3((S.xy * ProjInfo.xy + ProjInfo.zw) * z, z); - } - } - - stage float3 reconstructCSNormal(float3 position) - { - return normalize(cross(ddy(position), ddx(position))); - } - - stage float sampleAO(int2 screenPosition, float3 viewPosition, float3 viewNormal, float diskRadius, int i, float randomPatternRotationAngle) - { - //***************************** - // Sample Offset - float alpha = 1 * (i + 0.5) * 0.675f / SamplesCount; - float angle = 1 * 43.9822971503f * alpha + randomPatternRotationAngle; - - float2 offset = float2(cos(angle), sin(angle)); - float ssRadius = alpha * diskRadius; - - //***************************** - // Depth - float2 samplePos = streams.TexCoord + offset * ssRadius; - int2 samplePosInt = saturate(samplePos) * ScreenInfo.xy; - - float depth = Texture0.Load(int3(samplePosInt, 0)); - float linearDepth = reconstructCSZ(depth); - - //***************************** - // View Position - float3 position = reconstructCSPosition(samplePosInt + float2(0.5, 0.5), linearDepth); - position.x *= -1; - - //***************************** - // View Normal - float3 v = position - viewPosition; - v.z *= -1; - - //***************************** - // Ambient Occlusion - float distSq = dot(v, v); - float vn = dot(v, viewNormal); - - const float epsilon = 0.01; - - float f = max(ParamRadiusSquared - distSq, 0.0); - - return f * f * f * max((vn - ParamBias) / (epsilon + distSq), 0.0); - } - - stage override float4 Shading() - { - //***************************** - // Reconstruct View space linear depth Z from the depth buffer - float depth = Texture0.SampleLevel(Sampler, streams.TexCoord, 0).x; - float linearDepth = reconstructCSZ(depth); - - //***************************** - // Reconstruct View space position XYZ - int2 screenPosition = streams.TexCoord.xy * ScreenInfo.xy; - float3 viewPosition = reconstructCSPosition(screenPosition + float2(0.5, 0.5), linearDepth); - viewPosition.x *= -1; - - //***************************** - // Reconstruct View space normal NxNyNz - float3 viewNormal = reconstructCSNormal(viewPosition.xyz); - viewNormal.xy *= -1; - - //***************************** - // Hash function used in the HPG12 AlchemyAO paper - int linearDepthInt = (int)linearDepth; - //float randomPatternRotationAngle = (3 * screenPosition.x ^ screenPosition.y + screenPosition.x * screenPosition.y) * 10; - float randomPatternRotationAngle = ((15 * linearDepthInt + 3 * screenPosition.x ^ 2 * screenPosition.y + screenPosition.x * screenPosition.y) & 0x0000FFFF) * 10; - - //***************************** - // Choose a sample radius proportional to the projected area of the half-sphere - //float diskRadius = -projScale * radius / linearDepth; - float diskRadius; - if (IsOrthographic) - diskRadius = ParamProjScale / ProjInfo.z; - else - diskRadius = ParamProjScale / linearDepth; - - //***************************** - // Compute the ambient occlusion - float sum = 0.0; - for (int i = 0; i < SamplesCount; i++) - { - sum += sampleAO(screenPosition, viewPosition, viewNormal, diskRadius, i, randomPatternRotationAngle); - } - - float temp = ParamRadiusSquared * ParamRadius; - sum /= temp * temp; - float A = max(0.0, 1.0 - sum * 5 * ParamIntensity / SamplesCount); - - float nearPlaneFade = saturate(linearDepth * 2.0 - 0.5); - A = lerp(1, A, nearPlaneFade); - - //***************************** - // Bilateral box-filter over a quad for free, respecting depth edges - // (the difference that this makes is subtle) - if (abs(ddx(linearDepth)) < 0.02) - { - A -= ddx(A) * ((screenPosition.x & 1) - 0.5); - } - if (abs(ddy(linearDepth)) < 0.02) - { - A -= ddy(A) * ((screenPosition.y & 1) - 0.5); - } - - //************************ - // A now contains the light intensity factor (0 to 1) which can be applied to the ambient light illuminating the pixel - - - - //************************ - // Debug - visualize different - //************************ - - /************************ - // Visualize depth as color bands - //************************ - linearDepth = sum; - float4 color = Texture0.Sample(Sampler, streams.TexCoord); - color.r = ((float)(linearDepth % 4)) / 4.0; - color.g = ((float)((linearDepth / 4) % 4)) / 4.0; - color.b = ((float)((linearDepth / 16) % 4)) / 4.0; - return color; //*/ - - - - return float4(A, A, A, A); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl b/sources/shaders/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl deleted file mode 100644 index 80cdf56753..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ApplyAmbientOcclusionShader.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using Stride.Rendering.Materials.ComputeColors; - -namespace Stride.Rendering.Images -{ - shader ApplyAmbientOcclusionShader : ImageEffectShader - { - stage override float4 Shading() - { - //***************************** - float4 color = Texture0.SampleLevel(Sampler, streams.TexCoord, 0); - float occlusion = Texture1.SampleLevel(Sampler, streams.TexCoord, 0).x; - - // TODO Enable debug output as a mixin - // color.rgba = occlusion; - - color.rgb *= occlusion; - - return color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/B.sdsl b/sources/shaders/assets/Stride/SDSL/B.sdsl deleted file mode 100644 index 86cd4a796d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/B.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader B -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/BRDFMicrofacet.sdsl b/sources/shaders/assets/Stride/SDSL/BRDFMicrofacet.sdsl deleted file mode 100644 index 3e1d16be54..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BRDFMicrofacet.sdsl +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.BRDF -{ - /// - /// Utility shader for calculating the various variations of the functions - /// (Fresnel, NDF and Visibility) involved in a Microfacet shading model. - /// - shader BRDFMicrofacet : Math - { - // References: - // http://graphicrants.blogspot.jp/2013/08/specular-brdf-reference.html - // TODO: Add reference to original papers here - - // ------------------------------------------------- - // Normal Distribution Functions - // ------------------------------------------------- - // Expected parameters: - // alphaR = roughness^2 (Burley) - // nDotH = saturate(dot(n, h)) - // ------------------------------------------------- - // TODO Add GGX Anisotropic - - float ClampedPow(float x, float y) - { - return pow(max(x, 0.00001f), y); - } - - /// - /// Calculate the NDF Blinn-Phong - /// - float NormalDistributionBlinnPhong(float alphaR, float nDotH) - { - var alphaR2 = max(alphaR * alphaR, 0.1); // Cap the value to avoid high exponents. TODO: Find an acceptable limit with 16 bits floats targets - return ClampedPow(nDotH, 2 / alphaR2 - 2) / (PI * alphaR2); - } - - /// - /// Calculate the NDF Beckmann - /// - float NormalDistributionBeckmann(float alphaR, float nDotH) - { - var alphaR2 = max(alphaR * alphaR, 0.1); // Cap the value to avoid high exponents. TODO: Find an acceptable limit with 16 bits floats targets - var nDotH2 = max(nDotH * nDotH, 0.0001); - var nDotH4 = nDotH2 * nDotH2; - return exp((nDotH2 -1)/(alphaR2 * nDotH2))/(PI * alphaR2 * nDotH4); - } - - /// - /// Calculate the NDF GGX - /// - float NormalDistributionGGX(float alphaR, float nDotH) - { - var alphaR2 = alphaR * alphaR; - var d = max(nDotH * nDotH * (alphaR2 - 1) + 1, 0.0001); - return alphaR2 / (PI * d * d); - } - - // ------------------------------------------------- - // Fresnel Functions - // ------------------------------------------------- - // Expected parameters: - // f0 = fresnel specular color at angle 0 - // vDotH = saturate(dot(v, h)) - // ------------------------------------------------- - - /// - /// Calculate a nop Fresnel. - /// - float3 FresnelNone(float3 f0) - { - return f0; - } - - /// - /// Calculate a Schlick approximation to Fresnel - /// - float3 FresnelSchlick(float3 f0, float lOrVDotH) - { - return FresnelSchlick(f0, 1.0f, lOrVDotH); - } - - /// - /// Calculate a Schlick approximation to Fresnel with f0, f90 - /// - float3 FresnelSchlick(float3 f0, float3 f90, float lOrVDotH) - { - return f0 + (f90 - f0) * pow((1-lOrVDotH), 5); - } - - // ------------------------------------------------- - // Geometric Shadowing Functions - // ------------------------------------------------- - // We are using V (Visibility) instead of G (Geometric Shadowing function) - // The formula for V is given by: - // V = G / (nDotL * nDotV) - // - // Expected parameters: - // alphaR = roughness^2 (Burley) - // nDotV = max(dot(n, v), 1e-5f) - // nDotL = saturate(dot(n, l)) - // nDotH = saturate(dot(n, h)) - // ------------------------------------------------- - - /// - /// Calculate the Implicit Geometric Shadowing - /// - float VisibilityImplicit(float nDotL, float nDotV) - { - // G = nDotL * nDotV - return 1.0f; - } - - /// - /// Calculate the Neumann Geometric Shadowing - /// - float VisibilityNeumann(float nDotL, float nDotV) - { - // G = (nDotL * nDotV) / max(nDotL, nDotV) - return 1.0 / max(nDotL, nDotV); - } - - /// - /// Calculate the Cook-Torrance Geometric Shadowing - /// - float VisibilityCookTorrance(float nDotH, float vDotH, float nDotL, float nDotV) - { - // G = min(1, min(2 * nDotH * nDotV / vDotH, 2 * nDotH * nDotL / vDotH)); - return min(1, min(2 * nDotH * nDotV / vDotH, 2 * nDotH * nDotL / vDotH)) / (nDotL * nDotV); - } - - /// - /// Calculate the Kelemen Geometric Shadowing - /// - float VisibilityKelemen(float vDotH, float nDotL, float nDotV) - { - // G = nDotL * nDotV / (vDotH * vDotH); - return 1.0f / (vDotH * vDotH); - } - - float VisibilityBeckmann(float alphaR, float nDotX) - { - float c = nDotX / (alphaR * sqrt(1 - nDotX * nDotX)); - return c < 1.6f ? (3.535f * c + 2.181f * c * c) / ( 1 + 2.276f * c + 2577 * c * c) : 1.0f; - } - - /// - /// Calculate the Smith-Beckmann Geometric Shadowing (to use with their respective NDF) - /// - float VisibilitySmithBeckmann(float alphaR, float nDotL, float nDotV) - { - return (VisibilityBeckmann(alphaR, nDotL) * VisibilityBeckmann(alphaR, nDotV)) / (nDotL * nDotV); - } - - float VisibilityGGXCorrelated(float alphaR, float nDotX) - { - var alphaR2 = alphaR * alphaR; - var nDotX2 = nDotX * nDotX; - return sqrt(1 + alphaR2 * ( 1 - nDotX2) / nDotX2); - } - - /// - /// Calculate the Smith-GGX Correlated Geometric Shadowing - /// - /// See Moving Frostbite to PBR. SmithGGX Correlated - float VisibilitySmithGGXCorrelated(float alphaR, float nDotL, float nDotV) - { - // TODO: Expand (nDotL * nDotV) - return 2.0f / ( VisibilityGGXCorrelated(alphaR, nDotL) + VisibilityGGXCorrelated(alphaR, nDotV)) / (nDotL * nDotV); - } - - float VisibilityhSchlickBeckmann(float alphaR, float nDotX) - { - var k = alphaR * sqrt(2.0f / PI); - return nDotX / (nDotX * (1 - k) + k); - } - - /// - /// Calculate the Smith-Schlick-Beckmann Geometric Shadowing - /// - float VisibilitySmithSchlickBeckmann(float alphaR, float nDotL, float nDotV) - { - return VisibilityhSchlickBeckmann(alphaR, nDotL) * VisibilityhSchlickBeckmann(alphaR, nDotV) / (nDotL * nDotV); - } - - float VisibilityhSchlickGGX(float alphaR, float nDotX) - { - var k = alphaR * 0.5f; - return nDotX / (nDotX * (1.0f - k) + k); - } - - /// - /// Calculate the Smith-Schlick-GGX Geometric Shadowing - /// - float VisibilitySmithSchlickGGX(float alphaR, float nDotL, float nDotV) - { - return VisibilityhSchlickGGX(alphaR, nDotL) * VisibilityhSchlickGGX(alphaR, nDotV) / (nDotL * nDotV); - } - - float3 EnvironmentLightingDFG_GGX_Schlick_SmithSchlickGGX( float3 specularColor, float alphaR, float nDotV ) - { - float x = 1 - alphaR; - float y = nDotV; - - float b1 = -0.1688; - float b2 = 1.895; - float b3 = 0.9903; - float b4 = -4.853; - float b5 = 8.404; - float b6 = -5.069; - float bias = saturate( min( b1 * x + b2 * x * x, b3 + b4 * y + b5 * y * y + b6 * y * y * y ) ); - - float d0 = 0.6045; - float d1 = 1.699; - float d2 = -0.5228; - float d3 = -3.603; - float d4 = 1.404; - float d5 = 0.1939; - float d6 = 2.661; - float delta = saturate( d0 + d1 * x + d2 * y + d3 * x * x + d4 * x * y + d5 * y * y + d6 * x * x * x ); - float scale = delta - bias; - - bias *= saturate( 50.0 * specularColor.y ); - return specularColor * scale + bias; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BackgroundCubemapShader.sdsl b/sources/shaders/assets/Stride/SDSL/BackgroundCubemapShader.sdsl deleted file mode 100644 index 6bd53afbe4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BackgroundCubemapShader.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader BackgroundCubemapShader : BackgroundShader -{ - stage TextureCube Cubemap; - - // Shading of the sprite - stage override float4 Shading() - { - var directionVector = float3(1, 1-2*streams.TexCoord.y, 1-2*streams.TexCoord.x); - return Intensity * Cubemap.Sample(LinearSampler, normalize(directionVector)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BackgroundShader.sdsl b/sources/shaders/assets/Stride/SDSL/BackgroundShader.sdsl deleted file mode 100644 index d3b16762a3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BackgroundShader.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader BackgroundShader : SpriteBase -{ - stage float Intensity; - - // Shading of the sprite - stage override float4 Shading() - { - return Intensity * base.Shading(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BackgroundVelocity.sdsl b/sources/shaders/assets/Stride/SDSL/BackgroundVelocity.sdsl deleted file mode 100644 index c8e0763b80..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BackgroundVelocity.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Computes screen space velocity for backgrounds -shader BackgroundVelocity : ShaderBase, VelocityStream, PositionStream4, ScreenPositionBase -{ - stage float4x4 DeltaMatrix; - - stage stream float4 currentShadingPosition; - stage stream float4 previousShadingPosition; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position.xyz, 1); - streams.currentShadingPosition = streams.Position; - streams.previousShadingPosition = mul(streams.ShadingPosition, DeltaMatrix); - base.VSMain(); - } - - stage override void PSMain() - { - streams.currentShadingPosition /= streams.currentShadingPosition.w; - streams.previousShadingPosition /= streams.previousShadingPosition.w; - float2 delta = (streams.currentShadingPosition - streams.previousShadingPosition).xy; - streams.velocity = delta; - base.PSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BakeLightProbeShader.sdsl b/sources/shaders/assets/Stride/SDSL/BakeLightProbeShader.sdsl deleted file mode 100644 index 46407dc092..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BakeLightProbeShader.sdsl +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.LightProbes -{ - // TODO: Inherit from SpriteBase; however we can't redefine SV_Target0 to have a different type due to ColorTarget being defined by ShaderBase => ShaderBaseStream - shader BakeLightProbeShader : PositionStream4, Texturing - { - // Default SV_POSITION output for VS/GS shaders - stage stream float4 ShadingPosition : SV_Position; - - stage stream uint LightProbeId : LIGHTPROBE_ID; - stage stream uint LightProbeIdOutput : SV_Target0; - - cbuffer PerDraw - { - stage float4x4 MatrixTransform; - } - - stage void VSMain() - { - streams.ShadingPosition = mul(streams.Position, MatrixTransform); - } - - stage void PSMain() - { - streams.LightProbeIdOutput = streams.LightProbeId; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BaseTestChild.sdsl b/sources/shaders/assets/Stride/SDSL/BaseTestChild.sdsl deleted file mode 100644 index 6989375ea0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BaseTestChild.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestChild : BaseTestInter -{ - override void test1() - { - base.test1(); - } - - override void test2() - { - this.test1(); - base.test2(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BaseTestInter.sdsl b/sources/shaders/assets/Stride/SDSL/BaseTestInter.sdsl deleted file mode 100644 index 3ca4eef00c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BaseTestInter.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestInter : BaseTestParent -{ - override void test1() - { - this.test2(); - base.test1(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BaseTestParent.sdsl b/sources/shaders/assets/Stride/SDSL/BaseTestParent.sdsl deleted file mode 100644 index b5bf42275b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BaseTestParent.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestParent -{ - void test1(){} - - void test2(){} -}; diff --git a/sources/shaders/assets/Stride/SDSL/BasicMixin.sdsl b/sources/shaders/assets/Stride/SDSL/BasicMixin.sdsl deleted file mode 100644 index 06fd04207b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BasicMixin.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BasicMixin -{ - float myFloat = 0.2f; - stage float3 myPosition : register(b); - stream float2 screenPosition : register(vs, b); - - abstract void myFunc(); - float myFunc2() - { - var a = myFloat; - return a; - } - abstract stage void myFunc3(); -}; diff --git a/sources/shaders/assets/Stride/SDSL/BasicMixin2.sdsl b/sources/shaders/assets/Stride/SDSL/BasicMixin2.sdsl deleted file mode 100644 index 6ebef4b2f8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BasicMixin2.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BasicMixin2 -{ - float myFloat = 0.2f; - - void myFunc4() {} -}; diff --git a/sources/shaders/assets/Stride/SDSL/BlendUtils.sdsl b/sources/shaders/assets/Stride/SDSL/BlendUtils.sdsl deleted file mode 100644 index fdab8ccb49..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BlendUtils.sdsl +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various helper functions to perform blending. -/// -shader BlendUtils -{ - // Performs an overlay operation between the two colors. - float4 Overlay(float4 col1, float4 col2) - { - // http://en.wikipedia.org/wiki/Blend_modes#Overlay - // if a < 0.5f: 2ab - // if a >= 0.5f: 1 - 2(1 - a)(1 - b) - return lerp(2.0f * col1 * col2, - 1.0f - 2.0f * (1.0f - col1) * (1.0f - col2), - step(col2, 0.5)); - } - - // Performs a blend operation between the three colors (RGB only). - float3 BasicColorBlend(float4 backColor, float4 frontColor, float3 interColor) - { - return frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb; - } - - // Performs a blend operation between the two alpha values. - float BasicAlphaBlend(float ba, float fa) - { - return lerp(fa, 1.0f, ba); - } - - // Performs a blend operation between the three colors. - float4 BasicBlend(float4 backColor, float4 frontColor, float3 interColor) - { - return float4(frontColor.a * backColor.a * interColor + frontColor.a*(1.0f-backColor.a) * frontColor.rgb + (1.0f-frontColor.a)*backColor.a * backColor.rgb, - lerp(frontColor.a, 1.0f, backColor.a)); - } - - // Performs a divide operation between the three colors (RGB only). - float3 ColorDivide(float3 t1, float3 t2) - { - // http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // Division - // "0/0" : 0 - // "t1/0" : 1 - // "t1/t2" : t1/t2 - - /*return lerp(t1 / t2, - 1.0 - Equals(t1, 0.0f), - Equals(t2, 0.0f));*/ - return lerp(t1 / t2, - 1.0 - step(t1, 0.0f), - step(t2, 0.0f)); - /*return lerp(t1 / t2, - 1.0 - step(abs(t1), 0.0f), - step(abs(t2), 0.0f));*/ - } - - // Compare each channel of the colors. - float3 Equals(float3 t1, float3 t2) - { - return step(abs(t1 - t2), 0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl b/sources/shaders/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl deleted file mode 100644 index a0a556a60c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BloomAfterimageCombineShader.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Combines persistence with current brightness. - /// Expects as input: - /// - Texture0: current brightness - /// - Texture1: persistence brightness - /// - internal shader BloomAfterimageCombineShader : ImageEffectShader - { - - stage override float4 Shading() - { - float3 currentColor = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - float3 persistenceColor = Texture1.Sample(PointSampler, streams.TexCoord).rgb; - - float3 result = max(currentColor, persistenceColor); - return float4(result, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BloomAfterimageShader.sdsl b/sources/shaders/assets/Stride/SDSL/BloomAfterimageShader.sdsl deleted file mode 100644 index 7a1ed8159f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BloomAfterimageShader.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Simulates retina persistence / afterimage with bright ghost slowly fading out. - /// - internal shader BloomAfterimageShader : ImageEffectShader - { - // Fade-out speed of the persistence image - stage float FadeOutSpeed; - - // How much sensitive we are to the bright light - stage float Sensitivity; - - stage override float4 Shading() - { - float3 currentColor = Texture0.Sample(LinearSampler, streams.TexCoord).rgb; - float3 persistenceColor = Texture1.Sample(LinearSampler, streams.TexCoord).rgb; - - persistenceColor *= FadeOutSpeed; - - var newPersistence = persistenceColor + currentColor * Sensitivity; - - // Never go brighter than the current brightness - if ( any(newPersistence > currentColor)) newPersistence = persistenceColor; - - return float4(newPersistence, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BrightFilterShader.sdsl b/sources/shaders/assets/Stride/SDSL/BrightFilterShader.sdsl deleted file mode 100644 index d45c30d67d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BrightFilterShader.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A bright filter shader - /// - internal shader BrightFilterShader : ImageEffectShader - { - [Color] - stage float3 ColorModulator; - - stage float BrightPassSteepness = 2.0f; - stage float ThresholdOffset = 0.2f; - - stage override float4 Shading() - { - float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - - // Calculate relative luminance - float luminance = LuminanceUtils.Luma(color); - - // method 1 - // Apply threshold - // float middle = luminance - ThresholdOffset; - // float range = 0.5f; - // float value = smoothstep(0, 1, saturate(middle * range)); - // color *= value; - - // method 2 - // color *= luminance < ThresholdOffset ? 0.0f : 1.0f; - - // method 3 - color *= smoothstep(0, 1, saturate(sqrt(luminance) / (BrightPassSteepness + 1) - ThresholdOffset)); - - return float4(color * ColorModulator, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BufferToTexture.sdsl b/sources/shaders/assets/Stride/SDSL/BufferToTexture.sdsl deleted file mode 100644 index 3459d6dc2b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BufferToTexture.sdsl +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader BufferToTexture : LocalSamples, ComputeShaderBase, VoxelPositionStream, DataPacking - { - stage RWBuffer VoxelFragments; - - stage float3 clipMapResolution; - - stage float storageUints; - - stage uint clipOffset; - - compose VoxelAttribute AttributesTemp[]; - compose VoxelAttribute AttributesIndirect[]; - - #ifndef IndirectStoreMacro - #define IndirectStoreMacro - #define IndirectReadAndStoreMacro - #endif - - override void Compute() - { - int3 clipMapResolutionI = (int3)clipMapResolution; - - uint3 pos = streams.DispatchThreadId.xyz; - pos.y = pos.y % clipMapResolutionI.y; - uint clipIndex = clipOffset + streams.DispatchThreadId.y/clipMapResolutionI.y; - - streams.PositionVXPS = pos; - streams.VoxelVolumeSize = clipMapResolutionI; - - uint wStride = clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z; - uint VoxelFragmentsIndex = clipIndex * wStride + pos.x + pos.y * clipMapResolutionI.x + pos.z * clipMapResolutionI.x * clipMapResolutionI.y; - VoxelFragmentsIndex *= (uint)storageUints; - - uint yStride = clipMapResolutionI.x * (uint)storageUints; - uint initialVoxelFragmentsIndex = VoxelFragmentsIndex; - - - - foreach (var attr in AttributesTemp) - attr.InitializeDummy(); - foreach (var attr in AttributesIndirect) - attr.InitializeDummy(); - - IndirectReadAndStoreMacro - - foreach (var attr in AttributesIndirect) - attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BufferToTextureColumns.sdsl b/sources/shaders/assets/Stride/SDSL/BufferToTextureColumns.sdsl deleted file mode 100644 index dbbeb691e7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BufferToTextureColumns.sdsl +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader BufferToTextureColumns : LocalSamples, ComputeShaderBase, VoxelPositionStream, DataPacking - { - [Link("BufferToTexture.VoxelFragments")] - stage RWBuffer VoxelFragments; - - [Link("BufferToTexture.clipMapResolution")] - stage float3 clipMapResolution; - - [Link("BufferToTexture.storageUints")] - stage float storageUints; - - [Link("BufferToTexture.clipOffset")] - stage uint clipOffset; - - - compose VoxelAttribute AttributesTemp[]; - compose VoxelAttribute AttributesIndirect[]; - - #ifndef IndirectStoreMacro - #define IndirectStoreMacro - #define IndirectReadAndStoreMacro - #endif - - override void Compute() - { - int3 clipMapResolutionI = (int3)clipMapResolution; - - uint3 pos = streams.DispatchThreadId.xyz; - uint clipIndex = streams.DispatchThreadId.y + clipOffset; - - pos.y = 0; - streams.PositionVXPS = pos; - streams.VoxelVolumeSize = clipMapResolutionI; - - uint wStride = clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z; - uint VoxelFragmentsIndex = clipIndex * wStride + pos.x + pos.y * clipMapResolutionI.x + pos.z * clipMapResolutionI.x * clipMapResolutionI.y; - VoxelFragmentsIndex *= (uint)storageUints; - - uint yStride = clipMapResolutionI.x * (uint)storageUints; - uint initialVoxelFragmentsIndex = VoxelFragmentsIndex; - - foreach (var attr in AttributesTemp) - attr.InitializeDummy(); - foreach (var attr in AttributesIndirect) - attr.InitializeDummy(); - - IndirectStoreMacro - - VoxelFragmentsIndex += (uint)storageUints * clipMapResolutionI.x; - - foreach (var attr in AttributesIndirect) - attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); - - streams.PositionVXPS.y++; - for (int i = 0; streams.PositionVXPS.y < clipMapResolutionI.y-1 ; streams.PositionVXPS.y ++) - { - uint VoxelFragmentsIndexOld = VoxelFragmentsIndex; - - //See VoxelStorageClipmaps.cs Line #307 - IndirectReadAndStoreMacro - - foreach (var attr in AttributesIndirect) - attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); - - VoxelFragmentsIndex = VoxelFragmentsIndexOld + (uint)storageUints * clipMapResolutionI.x; - } - foreach (var attr in AttributesTemp) - attr.InitializeDummy(); - - foreach (var attr in AttributesIndirect) - attr.InitializeDummy(); - - IndirectStoreMacro - - foreach (var attr in AttributesIndirect) - attr.DirectWrite(streams.PositionVXPS, clipIndex, (int)clipMapResolutionI.y); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl b/sources/shaders/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl deleted file mode 100644 index 52721bd0c3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BufferToTextureColumnsEffect.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - partial effect BufferToTextureColumnsEffect - { - using params BufferToTextureKeys; - - mixin BufferToTextureColumns; - if (BufferToTextureKeys.AttributesIndirect!=null) - { - foreach (var attr in BufferToTextureKeys.AttributesIndirect) - { - mixin compose AttributesIndirect += (attr); - } - } - if (BufferToTextureKeys.AttributesTemp!=null) - { - foreach (var attr in BufferToTextureKeys.AttributesTemp) - { - mixin compose AttributesTemp += (attr); - } - } - - mixin macro BufferToTextureKeys.IndirectReadAndStoreMacro; - mixin macro BufferToTextureKeys.IndirectStoreMacro; - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/BufferToTextureEffect.sdsl b/sources/shaders/assets/Stride/SDSL/BufferToTextureEffect.sdsl deleted file mode 100644 index c0bacbe926..0000000000 --- a/sources/shaders/assets/Stride/SDSL/BufferToTextureEffect.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - partial effect BufferToTextureEffect - { - using params BufferToTextureKeys; - - mixin BufferToTexture; - if (BufferToTextureKeys.AttributesIndirect!=null) - { - foreach (var attr in BufferToTextureKeys.AttributesIndirect) - { - mixin compose AttributesIndirect += (attr); - } - } - if (BufferToTextureKeys.AttributesTemp!=null) - { - foreach (var attr in BufferToTextureKeys.AttributesTemp) - { - mixin compose AttributesTemp += (attr); - } - } - - mixin macro BufferToTextureKeys.IndirectReadAndStoreMacro; - mixin macro BufferToTextureKeys.IndirectStoreMacro; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/C.sdsl b/sources/shaders/assets/Stride/SDSL/C.sdsl deleted file mode 100644 index fb03f434ea..0000000000 --- a/sources/shaders/assets/Stride/SDSL/C.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader C -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/C1.sdsl b/sources/shaders/assets/Stride/SDSL/C1.sdsl deleted file mode 100644 index 269864958f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/C1.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader C1 -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/Camera.sdsl b/sources/shaders/assets/Stride/SDSL/Camera.sdsl deleted file mode 100644 index a5c1672adf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Camera.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Camera -{ - cbuffer PerView { - // Camera Z NearClipPlane value. - stage float NearClipPlane = 1.0f; - // Camera Z FarClipPlane value. - stage float FarClipPlane = 100.0f; - // Z Retro projection factor used retro project a non-linear 1/z depth in the range [0.0 - 1.0] to a linear-depth in view space. - // Remarks: ZInViewSpace = ZProjection.y / (depth - ZProjection.x) - stage float2 ZProjection; - - // Camera View size - stage float2 ViewSize; - // Camera aspect ratio. - stage float AspectRatio; - }; -}; diff --git a/sources/shaders/assets/Stride/SDSL/CameraCube.sdsl b/sources/shaders/assets/Stride/SDSL/CameraCube.sdsl deleted file mode 100644 index 0962ada297..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CameraCube.sdsl +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Renders the geometry in the correct view for a cube map. -/// -shader CameraCube : PositionStream4, ShaderBase -{ - float3 CameraWorldPosition; - - float4x4 CameraViewProjectionMatrices[6]; - - stream uint RTAIndex : SV_RenderTargetArrayIndex; - - // flip render - [maxvertexcount(18)] - stage void GSMain(triangle Input input[3], inout TriangleStream triangleStream) - { - for (int i = 0; i < 6; ++i) - { - streams.RTAIndex = i; - - // TODO: verify that for OpenGL. This is likely to be wrong. Perhaps we don't have to change face winding. - for (int j = 0; j < 3; ++j) - { - streams = input[j]; - streams.ShadingPosition = mul(streams.PositionWS, CameraViewProjectionMatrices[i]); - triangleStream.Append(streams); - } - - triangleStream.RestartStrip(); - } - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl b/sources/shaders/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl deleted file mode 100644 index 461f20ab9b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CameraOrientationGizmoShader.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader CameraOrientationGizmoShader : ComputeColor, PositionStream4 -{ - override float4 Compute() - { - float yPosRemapped = pow((streams.PositionWS.y + 1) / 2, 3.5f); - return float4(0.6f, 0.6f, 0.6f, 1.0f) * yPosRemapped; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/Child.sdsl b/sources/shaders/assets/Stride/SDSL/Child.sdsl deleted file mode 100644 index f3527309d1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Child.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Child : Parent -{ - SamplerState childSampler; - Texture2D childTexture; - - override float AddBaseValue(float inValue) - { - childTexture.Sample(childSampler, float2(0.0f, 0.0f)); - parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); - Parent.parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); - return inValue + baseValue + base.AddBaseValue(inValue); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ChildError.sdsl b/sources/shaders/assets/Stride/SDSL/ChildError.sdsl deleted file mode 100644 index c7dc21c5e3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ChildError.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ChildError : Parent -{ - float AddBaseValue(float inValue) - { - return inValue + base.AddBaseValue(inValue); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CircleOfConfusion.sdsl b/sources/shaders/assets/Stride/SDSL/CircleOfConfusion.sdsl deleted file mode 100644 index 856d077158..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CircleOfConfusion.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Computes the Circle of Confusion map. - /// - shader CircleOfConfusion - { - // TODO Might want to replace this with a real formula from camera lens parameters, - // but for now we'll keep these simple parameters for easy debugging. - // [Near Start, Near End, Far Start, Far End] - stage float4 depthAreas; - - //Gets the circle of confusion strength for a certain depth. - float getCoCFactor(float linearDepth) - { - //CoC factor for the front area - float nearLength = max(depthAreas.y - depthAreas.x, 0.01f); - float nearCoC = 1.0 - saturate( (linearDepth - depthAreas.x) / nearLength); - - //CoC factor for the back area - float farLength = max(depthAreas.w - depthAreas.z, 0.01f); - float farCoC = saturate( (linearDepth - depthAreas.z) / farLength); - - float result = saturate(nearCoC + farCoC); - - // We need to be able to distinguish the out-of-focus near area from the far area. - if (linearDepth < depthAreas.y) result = -result; - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ClearBuffer.sdsl b/sources/shaders/assets/Stride/SDSL/ClearBuffer.sdsl deleted file mode 100644 index 2cc0e6b229..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ClearBuffer.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader ClearBuffer : ComputeShaderBase - { - stage RWBuffer buffer; - int offset; - override void Compute() - { - buffer[streams.DispatchThreadId.x + offset] = 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CloneTestBase.sdsl b/sources/shaders/assets/Stride/SDSL/CloneTestBase.sdsl deleted file mode 100644 index 63775da982..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CloneTestBase.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestBase -{ - stage void testFunc() {} -}; diff --git a/sources/shaders/assets/Stride/SDSL/CloneTestExtern.sdsl b/sources/shaders/assets/Stride/SDSL/CloneTestExtern.sdsl deleted file mode 100644 index ec06d0ee40..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CloneTestExtern.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestExtern : CloneTestBase -{ - override stage clone void testFunc() - { - base.testFunc(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CloneTestRoot.sdsl b/sources/shaders/assets/Stride/SDSL/CloneTestRoot.sdsl deleted file mode 100644 index ab31eb2406..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CloneTestRoot.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestRoot : CloneTestBase -{ - compose CloneTestExtern extern0; - compose CloneTestExtern extern1; - - override stage void testFunc() - { - base.testFunc(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CoCLinearDepthShader.sdsl b/sources/shaders/assets/Stride/SDSL/CoCLinearDepthShader.sdsl deleted file mode 100644 index 82b4dda9f2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CoCLinearDepthShader.sdsl +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Outputs CoC and linear depth. - /// Expects as input: - /// - Texture0: the raw depth-buffer used to render the original scene - /// - shader CoCLinearDepthShader : ImageEffectShader, Camera, CircleOfConfusion - { - - stage override float4 Shading() - { - // Linearizes the depth for view space - float depth = Texture0.Sample(Sampler, streams.TexCoord).x; - float linearDepth = ZProjection.y / (depth - ZProjection.x); - - // Debug: use this to visualize with a color in the [0, 1] range - // color = 1.0 - linearDepth / FarClipPlane; - - // Calculates the CoC based on the linearized depth - float CoC = getCoCFactor(linearDepth); - - return float4(CoC, linearDepth, 0.0, 0.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CoCMapBlurShader.sdsl b/sources/shaders/assets/Stride/SDSL/CoCMapBlurShader.sdsl deleted file mode 100644 index a4fdc018d7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CoCMapBlurShader.sdsl +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Blurs a CoC map but keeps sharp border around CoC == 0. - /// It prevents out-of-focus silhouette outline appearing in front of another out-of-focus object, - /// due to abrupt changes in the CoC transitions. - /// - /// - /// Number of weights. (And number of taps along one direction from the center.) - - shader CoCMapBlurShader : ImageEffectShader - { - // Direction to apply the blur. (normalized vector) - float2 Direction; - - // The radius of the blur to apply around the considered fragment - float Radius; - - // Weights of each tap - float2 OffsetsWeights[TBlurCount]; - - stage override float4 Shading() - { - float2 direction = Direction * Texture0TexelSize; - - // Add center - float2 centerCoCDepth = Texture0.Sample(LinearSampler, streams.TexCoord).xy; - //float centerDepth = centerCoCDepth.y; - float value = centerCoCDepth.x * OffsetsWeights[0].y; - - float totalWeight = OffsetsWeights[0].y; - - // Mirrored samples - [unroll] - for(int i = 1; i < TBlurCount; i++) - { - - [unroll] - for (int j = -1.0; j <= 1.0; j += 2) // Backward(-1) and forward(+1) along the direction - { - float2 tapCoCDepth = Texture0.Sample(LinearSampler, streams.TexCoord + j * direction * OffsetsWeights[i].x).xy; - - float contribution = 1.0; - - if ( tapCoCDepth.y <= centerCoCDepth.y ) { - // Pixel in the back should not accept a sample in front with CoC null. - contribution *= sign(tapCoCDepth.x); - } - else - { - // Pixel with CoC null should not accept any sample, except if the sample is in front. - // if (sign(centerCoCDepth.x) == 0) contribution = 0.0; - contribution = centerCoCDepth.x; - } - - contribution = saturate(contribution); - float tapWeight = OffsetsWeights[i].y * contribution; - value += tapCoCDepth.x * tapWeight; - totalWeight += tapWeight; - } - - } - - return float4(value / totalWeight, centerCoCDepth.y, 0.0, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ColorBase.sdsl b/sources/shaders/assets/Stride/SDSL/ColorBase.sdsl deleted file mode 100644 index 7792d17540..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ColorBase.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a color stream. -/// -shader ColorBase -{ - // A color attribute - stage stream float4 Color : COLOR; -}; diff --git a/sources/shaders/assets/Stride/SDSL/ColorCombinerShader.sdsl b/sources/shaders/assets/Stride/SDSL/ColorCombinerShader.sdsl deleted file mode 100644 index e282e3e5d4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ColorCombinerShader.sdsl +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A shader combiner - /// - internal shader ColorCombinerShader : ImageEffectShader - { - float Factors[10]; - - [Color] - float3 ModulateRGB[10]; - - stage override float4 Shading() - { - float3 color = 0; - if (count > 0) - color += Texture0.Sample(Sampler, streams.TexCoord).rgb * Factors[0] * ModulateRGB[0]; - if (count > 1) - color += Texture1.Sample(Sampler, streams.TexCoord).rgb * Factors[1] * ModulateRGB[1]; - if (count > 2) - color += Texture2.Sample(Sampler, streams.TexCoord).rgb * Factors[2] * ModulateRGB[2]; - if (count > 3) - color += Texture3.Sample(Sampler, streams.TexCoord).rgb * Factors[3] * ModulateRGB[3]; - if (count > 4) - color += Texture4.Sample(Sampler, streams.TexCoord).rgb * Factors[4] * ModulateRGB[4]; - if (count > 5) - color += Texture5.Sample(Sampler, streams.TexCoord).rgb * Factors[5] * ModulateRGB[5]; - if (count > 6) - color += Texture6.Sample(Sampler, streams.TexCoord).rgb * Factors[6] * ModulateRGB[6]; - if (count > 7) - color += Texture7.Sample(Sampler, streams.TexCoord).rgb * Factors[7] * ModulateRGB[7]; - if (count > 8) - color += Texture8.Sample(Sampler, streams.TexCoord).rgb * Factors[8] * ModulateRGB[8]; - if (count > 9) - color += Texture9.Sample(Sampler, streams.TexCoord).rgb * Factors[9] * ModulateRGB[9]; - - return float4(color, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ColorTransformGroupShader.sdsl b/sources/shaders/assets/Stride/SDSL/ColorTransformGroupShader.sdsl deleted file mode 100644 index 7f9b617453..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ColorTransformGroupShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Computes shading for all the groups of lights. -/// -shader ColorTransformGroupShader : ImageEffectShader -{ - compose ColorTransformShader Transforms[]; - - override stage float4 Shading() - { - float4 color = base.Shading(); - - foreach (var transform in Transforms) - { - color = transform.Compute(color); - } - return color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ColorTransformShader.sdsl b/sources/shaders/assets/Stride/SDSL/ColorTransformShader.sdsl deleted file mode 100644 index cf53d814ae..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ColorTransformShader.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A generic interface for processing/filtering a color. - /// - shader ColorTransformShader - { - float4 Compute(float4 color) - { - return color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ColorUtility.sdsl b/sources/shaders/assets/Stride/SDSL/ColorUtility.sdsl deleted file mode 100644 index 6d1f7af9bd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ColorUtility.sdsl +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ColorUtility -{ - // Converts an srgb color to linear space - float ToLinear(float sRGB) - { - // http://chilliant.blogspot.jp/2012/08/srgb-approximations-for-hlsl.html - return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878); - } - - // Converts an srgb color to linear space - float3 ToLinear(float3 sRGB) - { - return sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878); - } - - // Converts an srgb color to linear space - float4 ToLinear(float4 sRGBa) - { - float3 sRGB = sRGBa.rgb; - return float4(sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878), sRGBa.a); - } - - // simple screen gamma conversion - float4 GammaToLinear (float4 RGBa, float Gamma = 2.2) - { - RGBa.rgb = pow(RGBa.rgb, 1.0/Gamma); - return RGBa; - } - - float4 LinearToGamma (float4 RGBa, float Gamma = 2.2) - { - RGBa.rgb = pow(RGBa.rgb, Gamma); - return RGBa; - } - - //https://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html - // Converts an sRGB color to linear space - float4 SRgbToLinear(float4 sRGBa) - { - float3 sRGB = sRGBa.rgb; - return float4(sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878), sRGBa.a); - } - - // Converts an linear color to sRGB space - float4 LinearToSRgb(float4 RGBa) - { - float3 RGB = RGBa.rgb; - - float3 S1 = sqrt(RGB); - float3 S2 = sqrt(S1); - float3 S3 = sqrt(S2); - - return float4(0.662002687f * S1 + 0.684122060f * S2 - 0.323583601f * S3 - 0.0225411470f * RGB, RGBa.a); - } - - //https://github.com/vvvv/VL.Stride/pull/395#issuecomment-760253956 - // Converts a color from linear to sRGB - float4 LinearToSRgbPrecise(float4 RGBa) - { - float3 rgb = RGBa.rgb; - float3 higher = 1.055 * pow(rgb, 1.0/2.4) - 0.055; - float3 lower = rgb * 12.92f; - - float3 cutoff = step(rgb, 0.0031308); - RGBa.rgb = lerp(higher, lower, cutoff); - return RGBa; - } - - // Converts a color from sRGB to linear - float4 SRgbToLinearPrecise(float4 sRGBa) - { - float3 srgb = sRGBa.rgb; - float3 higher = pow((srgb + 0.055) / 1.055, 2.4); - float3 lower = srgb / 12.92; - - float3 cutoff = step(srgb, 0.04045); - sRGBa.rgb = lerp(higher, lower, cutoff); - return sRGBa; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CombineFrontCoCShader.sdsl b/sources/shaders/assets/Stride/SDSL/CombineFrontCoCShader.sdsl deleted file mode 100644 index 9510c3e829..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CombineFrontCoCShader.sdsl +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - - -namespace Stride.Rendering.Images -{ - - /// - /// Combines the different blur levels depending on the pixel's CoC. (Front area only.) - /// - shader CombineFrontCoCShader : ImageEffectShader - { - - stage override float4 Shading() - { - - // Fetch all our levels - float4 colorLevels[8]; - - // Note: Manually unrolled until better HLSL2GLSL support - if (TLevelCount >= 1) - colorLevels[0] = Texture2.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 2) - colorLevels[1] = Texture3.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 3) - colorLevels[2] = Texture4.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 4) - colorLevels[3] = Texture5.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 5) - colorLevels[4] = Texture6.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 6) - colorLevels[5] = Texture7.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 7) - colorLevels[6] = Texture8.Sample(LinearSampler, streams.TexCoord).rgba; - if (TLevelCount >= 8) - colorLevels[7] = Texture9.Sample(LinearSampler, streams.TexCoord).rgba; - - - float4 result = float4(0.0, 0.0, 0.0, 0.0); - - // Gets the CoC of the current pixel - float CoC = Texture0.Sample(LinearSampler, streams.TexCoord).x; - - // A front object has by default its in-focus color. - if (CoC < 0) result = colorLevels[0]; - - // Alpha blend all the layers in the good order - // TODO we should be more selective and only blend the layer closest to the pixel CoC - [unroll] - for (int k = 1; k < TLevelCount; k++) - { - float4 layerColor = colorLevels[k]; - float newAlpha = layerColor.a + result.a * (1.0 - layerColor.a); - float3 newRGB = float4(0.0, 0.0, 0.0, 0.0); - if (newAlpha > 0) - { - newRGB = (layerColor.rgb * layerColor.a + result.rgb * result.a * (1.0 - layerColor.a)) / newAlpha; - } - result = float4(newRGB, newAlpha); - } - - // Need pre-multiply alpha for the blending with the render target. - result.rgb *= result.a; - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl b/sources/shaders/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl deleted file mode 100644 index e87644859f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CombineLevelsFromCoCShader.sdsl +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Define to visualize debug colors for the different CoC levels. -#define DEBUG_COC_LEVEL_COLOR 0 - -namespace Stride.Rendering.Images -{ - /// - /// This takes in entry several blurred levels, and depending on the pixel CoC, - /// the final color will be an interpolation between 2 of these levels. - /// Level 0 is the original sharp image. The last level is the blurriest version. - /// Expects as input: - /// - Texture0: a [CoC, Linear Depth] buffer - /// - Texture1 ~ TextureX: the different blur levels. (0 == no blur) - /// - /// - /// Total number of layers used, including the original non-blurred image. - - shader CombineLevelsFromCoCShader : ImageEffectShader - { - // The CoC corresponding to each level of blur - stage float CoCLevelValues[TLevelCount]; - - stage override float4 Shading() - { - // Need to be able to access blur textures by index - //Texture2D dofTextureLevels[8] = - //{ - // Texture2, - // Texture3, - // Texture4, - // Texture5, - // Texture6, - // Texture7, - // Texture8, - // Texture9 - //}; - -#if DEBUG_COC_LEVEL_COLOR - // Some debug colors to visualize each layer - float3 debugColors[8] = - { - float3(1.0, 1.0, 1.0), - float3(0.5, 0.5, 1.0), - float3(0.5, 1.0, 0.5), - float3(1.0, 0.5, 0.5), - // Set more colors here - float3(1.0, 0.0, 0.0), - float3(1.0, 0.0, 0.0), - float3(1.0, 0.0, 0.0), - float3(1.0, 0.0, 0.0) - }; -#endif - - // Fetch all our levels - float3 colorLevels[8]; - - // Note: Manually unrolled until better HLSL2GLSL support - if (TLevelCount >= 1) - colorLevels[0] = Texture2.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 2) - colorLevels[1] = Texture3.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 3) - colorLevels[2] = Texture4.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 4) - colorLevels[3] = Texture5.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 5) - colorLevels[4] = Texture6.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 6) - colorLevels[5] = Texture7.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 7) - colorLevels[6] = Texture8.Sample(LinearSampler, streams.TexCoord).rgb; - if (TLevelCount >= 8) - colorLevels[7] = Texture9.Sample(LinearSampler, streams.TexCoord).rgb; - - [unroll] - for (int k = 0; k < TLevelCount; k++) - { - //colorLevels[k] = dofTextureLevels[k].Sample(LinearSampler, streams.TexCoord).rgb; -#if DEBUG_COC_LEVEL_COLOR - // Affects a debug color - colorLevels[k] *= debugColors[k]; -#endif - } - - // Gets the CoC of the current pixel - float CoC = abs(Texture0.Sample(LinearSampler, streams.TexCoord).x); - - // If the pixel is not in focus, use a blur version of the CoC to avoid sharp transitions - float blurredCoC = Texture1.Sample(LinearSampler, streams.TexCoord).x; - CoC = lerp(CoC, blurredCoC, sign(blurredCoC)); - - float3 result = float3(0.0, 0.0, 0.0); - - // We now find the 2 levels closest to the pixel CoC. - // We go down the levels, starting at the blurriest version. Once we find a level pair - // whose range contains our CoC, we keep the lerp between these 2 levels. - // (This part also supports a branch-less version.) - [unroll] - for (int i = TLevelCount - 2; i >= 0; i--) - { - // Current range we consider - float rangeMin = CoCLevelValues[i]; - float rangeMax = CoCLevelValues[i + 1]; - - // Does our CoC belong to this range? - float cocInRange = ((rangeMin < CoC && CoC <= rangeMax) || (rangeMin == CoC && rangeMin == 0))? 1.0 : 0.0; - // Here is the same test in a branch-less version for reference: - // float cocInRange = step(rangeMin, CoC) * step(CoC, rangeMax) * sign( abs(CoC - rangeMin)); - // cocInRange += (1.0 - sign(rangeMin)) * (1.0 - sign(CoC)); //Special edge-case for CoC 0 - - // We calculate the lerp factor between the 2 levels. - float lerpFactor = clamp( (CoC - rangeMin) / (rangeMax - rangeMin), 0.0, 1.0 ); // try smoothstep()? - - // We keep the lerp result only if the current level pair contains our CoC - result += cocInRange * lerp(colorLevels[i], colorLevels[i+1], lerpFactor); - } - - return float4( result, 1.0 ); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CompilationErrorShader.sdsl b/sources/shaders/assets/Stride/SDSL/CompilationErrorShader.sdsl deleted file mode 100644 index 688292ac4b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CompilationErrorShader.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader CompilationErrorShader : ShadingBase -{ - // method computing color - stage override float4 Shading() - { - float factor = sin(Global.Time * 6.0f) * 0.25f + 0.25f; - float4 errorColor = float4(1.0f, 0.25f, 0.25f, 1.0f); - - // High frequency glow to let user know effect is reloading - return lerp(base.Shading(), errorColor, factor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColor.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColor.sdsl deleted file mode 100644 index 3aeba9aa7e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColor.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Base shader to compute a color (float4). -/// -shader ComputeColor -{ - float4 Compute() - { - return 0; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColor3.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColor3.sdsl deleted file mode 100644 index 697d709006..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColor3.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Base shader to compute a color (float3). -/// -shader ComputeColor3 -{ - float3 Compute() - { - return 0; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorAdd.sdsl deleted file mode 100644 index 33c1befd38..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorAdd : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - return tex1.rgba + tex2.rgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3.sdsl deleted file mode 100644 index 5b32dba7e3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorAdd3 : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - return tex1.rgba + float4(tex2.rgb, 0.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl deleted file mode 100644 index 41f66b22fe..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorAdd3ds.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorAdd3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Add: - // r = fc + bc - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = frontColor.rgb + backColor.rgb; - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorAddMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorAddMaya.sdsl deleted file mode 100644 index ef218b08ad..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorAddMaya.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorAddMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Add: - // color = bc + (fc * fa) - // alpha = ba - // - - return float4(backColor.rgb + (frontColor.rgb * frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorAverage.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorAverage.sdsl deleted file mode 100644 index 9149b96a5c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorAverage.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorAverage : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Average: - // r = (fc + bc) /2 - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 averageColor = (frontColor.rgb + backColor.rgb) * 0.5f; - - return BlendUtils.BasicBlend(backColor, frontColor, averageColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorCave.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorCave.sdsl deleted file mode 100644 index b6f39902c2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorCave.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorCave : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - compose ComputeColor color3; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - float4 tex3 = color3.Compute(); - - float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); - float3 mix2 = mix1 * tex3.rgb; - - return float4(mix2, 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorColor.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorColor.sdsl deleted file mode 100644 index fe9336d0ce..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorColor.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorColor : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Color: - // if sat(fc) == 0 : color = val(bc), val(bc), val(bc) - // if sat(fc) != 0 : color = rgb(hue(fc), sat(fc), val(bc)) - // - // alpha = fa * (1-ba) + ba - - float3 color; - float frontSaturation = HSVUtils.GetSaturation(frontColor.rgb); - - if(frontSaturation == 0.0f) { - float valueResult = HSVUtils.GetValue(backColor.rgb); - color = float3(valueResult, valueResult, valueResult); - } else { - color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(frontColor.rgb), frontSaturation, HSVUtils.GetValue(backColor.rgb))); - } - - return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorColorBurn.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorColorBurn.sdsl deleted file mode 100644 index cfdfff98fb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorColorBurn.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorColorBurn : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // http://en.wikipedia.org/wiki/Blend_modes#Dodge_and_burn - // The Color Burn mode divides the inverted bottom layer by the top layer, and then inverts the result - return float4(1.0f - BlendUtils.ColorDivide((1.0f - backColor.rgb), frontColor.rgb), 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorColorDodge.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorColorDodge.sdsl deleted file mode 100644 index dab222b6ac..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorColorDodge.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorColorDodge : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtain with the above formula - // - // ColorDodge: - // if (fc == 1) : r = ceiling(bc) - // if (fc != 1) : r = bc / (1 - fc) in[0,1] - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = lerp(saturate(backColor.rgb / (1.0f - frontColor.rgb)), - ceil(backColor.rgb), - BlendUtils.Equals(frontColor.rgb, 1.0f)); - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl deleted file mode 100644 index ff61960f00..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantColorLink.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the color behind the key passed as generic. -/// -/// -/// LinkName: generic LinkType - the name of the key used to set the color. -/// -shader ComputeColorConstantColorLink : ComputeColor -{ - cbuffer PerMaterial - { - [Color] - [Link("LinkName")] - stage float4 constantColor; - } - - override float4 Compute() - { - return constantColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl deleted file mode 100644 index c7a13257a2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantFloatLink.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the color from a float behind the key passed as generic. -/// -/// -/// LinkName: generic LinkType - the name of the key used to set the float value. -/// -shader ComputeColorConstantFloatLink : ComputeColor -{ - cbuffer PerMaterial - { - [Link("LinkName")] - stage float constantFloat; - } - - override float4 Compute() - { - return float4(constantFloat, constantFloat, constantFloat, constantFloat); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantLink.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorConstantLink.sdsl deleted file mode 100644 index 53294cf6ef..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorConstantLink.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the color from a float4 behind the key passed as generic. -/// -/// -/// LinkName: generic LinkType - the name of the key used to set the float4. -/// -shader ComputeColorConstantLink : ComputeColor -{ - [Link("LinkName")] - stage float4 constantColor; - - override float4 Compute() - { - return constantColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl deleted file mode 100644 index 93e3499c1f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDarken3ds.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDarken3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Darken: - // color = min((1 - fa) * ba * bc + (fa * fc), (1 - ba) * fa * fc + (ba * bc)) - // alpha = fa * (1-ba) + ba - - return float4(min(lerp(backColor.a * backColor.rgb, frontColor.rgb, frontColor.a), lerp(frontColor.a * frontColor.rgb, backColor.rgb, backColor.a)), - BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl deleted file mode 100644 index 0a9e54e239..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDarkenMaya.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDarkenMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Darken: - // color = min(fc, bc) * fa + bc * (1 - fa) - // alpha = ba - - float3 min = min(frontColor.rgb, backColor.rgb); - - //return float4(lerp(backColor.rgb, min, frontColor.a), frontColor.a); - return float4(lerp(backColor.rgb, min, frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDesaturate.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDesaturate.sdsl deleted file mode 100644 index 42a5659201..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDesaturate.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDesaturate : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Desaturate: - // color = bc * (1 - (fc * fa)) - // alpha = ba - - return float4(backColor.rgb * (1.0f - (frontColor.rgb * frontColor.a)), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl deleted file mode 100644 index 5d01309282..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDifference3ds.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDifference3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // ColorDodge: - // r = abs(fc - bc) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = abs(frontColor.rgb - backColor.rgb); - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl deleted file mode 100644 index aae32624d6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDifferenceMaya.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDifferenceMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Difference: - // color = abs(fc - bc) * fa + bc * (1 - fa) - // alpha = ba - - float3 diff = abs(frontColor.rgb - backColor.rgb); - - return float4(lerp(backColor.rgb, diff, frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorDivide.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorDivide.sdsl deleted file mode 100644 index 7981fc646e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorDivide.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorDivide : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Divide: - // if (fc == 0 && bc == 0) : r = 0 - // if (fc == 0 && bc != 0) : r = 1 - // if (fc != 0) : r = bc / fc - // - // color = r - // alpha = fa * (1-ba) + ba - - float3 interColor = BlendUtils.ColorDivide(backColor.rgb, frontColor.rgb); - - return float4(interColor, - BlendUtils.BasicAlphaBlend(backColor.a,frontColor.a)); - } -}; - diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorExclusion.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorExclusion.sdsl deleted file mode 100644 index 7b61397816..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorExclusion.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorExclusion : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Exclusion: - // r = fc + bc - 2*(fc * bc) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = frontColor.rgb + backColor.rgb - 2.0f * frontColor.rgb * backColor.rgb ; - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorFixed.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorFixed.sdsl deleted file mode 100644 index 7945f29521..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorFixed.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns a fixed color. -/// -/// -/// TVALUE: generic float4 - the color (as a float4). -/// -shader ComputeColorFixed : ComputeColor -{ - override float4 Compute() - { - return TVALUE; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorFromStream.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorFromStream.sdsl deleted file mode 100644 index 6467552eca..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorFromStream.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Compute the color from a stream -/// -shader ComputeColorFromStream : ComputeColor -{ - stream float4 LocalColor : TStream; - - override float4 Compute() { - return saturate(streams.LocalColor.TRgba); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorHardLight.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorHardLight.sdsl deleted file mode 100644 index 31433e1f2f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorHardLight.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorHardLight : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // HardLight: - // if (fc < 0.5) : r = 2 * fc * bc - // if (fc >= 0.5) : r = 1 - 2*(1 - fc)*(1 - bc) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = lerp(2.0f * frontColor.rgb * backColor.rgb, - 1.0f - 2.0f * (1.0f - frontColor.rgb) * (1.0f - backColor.rgb), - step(0.5, frontColor.rgb)); - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorHardMix.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorHardMix.sdsl deleted file mode 100644 index fb8d585c2d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorHardMix.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorHardMix : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // HardMix: - // if (bc + fc) <= 1 : r = 0 (in 3DsMax, the case (bc + fc == 1) always return 0) - // if (bc + fc) > 1 : r = 1 - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = 1.0f - step(backColor.rbg + frontColor.rgb, 1.0f); - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorHue.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorHue.sdsl deleted file mode 100644 index 2ef9893ac8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorHue.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorHue : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Hue: - // if sat(fc) == 0 : color = val(bc), val(bc), val(bc) - // if sat(fc) != 0 : color = rgb(hue(fc), sat(bc), val(bc)) - // - // alpha = fa * (1-ba) + ba - - float3 color; - - if(HSVUtils.GetSaturation(frontColor.rgb) == 0.0f) { - float colorValue = HSVUtils.GetValue(backColor.rgb); - color = float3(colorValue, colorValue, colorValue); - } else { - color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(frontColor.rgb), HSVUtils.GetSaturation(backColor.rgb), HSVUtils.GetValue(backColor.rgb))); - } - - return float4(color, - BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorIlluminate.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorIlluminate.sdsl deleted file mode 100644 index 60917c1f4e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorIlluminate.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorIlluminate : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Illuminate: - // color = bc * (2 * fc * fa + 1 - fa) - // alpha = ba - - return float4(backColor.rgb * (2.0f * frontColor.rgb * frontColor.a + 1.0f - frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorIn.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorIn.sdsl deleted file mode 100644 index eafa39907e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorIn.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorIn : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // In: - // color = bc * fa - // alpha = ba * fa - - return backColor * frontColor.a; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl deleted file mode 100644 index d8233c19d5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorLerpAlpha.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorLerpAlpha : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); - - return float4(mix1, 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl deleted file mode 100644 index 0b56d9b25b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorLighten3ds.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorLighten3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Lighten: - // color = max((1 - fa) * ba * bc + (fa * fc), (1 - ba) * fa * fc + (ba * bc)) - // alpha = fa * (1-ba) + ba - - return float4(max(lerp(backColor.a * backColor.rgb, frontColor.rgb, frontColor.a), lerp(frontColor.a * frontColor.rgb, backColor.rgb, backColor.a)), - BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl deleted file mode 100644 index d637a2bda6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorLightenMaya.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorLightenMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Lighten: - // color = max(fc, bc) * fa + bc * (1 - fa) - // alpha = ba - - float3 maxColor = max(frontColor.rgb, backColor.rgb); - - return float4(lerp(backColor.rgb, maxColor, frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl deleted file mode 100644 index a1d8995fa5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorLinearBurn.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorLinearBurn : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // LinearBurn: - // if (bc + fc) <= 1 : r = 0 - // if (bc + fc) > 1 : r = fc + bc - 1 - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = lerp(frontColor.rgb + backColor.rgb - 1.0f, - 0.0f, - step(1.0f , (frontColor.rbg + backColor.rgb))); - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; - - diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl deleted file mode 100644 index bd508fd77c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorLinearDodge.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorLinearDodge : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Linear Dodge: - // r = fc + bc in [0,1] - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = saturate(frontColor.rgb + backColor.rgb); - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMask.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMask.sdsl deleted file mode 100644 index fc1e2a24a4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMask.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -//shader ComputeColorDifference3ds : ComputeColor -shader ComputeColorMask : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 mask = color2.Compute(); - - // t = texture, m = mask, c = color, a = alpha - // - // Mask: - // color = tc - // alpha = ta * avg(mc) - - return float4(backColor.rgb, - backColor.a * (mask.r + mask.g + mask.b) / 3.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMask3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMask3ds.sdsl deleted file mode 100644 index ca606c7992..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMask3ds.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -//shader ComputeColorDifference3ds : ComputeColor -shader ComputeColorMask3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor maskColor; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 mask = maskColor.Compute(); - - // t = texture, m = mask, c = color, a = alpha - // - // Mask: - // color = tc - // alpha = ta * avg(mc) - - return float4(backColor.rgb, - backColor.a * (mask.r + mask.g + mask.b) / 3.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl deleted file mode 100644 index 8bea684ed4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMaterialAlphaBlend.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader ComputeColorMaterialAlphaBlend : ComputeColor, MaterialPixelStream -{ - compose ComputeColor color; - - override float4 Compute() - { - var alpha = 2.0 * color.Compute().x; - float specularFactor = min(1, alpha); - float diffuseFactor = max(0, alpha - 1.0); - return float4(diffuseFactor, specularFactor, 0, 0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply.sdsl deleted file mode 100644 index 1ca85eb525..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorMultiply : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - float4 mix1 = tex1 * tex2; - - return mix1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl deleted file mode 100644 index dc66cd54d8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiply3ds.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorMultiply3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Multiply: - // r = fc * bc - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 interColor = frontColor.rgb * backColor.rgb; - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl deleted file mode 100644 index b8c3f7b197..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorMultiplyMaya.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorMultiplyMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Multiply: - // color = bc * (fc * fa + 1 - fa) - // alpha = ba - - return float4(backColor.rgb * (frontColor.rgb * frontColor.a + 1.0f - frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOne.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOne.sdsl deleted file mode 100644 index 0e7819dca3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOne.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the white opaque color. -/// -shader ComputeColorOne : ComputeColor -{ - override float4 Compute() - { - return 1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOut.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOut.sdsl deleted file mode 100644 index 617312f11b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOut.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOut : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Out: - // color = bc * (1 - fa) - // alpha = ba * (1 - fa) - - return backColor * (1.0f - frontColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOutdoor.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOutdoor.sdsl deleted file mode 100644 index 5ad4861e0e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOutdoor.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOutdoor : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - compose ComputeColor color3; - compose ComputeColor color4; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - float4 tex3 = color3.Compute(); - - float3 mix1 = lerp(tex1.rgb, tex2.rgb, tex2.a); - float3 mix2 = lerp(mix1.rgb, tex3.rgb, tex3.a); - - return float4(mix2, 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOver3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOver3ds.sdsl deleted file mode 100644 index a4af3073df..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOver3ds.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOver3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Over: - // r = fc - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - return BlendUtils.BasicBlend(backColor, frontColor, frontColor.rgb); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOverMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOverMaya.sdsl deleted file mode 100644 index 33da6e6d7e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOverMaya.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOverMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Over: - // color = bc + ((fc - bc) * fa) = (1 - fa) * bc + fa * fc - // alpha = ba + fa - (ba * fa) - // - - return float4(lerp(backColor.rgb, frontColor.rgb, frontColor.a), - BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay.sdsl deleted file mode 100644 index a8095b46eb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOverlay : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - // http://en.wikipedia.org/wiki/Blend_modes#Overlay - // if a < 0.5f: 2ab - // if a >= 0.5f: 1 - 2(1 - a)(1 - b) - return lerp(2.0f * tex1 * tex2, - 1.0f - 2.0f * (1.0f - tex1) * (1.0f - tex2), - step(tex2, 0.5)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl deleted file mode 100644 index 74346a94c8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorOverlay3ds.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorOverlay3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Overlay: - // if bc < 0.5 : r = 2fc * bc - // if bc >= 0.5 : r = 1 - 2(1 - fc)(1 - bc) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = lerp(2.0f * frontColor.rgb * backColor.rgb, - 1.0f - 2.0f * (1.0f - frontColor.rgb) * (1.0f - backColor.rgb), - step(backColor.rgb, 0.5f)); - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorParameter.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorParameter.sdsl deleted file mode 100644 index 1bd60ba73a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorParameter.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the color from a parameter. -/// -shader ComputeColorParameter : ComputeColor -{ - [Color] - stage float4 ColorParameter; - - override float4 Compute() - { - return ColorParameter; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorPinLight.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorPinLight.sdsl deleted file mode 100644 index 02e95946e1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorPinLight.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorPinLight : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // PinLight: - // if fc <= 0.5 : r = min(bc, 2fc) - // if fc > 0.5 : r = max(bc, (2fc - 1)) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = lerp(max(backColor.rgb, (2.0f * frontColor.rgb - 1.0f)), - min(backColor.rgb, 2.0f * frontColor.rgb), - step(frontColor.rgb, 0.5f)); - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorRadial.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorRadial.sdsl deleted file mode 100644 index acfea5db73..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorRadial.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// This is a little more complex example which you can use -// Refer to the Radial Partical System in the Editor -// Under Material it uses a Shader for its Emissive color, and the shader's name is ComputeColorRadial -// In addition to ComputeColor this shader also inherits Texturing so it can use texture coordinates -// ColorCenter and ColorEdge are design time permutations and appear in the shader dictionary when you choose ComputeColorRadial from the proeprty grid - -shader ComputeColorRadial : ComputeColor, Texturing -{ - override float4 Compute() - { - float radialDistance = length(streams.TexCoord - float2(0.5, 0.5)) * 2; - - float4 unclamped = lerp(ColorCenter, ColorEdge, radialDistance); - - // We want to allow the intensity to grow a lot, but cap the alpha to 1 - float4 clamped = clamp(unclamped, float4(0, 0, 0, 0), float4(1000, 1000, 1000, 1)); - - // Remember that we use a premultiplied alpha pipeline so all color values should be premultiplied - clamped.rgb *= clamped.a; - - return clamped; - } -}; - diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorRed.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorRed.sdsl deleted file mode 100644 index 5435bcb468..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorRed.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// This is the simplest way of overriding particle shader behavior -// Refer to the Red Particle System in the Editor -// Under Material it uses a Shader for its Emissive color, and the shader's name is ComputeColorRed -// As long as your shader inherits ComputeColor and overrides float4 Compute() you can add any custom behavior to it - -shader ComputeColorRed : ComputeColor -{ - override float4 Compute() - { - return float4(1, 0, 0, 1); - } -}; - diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSaturate.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSaturate.sdsl deleted file mode 100644 index 32e01a3676..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSaturate.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSaturate : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Saturate: - // color = bc * (1 + (fc * fa)) - // alpha = ba - - return float4(backColor.rgb * (1.0f + (frontColor.rgb * frontColor.a)), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSaturation.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSaturation.sdsl deleted file mode 100644 index d0777e1e06..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSaturation.sdsl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSaturation : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Saturation: - // if sat(bc) == 0 : color = val(bc), val(bc), val(bc) - // if sat(bc) != 0 : color = rgb(hue(bc), sat(fc), val(bc)) - // - // alpha = fa * (1-ba) + ba - - float3 color; - float backSaturation = HSVUtils.GetSaturation(backColor.rgb); - if( backSaturation == 0.0f) { - float colorValue = HSVUtils.GetValue(backColor.rgb); - color = float3(colorValue, colorValue, colorValue); - } else { - color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(backColor.rgb), HSVUtils.GetSaturation(frontColor.rgb), HSVUtils.GetValue(backColor.rgb))); - } - - return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorScaler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorScaler.sdsl deleted file mode 100644 index 58f41d9ac2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorScaler.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorScaler : ComputeColor -{ - override float4 Compute() - { - float4 baseColor = base.Compute(); - // TODO Check where to put gamma correction? => float tempScaleValue = pow(TScaleValue, 2.2) - // USe faster 2.0 instead of 2.2 - return float4(baseColor.xyz * TScaleValue * TScaleValue, baseColor.w); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorScreen.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorScreen.sdsl deleted file mode 100644 index 79c4e36b1e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorScreen.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorScreen : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha - // - // Screen: - // color = fc * fa * (1 - bc * ba) + bc * ba - // alpha = fa * (1-ba) + ba - - return float4(frontColor.rgb * frontColor.a * (1.0f - backColor.rgb * backColor.a) + backColor.rgb * backColor.a, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSoftLight.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSoftLight.sdsl deleted file mode 100644 index 45157e6c49..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSoftLight.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSoftLight : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // SoftLight: - // if fc < 0.5 : r = bc(1 + (1 - bc)(2fc - 1)) - // else if bc < 9/64 : r = bc(bc(9 - 18fc) + 5.76fc - 1.88) - // else : r = bc + (sqrt(bc) - bc)(2fc - 1) - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r1 = backColor.rgb * (1.0f + (1.0f - backColor.rgb) * (2.0f * backColor.rgb -1.0f)); - float3 r2 = backColor.rgb * (backColor.rgb * (9.0f - 18.0f * frontColor.rgb) + 5.76f *frontColor.rgb -1.88f); - float3 r3 = backColor.rgb + (sqrt(backColor.rgb) - backColor.rgb) * (2.0f * frontColor.rgb - 1.0f); - - float interColor = lerp( r1, - lerp(r2, - r3, - step(9.0f / 64.0f, backColor.rgb)), - step(0.5f, frontColor.rgb)); - - return BlendUtils.BasicBlend(backColor, frontColor, interColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorStream.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorStream.sdsl deleted file mode 100644 index 75a3db6de4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorStream.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Returns the color attribute of the mesh. -/// -shader ComputeColorStream : ComputeColor, ColorBase -{ - override float4 Compute() { - return streams.Color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl deleted file mode 100644 index 54bf3be179..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlpha.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSubstituteAlpha : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - return float4(tex1.rgb, tex2.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl deleted file mode 100644 index 1af92e63ee..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSubstituteAlphaWithColor.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSubstituteAlphaWithColor : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 tex1 = color1.Compute(); - float4 tex2 = color2.Compute(); - - return float4(tex1.rgb, tex2.r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract.sdsl deleted file mode 100644 index af3e077af0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSubtract : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - return backColor - frontColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl deleted file mode 100644 index 088a73a9d2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtract3ds.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSubtract3ds : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Add: - // r = bc - fc - // - // color = (fa * ba) * r + (fa * (1-ba)) * fc + ((1-fa) * ba) * bc - // alpha = fa * (1-ba) + ba - - float3 r = backColor.rgb - frontColor.rgb; - - return BlendUtils.BasicBlend(backColor, frontColor, r); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl deleted file mode 100644 index 0a2c5e1322..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSubtractMaya.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSubtractMaya : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From Maya API (LayeredTexture node) - // - // b = background, f = foreground, c = color, a = alpha - // - // Subtract: - // color = bc - (fc * fa) - // alpha = ba - - return float4(backColor.rgb - (frontColor.rgb * frontColor.a), - backColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorSynthetic.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorSynthetic.sdsl deleted file mode 100644 index fe4e3986d6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorSynthetic.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSynthetic : ComputeColor -{ - override float4 Compute() - { - return Material.SpecularColorValue; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTexture.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTexture.sdsl deleted file mode 100644 index 08b82a0651..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTexture.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with default sampler. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// -shader ComputeColorTexture : ComputeColor -{ - stage stream float2 TexCoord : TStream; - - override float4 Compute() - { - return TTexture.Sample(Texturing.Sampler, streams.TexCoord); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl deleted file mode 100644 index 71f22298b2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureDynamicScaledOffset.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with default sampler wit a scale and an offset. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// -shader ComputeColorTextureDynamicScaledOffset : ComputeColor -{ - stage stream float2 TexCoord : TStream; - - // ------------------------------------- - // uniforms - // ------------------------------------- - stage float2 Offset = float2(0,0); - stage float2 Scale = float2(1,1); - - override float4 Compute() - { - return TTexture.Sample(Texturing.Sampler, streams.TexCoord * Scale + Offset); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl deleted file mode 100644 index 6fd51fd12f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodSampler.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TSampler: generic SamplerState - the sampler. -/// -shader ComputeColorTextureLodSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() - { - return Texture.SampleLevel(Sampler, streams.TexCoord, TLod).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl deleted file mode 100644 index e5e84675f9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetDynamicSampler.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. -/// TOffset: generic LinkType - the float2 key for texture coordinates offset. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureLodScaledOffsetDynamicSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - cbuffer PerMaterial - { - [Link("TScale")] - stage float2 scale; - - [Link("TOffset")] - stage float2 offset; - } - - override float4 Compute() { - return Texture.SampleLevel(Sampler, streams.TexCoord * scale + offset, TLod).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl deleted file mode 100644 index 780d3fdd90..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledOffsetSampler.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// TOffset: generic float2 - the texture coordinates offset. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureLodScaledOffsetSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() { - return Texture.SampleLevel(Sampler, streams.TexCoord * TScale + TOffset, TLod).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl deleted file mode 100644 index a6aeef0282..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureLodScaledSampler.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureLodScaledSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() - { - return Texture.SampleLevel(Sampler, streams.TexCoord * TScale, TLod).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl deleted file mode 100644 index fbe8671779..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureRepeat.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a repeated texture with default sampler. Default sampler should be on repeat for this shader to behave correctly. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TFactor: generic float - the repeat factor. -/// -shader ComputeColorTextureRepeat : ComputeColor -{ - stage stream float2 TexCoord : TStream; - - override float4 Compute() - { - return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TFactor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl deleted file mode 100644 index 621a08f55b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureSampler.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TSampler: generic SamplerState - the sampler. -/// -shader ComputeColorTextureSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() - { - return Texture.Sample(Sampler, streams.TexCoord).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl deleted file mode 100644 index 9ec08a6df8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaled.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with the default sampler and fix texture coordinates scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// -shader ComputeColorTextureScaled : ComputeColor -{ - stream float2 TexCoord : TStream; - - override float4 Compute() { - return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TScale); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl deleted file mode 100644 index 72c6de2899..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffset.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with the default sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// TOffset: generic float2 - the texture coordinates offset. -/// -shader ComputeColorTextureScaledOffset : ComputeColor -{ - stream float2 TexCoord : TStream; - - override float4 Compute() { - return TTexture.Sample(Texturing.Sampler, streams.TexCoord * TScale + TOffset); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl deleted file mode 100644 index 1b8063fb58..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSampler.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. -/// TOffset: generic LinkType - the float2 key for texture coordinates offset. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureScaledOffsetDynamicSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - cbuffer PerMaterial - { - [Link("TScale")] - stage float2 scale; - - [Link("TOffset")] - stage float2 offset; - } - - override float4 Compute() { - return Texture.Sample(Sampler, streams.TexCoord * scale + offset).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl deleted file mode 100644 index 888db62590..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetDynamicSamplerRandomUV.sdsl +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic LinkType - the float2 key for scaling factor of the texture coordinates. -/// TOffset: generic LinkType - the float2 key for texture coordinates offset. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureScaledOffsetDynamicSamplerRandomUV : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - cbuffer PerMaterial - { - [Link("TScale")] - stage float2 scale; - - [Link("TOffset")] - stage float2 offset; - } - - //------------------------------------------------------------------------------ - // Gererate pseudorandom number - //------------------------------------------------------------------------------ - float Random(in float2 uv) - { - float2 noise = (frac(sin(dot(uv,float2(12.9898,78.233)*2.0)) * 43758.5453)); - return abs(noise.x + noise.y) * 0.5; - } - - //------------------------------------------------------------------------------ - // Gererate texture coordinates for random placement - //------------------------------------------------------------------------------ - float2 RandomUV(in float2 uv) - { - const uint NUM_PATTERNS = 2 * 2 * 4 * 4 * 4; - - uint pattern = (uint)(Random(floor(uv)) * (float)NUM_PATTERNS) % NUM_PATTERNS; - float2 result = frac(uv); - - // flip - if ((uint)(pattern % 2) != 0) - { - result.x = 1.0f - result.x; - } - pattern /= 2; - if ((uint)(pattern % 2) != 0) - { - result.y = 1.0f - result.y; - } - - // rotate - pattern /= 2; - if (pattern % 4 == 1) - { - result = float2(result.y, 1.0f - result.x); - } - else if (pattern % 4 == 2) - { - result = float2(1.0f - result.y, result.x); - } - else if (pattern % 4 == 3) - { - result = 1.0f - result; - } - - // offset - pattern /= 4; - result.x += (pattern % 4) * 0.25f; - pattern /= 4; - result.y += (pattern % 4) * 0.25f; - - return result; - } - - override float4 Compute() { - return Texture.Sample(Sampler, RandomUV(streams.TexCoord * scale + offset)).TRgba; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl deleted file mode 100644 index 7a4544e901..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledOffsetSampler.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates offset and scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// TOffset: generic float2 - the texture coordinates offset. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureScaledOffsetSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() { - return Texture.Sample(Sampler, streams.TexCoord * TScale + TOffset).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl deleted file mode 100644 index e38a15f60a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScaledSampler.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Samples a texture with a custom sampler and fix texture coordinates scale. -/// -/// -/// TTexture: generic Texture2D - the texture to sample. -/// TStream: generic Semantic - the texcoord index semantic used to sample the texture. -/// TScale: generic float2 - the scaling factor of the texture coordinates. -/// TSampler: generic SamplerState - the custom sampler. -/// -shader ComputeColorTextureScaledSampler : ComputeColor, - DynamicTexture, - DynamicSampler, - DynamicTextureStream -{ - override float4 Compute() - { - return Texture.Sample(Sampler, streams.TexCoord * TScale).TRgba; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl deleted file mode 100644 index 85e1147ac7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorTextureScroll.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Only works properly for ProceduralCylinder! -// You will have to customize it to handle other shapes if they are required. -shader ComputeColorTextureScroll : ComputeColor, Texturing -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Position : POSITION; - - // Only works properly for ProceduralCylinder! - // You will have to customize it to handle other shapes if they are required. - override float4 Compute() - { - streams.TexCoord.y += Global.Time * UvSpeed; - - float alpha = 1 - 10 * (abs(streams.Position.y) - 0.4f); - - return float4(alpha * colorIntensity, alpha * colorIntensity, alpha * colorIntensity, alpha); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorThreshold.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorThreshold.sdsl deleted file mode 100644 index 1be707487e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorThreshold.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorThreshold : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 baseColor = color1.Compute(); - float4 maskColor = color2.Compute(); - - return float4( - smoothstep(maskColor.r, maskColor.r, baseColor.r), - smoothstep(maskColor.g, maskColor.g, baseColor.g), - smoothstep(maskColor.b, maskColor.b, baseColor.b), - smoothstep(maskColor.a, maskColor.a, baseColor.a) - ); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorValue.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorValue.sdsl deleted file mode 100644 index a284b9e166..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorValue.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorValue : ComputeColor -{ - compose ComputeColor color1; - compose ComputeColor color2; - - override float4 Compute() - { - float4 backColor = color1.Compute(); - float4 frontColor = color2.Compute(); - - // From http://msdn.microsoft.com/en-us/library/windows/desktop/hh706313(v=vs.85).aspx - // - // b = background, f = foreground, c = color, a = alpha, r = result color obtained with the specific blend formula - // - // Value : - // if sat(bc) == 0 : color = val(bc), val(bc), val(bc) - // if sat(bc) != 0 : color = rgb(hue(bc), sat(bc), val(fc)) - // - // alpha = fa * (1-ba) + ba - - float3 color; - - if(HSVUtils.GetSaturation(backColor.rgb) == 0.0f) - color = float3(HSVUtils.GetValue(backColor.rgb)); - else - color = HSVUtils.ToRGB(float3(HSVUtils.GetHue(backColor.rgb), HSVUtils.GetSaturation(backColor.rgb), HSVUtils.GetValue(frontColor.rgb))); - - return float4(color, BlendUtils.BasicAlphaBlend(backColor.a, frontColor.a)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorWave.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorWave.sdsl deleted file mode 100644 index 457be899b7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorWave.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader ComputeColorWave : ComputeColor, Texturing -{ - override float4 Compute() - { - float phase = length(streams.TexCoord - 0.5); - return sin((phase + Global.Time * Speed) * 2 * 3.14 * Frequency) * Amplitude; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl deleted file mode 100644 index 5d899f7df7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorWaveNormal.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader ComputeColorWaveNormal : ComputeColor, Texturing -{ - override float4 Compute() - { - float2 offset = streams.TexCoord - 0.5; - float phase = length(offset); - - float derivative = cos((phase + Global.Time * Speed) * 2 * 3.14 * Frequency) * Amplitude; - - float2 xz = SincosOfAtan(offset.y / offset.x); - float2 xy = SincosOfAtan(derivative); - - float3 normal; - normal.xy = (xz.yx * sign(offset.x) * -xy.x) * 0.5 + 0.5; - normal.z = xy.y; - return float4(normal, 1); - } - - float2 SincosOfAtan(float x) - { - return float2(x, 1) / sqrt(1 + x * x); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeColorWhite.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeColorWhite.sdsl deleted file mode 100644 index f93b21ffd5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeColorWhite.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Particles.Shaders -{ - shader ComputeColorWhite : ComputeColor - { - override float4 Compute() - { - return float4(1, 1, 1, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ComputeShaderBase.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeShaderBase.sdsl deleted file mode 100644 index 552b1162ea..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeShaderBase.sdsl +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Base compute shader. -/// -/// -/// ThreadNumberX: Macro - number of threads on the X axis. -/// ThreadNumberY: Macro - number of threads on the Y axis. -/// ThreadNumberZ: Macro - number of threads on the Z axis. -/// -#ifndef ThreadNumberX -# define ThreadNumberX 1 -#endif -#ifndef ThreadNumberY -# define ThreadNumberY 1 -#endif -#ifndef ThreadNumberZ -# define ThreadNumberZ 1 -#endif -shader ComputeShaderBase -{ - stage stream uint3 GroupId : SV_GroupID; - stage stream uint3 DispatchThreadId : SV_DispatchThreadID; - stage stream uint3 GroupThreadId : SV_GroupThreadID; - stage stream uint GroupIndex : SV_GroupIndex; - - stage stream uint3 ThreadGroupCount; - stage stream uint ThreadCountPerGroup; - stage stream uint ThreadGroupIndex; - - stage stream int ThreadCountX; - stage stream int ThreadCountY; - stage stream int ThreadCountZ; - - cbuffer PerDispatch { - // This variable provides the ThreadGroupCount from the dispatch method - [Link("ComputeShaderBase.ThreadGroupCountGlobal")] - stage int3 ThreadGroupCountGlobal; - }; - - [numthreads(ThreadNumberX, ThreadNumberY, ThreadNumberZ)] - void CSMain() - { - // give access to ThreadCounts everywhere in the shader - streams.ThreadCountX = ThreadNumberX; - streams.ThreadCountY = ThreadNumberY; - streams.ThreadCountZ = ThreadNumberZ; - - // Predefined variable that gives the number of threads per group - streams.ThreadCountPerGroup = ThreadNumberX * ThreadNumberY * ThreadNumberZ; - - // Copy the global variable to the stream to make it consistent - streams.ThreadGroupCount = ThreadGroupCountGlobal; - - // Calculate a unique thread group index, an index that identifies a unique group of thread from a dispatch - streams.ThreadGroupIndex = (streams.GroupId.z * streams.ThreadGroupCount.y + streams.GroupId.y) * streams.ThreadGroupCount.x + streams.GroupId.x; - - Compute(); - } - - void Compute() - { - } - - bool IsFirstThreadOfGroup() - { - return streams.GroupThreadId.x == 0 && streams.GroupThreadId.y == 0 && streams.GroupThreadId.z == 0; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ComputeShaderTest.sdsl b/sources/shaders/assets/Stride/SDSL/ComputeShaderTest.sdsl deleted file mode 100644 index e203546927..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ComputeShaderTest.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Graphics.Tests -{ - /// - /// A shader performing Lambertian pre-filtering. - /// - internal shader ComputeShaderTest: ComputeShaderBase - { - stage Texture2D input; - stage RWTexture2D output; - - override void Compute() - { - float4 Sum = float4(0,0,0,0); - - [unroll] - for(int i=0; i - /// Base shader to sample an environment - /// - shader ComputeSphericalHarmonics : SphericalHarmonicsUtils, ComputeColor, NormalStream - { - cbuffer PerMaterial - { - [Color] - stage float3 SphericalColors[TOrder * TOrder]; - } - - override float4 Compute() - { - var direction = float3(streams.normalWS.xy, -streams.normalWS.z); - - return EvaluateSphericalHarmonics(SphericalColors, direction); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ConstantBufferTest.sdsl b/sources/shaders/assets/Stride/SDSL/ConstantBufferTest.sdsl deleted file mode 100644 index fd0251196e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ConstantBufferTest.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ConstantBufferTest -{ - cbuffer PerVertex - { - float a; - float c; - }; - - cbuffer PerVertex - { - float b; - }; - - cbuffer PerPixel - { - float d; - }; - - float e; -}; diff --git a/sources/shaders/assets/Stride/SDSL/CubemapSprite.sdsl b/sources/shaders/assets/Stride/SDSL/CubemapSprite.sdsl deleted file mode 100644 index 1daa80a24a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CubemapSprite.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader CubemapSprite : SpriteEffect, Texturing -{ - stage float ViewIndex; - - // Shading of the sprite - stage override float4 Shading() - { - return TextureCube0.Sample(Sampler, CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, ViewIndex)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CubemapUtils.sdsl b/sources/shaders/assets/Stride/SDSL/CubemapUtils.sdsl deleted file mode 100644 index a557c845d5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CubemapUtils.sdsl +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Cubemap -{ - /// - /// Utilities functions for cubemap sampling. - /// - shader CubemapUtils - { - // TODO: this might change on OpenGL - - // This is for indirect coordinate system cubemap sampling = Direct3D - // ________ ________ ________ ________ ________ ________ - // | y | y | ___x | z | y | y | - // | | | | | | | | | | | | | - // | z___| | |___z | | | |___x | |___x | x___| | - // | | | z | | | | - // |________|________|________|________|________|________| - // face X face -X face Y face -Y face Z face -Z - // - float3 ConvertTexcoordsNoFlip(float2 inputTexcoord, int viewIndex) - { - float2 position = 2 * inputTexcoord - 1; - - if (viewIndex == 0) - return float3(1, -position.y, -position.x); // face X - if (viewIndex == 1) - return float3(-1, -position.y, position.x); // face -X - if (viewIndex == 2) - return float3(position.x, 1, position.y); // face Y - if (viewIndex == 3) - return float3(position.x, -1, -position.y); // face -Y - if (viewIndex == 4) - return float3(position.x, -position.y, 1); // face Z - if (viewIndex == 5) - return float3(-position.x, -position.y, -1); // face -Z - - return 0; - } - - float3 ConvertTexcoordsFlip(float2 inputTexcoord, int viewIndex) - { - float2 position = float2(2, -2) * inputTexcoord + float2(-1, 1); - - if (viewIndex == 0) - return float3(1, position.y, position.x); // face X - if (viewIndex == 1) - return float3(-1, position.y, -position.x); // face -X - if (viewIndex == 2) - return float3(position.x, 1, -position.y); // face Y - if (viewIndex == 3) - return float3(-position.x, -1, position.y); // face -Y - if (viewIndex == 4) - return float3(-position.x, position.y, 1); // face Z - if (viewIndex == 5) - return float3(position.x, position.y, -1); // face -Z - - return 0; - } - - float3 ParallaxCorrectionCube(float3 samplingDir, float3 reflectionPoint, float3 cubemapCenter, float cubemapRange) - { - // TODO: evolve to a more generic transformation (rotation, scale of the BB) - reflectionPoint -= cubemapCenter; - float3 lambdaPos = (cubemapRange - reflectionPoint) / samplingDir; - float3 lambdaNeg = (-cubemapRange - reflectionPoint) / samplingDir; - - float3 maxLambda = max(lambdaPos, lambdaNeg); // only take strictly positive values - float minLambda = min(maxLambda.x, min(maxLambda.y, maxLambda.z)); // take the smallest one - - // no need to normalize - return reflectionPoint + minLambda * samplingDir; - } - - float3 ParallaxCorrectionSphere(float3 samplingDir, float3 reflectionPoint, float3 cubemapCenter, float cubemapRadius) - { - samplingDir = normalize(samplingDir); - float3 reflectionPointDir = reflectionPoint - cubemapCenter; - - float b = 2 * dot(reflectionPointDir, samplingDir); - float c = dot(reflectionPointDir, reflectionPointDir) - cubemapRadius * cubemapRadius; - float discr = b*b - 4*c; - - if (discr >= 0) - { - float sqrtDelta = sqrt(discr); - float lambda = 0.5 * (sqrtDelta - b); - // no need to normalize - return reflectionPointDir + lambda * samplingDir; - } - else - { - return samplingDir; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CustomFogEffect.sdsl b/sources/shaders/assets/Stride/SDSL/CustomFogEffect.sdsl deleted file mode 100644 index fbb011ef62..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CustomFogEffect.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Simple fog emulating fixed pipeline as described in http://www.ozone3d.net/tutorials/glsl_fog/p03.php -shader CustomFogEffect : ShadingBase, TransformationBase, Camera -{ - cbuffer PerDraw - { - // Color of the fog - [Color] - stage float4 FogColor = float4(1,1,1,1); - - stage float fogNearPlaneZ = 80.0f;//35.0f; - stage float fogFarPlaneZ = 250.0f; - - stage float fogNearPlaneY = 0.0f; - stage float fogFarPlaneY = 120.0f; - } - - // Varying FogFactor calculated from VS and passed to PS - stage stream float FogFactor : FOG; - - stage override void PostTransformPosition() - { - base.PostTransformPosition(); - float depth; - const float LOG2 = 1.442695; - - float depthFactor = max ( (fogFarPlaneZ - streams.ShadingPosition.w ) / (fogFarPlaneZ - fogNearPlaneZ), 0.0); - float heightFactor = max ( (streams.ShadingPosition.y - fogFarPlaneY) / ( fogFarPlaneY - fogNearPlaneY), 0.0); - streams.FogFactor = saturate( depthFactor + heightFactor ); - } - - stage override float4 Shading() - { - float4 normalShade = base.Shading(); - - if(normalShade.w <= 0.005) - return normalShade; - - return lerp(FogColor, normalShade, streams.FogFactor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/CustomShader.sdsl b/sources/shaders/assets/Stride/SDSL/CustomShader.sdsl deleted file mode 100644 index 2c4fe84f4b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CustomShader.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Graphics.Tests -{ - shader CustomShader : SpriteBase - { - // factor used by CustomEffect - stage float SwitchEffectLevel; - - cbuffer PerPass - { - [Link("MyCustomShader.ColorFactor2")] - stage float4 ColorFactor2; - }; - - // Shading of the sprite with dual texturing - stage override float4 Shading() - { - return base.Shading() * ColorFactor2; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/CyclicTest.sdsl b/sources/shaders/assets/Stride/SDSL/CyclicTest.sdsl deleted file mode 100644 index 919664c10d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/CyclicTest.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CyclicTest : CyclicTest -{ - -}; diff --git a/sources/shaders/assets/Stride/SDSL/DataPacking.sdsl b/sources/shaders/assets/Stride/SDSL/DataPacking.sdsl deleted file mode 100644 index a3c62b2f88..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DataPacking.sdsl +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader DataPacking -{ - uint FloatToUnsignedFloatWExponent5(float num, int mantissa) - { - uint fltInt32 = asuint(num); - int offset = (23-mantissa); - int bitdepth = mantissa+5; - int bias = 15;//pow(2,5 - 1) - 1; - int biascounter = 0x38000000;//(127-bias)<<23; - - if (((fltInt32 & 0x7f800000) >> offset) <= (biascounter >> offset)) - return 0; - - uint fltInt16 = (((fltInt32 & 0x7fffffff) >> offset) - (biascounter >> offset)) & (0xFFFFFFFF >> (32-bitdepth)); - - return fltInt16; - } - float UnsignedFloatWExponent5ToFloat(uint num, int mantissa) - { - uint fltInt16 = num; - int offset = (23-mantissa); - int bitdepth = mantissa+5; - int bias = pow(2,5 - 1) - 1; - int biascounter = (127-bias)<<23; - - if (num==0) - return 0; - - uint fltInt32 = ((fltInt16) << offset) + 0x38000000; - - return asfloat(fltInt32); - } - uint Float3ToR11G11B10(float3 num) - { - return FloatToUnsignedFloatWExponent5(num.r, 6) | (FloatToUnsignedFloatWExponent5(num.g, 6)<<11) | (FloatToUnsignedFloatWExponent5(num.b, 5)<<22); - } - float3 R11G11B10ToFloat3(uint num) - { - float3 ret; - ret.r = UnsignedFloatWExponent5ToFloat(num & (0xFFFFFFFF>>(32-11)),6); - ret.g = UnsignedFloatWExponent5ToFloat((num>>11) & (0xFFFFFFFF>>(32-11)),6); - ret.b = UnsignedFloatWExponent5ToFloat((num>>22),5); - return ret; - } - uint FloatToHalfFloat(float num) - { - uint fltInt32 = asuint(num); - - if (((fltInt32 & 0x7f800000) >> 13) <= (0x38000000 >> 13)) - return 0; - - uint fltInt16 = (((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13)) & 0x00007fff; - fltInt16 |= ((fltInt32 & 0x80000000) >> 16); - - return fltInt16; - } - float HalfFloatToFloat(uint num) - { - if (num==0) - return 0; - - uint fltInt16 = num; - - uint fltInt32 = ((fltInt16 & 0x00008000) << 16); - fltInt32 |= ((fltInt16 & 0x00007fff) << 13) + 0x38000000; - - return asfloat(fltInt32); - } - uint PackFloat2ToHalfFloat2(float2 num) - { - return FloatToHalfFloat(num.r) | (FloatToHalfFloat(num.g)<<16); - } - float2 UnpackHalfFloat2ToFloat2(uint num) - { - return float2( HalfFloatToFloat(num & 0x0000ffff), - HalfFloatToFloat(num >> 16) ); - } - - uint3 UnpackByte3ToUint3(uint num) - { - return uint3( - num & 0x000000ff, - (num >> 8) & 0x000000ff, - (num >> 16) & 0x000000ff - ); - } - - uint FloatUnormToUint(float num) - { - return (uint)(num * 4294967295.0); - } - float UintToFloatUnorm(uint num) - { - return float(num) / 4294967295.0; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/DeepExtern.sdsl b/sources/shaders/assets/Stride/SDSL/DeepExtern.sdsl deleted file mode 100644 index 1b378d8113..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DeepExtern.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader DeepExtern -{ - compose ExternMixin myExtern; -}; diff --git a/sources/shaders/assets/Stride/SDSL/DeepExternTest.sdsl b/sources/shaders/assets/Stride/SDSL/DeepExternTest.sdsl deleted file mode 100644 index 8b2fca2f23..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DeepExternTest.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader DeepExternTest -{ - compose DeepExtern myExtern; - - float externCall() - { - myExtern.myExtern.externFunc(); - return myExtern.myExtern.externMember; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl b/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl deleted file mode 100644 index adf46d7bbb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - - /// - /// A blur with uniform weights applied along one direction. (depth-aware blur to avoid artifacts) - /// - - shader DepthAwareDirectionalBlurShader - : DepthAwareDirectionalBlurUtil, ImageEffectShader - { - stage override float4 Shading() - { - return Compute(); - } - - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl b/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl deleted file mode 100644 index 597b68bff8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DepthAwareDirectionalBlurUtil.sdsl +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - - /// - /// A blur with weights applied along one direction. - /// Expects as input: - /// - Texture0: color buffer - /// - /// - /// The number of weights along a direction. - /// Total number of tpas. The value is always 2 * TWeightCount - 1. - - shader DepthAwareDirectionalBlurUtil : Texturing, ComputeColor - { - // Direction to apply the blur. (normalized vector) - float2 Direction; - - // The radius of the blur to apply around the considered fragment - float Radius; - - // Weights of each tap (weights values are symmetric along each direction) - float TapWeights[TWeightCount]; - - float CoCReference; - - // Gets the blur result for the current pixel. - override float4 Compute() - { - // Offset between 2 consecutive taps - float2 tapOffset = Radius / (TWeightCount - 1) * Texture0TexelSize; - - // Fills arrays with all the taps - float4 tapColor[TTotalNumber]; // All the taps colors - float tapOriginalWeight[TTotalNumber]; // With their respective weight - - // Center tap - int centerIndex = TWeightCount - 1; - tapColor[centerIndex] = Texture0.Sample(LinearSampler, streams.TexCoord).xyzw; - // Premultiply alpha - tapColor[centerIndex].rgb *= tapColor[centerIndex].a; - tapOriginalWeight[centerIndex] = TapWeights[0]; - - // Treats all the taps in the 2 directions from the center - [unroll] - for(int i = 1; i < TWeightCount; i++) - { - // Backwards - float2 tapUV = streams.TexCoord - i * Direction * tapOffset; - int tapIndex = centerIndex - i; - tapColor[tapIndex] = Texture0.Sample(LinearSampler, tapUV).xyzw; - // Premultiply alpha - tapColor[tapIndex].rgb *= tapColor[tapIndex].a; - tapOriginalWeight[tapIndex] = TapWeights[i]; - - // Forwards - tapUV = streams.TexCoord + i * Direction * tapOffset; - tapIndex = centerIndex + i; - tapColor[tapIndex] = Texture0.Sample(LinearSampler, tapUV).xyzw; - // Premultiply alpha - tapColor[tapIndex].rgb *= tapColor[tapIndex].a; - tapOriginalWeight[tapIndex] = TapWeights[i]; - } - - // Calculate the final average color - float4 resultColor = float4(0.0, 0.0, 0.0, 0.0); - float totalWeight = 0.0; - - [unroll] - for(int k = 0; k < TTotalNumber; k++) - { - float tapWeight = tapOriginalWeight[k]; - // You could change the weight on the fly here to discard some sample - resultColor += tapColor[k].xyzw * tapWeight; - totalWeight += tapWeight; - } - - if (totalWeight > 0) { - // Normalizes the final result - resultColor /= totalWeight; - } else { - resultColor = float4(0.0, 0.0, 0.0, 0.0); - } - - // Go back to non-premultiplied-alpha - if (resultColor.a > 0) - { - resultColor.rgb /= resultColor.a; - } - - return resultColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DepthBase.sdsl b/sources/shaders/assets/Stride/SDSL/DepthBase.sdsl deleted file mode 100644 index 1ecdc246dd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DepthBase.sdsl +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a depth texture. -/// Various helper functions to extract information from a depth buffer. -/// -shader DepthBase : Camera, Texturing -{ - // ------------------------------------- - // Resources - // ------------------------------------- - rgroup PerView.Depth - { - //[Link("RenderTarget.DepthStencilSource")] - stage Texture2D DepthStencil; - } - - // Sample the depth from the texture - float GetZProjDepthFromUV(float2 uv) { - return DepthStencil.SampleLevel(PointSampler, uv, 0.0).x; - } - - float GetZProjDepthFromScreenPosition(int2 screenPosition) { - return DepthStencil.Load(int3(screenPosition,0), 0).x; - } - - float ComputeDepthFromZProj(float depth) { - // Retro project non linear 1/z depth to linear depth in view space - return ZProjection.y / (depth - ZProjection.x); - } - - float ComputeDepthFromUV(float2 uv) { - return ComputeDepthFromZProj(GetZProjDepthFromUV(uv)); - } - - float ComputeDepthFromScreenPosition(int2 screenPosition) { - return ComputeDepthFromZProj(GetZProjDepthFromScreenPosition(screenPosition)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DepthMinMaxShader.sdsl b/sources/shaders/assets/Stride/SDSL/DepthMinMaxShader.sdsl deleted file mode 100644 index 63a1a1d4a0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DepthMinMaxShader.sdsl +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// STRIDE_GRAPHICS_PROFILE: Macro - graphics profile level. -/// - -namespace Stride.Rendering.Images -{ - /// - /// A reduction shader - /// - shader DepthMinMaxShader : ImageEffectShader - { - Texture2D TextureMap; - Texture2D TextureReduction; - - - float max_not_1(float left, float right) - { - if (left == 1.0f) return right; - if (right == 1.0f) return left; - return max(left, right); - } - - stage override float4 Shading() - { - if (TFirstPass) - { - float4 values; - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_1 - values = TextureMap.Gather(LinearSampler, streams.TexCoord); -#else - values.x = TextureMap.Sample(PointSampler, streams.TexCoord, int2(-1, 0)).r; - values.y = TextureMap.Sample(PointSampler, streams.TexCoord, int2(0, 0)).r; - values.z = TextureMap.Sample(PointSampler, streams.TexCoord, int2(0, -1)).r; - values.w = TextureMap.Sample(PointSampler, streams.TexCoord, int2(-1, -1)).r; -#endif - // TODO: do a simple sort for 4 values quicker than min/max - var minValue = min(min(values[0], values[1]), min(values[2], values[3])); - var maxValue = max_not_1(max_not_1(values[0], values[1]), max_not_1(values[2], values[3])); - - return float4(minValue, maxValue, 0, 0); - } - else - { - float4 minValues, maxValues; - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_11_0 - minValues = TextureReduction.GatherRed(LinearSampler, streams.TexCoord); - maxValues = TextureReduction.GatherGreen(LinearSampler, streams.TexCoord); -#else - float2 value0 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(-1, 0)).rg; - float2 value1 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(0, 0)).rg; - float2 value2 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(0, -1)).rg; - float2 value3 = TextureReduction.Sample(PointSampler, streams.TexCoord, int2(-1, -1)).rg; - minValues = float4(value0.r, value1.r, value2.r, value3.r); - maxValues = float4(value0.g, value1.g, value2.g, value3.g); -#endif - - // TODO: do a simple sort for 4 values quicker than min/max - var minValue = min(min(minValues[0], minValues[1]), min(minValues[2], minValues[3])); - var maxValue = max_not_1(max_not_1(maxValues[0], maxValues[1]), max_not_1(maxValues[2], maxValues[3])); - - return float4(minValue, maxValue, 0, 0); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DirectLightGroup.sdsl b/sources/shaders/assets/Stride/SDSL/DirectLightGroup.sdsl deleted file mode 100644 index 9b81711f7b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DirectLightGroup.sdsl +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of similar lights (directional, spot...etc.) - /// - shader DirectLightGroup : - LightStream, - ShadowGroup, // Required for "ComputeShadow()". - TextureProjectionGroup, // Required for "ComputeTextureProjection()". - NormalStream, // Required for "streams.normalWS". - PositionStream4, // Required for "streams.PositionWS". - MaterialPixelStream // Required for "streams.viewWS" - { - int GetMaxLightCount() - { - return 0; - } - - /// - /// Gets the number of lights of this group - /// - int GetLightCount() - { - return 0; - } - - /// - /// One-time initialization before the light loop. - /// - void PrepareDirectLights() - { - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - void PrepareDirectLight(int lightIndex) - { - PrepareDirectLightCore(lightIndex); - - // Compute NdotL - streams.NdotL = max(dot(streams.normalWS, streams.lightDirectionWS), 0.0001f); - - // Computes the shadowColor - streams.shadowColor = ComputeShadow(streams.PositionWS.xyz, lightIndex); - - // Compute the final color with NdotL - streams.lightColorNdotL = streams.lightColor * streams.lightAttenuation * streams.shadowColor * streams.NdotL * streams.lightDirectAmbientOcclusion; - streams.lightSpecularColorNdotL = streams.lightColorNdotL; - - // Mask the light by the color of the projected texture: - streams.lightColorNdotL *= ComputeTextureProjection(streams.PositionWS.xyz, lightIndex); // TODO: Modify "streams.lightColor" instead? - - - float3 reflectionVectorWS = reflect(-streams.viewWS, streams.normalWS); - streams.lightSpecularColorNdotL *= ComputeSpecularTextureProjection(streams.PositionWS.xyz, reflectionVectorWS, lightIndex); - } - - void PrepareDirectLightCore(int lightIndex) - { - } - - float ComputeAttenuation(float3 position, int lightIndex) - { - return 1; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DirectLightGroupArray.sdsl b/sources/shaders/assets/Stride/SDSL/DirectLightGroupArray.sdsl deleted file mode 100644 index 4782cd84d8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DirectLightGroupArray.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// An array of light groups - /// - shader DirectLightGroupArray - { - stage compose DirectLightGroup directLightGroups[]; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DirectLightGroupFixed.sdsl b/sources/shaders/assets/Stride/SDSL/DirectLightGroupFixed.sdsl deleted file mode 100644 index 3358ca092b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DirectLightGroupFixed.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Overrides the default behaviour of DirectLightGroup to only return a fixed number of lights - /// - shader DirectLightGroupFixed : DirectLightGroup - { - /// - /// Gets the number of lights of this group - /// - override int GetLightCount() - { - return TLightCount; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl b/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl deleted file mode 100644 index 219869ddb2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerDraw.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of similar lights (directional, spot...etc.) - /// - shader DirectLightGroupPerDraw : DirectLightGroup - { - cbuffer PerDraw.Lighting - { - int LightCount; - } - - /// - /// Gets the number of lights of this group - /// - override int GetLightCount() - { - return LightCount; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerView.sdsl b/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerView.sdsl deleted file mode 100644 index 977874c86c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DirectLightGroupPerView.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of similar lights (directional, spot...etc.) - /// - shader DirectLightGroupPerView : DirectLightGroup - { - cbuffer PerView.Lighting - { - int LightCount; - } - - /// - /// Gets the number of lights of this group - /// - override int GetLightCount() - { - return LightCount; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Dither.sdsl b/sources/shaders/assets/Stride/SDSL/Dither.sdsl deleted file mode 100644 index 5fee978311..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Dither.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader Dither : ColorTransformShader, Texturing -{ - // Time changing at each frame for the animation - float Time; - - override float4 Compute(float4 color) - { - // Test cases that truncate to 8 bit and scale the result: - //return float4(Truncate(ScreenSpaceDither(color.rgb*0.1), 255), color.a) * 10; - //return float4(Truncate(color.rgb*0.1, 255), color.a) * 10; - - return float4(ScreenSpaceDither(color.rgb), color.a); - //return float4(color.rgb, color.a); - } - - float3 Truncate( float3 x, float n ) - { - return floor(x*n)/n; - } - - - float3 ScreenSpaceDither(float3 input) - { - float2 vScreenPos = streams.TexCoord; - vScreenPos /= Texture0TexelSize; - - // http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf - // lestyn's RGB dither (7 asm instructions) from Portal 2 X360, slightly modified for VR - float3 vDither = dot(float2(131.0, 312.0), vScreenPos + Time); - vDither.rgb = frac(vDither.rgb / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5); - float d = max(input.x, max(input.y, input.z)); - return input + (vDither.rgb / 255.0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DynamicSampler.sdsl b/sources/shaders/assets/Stride/SDSL/DynamicSampler.sdsl deleted file mode 100644 index a6fc09bcfb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DynamicSampler.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a Texture2D. -/// -/// -/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. -/// -shader DynamicSampler -{ - rgroup LocalResourceGroup - { - [Link("TSampler")] - stage SamplerState Sampler; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DynamicTexture.sdsl b/sources/shaders/assets/Stride/SDSL/DynamicTexture.sdsl deleted file mode 100644 index 02f79c3a49..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DynamicTexture.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a Texture2D. -/// -/// -/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. -/// -shader DynamicTexture -{ - rgroup LocalResourceGroup - { - [Link("TTexture")] - stage Texture2D Texture; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DynamicTextureCube.sdsl b/sources/shaders/assets/Stride/SDSL/DynamicTextureCube.sdsl deleted file mode 100644 index 5f47583d9d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DynamicTextureCube.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a Texture2D. -/// -/// -/// TEXTURE_KEY: generic LinkType - the name of the ParameterKey that will link to this texture. -/// -shader DynamicTextureCube -{ - rgroup LocalResourceGroup - { - [Link("TTexture")] - stage TextureCube CubeMap; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/DynamicTextureStream.sdsl b/sources/shaders/assets/Stride/SDSL/DynamicTextureStream.sdsl deleted file mode 100644 index 6d87f6feb0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/DynamicTextureStream.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a stream with custom attribute (usually texcoord). -/// -/// -/// NAME: generic Semantic - the name of the texcoord (e.g. TEXCOORD0). -/// -shader DynamicTextureStream -{ - stream float2 TexCoord : NAME; -}; diff --git a/sources/shaders/assets/Stride/SDSL/Effect.sdsl b/sources/shaders/assets/Stride/SDSL/Effect.sdsl deleted file mode 100644 index 90c1706446..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Effect.sdsl +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader Effect : SpriteBase -{ - stage float2 Center; - stage float Frequency; - stage float Phase; - stage float Spread; - stage float Amplitude; - stage float InvAspectRatio; - - stage override float4 Shading() - { - float2 wave; - - float2 toPixel = (streams.TexCoord.xy - Center) * float2(1, InvAspectRatio); - - float distance = length(toPixel); - float2 direction = normalize(toPixel); - - sincos(Frequency * distance + Phase, wave.x, wave.y); - - // Clamps the distance between 0 and 1 and squares the value. - float falloff = saturate(1 - distance); - falloff = pow(falloff, 1.0f / Spread); - - // Calculates new mapping coordinates based on the frequency, center, and amplitude. - float2 uv2 = streams.TexCoord.xy + (wave.x * falloff * Amplitude) * direction; - float lighting = lerp(1.0f, 1.0f + wave.x * falloff * 0.2f, saturate(Amplitude / 0.015f)); - - // Resamples the image based on the new coordinates. - float4 color = Texture0.Sample(Sampler, uv2); - color.rgb *= lighting; - - return color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/EffectCompiling.sdsl b/sources/shaders/assets/Stride/SDSL/EffectCompiling.sdsl deleted file mode 100644 index 004c4c70e2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/EffectCompiling.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader EffectCompiling : ShadingBase -{ - // method computing color - stage override float4 Shading() - { - float factor = sin(Global.Time * 6.0f) * 0.25f + 0.25f; - float4 reloadColor = float4(0.66f, 1.0f, 0.25f, 1.0f); - - // High frequency glow to let user know effect is reloading - return lerp(base.Shading(), reloadColor, factor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/EnvironmentLight.sdsl b/sources/shaders/assets/Stride/SDSL/EnvironmentLight.sdsl deleted file mode 100644 index fe9aecb246..0000000000 --- a/sources/shaders/assets/Stride/SDSL/EnvironmentLight.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines an environment light (ambient, IBL... etc.) - /// - shader EnvironmentLight : LightStream, ShadowGroup, NormalStream - { - void PrepareEnvironmentLight() - { - streams.envLightDiffuseColor = 0; - streams.envLightSpecularColor = 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/EnvironmentLightArray.sdsl b/sources/shaders/assets/Stride/SDSL/EnvironmentLightArray.sdsl deleted file mode 100644 index 599b7c6c04..0000000000 --- a/sources/shaders/assets/Stride/SDSL/EnvironmentLightArray.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// An array of environment lights - /// - shader EnvironmentLightArray - { - stage compose EnvironmentLight environmentLights[]; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ExternClone.sdsl b/sources/shaders/assets/Stride/SDSL/ExternClone.sdsl deleted file mode 100644 index f30dc65da8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ExternClone.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternClone -{ - clone void test() - { - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ExternCloneTest.sdsl b/sources/shaders/assets/Stride/SDSL/ExternCloneTest.sdsl deleted file mode 100644 index af0015bebf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ExternCloneTest.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternCloneTest -{ - compose DeepExtern ext0; - compose DeepExtern ext1; - - void Test() - { - float fext0 = ext0.myExtern.externMember; - float fext1 = ext1.myExtern.externMember; - ext0.myExtern.externFunc(); - ext1.myExtern.externFunc(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ExternMixin.sdsl b/sources/shaders/assets/Stride/SDSL/ExternMixin.sdsl deleted file mode 100644 index 56dcf2ea5a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ExternMixin.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternMixin -{ - float externMember = 1.0f; - - void externFunc() - { - float a = 0.0f; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ExternTest.sdsl b/sources/shaders/assets/Stride/SDSL/ExternTest.sdsl deleted file mode 100644 index f83715581a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ExternTest.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternTest -{ - compose ExternMixin myExtern; - - void externFunc(){} - - float externCall() - { - myExtern.externFunc(); - return myExtern.externMember; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/FXAAShader.sdsl b/sources/shaders/assets/Stride/SDSL/FXAAShader.sdsl deleted file mode 100644 index fd748d9137..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FXAAShader.sdsl +++ /dev/null @@ -1,2067 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#define FXAA_PC 1 -#define FXAA_HLSL_4 1 -#ifndef FXAA_QUALITY__PRESET -#define FXAA_QUALITY__PRESET 15 -#endif -shader FXAAShader : ImageEffectShader -{ - -/*============================================================================ - - - NVIDIA FXAA 3.11 by TIMOTHY LOTTES - - ------------------------------------------------------------------------------- -COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED. ------------------------------------------------------------------------------- -TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED -*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA -OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR -CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR -LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, -OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE -THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - ------------------------------------------------------------------------------- - INTEGRATION CHECKLIST ------------------------------------------------------------------------------- -(1.) -In the shader source, setup defines for the desired configuration. -When providing multiple shaders (for different presets), -simply setup the defines differently in multiple files. -Example, - - #define FXAA_PC 1 - #define FXAA_HLSL_5 1 - #define FXAA_QUALITY__PRESET 12 - -Or, - - #define FXAA_360 1 - -Or, - - #define FXAA_PS3 1 - -Etc. - -(2.) -Then include this file, - - #include "Fxaa3_11.h" - -(3.) -Then call the FXAA pixel shader from within your desired shader. -Look at the FXAA Quality FxaaPixelShader() for docs on inputs. -As for FXAA 3.11 all inputs for all shaders are the same -to enable easy porting between platforms. - - return FxaaPixelShader(...); - -(4.) -Insure pass prior to FXAA outputs RGBL (see next section). -Or use, - - #define FXAA_GREEN_AS_LUMA 1 - -(5.) -Setup engine to provide the following constants -which are used in the FxaaPixelShader() inputs, - - FxaaFloat2 fxaaQualityRcpFrame, - FxaaFloat4 fxaaConsoleRcpFrameOpt, - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - FxaaFloat fxaaQualitySubpix, - FxaaFloat fxaaQualityEdgeThreshold, - FxaaFloat fxaaQualityEdgeThresholdMin, - FxaaFloat fxaaConsoleEdgeSharpness, - FxaaFloat fxaaConsoleEdgeThreshold, - FxaaFloat fxaaConsoleEdgeThresholdMin, - FxaaFloat4 fxaaConsole360ConstDir - -Look at the FXAA Quality FxaaPixelShader() for docs on inputs. - -(6.) -Have FXAA vertex shader run as a full screen triangle, -and output "pos" and "fxaaConsolePosPos" -such that inputs in the pixel shader provide, - - // {xy} = center of pixel - FxaaFloat2 pos, - - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - FxaaFloat4 fxaaConsolePosPos, - -(7.) -Insure the texture sampler(s) used by FXAA are set to bilinear filtering. - - ------------------------------------------------------------------------------- - INTEGRATION - RGBL AND COLORSPACE ------------------------------------------------------------------------------- -FXAA3 requires RGBL as input unless the following is set, - - #define FXAA_GREEN_AS_LUMA 1 - -In which case the engine uses green in place of luma, -and requires RGB input is in a non-linear colorspace. - -RGB should be LDR (low dynamic range). -Specifically do FXAA after tonemapping. - -RGB data as returned by a texture fetch can be non-linear, -or linear when FXAA_GREEN_AS_LUMA is not set. -Note an "sRGB format" texture counts as linear, -because the result of a texture fetch is linear data. -Regular "RGBA8" textures in the sRGB colorspace are non-linear. - -If FXAA_GREEN_AS_LUMA is not set, -luma must be stored in the alpha channel prior to running FXAA. -This luma should be in a perceptual space (could be gamma 2.0). -Example pass before FXAA where output is gamma 2.0 encoded, - - color.rgb = ToneMap(color.rgb); // linear color output - color.rgb = sqrt(color.rgb); // gamma 2.0 color output - return color; - -To use FXAA, - - color.rgb = ToneMap(color.rgb); // linear color output - color.rgb = sqrt(color.rgb); // gamma 2.0 color output - color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma - return color; - -Another example where output is linear encoded, -say for instance writing to an sRGB formated render target, -where the render target does the conversion back to sRGB after blending, - - color.rgb = ToneMap(color.rgb); // linear color output - return color; - -To use FXAA, - - color.rgb = ToneMap(color.rgb); // linear color output - color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma - return color; - -Getting luma correct is required for the algorithm to work correctly. - - ------------------------------------------------------------------------------- - BEING LINEARLY CORRECT? ------------------------------------------------------------------------------- -Applying FXAA to a framebuffer with linear RGB color will look worse. -This is very counter intuitive, but happends to be true in this case. -The reason is because dithering artifacts will be more visiable -in a linear colorspace. - - ------------------------------------------------------------------------------- - COMPLEX INTEGRATION ------------------------------------------------------------------------------- -Q. What if the engine is blending into RGB before wanting to run FXAA? - -A. In the last opaque pass prior to FXAA, - have the pass write out luma into alpha. - Then blend into RGB only. - FXAA should be able to run ok - assuming the blending pass did not any add aliasing. - This should be the common case for particles and common blending passes. - -A. Or use FXAA_GREEN_AS_LUMA. - -============================================================================*/ - -/*============================================================================ - - INTEGRATION KNOBS - -============================================================================*/ -// -// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE). -// FXAA_360_OPT is a prototype for the new optimized 360 version. -// -// 1 = Use API. -// 0 = Don't use API. -// -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_PS3 - #define FXAA_PS3 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_360 - #define FXAA_360 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_360_OPT - #define FXAA_360_OPT 0 -#endif -/*==========================================================================*/ -#ifndef FXAA_PC - // - // FXAA Quality - // The high quality PC algorithm. - // - #define FXAA_PC 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_PC_CONSOLE - // - // The console algorithm for PC is included - // for developers targeting really low spec machines. - // Likely better to just run FXAA_PC, and use a really low preset. - // - #define FXAA_PC_CONSOLE 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_GLSL_120 - #define FXAA_GLSL_120 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_GLSL_130 - #define FXAA_GLSL_130 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_HLSL_3 - #define FXAA_HLSL_3 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_HLSL_4 - #define FXAA_HLSL_4 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_HLSL_5 - #define FXAA_HLSL_5 0 -#endif -/*==========================================================================*/ -#ifndef FXAA_GREEN_AS_LUMA - // - // For those using non-linear color, - // and either not able to get luma in alpha, or not wanting to, - // this enables FXAA to run using green as a proxy for luma. - // So with this enabled, no need to pack luma in alpha. - // - // This will turn off AA on anything which lacks some amount of green. - // Pure red and blue or combination of only R and B, will get no AA. - // - // Might want to lower the settings for both, - // fxaaConsoleEdgeThresholdMin - // fxaaQualityEdgeThresholdMin - // In order to insure AA does not get turned off on colors - // which contain a minor amount of green. - // - // 1 = On. - // 0 = Off. - // - #define FXAA_GREEN_AS_LUMA 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_EARLY_EXIT - // - // Controls algorithm's early exit path. - // On PS3 turning this ON adds 2 cycles to the shader. - // On 360 turning this OFF adds 10ths of a millisecond to the shader. - // Turning this off on console will result in a more blurry image. - // So this defaults to on. - // - // 1 = On. - // 0 = Off. - // - #define FXAA_EARLY_EXIT 1 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_DISCARD - // - // Only valid for PC OpenGL currently. - // Probably will not work when FXAA_GREEN_AS_LUMA = 1. - // - // 1 = Use discard on pixels which don't need AA. - // For APIs which enable concurrent TEX+ROP from same surface. - // 0 = Return unchanged color on pixels which don't need AA. - // - #define FXAA_DISCARD 0 -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_FAST_PIXEL_OFFSET - // - // Used for GLSL 120 only. - // - // 1 = GL API supports fast pixel offsets - // 0 = do not use fast pixel offsets - // - #ifdef GL_EXT_gpu_shader4 - #define FXAA_FAST_PIXEL_OFFSET 1 - #endif - #ifdef GL_NV_gpu_shader5 - #define FXAA_FAST_PIXEL_OFFSET 1 - #endif - #ifdef GL_ARB_gpu_shader5 - #define FXAA_FAST_PIXEL_OFFSET 1 - #endif - #ifndef FXAA_FAST_PIXEL_OFFSET - #define FXAA_FAST_PIXEL_OFFSET 0 - #endif -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_GATHER4_ALPHA - // - // 1 = API supports gather4 on alpha channel. - // 0 = API does not support gather4 on alpha channel. - // - #if (FXAA_HLSL_5 == 1) - #define FXAA_GATHER4_ALPHA 1 - #endif - #ifdef GL_ARB_gpu_shader5 - #define FXAA_GATHER4_ALPHA 1 - #endif - #ifdef GL_NV_gpu_shader5 - #define FXAA_GATHER4_ALPHA 1 - #endif - #ifndef FXAA_GATHER4_ALPHA - #define FXAA_GATHER4_ALPHA 0 - #endif -#endif - -/*============================================================================ - FXAA CONSOLE PS3 - TUNING KNOBS -============================================================================*/ -#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS - // - // Consoles the sharpness of edges on PS3 only. - // Non-PS3 tuning is done with shader input. - // - // Due to the PS3 being ALU bound, - // there are only two safe values here: 4 and 8. - // These options use the shaders ability to a free *|/ by 2|4|8. - // - // 8.0 is sharper - // 4.0 is softer - // 2.0 is really soft (good for vector graphics inputs) - // - #if 1 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0 - #endif - #if 0 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0 - #endif - #if 0 - #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0 - #endif -#endif -/*--------------------------------------------------------------------------*/ -#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD - // - // Only effects PS3. - // Non-PS3 tuning is done with shader input. - // - // The minimum amount of local contrast required to apply algorithm. - // The console setting has a different mapping than the quality setting. - // - // This only applies when FXAA_EARLY_EXIT is 1. - // - // Due to the PS3 being ALU bound, - // there are only two safe values here: 0.25 and 0.125. - // These options use the shaders ability to a free *|/ by 2|4|8. - // - // 0.125 leaves less aliasing, but is softer - // 0.25 leaves more aliasing, and is sharper - // - #if 1 - #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125 - #else - #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25 - #endif -#endif - -/*============================================================================ - FXAA QUALITY - TUNING KNOBS ------------------------------------------------------------------------------- -NOTE the other tuning knobs are now in the shader function inputs! -============================================================================*/ -#ifndef FXAA_QUALITY__PRESET - // - // Choose the quality preset. - // This needs to be compiled into the shader as it effects code. - // Best option to include multiple presets is to - // in each shader define the preset, then include this file. - // - // OPTIONS - // ----------------------------------------------------------------------- - // 10 to 15 - default medium dither (10=fastest, 15=highest quality) - // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality) - // 39 - no dither, very expensive - // - // NOTES - // ----------------------------------------------------------------------- - // 12 = slightly faster then FXAA 3.9 and higher edge quality (default) - // 13 = about same speed as FXAA 3.9 and better than 12 - // 23 = closest to FXAA 3.9 visually and performance wise - // _ = the lowest digit is directly related to performance - // _ = the highest digit is directly related to style - // - #define FXAA_QUALITY__PRESET 12 -#endif - - -/*============================================================================ - - FXAA QUALITY - PRESETS - -============================================================================*/ - -/*============================================================================ - FXAA QUALITY - MEDIUM DITHER PRESETS -============================================================================*/ -#if (FXAA_QUALITY__PRESET == 10) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 3.0 - #define FXAA_QUALITY__P2 12.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 11) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 3.0 - #define FXAA_QUALITY__P3 12.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 12) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 4.0 - #define FXAA_QUALITY__P4 12.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 13) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 4.0 - #define FXAA_QUALITY__P5 12.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 14) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 4.0 - #define FXAA_QUALITY__P6 12.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 15) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 12.0 -#endif - -/*============================================================================ - FXAA QUALITY - LOW DITHER PRESETS -============================================================================*/ -#if (FXAA_QUALITY__PRESET == 20) - #define FXAA_QUALITY__PS 3 - #define FXAA_QUALITY__P0 1.5 - #define FXAA_QUALITY__P1 2.0 - #define FXAA_QUALITY__P2 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 21) - #define FXAA_QUALITY__PS 4 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 22) - #define FXAA_QUALITY__PS 5 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 23) - #define FXAA_QUALITY__PS 6 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 24) - #define FXAA_QUALITY__PS 7 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 3.0 - #define FXAA_QUALITY__P6 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 25) - #define FXAA_QUALITY__PS 8 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 4.0 - #define FXAA_QUALITY__P7 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 26) - #define FXAA_QUALITY__PS 9 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 4.0 - #define FXAA_QUALITY__P8 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 27) - #define FXAA_QUALITY__PS 10 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 4.0 - #define FXAA_QUALITY__P9 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 28) - #define FXAA_QUALITY__PS 11 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 4.0 - #define FXAA_QUALITY__P10 8.0 -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_QUALITY__PRESET == 29) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.5 - #define FXAA_QUALITY__P2 2.0 - #define FXAA_QUALITY__P3 2.0 - #define FXAA_QUALITY__P4 2.0 - #define FXAA_QUALITY__P5 2.0 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 -#endif - -/*============================================================================ - FXAA QUALITY - EXTREME QUALITY -============================================================================*/ -#if (FXAA_QUALITY__PRESET == 39) - #define FXAA_QUALITY__PS 12 - #define FXAA_QUALITY__P0 1.0 - #define FXAA_QUALITY__P1 1.0 - #define FXAA_QUALITY__P2 1.0 - #define FXAA_QUALITY__P3 1.0 - #define FXAA_QUALITY__P4 1.0 - #define FXAA_QUALITY__P5 1.5 - #define FXAA_QUALITY__P6 2.0 - #define FXAA_QUALITY__P7 2.0 - #define FXAA_QUALITY__P8 2.0 - #define FXAA_QUALITY__P9 2.0 - #define FXAA_QUALITY__P10 4.0 - #define FXAA_QUALITY__P11 8.0 -#endif - - - -/*============================================================================ - - API PORTING - -============================================================================*/ -#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1) - #define FxaaBool bool - #define FxaaDiscard discard - #define FxaaFloat float - #define FxaaFloat2 vec2 - #define FxaaFloat3 vec3 - #define FxaaFloat4 vec4 - #define FxaaHalf float - #define FxaaHalf2 vec2 - #define FxaaHalf3 vec3 - #define FxaaHalf4 vec4 - #define FxaaInt2 ivec2 - #define FxaaSat(x) clamp(x, 0.0, 1.0) - #define FxaaTex sampler2D -#else - #define FxaaBool bool - #define FxaaDiscard clip(-1) - #define FxaaFloat float - #define FxaaFloat2 float2 - #define FxaaFloat3 float3 - #define FxaaFloat4 float4 - #define FxaaHalf half - #define FxaaHalf2 half2 - #define FxaaHalf3 half3 - #define FxaaHalf4 half4 - #define FxaaSat(x) saturate(x) -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_GLSL_120 == 1) - // Requires, - // #version 120 - // And at least, - // #extension GL_EXT_gpu_shader4 : enable - // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9) - #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0) - #if (FXAA_FAST_PIXEL_OFFSET == 1) - #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o) - #else - #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0) - #endif - #if (FXAA_GATHER4_ALPHA == 1) - // use #extension GL_ARB_gpu_shader5 : enable - #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) - #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) - #define FxaaTexGreen4(t, p) textureGather(t, p, 1) - #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) - #endif -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_GLSL_130 == 1) - // Requires "#version 130" or better - #define FxaaTexTop(t, p) textureLod(t, p, 0.0) - #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o) - #if (FXAA_GATHER4_ALPHA == 1) - // use #extension GL_ARB_gpu_shader5 : enable - #define FxaaTexAlpha4(t, p) textureGather(t, p, 3) - #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3) - #define FxaaTexGreen4(t, p) textureGather(t, p, 1) - #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1) - #endif -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1) - #define FxaaInt2 float2 - #define FxaaTex sampler2D - #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0)) - #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0)) -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_HLSL_4 == 1) - #define FxaaInt2 int2 - #define FxaaTex Texture2D - #define FxaaTexTop(t, p) t.SampleLevel(LinearSampler, p, 0.0) - #define FxaaTexOff(t, p, o, r) t.SampleLevel(LinearSampler, p, 0.0, o) -#endif -/*--------------------------------------------------------------------------*/ -#if (FXAA_HLSL_5 == 1) - #define FxaaInt2 int2 - #define FxaaTex Texture2D - #define FxaaTexTop(t, p) t.SampleLevel(LinearSampler, p, 0.0) - #define FxaaTexOff(t, p, o, r) t.SampleLevel(LinearSampler, p, 0.0, o) - #define FxaaTexAlpha4(t, p) t.GatherAlpha(LinearSampler, p) - #define FxaaTexOffAlpha4(t, p, o) t.GatherAlpha(LinearSampler, p, o) - #define FxaaTexGreen4(t, p) t.GatherGreen(LinearSampler, p) - #define FxaaTexOffGreen4(t, p, o) t.GatherGreen(LinearSampler, p, o) -#endif - - -/*============================================================================ - GREEN AS LUMA OPTION SUPPORT FUNCTION -============================================================================*/ -#if (FXAA_GREEN_AS_LUMA == 0) - FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; } -#else - FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; } -#endif - - - - -/*============================================================================ - - FXAA3 QUALITY - PC - -============================================================================*/ -#if (FXAA_PC == 1) -/*--------------------------------------------------------------------------*/ -FxaaFloat4 FxaaPixelShader( - // - // Use noperspective interpolation here (turn off perspective interpolation). - // {xy} = center of pixel - FxaaFloat2 pos, - // - // Used only for FXAA Console, and not used on the 360 version. - // Use noperspective interpolation here (turn off perspective interpolation). - // {xy__} = upper left of pixel - // {__zw} = lower right of pixel - FxaaFloat4 fxaaConsolePosPos, - // - // Input color texture. - // {rgb_} = color in linear or perceptual color space - // if (FXAA_GREEN_AS_LUMA == 0) - // {___a} = luma in perceptual color space (not linear) - FxaaTex tex, - // - // Only used on the optimized 360 version of FXAA Console. - // For everything but 360, just use the same input here as for "tex". - // For 360, same texture, just alias with a 2nd sampler. - // This sampler needs to have an exponent bias of -1. - FxaaTex fxaaConsole360TexExpBiasNegOne, - // - // Only used on the optimized 360 version of FXAA Console. - // For everything but 360, just use the same input here as for "tex". - // For 360, same texture, just alias with a 3nd sampler. - // This sampler needs to have an exponent bias of -2. - FxaaTex fxaaConsole360TexExpBiasNegTwo, - // - // Only used on FXAA Quality. - // This must be from a constant/uniform. - // {x_} = 1.0/screenWidthInPixels - // {_y} = 1.0/screenHeightInPixels - FxaaFloat2 fxaaQualityRcpFrame, - // - // Only used on FXAA Console. - // This must be from a constant/uniform. - // This effects sub-pixel AA quality and inversely sharpness. - // Where N ranges between, - // N = 0.50 (default) - // N = 0.33 (sharper) - // {x___} = -N/screenWidthInPixels - // {_y__} = -N/screenHeightInPixels - // {__z_} = N/screenWidthInPixels - // {___w} = N/screenHeightInPixels - FxaaFloat4 fxaaConsoleRcpFrameOpt, - // - // Only used on FXAA Console. - // Not used on 360, but used on PS3 and PC. - // This must be from a constant/uniform. - // {x___} = -2.0/screenWidthInPixels - // {_y__} = -2.0/screenHeightInPixels - // {__z_} = 2.0/screenWidthInPixels - // {___w} = 2.0/screenHeightInPixels - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - // - // Only used on FXAA Console. - // Only used on 360 in place of fxaaConsoleRcpFrameOpt2. - // This must be from a constant/uniform. - // {x___} = 8.0/screenWidthInPixels - // {_y__} = 8.0/screenHeightInPixels - // {__z_} = -4.0/screenWidthInPixels - // {___w} = -4.0/screenHeightInPixels - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - // - // Only used on FXAA Quality. - // This used to be the FXAA_QUALITY__SUBPIX define. - // It is here now to allow easier tuning. - // Choose the amount of sub-pixel aliasing removal. - // This can effect sharpness. - // 1.00 - upper limit (softer) - // 0.75 - default amount of filtering - // 0.50 - lower limit (sharper, less sub-pixel aliasing removal) - // 0.25 - almost off - // 0.00 - completely off - FxaaFloat fxaaQualitySubpix, - // - // Only used on FXAA Quality. - // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define. - // It is here now to allow easier tuning. - // The minimum amount of local contrast required to apply algorithm. - // 0.333 - too little (faster) - // 0.250 - low quality - // 0.166 - default - // 0.125 - high quality - // 0.063 - overkill (slower) - FxaaFloat fxaaQualityEdgeThreshold, - // - // Only used on FXAA Quality. - // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define. - // It is here now to allow easier tuning. - // Trims the algorithm from processing darks. - // 0.0833 - upper limit (default, the start of visible unfiltered edges) - // 0.0625 - high quality (faster) - // 0.0312 - visible limit (slower) - // Special notes when using FXAA_GREEN_AS_LUMA, - // Likely want to set this to zero. - // As colors that are mostly not-green - // will appear very dark in the green channel! - // Tune by looking at mostly non-green content, - // then start at zero and increase until aliasing is a problem. - FxaaFloat fxaaQualityEdgeThresholdMin, - // - // Only used on FXAA Console. - // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define. - // It is here now to allow easier tuning. - // This does not effect PS3, as this needs to be compiled in. - // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3. - // Due to the PS3 being ALU bound, - // there are only three safe values here: 2 and 4 and 8. - // These options use the shaders ability to a free *|/ by 2|4|8. - // For all other platforms can be a non-power of two. - // 8.0 is sharper (default!!!) - // 4.0 is softer - // 2.0 is really soft (good only for vector graphics inputs) - FxaaFloat fxaaConsoleEdgeSharpness, - // - // Only used on FXAA Console. - // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define. - // It is here now to allow easier tuning. - // This does not effect PS3, as this needs to be compiled in. - // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3. - // Due to the PS3 being ALU bound, - // there are only two safe values here: 1/4 and 1/8. - // These options use the shaders ability to a free *|/ by 2|4|8. - // The console setting has a different mapping than the quality setting. - // Other platforms can use other values. - // 0.125 leaves less aliasing, but is softer (default!!!) - // 0.25 leaves more aliasing, and is sharper - FxaaFloat fxaaConsoleEdgeThreshold, - // - // Only used on FXAA Console. - // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define. - // It is here now to allow easier tuning. - // Trims the algorithm from processing darks. - // The console setting has a different mapping than the quality setting. - // This only applies when FXAA_EARLY_EXIT is 1. - // This does not apply to PS3, - // PS3 was simplified to avoid more shader instructions. - // 0.06 - faster but more aliasing in darks - // 0.05 - default - // 0.04 - slower and less aliasing in darks - // Special notes when using FXAA_GREEN_AS_LUMA, - // Likely want to set this to zero. - // As colors that are mostly not-green - // will appear very dark in the green channel! - // Tune by looking at mostly non-green content, - // then start at zero and increase until aliasing is a problem. - FxaaFloat fxaaConsoleEdgeThresholdMin, - // - // Extra constants for 360 FXAA Console only. - // Use zeros or anything else for other platforms. - // These must be in physical constant registers and NOT immedates. - // Immedates will result in compiler un-optimizing. - // {xyzw} = float4(1.0, -1.0, 0.25, -0.25) - FxaaFloat4 fxaaConsole360ConstDir -) { -/*--------------------------------------------------------------------------*/ - FxaaFloat2 posM; - posM.x = pos.x; - posM.y = pos.y; - #if (FXAA_GATHER4_ALPHA == 1) - #if (FXAA_DISCARD == 0) - FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); - #if (FXAA_GREEN_AS_LUMA == 0) - #define lumaM rgbyM.w - #else - #define lumaM rgbyM.y - #endif - #endif - #if (FXAA_GREEN_AS_LUMA == 0) - FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM); - FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1)); - #else - FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM); - FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1)); - #endif - #if (FXAA_DISCARD == 1) - #define lumaM luma4A.w - #endif - #define lumaE luma4A.z - #define lumaS luma4A.x - #define lumaSE luma4A.y - #define lumaNW luma4B.w - #define lumaN luma4B.z - #define lumaW luma4B.x - #else - FxaaFloat4 rgbyM = FxaaTexTop(tex, posM); - #if (FXAA_GREEN_AS_LUMA == 0) - #define lumaM rgbyM.w - #else - #define lumaM rgbyM.y - #endif - FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy)); - #endif -/*--------------------------------------------------------------------------*/ - FxaaFloat maxSM = max(lumaS, lumaM); - FxaaFloat minSM = min(lumaS, lumaM); - FxaaFloat maxESM = max(lumaE, maxSM); - FxaaFloat minESM = min(lumaE, minSM); - FxaaFloat maxWN = max(lumaN, lumaW); - FxaaFloat minWN = min(lumaN, lumaW); - FxaaFloat rangeMax = max(maxWN, maxESM); - FxaaFloat rangeMin = min(minWN, minESM); - FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold; - FxaaFloat range = rangeMax - rangeMin; - FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled); - FxaaBool earlyExit = range < rangeMaxClamped; -/*--------------------------------------------------------------------------*/ - if(earlyExit) - #if (FXAA_DISCARD == 1) - FxaaDiscard; - #else - return rgbyM; - #endif -/*--------------------------------------------------------------------------*/ - #if (FXAA_GATHER4_ALPHA == 0) - FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); - #else - FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy)); - FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy)); - #endif -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaNS = lumaN + lumaS; - FxaaFloat lumaWE = lumaW + lumaE; - FxaaFloat subpixRcpRange = 1.0/range; - FxaaFloat subpixNSWE = lumaNS + lumaWE; - FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS; - FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE; -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaNESE = lumaNE + lumaSE; - FxaaFloat lumaNWNE = lumaNW + lumaNE; - FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE; - FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE; -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaNWSW = lumaNW + lumaSW; - FxaaFloat lumaSWSE = lumaSW + lumaSE; - FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2); - FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2); - FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW; - FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE; - FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4; - FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4; -/*--------------------------------------------------------------------------*/ - FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE; - FxaaFloat lengthSign = fxaaQualityRcpFrame.x; - FxaaBool horzSpan = edgeHorz >= edgeVert; - FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE; -/*--------------------------------------------------------------------------*/ - if(!horzSpan) lumaN = lumaW; - if(!horzSpan) lumaS = lumaE; - if(horzSpan) lengthSign = fxaaQualityRcpFrame.y; - FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM; -/*--------------------------------------------------------------------------*/ - FxaaFloat gradientN = lumaN - lumaM; - FxaaFloat gradientS = lumaS - lumaM; - FxaaFloat lumaNN = lumaN + lumaM; - FxaaFloat lumaSS = lumaS + lumaM; - FxaaBool pairN = abs(gradientN) >= abs(gradientS); - FxaaFloat gradient = max(abs(gradientN), abs(gradientS)); - if(pairN) lengthSign = -lengthSign; - FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange); -/*--------------------------------------------------------------------------*/ - FxaaFloat2 posB; - posB.x = posM.x; - posB.y = posM.y; - FxaaFloat2 offNP; - offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x; - offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y; - if(!horzSpan) posB.x += lengthSign * 0.5; - if( horzSpan) posB.y += lengthSign * 0.5; -/*--------------------------------------------------------------------------*/ - FxaaFloat2 posN; - posN.x = posB.x - offNP.x * FXAA_QUALITY__P0; - posN.y = posB.y - offNP.y * FXAA_QUALITY__P0; - FxaaFloat2 posP; - posP.x = posB.x + offNP.x * FXAA_QUALITY__P0; - posP.y = posB.y + offNP.y * FXAA_QUALITY__P0; - FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0; - FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN)); - FxaaFloat subpixE = subpixC * subpixC; - FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP)); -/*--------------------------------------------------------------------------*/ - if(!pairN) lumaNN = lumaSS; - FxaaFloat gradientScaled = gradient * 1.0/4.0; - FxaaFloat lumaMM = lumaM - lumaNN * 0.5; - FxaaFloat subpixF = subpixD * subpixE; - FxaaBool lumaMLTZero = lumaMM < 0.0; -/*--------------------------------------------------------------------------*/ - lumaEndN -= lumaNN * 0.5; - lumaEndP -= lumaNN * 0.5; - FxaaBool doneN = abs(lumaEndN) >= gradientScaled; - FxaaBool doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1; - FxaaBool doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1; -/*--------------------------------------------------------------------------*/ - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 3) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 4) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 5) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 6) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 7) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 8) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 9) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 10) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 11) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11; -/*--------------------------------------------------------------------------*/ - #if (FXAA_QUALITY__PS > 12) - if(doneNP) { - if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy)); - if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy)); - if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5; - if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5; - doneN = abs(lumaEndN) >= gradientScaled; - doneP = abs(lumaEndP) >= gradientScaled; - if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12; - if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12; - doneNP = (!doneN) || (!doneP); - if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12; - if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12; -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } - #endif -/*--------------------------------------------------------------------------*/ - } -/*--------------------------------------------------------------------------*/ - FxaaFloat dstN = posM.x - posN.x; - FxaaFloat dstP = posP.x - posM.x; - if(!horzSpan) dstN = posM.y - posN.y; - if(!horzSpan) dstP = posP.y - posM.y; -/*--------------------------------------------------------------------------*/ - FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero; - FxaaFloat spanLength = (dstP + dstN); - FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero; - FxaaFloat spanLengthRcp = 1.0/spanLength; -/*--------------------------------------------------------------------------*/ - FxaaBool directionN = dstN < dstP; - FxaaFloat dst = min(dstN, dstP); - FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP; - FxaaFloat subpixG = subpixF * subpixF; - FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5; - FxaaFloat subpixH = subpixG * fxaaQualitySubpix; -/*--------------------------------------------------------------------------*/ - FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0; - FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH); - if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign; - if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign; - #if (FXAA_DISCARD == 1) - return FxaaTexTop(tex, posM); - #else - return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM); - #endif -} -/*==========================================================================*/ -#endif - - - - -/*============================================================================ - - FXAA3 CONSOLE - PC VERSION - ------------------------------------------------------------------------------- -Instead of using this on PC, I'd suggest just using FXAA Quality with - #define FXAA_QUALITY__PRESET 10 -Or - #define FXAA_QUALITY__PRESET 20 -Either are higher qualilty and almost as fast as this on modern PC GPUs. -============================================================================*/ -#if (FXAA_PC_CONSOLE == 1) -/*--------------------------------------------------------------------------*/ -FxaaFloat4 FxaaPixelShader( - // See FXAA Quality FxaaPixelShader() source for docs on Inputs! - FxaaFloat2 pos, - FxaaFloat4 fxaaConsolePosPos, - FxaaTex tex, - FxaaTex fxaaConsole360TexExpBiasNegOne, - FxaaTex fxaaConsole360TexExpBiasNegTwo, - FxaaFloat2 fxaaQualityRcpFrame, - FxaaFloat4 fxaaConsoleRcpFrameOpt, - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - FxaaFloat fxaaQualitySubpix, - FxaaFloat fxaaQualityEdgeThreshold, - FxaaFloat fxaaQualityEdgeThresholdMin, - FxaaFloat fxaaConsoleEdgeSharpness, - FxaaFloat fxaaConsoleEdgeThreshold, - FxaaFloat fxaaConsoleEdgeThresholdMin, - FxaaFloat4 fxaaConsole360ConstDir -) { -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy)); - FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw)); - FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy)); - FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw)); -/*--------------------------------------------------------------------------*/ - FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy); - #if (FXAA_GREEN_AS_LUMA == 0) - FxaaFloat lumaM = rgbyM.w; - #else - FxaaFloat lumaM = rgbyM.y; - #endif -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw); - lumaNe += 1.0/384.0; - FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw); -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe); - FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe); -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw); - FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw); -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold; -/*--------------------------------------------------------------------------*/ - FxaaFloat lumaMinM = min(lumaMin, lumaM); - FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled); - FxaaFloat lumaMaxM = max(lumaMax, lumaM); - FxaaFloat dirSwMinusNe = lumaSw - lumaNe; - FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM; - FxaaFloat dirSeMinusNw = lumaSe - lumaNw; - if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM; -/*--------------------------------------------------------------------------*/ - FxaaFloat2 dir; - dir.x = dirSwMinusNe + dirSeMinusNw; - dir.y = dirSwMinusNe - dirSeMinusNw; -/*--------------------------------------------------------------------------*/ - FxaaFloat2 dir1 = normalize(dir.xy); - FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw); - FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw); -/*--------------------------------------------------------------------------*/ - FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness; - FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0); -/*--------------------------------------------------------------------------*/ - FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw); - FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw); -/*--------------------------------------------------------------------------*/ - FxaaFloat4 rgbyA = rgbyN1 + rgbyP1; - FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25); -/*--------------------------------------------------------------------------*/ - #if (FXAA_GREEN_AS_LUMA == 0) - FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax); - #else - FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax); - #endif - if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5; - return rgbyB; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - 360 PIXEL SHADER - ------------------------------------------------------------------------------- -This optimized version thanks to suggestions from Andy Luedke. -Should be fully tex bound in all cases. -As of the FXAA 3.11 release, I have still not tested this code, -however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10. -And note this is replacing the old unoptimized version. -If it does not work, please let me know so I can fix it. -============================================================================*/ -#if (FXAA_360 == 1) -/*--------------------------------------------------------------------------*/ -[reduceTempRegUsage(4)] -float4 FxaaPixelShader( - // See FXAA Quality FxaaPixelShader() source for docs on Inputs! - FxaaFloat2 pos, - FxaaFloat4 fxaaConsolePosPos, - FxaaTex tex, - FxaaTex fxaaConsole360TexExpBiasNegOne, - FxaaTex fxaaConsole360TexExpBiasNegTwo, - FxaaFloat2 fxaaQualityRcpFrame, - FxaaFloat4 fxaaConsoleRcpFrameOpt, - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - FxaaFloat fxaaQualitySubpix, - FxaaFloat fxaaQualityEdgeThreshold, - FxaaFloat fxaaQualityEdgeThresholdMin, - FxaaFloat fxaaConsoleEdgeSharpness, - FxaaFloat fxaaConsoleEdgeThreshold, - FxaaFloat fxaaConsoleEdgeThresholdMin, - FxaaFloat4 fxaaConsole360ConstDir -) { -/*--------------------------------------------------------------------------*/ - float4 lumaNwNeSwSe; - #if (FXAA_GREEN_AS_LUMA == 0) - asm { - tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false - }; - #else - asm { - tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false - tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false - }; - #endif -/*--------------------------------------------------------------------------*/ - lumaNwNeSwSe.y += 1.0/384.0; - float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); - float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw); - float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y); - float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y); -/*--------------------------------------------------------------------------*/ - float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0)); - #if (FXAA_GREEN_AS_LUMA == 0) - float lumaMinM = min(lumaMin, rgbyM.w); - float lumaMaxM = max(lumaMax, rgbyM.w); - #else - float lumaMinM = min(lumaMin, rgbyM.y); - float lumaMaxM = max(lumaMax, rgbyM.y); - #endif - if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM; -/*--------------------------------------------------------------------------*/ - float2 dir; - dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx); - dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy); - dir = normalize(dir); -/*--------------------------------------------------------------------------*/ - float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw; -/*--------------------------------------------------------------------------*/ - float4 dir2; - float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness; - dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5); - dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw; -/*--------------------------------------------------------------------------*/ - float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0)); - float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0)); - float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0)); - float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0)); -/*--------------------------------------------------------------------------*/ - float4 rgbyA = rgbyN1 + rgbyP1; - float4 rgbyB = rgbyN2 + rgbyP2 * 0.5 + rgbyA; -/*--------------------------------------------------------------------------*/ - float4 rgbyR = ((rgbyB.w - lumaMax) > 0.0) ? rgbyA : rgbyB; - rgbyR = ((rgbyB.w - lumaMin) > 0.0) ? rgbyR : rgbyA; - return rgbyR; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT) - -============================================================================== -The code below does not exactly match the assembly. -I have a feeling that 12 cycles is possible, but was not able to get there. -Might have to increase register count to get full performance. -Note this shader does not use perspective interpolation. - -Use the following cgc options, - - --fenable-bx2 --fastmath --fastprecision --nofloatbindings - ------------------------------------------------------------------------------- - NVSHADERPERF OUTPUT ------------------------------------------------------------------------------- -For reference and to aid in debug, output of NVShaderPerf should match this, - -Shader to schedule: - 0: texpkb h0.w(TRUE), v5.zyxx, #0 - 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x - 4: texpkb h0.w(TRUE), v5.xwxx, #0 - 6: addh h0.z(TRUE), -h2, h0.w - 7: texpkb h1.w(TRUE), v5, #0 - 9: addh h0.x(TRUE), h0.z, -h1.w - 10: addh h3.w(TRUE), h0.z, h1 - 11: texpkb h2.w(TRUE), v5.zwzz, #0 - 13: addh h0.z(TRUE), h3.w, -h2.w - 14: addh h0.x(TRUE), h2.w, h0 - 15: nrmh h1.xz(TRUE), h0_n - 16: minh_m8 h0.x(TRUE), |h1|, |h1.z| - 17: maxh h4.w(TRUE), h0, h1 - 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n - 19: movr r1.zw(TRUE), v4.xxxy - 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww - 22: minh h5.w(TRUE), h0, h1 - 23: texpkb h0(TRUE), r2.xzxx, #0 - 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1 - 27: maxh h4.x(TRUE), h2.z, h2.w - 28: texpkb h1(TRUE), r0.zwzz, #0 - 30: addh_d2 h1(TRUE), h0, h1 - 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 33: texpkb h0(TRUE), r0, #0 - 35: minh h4.z(TRUE), h2, h2.w - 36: fenct TRUE - 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 39: texpkb h2(TRUE), r1, #0 - 41: addh_d2 h0(TRUE), h0, h2 - 42: maxh h2.w(TRUE), h4, h4.x - 43: minh h2.x(TRUE), h5.w, h4.z - 44: addh_d2 h0(TRUE), h0, h1 - 45: slth h2.x(TRUE), h0.w, h2 - 46: sgth h2.w(TRUE), h0, h2 - 47: movh h0(TRUE), h0 - 48: addx.c0 rc(TRUE), h2, h2.w - 49: movh h0(c0.NE.x), h1 - -IPU0 ------ Simplified schedule: -------- -Pass | Unit | uOp | PC: Op ------+--------+------+------------------------- - 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-; - | | | - 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; - | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0; - | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-; - | | | - 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; - | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0; - | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---; - | SCB1 | add | 10: ADDh h3.w, h0.---z, h1; - | | | - 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | SCB0 | add | 14: ADDh h0.x, h2.w---, h0; - | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-; - | | | - 5 | SCT1 | mov | 15: NRMh h1.xz, h0; - | SRB | nrm | 15: NRMh h1.xz, h0; - | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|; - | SCB1 | max | 17: MAXh h4.w, h0, h1; - | | | - 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0; - | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy; - | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-; - | SCB1 | min | 22: MINh h5.w, h0, h1; - | | | - 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; - | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0; - | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---; - | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1; - | | | - 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; - | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0; - | SCB0/1 | add | 30: ADDh/2 h1, h0, h1; - | | | - 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--; - | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0; - | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0; - | SCB1 | min | 35: MINh h4.z, h2, h2.--w-; - | | | - 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--; - | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0; - | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0; - | SCB0/1 | add | 41: ADDh/2 h0, h0, h2; - | | | - 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---; - | SCT1 | max | 42: MAXh h2.w, h4, h4.---x; - | SCB0/1 | add | 44: ADDh/2 h0, h0, h1; - | | | - 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2; - | SCT1 | set | 46: SGTh h2.w, h0, h2; - | SCB0/1 | mul | 47: MOVh h0, h0; - | | | - 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---; - | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1; - -Pass SCT TEX SCB - 1: 0% 100% 25% - 2: 0% 100% 25% - 3: 0% 100% 50% - 4: 0% 100% 50% - 5: 0% 0% 50% - 6: 100% 0% 75% - 7: 0% 100% 75% - 8: 0% 100% 100% - 9: 0% 100% 25% - 10: 0% 100% 100% - 11: 50% 0% 100% - 12: 50% 0% 100% - 13: 25% 0% 100% - -MEAN: 17% 61% 67% - -Pass SCT0 SCT1 TEX SCB0 SCB1 - 1: 0% 0% 100% 0% 100% - 2: 0% 0% 100% 0% 100% - 3: 0% 0% 100% 100% 100% - 4: 0% 0% 100% 100% 100% - 5: 0% 0% 0% 100% 100% - 6: 100% 100% 0% 100% 100% - 7: 0% 0% 100% 100% 100% - 8: 0% 0% 100% 100% 100% - 9: 0% 0% 100% 0% 100% - 10: 0% 0% 100% 100% 100% - 11: 100% 100% 0% 100% 100% - 12: 100% 100% 0% 100% 100% - 13: 100% 0% 0% 100% 100% - -MEAN: 30% 23% 61% 76% 100% -Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 -Results 13 cycles, 3 r regs, 923,076,923 pixels/s -============================================================================*/ -#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0) -/*--------------------------------------------------------------------------*/ -#pragma regcount 7 -#pragma disablepc all -#pragma option O3 -#pragma option OutColorPrec=fp16 -#pragma texformat default RGBA8 -/*==========================================================================*/ -half4 FxaaPixelShader( - // See FXAA Quality FxaaPixelShader() source for docs on Inputs! - FxaaFloat2 pos, - FxaaFloat4 fxaaConsolePosPos, - FxaaTex tex, - FxaaTex fxaaConsole360TexExpBiasNegOne, - FxaaTex fxaaConsole360TexExpBiasNegTwo, - FxaaFloat2 fxaaQualityRcpFrame, - FxaaFloat4 fxaaConsoleRcpFrameOpt, - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - FxaaFloat fxaaQualitySubpix, - FxaaFloat fxaaQualityEdgeThreshold, - FxaaFloat fxaaQualityEdgeThresholdMin, - FxaaFloat fxaaConsoleEdgeSharpness, - FxaaFloat fxaaConsoleEdgeThreshold, - FxaaFloat fxaaConsoleEdgeThresholdMin, - FxaaFloat4 fxaaConsole360ConstDir -) { -/*--------------------------------------------------------------------------*/ -// (1) - half4 dir; - half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - lumaNe.w += half(1.0/512.0); - dir.x = -lumaNe.w; - dir.z = -lumaNe.w; - #else - lumaNe.y += half(1.0/512.0); - dir.x = -lumaNe.y; - dir.z = -lumaNe.y; - #endif -/*--------------------------------------------------------------------------*/ -// (2) - half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - dir.x += lumaSw.w; - dir.z += lumaSw.w; - #else - dir.x += lumaSw.y; - dir.z += lumaSw.y; - #endif -/*--------------------------------------------------------------------------*/ -// (3) - half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - dir.x -= lumaNw.w; - dir.z += lumaNw.w; - #else - dir.x -= lumaNw.y; - dir.z += lumaNw.y; - #endif -/*--------------------------------------------------------------------------*/ -// (4) - half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - dir.x += lumaSe.w; - dir.z -= lumaSe.w; - #else - dir.x += lumaSe.y; - dir.z -= lumaSe.y; - #endif -/*--------------------------------------------------------------------------*/ -// (5) - half4 dir1_pos; - dir1_pos.xy = normalize(dir.xyz).xz; - half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); -/*--------------------------------------------------------------------------*/ -// (6) - half4 dir2_pos; - dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0)); - dir1_pos.zw = pos.xy; - dir2_pos.zw = pos.xy; - half4 temp1N; - temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ -// (7) - temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); - half4 rgby1; - rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; -/*--------------------------------------------------------------------------*/ -// (8) - rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); - rgby1 = (temp1N + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (9) - half4 temp2N; - temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; - temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); -/*--------------------------------------------------------------------------*/ -// (10) - half4 rgby2; - rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; - rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); - rgby2 = (temp2N + rgby2) * 0.5; -/*--------------------------------------------------------------------------*/ -// (11) - // compilier moves these scalar ops up to other cycles - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w)); - half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w)); - #else - half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y)); - half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y)); - #endif - rgby2 = (rgby2 + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (12) - #if (FXAA_GREEN_AS_LUMA == 0) - bool twoTapLt = rgby2.w < lumaMin; - bool twoTapGt = rgby2.w > lumaMax; - #else - bool twoTapLt = rgby2.y < lumaMin; - bool twoTapGt = rgby2.y > lumaMax; - #endif -/*--------------------------------------------------------------------------*/ -// (13) - if(twoTapLt || twoTapGt) rgby2 = rgby1; -/*--------------------------------------------------------------------------*/ - return rgby2; } -/*==========================================================================*/ -#endif - - - -/*============================================================================ - - FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT) - -============================================================================== -The code mostly matches the assembly. -I have a feeling that 14 cycles is possible, but was not able to get there. -Might have to increase register count to get full performance. -Note this shader does not use perspective interpolation. - -Use the following cgc options, - - --fenable-bx2 --fastmath --fastprecision --nofloatbindings - -Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks). -Will look at fixing this for FXAA 3.12. ------------------------------------------------------------------------------- - NVSHADERPERF OUTPUT ------------------------------------------------------------------------------- -For reference and to aid in debug, output of NVShaderPerf should match this, - -Shader to schedule: - 0: texpkb h0.w(TRUE), v5.zyxx, #0 - 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x - 4: texpkb h1.w(TRUE), v5.xwxx, #0 - 6: addh h0.x(TRUE), h1.w, -h2.y - 7: texpkb h2.w(TRUE), v5.zwzz, #0 - 9: minh h4.w(TRUE), h2.y, h2 - 10: maxh h5.x(TRUE), h2.y, h2.w - 11: texpkb h0.w(TRUE), v5, #0 - 13: addh h3.w(TRUE), -h0, h0.x - 14: addh h0.x(TRUE), h0.w, h0 - 15: addh h0.z(TRUE), -h2.w, h0.x - 16: addh h0.x(TRUE), h2.w, h3.w - 17: minh h5.y(TRUE), h0.w, h1.w - 18: nrmh h2.xz(TRUE), h0_n - 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z| - 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w - 21: movr r1.zw(TRUE), v4.xxxy - 22: maxh h2.w(TRUE), h0, h1 - 23: fenct TRUE - 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz - 26: texpkb h0(TRUE), r0, #0 - 28: maxh h5.x(TRUE), h2.w, h5 - 29: minh h5.w(TRUE), h5.y, h4 - 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz - 32: texpkb h2(TRUE), r1, #0 - 34: addh_d2 h2(TRUE), h0, h2 - 35: texpkb h1(TRUE), v4, #0 - 37: maxh h5.y(TRUE), h5.x, h1.w - 38: minh h4.w(TRUE), h1, h5 - 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 41: texpkb h0(TRUE), r0, #0 - 43: addh_m8 h5.z(TRUE), h5.y, -h4.w - 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz - 46: texpkb h3(TRUE), r2, #0 - 48: addh_d2 h0(TRUE), h0, h3 - 49: addh_d2 h3(TRUE), h0, h2 - 50: movh h0(TRUE), h3 - 51: slth h3.x(TRUE), h3.w, h5.w - 52: sgth h3.w(TRUE), h3, h5.x - 53: addx.c0 rc(TRUE), h3.x, h3 - 54: slth.c0 rc(TRUE), h5.z, h5 - 55: movh h0(c0.NE.w), h2 - 56: movh h0(c0.NE.x), h1 - -IPU0 ------ Simplified schedule: -------- -Pass | Unit | uOp | PC: Op ------+--------+------+------------------------- - 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0; - | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--; - | | | - 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; - | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0; - | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---; - | | | - 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0; - | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---; - | SCB1 | min | 9: MINh h4.w, h2.---y, h2; - | | | - 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; - | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0; - | SCB0 | add | 14: ADDh h0.x, h0.w---, h0; - | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x; - | | | - 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---; - | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-; - | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--; - | | | - 6 | SCT1 | mov | 18: NRMh h2.xz, h0; - | SRB | nrm | 18: NRMh h2.xz, h0; - | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|; - | | | - 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--; - | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy; - | SCB1 | max | 22: MAXh h2.w, h0, h1; - | | | - 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--; - | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0; - | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0; - | SCB0 | max | 28: MAXh h5.x, h2.w---, h5; - | SCB1 | min | 29: MINh h5.w, h5.---y, h4; - | | | - 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--; - | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0; - | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0; - | SCB0/1 | add | 34: ADDh/2 h2, h0, h2; - | | | - 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; - | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0; - | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--; - | SCB1 | min | 38: MINh h4.w, h1, h5; - | | | - 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--; - | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0; - | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0; - | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--; - | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-; - | | | - 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0; - | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0; - | SCB0/1 | add | 48: ADDh/2 h0, h0, h3; - | | | - 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2; - | SCB0/1 | mul | 50: MOVh h0, h3; - | | | - 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---; - | SCT1 | set | 52: SGTh h3.w, h3, h5.---x; - | SCB0 | set | 54: SLThc0 rc, h5.z---, h5; - | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3; - | | | - 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2; - | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1; - -Pass SCT TEX SCB - 1: 0% 100% 25% - 2: 0% 100% 25% - 3: 0% 100% 50% - 4: 0% 100% 50% - 5: 50% 0% 25% - 6: 0% 0% 25% - 7: 100% 0% 25% - 8: 0% 100% 50% - 9: 0% 100% 100% - 10: 0% 100% 50% - 11: 0% 100% 75% - 12: 0% 100% 100% - 13: 100% 0% 100% - 14: 50% 0% 50% - 15: 100% 0% 100% - -MEAN: 26% 60% 56% - -Pass SCT0 SCT1 TEX SCB0 SCB1 - 1: 0% 0% 100% 100% 0% - 2: 0% 0% 100% 100% 0% - 3: 0% 0% 100% 100% 100% - 4: 0% 0% 100% 100% 100% - 5: 100% 100% 0% 100% 0% - 6: 0% 0% 0% 0% 100% - 7: 100% 100% 0% 0% 100% - 8: 0% 0% 100% 100% 100% - 9: 0% 0% 100% 100% 100% - 10: 0% 0% 100% 100% 100% - 11: 0% 0% 100% 100% 100% - 12: 0% 0% 100% 100% 100% - 13: 100% 100% 0% 100% 100% - 14: 100% 100% 0% 100% 100% - 15: 100% 100% 0% 100% 100% - -MEAN: 33% 33% 60% 86% 80% -Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5 -Results 15 cycles, 3 r regs, 800,000,000 pixels/s -============================================================================*/ -#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1) -/*--------------------------------------------------------------------------*/ -#pragma regcount 7 -#pragma disablepc all -#pragma option O2 -#pragma option OutColorPrec=fp16 -#pragma texformat default RGBA8 -/*==========================================================================*/ -half4 FxaaPixelShader( - // See FXAA Quality FxaaPixelShader() source for docs on Inputs! - FxaaFloat2 pos, - FxaaFloat4 fxaaConsolePosPos, - FxaaTex tex, - FxaaTex fxaaConsole360TexExpBiasNegOne, - FxaaTex fxaaConsole360TexExpBiasNegTwo, - FxaaFloat2 fxaaQualityRcpFrame, - FxaaFloat4 fxaaConsoleRcpFrameOpt, - FxaaFloat4 fxaaConsoleRcpFrameOpt2, - FxaaFloat4 fxaaConsole360RcpFrameOpt2, - FxaaFloat fxaaQualitySubpix, - FxaaFloat fxaaQualityEdgeThreshold, - FxaaFloat fxaaQualityEdgeThresholdMin, - FxaaFloat fxaaConsoleEdgeSharpness, - FxaaFloat fxaaConsoleEdgeThreshold, - FxaaFloat fxaaConsoleEdgeThresholdMin, - FxaaFloat4 fxaaConsole360ConstDir -) { -/*--------------------------------------------------------------------------*/ -// (1) - half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaNe = rgbyNe.w + half(1.0/512.0); - #else - half lumaNe = rgbyNe.y + half(1.0/512.0); - #endif -/*--------------------------------------------------------------------------*/ -// (2) - half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaSwNegNe = lumaSw.w - lumaNe; - #else - half lumaSwNegNe = lumaSw.y - lumaNe; - #endif -/*--------------------------------------------------------------------------*/ -// (3) - half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaMaxNwSw = max(lumaNw.w, lumaSw.w); - half lumaMinNwSw = min(lumaNw.w, lumaSw.w); - #else - half lumaMaxNwSw = max(lumaNw.y, lumaSw.y); - half lumaMinNwSw = min(lumaNw.y, lumaSw.y); - #endif -/*--------------------------------------------------------------------------*/ -// (4) - half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0)); - #if (FXAA_GREEN_AS_LUMA == 0) - half dirZ = lumaNw.w + lumaSwNegNe; - half dirX = -lumaNw.w + lumaSwNegNe; - #else - half dirZ = lumaNw.y + lumaSwNegNe; - half dirX = -lumaNw.y + lumaSwNegNe; - #endif -/*--------------------------------------------------------------------------*/ -// (5) - half3 dir; - dir.y = 0.0; - #if (FXAA_GREEN_AS_LUMA == 0) - dir.x = lumaSe.w + dirX; - dir.z = -lumaSe.w + dirZ; - half lumaMinNeSe = min(lumaNe, lumaSe.w); - #else - dir.x = lumaSe.y + dirX; - dir.z = -lumaSe.y + dirZ; - half lumaMinNeSe = min(lumaNe, lumaSe.y); - #endif -/*--------------------------------------------------------------------------*/ -// (6) - half4 dir1_pos; - dir1_pos.xy = normalize(dir).xz; - half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS); -/*--------------------------------------------------------------------------*/ -// (7) - half4 dir2_pos; - dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0)); - dir1_pos.zw = pos.xy; - dir2_pos.zw = pos.xy; - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaMaxNeSe = max(lumaNe, lumaSe.w); - #else - half lumaMaxNeSe = max(lumaNe, lumaSe.y); - #endif -/*--------------------------------------------------------------------------*/ -// (8) - half4 temp1N; - temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; - temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0)); - half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe); - half lumaMin = min(lumaMinNwSw, lumaMinNeSe); -/*--------------------------------------------------------------------------*/ -// (9) - half4 rgby1; - rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw; - rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0)); - rgby1 = (temp1N + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (10) - half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0)); - #if (FXAA_GREEN_AS_LUMA == 0) - half lumaMaxM = max(lumaMax, rgbyM.w); - half lumaMinM = min(lumaMin, rgbyM.w); - #else - half lumaMaxM = max(lumaMax, rgbyM.y); - half lumaMinM = min(lumaMin, rgbyM.y); - #endif -/*--------------------------------------------------------------------------*/ -// (11) - half4 temp2N; - temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; - temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0)); - half4 rgby2; - rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw; - half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD; -/*--------------------------------------------------------------------------*/ -// (12) - rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0)); - rgby2 = (temp2N + rgby2) * 0.5; -/*--------------------------------------------------------------------------*/ -// (13) - rgby2 = (rgby2 + rgby1) * 0.5; -/*--------------------------------------------------------------------------*/ -// (14) - #if (FXAA_GREEN_AS_LUMA == 0) - bool twoTapLt = rgby2.w < lumaMin; - bool twoTapGt = rgby2.w > lumaMax; - #else - bool twoTapLt = rgby2.y < lumaMin; - bool twoTapGt = rgby2.y > lumaMax; - #endif - bool earlyExit = lumaRangeM < lumaMax; - bool twoTap = twoTapLt || twoTapGt; -/*--------------------------------------------------------------------------*/ -// (15) - if(twoTap) rgby2 = rgby1; - if(earlyExit) rgby2 = rgbyM; -/*--------------------------------------------------------------------------*/ - return rgby2; } -/*==========================================================================*/ -#endif - - stage override float4 Shading() - { - var texCoord = streams.TexCoord; - - float2 screenPixelRatio = Texture0TexelSize; - return FxaaPixelShader(texCoord, 0, Texture0, Texture0, Texture0, screenPixelRatio, 0, 0, 0, 0.75, 0.063, 0.0312, 8, 0.125, 0.05, 0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/FilmGrainShader.sdsl b/sources/shaders/assets/Stride/SDSL/FilmGrainShader.sdsl deleted file mode 100644 index 9453390c87..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FilmGrainShader.sdsl +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Film-grain shader. - /// Adapted from the shader of Martins Upitis. - /// http://devlog-martinsh.blogspot.ca/2013/05/image-imperfections-and-film-grain-post.html - /// - internal shader FilmGrainShader : ColorTransformShader, Texturing - { - // Amount - float Amount; - - // Time changing at each frame for the animation - float Time; - - // Size of the grain - float GrainSize; - - // How the luminance influences the amount of grain. - float LuminanceFactor; - - override float4 Compute(float4 color) - { - float2 texCoord = streams.TexCoord; - - float2 rotCoordsR = coordRot(texCoord, Time); - float2 newCoord = rotCoordsR / Texture0TexelSize / GrainSize; - float n = pnoise3D(float3(newCoord, 0.0)); - float3 noiseFactor = float3(n, n, n); - - float3 col = color.rgb; - - // Noisiness response curve based on scene luminance - float luminance = lerp(0.0, LuminanceUtils.Luma(col), LuminanceFactor); - float lum = smoothstep(0.2, 0.0, luminance) + luminance; - - noiseFactor = saturate( lerp(noiseFactor, float3(0.0, 0.0, 0.0), pow(lum, 4.0))); - color.rgb += noiseFactor * Amount; - - return color; - } - - // Random texture generation - float4 rnm(float2 tc) - { - float noiseFactor = sin(dot(tc + float2(Time, Time), float2(12.9898, 78.233))) * 43758.5453; - - float4 result = float4( frac(noiseFactor), - frac(noiseFactor * 1.2154), - frac(noiseFactor * 1.3453), - frac(noiseFactor * 1.3647)); - return result * 2.0 - 1; - } - - float fade(float t) { - return Math.Quintic(t); - } - - float pnoise3D(float3 p) - { - float permTexUnit = 1.0 / 256.0; - float permTexUnitHalf = permTexUnit * 0.5; - - float3 pi = permTexUnit * floor(p) + permTexUnitHalf; // Integer part, scaled so +1 moves permTexUnit texel - // and offset 1/2 texel to sample texel centers - float3 pf = frac(p); // Fractional part for interpolation - - // Noise contributions from (x=0, y=0), z=0 and z=1 - float perm00 = rnm(pi.xy).a ; - float3 grad000 = rnm(float2(perm00, pi.z)).rgb * 4.0 - 1.0; - float n000 = dot(grad000, pf); - float3 grad001 = rnm(float2(perm00, pi.z + permTexUnit)).rgb * 4.0 - 1.0; - float n001 = dot(grad001, pf - float3(0.0, 0.0, 1.0)); - - // Noise contributions from (x=0, y=1), z=0 and z=1 - float perm01 = rnm(pi.xy + float2(0.0, permTexUnit)).a ; - float3 grad010 = rnm(float2(perm01, pi.z)).rgb * 4.0 - 1.0; - float n010 = dot(grad010, pf - float3(0.0, 1.0, 0.0)); - float3 grad011 = rnm(float2(perm01, pi.z + permTexUnit)).rgb * 4.0 - 1.0; - float n011 = dot(grad011, pf - float3(0.0, 1.0, 1.0)); - - // Noise contributions from (x=1, y=0), z=0 and z=1 - float perm10 = rnm(pi.xy + float2(permTexUnit, 0.0)).a ; - float3 grad100 = rnm(float2(perm10, pi.z)).rgb * 4.0 - 1.0; - float n100 = dot(grad100, pf - float3(1.0, 0.0, 0.0)); - float3 grad101 = rnm(float2(perm10, pi.z + permTexUnit)).rgb * 4.0 - 1.0; - float n101 = dot(grad101, pf - float3(1.0, 0.0, 1.0)); - - // Noise contributions from (x=1, y=1), z=0 and z=1 - float perm11 = rnm(pi.xy + float2(permTexUnit, permTexUnit)).a ; - float3 grad110 = rnm(float2(perm11, pi.z)).rgb * 4.0 - 1.0; - float n110 = dot(grad110, pf - float3(1.0, 1.0, 0.0)); - float3 grad111 = rnm(float2(perm11, pi.z + permTexUnit)).rgb * 4.0 - 1.0; - float n111 = dot(grad111, pf - float3(1.0, 1.0, 1.0)); - - // Blend contributions along x - float4 n_x = lerp(float4(n000, n001, n010, n011), float4(n100, n101, n110, n111), fade(pf.x)); - - // Blend contributions along y - float2 n_xy = lerp(n_x.xy, n_x.zw, fade(pf.y)); - - // Blend contributions along z - float n_xyz = lerp(n_xy.x, n_xy.y, fade(pf.z)); - - // We're done, return the final noise value. - return n_xyz; - } - - float2 coordRot(float2 tc, float angle) - { - float aspect = Texture0TexelSize.y / Texture0TexelSize.x; - float rotX = ((tc.x * 2.0 - 1.0) * aspect * cos(angle)) - ((tc.y * 2.0 - 1.0) * sin(angle)); - float rotY = ((tc.y * 2.0 - 1.0) * cos(angle)) + ((tc.x * 2.0 - 1.0) * aspect * sin(angle)); - rotX = ((rotX/aspect)*0.5+0.5); - rotY = rotY * 0.5 + 0.5; - return float2(rotX, rotY); - } - - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/FlareArtifactShader.sdsl b/sources/shaders/assets/Stride/SDSL/FlareArtifactShader.sdsl deleted file mode 100644 index 0b212a46a8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FlareArtifactShader.sdsl +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Lens flare artifact shader. - /// - internal shader FlareArtifactShader : ImageEffectShader - { - // Amount of blending - float Amount; - - // Offsets (zoom factor) and distortion of each tap - float2 ZoomOffsetsDistortions[TapCount]; - - // Modulate the color of each tap - float3 ColorAberrations[TapCount]; - - // Aberration strength - float AberrationStrength = 0; - - stage override float4 Shading() - { - float2 uv = streams.TexCoord; - - float2 fromCenterVector = uv - float2(0.5, 0.5); - float squareDistanceToCenter = dot(fromCenterVector, fromCenterVector); - float distanceToCenter = sqrt(squareDistanceToCenter); - - float2 originalUV = uv; - - float3 result = float3(0.0, 0.0, 0.0); - - [unroll] - for (int i = 0; i < TapCount; i++) - { - // Zoom effect - float2 zoomOffsetsDistortions = ZoomOffsetsDistortions[i]; - uv = ( originalUV - 0.5) * zoomOffsetsDistortions.x + 0.5; - - // Distort UV around the center - float distortion = sin(pow(distanceToCenter, zoomOffsetsDistortions.y)); // NOTE: Introducing the zoomOffsetsDistortions local variable prevents glLinkProgram from freezing on some android devices - float2 distortedUV = distortion * (uv - 0.5) + 0.5; - float3 tapColor = Texture0.Sample(LinearSampler, distortedUV).rgb; - - // Avoid hard cuts on the edge (vignetting-like) - float border = 0.1; - float2 borderNear = lerp( float2(0.0, 0.0), float2(1.0, 1.0), (0.5 - abs(distortedUV - 0.5)) / border); - float alpha = saturate(borderNear.x * borderNear.y); - tapColor *= alpha * alpha; - - // Avoid bleeding (could be clamp to border instead) - if (distortedUV.x < 0 || distortedUV.x > 1 || distortedUV.y < 0 || distortedUV.y > 1) tapColor = float3(0.0, 0.0, 0.0); - - /* - // Debug colors - if (i == 0 || i == 3) tapColor.r *= 10; - if (i == 1 || i == 4) tapColor.g *= 10; - if (i == 2 || i == 3 || i == 4) tapColor.b *= 10; - */ - - // Aberration - tapColor *= lerp( float3(1, 1, 1), ColorAberrations[i], AberrationStrength ); - - result += tapColor; - } - - return float4(result * Amount, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/FlareReplicate.sdsl b/sources/shaders/assets/Stride/SDSL/FlareReplicate.sdsl deleted file mode 100644 index 7df477b063..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FlareReplicate.sdsl +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Replicates lens flare artifacts around. - /// - internal shader FlareReplicate : ImageEffectShader - { - - // Amount of blending - float Amount; - - // Halo factor - float HaloFactor; - - stage override float4 Shading() - { - float3 result = float3(0.0, 0.0, 0.0); - float2 originalUV = streams.TexCoord; - float2 uv = originalUV; - - // Initial flares - result += softBorderTap(uv); - - // Same flares downscaled - uv = (originalUV - 0.5) * 2.5 + 0.5; - result += softBorderTap(uv); - - uv = (originalUV - 0.5) * 4.0 + 0.5; - result += softBorderTap(uv); - - - // Symetry with scaling - uv = (originalUV - 0.5) * -4.5 + 0.5; - result += softBorderTap(uv); - - uv = (originalUV - 0.5) * -8.0 + 0.5; - result += softBorderTap(uv); - - - // Add some scale of the original bright pass + double-halo - uv = ( originalUV - 0.5) * -1.0 + 0.5; - result += Texture1.Sample(LinearSampler, uv).rgb * HaloFactor; - - uv = ( originalUV - 0.5) * -0.05 + 0.5; - result += Texture1.Sample(LinearSampler, uv).rgb * Amount; - - uv = ( originalUV - 0.5) * 0.1 + 0.5; - result += Texture1.Sample(LinearSampler, uv).rgb * HaloFactor * 0.5; - - return float4(result, 1.0); - } - - float3 softBorderTap(float2 uv) - { - float border = 0.18; - float2 borderNear = lerp( float2(0.0, 0.0), float2(1.0, 1.0), (0.5 - abs(uv - 0.5)) / border); - float alpha = saturate(borderNear.x * borderNear.y); - float3 result = Texture0.Sample(LinearSampler, uv).rgb * alpha; - if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) result = float3(0.0, 0.0, 0.0); - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/FlattenLayers.sdsl b/sources/shaders/assets/Stride/SDSL/FlattenLayers.sdsl deleted file mode 100644 index 51ecff4120..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FlattenLayers.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Outputs the result of a compute color (useful to perform offline texture creation). -/// -shader FlattenLayers : ShaderBase, PositionStream4 -{ - compose ComputeColor outColor; - - stage override void VSMain() - { - base.VSMain(); - streams.ShadingPosition = streams.Position; - } - - stage override void PSMain() - { - base.PSMain(); - streams.ColorTarget = outColor.Compute(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/FogEffect.sdsl b/sources/shaders/assets/Stride/SDSL/FogEffect.sdsl deleted file mode 100644 index 927b5319f4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/FogEffect.sdsl +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Simple fog - /// - internal shader FogEffect : ImageEffectShader - { - stage float FogStart; - stage float Density; - stage float zFar; - stage float zNear; - stage bool skipBG; - - stage float3 FogColor; - stage Texture2D DepthTexture; - - stage override float4 Shading() - { - float4 color = Texture0.Sample(PointSampler, streams.TexCoord); - float z_b = DepthTexture.SampleLevel(PointSampler, streams.TexCoord, 0.0).x; - - if (!skipBG || z_b < 1.0) { - float z_n = 2.0 * z_b - 1.0; - float dist = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); - dist -= FogStart; - - float fogAmount = clamp(exp(dist * -Density), 0.0, 1.0); - - color.xyz = lerp(FogColor, color.xyz, fogAmount); - } - - return color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ForEachTest.sdsl b/sources/shaders/assets/Stride/SDSL/ForEachTest.sdsl deleted file mode 100644 index 3f9b08c2af..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ForEachTest.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ForEachTest -{ - float collec[5]; - - float test() - { - float res = 0.0; - foreach (var val in collec) - { - res += val; - } - return res; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/GBuffer.sdsl b/sources/shaders/assets/Stride/SDSL/GBuffer.sdsl deleted file mode 100644 index a560d7de83..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GBuffer.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Deferred -{ - /// - /// An array of light groups - /// - shader GBuffer : ShaderBase, MaterialPixelStream - { - stage override void PSMain() - { - base.PSMain(); - - streams.ColorTarget = float4(streams.normalWS, 1.0f); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/GBufferOutputNormals.sdsl b/sources/shaders/assets/Stride/SDSL/GBufferOutputNormals.sdsl deleted file mode 100644 index 7c1585c251..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GBufferOutputNormals.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials.Shaders -{ - /// - /// Outputs material world space normal vectors (packed from [-1;-1] to [0;1] to fit smaller render targets) - /// - shader GBufferOutputNormals : ComputeColor, MaterialPixelShadingStream, NormalPack - { - override float4 Compute() - { - return float4(EncodeNormal(streams.normalWS), 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl b/sources/shaders/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl deleted file mode 100644 index 0d5fca8567..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GBufferOutputSpecularColorRoughness.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials.Shaders -{ - /// - /// Outputs material specular color (RGB) and roughness (A) - /// - shader GBufferOutputSpecularColorRoughness : ComputeColor, MaterialPixelShadingStream, Utilities - { - override float4 Compute() - { - return float4(streams.matSpecularVisible, sqrt(streams.alphaRoughness)); // alphaRoughness = roughness^2 - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl b/sources/shaders/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl deleted file mode 100644 index 1ba7541a6a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GBufferOutputSubsurfaceScatteringMaterialIndex.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// - class GBufferOutputSubsurfaceScatteringMaterialIndex : ComputeColor - { - cbuffer PerDraw - { - // TODO: How to initialize this to 0 at all times for every material? - stage uint MaterialIndex; // This is only defined here so it can be overwritten by SubsurfaceScatteringRenderFeature in order to index the material inside the post process. - } - - override float4 Compute() - { - return MaterialIndex; - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/GaussianBlurShader.sdsl b/sources/shaders/assets/Stride/SDSL/GaussianBlurShader.sdsl deleted file mode 100644 index c7335bcd14..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GaussianBlurShader.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A gaussian blur shader - /// - internal shader GaussianBlurShader : ImageEffectShader - { - stage float2 OffsetsWeights[BlurCount]; - - stage override float4 Shading() - { - // Direction in texel size: (float2(1,0) or float2(0,1)) * texel size - float2 direction = (IsVertical ? float2(0, 1) : float2(1, 0)) * Texture0TexelSize; - - // Add center - float3 value = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * OffsetsWeights[0].y; - - // mirrored samples using bilinear filtering - [unroll] - for(int i = 1; i < BlurCount; i++) - { - value += Texture0.Sample(LinearSampler, streams.TexCoord - direction * OffsetsWeights[i].x).rgb * OffsetsWeights[i].y; - value += Texture0.Sample(LinearSampler, streams.TexCoord + direction * OffsetsWeights[i].x).rgb * OffsetsWeights[i].y; - } - - return float4(value, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/GenericCall.sdsl b/sources/shaders/assets/Stride/SDSL/GenericCall.sdsl deleted file mode 100644 index e08c997320..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GenericCall.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericCall : TestGenerics<1.000000> -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/GenericClass.sdsl b/sources/shaders/assets/Stride/SDSL/GenericClass.sdsl deleted file mode 100644 index cba53fa421..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GenericClass.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericClass< - Texture2D Texture,// = Texturing.Texture0, - SamplerState Sampler,// = Texturing.Sampler, - Semantic NAME, // = TEXCOORD0 - LinkType myLink, - float constFloat, - int2 constInt2, - uint3 constUInt3, - float4 constUNormFloat4, - float linkVariable -> : TestBaseClass -{ - [Link("GenericLink.myLink")] - stage float3 uniformVariable; - - stage stream float2 texCoord : NAME; - - float genericCompute() - { - float4 value0 = TestBaseClass.Value; - return streams.texCoord.x * Texture.Sample(Sampler, streams.texCoord).x; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/GenericClass2.sdsl b/sources/shaders/assets/Stride/SDSL/GenericClass2.sdsl deleted file mode 100644 index 6d724ee1dd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GenericClass2.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericClass2 -< - Texture2D Texture, - Semantic TEXCOORD_INDEX, - float4 scale -> : ShaderBase, Texturing -{ - stage stream float2 texcoord0 : TEXCOORD_INDEX; - Texture2D TextureAll = Texturing.Texture3; - - stage override void VSMain() - { - streams.ShadingPosition = float4(1,1,1,1) * Texture.SampleLevel(Sampler, streams.texcoord0, 0); - } - - stage override void PSMain() - { - streams.ColorTarget = scale * float4(1,1,1,1) * streams.ShadingPosition * Texturing.Texture1.Sample(Sampler, streams.texcoord0); - streams.ColorTarget = streams.ColorTarget * GenericClass.genericCompute(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/GenericExtern.sdsl b/sources/shaders/assets/Stride/SDSL/GenericExtern.sdsl deleted file mode 100644 index 655f2afb72..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GenericExtern.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericExtern -{ - compose GenericTexcoord myExtern; -}; diff --git a/sources/shaders/assets/Stride/SDSL/GenericTexcoord.sdsl b/sources/shaders/assets/Stride/SDSL/GenericTexcoord.sdsl deleted file mode 100644 index 6ce943dc08..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GenericTexcoord.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericTexcoord -{ - float2 coords : T; -}; diff --git a/sources/shaders/assets/Stride/SDSL/GeometryShaderTest.sdsl b/sources/shaders/assets/Stride/SDSL/GeometryShaderTest.sdsl deleted file mode 100644 index 17f90de8ce..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GeometryShaderTest.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GeometryShaderTest : TestStructure -{ - void testGS0(point Input input[1], TriangleStream param){} - void testGS1(LineStream param){} - void testGS2(PointStream param){} -}; diff --git a/sources/shaders/assets/Stride/SDSL/Global.sdsl b/sources/shaders/assets/Stride/SDSL/Global.sdsl deleted file mode 100644 index 87c3072068..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Global.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Global -{ - cbuffer PerFrame { - stage float Time; - stage float TimeStep; - }; -}; diff --git a/sources/shaders/assets/Stride/SDSL/GlobalVR.sdsl b/sources/shaders/assets/Stride/SDSL/GlobalVR.sdsl deleted file mode 100644 index 0d4e9af756..0000000000 --- a/sources/shaders/assets/Stride/SDSL/GlobalVR.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GlobalVR -{ - cbuffer PerView.GlobalVR { - stage int EyeIndex; - stage int EyeCount; - }; -}; diff --git a/sources/shaders/assets/Stride/SDSL/HSVUtils.sdsl b/sources/shaders/assets/Stride/SDSL/HSVUtils.sdsl deleted file mode 100644 index 70354af21d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/HSVUtils.sdsl +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various helper functions to convert color between RGB and HSV. -/// -shader HSVUtils -{ - float GetSaturation(float3 tex) - { - float e = 1.0e-10; - float maxChannel = max(max(tex.r, tex.g), tex.b); - if(maxChannel < e) - return 0.0f; - else - return 1.0f - min(min(tex.r, tex.g), tex.b) / maxChannel; - } - - float GetValue(float3 tex) - { - return max(max(tex.r, tex.g), tex.b); - } - - float GetHue(float3 tex) - { - float e = 1.0e-10; - float maxChannel = max(max(tex.r, tex.g), tex.b); - - float delta = maxChannel - min(min(tex.r, tex.g), tex.b); - if (delta < e) - return 0.0f; - if(maxChannel == tex.r) - { - return frac(1.0f + (tex.g - tex.b) / (6.0f * delta)); - } - else if(maxChannel == tex.g) - { - return 1.0f / 3.0f + (tex.b - tex.r) / (6.0f * delta); - } - else - { - return 2.0f / 3.0f + (tex.r - tex.g) / (6.0f * delta); - } - } - /* - float3 ToHSV(float3 tex) - { - return float3(GetHue(tex), GetSaturation(tex), GetValue(tex)); - } - - float3 ToRGB(float3 hsv) - { - - float s = hsl[1]; - float v = hsl[2]; - - if(s == 0) - return float3(v); - - float h = hsl[0]; - - int i = floor(h); - float f = h - i; - float p = v * (1.0f - s); - float q = v * (1.0f - s * f); - float t = v * (1.0f - s * (1.0f - f)); - - switch(i) - { - case 0 : - return float3(v, t, p); - case 1 : - return float3(q, v, p); - case 2 : - return float3(p, v, t); - case 3 : - return float3(p, q, v); - case 4 : - return float3(t, p, v); - default : - return float3(v, p, q); - } - } - */ - // From http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl - float3 ToHSV(float3 color) - { - float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - float4 p = lerp(float4(color.bg, K.wz), float4(color.gb, K.xy), step(color.b, color.g)); - float4 q = lerp(float4(p.xyw, color.r), float4(color.r, p.yzx), step(p.x, color.r)); - - float d = q.x - min(q.w, q.y); - float e = 1.0e-10; - return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); - } - - float3 ToRGB(float3 color) - { - float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - float3 p = abs(frac(color.xxx + K.xyz) * 6.0 - K.www); - return color.z * lerp(K.xxx, saturate(p - K.xxx), color.y); - } - -}; diff --git a/sources/shaders/assets/Stride/SDSL/Hammersley.sdsl b/sources/shaders/assets/Stride/SDSL/Hammersley.sdsl deleted file mode 100644 index 48c399d9f0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Hammersley.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Hammersley sampling on a Plane, Sphere, etc... - /// - shader Hammersley : Math - { - float2 GetSamplePlane(int k, int samplesCount) - { - var u = 0.0; - var p = 0.5; - for (int kk=k; kk; p*=0.5, kk>>=1) - { - if (kk & 1) // kk mod 2 == 1 - u += p; - } - - var v = (k + 0.5) / samplesCount; - - return float2(u,v); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/HammersleyTest.sdsl b/sources/shaders/assets/Stride/SDSL/HammersleyTest.sdsl deleted file mode 100644 index 9338b60529..0000000000 --- a/sources/shaders/assets/Stride/SDSL/HammersleyTest.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader HammersleyTest : ComputeShaderBase -{ - stage int SamplesCount; - - RWTexture2D OutputTexture; - - // Shading of the sprite - override void Compute() - { - var xy = Hammersley.GetSamplePlane(streams.ThreadGroupIndex, SamplesCount); - - uint width, height; - OutputTexture.GetDimensions(width, height); - - OutputTexture[xy * float2(width, height)] = float4(1, 0, 0, 1); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/HighlightShader.sdsl b/sources/shaders/assets/Stride/SDSL/HighlightShader.sdsl deleted file mode 100644 index 05e97f91d8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/HighlightShader.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering -{ - // TODO GRAPHICS REFACTOR: Unify passthrough color shaders (picking, highlight, etc.) - shader HighlightShader : ShaderBase - { - cbuffer PerDraw - { - stage float4 HighlightColor; - } - - stage override void PSMain() - { - streams.ColorTarget = HighlightColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl b/sources/shaders/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl deleted file mode 100644 index f5a1431a24..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IComputeEnvironmentColor.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - /// - /// Base shader to sample an environment - /// - shader IComputeEnvironmentColor - { - float4 Compute(float3 direction) - { - return 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl deleted file mode 100644 index f27432c8c4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialCelShadingLightFunction.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - class IMaterialCelShadingLightFunction : MaterialPixelShadingStream - { - float3 Compute(float lightIn) - { - return float3(lightIn, lightIn, lightIn); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl deleted file mode 100644 index c953febd16..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialHairDirectionFunction.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class IMaterialHairDirectionFunction - { - abstract float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose); - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl deleted file mode 100644 index fc67a2eb75..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialHairDiscardFunction.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Common interface for discarding pixels for the hair shading model. - /// - class IMaterialHairDiscardFunction - { - // TODO: Can't we move the cbuffer with the HairAlphaThreshold here? - abstract void Discard(void); - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl deleted file mode 100644 index 19f5d994f0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialHairLightAttenuationFunction.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class IMaterialHairLightAttenuationFunction - { - abstract float Compute(void); - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl deleted file mode 100644 index 72b7f28abf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialHairShadowingFunction.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class IMaterialHairShadowingFunction - { - abstract float3 Compute(); - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl deleted file mode 100644 index a1bba7ba0a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetEnvironmentFunction.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet IBL environment (DFG) function - /// - shader IMaterialSpecularMicrofacetEnvironmentFunction : MaterialPixelShadingStream, BRDFMicrofacet - { - float3 Compute(float3 specularColor, float alphaR, float nDotV) - { - return 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl deleted file mode 100644 index 80ee00b2df..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetFresnelFunction.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader IMaterialSpecularMicrofacetFresnelFunction : MaterialPixelShadingStream, BRDFMicrofacet - { - // TODO: We could provide f90 as well - float3 Compute(float3 f0) - { - return FresnelNone(f0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl deleted file mode 100644 index f035efadfa..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetNormalDistributionFunction.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Normal Distribution function - /// - shader IMaterialSpecularMicrofacetNormalDistributionFunction : MaterialPixelShadingStream, BRDFMicrofacet - { - float Compute() - { - return NormalDistributionBlinnPhong(streams.alphaRoughness, streams.NdotH); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl deleted file mode 100644 index 2467ee9bbe..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSpecularMicrofacetVisibilityFunction.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader IMaterialSpecularMicrofacetVisibilityFunction : MaterialPixelShadingStream, BRDFMicrofacet - { - float Compute() - { - return VisibilityImplicit(streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialStreamBlend.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialStreamBlend.sdsl deleted file mode 100644 index 29281974b9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialStreamBlend.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// An interface to blend a stream - /// - shader IMaterialStreamBlend : MaterialStream, MaterialVertexStream, MaterialPixelStream - { - void Compute(Streams fromStream) - { - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl deleted file mode 100644 index 005ca3b78e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSubsurfaceScatteringScatteringProfile.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class IMaterialSubsurfaceScatteringScatteringProfile - { - void Prepare(void) // Called once at the beginning of the shader. - { - } - - abstract float3 Compute(float dd); // Called once per light. - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSurface.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSurface.sdsl deleted file mode 100644 index c0cf2e91be..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSurface.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for a material layer - /// - shader IMaterialSurface : MaterialStream // TODO: provide a way to extend MaterialStream easily - { - void Compute() - { - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl deleted file mode 100644 index 0aa099a035..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceDomain.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for a material layer (vertex stage) - /// - shader IMaterialSurfaceDomain : IMaterialSurface, MaterialDomainStream - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl deleted file mode 100644 index 73c8e12f6e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSurfacePixel.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for a material layer - /// - shader IMaterialSurfacePixel : IMaterialSurface, MaterialPixelStream - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl deleted file mode 100644 index 5909f82996..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceShading.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for a material layer shading. - /// - shader IMaterialSurfaceShading : MaterialPixelStream, LightStream - { - void PrepareForLightingAndShading() - { - } - - float3 ComputeDirectLightContribution() - { - return 0; - } - - float3 ComputeEnvironmentLightContribution() - { - return 0; - } - - void AfterLightingAndShading() - { - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl b/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl deleted file mode 100644 index 8506bb6759..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IMaterialSurfaceVertex.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for a material layer (vertex stage) - /// - shader IMaterialSurfaceVertex : IMaterialSurface, MaterialVertexStream - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IStreamInitializer.sdsl b/sources/shaders/assets/Stride/SDSL/IStreamInitializer.sdsl deleted file mode 100644 index 2c66a0d0e5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IStreamInitializer.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Base interface for initializing streams - /// - shader IStreamInitializer - { - void ResetStream() - { - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/IVoxelSampler.sdsl b/sources/shaders/assets/Stride/SDSL/IVoxelSampler.sdsl deleted file mode 100644 index 3861f40f16..0000000000 --- a/sources/shaders/assets/Stride/SDSL/IVoxelSampler.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader IVoxelSampler - { - float4 Sample(float3 position, float3 normal, float diameter) - { - return 0; - } - float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - return 0; - } - float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - return 0; - } - float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return float4(1, 0, 0, 0); - } - float VoxelSize() - { - return 1.0; - } - float4 Test() - { - return float4(1,0,0,1); - } - float4 ComputeLocal(float3 position) - { - return 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ImageEffectShader.sdsl b/sources/shaders/assets/Stride/SDSL/ImageEffectShader.sdsl deleted file mode 100644 index 14608ef8bd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ImageEffectShader.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Base shader to perform post effects. Draws the input mesh without transformation. - /// - shader ImageEffectShader : SpriteBase - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ImageScalerShader.sdsl b/sources/shaders/assets/Stride/SDSL/ImageScalerShader.sdsl deleted file mode 100644 index 6ba7d6c2f3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ImageScalerShader.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A copier shader - /// - internal shader ImageScalerShader : ImageEffectShader - { - // TODO: Color and IsOnlyChannelRed could be part of a color filter that we can pre-prend automatically - [Color] - stage float4 Color; - stage float IsOnlyChannelRed; - - // Shading of the sprite - stage override float4 Shading() - { - float4 color = base.Shading(); - if (IsOnlyChannelRed != 0) - { - color = float4(color.rrr, 1); - } - return color * Color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl b/sources/shaders/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl deleted file mode 100644 index ac1895a3a2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ImportanceSamplingGGX.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Importance sampling for the GGX function. - /// - shader ImportanceSamplingGGX : Math - { - float3 GetSample(float2 xi, float roughness, float3 N) - { - float a = roughness * roughness; - float phi = 2 * Math.PI * xi.x; - float CosTheta = sqrt( (1 - xi.y) / ( 1 + (a*a - 1) * xi.y ) ); - float SinTheta = sqrt( 1 - CosTheta * CosTheta ); - - float3 H; - H.x = SinTheta * cos( phi ); - H.y = SinTheta * sin( phi ); - H.z = CosTheta; - - float3 UpVector = abs(N.z) < 0.999 ? float3(0,0,1) : float3(1,0,0); - float3 TangentX = normalize( cross( UpVector, N ) ); - float3 TangentY = cross( N, TangentX ); - - // Tangent to world space - return TangentX * H.x + TangentY * H.y + N * H.z; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/InterfaceTest.sdsl b/sources/shaders/assets/Stride/SDSL/InterfaceTest.sdsl deleted file mode 100644 index f90b316241..0000000000 --- a/sources/shaders/assets/Stride/SDSL/InterfaceTest.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader InterfaceTest -{ - interface myInterface - { - abstract void test(); - }; -}; diff --git a/sources/shaders/assets/Stride/SDSL/InternalReferenceMixin.sdsl b/sources/shaders/assets/Stride/SDSL/InternalReferenceMixin.sdsl deleted file mode 100644 index c337ce8bbe..0000000000 --- a/sources/shaders/assets/Stride/SDSL/InternalReferenceMixin.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader InternalReferenceMixin -{ - float myValue = 2.0f; - - float test() - { - return myValue; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl b/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl deleted file mode 100644 index b51e719d9c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass1.sdsl +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The first pass of a shader performing Lambertian pre-filtering using Spherical Harmonics - /// - shader LambertianPrefilteringSHNoComputePass1 : SphericalHarmonicsBase, ImageEffectShader, Texturing - { - // the input texture containing the radiance - TextureCube RadianceMap; - - // Index of the spherical harmonics coefficient to compute - int CoefficientIndex; - - // The Cosine kernel factors - static const float A0 = 1.0; - static const float A1 = 2.0 / 3.0; - static const float A2 = 1.0 / 4.0; - static const float A3 = 0.0; - static const float A4 = -1.0 / 24.0; - static const float A[5 * 5] = - { - A0, - A1, A1, A1, - A2, A2, A2, A2, A2, - A3, A3, A3, A3, A3, A3, A3, - A4, A4, A4, A4, A4, A4, A4, A4, A4 - }; - - stage override float4 Shading() - { - float3 result = 0; - - float2 uv = streams.TexCoord * 2.0 - 1.0; - - // Calculate weight - float dist = 1.0f + dot(uv, uv); - float weight = 4.0f / (sqrt(dist) * dist); - - [unroll] - for (int faceIndex = 0; faceIndex < 6; faceIndex++) - { - // Extract direction from texel u, v - float3 dirVS = normalize(uvToDirectionVS(uv.x, uv.y, faceIndex)); - - // Calculates the values of the SH bases - EvaluateSHBases(dirVS); - - float3 radiance = RadianceMap.Sample(PointSampler, dirVS).xyz; - - result += A[CoefficientIndex] * streams.SHBaseValues[CoefficientIndex] * radiance * weight; - } - - return float4(result, weight * 6); - } - - float3 uvToDirectionVS(float u, float v, int viewIndex) - { - if (viewIndex == 0) - return float3(1, -v, -u); // face X - if (viewIndex == 1) - return float3(-1, -v, u); // face -X - if (viewIndex == 2) - return float3(u, 1, v); // face Y - if (viewIndex == 3) - return float3(u, -1, -v); // face -Y - if (viewIndex == 4) - return float3(u, -v, 1); // face Z - if (viewIndex == 5) - return float3(-u, -v, -1); // face -Z - - return 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl b/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl deleted file mode 100644 index 8961b52ef7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHNoComputePass2.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The second pass of a shader performing Lambertian pre-filtering using Spherical Harmonics - /// - shader LambertianPrefilteringSHNoComputePass2 : ImageEffectShader, Texturing - { - stage override float4 Shading() - { - float4 result = 0; - - result += Texture0.Sample(PointSampler, streams.TexCoord, int2(-1, 0)); - result += Texture0.Sample(PointSampler, streams.TexCoord, int2(0, 0)); - result += Texture0.Sample(PointSampler, streams.TexCoord, int2(0, -1)); - result += Texture0.Sample(PointSampler, streams.TexCoord, int2(-1, -1)); - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl b/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl deleted file mode 100644 index 290773888d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LambertianPrefilteringSHPass1.sdsl +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The first pass of a shader performing Lambertian pre-filtering using Spherical Harmonics - /// - shader LambertianPrefilteringSHPass1 : SphericalHarmonicsBase, ComputeShaderBase, Texturing - { - // the input texture containing the radiance - TextureCube RadianceMap; - - // the output buffer containing SH coefficient partially summed. - RWBuffer OutputBuffer; - - // The Cosine kernel factors - static const float A0 = 1.0; - static const float A1 = 2.0/3.0; - static const float A2 = 1.0/4.0; - static const float A3 = 0.0; - static const float A4 = -1.0/24.0; - static const float A[5*5] = - { - A0, - A1, A1, A1, - A2, A2, A2, A2, A2, - A3, A3, A3, A3, A3, A3, A3, - A4, A4, A4, A4, A4, A4, A4, A4, A4 - }; - - // Shared memory for summing SH-Basis coefficients for a block - groupshared float4 PartialSHCoeffs[TBlockSize][TBlockSize][CoefficientsCount]; - - // Projects radiance on SH basis and sums results along rows. - override void Compute() - { - // Determine the indices of the texel to compute - const int3 location = int3(streams.GroupThreadId.xy + streams.GroupId.xy * TBlockSize, streams.GroupId.z); - - // Calculate the location in [-1, 1] texture space (center at the pixel center) - float inverseSize = 1 / float(TBlockSize * streams.ThreadGroupCount.x); - float u = ((location.x+0.5) * inverseSize) * 2.0f - 1.0f; - float v = ((location.y+0.5) * inverseSize) * 2.0f - 1.0f; - - // Extract direction from texel u,v - float3 dirVS = normalize(uvToDirectionVS(u, v, location.z)); - float3 radiance = RadianceMap.SampleLevel(Texturing.PointSampler, dirVS, 0).xyz; - - // Calculate weight - var dist = 1.0f + u * u + v * v; - var weight = 4.0f / (sqrt(dist) * dist); - radiance *= weight; - - // Calculates the values of the SH bases - EvaluateSHBases(dirVS); - - // Store the results in the shared memory - [unroll] - for(int c=0; c - /// The second pass of a shader performing Lambertian pre-filtering using Spherical Harmonics - /// - shader LambertianPrefilteringSHPass2 : SphericalHarmonicsBase, ComputeShaderBase, Texturing, Math - { - // the input buffer containing SH coefficients summed up along rows. - Buffer InputBuffer; - - // the output buffer containing the final SH coefficients. - RWBuffer OutputBuffer; - - // Shared memory for reducing SH-Basis coefficients - groupshared float4 PartialSHCoeffs[TSize]; - - // Reduce (sums) the SH coefficients along the columns - override void Compute() - { - int coeffId = streams.GroupId.z; - int threadId = streams.GroupThreadId.x; - int groupId = streams.GroupId.x + streams.ThreadGroupCount.x * streams.GroupId.y; - - // Store in shared memory - PartialSHCoeffs[threadId] = InputBuffer[coeffId + CoefficientsCount * (threadId + TSize * groupId)]; - GroupMemoryBarrierWithGroupSync(); - - // Sum the coefficients - for(int s = TSize / 2; s > 0; s >>= 1) - { - if(threadId < s) - PartialSHCoeffs[threadId] += PartialSHCoeffs[threadId + s]; - - GroupMemoryBarrierWithGroupSync(); - } - - // Have the first thread write out to the output buffer - if (IsFirstThreadOfGroup()) - { - OutputBuffer[coeffId + CoefficientsCount * groupId] = PartialSHCoeffs[0]; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl b/sources/shaders/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl deleted file mode 100644 index dbd5111753..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LevelCubeMapEnvironmentColor.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - /// - /// Sample a cubemap using the MaterialPixelShadingStream roughness parameter. - /// - shader LevelCubeMapEnvironmentColor : IComputeEnvironmentColor, Texturing - { - TextureCube CubeMap; - float MipLevel; - - override float4 Compute(float3 direction) - { - return CubeMap.SampleLevel(LinearSampler, direction, MipLevel); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightClustered.sdsl b/sources/shaders/assets/Stride/SDSL/LightClustered.sdsl deleted file mode 100644 index bed769dc8f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightClustered.sdsl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - shader LightClustered : ScreenPositionBase, ShaderBaseStream, Camera - { - stage stream uint2 lightData; - stage stream int lightIndex; - - rgroup PerView.Lighting - { - stage Texture3D LightClusters; - stage Buffer LightIndices; - } - - cbuffer PerView.Lighting - { - stage float ClusterDepthScale; - stage float ClusterDepthBias; - stage float2 ClusterStride; - } - - void PrepareLightData() - { - float projectedDepth = streams.ShadingPosition.z; - float depth = ZProjection.y / (projectedDepth - ZProjection.x); - - float2 texCoord = float2(streams.ScreenPosition.x + 1, 1 - streams.ScreenPosition.y) * 0.5; - int slice = int(max(log2(depth * ClusterDepthScale + ClusterDepthBias), 0)); - streams.lightData = LightClusters.Load(int4(texCoord * ClusterStride, slice, 0)); - streams.lightIndex = streams.lightData.x; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightClusteredPointGroup.sdsl b/sources/shaders/assets/Stride/SDSL/LightClusteredPointGroup.sdsl deleted file mode 100644 index 7a251ed15b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightClusteredPointGroup.sdsl +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of point lights in clustered shading. - /// - shader LightClusteredPointGroup : DirectLightGroup, LightClustered, LightPoint - { - rgroup PerView.Lighting - { - stage Buffer PointLights; - } - - override void PrepareDirectLights() - { - PrepareLightData(); - } - - override int GetMaxLightCount() - { - return streams.lightData.y & 0xFFFF; - } - - override int GetLightCount() - { - return streams.lightData.y & 0xFFFF; - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - override void PrepareDirectLightCore(int lightIndexIgnored) - { - // What we had so far was just a loop index - // Note: we have lightIndex as a parameter but we ignore it since we want to preserve it between point and spot lights - int realLightIndex = LightIndices.Load(streams.lightIndex); - streams.lightIndex++; - - // Build PointLightData - PointLightDataInternal pointLight; - float4 pointLight1 = PointLights.Load(realLightIndex * 2); - float4 pointLight2 = PointLights.Load(realLightIndex * 2 + 1); - pointLight.PositionWS = pointLight1.xyz; - pointLight.InvSquareRadius = pointLight1.w; - pointLight.Color = pointLight2.xyz; - - // Perform lighting - ProcessLight(pointLight); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl b/sources/shaders/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl deleted file mode 100644 index 2a387ca574..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightClusteredSpotGroup.sdsl +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of spot lights in clustered shading. - /// - shader LightClusteredSpotGroup : - DirectLightGroup, - LightClustered, - LightSpot, // Required for "ProcessLight()". - SpotLightDataInternalShader // Required for "SpotLightDataInternal" - { - rgroup PerView.Lighting - { - stage Buffer SpotLights; - } - - override int GetMaxLightCount() - { - return streams.lightData.y >> 16; - } - - override int GetLightCount() - { - return streams.lightData.y >> 16; - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - override void PrepareDirectLightCore(int lightIndexIgnored) - { - // What we had so far was just a loop index - // Note: we have lightIndex as a parameter but we ignore it since we want to preserve it between point and spot lights - int realLightIndex = LightIndices.Load(streams.lightIndex); - streams.lightIndex++; - - // Build SpotLightData - SpotLightDataInternal spotLight; - float4 spotLight1 = SpotLights.Load(realLightIndex * 4); - float4 spotLight2 = SpotLights.Load(realLightIndex * 4 + 1); - float4 spotLight3 = SpotLights.Load(realLightIndex * 4 + 2); - float4 spotLight4 = SpotLights.Load(realLightIndex * 4 + 3); - spotLight.PositionWS = spotLight1.xyz; - spotLight.DirectionWS = spotLight2.xyz; - spotLight.AngleOffsetAndInvSquareRadius = spotLight3.xyz; - spotLight.Color = spotLight4.xyz; - - // Perform lighting - ProcessLight(spotLight); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightConstantWhite.sdsl b/sources/shaders/assets/Stride/SDSL/LightConstantWhite.sdsl deleted file mode 100644 index 25b2ffba31..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightConstantWhite.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a white environment light - /// - shader LightConstantWhite : EnvironmentLight, LightStream - { - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - streams.envLightDiffuseColor = 1; - streams.envLightSpecularColor = 1; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightDirectional.sdsl b/sources/shaders/assets/Stride/SDSL/LightDirectional.sdsl deleted file mode 100644 index c404e52098..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightDirectional.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a directional light - /// - shader LightDirectional - { - struct DirectionalLightData - { - float3 DirectionWS; - [Color] - float3 Color; - }; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightDirectionalGroup.sdsl b/sources/shaders/assets/Stride/SDSL/LightDirectionalGroup.sdsl deleted file mode 100644 index 36c1e6de65..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightDirectionalGroup.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of directional lights - /// - shader LightDirectionalGroup : DirectLightGroupPerView, LightDirectional - { - cbuffer PerView.Lighting - { - DirectionalLightData Lights[TMaxLightCount]; - } - - override int GetMaxLightCount() - { - return TMaxLightCount; - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - override void PrepareDirectLightCore(int lightIndex) - { - streams.lightColor = Lights[lightIndex].Color; - // TODO: Add support for disk based Directional light - streams.lightDirectionWS = -Lights[lightIndex].DirectionWS; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightPoint.sdsl b/sources/shaders/assets/Stride/SDSL/LightPoint.sdsl deleted file mode 100644 index 96a4946e85..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightPoint.sdsl +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a point light - /// - shader LightPoint : LightUtil, LightStream, PositionStream4 - { - struct PointLightData - { - float3 PositionWS; - float InvSquareRadius; - [Color] - float3 Color; - }; - - struct PointLightDataInternal - { - float3 PositionWS; - float InvSquareRadius; - [Color] - float3 Color; - }; - - void ProcessLight(PointLightDataInternal light) - { - float3 lightVectorNorm; - float attenuation = ComputeAttenuation(light, streams.PositionWS.xyz, lightVectorNorm); - - streams.lightPositionWS = light.PositionWS; - streams.lightColor = light.Color; - streams.lightAttenuation = attenuation; - streams.lightDirectionWS = lightVectorNorm; - } - - float ComputeAttenuation(PointLightDataInternal light, float3 position, inout float3 lightVectorNorm) - { - float3 lightVector = light.PositionWS - position; - float lightVectorLength = length(lightVector); - lightVectorNorm = lightVector / lightVectorLength; - - float lightInvSquareRadius = light.InvSquareRadius; - return GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightPointGroup.sdsl b/sources/shaders/assets/Stride/SDSL/LightPointGroup.sdsl deleted file mode 100644 index 27c2e20a16..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightPointGroup.sdsl +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of point lights - /// - shader LightPointGroup : DirectLightGroupPerDraw, LightPoint - { - cbuffer PerDraw.Lighting - { - PointLightData Lights[TMaxLightCount]; - } - - override int GetMaxLightCount() - { - return TMaxLightCount; - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - override void PrepareDirectLightCore(int lightIndex) - { - // TODO: Workaraound for SPIR-V compiler. Revert later - PointLightDataInternal data; - data.PositionWS = Lights[lightIndex].PositionWS; - data.InvSquareRadius = Lights[lightIndex].InvSquareRadius; - data.Color = Lights[lightIndex].Color; - - ProcessLight(data); - } - - override float ComputeAttenuation(float3 position, int lightIndex) - { - // TODO: Workaraound for SPIR-V compiler. Revert later - PointLightDataInternal data; - data.PositionWS = Lights[lightIndex].PositionWS; - data.InvSquareRadius = Lights[lightIndex].InvSquareRadius; - - float3 lightVectorNorm; - return ComputeAttenuation(data, position, lightVectorNorm); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightProbeShader.sdsl b/sources/shaders/assets/Stride/SDSL/LightProbeShader.sdsl deleted file mode 100644 index 487c3da1db..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightProbeShader.sdsl +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.LightProbes -{ - /// - /// Defines a skybox environment light - /// - shader LightProbeShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation, ShaderBaseStream, PositionStream4, SphericalHarmonicsUtils - { - cbuffer PerView.LightProbes - { - stage int IgnoredProbeStart; - } - rgroup PerView.LightProbes - { -#ifdef STRIDE_MULTISAMPLE_COUNT - #if STRIDE_MULTISAMPLE_COUNT > 1 - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #else - stage Texture2D LightProbeTetrahedronIds; // SV_Position => tetrahedron ID - #endif -#else - stage Texture2DMS LightProbeTetrahedronIds; // SV_Position => tetrahedron ID -#endif - stage Buffer LightProbeTetrahedronProbeIndices; // tetrahaedron ID => 4 probe IDs - stage Buffer LightProbeTetrahedronMatrices; // tetrahaedron ID => world to tetrahedron space matrix - stage Buffer LightProbeCoefficients; // probe ID => SH coefficients - } - - void FetchLightProbe(inout float3 sphericalColors[TOrder * TOrder], uint lightprobeIndex, float weight) - { - // Early exit - if (weight == 0.0f) - return; - - int lightprobeIndexStart = lightprobeIndex * TOrder * TOrder; - for (int i = 0; i < TOrder * TOrder; ++i) - { - // TODO: Need float4() because type inference don't work on generics Buffer.Load() properly - sphericalColors[i] += LightProbeCoefficients.Load(lightprobeIndexStart + i).rgb * weight; - } - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - var sampleDirection = streams.normalWS; - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - var shadingPosition = int3(streams.ShadingPosition.xy, 0); -#if STRIDE_MULTISAMPLE_COUNT == 1 - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition); -#else - // TODO: Use SV_SampleIndex - uint tetrahedronIndex = LightProbeTetrahedronIds.Load(shadingPosition, 0); -#endif - - uint4 probeIndices = LightProbeTetrahedronProbeIndices.Load(tetrahedronIndex); - float3x4 tetrahedronMatrix = float3x4(LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 0), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 1), - LightProbeTetrahedronMatrices.Load(tetrahedronIndex * 3 + 2)); - - float3 tetrahedronFactors3 = mul((float3x3)tetrahedronMatrix, streams.PositionWS.xyz - tetrahedronMatrix._14_24_34); - - // Protect ourselves against degenerate cases - // TODO: Investigate why those happen (almost coplanar tetrahedron?) - tetrahedronFactors3 = saturate(tetrahedronFactors3); - - float4 tetrahedronFactors4 = float4(tetrahedronFactors3, 1.0f - tetrahedronFactors3.x - tetrahedronFactors3.y - tetrahedronFactors3.z); - - // Zero all the barycentric coordinates that reference probes past IgnoredProbeStart (the one far away) - tetrahedronFactors4 = lerp(tetrahedronFactors4, 0.0f, probeIndices >= IgnoredProbeStart ? float4(1.0f, 1.0f, 1.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f)); - - // Renormalize barycentric coordinates - var totalSum = tetrahedronFactors4.x + tetrahedronFactors4.y + tetrahedronFactors4.z + tetrahedronFactors4.w; - if (totalSum > 0.0f) - tetrahedronFactors4 /= totalSum; - - float3 sphericalColors[TOrder * TOrder]; - for (int i = 0; i < TOrder * TOrder; ++i) - sphericalColors[i] = 0.0f; - - FetchLightProbe(sphericalColors, probeIndices.x, tetrahedronFactors4.x); - FetchLightProbe(sphericalColors, probeIndices.y, tetrahedronFactors4.y); - FetchLightProbe(sphericalColors, probeIndices.z, tetrahedronFactors4.z); - FetchLightProbe(sphericalColors, probeIndices.w, tetrahedronFactors4.w); - - streams.envLightDiffuseColor = EvaluateSphericalHarmonics(sphericalColors, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - // TEST: - //streams.envLightDiffuseColor = LightProbeCube.Sample(Texturing.LinearSampler, sampleDirection).rgb * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - //streams.envLightDiffuseColor = tetrahedronFactors3; - //streams.envLightDiffuseColor = float4(tetrahedronIndex.xxx * 0.2, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightShaftsShader.sdsl b/sources/shaders/assets/Stride/SDSL/LightShaftsShader.sdsl deleted file mode 100644 index 807010740c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightShaftsShader.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - shader LightShaftsShader : ImageEffectShader, PostEffectBoundingRay, LightStream, NormalStream - { - stage compose DirectLightGroup lightGroup; - - cbuffer PerFrame - { - stage float DensityFactor; - }; - - override float3 ComputeColorIn(float4 positionWS, float stepSize, int stepIndex) - { - // Most shadow groups use these for normal scaled bias - ResetLightStream(); - streams.NdotL = 1; - streams.normalWS = float3(0,1,0); - // Needed by thickness computation (TODO: need a way to disable ComputeTransmittance when computing light shafts) - streams.meshNormalWS = 0.0f; - streams.PositionWS = 0.0f; - - float atten = lightGroup.ComputeAttenuation(positionWS.xyz, 0); - float3 shadowColor = lightGroup.ComputeShadow(positionWS.xyz, 0); - - // Right now this doesn't support multi-colored shadows, since this shader only calculates the light shaft intensity, which is later multiplied by the light color - // So take the max here - float shadow = max(max(shadowColor.x, shadowColor.y), shadowColor.z); - - return DensityFactor * stepSize * shadow * atten; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSimpleAmbient.sdsl b/sources/shaders/assets/Stride/SDSL/LightSimpleAmbient.sdsl deleted file mode 100644 index 67308901cc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSimpleAmbient.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a simple environment light - /// - shader LightSimpleAmbient : EnvironmentLight, MaterialPixelShadingStream - { - cbuffer PerView.Lighting - { - [Color] - float3 AmbientLight; - } - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - float3 lightColor = AmbientLight * streams.matAmbientOcclusion; - streams.envLightDiffuseColor = lightColor; - streams.envLightSpecularColor = lightColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSkyboxShader.sdsl b/sources/shaders/assets/Stride/SDSL/LightSkyboxShader.sdsl deleted file mode 100644 index e7cc2d7317..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSkyboxShader.sdsl +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a skybox environment light - /// - shader LightSkyboxShader : EnvironmentLight, MaterialPixelShadingStream, NormalStream, Transformation - { - cbuffer PerView.Lighting - { - float4x4 SkyMatrix; - float Intensity; - } - - compose IComputeEnvironmentColor lightDiffuseColor; - - compose IComputeEnvironmentColor lightSpecularColor; - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - - var ambientAccessibility = streams.matAmbientOcclusion; - - // ----------------------------------------- - // Diffuse lighting - // ----------------------------------------- - // TODO: This could be optimized by having a flag to allow rotation only if necessary - // Rotate the skybox - var sampleDirection = mul(streams.normalWS, (float3x3)SkyMatrix); - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - streams.envLightDiffuseColor = lightDiffuseColor.Compute(sampleDirection).rgb * Intensity * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.x; - - // ----------------------------------------- - // Specular lighting - // ----------------------------------------- - // TODO: This could be optimized by having a flag to allow rotation only if necessary - // Rotate the skybox - // TODO: Sample into "Importance Sampling" direction instead of the "reflect" direction - sampleDirection = reflect( -streams.viewWS, streams.normalWS ); - sampleDirection = mul(sampleDirection, (float3x3)SkyMatrix); - sampleDirection = float3(sampleDirection.xy, -sampleDirection.z); - - streams.envLightSpecularColor = lightSpecularColor.Compute(sampleDirection).rgb * Intensity * ambientAccessibility * streams.matDiffuseSpecularAlphaBlend.y; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSpot.sdsl b/sources/shaders/assets/Stride/SDSL/LightSpot.sdsl deleted file mode 100644 index cda55290f4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSpot.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a spot light - /// - shader LightSpot : - LightStream, // Required for "streams.lightColor" and "streams.lightDirectionWS". - PositionStream4, // Required for "streams.PositionWS". - SpotLightDataInternalShader, // Required for "SpotLightDataInternal" - LightSpotAttenuationDefault // Required for "ComputeAttenuation()" - { - struct SpotLightData - { - float3 PositionWS; - float3 DirectionWS; - float3 AngleOffsetAndInvSquareRadius; - [Color] - float3 Color; - }; - - void ProcessLight(SpotLightDataInternal light) - { - float3 lightVectorNorm; - //float attenuation = ComputeAttenuation(light, streams.PositionWS.xyz, lightVectorNorm); - float attenuation = ComputeAttenuation(light.PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. - light.AngleOffsetAndInvSquareRadius, - light.DirectionWS, - streams.PositionWS.xyz, lightVectorNorm); - - streams.lightColor = light.Color; - streams.lightAttenuation = attenuation; - streams.lightDirectionWS = lightVectorNorm; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl b/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl deleted file mode 100644 index 1c2967c6ae..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationDefault.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Code for attenuating a group of spotlights using angular attenuation. - /// - shader LightSpotAttenuationDefault : - //SpotLightDataInternalShader, // Required for "SpotLightDataInternal" // TODO: Revert this line as soon as the shader compiler is fixed. - LightUtil // Required for "GetDistanceAttenuation()" and "GetAngularAttenuation()". - { - //override float ComputeAttenuation(SpotLightDataInternal light, float3 position, inout float3 lightVectorNorm) - float ComputeAttenuation(float3 PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. - float3 AngleOffsetAndInvSquareRadius, - float3 DirectionWS, - float3 position, - inout float3 lightVectorNorm) // This overload is a temporary fix for a compiler error rendering us unable to override "ComputeAttenution()". - { - // TODO: There's duplicate code here. See "LightSpotAttenuationRectangular". - - //float3 lightVector = light.PositionWS - position; - float3 lightVector = PositionWS - position; // TODO: Revert to the above line as soon as the shader compiler is fixed. - float lightVectorLength = length(lightVector); - lightVectorNorm = lightVector / lightVectorLength; - - //float3 lightAngleOffsetAndInvSquareRadius = light.AngleOffsetAndInvSquareRadius; - float3 lightAngleOffsetAndInvSquareRadius = AngleOffsetAndInvSquareRadius; // TODO: Revert to the above line as soon as the shader compiler is fixed. - float2 lightAngleAndOffset = lightAngleOffsetAndInvSquareRadius.xy; - float lightInvSquareRadius = lightAngleOffsetAndInvSquareRadius.z; - - // TODO: Add support for disk based Directional light - //float3 lightDirection = -light.DirectionWS; - float3 lightDirection = -DirectionWS; // TODO: Revert to the above line as soon as the shader compiler is fixed. - - float attenuation = GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); - attenuation *= GetAngularAttenuation(lightVectorNorm, lightDirection, lightAngleAndOffset.x, lightAngleAndOffset.y); - return attenuation; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl b/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl deleted file mode 100644 index 35a1c0ca5d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSpotAttenuationRectangular.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a function for attenuating a spot light. - /// Overrides the default implementation and replaces it - /// with a rectangular attenuation (hard cut off at spotlight - /// frustum edges) for use with textured spotlights. - /// - shader LightSpotAttenuationRectangular : - LightSpotAttenuationDefault // Defines the function "ComputeAttenuation()" that we are overriding here. - { - //override float ComputeAttenuation(SpotLightDataInternal light, float3 position, inout float3 lightVectorNorm) - override float ComputeAttenuation(float3 PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. - float3 AngleOffsetAndInvSquareRadius, - float3 DirectionWS, - float3 position, - inout float3 lightVectorNorm) // This overload is a temporary fix for a compiler error rendering us unable to override "ComputeAttenution()". - { - // TODO: There's duplicate code here. See "LightSpotAttenuationDefault". - - //float3 lightVector = light.PositionWS - position; - float3 lightVector = PositionWS - position; // TODO: Revert to the above line as soon as the shader compiler is fixed. - float lightVectorLength = length(lightVector); - lightVectorNorm = lightVector / lightVectorLength; - - //float3 lightAngleOffsetAndInvSquareRadius = light.AngleOffsetAndInvSquareRadius; - float3 lightAngleOffsetAndInvSquareRadius = AngleOffsetAndInvSquareRadius; // TODO: Revert to the above line as soon as the shader compiler is fixed. - float2 lightAngleAndOffset = lightAngleOffsetAndInvSquareRadius.xy; - float lightInvSquareRadius = lightAngleOffsetAndInvSquareRadius.z; - - // TODO: Add support for disk based Directional light - //float3 lightDirection = -light.DirectionWS; - float3 lightDirection = -DirectionWS; // TODO: Revert to the above line as soon as the shader compiler is fixed. - - return GetDistanceAttenuation(lightVectorLength, lightInvSquareRadius); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightSpotGroup.sdsl b/sources/shaders/assets/Stride/SDSL/LightSpotGroup.sdsl deleted file mode 100644 index fabe1d16ee..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightSpotGroup.sdsl +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a group of spot lights - /// - shader LightSpotGroup : - DirectLightGroupPerDraw, // Required for "PrepareDirectLightCore()", "PrepareDirectLight()", "ComputeAttenuation()" and other stuff. - LightSpot, // Required for "SpotLightData". - LightSpotAttenuationDefault // Required for "ComputeAttenuation()" - { - cbuffer PerDraw.Lighting - { - SpotLightData Lights[TMaxLightCount]; - } - - override int GetMaxLightCount() - { - return TMaxLightCount; - } - - /// - /// Compute the light color/direction for the specified index within this group - /// - override void PrepareDirectLightCore(int lightIndex) - { - // TODO: Workaraound for SPIR-V compiler. Revert later - SpotLightDataInternal data; - data.PositionWS = Lights[lightIndex].PositionWS; - data.DirectionWS = Lights[lightIndex].DirectionWS; - data.AngleOffsetAndInvSquareRadius = Lights[lightIndex].AngleOffsetAndInvSquareRadius; - data.Color = Lights[lightIndex].Color; - - ProcessLight(data); - } - - override float ComputeAttenuation(float3 position, int lightIndex) - { - // TODO: Workaraound for SPIR-V compiler. Revert later - SpotLightDataInternal data; - data.PositionWS = Lights[lightIndex].PositionWS; - data.DirectionWS = Lights[lightIndex].DirectionWS; - data.AngleOffsetAndInvSquareRadius = Lights[lightIndex].AngleOffsetAndInvSquareRadius; - - float3 lightVectorNorm; - //return ComputeAttenuation(data, position, lightVectorNorm); - return ComputeAttenuation(data.PositionWS, // TODO: Revert to the above line as soon as the shader compiler is fixed. - data.AngleOffsetAndInvSquareRadius, - data.DirectionWS, - position, lightVectorNorm); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightStreakShader.sdsl b/sources/shaders/assets/Stride/SDSL/LightStreakShader.sdsl deleted file mode 100644 index aa975db334..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightStreakShader.sdsl +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// LightStreak shader. This extends colors along a direction, while applying an attenuation - /// factor along the way. - /// - internal shader LightStreakShader : ImageEffectShader - { - // Offset of the taps and their own weights - stage float2 TapOffsetsWeights[TapCount]; - - // Direction of the tap line - stage float2 Direction; - - // Light aberration coefficients along the streak - stage float3 ColorAberrationCoefficients; - - // Count of anamorphic sub-streaks with offsets and strength (including the main streak) - stage float3 AnamorphicOffsetsWeight[AnamorphicCount]; - - stage override float4 Shading() - { - // Direction in texel size - float2 direction = Direction * Texture0TexelSize; - float3 color = float3(0.0, 0.0, 0.0); - - [unroll] - for (int anamorphic = 0; anamorphic < AnamorphicCount; anamorphic++) { // All the anamorphic - - float2 textOffset = AnamorphicOffsetsWeight[anamorphic].xy * Texture0TexelSize; - - [unroll] - for(int i = 0; i < TapCount; i++) - { - float2 tapUV = streams.TexCoord + direction * TapOffsetsWeights[i].x + textOffset; - - float3 tapColor = Texture0.Sample(LinearSampler, tapUV).rgb; - - // TODO switch to vignetting-like lerp for nicer effect, - // or directly clamp to border instead - if (tapUV.x < 0 || tapUV.x > 1 || tapUV.y < 0 || tapUV.y > 1) { - tapColor = float3(0.0, 0.0, 0.0); - } - - // Some trick to apply chromatic aberration - if (i == 0) tapColor.r *= ColorAberrationCoefficients.r; - else if (i == 1) tapColor.g *= ColorAberrationCoefficients.g; - else if (i == 2) tapColor.b *= ColorAberrationCoefficients.b; - - tapColor *= AnamorphicOffsetsWeight[anamorphic].z; - - color += tapColor * TapOffsetsWeights[i].y; - } - } - - return float4(color, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightStream.sdsl b/sources/shaders/assets/Stride/SDSL/LightStream.sdsl deleted file mode 100644 index a083bf9d2b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightStream.sdsl +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines light streams variable. - /// - shader LightStream - { - stage stream float3 lightPositionWS; - stage stream float3 lightDirectionWS; - stage stream float3 lightColor; - stage stream float3 lightColorNdotL; - stage stream float3 lightSpecularColorNdotL; - stage stream float lightAttenuation; - stage stream float3 envLightDiffuseColor; - stage stream float3 envLightSpecularColor; - - // normal dot light - stage stream float NdotL; - - stage stream float lightDirectAmbientOcclusion; - - void ResetLightStream() - { - streams.lightPositionWS = 0; - streams.lightDirectionWS = 0; - streams.lightColor = 0; - streams.lightColorNdotL = 0; - streams.lightSpecularColorNdotL = 0; - streams.lightAttenuation = 1.0f; - streams.envLightDiffuseColor = 0; - streams.envLightSpecularColor = 0; - streams.lightDirectAmbientOcclusion = 1.0f; - streams.NdotL = 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightTiling.sdsl b/sources/shaders/assets/Stride/SDSL/LightTiling.sdsl deleted file mode 100644 index aea96478c5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightTiling.sdsl +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Lights -{ - shader LightTiling : ComputeShaderBase - { - struct PointLight - { - float3 Position; - float Radius; - }; - - - - // All point lights - int PointLightCount; - Buffer PointLights; - - // Light indices in this tile - RWBuffer FilteredLightIndicesBuffer; - - groupshared float4 FrustumPlanes[4]; - - groupshared uint FilteredLightIndicesCount; - groupshared uint FilteredLightIndices[1024]; - - override void Compute() - { - // Initialize variables and build frustum - if (ThreadGroupIndex == 0) - { - FilteredLightIndicesCount = 0; - //FrustumPlanes[0] = - } - - GroupMemoryBarrierWithGroupSync(); - - // Loop over lights - for (uint i = ThreadGroupIndex; i < PointLightCount; i += ThreadCountPerGroup) - { - PointLight pointLight = PointLights[i]; - - // Check our point against frustum planes - //if (dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) - // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) - // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f) - // && dot(pointLight.Position, FrustumPlanes[j]) + pointLight.Radius > 0.0f)) - { - uint lightIndex; - InterlockedAdd(FilteredLightIndicesCount, 1, lightIndex); - FilteredLightIndices[lightIndex] = i; - } - } - - GroupMemoryBarrierWithGroupSync(); - - // Copy results to buffer - for (uint i = ThreadGroupIndex; i < FilteredLightIndicesCount; i += ThreadCountPerGroup) - { - FilteredLightIndicesBuffer[i] = FilteredLightIndices[i]; - } - - // Put sentinel value to mark last point light - if (ThreadGroupIndex == 0) - { - FilteredLightIndicesBuffer[FilteredLightIndicesCount] = -1; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightUtil.sdsl b/sources/shaders/assets/Stride/SDSL/LightUtil.sdsl deleted file mode 100644 index 6f94a098a5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightUtil.sdsl +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Lights -{ - /// - /// Defines common function for direct lights - /// - shader LightUtil - { - // Code from "Moving Frostbite to Physically Based Rendering" Rousiers, Charles De Lagarde, Sébastien p32 - float SmoothDistanceAttenuation(float squaredDistance, float lightInvSquareRadius) - { - float factor = squaredDistance * lightInvSquareRadius; - float smoothFactor = saturate(1.0f - factor * factor); - return smoothFactor * smoothFactor; - } - - float GetDistanceAttenuation(float lightVectorLength, float lightInvSquareRadius) - { - float d2 = lightVectorLength * lightVectorLength; - float attenuation = 1.0 / (max(d2 , 0.01 * 0.01)); - attenuation *= SmoothDistanceAttenuation(d2, lightInvSquareRadius); - return attenuation; - } - - float GetAngularAttenuation(float3 lightVector, float3 lightDirection, float lightAngleScale, float lightAngleOffset) - { - // On the CPU - // float lightAngleScale = 1.0f / max (0.001f, (cosInner - cosOuter)); - // float lightAngleOffset = -cosOuter * angleScale; - float cd = dot(lightDirection, lightVector); - float attenuation = saturate(cd * lightAngleScale + lightAngleOffset); - // smooth the transition - attenuation *= attenuation; - return attenuation; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightVoxelEffect.sdsl b/sources/shaders/assets/Stride/SDSL/LightVoxelEffect.sdsl deleted file mode 100644 index 8009fe7e49..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightVoxelEffect.sdsl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; -using Stride.Rendering.Lights; - -namespace Stride.Rendering.Voxels.VoxelGI -{ - /// - /// Base effect - /// - effect LightVoxelEffect - { - using params LightVoxelShaderKeys; - using params MarchAttributesKeys; - - mixin LightVoxelShader; - - if (LightVoxelShaderKeys.diffuseMarcher != null) - { - mixin compose diffuseMarcher = LightVoxelShaderKeys.diffuseMarcher; - } - if (LightVoxelShaderKeys.specularMarcher != null) - { - mixin compose specularMarcher = LightVoxelShaderKeys.specularMarcher; - } - if (MarchAttributesKeys.AttributeSamplers!=null) - { - foreach (var attr in MarchAttributesKeys.AttributeSamplers) - { - mixin compose AttributeSamplers += (attr); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LightVoxelShader.sdsl b/sources/shaders/assets/Stride/SDSL/LightVoxelShader.sdsl deleted file mode 100644 index 0d679a9ece..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LightVoxelShader.sdsl +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Lights; -namespace Stride.Rendering.Voxels.VoxelGI -{ - /// - /// Defines a Voxel environment light - /// - shader LightVoxelShader : MarchAttributes, Camera, Texturing, EnvironmentLight, MaterialPixelShadingStream, NormalStream, PositionStream4, Transformation - { - cbuffer PerView.Lighting - { - float Intensity; - float SpecularIntensity; - } - - compose VoxelMarchSet diffuseMarcher; - compose VoxelRadiusMarchMethod specularMarcher; - - override void PrepareEnvironmentLight() - { - base.PrepareEnvironmentLight(); - if (Intensity > 0.0) - { - float3 worldPos = streams.PositionWS; - - float3 tan = normalize(cross(streams.normalWS.xyz, normalize(float3(1, 1, 1)))); - float3 bitan = cross(tan, streams.normalWS.xyz); - float3x3 tangentMatrix = float3x3(tan, bitan, streams.normalWS.xyz); - - float4 reflLighting = float4(0, 0, 0, 0); - - float3 startPos = worldPos + streams.normalWS.xyz * specularMarcher.StepSizeRadius(1.0); - - reflLighting = diffuseMarcher.March(worldPos, streams.normalWS.xyz); - - streams.envLightDiffuseColor = reflLighting.rgb * Intensity; - if (SpecularIntensity > 0.0) - streams.envLightSpecularColor = specularMarcher.MarchRadius(startPos, reflect(-streams.viewWS, streams.normalWS), sqrt(streams.alphaRoughness)).rgb * SpecularIntensity; - else - streams.envLightSpecularColor = float4(0,0,0,0); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LocalSamples.sdsl b/sources/shaders/assets/Stride/SDSL/LocalSamples.sdsl deleted file mode 100644 index 8805eafa54..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LocalSamples.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader LocalSamples -{ - stage stream float4 LocalSample[10]; -}; diff --git a/sources/shaders/assets/Stride/SDSL/LuminanceLogShader.sdsl b/sources/shaders/assets/Stride/SDSL/LuminanceLogShader.sdsl deleted file mode 100644 index d784fcf92c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LuminanceLogShader.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A log luminance shader (by default using luma/Perceptive luminance Y'601) - /// - shader LuminanceLogShader : ImageEffectShader - { - float GetLuminance(float3 color) - { - return LuminanceUtils.Luma(color); - } - - stage override float4 Shading() - { - float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - - // TODO: Make the Luma configurable from the LuminanceLogEffect - // Make sure that we don't go beyond max half float (65504), so we cap values here - var lum = max(0.001, GetLuminance(color)); - return float4(log2(lum), 1.0, 1.0, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LuminanceToChannelShader.sdsl b/sources/shaders/assets/Stride/SDSL/LuminanceToChannelShader.sdsl deleted file mode 100644 index 3d21f705e8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LuminanceToChannelShader.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A color transform for to output the luminance to the specified channel. - /// - internal shader LuminanceToChannelShader : ColorTransformShader - { - override float4 Compute(float4 color) - { - float4 outColor = color; - outColor.TChannel = LuminanceUtils.Luma(color.rgb); - return outColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/LuminanceUtils.sdsl b/sources/shaders/assets/Stride/SDSL/LuminanceUtils.sdsl deleted file mode 100644 index 93031ca3c2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/LuminanceUtils.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A utility shader for luminance. - /// - shader LuminanceUtils - { - /// - /// Calculate the perceptive luminance (601Y') - /// - /// - /// http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness - /// http://www.poynton.com/PDFs/YUV_and_luminance_harmful.pdf - /// - static float Luma(float3 color) - { - return max(dot(color, float3(0.299, 0.587, 0.114)), 0.0001); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MSAADepthResolverShader.sdsl b/sources/shaders/assets/Stride/SDSL/MSAADepthResolverShader.sdsl deleted file mode 100644 index 37a908d74c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MSAADepthResolverShader.sdsl +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Compositing -{ - /// - /// A MSAA depth textures resolver shader - /// - internal shader MSAADepthResolverShader : ShaderBase, Texturing, Math - { - stage stream float4 Position : POSITION; - - stage float4 SvPosUnpack; - stage float2 TextureSizeLess1; - -#ifndef INPUT_MSAA_SAMPLES - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 1 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 2 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 4 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 8 - stage Texture2DMS InputTexture; -#else - #error "Unsupported amount of MSAA texture samples." -#endif - - // 1:-1 to 0:TextureSize - int2 ClipPosToUvPos(float2 clipPos) - { - return (int2)(clipPos * SvPosUnpack.xy + SvPosUnpack.zw); - } - - stage override void VSMain() - { - streams.ShadingPosition = streams.Position; - } - - override stage void PSMain() - { - float4 output = 0; - int2 pixelPos = ClipPosToUvPos(streams.Position.xy); - - float resolvedDepth = InputTexture.Load(pixelPos, 0).r; - -#ifdef INPUT_MSAA_SAMPLES - - // Get the closest depth value - [unroll] - for (int sampleIndex = 1; sampleIndex < INPUT_MSAA_SAMPLES; sampleIndex++) - { - float sampleDepth = InputTexture.Load(pixelPos, sampleIndex).r; - resolvedDepth = min(resolvedDepth, sampleDepth); - } - -#endif - - streams.Depth = resolvedDepth; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MSAAResolverShader.sdsl b/sources/shaders/assets/Stride/SDSL/MSAAResolverShader.sdsl deleted file mode 100644 index 840bac1487..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MSAAResolverShader.sdsl +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Compositing -{ - /// - /// A MSAA textures resolver shader - /// - internal shader MSAAResolverShader : ImageEffectShader, Math - { - // Reference: https://github.com/TheRealMJP/MSAAFilter - - stage float4 SvPosUnpack; - stage float2 TextureSizeLess1; -#ifndef INPUT_MSAA_SAMPLES - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 1 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 2 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 4 - stage Texture2DMS InputTexture; -#elif INPUT_MSAA_SAMPLES == 8 - stage Texture2DMS InputTexture; -#else - #error "Unsupported amount of MSAA texture samples." -#endif - - // Supported filter types (note: this must match C# source) - static const int FilterTypes_Box = 1; - static const int FilterTypes_Triangle = 2; - static const int FilterTypes_Gaussian = 3; - static const int FilterTypes_BlackmanHarris = 4; - static const int FilterTypes_Smoothstep = 5; - static const int FilterTypes_BSpline = 6; - static const int FilterTypes_CatmullRom = 7; - static const int FilterTypes_Mitchell = 8; - static const int FilterTypes_Sinc = 9; - - // These are the sub-sample locations for the 2x, 4x, and 8x standard multisample patterns. - // See the MSDN documentation for the D3D11_STANDARD_MULTISAMPLE_QUALITY_LEVELS enumeration. - static const float2 SubSampleOffsets8[8] = { - float2( 0.0625f, -0.1875f), - float2(-0.0625f, 0.1875f), - float2( 0.3125f, 0.0625f), - float2(-0.1875f, -0.3125f), - float2(-0.3125f, 0.3125f), - float2(-0.4375f, -0.0625f), - float2( 0.1875f, 0.4375f), - float2( 0.4375f, -0.4375f), - }; - static const float2 SubSampleOffsets4[4] = { - float2(-0.125f, -0.375f), - float2( 0.375f, -0.125f), - float2(-0.375f, 0.125f), - float2( 0.125f, 0.375f), - }; - static const float2 SubSampleOffsets2[2] = { - float2( 0.25f, 0.25f), - float2(-0.25f, -0.25f), - }; - static const float2 SubSampleOffsets1[1] = { - float2(0.0f, 0.0f), - }; - - // All filtering functions assume that 'x' is normalized to [0, 1], where 1 == FilteRadius - - float FilterBox(in float x) - { - return x <= 1.0f; - } - - static float FilterTriangle(in float x) - { - return saturate(1.0f - x); - } - - static float FilterGaussian(in float x) - { - static const float sigma = 0.5f; - static const float g = 1.0f / sqrt(2.0f * 3.14159f * sigma * sigma); - return (g * exp(-(x * x) / (2 * sigma * sigma))); - } - - float FilterCubic(in float x, in float B, in float C) - { - float y = 0.0f; - float x2 = x * x; - float x3 = x * x * x; - if(x < 1) - y = (12 - 9 * B - 6 * C) * x3 + (-18 + 12 * B + 6 * C) * x2 + (6 - 2 * B); - else if (x <= 2) - y = (-B - 6 * C) * x3 + (6 * B + 30 * C) * x2 + (-12 * B - 48 * C) * x + (8 * B + 24 * C); - - return y / 6.0f; - } - - float FilterSinc(in float x) - { - float s; - - x *= ResolveFilterDiameter; - - if(x < 0.001f) - s = 1.0f; - else - s = sin(x * PI) / (x * PI); - - return s; - } - - float FilterBlackmanHarris(in float x) - { - x = 1.0f - x; - - static const float a0 = 0.35875f; - static const float a1 = 0.48829f; - static const float a2 = 0.14128f; - static const float a3 = 0.01168f; - return saturate(a0 - a1 * cos(PI * x) + a2 * cos(2 * PI * x) - a3 * cos(3 * PI * x)); - } - - float FilterSmoothstep(in float x) - { - return 1.0f - smoothstep(0.0f, 1.0f, x); - } - - float Filter(in float x) - { - // Cubic filters naturually work in a [-2, 2] domain. For the resolve case we - // want to rescale the filter so that it works in [-1, 1] instead - float cubicX = x * 2.0f; - - if(ResolveFilterType == FilterTypes_Box) - return FilterBox(x); - else if(ResolveFilterType == FilterTypes_Triangle) - return FilterTriangle(x); - else if(ResolveFilterType == FilterTypes_Gaussian) - return FilterGaussian(x); - else if(ResolveFilterType == FilterTypes_BlackmanHarris) - return FilterBlackmanHarris(x); - else if(ResolveFilterType == FilterTypes_Smoothstep) - return FilterSmoothstep(x); - else if(ResolveFilterType == FilterTypes_BSpline) - return FilterCubic(cubicX, 1.0, 0.0f); - else if(ResolveFilterType == FilterTypes_CatmullRom) - return FilterCubic(cubicX, 0, 0.5f); - else if(ResolveFilterType == FilterTypes_Mitchell) - return FilterCubic(cubicX, 1 / 3.0f, 1 / 3.0f); - else if(ResolveFilterType == FilterTypes_Sinc) - return FilterSinc(x); - else - return 1.0f; - } - - // 1:-1 to 0:TextureSize - int2 ClipPosToUvPos(float2 clipPos) - { - return (int2)(clipPos * SvPosUnpack.xy + SvPosUnpack.zw); - } - - override stage float4 Shading() - { - float4 output = 0; - int2 pixelPos = ClipPosToUvPos(streams.Position.xy); - - // Special case for single sample resolving - if(MSAASamples == 1) - { - output = InputTexture.Load(pixelPos, 0); - } - else - { - float4 sum = 0.0f; - float totalWeight = 0.0f; - - static const int SampleRadius = (int)((ResolveFilterDiameter / 2.0f) + 0.499f); - - for(int y = -SampleRadius; y <= SampleRadius; y++) - { - for(int x = -SampleRadius; x <= SampleRadius; x++) - { - float2 sampleOffset = float2(x, y); - float2 samplePos = pixelPos + sampleOffset; - samplePos = clamp(samplePos, 0, TextureSizeLess1); - - [unroll] - for(uint subSampleIdx = 0; subSampleIdx < MSAASamples; subSampleIdx++) - { - float2 subSampleOffset; - if(MSAASamples == 8) - subSampleOffset = SubSampleOffsets8[subSampleIdx].xy; - else if(MSAASamples == 4) - subSampleOffset = SubSampleOffsets4[subSampleIdx].xy; - else if(MSAASamples == 2) - subSampleOffset = SubSampleOffsets2[subSampleIdx].xy; - else - subSampleOffset = SubSampleOffsets1[subSampleIdx].xy; - float2 sampleDist = abs(sampleOffset + subSampleOffset) / (ResolveFilterDiameter / 2.0f); - - bool useSample = all(sampleDist <= 1.0f); - if(useSample) - { - float4 sampleValue = InputTexture.Load(samplePos, subSampleIdx); - float weight = Filter(sampleDist.x) * Filter(sampleDist.y); - float sampleLum = LuminanceUtils.Luma(sampleValue.rgb); - - // Use inverse luminance filtering (better quality on highlights) - weight *= 1.0f / (1.0f + sampleLum); - - sum += sampleValue * weight; - totalWeight += weight; - } - } - } - } - - output = sum / max(totalWeight, 0.00001f); - } - - return output; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MacroTest.sdsl b/sources/shaders/assets/Stride/SDSL/MacroTest.sdsl deleted file mode 100644 index c23fcc2b58..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MacroTest.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#ifndef MACRO_TEST -# define MACRO_TEST float -#endif -shader MacroTest -{ - MACRO_TEST u; -}; diff --git a/sources/shaders/assets/Stride/SDSL/MacroTestBase.sdsl b/sources/shaders/assets/Stride/SDSL/MacroTestBase.sdsl deleted file mode 100644 index b8a411cac5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MacroTestBase.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MacroTestBase -{ - float4 GetValue() - { - return float4(0,0,0,0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/MacroTestChild.sdsl b/sources/shaders/assets/Stride/SDSL/MacroTestChild.sdsl deleted file mode 100644 index 1bf53ae07d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MacroTestChild.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MacroTestChild : MacroTest -{ - -}; diff --git a/sources/shaders/assets/Stride/SDSL/MarchAttributes.sdsl b/sources/shaders/assets/Stride/SDSL/MarchAttributes.sdsl deleted file mode 100644 index d4d195721f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MarchAttributes.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MarchAttributes -{ - stage compose IVoxelSampler AttributeSamplers[]; -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MarchAttributesEffect.sdsl b/sources/shaders/assets/Stride/SDSL/MarchAttributesEffect.sdsl deleted file mode 100644 index 47a20343f0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MarchAttributesEffect.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - partial effect MarchAttributesEffect - { - using params MarchAttributesKeys; - - mixin MarchAttributes; - if (MarchAttributesKeys.AttributeSamplers!=null) - { - foreach (var attr in MarchAttributesKeys.AttributeSamplers) - { - mixin compose AttributeSamplers += (attr); - } - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl deleted file mode 100644 index 9c188ede8d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightDefault.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialCelShadingLightDefault : IMaterialCelShadingLightFunction - { - override float3 Compute(float lightIn) - { - if (IsBlackAndWhite) - { - if (lightIn > 0.2) - return float3(1, 1, 1); - } - else - { - if (lightIn > 0.8) - return float3(1, 1, 1); - - if (lightIn > 0.5) - return float3(0.8f, 0.8f, 0.8f); - - if (lightIn > 0.2) - return float3(0.3f, 0.3f, 0.3f); - } - - return 0; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl deleted file mode 100644 index e82999cacc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialCelShadingLightRamp.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialCelShadingLightRamp - : IMaterialCelShadingLightFunction, Texturing - { - rgroup PerMaterial - { - stage Texture2D CelShaderRamp; - } - - override float3 Compute(float lightIn) - { - float2 texCoord = float2(clamp(lightIn, 0, 1), 0.5); - return CelShaderRamp.SampleLevel(LinearSampler, texCoord, 0).rgb; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialDisplacementStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialDisplacementStream.sdsl deleted file mode 100644 index 675bdbdd5b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialDisplacementStream.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - shader MaterialDisplacementStream : IStreamInitializer - { - // Displacement height attribute - stage stream float matDisplacement; - - override void ResetStream() - { - base.ResetStream(); - - streams.matDisplacement = 0.0f; - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/MaterialDomainStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialDomainStream.sdsl deleted file mode 100644 index 34f5ea4bfc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialDomainStream.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Contains all the default streams of the domain shader stage. - /// - shader MaterialDomainStream : MaterialStream, MaterialDisplacementStream, MaterialTessellationStream, NormalStream, PositionStream, Texturing - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl deleted file mode 100644 index 1f94179874..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialFrontBackBlendShader.sdsl +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader MaterialFrontBackBlendShader : ShadingBase, Transformation, PositionStream, NormalStream -{ - cbuffer PerDraw - { - [Color] - stage float3 ColorFront; - - stage float ColorBlend; - - [Color] - stage float3 ColorBack; - - stage float AlphaBlend; - } - - // method computing color - stage override float4 Shading() - { - float3 color = ColorFront; - if (TUseNormalBackface) - { - float3 viewWS = normalize(Eye.xyz - streams.PositionWS.xyz); - // Allow smooth transition from front face to backface - float ndotV = saturate((dot(streams.normalWS, viewWS) + 0.25) / 0.25); - color = lerp(ColorBack, ColorFront, ndotV); - } - - return float4(color * ColorBlend, AlphaBlend); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl deleted file mode 100644 index 237f05e400..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionBitangent.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairDirectionFunctionBitangent : IMaterialHairDirectionFunction - { - float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose) - { - normalOS = normalize(normalOS); // TODO: PERFORMANCE: Normalization required? - - tangentOS.xyz = normalize(tangentOS.xyz); // TODO: PERFORMANCE: Normalization required? - const float3 bitangentOS = normalize(tangentOS.w * cross(normalOS, tangentOS.xyz)); // TODO: PERFORMANCE: Normalization required? - const float3 bitangentWS = normalize(mul(bitangentOS, worldInverseTranspose)); // TODO: PERFORMANCE: Normalization required? - return bitangentWS; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl deleted file mode 100644 index 431b4f4f38..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairDirectionFunctionTangent.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairDirectionFunctionTangent : IMaterialHairDirectionFunction - { - float3 Compute(float3 normalOS, float4 tangentOS, float3x3 worldInverseTranspose) - { - tangentOS.xyz = normalize(tangentOS.xyz); // TODO: PERFORMANCE: Normalization required? - const float3 tangentWS = normalize(mul(tangentOS, worldInverseTranspose)); // TODO: PERFORMANCE: Is this normalization required? - return tangentWS; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl deleted file mode 100644 index ab888cd944..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionOpaquePass.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Renders only the opaque parts for the opaque hair pass. - /// - class MaterialHairDiscardFunctionOpaquePass : IMaterialHairDiscardFunction, MaterialPixelStream - { - cbuffer PerMaterial - { - [Link("THairAlphaThreshold")] - stage float HairAlphaThreshold; // Any alpha value above this value is considered opaque. - } - - void Discard(void) - { - if(streams.matDiffuse.a < HairAlphaThreshold) - { - discard; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl deleted file mode 100644 index 16f618120d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairDiscardFunctionTransparentPass.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Renders only the transparent parts for the transparent hair pass. - /// - class MaterialHairDiscardFunctionTransparentPass : IMaterialHairDiscardFunction, MaterialPixelStream - { - cbuffer PerMaterial - { - [Link("THairAlphaThreshold")] - stage float HairAlphaThreshold; // Any alpha value above this value is considered opaque. - } - - void Discard(void) - { - if(streams.matDiffuse.a >= HairAlphaThreshold) - { - discard; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl deleted file mode 100644 index 16b12dde9f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionDirectional.sdsl +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairLightAttenuationFunctionDirectional : IMaterialHairLightAttenuationFunction, - NormalStream, LightStream // These are required for accessing the normals and light direction. - { - cbuffer PerMaterial - { - [Link("THardnessReciprocal")] - stage float HardnessReciprocal; // == 1.0 / hardness - [Link("TBoundaryShift")] - stage float BoundaryShift; // Range: [0.0 ... 0.5] - } - - float CalculateNdotL(void) - { - const float3 meshNormalWorldSpaceShifted = normalize(lerp(streams.meshNormalWS, -streams.lightDirectionWS, BoundaryShift)); - const float3 normalMapNormalShifted = normalize(lerp(streams.normalWS, -streams.lightDirectionWS, BoundaryShift)); // If no normal map is present, this will be equal to the mesh normal. - - if(NormalMode == 0) // Mesh normals: - { - return dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS); - } - else if(NormalMode == 1) // Normal map normals: - { - return dot(normalMapNormalShifted, streams.lightDirectionWS); - } - else // Mesh & normal map normals: - { - // Alternate approach: - //return max(dot(normalMapNormalShifted, streams.lightDirectionWS), - // dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS)); - - // More conservative approach: - return min(dot(normalMapNormalShifted, streams.lightDirectionWS), - dot(meshNormalWorldSpaceShifted, streams.lightDirectionWS)); - } - } - - float Compute(void) - { - float saturatedNdotL = saturate(CalculateNdotL()); - return pow(saturatedNdotL, HardnessReciprocal); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl deleted file mode 100644 index 6efe8ed9c9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairLightAttenuationFunctionNone.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairLightAttenuationFunctionNone : IMaterialHairLightAttenuationFunction - { - float Compute(void) - { - return(1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl deleted file mode 100644 index 917d4f97b1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionScattering.sdsl +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairShadowingFunctionScattering : IMaterialHairShadowingFunction, ShadowStream - { - cbuffer PerMaterial - { - [Link("TExtinctionStrength")] - stage float ExtinctionStrength; - } - - float3 Compute() - { - /* - // As an example, here is the SSSS code: - const float translucency = 0.5; - const float sssWidth = 0.1; - - // Calculate the scale of the effect: - const float scale = 8.25 * (1.0 - translucency) / sssWidth; - - // Armed with the thickness, we can now calculate the color by means of the - // precalculated transmittance profile. - // (It can be precomputed into a texture, for maximum performance): - const float d = scale * thickness; - - const float dd = -d * d; - float3 profile = float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + - float3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + - float3(0.118, 0.198, 0.0) * exp(dd / 0.187) + - float3(0.113, 0.007, 0.007) * exp(dd / 0.567) + - float3(0.358, 0.004, 0.0) * exp(dd / 1.99) + - float3(0.078, 0.0, 0.0) * exp(dd / 7.41); // TODO: How can we generate this profile for arbitrary materials? - - // Using the profile, we finally approximate the transmitted lighting from - // the back of the object: - //return profile * saturate(0.3 + dot(lightDirectionWS, -meshNormalWS)) * attenuatedLightColor; - finalLighting *= profile; - */ - - return exp(-streams.thicknessWS * ExtinctionStrength); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl deleted file mode 100644 index 41c29b1495..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairShadowingFunctionShadowing.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialHairShadowingFunctionShadowing : IMaterialHairShadowingFunction, ShadowStream - { - float3 Compute() - { - return streams.shadowColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialHairShared.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialHairShared.sdsl deleted file mode 100644 index 3003df01b5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialHairShared.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialHairShared - { - static const int HAIR_SHADING_SCHEUERMANN_APPROXIMATION = 0; // These values must correspond to the ones defined in "MaterialHairShared.cs". - static const int HAIR_SHADING_SCHEUERMANN_IMPROVED = 1; - static const int HAIR_SHADING_KAJIYAKAY_SHIFTED = 2; - - static const int Opaque = 0; - static const int TransparentBack = 1; - static const int TransparentFront = 2; - - cbuffer PerMaterial // Changed to "PerMaterial" because otherwise PassID contains garbage, as we don't require nor execute the HairRenderFeature anymore. - { - stage int PassID; // 0 == Opaque, 1 == Transparent back, 2 = Transparent front - } - - float3 GetDebugColor(int passID) - { - if(passID == Opaque) - { - return float3(1.0, 0.0, 0.0); - } - else if(passID == TransparentBack) - { - return float3(0.0, 1.0, 0.0); - } - else - { - return float3(0.0, 0.0, 1.0); - } - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl deleted file mode 100644 index ccb9355595..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialPixelShadingStream.sdsl +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialPixelShadingStream : MaterialPixelStream, LightStream - { - // Output of shading a material surface - stage stream float3 shadingColor; - - // Output of the shading color alpha - stage stream float shadingColorAlpha; - - // Half vector (sum of normalWS + lightDirectionWS) - stage stream float3 H; - - // normal dot half vector - stage stream float NdotH; - - // light dot half vector - stage stream float LdotH; - - // view dot half vector - stage stream float VdotH; - - override void ResetStream() - { - base.ResetStream(); - streams.shadingColorAlpha = 1.0f; - } - - // Computes material attributes per light - stage void PrepareMaterialPerDirectLight() - { - // TODO: This is not plug-n-play - // Used by microfacet - streams.H = normalize(streams.viewWS + streams.lightDirectionWS); - streams.NdotH = saturate(dot(streams.normalWS, streams.H)); - streams.LdotH = saturate(dot(streams.lightDirectionWS, streams.H)); - streams.VdotH = streams.LdotH; - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/MaterialPixelStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialPixelStream.sdsl deleted file mode 100644 index f761f2d6b7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialPixelStream.sdsl +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialPixelStream : MaterialStream, NormalStream, LightStream - { - // -------------------------------------------------- - // Values defined by materials - // -------------------------------------------------- - - // Surface attributes - stage stream float3 matNormal; - - // The color base attributes - stage stream float4 matColorBase; - - // Diffuse attributes - stage stream float4 matDiffuse; - - // Microsurface attributes - stage stream float matGlossiness; - - // Specular attributes - stage stream float3 matSpecular; - - stage stream float matSpecularIntensity; - // Occlusion attributes - stage stream float matAmbientOcclusion; - stage stream float matAmbientOcclusionDirectLightingFactor; - stage stream float matCavity; - stage stream float matCavityDiffuse; - stage stream float matCavitySpecular; - - // Emissive attributes - stage stream float4 matEmissive; - stage stream float matEmissiveIntensity; - - // Scattering attributes - stage stream float matScatteringStrength; - - // Transparent attributes - stage stream float2 matDiffuseSpecularAlphaBlend; - stage stream float3 matAlphaBlendColor; - stage stream float matAlphaDiscard; - - // Inputs while shading a material surface - stage stream float3 viewWS; - - // -------------------------------------------------- - // Values Precomputed before lighting - // -------------------------------------------------- - - stage stream float3 matDiffuseVisible; - - stage stream float alphaRoughness; // disney-burley roughness - - stage stream float3 matSpecularVisible; - - stage stream float NdotV; // normal dot view - - override void ResetStream() - { - base.ResetStream(); - - // Reset all values for material stream to avoid pulling from a different stage (VS...etc.) - // TODO: It might be interesting to support pulling from VS, but this should be done from the IMaterialSurface and dedicated ComputerColors - streams.matNormal = float3(0, 0, 1); - - streams.matColorBase = 0.0f; - streams.matDiffuse = 0.0f; - streams.matDiffuseVisible = 0.0f; - - streams.matSpecular = 0.0f; - streams.matSpecularVisible = 0.0f; - streams.matSpecularIntensity = 1.0f; - - streams.matGlossiness = 0.0f; - streams.alphaRoughness = 1.0f; - - streams.matAmbientOcclusion = 1.0f; // 0.0: occluded, 1.0: not occluded - streams.matAmbientOcclusionDirectLightingFactor = 0.0f; - - streams.matCavity = 1.0f; - streams.matCavityDiffuse = 0.0f; - streams.matCavitySpecular = 0.0f; - - streams.matEmissive = 0.0f; - streams.matEmissiveIntensity = 0.0f; - - streams.matScatteringStrength = 1.0f; - - streams.matDiffuseSpecularAlphaBlend = 1.0f; - streams.matAlphaBlendColor = 1.0f; - streams.matAlphaDiscard = 0.1f; - } - - void PrepareMaterialForLightingAndShading() - { - // Direct lighting can be slightly influenced by AO map - streams.lightDirectAmbientOcclusion = lerp(1.0, streams.matAmbientOcclusion, streams.matAmbientOcclusionDirectLightingFactor); - - // Diffuse visible - streams.matDiffuseVisible = streams.matDiffuse.rgb * lerp(1.0f, streams.matCavity, streams.matCavityDiffuse) * streams.matDiffuseSpecularAlphaBlend.r * streams.matAlphaBlendColor; - streams.matSpecularVisible = streams.matSpecular.rgb * streams.matSpecularIntensity * lerp(1.0f, streams.matCavity, streams.matCavitySpecular) * streams.matDiffuseSpecularAlphaBlend.g * streams.matAlphaBlendColor; - - streams.NdotV = max(dot(streams.normalWS, streams.viewWS), 0.0001f); - - var roughness = 1.0f - streams.matGlossiness; - - // Make sure alphaRoughness is not going below a certain value as it can generate Infinity with some specular model - streams.alphaRoughness = max(roughness * roughness, 0.001); - // TODO: precalculate alphaRoughness^2 - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl deleted file mode 100644 index 85b3ca5762..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXLUT.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader MaterialSpecularMicrofacetEnvironmentGGXLUT : IMaterialSpecularMicrofacetEnvironmentFunction, Texturing - { - rgroup PerMaterial - { - stage Texture2D EnvironmentLightingDFG_LUT; - } - - override float3 Compute(float3 specularColor, float alphaR, float nDotV) - { - float glossiness = 1.0f - sqrt(alphaR); -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 || STRIDE_GRAPHICS_API_OPENGL - // SampleLevel doesn't work on D3D feature level 9 - float4 environmentLightingDFG = EnvironmentLightingDFG_LUT.SampleLevel(LinearSampler, float2(glossiness, nDotV), 0); -#else - float4 environmentLightingDFG = EnvironmentLightingDFG_LUT.Sample(LinearSampler, float2(glossiness, nDotV)); -#endif - return specularColor * environmentLightingDFG.r + environmentLightingDFG.g; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl deleted file mode 100644 index 7a954d2b2a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentGGXPolynomial.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader MaterialSpecularMicrofacetEnvironmentGGXPolynomial : IMaterialSpecularMicrofacetEnvironmentFunction - { - override float3 Compute(float3 specularColor, float alphaR, float nDotV) - { - return EnvironmentLightingDFG_GGX_Schlick_SmithSchlickGGX(specularColor, alphaR, nDotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl deleted file mode 100644 index 0d7f0a3bd3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetEnvironmentThinGlass.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader MaterialSpecularMicrofacetEnvironmentThinGlass : IMaterialSpecularMicrofacetEnvironmentFunction, MaterialTransmittanceReflectanceStream - { - override float3 Compute(float3 specularColor, float alphaR, float nDotV) - { - return streams.matReflectance; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl deleted file mode 100644 index 9906e71c3e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelNone.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader MaterialSpecularMicrofacetFresnelNone : IMaterialSpecularMicrofacetFresnelFunction - { - override float3 Compute(float3 f0) - { - return FresnelNone(f0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl deleted file mode 100644 index f092d6d09e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelSchlick.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Fresnel function - /// - shader MaterialSpecularMicrofacetFresnelSchlick : IMaterialSpecularMicrofacetFresnelFunction - { - override float3 Compute(float3 f0) - { - return FresnelSchlick(f0, streams.LdotH); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl deleted file mode 100644 index b78e190fff..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetFresnelThinGlass.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Microfacet fresnel function for Glass materials. - /// - shader MaterialSpecularMicrofacetFresnelThinGlass : IMaterialSpecularMicrofacetFresnelFunction, MaterialTransmittanceReflectanceStream - { - override float3 Compute(float3 f0) - { - return streams.matReflectance; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl deleted file mode 100644 index 61b08d2ba3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBeckmann.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Normal Distribution function - /// - shader MaterialSpecularMicrofacetNormalDistributionBeckmann : IMaterialSpecularMicrofacetNormalDistributionFunction - { - override float Compute() - { - return NormalDistributionBeckmann(streams.alphaRoughness, streams.NdotH); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl deleted file mode 100644 index 4245669e9a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionBlinnPhong.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Normal Distribution function - /// - shader MaterialSpecularMicrofacetNormalDistributionBlinnPhong : IMaterialSpecularMicrofacetNormalDistributionFunction - { - override float Compute() - { - return NormalDistributionBlinnPhong(streams.alphaRoughness, streams.NdotH); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl deleted file mode 100644 index ae5a255067..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetNormalDistributionGGX.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Normal Distribution function - /// - shader MaterialSpecularMicrofacetNormalDistributionGGX : IMaterialSpecularMicrofacetNormalDistributionFunction - { - override float Compute() - { - return NormalDistributionGGX(streams.alphaRoughness, streams.NdotH); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl deleted file mode 100644 index f32050ec03..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityCookTorrance.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilityCookTorrance : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilityCookTorrance(streams.NdotH, streams.VdotH, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl deleted file mode 100644 index 29dc1ef414..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityImplicit.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilityImplicit : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilityImplicit(streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl deleted file mode 100644 index 43842d4f8b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityKelemen.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilityKelemen : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilityKelemen(streams.VdotH, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl deleted file mode 100644 index 4c2529f5a2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilityNeumann.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilityNeumann : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilityNeumann(streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl deleted file mode 100644 index 63db794b8b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithBeckmann.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilitySmithBeckmann : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilitySmithBeckmann(streams.alphaRoughness, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl deleted file mode 100644 index d1898afde3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilitySmithGGXCorrelated : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilitySmithGGXCorrelated(streams.alphaRoughness, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl deleted file mode 100644 index 66214bec56..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilitySmithSchlickBeckmann : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilitySmithSchlickBeckmann(streams.alphaRoughness, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl deleted file mode 100644 index f9cbc9a343..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSpecularMicrofacetVisibilitySmithSchlickGGX.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Interface for a microfacet Geometric Shadowing function - /// - shader MaterialSpecularMicrofacetVisibilitySmithSchlickGGX : IMaterialSpecularMicrofacetVisibilityFunction - { - override float Compute() - { - return VisibilitySmithSchlickGGX(streams.alphaRoughness, streams.NdotL, streams.NdotV); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialStream.sdsl deleted file mode 100644 index e68546945f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialStream.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialStream : IStreamInitializer - { - /// - /// The blending applied between the current and previous material attributes - /// - stage stream float matBlend; - - override void ResetStream() - { - base.ResetStream(); - - // Reset all values for material stream to avoid pulling from a different stage (VS...etc.) - // TODO: It might be interesting to support pulling from VS, but this should be done from the IMaterialSurface and dedicated ComputerColors - streams.matBlend = 0.0f; - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl deleted file mode 100644 index 72350d86c8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialStreamAdditiveBlend.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Blend a stream linearly - /// - shader MaterialStreamAdditiveBlend : IMaterialStreamBlend - { - override void Compute(Streams fromStream) - { - streams.TMember = fromStream.TMember + streams.TMember; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl deleted file mode 100644 index 4034194719..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialStreamLinearBlend.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Blend a stream linearly - /// - shader MaterialStreamLinearBlend : IMaterialStreamBlend - { - override void Compute(Streams fromStream) - { - streams.TMember = lerp(fromStream.TMember, streams.TMember, streams.matBlend); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl deleted file mode 100644 index d99113b45f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialStreamNormalBlend.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Blend a stream using RNM - /// - shader MaterialStreamNormalBlend : IMaterialStreamBlend - { - override void Compute(Streams fromStream) - { - // Linear interpolation (TODO: We could let the normal blending be configurable) - var middleNormal = NormalUtil.BlendRNM(fromStream.matNormal, streams.matNormal); - - // This is not correct, but try to have a good 0.5 and linear interpol from this - // ideally, we should have RNM support a blending based of matBlend - streams.matNormal = streams.matBlend < 0.5 ? - lerp(fromStream.matNormal, middleNormal, streams.matBlend / 0.5) - : lerp(middleNormal, streams.matNormal, (streams.matBlend - 0.5) * 2); - - //streams.matNormal = normalize(lerp(fromStream.matNormal, streams.matNormal, streams.matBlend)); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl deleted file mode 100644 index 78fc015a7b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomUniform.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialSubsurfaceScatteringScatteringProfileCustomUniform : IMaterialSubsurfaceScatteringScatteringProfile - { - cbuffer PerMaterial - { - stage float4 ScatteringProfile[6]; - } - - // TODO: This does not result in the exact same kind of profiles as the skin profile. But it's close. - // Improve it using the "Extending Separable Subsurface Scattering to Arbitrary Materials" paper. - float3 Compute(float dd) - { - float3 sum = 0.0; - - for(int i=0; i<6; ++i) - { - sum += exp(dd * ScatteringProfile[i].xyz) * ScatteringProfile[i].w; - } - - return sum; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl deleted file mode 100644 index 70fec5180b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileCustomVarying.sdsl +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialSubsurfaceScatteringScatteringProfileCustomVarying : IMaterialSubsurfaceScatteringScatteringProfile - { - compose ComputeColor FalloffMap; - - stage stream float3 falloff; - - override void Prepare(void) - { - // Calculate the falloff here and only once for all lights. - streams.falloff = FalloffMap.Compute().rgb; // TODO: Try supplying the texture using a streams variable instead? Might solve the issue with less code. - } - - float3 Gaussian(float variance, float dd, float3 falloff) - { - // We use a falloff to modulate the shape of the profile. Big falloffs - // spreads the shape making it wider, while small falloffs make it - // narrower. - const float3 adjustedFalloff = 0.001 + falloff; - const float3 adjustedFalloffSquared = adjustedFalloff * adjustedFalloff; - - const float twoVariance = 2.0 * variance; - const float twoPiVariance = 3.14 * twoVariance; - - const float3 adjustedFalloffSquaredTwoVariance = adjustedFalloffSquared * twoVariance; - - return exp(dd / adjustedFalloffSquaredTwoVariance) / twoPiVariance; - } - - float3 Compute(float dd) - { - // We used the red channel of the original skin profile defined in - // [d'Eon07] for all three channels. We noticed it can be used for green - // and blue channels (scaled using the falloff parameter) without - // introducing noticeable differences and allowing for total control over - // the profile. For example, it allows to create blue SSS gradients, which - // could be useful in case of rendering blue creatures. - - return 0.233 * Gaussian(0.0064, dd, streams.falloff) + // We consider this one to be directly bounced light, accounted by the strength parameter (see @STRENGTH) - 0.100 * Gaussian(0.0484, dd, streams.falloff) + - 0.118 * Gaussian(0.187, dd, streams.falloff) + - 0.113 * Gaussian(0.567, dd, streams.falloff) + - 0.358 * Gaussian(1.99, dd, streams.falloff) + - 0.078 * Gaussian(7.41, dd, streams.falloff); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl deleted file mode 100644 index 264fba91ca..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSubsurfaceScatteringScatteringProfileSkin.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - class MaterialSubsurfaceScatteringScatteringProfileSkin : IMaterialSubsurfaceScatteringScatteringProfile - { - float3 Compute(float dd) - { - // Hardcoded skin profile from https://github.com/iryoku/separable-sss - return float3(0.233, 0.455, 0.649) * exp(dd / 0.0064) + - float3(0.1, 0.336, 0.344) * exp(dd / 0.0484) + - float3(0.118, 0.198, 0.0) * exp(dd / 0.187) + - float3(0.113, 0.007, 0.007) * exp(dd / 0.567) + - float3(0.358, 0.004, 0.0) * exp(dd / 1.99) + - float3(0.078, 0.0, 0.0) * exp(dd / 7.41); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceArray.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceArray.sdsl deleted file mode 100644 index 9638626de5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceArray.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialSurfaceArray : IMaterialSurface - { - compose IMaterialSurface layers[]; - - override void Compute() - { - foreach(var layer in layers) - { - layer.Compute(); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl deleted file mode 100644 index 46b30c63f7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuse.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Converts diffuse color - /// - shader MaterialSurfaceDiffuse : IMaterialSurfacePixel - { - compose ComputeColor diffuseMap; - - override void Compute() - { - var colorBase = diffuseMap.Compute(); - streams.matDiffuse = colorBase; - - // Because matDiffuse can be modified when using a metalness, we are storing the colorBase into matColorBase - // so that we are able to query the original diffuse color without any modifications. - streams.matColorBase = colorBase; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl deleted file mode 100644 index 4493318e23..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseMetalFlakes.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Converts diffuse color (for metal flakes layer) - /// - shader MaterialSurfaceDiffuseMetalFlakes : MaterialSurfaceDiffuse, - Transformation, - PositionStream4 - { - compose ComputeColor surfaceToEyeDistanceFactor; - - override void Compute() - { - var basePaintColor = streams.matDiffuse; - - base.Compute(); - - var distanceFactor = surfaceToEyeDistanceFactor.Compute().r; - - // Interpolate the factors using the surface to camera distance - float LOD = saturate(distance(Eye.xyz, streams.PositionWS.xyz) * distanceFactor); - streams.matDiffuse = lerp(streams.matDiffuse, basePaintColor, LOD); - - // Because matDiffuse can be modified when using a metalness, we are storing the colorBase into matColorBase - // so that we are able to query the original diffuse color without any modifications. - streams.matColorBase = lerp(streams.matDiffuse, basePaintColor, LOD); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl deleted file mode 100644 index 6463f9529a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDiffuseSpecularAlphaBlendColor.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha - /// - shader MaterialSurfaceDiffuseSpecularAlphaBlendColor : IMaterialSurfacePixel, MaterialPixelShadingStream - { - override void Compute() - { - streams.shadingColorAlpha = lerp(0, streams.shadingColorAlpha, streams.matDiffuseSpecularAlphaBlend.r); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl deleted file mode 100644 index df813a082c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDisplacement.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Material displacement map - /// - shader MaterialSurfaceDisplacement : IMaterialSurface, MaterialDisplacementStream, PositionStream, NormalStream, Transformation - { - override void Compute() - { - float3 scaledNormal = streams.TNormal; - if(TScaleNormal) - { - scaledNormal *= WorldScale; - } - - streams.TPosition = float4(streams.TPosition.xyz + streams.matDisplacement * scaledNormal, streams.TPosition.w); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl deleted file mode 100644 index 6c0d3ad0e6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceDomainStageCompositor.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - // Temporary code for testing IMaterialSurface - shader MaterialSurfaceDomainStageCompositor : TessellationBase - { - compose IMaterialSurface materialDomainStage; - compose IStreamInitializer streamInitializerDomainStage; - - stage override void TessellateDomain() - { - base.TessellateDomain(); - - // Reset material streams - streamInitializerDomainStage.ResetStream(); - - // Compute the shading of the surface - materialDomainStage.Compute(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl deleted file mode 100644 index 5d7f9561e3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceEmissiveShading.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Emissive shading - /// - shader MaterialSurfaceEmissiveShading : IMaterialSurfacePixel, MaterialPixelShadingStream - { - override void Compute() - { - streams.shadingColor += streams.matEmissive.rgb * streams.matEmissiveIntensity; - if (TUseAlphaFromEmissive) - { - streams.shadingColorAlpha = streams.matEmissive.a; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl deleted file mode 100644 index 1066220f04..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMap.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Material glossiness map - /// - shader MaterialSurfaceGlossinessMap : IMaterialSurfacePixel - { - compose ComputeColor glossinessMap; - - override void Compute() - { - var glossiness = glossinessMap.Compute().r; - if (TInvert) - { - glossiness = 1.0 - glossiness; - } - - streams.matGlossiness = glossiness; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl deleted file mode 100644 index a082bde2f3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceGlossinessMapMetalFlakes.sdsl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Material glossiness map (for a metal flakes layer) - /// - shader MaterialSurfaceGlossinessMapMetalFlakes : MaterialSurfaceGlossinessMap, - Transformation, - PositionStream4 - { - compose ComputeColor surfaceToEyeDistanceFactor; - - override void Compute() - { - var metalFlakesGlossiness = streams.matGlossiness; - - // Compute base glossiness - base.Compute(); - - var distanceFactor = surfaceToEyeDistanceFactor.Compute().r; - - // Correct both glossiness factor (to avoid aliasing and unrealistic values) - float normalLength = length(streams.matNormal); - //streams.matGlossiness = normalLength * streams.matGlossiness / (normalLength + streams.matGlossiness * (1.0f - normalLength)); - metalFlakesGlossiness = normalLength * metalFlakesGlossiness / (normalLength + metalFlakesGlossiness * (1.0f - normalLength)); - - // Interpolate the factors using the surface to camera distance - float LOD = saturate(distance(Eye.xyz, streams.PositionWS.xyz) * distanceFactor); - - streams.matGlossiness = lerp(metalFlakesGlossiness, streams.matGlossiness, LOD); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl deleted file mode 100644 index 04ee00301e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceLightingAndShading.sdsl +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs the shading of a material according to the lights - /// - shader MaterialSurfaceLightingAndShading : IMaterialSurfacePixel, DirectLightGroupArray, EnvironmentLightArray, MaterialPixelShadingStream, Math, Transformation, ShaderBaseStream, NormalUpdate - { - compose IMaterialSurfaceShading surfaces[]; - - override void Compute() - { - // Before performing the shading for all lights, update the NormalVS with the latest normal - // In case normal mapping is not used, this is a no-op - UpdateNormalFromTangentSpace(streams.matNormal); - - // Flip the normal so it is facing the right direction for back faces -#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 - //streams.normalWS = streams.normalWS * sign(streams.IsFrontFace);// FIXME: VFACE seems to not work in a proper way -#else - if(!streams.IsFrontFace) - streams.normalWS = -streams.normalWS; -#endif - - // Make sure that light stream is reset - ResetLightStream(); - - // Prepare the material for lighting (allows to pre-compute things which are reused during lighting computation) - PrepareMaterialForLightingAndShading(); - - // Prepare shading model - foreach (var surface in surfaces) - { - surface.PrepareForLightingAndShading(); - } - - // --------------------------------------------------------------------------- - // Compute Direct Lighting contribution - // --------------------------------------------------------------------------- - float3 directLightingContribution = 0; - foreach(var lightGroup in directLightGroups) - { - lightGroup.PrepareDirectLights(); - - const int maxLightCount = lightGroup.GetMaxLightCount(); - int count = lightGroup.GetLightCount(); - - // [unroll] Don't unroll and let the driver handle it - for(int i = 0; i < maxLightCount; i++) - { - if (i >= count) - { - break; - } - - // Compute the light color and direction - lightGroup.PrepareDirectLight(i); - - // Compute common material shading streams (TODO: This is temporary) - PrepareMaterialPerDirectLight(); - - // Iterate on shading models - foreach(var surface in surfaces) - { - directLightingContribution += surface.ComputeDirectLightContribution(); - } - } - } - - // --------------------------------------------------------------------------- - // Compute Environment Lighting contribution - // --------------------------------------------------------------------------- - float3 environmentLightingContribution = 0; - foreach(var environmentLight in environmentLights) - { - // Compute the environment light color (streams.lightColor) - environmentLight.PrepareEnvironmentLight(); - - // Iterate on shading models - foreach(var surface in surfaces) - { - environmentLightingContribution += surface.ComputeEnvironmentLightContribution(); - } - } - - // Add Direct (*PI over hemisphere) and Environment Lighting - streams.shadingColor += directLightingContribution * PI + environmentLightingContribution; - streams.shadingColorAlpha = streams.matDiffuse.a; - - // Do any computations after lighting and shading, like discarding pixels for example. - foreach (var surface in surfaces) - { - surface.AfterLightingAndShading(); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl deleted file mode 100644 index 97d9fba5af..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceMetalness.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Converts Metalness to specular color - /// - shader MaterialSurfaceMetalness : IMaterialSurfacePixel - { - compose ComputeColor metalnessMap; - - override void Compute() - { - // Metallic workflow - // http://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf - float metalness = metalnessMap.Compute().r; - // Use a low 0.02 reflectance value for non-metal - streams.matSpecular = lerp(0.02, streams.matDiffuse.rgb, metalness); - - // Adjust diffuse - streams.matDiffuse.rgb = lerp(streams.matDiffuse.rgb, 0, metalness); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl deleted file mode 100644 index 11066973e9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalMap.sdsl +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Material normal map - /// - shader MaterialSurfaceNormalMap : IMaterialSurfacePixel - { - compose ComputeColor normalMap; - - override void Compute() - { - var normal = normalMap.Compute(); - - // For unsigned textures we need to convert (0, 1) to (-1, 1) range - if (TScaleAndBias) - { - normal = (2.0f * normal) - 1.0f; - } - - // If Z is calculated from XY do it here - if (TIsNormalXY1) - { - normal.z = sqrt(max(0, 1.0f - (normal.x * normal.x + normal.y * normal.y))); - } - - // Note! Don't normalize the streams.matNormal here, it's being normalize when streams.normalWS is calculated - streams.matNormal = normal.xyz; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl deleted file mode 100644 index 51e0a07775..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceNormalStreamShading.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - // Temporary code for testing IMaterialSurface - shader MaterialSurfaceNormalStreamShading : ShadingBase, NormalStream - { - stage override float4 Shading() - { - // Run surface shading but don't take the result - base.Shading(); - return float4(streams.normalWS * 0.5f + 0.5f, 1.0f); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl deleted file mode 100644 index c6b26c4ffb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfacePixelStageCompositor.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - // Temporary code for testing IMaterialSurface - shader MaterialSurfacePixelStageCompositor : ShadingBase, Transformation, PositionStream, MaterialPixelShadingStream, DirectLightGroupArray, EnvironmentLightArray - { - compose IMaterialSurface materialPixelStage; - compose IStreamInitializer streamInitializerPixelStage; - - stage override float4 Shading() - { - // Prepare global streams (temp) - streams.viewWS = normalize(Eye.xyz - streams.PositionWS.xyz); - streams.shadingColor = 0; - - // Reset material streams - streamInitializerPixelStage.ResetStream(); - - // Compute the shading of the surface - // TODO: separate between material attributes blending and material lighting/shadow shading - materialPixelStage.Compute(); - - // Return the actual shading color - return float4(streams.shadingColor, streams.shadingColorAlpha); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl deleted file mode 100644 index 599951dadf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSetStreamFromComputeColor.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialSurfaceSetStreamFromComputeColor : IMaterialSurfacePixel, IMaterialSurfaceVertex, IMaterialSurfaceDomain - { - compose ComputeColor computeColorSource; - - override void Compute() - { - streams.TStream = computeColorSource.Compute().TChannel; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl deleted file mode 100644 index a390e3a272..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingBlend.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialSurfaceShadingBlend : MaterialSurfaceArray, MaterialPixelShadingStream - { - override void Compute() - { - var backupShadingColor = streams.shadingColor; - var blending = streams.matBlend; - streams.shadingColor = 0; - base.Compute(); - streams.shadingColor = lerp(backupShadingColor, streams.shadingColor, blending); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl deleted file mode 100644 index 7e974af3c6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseCelShading.sdsl +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Cel shading - /// - class MaterialSurfaceShadingDiffuseCelShading : IMaterialSurfaceShading, Math, MaterialPixelShadingStream, LightStream, ShadowGroup - { - compose IMaterialCelShadingLightFunction celLightFunction; - - override float3 ComputeDirectLightContribution() - { - float3 celLight = streams.NdotL * streams.lightAttenuation; - - if (FakeNDotL > 0) - { - celLight = celLightFunction.Compute(celLight * FakeNDotL); - } - else - { - celLight = celLightFunction.Compute(celLight); - } - - float3 lighting = celLight * streams.lightColor * streams.shadowColor * streams.lightDirectAmbientOcclusion; - - var diffuseColor = streams.matDiffuseVisible; - if (TIsEnergyConservative) - { - // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf - diffuseColor *= (1 - streams.matSpecularVisible); - } - - float3 result = diffuseColor / PI * lighting * streams.matDiffuseSpecularAlphaBlend.x; - return result; - } - - override float3 ComputeEnvironmentLightContribution() - { - // TODO: Check how to factorize this with DirectLight - var diffuseColor = streams.matDiffuseVisible; - if (TIsEnergyConservative) - { - diffuseColor *= (1 - streams.matSpecularVisible); - } - - float3 celLight = celLightFunction.Compute(streams.envLightDiffuseColor); - return diffuseColor * celLight; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl deleted file mode 100644 index 4c371808e2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseHair.sdsl +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Calculates the diffuse lighting for hair. - /// - shader MaterialSurfaceShadingDiffuseHair : - IMaterialSurfaceShading, // Required for "ComputeDirectLightContribution()" and the like. - MaterialPixelShadingStream, - Math, // Required for "PI". - LightStream, // Required for "streams.lightColor" and "streams.lightDirectionWS". - MaterialHairShared, - Transformation, // Required for "WorldInverseTranspose". - NormalStream // Required for "streams.normalWS", "streams.meshNormal", "streams.meshTangent". - { - compose IMaterialHairLightAttenuationFunction hairLightAttenuationFunction; - compose IMaterialHairDirectionFunction hairDirectionFunction; - compose IMaterialHairShadowingFunction hairShadowingFunction; - compose IMaterialHairDiscardFunction hairDiscardFunction; - - stream float3 hairDirection; - - override void PrepareForLightingAndShading() - { - streams.hairDirection = hairDirectionFunction.Compute(streams.meshNormal, streams.meshTangent, (float3x3)WorldInverseTranspose); - } - - float3 ComputeHairLightingDiffuse(float3 hairDirection, float3 toLightVec, float3 diffuseLighting) - { - float3 diffuse = diffuseLighting; - //float4 diffuse = LambertBRDF(surfaceData); // Mizuchi version // TODO: Can we delete this line? - - if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) - { - // in Kajiya's model: diffuse component: sin(t, l) - float cosTL = dot(hairDirection, toLightVec); - float sinTL = sqrt(1.0 - cosTL * cosTL); - diffuse *= sinTL; - } - - return diffuse; - } - - float HairDiffuseAttenuation(float dotNL) // "dotNL" must be unsaturated! - { - if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) - { - // No ad-hoc attenuation in Kajiya-Kay formula - // The coefficient for diffuse is applied during ComputeHairLightingDiffuse(), - // therefore we do not apply dotNL. - return 1.0; - } - else - { - //------------------------------------------------------------------------------ - // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.243 : - // "Kajiya-kay diffuse term is too bright" - // "standard dotNL diffuse is too dark in areas facing away from the light" - // "a good compromise is a tweaked dotNL term" - //------------------------------------------------------------------------------ - return saturate(0.75 * dotNL + 0.25); - } - } - - override float3 ComputeDirectLightContribution() - { - if(DebugRenderPasses) - { - return 0.0; // Return 0.0 because the indirect lighting function already returns the debug color. - } - - var diffuseColor = streams.matDiffuseVisible; // This already includes the multiplication by the cavity map. - if (TIsEnergyConservative) - { - // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf - diffuseColor *= (1 - streams.matSpecularVisible); - } - - float3 diffuseLighting = diffuseColor / PI; - diffuseLighting *= streams.lightColor * streams.lightAttenuation; //diffuseLighting *= streams.lightColorNdotL; // Distance- & normal-attenuated light color. - diffuseLighting *= streams.matDiffuseSpecularAlphaBlend.x; - diffuseLighting *= hairShadowingFunction.Compute(); // Apply shadowing/scattering. - diffuseLighting *= streams.lightDirectAmbientOcclusion; - - const float NdotLUnsaturated = dot(streams.normalWS, streams.lightDirectionWS); - - // TODO: Multiply by alpha or not? - float3 finalLighting = ComputeHairLightingDiffuse(streams.hairDirection, streams.lightDirectionWS, diffuseLighting); - finalLighting *= HairDiffuseAttenuation(NdotLUnsaturated); - finalLighting *= hairLightAttenuationFunction.Compute(); - - return finalLighting; - } - - override float3 ComputeEnvironmentLightContribution() - { - if(DebugRenderPasses) - { - return GetDebugColor(PassID); - } - - // TODO: The indirect diffuse hair lighting could be much better. - // For example by taking the hair structure into account just like for the specular lighting. - // But that's difficult because the diffuse environmental lighting is calculated somewhere else. - - // TODO: Check how to factorize this with DirectLight - var diffuseColor = streams.matDiffuseVisible; // This already includes the multiplication by the cavity map. - if (TIsEnergyConservative) - { - diffuseColor *= (1 - streams.matSpecularVisible); - } - - // TODO: Multiply by alpha or not? - return diffuseColor * streams.envLightDiffuseColor; - //return diffuseColor * streams.envLightDiffuseColor * streams.matAmbientOcclusion; // TODO: Does AO work without this? - } - - /* - // TODO: Enabling this allows the diffuse hair shading model to be used independently of the specular one. - // But this would mean if both the specular and the diffuse models are present, the shader will have two conditional discards, which will cause a shader compilation error. - // Need to find a way to fix that. - override void AfterLightingAndShading() - { - hairDiscardFunction.Discard(); - } - */ - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl deleted file mode 100644 index 0532fde3c8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingDiffuseLambert.sdsl +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Lambert shading - /// - shader MaterialSurfaceShadingDiffuseLambert : IMaterialSurfaceShading, Math - { - override float3 ComputeDirectLightContribution() - { - var diffuseColor = streams.matDiffuseVisible; - if (TIsEnergyConservative) - { - // Approximation see: http://research.tri-ace.com/Data/course_note_practical_implementation_at_triace.pdf - diffuseColor *= (1 - streams.matSpecularVisible); - } - return diffuseColor / PI * streams.lightColorNdotL * streams.matDiffuseSpecularAlphaBlend.x; - } - - override float3 ComputeEnvironmentLightContribution() - { - // TODO: Check how to factorize this with DirectLight - var diffuseColor = streams.matDiffuseVisible; - if (TIsEnergyConservative) - { - diffuseColor *= (1 - streams.matSpecularVisible); - } - - return diffuseColor * streams.envLightDiffuseColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl deleted file mode 100644 index b9884e40bf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularBlinnPhong.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Lambert shading - /// - shader MaterialSurfaceShadingSpecularBlinnPhong : IMaterialSurfaceShading, NormalStream - { - override float3 ComputeDirectLightContribution() - { - float k = BRDFBlinnPhong.Compute(streams.lightDirectionWS, streams.normalWS, streams.viewWS, streams.matSpecularPower); - - var specularColor = streams.matSpecular * (streams.matCavity * streams.matCavitySpecular); - - // TODO: integrate AO/Cavity...etc. - // TODO: Check if we need to divide by PI - return specularColor * (k * streams.lightSpecularColorNdotL * streams.matDiffuseSpecularAlphaBlend.y); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl deleted file mode 100644 index 9ce4e1a084..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularCelShading.sdsl +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Microfacet shading - /// - class MaterialSurfaceShadingSpecularCelShading : IMaterialSurfaceShading, MaterialPixelShadingStream, Math, BRDFMicrofacet, LightStream - { - compose IMaterialCelShadingLightFunction celLightFunction; - - compose IMaterialSpecularMicrofacetFresnelFunction fresnelFunction; - - compose IMaterialSpecularMicrofacetVisibilityFunction geometricShadowingFunction; - - compose IMaterialSpecularMicrofacetNormalDistributionFunction normalDistributionFunction; - - compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; - - override float3 ComputeDirectLightContribution() - { - var specularColor = streams.matSpecularVisible; - - var fresnel = fresnelFunction.Compute(specularColor); - var geometricShadowing = geometricShadowingFunction.Compute(); - var normalDistribution = normalDistributionFunction.Compute(); - - var reflected = fresnel * geometricShadowing * normalDistribution / 4; - - return celLightFunction.Compute(reflected) * streams.lightColorNdotL * streams.matDiffuseSpecularAlphaBlend.y; - } - - override float3 ComputeEnvironmentLightContribution() - { - var specularColor = streams.matSpecularVisible; - - // TODO: Allow plugability of this function (pb is that it is a combination of fresnel, visibility and NDF) - //return specularColor * streams.envLightSpecularColor; - return environmentFunction.Compute(specularColor, streams.alphaRoughness, streams.NdotV) * streams.envLightSpecularColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl deleted file mode 100644 index 27008daae2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularHair.sdsl +++ /dev/null @@ -1,374 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs hair shading. - /// - shader MaterialSurfaceShadingSpecularHair : - IMaterialSurfaceShading, // Required for "ComputeDirectLightContribution()" and the like. - MaterialPixelShadingStream, - MaterialHairShared, - NormalStream, // Required for "streams.normalWS", "streams.meshNormal", "streams.meshTangent". - Transformation, // Required for "WorldInverseTranspose". - MaterialPixelStream // Required for "streams.matDiffuse". - { - compose ComputeColor SpecularHighlightsShiftNoiseTexture; - compose ComputeColor SecondarySpecularGlintsNoiseTexture; - - compose IMaterialHairLightAttenuationFunction hairLightAttenuationFunction; - compose IMaterialHairDirectionFunction hairDirectionFunction; - compose IMaterialHairShadowingFunction hairShadowingFunction; - compose IMaterialHairDiscardFunction hairDiscardFunction; - compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; - - cbuffer PerMaterial - { - [Color] - stage float3 HairSpecularColor1; // The color of the primary specular reflection. - - [Color] - stage float3 HairSpecularColor2; // The color of the secondary specular reflection. - - stage float HairScalesAngle; - stage float HairSpecularShiftRatio; - stage float HairSpecularExponent1; - stage float HairSpecularExponent2; - stage float HairSpecularScale1; - stage float HairSpecularScale2; - stage float HairShiftNoiseScale; // Controls how much the noise should affect the specular highlight direction. - stage float HairGlintsNoiseStrength; // Controls how much the glints noise should affect the secondary reflections. - } - - /// - /// Holds all the required input data for hair shading. - /// - struct SurfaceData - { - float hairScalesAngle; - float hairSpecularShiftRatio; - float3 WBinormal; - float3 WViewDir; - float3 WNormal; - float hairSpecularExponent1; // TODO: This is ignored by the indirect lighting. - float hairSpecularExponent2; // TODO: This is ignored by the indirect lighting. - float3 hairSpecularColor1; - float3 hairSpecularColor2; - float cavity; - float hairSpecularScale1; - float hairSpecularScale2; - float hairSecondarySpecularGlintsNoise; - float hairSpecularHighlightsShiftNoise; - }; - - //stream SurfaceData surfaceData; - static SurfaceData surfaceData; // TODO: How to make the variable not get exposed in the CodeBehind? Sadly making this a streams variable causes a shader compilation error. - - SurfaceData GenerateSurfaceData(void) - { - SurfaceData result; - result.hairScalesAngle = HairScalesAngle; - result.hairSpecularShiftRatio = HairSpecularShiftRatio; - result.WViewDir = streams.viewWS; - result.WNormal = streams.normalWS; - - // TODO: Use mesh normal or normal map normal? - result.WBinormal = hairDirectionFunction.Compute(streams.meshNormal, streams.meshTangent, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Get rid of the float3x3 cast? - - result.hairSpecularExponent1 = HairSpecularExponent1; - result.hairSpecularExponent2 = HairSpecularExponent2; - - result.hairSpecularColor1 = HairSpecularColor1; - result.hairSpecularColor2 = HairSpecularColor2; - - result.hairSpecularScale1 = HairSpecularScale1; - result.hairSpecularScale2 = HairSpecularScale2; - - // We can't use "streams.matSpecularVisible" here because it is multiplied by the specular color. - result.cavity = lerp(1.0, streams.matCavity, streams.matCavitySpecular); - - result.hairSpecularHighlightsShiftNoise = (SpecularHighlightsShiftNoiseTexture.Compute().r - 0.5) * HairShiftNoiseScale; - //result.hairSpecularHighlightsShiftNoise = SpecularHighlightsShiftNoiseTexture.Compute().r * HairShiftNoiseScale; - result.hairSecondarySpecularGlintsNoise = lerp(1.0, SecondarySpecularGlintsNoiseTexture.Compute().r, HairGlintsNoiseStrength); - - return result; - } - - override void PrepareForLightingAndShading() // This gets executed only once for the entire shader. - { - surfaceData = GenerateSurfaceData(); - } - - void CalculateShiftAngles(SurfaceData surfaceData, out float shiftAngle1, out float shiftAngle2) - { - // The hair shift is being calculated differently from Mizuchi because the Mizuchi implementation is weird. - - float scalesAngle = surfaceData.hairScalesAngle; - shiftAngle1 = 2.0 * scalesAngle; - shiftAngle2 = -shiftAngle1 * surfaceData.hairSpecularShiftRatio; // hairSpecularShiftRatio is theoretically 1.5 - - shiftAngle1 += surfaceData.hairSpecularHighlightsShiftNoise; - shiftAngle2 += surfaceData.hairSpecularHighlightsShiftNoise; // I think Mizuchi subtracts the noise from the 2nd shift angle. That isn't correct according to my research, so I changed it. - - } - - float HairSingleSpecularTerm_Kajiya(float3 T, float3 toLightVec, float3 viewDir, float shiftAngle) - { - float cosTL = dot(T, toLightVec); - float sinTL = sqrt(1.0 - cosTL * cosTL); - - // in Kajiya's model: specular component: cos(t, rl) * cos(t, e) + sin(t, rl)sin(t, e) - float cosT_RL = -cosTL; - float sinT_RL = sinTL; - float cosTE = dot(T, viewDir); - float sinTE = sqrt(1.0 - cosTE * cosTE); - - // Kajiya-Kay highlight: reflected direction shifted - float cosT_RL_shifted = cosT_RL * cos(shiftAngle) - sinT_RL * sin(shiftAngle); - float sinT_RL_shifted = sqrt(1 - cosT_RL_shifted * cosT_RL_shifted); - return max(0.0, cosT_RL_shifted * cosTE + sinT_RL_shifted * sinTE); - } - - //------------------------------------------------------------------------------ - // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.244 : - // "sum the contribution of two separate specular terms per light" - // "each term has different specular colors, exponents, and is shifted in different directions - //------------------------------------------------------------------------------ - float HairSingleSpecularTerm_Scheuermann(float3 T, float3 H, float exponent) - { - float dotTH = dot(T, H); - //float sinTH = sqrt(1.0 - dotTH * dotTH); // Original version from Mizuchi. Causes artifacts with Scheuermann approximation because of the mathematically correct rotation. The original implementation doesn't suffer from that issue. - float sinTH = sqrt(max(1.0 - dotTH * dotTH, 0.0)); // We limit the value above 0.0 so it doesn't cause NaN errors with the Scheuermann approximation (because of the mathematically correct rotation). - return pow(sinTH, exponent); - } - - //============================================================================== - // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.244 : - // "specular highlights are shifted because the scales on the surface of a hair strand have tilted normals" - // "ideally we would tilt the tangent in the direction of the viewer" - // "in practice it is sufficient to tilt in the direction of the geometric normal" - //============================================================================== - //------------------------------------------------------------------------------ - // Original formula - //------------------------------------------------------------------------------ - //float3 ShiftTangent(float3 T, float3 N, float shiftAmount) - //{ - // return normalize(T + shiftAmount * N); - //} - // - //------------------------------------------------------------------------------ - // Alternative formula (mathematically correct rotation): - // Return vector X (= vector T rotated by angle shiftAngle towards direction N) - //------------------------------------------------------------------------------ - float3 ShiftTangent(float3 T, float3 N, float shiftAngle) - { - // While this function performs mathematically correct rotation, it's probably not desired - // (because the shift texture doesn't represent angles) and instead the original formula should be preferred. - // This is because it can cause the rotation to go beyond 90 degrees, causing the shading vector to point inside the surface, - // causing weird artifacts and issues in other parts of the shading code, which weren't modified to work with the mathematically - // correct rotation but still assume the original shift implemnetation. - - float cosTX = cos(shiftAngle); - float sinTX = sqrt(1.0 - cosTX * cosTX) * sign(shiftAngle); - - if(ShadingModel == HAIR_SHADING_SCHEUERMANN_APPROXIMATION) - { - //return normalize(N + T * shiftAngle); // Original formula - // Simplification (if T,N normal) - Use when T and N are normal - //float cosTN = 0.0; - //float sinTN = 1.0; - return cosTX * T + sinTX * N; - } - else - { - // Handling case when T and N are not really normal - float cosTN = dot(T, N); - float sinTN = sqrt(1.0 - cosTN * cosTN); - float3 X = (cosTX * sinTN - cosTN * sinTX) * T + sinTN * sinTX * N; - return normalize(X); - } - } - - float HairSpecularAttenuation(float dotNL) // "dotNL" must be unsaturated! - { - if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) - { - // No ad-hoc attenuation in Kajiya-Kay formula - // The coefficient for diffuse is applied during ComputeHairLightingSpecular(), - // therefore we do not apply dotNL. - return 1.0; - } - else - { - //------------------------------------------------------------------------------ - // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.246 : - // "specular attenuation for hair facing away from light" - //------------------------------------------------------------------------------ - return saturate(1.75 * dotNL + 0.25); - } - } - - float3 ComputeSpecularKajiya(SurfaceData surfaceData, float3 toLightVec, float shiftAngle, - float specularScale, float specularExponent, float3 specularColor) - { - //-------------------------------------------------------------------------- - // Shifted Kajiya-Kay formula (extension of Kajiya-Kay) - // Similar to what is used in AMD TressFX sample. - //-------------------------------------------------------------------------- - - float shiftedSpecular = HairSingleSpecularTerm_Kajiya(surfaceData.WBinormal, toLightVec, surfaceData.WViewDir, shiftAngle); - return(specularScale * specularColor * pow(shiftedSpecular, specularExponent)); - } - - float3 ComputeSpecularScheuermann(SurfaceData surfaceData, float3 halfVector, float shiftAngle, - float specularScale, float specularExponent, float3 specularColor) - { - //-------------------------------------------------------------------------- - // Scheuermann formula - //-------------------------------------------------------------------------- - // From Shader X3, Chapter 2.14 (Hair Rendering and Shading), P.245 : - // "The lack of real self-shadowing will cause the specular highlights to be - // too bright on the hair facing away from the light" - // "To fade out the specular highlight on the shadowed side of the hair, we - // multiply by an attenuation term that is similar to the diffuse term." - //-------------------------------------------------------------------------- - - // shift tangents - float3 shiftDirection; - - if(ShadingModel == HAIR_SHADING_SCHEUERMANN_APPROXIMATION) - { - shiftDirection = surfaceData.WNormal; - } - else if(ShadingModel == HAIR_SHADING_SCHEUERMANN_IMPROVED) - { - shiftDirection = surfaceData.WViewDir; - } - - const float3 T = ShiftTangent(surfaceData.WBinormal, shiftDirection, shiftAngle); - - // specular term - return(specularScale * specularColor * HairSingleSpecularTerm_Scheuermann(T, halfVector, specularExponent)); - } - - //============================================================================== - // Specular term for hair (for Direct Lighting) - //============================================================================== - float3 ComputeHairLightingSpecular(SurfaceData surfaceData, float3 halfVector, float3 toLightVec) - { - // modulate specular shift by a texture - float shiftAngle1; - float shiftAngle2; - CalculateShiftAngles(surfaceData, shiftAngle1, shiftAngle2); - - float hairSpecularExponent1 = surfaceData.hairSpecularExponent1; // We already make sure on the CPU side that "surfaceData.hairSpecularExponent1" can't be "0.0". - float hairSpecularExponent2 = surfaceData.hairSpecularExponent2; // We already make sure on the CPU side that "surfaceData.hairSpecularExponent2" can't be "0.0". - - float3 specular1; - float3 specular2; - if(ShadingModel == HAIR_SHADING_KAJIYAKAY_SHIFTED) - { - // primary highlight: reflected direction shift towards tip - specular1 = ComputeSpecularKajiya(surfaceData, toLightVec, shiftAngle1, surfaceData.hairSpecularScale1, hairSpecularExponent1, surfaceData.hairSpecularColor1); - // secondary highlight: reflected direction shifted toward root - specular2 = ComputeSpecularKajiya(surfaceData, toLightVec, shiftAngle2, surfaceData.hairSpecularScale2, hairSpecularExponent2, surfaceData.hairSpecularColor2); - } - else - { - // specular terms - specular1 = ComputeSpecularScheuermann(surfaceData, halfVector, shiftAngle1, surfaceData.hairSpecularScale1, hairSpecularExponent1, surfaceData.hairSpecularColor1); - specular2 = ComputeSpecularScheuermann(surfaceData, halfVector, shiftAngle2, surfaceData.hairSpecularScale2, hairSpecularExponent2, surfaceData.hairSpecularColor2); - } - - // modulate secondary specular term with noise - specular2 *= surfaceData.hairSecondarySpecularGlintsNoise; - - float3 specular = (specular1 + specular2) * hairShadowingFunction.Compute(); // Used to apply shadowing/scattering. - return specular * surfaceData.cavity; - } - - float3 ComputeSpecularIndirectLighting(SurfaceData surfaceData, float shiftAngle, float3 specularColor) - { - const float3 shiftedNormal = ShiftTangent(surfaceData.WBinormal, surfaceData.WNormal, shiftAngle); - - // specular term - const float shiftedNdotV = max(dot(shiftedNormal, surfaceData.WViewDir), 0.0); - - float3 specular = environmentFunction.Compute(specularColor, streams.alphaRoughness, shiftedNdotV) * streams.envLightSpecularColor; - - // Since "SpecularTerm_IBL()", which is replaced by "environmentFunction.Compute()", - // applies the cavity parameter internally, we do it too: - specular *= surfaceData.cavity; - - return specular; - } - - //============================================================================== - // Specular term for hair (for Indirect Lighting) - //------------------------------------------------------------------------------ - // Similarly to what is done for the direct lighting, we compute the specular component based on the shifted hair tangents. - // This is not physically realistic because: - // - the ambientBRDF map does not convolve the hair specular BRDF - // However, this is a satisfying approximation at first. - //============================================================================== - float3 ComputeHairImageBasedLightingSpecular(SurfaceData surfaceData) //, IBLTextureParameters IBL) - { - //return 1.0; - - // shift tangents - float shiftAngle1; - float shiftAngle2; - CalculateShiftAngles(surfaceData, shiftAngle1, shiftAngle2); - - float3 specular1 = ComputeSpecularIndirectLighting(surfaceData, shiftAngle1, surfaceData.hairSpecularColor1); - float3 specular2 = ComputeSpecularIndirectLighting(surfaceData, shiftAngle2, surfaceData.hairSpecularColor2); - - specular1 *= surfaceData.hairSpecularScale1; // TODO: This is a workaround to make the indirect lighting look better. Not sure if we should keep it as it basically scales the specular reflection like it does for the direct lighting. - specular2 *= surfaceData.hairSpecularScale2; // TODO: This is a workaround to make the indirect lighting look better. Not sure if we should keep it as it basically scales the specular reflection like it does for the direct lighting. - - // modulate secondary specular term with noise - specular2 *= surfaceData.hairSecondarySpecularGlintsNoise; - - return specular1 + specular2; - } - - override float3 ComputeDirectLightContribution() - { - if(DebugRenderPasses) - { - return 0.0; // Return 0.0 because the indirect lighting function already returns the debug color. - } - - float3 specular = ComputeHairLightingSpecular(surfaceData, - streams.H, // Half vector - streams.lightDirectionWS); // Vector pointing from the pixel towards the light. - - const float NdotLUnsaturated = dot(normalize(streams.normalWS), normalize(streams.lightDirectionWS)); // TODO: PERFORMANCE: Normalization necessary? - - //specular *= saturate(NdotLUnsaturated * 0.5 + 0.5); // This could be used in combination with hair SSS. - specular *= HairSpecularAttenuation(NdotLUnsaturated); - specular *= hairLightAttenuationFunction.Compute(); - specular *= streams.lightColor * streams.lightAttenuation * streams.matDiffuseSpecularAlphaBlend.y; - //specular *= streams.lightDirectAmbientOcclusion; - - // TODO: Multiply by alpha or not? - return specular * streams.matDiffuse.a; // TODO: Technically we should use "streams.shadingColorAlpha" but its value is assigned AFTER the shading, which makes it useless. - } - - override float3 ComputeEnvironmentLightContribution() - { - if(DebugRenderPasses) - { - return GetDebugColor(PassID); - } - - // TODO: Multiply by alpha or not? - return ComputeHairImageBasedLightingSpecular(surfaceData).rgb * streams.matDiffuse.a; // TODO: Technically we should use "streams.shadingColorAlpha" but its value is assigned AFTER the shading, which makes it useless. - } - - override void AfterLightingAndShading() - { - hairDiscardFunction.Discard(); - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl deleted file mode 100644 index 850374956d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceShadingSpecularMicrofacet.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Microfacet shading - /// - shader MaterialSurfaceShadingSpecularMicrofacet : IMaterialSurfaceShading, MaterialPixelShadingStream, Math, BRDFMicrofacet - { - compose IMaterialSpecularMicrofacetFresnelFunction fresnelFunction; - - compose IMaterialSpecularMicrofacetVisibilityFunction geometricShadowingFunction; - - compose IMaterialSpecularMicrofacetNormalDistributionFunction normalDistributionFunction; - - compose IMaterialSpecularMicrofacetEnvironmentFunction environmentFunction; - - override float3 ComputeDirectLightContribution() - { - var specularColor = streams.matSpecularVisible; - - var fresnel = fresnelFunction.Compute(specularColor); - var geometricShadowing = geometricShadowingFunction.Compute(); - var normalDistribution = normalDistributionFunction.Compute(); - - var reflected = fresnel * geometricShadowing * normalDistribution / 4; - - return reflected * streams.lightSpecularColorNdotL * streams.matDiffuseSpecularAlphaBlend.y; - } - - override float3 ComputeEnvironmentLightContribution() - { - var specularColor = streams.matSpecularVisible; - - // TODO: Allow plugability of this function (pb is that it is a combination of fresnel, visibility and NDF) - //return specularColor * streams.envLightSpecularColor; - return environmentFunction.Compute(specularColor, streams.alphaRoughness, streams.NdotV) * streams.envLightSpecularColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl deleted file mode 100644 index 3509478b5b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamShading.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - // Temporary code for testing IMaterialSurface - shader MaterialSurfaceStreamShading : ShadingBase, MaterialPixelShadingStream - { - stage override float4 Shading() - { - // Run surface shading but don't take the result - base.Shading(); - var value = streams.TStreamName; - if (RemapSigned) - value = value * 0.5f + 0.5f; - return float4(value.TStreamRGB, 1.0f); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl deleted file mode 100644 index c87d7e44cf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceStreamsBlend.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialSurfaceStreamsBlend : IMaterialSurface - { - compose IMaterialSurface layer; - - compose IMaterialStreamBlend blends[]; - - override void Compute() - { - var backup = streams; - - // Compute the layer - layer.Compute(); - - // Compute the blending of this layer - foreach(var blendStep in blends) - { - blendStep.Compute(backup); - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl deleted file mode 100644 index 32668edf24..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceSubsurfaceScatteringShading.sdsl +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs subsurface scattering using shadow maps. - /// - class MaterialSurfaceSubsurfaceScatteringShading : - IMaterialSubsurfaceScatteringScatteringProfile, - IMaterialSurfaceShading, // Required for the "PrepareForLightingAndShading()", "ComputeDirectLightContribution()" and "AfterLightingAndShading()" functions. Already includes "MaterialPixelStream.sdsl". - MaterialPixelShadingStream, // Required for "streams.shadingColorAlpha". - ShadowStream, // Required for "streams.thicknessWS". - Math - { - cbuffer PerMaterial - { - stage float Translucency; - stage float ScatteringWidth; - } - - compose IMaterialSubsurfaceScatteringScatteringProfile scatteringProfileFunction; - - stream float scatteringStrength; // TODO: Do we need the stage keyword here? - - float3 CalculateTransmittance(float thickness, - float translucency, // This parameter allows to control the transmittance effect. Its range should be [0..1]. Higher values translate to a stronger effect. - float sssWidth, // This parameter should be the same as the one for the post-process. - float3 meshNormalWS, - float3 lightDirectionWS, - float3 attenuatedLightColor, - float3 surfaceAlbedo) - { - // Calculate the scale of the effect: - const float scale = 8.25 * (1.0 - translucency) / sssWidth; - - // Armed with the thickness, we can now calculate the color by means of the - // precalculated transmittance profile. - // (It can be precomputed into a texture, for maximum performance): - const float d = scale * thickness; - const float dd = -d * d; - - float3 profile = scatteringProfileFunction.Compute(dd); - - // Using the profile, we finally approximate the transmitted lighting from the back of the object: - return profile * saturate(0.3 + dot(lightDirectionWS, -meshNormalWS)) * attenuatedLightColor * surfaceAlbedo; - } - - override void PrepareForLightingAndShading() - { - scatteringProfileFunction.Prepare(); - streams.scatteringStrength = Translucency * streams.matScatteringStrength; - } - - override float3 ComputeDirectLightContribution() - { - float3 scatteredLighting = CalculateTransmittance(streams.thicknessWS, - streams.scatteringStrength, - ScatteringWidth, - streams.meshNormalWS, - streams.lightDirectionWS, - streams.lightColor * streams.lightAttenuation, - streams.matDiffuseVisible); - - return scatteredLighting; - //return scatteredLighting / PI; // TODO: Divide by Pi? - } - - override void AfterLightingAndShading() - { - // Store the scattering strength in the alpha channel, so the post-process can sample it: - streams.shadingColorAlpha = streams.scatteringStrength; // TODO: Is this the best way to write to the alpha channel of the render target? - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl deleted file mode 100644 index 8b829e0c7f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransmittanceShading.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha - /// - shader MaterialSurfaceTransmittanceShading : IMaterialSurfacePixel, MaterialPixelShadingStream, MaterialTransmittanceReflectanceStream - { - override void Compute() - { - // Blend mode is SRC_COLOR, ZERO - // Transmittance == 0 => black - // Transmittance == 1 => preserve color - streams.shadingColor = lerp(1, streams.matTransmittance, streams.shadingColorAlpha); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl deleted file mode 100644 index 26e8f51db8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceTransparentAlphaDiscard.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - shader MaterialSurfaceTransparentAlphaDiscard : IMaterialSurface, MaterialPixelShadingStream, ShaderBaseStream - { - override void Compute() - { - // Discard a pixel if the alpha from the material diffuse is less than the alpha discard limit - if (streams.shadingColorAlpha < streams.matAlphaDiscard) - { - discard; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl deleted file mode 100644 index 80773db836..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexDisplacement.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Material displacement map - /// - shader MaterialSurfaceVertexDisplacement : IMaterialSurfaceVertex - { - override void Compute() - { - var displacement = streams.matDisplacement; - if (TScaleAndBias) - { - displacement = displacement * 2 - 1; - } - - displacement *= streams.matDisplacementIntensity; - - streams.Position = float4(streams.Position.xyz + displacement * streams.meshNormal, streams.Position.w); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl deleted file mode 100644 index 9185a3ef64..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialSurfaceVertexStageCompositor.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - // Temporary code for testing IMaterialSurface - shader MaterialSurfaceVertexStageCompositor : ShaderBase - { - compose IMaterialSurface materialVertexStage; - compose IStreamInitializer streamInitializerVertexStage; - - stage override void VSMain() - { - base.VSMain(); - - // Reset material streams - streamInitializerVertexStage.ResetStream(); - - // Compute the shading of the surface - // TODO: separate between material attributes blending and material lighting/shadow shading - materialVertexStage.Compute(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialTessellationStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialTessellationStream.sdsl deleted file mode 100644 index 94f9aaddb5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialTessellationStream.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - shader MaterialTessellationStream : IStreamInitializer - { - // Displacement height attribute - stage stream float matSmoothingIntensity; - - // The level of details desired - stage stream float oppositeEdgeLOD; - - override void ResetStream() - { - base.ResetStream(); - - streams.oppositeEdgeLOD = 0.0f; - streams.matSmoothingIntensity = 0.0f; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl deleted file mode 100644 index ace6f7dcd0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialTransmittanceReflectanceStream.sdsl +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Modify the alpha color based on the matDiffuseSpecularAlphaBlend alpha - /// - shader MaterialTransmittanceReflectanceStream : MaterialPixelStream - { - cbuffer PerMaterial - { - stage float RefractiveIndex; - } - - stage stream float3 matTransmittance; - stage stream float3 matReflectance; - - override void ResetStream() - { - base.ResetStream(); - - streams.matTransmittance = 0.0f; - streams.matReflectance = 1.0f; - } - - override void PrepareMaterialForLightingAndShading() - { - base.PrepareMaterialForLightingAndShading(); - - // Angle between view vector and surface normal - const float cosTheta = streams.NdotV; - const float sinTheta2 = 1 - cosTheta * cosTheta; // Square of sinTheta - - float eta = max(RefractiveIndex, 1.0001); - - const float sinRefractedTheta2 = sinTheta2 / (eta * eta); // Square of sinRefractedTheta, We don't actually need sinRefractedTheta - const float cosRefractedTheta = sqrt(1 - sinRefractedTheta2); - - const float q0 = (eta * cosRefractedTheta - cosTheta); - const float q1 = (eta * cosRefractedTheta + cosTheta); - const float q2 = (eta * cosTheta - cosRefractedTheta); - const float q3 = (eta * cosTheta + cosRefractedTheta); - - const float r0 = q0 / q1; - const float r1 = q2 / q3; - - // Fresnel reflectance at the entering interface - const float R0 = 0.5 * saturate(r0 * r0 + r1 * r1); // TODO: Test if this command can be optimized by using float2(r0, r1).length() on target platforms - // Fresnel transmittance at the entering interface - const float T0 = 1 - R0; - - // intermediate float3 values - const float3 R = float3(R0, R0, R0); - const float3 T = float3(T0, T0, T0); - const float3 C = float3(cosRefractedTheta, cosRefractedTheta, cosRefractedTheta); - - // Coefficient to account for absorption - const float3 K = pow(max(streams.matColorBase.rgb, 0.001), 1 / C); - - const float3 RK = R*K; // intermediate value - - float3 transmittance = saturate(T*T * K / (1 - RK * RK)); - streams.matReflectance = saturate(RK * transmittance + R); - streams.matTransmittance = transmittance; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MaterialVertexStream.sdsl b/sources/shaders/assets/Stride/SDSL/MaterialVertexStream.sdsl deleted file mode 100644 index 8ffa0a9fbb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MaterialVertexStream.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Materials -{ - /// - /// Contains all the default streams of the vertex shader stage. - /// - shader MaterialVertexStream : MaterialStream, MaterialDisplacementStream, NormalStream, PositionStream - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Math.sdsl b/sources/shaders/assets/Stride/SDSL/Math.sdsl deleted file mode 100644 index cba0235c22..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Math.sdsl +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various math functions. -/// -shader Math -{ - // ------------------------------------- - // constant value - // ------------------------------------- - static const float PI = 3.14159265358979323846; - - // ------------------------------------- - // methods - // ------------------------------------- - // Tests intersection between a ray and a plane - static bool RayIntersectsPlane(float3 rayPosition, - float3 rayDirection, - float3 planeNormal, - float planeDirection, out float3 position) - { - float distance = (planeDirection - dot(planeNormal, rayPosition)) / dot(rayDirection, planeNormal); - position = rayPosition + rayDirection * distance; - return distance >= 0; - } - - // Tests intersection between a ray and a sphere - static bool RayIntersectsSphere(float3 rayPosition, float3 rayDirection, float3 spherePosition, float sphereRadius, out float distance) - { - //Source: Real-Time Collision Detection by Christer Ericson - //Reference: Page 177 - - float3 m = rayPosition - spherePosition; - - float b = dot(m, rayDirection); - float c = dot(m, m) - (sphereRadius * sphereRadius); - - if (c > 0 && b > 0) - { - distance = 0; - return false; - } - - float discriminant = b * b - c; - - if (discriminant < 0) - { - distance = 0; - return false; - } - - distance = -b - sqrt(discriminant); - - if (distance < 0) - distance = 0; - - return true; - } - - // Computes the luminance of a color - float Luminance(float3 color) { - return dot(color, float3(0.2126, 0.7152, 0.0722)); - } - - // ------------------------------------- - // Hermine interpolation - // ------------------------------------- - float Hermine(float x) { - return x * x * (3.0 - 2.0 * x); - } - float2 Hermine(float2 x) { - return x * x * (3.0 - 2.0 * x); - } - float3 Hermine(float3 x) { - return x * x * (3.0 - 2.0 * x); - } - float4 Hermine(float4 x) { - return x * x * (3.0 - 2.0 * x); - } - - // ------------------------------------- - // Quintic interpolation - // ------------------------------------- - float Quintic1(float x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float2 Quintic(float2 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float3 Quintic(float3 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - float4 Quintic(float4 x) { - return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); - } - - // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) - float FastRandom(uint n) - { - n = (n << 13) ^ n; - return float( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0; - } - - // Return a random number in the range [0,1] from Game Programming book (Chapter 5.4) - float FastRandom(float2 x) - { - return FastRandom(uint(x.x * 37 + x.y * 6007)); - } - - // Transforms "vec" by "mat" and does a W-divide. - float4 Project(float4 vec, float4x4 mat) - { - float4 vecProjected = mul(vec, mat); - vecProjected.xyz /= vecProjected.w; - return vecProjected; - } - - //Exponential damping - float ExpDecay(float a, float b, float lambda, float dt) - { - return b + (a - b) * exp(-lambda * dt); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/McIntoshCombineShader.sdsl b/sources/shaders/assets/Stride/SDSL/McIntoshCombineShader.sdsl deleted file mode 100644 index d046e49844..0000000000 --- a/sources/shaders/assets/Stride/SDSL/McIntoshCombineShader.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Outputs the minium of 2 textures. (Final pass of the McIntosh bokeh effect.) - /// Expects as input: - /// - Texture0: a color buffer with diagonal blur - /// - Texture1: a color buffer with diagonal blur - /// - shader McIntoshCombineShader : ImageEffectShader - { - - stage override float4 Shading() - { - float4 minimum = min( Texture0.Sample(Sampler, streams.TexCoord), - Texture1.Sample(Sampler, streams.TexCoord) ); - return minimum; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl b/sources/shaders/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl deleted file mode 100644 index e8b5e8d252..0000000000 --- a/sources/shaders/assets/Stride/SDSL/McIntoshOptimizedShader.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - - /// - /// Optimized version of the McIntosh bokeh effect. - /// Based on a first blur pass, computes the 2 diagonal blurs and keeps the minimum. - /// Expects as input: - /// - Texture0: a color buffer with a first directional blur - /// - Texture1: the corresponding depth buffer - /// - shader McIntoshOptimizedShader : ImageEffectShader - { - compose DepthAwareDirectionalBlurShader blurShader; - compose ComputeColor directionalBlurA; - compose ComputeColor directionalBlurB; - - stage override float4 Shading() - { - // First diagonal blur - float4 blurColorA = directionalBlurA.Compute(); - - // Second diagonal blur - float4 blurColorB = directionalBlurB.Compute(); - - return min(blurColorA, blurColorB); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MeshVelocity.sdsl b/sources/shaders/assets/Stride/SDSL/MeshVelocity.sdsl deleted file mode 100644 index 52c10e5720..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MeshVelocity.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Computes screen space velocity for meshes -shader MeshVelocity : PositionStream4, TransformationBase, ScreenPositionBase, VelocityStream -{ - cbuffer PerDraw - { - float4x4 PreviousWorldViewProjection; - } - - // The previous position in screen space - stage stream float4 PreviousPosition; - - stage override void VSMain() - { - base.VSMain(); - - // Calculate previous world position - streams.PreviousPosition = mul(streams.Position, PreviousWorldViewProjection); - } - - stage override void PSMain() - { - // Calculate screen space velocity - float2 position = streams.ScreenPosition.xy / streams.ScreenPosition.w; - float2 positionLast = streams.PreviousPosition.xy / streams.PreviousPosition.w; - streams.velocity = position - positionLast; - - base.PSMain(); - - //streams.ColorTarget = float4(abs(velocity.xy), 0.0f, 0.0f) * 1.0f; - - //float l = length(velocity.xy); - //streams.ColorTarget = float4(l.xxx, 0.0f) * 15.0f; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl b/sources/shaders/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl deleted file mode 100644 index 041feeb5b8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MixinFunctionParamaterTest.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinFunctionParamaterTest -{ - abstract ExternMixin test0(); - - abstract void test1(ExternMixin ext); -}; diff --git a/sources/shaders/assets/Stride/SDSL/MixinNameClash.sdsl b/sources/shaders/assets/Stride/SDSL/MixinNameClash.sdsl deleted file mode 100644 index 2b56f2ad0e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MixinNameClash.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinNameClash : BasicMixin, BasicMixin2 -{ - void test() - { - float i = myFloat; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/MixinNoNameClash.sdsl b/sources/shaders/assets/Stride/SDSL/MixinNoNameClash.sdsl deleted file mode 100644 index 4bc0d30555..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MixinNoNameClash.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinNoNameClash : BasicMixin, BasicMixin2 -{ - void test() - { - float i = BasicMixin.myFloat + BasicMixin2.myFloat; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ModelComponentPickingShader.sdsl b/sources/shaders/assets/Stride/SDSL/ModelComponentPickingShader.sdsl deleted file mode 100644 index 0ff79ab897..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ModelComponentPickingShader.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Utils -{ - /// - /// A shader used to output the id of the model component, mesh and material for a particular RenderMesh - /// - shader ModelComponentPickingShader : ShaderBase - { - [Color] - stage float4 ModelComponentId; - - [Color] - stage float4 MeshId; - - [Color] - stage float4 MaterialId; - - stage override void PSMain() - { - streams.ColorTarget = ModelComponentId; - streams.ColorTarget1 = MeshId; - streams.ColorTarget2 = MaterialId; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl b/sources/shaders/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl deleted file mode 100644 index 85d407da20..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MultiTexturesSpriteShader.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MultiTexturesSpriteShader : SpriteBase -{ - stage override float4 Shading() - { - return base.Shading() + Texture1.Sample(Sampler, streams.TexCoord); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl b/sources/shaders/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl deleted file mode 100644 index f4ded98eb8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/MultipleRenderTargetsEffectShader.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Graphics.Tests -{ - shader MultipleRenderTargetsEffectShader: ShadingBase - { - stage override void PSMain() - { - base.PSMain(); - streams.ColorTarget = this.Shading(); - streams.ColorTarget1 = this.Shading() * float4(0, 0, 1, 1); - streams.ColorTarget2 = this.Shading() * float4(1, 1, 0, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/NonStageStreamTest.sdsl b/sources/shaders/assets/Stride/SDSL/NonStageStreamTest.sdsl deleted file mode 100644 index 8bf84f7428..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NonStageStreamTest.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader NonStageStreamTest -{ - compose StreamParent2 ext0; - compose StreamParent2 ext1; - - float test() - { - return streams.ext0.parentStream + streams.ext1.parentStream + streams.ext0.stageStream + streams.ext1.stageStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalBase.sdsl b/sources/shaders/assets/Stride/SDSL/NormalBase.sdsl deleted file mode 100644 index 6fd4f17b60..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalBase.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines the methods to get the normal in view space and inserts them in the pipeline. -/// -shader NormalBase : NormalUpdate, ShaderBase -{ - override stage void VSMain() - { - base.VSMain(); - - // Perform normal generation at the end in case vNormal is modified. - // TODO: Another mechanism (compute on first access?) - GenerateNormal_VS(); - } - - override stage void PSMain() - { - // Perform normal generation at beginning so that it is accessible during PS. - // TODO: Another mechanism (compute on first access?) - GenerateNormal_PS(); - base.PSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromMesh.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromMesh.sdsl deleted file mode 100644 index 7fc142c48d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromMesh.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Computes normals in view space. -/// -shader NormalFromMesh : NormalBase, Transformation -{ - override stage void GenerateNormal_VS() - { - // Perform normal generation at the end in case meshNormal is modified - streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? - streams.normalWS = streams.meshNormalWS; - } - - override stage void GenerateNormal_PS() - { - // Normalize just once the normal coming from the vertex shader - if (dot(streams.normalWS, streams.normalWS) > 0) - streams.normalWS = normalize(streams.normalWS); - streams.meshNormalWS = streams.normalWS; - } - - stage override void UpdateNormalFromTangentSpace(float3 normalInTangentSpace) - { - // Override the default behavior, as we are not changing the NormalVS calculated at vertex stage when normal mapping is not used - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl deleted file mode 100644 index 92fb617f76..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromMeshInstanced.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Computes normals in view space. -/// -shader NormalFromMeshInstanced : NormalFromMesh, TransformationInstancing -{ - override stage void GenerateNormal_VS() - { - // Perform normal generation at the end in case meshNormal is modified - streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? - streams.normalWS = streams.meshNormalWS; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMapping.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromNormalMapping.sdsl deleted file mode 100644 index e92e0e9b2f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMapping.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Calculates the normal the normals from a normal map. -/// -shader NormalFromNormalMapping : Transformation, NormalBase, NormalStream -{ - override stage void GenerateNormal_PS() - { - base.GenerateNormal_PS(); - UpdateTangentToWorld(); - // Transform meshNormal from object space to world space: - streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? - } - - override float3x3 GetTangentWorldTransform() - { - return (float3x3)WorldInverseTranspose; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl deleted file mode 100644 index 3c289ea545..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingInstanced.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Calculates the normal the normals from a normal map. -/// -shader NormalFromNormalMappingInstanced : TransformationInstancing, NormalBase, NormalStream -{ - override stage void GenerateNormal_PS() - { - base.GenerateNormal_PS(); - UpdateTangentToWorld(); - // Transform meshNormal from object space to world space: - streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? - } - - override float3x3 GetTangentWorldTransform() - { - return transpose((float3x3)GetInstanceWorldInverse(streams.InstanceID)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl deleted file mode 100644 index cfcd65e7ab..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellation.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Calculates the normal the normals from a normal map. -/// -shader NormalFromNormalMappingTessellation : NormalFromNormalMapping -{ - override stage void GenerateNormal_VS() - { - // Perform normal generation at the end in case meshNormal is modified - streams.meshNormalWS = mul(streams.meshNormal, (float3x3)WorldInverseTranspose); // TODO: PERFORMANCE: Normalization required? - streams.normalWS = streams.meshNormalWS; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl b/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl deleted file mode 100644 index e01db64831..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalFromNormalMappingTessellationInstanced.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Calculates the normal the normals from a normal map. -/// -shader NormalFromNormalMappingTessellationInstanced : NormalFromNormalMappingInstanced, TransformationInstancing -{ - override stage void GenerateNormal_VS() - { - // Perform normal generation at the end in case meshNormal is modified - streams.meshNormalWS = mul((float3x3)GetInstanceWorldInverse(streams.InstanceID), streams.meshNormal); // TODO: PERFORMANCE: Normalization required? - streams.normalWS = streams.meshNormalWS; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalMeshSkinning.sdsl b/sources/shaders/assets/Stride/SDSL/NormalMeshSkinning.sdsl deleted file mode 100644 index 84c1212c6d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalMeshSkinning.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Performs skinning on the normals. -/// -shader NormalMeshSkinning : TransformationSkinning, NormalStream -{ - override stage void PreTransformPosition() - { - base.PreTransformPosition(); - streams.meshNormal = normalize(mul(streams.meshNormal, (float3x3)streams.skinningBlendMatrix)); // TODO: Does this result in an object or world space normal? If world space, write to meshNormalWS instead! - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalPack.sdsl b/sources/shaders/assets/Stride/SDSL/NormalPack.sdsl deleted file mode 100644 index debed9bd89..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalPack.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Packs and stores the normals into the GBuffer. Expected texture output format: float3. -/// -shader NormalPack -{ - // Compact Normal Storage for Small G-Buffers - // [Aras Pranckevičius 2010, http://aras-p.info/texts/CompactNormalStorage.html] - float3 EncodeNormal(float3 n) - { - // Pack to [0;1] range - return n * 0.5 + 0.5; - } - - // Compact Normal Storage for Small G-Buffers - // [Aras Pranckevičius 2010, http://aras-p.info/texts/CompactNormalStorage.html] - float3 DecodeNormal(float3 enc) - { - // Unpack from [0;1] range - return normalize(enc * 2 - 1); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalStream.sdsl b/sources/shaders/assets/Stride/SDSL/NormalStream.sdsl deleted file mode 100644 index 737af23cfa..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalStream.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines the normal, view space normal and tangent streams. -/// -shader NormalStream -{ - // The normal attribute from the mesh - stage stream float3 meshNormal : NORMAL; - - // The above normal but in world space - stage stream float3 meshNormalWS; // This gets set in "NormalFromNormalMapping.sdsl" and "NormalFromMesh.sdsl". - - // The tangent attribute from the mesh - stage stream float4 meshTangent : TANGENT; - - // The normal in world space - stage stream float3 normalWS : NORMALWS; - - // The tangent to view matrix to transform a tangent normal vector to normal vector in viewspace - stage stream float3x3 tangentToWorld; -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalUpdate.sdsl b/sources/shaders/assets/Stride/SDSL/NormalUpdate.sdsl deleted file mode 100644 index 19952503db..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalUpdate.sdsl +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines the methods to get the normal in world space. -/// -shader NormalUpdate : NormalStream -{ - stage void GenerateNormal_VS() - { - streams.normalWS = 0.0f; - } - - stage void GenerateNormal_PS() - { - } - - float3x3 GetTangentMatrix() - { - float3x3 tangentMatrix; - - streams.meshNormal = normalize(streams.meshNormal); - var tangent = normalize(streams.meshTangent.xyz); - float3 bitangent = streams.meshTangent.w * cross(streams.meshNormal, tangent); - tangentMatrix = float3x3(tangent, bitangent, streams.meshNormal); - - return tangentMatrix; - } - - stage void UpdateTangentToWorld() - { - var tangentMatrix = GetTangentMatrix(); - var tangentWorldTransform = GetTangentWorldTransform(); - streams.tangentToWorld = mul(tangentMatrix, tangentWorldTransform); - } - - float3x3 GetTangentWorldTransform() - { - return float3x3(1,0,0, 0,1,0, 0,0,1); - } - - // This method is called by the MaterialSurfaceLightingAndShading to calculate the effective normal - stage void UpdateNormalFromTangentSpace(float3 normalInTangentSpace) - { - streams.normalWS = normalize(mul(normalInTangentSpace, streams.tangentToWorld)); - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/NormalUtil.sdsl b/sources/shaders/assets/Stride/SDSL/NormalUtil.sdsl deleted file mode 100644 index ec71999000..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalUtil.sdsl +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various methods for manipulating normals -/// -shader NormalUtil -{ - // Blending Normal methods: http://blog.selfshadow.com/publications/blending-in-detail/ - - float3 BlendLinear(float3 n1, float3 n2) - { - return normalize(n1 + n2); - } - - float3 BlendPartialDerivative(float3 n1, float3 n2) - { - return normalize(float3(n1.xy*n2.z + n2.xy*n1.z, n1.z*n2.z)); - } - - float3 BlendPartialDerivative(float3 n1, float3 n2, float blend) - { - float2 pd = lerp(n1.xy/(n1.z + 0.00001), n2.xy/(n2.z + 0.00001), blend); - return normalize(float3(pd, 1)); - } - - float3 BlendWhiteout(float3 n1, float3 n2) - { - return float3(n1.xy + n2.xy, n1.z*n2.z); - } - - float3 BlendUDN(float3 n1, float3 n2) - { - return normalize(float3(n1.xy + n2.xy, n1.z)); - } - - float3 BlendRNM(float3 n1, float3 n2) - { - // TEMP try to keep length - var length_n1n2 = length(n1+n2); - n1 = normalize(n1); - n2 = normalize(n2); - - float3 t = n1 + float3(0, 0, 1); - float3 u = float3(-n2.x, -n2.y, n2.z); - float3 r = t*dot(t, u) - u*t.z; - return normalize(r) * length_n1n2; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl b/sources/shaders/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl deleted file mode 100644 index 169d3ca5bc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningFromMesh.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Computes skinned normals in view space. -/// -shader NormalVSSkinningFromMesh : NormalFromMesh -{ - override stage void GenerateNormal_VS() - { - // Because meshNormal is already integrating World space, use it as-is for final normalWS - streams.normalWS = streams.meshNormal; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl b/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl deleted file mode 100644 index 09aed85e27..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMapping.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Computes the transformation matrix from tangent to view space when skinning occured. -/// -shader NormalVSSkinningNormalMapping : NormalFromNormalMapping -{ - override float3x3 GetTangentWorldTransform() - { - // TangentMatrix is already in world space, so return an identity matrix here - return float3x3(1,0,0, 0,1,0, 0,0,1); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl b/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl deleted file mode 100644 index 12e6d9fbc1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/NormalVSSkinningNormalMappingTessellation.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Calculates the normal the normals from a normal map. -/// -shader NormalVSSkinningNormalMappingTessellation : NormalVSSkinningNormalMapping -{ - override stage void GenerateNormal_VS() - { - // Because meshNormal is already integrating World space, use it as-is for final normalWS - streams.normalWS = streams.meshNormal; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/OpaqueBase.sdsl b/sources/shaders/assets/Stride/SDSL/OpaqueBase.sdsl deleted file mode 100644 index 2c96caccfa..0000000000 --- a/sources/shaders/assets/Stride/SDSL/OpaqueBase.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a texture for the output of the opaque render pass -/// and a helper function to extract the color of it. -/// -shader OpaqueBase : Texturing -{ - // ------------------------------------- - // Resources - // ------------------------------------- - rgroup PerView.Opaque - { - stage Texture2D OpaqueRenderTarget; - } - - float3 GetOpaqueColor(float2 uv) - { - return OpaqueRenderTarget.SampleLevel(PointSampler, uv, 0.0).xyz; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/OutlineEffect.sdsl b/sources/shaders/assets/Stride/SDSL/OutlineEffect.sdsl deleted file mode 100644 index 36fbc41684..0000000000 --- a/sources/shaders/assets/Stride/SDSL/OutlineEffect.sdsl +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Simple fog - /// - internal shader OutlineEffect : ImageEffectShader - { - stage float2 ScreenDiffs; // .x = Width, .y = Height - - stage float zFar; - stage float zNear; - - stage float NormalWeight; - stage float DepthWeight; - stage float NormalNearCutoff; - - stage Texture2D DepthTexture; - - float3 normal_from_depth(float depth, float2 texcoords) { - const float2 offset1 = float2(0.0,ScreenDiffs.y); - const float2 offset2 = float2(ScreenDiffs.x,0.0); - - float depth1 = DepthTexture.SampleLevel(PointSampler, texcoords + offset1, 0.0).x; - float depth2 = DepthTexture.SampleLevel(PointSampler, texcoords + offset2, 0.0).x; - - float3 p1 = float3(offset1, depth1 - depth); - float3 p2 = float3(offset2, depth2 - depth); - - float3 normal = cross(p1, p2); - normal.z = -normal.z; - - return normalize(normal); - } - - float4 fetchNormalDepth(float2 tc){ - float4 nd; // return value - - // get depth - float z_b = DepthTexture.SampleLevel(PointSampler, tc, 0.0).x; - float z_n = 2.0 * z_b - 1.0; - float linearDepth = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear)); - - // linear depth - nd.w = DepthWeight * linearDepth; - - // normal, but skip stuff really close - nd.xyz = step(NormalNearCutoff, linearDepth) * normal_from_depth(z_b, tc) * NormalWeight; - - return nd; - } - - stage override float4 Shading() { - float4 color = Texture0.Sample(PointSampler, streams.TexCoord); - - float4 n1 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, -ScreenDiffs.y)); - float4 n2 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, ScreenDiffs.y)); - float4 n3 = fetchNormalDepth(streams.TexCoord + float2(-ScreenDiffs.x, ScreenDiffs.y)); - float4 n4 = fetchNormalDepth(streams.TexCoord + float2( ScreenDiffs.x, -ScreenDiffs.y)); - - // Work out how much the normal and depth values are changing. - float4 diagonalDelta = abs(n1 - n2) + abs(n3 - n4); - - float normalDelta = dot(diagonalDelta.xyz, float3(1.0, 1.0, 1.0)); - float totalDelta = diagonalDelta.w + normalDelta * 0.4; - - return float4(color.xyz * (1.0 - clamp(totalDelta, 0.0, 1.0)), 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Parent.sdsl b/sources/shaders/assets/Stride/SDSL/Parent.sdsl deleted file mode 100644 index e58652e647..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Parent.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Parent -{ - float baseValue = 2.0f; - Texture2D parentTexture; - - float AddBaseValue(float inValue) - { - float a0 = 0.0f, - a1 = 1.0f; - return inValue + baseValue + a0 + a1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ParticleBase.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleBase.sdsl deleted file mode 100644 index 617678c76f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleBase.sdsl +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#ifndef UsesSoftEdge -# define UsesSoftEdge 0 -#endif - -shader ParticleBase : DepthBase, ShaderBase, Texturing, ParticleUtilities -{ - // ------------------------------------- - // streams - // ------------------------------------- - - // Shading position of the vertices/pixels - stage stream float4 Position : POSITION; - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 - // No extra streams are required -#else - stage stream float4 ScreenPosition : SCREEN_POSITION; -#endif - - // Linear depth of the position in view space in world units, used for soft edges - stage stream float ZDepth : Z_DEPTH_VALUE; - - // ------------------------------------- - // conditional streams - may or may not be present depending on existing particle fields - // ------------------------------------- - //stage stream float4 Color : COLOR; - nointerpolation stage stream float Lifetime : BATCH_LIFETIME; - nointerpolation stage stream float RandomSeed : BATCH_RANDOMSEED; // Ideally should be uint. Note! The sdsl doesn't support nointerpolation, so cast the float as int before using it - - cbuffer PerMaterial - { - stage float4 ColorScale; - - // When the value is 0 there is no occlusion (100% emissive), when it is 1 there is 100% occlusion (still limited by alpha) - stage float AlphaAdditive; - - // Z offset is how much the depth should be adjusted when rendering - stage float ZOffset; - - // 0 if disabled, equal to 1/Distance otherwise - stage float SoftEdgeInverseDistance; - } - - // ------------------------------------- - // VertexShader - // ------------------------------------- - - // Override Vertex shader main method from the ShaderBase shader - stage override void VSMain() - { - float4 worldPos = streams.Position; - - float4 viewPos = mul(worldPos, ViewMatrix); - - streams.ShadingPosition = mul(viewPos, ProjectionMatrix); - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 - // No extra code is required -#else - // TODO Check if we can optimize the code here. Possible that the .x/.w and .y/.w operations can't be optimized because of inproper interpolation. - streams.ScreenPosition = streams.ShadingPosition; -#endif - - // Z Offset - viewPos.w = 1; - viewPos.z += ZOffset; - - streams.ZDepth = viewPos.z; - - float4 viewProjPos = mul(viewPos, ProjectionMatrix); - - streams.ShadingPosition.z = (viewProjPos.z / viewProjPos.w) * streams.ShadingPosition.w; - } - - // ------------------------------------- - // PixelShader - // ------------------------------------- - - // Override Pixel shader main method from the ShaderBase shader - stage override void PSMain() - { - float4 colorTarget = Shading(); - - if (UsesSoftEdge > 0) - { - float screenWidth = ViewFrustum.x; - float screenHeight = ViewFrustum.y; - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 - var screenCoords = streams.ShadingPosition.xy; - screenCoords.x /= screenWidth; - screenCoords.y /= screenHeight; -#else - var screenCoords = (streams.ScreenPosition.xy / streams.ScreenPosition.ww) * float2(0.5, 0.5) + float2(0.5, 0.5); - screenCoords.y = 1 - screenCoords.y; -#endif - - // Account for Viewport offset and scaling - screenCoords.xy = Viewport.xy + screenCoords.xy * Viewport.zw; - - // Convert to linear depth for proper edge smoothing - float linearZOwn = -streams.ZDepth; - float linearZOpaque = GetLinearDepth(DepthStencil.Sample(Texturing.PointSampler, screenCoords).r); - - // Get the positive difference - var depthDistance = linearZOpaque - linearZOwn; - - // TODO Maybe set upper and lower bounds for more interesting effects - - // smoothstep(...) looks more natural than saturate(...): - var softEdge = smoothstep(0, 1, depthDistance * SoftEdgeInverseDistance); - colorTarget.rgba *= softEdge; - } - else - { - // Do nothing. The depth testing is enabled - } - - colorTarget.a *= AlphaAdditive; - - streams.ColorTarget = colorTarget; - } - - stage float4 Shading() - { - return ColorScale; - } - -}; diff --git a/sources/shaders/assets/Stride/SDSL/ParticleColor.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleColor.sdsl deleted file mode 100644 index 18226c4bb8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleColor.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Rendering -{ - // This is a sample shader for plugging into the Shader input for ComputeColor computations - shader ParticleColor : ComputeColor - { - override float4 Compute() - { - return float4(1, 1, 1, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ParticleColorStream.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleColorStream.sdsl deleted file mode 100644 index 59ef3470fc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleColorStream.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Rendering -{ - // This is a sample shader for plugging into the Shader input for ComputeColor computations - shader ParticleColorStream : ParticleColor - { - // ------------------------------------- - // uniforms - // ------------------------------------- - stage stream float4 Color : COLOR; - - override float4 Compute() - { - return streams.Color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ParticleComputeColorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleComputeColorShader.sdsl deleted file mode 100644 index ef9562d873..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleComputeColorShader.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering -{ - -shader ParticleComputeColorShader : ParticleBase -{ - // ------------------------------------- - // streams - // ------------------------------------- - compose ComputeColor baseColor; - - // Shading of the sprite - stage override float4 Shading() - { - // ----------------------------------------------- - // Base particle color - // ----------------------------------------------- - float4 finalColor = base.Shading() * baseColor.Compute(); - - return finalColor; - } -}; - -} diff --git a/sources/shaders/assets/Stride/SDSL/ParticleCustomShader.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleCustomShader.sdsl deleted file mode 100644 index 306d4fbf64..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleCustomShader.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// By inheriting the ParticleBase we inherit Texturing and the VSMain/PSMain methods, enough to draw a uniformly colored quad - -shader ParticleCustomShader : ParticleBase -{ - // ------------------------------------- - // streams - // ------------------------------------- - - // This shader is settable by the user, and it's a binary tree made up from smaller shaders - compose ComputeColor baseColor; - - // This shader is settable by the user, and it's a binary tree made up from smaller shaders - compose ComputeColor baseIntensity; - - // Shading of the sprite - we override the base shader's Shading(), which only returns ColorScale - stage override float4 Shading() - { - // ----------------------------------------------- - // Base particle color RGB - // ----------------------------------------------- - float4 finalColor = base.Shading() * baseColor.Compute(); - - // ----------------------------------------------- - // Base particle alpha - // ----------------------------------------------- - finalColor.a = baseIntensity.Compute(); - - // Don't forget to premultiply the alpha - finalColor.rgb *= finalColor.aaa; - - return finalColor; - } -}; - diff --git a/sources/shaders/assets/Stride/SDSL/ParticleUtilities.sdsl b/sources/shaders/assets/Stride/SDSL/ParticleUtilities.sdsl deleted file mode 100644 index a4f3db83e9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ParticleUtilities.sdsl +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader ParticleUtilities -{ - - // ------------------------------------- - // uniforms - // ------------------------------------- - - // !When a bigger structure (float4) follow a smaller structure (float) the binding seems off - // Declare the uniforms in the order float4x4 > float4 > float > uint - cbuffer PerView - { - stage float4x4 ViewMatrix; - stage float4x4 ProjectionMatrix; - stage float4x4 ViewProjectionMatrix; - - // .x - Width, .y - Height, .z - Near, .w - Far - stage float4 ViewFrustum; - - stage float4 Viewport; - } - - stage float GetLinearDepth(float z) - { - float fastA = -ProjectionMatrix._33; // = zFar / (zFar - zNear); - float fastB = ProjectionMatrix._43; // = (-zFar * zNear) / (zFar - zNear); - return fastB / (z - fastA); - } - - // ------------------------------------- - // Randomness - // ------------------------------------- - - // Some notes on randomness - // The algorithm below is uses unsigned integer as input and generates deterministic random values with good distribution. - // Because we can't pass uint as vertex input, we use a float and cast it twice to prevent interpolation errors. - // Also, casting a huge uint value to float causes underflow, so we limit the input value to 0 .. 0xFFFF (the masking is done on the CPU side) - - static const float GelfondConst = 23.1406926327792690; // e to the power of Pi = (-1) to the power of -i - static const float GelfondSchneiderConst = 2.6651441426902251; // 2 to the power of sqrt(2) - static const float2 Gelfond = float2(GelfondConst, GelfondSchneiderConst); - static const float Numerator = 123456789; - - float GetRandom(float fSeed) - { - // Cast to int once to prevent interpolation errors - int uSeed = (int) (fSeed); - fSeed = (float) uSeed; - - float2 rand2 = float2(cos(fSeed), sin(fSeed)); - - float dotProduct = dot(rand2, Gelfond); - - return frac(fmod(Numerator, 1e-7 + 256.f * dotProduct)); - } -}; - diff --git a/sources/shaders/assets/Stride/SDSL/PickingShader.sdsl b/sources/shaders/assets/Stride/SDSL/PickingShader.sdsl deleted file mode 100644 index 934e4b9c36..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PickingShader.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering -{ - /// - /// A shader used to output the id of the model component, mesh and material for a particular RenderMesh - /// - shader PickingShader : ShaderBase - { - cbuffer PerDraw - { - stage float4 PickingData; - } - - stage override void PSMain() - { - float modelComponentId = PickingData.x + (min(streams.InstanceID, 1023.0) / 1024.0); - float meshMaterialIndex = PickingData.y; - streams.ColorTarget = float4(modelComponentId, meshMaterialIndex, 1, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/PointDepth.sdsl b/sources/shaders/assets/Stride/SDSL/PointDepth.sdsl deleted file mode 100644 index 482ab118e4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PointDepth.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Constantlty outputs the depth of a given point in the image. - /// - shader PointDepth: ImageEffectShader - { - float2 Coordinate; - - stage override float4 Shading() - { - return Texture0.Sample(Sampler, Coordinate).y; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/PositionHStream4.sdsl b/sources/shaders/assets/Stride/SDSL/PositionHStream4.sdsl deleted file mode 100644 index 435b723332..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PositionHStream4.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines a world space position stream. -/// -shader PositionHStream4 -{ - stream float4 PositionH : POSITIONH; -}; diff --git a/sources/shaders/assets/Stride/SDSL/PositionStream.sdsl b/sources/shaders/assets/Stride/SDSL/PositionStream.sdsl deleted file mode 100644 index a1523f093d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PositionStream.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Gets the correct shader to have a position stream in a float4 (even if attribute is a float2). -/// -/// -/// PDX_USE_FLOAT_INPUT: Macro - Switch between float2 of float4 position attribute. -/// -#ifdef PDX_USE_FLOAT2_INPUT_INPUT -shader PositionStream : PositionStream2 -{ -}; -#else -shader PositionStream : PositionStream4 -{ -}; -#endif diff --git a/sources/shaders/assets/Stride/SDSL/PositionStream2.sdsl b/sources/shaders/assets/Stride/SDSL/PositionStream2.sdsl deleted file mode 100644 index 150c3bc8bb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PositionStream2.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines streams for object space position when the corresponding attribute is a float2. Sets its value in a float4. -/// -shader PositionStream2 : ShaderBase -{ - // The position attribute - stage stream float2 Position2 : POSITION; - - // The position as a float4 - stage stream float4 Position : ExpandedPosition4; - - override stage void VSMain() - { - streams.Position = float4(streams.Position2, 0.0f, 1.0f); - base.VSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/PositionStream4.sdsl b/sources/shaders/assets/Stride/SDSL/PositionStream4.sdsl deleted file mode 100644 index cde967ff1c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PositionStream4.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines streams for object space and world space position. -/// -shader PositionStream4 -{ - // The position attribute - stage stream float4 Position : POSITION; - - // The position in world space - stage stream float4 PositionWS : POSITION_WS; - - // The depth in view space - stage stream float DepthVS : DEPTH_VS; -}; diff --git a/sources/shaders/assets/Stride/SDSL/PositionVertexTransform.sdsl b/sources/shaders/assets/Stride/SDSL/PositionVertexTransform.sdsl deleted file mode 100644 index 454dacb2a2..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PositionVertexTransform.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Provides a stream with the view space position (vertex or fragment) from the vertex attributes. -/// -shader PositionVertexTransform : ShaderBase, Transformation, PositionStream -{ - stage override void VSMain() - { - base.VSMain(); - streams.PositionWS = mul(streams.Position, World); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/PostEffectBoundingRay.sdsl b/sources/shaders/assets/Stride/SDSL/PostEffectBoundingRay.sdsl deleted file mode 100644 index 230dd9b0be..0000000000 --- a/sources/shaders/assets/Stride/SDSL/PostEffectBoundingRay.sdsl +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -/// -/// TSampleCount: generic int - number of iterations. -/// -shader PostEffectBoundingRay : ImageEffectShader, DepthBase, Transformation, PositionStream4 -{ - float3 ComputeColorOut() - { - return 0; - } - - float3 ComputeColorIn(float4 positionWS, float stepSize, int stepIndex) - { - return 0; - } - - int HashXYZ(float3 input) - { - return int(input.z * 313 + input.x * 1039 + input.y * 638359); - } - - float RayStepJitter(float3 input, float stepSize) - { - return stepSize * Math.FastRandom(HashXYZ(input)); - } - - float4 ComputeFinalColor(float3 lightAcc) - { - return float4(lightAcc.xxx, 1.0f); - } - - stage override void PSMain() - { - // minmax.x = min - // minmax.y = max - float2 minmax = Texture0.Sample(PointSampler, streams.TexCoord).xy; - - float backsideMin = Texture1.Sample(PointSampler, 0.0f).x; - if(backsideMin < 1.0f) - minmax.x = 0.0f; - - // Need at least a maximum value for this pixel to be contained in the bounding box - if(minmax.y < 1.0f) - { - float currentZ = GetZProjDepthFromUV(streams.TexCoord); - float minZ = minmax.x; - float maxZ = min(minmax.y, currentZ); - - float minDistance = ComputeDepthFromZProj(minZ); - float maxDistance = ComputeDepthFromZProj(maxZ); - - // Compute world space direction and position of the ending position - float4 positionClipSpace = float4((1.0f - streams.TexCoord.xy * 2.0f) * float2(-1.0f, 1.0f), maxZ, 1.0f); - float4 positionVS = mul(positionClipSpace, ProjectionInverse); - positionVS.xyzw /= positionVS.w; - float4 endingPosition = mul(positionVS, ViewInverse); - float3 endingPositionDelta = endingPosition.xyz - Eye.xyz; - float4 directionWS = float4(endingPositionDelta, 0.0f); - directionWS = normalize(directionWS); - - // Compute depth slope and apply it to the world space direction so it can be multiplied by depth distances - float depthSlope = length(endingPositionDelta) / maxDistance; - directionWS *= depthSlope; - - float stepRange = (maxDistance - minDistance); - float stepSize = stepRange / (float)TSampleCount; - - float3 lightResult = 0.0f; - - // Expected by the directional shadow map to compute the cascades - streams.DepthVS = minDistance; - if(maxDistance > minDistance) - { - // Recalculate max distance by jittering the length of the ray to avoid banding artifacts - stepSize = (maxDistance - minDistance) / (float)TSampleCount; - - // Starting position - float4 positionWS = endingPosition + (RayStepJitter(positionVS.xyz, stepSize)-stepRange) * directionWS; - streams.DepthVS = minDistance; - - for(int i = 0; i < TSampleCount; i++) - { - lightResult += this.ComputeColorIn(positionWS, stepSize, i); - positionWS += stepSize * directionWS; - streams.DepthVS += stepSize; - } - } - - streams.ColorTarget = ComputeFinalColor(lightResult); - } - else // Outside the bounding box - { - streams.ColorTarget = ComputeFinalColor(this.ComputeColorOut()); - } - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl b/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl deleted file mode 100644 index 3a20edde68..0000000000 --- a/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXNoComputeShader.sdsl +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Shader performing radiance GGX pre-filtering - /// - shader RadiancePrefilteringGGXNoComputeShader : Math, ImageEffectShader - { - // the input texture containing the radiance - int RadianceMapSize; - - TextureCube RadianceMap; - - // The number of mipmap available - stage float MipmapCount; - - // The roughness of the GGX distribution - stage float Roughness; - - // The current face - stage int Face; - - // compute the pre-filtered environment map for input (group) direction - override stage float4 Shading() - { - // Calculate the direction of the texel in the cubemap - float3 R = normalize(CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, Face)); - - float4 prefilteredSample = 0; - - for (int sampleIndex = 0; sampleIndex < TNbOfSamples; sampleIndex++) - { - // Perform one sampling, calculate pre-filtered color and weight contribution - var xi = Hammersley.GetSamplePlane(sampleIndex, TNbOfSamples); - var H = ImportanceSamplingGGX.GetSample(xi, Roughness, R); - - float3 L = 2 * dot(R, H) * H - R; - float NoL = saturate(dot(R, L)); - float pdf = BRDFMicrofacet.NormalDistributionGGX(Roughness*Roughness, NoL) / 4; - float omegaS = 1.0 / (TNbOfSamples * pdf); - float omegaP = 4.0 * Math.PI / (6.0 * RadianceMapSize * RadianceMapSize) ; - float mipLevel = clamp(0.5 * log2(omegaS / omegaP) , 0, MipmapCount); - - float3 prefilteredColor = 0; - float weight = 0; - if (NoL > 0) - { - weight = NoL; - prefilteredColor = RadianceMap.SampleLevel(Texturing.LinearSampler, L, mipLevel).rgb * weight; - } - - // Stock the result in group-shared memory - prefilteredSample += float4(prefilteredColor, weight); - } - - return prefilteredSample / prefilteredSample.w; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl b/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl deleted file mode 100644 index 56e5d490a3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/RadiancePrefilteringGGXShader.sdsl +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Shader performing radiance GGX pre-filtering - /// - shader RadiancePrefilteringGGXShader : Math, ComputeShaderBase - { - // the input texture containing the radiance - int RadianceMapSize; - TextureCube RadianceMap; - - // the output cube map containing the filtered radiance. - RWTexture2DArray FilteredRadiance; - - // Shared memory for summing SH-Basis coefficients for a block - groupshared float4 PrefilteredSamples[TNbOfSamples]; - - // The number of mipmap available - stage float MipmapCount; - - // The roughness of the GGX distribution - stage float Roughness; - - // compute the pre-filtered environment map for input (group) direction - override void Compute() - { - int2 pixel = streams.GroupId.xy; - int face = streams.GroupId.z; - int threadId = streams.GroupThreadId.x; - - // Calculate the uv of the pixel in [0, 1] - float u = (pixel.x + 0.5) / float(streams.ThreadGroupCount.x); - float v = (pixel.y + 0.5) / float(streams.ThreadGroupCount.y); - - // Calculate the direction of the texel in the cubemap - float3 R = normalize(CubemapUtils.ConvertTexcoordsNoFlip(float2(u, v), face)); - - // Perform one sampling, calculate pre-filtered color and weight contribution - var xi = Hammersley.GetSamplePlane(threadId, TNbOfSamples); - var H = ImportanceSamplingGGX.GetSample(xi, Roughness, R); - - float3 L = 2 * dot( R, H ) * H - R; - float NoL = saturate( dot( R, L ) ); - float pdf = BRDFMicrofacet.NormalDistributionGGX(Roughness*Roughness, NoL) / 4; - float omegaS = 1.0 / ( TNbOfSamples * pdf ); - float omegaP = 4.0 * Math.PI / (6.0 * RadianceMapSize * RadianceMapSize ) ; - float mipLevel = clamp (0.5 * log2 ( omegaS / omegaP ) , 0, MipmapCount ); - - float3 prefilteredColor = 0; - float weight = 0; - if( NoL > 0 ) - { - weight = NoL; - prefilteredColor = RadianceMap.SampleLevel(Texturing.LinearSampler, L, mipLevel).rgb * weight; - } - - // Stock the result in group-shared memory - PrefilteredSamples[threadId] = float4(prefilteredColor, weight); - GroupMemoryBarrierWithGroupSync(); - - // Perform the sums among the group - for(int s = TNbOfSamples / 2; s > 0; s >>= 1) - { - if(threadId < s) - PrefilteredSamples[threadId] += PrefilteredSamples[threadId + s]; - - GroupMemoryBarrierWithGroupSync(); - } - - // Let the first thread stock the final result in output texture - if(IsFirstThreadOfGroup()) - { - FilteredRadiance[float3(pixel.xy, face)] = PrefilteredSamples[0] / PrefilteredSamples[0].w; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/RangeCompressorShader.sdsl b/sources/shaders/assets/Stride/SDSL/RangeCompressorShader.sdsl deleted file mode 100644 index 0a75198290..0000000000 --- a/sources/shaders/assets/Stride/SDSL/RangeCompressorShader.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - shader RangeCompressorShader : ImageEffectShader - { - stage override float4 Shading() - { - float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - - // compute luma from HDR value: - float3 ntsc = float3(0.2126, 0.7152, 0.0722); - float relativeLuminance = dot(ntsc, color); - float perceptiveLuma = sqrt(relativeLuminance); - - // tone to "non-lossy" LDR: - float targetRange = 1.0; - float maxComponent = max(max(color.r, color.g), color.b); - // http://graphicrants.blogspot.jp/2013/12/tone-mapping.html - float3 brianKarisToned = color / (1 + maxComponent / targetRange); - - float3 mapped = brianKarisToned; - // and we don't apply gamma. because of big outlining artefact around [0-1] range objects in front of high [10-80] range emissive objects. - - // write output for FXAA: - return float4(mapped, perceptiveLuma); - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/RangeDecompressorShader.sdsl b/sources/shaders/assets/Stride/SDSL/RangeDecompressorShader.sdsl deleted file mode 100644 index 44bc993275..0000000000 --- a/sources/shaders/assets/Stride/SDSL/RangeDecompressorShader.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - shader RangeDecompressorShader : ImageEffectShader - { - stage override float4 Shading() - { - float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - - float3 linearColor = color; - - // reverse karis tone map: - float targetRange = 1.0; - float maxComponent = max(max(linearColor.r, linearColor.g), linearColor.b); - float3 reverseKaris = linearColor / (1 - maxComponent / targetRange); - - // write output for the rest of the post effects: - return float4(reverseKaris, 1.0); - } - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl b/sources/shaders/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl deleted file mode 100644 index 51f48836cb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/RoughnessCubeMapEnvironmentColor.sdsl +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - /// - /// Sample a cubemap using the MaterialPixelShadingStream roughness parameter. - /// - shader RoughnessCubeMapEnvironmentColor : IComputeEnvironmentColor, Texturing, MaterialPixelShadingStream - { - cbuffer PerView.Lighting - { - float MipCount; - } - - rgroup PerView.Lighting - { - TextureCube CubeMap; - } - - override float4 Compute(float3 direction) - { - var alpha = streams.alphaRoughness; - var mipLevel = sqrt(alpha) * MipCount; - - return CubeMap.SampleLevel(LinearSampler, direction, mipLevel); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SSLRBlurPass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRBlurPass.sdsl deleted file mode 100644 index fdac658863..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRBlurPass.sdsl +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Blur Pass - /// - shader SSLRBlurPass : ImageEffectShader - { - // Options: - // 3 - 5-tap blur - // 5 - 9-tap blur - #define SSR_BLUR_STEPS 3 - - override stage float4 Shading() - { - #if CONVOLVE_VERTICAL - const float2 offsets[SSR_BLUR_STEPS] = { - #if SSR_BLUR_STEPS == 3 - {0, 0}, - {1.3846153846, 0}, - {3.2307692308, 0} - #elif SSR_BLUR_STEPS == 5 - {0, 0}, - {1, 0}, - {2, 0}, - {3, 0}, - {4, 0} - #endif - }; - #else - const float2 offsets[SSR_BLUR_STEPS] = { - #if SSR_BLUR_STEPS == 3 - {0, 0}, - {0, 1.3846153846}, - {0, 3.2307692308} - #elif SSR_BLUR_STEPS == 5 - {0, 0}, - {0, 1}, - {0, 2}, - {0, 3}, - {0, 4} - #endif - }; - #endif - const float weights[SSR_BLUR_STEPS] = { - #if SSR_BLUR_STEPS == 3 - 0.2270270270, - 0.3162162162, - 0.0702702703 - #elif SSR_BLUR_STEPS == 5 - 0.2270270270, - 0.1945945946, - 0.1216216216, - 0.0540540541, - 0.0162162162 - #endif - }; - - float3 color = Texture0.Sample(LinearSampler, streams.TexCoord).rgb * weights[0]; - - for (int i = 1; i < SSR_BLUR_STEPS; i++) - { - float2 texCoordOffset = offsets[i] * Texture0TexelSize; - - color += (Texture0.Sample(LinearSampler, streams.TexCoord + texCoordOffset).rgb - + Texture0.Sample(LinearSampler, streams.TexCoord - texCoordOffset).rgb) - * weights[i]; - } - - return float4(color, 1.0f); - } - }; - - effect SSLRBlurPassEffectH - { - mixin macro CONVOLVE_VERTICAL = 0; - mixin SSLRBlurPass; - }; - - effect SSLRBlurPassEffectV - { - mixin macro CONVOLVE_VERTICAL = 1; - mixin SSLRBlurPass; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SSLRCombinePass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRCombinePass.sdsl deleted file mode 100644 index 9cb48d6731..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRCombinePass.sdsl +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Combine Pass - /// - shader SSLRCombinePass : ImageEffectShader, SSLRCommon, Utilities - { - // Enable/disable blurring SSR during sampling results and mixing with reflections buffer - #define SSR_MIX_BLUR 1 - - float3 SampleSSR(float2 uv) - { - float4 ssr = Texture4.SampleLevel(LinearSampler, uv, 0); - - #if SSR_MIX_BLUR - ssr += Texture4.SampleLevel(LinearSampler, uv + float2(0, Texture4TexelSize.y), 0); - ssr += Texture4.SampleLevel(LinearSampler, uv - float2(0, Texture4TexelSize.y), 0); - ssr += Texture4.SampleLevel(LinearSampler, uv + float2(Texture4TexelSize.x, 0), 0); - ssr += Texture4.SampleLevel(LinearSampler, uv - float2(Texture4TexelSize.x, 0), 0); - ssr *= (1.0f / 5.0f); - #endif - - return ssr; - } - - // [Lazarov 2013, "Getting More Physical in Call of Duty: Black Ops II"] - float3 EnvBRDFApprox(float3 specularColor, float roughness, float NoV) - { - // Approximate version, base for pre integrated version - const half4 c0 = {-1, -0.0275, -0.572, 0.022}; - const half4 c1 = {1, 0.0425, 1.04, -0.04}; - half4 r = roughness * c0 + c1; - half a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y; - half2 AB = half2(-1.04, 1.04) * a004 + r.zw; - return specularColor * AB.x + saturate(50.0 * specularColor.g) * AB.y; - } - - override stage float4 Shading() - { - // Inputs Mapping: - // Texture0 - Scene Color - // Texture1 - Depth - // Texture2 - World Space Normals - // Texture3 - Specular Color + Roughness - // Texture4 - Reflections result - - float2 uv = streams.TexCoord; - - // Sample inputs - float4 sceneColor = Texture0.SampleLevel(PointSampler, uv, 0); - float3 ssr = SampleSSR(uv); - float3 positionWS = ComputeWorldPosition(uv); - - // Calculate view space normal vector - float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); - float3 normalWS = DecodeNormal(normalsBuffer.rgb); - float3 normalVS = mul(normalWS, (float3x3)V); - - // Sample material specular color and roughness - float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); - float3 specularColor = specularRoughnessBuffer.rgb; - float roughness = specularRoughnessBuffer.a; - - // Calculate reflection color - float3 viewVector = normalize(CameraPosWS.xyz - positionWS); - float NoV = saturate(dot(normalWS, viewVector)); - sceneColor.rgb += ssr * EnvBRDFApprox(specularColor, roughness, NoV); - - return sceneColor; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SSLRCommon.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRCommon.sdsl deleted file mode 100644 index 5ea5442a4e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRCommon.sdsl +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader with common variables and functions - /// - shader SSLRCommon : ImageEffectShader, Utilities, NormalPack - { - cbuffer Data - { - stage float MaxColorMiplevel; - stage float TraceSizeMax; - stage float MaxTraceSamples; - //stage float Padding0; - - stage float RoughnessFade; - stage float TemporalTime; - stage float BRDFBias; - stage float ViewFarPlane; - - stage float4 ViewInfo; - - stage float3 CameraPosWS; - stage float WorldAntiSelfOcclusionBias; - - stage float4x4 V; - stage float4x4 IVP; - }; - - // Sample raw device depth buffer - float SampleZ(in float2 uv) - { - return Texture1.SampleLevel(PointSampler, uv, 0).r; - } - - // Linearize raw device depth - float LinearizeZ(in float depth) - { - return ViewInfo.w / (depth - ViewInfo.z); - } - - // Sample linear depth - float SampleDepth(in float2 uv) - { - float depth = SampleZ(uv); - return LinearizeZ(depth); - } - - // 1:-1 to 0:1 - float2 ClipToUv(float2 clipPos) - { - return clipPos * float2(0.5, -0.5) + float2(0.5, 0.5); - } - - // 0:1 to 1:-1 - float2 UvToClip(float2 uv) - { - return uv * float2(2, -2) + float2(-1, 1); - } - - float3 ComputeWorldPosition(float2 uv, float rawDepth) - { - float4 clipPos = float4(UvToClip(uv), rawDepth, 1); - float4 pos = mul(clipPos, IVP); - return pos.xyz / pos.w; - } - - float3 ComputeWorldPosition(float2 uv) - { - float rawDepth = SampleZ(uv); - return ComputeWorldPosition(uv, rawDepth); - } - - float3 ComputeViewPosition(float2 uv, float rawDepth) - { - float eyeZ = LinearizeZ(rawDepth) * ViewFarPlane; - return float3(UvToClip(uv) * ViewInfo.xy * eyeZ, eyeZ); - } - - float3 SampleViewPosition(float2 uv) - { - float rawDepth = SampleZ(uv); - return ComputeViewPosition(uv, rawDepth); - } - - float3 ScreenToView(float2 uv, float depth) - { - return float3(UvToClip(uv) * ViewInfo.xy, depth); - } - - float max2(float2 v) - { - return max(v.x, v.y); - } - - float2 RandN2(float2 pos, float2 random) - { - return frac(sin(dot(pos.xy + random, float2(12.9898, 78.233))) * float2(43758.5453, 28001.8384)); - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/SSLRDepthPass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRDepthPass.sdsl deleted file mode 100644 index 61437a16ee..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRDepthPass.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Depth Pass - /// - shader SSLRDepthPass : ImageEffectShader - { - override stage float4 Shading() - { - float depth = Texture0.Sample(PointSampler, streams.TexCoord).r; - return depth.xxxx; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SSLRRayTracePass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRRayTracePass.sdsl deleted file mode 100644 index 3c9bb44b55..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRRayTracePass.sdsl +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Ray Trace Pass - /// - shader SSLRRayTracePass : ImageEffectShader, SSLRCommon, NormalPack, Math - { - cbuffer Data - { - stage float EdgeFadeFactor; - - stage float4x4 VP; - }; - - // go into clip space (-1:1 from bottom/left to up/right) - float3 ProjectWorldToClip(float3 wsPos) - { - float4 uv = mul(float4(wsPos, 1), VP); - uv /= uv.w; - return uv.xyz; - } - - // go into UV space. (0:1 from top/left to bottom/right) - float3 ProjectWorldToUv(float3 wsPos) - { - float3 pos = ProjectWorldToClip(wsPos); - return float3(ClipToUv(pos.xy), pos.z); - } - - float4 TangentToWorld(float3 N, float4 H) - { - float3 UpVector = abs(N.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); - float3 T = normalize( cross( UpVector, N ) ); - float3 B = cross( N, T ); - - return float4((T * H.x) + (B * H.y) + (N * H.z), H.w); - } - - // Brian Karis, Epic Games "Real Shading in Unreal Engine 4" - float4 ImportanceSampleGGX(float2 Xi, float Roughness) - { - float m = Roughness * Roughness; - float m2 = m * m; - - float Phi = 2 * PI * Xi.x; - - float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (m2 - 1.0) * Xi.y)); - float SinTheta = sqrt(max(1e-5, 1.0 - CosTheta * CosTheta)); - - float3 H; - H.x = SinTheta * cos(Phi); - H.y = SinTheta * sin(Phi); - H.z = CosTheta; - - float d = (CosTheta * m2 - CosTheta) * CosTheta + 1; - float D = m2 / (PI * d * d); - float pdf = D * CosTheta; - - return float4(H, pdf); - } - - float RayAttenBorder(float2 pos, float value) - { - float borderDist = min(1.0 - max(pos.x, pos.y), min(pos.x, pos.y)); - return saturate(borderDist > value ? 1.0 : borderDist / value); - } - - override stage float4 Shading() - { - // Inputs Mapping: - // Texture0 - Scene Color - // Texture1 - Depth - // Texture2 - World Space Normals - // Texture3 - Specular Color + Roughness - - float2 uv = streams.TexCoord; - - // Sample material roughness - float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); - float roughness = specularRoughnessBuffer.a; - - // Get view space position - float depth = SampleZ(uv); - float3 positionVS = ComputeViewPosition(uv, depth); - - // Reject invalid pixels - if(positionVS.z > 100.0f || roughness > RoughnessFade) - return 0; - - // Calculate view space normal vector - float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); - float3 normalWS = DecodeNormal(normalsBuffer.rgb); - float3 normalVS = mul(normalWS, (float3x3)V); - - // Randomize it a little - float2 jitter = RandN2(uv, TemporalTime); - float2 Xi = jitter; - Xi.y = lerp(Xi.y, 0.0, BRDFBias); - - float4 H = TangentToWorld(normalWS, ImportanceSampleGGX(Xi, roughness)); - - // Calculate normalized view space reflection vector - float3 reflectVS = normalize(reflect(positionVS, normalVS)); - - if(positionVS.z < 1.0 && reflectVS.z < 0.4) - return 0; - - float3 positionWS = ComputeWorldPosition(uv, depth); - float3 viewWS = normalize(positionWS - CameraPosWS.xyz); - float3 reflectWS = reflect(viewWS, H.xyz); - - float3 startWS = positionWS + normalWS * WorldAntiSelfOcclusionBias; - float3 startUV = ProjectWorldToUv(startWS); - float3 endUV = ProjectWorldToUv(startWS + reflectWS); - - float3 rayUV = endUV - startUV; - float screenStep = Texture1TexelSize.x; - rayUV *= screenStep / max2(abs(rayUV.xy)); - float3 startUv = startUV + rayUV * 2; - - float3 currOffset = startUv; - float3 rayStep = rayUV * 2; - - // Calculate number of samples - float3 samplesToEdge = ((sign(rayStep.xyz) * 0.5 + 0.5) - currOffset.xyz) / rayStep.xyz; - samplesToEdge.x = min(samplesToEdge.x, min(samplesToEdge.y, samplesToEdge.z)) * 1.05f; - float numSamples = min(MaxTraceSamples, samplesToEdge.x); - rayStep *= samplesToEdge.x / numSamples; - - // Calculate depth diffrence error - float depthDiffError = 1.3f * abs(rayStep.z); - - // Ray trace - float currSampleIndex = 0; - float currSample, depthDiff; - [loop] - while (currSampleIndex < numSamples) - { - // Sample depth buffer and calculate depth diffrence - currSample = SampleZ(currOffset.xy); - depthDiff = currOffset.z - currSample; - - // Check intersection - if(depthDiff >= 0) - { - if (depthDiff < depthDiffError) - { - break; - } - else - { - currOffset -= rayStep; - rayStep *= 0.5; - } - } - - // Move forward - currOffset += rayStep; - currSampleIndex++; - } - - // Check if has valid result after ray traycing - if(currSampleIndex >= numSamples || currOffset.z > 0.999) - { - // All samples done but no result - return 0; - } - - float2 hitUV = currOffset.xy; - - // Fade rays close to screen edge - const float fadeStart = 0.9f; - const float fadeEnd = 1.0f; - const float fadeDiffRcp = 1.0f / (fadeEnd - fadeStart); - float2 boundary = abs(hitUV - float2(0.5f, 0.5f)) * 2.0f; - float fadeOnBorder = 1.0f - saturate((boundary.x - fadeStart) * fadeDiffRcp); - fadeOnBorder *= 1.0f - saturate((boundary.y - fadeStart) * fadeDiffRcp); - fadeOnBorder = smoothstep(0.0f, 1.0f, fadeOnBorder); - fadeOnBorder *= RayAttenBorder(hitUV, EdgeFadeFactor); - - // Fade rays on high roughness - float roughnessFade = saturate((RoughnessFade - roughness) * 20); - - // Output: xy: hitUV, z: hitMask, w: unused - return float4(hitUV, fadeOnBorder * roughnessFade, 0); - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/SSLRResolvePass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRResolvePass.sdsl deleted file mode 100644 index 9218b2839e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRResolvePass.sdsl +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Resolve Pass - /// - shader SSLRResolvePass : ImageEffectShader, SSLRCommon, NormalPack, Math, BRDFMicrofacet - { - static const float2 Offsets[8] = - { - float2( 0, 0), - float2( 2, -2), - float2(-2, -2), - float2( 0, 2), - float2(-2, 0), - float2( 0, -2), - float2( 2, 0), - float2( 2, 2), - }; - - override stage float4 Shading() - { - // Inputs Mapping: - // Texture0 - Scene Color (with blurred mip maps chain or without) - // Texture1 - Depth - // Texture2 - World Space Normals - // Texture3 - Specular Color + Roughness - // Texture4 - Ray Trace result - - float2 uv = streams.TexCoord; - - // Early out for pixels with no hit result - if(Texture4.SampleLevel(LinearSampler, uv, 0).z <= 0.001) - return 0; - - // Sample material roughness - float4 specularRoughnessBuffer = Texture3.SampleLevel(PointSampler, uv, 0); - float roughness = specularRoughnessBuffer.a; - - // Get view space position - float depth = SampleZ(uv); - float3 positionVS = ComputeViewPosition(uv, depth); - - // Reject invalid pixels - if(positionVS.z > 100.0f || roughness > RoughnessFade) - return 0; - - // Calculate view space normal vector - float4 normalsBuffer = Texture2.SampleLevel(PointSampler, uv, 0); - float3 normalWS = DecodeNormal(normalsBuffer.rgb); - - // Calculate view vector - float3 positionWS = ComputeWorldPosition(uv, depth); - float3 viewVector = normalize(CameraPosWS.xyz - positionWS); - - // Randomize it a little - float2 random = RandN2(uv, TemporalTime); - float2 blueNoise = random.xy * 2.0 - 1.0; - float2x2 offsetRotationMatrix = float2x2(blueNoise.x, blueNoise.y, -blueNoise.y, blueNoise.x); - - float NdotV = saturate(dot(normalWS, viewVector)); - float coneTangent = lerp(0.0, roughness * 5 * (1.0 - BRDFBias), pow(NdotV, 1.5) * sqrt(roughness)); - - // Resolve samples - float4 result = 0.0; - for(int i = 0; i < ResolveSamples; i++) - { - float2 offsetUV = Offsets[i] * Texture4TexelSize; - offsetUV = mul(offsetRotationMatrix, offsetUV); - - // "uv" is the location of the current (or "local") pixel. We want to resolve the local pixel using - // intersections spawned from neighboring pixels. The neighboring pixel is this one: - float2 neighborUv = uv + offsetUV; - - // Now we fetch the intersection point - float4 hitPacked = Texture4.SampleLevel(LinearSampler, neighborUv, 0); - float2 hitUv = hitPacked.xy; - float hitMask = hitPacked.z; - - float intersectionCircleRadius = coneTangent * length(hitUv - uv); - float mip = clamp(log2(intersectionCircleRadius * TraceSizeMax), 0.0, MaxColorMiplevel); - - float4 sampleColor = float4(Texture0.SampleLevel(LinearSampler, hitUv, mip).rgb, 1); - if(ReduceHighlights) - sampleColor.rgb /= 1 + Luminance(sampleColor.rgb); - - result += sampleColor * hitMask; - } - - // Calculate final result value - result /= ResolveSamples; - if(ReduceHighlights) - result.rgb /= 1 - Luminance(result.rgb); - result.rgb *= result.a; - - return max(1e-5, result); - } - }; - - effect SSLRResolvePassEffect - { - using params SSLRKeys; - - mixin SSLRResolvePass; - } -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/SSLRTemporalPass.sdsl b/sources/shaders/assets/Stride/SDSL/SSLRTemporalPass.sdsl deleted file mode 100644 index dc1f203315..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SSLRTemporalPass.sdsl +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Screen Space Local Reflections shader for Temporal Pass - /// - shader SSLRTemporalPass : ImageEffectShader, Texturing - { - stage float TemporalResponse; - stage float TemporalScale; - stage float4x4 IVP; // Current frame inverse view*projection matrix - stage float4x4 prevVP; // Previous frame view*projection matrix - - // 1:-1 to 0:1 - float2 ClipToUv(float2 clipPos) - { - return clipPos * float2(0.5, -0.5) + float2(0.5, 0.5); - } - - // 0:1 to 1:-1 - float2 UvToClip(float2 uv) - { - return uv * float2(2, -2) + float2(-1, 1); - } - - float3 ComputeWorldPosition(float2 uv, float rawDepth) - { - float4 clipPos = float4(UvToClip(uv), rawDepth, 1); - float4 pos = mul(clipPos, IVP); - return pos.xyz / pos.w; - } - - float3 SampleWorldPosition(float2 uv) - { - float rawDepth = Texture2.SampleLevel(PointSampler, uv, 0).r; - return ComputeWorldPosition(uv, rawDepth); - } - - override stage float4 Shading() - { - // Inputs Mapping: - // Texture0 - Resolved reflections - // Texture1 - Previous frame resolved reflections - // Texture2 - Depth - - float2 uv = streams.TexCoord; - - // Reconstruct previous frame screen space position - float3 posWS = SampleWorldPosition(uv); - float4 prevSS = mul(float4(posWS, 1), prevVP); - prevSS.xy /= prevSS.w; - - float2 prevUV = ClipToUv(prevSS.xy); - - float4 current = Texture0.SampleLevel(LinearSampler, uv, 0); - float4 previous = Texture1.SampleLevel(LinearSampler, prevUV, 0); - - float2 du = float2(Texture0TexelSize.x, 0.0); - float2 dv = float2(0.0, Texture0TexelSize.y); - - float4 currentTopLeft = Texture0.SampleLevel(LinearSampler, uv.xy - dv - du, 0); - float4 currentTopCenter = Texture0.SampleLevel(LinearSampler, uv.xy - dv, 0); - float4 currentTopRight = Texture0.SampleLevel(LinearSampler, uv.xy - dv + du, 0); - float4 currentMiddleLeft = Texture0.SampleLevel(LinearSampler, uv.xy - du, 0); - float4 currentMiddleCenter = Texture0.SampleLevel(LinearSampler, uv.xy, 0); - float4 currentMiddleRight = Texture0.SampleLevel(LinearSampler, uv.xy + du, 0); - float4 currentBottomLeft = Texture0.SampleLevel(LinearSampler, uv.xy + dv - du, 0); - float4 currentBottomCenter = Texture0.SampleLevel(LinearSampler, uv.xy + dv, 0); - float4 currentBottomRight = Texture0.SampleLevel(LinearSampler, uv.xy + dv + du, 0); - - float4 currentMin = min(currentTopLeft, min(currentTopCenter, min(currentTopRight, min(currentMiddleLeft, min(currentMiddleCenter, min(currentMiddleRight, min(currentBottomLeft, min(currentBottomCenter, currentBottomRight)))))))); - float4 currentMax = max(currentTopLeft, max(currentTopCenter, max(currentTopRight, max(currentMiddleLeft, max(currentMiddleCenter, max(currentMiddleRight, max(currentBottomLeft, max(currentBottomCenter, currentBottomRight)))))))); - - float scale = TemporalScale; - - float4 center = (currentMin + currentMax) * 0.5f; - currentMin = (currentMin - center) * scale + center; - currentMax = (currentMax - center) * scale + center; - - previous = clamp(previous, currentMin, currentMax); - - return lerp(current, previous, TemporalResponse); - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/ScreenPositionBase.sdsl b/sources/shaders/assets/Stride/SDSL/ScreenPositionBase.sdsl deleted file mode 100644 index a239e4b8d3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ScreenPositionBase.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Declares and sets the value of the screen position of the fragment ({x,y} in [-1,1], z in [0,1]). -/// Be careful when to include this shader because ShadingPosition should be correct at this point. Include this shader at the end of the mixin list. -/// -shader ScreenPositionBase : ShaderBase -{ - // The position in screen space - stage stream float4 ScreenPosition; - - stage override void VSMain() - { - base.VSMain(); - streams.ScreenPosition = streams.ShadingPosition; - } - - stage override void PSMain() - { - streams.ScreenPosition /= streams.ScreenPosition.w; - base.PSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SelectedSpriteShader.sdsl b/sources/shaders/assets/Stride/SDSL/SelectedSpriteShader.sdsl deleted file mode 100644 index 4db2057edb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SelectedSpriteShader.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SelectedSpriteShader : SpriteBase -{ - float Blend; - - // method computing color - stage override float4 Shading() - { - float factor = fmod(streams.ShadingPosition.x, 2) * fmod(streams.ShadingPosition.y, 2); - float4 selectionColor = float4(0.0f, 0.5f, 1, 1); - float4 baseColor = base.Shading(); - - return lerp(baseColor, selectionColor, factor * Blend * Blend * baseColor.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SemanticTest.sdsl b/sources/shaders/assets/Stride/SDSL/SemanticTest.sdsl deleted file mode 100644 index a6097376aa..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SemanticTest.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SemanticTest -{ - cbuffer PerFrame - { - float sem0 : POSITION; - float sem1 : POSITION; - } - - float test() - { - return sem0 + sem1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ShaderBase.sdsl b/sources/shaders/assets/Stride/SDSL/ShaderBase.sdsl deleted file mode 100644 index 4ade27f5c5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShaderBase.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -// Base shader for all the graphics shaders -shader ShaderBase : ShaderBaseStream -{ - // Declare Vertex shader main method - stage void VSMain() {} - - // Declare Pixel shader main method - stage void PSMain() {} -}; diff --git a/sources/shaders/assets/Stride/SDSL/ShaderBaseStream.sdsl b/sources/shaders/assets/Stride/SDSL/ShaderBaseStream.sdsl deleted file mode 100644 index cce58432bf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShaderBaseStream.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// Base stream for a shader -shader ShaderBaseStream -{ - // Default SV_POSITION output for VS/GS shaders - stage stream float4 ShadingPosition : SV_Position; - -#if STRIDE_GRAPHICS_API_DIRECT3D && STRIDE_GRAPHICS_PROFILE < GRAPHICS_PROFILE_LEVEL_10_0 - // Positive if this face is a front face, negative otherwise - stage stream float IsFrontFace : VFACE; -#else - // True if this face is a front face - stage stream bool IsFrontFace : SV_IsFrontFace; -#endif - - // Default COLOR outputs for PS shader - stage stream float4 ColorTarget : SV_Target0; - stage stream float4 ColorTarget1 : SV_Target1; - stage stream float4 ColorTarget2 : SV_Target2; - stage stream float4 ColorTarget3 : SV_Target3; - stage stream float4 ColorTarget4 : SV_Target4; - stage stream float4 ColorTarget5 : SV_Target5; - stage stream float4 ColorTarget6 : SV_Target6; - stage stream float4 ColorTarget7 : SV_Target7; - - // Default DEPTH output for PS shader - stage stream float Depth : SV_Depth; - stage stream float DepthGreater : SV_DepthGreater; // Special output after PS - stage stream float DepthLessEqual : SV_DepthLessEqual; // Special output after PS - - // Default InstanceId for VS/GS shaders - stage stream uint InstanceID : SV_InstanceID; -}; diff --git a/sources/shaders/assets/Stride/SDSL/ShadingBase.sdsl b/sources/shaders/assets/Stride/SDSL/ShadingBase.sdsl deleted file mode 100644 index 58690f735b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadingBase.sdsl +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Base shader to perfom shading. Defines the basic method and inserts it in the pipeline. -/// -/// -/// STRIDE_RENDER_TARGET_COUNT: Macro - Number of render targets. -/// - -#ifndef STRIDE_RENDER_TARGET_COUNT -# define STRIDE_RENDER_TARGET_COUNT 1 -#endif - -shader ShadingBase : ShaderBase -{ - compose ComputeColor ShadingColor0; - -#if STRIDE_RENDER_TARGET_COUNT > 1 - compose ComputeColor ShadingColor1; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 2 - compose ComputeColor ShadingColor2; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 3 - compose ComputeColor ShadingColor3; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 4 - compose ComputeColor ShadingColor4; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 5 - compose ComputeColor ShadingColor5; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 6 - compose ComputeColor ShadingColor6; -#endif -#if STRIDE_RENDER_TARGET_COUNT > 7 - compose ComputeColor ShadingColor7; -#endif - - // method computing color - stage float4 Shading() - { - return ShadingColor0.Compute(); - } - - stage override void PSMain() - { - base.PSMain(); - streams.ColorTarget = this.Shading(); - -#if STRIDE_RENDER_TARGET_COUNT > 1 - streams.ColorTarget1 = ShadingColor1.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 2 - streams.ColorTarget2 = ShadingColor2.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 3 - streams.ColorTarget3 = ShadingColor3.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 4 - streams.ColorTarget4 = ShadingColor4.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 5 - streams.ColorTarget5 = ShadingColor5.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 6 - streams.ColorTarget6 = ShadingColor6.Compute(); -#endif -#if STRIDE_RENDER_TARGET_COUNT > 7 - streams.ColorTarget7 = ShadingColor7.Compute(); -#endif - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ShadingColor.sdsl b/sources/shaders/assets/Stride/SDSL/ShadingColor.sdsl deleted file mode 100644 index 42ca52d9c1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadingColor.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Class outputing color from a single ComputeColor and overriding any previous color computations. -/// -shader ShadingColor : ShaderBase -{ - compose ComputeColor Color; - - override void PSMain() - { - base.PSMain(); - streams.ColorTarget = Color.Compute(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ShadowGroup.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowGroup.sdsl deleted file mode 100644 index 0e47664834..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowGroup.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Defines the methods to compute shadowing and the sampler used on the shadow map. - /// - shader ShadowGroup : ShadowStream - { - // Computes the shadow for a given world position and light index - float3 ComputeShadow(float3 position, int lightIndex) - { - streams.thicknessWS = 0.0; // No thickness - return 1.0f; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl deleted file mode 100644 index e9186ce9cd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDiscard.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Shadow map caster with pixel shader performing alpha discard test. - /// - shader ShadowMapCasterAlphaDiscard : Transformation, ShaderBase, PositionStream, MaterialPixelStream - { - override stage void PSMain() - { - base.PSMain(); - - clip(streams.ColorTarget.a - streams.matAlphaDiscard); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl deleted file mode 100644 index f17f58ea6e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterAlphaDithered.sdsl +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Shadow map caster with pixel shader performing a dithered alpha discard test. - /// - shader ShadowMapCasterAlphaDithered : Transformation, ShaderBase, PositionStream, MaterialPixelStream - { - static const float BayerMatrix[16] = - { - 0, - 0.53333336, - 0.13333334, - 0.6666667, - 0.8, - 0.26666668, - 0.9333333, - 0.4, - 0.2, - 0.73333335, - 0.06666667, - 0.6, - 1, - 0.4666667, - 0.8666667, - 0.33333334, - }; - - override stage void PSMain() - { - base.PSMain(); - - int2 coord = int2(streams.ShadingPosition.xy % 4.0); - float bayer = BayerMatrix[coord.x+coord.y*4]; - clip( -1.01 + bayer + streams.ColorTarget.a * 1.01 ); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl deleted file mode 100644 index c83ccadeff..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterCubeMapProjection.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Shadows -{ - shader ShadowMapCasterCubeMapProjection : TransformationBase, PositionStream4, Texturing - { - stage override void PostTransformPosition() - { - streams.ShadingPosition = ComputeShadingPosition(streams.PositionWS); - } - - stage override float4 ComputeShadingPosition(float4 world) - { - return mul(world, Transformation.ViewProjection); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl deleted file mode 100644 index 05cd47a7ea..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterNoPixelShader.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Shadow map caster without pixel shader color outputs (only depth). - /// - shader ShadowMapCasterNoPixelShader : Transformation, ShaderBase, PositionStream - { - override stage void PSMain() - { - // no code = null pixel shader, as we are outputing depth only - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl deleted file mode 100644 index 1519eacf6d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterParaboloidProjection.sdsl +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Shadows -{ - shader ShadowMapCasterParaboloidProjection : TransformationBase, PositionStream4, Texturing - { - static const float ClippingEpsilon = 0.03; - - cbuffer PerView.ShadowCaster - { - // x = Near; y = 1/(Far-Near) - float2 DepthParameters; - } - - // Used to write the distance from an object to the light to the depth buffer - stage stream float PixelDepth : SV_DEPTH; - - stage override void PostTransformPosition() - { - streams.ShadingPosition = ComputeParaboloidProjection(streams.PositionWS, streams.DepthVS); - } - - stage override float4 ComputeShadingPosition(float4 world) - { - float dummy; - return ComputeParaboloidProjection(world, dummy); - } - - float4 ComputeParaboloidProjection(float4 world, out float depth) - { - // Project into light view space - float4 lightSpace = mul(world, Transformation.View); - - // Store length and normalize - float distanceToLight = length(lightSpace.xyz); - float3 intermediate = lightSpace.xyz / distanceToLight; - - // Project x/y coordinates on parabola - intermediate.xy /= 1.0f+intermediate.z; - - // 2 different depth values - // The first one is the depth written to the depth buffer (always positive, since it is the distance to the point light) - // The second one is used for clipping (world space along the light's z-axis) - float2 depthValues = float2(distanceToLight, lightSpace.z + ClippingEpsilon) * DepthParameters.y; - - // Send projected depth to pixel shader - depth = depthValues.x; - - return float4(intermediate.xy, depthValues.y, 1); - } - - stage override void PSMain() - { - base.PSMain(); - - streams.PixelDepth = streams.DepthVS; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl deleted file mode 100644 index 356b71c7ce..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCasterVsm.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Creates shadow map for variance shadow mapping. - /// - shader ShadowMapCasterVsm : ShadowMapCasterBase - { - /// -------------------------------------------------------------------------------- - /// Pixel Shader - /// -------------------------------------------------------------------------------- - override stage void PSMain() - { - float depth = streams.ShadingPosition.z; - - // Compute partial derivatives of depth. - float dx = ddx(depth); - float dy = ddy(depth); - // Compute second moment over the pixel extents. - streams.ColorTarget = float4(depth, depth * depth + 0.25*(dx*dx + dy*dy), 0, 0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapCommon.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapCommon.sdsl deleted file mode 100644 index e4e27d31b8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapCommon.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Defines the textures used for shadow mapping. - /// - shader ShadowMapCommon - { - rgroup PerLighting - { - [Link("ShadowMap.ShadowMapTexture")] - Texture2D ShadowMapTexture; - } - - cbuffer PerLighting - { - [Link("ShadowMap.TextureSize")] - float2 ShadowMapTextureSize; - - [Link("ShadowMap.TextureTexelSize")] - float2 ShadowMapTextureTexelSize; - // TODO: We could have different types (Texture2DArray for optimized paths, TextureCube for omni...etc.) - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterBase.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapFilterBase.sdsl deleted file mode 100644 index e407b7ab55..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterBase.sdsl +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Defines shadow filtering method. - /// - shader ShadowMapFilterBase : ShadowMapCommon, Texturing, Math - { - /// - /// Calculate the shadow factor based on the position and shadow map distance. - /// - abstract float FilterShadow(float2 position, float positionDepth); - - /// - /// Used to calculate offsetted shadow map and world space pixel coordinates, - /// in order to mitigate shadow mapping artifacts for thickness calculation. - /// - void CalculateAdjustedShadowSpacePixelPosition(float filterRadiusInPixels, // The radius of the sampling kernel in texture space. - float3 pixelPositionWS, - float3 meshNormalWS, - float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. - float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. - out float3 adjustedPixelPositionWS, - out float3 adjustedPixelPositionShadowSpace) - { - // TODO: PERFORMANCE: The offset length can be calculated once for for each directional light on the CPU. For perspective shadows, this is a bit more complex. - // TODO: PERFORMANCE: Can we do the offset in shadow map space (by projecting the normal vector)? - - float4 bottomLeftTexelWS = Project(float4(0.0, 0.0, 0.0, 1.0), inverseWorldToShadowCascadeUV); - - // TODO: Does "ShadowMapTextureTexelSize" contain the texel size relative to the light's viewport or relative to the whole atlas? - const float4 topRightTexelWS = Project(float4(ShadowMapTextureTexelSize.xy * filterRadiusInPixels, 0.0, 1.0), inverseWorldToShadowCascadeUV); - - const float texelDiagonalLength = distance(topRightTexelWS.xyz, bottomLeftTexelWS.xyz); - - const float3 positionOffsetWS = meshNormalWS * texelDiagonalLength; // TODO: Do we even need an offset on faces that face the light? - adjustedPixelPositionWS = pixelPositionWS - positionOffsetWS; // Shrink the position into the surface to avoid SSS artifacts. - - // The pixel coordinate within shadow space (the light's post-projection space): - const float4 shadowMapCoordinate = Project(float4(adjustedPixelPositionWS, 1.0), worldToShadowCascadeUV); - - adjustedPixelPositionShadowSpace = shadowMapCoordinate.xyz; - } - - /// - /// Used to calculate offsetted shadow map and world space pixel coordinates, - /// in order to mitigate shadow mapping artifacts for thickness calculation. - /// - void CalculateAdjustedShadowSpacePixelPositionPerspective(float filterRadiusInPixels, // The radius of the sampling kernel in texture space. - float3 pixelPositionWS, - float3 meshNormalWS, - float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. - float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. - out float3 adjustedPixelPositionWS, - out float3 adjustedPixelPositionShadowSpace) - { - // TODO: PERFORMANCE: The offset length can be calculated once for for each directional light on the CPU. For perspective shadows, this is a bit more complex. - // TODO: PERFORMANCE: Can we do the offset in shadow map space (by projecting the normal vector)? - - const float4 shadowMapCoordinate = Project(float4(pixelPositionWS, 1.0), worldToShadowCascadeUV); - - - - // TODO: Does "ShadowMapTextureTexelSize" contain the texel size relative to the light's viewport or relative to the whole atlas? - const float4 topRightTexelWS = Project(float4(shadowMapCoordinate.xy + ShadowMapTextureTexelSize.xy * filterRadiusInPixels, shadowMapCoordinate.z, 1.0), inverseWorldToShadowCascadeUV); // TODO: Calculate two coordinates (that center shadowMapCoordinate)? - - const float texelDiagonalLength = distance(topRightTexelWS.xyz, pixelPositionWS); - - const float3 positionOffsetWS = meshNormalWS * texelDiagonalLength; // TODO: Do we even need an offset on faces that face the light? - adjustedPixelPositionWS = pixelPositionWS - positionOffsetWS; // Shrink the position into the surface to avoid SSS artifacts. - - // The pixel coordinate within shadow space (the light's post-projection space): - const float4 adjustedShadowMapCoordinate = Project(float4(adjustedPixelPositionWS, 1.0), worldToShadowCascadeUV); - - adjustedPixelPositionShadowSpace = adjustedShadowMapCoordinate.xyz; - } - - /// - /// Calculate the thickness of the object at this pixel using the shadow map. - /// - abstract float FilterThickness(float3 pixelPositionWS, - float3 meshNormalWS, - float2 depthRanges, - float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. - float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. - bool isOrthographic); - - // TODO: Maybe implement separate linear and a perspective functions? - float SampleThickness(float3 shadowSpaceCoordinate, - float3 pixelPositionWS, - float2 depthRanges, - float4x4 inverseWorldToShadowCascadeUV, - bool isOrthographic) - { - const float shadowMapDepth = ShadowMapTexture.SampleLevel(LinearBorderSampler, shadowSpaceCoordinate.xy, 0).r; - - float thickness; - - // Now we calculate the thickness from the light's point of view: - if(isOrthographic) - { - // Subtract the two linear depth values and multiply them by Z-far in order to get the thickness in world/view space. - // This works because for directional lightmaps, Z-near is 0.0. - thickness = abs(shadowMapDepth - shadowSpaceCoordinate.z) * depthRanges.y; // Same as the above, but faster. // TODO: Better use max(thickness, 0.0) instead of abs()? - } - else - { - //float znear = depthRanges.x; - //float zfar = depthRanges.y; - //float2 ZProjection = float2(zfar / (zfar - znear), (-zfar * znear) / (zfar - znear)); - //float d1 = CalculateViewSpaceDepthFromNonlinearDepth(shadowMapDepth, ZProjection); - //float d2 = CalculateViewSpaceDepthFromNonlinearDepth(positionDepth, ZProjection); - - //float d1 = ConvertToLinearDepth(shadowMapDepth, depthRanges.x, depthRanges.y); // TODO: Multiply by (far - near)? - //float d2 = ConvertToLinearDepth(shadowSpaceCoordinate.z, depthRanges.x, depthRanges.y); - - // TODO: PERFORMANCE: Instead of doing a matrix multiplication, just correctly linearize the depth and calculate the DISTANCE (not just the depth!)! - float4 shadowmapPositionWorldSpace = Project(float4(shadowSpaceCoordinate.xy, shadowMapDepth, 1.0), inverseWorldToShadowCascadeUV); - thickness = distance(shadowmapPositionWorldSpace.xyz, pixelPositionWS.xyz); - } - - return(thickness); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl deleted file mode 100644 index 7bd7877374..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterDefault.sdsl +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Performs default filtering: no filtering. - /// - shader ShadowMapFilterDefault : ShadowMapFilterBase - { - /// - /// Calculate the shadow factor based on the shadow map texture, the position, a sampler - /// - float FilterShadow(float2 position, float positionDepth) - { - return ShadowMapTexture.SampleCmpLevelZero(LinearClampCompareLessEqualSampler, position, positionDepth); - } - - float FilterThickness(float3 pixelPositionWS, - float3 meshNormalWS, - float2 depthRanges, - float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. - float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. - bool isOrthographic) - { - //const float filterRadiusInPixels = 1.0; // 1 pixel filter radius - const float filterRadiusInPixels = 1.5; // 1.5 pixel filter radius - - float3 adjustedPixelPositionWS; - float3 adjustedPixelPositionShadowSpace; - - if(isOrthographic) - { - CalculateAdjustedShadowSpacePixelPosition(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, - adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); - } - else - { - CalculateAdjustedShadowSpacePixelPositionPerspective(filterRadiusInPixels, pixelPositionWS, meshNormalWS, worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, - adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); - } - - return SampleThickness(adjustedPixelPositionShadowSpace, adjustedPixelPositionWS, depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl deleted file mode 100644 index 7f5469796a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterPcf.sdsl +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Performs percentage closer filtering. - /// - shader ShadowMapFilterPcf : ShadowMapFilterBase - { - void CalculatePCFKernelParameters(float2 position, out float2 base_uv, out float2 st) // TODO: Make "st"! - { - float2 uv = position * ShadowMapTextureSize; // 1 unit - 1 texel - - base_uv = floor(uv + 0.5); - - st = uv + 0.5 - base_uv; - - base_uv -= 0.5; - base_uv *= ShadowMapTextureTexelSize; - } - - float Get3x3FilterKernel(float2 base_uv, float2 st, out float3 kernel[4]) - { - float2 uvW0 = (3 - 2 * st); - float2 uvW1 = (1 + 2 * st); - - float2 uv0 = (2 - st) / uvW0 - 1; - float2 uv1 = st / uvW1 + 1; - - // Each kernel element contains a texture coordinate (XY) and a weight (Z). - kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); - kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); - kernel[2] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); - kernel[3] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); - - return 16.0; - } - - float Get5x5FilterKernel(float2 base_uv, float2 st, out float3 kernel[9]) - { - float2 uvW0 = (4 - 3 * st); - float2 uvW1 = 7; - float2 uvW2 = (1 + 3 * st); - - float2 uv0 = (3 - 2 * st) / uvW0 - 2; - float2 uv1 = (3 + st) / uvW1; - float2 uv2 = st / uvW2 + 2; - - // Each kernel element contains a texture coordinate (XY) and a weight (Z). - kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); - kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); - kernel[2] = float3(base_uv + float2(uv2.x, uv0.y) * ShadowMapTextureTexelSize, uvW2.x * uvW0.y); - kernel[3] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); - kernel[4] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); - kernel[5] = float3(base_uv + float2(uv2.x, uv1.y) * ShadowMapTextureTexelSize, uvW2.x * uvW1.y); - kernel[6] = float3(base_uv + float2(uv0.x, uv2.y) * ShadowMapTextureTexelSize, uvW0.x * uvW2.y); - kernel[7] = float3(base_uv + float2(uv1.x, uv2.y) * ShadowMapTextureTexelSize, uvW1.x * uvW2.y); - kernel[8] = float3(base_uv + uv2 * ShadowMapTextureTexelSize, uvW2.x * uvW2.y); - - return 144.0; - } - - float Get7x7FilterKernel(float2 base_uv, float2 st, out float3 kernel[16]) - { - float2 uvW0 = (5 * st - 6); - float2 uvW1 = (11 * st - 28); - float2 uvW2 = -(11 * st + 17); - float2 uvW3 = -(5 * st + 1); - - float2 uv0 = (4 * st - 5) / uvW0 - 3; - float2 uv1 = (4 * st - 16) / uvW1 - 1; - float2 uv2 = -(7 * st + 5) / uvW2 + 1; - float2 uv3 = -st / uvW3 + 3; - - // Each kernel element contains a texture coordinate (XY) and a weight (Z). - kernel[0] = float3(base_uv + uv0 * ShadowMapTextureTexelSize, uvW0.x * uvW0.y); - kernel[1] = float3(base_uv + float2(uv1.x, uv0.y) * ShadowMapTextureTexelSize, uvW1.x * uvW0.y); - kernel[2] = float3(base_uv + float2(uv2.x, uv0.y) * ShadowMapTextureTexelSize, uvW2.x * uvW0.y); - kernel[3] = float3(base_uv + float2(uv3.x, uv0.y) * ShadowMapTextureTexelSize, uvW3.x * uvW0.y); - kernel[4] = float3(base_uv + float2(uv0.x, uv1.y) * ShadowMapTextureTexelSize, uvW0.x * uvW1.y); - kernel[5] = float3(base_uv + uv1 * ShadowMapTextureTexelSize, uvW1.x * uvW1.y); - kernel[6] = float3(base_uv + float2(uv2.x, uv1.y) * ShadowMapTextureTexelSize, uvW2.x * uvW1.y); - kernel[7] = float3(base_uv + float2(uv3.x, uv1.y) * ShadowMapTextureTexelSize, uvW3.x * uvW1.y); - kernel[8] = float3(base_uv + float2(uv0.x, uv2.y) * ShadowMapTextureTexelSize, uvW0.x * uvW2.y); - kernel[9] = float3(base_uv + float2(uv1.x, uv2.y) * ShadowMapTextureTexelSize, uvW1.x * uvW2.y); - kernel[10] = float3(base_uv + uv2 * ShadowMapTextureTexelSize, uvW2.x * uvW2.y); - kernel[11] = float3(base_uv + float2(uv3.x, uv2.y) * ShadowMapTextureTexelSize, uvW3.x * uvW2.y); - kernel[12] = float3(base_uv + float2(uv0.x, uv3.y) * ShadowMapTextureTexelSize, uvW0.x * uvW3.y); - kernel[13] = float3(base_uv + float2(uv1.x, uv3.y) * ShadowMapTextureTexelSize, uvW1.x * uvW3.y); - kernel[14] = float3(base_uv + float2(uv2.x, uv3.y) * ShadowMapTextureTexelSize, uvW2.x * uvW3.y); - kernel[15] = float3(base_uv + uv3 * ShadowMapTextureTexelSize, uvW3.x * uvW3.y); - - return 2704.0; - } - - float SampleTextureAndCompare(float2 position, float positionDepth) - { - return ShadowMapTexture.SampleCmpLevelZero(LinearClampCompareLessEqualSampler, position, positionDepth); - } - - float FilterShadow(float2 position, float positionDepth) - { - float shadow = 0.0f; - - // TODO: handle bias - - float2 base_uv; - float2 st; - CalculatePCFKernelParameters(position, base_uv, st); - - // TODO: Apply gradient for initial offset in this way once gradient mapping has been added - // Replacing the above 2 lines this this and using the float2 parameter depthGradient which contains the change in depth along the x and y axis over the size of the entire texture atlas - //base_uv -= float2(0.5, 0.5); - //float2 initialOffset = base_uv - uv; - //base_uv *= ShadowMapTextureTexelSize; - // - // Take offset to pixel center into account according to the depth gradient - //positionDepth += dot(initialOffset * ShadowMapTextureTexelSize, depthGradient); - - if (TFilterSize == 3) - { - float3 kernel[4]; - float normalizationFactor = Get3x3FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<4; ++i) - { - shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); - } - - shadow /= normalizationFactor; - } - else if (TFilterSize == 5) - { - float3 kernel[9]; - float normalizationFactor = Get5x5FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<9; ++i) - { - shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); - } - - shadow /= normalizationFactor; - } - else if (TFilterSize == 7) - { - float3 kernel[16]; - float normalizationFactor = Get7x7FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<16; ++i) - { - shadow += kernel[i].z * SampleTextureAndCompare(kernel[i].xy, positionDepth); - } - - shadow /= normalizationFactor; - } - - return shadow; - } - - /// - /// Returns the filter radius in texture space. - /// - float GetFilterRadiusInPixels(void) - { - // TODO: Some of these filters are so wide, that they cause artifacts on thin objects like ears for example. - - //return float(TFilterSize) / 2.0 + 1.0; - - if (TFilterSize == 3) - { - return 2.5; // 3 - } - else if (TFilterSize == 5) - { - return 3.5; // 5 - } - else - { - return 4.5; // 7 - } - } - - float SampleAndFilter(float3 adjustedPixelPositionWS, float3 adjustedPixelPositionShadowSpace, float2 depthRanges, float4x4 inverseWorldToShadowCascadeUV, bool isOrthographic, bool isDualParaboloid = false) - { - float2 uv = adjustedPixelPositionShadowSpace.xy * ShadowMapTextureSize; // 1 unit - 1 texel - - float2 base_uv = floor(uv + 0.5); - float2 st = uv + 0.5 - base_uv; - base_uv *= ShadowMapTextureTexelSize; - - float thickness = 0.0; - float normalizationFactor = 1.0; - - if (TFilterSize == 3) - { - float3 kernel[4]; - normalizationFactor = Get3x3FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<4; ++i) - { - thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, - depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); - } - } - else if (TFilterSize == 5) - { - float3 kernel[9]; - normalizationFactor = Get5x5FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<9; ++i) - { - thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, - depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); - } - } - else if (TFilterSize == 7) - { - float3 kernel[16]; - normalizationFactor = Get7x7FilterKernel(base_uv, st, kernel); - - [unroll] // The shader compiler is stupid and refuses to compile without this attribute because "divergent control flow"... - for(int i=0; i<16; ++i) - { - thickness += kernel[i].z * SampleThickness(float3(kernel[i].xy, adjustedPixelPositionShadowSpace.z), adjustedPixelPositionWS, - depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); - } - } - - return(thickness / normalizationFactor); - } - - float FilterThickness(float3 pixelPositionWS, - float3 meshNormalWS, - float2 depthRanges, - float4x4 worldToShadowCascadeUV, // Transforms from world space to shadow cascade UV. - float4x4 inverseWorldToShadowCascadeUV, // Transforms from shadow cascade UV to world space. - bool isOrthographic) - { - // TODO: This filter is not great yet (quality wise), because we'd probably have to evaluate the scattering per sample to get smooth results. But that's too slow. - - float3 adjustedPixelPositionWS; - float3 adjustedPixelPositionShadowSpace; - - if(isOrthographic) // TODO: The offset calculation only works for directional lights for now. - { - // Calculate the adjusted world space coordinate and shadow map coordinate of the current pixel: - - - // TODO: PERFORMANCE: Ideally we'd like to move this to "ShadowMapReceiverDirectional.sdsl", - // because that way we can ensure that the adjusted pixel positions are calculated only once per pixel per light. - // Sadly this is not that easy because the offset depends on the filter width, which is only available inside of "ShadowMapFilterPcf.sdsl". - - CalculateAdjustedShadowSpacePixelPosition(GetFilterRadiusInPixels(), pixelPositionWS, meshNormalWS, - worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, - adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); - } - else - { - /* - float3 offset = -meshNormalWS * 0.01; // TODO: This is bad! - - // Calculate the regular shadow map coordinate: // TODO: Use the one calculated by the shadow mapping? - float4 shadowMapCoordinate = mul(float4(pixelPositionWS + offset, 1.0), worldToShadowCascadeUV); - shadowMapCoordinate.xyz /= shadowMapCoordinate.w; - - adjustedPixelPositionShadowSpace = shadowMapCoordinate.xyz; - adjustedPixelPositionWS = pixelPositionWS; - */ - - CalculateAdjustedShadowSpacePixelPositionPerspective(GetFilterRadiusInPixels(), pixelPositionWS, meshNormalWS, - worldToShadowCascadeUV, inverseWorldToShadowCascadeUV, - adjustedPixelPositionWS, adjustedPixelPositionShadowSpace); - } - - // Now perform the actual filtering: - return SampleAndFilter(adjustedPixelPositionWS, adjustedPixelPositionShadowSpace, depthRanges, inverseWorldToShadowCascadeUV, isOrthographic); - } - - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl deleted file mode 100644 index ecbfc413d7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapFilterVsm.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Performs variance filtering. - /// - shader ShadowMapFilterVsm : ShadowMapFilterBase - { - cbuffer PerLighting - { - float BleedingFactor; - float MinVariance; - }; - - float FilterShadow(float2 position, float shadowMapDistance) - { - float2 moments = (float2)ShadowMapTexture.SampleLevel(LinearBorderSampler, position, 0.0); - float variance = moments.y - moments.x * moments.x; - // Clamp variance to min - variance = max(variance, MinVariance); - float dist = moments.x - shadowMapDistance; - float pMax = variance / (variance + dist * dist); - // Light bleeding reduction (See http://http.developer.nvidia.com/GPUGems3/gpugems3_ch08.html Light Bleeding 8.4.3) - pMax = saturate((pMax - BleedingFactor) / (1.0 - BleedingFactor)); - float p = shadowMapDistance <= moments.x; - return max(p, pMax); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapGroup.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapGroup.sdsl deleted file mode 100644 index 7055dc7c79..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapGroup.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Defines the structures for shadow mapping. - /// - shader ShadowMapGroup : ShadowGroup, ShadowMapCommon - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl deleted file mode 100644 index ec5ffd9bf0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverBase.sdsl +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Selects the shadow map and computes the shadow factor. - /// - /// - /// TCascadeCountBase: Number of cascades. - /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). - /// - internal shader ShadowMapReceiverBase : - MaterialPixelShadingStream, - ShadowMapGroup, - ShadowMapFilterBase, - PositionStream4 - { - cbuffer PerLighting // TODO: Use a proper cbuffer for this? - { - float4x4 WorldToShadowCascadeUV[TCascadeCountBase * TLightCountBase]; - float4x4 InverseWorldToShadowCascadeUV[TCascadeCountBase * TLightCountBase]; // This is only required for SSS. - float4x4 ViewMatrices[TCascadeCountBase * TLightCountBase]; // This is only required for SSS. - float2 DepthRanges[TCascadeCountBase * TLightCountBase]; // x = z-near, y = z-far. This is only required for SSS. - float DepthBiases[TLightCountBase]; - float OffsetScales[TLightCountBase]; - }; - - float3 GetShadowPositionOffset(float offsetScale, float nDotL, float3 normal) - { - float normalOffsetScale = saturate(1.0f - nDotL); - return 2.0f * ShadowMapTextureTexelSize.x * offsetScale * normalOffsetScale * normal; - } - - float ComputeShadowFromCascade(float3 shadowPositionWS, int cascadeIndex, int lightIndex) - { - //float3 shadowPositionWSddx = ddx_fine(shadowPositionWS); - //float3 shadowPositionWSddy = ddy_fine(shadowPositionWS); - - float4 shadowPosition = mul(float4(shadowPositionWS, 1.0), WorldToShadowCascadeUV[cascadeIndex + lightIndex * TCascadeCountBase]); - shadowPosition.z -= DepthBiases[lightIndex]; - shadowPosition.xyz /= shadowPosition.w; - - return FilterShadow(shadowPosition.xy, shadowPosition.z); - } - - float ComputeThicknessFromCascade(float3 pixelPositionWS, // TODO: This is named "compute..." and the other function is named "calculate..."! - float3 meshNormalWS, - int cascadeIndex, - int lightIndex, - bool isOrthographic) - { - const int arrayIndex = cascadeIndex + lightIndex * TCascadeCountBase; - - return FilterThickness(pixelPositionWS, - meshNormalWS, - DepthRanges[arrayIndex], - WorldToShadowCascadeUV[arrayIndex], - InverseWorldToShadowCascadeUV[arrayIndex], - isOrthographic); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl deleted file mode 100644 index a4393aa152..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverDirectional.sdsl +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Selects the shadow map and computes the shadow factor. - /// - /// - /// TCascadeCount: Number of cascades. - /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). - /// - internal shader ShadowMapReceiverDirectional : - ShadowMapReceiverBase, - Transformation // Required for "WorldInverseTranspose". - { - cbuffer PerView.Lighting // TODO: Use a proper cbuffer for this? - { - float CascadeDepthSplits[TCascadeCount * TLightCount]; - }; - - override float3 ComputeShadow(float3 position, int lightIndex) - { - int cascadeIndexBase = lightIndex * TCascadeCount; - - // Only support a single light per group - int cascadeIndex = 0; - [unroll] - for(int i = 0; i < TCascadeCount - 1; i++) - { - [flatten] - if (streams.DepthVS > CascadeDepthSplits[cascadeIndexBase + i]) - { - cascadeIndex = i + 1; - } - } - float3 shadow = 1.0; - float tempThickness = 999.0; - - // Offset the shadow position - float3 shadowPosition = position.xyz; - shadowPosition += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); - // If we are within the cascades - if (cascadeIndex < TCascadeCount) - { - shadow = ComputeShadowFromCascade(shadowPosition, cascadeIndex, lightIndex); - - if(TComputeTransmittance) - { - tempThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, - streams.meshNormalWS, // Use the vertex normal, not the normal map normal. - cascadeIndex, - lightIndex, - true); - } - - float nextSplit = CascadeDepthSplits[cascadeIndexBase + cascadeIndex]; - float splitSize = nextSplit; - if(cascadeIndex > 0) - { - splitSize = nextSplit - CascadeDepthSplits[cascadeIndexBase + cascadeIndex - 1]; - } - float splitDist = (nextSplit - streams.DepthVS) / splitSize; - - if (splitDist < 0.2) - { - float lerpAmt = smoothstep(0.0, 0.2, splitDist); - - if (cascadeIndex == TCascadeCount - 1) - { - if (!TDepthRangeAuto) - { - shadow = lerp(1.0f, shadow, lerpAmt); - - if(TComputeTransmittance) - { - tempThickness = lerp(0.0, tempThickness, lerpAmt); - } - } - } - else if (TBlendCascades) - { - float nextShadow = ComputeShadowFromCascade(shadowPosition, cascadeIndex + 1, lightIndex); - shadow = lerp(nextShadow, shadow, lerpAmt); - - if(TComputeTransmittance) - { - float nextThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, - streams.meshNormalWS, // Use the vertex normal, not the normal map normal. - cascadeIndex + 1, - lightIndex, - true); - - tempThickness = lerp(nextThickness, tempThickness, lerpAmt); - } - } - } - } - - streams.thicknessWS = tempThickness; - - // Output the shadow color - if (TCascadeDebug) - { - //// Display Cascade with colors in debug mode - //// GREEN BLUE PURPLE RED WHITE - static const float3 colors[5] = { float3(0,1,0), float3(0,0,1), float3(1,0,1), float3(1,0,0), float3(1,1,1)}; - return colors[cascadeIndex] * shadow; - } - - return shadow; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl deleted file mode 100644 index 442fb3b969..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointCubeMap.sdsl +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Shadows -{ - /// - /// Selects the shadow map and computes the shadow factor. - /// - internal shader ShadowMapReceiverPointCubeMap : ShadowMapGroup, ShadowMapFilterBase, PositionStream4, ShaderBaseStream, LightStream, Texturing, NormalStream - { - cbuffer PerDraw.Lighting - { - float4x4 WorldToShadow[TLightCount*6]; - float4x4 InverseWorldToShadow[TLightCount*6]; - float DepthBiases[TLightCount]; - float OffsetScales[TLightCount]; - float2 DepthParameters[TLightCount]; - }; - - // TODO: Deduplicate - float3 GetShadowPositionOffset(float offsetScale, float nDotL, float3 normal) - { - float normalOffsetScale = saturate(1.0f - nDotL); - return 2.0f * ShadowMapTextureTexelSize.x * offsetScale * normalOffsetScale * normal; - } - - float ComputeThickness(float3 positionWS, int cascadeIndex) - { - // Calculate thickness for SSS: - float tempThickness = 0.0; - - const bool ComputeThickness = true; // TODO: This should be a mixin parameter or something! - if(ComputeThickness) - { - // TODO: I don't know if the shadow map filtering can be done for cube maps in the same way as for directional lights or spot lights. - tempThickness = FilterThickness(positionWS, - streams.meshNormalWS, - float2(0.0f, 1.0f), //DepthRanges[lightIndex*6+faceIndex], // TODO: Currently not needed for perspective shadow maps. - WorldToShadow[cascadeIndex], - InverseWorldToShadow[cascadeIndex], - false); - } - - return tempThickness; - } - - override float3 ComputeShadow(float3 positionWS, int lightIndex) - { - // Calculate shadow: - float3 lightPosition = LightPointGroup.Lights[lightIndex].PositionWS.xyz; - float3 lightDelta = positionWS.xyz - lightPosition; - float distanceToLight = length(lightDelta); - float3 direction = lightDelta / distanceToLight; - float3 directionAbs = abs(direction); - - float longestAxis = max(directionAbs.x, max(directionAbs.y, directionAbs.z)); - - int faceIndex; - float lightSpaceZ; - - // Select the base face index for either X,Y or Z facing - [flatten] - if(directionAbs.x == longestAxis) - { - lightSpaceZ = lightDelta.x; - faceIndex = 2; - } - else if(directionAbs.y == longestAxis) - { - lightSpaceZ = lightDelta.y; - faceIndex = 4; - } - else // direction.z == longestAxis - { - lightSpaceZ = lightDelta.z; - faceIndex = 0; - } - - // Apply offset for the negative side of a direction (+1) - float lightSpaceZDirection = sign(lightSpaceZ); - faceIndex += int(-min(0.0, lightSpaceZDirection)); - - - int cascadeIndex = lightIndex * 6 + faceIndex; - - // Compute the thickness before modifying "positionWS": - streams.thicknessWS = ComputeThickness(positionWS, cascadeIndex); - - - // Apply normal scaled bias - positionWS += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); - - // Map to texture space - float4 projectedPosition = mul(float4(positionWS,1), WorldToShadow[cascadeIndex]); - projectedPosition /= projectedPosition.w; - - // Apply bias in view space - lightSpaceZ = abs(lightSpaceZ); - lightSpaceZ -= DepthBiases[lightIndex]; - - // Project view space depth into the same space as the shadow map - float depth = DepthParameters[lightIndex].x + (DepthParameters[lightIndex].y / lightSpaceZ); - - if(depth < 0 || depth > 1) - return 1; - - // Compare distance to light to value inside of the shadow map - float shadow = FilterShadow(projectedPosition.xy, depth); - - return(shadow); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl deleted file mode 100644 index c086acd565..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverPointParaboloid.sdsl +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Shadows -{ - /// - /// Selects the shadow map and computes the shadow factor. - /// - internal shader ShadowMapReceiverPointParaboloid : ShadowMapGroup, ShadowMapFilterBase, PositionStream4, ShaderBaseStream - { - cbuffer PerDraw.Lighting - { - float4x4 View[TLightCount]; - float2 FaceOffsets[TLightCount]; - float2 BackfaceOffsets[TLightCount]; - float2 FaceSizes[TLightCount]; - float DepthBiases[TLightCount]; - float2 DepthParameters[TLightCount]; - }; - - override float3 ComputeShadow(float3 position, int lightIndex) - { - float4 lightSpace = mul(float4(position, 1), View[lightIndex]); - - // Store length and normalize - float distanceToLight = length(lightSpace.xyz); - float3 intermediate = lightSpace.xyz / distanceToLight; - - // Project x/y coordinates on parabola - intermediate.xy /= 1.0f + abs(intermediate.z); - - float2 depthParameters = DepthParameters[lightIndex]; - - // Apply bias - distanceToLight -= DepthBiases[lightIndex]; - - // Scale distance to light depth buffer range - distanceToLight *= depthParameters.y; - - // Map from (-1,1) to (0,1) - intermediate.xy = intermediate.xy * 0.5 + float2(0.5, 0.5); - intermediate.y = 1.0f-intermediate.y; - - // Apply offset into atlas and size of a single face in the atlas - float2 samplePosition = intermediate.xy * FaceSizes[lightIndex] + FaceOffsets[lightIndex]; - - // Apply offset for the back side face - [flatten] - if(lightSpace.z < 0) - { - samplePosition += BackfaceOffsets[lightIndex]; - } - - // Compare distance to light to value inside of the shadow map - float shadow = FilterShadow(samplePosition, distanceToLight); - - // Calculate thickness for SSS: - float tempThickness = 999.9; // No scattering for now. - - - - streams.thicknessWS = tempThickness; - - return(shadow); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl deleted file mode 100644 index d617f548ad..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowMapReceiverSpot.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Shadows -{ - /// - /// Selects the shadow map and computes the shadow factor. - /// - /// - /// TCascadeCount: Number of cascades. - /// TCascadeDebug: Flag to enable debug mode (1 color per cascade). - /// - internal shader ShadowMapReceiverSpot : - ShadowMapReceiverBase, - Transformation // Required for "WorldInverseTranspose". - { - override float3 ComputeShadow(float3 position, int lightIndex) - { - // Offset the shadow position - float3 shadowPosition = position.xyz; - shadowPosition += GetShadowPositionOffset(OffsetScales[lightIndex], streams.NdotL, streams.normalWS); - - float3 shadow = ComputeShadowFromCascade(shadowPosition, 0, lightIndex); - - float tempThickness = 0.0; - - // Note: transmittance is currently disabled for spot lights - //const bool ComputeTransmittance = true; // TODO: This should be a mixin parameter or something! - //if(ComputeTransmittance) - //{ - // tempThickness = ComputeThicknessFromCascade(streams.PositionWS.xyz, - // streams.meshNormalWS, - // 0, - // lightIndex, - // false); - //} - - streams.thicknessWS = tempThickness; - - // Output the shadow color - if (TCascadeDebug) - { - return float3(0, 1, 0) * shadow; - } - else - { - return shadow; - } - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ShadowStream.sdsl b/sources/shaders/assets/Stride/SDSL/ShadowStream.sdsl deleted file mode 100644 index f3c913735f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ShadowStream.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -/// -/// Defines shadow stream variables. -/// -shader ShadowStream -{ - stage stream float3 shadowColor; - stage stream float thicknessWS; -}; diff --git a/sources/shaders/assets/Stride/SDSL/SharedTextureCoordinate.sdsl b/sources/shaders/assets/Stride/SDSL/SharedTextureCoordinate.sdsl deleted file mode 100644 index f5b1bde11a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SharedTextureCoordinate.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SharedTextureCoordinate : ShaderBase, Texturing -{ - override stage void PSMain() - { - // Remap all texture coords to TEXCOORD0 - streams.TexCoord1 = streams.TexCoord; - streams.TexCoord2 = streams.TexCoord; - streams.TexCoord3 = streams.TexCoord; - streams.TexCoord4 = streams.TexCoord; - streams.TexCoord5 = streams.TexCoord; - streams.TexCoord6 = streams.TexCoord; - streams.TexCoord7 = streams.TexCoord; - streams.TexCoord8 = streams.TexCoord; - streams.TexCoord9 = streams.TexCoord; - - base.PSMain(); - } - - override stage void VSMain() - { - base.VSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl b/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl deleted file mode 100644 index 491c9ea355..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFont.sdsl +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SignedDistanceFieldFont : Texturing -{ - - // Gets the median of 3 values - float median(float r, float g, float b) - { - return max(min(r, g), min(max(r, g), b)); - } - - // Retrieves the pixel's color sampled from a signed distance field font texture, with font color, border and shadows - stage float4 FontColor(float4 sampledColor, float4 textColor, float4 borderColor, float borderThickness) - { - // -0.5 to +0.5 is the maximum distance msdfgen can produce, but it's blurry so cap the border at 0.25 - borderThickness = clamp(borderThickness, 0, 0.2); - - // Higher (more than 1) - sharper - // Lower (less than 1, more than 0) - blurry - float sharpnessMagnitude = 0.5f; - float axisDistance = 0.4 - borderThickness; - - // Get the median distance encoded in the signed distance field - float medianDistance = median(sampledColor.r, sampledColor.g, sampledColor.b); - - float sigDist = medianDistance - axisDistance; - - float transition = fwidth(sigDist) * 0.85; - float opacity = smoothstep(-transition, transition, sigDist); - opacity *= opacity; - - // Detect edge - if (borderThickness > 0) - { - float farDistance = axisDistance + borderThickness * 2; - float sigDistBorder = medianDistance - farDistance; - float borderLine = sharpnessMagnitude * sigDistBorder/fwidth(sigDistBorder) + farDistance; - float borderOpacity = smoothstep(0, 1, borderLine); - - textColor = lerp(borderColor, textColor, borderOpacity); - } - - sampledColor = lerp(float4(0,0,0,0), textColor, opacity); - - return sampledColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl b/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl deleted file mode 100644 index c8e739a6d4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SignedDistanceFieldFontShader.sdsl +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SignedDistanceFieldFontShader : ShaderBase, SignedDistanceFieldFont -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Position : POSITION; - stage stream float4 Color : COLOR; - stage stream float Swizzle : BATCH_SWIZZLE; - - // ------------------------------------- - // VertexShader - // ------------------------------------- - stage override void VSMain() - { - streams.ShadingPosition = streams.Position; - } - - // ------------------------------------- - // PixelShader - // ------------------------------------- - stage override void PSMain() - { - streams.ColorTarget = Shading(); - } - - stage float4 Shading() - { - // This should be a 3-channel signed distance field texture - float4 signedMultiDistance = Texture0.Sample(Sampler, streams.TexCoord); - - // These values can go into streams later - float4 borderColor = float4(0, 0, 0, 1); - float borderThickness = 0.f; - - return FontColor(signedMultiDistance, streams.Color, borderColor, borderThickness); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/Simple.sdsl b/sources/shaders/assets/Stride/SDSL/Simple.sdsl deleted file mode 100644 index 65cf152d21..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Simple.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Simple -{ - float test; -}; diff --git a/sources/shaders/assets/Stride/SDSL/SimpleShader.sdsl b/sources/shaders/assets/Stride/SDSL/SimpleShader.sdsl deleted file mode 100644 index 221a8aff7e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SimpleShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SimpleShader : ShaderBase, Texturing -{ - stage stream float2 Position : POSITION; - - float4 BaseColor; - - //stage float4 TestColor; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor + Texture0.Sample(PointRepeatSampler, streams.Position); // + TestColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SkyboxShaderBase.sdsl b/sources/shaders/assets/Stride/SDSL/SkyboxShaderBase.sdsl deleted file mode 100644 index 22fc687342..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SkyboxShaderBase.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - shader SkyboxShaderBase : SpriteBase, SkyboxStream - { - stage float Intensity; - stage float4x4 ProjectionInverse; - stage float4x4 ViewInverse; - stage float4x4 SkyMatrix; - - override stage void VSMain() - { - base.VSMain(); - var screenPosition = streams.ShadingPosition / streams.ShadingPosition.w; - var position = float4(screenPosition.x, screenPosition.y, 1.0f, 1.0f); - var directionVS = mul(position, ProjectionInverse).xyz; - var directionWS = mul(float4(directionVS,0), ViewInverse).xyz; - streams.skyboxViewDirection = mul(directionWS, (float3x3)SkyMatrix); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl b/sources/shaders/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl deleted file mode 100644 index 0ffcf1eeb8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SkyboxShaderCubemap.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - shader SkyboxShaderCubemap : SkyboxShaderBase - { - stage TextureCube CubeMap; - - override stage float4 Shading() - { - var samplingDir = normalize(streams.skyboxViewDirection); - var color = CubeMap.Sample(LinearSampler, float3(samplingDir.x, samplingDir.y, -samplingDir.z)).rgb; - return float4(color * Intensity, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SkyboxShaderTexture.sdsl b/sources/shaders/assets/Stride/SDSL/SkyboxShaderTexture.sdsl deleted file mode 100644 index 795273865d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SkyboxShaderTexture.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - shader SkyboxShaderTexture : SkyboxShaderBase, Math - { - stage Texture2D Texture; - - override stage float4 Shading() - { - var samplingDir = normalize(streams.skyboxViewDirection); - var samplingDirSquare = float3(samplingDir.x*samplingDir.x, samplingDir.y*samplingDir.y, samplingDir.z*samplingDir.z); - var u = atan2(-samplingDir.z, -samplingDir.x)/(2*Math.PI) + 0.5; - var v = atan2(-samplingDir.y, length(samplingDir.xz))/Math.PI + 0.5; - -#if STRIDE_GRAPHICS_PROFILE >= GRAPHICS_PROFILE_LEVEL_10_0 - var color = Texture.SampleLevel(LinearSampler, float2(u, v), 0).rgb; -#else - var color = Texture.Sample(LinearSampler, float2(u, v)).rgb; -#endif - return float4(color * Intensity, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SkyboxStream.sdsl b/sources/shaders/assets/Stride/SDSL/SkyboxStream.sdsl deleted file mode 100644 index c91f12856d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SkyboxStream.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Skyboxes -{ - shader SkyboxStream - { - stage stream float3 skyboxViewDirection; - }; -} - diff --git a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl b/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl deleted file mode 100644 index 9f314bb389..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsBase.sdsl +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A shader performing Lambertian pre-filtering. - /// - internal shader SphericalHarmonicsBase : Math - { - static const int CoefficientsCount = TOrder * TOrder; - - // Pi constants - static const float PI4 = 4 * PI; - static const float PI16 = 16 * PI; - static const float PI64 = 64 * PI; - static const float SQRT_PI = 1.77245385090551602729; - - // The values of the SH bases function after last evaluation - stream float SHBaseValues[CoefficientsCount]; - - void EvaluateSHBases(float3 direction) - { - var x = direction.x; - var y = direction.y; - var z = direction.z; - - var x2 = x*x; - var y2 = y*y; - var z2 = z*z; - - streams.SHBaseValues[0] = 1.0/(2.0*SQRT_PI); - -if(TOrder>1) -{ - streams.SHBaseValues[1] = -sqrt(3.0/PI4)*y; - streams.SHBaseValues[2] = sqrt(3.0/PI4)*z; - streams.SHBaseValues[3] = -sqrt(3.0/PI4)*x; - -if(TOrder>2) -{ - streams.SHBaseValues[4] = sqrt(15.0/PI4)*y*x; - streams.SHBaseValues[5] = -sqrt(15.0/PI4)*y*z; - streams.SHBaseValues[6] = sqrt(5.0/PI16)*(3.0*z2-1.0); - streams.SHBaseValues[7] = -sqrt(15.0/PI4)*x*z; - streams.SHBaseValues[8] = sqrt(15.0/PI16)*(x2-y2); - -if(TOrder>3) -{ - var z3 = pow(z, 3.0); - - var x4 = pow(x, 4.0); - var y4 = pow(y, 4.0); - var z4 = pow(z, 4.0); - - streams.SHBaseValues[ 9] = -sqrt( 70.0/PI64)*y*(3*x2-y2); - streams.SHBaseValues[10] = sqrt(105.0/ PI4)*y*x*z; - streams.SHBaseValues[11] = -sqrt( 21.0/PI16)*y*(-1.0+5.0*z2); - streams.SHBaseValues[12] = sqrt( 7.0/PI16)*(5.0*z3-3.0*z); - streams.SHBaseValues[13] = -sqrt( 42.0/PI64)*x*(-1.0+5.0*z2); - streams.SHBaseValues[14] = sqrt(105.0/PI16)*(x2-y2)*z; - streams.SHBaseValues[15] = -sqrt( 70.0/PI64)*x*(x2-3.0*y2); - -if(TOrder>4) -{ - streams.SHBaseValues[16] = 3.0*sqrt(35.0/PI16)*x*y*(x2-y2); - streams.SHBaseValues[17] = -3.0*sqrt(70.0/PI64)*y*z*(3.0*x2-y2); - streams.SHBaseValues[18] = 3.0*sqrt( 5.0/PI16)*y*x*(-1.0+7.0*z2); - streams.SHBaseValues[19] = -3.0*sqrt(10.0/PI64)*y*z*(-3.0+7.0*z2); - streams.SHBaseValues[20] = (105.0*z4-90.0*z2+9.0)/(16.0*SQRT_PI); - streams.SHBaseValues[21] = -3.0*sqrt(10.0/PI64)*x*z*(-3.0+7.0*z2); - streams.SHBaseValues[22] = 3.0*sqrt( 5.0/PI64)*(x2-y2)*(-1.0+7.0*z2); - streams.SHBaseValues[23] = -3.0*sqrt(70.0/PI64)*x*z*(x2-3.0*y2); - streams.SHBaseValues[24] = 3.0*sqrt(35.0/(4.0*PI64))*(x4-6.0*y2*x2+y4); -}}}} - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl b/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl deleted file mode 100644 index a13028600e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsEnvironmentColor.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Skyboxes -{ - /// - /// Base shader to sample an environment - /// - shader SphericalHarmonicsEnvironmentColor : SphericalHarmonicsUtils, IComputeEnvironmentColor - { - cbuffer PerView.Lighting - { - [Color] - float3 SphericalColors[TOrder * TOrder]; - } - - override float4 Compute(float3 direction) - { - // Workaround for type mismatch during SPIR-V validation - //float3 test[TOrder * TOrder]; - //for (int i = 0; i < TOrder * TOrder; i++) - // test[i] = SphericalColors[i]; - //return EvaluateSphericalHarmonics(test, direction); - - return EvaluateSphericalHarmonics(SphericalColors, direction); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl b/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl deleted file mode 100644 index 592cbba076..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SphericalHarmonicsRenderer.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A shader performing Lambertian pre-filtering. - /// - internal shader SphericalHarmonicsRenderer: SphericalHarmonicsBase, ImageEffectShader, Texturing - { - [Color] stage float3 SHCoefficients[CoefficientsCount]; - - // Shading of the sprite - stage override void PSMain() - { - float3 ColorTargets[6]; - for( uint i=0; i<6; ++i) - { - var direction = normalize(CubemapUtils.ConvertTexcoordsNoFlip(streams.TexCoord, i)); // remarks: TexCoord points to the center of the pixel (what we want) - - EvaluateSHBases(direction); - - ColorTargets[i] = float3(0, 0, 0); - for(int k=0; k - /// A shader performing Lambertian pre-filtering. - /// - internal shader SphericalHarmonicsUtils : Math - { - static const int CoefficientsCount = TOrder * TOrder; - - float4 EvaluateSphericalHarmonics(float3 sphericalColors[TOrder * TOrder], float3 direction) - { - var x = direction.x; - var y = direction.y; - var z = direction.z; - - var x2 = x*x; - var y2 = y*y; - var z2 = z*z; - - float3 color = sphericalColors[0]; - -if(TOrder>1) -{ - color += sphericalColors[1]*y; - color += sphericalColors[2]*z; - color += sphericalColors[3]*x; - -if(TOrder>2) -{ - color += sphericalColors[4]*y*x; - color += sphericalColors[5]*y*z; - color += sphericalColors[6]*(3.0*z2-1.0); - color += sphericalColors[7]*x*z; - color += sphericalColors[8]*(x2-y2); - -if(TOrder>3) -{ - var z3 = z2 * z; - - var x4 = x2 * x2; - var y4 = y2 * y2; - var z4 = z2 * z2; - - color += sphericalColors[9]*y*(3*x2-y2); - color += sphericalColors[10]*y*x*z; - color += sphericalColors[11]*y*(-1.0+5.0*z2); - color += sphericalColors[12]*(5.0*z3-3.0*z); - color += sphericalColors[13]*x*(-1.0+5.0*z2); - color += sphericalColors[14]*(x2-y2)*z; - color += sphericalColors[15]*x*(x2-3.0*y2); - -if(TOrder>4) -{ - color += sphericalColors[16]*x*y*(x2-y2); - color += sphericalColors[17]*y*z*(3.0*x2-y2); - color += sphericalColors[18]*y*x*(-1.0+7.0*z2); - color += sphericalColors[19]*y*z*(-3.0+7.0*z2); - color += sphericalColors[20]*(105.0*z4-90.0*z2+9.0); - color += sphericalColors[21]*x*z*(-3.0+7.0*z2); - color += sphericalColors[22]*(x2-y2)*(-1.0+7.0*z2); - color += sphericalColors[23]*x*z*(x2-3.0*y2); - color += sphericalColors[24]*(x4-6.0*y2*x2+y4); -}}}} - return float4(color, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl b/sources/shaders/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl deleted file mode 100644 index 79bf42d82e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpotLightDataInternalShader.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a structure that is used only within the spotlight shaders. - /// - shader SpotLightDataInternalShader // Named "SpotLightDataInternalShader" instead of "SpotLightDataInternal" because otherwise the name clashes with the name of the "SpotLightDataInternal" structure. - { - struct SpotLightDataInternal - { - float3 PositionWS; - float3 DirectionWS; - float3 AngleOffsetAndInvSquareRadius; - [Color] - float3 Color; - }; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Sprite3DBase.sdsl b/sources/shaders/assets/Stride/SDSL/Sprite3DBase.sdsl deleted file mode 100644 index 6cb51ecbdc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Sprite3DBase.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader Sprite3DBase : SpriteBase -{ - stage float SliceCoordinate; - - override stage float4 Shading() - { - return Texture3D0.Sample(Sampler, float3(streams.TexCoord, SliceCoordinate)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl deleted file mode 100644 index ed38241453..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteAlphaCutoff.sdsl +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SpriteAlphaCutoff : SpriteBase -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Color : COLOR; - stage stream float4 ColorAdd : COLOR1; - stage stream float Swizzle : BATCH_SWIZZLE; - - // ------------------------------------- - // VertexShader - // ------------------------------------- - stage override void VSMain() - { - base.VSMain(); - if (TSRgb) - { - streams.Color = ColorUtility.ToLinear(streams.Color); - } - } - - // Shading of the sprite - stage override float4 Shading() - { - // Because we use float input values we should allow certain threshold - lets fix it at 0.1 - - // Alpha grayscale - float4 swizzleColor = (abs(streams.Swizzle - 1) <= 0.1) ? base.Shading().rrrr : base.Shading(); - - // Normal maps - if (abs(streams.Swizzle - 2) <= 0.1) - { - // TODO This should change if we move the flags (reconstruct Z, etc) to the texture - // For now just assume the formula below is correct (works for 90% of teh cases) - float nX = swizzleColor.r * 2 - 1; - float nY = swizzleColor.g * 2 - 1; - swizzleColor.a = 1; - float nZ = 1 - sqrt(saturate(nX * nX + nY * nY)); - swizzleColor.b = nZ * 0.5f + 0.5f; // Don't forget that the Z-component is also in the range (-1, 1) so all normal textures have Blue channel above 0.5 - } - - // Opaque grayscale - if (abs(streams.Swizzle - 3) <= 0.1) - { - swizzleColor.gb = swizzleColor.rr; - swizzleColor.a = 1; - } - - float4 finalColor = swizzleColor * streams.Color + streams.ColorAdd; - - // Discard low alpha pixels - clip(finalColor.a - 0.1); - - // Premultiply color and set alpha to 1 - //finalColor = float4(finalColor.rgb * finalColor.a, 1); - - return finalColor; - } -}; - -namespace Stride.Rendering -{ - partial effect SpriteAlphaCutoffEffect - { - using params SpriteBaseKeys; - mixin SpriteAlphaCutoff; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SpriteBase.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteBase.sdsl deleted file mode 100644 index c3c1694ec1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteBase.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteBase : ShaderBase, Texturing -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Position : POSITION; - - cbuffer PerDraw - { - // ------------------------------------- - // uniforms - // ------------------------------------- - // A general transformation matrix - stage float4x4 MatrixTransform; - } - - // ------------------------------------- - // VertexShader - // ------------------------------------- - stage override void VSMain() - { - streams.ShadingPosition = mul(streams.Position, MatrixTransform); - } - - // Shading of the sprite - stage override void PSMain() - { - streams.ColorTarget = Shading(); - } - - stage float4 Shading() - { - return Texture0.Sample(Sampler, streams.TexCoord); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteBatchShader.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteBatchShader.sdsl deleted file mode 100644 index d6ce2dfc08..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteBatchShader.sdsl +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteBatchShader : SpriteBase -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Color : COLOR; - stage stream float4 ColorAdd : COLOR1; - stage stream float Swizzle : BATCH_SWIZZLE; - - // ------------------------------------- - // VertexShader - // ------------------------------------- - stage override void VSMain() - { - base.VSMain(); - if (TSRgb) - { - streams.Color = ColorUtility.ToLinear(streams.Color); - } - } - - // Shading of the sprite - stage override float4 Shading() - { - // Because we use float input values we should allow certain threshold - lets fix it at 0.1 - - // Alpha grayscale - float4 swizzleColor = (abs(streams.Swizzle - 1) <= 0.1) ? base.Shading().rrrr : base.Shading(); - - // Normal maps - if (abs(streams.Swizzle - 2) <= 0.1) - { - // TODO This should change if we move the flags (reconstruct Z, etc) to the texture - // For now just assume the formula below is correct (works for 90% of teh cases) - float nX = swizzleColor.r * 2 - 1; - float nY = swizzleColor.g * 2 - 1; - swizzleColor.a = 1; - float nZ = 1 - sqrt(saturate(nX * nX + nY * nY)); - swizzleColor.b = nZ * 0.5f + 0.5f; // Don't forget that the Z-component is also in the range (-1, 1) so all normal textures have Blue channel above 0.5 - } - - // Opaque grayscale - if (abs(streams.Swizzle - 3) <= 0.1) - { - swizzleColor.gb = swizzleColor.rr; - swizzleColor.a = 1; - } - - - float4 finalColor = swizzleColor * streams.Color + streams.ColorAdd; - return finalColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteEffect.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteEffect.sdsl deleted file mode 100644 index e1b0e4db56..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteEffect.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteEffect : SpriteBase -{ - // Color used to tint the sprite - [Color] - stage float4 Color = float4(1,1,1,1); - - // Shading of the sprite - stage override float4 Shading() - { - return base.Shading() * Color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl deleted file mode 100644 index f20005db50..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTexture.sdsl +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteEffectExtTexture : ShaderBase -{ - // Color used to tint the sprite - //[Color] - //stage float4 Color = float4(1,1,1,1); - - //[ExternalOES] - stage Texture2D StrideInternal_TextureExt0; // DO NOT RENAME THIS VARIABLE! The ShaderCompiler specifically looks for "TextureExt0". - stage float MipLevel; - stage float Gamma; - //stage Texture2DExternalOES StrideInternal_TextureExt0; - - stage SamplerState Sampler; - - stage stream float2 TexCoord : TEXCOORD0; - stage stream float4 Position : POSITION; - - /*cbuffer PerDraw - { - stage float4x4 MatrixTransform; - }*/ - - stage override void VSMain() - { - //streams.ShadingPosition = mul(streams.Position, MatrixTransform); - streams.ShadingPosition = streams.Position; - } - - stage override void PSMain() - { - streams.ColorTarget = Shading(); - } - - float4 GetMipmapLevelDebugMask() - { - // These values depend on each other because the mip levels are - // copied down and therefore mask each other out. - // That's why no value is set to zero. - if(MipLevel < 0.5f) - { - return float4(1.0f, 1.0f, 1.0f, 1.0f); // White - } - else if(MipLevel < 1.5f) - { - return float4(1.0f, 0.5f, 0.5f, 1.0f); // Red - } - else if(MipLevel < 2.5f) - { - return float4(0.5f, 2.0f, 1.0f, 1.0f); // Green - } - else if(MipLevel < 3.5f) - { - return float4(1.0f, 0.5f, 2.0f, 1.0f); // Blue - } - else if(MipLevel < 4.5f) - { - return float4(2.0f, 2.0f, 0.5f, 1.0f); // Yellow - } - - // TODO: - else if(MipLevel < 5.5f) - { - return float4(1.0f, 2.0f, 2.0f, 1.0f); - } - else if(MipLevel < +.5f) - { - return float4(2.0f, 1.0f, 2.0f, 1.0f); - } - else if(MipLevel < 7.5f) - { - return float4(2.0f, 1.0f, 2.0f, 1.0f); - } - else if(MipLevel < 8.5f) - { - return float4(2.0f, 2.0f, 1.0f, 1.0f); - } - - return 2.0f; - } - - float3 ConvertToLinearSpace(float3 color) - { - return pow(color, Gamma); - } - - stage float4 Shading() - { - //return StrideInternal_TextureExt0.Sample(Sampler, streams.TexCoord) * Color; - - // Generate a "random" color based on the mip level, for debug purposes: - //float4 debugColor = GetMipmapLevelDebugMask(); - - //float4 debugColor = 1.0f; - //float4 textureColor = StrideInternal_TextureExt0.SampleLevel(Sampler, streams.TexCoord, MipLevel); //Failed to compile on GLSL - //return float4(ConvertToLinearSpace(textureColor.rgb), 1.0f) * debugColor; - - float4 textureColor = StrideInternal_TextureExt0.Sample(Sampler, streams.TexCoord); - return float4(ConvertToLinearSpace(textureColor.rgb), 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl deleted file mode 100644 index cfc3860fef..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteEffectExtTextureRegular.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteEffectExtTextureRegular : ShaderBase -{ - stage Texture2D TextureRegular; - - stage SamplerState Sampler; - stage float MipLevel; - - stage stream float2 TexCoord : TEXCOORD0; - stage stream float4 Position : POSITION; - - stage override void VSMain() - { - streams.ShadingPosition = streams.Position; - } - - stage override void PSMain() - { - streams.ColorTarget = Shading(); - } - - stage float4 Shading() - { - return TextureRegular.SampleLevel(Sampler, streams.TexCoord, MipLevel); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpritePicking.sdsl b/sources/shaders/assets/Stride/SDSL/SpritePicking.sdsl deleted file mode 100644 index 653fcbdea7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpritePicking.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SpritePicking : SpriteBase -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Color : COLOR; - - // method computing color - stage override float4 Shading() - { - base.Shading(); // discard pixel if needed. - - return streams.Color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl deleted file mode 100644 index 17d75a3631..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteSignedDistanceFieldFontShader.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SpriteSignedDistanceFieldFontShader : SpriteBase, SignedDistanceFieldFont -{ - stage stream float4 Color : COLOR; - - // Shading of the sprite - stage override float4 Shading() - { - return FontColor(base.Shading(), streams.Color, float4(0,0,0,1), 0.f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SpriteSuperSampler.sdsl b/sources/shaders/assets/Stride/SDSL/SpriteSuperSampler.sdsl deleted file mode 100644 index c2d897abc9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SpriteSuperSampler.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader SpriteSuperSampler : SpriteBase -{ - stage override float4 Shading() - { - // "call of duty"-type of h4x4 checker box, but reduced to 9 picks instead of 13: - float2 jitters[] = { - float2(-2.0, 0.0), - float2(0.0, 0.0), - float2(2.0, 0.0), - float2(-1.0, 1.0), - float2(1.0, 1.0), - float2(-1.0, -1.0), - float2(1.0, -1.0), - float2(0.0, 2.0), - float2(0.0, -2.0) - }; - - float weightSum = 0; - float4 color = 0; - float2 texCoordBackup = streams.TexCoord; - - [unroll] - for (uint j = 0; j < 9; ++j) - { - float2 jitter = jitters[j]; - float dist = max(abs(jitter.x), abs(jitter.y)); - float weight = 3 - dist; - streams.TexCoord = texCoordBackup + jitter * Texture0TexelSize; - color += weight * base.Shading(); - weightSum += weight; - } - - streams.TexCoord = texCoordBackup; - - return color / weightSum; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StageBase.sdsl b/sources/shaders/assets/Stride/SDSL/StageBase.sdsl deleted file mode 100644 index d4a4d22e00..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StageBase.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageBase -{ - abstract stage void stageCall(); - stage float stageMember = 1.0f; -}; diff --git a/sources/shaders/assets/Stride/SDSL/StageCallExtern.sdsl b/sources/shaders/assets/Stride/SDSL/StageCallExtern.sdsl deleted file mode 100644 index a65e6bb714..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StageCallExtern.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageCallExtern : StageBase -{ - void test() - { - float u = stageMember; - stageCall(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StageDecl.sdsl b/sources/shaders/assets/Stride/SDSL/StageDecl.sdsl deleted file mode 100644 index b7186c6c75..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StageDecl.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageDecl -{ - stage int myStageVar = 1; -}; diff --git a/sources/shaders/assets/Stride/SDSL/StageValueReference.sdsl b/sources/shaders/assets/Stride/SDSL/StageValueReference.sdsl deleted file mode 100644 index f152267982..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StageValueReference.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageValueReference -{ - compose StageValueTest myStageVar = stage; - - void test() - { - myStageVar.test(); - float u = myStageVar.testFloat; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StageValueTest.sdsl b/sources/shaders/assets/Stride/SDSL/StageValueTest.sdsl deleted file mode 100644 index 8234eabb92..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StageValueTest.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageValueTest -{ - compose StageValueReference myExtern; - float testFloat; - - void test() - { - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StaticCallMixin.sdsl b/sources/shaders/assets/Stride/SDSL/StaticCallMixin.sdsl deleted file mode 100644 index 664bed071d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StaticCallMixin.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticCallMixin -{ - void call() - { - StaticMixin.staticCall(); - float a = -StaticMixin.staticMember; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StaticMixin.sdsl b/sources/shaders/assets/Stride/SDSL/StaticMixin.sdsl deleted file mode 100644 index 911790092d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StaticMixin.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticMixin -{ - float staticMember; - - void staticCall() - { - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StaticStageCallTest.sdsl b/sources/shaders/assets/Stride/SDSL/StaticStageCallTest.sdsl deleted file mode 100644 index c2e581c111..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StaticStageCallTest.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticStageCallTest : StageBase -{ - compose StageCallExtern myExtern; - - stage void stageCall() - { - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamChild.sdsl b/sources/shaders/assets/Stride/SDSL/StreamChild.sdsl deleted file mode 100644 index 180e55db59..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamChild.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamChild : StreamParent0, StreamParent1 -{ - float test() - { - return streams.StreamParent0.parentStream + streams.StreamParent1.parentStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamError.sdsl b/sources/shaders/assets/Stride/SDSL/StreamError.sdsl deleted file mode 100644 index 61577f7001..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamError.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamError -{ - stream float myStream; - - void test0(inout float value) - { - value = 2.0*value; - } - - void test1() - { - test0(streams.myStream); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamParent0.sdsl b/sources/shaders/assets/Stride/SDSL/StreamParent0.sdsl deleted file mode 100644 index 8f2b752f80..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamParent0.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent0 -{ - stream float parentStream = 0.0f; -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamParent1.sdsl b/sources/shaders/assets/Stride/SDSL/StreamParent1.sdsl deleted file mode 100644 index f97b938f0d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamParent1.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent1 -{ - stream float parentStream = 0.0f; -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamParent2.sdsl b/sources/shaders/assets/Stride/SDSL/StreamParent2.sdsl deleted file mode 100644 index b55c0f6d3d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamParent2.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent2 -{ - stream float parentStream = 0.0f; - stage stream float stageStream = 0.0f; -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamSolverExternTest.sdsl b/sources/shaders/assets/Stride/SDSL/StreamSolverExternTest.sdsl deleted file mode 100644 index 020d4a5d28..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamSolverExternTest.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamSolverExternTest -{ - compose StreamChild myExtern; - float func() - { - return streams.myExtern.StreamParent0.parentStream + streams.myExtern.StreamParent1.parentStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StreamTest.sdsl b/sources/shaders/assets/Stride/SDSL/StreamTest.sdsl deleted file mode 100644 index 6918d24a02..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StreamTest.sdsl +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamTest -{ - stream float2 PositionIn : Position; - stream float4 PositionOut; - stream float4 Color; - patchstream float3 patchstreamParam; - - void test() - { - streams.PositionOut = 2.0f*streams.PositionOut; - } - - void VSMain() - { - streams.PositionOut = float4(streams.PositionIn, 0.0f, 1.0f); - test(); - test(); - float4 a = streams.PositionOut; - } - - void PSMain() - { - streams.Color = streams.PositionOut; - //streams.Color = float4(0,0,0,0); - } - - void GSMain(point Input input[1], inout PointStream outStream) - { - streams = input[0]; - - streams.PositionOut = 0.5f * streams.PositionOut; - - outStream.Append(streams); - - for (int i = 0; i < 2; ++i) - { - outStream.Append(streams); - } - - outStream.RestartStrip(); - } - - void HSMain(InputPatch input, out Output output) - { - streams = input[0]; - //streams.PositionOut = 0.5f * streams.PositionOut; - output.PositionOut = 0.5f * input[0].PositionOut; - - output = streams; - - // TODO: using this syntax should be possible too - // TODO: add corresponding StreamUsage - //output.PositionOut = 0.5f * input[0].PositionOut; - } - - void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) - { - constants.patchstreamParam = 1.0f; - } - - void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) - { - streams = input[0]; - //streams.PositionOut = 0.5f * streams.PositionOut * constants.patchstreamParam.x; - streams = 0.5f * streams;// * constants.patchstreamParam.x; - output = streams; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl b/sources/shaders/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl deleted file mode 100644 index afcb07baa8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StrideForwardShadingEffectVXGI.sdsl +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Data; -using Stride.Rendering.Materials; - -namespace Stride.Rendering.Voxels -{ - partial effect StrideLightingVXGI - { - using params LightingKeys; - - // ----------------------------------------------- - // Add light groups - // ----------------------------------------------- - ShaderSourceCollection directLightGroups = LightingKeys.DirectLightGroups; - if (directLightGroups != null) - { - foreach(ShaderSource directLightGroup in directLightGroups) - { - // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" - mixin compose directLightGroups += (directLightGroup); - } - } - - // ----------------------------------------------- - // Add environment light groups - // ----------------------------------------------- - ShaderSourceCollection environmentLights = LightingKeys.EnvironmentLights; - if (environmentLights != null) - { - foreach(ShaderSource environmentLight in environmentLights) - { - // Use parenthesis (...) to avoid lightGroup to be interpreted as a mixin named "lightGroup" - mixin compose environmentLights += (environmentLight); - } - } - } - - /// - /// Forward shading effect - /// - effect StrideForwardShadingEffectVXGI - { - using params MaterialKeys; - - // Derive from StrideEffectBase - mixin StrideEffectBase; - - // ----------------------------------------------- - // Mix material and lighting shading for Pixel Shader - // ----------------------------------------------- - ShaderSource extensionPixelStageSurfaceShaders = MaterialKeys.PixelStageSurfaceShaders; - if (extensionPixelStageSurfaceShaders != null) - { - mixin MaterialSurfacePixelStageCompositor; - mixin compose materialPixelStage = (extensionPixelStageSurfaceShaders); - mixin compose streamInitializerPixelStage = MaterialKeys.PixelStageStreamInitializer; - - ShaderSource extensionPixelStageSurfaceFilter = MaterialKeys.PixelStageSurfaceFilter; - if (extensionPixelStageSurfaceFilter != null) - { - mixin (extensionPixelStageSurfaceFilter); - } - } - - // ----------------------------------------------- - // Add direct and environment light groups - // ----------------------------------------------- - mixin StrideLightingVXGI; - - mixin child VoxelizeToFragmentsEffect; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/StructuredBufferTest.sdsl b/sources/shaders/assets/Stride/SDSL/StructuredBufferTest.sdsl deleted file mode 100644 index 2479ccc773..0000000000 --- a/sources/shaders/assets/Stride/SDSL/StructuredBufferTest.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StructuredBufferTest -{ - StructuredBuffer sbtest; - RWStructuredBuffer rwsbtest; - - void test() - { - uint numStructs; - uint stride; - sbtest.GetDimensions(numStructs, stride); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl b/sources/shaders/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl deleted file mode 100644 index ad87885410..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SubsurfaceScatteringBlurShader.sdsl +++ /dev/null @@ -1,512 +0,0 @@ - /* - * Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) - - * Copyright (C) 2012 Jorge Jimenez (jorge@iryoku.com) - * Copyright (C) 2012 Diego Gutierrez (diegog@unizar.es) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the following disclaimer - * in the documentation and/or other materials provided with the - * distribution: - * - * "Uses Separable SSS. Copyright (C) 2012 by Jorge Jimenez and Diego - * Gutierrez." - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS - * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are - * those of the authors and should not be interpreted as representing official - * policies, either expressed or implied, of the copyright holders. - */ - -/** - * _______ _______ _______ _______ - * / | / | / | / | - * | (---- | (---- | (---- | (---- - * \ \ \ \ \ \ \ \ - * ----) | ----) | ----) | ----) | - * |_______/ |_______/ |_______/ |_______/ - * - * S E P A R A B L E S U B S U R F A C E S C A T T E R I N G - * - * http://www.iryoku.com/ - * - * Hi, thanks for your interest in Separable SSS! - * - * It's a simple shader composed of two components: - * - * 1) A transmittance function, 'SSSSTransmittance', which allows to calculate - * light transmission in thin slabs, useful for ears and nostrils. It should - * be applied during the main rendering pass as follows: - * - * float3 t = albedo.rgb * lights[i].color * attenuation * spot; - * color.rgb += t * SSSSTransmittance(...) - * - * (See 'Main.fx' for more details). - * - * 2) A simple two-pass reflectance post-processing shader, 'SSSSBlur*', which - * softens the skin appearance. It should be applied as a regular - * post-processing effect like bloom (the usual framebuffer ping-ponging): - * - * a) The first pass (horizontal) must be invoked by taking the final color - * framebuffer as input, and storing the results into a temporal - * framebuffer. - * b) The second pass (vertical) must be invoked by taking the temporal - * framebuffer as input, and storing the results into the original final - * color framebuffer. - * - * Note that This SSS filter should be applied *before* tonemapping. - * - * Before including SeparableSSS.h you'll have to setup the target. The - * following targets are available: - * SMAA_HLSL_3 - * SMAA_HLSL_4 - * SMAA_GLSL_3 - * - * For more information of what's under the hood, you can check the following - * URLs (but take into account that the shader has evolved a little bit since - * these publications): - * - * 1) Reflectance: http://www.iryoku.com/sssss/ - * 2) Transmittance: http://www.iryoku.com/translucency/ - * - * If you've got any doubts, just contact us! - */ - -namespace Stride.Rendering.SubsurfaceScattering -{ - /// - /// The Separable Subsurface Scattering shader based on https://github.com/iryoku/separable-sss. - /// - shader SubsurfaceScatteringBlurShader< - bool BlurHorizontally, - bool KernelSizeJittering, - bool OrthographicProjection, // If orthographic projection is used, this is true. If perspective projections are used, this is false. - int MaxMaterialCount, - int KernelLength, - int RenderMode - > : ImageEffectShader, Camera, Math - { - // Generated values: - stage float2 ProjectionSizeOnUnitPlaneInClipSpace; - stage float ScatteringWidths[MaxMaterialCount]; // TODO: Use Buffer instead? - stage float IterationNumber; - stage float4x4 ViewProjectionMatrix; // This is used for debugging only. - - cbuffer PerDraw - { - // Filter kernel layout is as follows: - // - Weights in the RGB channels. - // - Offsets in the A channel. - stage Buffer KernelBuffer; - } - - // These values correspond to the ones defined in SubsurfaceScatteringBlur.cs - #define SHOW_SCATTERING_OBJECTS 1 - #define SHOW_MATERIAL_INDEX 2 - #define SHOW_SCATTERING_WIDTH 3 - - //------------------------------------------------------------------------------ - // Configurable Defines - - // Light diffusion should occur on the surface of the object, not in a screen - // oriented plane. Setting SSSS_FOLLOW_SURFACE to 1 will ensure that diffusion - // is more accurately calculated, at the expense of more memory accesses. - #ifndef SSSS_FOLLOW_SURFACE - #define SSSS_FOLLOW_SURFACE 0 - #endif - - // This define allows to specify a different source for the SSS strength - // (instead of using the alpha channel of the color framebuffer). This is useful - // when the alpha channel of the mian color buffer is used for something else. - #ifndef SSSS_STRENGTH_SOURCE - #define SSSS_STRENGTH_SOURCE (colorM.a) - #endif - - //------------------------------------------------------------------------------ - // Porting Functions - //SamplerState LinearSampler { Filter = MIN_MAG_LINEAR_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; - //SamplerState PointSampler { Filter = MIN_MAG_MIP_POINT; AddressU = Clamp; AddressV = Clamp; }; - #define SSSSTexture2D Texture2D - #define SSSSSampleLevelZero(tex, coord) tex.SampleLevel(LinearSampler, coord, 0) - #define SSSSSampleLevelZeroPoint(tex, coord) tex.SampleLevel(PointSampler, coord, 0) - #define SSSSSample(tex, coord) SSSSSampleLevelZero(tex, coord) - #define SSSSSamplePoint(tex, coord) SSSSSampleLevelZeroPoint(tex, coord) - #define SSSSSampleLevelZeroOffset(tex, coord, offset) tex.SampleLevel(LinearSampler, coord, 0, offset) - #define SSSSSampleOffset(tex, coord, offset) SSSSSampleLevelZeroOffset(tex, coord, offset) - #define SSSSLerp(a, b, t) lerp(a, b, t) - #define SSSSSaturate(a) saturate(a) - #define SSSSMad(a, b, c) mad(a, b, c) - #define SSSSMul(v, m) mul(v, m) - #define SSSS_FLATTEN [flatten] - #define SSSS_BRANCH [branch] - #define SSSS_UNROLL [unroll] - - //------------------------------------------------------------------------------ - // Separable SSS Reflectance Pixel Shader - - float4 SSSSBlurPS( - // The usual quad texture coordinates. - float2 texcoord, - - // This is a SRGB or HDR color input buffer, which should be the final - // color frame, resolved in case of using multisampling. The desired - // SSS strength should be stored in the alpha channel (1 for full - // strength, 0 for disabling SSS). If this is not possible, you an - // customize the source of this value using SSSS_STRENGTH_SOURCE. - // - // When using non-SRGB buffers, you should convert to - // linear before processing, and back again to gamma space before - // storing the pixels (see Chapter 24 of GPU Gems 3 for more info) - // - // IMPORTANT: WORKING IN A NON-LINEAR SPACE WILL TOTALLY RUIN SSS! - SSSSTexture2D colorTex, - - // The linear depth buffer of the scene, resolved in case of using - // multisampling. The resolve should be a simple average to avoid - // artifacts in the silhouette of objects. - SSSSTexture2D depthTex, - - // This parameter specifies the global level of subsurface scattering - // or, in other words, the width of the filter. It's specified in - // world space units. - float sssWidth, - - // Direction of the blur: - // - First pass: float2(1.0, 0.0) - // - Second pass: float2(0.0, 1.0) - float2 dir, - - // This parameter indicates whether the stencil buffer should be - // initialized. Should be set to 'true' for the first pass if not - // previously initialized, to enable optimization of the second pass - bool initStencil, - - // Stride: The material index used to access the correct scattering kernel. - uint materialIndex) - { - // Fetch color of current pixel: - float4 colorM = SSSSSamplePoint(colorTex, texcoord); - - // This is disabled because we already discard using the material index. - /* - // Initialize the stencil buffer in case it was not already available: - if (initStencil) // (Checked in compile time, it's optimized away) - if (SSSS_STRENGTH_SOURCE == 0.0) discard; - */ - - // Fetch linear depth of current pixel: - float depthM = SSSSSamplePoint(depthTex, texcoord).r; - depthM = CalculateViewSpaceDepth(depthM); - - // Calculate the sssWidth scale (1.0 for a unit plane sitting on the projection window): - float2 scale = CalculateProjectionSize(depthM); // This is more accurate than the original approach, because it calculates the correct radius for non-square viewports. - - // Calculate the final step to fetch the surrounding pixels: - float2 finalStep = sssWidth * scale * dir; - finalStep *= SSSS_STRENGTH_SOURCE; // Modulate it using the alpha channel. - //finalStep *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3. // This is disabled because we bake it into the kernel on the CPU instead. - - if(KernelSizeJittering) - { - // This reduces the banding artifacts by introducing a bit of noise. - // This might create a less mathematically correct falloff, since it messes with the sample offsets. - // But the difference is barely noticeable. - //finalStep *= 0.5 + GetRandomNumber(streams.ShadingPosition.xy + int(IterationNumber) * 10) * 0.5; // More noisy - finalStep *= 0.5 + GetRandomNumber8x8(streams.ShadingPosition.xy + 2 + int(IterationNumber) * 10) * 0.5; // More regular (shows a bit of a grid pattern) - //finalStep *= 0.5 + FastRandom(streams.ShadingPosition.xy + 2 + int(IterationNumber) * 10) * 0.5; // More noisy - } - - // Accumulate the center sample: - float4 colorBlurred = colorM; - colorBlurred.rgb *= GetKernelElement(materialIndex, 0).rgb; - - // Accumulate the other samples: - SSSS_UNROLL - for (int i = 1; i < KernelLength; i++) - { - // Fetch color and depth for current sample: - float2 offset = texcoord + GetKernelElement(materialIndex, i).a * finalStep; - float4 color = SSSSSample(colorTex, offset); - - #if SSSS_FOLLOW_SURFACE == 1 - // If the difference in depth is huge, we lerp color back to "colorM": - float depth = SSSSSample(depthTex, offset).r; - depth = CalculateViewSpaceDepth(depth); - - //float s = SSSSSaturate(300.0 * distanceToProjectionWindow * sssWidth * abs(depthM - depth)); // Original version - float s = SSSSSaturate(abs(depthM - depth) / sssWidth * 0.5); // TODO: Use a quadratic falloff or something? - color.rgb = SSSSLerp(color.rgb, colorM.rgb, s); - #endif - - // Accumulate: - colorBlurred.rgb += GetKernelElement(materialIndex, i).rgb * color.rgb; - } - - return colorBlurred; - } - - //------------------------------------------------------------------------------ - - float4 CalculateDebugView(float3 valueCenter, float3 valueTopLeft, float3 valueBottomLeft, float3 valueTopRight, float valueBottomRight, float centerImageMargin) - { - float3 output = float3(0.0, 0.0, 0.0); - - if(streams.TexCoord.x < 0.5) - { - if(streams.TexCoord.y < 0.5) - { - output = valueTopLeft; - } - else - { - output = valueBottomLeft; - } - } - else - { - if(streams.TexCoord.y < 0.5) - { - output = valueTopRight; - } - else - { - output = valueBottomRight; - } - } - - if((streams.TexCoord.x > centerImageMargin)&&(streams.TexCoord.x < 1.0 - centerImageMargin)&& - (streams.TexCoord.y > centerImageMargin)&&(streams.TexCoord.y < 1.0 - centerImageMargin)) - { - return(float4(valueCenter, 1.0)); - } - - return(float4(output, 1.0)); - } - - float4 GenerateColorFromID(int id) - { - return float4((23 + id * 109) % 256, - (67 + id * 67) % 256, - (109 + id * 23) % 256, - 255.0) / 255.0; - } - - float4 GetKernelElement(uint materialIndex, int sampleIndex) // TODO: Make both signed or unsigned? - { - return KernelBuffer.Load(materialIndex * KernelLength + sampleIndex); - } - /* - // Based on this article: https://briansharpe.wordpress.com/2011/11/15/a-fast-and-simple-32bit-floating-point-hash-function/ - float Hash(float2 p, float2 offset, float domainSize) // "p" is assumed to be an integer coordinate. - { - const float inverseLargeFloat = 1.0 / 951.135664; - - //p = p - floor(p / domain) * domain; // Truncate the domain - p = p % domainSize; // Truncate the domain (same as the above line). - p += offset; // Offset to the interesting part of the noise. - p *= p; // Square the vector. - - return(frac(p.x * p.y * inverseLargeFloat)); - } - */ - float GetRandomNumber4x4(int2 coordinate) - { - float randomNumbers[16] = - { - 0.3125, 0.625, 0.875, 0.25, - 0.1875, 0.4375, 0.0625, 0.75, - 1, 0.375, 0.6875, 0.9375, - 0.5, 0.5625, 0.8125, 0.125 - }; - - int2 wrappedCoordinate = coordinate % 4; - return randomNumbers[wrappedCoordinate.x * 4 + wrappedCoordinate.y]; - } - - float GetRandomNumber8x8(int2 coordinate) - { - float randomNumbers[64] = - { - 0.907692307692306, 0.153846153846154, 0.523076923076923, 0.769230769230768, - 0.215384615384615, 0.338461538461538, 0.030769230769230, 0.107692307692308, - 0.123076923076923, 0.492307692307692, 0.676923076923076, 0.861538461538460, - 0.692307692307692, 0.230769230769231, 0.892307692307691, 0.984615384615383, - 0.584615384615384, 0.461538461538462, 0.476923076923077, 0.015384615384615, - 0.815384615384614, 0.569230769230769, 0.092307692307692, 0.553846153846154, - 0.707692307692307, 0.307692307692308, 0.046153846153846, 0.830769230769230, - 0.384615384615385, 0.953846153846152, 0.261538461538462, 0.538461538461538, - 0.923076923076922, 0.369230769230769, 0.738461538461538, 0.753846153846153, - 0.200000000000000, 0.076923076923076, 0.415384615384615, 0.969230769230768, - 0.846153846153845, 0.169230769230769, 0.061538461538461, 0.876923076923076, - 0.600000000000000, 0.799999999999999, 0.784615384615384, 0.246153846153846, - 0.323076923076923, 0.430769230769231, 0.938461538461537, 0.138461538461538, - 0.446153846153846, 0.353846153846154, 0.292307692307692, 0.400000000000000, - 0.184615384615385, 0.723076923076922, 0.507692307692308, 0.615384615384615, - 0.276923076923077, 0.646153846153846, 0.630769230769230, 0.661538461538461 - }; - - int2 wrappedCoordinate = coordinate % 8; - return randomNumbers[wrappedCoordinate.x * 8 + wrappedCoordinate.y]; - } - /* - float GetRandomNumber(int2 coordinate) - { - return(frac(sin(dot(coordinate, float2(12.9898, 78.2332))) * 43758.5453)); - } - */ - float2 CalculateProjectionSize(float viewSpaceDepth) - { - if(OrthographicProjection) - { - return ProjectionSizeOnUnitPlaneInClipSpace; // Size stays the same regardless of distance. - } - - return ProjectionSizeOnUnitPlaneInClipSpace / viewSpaceDepth; - } - - float CalculateViewSpaceDepth(float nonlinearDepth) // TODO: Does this really convert to view space Z or just linearize the depth? - { - if(OrthographicProjection) - { - return(NearClipPlane + nonlinearDepth * (FarClipPlane - NearClipPlane)); // TODO: PERFORMANCE: Precompute "FarClipPlane - NearClipPlane" because it can't be inlined? // TODO: PERFORMANCE: And do we need the addition with "NearClipPlane"? I think it's redundant in this case because the orthographic projection matrix's near plane is at 0.0. - } - - return(ZProjection.y / (nonlinearDepth - ZProjection.x)); - } - - bool IntersectsProjectedSphere(float3 sphereWorldSpacePosition, float sphereRadiusWorldSpace, float2 clipSpaceCoordinate) - { - // Code for debugging the sampling radius calculation: - float4 projectedSphereCoordinate = mul(float4(sphereWorldSpacePosition, 1.0), ViewProjectionMatrix); - projectedSphereCoordinate.y = -projectedSphereCoordinate.y; // TODO: Why is this necessary? - projectedSphereCoordinate.xyz /= projectedSphereCoordinate.w; - - float projectedSphereViewSpaceDepth = CalculateViewSpaceDepth(projectedSphereCoordinate.z); - float2 projectedSphereScreenDimensions = CalculateProjectionSize(projectedSphereViewSpaceDepth); - - float2 SphereToPixelClipSpace = clipSpaceCoordinate.xy - projectedSphereCoordinate.xy; - - return length(SphereToPixelClipSpace / projectedSphereScreenDimensions) < sphereRadiusWorldSpace; - } - - stage override float4 Shading() - { - uint materialIndex = uint(Texture2.Load(int3(streams.ShadingPosition.xy, 0.0)).r + 0.5); // Version for material ID stored as a float. - - if(RenderMode == SHOW_SCATTERING_OBJECTS) - { - if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. - { - return 0.0; - } - - return 1.0; - } - else if(RenderMode == SHOW_MATERIAL_INDEX) - { - if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. - { - return 0.0; - } - - // Generate a "random" color using the material index: - return GenerateColorFromID(materialIndex); - } - else if(RenderMode == SHOW_SCATTERING_WIDTH) - { - return fmod(ScatteringWidths[materialIndex], 1.0); - } - - const float4 sceneColor = Texture0.Sample(LinearSampler, streams.TexCoord); - - if(materialIndex == 0) // Material index 0 means it's not a scattering material and we can discard it. - { - return sceneColor; // Return the scene color because we are doing texture ping-ponging. - } - - float randomNumber = GetRandomNumber4x4(streams.ShadingPosition.xy + int(IterationNumber)); // More regular (shows a bit of a grid pattern) - //float randomNumber = FastRandom(streams.ShadingPosition.xy + int(IterationNumber)); // More noisy - - /* - float2 scale = CalculateProjectionSize(viewSpaceDepth); - if(scale.x < 1.0)// TODO: PEFORMANCE: Turn off rotation for small kernels (mentioned in the paper)? - { - randomNumber = 0.0; - } - */ - - float randomAngle = randomNumber * PI; // TODO: PERFORMANCE: Rotate only by 90 degrees? - randomAngle += IterationNumber; // TODO: Scale this vector somehow? Maybe from 0 to PI / 2 (depending on the number of passes). - - if(!BlurHorizontally) - { - randomAngle += PI / 2.0; - } - - float2 blurDirection = float2(cos(randomAngle), sin(randomAngle)); - float scatteringWidth = ScatteringWidths[materialIndex]; - - float4 blurredSSS = SSSSBlurPS(streams.TexCoord, - Texture0, - Texture1, // TODO: PERFORMANCE: Preconvert to view space/linearize? - scatteringWidth, - blurDirection, - false, - materialIndex); - return blurredSSS; - - // Code for debugging the sampling radius calculation: - /* - float2 clipSpaceCoordinate = streams.TexCoord.xy * 2.0 - 1.0; - if(IntersectsProjectedSphere(float3(0.0, 0.0, 0.0), 1.0, clipSpaceCoordinate)) - { - if(OrthographicProjection) - { - return sceneColor * float4(0.1, 1.0, 0.1, 1.0); - } - - return sceneColor * float4(1.0, 0.1, 0.1, 1.0); - } - */ - - // Code for debugging the SSSS in general, by visualizing the different buffers: - /* - if(BlurHorizontally) // If this is the 1st pass: - { - return blurredSSS; - } - else // If this is the 2nd pass: - { - const float nonlinearDepth = Texture1.Sample(Sampler, streams.TexCoord).r; - const float viewSpaceDepth = CalculateViewSpaceDepth(nonlinearDepth); - - const float centerImageMargin = 0.25; - - return CalculateDebugView(blurredSSS, - viewSpaceDepth, - sceneColor.rgb, //MaxMaterialCount / 500.0, - float(materialIndex) / 255.0, - ScatteringWidths[materialIndex] * 10.0, - centerImageMargin); - } - */ - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/SwapUV.sdsl b/sources/shaders/assets/Stride/SDSL/SwapUV.sdsl deleted file mode 100644 index 9d3b82b544..0000000000 --- a/sources/shaders/assets/Stride/SDSL/SwapUV.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Flips the V coordinate of the texcoord. -/// -/// -/// TStream: generic Semantic - Texcoord semantic. -/// -shader SwapUV : ShaderBase, Texturing -{ - stream float2 Texcoord : TStream; - - override void VSMain() - { - streams.Texcoord = float2(streams.Texcoord.x, 1.0f - streams.Texcoord.y); - base.VSMain(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TangentMeshSkinning.sdsl b/sources/shaders/assets/Stride/SDSL/TangentMeshSkinning.sdsl deleted file mode 100644 index 3134d27db4..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TangentMeshSkinning.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Performs skinning on the tangent. -/// -shader TangentMeshSkinning : TransformationSkinning, NormalStream -{ - override void PreTransformPosition() - { - base.PreTransformPosition(); - streams.meshTangent.xyz = mul(streams.meshTangent.xyz, (float3x3)streams.skinningBlendMatrix); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl b/sources/shaders/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl deleted file mode 100644 index 01562f7281..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TemporalAntiAliasShader.sdsl +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TemporalAntiAliasShader : ImageEffectShader -{ - static const int OFFSET_LENGTH = 2; - - cbuffer PerDraw - { - float u_BlendWeightMin; // default = 1.0 / 8.0 - float u_BlendWeightMax; // default = 0.5 - float u_HistoryBlurAmp; // default = 2.0 - float u_LumaContrastFactor; // default = 128.0 - float u_VelocityDecay; // default = 0.5 - float u_WeightCenter; - float u_WeightLowCenter; - float4 u_Weight1; - float4 u_Weight2; - float4 u_WeightLow1; - float4 u_WeightLow2; - } - - // Texture0: color - // Texture1: depth - // Texture2: velocity - // Texture3: color previous frame (blurred) - stage override float4 Shading() - { - var texCoord = streams.TexCoord; - - // fetch position of current color - float centerDepth = Texture1.SampleLevel(PointSampler, streams.TexCoord, 0).r; - float3 currentUV = float3(streams.TexCoord, centerDepth); - - // fetch position of history color - float3 historyUV = currentUV; - - //-------------------------------------------------------------------------- - // Find the offset to the position with minimum depth in neighborhood - // for diolation of foreground velocity map - //-------------------------------------------------------------------------- - int2 offsets[] = - { - {-OFFSET_LENGTH, -OFFSET_LENGTH}, - { OFFSET_LENGTH, -OFFSET_LENGTH}, - {-OFFSET_LENGTH, OFFSET_LENGTH}, - { OFFSET_LENGTH, OFFSET_LENGTH} - }; - - float4 neighbor4Depths = Texture1.GatherRed(PointSampler, - streams.TexCoord, - offsets[0], - offsets[1], - offsets[2], - offsets[3]); - - float2 neighborDepthOffset = float2(OFFSET_LENGTH, OFFSET_LENGTH); - float neighborDepthOffsetX = OFFSET_LENGTH; - - if(neighbor4Depths.x < neighbor4Depths.y) - { - neighborDepthOffsetX = -OFFSET_LENGTH; - } - if(neighbor4Depths.z < neighbor4Depths.w) - { - neighborDepthOffset.x = -OFFSET_LENGTH; - } - float depthXY = min(neighbor4Depths.x, neighbor4Depths.y); - float depthZW = min(neighbor4Depths.z, neighbor4Depths.w); - if(depthXY < depthZW) - { - neighborDepthOffset.y = -OFFSET_LENGTH; - neighborDepthOffset.x = neighborDepthOffsetX; - } - - float depthXYZW = min(depthXY, depthZW); - if(centerDepth > depthXYZW) - { - historyUV.xy += neighborDepthOffset * Texture0TexelSize; - historyUV.z = depthXYZW; - } - - // neighbor 3x3 pixels - // 012 - // 345 - // 678 - float4 currentNeighborColor0 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, -1)); - float4 currentNeighborColor1 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, -1)); - float4 currentNeighborColor2 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, -1)); - float4 currentNeighborColor3 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, 0)); - float4 currentNeighborColor4 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, 0)); - float4 currentNeighborColor5 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, 0)); - float4 currentNeighborColor6 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2(-1, 1)); - float4 currentNeighborColor7 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 0, 1)); - float4 currentNeighborColor8 = Texture0.SampleLevel(PointSampler, currentUV.xy, 0, int2( 1, 1)); - - // Apply tonemapping - currentNeighborColor0.rgb *= SimpleTonemap(currentNeighborColor0.rgb); - currentNeighborColor1.rgb *= SimpleTonemap(currentNeighborColor1.rgb); - currentNeighborColor2.rgb *= SimpleTonemap(currentNeighborColor2.rgb); - currentNeighborColor3.rgb *= SimpleTonemap(currentNeighborColor3.rgb); - currentNeighborColor4.rgb *= SimpleTonemap(currentNeighborColor4.rgb); - currentNeighborColor5.rgb *= SimpleTonemap(currentNeighborColor5.rgb); - currentNeighborColor6.rgb *= SimpleTonemap(currentNeighborColor6.rgb); - currentNeighborColor7.rgb *= SimpleTonemap(currentNeighborColor7.rgb); - currentNeighborColor8.rgb *= SimpleTonemap(currentNeighborColor8.rgb); - - // Fetch velocity map with offset position by depth check - float2 velocityUV = Texture2.Sample(PointSampler, historyUV.xy).xy; // [-1, 1] - velocityUV.x = -velocityUV.x; - - float2 velocityPixels = velocityUV / Texture0TexelSize; // [-1, 1] * (RTWidth, RTHeight) - - // Fetch history color (bilinear filter) - float4 historyColor = Texture3.Sample(LinearSampler, currentUV.xy + velocityUV); - - // Apply tonemapping - historyColor.rgb *= SimpleTonemap(historyColor.rgb); - - //-------------------------------------------------------------------------- - // Find min/max luminance on current neighbor pixels - //-------------------------------------------------------------------------- - // Find minmax on cross shaped pixels (1) - // x1x - // 345 - // x7x - float4 neighborMin = min(min(min(currentNeighborColor1, currentNeighborColor3), min(currentNeighborColor4, currentNeighborColor5)), currentNeighborColor7); - float4 neighborMax = max(max(max(currentNeighborColor1, currentNeighborColor3), max(currentNeighborColor4, currentNeighborColor5)), currentNeighborColor7); - - // Find minmax on 3x3 pixels (2) - // 012 - // 345 - // 678 - float4 neighborMin2 = min(min(currentNeighborColor0, currentNeighborColor2), min(currentNeighborColor6, currentNeighborColor8)); - float4 neighborMax2 = max(max(currentNeighborColor0, currentNeighborColor2), max(currentNeighborColor6, currentNeighborColor8)); - neighborMin2 = min(neighborMin2, neighborMin); - neighborMax2 = max(neighborMax2, neighborMax); - - // Blend (1) and (2) - neighborMin = neighborMin * 0.5 + neighborMin2 * 0.5; - neighborMax = neighborMax * 0.5 + neighborMax2 * 0.5; - - // luminance range of current neighbor pixels - float currentLumaMin = Luma(neighborMin.rgb); - float currentLumaMax = Luma(neighborMax.rgb); - float currentLumaContrast = currentLumaMax - currentLumaMin; - - - // Apply LPF to current color - float4 currentLPFColor = - currentNeighborColor0 * u_WeightLow1.x + - currentNeighborColor1 * u_WeightLow1.y + - currentNeighborColor2 * u_WeightLow1.z + - currentNeighborColor3 * u_WeightLow1.w + - currentNeighborColor4 * u_WeightLowCenter + - currentNeighborColor5 * u_WeightLow2.x + - currentNeighborColor6 * u_WeightLow2.y + - currentNeighborColor7 * u_WeightLow2.z + - currentNeighborColor8 * u_WeightLow2.w; - - - //-------------------------------------------------------------------------- - // Blend history color and current LPF color - // - // Blend weight is computed from the intersect point between - // AABB(neighborMin-neighborMax) and line(historyColor-currentLPFColor). - //-------------------------------------------------------------------------- - historyColor.rgb = IntersectAABBWithLine(historyColor.rgb, - currentLPFColor.rgb, - neighborMin.rgb, - neighborMax.rgb); - - - //-------------------------------------------------------------------------- - // Apply reconstruction filter current color - // Use Blackman-Harris 3.3 - //-------------------------------------------------------------------------- - float4 currentColor = - currentNeighborColor0 * u_Weight1.x + - currentNeighborColor1 * u_Weight1.y + - currentNeighborColor2 * u_Weight1.z + - currentNeighborColor3 * u_Weight1.w + - currentNeighborColor4 * u_WeightCenter + - currentNeighborColor5 * u_Weight2.x + - currentNeighborColor6 * u_Weight2.y + - currentNeighborColor7 * u_Weight2.z + - currentNeighborColor8 * u_Weight2.w; - - // Sharpening of current filtered color - const float historyBlur = saturate((abs(velocityPixels.x) + abs(velocityPixels.y)) * u_HistoryBlurAmp); - const float sharpness = saturate(saturate(historyBlur) * 0.5 + rcp(1.0 + currentLumaContrast * u_LumaContrastFactor)); - currentColor.rgb = lerp(currentColor.rgb, currentNeighborColor4.rgb, sharpness); - - //-------------------------------------------------------------------------- - // Compute blend weight from luminance and velocity amounts - //-------------------------------------------------------------------------- - const float historyAmount = (1.0f + historyBlur) * u_BlendWeightMin; - float historyLuma = Luma(historyColor.rgb); - historyLuma = min(abs(currentLumaMin - historyLuma), abs(currentLumaMax - historyLuma)); - const float historyFactor = historyLuma * historyAmount * (1.0 + historyBlur * historyAmount * 8.0); - float blendWeight = saturate(historyFactor * rcp(max(0.001f, historyLuma + currentLumaContrast))); - - //-------------------------------------------------------------------------- - // Clamp blend weight by velocity amounts and blend weight of previous frame - //-------------------------------------------------------------------------- - const float velocityLength = sqrt(dot(velocityPixels, velocityPixels)); - const float prevBlendWeight = historyColor.a; - const float velocityDiff = abs(prevBlendWeight - velocityLength) / max(1.0, max(prevBlendWeight, velocityLength)); - blendWeight = clamp(blendWeight, velocityDiff * u_BlendWeightMin, u_BlendWeightMax); - - //-------------------------------------------------------------------------- - // Blend filtered current color and history color - //-------------------------------------------------------------------------- - float4 outputColor = float4(0.0f, 0.0f, 0.0f, 0.0f); - outputColor.rgb = lerp(historyColor.rgb, currentColor.rgb, blendWeight); - - // Save alpha channel for velocityUV weighting - outputColor.a = max(historyColor.a * u_VelocityDecay, velocityLength * rcp(u_VelocityDecay)); - - // Revert tonemapping - outputColor.rgb *= SimpleTonemapInv(outputColor.rgb); - - // Avoid NaN : transform to 0 - outputColor.rgb = -min(-outputColor.rgb, 0.0); - - return outputColor; - } - - //------------------------------------------------------------------------------ - // - // Utility functions - // - //------------------------------------------------------------------------------ - float nonzero(float a) - { - const float CLAMP_MIN= 0.001f; - return a > -CLAMP_MIN && a < CLAMP_MIN ? CLAMP_MIN : a; - } - float3 nonzero3(float3 a) - { - return float3( nonzero(a.x), nonzero(a.y), nonzero(a.z) ); - } - - float3 IntersectAABBWithLine(float3 startLine, float3 endLine, float3 minAABB, float3 maxAABB) - { - float3 minPos = min(endLine, min(minAABB, maxAABB)); - float3 maxPos = max(endLine, max(minAABB, maxAABB)); - float3 centerAABB = (maxPos + minPos) * 0.5; - float3 dir = nonzero3(endLine - startLine); - float3 invDir = rcp(dir); - float3 org = startLine - centerAABB; - float3 scaleAABB = maxPos - centerAABB; - - float3 pos0 = (scaleAABB - org) * invDir; - float3 pos1 = ((-scaleAABB) - org) * invDir; - float intersectPos = saturate(max(max(min(pos0.x, pos1.x), min(pos0.y, pos1.y)), min(pos0.z, pos1.z))); - return lerp(startLine, endLine, intersectPos); - } - - float Luma(float3 rgbColor) - { - return dot(rgbColor, float3(0.299, 0.587, 0.114)); - } - - - float3 SimpleTonemap(float3 linearColor) - { - return rcp(linearColor + 1.0f); - } - - - float3 SimpleTonemapInv(float3 tonemappedColor) - { - return rcp(1.0f - tonemappedColor); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationAE2.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationAE2.sdsl deleted file mode 100644 index dc3a4e06d5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationAE2.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -/// -/// Performs Adjacent Edge tessellation on float3 stream. -/// -shader TessellationAE2 : TessellationBase, MaterialDomainStream -{ - stream float2 DomEdgeValue2[2]; - stream float2 DomVertValue2; - - stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) - { - base.TessellateHull(input, uCPID, NextCPID); - - const uint DominantEdge = uCPID * 2 + 3; - const uint DominantVertex = uCPID + 9; - - streams.DomEdgeValue2[0] = input[DominantEdge].TStream; - streams.DomEdgeValue2[1] = input[DominantEdge+1].TStream; - streams.DomVertValue2 = input[DominantVertex].TStream; - } - - stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) - { - base.InterpolateBarycentric(input, constants, f3BarycentricCoords); - - float fU = f3BarycentricCoords.x; - float fV = f3BarycentricCoords.y; - float fW = f3BarycentricCoords.z; - - float - uCorner = (fU == 1 ? 1:0), - vCorner = (fV == 1 ? 1:0), - wCorner = (fW == 1 ? 1:0), - uEdge = (fU == 0 && fV * fW ? 1:0), - vEdge = (fV == 0 && fU * fW ? 1:0), - wEdge = (fW == 0 && fU * fV ? 1:0), - interior = (fU * fV * fW) ? 1 : 0; - - streams.TStream = - uCorner * input[0].DomVertValue2 - + vCorner * input[1].DomVertValue2 - + wCorner * input[2].DomVertValue2 - + uEdge * lerp(input[1].DomEdgeValue2[1], input[1].DomEdgeValue2[0], fV) - + vEdge * lerp(input[2].DomEdgeValue2[1], input[2].DomEdgeValue2[0], fW) - + wEdge * lerp(input[0].DomEdgeValue2[1], input[0].DomEdgeValue2[0], fU) - + interior * streams.TStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationAE3.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationAE3.sdsl deleted file mode 100644 index 9f955a4a98..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationAE3.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -/// -/// Performs Adjacent Edge tessellation on float3 stream. -/// -shader TessellationAE3 : TessellationBase, MaterialDomainStream -{ - stream float3 DomEdgeValue3[2]; - stream float3 DomVertValue3; - - stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) - { - base.TessellateHull(input, uCPID, NextCPID); - - const uint DominantEdge = uCPID * 2 + 3; - const uint DominantVertex = uCPID + 9; - - streams.DomEdgeValue3[0] = input[DominantEdge].TStream; - streams.DomEdgeValue3[1] = input[DominantEdge+1].TStream; - streams.DomVertValue3 = input[DominantVertex].TStream; - } - - stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) - { - base.InterpolateBarycentric(input, constants, f3BarycentricCoords); - - float fU = f3BarycentricCoords.x; - float fV = f3BarycentricCoords.y; - float fW = f3BarycentricCoords.z; - - float - uCorner = (fU == 1 ? 1:0), - vCorner = (fV == 1 ? 1:0), - wCorner = (fW == 1 ? 1:0), - uEdge = (fU == 0 && fV * fW ? 1:0), - vEdge = (fV == 0 && fU * fW ? 1:0), - wEdge = (fW == 0 && fU * fV ? 1:0), - interior = (fU * fV * fW) ? 1 : 0; - - streams.TStream = - uCorner * input[0].DomVertValue3 - + vCorner * input[1].DomVertValue3 - + wCorner * input[2].DomVertValue3 - + uEdge * lerp(input[1].DomEdgeValue3[1], input[1].DomEdgeValue3[0], fV) - + vEdge * lerp(input[2].DomEdgeValue3[1], input[2].DomEdgeValue3[0], fW) - + wEdge * lerp(input[0].DomEdgeValue3[1], input[0].DomEdgeValue3[0], fU) - + interior * streams.TStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationAE4.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationAE4.sdsl deleted file mode 100644 index 8cb8301cea..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationAE4.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -/// -/// Performs Adjacent Edge tessellation on float4 stream. -/// -shader TessellationAE4 : TessellationBase, MaterialDomainStream -{ - stream float4 DomEdgeValue4[2]; - stream float4 DomVertValue4; - - stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) - { - base.TessellateHull(input, uCPID, NextCPID); - - const uint DominantEdge = uCPID * 2 + 3; - const uint DominantVertex = uCPID + 9; - - streams.DomEdgeValue4[0] = input[DominantEdge].TStream; - streams.DomEdgeValue4[1] = input[DominantEdge+1].TStream; - streams.DomVertValue4 = input[DominantVertex].TStream; - } - - stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) - { - base.InterpolateBarycentric(input, constants, f3BarycentricCoords); - - float fU = f3BarycentricCoords.x; - float fV = f3BarycentricCoords.y; - float fW = f3BarycentricCoords.z; - - float - uCorner = (fU == 1 ? 1:0), - vCorner = (fV == 1 ? 1:0), - wCorner = (fW == 1 ? 1:0), - uEdge = (fU == 0 && fV * fW ? 1:0), - vEdge = (fV == 0 && fU * fW ? 1:0), - wEdge = (fW == 0 && fU * fV ? 1:0), - interior = (fU * fV * fW) ? 1 : 0; - - streams.TStream = - uCorner * input[0].DomVertValue4 - + vCorner * input[1].DomVertValue4 - + wCorner * input[2].DomVertValue4 - + uEdge * lerp(input[1].DomEdgeValue4[1], input[1].DomEdgeValue4[0], fV) - + vEdge * lerp(input[2].DomEdgeValue4[1], input[2].DomEdgeValue4[0], fW) - + wEdge * lerp(input[0].DomEdgeValue4[1], input[0].DomEdgeValue4[0], fU) - + interior * streams.TStream; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationBase.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationBase.sdsl deleted file mode 100644 index ebea982d65..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationBase.sdsl +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines the basic methods for tessellation. -/// -/// -/// InputControlPointCount: Macro - Input control points count. -/// OutputControlPointCount: Macro - Output control points count. -/// - -#ifndef InputControlPointCount -# define InputControlPointCount 3 -#endif - -#ifndef OutputControlPointCount -# define OutputControlPointCount 3 -#endif - -shader TessellationBase : ShaderBase, TransformationBase, MaterialDomainStream, Camera, Transformation, NormalBase -{ - cbuffer PerMaterial - { - [Link("Tessellation.DesiredTriangleSize")] - stage float DesiredTriangleSize = 12.0f; - } - - patchstream float tessFactor[3] : SV_TessFactor; - patchstream float insideTessFactor : SV_InsideTessFactor; - - override stage void GenerateNormal_VS() - { - base.GenerateNormal_VS(); - - // Ensure that normal is normalized at every steps of the tessellation. - streams.normalWS = normalize(streams.normalWS); - } - - [domain("tri")] - [partitioning("fractional_odd")] - [outputtopology("triangle_cw")] - [outputcontrolpoints(3)] - [patchconstantfunc("HSConstantMain")] - void HSMain(InputPatch input, out Output output, uint uCPID : SV_OutputControlPointID) - { - const uint NextCPID = uCPID < 2 ? uCPID + 1 : 0; - - streams = input[uCPID]; - - TessellateHull(input, uCPID, NextCPID); - - // Compute screen space position of current control point and next one - // TODO: Reuse ShadingPosition? - // However, not sure if we can do tessellation directly through ShadingPosition interpolation (in which case we wouldn't need to do it in domain shader either) - float2 screenPosition0 = GetScreenSpacePosition(input[uCPID].PositionWS, ViewSize.x, ViewSize.y); - float2 screenPosition1 = GetScreenSpacePosition(input[NextCPID].PositionWS, ViewSize.x, ViewSize.y); - - // Screen space tessellation based on desired triangle size - streams.oppositeEdgeLOD = distance(screenPosition0, screenPosition1) / DesiredTriangleSize; - - output = streams; - } - - void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) - { - constants.tessFactor[0] = output[1].oppositeEdgeLOD; - constants.tessFactor[1] = output[2].oppositeEdgeLOD; - constants.tessFactor[2] = output[0].oppositeEdgeLOD; - constants.insideTessFactor = 0.33f * (constants.tessFactor[0] + constants.tessFactor[1] + constants.tessFactor[2]); - - TessellateHullConstant(input, output, constants); - - if (ComputeClipping(input, output, constants)) - { - constants.tessFactor[0] = 0.0f; - constants.tessFactor[1] = 0.0f; - constants.tessFactor[2] = 0.0f; - constants.insideTessFactor = 0.0f; - } - } - - [domain("tri")] - void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) - { - InterpolateBarycentric(input, constants, f3BarycentricCoords); - - this.BaseTransformDS(); - - output = streams; - } - - stage override void BaseTransformVS() - { - this.PreTransformPosition(); - } - - stage void BaseTransformDS() - { - this.TransformPosition(); - this.PostTransformPosition(); - } - - stage override void TransformPosition() - { - base.TransformPosition(); - - // Apply tessellation map, etc... - TessellateDomain(); - } - - float2 GetScreenSpacePosition( - float4 f3Position, // View space position of patch control point - float fScreenWidth, // Screen width - float fScreenHeight // Screen height - ) - { - float4 f4ProjectedPosition = this.ComputeShadingPosition(f3Position); - float2 f2ScreenPosition = f4ProjectedPosition.xy / f4ProjectedPosition.w; - f2ScreenPosition = ( f2ScreenPosition + 1.0f ) * 0.5f * float2( fScreenWidth, -fScreenHeight ); - return f2ScreenPosition; - } - - stage void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) {} - stage void TessellateHullConstant(InputPatch input, const OutputPatch output, inout Constants constants) {} - stage float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) {} - stage void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) {} - stage void TessellateDomain() {} -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationFlat.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationFlat.sdsl deleted file mode 100644 index baaff3ea12..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationFlat.sdsl +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Tessellates without displacing. -/// -/// -/// InputControlPointCount: Macro - number of input control points. -/// - -#ifndef InputControlPointCount -#define InputControlPointCount 3 -#endif - -shader TessellationFlat : TessellationBase -{ - stage override float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) - { - return ComputeClippingGroup3(input[0].PositionWS, input[1].PositionWS, input[2].PositionWS); - } - - float ComputeClippingGroup3(float4 f3Position1, float4 f3Position2, float4 f3Position3) - { - float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); - float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); - float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); - - float3 clipPos1P = sign(clipPos1.xyz + clipPos1.www); - float3 clipPos1M = sign(clipPos1.xyz - clipPos1.www); - float3 clipPos2P = sign(clipPos2.xyz + clipPos2.www); - float3 clipPos2M = sign(clipPos2.xyz - clipPos2.www); - float3 clipPos3P = sign(clipPos3.xyz + clipPos3.www); - float3 clipPos3M = sign(clipPos3.xyz - clipPos3.www); - - float3 planeTests = abs(clipPos1P + clipPos1M + clipPos2P + clipPos2M + clipPos3P + clipPos3M); - - return all(planeTests != 6.0f) ? 0.0 : 1.0; - } - - stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) - { - //streams = input[0] * fU + input[1] * fV + input[2] * fW; - - float fU = f3BarycentricCoords.x; - float fV = f3BarycentricCoords.y; - float fW = f3BarycentricCoords.z; - - streams = input[0] * fU + input[1] * fV + input[2] * fW; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationPN.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationPN.sdsl deleted file mode 100644 index d8113fc024..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationPN.sdsl +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Performs PN tessellation (ensures edges preservation). -/// -/// -/// InputControlPointCount: Macro - number of input control points. -/// -#ifndef InputControlPointCount -# define InputControlPointCount 3 -#endif - -shader TessellationPN : TessellationFlat -{ - patchstream float3 f3ViewB111; - stream float3 nextPositionVS1; - stream float3 nextPositionVS2; - - float3 ComputeControlPoint(float3 pA, float3 pB, float3 nA) - { - return (2.0 * pA + pB - (dot((pB - pA), nA) * nA)) / 3.0f; - } - - float ComputeClippingGroup4(float3 f3Position1, float3 f3Position2, float3 f3Position3, float3 f3Position4) - { - float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); - float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); - float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); - float4 clipPos4 = this.ComputeShadingPosition(float4(f3Position4.xyz, 1.0f)); - - float3 planeTest; - - planeTest.x = ((-clipPos1.w <= clipPos1.x && clipPos1.x <= clipPos1.w) ? 1.0f : 0.0f) - + ((-clipPos2.w <= clipPos2.x && clipPos2.x <= clipPos2.w) ? 1.0f : 0.0f) - + ((-clipPos3.w <= clipPos3.x && clipPos3.x <= clipPos3.w) ? 1.0f : 0.0f) - + ((-clipPos4.w <= clipPos4.x && clipPos4.x <= clipPos4.w) ? 1.0f : 0.0f); - - planeTest.y = ((-clipPos1.w <= clipPos1.y && clipPos1.y <= clipPos1.w) ? 1.0f : 0.0f) - + ((-clipPos2.w <= clipPos2.y && clipPos2.y <= clipPos2.w) ? 1.0f : 0.0f) - + ((-clipPos3.w <= clipPos3.y && clipPos3.y <= clipPos3.w) ? 1.0f : 0.0f) - + ((-clipPos4.w <= clipPos4.y && clipPos4.y <= clipPos4.w) ? 1.0f : 0.0f); - - planeTest.z = ((-clipPos1.w <= clipPos1.z && clipPos1.z <= clipPos1.w) ? 1.0f : 0.0f) - + ((-clipPos2.w <= clipPos2.z && clipPos2.z <= clipPos2.w) ? 1.0f : 0.0f) - + ((-clipPos3.w <= clipPos3.z && clipPos3.z <= clipPos3.w) ? 1.0f : 0.0f) - + ((-clipPos4.w <= clipPos4.z && clipPos4.z <= clipPos4.w) ? 1.0f : 0.0f); - - return !all(planeTest != 0.0f) ? 1.0 : 0.0; - } - - float ComputeClippingGroup8(float3 f3Position1, float3 f3Position2, float3 f3Position3, float3 f3Position4, float3 f3Position5, float3 f3Position6, float3 f3Position7, float3 f3Position8) - { - float4 clipPos1 = this.ComputeShadingPosition(float4(f3Position1.xyz, 1.0f)); - float4 clipPos2 = this.ComputeShadingPosition(float4(f3Position2.xyz, 1.0f)); - float4 clipPos3 = this.ComputeShadingPosition(float4(f3Position3.xyz, 1.0f)); - float4 clipPos4 = this.ComputeShadingPosition(float4(f3Position4.xyz, 1.0f)); - float4 clipPos5 = this.ComputeShadingPosition(float4(f3Position5.xyz, 1.0f)); - float4 clipPos6 = this.ComputeShadingPosition(float4(f3Position6.xyz, 1.0f)); - float4 clipPos7 = this.ComputeShadingPosition(float4(f3Position7.xyz, 1.0f)); - float4 clipPos8 = this.ComputeShadingPosition(float4(f3Position8.xyz, 1.0f)); - - float3 planeTest; - - planeTest.x = ((-clipPos1.w <= clipPos1.x && clipPos1.x <= clipPos1.w) ? 1.0f : 0.0f) - + ((-clipPos2.w <= clipPos2.x && clipPos2.x <= clipPos2.w) ? 1.0f : 0.0f) - + ((-clipPos3.w <= clipPos3.x && clipPos3.x <= clipPos3.w) ? 1.0f : 0.0f) - + ((-clipPos4.w <= clipPos4.x && clipPos4.x <= clipPos4.w) ? 1.0f : 0.0f) - + ((-clipPos5.w <= clipPos5.x && clipPos5.x <= clipPos5.w) ? 1.0f : 0.0f) - + ((-clipPos6.w <= clipPos6.x && clipPos6.x <= clipPos6.w) ? 1.0f : 0.0f) - + ((-clipPos7.w <= clipPos7.x && clipPos7.x <= clipPos7.w) ? 1.0f : 0.0f) - + ((-clipPos8.w <= clipPos8.x && clipPos8.x <= clipPos8.w) ? 1.0f : 0.0f); - - planeTest.y = ((-clipPos1.w <= clipPos1.y && clipPos1.y <= clipPos1.w) ? 1.0f : 0.0f) - + ((-clipPos2.w <= clipPos2.y && clipPos2.y <= clipPos2.w) ? 1.0f : 0.0f) - + ((-clipPos3.w <= clipPos3.y && clipPos3.y <= clipPos3.w) ? 1.0f : 0.0f) - + ((-clipPos4.w <= clipPos4.y && clipPos4.y <= clipPos4.w) ? 1.0f : 0.0f) - + ((-clipPos5.w <= clipPos5.y && clipPos5.y <= clipPos5.w) ? 1.0f : 0.0f) - + ((-clipPos6.w <= clipPos6.y && clipPos6.y <= clipPos6.w) ? 1.0f : 0.0f) - + ((-clipPos7.w <= clipPos7.y && clipPos7.y <= clipPos7.w) ? 1.0f : 0.0f) - + ((-clipPos8.w <= clipPos8.y && clipPos8.y <= clipPos8.w) ? 1.0f : 0.0f); - - planeTest.z = ((0.0f <= clipPos1.z && clipPos1.z <= clipPos1.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos2.z && clipPos2.z <= clipPos2.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos3.z && clipPos3.z <= clipPos3.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos4.z && clipPos4.z <= clipPos4.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos5.z && clipPos5.z <= clipPos5.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos6.z && clipPos6.z <= clipPos6.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos7.z && clipPos7.z <= clipPos7.w) ? 1.0f : 0.0f) - + ((0.0f <= clipPos8.z && clipPos8.z <= clipPos8.w) ? 1.0f : 0.0f); - - return !all(planeTest != 0.0f) ? 1.0 : 0.0; - } - - stage override float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) - { - // For now, Displacement clipping is hardcoded here, need to be able to split that! (maybe not that easy, need array or something) - const float displacementSize = 75; - float3 f3Position5 = input[0].PositionWS.xyz + input[0].normalWS * displacementSize; - float3 f3Position6 = input[1].PositionWS.xyz + input[1].normalWS * displacementSize; - float3 f3Position7 = input[2].PositionWS.xyz + input[2].normalWS * displacementSize; - - float3 normalB111 = normalize((input[0].normalWS + input[1].normalWS + input[2].normalWS) / 3.0f); - float3 f3Position8 = constants.f3ViewB111 + normalB111 * displacementSize; - - return ComputeClippingGroup8(input[0].PositionWS.xyz, input[1].PositionWS.xyz, input[2].PositionWS.xyz, constants.f3ViewB111, - f3Position5, f3Position6, f3Position7, f3Position8); - //return ComputeClippingGroup4(input[0].PositionWS.xyz, input[1].PositionWS.xyz, input[2].PositionWS.xyz, constants.f3ViewB111, ViewProjection); - } - - stage override void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) - { - streams.nextPositionVS1 = ComputeControlPoint((float3)input[uCPID].PositionWS, (float3)input[NextCPID].PositionWS, input[uCPID].normalWS); - streams.nextPositionVS2 = ComputeControlPoint((float3)input[NextCPID].PositionWS, (float3)input[uCPID].PositionWS, input[NextCPID].normalWS); - } - - stage override void TessellateHullConstant(InputPatch input, const OutputPatch output, inout Constants constants) - { - float3 f3B300 = output[0].PositionWS.xyz, - f3B210 = output[0].nextPositionVS1.xyz, - f3B120 = output[0].nextPositionVS2.xyz, - f3B030 = output[1].PositionWS.xyz, - f3B021 = output[1].nextPositionVS1.xyz, - f3B012 = output[1].nextPositionVS2.xyz, - f3B003 = output[2].PositionWS.xyz, - f3B102 = output[2].nextPositionVS1.xyz, - f3B201 = output[2].nextPositionVS2.xyz; - - float3 f3E = (f3B210 + f3B120 + f3B021 + f3B012 + f3B102 + f3B201) / 6.0f; - float3 f3V = (f3B003 + f3B030 + f3B300) / 3.0f; - constants.f3ViewB111 = f3E + ((f3E - f3V) / 2.0f); - - // TODO: Clipping test ? - //if (ComputeClipping(constants.f3ViewB111, ViewProjection)) - //{ - // constants.tessFactor[0] = 0.0f; - // constants.tessFactor[1] = 0.0f; - // constants.tessFactor[2] = 0.0f; - //} - - //float fB111Clipped = IsClipped( - // ApplyProjection(g_f4x4ViewProjection, O.f3ViewB111)); - } - - stage override void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) - { - base.InterpolateBarycentric(input, constants, f3BarycentricCoords); - - float fU = f3BarycentricCoords.x; - float fV = f3BarycentricCoords.y; - float fW = f3BarycentricCoords.z; - - float fUU = fU * fU; - float fVV = fV * fV; - float fWW = fW * fW; - float fUU3 = fUU * 3.0f; - float fVV3 = fVV * 3.0f; - float fWW3 = fWW * 3.0f; - - streams.PositionWS = - float4((float3)input[0].PositionWS * fUU * fU - + (float3)input[1].PositionWS * fVV * fV - + (float3)input[2].PositionWS * fWW * fW - + input[0].nextPositionVS1 * fUU3 * fV - + input[0].nextPositionVS2 * fVV3 * fU - + input[1].nextPositionVS1 * fVV3 * fW - + input[1].nextPositionVS2 * fWW3 * fV - + input[2].nextPositionVS1 * fWW3 * fU - + input[2].nextPositionVS2 * fUU3 * fW - + constants.f3ViewB111 * 6.0f * fW * fU * fV, 1.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TessellationTest.sdsl b/sources/shaders/assets/Stride/SDSL/TessellationTest.sdsl deleted file mode 100644 index 161b4bc557..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TessellationTest.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TessellationTest -{ - patchstream float tessFactor[3] : SV_TessFactor; - patchstream float insideTessFactor : SV_InsideTessFactor; - - float test(Constants constants) - { - return constants.tessFactor[0] + constants.insideTessFactor; - } - - float test2(InputPatch input, OutputPatch output, inout Constants constants) - { - return 0.0f; - } - - float test3(InputPatch input, OutputPatch output, inout Constants constants) - { - return test2(input, output, constants); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestComputeColor.sdsl b/sources/shaders/assets/Stride/SDSL/TestComputeColor.sdsl deleted file mode 100644 index 79a70a2305..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestComputeColor.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColor -{ - float4 Compute(float4 color) - { - return color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestComputeColor2.sdsl b/sources/shaders/assets/Stride/SDSL/TestComputeColor2.sdsl deleted file mode 100644 index 4fe2cdd536..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestComputeColor2.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColor2 : ComputeColor -{ - [Color] - float4 Color; - - override float4 Compute(float4 color) - { - return Color + color * 1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestComputeColorRedirect.sdsl b/sources/shaders/assets/Stride/SDSL/TestComputeColorRedirect.sdsl deleted file mode 100644 index 6d3ff13808..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestComputeColorRedirect.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorRedirect : ComputeColor -{ - compose TestComputeColor ColorRedirect; - - override float4 Compute(float4 color) - { - return ColorRedirect.Compute(color) + color * 1; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestComputeShader.sdsl b/sources/shaders/assets/Stride/SDSL/TestComputeShader.sdsl deleted file mode 100644 index 4cfbb18e4b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestComputeShader.sdsl +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#ifndef ThreadCountX -# define ThreadCountX 10 -#endif -#ifndef ThreadCountY -# define ThreadCountY 5 -#endif -#ifndef ThreadCountZ -# define ThreadCountZ 2 -#endif - -shader TestComputeShader -{ - stage stream uint3 GroupId : SV_GroupID; - stage stream uint3 DispatchThreadId : SV_DispatchThreadID; - stage stream uint3 GroupThreadId : SV_GroupThreadID; - stage stream uint GroupIndex : SV_GroupIndex; - - stage stream uint3 ThreadGroupCount; - stage stream uint ThreadCountPerGroup; - stage stream uint ThreadGroupIndex; - - cbuffer PerDispatch { - //[Link("Stride.Effects.ComputeShaderPluginKeys.ThreadGroupCount")] - stage uint3 ThreadGroupCountGlobal; - }; - - cbuffer ParticleCountBuffer { - uint ParticleCount; - uint ParticleStartIndex; - }; - - stage RWStructuredBuffer ParticleSortBuffer; - [Link("ParticleSortBuffer")] - stage StructuredBuffer ParticleSortBufferRO; - - [numthreads(ThreadCountX, ThreadCountY, ThreadCountZ)] - void CSMain() - { - streams.ThreadCountPerGroup = ThreadCountX * ThreadCountY * ThreadCountZ; - streams.ThreadGroupCount = ThreadGroupCountGlobal; - streams.ThreadGroupIndex = (streams.GroupId.z * streams.ThreadGroupCount.y + streams.GroupId.y) * streams.ThreadGroupCount.x + streams.GroupId.x; - Compute(); - } - - void Compute() - { - ParticleSortBuffer[0] = uint2(0,1); - uint numStructs; - uint stride; - ParticleSortBufferRO.GetDimensions(numStructs, stride); - ParticleSortBuffer.IncrementCounter(); - ParticleSortBuffer.DecrementCounter(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestErrors.sdsl b/sources/shaders/assets/Stride/SDSL/TestErrors.sdsl deleted file mode 100644 index 352ad88626..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestErrors.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestErrors -{ - abstract override void test0(); // 1 error + 1 error - override void test1(); // 2 errors + 1 error - abstract void test2(){} // 1 error - - stream float myStream; - float nonStream; - - extern int falseExtern = stage; // 2 errors - - extern ExternMixin myExtern; - - void test3() - { - test3(); // cyclic error - this.testNone(); // this error + 1 type inference - test1(); // 1 error call to declaration - - streams.myStream = myStream + 1.0f; // 1 error - streams.myStream = streams.nonStream; // 2 errors - streams.myStream = stage.noMember; // stage use error + stage name error + 2 types errors - - var varVar; // 1 error - - myExtern.falseCall(); // 1 no member error + 2 function not found errors - } - - void test4() - { - base.test4(); // no base mixin + base error + 1 type inferences - } - - float test5(float param) - { - return param; - } - int test5(int param) - { - return param; - } - - float test6() - { - var varIn; // 1 error - var varOut = test5(param); // 1 var error + 2 function error - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestExternArray.sdsl b/sources/shaders/assets/Stride/SDSL/TestExternArray.sdsl deleted file mode 100644 index d1225b19c6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestExternArray.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestExternArray -{ - compose ExternMixin externArray[]; - - float test() - { - externArray[0].externFunc(); - externArray[1].externFunc(); - - float a = externArray[0].externMember + externArray[1].externMember; - - foreach (var ext in externArray) - { - ext.externFunc(); - a += ext.externMember; - } - - return a; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestGenerator.sdsl b/sources/shaders/assets/Stride/SDSL/TestGenerator.sdsl deleted file mode 100644 index 974dfaed88..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestGenerator.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader TestGenerator -{ - cbuffer ConstantBuffer - { - float TestFloat; - [Color] - float3 TestColor; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestGenericComplex.sdsl b/sources/shaders/assets/Stride/SDSL/TestGenericComplex.sdsl deleted file mode 100644 index 2519535b95..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestGenericComplex.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenericComplex -{ - float test0() - { - return TestGenericMacro.test(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestGenericMacro.sdsl b/sources/shaders/assets/Stride/SDSL/TestGenericMacro.sdsl deleted file mode 100644 index 30d55dc807..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestGenericMacro.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenericMacro -{ - float test() - { - return MACRO; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestGenerics.sdsl b/sources/shaders/assets/Stride/SDSL/TestGenerics.sdsl deleted file mode 100644 index c96d51ee3a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestGenerics.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenerics -{ - float myMember = 2.0f; - - float test() - { - return myMember + myGen; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestMacros.sdsl b/sources/shaders/assets/Stride/SDSL/TestMacros.sdsl deleted file mode 100644 index ad4ff21633..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestMacros.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMacros : PositionVertexTransform, ShadingBase -{ - compose MacroTest macros0; - compose MacroTest macros1; - compose MacroTest macros2; - - stage override void PSMain() - { - base.PSMain(); - float4 color = macros0.u * streams.ColorTarget + macros1.u * macros2.u; - streams.ColorTarget = color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestMacrosArray.sdsl b/sources/shaders/assets/Stride/SDSL/TestMacrosArray.sdsl deleted file mode 100644 index fbf4bf4b1f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestMacrosArray.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMacrosArray : PositionVertexTransform, ShadingBase -{ - compose MacroTest macrosArray[]; - - stage override void PSMain() - { - base.PSMain(); - float4 color = macrosArray[0].u * streams.ColorTarget + macrosArray[1].u * macrosArray[2].u; - streams.ColorTarget = color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestMultipleStatic.sdsl b/sources/shaders/assets/Stride/SDSL/TestMultipleStatic.sdsl deleted file mode 100644 index a3bc389325..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestMultipleStatic.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMultipleStatic -{ - compose StaticCallMixin staticExtern; - - void test() - { - StaticMixin.staticCall(); - float u = StaticMixin.staticMember; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestPixelStream.sdsl b/sources/shaders/assets/Stride/SDSL/TestPixelStream.sdsl deleted file mode 100644 index 1934dae119..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestPixelStream.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestPixelStream : TestScreenPosition -{ - stream float4 OutputColor; - - void PSMain() - { - streams.OutputColor = streams.ScreenPosition; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestScreenPosition.sdsl b/sources/shaders/assets/Stride/SDSL/TestScreenPosition.sdsl deleted file mode 100644 index 64bf3fc629..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestScreenPosition.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestScreenPosition -{ - stream float4 ScreenPosition; -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestStream.sdsl b/sources/shaders/assets/Stride/SDSL/TestStream.sdsl deleted file mode 100644 index 295f9f3e98..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestStream.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStream : ShaderBase -{ - stage stream float2 Position : POSITION; - stage stream float blend; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - var backup = streams; - Toto(backup); - - streams.ColorTarget = float4(streams.Position, 0, 1); - } - - - void Toto(Streams backup) - { - streams.Position = lerp(streams.Position, backup.Position, backup.blend); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestStreams.sdsl b/sources/shaders/assets/Stride/SDSL/TestStreams.sdsl deleted file mode 100644 index 27b2b8ebc6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestStreams.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStreams : TestVertexStream, TestPixelStream -{ - void test0(Input input) - { - streams = input; - float4 a = streams.Position; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestStructInheritance.sdsl b/sources/shaders/assets/Stride/SDSL/TestStructInheritance.sdsl deleted file mode 100644 index e1e3303443..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestStructInheritance.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStructInheritance : TestStructure -{ - myStruct member; - - float test2() - { - return member.structFloat; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestStructure.sdsl b/sources/shaders/assets/Stride/SDSL/TestStructure.sdsl deleted file mode 100644 index 90a066bd71..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestStructure.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStructure -{ - struct myStruct - { - float structFloat; - }; - - float test(myStruct param) - { - return param.structFloat; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TestVertexStream.sdsl b/sources/shaders/assets/Stride/SDSL/TestVertexStream.sdsl deleted file mode 100644 index ca183348e1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TestVertexStream.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestVertexStream : TestScreenPosition -{ - stream float4 Position; - - void VSMain() - { - // TODO: remove extra code for this type check (float * floatX) - streams.ScreenPosition = 2.0*streams.Position; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TextureProjectionCommon.sdsl b/sources/shaders/assets/Stride/SDSL/TextureProjectionCommon.sdsl deleted file mode 100644 index 949927b884..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TextureProjectionCommon.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines the texture that is projected onto geometry. - /// - shader TextureProjectionCommon - { - cbuffer PerLightGroup - { - [Link("TextureProjection.UVScale")] // Defined in "TextureProjectionKeys". - float2 UVScale; - - [Link("TextureProjection.UVOffset")] // Defined in "TextureProjectionKeys". - float2 UVOffset; - } - - rgroup PerLightGroup - { - [Link("TextureProjection.ProjectionTexture")] // Defined in "TextureProjectionKeys". - Texture2D ProjectionTexture; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl b/sources/shaders/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl deleted file mode 100644 index 9ac0e20ba1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TextureProjectionFilterDefault.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Filters the texture projected by a light using a linear sampler at the specified mip map level. - /// - /// - /// PerLightGroup: Parameter used to uniquely identify this group of lights. - /// - internal shader TextureProjectionFilterDefault : - TextureProjectionCommon, // Defines "ProjectionTexture". - Texturing // Defines "LinearSampler". - { - // Filters the projected texture using a linear sampler at the specified mip map level. - float3 FilterProjectedTexture(float2 textureCoordinate, float mipMapLevel) - { - return ProjectionTexture.SampleLevel(LinearSampler, textureCoordinate * UVScale + UVOffset, mipMapLevel).rgb; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/TextureProjectionGroup.sdsl b/sources/shaders/assets/Stride/SDSL/TextureProjectionGroup.sdsl deleted file mode 100644 index 44d82daba8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TextureProjectionGroup.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Defines a base function for calculating the color of a texture projected by a light onto a world space position. - /// Based on whether or not the light has texture projection enabled, this function will be overridden by one that computes the projection. - /// - shader TextureProjectionGroup - { - // Computes the color of the projected texture for a given world position and light index - float3 ComputeTextureProjection(float3 positionWS, int lightIndex) - { - return 1.0f; - } - - // Computes a reflection of the texture projector - float3 ComputeSpecularTextureProjection(float3 positionWS, float3 reflectionWS, int lightIndex) - { - return 1.0f; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl b/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl deleted file mode 100644 index f172e97466..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverBase.sdsl +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Base class for computing texture projection for a light. Defines functions for computing the color of the projected texture at this world space position. - /// - /// - /// PerLightGroup: Parameter used to uniquely identify this group of lights. - /// TCascadeCountBase: The number of cascades of the current light. - /// TLightCountBase: The number of lights inside of this light group. - /// - internal shader TextureProjectionReceiverBase : // TODO: Rename to "TextureProjectionReceiver". - TextureProjectionCommon, // Required for accessing the texture that is projected. - TextureProjectionFilterDefault, // Defines "FilterProjectedTexture()". - Texturing // Required for the texture sampling. - { - // Enum values for the texture flip mode: - // These values have to match the ones defined in "LightSpot.cs". - const int FlipModeNone = 0; - const int FlipModeX = 1; - const int FlipModeY = 2; - const int FlipModeXY = 3; - ///////////////////////////////////////////////////////////////// - - cbuffer PerLightGroup - { - float4x4 WorldToProjectiveTextureUV[TCascadeCountBase * TLightCountBase]; - float4x4 ProjectorPlaneMatrices[TCascadeCountBase * TLightCountBase]; // Contains the world matrix of the projector plane. Required for ray-plane intersection testing. - float ProjectionTextureMipMapLevels[TLightCountBase]; // TODO: Not sure how to handle this in combination with cascades. - float TransitionAreas[TLightCountBase]; - }; - - /* - // Returns "1.0" if "point" is inside the box defined by "bottomLeft" and "topRight". Returns "0.0" otherwise. - // This function was taken from here: http://stackoverflow.com/questions/12751080/glsl-point-inside-box-test - float InsideOfRectangle(float2 p, float2 bottomLeft, float2 topRight) - { - float2 s = step(bottomLeft, p) - step(topRight, p); - return(s.x * s.y); - } - */ - - // The "transitionArea" parameter defines the size of the transition area between inside and outside the rectangle. - // The transition is faded inside the rectangle, not outside of it. - // NOTE: The "transitionArea" parameter must be smaller than the distance between "bottomLeft" and "topRight" (in each dimension). - // More information: http://stackoverflow.com/questions/12751080/glsl-point-inside-box-test - float insideOfRectangleSmooth(float2 p, float2 bottomLeft, float2 topRight, float transitionArea) - { - float2 s = smoothstep(bottomLeft, bottomLeft + transitionArea, p) - - smoothstep(topRight - transitionArea, topRight, p); - return(s.x * s.y); - } - - float CalculateRectangularMask(float2 projectedTextureCoordinate, float clipSpaceZ, float transitionArea) - { - // Mask the projection at the edges of the frustum: - //float mask = InsideOfRectangle(projectedTextureCoordinate, 0.0f, 1.0f); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. - float mask = insideOfRectangleSmooth(projectedTextureCoordinate, 0.0f, 1.0f, transitionArea); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. - - // Now mask the back projection, because we don't want any texture on the back of the light: - // TODO: PERFORMANCE: Profile performance difference between branching and masking the back projection. - //if(clipSpaceCoordinate.z < 0.0f) - //{ - // return float3(0.0f, 0.0f, 0.0f); - //} - - // Same as the above but branchless: - mask *= step(0.0f, clipSpaceZ); // If clipSpaceCoordinate.z >= 0.0f, return 1.0f. Otherwise return 0.0f. // TODO: Maybe we should move this to the light attenuation code. - - return mask; - } - - void ModifyTextureCoordinate(inout float2 textureCoordinate) - { - if(TFlipMode == FlipModeX || TFlipMode == FlipModeXY) - { - textureCoordinate.x = 1.0f - textureCoordinate.x; - } - - if(TFlipMode == FlipModeY || TFlipMode == FlipModeXY) - { - textureCoordinate.y = 1.0f - textureCoordinate.y; - } - } - - // Implemented according to "http://geomalgorithms.com/a06-_intersect-2.html". - bool IntersectPlane(float3 rayOrigin, float3 rayDirection, float3 planeNormal, float3 planeOrigin, out float3 pointOfIntersection) - { - const float epsilon = 0.001f; - - float planeDotRayOrigin = dot(planeNormal, planeOrigin - rayOrigin); - float planeDotRayDirection = dot(planeNormal, rayDirection); - - if((planeDotRayDirection > -epsilon)&&(planeDotRayDirection < epsilon)) // The ray is (almost) parallel to the plane. No intersection is possible: - { - return(false); - } - - /* - When the denominator n_dot_(P1-P0)=0, the line L is parallel to the plane P, - and thus either does not intersect it or else lies completely in the plane - (whenever either P0 or P1 is in P ). - Otherwise, when the denominator is nonzero and rI is a real number, - then the ray R intersects the plane P only when rI.ge.0. - A segment S intersects P only if rI.ge-0.le-1. - In all algorithms, the additional test rI.le.1 is the only difference for a segment instead of a ray. - */ - - float intersectionDistance = planeDotRayOrigin / planeDotRayDirection; - - if(intersectionDistance >= 0.0f) // TODO: Remove branch? - { - pointOfIntersection = rayOrigin + rayDirection * intersectionDistance; - return(true); - } - - return(false); - } - - // Computes a reflection fo the texture projector the world position "positionWS". - float3 ComputeSpecularTextureProjectionFromCascade(float3 positionWS, float3 reflectionWS, int cascadeIndex, int lightIndex) - { - int matrixIndex = cascadeIndex + lightIndex * TCascadeCountBase; - - float3 rayOrigin = positionWS; - float3 rayDirection = reflectionWS; - - float4x4 projectorPlaneMatrix = ProjectorPlaneMatrices[matrixIndex]; - float3 planeAxisX = float3(projectorPlaneMatrix._m00, projectorPlaneMatrix._m01, projectorPlaneMatrix._m02); - float3 planeAxisY = float3(projectorPlaneMatrix._m10, projectorPlaneMatrix._m11, projectorPlaneMatrix._m12); - float3 planeNormal = float3(projectorPlaneMatrix._m20, projectorPlaneMatrix._m21, projectorPlaneMatrix._m22); // Z axis - float3 planeOrigin = float3(projectorPlaneMatrix._m30, projectorPlaneMatrix._m31, projectorPlaneMatrix._m32); // Position/Origin - - float3 pointOfIntersection; - bool intersectionFound = IntersectPlane(rayOrigin, rayDirection, planeNormal, planeOrigin, pointOfIntersection); - - if(intersectionFound) // TODO: PERFORMANCE: Branch or just mask the result? - { - float mipMapLevel = ProjectionTextureMipMapLevels[lightIndex]; - float transitionArea = TransitionAreas[lightIndex]; - - float planeWidth = length(planeAxisX); - float planeHeight = length(planeAxisY); - - // Project the intersection point to plane space: - float3 planeOriginToPointOfIntersection = pointOfIntersection - planeOrigin; - float planeSpaceX = dot(planeOriginToPointOfIntersection, planeAxisX) / planeWidth; - float planeSpaceY = dot(planeOriginToPointOfIntersection, planeAxisY) / planeHeight; - - // Normalize the plane space coordinates: - float2 planeTextureCoordinate = float2(planeSpaceX, planeSpaceY) * 0.5f / float2(planeWidth, planeHeight) + 0.5f; - //planeTextureCoordinate = 1.0f - planeTextureCoordinate; - - //float planeReflectionMask = insideOfRectangleSmooth(planeTextureCoordinate, 0.0f, 1.0f, transitionArea); // TODO: Move the mask to the light attenuation code? It would be cleaner but also more difficult, because we don't have the texture coordinates there. - float planeReflectionMask = CalculateRectangularMask(planeTextureCoordinate, - dot(planeNormal, rayDirection), // Pass dot product instead of clip space z, because all we need is a negative value to mask out he back side. - transitionArea); - - return FilterProjectedTexture(planeTextureCoordinate, mipMapLevel) * planeReflectionMask; - - } - - return 0.0f; - } - - // Computes the color of the projected texture at the world position "positionWS". - float3 ComputeTextureProjectionFromCascade(float3 positionWS, int cascadeIndex, int lightIndex) - { - int matrixIndex = cascadeIndex + lightIndex * TCascadeCountBase; - - float4 clipSpaceCoordinate = mul(float4(positionWS, 1.0), WorldToProjectiveTextureUV[matrixIndex]); - float2 projectedTextureCoordinate = clipSpaceCoordinate.xy / clipSpaceCoordinate.w; // W-divide because it's a projection matrix. - projectedTextureCoordinate.xy = projectedTextureCoordinate.xy * 0.5 + 0.5; // Offset the clip space coordinates from [-1.0 ... 1.0] to [0.0 ... 1.0]. - projectedTextureCoordinate.y = 1.0f - projectedTextureCoordinate.y; - - ModifyTextureCoordinate(projectedTextureCoordinate); - - // TODO: PERFORMANCE: Using a texture border and setting the wrapping mode to "clamp" would be faster. Not sure if that would be a possibility though. - float mipMapLevel = ProjectionTextureMipMapLevels[lightIndex]; - float transitionArea = TransitionAreas[lightIndex]; - float mask = CalculateRectangularMask(projectedTextureCoordinate, clipSpaceCoordinate.z, transitionArea); - return FilterProjectedTexture(projectedTextureCoordinate, mipMapLevel) * mask; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl b/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl deleted file mode 100644 index 4ab863d30f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TextureProjectionReceiverSpot.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Lights -{ - /// - /// Computes the texture projection of a spotlight. Returns the color of the projected texture at this world space position. - /// - /// - /// PerLightGroup: Parameter used to uniquely identify this group of lights. - /// TLightCount: The number of lights inside of this light group. - /// - internal shader TextureProjectionReceiverSpot : - TextureProjectionGroup, // Defines "ComputeTextureProjection()", which this shader overrides. - TextureProjectionReceiverBase // Defines "CalculateTextureProjectionFromCascade()". - { - override float3 ComputeTextureProjection(float3 positionWS, int lightIndex) - { - return ComputeTextureProjectionFromCascade(positionWS, 0, lightIndex); // Spotlights have only one cascade, so we hardcode the cascade index to zero. - } - - override float3 ComputeSpecularTextureProjection(float3 positionWS, float3 reflectionWS, int lightIndex) - { - return ComputeSpecularTextureProjectionFromCascade(positionWS, reflectionWS, 0, lightIndex); // Spotlights have only one cascade, so we hardcode the cascade index to zero. - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Texturing.sdsl b/sources/shaders/assets/Stride/SDSL/Texturing.sdsl deleted file mode 100644 index 4f201a2c8f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Texturing.sdsl +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Texturing -{ - // Default texture slots - might be automatically used by the material - stage Texture2D Texture0; - stage float2 Texture0TexelSize; - stage Texture2D Texture1; - stage float2 Texture1TexelSize; - stage Texture2D Texture2; - stage float2 Texture2TexelSize; - stage Texture2D Texture3; - stage float2 Texture3TexelSize; - stage Texture2D Texture4; - stage float2 Texture4TexelSize; - stage Texture2D Texture5; - stage float2 Texture5TexelSize; - stage Texture2D Texture6; - stage float2 Texture6TexelSize; - stage Texture2D Texture7; - stage float2 Texture7TexelSize; - stage Texture2D Texture8; - stage float2 Texture8TexelSize; - stage Texture2D Texture9; - stage float2 Texture9TexelSize; - - // Default texture cube slots - stage TextureCube TextureCube0; - stage TextureCube TextureCube1; - stage TextureCube TextureCube2; - stage TextureCube TextureCube3; - - // Default texture 3D slots - stage Texture3D Texture3D0; - stage Texture3D Texture3D1; - stage Texture3D Texture3D2; - stage Texture3D Texture3D3; - - // Default sampler - stage SamplerState Sampler; - - stage SamplerState PointSampler - { - Filter = MIN_MAG_MIP_POINT; - }; - - stage SamplerState LinearSampler - { - Filter = MIN_MAG_MIP_LINEAR; - }; - - stage SamplerState LinearBorderSampler - { - Filter = MIN_MAG_MIP_LINEAR; - AddressU = Border; - AddressV = Border; - }; - - stage SamplerComparisonState LinearClampCompareLessEqualSampler - { - Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT; - AddressU = Clamp; - AddressV = Clamp; - ComparisonFunc = LessEqual; - - }; - - stage SamplerState AnisotropicSampler - { - Filter = ANISOTROPIC; - }; - - stage SamplerState AnisotropicRepeatSampler - { - Filter = ANISOTROPIC; - AddressU = Wrap; - AddressV = Wrap; - MaxAnisotropy = 16; - }; - - stage SamplerState PointRepeatSampler - { - Filter = MIN_MAG_MIP_POINT; - AddressU = Wrap; - AddressV = Wrap; - }; - - stage SamplerState LinearRepeatSampler - { - Filter = MIN_MAG_MIP_LINEAR; - AddressU = Wrap; - AddressV = Wrap; - }; - - stage SamplerState RepeatSampler - { - AddressU = Wrap; - AddressV = Wrap; - }; - - // Default custom samplers - might be automatically used by the materials - stage SamplerState Sampler0; - stage SamplerState Sampler1; - stage SamplerState Sampler2; - stage SamplerState Sampler3; - stage SamplerState Sampler4; - stage SamplerState Sampler5; - stage SamplerState Sampler6; - stage SamplerState Sampler7; - stage SamplerState Sampler8; - stage SamplerState Sampler9; - - // Texcoord attribute inputs - stage stream float2 TexCoord : TEXCOORD0; - stage stream float2 TexCoord1 : TEXCOORD1; - stage stream float2 TexCoord2 : TEXCOORD2; - stage stream float2 TexCoord3 : TEXCOORD3; - stage stream float2 TexCoord4 : TEXCOORD4; - stage stream float2 TexCoord5 : TEXCOORD5; - stage stream float2 TexCoord6 : TEXCOORD6; - stage stream float2 TexCoord7 : TEXCOORD7; - stage stream float2 TexCoord8 : TEXCOORD8; - stage stream float2 TexCoord9 : TEXCOORD9; -}; diff --git a/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl b/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl deleted file mode 100644 index cebf4b907b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoC.sdsl +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Makes front-objects transparent for the back out-of-focus area. - /// - shader ThresholdAlphaCoC: ImageEffectShader - { - // Previous CoC value (lower level) - float CoCReference; - - // Current CoC value - float CoCCurrent; - - // the epsilon is 0.5% of the -1;1 range of the CoC, which is enough to fix the problem of largely foreground objects getting selected as background. - static const float CoCCompareEpsilon = 0.01; - - stage override float4 Shading() - { - float4 color = Texture0.Sample(Sampler, streams.TexCoord).rgba; - - float4 result = color; - - float minCoC = Texture1.Sample(Sampler, streams.TexCoord).x; - - // To sample multiple neighbors - /* - float neighborCoC[5]; - - neighborCoC[0] = Texture1.Sample(Sampler, streams.TexCoord).x; - neighborCoC[1] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, 1)).x; - neighborCoC[2] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, -1)).x; - neighborCoC[3] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(1,0)).x; - neighborCoC[4] = Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(-1, 0)).x; - - float minCoC = 1; - [unroll] - for (int i = 0; i < 5; i++) - { - minCoC = min(minCoC, neighborCoC[i]); - } - */ - - // Front-objects are made transparent. & use an epsilon to give slack to the compare operator - if (minCoC < CoCReference + CoCCompareEpsilon) - { - - if (CoCReference > 0) - { - // Keep a "ghost" of the bleeding front object. - // The closest to our level, the more visible. - result.a = saturate ( lerp(0, 1, minCoC / CoCReference) ); - } - else - { - result.a = 0.0; - } - } - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl b/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl deleted file mode 100644 index c306650a9c..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ThresholdAlphaCoCFront.sdsl +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Makes back-objects transparent for the front out-of-focus area. - /// - shader ThresholdAlphaCoCFront: ImageEffectShader - { - - // Previous CoC value (higher level in the negative values) - float CoCReference; - - // Current CoC value - float CoCCurrent; - - stage override float4 Shading() - { - float4 color = Texture0.Sample(Sampler, streams.TexCoord).rgba; - - float4 result = color; - - float minCoC = - Texture1.Sample(Sampler, streams.TexCoord).x; - - // To sample multiple neighbors - /* - float neighborCoC[5]; - - neighborCoC[0] = - Texture1.Sample(Sampler, streams.TexCoord).x; - neighborCoC[1] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, 1)).x; - neighborCoC[2] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(0, -1)).x; - neighborCoC[3] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(1,0)).x; - neighborCoC[4] = - Texture1.Sample(Sampler, streams.TexCoord + Texture0TexelSize * float2(-1, 0)).x; - - float minCoC = 1; - [unroll] - for (int i = 0; i < 1; i++) - { - minCoC = min(minCoC, neighborCoC[i]); - } - */ - - // Pixel higher than the current CoC level will be opaque. - // Under the CoC of the previous pass, completely transparent. - // Between the two CoC, lerp. - float range = CoCCurrent - CoCReference; - result.a = saturate( lerp(0, 1, (minCoC - CoCReference) / range ) ); - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToGlslShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToGlslShader.sdsl deleted file mode 100644 index 7f63bf41fd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToGlslShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ToGlslShader : ShaderBase, Texturing -{ - stage stream float2 Position : POSITION; - - float4 BaseColor; - - float TestArray[4]; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor*TestArray[0]*TestArray[1] + Texture0.Sample(PointRepeatSampler, streams.Position); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl deleted file mode 100644 index 44238e6259..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapACESOperatorShader.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The ACES tonemap operator. - /// - internal shader ToneMapACESOperatorShader : ToneMapCommonOperatorShader - { - // ACES filmic tonemapper with highlight desaturation ("crosstalk"). - // Based on the curve fit by Krzysztof Narkowicz. - // https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ - - override float4 Compute(float4 color) - { - float pixelLuminance = LuminanceUtils.Luma(color); - - // ACES Tonemapper - const float a = 2.51f; - const float b = 0.03f; - const float c = 2.43f; - const float d = 0.59f; - const float e = 0.14f; - - float toneMappedLuminance = (pixelLuminance * (a * pixelLuminance + b)) / (pixelLuminance * (c * pixelLuminance + d) + e); - float whiteLuminance = (WhiteLevel * (a * WhiteLevel + b)) / (WhiteLevel * (c * WhiteLevel + d) + e); - return toneMappedLuminance / whiteLuminance * pow(color / pixelLuminance, LuminanceSaturation); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl deleted file mode 100644 index e17a49d894..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapCommonOperatorShader.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The common tonemap operator used by Reinhard, Drago, Exponential, Logarithmic. Just define common variables - /// - internal shader ToneMapCommonOperatorShader : ToneMapOperatorShader - { - float LuminanceSaturation = 1.0f; - float WhiteLevel = 5.0f; - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl deleted file mode 100644 index 9a4c4bdce1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapDragoOperatorShader.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The Drago tonemap operator. - /// - internal shader ToneMapDragoOperatorShader : ToneMapCommonOperatorShader - { - float DragoBias = 0.5f; - - override float4 Compute(float4 color) - { - float pixelLuminance = LuminanceUtils.Luma(color); - float toneMappedLuminance = log10(1 + pixelLuminance); - toneMappedLuminance /= log10(1 + WhiteLevel); - toneMappedLuminance /= log10(2 + 8 * ((pixelLuminance / WhiteLevel) * log10(DragoBias) / log10(0.5f))); - return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl deleted file mode 100644 index a52b444e1e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapExponentialOperatorShader.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The logarithmic tonemap operator. - /// - internal shader ToneMapExponentialOperatorShader : ToneMapCommonOperatorShader - { - override float4 Compute(float4 color) - { - float pixelLuminance = LuminanceUtils.Luma(color); - float toneMappedLuminance = 1 - exp(-pixelLuminance / WhiteLevel); - return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl deleted file mode 100644 index 2b5a89e145..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapHejl2OperatorShader.sdsl +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The tonemap operator by Jim Hejl version 2 that does not include the gamma correction and has a whitepoint parameter. - /// - /// - /// https://twitter.com/jimhejl/status/633777619998130176 - /// - internal shader ToneMapHejl2OperatorShader : ToneMapOperatorShader - { - float WhitePoint = 5.0f; - - override float4 Compute(float4 color) - { - // Workaround for Huawei Mate 9 Pro (Mali) GLSL bug - float w = (1.425 * WhitePoint) + 0.05f; - w = ((WhitePoint * w + 0.004f) / ((WhitePoint * (w + 0.55f) + 0.0491f))) - 0.0821f; - - float4 vh = float4(color.rgb, WhitePoint); - float4 va = (1.425 * vh) + 0.05f; // eval filmic curve - float4 vf = ((vh * va + 0.004f) / ((vh * (va + 0.55f) + 0.0491f))) - 0.0821f; - return float4(vf.rgb / w, 1.0); // white point correction - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl deleted file mode 100644 index a85de5124e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapHejlDawsonOperatorShader.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The tonemap operator by Jim Hejl and Richard Burgess-Dawson. - /// - /// - /// http://filmicgames.com/archives/75 - /// - internal shader ToneMapHejlDawsonOperatorShader : ToneMapOperatorShader - { - override float4 Compute(float4 color) - { - color = max(0,color-0.004); - color = (color*(6.2*color+.5))/(color*(6.2*color+1.7)+0.06); - // TODO: Reverts the gamma correction which was automatically applied by the formula - // TODO: Refit the curve without gamma correction - float3 linearColor = pow(color.rgb, 2.2); - return float4(linearColor, 1.0); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl deleted file mode 100644 index 1c7a924954..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapLogarithmicOperatorShader.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The logarithmic tonemap operator. - /// - internal shader ToneMapLogarithmicOperatorShader : ToneMapCommonOperatorShader - { - override float4 Compute(float4 color) - { - float pixelLuminance = LuminanceUtils.Luma(color); - float toneMappedLuminance = log10(1 + pixelLuminance) / log10(1 + WhiteLevel); - return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl deleted file mode 100644 index 707d711eec..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapMikeDayOperatorShader.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The tonemap operator from Mike Day, Insomniac Games. - /// - /// - /// https://d3cw3dd2w32x2b.cloudfront.net/wp-content/uploads/2012/09/an-efficient-and-user-friendly-tone-mapping-operator.pdf - /// - internal shader ToneMapMikeDayOperatorShader : ToneMapOperatorShader - { - float4 ToeCoeffs; - float4 ShoulderCoeffs; - float MiddleCrossOver; - - float Remap(float x) - { - float4 coeffs = (x < MiddleCrossOver) ? ToeCoeffs : ShoulderCoeffs; - float2 fraction = coeffs.xy * x + coeffs.zw; - return fraction.x / fraction.y; - } - - override float4 Compute(float4 color) - { - return float4(Remap(color.r), Remap(color.g), Remap(color.b), color.a); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapOperatorShader.sdsl deleted file mode 100644 index 1b4c84f4fe..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapOperatorShader.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A generic interface for computing a tonemap operator. - /// - shader ToneMapOperatorShader : ColorTransformShader - { - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl deleted file mode 100644 index b857e6c795..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapReinhardOperatorShader.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The Reinhard tonemap operator. - /// - internal shader ToneMapReinhardOperatorShader : ToneMapCommonOperatorShader - { - override float4 Compute(float4 color) - { - float pixelLuminance = LuminanceUtils.Luma(color); - // TODO add version: toneMappedLuminance = pixelLuminance / (1.0f + pixelLuminance); - float toneMappedLuminance = pixelLuminance * (1.0f + pixelLuminance / (WhiteLevel * WhiteLevel)) / (1.0f + pixelLuminance); - return toneMappedLuminance * pow(color / pixelLuminance, LuminanceSaturation); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapShader.sdsl deleted file mode 100644 index 59dc3e3668..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapShader.sdsl +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// A tonemap shader - /// - internal shader ToneMapShader : ColorTransformShader, Texturing - { - // Luminance texture - Texture2D LuminanceTexture; - - // Exposure - float KeyValue = 0.18f; - float LuminanceLocalFactor = 0.0f; - float LuminanceAverageGlobal; - - // Color/Gamma correction - float Contrast = 0.0f; - float Brightness = 0.0f; - float Exposure = 1.0f; - - // ToneMap Operator - [Link("ToneMap.Operator")] - compose ToneMapOperatorShader ToneMapOperator; - - override float4 Compute(float4 inputColor) - { - // Get the input color to tonemap - float3 color = inputColor.rgb; - - // Code based on Matt Pettineo: https://mynameismjp.wordpress.com/2010/04/30/a-closer-look-at-tone-mapping/ - // Use local luminance slightly differently to allow mix between local and global - - // Gets the local luminance - float avgLuminance = LuminanceAverageGlobal; - if (TUseLocalLuminance) - { - float luminanceAverageLocal = LuminanceTexture.Sample(Texturing.LinearSampler, streams.TexCoord).r; - - // Calculate average geometric mean for luminance using local and global average luminances - avgLuminance = lerp(avgLuminance, luminanceAverageLocal, LuminanceLocalFactor); - } - avgLuminance = exp2(avgLuminance); - avgLuminance = max(avgLuminance, 0.0001f); - - // Apply brightness and contrast - float globalAverageLum = exp2(LuminanceAverageGlobal); - color = max(color + globalAverageLum.xxx * Brightness, 0.0001); - color = max(lerp(globalAverageLum.xxx, color, Contrast + 1.0f), 0.0001); - - // Apply ToneMapping - color = ToneMap(color, avgLuminance); - - return float4(color, inputColor.a); - } - - float CalculateExposure(float avgLuminance) - { - float exposure; - if (TAutoExposure) - { - float keyValue; - if (TAutoKeyValue) - { - keyValue = 1.03f - (2.0f / (2 + log10(avgLuminance + 1))); - } - else - { - keyValue = KeyValue; - } - float linearExposure = (keyValue / avgLuminance); - exposure = max(linearExposure, 0.0001f); - } - else - { - exposure = Exposure; - } - return exposure; - } - - float3 ToneMap(float3 color, float avgLuminance) - { - float exposure = CalculateExposure(avgLuminance); - color *= exposure; - color = ToneMapOperator.Compute(float4(color,1)).rgb; - return color; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl b/sources/shaders/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl deleted file mode 100644 index fe2d6c3f8d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/ToneMapU2FilmicOperatorShader.sdsl +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// The U2Filmic tonemap operator. - /// - internal shader ToneMapU2FilmicOperatorShader : ToneMapOperatorShader - { - float ShoulderStrength = 0.22f; - float LinearStrength = 0.25f; - float LinearAngle = 0.1f; - float ToeStrength = 0.2f; - float ToeNumerator = 0.01f; - float ToeDenominator = 0.3f; - float LinearWhite = 11.2f; - - // Function used by the Uncharted2 tone mapping curve - float3 U2Func(float3 x) - { - float A = ShoulderStrength; - float B = LinearStrength; - float C = LinearAngle; - float D = ToeStrength; - float E = ToeNumerator; - float F = ToeDenominator; - return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F)) - E/F; - } - - override float4 Compute(float4 color) - { - // Applies the Uncharted 2 filmic tone mapping curve - float3 numerator = U2Func(color.rgb); - float3 denominator = U2Func(LinearWhite); - - return float4(numerator / denominator, 1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Transformation.sdsl b/sources/shaders/assets/Stride/SDSL/Transformation.sdsl deleted file mode 100644 index e85458426f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Transformation.sdsl +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Transformation -{ - cbuffer PerView { - // View matrix. Default to Matrix.Identity. - stage float4x4 View; - // Inverse View matrix. Default to Matrix.Inverse(View) - stage float4x4 ViewInverse; - // Projection matrix. Default to Matrix.Identity. - stage float4x4 Projection; - // Projection matrix. Default to Matrix.Inverse(Projection). - stage float4x4 ProjectionInverse; - // ViewProjection matrix. Default to = View * Projection. - stage float4x4 ViewProjection; - // Screen projected ray vector. Default to = new Vector2(-1.0f / Projection.M11, 1.0f / Projection.M22); - stage float2 ProjScreenRay; - // Eye vector. Default to = View^-1[M41,M42,M43,1.0] - stage float4 Eye; - }; - - cbuffer PerDraw { - // World matrix. Default to Matrix.Identity. - stage float4x4 World; - } - cbuffer PerDraw { - // Inverse World matrix. Default to Matrix.Inverse(World). - stage float4x4 WorldInverse; - // Inverse Transpose World matrix. Default to Matrix.Transpose(Matrix.Inverse(World)). - stage float4x4 WorldInverseTranspose; - // WorldView matrix. Default to = World * View. - stage float4x4 WorldView; - // Inverse WorldView matrix. Default to Matrix.Inverse(WorldView) - stage float4x4 WorldViewInverse; - // WorldViewProjection matrix. Default to = World * ViewProjection. - stage float4x4 WorldViewProjection; - // The scale of the World. Default to Vector2.One. - stage float3 WorldScale; - // Eye vector in model space. Default to = (World*View)^-1[M41,M42,M43,1.0] - stage float4 EyeMS; - }; -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationBase.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationBase.sdsl deleted file mode 100644 index 4e64b78b0a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationBase.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Defines the 3 transformations steps used in the pipeline. -/// The first is performed at the end of the VS. -/// The second is performed after the tessellation. -/// The third is performed at the end of the geometry pipeline. -/// -shader TransformationBase : ShaderBase -{ - // End of the VS (usually skinning) - stage void PreTransformPosition() {} - - // End of tessellation (usually displacement mapping in world space, etc...) - stage void TransformPosition() {} - - // At the end of the geometry pipeline (to generate ShadingPosition) - stage void PostTransformPosition() {} - - // Used in cases where a shading position needs to be calculated from a given world position - // for example: in tesselation, which needs to determine the triangle size on the screen - stage float4 ComputeShadingPosition(float4 world) { return 0; } - - stage void BaseTransformVS() - { - this.PreTransformPosition(); - this.TransformPosition(); - this.PostTransformPosition(); - } - - stage override void VSMain() - { - base.VSMain(); - this.BaseTransformVS(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationBendWorld.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationBendWorld.sdsl deleted file mode 100644 index 5f77176a86..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationBendWorld.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader TransformationBendWorld : TransformationBase, PositionStream4 -{ - cbuffer PerDraw - { - // Adjusting Parameters - stage float DeformFactorX = -0.001f; - stage float DeformFactorY = -0.0006f; - } - - stage override void PreTransformPosition() - { - base.PreTransformPosition(); - - // Deform Y - streams.PositionWS.y += DeformFactorY * streams.PositionWS.z * streams.PositionWS.z; - // Deform X - streams.PositionWS.x += DeformFactorX * streams.PositionWS.z * streams.PositionWS.z; - } - -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationInstancing.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationInstancing.sdsl deleted file mode 100644 index 11c75b3c5f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationInstancing.sdsl +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#ifndef ModelTransformUsage -# define ModelTransformUsage 0 -#endif - -shader TransformationInstancing : TransformationBase, Transformation -{ - struct InstanceTransform - { - float4x4 Matrix; - }; - - rgroup PerDraw.Instancing - { - stage StructuredBuffer InstanceWorld; - stage StructuredBuffer InstanceWorldInverse; - } - - float4x4 GetInstanceWorld(uint instanceId) - { -#if ModelTransformUsage == 0 - return InstanceWorld[instanceId].Matrix; -#elif ModelTransformUsage == 1 - return mul(Transformation.World, InstanceWorld[instanceId].Matrix); -#else - return mul(InstanceWorld[instanceId].Matrix, Transformation.World); -#endif - } - - float4x4 GetInstanceWorldInverse(uint instanceId) - { -#if ModelTransformUsage == 0 - return InstanceWorldInverse[instanceId].Matrix; -#elif ModelTransformUsage == 1 - return mul(InstanceWorldInverse[instanceId].Matrix, Transformation.WorldInverse); -#else - return mul(Transformation.WorldInverse, InstanceWorldInverse[instanceId].Matrix); -#endif - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationMatrix.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationMatrix.sdsl deleted file mode 100644 index a9b3f9b4c3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationMatrix.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Transform the position of the vertex with the given matrix. -/// -/// -/// TRANSFORMATION_MATRIX: generic float4x4 - The transformation matrix. -/// -shader TransformationMatrix : TransformationBase, PositionStream4, PositionHStream4 -{ - stage override void PostTransformPosition() - { - base.PostTransformPosition(); - streams.ShadingPosition = mul(streams.Position, TRANSFORMATION_MATRIX); - streams.PositionH = streams.ShadingPosition; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationSkinning.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationSkinning.sdsl deleted file mode 100644 index fa8543914d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationSkinning.sdsl +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Performs skinning on the position. -/// -/// -/// SkinningMaxBones: Macro - number of threads on the X axis. -/// -#ifndef SkinningMaxBones -# define SkinningMaxBones 4 -#endif - -shader TransformationSkinning : TransformationBase, PositionStream4, Transformation -{ - cbuffer PerDraw - { - // TODO switch to float4x3 in a way compatible with ES 2.0 - stage float4x4 BlendMatrixArray[SkinningMaxBones]; - } - - stage stream float4 BlendWeights : BLENDWEIGHT; - stage stream uint4 BlendIndices : BLENDINDICES; - - stage stream float4x4 skinningBlendMatrix; - - float4x4 GetBlendMatrix(int index) - { - return BlendMatrixArray[index]; - } - - override stage void PreTransformPosition() - { - base.PreTransformPosition(); - - streams.skinningBlendMatrix = GetBlendMatrix(streams.BlendIndices[0]) * streams.BlendWeights[0] - + GetBlendMatrix(streams.BlendIndices[1]) * streams.BlendWeights[1] - + GetBlendMatrix(streams.BlendIndices[2]) * streams.BlendWeights[2] - + GetBlendMatrix(streams.BlendIndices[3]) * streams.BlendWeights[3]; - float4 blendPos = mul(float4(streams.Position.xyz, 1.0f), streams.skinningBlendMatrix); - blendPos /= blendPos.w; - streams.PositionWS = blendPos; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl deleted file mode 100644 index 3f46534d68..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationSkinningInstanced.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TransformationSkinningInstanced : TransformationSkinning, TransformationInstancing -{ - override stage void PreTransformPosition() - { - base.PreTransformPosition(); - - streams.skinningBlendMatrix = GetBlendMatrix(streams.BlendIndices[0]) * streams.BlendWeights[0] - + GetBlendMatrix(streams.BlendIndices[1]) * streams.BlendWeights[1] - + GetBlendMatrix(streams.BlendIndices[2]) * streams.BlendWeights[2] - + GetBlendMatrix(streams.BlendIndices[3]) * streams.BlendWeights[3]; - - // Put back to object space - streams.skinningBlendMatrix = mul(streams.skinningBlendMatrix, Transformation.WorldInverse); - - // Apply instance transformation - streams.skinningBlendMatrix = mul(streams.skinningBlendMatrix, GetInstanceWorld(streams.InstanceID)); - - // Transform position - float4 blendPos = mul(streams.Position, streams.skinningBlendMatrix); - - streams.PositionWS = blendPos; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationTextureUV.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationTextureUV.sdsl deleted file mode 100644 index 88be67a557..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationTextureUV.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader TransformationTextureUV : ShaderBase, Texturing -{ - override void VSMain() - { - TransformUV_VS(); - - base.VSMain(); - } - - cbuffer PerDraw - { - stage float4 TextureRegion = float4(0,0,1,1); - } - - stage void TransformUV_VS() - { - streams.TexCoord = TextureRegion.xy + TextureRegion.zw * streams.TexCoord; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationWAndVP.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationWAndVP.sdsl deleted file mode 100644 index f18b9b1512..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationWAndVP.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Transforms the position of the vertex in world space first then in projection space -/// -shader TransformationWAndVP : TransformationBase, PositionStream4, PositionHStream4 -{ - stage override void PreTransformPosition() - { - base.PreTransformPosition(); - streams.PositionWS = mul(streams.Position, Transformation.World); - } - - stage override void PostTransformPosition() - { - base.PostTransformPosition(); - streams.ShadingPosition = ComputeShadingPosition(streams.PositionWS); - streams.PositionH = streams.ShadingPosition; - streams.DepthVS = streams.ShadingPosition.w; - } - - stage override float4 ComputeShadingPosition(float4 world) - { - return mul(world, Transformation.ViewProjection); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl deleted file mode 100644 index f15b86663e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationWAndVPInstanced.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Tebjan Halm -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Transforms the position of the vertex in world space first then in projection space -/// -shader TransformationWAndVPInstanced : TransformationWAndVP, TransformationInstancing, PositionStream4, PositionHStream4 -{ - stage override void PreTransformPosition() - { - streams.PositionWS = mul(streams.Position, GetInstanceWorld(streams.InstanceID)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationWVP.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationWVP.sdsl deleted file mode 100644 index 11b4f07bca..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationWVP.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Transforms the local position of the vertex into the projection space. -/// -shader TransformationWVP : TransformationMatrix -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/TransformationZero.sdsl b/sources/shaders/assets/Stride/SDSL/TransformationZero.sdsl deleted file mode 100644 index 5bea18abb3..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TransformationZero.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Resets the position to the origin. -/// -shader TransformationZero : TransformationBase -{ - stage override void BaseTransformVS() - { - streams.PositionStream4.Position = float4(0.0f, 0.0f, 0.0f, 1.0f); - base.BaseTransformVS(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl b/sources/shaders/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl deleted file mode 100644 index ecc128b20e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/TripleRhombiCombineShader.sdsl +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Combines the 3 rhombi blurs into an hexagonal blur. (Final pass of the TripleRhombi bokeh effect.) - /// Expects as input: - /// - Texture0: a color buffer with the top-left rhombi blur - /// - Texture1: a color buffer with the top-right rhombi blur - /// - Texture2: a color buffer with the bottom rhombi blur - /// - shader TripleRhombiCombineShader : ImageEffectShader - { - // Offset to apply when reading a texture coordinate (for each of the 3 rhombis) - stage float2 RhombiTapOffsets[3]; - - stage override float4 Shading() - { - float4 tapColor[3]; - - tapColor[0] = Texture0.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[0] * Texture0TexelSize ); - tapColor[1] = Texture1.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[1] * Texture1TexelSize ); - tapColor[2] = Texture2.Sample( LinearSampler, streams.TexCoord + RhombiTapOffsets[2] * Texture2TexelSize ); - - float4 result = float4(0.0, 0.0, 0.0, 0.0); - [unroll] - for (int i = 0; i < 3; i++) - { - float4 color = tapColor[i]; - color.rgb *= color.a; //Pre-multiply alpha - result += color; - } - - result /= 3.0; - - if (result.a > 0) result.rgb /= result.a; // Converts back to non-pre-multiplied alpha - - return result; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/UIEffectShader.sdsl b/sources/shaders/assets/Stride/SDSL/UIEffectShader.sdsl deleted file mode 100644 index 605c75e9ff..0000000000 --- a/sources/shaders/assets/Stride/SDSL/UIEffectShader.sdsl +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader UIEffectShader : ShaderBase, Texturing -{ - // ------------------------------------- - // streams - // ------------------------------------- - stage stream float4 Position : POSITION; - stage stream float4 Color : COLOR; - stage stream float Swizzle : BATCH_SWIZZLE; - - // ------------------------------------- - // VertexShader - // ------------------------------------- - stage override void VSMain() - { - streams.ShadingPosition = streams.Position; - if (TSRgb) - { - streams.Color = ColorUtility.ToLinear(streams.Color); - } - } - - // Shading of the sprite - stage override void PSMain() - { - streams.ColorTarget = Shading(); - } - - stage float4 Shading() - { - float4 sampledColor = Texture0.Sample(Sampler, streams.TexCoord); - float4 swizzledColor = streams.Swizzle == 0? sampledColor: sampledColor.rrrr; - - return swizzledColor * streams.Color; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/Utilities.sdsl b/sources/shaders/assets/Stride/SDSL/Utilities.sdsl deleted file mode 100644 index 85e878c077..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Utilities.sdsl +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/// -/// Various helper functions. -/// -shader Utilities -{ - // ------------------------------------- - // type definition - // ------------------------------------- - typedef uint Half2; - typedef uint2 Half4; - - // Converts a Half2 to a float2 - float2 Half2ToFloat2(Half2 value) - { - return float2(f16tof32(value), f16tof32(value >> 16)); - } - - // Converts a float2 to a Half2 - Half2 Float2ToHalf2(float2 value) - { - return f32tof16(value.x) | (f32tof16(value.y) << 16); - } - - // Converts a Half4 to a float4 - float4 Half4ToFloat4(Half4 value) { - return float4(f16tof32(value.x), f16tof32(value.x>>16), f16tof32(value.y), f16tof32(value.y>>16)); - } - - // Converts a float4 to a Half4 - Half4 Float4ToHalf4(float4 value) { - return uint2(f32tof16(value.x) | (f32tof16(value.y) << 16), f32tof16(value.z) | (f32tof16(value.w) << 16)); - } - - // Commpute Schlick's approximation of Fresnel - float3 FresnelSchlick(float3 specularColor, float3 eye, float3 h, float factor) - { - return specularColor + (1.0f - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; - } - - // Commpute Schlick's approximation of Fresnel - float3 FresnelSchlickWithGloss(float3 specularColor, float3 eye, float3 h, float factor, float gloss) - { - return specularColor + (max(specularColor, gloss) - specularColor) * pow(1.0f - saturate(dot(eye, h)), 5.0f) * factor; - } - - // flip the texture coordinate if on an opengl device. - static float2 ConvertTexCoord(float2 texcoord) { -#ifdef STRIDE_GRAPHICS_API_OPENGL - return float2(texcoord.x, 1.0f - texcoord.y); -#else - return texcoord; -#endif - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VelocityOutput.sdsl b/sources/shaders/assets/Stride/SDSL/VelocityOutput.sdsl deleted file mode 100644 index baf60694f0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VelocityOutput.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -// ComputeColor that just returns streams.velocity -shader VelocityOutput : ComputeColor, VelocityStream -{ - override float4 Compute() - { - return float4(streams.velocity.xy, 0.0f, 0.0f); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VelocityStream.sdsl b/sources/shaders/assets/Stride/SDSL/VelocityStream.sdsl deleted file mode 100644 index 77602e8b60..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VelocityStream.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader VelocityStream : ShaderBase -{ - // Screen space velocity - stage stream float2 velocity; - - stage override void VSMain() - { - base.VSMain(); - streams.velocity = float2(0,0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VideoShader.sdsl b/sources/shaders/assets/Stride/SDSL/VideoShader.sdsl deleted file mode 100644 index a3392755ce..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VideoShader.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader VideoShader : SpriteBase -{ -}; diff --git a/sources/shaders/assets/Stride/SDSL/VignettingShader.sdsl b/sources/shaders/assets/Stride/SDSL/VignettingShader.sdsl deleted file mode 100644 index 4b12a46146..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VignettingShader.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -namespace Stride.Rendering.Images -{ - /// - /// Vignetting shader. - /// - internal shader VignettingShader : ColorTransformShader, Texturing - { - // Amount - float Amount; - - // At which radius from the center the vignetting begins, in [0, 1] - float RadiusBegin; - - // Color othe vignette - [Color] - float3 Color; - - override float4 Compute(float4 color) - { - float2 fromCenterVector = streams.TexCoord - float2(0.5, 0.5); - float squareDistanceToCenter = dot(fromCenterVector, fromCenterVector); - float distanceToCenter = sqrt(squareDistanceToCenter); - - float vignette = smoothstep(RadiusBegin, 1.0, distanceToCenter / 0.7071); // 0.7071 is sqrt(0.5), at the screen corner - vignette *= Amount; - color.rgb = color.rgb * (1.0 - vignette) + vignette * Color; - - return color; - - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VolumeMinMaxShader.sdsl b/sources/shaders/assets/Stride/SDSL/VolumeMinMaxShader.sdsl deleted file mode 100644 index ff56555e58..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VolumeMinMaxShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -shader VolumeMinMaxShader : ShaderBase, PositionHStream4 -{ - stage matrix WorldViewProjection; - stage stream float4 Position : POSITION; - - stage override void VSMain() - { - streams.ShadingPosition = mul(streams.Position, WorldViewProjection); - streams.PositionH = streams.ShadingPosition; - } - - stage override void PSMain() - { - float depth = streams.PositionH.z / streams.PositionH.w; - streams.ColorTarget = float4(depth, depth, 0, 1); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl deleted file mode 100644 index 0de543508e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmap.sdsl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmap : Math, Texturing, ComputeShaderBase - { - stage float3 ReadOffset; - stage float3 WriteOffset; - stage Texture3D ReadTex; - stage RWTexture3D WriteTex; - - compose Voxel2x2x2Mipmapper mipmapper; - - override void Compute() - { - uint3 pos = streams.DispatchThreadId; - - uint3 posR = pos * 2 + (int3)ReadOffset; - - float4 fragmentSum = mipmapper.Mipmap( - ReadTex.Load(int4(posR, 0)), - ReadTex.Load(int4(posR + uint3(1, 0, 0), 0)), - ReadTex.Load(int4(posR + uint3(1, 1, 0), 0)), - ReadTex.Load(int4(posR + uint3(1, 0, 1), 0)), - ReadTex.Load(int4(posR + uint3(0, 1, 1), 0)), - ReadTex.Load(int4(posR + uint3(0, 1, 0), 0)), - ReadTex.Load(int4(posR + uint3(0, 0, 1), 0)), - ReadTex.Load(int4(posR + uint3(1, 1, 1), 0)) - ); - - WriteTex[pos + WriteOffset] = fragmentSum; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl deleted file mode 100644 index e84a8b65d0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapEffect.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - partial effect Voxel2x2x2MipmapEffect - { - using params Voxel2x2x2MipmapKeys; - - mixin Voxel2x2x2Mipmap; - if (Voxel2x2x2MipmapKeys.mipmapper!=null) - { - mixin compose mipmapper = Voxel2x2x2MipmapKeys.mipmapper; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl deleted file mode 100644 index 034a758332..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper : Math, Texturing, ComputeShaderBase - { - float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return float4(1,0,0,1); - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl deleted file mode 100644 index 85cd028574..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperHeuristic.sdsl +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2MipmapperHeuristic : Voxel2x2x2Mipmapper - { - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - float filledSum = ceil(s000.a) + ceil(s100.a) + ceil(s110.a) + ceil(s101.a) + ceil(s011.a) + ceil(s010.a) + ceil(s001.a) + ceil(s111.a); - float4 fragmentSum = (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111); - fragmentSum.rgb /= max(filledSum, 4); - fragmentSum.a /= 8; - return fragmentSum; - //Rather than divide by 8... - //I figure that since the visible surface of the - //emitter is a 2D projection, it should decrease - //by 2 dimensions rather than 3 (i.e divide by 4 rather than 8). - - //This makes the lighting fall-off much more realistic, - //but I find the opacity coverage too strong then. - //so keep that dividing by 8. - - //Of course, then the brightness in areas with clusters of voxels - //becomes too high, so instead divide by the number of filled voxels, minimum 4 - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl deleted file mode 100644 index 08da325c53..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperPhysicallyBased.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2MipmapperPhysicallyBased : Voxel2x2x2Mipmapper - { - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - float4 fragmentSum = (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111); - fragmentSum.rgb /= 4; - fragmentSum.a /= 8; - return fragmentSum; - //Rather than divide by 8... - //I figure that since the visible surface of the - //emitter is a 2D projection, it should decrease - //by 2 dimensions rather than 3 (i.e divide by 4 rather than 8). - - //This makes the lighting fall-off much more realistic, - //but I find the opacity coverage too strong then. - //so keep that dividing by 8. - } - }; -} \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl deleted file mode 100644 index 37c4138c73..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2MipmapperSimple.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2MipmapperSimple : Voxel2x2x2Mipmapper - { - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (s000 + s100 + s110 + s101 + s011 + s010 + s001 + s111)/8; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl deleted file mode 100644 index c8911d6765..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXN.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoXN : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s100,s000) + blend(s110,s010) + blend(s111,s011) + blend(s101,s001))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl deleted file mode 100644 index 87d50fc1f1..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoXP.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoXP : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s000,s100) + blend(s010,s110) + blend(s011,s111) + blend(s001,s101))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl deleted file mode 100644 index 09425b6ac9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYN.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoYN : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s010,s000) + blend(s110,s100) + blend(s111,s101) + blend(s011,s001))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl deleted file mode 100644 index ef90d45c4f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoYP.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoYP : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s000,s010) + blend(s100,s110) + blend(s101,s111) + blend(s001,s011))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl deleted file mode 100644 index 554f527914..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZN.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoZN : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s001,s000) + blend(s101,s100) + blend(s111,s110) + blend(s011,s010))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl b/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl deleted file mode 100644 index 0a0ea9d967..0000000000 --- a/sources/shaders/assets/Stride/SDSL/Voxel2x2x2Mipmapper_AnisoZP.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader Voxel2x2x2Mipmapper_AnisoZP : Voxel2x2x2Mipmapper - { - float4 blend(float4 s0, float4 s1) - { - return s0*(1-s1.a) + s1; - } - override float4 Mipmap(float4 s000, float4 s100, float4 s110, float4 s101, float4 s011, float4 s010, float4 s001, float4 s111) - { - return (blend(s000,s001) + blend(s100,s101) + blend(s110,s111) + blend(s010,s011))/4; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl deleted file mode 100644 index d1a80cc183..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedSampler.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader VoxelAnisotropicPairedSampler : IVoxelSampler, Texturing - { - compose VoxelStorageTextureShader storage; - cbuffer PerView.Lighting - { - float maxBrightness; - } - - float4 applyMaxBrightness(float4 col) - { - return float4(col.rgb * maxBrightness, col.a); - } - override float4 Sample(float3 position, float3 normal, float diameter) - { - return applyMaxBrightness( - storage.Sample(position, diameter, 0) * abs(normal.x) + - storage.Sample(position, diameter, 1) * abs(normal.y) + - storage.Sample(position, diameter, 2) * abs(normal.z) - ); - } - override float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - return applyMaxBrightness( - storage.SampleNearestMip(position, diameter, 0) * abs(normal.x) + - storage.SampleNearestMip(position, diameter, 1) * abs(normal.y) + - storage.SampleNearestMip(position, diameter, 2) * abs(normal.z) - ); - } - override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - return applyMaxBrightness( - storage.SampleByMipNearestMip(position, diameter, 0) * abs(normal.x) + - storage.SampleByMipNearestMip(position, diameter, 1) * abs(normal.y) + - storage.SampleByMipNearestMip(position, diameter, 2) * abs(normal.z) - ); - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return storage.SampleRaw(pos, mipmap, textureID, axis); - } - override float VoxelSize() - { - return storage.VoxelSize(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl deleted file mode 100644 index 18925b8ea5..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicPairedWriter_Float4.sdsl +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAnisotropicPairedWriter_Float4 : VoxelLayout_Float4, NormalStream -{ - stream float4 axisX; - stream float4 axisY; - stream float4 axisZ; - RWTexture3D DirectOutput; - compose VoxelFragmentPacker writer; - - float maxBrightnessInv; - - compose VoxelModifierApplierAnisotropicPaired Modifiers[]; - override void InitializeDummy() - { - streams.axisX = float4(0,0,0,0); - streams.axisY = float4(0,0,0,0); - streams.axisZ = float4(0,0,0,0); - } - override void InitializeFromStreams(float4 original) - { - streams.axisX = original * abs(streams.normalWS.x); - streams.axisY = original * abs(streams.normalWS.y); - streams.axisZ = original * abs(streams.normalWS.z); - } - float4 applyMaxBrightness(float4 col) - { - return float4(col.rgb * maxBrightnessInv, col.a); - } - override void DirectWrite(uint3 address, uint strideIndex, uint stride) - { - address.y += strideIndex * stride * 3; - float4 tempAxisX = streams.axisX; - float4 tempAxisY = streams.axisY; - float4 tempAxisZ = streams.axisZ; - foreach (var modifier in Modifiers) - { - modifier.Apply(tempAxisX, tempAxisY, tempAxisZ); - } - streams.axisX = tempAxisX; - streams.axisY = tempAxisY; - streams.axisZ = tempAxisZ; - - DirectOutput[address] = applyMaxBrightness(streams.axisX);address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisY);address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisZ); - } - override void IndirectWrite(RWBuffer buffer, uint address) - { - writer.Write(buffer, address, streams.axisX); - writer.Write(buffer, address, streams.axisY); - writer.Write(buffer, address, streams.axisZ); - } - override void InitializeFromBuffer(RWBuffer buffer, uint address) - { - writer.Read(buffer, address, streams.axisX); - writer.Read(buffer, address, streams.axisY); - writer.Read(buffer, address, streams.axisZ); - } - override float4 SampleLocal() - { - return streams.axisX; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl deleted file mode 100644 index 68a58069f8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicSampler.sdsl +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader VoxelAnisotropicSampler : IVoxelSampler, Texturing - { - compose VoxelStorageTextureShader storage; - cbuffer PerView.Lighting - { - float maxBrightness; - } - - float4 applyMaxBrightness(float4 col) - { - return float4(col.rgb * maxBrightness, col.a); - } - override float4 Sample(float3 position, float3 normal, float diameter) - { - float4 sum = float4(0,0,0,0); - - sum = storage.Sample(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); - sum += storage.Sample(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); - sum += storage.Sample(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); - - return applyMaxBrightness(sum); - } - override float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - float4 sum = float4(0, 0, 0, 0); - - sum = storage.SampleNearestMip(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); - sum += storage.SampleNearestMip(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); - sum += storage.SampleNearestMip(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); - - return applyMaxBrightness(sum); - } - override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - float4 sum = float4(0, 0, 0, 0); - - sum = storage.SampleByMipNearestMip(position, diameter, normal.x > 0 ? 0 : 1) * abs(normal.x); - sum += storage.SampleByMipNearestMip(position, diameter, normal.y > 0 ? 2 : 3) * abs(normal.y); - sum += storage.SampleByMipNearestMip(position, diameter, normal.z > 0 ? 4 : 5) * abs(normal.z); - - return applyMaxBrightness(sum); - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return storage.SampleRaw(pos, mipmap, textureID, axis); - } - override float VoxelSize() - { - return storage.VoxelSize(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl deleted file mode 100644 index a0bdfe49e0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAnisotropicWriter_Float4.sdsl +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAnisotropicWriter_Float4 : VoxelLayout_Float4, NormalStream -{ - stream float4 axisXP; - stream float4 axisXN; - stream float4 axisYP; - stream float4 axisYN; - stream float4 axisZP; - stream float4 axisZN; - RWTexture3D DirectOutput; - compose VoxelFragmentPacker writer; - - float maxBrightnessInv; - - compose VoxelModifierApplierAnisotropic Modifiers[]; - override void InitializeDummy() - { - streams.axisXP = float4(0,0,0,0); - streams.axisYP = float4(0,0,0,0); - streams.axisZP = float4(0,0,0,0); - streams.axisXN = float4(0,0,0,0); - streams.axisYN = float4(0,0,0,0); - streams.axisZN = float4(0,0,0,0); - } - override void InitializeFromStreams(float4 original) - { - if (streams.normalWS.x > 0) - streams.axisXP = original * streams.normalWS.x; - else - streams.axisXN = original * -streams.normalWS.x; - - if (streams.normalWS.y > 0) - streams.axisYP = original * streams.normalWS.y; - else - streams.axisYN = original * -streams.normalWS.y; - - if (streams.normalWS.z > 0) - streams.axisZP = original * streams.normalWS.z; - else - streams.axisZN = original * -streams.normalWS.z; - } - float4 applyMaxBrightness(float4 col) - { - return float4(col.rgb * maxBrightnessInv, col.a); - } - override void DirectWrite(uint3 address, uint strideIndex, uint stride) - { - address.y += strideIndex * stride * 6; - float4 tempAxisXP = streams.axisXP; - float4 tempAxisXN = streams.axisXN; - float4 tempAxisYP = streams.axisYP; - float4 tempAxisYN = streams.axisYN; - float4 tempAxisZP = streams.axisZP; - float4 tempAxisZN = streams.axisZN; - foreach (var modifier in Modifiers) - { - modifier.Apply(tempAxisXP, tempAxisXN, tempAxisYP, tempAxisYN, tempAxisZP, tempAxisZN); - } - streams.axisXP = tempAxisXP; - streams.axisXN = tempAxisXN; - streams.axisYP = tempAxisYP; - streams.axisYN = tempAxisYN; - streams.axisZP = tempAxisZP; - streams.axisZN = tempAxisZN; - DirectOutput[address] = applyMaxBrightness(streams.axisXP); - address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisXN); - address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisYP); - address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisYN); - address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisZP); - address.y += stride; - DirectOutput[address] = applyMaxBrightness(streams.axisZN); - } - override void IndirectWrite(RWBuffer buffer, uint address) - { - writer.Write(buffer, address, streams.axisXP); - writer.Write(buffer, address, streams.axisXN); - writer.Write(buffer, address, streams.axisYP); - writer.Write(buffer, address, streams.axisYN); - writer.Write(buffer, address, streams.axisZP); - writer.Write(buffer, address, streams.axisZN); - } - override void InitializeFromBuffer(RWBuffer buffer, uint address) - { - writer.Read(buffer, address, streams.axisXP); - writer.Read(buffer, address, streams.axisXN); - writer.Read(buffer, address, streams.axisYP); - writer.Read(buffer, address, streams.axisYN); - writer.Read(buffer, address, streams.axisZP); - writer.Read(buffer, address, streams.axisZN); - } - override float4 SampleLocal() - { - return streams.axisXP; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttribute.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttribute.sdsl deleted file mode 100644 index 0464c4b1db..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttribute.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAttribute -{ - void InitializeDummy(){} - void InitializeFromStreams(){} - void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride){} - void IndirectWrite(RWBuffer buffer, uint address){} - void DirectWrite(uint3 address, uint strideIndex, uint stride){} - float4 SampleLocal(){return float4(0,0,0,1);} -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl deleted file mode 100644 index 5172a57787..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageSampler.sdsl +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader VoxelAttributeDirectionalCoverageSampler : IVoxelSampler, Texturing - { - compose VoxelStorageTextureShader storage; - - override float4 ComputeLocal(float3 position) - { - return float4(0,0,0,1); - } - - float4 SetColor(float3 col) - { - return float4(col.r,col.g,col.b,max(col.r,max(col.g,col.b))); - } - override float4 Sample(float3 position, float3 normal, float diameter) - { - return SetColor(storage.Sample(position, diameter, 0).rgb); - } - override float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - return SetColor(storage.SampleNearestMip(position, diameter, 0).rgb); - } - override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - return SetColor(storage.SampleByMipNearestMip(position, diameter, 0).rgb); - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return storage.SampleRaw(pos,mipmap,textureID,axis); - } - override float VoxelSize() - { - return storage.VoxelSize(); - } - override float4 Test() - { - return float4(0,1,0,1); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl deleted file mode 100644 index 1250bc6ecf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttributeDirectionalCoverageShader.sdsl +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAttributeDirectionalCoverageShader : VoxelAttribute, ShaderBaseStream, NormalStream, DataPacking -{ - stream uint Voxel_Coverage; - stream float3 Voxel_CoverageResolved; - stream uint coverage : SV_Coverage; - - RWTexture3D DirectOutput; - - override void InitializeDummy() - { - streams.Voxel_Coverage = 0; - streams.Voxel_CoverageResolved = float3(0,0,0); - } - override void InitializeFromStreams() - { - uint shift = 0; - float xdot = abs(streams.normalWS.x); - float ydot = abs(streams.normalWS.y); - float zdot = abs(streams.normalWS.z); - if (xdot > ydot && xdot > zdot) - shift = 0; - if (ydot > xdot && ydot > zdot) - shift = 8; - if (zdot > ydot && zdot > xdot) - shift = 16; - streams.Voxel_Coverage = uint(streams.coverage)< buffer, uint address) - { - uint unusedOut; - InterlockedOr(buffer[address], streams.Voxel_Coverage, unusedOut); - address++; - } - override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) - { - streams.Voxel_Coverage = buffer[address]; - address++; - - uint3 coverage = UnpackByte3ToUint3(streams.Voxel_Coverage); - streams.Voxel_CoverageResolved = (float3(countbits(coverage.x),countbits(coverage.y),countbits(coverage.z)))/8.0; - } - float3 GetResolved(){ - return streams.Voxel_CoverageResolved; - } - override float4 SampleLocal() - { - return float4(streams.Voxel_CoverageResolved, 1.0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl deleted file mode 100644 index aa14c5df90..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttributeEmissionOpacityShader.sdsl +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAttributeEmissionOpacityShader : VoxelAttribute, ShaderBaseStream -{ - compose VoxelLayout_Float4 layout; - - override void InitializeDummy() - { - layout.InitializeDummy(); - } - override void InitializeFromStreams() - { - layout.InitializeFromStreams(streams.ColorTarget); - } - override void DirectWrite(uint3 address, uint strideIndex, uint stride) - { - layout.DirectWrite(address, strideIndex, stride); - } - override void IndirectWrite(RWBuffer buffer, uint address) - { - layout.IndirectWrite(buffer,address); - } - override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) - { - layout.InitializeFromBuffer(buffer, address); - } - override float4 SampleLocal() - { - return layout.SampleLocal(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl deleted file mode 100644 index 59460049e6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttributeSoliditySampler.sdsl +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader VoxelAttributeSoliditySampler : IVoxelSampler, Texturing - { - compose VoxelStorageTextureShader storage; - - override float4 ComputeLocal(float3 position) - { - return float4(0,0,0,1); - } - - float4 SetColor(float4 col) - { - return float4(0,0,0,col.a); - } - override float4 Sample(float3 position, float3 normal, float diameter) - { - return SetColor(storage.Sample(position, diameter, 0).rrrr); - } - override float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - return SetColor(storage.SampleNearestMip(position, diameter, 0).rrrr); - } - override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - return SetColor(storage.SampleByMipNearestMip(position, diameter, 0).rrrr); - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return storage.SampleRaw(pos,mipmap,textureID,axis); - } - override float VoxelSize() - { - return storage.VoxelSize(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl deleted file mode 100644 index 4058ea5066..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelAttributeSolidityShader.sdsl +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelAttributeSolidityShader : VoxelAttribute, VoxelPositionStream, ShaderBaseStream, NormalStream, DataPacking -{ - stream uint Voxel_SolidifyTop; - stream uint Voxel_SolidifyBottom; - stream float Voxel_Solidity; - stream int sendTo; - stream int ignoreTil; - - RWTexture3D DirectOutput; - - override void InitializeDummy() - { - streams.Voxel_SolidifyTop = 0; - streams.Voxel_SolidifyBottom = 0; - streams.Voxel_Solidity = 0; - streams.sendTo = 0; - streams.ignoreTil = 0; - } - override void InitializeFromStreams() - { - uint pos = FloatUnormToUint(streams.PositionVXS.y) & (0xFFFFFFFF << 2); - uint invpos = FloatUnormToUint(1.0 - streams.PositionVXS.y) & (0xFFFFFFFF << 2); - uint type = 0; - streams.normalWS = normalize(streams.normalWS); - if (streams.normalWS.y < -0.0) - type = 1; - if (streams.normalWS.y > 0.0) - type = 2; - - streams.Voxel_SolidifyTop = pos + type; - streams.Voxel_SolidifyBottom = invpos + type; - - streams.sendTo = 0; - streams.ignoreTil = 0; - } - override void DirectWrite(uint3 address, uint strideIndex, uint stride) - { - address.y += strideIndex * stride; - DirectOutput[address] = streams.Voxel_Solidity; - } - override void IndirectWrite(RWBuffer buffer, uint address) - { - InterlockedMax(buffer[address], streams.Voxel_SolidifyTop); - address++; - InterlockedMax(buffer[address], streams.Voxel_SolidifyBottom); - } - bool ResolvesSelf() - { - return (streams.Voxel_SolidifyTop & 3) == 2 && (streams.Voxel_SolidifyBottom & 3) == 1; - } - bool IsSender() - { - return (streams.Voxel_SolidifyTop & 3) == 1; - } - bool IsReceiver() - { - return (streams.Voxel_SolidifyBottom & 3) == 2; - } - override float4 SampleLocal() - { - return float4(IsReceiver()?1:0,IsSender()?1:0,ResolvesSelf()?1:0,streams.Voxel_Solidity); - } - override void InitializeFromBuffer(RWBuffer buffer, uint address, uint2 base_stride) - { - int Y = streams.PositionVXPS.y; - int maxY = streams.VoxelVolumeSize.y; - - uint originalAddress = address; - - streams.Voxel_Solidity = 0; - - if (Y>streams.ignoreTil) - { - if (Y>=streams.sendTo) - { - streams.ignoreTil = maxY; - for(int y = Y ; y < maxY; y++) - { - uint tempAddress = base_stride.x + base_stride.y * y; - streams.Voxel_SolidifyTop = buffer[tempAddress]; - streams.Voxel_SolidifyBottom = buffer[tempAddress + 1]; - if (IsReceiver()) - { - if (streams.ignoreTil -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - shader VoxelBufferWriteAssign : VoxelBufferWriter - { - override void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data) - { - fragmentsBuffer[address] = data; - address++; - } - - override float4 Test() - { - return float4(0,1,0,1); - } - }; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl deleted file mode 100644 index e7d44d7ddb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelBufferWriteMax.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - shader VoxelBufferWriteMax : VoxelBufferWriter - { - override void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data) - { - uint unusedOut = -1; - InterlockedMax(fragmentsBuffer[address], data, unusedOut); - address++; - } - - override float4 Test() - { - return float4(0,1,0,1); - } - }; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelBufferWriter.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelBufferWriter.sdsl deleted file mode 100644 index 750d093c0e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelBufferWriter.sdsl +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - shader VoxelBufferWriter - { - void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint data){} - void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint2 data) - { - Write_Internal(fragmentsBuffer, address,data.x); - Write_Internal(fragmentsBuffer, address,data.y); - } - void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint3 data) - { - Write_Internal(fragmentsBuffer, address,data.x); - Write_Internal(fragmentsBuffer, address,data.y); - Write_Internal(fragmentsBuffer, address,data.z); - } - void Write_Internal(RWBuffer fragmentsBuffer, inout uint address, uint4 data) - { - Write_Internal(fragmentsBuffer, address,data.x); - Write_Internal(fragmentsBuffer, address,data.y); - Write_Internal(fragmentsBuffer, address,data.z); - Write_Internal(fragmentsBuffer, address,data.w); - } - - float4 Test() - { - return float4(1,0,0,1); - } - }; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl deleted file mode 100644 index ec1fe9efac..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat16.sdsl +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelFragmentPackFloat16 : VoxelFragmentPacker, DataPacking -{ - override void Skip(inout uint address, float unpacked){address += 1;} - override void Skip(inout uint address, float2 unpacked){address += 1;} - override void Skip(inout uint address, float3 unpacked){address += 2;} - override void Skip(inout uint address, float4 unpacked){address += 2;} - override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, FloatToHalfFloat(unpacked.r)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, PackFloat2ToHalfFloat2(unpacked.rg)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, - uint2( - PackFloat2ToHalfFloat2(unpacked.rg), - FloatToHalfFloat(unpacked.b) - ) - ); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, - uint2( - PackFloat2ToHalfFloat2(unpacked.rg), - PackFloat2ToHalfFloat2(unpacked.ba) - ) - ); - } - - - - - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) - { - unpacked = HalfFloatToFloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) - { - unpacked = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) - { - unpacked.rg = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); - address++; - unpacked.b = HalfFloatToFloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) - { - unpacked.rg = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); - address++; - unpacked.ba = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); - address++; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl deleted file mode 100644 index 4313d04aed..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloat32.sdsl +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelFragmentPackFloat32 : VoxelFragmentPacker -{ - override void Skip(inout uint address, float unpacked){address += 1;} - override void Skip(inout uint address, float2 unpacked){address += 2;} - override void Skip(inout uint address, float3 unpacked){address += 3;} - override void Skip(inout uint address, float4 unpacked){address += 4;} - override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, asuint(unpacked)); - } - - - - - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) - { - unpacked = asfloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) - { - unpacked.r = asfloat(fragmentsBuffer[address]); - address++; - unpacked.g = asfloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) - { - unpacked.r = asfloat(fragmentsBuffer[address]); - address++; - unpacked.g = asfloat(fragmentsBuffer[address]); - address++; - unpacked.b = asfloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) - { - unpacked.r = asfloat(fragmentsBuffer[address]); - address++; - unpacked.g = asfloat(fragmentsBuffer[address]); - address++; - unpacked.b = asfloat(fragmentsBuffer[address]); - address++; - unpacked.a = asfloat(fragmentsBuffer[address]); - address++; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl deleted file mode 100644 index d361704b63..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPackFloatR11G11B10.sdsl +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelFragmentPackFloatR11G11B10 : VoxelFragmentPacker, DataPacking -{ - override void Skip(inout uint address, float unpacked){address += 1;} - override void Skip(inout uint address, float2 unpacked){address += 1;} - override void Skip(inout uint address, float3 unpacked){address += 1;} - override void Skip(inout uint address, float4 unpacked){address += 2;} - override void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, Float3ToR11G11B10(unpacked)); - } - - - - - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked) - { - unpacked.rgb = R11G11B10ToFloat3(fragmentsBuffer[address]); - address++; - } - - - - //Until partial packing is implemented (if ever), write some halfs when not writing exactly 3 values - //Otherwise many bits are wasted - //Keep layout consistent though (or things like InterlockedMax can give unexpected results) - override void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, FloatToHalfFloat(unpacked.r)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, PackFloat2ToHalfFloat2(unpacked.rg)); - } - override void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked) - { - writer.Write_Internal(fragmentsBuffer, address, - uint2( - Float3ToR11G11B10(unpacked.rgb), - FloatToHalfFloat(unpacked.a) - ) - ); - } - - - - - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked) - { - unpacked = HalfFloatToFloat(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked) - { - unpacked = UnpackHalfFloat2ToFloat2(fragmentsBuffer[address]); - address++; - } - override void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked) - { - unpacked.rgb = R11G11B10ToFloat3(fragmentsBuffer[address]); - address++; - unpacked.a = HalfFloatToFloat(fragmentsBuffer[address]); - address++; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPacker.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelFragmentPacker.sdsl deleted file mode 100644 index 731079e1cc..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelFragmentPacker.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelFragmentPacker -{ - compose VoxelBufferWriter writer; - - void Skip(inout uint address, float unpacked){} - void Skip(inout uint address, float2 unpacked){} - void Skip(inout uint address, float3 unpacked){} - void Skip(inout uint address, float4 unpacked){} - - void Write(RWBuffer fragmentsBuffer, inout uint address, float unpacked){} - void Write(RWBuffer fragmentsBuffer, inout uint address, float2 unpacked){} - void Write(RWBuffer fragmentsBuffer, inout uint address, float3 unpacked){} - void Write(RWBuffer fragmentsBuffer, inout uint address, float4 unpacked){} - - void Read(RWBuffer fragmentsBuffer, inout uint address, out float unpacked){unpacked = 0;} - void Read(RWBuffer fragmentsBuffer, inout uint address, out float2 unpacked){unpacked = float2(0,0);} - void Read(RWBuffer fragmentsBuffer, inout uint address, out float3 unpacked){unpacked = float3(0,0,0);} - void Read(RWBuffer fragmentsBuffer, inout uint address, out float4 unpacked){unpacked = float4(0,0,0,0);} -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl deleted file mode 100644 index af69989e01..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelIsotropicSampler.sdsl +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - shader VoxelIsotropicSampler : IVoxelSampler, Texturing - { - compose VoxelStorageTextureShader storage; - cbuffer PerView.Lighting - { - float maxBrightness; - } - - override float4 ComputeLocal(float3 position) - { - return float4(0,0,0,1); - } - override float4 Sample(float3 position, float3 normal, float diameter) - { - return storage.Sample(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); - } - override float4 SampleNearestMip(float3 position, float3 normal, float diameter) - { - return storage.SampleNearestMip(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); - } - override float4 SampleByMipNearestMip(float3 position, float3 normal, float diameter) - { - return storage.SampleByMipNearestMip(position, diameter, 0) * float4(maxBrightness, maxBrightness, maxBrightness, 1.0); - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - return storage.SampleRaw(pos,mipmap,textureID,axis); - } - override float VoxelSize() - { - return storage.VoxelSize(); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl deleted file mode 100644 index 7505db6c0f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelIsotropicWriter_Float4.sdsl +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelIsotropicWriter_Float4 : VoxelLayout_Float4 -{ - stream float4 center; - RWTexture3D DirectOutput; - compose VoxelFragmentPacker writer; - - float maxBrightnessInv; - - compose VoxelModifierApplierIsotropic Modifiers[]; - override void InitializeDummy() - { - streams.center = float4(0,0,0,0); - } - override void InitializeFromStreams(float4 original) - { - streams.center = original; - } - override void DirectWrite(uint3 address, uint strideIndex, uint stride) - { - address.y += strideIndex * stride; - float4 tempcenter = streams.center; - foreach (var modifier in Modifiers) - { - modifier.Apply(tempcenter); - } - streams.center = tempcenter; - - DirectOutput[address] = float4(streams.center.rgb * maxBrightnessInv, streams.center.a); - } - override void IndirectWrite(RWBuffer buffer, uint address) - { - writer.Write(buffer, address, streams.center); - } - override void InitializeFromBuffer(RWBuffer buffer, uint address) - { - writer.Read(buffer, address, streams.center); - } - override float4 SampleLocal() - { - return streams.center; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelLayout_Float4.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelLayout_Float4.sdsl deleted file mode 100644 index d504cc51e8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelLayout_Float4.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelLayout_Float4 : NormalStream -{ - void InitializeDummy(){} - void InitializeFromStreams(float4 original){} - void IndirectWrite(RWBuffer buffer, uint address){} - void InitializeFromBuffer(RWBuffer buffer, uint address){} - void DirectWrite(uint3 address, uint strideIndex, uint stride){} - float4 SampleLocal() - { - return float4(0,0,0,0); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchBeam.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchBeam.sdsl deleted file mode 100644 index 704c5ace1a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchBeam.sdsl +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchBeam : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes -{ - #ifndef AttributeID - #define AttributeID 0 - #endif - override float4 March(float3 rayPos, float3 rayDir) - { - return MarchRadius(rayPos, rayDir, 1.0); - } - override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) - { - float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); - float dist = voxelSize; - float4 light = float4(0.0, 0.0, 0.0, 0.0); - - for (int i = 0; i < steps; i++) - { - float size = beamDiameter * radiusScale; - float3 pos = rayPos + rayDir * dist; - - light += AttributeSamplers[AttributeID].Sample(pos, -rayDir, AttributeSamplers[AttributeID].VoxelSize() * size) * saturate(1.0 - light.a); - - dist += AttributeSamplers[AttributeID].VoxelSize() * stepScale; - } - return light; - } - - override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } - override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchCone.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchCone.sdsl deleted file mode 100644 index 3dd3d7c411..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchCone.sdsl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchCone : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes -{ - #ifndef sampleFunction - #define sampleFunction Sample - #define AttributeID 0 - #endif - override float4 March(float3 rayPos, float3 rayDir) - { - return MarchRadius(rayPos, rayDir, 1.0); - } - override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) - { - float finalRatio = coneRatio.x * radiusScale; - float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); - - float dist = voxelSize / max(1,finalRatio); - - float4 light = float4(0.0, 0.0, 0.0, 0.0); - rayPos += offset * voxelSize * rayDir; - - for (int i = 0; i < steps; i ++) - { - float diameter = max(voxelSize, finalRatio * dist); - float3 pos = rayPos + rayDir * dist; - - light += AttributeSamplers[AttributeID].sampleFunction(pos, -rayDir, diameter) * saturate(1.0 - light.a); - - dist += diameter * stepScale; - } - return light; - } - override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } - override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl deleted file mode 100644 index 428f8ce219..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchConeEditMode.sdsl +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchConeEditMode : VoxelMarchMethod, VoxelRadiusMarchMethod, MarchAttributes -{ - #ifndef AttributeID - #define AttributeID 0 - #endif - cbuffer PerView.Lighting - { - int steps; - float stepScale; - float coneRatio; - int fast; - float offset; - } - override float4 March(float3 rayPos, float3 rayDir) - { - return MarchRadius(rayPos, rayDir, 1.0); - } - override float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale) - { - float finalRatio = coneRatio.x * radiusScale; - float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); - - float dist = voxelSize / max(1,finalRatio); - - float4 light = float4(0.0, 0.0, 0.0, 0.0); - rayPos += offset * voxelSize * rayDir; - - for (int i = 0; i < steps; i ++) - { - float diameter = max(voxelSize, finalRatio * dist); - float3 pos = rayPos + rayDir * dist; - - if (fast) - light += AttributeSamplers[AttributeID].SampleNearestMip(pos, -rayDir, diameter) * saturate(1.0 - light.a); - else - light += AttributeSamplers[AttributeID].Sample(pos, -rayDir, diameter) * saturate(1.0 - light.a); - - dist += diameter * stepScale; - } - return light; - } - - override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } - override float StepSizeRadius(float radiusScale) { return radiusScale * AttributeSamplers[AttributeID].VoxelSize(); } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl deleted file mode 100644 index b9847d3516..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchConePerMipmap.sdsl +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchConePerMipmap : VoxelMarchMethod, MarchAttributes -{ - #ifndef AttributeID - #define AttributeID 0 - #endif - cbuffer PerView.Lighting - { - float offset; - float coneRatioInv; - } - override float4 March(float3 rayPos, float3 rayDir) - { - float voxelSize = AttributeSamplers[AttributeID].VoxelSize(); - rayPos += rayDir * voxelSize * offset; - float dist = voxelSize * coneRatioInv; - float size = 0; - float4 light = float4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < steps; i++) - { - float3 pos = rayPos + rayDir * dist; - - light += AttributeSamplers[AttributeID].SampleByMipNearestMip(pos, -rayDir, size) * saturate(1.0 - light.a); - - dist *= 2; - size += 1; - } - return light; - } - - override float StepSize() { return AttributeSamplers[AttributeID].VoxelSize(); } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchMethod.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchMethod.sdsl deleted file mode 100644 index 86833761aa..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchMethod.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchMethod -{ - float4 March(float3 rayPos, float3 rayDir){ return float4(0, 0, 0, 0); } - float StepSize(){ return 1.0; } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchSet.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchSet.sdsl deleted file mode 100644 index 0bb7aa8b38..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchSet.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchSet -{ - float4 March(float3 rayPos, float3 rayDir){ return float4(0, 0, 0, 0); } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl deleted file mode 100644 index cd3006e6ad..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere12.sdsl +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchSetHemisphere12 : VoxelMarchSet -{ - cbuffer PerView.Lighting - { - float offset; - } - compose VoxelMarchMethod Marcher; - override float4 March(float3 rayPos, float3 rayDir) - { - float3 tan = normalize(cross(rayDir, normalize(float3(1, 1, 1)))); - float3 bitan = cross(tan, rayDir); - float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); - - float3 startPos = rayPos + rayDir * Marcher.StepSize() * offset; - - float4 reflLighting = float4(0, 0, 0, 0); - - //Dot products of rays - float central = 0.84; - float outer = 0.22; - float sum = (central*4+outer*8); - central /= sum; - outer /= sum; - - rayDir = mul(float3(-0.38, -0.37, 0.84), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * central; - rayDir = mul(float3(-0.31, 0.43, 0.84), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * central; - rayDir = mul(float3(0.36, 0.39, 0.84), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * central; - rayDir = mul(float3(0.36, -0.39, 0.84), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * central; - - rayDir = mul(float3(-0.87, 0.41, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(-0.35, 0.90, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(0.40, 0.88, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(0.92, 0.31, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(0.87, -0.43, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(0.30, -0.92, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(-0.43, -0.87, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - rayDir = mul(float3(-0.93, -0.28, 0.22), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - return reflLighting; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl deleted file mode 100644 index a2bcff2a6a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetHemisphere6.sdsl +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchSetHemisphere6 : VoxelMarchSet, ShaderBase -{ - cbuffer PerView.Lighting - { - float offset; - } - compose VoxelMarchMethod Marcher; - override float4 March(float3 rayPos, float3 rayDir) - { - float3 tan = normalize(cross(rayDir, normalize(float3(1, 1, 1)))); - float3 bitan = cross(tan, rayDir); - float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); - - float3 startPos = rayPos + rayDir * Marcher.StepSize() * offset; - - float4 reflLighting = float4(0, 0, 0, 0); - - //Dot products of rays - float central = 1.0; - float outer = 0.445; - float sum = central + outer * 5; - central /= sum; - outer /= sum; - - rayDir = mul(float3(0, 0, 1), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * central; - - rayDir = mul(normalize(float3(0.85, 0.278, 0.445)), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - rayDir = mul(normalize(float3(0.527, -0.723, 0.445)), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - rayDir = mul(normalize(float3(-0.526, -0.724, 0.445)), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - rayDir = mul(normalize(float3(-0.851, 0.277, 0.445)), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - rayDir = mul(normalize(float3(0.895, 0.445, 0.445)), tangentMatrix); - reflLighting += Marcher.March(startPos, rayDir) * outer; - - return reflLighting; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl deleted file mode 100644 index 48206a4146..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelMarchSetRandomHemisphere.sdsl +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelMarchSetRandomHemisphere : VoxelMarchSet, ShaderBase -{ - cbuffer PerView.Lighting - { - int marchCount; - float time; - } - float Random(in float2 uv) - { - float2 noise = (frac(sin(dot(uv,float2(12.9898,78.233)*2.0)) * 43758.5453)); - return abs(noise.x + noise.y) * 0.5; - } - float3 CosineWeightedPointOnHemisphere(float2 uv) { - float u = Random(uv) * 6.28; - float v = Random(uv + 0.1); - - v = sqrt(v); - - float2 pos = float2(sin(u),cos(u)) * v; - - return float3(pos, sqrt(1-pos.x*pos.x-pos.y*pos.y)); - } - - compose VoxelMarchMethod Marcher; - override float4 March(float3 rayPos, float3 rayDir) - { - float3 tan = normalize(cross(rayDir, normalize(float3(1,1,1)))); - float3 bitan = cross(tan, rayDir); - float3x3 tangentMatrix = float3x3(tan, bitan, rayDir); - - float3 startPos = rayPos + rayDir * Marcher.StepSize(); - - float4 reflLighting = float4(0, 0, 0, 0); - - for(int i = 0; i < marchCount; i ++) - { - float3 dir = CosineWeightedPointOnHemisphere(streams.ShadingPosition.xy + i*1.73 + time); - dir = mul(dir, tangentMatrix); - reflLighting += Marcher.March(startPos, dir); - } - - return reflLighting/(float)marchCount; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl deleted file mode 100644 index 64d397ed0a..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropic.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierAnisotropic -{ - void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN){ } - void Apply(inout float3 XP, inout float3 XN, inout float3 YP, inout float3 YN, inout float3 ZP, inout float3 ZN){ } - void Apply(inout float2 XP, inout float2 XN, inout float2 YP, inout float2 YN, inout float2 ZP, inout float2 ZN){ } - void Apply(inout float XP, inout float XN, inout float YP, inout float YN, inout float ZP, inout float ZN){ } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl deleted file mode 100644 index e67093323d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAnisotropicPaired.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierAnisotropicPaired -{ - void Apply(inout float4 X, inout float4 Y, inout float4 Z){ } - void Apply(inout float3 X, inout float3 Y, inout float3 Z){ } - void Apply(inout float2 X, inout float2 Y, inout float2 Z){ } - void Apply(inout float X, inout float Y, inout float Z){ } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl deleted file mode 100644 index a5f09799f8..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropic.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierAntiAliasingAnisotropic : VoxelModifierApplierAnisotropic, LocalSamples -{ - override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) - { - float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; - XP *= PlaneCoverage.x; - XN *= PlaneCoverage.x; - YP *= PlaneCoverage.y; - YN *= PlaneCoverage.y; - ZP *= PlaneCoverage.z; - ZN *= PlaneCoverage.z; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl deleted file mode 100644 index 62e9f2218f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingAnisotropicPaired.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierAntiAliasingAnisotropicPaired : VoxelModifierApplierAnisotropicPaired, LocalSamples -{ - override void Apply(inout float4 X, inout float4 Y, inout float4 Z) - { - float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; - X *= PlaneCoverage.x; - Y *= PlaneCoverage.y; - Z *= PlaneCoverage.z; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl deleted file mode 100644 index 8185dbb518..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierAntiAliasingIsotropic.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierAntiAliasingIsotropic : VoxelModifierApplierIsotropic, LocalSamples -{ - override void Apply(inout float4 center) - { - float3 PlaneCoverage = streams.LocalSample[DirectionalOpacityAttributeID].xyz; - center *= max(PlaneCoverage.x, max(PlaneCoverage.y, PlaneCoverage.z)); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl deleted file mode 100644 index 23d34d62bb..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierIsotropic.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierIsotropic -{ - void Apply(inout float4 center){} - void Apply(inout float3 center){} - void Apply(inout float2 center){} - void Apply(inout float center){} -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl deleted file mode 100644 index 9006b8e50b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropic.sdsl +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierOpacifyAnisotropic : VoxelModifierApplierAnisotropic -{ - [Link("VoxelModifierApplierOpacifyIsotropic.Amount")] - float Amount; - - override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) - { - XP.a *= Amount; - XN.a *= Amount; - YP.a *= Amount; - YN.a *= Amount; - ZP.a *= Amount; - ZN.a *= Amount; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl deleted file mode 100644 index 9b83671281..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyAnisotropicPaired.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierOpacifyAnisotropicPaired : VoxelModifierApplierAnisotropicPaired -{ - [Link("VoxelModifierApplierOpacifyIsotropic.Amount")] - float Amount; - - override void Apply(inout float4 X, inout float4 Y, inout float4 Z) - { - X.a *= Amount; - Y.a *= Amount; - Z.a *= Amount; - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl deleted file mode 100644 index e0997dfd3b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierOpacifyIsotropic.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierOpacifyIsotropic : VoxelModifierApplierIsotropic -{ - float Amount; - override void Apply(inout float4 center) - { - center.a *= Amount; - } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl deleted file mode 100644 index 19763d2e4d..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropic.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierSolidifyAnisotropic : VoxelModifierApplierAnisotropic, LocalSamples -{ - override void Apply(inout float4 XP, inout float4 XN, inout float4 YP, inout float4 YN, inout float4 ZP, inout float4 ZN) - { - float Solidity = streams.LocalSample[SolidityAttributeID].a; - XP.a = max(Solidity, XP.a); - XN.a = max(Solidity, XN.a); - YP.a = max(Solidity, YP.a); - YN.a = max(Solidity, YN.a); - ZP.a = max(Solidity, ZP.a); - ZN.a = max(Solidity, ZN.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl deleted file mode 100644 index 1967d6b166..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyAnisotropicPaired.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierSolidifyAnisotropicPaired : VoxelModifierApplierAnisotropicPaired, LocalSamples -{ - override void Apply(inout float4 X, inout float4 Y, inout float4 Z) - { - float Solidity = streams.LocalSample[SolidityAttributeID].a; - X.a = max(Solidity, X.a); - Y.a = max(Solidity, Y.a); - Z.a = max(Solidity, Z.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl deleted file mode 100644 index 5fc4ac4f1b..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelModifierApplierSolidifyIsotropic.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelModifierApplierSolidifyIsotropic : VoxelModifierApplierIsotropic, LocalSamples -{ - override void Apply(inout float4 center) - { - float Solidity = streams.LocalSample[SolidityAttributeID].a; - center.a = max(Solidity, center.a); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelPositionStream.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelPositionStream.sdsl deleted file mode 100644 index 245c59bebf..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelPositionStream.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelPositionStream -{ - stage stream float3 PositionVXS : POSITIONVXS; - stage stream int3 PositionVXPS : POSITIONVXPS; - stage stream float3 VoxelVolumeSize : VOXELVOLUMESIZE; -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl deleted file mode 100644 index a8d4ea59d9..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelRadiusMarchMethod.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelRadiusMarchMethod -{ - float4 MarchRadius(float3 rayPos, float3 rayDir, float radiusScale){ return float4(0, 0, 0, 0); } - float StepSizeRadius(float radiusScale){ return radiusScale; } -}; \ No newline at end of file diff --git a/sources/shaders/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl deleted file mode 100644 index 6c92423e2e..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelStorageClipmapShader.sdsl +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelStorageClipmapShader : VoxelStorageShader, Texturing, ShaderBaseStream, Transformation -{ - cbuffer PerView.VoxelizerStorer - { - float3 clipMapResolution; - //#ifdef singleClip - float clipPos; - float3 clipScale; - float3 clipOffset; - //#else - float clipMapCount; - float4 perClipMapOffsetScale[20]; - //#endif - float storageUints; - } - rgroup PerView.VoxelizerStorer - { - RWBuffer fragmentsBuffer; - } - compose VoxelAttribute AttributesTemp[]; - compose VoxelAttribute AttributesDirect[]; - compose VoxelAttribute AttributesIndirect[]; - - #ifdef singleClip - #define clipScaleIn clipScale - #define clipOffsetIn clipOffset - #define clipPosIn ((uint)clipPos) - #else - stage stream uint clipIndex; - #define clipScaleIn perClipMapOffsetScale[streams.clipIndex].w - #define clipOffsetIn perClipMapOffsetScale[streams.clipIndex].xyz - #define clipPosIn ((streams.clipIndex) * clipMapResolutionI.x * clipMapResolutionI.y * clipMapResolutionI.z) - #endif - - #ifndef IndirectStoreMacro - #define IndirectStoreMacro - #endif - - override bool MightStoreFragments() - { - float3 texPos = streams.PositionWS.xyz * clipScaleIn + clipOffsetIn; - return dot(texPos - saturate(texPos), float3(1, 1, 1)) == 0; - } - override void StoreFragments() - { - int3 clipMapResolutionI = (int3)clipMapResolution; - - float3 texPos = streams.PositionWS.xyz * clipScaleIn + clipOffsetIn; - - streams.PositionVXS = texPos; - streams.VoxelVolumeSize = clipMapResolution; - streams.PositionVXPS = int3(floor(saturate(texPos) * clipMapResolution)); - - int3 pixelPos = streams.PositionVXPS; - - uint index = clipPosIn + pixelPos.x + pixelPos.y * clipMapResolutionI.x + pixelPos.z * clipMapResolutionI.x * clipMapResolutionI.y; - - uint writeindex = index * (uint)storageUints; - - foreach (var attr in AttributesTemp) - { - attr.InitializeFromStreams(); - } - - foreach (var attr in AttributesDirect) - { - attr.InitializeFromStreams(); - } - - foreach (var attr in AttributesIndirect) - { - attr.InitializeFromStreams(); - } - - //See VoxelStorageClipmaps.cs Line #307 and Line #425 - IndirectStoreMacro - } - #ifndef singleClip - override void GenerateTriangles(triangle Input input[3], inout TriangleStream triangleStream) - { - method.InitializeFromTriangle(input); - int3 clipMapResolutionI = (int3)clipMapResolution; - - for (streams.clipIndex = 0; streams.clipIndex < clipMapCount; streams.clipIndex++) - { - [unroll] - for (int i = 0; i < 3 ; i ++) - { - streams = input[i]; - streams.ShadingPosition.xyz = mul(float4(streams.PositionWS.xyz * clipScaleIn + clipOffsetIn, 1),Transformation.View).xyz; - streams.ShadingPosition.xyz = streams.ShadingPosition.xyz * 2 - 1; - method.Append(triangleStream); - } - method.RestartStrip(triangleStream); - } - } - #else - override void PrepareVertex() - { - method.PrepareVertex(); - streams.ShadingPosition.xyz = mul(float4(streams.PositionWS.xyz * clipScaleIn + clipOffsetIn, 1),Transformation.View).xyz; - streams.ShadingPosition.xyz = streams.ShadingPosition.xyz * 2 - 1; - } - #endif -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelStorageShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelStorageShader.sdsl deleted file mode 100644 index ed92b8d972..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelStorageShader.sdsl +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelStorageShader : VoxelPositionStream, PositionStream4, ShaderBaseStream -{ - compose VoxelizationMethod method; - void PrepareFragments(){ method.PrepareFragment(); } - void StoreFragments(){ } - bool MightStoreFragments(){ return false; } - void PrepareVertex(){ method.PrepareVertex(); } - void GenerateTriangles(triangle Input input [3], inout TriangleStream triangleStream) - { - method.InitializeFromTriangle(input); - [unroll] - for (int i = 0; i < 3 ; i++) - { - streams = input[i]; - method.Append(triangleStream); - } - method.RestartStrip(triangleStream); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl deleted file mode 100644 index 67fe02142f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureClipmapShader.sdsl +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelStorageTextureClipmapShader : VoxelStorageTextureShader, Texturing -{ - #define MapCount 20 - cbuffer PerView.Lighting - { - float4 perMapOffsetScale[MapCount]; - } - rgroup PerView.Lighting - { - Texture3D clipMaps; - Texture3D mipMaps; - } - - stage SamplerState LinearBorderSampler3D - { - Filter = MIN_MAG_MIP_LINEAR; - AddressU = Border; - AddressV = Border; - AddressW = Border; - }; - stage SamplerState LinearBorderSampler3D_NearestMip - { - Filter = MIN_MAG_LINEAR_MIP_POINT; - AddressU = Border; - AddressV = Border; - AddressW = Border; - }; - override float VoxelSize() - { - return voxelSizeT; - } - override float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis) - { - if (textureID == 0) - { - return clipMaps.SampleLevel(Sampler, pos, 0); - } - else - { - return mipMaps.SampleLevel(Sampler, pos, mipmap); - } - return float4(0,0,0,0); - } - - override float4 SampleNearestMip(float3 pos, float diameter, int axis) - { - diameter *= 1.0 / voxelSizeT; - float mipmap = log2(max(1, diameter)); - return SampleByMipNearestMip(pos, mipmap, axis); - } - override float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis) - { - //Clipmaps - float3 clipMapSizeClip = float3(1, 1.0 / (clipCountT * axisCountT), 1); - float3 axisStrideClip = float3(0, 1.0 / (clipCountT * axisCountT), 0); - float3 clipSetStrideClip = float3(0, 1.0 / clipCountT, 0); - - //Mipmaps - float3 axisSizeMip = float3(1, 1.0 / (axisCountT), 1); - float3 axisStrideMip = float3(0, 1.0 / (axisCountT), 0); - - float mipBase = floor(mipmap); - - float4 offsetScale = perMapOffsetScale[mipBase]; - pos = pos * offsetScale.w + offsetScale.xyz; - - if (mipBase >= clipCountT) - { - //Seperate the different axis within the same texture - //by clamping to the usable texel range - //and fading out above and below - float boundaryFade = 1.0; - if (axisCountT > 1) - { - float height = mipHeightT / (pow(2, mipBase - clipCountT)); - - float texelY = pos.y * height; - float texelYClamped = clamp(texelY, 1, height - 1); - float boundaryFade = saturate(1.0 - abs(texelYClamped - texelY)); - - pos.y = texelYClamped / height; - - pos *= axisSizeMip; - pos += axisStrideMip * axis; - } - return mipMaps.SampleLevel(LinearBorderSampler3D_NearestMip, pos, mipBase - clipCountT) * boundaryFade; - } - else - { - pos.y = saturate(pos.y); - - pos *= clipMapSizeClip; - pos += axisStrideClip * axis + clipSetStrideClip * mipBase; - return clipMaps.SampleLevel(LinearBorderSampler3D_NearestMip, pos, 0); - } - } - override float4 Sample(float3 pos, float diameter, int axis) - { - //Clipmaps - float3 clipMapSizeClip = float3(1, 1.0 / (clipCountT * axisCountT), 1); - float3 axisStrideClip = float3(0, 1.0 / (clipCountT * axisCountT), 0); - float3 clipSetStrideClip = float3(0, 1.0 / clipCountT, 0); - - //Mipmaps - float3 axisSizeMip = float3(1, 1.0 / (axisCountT), 1); - float3 axisStrideMip = float3(0, 1.0 / (axisCountT), 0); - - - diameter *= 1.0 / voxelSizeT; - float mipmap = log2(max(1, diameter)); - - float mipBase = floor(mipmap); - - - float4 offsetScale = perMapOffsetScale[mipBase]; - float3 posFine = pos * offsetScale.w + offsetScale.xyz; - - offsetScale = perMapOffsetScale[mipBase + 1]; - float3 posCoarse = pos * offsetScale.w + offsetScale.xyz; - if (mipBase >= clipCountT) - { - //Seperate the different axis within the same texture - //by clamping to the usable texel range - //and fading out above and below - float boundaryFade = 1.0; - if (axisCountT > 1) - { - float height = mipHeightT / (pow(2, mipBase - clipCountT)); - - float texelY = posFine.y * height; - float texelYClamped = clamp(texelY, 1, height - 1); - float boundaryFade = saturate(1.0 - abs(texelYClamped - texelY)); - - posFine.y = texelYClamped / height; - - posFine *= axisSizeMip; - posFine += axisStrideMip * axis; - - posCoarse *= axisSizeMip; - posCoarse += axisStrideMip * axis; - } - return lerp ( - mipMaps.SampleLevel(LinearBorderSampler3D, posFine, mipBase - clipCountT), - mipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, mipBase - clipCountT + 1), - mipmap - mipBase) * boundaryFade; - } - else - { - posFine.y = saturate(posFine.y); - posCoarse.y = saturate(posCoarse.y); - if (mipBase == clipCountT-1) - { - posFine *= clipMapSizeClip; - posFine += axisStrideClip * axis + clipSetStrideClip * mipBase; - - posCoarse *= axisSizeMip; - posCoarse += axisStrideMip * axis; - return lerp( - clipMaps.SampleLevel(LinearBorderSampler3D, posFine, 0), - mipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, 0), - mipmap-mipBase - ); - } - else - { - posFine *= clipMapSizeClip; - posFine += axisStrideClip * axis + clipSetStrideClip * mipBase; - - posCoarse *= clipMapSizeClip; - posCoarse += axisStrideClip * axis + clipSetStrideClip * (mipBase+1); - return lerp( - clipMaps.SampleLevel(LinearBorderSampler3D, posFine, 0), - clipMaps.SampleLevel(LinearBorderSampler3D, posCoarse, 0), - mipmap-mipBase - ); - } - } - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl deleted file mode 100644 index d1d86dd1dd..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelStorageTextureShader.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelStorageTextureShader -{ - float4 Sample(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } - float4 SampleNearestMip(float3 pos, float diameter, int axis){ return float4(0, 1, 0, 0); } - float4 SampleByMipNearestMip(float3 pos, float mipmap, int axis){ return float4(0, 1, 0, 0); } - float4 SampleRaw(float3 pos, float mipmap, int textureID, int axis){ return float4(1, 0, 0, 0); } - float VoxelSize(){ return 1.0; } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl deleted file mode 100644 index d63df75527..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawEffect.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels.Debug -{ - effect VoxelVisualizationRawEffect - { - using params VoxelVisualizationRawShaderKeys; - - mixin VoxelVisualizationRawShader; - if (VoxelVisualizationRawShaderKeys.Attribute != null) - { - mixin compose Attribute = VoxelVisualizationRawShaderKeys.Attribute; - } - } -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl deleted file mode 100644 index 200a24c716..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationRawShader.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels.Debug -{ - shader VoxelVisualizationRawShader : ImageEffectShader - { - compose IVoxelSampler Attribute; - float2 range; - float rangeOffset; - float mip; - - stage override float4 Shading() - { - float2 offsetRange = range + float(abs(range.y-range.x) * rangeOffset).xx; - float2 screenPos = streams.TexCoord.xy; - screenPos.y = 1.0 - screenPos.y; - - float4 color = float4(0, 0, 0, 0); - for (int i = 0; i < 200; i++) - { - color += Attribute.SampleRaw(float3(streams.TexCoord.x, lerp(offsetRange.x, offsetRange.y, (float)i / 200.0), streams.TexCoord.y), mip-1, (mip>0)?1:0, 0) * (1.0 - color.a); - if (color.a > 0.99) - { - break; - } - } - return color.xyzz + float4(0.1, 0.1, 0.1, 1.0) * (1.0 - color.a); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl deleted file mode 100644 index f458e6f9a7..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewEffect.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels.Debug -{ - effect VoxelVisualizationViewEffect - { - using params VoxelVisualizationViewShaderKeys; - using params MarchAttributesKeys; - - mixin VoxelVisualizationViewShader; - if (VoxelVisualizationViewShaderKeys.marcher != null) - { - mixin compose marcher = VoxelVisualizationViewShaderKeys.marcher; - } - if (MarchAttributesKeys.AttributeSamplers != null) - { - foreach (var attr in MarchAttributesKeys.AttributeSamplers) - { - mixin compose AttributeSamplers += (attr); - } - } - } -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl deleted file mode 100644 index 09594aed14..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelVisualizationViewShader.sdsl +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels.Debug -{ - shader VoxelVisualizationViewShader : MarchAttributes, ImageEffectShader - { - compose VoxelMarchMethod marcher; - - float4 background; - float4x4 view; - float4x4 viewInv; - - stage override float4 Shading() - { - float2 screenPos = streams.TexCoord.xy; - screenPos.y = 1.0 - screenPos.y; - - float4 p1 = mul(float4(screenPos*2.0-1.0,1,1), viewInv); - p1.xyz/=p1.w; - float4 p2 = mul(float4(0,0,0,1), viewInv); - p2.xyz/=p2.w; - - float3 rayDir = normalize( p1.xyz - p2.xyz); - float3 rayPos = p2.xyz; - - float4 color = marcher.March(rayPos, rayDir); - return color.xyzz + background * saturate(1.0-color.a); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelizationMethod.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelizationMethod.sdsl deleted file mode 100644 index 0923c50d6f..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelizationMethod.sdsl +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader VoxelizationMethod : VoxelPositionStream, PositionStream4, ShaderBaseStream -{ - void PrepareFragment(){ } - void PrepareVertex(){ } - - void InitializeFromTriangle(triangle Input input[3]) { } - - void Append(inout TriangleStream triangleStream) - { - streams.ShadingPosition.z = streams.ShadingPosition.z * 0.5 + 0.5; - triangleStream.Append(streams); - } - void RestartStrip(inout TriangleStream triangleStream) - { - triangleStream.RestartStrip(); - } -}; diff --git a/sources/shaders/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl deleted file mode 100644 index 23dda41cde..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelizationMethodDominantAxis.sdsl +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - /// - /// Voxelization, projects to axis of largest area and writes fragments to buffer - /// - shader VoxelizationMethodDominantAxis : VoxelizationMethod, Math, Transformation, ShaderBase, NormalStream, PositionStream4, VoxelPositionStream - { - centroid stream float3 centroidPositionWS; - centroid stream float3 centroidNormalWS; - override void PrepareFragment() - { - streams.PositionWS = float4(streams.centroidPositionWS,1); - streams.normalWS = streams.centroidNormalWS; - } - override void PrepareVertex() - { - streams.centroidPositionWS = streams.PositionWS.xyz; - streams.centroidNormalWS = streams.normalWS.xyz; - } - stream int dominantAxis; - override void InitializeFromTriangle(triangle Input input[3]) - { - float3 nor = abs(cross((input[1].ShadingPosition.xyz - input[0].ShadingPosition.xyz), (input[2].ShadingPosition.xyz - input[0].ShadingPosition.xyz))); - streams.dominantAxis = nor.x > nor.y ? 0 : 1; - streams.dominantAxis = nor.z > nor.y && nor.z > nor.x ? 2 : streams.dominantAxis; - } - void TransformPoint(inout float4 v1) - { - if (streams.dominantAxis == 0) - { - v1.xyz = float3(v1.yzx); - } - else if (streams.dominantAxis == 1) - { - v1.xyz = float3(v1.xzy); - } - v1.w = 1; - } - override void Append(inout TriangleStream triangleStream) - { - TransformPoint(streams.ShadingPosition); - streams.ShadingPosition.z = streams.ShadingPosition.z * 0.5 + 0.5; - triangleStream.Append(streams); - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl deleted file mode 100644 index 1462f37243..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelizationMethodSingleAxis.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - /// - /// Voxelization, projects to axis of largest area and writes fragments to buffer - /// - shader VoxelizationMethodSingleAxis : VoxelizationMethod, Math, Transformation, ShaderBase, NormalStream, PositionStream4, VoxelPositionStream - { - centroid stream float3 centroidPositionWS; - override void PrepareFragment() - { - streams.PositionWS = float4(streams.centroidPositionWS,1); - } - override void PrepareVertex() - { - streams.centroidPositionWS = streams.PositionWS.xyz; - } - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelizeToFragments.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelizeToFragments.sdsl deleted file mode 100644 index e5ab198df6..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelizeToFragments.sdsl +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Voxels -{ - /// - /// Voxelization, projects to axis of largest area and writes fragments to buffer - /// - shader VoxelizeToFragments : Math, Transformation, ShaderBase, Texturing, NormalStream, PositionStream4, VoxelPositionStream, MaterialPixelStream, MaterialPixelShadingStream - { - compose VoxelStorageShader Storage; - override stage void PSMain() - { - Storage.PrepareFragments(); - streams.IsFrontFace = true; - if (Storage.MightStoreFragments()) - { - base.PSMain(); - Storage.StoreFragments(); - streams.ColorTarget = float4(0,0,0,0); - } - } - override stage void VSMain() - { - base.VSMain(); - Storage.PrepareVertex(); - } - #ifdef RequireGeometryShader - [maxvertexcount(GeometryShaderMaxVertexCount)] - void GSMain(triangle Input input[3], inout TriangleStream triangleStream) - { - Storage.GenerateTriangles(input, triangleStream); - } - #endif - }; -} diff --git a/sources/shaders/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl b/sources/shaders/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl deleted file mode 100644 index 3a876b4ec0..0000000000 --- a/sources/shaders/assets/Stride/SDSL/VoxelizeToFragmentsEffect.sdsl +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Sean Boettger -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Stride.Rendering.Materials; -using Stride.Rendering.Voxels; - -namespace Stride.Rendering.Voxels -{ - partial effect VoxelizeToFragmentsEffect - { - using params MaterialKeys; - using params VoxelizeToFragmentsKeys; - - mixin VoxelizeToFragments; - if (VoxelizeToFragmentsKeys.Storage!=null) - { - mixin compose Storage = (VoxelizeToFragmentsKeys.Storage); - } - if (VoxelizeToFragmentsKeys.RequireGeometryShader == true) - { - mixin macro RequireGeometryShader = true; - mixin macro VoxelizeToFragmentsKeys.GeometryShaderMaxVertexCount; - } - }; -} diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index d6f71575a6..202f2ce2fd 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -75,8 +75,6 @@ - - From 4a004331f865b07457f222e3f996e24bdea1849f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Feb 2026 15:21:36 +0900 Subject: [PATCH 0838/1182] SDSL: removed unused code --- .../Spirv/Processing/Interfaces/InterfaceProcessor.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index ce011df1dc..80e274d6b8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -211,15 +211,6 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) var stage = ExecutionModelToStageId(executionModel); - - - bool AddBuiltin(int variable, BuiltIn builtin) => BuiltinProcessor.AddBuiltin(context, variable, builtin); - - bool AddLocation(int variable, string location) => BuiltinProcessor.AddLocation(context, variable, location); - - int ConvertInterfaceVariable(SymbolType sourceType, SymbolType castType, int value) => - BuiltinProcessor.ConvertInterfaceVariable(buffer, context, sourceType, castType, value); - var entryPointFunctionType = (FunctionType)entryPoint.Type; // TODO: check all parameters instead of hardcoded 0 int? arrayInputSize = executionModel switch From f3fff48bf83aada6f6b098e7dd62e57fe4b0fd5f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 16:40:36 +0900 Subject: [PATCH 0839/1182] SDSL: added support for doing binary operations on Streams/struct, i.e. input[2] * 0.5f (typically used in tessellation stage) --- .../IntrinsicGenerator.cs | 1 + .../Parsing/Analysis/SymbolTable.cs | 12 ++ .../Spirv/Building/BasicBlocks.cs | 41 ----- .../Spirv/Building/Builder.Expressions.cs | 173 +++++++++++++----- .../Spirv/Building/ExpressionExtensions.cs | 1 + .../Interfaces/InterfaceProcessor.cs | 2 +- .../Interfaces/Models/StreamVariableInfo.cs | 8 +- .../Transformation/StreamAccessPatcher.cs | 27 ++- .../Buffers/SpirvBuffer.cs | 23 ++- .../Extensions/spirv.sdsl.grammar-ext.json | 11 ++ .../Stride.Shaders.Spirv.Core/SpirvValue.cs | 31 ++++ .../SPVGenerator.Instructions.cs | 10 + 12 files changed, 253 insertions(+), 87 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index 3af416257d..75535e4d0c 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -148,6 +148,7 @@ namespace Stride.Shaders.Parsing.SDSL; using System.Collections.Frozen; using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; + using Stride.Shaders.Spirv.Core; using Stride.Shaders.Parsing.Analysis; """); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index d2fd4ca826..b044d413c3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -80,6 +80,18 @@ public bool TryResolveSymbol(int id, [MaybeNullWhen(false)] out Symbol symbol) symbol = symbol2.Value; return true; } + // Check function groups + if (symbol2.Value.Type is FunctionGroupType) + { + foreach (var symbol3 in symbol2.Value.GroupMembers) + { + if (symbol3.IdRef == id) + { + symbol = symbol3; + return true; + } + } + } } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs index 17cf184ca4..bc9a9ecb5c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs @@ -1,50 +1,9 @@ using Stride.Shaders.Core; using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Spirv.Building; - - -/// -/// A SPIR-V value representing the result of an instruction -/// -public struct SpirvValue -{ - /// IdResult of the instruction - /// IdResultType of the instruction - /// Optional name attached to the value - public SpirvValue(IdRef id, IdRef typeId, string? name = null) - { - Id = id; - TypeId = typeId; - Name = name; - } - - public SpirvValue(OpData instruction, string? name = null) - { - if (InstructionInfo.GetInfo(instruction).GetResultIndex(out var index)) - Id = instruction.Memory.Span[index + 1]; - if (InstructionInfo.GetInfo(instruction).GetResultTypeIndex(out var typeIndex)) - TypeId = instruction.Memory.Span[typeIndex + 1]; - Name = name; - } - public int Id { get; set; } - public int TypeId { get; set; } - public string? Name { get; set; } - - public SymbolType GetValueType(SpirvContext context) - { - var type = context.ReverseTypes[TypeId]; - if (type is PointerType p) - type = p.BaseType; - - return type; - } -} - - /// /// Interface for SpirvBlock and SpirvFunction to avoid duplicating code. /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 6664a87ef1..007f339d6d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -119,6 +119,24 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOperation(SymbolTable table, SymbolType leftType, Operator op, SymbolType rightType, TextLocation info) { + static bool IsComplexType(SymbolType type) => type is StreamsType or StructType; + + // struct or streams types + var complexType = IsComplexType(leftType) ? leftType : (IsComplexType(rightType) ? rightType : null); + if (complexType != null) + { + // Only simple operations are allowed (they will be applied on each member) + var otherType = IsComplexType(leftType) ? rightType : leftType; + if (otherType is not ScalarType { Type: Scalar.Float } and not StreamsType + || (op != Operator.Plus && op != Operator.Minus && op != Operator.Mul && op != Operator.Div)) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); + return null; + } + + return (complexType, complexType); + } + var leftElementType = leftType.GetElementType(); var rightElementType = rightType.GetElementType(); @@ -172,11 +190,79 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper return (operandType, resultType); } - public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, SpirvValue left, Operator op, SpirvValue right, TextLocation info, string? name = null) + public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, SpirvValue left, Operator op, SpirvValue right, TextLocation info, string? name = null, int? desiredResultId = null) { var leftType = context.ReverseTypes[left.TypeId]; var rightType = context.ReverseTypes[right.TypeId]; + var resultId = desiredResultId ?? context.Bound++; + + var streamsType = leftType as StreamsType ?? rightType as StreamsType; + if (streamsType != null) + { + // We can't expand yet as we don't know all the members, encode it with a custom SPIR-V opcode + // It will be processed later by StreamAccessPatcher + return Buffer.Insert(Position++, new OpBinaryOperationSDSL(context.GetOrRegister(streamsType), resultId, (int)op, left.Id, right.Id)).ToValue(); + } + + var structType = leftType as StructType ?? rightType as StructType; + if (structType != null) + { + // If there is a struct, we simply apply the operation for each member + // (this is SDSL-specific) + var structValue = leftType is StructType ? left : right; + var otherType = leftType is StructType ? rightType : leftType; + var otherValue = leftType is StructType ? right : left; + + Span structValues = stackalloc int[structType.Members.Count]; + for (var i = 0; i < structType.Members.Count; i++) + { + var member = structType.Members[i]; + var memberValue = Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(member.Type), context.Bound++, structValue.Id, [i])).ToValue(); + + var otherMemberValue = otherType switch + { + // If the other value is also a struct of same type, extract its value + StructType otherStructType when otherStructType == structType + => Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(member.Type), context.Bound++, otherValue.Id, [i])).ToValue(), + ScalarType => otherValue, + }; + memberValue = leftType is StructType + ? BinaryOperation(table, context, memberValue, op, otherMemberValue, info, name) + : BinaryOperation(table, context, otherMemberValue, op, memberValue, info, name); + structValues[i] = memberValue.Id; + } + + return Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(structType), resultId, [..structValues])).ToValue(); + } + + // Can indirectly happen inside struct (SDSL specific) + var arrayType = leftType as ArrayType ?? rightType as ArrayType; + if (arrayType != null) + { + var arrayValue = leftType is ArrayType ? left : right; + var otherType = leftType is ArrayType ? rightType : leftType; + var otherValue = leftType is ArrayType ? right : left; + + Span arrayValues = stackalloc int[arrayType.Size]; + for (int i = 0; i < arrayType.Size; ++i) + { + var memberValue = Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(arrayType.BaseType), context.Bound++, arrayValue.Id, [i])).ToValue(); + var otherMemberValue = otherType switch + { + // If the other value is also a struct of same type, extract its value + ArrayType otherArrayType when otherArrayType == arrayType + => Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(arrayType.BaseType), context.Bound++, otherValue.Id, [i])).ToValue(), + ScalarType => otherValue, + }; + arrayValues[i] = leftType is StructType + ? BinaryOperation(table, context, memberValue, op, otherMemberValue, info, name).Id + : BinaryOperation(table, context, otherMemberValue, op, memberValue, info, name).Id; + } + + return Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(arrayType), resultId, [.. arrayValues])).ToValue(); + } + (var operandType, var resultType) = AnalyzeBinaryOperation(table, leftType, op, rightType, info) ?? throw new InvalidOperationException("Type of binary operation could not be determined"); // TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations) @@ -197,132 +283,132 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv { (Operator.Plus, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpIAdd(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIAdd(resultTypeId, resultId, left.Id, right.Id)), (Operator.Plus, SymbolType l, SymbolType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFAdd(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFAdd(resultTypeId, resultId, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpISub(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpISub(resultTypeId, resultId, left.Id, right.Id)), (Operator.Minus, SymbolType l, SymbolType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFSub(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFSub(resultTypeId, resultId, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpIMul(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIMul(resultTypeId, resultId, left.Id, right.Id)), (Operator.Mul, SymbolType l, SymbolType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFMul(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFMul(resultTypeId, resultId, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsUnsignedInteger() && r.IsUnsignedInteger() - => Buffer.InsertData(Position++, new OpUDiv(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUDiv(resultTypeId, resultId, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpSDiv(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSDiv(resultTypeId, resultId, left.Id, right.Id)), (Operator.Div, SymbolType l, SymbolType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFDiv(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFDiv(resultTypeId, resultId, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsUnsignedInteger() && r.IsUnsignedInteger() - => Buffer.InsertData(Position++, new OpUMod(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUMod(resultTypeId, resultId, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpSMod(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSMod(resultTypeId, resultId, left.Id, right.Id)), (Operator.Mod, SymbolType l, SymbolType r) when l.IsFloating() && r.IsNumber() - => Buffer.InsertData(Position++, new OpFMod(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFMod(resultTypeId, resultId, left.Id, right.Id)), (Operator.RightShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, resultId, left.Id, right.Id)), (Operator.LeftShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, resultId, left.Id, right.Id)), (Operator.AND, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseAnd(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseAnd(resultTypeId, resultId, left.Id, right.Id)), (Operator.OR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseOr(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseOr(resultTypeId, resultId, left.Id, right.Id)), (Operator.XOR, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseXor(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpBitwiseXor(resultTypeId, resultId, left.Id, right.Id)), (Operator.LogicalAND, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalAnd(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalAnd(resultTypeId, resultId, left.Id, right.Id)), (Operator.LogicalOR, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, resultId, left.Id, right.Id)), (Operator.Equals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.Equals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) - => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.Equals, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.NotEquals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpLogicalNotEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.NotEquals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) - => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.NotEquals, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdNotEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdNotEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.Lower, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.Lower, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpULessThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpULessThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.Lower, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdLessThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdLessThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.LowerOrEqual, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdLessThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdLessThanEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.Greater, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.Greater, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpUGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUGreaterThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.Greater, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdGreaterThan(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdGreaterThan(resultTypeId, resultId, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpUGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpUGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), (Operator.GreaterOrEqual, ScalarType l, ScalarType r) when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, context.Bound++, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), _ => throw new NotImplementedException() }; if (name is not null) - context.AddName(instruction.IdResult ?? -1, name); - return new(instruction, name); + context.AddName(resultId, name); + return new(resultId, resultTypeId, name); } /// @@ -615,6 +701,11 @@ public SpirvValue CallFunction(SymbolTable table, SpirvContext context, Symbol f internal static class SymbolExtensions { + public static SymbolType GetValueType(this SpirvValue value, SpirvContext context) + { + return context.ReverseTypes[value.TypeId].GetValueType(); + } + public static SymbolType GetValueType(this SymbolType type) { return type switch @@ -719,4 +810,4 @@ public static bool SameSignage(SymbolType left, SymbolType right) (MatrixType l, MatrixType r) => l.BaseType == r.BaseType, _ => false }; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs index 177df1c305..9ed4cdd55c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs @@ -2,6 +2,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using static Stride.Shaders.Spirv.Specification; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 80e274d6b8..f47b28d7fc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -244,7 +244,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) if (method.Value.UsedThisStage && method.Value.HasStreamAccess) { MethodDuplicator.DuplicateMethodIfNecessary(buffer, context, method.Key, analysisResult, liveAnalysis, CodeInserted); - StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis); + StreamAccessPatcher.PatchStreamsAccesses(table, buffer, context, method.Key, streamsType, inputType, outputType, constantsType, streamsVariable.ResultId, analysisResult, liveAnalysis, CodeInserted); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs index f41976db0f..4742b843a2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs @@ -38,5 +38,11 @@ internal class StreamVariableInfo(string? semantic, string name, PointerType typ // Note: if Patch is true, it will be index in CONSTANTS struct, otherwise STREAMS struct public int StreamStructFieldIndex { get; internal set; } - public override string ToString() => $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; + public override string ToString() + { + var result = $"{Type} {Name} {(Read ? "R" : "")} {(Write ? "W" : "")}"; + if (Semantic != null) + result += $" : {Semantic}"; + return result; + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index d2c0191ddd..73b2b24c20 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -1,3 +1,4 @@ +using CommunityToolkit.HighPerformance; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; @@ -44,7 +45,8 @@ public static void PatchStreamsAccesses( StructType? constantsStructType, int streamsVariableId, AnalysisResult analysisResult, - LiveAnalysis liveAnalysis) + LiveAnalysis liveAnalysis, + Action? codeInserted = null) { var methodInfo = liveAnalysis.GetOrCreateMethodInfo(functionId); @@ -131,6 +133,29 @@ void CheckStreamTypes(int id) accessChain.BaseId = accessChain.BaseId; } } + else if (i.Op == Op.OpBinaryOperationSDSL && (OpBinaryOperationSDSL)i is {} binaryOperation) + { + var targetType = (StreamsType)context.ReverseTypes[binaryOperation.ResultType]; + + if (!buffer.TryGetTypeId(binaryOperation.Operand1, out var leftType) + || !buffer.TryGetTypeId(binaryOperation.Operand2, out var rightType)) + { + throw new InvalidOperationException("Can't figure out operand types in OpBinaryOperationSDSL"); + } + + // Emit expanded code in temp buffer + var builder = new SpirvBuilder(); + builder.BinaryOperation(table, context, new(binaryOperation.Operand1, leftType), (Operator)binaryOperation.Operation, new(binaryOperation.Operand2, rightType), default, desiredResultId: binaryOperation.ResultId); + + // Replace OpBinaryOperationSDSL with expanded code + buffer.RemoveAt(index); + var instructions = new List(); + foreach (var inst in builder.GetBuffer()) + instructions.Add(inst.Data); + buffer.InsertRange(index, instructions.AsSpan()); + + codeInserted?.Invoke(index--, instructions.Count - 1); + } else if (i.Op == Op.OpCopyLogical && (OpCopyLogical)i is { } copyLogical) { // Cast input to streams diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index faf3afecf6..04badcbd09 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -192,12 +192,31 @@ public Span ToBytecode() return SpirvBytecode.CreateBytecodeFromBuffers(this); } - public bool TryGetInstructionById(int typeId, out OpDataIndex instruction) + /// + /// Gets type ID from value ID. Only work if the defining type instruction ID has a ResultType operand. + /// + public bool TryGetTypeId(int id, out int typeId) + { + typeId = default; + if (TryGetInstructionById(id, out var instruction)) + { + var info = InstructionInfo.GetInfo(instruction.Op); + if (info.GetResultTypeIndex(out int typeIndex) && typeIndex < instruction.Data.Memory.Length) + { + typeId = instruction.Data.Memory.Span[typeIndex + 1]; + return true; + } + } + + return false; + } + + public bool TryGetInstructionById(int id, out OpDataIndex instruction) { foreach (var op in this) { var info = InstructionInfo.GetInfo(op.Op); - if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == typeId) + if (info.GetResultIndex(out int index) && index < op.Data.Memory.Length && op.Data.Memory.Span[index + 1] == id) { instruction = op; return true; diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index 48815c26f5..dd10b92836 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -364,6 +364,17 @@ } ] }, + { + "opname": "OpBinaryOperationSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind": "IdResultType" }, + { "kind": "IdResult" }, + { "kind" : "LiteralInteger", "name" : "'Operation'" }, + { "kind" : "IdRef", "name" : "'Operand 1'" }, + { "kind" : "IdRef", "name" : "'Operand 2'" } + ] + }, { "opname": "OpEffectSDFX", "opcode" : 9000, diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs b/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs new file mode 100644 index 0000000000..1a6c77e403 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs @@ -0,0 +1,31 @@ +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Core; + +/// +/// A SPIR-V value representing the result of an instruction +/// +public struct SpirvValue +{ + /// IdResult of the instruction + /// IdResultType of the instruction + /// Optional name attached to the value + public SpirvValue(IdRef id, IdRef typeId, string? name = null) + { + Id = id; + TypeId = typeId; + Name = name; + } + + public SpirvValue(OpData instruction, string? name = null) + { + if (InstructionInfo.GetInfo(instruction).GetResultIndex(out var index)) + Id = instruction.Memory.Span[index + 1]; + if (InstructionInfo.GetInfo(instruction).GetResultTypeIndex(out var typeIndex)) + TypeId = instruction.Memory.Span[typeIndex + 1]; + Name = name; + } + public int Id { get; set; } + public int TypeId { get; set; } + public string? Name { get; set; } +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 16f20d0796..b0ad1fc9e9 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -147,6 +147,16 @@ private set structBuilder.AppendLine(@$" public static implicit operator int({instruction.OpName}{(instruction.OpName.EndsWith("Constant") ? "" : "")} inst) => inst.ResultId;" ); + + if (operands.Any(x => x is { Kind: "IdResultType" })) + { + var resultTypeOperand = operands.First(x => x is { Kind: "IdResultType" }); + structBuilder.AppendLine(@$" + public static implicit operator SpirvValue({instruction.OpName}{(instruction.OpName.EndsWith("Constant") ? "" : "")} inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, {ToTypeFieldAndOperandName(resultTypeOperand).FieldName}); + " + ); + } } structBuilder.AppendLine(@$" public {instruction.OpName}({string.Join(", ", operands.Select(ToFunctionParameters))}) From 69fd55d36e8854ad475f427a3ff5aa46f224de25 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 16:41:17 +0900 Subject: [PATCH 0840/1182] SDSL: support more kind of builtin conversion (esp. scalar <=> arrays/vector) --- .../Interfaces/Generation/BuiltinProcessor.cs | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index f45bf82b41..d517e49a51 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -46,33 +46,33 @@ public static int ConvertInterfaceVariable( if (sourceType == castType) return value; - if (sourceType is VectorType v1 && castType is VectorType v2 && v1.BaseType == v2.BaseType) - { - Span components = stackalloc int[v2.Size]; - for (int i = 0; i < v2.Size; ++i) - { - components[i] = i < v1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(v1.BaseType), context.Bound++, value, [i])).ResultId - : context.CreateDefaultConstantComposite(v1.BaseType).Id; - } + var (castSize, castBaseType) = ExtractSizeAndBaseType(castType); + var (sourceSize, sourceBaseType) = ExtractSizeAndBaseType(sourceType); + + if (castBaseType != sourceBaseType) + throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); + + Span components = stackalloc int[castSize]; - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(v2), context.Bound++, new(components))).ResultId; + for (int i = 0; i < castSize; ++i) + { + components[i] = i < sourceSize + ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(sourceBaseType), context.Bound++, value, [i])).ResultId + : context.CreateDefaultConstantComposite(sourceBaseType).Id; } - if (sourceType is ArrayType a1 && castType is ArrayType a2 && a1.BaseType == a2.BaseType) + return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(castType), context.Bound++, new(components))).ResultId; + + (int Size, SymbolType baseType) ExtractSizeAndBaseType(SymbolType castType) { - Span components = stackalloc int[a2.Size]; - for (int i = 0; i < a2.Size; ++i) + return castType switch { - components[i] = i < a1.Size - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(a1.BaseType), context.Bound++, value, [i])).ResultId - : context.CreateDefaultConstantComposite(a1.BaseType).Id; - } - - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(a2), context.Bound++, new(components))).ResultId; + ScalarType s => (1, s), + VectorType v => (v.Size, v.BaseType), + ArrayType a => (a.Size, a.BaseType), + _ => throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"), + }; } - - throw new InvalidOperationException($"Can't convert interface variable from {sourceType} to {castType}"); } /// From dd23416535b5e974c501c6ee4b0973bedbf95a29 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 16:41:57 +0900 Subject: [PATCH 0841/1182] Tessellation: Make sure TessellationBase.ComputeClipping() returns a value --- .../Rendering/Tessellation/TessellationBase.sdsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl index ebea982d65..9be1609af0 100644 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl @@ -121,7 +121,7 @@ shader TessellationBase : ShaderBase, TransformationBase, MaterialDomainStream, stage void TessellateHull(InputPatch input, uint uCPID, uint NextCPID) {} stage void TessellateHullConstant(InputPatch input, const OutputPatch output, inout Constants constants) {} - stage float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) {} + stage float ComputeClipping(InputPatch input, const OutputPatch output, inout Constants constants) { return 0.0f; } stage void InterpolateBarycentric(const OutputPatch input, in Constants constants, float3 f3BarycentricCoords) {} stage void TessellateDomain() {} }; From 7ae07160af7e190f05c4ab64d33e5e4f32574226 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Feb 2026 16:43:00 +0900 Subject: [PATCH 0842/1182] SDSL: InterfaceProcessor, better process tessellation stage in order and expect SV_Position only once --- .../Interfaces/InterfaceProcessor.cs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index f47b28d7fc..2417325834 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -106,7 +106,11 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex VariableMerger.PropagateStreamsFromPreviousStage(streams); - foreach (var entryPoint in new[] { (ExecutionModel.TessellationControl, entryPointHS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.Geometry, entryPointGS) }) + // Remember if a stage output SV_Position already (it should be the first active stage before pixel shader) + bool requirePosition = true; + + // Reminder: we process stage in reverse GPU execution order + foreach (var entryPoint in new[] { (ExecutionModel.Geometry, entryPointGS), (ExecutionModel.TessellationEvaluation, entryPointDS), (ExecutionModel.TessellationControl, entryPointHS) }) { if (entryPoint.Item2 != null) { @@ -122,8 +126,11 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex { if (stream.Value.Semantic is { } semantic) { - if (semantic.ToUpperInvariant().StartsWith("SV_POSITION")) + if (semantic.ToUpperInvariant().StartsWith("SV_POSITION") && requirePosition) + { stream.Value.Output = true; + requirePosition = false; + } if (entryPoint.Item1 == ExecutionModel.TessellationControl && (semantic.ToUpperInvariant().StartsWith("SV_TESSFACTOR") || semantic.ToUpperInvariant().StartsWith("SV_INSIDETESSFACTOR"))) @@ -157,8 +164,14 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader foreach (var stream in streams) { - if (stream.Value.Semantic is { } semantic && semantic.ToUpperInvariant().StartsWith("SV_POSITION")) - stream.Value.Output = true; + if (stream.Value.Semantic is { } semantic) + { + if (semantic.ToUpperInvariant().StartsWith("SV_POSITION") && requirePosition) + { + stream.Value.Output = true; + requirePosition = false; + } + } } (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); From 41096c48eebbcb9e77f3100d7bca22a47a741710 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Feb 2026 14:21:21 +0900 Subject: [PATCH 0843/1182] SDSL: fix sign() for float --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index f6316d6f72..d4316f9169 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -201,10 +201,11 @@ public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builde { var instruction = functionType.ReturnType.GetElementType() switch { - ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), - ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.UInt64 or Scalar.Int64 } => builder.InsertData(new GLSLFSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFSign(x.TypeId, context.Bound++, context.GetGLSL(), x.Id)), + ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.UInt64 or Scalar.Int64 } => builder.InsertData(new GLSLSSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), }; - return new(instruction); + // FSign return float whereas HLSL sign() expects int + return builder.Convert(context, new(instruction), functionType.ReturnType); } public override SpirvValue CompileSmoothstep(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue x) From 3a4b83e336a78806a50b0ebefd942247257d5687 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Feb 2026 14:37:18 +0900 Subject: [PATCH 0844/1182] SDSL: support non-bool condition in ternary expression --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 66de50c8dd..4f6de2a457 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1386,9 +1386,9 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { Condition.ProcessSymbol(table); - if (Condition.ValueType.GetElementType() is not ScalarType { Type: Scalar.Boolean }) + if (Condition.ValueType.GetElementType() is not ScalarType) table.AddError(new(Condition.Info, SDSLErrorMessages.SDSL0106)); - + Left.ProcessSymbol(table); Right.ProcessSymbol(table); @@ -1410,6 +1410,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var conditionValue = Condition.CompileAsValue(table, compiler); + // Might need implicit conversion from float/int to bool + conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); + // TODO: Review choice between if/else like branch (OpBranchConditional) which evaluate only one side, or select (OpSelect) which evaluate both side but can work per component but is limited to specific types // It seems HLSL 2021 changed the behavior to align it with C-style short-circuiting. // For now, we use OpSelect only with per-component, otherwise we use if/else branching From 629b05f72f09e6849ea02b4858488e6f040fca65 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Feb 2026 14:28:15 +0900 Subject: [PATCH 0845/1182] SDSL: various improvements for tessellation --- .../Parsing/SDSL/AST/Expression.cs | 11 +- .../Spirv/Building/Builder.Expressions.cs | 18 ++- .../Spirv/Building/Builder.Functions.cs | 4 +- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 111 ++++++++++++------ .../Interfaces/Generation/BuiltinProcessor.cs | 6 +- .../Generation/EntryPointWrapperGenerator.cs | 49 ++++---- .../Interfaces/InterfaceProcessor.cs | 27 ++--- .../Transformation/StreamAccessPatcher.cs | 40 +++++-- .../Stride.Shaders.Tests/StrideShaderTests.cs | 24 +++- 9 files changed, 195 insertions(+), 95 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 4f6de2a457..60fdb9ee27 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -921,12 +921,21 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } + // We emit chain access so far + // It's not necessary for SPIR-V, but StreamAccessPatcher.PatchStreamsAccesses() expect a simple format without + // multiple access chained (which make it harder to compute type) + EmitOpAccessChain(accessChainIds, i - 1); + // Since we cheated a bit by overwriting the accessor.Type, set it back during Compile() accessor.Type = (PointerType)accessor.Type with { StorageClass = Specification.StorageClass.Private }; // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now var streamVariableResult = streamVar.Compile(table, compiler); accessor.Type = (PointerType)accessor.Type with { StorageClass = p.StorageClass }; PushAccessChainId(accessChainIds, streamVariableResult.Id); + + // For same reason as before (we want easy to detect pattern for StreamAccessPatcher), emit again + currentValueType = accessor.Type; + EmitOpAccessChain(accessChainIds, i); break; case (PointerType { BaseType: StructType s } p, Identifier field): var index = s.TryGetFieldIndex(field); @@ -1470,4 +1479,4 @@ public override string ToString() { return $"({Condition} ? {Left} : {Right})"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 007f339d6d..ab72fb3ea4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -142,7 +142,11 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper // Check base types // TODO: special case for operators expecting different types (i.e. bit shifts) - var desiredElementType = FindCommonBaseTypeForBinaryOperation(leftElementType, rightElementType); + var desiredElementType = op switch + { + Operator.LogicalAND or Operator.LogicalOR => ScalarType.Boolean, + _ => FindCommonBaseTypeForBinaryOperation(leftElementType, rightElementType), + }; // Check size SymbolType resultType; @@ -183,8 +187,8 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper var operandType = resultType; // Comparisons and logical operators - if (op == Operator.Greater || op == Operator.Lower || op == Operator.GreaterOrEqual || op == Operator.LowerOrEqual - || op == Operator.NotEquals || op == Operator.Equals || op == Operator.LogicalAND || op == Operator.LogicalOR) + if (op is Operator.Greater or Operator.Lower or Operator.GreaterOrEqual or Operator.LowerOrEqual + or Operator.NotEquals or Operator.Equals or Operator.LogicalAND or Operator.LogicalOR) resultType = resultType.WithElementType(ScalarType.Boolean); return (operandType, resultType); @@ -643,8 +647,12 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Float }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), - (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, context.CompileConstant(0).Id)), - (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CompileConstant(0.0).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, + context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 1, new()), elementSize).Id, + context.CreateConstantCompositeVectorRepeat(new IntegerLiteral(new(32, false, true), 0, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, + context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, + context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), // Bitcast (int=>uint or uint=>int) (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs index 468a53b952..8fa1a5f931 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs @@ -67,7 +67,7 @@ public static OpFunctionParameter GetFunctionParameter(SpirvBuffer buffer, Symbo throw new InvalidOperationException(); } - public static void FunctionRemoveArgument(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex) + public static void FunctionRemoveParameter(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex) { var methodType = (FunctionType)method.Type; method.Type = methodType with { ParameterTypes = methodType.ParameterTypes[0..^1] }; @@ -77,7 +77,7 @@ public static void FunctionRemoveArgument(SpirvContext context, SpirvBuffer buff SetOpNop(functionParameter.InstructionMemory.Span); } - public static void FunctionReplaceArgument(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex, SymbolType newType) + public static void FunctionReplaceParameter(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex, SymbolType newType) { var methodType = (FunctionType)method.Type; var parameterTypes = new List(methodType.ParameterTypes); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index cbd187e9a3..ce9b646b34 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -37,10 +37,11 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont methodInstructions = buffer.Slice(methodStart, methodEnd - methodStart); } - var streamsInstructionIds = new HashSet(); + var streamsInstructionIds = new Dictionary(); + var patchInstructionIds = new Dictionary(); var streams = analysisResult.Streams; var variables = analysisResult.Variables; - var accessChainBases = new Dictionary(); + var accessChainBases = new Dictionary(); foreach (ref var i in CollectionsMarshal.AsSpan(methodInstructions)) { @@ -56,10 +57,10 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont else if (i.Op is Op.OpVariable && new OpVariable(ref i) is { } variable) { var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType { BaseType: StreamsType }) + if (type is PointerType { BaseType: StreamsType s }) { // Note: we should restrict to R except if inout variable - streamsInstructionIds.Add(variable.ResultId); + streamsInstructionIds.Add(variable.ResultId, s.Kind); methodInfo.HasStreamAccess = true; } } @@ -67,69 +68,111 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont else if (i.Op is Op.OpFunctionParameter && new OpFunctionParameter(ref i) is { } functionParameter) { var type = context.ReverseTypes[functionParameter.ResultType]; - if (type is PointerType { BaseType: StreamsType }) + if (type is PointerType { BaseType: StreamsType s }) { // Note: we should restrict to R except if inout variable - streamsInstructionIds.Add(functionParameter.ResultId); + streamsInstructionIds.Add(functionParameter.ResultId, s.Kind); + methodInfo.HasStreamAccess = true; + } + else if (type is PointerType { BaseType: PatchType { BaseType: StreamsType s2 } }) + { + patchInstructionIds.Add(functionParameter.ResultId, s2.Kind); methodInfo.HasStreamAccess = true; } } else if (i.Op is Op.OpLoad && new OpLoad(ref i) is { } load) { // Check for indirect access chains - if (!accessChainBases.TryGetValue(load.Pointer, out var pointer)) - pointer = load.Pointer; + if (!accessChainBases.TryGetValue(load.Pointer, out var accessChain)) + accessChain.Base = load.Pointer; + if (streams.TryGetValue(accessChain.Base, out var streamInfo)) + { + var streamKind = accessChain.StreamKind.Value; - if (streams.TryGetValue(pointer, out var streamInfo) && !streamInfo.Write) - streamInfo.Read = true; - if (variables.TryGetValue(pointer, out var variableInfo)) + // If read on input/output stream, we force it to be emitted in the input/output struct + if (streamKind == StreamsKindSDSL.Output) + streamInfo.Output = true; + else if (streamKind == StreamsKindSDSL.Input) + streamInfo.Read = true; + else + { + // In case of streams or constants access, check if there was a previous write on the variable + // (in which case it is read after being written, which we do not need to write as a read from previous stage) + if (!streamInfo.Write) + streamInfo.Read = true; + } + } + if (variables.TryGetValue(accessChain.Base, out var variableInfo)) variableInfo.UsedThisStage = true; - if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) + if (analysisResult.Resources.TryGetValue(accessChain.Base, out var resourceInfo)) resourceInfo.UsedThisStage = true; - if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + if (analysisResult.CBuffers.TryGetValue(accessChain.Base, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } else if (i.Op is Op.OpStore && new OpStore(ref i) is { } store) { // Check for indirect access chains - if (!accessChainBases.TryGetValue(store.Pointer, out var pointer)) - pointer = store.Pointer; + if (!accessChainBases.TryGetValue(store.Pointer, out var accessChain)) + accessChain.Base = store.Pointer; + + if (streams.TryGetValue(accessChain.Base, out var streamInfo)) + { + var streamKind = accessChain.StreamKind.Value; + // Write on input/output stream are not allowed + if (streamKind is StreamsKindSDSL.Input or StreamsKindSDSL.Output) + throw new InvalidOperationException("Can't write value on input or output struct"); - if (streams.TryGetValue(pointer, out var streamInfo)) streamInfo.Write = true; - if (variables.TryGetValue(pointer, out var variableInfo)) + } + if (variables.TryGetValue(accessChain.Base, out var variableInfo)) variableInfo.UsedThisStage = true; - if (analysisResult.Resources.TryGetValue(pointer, out var resourceInfo)) + if (analysisResult.Resources.TryGetValue(accessChain.Base, out var resourceInfo)) resourceInfo.UsedThisStage = true; - if (analysisResult.CBuffers.TryGetValue(pointer, out var cbufferInfo)) + if (analysisResult.CBuffers.TryGetValue(accessChain.Base, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } else if (i.Op == Op.OpStreamsSDSL && new OpStreamsSDSL(ref i) is { } streamsInstruction) { - streamsInstructionIds.Add(streamsInstruction.ResultId); + streamsInstructionIds.Add(streamsInstruction.ResultId, StreamsKindSDSL.Streams); methodInfo.HasStreamAccess = true; } else if (i.Op == Op.OpAccessChain && new OpAccessChain(ref i) is { } accessChain) { var currentBase = accessChain.BaseId; - // In case it's a streams access, mark the stream as being the base - if (streamsInstructionIds.Contains(currentBase)) + // In case it's a patch access, i.e. patch[0], mark the access as being a stream + if (patchInstructionIds.TryGetValue(currentBase, out var patchStreamKind)) { - var streamVariableId = accessChain.Values.Elements.Span[0]; - var streamInfo = streams[streamVariableId]; - - // Set this base for OpStore/OpLoad stream R/W analysis - currentBase = streamVariableId; + var patchVariableId = accessChain.Values.Elements.Span[0]; + if (accessChain.Values.Elements.Length > 1) + throw new InvalidOperationException("OpAccessChain on PatchType can have only 1 element"); + streamsInstructionIds.Add(accessChain.ResultId, patchStreamKind); } + else + { + StreamsKindSDSL? currentStreamKind = null; + // In case it's a streams access, mark the stream as being the base + if (streamsInstructionIds.TryGetValue(currentBase, out var streamKind)) + { + var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamInfo = streams[streamVariableId]; + + // Set this base for OpStore/OpLoad stream R/W analysis + currentBase = streamVariableId; + currentStreamKind = streamKind; + } - // Any read or write through an access chain will be treated as doing it on the main variable. - // i.e., streams.A.B will share same streamInfo as streams.A - // TODO: what happens in case of partial write? - // Recurse in case we have multiple access chain chained after each other - while (accessChainBases.TryGetValue(currentBase, out var nextBase)) - currentBase = nextBase; - accessChainBases.Add(accessChain.ResultId, currentBase); + // Any read or write through an access chain will be treated as doing it on the main variable. + // i.e., streams.A.B will share same streamInfo as streams.A + // TODO: what happens in case of partial write? + // Recurse in case we have multiple access chain chained after each other + while (accessChainBases.TryGetValue(currentBase, out var nextBase)) + { + currentBase = nextBase.Base; + currentStreamKind ??= nextBase.StreamKind; + } + accessChainBases.Add(accessChain.ResultId, (currentBase, currentStreamKind)); + } } else if (i.Op == Op.OpFunctionCall && new OpFunctionCall(ref i) is { } call) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index d517e49a51..e85c7a6a1b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -57,11 +57,13 @@ public static int ConvertInterfaceVariable( for (int i = 0; i < castSize; ++i) { components[i] = i < sourceSize - ? buffer.Add(new OpCompositeExtract(context.GetOrRegister(sourceBaseType), context.Bound++, value, [i])).ResultId + ? (sourceType is ScalarType ? value : buffer.Add(new OpCompositeExtract(context.GetOrRegister(sourceBaseType), context.Bound++, value, [i])).ResultId) : context.CreateDefaultConstantComposite(sourceBaseType).Id; } - return buffer.Add(new OpCompositeConstruct(context.GetOrRegister(castType), context.Bound++, new(components))).ResultId; + return castType is ScalarType + ? components[0] + : buffer.Add(new OpCompositeConstruct(context.GetOrRegister(castType), context.Bound++, new(components))).ResultId; (int Size, SymbolType baseType) ExtractSizeAndBaseType(SymbolType castType) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index b613a4811e..4dcc4847df 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -5,6 +5,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Processing.Interfaces.Models; +using Stride.Shaders.Spirv.Processing.Interfaces.Transformation; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Spirv.Processing.Interfaces.Generation; @@ -160,16 +161,19 @@ int ConvertInputsArray() var entryPointTypeId = context.GetOrRegister(entryPoint.Type); if (executionModel == ExecutionModel.TessellationControl || executionModel == ExecutionModel.TessellationEvaluation) { + var arraySize = executionModel == ExecutionModel.TessellationControl + ? arrayOutputSize ?? throw new InvalidOperationException("Can't figure array output size for tessellation shader") + : arrayInputSize.Value; bool hullTessellationOutputsGenerated = false; int GenerateHullTessellationOutputs() { if (hullTessellationOutputsGenerated) throw new InvalidOperationException("Hull OutputPatch can only be used in once place (constant patch)"); hullTessellationOutputsGenerated = true; - var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arraySize), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; context.AddName(outputsVariable, "outputs"); - for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + for (int arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) { for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) { @@ -204,42 +208,39 @@ void FillTessellationArguments(Symbol function, Span arguments) (inputPatchType.Kind == PatchTypeKindSDSL.Input && executionModel == ExecutionModel.TessellationControl) || (inputPatchType.Kind == PatchTypeKindSDSL.Output && executionModel == ExecutionModel.TessellationEvaluation): { - // Change signature of main() to use an array instead of InputPatch - // InputPatch becomes HS_INPUT[X] - SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(inputPatchType.BaseType, inputPatchType.Size), Specification.StorageClass.Function)); - context.ReplaceType(function.Type, functionTypeId); arguments[i] = inputsVariable; break; } // Hull outputs case PatchType { Kind: PatchTypeKindSDSL.Output } outputPatchType when executionModel == ExecutionModel.TessellationControl: { - // Change signature of main() to use an array instead of InputPatch - // InputPatch becomes HS_INPUT[X] - SpirvBuilder.FunctionReplaceArgument(context, buffer, function, i, new PointerType(new ArrayType(outputPatchType.BaseType, outputPatchType.Size), Specification.StorageClass.Function)); - context.ReplaceType(function.Type, functionTypeId); arguments[i] = GenerateHullTessellationOutputs(); break; } - case StructType t when (t == constantsType) && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: + case StreamsType t when t.Kind is StreamsKindSDSL.Constants && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: { // Parameter is "HS_CONSTANTS constants" - var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(constantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = constantVariable; // Copy back values from semantic/builtin variables to Constants struct foreach (var stream in patchInputStreams) { var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), stream.Id, constantVariable, null, [])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, stream.Id, null, [])).ResultId; inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); buffer.Add(new OpStore(inputPtr, inputResult, null, [])); } break; } - case StructType t when (t == outputType || t == constantsType) && parameterModifiers == ParameterModifiers.Out: + case StreamsType t when t.Kind is StreamsKindSDSL.Output or StreamsKindSDSL.Constants && parameterModifiers == ParameterModifiers.Out: { // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" - var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(t, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var structType = t.Kind switch + { + StreamsKindSDSL.Output => outputType, + StreamsKindSDSL.Constants => constantsType, + }; + var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = outVariable; break; } @@ -258,12 +259,12 @@ void ProcessTessellationArguments(Symbol function, Span arguments) var parameterModifiers = functionType.ParameterTypes[i].Modifiers; switch (parameterType) { - case StructType t when t == outputType && parameterModifiers == ParameterModifiers.Out: + case StreamsType { Kind: StreamsKindSDSL.Output } when parameterModifiers == ParameterModifiers.Out: { // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(outputType), context.Bound++, outputVariable, null, [])).ResultId; // Do we need to index into array? if yes, get index (gl_invocationID) int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; // Copy back values from Output struct to semantic/builtin variables @@ -281,12 +282,12 @@ void ProcessTessellationArguments(Symbol function, Span arguments) } break; } - case StructType t when t == constantsType && parameterModifiers == ParameterModifiers.Out: + case StreamsType { Kind: StreamsKindSDSL.Constants } when parameterModifiers == ParameterModifiers.Out: { // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(t), context.Bound++, outputVariable, null, [])).ResultId; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(constantsType ?? throw new InvalidOperationException()), context.Bound++, outputVariable, null, [])).ResultId; // Copy back values from Output struct to semantic/builtin variables foreach (var stream in patchOutputStreams) { @@ -348,15 +349,17 @@ void ProcessTessellationArguments(Symbol function, Span arguments) else if (executionModel == ExecutionModel.Geometry) { // Change signature of main() to not use the output Stream anymore - SpirvBuilder.FunctionRemoveArgument(context, buffer, entryPoint, 1); + // TODO: Check it's really the 2nd parameter + SpirvBuilder.FunctionRemoveParameter(context, buffer, entryPoint, 1); // Extract and remove execution mode (line, point, triangleadj, etc.) var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; if (executionMode == ParameterModifiers.None) throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; + entryPointFunctionType.ParameterTypes.RemoveAt(1); - context.ReplaceType(entryPoint.Type, entryPointTypeId); + context.ReplaceType(entryPointFunctionType, entryPointTypeId); context.Add(new OpExecutionMode(entryPoint.IdRef, executionMode switch { ParameterModifiers.Point => ExecutionMode.InputPoints, @@ -368,8 +371,8 @@ void ProcessTessellationArguments(Symbol function, Span arguments) arguments[0] = inputsVariable; - // Call main(inputs) - buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); + // Call main(inputs) without 2nd argument + buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, [arguments[0], .. arguments[2..]])); } } else diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 2417325834..1297f4056d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -116,11 +116,11 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex { ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPoint.Item2.IdRef, analysisResult, liveAnalysis); - // Find patch constant entry point and process it as well + // Find patch constant entry point and process var patchConstantEntryPoint = entryPoint.Item1 == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint.Item2) : null; if (patchConstantEntryPoint != null) ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, patchConstantEntryPoint.IdRef, analysisResult, liveAnalysis); - + // If specific semantic are written to (i.e. SV_Position), they are expected at the end of vertex shader foreach (var stream in streams) { @@ -251,6 +251,14 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) // Find patch constant entry point var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; + // Generate entry point wrapper + var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper(context, + buffer, entryPoint, executionModel, analysisResult, + liveAnalysis, inputStreams, outputStreams, patchInputStreams, + patchOutputStreams, inputType, outputType, streamsType, + constantsType, arrayInputSize, arrayOutputSize, streamsVariable.ResultId, + patchConstantEntryPoint); + // Patch any OpStreams/OpAccessChain to use the new struct foreach (var method in liveAnalysis.ReferencedMethods) { @@ -261,14 +269,6 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) } } - // Generate entry point wrapper - var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper(context, - buffer, entryPoint, executionModel, analysisResult, - liveAnalysis, inputStreams, outputStreams, patchInputStreams, - patchOutputStreams, inputType, outputType, streamsType, - constantsType, arrayInputSize, arrayOutputSize, streamsVariable.ResultId, - patchConstantEntryPoint); - // Move OpExecutionMode on new wrapper foreach (var i in context) { @@ -400,12 +400,7 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel { // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic if (stream.Value.OutputLayoutLocation == null) - { - if (stream.Value.Semantic?.ToUpperInvariant().StartsWith("SV_") ?? false) - stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; - else - throw new InvalidOperationException($"Can't find output layout location for variable [{stream.Value.Name}]"); - } + stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); if (stream.Value.Semantic != null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 73b2b24c20..52f88ec1d1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -29,6 +29,11 @@ public override SymbolType VisitStreamsType(StreamsType streamsType) StreamsKindSDSL.Constants => constantsReplacement ?? throw new InvalidOperationException(), }; } + + public override SymbolType VisitPatchType(PatchType patchType) + { + return new ArrayType(VisitType(patchType.BaseType), patchType.Size); + } } /// @@ -54,12 +59,13 @@ public static void PatchStreamsAccesses( var streams = analysisResult.Streams; // true => implicit (streams.), false => specific variable - var streamsInstructionIds = new Dictionary(); + var streamsInstructionIds = new Dictionary(); var method = (OpFunction)buffer[methodStart]; var methodType = (FunctionType)context.ReverseTypes[method.FunctionType]; var streamTypeReplacer = new StreamsTypeReplace(streamsStructType, inputStructType, outputStructType, constantsStructType); + var oldMethodType = methodType; var newMethodType = (FunctionType)streamTypeReplacer.VisitType(methodType)!; if (!ReferenceEquals(newMethodType, methodType)) { @@ -85,7 +91,7 @@ void CheckStreamTypes(int id) } } - // TODO: remap method type! + int parameterIndex = 0; Span tempIdsForStreamCopy = stackalloc int[streams.Values.Count]; for (int index = methodStart; ; ++index) { @@ -96,36 +102,48 @@ void CheckStreamTypes(int id) if (i.Op == Op.OpStreamsSDSL && (OpStreamsSDSL)i is { } streamsInstruction) { - streamsInstructionIds.Add(streamsInstruction.ResultId, true); + streamsInstructionIds.Add(streamsInstruction.ResultId, (true, StreamsKindSDSL.Streams)); remapIds.Add(streamsInstruction.ResultId, streamsVariableId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); } else if (i.Op is Op.OpVariable && (OpVariable)i is { } variable) { var type = context.ReverseTypes[variable.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(variable.ResultId, false); + if (type is PointerType { BaseType: StreamsType s }) + streamsInstructionIds.Add(variable.ResultId, (false, s.Kind)); } else if (i.Op is Op.OpFunctionParameter && (OpFunctionParameter)i is { } functionParameter) { var type = context.ReverseTypes[functionParameter.ResultType]; - if (type is PointerType { BaseType: StreamsType }) - streamsInstructionIds.Add(functionParameter.ResultId, false); + if (type is PointerType { BaseType: StreamsType s }) + streamsInstructionIds.Add(functionParameter.ResultId, (false, s.Kind)); } else if (i.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { - // In case it's a streams access, patch acces to use STREAMS struct with proper index - if (streamsInstructionIds.TryGetValue(accessChain.BaseId, out var isImplicit)) + // It might return a StreamsType too + var type = context.ReverseTypes[accessChain.ResultType]; + if (type is PointerType { BaseType: StreamsType s }) + streamsInstructionIds.Add(accessChain.ResultId, (false, s.Kind)); + + // In case it's a streams.Variable access, patch acces to use STREAMS struct with proper index to this variable + // Note: we made sure in AccessChainExpression to decompose access such as inputs[2].variable into two OpAccessChain + // so that we match this easier to detect format + if (accessChain.Values.Elements.Length == 1 && streamsInstructionIds.TryGetValue(accessChain.BaseId, out var streamAccessInfo)) { var streamVariableId = accessChain.Values.Elements.Span[0]; var streamInfo = streams[streamVariableId]; - var streamStructMemberIndex = streamInfo.StreamStructFieldIndex; + var streamStructMemberIndex = streamAccessInfo.Kind switch + { + StreamsKindSDSL.Streams or StreamsKindSDSL.Constants => streamInfo.StreamStructFieldIndex, + StreamsKindSDSL.Input => streamInfo.InputStructFieldIndex.Value, + StreamsKindSDSL.Output => streamInfo.OutputStructFieldIndex.Value, + }; // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that // we'll need a better way to update LiteralArray and propagate changes accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; - if (isImplicit) + if (streamAccessInfo.IsImplicit) accessChain.BaseId = streamsVariableId; else // Force refresh of InstructionMemory diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index e5110e38ce..dda0967eb8 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -1,7 +1,14 @@ using System; using System.Collections.Generic; using System.Text; +using CommunityToolkit.HighPerformance; +using Silk.NET.SPIRV; +using Silk.NET.SPIRV.Cross; +using Stride.Shaders.Compilers; using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Tools; +using Spv = Stride.Shaders.Spirv.Tools.Spv; namespace Stride.Shaders.Parsers.Tests; @@ -21,7 +28,8 @@ public void Tessellation() new ShaderClassSource("NormalStream"), new ShaderClassSource("TransformationWAndVP"), new ShaderClassSource("NormalFromMesh"), -new ShaderClassSource("TessellationFlat"), +new ShaderClassSource("TessellationPN"), +new ShaderClassSource("TessellationAE4","PositionWS"), new ShaderClassSource("MaterialSurfacePixelStageCompositor"), }, Compositions = @@ -33,6 +41,7 @@ public void Tessellation() Mixins ={new ShaderClassSource("LightSimpleAmbient")}, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -63,6 +72,7 @@ public void Tessellation() Compositions ={["diffuseMap"] = new ShaderClassSource("ComputeColorConstantColorLink","Material.DiffuseValue")}, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -91,6 +101,7 @@ public void Tessellation() }, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -111,6 +122,7 @@ public void Tessellation() }, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -136,6 +148,7 @@ public void Tessellation() }, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -155,6 +168,7 @@ public void Tessellation() }, Macros = { +new ShaderMacro("InputControlPointCount", "12"), new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), @@ -174,5 +188,13 @@ public void Tessellation() var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + + File.WriteAllBytes($"StrideTessellation.spv", bytecode); + File.WriteAllText($"StrideTessellation.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); + var entryPoints = translator.GetEntryPoints(); + var codeHS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationControl)); + var codeDS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationEvaluation)); } } From c8d47b7a65696ba2a3a955edcd3ca88298ffb3fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Feb 2026 02:38:15 +0900 Subject: [PATCH 0846/1182] SDSL: fix decorations (missing patch decoration and allocate multiple locations for matrix/array) --- .../Interfaces/InterfaceProcessor.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 1297f4056d..9a99a48b87 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -364,6 +364,16 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel var stage = ExecutionModelToStageId(executionModel); foreach (var stream in streams) { + int RequiredLocations(SymbolType type) + { + return type switch + { + ScalarType or VectorType => 1, + MatrixType m => m.Columns, + ArrayType a => a.Size, + }; + } + if (stream.Value.Input) { var variableId = context.Bound++; @@ -371,7 +381,10 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel if (!ProcessBuiltinsDecoration(variableId, StreamVariableType.Input, stream.Value.Semantic, ref variableType)) { if (stream.Value.InputLayoutLocation == null) - stream.Value.InputLayoutLocation = inputLayoutLocationCount++; + { + stream.Value.InputLayoutLocation = inputLayoutLocationCount; + inputLayoutLocationCount += RequiredLocations(variableType); + } context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.InputLayoutLocation.Value])); if (stream.Value.Semantic != null) context.Add(new OpDecorateString(variableId, Decoration.UserSemantic, stream.Value.Semantic)); @@ -388,6 +401,9 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); + if (stream.Value.Patch) + context.Add(new OpDecorate(variable, Decoration.Patch, [])); + stream.Value.InputId = variable.ResultId; (stream.Value.Patch ? patchInputStreams : inputStreams).Add((stream.Value, variable.ResultId, variableType)); } @@ -400,7 +416,10 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel { // TODO: this shouldn't be necessary if we allocated layout during first forward pass for any SV_ semantic if (stream.Value.OutputLayoutLocation == null) - stream.Value.OutputLayoutLocation = outputLayoutLocationCount++; + { + stream.Value.OutputLayoutLocation = outputLayoutLocationCount; + outputLayoutLocationCount += RequiredLocations(variableType); + } context.Add(new OpDecorate(variableId, Decoration.Location, [stream.Value.OutputLayoutLocation.Value])); if (stream.Value.Semantic != null) @@ -418,6 +437,9 @@ private static void GenerateStreamVariables(SpirvContext context, ExecutionModel if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); + if (stream.Value.Patch) + context.Add(new OpDecorate(variable, Decoration.Patch, [])); + stream.Value.OutputId = variable.ResultId; (stream.Value.Patch ? patchOutputStreams : outputStreams).Add((stream.Value, variable.ResultId, variableType)); } From e05c64be698cfa0ccbbe801b652a9c04f0116a45 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Feb 2026 16:23:40 +0900 Subject: [PATCH 0847/1182] SDSL: rearrange cache --- sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 2 +- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 7 +------ .../shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs | 9 ++++----- .../Spirv/Building/Builder.Class.cs | 7 +++---- .../Stride.Shaders.Parsers/Spirv/Building/Context.cs | 3 +-- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 386c403b63..277cc0356c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -45,7 +45,7 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan /// Expects hash to be stored. - public IShaderCache FileCache => inner.FileCache; - /// - /// Cache per generic instantiation. - /// - /// Hashes are not needed. - public IShaderCache GenericCache => inner.GenericCache; + public IShaderCache Cache => inner.Cache; public HashSourceCollection Sources { get; } = new(); diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 238059ec40..1627c4cf96 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -12,12 +12,11 @@ namespace Stride.Shaders.Compilers; public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShaderLoader { - public IShaderCache FileCache => fileCache; - public IShaderCache GenericCache { get; } = new ShaderCache(); + public IShaderCache Cache => fileCache; public bool Exists(string name) { - if (fileCache.Exists(name)) + if (Cache.Exists(name)) return true; return ExternalFileExists(name); @@ -28,7 +27,7 @@ public bool Exists(string name) public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = fileCache.TryLoadFromCache(name, defines, out buffer, out hash); + isFromCache = Cache.TryLoadFromCache(name, defines, out buffer, out hash); if (isFromCache) return true; @@ -52,7 +51,7 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = fileCache.TryLoadFromCache(name, defines, out buffer, out hash); + isFromCache = Cache.TryLoadFromCache(name, defines, out buffer, out hash); if (isFromCache) return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index a187649dd6..90ae53e838 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -706,13 +706,12 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, // Split context and buffer - // TODO: generics cache? if (genericResolver.GenericArgumentCount > 0) { // First, try to build name for cache lookup var classNameWithGenerics = BuildGenericClassName(className, genericResolver); - var cache = genericResolver.Cache ?? shaderLoader.GenericCache; - if (shaderLoader.GenericCache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers, out var cachedHash)) + var cache = genericResolver.Cache ?? shaderLoader.Cache; + if (cache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers, out var cachedHash)) { shaderBuffers = cachedShaderBuffers; hash = cachedHash; @@ -732,7 +731,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); - shaderLoader.GenericCache.RegisterShader(classNameWithGenerics, macros, shaderBuffers, hash); + cache.RegisterShader(classNameWithGenerics, macros, shaderBuffers, hash); } // Run in all cases (even if cached) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 318e992158..35501b5efc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -74,8 +74,7 @@ public bool TryLoadFromCache(string name, ReadOnlySpan defines, [Ma public interface IExternalShaderLoader { - public IShaderCache FileCache { get; } - public IShaderCache GenericCache { get; } + public IShaderCache Cache { get; } public bool Exists(string name); public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); From 468d665b39b7b12da942be489278c087bb1f897e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Feb 2026 14:29:30 +0900 Subject: [PATCH 0848/1182] SDSL: Tests: make sure sdfx are properly included in the shader file generator --- .../shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index ae48ccb3f4..efd3088852 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -35,7 +35,7 @@ - + From e37c8225f42f049cdb8b56c1e33deb04fd242a4a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 00:53:49 +0900 Subject: [PATCH 0849/1182] SDSL: fix Vulkan precompiled shaders --- .../Shaders.Bytecodes/CompileShaders.cmd | 2 +- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 530 +++++++++++------ ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 541 ++++++++++++------ .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 321 ++++++----- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 392 +++++++++---- .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 403 ++++++++----- 6 files changed, 1456 insertions(+), 733 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index dda37a3dec..693774cb9e 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -5,4 +5,4 @@ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.Compiler rmdir /s %~dp0obj\ %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index bad07c9fdf..28f9fb268d 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -1,186 +1,378 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { public partial class SpriteBatch { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, -68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, -0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, -17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, -120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, -1, 177, 26, 161, 230, 203, 43, 149, 201, 25, 229, 198, 102, 88, 176, 114, 25, 0, 72, 16, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 2, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 3, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 4, 0, 0, 0, 0, 6, 67, 79, 76, 79, 82, 49, 0, 2, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, -0, 0, 216, 15, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 126, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, -0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 46, 0, 0, 0, 51, 0, 0, 0, 54, 0, 0, 0, 100, 0, 0, 0, 105, 0, 0, 0, 109, 0, 0, 0, 113, 0, 0, 0, 116, 0, -0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 80, 111, -115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, -0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 6, 0, 8, 0, 9, 0, -0, 0, 5, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 5, 0, 16, 0, 13, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 117, 99, 116, 45, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, -102, 52, 45, 118, 102, 52, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 22, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 6, 0, 9, 0, 22, 0, -0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 5, 0, 3, 0, 24, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 30, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, -7, 0, 30, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 6, 0, 30, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 30, 0, 0, 0, 2, 0, 0, 0, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 30, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 30, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, -100, 55, 54, 0, 0, 0, 5, 0, 5, 0, 32, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 35, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 49, 0, 0, 0, 0, 5, 0, 5, 0, 40, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, -48, 0, 5, 0, 7, 0, 46, 0, 0, 0, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 51, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 54, 0, 0, 0, 97, 95, 80, 79, 83, 73, -84, 73, 79, 78, 48, 0, 5, 0, 4, 0, 57, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 73, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 77, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 77, 0, -0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 77, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 77, 0, 0, 0, 2, 0, 0, 0, 83, 119, -105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 77, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 77, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, -100, 55, 54, 0, 0, 0, 5, 0, 5, 0, 79, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 98, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 98, 0, 0, 0, 0, 0, 0, 0, 103, 108, -95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 7, 0, 98, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 98, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, -101, 0, 6, 0, 7, 0, 98, 0, 0, 0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 100, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 105, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, -7, 0, 109, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 113, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 116, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 49, 0, 0, -0, 0, 5, 0, 5, 0, 125, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 72, 0, 4, 0, 22, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 72, 0, 5, 0, 22, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 22, 0, -0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 3, 0, 22, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 35, 0, -0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 46, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 51, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 54, 0, -0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 98, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 98, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 98, 0, 0, 0, 2, 0, 0, 0, 11, 0, -0, 0, 3, 0, 0, 0, 72, 0, 5, 0, 98, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 98, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 105, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 109, 0, 0, 0, 30, 0, -0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 113, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 125, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 125, 0, 0, 0, 33, 0, -0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, -0, 0, 2, 0, 0, 0, 30, 0, 8, 0, 9, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 2, 0, -0, 0, 10, 0, 0, 0, 21, 0, 4, 0, 15, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 15, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 43, 0, 4, 0, 15, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 7, 0, -0, 0, 7, 0, 0, 0, 24, 0, 4, 0, 21, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 22, 0, 0, 0, 21, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 2, 0, 0, 0, 22, 0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 24, 0, 0, 0, 2, 0, -0, 0, 32, 0, 4, 0, 25, 0, 0, 0, 2, 0, 0, 0, 21, 0, 0, 0, 30, 0, 7, 0, 30, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 31, 0, 0, 0, 7, 0, 0, 0, 30, 0, 0, 0, 43, 0, -4, 0, 15, 0, 0, 0, 33, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 34, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 34, 0, 0, 0, 35, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 15, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, -4, 0, 39, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 40, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 15, 0, 0, 0, 44, 0, 0, 0, 2, 0, 0, 0, 32, 0, -4, 0, 45, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 0, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 48, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 43, 0, 4, 0, 15, 0, 0, 0, 50, 0, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 34, 0, 0, 0, 51, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 0, 0, 0, 54, 0, 0, 0, 1, 0, 0, 0, 30, 0, 7, 0, 77, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 78, 0, -0, 0, 7, 0, 0, 0, 77, 0, 0, 0, 21, 0, 4, 0, 95, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 95, 0, 0, 0, 96, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, 0, 97, 0, 0, 0, 6, 0, 0, 0, 96, 0, 0, 0, 30, 0, 6, 0, 98, 0, -0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 97, 0, 0, 0, 97, 0, 0, 0, 32, 0, 4, 0, 99, 0, 0, 0, 3, 0, 0, 0, 98, 0, 0, 0, 59, 0, 4, 0, 99, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 103, 0, 0, 0, 3, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 103, 0, 0, 0, 105, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 108, 0, 0, 0, 109, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 112, 0, 0, 0, 3, 0, 0, 0, 8, 0, -0, 0, 59, 0, 4, 0, 112, 0, 0, 0, 113, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 103, 0, 0, 0, 116, 0, 0, 0, 3, 0, 0, 0, 26, 0, 2, 0, 123, 0, 0, 0, 32, 0, 4, 0, 124, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 59, 0, 4, 0, 124, 0, -0, 0, 125, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 31, 0, 0, 0, 32, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 57, 0, -0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 73, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 78, 0, 0, 0, 79, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 37, 0, -0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 36, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 41, 0, 0, 0, 40, 0, 0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 43, 0, 0, 0, 32, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 43, 0, -0, 0, 41, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 47, 0, 0, 0, 46, 0, 0, 0, 65, 0, 5, 0, 48, 0, 0, 0, 49, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 62, 0, 3, 0, 49, 0, 0, 0, 47, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 52, 0, -0, 0, 51, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 53, 0, 0, 0, 32, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 53, 0, 0, 0, 52, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 56, 0, -0, 0, 32, 0, 0, 0, 17, 0, 0, 0, 62, 0, 3, 0, 56, 0, 0, 0, 55, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 58, 0, 0, 0, 32, 0, 0, 0, 17, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 59, 0, 0, 0, 58, 0, 0, 0, 65, 0, 5, 0, 18, 0, -0, 0, 60, 0, 0, 0, 57, 0, 0, 0, 17, 0, 0, 0, 62, 0, 3, 0, 60, 0, 0, 0, 59, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 0, 0, 0, 32, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 62, 0, 0, 0, 61, 0, 0, 0, 65, 0, -5, 0, 18, 0, 0, 0, 63, 0, 0, 0, 57, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 63, 0, 0, 0, 62, 0, 0, 0, 65, 0, 5, 0, 48, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 65, 0, 0, 0, 64, 0, -0, 0, 65, 0, 5, 0, 48, 0, 0, 0, 66, 0, 0, 0, 57, 0, 0, 0, 44, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 65, 0, 0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 67, 0, 0, 0, 32, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 68, 0, -0, 0, 67, 0, 0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 69, 0, 0, 0, 57, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 69, 0, 0, 0, 68, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 70, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 61, 0, 4, 0, 7, 0, -0, 0, 71, 0, 0, 0, 70, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 72, 0, 0, 0, 57, 0, 0, 0, 33, 0, 0, 0, 62, 0, 3, 0, 72, 0, 0, 0, 71, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 74, 0, 0, 0, 57, 0, 0, 0, 62, 0, 3, 0, 73, 0, -0, 0, 74, 0, 0, 0, 57, 0, 5, 0, 2, 0, 0, 0, 75, 0, 0, 0, 13, 0, 0, 0, 73, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 76, 0, 0, 0, 73, 0, 0, 0, 62, 0, 3, 0, 57, 0, 0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 80, 0, -0, 0, 57, 0, 0, 0, 16, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 82, 0, 0, 0, 79, 0, 0, 0, 17, 0, 0, 0, 62, 0, 3, 0, 82, 0, 0, 0, 81, 0, 0, 0, 65, 0, 5, 0, 18, 0, -0, 0, 83, 0, 0, 0, 57, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 84, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 85, 0, 0, 0, 79, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 84, 0, 0, 0, 65, 0, -5, 0, 48, 0, 0, 0, 86, 0, 0, 0, 57, 0, 0, 0, 44, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 87, 0, 0, 0, 86, 0, 0, 0, 65, 0, 5, 0, 48, 0, 0, 0, 88, 0, 0, 0, 79, 0, 0, 0, 44, 0, 0, 0, 62, 0, 3, 0, 88, 0, 0, 0, 87, 0, -0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 89, 0, 0, 0, 57, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 90, 0, 0, 0, 89, 0, 0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 91, 0, 0, 0, 79, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 91, 0, -0, 0, 90, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 92, 0, 0, 0, 57, 0, 0, 0, 33, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 93, 0, 0, 0, 92, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 94, 0, 0, 0, 79, 0, 0, 0, 33, 0, 0, 0, 62, 0, -3, 0, 94, 0, 0, 0, 93, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 101, 0, 0, 0, 79, 0, 0, 0, 17, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 102, 0, 0, 0, 101, 0, 0, 0, 65, 0, 5, 0, 103, 0, 0, 0, 104, 0, 0, 0, 100, 0, 0, 0, 17, 0, -0, 0, 62, 0, 3, 0, 104, 0, 0, 0, 102, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 106, 0, 0, 0, 79, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 107, 0, 0, 0, 106, 0, 0, 0, 62, 0, 3, 0, 105, 0, 0, 0, 107, 0, 0, 0, 65, 0, -5, 0, 48, 0, 0, 0, 110, 0, 0, 0, 79, 0, 0, 0, 44, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 111, 0, 0, 0, 110, 0, 0, 0, 62, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 65, 0, 5, 0, 42, 0, 0, 0, 114, 0, 0, 0, 79, 0, 0, 0, 38, 0, -0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 115, 0, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 113, 0, 0, 0, 115, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 117, 0, 0, 0, 79, 0, 0, 0, 33, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 118, 0, 0, 0, 117, 0, -0, 0, 62, 0, 3, 0, 116, 0, 0, 0, 118, 0, 0, 0, 65, 0, 6, 0, 108, 0, 0, 0, 119, 0, 0, 0, 100, 0, 0, 0, 17, 0, 0, 0, 96, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 120, 0, 0, 0, 119, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 121, 0, -0, 0, 120, 0, 0, 0, 65, 0, 6, 0, 108, 0, 0, 0, 122, 0, 0, 0, 100, 0, 0, 0, 17, 0, 0, 0, 96, 0, 0, 0, 62, 0, 3, 0, 122, 0, 0, 0, 121, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 2, 0, 0, 0, 13, 0, 0, 0, 0, 0, -0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 19, 0, 0, 0, 12, 0, 0, 0, 17, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 65, 0, -5, 0, 25, 0, 0, 0, 26, 0, 0, 0, 24, 0, 0, 0, 17, 0, 0, 0, 61, 0, 4, 0, 21, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 144, 0, 5, 0, 7, 0, 0, 0, 28, 0, 0, 0, 20, 0, 0, 0, 27, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 29, 0, -0, 0, 12, 0, 0, 0, 16, 0, 0, 0, 62, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 164, 177, 32, 18, 95, 250, 206, 184, 106, 101, 212, 154, 236, 240, 198, 17, 0, 238, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, -0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 3, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 164, -18, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 180, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, -0, 0, 0, 15, 0, 11, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 134, 0, 0, 0, 138, 0, 0, 0, 142, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 176, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, -0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, -100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 9, -0, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 15, 0, 13, 0, 0, 0, 83, 104, 97, 100, 105, -110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, -0, 15, 0, 16, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 52, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 15, -0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 6, 0, 20, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 24, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, 6, 0, 37, -0, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 51, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 57, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 3, 0, 70, 0, 0, 0, 110, 88, 0, 0, 5, -0, 3, 0, 77, 0, 0, 0, 110, 89, 0, 0, 5, 0, 3, 0, 85, 0, 0, 0, 110, 90, 0, 0, 5, 0, 5, 0, 116, 0, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, -0, 8, 0, 129, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 129, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 2, -0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, -65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 5, 0, 5, 0, 131, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 49, 0, 0, 0, 0, 5, 0, 5, 0, 138, 0, 0, 0, 118, 95, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 5, 0, 7, 0, 142, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 6, 0, 148, 0, 0, 0, 103, -108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 164, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 169, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, -0, 0, 0, 6, 0, 7, 0, 169, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 171, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 176, 0, 0, 0, 111, 117, 116, 95, 103, -108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 179, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 20, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, -0, 4, 0, 20, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 33, 0, 0, 0, 21, 0, 0, 0, 71, 0, 4, 0, 134, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, -0, 4, 0, 138, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 142, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 145, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 148, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, -0, 4, 0, 176, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 179, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, -0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 9, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, -0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 25, 0, 9, 0, 18, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 19, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 59, 0, 4, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 22, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 0, -0, 0, 0, 22, 0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 26, 0, 0, 0, 18, 0, 0, 0, 21, 0, 4, 0, 28, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 29, 0, 0, 0, 1, -0, 0, 0, 32, 0, 4, 0, 30, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 39, 0, 0, 0, 7, 0, 0, 0, 6, -0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 42, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 6, 0, 0, 0, 45, 0, 0, 0, 205, 204, 204, 61, 20, 0, 2, 0, 46, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 64, 21, 0, 4, 0, 71, -0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 71, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 71, 0, 0, 0, 78, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 71, 0, 0, 0, 83, 0, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 6, -0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 71, 0, 0, 0, 101, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 105, 0, 0, 0, 0, 0, 64, 64, 43, 0, 4, 0, 28, -0, 0, 0, 118, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 122, 0, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 129, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 130, 0, 0, 0, 7, -0, 0, 0, 129, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 132, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 133, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 1, -0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 138, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 141, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 141, 0, 0, 0, 142, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 145, -0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 148, 0, 0, 0, 1, 0, 0, 0, 30, 0, 3, 0, 169, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 170, 0, 0, 0, 7, 0, 0, 0, 169, 0, 0, 0, 32, 0, 4, 0, 175, 0, 0, 0, 3, 0, 0, 0, 8, -0, 0, 0, 59, 0, 4, 0, 175, 0, 0, 0, 176, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, -0, 4, 0, 130, 0, 0, 0, 131, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 170, 0, 0, 0, 171, 0, 0, 0, 7, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 132, 0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 139, 0, 0, 0, 138, 0, 0, 0, 65, -0, 5, 0, 30, 0, 0, 0, 140, 0, 0, 0, 131, 0, 0, 0, 122, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 144, 0, 0, 0, 131, 0, 0, 0, 118, -0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 146, 0, 0, 0, 145, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 147, 0, 0, 0, 131, 0, 0, 0, 29, 0, 0, 0, 62, 0, 3, 0, 147, 0, 0, 0, 146, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 149, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 150, 0, 0, 0, 131, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 152, 0, 0, 0, 131, 0, 0, 0, 29, -0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 118, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 155, 0, 0, 0, 131, -0, 0, 0, 118, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 157, 0, 0, 0, 151, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 158, -0, 0, 0, 131, 0, 0, 0, 122, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 160, 0, 0, 0, 151, 0, 0, 0, 29, 0, 0, 0, 62, 0, 3, 0, 160, 0, 0, 0, 159, 0, 0, 0, 65, 0, 5, 0, 36, -0, 0, 0, 161, 0, 0, 0, 131, 0, 0, 0, 132, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 163, 0, 0, 0, 151, 0, 0, 0, 122, 0, 0, 0, 62, 0, 3, 0, 163, 0, 0, 0, 162, 0, 0, 0, 61, -0, 4, 0, 9, 0, 0, 0, 165, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 165, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 166, 0, 0, 0, 16, 0, 0, 0, 164, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 62, -0, 3, 0, 151, 0, 0, 0, 167, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 168, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 166, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 172, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 174, 0, 0, 0, 171, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 173, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 177, 0, 0, 0, 171, 0, 0, 0, 38, -0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 176, 0, 0, 0, 178, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, -0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 61, 0, 4, 0, 18, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 61, 0, 4, 0, 22, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 86, 0, 5, 0, 26, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 25, -0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 31, 0, 0, 0, 12, 0, 0, 0, 29, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 87, 0, 5, 0, 8, 0, 0, 0, 33, 0, 0, 0, 27, 0, 0, 0, 32, 0, 0, 0, 254, 0, 2, 0, 33, -0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 15, 0, 0, 0, 248, 0, 2, 0, 17, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 37, 0, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 36, 0, 0, 0, 48, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 57, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 70, 0, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 39, 0, 0, 0, 77, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 85, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 116, 0, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 40, 0, 0, 0, 15, 0, 0, 0, 38, -0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 41, 0, 0, 0, 40, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 42, 0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 44, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 188, -0, 5, 0, 46, 0, 0, 0, 47, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 247, 0, 3, 0, 50, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 47, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 248, 0, 2, 0, 49, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 52, -0, 0, 0, 15, 0, 0, 0, 62, 0, 3, 0, 51, 0, 0, 0, 52, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 53, 0, 0, 0, 13, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 54, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 54, -0, 0, 0, 79, 0, 9, 0, 8, 0, 0, 0, 55, 0, 0, 0, 53, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 48, 0, 0, 0, 55, 0, 0, 0, 249, 0, 2, 0, 50, 0, 0, 0, 248, 0, 2, 0, 56, -0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 58, 0, 0, 0, 15, 0, 0, 0, 62, 0, 3, 0, 57, 0, 0, 0, 58, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 59, 0, 0, 0, 13, 0, 0, 0, 57, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 60, 0, 0, 0, 57, -0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 60, 0, 0, 0, 62, 0, 3, 0, 48, 0, 0, 0, 59, 0, 0, 0, 249, 0, 2, 0, 50, 0, 0, 0, 248, 0, 2, 0, 50, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 61, 0, 0, 0, 48, 0, 0, 0, 62, 0, 3, 0, 37, -0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 62, 0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 65, 0, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 12, -0, 6, 0, 6, 0, 0, 0, 66, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 65, 0, 0, 0, 188, 0, 5, 0, 46, 0, 0, 0, 67, 0, 0, 0, 66, 0, 0, 0, 45, 0, 0, 0, 247, 0, 3, 0, 69, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 67, 0, 0, 0, 68, -0, 0, 0, 69, 0, 0, 0, 248, 0, 2, 0, 68, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 73, 0, 0, 0, 37, 0, 0, 0, 72, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 74, 0, 0, 0, 73, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 75, 0, 0, 0, 74, -0, 0, 0, 64, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 76, 0, 0, 0, 75, 0, 0, 0, 42, 0, 0, 0, 62, 0, 3, 0, 70, 0, 0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 79, 0, 0, 0, 37, 0, 0, 0, 78, 0, 0, 0, 61, 0, 4, 0, 6, -0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 64, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 42, 0, 0, 0, 62, 0, 3, 0, 77, 0, 0, 0, 82, 0, 0, 0, 65, -0, 5, 0, 39, 0, 0, 0, 84, 0, 0, 0, 37, 0, 0, 0, 83, 0, 0, 0, 62, 0, 3, 0, 84, 0, 0, 0, 42, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 86, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 87, 0, 0, 0, 70, 0, 0, 0, 133, -0, 5, 0, 6, 0, 0, 0, 88, 0, 0, 0, 86, 0, 0, 0, 87, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 89, 0, 0, 0, 77, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 90, 0, 0, 0, 77, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 91, 0, 0, 0, 89, -0, 0, 0, 90, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 92, 0, 0, 0, 88, 0, 0, 0, 91, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, 42, 0, 0, 0, 12, 0, 6, 0, 6, -0, 0, 0, 95, 0, 0, 0, 1, 0, 0, 0, 31, 0, 0, 0, 94, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 96, 0, 0, 0, 42, 0, 0, 0, 95, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 96, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 97, 0, 0, 0, 85, -0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 99, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 100, 0, 0, 0, 99, 0, 0, 0, 98, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 102, 0, 0, 0, 37, 0, 0, 0, 101, 0, 0, 0, 62, -0, 3, 0, 102, 0, 0, 0, 100, 0, 0, 0, 249, 0, 2, 0, 69, 0, 0, 0, 248, 0, 2, 0, 69, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 103, 0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 104, 0, 0, 0, 103, 0, 0, 0, 131, -0, 5, 0, 6, 0, 0, 0, 106, 0, 0, 0, 104, 0, 0, 0, 105, 0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 107, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 106, 0, 0, 0, 188, 0, 5, 0, 46, 0, 0, 0, 108, 0, 0, 0, 107, 0, 0, 0, 45, 0, 0, 0, 247, -0, 3, 0, 110, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 108, 0, 0, 0, 109, 0, 0, 0, 110, 0, 0, 0, 248, 0, 2, 0, 109, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 111, 0, 0, 0, 37, 0, 0, 0, 79, 0, 7, 0, 7, 0, 0, 0, 112, 0, 0, 0, 111, -0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 113, 0, 0, 0, 37, 0, 0, 0, 79, 0, 9, 0, 8, 0, 0, 0, 114, 0, 0, 0, 113, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, -0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 114, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 115, 0, 0, 0, 37, 0, 0, 0, 83, 0, 0, 0, 62, 0, 3, 0, 115, 0, 0, 0, 42, 0, 0, 0, 249, 0, 2, 0, 110, 0, 0, 0, 248, 0, 2, 0, 110, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 119, 0, 0, 0, 15, 0, 0, 0, 118, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 120, 0, 0, 0, 119, 0, 0, 0, 133, 0, 5, 0, 8, 0, 0, 0, 121, 0, 0, 0, 117, -0, 0, 0, 120, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 123, 0, 0, 0, 15, 0, 0, 0, 122, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 124, 0, 0, 0, 123, 0, 0, 0, 129, 0, 5, 0, 8, 0, 0, 0, 125, 0, 0, 0, 121, 0, 0, 0, 124, 0, 0, 0, 62, -0, 3, 0, 116, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 126, 0, 0, 0, 116, 0, 0, 0, 254, 0, 2, 0, 126, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, +0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, +2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 150, 121, 37, 154, 211, 55, 191, 41, 11, 9, 239, 133, 109, 6, 77, 122, 0, 240, 40, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, +1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, +2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, +2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, +0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, +116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, +0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, +46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, +110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, +0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, +108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, +0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, +0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, +0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, +0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, +0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, +117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, +0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, +50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, +0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, +0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, +48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, +97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, +0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, +0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, +1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, +1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, +110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, +0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, +2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, +116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, +95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, +0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, +97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, +111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, +119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, +82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, +0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, +116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, +97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, +2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, +0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, +83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, +0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, +0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, +65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, +0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, +0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, +0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, +108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, +112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, +121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, +114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, +108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, +79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, +2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, +2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, +0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, +0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, +22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, +22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, +0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, +0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, +0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, +0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, +0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, +0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, +0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, +0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, +0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, +0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, +0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, +0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, +0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, +0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, +0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, +0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, +0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, +0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, +0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, +1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, +1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, +2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, +0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, +0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, +2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, +0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, +0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, +0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, +0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, +0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, +0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, +0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, +0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, +0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, +0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, +0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, +0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, +0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, +2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, +0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, +0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, +0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, +0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, +0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, +0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, +0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, +0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, +0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, +1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, +0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, +0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, +0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, +0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, +1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, +1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, +0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, +0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, +0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, +1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, +0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, +1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, +1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, +1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, +0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, +0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, +0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, +0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, +2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, +0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, +0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, +0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, +1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, +0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, +2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, +0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, +2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, +2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, +2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, +0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, +0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, +2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, +2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, +0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, +2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, +2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, +2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, +0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, +2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 150, 121, 37, 154, 211, 55, 191, 41, 11, 9, 239, 133, 109, 6, 77, 122, 0, 240, 40, 0, 0, 3, 2, +35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, +116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, +0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, +0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, 0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, +111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, +120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, +111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, +105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, +0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, +8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, +116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, +7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, +111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, +0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, +0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, +0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, +111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, +0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, +103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, +0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, +121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, +0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, +0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, +95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, +0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, +95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, +67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, +0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, +0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, +6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, +0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, +114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 46, 2, +0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, +0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, +0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, +0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, +95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, +0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, +101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, +0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, +0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, +97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, +7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, +0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, +0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, +0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, +5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, +0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, +0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, +0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, +0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, +0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, +4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, +0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, +0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, +0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, +0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, +0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, +0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, +0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, +0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, +0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, +0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, +3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, +0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, +0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, +0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, +4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, +0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, +4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, +4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, +4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, +4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, +4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, +0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, +0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, +0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, +4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, +4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, +0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, +0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, +0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, +4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, +0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, +0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, +0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, +0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, +0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, +4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, +0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, +0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, +0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, +0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, +0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, +0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, +0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, +3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, +0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, +0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, +0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, +0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, +0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, +0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, +0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, +5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, +5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, +0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, +0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, +0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, +2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, +0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, +0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, +0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, +0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, +0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, +0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, +0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, +0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, +0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, +0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, +0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, +0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, +0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, +0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, +0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, +114, 0, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index 28f61f89e4..0534383338 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -1,198 +1,377 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { public partial class SpriteBatch { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, -68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, -0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 0, 6, 0, 0, 0, -17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 68, 125, 196, 122, 44, 200, 178, 214, 102, 182, 134, 84, 184, 236, 159, 103, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, -120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, -1, 167, 122, 232, 175, 57, 0, 147, 19, 218, 30, 62, 99, 94, 48, 223, 30, 0, 56, 19, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 2, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 3, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 4, 0, 0, 0, 0, 6, 67, 79, 76, 79, 82, 49, 0, 2, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, -0, 0, 200, 18, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 162, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, -0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 68, 0, 0, 0, 73, 0, 0, 0, 79, 0, 0, 0, 83, 0, 0, 0, 86, 0, 0, 0, 136, 0, 0, 0, 141, 0, 0, 0, 145, 0, 0, 0, 149, 0, 0, 0, 152, 0, -0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 7, 0, 11, 0, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 53, 40, 118, 102, 52, 59, 0, 0, 0, 5, 0, 4, 0, 10, 0, -0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 5, 0, 14, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 14, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 6, 0, 14, 0, -0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 14, 0, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 14, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, -114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 14, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 6, 0, 8, 0, 14, 0, 0, 0, 5, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 48, 0, 5, 0, 16, 0, 18, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 105, 100, 50, 40, 115, 116, 114, 117, 99, 116, 45, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, 102, 52, 45, 118, 102, 52, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, -52, 49, 59, 0, 0, 0, 5, 0, 4, 0, 17, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 22, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 55, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 6, 0, 9, 0, 55, 0, 0, 0, 0, 0, -0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 5, 0, 3, 0, 57, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 63, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 7, 0, 63, 0, -0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 6, 0, 63, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 63, 0, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 63, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 63, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, -0, 0, 5, 0, 5, 0, 65, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 68, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 49, 0, 0, 0, 0, 5, 0, 5, 0, 73, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, -7, 0, 79, 0, 0, 0, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 83, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 86, 0, 0, 0, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, -48, 0, 5, 0, 4, 0, 89, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 105, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 109, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 86, 83, 95, 79, 85, 84, -80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 114, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 114, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, -7, 0, 114, 0, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 114, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 114, 0, 0, 0, 4, 0, -0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 5, 0, 5, 0, 116, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 134, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, -6, 0, 134, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 7, 0, 134, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 134, 0, 0, 0, 2, 0, 0, 0, 103, 108, -95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, 101, 0, 6, 0, 7, 0, 134, 0, 0, 0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 136, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 118, 95, -67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 7, 0, 145, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 149, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 152, 0, -0, 0, 118, 95, 67, 79, 76, 79, 82, 49, 0, 0, 0, 0, 5, 0, 5, 0, 161, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 72, 0, 4, 0, 55, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 72, 0, 5, 0, 55, 0, 0, 0, 0, 0, 0, 0, 35, 0, -0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 55, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 3, 0, 55, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 57, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 0, 0, 0, 33, 0, -0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 68, 0, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 71, 0, 4, 0, 73, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 79, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 30, 0, -0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 86, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 134, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 134, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, -5, 0, 134, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 72, 0, 5, 0, 134, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 134, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 141, 0, 0, 0, 30, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 145, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 149, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 152, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 161, 0, 0, 0, 34, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 161, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, -0, 0, 32, 0, 4, 0, 8, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 33, 0, 4, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 23, 0, 4, 0, 13, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 8, 0, 14, 0, 0, 0, 7, 0, 0, 0, 7, 0, -0, 0, 6, 0, 0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 15, 0, 0, 0, 7, 0, 0, 0, 14, 0, 0, 0, 33, 0, 4, 0, 16, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 23, 0, 4, 0, 20, 0, 0, 0, 6, 0, 0, 0, 3, 0, -0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 28, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 6, 0, 0, 0, 30, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 6, 0, 0, 0, 34, 0, 0, 0, 194, 44, -77, 60, 21, 0, 4, 0, 38, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 38, 0, 0, 0, 39, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 40, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 21, 0, 4, 0, 49, 0, 0, 0, 32, 0, 0, 0, 1, 0, -0, 0, 43, 0, 4, 0, 49, 0, 0, 0, 50, 0, 0, 0, 5, 0, 0, 0, 43, 0, 4, 0, 49, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 24, 0, 4, 0, 54, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 55, 0, 0, 0, 54, 0, 0, 0, 32, 0, -4, 0, 56, 0, 0, 0, 2, 0, 0, 0, 55, 0, 0, 0, 59, 0, 4, 0, 56, 0, 0, 0, 57, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 0, 30, 0, 7, 0, 63, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, -0, 0, 13, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 43, 0, 4, 0, 49, 0, 0, 0, 66, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 67, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 67, 0, -0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 49, 0, 0, 0, 71, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 72, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 59, 0, 4, 0, 72, 0, 0, 0, 73, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 75, 0, -0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 43, 0, 4, 0, 49, 0, 0, 0, 77, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 78, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 78, 0, 0, 0, 79, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 49, 0, -0, 0, 82, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 67, 0, 0, 0, 83, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 67, 0, 0, 0, 86, 0, 0, 0, 1, 0, 0, 0, 30, 0, 7, 0, 114, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 13, 0, -0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 115, 0, 0, 0, 7, 0, 0, 0, 114, 0, 0, 0, 43, 0, 4, 0, 38, 0, 0, 0, 132, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, 0, 133, 0, 0, 0, 6, 0, 0, 0, 132, 0, 0, 0, 30, 0, 6, 0, 134, 0, 0, 0, 7, 0, -0, 0, 6, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 32, 0, 4, 0, 135, 0, 0, 0, 3, 0, 0, 0, 134, 0, 0, 0, 59, 0, 4, 0, 135, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 139, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 139, 0, 0, 0, 141, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 144, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 144, 0, 0, 0, 145, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 3, 0, 0, 0, 13, 0, 0, 0, 59, 0, -4, 0, 148, 0, 0, 0, 149, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 139, 0, 0, 0, 152, 0, 0, 0, 3, 0, 0, 0, 26, 0, 2, 0, 159, 0, 0, 0, 32, 0, 4, 0, 160, 0, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 59, 0, 4, 0, 160, 0, 0, 0, 161, 0, -0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 64, 0, 0, 0, 65, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 89, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 105, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 8, 0, 0, 0, 109, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 116, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 69, 0, 0, 0, 68, 0, -0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 70, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 62, 0, 3, 0, 70, 0, 0, 0, 69, 0, 0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 74, 0, 0, 0, 73, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 76, 0, 0, 0, 65, 0, -0, 0, 71, 0, 0, 0, 62, 0, 3, 0, 76, 0, 0, 0, 74, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 81, 0, 0, 0, 65, 0, 0, 0, 77, 0, 0, 0, 62, 0, 3, 0, 81, 0, 0, 0, 80, 0, -0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 84, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 85, 0, 0, 0, 65, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 84, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 87, 0, 0, 0, 86, 0, -0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 88, 0, 0, 0, 65, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 88, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 90, 0, 0, 0, 65, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 91, 0, -0, 0, 90, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 92, 0, 0, 0, 89, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 92, 0, 0, 0, 91, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 93, 0, 0, 0, 65, 0, 0, 0, 82, 0, 0, 0, 61, 0, 4, 0, 7, 0, -0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 95, 0, 0, 0, 89, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 95, 0, 0, 0, 94, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 96, 0, 0, 0, 65, 0, 0, 0, 77, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 97, 0, 0, 0, 96, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 98, 0, 0, 0, 89, 0, 0, 0, 77, 0, 0, 0, 62, 0, 3, 0, 98, 0, 0, 0, 97, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 99, 0, 0, 0, 65, 0, 0, 0, 71, 0, -0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 100, 0, 0, 0, 99, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 101, 0, 0, 0, 89, 0, 0, 0, 71, 0, 0, 0, 62, 0, 3, 0, 101, 0, 0, 0, 100, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 102, 0, 0, 0, 65, 0, -0, 0, 66, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 103, 0, 0, 0, 102, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 104, 0, 0, 0, 89, 0, 0, 0, 66, 0, 0, 0, 62, 0, 3, 0, 104, 0, 0, 0, 103, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 106, 0, -0, 0, 89, 0, 0, 0, 62, 0, 3, 0, 105, 0, 0, 0, 106, 0, 0, 0, 57, 0, 5, 0, 2, 0, 0, 0, 107, 0, 0, 0, 18, 0, 0, 0, 105, 0, 0, 0, 61, 0, 4, 0, 14, 0, 0, 0, 108, 0, 0, 0, 105, 0, 0, 0, 62, 0, 3, 0, 89, 0, 0, 0, 108, 0, -0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 110, 0, 0, 0, 89, 0, 0, 0, 82, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 111, 0, 0, 0, 110, 0, 0, 0, 62, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 57, 0, 5, 0, 7, 0, 0, 0, 112, 0, 0, 0, 11, 0, -0, 0, 109, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 113, 0, 0, 0, 89, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 113, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 117, 0, 0, 0, 89, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, -0, 0, 118, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 119, 0, 0, 0, 116, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 119, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 120, 0, 0, 0, 89, 0, 0, 0, 82, 0, 0, 0, 61, 0, -4, 0, 7, 0, 0, 0, 121, 0, 0, 0, 120, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 122, 0, 0, 0, 116, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 122, 0, 0, 0, 121, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 123, 0, 0, 0, 89, 0, 0, 0, 77, 0, -0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 124, 0, 0, 0, 123, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 125, 0, 0, 0, 116, 0, 0, 0, 77, 0, 0, 0, 62, 0, 3, 0, 125, 0, 0, 0, 124, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 126, 0, 0, 0, 89, 0, -0, 0, 71, 0, 0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 127, 0, 0, 0, 126, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 128, 0, 0, 0, 116, 0, 0, 0, 71, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 127, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 129, 0, -0, 0, 89, 0, 0, 0, 66, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 130, 0, 0, 0, 129, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 131, 0, 0, 0, 116, 0, 0, 0, 66, 0, 0, 0, 62, 0, 3, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 8, 0, -0, 0, 137, 0, 0, 0, 116, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 138, 0, 0, 0, 137, 0, 0, 0, 65, 0, 5, 0, 139, 0, 0, 0, 140, 0, 0, 0, 136, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 138, 0, 0, 0, 65, 0, -5, 0, 8, 0, 0, 0, 142, 0, 0, 0, 116, 0, 0, 0, 82, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 141, 0, 0, 0, 143, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 146, 0, 0, 0, 116, 0, 0, 0, 77, 0, -0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 147, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 147, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 150, 0, 0, 0, 116, 0, 0, 0, 71, 0, 0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 151, 0, 0, 0, 150, 0, -0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 151, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 153, 0, 0, 0, 116, 0, 0, 0, 66, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 154, 0, 0, 0, 153, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 154, 0, 0, 0, 65, 0, -6, 0, 144, 0, 0, 0, 155, 0, 0, 0, 136, 0, 0, 0, 51, 0, 0, 0, 132, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 65, 0, 6, 0, 144, 0, 0, 0, 158, 0, -0, 0, 136, 0, 0, 0, 51, 0, 0, 0, 132, 0, 0, 0, 62, 0, 3, 0, 158, 0, 0, 0, 157, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 7, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 55, 0, 3, 0, 8, 0, 0, 0, 10, 0, -0, 0, 248, 0, 2, 0, 12, 0, 0, 0, 59, 0, 4, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 23, 0, 0, 0, 10, 0, 0, 0, 79, 0, 8, 0, 20, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 22, 0, 0, 0, 24, 0, 0, 0, 61, 0, 4, 0, 20, 0, 0, 0, 25, 0, 0, 0, 22, 0, 0, 0, 61, 0, 4, 0, 20, 0, 0, 0, 26, 0, 0, 0, 22, 0, 0, 0, 61, 0, 4, 0, 20, 0, 0, 0, 27, 0, -0, 0, 22, 0, 0, 0, 142, 0, 5, 0, 20, 0, 0, 0, 29, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 80, 0, 6, 0, 20, 0, 0, 0, 31, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 30, 0, 0, 0, 129, 0, 5, 0, 20, 0, 0, 0, 32, 0, 0, 0, 29, 0, -0, 0, 31, 0, 0, 0, 133, 0, 5, 0, 20, 0, 0, 0, 33, 0, 0, 0, 26, 0, 0, 0, 32, 0, 0, 0, 80, 0, 6, 0, 20, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 34, 0, 0, 0, 129, 0, 5, 0, 20, 0, 0, 0, 36, 0, 0, 0, 33, 0, -0, 0, 35, 0, 0, 0, 133, 0, 5, 0, 20, 0, 0, 0, 37, 0, 0, 0, 25, 0, 0, 0, 36, 0, 0, 0, 65, 0, 5, 0, 40, 0, 0, 0, 41, 0, 0, 0, 10, 0, 0, 0, 39, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 42, 0, 0, 0, 41, 0, 0, 0, 81, 0, -5, 0, 6, 0, 0, 0, 43, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 6, 0, 0, 0, 44, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 6, 0, 0, 0, 45, 0, 0, 0, 37, 0, 0, 0, 2, 0, 0, 0, 80, 0, 7, 0, 7, 0, -0, 0, 46, 0, 0, 0, 43, 0, 0, 0, 44, 0, 0, 0, 45, 0, 0, 0, 42, 0, 0, 0, 254, 0, 2, 0, 46, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 2, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 55, 0, 3, 0, 15, 0, 0, 0, 17, 0, -0, 0, 248, 0, 2, 0, 19, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 52, 0, 0, 0, 17, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 53, 0, 0, 0, 52, 0, 0, 0, 65, 0, 5, 0, 58, 0, 0, 0, 59, 0, 0, 0, 57, 0, 0, 0, 51, 0, -0, 0, 61, 0, 4, 0, 54, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 144, 0, 5, 0, 7, 0, 0, 0, 61, 0, 0, 0, 53, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 62, 0, 0, 0, 17, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 62, 0, -0, 0, 61, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 164, 177, 32, 18, 95, 250, 206, 184, 106, 101, 212, 154, 236, 240, 198, 17, 0, 238, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, -120, 116, 117, 114, 101, 48, 3, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 164, 18, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 180, -0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 11, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, -97, 105, 110, 0, 0, 0, 0, 134, 0, 0, 0, 138, 0, 0, 0, 142, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 176, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, -97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, -105, 100, 55, 54, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 15, 0, 13, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 15, 0, 16, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, -100, 52, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 102, 49, 45, 118, 102, 50, 45, 118, 102, 52, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 15, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 6, 0, 20, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 24, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, 6, 0, 37, 0, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, -0, 0, 0, 5, 0, 4, 0, 51, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 57, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 3, 0, 70, 0, 0, 0, 110, 88, 0, 0, 5, 0, 3, 0, 77, 0, 0, 0, 110, 89, 0, 0, 5, 0, 3, 0, 85, -0, 0, 0, 110, 90, 0, 0, 5, 0, 5, 0, 116, 0, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 8, 0, 129, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 129, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 53, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 55, 0, -0, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 129, 0, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 95, 105, 100, 55, 54, 0, 0, 0, 5, 0, 5, 0, 131, -0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 49, 0, 0, 0, 0, 5, 0, 5, 0, 138, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 7, 0, 142, 0, 0, 0, 118, -95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 6, 0, 148, 0, 0, 0, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, -0, 4, 0, 151, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 164, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 169, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 169, 0, 0, 0, 0, 0, 0, 0, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 171, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 176, 0, 0, 0, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 179, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 20, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 20, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 71, -0, 4, 0, 24, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 33, 0, 0, 0, 21, 0, 0, 0, 71, 0, 4, 0, 134, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 138, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, -0, 4, 0, 142, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 145, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 148, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 176, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, -0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 179, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, -0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 9, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, -0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 25, 0, 9, 0, 18, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, -0, 4, 0, 19, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 59, 0, 4, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 22, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 24, -0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 26, 0, 0, 0, 18, 0, 0, 0, 21, 0, 4, 0, 28, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 29, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 30, 0, 0, 0, 7, 0, 0, 0, 7, -0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 39, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 42, 0, 0, 0, 0, -0, 128, 63, 43, 0, 4, 0, 6, 0, 0, 0, 45, 0, 0, 0, 205, 204, 204, 61, 20, 0, 2, 0, 46, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 64, 21, 0, 4, 0, 71, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 71, -0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 71, 0, 0, 0, 78, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 71, 0, 0, 0, 83, 0, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 6, -0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 71, 0, 0, 0, 101, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 105, 0, 0, 0, 0, 0, 64, 64, 43, 0, 4, 0, 28, 0, 0, 0, 118, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 28, -0, 0, 0, 122, 0, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 129, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 130, 0, 0, 0, 7, 0, 0, 0, 129, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 132, -0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 133, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 138, -0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 141, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 141, 0, 0, 0, 142, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 133, 0, 0, 0, 148, -0, 0, 0, 1, 0, 0, 0, 30, 0, 3, 0, 169, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 170, 0, 0, 0, 7, 0, 0, 0, 169, 0, 0, 0, 32, 0, 4, 0, 175, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 175, 0, 0, 0, 176, 0, 0, 0, 3, -0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 130, 0, 0, 0, 131, 0, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 10, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 170, 0, 0, 0, 171, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 65, -0, 5, 0, 36, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 132, 0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 139, 0, 0, 0, 138, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 140, 0, 0, 0, 131, 0, 0, 0, 122, -0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 144, 0, 0, 0, 131, 0, 0, 0, 118, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 143, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 146, 0, 0, 0, 145, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 147, 0, 0, 0, 131, 0, 0, 0, 29, 0, 0, 0, 62, 0, 3, 0, 147, 0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 149, 0, 0, 0, 148, 0, 0, 0, 65, -0, 5, 0, 36, 0, 0, 0, 150, 0, 0, 0, 131, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 152, 0, 0, 0, 131, 0, 0, 0, 29, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 153, 0, 0, 0, 152, -0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 118, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 155, 0, 0, 0, 131, 0, 0, 0, 118, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 156, -0, 0, 0, 155, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 157, 0, 0, 0, 151, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 158, 0, 0, 0, 131, 0, 0, 0, 122, 0, 0, 0, 61, 0, 4, 0, 7, -0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 160, 0, 0, 0, 151, 0, 0, 0, 29, 0, 0, 0, 62, 0, 3, 0, 160, 0, 0, 0, 159, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 161, 0, 0, 0, 131, 0, 0, 0, 132, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 163, 0, 0, 0, 151, 0, 0, 0, 122, 0, 0, 0, 62, 0, 3, 0, 163, 0, 0, 0, 162, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 165, 0, 0, 0, 151, 0, 0, 0, 62, -0, 3, 0, 164, 0, 0, 0, 165, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 166, 0, 0, 0, 16, 0, 0, 0, 164, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 167, 0, 0, 0, 65, 0, 5, 0, 36, -0, 0, 0, 168, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 166, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 172, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 65, -0, 5, 0, 36, 0, 0, 0, 174, 0, 0, 0, 171, 0, 0, 0, 38, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 173, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 177, 0, 0, 0, 171, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 178, 0, 0, 0, 177, -0, 0, 0, 62, 0, 3, 0, 176, 0, 0, 0, 178, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 61, -0, 4, 0, 18, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 61, 0, 4, 0, 22, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 86, 0, 5, 0, 26, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 25, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 31, 0, 0, 0, 12, -0, 0, 0, 29, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 87, 0, 5, 0, 8, 0, 0, 0, 33, 0, 0, 0, 27, 0, 0, 0, 32, 0, 0, 0, 254, 0, 2, 0, 33, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 16, -0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 15, 0, 0, 0, 248, 0, 2, 0, 17, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 37, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 48, 0, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 10, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 57, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 70, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 77, 0, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 39, 0, 0, 0, 85, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 116, 0, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 40, 0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 41, 0, 0, 0, 40, -0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 43, 0, 0, 0, 41, 0, 0, 0, 42, 0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 44, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 188, 0, 5, 0, 46, 0, 0, 0, 47, 0, 0, 0, 44, 0, 0, 0, 45, -0, 0, 0, 247, 0, 3, 0, 50, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 47, 0, 0, 0, 49, 0, 0, 0, 56, 0, 0, 0, 248, 0, 2, 0, 49, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 52, 0, 0, 0, 15, 0, 0, 0, 62, 0, 3, 0, 51, 0, 0, 0, 52, -0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 53, 0, 0, 0, 13, 0, 0, 0, 51, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 54, 0, 0, 0, 51, 0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 54, 0, 0, 0, 79, 0, 9, 0, 8, 0, 0, 0, 55, 0, 0, 0, 53, -0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 48, 0, 0, 0, 55, 0, 0, 0, 249, 0, 2, 0, 50, 0, 0, 0, 248, 0, 2, 0, 56, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 58, 0, 0, 0, 15, -0, 0, 0, 62, 0, 3, 0, 57, 0, 0, 0, 58, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 59, 0, 0, 0, 13, 0, 0, 0, 57, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 60, 0, 0, 0, 57, 0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 60, 0, 0, 0, 62, -0, 3, 0, 48, 0, 0, 0, 59, 0, 0, 0, 249, 0, 2, 0, 50, 0, 0, 0, 248, 0, 2, 0, 50, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 61, 0, 0, 0, 48, 0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 62, -0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 63, 0, 0, 0, 62, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 65, 0, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 66, 0, 0, 0, 1, 0, 0, 0, 4, -0, 0, 0, 65, 0, 0, 0, 188, 0, 5, 0, 46, 0, 0, 0, 67, 0, 0, 0, 66, 0, 0, 0, 45, 0, 0, 0, 247, 0, 3, 0, 69, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 67, 0, 0, 0, 68, 0, 0, 0, 69, 0, 0, 0, 248, 0, 2, 0, 68, 0, 0, 0, 65, -0, 5, 0, 39, 0, 0, 0, 73, 0, 0, 0, 37, 0, 0, 0, 72, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 74, 0, 0, 0, 73, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 75, 0, 0, 0, 74, 0, 0, 0, 64, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 76, -0, 0, 0, 75, 0, 0, 0, 42, 0, 0, 0, 62, 0, 3, 0, 70, 0, 0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 79, 0, 0, 0, 37, 0, 0, 0, 78, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 133, 0, 5, 0, 6, -0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 64, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 82, 0, 0, 0, 81, 0, 0, 0, 42, 0, 0, 0, 62, 0, 3, 0, 77, 0, 0, 0, 82, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 84, 0, 0, 0, 37, 0, 0, 0, 83, -0, 0, 0, 62, 0, 3, 0, 84, 0, 0, 0, 42, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 86, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 87, 0, 0, 0, 70, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 88, 0, 0, 0, 86, 0, 0, 0, 87, -0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 89, 0, 0, 0, 77, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 90, 0, 0, 0, 77, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 91, 0, 0, 0, 89, 0, 0, 0, 90, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 92, -0, 0, 0, 88, 0, 0, 0, 91, 0, 0, 0, 12, 0, 8, 0, 6, 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 92, 0, 0, 0, 93, 0, 0, 0, 42, 0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 95, 0, 0, 0, 1, 0, 0, 0, 31, 0, 0, 0, 94, -0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 96, 0, 0, 0, 42, 0, 0, 0, 95, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 96, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 97, 0, 0, 0, 85, 0, 0, 0, 133, 0, 5, 0, 6, 0, 0, 0, 99, 0, 0, 0, 97, -0, 0, 0, 98, 0, 0, 0, 129, 0, 5, 0, 6, 0, 0, 0, 100, 0, 0, 0, 99, 0, 0, 0, 98, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 102, 0, 0, 0, 37, 0, 0, 0, 101, 0, 0, 0, 62, 0, 3, 0, 102, 0, 0, 0, 100, 0, 0, 0, 249, 0, 2, 0, 69, -0, 0, 0, 248, 0, 2, 0, 69, 0, 0, 0, 65, 0, 5, 0, 39, 0, 0, 0, 103, 0, 0, 0, 15, 0, 0, 0, 38, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 104, 0, 0, 0, 103, 0, 0, 0, 131, 0, 5, 0, 6, 0, 0, 0, 106, 0, 0, 0, 104, 0, 0, 0, 105, -0, 0, 0, 12, 0, 6, 0, 6, 0, 0, 0, 107, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 106, 0, 0, 0, 188, 0, 5, 0, 46, 0, 0, 0, 108, 0, 0, 0, 107, 0, 0, 0, 45, 0, 0, 0, 247, 0, 3, 0, 110, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 108, -0, 0, 0, 109, 0, 0, 0, 110, 0, 0, 0, 248, 0, 2, 0, 109, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 111, 0, 0, 0, 37, 0, 0, 0, 79, 0, 7, 0, 7, 0, 0, 0, 112, 0, 0, 0, 111, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, -0, 4, 0, 8, 0, 0, 0, 113, 0, 0, 0, 37, 0, 0, 0, 79, 0, 9, 0, 8, 0, 0, 0, 114, 0, 0, 0, 113, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 37, 0, 0, 0, 114, 0, 0, 0, 65, -0, 5, 0, 39, 0, 0, 0, 115, 0, 0, 0, 37, 0, 0, 0, 83, 0, 0, 0, 62, 0, 3, 0, 115, 0, 0, 0, 42, 0, 0, 0, 249, 0, 2, 0, 110, 0, 0, 0, 248, 0, 2, 0, 110, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 65, -0, 5, 0, 36, 0, 0, 0, 119, 0, 0, 0, 15, 0, 0, 0, 118, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 120, 0, 0, 0, 119, 0, 0, 0, 133, 0, 5, 0, 8, 0, 0, 0, 121, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 65, 0, 5, 0, 36, 0, 0, 0, 123, -0, 0, 0, 15, 0, 0, 0, 122, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 124, 0, 0, 0, 123, 0, 0, 0, 129, 0, 5, 0, 8, 0, 0, 0, 125, 0, 0, 0, 121, 0, 0, 0, 124, 0, 0, 0, 62, 0, 3, 0, 116, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 8, -0, 0, 0, 126, 0, 0, 0, 116, 0, 0, 0, 254, 0, 2, 0, 126, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, +114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, +1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, +122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, +0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, +0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, +0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, +2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 117, 76, 56, 59, 32, 6, 42, 25, 181, 71, 17, 176, 109, 21, 238, 52, 0, 236, 40, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, +1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, +2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, +2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, +0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, +116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, +0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, +46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, +110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, +0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, +108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, +0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, +0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, +0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, +0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, +0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, +117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, +0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, +50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, +0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, +0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, +48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, +97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 170, +1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, +1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, +101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, +102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, +0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, +0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, +102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, +117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, +97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, +2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, +0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, +0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, +108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, +83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, +111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, +114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, +60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, +110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, +2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, +0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, +108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, +2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, +0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, +0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, +111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, +0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, +0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, +101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, +71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, +101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, +0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, +0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, +22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, +22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, +0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, +79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, +2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, +2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, +0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, +0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, +0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, +0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, +0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, +0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, +0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, +0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, +0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, +0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, +0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, +0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, +0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, +0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, +0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, +0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, +0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, +1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, +1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, +1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, +204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, +0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, +0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, +0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, +0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, +0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, +0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, +2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, +2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, +0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, +2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, +2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, +2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, +2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, +2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, +0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, +0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, +0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, +0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, +0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, +0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, +0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, +0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, +0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, +0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, +0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, +0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, +0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, +0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, +1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, +1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, +1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, +1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, +2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, +0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, +1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, +1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, +0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, +1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, +1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, +1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, +0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, +1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, +1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, +1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, +1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, +1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, +1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, +2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, +2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, +0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, +0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, +0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, +0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, +2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, +2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, +2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, +2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, +0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, +0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, +2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, +2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, +2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, +2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, +2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, +2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, +2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, +2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, +2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 117, 76, 56, 59, 32, 6, 42, 25, 181, 71, 17, 176, 109, 21, 238, 52, 0, 236, 40, 0, 0, 3, 2, 35, 7, 0, 4, +1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, +53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, +0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, +0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, 0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, +0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, +101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, +0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, +6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, +100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, +111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, +111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, +7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, +111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, +49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, +82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, +104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, +6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, +0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, +0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, +0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, +0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, +0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, +0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, +0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, +85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, +108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, +0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, +0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, +0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, +0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, +0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, +0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, +67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, +0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, +0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, +108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, +80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, +0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, +100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, +0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, +4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, +108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, +0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, +0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, +0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, +4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, +0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, +0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, +0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, +0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, +0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, +0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, +0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, +0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, +0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, +0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, +4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, +4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, +4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, +0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, +165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, +97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, +4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, +4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, +4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, +4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, +0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, +4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, +4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, +0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, +0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, +0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, +0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, +0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, +0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, +0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, +0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, +0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, +0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, +0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, +0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, +0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, +0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, +0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, +5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, +2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, +0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, +0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, +0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, +0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, +0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, +0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, +0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, +0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, +0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, +0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, +0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, +0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, +0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, +5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, +0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, +5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, +0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, +0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, +7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, +0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, +2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, +0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, +0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, +0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, +0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, +3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, +3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, +0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, +0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, +0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, +0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index dca05de546..85f0a00eae 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -1,147 +1,208 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { public partial class SpriteEffect { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 5, 0, 0, -0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, -0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, -7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, -112, 108, 101, 114, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 20, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, -0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -22, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 53, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, -0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, -83, 105, 122, 101, 95, 105, 100, 49, 57, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, -51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 32, 0, 0, 0, 8, -0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, -120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, -0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 50, 57, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, -0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 22, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 72, 0, 0, 0, 8, 0, 0, 0, -1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 10, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 80, 0, 0, 0, -16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, -101, 99, 116, 1, 197, 28, 71, 53, 50, 246, 70, 142, 27, 184, 231, 50, 114, 52, 51, 181, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 227, 25, 196, 119, 122, 150, 76, 62, 187, 143, 130, 89, 14, 78, 39, 241, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, -68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, -249, 84, 156, 111, 93, 41, 30, 97, 165, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 252, 67, 71, 43, 11, 48, 184, 87, 53, 227, 28, 180, 25, 12, 125, 19, 0, 166, 9, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, -0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 2, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 96, 9, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 77, 0, 0, 0, 0, -0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 9, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, -0, 0, 0, 15, 0, 0, 0, 21, 0, 0, 0, 60, 0, 0, 0, 66, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, -0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 5, 0, 5, 0, 11, -0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 15, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 21, 0, 0, 0, 97, 95, 80, 79, 83, 73, 84, 73, 79, 78, 48, 0, 5, 0, 5, 0, 25, 0, 0, 0, 86, -83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 25, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 50, 0, 0, 0, 6, 0, 7, 0, 25, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -0, 0, 0, 6, 0, 8, 0, 25, 0, 0, 0, 2, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 5, 0, 4, 0, 27, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 38, 0, 0, 0, 80, 101, 114, 68, 114, -97, 119, 0, 6, 0, 9, 0, 38, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 95, 105, 100, 55, 51, 0, 0, 0, 0, 5, 0, 3, 0, 40, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 46, 0, 0, 0, 86, 83, 95, 79, 85, -84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 46, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 7, 0, 46, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, -0, 0, 0, 5, 0, 5, 0, 48, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 58, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 58, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 0, 6, 0, 7, 0, 58, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 58, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, 101, 0, 6, -0, 7, 0, 58, 0, 0, 0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 60, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 66, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 76, -0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 15, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 21, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 38, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 72, -0, 5, 0, 38, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 38, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 3, 0, 38, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 58, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 58, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 58, -0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 72, 0, 5, 0, 58, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 58, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 66, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, -0, 4, 0, 76, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 76, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, -0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 4, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 21, -0, 4, 0, 12, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 13, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 14, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 14, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 32, -0, 4, 0, 17, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 20, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 20, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 32, -0, 4, 0, 23, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 30, 0, 5, 0, 25, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 34, 0, 0, 0, 2, -0, 0, 0, 24, 0, 4, 0, 37, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 38, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 39, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 59, 0, 4, 0, 39, 0, 0, 0, 40, 0, 0, 0, 2, 0, 0, 0, 32, -0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 30, 0, 4, 0, 46, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 47, 0, 0, 0, 7, 0, 0, 0, 46, 0, 0, 0, 21, 0, 4, 0, 55, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, -0, 4, 0, 55, 0, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, 0, 57, 0, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 30, 0, 6, 0, 58, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 57, 0, 0, 0, 57, 0, 0, 0, 32, 0, 4, 0, 59, 0, 0, 0, 3, -0, 0, 0, 58, 0, 0, 0, 59, 0, 4, 0, 59, 0, 0, 0, 60, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 65, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 65, 0, 0, 0, 66, -0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 26, 0, 2, 0, 74, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 59, 0, 4, 0, 75, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 54, -0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 26, 0, 0, 0, 27, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 47, -0, 0, 0, 48, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 18, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 18, 0, 0, 0, 16, 0, 0, 0, 61, 0, 4, 0, 7, -0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 24, 0, 0, 0, 22, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 28, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 61, -0, 4, 0, 7, 0, 0, 0, 29, 0, 0, 0, 28, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 30, 0, 0, 0, 27, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 30, 0, 0, 0, 29, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 31, 0, 0, 0, 11, 0, 0, 0, 13, -0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 33, 0, 0, 0, 27, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 33, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 35, 0, 0, 0, 27, -0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 65, 0, 5, 0, 41, 0, 0, 0, 42, 0, 0, 0, 40, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 43, 0, 0, 0, 42, 0, 0, 0, 144, 0, 5, 0, 7, -0, 0, 0, 44, 0, 0, 0, 36, 0, 0, 0, 43, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 45, 0, 0, 0, 27, 0, 0, 0, 34, 0, 0, 0, 62, 0, 3, 0, 45, 0, 0, 0, 44, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 49, 0, 0, 0, 27, 0, 0, 0, 34, -0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 50, 0, 0, 0, 49, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 51, 0, 0, 0, 48, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 51, 0, 0, 0, 50, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 52, 0, 0, 0, 27, -0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 53, 0, 0, 0, 52, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 0, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 54, 0, 0, 0, 53, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 61, -0, 0, 0, 48, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 62, 0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 63, 0, 0, 0, 64, 0, 0, 0, 60, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 64, 0, 0, 0, 62, 0, 0, 0, 65, 0, 5, 0, 17, -0, 0, 0, 67, 0, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 68, 0, 0, 0, 67, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 68, 0, 0, 0, 65, 0, 6, 0, 69, 0, 0, 0, 70, 0, 0, 0, 60, 0, 0, 0, 19, 0, 0, 0, 56, -0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 71, 0, 0, 0, 70, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 72, 0, 0, 0, 71, 0, 0, 0, 65, 0, 6, 0, 69, 0, 0, 0, 73, 0, 0, 0, 60, 0, 0, 0, 19, 0, 0, 0, 56, 0, 0, 0, 62, 0, 3, 0, 73, -0, 0, 0, 72, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 36, 5, 150, 203, 86, 103, 104, 49, 183, 212, 179, 236, 234, 198, 94, 8, 0, 246, 11, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 2, 0, 0, 0, -18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 3, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 41, 0, 0, 0, 0, 160, 11, 0, 0, -3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 83, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, -15, 0, 8, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 55, 0, 0, 0, 59, 0, 0, 0, 79, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, -109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, -1, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 12, 0, 13, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, 102, 50, 45, 118, 102, -52, 49, 59, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 12, 0, 16, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 51, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, 102, 50, 45, 118, 102, -52, 49, 59, 0, 5, 0, 4, 0, 15, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 6, 0, 20, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 24, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, -0, 0, 0, 0, 5, 0, 4, 0, 36, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 4, 0, 40, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 6, 0, 9, 0, 40, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, -101, 95, 105, 100, 49, 53, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 55, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, -84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 49, 57, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 49, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 4, 0, 0, 0, -84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 51, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 53, 0, 0, 6, 0, 9, 0, -40, 0, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 50, 55, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, -50, 57, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 95, 105, 100, 51, 49, 0, 0, 6, 0, 9, 0, 40, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, -108, 83, 105, 122, 101, 95, 105, 100, 51, 51, 0, 0, 6, 0, 6, 0, 40, 0, 0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 5, 0, 3, 0, 42, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 50, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, -0, 0, 0, 0, 6, 0, 8, 0, 50, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 7, 0, 50, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, -5, 0, 5, 0, 52, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 55, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 6, 0, 59, 0, 0, 0, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, -5, 0, 4, 0, 63, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 67, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 72, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 72, 0, 0, 0, 0, 0, 0, 0, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 74, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 79, 0, 0, 0, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 82, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 20, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 20, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, -71, 0, 4, 0, 24, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 24, 0, 0, 0, 33, 0, 0, 0, 21, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 1, 0, 0, 0, -35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, -32, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, -72, 0, 5, 0, 40, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 40, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 71, 0, 3, 0, -40, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 42, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 42, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 55, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 59, 0, 0, 0, -11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 79, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 82, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 82, 0, 0, 0, 33, 0, 0, 0, 41, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, -33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 9, 0, 0, 0, -7, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 25, 0, 9, 0, 18, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 19, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 59, 0, 4, 0, 19, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 22, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 0, 0, 0, 0, -22, 0, 0, 0, 59, 0, 4, 0, 23, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 26, 0, 0, 0, 18, 0, 0, 0, 21, 0, 4, 0, 28, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 30, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 30, 0, 13, 0, 40, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, -8, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 40, 0, 0, 0, 59, 0, 4, 0, 41, 0, 0, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 43, 0, 0, 0, 10, 0, 0, 0, 32, 0, 4, 0, 44, 0, 0, 0, 2, 0, 0, 0, -8, 0, 0, 0, 30, 0, 4, 0, 50, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 51, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 43, 0, 4, 0, 28, 0, 0, 0, 53, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 54, 0, 0, 0, 1, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 54, 0, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 58, 0, 0, 0, 59, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 61, 0, 0, 0, 7, 0, 0, 0, -8, 0, 0, 0, 30, 0, 3, 0, 72, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 73, 0, 0, 0, 7, 0, 0, 0, 72, 0, 0, 0, 32, 0, 4, 0, 78, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 78, 0, 0, 0, 79, 0, 0, 0, 3, 0, 0, 0, -59, 0, 4, 0, 23, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 51, 0, 0, 0, 52, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, -10, 0, 0, 0, 63, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 67, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 73, 0, 0, 0, 74, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 56, 0, 0, 0, 55, 0, 0, 0, 65, 0, 5, 0, -30, 0, 0, 0, 57, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 62, 0, 3, 0, 57, 0, 0, 0, 56, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 60, 0, 0, 0, 59, 0, 0, 0, 65, 0, 5, 0, 61, 0, 0, 0, 62, 0, 0, 0, 52, 0, 0, 0, 29, 0, 0, 0, -62, 0, 3, 0, 62, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 64, 0, 0, 0, 52, 0, 0, 0, 53, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 65, 0, 0, 0, 64, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 66, 0, 0, 0, 63, 0, 0, 0, -29, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 65, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 68, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 67, 0, 0, 0, 68, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 69, 0, 0, 0, 16, 0, 0, 0, 67, 0, 0, 0, -61, 0, 4, 0, 9, 0, 0, 0, 70, 0, 0, 0, 67, 0, 0, 0, 62, 0, 3, 0, 63, 0, 0, 0, 70, 0, 0, 0, 65, 0, 5, 0, 61, 0, 0, 0, 71, 0, 0, 0, 63, 0, 0, 0, 53, 0, 0, 0, 62, 0, 3, 0, 71, 0, 0, 0, 69, 0, 0, 0, 65, 0, 5, 0, -61, 0, 0, 0, 75, 0, 0, 0, 63, 0, 0, 0, 53, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 76, 0, 0, 0, 75, 0, 0, 0, 65, 0, 5, 0, 61, 0, 0, 0, 77, 0, 0, 0, 74, 0, 0, 0, 29, 0, 0, 0, 62, 0, 3, 0, 77, 0, 0, 0, 76, 0, 0, 0, -65, 0, 5, 0, 61, 0, 0, 0, 80, 0, 0, 0, 74, 0, 0, 0, 29, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 62, 0, 3, 0, 79, 0, 0, 0, 81, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 61, 0, 4, 0, 18, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 61, 0, 4, 0, 22, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, -86, 0, 5, 0, 26, 0, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 25, 0, 0, 0, 65, 0, 5, 0, 30, 0, 0, 0, 31, 0, 0, 0, 12, 0, 0, 0, 29, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 87, 0, 5, 0, 8, 0, 0, 0, -33, 0, 0, 0, 27, 0, 0, 0, 32, 0, 0, 0, 254, 0, 2, 0, 33, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 15, 0, 0, 0, 248, 0, 2, 0, 17, 0, 0, 0, -59, 0, 4, 0, 10, 0, 0, 0, 36, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 37, 0, 0, 0, 15, 0, 0, 0, 62, 0, 3, 0, 36, 0, 0, 0, 37, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 36, 0, 0, 0, -61, 0, 4, 0, 9, 0, 0, 0, 39, 0, 0, 0, 36, 0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 39, 0, 0, 0, 65, 0, 5, 0, 44, 0, 0, 0, 45, 0, 0, 0, 42, 0, 0, 0, 43, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 46, 0, 0, 0, 45, 0, 0, 0, -133, 0, 5, 0, 8, 0, 0, 0, 47, 0, 0, 0, 38, 0, 0, 0, 46, 0, 0, 0, 254, 0, 2, 0, 47, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, +114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, +97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, +71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, +101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, +1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, +3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, +101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, +120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, +122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, +105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, +0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, +102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, +0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, +28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 178, 39, 67, 162, 90, 62, 172, 105, 181, 17, 250, 4, 227, 29, +206, 0, 208, 19, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 205, 0, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 204, 0, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 239, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 225, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 0, +0, 0, 218, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 111, 0, 0, 0, 239, 0, 0, 0, 16, 0, 3, 0, 205, 0, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, +0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, +0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, +116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, +112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, +97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, +4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, +105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 179, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, +0, 0, 5, 0, 7, 0, 180, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 197, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, +95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 199, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, +0, 0, 5, 0, 6, 0, 198, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 200, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 200, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 201, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 201, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 202, 0, 0, 0, 80, 83, 95, 83, 84, 82, +69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 202, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 202, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 203, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 205, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, +83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 208, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, +0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 219, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 218, 0, 0, 0, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, +0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, +110, 0, 6, 0, 6, 0, 221, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 222, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 223, 0, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 225, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, +99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 230, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 237, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 237, 0, +0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, +0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, +0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, +0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, +0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, +0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, +101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 238, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, +108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 49, 48, 0, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 196, 0, 0, 0, 30, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 198, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 198, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 0, +0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 0, 0, 0, 3, 22, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 237, 0, 0, 0, 2, 0, 0, 0, 72, 0, +5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 0, 0, +0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 3, 0, 0, 0, 35, 0, +0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, +0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, +5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 34, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, +2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, +0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, +4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, +4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, +0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 180, 0, 0, 0, 2, 0, 0, 0, 3, 0, +0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 197, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 199, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, 0, 200, 0, 0, 0, 38, 0, 0, 0, 30, 0, +3, 0, 201, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 202, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 6, 0, 0, 0, 202, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, +0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 219, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 220, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 221, 0, +0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 222, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 6, 0, 0, 0, 222, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 0, 0, 0, 2, 0, 0, 0, 30, 0, +13, 0, 237, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 238, 0, 0, 0, 2, 0, 0, 0, 237, 0, +0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 241, 0, 0, 0, 10, 0, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, +0, 0, 59, 0, 4, 0, 238, 0, 0, 0, 239, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 196, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 204, 0, 0, 0, 6, 0, +0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 214, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 215, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 0, 0, 0, 216, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 219, 0, 0, 0, 218, 0, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 224, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 212, 0, +0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, +0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, +0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 204, 0, +0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, +0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 190, 0, 0, 0, 57, 0, 4, 0, 3, 0, +0, 0, 193, 0, 0, 0, 114, 0, 0, 0, 65, 0, 5, 0, 180, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 195, 0, 0, 0, 193, 0, 0, 0, 194, 0, +0, 0, 254, 0, 2, 0, 195, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 206, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 207, 0, 0, 0, 204, 0, 0, 0, 208, 0, 0, 0, 61, 0, +4, 0, 38, 0, 0, 0, 209, 0, 0, 0, 198, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 209, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 210, 0, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 211, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 196, 0, 0, 0, 213, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 65, 0, +5, 0, 70, 0, 0, 0, 227, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 229, 0, 0, 0, 224, 0, 0, 0, 230, 0, +0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 231, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 231, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 232, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 233, 0, 0, 0, 224, 0, 0, 0, 212, 0, +0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 234, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 235, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 236, 0, 0, 0, 235, 0, +0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 236, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 216, 178, 39, 67, 162, 90, 62, 172, 105, 181, 17, 250, 4, 227, 29, 206, +0, 208, 19, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 205, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 204, 0, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 239, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 225, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 0, 0, +0, 218, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 111, 0, 0, 0, 239, 0, 0, 0, 16, 0, 3, 0, 205, 0, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, +0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, +0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, +101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, +105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, +0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 179, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, +0, 5, 0, 7, 0, 180, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 197, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, +102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 199, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, +0, 5, 0, 6, 0, 198, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 200, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 200, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 5, 0, 5, 0, 201, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 201, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 202, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 6, 0, 6, 0, 202, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 202, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 203, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 205, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 208, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, +0, 5, 0, 6, 0, 216, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 219, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 218, 0, 0, 0, 105, 110, 95, +86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, +0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +0, 6, 0, 6, 0, 221, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 222, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 223, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 225, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, +116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 230, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 237, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, +0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, +0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, +0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, +0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, +0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, +0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, +49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, +51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, +53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, +55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, +57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 238, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, +115, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 49, 48, 0, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 196, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 198, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 198, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 0, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 237, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, +0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 0, 0, 0, +0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, +0, 24, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, +0, 72, 0, 5, 0, 237, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, +0, 237, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 239, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, +0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, +0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, +0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, +0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 180, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, +0, 43, 0, 4, 0, 4, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 197, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 199, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, 0, 200, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, +0, 201, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 202, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 6, 0, 0, 0, 202, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, +0, 212, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 219, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 220, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 221, 0, 0, +0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 222, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 6, 0, 0, 0, 222, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 0, 0, 0, 2, 0, 0, 0, 30, 0, 13, +0, 237, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 238, 0, 0, 0, 2, 0, 0, 0, 237, 0, 0, +0, 43, 0, 4, 0, 133, 0, 0, 0, 241, 0, 0, 0, 10, 0, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, +0, 59, 0, 4, 0, 238, 0, 0, 0, 239, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 196, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 204, 0, 0, 0, 6, 0, 0, +0, 59, 0, 4, 0, 197, 0, 0, 0, 214, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 215, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 0, 0, 0, 216, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 219, 0, 0, 0, 218, 0, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 223, 0, 0, 0, 224, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 212, 0, 0, +0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, +0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, +0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 204, 0, 0, +0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, +0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 190, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, +0, 193, 0, 0, 0, 114, 0, 0, 0, 65, 0, 5, 0, 180, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 195, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, +0, 254, 0, 2, 0, 195, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 206, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 207, 0, 0, 0, 204, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, +0, 38, 0, 0, 0, 209, 0, 0, 0, 198, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 209, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 210, 0, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 211, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, +0, 3, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 196, 0, 0, 0, 213, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 65, 0, 5, +0, 70, 0, 0, 0, 227, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 229, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, +0, 61, 0, 4, 0, 3, 0, 0, 0, 231, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 231, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 232, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 233, 0, 0, 0, 224, 0, 0, 0, 212, 0, 0, +0, 61, 0, 4, 0, 3, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 234, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 235, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, +0, 62, 0, 3, 0, 216, 0, 0, 0, 236, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index 8666d79cf3..88664ea3d7 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -1,137 +1,289 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { internal partial class UIEffect { private static readonly byte[] binaryBytecode = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, -8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, -114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, -108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 20, 215, 173, 62, 239, 254, 242, 28, 221, 213, 6, 249, 205, 142, 245, 217, 0, 68, 12, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, -80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 2, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, -112, 108, 101, 114, 40, 0, 0, 0, 0, 236, 11, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 97, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, -0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 15, 0, 0, 0, 21, 0, 0, 0, 27, 0, 0, 0, 32, 0, 0, 0, 74, 0, 0, 0, 79, 0, 0, 0, 83, 0, 0, 0, 87, 0, 0, -0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, -0, 6, 0, 7, 0, 9, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, 0, 11, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 7, 0, 15, 0, 0, 0, 97, 95, 66, 65, 84, 67, 72, -95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 21, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 27, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 32, 0, 0, 0, 97, 95, 80, -79, 83, 73, 84, 73, 79, 78, 48, 0, 5, 0, 5, 0, 35, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 35, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 0, 0, 6, 0, 6, 0, 35, 0, 0, -0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 35, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 35, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 0, 0, 0, 0, 6, 0, 8, 0, 35, 0, 0, 0, 4, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 5, 0, 4, 0, 37, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 5, 0, 54, 0, 0, -0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 54, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 54, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, -100, 55, 52, 0, 0, 6, 0, 7, 0, 54, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 54, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, -0, 56, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 72, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 72, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, -0, 6, 0, 7, 0, 72, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 72, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, 97, 110, 99, 101, 0, 6, 0, 7, 0, 72, 0, 0, -0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 74, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 79, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 83, 0, 0, 0, 118, 95, 84, -69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 7, 0, 87, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 96, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 15, 0, 0, -0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 21, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 27, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 32, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 72, 0, 0, -0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 72, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 72, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, 0, 72, 0, 5, 0, 72, 0, 0, 0, 3, 0, 0, -0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 72, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 79, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 30, 0, 0, -0, 2, 0, 0, 0, 71, 0, 4, 0, 96, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 96, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, -0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 6, 0, 9, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, -0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 21, 0, 4, 0, 12, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 14, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 14, 0, 0, 0, 15, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 20, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, -0, 20, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 23, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 25, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 26, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, -0, 26, 0, 0, 0, 27, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 29, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 26, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 30, 0, 7, -0, 35, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 43, 0, 4, 0, 12, 0, 0, 0, 50, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 54, 0, 0, -0, 7, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, 0, 55, 0, 0, 0, 7, 0, 0, 0, 54, 0, 0, 0, 21, 0, 4, 0, 69, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 69, 0, 0, 0, 70, 0, 0, 0, 1, 0, 0, -0, 28, 0, 4, 0, 71, 0, 0, 0, 6, 0, 0, 0, 70, 0, 0, 0, 30, 0, 6, 0, 72, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 71, 0, 0, 0, 71, 0, 0, 0, 32, 0, 4, 0, 73, 0, 0, 0, 3, 0, 0, 0, 72, 0, 0, 0, 59, 0, 4, 0, 73, 0, 0, -0, 74, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 77, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 77, 0, 0, 0, 79, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 82, 0, 0, -0, 83, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 87, 0, 0, 0, 3, 0, 0, 0, 26, 0, 2, 0, 94, 0, 0, 0, 32, 0, 4, 0, 95, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, -0, 59, 0, 4, 0, 95, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 11, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, -0, 36, 0, 0, 0, 37, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 55, 0, 0, 0, 56, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 16, 0, 0, 0, 15, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 18, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, -0, 62, 0, 3, 0, 18, 0, 0, 0, 16, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 24, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 24, 0, 0, 0, 22, 0, 0, 0, 61, 0, 4, -0, 7, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 30, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 30, 0, 0, 0, 28, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 33, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, -0, 29, 0, 0, 0, 34, 0, 0, 0, 11, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 34, 0, 0, 0, 33, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 38, 0, 0, 0, 11, 0, 0, 0, 31, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 39, 0, 0, 0, 38, 0, 0, -0, 65, 0, 5, 0, 29, 0, 0, 0, 40, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 40, 0, 0, 0, 39, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 41, 0, 0, 0, 11, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 42, 0, 0, -0, 41, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 43, 0, 0, 0, 37, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 43, 0, 0, 0, 42, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 44, 0, 0, 0, 11, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, -0, 45, 0, 0, 0, 44, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 46, 0, 0, 0, 37, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 46, 0, 0, 0, 45, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, -0, 6, 0, 0, 0, 48, 0, 0, 0, 47, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 49, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 49, 0, 0, 0, 48, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 51, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, -0, 61, 0, 4, 0, 7, 0, 0, 0, 52, 0, 0, 0, 51, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 53, 0, 0, 0, 37, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 53, 0, 0, 0, 52, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 57, 0, 0, 0, 37, 0, 0, -0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 58, 0, 0, 0, 57, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 59, 0, 0, 0, 56, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 59, 0, 0, 0, 58, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 60, 0, 0, -0, 37, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 61, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 62, 0, 0, 0, 56, 0, 0, 0, 25, 0, 0, 0, 62, 0, 3, 0, 62, 0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, -0, 63, 0, 0, 0, 37, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 64, 0, 0, 0, 63, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 65, 0, 0, 0, 56, 0, 0, 0, 19, 0, 0, 0, 62, 0, 3, 0, 65, 0, 0, 0, 64, 0, 0, 0, 65, 0, 5, -0, 17, 0, 0, 0, 66, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 67, 0, 0, 0, 66, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 68, 0, 0, 0, 56, 0, 0, 0, 13, 0, 0, 0, 62, 0, 3, 0, 68, 0, 0, 0, 67, 0, 0, -0, 65, 0, 5, 0, 29, 0, 0, 0, 75, 0, 0, 0, 56, 0, 0, 0, 31, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 76, 0, 0, 0, 75, 0, 0, 0, 65, 0, 5, 0, 77, 0, 0, 0, 78, 0, 0, 0, 74, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 78, 0, 0, -0, 76, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 80, 0, 0, 0, 56, 0, 0, 0, 25, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 81, 0, 0, 0, 80, 0, 0, 0, 62, 0, 3, 0, 79, 0, 0, 0, 81, 0, 0, 0, 65, 0, 5, 0, 23, 0, 0, 0, 84, 0, 0, -0, 56, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 85, 0, 0, 0, 84, 0, 0, 0, 62, 0, 3, 0, 83, 0, 0, 0, 85, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 0, 0, 0, 56, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, -0, 89, 0, 0, 0, 88, 0, 0, 0, 62, 0, 3, 0, 87, 0, 0, 0, 89, 0, 0, 0, 65, 0, 6, 0, 86, 0, 0, 0, 90, 0, 0, 0, 74, 0, 0, 0, 31, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 127, 0, 4, -0, 6, 0, 0, 0, 92, 0, 0, 0, 91, 0, 0, 0, 65, 0, 6, 0, 86, 0, 0, 0, 93, 0, 0, 0, 74, 0, 0, 0, 31, 0, 0, 0, 70, 0, 0, 0, 62, 0, 3, 0, 93, 0, 0, 0, 92, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 88, -73, 87, 188, 34, 20, 168, 55, 190, 124, 230, 223, 190, 1, 43, 64, 0, 154, 11, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 2, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -83, 97, 109, 112, 108, 101, 114, 20, 0, 0, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 40, 0, 0, 0, 0, 80, 11, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 101, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, -0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 10, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 69, 0, 0, 0, 72, 0, -0, 0, 97, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, 0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, -0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 6, 0, 6, 0, 9, 0, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 14, 0, 13, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, -50, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 45, 118, 102, 50, 45, 102, 49, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 6, 0, 16, 0, 0, 0, 115, 97, -109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 19, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 23, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, -6, 0, 33, 0, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 56, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 8, 0, 56, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 56, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 56, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, -7, 0, 56, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, 0, 58, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 7, 0, 61, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, -73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 65, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 69, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 6, 0, 72, 0, 0, 0, 103, 108, 95, 70, 114, 97, -103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 4, 0, 75, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 85, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 90, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, -7, 0, 90, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 92, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 97, 0, 0, 0, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, -103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 100, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 19, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 19, 0, -0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 23, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 23, 0, 0, 0, 33, 0, 0, 0, 20, 0, 0, 0, 71, 0, 4, 0, 61, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 65, 0, -0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 69, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 72, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 97, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, -0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 23, 0, 4, 0, 8, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 9, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, -0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 32, 0, 4, 0, 15, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 25, 0, 9, 0, 17, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 59, 0, 4, 0, 18, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 21, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 59, 0, -4, 0, 22, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 27, 0, 3, 0, 25, 0, 0, 0, 17, 0, 0, 0, 21, 0, 4, 0, 27, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 29, 0, -0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 20, 0, 2, 0, 39, 0, -0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 50, 0, 0, 0, 2, 0, 0, 0, 30, 0, 6, 0, 56, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, 0, 57, 0, 0, 0, 7, 0, 0, 0, 56, 0, 0, 0, 43, 0, 4, 0, 27, 0, -0, 0, 59, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 60, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 60, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 64, 0, -0, 0, 65, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 68, 0, 0, 0, 69, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 68, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 0, 30, 0, 3, 0, 90, 0, -0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 91, 0, 0, 0, 7, 0, 0, 0, 90, 0, 0, 0, 32, 0, 4, 0, 96, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 96, 0, 0, 0, 97, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 22, 0, 0, 0, 100, 0, -0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 57, 0, 0, 0, 58, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 75, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 85, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 91, 0, 0, 0, 92, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 62, 0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 63, 0, 0, 0, 58, 0, -0, 0, 59, 0, 0, 0, 62, 0, 3, 0, 63, 0, 0, 0, 62, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 67, 0, 0, 0, 58, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 67, 0, 0, 0, 66, 0, -0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 70, 0, 0, 0, 69, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 71, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 62, 0, 3, 0, 71, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 73, 0, 0, 0, 72, 0, -0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 74, 0, 0, 0, 58, 0, 0, 0, 28, 0, 0, 0, 62, 0, 3, 0, 74, 0, 0, 0, 73, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 76, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 77, 0, -0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 78, 0, 0, 0, 75, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 78, 0, 0, 0, 77, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 79, 0, 0, 0, 58, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, -0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 81, 0, 0, 0, 75, 0, 0, 0, 28, 0, 0, 0, 62, 0, 3, 0, 81, 0, 0, 0, 80, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 82, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 61, 0, -4, 0, 6, 0, 0, 0, 83, 0, 0, 0, 82, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 84, 0, 0, 0, 75, 0, 0, 0, 34, 0, 0, 0, 62, 0, 3, 0, 84, 0, 0, 0, 83, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 86, 0, 0, 0, 75, 0, 0, 0, 62, 0, -3, 0, 85, 0, 0, 0, 86, 0, 0, 0, 57, 0, 5, 0, 8, 0, 0, 0, 87, 0, 0, 0, 13, 0, 0, 0, 85, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 88, 0, 0, 0, 85, 0, 0, 0, 62, 0, 3, 0, 75, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 15, 0, -0, 0, 89, 0, 0, 0, 75, 0, 0, 0, 59, 0, 0, 0, 62, 0, 3, 0, 89, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 93, 0, 0, 0, 75, 0, 0, 0, 59, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 65, 0, -5, 0, 15, 0, 0, 0, 95, 0, 0, 0, 92, 0, 0, 0, 28, 0, 0, 0, 62, 0, 3, 0, 95, 0, 0, 0, 94, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 98, 0, 0, 0, 92, 0, 0, 0, 28, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 99, 0, 0, 0, 98, 0, -0, 0, 62, 0, 3, 0, 97, 0, 0, 0, 99, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 59, 0, -4, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 33, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 41, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 17, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 61, 0, -4, 0, 21, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 86, 0, 5, 0, 25, 0, 0, 0, 26, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 30, 0, 0, 0, 12, 0, 0, 0, 28, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 31, 0, -0, 0, 30, 0, 0, 0, 87, 0, 5, 0, 8, 0, 0, 0, 32, 0, 0, 0, 26, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 16, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 36, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 61, 0, 4, 0, 6, 0, -0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 180, 0, 5, 0, 39, 0, 0, 0, 40, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 247, 0, 3, 0, 43, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 40, 0, 0, 0, 42, 0, 0, 0, 45, 0, 0, 0, 248, 0, 2, 0, 42, 0, -0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 44, 0, 0, 0, 16, 0, 0, 0, 62, 0, 3, 0, 41, 0, 0, 0, 44, 0, 0, 0, 249, 0, 2, 0, 43, 0, 0, 0, 248, 0, 2, 0, 45, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 46, 0, 0, 0, 16, 0, 0, 0, 79, 0, -9, 0, 8, 0, 0, 0, 47, 0, 0, 0, 46, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 41, 0, 0, 0, 47, 0, 0, 0, 249, 0, 2, 0, 43, 0, 0, 0, 248, 0, 2, 0, 43, 0, 0, 0, 61, 0, -4, 0, 8, 0, 0, 0, 48, 0, 0, 0, 41, 0, 0, 0, 62, 0, 3, 0, 33, 0, 0, 0, 48, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 49, 0, 0, 0, 33, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 51, 0, 0, 0, 12, 0, 0, 0, 50, 0, 0, 0, 61, 0, -4, 0, 8, 0, 0, 0, 52, 0, 0, 0, 51, 0, 0, 0, 133, 0, 5, 0, 8, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 52, 0, 0, 0, 254, 0, 2, 0, 53, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, +93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, +24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 187, 195, 141, 246, 160, 52, 251, 46, 218, 4, 81, 95, 110, 153, 4, 148, 0, 76, 30, 0, 0, 3, +2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, +0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, +0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, +0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, +0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, +0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, +48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, +114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, +116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, +0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, +0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, +54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, +0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, +82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, +108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, +50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, +1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, +108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 81, 1, 0, 0, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, +97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, +0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, +111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, +97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, +1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, +1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, +0, 6, 0, 184, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, +0, 5, 0, 185, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, +0, 6, 0, 186, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, +0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, +116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 192, +1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, +1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, +117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, +0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, +0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, +83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, +1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, +0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, +0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, +111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, +1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, +0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, +83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, +71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, +1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, +0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, +0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, +0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, +1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, +0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, +95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, +0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, +1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, +0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, +0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, +0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, +0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, +0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, +0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, +0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, +0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, +0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, +0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, +0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, +0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, +0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, +0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 42, +0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, +0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, +0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, +0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, +1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, +0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, +1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, +0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, +1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, +1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, +1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, +1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, +0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, +0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, +0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, +0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, +0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, +0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, +0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, +0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, +1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, +1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, +1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, +0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, +0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, +1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, +1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, +0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, +1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, +1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, +1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, +1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, +0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, +1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, +1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, +1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, +1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, +1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, +1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, +1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, +1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, +1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, +1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 187, 195, 141, 246, 160, 52, 251, 46, 218, 4, 81, 95, 110, 153, 4, 148, 0, 76, 30, 0, 0, 3, 2, 35, 7, 0, 4, +1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, +0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0, 219, 1, +0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, 0, 3, 0, 189, 1, +0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, +7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, +7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, +0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, 0, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, +0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 132, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, 82, 71, 66, 97, 0, +0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, +54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, 1, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 81, 1, 0, 0, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, +0, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, +5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, +0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, +0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, +116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, +114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, +0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, +0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, +0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, +5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, +115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, +116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, +116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, +95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, +0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, +7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, +85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, +0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, +0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, +6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, +0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, +114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 228, 1, +0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, +108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, +0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, +6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, +4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, +7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, +90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, +0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, +0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, +0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, +0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, +4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, +0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, +0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, +0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, +4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, +0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, +0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, +0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, +0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, +0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, +0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, +0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, +4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, +0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, +0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, +0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, +0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, +0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, +0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, +0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, +0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, +0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, +0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, +0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, +0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, +0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, +0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, +2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, +0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, +0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, +0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, +0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, +4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, +0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, +0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, +0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, +3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, +5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, +0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, +3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, +3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, +0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, +0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, +5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, +0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, +0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } + #endif diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index b0c551c784..5d87b5ca02 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -1,149 +1,288 @@ -#if STRIDE_GRAPHICS_API_VULKAN -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\..\..\..\..\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net472\Stride.Core.Assets.CompilerApp.exe --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Stride.Graphics +#if STRIDE_GRAPHICS_API_VULKAN + +namespace Stride.Graphics { internal partial class UIEffect { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -7, 192, 254, 239, 0, 0, 9, 0, 0, 0, 0, 0, 22, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 44, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 148, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 34, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 85, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, -255, 127, 255, 255, 255, 127, 127, 0, 0, 28, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 29, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 0, 23, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 3, 0, 0, -0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 13, 84, 101, 120, 116, 117, 114, 101, -48, 95, 105, 100, 49, 52, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 12, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 9, 78, 111, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, -8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 26, 75, 115, 151, 65, 210, 132, 26, 166, 252, 249, 19, 59, 219, 173, 91, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 172, 190, 61, 77, 68, 160, 70, 238, 222, 135, 17, 118, 190, 233, 199, 84, 16, 83, 104, 97, 100, 101, -114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 163, 165, 191, 129, 133, 242, 163, 216, 153, 114, 41, 63, 128, 100, 48, 211, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 230, 218, 239, 13, 217, 10, 85, 249, 84, 156, 111, 93, 41, 30, 97, 165, 12, 67, 111, 108, 111, 114, 85, 116, 105, -108, 105, 116, 121, 1, 124, 200, 88, 161, 33, 56, 76, 239, 97, 45, 238, 84, 91, 130, 62, 69, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 254, 15, 19, 108, 23, 38, 247, 78, 102, 115, 175, 155, 49, 213, 166, 178, 0, 52, 15, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, -80, 79, 83, 73, 84, 73, 79, 78, 1, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 2, 0, 0, 0, 0, 9, 84, 69, 88, 67, 79, 79, 82, 68, 48, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 1, 0, 0, 0, 9, 78, 111, 83, 97, 109, -112, 108, 101, 114, 40, 0, 0, 0, 0, 220, 14, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 133, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, -0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 0, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 49, 0, 0, 0, 54, 0, 0, 0, 60, 0, 0, 0, 64, 0, 0, 0, 110, 0, 0, 0, 115, 0, 0, 0, 119, 0, 0, 0, 123, 0, 0, -0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 7, 0, 11, 0, 0, 0, 84, 111, 76, 105, 110, 101, 97, 114, 95, 105, 100, 51, 40, 118, 102, 52, 59, 0, 0, 0, 5, 0, 4, 0, 10, 0, 0, -0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 15, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 5, 0, 43, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 7, 0, 43, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, -110, 95, 105, 100, 55, 51, 0, 0, 0, 6, 0, 6, 0, 43, 0, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 43, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, -0, 43, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, 0, 45, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 7, 0, 49, 0, 0, 0, 97, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, -90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 54, 0, 0, 0, 97, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 60, 0, 0, 0, 97, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 5, 0, 64, 0, 0, 0, 97, 95, 80, 79, 83, 73, 84, -73, 79, 78, 48, 0, 5, 0, 5, 0, 67, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 67, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 55, 51, 0, 0, 0, 6, 0, 6, 0, 67, 0, 0, 0, 1, 0, 0, -0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 67, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 67, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, -53, 0, 0, 0, 0, 6, 0, 8, 0, 67, 0, 0, 0, 4, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 5, 0, 4, 0, 69, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 86, 0, 0, 0, 112, 97, 114, -97, 109, 0, 0, 0, 5, 0, 5, 0, 91, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 8, 0, 91, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 91, 0, 0, -0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 91, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 91, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, -95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, 0, 93, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 6, 0, 108, 0, 0, 0, 103, 108, 95, 80, 101, 114, 86, 101, 114, 116, 101, 120, 0, 0, 0, 0, 6, 0, 6, 0, 108, 0, 0, 0, 0, 0, 0, -0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 7, 0, 108, 0, 0, 0, 1, 0, 0, 0, 103, 108, 95, 80, 111, 105, 110, 116, 83, 105, 122, 101, 0, 0, 0, 0, 6, 0, 7, 0, 108, 0, 0, 0, 2, 0, 0, 0, 103, 108, 95, 67, 108, 105, 112, 68, 105, 115, 116, -97, 110, 99, 101, 0, 6, 0, 7, 0, 108, 0, 0, 0, 3, 0, 0, 0, 103, 108, 95, 67, 117, 108, 108, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 3, 0, 110, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 115, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, -0, 5, 0, 5, 0, 119, 0, 0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 7, 0, 123, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 132, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, -101, 114, 0, 0, 0, 71, 0, 4, 0, 49, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 71, 0, 4, 0, 54, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 60, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 64, 0, 0, 0, 30, 0, 0, -0, 0, 0, 0, 0, 72, 0, 5, 0, 108, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 108, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 72, 0, 5, 0, 108, 0, 0, 0, 2, 0, 0, 0, 11, 0, 0, 0, 3, 0, 0, -0, 72, 0, 5, 0, 108, 0, 0, 0, 3, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 71, 0, 3, 0, 108, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 115, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 119, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, -0, 71, 0, 4, 0, 123, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 132, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 132, 0, 0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, -0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 8, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 33, 0, 4, 0, 9, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, -0, 23, 0, 4, 0, 13, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 14, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 21, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 6, 0, 0, 0, 23, 0, 0, 0, 196, 162, 46, -63, 43, 0, 4, 0, 6, 0, 0, 0, 27, 0, 0, 0, 194, 44, 77, 60, 21, 0, 4, 0, 31, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 31, 0, 0, 0, 32, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, -0, 23, 0, 4, 0, 42, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 30, 0, 6, 0, 43, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 42, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, 0, 44, 0, 0, 0, 7, 0, 0, 0, 43, 0, 0, 0, 21, 0, 4, 0, 46, 0, 0, -0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 46, 0, 0, 0, 47, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 48, 0, 0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 48, 0, 0, 0, 49, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 46, 0, 0, -0, 52, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 53, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 59, 0, 4, 0, 53, 0, 0, 0, 54, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 56, 0, 0, 0, 7, 0, 0, 0, 42, 0, 0, 0, 43, 0, 4, 0, 46, 0, 0, -0, 58, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 59, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 59, 0, 0, 0, 60, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 46, 0, 0, 0, 63, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 59, 0, 0, -0, 64, 0, 0, 0, 1, 0, 0, 0, 30, 0, 7, 0, 67, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 42, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 7, 0, 0, 0, 67, 0, 0, 0, 43, 0, 4, 0, 46, 0, 0, 0, 82, 0, 0, -0, 4, 0, 0, 0, 30, 0, 6, 0, 91, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 42, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, 0, 92, 0, 0, 0, 7, 0, 0, 0, 91, 0, 0, 0, 43, 0, 4, 0, 31, 0, 0, 0, 106, 0, 0, 0, 1, 0, 0, 0, 28, 0, 4, -0, 107, 0, 0, 0, 6, 0, 0, 0, 106, 0, 0, 0, 30, 0, 6, 0, 108, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 107, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 109, 0, 0, 0, 3, 0, 0, 0, 108, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 110, 0, 0, -0, 3, 0, 0, 0, 32, 0, 4, 0, 113, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 113, 0, 0, 0, 115, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 118, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 59, 0, 4, 0, 118, 0, 0, 0, 119, 0, 0, -0, 3, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 3, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 123, 0, 0, 0, 3, 0, 0, 0, 26, 0, 2, 0, 130, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 59, 0, 4, -0, 131, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 44, 0, 0, 0, 45, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 68, 0, 0, -0, 69, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 8, 0, 0, 0, 86, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 92, 0, 0, 0, 93, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 50, 0, 0, 0, 49, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, -0, 51, 0, 0, 0, 45, 0, 0, 0, 47, 0, 0, 0, 62, 0, 3, 0, 51, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 55, 0, 0, 0, 54, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 57, 0, 0, 0, 45, 0, 0, 0, 52, 0, 0, 0, 62, 0, 3, -0, 57, 0, 0, 0, 55, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 61, 0, 0, 0, 60, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 62, 0, 0, 0, 45, 0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 62, 0, 0, 0, 61, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, -0, 65, 0, 0, 0, 64, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 66, 0, 0, 0, 45, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 66, 0, 0, 0, 65, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 70, 0, 0, 0, 45, 0, 0, 0, 63, 0, 0, 0, 61, 0, 4, -0, 7, 0, 0, 0, 71, 0, 0, 0, 70, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 72, 0, 0, 0, 69, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 72, 0, 0, 0, 71, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 73, 0, 0, 0, 45, 0, 0, 0, 58, 0, 0, -0, 61, 0, 4, 0, 7, 0, 0, 0, 74, 0, 0, 0, 73, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 75, 0, 0, 0, 69, 0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 75, 0, 0, 0, 74, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 76, 0, 0, 0, 45, 0, 0, -0, 52, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 77, 0, 0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 78, 0, 0, 0, 69, 0, 0, 0, 52, 0, 0, 0, 62, 0, 3, 0, 78, 0, 0, 0, 77, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 79, 0, 0, -0, 45, 0, 0, 0, 47, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 81, 0, 0, 0, 69, 0, 0, 0, 47, 0, 0, 0, 62, 0, 3, 0, 81, 0, 0, 0, 80, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, -0, 83, 0, 0, 0, 69, 0, 0, 0, 63, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 84, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 85, 0, 0, 0, 69, 0, 0, 0, 82, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 84, 0, 0, 0, 65, 0, 5, -0, 8, 0, 0, 0, 87, 0, 0, 0, 69, 0, 0, 0, 58, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 88, 0, 0, 0, 87, 0, 0, 0, 62, 0, 3, 0, 86, 0, 0, 0, 88, 0, 0, 0, 57, 0, 5, 0, 7, 0, 0, 0, 89, 0, 0, 0, 11, 0, 0, 0, 86, 0, 0, -0, 65, 0, 5, 0, 8, 0, 0, 0, 90, 0, 0, 0, 69, 0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 90, 0, 0, 0, 89, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 94, 0, 0, 0, 69, 0, 0, 0, 82, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 95, 0, 0, -0, 94, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 96, 0, 0, 0, 93, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 96, 0, 0, 0, 95, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 97, 0, 0, 0, 69, 0, 0, 0, 58, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, -0, 98, 0, 0, 0, 97, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 99, 0, 0, 0, 93, 0, 0, 0, 58, 0, 0, 0, 62, 0, 3, 0, 99, 0, 0, 0, 98, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 100, 0, 0, 0, 69, 0, 0, 0, 52, 0, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 101, 0, 0, 0, 100, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 102, 0, 0, 0, 93, 0, 0, 0, 52, 0, 0, 0, 62, 0, 3, 0, 102, 0, 0, 0, 101, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 103, 0, 0, 0, 69, 0, 0, 0, 47, 0, 0, -0, 61, 0, 4, 0, 6, 0, 0, 0, 104, 0, 0, 0, 103, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 105, 0, 0, 0, 93, 0, 0, 0, 47, 0, 0, 0, 62, 0, 3, 0, 105, 0, 0, 0, 104, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 111, 0, 0, 0, 93, 0, 0, -0, 63, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 112, 0, 0, 0, 111, 0, 0, 0, 65, 0, 5, 0, 113, 0, 0, 0, 114, 0, 0, 0, 110, 0, 0, 0, 63, 0, 0, 0, 62, 0, 3, 0, 114, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 8, 0, 0, 0, 116, 0, 0, -0, 93, 0, 0, 0, 58, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 117, 0, 0, 0, 116, 0, 0, 0, 62, 0, 3, 0, 115, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 56, 0, 0, 0, 120, 0, 0, 0, 93, 0, 0, 0, 52, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 121, 0, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 119, 0, 0, 0, 121, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 124, 0, 0, 0, 93, 0, 0, 0, 47, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 125, 0, 0, 0, 124, 0, 0, 0, 62, 0, 3, 0, 123, 0, 0, -0, 125, 0, 0, 0, 65, 0, 6, 0, 122, 0, 0, 0, 126, 0, 0, 0, 110, 0, 0, 0, 63, 0, 0, 0, 106, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 127, 0, 0, 0, 126, 0, 0, 0, 127, 0, 4, 0, 6, 0, 0, 0, 128, 0, 0, 0, 127, 0, 0, 0, 65, 0, 6, -0, 122, 0, 0, 0, 129, 0, 0, 0, 110, 0, 0, 0, 63, 0, 0, 0, 106, 0, 0, 0, 62, 0, 3, 0, 129, 0, 0, 0, 128, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 7, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 55, 0, 3, -0, 8, 0, 0, 0, 10, 0, 0, 0, 248, 0, 2, 0, 12, 0, 0, 0, 59, 0, 4, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 16, 0, 0, 0, 10, 0, 0, 0, 79, 0, 8, 0, 13, 0, 0, 0, 17, 0, 0, 0, 16, 0, 0, -0, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 15, 0, 0, 0, 17, 0, 0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 18, 0, 0, 0, 15, 0, 0, 0, 61, 0, 4, 0, 13, 0, 0, 0, 19, 0, 0, 0, 15, 0, 0, 0, 61, 0, 4, -0, 13, 0, 0, 0, 20, 0, 0, 0, 15, 0, 0, 0, 142, 0, 5, 0, 13, 0, 0, 0, 22, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 80, 0, 6, 0, 13, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 23, 0, 0, 0, 129, 0, 5, 0, 13, 0, 0, -0, 25, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 133, 0, 5, 0, 13, 0, 0, 0, 26, 0, 0, 0, 19, 0, 0, 0, 25, 0, 0, 0, 80, 0, 6, 0, 13, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 27, 0, 0, 0, 27, 0, 0, 0, 129, 0, 5, 0, 13, 0, 0, -0, 29, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 133, 0, 5, 0, 13, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 65, 0, 5, 0, 33, 0, 0, 0, 34, 0, 0, 0, 10, 0, 0, 0, 32, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 35, 0, 0, -0, 34, 0, 0, 0, 81, 0, 5, 0, 6, 0, 0, 0, 36, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 6, 0, 0, 0, 37, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 6, 0, 0, 0, 38, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 80, 0, 7, 0, 7, 0, 0, 0, 39, 0, 0, 0, 36, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 35, 0, 0, 0, 254, 0, 2, 0, 39, 0, 0, 0, 56, 0, 1, 0, 0, 5, 0, 0, 0, 1, 88, 73, 87, 188, 34, 20, 168, 55, 190, 124, 230, 223, 190, 1, 43, 64, 0, -154, 11, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 2, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 20, 0, 0, 0, 9, 78, 111, 83, 97, -109, 112, 108, 101, 114, 40, 0, 0, 0, 0, 80, 11, 0, 0, 3, 2, 35, 7, 0, 0, 1, 0, 7, 0, 8, 0, 101, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 1, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, -0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 10, 0, 4, 0, 0, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 61, 0, 0, 0, 65, 0, 0, 0, 69, 0, 0, 0, 72, 0, 0, 0, 97, 0, 0, 0, 16, 0, 3, 0, 4, 0, 0, 0, 7, 0, -0, 0, 3, 0, 3, 0, 2, 0, 0, 0, 194, 1, 0, 0, 5, 0, 4, 0, 4, 0, 0, 0, 109, 97, 105, 110, 0, 0, 0, 0, 5, 0, 5, 0, 9, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 1, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 6, 0, 6, 0, 9, 0, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, -0, 0, 6, 0, 7, 0, 9, 0, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 14, 0, 13, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 95, 105, 100, 50, 40, 115, 116, 114, 117, 99, 116, 45, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 45, 118, 102, 50, 45, 102, 49, 45, 118, 102, 52, 45, 118, 102, 52, 49, 59, 0, 0, 5, 0, 4, 0, 12, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 6, 0, 16, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, -6, 0, 19, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 95, 105, 100, 49, 52, 0, 0, 0, 5, 0, 6, 0, 23, 0, 0, 0, 83, 97, 109, 112, 108, 101, 114, 95, 105, 100, 52, 50, 0, 0, 0, 0, 5, 0, 6, 0, 33, 0, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, -108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 56, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 8, 0, 56, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 95, 105, 100, 48, 0, 6, 0, 6, 0, 56, 0, -0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 95, 105, 100, 55, 52, 0, 0, 6, 0, 7, 0, 56, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 95, 105, 100, 54, 50, 0, 0, 0, 6, 0, 7, 0, 56, 0, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, -101, 95, 105, 100, 55, 53, 0, 0, 0, 0, 5, 0, 5, 0, 58, 0, 0, 0, 95, 48, 105, 110, 112, 117, 116, 95, 48, 0, 0, 0, 5, 0, 7, 0, 61, 0, 0, 0, 118, 95, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 48, 0, 0, 0, 0, 5, 0, 5, 0, 65, 0, -0, 0, 118, 95, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 5, 0, 5, 0, 69, 0, 0, 0, 118, 95, 67, 79, 76, 79, 82, 48, 0, 0, 0, 0, 5, 0, 6, 0, 72, 0, 0, 0, 103, 108, 95, 70, 114, 97, 103, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 4, 0, 75, 0, -0, 0, 115, 116, 114, 101, 97, 109, 115, 0, 5, 0, 4, 0, 85, 0, 0, 0, 112, 97, 114, 97, 109, 0, 0, 0, 5, 0, 5, 0, 90, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 92, 0, 0, 0, 95, 48, 111, 117, 116, 112, 117, 116, 95, 48, 0, 0, 5, 0, 10, 0, 97, 0, 0, 0, 111, 117, 116, 95, 103, 108, 95, 102, 114, 97, 103, 100, 97, 116, 97, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 95, 105, 100, 50, 0, 5, 0, 5, 0, 100, 0, 0, 0, 78, 111, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 71, 0, 4, 0, 19, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 19, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 23, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 23, 0, 0, 0, 33, 0, 0, 0, 20, 0, 0, 0, 71, 0, 4, 0, 61, 0, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 65, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 69, 0, -0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 72, 0, 0, 0, 11, 0, 0, 0, 15, 0, 0, 0, 71, 0, 4, 0, 97, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 0, -0, 0, 33, 0, 0, 0, 40, 0, 0, 0, 19, 0, 2, 0, 2, 0, 0, 0, 33, 0, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 6, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 23, 0, 4, 0, 8, 0, -0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 9, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 10, 0, 0, 0, 7, 0, 0, 0, 9, 0, 0, 0, 33, 0, 4, 0, 11, 0, 0, 0, 8, 0, 0, 0, 10, 0, -0, 0, 32, 0, 4, 0, 15, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 25, 0, 9, 0, 17, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 0, 0, -0, 0, 17, 0, 0, 0, 59, 0, 4, 0, 18, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 26, 0, 2, 0, 21, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 59, 0, 4, 0, 22, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 27, 0, -3, 0, 25, 0, 0, 0, 17, 0, 0, 0, 21, 0, 4, 0, 27, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 29, 0, 0, 0, 7, 0, 0, 0, 7, 0, 0, 0, 43, 0, 4, 0, 27, 0, -0, 0, 34, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 43, 0, 4, 0, 6, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 20, 0, 2, 0, 39, 0, 0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 50, 0, 0, 0, 2, 0, -0, 0, 30, 0, 6, 0, 56, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 32, 0, 4, 0, 57, 0, 0, 0, 7, 0, 0, 0, 56, 0, 0, 0, 43, 0, 4, 0, 27, 0, 0, 0, 59, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 60, 0, -0, 0, 1, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 60, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 64, 0, 0, 0, 65, 0, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 68, 0, -0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 68, 0, 0, 0, 69, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 68, 0, 0, 0, 72, 0, 0, 0, 1, 0, 0, 0, 30, 0, 3, 0, 90, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 91, 0, 0, 0, 7, 0, -0, 0, 90, 0, 0, 0, 32, 0, 4, 0, 96, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 59, 0, 4, 0, 96, 0, 0, 0, 97, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 22, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 54, 0, 5, 0, 2, 0, 0, 0, 4, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 248, 0, 2, 0, 5, 0, 0, 0, 59, 0, 4, 0, 57, 0, 0, 0, 58, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 75, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 10, 0, 0, 0, 85, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 91, 0, 0, 0, 92, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 62, 0, 0, 0, 61, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 63, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 62, 0, 3, 0, 63, 0, 0, 0, 62, 0, -0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 66, 0, 0, 0, 65, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 67, 0, 0, 0, 58, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 67, 0, 0, 0, 66, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 70, 0, 0, 0, 69, 0, -0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 71, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 62, 0, 3, 0, 71, 0, 0, 0, 70, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 73, 0, 0, 0, 72, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 74, 0, 0, 0, 58, 0, -0, 0, 28, 0, 0, 0, 62, 0, 3, 0, 74, 0, 0, 0, 73, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 76, 0, 0, 0, 58, 0, 0, 0, 34, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 77, 0, 0, 0, 76, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 78, 0, -0, 0, 75, 0, 0, 0, 50, 0, 0, 0, 62, 0, 3, 0, 78, 0, 0, 0, 77, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 79, 0, 0, 0, 58, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 80, 0, 0, 0, 79, 0, 0, 0, 65, 0, 5, 0, 29, 0, -0, 0, 81, 0, 0, 0, 75, 0, 0, 0, 28, 0, 0, 0, 62, 0, 3, 0, 81, 0, 0, 0, 80, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 82, 0, 0, 0, 58, 0, 0, 0, 59, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 83, 0, 0, 0, 82, 0, 0, 0, 65, 0, -5, 0, 35, 0, 0, 0, 84, 0, 0, 0, 75, 0, 0, 0, 34, 0, 0, 0, 62, 0, 3, 0, 84, 0, 0, 0, 83, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 86, 0, 0, 0, 75, 0, 0, 0, 62, 0, 3, 0, 85, 0, 0, 0, 86, 0, 0, 0, 57, 0, 5, 0, 8, 0, -0, 0, 87, 0, 0, 0, 13, 0, 0, 0, 85, 0, 0, 0, 61, 0, 4, 0, 9, 0, 0, 0, 88, 0, 0, 0, 85, 0, 0, 0, 62, 0, 3, 0, 75, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 89, 0, 0, 0, 75, 0, 0, 0, 59, 0, 0, 0, 62, 0, -3, 0, 89, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 93, 0, 0, 0, 75, 0, 0, 0, 59, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 95, 0, 0, 0, 92, 0, 0, 0, 28, 0, -0, 0, 62, 0, 3, 0, 95, 0, 0, 0, 94, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 98, 0, 0, 0, 92, 0, 0, 0, 28, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 99, 0, 0, 0, 98, 0, 0, 0, 62, 0, 3, 0, 97, 0, 0, 0, 99, 0, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 8, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 55, 0, 3, 0, 10, 0, 0, 0, 12, 0, 0, 0, 248, 0, 2, 0, 14, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 15, 0, 0, 0, 33, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 15, 0, 0, 0, 41, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 17, 0, 0, 0, 20, 0, 0, 0, 19, 0, 0, 0, 61, 0, 4, 0, 21, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 86, 0, -5, 0, 25, 0, 0, 0, 26, 0, 0, 0, 20, 0, 0, 0, 24, 0, 0, 0, 65, 0, 5, 0, 29, 0, 0, 0, 30, 0, 0, 0, 12, 0, 0, 0, 28, 0, 0, 0, 61, 0, 4, 0, 7, 0, 0, 0, 31, 0, 0, 0, 30, 0, 0, 0, 87, 0, 5, 0, 8, 0, 0, 0, 32, 0, -0, 0, 26, 0, 0, 0, 31, 0, 0, 0, 62, 0, 3, 0, 16, 0, 0, 0, 32, 0, 0, 0, 65, 0, 5, 0, 35, 0, 0, 0, 36, 0, 0, 0, 12, 0, 0, 0, 34, 0, 0, 0, 61, 0, 4, 0, 6, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 180, 0, 5, 0, 39, 0, -0, 0, 40, 0, 0, 0, 37, 0, 0, 0, 38, 0, 0, 0, 247, 0, 3, 0, 43, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 40, 0, 0, 0, 42, 0, 0, 0, 45, 0, 0, 0, 248, 0, 2, 0, 42, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 44, 0, 0, 0, 16, 0, -0, 0, 62, 0, 3, 0, 41, 0, 0, 0, 44, 0, 0, 0, 249, 0, 2, 0, 43, 0, 0, 0, 248, 0, 2, 0, 45, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 46, 0, 0, 0, 16, 0, 0, 0, 79, 0, 9, 0, 8, 0, 0, 0, 47, 0, 0, 0, 46, 0, 0, 0, 46, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 41, 0, 0, 0, 47, 0, 0, 0, 249, 0, 2, 0, 43, 0, 0, 0, 248, 0, 2, 0, 43, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 48, 0, 0, 0, 41, 0, 0, 0, 62, 0, -3, 0, 33, 0, 0, 0, 48, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 49, 0, 0, 0, 33, 0, 0, 0, 65, 0, 5, 0, 15, 0, 0, 0, 51, 0, 0, 0, 12, 0, 0, 0, 50, 0, 0, 0, 61, 0, 4, 0, 8, 0, 0, 0, 52, 0, 0, 0, 51, 0, 0, 0, 133, 0, -5, 0, 8, 0, 0, 0, 53, 0, 0, 0, 49, 0, 0, 0, 52, 0, 0, 0, 254, 0, 2, 0, 53, 0, 0, 0, 56, 0, 1, 0, +8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, +8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, +8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, +101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, +1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, +114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, +117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, +69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, +93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, +24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 183, 103, 133, 203, 32, 55, 146, 141, 231, 231, 212, 229, 165, 147, 143, 186, 0, 60, 30, 0, 0, 3, +2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, +0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, +0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, +0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, +0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, +0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, +48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, +114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, +116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, +0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, +0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, +54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, +0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, +82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, +108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, +50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, +1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, +108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 81, 1, 0, 0, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, +0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 107, +1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, +0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, +0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, 114, 95, 73, +110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, 0, 0, 0, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, 0, 0, 80, +83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, 0, 0, 0, +0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 186, +1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, +0, 0, 0, 5, 0, 11, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, +0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, +0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, +116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, +0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, +0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, +119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, +1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, +0, 0, 0, 5, 0, 11, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, +0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, +0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, +1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, +0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, +22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, +0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, +0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, +65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, +1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, +0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, +0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, +1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, +0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, +0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, +0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, +0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, +0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, +0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, +0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, +0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, +0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, +0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, +0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, +0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, +0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, +1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, +0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, +0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, +0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, +1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, +1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, +0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, +0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, +1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, +1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, +1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, +1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, +0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, +0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, +0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, +0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, +0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, +0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, +0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, +0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, +1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, +1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, +1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, +0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, +0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, +1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, +0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, +1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, +1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, +0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, +1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, +1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, +1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, +0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, +0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, +1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, +1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, +1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, +1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, +1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, +1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, +80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 183, 103, 133, 203, 32, 55, 146, 141, 231, 231, 212, 229, 165, 147, 143, 186, 0, 60, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, +2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, +0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, 0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, +116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, +11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, +0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, +7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 81, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, +83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, +60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, +0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, +0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, +0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, +0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, +102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, +95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, +0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, +0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, +0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, +0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, +0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, +95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, +6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, +101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, +69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, +0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, +0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, +5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, +4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, +79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, +0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, +0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, +0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, +5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, +0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, +4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, +0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, +0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, +0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, +0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, +0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, +0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, +0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, +0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, +4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, +4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, +0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, +0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, +0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, +0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, +0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, +0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, +0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, +0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, +0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, +0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, +0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, +5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, +2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, +0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, +0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, +0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, +0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, +0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, +0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, +0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, +5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, +0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, +0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, +4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, +2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, +0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, +5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, +3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, +0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, +0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, +0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, +0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, +0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, +0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, +5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } + #endif From 78ccde84d784fbcd67ccf9701c27fe4d9826fbdf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 01:25:34 +0900 Subject: [PATCH 0850/1182] SDSL: avoid duplicates when OpTypeFunctionSDSL are simplified into OpTypeFunction --- .../SDSL/ShaderMixer.cs | 62 ++++++++++++++++--- .../Spirv/Building/Builder.Class.cs | 4 ++ 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 304be95300..fc3848464c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -12,6 +12,7 @@ using Stride.Shaders.Spirv.Processing.Interfaces; using static Stride.Shaders.Spirv.Specification; using EntryPoint = Stride.Shaders.Core.EntryPoint; +using Stride.Core.UnsafeExtensions; namespace Stride.Shaders.Compilers.SDSL; @@ -923,6 +924,35 @@ private static void RemoveInstructionWhere(SpirvBuffer buffer, Func(); + var remapIds = new Dictionary(); + foreach (var i in temp) + { + // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) + if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) + { + Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; + for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) + parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; + + // Make sure to unify same types: they might have different OpTypeFunctionSDSL due to modifiers but end up having the same OpTypeFunction once modifiers info is removed + // If two duplicate OpTypeFunction exists, this causes SPIR-V validation errors + var functionTypeWithIds = new FunctionTypeWithIds(functionType.ReturnType, parameterTypes.ToArray()); + if (functionTypes.TryGetValue(functionTypeWithIds, out var functionTypeId)) + { + remapIds.Add(functionType.ResultId, functionTypeId); + SetOpNop(i.Data.Memory.Span); + } + else + { + temp.Replace(i.Index, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [.. parameterTypes])); + functionTypes.Add(functionTypeWithIds, functionType.ResultId); + } + } + } + SpirvBuilder.RemapIds(temp, 0, temp.Count, remapIds); + // Remove in a single pass (we do in-place without RemoveAt otherwise it would be up to O(n^2) complexity) RemoveInstructionWhere(temp, i => { @@ -975,7 +1005,7 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio } return false; }); - + var ids = new HashSet(); foreach (var i in temp) { @@ -984,15 +1014,6 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) temp.Replace(i.Index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); - // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) - if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) - { - Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; - for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) - parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; - temp.Replace(i.Index, new OpTypeFunction(functionType.ResultId, functionType.ReturnType, [..parameterTypes])); - } - // Collect IDs (except for OpName/OpDecorate/OpDecorateString metadata) if (i.Op != Op.OpName && i.Op != Op.OpDecorate && i.Op != Op.OpDecorateString) SpirvBuilder.CollectIds(i.Data, id => ids.Add(id)); @@ -1023,6 +1044,27 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio } } +public sealed partial record FunctionTypeWithIds(int ReturnType, int[] ParameterTypes) +{ + public bool Equals(FunctionTypeWithIds? other) + { + if (other is null) + return false; + return ReturnType == other.ReturnType && ParameterTypes.SequenceEqual(other.ParameterTypes); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + ReturnType.GetHashCode(); + foreach (var item in ParameterTypes) + { + hash = hash * 31 + item.GetHashCode(); + } + return hash; + } +} + public class CaptureLoadedShaders(IExternalShaderLoader inner) : IExternalShaderLoader { /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 90ae53e838..febd86e340 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -579,6 +579,8 @@ public static bool ContainIds(HashSet ids, OpData i) public static void RemapIds(SpirvBuffer buffer, int shaderStart, int shaderEnd, Dictionary idRemapping) { + if (idRemapping.Count == 0) + return; for (var index = shaderStart; index < buffer.Count; index++) { var i = buffer[index]; @@ -588,6 +590,8 @@ public static void RemapIds(SpirvBuffer buffer, int shaderStart, int shaderEnd, public static void RemapIds(Dictionary idRemapping, ref OpData i) { + if (idRemapping.Count == 0) + return; // Special case: remove OpName and such if (i.Op == Op.OpName || i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString || i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) From e340ddb9e31476b68c73702012d62a8464f31322 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 01:26:13 +0900 Subject: [PATCH 0851/1182] SDSL: fix sign() implementation --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index d4316f9169..b8484312ef 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -199,7 +199,8 @@ public override SpirvValue CompileSaturate(SpirvContext context, SpirvBuilder bu } public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) { - var instruction = functionType.ReturnType.GetElementType() switch + var sourceType = context.ReverseTypes[x.TypeId]; + var instruction = sourceType.GetElementType() switch { ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFSign(x.TypeId, context.Bound++, context.GetGLSL(), x.Id)), ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.UInt64 or Scalar.Int64 } => builder.InsertData(new GLSLSSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), From 0691a056957ec70ed5716177b483e76f68ee5887 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 02:40:03 +0900 Subject: [PATCH 0852/1182] SDSL: applied .editorconfig to new shader files --- .../Stride.Shaders.Compilers/Direct3D/DXC.cs | 10 +- .../Direct3D/DxilHash.cs | 156 +++---- .../Stride.Shaders.Compilers/Direct3D/FXC.cs | 4 +- .../Direct3D/Spv2DXIL.cs | 31 +- .../Stride.Shaders.Compilers/ICompiler.cs | 2 +- .../Stride.Shaders.Compilers/MainMethod.cs | 2 +- .../SDSL/EffectEvaluator.cs | 2 +- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 8 +- .../SDSL/ShaderMixer.CBuffers.cs | 30 +- .../SDSL/ShaderMixer.Decorations.cs | 4 +- .../SDSL/ShaderMixer.MixinNode.cs | 4 +- .../SDSL/ShaderMixer.Reflection.cs | 56 +-- .../SDSL/ShaderMixer.ShaderInfo.cs | 4 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 15 +- .../SDSL/ShaderMixer.cs | 48 +-- .../ShaderLoaderBase.cs | 2 +- .../ShaderSourceManager.cs | 2 +- .../Stride.Shaders.Compilers/SpirvOpt.cs | 2 +- .../SpirvTranslator.cs | 4 +- .../Examples.Effects.cs | 8 +- .../Stride.Shaders.Experiments/Examples.cs | 6 +- .../Stride.Shaders.Experiments/Program.cs | 2 +- .../IntrinsicGenerator.cs | 42 +- .../Intrinsics/IntrinAST.cs | 6 +- .../Intrinsics/Parser.cs | 26 +- .../VisitorGenerator.cs | 14 +- .../EffectCodeWriter.cs | 226 +++++----- .../EffectGenerator.cs | 8 +- .../Core/EntryPoints.cs | 2 +- .../Core/IntrinsicsParameters.cs | 253 +++++------ .../Core/Node.Visitors.cs | 2 +- .../Stride.Shaders.Parsers/Core/Symbol.cs | 2 +- .../Core/SymbolFrame.cs | 4 +- .../Core/SymbolTypes.Globals.cs | 20 +- .../Core/SymbolTypes.Visitors.cs | 2 +- .../Core/SymbolTypes.cs | 22 +- .../Stride.Shaders.Parsers/Parsing/ASTNode.cs | 4 +- .../Parsing/Analysis/CFG.cs | 2 +- .../Parsing/Analysis/IStreamChecker.cs | 2 +- .../Parsing/Analysis/SDIR.cs | 8 +- .../Parsing/Analysis/SymbolTable.cs | 6 +- .../Parsing/Analysis/TypeNameExtensions.cs | 4 +- .../Stride.Shaders.Parsers/Parsing/Grammar.cs | 6 +- .../Stride.Shaders.Parsers/Parsing/IParser.cs | 2 +- .../Parsing/ParseResult.cs | 16 +- .../PreProcessing/CMacros/CodeFrame.cs | 2 +- .../CMacros/CodeFrameSnippets.cs | 10 +- .../PreProcessing/CMacros/CodeProcessor.cs | 4 +- .../PreProcessing/CMacros/CommentPhase.cs | 4 +- .../PreProcessing/CommentProcessedCode.cs | 2 +- .../PreProcessing/MacroPreProcessor.cs | 2 +- .../PreProcessing/MemoryOwnerExtensions.cs | 2 +- .../PreProcessing/TextLinkExtensions.cs | 2 +- .../Parsing/SDFX/AST/Effect.Parameters.cs | 6 +- .../Parsing/SDFX/AST/Effect.cs | 10 +- .../Parsing/SDFX/Parsers/EffectFileParsers.cs | 4 +- .../Parsing/SDFX/Parsers/EffectParser.cs | 4 +- .../EffectStatementParsers.Conditional.cs | 4 +- .../Parsers/EffectStatementParsers.Flow.cs | 30 +- .../SDFX/Parsers/EffectStatementParsers.cs | 12 +- .../Parsing/SDFX/Parsers/ParamsParsers.cs | 2 +- .../Parsing/SDFX/ShaderWriter.cs | 36 +- .../SDSL/AST/BufferMethodsImplementations.cs | 2 +- .../Parsing/SDSL/AST/Expression.cs | 400 +++++++++--------- .../Parsing/SDSL/AST/IntrinsicCall.cs | 26 +- .../SDSL/AST/IntrinsicImplementations.cs | 58 +-- .../SDSL/AST/IntrinsicTemplateExpander.cs | 96 ++--- .../Parsing/SDSL/AST/Literals.cs | 32 +- .../Parsing/SDSL/AST/Shader.cs | 28 +- .../Parsing/SDSL/AST/ShaderAttributes.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 36 +- .../Parsing/SDSL/AST/ShaderElements.cs | 52 +-- .../Parsing/SDSL/AST/ShaderGenericsValues.cs | 4 +- .../Parsing/SDSL/AST/Statements.Control.cs | 4 +- .../Parsing/SDSL/AST/Statements.Flow.cs | 4 +- .../Parsing/SDSL/AST/Statements.cs | 10 +- .../SDSL/AST/TextureMethodsImplementations.cs | 14 +- .../SDSL/Parsers/Common/CommonParsers.cs | 70 +-- .../SDSL/Parsers/Common/OptionalParser.cs | 2 +- .../Parsing/SDSL/Parsers/Common/Spaces.cs | 2 +- .../DirectiveBinaryParsers.cs | 16 +- .../DirectiveExpressions/DirectiveParsers.cs | 18 +- .../DirectivePrimaryExpressionParsers.cs | 4 +- .../DirectiveUnaryParsers.Prefix.cs | 8 +- .../PrimaryExpressionParsers.cs | 10 +- .../ExpressionParsers/UnaryParsers.Prefix.cs | 8 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 10 +- .../Parsers/LiteralParsers/NumberParsers.cs | 2 +- .../SDSL/Parsers/LiteralParsers/Reserved.cs | 6 +- .../ShaderParsers/CompositionParsers.cs | 4 +- .../ShaderParsers/ShaderBufferParsers.cs | 4 +- .../ShaderParsers/ShaderClassParser.cs | 10 +- .../ShaderParsers/ShaderDataParsers.cs | 2 +- .../ShaderParsers/ShaderElementParsers.cs | 6 +- .../ShaderParsers/ShaderFileParsers.cs | 8 +- .../ShaderParsers/ShaderMethodParsers.cs | 12 +- .../Parsers/ShaderParsers/ShaderParameters.cs | 4 +- .../StatementParsers.Control.cs | 6 +- .../StatementParsers/StatementParsers.Flow.cs | 28 +- .../StatementParsers/StatementParsers.cs | 2 +- .../SDSL/Parsers/Terminals/Terminals.cs | 20 +- .../Stride.Shaders.Parsers/Parsing/SDSLERR.cs | 2 +- .../Parsing/SDSLParser.cs | 2 +- .../Parsing/Scanners/ErrorLocation.cs | 4 +- .../Parsing/Scanners/ScannableString.cs | 4 +- .../Parsing/Scanners/ScannerGeneric.cs | 2 +- .../Parsing/Scanners/TextLocation.cs | 6 +- .../Spirv/Building/Builder.Class.cs | 10 +- .../Spirv/Building/Builder.Expressions.cs | 60 +-- .../Spirv/Building/Builder.Flow.cs | 2 +- .../Spirv/Building/Builder.Functions.cs | 14 +- .../Spirv/Building/Builder.cs | 2 +- .../Spirv/Building/CompilerUnit.cs | 4 +- .../Spirv/Building/Context.Constants.cs | 8 +- .../Spirv/Building/Context.ExtractBuffers.cs | 8 +- .../Spirv/Building/Context.cs | 24 +- .../Spirv/Building/ExpressionExtensions.cs | 4 +- .../Spirv/Building/SpirvContext.Types.cs | 8 +- .../Spirv/Processing/BoundReducer.cs | 12 +- .../Spirv/Processing/CapabilitiesCompute.cs | 2 +- .../Spirv/Processing/CompressBuffer.cs | 2 +- .../Processing/FunctionVariableOrderer.cs | 2 +- .../Spirv/Processing/IOReplace.cs | 2 +- .../Spirv/Processing/IOVariableDecorator.cs | 2 +- .../Interfaces/Analysis/StreamAnalyzer.cs | 4 +- .../Interfaces/Generation/BuiltinProcessor.cs | 2 +- .../Generation/EntryPointWrapperGenerator.cs | 128 +++--- .../Interfaces/InterfaceProcessor.cs | 32 +- .../Transformation/StreamAccessPatcher.cs | 2 +- .../MemoryModelDuplicatesRemover.cs | 2 +- .../Spirv/Processing/MixinMerger.cs | 2 +- .../Spirv/Processing/PostProcessor.cs | 2 +- .../Spirv/Processing/SDSLOpRemover.cs | 2 +- .../Spirv/Processing/TypeDuplicatesRemover.cs | 4 +- .../Stride.Shaders.Parsers/Spirv/Tools/Dis.cs | 2 +- .../Spirv/Tools/Validator.cs | 2 +- .../Buffers/IMemoryInstruction.cs | 2 +- .../Buffers/OpData.cs | 4 +- .../Buffers/OpDataIndex.cs | 2 +- .../Buffers/SpirvBuffer.cs | 4 +- .../Buffers/SpirvBytecode.cs | 4 +- .../ISpirvElement.cs | 2 +- .../IWrapperInstruction.cs | 2 +- .../Information/InstructionInfo.cs | 8 +- .../Information/LogicalOperand.cs | 2 +- .../Information/LogicalOperandArray.cs | 6 +- .../Literals/EnumerantParameters.cs | 2 +- .../Literals/IdMemorySemantics.cs | 2 +- .../Literals/IdRef.cs | 4 +- .../Literals/IdResult.cs | 4 +- .../Literals/IdResultType.cs | 4 +- .../Literals/IdScope.cs | 4 +- .../Literals/LiteralArray.cs | 4 +- .../Literals/LiteralFloat.cs | 2 +- .../Literals/LiteralString.cs | 7 +- .../Literals/LiteralValue.cs | 2 +- .../Literals/PairIdRefIdRef.cs | 6 +- .../Literals/PairIdRefLiteralInteger.cs | 6 +- .../Literals/PairLiteralIntegerIdRef.cs | 6 +- .../Literals/ParameterizedFlag.cs | 2 +- .../Literals/SpvOp.cs | 2 +- .../MemoryInstruction.cs | 2 +- .../OperandQuantifier.cs | 4 +- .../Parsing/OpDataEnumerator.cs | 2 +- .../Parsing/OperandEnumerator.cs | 4 +- .../Parsing/SpirvHeader.cs | 2 +- .../Parsing/SpirvReader.cs | 2 +- .../Stride.Shaders.Spirv.Core/SpirvValue.cs | 2 +- .../Stride.Shaders.Spirv.Core/SpvLiteral.cs | 2 +- .../WordsExtensions.cs | 4 +- .../Stride.Shaders.Spirv.Generators/Data.cs | 2 +- .../EquatableArray.cs | 4 +- .../EquatableDictionary.cs | 14 +- .../EquatableList.cs | 4 +- .../SPVGenerator.Buffers.cs | 2 +- .../SPVGenerator.EnumerantParams.cs | 2 +- .../SPVGenerator.Extensions.cs | 4 +- .../SPVGenerator.Helpers.Naming.cs | 2 +- .../SPVGenerator.Helpers.Preprocessing.cs | 2 +- .../SPVGenerator.Info.cs | 2 +- .../SPVGenerator.Instructions.cs | 2 +- .../SPVGenerator.SDSLOp.cs | 4 +- .../SPVGenerator.Specification.cs | 2 +- .../SPVGenerator.cs | 2 +- .../FrameRenderer.D3D11.cs | 18 +- .../Stride.Shaders.Tests/RenderingTests.cs | 16 +- .../Stride.Shaders.Tests/ShaderLoader.cs | 4 +- .../Compiler/EffectCompilerCache.cs | 8 +- .../shaders/Stride.Shaders/EffectBytecode.cs | 4 +- .../Stride.Shaders/ShaderArraySource.cs | 2 +- .../shaders/Stride.Shaders/ShaderBytecode.cs | 2 +- .../shaders/Stride.Shaders/ShaderClassCode.cs | 2 +- .../Stride.Shaders/ShaderClassSource.cs | 2 +- .../Stride.Shaders/ShaderClassString.cs | 2 +- .../Stride.Shaders/ShaderMixinContext.cs | 4 +- 195 files changed, 1426 insertions(+), 1420 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs index 69faa30adc..a16e51ef61 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs @@ -42,7 +42,7 @@ float4 PSMain(PSInput input) : SV_TARGET static Guid compilerArgsGuid = Guid.Parse("3e56ae82-224d-470f-a1a1-fe3016ee9f9d"); static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); static readonly DXC dxc = DXC.GetApi(); - + public bool Compile(string code, out byte[] compiled) { throw new NotImplementedException(); @@ -52,10 +52,10 @@ public bool Compile(string code, out byte[] compiled) // var compiler = dxc.CreateInstance(ref compilerGuid); // var utils = dxc.CreateInstance(ref utilsGuid); // var args = dxc.CreateInstance(ref compilerArgsGuid); - + // // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); // IDxcBlobEncoding* sourceBlob = null; - + // SilkMarshal.ThrowHResult( // utils.Get().CreateBlobFromPinned((void*)SilkMarshal.StringToPtr(Code), (uint)Code.Length, 1200, ref sourceBlob) // ); @@ -66,10 +66,10 @@ public bool Compile(string code, out byte[] compiled) // SilkMarshal.ThrowHResult( // compiler.Get().Compile(&buff, parms, (uint)parms.Length, null, ref resultGuid,(void**)result) // ); - + // // Console.WriteLine((nint)result); // } // compiled = Memory.Empty; // return true; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DxilHash.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DxilHash.cs index 6ef84337fe..06d488bc69 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DxilHash.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DxilHash.cs @@ -63,7 +63,7 @@ public static unsafe void ComputeHashRetail(byte* pData, uint byteCount, byte* p uint leftOver = byteCount & 0x3f; uint padAmount; bool bTwoRowsPadding = false; - if( leftOver < 56 ) + if (leftOver < 56) { padAmount = 56 - leftOver; } @@ -73,41 +73,41 @@ public static unsafe void ComputeHashRetail(byte* pData, uint byteCount, byte* p bTwoRowsPadding = true; } uint padAmountPlusSize = padAmount + 8; - var state = stackalloc uint[] {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; + var state = stackalloc uint[] { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; uint N = (byteCount + padAmountPlusSize) >> 6; uint offset = 0; - uint NextEndState = bTwoRowsPadding ? N-2 : N-1; + uint NextEndState = bTwoRowsPadding ? N - 2 : N - 1; byte* pCurrData = pData; var x = stackalloc uint[16]; - for (uint i = 0; i < N; i++, offset+=64, pCurrData+=64) + for (uint i = 0; i < N; i++, offset += 64, pCurrData += 64) { uint* pX; - if( i == NextEndState ) + if (i == NextEndState) { - if( !bTwoRowsPadding && i == N-1 ) + if (!bTwoRowsPadding && i == N - 1) { uint remainder = byteCount - offset; x[0] = byteCount << 3; - + Debug.Assert(byteCount - offset <= byteCount); // check for underflow Debug.Assert(pCurrData + remainder == pData + byteCount); Buffer.MemoryCopy(pCurrData, (byte*)x + 4, remainder, remainder); // could copy nothing Buffer.MemoryCopy(padding, (byte*)x + 4 + remainder, padAmount, padAmount); x[15] = 1 | (byteCount << 1); } - else if( bTwoRowsPadding ) + else if (bTwoRowsPadding) { - if( i == N-2 ) + if (i == N - 2) { uint remainder = byteCount - offset; Debug.Assert(byteCount - offset <= byteCount); // check for underflow Debug.Assert(pCurrData + remainder == pData + byteCount); Buffer.MemoryCopy(pCurrData, x, remainder, remainder); - Buffer.MemoryCopy(padding, (byte*)x + remainder, padAmount-56, padAmount - 56); - NextEndState = N-1; + Buffer.MemoryCopy(padding, (byte*)x + remainder, padAmount - 56, padAmount - 56); + NextEndState = N - 1; } - else if( i == N-1 ) + else if (i == N - 1) { x[0] = byteCount << 3; Buffer.MemoryCopy(padding + padAmount - 56, (byte*)x + 4, 56, 56); @@ -127,78 +127,78 @@ public static unsafe void ComputeHashRetail(byte* pData, uint byteCount, byte* p uint c = state[2]; uint d = state[3]; - /* Round 1 */ - FF(ref a, b, c, d, pX[ 0], S11, 0xd76aa478 ); /* 1 */ - FF(ref d, a, b, c, pX[ 1], S12, 0xe8c7b756 ); /* 2 */ - FF(ref c, d, a, b, pX[ 2], S13, 0x242070db ); /* 3 */ - FF(ref b, c, d, a, pX[ 3], S14, 0xc1bdceee ); /* 4 */ - FF(ref a, b, c, d, pX[ 4], S11, 0xf57c0faf ); /* 5 */ - FF(ref d, a, b, c, pX[ 5], S12, 0x4787c62a ); /* 6 */ - FF(ref c, d, a, b, pX[ 6], S13, 0xa8304613 ); /* 7 */ - FF(ref b, c, d, a, pX[ 7], S14, 0xfd469501 ); /* 8 */ - FF(ref a, b, c, d, pX[ 8], S11, 0x698098d8 ); /* 9 */ - FF(ref d, a, b, c, pX[ 9], S12, 0x8b44f7af ); /* 10 */ - FF(ref c, d, a, b, pX[10], S13, 0xffff5bb1 ); /* 11 */ - FF(ref b, c, d, a, pX[11], S14, 0x895cd7be ); /* 12 */ - FF(ref a, b, c, d, pX[12], S11, 0x6b901122 ); /* 13 */ - FF(ref d, a, b, c, pX[13], S12, 0xfd987193 ); /* 14 */ - FF(ref c, d, a, b, pX[14], S13, 0xa679438e ); /* 15 */ - FF(ref b, c, d, a, pX[15], S14, 0x49b40821 ); /* 16 */ + /* Round 1 */ + FF(ref a, b, c, d, pX[0], S11, 0xd76aa478); /* 1 */ + FF(ref d, a, b, c, pX[1], S12, 0xe8c7b756); /* 2 */ + FF(ref c, d, a, b, pX[2], S13, 0x242070db); /* 3 */ + FF(ref b, c, d, a, pX[3], S14, 0xc1bdceee); /* 4 */ + FF(ref a, b, c, d, pX[4], S11, 0xf57c0faf); /* 5 */ + FF(ref d, a, b, c, pX[5], S12, 0x4787c62a); /* 6 */ + FF(ref c, d, a, b, pX[6], S13, 0xa8304613); /* 7 */ + FF(ref b, c, d, a, pX[7], S14, 0xfd469501); /* 8 */ + FF(ref a, b, c, d, pX[8], S11, 0x698098d8); /* 9 */ + FF(ref d, a, b, c, pX[9], S12, 0x8b44f7af); /* 10 */ + FF(ref c, d, a, b, pX[10], S13, 0xffff5bb1); /* 11 */ + FF(ref b, c, d, a, pX[11], S14, 0x895cd7be); /* 12 */ + FF(ref a, b, c, d, pX[12], S11, 0x6b901122); /* 13 */ + FF(ref d, a, b, c, pX[13], S12, 0xfd987193); /* 14 */ + FF(ref c, d, a, b, pX[14], S13, 0xa679438e); /* 15 */ + FF(ref b, c, d, a, pX[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ - GG(ref a, b, c, d, pX[ 1], S21, 0xf61e2562 ); /* 17 */ - GG(ref d, a, b, c, pX[ 6], S22, 0xc040b340 ); /* 18 */ - GG(ref c, d, a, b, pX[11], S23, 0x265e5a51 ); /* 19 */ - GG(ref b, c, d, a, pX[ 0], S24, 0xe9b6c7aa ); /* 20 */ - GG(ref a, b, c, d, pX[ 5], S21, 0xd62f105d ); /* 21 */ - GG(ref d, a, b, c, pX[10], S22, 0x2441453 ); /* 22 */ - GG(ref c, d, a, b, pX[15], S23, 0xd8a1e681 ); /* 23 */ - GG(ref b, c, d, a, pX[ 4], S24, 0xe7d3fbc8 ); /* 24 */ - GG(ref a, b, c, d, pX[ 9], S21, 0x21e1cde6 ); /* 25 */ - GG(ref d, a, b, c, pX[14], S22, 0xc33707d6 ); /* 26 */ - GG(ref c, d, a, b, pX[ 3], S23, 0xf4d50d87 ); /* 27 */ - GG(ref b, c, d, a, pX[ 8], S24, 0x455a14ed ); /* 28 */ - GG(ref a, b, c, d, pX[13], S21, 0xa9e3e905 ); /* 29 */ - GG(ref d, a, b, c, pX[ 2], S22, 0xfcefa3f8 ); /* 30 */ - GG(ref c, d, a, b, pX[ 7], S23, 0x676f02d9 ); /* 31 */ - GG(ref b, c, d, a, pX[12], S24, 0x8d2a4c8a ); /* 32 */ + GG(ref a, b, c, d, pX[1], S21, 0xf61e2562); /* 17 */ + GG(ref d, a, b, c, pX[6], S22, 0xc040b340); /* 18 */ + GG(ref c, d, a, b, pX[11], S23, 0x265e5a51); /* 19 */ + GG(ref b, c, d, a, pX[0], S24, 0xe9b6c7aa); /* 20 */ + GG(ref a, b, c, d, pX[5], S21, 0xd62f105d); /* 21 */ + GG(ref d, a, b, c, pX[10], S22, 0x2441453); /* 22 */ + GG(ref c, d, a, b, pX[15], S23, 0xd8a1e681); /* 23 */ + GG(ref b, c, d, a, pX[4], S24, 0xe7d3fbc8); /* 24 */ + GG(ref a, b, c, d, pX[9], S21, 0x21e1cde6); /* 25 */ + GG(ref d, a, b, c, pX[14], S22, 0xc33707d6); /* 26 */ + GG(ref c, d, a, b, pX[3], S23, 0xf4d50d87); /* 27 */ + GG(ref b, c, d, a, pX[8], S24, 0x455a14ed); /* 28 */ + GG(ref a, b, c, d, pX[13], S21, 0xa9e3e905); /* 29 */ + GG(ref d, a, b, c, pX[2], S22, 0xfcefa3f8); /* 30 */ + GG(ref c, d, a, b, pX[7], S23, 0x676f02d9); /* 31 */ + GG(ref b, c, d, a, pX[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ - HH(ref a, b, c, d, pX[ 5], S31, 0xfffa3942 ); /* 33 */ - HH(ref d, a, b, c, pX[ 8], S32, 0x8771f681 ); /* 34 */ - HH(ref c, d, a, b, pX[11], S33, 0x6d9d6122 ); /* 35 */ - HH(ref b, c, d, a, pX[14], S34, 0xfde5380c ); /* 36 */ - HH(ref a, b, c, d, pX[ 1], S31, 0xa4beea44 ); /* 37 */ - HH(ref d, a, b, c, pX[ 4], S32, 0x4bdecfa9 ); /* 38 */ - HH(ref c, d, a, b, pX[ 7], S33, 0xf6bb4b60 ); /* 39 */ - HH(ref b, c, d, a, pX[10], S34, 0xbebfbc70 ); /* 40 */ - HH(ref a, b, c, d, pX[13], S31, 0x289b7ec6 ); /* 41 */ - HH(ref d, a, b, c, pX[ 0], S32, 0xeaa127fa ); /* 42 */ - HH(ref c, d, a, b, pX[ 3], S33, 0xd4ef3085 ); /* 43 */ - HH(ref b, c, d, a, pX[ 6], S34, 0x4881d05 ); /* 44 */ - HH(ref a, b, c, d, pX[ 9], S31, 0xd9d4d039 ); /* 45 */ - HH(ref d, a, b, c, pX[12], S32, 0xe6db99e5 ); /* 46 */ - HH(ref c, d, a, b, pX[15], S33, 0x1fa27cf8 ); /* 47 */ - HH(ref b, c, d, a, pX[ 2], S34, 0xc4ac5665 ); /* 48 */ + HH(ref a, b, c, d, pX[5], S31, 0xfffa3942); /* 33 */ + HH(ref d, a, b, c, pX[8], S32, 0x8771f681); /* 34 */ + HH(ref c, d, a, b, pX[11], S33, 0x6d9d6122); /* 35 */ + HH(ref b, c, d, a, pX[14], S34, 0xfde5380c); /* 36 */ + HH(ref a, b, c, d, pX[1], S31, 0xa4beea44); /* 37 */ + HH(ref d, a, b, c, pX[4], S32, 0x4bdecfa9); /* 38 */ + HH(ref c, d, a, b, pX[7], S33, 0xf6bb4b60); /* 39 */ + HH(ref b, c, d, a, pX[10], S34, 0xbebfbc70); /* 40 */ + HH(ref a, b, c, d, pX[13], S31, 0x289b7ec6); /* 41 */ + HH(ref d, a, b, c, pX[0], S32, 0xeaa127fa); /* 42 */ + HH(ref c, d, a, b, pX[3], S33, 0xd4ef3085); /* 43 */ + HH(ref b, c, d, a, pX[6], S34, 0x4881d05); /* 44 */ + HH(ref a, b, c, d, pX[9], S31, 0xd9d4d039); /* 45 */ + HH(ref d, a, b, c, pX[12], S32, 0xe6db99e5); /* 46 */ + HH(ref c, d, a, b, pX[15], S33, 0x1fa27cf8); /* 47 */ + HH(ref b, c, d, a, pX[2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ - II(ref a, b, c, d, pX[ 0], S41, 0xf4292244 ); /* 49 */ - II(ref d, a, b, c, pX[ 7], S42, 0x432aff97 ); /* 50 */ - II(ref c, d, a, b, pX[14], S43, 0xab9423a7 ); /* 51 */ - II(ref b, c, d, a, pX[ 5], S44, 0xfc93a039 ); /* 52 */ - II(ref a, b, c, d, pX[12], S41, 0x655b59c3 ); /* 53 */ - II(ref d, a, b, c, pX[ 3], S42, 0x8f0ccc92 ); /* 54 */ - II(ref c, d, a, b, pX[10], S43, 0xffeff47d ); /* 55 */ - II(ref b, c, d, a, pX[ 1], S44, 0x85845dd1 ); /* 56 */ - II(ref a, b, c, d, pX[ 8], S41, 0x6fa87e4f ); /* 57 */ - II(ref d, a, b, c, pX[15], S42, 0xfe2ce6e0 ); /* 58 */ - II(ref c, d, a, b, pX[ 6], S43, 0xa3014314 ); /* 59 */ - II(ref b, c, d, a, pX[13], S44, 0x4e0811a1 ); /* 60 */ - II(ref a, b, c, d, pX[ 4], S41, 0xf7537e82 ); /* 61 */ - II(ref d, a, b, c, pX[11], S42, 0xbd3af235 ); /* 62 */ - II(ref c, d, a, b, pX[ 2], S43, 0x2ad7d2bb ); /* 63 */ - II(ref b, c, d, a, pX[ 9], S44, 0xeb86d391 ); /* 64 */ - + II(ref a, b, c, d, pX[0], S41, 0xf4292244); /* 49 */ + II(ref d, a, b, c, pX[7], S42, 0x432aff97); /* 50 */ + II(ref c, d, a, b, pX[14], S43, 0xab9423a7); /* 51 */ + II(ref b, c, d, a, pX[5], S44, 0xfc93a039); /* 52 */ + II(ref a, b, c, d, pX[12], S41, 0x655b59c3); /* 53 */ + II(ref d, a, b, c, pX[3], S42, 0x8f0ccc92); /* 54 */ + II(ref c, d, a, b, pX[10], S43, 0xffeff47d); /* 55 */ + II(ref b, c, d, a, pX[1], S44, 0x85845dd1); /* 56 */ + II(ref a, b, c, d, pX[8], S41, 0x6fa87e4f); /* 57 */ + II(ref d, a, b, c, pX[15], S42, 0xfe2ce6e0); /* 58 */ + II(ref c, d, a, b, pX[6], S43, 0xa3014314); /* 59 */ + II(ref b, c, d, a, pX[13], S44, 0x4e0811a1); /* 60 */ + II(ref a, b, c, d, pX[4], S41, 0xf7537e82); /* 61 */ + II(ref d, a, b, c, pX[11], S42, 0xbd3af235); /* 62 */ + II(ref c, d, a, b, pX[2], S43, 0x2ad7d2bb); /* 63 */ + II(ref b, c, d, a, pX[9], S44, 0xeb86d391); /* 64 */ + state[0] += a; state[1] += b; state[2] += c; diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs index eeec9260a1..1d3ba4d3a9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs @@ -10,9 +10,9 @@ namespace Stride.Shaders.Compilers.Direct3D; public record struct FXCompiler() : ICompiler { static D3DCompiler d3d = D3DCompiler.GetApi(); - + public bool Compile(string code, out byte[] compiled) { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index f5160e7c94..90f3ae6332 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -4,6 +4,7 @@ [assembly: DisableRuntimeMarshalling] namespace Stride.Shaders.Compilers.Direct3D; + public enum ShaderStage { DXIL_SPIRV_SHADER_NONE = -1, @@ -109,7 +110,8 @@ public unsafe struct DXILSpirvLogger public nint log; } -public unsafe struct DXILSpirvObject { +public unsafe struct DXILSpirvObject +{ // Some sysval or other type of data is accessed which needs to be piped // from the app/API implementation into the shader via a buffer public bool metadata_requires_runtime_data; @@ -120,7 +122,7 @@ public unsafe struct DXILSpirvObject { // complex. public bool metadata_needs_draw_sysvals; - public void *buffer; + public void* buffer; public nint size; } public unsafe struct Specialization @@ -130,17 +132,18 @@ public unsafe struct Specialization bool defined_on_module; } -public enum ValidatorVersion { - NO_DXIL_VALIDATION, - DXIL_VALIDATOR_1_0 = 0x10000, - DXIL_VALIDATOR_1_1, - DXIL_VALIDATOR_1_2, - DXIL_VALIDATOR_1_3, - DXIL_VALIDATOR_1_4, - DXIL_VALIDATOR_1_5, - DXIL_VALIDATOR_1_6, - DXIL_VALIDATOR_1_7, - DXIL_VALIDATOR_1_8, +public enum ValidatorVersion +{ + NO_DXIL_VALIDATION, + DXIL_VALIDATOR_1_0 = 0x10000, + DXIL_VALIDATOR_1_1, + DXIL_VALIDATOR_1_2, + DXIL_VALIDATOR_1_3, + DXIL_VALIDATOR_1_4, + DXIL_VALIDATOR_1_5, + DXIL_VALIDATOR_1_6, + DXIL_VALIDATOR_1_7, + DXIL_VALIDATOR_1_8, }; public static partial class Spv2DXIL @@ -168,4 +171,4 @@ out DXILSpirvObject out_dxil [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] public static partial ulong spirv_to_dxil_get_version(); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs b/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs index b5cc9710ba..e81f80f7d5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs @@ -4,4 +4,4 @@ namespace Stride.Shaders.Compilers; public interface ICompiler { bool Compile(string code, out byte[] compiled); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/MainMethod.cs b/sources/shaders/Stride.Shaders.Compilers/MainMethod.cs index 1ccc34ea78..46287ddaa2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/MainMethod.cs +++ b/sources/shaders/Stride.Shaders.Compilers/MainMethod.cs @@ -7,4 +7,4 @@ public enum CompilerShaderStage Hull, Domain, Compute -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index a4d8e45873..d506f2e705 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -162,7 +162,7 @@ public void MergeComposition(ShaderMixinSource mixinTree, string compositionName { if (!mixinTree.Compositions.TryGetValue(compositionName, out var composition)) mixinTree.Compositions[compositionName] = composition = compositionToAdd is ShaderArraySource ? new ShaderArraySource() : new ShaderMixinSource(); - + if (compositionToAdd is ShaderArraySource compositionArrayToAdd) { var compositionArray = (ShaderArraySource)composition; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 277cc0356c..365f3e88dd 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -24,7 +24,7 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan x.Declarations).Concat(sf.RootDeclarations); @@ -36,7 +36,7 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan(); var removedIds = new HashSet(); foreach (var cbuffersEntry in cbuffersByNames) @@ -270,7 +270,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData var mergedCbufferPtrStructId = context.GetOrRegister(mergedCbufferPtrStruct); ProcessDecorations(cbuffersSpan, mergedCbufferStruct, true); - + // Remap member ids foreach (var i in buffer) { @@ -341,7 +341,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData EffectTypeDescription ConvertStructType(SpirvContext context, StructType s, SpirvBuilder.AlignmentRules alignmentRules) { EmitStructDecorations(context, s, alignmentRules, out int size, out var offsets); - + var members = new EffectTypeMemberDescription[s.Members.Count]; for (int i = 0; i < s.Members.Count; ++i) { @@ -354,7 +354,7 @@ EffectTypeDescription ConvertStructType(SpirvContext context, StructType s, Spir } return new EffectTypeDescription { Class = EffectParameterClass.Struct, RowCount = 1, ColumnCount = 1, Name = s.Name, Members = members, ElementSize = size }; } - + EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { EmitArrayStrideDecorations(context, a, typeModifier, alignmentRules, out var arrayStride); @@ -362,7 +362,7 @@ EffectTypeDescription ConvertArrayType(SpirvContext context, ArrayType a, TypeMo var elementType = ConvertType(context, a.BaseType, typeModifier, alignmentRules); return elementType with { Elements = a.Size }; } - + EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, TypeModifier typeModifier, SpirvBuilder.AlignmentRules alignmentRules) { return symbolType switch @@ -408,7 +408,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon var memberInfos = new EffectValueDescription[cb.Members.Count]; if (!cbufferMemberMetadata.TryGetValue(cbuffer.VariableId, out var cbufferMetadata)) throw new InvalidOperationException($"Could not find cbuffer member link info for {context.Names[cbuffer.VariableId]}; it should have been generated during {nameof(MergeCBuffers)}"); - + for (var index = 0; index < cb.Members.Count; index++) { // Properly compute size and offset according to DirectX rules diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs index 0c396d7575..bbf938345f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -54,7 +54,7 @@ private void EmitArrayStrideDecorations(SpirvContext context, ArrayType a, TypeM SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, }; context.Add(new OpDecorate(typeId, Specification.Decoration.ArrayStride, [arrayStride])); - + decoratedArrays[typeId] = (alignmentRules, arrayStride); } @@ -86,4 +86,4 @@ private void EmitStructDecorations(SpirvContext context, StructType s, SpirvBuil decoratedStructs[structId] = (alignmentRules, offset, offsets); size = offset; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 98af94391e..0fd926e217 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -42,7 +42,7 @@ private partial class MixinNode(MixinNode? stage, string? compositionPath) public Dictionary ShadersByName { get; } = new(); public Dictionary<(string MethodName, FunctionType FunctionType), int> MethodGroupsByName { get; } = new(); public Dictionary MethodGroups { get; } = new(); - + public Dictionary Compositions { get; } = new(); public Dictionary CompositionArrays { get; } = new(); @@ -77,4 +77,4 @@ class MethodGroup public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index a3f735f6dd..bfafac79a6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -12,7 +12,7 @@ public partial class ShaderMixer { private record struct VariableMetadata(string? Link = null, string? ResourceGroup = null, string? LogicalGroup = null, bool Color = false); private record struct CBufferMemberMetadata(string? Link = null, string? LogicalGroup = null, bool Color = false); - + private Dictionary variableMetadata = new(); // Note: cbuffer might share same struct, which is why we store this info per variable instead of per struct (as per OpMemberDecorate was doing) private Dictionary cbufferMemberMetadata = new(); @@ -46,7 +46,7 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) } } else if (i.Op == Specification.Op.OpDecorateString && (OpDecorateString)i is - { Decoration: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL } decorateString) + { Decoration: Specification.Decoration.LinkSDSL or Specification.Decoration.ResourceGroupSDSL or Specification.Decoration.LogicalGroupSDSL } decorateString) { ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(variableDecorationMetadata, decorateString.Target, out _); switch (decorateString.Decoration) @@ -65,7 +65,7 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) } } else if (i.Op == Specification.Op.OpMemberDecorate && (OpMemberDecorate)i is - { Decoration: Specification.Decoration.ColorSDSL } memberDecorate) + { Decoration: Specification.Decoration.ColorSDSL } memberDecorate) { ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(structDecorationMetadata, (memberDecorate.StructureType, memberDecorate.Member), out _); switch (memberDecorate.Decoration) @@ -78,7 +78,7 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) } } else if (i.Op == Specification.Op.OpMemberDecorateString && (OpMemberDecorateString)i is - { Decoration: Specification.Decoration.LinkSDSL } memberDecorateString) + { Decoration: Specification.Decoration.LinkSDSL } memberDecorateString) { ref var metadata = ref CollectionsMarshal.GetValueRefOrAddDefault(structDecorationMetadata, (memberDecorateString.StructType, memberDecorateString.Member), out _); switch (memberDecorateString.Decoration) @@ -122,7 +122,7 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) metadata.Link = ComposeLinkName(metadata.Link, compositionPath); variableMetadata[variableInstruction.ResultId] = metadata; - + if (variableType is ConstantBufferSymbol cb) { var constantBufferStructId = context.Types[cb]; @@ -169,7 +169,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont : shader.ShaderName; } else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is - { Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer } variable) + { Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer } variable) { // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore var type = context.ReverseTypes[variable.ResultType]; @@ -210,7 +210,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon { Span slotCounts = stackalloc int[options.ResourcesRegisterSeparate ? 4 : 1]; slotCounts.Clear(); - + // If areResourcesSharingSlots is true, every slot type will point to same value ref var srvSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 0 : 0]; ref var samplerSlot = ref slotCounts[options.ResourcesRegisterSeparate ? 1 : 0]; @@ -224,7 +224,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon if ((i.Op == Specification.Op.OpDecorate || i.Op == Specification.Op.OpDecorateString) && (OpDecorate)i is { - Decoration : + Decoration: Specification.Decoration.SamplerStateFilter or Specification.Decoration.SamplerStateAddressU or Specification.Decoration.SamplerStateAddressV @@ -235,7 +235,7 @@ or Specification.Decoration.SamplerStateComparisonFunc or Specification.Decoration.SamplerStateMinLOD or Specification.Decoration.SamplerStateMaxLOD, DecorationParameters: { } p - + } decorate) { ref var samplerState = @@ -257,11 +257,11 @@ or Specification.Decoration.SamplerStateMinLOD samplerState.AddressW = (Graphics.TextureAddressMode)p.Span[0]; break; case Specification.Decoration.SamplerStateMipLODBias: - { - using var n = new LiteralValue(p.Span); - samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); - break; - } + { + using var n = new LiteralValue(p.Span); + samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); + break; + } case Specification.Decoration.SamplerStateMaxAnisotropy: samplerState.MaxAnisotropy = p.Span[0]; break; @@ -269,17 +269,17 @@ or Specification.Decoration.SamplerStateMinLOD samplerState.CompareFunction = (Graphics.CompareFunction)p.Span[0]; break; case Specification.Decoration.SamplerStateMinLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MinMipLevel = float.Parse(n.Value); - break; - } + { + using var n = new LiteralValue(p.Span); + samplerState.MinMipLevel = float.Parse(n.Value); + break; + } case Specification.Decoration.SamplerStateMaxLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MaxMipLevel = float.Parse(n.Value); - break; - } + { + using var n = new LiteralValue(p.Span); + samplerState.MaxMipLevel = float.Parse(n.Value); + break; + } } } } @@ -299,16 +299,16 @@ or Specification.Decoration.SamplerStateMinLOD if (IsResourceType(variableType)) { var name = context.Names[variable.ResultId]; - + variableMetadata.TryGetValue(variable.ResultId, out var linkInfo); var linkName = variableType switch { // TODO: Special case, Stride EffectCompiler.CleanupReflection() expect a different format here (let's fix that later in Stride) // Anyway, since buffer is merged, KeyName with form ShaderName.VariableName doesn't make sense as it doesn't belong to a specific shader anymore - ConstantBufferSymbol cb => name, + ConstantBufferSymbol cb => name, _ => linkInfo.Link ?? throw new InvalidOperationException($"Missing Link info for variable {name}"), }; - + var effectResourceBinding = new EffectResourceBindingDescription { KeyInfo = new EffectParameterKeyInfo { KeyName = linkName }, @@ -412,4 +412,4 @@ or Specification.Decoration.SamplerStateMinLOD } } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index c4b1aaf36c..64d31a367a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -25,7 +25,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio /// The for the same shader at the top-level (for all the stage members, if any). /// public ShaderInfo? Stage { get; set; } - + public LoadedShaderSymbol Symbol { get; set; } /// @@ -134,4 +134,4 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin } } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index fe39709557..0bbb768d48 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Compilers.SDSL; + using static Stride.Shaders.Spirv.Specification; public partial class ShaderMixer @@ -56,7 +57,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, macros, mixinList, ResolveStep.Mix); } - + ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot); return result; @@ -65,15 +66,15 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null) { int shaderIndex = 0; - + var addToRootRecursive = addToRoot; if (addToRootRecursive == null) { addToRootRecursive = shaderName => { var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; - - + + // Make sure it's not already added yet (either standard or stage only) if (!result.Mixins.Contains(shaderName) && !result!.Mixins.Contains(shaderNameStageOnly)) { @@ -99,7 +100,7 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con for (; shaderIndex < mixinList.Count; shaderIndex++) { var shaderName = mixinList[shaderIndex]; - + // Note: this should only happen due to addToRootRecursive readding some mixin earlier if (result.Mixins.Contains(shaderName)) continue; @@ -141,7 +142,7 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, addToRootRecursive)); - compositions[variableName] = [..variableCompositions]; + compositions[variableName] = [.. variableCompositions]; } else { @@ -160,7 +161,7 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con // If there are any stage variables, add class to root if (hasStage) addToRoot?.Invoke(shaderName); - + // Note: make sure to add only *after* compositions EvaluateInheritanceAndCompositions recursive call is done (a composition might add a "stage" inheritance with root!.Mixins.Add() // and this should be done before the composition mixin is added. // For example, a composition might import a struct, so if we import and mix the composition mixin before the "stage" one defining the struct, the struct is not defined before the composition using it. diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index fc3848464c..08470157c1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -23,9 +23,9 @@ public partial class ShaderMixer(IExternalShaderLoader shaderLoader) /// /// For D3D11/12: t, b and s registers are separate (and should be kept as low as possible so we number them from 0 in each category). public record struct Options(bool ResourcesRegisterSeparate); - + public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - + public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) { // Create new buffer for the merged result @@ -58,7 +58,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span ShaderClass.ProcessNameAndTypes(context); var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); - + // Add optional capabilities foreach (var i in context) { @@ -83,7 +83,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span CodeInserted = (int index, int count) => AdjustIndicesAfterAppendInstructions(rootMixin, index, count) }; (entryPoints, globalContext.Reflection.InputAttributes) = interfaceProcessor.Process(table, temp, context); - + // Process Link (add CompositionPath, generate missing ones, etc.) ProcessLinks(context, temp); @@ -92,7 +92,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span // force cbuffer to be epxlicit? (and not need "static" anymore for mixin nodes member, which is weird) // It's a breaking change and will require some changes to Stride shaders (esp. in post effects) GenerateDefaultCBuffer(rootMixin, globalContext, context, temp); - + // Merge cbuffers and rgroups MergeCBuffers(globalContext, context, temp); ComputeCBufferReflection(globalContext, context, temp); @@ -105,7 +105,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span ProcessReflection(globalContext, context, temp, options); SimplifyNotSupportedConstantsInShader(context, temp); - + foreach (var inst in context) temp.Add(inst.Data); @@ -144,7 +144,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); - + BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); // Compositions (recursive) @@ -222,7 +222,7 @@ private static string ComposeLinkName(string linkName, string? compositionPath = linkName += $".{compositionPath}"; return linkName; } - + // Append CompositionPath to "Link" for any non-stage variable // Also force-emit the missing "Link" decorations @@ -505,11 +505,11 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && - (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) + (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) { var functionName = context.Names[function.ResultId]; var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; - + // Add symbol for each method in current type (equivalent to implicit this pointer) var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId, OwnerType: currentShader.Symbol); table.CurrentFrame.Add(functionName, symbol); @@ -548,7 +548,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, var removedIds = new HashSet(); while (temp[index].Op != Op.OpFunctionEnd) { - if (temp[index].Data.IdResult is {} idResult) + if (temp[index].Data.IdResult is { } idResult) removedIds.Add(idResult); SetOpNop(temp[index++].Data.Memory.Span); } @@ -626,17 +626,17 @@ private static void ExpandForeach(MixinGlobalContext globalContext, SpirvContext foreachBufferCopy.Add(i2); } } - + // Clean OpName used by removed instructions (only for IdResult) var removedIds = new HashSet(); foreach (var i in foreachBuffer) if (i.IdResult is { } idResult) removedIds.Add(idResult); context.RemoveNameAndDecorations(removedIds); - + // Insert new code buffer.InsertRange(index, foreachBufferCopy.AsSpan()); - + // Note: mixinNode is not added to rootMixin hierarchy yet // Moreover, we are the last mixin (or one of our child is) // So we need (and it's safe) to call this on mixinNode rather than root node @@ -654,13 +654,13 @@ private static void AdjustIndicesAfterAppendInstructions(MixinNode rootMixin, in // Check bounds: we can't add before or at start of first mixin if (insertIndex <= rootMixin.StartInstruction) throw new ArgumentOutOfRangeException(nameof(insertIndex)); - + // Nothing to shift if (insertCount == 0) return; AdjustIndicesAfterAppendInstructionsInner(rootMixin, insertIndex, insertCount); - + static void AdjustIndicesAfterAppendInstructionsInner(MixinNode mixinNode, int insertIndex, int insertCount) { if (mixinNode.StartInstruction > insertIndex) @@ -882,7 +882,7 @@ public static void OffsetIds(OpData inst, int offset) } } } - + private void SimplifyNotSupportedConstantsInShader(SpirvContext context, SpirvBuffer temp) { foreach (var i in context) @@ -917,7 +917,7 @@ private static void RemoveInstructionWhere(SpirvBuffer buffer, Func { - if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) + if (i.Op == Op.OpName && (OpName)i is { } nameInstruction) { if (!ids.Contains(nameInstruction.Target)) return true; } - if (i.Op == Op.OpDecorate && (OpDecorate)i is {} decorate) + if (i.Op == Op.OpDecorate && (OpDecorate)i is { } decorate) { if (!ids.Contains(decorate.Target)) return true; } - if (i.Op == Op.OpDecorate && (OpDecorateString)i is {} decorateString) + if (i.Op == Op.OpDecorate && (OpDecorateString)i is { } decorateString) { if (!ids.Contains(decorateString.Target)) return true; @@ -1074,11 +1074,11 @@ public class CaptureLoadedShaders(IExternalShaderLoader inner) : IExternalShader public IShaderCache Cache => inner.Cache; public HashSourceCollection Sources { get; } = new(); - + public bool Exists(string name) => inner.Exists(name); - + public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) - => inner.LoadExternalFileContent(name, out filename, out code, out hash); + => inner.LoadExternalFileContent(name, out filename, out code, out hash); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) { diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 1627c4cf96..7b9bc139b1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -80,4 +80,4 @@ protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, return sdslc.Compile(text, hash, macros, out buffer); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs index c810017dc3..3bae2ce50f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs @@ -230,7 +230,7 @@ public bool IsClassExists(string typeName) { return FindFilePath(typeName) != null; } - + public string FindFilePath(string type) { lock (locker) diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs index 8e538a91fb..7679abf23e 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs @@ -89,4 +89,4 @@ public static void Optimize(ReadOnlyMemory words) } } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs index 9d23eac64f..745cb5749a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -34,7 +34,7 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); var result = new List<(string RealName, string TranslatedName, ExecutionModel ExecutionModel)>(); - EntryPoint * entry_points = null; + EntryPoint* entry_points = null; nuint num_entry_points = 0; bool entryPointFound = false; cross.CompilerGetEntryPoints(compiler, &entry_points, &num_entry_points); @@ -95,7 +95,7 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam // HLSL: remove type_ prefix from cbuffer (they get names from struct instead of cbuffer variable itself) if (backend == Backend.Hlsl) { - + ReflectedResource* resourcesList; nuint resourcesCount; cross.ResourcesGetResourceListForType(resources, ResourceType.UniformBuffer, &resourcesList, &resourcesCount); diff --git a/sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs b/sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs index 646d9498c6..80c172fd96 100644 --- a/sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs +++ b/sources/shaders/Stride.Shaders.Experiments/Examples.Effects.cs @@ -29,7 +29,7 @@ public static void CompileBasicEffect() var effectGenerator = new EffectCodeWriter(); effectGenerator.Run(parsed.AST); var code = effectGenerator.Text; - + Console.WriteLine(code); } @@ -47,11 +47,11 @@ public override bool LoadExternalFileContent(string name, out string filename, o var fileData = File.ReadAllBytes(filename); hash = ObjectId.FromBytes(fileData); - + using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); code = reader.ReadToEnd(); - + return true; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Experiments/Examples.cs b/sources/shaders/Stride.Shaders.Experiments/Examples.cs index 63b20628a5..26f9015d55 100644 --- a/sources/shaders/Stride.Shaders.Experiments/Examples.cs +++ b/sources/shaders/Stride.Shaders.Experiments/Examples.cs @@ -221,10 +221,10 @@ protected override bool ExternalFileExists(string name) public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { filename = $"{basePath}/{name}.sdsl"; - + var fileData = File.ReadAllBytes(filename); hash = ObjectId.FromBytes(fileData); - + // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); code = reader.ReadToEnd(); @@ -232,4 +232,4 @@ public override bool LoadExternalFileContent(string name, out string filename, o return true; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Experiments/Program.cs b/sources/shaders/Stride.Shaders.Experiments/Program.cs index 4fea8b337f..3f840c0a81 100644 --- a/sources/shaders/Stride.Shaders.Experiments/Program.cs +++ b/sources/shaders/Stride.Shaders.Experiments/Program.cs @@ -8,4 +8,4 @@ using Stride.Shaders; -Examples.CompileBasicEffect(); \ No newline at end of file +Examples.CompileBasicEffect(); diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index 75535e4d0c..8f341c5b73 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -43,7 +43,7 @@ namespace Stride.Shaders.Core; public static partial class IntrinsicsDefinitions { """); - + if (namespaces.Items.Count == 0) builder.AppendLine("// No intrinsics parsed"); @@ -74,7 +74,7 @@ public static partial class IntrinsicsDefinitions builder.AppendLine("), "); // Parameters builder.AppendLine("["); - + foreach (var param in overload.Parameters.Items.Where(p => p.Name.Name != "...")) { builder.Append("new("); @@ -85,12 +85,12 @@ public static partial class IntrinsicsDefinitions { Qualifier: string q } => builder.Append($"FromString(\"{q}\"), null, "), _ => builder.Append("null, null, ") }; - + // Type builder.Append($"new(\"{param.TypeInfo.Typename.Name}\""); _ = param.TypeInfo.Typename switch { - {Size : {Size1 : string, Size2 : string}} => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\", \"{param.TypeInfo.Typename.Size.Size2}\")"), + { Size: { Size1: string, Size2: string } } => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\", \"{param.TypeInfo.Typename.Size.Size2}\")"), { Size.Size1: string } => builder.Append($", new(\"{param.TypeInfo.Typename.Size.Size1}\")"), _ => builder.Append(", null") }; @@ -130,13 +130,13 @@ static string GenerateArguments(List parameters, bool option { return string.Concat(parameters.Where(p => p.Name.Name != "...").Select((p, i) => $", {(optional ? $"{p.Name.Name}:" : "")}new SpirvValue(compiledParams[{startIndex + i}], context.GetOrRegister(functionType.ParameterTypes[{startIndex + i}].Type))")); } - + static string CapitalizeFirstLetter(string s) => char.ToUpper(s[0]) + s[1..]; static string UncapitalizeFirstLetter(string s) => char.ToLower(s[0]) + s[1..]; // Group of intrinsics with same parameter names (parameter types might differ) record IntrinsicOverloadGroup(string Name, List MandatoryParameters, List OptionalParameters, List<(string DeclaringNamespace, IntrinsicDeclaration Declaration)> Overloads); - + static void GenerateIntrinsicsCall(SourceProductionContext spc, EquatableList namespaces) { var builder = new StringBuilder(); @@ -161,16 +161,16 @@ namespace Stride.Shaders.Parsing.SDSL; static string IntrinsicDeclarationKey(NamespaceDeclaration arg) { var key = arg.Name.Name; - + // Merge RW and non-RW methods in same type if (key.StartsWith("RW")) key = key.Substring("RW".Length); - - + + // Merge all texture methods in same type if (key.StartsWith("Texture")) return "TextureMethods"; - + return key; } @@ -194,15 +194,15 @@ static string NormalizeParameters(string @namespace, string methodName, string p _ => parameterName, }; } - + foreach (var ns in namespaces.Items.GroupBy(IntrinsicDeclarationKey)) { bool hasThis = DecodeThisType(ns.Key, out var thisType); var thisParam = hasThis ? $", SpirvValue {UncapitalizeFirstLetter(thisType)}" : ""; var thisArg = hasThis ? ", thisValue!.Value" : ""; - + var intrinsicGroups = new Dictionary(); - + foreach (var intrinsicGroup in ns.SelectMany(x => x.Intrinsics.Items.Select(y => (DeclaringNamespace: x.Name.Name, Declaration: y))) .Where(x => x.Declaration.Parameters.Items.All(p => p.Name.Name != "...")) .GroupBy(i => i.Declaration.Name.Name)) @@ -214,7 +214,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p x.Declaration.Parameters.Items.Clear(); x.Declaration.Parameters.Items.AddRange(parameters); } - + // Find common parameters var maxParameterCount = intrinsicGroup.Min(x => x.Declaration.Parameters.Items.Count); var mandatoryParameters = intrinsicGroup.First().Declaration.Parameters.Items.GetRange(0, maxParameterCount); @@ -226,7 +226,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p break; } } - + var optionalParameters = intrinsicGroup .SelectMany(x => x.Declaration.Parameters.Items.Skip(mandatoryParameters.Count)) .GroupBy(x => x.Name.Name) @@ -235,10 +235,10 @@ static string NormalizeParameters(string @namespace, string methodName, string p intrinsicGroups[intrinsicGroup.Key] = new IntrinsicOverloadGroup(intrinsicGroup.Key, mandatoryParameters, optionalParameters, intrinsicGroup.ToList()); } - + builder.AppendLine($"public abstract class {ns.Key}Declarations : IIntrinsicCompiler"); builder.AppendLine("{"); - + foreach (var intrinsicGroup in intrinsicGroups) { // Get parameters of first and last overload (the ones with the less and most parameters) @@ -247,7 +247,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p var optionalParameters = intrinsicGroup.Value.OptionalParameters; builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{thisParam}{GenerateParameters(mandatoryParameters)}{GenerateParameters(optionalParameters, true)}) => throw new NotImplementedException();"); } - + builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams) {"); builder.AppendLine("var (builder, context) = compiler;"); builder.AppendLine("return (@namespace, name, compiledParams.Length) switch {"); @@ -280,7 +280,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p { var optionalParameters = y.First().Declaration.Parameters.Items.GetRange(mandatoryParameters.Count, y.First().Declaration.Parameters.Items.Count - mandatoryParameters.Count); builder.Append($"({@namespace}, \"{intrinsicGroup.Key}\", {y.First().Declaration.Parameters.Items.Count})"); - + // special switch/case (same number of parameters of different type) if (intrinsicGroup.Key == "Barrier") { @@ -289,7 +289,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p builder.Append(" not"); builder.Append(" ScalarType"); } - + builder.AppendLine($" => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}),"); } } @@ -320,4 +320,4 @@ internal static EquatableList ParseInstrinsics(AdditionalT return ns; else return []; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs index 62651173cb..79ed29cf90 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/IntrinAST.cs @@ -7,7 +7,7 @@ namespace Stride.Shaders.Generators.Intrinsics; // \[\[[attr]\]\] ([ [, ... ]]) [ : ] -internal abstract record Node([property:JsonIgnore]TextLocation Location); +internal abstract record Node([property: JsonIgnore] TextLocation Location); internal record Identifier(string Name, TextLocation Location) : Node(Location) { @@ -31,7 +31,7 @@ internal record Typename(string Name, Layout? Size, TextLocation Location) : Nod // internal record NumericType(Layout Size, TextLocation Location) : Typename("numeric", Size, Location); internal record Matching(int LayoutIndex, int BaseTypeIndex, TextLocation Location) : Node(Location); -internal record ClassTMatch(TextLocation Location) : Matching(-1, 0,Location); +internal record ClassTMatch(TextLocation Location) : Matching(-1, 0, Location); internal record FuncMatch(TextLocation Location) : Matching(-3, 0, Location); internal record Func2Match(TextLocation Location) : Matching(-3, 0, Location); internal record TypeMatch(int Index, TextLocation Location) : Matching(Index, Index, Location); @@ -50,7 +50,7 @@ internal record NamespaceDeclaration(Identifier Name, EquatableList Create(ReadOnlySpan items) => new([..items]); + public static EquatableList Create(ReadOnlySpan items) => new([.. items]); } [CollectionBuilder(typeof(EquatableListBuilder), "Create")] diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs index cd321683d7..05074aefa7 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs @@ -262,7 +262,7 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) if (scanner.Match("<", true)) { scanner.MatchWhiteSpace(advance: true); - if(scanner.Match(">", true)) + if (scanner.Match(">", true)) { layout = new Layout("any", "any", new TextLocation(scanner.Code, position..scanner.Position)); return true; @@ -351,7 +351,7 @@ internal static bool IntrinsicParameter(this ref Scanner scanner, out IntrinsicP { var position = scanner.Position; parameter = new(null, null!, null!, new()); - if(scanner.Match("...", true)) + if (scanner.Match("...", true)) { parameter = parameter with { Name = new Identifier("...", new TextLocation(scanner.Code, position..scanner.Position)), Location = new TextLocation(scanner.Code, position..scanner.Position) }; return scanner.Success(); @@ -469,20 +469,20 @@ internal static class IntrinParser internal static bool ProcessAndParse(string code, out EquatableList result) => Parse(PreProcess(code), out result); - + internal static string PreProcess(string code) => string.Join("\n", code.Split('\n').Where(line => !line.TrimStart().StartsWith("//"))); internal static bool Parse(string code, out EquatableList result) { var scanner = new Scanner(code); - if(scanner.IntrinsicFile(out var ns)) + if (scanner.IntrinsicFile(out var ns)) { - foreach(var n in ns) + foreach (var n in ns) { - for(int i = 0; i < n.Intrinsics.Items.Count; i++) + for (int i = 0; i < n.Intrinsics.Items.Count; i++) { var intrinsic = n.Intrinsics.Items[i]; - if(intrinsic.ReturnType is { Typename.Name: "$to_resolve" }) + if (intrinsic.ReturnType is { Typename.Name: "$to_resolve" }) { var name = intrinsic.Parameters.Items[intrinsic.ReturnType.Match is TypeMatch tm ? tm.Index - 1 : throw new InvalidOperationException()].TypeInfo.Typename.Name; intrinsic = intrinsic with @@ -493,10 +493,10 @@ internal static bool Parse(string code, out EquatableList } }; } - for(int j = 0; j < intrinsic.Parameters.Items.Count; j++) + for (int j = 0; j < intrinsic.Parameters.Items.Count; j++) { var parameter = intrinsic.Parameters.Items[j]; - if(parameter is not null && parameter.TypeInfo is { Typename.Name: "$to_resolve", Match: TypeMatch {Index : >= 0} tm}) + if (parameter is not null && parameter.TypeInfo is { Typename.Name: "$to_resolve", Match: TypeMatch { Index: >= 0 } tm }) { var name = tm switch { @@ -510,13 +510,13 @@ internal static bool Parse(string code, out EquatableList }; } } - + n.Intrinsics.Items[i] = intrinsic; - + } } } - + if (!scanner.EOF) { result = []; @@ -525,4 +525,4 @@ internal static bool Parse(string code, out EquatableList result = ns; return true; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs index 0968b1277a..18e03e3b83 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs @@ -40,7 +40,7 @@ private string GenerateVisitSuffix(INamedTypeSymbol type) { return type.Name; } - + private void GenerateVisitorsBase(SourceProductionContext context, Compilation compilation, bool generateRewriter, string visitorName, Func isNodeType) { var classVisitor = new NodeTypeClassFinder(isNodeType); @@ -90,7 +90,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var memberTypeName = memberType.ToDisplayString(); var nodeListElementType = memberType.AllInterfaces.FirstOrDefault(x => x.IsGenericType && x.ConstructUnboundGenericType().ToDisplayString() == ilistName && isNodeType(x.TypeArguments[0]))?.TypeArguments[0]; var isNode = isNodeType(memberType); - var hasNullableAnnoation = memberType.NullableAnnotation; + var hasNullableAnnoation = memberType.NullableAnnotation; if (isNode) { if (memberType.NullableAnnotation == NullableAnnotation.Annotated) @@ -109,7 +109,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c } sb.AppendLine(" }"); - + if (generateRewriter) { sb.AppendLine($" public partial class {visitorName}Visitor"); @@ -119,7 +119,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c var typeName = type.ToDisplayString(); var variableName = GenerateVariableName(type.Name); var genericParameters = type.IsGenericType ? $"<{string.Join(",", type.TypeArguments)}>" : string.Empty; - + if (variableName is "if" or "else" or "continue" or "while" or "return" or "break" or "for") { variableName = "@" + variableName; @@ -136,7 +136,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c } sb.AppendLine(" }"); - + sb.AppendLine($" public partial class {visitorName}Rewriter"); sb.AppendLine(" {"); foreach (var type in symbolTypes) @@ -191,7 +191,7 @@ private void GenerateVisitorsBase(SourceProductionContext context, Compilation c sb.AppendLine(" }"); } - + sb.AppendLine("}"); foreach (var type in symbolTypes) @@ -320,7 +320,7 @@ private static bool IsNodeType(ITypeSymbol type) return false; } - + private static IEnumerable GetBaseTypesAndThis(ITypeSymbol type) { var current = type; diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index 65be69f2be..cc561e8cdc 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -10,7 +10,7 @@ namespace Stride.Shaders.Parsing.SDFX; public class EffectCodeWriter : ShaderWriter { private const string DefaultNameSpace = "Stride.Rendering"; - + private readonly List<(string Message, TextLocation Location)> logging = new(); private Stack contextStack = new(); private Dictionary blockContexts = new(); @@ -18,7 +18,7 @@ public class EffectCodeWriter : ShaderWriter private SymbolTable table = new(new()) { ResolveArraySizes = false, ResolveExternalTypes = false }; private bool isProcessingColor = false; - + public bool Run(Node node) { void LogErrors() @@ -28,7 +28,7 @@ void LogErrors() Write("#error ").WriteLine(reportMessage.ToString()); } } - + var blockVisitor = new ShaderBlockVisitor(this); blockVisitor.VisitNode(node); @@ -84,7 +84,7 @@ public override void VisitShaderStruct(ShaderStruct shaderStruct) // Register struct in table shaderStruct.ProcessSymbol(table, table.Context); } - + protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Identifier name, Expression? initialValue, List attributes) { isProcessingColor = attributes.OfType().Any(x => x.Name == "Color"); @@ -95,7 +95,7 @@ protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Ident typeName.ProcessSymbol(table); var type = typeName.Type; - + // ParameterKey shouldn't contain only the underlying type in case of arrays (we use slots) var parameterType = type; @@ -106,7 +106,7 @@ protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Ident } else { - + while (parameterType is ArrayType a) { parameterType = a.BaseType; @@ -242,7 +242,7 @@ public override void VisitShaderSamplerComparisonState(ShaderSamplerComparisonSt if (IsParameterKey(shaderSamplerState)) WriteVariableAsParameterKey(false, new TypeName("SamplerState", default), shaderSamplerState.Name, null, shaderSamplerState.Attributes ?? []); } - + public override void VisitBlockStatement(BlockStatement blockStatement) { contextStack.Push(new ShaderBlockContext()); @@ -261,7 +261,7 @@ public override void VisitShaderFile(ShaderFile shaderFile) if (rootClasses.Count > 0) { shaderFile.RootDeclarations.RemoveAll(x => x is ShaderClass); - + // Make sure all top-level objects without namespace are wrapped inside a namespace shaderFile.Namespaces.Add(new ShaderNamespace(default) { @@ -285,7 +285,7 @@ public override void VisitShaderNamespace(ShaderNamespace shaderNamespace) // (otherwise our unit tests are generating too many collisions -- we could revisit that decision later if we allow more than one shader per file in production) var lastShaderClass = declarations.OfType().LastOrDefault(); declarations = declarations.Where(x => x is not ShaderClass || x == lastShaderClass).ToList(); - + foreach (var node in declarations) { VisitNode(node); @@ -311,7 +311,7 @@ public override void VisitAssign(Assign assign) base.VisitAssign(assign); } } - + public override void VisitAccessorChainExpression(AccessorChainExpression accessorChainExpression) { if (TryParameters(accessorChainExpression, out var typeTarget, out var typeMember, out var extraPath)) @@ -357,7 +357,7 @@ private void ExtractGenericParameters(Expression mixinStatementValue, out Expres if (mixinStatementValue is AccessorChainExpression accessorChainExpression && accessorChainExpression.Accessors.Count > 0 && accessorChainExpression.Accessors[^1] is GenericIdentifier genericIdentifier1) { // Recreate an access chain expression without the generics at the end - mixinName = new AccessorChainExpression(accessorChainExpression.Source, accessorChainExpression.Info) { Accessors = [..accessorChainExpression.Accessors[..^1], genericIdentifier1.Name] }; + mixinName = new AccessorChainExpression(accessorChainExpression.Source, accessorChainExpression.Info) { Accessors = [.. accessorChainExpression.Accessors[..^1], genericIdentifier1.Name] }; genericParameters = genericIdentifier1.Generics; } // Pattern like A @@ -440,130 +440,130 @@ public override void VisitMixin(Mixin mixinStatement) switch (mixinStatement.Kind) { case Specification.MixinKindSDFX.Default: - { - ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); - - WriteLinkLine(mixinStatement); - Write("context.Mixin(mixin, "); - WriteMixinName(mixinName); - WriteGenericParameters(genericParameters); - WriteLine(");"); - break; - } - case Specification.MixinKindSDFX.Child: - { - // mixin child can come in 2 flavour: - // 1) mixin child MyEffect - // => equivalent to 2) with "mixin child MyEffect = MyEffect" - // 2) mixin child MyGenericEffectName = MyEffect - ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); - var childName = mixinStatement.Target ?? (Identifier)mixinStatement.Value; { - WriteLinkLine(mixinStatement); - Write("if (context.ChildEffectName == "); - WriteMixinName(childName); - WriteLine(")"); - OpenBrace(); + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); WriteLinkLine(mixinStatement); Write("context.Mixin(mixin, "); WriteMixinName(mixinName); WriteGenericParameters(genericParameters); WriteLine(");"); - WriteLine("return;"); - - CloseBrace(); + break; + } + case Specification.MixinKindSDFX.Child: + { + // mixin child can come in 2 flavour: + // 1) mixin child MyEffect + // => equivalent to 2) with "mixin child MyEffect = MyEffect" + // 2) mixin child MyGenericEffectName = MyEffect + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + var childName = mixinStatement.Target ?? (Identifier)mixinStatement.Value; + { + WriteLinkLine(mixinStatement); + Write("if (context.ChildEffectName == "); + WriteMixinName(childName); + WriteLine(")"); + OpenBrace(); + + WriteLinkLine(mixinStatement); + Write("context.Mixin(mixin, "); + WriteMixinName(mixinName); + WriteGenericParameters(genericParameters); + WriteLine(");"); + WriteLine("return;"); + + CloseBrace(); + } + break; } - break; - } case Specification.MixinKindSDFX.Remove: - { - ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); - - WriteLinkLine(mixinStatement); - Write("context.RemoveMixin(mixin, "); - WriteMixinName(mixinName); - WriteGenericParameters(genericParameters); - WriteLine(");"); - break; - } - case Specification.MixinKindSDFX.Macro: - { - WriteLinkLine(mixinStatement); - Expression macroName; - Expression macroValue; - - if (mixinStatement.Target != null) { - macroName = mixinStatement.Target; - if (macroName is Identifier id) - macroName = new StringLiteral(id.Name, id.Info); - macroValue = mixinStatement.Value; + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + + WriteLinkLine(mixinStatement); + Write("context.RemoveMixin(mixin, "); + WriteMixinName(mixinName); + WriteGenericParameters(genericParameters); + WriteLine(");"); + break; } - else + case Specification.MixinKindSDFX.Macro: { - var variableReference = mixinStatement.Value as AccessorChainExpression; - if (variableReference == null || !(variableReference.Source is Identifier id) || !IsParameterDeclaredInContext(id.Name)) + WriteLinkLine(mixinStatement); + Expression macroName; + Expression macroValue; + + if (mixinStatement.Target != null) { - logging.Add(("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info)); - macroName = new StringLiteral("#INVALID_MACRO_NAME", default); + macroName = mixinStatement.Target; + if (macroName is Identifier id) + macroName = new StringLiteral(id.Name, id.Info); macroValue = mixinStatement.Value; } else { - macroName = new StringLiteral(((Identifier)variableReference.Accessors[0]).Name, variableReference.Accessors[0].Info); - macroValue = mixinStatement.Value; + var variableReference = mixinStatement.Value as AccessorChainExpression; + if (variableReference == null || !(variableReference.Source is Identifier id) || !IsParameterDeclaredInContext(id.Name)) + { + logging.Add(("Invalid syntax. Expecting: mixin macro Parameters.NameOfProperty or mixin macro nameOfProperty = value", mixinStatement.Info)); + macroName = new StringLiteral("#INVALID_MACRO_NAME", default); + macroValue = mixinStatement.Value; + } + else + { + macroName = new StringLiteral(((Identifier)variableReference.Accessors[0]).Name, variableReference.Accessors[0].Info); + macroValue = mixinStatement.Value; + } } - } - Write("mixin.AddMacro("); - VisitNode(macroName); - Write(", "); - VisitNode(macroValue); - WriteLine(");"); - break; - } + Write("mixin.AddMacro("); + VisitNode(macroName); + Write(", "); + VisitNode(macroValue); + WriteLine(");"); + break; + } case Specification.MixinKindSDFX.ComposeSet: case Specification.MixinKindSDFX.ComposeAdd: - { - if (mixinStatement.Target == null) { - logging.Add(("Expecting assign expression for composition", mixinStatement.Value.Info)); - return; - } + if (mixinStatement.Target == null) + { + logging.Add(("Expecting assign expression for composition", mixinStatement.Value.Info)); + return; + } - var addCompositionFunction = "PushComposition"; + var addCompositionFunction = "PushComposition"; - // If it's a +=, let's create or complete a ShaderArraySource - if (mixinStatement.Kind == Specification.MixinKindSDFX.ComposeAdd) - { - addCompositionFunction = "PushCompositionArray"; - } + // If it's a +=, let's create or complete a ShaderArraySource + if (mixinStatement.Kind == Specification.MixinKindSDFX.ComposeAdd) + { + addCompositionFunction = "PushCompositionArray"; + } - ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); + ExtractGenericParameters(mixinStatement.Value, out var mixinName, out var genericParameters); - OpenBrace(); - WriteLinkLine(mixinStatement); - Write("var __mixinToCompose__ = "); - WriteMixinName(mixinName); - WriteLine(";"); - WriteLine("var __subMixin = new ShaderMixinSource();"); - - WriteLinkLine(mixinStatement); - Write("context.").Write(addCompositionFunction).Write("(mixin, "); - WriteStringOrExpression(mixinStatement.Target); - WriteLine(", __subMixin);"); - - WriteLinkLine(mixinStatement); - Write("context.Mixin(__subMixin, __mixinToCompose__"); - WriteGenericParameters(genericParameters); - WriteLine(");"); - - WriteLinkLine(mixinStatement); - WriteLine("context.PopComposition();"); - CloseBrace(); - break; - } + OpenBrace(); + WriteLinkLine(mixinStatement); + Write("var __mixinToCompose__ = "); + WriteMixinName(mixinName); + WriteLine(";"); + WriteLine("var __subMixin = new ShaderMixinSource();"); + + WriteLinkLine(mixinStatement); + Write("context.").Write(addCompositionFunction).Write("(mixin, "); + WriteStringOrExpression(mixinStatement.Target); + WriteLine(", __subMixin);"); + + WriteLinkLine(mixinStatement); + Write("context.Mixin(__subMixin, __mixinToCompose__"); + WriteGenericParameters(genericParameters); + WriteLine(");"); + + WriteLinkLine(mixinStatement); + WriteLine("context.PopComposition();"); + CloseBrace(); + break; + } } } @@ -610,7 +610,7 @@ public override void VisitUsingParams(UsingParams usingParametersStatement) public override void VisitShaderClass(ShaderClass shaderClass) { table.Push(); - + // Process generic symbols (might be used in type arrays) if (shaderClass.Generics != null) { @@ -667,7 +667,7 @@ public override void VisitEffectParameters(EffectParameters effectParameters) CloseBrace(false).WriteLine(); } } - + internal bool IsParameterKey(ShaderElement element) { if (element is ShaderMember member) @@ -726,7 +726,7 @@ public override void VisitShaderEffect(ShaderEffect shaderEffect) { HasMixin = true; } - + public override void VisitShaderClass(ShaderClass shaderClassType) { // Check if there are any parameter keys in ShaderClassType and ConstantBuffer @@ -748,4 +748,4 @@ private void CheckParameterKeys(IEnumerable variables) } } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs index 4de1202e5e..a4e32df759 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs @@ -14,14 +14,14 @@ public void Initialize(IncrementalGeneratorInitializationContext context) context .AdditionalTextsProvider .Where(x => Path.GetExtension(x.Path).ToLowerInvariant() is ".sdfx" or ".sdsl"); - + context.RegisterSourceOutput(shaderFiles, GenerateShaderKeysAndEffects); } private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, AdditionalText arg2) { var filename = GetSafeHintName(arg2.Path); - + try { var preprocessedText = MonoGamePreProcessor.Run(arg2.GetText().ToString(), arg2.Path); @@ -46,7 +46,7 @@ private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, Addition arg1.AddSource(filename, sb.ToString()); } } - + public static string GetSafeHintName(string absolutePath) { // 1. Get the file name without extension (e.g., "MyConfig") @@ -67,4 +67,4 @@ public static string GetSafeHintName(string absolutePath) // 4. Combine into a stable hint name (e.g., "MyConfig_A1B2C3D4.g.cs") return $"{sanitizedName}_{hash}.g.cs"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs b/sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs index 793de82e25..9ab34b3347 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/EntryPoints.cs @@ -26,4 +26,4 @@ public enum EntryPoint : uint Callable = 1 << 13, TaskEXT = 1 << 14, MeshEXT = 1 << 15, -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs index 7657b1e83f..2eefd35f30 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/IntrinsicsParameters.cs @@ -10,144 +10,145 @@ public enum OptionalQualifier { RowMajor, ColumnMajor }; public record struct VectorSize(string X, string? Y = null); public record struct ParameterType(BaseType BaseType, VectorSize? VectorSize = null, (int Layout, int BaseType)? Match = null) { - public ParameterType(int matchLayout, int matchBaseType) : this(BaseType.Match, Match: (matchLayout, matchBaseType)){} - public ParameterType(string baseType,VectorSize? VectorSize = null, (int Layout, int BaseType)? matching = null) : - this( - baseType switch - { - "bool" => BaseType.Bool, - "int" => BaseType.Int, - "int16_t" => BaseType.Int16, - "int32_only" => BaseType.Int32Only, - "int64_t" => BaseType.Int64, - "int64_only" => BaseType.Int64Only, - "sint16or32_only" => BaseType.SInt16Or32, - "any_int" => BaseType.AnyInt, - "any_int32" => BaseType.AnyInt32, - "any_int64" => BaseType.AnyInt64, - "any_int16or32" => BaseType.AnyInt16Or32, - "uint" => BaseType.Uint, - "uint16_t" => BaseType.Uint16, - "u64" => BaseType.U64, - "float" => BaseType.Float, - "float16" or "half" or "float16_t" => BaseType.Float16, - "any_float" => BaseType.AnyFloat, - "double" => BaseType.Float, - "double_only" => BaseType.DoubleOnly, - "sampler1d" => BaseType.Sampler1d, - "sampler2d" => BaseType.Sampler2d, - "sampler3d" => BaseType.Sampler3d, - "sampler_cube" => BaseType.SamplerCube, - "sampler_cmp" => BaseType.SamplerCmp, - "sampler" => BaseType.Sampler, - "any_sampler" => BaseType.AnySampler, - "wave" => BaseType.Wave, - "void" => BaseType.Void, - "uint_only" => BaseType.UIntOnly, - "numeric" => BaseType.Numeric, - "numeric16_only" => BaseType.Numeric16Only, - "numeric32_only" => BaseType.Numeric32Only, - "float32_only" => BaseType.Float32Only, - "any" => BaseType.Any, - "float_like" => BaseType.FloatLike, - "match" => BaseType.Match, - "ByteAddressBuffer" => BaseType.ByteAddressBuffer, - "RWByteAddressBuffer" => BaseType.RWByteAddressBuffer, - "VkBufferPointer" => BaseType.VkBufferPointer, - "Texture2D" => BaseType.Texture2D, - "Texture2DArray" => BaseType.Texture2DArray, - "acceleration_struct" - or "ray_desc" - or "udt" - or "triangle_positions" - or "p32i8" - or "p32u8" - or "resource" - or "NodeRecordOrUAV" - or "LinAlg" - or "DxHitObject" - or "RayQuery" - or "ThreadNodeOutputRecords" - or "GroupNodeOutputRecords" - => BaseType.Other, - _ => throw new ArgumentException($"Unknown base type: {baseType}"), - }, - VectorSize, - matching - ) - - {} + public ParameterType(int matchLayout, int matchBaseType) : this(BaseType.Match, Match: (matchLayout, matchBaseType)) { } + public ParameterType(string baseType, VectorSize? VectorSize = null, (int Layout, int BaseType)? matching = null) : + this( + baseType switch + { + "bool" => BaseType.Bool, + "int" => BaseType.Int, + "int16_t" => BaseType.Int16, + "int32_only" => BaseType.Int32Only, + "int64_t" => BaseType.Int64, + "int64_only" => BaseType.Int64Only, + "sint16or32_only" => BaseType.SInt16Or32, + "any_int" => BaseType.AnyInt, + "any_int32" => BaseType.AnyInt32, + "any_int64" => BaseType.AnyInt64, + "any_int16or32" => BaseType.AnyInt16Or32, + "uint" => BaseType.Uint, + "uint16_t" => BaseType.Uint16, + "u64" => BaseType.U64, + "float" => BaseType.Float, + "float16" or "half" or "float16_t" => BaseType.Float16, + "any_float" => BaseType.AnyFloat, + "double" => BaseType.Float, + "double_only" => BaseType.DoubleOnly, + "sampler1d" => BaseType.Sampler1d, + "sampler2d" => BaseType.Sampler2d, + "sampler3d" => BaseType.Sampler3d, + "sampler_cube" => BaseType.SamplerCube, + "sampler_cmp" => BaseType.SamplerCmp, + "sampler" => BaseType.Sampler, + "any_sampler" => BaseType.AnySampler, + "wave" => BaseType.Wave, + "void" => BaseType.Void, + "uint_only" => BaseType.UIntOnly, + "numeric" => BaseType.Numeric, + "numeric16_only" => BaseType.Numeric16Only, + "numeric32_only" => BaseType.Numeric32Only, + "float32_only" => BaseType.Float32Only, + "any" => BaseType.Any, + "float_like" => BaseType.FloatLike, + "match" => BaseType.Match, + "ByteAddressBuffer" => BaseType.ByteAddressBuffer, + "RWByteAddressBuffer" => BaseType.RWByteAddressBuffer, + "VkBufferPointer" => BaseType.VkBufferPointer, + "Texture2D" => BaseType.Texture2D, + "Texture2DArray" => BaseType.Texture2DArray, + "acceleration_struct" + or "ray_desc" + or "udt" + or "triangle_positions" + or "p32i8" + or "p32u8" + or "resource" + or "NodeRecordOrUAV" + or "LinAlg" + or "DxHitObject" + or "RayQuery" + or "ThreadNodeOutputRecords" + or "GroupNodeOutputRecords" + => BaseType.Other, + _ => throw new ArgumentException($"Unknown base type: {baseType}"), + }, + VectorSize, + matching + ) + + { } } public record struct Parameter(Qualifier? Qualifier, OptionalQualifier? OptionalQualifier, ParameterType Type, string Name); public record class IntrinsicDefinition(ParameterType Return, Parameter[] Parameters) { - public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan parameters) - : this(@return, parameters.ToArray()) - {} + public IntrinsicDefinition(ParameterType @return, params ReadOnlySpan parameters) + : this(@return, parameters.ToArray()) + { } } public static partial class IntrinsicsDefinitions { - static Qualifier FromString(string str) => str switch - { - "in" => Qualifier.In, - "out" => Qualifier.Out, - "inout" => Qualifier.InOut, - "ref" => Qualifier.Ref, - _ => throw new ArgumentException($"Unknown qualifier: {str}"), - }; - static OptionalQualifier FromStringOptional(string str) => str switch - { - "row_major" => OptionalQualifier.RowMajor, - "col_major" => OptionalQualifier.ColumnMajor, - _ => throw new ArgumentException($"Unknown optional qualifier: {str}"), - }; + static Qualifier FromString(string str) => str switch + { + "in" => Qualifier.In, + "out" => Qualifier.Out, + "inout" => Qualifier.InOut, + "ref" => Qualifier.Ref, + _ => throw new ArgumentException($"Unknown qualifier: {str}"), + }; + static OptionalQualifier FromStringOptional(string str) => str switch + { + "row_major" => OptionalQualifier.RowMajor, + "col_major" => OptionalQualifier.ColumnMajor, + _ => throw new ArgumentException($"Unknown optional qualifier: {str}"), + }; } -public enum BaseType { - Bool, - Int, - Int32Only, - Int16, - Int64, - SInt16Or32, - AnyInt, - AnyInt16Or32, - AnyInt32, - AnyInt64, - Int64Only, - Uint, - Uint16, - U64, - Float, - Float16, - AnyFloat, - FloatLike, - Float32Only, - DoubleOnly, - Sampler1d, - Sampler2d, - Sampler3d, - SamplerCube, - SamplerCmp, - Sampler, - AnySampler, - Wave, - Void, - Texture2D, +public enum BaseType +{ + Bool, + Int, + Int32Only, + Int16, + Int64, + SInt16Or32, + AnyInt, + AnyInt16Or32, + AnyInt32, + AnyInt64, + Int64Only, + Uint, + Uint16, + U64, + Float, + Float16, + AnyFloat, + FloatLike, + Float32Only, + DoubleOnly, + Sampler1d, + Sampler2d, + Sampler3d, + SamplerCube, + SamplerCmp, + Sampler, + AnySampler, + Wave, + Void, + Texture2D, - UIntOnly, - Numeric, - Numeric16Only, - Numeric32Only, - Any, - Match, - ByteAddressBuffer, - RWByteAddressBuffer, - VkBufferPointer, - Other, + UIntOnly, + Numeric, + Numeric16Only, + Numeric32Only, + Any, + Match, + ByteAddressBuffer, + RWByteAddressBuffer, + VkBufferPointer, + Other, Texture2DArray -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs index 63ab6c00f5..c592429060 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/Node.Visitors.cs @@ -37,4 +37,4 @@ public virtual void VisitItem(T node) where T : INodeItem public partial class NodeWalker : NodeVisitor { -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs index 0570bb004c..6015bee315 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs @@ -70,4 +70,4 @@ public record struct ConstantGenericSymbol(); public record struct CompositionSymbol(); public record struct CBufferSymbol(); public record struct TBufferSymbol(); -public record struct RGroupSymbol(); \ No newline at end of file +public record struct RGroupSymbol(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs index e05a214ecb..6c93951cf9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs @@ -25,7 +25,7 @@ public void Add(string name, Symbol symbol) if (existingSymbol.Type is FunctionType) existingSymbol = new Symbol(new(name, SymbolKind.MethodGroup, IsStage: existingSymbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [existingSymbol]); - existingSymbol = existingSymbol with { GroupMembers = existingSymbol.GroupMembers.Add(symbol) }; + existingSymbol = existingSymbol with { GroupMembers = existingSymbol.GroupMembers.Add(symbol) }; symbols[name] = existingSymbol; } else @@ -68,4 +68,4 @@ public bool TryGetValues(string name, List result) public sealed class RootSymbolFrame() : SymbolFrame() { -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs index ac3dda18d6..337c44c48e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Globals.cs @@ -31,9 +31,9 @@ public partial record VectorType internal static FrozenDictionary Init() { var arr = new KeyValuePair[ScalarType.names.Length * 3]; - for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 2; x <= 4; x++) - arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i].Key}{x}", new(ScalarType.names[i].Value,x)); + for (int i = 0; i < ScalarType.names.Length; i++) + for (int x = 2; x <= 4; x++) + arr[i * 3 + (x - 2)] = new($"{ScalarType.names[i].Key}{x}", new(ScalarType.names[i].Value, x)); return arr.ToFrozenDictionary(); } } @@ -46,12 +46,12 @@ public partial record MatrixType internal static FrozenDictionary Init() { var arr = new List>(ScalarType.names.Length * 3 * 3); - for(int i = 0; i < ScalarType.names.Length; i++) - for(int x = 2; x <= 4; x++) - for(int y = 2; y <= 4; y++) + for (int i = 0; i < ScalarType.names.Length; i++) + for (int x = 2; x <= 4; x++) + for (int y = 2; y <= 4; y++) // Note: this is HLSL-style so Rows/Columns meaning is swapped - arr.Add(new($"{ScalarType.names[i].Key}{y}x{x}", new(ScalarType.names[i].Value,x,y))); - arr.Add(new KeyValuePair("matrix", new(ScalarType.Float,4,4))); - return arr.ToFrozenDictionary(); + arr.Add(new($"{ScalarType.names[i].Key}{y}x{x}", new(ScalarType.names[i].Value, x, y))); + arr.Add(new KeyValuePair("matrix", new(ScalarType.Float, 4, 4))); + return arr.ToFrozenDictionary(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs index 4a7870468a..64cd794460 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs @@ -114,4 +114,4 @@ protected List VisitItemList(List list) where T : struct, ISymbolTypeIt return newList ?? list; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index f5486a71fa..0b576086f8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -25,7 +25,7 @@ public abstract record SymbolType() /// /// public virtual string ToId() => ToString(); - + public static bool TryGetNumeric(string name, [MaybeNullWhen(false)] out SymbolType result) { if (ScalarType.Types.TryGetValue(name, out var s)) @@ -83,7 +83,7 @@ static ScalarType ResolveScalarType(TypeName? templateTypeName) "Texture2DMS" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true }, "Texture3D" => new Texture3DType(ResolveScalarType(templateTypeName)), "TextureCube" => new TextureCubeType(ResolveScalarType(templateTypeName)), - + "Texture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, "Texture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, "Texture2DMSArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true, Arrayed = true }, @@ -96,7 +96,7 @@ static ScalarType ResolveScalarType(TypeName? templateTypeName) "RWTexture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, "RWTexture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, - + _ => null, }; @@ -138,7 +138,7 @@ internal static SymbolType Of() var t when t == typeof(System.Numerics.Matrix4x4) => MatrixType.From("float4x4"), _ => throw new NotSupportedException($"Type '{typeof(T)}' is not supported as a SymbolType."), - }; + }; } } @@ -447,7 +447,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo if (symbol.Type is FunctionGroupType) throw new InvalidOperationException($"Can't import symbol for {nameof(FunctionGroupType)}"); - + if (symbol.Type is FunctionType) { var methods = CollectionsMarshal.AsSpan(symbol.OwnerType.Methods); @@ -490,7 +490,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; return symbol; } - + if (c.Symbol.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) { for (int index = 0; index < cb.Members.Count; index++) @@ -507,7 +507,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo var shaderId = context.GetOrRegister(symbol.OwnerType); context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); } - + symbol.IdRef = c.Symbol.IdRef; if (!isCurrentShader) symbol = symbol with { MemberAccessWithImplicitThis = c.Symbol.Type }; @@ -518,10 +518,10 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo } } } - + throw new InvalidOperationException($"Symbol {symbol} could not be imported because it was not found in its owner type {symbol.OwnerType}"); } - + /// /// Try to resolve a symbol in shader or inherited shader. If is null, you can use this method without importing type or symbol in a context (useful for type evaluation). /// @@ -577,7 +577,7 @@ private bool TryResolveSymbolNoRecursion(int id, out Symbol symbol) return true; } } - + var variables = CollectionsMarshal.AsSpan(Variables); foreach (ref var c in variables) { @@ -695,4 +695,4 @@ public sealed partial record ShaderMixinType : SymbolType public sealed partial record ExternalType(string Name, ShaderExpressionList? Generics) : SymbolType { public override string ToString() => Generics != null && Generics.Values.Count > 0 ? $"{Name}<{string.Join(",", Generics.Values)}>" : Name; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs index 660575a49a..91b748ec38 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/ASTNode.cs @@ -16,7 +16,7 @@ public interface INodeItem public abstract partial class Node(TextLocation info) { public TextLocation Info { get; set; } = info; - + public abstract void Accept(NodeVisitor visitor); } @@ -75,4 +75,4 @@ public override string ToString() { return $"namespace {string.Join(".", NamespacePath)}\nBlock\n{string.Join("\n", Declarations)}End\n"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs index b09834c0a0..376b92e1dc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/CFG.cs @@ -10,4 +10,4 @@ public class BasicBlock public class CFG { -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs index 36ea74af96..7c73683fc7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/IStreamChecker.cs @@ -5,4 +5,4 @@ namespace Stride.Shaders.Parsing.Analysis; public interface IStreamChecker { public void CheckIO(SymbolTable table, EntryPoint? entryPoint = null); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs index 2b32491a67..d628fbdac0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SDIR.cs @@ -13,10 +13,10 @@ public enum IROp LeftShift, RightShift, Greater, GreaterThan, Lower, LowerThan, Equals, NotEquals, - BitwiseAND, BitwiseXOR, BitwiseOR, + BitwiseAND, BitwiseXOR, BitwiseOR, LogicalAND, LogicalOR, - -} + +} public record struct QuadrupleArg( string Name, @@ -29,4 +29,4 @@ public record struct Quadruple( QuadrupleArg Arg2, QuadrupleArg Result -); \ No newline at end of file +); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index b044d413c3..a682c3091e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -17,7 +17,7 @@ public partial class SymbolTable : ISymbolProvider { public bool ResolveArraySizes { get; set; } = true; public bool ResolveExternalTypes { get; set; } = true; - + public Dictionary DeclaredTypes { get; } = []; public SpirvContext Context { get; init; } @@ -101,7 +101,7 @@ public bool TryResolveSymbol(int id, [MaybeNullWhen(false)] out Symbol symbol) symbol = null; return false; } - + public Symbol ResolveSymbol(int id) { if (!TryResolveSymbol(id, out var symbol)) @@ -120,4 +120,4 @@ public void AddError(SemanticError error) { Errors.Add(error); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs index e907ff01ac..b9abc4aff7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/TypeNameExtensions.cs @@ -9,8 +9,8 @@ public static partial class TypeNameExtensions { public static SymbolType ToSymbol(this TypeName typeName) { - if(!typeName.IsArray && typeName.Generics.Count == 0 && SymbolType.TryGetNumeric(typeName.Name, out var result)) + if (!typeName.IsArray && typeName.Generics.Count == 0 && SymbolType.TryGetNumeric(typeName.Name, out var result)) return result!; else return new UndefinedType(typeName); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs index f42ab1279c..74f6bb44f4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Grammar.cs @@ -17,7 +17,7 @@ public static ParseResult Match(string code, TParser? parser = var result = new ParseResult(); if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; - if(!Tokens.EOF(ref scanner)) + if (!Tokens.EOF(ref scanner)) result.Errors.Add(new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); return result; } @@ -33,7 +33,7 @@ public static ParseResult Match(TScannable code, TP var result = new ParseResult(); if (p.Match(ref scanner, result, out var fnum)) result.AST = fnum; - if(!Tokens.EOF(ref scanner)) + if (!Tokens.EOF(ref scanner)) result.Errors.Add(new(SDSLErrorMessages.SDSL0009, scanner[scanner.Position], scanner.Memory)); return result; } @@ -54,4 +54,4 @@ public static ParseResult MatchTyped(string code, TPars } else return null!; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs index 6313f4a4e3..7ba2b60ce9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs @@ -25,4 +25,4 @@ public interface IParser : IParser /// public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs index 4f5092b40a..094869a0dc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/ParseResult.cs @@ -14,25 +14,25 @@ readonly ReadOnlySpan GetNextToken() var pos = Location.Position; if (pos >= Code.Span.Length) return []; - if(operators.Contains(Code.Span[pos])) + if (operators.Contains(Code.Span[pos])) { - while(operators.Contains(Code.Span[pos])) + while (operators.Contains(Code.Span[pos])) pos++; return Code.Span[Location.Position..pos]; } - else if(char.IsDigit(Code.Span[pos])) + else if (char.IsDigit(Code.Span[pos])) { - while(char.IsDigit(Code.Span[pos])) + while (char.IsDigit(Code.Span[pos])) pos++; return Code.Span[Location.Position..pos]; } - else if(char.IsLetter(Code.Span[pos]) || Code.Span[pos] == '_' ) + else if (char.IsLetter(Code.Span[pos]) || Code.Span[pos] == '_') { - while(char.IsLetterOrDigit(Code.Span[pos]) || Code.Span[pos] == '_') + while (char.IsLetterOrDigit(Code.Span[pos]) || Code.Span[pos] == '_') pos++; return Code.Span[Location.Position..pos]; } - else return Code.Span[Location.Position..(Location.Position+1)]; + else return Code.Span[Location.Position..(Location.Position + 1)]; } public override readonly string ToString() { @@ -54,4 +54,4 @@ public class ParseResult /// /// Default parser result /// -public class ParseResult : ParseResult; \ No newline at end of file +public class ParseResult : ParseResult; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs index 3f96fcfa20..42d317d396 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrame.cs @@ -21,4 +21,4 @@ public void Add(CodeFrame previousFrame, Range range) public void Dispose() => Code.Dispose(); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs index 5f914bebfe..6149a4e207 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeFrameSnippets.cs @@ -5,20 +5,20 @@ public record struct CodeFrameSnippets(CodeFrame Frame, Range Location) public readonly Span Span => Frame.Code.Span[Location]; public readonly Memory Memory => Frame.Code.Memory[Location]; - public readonly int Line + public readonly int Line { - get + get { (int offset, int length) = Location.GetOffsetAndLength(Frame.Code.Length); return Frame.Code.Span[..(offset + length)].Count('\n'); } } - public readonly int Column + public readonly int Column { - get + get { (int offset, int length) = Location.GetOffsetAndLength(Frame.Code.Length); - return Frame.Code.Span[..(offset + length)].Length - Frame.Code.Span[..(offset + length)].LastIndexOf('\n'); + return Frame.Code.Span[..(offset + length)].Length - Frame.Code.Span[..(offset + length)].LastIndexOf('\n'); } } public static implicit operator CodeFrameSnippets((CodeFrame frame, Range range) tuple) => new(tuple.frame, tuple.range); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs index 446a225427..0dfc8bade6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CodeProcessor.cs @@ -9,7 +9,7 @@ public class SDSLPreProcessor() : IDisposable public void Run() => Apply(); - public SDSLPreProcessor Apply() + public SDSLPreProcessor Apply() where TPhase : struct, IPreProcessorPhase => new TPhase().Apply(this); @@ -18,4 +18,4 @@ public void Dispose() CodeFrames.ForEach(static x => x.Dispose()); CodeFrames.Clear(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs index 29b917c803..bcbe36ae05 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CMacros/CommentPhase.cs @@ -10,9 +10,9 @@ public readonly SDSLPreProcessor Apply(SDSLPreProcessor sdslpp) var last = sdslpp.CodeFrames[^1]; var scanner = new Scanner(last.Code.Memory); var started = false; - while(!Parsers.Until(ref scanner, ["//", "/*"])) + while (!Parsers.Until(ref scanner, ["//", "/*"])) { - if(!started) + if (!started) started = true; frame.Add(last, ..scanner.Position); if (Tokens.Literal("//", ref scanner)) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs index 14d42c72ed..874b5c983a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/CommentProcessedCode.cs @@ -99,4 +99,4 @@ public readonly TextLocation GetOriginalLocation(Range range) } return new(Original, 0..0); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs index 9dbc17e0b5..5f8bcf11fd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs @@ -63,4 +63,4 @@ public static string Run(string content, string filename, params ReadOnlySpan<(s } return textBuilder.ToString(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs index 0616f78944..811b6eacc9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MemoryOwnerExtensions.cs @@ -29,4 +29,4 @@ public static MemoryOwner Add(this MemoryOwner owner, Memory other, { return owner.Add(other.Span[range]); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs index 377b4fb63c..bf035637f0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/TextLinkExtensions.cs @@ -28,4 +28,4 @@ public static bool OriginIntersect(this TextLink link, Range range, int length, result = null; return false; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs index 6470ed410d..c3a2501f23 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.Parameters.cs @@ -15,7 +15,7 @@ public partial class EffectParameters(TypeName name, TextLocation info) : Shader public void Compile(SymbolTable table, CompilerUnit compiler) { compiler.Builder.Insert(new OpParamsSDFX(Name.Name)); - foreach(var parameter in Parameters) + foreach (var parameter in Parameters) parameter.Compile(table, compiler); } } @@ -24,7 +24,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) public partial class EffectParameter(TypeName type, Identifier identifier, TextLocation info, Expression? value = null) : Node(info) { public TypeName Type { get; set; } = type; - public Identifier Identifier { get; set;} = identifier; + public Identifier Identifier { get; set; } = identifier; public Expression? DefaultValue { get; set; } = value; public void Compile(SymbolTable table, CompilerUnit compiler) @@ -32,4 +32,4 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var (_, context) = compiler; context.Add(new OpParamsFieldSDFX(Identifier, Type)); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs index b57d7300ea..f1cc8c28a8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs @@ -81,7 +81,7 @@ public override void ProcessSymbol(SymbolTable table) public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, _) = compiler; - + var paramsName = ParamsName.Compile(table, compiler); builder.Insert(new OpParamsUseSDFX(paramsName.Id)); } @@ -119,7 +119,7 @@ public enum MixinStatementType /// The compose mixin used to add a composition (using +=). /// ComposeAdd, - + /// /// The child mixin used to specify a children shader. /// @@ -129,7 +129,7 @@ public enum MixinStatementType /// The clone mixin to clone the current mixins where the clone is emitted. /// Clone, - + /// /// The remove mixin to remove a mixin from current mixins. /// @@ -139,8 +139,8 @@ public enum MixinStatementType /// The macro mixin to declare a variable to be exposed in the mixin /// Macro, - - + + } public partial class Mixin(Specification.MixinKindSDFX kind, Identifier? target, Expression value, TextLocation info) : Statement(info) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs index ad588443e3..b97a9fe1cd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs @@ -26,11 +26,11 @@ namespace Stride.Shaders.Parsing.SDFX; // { // do // { - + // } // while (!scanner.IsEof && !Terminals.Char(';', ref scanner) && Terminals.Char('.', ref scanner, advance: true)); // } // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); // } -// } \ No newline at end of file +// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs index 0d53a563e8..4f87daf482 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs @@ -12,7 +12,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var position = scanner.Position; var isPartial = Tokens.Literal("partial", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _); - if(!isPartial) + if (!isPartial) scanner.Position = position; if (Tokens.Literal("effect", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) @@ -35,4 +35,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public static bool Effect(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectParser().Match(ref scanner, result, out parsed, orError); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs index 2b6cd4bae9..d795ebd310 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs @@ -15,14 +15,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (If(ref scanner, result, out var ifstatement, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) { parsed = new(ifstatement, scanner[..]); - while(ElseIf(ref scanner, result, out var elseif, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) + while (ElseIf(ref scanner, result, out var elseif, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; parsed.Info = scanner[position..scanner.Position]; return true; } - else if(Tokens.Literal("else ", ref scanner)) + else if (Tokens.Literal("else ", ref scanner)) return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner[scanner.Position], scanner.Memory)); return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs index 24b6257611..34704ad5ab 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs @@ -18,7 +18,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o scanner.Position = position; if (While(ref scanner, result, out var w, orError)) { - if(hasAttributes) + if (hasAttributes) w.Attribute = attribute; parsed = w; return true; @@ -30,7 +30,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (For(ref scanner, result, out var f, orError)) { - if(hasAttributes) + if (hasAttributes) f.Attribute = attribute; parsed = f; return true; @@ -57,7 +57,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if( + if ( Tokens.Literal("for", ref scanner, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) ) @@ -68,32 +68,32 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); // Parsing the initialization - if(StatementParsers.Expression(ref scanner, result, out init)){} - else if(StatementParsers.DeclareOrAssign(ref scanner, result, out init)){} - else if(StatementParsers.Empty(ref scanner, result, out init)){} + if (StatementParsers.Expression(ref scanner, result, out init)) { } + else if (StatementParsers.DeclareOrAssign(ref scanner, result, out init)) { } + else if (StatementParsers.Empty(ref scanner, result, out init)) { } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0036, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (ExpressionParser.Expression(ref scanner, result, out condition) - && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) {} + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) { } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); - + Parsers.Spaces0(ref scanner, result, out _); // parsing the final expression - + var tmpPos = scanner.Position; if (!Parsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) expressions = [new EmptyStatement(scanner[tmpPos..scanner.Position])]; - if(!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) - return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + if (!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); // parsing the block or statement - if(EffectStatementParsers.Statement(ref scanner, result, out var body)) + if (EffectStatementParsers.Statement(ref scanner, result, out var body)) { parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); return true; @@ -107,7 +107,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes where TScanner : struct, IScanner { var position = scanner.Position; - if( + if ( PostfixParser.Postfix(ref scanner, result, out var variable) && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) @@ -120,7 +120,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; } scanner.Position = position; - if(ExpressionParser.Expression(ref scanner, result, out var expression)) + if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; @@ -200,4 +200,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs index ba3e2c4828..04377315ee 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -67,7 +67,7 @@ public static bool Mixin(ref TScanner scanner, ParseResult result, out => new MixinParser().Match(ref scanner, result, out parsed, orError); public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); - + public static bool EffectBlock(ref TScanner scanner, ParseResult result, out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -91,7 +91,7 @@ public static bool ShaderSourceDeclaration(ref TScanner scanner, Parse var position = scanner.Position; if ( Tokens.AnyOf(["ShaderSourceCollection ", "ShaderSource ", "var "], ref scanner, out _) - && SDSL.Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name,out var value) + && SDSL.Parsers.TypeNameIdentifierArraySizeValue(ref scanner, result, out var typename, out var name, out var value) && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { @@ -147,7 +147,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { if (mixinType is Specification.MixinKindSDFX.ComposeSet or Specification.MixinKindSDFX.Child or Specification.MixinKindSDFX.Macro - && statement is Assign { Variables: [{ Value: {} value, Variable: Identifier variable }] } assign) + && statement is Assign { Variables: [{ Value: { } value, Variable: Identifier variable }] } assign) { if (assign.Variables[0].Operator == AssignOperator.Plus && mixinType == Specification.MixinKindSDFX.ComposeSet) mixinType = Specification.MixinKindSDFX.ComposeAdd; @@ -166,12 +166,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if( + if ( PostfixParser.Postfix(ref scanner, result, out var variable) && SDSL.Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) && SDSL.Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) @@ -184,7 +184,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; } scanner.Position = position; - if(ExpressionParser.Expression(ref scanner, result, out var expression)) + if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs index e2d5867b22..77174fe826 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs @@ -75,4 +75,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs index 091e0f1b2b..d83c97ec5b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs @@ -25,7 +25,7 @@ public class ShaderWriter : NodeWalker /// The indent level. ///
private int IndentLevel { get; set; } - + /// /// Gets or sets a value indicating whether [new line]. /// @@ -41,18 +41,18 @@ public class ShaderWriter : NodeWalker /// The string builder. ///
private StringBuilder StringBuilder { get; set; } = new(); - + private void PrefixIndent() { if (NewLine) { - for (int i = 0; i < IndentLevel; ++i) + for (int i = 0; i < IndentLevel; ++i) Append(" "); NewLine = false; } } - + /// /// Gets the text. /// @@ -81,7 +81,7 @@ public ShaderWriter Outdent() IndentLevel--; return this; } - + /// /// Appends the specified text. /// @@ -96,7 +96,7 @@ protected ShaderWriter Append(string text) StringBuilder.Append(text); return this; } - + /// /// Closes the brace. /// @@ -128,7 +128,7 @@ protected ShaderWriter OpenBrace() Indent(); return this; } - + /// /// Writes the line. /// @@ -167,7 +167,7 @@ public ShaderWriter WriteLine(string text) return this; } - + /// /// Writes the space. /// @@ -179,7 +179,7 @@ public ShaderWriter WriteSpace() Append(" "); return this; } - + /// /// Writes the specified text. /// @@ -195,7 +195,7 @@ public ShaderWriter Write(string text) Append(text); return this; } - + /// /// Writes the content of the statement. /// @@ -215,7 +215,7 @@ protected void WriteStatementContent(Statement statement) Outdent(); } } - + public override void VisitIdentifier(Identifier identifier) { Write(identifier.Name); @@ -447,7 +447,7 @@ public override void VisitShaderClass(ShaderClass shaderClass) if (i < shaderClass.Mixins.Count - 1) Write(",").WriteSpace(); } } - + WriteLine(); OpenBrace(); foreach (var element in shaderClass.Elements) @@ -473,7 +473,7 @@ public override void VisitShaderMember(ShaderMember shaderMember) if (shaderMember.IsStaged) Write("stage").WriteSpace(); if (shaderMember.StreamKind != StreamKind.None) Write(shaderMember.StreamKind.ToString().ToLowerInvariant()).WriteSpace(); if (shaderMember.StorageClass != StorageClass.None) Write(shaderMember.StorageClass.ToString().ToLowerInvariant()).WriteSpace(); - + VisitNode(shaderMember.TypeName); WriteSpace(); VisitNode(shaderMember.Name); @@ -504,7 +504,7 @@ public override void VisitShaderMethod(ShaderMethod shaderMethod) if (i < shaderMethod.Parameters.Count - 1) Write(",").WriteSpace(); } Write(")"); - + if (shaderMethod.Body != null) { WriteLine(); @@ -616,7 +616,7 @@ public override void VisitIf(If @if) WriteLine(")"); WriteStatementContent(@if.Body); } - + public override void VisitElseIf(ElseIf elseIf) { Write("else if").WriteSpace().Write("("); @@ -624,7 +624,7 @@ public override void VisitElseIf(ElseIf elseIf) WriteLine(")"); WriteStatementContent(elseIf.Body); } - + public override void VisitElse(Else @else) { WriteLine("else"); @@ -635,9 +635,9 @@ public override void DefaultVisit(Node node) { //throw new NotImplementedException($"No shader text writer for {node.GetType().Name}"); } - + protected ShaderWriter WriteLinkLine(Node node) { return this; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs index 573c39a957..7316ce678c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs @@ -13,4 +13,4 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(functionType.ReturnType), context.Bound++, buffer.Id, x.Id, null, [])); return new(loadResult.ResultId, loadResult.ResultType); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 60fdb9ee27..c41fd17324 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -26,14 +26,14 @@ public abstract class Expression(TextLocation info) : ValueNode(info) /// /// public virtual void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) => throw new NotImplementedException($"Symbol table cannot process type : {GetType().Name}"); - + public SpirvValue Compile(SymbolTable table, CompilerUnit compiler, SymbolType? expectedType = null) { if (Type == null) throw new InvalidOperationException($"{nameof(ProcessSymbol)} was not called on expression {this} or type resolution failed"); - + var result = CompileImpl(table, compiler); - + // Check types are matching if (result.TypeId != 0 && Type != compiler.Context.ReverseTypes[result.TypeId]) throw new InvalidOperationException($"{nameof(ProcessSymbol)} computed type {Type} but {nameof(Compile)} created a value of type {compiler.Context.ReverseTypes[result.TypeId]} on expression {this}"); @@ -95,7 +95,7 @@ public partial class MethodCall(Identifier name, ShaderExpressionList arguments, { public Identifier Name = name; public ShaderExpressionList Arguments = arguments; - + public SymbolType? MemberCallBaseType { get; set; } public SpirvValue? MemberCall { get; set; } @@ -104,7 +104,7 @@ public partial class MethodCall(Identifier name, ShaderExpressionList arguments, private IIntrinsicCompiler? resolvedIntrinsicCompiler; private string? resolvedIntrinsicNamespace; private IntrinsicTemplateExpander.IntrinsicOverload? resolvedIntrinsicOverload; - + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { ProcessParameterSymbols(table); @@ -112,7 +112,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = var argumentValueTypes = new SymbolType[arguments.Values.Count]; for (int i = 0; i < arguments.Values.Count; ++i) argumentValueTypes[i] = arguments.Values[i].ValueType; - + if (TryResolveFunctionSymbol(table, argumentValueTypes, out var functionSymbol)) { var functionType = (FunctionType)functionSymbol.Type; @@ -154,7 +154,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var functionType = resolvedIntrinsicOverload != null ? resolvedIntrinsicOverload.Value.Type : (FunctionType)functionSymbol.Type; Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; - + ProcessInputArguments(table, compiler, functionType, compiledParams, functionSymbol?.MethodDefaultParameters); SpirvValue result; @@ -190,7 +190,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams, MethodSymbolDefaultParameters? methodDefaultParameters = null) { var (builder, context) = compiler; - + if (arguments.Values.Count > functionType.ParameterTypes.Count) throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); @@ -219,7 +219,7 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); } - + compiledParams[i] = paramVariable; } else @@ -232,11 +232,11 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F compiledParams[i] = paramSource.Id; } } - + // Find default parameters decoration (if any) var missingParameters = functionType.ParameterTypes.Count - arguments.Values.Count; var defaultParameters = 0; - if (missingParameters > 0 && methodDefaultParameters is {} methodDefaultParametersValue) + if (missingParameters > 0 && methodDefaultParameters is { } methodDefaultParametersValue) { // Is there enough parameters now? if (missingParameters <= methodDefaultParametersValue.DefaultValues.Length) @@ -253,7 +253,7 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F var bufferForConstant = methodDefaultParametersValue.SourceContext.ExtractConstantAsSpirvBuffer(source); source = context.InsertWithoutDuplicates(null, bufferForConstant); } - + var paramVariable = context.Bound++; builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); builder.Insert(new OpStore(paramVariable, source, null, [])); @@ -263,11 +263,11 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F missingParameters = 0; } } - + if (missingParameters > 0) throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); } - + protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams) { var (builder, context) = compiler; @@ -297,20 +297,20 @@ public static int OverloadScore(FunctionType functionType, int defaultParameters // Check argument count if (argumentValueTypes.Length > functionType.ParameterTypes.Count || argumentValueTypes.Length < functionType.ParameterTypes.Count + defaultParameters) return int.MaxValue; - + // Check if argument can be converted var score = 0; for (var index = 0; index < argumentValueTypes.Length; index++) { var argumentValueType = argumentValueTypes[index]; - var parameter = functionType.ParameterTypes[index]; + var parameter = functionType.ParameterTypes[index]; var argScore = SpirvBuilder.CanConvertScore(argumentValueType, parameter.Type.GetValueType()); if (argScore == int.MaxValue) return int.MaxValue; score += argScore; } - + // method with fewer optional parameters that need to be filled in by default values is generally preferred score += functionType.ParameterTypes.Count - argumentValueTypes.Length; @@ -476,7 +476,7 @@ var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate } } - public override string ToString() => $"{Operator.ToSymbol()}{Expression}"; + public override string ToString() => $"{Operator.ToSymbol()}{Expression}"; } public partial class CastExpression(TypeName typeName, Operator op, Expression expression, TextLocation info) : PrefixExpression(op, expression, info) @@ -502,7 +502,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) return builder.Convert(context, value, castType); } - public override string ToString() => $"({TypeName}){Expression}"; + public override string ToString() => $"({TypeName}){Expression}"; } @@ -545,11 +545,11 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal // Compute the l-value (and all its intermediate values) CompileHelper(table, compiler); - + // Only things left should be: // - RWBuffer/Texture setters // - Swizzles - + // Process from end for (var i = Accessors.Count - 1; i >= 0; --i) { @@ -567,38 +567,38 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal builder.Insert(new OpStore(lvalueResult.Id, rvalue.Id, null, [])); return; } - + switch (currentValueType, accessor) { case (PointerType { BaseType: BufferType bufferType }, IndexerExpression indexer): - { - var resultType = new VectorType(bufferType.BaseType, 4); - var buffer = builder.AsValue(context, lvalueBase); - - var location = indexer.Index.CompileAsValue(table, compiler); - location = builder.Convert(context, location, ScalarType.Int); - var bufferValue = builder.Convert(context, rvalue, resultType); - builder.Insert(new OpImageWrite(buffer.Id, location.Id, bufferValue.Id, null, [])); - // We stop there - return; - } + { + var resultType = new VectorType(bufferType.BaseType, 4); + var buffer = builder.AsValue(context, lvalueBase); + + var location = indexer.Index.CompileAsValue(table, compiler); + location = builder.Convert(context, location, ScalarType.Int); + var bufferValue = builder.Convert(context, rvalue, resultType); + builder.Insert(new OpImageWrite(buffer.Id, location.Id, bufferValue.Id, null, [])); + // We stop there + return; + } // ImageWrite case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): - { - var resultType = new VectorType(textureType.ReturnType, 4); - var image = builder.AsValue(context, lvalueBase); - - var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); - var texelValue = builder.Convert(context, rvalue, resultType); - builder.Insert(new OpImageWrite(image.Id, imageCoordValue.Id, texelValue.Id, null, [])); - // We stop there - return; - } + { + var resultType = new VectorType(textureType.ReturnType, 4); + var image = builder.AsValue(context, lvalueBase); + + var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); + var texelValue = builder.Convert(context, rvalue, resultType); + builder.Insert(new OpImageWrite(image.Id, imageCoordValue.Id, texelValue.Id, null, [])); + // We stop there + return; + } case (PointerType { BaseType: MatrixType } or MatrixType, Identifier { Name: var swizzle } id) when id.IsMatrixSwizzle((MatrixType)currentValueType.GetValueType(), out var swizzles): throw new NotImplementedException("Assign back to matrix swizzle is not implemented yet"); case (PointerType { BaseType: VectorType or ScalarType } or VectorType or ScalarType, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): // Swizzle: we transform the value to assign accordingly - + // We load the original value (if pointer) var lvalueType = currentValueType; if (lvalueType is PointerType p) @@ -606,7 +606,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal lvalueBase = new(builder.InsertData(new OpLoad(context.GetOrRegister(p.BaseType), context.Bound++, lvalueBase.Id, null, []))); lvalueType = p.BaseType; } - + // Shuffle with new data switch (lvalueType) { @@ -627,7 +627,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal break; } } - + // Need to assign to Source if (Source.Type is PointerType expectedType2) { @@ -635,7 +635,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal builder.Insert(new OpStore(intermediateValues[0].Id, rvalue.Id, null, [])); return; } - + // We should not reach this point (unless we can't write back to lvalue) ThrowErrorOnLValue(); } @@ -683,7 +683,7 @@ void PushAccessChainId(Span accessChainIds, int accessChainIndex) throw new InvalidOperationException(); accessChainIds[accessChainIdCount++] = accessChainIndex; } - + void EmitOpAccessChain(Span accessChainIds, int? intermediateValueIndex) { if (compiler == null) @@ -694,7 +694,7 @@ void EmitOpAccessChain(Span accessChainIds, int? intermediateValueIndex) var resultType = compiler.Context.GetOrRegister(currentValueType); var accessChain = compiler.Builder.Insert(new OpAccessChain(resultType, compiler.Context.Bound++, result.Id, [.. accessChainIds.Slice(0, accessChainIdCount)])); result = new SpirvValue(accessChain.ResultId, resultType); - + if (intermediateValueIndex != null) intermediateValues[1 + intermediateValueIndex.Value] = result; } @@ -710,14 +710,14 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso && Accessors[i] is Identifier { Name: var swizzle1 } id1 && id1.IsVectorSwizzle() && Accessors[i + 1] is Identifier { Name: var swizzle2 } id2 && id2.IsVectorSwizzle()) { - var vectorOrScalarType = currentValueType is PointerType p ? p.BaseType : currentValueType; - + var vectorOrScalarType = currentValueType is PointerType p ? p.BaseType : currentValueType; + (var size, ScalarType baseType) = vectorOrScalarType switch { ScalarType s => (1, s), VectorType v => (v.Size, v.BaseType), }; - + var swizzleIndices = new int[swizzle1.Length]; for (int j = 0; j < swizzle1.Length; ++j) { @@ -725,7 +725,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso if (swizzleIndices[j] >= size) throw new InvalidOperationException($"Swizzle {Accessors[i]} is out of bound for expression {ToString(i)} of type {vectorOrScalarType}"); } - + // Combine swizzles with previous ones var newSwizzleIndices = new int[swizzle2.Length]; for (int j = 0; j < swizzle2.Length; ++j) @@ -760,105 +760,105 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso switch (currentValueType, accessor) { case (PointerType { BaseType: BufferType or TextureType } pointerType, IndexerExpression indexer): - { - if (compiler == null) { - indexer.Index.ProcessSymbol(table); + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + + // Note: Texture.Load expects one more coordinate + // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) + var indexerType = pointerType.BaseType is TextureType + ? indexer.Index.ValueType!.GetElementType().GetVectorOrScalar(indexer.Index.ValueType!.GetElementCount() + 1) + : indexer.Index.ValueType!; + + if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType], out var resolvedIntrinsic2)) + throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); + accessor.Type = resolvedIntrinsic2.Overload.Type.ReturnType; + break; + } + + var (builder, context) = compiler; + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); // Note: Texture.Load expects one more coordinate // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) - var indexerType = pointerType.BaseType is TextureType + var indexerType2 = pointerType.BaseType is TextureType ? indexer.Index.ValueType!.GetElementType().GetVectorOrScalar(indexer.Index.ValueType!.GetElementCount() + 1) : indexer.Index.ValueType!; - - if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType], out var resolvedIntrinsic2)) + + if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType2], out var resolvedIntrinsic)) throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); - accessor.Type = resolvedIntrinsic2.Overload.Type.ReturnType; - break; - } - var (builder, context) = compiler; + // Generate Load parameter + var indexValue = indexer.Index.CompileAsValue(table, compiler); + var texcoordType = resolvedIntrinsic.Overload.Type.ParameterTypes[0].Type; + if (pointerType.BaseType is TextureType) + { + // Find expected type for array (same as Load() but with 1 less component) + var texcoordSize = texcoordType.GetElementCount(); + indexValue = builder.Convert(context, indexValue, texcoordType.GetElementType().GetVectorOrScalar(texcoordSize - 1)); + + Span values = stackalloc int[texcoordSize]; + for (int j = 0; j < texcoordSize - 1; ++j) + values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; + values[^1] = context.CompileConstant((int)0).Id; + indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [.. values]))); + } + else + { + indexValue = builder.Convert(context, indexValue, texcoordType); + } - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - - // Note: Texture.Load expects one more coordinate - // i.e. tex[coord.xy] => tex.Load(int3(coord.xy, 0)) - var indexerType2 = pointerType.BaseType is TextureType - ? indexer.Index.ValueType!.GetElementType().GetVectorOrScalar(indexer.Index.ValueType!.GetElementCount() + 1) - : indexer.Index.ValueType!; - - if (!IntrinsicCallHelper.TryResolveIntrinsic(table, pointerType.BaseType, "Load", [indexerType2], out var resolvedIntrinsic)) - throw new InvalidOperationException($"Unable to resolve intrinsic Load for type {pointerType.BaseType}"); - - // Generate Load parameter - var indexValue = indexer.Index.CompileAsValue(table, compiler); - var texcoordType = resolvedIntrinsic.Overload.Type.ParameterTypes[0].Type; - if (pointerType.BaseType is TextureType) - { - // Find expected type for array (same as Load() but with 1 less component) - var texcoordSize = texcoordType.GetElementCount(); - indexValue = builder.Convert(context, indexValue, texcoordType.GetElementType().GetVectorOrScalar(texcoordSize - 1)); - - Span values = stackalloc int[texcoordSize]; - for (int j = 0; j < texcoordSize - 1; ++j) - values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; - values[^1] = context.CompileConstant((int)0).Id; - indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [..values]))); - } - else - { - indexValue = builder.Convert(context, indexValue, texcoordType); - } + result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, result, [indexValue.Id]); + accessor.Type = resolvedIntrinsic.Overload.Type.ReturnType; - result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, result, [indexValue.Id]); - accessor.Type = resolvedIntrinsic.Overload.Type.ReturnType; - - break; - } + break; + } case (PointerType { BaseType: StructuredBufferType bufferType }, IndexerExpression indexer): - { - if (compiler == null) { - indexer.Index.ProcessSymbol(table); - accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(bufferType.BaseType, Specification.StorageClass.StorageBuffer); + break; + } + + // StructuredBuffer are declared as OpTypeStruct { OpTypeRuntimeArray } + // so first, we push a 0 to access the OpTypeRuntimeArray + PushAccessChainId(accessChainIds, compiler.Context.CompileConstant(0).Id); + // Then we push the index inside the array + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); break; } - - // StructuredBuffer are declared as OpTypeStruct { OpTypeRuntimeArray } - // so first, we push a 0 to access the OpTypeRuntimeArray - PushAccessChainId(accessChainIds, compiler.Context.CompileConstant(0).Id); - // Then we push the index inside the array - var indexerValue = indexer.Index.CompileAsValue(table, compiler); - PushAccessChainId(accessChainIds, indexerValue.Id); - break; - } case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, MethodCall { Name.Name: "Append", Arguments.Values.Count: 1 } methodCall): - { - if (compiler == null) { - ((MethodCall)accessor).ProcessParameterSymbols(table, null); - accessor.Type = ScalarType.Void; - break; - } + if (compiler == null) + { + ((MethodCall)accessor).ProcessParameterSymbols(table, null); + accessor.Type = ScalarType.Void; + break; + } - var (builder, context) = compiler; + var (builder, context) = compiler; - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); - var output = methodCall.Arguments.Values[0].CompileAsValue(table, compiler); - var streamsType = (StreamsType)methodCall.Arguments.Values[0].ValueType!; - // Note: if it was a Streams, implicit cast it to Output - if (streamsType.Kind == StreamsKindSDSL.Streams) - output = new(builder.InsertData(new OpCopyLogical(context.GetOrRegister(new StreamsType(StreamsKindSDSL.Output)), context.Bound++, output.Id))); - else if (streamsType.Kind == StreamsKindSDSL.Input) - throw new InvalidOperationException("StreamOutput.Append() only accepts Streams or Output objects"); - builder.Insert(new OpEmitVertexSDSL(output.Id)); - result = default; - break; - } + var output = methodCall.Arguments.Values[0].CompileAsValue(table, compiler); + var streamsType = (StreamsType)methodCall.Arguments.Values[0].ValueType!; + // Note: if it was a Streams, implicit cast it to Output + if (streamsType.Kind == StreamsKindSDSL.Streams) + output = new(builder.InsertData(new OpCopyLogical(context.GetOrRegister(new StreamsType(StreamsKindSDSL.Output)), context.Bound++, output.Id))); + else if (streamsType.Kind == StreamsKindSDSL.Input) + throw new InvalidOperationException("StreamOutput.Append() only accepts Streams or Output objects"); + builder.Insert(new OpEmitVertexSDSL(output.Id)); + result = default; + break; + } case (PointerType { BaseType: GeometryStreamType geometryStreamOutput }, MethodCall { Name.Name: "RestartStrip", Arguments.Values.Count: 0 }): if (compiler == null) @@ -881,37 +881,37 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso methodCall.ProcessSymbol(table); break; } - + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); methodCall.MemberCall = result; result = methodCall.Compile(table, compiler); break; case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): - { - if (compiler == null) { - if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) + if (compiler == null) { - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0112, field.Name, new AccessorChainExpression(Source, info) { Accessors = Accessors[0..i] }, currentValueType))); - return default; + if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) + { + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0112, field.Name, new AccessorChainExpression(Source, info) { Accessors = Accessors[0..i] }, currentValueType))); + return default; + } + + field.ResolvedSymbol = matchingComponent; + accessor.Type = matchingComponent.Type; + break; } - field.ResolvedSymbol = matchingComponent; - accessor.Type = matchingComponent.Type; + var (builder, context) = compiler; + var importedVariable = LoadedShaderSymbol.ImportSymbol(table, context, field.ResolvedSymbol); + + // Emit OpAccessChain with everything so far + EmitOpAccessChain(accessChainIds, i - 1); + + // TODO: figure out instance (this vs composition) + result = IdentifierBase.EmitSymbol(builder, context, importedVariable, false, result.Id); break; } - - var (builder, context) = compiler; - var importedVariable = LoadedShaderSymbol.ImportSymbol(table, context, field.ResolvedSymbol); - - // Emit OpAccessChain with everything so far - EmitOpAccessChain(accessChainIds, i - 1); - - // TODO: figure out instance (this vs composition) - result = IdentifierBase.EmitSymbol(builder, context, importedVariable, false, result.Id); - break; - } case (PointerType { BaseType: StreamsType s } p, Identifier streamVar): if (compiler == null) { @@ -955,58 +955,58 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; // Swizzles case (PointerType { BaseType: MatrixType m } p, Identifier id) when id.IsMatrixSwizzle(m, out var swizzles): - { - if (swizzles.Count > 1) { - if (compiler == null) + if (swizzles.Count > 1) { - if (swizzles.Count > 4) + if (compiler == null) { - table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); - return default; + if (swizzles.Count > 4) + { + table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + return default; + } + + accessor.Type = new VectorType(m.BaseType, swizzles.Count); + break; } - accessor.Type = new VectorType(m.BaseType, swizzles.Count); - break; + var (builder, context) = compiler; + EmitOpAccessChain(accessChainIds, i - 1); + (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); } - - var (builder, context) = compiler; - EmitOpAccessChain(accessChainIds, i - 1); - (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); - } - else - { - // Keep as a pointer - if (compiler == null) + else { - accessor.Type = new PointerType(m.BaseType, p.StorageClass); - break; + // Keep as a pointer + if (compiler == null) + { + accessor.Type = new PointerType(m.BaseType, p.StorageClass); + break; + } + + var (builder, context) = compiler; + PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Column).Id); + PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Row).Id); } - - var (builder, context) = compiler; - PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Column).Id); - PushAccessChainId(accessChainIds, context.CompileConstant(swizzles[0].Row).Id); + break; } - break; - } case (MatrixType m, Identifier id) when id.IsMatrixSwizzle(m, out var swizzles): - { - if (compiler == null) { - if (swizzles.Count > 4) + if (compiler == null) { - table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); - return default; + if (swizzles.Count > 4) + { + table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + return default; + } + + accessor.Type = m.BaseType.GetVectorOrScalar(swizzles.Count); + break; } - accessor.Type = m.BaseType.GetVectorOrScalar(swizzles.Count); + var (builder, context) = compiler; + (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); break; } - - var (builder, context) = compiler; - (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); - break; - } case (PointerType { BaseType: VectorType v } p, Identifier { Name: var swizzle } id) when id.IsVectorSwizzle(): if (swizzle.Length > 1) { @@ -1192,17 +1192,17 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } case (PointerType { BaseType: PatchType { BaseType: var t } } p, IndexerExpression indexer): - { - if (compiler == null) { - indexer.Index.ProcessSymbol(table); - accessor.Type = new PointerType(t, p.StorageClass); + if (compiler == null) + { + indexer.Index.ProcessSymbol(table); + accessor.Type = new PointerType(t, p.StorageClass); + break; + } + var indexerValue = indexer.Index.CompileAsValue(table, compiler); + PushAccessChainId(accessChainIds, indexerValue.Id); break; } - var indexerValue = indexer.Index.CompileAsValue(table, compiler); - PushAccessChainId(accessChainIds, indexerValue.Id); - break; - } case (PointerType { BaseType: var type }, PostfixIncrement postfix): { if (compiler == null) @@ -1210,9 +1210,9 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso accessor.Type = type; break; } - + var (builder, context) = compiler; - + // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -1351,12 +1351,12 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = // TODO: review XOR/OR/Shift etc. _ => null, }; - + Left.ProcessSymbol(table, expectedOperandType); Right.ProcessSymbol(table, expectedOperandType); var analysisResult = SpirvBuilder.AnalyzeBinaryOperation(table, Left.ValueType, Op, Right.ValueType, info); - + // If type is different than expected, try again with proper type // this will help in some cases (i.e. emit literal as float instead of integer, which is necessary for constants) expectedOperandType = analysisResult?.OperandType; @@ -1394,7 +1394,7 @@ public partial class TernaryExpression(Expression cond, Expression left, Express public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { Condition.ProcessSymbol(table); - + if (Condition.ValueType.GetElementType() is not ScalarType) table.AddError(new(Condition.Info, SDSLErrorMessages.SDSL0106)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index 0a0d46b0bc..22649fd308 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -13,7 +13,7 @@ public class IntrinsicCallHelper { private static IntrinsicTemplateExpander? TemplateExpander { get; set; } private static Dictionary ClassTemplateExpanders = new(); - + public static bool TryResolveIntrinsic(SymbolTable table, SymbolType? thisType, string name, SymbolType[] argumentValueTypes, out (IIntrinsicCompiler Compiler, string Namespace, IntrinsicTemplateExpander.IntrinsicOverload Overload) resolvedIntrinsic) { resolvedIntrinsic = default; @@ -50,11 +50,11 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na BufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.BufferMethods), IntrinsicsDefinitions.BufferMethods), BufferMethodsImplementations.Instance), BufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWBufferMethods), IntrinsicsDefinitions.RWBufferMethods), BufferMethodsImplementations.Instance), - + StructuredBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.StructuredBufferMethods), IntrinsicsDefinitions.StructuredBufferMethods), null), StructuredBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWStructuredBufferMethods), IntrinsicsDefinitions.RWStructuredBufferMethods), null), }; - + if (!templateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) { return false; @@ -87,7 +87,7 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, IIntrinsicCompiler intrinsicCompiler, string @namespace, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, SpirvValue? thisValue, Span compiledParams) { var functionType = bestOverload.Type; - + // Check if we can automatically handle matrix (SPIR-V doesn't but HLSL does allow matrix on most types) SpirvValue result; if (bestOverload.AutoMatrixLoopLocations != null) @@ -95,7 +95,7 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil var (builder, context) = compiler; var innerFunctionType = new FunctionType(functionType.ReturnType, functionType.ParameterTypes.ToList()); - + // Extract rows bool isReturnUsingLoop = false; Span vectorValues = stackalloc int[bestOverload.AutoMatrixLoopLocations.Count * bestOverload.AutoMatrixLoopSize]; @@ -105,7 +105,7 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil if (location.TemplateIndex != 0) throw new InvalidOperationException("Matrix loop should only be generated for HLSL row parameter"); - + // Skip return type for now if (location.SourceArgument == 0) { @@ -124,10 +124,10 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil { vectorValues[index * bestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[location.SourceArgument - 1], [col])).ResultId; } - - innerFunctionType.ParameterTypes[location.SourceArgument - 1] = innerFunctionType.ParameterTypes[location.SourceArgument - 1] with { Type = vectorType }; + + innerFunctionType.ParameterTypes[location.SourceArgument - 1] = innerFunctionType.ParameterTypes[location.SourceArgument - 1] with { Type = vectorType }; } - + // Call core function Span results = stackalloc int[bestOverload.AutoMatrixLoopSize]; for (int col = 0; col < bestOverload.AutoMatrixLoopSize; col++) @@ -139,17 +139,17 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil continue; compiledParams[location.SourceArgument - 1] = vectorValues[index * bestOverload.AutoMatrixLoopSize + col]; } - + results[col] = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, innerFunctionType, thisValue, compiledParams).Id; } - + // Rebuild return value if (isReturnUsingLoop) { if (functionType.ReturnType is not MatrixType) throw new InvalidOperationException("Return type should be a matrix"); - - result = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(functionType.ReturnType), context.Bound++, [..results]))); + + result = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(functionType.ReturnType), context.Bound++, [.. results]))); } else { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index b8484312ef..a7473bb55a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -8,11 +8,11 @@ namespace Stride.Shaders.Parsing.SDSL; internal class IntrinsicImplementations : IntrinsicsDeclarations { public static IntrinsicImplementations Instance { get; } = new(); - + // Bool public override SpirvValue CompileAll(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAll); public override SpirvValue CompileAny(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAny); - + // Cast public override SpirvValue CompileAsfloat(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); public override SpirvValue CompileAsint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); @@ -29,18 +29,18 @@ public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder buil public override SpirvValue CompileAsuint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); // Trigo - public override SpirvValue CompileSin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); - public override SpirvValue CompileSinh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); - public override SpirvValue CompileAsin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); - public override SpirvValue CompileCos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); - public override SpirvValue CompileCosh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); - public override SpirvValue CompileAcos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); - public override SpirvValue CompileTan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTan, x); + public override SpirvValue CompileSin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); + public override SpirvValue CompileSinh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); + public override SpirvValue CompileAsin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); + public override SpirvValue CompileCos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + public override SpirvValue CompileCosh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); + public override SpirvValue CompileAcos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); + public override SpirvValue CompileTan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTan, x); public override SpirvValue CompileTanh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); public override SpirvValue CompileAtan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); public override SpirvValue CompileAtan2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); public override SpirvValue CompileSincos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c) => throw new NotImplementedException(); - + // Derivatives public override SpirvValue CompileDdx(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdx, x); public override SpirvValue CompileDdx_coarse(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdxCoarse, x); @@ -98,7 +98,7 @@ public override SpirvValue CompileClamp(SpirvContext context, SpirvBuilder build public override SpirvValue CompileRadians(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRadians, x); public override SpirvValue CompileDegrees(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLDegrees, x); - + public override SpirvValue CompileExp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp, x); public override SpirvValue CompileExp2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp2, x); public override SpirvValue CompileLog(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog, x); @@ -178,7 +178,7 @@ public override SpirvValue CompileFaceforward(SpirvContext context, SpirvBuilder var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GetGLSL(), N.Id, I.Id, Ng.Id)); return new(instruction.ResultId, instruction.ResultType); } - + public override SpirvValue CompileRound(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRound, x); public override SpirvValue CompileRsqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLInverseSqrt, x); public override SpirvValue CompileSqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSqrt, x); @@ -227,7 +227,7 @@ public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builde return new(instruction.ResultId, instruction.ResultType); } public override SpirvValue CompileFrac(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFract, x); - + // Compute Barriers const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; @@ -238,7 +238,7 @@ public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builde public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); public override SpirvValue CompileGroupMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); - + // Compute interlocked public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value, original); public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value, original); @@ -257,7 +257,7 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build builder.Insert(new OpTerminateInvocation()); return new(); } - + public override SpirvValue CompileD3DCOLORtoUBYTE4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileGetRenderTargetSampleCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileGetRenderTargetSamplePosition(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s) => throw new NotImplementedException(); @@ -332,7 +332,7 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileWorldToObject3x4(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileObjectToWorld4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileWorldToObject4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - + // Wave public override SpirvValue CompileWaveIsFirstLane(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileWaveGetLaneIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); @@ -361,7 +361,7 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileWaveMultiPrefixCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); public override SpirvValue CompileWaveMultiPrefixProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); public override SpirvValue CompileWaveMultiPrefixSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - + // Obsolete public override SpirvValue CompileDst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); @@ -392,7 +392,7 @@ public static SpirvValue CompileFloatUnaryCall(SpirvContext context, SpirvBuilde instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } - + public static SpirvValue CompileGLSLFloatUnaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x) { var instruction = builder.Insert(new GLSLExp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); @@ -408,7 +408,7 @@ public static SpirvValue MultiplyConstant(SpirvContext context, SpirvBuilder bui var instruction2 = builder.Insert(new OpFMul(context.GetOrRegister(functionType.ReturnType), context.Bound++, value.Id, constant.Id)); return new SpirvValue(instruction2.ResultId, instruction2.ResultType); } - + public static SpirvValue CompileGLSLFloatBinaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) { var instruction = builder.Insert(new GLSLPow(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, y.Id)); @@ -422,7 +422,7 @@ public static SpirvValue CompileBitcastCall(SpirvContext context, SpirvBuilder b var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); return new(instruction.ResultId, instruction.ResultType); } - + public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) { var destType = context.ReverseTypes[dest.TypeId]; @@ -445,8 +445,8 @@ public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuild } else { - var instruction = builder.Insert(new OpAtomicIAdd(context.GetOrRegister(resultType), context.Bound++, dest.Id, - context.CompileConstant((int)Specification.Scope.Device).Id, + var instruction = builder.Insert(new OpAtomicIAdd(context.GetOrRegister(resultType), context.Bound++, dest.Id, + context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, value.Id)); // Update instruction type (they all share same memory layout) @@ -464,19 +464,19 @@ public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuild } // Out parameter? - if (originalLocation is {} originalLocationValue) + if (originalLocation is { } originalLocationValue) { var originalLocationType = context.ReverseTypes[originalLocationValue.TypeId]; if (originalLocationType is not PointerType originalLocationPointerType) throw new InvalidOperationException($"out parameter is not a l-value, got {originalLocationType} instead"); - + originalValue = builder.Convert(context, originalValue, originalLocationPointerType.BaseType); builder.Insert(new OpStore(originalLocationValue.Id, originalValue.Id, null, [])); } return new(); } - + public static SpirvValue CompileMemoryBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) { builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); @@ -487,7 +487,7 @@ public static SpirvValue CompileControlBarrierCall(SpirvContext context, SpirvBu builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } - + public static SpirvValue CompileBoolToScalarBoolCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, Specification.Op op) { // We handle matrix specifically in this case (auto loop doesn't work since it's not per item) @@ -506,9 +506,9 @@ public static SpirvValue CompileBoolToScalarBoolCall(SpirvContext context, Spirv vectorBools[i] = instruction2.ResultId; } - x = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(new VectorType(ScalarType.Boolean, m.Columns)), context.Bound++, [..vectorBools]))); + x = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(new VectorType(ScalarType.Boolean, m.Columns)), context.Bound++, [.. vectorBools]))); } - + var parameterType = context.ReverseTypes[x.TypeId].WithElementType(ScalarType.Boolean); x = builder.Convert(context, x, parameterType); @@ -516,4 +516,4 @@ public static SpirvValue CompileBoolToScalarBoolCall(SpirvContext context, Spirv instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index 134f541102..e895538637 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -12,7 +12,7 @@ namespace Stride.Shaders.Parsing.SDSL; public class IntrinsicTemplateExpander(SymbolType? thisType, string @namespace, FrozenDictionary intrinsicsDefinitions) { public string Namespace { get; } = @namespace; - + record SizePermutationGenerator(string? Name, List Sizes, List<(int SourceArgument, int TemplateIndex)> Locations) { public IEnumerable Generate() @@ -39,7 +39,7 @@ record SizePermutation(int Size, SizePermutationGenerator Generator); record BaseTypePermutation(SymbolType Type, BaseTypePermutationGenerator Generator); record struct SizeValue(int Value, SizePermutationGenerator Generator); - + public record struct IntrinsicOverload(FunctionType Type, List<(int SourceArgument, int TemplateIndex)>? AutoMatrixLoopLocations, int AutoMatrixLoopSize); Dictionary> intrinsicDefinitionsCache = new(); @@ -57,7 +57,7 @@ public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(fal result = null; return false; } - + result = new(); foreach (var intrinsicDefinition in intrinsicDefinitions) { @@ -67,14 +67,14 @@ public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(fal void AddVectorSizePermutation(int argument, int templateIndex, string name) { SizePermutationGenerator permutation; - + // name can be either a value (1,2,3,4,any) or a name (when multiple slots adjusted with same permutation, in which case value is [1,2,3,4]). switch (name) { case "any" or "1" or "2" or "3" or "4": permutation = new SizePermutationGenerator(null, name switch { - "any" => [1,2,3,4], + "any" => [1, 2, 3, 4], "1" => [1], "2" => [2], "3" => [3], @@ -87,7 +87,7 @@ void AddVectorSizePermutation(int argument, int templateIndex, string name) permutation = sizePermutationGenerators.FirstOrDefault(x => x.Name == name); if (permutation == null) { - permutation = new SizePermutationGenerator(name, [1,2,3,4], new()); + permutation = new SizePermutationGenerator(name, [1, 2, 3, 4], new()); sizePermutationGenerators.Add(permutation); } break; @@ -104,13 +104,13 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) { var parameterType = index > 0 ? intrinsicDefinition.Parameters[index - 1].Type : intrinsicDefinition.Return; - + // Find which part can permutate freely var isLayoutFree = parameterType.Match == null || parameterType.Match.Value.Layout == index; var isBaseTypeFree = parameterType.Match == null || parameterType.Match.Value.BaseType == index; //var isVectorSizeFree = parameterType.Match == null || parameterType.Match.Value.Size == 0; - if (parameterType.VectorSize is {} vectorSize) + if (parameterType.VectorSize is { } vectorSize) { // Note: even if size is set using match (isLayoutFree is true), it can still be overriden (value is anything else than "any") so check for it if (isLayoutFree || vectorSize.X != "any") @@ -122,46 +122,46 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) } } } - + if (isBaseTypeFree) { SymbolType[] baseTypes = parameterType.BaseType switch { - BaseType.Bool => [ ScalarType.Boolean ], - BaseType.Int => [ ScalarType.Int ], - BaseType.Int32Only => [ ScalarType.Int ], + BaseType.Bool => [ScalarType.Boolean], + BaseType.Int => [ScalarType.Int], + BaseType.Int32Only => [ScalarType.Int], BaseType.Int16 => throw new NotImplementedException(), - BaseType.Int64 => [ ScalarType.Int64 ], - BaseType.SInt16Or32 => [ ScalarType.Int ], - BaseType.AnyInt => [ ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64 ], - BaseType.AnyInt16Or32 => [ ScalarType.Int, ScalarType.UInt ], - BaseType.AnyInt32 => [ ScalarType.Int, ScalarType.UInt ], - BaseType.AnyInt64 => [ ScalarType.Int64, ScalarType.UInt64 ], - BaseType.Int64Only => [ ScalarType.Int64 ], - BaseType.Uint => [ ScalarType.UInt ], + BaseType.Int64 => [ScalarType.Int64], + BaseType.SInt16Or32 => [ScalarType.Int], + BaseType.AnyInt => [ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64], + BaseType.AnyInt16Or32 => [ScalarType.Int, ScalarType.UInt], + BaseType.AnyInt32 => [ScalarType.Int, ScalarType.UInt], + BaseType.AnyInt64 => [ScalarType.Int64, ScalarType.UInt64], + BaseType.Int64Only => [ScalarType.Int64], + BaseType.Uint => [ScalarType.UInt], BaseType.Uint16 => throw new NotImplementedException(), - BaseType.U64 => [ ScalarType.UInt64 ], - BaseType.Float => [ ScalarType.Float ], + BaseType.U64 => [ScalarType.UInt64], + BaseType.Float => [ScalarType.Float], BaseType.Float16 => throw new NotImplementedException(), - BaseType.AnyFloat => [ ScalarType.Float, ScalarType.Double ], - BaseType.FloatLike => [ ScalarType.Float ], - BaseType.Float32Only => [ ScalarType.Float ], - BaseType.DoubleOnly => [ ScalarType.Double ], - BaseType.Sampler1d => throw new NotImplementedException(), + BaseType.AnyFloat => [ScalarType.Float, ScalarType.Double], + BaseType.FloatLike => [ScalarType.Float], + BaseType.Float32Only => [ScalarType.Float], + BaseType.DoubleOnly => [ScalarType.Double], + BaseType.Sampler1d => throw new NotImplementedException(), BaseType.Sampler2d => throw new NotImplementedException(), BaseType.Sampler3d => throw new NotImplementedException(), BaseType.SamplerCube => throw new NotImplementedException(), - BaseType.SamplerCmp => [ new SamplerType() ], - BaseType.Sampler => [ new SamplerType() ], - BaseType.AnySampler => [ new SamplerType() ], + BaseType.SamplerCmp => [new SamplerType()], + BaseType.Sampler => [new SamplerType()], + BaseType.AnySampler => [new SamplerType()], BaseType.Wave => throw new NotImplementedException(), - BaseType.Void => [ ScalarType.Void ], + BaseType.Void => [ScalarType.Void], BaseType.Texture2D => throw new NotImplementedException(), - BaseType.UIntOnly => [ ScalarType.UInt, ScalarType.UInt64 ], - BaseType.Numeric => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64 ], + BaseType.UIntOnly => [ScalarType.UInt, ScalarType.UInt64], + BaseType.Numeric => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64], BaseType.Numeric16Only => throw new NotImplementedException(), - BaseType.Numeric32Only => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt ], - BaseType.Any => [ ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean ], + BaseType.Numeric32Only => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt], + BaseType.Any => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean], BaseType.Match => throw new InvalidOperationException(), BaseType.ByteAddressBuffer => throw new NotImplementedException(), BaseType.RWByteAddressBuffer => throw new NotImplementedException(), @@ -173,7 +173,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) AddBaseTypePermutation(index, baseTypes); } } - + // Step 2: generate permutations for base types var baseTypeSequences = new List>(); foreach (var baseTypePermutationGenerator in baseTypePermutationGenerators) @@ -185,7 +185,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) foreach (var sizePermutationGenerator in sizePermutationGenerators) sizeSequences.Add(new(sizePermutationGenerator.Generate())); var sizePermutations = CartesianProduct.Generate(sizeSequences); - + // Step 4: generate signature using permutations ParameterTypeInfo[] parameterTypeHelper = new ParameterTypeInfo[intrinsicDefinition.Parameters.Length + 1]; SymbolType[] parameterTypes = new SymbolType[intrinsicDefinition.Parameters.Length + 1]; @@ -195,7 +195,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) // Use base type permutations to fill initial types foreach (var baseTypePermutation in baseTypePermutationList) parameterTypeHelper[baseTypePermutation.Generator.SourceArgument].BaseType = baseTypePermutation.Type; - + // Set other parameters (which might use initial types) // Only Match type should be left for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) @@ -209,9 +209,9 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) throw new InvalidOperationException($"Intrinsic {name}: Can't resolve parameter {index} of type {parameterType}"); parameterTypeHelper[index].BaseType = parameterTypeHelper[parameterType.Match.Value.BaseType].BaseType; - } + } } - + // Now, iterate on size permutations bool firstIteration = true; foreach (var sizePermutationList in sizePermutations) @@ -222,7 +222,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) parameterTypeHelper[index].Size1 = default; parameterTypeHelper[index].Size2 = default; } - + foreach (var sizePermutation in sizePermutationList) { foreach (var location in sizePermutation.Generator.Locations) @@ -284,12 +284,12 @@ ParameterTypeInfo GetParameterInfo(int index) SizePermutationGenerator? autoMatrixLoop = null; FunctionType? autoMatrixLoopType = null; int autoMatrixLoopSize = 0; - + // Generate real types using sizes for (var index = 0; index < intrinsicDefinition.Parameters.Length + 1; index++) { ref var resolvedBaseType = ref parameterTypeHelper[index]; - + if (resolvedBaseType.Size1.Value > 1 && resolvedBaseType.Size2.Value > 1) { if (resolvedBaseType.Size1.Generator.Name == null) @@ -314,7 +314,7 @@ ParameterTypeInfo GetParameterInfo(int index) parameterTypes[index] = resolvedBaseType.BaseType; } } - + // Note: we remove auto matrix loop if result type is not either void or matrix of the desired size if (autoMatrixLoop != null) { @@ -334,17 +334,17 @@ ParameterTypeInfo GetParameterInfo(int index) })); } var functionType = new FunctionType(parameterTypes[0], functionParameters); - + result.Add(new(functionType, autoMatrixLoop?.Locations, autoMatrixLoopSize)); } } } - + intrinsicDefinitionsCache.Add(name, result); return true; } } - + /// /// Helper class to generate all permutations using cartesian product. /// @@ -382,4 +382,4 @@ private static void CartesianRecurse(List> accumulator, List curre } } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 5cbdf30e1f..a9123fee92 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -91,7 +91,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), value, null, info)); } - + return compiler.Context.CompileConstantLiteral(this); } } @@ -100,7 +100,7 @@ public sealed partial class FloatLiteral(Suffix suffix, double value, int? expon { public int? Exponent { get; set; } = exponent; public static implicit operator FloatLiteral(double v) => new(new(), v, null, new()); - + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { Type = SpirvContext.ComputeLiteralType(this); @@ -122,7 +122,7 @@ public partial class BoolLiteral(bool value, TextLocation info) : ScalarLiteral( { public bool Value { get; set; } = value; public override SymbolType? Type => ScalarType.Boolean; - + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { Type = ScalarType.Boolean; @@ -140,7 +140,7 @@ public partial class ExpressionLiteral(Expression value, TypeName typeName, Text { public Expression Value { get; set; } = value; public TypeName TypeName { get; set; } = typeName; - + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { TypeName.ProcessSymbol(table); @@ -192,7 +192,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // i.e. float3(float, float, float) is OK but float3(float, float2) is not as we don't know which element will be which before compiling them (we would need 2-pass compilation for that) var value = Values[i].CompileAsValue(table, compiler, expectedElementType); var valueType = Values[i].ValueType; - + // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) if (Type is ScalarType or VectorType or MatrixType) { @@ -303,10 +303,10 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { Type = expectedType; var expectedElementType = (expectedType as ArrayType)?.BaseType; - + foreach (var value in Values) value.ProcessSymbol(table, expectedElementType); - + if (Type == null && Values.Count > 0) Type = new ArrayType(Values[0].ValueType, Values.Count); @@ -343,7 +343,7 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, { if (symbol.IdRef == 0) throw new InvalidOperationException($"Symbol {symbol} has not been imported or created properly"); - + var resultType = context.GetOrRegister(symbol.Type); var result = new SpirvValue(symbol.IdRef, resultType, symbol.Id.Name); @@ -358,7 +358,7 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, result.Id = instance.Value; return result; } - + if (symbol.ExternalConstant is { } externalConstant) { if (externalConstant.SourceContext != context) @@ -423,7 +423,7 @@ protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder build public partial class Identifier(string name, TextLocation info) : IdentifierBase(name, info) { internal bool AllowStreamVariables { get; set; } - + public static implicit operator string(Identifier identifier) => identifier.Name; public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) @@ -468,7 +468,7 @@ protected override SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder buil var result = builder.Insert(new OpStreamsSDSL(context.Bound++)); return new(result.ResultId, context.GetOrRegister(new PointerType(new StreamsType(Specification.StreamsKindSDSL.Streams), Specification.StorageClass.Private))); } - + return base.CompileSymbol(table, builder, context, constantOnly); } @@ -565,7 +565,7 @@ public partial class GenericIdentifier(Identifier name, ShaderExpressionList? ge public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { var context = table.Context; - + var symbol = ResolveExternalShader(table, context, info, Name, Generics); if (symbol != null) @@ -582,7 +582,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = var type = new ExternalType(name, generics); return new Symbol(new(name, SymbolKind.ExternalType), type, 0); } - + // GenericIdentifier is same as Identifier static variable case, except we have generics (which is why GenericIdentifier was chosen over Identifier) var compiledGenerics = SDFX.AST.ShaderEffect.CompileGenerics(table, context, generics); var classSource = new ShaderClassInstantiation(name, compiledGenerics); @@ -593,7 +593,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0110, name))); return null; } - + if (!table.ShaderLoader.Exists(classSource.ClassName)) throw new InvalidOperationException($"Symbol [{classSource.ClassName}] could not be found."); @@ -624,7 +624,7 @@ public partial class TypeName(string name, TextLocation info) : Literal(info) public bool IsArray => ArraySize != null && ArraySize.Count > 0; public List? ArraySize { get; set; } public List Generics { get; set; } = []; - + public bool TryResolveType(SymbolTable table, SpirvContext context, [MaybeNullWhen(false)] out SymbolType symbolType) { if (Name == "LinkType") @@ -769,7 +769,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = Type = ResolveType(table, table.Context); } - + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) => throw new NotImplementedException(); public override string ToString() => GenerateTypeName(includeGenerics: true, includeArray: true); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index e5624dba47..26851d265f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -158,7 +158,7 @@ void RegisterName(int target, string name) fields.Add(new(name, type, TypeModifier.None)); } StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) - ? structName switch + ? structName switch { var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type), var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type, true), @@ -313,7 +313,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); var methodsDefaultParameters = new Dictionary(); var structTypes = new List<(StructuredType Type, int ImportedId)>(); - + // Build full inheritance list List inheritanceList = new(); SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context, inheritanceList, ResolveStep.Compile); @@ -338,18 +338,18 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte structTypes.Add(((StructuredType)shaderBuffers.Context.ReverseTypes[typeStructInstruction.ResultId], -1)); } else if (i.Op == Op.OpDecorate && (OpDecorate)i is - { - Decoration: Decoration.FunctionParameterDefaultValueSDSL, - Target: var target, - } decorateFunctionParameters) + { + Decoration: Decoration.FunctionParameterDefaultValueSDSL, + Target: var target, + } decorateFunctionParameters) { methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.DecorationParameters.Span.ToArray())); } else if (i.Op == Op.OpDecorate && (OpDecorate)i is - { - Decoration: Decoration.ShaderConstantSDSL, - Target: var target2, - } decorateShaderConstant) + { + Decoration: Decoration.ShaderConstantSDSL, + Target: var target2, + } decorateShaderConstant) { if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) throw new InvalidOperationException(); @@ -358,7 +358,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte variables.Add((symbol, VariableFlagsMask.None)); } } - + for (var index = 0; index < shaderBuffers.Buffer.Count; index++) { var instruction = shaderBuffers.Buffer[index]; @@ -403,7 +403,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderTyp { table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); } - + public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; @@ -413,7 +413,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var currentShader = new LoadedShaderSymbol(Name, openGenerics); table.Push(); table.CurrentShader = currentShader; - + var hasUnresolvableGenerics = false; if (Generics != null) { @@ -536,7 +536,7 @@ public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int ind genericParameter.TypeName.ProcessSymbol(table); var genericParameterType = genericParameter.TypeName.Type; table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); - + var genericParameterTypeId = context.GetOrRegister(genericParameterType); context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, index, Name.Name)); context.AddName(context.Bound, genericParameter.Name); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs index d3cbce705e..56ca5fd956 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderAttributes.cs @@ -19,7 +19,7 @@ public override string ToString() return Parameters switch { null => Name.Name, - _ => $"{Name}({string.Join(", ",Parameters.Select(x => x.ToString()))})" + _ => $"{Name}({string.Join(", ", Parameters.Select(x => x.ToString()))})" }; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index c54ed6644f..4b1ce26e98 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -36,7 +36,7 @@ public partial class ShaderSamplerState(Identifier name, TextLocation info) : Me { public Identifier Name { get; set; } = name; public List Parameters { get; set; } = []; - + public Symbol Symbol { get; private set; } public override void ProcessSymbol(SymbolTable table, SpirvContext context) @@ -44,7 +44,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) base.ProcessSymbol(table, context); Type = new PointerType(new SamplerType(), Specification.StorageClass.UniformConstant); table.DeclaredTypes.TryAdd(Type.ToString(), Type); - + var sid = new SymbolID(Name, SymbolKind.SamplerState); Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); @@ -56,7 +56,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var registeredType = context.GetOrRegister(Type); if (table.RootSymbols.TryGetValue(Name, out _)) throw new Exception($"SamplerState {Name} already defined"); - + var variableId = context.Bound++; // We store SamplerState as decoration for later processing during ShaderMixer.ProcessReflection() @@ -128,7 +128,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable.ResultId, Name); Symbol.IdRef = variableId; - + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } @@ -206,14 +206,14 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, (_, StorageClass.Static, _) => Specification.StorageClass.Private, (_, _, StreamKind.Stream or StreamKind.PatchStream) => Specification.StorageClass.Private, - _ => Specification.StorageClass.Uniform, + _ => Specification.StorageClass.Uniform, }; - + if (TypeModifier == TypeModifier.Const) { if (Value == null) throw new InvalidOperationException($"Constant {Name} doesn't have a value"); - + // Constant: compile right away var constantValue = Value.CompileConstantValue(table, context, memberType); context.SetName(constantValue.Id, Name); @@ -229,7 +229,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) Type = new PointerType(memberType, storageClass); table.DeclaredTypes.TryAdd(Type.ToString(), Type); } - + var sid = new SymbolID ( @@ -285,12 +285,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Semantic != null) context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); - + Symbol.IdRef = variable; if (StreamKind == StreamKind.PatchStream) context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); - + if (pointerType.BaseType is StructuredBufferType) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"structuredbuffer:<{pointerType.BaseType.ToId().ToLowerInvariant()}>")); @@ -362,10 +362,10 @@ public partial class ShaderMethod( public List Parameters { get; set; } = []; public BlockStatement? Body { get; set; } - + public SymbolFrame SymbolFrame { get; private set; } public List ParameterSymbols { get; private set; } = new(); - + public override void ProcessSymbol(SymbolTable table, SpirvContext context) { ReturnTypeName.ProcessSymbol(table); @@ -381,7 +381,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) functionFlags |= Specification.FunctionFlagsMask.Virtual; if (IsStaged) functionFlags |= Specification.FunctionFlagsMask.Stage; - + table.Push(); ParameterSymbols.Clear(); foreach (var p in Parameters) @@ -396,7 +396,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) table.CurrentFrame.Add(p.Name, parameterSymbol); ParameterSymbols.Add(parameterSymbol); } - + Span defaultParameters = stackalloc int[Parameters.Count]; var firstDefaultParameter = -1; for (var index = 0; index < Parameters.Count; index++) @@ -410,7 +410,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) firstDefaultParameter = index; defaultParameters[index] = arg.DefaultValue.CompileConstantValue(table, context, arg.Type).Id; } - + if (arg.Semantic != null) { // We use OpMemberDecorateString on the function ID @@ -430,10 +430,10 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()), }; } - + Type = ftype; table.DeclaredTypes.TryAdd(Type.ToString(), Type); - + SymbolFrame = table.Pop(); table.CurrentShader.Methods.Add((symbol, functionFlags)); } @@ -444,7 +444,7 @@ public void ProcessSymbolBody(SymbolTable table, SpirvContext context) Body?.ProcessSymbol(table); table.Pop(); } - + public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler, bool hasUnresolvableGenerics) { var (builder, context) = compiler; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index c3a0998c56..850aaec249 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -69,7 +69,7 @@ public enum ParameterModifiers : int InOut = In | Out, Const = 0x10, - + Point = 0x20, Line = 0x40, LineAdjacency = 0x80, @@ -267,37 +267,37 @@ public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, Spirv switch (anyAttribute.Name) { case "Link": - { - if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) { - // Try to resolve generic parameter when encoded as string (deprecated) - if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) + if (anyAttribute.Parameters[0] is StringLiteral linkLiteral) { - linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); - // TODO: make it a warning only? - //table.AddError(new(info, "LinkType generics should be passed without quotes")); - result.LinkId = linkLiteralSymbol.IdRef; + // Try to resolve generic parameter when encoded as string (deprecated) + if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) + { + linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); + // TODO: make it a warning only? + //table.AddError(new(info, "LinkType generics should be passed without quotes")); + result.LinkId = linkLiteralSymbol.IdRef; + } + else + { + result.LinkName = linkLiteral.Value; + } } - else + else if (anyAttribute.Parameters[0] is Identifier identifier) { - result.LinkName = linkLiteral.Value; + if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + { + throw new InvalidOperationException(); + } + linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); + result.LinkId = linkSymbol.IdRef; } - } - else if (anyAttribute.Parameters[0] is Identifier identifier) - { - if (!table.TryResolveSymbol(identifier.Name, out var linkSymbol)) + else { - throw new InvalidOperationException(); + throw new NotImplementedException($"Attribute {attribute} is not supported"); } - linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); - result.LinkId = linkSymbol.IdRef; + break; } - else - { - throw new NotImplementedException($"Attribute {attribute} is not supported"); - } - break; - } case "Color": result.Color = true; break; @@ -332,7 +332,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) if (isStaged != member.IsStaged) throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); } - + var constantBufferType = (ConstantBufferSymbol)Type; // We try to avoid clash in case multiple cbuffer TYPE with same name @@ -400,7 +400,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) BufferType => (Specification.StorageClass.UniformConstant, SymbolKind.TBuffer), _ => throw new NotImplementedException(), }; - + var type = new PointerType(member.Type, storageClass); var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, 0, OwnerType: table.CurrentShader); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs index 6bd311f8e3..f8d77bdb7b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderGenericsValues.cs @@ -5,7 +5,7 @@ public interface IGenericValue; public abstract class ShaderGenericsValue(TextLocation info) : Node(info); -public partial class ValueTypeGenerics(ValueLiteral value,TextLocation info) : ShaderGenericsValue(info) +public partial class ValueTypeGenerics(ValueLiteral value, TextLocation info) : ShaderGenericsValue(info) { public ValueLiteral Value { get; set; } = value; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs index c5cef2c779..e11629e748 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs @@ -17,7 +17,7 @@ public partial class ConditionalFlow(If first, TextLocation info) : Flow(info) public List ElseIfs { get; set; } = []; public Else? Else { get; set; } public ShaderAttributeList? Attributes { get; set; } - + public override void ProcessSymbol(SymbolTable table) { If.ProcessSymbol(table); @@ -148,4 +148,4 @@ public override string ToString() { return $"else {Body}"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index 39967d7ce4..6252b4a4a6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -74,11 +74,11 @@ public override void ProcessSymbol(SymbolTable table) TypeName.ProcessSymbol(table, variableType); else TypeName.Type = arrayType.BaseType; - + // TODO: check conversions if (variableType.BaseType != TypeName.Type) throw new InvalidOperationException("foreach: collection and variable type not matching"); - + table.Push(); var variableSymbol = new Symbol(new(Variable.Name, SymbolKind.Variable), Variable.Type, 0, OwnerType: table.CurrentShader); table.CurrentFrame.Add(Variable.Name, variableSymbol); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index d60f7acca4..bcb17a4800 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -30,7 +30,7 @@ public partial class ExpressionStatement(Expression expression, TextLocation inf { public override SymbolType? Type { get => Expression.Type; set { } } public Expression Expression { get; set; } = expression; - + public override void ProcessSymbol(SymbolTable table) { Expression.ProcessSymbol(table); @@ -51,7 +51,7 @@ public override string ToString() public partial class Return(TextLocation info, Expression? expression = null) : Statement(info) { public Expression? Value { get; set; } = expression; - + public override void ProcessSymbol(SymbolTable table) { Value?.ProcessSymbol(table); @@ -112,7 +112,7 @@ public List? ArraySizes get => TypeName.ArraySize; set => TypeName.ArraySize = value; } - + public override void ProcessSymbol(SymbolTable table) { Value?.ProcessSymbol(table, TypeName.Type); @@ -177,12 +177,12 @@ public override void ProcessSymbol(SymbolTable table) var declaration = Variables[index]; declaration.TypeName = new TypeName(TypeName.Name, info) { ArraySize = declaration.ArraySizes }; declaration.ProcessSymbol(table); - + var variableSymbol = new Symbol(new(declaration.Variable, SymbolKind.Variable), declaration.Type, 0, OwnerType: table.CurrentShader); table.CurrentFrame.Add(declaration.Variable, variableSymbol); VariableSymbols.Add(variableSymbol); } - + Type = Variables[0].Type; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index ff78384b46..9dc4133f50 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -39,7 +39,7 @@ public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder buil { if (clamp != null || status != null) throw new NotImplementedException(); - + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); @@ -76,8 +76,8 @@ public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder b var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -92,13 +92,13 @@ public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, Spirv var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - - TextureGenerateImageOperands(context.CompileConstant(0.0f), o, null, out var imask, out var imParams); + + TextureGenerateImageOperands(context.CompileConstant(0.0f), o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams) { imask = ImageOperandsMask.None; @@ -123,4 +123,4 @@ private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, S imParams = operandCount > 0 ? new EnumerantParameters(operands.Slice(0, operandCount)) : new EnumerantParameters(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 9b0a568681..689ca57b3b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -35,24 +35,24 @@ public static bool Spaces1(ref TScanner scanner, ParseResult result, o - public static bool Alternatives(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null, params ReadOnlySpan> parsers) + public static bool Alternatives(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null, params ReadOnlySpan> parsers) where TScanner : struct, IScanner where TResult : Node { var position = scanner.Position; - foreach(var p in parsers) - if(p.Invoke(ref scanner, result, out parsed)) + foreach (var p in parsers) + if (p.Invoke(ref scanner, result, out parsed)) return true; return Exit(ref scanner, result, out parsed, position, orError); } - public static bool Sequences(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null, bool withSPaces = false, string? separator = null, params ReadOnlySpan> parsers) + public static bool Sequences(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null, bool withSPaces = false, string? separator = null, params ReadOnlySpan> parsers) where TScanner : struct, IScanner where TResult : Node { parsed = []; var position = scanner.Position; - foreach(var p in parsers) - if(p.Invoke(ref scanner, result, out var r)) + foreach (var p in parsers) + if (p.Invoke(ref scanner, result, out var r)) parsed.Add(r); else return Exit(ref scanner, result, out parsed, position, orError); @@ -90,31 +90,31 @@ public static bool MethodModifiers(ref TScanner scanner, ParseResult r while ( Tokens.AnyOf( [ - "stage", + "stage", "override", "clone", "abstract", "static" - ], - ref scanner, + ], + ref scanner, out string match, - advance: true) + advance: true) && Spaces1(ref scanner, result, out _)) { matched = true; - if(match == "stage") - isStaged = true; - else if(match == "override") + if (match == "stage") + isStaged = true; + else if (match == "override") isOverride = true; - else if(match == "clone") + else if (match == "clone") isClone = true; - else if(match == "abstract") + else if (match == "abstract") isAbstract = true; - else if(match == "static") + else if (match == "static") isStatic = true; else break; } - if(!advance) + if (!advance) scanner.Position = position; return matched; } @@ -136,28 +136,28 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult [ "stage", "compose", - "stream", - "patchstream", - "linear", - "centroid", - "nointerpolation", - "noperspective", + "stream", + "patchstream", + "linear", + "centroid", + "nointerpolation", + "noperspective", "sample", - "extern", - "nointerpolation", - "precise", - "shared", - "groupshared", - "static", - "uniform", + "extern", + "nointerpolation", + "precise", + "shared", + "groupshared", + "static", + "uniform", "volatile", "const", "rowmajor", "columnmajor" - ], - ref scanner, + ], + ref scanner, out string match, - advance: true) + advance: true) && Spaces1(ref scanner, result, out _)) { matched = true; @@ -203,7 +203,7 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult typeModifier = TypeModifier.ColumnMajor; else break; } - if(!advance) + if (!advance) scanner.Position = position; return matched; } @@ -588,4 +588,4 @@ public static bool Repeat(ref TScanner scanner, ParseResult res return true; else return Exit(ref scanner, result, out nodes, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs index 7572169634..2f54f6cfd0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs @@ -9,4 +9,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parser.Match(ref scanner, result, out parsed, orError); return true; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs index 68166be99c..2d9d849064 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Spaces.cs @@ -57,4 +57,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index 39e1f7e153..1bb7d156ff 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -199,7 +199,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.XOr(ref scanner, result, out var left)) @@ -248,7 +248,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.BAnd(ref scanner, result, out var left)) @@ -297,7 +297,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Equality(ref scanner, result, out var left)) @@ -349,7 +349,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Relation(ref scanner, result, out var left)) @@ -399,7 +399,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Shift(ref scanner, result, out var left)) @@ -473,7 +473,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Add(ref scanner, result, out var left)) @@ -523,7 +523,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - + parsed = null!; Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); if (DirectiveExpressionParser.Mul(ref scanner, result, out var left)) @@ -611,4 +611,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index 1ecf478af4..9401451ff8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -33,7 +33,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = conditional; return true; } - else if(Define(ref scanner, result, out var obj)) + else if (Define(ref scanner, result, out var obj)) { parsed = obj; return true; @@ -375,7 +375,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(identifier, expression, scanner[position..scanner.Position]); return true; } - else if(Tokens.EOL(ref scanner, advance: true)) + else if (Tokens.EOL(ref scanner, advance: true)) { parsed = new(identifier, null, scanner[position..scanner.Position]); return true; @@ -415,13 +415,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true); var func = new FunctionDefineDirective(identifier, "", new()); - + if ( - LiteralsParser.Identifier(ref scanner, result, out var param) + LiteralsParser.Identifier(ref scanner, result, out var param) && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) ) func.Parameters.Add(param); - while( + while ( Tokens.Char(',', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _, onlyWhiteSpace: true) && LiteralsParser.Identifier(ref scanner, result, out param) @@ -429,7 +429,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) func.Parameters.Add(param); - if(!Tokens.Char(')', ref scanner, advance: true)) + if (!Tokens.Char(')', ref scanner, advance: true)) { result.Errors.Add(new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); scanner.Position = position; @@ -439,10 +439,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else { var startPattern = scanner.Position; - while(!(scanner.IsEof || Tokens.Char('\n', ref scanner) || Tokens.Literal("\r\n", ref scanner))) + while (!(scanner.IsEof || Tokens.Char('\n', ref scanner) || Tokens.Literal("\r\n", ref scanner))) scanner.Advance(1); func.Pattern = scanner.Memory[startPattern..scanner.Position].TrimEnd().TrimStart().ToString(); - if(!Tokens.Char('\n', ref scanner, advance: true)) + if (!Tokens.Char('\n', ref scanner, advance: true)) Tokens.Literal("\r\n", ref scanner, advance: true); parsed = func; return true; @@ -455,4 +455,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index f158d1b0d4..cc572fa91b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -86,7 +86,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); } - + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index b2ce2d61ea..7f9d187595 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -77,7 +77,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - if(orError is not null) + if (orError is not null) result.Errors.Add(orError.Value); scanner.Position = position; parsed = null!; @@ -111,7 +111,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } - else + else { if (orError is not null) result.Errors.Add(orError.Value with { Location = scanner[position] }); @@ -147,7 +147,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } - else + else { if (orError is not null) result.Errors.Add(orError.Value with { Location = scanner[position] }); @@ -183,4 +183,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 7da7ec4e32..00fe2b111a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -30,15 +30,15 @@ public static bool Literal(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if(LiteralsParser.Literal(ref scanner, result, out var lit)) + if (LiteralsParser.Literal(ref scanner, result, out var lit)) { parsed = lit; return true; } else return Parsers.Exit(ref scanner, result, out parsed, position); } - - + + public static bool Method(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -97,7 +97,7 @@ public static bool ArrayLiteral(ref TScanner scanner, ParseResult resu } else return Parsers.Exit(ref scanner, result, out parsed, position); } - + public static bool IdentifierBase(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { @@ -112,4 +112,4 @@ public static bool IdentifierBase(ref TScanner scanner, ParseResult re } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 69376bdf55..8a37098a50 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -15,9 +15,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { return Parsers.Alternatives( - ref scanner, - result, - out parsed, + ref scanner, + result, + out parsed, orError, PrefixIncrement, Signed, @@ -65,7 +65,7 @@ public static bool Signed(ref TScanner scanner, ParseResult result, ou } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - + public static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index f5e641d149..487d951241 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -73,14 +73,14 @@ public static bool IdentifierBase(ref TScanner scanner, ParseResult re } parsed = default; - return Parsers.Exit(ref scanner, result, out parsed, position, orError);; - } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); ; + } public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; - if(TypeNameLiteral(ref scanner, result, out var tn, orError)) + if (TypeNameLiteral(ref scanner, result, out var tn, orError)) { parsed = tn; return true; @@ -281,7 +281,7 @@ public readonly override string ToString() (false, true, 32) => "", (false, false, 64) => "ul", (false, true, 64) => "l", - + (true, _, _) => $"f{Size}", (false, false, _) => $"u{Size}", (false, true, _) => $"i{Size}", @@ -433,4 +433,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 8b7d29f480..0ebb2d5a41 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -17,7 +17,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Hex, Float, Integer - + ); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs index f473f7a803..5083f9ab7a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/Reserved.cs @@ -30,9 +30,9 @@ static Reserved() "min16uint" ]; - foreach(var t in types) + foreach (var t in types) { - for(int i = 1; i < 5; i ++) + for (int i = 1; i < 5; i++) { TypeNames.Add($"{t}{i}"); for (int j = 1; j < 5; j++) @@ -175,4 +175,4 @@ static Reserved() "while" ]; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index b2e26bad60..fc7b66af20 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -12,7 +12,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes) && Parsers.Spaces0(ref scanner, result, out _); var isStaged = Tokens.Literal("stage", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _); - + if (Tokens.Literal("compose", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) { var tmp = scanner.Position; @@ -32,4 +32,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs index c41499483b..a225d37550 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs @@ -166,11 +166,11 @@ public static bool BufferName(ref TScanner scanner, ParseResult result where TScanner : struct, IScanner { parsed = null!; - if(Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out List identifiers, 1, true, ".", orError)) + if (Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out List identifiers, 1, true, ".", orError)) { parsed = new Identifier(string.Join(".", identifiers.Select(i => i.Name)), scanner[identifiers[0].Info.Range.Start..identifiers[^1].Info.Range.End]); return true; } else return false; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index 0562cb4bac..dc302b28f0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -70,14 +70,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o @internal = true; tmp = scanner.Position; } - if(Parsers.FollowedBy(ref scanner, Tokens.Literal("partial"), withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) + if (Parsers.FollowedBy(ref scanner, Tokens.Literal("partial"), withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) tmp = scanner.Position; if ( ( - Tokens.Literal("shader", ref scanner, advance: true) - || Tokens.Literal("class", ref scanner, advance: true) + Tokens.Literal("shader", ref scanner, advance: true) + || Tokens.Literal("class", ref scanner, advance: true) ) - && Parsers.Spaces1(ref scanner, result,out _)) + && Parsers.Spaces1(ref scanner, result, out _)) { if ( LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) @@ -183,4 +183,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 0c49ab77de..33a829dca9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -31,7 +31,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (!Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out semantic, withSpaces: true, advance: true)) return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - + if (Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { parsed = new(typeName, identifier, value, scanner[position..scanner.Position]) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index 9fd96da1ae..b2ab627dad 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -30,7 +30,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { - if(AnySamplers(ref scanner, result, out var sampler)) + if (AnySamplers(ref scanner, result, out var sampler)) { parsed = sampler; return true; @@ -77,7 +77,7 @@ public static bool AnySamplers(ref TScanner scanner, ParseResult resul parsed = samplerCompState; return true; } - else return Parsers.Exit(ref scanner, result, out parsed, position); + else return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -114,4 +114,4 @@ public static bool TypeDef(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 0e6cd5cb8b..5a15774180 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -133,11 +133,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); while (!scanner.IsEof) { - if(ShaderClassParsers.Class(ref scanner, result, out var shader) && Parsers.Spaces0(ref scanner, result, out _)) + if (ShaderClassParsers.Class(ref scanner, result, out var shader) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(shader); - else if( EffectParser.Effect(ref scanner, result, out var effect) && Parsers.Spaces0(ref scanner, result, out _)) + else if (EffectParser.Effect(ref scanner, result, out var effect) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(effect); - else if( ParamsParsers.Params(ref scanner, result, out var p) && Parsers.Spaces0(ref scanner, result, out _)) + else if (ParamsParsers.Params(ref scanner, result, out var p) && Parsers.Spaces0(ref scanner, result, out _)) ns.Declarations.Add(p); else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); @@ -171,4 +171,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public static bool Namespace(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new NamespaceParsers().Match(ref scanner, result, out parsed, orError); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 0a45db0a5b..615f8a6734 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -48,12 +48,12 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult } else - if (Parsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) - { - parsed = parameters; - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position); + if (Parsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) + { + parsed = parameters; + return true; + } + else return Parsers.Exit(ref scanner, result, out parsed, position); } public static bool MethodParameter(ref TScanner scanner, ParseResult result, out MethodParameter parsed, in ParseError? orError = null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 8d19ee8ab7..3896935a6e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -63,7 +63,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o values.Add(expr); else if (LiteralsParser.StringLiteral(ref scanner, result, out var str)) values.Add(str); - else + else break; // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } @@ -146,4 +146,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 0a7cd6a421..689d891cdb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -10,7 +10,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if(ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributeList)) + if (ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributeList)) Parsers.Spaces0(ref scanner, result, out _); if (If(ref scanner, result, out var ifstatement, orError) && Parsers.Spaces0(ref scanner, result, out _)) { @@ -18,14 +18,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { Attributes = attributeList }; - while(ElseIf(ref scanner, result, out var elseif, orError) && Parsers.Spaces0(ref scanner, result, out _)) + while (ElseIf(ref scanner, result, out var elseif, orError) && Parsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); if (Else(ref scanner, result, out var elseStatement, orError)) parsed.Else = elseStatement; parsed.Info = scanner[position..scanner.Position]; return true; } - else if(Tokens.Literal("else ", ref scanner)) + else if (Tokens.Literal("else ", ref scanner)) return Parsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner[scanner.Position], scanner.Memory)); return Parsers.Exit(ref scanner, result, out parsed, position, orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 856017c2b6..385c9ddd0a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -16,7 +16,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o scanner.Position = position; if (While(ref scanner, result, out var w, orError)) { - if(hasAttributes) + if (hasAttributes) w.Attribute = attribute; parsed = w; return true; @@ -28,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else if (For(ref scanner, result, out var f, orError)) { - if(hasAttributes) + if (hasAttributes) f.Attribute = attribute; parsed = f; return true; @@ -55,7 +55,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if( + if ( Tokens.Literal("for", ref scanner, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) ) @@ -66,32 +66,32 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o Parsers.Spaces0(ref scanner, result, out _); // Parsing the initialization - if(StatementParsers.Expression(ref scanner, result, out init)){} - else if(StatementParsers.DeclareOrAssign(ref scanner, result, out init)){} - else if(StatementParsers.Empty(ref scanner, result, out init)){} + if (StatementParsers.Expression(ref scanner, result, out init)) { } + else if (StatementParsers.DeclareOrAssign(ref scanner, result, out init)) { } + else if (StatementParsers.Empty(ref scanner, result, out init)) { } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0036, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); // Parsing the condition if (ExpressionParser.Expression(ref scanner, result, out condition) - && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) {} + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) { } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); - + Parsers.Spaces0(ref scanner, result, out _); // parsing the final expression - + var tmpPos = scanner.Position; if (!Parsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) expressions = [new EmptyStatement(scanner[tmpPos..scanner.Position])]; - if(!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) - return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + if (!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) + return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); // parsing the block or statement - if(StatementParsers.Statement(ref scanner, result, out var body)) + if (StatementParsers.Statement(ref scanner, result, out var body)) { parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); return true; @@ -105,7 +105,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes where TScanner : struct, IScanner { var position = scanner.Position; - if( + if ( PostfixParser.Postfix(ref scanner, result, out var variable) && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) @@ -118,7 +118,7 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes return true; } scanner.Position = position; - if(ExpressionParser.Expression(ref scanner, result, out var expression)) + if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 16835d0d99..2180423771 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -156,7 +156,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else if ( - Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Parenthesis, out Expression p, advance : true) + Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Parenthesis, out Expression p, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs index c5068fa940..3502317c65 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -20,13 +20,13 @@ public static bool Char(char c, ref TScanner scanner, bool advance = f public static bool Set(string set, ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner => new SetTokenParser(set).Match(ref scanner, advance); - + public static bool Set(string set, ref TScanner scanner, out char chosen, bool advance = false) where TScanner : struct, IScanner { chosen = '\0'; - foreach(var c in set) - if(Char(c, ref scanner, advance: advance)) + foreach (var c in set) + if (Char(c, ref scanner, advance: advance)) { chosen = c; return true; @@ -41,8 +41,8 @@ public static bool AnyOf(ReadOnlySpan literals, ref TScanner s where TScanner : struct, IScanner { matched = null!; - foreach(var l in literals) - if(new LiteralTokenParser(l).Match(ref scanner, advance)) + foreach (var l in literals) + if (new LiteralTokenParser(l).Match(ref scanner, advance)) { matched = l; return true; @@ -72,7 +72,7 @@ public static bool EOF(ref TScanner scanner) => new EOFTokenParser().Match(ref scanner, false); - + public static bool FloatSuffix(ref TScanner scanner, out Suffix? suffix, bool advance = false) where TScanner : struct, IScanner { @@ -122,7 +122,7 @@ public readonly bool Match(ref TScanner scanner, bool advance) { if (scanner.Peek() == Character) { - if(advance) + if (advance) scanner.Advance(1); return true; } @@ -141,7 +141,7 @@ public struct DigitRange public DigitRange(Range range) { var (o, l) = range.GetOffsetAndLength(allChars.Length); - Chars = allChars[o..Math.Min(allChars.Length,o+l+1)]; + Chars = allChars[o..Math.Min(allChars.Length, o + l + 1)]; } public DigitRange(int digit) { @@ -149,8 +149,8 @@ public DigitRange(int digit) } public DigitRange(string chars) { - foreach(var e in chars) - if(!char.IsDigit(e)) + foreach (var e in chars) + if (!char.IsDigit(e)) throw new ArgumentException($"Cannot use {chars} as a list of digit"); Chars = chars; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs index 130ab926d5..4f7fa527f3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLERR.cs @@ -68,4 +68,4 @@ public static class SDSLErrorMessages public const string SDSL0111 = "SDSL0111: Unimplemented: {0}"; public const string SDSL0112 = "SDSL0112: Could not resolve member {0} in expression {1} of type {2}"; public const string SDSL0113 = "SDSL0113: Could not resolve member {0} in structure of type {1}"; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs index b6c963168d..d14697e4f2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSLParser.cs @@ -14,4 +14,4 @@ public static ParseResult Parse(string code) var c = new CommentProcessedCode(code); return Grammar.Match(c); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs index 0f75c11ce4..758bbf9deb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ErrorLocation.cs @@ -7,8 +7,8 @@ public struct ErrorLocation public int Position { get; private set; } private int leftOffset; private int rightOffset; - public int Line { get; private set;} - public int Column { get; private set;} + public int Line { get; private set; } + public int Column { get; private set; } public ErrorLocation(Scanner scanner, int position) { // Getting the line and column at the position given. diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs index ec19b5c78c..e2d69be588 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannableString.cs @@ -8,7 +8,7 @@ public readonly struct ScannableString(string code) : IScannableCode public readonly ReadOnlySpan Span => Code.AsSpan(); public readonly ReadOnlyMemory Memory => Code.AsMemory(); - public static implicit operator ScannableString(string s) => new (s); + public static implicit operator ScannableString(string s) => new(s); public static implicit operator string(ScannableString s) => s.Code; } @@ -29,4 +29,4 @@ public readonly struct ScannableReadOnlyMemory(ReadOnlyMemory code) : ISca public static implicit operator ScannableReadOnlyMemory(Memory s) => new(s); public static implicit operator ReadOnlyMemory(ScannableReadOnlyMemory s) => s.Code; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs index 066ee2eb85..3fc8092f52 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/ScannerGeneric.cs @@ -119,4 +119,4 @@ public readonly TextLocation GetLocation(Range range) { return new(Memory, range); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs index 0223a997aa..3bea68045e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Scanners/TextLocation.cs @@ -24,12 +24,12 @@ public static class SpanCharExtensions public static int EndsAt(this Range range, int originalLength) { - var (o, l) =range.GetOffsetAndLength(originalLength); + var (o, l) = range.GetOffsetAndLength(originalLength); return o + l; } public static int StartsAt(this Range range, int originalLength) { - var (o, _) =range.GetOffsetAndLength(originalLength); + var (o, _) = range.GetOffsetAndLength(originalLength); return o; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index febd86e340..08c8e4109f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -284,7 +284,7 @@ public override string ResolveGenericAsString(int genericIndex) textValue = declaringContext.TryGetConstantValue(constantId, out var constantValue, out _, false) ? constantValue.ToString() : GetIdRefAsString(genericIndex); - + declaringContext.GenericValueCache.Add(constantId, textValue); } @@ -367,7 +367,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st { var resolvedLinks = new Dictionary(); var semantics = new Dictionary(); - + var genericParameters = new List(); for (int index = 0; index < shaderBuffers.Context.Count; ++index) { @@ -447,7 +447,7 @@ private static void TransformResolvedSemantics(SpirvContext context, Dictionary< if (semantics.TryGetValue(m, out var newSemantic)) decorate.Value = newSemantic; } - else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: Decoration.UserSemantic, Value : string m2 } decorate2) + else if (i.Op == Op.OpMemberDecorateString && (OpMemberDecorateString)i is { Decoration: Decoration.UserSemantic, Value: string m2 } decorate2) { if (semantics.TryGetValue(m2, out var newSemantic)) decorate2.Value = newSemantic; @@ -657,7 +657,7 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) } } } - + public static void CollectIds(OpData i, Action ids) { foreach (var op in i) @@ -737,7 +737,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); cache.RegisterShader(classNameWithGenerics, macros, shaderBuffers, hash); } - + // Run in all cases (even if cached) genericResolver.PostProcess(classNameWithGenerics); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index ab72fb3ea4..d3c9a855f9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -82,7 +82,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) else throw new InvalidOperationException(); } - + public (SpirvValue, SymbolType) ApplyMatrixSwizzles(SpirvContext context, SpirvValue value, MatrixType m, Span<(int Column, int Row)> swizzles) { Span elements = stackalloc int[swizzles.Length]; @@ -94,7 +94,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) var resultType = m.BaseType.GetVectorOrScalar(swizzles.Length); value = swizzles.Length > 1 - ? new(InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, [..elements]))) + ? new(InsertData(new OpCompositeConstruct(context.GetOrRegister(resultType), context.Bound++, [.. elements]))) : new(elements[0], context.GetOrRegister(resultType)); return (value, resultType); @@ -147,7 +147,7 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper Operator.LogicalAND or Operator.LogicalOR => ScalarType.Boolean, _ => FindCommonBaseTypeForBinaryOperation(leftElementType, rightElementType), }; - + // Check size SymbolType resultType; switch (leftType, rightType) @@ -174,18 +174,18 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper break; case (MatrixType, VectorType): case (VectorType, MatrixType): - table.AddError(new (info, SDSLErrorMessages.SDSL0107)); + table.AddError(new(info, SDSLErrorMessages.SDSL0107)); return null; case (MatrixType l, MatrixType r): resultType = new MatrixType(desiredElementType, Math.Min(l.Rows, r.Rows), Math.Min(l.Columns, r.Columns)); break; default: - table.AddError(new (info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); + table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0108, leftType, rightType))); return null; } var operandType = resultType; - + // Comparisons and logical operators if (op is Operator.Greater or Operator.Lower or Operator.GreaterOrEqual or Operator.LowerOrEqual or Operator.NotEquals or Operator.Equals or Operator.LogicalAND or Operator.LogicalOR) @@ -193,7 +193,7 @@ public static (SymbolType OperandType, SymbolType ResultType)? AnalyzeBinaryOper return (operandType, resultType); } - + public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, SpirvValue left, Operator op, SpirvValue right, TextLocation info, string? name = null, int? desiredResultId = null) { var leftType = context.ReverseTypes[left.TypeId]; @@ -237,7 +237,7 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv structValues[i] = memberValue.Id; } - return Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(structType), resultId, [..structValues])).ToValue(); + return Buffer.Insert(Position++, new OpCompositeConstruct(context.GetOrRegister(structType), resultId, [.. structValues])).ToValue(); } // Can indirectly happen inside struct (SDSL specific) @@ -268,7 +268,7 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv } (var operandType, var resultType) = AnalyzeBinaryOperation(table, leftType, op, rightType, info) ?? throw new InvalidOperationException("Type of binary operation could not be determined"); - + // TODO: Some specific cases where one of the operands doesn't need to have exact same type as resultType (such as shift in OpShiftRightLogical, or signedness for some other operations) // We'll need to review those cases left = Convert(context, left, operandType); @@ -428,7 +428,7 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) if (castType is StructType || valueType is StructType) throw new NotImplementedException($"Can't cast between structures (cast from {valueType} to {castType})"); - + if (castType is ArrayType a1 && valueType is ArrayType a2) { if (a1.BaseType == a2.BaseType) @@ -450,7 +450,7 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // Note: order is Input, Streams, Output && targetKind > sourceKind) return 1; - + // We don't support cast with object yet, filter for numeral types if ((castType is not ScalarType && castType is not VectorType && castType is not MatrixType) || (valueType is not ScalarType && valueType is not VectorType && valueType is not MatrixType)) @@ -465,36 +465,36 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // Promotion scalar to scalar, vector or matrix (replicate value) (ScalarType, VectorType or MatrixType) => 1, - + // Truncation // Emit warning? (warning: implicit truncation of vector type) (VectorType or MatrixType, ScalarType) => 13, (VectorType v1, VectorType v2) when v1.Size > v2.Size => 13, (MatrixType m1, MatrixType m2) when m1.Rows > m2.Rows && m1.Columns > m2.Columns => 13, - + // Note: conversions such as float2x2<=>float4 are allowed but not implemented in Convert() (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, (VectorType v1, MatrixType m2) when v1.Size == m2.Rows * m2.Columns => 1, - + // vector<=>matrix but size doesn't match (impossible) (VectorType v1, MatrixType m2) when v1.Size != m2.Rows * m2.Columns => int.MaxValue, (MatrixType m1, VectorType v2) when v2.Size != m1.Rows * m1.Columns => int.MaxValue, - + // Expansion not from scalar (impossible) (VectorType v1, VectorType v2) when v1.Size < v2.Size => int.MaxValue, (MatrixType m1, MatrixType m2) when m1.Rows < m2.Rows || m1.Columns < m2.Columns => int.MaxValue, - + _ => int.MaxValue }; if (conversionScore == int.MaxValue) return int.MaxValue; - + // Check element types now var scalarScore = (valueType.GetElementType(), castType.GetElementType()) switch { (ScalarType s1, ScalarType s2) when s1 == s2 => 0, - + // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => 7, (ScalarType { Type: Scalar.Float or Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => 7, @@ -503,7 +503,7 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // Bitcast (int=>uint or uint=>int) (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => 2, (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => 2, - + _ => int.MaxValue, }; if (scalarScore == int.MaxValue) @@ -725,19 +725,19 @@ public static SymbolType GetValueType(this SymbolType type) public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) => size == 1 ? scalar : new VectorType(scalar, size); - + public static int GetElementCount(this SymbolType symbol) => symbol switch - { - ScalarType s => 1, - VectorType v => v.Size, - MatrixType m => m.Rows * m.Columns, - }; + { + ScalarType s => 1, + VectorType v => v.Size, + MatrixType m => m.Rows * m.Columns, + }; public static ScalarType GetElementType(this SymbolType symbol) => symbol switch - { - ScalarType s => s, - VectorType v => v.BaseType, - MatrixType m => m.BaseType, - }; + { + ScalarType s => s, + VectorType v => v.BaseType, + MatrixType m => m.BaseType, + }; public static SymbolType WithElementType(this SymbolType symbol, ScalarType elementType) => symbol switch { ScalarType s => elementType, diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs index ffb7c17342..e01f04a9b1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs @@ -82,4 +82,4 @@ public void Return(in SpirvValue? value = null) _ => Buffer.InsertData(Position++, new OpReturn()) }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs index 8fa1a5f931..5c12eab3e5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs @@ -47,7 +47,7 @@ public SpirvValue EmitFunctionParameter(SpirvContext context, string name, Symbo context.AddName(p, name); var value = new SpirvValue(p.ResultId, p.ResultType, name); CurrentFunction!.Value.Parameters.Add(name, value); - return value; + return value; } public static OpFunctionParameter GetFunctionParameter(SpirvBuffer buffer, Symbol method, int functionParameterIndex) @@ -58,7 +58,7 @@ public static OpFunctionParameter GetFunctionParameter(SpirvBuffer buffer, Symbo for (int index = start; index < end; ++index) { var i = buffer[index]; - if (i.Op == Op.OpFunctionParameter && functionParameterCurrent++ == functionParameterIndex && (OpFunctionParameter)i is {} functionParameter) + if (i.Op == Op.OpFunctionParameter && functionParameterCurrent++ == functionParameterIndex && (OpFunctionParameter)i is { } functionParameter) { return functionParameter; } @@ -66,12 +66,12 @@ public static OpFunctionParameter GetFunctionParameter(SpirvBuffer buffer, Symbo throw new InvalidOperationException(); } - + public static void FunctionRemoveParameter(SpirvContext context, SpirvBuffer buffer, Symbol method, int argIndex) { var methodType = (FunctionType)method.Type; method.Type = methodType with { ParameterTypes = methodType.ParameterTypes[0..^1] }; - + // Find OpFunctionParameter and remove it var functionParameter = GetFunctionParameter(buffer, method, argIndex); SetOpNop(functionParameter.InstructionMemory.Span); @@ -83,12 +83,12 @@ public static void FunctionReplaceParameter(SpirvContext context, SpirvBuffer bu var parameterTypes = new List(methodType.ParameterTypes); parameterTypes[argIndex] = parameterTypes[argIndex] with { Type = newType }; method.Type = methodType with { ParameterTypes = parameterTypes }; - + // Find OpFunctionParameter and remove it var functionParameter = GetFunctionParameter(buffer, method, argIndex); functionParameter.ResultType = context.GetOrRegister(newType); } - + public static (int Start, int End) FindMethodBounds(SpirvBuffer buffer, int functionId) { int? start = null; @@ -103,4 +103,4 @@ public static (int Start, int End) FindMethodBounds(SpirvBuffer buffer, int func throw new InvalidOperationException($"Could not find start of method {functionId}"); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs index 47d3f5134d..5ea62d67de 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs @@ -123,7 +123,7 @@ public void Merge(SpirvBuffer other) var instructions = new List(); foreach (var instruction in other) instructions.Add(instruction.Data); - + buffer.InsertRange(Position, instructions.AsSpan()); Position += other.Count; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs index 96a178cccf..cbe5843a3e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs @@ -47,7 +47,7 @@ public SpirvBuffer ToBuffer() public ShaderBuffers ToShaderBuffers() { Context.Sort(); - return new(Context, Builder.GetBuffer()); + return new(Context, Builder.GetBuffer()); } // public override string ToString() // { @@ -60,4 +60,4 @@ public ShaderBuffers ToShaderBuffers() // return builder.ToString(); // } #pragma warning restore CS0618 // Type or member is obsolete -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 711e9c8781..d2bed923b8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -146,7 +146,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object default: throw new NotImplementedException(); } - + if (simplifyInBuffer) { if (value is int valueI) @@ -259,7 +259,7 @@ public SpirvValue CreateConstantCompositeVectorRepeat(Literal literal, int size) var value = CompileConstantLiteral(literal); if (size == 1) return value; - + var type = new VectorType((ScalarType)ReverseTypes[value.TypeId], size); return CreateConstantCompositeRepeat(type, value, size); } @@ -269,7 +269,7 @@ public unsafe SpirvValue CreateConstantCompositeRepeat(SymbolType type, SpirvVal Span values = stackalloc int[size]; for (int i = 0; i < size; ++i) values[i] = value.Id; - + return new(Buffer.AddData(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); } @@ -380,4 +380,4 @@ public static ScalarType ComputeLiteralType(Literal literal) }, }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index fc51d23785..4a1ecf09fd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -18,7 +18,7 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI var typeDuplicateInserter = new TypeDuplicateHelper(this); var remapIds = new Dictionary(); int lastResultId = -1; - + var lastResultIndex = -1; if (desiredResultId != null) { @@ -84,8 +84,8 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI // Note: we made sure to not copy last instruction which should have the constant we want, so this case shouldn't happen anymore if (desiredResultId != null && lastResultId != desiredResultId) throw new InvalidOperationException(); - // Note: if we were to readd this, we would also need to process the main buffer - //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); + // Note: if we were to readd this, we would also need to process the main buffer + //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); return lastResultId; } @@ -140,4 +140,4 @@ public SpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) newBuffer.Add(i); return newBuffer; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 35501b5efc..6a96d0ff06 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -56,7 +56,7 @@ public virtual void RegisterShader(string name, ReadOnlySpan define if (hash != null) loadedShadersByName.Hash = hash.Value; } - + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) { if (loadedShaders.TryGetValue(name, out var loadedShadersByName) @@ -75,7 +75,7 @@ public bool TryLoadFromCache(string name, ReadOnlySpan defines, [Ma public interface IExternalShaderLoader { public IShaderCache Cache { get; } - + public bool Exists(string name); public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); @@ -89,14 +89,14 @@ public partial class SpirvContext // Used internally by GenericResolverFromInstantiatingBuffer (cache from constant ID to string representation) internal IShaderCache GenericCache { get; } = new ShaderCache(); internal Dictionary GenericValueCache { get; } = new(); - + private int bound = 1; public int ResourceGroupBound { get; set; } = 1; public ref int Bound => ref bound; public Dictionary Types { get; init; } = []; public Dictionary ReverseTypes { get; init; } = []; public Dictionary Names { get; init; } = []; - + public OpDataIndex this[int index] => new(index, Buffer); public int Count => Buffer.Count; @@ -117,9 +117,9 @@ public SpirvContext(SpirvBuffer buffer) public void ImportGLSL() { - foreach(var i in Buffer) + foreach (var i in Buffer) { - if(i.Op == Op.OpExtInstImport && (OpExtInstImport)i is { Name: "GLSL.std.450" }) + if (i.Op == Op.OpExtInstImport && (OpExtInstImport)i is { Name: "GLSL.std.450" }) { GLSLSet ??= ((OpExtInstImport)i).ResultId; return; @@ -165,11 +165,11 @@ public void SetName(int target, string name) return; } } - + // Not found, create new one Buffer.Add(new OpName(target, name)); } - + public void AddMemberName(int target, int accessor, string name) => Buffer.AddData(new OpMemberName(target, accessor, name.Replace('.', '_'))); @@ -197,7 +197,7 @@ public OpDataIndex Insert(int index, OpData data) public T Add(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.Add(value); - + public OpData AddData(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.AddData(value); @@ -220,7 +220,7 @@ public SpirvContext FluentAdd(in T value, out T result) public void RemoveNameAndDecorations(HashSet ids) { - foreach (var i in Buffer) + foreach (var i in Buffer) { if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) { @@ -232,7 +232,7 @@ public void RemoveNameAndDecorations(HashSet ids) if (ids.Contains(decorateString.Target)) SpirvBuilder.SetOpNop(i.Data.Memory.Span); } - else if (i.Op == Op.OpName && (OpName)i is {} nameInstruction) + else if (i.Op == Op.OpName && (OpName)i is { } nameInstruction) { if (ids.Contains(nameInstruction.Target)) { @@ -254,4 +254,4 @@ public override string ToString() { return Spv.Dis(Buffer, writeToConsole: false); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs index 9ed4cdd55c..2c66ad51e6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs @@ -51,7 +51,7 @@ public static class ExpressionExtensions Op.OpUGreaterThanEqual, Op.OpSGreaterThanEqual, }; - + public static HashSet KernelSpecConstantOpSupportedOps = new() { // Note: those are not supported in shaders @@ -105,7 +105,7 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol result = new(instruction.Data); } // Rewrite using OpSpecConstantOp when possible - else if(ShaderSpecConstantOpSupportedOps.Contains(i.Op) || KernelSpecConstantOpSupportedOps.Contains(i.Op)) + else if (ShaderSpecConstantOpSupportedOps.Contains(i.Op) || KernelSpecConstantOpSupportedOps.Contains(i.Op)) { var resultType = i.Data.Memory.Span[1]; var resultId = i.Data.Memory.Span[2]; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 629df5d095..a7cd9ede21 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -28,7 +28,7 @@ public int RemoveType(SymbolType type) RemoveType(typeId); return typeId; } - + public void RemoveType(int typeId) { foreach (var i in Buffer) @@ -102,11 +102,11 @@ public int RegisterType(SymbolType type, int id) private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) { var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).ResultId; - + var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; AddName(bufferType, $"type.{(structuredBufferType.WriteAllowed ? "RW" : "")}StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); - + // TODO: Add array stride and offsets Buffer.Add(new OpDecorate(bufferType, Specification.Decoration.Block, [])); @@ -250,4 +250,4 @@ private int RegisterPointerType(PointerType pointerType, int id) AddName(id, pointerType.ToId()); return id; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs index 0504c1396f..10b0105c5d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs @@ -27,15 +27,15 @@ public readonly void Apply(SpirvBuffer buffer) var previousId = 0; OpData? next = null!; var countIds = 0; - + foreach (var i in buffer) countIds += i.Data.IdResult != null ? 1 : 0; while (!finished && previousId < countIds) { var countAbove = 0; - foreach(var i in buffer) + foreach (var i in buffer) { - if(i.Data.IdResult == previousId + 1) + if (i.Data.IdResult == previousId + 1) { countAbove += 1; previousId += 1; @@ -47,7 +47,7 @@ public readonly void Apply(SpirvBuffer buffer) countAbove += 1; next = i.Data; } - else if(next is not null && i.Data.IdResult > previousId + 1 && i.Data.IdResult < (next?.IdResult ?? 0)) + else if (next is not null && i.Data.IdResult > previousId + 1 && i.Data.IdResult < (next?.IdResult ?? 0)) { countAbove += 1; next = i.Data; @@ -55,7 +55,7 @@ public readonly void Apply(SpirvBuffer buffer) } if (countAbove == 0) finished = true; - else if(next is OpData && (next?.IdResult ?? 0) > previousId + 1) + else if (next is OpData && (next?.IdResult ?? 0) > previousId + 1) { next?.IdResult = previousId + 1; ReplaceRefs(next?.IdResult ?? -1, previousId + 1, buffer); @@ -63,7 +63,7 @@ public readonly void Apply(SpirvBuffer buffer) } - + } static void ReplaceRefs(int from, int to, SpirvBuffer buffer) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs index 9ba158373a..266c4b9d1a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs @@ -50,7 +50,7 @@ // { // // Add capability Float64 // } - + // // TODO : Check if any atomic instructions operates on integers // // else if (instruction.OpCode == Op.OpAtomic && instruction.Words.Span[2] == 64) // // { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs index b15cd2229b..89a27561ea 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs @@ -27,4 +27,4 @@ // f.RecomputeLength(); // } // } -// } \ No newline at end of file +// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs index d714fad84d..9f7a2d8275 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs @@ -29,7 +29,7 @@ // } // while(enumerator.Current.OpCode != Op.OpLabel) // enumerator.MoveNext(); - + // tmp.Insert(tmp.Length, enumerator.Current.Words); // foreach (var i in function) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs index 2c2f156af0..eaf7f3a8e7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs @@ -71,4 +71,4 @@ // words[0] = words.Length << 16; // words[1..].Clear(); // } -// } \ No newline at end of file +// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs index d0cccf0503..874b12a34a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs @@ -502,4 +502,4 @@ // } // } // } -// } \ No newline at end of file +// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index f5274f1b1a..0c84f4f364 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -64,7 +64,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) semanticTable[t] = m; } } - + // Patch if (i.Op == Op.OpDecorate && (OpDecorate)i is { Target: int t3, Decoration: Decoration.Patch }) { @@ -153,7 +153,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) // Process ResourceGroup and LogicalGroup decorations foreach (var i in context) { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) { if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) // Note: ResourceGroup should not be null if set diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index e85c7a6a1b..4b7473b6fd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -116,7 +116,7 @@ public static bool ProcessBuiltinsDecoration( // Vertex shaders inputs (SV_InstanceID, SV_VertexID, etc.) (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(context, variable, BuiltIn.InstanceIndex), (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(context, variable, BuiltIn.VertexIndex), - (>= ExecutionModel.Vertex, _, "SV_INSTANCEID" or "SV_VERTEXID") => false, // forward from VS to the next stages + ( >= ExecutionModel.Vertex, _, "SV_INSTANCEID" or "SV_VERTEXID") => false, // forward from VS to the next stages // Pixel shader inputs (SV_IsFrontFace) (ExecutionModel.Fragment, StreamVariableType.Input, "SV_ISFRONTFACE") => AddBuiltin(context, variable, BuiltIn.FrontFacing), // SV_PrimitiveID diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 4dcc4847df..6e017265c2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -147,10 +147,10 @@ int ConvertInputsArray() inputFieldValues[inputIndex] = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); } - inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [..inputFieldValues])).ResultId; + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [.. inputFieldValues])).ResultId; } - var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [..inputValues])).ResultId; + var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [.. inputValues])).ResultId; return inputsData1; } @@ -207,43 +207,43 @@ void FillTessellationArguments(Symbol function, Span arguments) case PatchType inputPatchType when (inputPatchType.Kind == PatchTypeKindSDSL.Input && executionModel == ExecutionModel.TessellationControl) || (inputPatchType.Kind == PatchTypeKindSDSL.Output && executionModel == ExecutionModel.TessellationEvaluation): - { - arguments[i] = inputsVariable; - break; - } + { + arguments[i] = inputsVariable; + break; + } // Hull outputs case PatchType { Kind: PatchTypeKindSDSL.Output } outputPatchType when executionModel == ExecutionModel.TessellationControl: - { - arguments[i] = GenerateHullTessellationOutputs(); - break; - } + { + arguments[i] = GenerateHullTessellationOutputs(); + break; + } case StreamsType t when t.Kind is StreamsKindSDSL.Constants && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: - { - // Parameter is "HS_CONSTANTS constants" - var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(constantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - arguments[i] = constantVariable; - // Copy back values from semantic/builtin variables to Constants struct - foreach (var stream in patchInputStreams) { - var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; - var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, stream.Id, null, [])).ResultId; - inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); - buffer.Add(new OpStore(inputPtr, inputResult, null, [])); + // Parameter is "HS_CONSTANTS constants" + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(constantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = constantVariable; + // Copy back values from semantic/builtin variables to Constants struct + foreach (var stream in patchInputStreams) + { + var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, stream.Id, null, [])).ResultId; + inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); + buffer.Add(new OpStore(inputPtr, inputResult, null, [])); + } + break; } - break; - } case StreamsType t when t.Kind is StreamsKindSDSL.Output or StreamsKindSDSL.Constants && parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" - var structType = t.Kind switch { - StreamsKindSDSL.Output => outputType, - StreamsKindSDSL.Constants => constantsType, - }; - var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; - arguments[i] = outVariable; - break; - } + // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" + var structType = t.Kind switch + { + StreamsKindSDSL.Output => outputType, + StreamsKindSDSL.Constants => constantsType, + }; + var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + arguments[i] = outVariable; + break; + } case var t when arguments[i] == 0: throw new NotImplementedException($"Can't process argument {i + 1} of type {parameterType} in method {entryPoint.Id.Name}"); } @@ -260,43 +260,43 @@ void ProcessTessellationArguments(Symbol function, Span arguments) switch (parameterType) { case StreamsType { Kind: StreamsKindSDSL.Output } when parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" - var outputVariable = arguments[i]; - // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(outputType), context.Bound++, outputVariable, null, [])).ResultId; - // Do we need to index into array? if yes, get index (gl_invocationID) - int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; - // Copy back values from Output struct to semantic/builtin variables - for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) { - var stream = outputStreams[outputIndex]; - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; - outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); - var outputTargetPtr = arrayOutputSize != null - ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), - context.Bound++, stream.Id, - [invocationIdValue.Value])).ResultId - : stream.Id; - buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(outputType), context.Bound++, outputVariable, null, [])).ResultId; + // Do we need to index into array? if yes, get index (gl_invocationID) + int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; + // Copy back values from Output struct to semantic/builtin variables + for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + { + var stream = outputStreams[outputIndex]; + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; + outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); + var outputTargetPtr = arrayOutputSize != null + ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), + context.Bound++, stream.Id, + [invocationIdValue.Value])).ResultId + : stream.Id; + buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); + } + break; } - break; - } case StreamsType { Kind: StreamsKindSDSL.Constants } when parameterModifiers == ParameterModifiers.Out: - { - // Parameter is "out HS_OUTPUT output" - var outputVariable = arguments[i]; - // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(constantsType ?? throw new InvalidOperationException()), context.Bound++, outputVariable, null, [])).ResultId; - // Copy back values from Output struct to semantic/builtin variables - foreach (var stream in patchOutputStreams) { - var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; - outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); - buffer.Add(new OpStore(stream.Id, outputResult, null, [])); + // Parameter is "out HS_OUTPUT output" + var outputVariable = arguments[i]; + // Load as value + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(constantsType ?? throw new InvalidOperationException()), context.Bound++, outputVariable, null, [])).ResultId; + // Copy back values from Output struct to semantic/builtin variables + foreach (var stream in patchOutputStreams) + { + var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; + outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); + buffer.Add(new OpStore(stream.Id, outputResult, null, [])); + } + break; } - break; - } } } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 9a99a48b87..7d40305b07 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -36,7 +36,7 @@ public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, _ => entryPoint }; } - + public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext context) { var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); @@ -64,14 +64,14 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); } - + if (entryPointHS != null || entryPointDS != null) context.Add(new OpCapability(Capability.Tessellation)); else if (entryPointGS != null) context.Add(new OpCapability(Capability.Geometry)); var inputAttributes = new List(); - + if (entryPointPS != null) { // If written to, they are expected at the end of pixel shader @@ -131,13 +131,13 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex stream.Value.Output = true; requirePosition = false; } - + if (entryPoint.Item1 == ExecutionModel.TessellationControl && (semantic.ToUpperInvariant().StartsWith("SV_TESSFACTOR") || semantic.ToUpperInvariant().StartsWith("SV_INSIDETESSFACTOR"))) stream.Value.Output = true; } } - + (var wrapperId, var wrapperName) = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); var stage = entryPoint.Item1 switch { @@ -146,17 +146,17 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex ExecutionModel.Geometry => ShaderStage.Geometry, }; entryPoints.Add((wrapperName, wrapperId, stage)); - + // Reset cbuffer/resource/methods used for next stage DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); - + VariableMerger.PropagateStreamsFromPreviousStage(streams); - + if (entryPointVS == null) throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); } } - + if (entryPointVS != null) { ReadWriteAnalyzer.AnalyzeStreamReadWrites(buffer, context, entryPointVS.IdRef, analysisResult, liveAnalysis); @@ -176,12 +176,12 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); - + // Process shader input attributes foreach (var stream in streams) { // Note: built-ins won't have a inputLayoutLocation so they will be skipped - if (stream.Value.Input && stream.Value.InputLayoutLocation is {} inputLayoutLocation) + if (stream.Value.Input && stream.Value.InputLayoutLocation is { } inputLayoutLocation) { if (stream.Value.Semantic == null) throw new InvalidOperationException($"Vertex shader input {stream.Value.Name} doesn't have semantic"); @@ -199,7 +199,7 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex return new(entryPoints, inputAttributes); } - + static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) { foreach (var i in context) @@ -237,7 +237,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) ExecutionModel.TessellationControl => FindOutputPatchSize(context, entryPoint), _ => null, }; - + // Generate stream variables GenerateStreamVariables(context, executionModel, streams, arrayInputSize, arrayOutputSize, out var inputStreams, out var outputStreams, out var patchInputStreams, out var patchOutputStreams); @@ -247,7 +247,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) // Create a static global streams variable var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); context.AddName(streamsVariable.ResultId, $"streams{stage}"); - + // Find patch constant entry point var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; @@ -397,7 +397,7 @@ int RequiredLocations(SymbolType type) Specification.StorageClass.Input); var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); @@ -433,7 +433,7 @@ int RequiredLocations(SymbolType type) Specification.StorageClass.Output); var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - + if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 52f88ec1d1..2214c623dc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -151,7 +151,7 @@ void CheckStreamTypes(int id) accessChain.BaseId = accessChain.BaseId; } } - else if (i.Op == Op.OpBinaryOperationSDSL && (OpBinaryOperationSDSL)i is {} binaryOperation) + else if (i.Op == Op.OpBinaryOperationSDSL && (OpBinaryOperationSDSL)i is { } binaryOperation) { var targetType = (StreamsType)context.ReverseTypes[binaryOperation.ResultType]; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs index d96e218134..bd51f00fd5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs @@ -38,5 +38,5 @@ // words[0] = words.Length << 16; // words[1..].Clear(); // } - + // } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs index 292c96885c..a1e7212820 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs @@ -27,7 +27,7 @@ // //foreach (var e in ordered) // // if(e.OpCode != Op.OpNop) // // temp.Add(e.Words.Span); - + // //buffer.Replace(temp, out var dispose); // //if(dispose) // // temp.Dispose(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs index 1d5ec22c2d..a7a2ae000c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs @@ -22,4 +22,4 @@ static void Apply(SpirvBuffer buffer) var p = new T(); p.Apply(buffer); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs index 99f9c47cae..6b6660cfa6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs @@ -14,5 +14,5 @@ public readonly void Apply(SpirvBuffer buffer) for (int i = 0; i < buffer.Count; i++) if (buffer[i].Op == Op.OpNop) buffer.RemoveAt(i--); - } + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 9d99027e35..331f3c9d18 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -322,7 +322,7 @@ public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) public void RemoveDuplicates() { var buffer = context.GetBuffer(); - + // Note: We process instruction by types depending on their dependencies // i.e. a OpTypeFloat being unified means a OpTypeVector depending on it might too @@ -360,7 +360,7 @@ private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer) { - for (var firstIndex = start; firstIndex < end; ) + for (var firstIndex = start; firstIndex < end;) { var i = buffer[instructionsByOp[firstIndex].Index]; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs index 2643085b1e..80286135c2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs @@ -470,4 +470,4 @@ public readonly void Dispose() key.Dispose(); } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs index 60ba34aafb..7baa47b920 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs @@ -5,4 +5,4 @@ namespace Stride.Shaders.Spirv.Tools; public struct SpirvVal { // public List Passes = []; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs index 06a159535b..eebe86eb49 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/IMemoryInstruction.cs @@ -8,4 +8,4 @@ public interface IMemoryInstruction void Attach(OpDataIndex dataIndex); MemoryOwner InstructionMemory { get; } public void UpdateInstructionMemory(); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs index d3cda1a256..c80fb648ca 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpData.cs @@ -20,7 +20,7 @@ public readonly int? IdResult } public readonly int? IdResultType { - get => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; + get => InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) ? Memory.Span[index + 1] : null; set { if (InstructionInfo.GetInfo(this).GetResultTypeIndex(out var index) && value is not null) @@ -158,4 +158,4 @@ public override string ToString() } return sb.ToString(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs index be1b08777f..ceb8c05995 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/OpDataIndex.cs @@ -4,4 +4,4 @@ public record struct OpDataIndex(int Index, SpirvBuffer Buffer) { public readonly Specification.Op Op => Data.Op; public readonly ref OpData Data => ref Buffer.GetRef(Index); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs index 04badcbd09..5e52e86621 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBuffer.cs @@ -145,7 +145,7 @@ public SpirvBuffer FluentReplace(int index, in T instruction, out T result) w result = instruction; return this; } - + public Enumerator GetEnumerator() => new(this); public struct Enumerator(SpirvBuffer buffer) : IEnumerator @@ -266,4 +266,4 @@ public static LogicalOperandArray GetInfo(this T op) return InstructionInfo.GetInfo(op.OpData); return InstructionInfo.GetInfo(op.InstructionMemory.Span); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs index b177a22012..007a6130ec 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs @@ -39,7 +39,7 @@ public static SpirvBytecode CreateBufferFromBytecode(Span span) { if (span[0] != Specification.MagicNumber) throw new InvalidOperationException("SPIRV Magic number not found"); - + var header = SpirvHeader.Read(span); return new(header, new SpirvBuffer(span[SpirvHeader.IntSpanSize..])); @@ -87,4 +87,4 @@ public static Span CreateBytecodeFromBuffers(SpirvHeader header, bool comp { return MemoryMarshal.AsBytes(CreateSpanFromBuffers(header, computeBounds, buffers).Span); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs b/sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs index 9854e141f4..51715ae06d 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/ISpirvElement.cs @@ -7,4 +7,4 @@ public interface ISpirvElement : IDisposable { ReadOnlySpan Words { get; } public int WordCount { get; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs index 5204533784..046bd27512 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/IWrapperInstruction.cs @@ -3,4 +3,4 @@ namespace Stride.Shaders.Spirv.Core; public interface IWrapperInstruction { Instruction Inner { get; set; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs index e6fc6a57b5..30f2120979 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.cs @@ -36,12 +36,12 @@ internal void Register(Op op, OperandKind? kind, OperandQuantifier? quantifier, public static LogicalOperandArray GetInfo(Op op) => Instance.Info[op]; - public static LogicalOperandArray GetInfo(Span words) + public static LogicalOperandArray GetInfo(Span words) => GetInfo((Op)(words[0] & 0xFFFF)); - public static LogicalOperandArray GetInfo(Instruction instruction) + public static LogicalOperandArray GetInfo(Instruction instruction) => GetInfo(instruction.Words); - + public static LogicalOperandArray GetInfo(OpData instruction) => GetInfo(instruction.Op); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs index 35fb0b15b4..4ffd0f5d50 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperand.cs @@ -21,4 +21,4 @@ public readonly partial record struct LogicalOperand(string? Name, OperandKind? { public LogicalOperand(OperandKind? kind, OperandQuantifier? quantifier, string? name = null) : this(name, kind, quantifier, []) { } public LogicalOperand(string kind, string quantifier, string? name = null) : this(name, Enum.Parse(kind), Enum.Parse(quantifier), []) { } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs index bbb17f2a3d..6496d7c7f1 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/LogicalOperandArray.cs @@ -14,7 +14,7 @@ public readonly struct LogicalOperandArray(string? className, List LogicalOperands { get; } = operands ?? []; public int Count => LogicalOperands.Count; - + public LogicalOperand this[int index] { get => LogicalOperands[index]; @@ -23,7 +23,7 @@ public LogicalOperand this[int index] public bool GetResultIndex(out int index) { - for(int i = 0; i < LogicalOperands.Count; i++) + for (int i = 0; i < LogicalOperands.Count; i++) { var o = LogicalOperands[i]; if (o.Kind == OperandKind.IdResult) @@ -92,4 +92,4 @@ public bool Remove(LogicalOperand item) } public List.Enumerator GetEnumerator() => LogicalOperands.GetEnumerator(); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs index 8f87402f64..a8d8b46f6e 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/EnumerantParameters.cs @@ -86,4 +86,4 @@ public string ReadString() position += lit.Words.Length; return lit.Value; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs index 07161fd69e..8ee4b4de21 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdMemorySemantics.cs @@ -12,4 +12,4 @@ public static IdMemorySemantics From(string value) { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs index 2c3d378def..ca6d299cf5 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdRef.cs @@ -10,7 +10,7 @@ public record struct IdRef : ISpirvElement, IFromSpirv public readonly int Value => Word.Span[0]; public MemoryOwner Word { get; set; } public readonly ReadOnlySpan Words => Word.Span; - + public IdRef(int value) { Word = MemoryOwner.Allocate(1); @@ -40,4 +40,4 @@ public void Dispose() { Word.Dispose(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs index df3522002e..26deeb3b6e 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResult.cs @@ -12,7 +12,7 @@ public record struct IdResult : ISpirvElement, IFromSpirv public readonly int Value => Word.Span[0]; public MemoryOwner Word { get; set; } public readonly ReadOnlySpan Words => Word.Span; - + public IdResult(int value) { Word = MemoryOwner.Allocate(1); @@ -42,4 +42,4 @@ public void Dispose() { Word.Dispose(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs index 58090d7c39..b3f16731cd 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdResultType.cs @@ -12,7 +12,7 @@ public record struct IdResultType : ISpirvElement, IFromSpirv public readonly int Value => Word.Span[0]; public MemoryOwner Word { get; set; } public readonly ReadOnlySpan Words => Word.Span; - + public IdResultType(int value) { Word = MemoryOwner.Allocate(1); @@ -42,4 +42,4 @@ public void Dispose() { Word.Dispose(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs index 854855814a..295b6bdaaa 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/IdScope.cs @@ -12,7 +12,7 @@ public record struct IdScope : ISpirvElement, IFromSpirv public readonly int Value => Word.Span[0]; public MemoryOwner Word { get; set; } public readonly ReadOnlySpan Words => Word.Span; - + public IdScope(int value) { Word = MemoryOwner.Allocate(1); @@ -42,4 +42,4 @@ public void Dispose() { Word.Dispose(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs index f68e2181db..328c37e86b 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralArray.cs @@ -49,7 +49,7 @@ public LiteralArray() { Elements = MemoryOwner.Empty; } - + public LiteralArray(MemoryOwner elements) { Elements = elements; @@ -175,4 +175,4 @@ public static LiteralArray From(string value) { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs index 6df38cf9e4..e72c867f0c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralFloat.cs @@ -140,4 +140,4 @@ public void Dispose() { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs index f6b289646c..4ec42db27e 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralString.cs @@ -25,7 +25,7 @@ public LiteralString(string value) { Value = pool.GetOrAdd(value); Memory = MemoryOwner.Allocate(WordCount); - + } public LiteralString(Span words) { @@ -38,7 +38,8 @@ public LiteralString(Span words) chars[i * 4 + 1] = (char)(words[i] >> 8 & 0xFF); chars[i * 4 + 2] = (char)(words[i] >> 16 & 0xFF); chars[i * 4 + 3] = (char)(words[i] >> 24 & 0xFF); - }; + } + ; var real = chars[..chars.IndexOf('\0')]; Value = pool.GetOrAdd(real); } @@ -73,4 +74,4 @@ public void Dispose() { Memory.Dispose(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index dc8e2cad7a..68d28bfa74 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -299,4 +299,4 @@ public void Add(int value) public readonly Span.Enumerator GetEnumerator() => Memory.Span[..Length].GetEnumerator(); public readonly void Dispose() => Memory.Dispose(); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs index bdebe600f9..e489ec7316 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefIdRef.cs @@ -5,8 +5,8 @@ namespace Stride.Shaders.Spirv.Core; public struct PairIdRefIdRef : ISpirvElement, IFromSpirv { - public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } - public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } + public readonly int Item1 { get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2 { get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; MemoryOwner Memory { get; set; } public readonly ReadOnlySpan Words => Memory.Span; @@ -36,4 +36,4 @@ public void Dispose() { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs index fcf6307cf9..398af5ebf7 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairIdRefLiteralInteger.cs @@ -4,8 +4,8 @@ namespace Stride.Shaders.Spirv.Core; public struct PairIdRefLiteralInteger : ISpirvElement, IFromSpirv { - public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } - public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } + public readonly int Item1 { get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2 { get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; MemoryOwner Memory { get; set; } public readonly ReadOnlySpan Words => Memory.Span; @@ -35,4 +35,4 @@ public void Dispose() { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs index e3ef1824a5..abfb7b461c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/PairLiteralIntegerIdRef.cs @@ -5,8 +5,8 @@ namespace Stride.Shaders.Spirv.Core; public struct PairLiteralIntegerIdRef : ISpirvElement, IFromSpirv { - public readonly int Item1{ get => Memory.Span[0]; set => Memory.Span[0] = value; } - public readonly int Item2{ get => Memory.Span[1]; set => Memory.Span[1] = value; } + public readonly int Item1 { get => Memory.Span[0]; set => Memory.Span[0] = value; } + public readonly int Item2 { get => Memory.Span[1]; set => Memory.Span[1] = value; } public readonly int WordCount => 2; MemoryOwner Memory { get; set; } public readonly ReadOnlySpan Words => Memory.Span; @@ -36,4 +36,4 @@ public void Dispose() { throw new NotImplementedException(); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs index 0cf9a891b1..671fb84d0a 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/ParameterizedFlag.cs @@ -20,4 +20,4 @@ public readonly override string ToString() { return $"{Value}"; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs index e51e5a3237..986665bcf5 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/SpvOp.cs @@ -16,4 +16,4 @@ namespace Stride.Shaders.Spirv.Core; // { // throw new NotImplementedException(); // } -// } \ No newline at end of file +// } diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs b/sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs index 86d2c2d12b..afb584666e 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/MemoryInstruction.cs @@ -84,7 +84,7 @@ public override string ToString() return (ResultId == null ? "" : $"%{ResultId} = ") + $"{OpCode} {string.Join(" ", Operands.ToArray().Select(x => x.ToString()))}"; } - public int? GetResultId() + public int? GetResultId() { TryGetOperand("resultId", out var resultId); return resultId; diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs b/sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs index 2e080fe9f1..6e38151348 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/OperandQuantifier.cs @@ -1,8 +1,8 @@ namespace Stride.Shaders.Spirv.Core; -public enum OperandQuantifier +public enum OperandQuantifier { One, ZeroOrOne, ZeroOrMore -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 44393407d9..20ea35928d 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -165,4 +165,4 @@ public SpvOperand ParseCurrent() }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs index ef5dbfb0dd..6011731555 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OperandEnumerator.cs @@ -25,7 +25,7 @@ public bool MoveNext() return false; return true; } - else if(oid >= logicalOperands.Count - 1) + else if (oid >= logicalOperands.Count - 1) return false; else { @@ -167,4 +167,4 @@ public SpvOperand ParseCurrent() } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs index b0e70d135d..80cd3db0bf 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvHeader.cs @@ -25,7 +25,7 @@ public SpirvVersion(int major, int minor) } public SpirvVersion(string version) { - if(version.Length == 3 && char.IsDigit(version[0]) && version[1] == '.' && char.IsDigit(version[2])) + if (version.Length == 3 && char.IsDigit(version[0]) && version[1] == '.' && char.IsDigit(version[2])) { Version = version[0] - '0' << 16 | version[2] - '0' << 8; } diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs index ddf137b6d6..09bb2c71af 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/SpirvReader.cs @@ -23,7 +23,7 @@ public ref struct Enumerator(Span words) public bool MoveNext() { - if(wid == 0 && words[0] == Specification.MagicNumber) + if (wid == 0 && words[0] == Specification.MagicNumber) { wid = 5; return true; diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs b/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs index 1a6c77e403..e5fe34bd92 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/SpirvValue.cs @@ -6,7 +6,7 @@ namespace Stride.Shaders.Spirv.Core; /// A SPIR-V value representing the result of an instruction /// public struct SpirvValue -{ +{ /// IdResult of the instruction /// IdResultType of the instruction /// Optional name attached to the value diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs b/sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs index 23bd77311a..091deb0f33 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/SpvLiteral.cs @@ -207,4 +207,4 @@ public override string ToString() _ => Words[0].ToString() }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs b/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs index b67520088c..7d834fec82 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs @@ -22,8 +22,8 @@ public static int LengthOfString(this Span ints) public static int GetWordCount(this string s) { var length = s.Length + 1; // +1 for the null terminator - if(length % 4 == 0) + if (length % 4 == 0) return length / 4; return (length / 4) + 1; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs index b191e1dba4..21c4f3714c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Data.cs @@ -154,4 +154,4 @@ public SpirvGrammar() GLSLDoc = ""; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs index 4fce6b4bd5..d8d3059b7d 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableArray.cs @@ -18,7 +18,7 @@ public class EquatableArrayJsonConverter : JsonConverter> public override EquatableArray Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var array = JsonSerializer.Deserialize(ref reader, options) ?? []; - return new EquatableArray([..array]); + return new EquatableArray([.. array]); } public override void Write(Utf8JsonWriter writer, EquatableArray value, JsonSerializerOptions options) @@ -138,4 +138,4 @@ IEnumerator IEnumerable.GetEnumerator() public static implicit operator EquatableArray(T[] arr) => new(arr); public static implicit operator EquatableArray(List list) => new([.. list]); public static implicit operator EquatableArray(ImmutableArray list) => new([.. list]); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs index 1c5dbd6f47..a4623f8742 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableDictionary.cs @@ -16,13 +16,13 @@ public class EquatableDictionaryJsonConverter : JsonConverter where TValue : IEquatable { - public override EquatableDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + public override EquatableDictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - var dict = JsonSerializer.Deserialize>(ref reader, options) ?? []; + var dict = JsonSerializer.Deserialize>(ref reader, options) ?? []; return new EquatableDictionary(dict); } - public override void Write(Utf8JsonWriter writer, EquatableDictionary value, JsonSerializerOptions options) + public override void Write(Utf8JsonWriter writer, EquatableDictionary value, JsonSerializerOptions options) { JsonSerializer.Serialize(value.AsDictionary(), options); } @@ -43,7 +43,7 @@ public readonly struct EquatableDictionary(Dictionary /// The underlying array. /// - private readonly Dictionary? _dict = dict; + private readonly Dictionary? _dict = dict; /// /// Gets the length of the array, or 0 if the array is null @@ -88,7 +88,7 @@ public override bool Equals(object? obj) /// public override int GetHashCode() { - if (_dict is not Dictionary dict) + if (_dict is not Dictionary dict) { return 0; } @@ -122,5 +122,5 @@ IEnumerator IEnumerable.GetEnumerator() return GetEnumerator(); } - public static implicit operator EquatableDictionary(Dictionary dict) => new(dict); -} \ No newline at end of file + public static implicit operator EquatableDictionary(Dictionary dict) => new(dict); +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs index d6ca68b626..330b582da4 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/EquatableList.cs @@ -17,7 +17,7 @@ public class EquatableListJsonConverter : JsonConverter> public override EquatableList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var array = JsonSerializer.Deserialize(ref reader, options) ?? []; - return new EquatableList([..array]); + return new EquatableList([.. array]); } public override void Write(Utf8JsonWriter writer, EquatableList value, JsonSerializerOptions options) @@ -122,4 +122,4 @@ IEnumerator IEnumerable.GetEnumerator() } public static implicit operator EquatableList(List list) => new([.. list]); -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs index 644f7780fa..9582685785 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Buffers.cs @@ -224,4 +224,4 @@ public static void CreateGlslOperation(InstructionData op, StringBuilder code, D .AppendLine("}"); } } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs index 23ba4be82b..7cc1ec1464 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs @@ -263,4 +263,4 @@ public static string ToCSType(this string kind) _ => kind }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs index 4396a19af2..5960acccd4 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs @@ -15,9 +15,9 @@ public static SourceText ToSourceText(this StringBuilder builder) SyntaxFactory .ParseCompilationUnit(builder.ToString()) .NormalizeWhitespace() - .ToFullString(), + .ToFullString(), Encoding.UTF8 ); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 0bcb5d7d98..f49f03028f 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -293,4 +293,4 @@ public static string ConvertOperandName(string input, string? quant = null, bool static string LowerFirst(string s) => char.IsLower(s[0]) ? s : $"{char.ToLowerInvariant(s[0])}{s[1..]}"; -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index e3c4296696..34763c274b 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -201,4 +201,4 @@ public static string KindToVariableName(string kind) _ => kind.Replace("'", "").Replace(" ", "").ToLowerInvariant() }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 176046f986..8847293a59 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -222,4 +222,4 @@ public static void GenerateInfo(InstructionData op, StringBuilder code, SpirvGra else code.Append("Instance.Register(Op.").Append(opname).AppendLine(", OperandKind.None, null, \"Debug\");"); } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index b0ad1fc9e9..31d94795da 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -399,4 +399,4 @@ static string ToSpreadOperator(OperandData operand) _ => $".. {fieldName}.AsDisposableLiteralValue().Words" }; } -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 589122704c..9f18159358 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -76,7 +76,7 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList CompileShader(string shaderModel, string source) { ComPtr code = default; @@ -256,7 +256,7 @@ public void PresentAndFinish() public unsafe void Compute() { ComPtr computeCode = CompileShader("cs_5_0", ComputeShaderSource); - + // Create vertex shader. SilkMarshal.ThrowHResult ( @@ -270,7 +270,7 @@ ref computeShader ); deviceContext.CSSetShader(computeShader, ref Unsafe.NullRef>(), 0); - + ApplyParameters(); deviceContext.Dispatch(32, 32, 1); @@ -297,7 +297,7 @@ ref Unsafe.NullRef(), ref vertexShader ) ); - + // Create geometry shader. if (geometryCode.Handle != null) { @@ -324,7 +324,7 @@ ref Unsafe.NullRef(), ref pixelShader ) ); - + // Describe the layout of the input data for the shader. fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) @@ -416,7 +416,7 @@ ref inputLayout ) ); } - + ComPtr renderTexture = default; ComPtr renderTextureStaging = default; @@ -484,10 +484,10 @@ ref renderTextureStaging deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); ApplyParameters(); - + // Draw the quad. deviceContext.DrawIndexed(6, 0, 0); - + deviceContext.CopyResource(renderTextureStaging, renderTexture); MappedSubresource mappedResource = default; @@ -507,7 +507,7 @@ ref renderTextureStaging renderTargetView.Dispose(); framebuffer.Dispose(); - + vertexCode.Dispose(); pixelCode.Dispose(); } diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 07089d552b..26d2d56a22 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -36,11 +36,11 @@ public void ComputeTest1(string shaderName) var shaderSource = ShaderMixinManager.Contains(shaderName) ? new ShaderMixinGeneratorSource(shaderName) : (ShaderSource)new ShaderClassSource(shaderName); - + // Force file to be parsed and all its shaders registered // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); @@ -50,21 +50,21 @@ public void ComputeTest1(string shaderName) var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); var codeCS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.GLCompute)); - + Console.WriteLine(codeCS); - + // Execute test var renderer = new D3D11FrameRenderer((uint)width, (uint)height); - + renderer.ComputeShaderSource = codeCS; renderer.EffectReflection = effectReflection; - + var code = File.ReadAllLines($"./assets/SDSL/ComputeTests/{shaderName}.sdsl"); foreach (var test in TestHeaderParser.ParseHeaders(code)) { var parameters = TestHeaderParser.ParseParameters(test.Parameters); SetupTestParameters(renderer, parameters); - + renderer.SetupTest(); renderer.Compute(); // Present is useful for RenderDoc and other graphics capture programs @@ -120,7 +120,7 @@ public void RenderTest1(string shaderName) renderer.GeometryShaderSource = codeGS; renderer.PixelShaderSource = codePS; renderer.EffectReflection = effectReflection; - + var code = File.ReadAllLines($"./assets/SDSL/RenderTests/{shaderName}.sdsl"); foreach (var test in TestHeaderParser.ParseHeaders(code)) { diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs index bb60495791..762feb2d5f 100644 --- a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -18,10 +18,10 @@ protected override bool ExternalFileExists(string name) public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { filename = $"{basePath}/{name}.sdsl"; - + var fileData = File.ReadAllBytes(filename); hash = ObjectId.FromBytes(fileData); - + // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); code = reader.ReadToEnd(); diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index ac638718fb..ad4bbcfb75 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -71,7 +71,7 @@ public override TaskOrResult Compile(ShaderMixinSo var bytecode = new KeyValuePair(null, EffectBytecodeCacheLoadSource.JustCompiled); lock (bytecodes) - { + { // ------------------------------------------------------------------------------------------------------------ // 1) Try to load latest bytecode // ------------------------------------------------------------------------------------------------------------ @@ -157,7 +157,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree // Note: this compiler is expected to not be async and directly write stuff in localLogger var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters).WaitForResult(); compiledShader.CompilationLog.CopyTo(log); - + // If there are any errors, return immediately if (log.HasErrors) { @@ -180,7 +180,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree // TODO: Check if we really need to write the bytecode everytime even if id is not changed var memoryStream = new MemoryStream(); compiledShader.Bytecode.WriteTo(memoryStream); - + // Write current cache at the end (not part of the pure bytecode, but we use this as meta info) var writer = new BinarySerializationWriter(memoryStream); writer.Write(CurrentCache); @@ -290,5 +290,5 @@ private bool IsBytecodeObsolete(EffectBytecode bytecode) } return false; } - } + } } diff --git a/sources/shaders/Stride.Shaders/EffectBytecode.cs b/sources/shaders/Stride.Shaders/EffectBytecode.cs index 2b343fcd70..9e9342786d 100644 --- a/sources/shaders/Stride.Shaders/EffectBytecode.cs +++ b/sources/shaders/Stride.Shaders/EffectBytecode.cs @@ -52,9 +52,9 @@ public ObjectId ComputeId() // We should most of the time have stages, unless someone is calling this method on a new EffectBytecode if (effectBytecode.Stages is not null) { - effectBytecode = (EffectBytecode) MemberwiseClone(); + effectBytecode = (EffectBytecode)MemberwiseClone(); - effectBytecode.Stages = (ShaderBytecode[]) effectBytecode.Stages.Clone(); + effectBytecode.Stages = (ShaderBytecode[])effectBytecode.Stages.Clone(); // Because ShaderBytecode.Data can vary, we are calculating the bytecodeId only with the ShaderBytecode.Id for (int i = 0; i < effectBytecode.Stages.Length; i++) diff --git a/sources/shaders/Stride.Shaders/ShaderArraySource.cs b/sources/shaders/Stride.Shaders/ShaderArraySource.cs index 1db96a0179..2cc2371c2e 100644 --- a/sources/shaders/Stride.Shaders/ShaderArraySource.cs +++ b/sources/shaders/Stride.Shaders/ShaderArraySource.cs @@ -80,7 +80,7 @@ public override int GetHashCode() if (Values != null) { foreach (var current in Values) - hashCode = (hashCode*397) ^ (current?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); } return hashCode; } diff --git a/sources/shaders/Stride.Shaders/ShaderBytecode.cs b/sources/shaders/Stride.Shaders/ShaderBytecode.cs index c88066ca2c..965348d63a 100644 --- a/sources/shaders/Stride.Shaders/ShaderBytecode.cs +++ b/sources/shaders/Stride.Shaders/ShaderBytecode.cs @@ -61,7 +61,7 @@ public ShaderBytecode(ShaderStage stage, ObjectId id, byte[] data) /// A shallow copy of the current instance. public ShaderBytecode Clone() { - return (ShaderBytecode) MemberwiseClone(); + return (ShaderBytecode)MemberwiseClone(); } /// diff --git a/sources/shaders/Stride.Shaders/ShaderClassCode.cs b/sources/shaders/Stride.Shaders/ShaderClassCode.cs index 453a2f40b2..6ce80a4b31 100644 --- a/sources/shaders/Stride.Shaders/ShaderClassCode.cs +++ b/sources/shaders/Stride.Shaders/ShaderClassCode.cs @@ -57,7 +57,7 @@ public string ToClassName() return result.ToString(); } - + public override string ToString() { return ToClassName(); diff --git a/sources/shaders/Stride.Shaders/ShaderClassSource.cs b/sources/shaders/Stride.Shaders/ShaderClassSource.cs index 63571907b3..30dbbd64dc 100644 --- a/sources/shaders/Stride.Shaders/ShaderClassSource.cs +++ b/sources/shaders/Stride.Shaders/ShaderClassSource.cs @@ -109,7 +109,7 @@ public override object Clone() { return new ShaderClassSource(ClassName, GenericArguments = GenericArguments != null ? GenericArguments.ToArray() : null); } - + public override string ToString() { return ToClassName(); diff --git a/sources/shaders/Stride.Shaders/ShaderClassString.cs b/sources/shaders/Stride.Shaders/ShaderClassString.cs index b97cd22bb6..0a0525d1e8 100644 --- a/sources/shaders/Stride.Shaders/ShaderClassString.cs +++ b/sources/shaders/Stride.Shaders/ShaderClassString.cs @@ -112,7 +112,7 @@ public override object Clone() { return new ShaderClassString(ClassName, ShaderSourceCode, GenericArguments = GenericArguments != null ? GenericArguments.ToArray() : null); } - + public override string ToString() { return ToClassName(); diff --git a/sources/shaders/Stride.Shaders/ShaderMixinContext.cs b/sources/shaders/Stride.Shaders/ShaderMixinContext.cs index 2b19724f51..6b21102b37 100644 --- a/sources/shaders/Stride.Shaders/ShaderMixinContext.cs +++ b/sources/shaders/Stride.Shaders/ShaderMixinContext.cs @@ -146,7 +146,7 @@ private ParameterCollection FindKeyValue(PermutationParameterKey key, out selectedKey = key; return compilerParameters; } - + return null; } @@ -225,7 +225,7 @@ public void Mixin(ShaderMixinSource mixinTree, string name, params object[] gene { // Else simply add the name of the shader mixinTree.Mixins.Add(new ShaderClassSource(name, genericParameters)); - } + } else if (builder != null) { if (genericParameters != null && genericParameters.Length != 0) From e1a76455147ef29848a1972bdf55194905badbce Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 13:18:15 +0900 Subject: [PATCH 0853/1182] SDSL: remove unused globals --- .../Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs | 5 +++-- .../Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index 0c84f4f364..7abc7a26d2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -87,9 +87,10 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup, + Storageclass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, ResultId: int - } variable) + } variable + && context.ReverseTypes[variable.ResultType] is PointerType { BaseType: not ConstantBufferSymbol }) { var name = nameTable.TryGetValue(variable.ResultId, out var nameId) ? nameId diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 341683b198..fd8f19dcdb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -1,4 +1,5 @@ using System.Runtime.InteropServices; +using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -146,9 +147,10 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup, + Storageclass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, ResultId: int - } variable2) + } variable2 + && context.ReverseTypes[variable2.ResultType] is PointerType { BaseType: not ConstantBufferSymbol }) { if (variable2.Flags.HasFlag(VariableFlagsMask.Stream)) { From 46fc6d6396cb86d5cd709bd67de8ae4038ff7b78 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 13:39:05 +0900 Subject: [PATCH 0854/1182] SDSL: in hull shader, when reading tessellation constants, OpAccessChain was not using pointer type --- .../Interfaces/Generation/EntryPointWrapperGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 6e017265c2..dae2e50dcf 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -225,7 +225,7 @@ void FillTessellationArguments(Symbol function, Span arguments) // Copy back values from semantic/builtin variables to Constants struct foreach (var stream in patchInputStreams) { - var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(stream.Info.Type), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, stream.Id, null, [])).ResultId; inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); buffer.Add(new OpStore(inputPtr, inputResult, null, [])); From b759a12dd0c265ebb4556216c0e9dbb7303ae510 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 14:06:38 +0900 Subject: [PATCH 0855/1182] Vulkan: process buffer copy for staging resources the same way we do for texture --- .../engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs | 8 ++++++++ .../Stride.Graphics/Vulkan/CompiledCommandList.Vulkan.cs | 2 +- .../Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index 68f2217854..9fe40d92e5 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -1037,6 +1037,14 @@ public unsafe void Copy(GraphicsResource source, GraphicsResource destination) }; GraphicsDevice.NativeDeviceApi.vkCmdCopyBuffer(currentCommandList.NativeCommandBuffer, sourceBuffer.NativeBuffer, destinationBuffer.NativeBuffer, regionCount: 1, ©); + if (destinationBuffer.Usage == GraphicsResourceUsage.Staging) + { + // VkFence for host access + destinationBuffer.CommandListFenceValue = null; + destinationBuffer.UpdatingCommandList = this; + currentCommandList.StagingResources.Add(destinationBuffer); + } + bufferBarriers[0] = new VkBufferMemoryBarrier(sourceBuffer.NativeBuffer, VkAccessFlags.TransferRead, sourceBuffer.NativeAccessMask); bufferBarriers[1] = new VkBufferMemoryBarrier(destinationBuffer.NativeBuffer, VkAccessFlags.TransferWrite, destinationBuffer.NativeAccessMask); GraphicsDevice.NativeDeviceApi.vkCmdPipelineBarrier(currentCommandList.NativeCommandBuffer, VkPipelineStageFlags.Transfer, sourceBuffer.NativePipelineStageMask, VkDependencyFlags.None, memoryBarrierCount: 0, memoryBarriers: null, bufferMemoryBarrierCount: 2, bufferBarriers, imageMemoryBarrierCount: 0, imageMemoryBarriers: null); diff --git a/sources/engine/Stride.Graphics/Vulkan/CompiledCommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CompiledCommandList.Vulkan.cs index 116970c956..9c1d6dcebe 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CompiledCommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CompiledCommandList.Vulkan.cs @@ -11,7 +11,7 @@ public partial struct CompiledCommandList internal CommandList Builder; internal VkCommandBuffer NativeCommandBuffer; internal List DescriptorPools; - internal List StagingResources; + internal List StagingResources; } } #endif diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index a9da96914f..38d5050bbe 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -20,7 +20,7 @@ public partial class GraphicsDevice internal int ConstantBufferDataPlacementAlignment; internal readonly ConcurrentPool> DescriptorPoolLists = new ConcurrentPool>(() => new List()); - internal readonly ConcurrentPool> StagingResourceLists = new ConcurrentPool>(() => new List()); + internal readonly ConcurrentPool> StagingResourceLists = new ConcurrentPool>(() => new List()); private const GraphicsPlatform GraphicPlatform = GraphicsPlatform.Vulkan; internal GraphicsProfile RequestedProfile; From b0da8f5e79cea360b904e5f46418deb4ace30e82 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 21:12:02 +0900 Subject: [PATCH 0856/1182] SDSL: When adding patch constant to output in hull shader, make sure to add the same in domain shader to avoid Vulkan warning --- .../SDSL/ShaderMixer.cs | 2 +- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 4 + .../Interfaces/Cleanup/VariableMerger.cs | 1 + .../Generation/EntryPointWrapperGenerator.cs | 5 +- .../Interfaces/InterfaceProcessor.cs | 93 ++++++++++++++----- .../Interfaces/Models/StreamVariableInfo.cs | 10 +- 6 files changed, 89 insertions(+), 26 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 08470157c1..24e15859c5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -26,7 +26,7 @@ public record struct Options(bool ResourcesRegisterSeparate); public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List<(string Name, int Id, ShaderStage Stage)> entryPoints) + public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List entryPoints) { // Create new buffer for the merged result var temp = new SpirvBuffer(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index ce9b646b34..70b9d2fd19 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -91,7 +91,11 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont // If read on input/output stream, we force it to be emitted in the input/output struct if (streamKind == StreamsKindSDSL.Output) + { + if (!streamInfo.Output) + streamInfo.InternalPatchConstantOutput = true; streamInfo.Output = true; + } else if (streamKind == StreamsKindSDSL.Input) streamInfo.Read = true; else diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs index 9621e944ac..88c305ef6f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/VariableMerger.cs @@ -63,6 +63,7 @@ public static void PropagateStreamsFromPreviousStage(Dictionary arguments) } liveAnalysis.ExtraReferencedMethods.Add(newEntryPointFunction); - context.Add(new OpEntryPoint(executionModel, newEntryPointFunction, entryPointName, [.. entryPointInterfaceVariables.Slice(0, pvariableIndex)])); - return (newEntryPointFunction.ResultId, entryPointName); + return new InterfaceProcessor.EntryPointInfo(entryPointName, newEntryPointFunction.ResultId, executionModel, [.. entryPointInterfaceVariables.Slice(0, pvariableIndex)]) { ArrayInputSize = streamLayout.ArrayInputSize }; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 7d40305b07..6d642da3b8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -25,7 +25,35 @@ public class InterfaceProcessor { public Action? CodeInserted { get; set; } - public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, List InputAttributes); + public class EntryPointInfo + { + internal EntryPointInfo(string name, int id, ExecutionModel model, List interfaceVariables) + { + Name = name; + Id = id; + Model = model; + InterfaceVariables = interfaceVariables; + Stage = model switch + { + ExecutionModel.Vertex => ShaderStage.Vertex, + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + ExecutionModel.Fragment => ShaderStage.Pixel, + ExecutionModel.GLCompute => ShaderStage.Compute, + _ => throw new NotImplementedException() + }; + } + + public string Name { get; } + public int Id { get; } + public ShaderStage Stage { get; } + internal ExecutionModel Model { get; } + internal List InterfaceVariables { get; } + internal int? ArrayInputSize { get; init; } + } + + public record Result(List EntryPoints, List InputAttributes); Symbol? ResolveEntryPoint(SymbolTable table, string name) { @@ -39,7 +67,8 @@ public record Result(List<(string Name, int Id, ShaderStage Stage)> EntryPoints, public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext context) { - var entryPoints = new List<(string Name, int Id, ShaderStage Stage)>(); + // OpEntryPoint emission is deferred to allow fixups (e.g. adding dummy DS inputs for HS-internal outputs) + var entryPoints = new List(); var entryPointVS = ResolveEntryPoint(table, "VSMain"); var entryPointHS = ResolveEntryPoint(table, "HSMain"); @@ -61,8 +90,7 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex if (entryPointCS != null) { - (var csWrapperId, var csWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false); - entryPoints.Add((csWrapperName, csWrapperId, ShaderStage.Compute)); + entryPoints.Add(GenerateStreamWrapper(table, buffer, context, ExecutionModel.GLCompute, entryPointCS, analysisResult, liveAnalysis, false)); } if (entryPointHS != null || entryPointDS != null) @@ -88,10 +116,10 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) if (streams.Any(x => x.Value.Output)) { - (var psWrapperId, var psWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); - entryPoints.Add((psWrapperName, psWrapperId, ShaderStage.Pixel)); + var psEntry = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); + entryPoints.Add(psEntry); - buffer.Add(new OpExecutionMode(psWrapperId, ExecutionMode.OriginUpperLeft, [])); + buffer.Add(new OpExecutionMode(psEntry.Id, ExecutionMode.OriginUpperLeft, [])); } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages @@ -138,14 +166,34 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex } } - (var wrapperId, var wrapperName) = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); - var stage = entryPoint.Item1 switch + var entry = GenerateStreamWrapper(table, buffer, context, entryPoint.Item1, entryPoint.Item2, analysisResult, liveAnalysis, false); + entryPoints.Add(entry); + + // After HS processing, add dummy DS inputs for HS-internal outputs to avoid Vulkan interface mismatch warning + if (entryPoint.Item1 == ExecutionModel.TessellationControl) { - ExecutionModel.TessellationControl => ShaderStage.Hull, - ExecutionModel.TessellationEvaluation => ShaderStage.Domain, - ExecutionModel.Geometry => ShaderStage.Geometry, - }; - entryPoints.Add((wrapperName, wrapperId, stage)); + var dsEntryPoint = entryPoints.FirstOrDefault(ep => ep.Model == ExecutionModel.TessellationEvaluation); + if (dsEntryPoint.InterfaceVariables != null) + { + foreach (var stream in streams) + { + if (stream.Value.InternalPatchConstantOutput && stream.Value.OutputLayoutLocation is { } location) + { + // Create a dummy Input variable in DS with the same Location to match the HS output + var dummyInputId = context.Bound++; + var variableType = stream.Value.Type; + var inputPointerType = new PointerType( + !stream.Value.Patch && dsEntryPoint.ArrayInputSize is { } arrayInputSize ? new ArrayType(variableType, arrayInputSize) : variableType, + Specification.StorageClass.Input); + context.Add(new OpVariable(context.GetOrRegister(inputPointerType), dummyInputId, Specification.StorageClass.Input, null)); + context.Add(new OpDecorate(dummyInputId, Decoration.Location, [location])); + if (variableType is ScalarType or VectorType or MatrixType && !variableType.GetElementType().IsFloating()) + context.Add(new OpDecorate(dummyInputId, Decoration.Flat, [])); + dsEntryPoint.InterfaceVariables.Add(dummyInputId); + } + } + } + } // Reset cbuffer/resource/methods used for next stage DeadCodeRemover.ResetUsedThisStage(analysisResult, liveAnalysis); @@ -153,7 +201,7 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex VariableMerger.PropagateStreamsFromPreviousStage(streams); if (entryPointVS == null) - throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {stage} shader is specified, a vertex shader is needed too"); + throw new InvalidOperationException($"{nameof(InterfaceProcessor)}: If a {entry.Stage} shader is specified, a vertex shader is needed too"); } } @@ -174,8 +222,7 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex } } - (var vsWrapperId, var vsWrapperName) = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true); - entryPoints.Add((vsWrapperName, vsWrapperId, ShaderStage.Vertex)); + entryPoints.Add(GenerateStreamWrapper(table, buffer, context, ExecutionModel.Vertex, entryPointVS, analysisResult, liveAnalysis, true)); // Process shader input attributes foreach (var stream in streams) @@ -192,6 +239,10 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex } } + // Emit all OpEntryPoints (deferred to allow fixups like adding dummy DS inputs for HS-internal outputs) + foreach (var ep in entryPoints) + context.Add(new OpEntryPoint(ep.Model, ep.Id, ep.Name, [.. ep.InterfaceVariables])); + // This will remove a lot of unused methods, resources and variables // (while following proper rules to preserve rgroup, cbuffer, logical groups, etc.) DeadCodeRemover.RemoveUnreferencedCode(buffer, context, analysisResult, liveAnalysis); @@ -218,7 +269,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) throw new InvalidOperationException($"outputcontrolpoints not found on hull shader {entryPoint.Id.Name}"); } - private (int Id, string Name) GenerateStreamWrapper(SymbolTable table, SpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) + private EntryPointInfo GenerateStreamWrapper(SymbolTable table, SpirvBuffer buffer, SpirvContext context, ExecutionModel executionModel, Symbol entryPoint, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, bool isFirstActiveShader) { var streams = analysisResult.Streams; @@ -252,7 +303,7 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; // Generate entry point wrapper - var (newEntryPointFunctionResultId, entryPointName) = EntryPointWrapperGenerator.GenerateWrapper(context, + var entryPointInfo = EntryPointWrapperGenerator.GenerateWrapper(context, buffer, entryPoint, executionModel, analysisResult, liveAnalysis, inputStreams, outputStreams, patchInputStreams, patchOutputStreams, inputType, outputType, streamsType, @@ -275,11 +326,11 @@ static int FindOutputPatchSize(SpirvContext context, Symbol entryPoint) if (i.Op == Op.OpExecutionMode && (OpExecutionMode)i is { } executionMode) { if (executionMode.EntryPoint == entryPoint.IdRef) - executionMode.EntryPoint = newEntryPointFunctionResultId; + executionMode.EntryPoint = entryPointInfo.Id; } } - return (newEntryPointFunctionResultId, entryPointName); + return entryPointInfo; } private static string ExecutionModelToStageId(ExecutionModel executionModel) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs index 4742b843a2..716254566f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StreamVariableInfo.cs @@ -27,8 +27,16 @@ internal class StreamVariableInfo(string? semantic, string name, PointerType typ /// public bool Input => Read || (Output && !Write); public bool Output { get => field; set { field = value; UsedAnyStage = true; } } - public bool UsedThisStage => Input || Output || Read || Write; + public bool UsedThisStage => Input || Output || InternalPatchConstantOutput || Read || Write; + /// + /// When true, this variable is only used to transfer data from the hull shader main function + /// to the patch constant function (via inter-invocation Output read after barrier). + /// It still needs a StorageClass.Output variable with a Location, but the next stage (DS) + /// doesn't consume it, so a dummy matching Input variable is added to DS to satisfy + /// Vulkan interface matching requirements. + /// + public bool InternalPatchConstantOutput { get => field; set { field = value; UsedAnyStage = true; } } public bool Read { get => field; set { field = value; UsedAnyStage = true; } } public bool Write { get => field; set { field = value; UsedAnyStage = true; } } public bool UsedAnyStage { get; private set; } From 7dd2e23526776f699321f24608f5e7c8c216ea96 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 21:28:08 +0900 Subject: [PATCH 0857/1182] SDSL: simplified arguments to GenerateWrapper by using a record struct --- .../Generation/EntryPointWrapperGenerator.cs | 90 +++++++++---------- .../Interfaces/InterfaceProcessor.cs | 9 +- .../Interfaces/Models/StageStreamLayout.cs | 19 ++++ 3 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StageStreamLayout.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 181d660d3a..4c9f40f14c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -18,17 +18,7 @@ public static InterfaceProcessor.EntryPointInfo GenerateWrapper(SpirvContext con ExecutionModel executionModel, AnalysisResult analysisResult, LiveAnalysis liveAnalysis, - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> inputStreams, - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams, - List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams, - StructType inputType, - StructType outputType, - StructType streamsType, - StructType? constantsType, - int? arrayInputSize, - int? arrayOutputSize, - int streamsVariableId, + StageStreamLayout streamLayout, Symbol? patchConstantEntryPoint) { var entryPointFunctionType = (FunctionType)entryPoint.Type; @@ -117,40 +107,40 @@ void FillSemanticArguments(FunctionType functionType, Span arguments) FillSemanticArguments(entryPointFunctionType, arguments); // Setup input and call original main() - if (arrayInputSize != null) + if (streamLayout.ArrayInputSize != null) { // Copy variables to Input[X] which is first method parameter of main() // Pattern is a loop over index i looking like: // inputs[i].Position = gl_Position[i]; // inputs[i].Normal = in_GS_normals[i]; - var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(inputType, arrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var inputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(streamLayout.InputType, streamLayout.ArrayInputSize.Value), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; context.AddName(inputsVariable, "inputs"); int ConvertInputsArray() { - Span inputLoadValues = stackalloc int[inputType.Members.Count]; - for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + Span inputLoadValues = stackalloc int[streamLayout.InputType.Members.Count]; + for (var inputIndex = 0; inputIndex < streamLayout.InputStreams.Count; inputIndex++) { - var stream = inputStreams[inputIndex]; - var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, arrayInputSize.Value)), context.Bound++, stream.Id, null, [])); + var stream = streamLayout.InputStreams[inputIndex]; + var loadedValue = buffer.Add(new OpLoad(context.GetOrRegister(new ArrayType(stream.Info.Type, streamLayout.ArrayInputSize.Value)), context.Bound++, stream.Id, null, [])); inputLoadValues[inputIndex] = loadedValue.ResultId; } - Span inputFieldValues = stackalloc int[inputType.Members.Count]; - Span inputValues = stackalloc int[arrayInputSize.Value]; - for (int arrayIndex = 0; arrayIndex < arrayInputSize; ++arrayIndex) + Span inputFieldValues = stackalloc int[streamLayout.InputType.Members.Count]; + Span inputValues = stackalloc int[streamLayout.ArrayInputSize.Value]; + for (int arrayIndex = 0; arrayIndex < streamLayout.ArrayInputSize; ++arrayIndex) { - for (var inputIndex = 0; inputIndex < inputStreams.Count; inputIndex++) + for (var inputIndex = 0; inputIndex < streamLayout.InputStreams.Count; inputIndex++) { - var stream = inputStreams[inputIndex]; + var stream = streamLayout.InputStreams[inputIndex]; inputFieldValues[inputIndex] = buffer.Add(new OpCompositeExtract(context.Types[stream.Info.Type], context.Bound++, inputLoadValues[inputIndex], [arrayIndex])).ResultId; inputFieldValues[inputIndex] = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputFieldValues[inputIndex]); } - inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(inputType), context.Bound++, [.. inputFieldValues])).ResultId; + inputValues[arrayIndex] = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(streamLayout.InputType), context.Bound++, [.. inputFieldValues])).ResultId; } - var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(inputType, arrayInputSize.Value)), context.Bound++, [.. inputValues])).ResultId; + var inputsData1 = buffer.Add(new OpCompositeConstruct(context.GetOrRegister(new ArrayType(streamLayout.InputType, streamLayout.ArrayInputSize.Value)), context.Bound++, [.. inputValues])).ResultId; return inputsData1; } @@ -162,22 +152,22 @@ int ConvertInputsArray() if (executionModel == ExecutionModel.TessellationControl || executionModel == ExecutionModel.TessellationEvaluation) { var arraySize = executionModel == ExecutionModel.TessellationControl - ? arrayOutputSize ?? throw new InvalidOperationException("Can't figure array output size for tessellation shader") - : arrayInputSize.Value; + ? streamLayout.ArrayOutputSize ?? throw new InvalidOperationException("Can't figure array output size for tessellation shader") + : streamLayout.ArrayInputSize.Value; bool hullTessellationOutputsGenerated = false; int GenerateHullTessellationOutputs() { if (hullTessellationOutputsGenerated) throw new InvalidOperationException("Hull OutputPatch can only be used in once place (constant patch)"); hullTessellationOutputsGenerated = true; - var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(outputType, arraySize), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var outputsVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(new ArrayType(streamLayout.OutputType, arraySize), Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; context.AddName(outputsVariable, "outputs"); for (int arrayIndex = 0; arrayIndex < arraySize; ++arrayIndex) { - for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + for (var outputIndex = 0; outputIndex < streamLayout.OutputStreams.Count; outputIndex++) { - var stream = outputStreams[outputIndex]; + var stream = streamLayout.OutputStreams[outputIndex]; var outputsVariablePtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), context.Bound++, outputsVariable, [context.CompileConstant(arrayIndex).Id, context.CompileConstant(outputIndex).Id])).ResultId; @@ -220,10 +210,10 @@ void FillTessellationArguments(Symbol function, Span arguments) case StreamsType t when t.Kind is StreamsKindSDSL.Constants && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: { // Parameter is "HS_CONSTANTS constants" - var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(constantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(streamLayout.ConstantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = constantVariable; // Copy back values from semantic/builtin variables to Constants struct - foreach (var stream in patchInputStreams) + foreach (var stream in streamLayout.PatchInputStreams) { var inputPtr = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Function)), context.Bound++, constantVariable, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; var inputResult = buffer.Add(new OpLoad(context.GetOrRegister(stream.Info.Type), context.Bound++, stream.Id, null, [])).ResultId; @@ -237,8 +227,8 @@ void FillTessellationArguments(Symbol function, Span arguments) // Parameter is "out HS_OUTPUT output" or "out HS_CONSTANTS constants" var structType = t.Kind switch { - StreamsKindSDSL.Output => outputType, - StreamsKindSDSL.Constants => constantsType, + StreamsKindSDSL.Output => streamLayout.OutputType, + StreamsKindSDSL.Constants => streamLayout.ConstantsType, }; var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = outVariable; @@ -264,16 +254,16 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(outputType), context.Bound++, outputVariable, null, [])).ResultId; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(streamLayout.OutputType), context.Bound++, outputVariable, null, [])).ResultId; // Do we need to index into array? if yes, get index (gl_invocationID) - int? invocationIdValue = arrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; + int? invocationIdValue = streamLayout.ArrayOutputSize != null ? GetOrDeclareBuiltInValue(ScalarType.UInt, "SV_OutputControlPointID") : null; // Copy back values from Output struct to semantic/builtin variables - for (var outputIndex = 0; outputIndex < outputStreams.Count; outputIndex++) + for (var outputIndex = 0; outputIndex < streamLayout.OutputStreams.Count; outputIndex++) { - var stream = outputStreams[outputIndex]; + var stream = streamLayout.OutputStreams[outputIndex]; var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [outputIndex])).ResultId; outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); - var outputTargetPtr = arrayOutputSize != null + var outputTargetPtr = streamLayout.ArrayOutputSize != null ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), context.Bound++, stream.Id, [invocationIdValue.Value])).ResultId @@ -287,9 +277,9 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Parameter is "out HS_OUTPUT output" var outputVariable = arguments[i]; // Load as value - outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(constantsType ?? throw new InvalidOperationException()), context.Bound++, outputVariable, null, [])).ResultId; + outputVariable = buffer.Add(new OpLoad(context.GetOrRegister(streamLayout.ConstantsType ?? throw new InvalidOperationException()), context.Bound++, outputVariable, null, [])).ResultId; // Copy back values from Output struct to semantic/builtin variables - foreach (var stream in patchOutputStreams) + foreach (var stream in streamLayout.PatchOutputStreams) { var outputResult = buffer.Add(new OpCompositeExtract(context.GetOrRegister(stream.Info.Type), context.Bound++, outputVariable, [stream.Info.StreamStructFieldIndex])).ResultId; outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); @@ -381,9 +371,9 @@ void ProcessTessellationArguments(Symbol function, Span arguments) // Note: we could in the future support having Input/Output in the function signature, just like we do for HS/DS/GS // Copy variables from input to streams struct - foreach (var stream in inputStreams) + foreach (var stream in streamLayout.InputStreams) { - var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamLayout.StreamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; var inputResult = buffer.Add(new OpLoad(context.Types[stream.Info.Type], context.Bound++, stream.Id, null, [])).ResultId; inputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.InterfaceType, stream.Info.Type, inputResult); buffer.Add(new OpStore(streamPointer, inputResult, null, [])); @@ -393,10 +383,10 @@ void ProcessTessellationArguments(Symbol function, Span arguments) buffer.Add(new OpFunctionCall(voidType, context.Bound++, entryPoint.IdRef, new(arguments))); // Copy variables from streams struct to output - foreach (var stream in outputStreams) + foreach (var stream in streamLayout.OutputStreams) { var baseType = stream.Info.Type; - var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; + var streamPointer = buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Private)), context.Bound++, streamLayout.StreamsVariableId, [context.CompileConstant(stream.Info.StreamStructFieldIndex).Id])).ResultId; var outputResult = buffer.Add(new OpLoad(context.Types[baseType], context.Bound++, streamPointer, null, [])).ResultId; outputResult = BuiltinProcessor.ConvertInterfaceVariable(buffer, context, stream.Info.Type, stream.InterfaceType, outputResult); buffer.Add(new OpStore(stream.Id, outputResult, null, [])); @@ -407,17 +397,17 @@ void ProcessTessellationArguments(Symbol function, Span arguments) buffer.Add(new OpFunctionEnd()); // Note: we overallocate and filter with UsedThisStage after - Span entryPointInterfaceVariables = stackalloc int[inputStreams.Count + outputStreams.Count + patchInputStreams.Count + patchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; + Span entryPointInterfaceVariables = stackalloc int[streamLayout.InputStreams.Count + streamLayout.OutputStreams.Count + streamLayout.PatchInputStreams.Count + streamLayout.PatchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; int pvariableIndex = 0; - foreach (var inputStream in inputStreams) + foreach (var inputStream in streamLayout.InputStreams) entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; - foreach (var outputStream in outputStreams) + foreach (var outputStream in streamLayout.OutputStreams) entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; - foreach (var inputStream in patchInputStreams) + foreach (var inputStream in streamLayout.PatchInputStreams) entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; - foreach (var outputStream in patchOutputStreams) + foreach (var outputStream in streamLayout.PatchOutputStreams) entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; - entryPointInterfaceVariables[pvariableIndex++] = streamsVariableId; + entryPointInterfaceVariables[pvariableIndex++] = streamLayout.StreamsVariableId; foreach (var variable in analysisResult.Variables) { if (variable.Value.UsedThisStage) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 6d642da3b8..b28f35b629 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -1,4 +1,4 @@ -using Stride.Shaders.Core; +using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; @@ -299,16 +299,15 @@ private EntryPointInfo GenerateStreamWrapper(SymbolTable table, SpirvBuffer buff var streamsVariable = context.Add(new OpVariable(context.GetOrRegister(new PointerType(streamsType, Specification.StorageClass.Private)), context.Bound++, Specification.StorageClass.Private, null)); context.AddName(streamsVariable.ResultId, $"streams{stage}"); + var streamLayout = new StageStreamLayout(inputStreams, outputStreams, patchInputStreams, patchOutputStreams, inputType, outputType, streamsType, constantsType, arrayInputSize, arrayOutputSize, streamsVariable.ResultId); + // Find patch constant entry point var patchConstantEntryPoint = executionModel == ExecutionModel.TessellationControl ? ResolveHullPatchConstantEntryPoint(table, context, entryPoint) : null; // Generate entry point wrapper var entryPointInfo = EntryPointWrapperGenerator.GenerateWrapper(context, buffer, entryPoint, executionModel, analysisResult, - liveAnalysis, inputStreams, outputStreams, patchInputStreams, - patchOutputStreams, inputType, outputType, streamsType, - constantsType, arrayInputSize, arrayOutputSize, streamsVariable.ResultId, - patchConstantEntryPoint); + liveAnalysis, streamLayout, patchConstantEntryPoint); // Patch any OpStreams/OpAccessChain to use the new struct foreach (var method in liveAnalysis.ReferencedMethods) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StageStreamLayout.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StageStreamLayout.cs new file mode 100644 index 0000000000..534468bf4f --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/StageStreamLayout.cs @@ -0,0 +1,19 @@ +using Stride.Shaders.Core; + +namespace Stride.Shaders.Spirv.Processing.Interfaces.Models; + +/// +/// Groups all stream-related data for a shader stage: interface variables, struct types, and array sizes. +/// +internal record struct StageStreamLayout( + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> InputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> OutputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> PatchInputStreams, + List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> PatchOutputStreams, + StructType InputType, + StructType OutputType, + StructType StreamsType, + StructType? ConstantsType, + int? ArrayInputSize, + int? ArrayOutputSize, + int StreamsVariableId); From 71138a45369cd978b9cf54d6f694ae488faec629 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Feb 2026 01:29:39 +0900 Subject: [PATCH 0858/1182] Vulkan: tessellation support --- sources/engine/Stride.Engine.Tests/TesselationTest.cs | 2 -- .../Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs | 1 + .../Stride.Graphics/Vulkan/PipelineState.Vulkan.cs | 11 ++++++----- .../Stride.Graphics/Vulkan/VulkanConvertExtensions.cs | 4 +++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Engine.Tests/TesselationTest.cs b/sources/engine/Stride.Engine.Tests/TesselationTest.cs index b00497cb1c..a5e1d52827 100644 --- a/sources/engine/Stride.Engine.Tests/TesselationTest.cs +++ b/sources/engine/Stride.Engine.Tests/TesselationTest.cs @@ -201,8 +201,6 @@ private void ChangeMaterial(int i) [SkippableFact] public void RunTestGame() { - SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); - RunGameTest(new TesselationTest()); } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index 38d5050bbe..3f555d98d2 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -376,6 +376,7 @@ void SetMaxDescriptorTypeCount(VkDescriptorType type, uint limit) shaderCullDistance = true, samplerAnisotropy = true, depthClamp = true, + tessellationShader = RequestedProfile >= GraphicsProfile.Level_11_0, }; NativeInstanceApi.vkGetPhysicalDeviceFeatures(NativePhysicalDevice, out var deviceFeatures); diff --git a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs index 5e1285aa66..83ae943248 100644 --- a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs @@ -128,7 +128,7 @@ private unsafe void RecreateInner() primitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType) }; - // TODO VULKAN: Tessellation and multisampling + // TODO VULKAN: Multisampling var multisampleState = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo, @@ -137,7 +137,8 @@ private unsafe void RecreateInner() var tessellationState = new VkPipelineTessellationStateCreateInfo { - sType = VkStructureType.PipelineTessellationStateCreateInfo + sType = VkStructureType.PipelineTessellationStateCreateInfo, + patchControlPoints = (uint)(Description.PrimitiveType >= PrimitiveType.PatchList && Description.PrimitiveType < PrimitiveType.PatchList + 32 ? Description.PrimitiveType - PrimitiveType.PatchList + 1 : 0), }; var rasterizationState = CreateRasterizationState(Description.RasterizerState); @@ -212,7 +213,6 @@ private unsafe void RecreateInner() layout = NativeLayout, stageCount = (uint)stages.Length, pStages = stages.Length > 0 ? fStages : null, - //tessellationState = &tessellationState, pVertexInputState = &vertexInputState, pInputAssemblyState = &inputAssemblyState, pRasterizationState = &rasterizationState, @@ -221,8 +221,9 @@ private unsafe void RecreateInner() pColorBlendState = &colorBlendState, pDynamicState = &dynamicState, pViewportState = &viewportState, + pTessellationState = &tessellationState, renderPass = NativeRenderPass, - subpass = 0 + subpass = 0, }; fixed (VkPipeline* nativePipelinePtr = &NativePipeline) GraphicsDevice.CheckResult(GraphicsDevice.NativeDeviceApi.vkCreateGraphicsPipelines(GraphicsDevice.NativeDevice, VkPipelineCache.Null, createInfoCount: 1, &createInfo, allocator: null, nativePipelinePtr)); @@ -436,7 +437,7 @@ private unsafe VkPipelineShaderStageCreateInfo[] CreateShaderStages(PipelineStat for (int i = 0; i < stages.Length; i++) { var stage = stages[i]; - if (stage.Data != shaderBytecode) + if (!stage.Data.SequenceEqual(shaderBytecode)) throw new InvalidOperationException("Vulkan: bytecode is expected to be the same for all stages"); if (stage.Stage == ShaderStage.Compute) diff --git a/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs b/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs index 180bcc2668..e052c16c26 100644 --- a/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs +++ b/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs @@ -63,6 +63,8 @@ public static VkPrimitiveTopology ConvertPrimitiveType(PrimitiveType primitiveTy return VkPrimitiveTopology.TriangleListWithAdjacency; case PrimitiveType.TriangleStripWithAdjacency: return VkPrimitiveTopology.TriangleStripWithAdjacency; + case >= PrimitiveType.PatchList and < PrimitiveType.PatchList + 32: + return VkPrimitiveTopology.PatchList; default: throw new ArgumentOutOfRangeException(nameof(primitiveType)); } @@ -77,7 +79,7 @@ public static bool ConvertPrimitiveRestart(PrimitiveType primitiveType) case PrimitiveType.TriangleList: case PrimitiveType.LineListWithAdjacency: case PrimitiveType.TriangleListWithAdjacency: - case PrimitiveType.PatchList: + case >= PrimitiveType.PatchList and < PrimitiveType.PatchList + 32: return false; default: return true; From 7c78bfea78fc1d9db65c6487a7c9d80f19faa2aa Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 22 Feb 2026 14:26:11 +0100 Subject: [PATCH 0859/1182] NumberLiteral ToString uses invariant culture. --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index a9123fee92..91e2ab500f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -11,6 +11,7 @@ using System.Numerics; using System.Reflection; using System.Text; +using System.Globalization; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -69,7 +70,7 @@ public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info public override string ToString() { - return $"{Value}{Suffix}"; + return string.Create(CultureInfo.InvariantCulture, $"{Value}{Suffix}"); } } From e4d904cb2955a6951c33df74da2cbae798c0d81d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 00:30:02 +0900 Subject: [PATCH 0860/1182] SDSL: added rcp() intrinsic --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index a7473bb55a..5e92c9fc1b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -228,6 +228,13 @@ public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builde } public override SpirvValue CompileFrac(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFract, x); + public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var constant1 = builder.Convert(context, context.CompileConstant(1.0f), functionType.ReturnType); + var instruction = builder.Insert(new OpFDiv(context.GetOrRegister(functionType.ReturnType), context.Bound++, constant1.Id, x.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + // Compute Barriers const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; @@ -292,7 +299,6 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileProcessTriTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); public override SpirvValue CompileProcessTriTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); public override SpirvValue CompileProcessTriTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); - public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileReversebits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileSource_mark(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileTranspose(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); From 3f629339788ecfceed4e730fe84a9a32989ce66b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 01:42:41 +0900 Subject: [PATCH 0861/1182] SDSL: added support for ByteAddressBuffer --- .../SDSL/ShaderMixer.Reflection.cs | 12 +- .../EffectCodeWriter.cs | 4 +- .../Core/SymbolTypes.cs | 9 + ...ByteAddressBufferMethodsImplementations.cs | 270 ++++++++++++++++++ .../Parsing/SDSL/AST/Expression.cs | 5 +- .../Parsing/SDSL/AST/IntrinsicCall.cs | 3 + .../SDSL/AST/IntrinsicTemplateExpander.cs | 17 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 4 +- .../Spirv/Building/SpirvContext.Types.cs | 15 + .../Stride.Shaders.Tests.csproj | 1 + .../ComputeTests/CSByteAddressBuffer.sdsl | 22 ++ 11 files changed, 354 insertions(+), 8 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs create mode 100644 sources/shaders/assets/SDSL/ComputeTests/CSByteAddressBuffer.sdsl diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index bfafac79a6..5be4ea1bf6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -18,7 +18,7 @@ private record struct CBufferMemberMetadata(string? Link = null, string? Logical private Dictionary cbufferMemberMetadata = new(); private static bool IsResourceType(SymbolType type) - => type is TextureType or SamplerType or BufferType or StructuredBufferType or ConstantBufferSymbol; + => type is TextureType or SamplerType or BufferType or StructuredBufferType or ByteAddressBufferType or ConstantBufferSymbol; // Process LinkSDSL, ResourceGroupSDSL and LogicalGroupSDSL; Info will be stored in resourceLinks and cbufferMemberLinks private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) @@ -319,13 +319,14 @@ or Specification.Decoration.SamplerStateMinLOD LogicalGroup = linkInfo.LogicalGroup, }; - if (variableType is TextureType or BufferType or StructuredBufferType) + if (variableType is TextureType or BufferType or StructuredBufferType or ByteAddressBufferType) { bool isUAV = variableType switch { TextureType t1 => t1.Sampled == 2, BufferType b1 => b1.WriteAllowed, StructuredBufferType sb1 => sb1.WriteAllowed, + ByteAddressBufferType bab1 => bab1.WriteAllowed, }; ref var slot = ref (isUAV ? ref uavSlot : ref srvSlot); effectResourceBinding.Class = isUAV ? EffectParameterClass.UnorderedAccessView : EffectParameterClass.ShaderResourceView; @@ -372,6 +373,13 @@ or Specification.Decoration.SamplerStateMinLOD // This will add array stride and offsets decorations EmitTypeDecorationsRecursively(context, baseType, SpirvBuilder.AlignmentRules.StructuredBuffer); } + else if (variableType is ByteAddressBufferType byteAddressBufferType) + { + globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + { + Type = byteAddressBufferType.WriteAllowed ? EffectParameterType.RWByteAddressBuffer : EffectParameterType.ByteAddressBuffer, + }); + } } else if (variableType is SamplerType) { diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index cc561e8cdc..67e41cb541 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -112,7 +112,7 @@ protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Ident parameterType = a.BaseType; } - if (parameterType is ShaderSymbol or TextureType or BufferType or StructuredBufferType or SamplerType) + if (parameterType is ShaderSymbol or TextureType or BufferType or StructuredBufferType or ByteAddressBufferType or SamplerType) { parameterKeyType = "Object"; } @@ -417,7 +417,7 @@ public override void VisitTypeName(TypeName typeName) { Write("Matrix"); } - else if (typeName.Type is BufferType or StructuredBufferType) + else if (typeName.Type is BufferType or StructuredBufferType or ByteAddressBufferType) { Write("Buffer"); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 0b576086f8..2d5f8a66f7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -78,6 +78,9 @@ static ScalarType ResolveScalarType(TypeName? templateTypeName) "Buffer" => new BufferType(ResolveScalarType(templateTypeName)), "RWBuffer" => new BufferType(ResolveScalarType(templateTypeName), true), + "ByteAddressBuffer" => new ByteAddressBufferType(false), + "RWByteAddressBuffer" => new ByteAddressBufferType(true), + "Texture1D" => new Texture1DType(ResolveScalarType(templateTypeName)), "Texture2D" => new Texture2DType(ResolveScalarType(templateTypeName)), "Texture2DMS" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true }, @@ -273,6 +276,12 @@ public sealed partial record BufferType(ScalarType BaseType, bool WriteAllowed = public override string ToString() => $"{(WriteAllowed ? "RW" : "")}Buffer<{BaseType}>"; } +public sealed partial record ByteAddressBufferType(bool WriteAllowed = false) : SymbolType() +{ + public override string ToId() => $"{(WriteAllowed ? "RW" : "")}ByteAddressBuffer"; + public override string ToString() => $"{(WriteAllowed ? "RW" : "")}ByteAddressBuffer"; +} + // TODO: Add sampler parameters public sealed partial record SamplerType() : SymbolType() { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs new file mode 100644 index 0000000000..349bd69659 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs @@ -0,0 +1,270 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Parsing.SDSL; + +public class ByteAddressBufferMethodsImplementations : ByteAddressBufferMethodsDeclarations +{ + public static ByteAddressBufferMethodsImplementations Instance { get; } = new(); + + /// + /// Compute the uint element index from a byte offset: index = byteOffset >> 2 + /// + private SpirvValue ComputeElementIndex(SpirvContext context, SpirvBuilder builder, SpirvValue byteOffset) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var const2 = context.CompileConstant((uint)2); + return new(builder.InsertData(new OpShiftRightLogical(uintType, context.Bound++, byteOffset.Id, const2.Id))); + } + + /// + /// Get a pointer to a uint element at a given byte offset in the buffer. + /// The buffer is a pointer to a struct { uint[] }, so we access chain: buffer -> member 0 (runtime array) -> element index. + /// + private SpirvValue AccessChainAtByteOffset(SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset) + { + var index = ComputeElementIndex(context, builder, byteOffset); + var ptrUintType = context.GetOrRegister(new PointerType(ScalarType.UInt, StorageClass.StorageBuffer)); + var const0 = context.CompileConstant((int)0); + return new(builder.InsertData(new OpAccessChain(ptrUintType, context.Bound++, bufferPtr.Id, [const0.Id, index.Id]))); + } + + /// + /// Get a pointer to a uint element at a given byte offset + additional uint offset. + /// + private SpirvValue AccessChainAtByteOffsetPlus(SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset, int extraUintOffset) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var index = ComputeElementIndex(context, builder, byteOffset); + if (extraUintOffset > 0) + { + var offset = context.CompileConstant((uint)extraUintOffset); + index = new(builder.InsertData(new OpIAdd(uintType, context.Bound++, index.Id, offset.Id))); + } + var ptrUintType = context.GetOrRegister(new PointerType(ScalarType.UInt, StorageClass.StorageBuffer)); + var const0 = context.CompileConstant((int)0); + return new(builder.InsertData(new OpAccessChain(ptrUintType, context.Bound++, bufferPtr.Id, [const0.Id, index.Id]))); + } + + // Load(uint byteOffset) -> uint + public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); + + var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); + var uintType = context.GetOrRegister(ScalarType.UInt); + var loadResult = builder.Insert(new OpLoad(uintType, context.Bound++, ptr.Id, null, [])); + + // If the return type is different from uint (e.g., $funcT resolved to something else), bitcast + var returnType = functionType.ReturnType; + if (returnType != ScalarType.UInt) + { + var result = builder.Insert(new OpBitcast(context.GetOrRegister(returnType), context.Bound++, loadResult.ResultId)); + return new(result.ResultId, result.ResultType); + } + + return new(loadResult.ResultId, loadResult.ResultType); + } + + // Load2(uint byteOffset) -> uint2 + public override SpirvValue CompileLoad2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); + + return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 2); + } + + // Load3(uint byteOffset) -> uint3 + public override SpirvValue CompileLoad3(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); + + return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 3); + } + + // Load4(uint byteOffset) -> uint4 + public override SpirvValue CompileLoad4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); + + return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 4); + } + + private SpirvValue LoadN(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue bufferPtr, SpirvValue byteOffset, int count) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + Span values = stackalloc int[count]; + for (int i = 0; i < count; i++) + { + var ptr = AccessChainAtByteOffsetPlus(context, builder, bufferPtr, byteOffset, i); + values[i] = builder.Insert(new OpLoad(uintType, context.Bound++, ptr.Id, null, [])).ResultId; + } + + var returnTypeId = context.GetOrRegister(functionType.ReturnType); + var composite = builder.InsertData(new OpCompositeConstruct(returnTypeId, context.Bound++, [.. values])); + return new(composite); + } + + // Store(uint byteOffset, T value) + public override SpirvValue CompileStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + { + // If the value is not uint, bitcast to uint first + var valueType = context.ReverseTypes[value.TypeId]; + if (valueType != ScalarType.UInt) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + value = new(builder.InsertData(new OpBitcast(uintType, context.Bound++, value.Id))); + } + + var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); + builder.Insert(new OpStore(ptr.Id, value.Id, null, [])); + return default; + } + + // Store2(uint byteOffset, uint2 value) + public override SpirvValue CompileStore2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + { + StoreN(context, builder, byteAddressBuffer, byteOffset, value, 2); + return default; + } + + // Store3(uint byteOffset, uint3 value) + public override SpirvValue CompileStore3(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + { + StoreN(context, builder, byteAddressBuffer, byteOffset, value, 3); + return default; + } + + // Store4(uint byteOffset, uint4 value) + public override SpirvValue CompileStore4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + { + StoreN(context, builder, byteAddressBuffer, byteOffset, value, 4); + return default; + } + + private void StoreN(SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset, SpirvValue value, int count) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + for (int i = 0; i < count; i++) + { + var component = builder.Insert(new OpCompositeExtract(uintType, context.Bound++, value.Id, [i])); + var ptr = AccessChainAtByteOffsetPlus(context, builder, bufferPtr, byteOffset, i); + builder.Insert(new OpStore(ptr.Id, component.ResultId, null, [])); + } + } + + // GetDimensions(out uint width) - returns buffer size in bytes + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue width) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + // OpArrayLength returns number of elements in the runtime array (member 0) + var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, byteAddressBuffer.Id, 0)); + // Multiply by 4 to convert from element count to byte count + var const4 = context.CompileConstant((uint)4); + var byteSize = builder.Insert(new OpIMul(uintType, context.Bound++, arrayLen.ResultId, const4.Id)); + // Store result to the out parameter + builder.Insert(new OpStore(width.Id, byteSize.ResultId, null, [])); + return default; + } + + // InterlockedAdd(uint byteOffset, uint value [, out uint original]) + public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Add); + } + + // InterlockedMin(uint byteOffset, uint/int value [, out uint original]) + public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.UMin); + } + + // InterlockedMax(uint byteOffset, uint/int value [, out uint original]) + public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.UMax); + } + + // InterlockedAnd(uint byteOffset, uint value [, out uint original]) + public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.And); + } + + // InterlockedOr(uint byteOffset, uint value [, out uint original]) + public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Or); + } + + // InterlockedXor(uint byteOffset, uint value [, out uint original]) + public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Xor); + } + + // InterlockedExchange(uint byteOffset, uint value, out uint original) + public override SpirvValue CompileInterlockedExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue original) + { + return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Exchange); + } + + // InterlockedCompareStore(uint byteOffset, uint compare, uint value) + public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value) + { + var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); + var uintType = context.GetOrRegister(ScalarType.UInt); + var scopeDevice = context.CompileConstant((uint)Scope.Device); + var memSemanticsNone = context.CompileConstant((uint)0); + // OpAtomicCompareExchange: result = (original == compare) ? value : original + builder.Insert(new OpAtomicCompareExchange(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, memSemanticsNone.Id, value.Id, compare.Id)); + return default; + } + + // InterlockedCompareExchange(uint byteOffset, uint compare, uint value, out uint original) + public override SpirvValue CompileInterlockedCompareExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value, SpirvValue original) + { + var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); + var uintType = context.GetOrRegister(ScalarType.UInt); + var scopeDevice = context.CompileConstant((uint)Scope.Device); + var memSemanticsNone = context.CompileConstant((uint)0); + var result = builder.Insert(new OpAtomicCompareExchange(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, memSemanticsNone.Id, value.Id, compare.Id)); + builder.Insert(new OpStore(original.Id, result.ResultId, null, [])); + return default; + } + + private enum AtomicOp { Add, UMin, UMax, And, Or, Xor, Exchange } + + private SpirvValue CompileAtomicOp(SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset, SpirvValue value, SpirvValue? original, AtomicOp op) + { + var ptr = AccessChainAtByteOffset(context, builder, bufferPtr, byteOffset); + var uintType = context.GetOrRegister(ScalarType.UInt); + var scopeDevice = context.CompileConstant((uint)Scope.Device); + var memSemanticsNone = context.CompileConstant((uint)0); + + var resultId = op switch + { + AtomicOp.Add => builder.Insert(new OpAtomicIAdd(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.UMin => builder.Insert(new OpAtomicUMin(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.UMax => builder.Insert(new OpAtomicUMax(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.And => builder.Insert(new OpAtomicAnd(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.Or => builder.Insert(new OpAtomicOr(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.Xor => builder.Insert(new OpAtomicXor(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + AtomicOp.Exchange => builder.Insert(new OpAtomicExchange(uintType, context.Bound++, ptr.Id, scopeDevice.Id, memSemanticsNone.Id, value.Id)).ResultId, + _ => throw new NotImplementedException($"Atomic operation {op} not implemented"), + }; + + if (original != null) + { + builder.Insert(new OpStore(original.Value.Id, resultId, null, [])); + } + + return default; + } +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index c41fd17324..decc237af2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -160,7 +160,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) SpirvValue result; if (resolvedIntrinsicOverload != null) { - SpirvValue? @this = MemberCall != null ? builder.AsValue(context, MemberCall.Value) : null; + // ByteAddressBuffer needs the pointer for OpAccessChain, not the loaded struct value + SpirvValue? @this = MemberCall != null + ? (MemberCallBaseType is ByteAddressBufferType ? MemberCall.Value : builder.AsValue(context, MemberCall.Value)) + : null; result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler, resolvedIntrinsicNamespace, name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams); } else diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index 22649fd308..c8fafaef33 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -53,6 +53,9 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na StructuredBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.StructuredBufferMethods), IntrinsicsDefinitions.StructuredBufferMethods), null), StructuredBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWStructuredBufferMethods), IntrinsicsDefinitions.RWStructuredBufferMethods), null), + + ByteAddressBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.ByteAddressBufferMethods), IntrinsicsDefinitions.ByteAddressBufferMethods), ByteAddressBufferMethodsImplementations.Instance), + ByteAddressBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWByteAddressBufferMethods), IntrinsicsDefinitions.RWByteAddressBufferMethods), ByteAddressBufferMethodsImplementations.Instance), }; if (!templateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index e895538637..aef32f54a1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -163,8 +163,8 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.Numeric32Only => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt], BaseType.Any => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean], BaseType.Match => throw new InvalidOperationException(), - BaseType.ByteAddressBuffer => throw new NotImplementedException(), - BaseType.RWByteAddressBuffer => throw new NotImplementedException(), + BaseType.ByteAddressBuffer => [new ByteAddressBufferType(false)], + BaseType.RWByteAddressBuffer => [new ByteAddressBufferType(true)], BaseType.VkBufferPointer => throw new NotImplementedException(), BaseType.Other => throw new NotImplementedException(), BaseType.Texture2DArray => throw new NotImplementedException(), @@ -186,6 +186,10 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) sizeSequences.Add(new(sizePermutationGenerator.Generate())); var sizePermutations = CartesianProduct.Generate(sizeSequences); + // If there are no size permutations, we still need one iteration to generate the signature + if (sizePermutations.Count == 0) + sizePermutations.Add([]); + // Step 4: generate signature using permutations ParameterTypeInfo[] parameterTypeHelper = new ParameterTypeInfo[intrinsicDefinition.Parameters.Length + 1]; SymbolType[] parameterTypes = new SymbolType[intrinsicDefinition.Parameters.Length + 1]; @@ -250,6 +254,15 @@ ParameterTypeInfo GetParameterInfo(int index) BufferType b => new(b.BaseType, new(4, null), default), }; } + if (index == -3) + { + return thisType switch + { + null => throw new ArgumentNullException(nameof(thisType)), + ByteAddressBufferType => new(ScalarType.UInt, new(1, null), default), + _ => throw new NotImplementedException($"$funcT not supported for {thisType}"), + }; + } return parameterTypeHelper[index]; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4b1ce26e98..911faebcce 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -202,7 +202,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var storageClass = (memberType, StorageClass, StreamKind) switch { (TextureType or BufferType, _, _) => Specification.StorageClass.UniformConstant, - (StructuredBufferType, _, _) => Specification.StorageClass.StorageBuffer, + (StructuredBufferType or ByteAddressBufferType, _, _) => Specification.StorageClass.StorageBuffer, (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, (_, StorageClass.Static, _) => Specification.StorageClass.Private, (_, _, StreamKind.Stream or StreamKind.PatchStream) => Specification.StorageClass.Private, @@ -293,6 +293,8 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (pointerType.BaseType is StructuredBufferType) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"structuredbuffer:<{pointerType.BaseType.ToId().ToLowerInvariant()}>")); + else if (pointerType.BaseType is ByteAddressBufferType) + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, "byteaddressbuffer")); RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index a7cd9ede21..d6168d8f6d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -86,6 +86,7 @@ public int RegisterType(SymbolType type, int id) BufferType b => Buffer.AddData(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, StructuredBufferType b => RegisterStructuredBufferType(b), + ByteAddressBufferType b => RegisterByteAddressBufferType(b), SampledImage si => Buffer.AddData(new OpTypeSampledImage(id, GetOrRegister(si.ImageType))).IdResult, GenericParameterType g => Buffer.AddData(new OpTypeGenericSDSL(id, g.Kind)).IdResult, StreamsType s => Buffer.AddData(new OpTypeStreamsSDSL(id, s.Kind)).IdResult, @@ -113,6 +114,20 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy return bufferType; } + private int RegisterByteAddressBufferType(ByteAddressBufferType byteAddressBufferType) + { + var uintTypeId = GetOrRegister(ScalarType.UInt); + var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, uintTypeId)).ResultId; + Buffer.Add(new OpDecorate(runtimeArrayType, Specification.Decoration.ArrayStride, [4])); + + var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; + AddName(bufferType, $"type.{(byteAddressBufferType.WriteAllowed ? "RW" : "")}ByteAddressBuffer"); + Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); + Buffer.Add(new OpDecorate(bufferType, Specification.Decoration.Block, [])); + + return bufferType; + } + private int RegisterArrayType(ArrayType a) { int sizeId; diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index efd3088852..5fa99b7949 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -36,6 +36,7 @@ + diff --git a/sources/shaders/assets/SDSL/ComputeTests/CSByteAddressBuffer.sdsl b/sources/shaders/assets/SDSL/ComputeTests/CSByteAddressBuffer.sdsl new file mode 100644 index 0000000000..f9a9d4b621 --- /dev/null +++ b/sources/shaders/assets/SDSL/ComputeTests/CSByteAddressBuffer.sdsl @@ -0,0 +1,22 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +shader CSByteAddressBuffer +{ + stage stream uint3 GroupId : SV_GroupID; + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + stage stream uint3 GroupThreadId : SV_GroupThreadID; + stage stream uint GroupIndex : SV_GroupIndex; + + ByteAddressBuffer Input; + RWByteAddressBuffer Output; + + [numthreads(32, 32, 1)] + void CSMain() + { + uint val = Input.Load(0); + Output.Store(0, val); + Output.InterlockedAdd(0, 1); + } +} From 0f4fe2e6a81bf5a61bf7de69a2bde59d417e16d3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 16:10:35 +0900 Subject: [PATCH 0862/1182] SDSL: Better merge ArrayStride and other decorations --- .../SDSL/ShaderMixer.cs | 31 ++++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 3 + .../Spirv/Building/SpirvContext.Types.cs | 15 +++ .../Spirv/Processing/TypeDuplicatesRemover.cs | 101 +++++++++++++++++- 4 files changed, 136 insertions(+), 14 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 24e15859c5..f11e0e4111 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -12,6 +12,7 @@ using Stride.Shaders.Spirv.Processing.Interfaces; using static Stride.Shaders.Spirv.Specification; using EntryPoint = Stride.Shaders.Core.EntryPoint; +using Stride.Core.Diagnostics; using Stride.Core.UnsafeExtensions; namespace Stride.Shaders.Compilers.SDSL; @@ -34,6 +35,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span // This is the global context for this merge operation var context = new SpirvContext(); context.Add(new OpCapability(Capability.Shader)); + context.Add(new OpExtension("SPV_GOOGLE_user_type")); context.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); var shaderLoader = new CaptureLoadedShaders(ShaderLoader); var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; @@ -52,12 +54,13 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, null, shaderSource); // Root shader - var globalContext = new MixinGlobalContext(); + var log = new LoggerResult(); + var globalContext = new MixinGlobalContext(table, log); // Process name and types imported by constants due to generics instantiation ShaderClass.ProcessNameAndTypes(context); - var rootMixin = MergeMixinNode(globalContext, context, table, temp, shaderSource2); + var rootMixin = MergeMixinNode(globalContext, context, temp, shaderSource2); // Add optional capabilities foreach (var i in context) @@ -119,8 +122,10 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span usedHashSources = shaderLoader.Sources; } - class MixinGlobalContext + class MixinGlobalContext(SymbolTable table, LoggerResult log) { + public SymbolTable Table { get; } = table; + public LoggerResult Log { get; } = log; public EffectReflection Reflection { get; } = new(); public Dictionary ExternalShaders { get; } = new(); @@ -133,7 +138,7 @@ class MixinNodeContext public MixinNode? Result { get; } } - MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, SpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) + MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer buffer, ShaderMixinInstantiation mixinSource, MixinNode? stage = null, string? currentCompositionPath = null) { // We emit OPSDSLEffect for any non-root composition if (currentCompositionPath != null) @@ -145,7 +150,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // Merge all classes from mixinSource.Mixins in main buffer ProcessMixinClasses(globalContext, context, buffer, mixinSource, mixinNode); - BuildTypesAndMethodGroups(globalContext, context, table, buffer, mixinNode); + BuildTypesAndMethodGroups(globalContext, context, buffer, mixinNode); // Compositions (recursive) foreach (var shader in mixinNode.Shaders) @@ -169,7 +174,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, // TODO: Review: it seems like Stride compose variable the opposite way that we expect // Let's change it so that it becomes {currentCompositionPath}.{localKey}! var compositionPath = currentCompositionPath != null ? $"{localKey}.{currentCompositionPath}" : localKey; - compositionResults[i] = MergeMixinNode(globalContext, context, table, buffer, compositionMixins[i], mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); + compositionResults[i] = MergeMixinNode(globalContext, context, buffer, compositionMixins[i], mixinNode.IsRoot ? mixinNode : mixinNode.Stage, compositionPath); } if (isCompositionArray) @@ -401,7 +406,15 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (i2.IdResult is int id) { remapIds.Add(id, existingInstruction.Data.IdResult.Value); - removedIds.Add(existingInstruction.Data.IdResult.Value); + var mismatches = typeDuplicateInserter.MergeTypeDecorations(existingInstruction.Data.IdResult.Value, id); + if (mismatches != null) + { + var details = string.Join("; ", mismatches.Select(m => + $"{m.Data} (only on {(m.OnKeepOnly ? "kept" : "removed")} type)")); + globalContext.Log.Warning($"Mismatched decorations when merging type {id} into {existingInstruction.Data.IdResult.Value}: {details}"); + foreach (var entry in mismatches) + if (!entry.OnKeepOnly) entry.Data.Dispose(); + } } } else @@ -485,7 +498,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS return shaderInfo; } - private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SymbolTable table, SpirvBuffer temp, MixinNode mixinNode) + private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, SpirvContext context, SpirvBuffer temp, MixinNode mixinNode) { // Build method group info (override, etc.) ShaderInfo? currentShader = null; @@ -512,7 +525,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // Add symbol for each method in current type (equivalent to implicit this pointer) var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId, OwnerType: currentShader.Symbol); - table.CurrentFrame.Add(functionName, symbol); + globalContext.Table.CurrentFrame.Add(functionName, symbol); var methodMixinGroup = mixinNode; if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 911faebcce..452dcbdfb0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -296,6 +296,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler else if (pointerType.BaseType is ByteAddressBufferType) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, "byteaddressbuffer")); + if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false }) + context.Add(new OpDecorate(variable, Specification.Decoration.NonWritable, [])); + RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index d6168d8f6d..8217b55c39 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -6,6 +6,21 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvContext { + // Cache for RuntimeArray types keyed by element type ID, to avoid creating duplicates + // that would lose their ArrayStride decoration during type deduplication in the mixer. + private Dictionary runtimeArrayCache = []; + + private int GetOrCreateRuntimeArray(int elementTypeId, int arrayStride) + { + if (runtimeArrayCache.TryGetValue(elementTypeId, out var id)) + return id; + + id = Buffer.Add(new OpTypeRuntimeArray(Bound++, elementTypeId)).ResultId; + Buffer.Add(new OpDecorate(id, Specification.Decoration.ArrayStride, [arrayStride])); + runtimeArrayCache[elementTypeId] = id; + return id; + } + public int GetOrRegister(SymbolType? type) { if (type is null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 331f3c9d18..2b2eccecdb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -57,7 +57,8 @@ private static int RemapOp(Op op) // Make sure all OpName and OpMember are contiguous return op switch { - Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString => -1, + Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString + or Op.OpDecorate or Op.OpDecorateString => -1, _ => (int)op, }; } @@ -244,7 +245,8 @@ private List GetTargetList(OpData data) { switch (data.Op) { - case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString: + case Op.OpName or Op.OpMemberName or Op.OpMemberDecorate or Op.OpMemberDecorateString + or Op.OpDecorate or Op.OpDecorateString: // Target is always in operand 1 for all those instructions return namesByOp; default: @@ -305,6 +307,90 @@ public static bool OpCheckDuplicateForConstant(Op op) || op == Op.OpSpecConstantOp; } + public (int Start, int End) FindDecorationRange(int targetId) + { + var span = CollectionsMarshal.AsSpan(namesByOp); + int lo = 0, hi = namesByOp.Count - 1, start = namesByOp.Count; + while (lo <= hi) + { + int mid = lo + (hi - lo) / 2; + if (span[mid].Data.Memory.Span[1] < targetId) + lo = mid + 1; + else if (span[mid].Data.Memory.Span[1] > targetId) + hi = mid - 1; + else { start = mid; hi = mid - 1; } + } + int end = start; + while (end < namesByOp.Count && span[end].Data.Memory.Span[1] == targetId) + end++; + return (start, end); + } + + /// + /// Compares decorations for two type IDs and removes the duplicate side. + /// Returns true if all decorations matched, false if there was a mismatch. + /// + /// + /// Merges decorations when deduplicating types. Removes the removeId's decorations + /// and returns a list of decorations that only exist on one side (mismatches). + /// Each entry is (Data, OnKeepOnly: true if only on keepId, false if only on removeId). + /// Remove-side OpData are clones that the caller should dispose. + /// + public List<(OpData Data, bool OnKeepOnly)>? MergeTypeDecorations(int keepId, int removeId) + { + var (keepStart, keepEnd) = FindDecorationRange(keepId); + var (removeStart, removeEnd) = FindDecorationRange(removeId); + + List<(OpData Data, bool OnKeepOnly)>? mismatches = null; + var span = CollectionsMarshal.AsSpan(namesByOp); + + // Check: every removeId decoration has a match in keepId + for (int r = removeStart; r < removeEnd; r++) + { + ref var rInst = ref span[r]; + bool found = false; + for (int k = keepStart; k < keepEnd; k++) + { + ref var kInst = ref span[k]; + if (kInst.Op == rInst.Op + && MemoryExtensions.SequenceEqual(kInst.Data.Memory.Span[2..], rInst.Data.Memory.Span[2..])) + { + found = true; + break; + } + } + if (!found) + (mismatches ??= []).Add((new OpData(rInst.Data.Memory.Span), false)); + } + // Check reverse: every keepId decoration has a match in removeId + for (int k = keepStart; k < keepEnd; k++) + { + ref var kInst = ref span[k]; + bool found = false; + for (int r = removeStart; r < removeEnd; r++) + { + ref var rInst = ref span[r]; + if (rInst.Op == kInst.Op + && MemoryExtensions.SequenceEqual(rInst.Data.Memory.Span[2..], kInst.Data.Memory.Span[2..])) + { + found = true; + break; + } + } + if (!found) + (mismatches ??= []).Add((kInst.Data, true)); + } + + // Nop and remove the removeId's decorations + for (int r = removeEnd - 1; r >= removeStart; r--) + { + SetOpNop(namesByOp[r].Data.Memory.Span); + namesByOp.RemoveAt(r); + } + + return mismatches; + } + public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) { var index = instructionsByOp.BinarySearch(new InstructionSortHelper { Op = data.Op, Index = -1, Data = data }, comparerInsert); @@ -369,15 +455,20 @@ private static void ProcessSortedInstructions(SpirvBuffer buffer, List 1) { - bool isOpWithResultId = i.Op == Op.OpName || i.Op == Op.OpMemberName || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString; + bool isOpWithResultId = i.Op == Op.OpName || i.Op == Op.OpMemberName + || i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString + || i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString; // Build list of IdResult matching first instruction Span matchingRefs = new int[lastIndex - (firstIndex + 1)]; From bc35db0ba0add730c458c00454f9f784773885de Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 17:00:14 +0900 Subject: [PATCH 0863/1182] SDSL: use ILogger for ShaderMixer --- sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs | 2 +- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 7 +++---- sources/shaders/Stride.Shaders.Tests/RenderingTests.cs | 4 ++-- sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 69170303e8..69503e26c2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -161,7 +161,7 @@ public override TaskOrResult Compile(ShaderMixinSo shaderMixinSource.AddMacro("class", "shader"); var shaderMixer = new ShaderMixer(GetShaderLoader()); - shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); + shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index f11e0e4111..852347f1f6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -27,7 +27,7 @@ public record struct Options(bool ResourcesRegisterSeparate); public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, Options options, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List entryPoints) + public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List entryPoints) { // Create new buffer for the merged result var temp = new SpirvBuffer(); @@ -54,7 +54,6 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span var shaderSource2 = EvaluateInheritanceAndCompositions(shaderLoader, context, null, shaderSource); // Root shader - var log = new LoggerResult(); var globalContext = new MixinGlobalContext(table, log); // Process name and types imported by constants due to generics instantiation @@ -122,10 +121,10 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, out Span usedHashSources = shaderLoader.Sources; } - class MixinGlobalContext(SymbolTable table, LoggerResult log) + class MixinGlobalContext(SymbolTable table, ILogger log) { public SymbolTable Table { get; } = table; - public LoggerResult Log { get; } = log; + public ILogger Log { get; } = log; public EffectReflection Reflection { get; } = new(); public Dictionary ExternalShaders { get; } = new(); diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 26d2d56a22..f617937e17 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -41,7 +41,7 @@ public void ComputeTest1(string shaderName) // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -86,7 +86,7 @@ public void RenderTest1(string shaderName) // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index dda0967eb8..18a1d34c05 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -187,7 +187,7 @@ public void Tessellation() }; var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"StrideTessellation.spv", bytecode); File.WriteAllText($"StrideTessellation.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); From 0bb8f84bb1895dbef8382e3881296f4ac8fdbd50 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 17:54:34 +0900 Subject: [PATCH 0864/1182] SDSL: fix LOD and texture load --- .../Parsing/SDSL/AST/Expression.cs | 26 +++++++--- .../SDSL/AST/TextureMethodsImplementations.cs | 51 +++++++++++++------ 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index decc237af2..8926bfa863 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -799,22 +799,32 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso var texcoordType = resolvedIntrinsic.Overload.Type.ParameterTypes[0].Type; if (pointerType.BaseType is TextureType) { - // Find expected type for array (same as Load() but with 1 less component) var texcoordSize = texcoordType.GetElementCount(); - indexValue = builder.Convert(context, indexValue, texcoordType.GetElementType().GetVectorOrScalar(texcoordSize - 1)); + var inputSize = context.ReverseTypes[indexValue.TypeId].GetElementCount(); - Span values = stackalloc int[texcoordSize]; - for (int j = 0; j < texcoordSize - 1; ++j) - values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; - values[^1] = context.CompileConstant((int)0).Id; - indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [.. values]))); + if (texcoordSize > inputSize) + { + // Intrinsic expects more components than input (e.g. Texture2D.Load takes int3 = coord + LOD) + // Decompose input coord, append LOD=0, recompose + Span values = stackalloc int[texcoordSize]; + for (int j = 0; j < inputSize; ++j) + values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; + for (int j = inputSize; j < texcoordSize; ++j) + values[j] = context.CompileConstant((int)0).Id; + indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [.. values]))); + } + else + { + // No extra components needed (e.g. RWTexture2D.Load takes int2 directly) + indexValue = builder.Convert(context, indexValue, texcoordType); + } } else { indexValue = builder.Convert(context, indexValue, texcoordType); } - result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, result, [indexValue.Id]); + result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, builder.AsValue(context, result), [indexValue.Id]); accessor.Type = resolvedIntrinsic.Overload.Type.ReturnType; break; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index 9dc4133f50..8e211132ed 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -15,24 +15,43 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde if (status != null) throw new NotImplementedException(); + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var imageCoordType = context.ReverseTypes[x.TypeId]; - - // We get all components except last one (LOD) var imageCoordSize = imageCoordType.GetElementCount(); - imageCoordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); - Span shuffleIndices = stackalloc int[imageCoordSize - 1]; - for (int i = 0; i < shuffleIndices.Length; ++i) - shuffleIndices[i] = i; - - // Note: assign LOD first because we truncate imageCoordValue right after - // Extract LOD (last coordinate) as a separate value - var lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); - // Remove last component (LOD) from texcoord - x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(imageCoordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); - - TextureGenerateImageOperands(lod, o, s, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); - return new(loadResult.ResultId, loadResult.ResultType); + + // Determine the texture's natural coordinate dimension + var textureDim = textureType switch + { + Texture1DType => 1, + Texture2DType => 2, + Texture3DType or TextureCubeType => 3, + _ => throw new NotImplementedException($"Unsupported texture type {textureType}") + }; + if (textureType.Arrayed) + textureDim++; + + if (imageCoordSize > textureDim) + { + // Coord has extra component (LOD): extract it and strip from coord + var coordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); + Span shuffleIndices = stackalloc int[imageCoordSize - 1]; + for (int i = 0; i < shuffleIndices.Length; ++i) + shuffleIndices[i] = i; + + var lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); + x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(coordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); + + TextureGenerateImageOperands(lod, o, s, out var imask, out var imParams); + var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); + return new(loadResult.ResultId, loadResult.ResultType); + } + else + { + // No LOD component (e.g. RWTexture): use coord directly + TextureGenerateImageOperands(null, o, s, out var imask, out var imParams); + var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); + return new(loadResult.ResultId, loadResult.ResultType); + } } public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) From a0adbdee40d067387ab84c735df96cea1d476b02 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Fri, 27 Feb 2026 11:30:47 +0100 Subject: [PATCH 0865/1182] Added uint/ulong specific values in NumberLiteral to prevent overflow errors --- .../Parsing/SDSL/AST/Literals.cs | 4 ++++ .../Spirv/Building/Context.Constants.cs | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 91e2ab500f..2781571d62 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -55,7 +55,9 @@ public override string ToString() public abstract class NumberLiteral(TextLocation info) : ScalarLiteral(info) { public abstract double DoubleValue { get; } + public abstract uint UIntValue { get; } public abstract int IntValue { get; } + public abstract ulong ULongValue { get; } public abstract long LongValue { get; } } @@ -65,7 +67,9 @@ public abstract class NumberLiteral(Suffix suffix, T value, TextLocation info public Suffix Suffix { get; set; } = suffix; public T Value { get; set; } = value; public override double DoubleValue => Convert.ToDouble(Value); + public override ulong ULongValue => Convert.ToUInt64(Value); public override long LongValue => Convert.ToInt64(Value); + public override uint UIntValue => Convert.ToUInt32(Value); public override int IntValue => Convert.ToInt32(Value); public override string ToString() diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index d2bed923b8..6a46c45005 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -1,4 +1,4 @@ -using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using Stride.Shaders.Core; using Stride.Shaders.Parsing; @@ -301,9 +301,11 @@ public SpirvValue CompileConstantLiteral(Literal literal) object literalValue = literal switch { BoolLiteral lit => lit.Value, - IntegerLiteral lit => lit.Suffix.Size switch + IntegerLiteral lit => lit.Suffix switch { - > 32 => lit.LongValue, + { Size: > 32, Signed: false } => lit.ULongValue, + { Size: > 32, Signed: true } => lit.LongValue, + { Signed: false } => lit.UIntValue, _ => lit.IntValue, }, FloatLiteral lit => lit.Suffix.Size switch @@ -311,6 +313,7 @@ public SpirvValue CompileConstantLiteral(Literal literal) > 32 => lit.DoubleValue, _ => (float)lit.DoubleValue, }, + _ => throw new NotImplementedException() }; literal.Type ??= ComputeLiteralType(literal); @@ -328,9 +331,9 @@ public SpirvValue CompileConstantLiteral(Literal literal) { Size: <= 8, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (sbyte)lit.IntValue)), { Size: <= 16, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (ushort)lit.IntValue)), { Size: <= 16, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, (short)lit.IntValue)), - { Size: <= 32, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.IntValue))), + { Size: <= 32, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.UIntValue)), { Size: <= 32, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.IntValue)), - { Size: <= 64, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, unchecked((uint)lit.LongValue))), + { Size: <= 64, Signed: false } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.ULongValue)), { Size: <= 64, Signed: true } => Buffer.AddData(new OpConstant(GetOrRegister(lit.Type), Bound++, lit.LongValue)), _ => throw new NotImplementedException() }, From f3e4579af5b41063f8c0213e69a7d90b7b68b370 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Fri, 27 Feb 2026 14:07:17 +0100 Subject: [PATCH 0866/1182] Implemented ProcessSymbol for While --- .../Parsing/SDSL/AST/Statements.Flow.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index 6252b4a4a6..b5268ff0c4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -118,6 +118,12 @@ public partial class While(Expression condition, Statement body, TextLocation in public Statement Body { get; set; } = body; public ShaderAttribute? Attribute { get; internal set; } = attribute; + public override void ProcessSymbol(SymbolTable table) + { + Condition.ProcessSymbol(table); + Body.ProcessSymbol(table); + } + public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; From 0e591aba361593491dcd72c735f2ff40a79a3231 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 18:34:57 +0900 Subject: [PATCH 0867/1182] SDSL: SpirvBuilder.GetOrLoadShader(): at mix time, generics are fully resolved, so resolve to string values and use the value-based path which caches to shaderLoader.Cache (persistent) --- .../Spirv/Building/Builder.Class.cs | 24 +++++++++++++++++ .../Stride.Shaders/ShaderClassSource.cs | 27 +++++++++++-------- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 08c8e4109f..77e097a0f4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -696,6 +696,30 @@ public static void CollectIds(OpData i, Action ids) /// public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, ShaderClassInstantiation classSource, ReadOnlySpan macros, ResolveStep resolveStep, SpirvContext context) { + if (resolveStep == ResolveStep.Mix && classSource.GenericArguments.Length > 0) + { + // At mix time, generics are fully resolved — resolve to string values + // and use the value-based path which caches to shaderLoader.Cache (persistent) + var genericValues = new string[classSource.GenericArguments.Length]; + for (int i = 0; i < genericValues.Length; i++) + { + var constantId = classSource.GenericArguments[i]; + if (context.TryGetConstantValue(constantId, out var constantValue, out _, false)) + genericValues[i] = ShaderClassSource.ConvertGenericArgToString(constantValue); + else + throw new InvalidOperationException($"Generic argument {i} (ID %{constantId}) for {classSource.ClassName} could not be resolved during mix phase"); + } + + var result = GetOrLoadShader(shaderLoader, classSource.ClassName, genericValues, macros); + + // PostProcess: update classSource (same as GenericResolverFromInstantiatingBuffer.PostProcess) + var classNameWithGenerics = $"{classSource.ClassName}<{string.Join(",", genericValues)}>"; + classSource.ClassName = classNameWithGenerics; + classSource.GenericArguments = []; + + return result; + } + return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context), macros); } diff --git a/sources/shaders/Stride.Shaders/ShaderClassSource.cs b/sources/shaders/Stride.Shaders/ShaderClassSource.cs index 30dbbd64dc..a3942f7a84 100644 --- a/sources/shaders/Stride.Shaders/ShaderClassSource.cs +++ b/sources/shaders/Stride.Shaders/ShaderClassSource.cs @@ -59,20 +59,25 @@ public ShaderClassSource(string className, params object[] genericArguments) { GenericArguments = new string[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; ++i) - { - var genArg = genericArguments[i]; - if (genArg is bool) - GenericArguments[i] = ((bool)genArg) ? "true" : "false"; - else if (genArg is Vector4 v) - GenericArguments[i] = $"float4({v.X}, {v.Y}, {v.Z}, {v.W})"; - else if (genArg is Vector3 v2) - GenericArguments[i] = $"float3({v2.X}, {v2.Y}, {v2.Z})"; - else - GenericArguments[i] = genArg == null ? "null" : Convert.ToString(genArg, CultureInfo.InvariantCulture); - } + GenericArguments[i] = ConvertGenericArgToString(genericArguments[i]); } } + /// + /// Converts a generic argument value to its SDSL-parseable string representation. + /// + public static string ConvertGenericArgToString(object value) + { + return value switch + { + bool b => b ? "true" : "false", + Vector4 v => $"float4({v.X}, {v.Y}, {v.Z}, {v.W})", + Vector3 v => $"float3({v.X}, {v.Y}, {v.Z})", + null => "null", + _ => Convert.ToString(value, CultureInfo.InvariantCulture), + }; + } + public bool Equals(ShaderClassSource shaderClassSource) { if (ReferenceEquals(null, shaderClassSource)) return false; From dea28d5434f2385483cc36a24fd74dd5493b2df4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 19:09:58 +0900 Subject: [PATCH 0868/1182] SDSL: fix ternary operator with vectors (bool2/3/4) --- .../Parsing/SDSL/AST/Expression.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 8926bfa863..a38157bef0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1432,8 +1432,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var conditionValue = Condition.CompileAsValue(table, compiler); - // Might need implicit conversion from float/int to bool - conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); + // Might need implicit conversion from float/int to bool, preserving vector shape + if (Condition.ValueType is VectorType condVec) + conditionValue = builder.Convert(context, conditionValue, new VectorType(ScalarType.Boolean, condVec.Size)); + else + conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); // TODO: Review choice between if/else like branch (OpBranchConditional) which evaluate only one side, or select (OpSelect) which evaluate both side but can work per component but is limited to specific types // It seems HLSL 2021 changed the behavior to align it with C-style short-circuiting. @@ -1477,6 +1480,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { conditionValue = builder.Convert(context, conditionValue, new VectorType(conditionScalar, v.Size)); } + else if (Condition.ValueType is VectorType condVec2 && (Type is not VectorType resultVec || resultVec.Size != condVec2.Size)) + { + table.AddError(new(info, $"Ternary condition is {Condition.ValueType} but result type is {Type}; vector sizes must match")); + return default; + } var leftResult = Left.CompileAsValue(table, compiler); leftResult = builder.Convert(context, leftResult, Type); From e3276162099750c337a9765984bf9f877f8f7ac3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 20:58:33 +0900 Subject: [PATCH 0869/1182] SDSL: added unit tests for geometry and tessellation stages --- .../FrameRenderer.D3D11.cs | 308 ++++++++++++++++-- .../Stride.Shaders.Tests/RenderingTests.cs | 117 ++++++- .../Stride.Shaders.Tests.csproj | 1 + .../StreamGS.sdsl | 4 +- .../StreamTessellation.sdsl | 32 +- 5 files changed, 400 insertions(+), 62 deletions(-) rename sources/shaders/assets/SDSL/{RenderTests => StreamOutTests}/StreamGS.sdsl (93%) rename sources/shaders/assets/SDSL/{RenderTests => StreamOutTests}/StreamTessellation.sdsl (54%) diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 17c1b043ba..7677a9f1ad 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -36,6 +36,8 @@ public class D3D11FrameRenderer(uint width = 800, uint height = 600, byte[]? fra ComPtr indexBuffer = default; ComPtr vertexShader = default; ComPtr geometryShader = default; + ComPtr hullShader = default; + ComPtr domainShader = default; ComPtr pixelShader = default; ComPtr computeShader = default; ComPtr inputLayout = default; @@ -66,6 +68,10 @@ vs_out main(vs_in input) { public string? GeometryShaderSource; + public string? HullShaderSource; + + public string? DomainShaderSource; + //Fragment shaders are run on each fragment/pixel of the geometry. public string PixelShaderSource = @" struct vs_out { @@ -187,7 +193,7 @@ ref deviceContext SampleDesc = new SampleDesc(1, 0) }; - // Create our DXGI factory to allow us to create a swapchain. + // Create our DXGI factory to allow us to create a swapchain. factory = dxgi.CreateDXGIFactory(); // Create the swapchain. @@ -278,13 +284,17 @@ ref computeShader computeCode.Dispose(); } - public unsafe void RenderFrame(Span result) + private unsafe void CompileAndSetupPipeline( + out ComPtr vertexCode, + out ComPtr geometryCode, + out ComPtr hullCode, + out ComPtr domainCode) { - BufferDesc bufferDesc; - // Compile vertex shader. - ComPtr vertexCode = CompileShader("vs_5_0", VertexShaderSource); - ComPtr geometryCode = GeometryShaderSource != null ? CompileShader("gs_5_0", GeometryShaderSource) : null; - ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); + // Compile shaders. + vertexCode = CompileShader("vs_5_0", VertexShaderSource); + geometryCode = GeometryShaderSource != null ? CompileShader("gs_5_0", GeometryShaderSource) : default; + hullCode = HullShaderSource != null ? CompileShader("hs_5_0", HullShaderSource) : default; + domainCode = DomainShaderSource != null ? CompileShader("ds_5_0", DomainShaderSource) : default; // Create vertex shader. SilkMarshal.ThrowHResult @@ -298,34 +308,39 @@ ref vertexShader ) ); - // Create geometry shader. - if (geometryCode.Handle != null) + // Create hull shader. + if (hullCode.Handle != null) { SilkMarshal.ThrowHResult ( - device.CreateGeometryShader + device.CreateHullShader ( - geometryCode.GetBufferPointer(), - geometryCode.GetBufferSize(), + hullCode.GetBufferPointer(), + hullCode.GetBufferSize(), ref Unsafe.NullRef(), - ref geometryShader + ref hullShader ) ); } - // Create pixel shader. - SilkMarshal.ThrowHResult - ( - device.CreatePixelShader + // Create domain shader. + if (domainCode.Handle != null) + { + SilkMarshal.ThrowHResult ( - pixelCode.GetBufferPointer(), - pixelCode.GetBufferSize(), - ref Unsafe.NullRef(), - ref pixelShader - ) - ); + device.CreateDomainShader + ( + domainCode.GetBufferPointer(), + domainCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref domainShader + ) + ); + } + } - // Describe the layout of the input data for the shader. + private unsafe void SetupInputAssemblerState(ComPtr vertexCode) + { fixed (byte* pos = SilkMarshal.StringToMemory("POSITION")) fixed (byte* texcoord = SilkMarshal.StringToMemory("TEXCOORD")) { @@ -358,6 +373,7 @@ ref pixelShader // Start at input slot 1 (0 is standard vertex data) uint inputSlot = 1; + BufferDesc bufferDesc; foreach (var parameter in Parameters) { if (parameter.Key.StartsWith("stream.")) @@ -417,6 +433,62 @@ ref inputLayout ); } + // Update the input assembler to use our shader input layout, and associated vertex & index buffers. + var topology = hullShader.Handle != null + ? D3DPrimitiveTopology.D3DPrimitiveTopology3ControlPointPatchlist + : D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist; + deviceContext.IASetPrimitiveTopology(topology); + deviceContext.IASetInputLayout(inputLayout); + deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); + deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); + + // Bind base shaders. + deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); + if (hullShader.Handle != null) + deviceContext.HSSetShader(hullShader, ref Unsafe.NullRef>(), 0); + if (domainShader.Handle != null) + deviceContext.DSSetShader(domainShader, ref Unsafe.NullRef>(), 0); + } + + public unsafe void RenderFrame(Span result) + { + CompileAndSetupPipeline(out var vertexCode, out var geometryCode, out var hullCode, out var domainCode); + + // Create geometry shader. + if (geometryCode.Handle != null) + { + SilkMarshal.ThrowHResult + ( + device.CreateGeometryShader + ( + geometryCode.GetBufferPointer(), + geometryCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref geometryShader + ) + ); + } + + // Create pixel shader. + ComPtr pixelCode = CompileShader("ps_5_0", PixelShaderSource); + SilkMarshal.ThrowHResult + ( + device.CreatePixelShader + ( + pixelCode.GetBufferPointer(), + pixelCode.GetBufferSize(), + ref Unsafe.NullRef(), + ref pixelShader + ) + ); + + SetupInputAssemblerState(vertexCode); + + // Bind GS and PS. + if (geometryShader.Handle != null) + deviceContext.GSSetShader(geometryShader, ref Unsafe.NullRef>(), 0); + deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); + ComPtr renderTexture = default; ComPtr renderTextureStaging = default; @@ -471,18 +543,6 @@ ref renderTextureStaging deviceContext.RSSetViewports(1, in viewport); deviceContext.OMSetRenderTargets(1, ref renderTargetView, ref Unsafe.NullRef()); - // Update the input assembler to use our shader input layout, and associated vertex & index buffers. - deviceContext.IASetPrimitiveTopology(D3DPrimitiveTopology.D3DPrimitiveTopologyTrianglelist); - deviceContext.IASetInputLayout(inputLayout); - deviceContext.IASetVertexBuffers(0, 1, vertexBuffer, 3 * sizeof(float) + 2 * sizeof(float), 0); - deviceContext.IASetIndexBuffer(indexBuffer, Format.FormatR32Uint, 0); - - // Bind our shaders. - deviceContext.VSSetShader(vertexShader, ref Unsafe.NullRef>(), 0); - if (geometryShader.Handle != null) - deviceContext.GSSetShader(geometryShader, ref Unsafe.NullRef>(), 0); - deviceContext.PSSetShader(pixelShader, ref Unsafe.NullRef>(), 0); - ApplyParameters(); // Draw the quad. @@ -509,9 +569,168 @@ ref renderTextureStaging framebuffer.Dispose(); vertexCode.Dispose(); + if (geometryCode.Handle != null) geometryCode.Dispose(); + if (hullCode.Handle != null) hullCode.Dispose(); + if (domainCode.Handle != null) domainCode.Dispose(); pixelCode.Dispose(); } + public unsafe void RenderFrameWithStreamOutput(out byte[] soData, out int soVertexCount) + { + CompileAndSetupPipeline(out var vertexCode, out var geometryCode, out var hullCode, out var domainCode); + + // Determine which bytecode to use for SO declarations: GS if present, else DS, else VS + ComPtr soStageCode = geometryCode.Handle != null ? geometryCode + : domainCode.Handle != null ? domainCode + : vertexCode; + + // Reflect on the SO stage to get output parameter descriptions + ComPtr soReflection = default; + SilkMarshal.ThrowHResult( + compiler.Reflect( + soStageCode.GetBufferPointer(), + soStageCode.GetBufferSize(), + out soReflection + ) + ); + + ShaderDesc soShaderDesc = default; + soReflection.GetDesc(ref soShaderDesc); + + var soEntries = new List(); + var semanticNameMemories = new List(); + uint soStride = 0; + + for (uint i = 0; i < soShaderDesc.OutputParameters; i++) + { + SignatureParameterDesc paramDesc = default; + soReflection.GetOutputParameterDesc(i, ref paramDesc); + + var semanticName = SilkMarshal.PtrToString((nint)paramDesc.SemanticName); + // Skip system-value semantics like SV_Position + if (semanticName.StartsWith("SV_", StringComparison.OrdinalIgnoreCase)) + continue; + + // Count the number of components used from the mask + byte componentCount = 0; + var mask = paramDesc.Mask; + while (mask != 0) { componentCount += (byte)(mask & 1); mask >>= 1; } + + var nameMemory = SilkMarshal.StringToMemory(semanticName); + semanticNameMemories.Add(nameMemory); + + soEntries.Add(new SODeclarationEntry + { + Stream = (uint)paramDesc.Stream, + SemanticName = (byte*)nameMemory, + SemanticIndex = (uint)paramDesc.SemanticIndex, + StartComponent = 0, + ComponentCount = componentCount, + OutputSlot = 0 + }); + + soStride += (uint)(componentCount * sizeof(float)); + } + + soReflection.Dispose(); + + // Create GS with stream output (no rasterization) + ComPtr soGeometryShader = default; + fixed (SODeclarationEntry* soEntriesPtr = soEntries.ToArray()) + { + SilkMarshal.ThrowHResult( + device.CreateGeometryShaderWithStreamOutput( + soStageCode.GetBufferPointer(), + soStageCode.GetBufferSize(), + in soEntriesPtr[0], + (uint)soEntries.Count, + in soStride, + 1, + unchecked((uint)(-1)), // D3D11_SO_NO_RASTERIZED_STREAM + ref Unsafe.NullRef(), + ref soGeometryShader + ) + ); + } + + // Create SO output buffer (max 64KB) + const uint soBufferSize = 64 * 1024; + ComPtr soBuffer = default; + var bufferDesc = new BufferDesc + { + ByteWidth = soBufferSize, + Usage = Usage.Default, + BindFlags = (uint)BindFlag.StreamOutput, + }; + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, null, ref soBuffer)); + + // Create staging buffer for readback + ComPtr soStagingBuffer = default; + bufferDesc = new BufferDesc + { + ByteWidth = soBufferSize, + Usage = Usage.Staging, + CPUAccessFlags = (uint)CpuAccessFlag.Read, + }; + SilkMarshal.ThrowHResult(device.CreateBuffer(in bufferDesc, null, ref soStagingBuffer)); + + // Create SO statistics query + ComPtr soStatsQuery = default; + var queryDesc = new QueryDesc { Query = Query.SOStatistics }; + SilkMarshal.ThrowHResult(device.CreateQuery(in queryDesc, ref soStatsQuery)); + + SetupInputAssemblerState(vertexCode); + + // Bind SO GS (no pixel shader for SO-only rendering) + deviceContext.GSSetShader(soGeometryShader, ref Unsafe.NullRef>(), 0); + + ApplyParameters(); + + // Bind SO target + uint soOffset = 0; + deviceContext.SOSetTargets(1, soBuffer, in soOffset); + + // Begin query, draw, end query + deviceContext.Begin(soStatsQuery); + deviceContext.DrawIndexed(3, 0, 0); + deviceContext.End(soStatsQuery); + + // Wait for query results + QueryDataSOStatistics soStats = default; + while (deviceContext.GetData(soStatsQuery, ref soStats, (uint)sizeof(QueryDataSOStatistics), 0) != 0) + { + // Spin until data is ready + } + + // Read back SO buffer + deviceContext.CopyResource(soStagingBuffer, soBuffer); + MappedSubresource mappedResource = default; + deviceContext.Map(soStagingBuffer, 0, Map.MapRead, 0, ref mappedResource); + + // NumPrimitivesWritten is based on the output topology: + // - PointStream: each Append = 1 point = 1 primitive + // - TriangleStream/tessellation: each triangle = 1 primitive + soVertexCount = (int)soStats.NumPrimitivesWritten; + + soData = new byte[soBufferSize]; + new Span(mappedResource.PData, (int)soBufferSize).CopyTo(soData); + deviceContext.Unmap(soStagingBuffer, 0); + + // Copy to backbuffer for debug tools + var framebuffer = swapchain.GetBuffer(0); + framebuffer.Dispose(); + + // Cleanup + soStatsQuery.Dispose(); + soStagingBuffer.Dispose(); + soBuffer.Dispose(); + soGeometryShader.Dispose(); + vertexCode.Dispose(); + if (geometryCode.Handle != null) geometryCode.Dispose(); + if (hullCode.Handle != null) hullCode.Dispose(); + if (domainCode.Handle != null) domainCode.Dispose(); + } + private unsafe void ApplyParameters() { BufferDesc bufferDesc; @@ -563,6 +782,8 @@ private unsafe void ApplyParameters() } deviceContext.CSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.VSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); + deviceContext.HSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); + deviceContext.DSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.GSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); deviceContext.PSSetConstantBuffers((uint)resourceReflection.SlotStart, 1U, &cbuffer.Handle); } @@ -618,6 +839,8 @@ ref bufferSRV deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); + deviceContext.HSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); + deviceContext.DSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.GSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &bufferSRV.Handle); } @@ -685,6 +908,8 @@ ref textureSRV deviceContext.CSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.VSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); + deviceContext.HSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); + deviceContext.DSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.GSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); deviceContext.PSSetShaderResources((uint)resourceReflection.SlotStart, 1U, &textureSRV.Handle); } @@ -712,6 +937,17 @@ private static unsafe void FillData(string value, EffectTypeDescription type, in FillData(memberValue, member.Type, offset + member.Offset, cbufferDataPtr); } break; + case { Class: EffectParameterClass.Vector }: + int compIndex = 0; + foreach (var comp in TestHeaderParser.SplitArgs(value)) + { + if (type.Type == EffectParameterType.Float) + *((float*)&cbufferDataPtr[offset + compIndex * sizeof(float)]) = float.Parse(comp, CultureInfo.InvariantCulture); + else if (type.Type == EffectParameterType.Int) + *((int*)&cbufferDataPtr[offset + compIndex * sizeof(int)]) = int.Parse(comp, CultureInfo.InvariantCulture); + compIndex++; + } + break; case { Type: EffectParameterType.Int }: *((int*)&cbufferDataPtr[offset]) = int.Parse(value); break; diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index f617937e17..8d87cd2c33 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -91,34 +91,28 @@ public void RenderTest1(string shaderName) File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); - // Convert to GLSL + // Convert to HLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); - var codePS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)); - var codeHS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.TessellationControl)) - ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationControl)) + var codePS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Fragment) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)) : null; - var codeGS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Geometry)) - ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Geometry)) - : null; - var codeVS = (entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex)) + var codeVS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex) ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) : null; if (codeVS != null) Console.WriteLine(codeVS); - if (codeGS != null) - Console.WriteLine(codeGS); - Console.WriteLine(codePS); + if (codePS != null) + Console.WriteLine(codePS); // Execute test var renderer = new D3D11FrameRenderer((uint)width, (uint)height); if (codeVS != null) renderer.VertexShaderSource = codeVS; - if (codeGS != null) - renderer.GeometryShaderSource = codeGS; - renderer.PixelShaderSource = codePS; + if (codePS != null) + renderer.PixelShaderSource = codePS; renderer.EffectReflection = effectReflection; var code = File.ReadAllLines($"./assets/SDSL/RenderTests/{shaderName}.sdsl"); @@ -149,6 +143,92 @@ public void RenderTest1(string shaderName) } } + [Theory] + [MemberData(nameof(GetStreamOutTestFiles))] + public void StreamOutTest1(string shaderName) + { + // Compile shader + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/StreamOutTests")); + var shaderSource = ShaderMixinManager.Contains(shaderName) + ? new ShaderMixinGeneratorSource(shaderName) + : (ShaderSource)new ShaderClassSource(shaderName); + + shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); + + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); + + File.WriteAllBytes($"{shaderName}.spv", bytecode); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + + // Convert to HLSL + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); + var entryPoints = translator.GetEntryPoints(); + var codeVS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Vertex) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Vertex)) + : null; + var codeHS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.TessellationControl) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationControl)) + : null; + var codeDS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.TessellationEvaluation) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationEvaluation)) + : null; + var codeGS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Geometry) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Geometry)) + : null; + var codePS = entryPoints.Any(x => x.ExecutionModel == ExecutionModel.Fragment) + ? translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.Fragment)) + : null; + + if (codeVS != null) + Console.WriteLine(codeVS); + if (codeHS != null) + Console.WriteLine(codeHS); + if (codeDS != null) + Console.WriteLine(codeDS); + if (codeGS != null) + Console.WriteLine(codeGS); + if (codePS != null) + Console.WriteLine(codePS); + + // Execute test + var renderer = new D3D11FrameRenderer((uint)width, (uint)height); + + if (codeVS != null) + renderer.VertexShaderSource = codeVS; + if (codeHS != null) + renderer.HullShaderSource = codeHS; + if (codeDS != null) + renderer.DomainShaderSource = codeDS; + if (codeGS != null) + renderer.GeometryShaderSource = codeGS; + if (codePS != null) + renderer.PixelShaderSource = codePS; + renderer.EffectReflection = effectReflection; + + var code = File.ReadAllLines($"./assets/SDSL/StreamOutTests/{shaderName}.sdsl"); + foreach (var test in TestHeaderParser.ParseHeaders(code)) + { + var parameters = TestHeaderParser.ParseParameters(test.Parameters); + SetupTestParameters(renderer, parameters); + + renderer.SetupTest(); + renderer.RenderFrameWithStreamOutput(out var soData, out var soVertexCount); + renderer.PresentAndFinish(); + + Console.WriteLine($"SO: {soVertexCount} primitives, {soData.Length} bytes"); + + if (parameters.TryGetValue("ExpectedPrimitiveCount", out var expectedPrimCountStr)) + { + var expectedPrimCount = int.Parse(expectedPrimCountStr); + Assert.Equal(expectedPrimCount, soVertexCount); + } + else + { + Assert.True(soVertexCount > 0, "Stream output produced no primitives"); + } + } + } + private static void SetupTestParameters(D3D11FrameRenderer renderer, Dictionary parameters) { // Setup parameters @@ -167,6 +247,15 @@ public static IEnumerable GetRenderTestFiles() } } + public static IEnumerable GetStreamOutTestFiles() + { + foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/StreamOutTests")) + { + var shadername = Path.GetFileNameWithoutExtension(filename); + yield return [shadername]; + } + } + public static IEnumerable GetComputeTestFiles() { foreach (var filename in Directory.EnumerateFiles("./assets/SDSL/ComputeTests")) diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index 5fa99b7949..94adaad436 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -37,6 +37,7 @@ + diff --git a/sources/shaders/assets/SDSL/RenderTests/StreamGS.sdsl b/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl similarity index 93% rename from sources/shaders/assets/SDSL/RenderTests/StreamGS.sdsl rename to sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl index 011e612e20..7636c1dddf 100644 --- a/sources/shaders/assets/SDSL/RenderTests/StreamGS.sdsl +++ b/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl @@ -1,4 +1,4 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) +// GSMain(ExpectedPrimitiveCount=1, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; @@ -37,4 +37,4 @@ shader StreamGS { streams.ColorTarget = streams.ExtraColor2; } -} \ No newline at end of file +} diff --git a/sources/shaders/assets/SDSL/RenderTests/StreamTessellation.sdsl b/sources/shaders/assets/SDSL/StreamOutTests/StreamTessellation.sdsl similarity index 54% rename from sources/shaders/assets/SDSL/RenderTests/StreamTessellation.sdsl rename to sources/shaders/assets/SDSL/StreamOutTests/StreamTessellation.sdsl index bb90d0b315..d098c07735 100644 --- a/sources/shaders/assets/SDSL/RenderTests/StreamTessellation.sdsl +++ b/sources/shaders/assets/SDSL/StreamOutTests/StreamTessellation.sdsl @@ -1,4 +1,6 @@ -// PSMain(ExpectedResult=#7F7F7F7F, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) +// DSMain(ExpectedPrimitiveCount=1, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498), cbuffer.Test=(TessFactors=(1,1,1,1))) +// DSMain(ExpectedPrimitiveCount=7, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498), cbuffer.Test=(TessFactors=(1,1,1,2))) +// DSMain(ExpectedPrimitiveCount=13, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498), cbuffer.Test=(TessFactors=(2,2,2,1))) namespace Stride.Shaders.Tests; @@ -11,7 +13,12 @@ shader StreamTessellation stream float4 ExtraColor2; patchstream float Edges[3] : SV_TessFactor; - patchstream float Inside[2] : SV_InsideTessFactor; + patchstream float Inside : SV_InsideTessFactor; + + cbuffer Test + { + float4 TessFactors; + } void VSMain() { @@ -21,14 +28,15 @@ shader StreamTessellation void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) { - constants.Edges[0] = 1.0; - constants.Edges[1] = 1.0; - constants.Edges[2] = 1.0; - constants.Edges[3] = 1.0; - constants.Inside[0] = 1.0 * 3.12; - constants.Inside[1] = 1.0 * 3.12; + constants.Edges[0] = TessFactors.x; + constants.Edges[1] = TessFactors.y; + constants.Edges[2] = TessFactors.z; + constants.Inside = TessFactors.w; } + [domain("tri")] + [partitioning("fractional_odd")] + [outputtopology("triangle_cw")] [outputcontrolpoints(3)] [patchconstantfunc("HSConstantMain")] void HSMain(InputPatch input, out Output output, uint uCPID : SV_OutputControlPointID) @@ -41,7 +49,11 @@ shader StreamTessellation [domain("tri")] void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) { - streams = input[0]; + float fU = f3BarycentricCoords.x; + float fV = f3BarycentricCoords.y; + float fW = f3BarycentricCoords.z; + + streams = input[0] * fU + input[1] * fV + input[2] * fW; output = streams; } @@ -49,4 +61,4 @@ shader StreamTessellation { streams.ColorTarget = streams.ExtraColor2; } -} \ No newline at end of file +} From e9f341b82eea097b9278ce4afc4e498273a3ef7d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 21:43:42 +0900 Subject: [PATCH 0870/1182] SDSL: Improved test ShaderLoader to have multiple search paths --- .../Stride.Shaders.Tests/ShaderLoader.cs | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs index 762feb2d5f..f493b51533 100644 --- a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -7,26 +7,40 @@ namespace Stride.Shaders.Parsers.Tests; -class ShaderLoader(string basePath) : ShaderLoaderBase(new TestShaderCache()) +class ShaderLoader(params string[] searchPaths) : ShaderLoaderBase(new TestShaderCache()) { protected override bool ExternalFileExists(string name) { - var filename = $"{basePath}/{name}.sdsl"; - return File.Exists(filename); + foreach (var basePath in searchPaths) + { + if (File.Exists($"{basePath}/{name}.sdsl")) + return true; + } + return false; } public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) { - filename = $"{basePath}/{name}.sdsl"; + foreach (var basePath in searchPaths) + { + filename = $"{basePath}/{name}.sdsl"; + if (!File.Exists(filename)) + continue; - var fileData = File.ReadAllBytes(filename); - hash = ObjectId.FromBytes(fileData); + var fileData = File.ReadAllBytes(filename); + hash = ObjectId.FromBytes(fileData); - // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file - using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); - code = reader.ReadToEnd(); + // Note: we can't use Encoding.UTF8.GetString directly because there might be the UTF8 BOM at the beginning of the file + using var reader = new StreamReader(new MemoryStream(fileData), Encoding.UTF8); + code = reader.ReadToEnd(); + + return true; + } - return true; + filename = ""; + code = ""; + hash = default; + return false; } protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) From 8e0aba58eff9b09842326a629d3946b170e76286 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 22:16:49 +0900 Subject: [PATCH 0871/1182] SDSL: better handle/resolve out parameters --- .../Parsing/SDSL/AST/Expression.cs | 32 ++++++++++++------- .../Parsing/SDSL/AST/IntrinsicCall.cs | 4 +-- .../SDSL/AST/IntrinsicTemplateExpander.cs | 12 +++++-- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index a38157bef0..a5f49bd77f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -109,18 +109,18 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { ProcessParameterSymbols(table); - var argumentValueTypes = new SymbolType[arguments.Values.Count]; + var argumentTypes = new SymbolType[arguments.Values.Count]; for (int i = 0; i < arguments.Values.Count; ++i) - argumentValueTypes[i] = arguments.Values[i].ValueType; + argumentTypes[i] = arguments.Values[i].Type; - if (TryResolveFunctionSymbol(table, argumentValueTypes, out var functionSymbol)) + if (TryResolveFunctionSymbol(table, argumentTypes, out var functionSymbol)) { var functionType = (FunctionType)functionSymbol.Type; Type = functionType.ReturnType; } else { - if (IntrinsicCallHelper.TryResolveIntrinsic(table, MemberCallBaseType, name, argumentValueTypes, out var resolvedIntrinsic)) + if (IntrinsicCallHelper.TryResolveIntrinsic(table, MemberCallBaseType, name, argumentTypes, out var resolvedIntrinsic)) { resolvedIntrinsicCompiler = resolvedIntrinsic.Compiler; resolvedIntrinsicNamespace = resolvedIntrinsic.Namespace; @@ -295,19 +295,27 @@ protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, } // Note: int.MaxValue means incompatible - public static int OverloadScore(FunctionType functionType, int defaultParameters, SymbolType[] argumentValueTypes) + public static int OverloadScore(FunctionType functionType, int defaultParameters, SymbolType[] argumentTypes) { // Check argument count - if (argumentValueTypes.Length > functionType.ParameterTypes.Count || argumentValueTypes.Length < functionType.ParameterTypes.Count + defaultParameters) + if (argumentTypes.Length > functionType.ParameterTypes.Count || argumentTypes.Length < functionType.ParameterTypes.Count + defaultParameters) return int.MaxValue; // Check if argument can be converted var score = 0; - for (var index = 0; index < argumentValueTypes.Length; index++) + for (var index = 0; index < argumentTypes.Length; index++) { - var argumentValueType = argumentValueTypes[index]; + var argumentType = argumentTypes[index]; var parameter = functionType.ParameterTypes[index]; - var argScore = SpirvBuilder.CanConvertScore(argumentValueType, parameter.Type.GetValueType()); + + // out/inout parameters require a writable reference (PointerType) + if ((parameter.Modifiers & ParameterModifiers.Out) != 0) + { + if (argumentType is not PointerType) + return int.MaxValue; + } + + var argScore = SpirvBuilder.CanConvertScore(argumentType.GetValueType(), parameter.Type.GetValueType()); if (argScore == int.MaxValue) return int.MaxValue; @@ -315,12 +323,12 @@ public static int OverloadScore(FunctionType functionType, int defaultParameters } // method with fewer optional parameters that need to be filled in by default values is generally preferred - score += functionType.ParameterTypes.Count - argumentValueTypes.Length; + score += functionType.ParameterTypes.Count - argumentTypes.Length; return score; } - private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentValueTypes, out Symbol functionSymbol) + private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTypes, out Symbol functionSymbol) { // Note: for now, TypeId 0 is used for this/base; let's improve that later if (MemberCallBaseType is LoadedShaderSymbol loadedShaderSymbol) @@ -344,7 +352,7 @@ private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentVa { var accessibleMethods = functionSymbol.GroupMembers // Check overload score - .Select(x => (Score: OverloadScore((FunctionType)x.Type, x.MethodDefaultParameters?.DefaultValues.Length ?? 0, argumentValueTypes), Symbol: x)) + .Select(x => (Score: OverloadScore((FunctionType)x.Type, x.MethodDefaultParameters?.DefaultValues.Length ?? 0, argumentTypes), Symbol: x)) // Remove non-applicable methods .Where(x => x.Score != int.MaxValue) // Group by signature/score (we assume method with exact same signature means they are overriding each other, but we might need to do a better check using override info) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index c8fafaef33..a930d9c5aa 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -14,7 +14,7 @@ public class IntrinsicCallHelper private static IntrinsicTemplateExpander? TemplateExpander { get; set; } private static Dictionary ClassTemplateExpanders = new(); - public static bool TryResolveIntrinsic(SymbolTable table, SymbolType? thisType, string name, SymbolType[] argumentValueTypes, out (IIntrinsicCompiler Compiler, string Namespace, IntrinsicTemplateExpander.IntrinsicOverload Overload) resolvedIntrinsic) + public static bool TryResolveIntrinsic(SymbolTable table, SymbolType? thisType, string name, SymbolType[] argumentTypes, out (IIntrinsicCompiler Compiler, string Namespace, IntrinsicTemplateExpander.IntrinsicOverload Overload) resolvedIntrinsic) { resolvedIntrinsic = default; @@ -68,7 +68,7 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na var bestOverloadScore = int.MaxValue; foreach (var overload in overloads) { - var overloadScore = MethodCall.OverloadScore(overload.Type, 0, argumentValueTypes); + var overloadScore = MethodCall.OverloadScore(overload.Type, 0, argumentTypes); if (overloadScore < bestOverloadScore) { // Better overload diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index aef32f54a1..fe563efb72 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv; using SymbolType = Stride.Shaders.Core.SymbolType; namespace Stride.Shaders.Parsing.SDSL; @@ -338,13 +339,20 @@ ParameterTypeInfo GetParameterInfo(int index) var functionParameters = new List(); for (int i = 0; i < intrinsicDefinition.Parameters.Length; ++i) { - functionParameters.Add(new(parameterTypes[i + 1], intrinsicDefinition.Parameters[i].Qualifier switch + var paramType = (SymbolType)parameterTypes[i + 1]; + var modifier = intrinsicDefinition.Parameters[i].Qualifier switch { Qualifier.In => ParameterModifiers.In, Qualifier.Out => ParameterModifiers.Out, Qualifier.InOut or Qualifier.Ref => ParameterModifiers.InOut, null => ParameterModifiers.None, - })); + }; + + // Wrap out/inout parameters in PointerType, matching user-defined function convention + if ((modifier & ParameterModifiers.Out) != 0) + paramType = new PointerType(paramType, Specification.StorageClass.Function); + + functionParameters.Add(new(paramType, modifier)); } var functionType = new FunctionType(parameterTypes[0], functionParameters); From 8a966eea5d086d9c8256e4ff2839be9aa080079d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 22:53:49 +0900 Subject: [PATCH 0872/1182] SDSL: added support for Texture/Buffer GetDimensions() --- .../SDSL/ShaderMixer.cs | 8 ++ .../SDSL/AST/BufferMethodsImplementations.cs | 8 ++ .../SDSL/AST/TextureMethodsImplementations.cs | 134 ++++++++++++++++++ 3 files changed, 150 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 852347f1f6..9b2fc3c5ad 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -78,6 +78,14 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o break; } } + foreach (var i in temp) + { + if (i.Op is Op.OpImageQuerySizeLod or Op.OpImageQuerySize or Op.OpImageQueryLevels or Op.OpImageQuerySamples) + { + context.Add(new OpCapability(Capability.ImageQuery)); + break; + } + } // Process streams and remove unused code/cbuffer/variable/resources var interfaceProcessor = new InterfaceProcessor diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs index 7316ce678c..a3ea620dc9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs @@ -13,4 +13,12 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(functionType.ReturnType), context.Bound++, buffer.Id, x.Id, null, [])); return new(loadResult.ResultId, loadResult.ResultType); } + + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue width) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var sizeResult = builder.Insert(new OpImageQuerySize(uintType, context.Bound++, buffer.Id)); + builder.Insert(new OpStore(width.Id, sizeResult.ResultId, null, [])); + return default; + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index 8e211132ed..9b31b0dc82 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -118,6 +118,140 @@ public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, Spirv return new(sample.ResultId, sample.ResultType); } + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue? x = null, SpirvValue? width = null, SpirvValue? levels = null, SpirvValue? elements = null, SpirvValue? height = null, SpirvValue? samples = null, SpirvValue? depth = null) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var uintType = context.GetOrRegister(ScalarType.UInt); + + // Determine the number of size components returned by image size query + // SPIR-V returns: scalar for 1D, vec2 for 2D/Cube, vec3 for 3D + // Add 1 if arrayed (array layers as last component) + int sizeComponents = textureType switch + { + Texture1DType { Arrayed: false } => 1, + Texture1DType { Arrayed: true } => 2, + Texture2DType { Arrayed: false } => 2, + Texture2DType { Arrayed: true } => 3, + Texture3DType => 3, + TextureCubeType { Arrayed: false } => 2, + TextureCubeType { Arrayed: true } => 3, + _ => throw new NotImplementedException($"GetDimensions not supported for texture type {textureType}") + }; + + var sizeResultType = sizeComponents == 1 ? uintType : context.GetOrRegister(new VectorType(ScalarType.UInt, sizeComponents)); + + // Query image size + int sizeResultId; + if (x != null) + { + // LOD provided — use OpImageQuerySizeLod + sizeResultId = builder.Insert(new OpImageQuerySizeLod(sizeResultType, context.Bound++, texture.Id, x.Value.Id)).ResultId; + } + else if (textureType.Multisampled || textureType.Sampled == 2) + { + // Multisampled or RW texture — use OpImageQuerySize (no LOD) + sizeResultId = builder.Insert(new OpImageQuerySize(sizeResultType, context.Bound++, texture.Id)).ResultId; + } + else + { + // Regular sampled texture without explicit LOD — query at LOD 0 + var lod0 = context.CompileConstant((uint)0); + sizeResultId = builder.Insert(new OpImageQuerySizeLod(sizeResultType, context.Bound++, texture.Id, lod0.Id)).ResultId; + } + + // Map size components to out parameters based on texture type + // Component order from SPIR-V: [width, height?, depth_or_elements?] + int componentIdx = 0; + + // Component 0: width (always present) + if (width != null) + StoreQueryComponent(context, builder, uintType, sizeResultId, sizeComponents, componentIdx, width.Value); + componentIdx++; + + // Component 1 varies by texture type + if (componentIdx < sizeComponents) + { + if (textureType is Texture1DType) + { + // For 1DArray: component 1 is array elements + if (elements != null) + StoreQueryComponent(context, builder, uintType, sizeResultId, sizeComponents, componentIdx, elements.Value); + } + else + { + // For 2D/3D/Cube: component 1 is height + if (height != null) + StoreQueryComponent(context, builder, uintType, sizeResultId, sizeComponents, componentIdx, height.Value); + } + componentIdx++; + } + + // Component 2: depth (3D) or elements (arrayed 2D/Cube) + if (componentIdx < sizeComponents) + { + if (textureType is Texture3DType) + { + if (depth != null) + StoreQueryComponent(context, builder, uintType, sizeResultId, sizeComponents, componentIdx, depth.Value); + } + else if (textureType.Arrayed) + { + if (elements != null) + StoreQueryComponent(context, builder, uintType, sizeResultId, sizeComponents, componentIdx, elements.Value); + } + } + + // Query mip levels if requested + if (levels != null) + { + var levelsResult = builder.Insert(new OpImageQueryLevels(uintType, context.Bound++, texture.Id)); + StoreConvertedValue(context, builder, uintType, levelsResult.ResultId, levels.Value); + } + + // Query sample count if requested + if (samples != null) + { + var samplesResult = builder.Insert(new OpImageQuerySamples(uintType, context.Bound++, texture.Id)); + StoreConvertedValue(context, builder, uintType, samplesResult.ResultId, samples.Value); + } + + return default; + } + + private static void StoreQueryComponent(SpirvContext context, SpirvBuilder builder, int uintTypeId, int sizeResultId, int sizeComponents, int componentIndex, SpirvValue outParam) + { + int valueId; + if (sizeComponents == 1) + { + valueId = sizeResultId; + } + else + { + valueId = builder.Insert(new OpCompositeExtract(uintTypeId, context.Bound++, sizeResultId, [componentIndex])).ResultId; + } + + StoreConvertedValue(context, builder, uintTypeId, valueId, outParam); + } + + private static void StoreConvertedValue(SpirvContext context, SpirvBuilder builder, int uintTypeId, int valueId, SpirvValue outParam) + { + var ptrType = (PointerType)context.ReverseTypes[outParam.TypeId]; + var targetType = ptrType.BaseType; + + if (targetType is ScalarType { Type: Scalar.Float }) + { + // Convert uint to float + var floatTypeId = context.GetOrRegister(targetType); + var converted = builder.Insert(new OpConvertUToF(floatTypeId, context.Bound++, valueId)); + builder.Insert(new OpStore(outParam.Id, converted.ResultId, null, [])); + } + else + { + // uint — store directly + builder.Insert(new OpStore(outParam.Id, valueId, null, [])); + } + } + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams) { imask = ImageOperandsMask.None; From 9a67c2f4d70adfd868df335e0a26080e903637fb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 23:12:31 +0900 Subject: [PATCH 0873/1182] SDSL: intrinsic parameter is now adjusted to match DXC ones --- .../Parsing/SDSL/AST/IntrinsicTemplateExpander.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index fe563efb72..c24313b30c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -130,7 +130,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) { BaseType.Bool => [ScalarType.Boolean], BaseType.Int => [ScalarType.Int], - BaseType.Int32Only => [ScalarType.Int], + BaseType.Int32Only => [ScalarType.Int, ScalarType.UInt], BaseType.Int16 => throw new NotImplementedException(), BaseType.Int64 => [ScalarType.Int64], BaseType.SInt16Or32 => [ScalarType.Int], @@ -138,7 +138,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.AnyInt16Or32 => [ScalarType.Int, ScalarType.UInt], BaseType.AnyInt32 => [ScalarType.Int, ScalarType.UInt], BaseType.AnyInt64 => [ScalarType.Int64, ScalarType.UInt64], - BaseType.Int64Only => [ScalarType.Int64], + BaseType.Int64Only => [ScalarType.Int64, ScalarType.UInt64], BaseType.Uint => [ScalarType.UInt], BaseType.Uint16 => throw new NotImplementedException(), BaseType.U64 => [ScalarType.UInt64], @@ -161,7 +161,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.UIntOnly => [ScalarType.UInt, ScalarType.UInt64], BaseType.Numeric => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64], BaseType.Numeric16Only => throw new NotImplementedException(), - BaseType.Numeric32Only => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt], + BaseType.Numeric32Only => [ScalarType.Float, ScalarType.Int, ScalarType.UInt], BaseType.Any => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean], BaseType.Match => throw new InvalidOperationException(), BaseType.ByteAddressBuffer => [new ByteAddressBufferType(false)], From fa1ab3c4d05c1cd1bec608f1628e8f4777b18159 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 23:12:48 +0900 Subject: [PATCH 0874/1182] SDSL: added support for BitwiseNot --- .../Parsing/SDSL/AST/Expression.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index a5f49bd77f..4bd085da0c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -403,6 +403,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = case Operator.Inc: case Operator.Dec: case Operator.Not: + case Operator.BitwiseNot: case Operator.Plus: case Operator.Minus: expression.ProcessSymbol(table, expectedType); @@ -477,6 +478,14 @@ var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate Type = valueType; return new(result); } + case Operator.BitwiseNot: + { + if (!valueType.GetElementType().IsInteger()) + throw new InvalidOperationException($"Bitwise not operator requires an integer type, got {valueType}"); + var result = builder.InsertData(new OpNot(valueExpression.TypeId, context.Bound++, valueExpression.Id)); + Type = valueType; + return new(result); + } default: throw new NotImplementedException($"unary operator {Operator} is not implemented"); } From 01a3dbcfa414d0c46f4f5f4b06feb147eecb6ea7 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Fri, 27 Feb 2026 14:57:20 +0100 Subject: [PATCH 0875/1182] Implement isnan/inf, coutnbits and firstbithigh intrinsics --- .../SDSL/AST/IntrinsicImplementations.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 5e92c9fc1b..a5bfc834f0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -235,6 +235,22 @@ public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder return new(instruction.ResultId, instruction.ResultType); } + // Float checks + public override SpirvValue CompileIsnan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsNan, x); + public override SpirvValue CompileIsinf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsInf, x); + + // Bit operations + public override SpirvValue CompileCountbits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpBitCount, x); + public override SpirvValue CompileFirstbithigh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var op = context.ReverseTypes[x.TypeId].GetElementType() switch + { + ScalarType { Type: Scalar.UInt } => Specification.GLSLOp.GLSLFindUMsb, + _ => Specification.GLSLOp.GLSLFindSMsb, + }; + return CompileGLSLFloatUnaryCall(context, builder, functionType, op, x); + } + // Compute Barriers const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; @@ -269,20 +285,16 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileGetRenderTargetSampleCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileGetRenderTargetSamplePosition(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s) => throw new NotImplementedException(); public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileCountbits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeAtSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue index) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeCentroid(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeSnapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset) => throw new NotImplementedException(); public override SpirvValue CompileGetAttributeAtVertex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue VertexID) => throw new NotImplementedException(); public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileFirstbithigh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileIsinf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileIsnan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileIsnormal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileLdexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); public override SpirvValue CompileLit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m) => throw new NotImplementedException(); From 54b5732fd58d25ea42badd6dc1c2425c15b35e72 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Fri, 27 Feb 2026 15:07:39 +0100 Subject: [PATCH 0876/1182] Implemented While compilation --- .../Parsing/SDSL/AST/Statements.Flow.cs | 31 ++++++++++++++++++- .../Spirv/Building/Builder.Flow.cs | 2 ++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index b5268ff0c4..4ee1b2bef3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -128,6 +128,18 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; + // Prepare blocks ids + var whileCheckBlock = context.Bound++; + var whileBodyBlock = context.Bound++; + var previousEscapeBlocks = builder.CurrentEscapeBlocks; + var currentEscapeBlocks = new SpirvBuilder.EscapeBlocks(context.Bound++, context.Bound++); + builder.CurrentEscapeBlocks = currentEscapeBlocks; + + builder.Insert(new OpBranch(whileCheckBlock)); + + // Check block + builder.CreateBlock(context, whileCheckBlock, $"while_check_{builder.WhileBlockCount}"); + var conditionValue = Condition.CompileAsValue(table, compiler); if (Condition.ValueType is not ScalarType) table.AddError(new(Condition.Info, "while statement condition expression must evaluate to a scalar")); @@ -135,8 +147,25 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) // Might need implicit conversion from float/int to bool conditionValue = builder.Convert(context, conditionValue, ScalarType.Boolean); + builder.Insert(new OpLoopMerge(currentEscapeBlocks.MergeBlock, currentEscapeBlocks.ContinueBlock, Specification.LoopControlMask.None, [])); + builder.Insert(new OpBranchConditional(conditionValue.Id, whileBodyBlock, currentEscapeBlocks.MergeBlock, [])); + + // Body block + builder.CreateBlock(context, whileBodyBlock, $"while_body_{builder.WhileBlockCount}"); Body.Compile(table, compiler); - throw new NotImplementedException(); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(currentEscapeBlocks.ContinueBlock)); + + // Continue block + builder.CreateBlock(context, currentEscapeBlocks.ContinueBlock, $"while_continue_{builder.WhileBlockCount}"); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(whileCheckBlock)); + + // Merge block + builder.CreateBlock(context, currentEscapeBlocks.MergeBlock, $"while_merge_{builder.WhileBlockCount}"); + + builder.WhileBlockCount++; + builder.CurrentEscapeBlocks = previousEscapeBlocks; } public override string ToString() diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs index e01f04a9b1..d191c44a67 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs @@ -13,6 +13,8 @@ public record struct EscapeBlocks(int ContinueBlock, int MergeBlock); public int ForBlockCount { get; internal set; } = 0; + public int WhileBlockCount { get; internal set; } = 0; + public EscapeBlocks? CurrentEscapeBlocks { get; internal set; } public static bool IsFunctionTermination(Op op) From f1caf71f70775a9998a3880d4da08f70a17e6e3b Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Fri, 27 Feb 2026 15:25:06 +0100 Subject: [PATCH 0877/1182] Corrected decrement and left shift operators --- .../SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs | 2 +- .../Spirv/Building/Builder.Expressions.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 8a37098a50..0c342fa5da 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -86,7 +86,7 @@ public static bool PrefixIncrement(ref TScanner scanner, ParseResult r Parsers.Spaces0(ref scanner, result, out _); if (PostfixParser.Postfix(ref scanner, result, out var lit)) { - parsed = new PrefixExpression(Operator.Inc, lit, scanner[position..scanner.Position]); + parsed = new PrefixExpression(Operator.Dec, lit, scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0020, scanner[position], scanner.Memory)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index d3c9a855f9..faad7d9ce7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -339,7 +339,7 @@ when l.IsInteger() && r.IsInteger() (Operator.LeftShift, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, resultId, left.Id, right.Id)), + => Buffer.InsertData(Position++, new OpShiftLeftLogical(resultTypeId, resultId, left.Id, right.Id)), (Operator.AND, SymbolType l, SymbolType r) when l.IsInteger() && r.IsInteger() From 637bdc0789fbe28fb947f425506e5ddf539aec44 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Feb 2026 23:46:38 +0900 Subject: [PATCH 0878/1182] SDSL: ignore OpName differences during type merging --- .../Spirv/Processing/TypeDuplicatesRemover.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 2b2eccecdb..07b714a18d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -360,12 +360,25 @@ public static bool OpCheckDuplicateForConstant(Op op) } } if (!found) - (mismatches ??= []).Add((new OpData(rInst.Data.Memory.Span), false)); + { + if (rInst.Op is Op.OpName) + { + // OpName mismatches are harmless — just adopt the remove-side name onto keepId + var clone = new OpData(rInst.Data.Memory.Span); + clone.Memory.Span[1] = keepId; + namesByOp.Add(new InstructionSortHelper { Op = clone.Op, Index = -1, Data = clone }); + span = CollectionsMarshal.AsSpan(namesByOp); // re-acquire after mutation + } + else + (mismatches ??= []).Add((new OpData(rInst.Data.Memory.Span), false)); + } } // Check reverse: every keepId decoration has a match in removeId for (int k = keepStart; k < keepEnd; k++) { ref var kInst = ref span[k]; + if (kInst.Op is Op.OpName) + continue; // OpName on keep-side is always fine bool found = false; for (int r = removeStart; r < removeEnd; r++) { From 010769853978f9eef09d5d3e88215d3c71b6edaf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Feb 2026 00:09:22 +0900 Subject: [PATCH 0879/1182] SDSL: add support for (MyStruct)0 (which initialize to default value) --- .../Parsing/SDSL/AST/Expression.cs | 8 +++++++ .../Spirv/Building/Context.Constants.cs | 23 +------------------ 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 4bd085da0c..276b47a395 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -519,6 +519,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) Type = castType; + // HLSL zero-initialization idiom: (StructType)0 + if (castType is StructType) + { + if (Expression is IntegerLiteral { Value: 0 }) + return context.CreateDefaultConstantComposite(castType); + throw new NotImplementedException($"Can't cast from {Expression.ValueType} to {castType} (only (StructType)0 zero-initialization is supported)"); + } + return builder.Convert(context, value, castType); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 6a46c45005..d63452ae37 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -230,28 +230,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object public SpirvValue CreateDefaultConstantComposite(SymbolType type) { // TODO: cache results (either here or even more generally for any composite constant even if non-zero) - return type switch - { - ScalarType { Type: Scalar.Boolean } => CompileConstantLiteral(new BoolLiteral(false, new())), - ScalarType { Type: Scalar.Int } => CompileConstantLiteral(new IntegerLiteral(new(32, false, true), 0, new())), - ScalarType { Type: Scalar.UInt } => CompileConstantLiteral(new IntegerLiteral(new(32, false, false), 0, new())), - ScalarType { Type: Scalar.Int64 } => CompileConstantLiteral(new IntegerLiteral(new(64, false, true), 0, new())), - ScalarType { Type: Scalar.UInt64 } => CompileConstantLiteral(new IntegerLiteral(new(64, false, false), 0, new())), - ScalarType { Type: Scalar.Float } => CompileConstantLiteral(new FloatLiteral(new(32, true, false), 0.0, null, new())), - ScalarType { Type: Scalar.Double } => CompileConstantLiteral(new FloatLiteral(new(64, true, false), 0.0, null, new())), - VectorType v => CreateConstantCompositeRepeat(v, CreateDefaultConstantComposite(v.BaseType), v.Size), - MatrixType m => CreateConstantCompositeRepeat(m, CreateDefaultConstantComposite(m.BaseType.GetVectorOrScalar(m.Rows)), m.Columns), - StructType s => ProcessStruct(s), - ArrayType a when a.Size != -1 => CreateConstantCompositeRepeat(a, CreateDefaultConstantComposite(a.BaseType), a.Size), - }; - - SpirvValue ProcessStruct(StructType structType) - { - Span values = stackalloc int[structType.Members.Count]; - for (int i = 0; i < values.Length; ++i) - values[i] = CreateDefaultConstantComposite(structType.Members[i].Type).Id; - return new(Buffer.AddData(new OpConstantComposite(GetOrRegister(type), Bound++, new(values)))); - } + return new(Buffer.AddData(new OpConstantNull(GetOrRegister(type), Bound++))); } public SpirvValue CreateConstantCompositeVectorRepeat(Literal literal, int size) From b5a32407a45fee71bd89db59d1f5168a76474f99 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Feb 2026 00:29:27 +0900 Subject: [PATCH 0880/1182] SDSL: two small fixes for rgroup and matrix init from array --- .../Parsing/SDSL/AST/Literals.cs | 12 +++++++++++- .../Parsing/SDSL/AST/ShaderElements.cs | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 2781571d62..25431655df 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -307,11 +307,21 @@ public partial class ArrayLiteral(TextLocation info) : CompositeLiteral(info) public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { Type = expectedType; - var expectedElementType = (expectedType as ArrayType)?.BaseType; + + var expectedElementType = expectedType switch + { + MatrixType m => m.BaseType, + ArrayType a => a.BaseType, + _ => null, + }; foreach (var value in Values) value.ProcessSymbol(table, expectedElementType); + // Matrix brace initialization is fully handled by CompositeLiteral.CompileImpl + if (expectedType is MatrixType) + return; + if (Type == null && Values.Count > 0) Type = new ArrayType(Values[0].ValueType, Values.Count); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index 850aaec249..b163a76adc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -398,6 +398,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) TextureType => (Specification.StorageClass.UniformConstant, SymbolKind.Variable), SamplerType => (Specification.StorageClass.UniformConstant, SymbolKind.SamplerState), BufferType => (Specification.StorageClass.UniformConstant, SymbolKind.TBuffer), + StructuredBufferType or ByteAddressBufferType => (Specification.StorageClass.StorageBuffer, SymbolKind.Variable), _ => throw new NotImplementedException(), }; From 5f5b2fa119670f38c91dae6985153bc75d0e85e8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Feb 2026 00:39:30 +0900 Subject: [PATCH 0881/1182] SDSL: fix control barrier code generation --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index a5bfc834f0..892e3c4134 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -502,7 +502,7 @@ public static SpirvValue CompileMemoryBarrierCall(SpirvContext context, SpirvBui } public static SpirvValue CompileControlBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) { - builder.Insert(new OpControlBarrier((int)Specification.Scope.Workgroup, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); + builder.Insert(new OpControlBarrier(context.CompileConstant((int)Specification.Scope.Workgroup).Id, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } From e44e3cb9673fe0423ebac30e4179de93513e1165 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Feb 2026 01:56:02 +0900 Subject: [PATCH 0882/1182] SDSL: In cbuffer, bool are transformed to uint --- .../SDSL/ShaderMixer.CBuffers.cs | 107 ++++++++++++++++++ .../SDSL/ShaderMixer.cs | 6 + 2 files changed, 113 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index db95aaabe4..e7b0fbb6e0 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -467,5 +467,112 @@ private static void DecorateMember(SpirvContext context, int structTypeId, int i context.Add(new OpMemberDecorate(structTypeId, index, Decoration.MatrixStride, [16])); } } + + /// + /// SPIR-V does not allow OpTypeBool in uniform blocks (Block-decorated structs). + /// This pass converts bool cbuffer members to uint and inserts bool↔uint conversions at load/store sites. + /// Must run after ComputeCBufferReflection so that reflection still reports the original bool type. + /// + private static void ConvertBoolCBufferMembers(SpirvContext context, SpirvBuffer buffer) + { + // Check if PointerType(Boolean, Uniform) is registered — if not, no bool cbuffer members exist + var boolPtrUniform = new PointerType(ScalarType.Boolean, Specification.StorageClass.Uniform); + if (!context.Types.TryGetValue(boolPtrUniform, out var boolPtrUniformId)) + return; + + var boolTypeId = context.GetOrRegister(ScalarType.Boolean); + var uintTypeId = context.GetOrRegister(ScalarType.UInt); + var uintPtrUniformId = context.GetOrRegister(new PointerType(ScalarType.UInt, Specification.StorageClass.Uniform)); + + // 1. Find all Block-decorated struct type IDs (cbuffers) + var blockStructIds = new HashSet(); + foreach (var i in context) + { + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.Block } decorate) + blockStructIds.Add(decorate.Target); + } + + // 2. Patch OpTypeStruct instructions: replace bool member type IDs with uint + bool anyPatched = false; + foreach (var i in context) + { + if (i.Op == Op.OpTypeStruct && i.Data.IdResult is int structId && blockStructIds.Contains(structId)) + { + var span = i.Data.Memory.Span; + // OpTypeStruct layout: [wordcount|op] [resultId] [member0Type] [member1Type] ... + for (int j = 2; j < span.Length; j++) + { + if (span[j] == boolTypeId) + { + span[j] = uintTypeId; + anyPatched = true; + } + } + } + } + + if (!anyPatched) + return; + + // Also update ConstantBufferSymbol member types (for consistency after reflection is computed) + foreach (var (type, typeId) in context.Types) + { + if (type is ConstantBufferSymbol cbs && blockStructIds.Contains(typeId)) + { + for (int i = 0; i < cbs.Members.Count; i++) + { + if (cbs.Members[i].Type is ScalarType { Type: Scalar.Boolean }) + cbs.Members[i] = cbs.Members[i] with { Type = ScalarType.UInt }; + } + } + } + + // 3. Find all OpAccessChain with boolPtrUniform result type, patch to uintPtrUniform, and collect result IDs + var boolPtrResultIds = new HashSet(); + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index]; + if (i.Op == Op.OpAccessChain && i.Data.Memory.Span[1] == boolPtrUniformId) + { + i.Data.Memory.Span[1] = uintPtrUniformId; + boolPtrResultIds.Add(i.Data.Memory.Span[2]); + } + } + + if (boolPtrResultIds.Count == 0) + return; + + // 4. Fix loads and stores that use the patched access chains + var uint0 = context.CompileConstant(0u).Id; + var uint1 = context.CompileConstant(1u).Id; + for (var index = 0; index < buffer.Count; index++) + { + var i = buffer[index]; + if (i.Op == Op.OpLoad && (OpLoad)i is { } load) + { + if (boolPtrResultIds.Contains(load.Pointer)) + { + // Load now produces uint; convert to bool with OpINotEqual + var originalResultId = load.ResultId; + var tempUintId = context.Bound++; + load.ResultType = uintTypeId; + load.ResultId = tempUintId; + buffer.Insert(++index, new OpINotEqual(boolTypeId, originalResultId, tempUintId, uint0)); + } + } + else if (i.Op == Op.OpStore && (OpStore)i is { } store) + { + if (boolPtrResultIds.Contains(store.Pointer)) + { + // Store expects uint; convert bool to uint with OpSelect + var boolVal = store.ObjectId; + var uintVal = context.Bound++; + // Patch store before insert: insert shifts instructions, invalidating the store reference + store.ObjectId = uintVal; + buffer.Insert(index++, new OpSelect(uintTypeId, uintVal, boolVal, uint1, uint0)); + } + } + } + } } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9b2fc3c5ad..43ce56df29 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -107,6 +107,12 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o MergeCBuffers(globalContext, context, temp); ComputeCBufferReflection(globalContext, context, temp); + // From this point, assume ShaderInfo.StartInstruction/EndInstruction are not valid anymore, as we add instructions without updating them + + // SPIR-V doesn't allow OpTypeBool in uniform blocks; convert bool cbuffer members to uint + // (must run after ComputeCBufferReflection so reflection still reports the original bool type) + ConvertBoolCBufferMembers(context, temp); + // Try to give variables more sensible names // Note: since we mutate OpName and globalContext.Names, try to do that as late as possible because some code earlier use names to match variables/types RenameVariables(globalContext, context, temp); From 8764e1895a4079aa9d6055b76141910e0ccd35c9 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sat, 28 Feb 2026 20:56:13 +0100 Subject: [PATCH 0883/1182] Fixed structuredbuffer type array type resolution --- .../shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 26851d265f..8f88ea055b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -160,8 +160,8 @@ void RegisterName(int target, string name) StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) ? structName switch { - var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type), - var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type, true), + var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a ? a.BaseType : fields[0].Type), + var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a2 ? a2.BaseType : fields[0].Type, true), var s when s.StartsWith("type.") => new ConstantBufferSymbol(structName.Substring("type.".Length), fields), _ => throw new InvalidOperationException(), } From 0ff577b67b6de1d0d99d34dac5545ad8ca7dd99f Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 07:59:50 +0100 Subject: [PATCH 0884/1182] Implemented samplegrad --- .../SDSL/AST/TextureMethodsImplementations.cs | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index 9b31b0dc82..a4363ed6b6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -86,6 +86,22 @@ public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder return new(sample.ResultId, sample.ResultType); } + public override SpirvValue CompileSampleGrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, ddx, ddy); + var sample = builder.Insert(new OpImageSampleExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) { if (clamp != null || status != null) @@ -252,12 +268,19 @@ private static void StoreConvertedValue(SpirvContext context, SpirvBuilder build } } - private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams) + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null) { imask = ImageOperandsMask.None; - // Allocate for worst case (3 operands) - Span operands = stackalloc int[3]; + // Allocate for worst case (5 operands: lod/grad(2) + offset + sample) + Span operands = stackalloc int[5]; int operandCount = 0; + // Operands must appear in bit-order: Grad(0x4) < Lod(0x8) < Offset(0x10) < Sample(0x40) + if (ddx != null && ddy != null) + { + imask |= ImageOperandsMask.Grad; + operands[operandCount++] = ddx.Value.Id; + operands[operandCount++] = ddy.Value.Id; + } if (lod != null) { imask |= ImageOperandsMask.Lod; From f3377244f923b5a70de64dff58e166ce76f60ff8 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sat, 28 Feb 2026 10:33:21 +0100 Subject: [PATCH 0885/1182] rwbyteaddressbuffer fixes? --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 8 +++--- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 28 +++++++++++++++++++ .../Interfaces/Cleanup/DeadCodeRemover.cs | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 452dcbdfb0..e69befc497 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -291,10 +291,10 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (StreamKind == StreamKind.PatchStream) context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); - if (pointerType.BaseType is StructuredBufferType) - context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"structuredbuffer:<{pointerType.BaseType.ToId().ToLowerInvariant()}>")); - else if (pointerType.BaseType is ByteAddressBufferType) - context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, "byteaddressbuffer")); + if (pointerType.BaseType is StructuredBufferType sb) + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"{(sb.WriteAllowed ? "rw" : "")}structuredbuffer:<{sb.BaseType.ToId().ToLowerInvariant()}>")); + else if (pointerType.BaseType is ByteAddressBufferType bab) + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, bab.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false }) context.Add(new OpDecorate(variable, Specification.Decoration.NonWritable, [])); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index 70b9d2fd19..513a986f00 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -135,6 +135,34 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont if (analysisResult.CBuffers.TryGetValue(accessChain.Base, out var cbufferInfo)) cbufferInfo.UsedThisStage = true; } + else if (i.Op is Op.OpAtomicIAdd or Op.OpAtomicISub or Op.OpAtomicUMin or Op.OpAtomicUMax + or Op.OpAtomicSMin or Op.OpAtomicSMax or Op.OpAtomicAnd or Op.OpAtomicOr or Op.OpAtomicXor + or Op.OpAtomicExchange or Op.OpAtomicCompareExchange or Op.OpAtomicLoad or Op.OpAtomicStore + or Op.OpAtomicIIncrement or Op.OpAtomicIDecrement) + { + // Atomic operations reference a pointer (word 3 after opcode, i.e. first operand after ResultType+ResultId or just after opcode for OpAtomicStore) + // Extract the pointer and mark the underlying resource as used + var pointer = i.Op == Op.OpAtomicStore + ? i.Memory.Span[1] // OpAtomicStore has no ResultType/ResultId, pointer is word 1 + : i.Memory.Span[3]; // All other atomics: word 3 (after ResultType, ResultId) + if (!accessChainBases.TryGetValue(pointer, out var atomicAccessChain)) + atomicAccessChain.Base = pointer; + if (variables.TryGetValue(atomicAccessChain.Base, out var variableInfo2)) + variableInfo2.UsedThisStage = true; + if (analysisResult.Resources.TryGetValue(atomicAccessChain.Base, out var resourceInfo2)) + resourceInfo2.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(atomicAccessChain.Base, out var cbufferInfo2)) + cbufferInfo2.UsedThisStage = true; + } + else if (i.Op is Op.OpArrayLength) + { + // OpArrayLength directly references the struct variable pointer (word 3) + var structureId = i.Memory.Span[3]; + if (variables.TryGetValue(structureId, out var variableInfo3)) + variableInfo3.UsedThisStage = true; + if (analysisResult.Resources.TryGetValue(structureId, out var resourceInfo3)) + resourceInfo3.UsedThisStage = true; + } else if (i.Op == Op.OpStreamsSDSL && new OpStreamsSDSL(ref i) is { } streamsInstruction) { streamsInstructionIds.Add(streamsInstruction.ResultId, StreamsKindSDSL.Streams); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index fd8f19dcdb..36c5ddc07d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -131,7 +131,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant, + Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, ResultId: int } resource) { From cdab6a48206c3d1681be01842f99a891265491a8 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 08:52:28 +0100 Subject: [PATCH 0886/1182] Deduplicate OpExtInstImport --- .../Spirv/Processing/TypeDuplicatesRemover.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 07b714a18d..2679fc28f8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -288,7 +288,8 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpSDSLImportShader || op == Op.OpSDSLImportVariable || op == Op.OpSDSLImportFunction - || op == Op.OpSDSLImportStruct; + || op == Op.OpSDSLImportStruct + || op == Op.OpExtInstImport; } public static bool OpCheckDuplicateForConstant(Op op) From 41ce0952fdb2850f8e59877b611d572732313ce5 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 08:52:48 +0100 Subject: [PATCH 0887/1182] StructuredBuffer type resolution fix --- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 43ce56df29..f5dce6a543 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -454,6 +454,13 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (!remapIds.TryGetValue(typeStruct2.ResultId, out var structId)) structId = typeStruct2.ResultId; structTypes.Add(structName, structId); + // Also add an entry using ToId()-style name for structured buffer types, + // since OpSDSLImportStruct.StructName uses ToId() format (e.g. "StructuredBuffer") + // while OpName uses "type.StructuredBuffer.X" format + if (structName.StartsWith("type.StructuredBuffer.")) + structTypes.TryAdd($"StructuredBuffer<{structName.Substring("type.StructuredBuffer.".Length)}>", structId); + else if (structName.StartsWith("type.RWStructuredBuffer.")) + structTypes.TryAdd($"RWStructuredBuffer<{structName.Substring("type.RWStructuredBuffer.".Length)}>", structId); } // Process OpSDSLImport From a034b620f785764bf9445b1568487c4e380cd556 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 08:53:40 +0100 Subject: [PATCH 0888/1182] StructuredBuffer stride --- .../Spirv/Building/SpirvContext.Types.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 8217b55c39..b25254899f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; namespace Stride.Shaders.Spirv.Building; @@ -117,13 +118,12 @@ public int RegisterType(SymbolType type, int id) private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) { - var runtimeArrayType = Buffer.Add(new OpTypeRuntimeArray(Bound++, GetOrRegister(structuredBufferType.BaseType))).ResultId; + var elementSize = SpirvBuilder.TypeSizeInBuffer(structuredBufferType.BaseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var runtimeArrayType = GetOrCreateRuntimeArray(GetOrRegister(structuredBufferType.BaseType), elementSize); var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; AddName(bufferType, $"type.{(structuredBufferType.WriteAllowed ? "RW" : "")}StructuredBuffer.{structuredBufferType.BaseType.ToId()}"); Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); - - // TODO: Add array stride and offsets Buffer.Add(new OpDecorate(bufferType, Specification.Decoration.Block, [])); return bufferType; From d7c1d232db146dca6d317593d5e44578a389627a Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 09:38:28 +0100 Subject: [PATCH 0889/1182] UserTypeGoogle is preserved during mixin --- .../SDSL/ShaderMixer.Reflection.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 5be4ea1bf6..a626ada5a4 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -369,6 +369,11 @@ or Specification.Decoration.SamplerStateMinLOD Type = structuredBufferType.WriteAllowed ? EffectParameterType.RWStructuredBuffer : EffectParameterType.StructuredBuffer, }); + // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves StructuredBuffer type + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, $"{(structuredBufferType.WriteAllowed ? "rw" : "")}structuredbuffer:<{structuredBufferType.BaseType.ToId().ToLowerInvariant()}>")); + if (!structuredBufferType.WriteAllowed) + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.NonWritable, [])); + var baseType = structuredBufferType.BaseType; // This will add array stride and offsets decorations EmitTypeDecorationsRecursively(context, baseType, SpirvBuilder.AlignmentRules.StructuredBuffer); @@ -379,6 +384,11 @@ or Specification.Decoration.SamplerStateMinLOD { Type = byteAddressBufferType.WriteAllowed ? EffectParameterType.RWByteAddressBuffer : EffectParameterType.ByteAddressBuffer, }); + + // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves ByteAddressBuffer type + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, byteAddressBufferType.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); + if (!byteAddressBufferType.WriteAllowed) + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.NonWritable, [])); } } else if (variableType is SamplerType) From df7b29f396f8abcafafdfc3694ba049c51cf4964 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 09:56:55 +0100 Subject: [PATCH 0890/1182] Fixed argument out of range exception in intrinsic base type resolution --- .../SDSL/AST/IntrinsicTemplateExpander.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index c24313b30c..049d824878 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -213,7 +213,32 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) if (parameterType.Match == null || parameterType.Match.Value.BaseType == index) throw new InvalidOperationException($"Intrinsic {name}: Can't resolve parameter {index} of type {parameterType}"); - parameterTypeHelper[index].BaseType = parameterTypeHelper[parameterType.Match.Value.BaseType].BaseType; + var matchBaseTypeIndex = parameterType.Match.Value.BaseType; + if (matchBaseTypeIndex == -1) + { + // Match thisType's base type + parameterTypeHelper[index].BaseType = thisType switch + { + TextureType t => t.ReturnType, + BufferType b => b.BaseType, + null => throw new ArgumentNullException(nameof(thisType)), + _ => throw new InvalidOperationException($"Can't resolve thisType base type for {thisType}"), + }; + } + else if (matchBaseTypeIndex == -3) + { + // Match funcT base type + parameterTypeHelper[index].BaseType = thisType switch + { + ByteAddressBufferType => ScalarType.UInt, + null => throw new ArgumentNullException(nameof(thisType)), + _ => throw new NotImplementedException($"$funcT not supported for {thisType}"), + }; + } + else + { + parameterTypeHelper[index].BaseType = parameterTypeHelper[matchBaseTypeIndex].BaseType; + } } } From 0cadcca2df009f0da16371e1260cf308dbdb06d6 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 09:57:48 +0100 Subject: [PATCH 0891/1182] Promote bool to int/uint/float in arithmetic contexts --- .../Spirv/Building/Builder.Expressions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index faad7d9ce7..d232505eb8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -113,6 +113,9 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle // If one side is unsigned, promote to unsigned (bitcast) (ScalarType { Type: Scalar.Int } l, ScalarType { Type: Scalar.UInt } r) => r, (ScalarType { Type: Scalar.UInt } l, ScalarType { Type: Scalar.Int } r) => l, + // Bool promotes to int/uint/float in arithmetic contexts (HLSL implicit conversion) + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double } r) => r, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double } l, ScalarType { Type: Scalar.Boolean }) => l, _ => throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftElementType} and {rightElementType}"), }; } From 1d19500a9eee217fa3232f2178c009507b0c0f70 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 12:22:54 +0100 Subject: [PATCH 0892/1182] Implemented most texture methods --- .../SDSL/AST/TextureMethodsImplementations.cs | 267 +++++++++++++++++- 1 file changed, 259 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index a4363ed6b6..ad4a118339 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -70,6 +70,22 @@ public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder buil return new(sample.ResultId, sample.ResultType); } + public override SpirvValue CompileSampleBias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, bias: bias); + var sample = builder.Insert(new OpImageSampleImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null) { if (status != null) @@ -118,6 +134,54 @@ public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder b return new(sample.ResultId, sample.ResultType); } + public override SpirvValue CompileSampleCmpBias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, bias: bias); + var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + public override SpirvValue CompileSampleCmpGrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + { + if (clamp != null || status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, ddx, ddy); + var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + + public override SpirvValue CompileSampleCmpLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? compareValue = null, SpirvValue? lod = null, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? c = null) + { + if (status != null) + throw new NotImplementedException(); + + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(lod, o, null, out var imask, out var imParams); + var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue!.Value.Id, imask, imParams)); + + return new(sample.ResultId, sample.ResultType); + } + public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null) { if (status != null) @@ -134,6 +198,125 @@ public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, Spirv return new(sample.ResultId, sample.ResultType); } + public override SpirvValue CompileCalculateLevelOfDetail(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + var float2Type = context.GetOrRegister(new VectorType(ScalarType.Float, 2)); + var queryResult = builder.Insert(new OpImageQueryLod(float2Type, context.Bound++, sampledImage.ResultId, x.Id)); + + // Component 0 = selected (clamped) mip level + var floatType = context.GetOrRegister(ScalarType.Float); + var result = builder.Insert(new OpCompositeExtract(floatType, context.Bound++, queryResult.ResultId, [0])); + return new(result.ResultId, result.ResultType); + } + + public override SpirvValue CompileCalculateLevelOfDetailUnclamped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + var float2Type = context.GetOrRegister(new VectorType(ScalarType.Float, 2)); + var queryResult = builder.Insert(new OpImageQueryLod(float2Type, context.Bound++, sampledImage.ResultId, x.Id)); + + // Component 1 = unclamped LOD + var floatType = context.GetOrRegister(ScalarType.Float); + var result = builder.Insert(new OpCompositeExtract(floatType, context.Bound++, queryResult.ResultId, [1])); + return new(result.ResultId, result.ResultType); + } + + // Gather: component 0 (same as GatherRed) + public override SpirvValue CompileGather(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + return CompileGatherComponent(context, builder, functionType, texture, s, x, 0, o); + } + + public override SpirvValue CompileGatherRed(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 0, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherComponent(context, builder, functionType, texture, s, x, 0, o); + } + + public override SpirvValue CompileGatherGreen(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 1, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherComponent(context, builder, functionType, texture, s, x, 1, o); + } + + public override SpirvValue CompileGatherBlue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 2, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherComponent(context, builder, functionType, texture, s, x, 2, o); + } + + public override SpirvValue CompileGatherAlpha(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 3, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherComponent(context, builder, functionType, texture, s, x, 3, o); + } + + public override SpirvValue CompileGatherCmp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + } + + public override SpirvValue CompileGatherCmpRed(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + } + + public override SpirvValue CompileGatherCmpGreen(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + } + + public override SpirvValue CompileGatherCmpBlue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + } + + public override SpirvValue CompileGatherCmpAlpha(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + { + if (status != null) + throw new NotImplementedException(); + if (o1 != null) + return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); + return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + } + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue? x = null, SpirvValue? width = null, SpirvValue? levels = null, SpirvValue? elements = null, SpirvValue? height = null, SpirvValue? samples = null, SpirvValue? depth = null) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; @@ -234,6 +417,69 @@ public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuild return default; } + private SpirvValue CompileGatherComponent(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue? o) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + var componentConstant = context.CompileConstant(component); + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + var gather = builder.Insert(new OpImageGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, imask, imParams)); + return new(gather.ResultId, gather.ResultType); + } + + private SpirvValue CompileGatherComponentConstOffsets(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + var componentConstant = context.CompileConstant(component); + + // Build ConstOffsets: array of 4 vec2 constant + var int2Type = new VectorType(ScalarType.Int, 2); + var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); + var constOffsetsId = context.Bound++; + builder.InsertData(new OpConstantComposite(arrayType, constOffsetsId, [o1.Id, o2.Id, o3.Id, o4.Id])); + + Span operands = [constOffsetsId]; + var imask = ImageOperandsMask.ConstOffsets; + var imParams = new EnumerantParameters(operands); + var gather = builder.Insert(new OpImageGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, imask, imParams)); + return new(gather.ResultId, gather.ResultType); + } + + private SpirvValue CompileGatherDref(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + var gather = builder.Insert(new OpImageDrefGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + return new(gather.ResultId, gather.ResultType); + } + + private SpirvValue CompileGatherDrefConstOffsets(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4) + { + var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + + // Build ConstOffsets: array of 4 vec2 constant + var int2Type = new VectorType(ScalarType.Int, 2); + var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); + var constOffsetsId = context.Bound++; + builder.InsertData(new OpConstantComposite(arrayType, constOffsetsId, [o1.Id, o2.Id, o3.Id, o4.Id])); + + Span operands = [constOffsetsId]; + var imask = ImageOperandsMask.ConstOffsets; + var imParams = new EnumerantParameters(operands); + var gather = builder.Insert(new OpImageDrefGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); + return new(gather.ResultId, gather.ResultType); + } + private static void StoreQueryComponent(SpirvContext context, SpirvBuilder builder, int uintTypeId, int sizeResultId, int sizeComponents, int componentIndex, SpirvValue outParam) { int valueId; @@ -268,24 +514,29 @@ private static void StoreConvertedValue(SpirvContext context, SpirvBuilder build } } - private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null) + private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null, SpirvValue? bias = null) { imask = ImageOperandsMask.None; - // Allocate for worst case (5 operands: lod/grad(2) + offset + sample) - Span operands = stackalloc int[5]; + // Allocate for worst case (6 operands: bias + grad(2) + lod + offset + sample) + Span operands = stackalloc int[6]; int operandCount = 0; - // Operands must appear in bit-order: Grad(0x4) < Lod(0x8) < Offset(0x10) < Sample(0x40) - if (ddx != null && ddy != null) + // Operands must appear in bit-order: Bias(0x1) < Lod(0x2) < Grad(0x4) < Offset(0x10) < Sample(0x40) + if (bias != null) { - imask |= ImageOperandsMask.Grad; - operands[operandCount++] = ddx.Value.Id; - operands[operandCount++] = ddy.Value.Id; + imask |= ImageOperandsMask.Bias; + operands[operandCount++] = bias.Value.Id; } if (lod != null) { imask |= ImageOperandsMask.Lod; operands[operandCount++] = lod.Value.Id; } + if (ddx != null && ddy != null) + { + imask |= ImageOperandsMask.Grad; + operands[operandCount++] = ddx.Value.Id; + operands[operandCount++] = ddy.Value.Id; + } if (offset != null) { imask |= ImageOperandsMask.Offset; From 4255b098c4e064de2f086e244e08def08d725340 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 12:25:25 +0100 Subject: [PATCH 0893/1182] Implemented mad intrinsic --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 892e3c4134..448332201d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -235,6 +235,12 @@ public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder return new(instruction.ResultId, instruction.ResultType); } + public override SpirvValue CompileMad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) + { + var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, c.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + // Float checks public override SpirvValue CompileIsnan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsNan, x); public override SpirvValue CompileIsinf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsInf, x); @@ -298,7 +304,6 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileIsnormal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileLdexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); public override SpirvValue CompileLit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m) => throw new NotImplementedException(); - public override SpirvValue CompileMad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); public override SpirvValue CompileModf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue ip) => throw new NotImplementedException(); public override SpirvValue CompileMsad4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue reference, SpirvValue source, SpirvValue accum) => throw new NotImplementedException(); public override SpirvValue CompileProcess2DQuadTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); From c51569197e89f9fbec25dec1f882d438eb022a26 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 12:48:13 +0100 Subject: [PATCH 0894/1182] Implemented discard --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index 4ee1b2bef3..57cfa83165 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -31,7 +31,8 @@ public override void ProcessSymbol(SymbolTable table) } public override void Compile(SymbolTable table, CompilerUnit compiler) { - throw new NotImplementedException(); + var (builder, context) = compiler; + builder.Insert(new OpKill()); } } public partial class Continue(TextLocation info) : Statement(info) From 4517ab4b3474e6386e46fcd2c7740b8cf6f75de9 Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 12:57:58 +0100 Subject: [PATCH 0895/1182] Fixed bool to string conversions --- .../Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs | 4 ++-- .../Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 64d31a367a..684a9bb3fd 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -109,10 +109,10 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin var shaderName = importShader.ShaderName; if (importShader.Values.Elements.Length > 0) { - var genericArguments = new object[importShader.Values.Elements.Length]; + var genericArguments = new string[importShader.Values.Elements.Length]; for (int j = 0; j < genericArguments.Length; j++) { - genericArguments[j] = context.GetConstantValue(importShader.Values.Elements.Span[j]); + genericArguments[j] = ShaderClassSource.ConvertGenericArgToString(context.GetConstantValue(importShader.Values.Elements.Span[j])); } shaderName += $"<{string.Join(",", genericArguments)}>"; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 77e097a0f4..ad9bc10b4a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -282,7 +282,7 @@ public override string ResolveGenericAsString(int genericIndex) if (!declaringContext.GenericValueCache.TryGetValue(constantId, out var textValue)) { textValue = declaringContext.TryGetConstantValue(constantId, out var constantValue, out _, false) - ? constantValue.ToString() + ? ShaderClassSource.ConvertGenericArgToString(constantValue) : GetIdRefAsString(genericIndex); declaringContext.GenericValueCache.Add(constantId, textValue); From b5254b7d381d041ce0f14ce5aa007ecd9ccd079f Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 15:15:24 +0100 Subject: [PATCH 0896/1182] Think I solved cbuffer array alignment issues --- .../Direct3D/ShaderCompiler.cs | 11 +++++++++ .../SDSL/ShaderMixer.CBuffers.cs | 1 + .../SDSL/ShaderMixer.Decorations.cs | 1 + .../Spirv/Building/Builder.CBuffer.cs | 23 ++++++++++++++++++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index 7aa36c61c2..bf248ccca1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -354,6 +354,17 @@ void UpdateConstantBufferReflection(EffectConstantBufferDescription reflectionCo // Adjust offset for next item constantBufferOffset += memberSize; + // Pad offset past full array stride range for spirv-cross compatibility: + // spirv-cross uses stride*count for arrays, while HLSL allows packing into + // the last element's padding. Ensure next field starts after stride*count. + if (member.Type.Elements > 0) + { + var stride = (member.Type.ElementSize + 15) / 16 * 16; + var paddedEnd = member.Offset + stride * member.Type.Elements; + if (constantBufferOffset < paddedEnd) + constantBufferOffset = paddedEnd; + } + reflectionConstantBuffer.Members[index] = member; } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index e7b0fbb6e0..b661f10797 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -438,6 +438,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon // Adjust offset for next item constantBufferOffset += memberSize; + SpirvBuilder.PadOffsetAfterArray(member.Type, member.TypeModifier, memberInfos[index].Offset, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer); } globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs index bbf938345f..ad7f5cd283 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -81,6 +81,7 @@ private void EmitStructDecorations(SpirvContext context, StructType s, SpirvBuil DecorateMember(context, structId, i, offset, memberSize, s.Members[i].Type, s.Members[i].TypeModifier); offset += memberSize; + SpirvBuilder.PadOffsetAfterArray(s.Members[i].Type, s.Members[i].TypeModifier, offsets[i], ref offset, alignmentRules); } decoratedStructs[structId] = (alignmentRules, offset, offsets); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs index d7cd1699ff..66b470cb5c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs @@ -1,4 +1,4 @@ -using Stride.Shaders.Core; +using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using System; using System.Collections.Generic; @@ -21,6 +21,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type static (int Size, int Alignment) Array((int Size, int Alignment) current, int count, AlignmentRules alignmentRules) => alignmentRules switch { + // HLSL array size: last element is not padded to stride AlignmentRules.CBuffer => ((current.Size + 15) / 16 * 16 * (count - 1) + current.Size, 16), AlignmentRules.StructuredBuffer => (current.Size * count, current.Alignment), }; @@ -52,6 +53,9 @@ private static (int, int) StructSizeInBuffer(StructuredType s, AlignmentRules al { var memberSizeAndAlignment = ComputeBufferOffset(member.Type, member.TypeModifier, ref offset, alignmentRules); offset += memberSizeAndAlignment.Size; + // SPIR-V/spirv-cross requires that no field falls within stride*count of an array. + // Pad offset past the full array stride range so subsequent fields don't overlap. + PadOffsetAfterArray(member.Type, member.TypeModifier, offset - memberSizeAndAlignment.Size, ref offset, alignmentRules); maxAlignment = Math.Max(memberSizeAndAlignment.Alignment, maxAlignment); } @@ -84,4 +88,21 @@ public static (int Size, int Alignment) ComputeBufferOffset(SymbolType type, Typ return (size, alignment); } + + /// + /// After advancing past an array member, ensure the offset is past stride*count of the array. + /// SPIR-V/spirv-cross cannot express fields that fall within an array's stride*count range, + /// even if those bytes are padding in the last element (which HLSL allows). + /// + public static void PadOffsetAfterArray(SymbolType type, TypeModifier typeModifier, int memberOffset, ref int constantBufferOffset, AlignmentRules alignmentRules) + { + if (alignmentRules == AlignmentRules.CBuffer && type is ArrayType a) + { + var elementSize = TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size; + var stride = (elementSize + 15) / 16 * 16; + var paddedEnd = memberOffset + stride * a.Size; + if (constantBufferOffset < paddedEnd) + constantBufferOffset = paddedEnd; + } + } } From 80c6a503d15174de3c5f882edae37baa57477c7d Mon Sep 17 00:00:00 2001 From: Johan Gustafsson Date: Sun, 1 Mar 2026 15:32:12 +0100 Subject: [PATCH 0897/1182] Implemeneted clip intrinsic --- .../SDSL/AST/IntrinsicImplementations.cs | 40 ++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 448332201d..c0a49b0ced 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -281,6 +281,45 @@ public override SpirvValue CompileFirstbithigh(SpirvContext context, SpirvBuilde public override SpirvValue CompileInterlockedCompareStoreFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => throw new NotImplementedException(); public override SpirvValue CompileInterlockedCompareExchangeFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => throw new NotImplementedException(); + // Misc + public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + // clip(x) discards the pixel if any component of x is less than zero. + // Equivalent to: if (any(x < 0)) discard; + var inputType = context.ReverseTypes[x.TypeId]; + var zero = context.CompileConstant(0.0f); + + int conditionId; + if (inputType is VectorType v) + { + var zeroVec = context.CreateConstantCompositeRepeat(inputType, zero, v.Size); + var boolVecType = new VectorType(ScalarType.Boolean, v.Size); + var cmpId = context.Bound++; + builder.InsertData(new OpFOrdLessThan(context.GetOrRegister(boolVecType), cmpId, x.Id, zeroVec.Id)); + var anyResult = builder.Insert(new OpAny(context.GetOrRegister(ScalarType.Boolean), context.Bound++, cmpId)); + conditionId = anyResult.ResultId; + } + else + { + var cmpId = context.Bound++; + builder.InsertData(new OpFOrdLessThan(context.GetOrRegister(ScalarType.Boolean), cmpId, x.Id, zero.Id)); + conditionId = cmpId; + } + + var killBlockId = context.Bound++; + var mergeBlockId = context.Bound++; + + builder.Insert(new OpSelectionMerge(mergeBlockId, Specification.SelectionControlMask.None)); + builder.Insert(new OpBranchConditional(conditionId, killBlockId, mergeBlockId, [])); + + builder.CreateBlock(context, killBlockId, "clip_kill"); + builder.Insert(new OpKill()); + + builder.CreateBlock(context, mergeBlockId, "clip_merge"); + + return new(); + } + public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder builder, FunctionType functionType) { builder.Insert(new OpTerminateInvocation()); @@ -290,7 +329,6 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileD3DCOLORtoUBYTE4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileGetRenderTargetSampleCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); public override SpirvValue CompileGetRenderTargetSamplePosition(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s) => throw new NotImplementedException(); - public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeAtSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue index) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeCentroid(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeSnapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset) => throw new NotImplementedException(); From d1e6df3d2f2cb38e58fbb0d726e7c94c6990c4a1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Feb 2026 09:38:23 +0900 Subject: [PATCH 0898/1182] SDSL: Adjusted cache system to cache each individual .sdsl shader --- .../EffectCompiler.cs | 31 +-- .../FileShaderCache.cs | 197 ++++++++++++++++++ .../FileShaderLoader.cs | 22 ++ 3 files changed, 226 insertions(+), 24 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs create mode 100644 sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 69503e26c2..53214f1501 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -33,12 +33,12 @@ namespace Stride.Shaders.Compiler /// /// An which will compile effect into multiple shader code, and compile them with a . /// - public class EffectCompiler : EffectCompilerBase + public partial class EffectCompiler : EffectCompilerBase { private bool d3dCompilerLoaded = false; private static readonly Object WriterLock = new Object(); - private ShaderLoader shaderLoader; + private FileShaderLoader shaderLoader; private readonly object shaderMixinParserLock = new object(); @@ -63,7 +63,7 @@ public EffectCompiler(IVirtualFileProvider fileProvider) public override ObjectId GetShaderSourceHash(string type) { - return GetShaderLoader().SourceManager.GetShaderSourceHash(type); + return GetFileShaderLoader().SourceManager.GetShaderSourceHash(type); } /// @@ -72,16 +72,16 @@ public override ObjectId GetShaderSourceHash(string type) /// public override void ResetCache(HashSet modifiedShaders) { - GetShaderLoader().SourceManager.DeleteObsoleteCache(modifiedShaders); + GetFileShaderLoader().SourceManager.DeleteObsoleteCache(modifiedShaders); } - public ShaderLoader GetShaderLoader() + public FileShaderLoader GetFileShaderLoader() { lock (shaderMixinParserLock) { if (shaderLoader == null) { - shaderLoader = new ShaderLoader(FileProvider); + shaderLoader = new FileShaderLoader(FileProvider); shaderLoader.SourceManager.LookupDirectoryList.AddRange(SourceDirectories); // TODO: temp shaderLoader.SourceManager.UseFileSystem = UseFileSystem; shaderLoader.SourceManager.UrlToFilePath = UrlToFilePath; // TODO: temp @@ -91,23 +91,6 @@ public ShaderLoader GetShaderLoader() } } - public class ShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new ShaderCache()) - { - public ShaderSourceManager SourceManager { get; } = new(FileProvider); - - protected override bool ExternalFileExists(string name) => SourceManager.IsClassExists(name); - - public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) - { - var result = SourceManager.LoadShaderSource(name); - filename = result.Path; - code = result.Source; - hash = result.Hash; - - return true; - } - } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters) { var log = new LoggerResult(); @@ -160,7 +143,7 @@ public override TaskOrResult Compile(ShaderMixinSo // In .sdsl, class has been renamed to shader to avoid ambiguities with HLSL shaderMixinSource.AddMacro("class", "shader"); - var shaderMixer = new ShaderMixer(GetShaderLoader()); + var shaderMixer = new ShaderMixer(GetFileShaderLoader()); shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs new file mode 100644 index 0000000000..7b146eeef3 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs @@ -0,0 +1,197 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using Stride.Core.IO; +using Stride.Core.Storage; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Compilers; + +/// +/// File-backed that persists compiled shader bytecodes +/// to disk via , falling back to in-memory cache for hot lookups. +/// +public class FileShaderCache(IVirtualFileProvider fileProvider, string basePath = "shader/cache") : IShaderCache +{ + private readonly ShaderCache memoryCache = new(); + + public bool Exists(string name) + { + if (memoryCache.Exists(name)) + return true; + + try + { + var dir = $"{basePath}/{SanitizeName(name)}"; + return fileProvider.DirectoryExists(dir); + } + catch + { + return false; + } + } + + public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash) + { + memoryCache.RegisterShader(name, defines, bytecode, hash); + + try + { + var path = GetCachePath(name, defines); + var dir = path[..path.LastIndexOf('/')]; + if (!fileProvider.DirectoryExists(dir)) + fileProvider.CreateDirectory(dir); + + using var stream = fileProvider.OpenStream(path, VirtualFileMode.Create, VirtualFileAccess.Write); + using var writer = new BinaryWriter(stream); + Serialize(writer, bytecode, hash ?? ObjectId.Empty); + } + catch + { + // Silently ignore write failures — next run will just recompile + } + } + + public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) + { + if (memoryCache.TryLoadFromCache(name, defines, out buffer, out hash)) + return true; + + try + { + var path = GetCachePath(name, defines); + if (!fileProvider.FileExists(path)) + { + buffer = default; + hash = default; + return false; + } + + using var stream = fileProvider.OpenStream(path, VirtualFileMode.Open, VirtualFileAccess.Read); + using var reader = new BinaryReader(stream); + buffer = Deserialize(reader, out hash); + + // Populate in-memory cache for subsequent lookups + memoryCache.RegisterShader(name, defines, buffer, hash); + return true; + } + catch + { + // Corrupt or incompatible cache — fall back to recompilation + buffer = default; + hash = default; + return false; + } + } + + private string GetCachePath(string name, ReadOnlySpan defines) + { + var sanitized = SanitizeName(name); + var macrosKey = defines.Length == 0 ? "default" : ComputeMacrosHash(defines); + return $"{basePath}/{sanitized}/{macrosKey}"; + } + + private static string SanitizeName(string name) + { + Span result = stackalloc char[name.Length]; + for (int i = 0; i < name.Length; i++) + { + var c = name[i]; + result[i] = c switch + { + '<' or '>' or '%' or '"' or '|' or '*' or '?' or ':' => '_', + _ => c, + }; + } + return new string(result); + } + + private static string ComputeMacrosHash(ReadOnlySpan defines) + { + var builder = new ObjectIdBuilder(); + for (int i = 0; i < defines.Length; i++) + { + var nameBytes = Encoding.UTF8.GetBytes(defines[i].Name ?? string.Empty); + var defBytes = Encoding.UTF8.GetBytes(defines[i].Definition ?? string.Empty); + builder.Write(nameBytes, 0, nameBytes.Length); + builder.Write(defBytes, 0, defBytes.Length); + } + return builder.ComputeHash().ToString(); + } + + private static void Serialize(BinaryWriter writer, ShaderBuffers buffers, ObjectId hash) + { + // Header + writer.Write(buffers.Context.Bound); + WriteObjectId(writer, hash); + + // Context buffer + var contextBuffer = buffers.Context.GetBuffer(); + writer.Write(GetTotalWordCount(contextBuffer)); + WriteBuffer(writer, contextBuffer); + + // Main buffer + WriteBuffer(writer, buffers.Buffer); + } + + private static ShaderBuffers Deserialize(BinaryReader reader, out ObjectId hash) + { + // Header + var bound = reader.ReadInt32(); + hash = ReadObjectId(reader); + + // Context buffer + var contextWordCount = reader.ReadInt32(); + var contextWords = new int[contextWordCount]; + for (int i = 0; i < contextWordCount; i++) + contextWords[i] = reader.ReadInt32(); + + // Main buffer — read remaining bytes + var remainingBytes = reader.BaseStream.Length - reader.BaseStream.Position; + var mainWordCount = (int)(remainingBytes / sizeof(int)); + var mainWords = new int[mainWordCount]; + for (int i = 0; i < mainWordCount; i++) + mainWords[i] = reader.ReadInt32(); + + // Reconstruct + var contextBuffer = new SpirvBuffer(contextWords); + var mainBuffer = new SpirvBuffer(mainWords); + var context = new SpirvContext(contextBuffer) { Bound = bound }; + ShaderClass.ProcessNameAndTypes(context); + return new ShaderBuffers(context, mainBuffer); + } + + private static int GetTotalWordCount(SpirvBuffer buffer) + { + int count = 0; + foreach (var i in buffer) + count += i.Data.Memory.Length; + return count; + } + + private static void WriteBuffer(BinaryWriter writer, SpirvBuffer buffer) + { + foreach (var i in buffer) + { + var span = i.Data.Memory.Span; + for (int j = 0; j < span.Length; j++) + writer.Write(span[j]); + } + } + + private static void WriteObjectId(BinaryWriter writer, ObjectId id) + { + var bytes = MemoryMarshal.AsBytes(new ReadOnlySpan(in id)); + writer.Write(bytes); + } + + private static ObjectId ReadObjectId(BinaryReader reader) + { + Span bytes = stackalloc byte[ObjectId.HashSize]; + reader.Read(bytes); + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(bytes)); + } +} diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs new file mode 100644 index 0000000000..c7a86d4bc4 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs @@ -0,0 +1,22 @@ +using Stride.Core.IO; +using Stride.Core.Storage; +using Stride.Shaders.Spirv.Building; + +namespace Stride.Shaders.Compilers; + +public class FileShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new FileShaderCache(FileProvider)) +{ + public ShaderSourceManager SourceManager { get; } = new(FileProvider); + + protected override bool ExternalFileExists(string name) => SourceManager.IsClassExists(name); + + public override bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash) + { + var result = SourceManager.LoadShaderSource(name); + filename = result.Path; + code = result.Source; + hash = result.Hash; + + return true; + } +} From 86518be65d3070e4f4aa20d4aa8d05179ea2b16a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 9 Mar 2026 17:42:14 +0900 Subject: [PATCH 0899/1182] ShaderCompiler: fix error/warning processing (split by line, remove nul terminator) --- .../Direct3D/ShaderCompiler.cs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index bf248ccca1..01df1e05a0 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -121,7 +121,7 @@ public ShaderBytecodeResult Compile(string shaderSource, string entryPoint, Shad if (compileErrors.Handle is not null) { - bytecodeResult.Warning(GetTextFromBlob(compileErrors)); + ProcessCompilerErrors(compileErrors, bytecodeResult); } } @@ -195,13 +195,31 @@ HResult Compile() // Log compilation errors if (compileErrors.Handle is not null) { - bytecodeResult.Error(GetTextFromBlob(compileErrors)); + ProcessCompilerErrors(compileErrors, bytecodeResult); } } return result; } + static void ProcessCompilerErrors(ComPtr compileErrors, ShaderBytecodeResult bytecodeResult) + { + var compileErrorsStr = GetTextFromBlob(compileErrors); + using (StringReader reader = new StringReader(compileErrorsStr)) + { + string line; + while ((line = reader.ReadLine()) != null) + { + if (line.Contains(": error")) + bytecodeResult.Error(line); + else if (line.Contains(": warning")) + bytecodeResult.Warning(line); + else + bytecodeResult.Info(line); + } + } + } + // // Disassembles a blob of Shader byte-code to its textual equivalent in HLSL code. // @@ -700,7 +718,8 @@ static string GetTextFromBlob(ComPtr blob) if (blob.Handle is null) return null; - var blobBuffer = blob.Handle->Buffer; + // Remove nul terminator + var blobBuffer = blob.Handle->Buffer[0..^1]; return blobBuffer.GetString(); } From 69b263ce7f5e3a1fe322ab3f5118b441c756956c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 9 Mar 2026 18:42:38 +0900 Subject: [PATCH 0900/1182] SDSL: Properly cache intermediate shaders --- sources/core/Stride.Core/Storage/ObjectId.cs | 5 ++ .../EffectCompiler.cs | 2 +- .../FileShaderCache.cs | 83 +++++++++---------- .../FileShaderLoader.cs | 2 +- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 12 ++- .../SDSL/ShaderMixer.cs | 8 +- .../ShaderLoaderBase.cs | 8 +- .../Spirv/Building/Builder.Class.cs | 60 ++++++++++---- .../Spirv/Building/Context.cs | 16 ++-- .../Stride.Shaders.Parsers/Spirv/Tools/Dis.cs | 2 +- .../Buffers/SpirvBytecode.cs | 8 +- .../Extensions/spirv.sdsl.grammar-ext.json | 11 +++ .../Information/InstructionInfo.Order.cs | 5 +- .../Stride.Shaders.Tests/RenderingTests.cs | 6 +- .../Stride.Shaders.Tests/ShaderLoader.cs | 4 +- .../Stride.Shaders.Tests/StrideShaderTests.cs | 2 +- 16 files changed, 144 insertions(+), 90 deletions(-) diff --git a/sources/core/Stride.Core/Storage/ObjectId.cs b/sources/core/Stride.Core/Storage/ObjectId.cs index bbc591d2af..dedf8e4565 100644 --- a/sources/core/Stride.Core/Storage/ObjectId.cs +++ b/sources/core/Stride.Core/Storage/ObjectId.cs @@ -34,6 +34,11 @@ public unsafe partial struct ObjectId : IEquatable, IComparable hash1; + public uint Hash2 => hash2; + public uint Hash3 => hash3; + public uint Hash4 => hash4; + /// /// Initializes a new instance of the struct. /// diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 53214f1501..61a08b9efc 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -189,7 +189,7 @@ public override TaskOrResult Compile(ShaderMixinSo if (!File.Exists(shaderSourceFilename)) { File.WriteAllBytes(Path.ChangeExtension(shaderSourceFilename, ".spv"), spirvBytecode); - File.WriteAllText(Path.ChangeExtension(shaderSourceFilename, ".spvdis"), Spirv.Tools.Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); + File.WriteAllText(Path.ChangeExtension(shaderSourceFilename, ".spvdis"), Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); } } #else diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs index 7b146eeef3..3fdf6c8f66 100644 --- a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs @@ -2,10 +2,12 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; +using CommunityToolkit.HighPerformance; using Stride.Core.IO; using Stride.Core.Storage; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Compilers; @@ -14,7 +16,7 @@ namespace Stride.Shaders.Compilers; /// File-backed that persists compiled shader bytecodes /// to disk via , falling back to in-memory cache for hot lookups. /// -public class FileShaderCache(IVirtualFileProvider fileProvider, string basePath = "shader/cache") : IShaderCache +public class FileShaderCache(IVirtualFileProvider fileProvider, string basePath = "shaders") : IShaderCache { private readonly ShaderCache memoryCache = new(); @@ -34,13 +36,13 @@ public bool Exists(string name) } } - public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash) + public void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash) { - memoryCache.RegisterShader(name, defines, bytecode, hash); + memoryCache.RegisterShader(name, generics, defines, bytecode, hash); try { - var path = GetCachePath(name, defines); + var path = GetCachePath(name, generics, defines); var dir = path[..path.LastIndexOf('/')]; if (!fileProvider.DirectoryExists(dir)) fileProvider.CreateDirectory(dir); @@ -55,14 +57,14 @@ public void RegisterShader(string name, ReadOnlySpan defines, Shade } } - public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) + public bool TryLoadFromCache(string name, string? generics, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) { - if (memoryCache.TryLoadFromCache(name, defines, out buffer, out hash)) + if (memoryCache.TryLoadFromCache(name, generics, defines, out buffer, out hash)) return true; try { - var path = GetCachePath(name, defines); + var path = GetCachePath(name, generics, defines); if (!fileProvider.FileExists(path)) { buffer = default; @@ -75,7 +77,7 @@ public bool TryLoadFromCache(string name, ReadOnlySpan defines, [Ma buffer = Deserialize(reader, out hash); // Populate in-memory cache for subsequent lookups - memoryCache.RegisterShader(name, defines, buffer, hash); + memoryCache.RegisterShader(name, generics, defines, buffer, hash); return true; } catch @@ -87,11 +89,11 @@ public bool TryLoadFromCache(string name, ReadOnlySpan defines, [Ma } } - private string GetCachePath(string name, ReadOnlySpan defines) + private string GetCachePath(string name, string? generics, ReadOnlySpan defines) { var sanitized = SanitizeName(name); - var macrosKey = defines.Length == 0 ? "default" : ComputeMacrosHash(defines); - return $"{basePath}/{sanitized}/{macrosKey}"; + var macrosKey = defines.Length == 0 ? "default" : ComputeCacheFilename(generics, defines); + return $"{basePath}/{sanitized}_{macrosKey}.spv"; } private static string SanitizeName(string name) @@ -109,9 +111,11 @@ private static string SanitizeName(string name) return new string(result); } - private static string ComputeMacrosHash(ReadOnlySpan defines) + private static string ComputeCacheFilename(string? generics, ReadOnlySpan defines) { var builder = new ObjectIdBuilder(); + if (generics != null) + builder.Write(generics); for (int i = 0; i < defines.Length; i++) { var nameBytes = Encoding.UTF8.GetBytes(defines[i].Name ?? string.Empty); @@ -124,44 +128,31 @@ private static string ComputeMacrosHash(ReadOnlySpan defines) private static void Serialize(BinaryWriter writer, ShaderBuffers buffers, ObjectId hash) { - // Header - writer.Write(buffers.Context.Bound); - WriteObjectId(writer, hash); - - // Context buffer - var contextBuffer = buffers.Context.GetBuffer(); - writer.Write(GetTotalWordCount(contextBuffer)); - WriteBuffer(writer, contextBuffer); - - // Main buffer - WriteBuffer(writer, buffers.Buffer); + var bytecode = SpirvBytecode.CreateBytecodeFromBuffers(buffers.Context.GetBuffer(), buffers.Buffer); + writer.Write(bytecode); } private static ShaderBuffers Deserialize(BinaryReader reader, out ObjectId hash) { - // Header - var bound = reader.ReadInt32(); - hash = ReadObjectId(reader); - - // Context buffer - var contextWordCount = reader.ReadInt32(); - var contextWords = new int[contextWordCount]; - for (int i = 0; i < contextWordCount; i++) - contextWords[i] = reader.ReadInt32(); - - // Main buffer — read remaining bytes - var remainingBytes = reader.BaseStream.Length - reader.BaseStream.Position; - var mainWordCount = (int)(remainingBytes / sizeof(int)); - var mainWords = new int[mainWordCount]; - for (int i = 0; i < mainWordCount; i++) - mainWords[i] = reader.ReadInt32(); - - // Reconstruct - var contextBuffer = new SpirvBuffer(contextWords); - var mainBuffer = new SpirvBuffer(mainWords); - var context = new SpirvContext(contextBuffer) { Bound = bound }; - ShaderClass.ProcessNameAndTypes(context); - return new ShaderBuffers(context, mainBuffer); + var buffer = new byte[reader.BaseStream.Length]; + reader.ReadExactly(buffer); + + var result = ShaderBuffers.CreateFromSpan(buffer.AsSpan().Cast()); + + // Fetch hash from OpSourceHashSDSL + hash = default; + foreach (var i in result.Context) + { + if (i.Op == Spirv.Specification.Op.OpSourceHashSDSL && (OpSourceHashSDSL)i is { } sourceHash) + { + hash = new ObjectId((uint)sourceHash.Hash1, (uint)sourceHash.Hash2, (uint)sourceHash.Hash3, (uint)sourceHash.Hash4); + break; + } + } + + ShaderClass.ProcessNameAndTypes(result.Context); + + return result; } private static int GetTotalWordCount(SpirvBuffer buffer) diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs index c7a86d4bc4..e23ed7b0ef 100644 --- a/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs @@ -4,7 +4,7 @@ namespace Stride.Shaders.Compilers; -public class FileShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new FileShaderCache(FileProvider)) +public class FileShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new FileShaderCache(VirtualFileSystem.ApplicationCache)) { public ShaderSourceManager SourceManager { get; } = new(FileProvider); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 365f3e88dd..6b9ad8d9f1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -16,7 +16,7 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) + public readonly bool Compile(string filename, string code, ObjectId hash, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) { var parsed = SDSLParser.Parse(code); lastBuffer = default; @@ -38,6 +38,14 @@ public readonly bool Compile(string code, ObjectId hash, ReadOnlySpan 1 spv mapping anymore) + if (i.Op == Op.OpSourceHashSDSL) + include = false; + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; @@ -1003,7 +1008,8 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLImportShader || i.Op == Op.OpSDSLImportFunction || i.Op == Op.OpSDSLImportVariable - || i.Op == Op.OpSDSLFunctionInfo) + || i.Op == Op.OpSDSLFunctionInfo + || i.Op == Op.OpSourceHashSDSL) return true; if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is Decoration.FunctionParameterDefaultValueSDSL diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 7b9bc139b1..c1a1f2e0d2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -1,4 +1,4 @@ -using Stride.Shaders.Compilers.SDSL; +using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; @@ -27,7 +27,7 @@ public bool Exists(string name) public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = Cache.TryLoadFromCache(name, defines, out buffer, out hash); + isFromCache = Cache.TryLoadFromCache(name, null, defines, out buffer, out hash); if (isFromCache) return true; @@ -51,7 +51,7 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { - isFromCache = Cache.TryLoadFromCache(name, defines, out buffer, out hash); + isFromCache = Cache.TryLoadFromCache(name, null, defines, out buffer, out hash); if (isFromCache) return true; @@ -78,6 +78,6 @@ protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, ShaderLoader = this, }; - return sdslc.Compile(text, hash, macros, out buffer); + return sdslc.Compile(filename, text, hash, macros, out buffer); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index ad9bc10b4a..206d4e9f6e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -1,4 +1,4 @@ -using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; using Stride.Shaders.Parsing; @@ -19,12 +19,38 @@ using System.Threading.Tasks; using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; +using Stride.Shaders.Spirv.Core.Parsing; namespace Stride.Shaders.Spirv.Building; public record class ShaderMixinInstantiation(List Mixins, Dictionary Compositions); -public record struct ShaderBuffers(SpirvContext Context, SpirvBuffer Buffer); +public record struct ShaderBuffers(SpirvContext Context, SpirvBuffer Buffer) +{ + public static ShaderBuffers CreateFromSpan(Span span) + { + if (span[0] != Specification.MagicNumber) + throw new InvalidOperationException("SPIRV Magic number not found"); + + var header = SpirvHeader.Read(span); + + var context = new SpirvContext(); + var buffer = new SpirvBuffer(); + + int wid = SpirvHeader.IntSpanSize; + bool isContext = true; + while (wid < span.Length) + { + var instruction = new OpData(span.Slice(wid, span[wid] >> 16)); + if (instruction.Op == Op.OpSDSLShader) + isContext = false; + (isContext ? context.GetBuffer() : buffer).Add(instruction); + wid += span[wid] >> 16; + } + + return new(context, buffer); + } +} public enum ResolveStep { @@ -423,18 +449,21 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st genericResolver.ValidateGenericParameters(classNameWithGenerics, genericParameters); } - private static string BuildGenericClassName(string className, GenericResolver resolver) + private static string BuildGenericArguments(GenericResolver resolver) { - StringBuilder sb = new(); - sb.Append(className).Append("<"); - + var result = new string[resolver.GenericArgumentCount]; for (int i = 0; i < resolver.GenericArgumentCount; i++) - { - if (i > 0) - sb.Append(","); - sb.Append(resolver.ResolveGenericAsString(i)); - } - sb.Append(">"); + result[i] = resolver.ResolveGenericAsString(i); + return string.Join(',', result); + } + + private static string BuildGenericClassName(string className, string genericArguments) + { + StringBuilder sb = new(); + sb.Append(className) + .Append("<") + .Append(genericArguments) + .Append(">"); return sb.ToString(); } @@ -737,9 +766,10 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, if (genericResolver.GenericArgumentCount > 0) { // First, try to build name for cache lookup - var classNameWithGenerics = BuildGenericClassName(className, genericResolver); + var genericArguments = BuildGenericArguments(genericResolver); + var classNameWithGenerics = BuildGenericClassName(className, genericArguments); var cache = genericResolver.Cache ?? shaderLoader.Cache; - if (cache.TryLoadFromCache(classNameWithGenerics, macros, out var cachedShaderBuffers, out var cachedHash)) + if (cache.TryLoadFromCache(className, genericArguments, macros, out var cachedShaderBuffers, out var cachedHash)) { shaderBuffers = cachedShaderBuffers; hash = cachedHash; @@ -759,7 +789,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); - cache.RegisterShader(classNameWithGenerics, macros, shaderBuffers, hash); + cache.RegisterShader(className, genericArguments, macros, shaderBuffers, hash); } // Run in all cases (even if cached) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 6a96d0ff06..b134042428 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -17,9 +17,9 @@ namespace Stride.Shaders.Spirv.Building; public interface IShaderCache { - public void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash); + public void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash); public bool Exists(string name); - public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash); + public bool TryLoadFromCache(string name, string? generics, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash); } public class ShaderCache : IShaderCache @@ -43,13 +43,13 @@ public bool Equals(ShaderLoadKey other) } } - private Dictionary BuffersPerMacros)> loadedShaders = []; + private Dictionary<(string Name, string? Generics), (ObjectId Hash, Dictionary BuffersPerMacros)> loadedShaders = []; - public bool Exists(string name) => loadedShaders.ContainsKey(name); + public bool Exists(string name) => loadedShaders.ContainsKey((name, null)); - public virtual void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) + public virtual void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { - ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, name, out var exists); + ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, (name, generics), out var exists); if (!exists) loadedShadersByName = hash != null ? new(hash.Value, new()) : new(); loadedShadersByName.BuffersPerMacros.Add(new(defines.ToArray()), bytecode); @@ -57,9 +57,9 @@ public virtual void RegisterShader(string name, ReadOnlySpan define loadedShadersByName.Hash = hash.Value; } - public bool TryLoadFromCache(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) + public bool TryLoadFromCache(string name, string? generics, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) { - if (loadedShaders.TryGetValue(name, out var loadedShadersByName) + if (loadedShaders.TryGetValue((name, generics), out var loadedShadersByName) && loadedShadersByName.BuffersPerMacros.TryGetValue(new(defines.ToArray()), out buffer)) { hash = loadedShadersByName.Hash; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs index 80286135c2..b9ec7d66fe 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs @@ -58,7 +58,7 @@ public static string Dis(SpirvBytecode bytecode, DisassemblerFlags flags = Disas public static string Dis(SpirvReader reader, DisassemblerFlags flags = DisassemblerFlags.Name, bool writeToConsole = false) { - using var buffer = SpirvBytecode.CreateBufferFromBytecode(reader.Words); + using var buffer = SpirvBytecode.CreateFromSpan(reader.Words); var writer = new DisWriter(buffer, flags, writeToConsole); writer.Disassemble(); return writer.ToString(); diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs index 007a6130ec..ab41d98876 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Buffers/SpirvBytecode.cs @@ -25,17 +25,17 @@ public static SpirvHeader CreateHeader(SpirvBuffer buffer) return new SpirvHeader("1.4", 0, bound); } - public Span ToBytecode() + public Span ToSpan() { return CreateBytecodeFromBuffers(Header, false, Buffer); } - public static SpirvBytecode CreateBufferFromBytecode(Span span) + public static SpirvBytecode CreateFromSpan(Span span) { - return CreateBufferFromBytecode(MemoryMarshal.Cast(span)); + return CreateFromSpan(MemoryMarshal.Cast(span)); } - public static SpirvBytecode CreateBufferFromBytecode(Span span) + public static SpirvBytecode CreateFromSpan(Span span) { if (span[0] != Specification.MagicNumber) throw new InvalidOperationException("SPIRV Magic number not found"); diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index dd10b92836..dfd68d34fd 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -375,6 +375,17 @@ { "kind" : "IdRef", "name" : "'Operand 2'" } ] }, + { + "opname": "OpSourceHashSDSL", + "class": "Miscellaneous", + "operands": [ + { "kind" : "IdRef", "name" : "'File'" }, + { "kind" : "LiteralInteger", "name" : "Hash1" }, + { "kind" : "LiteralInteger", "name" : "Hash2" }, + { "kind" : "LiteralInteger", "name" : "Hash3" }, + { "kind" : "LiteralInteger", "name" : "Hash4" } + ] + }, { "opname": "OpEffectSDFX", "opcode" : 9000, diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 515d360af6..2a657b423c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; @@ -33,6 +33,9 @@ void InitOrder() foreach (var e in initSDSL) OrderGroup[(e, null)] = group; + group++; + OrderGroup[(Op.OpSourceHashSDSL, null)] = group; + group++; OrderGroup[(Op.OpExtension, null)] = group; diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 8d87cd2c33..3069c2bb59 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -44,7 +44,7 @@ public void ComputeTest1(string shaderName) shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); - File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); @@ -89,7 +89,7 @@ public void RenderTest1(string shaderName) shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); - File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); // Convert to HLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); @@ -158,7 +158,7 @@ public void StreamOutTest1(string shaderName) shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); - File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); // Convert to HLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs index f493b51533..45645dcdac 100644 --- a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -56,9 +56,9 @@ protected override bool LoadFromCode(string filename, string code, ObjectId hash class TestShaderCache : ShaderCache { - public override void RegisterShader(string name, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) + public override void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { - base.RegisterShader(name, defines, bytecode, hash); + base.RegisterShader(name, generics, defines, bytecode, hash); Console.WriteLine($"Registering shader {name}"); Spv.Dis(bytecode, DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true); diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index 18a1d34c05..4b5dbb0626 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -190,7 +190,7 @@ public void Tessellation() shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"StrideTessellation.spv", bytecode); - File.WriteAllText($"StrideTessellation.spvdis", Spv.Dis(SpirvBytecode.CreateBufferFromBytecode(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + File.WriteAllText($"StrideTessellation.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); From 12a02d3c8f79feb39dd112266a5bf9ce2c915e5c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 15:15:06 +0900 Subject: [PATCH 0901/1182] SDSL: Rewrote cache to save effect files in "cache\effects" and save .spv/.hlsl side by side --- .../Shaders.Compiler/RemoteEffectCompiler.cs | 2 +- .../EffectCompiler.cs | 98 ++++++------------- .../Compiler/EffectCompilerBase.cs | 6 +- .../Compiler/EffectCompilerCache.cs | 91 ++++++++++++++--- .../Compiler/EffectCompilerChain.cs | 4 +- .../Compiler/NullEffectCompiler.cs | 2 +- .../EffectCompilerServer.cs | 4 +- 7 files changed, 118 insertions(+), 89 deletions(-) diff --git a/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs b/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs index be29e0b39c..13385a904d 100644 --- a/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs +++ b/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs @@ -46,7 +46,7 @@ public override ObjectId GetShaderSourceHash(string type) } /// - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters = null) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) { return CompileAsync(mixinTree, effectParameters); } diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 61a08b9efc..7148e32efa 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; using CommunityToolkit.HighPerformance; using Silk.NET.SPIRV; @@ -91,7 +90,7 @@ public FileShaderLoader GetFileShaderLoader() } } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) { var log = new LoggerResult(); @@ -172,28 +171,25 @@ public override TaskOrResult Compile(ShaderMixinSo }*/ // ------------------------------------------------------- - // Save shader log - // TODO: TEMP code to allow debugging generated shaders on Windows Desktop + // Save shader log to DynamicCache folder #if STRIDE_PLATFORM_DESKTOP - var shaderId = ObjectId.FromBytes(spirvBytecode); - - var logDir = Path.Combine(PlatformFolders.ApplicationBinaryDirectory, "log"); - if (!Directory.Exists(logDir)) - { - Directory.CreateDirectory(logDir); - } - var shaderSourceFilename = Path.Combine(logDir, "shader_" + fullEffectName.Replace('.', '_') + "_" + shaderId + ".hlsl"); + var effectDir = Path.Combine( + PlatformFolders.ApplicationCacheDirectory, + EffectCompilerCache.GetEffectCacheDirectory(fullEffectName)); + if (!Directory.Exists(effectDir)) + Directory.CreateDirectory(effectDir); + var shaderBaseFilename = Path.Combine(effectDir, mixinObjectId.ToString()); lock (WriterLock) // protect write in case the same shader is created twice { // Write shader before generating to make sure that we are having a trace before compiling it (compiler may crash...etc.) - if (!File.Exists(shaderSourceFilename)) + if (!File.Exists(shaderBaseFilename + ".spv")) { - File.WriteAllBytes(Path.ChangeExtension(shaderSourceFilename, ".spv"), spirvBytecode); - File.WriteAllText(Path.ChangeExtension(shaderSourceFilename, ".spvdis"), Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); + File.WriteAllBytes(shaderBaseFilename + ".spv", spirvBytecode); + File.WriteAllText(shaderBaseFilename + ".spvdis", Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); } } #else - string shaderSourceFilename = null; + string shaderBaseFilename = null; #endif // Select the correct backend compiler @@ -226,8 +222,6 @@ public override TaskOrResult Compile(ShaderMixinSo var bytecode = new EffectBytecode { Reflection = effectReflection, HashSources = usedHashSources }; - var shaderSourceText = new StringBuilder(); - if (translatorBackend != null) { var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); @@ -247,20 +241,27 @@ public override TaskOrResult Compile(ShaderMixinSo ExecutionModel.Fragment => ShaderStage.Pixel, ExecutionModel.GLCompute => ShaderStage.Compute, }; - var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, shaderSourceFilename); - result.CopyTo(log); - - shaderSourceText.AppendLine("// =========================================="); - shaderSourceText.AppendLine($"// {shaderStage} shader"); - shaderSourceText.AppendLine(code); - shaderSourceText.AppendLine(); - shaderSourceText.AppendLine($"// {result.Messages.Count} errors & messages:"); - foreach (var message in result.Messages) +#if STRIDE_PLATFORM_DESKTOP + var stageSuffix = shaderStage switch { - shaderSourceText.AppendLine($"[{message.Type}] {message.Text}"); - shaderSourceText.AppendLine(); + ShaderStage.Vertex => "vs", + ShaderStage.Hull => "hs", + ShaderStage.Domain => "ds", + ShaderStage.Geometry => "gs", + ShaderStage.Pixel => "ps", + ShaderStage.Compute => "cs", + }; + var stageFilename = $"{shaderBaseFilename}_{stageSuffix}.hlsl"; + lock (WriterLock) + { + File.WriteAllText(stageFilename, code); } +#else + string stageFilename = null; +#endif + var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename); + result.CopyTo(log); if (result.HasErrors) { @@ -354,9 +355,6 @@ public override TaskOrResult Compile(ShaderMixinSo bytecode.Stages = shaderStageBytecodes.ToArray(); #if STRIDE_PLATFORM_DESKTOP - int shaderSourceLineOffset = 0; - int shaderSourceCharacterOffset = 0; - string outputShaderLog; lock (WriterLock) // protect write in case the same shader is created twice { var builder = new StringBuilder(); @@ -414,41 +412,7 @@ public override TaskOrResult Compile(ShaderMixinSo } builder.AppendLine("*************************/"); - shaderSourceCharacterOffset = builder.Length; - - // Re-append the shader with all informations - builder.Append(shaderSourceText); - - outputShaderLog = builder.ToString(); - - File.WriteAllText(shaderSourceFilename, outputShaderLog); - } - - // Count lines till source start - for (int i = 0; i < shaderSourceCharacterOffset-1;) - { - if (outputShaderLog[i] == '\r' && outputShaderLog[i + 1] == '\n') - { - shaderSourceLineOffset++; - i += 2; - } - else - i++; - } - - // Rewrite shader log - Regex shaderLogReplace = new Regex(@"\.hlsl\((\d+),[0-9\-]+\):"); - foreach (var msg in log.Messages) - { - var match = shaderLogReplace.Match(msg.Text); - if (match.Success) - { - int line = int.Parse(match.Groups[1].Value); - line += shaderSourceLineOffset; - - msg.Text = msg.Text.Remove(match.Groups[1].Index, match.Groups[1].Length) - .Insert(match.Groups[1].Index, line.ToString()); - } + File.WriteAllText(shaderBaseFilename + "_meta.hlsl", builder.ToString()); } #endif diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs index 70db9f3563..cdca95b7fa 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs @@ -67,7 +67,8 @@ public CompilerResults Compile(ShaderSource shaderSource, CompilerParameters com // Compile the whole mixin tree var compilerResults = new CompilerResults { Module = $"EffectCompile [{mixinToCompile.Name}]" }; - var bytecode = Compile(mixinToCompile, compilerParameters.EffectParameters, compilerParameters); + var mixinObjectId = ShaderMixinObjectId.Compute(mixinToCompile, compilerParameters.EffectParameters); + var bytecode = Compile(mixinToCompile, effectParameters: compilerParameters.EffectParameters, compilerParameters, mixinObjectId); // Since bytecode.Result is a struct, we check if any of its member has been set to know if it's valid if (bytecode.Result.CompilationLog is not null || bytecode.Task is not null) @@ -89,7 +90,8 @@ public CompilerResults Compile(ShaderSource shaderSource, CompilerParameters com public abstract TaskOrResult Compile( ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, - CompilerParameters compilerParameters); + CompilerParameters compilerParameters, + ObjectId mixinObjectId); public static readonly string DefaultSourceShaderFolder = "shaders"; diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index ad4bbcfb75..df97b9d103 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -61,11 +61,8 @@ public override void ResetCache(HashSet modifiedShaders) } } - public override TaskOrResult Compile(ShaderMixinSource mixin, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters) + public override TaskOrResult Compile(ShaderMixinSource mixin, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) { - var usedParameters = compilerParameters; - var mixinObjectId = ShaderMixinObjectId.Compute(mixin, usedParameters.EffectParameters); - // Final url of the compiled bytecode var compiledUrl = string.Format("{0}/{1}", CompiledShadersKey, mixinObjectId); @@ -85,7 +82,7 @@ public override TaskOrResult Compile(ShaderMixinSo if (Compiler is NullEffectCompiler && bytecode.Key == null) { var stringBuilder = new StringBuilder(); - stringBuilder.AppendFormat("Unable to find compiled shaders [{0}] for mixin [{1}] with parameters [{2}]", compiledUrl, mixin, usedParameters.ToStringPermutationsDetailed()); + stringBuilder.AppendFormat("Unable to find compiled shaders [{0}] for mixin [{1}] with parameters [{2}]", compiledUrl, mixin, compilerParameters.ToStringPermutationsDetailed()); Log.Error(stringBuilder.ToString()); throw new InvalidOperationException(stringBuilder.ToString()); } @@ -106,12 +103,39 @@ public override TaskOrResult Compile(ShaderMixinSo if (bytecode.Key != null) { - // If we successfully retrieved it from cache, add it to index map so that it won't be collected and available for faster lookup + // If we successfully retrieved it from cache, add it to index map so that it won't be collected and available for faster lookup database.ContentIndexMap[compiledUrl] = newBytecodeId; } } } } + + // ------------------------------------------------------------------------------------------------------------ + // 2.5) Try to load from application cache (DynamicCache entries) + // ------------------------------------------------------------------------------------------------------------ + if (bytecode.Key == null) + { + var appCachePath = GetAppCachePath(mixin.Name, mixinObjectId); + if (VirtualFileSystem.ApplicationCache.FileExists(appCachePath)) + { + try + { + using var stream = VirtualFileSystem.ApplicationCache.OpenStream( + appCachePath, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read); + var loadedBytecode = EffectBytecode.FromStream(stream); + if (loadedBytecode != null && !IsBytecodeObsolete(loadedBytecode)) + { + bytecode = new KeyValuePair( + loadedBytecode, EffectBytecodeCacheLoadSource.DynamicCache); + bytecodes[loadedBytecode.ComputeId()] = bytecode; + } + } + catch (Exception ex) + { + Log.Warning($"Failed to load effect bytecode from application cache '{appCachePath}': {ex.Message}"); + } + } + } } if (bytecode.Key != null) @@ -155,7 +179,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree var effectLog = GlobalLogger.GetLogger("EffectCompilerCache"); // Note: this compiler is expected to not be async and directly write stuff in localLogger - var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters).WaitForResult(); + var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters, mixinObjectId).WaitForResult(); compiledShader.CompilationLog.CopyTo(log); // If there are any errors, return immediately @@ -176,7 +200,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree // Check if we really need to store the bytecode lock (bytecodes) { - // Using custom serialization to the database to store an object with a custom id + // Using custom serialization to store the bytecode // TODO: Check if we really need to write the bytecode everytime even if id is not changed var memoryStream = new MemoryStream(); compiledShader.Bytecode.WriteTo(memoryStream); @@ -186,14 +210,37 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree writer.Write(CurrentCache); memoryStream.Position = 0; - database.ObjectDatabase.Write(memoryStream, newBytecodeId, true); - database.ContentIndexMap[compiledUrl] = newBytecodeId; - // Save bytecode Id to the database cache as well - memoryStream.SetLength(0); - memoryStream.Write((byte[])newBytecodeId, 0, ObjectId.HashSize); - memoryStream.Position = 0; - database.ObjectDatabase.Write(memoryStream, mixinObjectId, true); + if (CurrentCache == EffectBytecodeCacheLoadSource.DynamicCache) + { + // Persist to ApplicationCache (file-based, no ObjectDatabase index needed) + var appCachePath = GetAppCachePath(mixinTree.Name, mixinObjectId); + try + { + var dir = Path.GetDirectoryName(appCachePath)!; + if (!string.IsNullOrEmpty(dir) && !VirtualFileSystem.ApplicationCache.DirectoryExists(dir)) + VirtualFileSystem.ApplicationCache.CreateDirectory(dir); + using var appStream = VirtualFileSystem.ApplicationCache.OpenStream( + appCachePath, VirtualFileMode.Create, VirtualFileAccess.Write); + memoryStream.CopyTo(appStream); + } + catch (Exception ex) + { + Log.Warning($"Failed to save effect bytecode to application cache '{appCachePath}': {ex.Message}"); + } + } + else + { + // StartupCache: persist to DatabaseFileProvider + database.ObjectDatabase.Write(memoryStream, newBytecodeId, true); + database.ContentIndexMap[compiledUrl] = newBytecodeId; + + // Save bytecode Id to the database cache as well + memoryStream.SetLength(0); + memoryStream.Write((byte[])newBytecodeId, 0, ObjectId.HashSize); + memoryStream.Position = 0; + database.ObjectDatabase.Write(memoryStream, mixinObjectId, true); + } if (!bytecodes.ContainsKey(newBytecodeId)) { @@ -290,5 +337,19 @@ private bool IsBytecodeObsolete(EffectBytecode bytecode) } return false; } + + public static string GetEffectCacheDirectory(string mixinName) + => $"effects/{SanitizeMixinName(mixinName)}"; + + public static string GetAppCachePath(string mixinName, ObjectId mixinObjectId) + => $"{GetEffectCacheDirectory(mixinName)}/{mixinObjectId}"; + + public static string SanitizeMixinName(string name) + { + var sb = new StringBuilder(name.Length); + foreach (char c in name) + sb.Append(char.IsLetterOrDigit(c) || c == '.' || c == '-' || c == '_' ? c : '_'); + return sb.ToString(); + } } } diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs index 3093fb64fd..e5b16f996e 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs @@ -50,9 +50,9 @@ public override void ResetCache(HashSet modifiedShaders) compiler.ResetCache(modifiedShaders); } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters = null) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) { - return compiler.Compile(mixinTree, effectParameters, compilerParameters); + return compiler.Compile(mixinTree, effectParameters, compilerParameters, mixinObjectId); } } } diff --git a/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs b/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs index 76e21fc235..4774f16a88 100644 --- a/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs +++ b/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs @@ -29,7 +29,7 @@ public override ObjectId GetShaderSourceHash(string type) public override IVirtualFileProvider FileProvider { get; set; } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters = null) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) { throw new NotSupportedException("Shader Compilation is not allowed at run time on this platform."); } diff --git a/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs b/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs index 06692a46e5..03d135826b 100644 --- a/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs +++ b/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs @@ -11,6 +11,7 @@ using Stride.Assets.Effect; using Stride.ConnectionRouter; using Stride.Engine.Network; +using Stride.Shaders; using Stride.Shaders.Compiler; using Stride.Shaders.Compiler.Internals; @@ -103,7 +104,8 @@ private static async Task ShaderCompilerRequestHandler(SocketMessageLayer socket Console.WriteLine($"Compiling shader: {remoteEffectCompilerEffectRequest.MixinTree.Name}"); // A shader has been requested, compile it (asynchronously)! - var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters, null).AwaitResult(); + var mixinObjectId = ShaderMixinObjectId.Compute(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters); + var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters, null, mixinObjectId).AwaitResult(); // Send compiled shader await socketMessageLayer.Send(new RemoteEffectCompilerEffectAnswer From 8a26338b02f9be6ff22c9675e212868ace8464ea Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 16:51:30 +0900 Subject: [PATCH 0902/1182] SDSL: handle matrices in arithmetic operations --- .../Spirv/Building/Builder.Expressions.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index d232505eb8..687c6927e9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -283,6 +283,24 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv leftType = context.ReverseTypes[left.TypeId]; rightType = context.ReverseTypes[right.TypeId]; + // SPIR-V arithmetic ops (OpFAdd, OpFSub, OpFMul, etc.) only accept scalar/vector types. + // For matrices, decompose into column vectors, apply the op per-column, then reconstruct. + if (leftType is MatrixType matType) + { + if (op is not (Operator.Plus or Operator.Minus or Operator.Mul or Operator.Div)) + throw new InvalidOperationException($"Operator '{op}' is not supported on matrix types"); + + var columnTypeId = context.GetOrRegister(new VectorType(matType.BaseType, matType.Rows)); + Span columnResults = stackalloc int[matType.Columns]; + for (int i = 0; i < matType.Columns; i++) + { + var colLeft = Buffer.Insert(Position++, new OpCompositeExtract(columnTypeId, context.Bound++, left.Id, [i])).ToValue(); + var colRight = Buffer.Insert(Position++, new OpCompositeExtract(columnTypeId, context.Bound++, right.Id, [i])).ToValue(); + columnResults[i] = BinaryOperation(table, context, colLeft, op, colRight, info).Id; + } + return Buffer.Insert(Position++, new OpCompositeConstruct(resultTypeId, resultId, [.. columnResults])).ToValue(); + } + var leftElementType = leftType.GetElementType(); var rightElementType = rightType.GetElementType(); From 8bdcfe6eddaad8b72c111500b4e001a6c7f43c58 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 18:21:30 +0900 Subject: [PATCH 0903/1182] SDSL: added support for switch/case --- .../Parsing/SDSL/AST/Statements.Control.cs | 99 +++++++++++++++ .../StatementParsers.Switch.cs | 114 ++++++++++++++++++ .../StatementParsers/StatementParsers.cs | 8 ++ .../Spirv/Building/Builder.Flow.cs | 2 + .../Stride.Shaders.Parsers/Spirv/Tools/Dis.cs | 18 +++ .../assets/SDSL/RenderTests/Switch.sdsl | 37 ++++++ 6 files changed, 278 insertions(+) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs create mode 100644 sources/shaders/assets/SDSL/RenderTests/Switch.sdsl diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs index e11629e748..5a6d1d71ba 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Control.cs @@ -4,6 +4,7 @@ using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -149,3 +150,101 @@ public override string ToString() return $"else {Body}"; } } + + +public partial class SwitchStatement(Expression selector, TextLocation info) : Flow(info) +{ + public Expression Selector { get; set; } = selector; + public List Sections { get; set; } = []; + + public override void ProcessSymbol(SymbolTable table) + { + Selector.ProcessSymbol(table); + foreach (var section in Sections) + { + foreach (var label in section.Labels) + { + if (label is CaseLabel caseLabel) + caseLabel.Value.ProcessSymbol(table); + } + foreach (var stmt in section.Statements) + stmt.ProcessSymbol(table); + } + } + + public override void Compile(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + + // Compile selector (must be integer scalar) + var selectorValue = Selector.CompileAsValue(table, compiler); + if (Selector.ValueType is not ScalarType st || !st.IsInteger()) + table.AddError(new(Selector.Info, "switch selector must evaluate to an integer scalar")); + + // Pre-allocate block IDs: one per section + merge block + var mergeBlock = context.Bound++; + var sectionBlockIds = new int[Sections.Count]; + for (int i = 0; i < Sections.Count; i++) + sectionBlockIds[i] = context.Bound++; + + // Set up escape blocks so break targets the merge block + var previousEscapeBlocks = builder.CurrentEscapeBlocks; + builder.CurrentEscapeBlocks = new SpirvBuilder.EscapeBlocks(mergeBlock, mergeBlock); + + // Build (literal, blockId) pairs and find default block + int defaultBlockId = mergeBlock; + var casePairs = new List<(int, int)>(); + for (int i = 0; i < Sections.Count; i++) + { + foreach (var label in Sections[i].Labels) + { + if (label is DefaultLabel) + defaultBlockId = sectionBlockIds[i]; + else if (label is CaseLabel caseLabel && caseLabel.Value is IntegerLiteral intLit) + casePairs.Add(((int)intLit.Value, sectionBlockIds[i])); + else + table.AddError(new(label.Info, "case label must be an integer literal")); + } + } + + // Emit selection merge + switch + builder.Insert(new OpSelectionMerge(mergeBlock, Specification.SelectionControlMask.None)); + Span<(int, int)> pairsSpan = casePairs.ToArray(); + builder.Insert(new OpSwitch(selectorValue.Id, defaultBlockId, new LiteralArray<(int, int)>(pairsSpan))); + + // Compile each section's block + for (int i = 0; i < Sections.Count; i++) + { + builder.CreateBlock(context, sectionBlockIds[i], $"switch_case_{builder.SwitchBlockCount}_{i}"); + foreach (var stmt in Sections[i].Statements) + stmt.Compile(table, compiler); + if (!SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) + builder.Insert(new OpBranch(mergeBlock)); + } + + // Merge block + builder.CreateBlock(context, mergeBlock, $"switch_merge_{builder.SwitchBlockCount}"); + + builder.SwitchBlockCount++; + builder.CurrentEscapeBlocks = previousEscapeBlocks; + } +} + +public class SwitchSection(List labels, List statements, TextLocation info) +{ + public TextLocation Info { get; set; } = info; + public List Labels { get; set; } = labels; + public List Statements { get; set; } = statements; +} + +public abstract class SwitchLabel(TextLocation info) +{ + public TextLocation Info { get; set; } = info; +} + +public class CaseLabel(Expression value, TextLocation info) : SwitchLabel(info) +{ + public Expression Value { get; set; } = value; +} + +public class DefaultLabel(TextLocation info) : SwitchLabel(info); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs new file mode 100644 index 0000000000..42363e32ff --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs @@ -0,0 +1,114 @@ +using Stride.Shaders.Parsing.SDSL.AST; + +namespace Stride.Shaders.Parsing.SDSL; + + +public record struct SwitchStatementParser : IParser +{ + public readonly bool Match(ref TScanner scanner, ParseResult result, out SwitchStatement parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if ( + Tokens.Literal("switch", ref scanner, advance: true) + && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var selector, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(')', ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char('{', ref scanner, advance: true) + ) + { + parsed = new(selector, scanner[position..scanner.Position]); + Parsers.Spaces0(ref scanner, result, out _); + + while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) + { + if (SwitchSection(ref scanner, result, out var section)) + { + parsed.Sections.Add(section); + Parsers.Spaces0(ref scanner, result, out _); + } + else + return Parsers.Exit(ref scanner, result, out parsed, position, new("Expected case or default label", scanner[scanner.Position], scanner.Memory)); + } + + parsed.Info = scanner[position..scanner.Position]; + return true; + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } + + public static bool SwitchSection(ref TScanner scanner, ParseResult result, out SwitchSection parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + var labels = new List(); + + // Parse one or more labels (case or default) + while (SwitchLabel(ref scanner, result, out var label)) + { + labels.Add(label); + Parsers.Spaces0(ref scanner, result, out _); + } + + if (labels.Count == 0) + return false; + + // Parse statements until next case/default/closing brace + var statements = new List(); + while ( + !scanner.IsEof + && !Tokens.Literal("case", ref scanner) + && !Tokens.Literal("default", ref scanner) + && !Tokens.Char('}', ref scanner)) + { + if (StatementParsers.Statement(ref scanner, result, out var statement)) + { + statements.Add(statement); + Parsers.Spaces0(ref scanner, result, out _); + } + else + return Parsers.Exit(ref scanner, result, out parsed!, position, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)); + } + + parsed = new SwitchSection(labels, statements, scanner[position..scanner.Position]); + return true; + } + + public static bool SwitchLabel(ref TScanner scanner, ParseResult result, out SwitchLabel parsed, ParseError? orError = null) + where TScanner : struct, IScanner + { + parsed = null!; + var position = scanner.Position; + + if ( + Tokens.Literal("case", ref scanner, advance: true) + && Parsers.Spaces1(ref scanner, result, out _) + && ExpressionParser.Expression(ref scanner, result, out var value) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(':', ref scanner, advance: true) + ) + { + parsed = new CaseLabel(value, scanner[position..scanner.Position]); + return true; + } + + scanner.Position = position; + + if ( + Tokens.Literal("default", ref scanner, advance: true) + && Parsers.Spaces0(ref scanner, result, out _) + && Tokens.Char(':', ref scanner, advance: true) + ) + { + parsed = new DefaultLabel(scanner[position..scanner.Position]); + return true; + } + + scanner.Position = position; + return false; + } +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 2180423771..e322b3de09 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -17,6 +17,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = cond; return true; } + else if (Switch(ref scanner, result, out var switchStmt)) + { + parsed = switchStmt; + return true; + } else if (Flow(ref scanner, result, out var flow)) { parsed = flow; @@ -110,6 +115,9 @@ internal static bool DeclaredVarAssign(ref TScanner scanner, ParseResu internal static bool Controls(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ControlsParser().Match(ref scanner, result, out parsed, orError); + internal static bool Switch(ref TScanner scanner, ParseResult result, out SwitchStatement parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => new SwitchStatementParser().Match(ref scanner, result, out parsed, orError); internal static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs index d191c44a67..c9143a8b2f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Flow.cs @@ -15,6 +15,8 @@ public record struct EscapeBlocks(int ContinueBlock, int MergeBlock); public int WhileBlockCount { get; internal set; } = 0; + public int SwitchBlockCount { get; internal set; } = 0; + public EscapeBlocks? CurrentEscapeBlocks { get; internal set; } public static bool IsFunctionTermination(Op op) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs index b9ec7d66fe..4f11e75364 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs @@ -258,6 +258,23 @@ readonly DisWriter AppendResultId(int? id = null) } + private DisWriter AppendPairLiteralIntegerIdRefs(SpvOperand operand) + { + var count = operand.Quantifier switch + { + OperandQuantifier.One => 1, + OperandQuantifier.ZeroOrMore => operand.Words.Length / 2, + OperandQuantifier.ZeroOrOne => operand.Words.Length == 0 ? 0 : 1, + }; + + for (int i = 0; i < count; ++i) + { + AppendLiteralNumber(operand.Words[i * 2]); + AppendIdRef(operand.Words[i * 2 + 1]); + } + return this; + } + private DisWriter AppendPairIdRefLiteralIntegers(SpvOperand operand) { var count = operand.Quantifier switch @@ -369,6 +386,7 @@ or OperandKind.IdMemorySemantics _ => throw new NotImplementedException("Unsupported image operands quantifier " + operand.Quantifier + " with length " + operand.Words.Length) }, OperandKind.PairIdRefLiteralInteger => AppendPairIdRefLiteralIntegers(operand), + OperandKind.PairLiteralIntegerIdRef => AppendPairLiteralIntegerIdRefs(operand), }; } AppendLine(""); diff --git a/sources/shaders/assets/SDSL/RenderTests/Switch.sdsl b/sources/shaders/assets/SDSL/RenderTests/Switch.sdsl new file mode 100644 index 0000000000..e62f90ecd6 --- /dev/null +++ b/sources/shaders/assets/SDSL/RenderTests/Switch.sdsl @@ -0,0 +1,37 @@ +// PSMain(ExpectedResult=#FFFFFFFF, cbuffer.Test=(Test1=1)) +// PSMain(ExpectedResult=#7F7F7F7F, cbuffer.Test=(Test1=2)) +// PSMain(ExpectedResult=#3F3F3F3F, cbuffer.Test=(Test1=3)) +// PSMain(ExpectedResult=#00000000, cbuffer.Test=(Test1=99)) + +namespace Stride.Shaders.Tests; + +shader Switch +{ + stream float4 ColorTarget : SV_Target0; + + cbuffer Test + { + int Test1; + } + + void PSMain() + { + float v = 0.0; + switch (Test1) + { + case 1: + v = 1.0; + break; + case 2: + v = 127.0 / 255.0; + break; + case 3: + v = 63.0 / 255.0; + break; + default: + v = 0.0; + break; + } + streams.ColorTarget = float4(v, v, v, v); + } +} From 80be852bc578b4c438bf258ae0d2a62df7e4af3f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 22:01:14 +0900 Subject: [PATCH 0904/1182] SDSL: add scope for for() variable declarations --- .../Parsing/SDSL/AST/Statements.Flow.cs | 5 +++++ sources/shaders/assets/SDSL/RenderTests/ForContinue.sdsl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index 57cfa83165..0c9b70aa53 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -192,20 +192,24 @@ public partial class For(Statement initializer, Expression cond, List public Statement Body { get; set; } = body; public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; + public SymbolFrame SymbolFrame { get; set; } public override void ProcessSymbol(SymbolTable table) { + table.Push(); Initializer.ProcessSymbol(table); Condition.ProcessSymbol(table); Body.ProcessSymbol(table); foreach (var update in Update) update.ProcessSymbol(table); + SymbolFrame = table.Pop(); } public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; + table.Push(SymbolFrame); Initializer.Compile(table, compiler); // Prepare blocks ids @@ -248,6 +252,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) builder.ForBlockCount++; builder.CurrentEscapeBlocks = previousEscapeBlocks; + table.Pop(); } public override string ToString() diff --git a/sources/shaders/assets/SDSL/RenderTests/ForContinue.sdsl b/sources/shaders/assets/SDSL/RenderTests/ForContinue.sdsl index 8337870ba1..974c7c2ca9 100644 --- a/sources/shaders/assets/SDSL/RenderTests/ForContinue.sdsl +++ b/sources/shaders/assets/SDSL/RenderTests/ForContinue.sdsl @@ -20,7 +20,7 @@ shader ForContinue continue; streams.ColorTarget += float4(1.0, 0.0, 0.0, 0.0) / 255.0; } - for (i = 0; i < 10; ++i) + for (int i = 0; i < 10; ++i) { if (i % 2 == 1) continue; From be0fd772f74337a0b31e27c30a25389b3c1096c7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 22:17:40 +0900 Subject: [PATCH 0905/1182] SDSL: Added parsing for literal with scientific notation (exponent "e") --- .../SDSL/Parsers/LiteralParsers/NumberParsers.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index 0ebb2d5a41..cc7dce21f9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -70,7 +70,7 @@ public static bool Float(ref TScanner scanner, ParseResult result, out return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); while (Tokens.Digit(ref scanner, advance: true)) ; } - else if (Tokens.FloatSuffix(ref scanner, out _) || Tokens.Char('e', ref scanner)) { } + else if (Tokens.FloatSuffix(ref scanner, out _) || Tokens.Char('e', ref scanner) || Tokens.Char('E', ref scanner)) { } else return Parsers.Exit(ref scanner, result, out parsed, position); } else if (Tokens.Digit(ref scanner, 0, advance: true)) @@ -88,12 +88,14 @@ public static bool Float(ref TScanner scanner, ParseResult result, out var value = double.Parse(scanner.Span[position..scanner.Position], CultureInfo.InvariantCulture); int? exponent = null; - if (Tokens.Char('e', ref scanner, advance: true)) + if (Tokens.Char('e', ref scanner, advance: true) || Tokens.Char('E', ref scanner, advance: true)) { var signed = Tokens.AnyOf(["+", "-"], ref scanner, out var matched, advance: true); - if (Integer(ref scanner, result, out var exp)) + var expStart = scanner.Position; + if (Tokens.Digit(ref scanner, advance: true)) { - exponent = (int)((IntegerLiteral)exp).Value; + while (Tokens.Digit(ref scanner, advance: true)) ; + exponent = int.Parse(scanner.Span[expStart..scanner.Position], CultureInfo.InvariantCulture); if (signed && matched == "-") exponent = -exponent; } From f482e42a2ba7459a61e00eb3bdfa863958f32ada Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 23:17:54 +0900 Subject: [PATCH 0906/1182] SDSL: Added AssignExpression --- .../Parsing/SDSL/AST/Expression.cs | 49 +++++++++++++++++++ .../ExpressionParsers/BinaryParsers.cs | 34 ++++++++++++- .../Parsers/LiteralParsers/LiteralParsers.cs | 9 +++- 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 276b47a395..10a0e765be 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -77,6 +77,55 @@ public partial class EmptyExpression(TextLocation info) : Expression(info) public override string ToString() => string.Empty; } +public partial class AssignExpression(Expression target, AssignOperator op, Expression value, TextLocation info) : Expression(info) +{ + public Expression Target { get; set; } = target; + public AssignOperator Operator { get; set; } = op; + public Expression Value { get; set; } = value; + + public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) + { + Target.ProcessSymbol(table); + Value.ProcessSymbol(table); + Type = Target.Type; + } + + public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) + { + var (builder, context) = compiler; + var targetVal = Target.Compile(table, compiler); + var source = Value.CompileAsValue(table, compiler); + + if (Operator != AssignOperator.Simple) + { + var binaryOperator = Operator switch + { + AssignOperator.Plus => Core.Operator.Plus, + AssignOperator.Minus => Core.Operator.Minus, + AssignOperator.Mul => Core.Operator.Mul, + AssignOperator.Div => Core.Operator.Div, + AssignOperator.Mod => Core.Operator.Mod, + AssignOperator.RightShift => Core.Operator.RightShift, + AssignOperator.LeftShift => Core.Operator.LeftShift, + AssignOperator.AND => Core.Operator.AND, + AssignOperator.OR => Core.Operator.OR, + AssignOperator.XOR => Core.Operator.XOR, + }; + + var left = builder.AsValue(context, targetVal); + source = builder.BinaryOperation(table, context, left, binaryOperator, source, info); + } + + var resultType = targetVal.GetValueType(context); + source = builder.Convert(context, source, resultType); + Target.SetValue(table, compiler, source); + + return targetVal; + } + + public override string ToString() => $"{Target} {Operator.ToAssignSymbol()} {Value}"; +} + public partial class ParenthesisExpression(Expression expression, TextLocation info) : Expression(info) { public Expression Expression { get; set; } = expression; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index ef51adea9b..32c6e225b6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -13,11 +13,43 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o where TScanner : struct, IScanner { var position = scanner.Position; - if (Ternary(ref scanner, result, out parsed)) + if (Assignment(ref scanner, result, out parsed)) return true; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + /// + /// assignment ::= ternary ( assign_op assignment )? + /// Right-associative: a = b = c parses as a = (b = c) + /// + public static bool Assignment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Ternary(ref scanner, result, out parsed)) + { + var pos2 = scanner.Position; + Parsers.Spaces0(ref scanner, result, out _); + if (LiteralsParser.AssignOperators(ref scanner, null!, out var op)) + { + Parsers.Spaces0(ref scanner, result, out _); + // Right-associative: recurse into Assignment for the RHS + if (Assignment(ref scanner, result, out var rhs)) + { + parsed = new AssignExpression(parsed, op, rhs, scanner[position..scanner.Position]); + return true; + } + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)); + } + else + { + scanner.Position = pos2; + return true; + } + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } + /// /// add ::= mul ( spaces '+' spaces add)* /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 487d951241..5985bcff97 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -249,15 +249,22 @@ public static bool AssignOperators(ref TScanner scanner, ParseResult r where TScanner : struct, IScanner { op = AssignOperator.NOp; + var position = scanner.Position; if ( Tokens.AnyOf( - ["=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "<<=", ">>="], + ["<<=", ">>=", "+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=", "="], ref scanner, out var matched, advance: true ) ) { + // Guard: "=" must not be followed by "=" (that would be "==") + if (matched == "=" && Tokens.Char('=', ref scanner)) + { + scanner.Position = position; + return false; + } op = matched.ToAssignOperator(); return true; } From 83d5ac25ae927b8952dd4aaeaf27f264875f3a5d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 10 Mar 2026 23:18:19 +0900 Subject: [PATCH 0907/1182] SDSL: removed VariableAssign and Assign --- .../EffectCodeWriter.cs | 10 +-- .../Parsers/EffectStatementParsers.Flow.cs | 13 ---- .../SDFX/Parsers/EffectStatementParsers.cs | 17 +---- .../Parsing/SDFX/ShaderWriter.cs | 21 +---- .../Parsing/SDSL/AST/Statements.cs | 73 ------------------ .../ExpressionParsers/BinaryParsers.cs | 29 +++++-- .../StatementParsers/StatementParsers.Flow.cs | 13 ---- .../StatementParsers/StatementParsers.cs | 76 +------------------ 8 files changed, 34 insertions(+), 218 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index 67e41cb541..84734abe0d 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -294,21 +294,19 @@ public override void VisitShaderNamespace(ShaderNamespace shaderNamespace) CloseBrace(); } - public override void VisitAssign(Assign assign) + public override void VisitAssignExpression(AssignExpression assignExpression) { - if (assign.Variables.Count == 1 - && assign.Variables[0].Value is not null - && TryParameters(assign.Variables[0].Variable, out var typeTarget, out var typeMember, out var extraPath)) + if (TryParameters(assignExpression.Target, out var typeTarget, out var typeMember, out var extraPath)) { Write("context.SetParam(").Write(typeTarget).Write(".").Write(typeMember.ToString()).Write(", "); - VisitNode(assign.Variables[0].Value); + VisitNode(assignExpression.Value); Write(")"); if (extraPath != null) Write(".").Write(extraPath); } else { - base.VisitAssign(assign); + base.VisitAssignExpression(assignExpression); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs index 34704ad5ab..babd37e310 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs @@ -107,19 +107,6 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes where TScanner : struct, IScanner { var position = scanner.Position; - if ( - PostfixParser.Postfix(ref scanner, result, out var variable) - && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) - ) - { - parsed = new Assign(scanner[position..scanner.Position]) - { - Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] - }; - return true; - } - scanner.Position = position; if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs index 04377315ee..d9b663656a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -147,9 +147,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { if (mixinType is Specification.MixinKindSDFX.ComposeSet or Specification.MixinKindSDFX.Child or Specification.MixinKindSDFX.Macro - && statement is Assign { Variables: [{ Value: { } value, Variable: Identifier variable }] } assign) + && statement is ExpressionStatement { Expression: AssignExpression { Target: Identifier variable, Value: { } value } assign }) { - if (assign.Variables[0].Operator == AssignOperator.Plus && mixinType == Specification.MixinKindSDFX.ComposeSet) + if (assign.Operator == AssignOperator.Plus && mixinType == Specification.MixinKindSDFX.ComposeSet) mixinType = Specification.MixinKindSDFX.ComposeAdd; parsed = new Mixin(mixinType, variable, value, scanner[position..scanner.Position]); } @@ -171,19 +171,6 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes where TScanner : struct, IScanner { var position = scanner.Position; - if ( - PostfixParser.Postfix(ref scanner, result, out var variable) - && SDSL.Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) - && SDSL.Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) - ) - { - parsed = new Assign(scanner[position..scanner.Position]) - { - Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] - }; - return true; - } - scanner.Position = position; if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs index d83c97ec5b..8864a4cf91 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/ShaderWriter.cs @@ -383,14 +383,11 @@ public override void VisitDeclare(Declare declare) } } - public override void VisitVariableAssign(VariableAssign variableAssign) + public override void VisitAssignExpression(AssignExpression assignExpression) { - VisitNode(variableAssign.Variable); - if (variableAssign.Value != null) - { - WriteSpace().Write(variableAssign.Operator?.ToAssignSymbol() ?? "=").WriteSpace(); - VisitNode(variableAssign.Value); - } + VisitNode(assignExpression.Target); + WriteSpace().Write(assignExpression.Operator.ToAssignSymbol()).WriteSpace(); + VisitNode(assignExpression.Value); } public override void VisitDeclaredVariableAssign(DeclaredVariableAssign declaredVariableAssign) @@ -409,16 +406,6 @@ public override void VisitDeclaredVariableAssign(DeclaredVariableAssign declared WriteLine(";"); } - public override void VisitAssign(Assign assign) - { - for (var i = 0; i < assign.Variables.Count; i++) - { - VisitNode(assign.Variables[i]); - if (i < assign.Variables.Count - 1) Write(",").WriteSpace(); - } - WriteLine(";"); - } - public override void VisitShaderClass(ShaderClass shaderClass) { Write("shader").WriteSpace(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index bcb17a4800..a3b595f166 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -82,24 +82,6 @@ public abstract class Declaration(TypeName typename, TextLocation info) : Statem public TypeName TypeName { get; set; } = typename; } -public partial class VariableAssign(Expression variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) -{ - public Expression Variable { get; set; } = variable; - public AssignOperator? Operator { get; set; } = op; - public Expression? Value { get; set; } = value; - public bool IsConst { get; set; } = isConst; - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - throw new NotImplementedException(); - } - public override string ToString() - => Value switch - { - null => Variable.ToString() ?? "", - Expression v => $"{Variable} {Operator?.ToAssignSymbol()} {v}" - }; -} public partial class DeclaredVariableAssign(Identifier variable, bool isConst, TextLocation info, AssignOperator? op = null, Expression? value = null) : Statement(info) { public Identifier Variable { get; set; } = variable; @@ -221,61 +203,6 @@ public override string ToString() } } -public partial class Assign(TextLocation info) : Statement(info) -{ - public List Variables { get; set; } = []; - - public override void ProcessSymbol(SymbolTable table) - { - foreach (var variable in Variables) - { - variable.Variable.ProcessSymbol(table); - variable.Value!.ProcessSymbol(table); - } - } - - public override void Compile(SymbolTable table, CompilerUnit compiler) - { - var (builder, context) = compiler; - foreach (var variable in Variables) - { - var target = variable.Variable.Compile(table, compiler); - var source = variable.Value!.CompileAsValue(table, compiler); - - if (variable.Operator != AssignOperator.Simple) - { - var binaryOperator = (variable.Operator) switch - { - AssignOperator.Plus => Operator.Plus, - AssignOperator.Minus => Operator.Minus, - AssignOperator.Mul => Operator.Mul, - AssignOperator.Div => Operator.Div, - AssignOperator.Mod => Operator.Mod, - AssignOperator.RightShift => Operator.RightShift, - AssignOperator.LeftShift => Operator.LeftShift, - AssignOperator.AND => Operator.AND, - AssignOperator.OR => Operator.OR, - AssignOperator.XOR => Operator.XOR, - }; - - var left = builder.AsValue(context, target); - var right = builder.AsValue(context, source); - - source = builder.BinaryOperation(table, context, left, binaryOperator, right, info); - } - - // Make sure to convert to proper type - var resultType = target.GetValueType(context); - source = builder.Convert(context, source, resultType); - - variable.Variable.SetValue(table, compiler, source); - } - } - public override string ToString() - { - return string.Join(", ", Variables.Select(x => x.ToString())) + ";"; - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 32c6e225b6..099cf495a5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -75,7 +75,10 @@ public static bool Add(ref TScanner scanner, ParseResult result, out E else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, "+-", out op, withSpaces: true, advance: true)); + while ( + !Parsers.FollowedByAny(ref scanner, ["+=", "-="], out _, withSpaces: true) + && Parsers.FollowedByAny(ref scanner, "+-", out op, withSpaces: true, advance: true) + ); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -105,7 +108,10 @@ public static bool Mul(ref TScanner scanner, ParseResult result, out E else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, "*/%", out op, withSpaces: true, advance: true)); + while ( + !Parsers.FollowedByAny(ref scanner, ["*=", "/=", "%="], out _, withSpaces: true) + && Parsers.FollowedByAny(ref scanner, "*/%", out op, withSpaces: true, advance: true) + ); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -135,7 +141,10 @@ public static bool Shift(ref TScanner scanner, ParseResult result, out else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, [">>", "<<"], out op, withSpaces: true, advance: true)); + while ( + !Parsers.FollowedByAny(ref scanner, [">>=", "<<="], out _, withSpaces: true) + && Parsers.FollowedByAny(ref scanner, [">>", "<<"], out op, withSpaces: true, advance: true) + ); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -166,7 +175,10 @@ public static bool Relation(ref TScanner scanner, ParseResult result, } Parsers.Spaces0(ref scanner, result, out _); } - while (Parsers.FollowedByAny(ref scanner, ["<=", ">=", "<", ">"], out op, withSpaces: true, advance: true)); + while ( + !Parsers.FollowedByAny(ref scanner, ["<<=", ">>="], out _, withSpaces: true) + && Parsers.FollowedByAny(ref scanner, ["<=", ">=", "<", ">"], out op, withSpaces: true, advance: true) + ); if (parsed is not null) return true; @@ -228,7 +240,7 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out } } while ( - !Parsers.FollowedBy(ref scanner, Tokens.Literal("&&"), withSpaces: true) + !Parsers.FollowedByAny(ref scanner, ["&&", "&="], out _, withSpaces: true) && Parsers.FollowedByAny(ref scanner, ["&"], out op, advance: true) ); if (parsed is not null) @@ -263,7 +275,7 @@ public static bool BOr(ref TScanner scanner, ParseResult result, out E } } while ( - !Parsers.FollowedBy(ref scanner, Tokens.Literal("||"), withSpaces: true) + !Parsers.FollowedByAny(ref scanner, ["||", "|="], out _, withSpaces: true) && Parsers.FollowedByAny(ref scanner, ["|"], out op, advance: true) ); if (parsed is not null) @@ -296,7 +308,10 @@ public static bool XOr(ref TScanner scanner, ParseResult result, out E else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, ["^"], out op, advance: true)); + while ( + !Parsers.FollowedByAny(ref scanner, ["^="], out _, withSpaces: true) + && Parsers.FollowedByAny(ref scanner, ["^"], out op, advance: true) + ); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 385c9ddd0a..7233d0a200 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -105,19 +105,6 @@ internal static bool AssignOrExpression(ref TScanner scanner, ParseRes where TScanner : struct, IScanner { var position = scanner.Position; - if ( - PostfixParser.Postfix(ref scanner, result, out var variable) - && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.AssignOperators, out AssignOperator op, withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) - ) - { - parsed = new Assign(scanner[position..scanner.Position]) - { - Variables = [new(variable, false, scanner[position..scanner.Position], op, value)] - }; - return true; - } - scanner.Position = position; if (ExpressionParser.Expression(ref scanner, result, out var expression)) { parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index e322b3de09..7bbedeb563 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -39,8 +39,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; else if (!Tokens.Char('{', ref scanner) && Expression(ref scanner, result, out parsed)) return true; - else if (!Tokens.Char('{', ref scanner) && Assignments(ref scanner, result, out parsed)) - return true; else if (Block(ref scanner, result, out parsed)) return true; return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -83,14 +81,11 @@ internal static bool Expression(ref TScanner scanner, ParseResult resu internal static bool Declare(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new DeclareStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Assignments(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new AssignmentsParser().Match(ref scanner, result, out parsed, orError); internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Assignments(ref scanner, result, out parsed, orError)) + if (Expression(ref scanner, result, out parsed, orError)) return true; else if (Declare(ref scanner, result, out parsed, orError)) return true; @@ -98,17 +93,7 @@ internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult } internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Assignments(ref scanner, result, out parsed, orError)) - return true; - else if (Expression(ref scanner, result, out parsed, orError)) - return true; - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - internal static bool VarAssign(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - => new VariableAssignParser().Match(ref scanner, result, out parsed, orError); + => Expression(ref scanner, result, out parsed, orError); internal static bool DeclaredVarAssign(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DeclaredVariableAssignParser().Match(ref scanner, result, out parsed, orError); @@ -274,41 +259,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o -public record struct VariableAssignParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out VariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if (PostfixParser.Postfix(ref scanner, result, out var p)) - { - if ( - Parsers.FollowedBy( - ref scanner, - result, - (ref TScanner s, ParseResult result, out AssignOperator op, in ParseError? orError = null) => LiteralsParser.AssignOperators(ref s, null!, out op) && Parsers.Spaces0(ref s, result, out _), - out var op, - withSpaces: true, - advance: true) - ) - { - Parsers.Spaces0(ref scanner, result, out _); - if (ExpressionParser.Expression(ref scanner, result, out var expression)) - { - parsed = new(p, false, scanner[position..scanner.Position], op, expression); - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0015, scanner[position], scanner.Memory)); - } - else - { - parsed = new(p, false, scanner[position..scanner.Position]); - return true; - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position); - } -} - public record struct DeclaredVariableAssignParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner @@ -395,25 +345,3 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } -public record struct AssignmentsParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Parsers.Repeat(ref scanner, result, StatementParsers.VarAssign, out var assigns, 1, true, ",")) - { - Parsers.Spaces0(ref scanner, result, out _); - if (Tokens.Char(';', ref scanner, advance: true)) - { - parsed = new Assign(scanner[position..scanner.Position]) - { - Variables = assigns - }; - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[scanner.Position], scanner.Memory)); - } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} From 66eb636bd63cde5f03cae40f8697a4ee5fe87b9d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 11:23:58 +0900 Subject: [PATCH 0908/1182] SDSL: Resolve cbuffer members before the cbuffer name itself --- .../Core/SymbolTypes.cs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 2d5f8a66f7..153460ade2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -617,15 +617,23 @@ private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) } var variables = CollectionsMarshal.AsSpan(Variables); + + // Pass 1: non-cbuffer variables (stream outputs, plain shader members, etc.) foreach (ref var c in variables) { - if (c.Symbol.Id.Name == name) + if (c.Symbol.Id.Name == name + && !(c.Symbol.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } pp && pp.BaseType is ConstantBufferSymbol)) { symbol = c.Symbol; return true; } + } - // For cbuffer, all their members are visible directly at the top-level without referencing the cbuffer + // Pass 2: promoted cbuffer members across all cbuffers. + // Must be a separate pass so that no cbuffer variable name (from any cbuffer) can shadow + // a promoted member from another cbuffer (cbuffer names are transparent in HLSL). + foreach (ref var c in variables) + { if (c.Symbol.Type is PointerType { StorageClass: Specification.StorageClass.Uniform } p && p.BaseType is ConstantBufferSymbol cb) { for (int index = 0; index < cb.Members.Count; index++) @@ -641,6 +649,17 @@ private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) } } + // Pass 3: cbuffer variable itself (last resort — cbuffer names are not user-accessible in HLSL, + // but may be needed internally, e.g. when the compiler resolves a cbuffer by name). + foreach (ref var c in variables) + { + if (c.Symbol.Id.Name == name) + { + symbol = c.Symbol; + return true; + } + } + symbol = default; return false; } From 3eeb2b570b938bf03b390813a6d68902d1c3ce4a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 14:11:37 +0900 Subject: [PATCH 0909/1182] SDSL: Allow SV_Position in input elements --- .../Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs index 4b7473b6fd..0a51f01b44 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/BuiltinProcessor.cs @@ -113,6 +113,8 @@ public static bool ProcessBuiltinsDecoration( (not ExecutionModel.Fragment, StreamVariableType.Output, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), (not ExecutionModel.Fragment and not ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.Position), (ExecutionModel.Fragment, StreamVariableType.Input, "SV_POSITION") => AddBuiltin(context, variable, BuiltIn.FragCoord), + // In vertex shaders, SV_POSITION as input is just a regular vertex attribute (object-space position) + (ExecutionModel.Vertex, StreamVariableType.Input, "SV_POSITION") => false, // Vertex shaders inputs (SV_InstanceID, SV_VertexID, etc.) (ExecutionModel.Vertex, StreamVariableType.Input, "SV_INSTANCEID") => AddBuiltin(context, variable, BuiltIn.InstanceIndex), (ExecutionModel.Vertex, StreamVariableType.Input, "SV_VERTEXID") => AddBuiltin(context, variable, BuiltIn.VertexIndex), From 4fcfd06a4fa458a7e6a1f8fcd226e46f04ef865c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 14:39:05 +0900 Subject: [PATCH 0910/1182] SDSL: Properly distinguish between textured types, such as Texture2D vs Texture2D --- .../Core/SymbolTypes.cs | 47 ++++++------ .../Parsing/SDSL/AST/Expression.cs | 2 +- .../SDSL/AST/IntrinsicTemplateExpander.cs | 5 +- .../Parsing/SDSL/AST/Shader.cs | 74 ++++++++++++++++--- .../Spirv/Building/Context.ExtractBuffers.cs | 25 ++++++- .../Spirv/Building/SpirvContext.Types.cs | 42 +++++++++-- .../Spirv/Processing/TypeDuplicatesRemover.cs | 45 ++++++++++- 7 files changed, 191 insertions(+), 49 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 153460ade2..86b4d87dde 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -62,10 +62,15 @@ public static bool TryGetBufferType(string name, TypeName? templateTypeName, [Ma } // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) + + // Preserves the full vector/scalar type (e.g. float2 stays float2). Defaults to float4 when no template given (HLSL default). + static SymbolType ResolveReturnType(TypeName? templateTypeName) + => templateTypeName == null ? new VectorType(ScalarType.Float, 4) : templateTypeName.Type; + + // Returns only the scalar element type — required for OpTypeImage sampled type and intrinsic base-type matching. static ScalarType ResolveScalarType(TypeName? templateTypeName) { var templateType = templateTypeName?.Type ?? ScalarType.Float; - return templateType switch { VectorType v => v.BaseType, @@ -81,24 +86,24 @@ static ScalarType ResolveScalarType(TypeName? templateTypeName) "ByteAddressBuffer" => new ByteAddressBufferType(false), "RWByteAddressBuffer" => new ByteAddressBufferType(true), - "Texture1D" => new Texture1DType(ResolveScalarType(templateTypeName)), - "Texture2D" => new Texture2DType(ResolveScalarType(templateTypeName)), - "Texture2DMS" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true }, - "Texture3D" => new Texture3DType(ResolveScalarType(templateTypeName)), - "TextureCube" => new TextureCubeType(ResolveScalarType(templateTypeName)), + "Texture1D" => new Texture1DType(ResolveReturnType(templateTypeName)), + "Texture2D" => new Texture2DType(ResolveReturnType(templateTypeName)), + "Texture2DMS" => new Texture2DType(ResolveReturnType(templateTypeName)) { Multisampled = true }, + "Texture3D" => new Texture3DType(ResolveReturnType(templateTypeName)), + "TextureCube" => new TextureCubeType(ResolveReturnType(templateTypeName)), - "Texture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, - "Texture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, - "Texture2DMSArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Multisampled = true, Arrayed = true }, - "Texture3DArray" => new Texture3DType(ResolveScalarType(templateTypeName)) { Arrayed = true }, - "TextureCubeArray" => new TextureCubeType(ResolveScalarType(templateTypeName)) { Arrayed = true }, + "Texture1DArray" => new Texture1DType(ResolveReturnType(templateTypeName)) { Arrayed = true }, + "Texture2DArray" => new Texture2DType(ResolveReturnType(templateTypeName)) { Arrayed = true }, + "Texture2DMSArray" => new Texture2DType(ResolveReturnType(templateTypeName)) { Multisampled = true, Arrayed = true }, + "Texture3DArray" => new Texture3DType(ResolveReturnType(templateTypeName)) { Arrayed = true }, + "TextureCubeArray" => new TextureCubeType(ResolveReturnType(templateTypeName)) { Arrayed = true }, - "RWTexture1D" => new Texture1DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, - "RWTexture2D" => new Texture2DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, - "RWTexture3D" => new Texture3DType(ResolveScalarType(templateTypeName)) { Sampled = 2 }, + "RWTexture1D" => new Texture1DType(ResolveReturnType(templateTypeName)) { Sampled = 2 }, + "RWTexture2D" => new Texture2DType(ResolveReturnType(templateTypeName)) { Sampled = 2 }, + "RWTexture3D" => new Texture3DType(ResolveReturnType(templateTypeName)) { Sampled = 2 }, - "RWTexture1DArray" => new Texture1DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, - "RWTexture2DArray" => new Texture2DType(ResolveScalarType(templateTypeName)) { Sampled = 2, Arrayed = true }, + "RWTexture1DArray" => new Texture1DType(ResolveReturnType(templateTypeName)) { Sampled = 2, Arrayed = true }, + "RWTexture2DArray" => new Texture2DType(ResolveReturnType(templateTypeName)) { Sampled = 2, Arrayed = true }, _ => null, }; @@ -293,26 +298,26 @@ public sealed partial record SampledImage(TextureType ImageType) : SymbolType() public override string ToString() => $"SampledImage<{ImageType}>"; } -public abstract partial record TextureType(ScalarType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() +public abstract partial record TextureType(SymbolType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() { public override string ToId() => $"Texture_{ReturnType}"; public override string ToString() => $"Texture<{ReturnType}>({Dimension}, {Depth}, {Arrayed}, {Multisampled}, {Sampled}, {Format})"; } -public sealed partial record Texture1DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture1DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim1D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture1D{(Arrayed ? "Array" : "")}<{ReturnType}>"; } -public sealed partial record Texture2DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture2DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim2D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture2D{(Multisampled ? "MS" : "")}{(Arrayed ? "Array" : "")}<{ReturnType}>"; } -public sealed partial record Texture3DType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record Texture3DType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Dim3D, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"{(Sampled == 2 ? "RW" : "")}Texture3D{(Arrayed ? "Array" : "")}<{ReturnType}>"; } -public sealed partial record TextureCubeType(ScalarType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) +public sealed partial record TextureCubeType(SymbolType ReturnType) : TextureType(ReturnType, Dim.Cube, 2, false, false, 1, ImageFormat.Unknown) { public override string ToString() => $"TextureCube{(Arrayed ? "Array" : "")}<{ReturnType}>"; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 10a0e765be..df0227d391 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -662,7 +662,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal // ImageWrite case (PointerType { BaseType: TextureType textureType }, IndexerExpression indexer): { - var resultType = new VectorType(textureType.ReturnType, 4); + var resultType = textureType.ReturnType; var image = builder.AsValue(context, lvalueBase); var imageCoordValue = ConvertTexCoord(context, builder, textureType, indexer.Index.CompileAsValue(table, compiler), ScalarType.Int); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index 049d824878..bc09e0cb75 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -3,6 +3,7 @@ using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; using SymbolType = Stride.Shaders.Core.SymbolType; namespace Stride.Shaders.Parsing.SDSL; @@ -219,7 +220,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) // Match thisType's base type parameterTypeHelper[index].BaseType = thisType switch { - TextureType t => t.ReturnType, + TextureType t => t.ReturnType.GetElementType(), BufferType b => b.BaseType, null => throw new ArgumentNullException(nameof(thisType)), _ => throw new InvalidOperationException($"Can't resolve thisType base type for {thisType}"), @@ -276,7 +277,7 @@ ParameterTypeInfo GetParameterInfo(int index) return thisType switch { null => throw new ArgumentNullException(nameof(thisType)), - TextureType t => new(t.ReturnType, new(4, null), default), + TextureType t => new(t.ReturnType.GetElementType(), new(t.ReturnType.GetElementCount(), null), default), BufferType b => new(b.BaseType, new(4, null), default), }; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 8f88ea055b..5f491e7cba 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -71,6 +71,41 @@ void RegisterName(int target, string name) context.Names.Add(target, name); } + static SymbolType? ParseTextureReturnType(string s) => s switch + { + "float" => ScalarType.Float, + "float2" => new VectorType(ScalarType.Float, 2), + "float3" => new VectorType(ScalarType.Float, 3), + "float4" => new VectorType(ScalarType.Float, 4), + "int" => ScalarType.Int, + "int2" => new VectorType(ScalarType.Int, 2), + "int3" => new VectorType(ScalarType.Int, 3), + "int4" => new VectorType(ScalarType.Int, 4), + "uint" => ScalarType.UInt, + "uint2" => new VectorType(ScalarType.UInt, 2), + "uint3" => new VectorType(ScalarType.UInt, 3), + "uint4" => new VectorType(ScalarType.UInt, 4), + _ => null, + }; + + // Pre-pass: collect UserTypeGOOGLE decorations on texture types so we can + // recover the exact ReturnType (e.g. float2) when reading OpTypeImage. + var textureReturnTypes = new Dictionary(); + for (var i = start; i < end; i++) + { + var inst = context[i]; + if (inst.Op == Op.OpDecorateString) + { + OpDecorateString dec = inst; + if (dec.Decoration == Decoration.UserTypeGOOGLE) + { + var symbolType = ParseTextureReturnType(dec.Value); + if (symbolType != null) + textureReturnTypes[dec.Target] = symbolType; + } + } + } + var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); var importedShaders = new Dictionary(); @@ -207,12 +242,25 @@ void RegisterName(int target, string name) } else { + // Prefer UserTypeGOOGLE decoration (exact ReturnType from compilation). + // Fall back to ImageFormat for RW textures, or float4 for sampled (HLSL convention). + SymbolType returnType = textureReturnTypes.TryGetValue(typeImage.ResultId, out var userType) + ? userType + : (typeImage.Sampled == 2 + ? typeImage.Imageformat switch + { + Specification.ImageFormat.Rg32f or Specification.ImageFormat.Rg32i or Specification.ImageFormat.Rg32ui => new VectorType(sampledType, 2), + Specification.ImageFormat.Rgba32f or Specification.ImageFormat.Rgba32i or Specification.ImageFormat.Rgba32ui => new VectorType(sampledType, 4), + _ => (SymbolType)sampledType, + } + : new VectorType(sampledType, 4)); + TextureType textureType = typeImage.Dim switch { - Dim.Dim1D => new Texture1DType(sampledType), - Dim.Dim2D => new Texture2DType(sampledType), - Dim.Dim3D => new Texture3DType(sampledType), - Dim.Cube => new TextureCubeType(sampledType), + Dim.Dim1D => new Texture1DType(returnType), + Dim.Dim2D => new Texture2DType(returnType), + Dim.Dim3D => new Texture3DType(returnType), + Dim.Cube => new TextureCubeType(returnType), _ => throw new NotImplementedException(), }; textureType = textureType with @@ -337,15 +385,19 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte { structTypes.Add(((StructuredType)shaderBuffers.Context.ReverseTypes[typeStructInstruction.ResultId], -1)); } - else if (i.Op == Op.OpDecorate && (OpDecorate)i is + else if (i.Op == Op.OpDecorate) { - Decoration: Decoration.FunctionParameterDefaultValueSDSL, - Target: var target, - } decorateFunctionParameters) - { - methodsDefaultParameters.Add(target, new(shaderBuffers.Context, decorateFunctionParameters.DecorationParameters.Span.ToArray())); + // OpDecorate binary layout: [header][target][decoration][params...] + // Read raw memory to avoid InitializeProperties overwrite bug when params.count > 1 + var span = i.Data.Memory.Span; + if (span.Length >= 3 && span[2] == (int)Decoration.FunctionParameterDefaultValueSDSL) + { + var target = span[1]; + var defaultIds = span[3..].ToArray(); + methodsDefaultParameters.Add(target, new(shaderBuffers.Context, defaultIds)); + } } - else if (i.Op == Op.OpDecorate && (OpDecorate)i is + if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ShaderConstantSDSL, Target: var target2, diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index 4a1ecf09fd..dcae084fd9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -41,9 +41,30 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI if (isGenericReference) i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; - // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) + // For OpTypeImage: find the UserTypeGOOGLE decoration in the source buffer so CheckForDuplicates + // can distinguish e.g. Texture2D vs Texture2D (same binary, different return type). + // IdResult is still the original source ID here because RemapIds does not remap the current instruction's own result. + string? sourceUserTypeGOOGLE = null; + if (i.Op == Specification.Op.OpTypeImage && i.Data.IdResult.HasValue) + { + var originalId = i.Data.IdResult.Value; + foreach (var inst in source) + { + if (inst.Op == Specification.Op.OpDecorateString) + { + Spirv.Core.OpDecorateString dec = inst; + if (dec.Decoration == Specification.Decoration.UserTypeGOOGLE && dec.Target == originalId) + { + sourceUserTypeGOOGLE = dec.Value; + break; + } + } + } + } + + // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, out var existingData) + && typeDuplicateInserter.CheckForDuplicates(i.Data, sourceUserTypeGOOGLE, out var existingData) && (index != lastResultIndex || desiredResultId == null)) { // Make sure this data is declared at current index, otherwise move it. diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index b25254899f..710ebc1ac2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -90,14 +90,14 @@ public int RegisterType(SymbolType type, int id) FunctionType f => RegisterFunctionType(f, id), PointerType p => RegisterPointerType(p, id), LoadedShaderSymbol s => ImportShaderType(s, id), - Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - Texture3DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, - TextureCubeType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, - t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Format, null)).IdResult, + Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, + Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, + Texture3DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, + TextureCubeType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, SamplerType st => Buffer.AddData(new OpTypeSampler(id)).IdResult, BufferType b => Buffer.AddData(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, @@ -111,6 +111,9 @@ public int RegisterType(SymbolType type, int id) // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; + if (type is TextureType texType && instruction.HasValue) + Buffer.Add(new OpDecorateString(instruction.Value, Specification.Decoration.UserTypeGOOGLE, texType.ReturnType.ToId())); + Types[type] = instruction ?? -1; ReverseTypes[instruction ?? -1] = type; return instruction ?? -1; @@ -280,4 +283,27 @@ private int RegisterPointerType(PointerType pointerType, int id) AddName(id, pointerType.ToId()); return id; } + + // Derives the SPIR-V ImageFormat for a storage (RW) texture from its return type. + // Note: 3-component float/int/uint formats don't exist in SPIR-V (no Rgb32f etc.). + private static Specification.ImageFormat GetStorageImageFormat(SymbolType returnType) + { + var scalar = returnType.GetElementType(); + int count = returnType.GetElementCount(); + return (scalar.Type, count) switch + { + (Scalar.Float, 1) => Specification.ImageFormat.R32f, + (Scalar.Float, 2) => Specification.ImageFormat.Rg32f, + (Scalar.Float, 4) => Specification.ImageFormat.Rgba32f, + (Scalar.Float, 3) => throw new NotSupportedException( + "3-component float storage textures have no SPIR-V ImageFormat equivalent. Use float4 instead."), + (Scalar.UInt, 1) => Specification.ImageFormat.R32ui, + (Scalar.UInt, 2) => Specification.ImageFormat.Rg32ui, + (Scalar.UInt, 4) => Specification.ImageFormat.Rgba32ui, + (Scalar.Int, 1) => Specification.ImageFormat.R32i, + (Scalar.Int, 2) => Specification.ImageFormat.Rg32i, + (Scalar.Int, 4) => Specification.ImageFormat.Rgba32i, + _ => Specification.ImageFormat.Unknown, + }; + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 2679fc28f8..332ad7ebb2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -45,12 +45,13 @@ public int[] FindItemsWithTypes(SpirvBuffer buffer, params Span ops) // Note: Target is only for OpName and OpMember record struct InstructionSortHelper(Op Op, int Index, OpData Data) { + public string? UserTypeGOOGLE { get; set; } public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Index: {Index}"; } - class OperationComparer(SpirvContext Context, bool UseIndices) : IComparer + class OperationComparer(SpirvContext Context, bool UseIndices, TypeDuplicateHelper? Helper = null) : IComparer { private static int RemapOp(Op op) { @@ -118,6 +119,21 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) return comparison; + + // For OpTypeImage, also compare UserTypeGOOGLE decoration to distinguish e.g. Texture2D vs Texture2D. + // x.UserTypeGOOGLE is used as an override (set on search keys that have Index=-1 and can't look up the buffer). + if (x.Op == Op.OpTypeImage && Helper != null) + { + var xUserType = x.UserTypeGOOGLE ?? (x.Index >= 0 ? Helper.FindUserTypeGOOGLE(x.Data.IdResult ?? 0) : null); + var yUserType = y.UserTypeGOOGLE ?? (y.Index >= 0 ? Helper.FindUserTypeGOOGLE(y.Data.IdResult ?? 0) : null); + // Only treat as conflicting when both sides have the decoration; null means "unknown/old binary" → compatible. + if (xUserType != null && yUserType != null) + { + comparison = string.Compare(xUserType, yUserType, StringComparison.Ordinal); + if (comparison != 0) + return comparison; + } + } } else if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { @@ -173,11 +189,11 @@ public TypeDuplicateHelper(SpirvContext context) GetTargetList(i.Data).Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); } - comparerSort = new OperationComparer(context, true); + comparerSort = new OperationComparer(context, true, this); namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(context, false); + comparerInsert = new OperationComparer(context, false, this); // UserTypeGOOGLE override in search key covers Index=-1 case } public OpDataIndex InsertInstruction(int index, OpData data) @@ -405,9 +421,30 @@ public static bool OpCheckDuplicateForConstant(Op op) return mismatches; } + public string? FindUserTypeGOOGLE(int typeId) + { + var (start, end) = FindDecorationRange(typeId); + var span = CollectionsMarshal.AsSpan(namesByOp); + var buffer = context.GetBuffer(); + for (int i = start; i < end; i++) + { + if (span[i].Op == Op.OpDecorateString) + { + OpDecorateString dec = new OpDataIndex(span[i].Index, buffer); + if (dec.Decoration == Decoration.UserTypeGOOGLE) + return dec.Value; + } + } + return null; + } + public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) + => CheckForDuplicates(data, null, out foundData); + + public bool CheckForDuplicates(OpData data, string? userTypeGOOGLE, out OpDataIndex foundData) { - var index = instructionsByOp.BinarySearch(new InstructionSortHelper { Op = data.Op, Index = -1, Data = data }, comparerInsert); + var searchKey = new InstructionSortHelper { Op = data.Op, Index = -1, Data = data, UserTypeGOOGLE = userTypeGOOGLE }; + var index = instructionsByOp.BinarySearch(searchKey, comparerInsert); if (index >= 0) { From a38511249f0b9818fd8c9592e367890f57055cc8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 17:03:23 +0900 Subject: [PATCH 0911/1182] SDSL: fix optional parameters handling --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index df0227d391..8b0dbf4f82 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -317,7 +317,7 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F } if (missingParameters > 0) - throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected"); + throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected (methodDefaultParameters={(methodDefaultParameters == null ? "null" : $"[{string.Join(",", methodDefaultParameters.Value.DefaultValues)}]({methodDefaultParameters.Value.DefaultValues.Length} values)")}, missing={missingParameters})"); } protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams) @@ -347,7 +347,7 @@ protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, public static int OverloadScore(FunctionType functionType, int defaultParameters, SymbolType[] argumentTypes) { // Check argument count - if (argumentTypes.Length > functionType.ParameterTypes.Count || argumentTypes.Length < functionType.ParameterTypes.Count + defaultParameters) + if (argumentTypes.Length > functionType.ParameterTypes.Count || argumentTypes.Length < functionType.ParameterTypes.Count - defaultParameters) return int.MaxValue; // Check if argument can be converted From 9e5a61e3f03df5fedd321ee97a7f85b0400b66e7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 17:31:22 +0900 Subject: [PATCH 0912/1182] SDSL: declare struct earlier --- .../Parsing/SDSL/AST/ShaderElements.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index b163a76adc..a219c275fb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -233,13 +233,15 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) Type = new StructType(TypeName.ToString(), fields); table.DeclaredTypes.Add(TypeName.ToString(), Type); + + // Register in the SPIR-V context immediately so that CBuffer.ProcessSymbol can reference + // this struct type as a member type before the Compile phase runs. + context.DeclareStructuredType((StructType)Type, context.Bound++); } public void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { - var (builder, context) = compiler; - var structType = (StructType)Type; - context.DeclareStructuredType(structType, context.Bound++); + // Already registered in ProcessSymbol. } public override string ToString() From 20ca403abef4103fc24d02f7376821371bc39b23 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 11 Mar 2026 17:32:02 +0900 Subject: [PATCH 0913/1182] SDSL: Added support for AppendStructuredBuffer --- .../Core/SymbolTypes.cs | 20 +++++- ...dStructuredBufferMethodsImplementations.cs | 62 +++++++++++++++++++ .../Parsing/SDSL/AST/IntrinsicCall.cs | 2 + .../SDSL/AST/IntrinsicTemplateExpander.cs | 6 ++ .../Parsing/SDSL/AST/Shader.cs | 2 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 10 ++- .../Spirv/Building/SpirvContext.Types.cs | 15 +++++ 7 files changed, 113 insertions(+), 4 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 86b4d87dde..a5ae454e45 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -56,9 +56,15 @@ public static bool TryGetBufferType(string name, TypeName? templateTypeName, [Ma { case "StructuredBuffer": case "RWStructuredBuffer": - var templateType = templateTypeName.Type; + var templateType = templateTypeName!.Type; result = new StructuredBufferType(templateType, name.StartsWith("RW")); return true; + case "AppendStructuredBuffer": + result = new AppendStructuredBufferType(templateTypeName!.Type); + return true; + case "ConsumeStructuredBuffer": + result = new ConsumeStructuredBufferType(templateTypeName!.Type); + return true; } // Note: templateTypeName is resolved lazily (because it might not be a buffer type and we don't need to resolve it) @@ -276,6 +282,18 @@ public sealed partial record StructuredBufferType(SymbolType BaseType, bool Writ public override string ToString() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType}>"; } +public sealed partial record AppendStructuredBufferType(SymbolType BaseType) : StructuredType($"AppendStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +{ + public override string ToId() => $"AppendStructuredBuffer<{BaseType.ToId()}>"; + public override string ToString() => $"AppendStructuredBuffer<{BaseType}>"; +} + +public sealed partial record ConsumeStructuredBufferType(SymbolType BaseType) : StructuredType($"ConsumeStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +{ + public override string ToId() => $"ConsumeStructuredBuffer<{BaseType.ToId()}>"; + public override string ToString() => $"ConsumeStructuredBuffer<{BaseType}>"; +} + public sealed partial record BufferType(ScalarType BaseType, bool WriteAllowed = false) : SymbolType() { public override string ToString() => $"{(WriteAllowed ? "RW" : "")}Buffer<{BaseType}>"; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs new file mode 100644 index 0000000000..82282006ad --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs @@ -0,0 +1,62 @@ +using Stride.Shaders.Core; +using Stride.Shaders.Parsing.SDSL.AST; +using Stride.Shaders.Parsing.Analysis; +using SpirvStorageClass = Stride.Shaders.Spirv.Specification.StorageClass; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Parsing.SDSL; + +public class AppendStructuredBufferMethodsImplementations : AppendStructuredBufferMethodsDeclarations +{ + public static AppendStructuredBufferMethodsImplementations Instance { get; } = new(); + + public override SpirvValue CompileAppend(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue value) + { + // Buffer struct is { T[] }, member 0 is the runtime array + // We write to element 0 as a placeholder (no atomic counter implemented) + var const0 = context.CompileConstant((int)0); + var baseType = functionType.ParameterTypes[0].Type; + var ptrTType = context.GetOrRegister(new PointerType(baseType, SpirvStorageClass.StorageBuffer)); + var ptrToData = builder.InsertData(new OpAccessChain(ptrTType, context.Bound++, appendStructuredBuffer.Id, [const0.Id, const0.Id])); + builder.Insert(new OpStore(ptrToData.IdResult!.Value, value.Id, null, [])); + return default; + } + + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue count, SpirvValue stride) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, appendStructuredBuffer.Id, 0)); + builder.Insert(new OpStore(count.Id, arrayLen.ResultId, null, [])); + var baseType = functionType.ParameterTypes[0].Type; + var elementSize = SpirvBuilder.TypeSizeInBuffer(baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var strideConst = context.CompileConstant((uint)elementSize); + builder.Insert(new OpStore(stride.Id, strideConst.Id, null, [])); + return default; + } +} + +public class ConsumeStructuredBufferMethodsImplementations : ConsumeStructuredBufferMethodsDeclarations +{ + public static ConsumeStructuredBufferMethodsImplementations Instance { get; } = new(); + + public override SpirvValue CompileConsume(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer) + { + // Read from element 0 as a placeholder (no atomic counter implemented) + var const0 = context.CompileConstant((int)0); + var returnType = functionType.ReturnType; + var ptrTType = context.GetOrRegister(new PointerType(returnType, SpirvStorageClass.StorageBuffer)); + var ptrToData = builder.InsertData(new OpAccessChain(ptrTType, context.Bound++, consumeStructuredBuffer.Id, [const0.Id, const0.Id])); + var loadResult = builder.Insert(new OpLoad(context.GetOrRegister(returnType), context.Bound++, ptrToData.IdResult!.Value, null, [])); + return new(loadResult.ResultId, loadResult.ResultType); + } + + public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer, SpirvValue count, SpirvValue stride) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, consumeStructuredBuffer.Id, 0)); + builder.Insert(new OpStore(count.Id, arrayLen.ResultId, null, [])); + return default; + } +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index a930d9c5aa..8501d5c5ff 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -51,6 +51,8 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na BufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.BufferMethods), IntrinsicsDefinitions.BufferMethods), BufferMethodsImplementations.Instance), BufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWBufferMethods), IntrinsicsDefinitions.RWBufferMethods), BufferMethodsImplementations.Instance), + AppendStructuredBufferType => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.AppendStructuredBufferMethods), IntrinsicsDefinitions.AppendStructuredBufferMethods), AppendStructuredBufferMethodsImplementations.Instance), + ConsumeStructuredBufferType => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.ConsumeStructuredBufferMethods), IntrinsicsDefinitions.ConsumeStructuredBufferMethods), ConsumeStructuredBufferMethodsImplementations.Instance), StructuredBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.StructuredBufferMethods), IntrinsicsDefinitions.StructuredBufferMethods), null), StructuredBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWStructuredBufferMethods), IntrinsicsDefinitions.RWStructuredBufferMethods), null), diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index bc09e0cb75..15c89e1345 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -222,6 +222,9 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) { TextureType t => t.ReturnType.GetElementType(), BufferType b => b.BaseType, + AppendStructuredBufferType b => b.BaseType, + ConsumeStructuredBufferType b => b.BaseType, + StructuredBufferType b => b.BaseType, null => throw new ArgumentNullException(nameof(thisType)), _ => throw new InvalidOperationException($"Can't resolve thisType base type for {thisType}"), }; @@ -279,6 +282,9 @@ ParameterTypeInfo GetParameterInfo(int index) null => throw new ArgumentNullException(nameof(thisType)), TextureType t => new(t.ReturnType.GetElementType(), new(t.ReturnType.GetElementCount(), null), default), BufferType b => new(b.BaseType, new(4, null), default), + AppendStructuredBufferType b => new(b.BaseType, new(1, null), default), + ConsumeStructuredBufferType b => new(b.BaseType, new(1, null), default), + StructuredBufferType b => new(b.BaseType, new(1, null), default), }; } if (index == -3) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 5f491e7cba..b9c51ae0f3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -197,6 +197,8 @@ void RegisterName(int target, string name) { var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a ? a.BaseType : fields[0].Type), var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a2 ? a2.BaseType : fields[0].Type, true), + var s when s.StartsWith("type.AppendStructuredBuffer.") => new AppendStructuredBufferType(fields[0].Type is ArrayType a3 ? a3.BaseType : fields[0].Type), + var s when s.StartsWith("type.ConsumeStructuredBuffer.") => new ConsumeStructuredBufferType(fields[0].Type is ArrayType a4 ? a4.BaseType : fields[0].Type), var s when s.StartsWith("type.") => new ConstantBufferSymbol(structName.Substring("type.".Length), fields), _ => throw new InvalidOperationException(), } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e69befc497..b573562481 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -202,7 +202,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var storageClass = (memberType, StorageClass, StreamKind) switch { (TextureType or BufferType, _, _) => Specification.StorageClass.UniformConstant, - (StructuredBufferType or ByteAddressBufferType, _, _) => Specification.StorageClass.StorageBuffer, + (StructuredBufferType or ByteAddressBufferType or AppendStructuredBufferType or ConsumeStructuredBufferType, _, _) => Specification.StorageClass.StorageBuffer, (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, (_, StorageClass.Static, _) => Specification.StorageClass.Private, (_, _, StreamKind.Stream or StreamKind.PatchStream) => Specification.StorageClass.Private, @@ -291,12 +291,16 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (StreamKind == StreamKind.PatchStream) context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); - if (pointerType.BaseType is StructuredBufferType sb) + if (pointerType.BaseType is AppendStructuredBufferType asb) + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"appendstructuredbuffer:<{asb.BaseType.ToId().ToLowerInvariant()}>")); + else if (pointerType.BaseType is ConsumeStructuredBufferType csb) + context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"consumestructuredbuffer:<{csb.BaseType.ToId().ToLowerInvariant()}>")); + else if (pointerType.BaseType is StructuredBufferType sb) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"{(sb.WriteAllowed ? "rw" : "")}structuredbuffer:<{sb.BaseType.ToId().ToLowerInvariant()}>")); else if (pointerType.BaseType is ByteAddressBufferType bab) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, bab.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); - if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false }) + if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false } or ConsumeStructuredBufferType) context.Add(new OpDecorate(variable, Specification.Decoration.NonWritable, [])); RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 710ebc1ac2..7f515476b3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -101,6 +101,8 @@ public int RegisterType(SymbolType type, int id) SamplerType st => Buffer.AddData(new OpTypeSampler(id)).IdResult, BufferType b => Buffer.AddData(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, 2, 0, 0, b.WriteAllowed ? 2 : 1, Specification.ImageFormat.Unknown, null)).IdResult, + AppendStructuredBufferType ab => RegisterAppendOrConsumeStructuredBufferType("Append", ab.BaseType), + ConsumeStructuredBufferType cb => RegisterAppendOrConsumeStructuredBufferType("Consume", cb.BaseType), StructuredBufferType b => RegisterStructuredBufferType(b), ByteAddressBufferType b => RegisterByteAddressBufferType(b), SampledImage si => Buffer.AddData(new OpTypeSampledImage(id, GetOrRegister(si.ImageType))).IdResult, @@ -132,6 +134,19 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy return bufferType; } + private int RegisterAppendOrConsumeStructuredBufferType(string prefix, SymbolType baseType) + { + var elementSize = SpirvBuilder.TypeSizeInBuffer(baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var runtimeArrayType = GetOrCreateRuntimeArray(GetOrRegister(baseType), elementSize); + + var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; + AddName(bufferType, $"type.{prefix}StructuredBuffer.{baseType.ToId()}"); + Buffer.Add(new OpMemberDecorate(bufferType, 0, Specification.Decoration.Offset, [0])); + Buffer.Add(new OpDecorate(bufferType, Specification.Decoration.Block, [])); + + return bufferType; + } + private int RegisterByteAddressBufferType(ByteAddressBufferType byteAddressBufferType) { var uintTypeId = GetOrRegister(ScalarType.UInt); From d393ca68a02fd112bd5148a60879fb4fdbce3e34 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 10:37:11 +0900 Subject: [PATCH 0914/1182] SDSL: Implement transpose() intrinsic and fix accessor type propagation for pointer method calls --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 1 + .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 8b0dbf4f82..12677e8fad 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -966,6 +966,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { methodCall.MemberCallBaseType = ((PointerType)currentValueType).BaseType; methodCall.ProcessSymbol(table); + accessor.Type = methodCall.Type; break; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index c0a49b0ced..72f5337905 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -356,7 +356,12 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileProcessTriTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); public override SpirvValue CompileReversebits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileSource_mark(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileTranspose(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileTranspose(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + var returnTypeId = context.GetOrRegister(functionType.ReturnType); + var result = builder.Insert(new OpTranspose(returnTypeId, context.Bound++, x.Id)); + return new(result.ResultId, result.ResultType); + } public override SpirvValue CompileCheckAccessFullyMapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue status) => throw new NotImplementedException(); public override SpirvValue CompileAddUint64(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); public override SpirvValue CompileNonUniformResourceIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue index) => throw new NotImplementedException(); From 023e2debc559c645491b5737787bb2f81e62b7ca Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 10:37:36 +0900 Subject: [PATCH 0915/1182] SDSL: Add C-style cast parsing and fix operator whitespace handling in binary parsers --- .../ExpressionParsers/BinaryParsers.cs | 12 +++++----- .../ExpressionParsers/UnaryParsers.Prefix.cs | 22 ++++++++++--------- .../ShaderParsers/ShaderClassParser.cs | 11 +++++++++- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 099cf495a5..3a16ca6a3c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -173,13 +173,11 @@ public static bool Relation(ref TScanner scanner, ParseResult result, parsed = shift; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - Parsers.Spaces0(ref scanner, result, out _); } while ( !Parsers.FollowedByAny(ref scanner, ["<<=", ">>="], out _, withSpaces: true) && Parsers.FollowedByAny(ref scanner, ["<=", ">=", "<", ">"], out op, withSpaces: true, advance: true) ); - if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -241,7 +239,7 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out } while ( !Parsers.FollowedByAny(ref scanner, ["&&", "&="], out _, withSpaces: true) - && Parsers.FollowedByAny(ref scanner, ["&"], out op, advance: true) + && Parsers.FollowedByAny(ref scanner, ["&"], out op, withSpaces: true, advance: true) ); if (parsed is not null) return true; @@ -276,7 +274,7 @@ public static bool BOr(ref TScanner scanner, ParseResult result, out E } while ( !Parsers.FollowedByAny(ref scanner, ["||", "|="], out _, withSpaces: true) - && Parsers.FollowedByAny(ref scanner, ["|"], out op, advance: true) + && Parsers.FollowedByAny(ref scanner, ["|"], out op, withSpaces: true, advance: true) ); if (parsed is not null) return true; @@ -310,7 +308,7 @@ public static bool XOr(ref TScanner scanner, ParseResult result, out E } while ( !Parsers.FollowedByAny(ref scanner, ["^="], out _, withSpaces: true) - && Parsers.FollowedByAny(ref scanner, ["^"], out op, advance: true) + && Parsers.FollowedByAny(ref scanner, ["^"], out op, withSpaces: true, advance: true) ); if (parsed is not null) return true; @@ -342,7 +340,7 @@ public static bool And(ref TScanner scanner, ParseResult result, out E else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, ["&&"], out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["&&"], out op, withSpaces: true, advance: true)); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -372,7 +370,7 @@ public static bool Or(ref TScanner scanner, ParseResult result, out Ex else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - while (Parsers.FollowedByAny(ref scanner, ["||"], out op, advance: true)); + while (Parsers.FollowedByAny(ref scanner, ["||"], out op, withSpaces: true, advance: true)); if (parsed is not null) return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 0c342fa5da..007f249933 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -99,16 +99,18 @@ public static bool Cast(ref TScanner scanner, ParseResult result, out where TScanner : struct, IScanner { var position = scanner.Position; - if ( - Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - && Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true) - && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) - && Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true) - ) - { - parsed = new CastExpression(typeName, Operator.Cast, expression, scanner[position..scanner.Position]); - return true; + var s1 = Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true); + if (!s1) { return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + var s2 = Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true); + if (!s2) { scanner.Position = position; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + var s3 = Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true); + if (!s3) { scanner.Position = position; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } + var s4 = Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true); + if (!s4) { + scanner.Position = position; + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); + parsed = new CastExpression(typeName, Operator.Cast, expression, scanner[position..scanner.Position]); + return true; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index dc302b28f0..d6596e34b9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -152,10 +152,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Parsers.Spaces0(ref scanner, result, out _) ) { + var errCount = result.Errors.Count; ParameterParsers.GenericsList(ref scanner, result, out var values); Parsers.Spaces0(ref scanner, result, out _); if (!Tokens.Char('>', ref scanner, advance: true)) - return Parsers.Exit(ref scanner, result, out parsed, position); + { + // Not a generic — restore position and errors added by GenericsList + // to avoid poisoning downstream parsers (e.g. `x < y` parsed as `x`) + while (result.Errors.Count > errCount) + result.Errors.RemoveAt(result.Errors.Count - 1); + scanner.Position = position; + parsed = default; + return false; + } parsed = new GenericIdentifier(typename, values, scanner[position..scanner.Position]); return true; } From aa66d65501df8d9b22abe3b4ec86ddca50f70c66 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 11:23:13 +0900 Subject: [PATCH 0916/1182] SDSL: Fix intrinsic <> layout to generate vector-only permutations, not matrix --- .../Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs index 05074aefa7..d9ec455b2a 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs @@ -264,7 +264,7 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) scanner.MatchWhiteSpace(advance: true); if (scanner.Match(">", true)) { - layout = new Layout("any", "any", new TextLocation(scanner.Code, position..scanner.Position)); + layout = new Layout("any", null, new TextLocation(scanner.Code, position..scanner.Position)); return true; } var size1Pos = scanner.Position; From 7e16c5360b930158a027f25a7b10b6d1c5500ea6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 12:56:00 +0900 Subject: [PATCH 0917/1182] SDSL: Add float16 (half) type support and implement f16tof32/f32tof16 intrinsics - Register Scalar.Half as OpTypeFloat(16) in SPIR-V type emission - Reconstruct ScalarType.Half from OpTypeFloat{Width:16} on SPIR-V import - Enable Half constant emission (was commented out) - Add all Half cast paths: OpFConvert for float/double, OpConvertF/S/U for int/uint - Implement f16tof32 via GLSL.std.450 UnpackHalf2x16 (scalar + vector variants) - Implement f32tof16 via GLSL.std.450 PackHalf2x16 (scalar + vector variants) - Fix intrinsic template expansion for BaseType.Float16, Int16, Uint16, Numeric16Only --- .../SDSL/AST/IntrinsicImplementations.cs | 78 ++++++++++++++++++- .../SDSL/AST/IntrinsicTemplateExpander.cs | 8 +- .../Parsing/SDSL/AST/Shader.cs | 2 +- .../Spirv/Building/Builder.Expressions.cs | 14 ++++ .../Spirv/Building/Context.Constants.cs | 2 +- .../Spirv/Building/SpirvContext.Types.cs | 1 + 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 72f5337905..20087c9692 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -333,8 +333,82 @@ public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder build public override SpirvValue CompileEvaluateAttributeCentroid(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); public override SpirvValue CompileEvaluateAttributeSnapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset) => throw new NotImplementedException(); public override SpirvValue CompileGetAttributeAtVertex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue VertexID) => throw new NotImplementedException(); - public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + // f16tof32(uint) -> float: UnpackHalf2x16 returns float2, extract .x + // For vector variants: decompose, apply per-element, recompose + var returnType = functionType.ReturnType; + var inputType = context.ReverseTypes[x.TypeId]; + var float2Type = context.GetOrRegister(new VectorType(ScalarType.Float, 2)); + var floatType = context.GetOrRegister(ScalarType.Float); + + if (inputType is ScalarType) + { + // UnpackHalf2x16(x) -> float2, then extract .x + var unpack = builder.Insert(new GLSLExp(float2Type, context.Bound++, context.GetGLSL(), x.Id)); + unpack.InstructionMemory.Span[4] = 62; // GLSLstd450 UnpackHalf2x16 + var extract = new SpirvValue(builder.InsertData(new OpCompositeExtract(floatType, context.Bound++, unpack.ResultId, [0]))); + return extract; + } + else if (inputType is VectorType v) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var components = new int[v.Size]; + for (int i = 0; i < v.Size; i++) + { + // Extract uint component + var comp = new SpirvValue(builder.InsertData(new OpCompositeExtract(uintType, context.Bound++, x.Id, [i]))); + // UnpackHalf2x16 -> float2 + var unpack = builder.Insert(new GLSLExp(float2Type, context.Bound++, context.GetGLSL(), comp.Id)); + unpack.InstructionMemory.Span[4] = 62; // GLSLstd450 UnpackHalf2x16 + // Extract .x -> float + var extract = new SpirvValue(builder.InsertData(new OpCompositeExtract(floatType, context.Bound++, unpack.ResultId, [0]))); + components[i] = extract.Id; + } + var result = new SpirvValue(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(returnType), context.Bound++, [.. components]))); + return result; + } + throw new InvalidOperationException($"Unexpected type {inputType} for f16tof32"); + } + public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + // f32tof16(float) -> uint: PackHalf2x16(float2(x, 0.0)) -> uint + // For vector variants: decompose, apply per-element, recompose + var returnType = functionType.ReturnType; + var inputType = context.ReverseTypes[x.TypeId]; + var float2Type = context.GetOrRegister(new VectorType(ScalarType.Float, 2)); + var floatType = context.GetOrRegister(ScalarType.Float); + var uintType = context.GetOrRegister(ScalarType.UInt); + var zero = context.AddConstant(0.0f); + + if (inputType is ScalarType) + { + // Construct float2(x, 0.0) + var float2Val = new SpirvValue(builder.InsertData(new OpCompositeConstruct(float2Type, context.Bound++, [x.Id, zero]))); + // PackHalf2x16(float2) -> uint + var pack = builder.Insert(new GLSLExp(uintType, context.Bound++, context.GetGLSL(), float2Val.Id)); + pack.InstructionMemory.Span[4] = 58; // GLSLstd450 PackHalf2x16 + return new(pack.ResultId, pack.ResultType); + } + else if (inputType is VectorType v) + { + var components = new int[v.Size]; + for (int i = 0; i < v.Size; i++) + { + // Extract float component + var comp = new SpirvValue(builder.InsertData(new OpCompositeExtract(floatType, context.Bound++, x.Id, [i]))); + // Construct float2(comp, 0.0) + var float2Val = new SpirvValue(builder.InsertData(new OpCompositeConstruct(float2Type, context.Bound++, [comp.Id, zero]))); + // PackHalf2x16 -> uint + var pack = builder.Insert(new GLSLExp(uintType, context.Bound++, context.GetGLSL(), float2Val.Id)); + pack.InstructionMemory.Span[4] = 58; // GLSLstd450 PackHalf2x16 + components[i] = pack.ResultId; + } + var result = new SpirvValue(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(returnType), context.Bound++, [.. components]))); + return result; + } + throw new InvalidOperationException($"Unexpected type {inputType} for f32tof16"); + } public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index 15c89e1345..cbb3c41012 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -132,7 +132,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.Bool => [ScalarType.Boolean], BaseType.Int => [ScalarType.Int], BaseType.Int32Only => [ScalarType.Int, ScalarType.UInt], - BaseType.Int16 => throw new NotImplementedException(), + BaseType.Int16 => [ScalarType.Int], BaseType.Int64 => [ScalarType.Int64], BaseType.SInt16Or32 => [ScalarType.Int], BaseType.AnyInt => [ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64], @@ -141,10 +141,10 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.AnyInt64 => [ScalarType.Int64, ScalarType.UInt64], BaseType.Int64Only => [ScalarType.Int64, ScalarType.UInt64], BaseType.Uint => [ScalarType.UInt], - BaseType.Uint16 => throw new NotImplementedException(), + BaseType.Uint16 => [ScalarType.UInt], BaseType.U64 => [ScalarType.UInt64], BaseType.Float => [ScalarType.Float], - BaseType.Float16 => throw new NotImplementedException(), + BaseType.Float16 => [ScalarType.Half], BaseType.AnyFloat => [ScalarType.Float, ScalarType.Double], BaseType.FloatLike => [ScalarType.Float], BaseType.Float32Only => [ScalarType.Float], @@ -161,7 +161,7 @@ void AddBaseTypePermutation(int argument, SymbolType[] types) BaseType.Texture2D => throw new NotImplementedException(), BaseType.UIntOnly => [ScalarType.UInt, ScalarType.UInt64], BaseType.Numeric => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64], - BaseType.Numeric16Only => throw new NotImplementedException(), + BaseType.Numeric16Only => [ScalarType.Half], BaseType.Numeric32Only => [ScalarType.Float, ScalarType.Int, ScalarType.UInt], BaseType.Any => [ScalarType.Float, ScalarType.Double, ScalarType.Int, ScalarType.UInt, ScalarType.Int64, ScalarType.UInt64, ScalarType.Boolean], BaseType.Match => throw new InvalidOperationException(), diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index b9c51ae0f3..817b973c8d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -138,7 +138,7 @@ void RegisterName(int target, string name) RegisterType(floatInstruction.ResultId, floatInstruction.Width switch { - 16 => throw new NotImplementedException(), + 16 => ScalarType.Half, 32 => ScalarType.Float, 64 => ScalarType.Double, _ => throw new InvalidOperationException(), diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 687c6927e9..d4c480bfd6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -675,6 +675,20 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 1.0, null, new()), elementSize).Id, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(32, true, true), 0.0, null, new()), elementSize).Id)), + // Half conversions (OpFConvert for float<->half<->double, standard int conversions) + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Float }) => InsertData(new OpFConvert(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Double }) => InsertData(new OpFConvert(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Half }) => InsertData(new OpFConvert(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Double }, ScalarType { Type: Scalar.Half }) => InsertData(new OpFConvert(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Int }) => InsertData(new OpConvertFToS(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpConvertFToU(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Half }) => InsertData(new OpConvertSToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Half }) => InsertData(new OpConvertUToF(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Boolean }) => InsertData(new OpFOrdNotEqual(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(16, true, true), 0.0, null, new()), elementSize).Id)), + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Half }) => InsertData(new OpSelect(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue, + context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(16, true, true), 1.0, null, new()), elementSize).Id, + context.CreateConstantCompositeVectorRepeat(new FloatLiteral(new(16, true, true), 0.0, null, new()), elementSize).Id)), + // Bitcast (int=>uint or uint=>int) (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index d63452ae37..fbe0cf273c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -21,7 +21,7 @@ public int AddConstant(TScalar value) int v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Int), Bound++, v)), ulong v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.UInt64), Bound++, v)), long v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Int64), Bound++, v)), - //Half v => Buffer.Add(new OpConstant(GetOrRegister(ScalarType.From("half")), Bound++, v)), + Half v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Half), Bound++, v)), float v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Float), Bound++, v)), double v => Buffer.AddData(new OpConstant(GetOrRegister(ScalarType.Double), Bound++, v)), _ => throw new NotImplementedException() diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 7f515476b3..cfb33e852f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -75,6 +75,7 @@ public int RegisterType(SymbolType type, int id) Scalar.UInt => Buffer.AddData(new OpTypeInt(id, 32, 0)).IdResult, Scalar.Int64 => Buffer.AddData(new OpTypeInt(id, 64, 1)).IdResult, Scalar.UInt64 => Buffer.AddData(new OpTypeInt(id, 64, 0)).IdResult, + Scalar.Half => Buffer.AddData(new OpTypeFloat(id, 16, null)).IdResult, Scalar.Float => Buffer.AddData(new OpTypeFloat(id, 32, null)).IdResult, Scalar.Double => Buffer.AddData(new OpTypeFloat(id, 64, null)).IdResult, _ => throw new NotImplementedException($"Can't add type {type}") From 70de5c701db4d8d361fa15e39210bb340c2d2701 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 14:10:30 +0900 Subject: [PATCH 0918/1182] SDSL: Fix brace initializer type propagation for array-of-vector declarations Resolve TypeName before processing the initializer value so expectedType is available, and handle VectorType in ArrayLiteral.ProcessSymbol so that nested brace initializers like {1,0,0} are treated as vector constructors rather than int arrays. Fixes "Can't cast int[3][9] to float3[9]" in MaterialTerrainDiffuse. Co-Authored-By: Claude Opus 4.6 --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs | 5 +++-- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 25431655df..e8fdf32495 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -310,6 +310,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = var expectedElementType = expectedType switch { + VectorType v => v.BaseType, MatrixType m => m.BaseType, ArrayType a => a.BaseType, _ => null, @@ -318,8 +319,8 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = foreach (var value in Values) value.ProcessSymbol(table, expectedElementType); - // Matrix brace initialization is fully handled by CompositeLiteral.CompileImpl - if (expectedType is MatrixType) + // Vector/Matrix brace initialization is fully handled by CompositeLiteral.CompileImpl + if (expectedType is VectorType or MatrixType) return; if (Type == null && Values.Count > 0) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index a3b595f166..60632e5591 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -97,10 +97,10 @@ public List? ArraySizes public override void ProcessSymbol(SymbolTable table) { - Value?.ProcessSymbol(table, TypeName.Type); SymbolType valueType; if (TypeName.Name == "var") { + Value?.ProcessSymbol(table); if (Value == null) table.Errors.Add(new(Info, "can't infer `var` type without a value")); valueType = Value.ValueType; @@ -109,6 +109,7 @@ public override void ProcessSymbol(SymbolTable table) { TypeName.ProcessSymbol(table); valueType = TypeName.Type; + Value?.ProcessSymbol(table, TypeName.Type); } Type = new PointerType(valueType, Specification.StorageClass.Function); Variable.Type = Type; From 4a026d5eda0687e17c958d195d1a9667cf3b511b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 12 Mar 2026 16:51:18 +0900 Subject: [PATCH 0919/1182] SDSL: Fix image sample/fetch result type to always use vec4 per SPIR-V spec OpImageSampleImplicitLod, OpImageSampleExplicitLod, and OpImageFetch require their result type to be a 4-component vector. For textures with non-vec4 return types (e.g. Texture2D), we were incorrectly using the scalar/smaller vector type directly, producing invalid SPIR-V. Now always sample into vec4 and extract the needed components via OpCompositeExtract (scalar) or OpVectorShuffle (vec2/vec3). --- .../SDSL/AST/TextureMethodsImplementations.cs | 62 +++++++++++++++++-- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index ad4a118339..fabb7727d0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -10,6 +10,44 @@ internal class TextureMethodsImplementations : TextureMethodsDeclarations { public static TextureMethodsImplementations Instance { get; } = new(); + /// + /// SPIR-V requires OpImageSample*/OpImageFetch result types to be a 4-component vector. + /// This method returns the vec4 type for sampling, and if the actual return type is smaller, + /// extracts the needed components from the vec4 result. + /// + private static (int Vec4TypeId, bool NeedsExtract) GetImageSampleResultType(SpirvContext context, FunctionType functionType, TextureType textureType) + { + var returnType = functionType.ReturnType; + var scalarType = returnType.GetElementType(); + var vec4Type = new VectorType((ScalarType)scalarType, 4); + var vec4TypeId = context.GetOrRegister(vec4Type); + var needsExtract = returnType.GetElementCount() < 4; + return (vec4TypeId, needsExtract); + } + + private static SpirvValue ExtractFromVec4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, int vec4ResultId) + { + var returnType = functionType.ReturnType; + var elementCount = returnType.GetElementCount(); + var returnTypeId = context.GetOrRegister(returnType); + + if (elementCount == 1) + { + // Scalar: extract component 0 + var extract = builder.InsertData(new OpCompositeExtract(returnTypeId, context.Bound++, vec4ResultId, [0])); + return new(extract); + } + else + { + // vec2 or vec3: shuffle from vec4 + Span indices = stackalloc int[elementCount]; + for (int i = 0; i < elementCount; i++) + indices[i] = i; + var shuffle = builder.InsertData(new OpVectorShuffle(returnTypeId, context.Bound++, vec4ResultId, vec4ResultId, new(indices))); + return new(shuffle); + } + } + public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? s = null) { if (status != null) @@ -30,6 +68,8 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde if (textureType.Arrayed) textureDim++; + var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); + if (imageCoordSize > textureDim) { // Coord has extra component (LOD): extract it and strip from coord @@ -42,14 +82,16 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(coordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); TextureGenerateImageOperands(lod, o, s, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); + var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); return new(loadResult.ResultId, loadResult.ResultType); } else { // No LOD component (e.g. RWTexture): use coord directly TextureGenerateImageOperands(null, o, s, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(context.GetOrRegister(functionType.ReturnType), context.Bound++, texture.Id, x.Id, imask, imParams)); + var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); return new(loadResult.ResultId, loadResult.ResultType); } } @@ -60,13 +102,15 @@ public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder buil throw new NotImplementedException(); var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); - var sample = builder.Insert(new OpImageSampleImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } @@ -76,13 +120,15 @@ public override SpirvValue CompileSampleBias(SpirvContext context, SpirvBuilder throw new NotImplementedException(); var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, bias: bias); - var sample = builder.Insert(new OpImageSampleImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } @@ -92,13 +138,15 @@ public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder throw new NotImplementedException(); var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); TextureGenerateImageOperands(lod, o, null, out var imask, out var imParams); - var sample = builder.Insert(new OpImageSampleExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } @@ -108,13 +156,15 @@ public override SpirvValue CompileSampleGrad(SpirvContext context, SpirvBuilder throw new NotImplementedException(); var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; + var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, ddx, ddy); - var sample = builder.Insert(new OpImageSampleExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); + if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } From bc2ccdf9a86069191839aa4341ec14b61f3ab6c7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 00:14:44 +0900 Subject: [PATCH 0920/1182] SDSL: Allow partial matrix truncation in mul() overload resolution --- .../Spirv/Building/Builder.Expressions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index d4c480bfd6..5dbc02bad8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -491,7 +491,7 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // Emit warning? (warning: implicit truncation of vector type) (VectorType or MatrixType, ScalarType) => 13, (VectorType v1, VectorType v2) when v1.Size > v2.Size => 13, - (MatrixType m1, MatrixType m2) when m1.Rows > m2.Rows && m1.Columns > m2.Columns => 13, + (MatrixType m1, MatrixType m2) when (m1.Rows > m2.Rows && m1.Columns >= m2.Columns) || (m1.Rows >= m2.Rows && m1.Columns > m2.Columns) => 13, // Note: conversions such as float2x2<=>float4 are allowed but not implemented in Convert() (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, From 0fe76bafab98c06e94ef2a8f56c703247866cc41 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 00:58:05 +0900 Subject: [PATCH 0921/1182] SDSL: Fix intrinsic overload resolution to prefer dimension-reducing over shape-changing truncation --- .../Spirv/Building/Builder.Expressions.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 5dbc02bad8..6f93ed474e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -488,10 +488,11 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) (ScalarType, VectorType or MatrixType) => 1, // Truncation - // Emit warning? (warning: implicit truncation of vector type) - (VectorType or MatrixType, ScalarType) => 13, - (VectorType v1, VectorType v2) when v1.Size > v2.Size => 13, - (MatrixType m1, MatrixType m2) when (m1.Rows > m2.Rows && m1.Columns >= m2.Columns) || (m1.Rows >= m2.Rows && m1.Columns > m2.Columns) => 13, + // Shape-changing truncation (vector/matrix to scalar) costs more than dimension-reducing truncation + // This ensures e.g. mul(float3, float4x4) picks mul_vm(float3, float3x4) over mul_sm(float, float4x4) + (VectorType or MatrixType, ScalarType) => 20, + (VectorType v1, VectorType v2) when v1.Size > v2.Size => 10 + (v1.Size - v2.Size), + (MatrixType m1, MatrixType m2) when (m1.Rows > m2.Rows && m1.Columns >= m2.Columns) || (m1.Rows >= m2.Rows && m1.Columns > m2.Columns) => 10 + (m1.Rows - m2.Rows) + (m1.Columns - m2.Columns), // Note: conversions such as float2x2<=>float4 are allowed but not implemented in Convert() (MatrixType m1, VectorType v2) when v2.Size == m1.Rows * m1.Columns => 1, From 3dbc37f4df0a336c35d2b1c0c5a1bf04e1e85e71 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 01:12:26 +0900 Subject: [PATCH 0922/1182] SDSL: Use StorageImageWriteWithoutFormat for 3-component storage textures --- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 8 ++++++++ .../Spirv/Building/SpirvContext.Types.cs | 3 +-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5cbae48c0a..96263f8624 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -78,6 +78,14 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o break; } } + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.Imageformat == ImageFormat.Unknown) + { + context.Add(new OpCapability(Capability.StorageImageWriteWithoutFormat)); + break; + } + } foreach (var i in temp) { if (i.Op is Op.OpImageQuerySizeLod or Op.OpImageQuerySize or Op.OpImageQueryLevels or Op.OpImageQuerySamples) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index cfb33e852f..924eb6eeca 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -311,8 +311,7 @@ private static Specification.ImageFormat GetStorageImageFormat(SymbolType return (Scalar.Float, 1) => Specification.ImageFormat.R32f, (Scalar.Float, 2) => Specification.ImageFormat.Rg32f, (Scalar.Float, 4) => Specification.ImageFormat.Rgba32f, - (Scalar.Float, 3) => throw new NotSupportedException( - "3-component float storage textures have no SPIR-V ImageFormat equivalent. Use float4 instead."), + (Scalar.Float, 3) => Specification.ImageFormat.Unknown, (Scalar.UInt, 1) => Specification.ImageFormat.R32ui, (Scalar.UInt, 2) => Specification.ImageFormat.Rg32ui, (Scalar.UInt, 4) => Specification.ImageFormat.Rgba32ui, From c453b8e16ceddcc28b72ca6e97d18b44697bccc2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 08:04:50 +0900 Subject: [PATCH 0923/1182] SDSL: Fix SPVGenerator to produce PascalCase property names for multi-word operands --- .../Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs | 2 +- .../SDSL/ShaderMixer.Reflection.cs | 2 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 2 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 2 +- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 4 ++-- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 8 ++++---- .../Processing/Interfaces/Analysis/StreamAnalyzer.cs | 6 +++--- .../Processing/Interfaces/Cleanup/DeadCodeRemover.cs | 6 +++--- .../SPVGenerator.Helpers.Naming.cs | 2 +- .../SPVGenerator.Instructions.cs | 7 +++++-- 10 files changed, 22 insertions(+), 19 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index b661f10797..1d12fd5570 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -27,7 +27,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob foreach (var i in temp) { if (i.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)i) is { Storageclass: Specification.StorageClass.Uniform } variable + && ((OpVariableSDSL)i) is { StorageClass: Specification.StorageClass.Uniform } variable && context.ReverseTypes[variable.ResultType] is PointerType { BaseType: var variableType } && variableType is not ConstantBufferSymbol) { diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index a626ada5a4..0438630338 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -169,7 +169,7 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont : shader.ShaderName; } else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is - { Storageclass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer } variable) + { StorageClass: Specification.StorageClass.UniformConstant or Specification.StorageClass.StorageBuffer } variable) { // Note: we don't rename cbuffer as they have been merged and don't belong to a specific shader/composition anymore var type = context.ReverseTypes[variable.ResultType]; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 684a9bb3fd..2d6bad69a9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -73,7 +73,7 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext c shaderInfo.Functions.Add(functionName, functions = new()); functions.Add((function.ResultId, functionType)); } - else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + else if (i.Data.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.StorageClass != Specification.StorageClass.Function) { var variableName = context.Names[variable.ResultId]; var variableType = context.ReverseTypes[variable.ResultType]; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 0bbb768d48..7312a70dda 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -117,7 +117,7 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con foreach (var i in shader.Buffer) { - if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.Storageclass != Specification.StorageClass.Function) + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.StorageClass != Specification.StorageClass.Function) { hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 96263f8624..2dc83b645a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -80,7 +80,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o } foreach (var i in context) { - if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.Imageformat == ImageFormat.Unknown) + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.ImageFormat == ImageFormat.Unknown) { context.Add(new OpCapability(Capability.StorageImageWriteWithoutFormat)); break; @@ -1059,7 +1059,7 @@ or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoratio // Transform OpVariableSDSL into OpVariable (we don't need extra info anymore) // Note: we ignore initializer as we store a method which is already processed during InterfaceProcessor (as opposed to a const for OpVariable) if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable) - temp.Replace(i.Index, new OpVariable(variable.ResultType, variable.ResultId, variable.Storageclass, null)); + temp.Replace(i.Index, new OpVariable(variable.ResultType, variable.ResultId, variable.StorageClass, null)); // Collect IDs (except for OpName/OpDecorate/OpDecorateString metadata) if (i.Op != Op.OpName && i.Op != Op.OpDecorate && i.Op != Op.OpDecorateString) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 817b973c8d..7daf4287b6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -163,7 +163,7 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpTypePointer && (OpTypePointer)instruction is { } pointerInstruction) { var innerType = context.ReverseTypes[pointerInstruction.Type]; - RegisterType(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.Storageclass)); + RegisterType(pointerInstruction.ResultId, new PointerType(innerType, pointerInstruction.StorageClass)); } else if (instruction.Op == Op.OpTypeVoid && (OpTypeVoid)instruction is { } voidInstruction) { @@ -249,7 +249,7 @@ void RegisterName(int target, string name) SymbolType returnType = textureReturnTypes.TryGetValue(typeImage.ResultId, out var userType) ? userType : (typeImage.Sampled == 2 - ? typeImage.Imageformat switch + ? typeImage.ImageFormat switch { Specification.ImageFormat.Rg32f or Specification.ImageFormat.Rg32i or Specification.ImageFormat.Rg32ui => new VectorType(sampledType, 2), Specification.ImageFormat.Rgba32f or Specification.ImageFormat.Rgba32i or Specification.ImageFormat.Rgba32ui => new VectorType(sampledType, 4), @@ -270,7 +270,7 @@ void RegisterName(int target, string name) Depth = typeImage.Depth, Arrayed = typeImage.Arrayed == 1 ? true : false, Multisampled = typeImage.MS == 1 ? true : false, - Format = typeImage.Imageformat, + Format = typeImage.ImageFormat, Sampled = typeImage.Sampled, }; @@ -417,7 +417,7 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte { var instruction = shaderBuffers.Buffer[index]; if (instruction.Op == Op.OpVariableSDSL && (OpVariableSDSL)instruction is { } variable && - variable.Storageclass != Specification.StorageClass.Function) + variable.StorageClass != Specification.StorageClass.Function) { if (!shaderBuffers.Context.Names.TryGetValue(variable.ResultId, out var variableName)) variableName = $"_{variable.ResultId}"; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index 7abc7a26d2..83026b3731 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -76,7 +76,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) foreach (var i in buffer) { if (i.Op == Op.OpVariableSDSL - && ((OpVariableSDSL)i) is { Storageclass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } + && ((OpVariableSDSL)i) is { StorageClass: StorageClass.Uniform, ResultType: var pointerType2, ResultId: var bufferId } && context.ReverseTypes[pointerType2] is PointerType { BaseType: ConstantBufferSymbol }) { var name = nameTable[bufferId]; @@ -87,7 +87,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, + StorageClass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, ResultId: int } variable && context.ReverseTypes[variable.ResultType] is PointerType { BaseType: not ConstantBufferSymbol }) @@ -117,7 +117,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, + StorageClass: StorageClass.UniformConstant or StorageClass.StorageBuffer, ResultId: int } resource) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 36c5ddc07d..9d07556ff9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -117,7 +117,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Uniform, + StorageClass: StorageClass.Uniform, ResultId: int } variable && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) @@ -131,7 +131,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.UniformConstant or StorageClass.StorageBuffer, + StorageClass: StorageClass.UniformConstant or StorageClass.StorageBuffer, ResultId: int } resource) { @@ -147,7 +147,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte if (i.Op == Op.OpVariableSDSL && ((OpVariableSDSL)i) is { - Storageclass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, + StorageClass: StorageClass.Private or StorageClass.Workgroup or StorageClass.Uniform, ResultId: int } variable2 && context.ReverseTypes[variable2.ResultType] is PointerType { BaseType: not ConstantBufferSymbol }) diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index f49f03028f..64cd98b3dd 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -237,7 +237,7 @@ public static string ConvertKindToName(string kind, bool lower = true) ("IdRef", false) => "Id", ("IdResult", false) => "ResultId", ("IdResultType", false) => "ResultType", - (_, true) => kind.ToLower(), + (_, true) => LowerFirst(kind), (_, false) => kind }; } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 31d94795da..9c0de21016 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -368,9 +368,12 @@ public static (string TypeName, string FieldName, string OperandName) ToTypeFiel if (char.IsLetterOrDigit(c) || c == '_') { nameBuilder.Append(first ? char.ToUpperInvariant(c) : c); - first &= false; + first = false; + } + else + { + first = true; } - } fieldName = nameBuilder.ToString(); } From 6f75b407706731004abdcb663e49d667bf85a394 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 08:56:36 +0900 Subject: [PATCH 0924/1182] SDSL: Use grammar-derived names for * quantifier operands in SPVGenerator --- .../SDSL/EffectEvaluator.cs | 2 +- .../SDSL/ShaderMixer.CBuffers.cs | 8 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 6 +- .../SDSL/ShaderMixer.cs | 8 +- .../Parsing/SDSL/AST/Shader.cs | 6 +- .../Spirv/Building/Builder.Class.cs | 10 +-- .../Spirv/Building/Context.Constants.cs | 2 +- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 6 +- .../Transformation/StreamAccessPatcher.cs | 8 +- .../SPVGenerator.Helpers.Naming.cs | 89 +++++++++++++------ 10 files changed, 91 insertions(+), 54 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index d506f2e705..2828c9f05b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -97,7 +97,7 @@ private ShaderMixinSource EffectInterpreter(ShaderBuffers shaderBuffers, IDictio // Note: we currently use EffectCodeWriter to generate C# code instead throw new NotImplementedException(); string DecodeString(int id) => throw new NotImplementedException(); - var instSource = new ShaderClassSource(DecodeString(mixinInstruction.Value), mixinInstruction.Values); + var instSource = new ShaderClassSource(DecodeString(mixinInstruction.Value), mixinInstruction.Generics); var evaluatedSource = EvaluateEffects(instSource); switch (mixinInstruction.Kind) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 1d12fd5570..ae2bf33874 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -105,7 +105,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob { if (variableToMemberIndices.TryGetValue(accessChain.BaseId, out var memberIndex)) { - accessChain.Values = new([context.CompileConstant(memberIndex).Id, .. accessChain.Values.Elements.Span]); + accessChain.Indexes = new([context.CompileConstant(memberIndex).Id, .. accessChain.Indexes.Elements.Span]); accessChain.BaseId = cbufferVariable.ResultId; } } @@ -116,7 +116,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob { if (i.Op == Op.OpEntryPoint && (OpEntryPoint)i is { } entryPoint) { - entryPoint.Values = new([.. entryPoint.Values, cbufferVariable.ResultId]); + entryPoint.InterfaceIds = new([.. entryPoint.InterfaceIds, cbufferVariable.ResultId]); } } @@ -279,12 +279,12 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData if (variables.TryGetValue(accessChain.BaseId, out var cbuffer) && cbuffer.MemberIndexOffset > 0) { // According to spec, this must be a OpConstant (and we only create them with int) - var indexes = accessChain.Values.Elements.Span; + var indexes = accessChain.Indexes.Elements.Span; var constantId = indexes[0]; var index = cbuffer.MemberIndexOffset + (int)context.GetConstantValue(constantId); indexes[0] = context.CompileConstant(index).Id; - // Regenerate buffer (since we modify accessChain.Values, it doesn't get rebuilt automatically) + // Regenerate buffer (since we modify accessChain.Indexes, it doesn't get rebuilt automatically) accessChain.UpdateInstructionMemory(); } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 2d6bad69a9..a939758d7e 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -107,12 +107,12 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin { // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups var shaderName = importShader.ShaderName; - if (importShader.Values.Elements.Length > 0) + if (importShader.Generics.Elements.Length > 0) { - var genericArguments = new string[importShader.Values.Elements.Length]; + var genericArguments = new string[importShader.Generics.Elements.Length]; for (int j = 0; j < genericArguments.Length; j++) { - genericArguments[j] = ShaderClassSource.ConvertGenericArgToString(context.GetConstantValue(importShader.Values.Elements.Span[j])); + genericArguments[j] = ShaderClassSource.ConvertGenericArgToString(context.GetConstantValue(importShader.Generics.Elements.Span[j])); } shaderName += $"<{string.Join(",", genericArguments)}>"; } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 2dc83b645a..a8a7677a7b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -770,7 +770,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions) || (mixinNode.Stage != null && mixinNode.Stage.CompositionArrays.TryGetValue(accessChain.BaseId, out compositions))) { - var compositionIndex = (int)context.GetConstantValue(accessChain.Values.Elements.Span[0]); + var compositionIndex = (int)context.GetConstantValue(accessChain.Indexes.Elements.Span[0]); compositionArrayAccesses.Add(accessChain.ResultId, compositions[compositionIndex]); SetOpNop(i.Data.Memory.Span); @@ -978,9 +978,9 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) { - Span parameterTypes = stackalloc int[functionType.Values.Elements.Span.Length]; - for (int j = 0; j < functionType.Values.Elements.Span.Length; ++j) - parameterTypes[j] = functionType.Values.Elements.Span[j].Item1; + Span parameterTypes = stackalloc int[functionType.ParameterTypes.Elements.Span.Length]; + for (int j = 0; j < functionType.ParameterTypes.Elements.Span.Length; ++j) + parameterTypes[j] = functionType.ParameterTypes.Elements.Span[j].Item1; // Make sure to unify same types: they might have different OpTypeFunctionSDSL due to modifiers but end up having the same OpTypeFunction once modifiers info is removed // If two duplicate OpTypeFunction exists, this causes SPIR-V validation errors diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 7daf4287b6..30b097ae61 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -182,7 +182,7 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpTypeStruct && (OpTypeStruct)instruction is { } typeStructInstruction) { var structName = context.Names[typeStructInstruction.ResultId]; - var fieldsData = typeStructInstruction.Values; + var fieldsData = typeStructInstruction.MemberTypes; var fields = new List(); for (var index = 0; index < fieldsData.WordCount; index++) { @@ -229,7 +229,7 @@ void RegisterName(int target, string name) var tmp = new OpTypeFunction(instruction); var returnType = context.ReverseTypes[typeFunctionInstruction.ReturnType]; var parameterTypes = new List(); - foreach (var operand in typeFunctionInstruction.Values) + foreach (var operand in typeFunctionInstruction.ParameterTypes) { parameterTypes.Add(new(context.ReverseTypes[operand.Item1], (ParameterModifiers)operand.Item2)); } @@ -301,7 +301,7 @@ void RegisterName(int target, string name) // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { - var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); + var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Generics.Elements.Memory.ToArray()); var shaderSymbol = realShaderImporter.Import(classSource, context); RegisterType(importShader.ResultId, shaderSymbol); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 206d4e9f6e..16381f7545 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -184,7 +184,7 @@ int RemapGenericParameter(int localGeneric) public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpSDSLImportShader importShader) { - return new ShaderClassInstantiation(importShader.ShaderName, importShader.Values.Elements.Memory.ToArray()); + return new ShaderClassInstantiation(importShader.ShaderName, importShader.Generics.Elements.Memory.ToArray()); } public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep) @@ -654,16 +654,16 @@ public static void RemapIds(Dictionary idRemapping, ref OpData i) var existing = new HashSet(); var target = 0; - for (int index = 0; index < entryPoint.Values.Elements.Length; ++index) + for (int index = 0; index < entryPoint.InterfaceIds.Elements.Length; ++index) { - if (existing.Add(entryPoint.Values.Elements.Span[index])) + if (existing.Add(entryPoint.InterfaceIds.Elements.Span[index])) { - entryPoint.Values.Elements.Span[target++] = entryPoint.Values.Elements.Span[index]; + entryPoint.InterfaceIds.Elements.Span[target++] = entryPoint.InterfaceIds.Elements.Span[index]; } } // Slice and reassign to refresh InstructionMemory and size - entryPoint.Values = entryPoint.Values.Slice(0, target); + entryPoint.InterfaceIds = entryPoint.InterfaceIds.Slice(0, target); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index fbe0cf273c..ca754fd587 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -163,7 +163,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object if ((i.Op == Specification.Op.OpConstantComposite || i.Op == Specification.Op.OpSpecConstantComposite) && (OpConstantComposite)i is { } constantComposite) { - var values = constantComposite.Values; + var values = constantComposite.Constituents; var constants = new object[values.WordCount]; for (int j = 0; j < values.WordCount; ++j) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index 513a986f00..9eba9bd996 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -175,8 +175,8 @@ or Op.OpAtomicExchange or Op.OpAtomicCompareExchange or Op.OpAtomicLoad or Op.Op // In case it's a patch access, i.e. patch[0], mark the access as being a stream if (patchInstructionIds.TryGetValue(currentBase, out var patchStreamKind)) { - var patchVariableId = accessChain.Values.Elements.Span[0]; - if (accessChain.Values.Elements.Length > 1) + var patchVariableId = accessChain.Indexes.Elements.Span[0]; + if (accessChain.Indexes.Elements.Length > 1) throw new InvalidOperationException("OpAccessChain on PatchType can have only 1 element"); streamsInstructionIds.Add(accessChain.ResultId, patchStreamKind); } @@ -186,7 +186,7 @@ or Op.OpAtomicExchange or Op.OpAtomicCompareExchange or Op.OpAtomicLoad or Op.Op // In case it's a streams access, mark the stream as being the base if (streamsInstructionIds.TryGetValue(currentBase, out var streamKind)) { - var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamVariableId = accessChain.Indexes.Elements.Span[0]; var streamInfo = streams[streamVariableId]; // Set this base for OpStore/OpLoad stream R/W analysis diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index 2214c623dc..a679828c16 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -128,9 +128,9 @@ void CheckStreamTypes(int id) // In case it's a streams.Variable access, patch acces to use STREAMS struct with proper index to this variable // Note: we made sure in AccessChainExpression to decompose access such as inputs[2].variable into two OpAccessChain // so that we match this easier to detect format - if (accessChain.Values.Elements.Length == 1 && streamsInstructionIds.TryGetValue(accessChain.BaseId, out var streamAccessInfo)) + if (accessChain.Indexes.Elements.Length == 1 && streamsInstructionIds.TryGetValue(accessChain.BaseId, out var streamAccessInfo)) { - var streamVariableId = accessChain.Values.Elements.Span[0]; + var streamVariableId = accessChain.Indexes.Elements.Span[0]; var streamInfo = streams[streamVariableId]; var streamStructMemberIndex = streamAccessInfo.Kind switch { @@ -141,13 +141,13 @@ void CheckStreamTypes(int id) // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that // we'll need a better way to update LiteralArray and propagate changes - accessChain.Values.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; + accessChain.Indexes.Elements.Span[0] = context.CompileConstant(streamStructMemberIndex).Id; if (streamAccessInfo.IsImplicit) accessChain.BaseId = streamsVariableId; else // Force refresh of InstructionMemory - // TODO: remove when accessChain.Values update properly the instruction + // TODO: remove when accessChain.Indexes update properly the instruction accessChain.BaseId = accessChain.BaseId; } } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs index 64cd98b3dd..1fd4504446 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Naming.cs @@ -45,7 +45,6 @@ public static string ConvertNameQuantToName(string name, string quant) { return (name, quant) switch { - (_, "*") => "values", ("event", _) => "eventId", ("string", _) => "value", ("base", _) => "baseId", @@ -55,6 +54,42 @@ public static string ConvertNameQuantToName(string name, string quant) }; } + /// + /// Extracts the first quoted name from a SPIR-V operand name that may contain + /// multi-value documentation like "'Member 0 type', +\n'member 1 type', +\n...". + /// Strips digit suffixes to produce a clean base name (e.g., "Member 0 type" → "Member type"). + /// + static string ExtractFirstOperandName(string name) + { + // Take up to the first comma or + that separates multiple values + var commaIdx = name.IndexOf(','); + var plusIdx = name.IndexOf('+'); + var newlineIdx = name.IndexOf('\n'); + var end = name.Length; + if (commaIdx > 0) end = Math.Min(end, commaIdx); + if (plusIdx > 0) end = Math.Min(end, plusIdx); + if (newlineIdx > 0) end = Math.Min(end, newlineIdx); + var first = name[..end].Trim().Trim('\'').Trim(); + + // Strip digit suffixes and capitalize each word for CamelCase + // e.g. "Member 0 type" → "MemberTypes", "Argument 0" → "Arguments" + // If a digit was removed, pluralize by adding "s" at the end + var sb = new StringBuilder(); + var parts = first.Split(' '); + bool hadDigit = false; + foreach (var part in parts) + { + if (part.Length > 0 && part.All(char.IsDigit)) + { + hadDigit = true; + continue; + } + sb.Append(char.ToUpperInvariant(part[0])); + sb.Append(part[1..]); + } + return sb.Length > 0 ? sb.ToString() : first; + } + public static void PreProcessOperands(InstructionData op, Dictionary operandKinds, List<(string Name, string Type)> parameters) { var opname = op.OpName; @@ -84,14 +119,14 @@ public static void PreProcessOperands(InstructionData op, Dictionary"); + parameters.AddUnique(ConvertOperandName(ExtractFirstOperandName(name), "*"), $"Span<{realKind}>"); } else { if (e.Quantifier == "?") parameters.AddUnique(ConvertKindToName(kind!), $"{realKind}?"); else if (e.Quantifier == "*") - parameters.AddUnique("values", $"Span<{realKind}>"); + parameters.AddUnique(ConvertKindToName(kind!), $"Span<{realKind}>"); } } else @@ -139,14 +174,14 @@ public static List ConvertOperandsToParameters(InstructionData op, Dicti if (e.Quantifier == "?") parameters.AddUnique(realKind + "? " + ConvertOperandName(name)); else if (e.Quantifier == "*") - parameters.AddUnique("Span<" + realKind + "> values"); + parameters.AddUnique("Span<" + realKind + "> " + ConvertOperandName(ExtractFirstOperandName(name), "*")); } else { if (e.Quantifier == "?") parameters.AddUnique(realKind + "? " + ConvertKindToName(kind!)); else if (e.Quantifier == "*") - parameters.AddUnique("Span<" + realKind + "> values"); + parameters.AddUnique("Span<" + realKind + "> " + ConvertKindToName(kind!)); } } else @@ -190,14 +225,14 @@ public static List ConvertOperandsToParameterNames(InstructionData op, D if (quant == "?") parameters.AddUnique(ConvertOperandName(name)); else if (quant == "*") - parameters.AddUnique("values"); + parameters.AddUnique(ConvertOperandName(ExtractFirstOperandName(name), "*")); } else { if (quant == "?") parameters.AddUnique(ConvertKindToName(kind!)); else if (quant == "*") - parameters.AddUnique("values"); + parameters.AddUnique(ConvertKindToName(kind!)); } } else @@ -268,27 +303,29 @@ public static string ConvertOperandName(string input, string? quant = null, bool } } - return (result.ToString(), quant) switch + var name = result.ToString() switch { - ("event", _) => "eventId", - ("string", _) => "value", - ("base", _) => "baseId", - ("object", _) => "objectId", - ("default", _) => "defaultId", - ("IdResult", _) => "resultId", - ("IdResultType", _) => "resultType", - ("IdRef", "*") => "id", - ("IdRef", "?") => "id", - ("IdRef", null) => "id", - ("LiteralInteger", _) => "", - ("LiteralFloat", _) => "", - ("LiteralString", _) => "", - ("Dim", _) => "", - ("ImageFormat", _) => "", - ("ExecutionMode", _) => "", - ("ExecutionModel", _) => "", - (string v, _) => v + "event" => "eventId", + "string" => "value", + "base" => "baseId", + "object" => "objectId", + "default" => "defaultId", + "interface" => "interfaceId", + "IdResult" => "resultId", + "IdResultType" => "resultType", + "IdRef" => "id", + "LiteralInteger" => "", + "LiteralFloat" => "", + "LiteralString" => "", + "Dim" => "", + "ImageFormat" => "", + "ExecutionMode" => "", + "ExecutionModel" => "", + string v => v }; + if (quant == "*" && name.Length > 0 && !name.EndsWith("s")) + name += "s"; + return name; } static string LowerFirst(string s) => char.IsLower(s[0]) ? s : $"{char.ToLowerInvariant(s[0])}{s[1..]}"; From 4b57d1d5c32322a44667f6f6ea72bd0a24f5a3c1 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 09:32:37 +0900 Subject: [PATCH 0925/1182] SDSL: Fix argument list parser to allow spaces before commas --- .../Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 3896935a6e..7e04284dcd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -67,7 +67,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o break; // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLParsingMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } - while (!scanner.IsEof && Parsers.FollowedBy(ref scanner, Tokens.Char(','), advance: true)); + while (!scanner.IsEof && Parsers.FollowedBy(ref scanner, Tokens.Char(','), advance: true, withSpaces: true)); parsed = new(scanner[position..scanner.Position]) { From cb4996bc06c177aef3957b5cd91feac42a008877 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 09:56:07 +0900 Subject: [PATCH 0926/1182] SDSL: Fix intrinsic <> layout to generate matrix overloads with shared size permutation --- .../Intrinsics/Parser.cs | 2 +- .../Parsing/SDSL/AST/IntrinsicTemplateExpander.cs | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs index d9ec455b2a..05074aefa7 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Intrinsics/Parser.cs @@ -264,7 +264,7 @@ internal static bool LayoutSize(this ref Scanner scanner, out Layout layout) scanner.MatchWhiteSpace(advance: true); if (scanner.Match(">", true)) { - layout = new Layout("any", null, new TextLocation(scanner.Code, position..scanner.Position)); + layout = new Layout("any", "any", new TextLocation(scanner.Code, position..scanner.Position)); return true; } var size1Pos = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index cbb3c41012..efb3927233 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -73,10 +73,9 @@ void AddVectorSizePermutation(int argument, int templateIndex, string name) // name can be either a value (1,2,3,4,any) or a name (when multiple slots adjusted with same permutation, in which case value is [1,2,3,4]). switch (name) { - case "any" or "1" or "2" or "3" or "4": + case "1" or "2" or "3" or "4": permutation = new SizePermutationGenerator(null, name switch { - "any" => [1, 2, 3, 4], "1" => [1], "2" => [2], "3" => [3], @@ -86,10 +85,13 @@ void AddVectorSizePermutation(int argument, int templateIndex, string name) break; default: // use name as key (and find existing one if already declared) - permutation = sizePermutationGenerators.FirstOrDefault(x => x.Name == name); + // For "any", we use a synthetic key per dimension so that all <> occurrences + // share the same size permutation (e.g. f16tof32: float<> and uint<> must match) + var key = name == "any" ? $"__any{templateIndex}" : name; + permutation = sizePermutationGenerators.FirstOrDefault(x => x.Name == key); if (permutation == null) { - permutation = new SizePermutationGenerator(name, [1, 2, 3, 4], new()); + permutation = new SizePermutationGenerator(key, [1, 2, 3, 4], new()); sizePermutationGenerators.Add(permutation); } break; @@ -338,9 +340,9 @@ ParameterTypeInfo GetParameterInfo(int index) if (resolvedBaseType.Size1.Value > 1 && resolvedBaseType.Size2.Value > 1) { - if (resolvedBaseType.Size1.Generator.Name == null) + if (resolvedBaseType.Size1.Generator.Name == null || resolvedBaseType.Size1.Generator.Name.StartsWith("__any")) { - // If matrix types are generated from a size generator (without a name so that there is no specific row/column pattern like in mul()), + // If matrix types are generated from a <> size generator (without a specific row/column pattern like in mul()), // we can automatically convert a call to multiple calls on each inner vector. // So we try to remember this info here if (autoMatrixLoop != null && autoMatrixLoop != resolvedBaseType.Size1.Generator) From fc652ed05569f62577afd16f2c0171a6a0ff98e2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 10:56:16 +0900 Subject: [PATCH 0927/1182] SDSL: Extract binary operator dispatch into SelectBinaryOp lookup Replaces 125-line switch expression with a single instruction + opcode patch, matching the existing pattern used by CompileFloatUnaryCall and CompileInterlockedCall. --- .../Spirv/Building/Builder.Expressions.cs | 183 ++++++------------ 1 file changed, 57 insertions(+), 126 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 6f93ed474e..167ded9170 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -304,138 +304,69 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv var leftElementType = leftType.GetElementType(); var rightElementType = rightType.GetElementType(); - var instruction = (op, leftElementType, rightElementType) switch - { - (Operator.Plus, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpIAdd(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Plus, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFAdd(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Minus, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpISub(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Minus, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFSub(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Mul, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpIMul(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Mul, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFMul(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsUnsignedInteger() && r.IsUnsignedInteger() - => Buffer.InsertData(Position++, new OpUDiv(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpSDiv(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Div, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFDiv(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsUnsignedInteger() && r.IsUnsignedInteger() - => Buffer.InsertData(Position++, new OpUMod(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpSMod(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Mod, SymbolType l, SymbolType r) - when l.IsFloating() && r.IsNumber() - => Buffer.InsertData(Position++, new OpFMod(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.RightShift, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftRightLogical(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.LeftShift, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpShiftLeftLogical(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.AND, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseAnd(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.OR, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseOr(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.XOR, SymbolType l, SymbolType r) - when l.IsInteger() && r.IsInteger() - => Buffer.InsertData(Position++, new OpBitwiseXor(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.LogicalAND, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalAnd(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.LogicalOR, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalOr(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Equals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Equals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) - => Buffer.InsertData(Position++, new OpIEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Equals, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdEqual(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.NotEquals, ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Boolean }) - => Buffer.InsertData(Position++, new OpLogicalNotEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.NotEquals, ScalarType { Type: Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Int or Scalar.UInt }) - => Buffer.InsertData(Position++, new OpINotEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.NotEquals, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdNotEqual(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Lower, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSLessThan(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Lower, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpULessThan(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Lower, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdLessThan(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.LowerOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSLessThanEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.LowerOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpULessThanEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.LowerOrEqual, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdLessThanEqual(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.Greater, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSGreaterThan(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Greater, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpUGreaterThan(resultTypeId, resultId, left.Id, right.Id)), - (Operator.Greater, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdGreaterThan(resultTypeId, resultId, left.Id, right.Id)), - - (Operator.GreaterOrEqual, ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.Int }) - => Buffer.InsertData(Position++, new OpSGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.GreaterOrEqual, ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.UInt }) - => Buffer.InsertData(Position++, new OpUGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), - (Operator.GreaterOrEqual, ScalarType l, ScalarType r) - when l.IsFloating() && r.IsFloating() - => Buffer.InsertData(Position++, new OpFOrdGreaterThanEqual(resultTypeId, resultId, left.Id, right.Id)), - - _ => throw new NotImplementedException() - }; + var spirvOp = SelectBinaryOp(op, leftElementType); + // All SPIR-V binary ops share the same 5-word layout (wordcount|opcode, resultType, resultId, operand1, operand2), + // so we create one and patch the opcode. + var instruction = Buffer.Insert(Position++, new OpIAdd(resultTypeId, resultId, left.Id, right.Id)); + instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)spirvOp; if (name is not null) context.AddName(resultId, name); return new(resultId, resultTypeId, name); } + static Specification.Op SelectBinaryOp(Operator op, SymbolType elementType) => (op, elementType) switch + { + // Arithmetic + (Operator.Plus, _) when elementType.IsInteger() => Specification.Op.OpIAdd, + (Operator.Plus, _) when elementType.IsFloating() => Specification.Op.OpFAdd, + (Operator.Minus, _) when elementType.IsInteger() => Specification.Op.OpISub, + (Operator.Minus, _) when elementType.IsFloating() => Specification.Op.OpFSub, + (Operator.Mul, _) when elementType.IsInteger() => Specification.Op.OpIMul, + (Operator.Mul, _) when elementType.IsFloating() => Specification.Op.OpFMul, + (Operator.Div, _) when elementType.IsUnsignedInteger() => Specification.Op.OpUDiv, + (Operator.Div, _) when elementType.IsInteger() => Specification.Op.OpSDiv, + (Operator.Div, _) when elementType.IsFloating() => Specification.Op.OpFDiv, + (Operator.Mod, _) when elementType.IsUnsignedInteger() => Specification.Op.OpUMod, + (Operator.Mod, _) when elementType.IsInteger() => Specification.Op.OpSMod, + (Operator.Mod, _) when elementType.IsFloating() => Specification.Op.OpFMod, + + // Shift / bitwise + (Operator.RightShift, _) when elementType.IsInteger() => Specification.Op.OpShiftRightLogical, + (Operator.LeftShift, _) when elementType.IsInteger() => Specification.Op.OpShiftLeftLogical, + (Operator.AND, _) when elementType.IsInteger() => Specification.Op.OpBitwiseAnd, + (Operator.OR, _) when elementType.IsInteger() => Specification.Op.OpBitwiseOr, + (Operator.XOR, _) when elementType.IsInteger() => Specification.Op.OpBitwiseXor, + + // Logical + (Operator.LogicalAND, ScalarType { Type: Scalar.Boolean }) => Specification.Op.OpLogicalAnd, + (Operator.LogicalOR, ScalarType { Type: Scalar.Boolean }) => Specification.Op.OpLogicalOr, + + // Equality + (Operator.Equals, ScalarType { Type: Scalar.Boolean }) => Specification.Op.OpLogicalEqual, + (Operator.Equals, _) when elementType.IsInteger() => Specification.Op.OpIEqual, + (Operator.Equals, _) when elementType.IsFloating() => Specification.Op.OpFOrdEqual, + (Operator.NotEquals, ScalarType { Type: Scalar.Boolean }) => Specification.Op.OpLogicalNotEqual, + (Operator.NotEquals, _) when elementType.IsInteger() => Specification.Op.OpINotEqual, + (Operator.NotEquals, _) when elementType.IsFloating() => Specification.Op.OpFOrdNotEqual, + + // Comparison + (Operator.Lower, _) when elementType.IsUnsignedInteger() => Specification.Op.OpULessThan, + (Operator.Lower, _) when elementType.IsInteger() => Specification.Op.OpSLessThan, + (Operator.Lower, _) when elementType.IsFloating() => Specification.Op.OpFOrdLessThan, + (Operator.LowerOrEqual, _) when elementType.IsUnsignedInteger() => Specification.Op.OpULessThanEqual, + (Operator.LowerOrEqual, _) when elementType.IsInteger() => Specification.Op.OpSLessThanEqual, + (Operator.LowerOrEqual, _) when elementType.IsFloating() => Specification.Op.OpFOrdLessThanEqual, + (Operator.Greater, _) when elementType.IsUnsignedInteger() => Specification.Op.OpUGreaterThan, + (Operator.Greater, _) when elementType.IsInteger() => Specification.Op.OpSGreaterThan, + (Operator.Greater, _) when elementType.IsFloating() => Specification.Op.OpFOrdGreaterThan, + (Operator.GreaterOrEqual, _) when elementType.IsUnsignedInteger() => Specification.Op.OpUGreaterThanEqual, + (Operator.GreaterOrEqual, _) when elementType.IsInteger() => Specification.Op.OpSGreaterThanEqual, + (Operator.GreaterOrEqual, _) when elementType.IsFloating() => Specification.Op.OpFOrdGreaterThanEqual, + + _ => throw new NotImplementedException($"Binary operator {op} not supported for element type {elementType}") + }; + /// /// Check if a type can be converted to another. /// From 3081380571b95b5c743544d2a1963c14ac092875 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 11:05:09 +0900 Subject: [PATCH 0928/1182] SDSL: Consolidate texture dimension dispatch into TextureType properties Adds BaseDimension, CoordinateDimension, and SizeQueryDimension to TextureType, replacing 4 duplicated switch expressions across Expression.cs and TextureMethodsImplementations.cs. --- .../Core/SymbolTypes.cs | 9 +++++++ .../Parsing/SDSL/AST/Expression.cs | 20 ++------------ .../SDSL/AST/TextureMethodsImplementations.cs | 26 ++----------------- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index a5ae454e45..7036e2e7ac 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -318,6 +318,15 @@ public sealed partial record SampledImage(TextureType ImageType) : SymbolType() public abstract partial record TextureType(SymbolType ReturnType, Dim Dimension, int Depth, bool Arrayed, bool Multisampled, int Sampled, ImageFormat Format) : SymbolType() { + /// Base spatial dimensions: 1D→1, 2D→2, 3D/Cube→3. + public int BaseDimension => Dimension switch { Dim.Dim1D => 1, Dim.Dim2D => 2, _ => 3 }; + + /// Coordinate size including array layer (BaseDimension + 1 if Arrayed). + public int CoordinateDimension => BaseDimension + (Arrayed ? 1 : 0); + + /// Number of components returned by OpImageQuerySize (Cube maps return 2, not 3). + public int SizeQueryDimension => (Dimension == Dim.Cube ? 2 : BaseDimension) + (Arrayed ? 1 : 0); + public override string ToId() => $"Texture_{ReturnType}"; public override string ToString() => $"Texture<{ReturnType}>({Dimension}, {Depth}, {Arrayed}, {Multisampled}, {Sampled}, {Format})"; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 12677e8fad..f64d6f5c79 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1367,30 +1367,14 @@ private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, S SpirvValue ConvertTexCoord(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue, ScalarType baseType, bool hasLod = false) { - var textureCoordSize = textureType switch - { - Texture1DType => 1, - Texture2DType => 2, - Texture3DType or TextureCubeType => 3, - }; - if (textureType.Arrayed) - textureCoordSize++; - if (hasLod) - textureCoordSize++; + var textureCoordSize = textureType.CoordinateDimension + (hasLod ? 1 : 0); spirvValue = builder.Convert(context, spirvValue, baseType.GetVectorOrScalar(textureCoordSize)); return spirvValue; } SpirvValue ConvertOffset(SpirvContext context, SpirvBuilder builder, TextureType textureType, SpirvValue spirvValue) { - var offsetSize = textureType switch - { - Texture1DType => 1, - Texture2DType => 2, - Texture3DType or TextureCubeType => 3, - }; - - spirvValue = builder.Convert(context, spirvValue, ScalarType.Int.GetVectorOrScalar(offsetSize)); + spirvValue = builder.Convert(context, spirvValue, ScalarType.Int.GetVectorOrScalar(textureType.BaseDimension)); return spirvValue; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index fabb7727d0..e22fa1417d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -57,16 +57,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde var imageCoordType = context.ReverseTypes[x.TypeId]; var imageCoordSize = imageCoordType.GetElementCount(); - // Determine the texture's natural coordinate dimension - var textureDim = textureType switch - { - Texture1DType => 1, - Texture2DType => 2, - Texture3DType or TextureCubeType => 3, - _ => throw new NotImplementedException($"Unsupported texture type {textureType}") - }; - if (textureType.Arrayed) - textureDim++; + var textureDim = textureType.CoordinateDimension; var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); @@ -372,20 +363,7 @@ public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuild var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var uintType = context.GetOrRegister(ScalarType.UInt); - // Determine the number of size components returned by image size query - // SPIR-V returns: scalar for 1D, vec2 for 2D/Cube, vec3 for 3D - // Add 1 if arrayed (array layers as last component) - int sizeComponents = textureType switch - { - Texture1DType { Arrayed: false } => 1, - Texture1DType { Arrayed: true } => 2, - Texture2DType { Arrayed: false } => 2, - Texture2DType { Arrayed: true } => 3, - Texture3DType => 3, - TextureCubeType { Arrayed: false } => 2, - TextureCubeType { Arrayed: true } => 3, - _ => throw new NotImplementedException($"GetDimensions not supported for texture type {textureType}") - }; + int sizeComponents = textureType.SizeQueryDimension; var sizeResultType = sizeComponents == 1 ? uintType : context.GetOrRegister(new VectorType(ScalarType.UInt, sizeComponents)); From 6e4050714e1a82df134ebdd38127ef5813405227 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 11:44:04 +0900 Subject: [PATCH 0929/1182] SDSL: Encode full SamplerState as single OpDecorate with bit-cast parameters --- .../SDSL/ShaderMixer.Reflection.cs | 74 +++----------- .../SDSL/ShaderMixer.cs | 3 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 90 ++++++++--------- .../Extensions/spirv.sdsl.grammar-ext.json | 98 +++---------------- .../SDSL/RenderTests/TextureSample.sdsl | 14 ++- 5 files changed, 87 insertions(+), 192 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 0438630338..54123edf8a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -221,66 +221,24 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon var samplerStates = new Dictionary(); foreach (var i in context) { - if ((i.Op == Specification.Op.OpDecorate || i.Op == Specification.Op.OpDecorateString) && - (OpDecorate)i is - { - Decoration: - Specification.Decoration.SamplerStateFilter - or Specification.Decoration.SamplerStateAddressU - or Specification.Decoration.SamplerStateAddressV - or Specification.Decoration.SamplerStateAddressW - or Specification.Decoration.SamplerStateMipLODBias - or Specification.Decoration.SamplerStateMaxAnisotropy - or Specification.Decoration.SamplerStateComparisonFunc - or Specification.Decoration.SamplerStateMinLOD - or Specification.Decoration.SamplerStateMaxLOD, - DecorationParameters: { } p - - } decorate) + if (i.Op == Specification.Op.OpDecorate && + (OpDecorate)i is { Decoration: Specification.Decoration.SamplerStateSDSL, DecorationParameters: { } p } decorate) { - ref var samplerState = - ref CollectionsMarshal.GetValueRefOrAddDefault(samplerStates, decorate.Target, out var exists); - if (!exists) - samplerState = Graphics.SamplerStateDescription.Default; - switch (decorate.Decoration) + var s = p.Span; + samplerStates[decorate.Target] = new Graphics.SamplerStateDescription { - case Specification.Decoration.SamplerStateFilter: - samplerState.Filter = (Graphics.TextureFilter)p.Span[0]; - break; - case Specification.Decoration.SamplerStateAddressU: - samplerState.AddressU = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Specification.Decoration.SamplerStateAddressV: - samplerState.AddressV = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Specification.Decoration.SamplerStateAddressW: - samplerState.AddressW = (Graphics.TextureAddressMode)p.Span[0]; - break; - case Specification.Decoration.SamplerStateMipLODBias: - { - using var n = new LiteralValue(p.Span); - samplerState.MipMapLevelOfDetailBias = float.Parse(n.Value); - break; - } - case Specification.Decoration.SamplerStateMaxAnisotropy: - samplerState.MaxAnisotropy = p.Span[0]; - break; - case Specification.Decoration.SamplerStateComparisonFunc: - samplerState.CompareFunction = (Graphics.CompareFunction)p.Span[0]; - break; - case Specification.Decoration.SamplerStateMinLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MinMipLevel = float.Parse(n.Value); - break; - } - case Specification.Decoration.SamplerStateMaxLOD: - { - using var n = new LiteralValue(p.Span); - samplerState.MaxMipLevel = float.Parse(n.Value); - break; - } - } + Filter = (Graphics.TextureFilter)s[0], + AddressU = (Graphics.TextureAddressMode)s[1], + AddressV = (Graphics.TextureAddressMode)s[2], + AddressW = (Graphics.TextureAddressMode)s[3], + MipMapLevelOfDetailBias = BitConverter.Int32BitsToSingle(s[4]), + MaxAnisotropy = s[5], + CompareFunction = (Graphics.CompareFunction)s[6], + MinMipLevel = BitConverter.Int32BitsToSingle(s[7]), + MaxMipLevel = BitConverter.Int32BitsToSingle(s[8]), + BorderColor = new(BitConverter.Int32BitsToSingle(s[9]), BitConverter.Int32BitsToSingle(s[10]), + BitConverter.Int32BitsToSingle(s[11]), BitConverter.Int32BitsToSingle(s[12])), + }; } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a8a7677a7b..585c8917b7 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1024,8 +1024,7 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont or Decoration.ShaderConstantSDSL or Decoration.PatchConstantFuncSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL - or Decoration.SamplerStateFilter or Decoration.SamplerStateAddressU or Decoration.SamplerStateAddressV or Decoration.SamplerStateAddressW - or Decoration.SamplerStateMipLODBias or Decoration.SamplerStateMaxAnisotropy or Decoration.SamplerStateComparisonFunc or Decoration.SamplerStateMinLOD or Decoration.SamplerStateMaxLOD) + or Decoration.SamplerStateSDSL) return true; if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b573562481..82a86e2701 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -59,71 +59,67 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var variableId = context.Bound++; - // We store SamplerState as decoration for later processing during ShaderMixer.ProcessReflection() - // Note: we make sure to do it before the OpVariableSDSL as per SPIR-V spec so that it is correctly processed later + // Encode all sampler state fields into a single OpDecorate + // Defaults match SamplerStateDescription.Default: Linear(21) filter, Clamp(3) addressing, no LOD bias, 16x aniso, Never(1) compare, full LOD range + int filter = 21; // TextureFilter.Linear = MIN_MAG_MIP_LINEAR + int addressU = (int)Specification.SamplerTextureAddressModeSDSL.Clamp; + int addressV = (int)Specification.SamplerTextureAddressModeSDSL.Clamp; + int addressW = (int)Specification.SamplerTextureAddressModeSDSL.Clamp; + int mipLODBias = 0; // BitConverter.SingleToInt32Bits(0.0f) == 0 + int maxAnisotropy = 16; + int comparisonFunc = (int)Specification.SamplerComparisonFuncSDSL.Never; + int minLOD = BitConverter.SingleToInt32Bits(-float.MaxValue); + int maxLOD = BitConverter.SingleToInt32Bits(float.MaxValue); + int borderR = 0, borderG = 0, borderB = 0, borderA = 0; // Black (0,0,0,0) foreach (var parameter in Parameters) { switch (parameter.Name) { case "Filter": - { - var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateFilter, [(int)filter])); - break; - } + filter = (int)Enum.Parse(((Identifier)parameter.Value).Name, true); + break; case "AddressU": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressU, [(int)addressMode])); - break; - } + addressU = (int)Enum.Parse(((Identifier)parameter.Value).Name, true); + break; case "AddressV": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressV, [(int)addressMode])); - break; - } + addressV = (int)Enum.Parse(((Identifier)parameter.Value).Name, true); + break; case "AddressW": - { - var addressMode = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateAddressW, [(int)addressMode])); - break; - } + addressW = (int)Enum.Parse(((Identifier)parameter.Value).Name, true); + break; case "MipLODBias": - { - var mipLODBias = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMipLODBias, mipLODBias.ToString())); - break; - } + mipLODBias = BitConverter.SingleToInt32Bits((float)((FloatLiteral)parameter.Value).Value); + break; case "MaxAnisotropy": - { - var maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateMaxAnisotropy, [maxAnisotropy])); - break; - } + maxAnisotropy = ((IntegerLiteral)parameter.Value).IntValue; + break; + case "ComparisonFunc": + comparisonFunc = (int)Enum.Parse(((Identifier)parameter.Value).Name, true); + break; case "MinLOD": - { - var minLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMinLOD, minLOD.ToString())); - break; - } + minLOD = BitConverter.SingleToInt32Bits((float)((FloatLiteral)parameter.Value).Value); + break; case "MaxLOD": + maxLOD = BitConverter.SingleToInt32Bits((float)((FloatLiteral)parameter.Value).Value); + break; + case "BorderColor": { - var maxLOD = (float)((FloatLiteral)parameter.Value).Value; - context.Add(new OpDecorateString(variableId, Specification.Decoration.SamplerStateMaxLOD, maxLOD.ToString())); - break; - } - case "ComparisonFunc": - { - var filter = Enum.Parse(((Identifier)parameter.Value).Name, true); - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateComparisonFunc, [(int)filter])); + if (parameter.Value is not VectorLiteral { TypeName.Name: "float4", Values: { Count: 4 } args }) + throw new NotSupportedException($"BorderColor must be float4(r, g, b, a)"); + borderR = BitConverter.SingleToInt32Bits((float)((NumberLiteral)args[0]).DoubleValue); + borderG = BitConverter.SingleToInt32Bits((float)((NumberLiteral)args[1]).DoubleValue); + borderB = BitConverter.SingleToInt32Bits((float)((NumberLiteral)args[2]).DoubleValue); + borderA = BitConverter.SingleToInt32Bits((float)((NumberLiteral)args[3]).DoubleValue); break; } - case "BorderColor": default: - throw new NotImplementedException(); + throw new NotImplementedException($"SamplerState parameter '{parameter.Name}' not implemented"); } } + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateSDSL, [ + filter, addressU, addressV, addressW, mipLODBias, maxAnisotropy, comparisonFunc, minLOD, maxLOD, + borderR, borderG, borderB, borderA + ])); var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable.ResultId, Name); diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index dfd68d34fd..cc3c072993 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -569,92 +569,22 @@ "version": "1.0" }, { - "enumerant": "SamplerStateFilter", + "enumerant": "SamplerStateSDSL", "value": 8020, "parameters": [ - { - "kind": "SamplerFilterSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressU", - "value": 8021, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressV", - "value": 8022, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateAddressW", - "value": 8023, - "parameters": [ - { - "kind": "SamplerTextureAddressModeSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMipLODBias", - "value": 8024, - "parameters": [ - { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxAnisotropy", - "value": 8025, - "parameters": [ - { - "kind": "LiteralInteger" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateComparisonFunc", - "value": 8026, - "parameters": [ - { - "kind": "SamplerComparisonFuncSDSL" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMinLOD", - "value": 8027, - "parameters": [ - { - "kind": "LiteralString" - } - ], - "version": "1.0" - }, - { - "enumerant": "SamplerStateMaxLOD", - "value": 8028, - "parameters": [ - { - "kind": "LiteralString" - } + { "kind": "LiteralInteger", "name": "Filter" }, + { "kind": "LiteralInteger", "name": "AddressU" }, + { "kind": "LiteralInteger", "name": "AddressV" }, + { "kind": "LiteralInteger", "name": "AddressW" }, + { "kind": "LiteralInteger", "name": "MipLODBias" }, + { "kind": "LiteralInteger", "name": "MaxAnisotropy" }, + { "kind": "LiteralInteger", "name": "ComparisonFunc" }, + { "kind": "LiteralInteger", "name": "MinLOD" }, + { "kind": "LiteralInteger", "name": "MaxLOD" }, + { "kind": "LiteralInteger", "name": "BorderR" }, + { "kind": "LiteralInteger", "name": "BorderG" }, + { "kind": "LiteralInteger", "name": "BorderB" }, + { "kind": "LiteralInteger", "name": "BorderA" } ], "version": "1.0" }, diff --git a/sources/shaders/assets/SDSL/RenderTests/TextureSample.sdsl b/sources/shaders/assets/SDSL/RenderTests/TextureSample.sdsl index 9db879ae89..b40f0d0074 100644 --- a/sources/shaders/assets/SDSL/RenderTests/TextureSample.sdsl +++ b/sources/shaders/assets/SDSL/RenderTests/TextureSample.sdsl @@ -8,7 +8,19 @@ shader TextureSample stream float2 TexCoord : TEXCOORD; stage Texture2D Texture1; - stage SamplerState Sampler1; + stage SamplerState Sampler1 + { + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Clamp; + AddressV = Clamp; + AddressW = Clamp; + MipLODBias = 0.0; + MaxAnisotropy = 16; + ComparisonFunc = Never; + MinLOD = 0.0; + MaxLOD = 1000.0; + BorderColor = float4(0, 0, 0, 0); + }; void PSMain() { From 6013410f88ef213c4912750e2b60bdd96df7c0f7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 12:10:30 +0900 Subject: [PATCH 0930/1182] SDSL: Unify SDSL and SDFX statement parsers via delegate parameter --- .../EffectStatementParsers.Conditional.cs | 124 ------------ .../Parsers/EffectStatementParsers.Flow.cs | 190 ------------------ .../SDFX/Parsers/EffectStatementParsers.cs | 6 +- .../StatementParsers.Control.cs | 56 +++--- .../StatementParsers/StatementParsers.Flow.cs | 104 +++++----- .../StatementParsers/StatementParsers.cs | 11 +- 6 files changed, 89 insertions(+), 402 deletions(-) delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs deleted file mode 100644 index d795ebd310..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Conditional.cs +++ /dev/null @@ -1,124 +0,0 @@ -using Stride.Shaders.Parsing.SDFX.AST; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDFX; - - - -public record struct EffectControlsParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (If(ref scanner, result, out var ifstatement, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) - { - parsed = new(ifstatement, scanner[..]); - while (ElseIf(ref scanner, result, out var elseif, orError) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) - parsed.ElseIfs.Add(elseif); - if (Else(ref scanner, result, out var elseStatement, orError)) - parsed.Else = elseStatement; - parsed.Info = scanner[position..scanner.Position]; - return true; - } - else if (Tokens.Literal("else ", ref scanner)) - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new("Else block should be preceeded by If statement", scanner[scanner.Position], scanner.Memory)); - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - - public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new EffectControlsParser().Match(ref scanner, result, out parsed, orError); - - public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new IfStatementParser().Match(ref scanner, result, out parsed, orError); - public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ElseIfStatementParser().Match(ref scanner, result, out parsed, orError); - public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ElseStatementParser().Match(ref scanner, result, out parsed, orError); -} - - - -public record struct IfStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out If parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Tokens.Literal("if", ref scanner, advance: true) - && SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - ) - { - if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) - { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) - { - parsed = new(condition, statement, scanner[position..scanner.Position]); - return true; - } - } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} - -public record struct ElseIfStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseIf parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Tokens.Literal("else", ref scanner, advance: true) - && SDSL.Parsers.Spaces1(ref scanner, result, out _) - && Tokens.Literal("if", ref scanner, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && Tokens.Char('(', ref scanner, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && ExpressionParser.Expression(ref scanner, result, out var condition, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory)) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - ) - { - if (Tokens.Char(')', ref scanner, advance: true) && SDSL.Parsers.Spaces0(ref scanner, result, out _)) - { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) - { - parsed = new(condition, statement, scanner[position..scanner.Position]); - return true; - } - } - else return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} - -public record struct ElseStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Else parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Tokens.Literal("else", ref scanner, advance: true) - && SDSL.Parsers.Spaces0(ref scanner, result, out _) - && EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)) - ) - { - parsed = new(statement, scanner[position..scanner.Position]); - return true; - } - return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} - diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs deleted file mode 100644 index babd37e310..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.Flow.cs +++ /dev/null @@ -1,190 +0,0 @@ -using Stride.Shaders.Core; -using Stride.Shaders.Parsing.SDFX.AST; -using Stride.Shaders.Parsing.SDSL; -using Stride.Shaders.Parsing.SDSL.AST; - -namespace Stride.Shaders.Parsing.SDFX; - - - -public record struct FlowParsers : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && Parsers.Spaces0(ref scanner, result, out _); - if (!hasAttributes) - scanner.Position = position; - if (While(ref scanner, result, out var w, orError)) - { - if (hasAttributes) - w.Attribute = attribute; - parsed = w; - return true; - } - else if (ForEach(ref scanner, result, out var fe, orError)) - { - parsed = fe; - return true; - } - else if (For(ref scanner, result, out var f, orError)) - { - if (hasAttributes) - f.Attribute = attribute; - parsed = f; - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - - public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new WhileParser().Match(ref scanner, result, out parsed, orError); - public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ForEachParser().Match(ref scanner, result, out parsed, orError); - public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ForParser().Match(ref scanner, result, out parsed, orError); -} - - - -public record struct ForParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out For parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if ( - Tokens.Literal("for", ref scanner, advance: true) - && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - ) - { - Statement? init = null; - Expression? condition = null; - List? expressions = null; - Parsers.Spaces0(ref scanner, result, out _); - - // Parsing the initialization - if (StatementParsers.Expression(ref scanner, result, out init)) { } - else if (StatementParsers.DeclareOrAssign(ref scanner, result, out init)) { } - else if (StatementParsers.Empty(ref scanner, result, out init)) { } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0036, scanner[scanner.Position], scanner.Memory)); - - Parsers.Spaces0(ref scanner, result, out _); - // Parsing the condition - - if (ExpressionParser.Expression(ref scanner, result, out condition) - && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) { } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); - - Parsers.Spaces0(ref scanner, result, out _); - // parsing the final expression - - var tmpPos = scanner.Position; - - if (!Parsers.Repeat(ref scanner, result, AssignOrExpression, out expressions, 0, withSpaces: true, separator: ",")) - expressions = [new EmptyStatement(scanner[tmpPos..scanner.Position])]; - if (!Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true)) - return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - Parsers.Spaces0(ref scanner, result, out _); - - // parsing the block or statement - - if (EffectStatementParsers.Statement(ref scanner, result, out var body)) - { - parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); - return true; - } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - else return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } - - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (ExpressionParser.Expression(ref scanner, result, out var expression)) - { - parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); - return true; - } - return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} - -public record struct ForEachParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ForEach parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Tokens.Literal("foreach", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if ( - LiteralsParser.TypeName(ref scanner, result, out var typeName, new(SDSLErrorMessages.SDSL0017, scanner[scanner.Position], scanner.Memory)) - && Parsers.Spaces1(ref scanner, result, out _) - && LiteralsParser.Identifier(ref scanner, result, out var identifier, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) - && Parsers.Spaces1(ref scanner, result, out _) - ) - { - if (Tokens.Literal("in", ref scanner, advance: true) && Parsers.Spaces1(ref scanner, result, out _)) - { - if ( - ExpressionParser.Expression(ref scanner, result, out var collection, new(SDSLErrorMessages.SDSL0032, scanner[scanner.Position], scanner.Memory)) - && Parsers.Spaces0(ref scanner, result, out _) - ) - { - if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) - { - parsed = new(typeName, identifier, collection, statement, scanner[position..scanner.Position]); - return true; - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); - } - return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} - -public record struct WhileParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out While parsed, in ParseError? orError = null) - where TScanner : struct, IScanner - { - var position = scanner.Position; - if (Tokens.Literal("while", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) - { - if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (EffectStatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) - { - parsed = new(expression, statement, scanner[position..scanner.Position]); - return true; - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); - } - return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs index d9b663656a..12ba2d6e50 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -28,12 +28,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = p2; return true; } - else if (EffectControlsParser.Control(ref scanner, result, out var control)) + else if (ControlsParser.Control(ref scanner, result, out var control, Statement)) { parsed = control; return true; } - else if (Flow(ref scanner, result, out var flow)) + else if (FlowParsers.Flow(ref scanner, result, out var flow, Statement)) { parsed = flow; return true; @@ -65,8 +65,6 @@ public static bool UsingParams(ref TScanner scanner, ParseResult resul => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinParser().Match(ref scanner, result, out parsed, orError); - public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner - => new FlowParsers().Match(ref scanner, result, out parsed, orError); public static bool EffectBlock(ref TScanner scanner, ParseResult result, out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 689d891cdb..9f1d65e18f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -8,19 +8,23 @@ public record struct ControlsParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => Control(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParserDelegate statementParser, ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; if (ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributeList)) Parsers.Spaces0(ref scanner, result, out _); - if (If(ref scanner, result, out var ifstatement, orError) && Parsers.Spaces0(ref scanner, result, out _)) + if (If(ref scanner, result, out var ifstatement, statementParser, orError) && Parsers.Spaces0(ref scanner, result, out _)) { parsed = new(ifstatement, scanner[..]) { Attributes = attributeList }; - while (ElseIf(ref scanner, result, out var elseif, orError) && Parsers.Spaces0(ref scanner, result, out _)) + while (ElseIf(ref scanner, result, out var elseif, statementParser, orError) && Parsers.Spaces0(ref scanner, result, out _)) parsed.ElseIfs.Add(elseif); - if (Else(ref scanner, result, out var elseStatement, orError)) + if (Else(ref scanner, result, out var elseStatement, statementParser, orError)) parsed.Else = elseStatement; parsed.Info = scanner[position..scanner.Position]; return true; @@ -30,22 +34,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new IfStatementParser().Match(ref scanner, result, out parsed, orError); - public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ElseIfStatementParser().Match(ref scanner, result, out parsed, orError); - public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) + public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner - => new ElseStatementParser().Match(ref scanner, result, out parsed, orError); -} - - + => Control(ref scanner, result, out parsed, StatementParsers.Statement, orError); -public record struct IfStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out If parsed, in ParseError? orError = null) + public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -59,7 +52,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) + if (statementParser(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { parsed = new(condition, statement, scanner[position..scanner.Position]); return true; @@ -69,11 +62,12 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct ElseIfStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseIf parsed, in ParseError? orError = null) + public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => If(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -90,7 +84,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) + if (statementParser(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { parsed = new(condition, statement, scanner[position..scanner.Position]); return true; @@ -100,18 +94,19 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct ElseStatementParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out Else parsed, in ParseError? orError = null) + public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => ElseIf(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( Tokens.Literal("else", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)) + && statementParser(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory)) ) { parsed = new(statement, scanner[position..scanner.Position]); @@ -119,5 +114,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} + public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => Else(ref scanner, result, out parsed, StatementParsers.Statement, orError); +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 7233d0a200..9e45d21f1e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -9,24 +9,28 @@ public record struct FlowParsers : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => Flow(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParserDelegate statementParser, ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; var hasAttributes = ShaderAttributeListParser.Attribute(ref scanner, result, out var attribute) && Parsers.Spaces0(ref scanner, result, out _); if (!hasAttributes) scanner.Position = position; - if (While(ref scanner, result, out var w, orError)) + if (While(ref scanner, result, out var w, statementParser, orError)) { if (hasAttributes) w.Attribute = attribute; parsed = w; return true; } - else if (ForEach(ref scanner, result, out var fe, orError)) + else if (ForEach(ref scanner, result, out var fe, statementParser, orError)) { parsed = fe; return true; } - else if (For(ref scanner, result, out var f, orError)) + else if (For(ref scanner, result, out var f, statementParser, orError)) { if (hasAttributes) f.Attribute = attribute; @@ -36,22 +40,41 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new WhileParser().Match(ref scanner, result, out parsed, orError); - public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) + public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParseError? orError = null) where TScanner : struct, IScanner - => new ForEachParser().Match(ref scanner, result, out parsed, orError); - public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) - where TScanner : struct, IScanner - => new ForParser().Match(ref scanner, result, out parsed, orError); -} + => Flow(ref scanner, result, out parsed, StatementParsers.Statement, orError); + public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParserDelegate statementParser, ParseError? orError = null) + where TScanner : struct, IScanner + { + var position = scanner.Position; + if (Tokens.Literal("while", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) + { + if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + { + if (statementParser(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) + { + parsed = new(expression, statement, scanner[position..scanner.Position]); + return true; + } + } + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); + } + } + else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); + } + return Parsers.Exit(ref scanner, result, out parsed, position, orError); + } + public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => While(ref scanner, result, out parsed, StatementParsers.Statement, orError); -public record struct ForParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out For parsed, in ParseError? orError = null) + public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -91,7 +114,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o // parsing the block or statement - if (StatementParsers.Statement(ref scanner, result, out var body)) + if (statementParser(ref scanner, result, out var body)) { parsed = new For(init, condition, expressions!, body, scanner[position..scanner.Position]); return true; @@ -101,22 +124,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) where TScanner : struct, IScanner - { - var position = scanner.Position; - if (ExpressionParser.Expression(ref scanner, result, out var expression)) - { - parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); - return true; - } - return Parsers.Exit(ref scanner, result, out parsed, position, orError); - } -} + => For(ref scanner, result, out parsed, StatementParsers.Statement, orError); -public record struct ForEachParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out ForEach parsed, in ParseError? orError = null) + public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -140,7 +152,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) + if (statementParser(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) { parsed = new(typeName, identifier, collection, statement, scanner[position..scanner.Position]); return true; @@ -156,34 +168,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } -} -public record struct WhileParser : IParser -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out While parsed, in ParseError? orError = null) + public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) + where TScanner : struct, IScanner + => ForEach(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; - if (Tokens.Literal("while", ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) + if (ExpressionParser.Expression(ref scanner, result, out var expression)) { - if (Tokens.Char('(', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (ExpressionParser.Expression(ref scanner, result, out var expression, new(SDSLErrorMessages.SDSL0015, scanner[scanner.Position], scanner.Memory))) - { - if (Tokens.Char(')', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) - { - if (StatementParsers.Statement(ref scanner, result, out var statement, new(SDSLErrorMessages.SDSL0010, scanner[scanner.Position], scanner.Memory))) - { - parsed = new(expression, statement, scanner[position..scanner.Position]); - return true; - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0018, scanner[scanner.Position], scanner.Memory)); - } - } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0035, scanner[scanner.Position], scanner.Memory)); + parsed = new ExpressionStatement(expression, scanner[position..scanner.Position]); + return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } } - diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index 7bbedeb563..d300f0e631 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -43,12 +43,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new StatementParsers().Match(ref scanner, result, out parsed, orError); internal static bool Empty(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new EmptyStatementParser().Match(ref scanner, result, out parsed, orError); + internal static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) + where TScanner : struct, IScanner + => BlockStatementParser.Block(ref scanner, result, out parsed, statementParser, orError); internal static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new BlockStatementParser().Match(ref scanner, result, out parsed, orError); @@ -234,6 +237,10 @@ public record struct BlockStatementParser : IParser { public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + => Block(ref scanner, result, out parsed, StatementParsers.Statement, orError); + + public static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) + where TScanner : struct, IScanner { var position = scanner.Position; if (Tokens.Char('{', ref scanner, advance: true) && Parsers.Spaces0(ref scanner, result, out _)) @@ -242,7 +249,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o while (!scanner.IsEof && !Tokens.Char('}', ref scanner, advance: true)) { - if (StatementParsers.Statement(ref scanner, result, out var statement)) + if (statementParser(ref scanner, result, out var statement)) { block.Statements.Add(statement); Parsers.Spaces0(ref scanner, result, out _); From c6ea3e92d90a2b99e20919f15ad2181c4de61129 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 12:48:49 +0900 Subject: [PATCH 0931/1182] SDSL: Use spec-compliant UserTypeGOOGLE format for texture types --- .../Parsing/SDSL/AST/Shader.cs | 11 ++++++++++- .../Spirv/Building/SpirvContext.Types.cs | 15 ++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 30b097ae61..b77cf13746 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -71,7 +71,7 @@ void RegisterName(int target, string name) context.Names.Add(target, name); } - static SymbolType? ParseTextureReturnType(string s) => s switch + static SymbolType? ParseReturnType(string s) => s switch { "float" => ScalarType.Float, "float2" => new VectorType(ScalarType.Float, 2), @@ -88,6 +88,15 @@ void RegisterName(int target, string name) _ => null, }; + // Parse spec-compliant "texture2d:" format. + static SymbolType? ParseTextureReturnType(string s) + { + var colonIdx = s.IndexOf(':'); + if (colonIdx >= 0 && s.Length > colonIdx + 2 && s[colonIdx + 1] == '<' && s[^1] == '>') + return ParseReturnType(s[(colonIdx + 2)..^1]); + return null; + } + // Pre-pass: collect UserTypeGOOGLE decorations on texture types so we can // recover the exact ReturnType (e.g. float2) when reading OpTypeImage. var textureReturnTypes = new Dictionary(); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 924eb6eeca..61be9d6596 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -115,7 +115,20 @@ public int RegisterType(SymbolType type, int id) _ => throw new NotImplementedException($"Can't add type {type}") }; if (type is TextureType texType && instruction.HasValue) - Buffer.Add(new OpDecorateString(instruction.Value, Specification.Decoration.UserTypeGOOGLE, texType.ReturnType.ToId())); + { + var prefix = texType.Sampled == 2 ? "rw" : ""; + var dim = texType.Dimension switch + { + Specification.Dim.Dim1D => "texture1d", + Specification.Dim.Dim2D => "texture2d", + Specification.Dim.Dim3D => "texture3d", + Specification.Dim.Cube => "texturecube", + _ => throw new NotSupportedException($"Unsupported texture dimension {texType.Dimension}") + }; + var ms = texType.Multisampled ? "ms" : ""; + var array = texType.Arrayed ? "array" : ""; + Buffer.Add(new OpDecorateString(instruction.Value, Specification.Decoration.UserTypeGOOGLE, $"{prefix}{dim}{ms}{array}:<{texType.ReturnType.ToId()}>")); + } Types[type] = instruction ?? -1; ReverseTypes[instruction ?? -1] = type; From c52b8fd8a56be8bbb23ae6bbe195fda58ab86aaf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 14:34:24 +0900 Subject: [PATCH 0932/1182] SDSL: Fix UserTypeGOOGLE decoration loss during type deduplication in mixer --- .../SDSL/ShaderMixer.cs | 12 +- .../Spirv/Building/Context.ExtractBuffers.cs | 8 + .../Spirv/Processing/TypeDuplicatesRemover.cs | 8 + .../Stride.Shaders.Tests/StrideShaderTests.cs | 339 ++++++++++++++++++ 4 files changed, 366 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 585c8917b7..58ba1d698a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -426,8 +426,14 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } else { + // For OpTypeImage: find UserTypeGOOGLE decoration (already in context from earlier processing) + // so CheckForDuplicates can distinguish textures with different return types. + string? sourceUserTypeGOOGLE = null; + if (i2.Op == Op.OpTypeImage && i2.IdResult.HasValue) + sourceUserTypeGOOGLE = typeDuplicateInserter.FindUserTypeGOOGLE(i2.IdResult.Value); + // Check if type already exists in context (deduplicate them) - if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) + if (typeDuplicateInserter.CheckForDuplicates(i2, sourceUserTypeGOOGLE, out var existingInstruction)) { if (i2.IdResult is int id) { @@ -519,6 +525,10 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } } + // Re-sort decoration index after remapping changed target IDs in the buffer + if (remapIds.Count > 0) + typeDuplicateInserter.ResortDecorations(); + // Build ShaderInfo var shaderInfo = new ShaderInfo(mixinNode.Shaders.Count, shaderClass.ClassName, shaderStart, buffer.Count); shaderInfo.Symbol = shaderClass.Symbol; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index dcae084fd9..ed488d816c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -94,6 +94,14 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI i.Data.IdResult = resultId; typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + // For OpTypeImage: also insert the UserTypeGOOGLE decoration so it stays + // paired with the type during future deduplication in the mixer. + if (sourceUserTypeGOOGLE != null) + { + var dec = new OpDecorateString(resultId, Specification.Decoration.UserTypeGOOGLE, sourceUserTypeGOOGLE); + typeDuplicateInserter.InsertInstruction(instructionIndex++, new OpData(dec.InstructionMemory)); + } + lastResultId = resultId; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 332ad7ebb2..9119ab573e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -257,6 +257,14 @@ public void RemoveInstructionAt(int index, bool dispose) } } + /// + /// Re-sorts namesByOp after external mutations (e.g. RemapIds) that change target IDs in the buffer. + /// + public void ResortDecorations() + { + namesByOp.Sort(comparerSort); + } + private List GetTargetList(OpData data) { switch (data.Op) diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index 4b5dbb0626..6691cfd963 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -14,6 +14,340 @@ namespace Stride.Shaders.Parsers.Tests; public class StrideShaderTests { + [Fact] + public void TextureDecorateStringWarning() + { + var shaderSource = new ShaderMixinSource + { + Mixins = +{ +new ShaderClassSource("ShaderBase"), +new ShaderClassSource("ShadingBase"), +new ShaderClassSource("TransformationBase"), +new ShaderClassSource("NormalStream"), +new ShaderClassSource("TransformationWAndVP"), +new ShaderClassSource("NormalFromNormalMapping"), +new ShaderClassSource("MaterialSurfacePixelStageCompositor"), +}, + Compositions = +{ +["directLightGroups"] = new ShaderArraySource +{ +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("LightClusteredPointGroup")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("LightClusteredSpotGroup")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +["environmentLights"] = new ShaderArraySource +{ +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("LightSimpleAmbient")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("EnvironmentLight")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +["materialPixelStage"] = new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceArray")}, +Compositions = +{ +["layers"] = new ShaderArraySource +{ +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceDiffuse")}, +Compositions ={["diffuseMap"] = new ShaderClassSource("ComputeColorTextureScaledOffsetDynamicSampler","Material.DiffuseMap","TEXCOORD0","Material.Sampler.i0","rgba","Material.TextureScale","Material.TextureOffset")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceNormalMap","true","true")}, +Compositions ={["normalMap"] = new ShaderClassSource("ComputeColorTextureScaledOffsetDynamicSampler","Material.NormalMap","TEXCOORD0","Material.Sampler.i0","rgba","Material.TextureScale.i1","Material.TextureOffset.i1")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceGlossinessMap","false")}, +Compositions ={["glossinessMap"] = new ShaderClassSource("ComputeColorTextureScaledOffsetDynamicSampler","Material.GlossinessMap","TEXCOORD0","Material.Sampler.i0","r","Material.TextureScale.i2","Material.TextureOffset.i2")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceMetalness")}, +Compositions ={["metalnessMap"] = new ShaderClassSource("ComputeColorConstantFloatLink","Material.MetalnessValue")}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceLightingAndShading")}, +Compositions = +{ +["surfaces"] = new ShaderArraySource +{ +new ShaderClassSource("MaterialSurfaceShadingDiffuseLambert","false"), +new ShaderMixinSource +{ +Mixins ={new ShaderClassSource("MaterialSurfaceShadingSpecularMicrofacet")}, +Compositions = +{ +["environmentFunction"] = new ShaderClassSource("MaterialSpecularMicrofacetEnvironmentGGXLUT"), +["fresnelFunction"] = new ShaderClassSource("MaterialSpecularMicrofacetFresnelSchlick"), +["geometricShadowingFunction"] = new ShaderClassSource("MaterialSpecularMicrofacetVisibilitySmithSchlickGGX"), +["normalDistributionFunction"] = new ShaderClassSource("MaterialSpecularMicrofacetNormalDistributionGGX"), +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +["streamInitializerPixelStage"] = new ShaderMixinSource +{ +Mixins = +{ +new ShaderClassSource("MaterialStream"), +new ShaderClassSource("MaterialPixelShadingStream"), +}, +Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, +}, +}, + Macros = +{ +new ShaderMacro("STRIDE_RENDER_TARGET_COUNT", "1"), +new ShaderMacro("STRIDE_MULTISAMPLE_COUNT", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D", "1"), +new ShaderMacro("STRIDE_GRAPHICS_API_DIRECT3D11", "1"), +new ShaderMacro("STRIDE_GRAPHICS_PROFILE", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_1", "37120"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_2", "37376"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_9_3", "37632"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_0", "40960"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_10_1", "41216"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_0", "45056"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_1", "45312"), +new ShaderMacro("GRAPHICS_PROFILE_LEVEL_11_2", "45568"), +new ShaderMacro("class", "shader"), +}, + }; + + var logger = new Stride.Core.Diagnostics.LoggerResult(); + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), logger, out var bytecode, out var effectReflection, out _, out _); + + var warnings = logger.Messages + .Where(m => m.Type == Stride.Core.Diagnostics.LogMessageType.Warning && m.Text.Contains("Mismatched decorations")) + .Select(m => m.Text).ToList(); + Assert.Empty(warnings); + } + + [Fact] public void Tessellation() { @@ -186,6 +520,11 @@ public void Tessellation() }, }; + TestCore(shaderSource); + } + + private static void TestCore(ShaderMixinSource shaderSource) + { var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); From 2d048c6087e0f28c819a5e7396bd3d5d04d922b2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 19:21:08 +0900 Subject: [PATCH 0933/1182] SDSL: Fix for-loop condition parsing when space precedes semicolon --- .../SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 9e45d21f1e..5905fe3a4c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -98,7 +98,7 @@ public static bool For(ref TScanner scanner, ParseResult result, out F // Parsing the condition if (ExpressionParser.Expression(ref scanner, result, out condition) - && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), advance: true)) { } + && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true)) { } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0037, scanner[scanner.Position], scanner.Memory)); Parsers.Spaces0(ref scanner, result, out _); From 87cdf1f56bfd85cc9831bf919b6ead934698e425 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 13 Mar 2026 23:41:07 +0900 Subject: [PATCH 0934/1182] SDSL: Fix cbuffer initializer stores and set DefaultValue in reflection Uniform variables with initializers (e.g. stage float x = 2.0f) are now compiled as constants instead of wrapper functions. This avoids illegal stores to cbuffer members in the generated HLSL/SPIR-V, and allows extracting DefaultValue for EffectReflection. --- .../SDSL/ShaderMixer.CBuffers.cs | 8 ++++- .../SDSL/ShaderMixer.Reflection.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 35 ++++++++++++------- .../Interfaces/Analysis/StreamAnalyzer.cs | 4 +-- .../Generation/EntryPointWrapperGenerator.cs | 5 +++ .../Extensions/spirv.sdsl.grammar-ext.json | 2 +- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index ae2bf33874..d2284ea08a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -21,6 +21,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob var members = new List(); // Remap from variable ID to member index in our new struct var variables = new List(); + var methodInitializers = new List(); var variableToMemberIndices = new Dictionary(); // Collect any variable not a stream, not static and not a block int firstVariableIndex = -1; @@ -35,6 +36,7 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob variableToMemberIndices.Add(variable.ResultId, members.Count); members.Add(new(context.Names[variable.ResultId], variableType, TypeModifier.None)); variables.Add(variable.ResultId); + methodInitializers.Add(variable.MethodOrConstantInitializer); SetOpNop(i.Data.Memory.Span); } } @@ -53,7 +55,10 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob context.AddMemberName(globalCBufferTypeId, index, member.Name); var metadata = variableMetadata[variables[index]]; - memberMetadata[index] = new(Link: metadata.Link, LogicalGroup: metadata.LogicalGroup, Color: metadata.Color); + object? defaultValue = null; + if (methodInitializers[index] is int constantId) + context.TryGetConstantValue(constantId, out defaultValue, out _); + memberMetadata[index] = new(Link: metadata.Link, LogicalGroup: metadata.LogicalGroup, Color: metadata.Color, DefaultValue: defaultValue); } // Note: we make sure to add at a previous variable index, otherwise the OpVariableSDSL won't be inside the root MixinNode.StartInstruction/EndInstruction @@ -427,6 +432,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon Offset = constantBufferOffset, Size = memberSize, LogicalGroup = metadata.LogicalGroup, + DefaultValue = metadata.DefaultValue, }; if (metadata.Color) { diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 54123edf8a..7af2941478 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -11,7 +11,7 @@ namespace Stride.Shaders.Compilers.SDSL; public partial class ShaderMixer { private record struct VariableMetadata(string? Link = null, string? ResourceGroup = null, string? LogicalGroup = null, bool Color = false); - private record struct CBufferMemberMetadata(string? Link = null, string? LogicalGroup = null, bool Color = false); + private record struct CBufferMemberMetadata(string? Link = null, string? LogicalGroup = null, bool Color = false, object? DefaultValue = null); private Dictionary variableMetadata = new(); // Note: cbuffer might share same struct, which is why we store this info per variable instead of per struct (as per OpMemberDecorate was doing) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 82a86e2701..748d39d046 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -256,28 +256,39 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (StreamKind == StreamKind.Stream || StreamKind == StreamKind.PatchStream) variableFlags |= Specification.VariableFlagsMask.Stream; - int? initializerMethod = null; + int? initializerId = null; if (Value != null) { var valueType = pointerType.BaseType; - // TODO: differentiate const from code that needs to go in entry point? - // TODO: move to entry point - var functionType = new FunctionType(valueType, []); - initializerMethod = builder.Insert(new OpFunction(context.GetOrRegister(valueType), context.Bound++, Specification.FunctionControlMask.Const, context.GetOrRegister(functionType))).ResultId; - builder.Insert(new OpLabel(context.Bound++)); + if (pointerType.StorageClass == Specification.StorageClass.Uniform) + { + // Uniform variables become cbuffer members — their default values are set from the CPU side. + // Compile the initializer as a constant value (no function wrapper needed). + var constantValue = Value.CompileConstantValue(table, context, valueType); + initializerId = constantValue.Id; + } + else + { + // For other storage classes, wrap in an initializer method called from the entry point wrapper. + // This is necessary in case they can't be created as pure constant. + // TODO: some of them could become proper const, we could simplify those and use simpler system with constant ID (like StorageClass.Uniform) + var functionType = new FunctionType(valueType, []); + initializerId = builder.Insert(new OpFunction(context.GetOrRegister(valueType), context.Bound++, Specification.FunctionControlMask.Const, context.GetOrRegister(functionType))).ResultId; + builder.Insert(new OpLabel(context.Bound++)); - var initialValue = Value.CompileAsValue(table, compiler); - initialValue = builder.Convert(context, initialValue, pointerType.BaseType); + var initialValue = Value.CompileAsValue(table, compiler); + initialValue = builder.Convert(context, initialValue, pointerType.BaseType); - builder.Return(initialValue); - builder.Insert(new OpFunctionEnd()); + builder.Return(initialValue); + builder.Insert(new OpFunctionEnd()); - context.AddName(initializerMethod.Value, $"{Name}_Initializer"); + context.AddName(initializerId.Value, $"{Name}_Initializer"); + } } // Note: StorageClass was decided in Shader.Compile() - builder.Insert(new OpVariableSDSL(registeredType, variable, pointerType.StorageClass, variableFlags, initializerMethod)); + builder.Insert(new OpVariableSDSL(registeredType, variable, pointerType.StorageClass, variableFlags, initializerId)); if (Semantic != null) context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index 83026b3731..1d316f0aa6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -101,7 +101,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) { semanticTable.TryGetValue(variable.ResultId, out var semantic); - if (variable.MethodInitializer != null) + if (variable.MethodOrConstantInitializer != null) throw new NotImplementedException("Variable initializer is not supported on streams variable"); streams.Add(variable.ResultId, new StreamVariableInfo(semantic, name, type, variable.ResultId) { Patch = patchVariables.Contains(variable.ResultId) }); @@ -110,7 +110,7 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) { variables.Add(variable.ResultId, new VariableInfo(name, type, variable.ResultId) { - VariableMethodInitializerId = variable.MethodInitializer, + VariableMethodInitializerId = variable.MethodOrConstantInitializer, }); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 4c9f40f14c..1defaa04bc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -39,6 +39,11 @@ public static InterfaceProcessor.EntryPointInfo GenerateWrapper(SpirvContext con if (variable.Value.UsedThisStage && variable.Value.VariableMethodInitializerId is int methodInitializerId) { + // Skip initializer stores for Uniform variables — writing to a cbuffer is illegal + // in both SPIR-V and HLSL. These default values are set from the CPU side instead. + if (variable.Value.Type.StorageClass == Specification.StorageClass.Uniform) + continue; + liveAnalysis.ExtraReferencedMethods.Add(methodInitializerId); var variableValueType = variable.Value.Type.BaseType; diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index cc3c072993..ffb5c5c72c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -153,7 +153,7 @@ { "kind": "IdRef", "quantifier": "?", - "name": "'MethodInitializer'" + "name": "'MethodOrConstantInitializer'" } ] }, From bdb0315b1dd7a1cbc476bbad0e3adde406a9525a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 14 Mar 2026 20:03:48 +0900 Subject: [PATCH 0935/1182] SDSL: Generator: easier to understand error if missing files (need proper diagnostic later) --- .../SPVGenerator.Helpers.Preprocessing.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 34763c274b..04032e68f0 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -10,20 +10,27 @@ namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator { + static readonly string[] RequiredFiles = + [ + "spirv.core.grammar.json", + "spirv.sdsl.grammar-ext.json", + "extinst.glsl.std.450.grammar.json", + "SPIRV.html", + "GLSL.std.450.html" + ]; + public static bool IsSpirvSpecification(AdditionalText file) - => - Path.GetFileName(file.Path) switch - { - "spirv.core.grammar.json" - or "spirv.sdsl.grammar-ext.json" - or "extinst.glsl.std.450.grammar.json" - or "SPIRV.html" - or "GLSL.std.450.html" => true, - _ => false - }; + => Array.IndexOf(RequiredFiles, Path.GetFileName(file.Path)) >= 0; public SpirvGrammar PreProcessGrammar(ImmutableArray files, CancellationToken _) { + var fileNames = new HashSet(files.Select(f => Path.GetFileName(f.Path))); + var missing = RequiredFiles.Where(r => !fileNames.Contains(r)).ToArray(); + // TODO: Proper Roslyn diagnostics + if (missing.Length > 0) + throw new InvalidOperationException( + $"Missing SPIR-V specification files: {string.Join(", ", missing)}. Ensure git submodules are fetched (git submodule update --init)."); + SpirvGrammar grammar = new(); foreach (var file in files) { @@ -124,7 +131,11 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok // var buffer = new List(24); if (grammar.Instructions?.AsList() is List instructions) { - var extinst = instructions.First(x => x.OpName == "OpExtInst"); + var extinst = instructions.FirstOrDefault(x => x.OpName == "OpExtInst"); + if (extinst.OpName is null) + throw new InvalidOperationException( + "OpExtInst not found in SPIR-V grammar. Ensure git submodules are fetched (git submodule update --init). " + + $"Found {instructions.Count} instructions: [{string.Join(", ", instructions.Take(5).Select(x => x.OpName))}...]"); // Prebuilt for fast lookup var tableblocksCore = coreDoc!.QuerySelectorAll($"p.tableblock").ToArray(); var coreNodesById = new Dictionary(); From 5e682aedeec1fb0bcf4a2e6816e5657632238b34 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 14 Mar 2026 23:56:34 +0900 Subject: [PATCH 0936/1182] SDSL: Renamed mixinObjectId to effectInputHash --- .../Shaders.Compiler/RemoteEffectCompiler.cs | 2 +- .../Compiler/EffectCompilerBase.cs | 6 ++-- .../Compiler/EffectCompilerCache.cs | 36 +++++++++---------- .../Compiler/EffectCompilerChain.cs | 4 +-- .../Compiler/NullEffectCompiler.cs | 2 +- .../shaders/Stride.Shaders/EffectBytecode.cs | 4 +-- .../EffectCompilerServer.cs | 4 +-- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs b/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs index 13385a904d..2a8f63b49b 100644 --- a/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs +++ b/sources/engine/Stride.Engine/Shaders.Compiler/RemoteEffectCompiler.cs @@ -46,7 +46,7 @@ public override ObjectId GetShaderSourceHash(string type) } /// - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId effectInputHash) { return CompileAsync(mixinTree, effectParameters); } diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs index cdca95b7fa..e2f9c47597 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerBase.cs @@ -67,8 +67,8 @@ public CompilerResults Compile(ShaderSource shaderSource, CompilerParameters com // Compile the whole mixin tree var compilerResults = new CompilerResults { Module = $"EffectCompile [{mixinToCompile.Name}]" }; - var mixinObjectId = ShaderMixinObjectId.Compute(mixinToCompile, compilerParameters.EffectParameters); - var bytecode = Compile(mixinToCompile, effectParameters: compilerParameters.EffectParameters, compilerParameters, mixinObjectId); + var effectInputHash = ShaderMixinObjectId.Compute(mixinToCompile, compilerParameters.EffectParameters); + var bytecode = Compile(mixinToCompile, effectParameters: compilerParameters.EffectParameters, compilerParameters, effectInputHash); // Since bytecode.Result is a struct, we check if any of its member has been set to know if it's valid if (bytecode.Result.CompilationLog is not null || bytecode.Task is not null) @@ -91,7 +91,7 @@ public abstract TaskOrResult Compile( ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, - ObjectId mixinObjectId); + ObjectId effectInputHash); public static readonly string DefaultSourceShaderFolder = "shaders"; diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index df97b9d103..0e803af72e 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -61,10 +61,10 @@ public override void ResetCache(HashSet modifiedShaders) } } - public override TaskOrResult Compile(ShaderMixinSource mixin, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) + public override TaskOrResult Compile(ShaderMixinSource mixin, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId effectInputHash) { // Final url of the compiled bytecode - var compiledUrl = string.Format("{0}/{1}", CompiledShadersKey, mixinObjectId); + var compiledUrl = string.Format("{0}/{1}", CompiledShadersKey, effectInputHash); var bytecode = new KeyValuePair(null, EffectBytecodeCacheLoadSource.JustCompiled); lock (bytecodes) @@ -90,9 +90,9 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------------------------------------------------------------ // 2) Try to load from database cache // ------------------------------------------------------------------------------------------------------------ - if (bytecode.Key == null && database.ObjectDatabase.Exists(mixinObjectId)) + if (bytecode.Key == null && database.ObjectDatabase.Exists(effectInputHash)) { - using (var stream = database.ObjectDatabase.OpenStream(mixinObjectId)) + using (var stream = database.ObjectDatabase.OpenStream(effectInputHash)) { // We have an existing stream, make sure the shader is compiled var objectIdBuffer = new byte[ObjectId.HashSize]; @@ -115,7 +115,7 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------------------------------------------------------------ if (bytecode.Key == null) { - var appCachePath = GetAppCachePath(mixin.Name, mixinObjectId); + var appCachePath = GetAppCachePath(mixin.Name, effectInputHash); if (VirtualFileSystem.ApplicationCache.FileExists(appCachePath)) { try @@ -149,7 +149,7 @@ public override TaskOrResult Compile(ShaderMixinSo lock (compilingShaders) { Task compilingShaderTask; - if (compilingShaders.TryGetValue(mixinObjectId, out compilingShaderTask)) + if (compilingShaders.TryGetValue(effectInputHash, out compilingShaderTask)) { // Note: Task might still be compiling return compilingShaderTask; @@ -159,27 +159,27 @@ public override TaskOrResult Compile(ShaderMixinSo if (CompileEffectAsynchronously) { var compilerParametersCopy = compilerParameters != null ? new CompilerParameters(compilerParameters) : null; - var resultTask = Task.Factory.StartNew(() => CompileBytecode(mixin, effectParameters, compilerParametersCopy, mixinObjectId, database, compiledUrl), CancellationToken.None, TaskCreationOptions.None, taskSchedulerSelector != null ? taskSchedulerSelector(mixin, compilerParametersCopy.EffectParameters) : TaskScheduler.Default); + var resultTask = Task.Factory.StartNew(() => CompileBytecode(mixin, effectParameters, compilerParametersCopy, effectInputHash, database, compiledUrl), CancellationToken.None, TaskCreationOptions.None, taskSchedulerSelector != null ? taskSchedulerSelector(mixin, compilerParametersCopy.EffectParameters) : TaskScheduler.Default); - compilingShaders.Add(mixinObjectId, resultTask); + compilingShaders.Add(effectInputHash, resultTask); return resultTask; } else { - return CompileBytecode(mixin, effectParameters, compilerParameters, mixinObjectId, database, compiledUrl); + return CompileBytecode(mixin, effectParameters, compilerParameters, effectInputHash, database, compiledUrl); } } } - private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId, DatabaseFileProvider database, string compiledUrl) + private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId effectInputHash, DatabaseFileProvider database, string compiledUrl) { // Open the database for writing var log = new LoggerResult(); var effectLog = GlobalLogger.GetLogger("EffectCompilerCache"); // Note: this compiler is expected to not be async and directly write stuff in localLogger - var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters, mixinObjectId).WaitForResult(); + var compiledShader = base.Compile(mixinTree, effectParameters, compilerParameters, effectInputHash).WaitForResult(); compiledShader.CompilationLog.CopyTo(log); // If there are any errors, return immediately @@ -187,7 +187,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree { lock (compilingShaders) { - compilingShaders.Remove(mixinObjectId); + compilingShaders.Remove(effectInputHash); } log.CopyTo(effectLog); @@ -214,7 +214,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree if (CurrentCache == EffectBytecodeCacheLoadSource.DynamicCache) { // Persist to ApplicationCache (file-based, no ObjectDatabase index needed) - var appCachePath = GetAppCachePath(mixinTree.Name, mixinObjectId); + var appCachePath = GetAppCachePath(mixinTree.Name, effectInputHash); try { var dir = Path.GetDirectoryName(appCachePath)!; @@ -239,12 +239,12 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree memoryStream.SetLength(0); memoryStream.Write((byte[])newBytecodeId, 0, ObjectId.HashSize); memoryStream.Position = 0; - database.ObjectDatabase.Write(memoryStream, mixinObjectId, true); + database.ObjectDatabase.Write(memoryStream, effectInputHash, true); } if (!bytecodes.ContainsKey(newBytecodeId)) { - log.Verbose($"New effect compiled #{effectCompileCount} [{mixinObjectId}] (db: {newBytecodeId})\r\n{compilerParameters?.ToStringPermutationsDetailed()}"); + log.Verbose($"New effect compiled #{effectCompileCount} [{effectInputHash}] (db: {newBytecodeId})\r\n{compilerParameters?.ToStringPermutationsDetailed()}"); Interlocked.Increment(ref effectCompileCount); // Replace or add new bytecode @@ -254,7 +254,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree lock (compilingShaders) { - compilingShaders.Remove(mixinObjectId); + compilingShaders.Remove(effectInputHash); } log.CopyTo(effectLog); @@ -341,8 +341,8 @@ private bool IsBytecodeObsolete(EffectBytecode bytecode) public static string GetEffectCacheDirectory(string mixinName) => $"effects/{SanitizeMixinName(mixinName)}"; - public static string GetAppCachePath(string mixinName, ObjectId mixinObjectId) - => $"{GetEffectCacheDirectory(mixinName)}/{mixinObjectId}"; + public static string GetAppCachePath(string mixinName, ObjectId effectInputHash) + => $"{GetEffectCacheDirectory(mixinName)}/{effectInputHash}"; public static string SanitizeMixinName(string name) { diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs index e5b16f996e..2e657ff6eb 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerChain.cs @@ -50,9 +50,9 @@ public override void ResetCache(HashSet modifiedShaders) compiler.ResetCache(modifiedShaders); } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId effectInputHash) { - return compiler.Compile(mixinTree, effectParameters, compilerParameters, mixinObjectId); + return compiler.Compile(mixinTree, effectParameters, compilerParameters, effectInputHash); } } } diff --git a/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs b/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs index 4774f16a88..a5656f453e 100644 --- a/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs +++ b/sources/shaders/Stride.Shaders/Compiler/NullEffectCompiler.cs @@ -29,7 +29,7 @@ public override ObjectId GetShaderSourceHash(string type) public override IVirtualFileProvider FileProvider { get; set; } - public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId mixinObjectId) + public override TaskOrResult Compile(ShaderMixinSource mixinTree, EffectCompilerParameters effectParameters, CompilerParameters compilerParameters, ObjectId effectInputHash) { throw new NotSupportedException("Shader Compilation is not allowed at run time on this platform."); } diff --git a/sources/shaders/Stride.Shaders/EffectBytecode.cs b/sources/shaders/Stride.Shaders/EffectBytecode.cs index 9e9342786d..1bf3f56c36 100644 --- a/sources/shaders/Stride.Shaders/EffectBytecode.cs +++ b/sources/shaders/Stride.Shaders/EffectBytecode.cs @@ -42,9 +42,9 @@ public sealed class EffectBytecode /// - /// Computes a unique identifier for the Effect bytecode. + /// Computes a hash of the compiled effect bytecode output (stages + reflection). /// - /// An unique for the Effect bytecode. + /// A content-based for the compiled effect bytecode output. public ObjectId ComputeId() { var effectBytecode = this; diff --git a/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs b/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs index 03d135826b..d16f7a1acc 100644 --- a/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs +++ b/sources/tools/Stride.EffectCompilerServer/EffectCompilerServer.cs @@ -104,8 +104,8 @@ private static async Task ShaderCompilerRequestHandler(SocketMessageLayer socket Console.WriteLine($"Compiling shader: {remoteEffectCompilerEffectRequest.MixinTree.Name}"); // A shader has been requested, compile it (asynchronously)! - var mixinObjectId = ShaderMixinObjectId.Compute(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters); - var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters, null, mixinObjectId).AwaitResult(); + var effectInputHash = ShaderMixinObjectId.Compute(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters); + var precompiledEffectShaderPass = await effectCompiler.Compile(remoteEffectCompilerEffectRequest.MixinTree, remoteEffectCompilerEffectRequest.EffectParameters, null, effectInputHash).AwaitResult(); // Send compiled shader await socketMessageLayer.Send(new RemoteEffectCompilerEffectAnswer From 573d930159934793ae1ea7ef183e16576aaa67d8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 14 Mar 2026 23:57:30 +0900 Subject: [PATCH 0937/1182] SDSL: fix bug when multiple cbuffer were merged and the first one had a LogicalGroup (thanks @johang88 for the repro) --- sources/engine/Stride.Graphics/ResourceBinder.cs | 2 ++ .../Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs | 8 ++++++-- .../SDSL/ShaderMixer.Reflection.cs | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sources/engine/Stride.Graphics/ResourceBinder.cs b/sources/engine/Stride.Graphics/ResourceBinder.cs index 6a4cc71e52..fcb7044e88 100644 --- a/sources/engine/Stride.Graphics/ResourceBinder.cs +++ b/sources/engine/Stride.Graphics/ResourceBinder.cs @@ -151,6 +151,8 @@ private struct BindingOperation public ShaderStage Stage; public int SlotStart; public SamplerState ImmutableSampler; + + public string ToString() => $"DescriptorEntry [{EntryIndex}] => {Stage} {Class} {SlotStart}"; } } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index d2284ea08a..1328f52ea1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -1,4 +1,4 @@ -using CommunityToolkit.HighPerformance.Buffers; +using CommunityToolkit.HighPerformance.Buffers; using Stride.Core.Extensions; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -201,7 +201,6 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.VariableId])); // This helper method will transfer decorations from the old structure to the new merged structure - // Also, it will add a default "Link" decoration if none was set void ProcessDecorations(Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) { var cbufferStructId = context.Types[cbufferStruct]; @@ -309,6 +308,7 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData // Update first variable to use new type cbuffersSpan[0].Variable.Data.IdResultType = mergedCbufferPtrStructId; cbufferMemberMetadata[cbuffersSpan[0].VariableId] = GenerateCBufferLinks(cbuffersSpan[0].VariableId, cbuffersSpan, mergedCbufferStruct); + foreach (var i in buffer) { if (i.Op == Op.OpName && (OpName)i is { } name) @@ -337,6 +337,10 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData // Also, if we do so, maybe we could do it as part of a global pass at the end rather than now? } } + + // Clear variable-level LogicalGroup: cbuffer resource doesn't belong to a single logical group (only its members do) + if (variableMetadata.TryGetValue(cbuffersSpan[0].VariableId, out var mergedVarMetadata)) + variableMetadata[cbuffersSpan[0].VariableId] = mergedVarMetadata with { LogicalGroup = null }; } SpirvBuilder.RemapIds(buffer, 0, buffer.Count, idRemapping); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 7af2941478..e1b9250789 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -123,6 +123,8 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) variableMetadata[variableInstruction.ResultId] = metadata; + // Build per-member metadata for cbuffers: resolve link names (from decorations or generated from shader/member name), + // compose with composition path for non-stage variables, and propagate the cbuffer's LogicalGroup to each member. if (variableType is ConstantBufferSymbol cb) { var constantBufferStructId = context.Types[cb]; From 30903061082481169a0813cae58134218cda5370 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 15 Mar 2026 00:53:52 +0900 Subject: [PATCH 0938/1182] SDSL: Reorganized cache to have an extra indirection when a bytecode is shared. Also added ShaderSource in C# format in meta.hlsl --- .../EffectCompiler.cs | 136 ++++++++++-------- .../Compiler/EffectCompilerCache.cs | 74 +++++++--- .../shaders/Stride.Shaders/EffectBytecode.cs | 1 + .../Stride.Shaders/ShaderSourceToCode.cs | 2 +- 4 files changed, 133 insertions(+), 80 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 7148e32efa..db49c3ba8f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -171,25 +171,13 @@ public override TaskOrResult Compile(ShaderMixinSo }*/ // ------------------------------------------------------- - // Save shader log to DynamicCache folder + // Prepare DynamicCache folder for debug files (written after compilation using output hash) #if STRIDE_PLATFORM_DESKTOP var effectDir = Path.Combine( PlatformFolders.ApplicationCacheDirectory, EffectCompilerCache.GetEffectCacheDirectory(fullEffectName)); if (!Directory.Exists(effectDir)) Directory.CreateDirectory(effectDir); - var shaderBaseFilename = Path.Combine(effectDir, mixinObjectId.ToString()); - lock (WriterLock) // protect write in case the same shader is created twice - { - // Write shader before generating to make sure that we are having a trace before compiling it (compiler may crash...etc.) - if (!File.Exists(shaderBaseFilename + ".spv")) - { - File.WriteAllBytes(shaderBaseFilename + ".spv", spirvBytecode); - File.WriteAllText(shaderBaseFilename + ".spvdis", Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); - } - } -#else - string shaderBaseFilename = null; #endif // Select the correct backend compiler @@ -218,6 +206,7 @@ public override TaskOrResult Compile(ShaderMixinSo #if STRIDE_PLATFORM_DESKTOP var stageStringBuilder = new StringBuilder(); + var stageHlslSources = new List<(string Suffix, string Code)>(); #endif var bytecode = new EffectBytecode { Reflection = effectReflection, HashSources = usedHashSources }; @@ -252,11 +241,8 @@ public override TaskOrResult Compile(ShaderMixinSo ShaderStage.Pixel => "ps", ShaderStage.Compute => "cs", }; - var stageFilename = $"{shaderBaseFilename}_{stageSuffix}.hlsl"; - lock (WriterLock) - { - File.WriteAllText(stageFilename, code); - } + stageHlslSources.Add((stageSuffix, code)); + string stageFilename = null; #else string stageFilename = null; #endif @@ -354,65 +340,95 @@ public override TaskOrResult Compile(ShaderMixinSo bytecode.Stages = shaderStageBytecodes.ToArray(); + // ------------------------------------------------------- + // Write debug files using output hash (content-addressed, shared across inputs with same output) #if STRIDE_PLATFORM_DESKTOP + var outputHash = bytecode.ComputeId(); + var shaderBaseFilename = Path.Combine(effectDir, outputHash.ToString()); lock (WriterLock) // protect write in case the same shader is created twice { - var builder = new StringBuilder(); - builder.AppendLine("/**************************"); - builder.AppendLine("***** Compiler Parameters *****"); - builder.AppendLine("***************************"); - builder.Append("@P EffectName: "); - builder.AppendLine(fullEffectName ?? ""); - builder.Append(compilerParameters?.ToStringPermutationsDetailed()); - builder.AppendLine("***************************"); - - if (bytecode.Reflection.ConstantBuffers.Count > 0) + // Write SPV, disassembly and ShaderSource (skip if already written by another input with same output) + if (!File.Exists(shaderBaseFilename + ".spv")) + { + File.WriteAllBytes(shaderBaseFilename + ".spv", spirvBytecode); + File.WriteAllText(shaderBaseFilename + ".spvdis", Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); + } + + // Write per-stage HLSL + foreach (var (suffix, hlslCode) in stageHlslSources) { - builder.AppendLine("**** ConstantBuffers ****"); + var stageFile = $"{shaderBaseFilename}_{suffix}.hlsl"; + if (!File.Exists(stageFile)) + File.WriteAllText(stageFile, hlslCode); + } + + if (!File.Exists(shaderBaseFilename + "_meta.txt")) + { + var builder = new StringBuilder(); + builder.AppendLine("/**************************"); + builder.AppendLine("***** Compiler Parameters *****"); + builder.AppendLine("***************************"); + builder.Append("@P EffectName: "); + builder.AppendLine(fullEffectName ?? ""); + builder.Append(compilerParameters?.ToStringPermutationsDetailed()); + builder.AppendLine("***************************"); + builder.AppendLine("**** Shader Source ****"); + builder.AppendLine("***************************"); + builder.AppendLine("// ShaderSource in C# that generated this EffectBytecode. You can copy-psate it to reproduce it easily in a unit test."); + builder.AppendLine("// Note: Other slightly different ShaderSource inputs might produce the same EffectBytecode, only first one is saved here."); + builder.Append("var shaderSource = "); + builder.AppendLine(mixinTree.ToCode()); builder.AppendLine("***************************"); - foreach (var cBuffer in bytecode.Reflection.ConstantBuffers) + + + if (bytecode.Reflection.ConstantBuffers.Count > 0) { - builder.AppendFormat("cbuffer {0} [Size: {1}]", cBuffer.Name, cBuffer.Size).AppendLine(); - foreach (var parameter in cBuffer.Members) + builder.AppendLine("**** ConstantBuffers ****"); + builder.AppendLine("***************************"); + foreach (var cBuffer in bytecode.Reflection.ConstantBuffers) { - builder.AppendFormat("@C {0} => {1} [LogicalGroup: {2}]", parameter.RawName, parameter.KeyInfo.KeyName, parameter.LogicalGroup).AppendLine(); + builder.AppendFormat("cbuffer {0} [Size: {1}]", cBuffer.Name, cBuffer.Size).AppendLine(); + foreach (var parameter in cBuffer.Members) + { + builder.AppendFormat("@C {0} => {1} [LogicalGroup: {2}]", parameter.RawName, parameter.KeyInfo.KeyName, parameter.LogicalGroup).AppendLine(); + } } + builder.AppendLine("***************************"); } - builder.AppendLine("***************************"); - } - if (bytecode.Reflection.ResourceBindings.Count > 0) - { - builder.AppendLine("****** Resources ******"); - builder.AppendLine("***************************"); - foreach (var resource in bytecode.Reflection.ResourceBindings) + if (bytecode.Reflection.ResourceBindings.Count > 0) { - builder.AppendFormat("@R {0} => {1} [LogicalGroup: {2} Stage: {3}, Slot: ({4}-{5})]", resource.RawName, resource.KeyInfo.KeyName, resource.LogicalGroup, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine(); + builder.AppendLine("****** Resources ******"); + builder.AppendLine("***************************"); + foreach (var resource in bytecode.Reflection.ResourceBindings) + { + builder.AppendFormat("@R {0} => {1} [LogicalGroup: {2} Stage: {3}, Slot: ({4}-{5})]", resource.RawName, resource.KeyInfo.KeyName, resource.LogicalGroup, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine(); + } + builder.AppendLine("***************************"); } - builder.AppendLine("***************************"); - } - if (bytecode.HashSources.Count > 0) - { - builder.AppendLine("***** Sources *****"); - builder.AppendLine("***************************"); - foreach (var hashSource in bytecode.HashSources) + if (bytecode.HashSources.Count > 0) { - builder.AppendFormat("@S {0} => {1}", hashSource.Key, hashSource.Value).AppendLine(); + builder.AppendLine("***** Sources *****"); + builder.AppendLine("***************************"); + foreach (var hashSource in bytecode.HashSources) + { + builder.AppendFormat("@S {0} => {1}", hashSource.Key, hashSource.Value).AppendLine(); + } + builder.AppendLine("***************************"); } - builder.AppendLine("***************************"); - } - if (bytecode.Stages.Length > 0) - { - builder.AppendLine("***** Stages *****"); - builder.AppendLine("***************************"); - builder.Append(stageStringBuilder); - builder.AppendLine("***************************"); - } - builder.AppendLine("*************************/"); + if (bytecode.Stages.Length > 0) + { + builder.AppendLine("***** Stages *****"); + builder.AppendLine("***************************"); + builder.Append(stageStringBuilder); + builder.AppendLine("***************************"); + } + builder.AppendLine("*************************/"); - File.WriteAllText(shaderBaseFilename + "_meta.hlsl", builder.ToString()); + File.WriteAllText(shaderBaseFilename + "_meta.txt", builder.ToString()); + } } #endif diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index 0e803af72e..ba15e7634a 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -112,27 +112,45 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------------------------------------------------------------ // 2.5) Try to load from application cache (DynamicCache entries) + // Uses indirection: {effectInputHash}.cache contains the output hash, + // then {outputHash} contains the actual bytecode (shared across inputs with same output). // ------------------------------------------------------------------------------------------------------------ if (bytecode.Key == null) { - var appCachePath = GetAppCachePath(mixin.Name, effectInputHash); - if (VirtualFileSystem.ApplicationCache.FileExists(appCachePath)) + var indirectionPath = GetAppCacheIndirectionPath(mixin.Name, effectInputHash); + if (VirtualFileSystem.ApplicationCache.FileExists(indirectionPath)) { try { - using var stream = VirtualFileSystem.ApplicationCache.OpenStream( - appCachePath, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read); - var loadedBytecode = EffectBytecode.FromStream(stream); - if (loadedBytecode != null && !IsBytecodeObsolete(loadedBytecode)) + // Read the output hash from the indirection file + ObjectId outputHash; + using (var indirStream = VirtualFileSystem.ApplicationCache.OpenStream( + indirectionPath, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read)) { - bytecode = new KeyValuePair( - loadedBytecode, EffectBytecodeCacheLoadSource.DynamicCache); - bytecodes[loadedBytecode.ComputeId()] = bytecode; + var outputHashBuffer = new byte[ObjectId.HashSize]; + if (indirStream.Read(outputHashBuffer, 0, ObjectId.HashSize) != ObjectId.HashSize) + throw new InvalidOperationException("Truncated cache indirection file"); + outputHash = new ObjectId(outputHashBuffer); + } + + // Load bytecode from the shared output file + var bytecodePath = GetAppCachePath(mixin.Name, outputHash); + if (VirtualFileSystem.ApplicationCache.FileExists(bytecodePath)) + { + using var stream = VirtualFileSystem.ApplicationCache.OpenStream( + bytecodePath, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read); + var loadedBytecode = EffectBytecode.FromStream(stream); + if (loadedBytecode != null && !IsBytecodeObsolete(loadedBytecode)) + { + bytecode = new KeyValuePair( + loadedBytecode, EffectBytecodeCacheLoadSource.DynamicCache); + bytecodes[outputHash] = bytecode; + } } } catch (Exception ex) { - Log.Warning($"Failed to load effect bytecode from application cache '{appCachePath}': {ex.Message}"); + Log.Warning($"Failed to load effect bytecode from application cache: {ex.Message}"); } } } @@ -213,20 +231,35 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree if (CurrentCache == EffectBytecodeCacheLoadSource.DynamicCache) { - // Persist to ApplicationCache (file-based, no ObjectDatabase index needed) - var appCachePath = GetAppCachePath(mixinTree.Name, effectInputHash); + // Persist to ApplicationCache with content-addressed dedup: + // {effectInputHash}.cache → 16-byte output hash (indirection) + // {outputHash} → EffectBytecode (shared across inputs with same output) + var bytecodePath = GetAppCachePath(mixinTree.Name, newBytecodeId); + var indirectionPath = GetAppCacheIndirectionPath(mixinTree.Name, effectInputHash); try { - var dir = Path.GetDirectoryName(appCachePath)!; + var dir = Path.GetDirectoryName(bytecodePath)!; if (!string.IsNullOrEmpty(dir) && !VirtualFileSystem.ApplicationCache.DirectoryExists(dir)) VirtualFileSystem.ApplicationCache.CreateDirectory(dir); - using var appStream = VirtualFileSystem.ApplicationCache.OpenStream( - appCachePath, VirtualFileMode.Create, VirtualFileAccess.Write); - memoryStream.CopyTo(appStream); + + // Write bytecode (skip if already exists — another input already wrote the same output) + if (!VirtualFileSystem.ApplicationCache.FileExists(bytecodePath)) + { + using var appStream = VirtualFileSystem.ApplicationCache.OpenStream( + bytecodePath, VirtualFileMode.Create, VirtualFileAccess.Write); + memoryStream.CopyTo(appStream); + } + + // Write indirection file (always, maps this input to its output) + using (var indirStream = VirtualFileSystem.ApplicationCache.OpenStream( + indirectionPath, VirtualFileMode.Create, VirtualFileAccess.Write)) + { + indirStream.Write((byte[])newBytecodeId, 0, ObjectId.HashSize); + } } catch (Exception ex) { - Log.Warning($"Failed to save effect bytecode to application cache '{appCachePath}': {ex.Message}"); + Log.Warning($"Failed to save effect bytecode to application cache: {ex.Message}"); } } else @@ -341,8 +374,11 @@ private bool IsBytecodeObsolete(EffectBytecode bytecode) public static string GetEffectCacheDirectory(string mixinName) => $"effects/{SanitizeMixinName(mixinName)}"; - public static string GetAppCachePath(string mixinName, ObjectId effectInputHash) - => $"{GetEffectCacheDirectory(mixinName)}/{effectInputHash}"; + public static string GetAppCachePath(string mixinName, ObjectId hash) + => $"{GetEffectCacheDirectory(mixinName)}/{hash}.sdfxbc"; + + public static string GetAppCacheIndirectionPath(string mixinName, ObjectId effectInputHash) + => $"{GetEffectCacheDirectory(mixinName)}/{effectInputHash}.cache"; public static string SanitizeMixinName(string name) { diff --git a/sources/shaders/Stride.Shaders/EffectBytecode.cs b/sources/shaders/Stride.Shaders/EffectBytecode.cs index 1bf3f56c36..fa590bdb99 100644 --- a/sources/shaders/Stride.Shaders/EffectBytecode.cs +++ b/sources/shaders/Stride.Shaders/EffectBytecode.cs @@ -40,6 +40,7 @@ public sealed class EffectBytecode /// public ShaderBytecode[] Stages; + public override string ToString() => $"EffectBytecode {ComputeId()}"; /// /// Computes a hash of the compiled effect bytecode output (stages + reflection). diff --git a/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs b/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs index c6c67d9380..e41558658f 100644 --- a/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs +++ b/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs @@ -10,7 +10,7 @@ namespace Stride.Shaders /// /// Generates C# code to easily recreate a specific (i.e. for a unit test). /// - internal static class ShaderSourceToCode + public static class ShaderSourceToCode { public static string ToCode(this ShaderSource source) { From de0e1bc7c42b0e1bd078939f5012dca8cce991d8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 16 Mar 2026 18:28:19 +0900 Subject: [PATCH 0939/1182] SDSL: Better error reporting (and forbid Consume/AppendStructuredBuffer) --- .../EffectCompiler.cs | 3 + .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 121 ++++++++---------- .../SDSL/ShaderMixer.cs | 28 +++- .../ShaderLoaderBase.cs | 24 +++- .../EffectCodeWriter.cs | 4 +- .../Parsing/SDSL/AST/Shader.cs | 5 + .../SDSL/AST/ShaderElements.MethodOrMember.cs | 17 ++- .../Stride.Shaders.Tests/RenderingTests.cs | 9 +- .../Stride.Shaders.Tests/StrideShaderTests.cs | 19 +-- 9 files changed, 137 insertions(+), 93 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index db49c3ba8f..e3eccf625d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -145,6 +145,9 @@ public override TaskOrResult Compile(ShaderMixinSo var shaderMixer = new ShaderMixer(GetFileShaderLoader()); shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); + if (log.HasErrors) + return new EffectBytecodeCompilerResult(null, log); + /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); // Copy log from parser results to output diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 6b9ad8d9f1..f2878bbe5f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -9,6 +9,7 @@ using Stride.Shaders.Spirv.Tools; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using Stride.Core.Diagnostics; using Stride.Core.Storage; using Stride.Shaders.Parsing.SDFX.AST; @@ -16,92 +17,76 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string filename, string code, ObjectId hash, ReadOnlySpan macros, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) + public readonly bool Compile(string filename, string code, ObjectId hash, ReadOnlySpan macros, ILogger log, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) { - var parsed = SDSLParser.Parse(code); lastBuffer = default; + + var parsed = SDSLParser.Parse(code); if (parsed.Errors.Count > 0) { - throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, parsed.Errors)}"); + foreach (var error in parsed.Errors) + log.Error(error.ToString()); + return false; } - if (parsed.AST is ShaderFile sf) + if (parsed.AST is not ShaderFile sf) + return false; + + // TODO: support namespace + var declarations = sf.Namespaces.SelectMany(x => x.Declarations).Concat(sf.RootDeclarations); + foreach (var declaration in declarations) { - // TODO: support namespace - var declarations = sf.Namespaces.SelectMany(x => x.Declarations).Concat(sf.RootDeclarations); - foreach (var declaration in declarations) + if (declaration is ShaderClass shader) { - if (declaration is ShaderClass shader) + var compiler = new CompilerUnit(); + SymbolTable table = new(compiler.Context) { - var compiler = new CompilerUnit(); - SymbolTable table = new(compiler.Context) - { - ShaderLoader = ShaderLoader, - CurrentMacros = [.. macros], - }; - - // Add OpSource - var filenameId = compiler.Context.Add(new OpString(compiler.Context.Bound++, filename)).ResultId; - // TODO: Add SourceLanguage.SDSL - compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, null)); - compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); - // TODO: Do we want to record macros with a custom OpMacroSDSL? (mostly for debug purposes) + ShaderLoader = ShaderLoader, + CurrentMacros = [.. macros], + }; - compiler.Macros.AddRange(macros); - shader.Compile(table, compiler); + // Add OpSource + var filenameId = compiler.Context.Add(new OpString(compiler.Context.Bound++, filename)).ResultId; + // TODO: Add SourceLanguage.SDSL + compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, null)); + compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); + // TODO: Do we want to record macros with a custom OpMacroSDSL? (mostly for debug purposes) - if (table.Errors.Count > 0) - throw new Exception($"Some parse errors:{Environment.NewLine}{string.Join(Environment.NewLine, table.Errors)}"); - - lastBuffer = compiler.ToShaderBuffers(); - ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); - } - else if (declaration is ShaderEffect or EffectParameters) + compiler.Macros.AddRange(macros); + bool hasErrors = false; + try { - // Ignore (using C# codegen for now) - + shader.Compile(table, compiler); } - // Compiling SDFX to SPIR-V is not supported (we might switch to it in the future instead of using C# codegen) - /*else if (declaration is ShaderEffect effect) + catch (Exception e) { - var compiler = new CompilerUnit(); - SymbolTable table = new(compiler.Context) - { - ShaderLoader = ShaderLoader, - CurrentMacros = [..macros], - }; - compiler.Macros.AddRange(macros); - effect.Compile(table, compiler); - - lastBuffer = compiler.ToShaderBuffers(); - ShaderLoader.FileCache.RegisterShader(effect.Name, macros, lastBuffer, hash); + log.Error(e.Message, e); + hasErrors = true; } - else if (declaration is EffectParameters parameters) - { - var compiler = new CompilerUnit(); - SymbolTable table = new(compiler.Context) - { - ShaderLoader = ShaderLoader, - CurrentMacros = [..macros], - }; - compiler.Macros.AddRange(macros); - parameters.Compile(table, compiler); - lastBuffer = compiler.ToShaderBuffers(); - - ShaderLoader.FileCache.RegisterShader(parameters.Name, [], lastBuffer, hash); - }*/ - else + if (table.Errors.Count > 0) { - throw new NotImplementedException($"Compiling declaration [{declaration.GetType()}] is not implemented"); + foreach (var error in table.Errors) + log.Error(error.ToString()); + hasErrors = true; } - } - return lastBuffer != null; - } - else - { - lastBuffer = default; - return false; + if (hasErrors) + return false; + + lastBuffer = compiler.ToShaderBuffers(); + ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); + } + else if (declaration is ShaderEffect or EffectParameters) + { + // Ignore (using C# codegen for now) + } + else + { + log.Error($"Compiling declaration [{declaration.GetType()}] is not implemented"); + return false; + } } + + return lastBuffer != null; } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 58ba1d698a..69f666a7e4 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -29,6 +29,11 @@ public record struct Options(bool ResourcesRegisterSeparate); public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List entryPoints) { + bytecode = default; + effectReflection = default; + usedHashSources = default; + entryPoints = default; + // Create new buffer for the merged result var temp = new SpirvBuffer(); @@ -37,6 +42,8 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o context.Add(new OpCapability(Capability.Shader)); context.Add(new OpExtension("SPV_GOOGLE_user_type")); context.Add(new OpMemoryModel(AddressingModel.Logical, MemoryModel.GLSL450)); + if (ShaderLoader is ShaderLoaderBase shaderLoaderBase) + shaderLoaderBase.Log = log; var shaderLoader = new CaptureLoadedShaders(ShaderLoader); var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; @@ -59,7 +66,24 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o // Process name and types imported by constants due to generics instantiation ShaderClass.ProcessNameAndTypes(context); - var rootMixin = MergeMixinNode(globalContext, context, temp, shaderSource2); + MixinNode rootMixin; + try + { + rootMixin = MergeMixinNode(globalContext, context, temp, shaderSource2); + } + catch (Exception e) + { + log.Error(e.Message, e); + return; + } + + // If any semantic errors were collected during shader compilation, stop mixing + if (table.Errors.Count > 0) + { + foreach (var error in table.Errors) + log.Error(error.Message); + return; + } // Add optional capabilities foreach (var i in context) @@ -827,7 +851,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte // Process member call (composition) if (!instanceMixinGroup.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId) && (instanceMixinGroup.Stage == null || !instanceMixinGroup.Stage.MethodGroupsByName.TryGetValue((function.Name, functionType), out functionId))) - throw new InvalidOperationException($"Can't find function ID for {context.Names[functionId]}"); + throw new InvalidOperationException($"Can't find function {function.Name} in current mixin"); } bool foundInStage = false; diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index c1a1f2e0d2..3d04f18820 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -1,3 +1,5 @@ +using Stride.Core.Diagnostics; +using Stride.Core.Storage; using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; using Stride.Shaders.Spirv.Building; @@ -6,7 +8,6 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; -using Stride.Core.Storage; namespace Stride.Shaders.Compilers; @@ -14,6 +15,11 @@ public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShader { public IShaderCache Cache => fileCache; + /// + /// Optional logger for compilation errors. If not set, errors are thrown as exceptions. + /// + public ILogger? Log { get; set; } + public bool Exists(string name) { if (Cache.Exists(name)) @@ -43,6 +49,9 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ if (!LoadFromCode(filename, code, hash, defines, out buffer)) { + // If a logger is set, errors are already logged — just return false + if (Log != null) + return false; throw new InvalidOperationException($"Shader {name} could not be compiled"); } @@ -60,6 +69,9 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan m.Type >= LogMessageType.Error).Select(m => m.Text))); + return false; + } + return true; } } diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index 84734abe0d..fb349a0570 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -112,7 +112,7 @@ protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Ident parameterType = a.BaseType; } - if (parameterType is ShaderSymbol or TextureType or BufferType or StructuredBufferType or ByteAddressBufferType or SamplerType) + if (parameterType is ShaderSymbol or TextureType or BufferType or StructuredBufferType or AppendStructuredBufferType or ConsumeStructuredBufferType or ByteAddressBufferType or SamplerType) { parameterKeyType = "Object"; } @@ -415,7 +415,7 @@ public override void VisitTypeName(TypeName typeName) { Write("Matrix"); } - else if (typeName.Type is BufferType or StructuredBufferType or ByteAddressBufferType) + else if (typeName.Type is BufferType or StructuredBufferType or AppendStructuredBufferType or ConsumeStructuredBufferType or ByteAddressBufferType) { Write("Buffer"); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index b77cf13746..2efcfbd14c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -557,6 +557,11 @@ public void Compile(SymbolTable table, CompilerUnit compiler) // (SPIR-V allow forward calling) foreach (var method in Elements.OfType()) method.ProcessSymbol(table, context); + + // If any errors occurred during symbol processing, skip method body analysis and compilation + if (table.Errors.Count > 0) + return; + if (!hasUnresolvableGenerics) { foreach (var member in Elements.OfType()) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 748d39d046..f1b71854f6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -195,10 +195,17 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) memberType = TypeName.Type; } + if (memberType is AppendStructuredBufferType or ConsumeStructuredBufferType) + { + var bufTypeName = memberType is AppendStructuredBufferType ? "AppendStructuredBuffer" : "ConsumeStructuredBuffer"; + table.AddError(new(TypeName.Info, $"{bufTypeName} is not supported. Use RWStructuredBuffer with a separate counter buffer instead (variable '{Name}').")); + return; + } + var storageClass = (memberType, StorageClass, StreamKind) switch { (TextureType or BufferType, _, _) => Specification.StorageClass.UniformConstant, - (StructuredBufferType or ByteAddressBufferType or AppendStructuredBufferType or ConsumeStructuredBufferType, _, _) => Specification.StorageClass.StorageBuffer, + (StructuredBufferType or ByteAddressBufferType, _, _) => Specification.StorageClass.StorageBuffer, (_, StorageClass.GroupShared, _) => Specification.StorageClass.Workgroup, (_, StorageClass.Static, _) => Specification.StorageClass.Private, (_, _, StreamKind.Stream or StreamKind.PatchStream) => Specification.StorageClass.Private, @@ -298,16 +305,12 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (StreamKind == StreamKind.PatchStream) context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); - if (pointerType.BaseType is AppendStructuredBufferType asb) - context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"appendstructuredbuffer:<{asb.BaseType.ToId().ToLowerInvariant()}>")); - else if (pointerType.BaseType is ConsumeStructuredBufferType csb) - context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"consumestructuredbuffer:<{csb.BaseType.ToId().ToLowerInvariant()}>")); - else if (pointerType.BaseType is StructuredBufferType sb) + if (pointerType.BaseType is StructuredBufferType sb) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, $"{(sb.WriteAllowed ? "rw" : "")}structuredbuffer:<{sb.BaseType.ToId().ToLowerInvariant()}>")); else if (pointerType.BaseType is ByteAddressBufferType bab) context.Add(new OpDecorateString(variable, Specification.Decoration.UserTypeGOOGLE, bab.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); - if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false } or ConsumeStructuredBufferType) + if (pointerType.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false }) context.Add(new OpDecorate(variable, Specification.Decoration.NonWritable, [])); RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 3069c2bb59..43da24925c 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -41,7 +41,8 @@ public void ComputeTest1(string shaderName) // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); + var log = new Stride.Core.Diagnostics.LoggerResult(); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -86,7 +87,8 @@ public void RenderTest1(string shaderName) // (since there are multiple shader/effects in a simple file, simply using the effect would not go through normal load and it wouldn't know about the shaders in the file) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); + var log = new Stride.Core.Diagnostics.LoggerResult(); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); @@ -155,7 +157,8 @@ public void StreamOutTest1(string shaderName) shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); + var log = new Stride.Core.Diagnostics.LoggerResult(); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index 6691cfd963..c0c4a3a4f3 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -337,11 +337,11 @@ public void TextureDecorateStringWarning() }, }; - var logger = new Stride.Core.Diagnostics.LoggerResult(); + var log = new Stride.Core.Diagnostics.LoggerResult(); var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), logger, out var bytecode, out var effectReflection, out _, out _); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); - var warnings = logger.Messages + var warnings = log.Messages .Where(m => m.Type == Stride.Core.Diagnostics.LogMessageType.Warning && m.Text.Contains("Mismatched decorations")) .Select(m => m.Text).ToList(); Assert.Empty(warnings); @@ -520,16 +520,17 @@ public void Tessellation() }, }; - TestCore(shaderSource); + TestCore("StrideTessellation", shaderSource, "./assets/Stride/SDSL"); } - private static void TestCore(ShaderMixinSource shaderSource) + private static void TestCore(string shaderName, ShaderMixinSource shaderSource, params string[] searchPaths) { - var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/Stride/SDSL")); - shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), new Stride.Core.Diagnostics.LoggerResult(), out var bytecode, out var effectReflection, out _, out _); + var shaderMixer = new ShaderMixer(new ShaderLoader(searchPaths)); + var log = new Stride.Core.Diagnostics.LoggerResult(); + shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); - File.WriteAllBytes($"StrideTessellation.spv", bytecode); - File.WriteAllText($"StrideTessellation.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + File.WriteAllBytes($"{shaderName}.spv", bytecode); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); From a4cebdceee9a9c8b525e13bbc6144bdde624be58 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 14:15:35 +0900 Subject: [PATCH 0940/1182] SDSL: fixes for error reporting --- .../shaders/Stride.Shaders.Tests/StrideShaderTests.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index c0c4a3a4f3..d1bf19b6e2 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -529,12 +529,18 @@ private static void TestCore(string shaderName, ShaderMixinSource shaderSource, var log = new Stride.Core.Diagnostics.LoggerResult(); shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); + if (log.HasErrors) + Assert.Fail(string.Join(Environment.NewLine, log.Messages.Where(m => m.Type == Stride.Core.Diagnostics.LogMessageType.Error).Select(m => m.Text))); + File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); - var codeHS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationControl)); - var codeDS = translator.Translate(Backend.Hlsl, entryPoints.First(x => x.ExecutionModel == ExecutionModel.TessellationEvaluation)); + foreach (var entryPoint in entryPoints) + { + var hlsl = translator.Translate(Backend.Hlsl, entryPoint); + Console.WriteLine(hlsl); + } } } From ba1fff05c79fc2e3f4831b44ab5dce116ee412ac Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 11:54:52 +0900 Subject: [PATCH 0941/1182] SDSL: when a stage method references non-stage members, add the class without ImportStageOnly --- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 3 + .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 60 +++++++++++++++++-- .../Parsing/Analysis/SymbolTable.cs | 6 ++ .../Parsing/SDSL/AST/Expression.cs | 26 ++++++++ .../Parsing/SDSL/AST/Literals.cs | 25 ++++++++ .../Parsing/SDSL/AST/Shader.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 ++ .../Spirv/Building/BasicBlocks.cs | 1 + .../Extensions/spirv.sdsl.grammar-ext.json | 22 +++++++ .../CallNonStageFromStageMethod.sdsl | 26 ++++++++ .../CallNonStageFromStageMethodInherited.sdsl | 32 ++++++++++ 11 files changed, 201 insertions(+), 7 deletions(-) create mode 100644 sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethod.sdsl create mode 100644 sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethodInherited.sdsl diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index f2878bbe5f..36fc784bff 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -63,6 +63,9 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn hasErrors = true; } + foreach (var warning in table.Warnings) + log.Warning(warning.ToString()); + if (table.Errors.Count > 0) { foreach (var error in table.Errors) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 7312a70dda..63d9dae563 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -19,7 +19,7 @@ public partial class ShaderMixer /// /// /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderMixinSource? parent, ShaderSource shaderSource, Action? addToRoot = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderMixinSource? parent, ShaderSource shaderSource, Action? addToRoot = null, HashSet? needsFullImport = null) { var mixinList = new List(); @@ -58,15 +58,44 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, macros, mixinList, ResolveStep.Mix); } - ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot); + ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot, needsFullImport); return result; } - private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null) + private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null, HashSet? needsFullImport = null) { int shaderIndex = 0; + // Pre-scan: build set of shader names that need full import (not stage-only) at root level. + // Two sources: + // - OpSDSLMixinInherit with NeedsFullImport: parent shader whose non-stage members are called by a child's stage method + // - OpSDSLFunctionInfo with ReferencesNonStage: shader's own non-stage members are called by its own stage method + // The set is shared across root and composition calls so that compositions can contribute. + needsFullImport ??= new HashSet(); + foreach (var shader in mixinList) + { + var buf = shader.Buffer.Value; + foreach (var i in buf.Context) + { + if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit + && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 + && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss) + { + needsFullImport.Add(lss.Name); + } + } + foreach (var i in buf.Buffer) + { + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } fi + && (fi.Flags & FunctionFlagsMask.ReferencesNonStage) != 0) + { + needsFullImport.Add(shader.ClassName); + break; + } + } + } + var addToRootRecursive = addToRoot; if (addToRootRecursive == null) { @@ -89,6 +118,11 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con var newShadersToMergeNow = currentlyMixedList[result.Mixins.Count..]; result.Mixins.AddRange(newShadersToMergeNow); } + else if (needsFullImport.Contains(shaderName.ClassName)) + { + // Stage methods reference non-stage members from this shader, import fully + result.Mixins.Add(shaderName); + } else { result.Mixins.Add(shaderNameStageOnly); @@ -141,12 +175,12 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con { var variableCompositions = new List(); foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, addToRootRecursive)); + variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, addToRootRecursive, needsFullImport)); compositions[variableName] = [.. variableCompositions]; } else { - var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, compositionMixin, addToRootRecursive); + var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, compositionMixin, addToRootRecursive, needsFullImport); compositions[variableName] = [variableComposition]; } } @@ -158,7 +192,7 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con } } - // If there are any stage variables, add class to root + // If there are any stage variables/methods, add class to root if (hasStage) addToRoot?.Invoke(shaderName); @@ -167,6 +201,20 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con // For example, a composition might import a struct, so if we import and mix the composition mixin before the "stage" one defining the struct, the struct is not defined before the composition using it. result.Mixins.Add(shaderName); } + + // Post-processing: upgrade stage-only imports to full imports if compositions discovered + // that their non-stage members are needed (via needsFullImport set populated during composition processing) + if (addToRoot == null) + { + for (int i = 0; i < result.Mixins.Count; i++) + { + var mixin = result.Mixins[i]; + if (mixin.ImportStageOnly && needsFullImport.Contains(mixin.ClassName)) + { + result.Mixins[i] = new ShaderClassInstantiation(mixin.ClassName, mixin.GenericArguments) { Buffer = mixin.Buffer, Symbol = mixin.Symbol }; + } + } + } } private void PropagateMacrosRecursively(ShaderSource child, ShaderMixinSource? parent = null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index a682c3091e..60e2525f98 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -24,6 +24,7 @@ public partial class SymbolTable : ISymbolProvider public RootSymbolFrame RootSymbols { get; } public List Errors { get; } = []; + public List Warnings { get; } = []; // Used by Identifier.ResolveSymbol public SymbolFrame CurrentFrame => CurrentSymbols[^1]; @@ -120,4 +121,9 @@ public void AddError(SemanticError error) { Errors.Add(error); } + + public void AddWarning(SemanticError warning) + { + Warnings.Add(warning); + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index f64d6f5c79..8b2be06597 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -231,6 +231,32 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Note: we make a copy to not mutate original functionSymbol = functionSymbol with { IdRef = builder.Insert(new OpMemberAccessSDSL(context.GetOrRegister(functionType), context.Bound++, instanceId, functionSymbol.IdRef)).ResultId }; + // Track when a stage method references non-stage members (without composition qualifier). + // This forces the shader to be fully imported at root level instead of stage-only during mixin. + if (builder.CurrentFunction is { IsStage: true } && !functionSymbol.Id.IsStage && MemberCall == null) + { + var calleeOwner = functionSymbol.OwnerType; + if (calleeOwner != null && calleeOwner != table.CurrentShader) + { + // Parent shader: mark its OpSDSLMixinInherit with NeedsFullImport + foreach (var inst in context) + { + if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit + && context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss && lss.Name == calleeOwner.Name) + { + inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; + break; + } + } + } + else + { + // Self: mark current function + builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; + } + table.AddWarning(new(info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage method '{calleeOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + } + result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index e8fdf32495..4332026682 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -432,6 +432,31 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) { var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); + + // Track when a stage method accesses a non-stage variable (without composition qualifier). + // This forces the shader to be fully imported at root level instead of stage-only during mixin. + if (symbol.MemberAccessWithImplicitThis != null && !symbol.Id.IsStage && builder.CurrentFunction is { IsStage: true }) + { + var varOwner = symbol.OwnerType; + if (varOwner != null && varOwner != table.CurrentShader) + { + foreach (var inst in context) + { + if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit + && context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss && lss.Name == varOwner.Name) + { + inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; + break; + } + } + } + else + { + builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; + } + table.AddWarning(new(info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage variable '{varOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + } + return EmitSymbol(builder, context, symbol, constantOnly); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 2efcfbd14c..56adb00303 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -661,7 +661,7 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader table.CurrentShader.InheritedShaders.Add(shaderType); // Mark inherit - context.Add(new OpSDSLMixinInherit(shaderId)); + context.Add(new OpSDSLMixinInherit(shaderId, Spirv.Specification.MixinInheritFlagsMask.None)); } public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f1b71854f6..67954800a3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -599,6 +599,11 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { builder.Insert(new OpUnreachable()); } + + // After compiling the body, check if this stage function referenced non-stage members + if (builder.CurrentFunction is { ReferencesNonStageMembers: true }) + functionInfo.Flags |= Specification.FunctionFlagsMask.ReferencesNonStage; + builder.EndFunction(); table.Pop(); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs index bc9a9ecb5c..95c4250c4f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/BasicBlocks.cs @@ -23,6 +23,7 @@ public struct SpirvFunction(int id, string name, FunctionType type) : IInstructi public int Id { get; } = id; public string Name { get; } = name; public bool IsStage { get; set; } + public bool ReferencesNonStageMembers { get; set; } public FunctionType FunctionType { get; private set; } = type; public Dictionary Parameters { get; } = []; public SortedList BasicBlocks { get; } = []; diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index ffb5c5c72c..e5e2f745ec 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -36,6 +36,10 @@ { "kind": "IdRef", "name": "shader" + }, + { + "kind": "MixinInheritFlags", + "name": "flags" } ] }, @@ -456,6 +460,20 @@ } ], "operand_kinds": [ + { + "category": "BitEnum", + "kind": "MixinInheritFlags", + "enumerants": [ + { + "enumerant": "None", + "value": "0x0000" + }, + { + "enumerant": "NeedsFullImport", + "value": "0x0001" + } + ] + }, { "category": "BitEnum", "kind": "FunctionFlags", @@ -479,6 +497,10 @@ { "enumerant": "Override", "value": "0x0040" + }, + { + "enumerant": "ReferencesNonStage", + "value": "0x0080" } ] }, diff --git a/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethod.sdsl b/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethod.sdsl new file mode 100644 index 0000000000..470a18546f --- /dev/null +++ b/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethod.sdsl @@ -0,0 +1,26 @@ +// PSMain(ExpectedResult=#01010101) + +namespace Stride.Shaders.Tests; + +// Stage method calls non-stage method from the same shader. +shader CallNonStageFromStageMethod +{ + stream float4 ColorTarget : SV_Target0; + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + + float4 ComputeColor() + { + return float4(1.0, 1.0, 1.0, 1.0) / 255.0; + } + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + stage void PSMain() + { + streams.ColorTarget = ComputeColor(); + } +} diff --git a/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethodInherited.sdsl b/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethodInherited.sdsl new file mode 100644 index 0000000000..b2782d8eb7 --- /dev/null +++ b/sources/shaders/assets/SDSL/RenderTests/CallNonStageFromStageMethodInherited.sdsl @@ -0,0 +1,32 @@ +// PSMain(ExpectedResult=#01010101) + +namespace Stride.Shaders.Tests; + +// Base shader with a non-stage helper method +shader CallNonStageFromStageMethodInheritedBase +{ + float4 ComputeColor() + { + return float4(1.0, 1.0, 1.0, 1.0) / 255.0; + } +} + +// Stage method calls non-stage method from an inherited shader. +// This tests that ImportStageOnly correctly imports the parent fully +// when a stage method references its non-stage members. +shader CallNonStageFromStageMethodInherited : CallNonStageFromStageMethodInheritedBase +{ + stream float4 ColorTarget : SV_Target0; + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + + void VSMain() + { + streams.ShadingPosition = streams.Position; + } + + stage void PSMain() + { + streams.ColorTarget = ComputeColor(); + } +} From 014c7dee3685108aac8779b1880931497e4e60a6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 17:45:06 +0900 Subject: [PATCH 0942/1182] Tests: Add IsTestProject to xunit.runner.stride.csproj --- sources/tests/xunit.runner.stride/xunit.runner.stride.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/tests/xunit.runner.stride/xunit.runner.stride.csproj b/sources/tests/xunit.runner.stride/xunit.runner.stride.csproj index 08cceb8e08..db0d866097 100644 --- a/sources/tests/xunit.runner.stride/xunit.runner.stride.csproj +++ b/sources/tests/xunit.runner.stride/xunit.runner.stride.csproj @@ -4,6 +4,7 @@ enable latest enable + false false true app.manifest From f6cc37b0bc3a7fbab9747cf35d69e5e2baaa6798 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 18:07:41 +0900 Subject: [PATCH 0943/1182] SDSL: Wrap Texture/Buffer generic parameters in PointerType Generic parameters of resource types (Texture2D, Buffer, StructuredBuffer, ByteAddressBuffer) need the same PointerType wrapping as member variables, otherwise code accessing them fails with a cast exception. --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 56adb00303..28ad4c30bb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -603,6 +603,13 @@ public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int ind { genericParameter.TypeName.ProcessSymbol(table); var genericParameterType = genericParameter.TypeName.Type; + + // Wrap resource types in pointer (same as member variables) + if (genericParameterType is TextureType or BufferType) + genericParameterType = new PointerType(genericParameterType, Specification.StorageClass.UniformConstant); + else if (genericParameterType is StructuredBufferType or ByteAddressBufferType) + genericParameterType = new PointerType(genericParameterType, Specification.StorageClass.StorageBuffer); + table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); From fa6cd89345101e50df70655627be79030a711ebd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 19:12:00 +0900 Subject: [PATCH 0944/1182] SDSL: Improve overload resolution scoring and error messages --- .../Parsing/SDSL/AST/Expression.cs | 12 ++++++++++-- .../Parsing/SDSL/AST/IntrinsicCall.cs | 4 ++++ .../Spirv/Building/Builder.Expressions.cs | 12 ++++++------ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 8b2be06597..aecd655564 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -436,16 +436,24 @@ private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTy .OrderBy(x => x.Key.Score) .ToList(); + static string FormatSignature(string name, FunctionType ft) + => $"{name}({string.Join(", ", ft.ParameterTypes.Select(p => p.Type.GetValueType()))})"; + if (accessibleMethods.Count == 0) { - table.AddError(new(info, $"Can't find a valid method overload to call for {Name} (among {functionSymbol.GroupMembers} candidate(s))")); + var callStr = FormatSignature(Name, new FunctionType(null, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); + var candidatesStr = string.Join("\n ", functionSymbol.GroupMembers.Select(x => FormatSignature(Name, (FunctionType)x.Type))); + table.AddError(new(info, $"Can't find a valid method overload for '{callStr}'. Candidates:\n {candidatesStr}")); return false; } // Check if there is an ambiguous call (multiple method groups with the lowest score) if (accessibleMethods.Count > 1 && accessibleMethods[0].Key.Score == accessibleMethods[1].Key.Score) { - table.AddError(new(info, $"Ambiguous method overload when calling for {Name} (among {functionSymbol.GroupMembers} candidate(s))")); + var callStr = FormatSignature(Name, new FunctionType(null, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); + var ambiguousStr = string.Join("\n ", accessibleMethods.Where(g => g.Key.Score == accessibleMethods[0].Key.Score) + .SelectMany(g => g).Select(x => $"{FormatSignature(Name, (FunctionType)x.Symbol.Type)} [score: {x.Score}]")); + table.AddError(new(info, $"Ambiguous method overload for '{callStr}'. Matching candidates:\n {ambiguousStr}")); return false; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index 8501d5c5ff..42bd9f1322 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -58,8 +58,12 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na ByteAddressBufferType { WriteAllowed: false } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.ByteAddressBufferMethods), IntrinsicsDefinitions.ByteAddressBufferMethods), ByteAddressBufferMethodsImplementations.Instance), ByteAddressBufferType { WriteAllowed: true } => (GetOrCreateExpander(thisType, nameof(IntrinsicsDefinitions.RWByteAddressBufferMethods), IntrinsicsDefinitions.RWByteAddressBufferMethods), ByteAddressBufferMethodsImplementations.Instance), + _ => (null, null), }; + if (templateExpander == null) + return false; + if (!templateExpander.TryGetOrGenerateIntrinsicsDefinition(name, out var overloads)) { return false; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 167ded9170..4a188c682d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -415,8 +415,8 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) (VectorType v1, VectorType v2) when v1.Size == v2.Size => 0, (MatrixType m1, MatrixType m2) when m1.Rows == m2.Rows && m1.Columns == m2.Columns => 0, - // Promotion scalar to scalar, vector or matrix (replicate value) - (ScalarType, VectorType or MatrixType) => 1, + // Promotion scalar to vector or matrix (replicate value) — more expensive than scalar-to-scalar conversion + (ScalarType, VectorType or MatrixType) => 5, // Truncation // Shape-changing truncation (vector/matrix to scalar) costs more than dimension-reducing truncation @@ -451,11 +451,11 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => 7, (ScalarType { Type: Scalar.Float or Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => 7, - (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => 1, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => 2, - // Bitcast (int=>uint or uint=>int) - (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => 2, - (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => 2, + // Bitcast (int=>uint or uint=>int) — cheaper than int=>float since no precision change + (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => 1, + (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => 1, _ => int.MaxValue, }; From f566fec194d42aa14285dd092689d6249ae80576 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 19:49:59 +0900 Subject: [PATCH 0945/1182] SDSL: Fix matrix swizzle bounds check and overload error messages --- .../shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 4332026682..2b0516f976 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -585,7 +585,7 @@ static bool TryParseOne(ReadOnlySpan token, int cols, int rows, out (int C { if (++currentIndex == Name.Length || Name[currentIndex] == '_') { - if (!TryParseOne(Name.AsSpan(startIndex, currentIndex - startIndex), m.Rows, m.Columns, out var component)) + if (!TryParseOne(Name.AsSpan(startIndex, currentIndex - startIndex), m.Columns, m.Rows, out var component)) return false; result.Add(component); From c4a729637c3939986fc3723ed78f607d25a5e963 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 19:51:28 +0900 Subject: [PATCH 0946/1182] SDSL: Support scalar splat in vector/matrix constructors --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 2b0516f976..f8c5c79e55 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -223,6 +223,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } } + // Scalar splat: float3(x) means float3(x, x, x) + if (elementIndex == 1 && totalCount > 1 && Type is VectorType or MatrixType) + { + for (int j = 1; j < totalCount; ++j) + values[j] = values[0]; + elementIndex = totalCount; + } + if (elementIndex != totalCount) throw new InvalidOperationException($"{nameof(VectorLiteral)}: Expecting {totalCount} elements but got {elementIndex} for type {Type}"); From 7da68676b6c68a38f34eb8a1cc6384e53c263e12 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 21:46:47 +0900 Subject: [PATCH 0947/1182] SDSL: Stop using typedef and emit error if used --- .../Rendering/Utils/Utilities.sdsl | 14 ++++---------- .../Parsing/SDSL/AST/Shader.cs | 2 ++ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl b/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl index b721e8b936..79318166aa 100644 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Utils/Utilities.sdsl @@ -5,31 +5,25 @@ /// shader Utilities { - // ------------------------------------- - // type definition - // ------------------------------------- - typedef uint Half2; - typedef uint2 Half4; - // Converts a Half2 to a float2 - float2 Half2ToFloat2(Half2 value) + float2 UnpackHalf2ToFloat2(uint value) { return float2(f16tof32(value), f16tof32(value >> 16)); } // Converts a float2 to a Half2 - Half2 Float2ToHalf2(float2 value) + uint PackFloat2ToHalf2(float2 value) { return f32tof16(value.x) | (f32tof16(value.y) << 16); } // Converts a Half4 to a float4 - float4 Half4ToFloat4(Half4 value) { + float4 UnpackHalf4ToFloat4(uint2 value) { return float4(f16tof32(value.x), f16tof32(value.x>>16), f16tof32(value.y), f16tof32(value.y>>16)); } // Converts a float4 to a Half4 - Half4 Float4ToHalf4(float4 value) { + uint2 PackFloat4ToHalf4(float4 value) { return uint2(f32tof16(value.x) | (f32tof16(value.y) << 16), f32tof16(value.z) | (f32tof16(value.w) << 16)); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 28ad4c30bb..594b985f8a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -545,6 +545,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } // Process symbols and generate types + foreach (var td in Elements.OfType()) + table.AddError(new(td.Info, $"typedef is not implemented: '{td}'")); foreach (var member in Elements.OfType()) member.ProcessSymbol(table, context); foreach (var member in Elements.OfType()) From c35d961d4c98f45ea3d967b60e0b3c1d0ec75c9e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 22:01:22 +0900 Subject: [PATCH 0948/1182] SDSL: Basic support for half --- .../Spirv/Building/Builder.Expressions.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 4a188c682d..460d7b2fea 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -106,16 +106,22 @@ public static ScalarType FindCommonBaseTypeForBinaryOperation(SymbolType leftEle { (ScalarType { Type: Scalar.Int64 }, _) or (_, ScalarType { Type: Scalar.Int64 }) => throw new NotImplementedException("64bit integers"), // Matching types - (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double or Scalar.Boolean } l, ScalarType r) when l == r => l, - // If one side is float and other is non-floating, promote to floating + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Half or Scalar.Float or Scalar.Double or Scalar.Boolean } l, ScalarType r) when l == r => l, + // If one side is float/double and other is integer, promote to floating (ScalarType { Type: Scalar.Int or Scalar.UInt } l, ScalarType { Type: Scalar.Float or Scalar.Double } r) => r, (ScalarType { Type: Scalar.Float or Scalar.Double } l, ScalarType { Type: Scalar.Int or Scalar.UInt } r) => l, + // Half mixed with float/double: HLSL narrows to half + (ScalarType { Type: Scalar.Half } l, ScalarType { Type: Scalar.Float or Scalar.Double }) => l, + (ScalarType { Type: Scalar.Float or Scalar.Double }, ScalarType { Type: Scalar.Half } r) => r, + // Half mixed with integer promotes to half + (ScalarType { Type: Scalar.Int or Scalar.UInt } l, ScalarType { Type: Scalar.Half } r) => r, + (ScalarType { Type: Scalar.Half } l, ScalarType { Type: Scalar.Int or Scalar.UInt } r) => l, // If one side is unsigned, promote to unsigned (bitcast) (ScalarType { Type: Scalar.Int } l, ScalarType { Type: Scalar.UInt } r) => r, (ScalarType { Type: Scalar.UInt } l, ScalarType { Type: Scalar.Int } r) => l, // Bool promotes to int/uint/float in arithmetic contexts (HLSL implicit conversion) - (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double } r) => r, - (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Double } l, ScalarType { Type: Scalar.Boolean }) => l, + (ScalarType { Type: Scalar.Boolean }, ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Half or Scalar.Float or Scalar.Double } r) => r, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Half or Scalar.Float or Scalar.Double } l, ScalarType { Type: Scalar.Boolean }) => l, _ => throw new NotImplementedException($"Couldn't figure out element type for binary operation between {leftElementType} and {rightElementType}"), }; } @@ -450,9 +456,15 @@ public static int CanConvertScore(SymbolType valueType, SymbolType castType) // https://learn.microsoft.com/en-us/windows/win32/direct3d9/casting-and-conversion (ScalarType { Type: Scalar.Float }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => 7, - (ScalarType { Type: Scalar.Float or Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => 7, + (ScalarType { Type: Scalar.Float or Scalar.Half or Scalar.Int or Scalar.UInt }, ScalarType { Type: Scalar.Boolean }) => 7, (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Boolean }, ScalarType { Type: Scalar.Float }) => 2, + // Half conversions: half=>float (widening) is cheaper than float=>half (narrowing/lossy) + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Float or Scalar.Double }) => 1, + (ScalarType { Type: Scalar.Float or Scalar.Double }, ScalarType { Type: Scalar.Half }) => 3, + (ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Boolean }, ScalarType { Type: Scalar.Half }) => 2, + (ScalarType { Type: Scalar.Half }, ScalarType { Type: Scalar.Int or Scalar.UInt }) => 7, + // Bitcast (int=>uint or uint=>int) — cheaper than int=>float since no precision change (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => 1, (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => 1, @@ -713,7 +725,7 @@ public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) }; public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Int or Scalar.Int64 }; public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.UInt or Scalar.UInt64 }; - public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Float or Scalar.Double }; + public static bool IsFloating(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Half or Scalar.Float or Scalar.Double }; public static bool IsInteger(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsUnsignedInteger(); public static bool IsNumber(this SymbolType symbol) => symbol.IsInteger() || symbol.IsFloating(); public static bool IsSigned(this SymbolType symbol) => symbol.IsSignedInteger() || symbol.IsFloating(); From 872076edaab681631d32c13abeabb02c85b5a04c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 17 Mar 2026 22:02:57 +0900 Subject: [PATCH 0949/1182] Shaders: fix various unused shaders to at least parse properly --- .../AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl | 8 -------- ...AdditiveLightEffect.sdsl => AdditiveLightEffect.sdfx} | 0 .../ComputeColors/Shaders/ComputeColorSynthetic.sdsl | 9 --------- .../MaterialSurfaceShadingSpecularBlinnPhong.sdsl | 2 ++ .../Shaders/MaterialSurfaceVertexDisplacement.sdsl | 2 +- .../Rendering/Shadows/ShadowMapCasterVsm.sdsl | 2 +- .../Rendering/Transformation/TransformationZero.sdsl | 4 ++-- .../engine/Stride.Rendering/Rendering/Utils/Math.sdsl | 2 +- 8 files changed, 7 insertions(+), 22 deletions(-) rename sources/engine/Stride.Rendering/Rendering/Images/LightShafts/{AdditiveLightEffect.sdsl => AdditiveLightEffect.sdfx} (100%) delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl diff --git a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl index 80cdf56753..dbed3c37e3 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Images/AmbientOcclusion/ApplyAmbientOcclusionShader.sdsl @@ -1,14 +1,6 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using Stride.Rendering.Materials.ComputeColors; - namespace Stride.Rendering.Images { shader ApplyAmbientOcclusionShader : ImageEffectShader diff --git a/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdfx similarity index 100% rename from sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdsl rename to sources/engine/Stride.Rendering/Rendering/Images/LightShafts/AdditiveLightEffect.sdfx diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl b/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl deleted file mode 100644 index fe4e3986d6..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/ComputeColors/Shaders/ComputeColorSynthetic.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorSynthetic : ComputeColor -{ - override float4 Compute() - { - return Material.SpecularColorValue; - } -}; diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl index b9884e40bf..6c7140e846 100644 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl @@ -7,6 +7,8 @@ namespace Stride.Rendering.Materials /// shader MaterialSurfaceShadingSpecularBlinnPhong : IMaterialSurfaceShading, NormalStream { + ComputeColor BRDFBlinnPhong; + override float3 ComputeDirectLightContribution() { float k = BRDFBlinnPhong.Compute(streams.lightDirectionWS, streams.normalWS, streams.viewWS, streams.matSpecularPower); diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl index 80773db836..2227916449 100644 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceVertexDisplacement.sdsl @@ -15,7 +15,7 @@ namespace Stride.Rendering.Materials displacement = displacement * 2 - 1; } - displacement *= streams.matDisplacementIntensity; + //displacement *= streams.matDisplacementIntensity; streams.Position = float4(streams.Position.xyz + displacement * streams.meshNormal, streams.Position.w); } diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl index 356b71c7ce..cae2695081 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterVsm.sdsl @@ -5,7 +5,7 @@ namespace Stride.Rendering.Shadows /// /// Creates shadow map for variance shadow mapping. /// - shader ShadowMapCasterVsm : ShadowMapCasterBase + shader ShadowMapCasterVsm : ShaderBase { /// -------------------------------------------------------------------------------- /// Pixel Shader diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl index 5bea18abb3..76041558bc 100644 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationZero.sdsl @@ -3,11 +3,11 @@ /// /// Resets the position to the origin. /// -shader TransformationZero : TransformationBase +shader TransformationZero : TransformationBase, PositionStream4 { stage override void BaseTransformVS() { - streams.PositionStream4.Position = float4(0.0f, 0.0f, 0.0f, 1.0f); + streams.Position = float4(0.0f, 0.0f, 0.0f, 1.0f); base.BaseTransformVS(); } }; diff --git a/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl b/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl index cba0235c22..ea734efeb3 100644 --- a/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Utils/Math.sdsl @@ -81,7 +81,7 @@ shader Math // ------------------------------------- // Quintic interpolation // ------------------------------------- - float Quintic1(float x) { + float Quintic(float x) { return x * x * x * (x * (x * 6.0 - 15.0) + 10.0); } float2 Quintic(float2 x) { From d4db3a2d560766789c4a37be1a804fcb94228f57 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 01:12:11 +0900 Subject: [PATCH 0950/1182] SDSL: Fix cross-shader static const visibility using OpDecorateString (do not deduplicate) --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 7 ++++--- .../Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 594b985f8a..213b687d7f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -408,16 +408,17 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte methodsDefaultParameters.Add(target, new(shaderBuffers.Context, defaultIds)); } } - if (i.Op == Op.OpDecorate && (OpDecorate)i is + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ShaderConstantSDSL, Target: var target2, - } decorateShaderConstant) + Value: var constName, + }) { if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) throw new InvalidOperationException(); var resultType = typeInstruction.Data.IdResultType.Value; - var symbol = new Symbol(new(shaderBuffers.Context.Names[target2], SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2), OwnerType: shaderType); + var symbol = new Symbol(new(constName, SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2), OwnerType: shaderType); variables.Add((symbol, VariableFlagsMask.None)); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 67954800a3..b5ce7fb8b1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -224,8 +224,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) table.CurrentFrame.Add(Name, constant); Type = memberType; - // This constant is visible when inherited - context.Add(new OpDecorate(constantValue.Id, Specification.Decoration.ShaderConstantSDSL, [])); + // This constant is visible when inherited (name stored in decoration to avoid dedup conflicts) + context.Add(new OpDecorateString(constantValue.Id, Specification.Decoration.ShaderConstantSDSL, Name)); } else { From c19b7b46497f4e5be800ff698db394325525a494 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 08:53:11 +0900 Subject: [PATCH 0951/1182] Shaders: remove unused shader --- ...erialSurfaceShadingSpecularBlinnPhong.sdsl | 23 ------------------- 1 file changed, 23 deletions(-) delete mode 100644 sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl b/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl deleted file mode 100644 index 6c7140e846..0000000000 --- a/sources/engine/Stride.Rendering/Rendering/Materials/Shaders/MaterialSurfaceShadingSpecularBlinnPhong.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering.Materials -{ - /// - /// Performs a Lambert shading - /// - shader MaterialSurfaceShadingSpecularBlinnPhong : IMaterialSurfaceShading, NormalStream - { - ComputeColor BRDFBlinnPhong; - - override float3 ComputeDirectLightContribution() - { - float k = BRDFBlinnPhong.Compute(streams.lightDirectionWS, streams.normalWS, streams.viewWS, streams.matSpecularPower); - - var specularColor = streams.matSpecular * (streams.matCavity * streams.matCavitySpecular); - - // TODO: integrate AO/Cavity...etc. - // TODO: Check if we need to divide by PI - return specularColor * (k * streams.lightSpecularColorNdotL * streams.matDiffuseSpecularAlphaBlend.y); - } - }; -} From 57425eac6118ca5fe6fd482a2cda9aed51db9ab2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 11:26:58 +0900 Subject: [PATCH 0952/1182] SDSL: Add render test for composition stage parent not promoted to root Add CompositionStageInheritedNotPromotedToRoot test and surface compilation errors in RenderingTests instead of swallowing them. --- .../Stride.Shaders.Tests/RenderingTests.cs | 3 ++ ...sitionStageInheritedNotPromotedToRoot.sdsl | 54 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 sources/shaders/assets/SDSL/RenderTests/CompositionStageInheritedNotPromotedToRoot.sdsl diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 43da24925c..0be459cdd5 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -90,6 +90,9 @@ public void RenderTest1(string shaderName) var log = new Stride.Core.Diagnostics.LoggerResult(); shaderMixer.MergeSDSL(shaderSource, new ShaderMixer.Options(true), log, out var bytecode, out var effectReflection, out _, out _); + if (log.HasErrors) + Assert.Fail(string.Join(Environment.NewLine, log.Messages.Where(m => m.Type == Stride.Core.Diagnostics.LogMessageType.Error).Select(m => m.Text))); + File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); diff --git a/sources/shaders/assets/SDSL/RenderTests/CompositionStageInheritedNotPromotedToRoot.sdsl b/sources/shaders/assets/SDSL/RenderTests/CompositionStageInheritedNotPromotedToRoot.sdsl new file mode 100644 index 0000000000..98cab9e6aa --- /dev/null +++ b/sources/shaders/assets/SDSL/RenderTests/CompositionStageInheritedNotPromotedToRoot.sdsl @@ -0,0 +1,54 @@ +// This file provides shaders for the CompositionStageInheritedNotPromotedToRoot test in StrideShaderTests.cs. +// The test builds a ShaderMixinSource manually (not via effect block) to reproduce a bug where +// a parent shader's stage functions are not promoted to root level when the child is used in a composition. + +namespace Stride.Shaders.Tests; + +// Parent shader with a non-stage helper function (like TerrainQuery). +shader StageParentHelper +{ + float4 ComputeHelper() + { + return float4(1.0, 1.0, 1.0, 1.0) / 255.0; + } +} + +// Child shader inherits parent, has a stage method that calls parent's stage function. +// Mimics MaterialTreeDisplacementFeature inheriting TerrainQuery. +shader StageChildComposition : StageParentHelper +{ + stage void PreTransform() + { + float4 c = ComputeHelper(); + } +} + +// Root shader that declares a composition slot and calls the stage method. +shader CompositionStageInheritedNotPromotedToRootShader +{ + stream float4 ColorTarget : SV_Target0; + stream float4 Position : POSITION; + stream float4 ShadingPosition : SV_Position; + + stage void PreTransform() {} + + compose StageChildComposition vertexStageComposition; + + void VSMain() + { + PreTransform(); + streams.ShadingPosition = streams.Position; + } + + void PSMain() + { + streams.ColorTarget = float4(1.0, 1.0, 1.0, 1.0) / 255.0; + } +} + +// PSMain(ExpectedResult=#01010101) +effect CompositionStageInheritedNotPromotedToRoot +{ + mixin CompositionStageInheritedNotPromotedToRootShader; + mixin compose vertexStageComposition = StageChildComposition; +} From ac9235c81ab48bcc13f37d8a3e2bb27994ef53ec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 11:42:15 +0900 Subject: [PATCH 0953/1182] SDSL: Small refactor/comment in ShaderSourceEvaluator.cs for maintainability --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 279 ++++++++++-------- 1 file changed, 164 insertions(+), 115 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 63d9dae563..13d473f9e6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -15,11 +15,7 @@ public partial class ShaderMixer /// /// Expands inheritance (including implicit and transitive ones) and composition (including shaders that should be merged at stage level). /// - /// - /// - /// - /// - private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderMixinSource? parent, ShaderSource shaderSource, Action? addToRoot = null, HashSet? needsFullImport = null) + private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderMixinSource? parent, ShaderSource shaderSource, Action? promoteToParent = null, HashSet? needsFullImport = null) { var mixinList = new List(); @@ -58,16 +54,28 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, mixinToMerge2, macros, mixinList, ResolveStep.Mix); } - ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, addToRoot, needsFullImport); + ProcessClasses(shaderLoader, context, mixinList, shaderMixinSource, result, compositions, promoteToParent, needsFullImport); return result; } - private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? addToRoot = null, HashSet? needsFullImport = null) + /// + /// Processes a flat mixin list (already expanded with inheritance) to produce the final ShaderMixinInstantiation. + /// + /// Algorithm: + /// 1. Pre-scan: identify shaders that need full (non-stage-only) import at root level, + /// based on NeedsFullImport flags set by the parser when a stage method calls non-stage members. + /// 2. Build a promoteToParent callback for compositions to promote stage shaders to the parent level. + /// At root level (promoteToParent == null), this creates a closure that adds shaders to the root result, + /// choosing between stage-only, full import, or pull-forward based on needsFullImport and mixinList membership. + /// 3. Main loop: iterate each shader in mixinList, detect stage members and compositions, + /// recursively process compositions, then promote stage/needsFullImport shaders to parent. + /// 4. Post-processing (root only): upgrade any stage-only imports to full imports if compositions + /// discovered during step 3 that their non-stage members are needed. + /// + private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext context, List mixinList, ShaderMixinSource shaderMixinSource, ShaderMixinInstantiation result, Dictionary compositions, Action? promoteToParent = null, HashSet? needsFullImport = null) { - int shaderIndex = 0; - - // Pre-scan: build set of shader names that need full import (not stage-only) at root level. + // --- Step 1: Pre-scan for shaders needing full import --- // Two sources: // - OpSDSLMixinInherit with NeedsFullImport: parent shader whose non-stage members are called by a child's stage method // - OpSDSLFunctionInfo with ReferencesNonStage: shader's own non-stage members are called by its own stage method @@ -75,136 +83,74 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con needsFullImport ??= new HashSet(); foreach (var shader in mixinList) { - var buf = shader.Buffer.Value; - foreach (var i in buf.Context) - { - if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit - && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 - && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss) - { - needsFullImport.Add(lss.Name); - } - } - foreach (var i in buf.Buffer) - { - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } fi - && (fi.Flags & FunctionFlagsMask.ReferencesNonStage) != 0) - { - needsFullImport.Add(shader.ClassName); - break; - } - } + ScanNeedsFullImport(shader, needsFullImport); } - var addToRootRecursive = addToRoot; - if (addToRootRecursive == null) + // --- Step 2: Build the promote-to-parent callback --- + // At root level, we create a closure that decides how to add shaders to the root mixin list. + // At composition level, we reuse the parent's callback directly. + var promoteToParentForCompositions = promoteToParent; + if (promoteToParentForCompositions == null) { - addToRootRecursive = shaderName => + promoteToParentForCompositions = shaderName => { - var shaderNameStageOnly = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; + var stageOnlyVariant = new ShaderClassInstantiation(shaderName.ClassName, shaderName.GenericArguments, ImportStageOnly: true) { Buffer = shaderName.Buffer, Symbol = shaderName.Symbol }; + // Skip if already added (either standard or stage-only) + if (result.Mixins.Contains(shaderName) || result.Mixins.Contains(stageOnlyVariant)) + return; - // Make sure it's not already added yet (either standard or stage only) - if (!result.Mixins.Contains(shaderName) && !result!.Mixins.Contains(shaderNameStageOnly)) + if (mixinList.Contains(shaderName)) + { + // This shader is planned for normal addition later at root level. + // Pull it forward now (with its full inheritance) so it's available for the current composition. + var currentlyMixedList = result.Mixins[..]; + SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); + + var newShadersToMergeNow = currentlyMixedList[result.Mixins.Count..]; + result.Mixins.AddRange(newShadersToMergeNow); + } + else if (needsFullImport.Contains(shaderName.ClassName)) { - // Check if mixin will be added in future as a non-stage - if (mixinList.Contains(shaderName)) - { - // Special case: the current stage-only mixin is planned to be added later as a normal mixin at the root level - // It's a bit complex: we need to inherit from it right now instead of later - var currentlyMixedList = result.Mixins[..]; - SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); - - var newShadersToMergeNow = currentlyMixedList[result.Mixins.Count..]; - result.Mixins.AddRange(newShadersToMergeNow); - } - else if (needsFullImport.Contains(shaderName.ClassName)) - { - // Stage methods reference non-stage members from this shader, import fully - result.Mixins.Add(shaderName); - } - else - { - result.Mixins.Add(shaderNameStageOnly); - } + // Stage methods reference non-stage members from this shader — import fully + result.Mixins.Add(shaderName); + } + else + { + result.Mixins.Add(stageOnlyVariant); } }; } - for (; shaderIndex < mixinList.Count; shaderIndex++) + // --- Step 3: Main loop — detect stage members, process compositions, promote to parent --- + for (int shaderIndex = 0; shaderIndex < mixinList.Count; shaderIndex++) { var shaderName = mixinList[shaderIndex]; - // Note: this should only happen due to addToRootRecursive readding some mixin earlier + // May already be present if promoteToParent pulled it forward earlier if (result.Mixins.Contains(shaderName)) continue; var shader = shaderName.Buffer.Value; - bool hasStage = false; - foreach (var i in shader.Context) - { - if (i.Op == Op.OpTypeStruct) - { - hasStage = true; - } - } - foreach (var i in shader.Buffer) - { - if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.StorageClass != Specification.StorageClass.Function) - { - hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; - - var variableType = shader.Context.ReverseTypes[variable.ResultType]; - if (variableType is PointerType pointer && pointer.BaseType is ShaderSymbol or ArrayType { BaseType: ShaderSymbol }) - { - var variableName = shader.Context.Names[variable.ResultId]; - // Make sure we have a ShaderMixinSource - // If composition is not specified, use default class - if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) - { - if (pointer.BaseType is ShaderSymbol shaderSymbol) - compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; - else if (pointer.BaseType is ArrayType { BaseType: ShaderSymbol }) - compositionMixin = new ShaderArraySource(); - else - throw new NotImplementedException(); - } - - if (compositionMixin is ShaderArraySource shaderArraySource) - { - var variableCompositions = new List(); - foreach (var value in shaderArraySource.Values) - variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, addToRootRecursive, needsFullImport)); - compositions[variableName] = [.. variableCompositions]; - } - else - { - var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, compositionMixin, addToRootRecursive, needsFullImport); - compositions[variableName] = [variableComposition]; - } - } - } + bool hasStage = HasStageMembersOrCompositions(shader); - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } functionInfo) - { - hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; - } - } + // Discover and recursively process compositions + ProcessCompositions(shaderLoader, context, shader, shaderMixinSource, compositions, promoteToParentForCompositions, needsFullImport); - // If there are any stage variables/methods, add class to root - if (hasStage) - addToRoot?.Invoke(shaderName); + // Promote to parent level if this shader has stage members or needs full import + if (hasStage || needsFullImport.Contains(shaderName.ClassName)) + promoteToParent?.Invoke(shaderName); - // Note: make sure to add only *after* compositions EvaluateInheritanceAndCompositions recursive call is done (a composition might add a "stage" inheritance with root!.Mixins.Add() - // and this should be done before the composition mixin is added. - // For example, a composition might import a struct, so if we import and mix the composition mixin before the "stage" one defining the struct, the struct is not defined before the composition using it. + // Add to result *after* compositions are processed — a composition might add a "stage" inheritance + // that defines a struct, and that must come before the composition shader that uses it. result.Mixins.Add(shaderName); } - // Post-processing: upgrade stage-only imports to full imports if compositions discovered - // that their non-stage members are needed (via needsFullImport set populated during composition processing) - if (addToRoot == null) + // --- Step 4: Post-processing (root only) — upgrade stage-only to full import --- + // Compositions processed in step 3 may have added entries to needsFullImport. + // Shaders already added as stage-only need upgrading. + if (promoteToParent == null) { for (int i = 0; i < result.Mixins.Count; i++) { @@ -217,6 +163,109 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con } } + /// + /// Scans a shader's SPIR-V buffer for NeedsFullImport flags and adds matching shader names to the set. + /// + private static void ScanNeedsFullImport(ShaderClassInstantiation shader, HashSet needsFullImport) + { + var buf = shader.Buffer.Value; + foreach (var i in buf.Context) + { + if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit + && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 + && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss) + { + needsFullImport.Add(lss.Name); + } + } + foreach (var i in buf.Buffer) + { + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } fi + && (fi.Flags & FunctionFlagsMask.ReferencesNonStage) != 0) + { + needsFullImport.Add(shader.ClassName); + break; + } + } + } + + /// + /// Checks whether a shader buffer contains stage members (structs/streams, stage variables, or stage functions). + /// Also detects composition variables (returns true via hasStage if struct declarations exist). + /// + private static bool HasStageMembersOrCompositions(ShaderBuffers shader) + { + bool hasStage = false; + foreach (var i in shader.Context) + { + if (i.Op == Op.OpTypeStruct) + { + hasStage = true; + } + } + + foreach (var i in shader.Buffer) + { + if (i.Op == Op.OpVariableSDSL && (OpVariableSDSL)i is { } variable && variable.StorageClass != Specification.StorageClass.Function) + { + hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; + } + + if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } functionInfo) + { + hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; + } + } + + return hasStage; + } + + /// + /// Discovers composition variables in a shader buffer and recursively evaluates them. + /// + private void ProcessCompositions(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderBuffers shader, ShaderMixinSource shaderMixinSource, Dictionary compositions, Action promoteToParent, HashSet needsFullImport) + { + foreach (var i in shader.Buffer) + { + if (i.Op != Op.OpVariableSDSL) + continue; + + var variable = (OpVariableSDSL)i; + if (variable.StorageClass == Specification.StorageClass.Function) + continue; + + var variableType = shader.Context.ReverseTypes[variable.ResultType]; + if (variableType is not PointerType pointer || pointer.BaseType is not (ShaderSymbol or ArrayType { BaseType: ShaderSymbol })) + continue; + + var variableName = shader.Context.Names[variable.ResultId]; + + // Use the composition from ShaderMixinSource if specified, otherwise use the default type + if (!shaderMixinSource.Compositions.TryGetValue(variableName, out var compositionMixin)) + { + if (pointer.BaseType is ShaderSymbol shaderSymbol) + compositionMixin = new ShaderMixinSource { Mixins = { new ShaderClassSource(shaderSymbol.Name) } }; + else if (pointer.BaseType is ArrayType { BaseType: ShaderSymbol }) + compositionMixin = new ShaderArraySource(); + else + throw new NotImplementedException(); + } + + if (compositionMixin is ShaderArraySource shaderArraySource) + { + var variableCompositions = new List(); + foreach (var value in shaderArraySource.Values) + variableCompositions.Add(EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, value, promoteToParent, needsFullImport)); + compositions[variableName] = [.. variableCompositions]; + } + else + { + var variableComposition = EvaluateInheritanceAndCompositions(shaderLoader, context, shaderMixinSource, compositionMixin, promoteToParent, needsFullImport); + compositions[variableName] = [variableComposition]; + } + } + } + private void PropagateMacrosRecursively(ShaderSource child, ShaderMixinSource? parent = null) { var existingMacros = new HashSet(); From ccd2cb7e3b24acee11bfe58142a865f7cbe8f3dc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 14:14:26 +0900 Subject: [PATCH 0954/1182] SDSL: Further improvement to ShaderSourceEvaluator --- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 23 +++++++++++++++---- .../SDSL/Parsers/Common/CommonParsers.cs | 3 +-- .../ShaderParsers/ShaderDataParsers.cs | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 13d473f9e6..a4d0eec66d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -102,8 +102,6 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con if (mixinList.Contains(shaderName)) { - // This shader is planned for normal addition later at root level. - // Pull it forward now (with its full inheritance) so it's available for the current composition. var currentlyMixedList = result.Mixins[..]; SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), currentlyMixedList, ResolveStep.Mix); @@ -112,8 +110,25 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con } else if (needsFullImport.Contains(shaderName.ClassName)) { - // Stage methods reference non-stage members from this shader — import fully - result.Mixins.Add(shaderName); + // A fully-imported shader needs its parent shaders also fully imported, + // because its non-stage code may call non-stage methods from parents. + // Build the inheritance chain and add any missing parents (upgrading stage-only to full). + var inheritanceList = new List(); + SpirvBuilder.BuildInheritanceListIncludingSelf(shaderLoader, context, shaderName, shaderMixinSource.Macros.AsSpan(), inheritanceList, ResolveStep.Mix); + foreach (var ancestor in inheritanceList) + { + var ancestorStageOnly = new ShaderClassInstantiation(ancestor.ClassName, ancestor.GenericArguments, ImportStageOnly: true) { Buffer = ancestor.Buffer, Symbol = ancestor.Symbol }; + // Upgrade stage-only to full import + var stageOnlyIndex = result.Mixins.IndexOf(ancestorStageOnly); + if (stageOnlyIndex >= 0) + { + result.Mixins[stageOnlyIndex] = ancestor; + } + else if (!result.Mixins.Contains(ancestor)) + { + result.Mixins.Add(ancestor); + } + } } else { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 689ca57b3b..372e8287e2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -19,8 +19,7 @@ public static bool Exit(ref TScanner scanner, ParseResult resul parsed = null!; return false; } - if (result.Errors.Count == 0) - scanner.Position = beginningPosition; + scanner.Position = beginningPosition; parsed = null!; return false; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 33a829dca9..91f11fdc7f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -47,7 +47,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o }; return true; } - else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0013, scanner[scanner.Position], scanner.Memory)); + else return Parsers.Exit(ref scanner, result, out parsed, position); } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } From 1f6201d02a48fec2081958f53901afa7ccef0f45 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 16:28:49 +0900 Subject: [PATCH 0955/1182] SDSL: Fix Stride.Shaders.Compilers targets --- .../{Stride.Shaders.targets => Stride.Shaders.Compilers.targets} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sources/shaders/Stride.Shaders.Compilers/build/{Stride.Shaders.targets => Stride.Shaders.Compilers.targets} (100%) diff --git a/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.targets b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets similarity index 100% rename from sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.targets rename to sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets From 54cac5f52a821a6143423d63e78efd2d01e029ac Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 16:29:37 +0900 Subject: [PATCH 0956/1182] SDSL: In code generator for SDFX, removed exception for initial value (already handled) --- sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index fb349a0570..3d8bb5492f 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -658,8 +658,6 @@ public override void VisitEffectParameters(EffectParameters effectParameters) { WriteLinkLine(parameter); WriteVariableAsParameterKey(true, parameter.Type, parameter.Identifier, parameter.DefaultValue, []); - if (parameter.DefaultValue != null) - throw new NotImplementedException(); } CloseBrace(false).WriteLine(); From 3959ad29248b2d18e725c94b93dde9e7be2682d6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 17:55:26 +0900 Subject: [PATCH 0957/1182] SDSL: Allow non-function pointer (i.e. workgroup) for interlocked functions, and pass them directly as pointer --- .../Parsing/SDSL/AST/Expression.cs | 41 +++++++++++++------ .../SDSL/AST/IntrinsicTemplateExpander.cs | 7 ++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 9 +++- .../Parsing/SDSL/AST/ShaderElements.cs | 8 ++++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index aecd655564..f4b8138c4a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -282,23 +282,38 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F if (paramDefinition.Type is PointerType) { - var paramVariable = context.Bound++; - builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); - - if (inOutFlags != ParameterModifiers.Out) + // For ref params, pass the original pointer directly. + // Required for atomic intrinsics (InterlockedAdd, etc.) that need + // the actual memory pointer (Workgroup, StorageBuffer, etc.). + if (paramDefinition.Modifiers == ParameterModifiers.Ref) + { + var paramPointer = arguments.Values[i].Compile(table, compiler); + if (context.ReverseTypes[paramPointer.TypeId] is not PointerType) + table.AddError(new(arguments.Values[i].Info, + $"'ref' parameter at index {i} requires an l-value (pointer), but got {context.ReverseTypes[paramPointer.TypeId]}")); + compiledParams[i] = paramPointer.Id; + } + else { - var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + // Fallback for out/inout: copy-in/copy-out via function-local variable + var paramVariable = context.Bound++; + builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); - // Convert type (if necessary) - var paramExpectedValueType = paramDefinition.Type; - if (paramExpectedValueType is PointerType pointerType) - paramExpectedValueType = pointerType.BaseType; - paramSource = builder.Convert(context, paramSource, paramExpectedValueType); + if (inOutFlags != ParameterModifiers.Out) + { + var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); - builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); - } + // Convert type (if necessary) + var paramExpectedValueType = paramDefinition.Type; + if (paramExpectedValueType is PointerType pointerType) + paramExpectedValueType = pointerType.BaseType; + paramSource = builder.Convert(context, paramSource, paramExpectedValueType); - compiledParams[i] = paramVariable; + builder.Insert(new OpStore(paramVariable, paramSource.Id, null, [])); + } + + compiledParams[i] = paramVariable; + } } else { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index efb3927233..be29cd490e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -378,12 +378,13 @@ ParameterTypeInfo GetParameterInfo(int index) { Qualifier.In => ParameterModifiers.In, Qualifier.Out => ParameterModifiers.Out, - Qualifier.InOut or Qualifier.Ref => ParameterModifiers.InOut, + Qualifier.InOut => ParameterModifiers.InOut, + Qualifier.Ref => ParameterModifiers.Ref, null => ParameterModifiers.None, }; - // Wrap out/inout parameters in PointerType, matching user-defined function convention - if ((modifier & ParameterModifiers.Out) != 0) + // Wrap out/inout/ref parameters in PointerType, matching user-defined function convention + if ((modifier & ParameterModifiers.Out) != 0 || modifier == ParameterModifiers.Ref) paramType = new PointerType(paramType, Specification.StorageClass.Function); functionParameters.Add(new(paramType, modifier)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index b5ce7fb8b1..7d8b3b8eeb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -409,7 +409,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var argSym = p.TypeName.Type; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); p.Type = argSym; - var parameterType = new PointerType(p.Type, Specification.StorageClass.Function); + var parameterType = GenerateParameterType(p); ftype.ParameterTypes.Add(new(parameterType, p.Modifiers)); var parameterSymbol = new Symbol(new(p.Name, SymbolKind.Variable), parameterType, 0, OwnerType: table.CurrentShader); table.CurrentFrame.Add(p.Name, parameterSymbol); @@ -457,6 +457,13 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) table.CurrentShader.Methods.Add((symbol, functionFlags)); } + private static PointerType GenerateParameterType(MethodParameter p) + { + // Default: wrap everything in Function pointer + // TODO: what happens if we want to pass texture/sampler around as parameters? + return new PointerType(p.Type, Specification.StorageClass.Function); + } + public void ProcessSymbolBody(SymbolTable table, SpirvContext context) { table.Push(SymbolFrame); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index a219c275fb..ca102d2814 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -68,6 +68,14 @@ public enum ParameterModifiers : int Out = 0x2, InOut = In | Out, + /// + /// Pass the original pointer directly without copy-in/copy-out. + /// Unlike InOut which copies to a Function-local variable, Ref requires the argument + /// to be an l-value in non-Function storage (Workgroup, StorageBuffer, etc.). + /// Used by atomic intrinsics (InterlockedAdd, etc.) that need the actual memory pointer. + /// + Ref = 0x4, + Const = 0x10, Point = 0x20, From 6acd698fd6f606974886fec6e272294c35c40dc5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 18 Mar 2026 19:24:23 +0900 Subject: [PATCH 0958/1182] SDSL: Invalidate shader cache when source files change by tracking dependency hashes --- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 44 +++++++++++++++++ .../ShaderLoaderBase.cs | 47 ++++++++++++++++++- .../Spirv/Building/Context.cs | 2 +- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 36fc784bff..84f46dc7fc 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -53,6 +53,7 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn compiler.Macros.AddRange(macros); bool hasErrors = false; + try { shader.Compile(table, compiler); @@ -63,6 +64,21 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn hasErrors = true; } + // Collect dependency hashes from all shaders loaded during compilation. + // Each loaded shader's buffer has its own OpSourceHashSDSL — copy them into this shader's context. + var seenHashes = new HashSet(); + // Add own hash so we don't duplicate it + seenHashes.Add(hash); + foreach (var declaredType in table.DeclaredTypes.Values) + { + if (declaredType is LoadedShaderSymbol loadedShader + && loadedShader.Name != shader.Name + && ShaderLoader.Cache.TryLoadFromCache(loadedShader.Name, null, macros, out var depBuffer, out _)) + { + CopySourceHashes(depBuffer, compiler.Context, seenHashes); + } + } + foreach (var warning in table.Warnings) log.Warning(warning.ToString()); @@ -92,4 +108,32 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn return lastBuffer != null; } + + /// + /// Copies OpSourceHashSDSL entries from a dependency's buffer into the target context, skipping duplicates. + /// + private static void CopySourceHashes(ShaderBuffers source, SpirvContext target, HashSet seenHashes) + { + foreach (var inst in source.Context) + { + if (inst.Op != Spirv.Specification.Op.OpSourceHashSDSL) + continue; + + var sourceHash = (OpSourceHashSDSL)inst; + var depHash = new ObjectId((uint)sourceHash.Hash1, (uint)sourceHash.Hash2, (uint)sourceHash.Hash3, (uint)sourceHash.Hash4); + if (!seenHashes.Add(depHash)) + continue; + + // Find the filename string from the source context + foreach (var s in source.Context) + { + if (s.Op == Spirv.Specification.Op.OpString && ((OpString)s).ResultId == sourceHash.File) + { + var depFilenameId = target.Add(new OpString(target.Bound++, ((OpString)s).Value)).ResultId; + target.Add(new OpSourceHashSDSL(depFilenameId, sourceHash.Hash1, sourceHash.Hash2, sourceHash.Hash3, sourceHash.Hash4)); + break; + } + } + } + } } diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 3d04f18820..8ecd39b3e1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -2,7 +2,9 @@ using Stride.Core.Storage; using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Parsing; +using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Collections.Generic; @@ -35,7 +37,12 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ { isFromCache = Cache.TryLoadFromCache(name, null, defines, out buffer, out hash); if (isFromCache) - return true; + { + if (ValidateCachedHashes(buffer)) + return true; + // A dependency changed — invalidate and recompile + isFromCache = false; + } if (!ExternalFileExists(name)) { @@ -78,6 +85,44 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan + /// Validates all OpSourceHashSDSL entries in a cached buffer against current file content. + /// Returns false if any dependency has changed. + /// + private bool ValidateCachedHashes(ShaderBuffers buffer) + { + foreach (var i in buffer.Context) + { + if (i.Op == Specification.Op.OpSourceHashSDSL && (OpSourceHashSDSL)i is { } sourceHash) + { + var cachedHash = new ObjectId((uint)sourceHash.Hash1, (uint)sourceHash.Hash2, (uint)sourceHash.Hash3, (uint)sourceHash.Hash4); + + // Resolve filename from OpString + string? filename = null; + foreach (var s in buffer.Context) + { + if (s.Op == Specification.Op.OpString && ((OpString)s).ResultId == sourceHash.File) + { + filename = ((OpString)s).Value; + break; + } + } + if (filename == null) + continue; + + // Extract shader name from filename (strip path and extension) + var shaderName = Path.GetFileNameWithoutExtension(filename); + if (LoadExternalFileContent(shaderName, out _, out _, out var currentHash)) + { + if (cachedHash != currentHash) + return false; + } + // If file not found, it might be an internal shader — skip validation + } + } + return true; + } + protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) { var defines = new (string Name, string Definition)[macros.Length]; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index b134042428..cec93acb09 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -52,7 +52,7 @@ public virtual void RegisterShader(string name, string? generics, ReadOnlySpan Date: Thu, 19 Mar 2026 00:53:23 +0900 Subject: [PATCH 0959/1182] SDSL: ByteAddressBuffer were not properly decoded during ProcessNameAndTypes() --- .../shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs | 8 ++++---- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 7036e2e7ac..70282190e8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -276,19 +276,19 @@ public sealed partial record StructType(string Name, List public override string ToString() => base.ToString(); } -public sealed partial record StructuredBufferType(SymbolType BaseType, bool WriteAllowed = false) : StructuredType($"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +public sealed partial record StructuredBufferType(SymbolType BaseType, bool WriteAllowed = false) : StructuredType($"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, new ArrayType(BaseType, -1), TypeModifier.None)]) { public override string ToId() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType.ToId()}>"; public override string ToString() => $"{(WriteAllowed ? "RW" : "")}StructuredBuffer<{BaseType}>"; } -public sealed partial record AppendStructuredBufferType(SymbolType BaseType) : StructuredType($"AppendStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +public sealed partial record AppendStructuredBufferType(SymbolType BaseType) : StructuredType($"AppendStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, new ArrayType(BaseType, -1), TypeModifier.None)]) { public override string ToId() => $"AppendStructuredBuffer<{BaseType.ToId()}>"; public override string ToString() => $"AppendStructuredBuffer<{BaseType}>"; } -public sealed partial record ConsumeStructuredBufferType(SymbolType BaseType) : StructuredType($"ConsumeStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, BaseType, TypeModifier.None)]) +public sealed partial record ConsumeStructuredBufferType(SymbolType BaseType) : StructuredType($"ConsumeStructuredBuffer<{BaseType.ToId()}>", [new(string.Empty, new ArrayType(BaseType, -1), TypeModifier.None)]) { public override string ToId() => $"ConsumeStructuredBuffer<{BaseType.ToId()}>"; public override string ToString() => $"ConsumeStructuredBuffer<{BaseType}>"; @@ -299,7 +299,7 @@ public sealed partial record BufferType(ScalarType BaseType, bool WriteAllowed = public override string ToString() => $"{(WriteAllowed ? "RW" : "")}Buffer<{BaseType}>"; } -public sealed partial record ByteAddressBufferType(bool WriteAllowed = false) : SymbolType() +public sealed partial record ByteAddressBufferType(bool WriteAllowed = false) : StructuredType($"{(WriteAllowed ? "RW" : "")}ByteAddressBuffer", [new(string.Empty, new ArrayType(ScalarType.UInt, -1), TypeModifier.None)]) { public override string ToId() => $"{(WriteAllowed ? "RW" : "")}ByteAddressBuffer"; public override string ToString() => $"{(WriteAllowed ? "RW" : "")}ByteAddressBuffer"; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 213b687d7f..74ed8f94c5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -201,9 +201,12 @@ void RegisterName(int target, string name) name = $"_member{index}"; fields.Add(new(name, type, TypeModifier.None)); } + // TODO: Ideally we shouldn't depend on struct OpName, so we should use UserTypeGOOGLE? StructuredType structType = (blocks.Contains(typeStructInstruction.ResultId)) ? structName switch { + "type.ByteAddressBuffer" => new ByteAddressBufferType(false), + "type.RWByteAddressBuffer" => new ByteAddressBufferType(true), var s when s.StartsWith("type.StructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a ? a.BaseType : fields[0].Type), var s when s.StartsWith("type.RWStructuredBuffer.") => new StructuredBufferType(fields[0].Type is ArrayType a2 ? a2.BaseType : fields[0].Type, true), var s when s.StartsWith("type.AppendStructuredBuffer.") => new AppendStructuredBufferType(fields[0].Type is ArrayType a3 ? a3.BaseType : fields[0].Type), From 970d127fe0804ae10dba4a3c0d847a4dbf7696b2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Mar 2026 11:29:03 +0900 Subject: [PATCH 0960/1182] SDSL: non-async effect cache was compiling same effect multiple time if requested at same time from multiple threads --- .../Compiler/EffectCompilerCache.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index ba15e7634a..762226a152 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -27,11 +27,17 @@ namespace Stride.Shaders.Compiler public class EffectCompilerCache : EffectCompilerChain { private static readonly Logger Log = GlobalLogger.GetLogger("EffectCompilerCache"); + // Key is EffectBytecode.ComputeId() (hash of bytecode itself) private readonly Dictionary> bytecodes = new Dictionary>(); private readonly HashSet bytecodesByPassingStorage = new HashSet(); private const string CompiledShadersKey = "__shaders_bytecode__"; + // Key is effectInputHash (inputs to generate this bytecode) for both of those dictionaries + // Used for currently compiling shaders (when CompileEffectAsynchronously is true) private readonly Dictionary> compilingShaders = new Dictionary>(); + // Used when shader is compiled (esp. when CompileEffectAsynchronously is false, but also when true during some specific race conditions) + private readonly Dictionary compiledShaders = new Dictionary(); + private readonly DatabaseFileProvider database; private readonly TaskSchedulerSelector taskSchedulerSelector; @@ -166,13 +172,21 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------------------------------------------------------------ lock (compilingShaders) { + // Check if shader is still compiling Task compilingShaderTask; if (compilingShaders.TryGetValue(effectInputHash, out compilingShaderTask)) { - // Note: Task might still be compiling return compilingShaderTask; } + // Check if shader is already compiled, it can happen in two cases: + // - CompileEffectAsynchronously == false: if multiple same shaders waiting on lock (compilingShaders) + // - CompileEffectAsynchronously == true: race condition when shader is requested after async compilingShaders has been removed but cache was still not filled when we checked earlier + if (compiledShaders.TryGetValue(effectInputHash, out var result)) + { + return result; + } + // Compile the mixin in a Task if (CompileEffectAsynchronously) { @@ -288,6 +302,7 @@ private EffectBytecodeCompilerResult CompileBytecode(ShaderMixinSource mixinTree lock (compilingShaders) { compilingShaders.Remove(effectInputHash); + compiledShaders.Add(effectInputHash, compiledShader); } log.CopyTo(effectLog); From 4b9b81e8a408715d76a44ab46b466809666127cf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Mar 2026 18:49:01 +0900 Subject: [PATCH 0961/1182] SDSL: Add Frozen flag on SpirvContext for thread-safety Add Frozen property and FreezeableDictionary wrapper for Types/ReverseTypes/Names. Freeze contexts after caching in ShaderCache.RegisterShader to catch accidental mutations during development. ThrowIfFrozen guards on mutating methods. --- .../Spirv/Building/Context.cs | 59 +++++++++++++++---- .../Spirv/Building/FreezeableDictionary.cs | 48 +++++++++++++++ 2 files changed, 94 insertions(+), 13 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Building/FreezeableDictionary.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index cec93acb09..0616cd826d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -49,6 +49,9 @@ public bool Equals(ShaderLoadKey other) public virtual void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { + // Freeze the context so any accidental mutation after caching is caught + bytecode.Context.Frozen = true; + ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, (name, generics), out var exists); if (!exists) loadedShadersByName = hash != null ? new(hash.Value, new()) : new(); @@ -93,9 +96,32 @@ public partial class SpirvContext private int bound = 1; public int ResourceGroupBound { get; set; } = 1; public ref int Bound => ref bound; - public Dictionary Types { get; init; } = []; - public Dictionary ReverseTypes { get; init; } = []; - public Dictionary Names { get; init; } = []; + public FreezeableDictionary Types { get; init; } = new(); + public FreezeableDictionary ReverseTypes { get; init; } = new(); + public FreezeableDictionary Names { get; init; } = new(); + + /// + /// When true, any mutation to this context will throw. + /// Set after caching to catch thread-safety violations during development. + /// + public bool Frozen + { + get => frozen; + set + { + frozen = value; + Types.Frozen = value; + ReverseTypes.Frozen = value; + Names.Frozen = value; + } + } + private bool frozen; + + private void ThrowIfFrozen() + { + if (Frozen) + throw new InvalidOperationException("Attempted to mutate a frozen SpirvContext. Cached shader contexts must not be modified."); + } public OpDataIndex this[int index] => new(index, Buffer); @@ -144,6 +170,7 @@ public int GetGLSL() /// public void AddName(int target, string name) { + ThrowIfFrozen(); Buffer.Add(new OpName(target, name)); Names.Add(target, name); } @@ -155,6 +182,7 @@ public void AddName(int target, string name) /// public void SetName(int target, string name) { + ThrowIfFrozen(); Names[target] = name; foreach (var i in Buffer) @@ -171,10 +199,14 @@ public void SetName(int target, string name) } public void AddMemberName(int target, int accessor, string name) - => Buffer.AddData(new OpMemberName(target, accessor, name.Replace('.', '_'))); + { + ThrowIfFrozen(); + Buffer.AddData(new OpMemberName(target, accessor, name.Replace('.', '_'))); + } public void SetEntryPoint(ExecutionModel model, int function, string name, ReadOnlySpan variables) { + ThrowIfFrozen(); Span pvariables = stackalloc int[variables.Length]; int pos = 0; foreach (var v in variables) @@ -185,35 +217,36 @@ public void SetEntryPoint(ExecutionModel model, int function, string name, ReadO public T Insert(int index, in T value) where T : struct, IMemoryInstruction, allows ref struct - => Buffer.Insert(index, value); + { ThrowIfFrozen(); return Buffer.Insert(index, value); } public OpData InsertData(int index, in T value) where T : struct, IMemoryInstruction, allows ref struct - => Buffer.InsertData(index, value); + { ThrowIfFrozen(); return Buffer.InsertData(index, value); } public OpDataIndex Insert(int index, OpData data) - => Buffer.Insert(index, data); + { ThrowIfFrozen(); return Buffer.Insert(index, data); } public T Add(in T value) where T : struct, IMemoryInstruction, allows ref struct - => Buffer.Add(value); + { ThrowIfFrozen(); return Buffer.Add(value); } public OpData AddData(in T value) where T : struct, IMemoryInstruction, allows ref struct - => Buffer.AddData(value); + { ThrowIfFrozen(); return Buffer.AddData(value); } public OpDataIndex Add(OpData data) - => Buffer.Add(data); + { ThrowIfFrozen(); return Buffer.Add(data); } public void RemoveAt(int index, bool dispose = true) - => Buffer.RemoveAt(index, dispose); + { ThrowIfFrozen(); Buffer.RemoveAt(index, dispose); } public OpData Replace(int index, in T instruction) where T : struct, IMemoryInstruction, allows ref struct - => Buffer.Replace(index, instruction); + { ThrowIfFrozen(); return Buffer.Replace(index, instruction); } public SpirvContext FluentAdd(in T value, out T result) where T : struct, IMemoryInstruction, allows ref struct { + ThrowIfFrozen(); Buffer.FluentAdd(value, out result); return this; } @@ -243,7 +276,7 @@ public void RemoveNameAndDecorations(HashSet ids) } } - public void Sort() => Buffer.Sort(); + public void Sort() { ThrowIfFrozen(); Buffer.Sort(); } [Obsolete("Use the insert method instead")] public SpirvBuffer GetBuffer() => Buffer; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/FreezeableDictionary.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/FreezeableDictionary.cs new file mode 100644 index 0000000000..d434f5debb --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/FreezeableDictionary.cs @@ -0,0 +1,48 @@ +using System.Collections; +using System.Diagnostics.CodeAnalysis; + +namespace Stride.Shaders.Spirv.Building; + +/// +/// A dictionary wrapper that can be frozen to prevent mutations. +/// Read operations (indexer get, TryGetValue, ContainsKey, Count, enumeration) always work. +/// Write operations (Add, Remove, indexer set, Clear) throw after freezing. +/// +public class FreezeableDictionary : IReadOnlyDictionary where TKey : notnull +{ + private readonly Dictionary inner; + + public bool Frozen { get; set; } + + public FreezeableDictionary() => inner = new(); + public FreezeableDictionary(IEnumerable> source) => inner = new(source); + public FreezeableDictionary(FreezeableDictionary other) => inner = new(other.inner); + + private void ThrowIfFrozen() + { + if (Frozen) + throw new InvalidOperationException("Attempted to mutate a frozen dictionary. Cached shader contexts must not be modified."); + } + + // Read operations — always allowed + public TValue this[TKey key] + { + get => inner[key]; + set { ThrowIfFrozen(); inner[key] = value; } + } + public int Count => inner.Count; + public bool ContainsKey(TKey key) => inner.ContainsKey(key); + public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => inner.TryGetValue(key, out value); + public IEnumerable Keys => inner.Keys; + public IEnumerable Values => inner.Values; + /// Returns the struct enumerator directly to avoid boxing in foreach. + public Dictionary.Enumerator GetEnumerator() => inner.GetEnumerator(); + IEnumerator> IEnumerable>.GetEnumerator() => inner.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => inner.GetEnumerator(); + + // Write operations — throw when frozen + public void Add(TKey key, TValue value) { ThrowIfFrozen(); inner.Add(key, value); } + public bool TryAdd(TKey key, TValue value) { ThrowIfFrozen(); return inner.TryAdd(key, value); } + public bool Remove(TKey key) { ThrowIfFrozen(); return inner.Remove(key); } + public void Clear() { ThrowIfFrozen(); inner.Clear(); } +} From bd27b9d10f1e4065b7c1d87d73a77f64cc9d55d3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 20 Mar 2026 18:49:19 +0900 Subject: [PATCH 0962/1182] SDSL: Decouple ShaderDefinition from SymbolType ShaderDefinition no longer inherits from SymbolType. It's stored in SymbolTable.DeclaredShaders (not DeclaredTypes) and imported via SpirvContext.GetOrImportShader (not GetOrRegister). ShaderSymbol remains as the lightweight SymbolType placeholder in Types/ReverseTypes. --- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 11 +- .../SDSL/ShaderMixer.ShaderInfo.cs | 2 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 2 +- .../Stride.Shaders.Parsers/Core/Symbol.cs | 2 +- .../Core/SymbolTypes.cs | 54 ++++++- .../Parsing/Analysis/SymbolTable.cs | 31 +++- .../Parsing/SDSL/AST/Expression.cs | 12 +- .../Parsing/SDSL/AST/Literals.cs | 14 +- .../Parsing/SDSL/AST/Shader.cs | 142 ++++++++++++------ .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Parsing/SDSL/AST/ShaderElements.cs | 4 +- .../Spirv/Building/Builder.Class.cs | 2 +- .../Spirv/Building/Context.Constants.cs | 8 +- .../Spirv/Building/Context.ExtractBuffers.cs | 27 +++- .../Spirv/Building/SpirvContext.Types.cs | 82 +++++++++- .../Spirv/Processing/TypeDuplicatesRemover.cs | 2 +- 16 files changed, 312 insertions(+), 85 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 84f46dc7fc..6e9c8451d2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -69,10 +69,9 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn var seenHashes = new HashSet(); // Add own hash so we don't duplicate it seenHashes.Add(hash); - foreach (var declaredType in table.DeclaredTypes.Values) + foreach (var loadedShader in table.DeclaredShaders.Values) { - if (declaredType is LoadedShaderSymbol loadedShader - && loadedShader.Name != shader.Name + if (loadedShader.Name != shader.Name && ShaderLoader.Cache.TryLoadFromCache(loadedShader.Name, null, macros, out var depBuffer, out _)) { CopySourceHashes(depBuffer, compiler.Context, seenHashes); @@ -93,6 +92,12 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn return false; lastBuffer = compiler.ToShaderBuffers(); + + // Ensure all names and types from OpName/OpType instructions are registered + // in the context dictionaries. The compiler may not explicitly register everything + // (e.g. names for imported IDs, or types from InsertWithoutDuplicates). + ShaderClass.ProcessNameAndTypes(lastBuffer.Context); + ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); } else if (declaration is ShaderEffect or EffectParameters) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index a939758d7e..21d4528fe3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -26,7 +26,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio /// public ShaderInfo? Stage { get; set; } - public LoadedShaderSymbol Symbol { get; set; } + public ShaderDefinition Symbol { get; set; } /// /// Kept for debug purpose. diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index a4d0eec66d..1a4f676284 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -188,7 +188,7 @@ private static void ScanNeedsFullImport(ShaderClassInstantiation shader, HashSet { if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 - && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss) + && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is ShaderSymbol lss) { needsFullImport.Add(lss.Name); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs index 6015bee315..11c571f33c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs @@ -52,7 +52,7 @@ public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId /// Defines a symbol. /// /// Only used for specific such as -public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, LoadedShaderSymbol? OwnerType = null) +public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, ShaderDefinition? OwnerType = null) { public int IdRef { get; set; } = IdRef; public SymbolType Type { get; set; } = Type; diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 70282190e8..6d657b1b66 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -429,6 +429,20 @@ public sealed partial record EffectSymbol(string Name, List<(string Name, Symbol public partial record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType { + public virtual bool Equals(ShaderSymbol? other) + => other is not null + && Name == other.Name + && GenericArguments.AsSpan().SequenceEqual(other.GenericArguments); + + public override int GetHashCode() + { + var hash = new HashCode(); + hash.Add(Name); + foreach (var arg in GenericArguments) + hash.Add(arg); + return hash.ToHashCode(); + } + public string ToClassName() { if (GenericArguments.Length == 0) @@ -458,14 +472,42 @@ public override string ToString() } } -public sealed partial record LoadedShaderSymbol(string Name, int[] GenericArguments) : ShaderSymbol(Name, GenericArguments) +public sealed partial record ShaderDefinition(string Name, int[] GenericArguments) { + public string ToClassName() + { + if (GenericArguments.Length == 0) + return Name; + + var className = new ShaderClassInstantiation(Name, GenericArguments); + return className.ToClassNameWithGenerics(); + } + + public override string ToString() + { + var builder = new StringBuilder(); + builder.Append(Name); + if (GenericArguments.Length > 0) + { + builder.Append('<'); + for (int i = 0; i < GenericArguments.Length; i++) + { + if (i > 0) + builder.Append(','); + builder.Append('%'); + builder.Append(GenericArguments[i]); + } + builder.Append('>'); + } + return builder.ToString(); + } + public List<(Symbol Symbol, VariableFlagsMask Flags)> Variables { get; init; } = []; public List<(Symbol Symbol, FunctionFlagsMask Flags)> Methods { get; init; } = []; public List<(StructuredType Type, int ImportedId)> StructTypes { get; init; } = []; - public List InheritedShaders { get; init; } = []; + public List InheritedShaders { get; init; } = []; public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbol symbol) { @@ -500,7 +542,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo { // Emit symbol // TODO: emit it only when this specific method is *selected* as proper overload (signature) & override (base vs this) - var shaderId = context.GetOrRegister(symbol.OwnerType); + var shaderId = context.GetOrImportShader(symbol.OwnerType); context.ImportShaderMethod(shaderId, ref c.Symbol, c.Flags); } @@ -522,7 +564,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo if (c.Symbol.IdRef == 0) { // Emit symbol - var shaderId = context.GetOrRegister(symbol.OwnerType); + var shaderId = context.GetOrImportShader(symbol.OwnerType); context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); } @@ -545,7 +587,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo if (c.Symbol.IdRef == 0 && context != null) { // Emit symbol - var shaderId = context.GetOrRegister(symbol.OwnerType); + var shaderId = context.GetOrImportShader(symbol.OwnerType); context.ImportShaderVariable(shaderId, ref c.Symbol, c.Flags); } @@ -723,8 +765,6 @@ private bool BuildMethodGroup(string name, ref Symbol symbol) } return found; } - - public override string ToString() => base.ToString(); } public sealed partial record GenericParameterType(GenericParameterKindSDSL Kind) : SymbolType; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index 60e2525f98..7f9bffc569 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -20,6 +20,35 @@ public partial class SymbolTable : ISymbolProvider public Dictionary DeclaredTypes { get; } = []; + /// + /// Maps shader class names to their resolved definitions. Separate from DeclaredTypes + /// because ShaderDefinition is not a SymbolType. + /// + public Dictionary DeclaredShaders { get; } = []; + + /// + /// Maps SPIR-V IDs to resolved shader symbols. Separate from ReverseTypes to avoid mutating cached contexts. + /// + private readonly Dictionary loadedShaders = []; + + public ShaderDefinition? ResolveShader(int id) => loadedShaders.GetValueOrDefault(id); + + public ShaderDefinition? ResolveShader(ShaderSymbol symbol) + { + if (Context.Types.TryGetValue(symbol, out var id)) + return ResolveShader(id); + // Fallback: look up by name in DeclaredShaders (ShaderDefinition is no longer a SymbolType, + // so it may not have a corresponding entry in Context.Types during compilation) + if (DeclaredShaders.TryGetValue(symbol.Name, out var result)) + return result; + // Try with full generic class name (e.g. "LightPointGroup<3>") + if (symbol.GenericArguments.Length > 0) + return DeclaredShaders.GetValueOrDefault(symbol.ToClassName()); + return null; + } + + public void RegisterLoadedShader(int id, ShaderDefinition shader) => loadedShaders[id] = shader; + public SpirvContext Context { get; init; } public RootSymbolFrame RootSymbols { get; } @@ -32,7 +61,7 @@ public partial class SymbolTable : ISymbolProvider public List CurrentSymbols { get; } = new(); // Only valid during compilation (not during ShaderMixin phase) - public LoadedShaderSymbol? CurrentShader { get; set; } + public ShaderDefinition? CurrentShader { get; set; } public List CurrentMacros { get; set; } // Only valid during compilation (not during ShaderMixin phase) public List InheritedShaders { get; set; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index f4b8138c4a..5de4de81b5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -199,7 +199,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var functionSymbol = resolvedIntrinsicOverload != null ? null : LoadedShaderSymbol.ImportSymbol(table, context, ResolvedFunctionSymbol); + var functionSymbol = resolvedIntrinsicOverload != null ? null : ShaderDefinition.ImportSymbol(table, context, ResolvedFunctionSymbol); var functionType = resolvedIntrinsicOverload != null ? resolvedIntrinsicOverload.Value.Type : (FunctionType)functionSymbol.Type; Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; @@ -242,7 +242,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) foreach (var inst in context) { if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit - && context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss && lss.Name == calleeOwner.Name) + && table.ResolveShader(inherit.Shader) is { } lss && lss.Name == calleeOwner.Name) { inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; break; @@ -421,7 +421,7 @@ public static int OverloadScore(FunctionType functionType, int defaultParameters private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTypes, out Symbol functionSymbol) { // Note: for now, TypeId 0 is used for this/base; let's improve that later - if (MemberCallBaseType is LoadedShaderSymbol loadedShaderSymbol) + if (MemberCallBaseType is ShaderSymbol shaderSym && table.ResolveShader(shaderSym) is { } loadedShaderSymbol) { if (!loadedShaderSymbol.TryResolveSymbol(Name, out functionSymbol)) { @@ -1024,7 +1024,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso methodCall.MemberCall = result; result = methodCall.Compile(table, compiler); break; - case (PointerType { BaseType: LoadedShaderSymbol s }, Identifier field): + case (PointerType { BaseType: ShaderSymbol ss }, Identifier field) when table.ResolveShader(ss) is { } s: { if (compiler == null) { @@ -1040,7 +1040,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } var (builder, context) = compiler; - var importedVariable = LoadedShaderSymbol.ImportSymbol(table, context, field.ResolvedSymbol); + var importedVariable = ShaderDefinition.ImportSymbol(table, context, field.ResolvedSymbol); // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -1270,7 +1270,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } break; // Array indexer for shader compositions - case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol s } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): + case (PointerType { BaseType: ArrayType { BaseType: ShaderSymbol } }, IndexerExpression { Index: IntegerLiteral { Value: var compositionIndex } }): throw new NotImplementedException(); // Array indexer for arrays case (PointerType { BaseType: ArrayType { BaseType: var t } } p, IndexerExpression indexer): diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index f8c5c79e55..ceb2de9933 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -439,7 +439,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) { - var symbol = LoadedShaderSymbol.ImportSymbol(table, context, ResolvedSymbol); + var symbol = ShaderDefinition.ImportSymbol(table, context, ResolvedSymbol); // Track when a stage method accesses a non-stage variable (without composition qualifier). // This forces the shader to be fully imported at root level instead of stage-only during mixin. @@ -451,7 +451,7 @@ protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder build foreach (var inst in context) { if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit - && context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is LoadedShaderSymbol lss && lss.Name == varOwner.Name) + && table.ResolveShader(inherit.Shader) is { } lss && lss.Name == varOwner.Name) { inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; break; @@ -656,8 +656,8 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = } // We add the typename as a symbol (similar to static access in C#) - var shaderId = context.GetOrRegister(classSource.Symbol); - symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(classSource.Symbol, Specification.StorageClass.Private), shaderId); + var shaderId = context.GetOrImportShader(classSource.Symbol); + symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(new ShaderSymbol(classSource.Symbol.Name, classSource.Symbol.GenericArguments), Specification.StorageClass.Private), shaderId); table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); } @@ -709,6 +709,12 @@ or nameof(Specification.StreamsKindSDSL.Constants)) if (table.DeclaredTypes.TryGetValue(fullTypeName, out symbolType)) { + } + else if (table.DeclaredShaders.TryGetValue(fullTypeName, out var shaderDef)) + { + symbolType = new ShaderSymbol(shaderDef.Name, shaderDef.GenericArguments); + // Ensure the shader is imported in the current context so shaderImportIds has an entry + context.GetOrImportShader(shaderDef); } else if (Name == "PointStream" || Name == "LineStream" || Name == "TriangleStream") { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 74ed8f94c5..88bceea725 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -20,12 +20,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public interface IShaderImporter { - ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext); + SymbolType Import(ShaderClassInstantiation classSource, SpirvContext declaringContext); } public class EmptyShaderImporter : IShaderImporter { - public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) + public SymbolType Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) { return new ShaderSymbol(classSource.ClassName, classSource.GenericArguments); } @@ -42,6 +42,23 @@ public partial class ShaderClass(Identifier name, TextLocation info) : ShaderDec // Note: We should make this method incremental (called many times in ShaderMixer) // And possibly do the type deduplicating at the same time? (TypeDuplicateRemover) + /// + /// Registers all OpName instructions in the context's Names dictionary. + /// Safe to call multiple times (uses TryAdd). + /// + public static void RegisterContextNames(SpirvContext context) + { + for (var i = 0; i < context.Count; i++) + { + var instruction = context[i]; + if (instruction.Op == Op.OpName) + { + OpName nameInstruction = instruction; + context.Names.TryAdd(nameInstruction.Target, nameInstruction.Name); + } + } + } + public static void ProcessNameAndTypes(SpirvContext context, IShaderImporter? shaderImporter = null, bool allowReplace = false) { ProcessNameAndTypes(context, 0, context.Count, shaderImporter, allowReplace); @@ -55,12 +72,14 @@ void RegisterType(int typeId, SymbolType symbolType) { context.ReverseTypes[typeId] = symbolType; context.Types.Remove(existingSymbolType); + context.Types.Add(symbolType, typeId); } else { - context.ReverseTypes.Add(typeId, symbolType); + // TryAdd: skip if already registered (idempotent for cached contexts) + if (context.ReverseTypes.TryAdd(typeId, symbolType)) + context.Types.TryAdd(symbolType, typeId); } - context.Types.Add(symbolType, typeId); } void RegisterName(int target, string name) @@ -68,7 +87,7 @@ void RegisterName(int target, string name) if (allowReplace) context.Names[target] = name; else - context.Names.Add(target, name); + context.Names.TryAdd(target, name); } static SymbolType? ParseReturnType(string s) => s switch @@ -222,7 +241,8 @@ void RegisterName(int target, string name) var innerType = context.ReverseTypes[typeArray.ElementType]; if (context.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, false)) { - RegisterType(typeArray.ResultId, new ArrayType(innerType, (int)arraySizeObject)); + var arraySize = Convert.ToInt32(arraySizeObject); + RegisterType(typeArray.ResultId, new ArrayType(innerType, arraySize)); } else { @@ -309,27 +329,19 @@ void RegisterName(int target, string name) { RegisterType(typePatch.ResultId, new PatchType(context.ReverseTypes[typePatch.BaseType], typePatch.Kind, typePatch.Size)); } - // Unresolved content - // This only happens during EvaluateInheritanceAndCompositions so it's not important to have all information valid + // Import placeholders — registered here with EmptyShaderImporter during generic instantiation. + // When called with allowReplace=true from CreateShaderType, these get upgraded to real ShaderDefinition. else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Generics.Elements.Memory.ToArray()); var shaderSymbol = realShaderImporter.Import(classSource, context); - RegisterType(importShader.ResultId, shaderSymbol); } else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) { - var shaderSymbol = (ShaderSymbol)context.ReverseTypes[importStruct.Shader]; - if (shaderSymbol is LoadedShaderSymbol loadedShaderSymbol) - { - var structName = importStruct.StructName; - RegisterType(importStruct.ResultId, loadedShaderSymbol.StructTypes.Single(x => x.Type.ToId() == structName).Type); - } - else - { - RegisterType(importStruct.ResultId, new StructType(importStruct.StructName, [])); - } + // Register an empty placeholder struct — the real StructuredType is resolved + // later via ImportShaderStruct when the shader is imported into the main context. + RegisterType(importStruct.ResultId, new StructType(importStruct.StructName, [])); } } @@ -351,25 +363,64 @@ void RegisterName(int target, string name) } } - class ReplaceTypes(Dictionary TypesToReplace) : TypeRewriter + /// + /// Resolves OpSDSLImportShader/OpSDSLImportStruct into SymbolTable.loadedShaders + /// without mutating the cached shader context. + /// + private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext mainContext, SpirvContext shaderContext) { - public override SymbolType DefaultVisit(SymbolType node) => TypesToReplace.TryGetValue(node, out var result) ? result : node; + for (var i = 0; i < shaderContext.Count; i++) + { + var instruction = shaderContext[i]; + if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) + { + var genericIds = importShader.Generics.Elements.Memory.ToArray(); + + // Check if already loaded by name (not by ID — IDs are context-local and can collide + // between different cached shader contexts) + var stringKey = ResolveImportStringKey(importShader.ShaderName, genericIds, shaderContext); + if (stringKey != null + && table.DeclaredShaders.TryGetValue(stringKey, out var existingDef)) + { + table.RegisterLoadedShader(importShader.ResultId, existingDef); + continue; + } + + var classSource = new ShaderClassInstantiation(importShader.ShaderName, genericIds); + var shaderDef = LoadAndCacheExternalShaderType(table, mainContext, classSource, shaderContext); + table.RegisterLoadedShader(importShader.ResultId, shaderDef); + } + } } - public partial class ShaderImporter(SymbolTable table, SpirvContext context) : IShaderImporter + /// + /// Resolves a shader import's generic argument IDs to their string values and returns + /// the fully-qualified shader name (e.g. "SphericalHarmonicsUtils<3>"), or null if + /// any generic argument cannot be resolved as a constant. + /// + private static string? ResolveImportStringKey(string shaderName, int[] genericIds, SpirvContext shaderContext) { - public ShaderSymbol Import(ShaderClassInstantiation classSource, SpirvContext declaringContext) + if (genericIds.Length == 0) + return shaderName; + var args = new string[genericIds.Length]; + for (int j = 0; j < genericIds.Length; j++) { - return LoadAndCacheExternalShaderType(table, context, classSource, declaringContext); + if (!shaderContext.TryGetConstantValue(genericIds[j], out var value, out _, false)) + return null; + args[j] = ShaderClassSource.ConvertGenericArgToString(value); } + return $"{shaderName}<{string.Join(",", args)}>"; + } + + class ReplaceTypes(Dictionary TypesToReplace) : TypeRewriter + { + public override SymbolType DefaultVisit(SymbolType node) => TypesToReplace.TryGetValue(node, out var result) ? result : node; } - private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvContext context, ShaderBuffers shaderBuffers, ShaderClassInstantiation classSource) + private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext context, ShaderBuffers shaderBuffers, ShaderClassInstantiation classSource) { - // Reprocess types, this is necessary for: - // - ArrayType (with proper updated constants without generics) - // - ShaderClass (properly loaded as LoadedShaderSymbol) - ProcessNameAndTypes(shaderBuffers.Context, new ShaderImporter(table, context), true); + // Resolve imports from the cached shader context into the symbol table without mutating the frozen context. + ResolveImportsIntoTable(table, context, shaderBuffers.Context); var variables = new List<(Symbol Symbol, VariableFlagsMask Flags)>(); var methods = new List<(Symbol Symbol, FunctionFlagsMask Flags)>(); @@ -381,11 +432,11 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte SpirvBuilder.BuildInheritanceListWithoutSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), shaderBuffers.Context, inheritanceList, ResolveStep.Compile); // Load all the inherited shaders - List inheritedShaderSymbols = new(); + List inheritedShaderSymbols = new(); foreach (var inheritedClass in inheritanceList) inheritedShaderSymbols.Add(LoadAndCacheExternalShaderType(table, context, inheritedClass)); - var shaderType = new LoadedShaderSymbol(classSource.ClassName, classSource.GenericArguments) + var shaderType = new ShaderDefinition(classSource.ClassName, classSource.GenericArguments) { Variables = variables, Methods = methods, @@ -466,9 +517,9 @@ private static LoadedShaderSymbol CreateShaderType(SymbolTable table, SpirvConte return shaderType; } - private static void RegisterShaderType(SymbolTable table, ShaderSymbol shaderType) + private static void RegisterShaderType(SymbolTable table, ShaderDefinition shaderType) { - table.DeclaredTypes.Add(shaderType.ToClassName(), shaderType); + table.DeclaredShaders.Add(shaderType.ToClassName(), shaderType); } public void Compile(SymbolTable table, CompilerUnit compiler) @@ -477,7 +528,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) builder.Insert(new OpSDSLShader(name)); var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; - var currentShader = new LoadedShaderSymbol(Name, openGenerics); + var currentShader = new ShaderDefinition(Name, openGenerics); table.Push(); table.CurrentShader = currentShader; @@ -537,7 +588,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.CurrentShader = currentShader; table.InheritedShaders = inheritanceList; - var shaderSymbols = new List(); + var shaderSymbols = new List(); foreach (var mixin in inheritanceList) { shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderType(table, context, mixin)); @@ -659,13 +710,14 @@ public static string GetCBufferRealName(string cbufferName) } - public static void Inherit(SymbolTable table, SpirvContext context, LoadedShaderSymbol shaderType, bool addToRoot) + public static void Inherit(SymbolTable table, SpirvContext context, ShaderDefinition shaderType, bool addToRoot) { - var shaderId = context.GetOrRegister(shaderType); + var shaderId = context.GetOrImportShader(shaderType); + table.RegisterLoadedShader(shaderId, shaderType); foreach (var structType in shaderType.StructTypes) { - // Add the struct like if it was part of our shader (but using the imported id) + // Struct types are real SymbolTypes — register them for type resolution table.DeclaredTypes.TryAdd(structType.Type.Name, structType.Type); } @@ -677,11 +729,11 @@ public static void Inherit(SymbolTable table, SpirvContext context, LoadedShader context.Add(new OpSDSLMixinInherit(shaderId, Spirv.Specification.MixinInheritFlagsMask.None)); } - public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) + public static ShaderDefinition LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { // Already processed? - if (table.DeclaredTypes.TryGetValue(classSource.ToClassNameWithGenerics(), out var symbolType)) - return (LoadedShaderSymbol)symbolType; + if (table.DeclaredShaders.TryGetValue(classSource.ToClassNameWithGenerics(), out var cachedShader)) + return cachedShader; if (classSource.Buffer == null) throw new InvalidOperationException($"{nameof(classSource)}.{nameof(classSource.Buffer)} need to be set"); @@ -690,11 +742,11 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl return shaderType; } - public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, SpirvContext declaringContext) + public static ShaderDefinition LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource, SpirvContext declaringContext) { // Already processed? - if (table.DeclaredTypes.TryGetValue(classSource.ToClassNameWithGenerics(), out var symbolType)) - return (LoadedShaderSymbol)symbolType; + if (table.DeclaredShaders.TryGetValue(classSource.ToClassNameWithGenerics(), out var cachedShader)) + return cachedShader; if (classSource.Buffer == null) { @@ -705,7 +757,7 @@ public static LoadedShaderSymbol LoadAndCacheExternalShaderType(SymbolTable tabl return shaderType; } - public static LoadedShaderSymbol LoadExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) + public static ShaderDefinition LoadExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { var shaderBuffer = classSource.Buffer; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 7d8b3b8eeb..960972090f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -573,7 +573,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (parentSymbol.Type is FunctionGroupType) parentSymbol = parentSymbol.GroupMembers.Last(x => x.IdRef != function.Id && (FunctionType)x.Type == function.FunctionType); - parentSymbol = LoadedShaderSymbol.ImportSymbol(table, context, parentSymbol); + parentSymbol = ShaderDefinition.ImportSymbol(table, context, parentSymbol); functionInfo.Parent = parentSymbol.IdRef; functionInfo.Flags |= Specification.FunctionFlagsMask.Override; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index ca102d2814..f2d46ea9b4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -283,7 +283,7 @@ public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, Spirv // Try to resolve generic parameter when encoded as string (deprecated) if (table.TryResolveSymbol(linkLiteral.Value, out var linkLiteralSymbol)) { - linkLiteralSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkLiteralSymbol); + linkLiteralSymbol = ShaderDefinition.ImportSymbol(table, context, linkLiteralSymbol); // TODO: make it a warning only? //table.AddError(new(info, "LinkType generics should be passed without quotes")); result.LinkId = linkLiteralSymbol.IdRef; @@ -299,7 +299,7 @@ public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, Spirv { throw new InvalidOperationException(); } - linkSymbol = LoadedShaderSymbol.ImportSymbol(table, context, linkSymbol); + linkSymbol = ShaderDefinition.ImportSymbol(table, context, linkSymbol); result.LinkId = linkSymbol.IdRef; } else diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 16381f7545..26318ecaab 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -66,7 +66,7 @@ public record class ShaderClassInstantiation(string ClassName, int[] GenericArgu public int[] GenericArguments { get; set; } = GenericArguments; - public LoadedShaderSymbol Symbol { get; set; } + public ShaderDefinition Symbol { get; set; } public string ToClassNameWithGenerics() { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index ca754fd587..1d25c8ab09 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -188,10 +188,12 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object return true; } - typeId = i.Op switch + if (i.Op is not (Specification.Op.OpConstant or Specification.Op.OpSpecConstant)) { - Specification.Op.OpConstant or Specification.Op.OpSpecConstant => i.Data.Memory.Span[1], - }; + value = null; + return false; + } + typeId = i.Data.Memory.Span[1]; var operand = i.Data.Get("value"); if (Buffer.TryGetInstructionById(typeId, out var typeInst)) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index ed488d816c..5227878569 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -12,7 +12,7 @@ public int InsertWithoutDuplicates(int? desiredResultId, SpirvBuffer source) return InsertWithoutDuplicates(ref index, desiredResultId, source); } - public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, SpirvBuffer source) + public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, SpirvBuffer source, IReadOnlyDictionary? sourceNames = null) { // Import in current buffer (without duplicate) var typeDuplicateInserter = new TypeDuplicateHelper(this); @@ -113,8 +113,29 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI // Note: we made sure to not copy last instruction which should have the constant we want, so this case shouldn't happen anymore if (desiredResultId != null && lastResultId != desiredResultId) throw new InvalidOperationException(); - // Note: if we were to readd this, we would also need to process the main buffer - //SpirvBuilder.RemapIds(Buffer, 0, Buffer.Count, new Dictionary { { lastResultId, desiredResultId.Value } }); + + // Carry over names from source context for all remapped IDs + if (sourceNames != null) + { + foreach (var (sourceId, destId) in remapIds) + { + if (sourceNames.TryGetValue(sourceId, out var name)) + Names.TryAdd(destId, name); + } + } + + // Carry over OpName entries from the source buffer using remapped IDs. + // OpName has no IdResult so it is skipped in the main loop above. + // Process them here in a second pass so remapIds is fully populated. + foreach (var inst in source) + { + if (inst.Op == Specification.Op.OpName) + { + OpName nameInst = inst; + if (remapIds.TryGetValue(nameInst.Target, out var remappedTarget)) + Names.TryAdd(remappedTarget, nameInst.Name); + } + } return lastResultId; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 61be9d6596..54946cfda0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -1,4 +1,4 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Core; @@ -11,6 +11,16 @@ public partial class SpirvContext // that would lose their ArrayStride decoration during type deduplication in the mixer. private Dictionary runtimeArrayCache = []; + // Maps logical shader class name (e.g. "SomeMixin<3>") to the registered import ID, + // to deduplicate ShaderDefinitions that represent the same logical shader but differ + // only in their GenericArguments int[] reference (which breaks record equality). + private Dictionary shaderImportIds = []; + + // Cache of known ShaderDefinitions by name, populated by GetOrImportShader. + // Used by GetOrRegister to resolve ShaderSymbol → full import when encountering + // shader types from cached dependency contexts. + private Dictionary knownShaderDefs = []; + private int GetOrCreateRuntimeArray(int elementTypeId, int arrayStride) { if (runtimeArrayCache.TryGetValue(elementTypeId, out var id)) @@ -28,18 +38,78 @@ public int GetOrRegister(SymbolType? type) throw new ArgumentException($"Type is null"); if (Types.TryGetValue(type, out var res)) return res; + // ShaderSymbol is a lightweight placeholder — its ID is tracked in shaderImportIds, not Types + if (type is ShaderSymbol ss) + { + if (shaderImportIds.TryGetValue(ss.Name, out var importId)) + return importId; + // Try full import if the ShaderDefinition is known (populated by GetOrImportShader) + if (knownShaderDefs.TryGetValue(ss.Name, out var shaderDef)) + return GetOrImportShader(shaderDef); + // Fallback: create a minimal import for unresolved shader symbols + ThrowIfFrozen(); + var id = Bound++; + Add(new OpSDSLImportShader(id, new(ss.Name), new(ss.GenericArguments.AsSpan()))); + AddName(id, ss.Name); + shaderImportIds[ss.Name] = id; + return id; + } + ThrowIfFrozen(); return RegisterType(type, Bound++); } + /// + /// Returns the SPIR-V import ID for a shader definition, creating an OpSDSLImportShader + /// instruction if this is the first time this shader is imported in this context. + /// Struct types from the shader are registered in Types/ReverseTypes (they are real SPIR-V types). + /// + public int GetOrImportShader(ShaderDefinition shaderDef) + { + var key = shaderDef.Name; // For non-generic shaders + if (shaderDef.GenericArguments.Length > 0) + { + var resolved = ResolveShaderStringKey(shaderDef.Name, shaderDef.GenericArguments); + if (resolved != null) + key = resolved; + } + + // Cache the definition so GetOrRegister can resolve ShaderSymbol → full import + knownShaderDefs.TryAdd(shaderDef.Name, shaderDef); + + if (shaderImportIds.TryGetValue(key, out var id)) + return id; + + ThrowIfFrozen(); + return ImportShaderType(shaderDef, key); + } + + // Resolve a shader's generic argument IDs in this context to build a string key like "Shader<3,true>". + // Returns null if any generic arg can't be resolved as a constant. + private string? ResolveShaderStringKey(string name, int[] genericArguments) + { + if (genericArguments.Length == 0) + return name; + var args = new string[genericArguments.Length]; + for (int j = 0; j < genericArguments.Length; j++) + { + if (!TryGetConstantValue(genericArguments[j], out var value, out _, false)) + return null; + args[j] = ShaderClassSource.ConvertGenericArgToString(value); + } + return $"{name}<{string.Join(",", args)}>"; + } + public void ReplaceType(SymbolType type, int id) { + ThrowIfFrozen(); RemoveType(id); RegisterType(type, id); } public int RemoveType(SymbolType type) { + ThrowIfFrozen(); var typeId = Types[type]; RemoveType(typeId); return typeId; @@ -47,6 +117,7 @@ public int RemoveType(SymbolType type) public void RemoveType(int typeId) { + ThrowIfFrozen(); foreach (var i in Buffer) { if (i.Data.IdResult == typeId) @@ -90,7 +161,6 @@ public int RegisterType(SymbolType type, int id) StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f, id), PointerType p => RegisterPointerType(p, id), - LoadedShaderSymbol s => ImportShaderType(s, id), Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, @@ -209,19 +279,21 @@ private int RegisterArrayType(ArrayType a) return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).ResultId; } - public int ImportShaderType(LoadedShaderSymbol shaderSymbol, int id) + private int ImportShaderType(ShaderDefinition shaderSymbol, string key) { + var id = Bound++; Add(new OpSDSLImportShader(id, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan()))); AddName(id, shaderSymbol.Name); + shaderImportIds[key] = id; - // Import struct + // Import struct types — these ARE real SPIR-V types and belong in Types/ReverseTypes var structTypes = CollectionsMarshal.AsSpan(shaderSymbol.StructTypes); foreach (ref var structType in structTypes) { ImportShaderStruct(id, structType.Type, out structType.ImportedId); } - // Note: Variables and methods are imported lazily in LoadedShaderSymbol.TryResolveSymbol() + // Note: Variables and methods are imported lazily in ShaderDefinition.TryResolveSymbol() return id; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 9119ab573e..614d24209b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -163,7 +163,7 @@ private static int CompareIntConstant(SpirvContext context, int id1, int id2) return (value1Success, value2Success) switch { // Both succeeds: compare values - (true, true) => ((int)value1!).CompareTo((int)value2!), + (true, true) => Convert.ToInt32(value1!).CompareTo(Convert.ToInt32(value2!)), // Only one succeeds (use bool order) (true, false) or (false, true) => value1Success.CompareTo(value2Success), // Both fails: use ID From e7e476906946530f78a7f8d1977eaad436e48fa6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 19 Mar 2026 14:23:09 +0900 Subject: [PATCH 0963/1182] SDSL: FileShaderCache and IntrinsicCall is now thread-safe --- .../FileShaderCache.cs | 34 ++++++++++++------- .../Parsing/SDSL/AST/IntrinsicCall.cs | 9 +++-- .../Spirv/Building/Context.cs | 29 +++++++++------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs index 3fdf6c8f66..e07dc20e7a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs @@ -18,6 +18,7 @@ namespace Stride.Shaders.Compilers; /// public class FileShaderCache(IVirtualFileProvider fileProvider, string basePath = "shaders") : IShaderCache { + private readonly object lockObject = new(); private readonly ShaderCache memoryCache = new(); public bool Exists(string name) @@ -44,12 +45,16 @@ public void RegisterShader(string name, string? generics, ReadOnlySpan intrinsicsDefinitions) { - if (!ClassTemplateExpanders.TryGetValue(type, out var value)) - ClassTemplateExpanders.Add(type, value = new(type, @namespace, intrinsicsDefinitions)); - return value; + lock (ClassTemplateExpanders) + { + if (!ClassTemplateExpanders.TryGetValue(type, out var value)) + ClassTemplateExpanders.Add(type, value = new(type, @namespace, intrinsicsDefinitions)); + return value; + } } (var templateExpander, var intrinsicCompiler) = thisType switch diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 0616cd826d..fde5682f2e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -49,24 +49,29 @@ public bool Equals(ShaderLoadKey other) public virtual void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { - // Freeze the context so any accidental mutation after caching is caught bytecode.Context.Frozen = true; - - ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, (name, generics), out var exists); - if (!exists) - loadedShadersByName = hash != null ? new(hash.Value, new()) : new(); - loadedShadersByName.BuffersPerMacros[new(defines.ToArray())] = bytecode; - if (hash != null) - loadedShadersByName.Hash = hash.Value; + + lock (loadedShaders) + { + ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, (name, generics), out var exists); + if (!exists) + loadedShadersByName = hash != null ? new(hash.Value, new()) : new(); + loadedShadersByName.BuffersPerMacros[new(defines.ToArray())] = bytecode; + if (hash != null) + loadedShadersByName.Hash = hash.Value; + } } public bool TryLoadFromCache(string name, string? generics, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash) { - if (loadedShaders.TryGetValue((name, generics), out var loadedShadersByName) - && loadedShadersByName.BuffersPerMacros.TryGetValue(new(defines.ToArray()), out buffer)) + lock (loadedShaders) { - hash = loadedShadersByName.Hash; - return true; + if (loadedShaders.TryGetValue((name, generics), out var loadedShadersByName) + && loadedShadersByName.BuffersPerMacros.TryGetValue(new(defines.ToArray()), out buffer)) + { + hash = loadedShadersByName.Hash; + return true; + } } hash = default; From 4532f9f906061cdb5246930d81a5b5760b186a79 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 00:25:37 +0900 Subject: [PATCH 0964/1182] SDSL: Fix frozen buffer corruption in InsertWithoutDuplicates InsertWithoutDuplicates was modifying source buffer instructions in-place (RemapIds, opcode swaps) which corrupted frozen cached buffers when called via RegisterArrayType with an ArrayType storing a reference to the cached buffer. Copy each instruction before mutating to preserve source integrity. Also convert raw OpSDSLGenericParameter leaked from parent contexts into OpSDSLGenericReference during import to prevent generic parameter miscounts. Add ThrowIfFrozen guard to RemoveNameAndDecorations. --- .../Spirv/Building/Builder.Class.cs | 36 +++++++++- .../Spirv/Building/Context.Constants.cs | 1 + .../Spirv/Building/Context.ExtractBuffers.cs | 65 ++++++++++++------- .../Spirv/Building/Context.cs | 3 +- .../Spirv/Building/SpirvContext.Types.cs | 15 +++-- 5 files changed, 88 insertions(+), 32 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 26318ecaab..7695a241d3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -13,7 +13,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -169,7 +168,10 @@ int RemapGenericParameter(int localGeneric) { if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) { - var shaderName = shaderMapping[inherit.Shader]; + if (!shaderMapping.TryGetValue(inherit.Shader, out var shaderName)) + { + throw new InvalidOperationException($"BuildInheritanceListWithoutSelf: OpSDSLMixinInherit references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(", ", shaderMapping.Keys)}])"); + } // Remap/import generics var remappedGenericArguments = shaderName.GenericArguments.ToArray(); @@ -395,6 +397,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st var semantics = new Dictionary(); var genericParameters = new List(); + Dictionary? importMap = null; for (int index = 0; index < shaderBuffers.Context.Count; ++index) { var i = shaderBuffers.Context[index]; @@ -424,6 +427,34 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } + // Resolve OpSDSLGenericReference by looking up the parent import's argument + if (i.Op == Op.OpSDSLGenericReference) + { + // Build import map lazily (after all GenericParameters are resolved above) + if (importMap == null) + { + importMap = new(); + foreach (var inst in shaderBuffers.Context) + { + if (inst.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)inst is { } import) + importMap[import.ShaderName] = import.Generics.Elements.Memory.ToArray(); + } + } + + // OpSDSLGenericReference has the same layout as OpSDSLGenericParameter + var genRef = (OpSDSLGenericParameter)i; + if (importMap.TryGetValue(genRef.DeclaringClass, out var args) && genRef.Index < args.Length) + { + var resolvedArgId = args[genRef.Index]; + // Extract the resolved constant and its dependencies from the context buffer + var constantBuffer = SpirvContext.ExtractConstantFromBuffer(resolvedArgId, shaderBuffers.Context.GetBuffer()); + // Remove the GenericReference and insert the resolved constant with the same ResultId + shaderBuffers.Context.RemoveAt(index); + shaderBuffers.Context.InsertWithoutDuplicates(ref index, genRef.ResultId, constantBuffer); + index--; // adjust for loop increment + } + } + if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant) @@ -789,6 +820,7 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); + cache.RegisterShader(className, genericArguments, macros, shaderBuffers, hash); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 1d25c8ab09..8afa27ab3e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -149,6 +149,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object if (simplifyInBuffer) { + ThrowIfFrozen(); if (value is int valueI) Buffer.Replace(i.Index, new OpConstant(resultType, resultId, valueI)); else if (value is float valueF) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index 5227878569..546d20710a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -8,12 +8,14 @@ public partial class SpirvContext { public int InsertWithoutDuplicates(int? desiredResultId, SpirvBuffer source) { + ThrowIfFrozen(); var index = Buffer.Count; return InsertWithoutDuplicates(ref index, desiredResultId, source); } public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultId, SpirvBuffer source, IReadOnlyDictionary? sourceNames = null) { + ThrowIfFrozen(); // Import in current buffer (without duplicate) var typeDuplicateInserter = new TypeDuplicateHelper(this); var remapIds = new Dictionary(); @@ -33,21 +35,27 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI for (int index = 0; index < source.Count; ++index) { - var i = source[index]; - SpirvBuilder.RemapIds(remapIds, ref i.Data); + // Copy instruction data so we never modify the source buffer in-place. + // The source may be a frozen cached buffer shared across compilations. + var iData = new OpData(source[index].Data.Memory.Span); + SpirvBuilder.RemapIds(remapIds, ref iData); //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() - var isGenericReference = i.Op == Specification.Op.OpSDSLGenericReference; + var isGenericReference = iData.Op == Specification.Op.OpSDSLGenericReference; + // Also detect raw OpSDSLGenericParameter from parent contexts — these leaked through + // ExtractConstantAsSpirvBuffer and must be converted to references so they don't get + // mis-counted as the current shader's own generics. + var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpSDSLGenericParameter; if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; // For OpTypeImage: find the UserTypeGOOGLE decoration in the source buffer so CheckForDuplicates // can distinguish e.g. Texture2D vs Texture2D (same binary, different return type). // IdResult is still the original source ID here because RemapIds does not remap the current instruction's own result. string? sourceUserTypeGOOGLE = null; - if (i.Op == Specification.Op.OpTypeImage && i.Data.IdResult.HasValue) + if (iData.Op == Specification.Op.OpTypeImage && iData.IdResult.HasValue) { - var originalId = i.Data.IdResult.Value; + var originalId = iData.IdResult.Value; foreach (var inst in source) { if (inst.Op == Specification.Op.OpDecorateString) @@ -63,8 +71,8 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI } // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) - if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(i.Op) || isGenericReference) - && typeDuplicateInserter.CheckForDuplicates(i.Data, sourceUserTypeGOOGLE, out var existingData) + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(iData.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(iData.Op) || isGenericReference || isRawGenericParameter) + && typeDuplicateInserter.CheckForDuplicates(iData, sourceUserTypeGOOGLE, out var existingData) && (index != lastResultIndex || desiredResultId == null)) { // Make sure this data is declared at current index, otherwise move it. @@ -75,24 +83,24 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); } - remapIds.Add(i.Data.IdResult.Value, existingData.Data.IdResult.Value); + remapIds.Add(iData.IdResult.Value, existingData.Data.IdResult.Value); lastResultId = existingData.Data.IdResult.Value; } else { - if (isGenericReference) - i.Data.Memory.Span[0] = (int)(i.Data.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; + if (isGenericReference || isRawGenericParameter) + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; - if (i.Data.IdResult.HasValue) + if (iData.IdResult.HasValue) { // Make sure to remap last instruction (which we assume is the actual constant) with the desired result ID var resultId = index == lastResultIndex && desiredResultId != null ? desiredResultId.Value : bound++; - remapIds.Add(i.Data.IdResult.Value, resultId); - i.Data.IdResult = resultId; - typeDuplicateInserter.InsertInstruction(instructionIndex++, i.Data); + remapIds.Add(iData.IdResult.Value, resultId); + iData.IdResult = resultId; + typeDuplicateInserter.InsertInstruction(instructionIndex++, iData); // For OpTypeImage: also insert the UserTypeGOOGLE decoration so it stays // paired with the type during future deduplication in the mixer. @@ -114,13 +122,15 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI if (desiredResultId != null && lastResultId != desiredResultId) throw new InvalidOperationException(); - // Carry over names from source context for all remapped IDs + // Carry over names from source context for all remapped IDs. + // We must also emit OpName instructions into the buffer so that downstream consumers + // (e.g. MergeClassInBuffers) that read names from the buffer can find them. if (sourceNames != null) { foreach (var (sourceId, destId) in remapIds) { - if (sourceNames.TryGetValue(sourceId, out var name)) - Names.TryAdd(destId, name); + if (sourceNames.TryGetValue(sourceId, out var name) && Names.TryAdd(destId, name)) + Buffer.Add(new Spirv.Core.OpName(destId, name)); } } @@ -131,9 +141,9 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI { if (inst.Op == Specification.Op.OpName) { - OpName nameInst = inst; - if (remapIds.TryGetValue(nameInst.Target, out var remappedTarget)) - Names.TryAdd(remappedTarget, nameInst.Name); + Spirv.Core.OpName nameInst = inst; + if (remapIds.TryGetValue(nameInst.Target, out var remappedTarget) && Names.TryAdd(remappedTarget, nameInst.Name)) + Buffer.Add(new Spirv.Core.OpName(remappedTarget, nameInst.Name)); } } @@ -146,13 +156,22 @@ public SpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) // TODO: separate simplification from computing value? TryGetConstantValue(constantId, out _, out _, true); + return ExtractConstantFromBuffer(constantId, Buffer); + } + + /// + /// Extracts a constant and all its transitive dependencies from a buffer into a new standalone buffer. + /// Works on any buffer (not just this context's buffer). + /// + public static SpirvBuffer ExtractConstantFromBuffer(int constantId, SpirvBuffer source) + { // Go backward and find any reference var newBuffer = new SpirvBuffer(); var referenced = new HashSet { constantId }; var instructions = new List(); - for (int index = Buffer.Count - 1; index >= 0; --index) + for (int index = source.Count - 1; index >= 0; --index) { - var i = Buffer[index]; + var i = source[index]; if (i.Data.IdResult is int resultId && referenced.Remove(resultId)) { var i2 = new OpData(i.Data.Memory.Span); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index fde5682f2e..f6bb23f6ed 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -50,7 +50,7 @@ public bool Equals(ShaderLoadKey other) public virtual void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash = null) { bytecode.Context.Frozen = true; - + lock (loadedShaders) { ref var loadedShadersByName = ref CollectionsMarshal.GetValueRefOrAddDefault(loadedShaders, (name, generics), out var exists); @@ -258,6 +258,7 @@ public SpirvContext FluentAdd(in T value, out T result) public void RemoveNameAndDecorations(HashSet ids) { + ThrowIfFrozen(); foreach (var i in Buffer) { if (i.Op == Op.OpDecorate && ((OpDecorate)i) is { } decorate) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 54946cfda0..1d0cfa0336 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -254,15 +254,18 @@ private int RegisterArrayType(ArrayType a) } else if (a.SizeExpression is { } sizeExpression) { - // Import constants + // Import constants from the foreign buffer into this context var importBuffer = sizeExpression.Buffer; if (importBuffer != Buffer) { - var resultId = InsertWithoutDuplicates(null, importBuffer); - a.SizeExpression = (resultId, Buffer); - // Now that we reference a constant in context buffer, - // check again if array is not already added (if constants are unified, it should work) - if (Types.TryGetValue(a, out var res)) + // Extract just the constant and its dependencies to avoid importing + // unrelated types (e.g. OpTypeStruct, OpTypePointer) from the full buffer. + var constantBuffer = ExtractConstantFromBuffer(sizeExpression.Id, importBuffer); + var resultId = InsertWithoutDuplicates(null, constantBuffer); + // Do NOT mutate a.SizeExpression — the ArrayType may be shared across + // cached ShaderDefinitions. Use a local copy for the deduplication check. + var localArray = a with { SizeExpression = (resultId, Buffer) }; + if (Types.TryGetValue(localArray, out var res)) return res; sizeId = resultId; } From 36ada03d97d5b00bb087eee662850d1d0a061beb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 19:02:49 +0900 Subject: [PATCH 0965/1182] SDSL: Add ConstantExpression types for context-independent constant representation Introduces ConstantExpression hierarchy (IntConstExpr, FloatConstExpr, BoolConstExpr, StringConstExpr, GenericParamExpr, UnaryOpExpr, BinaryOpExpr, SelectExpr) with ParseFromBuffer, Emit, TryEvaluate, and Substitute methods. These will replace raw SPIR-V ID + buffer references in ArrayType.SizeExpression and ShaderClassInstantiation.GenericArguments. --- .../Core/ConstantExpression.cs | 497 ++++++++++++++++++ 1 file changed, 497 insertions(+) create mode 100644 sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs new file mode 100644 index 0000000000..aa0ca76b24 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs @@ -0,0 +1,497 @@ +using Stride.Shaders.Spirv; +using Stride.Shaders.Spirv.Building; +using Stride.Shaders.Spirv.Core; +using Stride.Shaders.Spirv.Core.Buffers; +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Core; + +/// +/// Context-independent constant expression with value equality. +/// Replaces raw SPIR-V ID + buffer references for array sizes and generic arguments. +/// +public abstract record ConstantExpression +{ + /// + /// Emit into a SPIR-V context, returning the result ID. Handles dedup via existing context caches. + /// + public abstract int Emit(SpirvContext context); + + /// + /// Try to evaluate to a concrete value without SPIR-V context. + /// Returns false for unresolved generic parameters and expressions containing them. + /// + public abstract bool TryEvaluate(out object? value); + + /// + /// Replace GenericParamExpr nodes matching the given declaringClass with resolved values. + /// Returns this if no substitution occurred. + /// + public virtual ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) => this; + + /// + /// Look up the ResultType of an emitted instruction by its ID. + /// + protected static int GetEmittedTypeId(SpirvContext context, int instructionId) + { + if (context.GetBuffer().TryGetInstructionById(instructionId, out var inst)) + { + if (inst.Data.IdResultType is int typeId) + return typeId; + } + throw new InvalidOperationException($"Cannot determine type for emitted instruction {instructionId}"); + } + + /// + /// Create a ConstantExpression from a concrete runtime value. + /// + public static ConstantExpression FromValue(object value) => value switch + { + int i => new IntConstExpr(i), + uint u => new IntConstExpr(u), + long l => new IntConstExpr(l), + ulong u => new IntConstExpr((long)u), + float f => new FloatConstExpr(f), + double d => new FloatConstExpr(d), + bool b => new BoolConstExpr(b), + string s => new StringConstExpr(s), + _ => throw new NotSupportedException($"Unsupported constant type: {value.GetType()}") + }; + + /// + /// Parse a SPIR-V constant ID into a ConstantExpression tree. + /// Replaces ExtractConstantFromBuffer for array sizes and generic arguments. + /// + public static ConstantExpression ParseFromBuffer(int constantId, SpirvBuffer buffer, SpirvContext context) + { + if (!buffer.TryGetInstructionById(constantId, out var inst)) + throw new InvalidOperationException($"Cannot find instruction for id {constantId}"); + + return ParseInstruction(inst, buffer, context); + } + + private static ConstantExpression ParseInstruction(OpDataIndex inst, SpirvBuffer buffer, SpirvContext context) + { + switch (inst.Op) + { + case Op.OpConstantTrue: + return new BoolConstExpr(true); + + case Op.OpConstantFalse: + return new BoolConstExpr(false); + + case Op.OpConstant: + case Op.OpSpecConstant: + { + var typeId = inst.Data.Memory.Span[1]; + var operand = inst.Data.Get("value"); + if (buffer.TryGetInstructionById(typeId, out var typeInst)) + { + if (typeInst.Op == Op.OpTypeInt) + { + var type = (OpTypeInt)typeInst; + long val = type switch + { + { Width: <= 32, Signedness: 0 } => (long)operand.ToLiteral(), + { Width: <= 32, Signedness: 1 } => operand.ToLiteral(), + { Width: 64, Signedness: 0 } => (long)operand.ToLiteral(), + { Width: 64, Signedness: 1 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported int width {type.Width}"), + }; + return new IntConstExpr(val); + } + else if (typeInst.Op == Op.OpTypeFloat) + { + var type = new OpTypeFloat(typeInst); + double val = type switch + { + { Width: 16 } => (double)operand.ToLiteral(), + { Width: 32 } => operand.ToLiteral(), + { Width: 64 } => operand.ToLiteral(), + _ => throw new NotImplementedException($"Unsupported float width {type.Width}"), + }; + return new FloatConstExpr(val); + } + else + throw new NotImplementedException($"Unsupported constant type {typeInst.Op}"); + } + throw new InvalidOperationException($"Cannot find type instruction for id {typeId}"); + } + + case Op.OpConstantStringSDSL: + { + var operand = inst.Data.Get("literalString"); + return new StringConstExpr(operand.ToLiteral()); + } + + case Op.OpSDSLGenericParameter: + case Op.OpSDSLGenericReference: + { + var genParam = (OpSDSLGenericParameter)inst; + return new GenericParamExpr(genParam.Index, genParam.DeclaringClass); + } + + case Op.OpSpecConstantOp: + { + var op = (Op)inst.Data.Memory.Span[3]; + switch (op) + { + // Conversions (unary) + case Op.OpConvertFToS: + case Op.OpConvertFToU: + case Op.OpConvertSToF: + case Op.OpConvertUToF: + case Op.OpSNegate: + case Op.OpFNegate: + case Op.OpNot: + case Op.OpLogicalNot: + { + var operandExpr = ParseFromBuffer(inst.Data.Memory.Span[4], buffer, context); + return new UnaryOpExpr(op, operandExpr); + } + // Binary operations + case Op.OpIAdd: + case Op.OpISub: + case Op.OpIMul: + case Op.OpUDiv: + case Op.OpSDiv: + case Op.OpFAdd: + case Op.OpFSub: + case Op.OpFMul: + case Op.OpFDiv: + case Op.OpShiftRightLogical: + case Op.OpShiftRightArithmetic: + case Op.OpShiftLeftLogical: + case Op.OpBitwiseOr: + case Op.OpBitwiseXor: + case Op.OpBitwiseAnd: + case Op.OpLogicalOr: + case Op.OpLogicalAnd: + case Op.OpLogicalEqual: + case Op.OpLogicalNotEqual: + case Op.OpIEqual: + case Op.OpINotEqual: + case Op.OpULessThan: + case Op.OpSLessThan: + case Op.OpUGreaterThan: + case Op.OpSGreaterThan: + case Op.OpULessThanEqual: + case Op.OpSLessThanEqual: + case Op.OpUGreaterThanEqual: + case Op.OpSGreaterThanEqual: + { + var left = ParseFromBuffer(inst.Data.Memory.Span[4], buffer, context); + var right = ParseFromBuffer(inst.Data.Memory.Span[5], buffer, context); + return new BinaryOpExpr(op, left, right); + } + case Op.OpSelect: + { + var cond = ParseFromBuffer(inst.Data.Memory.Span[4], buffer, context); + var trueVal = ParseFromBuffer(inst.Data.Memory.Span[5], buffer, context); + var falseVal = ParseFromBuffer(inst.Data.Memory.Span[6], buffer, context); + return new SelectExpr(cond, trueVal, falseVal); + } + default: + throw new NotImplementedException($"Unsupported OpSpecConstantOp inner op: {op}"); + } + } + + default: + throw new NotImplementedException($"Cannot parse constant expression from {inst.Op}"); + } + } +} + +/// +/// Integer constant. Covers int, uint, long, ulong — signedness determined at emission by SPIR-V type context. +/// +public sealed record IntConstExpr(long Value) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + // For values that fit in int, use int (signed) — matches the common case for array sizes + if (Value is >= int.MinValue and <= int.MaxValue) + return context.CompileConstant((int)Value).Id; + return context.CompileConstant(Value).Id; + } + + public override bool TryEvaluate(out object? value) + { + if (Value is >= int.MinValue and <= int.MaxValue) + value = (int)Value; + else + value = Value; + return true; + } + + public override string ToString() => Value.ToString(); +} + +/// +/// Float constant. Covers float, double — precision determined at emission. +/// +public sealed record FloatConstExpr(double Value) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + // Use float precision if the value fits without loss + var asFloat = (float)Value; + if ((double)asFloat == Value) + return context.CompileConstant(asFloat).Id; + return context.CompileConstant(Value).Id; + } + + public override bool TryEvaluate(out object? value) + { + var asFloat = (float)Value; + if ((double)asFloat == Value) + value = asFloat; + else + value = Value; + return true; + } + + public override string ToString() => Value.ToString(); +} + +/// +/// Boolean constant. +/// +public sealed record BoolConstExpr(bool Value) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + return context.CompileConstant(Value).Id; + } + + public override bool TryEvaluate(out object? value) + { + value = Value; + return true; + } + + public override string ToString() => Value.ToString(); +} + +/// +/// String constant. Used for LinkType, Semantic, and MemberName generic parameters. +/// Emits as OpConstantStringSDSL. +/// +public sealed record StringConstExpr(string Value) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + var id = context.Bound++; + context.Add(new OpConstantStringSDSL(id, Value)); + return id; + } + + public override bool TryEvaluate(out object? value) + { + value = Value; + return true; + } + + public override string ToString() => $"\"{Value}\""; +} + +/// +/// Reference to a generic parameter from a (possibly ancestor) shader. +/// Replaces both OpSDSLGenericParameter and OpSDSLGenericReference — +/// the distinction disappears at the expression level. +/// +public sealed record GenericParamExpr(int Index, string DeclaringClass) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + // Emit as GenericReference — when this appears in a child context, + // it references the parent's generic parameter + var typeId = context.GetOrRegister(ScalarType.Int); + var id = context.Bound++; + context.Add(new OpSDSLGenericReference(typeId, id, Index, DeclaringClass)); + return id; + } + + public override bool TryEvaluate(out object? value) + { + value = null; + return false; + } + + public override ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) + => declaringClass == DeclaringClass && Index < args.Length ? args[Index] : this; + + public override string ToString() => $"{DeclaringClass}[{Index}]"; +} + +/// +/// Unary spec-constant operation (SNegate, FNegate, Not, LogicalNot, conversions). +/// +public sealed record UnaryOpExpr(Op Op, ConstantExpression Operand) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + var operandId = Operand.Emit(context); + var operandTypeId = GetEmittedTypeId(context, operandId); + var resultTypeId = ResolveResultType(context, operandTypeId); + var resultId = context.Bound++; + Span instruction = [(int)Specification.Op.OpSpecConstantOp, resultTypeId, resultId, (int)Op, operandId]; + instruction[0] |= instruction.Length << 16; + context.Add(new OpData(instruction)); + return resultId; + } + + private int ResolveResultType(SpirvContext context, int operandTypeId) + { + return Op switch + { + // Conversions change the result type + Specification.Op.OpConvertFToS => context.GetOrRegister(ScalarType.Int), + Specification.Op.OpConvertFToU => context.GetOrRegister(ScalarType.UInt), + Specification.Op.OpConvertSToF => context.GetOrRegister(ScalarType.Float), + Specification.Op.OpConvertUToF => context.GetOrRegister(ScalarType.Float), + // Unary ops keep the same type + _ => operandTypeId, + }; + } + + public override bool TryEvaluate(out object? value) + { + value = null; + if (!Operand.TryEvaluate(out var operandValue) || operandValue is null) + return false; + + value = Op switch + { + Specification.Op.OpSNegate => (object)(-(int)operandValue), + Specification.Op.OpFNegate => -(float)operandValue, + Specification.Op.OpNot when operandValue is int i => ~i, + Specification.Op.OpLogicalNot when operandValue is bool b => !b, + Specification.Op.OpConvertFToS => (int)(float)operandValue, + Specification.Op.OpConvertFToU => (uint)(float)operandValue, + Specification.Op.OpConvertSToF => (float)(int)operandValue, + Specification.Op.OpConvertUToF => (float)(uint)operandValue, + _ => null, + }; + return value is not null; + } + + public override ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) + { + var newOperand = Operand.Substitute(declaringClass, args); + if (ReferenceEquals(newOperand, Operand)) return this; + var result = new UnaryOpExpr(Op, newOperand); + return result.TryEvaluate(out var val) && val is not null ? FromValue(val) : result; + } + + public override string ToString() => $"{Op}({Operand})"; +} + +/// +/// Binary spec-constant operation (IAdd, IMul, ISub, etc.) +/// +public sealed record BinaryOpExpr(Op Op, ConstantExpression Left, ConstantExpression Right) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + var leftId = Left.Emit(context); + var rightId = Right.Emit(context); + var resultTypeId = GetEmittedTypeId(context, leftId); + var resultId = context.Bound++; + Span instruction = [(int)Specification.Op.OpSpecConstantOp, resultTypeId, resultId, (int)Op, leftId, rightId]; + instruction[0] |= instruction.Length << 16; + context.Add(new OpData(instruction)); + return resultId; + } + + public override bool TryEvaluate(out object? value) + { + value = null; + if (!Left.TryEvaluate(out var leftVal) || leftVal is null) + return false; + if (!Right.TryEvaluate(out var rightVal) || rightVal is null) + return false; + + value = Op switch + { + Specification.Op.OpIAdd when leftVal is int l && rightVal is int r => (object)(l + r), + Specification.Op.OpISub when leftVal is int l && rightVal is int r => l - r, + Specification.Op.OpIMul when leftVal is int l && rightVal is int r => l * r, + Specification.Op.OpSDiv when leftVal is int l && rightVal is int r => l / r, + Specification.Op.OpUDiv when leftVal is uint l && rightVal is uint r => l / r, + Specification.Op.OpFAdd when leftVal is float l && rightVal is float r => l + r, + Specification.Op.OpFSub when leftVal is float l && rightVal is float r => l - r, + Specification.Op.OpFMul when leftVal is float l && rightVal is float r => l * r, + Specification.Op.OpFDiv when leftVal is float l && rightVal is float r => l / r, + Specification.Op.OpBitwiseAnd when leftVal is int l && rightVal is int r => l & r, + Specification.Op.OpBitwiseOr when leftVal is int l && rightVal is int r => l | r, + Specification.Op.OpBitwiseXor when leftVal is int l && rightVal is int r => l ^ r, + Specification.Op.OpShiftLeftLogical when leftVal is int l && rightVal is int r => l << r, + Specification.Op.OpShiftRightArithmetic when leftVal is int l && rightVal is int r => l >> r, + Specification.Op.OpLogicalAnd when leftVal is bool l && rightVal is bool r => l && r, + Specification.Op.OpLogicalOr when leftVal is bool l && rightVal is bool r => l || r, + Specification.Op.OpLogicalEqual when leftVal is bool l && rightVal is bool r => l == r, + Specification.Op.OpLogicalNotEqual when leftVal is bool l && rightVal is bool r => l != r, + Specification.Op.OpIEqual when leftVal is int l && rightVal is int r => l == r, + Specification.Op.OpINotEqual when leftVal is int l && rightVal is int r => l != r, + Specification.Op.OpSLessThan when leftVal is int l && rightVal is int r => l < r, + Specification.Op.OpSGreaterThan when leftVal is int l && rightVal is int r => l > r, + Specification.Op.OpSLessThanEqual when leftVal is int l && rightVal is int r => l <= r, + Specification.Op.OpSGreaterThanEqual when leftVal is int l && rightVal is int r => l >= r, + _ => null, + }; + return value is not null; + } + + public override ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) + { + var newLeft = Left.Substitute(declaringClass, args); + var newRight = Right.Substitute(declaringClass, args); + if (ReferenceEquals(newLeft, Left) && ReferenceEquals(newRight, Right)) return this; + var result = new BinaryOpExpr(Op, newLeft, newRight); + return result.TryEvaluate(out var val) && val is not null ? FromValue(val) : result; + } + + public override string ToString() => $"({Left} {Op} {Right})"; +} + +/// +/// Ternary select (OpSelect). +/// +public sealed record SelectExpr(ConstantExpression Cond, ConstantExpression TrueVal, ConstantExpression FalseVal) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + var condId = Cond.Emit(context); + var trueId = TrueVal.Emit(context); + var falseId = FalseVal.Emit(context); + var resultTypeId = GetEmittedTypeId(context, trueId); + var resultId = context.Bound++; + Span instruction = [(int)Specification.Op.OpSpecConstantOp, resultTypeId, resultId, (int)Op.OpSelect, condId, trueId, falseId]; + instruction[0] |= instruction.Length << 16; + context.Add(new OpData(instruction)); + return resultId; + } + + public override bool TryEvaluate(out object? value) + { + value = null; + if (!Cond.TryEvaluate(out var condVal) || condVal is not bool b) + return false; + return b ? TrueVal.TryEvaluate(out value) : FalseVal.TryEvaluate(out value); + } + + public override ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) + { + var newCond = Cond.Substitute(declaringClass, args); + var newTrue = TrueVal.Substitute(declaringClass, args); + var newFalse = FalseVal.Substitute(declaringClass, args); + if (ReferenceEquals(newCond, Cond) && ReferenceEquals(newTrue, TrueVal) && ReferenceEquals(newFalse, FalseVal)) + return this; + var result = new SelectExpr(newCond, newTrue, newFalse); + return result.TryEvaluate(out var val) && val is not null ? FromValue(val) : result; + } + + public override string ToString() => $"({Cond} ? {TrueVal} : {FalseVal})"; +} + From 4fbbcc31102d1dc25011e493f1eefd68d6bcb078 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 19:06:10 +0900 Subject: [PATCH 0966/1182] SDSL: Migrate ArrayType.SizeExpression to ConstantExpression Replace (int Id, SpirvBuffer Buffer)? with ConstantExpression? for array size expressions. This eliminates buffer reference equality issues, mutable setter, and complex import/extraction logic in RegisterArrayType. --- .../Core/SymbolTypes.cs | 5 +--- .../Parsing/SDSL/AST/Literals.cs | 3 +- .../Parsing/SDSL/AST/Shader.cs | 6 ++-- .../Spirv/Building/SpirvContext.Types.cs | 28 ++----------------- 4 files changed, 8 insertions(+), 34 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 6d657b1b66..6280239cde 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -2,7 +2,6 @@ using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; -using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; @@ -229,10 +228,8 @@ public sealed partial record MatrixType(ScalarType BaseType, int Rows, int Colum /// /// The base type for the array. /// The size of the array. If -1, it means size is not defined, such as using []. -public sealed partial record ArrayType(SymbolType BaseType, int Size, (int Id, SpirvBuffer Buffer)? SizeExpression = null) : SymbolType() +public sealed partial record ArrayType(SymbolType BaseType, int Size, ConstantExpression? SizeExpression = null) : SymbolType() { - // We want this mutable for internal use - public (int Id, SpirvBuffer Buffer)? SizeExpression { get; set; } = SizeExpression; public override string ToId() => $"{BaseType.ToId()}[{(Size != -1 ? Size : string.Empty)}]"; public override string ToString() => $"{BaseType}[{(Size != -1 ? Size : string.Empty)}]"; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index ceb2de9933..0673da2ec9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -791,7 +791,8 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte arrayComputedSize = (int)value; arraySymbolType = arrayComputedSize != -1 ? new ArrayType(arraySymbolType, arrayComputedSize) - : new ArrayType(arraySymbolType, arrayComputedSize, (constantArraySize.Id, context.GetBuffer())); + : new ArrayType(arraySymbolType, arrayComputedSize, + ConstantExpression.ParseFromBuffer(constantArraySize.Id, context.GetBuffer(), context)); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 88bceea725..3829684f51 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -246,9 +246,9 @@ void RegisterName(int target, string name) } else { - // Constant can't be computed; we need to save aside all opcodes - var bufferForConstant = context.ExtractConstantAsSpirvBuffer(typeArray.Length); - RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, (typeArray.Length, bufferForConstant))); + // Constant can't be computed (e.g. generic-dependent); parse into expression tree + var expr = ConstantExpression.ParseFromBuffer(typeArray.Length, context.GetBuffer(), context); + RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, expr)); } } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 1d0cfa0336..6f6100e76a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -249,35 +249,11 @@ private int RegisterArrayType(ArrayType a) { int sizeId; if (a.Size != -1) - { sizeId = CompileConstant((int)a.Size).Id; - } - else if (a.SizeExpression is { } sizeExpression) - { - // Import constants from the foreign buffer into this context - var importBuffer = sizeExpression.Buffer; - if (importBuffer != Buffer) - { - // Extract just the constant and its dependencies to avoid importing - // unrelated types (e.g. OpTypeStruct, OpTypePointer) from the full buffer. - var constantBuffer = ExtractConstantFromBuffer(sizeExpression.Id, importBuffer); - var resultId = InsertWithoutDuplicates(null, constantBuffer); - // Do NOT mutate a.SizeExpression — the ArrayType may be shared across - // cached ShaderDefinitions. Use a local copy for the deduplication check. - var localArray = a with { SizeExpression = (resultId, Buffer) }; - if (Types.TryGetValue(localArray, out var res)) - return res; - sizeId = resultId; - } - else - { - sizeId = sizeExpression.Id; - } - } + else if (a.SizeExpression is { } expr) + sizeId = expr.Emit(this); else - { throw new InvalidOperationException(); - } return Buffer.Add(new OpTypeArray(Bound++, GetOrRegister(a.BaseType), sizeId)).ResultId; } From f43dd227b82d376193dc3fb77beee52826fd9247 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 19:25:05 +0900 Subject: [PATCH 0967/1182] SDSL: Migrate GenericArguments from int[] to ConstantExpression[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace raw SPIR-V ID references in ShaderSymbol, ShaderDefinition, ShaderClassInstantiation, and effect/mixin generics with structured ConstantExpression trees. This eliminates buffer-dependent equality issues and enables expression-level generic substitution. Key changes: - ShaderSymbol/ShaderDefinition GenericArguments: int[] → ConstantExpression[] - BuildInheritanceListWithoutSelf: expression-level Substitute replaces RemapGenericParameter - InstantiateGenericShader: tracks currentShaderDeclaringClass for self-referencing generics - GenericResolver: uses TryEvaluate/EmitToBuffer instead of context.ExtractConstantAsSpirvBuffer - ConvertToShaderClassSource: parses import generics via ParseFromBuffer --- .../Core/ConstantExpression.cs | 11 ++ .../Core/SymbolTypes.cs | 6 +- .../Parsing/SDFX/AST/Effect.cs | 6 +- .../Parsing/SDSL/AST/Shader.cs | 34 ++--- .../Spirv/Building/Builder.Class.cs | 131 +++++++++--------- .../Spirv/Building/SpirvContext.Types.cs | 18 ++- 6 files changed, 112 insertions(+), 94 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs index aa0ca76b24..ad0743227f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs @@ -42,6 +42,17 @@ protected static int GetEmittedTypeId(SpirvContext context, int instructionId) throw new InvalidOperationException($"Cannot determine type for emitted instruction {instructionId}"); } + /// + /// Emit the expression into a temporary standalone SpirvBuffer. + /// Used when the expression needs to be imported into another context via InsertWithoutDuplicates. + /// + public SpirvBuffer EmitToBuffer() + { + var tempContext = new SpirvContext(); + var resultId = Emit(tempContext); + return SpirvContext.ExtractConstantFromBuffer(resultId, tempContext.GetBuffer()); + } + /// /// Create a ConstantExpression from a concrete runtime value. /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index 6280239cde..ec32efea81 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -424,7 +424,7 @@ public sealed partial record ConstantBufferSymbol(string Name, List Symbols) : SymbolType; public sealed partial record EffectSymbol(string Name, List<(string Name, SymbolType Type)> Symbols) : SymbolType; -public partial record ShaderSymbol(string Name, int[] GenericArguments) : SymbolType +public partial record ShaderSymbol(string Name, ConstantExpression[] GenericArguments) : SymbolType { public virtual bool Equals(ShaderSymbol? other) => other is not null @@ -460,7 +460,6 @@ public override string ToString() { if (i > 0) builder.Append(','); - builder.Append('%'); builder.Append(GenericArguments[i]); } builder.Append('>'); @@ -469,7 +468,7 @@ public override string ToString() } } -public sealed partial record ShaderDefinition(string Name, int[] GenericArguments) +public sealed partial record ShaderDefinition(string Name, ConstantExpression[] GenericArguments) { public string ToClassName() { @@ -491,7 +490,6 @@ public override string ToString() { if (i > 0) builder.Append(','); - builder.Append('%'); builder.Append(GenericArguments[i]); } builder.Append('>'); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs index f1cc8c28a8..a6686f7349 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs @@ -27,10 +27,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) Block.Compile(table, compiler); } - internal static int[] CompileGenerics(SymbolTable table, SpirvContext context, ShaderExpressionList? generics) + internal static ConstantExpression[] CompileGenerics(SymbolTable table, SpirvContext context, ShaderExpressionList? generics) { var genericCount = generics != null ? generics.Values.Count : 0; - var genericValues = new int[genericCount]; + var genericValues = new ConstantExpression[genericCount]; if (genericCount > 0) { int genericIndex = 0; @@ -40,7 +40,7 @@ internal static int[] CompileGenerics(SymbolTable table, SpirvContext context, S throw new InvalidOperationException($"Generic value {generic} is not a literal"); generic.ProcessSymbol(table); var compiledValue = generic.CompileConstantValue(table, context); - genericValues[genericIndex++] = compiledValue.Id; + genericValues[genericIndex++] = ConstantExpression.ParseFromBuffer(compiledValue.Id, context.GetBuffer(), context); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 3829684f51..80af94cc24 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -333,7 +333,7 @@ void RegisterName(int target, string name) // When called with allowReplace=true from CreateShaderType, these get upgraded to real ShaderDefinition. else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { - var classSource = new ShaderClassInstantiation(importShader.ShaderName, importShader.Generics.Elements.Memory.ToArray()); + var classSource = SpirvBuilder.ConvertToShaderClassSource(context, importShader); var shaderSymbol = realShaderImporter.Import(classSource, context); RegisterType(importShader.ResultId, shaderSymbol); } @@ -374,11 +374,11 @@ private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext main var instruction = shaderContext[i]; if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) { - var genericIds = importShader.Generics.Elements.Memory.ToArray(); + var classSource = SpirvBuilder.ConvertToShaderClassSource(shaderContext, importShader); // Check if already loaded by name (not by ID — IDs are context-local and can collide // between different cached shader contexts) - var stringKey = ResolveImportStringKey(importShader.ShaderName, genericIds, shaderContext); + var stringKey = ResolveImportStringKey(importShader.ShaderName, classSource.GenericArguments); if (stringKey != null && table.DeclaredShaders.TryGetValue(stringKey, out var existingDef)) { @@ -386,7 +386,6 @@ private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext main continue; } - var classSource = new ShaderClassInstantiation(importShader.ShaderName, genericIds); var shaderDef = LoadAndCacheExternalShaderType(table, mainContext, classSource, shaderContext); table.RegisterLoadedShader(importShader.ResultId, shaderDef); } @@ -398,14 +397,14 @@ private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext main /// the fully-qualified shader name (e.g. "SphericalHarmonicsUtils<3>"), or null if /// any generic argument cannot be resolved as a constant. /// - private static string? ResolveImportStringKey(string shaderName, int[] genericIds, SpirvContext shaderContext) + private static string? ResolveImportStringKey(string shaderName, ConstantExpression[] genericArgs) { - if (genericIds.Length == 0) + if (genericArgs.Length == 0) return shaderName; - var args = new string[genericIds.Length]; - for (int j = 0; j < genericIds.Length; j++) + var args = new string[genericArgs.Length]; + for (int j = 0; j < genericArgs.Length; j++) { - if (!shaderContext.TryGetConstantValue(genericIds[j], out var value, out _, false)) + if (!genericArgs[j].TryEvaluate(out var value) || value is null) return null; args[j] = ShaderClassSource.ConvertGenericArgToString(value); } @@ -527,7 +526,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; builder.Insert(new OpSDSLShader(name)); - var openGenerics = new int[Generics != null ? Generics.Parameters.Count : 0]; + var openGenerics = new ConstantExpression[Generics != null ? Generics.Parameters.Count : 0]; var currentShader = new ShaderDefinition(Name, openGenerics); table.Push(); table.CurrentShader = currentShader; @@ -538,7 +537,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) for (int i = 0; i < Generics.Parameters.Count; i++) { var genericParameter = Generics.Parameters[i]; - openGenerics[i] = ProcessGenericSymbol(table, context, i, genericParameter); + ProcessGenericSymbol(table, context, i, genericParameter); + openGenerics[i] = new GenericParamExpr(i, Name); var genericParameterType = genericParameter.TypeName.Type; if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) @@ -550,7 +550,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) foreach (var mixin in Mixins) { var mixinGenerics = (mixin as GenericIdentifier)?.Generics; - var generics = new int[mixinGenerics != null ? mixinGenerics.Values.Count : 0]; + var generics = new ConstantExpression[mixinGenerics != null ? mixinGenerics.Values.Count : 0]; if (mixinGenerics != null) { for (int i = 0; i < mixinGenerics.Values.Count; i++) @@ -561,21 +561,23 @@ public void Compile(SymbolTable table, CompilerUnit compiler) if (table.TryResolveSymbol(identifier.Name, out var symbol)) { mixinGenerics.Values[i].ProcessSymbol(table); - generics[i] = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; + var constantId = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; + generics[i] = ConstantExpression.ParseFromBuffer(constantId, context.GetBuffer(), context); } else { - generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, identifier.Name)).ResultId; + generics[i] = new StringConstExpr(identifier.Name); } } else if (mixinGenerics.Values[i] is AccessorChainExpression accessChain) { - generics[i] = context.Add(new OpConstantStringSDSL(context.Bound++, accessChain.ToString())).ResultId; + generics[i] = new StringConstExpr(accessChain.ToString()); } else { mixinGenerics.Values[i].ProcessSymbol(table); - generics[i] = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; + var constantId = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; + generics[i] = ConstantExpression.ParseFromBuffer(constantId, context.GetBuffer(), context); } } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 7695a241d3..8d54ea0eb4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -57,13 +57,13 @@ public enum ResolveStep Mix, } -public record class ShaderClassInstantiation(string ClassName, int[] GenericArguments, bool ImportStageOnly = false) : IEquatable +public record class ShaderClassInstantiation(string ClassName, ConstantExpression[] GenericArguments, bool ImportStageOnly = false) : IEquatable { public ShaderBuffers? Buffer { get; set; } public string ClassName { get; set; } = ClassName; - public int[] GenericArguments { get; set; } = GenericArguments; + public ConstantExpression[] GenericArguments { get; set; } = GenericArguments; public ShaderDefinition Symbol { get; set; } @@ -77,7 +77,7 @@ public string ToClassNameWithGenerics() if (GenericArguments != null && GenericArguments.Length > 0) { result.Append('<'); - result.Append(string.Join(",", GenericArguments.Select(x => $"%{x}"))); + result.Append(string.Join(",", GenericArguments.Select(x => x.ToString()))); result.Append('>'); } @@ -132,35 +132,42 @@ public partial class SpirvBuilder { public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderLoader, SpirvContext topLevelContext, ShaderClassInstantiation classSource, ReadOnlySpan macros, SpirvContext declaringContext, List inheritanceList, ResolveStep resolveStep) { - // Build shader name mapping + // Build shader name mapping and collect generic parameter expressions var shaderMapping = new Dictionary(); - var genericParameterRemapping = new Dictionary(); + // Map generic parameter index → resolved expression from classSource + ConstantExpression[]? resolvedGenericArgs = null; + string? declaringClassName = null; + // Also build import-level resolution: map shader name → its import's generic args (as expressions) + // Used to resolve GenericParamExpr that reference parent shaders' generics + var importArgsByName = new Dictionary(); + foreach (var i in declaringContext) { if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { if (genericParameter.Index >= classSource.GenericArguments.Length) throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}"); - genericParameterRemapping.Add(genericParameter.ResultId, classSource.GenericArguments[genericParameter.Index]); + resolvedGenericArgs ??= classSource.GenericArguments; + declaringClassName ??= genericParameter.DeclaringClass; } if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) { var shaderClassSource = ConvertToShaderClassSource(declaringContext, importShader); - shaderMapping[importShader.ResultId] = shaderClassSource; + if (shaderClassSource.GenericArguments.Length > 0) + importArgsByName[importShader.ShaderName] = shaderClassSource.GenericArguments; } } - int RemapGenericParameter(int localGeneric) + ConstantExpression ResolveGenericArg(ConstantExpression arg) { - if (genericParameterRemapping.TryGetValue(localGeneric, out var generic)) - return generic; - - // Otherwise, assume it's a constsant we need to import - var constantBuffer = declaringContext.ExtractConstantAsSpirvBuffer(localGeneric); - var resultId = topLevelContext.InsertWithoutDuplicates(null, constantBuffer); - - return resultId; + // First substitute the current shader's own generics + if (resolvedGenericArgs != null && declaringClassName != null) + arg = arg.Substitute(declaringClassName, resolvedGenericArgs); + // Then resolve any remaining GenericParamExpr by looking up parent imports + if (arg is GenericParamExpr genParam && importArgsByName.TryGetValue(genParam.DeclaringClass, out var parentArgs) && genParam.Index < parentArgs.Length) + arg = ResolveGenericArg(parentArgs[genParam.Index]); + return arg; } // Check inheritance @@ -173,20 +180,27 @@ int RemapGenericParameter(int localGeneric) throw new InvalidOperationException($"BuildInheritanceListWithoutSelf: OpSDSLMixinInherit references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(", ", shaderMapping.Keys)}])"); } - // Remap/import generics - var remappedGenericArguments = shaderName.GenericArguments.ToArray(); - for (int index = 0; index < remappedGenericArguments.Length; index++) - remappedGenericArguments[index] = RemapGenericParameter(remappedGenericArguments[index]); + // Resolve generic arguments: substitute own generics + resolve parent references + if (shaderName.GenericArguments.Length > 0) + { + var remappedArgs = new ConstantExpression[shaderName.GenericArguments.Length]; + for (int index = 0; index < remappedArgs.Length; index++) + remappedArgs[index] = ResolveGenericArg(shaderName.GenericArguments[index]); + shaderName = shaderName with { GenericArguments = remappedArgs }; + } - var remappedShaderName = shaderName with { GenericArguments = remappedGenericArguments }; - BuildInheritanceListIncludingSelf(shaderLoader, topLevelContext, remappedShaderName, macros, inheritanceList, resolveStep); + BuildInheritanceListIncludingSelf(shaderLoader, topLevelContext, shaderName, macros, inheritanceList, resolveStep); } } } public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpSDSLImportShader importShader) { - return new ShaderClassInstantiation(importShader.ShaderName, importShader.Generics.Elements.Memory.ToArray()); + var genericIds = importShader.Generics.Elements.Memory; + var exprs = new ConstantExpression[genericIds.Length]; + for (int i = 0; i < genericIds.Length; i++) + exprs[i] = ConstantExpression.ParseFromBuffer(genericIds.Span[i], declaringContext.GetBuffer(), declaringContext); + return new ShaderClassInstantiation(importShader.ShaderName, exprs); } public static ShaderClassInstantiation BuildInheritanceListIncludingSelf(IExternalShaderLoader shaderLoader, SpirvContext context, ShaderClassInstantiation classSource, ReadOnlySpan macros, List inheritanceList, ResolveStep resolveStep) @@ -306,64 +320,40 @@ class GenericResolverFromInstantiatingBuffer(ShaderClassInstantiation classSourc public override string ResolveGenericAsString(int genericIndex) { - var constantId = classSource.GenericArguments[genericIndex]; - if (!declaringContext.GenericValueCache.TryGetValue(constantId, out var textValue)) - { - textValue = declaringContext.TryGetConstantValue(constantId, out var constantValue, out _, false) - ? ShaderClassSource.ConvertGenericArgToString(constantValue) - : GetIdRefAsString(genericIndex); - - declaringContext.GenericValueCache.Add(constantId, textValue); - } - - return textValue; - } - - private string GetIdRefAsString(int index) - { - return declaringContext.Names.TryGetValue(classSource.GenericArguments[index], out var genericArgumentName) - ? $"%{genericArgumentName}[{classSource.GenericArguments[index]}]" - : $"%{classSource.GenericArguments[index]}"; + var expr = classSource.GenericArguments[genericIndex]; + if (expr.TryEvaluate(out var constantValue) && constantValue is not null) + return ShaderClassSource.ConvertGenericArgToString(constantValue); + return expr.ToString(); } public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) { - if (!declaringContext.TryGetConstantValue(classSource.GenericArguments[index], out value, out _, false)) + var expr = classSource.GenericArguments[index]; + if (expr.TryEvaluate(out var result) && result is not null) { - value = GetIdRefAsString(index); - return false; + value = result; + return true; } - return true; + value = expr.ToString(); + return false; } public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - // TODO: optimization: if it can be resolved fully (declaringContext.TryGetConstantValue succeeds), we could simply use/inject the value as is textValue = ResolveGenericAsString(genericIndex); var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; - var bufferWithConstant = declaringContext.ExtractConstantAsSpirvBuffer(classSource.GenericArguments[genericIndex]); + var expr = classSource.GenericArguments[genericIndex]; - bool resolved = true; - - // Remap OpSDSLGenericParameter to OpSDSLGenericReference - for (int index = 0; index < bufferWithConstant.Count; ++index) - { - var i = bufferWithConstant[index]; - - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter2) - { - bufferWithConstant.Replace(index, new OpSDSLGenericReference(genericParameter2.ResultType, genericParameter2.ResultId, genericParameter2.Index, genericParameter2.DeclaringClass)); - resolved = false; - } - } + // Build a standalone buffer from the expression, then import with the desired result ID. + // This replaces the old extract-from-declaring-context + GenericParameter→GenericReference conversion. + var constantBuffer = expr.EmitToBuffer(); context.RemoveAt(instructionIndex); - // TODO: Try to simplify constant var bound = context.Bound; - int resultId = context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, bufferWithConstant); + context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, constantBuffer); context.Bound = bound; return true; @@ -397,12 +387,14 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st var semantics = new Dictionary(); var genericParameters = new List(); + string? currentShaderDeclaringClass = null; Dictionary? importMap = null; for (int index = 0; index < shaderBuffers.Context.Count; ++index) { var i = shaderBuffers.Context[index]; if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) { + currentShaderDeclaringClass ??= genericParameter.DeclaringClass; var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; var genericParameterName = shaderBuffers.Context.Names[genericParameter.ResultId]; var instructionStart = index; @@ -439,6 +431,15 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st if (inst.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)inst is { } import) importMap[import.ShaderName] = import.Generics.Elements.Memory.ToArray(); } + // Also map the current shader's own resolved generics, so references to + // the current shader's declaring class can be resolved. + if (currentShaderDeclaringClass != null && genericParameters.Count > 0) + { + var currentShaderArgs = new int[genericParameters.Count]; + for (int j = 0; j < genericParameters.Count; j++) + currentShaderArgs[j] = genericParameters[j].ResultId; + importMap[currentShaderDeclaringClass] = currentShaderArgs; + } } // OpSDSLGenericReference has the same layout as OpSDSLGenericParameter @@ -763,11 +764,11 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, var genericValues = new string[classSource.GenericArguments.Length]; for (int i = 0; i < genericValues.Length; i++) { - var constantId = classSource.GenericArguments[i]; - if (context.TryGetConstantValue(constantId, out var constantValue, out _, false)) + var expr = classSource.GenericArguments[i]; + if (expr.TryEvaluate(out var constantValue) && constantValue is not null) genericValues[i] = ShaderClassSource.ConvertGenericArgToString(constantValue); else - throw new InvalidOperationException($"Generic argument {i} (ID %{constantId}) for {classSource.ClassName} could not be resolved during mix phase"); + throw new InvalidOperationException($"Generic argument {i} ({expr}) for {classSource.ClassName} could not be resolved during mix phase"); } var result = GetOrLoadShader(shaderLoader, classSource.ClassName, genericValues, macros); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 6f6100e76a..3670fec43b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -49,7 +49,10 @@ public int GetOrRegister(SymbolType? type) // Fallback: create a minimal import for unresolved shader symbols ThrowIfFrozen(); var id = Bound++; - Add(new OpSDSLImportShader(id, new(ss.Name), new(ss.GenericArguments.AsSpan()))); + var emittedArgs = new int[ss.GenericArguments.Length]; + for (int i = 0; i < emittedArgs.Length; i++) + emittedArgs[i] = ss.GenericArguments[i].Emit(this); + Add(new OpSDSLImportShader(id, new(ss.Name), new(emittedArgs.AsSpan()))); AddName(id, ss.Name); shaderImportIds[ss.Name] = id; return id; @@ -84,16 +87,16 @@ public int GetOrImportShader(ShaderDefinition shaderDef) return ImportShaderType(shaderDef, key); } - // Resolve a shader's generic argument IDs in this context to build a string key like "Shader<3,true>". - // Returns null if any generic arg can't be resolved as a constant. - private string? ResolveShaderStringKey(string name, int[] genericArguments) + // Resolve a shader's generic arguments to build a string key like "Shader<3,true>". + // Returns null if any generic arg can't be evaluated to a concrete value. + private static string? ResolveShaderStringKey(string name, ConstantExpression[] genericArguments) { if (genericArguments.Length == 0) return name; var args = new string[genericArguments.Length]; for (int j = 0; j < genericArguments.Length; j++) { - if (!TryGetConstantValue(genericArguments[j], out var value, out _, false)) + if (!genericArguments[j].TryEvaluate(out var value) || value is null) return null; args[j] = ShaderClassSource.ConvertGenericArgToString(value); } @@ -261,7 +264,10 @@ private int RegisterArrayType(ArrayType a) private int ImportShaderType(ShaderDefinition shaderSymbol, string key) { var id = Bound++; - Add(new OpSDSLImportShader(id, new(shaderSymbol.Name), new(shaderSymbol.GenericArguments.AsSpan()))); + var emittedArgs = new int[shaderSymbol.GenericArguments.Length]; + for (int i = 0; i < emittedArgs.Length; i++) + emittedArgs[i] = shaderSymbol.GenericArguments[i].Emit(this); + Add(new OpSDSLImportShader(id, new(shaderSymbol.Name), new(emittedArgs.AsSpan()))); AddName(id, shaderSymbol.Name); shaderImportIds[key] = id; From 2e395f0e8efcce8e40230869ae42b1920479624f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 20:45:14 +0900 Subject: [PATCH 0968/1182] SDSL: Fix transitive generic reference resolution in InstantiateGenericShader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a shader inherits from a generic parent that itself inherits from another generic parent (e.g., TerrainDrectional → Directional → Base), the import map contains chains of GenericReferences. The single-pass resolution would extract an unresolved reference instead of following the chain to the concrete constant. Now follows transitive references through the import map before extracting the constant buffer, with cycle detection via visited set. --- .../Spirv/Building/Builder.Class.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 8d54ea0eb4..7e5fa7ae0b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -447,6 +447,22 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st if (importMap.TryGetValue(genRef.DeclaringClass, out var args) && genRef.Index < args.Length) { var resolvedArgId = args[genRef.Index]; + + // Follow transitive references: the resolved arg may itself be a GenericReference + // (e.g., ShadowMapReceiverBase refs → ShadowMapReceiverDirectional refs → concrete). + // Resolve the chain before extracting. + var visited = new HashSet(); + while (shaderBuffers.Context.GetBuffer().TryGetInstructionById(resolvedArgId, out var resolvedInst) + && (resolvedInst.Op == Op.OpSDSLGenericReference || resolvedInst.Op == Op.OpSDSLGenericParameter) + && visited.Add(resolvedArgId)) + { + var innerRef = (OpSDSLGenericParameter)resolvedInst; + if (importMap.TryGetValue(innerRef.DeclaringClass, out var innerArgs) && innerRef.Index < innerArgs.Length) + resolvedArgId = innerArgs[innerRef.Index]; + else + break; // Can't resolve further + } + // Extract the resolved constant and its dependencies from the context buffer var constantBuffer = SpirvContext.ExtractConstantFromBuffer(resolvedArgId, shaderBuffers.Context.GetBuffer()); // Remove the GenericReference and insert the resolved constant with the same ResultId From 7ce525bc5feafc62830f5bae7585de39b8a33e67 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:11:50 +0900 Subject: [PATCH 0969/1182] SDSL: Remove unused GenericValueCache from SpirvContext This cache was used by the old GenericResolverFromInstantiatingBuffer to map constant IDs to string representations. After the migration to ConstantExpression, generic value resolution uses expr.TryEvaluate() directly, making this cache dead code. --- .../shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index f6bb23f6ed..3d1c51aa25 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -94,9 +94,8 @@ public interface IExternalShaderLoader // SPIR-V parameters public partial class SpirvContext { - // Used internally by GenericResolverFromInstantiatingBuffer (cache from constant ID to string representation) + // Used internally by GenericResolverFromInstantiatingBuffer internal IShaderCache GenericCache { get; } = new ShaderCache(); - internal Dictionary GenericValueCache { get; } = new(); private int bound = 1; public int ResourceGroupBound { get; set; } = 1; From b4328ec30a4da54c5b9dc140682bc904f1009533 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:25:11 +0900 Subject: [PATCH 0970/1182] SDSL: Migrate ExternalConstant and MethodSymbolDefaultParameters to ConstantExpression Replace raw SpirvContext + int ID references with context-independent ConstantExpression values. Add CompositeConstExpr for vector/composite constants. Delete unused ExtractConstantAsSpirvBuffer method. --- .../Core/ConstantExpression.cs | 63 +++++++++++++++++++ .../Stride.Shaders.Parsers/Core/Symbol.cs | 6 +- .../Parsing/SDSL/AST/Expression.cs | 9 +-- .../Parsing/SDSL/AST/Literals.cs | 10 +-- .../Parsing/SDSL/AST/Shader.cs | 10 ++- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 6 +- .../Spirv/Building/Context.ExtractBuffers.cs | 14 +---- 7 files changed, 82 insertions(+), 36 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs index ad0743227f..ca5a345073 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs @@ -142,6 +142,19 @@ private static ConstantExpression ParseInstruction(OpDataIndex inst, SpirvBuffer return new GenericParamExpr(genParam.Index, genParam.DeclaringClass); } + case Op.OpConstantComposite: + case Op.OpSpecConstantComposite: + { + var typeId = inst.Data.Memory.Span[1]; + if (!context.ReverseTypes.TryGetValue(typeId, out var compositeType)) + throw new InvalidOperationException($"Cannot find type for composite constant type id {typeId}"); + var constituents = inst.Data.Memory.Span[3..]; + var components = new ConstantExpression[constituents.Length]; + for (int i = 0; i < constituents.Length; i++) + components[i] = ParseFromBuffer(constituents[i], buffer, context); + return new CompositeConstExpr(compositeType, components); + } + case Op.OpSpecConstantOp: { var op = (Op)inst.Data.Memory.Span[3]; @@ -506,3 +519,53 @@ public override ConstantExpression Substitute(string declaringClass, ConstantExp public override string ToString() => $"({Cond} ? {TrueVal} : {FalseVal})"; } +/// +/// Composite constant (vector, array, struct). Stores constituent expressions and the composite type. +/// +public sealed record CompositeConstExpr(SymbolType Type, ConstantExpression[] Components) : ConstantExpression +{ + public override int Emit(SpirvContext context) + { + Span componentIds = stackalloc int[Components.Length]; + for (int i = 0; i < Components.Length; i++) + componentIds[i] = Components[i].Emit(context); + var typeId = context.GetOrRegister(Type); + var resultId = context.Bound++; + context.AddData(new OpConstantComposite(typeId, resultId, new(componentIds))); + return resultId; + } + + public override bool TryEvaluate(out object? value) + { + value = null; + return false; + } + + public override ConstantExpression Substitute(string declaringClass, ConstantExpression[] args) + { + var newComponents = new ConstantExpression[Components.Length]; + bool changed = false; + for (int i = 0; i < Components.Length; i++) + { + newComponents[i] = Components[i].Substitute(declaringClass, args); + if (!ReferenceEquals(newComponents[i], Components[i])) + changed = true; + } + return changed ? new CompositeConstExpr(Type, newComponents) : this; + } + + public bool Equals(CompositeConstExpr? other) => + other is not null && Type == other.Type && Components.AsSpan().SequenceEqual(other.Components); + + public override int GetHashCode() + { + var hash = new HashCode(); + hash.Add(Type); + foreach (var c in Components) + hash.Add(c); + return hash.ToHashCode(); + } + + public override string ToString() => $"composite({Type}, [{string.Join(", ", (object[])Components)}])"; +} + diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs index 11c571f33c..258cacb35f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs @@ -1,6 +1,4 @@ using System.Collections.Immutable; -using Stride.Shaders.Spirv; -using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Core; @@ -44,9 +42,9 @@ public enum StreamIO : byte public record struct SymbolID(string Name, SymbolKind Kind, Storage Storage = 0, bool IsStage = false); public record struct StreamInfo(ushort EntryPoint, StreamIO Stream); -public record struct MethodSymbolDefaultParameters(SpirvContext SourceContext, int[] DefaultValues); +public record struct MethodSymbolDefaultParameters(ConstantExpression[] DefaultValues); -public record struct ExternalConstant(SpirvContext SourceContext, int ConstantId); +public record struct ExternalConstant(ConstantExpression Expression); /// /// Defines a symbol. diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 5de4de81b5..730cfe5f28 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -339,13 +339,8 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F { var paramDefinition = functionType.ParameterTypes[arguments.Values.Count + i]; - var source = methodDefaultParametersValue.DefaultValues[^(missingParameters - i)]; - // Import in current buffer - if (methodDefaultParametersValue.SourceContext != context) - { - var bufferForConstant = methodDefaultParametersValue.SourceContext.ExtractConstantAsSpirvBuffer(source); - source = context.InsertWithoutDuplicates(null, bufferForConstant); - } + var expr = methodDefaultParametersValue.DefaultValues[^(missingParameters - i)]; + var source = expr.Emit(context); var paramVariable = context.Bound++; builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 0673da2ec9..34f3894a22 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -385,15 +385,7 @@ public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, if (symbol.ExternalConstant is { } externalConstant) { - if (externalConstant.SourceContext != context) - { - var bufferForConstant = externalConstant.SourceContext.ExtractConstantAsSpirvBuffer(externalConstant.ConstantId); - result.Id = context.InsertWithoutDuplicates(null, bufferForConstant); - } - else - { - result.Id = externalConstant.ConstantId; - } + result.Id = externalConstant.Expression.Emit(context); } else if (symbol.MemberAccessWithImplicitThis is { } thisType) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 80af94cc24..1f3e2e33a2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -457,8 +457,11 @@ private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext if (span.Length >= 3 && span[2] == (int)Decoration.FunctionParameterDefaultValueSDSL) { var target = span[1]; - var defaultIds = span[3..].ToArray(); - methodsDefaultParameters.Add(target, new(shaderBuffers.Context, defaultIds)); + var defaultIds = span[3..]; + var defaultExprs = new ConstantExpression[defaultIds.Length]; + for (int j = 0; j < defaultIds.Length; j++) + defaultExprs[j] = ConstantExpression.ParseFromBuffer(defaultIds[j], shaderBuffers.Context.GetBuffer(), shaderBuffers.Context); + methodsDefaultParameters.Add(target, new(defaultExprs)); } } if (i.Op == Op.OpDecorateString && (OpDecorateString)i is @@ -471,7 +474,8 @@ private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) throw new InvalidOperationException(); var resultType = typeInstruction.Data.IdResultType.Value; - var symbol = new Symbol(new(constName, SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(shaderBuffers.Context, target2), OwnerType: shaderType); + var constExpr = ConstantExpression.ParseFromBuffer(target2, shaderBuffers.Context.GetBuffer(), shaderBuffers.Context); + var symbol = new Symbol(new(constName, SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(constExpr), OwnerType: shaderType); variables.Add((symbol, VariableFlagsMask.None)); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 960972090f..e85e78b1d0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -444,9 +444,13 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) { context.Add(new OpDecorate(function.Id, Specification.Decoration.FunctionParameterDefaultValueSDSL, [.. defaultParameters[firstDefaultParameter..]])); + var defaultExprs = new ConstantExpression[defaultParameters.Length - firstDefaultParameter]; + for (int i = 0; i < defaultExprs.Length; i++) + defaultExprs[i] = ConstantExpression.ParseFromBuffer(defaultParameters[firstDefaultParameter + i], context.GetBuffer(), context); + symbol = symbol with { - MethodDefaultParameters = new(context, defaultParameters.Slice(firstDefaultParameter).ToArray()), + MethodDefaultParameters = new(defaultExprs), }; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index 546d20710a..f1b6542fa3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -42,9 +42,8 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() var isGenericReference = iData.Op == Specification.Op.OpSDSLGenericReference; - // Also detect raw OpSDSLGenericParameter from parent contexts — these leaked through - // ExtractConstantAsSpirvBuffer and must be converted to references so they don't get - // mis-counted as the current shader's own generics. + // Also detect raw OpSDSLGenericParameter from parent contexts — these must be + // converted to references so they don't get mis-counted as the current shader's own generics. var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpSDSLGenericParameter; if (isGenericReference) iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; @@ -150,15 +149,6 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI return lastResultId; } - public SpirvBuffer ExtractConstantAsSpirvBuffer(int constantId) - { - // First, run a simplification pass - // TODO: separate simplification from computing value? - TryGetConstantValue(constantId, out _, out _, true); - - return ExtractConstantFromBuffer(constantId, Buffer); - } - /// /// Extracts a constant and all its transitive dependencies from a buffer into a new standalone buffer. /// Works on any buffer (not just this context's buffer). From cdfca73ca5d481167bd3277cba3204eee5219d06 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:28:41 +0900 Subject: [PATCH 0971/1182] SDSL: Replace TryGetConstantValue(simplifyInBuffer: true) with ParseFromBuffer + TryEvaluate --- .../Parsing/SDSL/AST/Literals.cs | 8 ++++---- .../Spirv/Building/Builder.Class.cs | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 34f3894a22..ab409542c3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -779,12 +779,12 @@ public static SymbolType GenerateArrayType(SymbolTable table, SpirvContext conte arrayComputedSize = (int)i.Value; var constantArraySize = arraySize.CompileConstantValue(table, context); - if (context.TryGetConstantValue(constantArraySize.Id, out var value, out _, true)) - arrayComputedSize = (int)value; + var sizeExpr = ConstantExpression.ParseFromBuffer(constantArraySize.Id, context.GetBuffer(), context); + if (sizeExpr.TryEvaluate(out var value) && value is IConvertible) + arrayComputedSize = Convert.ToInt32(value); arraySymbolType = arrayComputedSize != -1 ? new ArrayType(arraySymbolType, arrayComputedSize) - : new ArrayType(arraySymbolType, arrayComputedSize, - ConstantExpression.ParseFromBuffer(constantArraySize.Id, context.GetBuffer(), context)); + : new ArrayType(arraySymbolType, arrayComputedSize, sizeExpr); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 7e5fa7ae0b..361448b572 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -474,11 +474,21 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st if (i.Op == Op.OpTypeArray && (OpTypeArray)i is { } typeArray) { - // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant) + // Make sure constant is a proper OpConstant (i.e. not an OpSpecConstant/OpSpecConstantOp) if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(typeArray.Length, out var lengthInstruction)) throw new InvalidOperationException(); - if (lengthInstruction.Op != Op.OpConstant && shaderBuffers.Context.TryGetConstantValue(typeArray.Length, out var value, out _, true)) + if (lengthInstruction.Op != Op.OpConstant) { + var expr = ConstantExpression.ParseFromBuffer(typeArray.Length, shaderBuffers.Context.GetBuffer(), shaderBuffers.Context); + if (expr.TryEvaluate(out var value) && value != null) + { + var resultType = lengthInstruction.Data.IdResultType!.Value; + var resultId = lengthInstruction.Data.IdResult!.Value; + if (value is int or long) + shaderBuffers.Context.Replace(lengthInstruction.Index, new OpConstant(resultType, resultId, System.Convert.ToInt32(value))); + else if (value is float or double) + shaderBuffers.Context.Replace(lengthInstruction.Index, new OpConstant(resultType, resultId, System.Convert.ToSingle(value))); + } } } } From d6e46d6dff6faa5c32f499cf909558ba400d5c7c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:35:08 +0900 Subject: [PATCH 0972/1182] SDSL: Remove simplifyInBuffer parameter from TryGetConstantValue --- .../Parsing/SDSL/AST/Shader.cs | 2 +- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 6 +++--- .../Spirv/Building/Context.Constants.cs | 19 ++++--------------- .../Spirv/Processing/TypeDuplicatesRemover.cs | 4 ++-- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 1f3e2e33a2..21d8b48c9f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -239,7 +239,7 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = context.ReverseTypes[typeArray.ElementType]; - if (context.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _, false)) + if (context.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _)) { var arraySize = Convert.ToInt32(arraySizeObject); RegisterType(typeArray.ResultId, new ArrayType(innerType, arraySize)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index e85e78b1d0..4e64c8c18c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -494,7 +494,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler // TODO: avoid emitting in context (use a temp buffer?) var constantArraySize = parameter.CompileConstantValue(table, context); - if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _, false)) + if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _)) throw new InvalidOperationException(); parameters[index] = (int)value; @@ -505,7 +505,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler else if (anyAttribute.Name == "maxvertexcount") { var maxVertexCount = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _, false)) + if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _)) throw new InvalidOperationException(); context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); @@ -513,7 +513,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler else if (anyAttribute.Name == "outputcontrolpoints") { var outputControlPoints = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _, false)) + if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _)) throw new InvalidOperationException(); context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)outputControlPointsValue))); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 8afa27ab3e..0a8f7fbdf2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -41,11 +41,11 @@ public object GetConstantValue(int constantId) throw new Exception("Cannot find constant instruction for id " + constantId); } - public bool TryGetConstantValue(int constantId, [MaybeNullWhen(false)] out object value, out int typeId, bool simplifyInBuffer = false) + public bool TryGetConstantValue(int constantId, [MaybeNullWhen(false)] out object value, out int typeId) { if (Buffer.TryGetInstructionById(constantId, out var constant)) { - return TryGetConstantValue(constant, out value, out typeId, simplifyInBuffer); + return TryGetConstantValue(constant, out value, out typeId); } typeId = 0; @@ -55,14 +55,14 @@ public bool TryGetConstantValue(int constantId, [MaybeNullWhen(false)] out objec public object ResolveConstantValue(OpDataIndex i) { - if (!TryGetConstantValue(i, out var value, out _, false)) + if (!TryGetConstantValue(i, out var value, out _)) throw new InvalidOperationException($"Can't process constant {i.Data.IdResult}"); return value; } // Note: this will return false if constant can't be resolved yet (i.e. due to unresolved generics). If it is not meant to become a constant (even later), behavior is undefined. - public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object value, out int typeId, bool simplifyInBuffer = false) + public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object value, out int typeId) { typeId = 0; value = null; @@ -147,17 +147,6 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object throw new NotImplementedException(); } - if (simplifyInBuffer) - { - ThrowIfFrozen(); - if (value is int valueI) - Buffer.Replace(i.Index, new OpConstant(resultType, resultId, valueI)); - else if (value is float valueF) - Buffer.Replace(i.Index, new OpConstant(resultType, resultId, valueF)); - else - throw new NotImplementedException(); - } - return true; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index 614d24209b..c4ac9c1cca 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -157,8 +157,8 @@ private static int CompareIntConstant(SpirvContext context, int id1, int id2) if (id1 == id2) return 0; - var value1Success = context.TryGetConstantValue(id1, out var value1, out _, false); - var value2Success = context.TryGetConstantValue(id2, out var value2, out _, false); + var value1Success = context.TryGetConstantValue(id1, out var value1, out _); + var value2Success = context.TryGetConstantValue(id2, out var value2, out _); return (value1Success, value2Success) switch { From d52899f7b35c33f28fe9cc0e61f1bbc38ec82a97 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:41:34 +0900 Subject: [PATCH 0973/1182] SDSL: Extract GenericReference opcode swap into named helpers in InsertWithoutDuplicates --- .../Spirv/Building/Context.ExtractBuffers.cs | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index f1b6542fa3..9e7c1b7b49 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -40,13 +40,9 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI var iData = new OpData(source[index].Data.Memory.Span); SpirvBuilder.RemapIds(remapIds, ref iData); - //// If it's a generic reference, remap to OpSDSLGenericParameter which has to match during typeDuplicateInserter.CheckForDuplicates() - var isGenericReference = iData.Op == Specification.Op.OpSDSLGenericReference; - // Also detect raw OpSDSLGenericParameter from parent contexts — these must be - // converted to references so they don't get mis-counted as the current shader's own generics. - var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpSDSLGenericParameter; - if (isGenericReference) - iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; + // For dedup: normalize GenericReference → GenericParameter so it matches existing entries. + // Also detect raw GenericParameter leaked from parent contexts. + var isGenericLike = NormalizeGenericForDedup(ref iData, out var isGenericReference); // For OpTypeImage: find the UserTypeGOOGLE decoration in the source buffer so CheckForDuplicates // can distinguish e.g. Texture2D vs Texture2D (same binary, different return type). @@ -70,7 +66,7 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI } // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) - if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(iData.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(iData.Op) || isGenericReference || isRawGenericParameter) + if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(iData.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(iData.Op) || isGenericLike) && typeDuplicateInserter.CheckForDuplicates(iData, sourceUserTypeGOOGLE, out var existingData) && (index != lastResultIndex || desiredResultId == null)) { @@ -87,8 +83,10 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI } else { - if (isGenericReference || isRawGenericParameter) - iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; + // After dedup failed, restore generic instructions to GenericReference + // so they're properly marked as parent-context references. + if (isGenericLike) + RestoreGenericReference(ref iData); if (iData.IdResult.HasValue) { @@ -149,6 +147,29 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI return lastResultId; } + /// + /// For dedup: temporarily convert GenericReference (and leaked raw GenericParameter from + /// parent contexts) to GenericParameter so they match existing entries during CheckForDuplicates. + /// + /// True if the instruction is a generic-like instruction that participates in dedup. + private static bool NormalizeGenericForDedup(ref OpData iData, out bool isGenericReference) + { + isGenericReference = iData.Op == Specification.Op.OpSDSLGenericReference; + var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpSDSLGenericParameter; + if (isGenericReference) + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; + return isGenericReference || isRawGenericParameter; + } + + /// + /// After a non-deduplicated generic instruction is inserted, restore its opcode + /// to GenericReference so it's properly marked as a parent-context reference. + /// + private static void RestoreGenericReference(ref OpData iData) + { + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; + } + /// /// Extracts a constant and all its transitive dependencies from a buffer into a new standalone buffer. /// Works on any buffer (not just this context's buffer). From 6c532b71b7170b44d638599d607635bdabd67fc7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 21 Mar 2026 21:51:24 +0900 Subject: [PATCH 0974/1182] SDSL: Replace TryGetConstantValue with ParseFromBuffer+TryEvaluate for array sizes and attributes --- .../Parsing/SDSL/AST/Shader.cs | 14 +++------- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 27 +++++++++---------- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 21d8b48c9f..a93e353c25 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -239,17 +239,11 @@ void RegisterName(int target, string name) else if (instruction.Op == Op.OpTypeArray && (OpTypeArray)instruction is { } typeArray) { var innerType = context.ReverseTypes[typeArray.ElementType]; - if (context.TryGetConstantValue(typeArray.Length, out var arraySizeObject, out _)) - { - var arraySize = Convert.ToInt32(arraySizeObject); - RegisterType(typeArray.ResultId, new ArrayType(innerType, arraySize)); - } + var sizeExpr = ConstantExpression.ParseFromBuffer(typeArray.Length, context.GetBuffer(), context); + if (sizeExpr.TryEvaluate(out var arraySizeObj) && arraySizeObj is IConvertible) + RegisterType(typeArray.ResultId, new ArrayType(innerType, Convert.ToInt32(arraySizeObj))); else - { - // Constant can't be computed (e.g. generic-dependent); parse into expression tree - var expr = ConstantExpression.ParseFromBuffer(typeArray.Length, context.GetBuffer(), context); - RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, expr)); - } + RegisterType(typeArray.ResultId, new ArrayType(innerType, -1, sizeExpr)); } else if (instruction.Op == Op.OpTypeRuntimeArray && (OpTypeRuntimeArray)instruction is { } typeRuntimeArray) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 4e64c8c18c..015f4223ad 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -490,33 +490,30 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler Span parameters = stackalloc int[anyAttribute.Parameters.Count]; for (var index = 0; index < anyAttribute.Parameters.Count; index++) { - var parameter = anyAttribute.Parameters[index]; - - // TODO: avoid emitting in context (use a temp buffer?) - var constantArraySize = parameter.CompileConstantValue(table, context); - if (!context.TryGetConstantValue(constantArraySize.Id, out var value, out _)) + var compiled = anyAttribute.Parameters[index].CompileConstantValue(table, context); + var expr = ConstantExpression.ParseFromBuffer(compiled.Id, context.GetBuffer(), context); + if (!expr.TryEvaluate(out var value) || value is null) throw new InvalidOperationException(); - - parameters[index] = (int)value; + parameters[index] = Convert.ToInt32(value); } context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.LocalSize, new(parameters))); } else if (anyAttribute.Name == "maxvertexcount") { - var maxVertexCount = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(maxVertexCount.Id, out var maxVertexCountValue, out _)) + var compiled = anyAttribute.Parameters[0].CompileConstantValue(table, context); + var expr = ConstantExpression.ParseFromBuffer(compiled.Id, context.GetBuffer(), context); + if (!expr.TryEvaluate(out var value) || value is null) throw new InvalidOperationException(); - - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)maxVertexCountValue))); + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new(Convert.ToInt32(value)))); } else if (anyAttribute.Name == "outputcontrolpoints") { - var outputControlPoints = anyAttribute.Parameters[0].CompileConstantValue(table, context); - if (!context.TryGetConstantValue(outputControlPoints.Id, out var outputControlPointsValue, out _)) + var compiled = anyAttribute.Parameters[0].CompileConstantValue(table, context); + var expr = ConstantExpression.ParseFromBuffer(compiled.Id, context.GetBuffer(), context); + if (!expr.TryEvaluate(out var value) || value is null) throw new InvalidOperationException(); - - context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new((int)outputControlPointsValue))); + context.Add(new OpExecutionMode(function.Id, Specification.ExecutionMode.OutputVertices, new(Convert.ToInt32(value)))); } else if (anyAttribute.Name == "patchconstantfunc") { From deeadd8e997a2725ca34245346354dc4e953334f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 22 Mar 2026 02:17:31 +0900 Subject: [PATCH 0975/1182] SDSL: Fold compile-time constant expressions to avoid unsupported OpSpecConstantOp CompileConstantValue was converting all arithmetic to OpSpecConstantOp, even when operands were known OpConstant values. SPIRV-Cross doesn't support all spec constant ops (e.g. FMul). Now folds at compile time when possible, emitting OpConstant/OpConstantComposite instead. Fixes ConstantTypeConversion render test. --- .../SDSL/ShaderMixer.cs | 49 +++++- .../Core/ConstantExpression.cs | 12 ++ .../Spirv/Building/ExpressionExtensions.cs | 139 ++++++++++++++++-- 3 files changed, 189 insertions(+), 11 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 69f666a7e4..497ef48026 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -963,19 +963,64 @@ public static void OffsetIds(OpData inst, int offset) } } + /// + /// SPIR-V spec constants can express operations like OpFMul, OpConvertSToF, etc. via + /// OpSpecConstantOp. However, not all backends (e.g. SPIRV-Cross → HLSL/GLSL) support + /// every operation inside OpSpecConstantOp. This method finds OpSpecConstantOp instructions + /// whose inner operation is NOT in the backend-supported set, resolves them to a concrete + /// value at compile time, and replaces them with plain OpConstant instructions so that + /// the cross-compiler can consume them. + /// private void SimplifyNotSupportedConstantsInShader(SpirvContext context, SpirvBuffer temp) { + // Collect instructions to simplify first to avoid modifying the buffer during iteration + var toSimplify = new List<(int Index, object Value, int TypeId, int ResultId)>(); foreach (var i in context) { if (i.Op == Op.OpSpecConstantOp && (OpSpecConstantOp)i is { } specConstantOp) { if (!ExpressionExtensions.ShaderSpecConstantOpSupportedOps.Contains((Op)specConstantOp.Opcode)) { - // Simplify the constant - context.TryGetConstantValue(i, out _, out _, true); + var resultType = i.Data.Memory.Span[1]; + if (context.TryGetConstantValue(i, out var value, out _) && value != null) + toSimplify.Add((i.Index, value, resultType, i.Data.IdResult!.Value)); } } } + + // Replace each OpSpecConstantOp with a resolved OpConstant + var buffer = context.GetBuffer(); + foreach (var (index, value, typeId, resultId) in toSimplify) + { + // Build replacement OpConstant instruction manually + var wordCount = value is long or ulong or double ? 5 : 4; + var mem = CommunityToolkit.HighPerformance.Buffers.MemoryOwner.Allocate(wordCount); + mem.Span[0] = (wordCount << 16) | (int)Op.OpConstant; + mem.Span[1] = typeId; + mem.Span[2] = resultId; + switch (value) + { + case int v: mem.Span[3] = v; break; + case uint v: mem.Span[3] = unchecked((int)v); break; + case float v: mem.Span[3] = BitConverter.SingleToInt32Bits(v); break; + case long v: + mem.Span[3] = (int)(v & 0xFFFFFFFF); + mem.Span[4] = (int)(v >> 32); + break; + case ulong v: + mem.Span[3] = (int)(v & 0xFFFFFFFF); + mem.Span[4] = (int)(v >> 32); + break; + case double v: + var bits = BitConverter.DoubleToInt64Bits(v); + mem.Span[3] = (int)(bits & 0xFFFFFFFF); + mem.Span[4] = (int)(bits >> 32); + break; + default: + throw new NotSupportedException($"Cannot simplify constant of type {value.GetType()}"); + } + buffer.Replace(index, new OpData(mem)); + } } private static void RemoveInstructionWhere(SpirvBuffer buffer, Func match) diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs index ca5a345073..5c7a505fbb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs @@ -355,6 +355,10 @@ public sealed record UnaryOpExpr(Op Op, ConstantExpression Operand) : ConstantEx { public override int Emit(SpirvContext context) { + // Try constant folding first — avoids OpSpecConstantOp which some backends don't support. + if (TryEvaluate(out var folded) && folded is not null) + return FromValue(folded).Emit(context); + var operandId = Operand.Emit(context); var operandTypeId = GetEmittedTypeId(context, operandId); var resultTypeId = ResolveResultType(context, operandTypeId); @@ -418,6 +422,10 @@ public sealed record BinaryOpExpr(Op Op, ConstantExpression Left, ConstantExpres { public override int Emit(SpirvContext context) { + // Try constant folding first — avoids OpSpecConstantOp which some backends don't support. + if (TryEvaluate(out var folded) && folded is not null) + return FromValue(folded).Emit(context); + var leftId = Left.Emit(context); var rightId = Right.Emit(context); var resultTypeId = GetEmittedTypeId(context, leftId); @@ -486,6 +494,10 @@ public sealed record SelectExpr(ConstantExpression Cond, ConstantExpression True { public override int Emit(SpirvContext context) { + // Try constant folding first — avoids OpSpecConstantOp which some backends don't support. + if (TryEvaluate(out var folded) && folded is not null) + return FromValue(folded).Emit(context); + var condId = Cond.Emit(context); var trueId = TrueVal.Emit(context); var falseId = FalseVal.Emit(context); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs index 2c66ad51e6..4b64f98d67 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/ExpressionExtensions.cs @@ -91,16 +91,36 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol var buffer = compiler.Builder.GetBuffer(); - // Process each instruction and check if it can be converted to constant version + // Process each instruction and check if it can be converted to constant version. + // When all operands are known OpConstant values, fold at compile time to avoid + // OpSpecConstantOp which some SPIR-V backends (e.g. SPIRV-Cross) don't fully support. for (int index = 0; index < buffer.Count; ++index) { var i = buffer[index]; if (i.Op == Op.OpCompositeConstruct) { - i.Data.Memory.Span[0] = (int)Op.OpSpecConstantComposite | (i.Data.Memory.Length << 16); + // Check if all constituents are plain OpConstant — if so, use OpConstantComposite instead of OpSpecConstantComposite. + var span = i.Data.Memory.Span; + bool allConstant = true; + for (int j = 3; j < span.Length; j++) + { + if (!IsPlainConstant(context, span[j])) + { + allConstant = false; + break; + } + } + + if (allConstant) + { + i.Data.Memory.Span[0] = (int)Op.OpConstantComposite | (i.Data.Memory.Length << 16); + } + else + { + i.Data.Memory.Span[0] = (int)Op.OpSpecConstantComposite | (i.Data.Memory.Length << 16); + } - // TODO: Check no IdRef to things outside context var instruction = context.Add(new(i.Data.Memory.Span)); result = new(instruction.Data); } @@ -110,12 +130,19 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol var resultType = i.Data.Memory.Span[1]; var resultId = i.Data.Memory.Span[2]; - Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; - instruction[0] |= instruction.Length << 16; - - // TODO: Check no IdRef to things outside context - context.Add(new OpData(instruction)); - result = new(resultId, resultType); + // Try to fold: if all operands are known constants, compute the result at compile time. + if (TryFoldConstantOp(context, i, out var foldedInstruction)) + { + context.Add(foldedInstruction); + result = new(resultId, resultType); + } + else + { + Span instruction = [(int)Op.OpSpecConstantOp, resultType, resultId, (int)i.Op, .. i.Data.Memory.Span[3..]]; + instruction[0] |= instruction.Length << 16; + context.Add(new OpData(instruction)); + result = new(resultId, resultType); + } } else { @@ -127,4 +154,98 @@ public static SpirvValue CompileConstantValue(this Expression expression, Symbol return result; } + + /// + /// Returns true if the given ID refers to an OpConstant, OpConstantTrue, OpConstantFalse, + /// or OpConstantComposite (i.e. not a spec constant). + /// + private static bool IsPlainConstant(SpirvContext context, int id) + { + if (!context.GetBuffer().TryGetInstructionById(id, out var inst)) + return false; + return inst.Op is Op.OpConstant or Op.OpConstantTrue or Op.OpConstantFalse or Op.OpConstantComposite or Op.OpConstantNull; + } + + /// + /// Try to fold a binary/unary operation at compile time when all operands are known OpConstant values. + /// Returns true and the folded OpConstant instruction if successful. + /// + private static bool TryFoldConstantOp(SpirvContext context, OpDataIndex instruction, out OpData foldedInstruction) + { + foldedInstruction = default; + var span = instruction.Data.Memory.Span; + var resultType = span[1]; + var resultId = span[2]; + var op = instruction.Op; + + // Get the type info for the result + if (!context.GetBuffer().TryGetInstructionById(resultType, out var typeInst)) + return false; + + // Handle unary operations (operand at index 3) + if (span.Length == 4) + { + if (!context.TryGetConstantValue(span[3], out var operandVal, out _) || operandVal is null) + return false; + + object? result = op switch + { + Op.OpSNegate when operandVal is int v => (object)(-(int)v), + Op.OpFNegate when operandVal is float v => -v, + Op.OpConvertFToS when operandVal is float v => (int)v, + Op.OpConvertFToU when operandVal is float v => (uint)v, + Op.OpConvertSToF when operandVal is int v => (float)v, + Op.OpConvertUToF when operandVal is uint v => (float)v, + _ => null, + }; + if (result is null) return false; + foldedInstruction = EmitFoldedConstant(resultType, resultId, result, typeInst); + return true; + } + + // Handle binary operations (operands at index 3, 4) + if (span.Length == 5) + { + if (!context.TryGetConstantValue(span[3], out var leftVal, out _) || leftVal is null) + return false; + if (!context.TryGetConstantValue(span[4], out var rightVal, out _) || rightVal is null) + return false; + + object? result = op switch + { + Op.OpIAdd when leftVal is int l && rightVal is int r => (object)(l + r), + Op.OpISub when leftVal is int l && rightVal is int r => l - r, + Op.OpIMul when leftVal is int l && rightVal is int r => l * r, + Op.OpSDiv when leftVal is int l && rightVal is int r => l / r, + Op.OpFAdd when leftVal is float l && rightVal is float r => l + r, + Op.OpFSub when leftVal is float l && rightVal is float r => l - r, + Op.OpFMul when leftVal is float l && rightVal is float r => l * r, + Op.OpFDiv when leftVal is float l && rightVal is float r => l / r, + Op.OpIAdd when leftVal is uint l && rightVal is uint r => l + r, + Op.OpISub when leftVal is uint l && rightVal is uint r => l - r, + Op.OpIMul when leftVal is uint l && rightVal is uint r => l * r, + Op.OpUDiv when leftVal is uint l && rightVal is uint r => l / r, + _ => null, + }; + if (result is null) return false; + foldedInstruction = EmitFoldedConstant(resultType, resultId, result, typeInst); + return true; + } + + return false; + } + + private static OpData EmitFoldedConstant(int resultType, int resultId, object value, OpDataIndex typeInst) + { + return value switch + { + int v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + uint v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + float v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + double v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + long v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + ulong v => new OpData(new OpConstant(resultType, resultId, v).InstructionMemory), + _ => throw new NotSupportedException($"Cannot fold constant of type {value.GetType()}"), + }; + } } From 211629c1ee8b47a89b08aa9134d329c31f4fb832 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 00:32:30 +0900 Subject: [PATCH 0976/1182] SDSL: Output .spv/.spvdis even if SPV could not be translated to HLSL --- .../EffectCompiler.cs | 277 +++++++++--------- 1 file changed, 142 insertions(+), 135 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index e3eccf625d..89a3d8a22e 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -145,36 +145,8 @@ public override TaskOrResult Compile(ShaderMixinSo var shaderMixer = new ShaderMixer(GetFileShaderLoader()); shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); - if (log.HasErrors) - return new EffectBytecodeCompilerResult(null, log); - - /*var parsingResult = GetMixinParser().Parse(shaderMixinSource, shaderMixinSource.Macros.ToArray()); - - // Copy log from parser results to output - CopyLogs(parsingResult, log); - - // Return directly if there are any errors - if (parsingResult.HasErrors) - { - return new EffectBytecodeCompilerResult(null, log); - } - - // Convert the AST to HLSL - var writer = new Stride.Core.Shaders.Writer.Hlsl.HlslWriter - { - EnablePreprocessorLine = false, // Allow to output links to original pdxsl via #line pragmas - }; - writer.Visit(parsingResult.Shader); - var shaderSourceText = writer.Text; - - if (string.IsNullOrEmpty(shaderSourceText)) - { - log.Error($"No code generated for effect [{fullEffectName}]"); - return new EffectBytecodeCompilerResult(null, log); - }*/ - // ------------------------------------------------------- - // Prepare DynamicCache folder for debug files (written after compilation using output hash) + // Prepare DynamicCache folder for debug files #if STRIDE_PLATFORM_DESKTOP var effectDir = Path.Combine( PlatformFolders.ApplicationCacheDirectory, @@ -183,6 +155,16 @@ public override TaskOrResult Compile(ShaderMixinSo Directory.CreateDirectory(effectDir); #endif + if (log.HasErrors) + { +#if STRIDE_PLATFORM_DESKTOP + if (spirvBytecode is { Length: > 0 }) + lock (WriterLock) + WriteSpvDebugFiles(effectDir, mixinObjectId.ToString(), spirvBytecode.ToArray()); +#endif + return new EffectBytecodeCompilerResult(null, log); + } + // Select the correct backend compiler IShaderCompiler compiler; // Set to null if translator is not needed @@ -213,133 +195,147 @@ public override TaskOrResult Compile(ShaderMixinSo #endif var bytecode = new EffectBytecode { Reflection = effectReflection, HashSources = usedHashSources }; +#if STRIDE_PLATFORM_DESKTOP + var spirvBytecodeForDebug = spirvBytecode.ToArray(); +#endif - if (translatorBackend != null) + try { - var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); - var translatorEntryPoints = translator.GetEntryPoints(); - foreach (var entryPoint in translatorEntryPoints) + if (translatorBackend != null) { - var code = translator.Translate(Backend.Hlsl, entryPoint); - - // Compile - // TODO: We could compile stages in different threads to improve compiler throughput? - var shaderStage = entryPoint.ExecutionModel switch + var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); + var translatorEntryPoints = translator.GetEntryPoints(); + foreach (var entryPoint in translatorEntryPoints) { - ExecutionModel.Vertex => ShaderStage.Vertex, - ExecutionModel.TessellationControl => ShaderStage.Hull, - ExecutionModel.TessellationEvaluation => ShaderStage.Domain, - ExecutionModel.Geometry => ShaderStage.Geometry, - ExecutionModel.Fragment => ShaderStage.Pixel, - ExecutionModel.GLCompute => ShaderStage.Compute, - }; + var code = translator.Translate(Backend.Hlsl, entryPoint); + + // Compile + // TODO: We could compile stages in different threads to improve compiler throughput? + var shaderStage = entryPoint.ExecutionModel switch + { + ExecutionModel.Vertex => ShaderStage.Vertex, + ExecutionModel.TessellationControl => ShaderStage.Hull, + ExecutionModel.TessellationEvaluation => ShaderStage.Domain, + ExecutionModel.Geometry => ShaderStage.Geometry, + ExecutionModel.Fragment => ShaderStage.Pixel, + ExecutionModel.GLCompute => ShaderStage.Compute, + }; #if STRIDE_PLATFORM_DESKTOP - var stageSuffix = shaderStage switch - { - ShaderStage.Vertex => "vs", - ShaderStage.Hull => "hs", - ShaderStage.Domain => "ds", - ShaderStage.Geometry => "gs", - ShaderStage.Pixel => "ps", - ShaderStage.Compute => "cs", - }; - stageHlslSources.Add((stageSuffix, code)); - string stageFilename = null; + var stageSuffix = shaderStage switch + { + ShaderStage.Vertex => "vs", + ShaderStage.Hull => "hs", + ShaderStage.Domain => "ds", + ShaderStage.Geometry => "gs", + ShaderStage.Pixel => "ps", + ShaderStage.Compute => "cs", + }; + stageHlslSources.Add((stageSuffix, code)); + string stageFilename = null; #else - string stageFilename = null; + string stageFilename = null; #endif - var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename); - result.CopyTo(log); + var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename); + result.CopyTo(log); - if (result.HasErrors) - { - continue; - } + if (result.HasErrors) + { + continue; + } - // ------------------------------------------------------- - // Append bytecode id to shader log + // ------------------------------------------------------- + // Append bytecode id to shader log #if STRIDE_PLATFORM_DESKTOP - stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); - if (result.DisassembleText != null) - { - stageStringBuilder.Append(result.DisassembleText); - } + stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); + if (result.DisassembleText != null) + { + stageStringBuilder.Append(result.DisassembleText); + } #endif - // ------------------------------------------------------- + // ------------------------------------------------------- - shaderStageBytecodes.Add(result.Bytecode); + shaderStageBytecodes.Add(result.Bytecode); - // When this is a compute shader, there is no need to scan other stages - if (shaderStage == ShaderStage.Compute) - break; - } + // When this is a compute shader, there is no need to scan other stages + if (shaderStage == ShaderStage.Compute) + break; + } - // Remove unused reflection data, as it is entirely resolved at compile time. - CleanupReflection(bytecode.Reflection); - } - // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) - else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) - { - // Check API - Spv2DXIL.spirv_to_dxil_get_version(); - foreach (var entryPoint in entryPoints) + // Remove unused reflection data, as it is entirely resolved at compile time. + CleanupReflection(bytecode.Reflection); + } + // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) + else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) { - unsafe + // Check API + Spv2DXIL.spirv_to_dxil_get_version(); + foreach (var entryPoint in entryPoints) { - fixed (byte* shaderData = spirvBytecode) + unsafe { - var debugOptions = new DebugOptions(); - var runtimeConf = new RuntimeConf + fixed (byte* shaderData = spirvBytecode) { - runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, - //first_vertex_and_base_instance_mode = SysvalType.Zero, - yzflip_mode = FlipMode.YZFlipNone, - shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, - }; - var logger = new DXILSpirvLogger(); - var result = Spv2DXIL.spirv_to_dxil((uint*)shaderData, spirvBytecode.Length / 4, - null, 0, - entryPoint.Stage switch + var debugOptions = new DebugOptions(); + var runtimeConf = new RuntimeConf { - ShaderStage.Vertex => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_VERTEX, - ShaderStage.Hull => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, - ShaderStage.Domain => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, - ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, - ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, - ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, - }, - entryPoint.Name, - ValidatorVersion.DXIL_VALIDATOR_1_4, - ref debugOptions, ref runtimeConf, ref logger, out var dxil); - - Span dxilSpan = new(dxil.buffer, (int)dxil.size); - fixed (byte* dxilSpanPtr = dxilSpan) - DxilHash.ComputeHashRetail(&dxilSpanPtr[20], (uint)(dxilSpan.Length - 20), &dxilSpanPtr[4]); - shaderStageBytecodes.Add(new ShaderBytecode(entryPoint.Stage, ObjectId.FromBytes(dxilSpan), dxilSpan.ToArray())); + runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, + //first_vertex_and_base_instance_mode = SysvalType.Zero, + yzflip_mode = FlipMode.YZFlipNone, + shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, + }; + var logger = new DXILSpirvLogger(); + var result = Spv2DXIL.spirv_to_dxil((uint*)shaderData, spirvBytecode.Length / 4, + null, 0, + entryPoint.Stage switch + { + ShaderStage.Vertex => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_VERTEX, + ShaderStage.Hull => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, + ShaderStage.Domain => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, + ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, + ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, + ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, + }, + entryPoint.Name, + ValidatorVersion.DXIL_VALIDATOR_1_4, + ref debugOptions, ref runtimeConf, ref logger, out var dxil); + + Span dxilSpan = new(dxil.buffer, (int)dxil.size); + fixed (byte* dxilSpanPtr = dxilSpan) + DxilHash.ComputeHashRetail(&dxilSpanPtr[20], (uint)(dxilSpan.Length - 20), &dxilSpanPtr[4]); + shaderStageBytecodes.Add(new ShaderBytecode(entryPoint.Stage, ObjectId.FromBytes(dxilSpan), dxilSpan.ToArray())); + } } } } - } - else - { - var spirvBytecodeArray = spirvBytecode.ToArray(); - var spirvBytecodeId = ObjectId.FromBytes(spirvBytecode); - foreach (var entryPoint in entryPoints) + else { - var entryPointName = new byte[Encoding.UTF8.GetByteCount(entryPoint.Name) + 1]; - entryPointName[^1] = 0; - Encoding.UTF8.GetBytes(entryPoint.Name.AsSpan(), entryPointName); - - shaderStageBytecodes.Add(new ShaderBytecode + var spirvBytecodeArray = spirvBytecode.ToArray(); + var spirvBytecodeId = ObjectId.FromBytes(spirvBytecode); + foreach (var entryPoint in entryPoints) { - Stage = entryPoint.Stage, - Data = spirvBytecodeArray, - Id = spirvBytecodeId, - EntryPoint = entryPointName, - }); + var entryPointName = new byte[Encoding.UTF8.GetByteCount(entryPoint.Name) + 1]; + entryPointName[^1] = 0; + Encoding.UTF8.GetBytes(entryPoint.Name.AsSpan(), entryPointName); + + shaderStageBytecodes.Add(new ShaderBytecode + { + Stage = entryPoint.Stage, + Data = spirvBytecodeArray, + Id = spirvBytecodeId, + EntryPoint = entryPointName, + }); + } } } + catch (Exception) + { +#if STRIDE_PLATFORM_DESKTOP + lock (WriterLock) + WriteSpvDebugFiles(effectDir, mixinObjectId.ToString(), spirvBytecodeForDebug); +#endif + throw; + } bytecode.Stages = shaderStageBytecodes.ToArray(); @@ -350,12 +346,8 @@ public override TaskOrResult Compile(ShaderMixinSo var shaderBaseFilename = Path.Combine(effectDir, outputHash.ToString()); lock (WriterLock) // protect write in case the same shader is created twice { - // Write SPV, disassembly and ShaderSource (skip if already written by another input with same output) - if (!File.Exists(shaderBaseFilename + ".spv")) - { - File.WriteAllBytes(shaderBaseFilename + ".spv", spirvBytecode); - File.WriteAllText(shaderBaseFilename + ".spvdis", Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); - } + // Note: we used input hash in previous case because bytecode was not valid, but when available we prefer bytecode hash + WriteSpvDebugFiles(effectDir, outputHash.ToString(), spirvBytecodeForDebug); // Write per-stage HLSL foreach (var (suffix, hlslCode) in stageHlslSources) @@ -505,5 +497,20 @@ private static void CleanupReflection(EffectReflection reflection) } } } + +#if STRIDE_PLATFORM_DESKTOP + /// + /// Writes .spv and .spvdis files. Caller must hold WriterLock. + /// + private static void WriteSpvDebugFiles(string effectDir, string hashName, byte[] spirvBytecode) + { + var baseFilename = Path.Combine(effectDir, hashName); + if (!File.Exists(baseFilename + ".spv")) + { + File.WriteAllBytes(baseFilename + ".spv", spirvBytecode); + File.WriteAllText(baseFilename + ".spvdis", Spirv.Tools.Spv.Dis(SpirvBytecode.CreateFromSpan(spirvBytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex)); + } + } +#endif } } From 796329c59a0b80d3b1f8ea1e8e194f9eadecfe5a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 12:28:57 +0900 Subject: [PATCH 0977/1182] SDSL: Add ResourceGroup info in meta.txt and put all Macros in one line --- .../shaders/Stride.Shaders.Compilers/EffectCompiler.cs | 8 ++++---- sources/shaders/Stride.Shaders/ShaderSourceToCode.cs | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 89a3d8a22e..3e3b9bbf57 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -382,10 +382,10 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine("***************************"); foreach (var cBuffer in bytecode.Reflection.ConstantBuffers) { - builder.AppendFormat("cbuffer {0} [Size: {1}]", cBuffer.Name, cBuffer.Size).AppendLine(); + builder.AppendLine($"cbuffer {cBuffer.Name} [Size: {cBuffer.Size}]"); foreach (var parameter in cBuffer.Members) { - builder.AppendFormat("@C {0} => {1} [LogicalGroup: {2}]", parameter.RawName, parameter.KeyInfo.KeyName, parameter.LogicalGroup).AppendLine(); + builder.AppendLine($"@C {parameter.RawName} => {parameter.KeyInfo.KeyName} [LogicalGroup: {parameter.LogicalGroup}]"); } } builder.AppendLine("***************************"); @@ -397,7 +397,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine("***************************"); foreach (var resource in bytecode.Reflection.ResourceBindings) { - builder.AppendFormat("@R {0} => {1} [LogicalGroup: {2} Stage: {3}, Slot: ({4}-{5})]", resource.RawName, resource.KeyInfo.KeyName, resource.LogicalGroup, resource.Stage, resource.SlotStart, resource.SlotStart + resource.SlotCount - 1).AppendLine(); + builder.AppendLine($"@R {resource.RawName} => {resource.KeyInfo.KeyName} [ResourceGroup: {resource.ResourceGroup} LogicalGroup: {resource.LogicalGroup} Stage: {resource.Stage}, Slot: ({resource.SlotStart}-{resource.SlotStart + resource.SlotCount - 1})]"); } builder.AppendLine("***************************"); } @@ -408,7 +408,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine("***************************"); foreach (var hashSource in bytecode.HashSources) { - builder.AppendFormat("@S {0} => {1}", hashSource.Key, hashSource.Value).AppendLine(); + builder.AppendLine($"@S {hashSource.Key} => {hashSource.Value}"); } builder.AppendLine("***************************"); } diff --git a/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs b/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs index e41558658f..78504376aa 100644 --- a/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs +++ b/sources/shaders/Stride.Shaders/ShaderSourceToCode.cs @@ -87,13 +87,12 @@ static void ToCode(ShaderSource source, StringBuilder sb) if (mixinSource.Macros != null && mixinSource.Macros.Count > 0) { - sb.AppendLine($"Macros ="); - sb.AppendLine($"{{"); + sb.Append($"Macros = {{ "); for (int i = 0; i < mixinSource.Macros.Count; i++) { - sb.AppendLine($"new ShaderMacro(\"{mixinSource.Macros[i].Name}\", \"{mixinSource.Macros[i].Definition}\"),"); + sb.Append($"new ShaderMacro(\"{mixinSource.Macros[i].Name}\", \"{mixinSource.Macros[i].Definition}\"),"); } - sb.AppendLine($"}},"); + sb.AppendLine($" }},"); } sb.Append($"}}"); From 714c6349567ff510476e90824e286b8045198922 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 12:53:29 +0900 Subject: [PATCH 0978/1182] SDSL: FindOperandInfo for flags was not thread-safe --- .../Parsing/OpDataEnumerator.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs index 20ea35928d..6bbe5e4762 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Parsing/OpDataEnumerator.cs @@ -47,15 +47,15 @@ public OpDataEnumerator(Span instruction) private bool FindOperandInfo(OperandParameters p, ParameterizedOperandKey key, [MaybeNullWhen(false)] out ParameterizedOperand[] operands) { - if (p.TryGetValue(key, out operands)) - return true; - - // ImageOperands is used as a flag. Each flag set will expect corresponding operand(s) (flags should be tested in ascending order) - // TODO: Does it apply to other operand kinds as well? - if (key.Kind == OperandKind.ImageOperands) + // In case it's run multithreaded + lock (p) { - // In case it's run multithreaded - lock (p) + if (p.TryGetValue(key, out operands)) + return true; + + // ImageOperands is used as a flag. Each flag set will expect corresponding operand(s) (flags should be tested in ascending order) + // TODO: Does it apply to other operand kinds as well? + if (key.Kind == OperandKind.ImageOperands) { // First time we encounter this combination, build it using flags var operandsList = new List(); From 4f24fb5c33563ed64106e05425f0f3c8b347a8f2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 15:12:56 +0900 Subject: [PATCH 0979/1182] SDSL: Emit MemberName generic args as GenericParamExpr for proper transitive resolution --- .../Stride.Shaders.Compilers/ShaderLoaderBase.cs | 2 +- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs | 11 +++++++++++ .../Spirv/Building/Builder.Class.cs | 10 +++++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 8ecd39b3e1..658516ba50 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -139,7 +139,7 @@ protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, var log = Log ?? new LoggerResult(); if (!sdslc.Compile(filename, text, hash, macros, log, out buffer)) { - if (Log == null && log is LoggerResult loggerResult && loggerResult.HasErrors) + if (log is LoggerResult loggerResult && loggerResult.HasErrors) throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.Text))); return false; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index a93e353c25..eed8b31f8e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -530,6 +530,8 @@ public void Compile(SymbolTable table, CompilerUnit compiler) table.CurrentShader = currentShader; var hasUnresolvableGenerics = false; + // Map MemberName parameter names to their GenericParamExpr so inheritance args can reference them + var memberNameParams = new Dictionary(); if (Generics != null) { for (int i = 0; i < Generics.Parameters.Count; i++) @@ -540,7 +542,10 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var genericParameterType = genericParameter.TypeName.Type; if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) + { hasUnresolvableGenerics = true; + memberNameParams[genericParameter.Name] = new GenericParamExpr(i, Name); + } } } @@ -562,6 +567,12 @@ public void Compile(SymbolTable table, CompilerUnit compiler) var constantId = mixinGenerics.Values[i].CompileConstantValue(table, context).Id; generics[i] = ConstantExpression.ParseFromBuffer(constantId, context.GetBuffer(), context); } + else if (memberNameParams.TryGetValue(identifier.Name, out var memberNameRef)) + { + // MemberName generic params aren't in the symbol table but should be + // referenced as GenericParamExpr so they participate in generic resolution + generics[i] = memberNameRef; + } else { generics[i] = new StringConstExpr(identifier.Name); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 361448b572..3025025a60 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -580,17 +580,17 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri var code = unresolvableShader.ShaderCode; if (instantiatedGenericsMacros.Count > 0) { - // Add something to shaderName (which is used as key in ShaderLoader cache) - var originalShaderName = shaderName; - shaderName += $"_{string.Join("_", instantiatedGenericsMacros.Select(x => RemoveInvalidCharactersFromSymbol(x.Definition)))}"; + // Use a unique cache key but keep the original shader class name in the source code. + // This ensures OpSDSLGenericReference.DeclaringClass still matches the import name. + var cacheKey = shaderName + $"_{string.Join("_", instantiatedGenericsMacros.Select(x => RemoveInvalidCharactersFromSymbol(x.Definition)))}"; // Note: we apply the preprocessor only the shader body to transform generics parameter into their actual value without touching the generic definition code = code.Substring(0, unresolvableShader.ShaderCodeNameEnd) - // Update shader name for ShaderLoader cache - .Replace(originalShaderName, shaderName) // Mark MemberName as resolved .Replace("MemberName ", "MemberNameResolved ") + MonoGamePreProcessor.Run(code.Substring(unresolvableShader.ShaderCodeNameEnd), $"{shaderName}.sdsl", CollectionsMarshal.AsSpan(instantiatedGenericsMacros)); + + shaderName = cacheKey; } // TODO: Cache? From 85199e48a3d211181085c679f6196eab7143b0a6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 15:28:31 +0900 Subject: [PATCH 0980/1182] SDSL: ShaderLoaderBase (using code instead of name for filename) --- sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 658516ba50..96016eef38 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -71,7 +71,7 @@ public bool LoadExternalBuffer(string name, string code, ReadOnlySpan Date: Mon, 23 Mar 2026 16:01:42 +0900 Subject: [PATCH 0981/1182] SDSL: D3D11FrameRenderer.window was static, causing multithreaded test issues --- sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index 7677a9f1ad..a27466ffc4 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -20,7 +20,7 @@ namespace Stride.Shaders.Parsers.Tests; public class D3D11FrameRenderer(uint width = 800, uint height = 600, byte[]? fragmentSpirv = null, byte[]? vertexSpirv = null) : FrameRenderer(width, height, vertexSpirv, fragmentSpirv) { - static IWindow? window; + IWindow? window; DXGI dxgi = null!; D3D11 d3d11 = null!; D3DCompiler compiler = null!; From 3b37b67b3779263ccf427b20b867b69c35c0bac0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 17:28:18 +0900 Subject: [PATCH 0982/1182] SDSL: Add registerInCache flag to SDSLC and fix MemberName cache registration --- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 18 +++++++++++------- .../SDSL/ShaderMixer.cs | 4 ++-- .../ShaderLoaderBase.cs | 13 ++++++------- .../Spirv/Building/Builder.Class.cs | 16 ++++++++-------- .../Spirv/Building/Context.cs | 2 +- .../Stride.Shaders.Tests/ShaderLoader.cs | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 6e9c8451d2..32acef7e0f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -17,7 +17,7 @@ namespace Stride.Shaders.Compilers.SDSL; public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string filename, string code, ObjectId hash, ReadOnlySpan macros, ILogger log, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer) + public readonly bool Compile(string? filename, string code, ObjectId hash, ReadOnlySpan macros, ILogger log, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer, bool registerInCache = true) { lastBuffer = default; @@ -44,11 +44,14 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn CurrentMacros = [.. macros], }; - // Add OpSource - var filenameId = compiler.Context.Add(new OpString(compiler.Context.Bound++, filename)).ResultId; - // TODO: Add SourceLanguage.SDSL - compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, null)); - compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); + // Add OpSource (skip for MemberName recompilations that have no real file) + if (filename != null) + { + var filenameId = compiler.Context.Add(new OpString(compiler.Context.Bound++, filename)).ResultId; + // TODO: Add SourceLanguage.SDSL + compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, null)); + compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); + } // TODO: Do we want to record macros with a custom OpMacroSDSL? (mostly for debug purposes) compiler.Macros.AddRange(macros); @@ -98,7 +101,8 @@ public readonly bool Compile(string filename, string code, ObjectId hash, ReadOn // (e.g. names for imported IDs, or types from InsertWithoutDuplicates). ShaderClass.ProcessNameAndTypes(lastBuffer.Context); - ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); + if (registerInCache) + ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); } else if (declaration is ShaderEffect or EffectParameters) { diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 497ef48026..6ff21e136c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1213,6 +1213,6 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, o return result; } - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) - => inner.LoadExternalBuffer(name, code, defines, out bytecode, out hash, out isFromCache); + public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) + => inner.LoadExternalBuffer(name, filename, code, defines, out bytecode, out hash, out isFromCache); } diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 96016eef38..feff5c5b4c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -65,16 +65,15 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ return true; } - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) + public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) { isFromCache = Cache.TryLoadFromCache(name, null, defines, out buffer, out hash); if (isFromCache) return true; - var filename = $"{name}{(Path.HasExtension(name) ? "" : ".sdsl")}"; - hash = ObjectId.FromBytes(Encoding.UTF8.GetBytes(code)); - if (!LoadFromCode(filename, code, hash, defines, out buffer)) + // Don't auto-register in SDSLC — the caller (InstantiateMemberNames) registers under the cache key + if (!LoadFromCode(filename, code, hash, defines, out buffer, registerInCache: false)) { // If a logger is set, errors are already logged — just return false if (Log != null) @@ -123,13 +122,13 @@ private bool ValidateCachedHashes(ShaderBuffers buffer) return true; } - protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) + protected virtual bool LoadFromCode(string? filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer, bool registerInCache = true) { var defines = new (string Name, string Definition)[macros.Length]; for (int i = 0; i < macros.Length; ++i) defines[i] = (macros[i].Name, macros[i].Definition); - var text = MonoGamePreProcessor.Run(code, Path.GetFileName(filename), defines); + var text = MonoGamePreProcessor.Run(code, filename, defines); var sdslc = new SDSLC { ShaderLoader = this, @@ -137,7 +136,7 @@ protected virtual bool LoadFromCode(string filename, string code, ObjectId hash, // Use provided logger, or a temporary one that throws on errors var log = Log ?? new LoggerResult(); - if (!sdslc.Compile(filename, text, hash, macros, log, out buffer)) + if (!sdslc.Compile(filename, text, hash, macros, log, out buffer, registerInCache)) { if (log is LoggerResult loggerResult && loggerResult.HasErrors) throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.Text))); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 3025025a60..2d40f07092 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -580,22 +580,24 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri var code = unresolvableShader.ShaderCode; if (instantiatedGenericsMacros.Count > 0) { - // Use a unique cache key but keep the original shader class name in the source code. - // This ensures OpSDSLGenericReference.DeclaringClass still matches the import name. var cacheKey = shaderName + $"_{string.Join("_", instantiatedGenericsMacros.Select(x => RemoveInvalidCharactersFromSymbol(x.Definition)))}"; - // Note: we apply the preprocessor only the shader body to transform generics parameter into their actual value without touching the generic definition + // Apply the preprocessor only to the shader body to substitute MemberName values + // without touching the generic definition code = code.Substring(0, unresolvableShader.ShaderCodeNameEnd) - // Mark MemberName as resolved .Replace("MemberName ", "MemberNameResolved ") + MonoGamePreProcessor.Run(code.Substring(unresolvableShader.ShaderCodeNameEnd), $"{shaderName}.sdsl", CollectionsMarshal.AsSpan(instantiatedGenericsMacros)); shaderName = cacheKey; } - // TODO: Cache? - if (!shaderLoader.LoadExternalBuffer(shaderName, code, macros, out shaderBuffers, out _, out _)) + // filename: null — no OpSource emitted (this is a MemberName recompilation, not a real file) + // registerInCache: false — we register under the cache key ourselves + if (!shaderLoader.LoadExternalBuffer(shaderName, null, code, macros, out shaderBuffers, out var compiledHash, out _)) throw new InvalidOperationException(); + + // Register under the MemberName cache key (e.g. "Foo_PerMaterial") + shaderLoader.Cache.RegisterShader(shaderName, null, macros, shaderBuffers, compiledHash); } } } @@ -819,8 +821,6 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, { var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var hash, out var isFromCache); - // Split context and buffer - if (genericResolver.GenericArgumentCount > 0) { // First, try to build name for cache lookup diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 3d1c51aa25..b87affb225 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -87,7 +87,7 @@ public interface IExternalShaderLoader public bool Exists(string name); public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); - public bool LoadExternalBuffer(string name, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); + public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs index 45645dcdac..8d34f41b5b 100644 --- a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -45,7 +45,7 @@ public override bool LoadExternalFileContent(string name, out string filename, o protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) { - var result = base.LoadFromCode(filename, code, hash, macros, out buffer); + var result = base.LoadFromCode(filename, code, hash, macros, out buffer, registerInCache); if (result) { Console.WriteLine($"Loading shader {filename}"); From 2b296c218dc319bfcbd31c5fecf31d8c87d68da8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 19:03:02 +0900 Subject: [PATCH 0983/1182] SDSL: Add Lazy<> compilation gate to prevent redundant parallel shader compilations --- .../ShaderLoaderBase.cs | 64 +++++++++++++---- .../Spirv/Building/Builder.Class.cs | 69 ++++++++++++++++--- 2 files changed, 109 insertions(+), 24 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index feff5c5b4c..2f14b8cc8c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Text; @@ -17,6 +18,11 @@ public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShader { public IShaderCache Cache => fileCache; + /// + /// Ensures only one thread compiles a given shader at a time. Other threads wait for the result. + /// + private readonly ConcurrentDictionary<(string Name, int MacrosHash), Lazy<(ShaderBuffers Buffer, ObjectId Hash)>> compilingShaders = new(); + /// /// Optional logger for compilation errors. If not set, errors are thrown as exceptions. /// @@ -44,25 +50,46 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ isFromCache = false; } - if (!ExternalFileExists(name)) + // Coordinate parallel compilations: only one thread compiles a given (name, macros) pair. + var macrosHash = ComputeMacrosHash(defines); + var macrosArray = defines.ToArray(); + var key = (name, macrosHash); + + var lazy = compilingShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(() => { - throw new InvalidOperationException($"Shader {name} could not be found"); - } + // Double-check cache (another thread may have finished between our check and this factory) + if (Cache.TryLoadFromCache(name, null, macrosArray, out var buf, out var h)) + return (buf, h); + + if (!ExternalFileExists(name)) + throw new InvalidOperationException($"Shader {name} could not be found"); + + if (!LoadExternalFileContent(name, out var filename, out var code, out h)) + throw new InvalidOperationException($"Shader {name} could not be loaded"); - if (!LoadExternalFileContent(name, out var filename, out var code, out hash)) + if (!LoadFromCode(filename, code, h, macrosArray, out buf)) + throw new InvalidOperationException($"Shader {name} could not be compiled"); + + return (buf, h); + }, LazyThreadSafetyMode.ExecutionAndPublication)); + + try { - throw new InvalidOperationException($"Shader {name} could not be loaded"); + var result = lazy.Value; + buffer = result.Buffer; + hash = result.Hash; + isFromCache = false; + return true; } - - if (!LoadFromCode(filename, code, hash, defines, out buffer)) + catch { - // If a logger is set, errors are already logged — just return false - if (Log != null) - return false; - throw new InvalidOperationException($"Shader {name} could not be compiled"); + compilingShaders.TryRemove(key, out _); + throw; + } + finally + { + compilingShaders.TryRemove(key, out _); } - - return true; } public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers buffer, out ObjectId hash, out bool isFromCache) @@ -122,6 +149,17 @@ private bool ValidateCachedHashes(ShaderBuffers buffer) return true; } + private static int ComputeMacrosHash(ReadOnlySpan macros) + { + unchecked + { + int hash = 0; + foreach (var m in macros) + hash = hash * 397 ^ m.GetHashCode(); + return hash; + } + } + protected virtual bool LoadFromCode(string? filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer, bool registerInCache = true) { var defines = new (string Name, string Definition)[macros.Length]; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 2d40f07092..c6bdbe3d73 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -10,6 +10,7 @@ using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -817,6 +818,22 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, return GetOrLoadShader(shaderLoader, className, new GenericResolverFromValues(genericValues), macros); } + /// + /// Ensures only one thread instantiates a given generic shader at a time. + /// + private static readonly ConcurrentDictionary<(string Name, string? Generics, int MacrosHash), Lazy<(ShaderBuffers Buffer, ObjectId Hash)>> compilingGenericShaders = new(); + + private static int ComputeMacrosHash(ReadOnlySpan macros) + { + unchecked + { + int hash = 0; + foreach (var m in macros) + hash = hash * 397 ^ m.GetHashCode(); + return hash; + } + } + private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var hash, out var isFromCache); @@ -834,21 +851,51 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, } else { - InstantiateMemberNames(ref shaderBuffers, className, genericResolver, shaderLoader, macros); + // Coordinate parallel instantiations: only one thread instantiates a given generic shader. + var macrosHash = ComputeMacrosHash(macros); + var macrosArray = macros.ToArray(); + var key = (className, genericArguments, macrosHash); - // Copy buffers (we don't want to edit original non-instantiated code as it might be reloaded through caching - shaderBuffers.Context = new SpirvContext(CopyBuffer(shaderBuffers.Context.GetBuffer())) + var lazy = compilingGenericShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(() => { - Bound = shaderBuffers.Context.Bound, - Names = new(shaderBuffers.Context.Names), - Types = new(shaderBuffers.Context.Types), - ReverseTypes = new(shaderBuffers.Context.ReverseTypes), - }; - shaderBuffers.Buffer = CopyBuffer(shaderBuffers.Buffer); + // Double-check cache + if (cache.TryLoadFromCache(className, genericArguments, macrosArray, out var buf, out var h)) + return (buf, h); - InstantiateGenericShader(ref shaderBuffers, classNameWithGenerics, genericResolver, shaderLoader, macros); + var localBuffers = shaderBuffers; + InstantiateMemberNames(ref localBuffers, className, genericResolver, shaderLoader, macrosArray); - cache.RegisterShader(className, genericArguments, macros, shaderBuffers, hash); + // Copy buffers (we don't want to edit original non-instantiated code as it might be reloaded through caching) + localBuffers.Context = new SpirvContext(CopyBuffer(localBuffers.Context.GetBuffer())) + { + Bound = localBuffers.Context.Bound, + Names = new(localBuffers.Context.Names), + Types = new(localBuffers.Context.Types), + ReverseTypes = new(localBuffers.Context.ReverseTypes), + }; + localBuffers.Buffer = CopyBuffer(localBuffers.Buffer); + + InstantiateGenericShader(ref localBuffers, classNameWithGenerics, genericResolver, shaderLoader, macrosArray); + + cache.RegisterShader(className, genericArguments, macrosArray, localBuffers, hash); + return (localBuffers, hash); + }, LazyThreadSafetyMode.ExecutionAndPublication)); + + try + { + var result = lazy.Value; + shaderBuffers = result.Buffer; + hash = result.Hash; + } + catch + { + compilingGenericShaders.TryRemove(key, out _); + throw; + } + finally + { + compilingGenericShaders.TryRemove(key, out _); + } } // Run in all cases (even if cached) From fbc6b9f38fcb6dfeb903153b8c0ba766becc2eef Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 23 Mar 2026 18:26:28 +0900 Subject: [PATCH 0984/1182] SDSL: Reorganize EffectReflection into ResourceGroup-based structure --- .../Stride.Graphics/DescriptorSetEntry.cs | 4 + .../EffectDescriptorSetReflection.cs | 57 +- .../engine/Stride.Graphics/Effects/Effect.cs | 67 +- .../Rendering/EffectInstance.cs | 2 +- .../Rendering/EffectParameterUpdaterLayout.cs | 4 +- .../engine/Stride.Graphics/ResourceBinder.cs | 54 +- ...riteBatch.bytecode.Direct3D11.Level_9_1.cs | 1046 ++++++++-------- ...riteBatch.bytecode.Direct3D12.Level_9_1.cs | 228 ++-- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 714 +++++------ ...Batch.bytecodeSRgb.Direct3D11.Level_9_1.cs | 1072 ++++++++--------- ...Batch.bytecodeSRgb.Direct3D12.Level_9_1.cs | 231 ++-- ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 713 +++++------ ...iteEffect.bytecode.Direct3D11.Level_9_1.cs | 745 ++++++------ ...iteEffect.bytecode.Direct3D12.Level_9_1.cs | 186 ++- .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 380 +++--- .../UIEffect.bytecode.Direct3D11.Level_9_1.cs | 769 ++++++------ .../UIEffect.bytecode.Direct3D12.Level_9_1.cs | 174 ++- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 521 ++++---- ...ffect.bytecodeSRgb.Direct3D11.Level_9_1.cs | 810 ++++++------- ...ffect.bytecodeSRgb.Direct3D12.Level_9_1.cs | 177 ++- .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 520 ++++---- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 857 ++++++------- ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 173 ++- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 560 +++++---- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 979 ++++++++------- ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 202 ++-- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 599 ++++----- .../Vulkan/PipelineState.Vulkan.cs | 14 +- .../Rendering/RootEffectRenderFeature.cs | 16 +- .../Direct3D/ShaderCompiler.cs | 24 + .../Direct3D/Spv2DXIL.cs | 9 +- .../EffectCompiler.cs | 108 +- .../SDSL/ShaderMixer.CBuffers.cs | 48 +- .../SDSL/ShaderMixer.Reflection.cs | 58 +- .../SDSL/ShaderMixer.cs | 11 + .../Spirv/Building/Context.Constants.cs | 1 - .../Interfaces/Cleanup/DeadCodeRemover.cs | 17 + .../FrameRenderer.D3D11.cs | 6 +- .../Stride.Shaders.Tests/ShaderLoader.cs | 2 +- .../shaders/Stride.Shaders/EffectBytecode.cs | 2 +- .../Stride.Shaders/EffectReflection.cs | 43 + .../Stride.Shaders/EffectResourceEntry.cs | 68 ++ .../EffectResourceGroupDescription.cs | 38 + sources/shaders/Stride.Shaders/ShaderStage.cs | 41 + 44 files changed, 6252 insertions(+), 6098 deletions(-) create mode 100644 sources/shaders/Stride.Shaders/EffectResourceEntry.cs create mode 100644 sources/shaders/Stride.Shaders/EffectResourceGroupDescription.cs diff --git a/sources/engine/Stride.Graphics/DescriptorSetEntry.cs b/sources/engine/Stride.Graphics/DescriptorSetEntry.cs index 32194140de..5b2f4e2d0b 100644 --- a/sources/engine/Stride.Graphics/DescriptorSetEntry.cs +++ b/sources/engine/Stride.Graphics/DescriptorSetEntry.cs @@ -21,4 +21,8 @@ internal struct DescriptorSetEntry(object value, int offset, int size) /// public int Size = size; + + /// + public override readonly string ToString() + => $"{Value ?? "null"} (Offset = {Offset}, Size = {Size})"; } diff --git a/sources/engine/Stride.Graphics/EffectDescriptorSetReflection.cs b/sources/engine/Stride.Graphics/EffectDescriptorSetReflection.cs index 83218e90ce..9a1597f276 100644 --- a/sources/engine/Stride.Graphics/EffectDescriptorSetReflection.cs +++ b/sources/engine/Stride.Graphics/EffectDescriptorSetReflection.cs @@ -48,37 +48,33 @@ public class EffectDescriptorSetReflection public static EffectDescriptorSetReflection New(GraphicsDevice graphicsDevice, EffectBytecode effectBytecode, List effectDescriptorSetSlots, string defaultSetSlot) { var descriptorSetLayouts = new EffectDescriptorSetReflection(defaultSetSlot); + var reflection = effectBytecode.Reflection; - // Find resource groups - // TODO: We should precompute most of that at compile time in BytecodeReflection. Jjust waiting for format to be more stable + // ResourceGroups are pre-grouped and pre-ordered at compile time foreach (var effectDescriptorSetSlot in effectDescriptorSetSlots) { - // Find all resources related to this slot name - // NOTE: Ordering is mirrored by GLSL layout in Vulkan + var group = reflection.FindResourceGroup(effectDescriptorSetSlot, defaultSetSlot); + if (group == null) + { + descriptorSetLayouts.AddLayout(effectDescriptorSetSlot, null); + continue; + } + var descriptorSetLayoutBuilder = new DescriptorSetLayoutBuilder(); bool hasBindings = false; - var resourceBindingsBySlot = effectBytecode.Reflection.ResourceBindings - // Resource bindings of a group with the same name as the slot, - // or to no group/to Globals group if default slot is used - .Where(x => x.ResourceGroup == effectDescriptorSetSlot || - (effectDescriptorSetSlot == defaultSetSlot && (x.ResourceGroup is null or "Globals"))) - .GroupBy(x => (x.KeyInfo.Key, x.Class, x.Type, ElementType: x.ElementType.Type, x.SlotCount, x.LogicalGroup)) - // NOTE: Putting Constant Buffers first for now - .OrderBy(x => x.Key.Class == EffectParameterClass.ConstantBuffer ? 0 : 1); + AddGroupEntries(graphicsDevice, group, descriptorSetLayoutBuilder, ref hasBindings); - foreach (var resourceBinding in resourceBindingsBySlot) + // When building the default set slot, also include entries from unnamed/Globals groups + // (resources without an explicit resource group). This avoids mutating + // EffectBytecode.Reflection while ensuring those resources are bound. + if (effectDescriptorSetSlot == defaultSetSlot) { - SamplerState samplerState = null; - if (resourceBinding.Key.Class == EffectParameterClass.Sampler) + foreach (var fallbackGroup in reflection.ResourceGroups) { - var matchingSamplerState = effectBytecode.Reflection.SamplerStates.FirstOrDefault(x => x.Key == resourceBinding.Key.Key); - if (matchingSamplerState is not null) - samplerState = SamplerState.New(graphicsDevice, in matchingSamplerState.Description); + if (fallbackGroup != group && fallbackGroup.Name is null or "Globals") + AddGroupEntries(graphicsDevice, fallbackGroup, descriptorSetLayoutBuilder, ref hasBindings); } - hasBindings = true; - - descriptorSetLayoutBuilder.AddBinding(resourceBinding.Key.Key, resourceBinding.Key.LogicalGroup, resourceBinding.Key.Class, resourceBinding.Key.Type, resourceBinding.Key.ElementType, resourceBinding.Key.SlotCount, samplerState); } descriptorSetLayouts.AddLayout(effectDescriptorSetSlot, hasBindings ? descriptorSetLayoutBuilder : null); @@ -87,6 +83,25 @@ public static EffectDescriptorSetReflection New(GraphicsDevice graphicsDevice, E return descriptorSetLayouts; } + private static void AddGroupEntries(GraphicsDevice graphicsDevice, EffectResourceGroupDescription group, DescriptorSetLayoutBuilder builder, ref bool hasBindings) + { + foreach (var entry in group.Entries) + { + // Note: we do NOT skip entries with Stages == None here. + // Unused resources must still occupy their slot in the descriptor set layout + // to preserve logical group offsets used by render features. + // The ResourceBinder handles this correctly — it simply won't create + // binding operations for entries with no matching stage. + + SamplerState samplerState = null; + if (entry.Class == EffectParameterClass.Sampler && entry.SamplerStateDescription.HasValue) + samplerState = SamplerState.New(graphicsDevice, entry.SamplerStateDescription.Value); + + hasBindings = true; + builder.AddBinding(entry.KeyInfo.Key, entry.LogicalGroup, entry.Class, entry.Type, entry.ElementType.Type, entry.SlotCount, samplerState); + } + } + private EffectDescriptorSetReflection(string defaultSetSlot) { DefaultSetSlot = defaultSetSlot; diff --git a/sources/engine/Stride.Graphics/Effects/Effect.cs b/sources/engine/Stride.Graphics/Effects/Effect.cs index 1fb5d4431a..d6e7cebdf1 100644 --- a/sources/engine/Stride.Graphics/Effects/Effect.cs +++ b/sources/engine/Stride.Graphics/Effects/Effect.cs @@ -70,7 +70,25 @@ public EffectBytecode Bytecode public bool HasParameter(ParameterKey parameterKey) { - // Check resources + // Check resources and cbuffer members via ResourceGroups + foreach (var group in reflection.ResourceGroups) + { + foreach (var entry in group.Entries) + { + if (entry.KeyInfo.Key == parameterKey) + return true; + } + if (group.ConstantBuffer != null) + { + foreach (var member in group.ConstantBuffer.Members) + { + if (member.KeyInfo.Key == parameterKey) + return true; + } + } + } + + // Fallback: Check old lists for (int i = 0; i < reflection.ResourceBindings.Count; i++) { var key = reflection.ResourceBindings[i].KeyInfo.Key; @@ -113,6 +131,24 @@ private static void PrepareReflection(EffectReflection reflection) // we use ref to avoid reassigning to the list (which cause a Collection modified during enumeration exception) UpdateResourceBindingKey(ref resourceBindingsSpan[i]); } + + // Resolve runtime ParameterKey references on ResourceGroups entries and cbuffer members. + // These are [DataMemberIgnore] so they don't affect EffectBytecode serialization/hashing. + foreach (var group in reflection.ResourceGroups) + { + var entriesSpan = CollectionsMarshal.AsSpan(group.Entries); + for (int i = 0; i < entriesSpan.Length; i++) + UpdateResourceEntryKey(ref entriesSpan[i]); + + // Resolve keys on cbuffer members + if (group.ConstantBuffer != null) + { + var members = group.ConstantBuffer.Members; + for (int i = 0; i < members.Length; i++) + UpdateValueBindingKey(ref members[i]); + } + } + foreach (var constantBuffer in reflection.ConstantBuffers) { var constantBufferMembers = constantBuffer.Members; @@ -169,18 +205,28 @@ private void LoadDefaultParameters() private static void UpdateResourceBindingKey(ref EffectResourceBindingDescription binding) { - var keyName = binding.KeyInfo.KeyName; + ResolveResourceKey(ref binding.KeyInfo, binding.Class, binding.Type); + } + + private static void UpdateResourceEntryKey(ref EffectResourceEntry entry) + { + ResolveResourceKey(ref entry.KeyInfo, entry.Class, entry.Type); + } + + private static void ResolveResourceKey(ref EffectParameterKeyInfo keyInfo, EffectParameterClass @class, EffectParameterType type) + { + var keyName = keyInfo.KeyName; - switch (binding.Class) + switch (@class) { case EffectParameterClass.Sampler: - binding.KeyInfo.Key = FindOrCreateResourceKey(keyName); + keyInfo.Key = FindOrCreateResourceKey(keyName); break; case EffectParameterClass.ConstantBuffer: case EffectParameterClass.TextureBuffer: case EffectParameterClass.ShaderResourceView: case EffectParameterClass.UnorderedAccessView: - switch (binding.Type) + switch (type) { case EffectParameterType.Buffer: case EffectParameterType.ConstantBuffer: @@ -192,7 +238,7 @@ private static void UpdateResourceBindingKey(ref EffectResourceBindingDescriptio case EffectParameterType.RWBuffer: case EffectParameterType.RWStructuredBuffer: case EffectParameterType.RWByteAddressBuffer: - binding.KeyInfo.Key = FindOrCreateResourceKey(keyName); + keyInfo.Key = FindOrCreateResourceKey(keyName); break; case EffectParameterType.Texture: case EffectParameterType.Texture1D: @@ -209,15 +255,15 @@ private static void UpdateResourceBindingKey(ref EffectResourceBindingDescriptio case EffectParameterType.TextureCubeArray: case EffectParameterType.RWTexture3D: case EffectParameterType.Texture3D: - binding.KeyInfo.Key = FindOrCreateResourceKey(keyName); + keyInfo.Key = FindOrCreateResourceKey(keyName); break; } break; } - if (binding.KeyInfo.Key == null) + if (keyInfo.Key == null) { - throw new InvalidOperationException(string.Format("Unable to find/generate key [{0}] with unsupported type [{1}/{2}]", binding.KeyInfo.KeyName, binding.Class, binding.Type)); + throw new InvalidOperationException(string.Format("Unable to find/generate key [{0}] with unsupported type [{1}/{2}]", keyInfo.KeyName, @class, type)); } } @@ -324,8 +370,6 @@ private static void UpdateConstantBufferHashes(EffectReflection reflection) // Update Constant buffers description foreach (var constantBuffer in reflection.ConstantBuffers) { - // We will generate a unique hash that depends on cbuffer layout (to easily detect if they differ when binding a new effect) - // TODO: currently done at runtime, but it should better be done at compile time var hashBuilder = new ObjectIdBuilder(); hashBuilder.Write(constantBuffer.Name); hashBuilder.Write(constantBuffer.Size); @@ -336,7 +380,6 @@ private static void UpdateConstantBufferHashes(EffectReflection reflection) HashConstantBufferMember(ref hashBuilder, ref member); } - // Update the hash constantBuffer.Hash = hashBuilder.ComputeHash(); } } diff --git a/sources/engine/Stride.Graphics/Rendering/EffectInstance.cs b/sources/engine/Stride.Graphics/Rendering/EffectInstance.cs index 64d624af2d..e5f5dffd6e 100644 --- a/sources/engine/Stride.Graphics/Rendering/EffectInstance.cs +++ b/sources/engine/Stride.Graphics/Rendering/EffectInstance.cs @@ -100,7 +100,7 @@ public bool UpdateEffect(GraphicsDevice graphicsDevice) // Update reflection and rearrange Buffers / resources var effectBytecode = Effect?.Bytecode; - var layoutNames = effectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); + var layoutNames = effectBytecode.Reflection.ResourceGroups.Select(g => g.Name).ToList(); DescriptorReflection = EffectDescriptorSetReflection.New(graphicsDevice, effectBytecode, layoutNames, defaultSetSlot: "Globals"); RootSignature?.Dispose(); diff --git a/sources/engine/Stride.Graphics/Rendering/EffectParameterUpdaterLayout.cs b/sources/engine/Stride.Graphics/Rendering/EffectParameterUpdaterLayout.cs index 65bdfdbaaa..b4fbd89f0e 100644 --- a/sources/engine/Stride.Graphics/Rendering/EffectParameterUpdaterLayout.cs +++ b/sources/engine/Stride.Graphics/Rendering/EffectParameterUpdaterLayout.cs @@ -76,7 +76,9 @@ public EffectParameterUpdaterLayout(GraphicsDevice graphicsDevice, // For now we assume first Constant Buffer will be the main one if (cbuffer is null) { - cbuffer = effectBytecode.Reflection.ConstantBuffers.First(x => x.Name == layoutEntry.Key.Name); + var resourceGroup = effectBytecode.Reflection.ResourceGroups.FirstOrDefault(g => g.Name == layoutEntry.Key.Name); + cbuffer = resourceGroup?.ConstantBuffer + ?? effectBytecode.Reflection.ConstantBuffers.First(x => x.Name == layoutEntry.Key.Name); ParameterCollectionLayout.ProcessConstantBuffer(cbuffer); } } diff --git a/sources/engine/Stride.Graphics/ResourceBinder.cs b/sources/engine/Stride.Graphics/ResourceBinder.cs index fcb7044e88..6e884fe125 100644 --- a/sources/engine/Stride.Graphics/ResourceBinder.cs +++ b/sources/engine/Stride.Graphics/ResourceBinder.cs @@ -41,36 +41,37 @@ internal struct ResourceBinder public void Compile(EffectDescriptorSetReflection descriptorSetLayouts, EffectBytecode effectBytecode) { descriptorSetBindings = new BindingOperation[descriptorSetLayouts.Layouts.Count][]; + var reflection = effectBytecode.Reflection; for (int setIndex = 0; setIndex < descriptorSetLayouts.Layouts.Count; setIndex++) { - var layout = descriptorSetLayouts.Layouts[setIndex].Layout; + var descriptorSetLayout = descriptorSetLayouts.Layouts[setIndex]; + var layout = descriptorSetLayout.Layout; if (layout is null) continue; + var group = reflection.FindResourceGroup(descriptorSetLayout.Name, descriptorSetLayouts.DefaultSetSlot); + if (group == null) + continue; + var bindingOperations = new List(); + var isDefaultSetSlot = descriptorSetLayout.Name == descriptorSetLayouts.DefaultSetSlot; for (int resourceIndex = 0; resourceIndex < layout.Entries.Count; resourceIndex++) { var layoutEntry = layout.Entries[resourceIndex]; - // Find it in shader reflection - foreach (var resourceBinding in effectBytecode.Reflection.ResourceBindings) + // Find matching entry in the resource group + if (!TryMatchEntry(group, layoutEntry, resourceIndex, bindingOperations) && isDefaultSetSlot) { - if (resourceBinding.Stage == ShaderStage.None) - continue; - - if (resourceBinding.KeyInfo.Key == layoutEntry.Key) + // Fallback: search unnamed/Globals groups (resources without explicit resource group) + foreach (var fallbackGroup in reflection.ResourceGroups) { - // Create a binding operation for this resource (Descriptor) - bindingOperations.Add(new BindingOperation + if (fallbackGroup != group && fallbackGroup.Name is null or "Globals") { - EntryIndex = resourceIndex, - Class = resourceBinding.Class, - Stage = resourceBinding.Stage, - SlotStart = resourceBinding.SlotStart, - ImmutableSampler = layoutEntry.ImmutableSampler - }); + if (TryMatchEntry(fallbackGroup, layoutEntry, resourceIndex, bindingOperations)) + break; + } } } } @@ -80,6 +81,29 @@ public void Compile(EffectDescriptorSetReflection descriptorSetLayouts, EffectBy } } + private static bool TryMatchEntry(EffectResourceGroupDescription group, DescriptorSetLayoutBuilder.Entry layoutEntry, int resourceIndex, List bindingOperations) + { + foreach (var resEntry in group.Entries) + { + if (resEntry.KeyInfo.Key == layoutEntry.Key && resEntry.Stages != ShaderStageFlags.None) + { + resEntry.Stages.ForEach(stage => + { + bindingOperations.Add(new BindingOperation + { + EntryIndex = resourceIndex, + Class = resEntry.Class, + Stage = stage, + SlotStart = resEntry.SlotStart, + ImmutableSampler = layoutEntry.ImmutableSampler + }); + }); + return true; + } + } + return false; + } + /// /// Binds the resources from the specified Descriptor Sets to the graphics pipeline. /// diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs index 622e06a3b4..99a954247b 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs @@ -16,65 +16,77 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, -114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, -0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, -1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, -88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, -140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, -105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 34, 78, 1, 177, 202, 75, 102, 209, 209, 54, 26, 46, 94, 167, 243, 149, 0, 212, 97, 0, 0, 68, 88, 66, 67, 231, 186, 219, 190, 149, 2, -188, 135, 14, 184, 254, 149, 79, 237, 192, 131, 1, 0, 0, 0, 212, 97, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 95, 0, 0, 112, 96, 0, 0, 36, 97, 0, 0, 160, 97, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, -255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, -0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, -99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, -255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 91, 0, 0, 0, 220, 4, 0, 0, 106, 0, 0, 0, 236, 4, 0, 0, 106, 0, 0, 0, 252, 4, 0, 0, 97, 0, -0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 36, 5, 0, 0, 104, 0, 0, 0, 52, 5, 0, 0, 109, 0, 0, 0, 72, 5, 0, 0, 111, 0, 0, 0, 92, 5, 0, 0, 108, 0, 0, 0, 108, 5, 0, 0, 111, 0, 0, 0, 128, 5, 0, 0, 111, 0, -0, 0, 148, 5, 0, 0, 111, 0, 0, 0, 160, 5, 0, 0, 111, 0, 0, 0, 172, 5, 0, 0, 112, 0, 0, 0, 188, 5, 0, 0, 113, 0, 0, 0, 208, 5, 0, 0, 113, 0, 0, 0, 220, 5, 0, 0, 113, 0, 0, 0, 240, 5, 0, 0, 114, 0, 0, 0, 4, 6, 0, 0, 114, 0, -0, 0, 20, 6, 0, 0, 114, 0, 0, 0, 32, 6, 0, 0, 118, 0, 0, 0, 48, 6, 0, 0, 118, 0, 0, 0, 60, 6, 0, 0, 118, 0, 0, 0, 72, 6, 0, 0, 118, 0, 0, 0, 84, 6, 0, 0, 118, 0, 0, 0, 104, 6, 0, 0, 119, 0, 0, 0, 124, 6, 0, 0, 119, 0, -0, 0, 136, 6, 0, 0, 119, 0, 0, 0, 148, 6, 0, 0, 119, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, -255, 255, 255, 255, 255, 255, 95, 52, 53, 52, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, -3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, -0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, -97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, -114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, -4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, -3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, -0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, -0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, -40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, -0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, -0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, -2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, -0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, -85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, -0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, -255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, -255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, -228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, -0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, -0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, -0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, -16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, -0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, -0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, -16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, -0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, -128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, -16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, -48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, +97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, +114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, +0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, +114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, +193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, +54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 157, 124, 117, 145, 120, 218, 0, 73, 20, 130, 190, 217, 127, 164, 168, 138, 0, 212, 89, 0, 0, 68, 88, 66, 67, 134, 248, 72, 118, 248, 51, 205, 98, 109, 185, 203, 178, 177, 242, 240, 4, 1, 0, 0, 0, 212, 89, +0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, +40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, +0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, +255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, +0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, +0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, 0, 0, 104, 0, +0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, 0, 0, 105, 0, +0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 52, 0, 171, 171, 171, 1, 0, +3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, +0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, +255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, +255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, +0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, +0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, +0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, +67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, +0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, +0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, +228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, +0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, +0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, +170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, +85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, +8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, +15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, +0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, +16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, +0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, +0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, +0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, +16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, +16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, +128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, +16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, +16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, +16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, +0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -82,7 +94,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -90,167 +102,151 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 12, 211, 32, 152, 191, 21, 148, 68, 180, 22, -79, 226, 163, 237, 224, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 251, 64, 95, 64, 131, 117, 74, 76, 174, 16, 216, 201, 202, 180, 228, 219, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, -3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 33, 155, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 37, 52, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, -117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, -116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, -125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, -32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, -54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, -32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, -32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, -108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, -46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, -32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, -32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, -49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, -114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, -115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, -101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, -111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, -32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, -41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, -46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, -32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, -95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 214, 14, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, -97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 57, 53, 98, 52, 55, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 66, 76, 11, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, -0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 125, 141, 252, 0, 33, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, -10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, -0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, -0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, -88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, -0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 62, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 61, 1, -104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, -3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, -6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, -13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 53, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, -152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, -0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, -4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, -110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, -0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, -114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, -20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, -78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 121, 191, 162, 18, 168, 171, 123, 217, 104, 0, 57, 20, 109, 234, 68, 168, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, -0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 144, 0, 0, 128, 104, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 128, 144, 0, 0, 0, 144, 0, 0, 0, 188, 0, 0, 0, 144, 0, 0, 128, 188, 0, 0, 0, 144, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 128, 200, 0, -0, 0, 144, 0, 0, 0, 236, 0, 0, 0, 144, 0, 0, 128, 236, 0, 0, 0, 144, 0, 0, 0, 0, 1, 0, 0, 144, 0, 0, 128, 0, 1, 0, 0, 144, 0, 0, 0, 4, 1, 0, 0, 144, 0, 0, 128, 4, 1, 0, 0, 144, 0, 0, 0, 40, 1, 0, 0, 144, 0, 0, 128, 40, 1, -0, 0, 144, 0, 0, 0, 44, 1, 0, 0, 144, 0, 0, 128, 44, 1, 0, 0, 144, 0, 0, 0, 104, 1, 0, 0, 144, 0, 0, 128, 104, 1, 0, 0, 144, 0, 0, 0, 132, 1, 0, 0, 144, 0, 0, 128, 132, 1, 0, 0, 144, 0, 0, 0, 160, 1, 0, 0, 144, 0, 0, 128, 160, 1, -0, 0, 144, 0, 0, 0, 188, 1, 0, 0, 144, 0, 0, 128, 188, 1, 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 144, 0, 0, 128, 208, 1, 0, 0, 144, 0, 0, 0, 240, 1, 0, 0, 144, 0, 0, 128, 240, 1, 0, 0, 144, 0, 0, 0, 20, 2, 0, 0, 144, 0, 0, 128, 20, 2, -0, 0, 144, 0, 0, 0, 40, 2, 0, 0, 144, 0, 0, 128, 40, 2, 0, 0, 144, 0, 0, 0, 76, 2, 0, 0, 144, 0, 0, 128, 76, 2, 0, 0, 144, 0, 0, 0, 96, 2, 0, 0, 144, 0, 0, 128, 96, 2, 0, 0, 144, 0, 0, 0, 116, 2, 0, 0, 144, 0, 0, 128, 116, 2, -0, 0, 144, 0, 0, 0, 152, 2, 0, 0, 144, 0, 0, 128, 152, 2, 0, 0, 144, 0, 0, 0, 188, 2, 0, 0, 147, 0, 0, 128, 188, 2, 0, 0, 147, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, +1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 224, 110, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 230, 247, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, +88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, +97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, +49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, +32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, +46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, +32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, +10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, +115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, +32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, +46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, +32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, +101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, +122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, +105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, +110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 109, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, +0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, +115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 49, 102, 100, 102, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 111, 222, 218, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 82, 155, 10, 88, 184, 11, +0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, +116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, +112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, +0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, +84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 62, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 61, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, +0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, +13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, +3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, +9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, +5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, +40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, +6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, +0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, +0, 0, 16, 1, 26, 200, 105, 104, 217, 102, 98, 165, 136, 234, 14, 33, 45, 167, 214, 5, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, 0, 128, 104, 0, +0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, 0, 128, 236, 0, +0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, 0, 128, 44, 1, +0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, 0, 128, 188, 1, +0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, 0, 128, 40, 2, +0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, 0, 128, 152, 2, +0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 2, 16, 0, 0, 0, 0, -0, 0, 95, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, +0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -258,15 +254,15 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, -0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, -83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, -5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, -111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, -242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, -0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, -1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, +0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, +242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, +0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, +8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, +0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 64, 78, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, +23, 21, 0, 0, 0, 0, 10, 2, 64, 78, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -274,134 +270,119 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, -117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, -116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, -125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, -32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, -54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, -32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, -32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, -108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, -46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, -32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, -32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, -49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, -114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, -115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, -101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, -111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, -32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, -41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, -46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, -32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, -95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, +88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, +97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, +49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, +32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, +46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, +32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, +10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, +115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, +32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, +46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, +32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, +101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, +122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, +105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, +110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, -0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, -97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, +0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, -0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, -97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, +0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, -81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, -105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, +255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, -1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, -0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, -255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, -114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 57, 53, 66, 52, 55, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 12, 211, 32, 152, 191, 21, 148, 68, 180, 22, -79, 226, 163, 237, 224, 240, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 102, 54, 57, 53, 98, 52, 55, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, -0, 0, 0, 0, 0, 0, 6, 15, 0, 0, 128, 0, 0, 0, 33, 14, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 38, 0, -0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, -0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, +0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, +100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 251, 64, 95, 64, 131, 117, 74, 76, 174, 16, 216, 201, 202, 180, 228, 219, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, +110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 49, 102, 100, 102, 56, 0, +4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 157, 12, 0, 0, 128, 0, 0, 0, 184, 11, +0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 24, 0, +0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, +0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -409,51 +390,50 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, +114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, +1, 126, 48, 116, 243, 51, 240, 117, 229, 225, 171, 194, 108, 72, 39, 156, 65, 0, 76, 87, 0, 0, 68, 88, 66, 67, 189, 198, 129, 17, 136, 147, 20, 199, 106, 227, 136, 204, 59, 219, 183, 4, 1, 0, 0, 0, 76, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, 0, 0, 168, 6, +0, 0, 176, 84, 0, 0, 44, 85, 0, 0, 252, 85, 0, 0, 172, 86, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, +0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, 0, 0, 0, 1, +0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, 49, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, +0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 90, 0, 0, 0, 44, 4, 0, 0, 90, 0, 0, 0, 60, 4, 0, 0, 90, 0, 0, 0, 76, 4, 0, 0, 90, 0, 0, 0, 92, 4, 0, 0, 124, 0, 0, 0, 108, 4, 0, 0, 124, 0, 0, 0, 128, 4, 0, 0, 126, 0, 0, 0, 140, 4, +0, 0, 126, 0, 0, 0, 152, 4, 0, 0, 128, 0, 0, 0, 164, 4, 0, 0, 129, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, +0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, +0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 5, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 56, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 120, 1, +0, 0, 56, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 132, 1, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 11, 0, 0, 0, 0, 0, +1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 13, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 14, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 28, 2, +0, 0, 24, 1, 0, 0, 43, 2, 0, 0, 56, 1, 0, 0, 58, 2, 0, 0, 56, 1, 0, 0, 70, 2, 0, 0, 56, 1, 0, 0, 85, 2, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 4, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 226, 2, 0, 0, 56, 1, 0, 0, 242, 2, +0, 0, 24, 1, 0, 0, 251, 2, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 56, 1, 0, 0, 10, 3, 0, 0, 56, 1, 0, 0, 19, 3, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 28, 3, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, +255, 255, 7, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 172, 1, 0, 0, 7, 0, 0, 0, 188, 1, 0, 0, 0, 1, 0, 0, 16, 2, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 156, 2, +0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 76, 3, 0, 0, 3, 0, 0, 0, 92, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, +0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, +4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, +3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, +0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, +16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, +0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, +0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, +16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, +16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, +68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, -0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, -255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, -76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, -0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, -95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 121, 92, 177, 92, 119, 169, 150, 232, 100, 221, 122, 148, 57, 180, 151, 104, 0, 76, 95, 0, 0, 68, 88, 66, 67, 128, 39, 109, 146, 27, 67, 146, 146, 146, 240, 79, 33, 157, 227, 169, 170, 1, 0, 0, 0, 76, 95, -0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, 0, 0, 168, 6, 0, 0, 176, 92, 0, 0, 44, 93, 0, 0, 252, 93, 0, 0, 172, 94, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, -48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, -0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, 0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, -104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, -0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, 0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 104, 0, 0, 0, 44, 4, 0, 0, 104, 0, 0, 0, 60, 4, 0, 0, 104, 0, 0, 0, 76, 4, 0, 0, 104, 0, 0, 0, 92, 4, 0, 0, 138, 0, 0, 0, 108, 4, -0, 0, 138, 0, 0, 0, 128, 4, 0, 0, 140, 0, 0, 0, 140, 4, 0, 0, 140, 0, 0, 0, 152, 4, 0, 0, 142, 0, 0, 0, 164, 4, 0, 0, 143, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, -171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, -100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 5, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, -0, 0, 56, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 120, 1, 0, 0, 56, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 132, 1, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 10, 0, -0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 11, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 13, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 14, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, -110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 28, 2, 0, 0, 24, 1, 0, 0, 43, 2, 0, 0, 56, 1, 0, 0, 58, 2, 0, 0, 56, 1, 0, 0, 70, 2, 0, 0, 56, 1, 0, 0, 85, 2, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, -5, 0, 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 4, 0, 0, 0, 14, 0, 255, 255, 255, 255, -255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, -122, 122, 108, 101, 0, 171, 226, 2, 0, 0, 56, 1, 0, 0, 242, 2, 0, 0, 24, 1, 0, 0, 251, 2, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 56, 1, 0, 0, 10, 3, 0, 0, 56, 1, 0, 0, 19, 3, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, -6, 0, 28, 3, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 172, 1, 0, 0, 7, 0, 0, 0, 188, 1, 0, 0, 0, 1, -0, 0, 16, 2, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 76, 3, 0, 0, 3, 0, 0, 0, 92, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, -67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, -0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, -4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, -0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, -0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, -16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, -16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, -0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, -32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, -32, 0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, -0, 0, 200, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -461,7 +441,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -469,311 +449,279 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 133, 228, 159, 76, 56, 213, 48, 75, 139, 10, 183, 67, 222, 135, 216, 253, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, +51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 78, 77, 192, 50, 130, 227, 146, 69, 191, 245, 179, 238, 225, 101, 249, 176, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, +101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 103, 159, 1, 0, 193, 33, 3, 0, 65, 185, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, -102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, -112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, -0, 0, 103, 159, 1, 0, 193, 33, 3, 0, 65, 185, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, +101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, +110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, +100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, +76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, +32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, +82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, +53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, +32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, +108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, +40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, +83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, +111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, -116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, -102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, -112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, -49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, -111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, -40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, -107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, -116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, -105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, -67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, -83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, -82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, -51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, -50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, -32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, -111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, -101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, -112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, -101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, -65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, -83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 131, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 0, 99, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 97, 55, 54, 53, 100, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, -116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 17, 53, 13, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 143, 177, 143, 206, 14, 0, 0, 1, 0, -0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, -41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, -95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 124, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, -0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, -212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, -4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, -212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, -4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, -117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 148, 0, -0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, -0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 120, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 37, 6, 12, 12, 128, 128, 80, 8, 0, 13, 36, 1, 128, 228, 12, 128, 128, 0, 0, 38, 0, 77, 17, 244, 3, 0, 0, 116, 4, 0, 0, 1, 16, -0, 0, 7, 0, 9, 5, 13, 24, 6, 2, 12, 128, 128, 80, 8, 0, 13, 23, 1, 128, 228, 12, 128, 128, 0, 0, 42, 0, 77, 17, 28, 4, 0, 0, 112, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 80, 8, 0, 9, 33, 13, 82, 1, 128, 228, 12, -128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 161, 123, 228, 163, 123, 235, 180, 4, 152, 115, 14, 39, 91, 198, 127, 247, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, -0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, 128, 148, 0, 0, 0, 152, 0, 0, 0, 168, 0, 0, 0, 152, 0, 0, 128, 168, 0, 0, 0, 152, 0, 0, 0, 188, 0, 0, 0, 152, 0, 0, 128, 188, 0, -0, 0, 152, 0, 0, 0, 208, 0, 0, 0, 152, 0, 0, 128, 208, 0, 0, 0, 152, 0, 0, 0, 228, 0, 0, 0, 145, 0, 0, 128, 228, 0, 0, 0, 145, 0, 0, 0, 4, 1, 0, 0, 145, 0, 0, 128, 4, 1, 0, 0, 145, 0, 0, 0, 36, 1, 0, 0, 145, 0, 0, 128, 36, 1, -0, 0, 145, 0, 0, 0, 68, 1, 0, 0, 145, 0, 0, 128, 68, 1, 0, 0, 145, 0, 0, 0, 100, 1, 0, 0, 152, 0, 0, 128, 100, 1, 0, 0, 152, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, -24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, -0, 0, 124, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, -97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 11, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 16, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, -0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, -3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, -0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, -105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, -3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, -86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, -242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, -0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 18, 216, 0, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 26, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, +83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, 49, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, +101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 49, 56, +102, 54, 50, 49, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 213, 11, 221, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 228, 52, 138, 92, 101, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, -49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, -111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, -40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, -107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, -116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, -105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, -67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, -83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, -82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, -51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, -50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, -32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, -111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, -101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, -109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, -112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, -101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, -65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, -83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, -0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, -100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, +109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, +108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 124, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, +0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, +0, 0, 120, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 37, 6, 12, 12, 128, 128, 80, 8, 0, 13, 36, 1, 128, 228, 12, 128, 128, 0, 0, 38, 0, 77, 17, 244, 3, 0, 0, 116, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 2, 12, 128, 128, 80, 8, 0, +13, 23, 1, 128, 228, 12, 128, 128, 0, 0, 42, 0, 77, 17, 28, 4, 0, 0, 112, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 80, 8, 0, 9, 33, 13, 82, 1, 128, 228, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, +78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 56, 159, 94, 2, 31, 111, 248, 71, 170, 144, 244, 59, 253, 212, 114, 240, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, 0, 0, 18, 0, +0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 138, 0, 0, 128, 148, 0, 0, 0, 138, 0, 0, 0, 168, 0, 0, 0, 138, 0, 0, 128, 168, 0, 0, 0, 138, 0, 0, 0, 188, 0, 0, 0, 138, 0, 0, 128, 188, 0, 0, 0, 138, 0, 0, 0, 208, 0, 0, 0, 138, 0, 0, 128, 208, 0, +0, 0, 138, 0, 0, 0, 228, 0, 0, 0, 131, 0, 0, 128, 228, 0, 0, 0, 131, 0, 0, 0, 4, 1, 0, 0, 131, 0, 0, 128, 4, 1, 0, 0, 131, 0, 0, 0, 36, 1, 0, 0, 131, 0, 0, 128, 36, 1, 0, 0, 131, 0, 0, 0, 68, 1, 0, 0, 131, 0, 0, 128, 68, 1, +0, 0, 131, 0, 0, 0, 100, 1, 0, 0, 138, 0, 0, 128, 100, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 100, 0, +0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 11, 16, 0, 0, 1, 0, +1, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, -0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, -100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 16, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, +27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, +242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, +3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, +0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 18, 216, 0, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, +110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, +100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, +76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, +32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, +95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, +82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, +53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, +32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, +108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, +40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, +83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, +111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, +0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, +1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, +0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, +1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, +0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 13, 16, 0, 0, 8, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, -114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, -0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, -48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 54, 65, 55, 54, 53, 68, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 78, 77, 192, 50, 130, 227, 146, 69, 191, 245, 179, 238, 225, 101, 249, 176, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, -47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 54, 97, 55, 54, 53, 100, 56, 0, 4, 0, 0, 0, -6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 13, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, +97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 72, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 179, 15, 0, 0, 128, 0, 0, 0, 206, 14, 0, 0, 212, 5, -0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 37, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 36, 0, 0, 0, 30, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, -0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, -0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 35, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, +101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, +49, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 133, 228, 159, 76, 56, 213, 48, 75, 139, 10, 183, 67, 222, 135, 216, 253, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, +101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, +115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 49, 56, 102, 54, 50, 49, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, +17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 72, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 74, 13, 0, 0, 128, 0, 0, 0, 101, 12, 0, 0, 212, 5, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 44, 2, +0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 16, 0, +0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 22, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 33, 0, +0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -789,17 +737,17 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, -0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, -111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, -82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, -0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, +114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, +100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, +0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, +171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, +0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, +0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs index 542a9c4142..8d59faecba 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs @@ -16,126 +16,116 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, -2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 205, 110, 243, 195, 215, 68, 58, 136, 133, 123, 105, 157, 89, 65, 222, 57, 0, 74, 11, 0, 0, 68, 88, 66, 67, 42, 181, 74, 147, 170, 152, 11, 218, 117, 228, 22, 161, 9, 159, 40, 250, 1, 0, 0, 0, 74, 11, 0, 0, 5, 0, 0, 0, 52, -0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 110, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, -240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 52, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, -0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 212, 8, 0, 0, 96, 0, 0, 0, 53, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 188, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 44, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, -0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, -36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, -0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 95, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, -49, 65, 128, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, -140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, -40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 128, 50, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 80, 3, 0, 0, 192, 61, 195, 229, 79, 216, 67, 72, 126, 8, 52, 195, 66, -160, 0, 2, 0, 0, 160, 24, 17, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 55, 13, 151, 63, 97, 15, 33, 249, 43, 33, 173, 196, 228, 23, 183, 141, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 128, 194, 76, 0, 0, 0, 16, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 128, 0, -0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 128, 24, 0, 0, 0, 6, 2, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, +0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, +105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 163, 199, 239, 174, 159, 178, 84, 108, 213, 29, 36, 80, 46, 217, 119, 84, 0, 230, 10, 0, 0, 68, 88, 66, 67, 132, 21, 53, 37, 64, 61, 183, 172, 137, 120, 56, 16, 111, 194, +17, 150, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, +0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, +0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, +20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, +7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, +73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, +65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, +62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, 0, 0, 24, 0, +0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, 12, 4, 0, 0, +19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, +48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, +7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 30, 32, 0, 4, +0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, +0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 0, +0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, 134, 6, 0, 0, +0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, 130, 96, 48, 162, +42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, 108, 16, 2, 101, +67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, 112, 115, 19, 4, +160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, +16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, 128, 13, 132, 24, +148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 120, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, +115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, +0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, +92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 232, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, +197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 158, 225, 242, 157, 199, 167, 26, 32, 194, 252, 226, 182, 109, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 35, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 173, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, +165, 166, 135, 154, 252, 226, 182, 1, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, +156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, 101, 192, 121, 35, +6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, 224, 130, 97, 150, +33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, 70, 19, 6, 97, +52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, 96, 52, 33, 0, +70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, 129, 29, 109, 32, +1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, 49, 75, 96, 12, +84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, 17, 117, 32, 1, +35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 97, 22, 132, 17, +131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 117, 113, 5, 93, 209, 38, 77, 200, 125, 107, 234, 233, 96, 184, 112, 97, 0, 181, 11, 0, 0, 68, 88, 66, 67, 67, 154, 77, 181, 29, 94, 23, 148, 252, 83, 211, 156, +25, 235, 105, 219, 1, 0, 0, 0, 181, 11, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, +8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, +69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, +67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, +0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, +0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 0, 8, 0, 0, 96, 0, 1, 0, 0, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 232, 7, 0, 0, 66, 67, 192, +222, 33, 12, 0, 0, 247, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, +8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, +32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, +80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, +0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, +32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, -32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, -0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 36, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 50, 0, 0, -0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, -40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 3, 2, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 8, 0, 0, 0, 138, 129, 0, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 8, 0, 0, 0, 74, 142, 0, 0, 0, 0, 102, 0, 136, 0, -0, 0, 160, 240, 8, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 136, 0, 0, 0, 160, 28, 10, 134, 0, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 2, 0, 0, 128, 82, 160, 6, 0, -0, 128, 146, 40, 132, 2, 1, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, -151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, -84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 184, 54, -12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 4, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 12, 38, 8, 77, 180, 33, 8, 38, 8, 205, 180, 97, 9, 196, 96, 12, 200, 160, 12, -204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 202, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 2, 102, 195, 194, 136, 193, 24, 144, 193, 26, 152, 1, 145, 6, 12, 25, 0, 19, 4, 162, 218, 16, 180, 193, 4, 161, 145, 54, 44, 109, 32, 6, 99, 64, -6, 110, 96, 6, 196, 27, 180, 1, 25, 0, 27, 136, 51, 80, 3, 54, 128, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 198, 12, 54, 44, 129, 28, 140, 193, 28, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 160, 131, 13, 67, 28, 212, 1, 192, 51, 152, 130, 147, 75, 163, 43, -19, 10, 163, 27, 67, 155, 66, 11, 35, 43, 147, 227, 49, 11, 99, 155, 43, 243, 113, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 119, 96, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, -115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, -163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 193, 29, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 232, 180, -25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 158, 225, 242, 157, 199, 167, 26, 32, 194, 252, 226, 182, 109, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 35, 128, 134, 203, 119, 30, 95, 2, -152, 103, 33, 252, 226, 182, 173, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 97, 32, 0, 0, 145, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 56, 102, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 103, 144, 133, 65, 24, 88, 216, -136, 65, 2, 128, 32, 24, 56, 104, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 105, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 106, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 107, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 56, 108, -224, 133, 129, 25, 112, 221, 136, 65, 2, 128, 32, 24, 56, 109, 240, 137, 193, 25, 112, 222, 136, 65, 2, 128, 32, 24, 56, 110, 0, 6, 99, 128, 6, 220, 55, 98, 144, 0, 32, 8, 6, 206, 27, 132, 1, 25, 164, 1, 7, 6, 35, 6, 9, 0, 130, 96, 224, 192, 129, 24, 112, 106, 0, 6, -97, 96, 1, 7, 129, 17, 3, 3, 0, 65, 48, 120, 226, 128, 11, 134, 27, 184, 96, 152, 101, 8, 132, 96, 196, 32, 1, 64, 16, 12, 36, 57, 224, 194, 192, 13, 220, 0, 13, 70, 12, 18, 0, 4, 193, 64, 154, 131, 174, 12, 222, 224, 13, 210, 96, 196, 224, 1, 64, 16, 12, 168, 57, 224, -2, 1, 122, 186, 238, 12, 206, 224, 12, 186, 209, 132, 0, 24, 77, 16, 130, 209, 132, 65, 24, 77, 32, 134, 89, 130, 97, 196, 32, 1, 64, 16, 12, 164, 60, 24, 3, 52, 168, 131, 58, 120, 131, 17, 131, 4, 0, 65, 48, 144, 244, 128, 12, 216, 192, 14, 236, 0, 14, 70, 12, 30, 0, 4, -193, 128, 210, 131, 49, 8, 132, 203, 34, 3, 50, 112, 3, 55, 112, 3, 50, 24, 77, 8, 128, 209, 4, 33, 24, 77, 24, 132, 209, 4, 98, 152, 37, 24, 6, 42, 0, 43, 64, 132, 129, 10, 0, 11, 16, 97, 160, 2, 208, 2, 68, 24, 168, 0, 184, 0, 17, 204, 90, 3, 8, 140, 24, 24, -0, 8, 130, 193, 99, 10, 113, 16, 12, 55, 196, 65, 48, 204, 50, 16, 69, 96, 71, 27, 72, 192, 130, 58, 128, 128, 33, 111, 32, 1, 11, 238, 0, 2, 54, 12, 18, 48, 65, 144, 128, 9, 1, 4, 70, 12, 12, 0, 4, 193, 224, 121, 133, 57, 8, 70, 12, 12, 0, 4, 193, 224, 129, 133, -57, 8, 108, 14, 130, 8, 88, 48, 7, 18, 176, 128, 14, 32, 48, 75, 96, 204, 18, 24, 3, 21, 128, 64, 136, 65, 49, 80, 1, 184, 3, 33, 6, 133, 157, 129, 29, 64, 96, 196, 192, 0, 64, 16, 12, 158, 91, 16, 133, 96, 184, 65, 20, 130, 97, 186, 1, 187, 130, 233, 134, 204, 16, 166, -27, 250, 192, 24, 108, 171, 3, 9, 24, 81, 7, 18, 48, 162, 14, 36, 96, 68, 29, 72, 192, 136, 58, 128, 128, 17, 117, 0, 1, 35, 234, 0, 2, 70, 212, 1, 4, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 168, 5, 98, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, -248, 5, 90, 24, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 152, 5, 97, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, 248, 5, 89, 8, 16, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 59, 95, 18, 105, 199, 9, 209, 190, 45, 143, 233, 76, 24, 234, 125, 51, -0, 25, 12, 0, 0, 68, 88, 66, 67, 178, 22, 21, 40, 224, 54, 248, 92, 5, 21, 208, 206, 31, 171, 253, 36, 1, 0, 0, 0, 25, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 189, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, -105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 180, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, -0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, -0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 68, 88, 73, 76, 84, 8, 0, 0, 96, 0, 1, 0, 21, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 60, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 12, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, -4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, -24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, -96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, -29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, -212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, -2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, -113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, -48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, -0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 25, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, -67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 50, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, -0, 128, 178, 43, 144, 2, 42, 176, 82, 40, 6, 82, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, -1, 81, 0, 19, 132, 35, 225, 1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, -44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 180, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, -80, 182, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 133, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 9, 2, 33, 109, 8, -204, 96, 195, 98, 6, 218, 198, 157, 1, 71, 132, 129, 25, 112, 192, 134, 192, 153, 32, 40, 206, 134, 197, 209, 54, 46, 13, 56, 66, 13, 28, 14, 216, 80, 124, 98, 80, 6, 104, 176, 6, 27, 150, 64, 219, 184, 206, 35, 188, 128, 3, 54, 44, 132, 182, 113, 96, 224, 17, 97, 64, 112, 192, 134, -101, 12, 180, 141, 35, 3, 143, 8, 131, 49, 224, 128, 13, 139, 25, 104, 27, 119, 6, 30, 161, 6, 102, 192, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 10, 180, 97, 113, 226, 96, 147, 131, 46, 12, 136, 48, 112, 56, 96, 67, 209, 6, 110, 240, 6, 112, 48, 7, 27, -6, 54, 160, 3, 128, 103, 48, 5, 39, 151, 70, 87, 38, 20, 70, 55, 134, 54, 133, 22, 70, 86, 38, 199, 99, 22, 198, 54, 87, 230, 227, 98, 53, 213, 20, 150, 230, 246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 236, 160, 14, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, -148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, -134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 236, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, -14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 235, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 164, 225, 242, 157, 199, 23, 34, 2, 152, 136, 16, 104, 134, 133, 176, 129, 109, 184, 124, 231, 241, 133, 128, -42, 10, 34, 42, 29, 96, 40, 9, 3, 16, 48, 191, 184, 109, 35, 168, 134, 203, 119, 30, 95, 154, 156, 136, 64, 169, 233, 161, 38, 191, 184, 109, 0, 0, 97, 32, 0, 0, 172, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 156, 116, 93, 80, 52, 98, 144, 0, 32, 8, 6, 75, -55, 97, 24, 36, 141, 24, 36, 0, 8, 130, 193, 226, 81, 88, 38, 77, 35, 6, 9, 0, 130, 96, 176, 124, 85, 166, 73, 212, 136, 65, 2, 128, 32, 24, 44, 96, 96, 105, 155, 84, 141, 24, 36, 0, 8, 130, 193, 18, 6, 215, 198, 73, 214, 136, 65, 2, 128, 32, 24, 44, 98, 128, 73, 157, -117, 141, 24, 36, 0, 8, 130, 193, 50, 6, 217, 228, 89, 216, 136, 65, 2, 128, 32, 24, 44, 100, 160, 81, 159, 149, 141, 24, 36, 0, 8, 130, 193, 82, 6, 91, 5, 6, 150, 54, 98, 144, 0, 32, 8, 6, 139, 25, 112, 85, 24, 104, 219, 136, 65, 2, 128, 32, 24, 44, 103, 208, 89, 98, -160, 113, 35, 6, 9, 0, 130, 96, 176, 160, 129, 119, 141, 129, 214, 141, 24, 36, 0, 8, 130, 193, 146, 6, 31, 70, 6, 154, 55, 98, 144, 0, 32, 8, 6, 139, 26, 128, 1, 24, 148, 129, 247, 141, 24, 36, 0, 8, 130, 193, 163, 6, 89, 87, 6, 101, 128, 213, 25, 136, 1, 142, 24, 28, -0, 8, 130, 65, 180, 6, 153, 16, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 84, 27, 116, 80, 65, 26, 224, 136, 193, 1, 128, 32, 24, 68, 114, 0, 6, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 116, 48, 6, 80, 1, 28, 224, 136, 193, -1, 128, 32, 24, 68, 121, 112, 6, 80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 123, 144, 6, 80, 193, 29, 224, 136, 193, 1, 128, 32, 24, 68, 160, 224, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 96, 150, 25, 72, 192, 160, 51, 144, -128, 41, 104, 32, 1, 35, 210, 64, 2, 182, 173, 129, 4, 44, 40, 32, 96, 86, 27, 72, 192, 2, 3, 2, 22, 189, 129, 4, 44, 56, 32, 96, 76, 28, 72, 192, 2, 4, 2, 70, 6, 116, 32, 1, 11, 16, 8, 216, 103, 7, 18, 176, 0, 129, 128, 105, 120, 32, 1, 11, 16, 8, 88, 165, -7, 18, 176, 0, 129, 128, 181, 65, 31, 72, 192, 2, 4, 2, 134, 6, 127, 32, 1, 11, 16, 8, 216, 24, 132, 130, 4, 44, 64, 32, 96, 222, 40, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 228, 130, 47, 220, 194, 49, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, -46, 248, 130, 45, 20, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 228, 130, 47, 212, 194, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, 46, 248, 2, 45, 4, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 248, 130, 47, 220, 194, 41, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, 224, 11, -190, 96, 11, 166, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 66, 47, 248, 194, 45, 132, 194, 136, 65, 2, 128, 32, 24, 72, 224, 176, 10, 189, 224, 11, 182, 0, 10, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 244, 130, 47, 212, 194, 31, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, 208, -11, 190, 64, 11, 126, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 194, 44, 248, 194, 45, 244, 193, 136, 65, 2, 128, 32, 24, 72, 224, 176, 10, 179, 224, 11, 182, 192, 7, 35, 6, 9, 0, 130, 96, 32, 129, 195, 42, 204, 130, 47, 212, 194, 30, 140, 24, 36, 0, 8, 130, 129, 4, 14, 171, -48, 11, 190, 64, 11, 122, 48, 98, 144, 0, 32, 8, 6, 18, 56, 172, 130, 44, 248, 194, 45, 228, 1, 2, 0, 0, 0, 0, 0, 0, 1, +32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, +0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, +71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, 2, 43, 133, 98, +160, 3, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 121, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, +185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 192, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, +27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 35, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 180, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, +124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, 2, 101, 130, 112, 48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, 11, 203, 52, 66, +11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, 152, 129, 24, 96, 0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, 136, 78, 193, 128, +13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 158, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, 153, 28, 143, 89, 24, 219, 92, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, 56, 128, 128, 42, +108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, 102, 87, 38, 55, 37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, 46, 114, 101, 115, +111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 112, 6, +83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 235, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 164, 225, 242, 157, 199, 23, 34, 2, 152, 136, 16, 104, +134, 133, 176, 129, 109, 184, 124, 231, 241, 133, 128, 42, 10, 34, 42, 29, 96, 40, 9, 3, 16, 48, 191, 184, 109, 35, 168, 134, 203, 119, 30, 95, 154, 156, 136, 64, 169, 233, 161, 38, 191, 184, 109, 0, 0, 97, 32, 0, 0, 171, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 154, +84, 85, 80, 52, 98, 144, 0, 32, 8, 6, 200, 54, 89, 22, 36, 141, 24, 36, 0, 8, 130, 1, 194, 81, 214, 37, 77, 35, 6, 9, 0, 130, 96, 128, 116, 213, 133, 73, 212, 136, 65, 2, 128, 32, 24, 32, 158, 133, 101, 82, 53, 98, 144, 0, 32, 8, 6, 200, 119, 101, 154, 100, 141, 24, +36, 0, 8, 130, 1, 2, 6, 152, 180, 89, 215, 136, 65, 2, 128, 32, 24, 32, 97, 144, 77, 156, 133, 141, 24, 36, 0, 8, 130, 1, 34, 6, 26, 213, 89, 217, 136, 65, 2, 128, 32, 24, 32, 99, 176, 85, 158, 165, 141, 24, 36, 0, 8, 130, 1, 66, 6, 92, 245, 105, 219, 136, 65, 2, +128, 32, 24, 32, 101, 208, 89, 96, 160, 113, 35, 6, 9, 0, 130, 96, 128, 152, 129, 119, 133, 129, 214, 141, 24, 36, 0, 8, 130, 1, 114, 6, 31, 38, 6, 154, 55, 98, 144, 0, 32, 8, 6, 8, 26, 128, 1, 24, 140, 129, 247, 141, 24, 36, 0, 8, 130, 1, 131, 6, 89, 71, 6, 100, +128, 85, 25, 136, 1, 142, 24, 28, 0, 8, 130, 129, 147, 6, 153, 16, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 26, 116, 80, 65, 26, 224, 136, 193, 1, 128, 32, 24, 56, 112, 0, 6, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 114, +48, 6, 80, 1, 28, 224, 136, 193, 1, 128, 32, 24, 56, 119, 112, 6, 80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 121, 144, 6, 80, 193, 29, 224, 136, 193, 1, 128, 32, 24, 56, 126, 224, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, +96, 150, 25, 72, 192, 160, 51, 144, 128, 41, 104, 32, 1, 35, 210, 64, 2, 182, 173, 129, 4, 44, 40, 32, 96, 86, 27, 72, 192, 2, 3, 2, 22, 189, 129, 4, 44, 56, 32, 96, 76, 28, 72, 192, 2, 4, 2, 70, 6, 116, 32, 1, 11, 16, 8, 216, 103, 7, 18, 176, 0, 129, 128, 105, +120, 32, 1, 11, 16, 8, 88, 165, 7, 18, 176, 0, 129, 128, 181, 65, 31, 72, 192, 2, 4, 2, 134, 6, 127, 32, 1, 11, 16, 8, 216, 24, 132, 130, 4, 44, 64, 32, 96, 222, 40, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 220, 194, 49, 98, 144, +0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 130, 45, 20, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 212, 194, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 2, 45, 4, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 240, 2, 47, 220, 194, 41, 140, 24, 36, 0, +8, 130, 193, 227, 11, 171, 192, 11, 188, 96, 11, 166, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 46, 240, 194, 45, 132, 194, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 187, 192, 11, 182, 0, 10, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 236, 2, 47, 212, 194, 31, 140, 24, 36, +0, 8, 130, 193, 227, 11, 171, 176, 11, 188, 64, 11, 126, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 44, 240, 194, 45, 244, 193, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 179, 192, 11, 182, 192, 7, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 204, 2, 47, 212, 194, 30, 140, 24, +36, 0, 8, 130, 193, 227, 11, 171, 48, 11, 188, 64, 11, 122, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 130, 44, 240, 194, 45, 228, 1, 2, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index 28f9fb268d..ef53fe7e73 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -16,361 +16,365 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, -2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 150, 121, 37, 154, 211, 55, 191, 41, 11, 9, 239, 133, 109, 6, 77, 122, 0, 240, 40, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, -1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, -2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, -2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, -0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, -116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, -0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, -110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, -0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, -108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, -0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, -101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, -0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, -0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, -0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, -0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, -117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, -0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, -50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, -0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, -0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, -48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, -97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, -0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, -0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, -1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, -1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, -110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, -0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, -2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, -116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, -95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, -0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, -97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, -111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, -119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, -0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, -116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, -97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, -2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, -0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, -111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, -83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, -0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, -0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, -65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, -0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, -0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, -0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, -108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, -112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, -121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, -114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, -108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, -79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, -2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, -2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, -0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, -0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, -22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, -22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, -0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, -0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, -0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, -0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, -0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, -0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, -0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, -0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, -0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, -0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, -0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, -0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, -0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, -0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, -0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, -0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, -0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, -0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, -0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, -1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, -1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, -2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, -0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, -0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, -2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, -0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, -0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, -0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, -0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, -0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, -0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, -0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, -0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, -0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, -0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, -0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, -0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, -0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, -2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, -0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, -0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, -0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, -0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, -0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, -0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, -0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, -0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, -0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, -1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, -0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, -0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, -0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, -0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, -1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, -1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, -0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, -0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, -0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, -1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, -0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, -1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, -1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, -1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, -0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, -0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, -0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, -0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, -2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, -0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, -0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, -0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, -1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, -0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, -2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, -0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, -2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, -2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, -2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, -0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, -0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, -2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, -2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, -0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, -2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, -2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, -2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, -0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, -2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 150, 121, 37, 154, 211, 55, 191, 41, 11, 9, 239, 133, 109, 6, 77, 122, 0, 240, 40, 0, 0, 3, 2, -35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, -116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, -0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, -0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, 0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, -111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, -120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, -111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, -105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, -0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, -0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, -8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, -116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, -7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, -111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, -0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, -0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, -0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, -111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, -0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, -103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, -0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, -121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, -0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, -0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, -95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, -0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, -95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, -67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, -0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, -0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, -6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, -0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, -114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 46, 2, -0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, -0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, -95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, -0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, -0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, -95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, -0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, -101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, -0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, -0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, -97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, -7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, -0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, -0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, -0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, -5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, -0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, -0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, -0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, -0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, -0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, -4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, -0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, -0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, -0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, -0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, -0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, -0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, -0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, -0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, -0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, -0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, -3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, -0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, -0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, -0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, -4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, -0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, -4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, -4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, -4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, -0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, -0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, -0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, -4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, -4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, -0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, -0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, -0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, -4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, -0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, -0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, -0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, -0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, -0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, -4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, -0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, -0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, -0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, -0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, -0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, -0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, -0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, -3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, -0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, -0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, -0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, -0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, -0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, -0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, -0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, -5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, -5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, -0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, -0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, -0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, -2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, -0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, -0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, -0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, -0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, -0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, -0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, -0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, -0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, -0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, -0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, -0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, -0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, -0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, -0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, -0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, -114, 0, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, +0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, +105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 29, 179, 72, 201, 228, 187, 147, 193, 184, 189, 228, 44, 171, 184, 227, 246, 0, 88, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, +3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, 0, 40, 0, +0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 82, 2, +0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, +101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, +47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, +108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, +97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, +47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, +115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, +101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, +0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 40, 2, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, +101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, +116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, +11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, +0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, 111, 114, 85, +116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 206, 0, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, 95, 70, 117, +110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, +4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, +48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, +5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 106, 1, +0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, +4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 164, 1, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, +95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, +114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, +4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, +0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, +0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, +103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, +116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, +5, 0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, +6, 0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, +6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, +100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, +0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, +4, 0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, +4, 0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, +0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, +6, 0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, +122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, +0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, +5, 0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, +5, 0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, +105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, +0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, +0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, +69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, +110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, +0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, +3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, +0, 0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, +6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, +4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, +0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, +3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, +0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, +0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, +0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, +4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, +0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, +0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, +0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, +4, 0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, +4, 0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, +4, 0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, +128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, +184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, +78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, +4, 0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, +4, 0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, +4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, +4, 0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, +4, 0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, +4, 0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, +0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, +0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, +0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, +0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, +5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, +0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, +0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, +0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, +0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, +0, 0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, +0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, +0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, +0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, +0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, +0, 0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, +0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, +2, 0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, +0, 0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, +0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, +0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, +3, 0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, +2, 0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, +0, 0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, +0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, +4, 0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, +0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, +0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, +3, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, +4, 0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, +0, 0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, +5, 0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, +0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, +2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, +6, 0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, +0, 0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, +0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, +0, 0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, +0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, +0, 0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, +4, 0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, +3, 0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, +0, 0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, +0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, +0, 0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, +4, 0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, +5, 0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, +0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 29, 179, 72, 201, 228, 187, 147, 193, 184, 189, 228, 44, 171, 184, 227, 246, 0, 88, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, +0, 117, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, +48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, +0, 57, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, +0, 78, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, +0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, +83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, +0, 7, 0, 20, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, +0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, +0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, +0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, +0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, +114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, +0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, +110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, +0, 5, 0, 7, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, +0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, +52, 55, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, +0, 5, 0, 5, 0, 106, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, +52, 53, 0, 0, 0, 5, 0, 4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, +0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, +0, 181, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, +0, 211, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, +0, 110, 88, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 3, 0, 248, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, +0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, +0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, +0, 44, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, +0, 50, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 0, 0, 5, 0, 5, 0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, +85, 84, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, +0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 5, 0, 5, 0, 57, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 5, 0, 4, 0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, +95, 52, 0, 0, 0, 5, 0, 4, 0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 5, 0, 6, 0, 80, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 0, 0, 0, 0, 5, 0, 6, 0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, +0, 5, 0, 5, 0, 88, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, +122, 122, 108, 101, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, +0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, +0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 6, 0, 6, 0, 90, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, +62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, +0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, +116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, +0, 50, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, +0, 76, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, +78, 0, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, +0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, +0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, +0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, +0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, +0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, +0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, +0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, +0, 5, 0, 0, 0, 33, 0, 4, 0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, +0, 194, 44, 77, 60, 23, 0, 4, 0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, +0, 4, 0, 0, 0, 33, 0, 4, 0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 4, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, +0, 76, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, +0, 106, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, +0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, +0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, +0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, +0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, +0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, +0, 42, 0, 0, 0, 32, 0, 4, 0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 104, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, +0, 45, 2, 0, 0, 44, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 52, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 49, 2, 0, 0, 83, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 91, 2, 0, 0, 92, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 135, 0, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, +0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, +0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, +0, 59, 0, 4, 0, 211, 0, 0, 0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 62, 0, 3, 0, 230, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, +0, 209, 0, 0, 0, 237, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, +0, 129, 0, 5, 0, 209, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, +0, 129, 0, 5, 0, 209, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, +0, 5, 0, 0, 0, 245, 0, 0, 0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 250, 0, 0, 0, 249, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, +0, 180, 1, 0, 0, 181, 1, 0, 0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 194, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, +0, 181, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, +0, 210, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, +0, 28, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, +0, 12, 0, 6, 0, 5, 0, 0, 0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, +0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, +0, 211, 1, 0, 0, 248, 0, 2, 0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, +0, 230, 1, 0, 0, 229, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, +0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, +0, 231, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, +0, 240, 1, 0, 0, 62, 0, 3, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, +0, 250, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, +0, 255, 1, 0, 0, 251, 1, 0, 0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, +0, 1, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 6, 2, 0, 0, 248, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, +0, 223, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, +0, 15, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, +0, 18, 2, 0, 0, 10, 2, 0, 0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, +0, 4, 0, 0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, +0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 31, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, +0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 38, 2, 0, 0, 28, 2, 0, 0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, +0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, +0, 48, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, +0, 93, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, +0, 96, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, +0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 102, 2, 0, 0, 83, 2, 0, 0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, +0, 105, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, +0, 108, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, +0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 114, 2, 0, 0, 113, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, +0, 116, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs index 2feb0a7d1a..d060e74911 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -16,65 +16,77 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, -114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, -0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, -1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, -88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, -140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, -105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 39, 157, 68, 28, 42, 149, 249, 159, 238, 192, 103, 70, 40, 36, 244, 0, 212, 97, 0, 0, 68, 88, 66, 67, 220, 182, 27, 10, 229, 195, -112, 16, 142, 228, 195, 14, 178, 185, 52, 133, 1, 0, 0, 0, 212, 97, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 95, 0, 0, 112, 96, 0, 0, 36, 97, 0, 0, 160, 97, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, -255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, -0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, -99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, -255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 91, 0, 0, 0, 220, 4, 0, 0, 106, 0, 0, 0, 236, 4, 0, 0, 106, 0, 0, 0, 252, 4, 0, 0, 97, 0, -0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 36, 5, 0, 0, 104, 0, 0, 0, 52, 5, 0, 0, 109, 0, 0, 0, 72, 5, 0, 0, 111, 0, 0, 0, 92, 5, 0, 0, 108, 0, 0, 0, 108, 5, 0, 0, 111, 0, 0, 0, 128, 5, 0, 0, 111, 0, -0, 0, 148, 5, 0, 0, 111, 0, 0, 0, 160, 5, 0, 0, 111, 0, 0, 0, 172, 5, 0, 0, 112, 0, 0, 0, 188, 5, 0, 0, 113, 0, 0, 0, 208, 5, 0, 0, 113, 0, 0, 0, 220, 5, 0, 0, 113, 0, 0, 0, 240, 5, 0, 0, 114, 0, 0, 0, 4, 6, 0, 0, 114, 0, -0, 0, 20, 6, 0, 0, 114, 0, 0, 0, 32, 6, 0, 0, 118, 0, 0, 0, 48, 6, 0, 0, 118, 0, 0, 0, 60, 6, 0, 0, 118, 0, 0, 0, 72, 6, 0, 0, 118, 0, 0, 0, 84, 6, 0, 0, 118, 0, 0, 0, 104, 6, 0, 0, 119, 0, 0, 0, 124, 6, 0, 0, 119, 0, -0, 0, 136, 6, 0, 0, 119, 0, 0, 0, 148, 6, 0, 0, 119, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, -255, 255, 255, 255, 255, 255, 95, 52, 53, 52, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, -3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, -0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, -97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, -114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, -4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, -3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, -0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, -0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, -40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, -0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, -0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, -2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, -0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, -85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, -0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, -255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, -255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, -228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, -0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, -0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, -0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, -16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, -0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, -0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, -16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, -0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, -128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, -16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, -48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, +97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, +114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, +0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, +114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, +193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, +54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 230, 110, 102, 238, 206, 20, 39, 1, 180, 20, 102, 188, 241, 12, 105, 41, 0, 212, 89, 0, 0, 68, 88, 66, 67, 41, 58, 3, 77, 142, 179, 65, 127, 140, 95, 49, 109, 120, 241, 116, 92, 1, 0, 0, 0, 212, 89, +0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, +40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, +0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, +255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, +0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, +0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, 0, 0, 104, 0, +0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, 0, 0, 105, 0, +0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 52, 0, 171, 171, 171, 1, 0, +3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, +0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, +255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, +255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, +0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, +0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, +0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, +67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, +0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, +0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, +228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, +0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, +0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, +170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, +85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, +8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, +15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, +0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, +16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, +0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, +0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, +0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, +16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, +16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, +128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, +16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, +16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, +16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, +0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -82,7 +94,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -90,319 +102,287 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 114, 78, 3, 249, 109, 197, 166, 74, 147, 45, -88, 122, 114, 201, 110, 163, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 144, 133, 76, 21, 226, 153, 238, 70, 128, 57, 7, 56, 78, 252, 242, 26, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, -3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 33, 155, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 37, 52, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, -117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, -116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, -125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, 32, -32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, -53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, -32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, -48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, -101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, -48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, -61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, -32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, -41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, -83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, -32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, -123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, -111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, -32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, -116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 212, 14, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, -97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 57, 97, 56, 55, 52, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 89, 41, 1, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, -0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 14, 44, 175, 59, 31, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, -10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, -0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, -0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, -88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, -0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 61, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 60, 1, -104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, -3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, -6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, -13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 53, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, -152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, -0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, -4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, -110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, -0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, -114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, -20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, -78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 203, 39, 249, 232, 99, 206, 164, 195, 125, 69, 140, 61, 231, 249, 19, 238, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, -0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 144, 0, 0, 128, 104, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 0, 144, 0, 0, 128, 144, 0, 0, 0, 144, 0, 0, 0, 188, 0, 0, 0, 144, 0, 0, 128, 188, 0, 0, 0, 144, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 128, 200, 0, -0, 0, 144, 0, 0, 0, 236, 0, 0, 0, 144, 0, 0, 128, 236, 0, 0, 0, 144, 0, 0, 0, 0, 1, 0, 0, 144, 0, 0, 128, 0, 1, 0, 0, 144, 0, 0, 0, 4, 1, 0, 0, 144, 0, 0, 128, 4, 1, 0, 0, 144, 0, 0, 0, 40, 1, 0, 0, 144, 0, 0, 128, 40, 1, -0, 0, 144, 0, 0, 0, 44, 1, 0, 0, 144, 0, 0, 128, 44, 1, 0, 0, 144, 0, 0, 0, 104, 1, 0, 0, 144, 0, 0, 128, 104, 1, 0, 0, 144, 0, 0, 0, 132, 1, 0, 0, 144, 0, 0, 128, 132, 1, 0, 0, 144, 0, 0, 0, 160, 1, 0, 0, 144, 0, 0, 128, 160, 1, -0, 0, 144, 0, 0, 0, 188, 1, 0, 0, 144, 0, 0, 128, 188, 1, 0, 0, 144, 0, 0, 0, 208, 1, 0, 0, 144, 0, 0, 128, 208, 1, 0, 0, 144, 0, 0, 0, 240, 1, 0, 0, 144, 0, 0, 128, 240, 1, 0, 0, 144, 0, 0, 0, 20, 2, 0, 0, 144, 0, 0, 128, 20, 2, -0, 0, 144, 0, 0, 0, 40, 2, 0, 0, 144, 0, 0, 128, 40, 2, 0, 0, 144, 0, 0, 0, 76, 2, 0, 0, 144, 0, 0, 128, 76, 2, 0, 0, 144, 0, 0, 0, 96, 2, 0, 0, 144, 0, 0, 128, 96, 2, 0, 0, 144, 0, 0, 0, 116, 2, 0, 0, 144, 0, 0, 128, 116, 2, -0, 0, 144, 0, 0, 0, 152, 2, 0, 0, 144, 0, 0, 128, 152, 2, 0, 0, 144, 0, 0, 0, 188, 2, 0, 0, 147, 0, 0, 128, 188, 2, 0, 0, 147, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, +1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 84, 60, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 66, 179, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, +88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, +97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, +52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, +49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, +32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, +48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, +40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, +116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, +120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, +102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, +114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, +32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, +122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 107, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, +0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, +115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 97, 56, 100, 50, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 4, 27, 216, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 180, 163, 63, 131, 182, 11, +0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, +116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, +112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, +0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, +0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, +84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 61, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 60, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, +0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, +13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, +3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, +9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, +5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, +80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, +40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, +6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, +0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, +0, 0, 16, 1, 82, 3, 152, 165, 246, 198, 226, 74, 24, 39, 198, 133, 161, 74, 251, 149, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, 0, 128, 104, 0, +0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, 0, 128, 236, 0, +0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, 0, 128, 44, 1, +0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, 0, 128, 188, 1, +0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, 0, 128, 40, 2, +0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, 0, 128, 152, 2, +0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 129, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 2, 16, 0, 0, 0, 0, -0, 0, 95, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, +0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, -0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, -83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, -5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, -111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, -242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, -0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, -1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, +0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, +242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, +0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, +8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, +0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 112, 82, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, +23, 21, 0, 0, 0, 0, 10, 2, 112, 82, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, -101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, -117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, -116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, -125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 53, 52, 59, 10, 32, 32, -32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, -53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, -32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 53, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 53, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, -48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, -101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, -48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, -61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, -32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, -41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, -83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, -65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, -32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, -123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, -111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, -32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, -116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, +88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, +97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, +52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, +49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, +32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, +48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, +40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, +116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, +120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, +102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, +114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, +32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, +122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, -0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, -100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, +0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, -0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, -100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, +0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, -81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, -105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, +255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, -1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, -0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, -255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, -114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 57, 65, 56, 55, 52, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 114, 78, 3, 249, 109, 197, 166, 74, 147, 45, -88, 122, 114, 201, 110, 163, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 102, 53, 57, 97, 56, 55, 52, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, -0, 0, 0, 0, 0, 0, 4, 15, 0, 0, 128, 0, 0, 0, 31, 14, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 38, 0, -0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, -0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 7, 0, 0, 0, 25, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, +0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, +100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 144, 133, 76, 21, 226, 153, 238, 70, 128, 57, 7, 56, 78, 252, 242, 26, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, +110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 97, 56, 100, 50, 97, 48, 0, +4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 155, 12, 0, 0, 128, 0, 0, 0, 182, 11, +0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 24, 0, +0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, +0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -410,54 +390,54 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, -0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, -255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, -76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, -0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, -95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 53, 138, 11, 189, 15, 213, 198, 220, 176, 48, 42, 17, 37, 88, 61, 33, 0, 88, 96, 0, 0, 68, 88, 66, 67, 126, 178, 213, 92, 34, 254, 209, 162, 226, 133, 21, 210, 21, 107, 78, 46, 1, 0, 0, 0, 88, 96, -0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 180, 7, 0, 0, 188, 93, 0, 0, 56, 94, 0, 0, 8, 95, 0, 0, 184, 95, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, -48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, -0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, 0, 0, 32, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, -104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 65, 67, 51, 56, 55, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, -0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, 255, 255, 76, 4, 0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 104, 0, 0, 0, 112, 4, 0, 0, 110, 0, 0, 0, 128, 4, 0, 0, 110, 0, 0, 0, 148, 4, 0, 0, 110, 0, 0, 0, 168, 4, -0, 0, 104, 0, 0, 0, 184, 4, 0, 0, 104, 0, 0, 0, 200, 4, 0, 0, 104, 0, 0, 0, 216, 4, 0, 0, 138, 0, 0, 0, 232, 4, 0, 0, 138, 0, 0, 0, 252, 4, 0, 0, 140, 0, 0, 0, 8, 5, 0, 0, 140, 0, 0, 0, 20, 5, 0, 0, 110, 0, 0, 0, 32, 5, -0, 0, 143, 0, 0, 0, 44, 5, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, -171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, -0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 37, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 88, 1, 0, 0, 120, 1, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 88, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, -5, 0, 164, 1, 0, 0, 6, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 13, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 15, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 16, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 18, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 72, 2, 0, 0, 56, 1, -0, 0, 87, 2, 0, 0, 88, 1, 0, 0, 102, 2, 0, 0, 88, 1, 0, 0, 114, 2, 0, 0, 88, 1, 0, 0, 129, 2, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 144, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, -0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 5, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 14, 3, 0, 0, 88, 1, 0, 0, 30, 3, 0, 0, 56, 1, -0, 0, 39, 3, 0, 0, 88, 1, 0, 0, 48, 3, 0, 0, 88, 1, 0, 0, 54, 3, 0, 0, 88, 1, 0, 0, 63, 3, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 72, 3, 0, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 11, 0, -0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 32, 1, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 220, 1, 0, 0, 32, 1, 0, 0, 60, 2, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 200, 2, 0, 0, 0, 0, -0, 0, 4, 3, 0, 0, 120, 3, 0, 0, 3, 0, 0, 0, 136, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, -15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, -15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, -228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, -228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, -0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, -16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, -0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, -0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, -156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, -0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, -0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, -0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, -0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, -0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, +114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, +1, 187, 67, 94, 69, 16, 128, 187, 174, 140, 86, 231, 247, 12, 157, 171, 5, 0, 88, 88, 0, 0, 68, 88, 66, 67, 175, 44, 248, 4, 18, 108, 254, 90, 234, 183, 239, 103, 250, 116, 180, 166, 1, 0, 0, 0, 88, 88, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 180, 7, +0, 0, 188, 85, 0, 0, 56, 86, 0, 0, 8, 87, 0, 0, 184, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, +0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, 0, 0, 32, 1, +0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, 0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, 255, 255, 76, 4, +0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 90, 0, 0, 0, 112, 4, 0, 0, 96, 0, 0, 0, 128, 4, 0, 0, 96, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 168, 4, 0, 0, 90, 0, 0, 0, 184, 4, 0, 0, 90, 0, 0, 0, 200, 4, +0, 0, 90, 0, 0, 0, 216, 4, 0, 0, 124, 0, 0, 0, 232, 4, 0, 0, 124, 0, 0, 0, 252, 4, 0, 0, 126, 0, 0, 0, 8, 5, 0, 0, 126, 0, 0, 0, 20, 5, 0, 0, 96, 0, 0, 0, 32, 5, 0, 0, 129, 0, 0, 0, 44, 5, 0, 0, 109, 97, 105, 110, 0, 111, +117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, +0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 37, 1, +0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 88, 1, 0, 0, 120, 1, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 88, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 164, 1, 0, 0, 6, 0, 0, 0, 255, 255, 255, 255, 13, 0, +255, 255, 9, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 13, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 15, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 16, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 17, 0, +0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 18, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, +105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 72, 2, 0, 0, 56, 1, 0, 0, 87, 2, 0, 0, 88, 1, 0, 0, 102, 2, 0, 0, 88, 1, +0, 0, 114, 2, 0, 0, 88, 1, 0, 0, 129, 2, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 144, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, +7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 5, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 14, 3, 0, 0, 88, 1, 0, 0, 30, 3, 0, 0, 56, 1, 0, 0, 39, 3, 0, 0, 88, 1, 0, 0, 48, 3, 0, 0, 88, 1, +0, 0, 54, 3, 0, 0, 88, 1, 0, 0, 63, 3, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 72, 3, 0, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 11, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, +255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 32, 1, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 220, 1, 0, 0, 32, 1, 0, 0, 60, 2, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 200, 2, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 120, 3, 0, 0, 3, 0, 0, 0, 136, 3, +0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, +0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, +0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, +228, 128, 2, 0, 228, 144, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, +170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 2, 0, +15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, +0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, +0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, +0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, +0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, +0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, +16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, +0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, +0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, +0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -465,7 +445,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -473,303 +453,255 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 45, 212, 199, 15, 241, 225, 180, 72, 181, 71, 25, 182, 177, 197, 31, 246, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 182, 45, 33, 236, 64, 67, 241, 65, 131, 147, 147, 152, 230, 208, 31, 20, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, +32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, +3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, -122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, -84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, -3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, 3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, +32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, +116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, +83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, +40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, +54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, +10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, +32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, +108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, +122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, +123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, +116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, +32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, +110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, +112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, -101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, -83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, -78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, -122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, -84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, -112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, -50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, -111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, -119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, -102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, -97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, -108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, -32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, -105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, -122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, -105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, -32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, -120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, -112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, -32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, -97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, -110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, -10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, -32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, -61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 128, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, -53, 65, 67, 51, 56, 55, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, -116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 97, 99, 51, 56, 55, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, -101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, -83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, -78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 122, 223, 2, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, -48, 1, 43, 208, 170, 75, 203, 14, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, -77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, -108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, -0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, -0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, -110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, -92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, -4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, -92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, -4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 8, 0, 0, 0, 50, 0, 77, 17, 136, 0, 0, 0, 220, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 36, 6, 12, 12, 128, 136, 40, 12, 128, 128, 128, 176, 8, 0, 13, 35, 1, 128, 196, 12, 128, -136, 0, 12, 128, 128, 128, 176, 0, 0, 0, 66, 0, 77, 17, 244, 3, 0, 0, 216, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 9, 5, 13, 24, 6, 9, 12, 128, 128, 128, 176, 8, 0, 9, 27, 13, 53, 1, 128, 196, 6, 8, 12, 128, 136, 0, -9, 5, 13, 23, 6, 9, 12, 128, 128, 128, 176, 0, 0, 0, 54, 0, 77, 17, 40, 4, 0, 0, 164, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 196, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, -128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 42, 0, 77, 17, 40, 4, 0, 0, 212, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 128, 216, 8, 0, 9, 33, 13, 82, 1, 129, 116, 12, 128, 128, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, -78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 182, 141, 131, 252, 216, 47, 208, 169, 159, 118, 77, 56, 148, 24, 182, 145, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, -0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 152, 0, 0, 128, 156, 0, 0, 0, 152, 0, 0, 0, 176, 0, 0, 0, 152, 0, 0, 128, 176, 0, 0, 0, 152, 0, 0, 0, 196, 0, 0, 0, 145, 0, 0, 128, 196, 0, 0, 0, 145, 0, 0, 0, 0, 1, 0, 0, 145, 0, 0, 128, 0, 1, -0, 0, 145, 0, 0, 0, 48, 1, 0, 0, 145, 0, 0, 128, 48, 1, 0, 0, 145, 0, 0, 0, 76, 1, 0, 0, 152, 0, 0, 128, 76, 1, 0, 0, 152, 0, 0, 0, 96, 1, 0, 0, 152, 0, 0, 128, 96, 1, 0, 0, 152, 0, 0, 0, 116, 1, 0, 0, 145, 0, 0, 128, 116, 1, -0, 0, 145, 0, 0, 0, 148, 1, 0, 0, 145, 0, 0, 128, 148, 1, 0, 0, 145, 0, 0, 0, 180, 1, 0, 0, 145, 0, 0, 128, 180, 1, 0, 0, 145, 0, 0, 0, 212, 1, 0, 0, 145, 0, 0, 128, 212, 1, 0, 0, 145, 0, 0, 0, 244, 1, 0, 0, 152, 0, 0, 128, 244, 1, -0, 0, 152, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 1, 16, -0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, -24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, -0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 56, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 8, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, -102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, -0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, -0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, -3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, -0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 181, 177, 2, 0, 64, 168, 2, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 23, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, +100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, +115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, +120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 102, 99, 99, 53, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, +95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 181, 52, 220, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 138, 47, 163, 182, 98, 12, 0, 0, 1, 0, 0, 0, 90, 0, +0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, +83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, +101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, 0, 0, 1, 0, +160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 156, 0, +0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 156, 0, +0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 8, 0, 0, 0, 50, 0, 77, 17, 136, 0, 0, 0, 220, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 36, 6, 12, 12, 128, 136, 40, 12, 128, 128, 128, 176, 8, 0, 13, 35, 1, 128, 196, 12, 128, 136, 0, 12, 128, 128, 128, 176, 0, 0, 0, 66, 0, 77, 17, 244, 3, +0, 0, 216, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 9, 5, 13, 24, 6, 9, 12, 128, 128, 128, 176, 8, 0, 9, 27, 13, 53, 1, 128, 196, 6, 8, 12, 128, 136, 0, 9, 5, 13, 23, 6, 9, 12, 128, 128, 128, 176, 0, 0, 0, 54, 0, +77, 17, 40, 4, 0, 0, 164, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 196, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 42, 0, 77, 17, 40, 4, +0, 0, 212, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 128, 216, 8, 0, 9, 33, 13, 82, 1, 129, 116, 12, 128, 128, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, +0, 0, 16, 1, 206, 253, 16, 195, 255, 2, 68, 226, 90, 0, 130, 233, 146, 246, 37, 224, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 138, 0, 0, 128, 156, 0, +0, 0, 138, 0, 0, 0, 176, 0, 0, 0, 138, 0, 0, 128, 176, 0, 0, 0, 138, 0, 0, 0, 196, 0, 0, 0, 131, 0, 0, 128, 196, 0, 0, 0, 131, 0, 0, 0, 0, 1, 0, 0, 131, 0, 0, 128, 0, 1, 0, 0, 131, 0, 0, 0, 48, 1, 0, 0, 131, 0, 0, 128, 48, 1, +0, 0, 131, 0, 0, 0, 76, 1, 0, 0, 138, 0, 0, 128, 76, 1, 0, 0, 138, 0, 0, 0, 96, 1, 0, 0, 138, 0, 0, 128, 96, 1, 0, 0, 138, 0, 0, 0, 116, 1, 0, 0, 131, 0, 0, 128, 116, 1, 0, 0, 131, 0, 0, 0, 148, 1, 0, 0, 131, 0, 0, 128, 148, 1, +0, 0, 131, 0, 0, 0, 180, 1, 0, 0, 131, 0, 0, 128, 180, 1, 0, 0, 131, 0, 0, 0, 212, 1, 0, 0, 131, 0, 0, 128, 212, 1, 0, 0, 131, 0, 0, 0, 244, 1, 0, 0, 138, 0, 0, 128, 244, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 94, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, -112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, -50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, -111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, -119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, -102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, -97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, -108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, -32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, -105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, -122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, -105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, -32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, -120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, -112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, -32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 51, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 51, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, -97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, -110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, -10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, -32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, -61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, -242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, +0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, +0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, -242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 56, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 8, 0, +0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, +3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, +105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, +0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, +5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, +1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 181, 177, 2, 0, 64, 168, 2, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, +116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, +83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, +40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, +54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, +10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, +32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, +108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, +122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, +123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, +116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, +32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, +110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, +112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, +0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, +116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, +0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, +116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 16, 16, 0, 0, 8, 0, -1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, -0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 9, 0, 228, 4, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, -0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 65, 67, 51, 56, 55, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 182, 45, 33, 236, 64, 67, 241, 65, 131, 147, 147, 152, 230, 208, 31, 20, 134, 0, -0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, -53, 97, 99, 51, 56, 55, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, -220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 16, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, +119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 112, 2, 0, 0, 111, 1, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 176, 15, -0, 0, 128, 0, 0, 0, 203, 14, 0, 0, 140, 6, 0, 0, 76, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 16, 0, -0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, -0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -777,15 +709,31 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 4, 0, 0, 0, 0, 0, 0, 156, 1, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, +48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 45, 212, 199, 15, 241, 225, 180, 72, 181, 71, 25, 182, 177, 197, 31, 246, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, +101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, +100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 102, 99, 99, 53, 99, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, +1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 112, 2, 0, 0, 111, 1, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 71, 13, 0, 0, 128, 0, 0, 0, 98, 12, 0, 0, 140, 6, 0, 0, 76, 0, +0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, +0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, +0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -793,17 +741,17 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, -0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, -0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, -0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, -79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, +0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, +40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, +84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs index cac4b1af4f..78d9f8939c 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -16,127 +16,118 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, -2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 88, 175, 127, 150, 28, 106, 83, 42, 77, 34, 205, 184, 82, 111, 42, 178, 0, 74, 11, 0, 0, 68, 88, 66, 67, 39, 222, 121, 150, 118, 100, 3, 3, 84, 220, 56, 253, 11, 63, 194, 79, 1, 0, 0, 0, 74, 11, 0, 0, 5, 0, 0, 0, 52, -0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 110, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, -240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 52, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, -0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 212, 8, 0, 0, 96, 0, 0, 0, 53, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 188, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 44, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, -0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, -36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, -0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 95, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, -49, 65, 128, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, -140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, -40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 128, 50, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 80, 3, 0, 0, 192, 61, 195, 229, 79, 216, 67, 72, 126, 8, 52, 195, 66, -160, 0, 2, 0, 0, 160, 24, 17, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 55, 13, 151, 63, 97, 15, 33, 249, 43, 33, 173, 196, 228, 23, 183, 141, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, 0, 128, 194, 76, 0, 0, 0, 16, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 128, 0, -0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 128, 24, 0, 0, 0, 6, 2, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, +0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, +105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 234, 105, 136, 35, 1, 148, 245, 75, 50, 184, 129, 147, 118, 56, 51, 106, 0, 230, 10, 0, 0, 68, 88, 66, 67, 172, 15, 200, 65, 127, 177, 110, 83, 54, 176, 161, 139, 87, 51, +100, 18, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, +0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, +0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, +20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, +7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, +73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, +65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, +62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, 0, 0, 24, 0, +0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, 12, 4, 0, 0, +19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, +48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, +7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 30, 32, 0, 4, +0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, +0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 0, +0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, 134, 6, 0, 0, +0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, 130, 96, 48, 162, +42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, 108, 16, 2, 101, +67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, 112, 115, 19, 4, +160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, +16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, 128, 13, 132, 24, +148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 104, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, +101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, +170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, +30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 208, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, +3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 219, 128, 52, 92, 190, 243, 248, 66, 68, 0, 19, 17, 2, 205, 176, 16, 70, 0, 13, 151, 239, 60, 190, 4, 48, 207, 66, 248, 197, 109, 91, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, +77, 15, 53, 249, 197, 109, 3, 0, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, +156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, 101, 192, 121, 35, +6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, 224, 130, 97, 150, +33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, 70, 19, 6, 97, +52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, 96, 52, 33, 0, +70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, 129, 29, 109, 32, +1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, 49, 75, 96, 12, +84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, 17, 117, 32, 1, +35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 97, 22, 132, 17, +131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 243, 209, 253, 213, 32, 128, 64, 13, 87, 75, 30, 43, 219, 231, 72, 85, 0, 21, 12, 0, 0, 68, 88, 66, 67, 0, 178, 107, 234, 243, 13, 57, 236, 150, 80, 222, 151, +230, 179, 195, 194, 1, 0, 0, 0, 21, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, +8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, +69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, +67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, +0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, +0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 96, 8, 0, 0, 96, 0, 1, 0, 24, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 72, 8, 0, 0, 66, 67, 192, +222, 33, 12, 0, 0, 15, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, +8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, +32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, +80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, +0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, +32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, -32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, -0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 36, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 50, 0, 0, -0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, -40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 3, 2, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 8, 0, 0, 0, 138, 129, 0, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 8, 0, 0, 0, 74, 142, 0, 0, 0, 0, 102, 0, 136, 0, -0, 0, 160, 240, 8, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 136, 0, 0, 0, 160, 28, 10, 134, 0, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 2, 0, 0, 128, 82, 160, 6, 0, -0, 128, 146, 40, 132, 2, 1, 0, 0, 121, 24, 0, 0, 131, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, -151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, -84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 184, 54, -12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 4, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 12, 38, 8, 77, 180, 33, 8, 38, 8, 205, 180, 97, 9, 196, 96, 12, 200, 160, 12, -204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 202, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 2, 102, 195, 194, 136, 193, 24, 144, 193, 26, 152, 1, 145, 6, 12, 25, 0, 19, 4, 162, 218, 16, 180, 193, 4, 161, 145, 54, 44, 109, 32, 6, 99, 64, -6, 110, 96, 6, 196, 27, 180, 1, 25, 0, 27, 136, 51, 80, 3, 54, 128, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 198, 12, 54, 44, 129, 28, 140, 193, 28, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 160, 131, 13, 67, 28, 212, 1, 64, 51, 152, 130, 147, 75, 163, 43, -19, 10, 163, 27, 67, 155, 66, 11, 35, 43, 147, 227, 161, 147, 171, 43, 243, 113, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 119, 96, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, -155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, -75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 193, 29, 0, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 208, 105, 51, -156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 219, 128, 52, 92, 190, 243, 248, 66, 68, 0, 19, 17, 2, 205, 176, 16, 70, 0, 13, 151, 239, 60, 190, 4, 48, -207, 66, 248, 197, 109, 91, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 97, 32, 0, 0, 145, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 56, 102, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 103, 144, 133, 65, 24, 88, 216, -136, 65, 2, 128, 32, 24, 56, 104, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 105, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 106, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 107, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 56, 108, -224, 133, 129, 25, 112, 221, 136, 65, 2, 128, 32, 24, 56, 109, 240, 137, 193, 25, 112, 222, 136, 65, 2, 128, 32, 24, 56, 110, 0, 6, 99, 128, 6, 220, 55, 98, 144, 0, 32, 8, 6, 206, 27, 132, 1, 25, 164, 1, 7, 6, 35, 6, 9, 0, 130, 96, 224, 192, 129, 24, 112, 106, 0, 6, -97, 96, 1, 7, 129, 17, 3, 3, 0, 65, 48, 120, 226, 128, 11, 134, 27, 184, 96, 152, 101, 8, 132, 96, 196, 32, 1, 64, 16, 12, 36, 57, 224, 194, 192, 13, 220, 0, 13, 70, 12, 18, 0, 4, 193, 64, 154, 131, 174, 12, 222, 224, 13, 210, 96, 196, 224, 1, 64, 16, 12, 168, 57, 224, -2, 1, 122, 186, 238, 12, 206, 224, 12, 186, 209, 132, 0, 24, 77, 16, 130, 209, 132, 65, 24, 77, 32, 134, 89, 130, 97, 196, 32, 1, 64, 16, 12, 164, 60, 24, 3, 52, 168, 131, 58, 120, 131, 17, 131, 4, 0, 65, 48, 144, 244, 128, 12, 216, 192, 14, 236, 0, 14, 70, 12, 30, 0, 4, -193, 128, 210, 131, 49, 8, 132, 203, 34, 3, 50, 112, 3, 55, 112, 3, 50, 24, 77, 8, 128, 209, 4, 33, 24, 77, 24, 132, 209, 4, 98, 152, 37, 24, 6, 42, 0, 43, 64, 132, 129, 10, 0, 11, 16, 97, 160, 2, 208, 2, 68, 24, 168, 0, 184, 0, 17, 204, 90, 3, 8, 140, 24, 24, -0, 8, 130, 193, 99, 10, 113, 16, 12, 55, 196, 65, 48, 204, 50, 16, 69, 96, 71, 27, 72, 192, 130, 58, 128, 128, 33, 111, 32, 1, 11, 238, 0, 2, 54, 12, 18, 48, 65, 144, 128, 9, 1, 4, 70, 12, 12, 0, 4, 193, 224, 121, 133, 57, 8, 70, 12, 12, 0, 4, 193, 224, 129, 133, -57, 8, 108, 14, 130, 8, 88, 48, 7, 18, 176, 128, 14, 32, 48, 75, 96, 204, 18, 24, 3, 21, 128, 64, 136, 65, 49, 80, 1, 184, 3, 33, 6, 133, 157, 129, 29, 64, 96, 196, 192, 0, 64, 16, 12, 158, 91, 16, 133, 96, 184, 65, 20, 130, 97, 186, 1, 187, 130, 233, 134, 204, 16, 166, -27, 250, 192, 24, 108, 171, 3, 9, 24, 81, 7, 18, 48, 162, 14, 36, 96, 68, 29, 72, 192, 136, 58, 128, 128, 17, 117, 0, 1, 35, 234, 0, 2, 70, 212, 1, 4, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 168, 5, 98, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, -248, 5, 90, 24, 70, 12, 18, 0, 4, 193, 160, 10, 135, 81, 248, 133, 95, 152, 5, 97, 196, 32, 1, 64, 16, 12, 170, 112, 24, 133, 95, 248, 5, 89, 8, 16, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 7, 201, 65, 51, 97, 119, 186, 124, 172, 222, 35, 223, 38, 225, 71, 50, -0, 121, 12, 0, 0, 68, 88, 66, 67, 28, 55, 175, 87, 179, 24, 200, 28, 226, 197, 227, 151, 15, 77, 194, 191, 1, 0, 0, 0, 121, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 189, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, -105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 180, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, -0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, -0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 68, 88, 73, 76, 180, 8, 0, 0, 96, 0, 1, 0, 45, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 156, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 36, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, -4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, -24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, -96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, -29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, -212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, -2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, -113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, -48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, -0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 32, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, -67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 50, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, -0, 128, 178, 43, 144, 2, 42, 48, 2, 0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, 16, 205, 85, 39, 61, 34, 0, 0, 0, 40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 130, 0, 0, 0, 26, 3, 76, 144, 70, 2, -19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, -46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 186, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, -4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 188, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 229, 219, 176, 16, 218, 198, 129, 1, 71, 132, -1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 9, 2, 33, 109, 8, 204, 96, 195, 98, 6, 218, 198, 157, 1, 71, 132, 129, 25, 112, 192, 134, 192, 153, 32, 40, 206, 134, 197, 209, 54, 46, 13, 56, 66, 13, 28, 14, 216, 80, 124, 98, -80, 6, 104, 176, 6, 27, 150, 64, 219, 184, 206, 35, 188, 128, 3, 54, 44, 132, 182, 113, 96, 224, 17, 97, 64, 112, 192, 134, 101, 12, 180, 141, 35, 3, 143, 8, 131, 49, 224, 128, 13, 139, 25, 104, 27, 119, 6, 30, 161, 6, 102, 192, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, -220, 38, 8, 10, 180, 97, 113, 226, 96, 147, 131, 46, 12, 136, 48, 112, 56, 96, 67, 209, 6, 110, 240, 6, 112, 48, 7, 27, 6, 54, 160, 3, 128, 102, 48, 5, 39, 151, 70, 87, 38, 20, 70, 55, 134, 54, 133, 22, 70, 86, 38, 199, 67, 39, 87, 87, 230, 227, 98, 53, 213, 20, 150, 230, -246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 236, 160, 14, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, -101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, -236, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 214, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, -72, 195, 229, 59, 143, 47, 68, 4, 48, 17, 33, 208, 12, 11, 97, 3, 219, 112, 249, 206, 227, 11, 1, 85, 20, 68, 84, 58, 192, 80, 18, 6, 32, 96, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 190, 0, -0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 95, 165, 105, 19, 53, 98, 144, 0, 32, 8, 6, 11, 24, 88, 219, 54, 85, 35, 6, 9, 0, 130, 96, 176, 132, 193, 181, 113, 149, 53, 98, 144, 0, 32, 8, 6, 139, 24, 96, 92, 87, 93, 35, 6, 9, 0, 130, 96, 176, 140, 65, 214, -121, 21, 54, 98, 144, 0, 32, 8, 6, 11, 25, 104, 222, 87, 101, 35, 6, 9, 0, 130, 96, 176, 148, 193, 86, 129, 65, 166, 141, 24, 36, 0, 8, 130, 193, 98, 6, 156, 21, 6, 217, 54, 98, 144, 0, 32, 8, 6, 203, 25, 116, 151, 24, 100, 220, 136, 65, 2, 128, 32, 24, 44, 104, 224, -97, 99, 144, 117, 35, 6, 9, 0, 130, 96, 176, 164, 193, 135, 145, 65, 231, 141, 24, 36, 0, 8, 130, 193, 162, 6, 96, 144, 149, 65, 247, 141, 24, 36, 0, 8, 130, 193, 178, 6, 97, 160, 153, 65, 7, 6, 35, 6, 9, 0, 130, 96, 176, 176, 129, 24, 108, 103, 208, 133, 193, 136, 65, 2, -128, 32, 24, 44, 109, 48, 6, 99, 128, 6, 97, 32, 6, 35, 6, 9, 0, 130, 96, 240, 180, 1, 7, 6, 104, 128, 6, 91, 169, 65, 25, 224, 136, 193, 1, 128, 32, 24, 68, 110, 192, 9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 193, 1, 24, 64, 5, 108, 128, -35, 6, 7, 0, 130, 96, 16, 213, 193, 24, 36, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 221, 129, 25, 64, 5, 115, 128, 35, 6, 7, 0, 130, 96, 16, 241, 129, 26, 64, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 249, 1, 27, 64, 5, -122, 128, 35, 6, 7, 0, 130, 96, 16, 141, 66, 28, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 102, 32, 1, 131, 206, 64, 2, 166, 160, 129, 4, 140, 72, 3, 9, 216, 182, 6, 18, 176, 160, 128, 128, 89, 109, 32, 1, 11, 12, 8, 88, 244, 6, 18, 176, -224, 128, 128, 49, 113, 32, 1, 11, 16, 8, 24, 25, 208, 129, 4, 44, 64, 32, 96, 159, 29, 72, 192, 2, 4, 2, 166, 225, 129, 4, 44, 64, 32, 96, 149, 30, 72, 192, 2, 4, 2, 214, 6, 125, 32, 1, 11, 16, 8, 24, 26, 252, 129, 4, 44, 64, 32, 96, 99, 16, 10, 18, 176, 0, -129, 128, 121, 163, 32, 1, 11, 16, 8, 88, 40, 184, 130, 4, 44, 20, 94, 65, 2, 22, 10, 176, 32, 1, 27, 96, 1, 2, 54, 196, 2, 4, 108, 144, 5, 8, 216, 41, 12, 18, 176, 83, 24, 36, 96, 167, 48, 72, 192, 134, 90, 128, 128, 13, 182, 0, 1, 27, 110, 1, 2, 214, 10, 131, -4, 172, 21, 6, 9, 88, 43, 12, 18, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 97, 29, 224, 33, 29, 172, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 214, 1, 30, 208, 129, 26, 49, 72, 0, 16, 4, 3, 73, 30, 116, 97, 29, 224, 225, 28, 164, 17, 131, 4, 0, 65, 48, 144, 228, -65, 23, 214, 1, 30, 204, 1, 26, 49, 72, 0, 16, 4, 3, 73, 30, 116, 1, 30, 224, 33, 29, 108, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 5, 120, 128, 7, 116, 168, 133, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 222, 1, 30, 210, 97, 24, 49, 72, 0, 16, 4, 3, 73, 30, -116, 225, 29, 224, 1, 29, 132, 17, 131, 4, 0, 65, 48, 144, 228, 65, 23, 222, 1, 30, 206, 33, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 225, 29, 224, 193, 28, 90, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 133, 114, 128, 135, 116, 96, 133, 17, 131, 4, 0, 65, 48, 144, 228, 65, -23, 202, 1, 30, 208, 97, 21, 70, 12, 18, 0, 4, 193, 64, 146, 7, 93, 40, 7, 120, 56, 7, 85, 24, 49, 72, 0, 16, 4, 3, 73, 30, 116, 161, 28, 224, 193, 28, 82, 97, 196, 32, 1, 64, 16, 12, 36, 121, 208, 5, 114, 128, 135, 116, 64, 5, 4, 0, 0, 0, 0, 0, 1, +32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, +0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, +71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, 2, 35, 0, 0, +0, 128, 49, 2, 25, 165, 241, 244, 27, 35, 32, 109, 180, 151, 191, 49, 2, 209, 92, 117, 210, 35, 2, 0, 0, 128, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 121, 24, 0, 0, 120, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, +146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, +145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 216, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 131, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, +46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 186, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, 2, 101, 130, 112, +48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, 152, 129, 24, 96, +0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, 136, 78, 193, 128, 13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 154, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, 153, 28, 15, 157, +92, 93, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, 56, 128, 128, 42, 108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, 102, 87, 38, 55, +37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, 46, 114, 101, 115, 111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, 231, 82, 230, 70, +39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 214, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, +139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 72, 195, 229, 59, 143, 47, 68, 4, 48, 17, 33, 208, 12, 11, 97, 3, 219, 112, 249, 206, 227, 11, 1, 85, 20, 68, 84, 58, 192, 80, 18, 6, 32, 96, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, +113, 219, 0, 0, 0, 97, 32, 0, 0, 189, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 93, 133, 97, 19, 53, 98, 144, 0, 32, 8, 6, 136, 103, 101, 217, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 153, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, 166, 109, 213, 53, +98, 144, 0, 32, 8, 6, 72, 24, 100, 27, 87, 97, 35, 6, 9, 0, 130, 96, 128, 136, 129, 198, 117, 85, 54, 98, 144, 0, 32, 8, 6, 200, 24, 108, 149, 151, 105, 35, 6, 9, 0, 130, 96, 128, 144, 1, 103, 125, 217, 54, 98, 144, 0, 32, 8, 6, 72, 25, 116, 23, 24, 100, 220, 136, +65, 2, 128, 32, 24, 32, 102, 224, 97, 97, 144, 117, 35, 6, 9, 0, 130, 96, 128, 156, 193, 135, 137, 65, 231, 141, 24, 36, 0, 8, 130, 1, 130, 6, 96, 144, 141, 65, 247, 141, 24, 36, 0, 8, 130, 1, 146, 6, 97, 160, 145, 65, 7, 6, 35, 6, 9, 0, 130, 96, 128, 168, 129, 24, +108, 101, 208, 133, 193, 136, 65, 2, 128, 32, 24, 32, 107, 48, 6, 99, 96, 6, 97, 32, 6, 35, 6, 9, 0, 130, 96, 192, 172, 1, 7, 6, 103, 112, 6, 91, 161, 65, 25, 224, 136, 193, 1, 128, 32, 24, 56, 108, 192, 9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, +67, 185, 1, 24, 64, 5, 108, 128, 35, 6, 7, 0, 130, 96, 224, 204, 193, 24, 36, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 213, 129, 25, 64, 5, 115, 128, 35, 6, 7, 0, 130, 96, 224, 232, 129, 26, 64, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, +38, 16, 67, 241, 1, 27, 64, 5, 122, 128, 35, 6, 7, 0, 130, 96, 224, 132, 66, 28, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 102, 32, 1, 131, 206, 64, 2, 166, 160, 129, 4, 140, 72, 3, 9, 216, 182, 6, 18, 176, 160, 128, 128, 89, 109, 32, 1, +11, 12, 8, 88, 244, 6, 18, 176, 224, 128, 128, 49, 113, 32, 1, 11, 16, 8, 24, 25, 208, 129, 4, 44, 64, 32, 96, 159, 29, 72, 192, 2, 4, 2, 166, 225, 129, 4, 44, 64, 32, 96, 149, 30, 72, 192, 2, 4, 2, 214, 6, 125, 32, 1, 11, 16, 8, 24, 26, 252, 129, 4, 44, 64, +32, 96, 99, 16, 10, 18, 176, 0, 129, 128, 121, 163, 32, 1, 11, 16, 8, 88, 40, 184, 130, 4, 44, 20, 94, 65, 2, 22, 10, 176, 32, 1, 27, 96, 1, 2, 54, 196, 2, 4, 108, 144, 5, 8, 216, 41, 12, 18, 176, 83, 24, 36, 96, 167, 48, 72, 192, 134, 90, 128, 128, 13, 182, 0, +1, 27, 110, 1, 2, 214, 10, 131, 4, 172, 21, 6, 9, 88, 43, 12, 18, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, 220, 33, 29, 172, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 208, 129, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, 220, 225, 28, 164, +17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 204, 1, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 193, 29, 220, 33, 29, 108, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 119, 112, 7, 116, 168, 133, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, 29, 210, 97, 24, +49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 1, 29, 132, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, 29, 206, 33, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 193, 28, 90, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 133, 114, 112, 135, 116, 96, 133, 17, +131, 4, 0, 65, 48, 120, 224, 65, 23, 202, 193, 29, 208, 97, 21, 70, 12, 18, 0, 4, 193, 224, 129, 7, 93, 40, 7, 119, 56, 7, 85, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 28, 220, 193, 28, 82, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 114, 112, 135, 116, 64, 5, +4, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index 0534383338..7f6caabd5a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -16,360 +16,365 @@ namespace Stride.Graphics public partial class SpriteBatch { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, -0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, -2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 117, 76, 56, 59, 32, 6, 42, 25, 181, 71, 17, 176, 109, 21, 238, 52, 0, 236, 40, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, -1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, -2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, 0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, -2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, -0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, -116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, -0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, -110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, -0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, -108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, -0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, -101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, -0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, -0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, -0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, -0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, -117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, -0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, -50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, -0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, -0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, -48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, -97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 170, -1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, -1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, -101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, -102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, -0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, -0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, -102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, -117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, -97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, -2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, -0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, -0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, -108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, -111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, -114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, -60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, -110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, -2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, -0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, -108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, -2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, -0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, -0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, -111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, -104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, -0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, -0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, -101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, -71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, -101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, -0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, -0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, -22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, -22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, -0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, -79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, -2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, -2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, -0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, -0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, -0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, -0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, -0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, -0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, -0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, -0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, -0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, -0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, -0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, -0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, -0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, -0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, 4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, -0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, -1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, -1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, -1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, -204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, -0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, -0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, -0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, 0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, -0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, -0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, -0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, -2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, 0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, -2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, -0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, -2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, -2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, -2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, -2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, -2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, -0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, -0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, -0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, -0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, -0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, -0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, -0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, -0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, -0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, -0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, -0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, -0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, -0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, 2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, -0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, 0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, -1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, -1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, 0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, -1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, -1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, -2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, 0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, -0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, -1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, -1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, -0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, -1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, -1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, -1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, -0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, -1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, -1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, -1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, -1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, -1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, 0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, -1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, -2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, -2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, -0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, -0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, -0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, 2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, -0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, -2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, 0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, -2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, -2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, -2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, -0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, -0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, -2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, -2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, -2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, -2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, -2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, -2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, -2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, -2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, -2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 117, 76, 56, 59, 32, 6, 42, 25, 181, 71, 17, 176, 109, 21, 238, 52, 0, 236, 40, 0, 0, 3, 2, 35, 7, 0, 4, -1, 0, 0, 0, 0, 0, 105, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 0, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 11, 0, 6, 0, 197, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, -53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 16, 0, 4, 0, 0, 0, 43, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 31, 2, 0, 0, 33, 2, 0, 0, 35, 2, 0, 0, 36, 2, 0, 0, 29, 2, -0, 0, 42, 2, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 104, 2, 0, 0, 15, 0, 20, 0, 0, 0, 0, 0, 78, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 2, 0, 0, 65, 2, 0, 0, 66, 2, 0, 0, 68, 2, 0, 0, 70, 2, -0, 0, 61, 2, 0, 0, 63, 2, 0, 0, 67, 2, 0, 0, 69, 2, 0, 0, 71, 2, 0, 0, 77, 2, 0, 0, 111, 0, 0, 0, 104, 2, 0, 0, 16, 0, 3, 0, 43, 2, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, -0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, -101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, -0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, -6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, -100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, -0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 176, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, -111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 179, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 192, 0, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 197, 0, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 218, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, -108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 219, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 221, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 102, 108, -111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 53, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 57, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, -7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 84, 1, 0, 0, 102, 108, -111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 86, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 97, 1, 0, 0, 102, 108, 111, 97, 116, 95, -49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 133, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 147, 1, 0, 0, 84, 83, -82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 153, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 154, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, -104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 170, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 171, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, -6, 0, 190, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 194, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 198, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 202, 1, -0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 203, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, -0, 0, 5, 0, 4, 0, 217, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 212, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 221, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 105, 110, 116, 95, 48, 0, -0, 0, 5, 0, 3, 0, 229, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 230, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 238, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 246, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 250, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 213, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, -0, 0, 5, 0, 4, 0, 5, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 0, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 1, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 18, 2, -0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 30, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 29, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 32, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 31, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 34, 2, -0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 33, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 35, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, -0, 0, 5, 0, 6, 0, 37, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 36, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 38, 2, 0, 0, 80, 83, 95, 73, 78, 80, -85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 38, 2, 0, 0, 2, 0, 0, 0, 67, 111, -108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 38, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 39, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 39, 2, 0, 0, 0, 0, 0, 0, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 40, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 40, 2, 0, 0, 1, 0, -0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 40, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 40, 2, -0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 41, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 42, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, -0, 0, 5, 0, 12, 0, 43, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 46, 2, 0, 0, 105, 110, 116, 95, 49, 0, -0, 0, 5, 0, 4, 0, 49, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 52, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 55, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 48, 0, -0, 0, 5, 0, 8, 0, 61, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 62, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 64, 2, -0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 63, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 65, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 66, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 67, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 68, 2, 0, 0, 105, 110, 95, 86, 83, 95, -67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 70, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 72, 2, -0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 71, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, -0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 2, 0, 0, 0, 67, 111, -108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 73, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 73, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 74, 2, 0, 0, 86, 83, 95, 79, 85, 84, -80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 74, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 74, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 74, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 74, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 75, 2, -0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 75, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 75, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 75, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, -100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 76, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 77, 2, -0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 78, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, -4, 0, 89, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 5, 0, 6, 0, 102, 2, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 102, 2, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 103, 2, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, -108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 29, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 31, 2, 0, 0, 30, 0, -0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 31, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 33, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 33, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, -0, 0, 71, 0, 4, 0, 35, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 35, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 36, 2, 0, 0, 3, 22, -0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 61, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 2, 0, 0, 3, 22, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 63, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 2, 0, 0, 30, 0, 0, 0, 1, 0, -0, 0, 0, 22, 6, 0, 65, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 66, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 66, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, -4, 0, 67, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 67, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 68, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 69, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 70, 2, -0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 71, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 71, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -0, 0, 71, 0, 3, 0, 102, 2, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 2, 0, -0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 5, 0, 0, 0, 35, 0, -0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, -0, 0, 72, 0, 5, 0, 102, 2, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, -0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 104, 2, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 104, 2, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, -0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, -0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, -0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, -0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, -0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 205, 204, 12, 64, 32, 0, -4, 0, 186, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 185, 0, 0, 0, 4, 0, 0, 0, 186, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 192, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 196, 162, 46, 63, 43, 0, -4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 200, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 200, 0, 0, 0, 33, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 202, 0, 0, 0, 32, 0, -4, 0, 218, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 239, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 243, 0, 0, 0, 3, 0, 0, 0, 218, 0, 0, 0, 186, 0, -0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 251, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 53, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 57, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 192, 172, -165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 84, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 86, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 92, 1, 0, 0, 174, 71, -97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 97, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 102, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 133, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 147, 1, 0, 0, 43, 0, -4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 198, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 133, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 0, 43, 0, -4, 0, 133, 0, 0, 0, 230, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 235, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 250, 1, 0, 0, 2, 0, 0, 0, 43, 0, -4, 0, 4, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 5, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 30, 2, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, -4, 0, 34, 2, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 37, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 38, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 39, 2, 0, 0, 3, 0, -0, 0, 30, 0, 7, 0, 40, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 6, 0, 0, 0, 40, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 43, 0, -4, 0, 133, 0, 0, 0, 49, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 52, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 55, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 32, 0, -4, 0, 64, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 72, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 73, 2, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 74, 2, -0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 8, 0, 75, 2, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 76, 2, 0, 0, 6, 0, -0, 0, 75, 2, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 89, 2, 0, 0, 5, 0, 0, 0, 30, 0, 12, 0, 102, 2, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, -0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 103, 2, 0, 0, 2, 0, 0, 0, 102, 2, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 103, 2, 0, 0, 104, 2, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, -0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 29, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 31, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 33, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 35, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 61, 2, -0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 32, 2, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, 2, 0, 0, 63, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 65, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 66, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 34, 2, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 30, 2, 0, 0, 69, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 70, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 72, 2, 0, 0, 71, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 76, 2, 0, 0, 77, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, -0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 77, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, -0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, -0, 0, 154, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, -0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, -0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, -0, 0, 217, 0, 0, 0, 55, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 248, 0, 2, 0, 220, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 222, 0, 0, 0, 219, 0, 0, 0, 79, 0, 8, 0, 200, 0, -0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 224, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 225, 0, -0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 200, 0, 0, 0, 226, 0, 0, 0, 221, 0, 0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 228, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 192, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 228, 0, -0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 230, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 229, 0, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 231, 0, 0, 0, 225, 0, 0, 0, 229, 0, -0, 0, 80, 0, 6, 0, 200, 0, 0, 0, 233, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 197, 0, 0, 0, 129, 0, 5, 0, 200, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 233, 0, 0, 0, 133, 0, 5, 0, 200, 0, 0, 0, 234, 0, 0, 0, 224, 0, 0, 0, 232, 0, -0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 236, 0, 0, 0, 234, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 65, 0, -5, 0, 186, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 242, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 241, 0, 0, 0, 254, 0, -2, 0, 242, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 153, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 181, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 169, 1, -0, 0, 112, 0, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 147, 1, 0, 0, 170, 1, 0, 0, 171, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 175, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 183, 1, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 184, 1, 0, 0, 183, 1, 0, 0, 62, 0, 3, 0, 181, 1, 0, 0, 184, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 176, 0, 0, 0, 181, 1, -0, 0, 62, 0, 3, 0, 175, 1, 0, 0, 186, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 154, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 189, 1, -0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 190, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 221, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 229, 1, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 186, 0, 0, 0, 238, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 218, 0, 0, 0, 18, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 192, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 193, 1, -0, 0, 192, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 195, 1, 0, 0, 193, 1, 0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 196, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 195, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 199, 1, 0, 0, 196, 1, -0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 201, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 199, 1, 0, 0, 202, 1, 0, 0, 203, 1, 0, 0, 248, 0, 2, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 206, 1, 0, 0, 114, 0, 0, 0, 79, 0, 9, 0, 3, 0, -0, 0, 207, 1, 0, 0, 206, 1, 0, 0, 206, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 207, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 203, 1, 0, 0, 57, 0, 4, 0, 3, 0, -0, 0, 210, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 210, 1, 0, 0, 249, 0, 2, 0, 201, 1, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 211, 1, 0, 0, 200, 1, 0, 0, 62, 0, 3, 0, 190, 1, 0, 0, 211, 1, -0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 215, 1, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 215, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 218, 1, 0, 0, 216, 1, 0, 0, 217, 1, 0, 0, 12, 0, 6, 0, 4, 0, -0, 0, 219, 1, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 218, 1, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 220, 1, 0, 0, 219, 1, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 213, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 220, 1, 0, 0, 212, 1, 0, 0, 213, 1, -0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 225, 1, 0, 0, 190, 1, 0, 0, 224, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 217, 1, -0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 228, 1, 0, 0, 227, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 231, 1, 0, 0, 190, 1, 0, 0, 230, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, -0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 217, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 186, 0, -0, 0, 236, 1, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 240, 1, 0, 0, 221, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 241, 1, 0, 0, 239, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 229, 1, 0, 0, 133, 0, -5, 0, 4, 0, 0, 0, 244, 1, 0, 0, 242, 1, 0, 0, 243, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 245, 1, 0, 0, 241, 1, 0, 0, 244, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 247, 1, 0, 0, 197, 1, 0, 0, 43, 0, 0, 0, 245, 1, 0, 0, 246, 1, -0, 0, 194, 1, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 248, 1, 0, 0, 197, 1, 0, 0, 31, 0, 0, 0, 247, 1, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 249, 1, 0, 0, 194, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 249, 1, 0, 0, 65, 0, -5, 0, 186, 0, 0, 0, 251, 1, 0, 0, 190, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 255, 1, -0, 0, 254, 1, 0, 0, 253, 1, 0, 0, 62, 0, 3, 0, 251, 1, 0, 0, 255, 1, 0, 0, 249, 0, 2, 0, 213, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 3, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 4, 2, 0, 0, 3, 2, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 2, 0, 0, 4, 2, 0, 0, 5, 2, 0, 0, 12, 0, 6, 0, 4, 0, 0, 0, 7, 2, 0, 0, 197, 1, 0, 0, 4, 0, 0, 0, 6, 2, 0, 0, 188, 0, 5, 0, 7, 0, 0, 0, 8, 2, -0, 0, 7, 2, 0, 0, 198, 1, 0, 0, 247, 0, 3, 0, 1, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 8, 2, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 248, 0, 2, 0, 0, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 9, 2, 0, 0, 190, 1, 0, 0, 79, 0, -7, 0, 38, 0, 0, 0, 11, 2, 0, 0, 9, 2, 0, 0, 9, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 12, 2, 0, 0, 190, 1, 0, 0, 79, 0, 7, 0, 38, 0, 0, 0, 13, 2, 0, 0, 12, 2, 0, 0, 12, 2, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 14, 2, 0, 0, 190, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 190, 1, -0, 0, 15, 2, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 16, 2, 0, 0, 190, 1, 0, 0, 235, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 2, 0, 0, 230, 1, 0, 0, 62, 0, 3, 0, 16, 2, 0, 0, 17, 2, 0, 0, 249, 0, 2, 0, 1, 2, 0, 0, 248, 0, -2, 0, 1, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 19, 2, 0, 0, 190, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 21, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 133, 0, 5, 0, 3, 0, -0, 0, 23, 2, 0, 0, 19, 2, 0, 0, 22, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 25, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 129, 0, 5, 0, 3, 0, 0, 0, 27, 2, 0, 0, 23, 2, -0, 0, 26, 2, 0, 0, 62, 0, 3, 0, 18, 2, 0, 0, 27, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 28, 2, 0, 0, 18, 2, 0, 0, 254, 0, 2, 0, 28, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 43, 2, 0, 0, 0, 0, 0, 0, 29, 0, -0, 0, 248, 0, 2, 0, 44, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 45, 2, 0, 0, 42, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 47, 2, 0, 0, 31, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 47, 2, 0, 0, 65, 0, 5, 0, 2, 0, -0, 0, 48, 2, 0, 0, 42, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 50, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 48, 2, 0, 0, 50, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 51, 2, 0, 0, 42, 2, 0, 0, 52, 2, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 53, 2, 0, 0, 35, 2, 0, 0, 62, 0, 3, 0, 51, 2, 0, 0, 53, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 54, 2, 0, 0, 42, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 56, 2, 0, 0, 36, 2, 0, 0, 62, 0, -3, 0, 54, 2, 0, 0, 56, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 57, 2, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 58, 2, 0, 0, 42, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 2, 0, 0, 58, 2, 0, 0, 62, 0, -3, 0, 29, 2, 0, 0, 60, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 78, 2, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 79, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 80, 2, 0, 0, 77, 2, 0, 0, 46, 2, -0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 81, 2, 0, 0, 62, 2, 0, 0, 62, 0, 3, 0, 80, 2, 0, 0, 81, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 82, 2, 0, 0, 77, 2, 0, 0, 49, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 83, 2, 0, 0, 65, 2, -0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 83, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 84, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 85, 2, 0, 0, 66, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 85, 2, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 87, 2, 0, 0, 68, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 87, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 88, 2, 0, 0, 77, 2, 0, 0, 89, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 70, 2, 0, 0, 62, 0, 3, 0, 88, 2, 0, 0, 90, 2, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 91, 2, 0, 0, 153, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 92, 2, 0, 0, 77, 2, 0, 0, 59, 2, -0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 93, 2, 0, 0, 92, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 93, 2, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 94, 2, 0, 0, 77, 2, 0, 0, 46, 2, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 95, 2, 0, 0, 94, 2, -0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 95, 2, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 52, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 97, 2, 0, 0, 96, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 97, 2, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 98, 2, 0, 0, 77, 2, 0, 0, 55, 2, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 2, 0, 0, 98, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 100, 2, 0, 0, 77, 2, 0, 0, 89, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 100, 2, 0, 0, 62, 0, 3, 0, 71, 2, 0, 0, 101, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, +0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, +105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 252, 110, 213, 113, 247, 170, 72, 161, 233, 148, 96, 217, 253, 21, 143, 230, 0, 84, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, +3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, 0, 40, 0, +0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 82, 2, +0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, +101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, +47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, +108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, +97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, +47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, +115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, +101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, +0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 40, 2, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, +101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, +116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, +11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, +108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, +0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, 111, 114, 85, +116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 206, 0, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, 95, 70, 117, +110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, +4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, +48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, +5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 106, 1, +0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, +4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 109, 101, 114, +103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, +0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, 114, 110, 97, 114, +121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 234, 1, +0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, 0, 0, 110, 90, +0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, +95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, +0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, 116, 95, 80, 83, +95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, 95, 80, 83, 95, +67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 53, 2, +0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 53, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 54, 2, +0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, +6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, +0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, 0, 0, 115, 116, +114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 61, 2, +0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 74, 2, +0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, 0, 0, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 83, 2, +0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, +0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, 0, 0, 86, 83, +95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 89, 2, +0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, +101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 4, 0, +0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, +0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, +0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, +0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, +4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, +0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 81, 2, +0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, +0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, +0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, +0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, +4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, +0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, +0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, +0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, +4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, +0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, +0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 194, 0, +0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 209, 0, +0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 226, 0, +0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 128, 63, 43, 0, +4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, 184, 60, 43, 0, +4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, 78, 65, 43, 0, +4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, +0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, +0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 52, 2, +0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, +0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 87, 2, +0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, +0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, 0, 0, 5, 0, +0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, 0, 0, 6, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 92, 2, +0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, +0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, +0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, +0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, +0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 230, 0, +0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, 0, 0, 232, 0, +0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, 0, 0, 201, 0, +0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, 0, 238, 0, +0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, 0, 241, 0, +0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 243, 0, +0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 80, 0, +7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 176, 1, +0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, 0, 0, 248, 0, +2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, 0, 0, 62, 0, +3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, 0, 0, 65, 0, +5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 206, 1, +0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, +2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 210, 1, +0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 211, 1, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, 0, 0, 225, 1, +0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, 0, 0, 208, 1, +0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, +0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, 0, 0, 65, 0, +5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 244, 1, +0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 246, 1, +0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 5, 0, +0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, 0, 0, 254, 1, +0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, 5, 0, 5, 0, +0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, 0, 0, 133, 0, +5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, 2, 0, 223, 1, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, 0, 0, 11, 2, +0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 22, 2, +0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, 0, 0, 24, 2, +0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 2, +0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, 0, 0, 57, 2, +0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, 0, 0, 254, 0, +2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, +0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, 3, 0, 63, 2, +0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 69, 2, +0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 73, 2, +0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, 0, 0, 31, 0, +0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, 0, 0, 62, 0, +3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, 4, 0, 30, 0, +0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, 5, 0, 74, 0, +0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, 0, 0, 62, 0, +3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 252, 110, 213, 113, 247, 170, 72, 161, 233, 148, 96, 217, 253, 21, 143, 230, 0, 84, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, +0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, +0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, +0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, +0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, +0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, +0, 182, 0, 0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, +0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, +0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, +97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, +0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, +119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, +111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, +111, 97, 116, 0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, +0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, +95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, +49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, +0, 5, 0, 5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, +0, 106, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, +0, 5, 0, 4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 164, 1, 0, +0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, +109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, 114, +110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, +0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, 0, +0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, 0, +0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, +101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, 116, +95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, +0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, +0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, +0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, +100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, 0, +0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, +0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, +0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, 0, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, +0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, 0, +0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, +0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, +0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, +122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, +0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, +0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, +0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, +0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, 0, +0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, +0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, +0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, +0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, +0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, +0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, +0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, +0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, +0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, +0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, +0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, +0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 128, +63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, 184, +60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, 78, +65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, +0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, +0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, +0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, +0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, 0, +0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, 0, +0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, +0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, +0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, +0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, +0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, +0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, 0, +0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, 0, +0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, +0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, +0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, +0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, +0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, +0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, 0, +0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, 0, +0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, +0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, +0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, +0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, +0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, 0, +0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, 0, +0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, 0, +0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, 3, +0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, 0, +0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, 5, +0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, 2, +0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, 6, +0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, 0, +0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, 0, +0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, +0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, 0, +0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, 0, +0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, 3, +0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, 0, +0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, 5, +0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, 0, +0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs index dfdf4567d6..e4090e38d9 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs @@ -16,54 +16,57 @@ namespace Stride.Graphics public partial class SpriteEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, -111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, -64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, -71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, -101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, -122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, -0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, -102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, -0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, -28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 19, 251, 146, 209, 31, 5, 162, 164, 79, 143, 65, 252, 225, 224, 252, -247, 0, 184, 77, 0, 0, 68, 88, 66, 67, 129, 194, 17, 166, 133, 94, 240, 180, 4, 42, 106, 110, 2, 202, 253, 177, 1, 0, 0, 0, 184, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, 73, 0, 0, 12, 74, 0, 0, 80, 77, 0, 0, 132, 77, -0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, -255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, -115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, -57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 71, 0, 0, 0, 60, 2, 0, 0, 76, 0, 0, 0, 76, 2, 0, 0, 76, 0, 0, 0, 92, 2, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, -171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 28, 1, 0, 0, 5, 0, -0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, -0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 108, 1, 0, 0, 5, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 212, 0, 0, 0, 0, 0, -0, 0, 224, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 4, 1, 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 1, 0, 0, 0, 148, 1, 0, 0, 77, 105, 99, 114, 111, 115, -111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, -15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, 0, 0, 39, 0, 0, 0, 89, 0, 0, 4, 70, 142, -32, 0, 1, 0, 0, 0, 6, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, -0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 142, -32, 0, 1, 0, 0, 0, 5, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, -0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, +112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, +63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 8, 0, 0, 0, 0, 18, 84, +101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, +0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, +10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, +0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, +0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, +68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, +114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, +110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 126, 136, 59, 109, 2, 73, +92, 69, 241, 194, 69, 194, 53, 203, 121, 230, 0, 160, 67, 0, 0, 68, 88, 66, 67, 12, 134, 39, 4, 100, 46, 223, 108, 105, 243, 53, 83, 239, 183, 234, 244, 1, 0, 0, 0, 160, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, 65, 0, 0, 12, +66, 0, 0, 56, 67, 0, 0, 108, 67, 0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, 58, 92, 100, 101, +118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, +64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, 53, 68, 65, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 61, 0, 0, 0, 60, 2, 0, 0, 66, 0, 0, 0, 76, 2, 0, 0, 66, 0, 0, 0, 92, +2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, +83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, +1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, +0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 108, 1, 0, 0, 5, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 196, 0, 0, 0, 1, +0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 4, 1, 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 1, 0, 0, 0, 148, +1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, +8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, 0, 0, 39, +0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, +32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, 0, 0, 0, 70, +14, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, +2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -71,7 +74,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -79,7 +82,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -87,7 +90,7 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -95,215 +98,201 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 152, 234, 110, 94, 183, 179, 219, 72, 183, 85, 123, 159, 38, 144, 9, 75, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 74, 171, 189, 113, 252, 234, 158, 74, 163, 70, 4, 131, 230, 180, 93, 106, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, -52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, 251, 3, 0, 138, 183, 3, 0, 80, 133, 1, 0, 211, 99, -0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 9, 36, 3, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, +49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, +102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, +103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, +115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, 251, 3, 0, 138, +183, 3, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 105, 127, 2, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, -10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, -78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, -85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, -52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, -99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, -52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, -112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, -108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, -109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, -101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, -116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, -95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, -61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, -112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, +49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, +102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, +103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, +116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, +115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, +32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, +110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, +101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 117, 6, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, +115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, +53, 68, 65, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, +111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 50, 53, 100, 97, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 218, 184, 215, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 53, +251, 236, 50, 192, 5, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, +114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, +114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 72, +0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 2, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, +0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, +0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, +0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 34, 0, 77, 17, 136, 0, 0, 0, 12, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 64, 4, 68, 8, 0, 13, 23, 1, 84, 12, 68, 0, 0, 38, 0, 77, 17, 180, 1, 0, 0, 8, +3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 51, 11, 32, 4, 68, 8, 0, 9, 29, 13, 50, 1, 84, 12, 68, 0, 0, 0, 0, 42, 0, 77, 17, 216, 1, 0, 0, 4, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 50, 11, 32, 4, 68, 8, 0, 9, 12, 13, 31, 1, +84, 3, 0, 13, 49, 12, 32, 36, 0, 0, 0, 38, 0, 77, 17, 0, 2, 0, 0, 0, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 84, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, +0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, 0, 0, 0, 1, +0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, +1, 235, 52, 182, 140, 55, 209, 158, 126, 139, 180, 56, 79, 213, 124, 128, 116, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 128, 84, 0, 0, 0, 84, +0, 0, 0, 120, 0, 0, 0, 84, 0, 0, 128, 120, 0, 0, 0, 84, 0, 0, 0, 152, 0, 0, 0, 87, 0, 0, 128, 152, 0, 0, 0, 87, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, +0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, +0, 0, 0, 56, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 148, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, +0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 38, 0, 5, 21, 1, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 2, +16, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, +0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, +0, 1, 0, 3, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, 0, 1, 0, 14, +0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 192, 82, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, +0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 185, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 0, 99, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 102, 97, 100, 50, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, -10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, -78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, -85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 72, 160, 229, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 159, 13, 21, 94, 4, 8, 0, 0, 1, 0, -0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, -41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, -95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 8, 16, 0, 0, 84, 0, -0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 2, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, -116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, -0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 34, 0, 77, 17, 136, 0, 0, 0, 12, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 64, 4, 68, 8, 0, 13, 23, 1, 84, 12, 68, 0, 0, 38, 0, 77, 17, 180, 1, 0, 0, 8, 3, 0, 0, 1, 16, 0, 0, 7, 0, -9, 5, 13, 51, 11, 32, 4, 68, 8, 0, 9, 29, 13, 50, 1, 84, 12, 68, 0, 0, 0, 0, 42, 0, 77, 17, 216, 1, 0, 0, 4, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 50, 11, 32, 4, 68, 8, 0, 9, 12, 13, 31, 1, 84, 3, 0, 13, 49, 12, 32, 36, 0, -0, 0, 38, 0, 77, 17, 0, 2, 0, 0, 0, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 84, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, -83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, -4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 28, 55, 102, 214, 79, 109, 121, 103, -244, 240, 146, 115, 125, 252, 244, 232, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 94, 0, 0, 128, 84, 0, 0, 0, 94, 0, 0, 0, 120, 0, 0, 0, 94, 0, -0, 128, 120, 0, 0, 0, 94, 0, 0, 0, 152, 0, 0, 0, 97, 0, 0, 128, 152, 0, 0, 0, 97, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, -0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 56, 0, 0, 0, 96, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 148, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 84, 0, 0, 0, 84, 0, -0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 0, 243, 242, 241, 38, 0, 5, 21, 1, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 2, 16, 0, 0, 22, 0, 27, 21, 64, 0, -0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 3, 16, 0, 0, 10, 0, -24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, -0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 16, 205, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, -0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, +32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, +97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, +110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, +101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 124, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, +0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, -99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, -52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, -112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, -108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, -109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, -101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, -116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, -95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, -61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, -112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 124, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, -0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, -97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 97, 0, 0, 0, 1, 0, 0, 0, 57, +0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, -0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, -97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 97, 0, 0, 0, 1, 0, 0, 0, 57, 0, 0, 0, 1, 0, 0, 0, 21, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 34, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 0, +0, 255, 255, 255, 255, 255, 255, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 38, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, +0, 81, 17, 20, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, +9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 34, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 80, 0, 255, 255, 255, 255, 255, 255, 71, 108, -111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 38, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 20, 16, 0, 0, 6, 0, -255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, +0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, +0, 9, 0, 20, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, +0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, +115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, 53, 68, 65, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 74, 171, 189, 113, 252, 234, 158, 74, 163, 70, 4, 131, 230, 180, 93, 106, 134, 0, 0, 0, 47, +76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, +115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 50, +53, 100, 97, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 204, 1, 0, 0, 111, 1, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 165, 6, 0, 0, 128, +0, 0, 0, 192, 5, 0, 0, 236, 3, 0, 0, 92, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 11, 0, 0, 0, 6, 0, 0, 0, 17, +0, 0, 0, 18, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 3, 0, 0, 0, 0, -0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, -48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 70, 65, 68, 50, 67, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 152, 234, 110, 94, 183, 179, 219, 72, 183, 85, 123, 159, 38, 144, 9, 75, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, -47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 102, 97, 100, 50, 99, 48, 0, 4, 0, 0, 0, -6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 204, 1, 0, 0, 111, 1, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 233, 8, 0, 0, 128, 0, 0, 0, 4, 8, 0, 0, 236, 3, -0, 0, 92, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, -0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -317,68 +306,42 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 36, 1, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 252, 0, 0, 0, 124, +0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 161, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, +114, 101, 48, 0, 71, 108, 111, 98, 97, 108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 1, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 71, +108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, +114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, +0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 232, 117, 61, 182, 112, 233, 130, 47, 238, 0, +255, 1, 115, 70, 101, 247, 0, 156, 68, 0, 0, 68, 88, 66, 67, 234, 238, 238, 130, 230, 199, 134, 215, 10, 138, 216, 132, 193, 237, 108, 157, 1, 0, 0, 0, 156, 68, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 66, 0, 0, 32, 67, 0, 0, 240, +67, 0, 0, 68, 68, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 68, 0, 0, 0, 200, 2, 0, 0, 68, 0, 0, 0, 216, 2, 0, 0, 68, 0, 0, 0, 232, 2, 0, 0, 68, +0, 0, 0, 248, 2, 0, 0, 80, 0, 0, 0, 8, 3, 0, 0, 80, 0, 0, 0, 28, 3, 0, 0, 82, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, +0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 20, +1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 112, 1, 0, 0, 232, 0, 0, 0, 127, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 144, 1, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, +111, 110, 0, 210, 1, 0, 0, 4, 1, 0, 0, 226, 1, 0, 0, 232, 0, 0, 0, 235, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, 1, 0, 0, 3, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, 1, 0, 255, +255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 36, 1, 0, 0, 4, 0, 0, 0, 52, 1, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 160, 1, 0, 0, 2, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 12, +2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, +0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, +0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 228, +0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 103, +0, 0, 4, 242, 32, 16, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, +0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, +0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, +83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 60, 3, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 20, 3, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 71, 108, 111, 98, 97, -108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 11, 0, 0, 0, 196, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 8, 0, 0, 0, 8, 0, -0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 48, 2, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 76, 2, -0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 104, 2, 0, 0, 40, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 132, 2, 0, 0, 48, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, -0, 0, 0, 0, 0, 0, 160, 2, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 188, 2, 0, 0, 64, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 72, 0, 0, 0, 8, 0, -0, 0, 0, 0, 0, 0, 232, 1, 0, 0, 0, 0, 0, 0, 244, 2, 0, 0, 80, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 1, 0, 3, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, -84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, -115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, -32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, -1, 0, 0, 0, 1, 179, 101, 129, 18, 6, 48, 240, 95, 15, 168, 51, 209, 234, 251, 219, 6, 0, 156, 76, 0, 0, 68, 88, 66, 67, 2, 182, 28, 15, 167, 158, 21, 225, 198, 254, 189, 79, 165, 68, 11, 139, 1, 0, 0, 0, 156, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, -0, 0, 156, 4, 0, 0, 164, 74, 0, 0, 32, 75, 0, 0, 240, 75, 0, 0, 68, 76, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, -48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, -0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 78, 0, 0, 0, 200, 2, 0, 0, 78, 0, -0, 0, 216, 2, 0, 0, 78, 0, 0, 0, 232, 2, 0, 0, 78, 0, 0, 0, 248, 2, 0, 0, 90, 0, 0, 0, 8, 3, 0, 0, 90, 0, 0, 0, 28, 3, 0, 0, 92, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, -0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 20, 1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 112, 1, 0, 0, 232, 0, 0, 0, 127, 1, 0, 0, 4, 1, 0, 0, 5, 0, -0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 210, 1, 0, 0, 4, 1, 0, 0, 226, 1, 0, 0, 232, 0, 0, 0, 235, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, 1, 0, 0, 3, 0, 0, 0, 0, 0, -255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 36, 1, 0, 0, 4, 0, 0, 0, 52, 1, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 160, 1, 0, 0, 2, 0, -0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 12, 2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, -49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, -2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, -3, 224, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 228, 0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, -0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 1, 0, 0, 0, 70, 30, -16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 1, 0, 0, 0, 70, 30, -16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, -99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -386,255 +349,223 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, -0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, -0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, +255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, -49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 198, 226, 161, 7, 188, 94, 11, 79, 175, 235, 198, 193, 0, 120, 144, 250, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, -114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, -114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, -101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, -41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 117, 131, -1, 0, 198, 90, 0, 0, 125, 123, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 118, 42, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, -114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, -114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, -101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, -41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, -55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, -125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, -97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, -116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, -73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, -103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 14, 52, 52, 242, 232, +78, 253, 70, 182, 151, 161, 65, 206, 34, 147, 237, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, -254, 239, 1, 0, 0, 0, 65, 9, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, -66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, -101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 99, 51, 55, 51, 48, 0, 115, 116, -114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, -48, 1, 128, 0, 0, 0, 241, 191, 231, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 218, 110, 132, 136, 140, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, +114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, +116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 117, 131, 1, 0, 198, 90, 0, 0, 125, 123, 1, 0, 8, 104, 0, 0, 38, +247, 2, 0, 118, 42, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, -48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, -97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, -152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, -60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, -0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, -0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 152, 2, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 6, 12, 128, 128, 20, 8, 0, 13, 23, 1, 96, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 68, 2, 0, 0, 148, 2, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, -6, 2, 12, 128, 128, 20, 8, 0, 9, 33, 13, 82, 1, 96, 12, 128, 128, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 80, 9, 255, 202, 160, 101, 211, 131, 82, 235, 207, 84, 203, 121, 74, 200, 0, 0, 242, 0, -0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 228, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 98, 0, 0, 128, 76, 0, 0, 0, 98, 0, 0, 0, 96, 0, 0, 0, 94, 0, 0, 128, 96, 0, 0, 0, 94, 0, 0, 0, 128, 0, -0, 0, 94, 0, 0, 128, 128, 0, 0, 0, 94, 0, 0, 0, 160, 0, 0, 0, 94, 0, 0, 128, 160, 0, 0, 0, 94, 0, 0, 0, 192, 0, 0, 0, 94, 0, 0, 128, 192, 0, 0, 0, 94, 0, 0, 0, 224, 0, 0, 0, 98, 0, 0, 128, 224, 0, 0, 0, 98, 0, 0, 0, 5, 0, -24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, -0, 0, 82, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 77, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, -49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, -0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, -0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, -0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, -1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, +114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, +116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, +116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, +105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, +110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, -55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 53, 41, 59, 10, -125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, -97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, -116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, -73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, -103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, -49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, -0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 253, 6, 0, 0, 0, 67, 58, 92, 100, +101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, +114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, +99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 99, 98, 55, 55, 101, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 143, 5, 219, 37, 88, 187, 220, 1, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, +0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 18, 137, 140, 72, 6, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, -68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, -0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, +0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, +70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 156, +2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, +0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, +0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, +108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, +0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 152, 2, 0, 0, 0, +16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 6, 12, 128, 128, 20, 8, 0, 13, 23, 1, 96, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 68, 2, 0, 0, 148, 2, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 20, 8, 0, 9, 33, 13, 82, 1, 96, 12, +128, 128, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 150, 151, 40, 233, 9, 246, 86, 99, 124, 194, 182, 35, 212, 190, 112, 227, 0, 0, 242, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 228, +0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 88, 0, 0, 128, 76, 0, 0, 0, 88, 0, 0, 0, 96, 0, 0, 0, 84, 0, 0, 128, 96, 0, 0, 0, 84, 0, 0, 0, 128, 0, 0, 0, 84, 0, 0, 128, 128, 0, 0, 0, 84, 0, 0, 0, 160, +0, 0, 0, 84, 0, 0, 128, 160, 0, 0, 0, 84, 0, 0, 0, 192, 0, 0, 0, 84, 0, 0, 128, 192, 0, 0, 0, 84, 0, 0, 0, 224, 0, 0, 0, 88, 0, 0, 128, 224, 0, 0, 0, 88, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, +0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 67, +0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 132, +1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, +0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, +0, 0, 0, 3, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, +0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, +0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, +0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, +59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, +116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, +105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, +110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, +90, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, +0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, +0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, -37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, +0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, -105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, -0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 67, 51, 55, 51, 48, 0, 0, 0, 0, 254, 239, -254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, -49, 1, 185, 180, 142, 105, 1, 0, 0, 0, 198, 226, 161, 7, 188, 94, 11, 79, 175, 235, 198, 193, 0, 120, 144, 250, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, -47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, -98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 99, 51, 55, 51, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, -10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, -0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 113, 9, 0, 0, 128, 0, 0, 0, 140, 8, 0, 0, 160, 3, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, -0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, -0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, +110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, +0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, +0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, +0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, +0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, +83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 14, 52, 52, 242, 232, +78, 253, 70, 182, 151, 161, 65, 206, 34, 147, 237, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, +101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, +114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 99, 98, 55, 55, 101, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, +0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, +1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 45, 7, 0, 0, 128, 0, 0, 0, 72, 6, 0, 0, 160, 3, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 26, +0, 0, 0, 20, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 21, 0, 0, 0, 22, +0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -650,15 +581,15 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, -65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, -0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, -114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, -77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, -105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 12, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, +0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, +0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, +0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, +0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, +79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs index 3bec61cd7b..d261d06a76 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs @@ -16,100 +16,98 @@ namespace Stride.Graphics public partial class SpriteEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, -114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, -97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, -71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, -101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, -122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, -0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, -102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, -0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, -28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 198, 150, 117, 170, 158, 22, 104, 190, 201, 199, 121, 23, 219, 13, 154, -239, 0, 83, 8, 0, 0, 68, 88, 66, 67, 101, 18, 21, 195, 25, 249, 112, 84, 60, 65, 28, 162, 142, 107, 178, 76, 1, 0, 0, 0, 83, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 125, 0, 0, 0, 183, 0, 0, 0, 107, 1, 0, 0, 83, 70, 73, 48, 8, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 49, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, -82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, -48, 172, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 224, 6, 0, 0, 96, 0, 0, 0, 184, 1, 0, -0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 200, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 175, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, -98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, -0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 104, 0, 0, -0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 6, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, -8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, -3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, -0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, -149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, -2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 163, 134, 203, 159, 176, 135, 144, 124, 110, 163, 138, 149, 152, 252, 226, 182, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 8, 10, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 128, 98, -44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, -48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, -7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 84, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 177, 128, 0, 24, 0, 0, 0, 0, 0, -0, 0, 32, 11, 4, 32, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 224, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, -24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 1, 34, 0, 0, 0, 40, 57, 106, 0, 0, 0, 40, 3, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 163, 6, 0, 0, 128, 34, 32, 2, 0, 0, 128, 2, 13, 40, 187, 82, 40, 6, 106, 0, -0, 0, 40, 137, 2, 41, 4, 0, 0, 121, 24, 0, 0, 111, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 4, 81, 0, 19, 4, 67, 97, 68, 85, 134, 71, 87, 39, -151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, -84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 216, 54, -12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 134, 155, 32, 52, 209, 134, 32, 152, 32, 52, 215, 134, 37, 16, 131, 49, 32, 131, 50, 48, -3, 194, 12, 2, 50, 0, 54, 4, 103, 192, 100, 202, 234, 139, 42, 76, 238, 172, 140, 110, 130, 208, 116, 19, 132, 198, 219, 176, 4, 105, 48, 6, 106, 80, 6, 100, 64, 172, 65, 64, 6, 192, 134, 128, 13, 54, 12, 104, 208, 6, 0, 183, 41, 56, 185, 52, 186, 178, 34, 51, 179, 178, 49, 58, -23, 168, 169, 166, 176, 52, 183, 175, 43, 185, 48, 56, 184, 50, 185, 13, 69, 247, 6, 110, 192, 1, 85, 216, 216, 236, 218, 92, 210, 200, 202, 220, 232, 166, 4, 81, 21, 50, 60, 23, 187, 50, 185, 185, 180, 55, 183, 41, 129, 212, 132, 12, 207, 197, 46, 140, 205, 174, 76, 110, 74, 64, 213, 33, -195, 115, 153, 67, 11, 35, 43, 147, 107, 122, 35, 43, 99, 155, 18, 92, 101, 200, 240, 92, 228, 202, 230, 222, 234, 228, 198, 202, 230, 166, 4, 91, 37, 50, 60, 23, 186, 60, 184, 178, 32, 55, 183, 55, 186, 48, 186, 180, 55, 183, 185, 41, 1, 24, 212, 33, 195, 115, 41, 115, 163, 147, 203, 131, -122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, -239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 176, 13, 151, 239, 60, 190, 16, 80, 69, 65, 68, 165, 3, 12, 37, 97, 0, 2, 230, 23, 183, 109, 5, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, -23, 183, 13, 0, 0, 97, 32, 0, 0, 50, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 30, 132, 97, 206, 51, 98, 144, 0, 32, 8, 6, 206, 23, 101, 153, 3, 141, 24, 36, 0, 8, 130, 65, 244, 57, 141, 166, 81, 35, 6, 9, 0, 130, 96, 16, 129, 193, 19, 109, 91, 53, -98, 240, 0, 32, 8, 6, 19, 24, 52, 129, 64, 12, 142, 51, 77, 147, 51, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 144, 0, 32, 8, 6, 145, 25, 84, 81, 24, 128, 193, 86, 98, 16, 65, 5, 27, 142, 24, 28, 0, 8, 130, 65, 117, 6, 210, 16, 140, 38, 4, -192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 24, 67, 72, 192, 24, 66, 2, 198, 16, 18, 48, 134, 144, 192, 136, 65, 2, 128, 32, 24, 88, 111, 160, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 214, 27, 104, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 129, 245, 6, 90, -27, 180, 65, 39, 140, 24, 36, 0, 8, 130, 129, 245, 6, 90, 27, 180, 1, 24, 4, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 155, 20, 167, 12, 233, 81, 79, 86, 205, 130, 34, 164, 247, 63, 64, 1, 0, 175, 8, 0, 0, 68, 88, 66, 67, 168, 48, 106, 90, 28, 212, 221, -191, 233, 113, 183, 216, 17, 215, 210, 235, 1, 0, 0, 0, 175, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 11, 1, 0, 0, 243, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, -0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, -0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 93, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, -80, 83, 86, 48, 224, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 1, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 180, 6, 0, 0, 96, 0, 1, 0, 173, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, -16, 0, 0, 0, 156, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 164, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, -136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, -64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, -96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 49, 0, 0, 0, 0, 238, -0, 23, 39, 0, 22, 9, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, -132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, -135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, -6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, -114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, -0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 0, 58, 0, 0, 0, 152, 1, 32, 2, -0, 0, 128, 2, 14, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, 43, 144, 2, 42, 176, 82, 40, 6, 82, 0, 0, 0, 40, 137, 66, 0, 0, 0, 121, 24, 0, 0, 101, 0, 0, 0, -26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 113, 196, 246, 38, 22, 198, 54, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, -46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 176, 13, 3, 20, 5, 27, -4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 178, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 69, 219, 176, 16, -218, 198, 129, 1, 71, 132, 1, 193, 1, 27, 132, 79, 12, 54, 44, 129, 182, 113, 157, 71, 120, 1, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 133, 40, 131, 205, 12, 186, 48, 32, 194, 128, 224, 128, 13, 2, 25, 156, 193, 134, 97, 12, 208, 0, 224, 54, -5, 39, 151, 70, 87, 86, 100, 102, 86, 54, 70, 231, 98, 53, 213, 20, 150, 230, 246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 212, 32, 13, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, -185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, -192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 212, 0, 113, 32, 0, 0, 24, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, -126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 97, 32, 0, 0, -103, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 26, 84, 85, 206, 51, 98, 144, 0, 32, 8, 6, 203, 22, 89, 150, 3, 141, 24, 36, 0, 8, 130, 193, 194, 73, 214, 5, 69, 35, 6, 9, 0, 130, 96, 176, 116, 211, 133, 65, 210, 136, 65, 2, 128, 32, 24, 44, 30, 133, 101, -208, 52, 98, 144, 0, 32, 8, 6, 203, 87, 101, 26, 68, 141, 24, 36, 0, 8, 130, 193, 243, 65, 210, 182, 61, 197, 93, 56, 98, 112, 0, 32, 8, 6, 17, 24, 64, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 98, 64, 65, 5, 30, 142, 24, 28, 0, 8, 130, -65, 116, 6, 87, 18, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 84, 26, 104, 80, 65, 25, 224, 136, 193, 1, 128, 32, 24, 68, 110, 224, 65, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 193, 1, 24, 64, 5, 108, 128, 35, 6, 7, 0, 130, 96, -16, 213, 65, 25, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 157, 4, 12, 242, 36, 96, 202, 39, 1, 35, 192, 64, 2, 182, 137, 129, 4, 44, 40, 32, 96, 22, 25, 72, 192, 2, 3, 2, 22, 153, 129, 4, 44, 56, 32, 96, 12, 26, 72, 192, 2, 4, 2, -70, 6, 107, 32, 1, 11, 16, 8, 216, 215, 6, 18, 176, 0, 129, 128, 105, 111, 32, 1, 11, 16, 8, 88, 21, 7, 18, 176, 0, 129, 128, 181, 1, 29, 72, 192, 2, 4, 2, 134, 6, 118, 32, 1, 11, 16, 8, 216, 24, 224, 129, 4, 44, 64, 32, 96, 158, 30, 72, 192, 2, 4, 2, 35, -6, 9, 0, 130, 96, 32, 213, 130, 40, 200, 194, 44, 176, 194, 49, 98, 144, 0, 32, 8, 6, 82, 45, 136, 130, 44, 204, 194, 42, 20, 35, 6, 9, 0, 130, 96, 32, 213, 130, 40, 200, 194, 44, 168, 194, 48, 98, 144, 0, 32, 8, 6, 82, 45, 136, 130, 44, 204, 66, 42, 4, 35, 6, 9, -0, 130, 96, 32, 213, 130, 40, 204, 194, 44, 176, 130, 31, 140, 24, 36, 0, 8, 130, 129, 84, 11, 162, 48, 11, 179, 176, 10, 125, 128, 0, 0, 0, 0, 0, 0, 1, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, +112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, +63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, +101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, +0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, +0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, +2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, +0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, +97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, +1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 147, 133, 148, 56, 208, 35, 91, 182, +8, 112, 227, 62, 62, 199, 25, 46, 0, 67, 8, 0, 0, 68, 88, 66, 67, 28, 217, 146, 72, 171, 203, 196, 188, 163, 49, 235, 5, 244, 153, 195, 36, 1, 0, 0, 0, 67, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 125, 0, 0, 0, 183, 0, 0, 0, 107, 1, 0, +0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 49, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, +103, 101, 116, 0, 80, 83, 86, 48, 172, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 208, 6, 0, 0, +96, 0, 0, 0, 180, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 184, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 171, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, +37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, +81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, +137, 32, 0, 0, 104, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 1, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, +0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, +144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, +0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, +39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 163, 134, 203, 159, 176, 135, 144, 124, 110, 163, 138, 149, 152, 252, 226, 182, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 8, 10, 0, 0, 0, 2, 0, 0, 0, 8, 0, +0, 0, 2, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, +122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, +208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 84, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 177, 128, +0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 31, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 16, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, +40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 1, 34, 0, 0, 0, 40, 57, 106, 0, 0, 0, 40, 3, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 163, 6, 0, 0, 128, 34, 32, 2, 0, 0, 128, 178, 43, 133, +98, 160, 6, 0, 0, 128, 146, 40, 144, 66, 0, 0, 121, 24, 0, 0, 109, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 4, 81, 0, 19, 4, 67, 97, 68, 85, 134, +71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, +4, 211, 60, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 208, 54, 12, 214, 21, +108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 102, 155, 32, 52, 209, 134, 32, 152, 32, 52, 215, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, +2, 50, 0, 54, 4, 103, 192, 100, 202, 234, 139, 42, 76, 238, 172, 140, 110, 130, 208, 112, 19, 132, 166, 219, 176, 4, 105, 48, 6, 106, 80, 6, 100, 64, 172, 65, 64, 6, 192, 134, 128, 13, 54, 12, 104, 208, 6, 0, 183, 41, 56, 185, 52, 186, 178, 34, 51, 179, 178, 49, 58, 23, 168, 169, +166, 176, 52, 183, 175, 43, 185, 48, 56, 184, 50, 185, 13, 69, 247, 6, 110, 192, 1, 85, 216, 216, 236, 218, 92, 210, 200, 202, 220, 232, 166, 4, 81, 21, 50, 60, 23, 187, 50, 185, 185, 180, 55, 183, 41, 129, 212, 132, 12, 207, 197, 46, 140, 205, 174, 76, 110, 74, 64, 213, 33, 195, 115, 153, +67, 11, 35, 43, 147, 107, 122, 35, 43, 99, 155, 18, 92, 101, 200, 240, 92, 228, 202, 230, 222, 234, 228, 198, 202, 230, 166, 4, 91, 37, 50, 60, 23, 186, 60, 184, 178, 32, 55, 183, 55, 186, 48, 186, 180, 55, 183, 185, 41, 1, 24, 212, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, +163, 155, 155, 18, 188, 1, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, +192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 176, 13, 151, 239, 60, 190, 16, 80, 69, 65, 68, 165, 3, 12, 37, 97, 0, 2, 230, 23, 183, 109, 5, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 0, +97, 32, 0, 0, 49, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 221, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 142, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 65, 228, 53, 76, 150, 77, 35, 6, 9, 0, 130, 96, 16, 125, 14, 164, 105, 212, 136, 193, 3, 128, 32, 24, +76, 31, 19, 8, 196, 208, 52, 146, 36, 53, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 35, 6, 9, 0, 130, 96, 16, 149, 1, 5, 129, 193, 167, 85, 24, 100, 56, 98, 112, 0, 32, 8, 6, 85, 25, 68, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, +196, 96, 11, 33, 1, 91, 8, 9, 216, 66, 72, 192, 22, 66, 2, 35, 6, 9, 0, 130, 96, 96, 181, 65, 182, 6, 107, 16, 6, 196, 136, 65, 2, 128, 32, 24, 88, 109, 144, 173, 193, 26, 128, 193, 48, 98, 144, 0, 32, 8, 6, 86, 27, 100, 107, 176, 6, 155, 48, 98, 144, 0, 32, 8, +6, 86, 27, 100, 107, 176, 6, 94, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 15, 153, 208, 250, 118, 99, 11, 83, 14, 171, 63, 32, 250, 99, 193, 228, 0, 167, 8, 0, 0, 68, 88, 66, 67, 236, 16, 247, 227, 62, 183, 101, 30, 126, 64, 124, 165, 71, 63, 7, 138, +1, 0, 0, 0, 167, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 11, 1, 0, 0, 243, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, +0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, +84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 93, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 224, 0, 0, 0, 36, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 68, 3, 3, 4, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 172, 6, 0, 0, 96, 0, 1, 0, 171, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 148, 6, 0, 0, 66, +67, 192, 222, 33, 12, 0, 0, 162, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, +41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, +255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, +113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 9, 0, 0, 0, 0, 238, 0, 23, 39, 0, 22, 9, 5, 5, 0, +0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, +0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, +1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, +3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, +7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, +144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, +0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 23, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 41, 132, 25, 0, 82, +0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, 43, 160, 2, 43, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 100, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, +80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 113, 196, 246, 38, 22, 198, 54, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 201, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 166, 198, +69, 198, 197, 6, 4, 229, 44, 141, 174, 133, 198, 198, 236, 230, 70, 108, 70, 6, 230, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 174, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, +109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 176, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 37, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 27, 132, 79, 12, 54, 44, 129, 182, 113, 157, +71, 120, 1, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 133, 40, 131, 205, 12, 186, 48, 32, 194, 128, 224, 128, 13, 2, 25, 156, 193, 134, 97, 12, 208, 0, 224, 54, 5, 39, 151, 70, 87, 86, 100, 102, 86, 54, 70, 231, 98, 53, 213, 20, 150, 230, 246, +117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 212, 32, 13, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, +114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 212, +0, 0, 0, 113, 32, 0, 0, 24, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, +44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 97, 32, 0, 0, 103, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 217, 67, 81, +141, 51, 98, 144, 0, 32, 8, 6, 139, 6, 85, 85, 243, 140, 24, 36, 0, 8, 130, 193, 178, 69, 149, 245, 64, 35, 6, 9, 0, 130, 96, 176, 112, 146, 117, 61, 209, 136, 65, 2, 128, 32, 24, 44, 221, 116, 97, 143, 52, 98, 144, 0, 32, 8, 6, 139, 71, 97, 217, 51, 141, 24, 36, 0, +8, 130, 193, 227, 61, 145, 166, 57, 181, 89, 56, 98, 112, 0, 32, 8, 6, 209, 247, 8, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 133, 65, 7, 21, 116, 56, 98, 112, 0, 32, 8, 6, 145, 25, 88, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, +196, 80, 104, 160, 65, 5, 100, 128, 35, 6, 7, 0, 130, 96, 16, 181, 65, 7, 5, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 245, 6, 96, 0, 21, 172, 1, 142, 24, 28, 0, 8, 130, 65, 68, 7, 100, 112, 5, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, +64, 12, 102, 117, 18, 48, 200, 147, 128, 41, 159, 4, 140, 0, 3, 9, 216, 38, 6, 18, 176, 160, 128, 128, 89, 100, 32, 1, 11, 12, 8, 88, 100, 6, 18, 176, 224, 128, 128, 49, 104, 32, 1, 11, 16, 8, 24, 25, 172, 129, 4, 44, 64, 32, 96, 95, 27, 72, 192, 2, 4, 2, 166, 189, +129, 4, 44, 64, 32, 96, 85, 28, 72, 192, 2, 4, 2, 214, 6, 116, 32, 1, 11, 16, 8, 24, 26, 216, 129, 4, 44, 64, 32, 96, 99, 128, 7, 18, 176, 0, 129, 128, 121, 122, 32, 1, 11, 16, 8, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 176, 10, 199, 136, 65, 2, +128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 170, 80, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 144, 10, 195, 136, 65, 2, 128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 168, 16, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 32, 11, 178, 176, 10, 126, 48, 98, 144, 0, 32, +8, 6, 18, 45, 136, 130, 44, 200, 130, 42, 244, 1, 2, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index 85f0a00eae..1b39f92fe3 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -16,191 +16,201 @@ namespace Stride.Graphics public partial class SpriteEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, -114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, -97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, -71, 108, 111, 98, 97, 108, 115, 96, 0, 0, 0, 1, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, -101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, -122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, -0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, -102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 80, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, -0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, -28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 178, 39, 67, 162, 90, 62, 172, 105, 181, 17, 250, 4, 227, 29, -206, 0, 208, 19, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 205, 0, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 204, 0, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 239, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 225, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 0, -0, 0, 218, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 111, 0, 0, 0, 239, 0, 0, 0, 16, 0, 3, 0, 205, 0, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, -0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, -0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, -0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, -116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, -112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, -97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, -4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, -105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 179, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, -0, 0, 5, 0, 7, 0, 180, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 197, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, -95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 199, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, -0, 0, 5, 0, 6, 0, 198, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 200, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 200, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, -114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 201, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 201, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 202, 0, 0, 0, 80, 83, 95, 83, 84, 82, -69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 202, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 202, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 203, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 205, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, -83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 208, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, -0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 219, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 218, 0, 0, 0, 105, 110, -95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, -0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 0, 6, 0, 6, 0, 221, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 222, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 223, 0, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 225, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, -99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 230, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 237, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 237, 0, -0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, -0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, -0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, -0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, -0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, -0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, -101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 238, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, -108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 49, 48, 0, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 196, 0, 0, 0, 30, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 198, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 198, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 0, -0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 0, 0, 0, 3, 22, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 237, 0, 0, 0, 2, 0, 0, 0, 72, 0, -5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 0, 0, -0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 3, 0, 0, 0, 35, 0, -0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, -0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, -5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 34, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, -2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, -0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, -4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, -4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, -0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 180, 0, 0, 0, 2, 0, 0, 0, 3, 0, -0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 197, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 199, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, 0, 200, 0, 0, 0, 38, 0, 0, 0, 30, 0, -3, 0, 201, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 202, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 6, 0, 0, 0, 202, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, -0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 219, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 220, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 221, 0, -0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 222, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 6, 0, 0, 0, 222, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 0, 0, 0, 2, 0, 0, 0, 30, 0, -13, 0, 237, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 238, 0, 0, 0, 2, 0, 0, 0, 237, 0, -0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 241, 0, 0, 0, 10, 0, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, -0, 0, 59, 0, 4, 0, 238, 0, 0, 0, 239, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 196, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 204, 0, 0, 0, 6, 0, -0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 214, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 215, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 0, 0, 0, 216, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 219, 0, 0, 0, 218, 0, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 224, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 212, 0, -0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, -0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, -0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 204, 0, -0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, -0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 190, 0, 0, 0, 57, 0, 4, 0, 3, 0, -0, 0, 193, 0, 0, 0, 114, 0, 0, 0, 65, 0, 5, 0, 180, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 195, 0, 0, 0, 193, 0, 0, 0, 194, 0, -0, 0, 254, 0, 2, 0, 195, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 206, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 207, 0, 0, 0, 204, 0, 0, 0, 208, 0, 0, 0, 61, 0, -4, 0, 38, 0, 0, 0, 209, 0, 0, 0, 198, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 209, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 210, 0, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 211, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 196, 0, 0, 0, 213, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 65, 0, -5, 0, 70, 0, 0, 0, 227, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 229, 0, 0, 0, 224, 0, 0, 0, 230, 0, -0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 231, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 231, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 232, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 233, 0, 0, 0, 224, 0, 0, 0, 212, 0, -0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 234, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 235, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 236, 0, 0, 0, 235, 0, -0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 236, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 216, 178, 39, 67, 162, 90, 62, 172, 105, 181, 17, 250, 4, 227, 29, 206, -0, 208, 19, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 205, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 204, 0, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 239, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 225, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 0, 0, -0, 218, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 111, 0, 0, 0, 239, 0, 0, 0, 16, 0, 3, 0, 205, 0, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, -0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, -0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, -101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, -105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, -0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 179, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, -0, 5, 0, 7, 0, 180, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 197, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, -102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 199, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, -0, 5, 0, 6, 0, 198, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 200, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 200, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 5, 0, 5, 0, 201, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 201, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 202, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 6, 0, 6, 0, 202, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 202, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 203, 0, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 205, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, -77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 208, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, -0, 5, 0, 6, 0, 216, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 219, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 218, 0, 0, 0, 105, 110, 95, -86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 0, 0, -0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -0, 6, 0, 6, 0, 221, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 222, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 223, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 225, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, -116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 230, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 237, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, -0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, -0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, -0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, -0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, -0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, -0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, -51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, -53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, -55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 237, 0, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, -57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 5, 0, 237, 0, 0, 0, 10, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 238, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, -115, 0, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 49, 48, 0, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 196, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 198, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 198, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 0, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 237, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, -0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 0, 0, 0, -0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, -0, 24, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, -0, 72, 0, 5, 0, 237, 0, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 237, 0, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, -0, 237, 0, 0, 0, 10, 0, 0, 0, 35, 0, 0, 0, 80, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 239, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 239, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, -0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, -0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, -0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, -0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 180, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, -0, 43, 0, 4, 0, 4, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 197, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 199, 0, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, 0, 200, 0, 0, 0, 38, 0, 0, 0, 30, 0, 3, -0, 201, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 202, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 6, 0, 0, 0, 202, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 208, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, -0, 212, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 219, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 220, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 221, 0, 0, -0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 222, 0, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 6, 0, 0, 0, 222, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 230, 0, 0, 0, 2, 0, 0, 0, 30, 0, 13, -0, 237, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 238, 0, 0, 0, 2, 0, 0, 0, 237, 0, 0, -0, 43, 0, 4, 0, 133, 0, 0, 0, 241, 0, 0, 0, 10, 0, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, -0, 59, 0, 4, 0, 238, 0, 0, 0, 239, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 197, 0, 0, 0, 196, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 198, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 204, 0, 0, 0, 6, 0, 0, -0, 59, 0, 4, 0, 197, 0, 0, 0, 214, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 199, 0, 0, 0, 215, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 0, 0, 0, 216, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 219, 0, 0, 0, 218, 0, 0, 0, 1, 0, 0, -0, 59, 0, 4, 0, 223, 0, 0, 0, 224, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 212, 0, 0, -0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, -0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, -0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 204, 0, 0, -0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, -0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 190, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, -0, 193, 0, 0, 0, 114, 0, 0, 0, 65, 0, 5, 0, 180, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 194, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 195, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, -0, 254, 0, 2, 0, 195, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 205, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 206, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 207, 0, 0, 0, 204, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, -0, 38, 0, 0, 0, 209, 0, 0, 0, 198, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 209, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 210, 0, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 211, 0, 0, 0, 204, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, -0, 3, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 196, 0, 0, 0, 213, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 65, 0, 5, -0, 70, 0, 0, 0, 227, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 228, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 229, 0, 0, 0, 224, 0, 0, 0, 230, 0, 0, -0, 61, 0, 4, 0, 3, 0, 0, 0, 231, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 231, 0, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 232, 0, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 233, 0, 0, 0, 224, 0, 0, 0, 212, 0, 0, -0, 61, 0, 4, 0, 3, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 234, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 235, 0, 0, 0, 224, 0, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, -0, 62, 0, 3, 0, 216, 0, 0, 0, 236, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, +112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, +63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 3, +0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, +101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, +0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, +2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, +0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, +2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, +0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, +97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, +1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 232, 235, 99, 87, 159, 250, 240, 73, +55, 165, 190, 209, 145, 166, 215, 143, 0, 68, 21, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, +101, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 216, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 209, 0, 0, 0, 207, 0, 0, 0, 215, 0, 0, 0, 192, 0, 0, 0, 40, 0, 0, +0, 87, 0, 0, 0, 250, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 236, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 226, 0, 0, 0, 229, 0, 0, 0, 225, 0, 0, 0, 227, 0, 0, 0, 235, 0, 0, 0, 116, 0, 0, 0, 250, 0, 0, +0, 16, 0, 3, 0, 216, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, +0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, +108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 203, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, +100, 115, 108, 0, 0, 7, 0, 20, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, +97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, +0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, +83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, +0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 188, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, +116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 193, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 208, 0, 0, +0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 210, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 209, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 211, 0, 0, +0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, +0, 213, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 213, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 5, 0, 8, 0, 214, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 216, 0, 0, 0, 83, 112, 114, +105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 225, 0, 0, +0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 226, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 227, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 230, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, +0, 5, 0, 6, 0, 229, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 231, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 233, 0, 0, +0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 233, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 0, 0, 5, 0, 8, 0, 234, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 235, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 236, 0, 0, +0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 248, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, +115, 0, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 249, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 250, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, +0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, +116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 207, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 209, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 209, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 225, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 226, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 229, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 229, 0, 0, +0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 248, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, +0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, +0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, +0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, +0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, +0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, +0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, +0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, +0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, +0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 194, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, +0, 193, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 210, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 211, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, +0, 213, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 214, 0, 0, 0, 6, 0, 0, 0, 213, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 228, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 230, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 231, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, +0, 233, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 234, 0, 0, 0, 6, 0, 0, 0, 233, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 241, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 248, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, +0, 249, 0, 0, 0, 2, 0, 0, 0, 248, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, +0, 249, 0, 0, 0, 250, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 207, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 214, 0, 0, 0, 215, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, +0, 208, 0, 0, 0, 225, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 226, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 227, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 230, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 234, 0, 0, 0, 235, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 135, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, +0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 188, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, +0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 197, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, +0, 119, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 251, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, +0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 217, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 218, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 220, 0, 0, 0, 209, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 220, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 221, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 222, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 224, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 224, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 237, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, +0, 238, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 239, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 239, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 240, 0, 0, 0, 242, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 243, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 244, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 245, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 246, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, +0, 227, 0, 0, 0, 247, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 232, 235, 99, 87, 159, 250, 240, 73, 55, 165, 190, 209, 145, 166, 215, 143, 0, 68, 21, 0, 0, +3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, +1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 216, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 209, 0, 0, 0, 207, 0, 0, 0, 215, 0, 0, 0, 192, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 250, 0, 0, 0, 15, 0, 14, 0, +0, 0, 0, 0, 236, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 226, 0, 0, 0, 229, 0, 0, 0, 225, 0, 0, 0, 227, 0, 0, 0, 235, 0, 0, 0, 116, 0, 0, 0, 250, 0, 0, 0, 16, 0, 3, 0, 216, 0, 0, 0, 7, 0, 0, 0, +7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, +0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, +100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 203, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 204, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, +115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, +46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, +110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, +116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 188, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, +5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 193, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, +108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 210, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, +5, 0, 6, 0, 209, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 211, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, +77, 83, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 213, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 216, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 225, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 226, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, +5, 0, 6, 0, 227, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 230, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 229, 0, 0, 0, 105, 110, 95, 86, +83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 231, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, +1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 233, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 234, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 235, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 236, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, +46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 248, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, +0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 249, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, +0, 0, 0, 0, 5, 0, 4, 0, 250, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, +116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, +2, 0, 0, 0, 71, 0, 4, 0, 207, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 209, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 209, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, +225, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 226, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 229, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 229, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, +0, 0, 0, 0, 71, 0, 3, 0, 248, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, +7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, +250, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, +6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, +5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, +0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, +113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, +189, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 194, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, +3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 210, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 211, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 213, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, +32, 0, 4, 0, 214, 0, 0, 0, 6, 0, 0, 0, 213, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, +32, 0, 4, 0, 230, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 231, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 233, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 234, 0, 0, 0, 6, 0, 0, 0, 233, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 241, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 248, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 249, 0, 0, 0, 2, 0, 0, 0, 248, 0, 0, 0, +59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 249, 0, 0, 0, 250, 0, 0, 0, 2, 0, 0, 0, +59, 0, 4, 0, 208, 0, 0, 0, 207, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 214, 0, 0, 0, 215, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 225, 0, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 210, 0, 0, 0, 226, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 227, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 230, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 234, 0, 0, 0, 235, 0, 0, 0, 6, 0, 0, 0, +54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 235, 0, 0, 0, +241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, +142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 149, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 188, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, +0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, +172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, +254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 197, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, +251, 0, 0, 0, 250, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 251, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, +30, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 217, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 218, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 220, 0, 0, 0, 209, 0, 0, 0, 62, 0, 3, 0, +218, 0, 0, 0, 220, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 221, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 222, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 224, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, +207, 0, 0, 0, 224, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 237, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 238, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 239, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 239, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, +62, 0, 3, 0, 240, 0, 0, 0, 242, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 243, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 244, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, +62, 0, 3, 0, 225, 0, 0, 0, 245, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 246, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 247, 0, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs index 0490cba4f2..a19d232f82 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs @@ -16,40 +16,48 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, -0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, -120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, -1, 157, 169, 222, 211, 157, 227, 183, 129, 47, 12, 215, 103, 164, 27, 71, 160, 0, 76, 76, 0, 0, 68, 88, 66, 67, 202, 185, 245, 184, 166, 29, 241, 92, 53, 186, 50, 135, 98, 216, 123, 59, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, -0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, 76, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, -0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, -105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, -48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 84, 0, 0, 0, 212, 2, 0, 0, 86, 0, 0, 0, 228, 2, 0, 0, 93, 0, -0, 0, 244, 2, 0, 0, 95, 0, 0, 0, 8, 3, 0, 0, 95, 0, 0, 0, 24, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, -0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 49, 55, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, -83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, 1, 0, 0, 12, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 64, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, -171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, -67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 156, 1, 0, 0, 172, 1, 0, 0, 12, 1, 0, 0, 184, 1, 0, 0, 200, 1, 0, 0, 5, 0, -0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, -0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 40, 1, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 116, 1, 0, 0, 40, 1, 0, 0, 128, 1, 0, 0, 240, 1, -0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, -0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, -255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, -16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, -16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, -16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, -16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, -0, 0, 35, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, +0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, +90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 132, 19, 121, 167, 249, 219, 0, 200, 135, 138, 10, 186, 134, 37, 106, 0, 0, 76, +76, 0, 0, 68, 88, 66, 67, 176, 53, 22, 232, 65, 34, 46, 61, 237, 16, 218, 78, 85, 126, 100, 8, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, 0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, 76, 0, 0, 65, +111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, +2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, 54, 66, 48, 0, 171, 171, 171, 40, +0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 70, 0, 0, 0, 212, 2, 0, 0, 72, 0, 0, 0, 228, 2, 0, 0, 79, 0, 0, 0, 244, 2, 0, 0, 81, 0, 0, 0, 8, 3, 0, 0, 81, 0, 0, 0, 24, +3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, +52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, 1, 0, 0, 12, +1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 64, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, +0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 156, 1, 0, 0, 172, 1, 0, 0, 12, 1, 0, 0, 184, 1, 0, 0, 200, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 40, +1, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 116, 1, 0, 0, 40, 1, 0, 0, 128, 1, 0, 0, 240, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, +32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, +8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, +0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, +85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, +0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, +0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, +80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -57,7 +65,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -65,7 +73,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -73,7 +81,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -81,280 +89,280 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 130, 106, 175, 65, 189, 22, 7, 71, 169, 90, 99, 76, 192, 226, 98, 206, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 156, 99, 6, 68, 59, 240, 200, 69, 146, 131, 182, 227, 96, 235, 238, 102, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, +81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, -49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, -1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 6, 212, 2, 0, 149, 49, 3, 0, 125, 218, 1, 0, 16, 77, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 142, +5, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, -59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, -98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, -49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, -120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, -99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, -112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, -105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, -10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, -101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, -111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, -85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, -101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, -80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, -101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, -97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, +116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, +95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, +101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, +105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, +125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, +102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, +125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, +105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, +110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 41, 11, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, -0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, -115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 102, 50, 51, 48, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, -59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 194, 222, 244, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 22, 1, 88, 250, 116, 10, -0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 192, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, 54, 66, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, +98, 97, 56, 54, 98, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 143, 5, 217, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 62, 245, 67, 219, 11, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, -116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, -112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, -0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, -0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, -32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, -132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 34, 6, 8, 12, 128, 128, 0, 8, 0, 13, 33, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, -9, 5, 13, 59, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 58, 1, 92, 12, 128, 128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, -36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, -0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, -0, 0, 8, 0, 95, 52, 49, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, -0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 167, 105, 80, 131, 81, 219, 190, 226, 110, 156, 131, 210, 74, 33, 25, 216, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, -0, 0, 117, 0, 0, 128, 92, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 128, 120, 0, 0, 0, 117, 0, 0, 0, 156, 0, 0, 0, 117, 0, 0, 128, 156, 0, 0, 0, 117, 0, 0, 0, 192, 0, 0, 0, 117, 0, 0, 128, 192, 0, 0, 0, 117, 0, 0, 0, 220, 0, -0, 0, 120, 0, 0, 128, 220, 0, 0, 0, 120, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, -0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, +111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, +115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, +16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, +0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, +0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, +0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, +16, 0, 0, 7, 0, 9, 5, 13, 34, 6, 8, 12, 128, 128, 0, 8, 0, 13, 33, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 59, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 58, 1, 92, 12, 128, +128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, +3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, +0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, +0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 209, 220, 250, 101, 106, 67, 151, +55, 132, 146, 64, 71, 126, 136, 126, 22, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, 0, 0, 0, 103, +0, 0, 128, 120, 0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, 0, 16, 0, 5, +0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, +0, 0, 0, 85, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, -0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, -242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, -0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, -0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, -8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, -0, 0, 3, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, -24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 170, 243, 1, 0, 72, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, +0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, +0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, +0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, +243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, +16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, +0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 170, 243, 1, 0, 72, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, -120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, -99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, -112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, -105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, -10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, -101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, -111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, -85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, -101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, -80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, -101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, -97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 108, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, -0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, +116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, +95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, +83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, +101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, +105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, +125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, +102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, +125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, +105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, +110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, -0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, +0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 108, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, +0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, +0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, +0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, +0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, -255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, +48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, -0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, -92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, -100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 70, 50, 51, 48, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 130, 106, 175, 65, 189, 22, 7, 71, 169, 90, 99, 76, 192, 226, 98, 206, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, -110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 102, 50, 51, 48, 56, 0, -4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, +255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, +54, 66, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 89, 11, 0, 0, 128, 0, 0, 0, 116, 10, -0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, 0, -0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, -0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 156, 99, 6, 68, 59, 240, 200, 69, 146, 131, 182, 227, 96, 235, 238, 102, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, +100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, +92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 97, 56, 54, 98, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, +0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 240, 8, 0, 0, 128, 0, 0, 0, 11, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, +2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, +0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, -105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, -114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 189, 216, 4, 4, 9, 10, 95, 53, 20, 49, 237, 127, 37, 201, 233, 45, 0, 76, 84, 0, 0, 68, 88, -66, 67, 126, 152, 11, 173, 26, 190, 123, 51, 53, 207, 60, 121, 110, 166, 76, 229, 1, 0, 0, 0, 76, 84, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 82, 0, 0, 224, 82, 0, 0, 44, 83, 0, 0, 196, 83, 0, 0, 65, 111, 110, 57, 80, 3, -0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, -0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 55, 48, 56, 56, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, -255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 117, 0, 0, 0, 224, 2, 0, 0, 119, 0, 0, 0, 244, 2, 0, 0, 119, 0, 0, 0, 0, 3, 0, 0, 121, 0, 0, 0, 12, 3, 0, 0, 117, 0, -0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, -3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, -0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 68, 1, 0, 0, 4, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 5, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 8, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 188, 1, 0, 0, 232, 0, 0, 0, 203, 1, 0, 0, 8, 1, 0, 0, 218, 1, 0, 0, 8, 1, -0, 0, 230, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, -0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 5, 0, 0, 0, 116, 1, 0, 0, 208, 0, 0, 0, 176, 1, 0, 0, 20, 2, 0, 0, 4, 0, 0, 0, 36, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, -72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, -0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, -228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, -16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, -0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, -0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, -0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, +0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, +0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 135, 221, 54, 159, 230, 55, 150, 185, 146, 186, 63, 39, 241, 96, 42, 12, 0, 76, 76, 0, 0, 68, 88, 66, 67, 234, 178, 68, 251, 216, 50, 142, 58, 243, 21, 245, 44, 111, 103, 12, 48, 1, +0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 74, 0, 0, 224, 74, 0, 0, 44, 75, 0, 0, 196, 75, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, +0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 2, +0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, +66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, +2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 102, 0, 0, 0, 224, 2, 0, 0, 104, 0, 0, 0, 244, 2, 0, 0, 104, 0, 0, 0, 0, 3, 0, 0, 106, 0, 0, 0, 12, 3, 0, 0, 102, 0, 0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, +83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, +1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 68, 1, 0, 0, 4, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 5, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 7, 0, 0, 0, 2, +0, 3, 0, 4, 0, 5, 0, 8, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 188, 1, 0, 0, 232, 0, 0, 0, 203, 1, 0, 0, 8, 1, 0, 0, 218, 1, 0, 0, 8, 1, 0, 0, 230, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, +0, 4, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 100, +1, 0, 0, 5, 0, 0, 0, 116, 1, 0, 0, 208, 0, 0, 0, 176, 1, 0, 0, 20, 2, 0, 0, 4, 0, 0, 0, 36, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, +114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, +0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, +72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, +0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, +16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, +0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, +0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -362,7 +370,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -370,211 +378,184 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 219, 11, 160, 241, 120, 159, 145, 64, 163, 147, 96, 41, 93, 101, 168, 9, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 11, 82, 101, 68, 46, 124, 64, 75, 161, 217, 238, 229, 178, 163, 235, 11, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, -3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, +122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, -85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, -105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, -97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, -46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, -111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, -95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, -97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, -56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, -55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, -97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, -32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, -118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, -32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, -61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, +83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, +122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, +117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, +82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, +51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, +50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, +125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, +116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, +116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 167, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, +48, 48, 48, 49, 101, 97, 51, 48, 101, 99, 97, 49, 48, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, +83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 134, 191, 219, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 183, 74, 243, 36, 242, 9, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 17, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, -53, 55, 48, 56, 56, 69, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, -116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 55, 48, 56, 56, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, -85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, -105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 1, 29, 248, 136, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, -48, 1, 166, 181, 185, 5, 92, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, +83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, +108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 8, 16, 0, 0, 108, 0, 0, 0, 1, 0, 160, 109, 97, +105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, +0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, +0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, +0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, +0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, 0, 0, 0, 58, +0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, +0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 108, +0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, +0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, +0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 133, 244, 175, 170, 177, 52, 113, 157, 86, 176, 18, 112, 12, 19, 68, 215, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 10, +0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 114, 0, 0, 128, 108, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 114, 0, 0, 128, 128, 0, 0, 0, 114, 0, 0, 0, 148, 0, 0, 0, 114, 0, 0, 128, 148, 0, 0, 0, 114, 0, 0, 0, 168, 0, 0, 0, 114, 0, 0, 128, 168, +0, 0, 0, 114, 0, 0, 0, 188, 0, 0, 0, 114, 0, 0, 128, 188, 0, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, +0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, -77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, -108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, -0, 0, 84, 0, 0, 0, 8, 16, 0, 0, 108, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, -0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, -84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, -4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 148, 126, 56, 207, 51, 152, 48, 72, 119, 243, 162, 56, 200, 164, 98, 39, 0, 0, 242, 0, 0, 0, 144, 0, -0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 129, 0, 0, 128, 108, 0, 0, 0, 129, 0, 0, 0, 128, 0, 0, 0, 129, 0, 0, 128, 128, 0, 0, 0, 129, 0, 0, 0, 148, 0, 0, 0, 129, 0, -0, 128, 148, 0, 0, 0, 129, 0, 0, 0, 168, 0, 0, 0, 129, 0, 0, 128, 168, 0, 0, 0, 129, 0, 0, 0, 188, 0, 0, 0, 129, 0, 0, 128, 188, 0, 0, 0, 129, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, -24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, +0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, +16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, +0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, +0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, +16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, -102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, -3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, -242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, -97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, -46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, -111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, -95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, -97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, -56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, -55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, -97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, -32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, -118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, -32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, -61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, -0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, +117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, +82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, +51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, +50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, +125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, +97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, +116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, +116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, +10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -586,55 +567,50 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, -0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 9, 0, 56, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, -0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 55, 48, 56, 56, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 219, 11, 160, 241, 120, 159, 145, 64, 163, 147, 96, 41, 93, 101, 168, 9, 134, 0, -0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, -53, 55, 48, 56, 56, 101, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, -220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 65, 13, -0, 0, 128, 0, 0, 0, 92, 12, 0, 0, 4, 4, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 20, 0, 0, 0, 32, 0, 0, 0, 21, 0, 0, 0, 15, 0, 0, 0, 6, 0, -0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, -0, 0, 7, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 31, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, +0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 56, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, +0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, +92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, +49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 11, 82, 101, 68, 46, 124, 64, 75, 161, 217, 238, 229, 178, 163, 235, 11, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, +47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, +103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 101, 99, 97, 49, 48, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, +0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 215, 10, 0, 0, 128, 0, 0, 0, 242, 9, 0, 0, 4, 4, 0, 0, 44, 0, 0, 0, 0, +0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 14, +0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -658,15 +634,14 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, -0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, -0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, -0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, -115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, +76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, +0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, +0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs index 4ea052e473..1506a4d722 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs @@ -16,99 +16,87 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, -93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, -24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 189, 77, 21, 155, 216, 171, 235, 220, 33, 193, 255, 51, 72, 41, 141, 73, 0, 1, 9, 0, 0, 68, -88, 66, 67, 67, 204, 72, 195, 110, 94, 19, 63, 70, 215, 205, 102, 206, 115, 208, 221, 1, 0, 0, 0, 1, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 9, 1, 0, 0, 21, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, -95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, -3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 228, 6, 0, 0, 96, 0, 0, 0, 185, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 204, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 176, 1, 0, 0, -11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, -196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, -255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 91, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, -72, 160, 144, 145, 129, 144, 64, 49, 65, 112, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, -0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, -0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, -3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, -0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, -52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, -109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, -96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, -16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 30, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, -1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, -2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 35, 0, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 133, 98, 160, 6, 0, 0, 128, 146, 40, 132, 2, 1, 121, 24, 0, 0, 124, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, -99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 35, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 10, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, -186, 58, 185, 50, 152, 9, 2, 177, 76, 16, 20, 102, 130, 64, 52, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, -152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 225, 108, 16, 8, 138, 2, 220, 220, 4, 129, 200, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 10, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, -67, 79, 79, 82, 68, 19, 132, 70, 155, 32, 52, 208, 134, 32, 152, 32, 52, 210, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, 2, 50, 0, 54, 4, 196, 4, 161, 217, 54, 44, 132, 24, 140, 1, 25, 160, 129, 25, 16, 105, 64, 144, 1, 176, 33, 96, 38, 8, 77, 180, 97, 97, 196, -96, 12, 200, 96, 13, 204, 128, 96, 3, 134, 12, 128, 13, 195, 25, 168, 65, 27, 48, 153, 178, 250, 162, 10, 147, 59, 43, 163, 155, 32, 52, 220, 134, 37, 120, 131, 49, 128, 131, 50, 32, 3, 34, 13, 2, 50, 0, 54, 4, 113, 176, 97, 112, 3, 57, 0, 72, 6, 85, 73, 69, 102, 102, 101, -99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 142, 14, 230, 128, 3, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 162, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, -169, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 128, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 184, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 182, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, -110, 115, 83, 2, 48, 168, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 160, 3, 0, 0, 0, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 65, 167, 205, 112, 218, 253, -189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, -82, 211, 67, 77, 126, 113, 219, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 220, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 78, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 129, 227, 69, 88, 246, 64, 35, 6, 9, 0, 130, 96, 224, 124, 82, 166, -61, 209, 136, 65, 2, 128, 32, 24, 56, 96, 48, 105, 219, 35, 141, 24, 36, 0, 8, 130, 129, 19, 6, 212, 198, 61, 211, 136, 65, 2, 128, 32, 24, 56, 98, 80, 97, 221, 68, 141, 24, 36, 0, 8, 130, 65, 36, 6, 80, 228, 121, 216, 136, 65, 2, 128, 32, 24, 68, 99, 16, 85, 223, 151, -141, 24, 60, 0, 8, 130, 193, 52, 6, 80, 32, 36, 72, 20, 93, 215, 21, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 12, 55, 32, 84, 48, 221, 64, 20, 193, 116, 3, 97, 8, 211, 13, 196, 49, 24, 2, 73, 192, 8, 72, 2, 70, 64, 18, 48, 2, 146, 192, 136, 65, -2, 128, 32, 24, 80, 111, 176, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 212, 27, 108, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 1, 245, 6, 91, 27, 180, 65, 24, 8, 35, 6, 9, 0, 130, 96, 64, 189, 193, 214, 6, 109, 0, 6, 1, 2, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 1, 59, 75, 78, 219, 93, 253, 16, 21, 103, 178, 237, 164, 19, 53, 47, 154, 0, 151, 8, 0, 0, 68, 88, 66, 67, 200, 4, 86, 72, 77, 165, 5, 2, 24, 188, 255, 202, 137, 38, 9, 225, 1, 0, 0, 0, 151, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, -68, 0, 0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 19, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, -86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 92, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 16, -0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, -0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, -0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 124, 5, 0, 0, 96, 0, 1, 0, 95, 1, 0, 0, 68, -88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 100, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 86, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, -64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, -140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, -113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, -8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, -104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, -160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, -7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 17, 0, 0, 0, 50, 30, 152, 20, 25, -17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, -24, 0, 0, 114, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, 54, 32, 129, 48, 4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, -152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, 133, 130, 221, 220, 4, 129, 128, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, -54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 35, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 164, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, -186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 225, 108, 8, 196, 96, 130, 112, 40, 27, 22, 49, 176, 46, 108, 12, 48, 130, 12, 196, 0, 3, 54, 16, 155, 23, 6, 101, 176, 97, 9, 172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, -52, 130, 12, 62, 12, 224, 50, 101, 245, 5, 245, 54, 151, 70, 151, 246, 230, 54, 65, 56, 152, 13, 139, 24, 168, 193, 181, 6, 89, 71, 116, 98, 128, 1, 27, 136, 51, 64, 131, 52, 96, 131, 13, 131, 25, 180, 1, 64, 50, 168, 74, 42, 50, 51, 43, 27, 163, 155, 66, 11, 35, 43, 147, 227, -49, 11, 99, 155, 43, 243, 113, 177, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 68, 111, 224, 6, 16, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 112, 84, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 32, 77, 200, 240, 92, 236, 194, 216, 236, -202, 228, 166, 4, 74, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 65, 83, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 240, 84, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 80, 117, 200, 240, 92, -202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 111, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 89, 167, 205, 112, 218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, -47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 66, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 18, 243, 60, 202, 50, 98, 144, 0, 32, 8, 6, 200, 212, 64, 144, -194, 140, 24, 36, 0, 8, 130, 1, 66, 57, 80, 196, 52, 35, 6, 9, 0, 130, 96, 128, 84, 79, 36, 49, 206, 136, 65, 2, 128, 32, 24, 32, 22, 36, 77, 204, 51, 98, 144, 0, 32, 8, 6, 200, 21, 77, 20, 3, 141, 24, 36, 0, 8, 130, 1, 130, 73, 76, 5, 69, 35, 6, 9, 0, -130, 96, 128, 100, 83, 99, 65, 210, 136, 65, 2, 128, 32, 24, 32, 26, 229, 92, 208, 52, 98, 144, 0, 32, 8, 6, 200, 86, 61, 24, 68, 141, 24, 36, 0, 8, 130, 1, 194, 89, 79, 70, 85, 35, 6, 9, 0, 130, 96, 144, 112, 15, 164, 85, 201, 136, 65, 2, 128, 32, 24, 36, 220, 3, -105, 20, 50, 98, 144, 0, 32, 8, 6, 9, 247, 64, 218, 116, 140, 24, 36, 0, 8, 130, 65, 194, 61, 144, 38, 25, 35, 6, 9, 0, 130, 96, 144, 112, 143, 166, 85, 203, 136, 65, 2, 128, 32, 24, 36, 220, 163, 105, 148, 50, 98, 144, 0, 32, 8, 6, 9, 247, 100, 90, 85, 140, 24, 36, -0, 8, 130, 65, 194, 61, 153, 70, 17, 35, 6, 9, 0, 130, 96, 144, 112, 79, 166, 77, 195, 136, 65, 2, 128, 32, 24, 36, 220, 147, 105, 146, 48, 98, 144, 0, 32, 8, 6, 9, 247, 68, 90, 21, 32, 0, 0, 0, 0, 0, 0, 1, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, +93, 42, 7, 223, 187, 80, 30, 215, 184, 137, 23, 133, 11, 41, 233, 90, 0, 169, 8, 0, 0, 68, 88, 66, 67, 63, 72, 10, 31, 174, 6, 95, 98, 208, 223, 126, 16, 24, 192, 5, 21, 1, 0, 0, 0, 169, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, +0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, +64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, +79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, +0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 156, 6, 0, 0, 96, 0, 0, 0, 167, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 132, 6, 0, 0, 66, 67, 192, 222, 33, 12, +0, 0, 158, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, +36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, +6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, +9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, +160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, +24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, +0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, 128, 129, 0, 0, +0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, +7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, +113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, +0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, +25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, 2, 0, 0, 0, +40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 113, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, 16, 134, 32, 32, +2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, +100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, 67, 144, 101, 27, +2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, 32, 19, 4, 229, +217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 201, 160, 42, 169, 200, 204, 172, 108, 140, +110, 10, 45, 140, 172, 76, 142, 199, 44, 140, 109, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, 109, 74, 224, 52, +33, 195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, 46, 237, 205, 109, +110, 74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 0, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 65, 167, 205, 112, 218, 253, 189, 202, +195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, +67, 77, 126, 113, 219, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, 210, 133, 61, 209, +136, 65, 2, 128, 32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, 217, 136, 193, 3, +128, 32, 24, 64, 97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, 36, 0, 8, 130, +65, 212, 6, 219, 26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +1, 0, 0, 0, 1, 38, 80, 102, 132, 127, 82, 13, 213, 245, 215, 76, 218, 16, 130, 201, 158, 0, 47, 8, 0, 0, 68, 88, 66, 67, 51, 9, 79, 152, 140, 60, 134, 143, 127, 116, 210, 3, 229, 153, 197, 148, 1, 0, 0, 0, 47, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, +0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, +84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, +80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, +0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, +0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 40, 5, 0, 0, 96, 0, 1, 0, 74, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 16, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, +0, 65, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, +72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, +0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, +0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, +0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, +32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, +7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, +0, 0, 0, 100, 129, 0, 0, 0, 0, 17, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, +34, 40, 131, 82, 40, 6, 34, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, 155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, +17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 193, 217, 48, 32, 9, 49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, +120, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 8, 104, 195, 50, 64, 145, 100, 73, 195, 53, 72, 192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, 2, 113, 108, 88, +56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, 160, 72, 210, 168, 193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, 44, 28, 25, 68, +101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 144, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, 120, 204, 194, 216, 230, 202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, 75, 26, 160, 1, +0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, 50, 185, 41, 129, 81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, 34, 195, 115, 161, +203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, +188, 236, 115, 89, 167, 205, 112, 218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 66, 0, 0, 0, 19, 4, 193, +136, 65, 2, 128, 32, 24, 20, 80, 227, 56, 11, 51, 98, 144, 0, 32, 8, 6, 69, 228, 60, 207, 210, 140, 24, 36, 0, 8, 130, 65, 33, 61, 11, 212, 56, 35, 6, 9, 0, 130, 96, 80, 76, 16, 19, 53, 207, 136, 65, 2, 128, 32, 24, 20, 84, 212, 72, 12, 52, 98, 144, 0, 32, 8, +6, 69, 37, 57, 19, 19, 141, 24, 36, 0, 8, 130, 65, 97, 77, 12, 21, 73, 35, 6, 9, 0, 130, 96, 80, 92, 84, 83, 69, 211, 136, 65, 2, 128, 32, 24, 20, 88, 229, 88, 16, 53, 98, 144, 0, 32, 8, 6, 69, 102, 61, 23, 84, 141, 24, 36, 0, 8, 130, 65, 161, 93, 15, 86, +89, 35, 6, 9, 0, 130, 96, 96, 104, 15, 148, 89, 201, 136, 65, 2, 128, 32, 24, 24, 218, 3, 101, 21, 50, 98, 144, 0, 32, 8, 6, 134, 246, 64, 217, 116, 140, 24, 36, 0, 8, 130, 129, 161, 61, 80, 38, 25, 35, 6, 9, 0, 130, 96, 96, 104, 79, 150, 89, 203, 136, 65, 2, 128, +32, 24, 24, 218, 147, 101, 149, 50, 98, 144, 0, 32, 8, 6, 134, 246, 80, 153, 85, 140, 24, 36, 0, 8, 130, 129, 161, 61, 84, 86, 17, 35, 6, 9, 0, 130, 96, 96, 104, 15, 149, 77, 195, 136, 65, 2, 128, 32, 24, 24, 218, 67, 101, 146, 48, 98, 144, 0, 32, 8, 6, 134, 246, 68, +153, 21, 32, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index 88664ea3d7..6768993f5e 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -16,272 +16,261 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, -93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, -24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 187, 195, 141, 246, 160, 52, 251, 46, 218, 4, 81, 95, 110, 153, 4, 148, 0, 76, 30, 0, 0, 3, -2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, -0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, -0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, -0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, -0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, -0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, -48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, -114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, -116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, -0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, -0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, -54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, -0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, -82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, -108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, -50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, -1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, -108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 81, 1, 0, 0, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, -97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, -0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, -111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, -97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, -1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, -1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, -0, 6, 0, 184, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, -0, 5, 0, 185, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, -0, 6, 0, 186, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, -0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, -116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 192, -1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, -1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, -117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, -0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, -0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, -83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, -1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, -0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, -0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, -111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, -1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, -0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, -83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, -71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, -1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, -0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, -0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, -0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, -1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, -0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, -95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, -0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, -1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, -0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, -0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, -0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, -0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, -0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, -0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, -0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, -0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, -0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, -0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, -0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, -0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, -0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, -0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 42, -0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, -0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, -0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, -0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, -1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, -0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, -1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, -0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, -1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, -1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, -1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, -1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, -0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, -0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, -0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, -0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, -0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, -0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, -0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, -0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, -1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, -1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, -1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, -0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, -0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, -1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, -1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, -0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, -1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, -1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, -1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, -1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, -0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, -1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, -1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, -1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, -1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, -1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, -1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, -1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, -1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, -1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, -1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 187, 195, 141, 246, 160, 52, 251, 46, 218, 4, 81, 95, 110, 153, 4, 148, 0, 76, 30, 0, 0, 3, 2, 35, 7, 0, 4, -1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, -0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0, 219, 1, -0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, 0, 3, 0, 189, 1, -0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, -7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, -7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, -0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, 0, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, -0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 132, 0, -0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, 82, 71, 66, 97, 0, -0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, -54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, 1, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 81, 1, 0, 0, 85, 73, 69, 102, 102, 101, -99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, -0, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, -5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, -0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, -0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, -116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, -114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, -0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, -0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, -0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, -5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, -115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, -116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, -116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, -95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, -0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, -7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, -85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, -0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, -0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, -6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, -0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, -114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 228, 1, -0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, -108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, -0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, -0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, -6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, -4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, -7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, -90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, -0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, -0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, -0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, -0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, -4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, -0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, -0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, -0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, -4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, -0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, -0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, -0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, -0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, -0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, -0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 7, 0, -0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, -4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, -0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, -0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, -0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, -0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, -0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, -0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, -0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, -0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, -0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, -0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, -0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, -0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, -0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, -0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, -2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, -0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, -0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, -0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, -0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, -4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, -0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, -0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, -0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, -3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, -5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, -0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, -3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, -3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, -0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, -0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, -5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, -0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, -0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, +71, 236, 145, 150, 195, 240, 161, 2, 171, 253, 209, 255, 135, 45, 216, 175, 0, 44, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, +117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, +83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, +0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, +0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, +0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, +0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, +99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, +49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, +0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, +0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, +53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, +0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, +102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, +0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, +0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, +0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, +0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, +108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, +80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, +0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, +0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, +0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, +0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, +0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, +0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, +122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, +83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, +0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, +0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, +116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, +116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, +0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, +0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, +76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, +0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, +0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, +0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, +0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, +0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, +64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, +63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, +0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, +0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, +0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, +0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, +0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, +0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, +0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, +0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, +0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, +0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, +0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, +0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, +0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, +0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, +0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, +0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, +0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, +0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, +0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, +0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, +0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, +0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, +0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, +0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, +0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, +0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, +0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, +0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, +0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, +0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 71, 236, 145, 150, 195, 240, 161, 2, 171, 253, 209, 255, 135, 45, 216, 175, 0, 44, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, +0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, +14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, +87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, +228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, +0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, +121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, +5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, +5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, +87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, +102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, +49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, +137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, +97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, +56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, +102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, +0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, +5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, +101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, +111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, +112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, +194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, +195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, +196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, +6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, +97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, +105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, +111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, +117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, +219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, +5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, +78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, +2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, +225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, +115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, +238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, +117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, +3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, +11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, +71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, +67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, +2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, +71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, +0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, +63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, +85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, +137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, +173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, +43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, +43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, +43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, +38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, +173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, +224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, +4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, +87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, +192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, +216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, +221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, +153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, +157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, +135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, +165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, +168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, +170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, +154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, +54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, +83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, +248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, +59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, +65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, +159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, +248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, +139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, +170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, +205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, +0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, +208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, +212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, +228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, +239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, +242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, +228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs index d508d15bf9..08b57ecd6b 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -16,40 +16,48 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, -0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, -120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, -1, 154, 189, 83, 121, 135, 82, 163, 70, 23, 190, 123, 153, 33, 15, 144, 64, 0, 72, 76, 0, 0, 68, 88, 66, 67, 242, 226, 198, 214, 21, 161, 113, 224, 244, 54, 44, 73, 216, 80, 228, 185, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, -0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, 76, 0, 0, 65, 111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, -0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, -105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, -48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 84, 0, 0, 0, 208, 2, 0, 0, 86, 0, 0, 0, 224, 2, 0, 0, 93, 0, -0, 0, 240, 2, 0, 0, 95, 0, 0, 0, 4, 3, 0, 0, 95, 0, 0, 0, 20, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, -0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 49, 55, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 60, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, -0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, -114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 168, 1, 0, 0, 8, 1, 0, 0, 180, 1, 0, 0, 196, 1, 0, 0, 5, 0, 0, 0, 1, 0, -7, 0, 1, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 1, -0, 0, 1, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 36, 1, 0, 0, 68, 1, 0, 0, 1, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 112, 1, 0, 0, 36, 1, 0, 0, 124, 1, 0, 0, 236, 1, 0, 0, 2, 0, -0, 0, 252, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, -0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, -228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, -0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, -0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, -0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, -0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, -0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, +0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, +90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, +182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, +62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 46, 32, 228, 6, 251, 177, 93, 246, 133, 15, 251, 122, 98, 177, 33, 174, 0, 72, +76, 0, 0, 68, 88, 66, 67, 60, 211, 228, 5, 120, 180, 199, 224, 249, 196, 224, 120, 231, 126, 120, 60, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, 0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, 76, 0, 0, 65, +111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, 0, 0, 0, 120, +2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, 171, 171, 171, 40, +0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 70, 0, 0, 0, 208, 2, 0, 0, 72, 0, 0, 0, 224, 2, 0, 0, 79, 0, 0, 0, 240, 2, 0, 0, 81, 0, 0, 0, 4, 3, 0, 0, 81, 0, 0, 0, 20, +3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 50, 51, 0, +171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, 1, 0, 0, 5, +0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 60, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, +0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 168, 1, 0, 0, 8, 1, 0, 0, 180, 1, 0, 0, 196, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, +0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 36, 1, 0, 0, 68, +1, 0, 0, 1, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 112, 1, 0, 0, 36, 1, 0, 0, 124, 1, 0, 0, 236, 1, 0, 0, 2, 0, 0, 0, 252, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, +32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, +0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, +0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, +16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, +0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, +0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, +70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -57,7 +65,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -65,7 +73,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -73,7 +81,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -81,284 +89,284 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 4, 46, 216, 174, 161, 45, 122, 65, 183, 32, 96, 199, 233, 143, 10, 227, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 27, 227, 109, 42, 194, 68, 17, 68, 135, 27, 15, 241, 78, 81, 40, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, -101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, -0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 6, 212, 2, 0, 149, 49, 3, 0, 125, 218, 1, 0, 16, 77, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 142, 5, 3, 0, 149, +49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, -101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, -97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, -46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, -101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, -117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, -32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, -32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, -123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, -111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, -99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, -67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, -40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, -115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, -114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, -117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, +10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, +122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, +32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, +100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, +105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, +69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, +77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, +32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 37, 11, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 0, 99, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 56, 56, 49, 54, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 229, 68, 21, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 234, 207, 16, 230, 112, 10, 0, 0, 1, 0, -0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 188, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, +100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, +101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 52, 53, 50, +51, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 218, 184, 215, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 35, 239, 192, 163, 7, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, -41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, -95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, -0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, -132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, -4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, -117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, -0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 8, 12, 128, 128, 0, 8, 0, 13, 32, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 58, -11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 57, 1, 92, 12, 128, 128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, -9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, -36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, -95, 52, 49, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, -5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, -0, 0, 1, 0, 0, 0, 16, 1, 61, 27, 161, 135, 201, 0, 224, 65, 85, 2, 199, 236, 7, 73, 45, 219, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 117, 0, -0, 128, 92, 0, 0, 0, 117, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 128, 120, 0, 0, 0, 117, 0, 0, 0, 156, 0, 0, 0, 117, 0, 0, 128, 156, 0, 0, 0, 117, 0, 0, 0, 192, 0, 0, 0, 117, 0, 0, 128, 192, 0, 0, 0, 117, 0, 0, 0, 220, 0, 0, 0, 120, 0, -0, 128, 220, 0, 0, 0, 120, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, -0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, -0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, -3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, -105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, -0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, -0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, -0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 3, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, -0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 20, 209, 2, 0, 170, 56, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, +108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, +116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, +0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, +0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, +0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, +0, 9, 5, 13, 33, 6, 8, 12, 128, 128, 0, 8, 0, 13, 32, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 58, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 57, 1, 92, 12, 128, 128, 0, 0, 78, +0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, +13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, +0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, +0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 162, 230, 18, 107, 157, 250, 40, 101, 185, 28, 2, +100, 78, 148, 241, 36, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, 0, 0, 0, 103, 0, 0, 128, 120, +0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, +0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 85, +0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, +0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, +0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, +95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, +0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, +8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, +0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 41, 75, 0, 0, 20, 209, 2, 0, 170, 56, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, -105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, -97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, -46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, -116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, -101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, -117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, -32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, -32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, -123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 49, 55, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, -111, 114, 32, 61, 32, 95, 52, 49, 55, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, -99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, -67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, -116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, -40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, -115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, -114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, -117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 104, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, -0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, -95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, +122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, +32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, +100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, +105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, +69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, +77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, +32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, -0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, -95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 104, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, +0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, +0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, +0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, +0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, +0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, -0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, -48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 52, 56, 56, 49, 54, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 4, 46, 216, 174, 161, 45, 122, 65, 183, 32, 96, 199, 233, 143, 10, 227, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, -47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 52, 56, 56, 49, 54, 56, 0, 4, 0, 0, 0, -6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 85, 11, 0, 0, 128, 0, 0, 0, 112, 10, 0, 0, 220, 4, -0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, -0, 0, 24, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, -0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, +0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, +0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 27, 227, 109, 42, 194, 68, 17, 68, 135, 27, 15, 241, 78, 81, 40, 62, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, +108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, +100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 52, 53, 50, 51, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, +0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 236, 8, 0, 0, 128, 0, 0, 0, 7, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, +0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, +0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, -83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, -46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 85, 241, 60, 24, 232, 10, 79, 78, 78, 208, 4, 40, 89, 149, 176, 122, 0, 88, 85, 0, 0, 68, 88, 66, 67, 232, 180, -97, 71, 2, 247, 132, 76, 220, 220, 206, 167, 20, 185, 16, 241, 1, 0, 0, 0, 88, 85, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 83, 0, 0, 236, 83, 0, 0, 56, 84, 0, 0, 208, 84, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, -0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 128, 2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, -97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, -0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 0, 0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 91, 0, 0, 0, 36, 3, 0, 0, 91, 0, 0, 0, 56, 3, 0, 0, 91, 0, 0, 0, 76, 3, 0, 0, 117, 0, 0, 0, 92, 3, -0, 0, 119, 0, 0, 0, 112, 3, 0, 0, 119, 0, 0, 0, 124, 3, 0, 0, 91, 0, 0, 0, 136, 3, 0, 0, 117, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, -2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 245, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, -4, 0, 100, 1, 0, 0, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 8, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, -5, 0, 12, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, -108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 232, 1, 0, 0, 8, 1, 0, 0, 247, 1, 0, 0, 40, 1, 0, 0, 6, 2, 0, 0, 40, 1, 0, 0, 18, 2, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 32, 2, -0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 240, 0, 0, 0, 132, 1, 0, 0, 6, 0, -0, 0, 148, 1, 0, 0, 240, 0, 0, 0, 220, 1, 0, 0, 64, 2, 0, 0, 4, 0, 0, 0, 80, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, -49, 0, 81, 0, 0, 5, 1, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, -0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, -228, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 0, 0, -12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 80, 1, 0, 0, 64, 0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, -0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 104, 0, -0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, -0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, -16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, -0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, -48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, +68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, +0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, +0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, +0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, +86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 29, 161, 12, 2, 233, 165, 178, 83, 112, 105, 229, 242, 0, 142, 46, 113, 0, 88, 77, 0, 0, 68, 88, 66, 67, 110, 135, 218, 8, 57, 42, 60, 65, 13, 102, 64, 206, 48, 224, 56, 141, 1, 0, 0, 0, 88, +77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 75, 0, 0, 236, 75, 0, 0, 56, 76, 0, 0, 208, 76, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, 0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, +0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 128, +2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, +99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 0, +0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 76, 0, 0, 0, 36, 3, 0, 0, 76, 0, 0, 0, 56, 3, 0, 0, 76, 0, 0, 0, 76, 3, 0, 0, 102, 0, 0, 0, 92, 3, 0, 0, 104, 0, 0, 0, 112, 3, 0, 0, 104, 0, 0, 0, 124, 3, 0, 0, 76, +0, 0, 0, 136, 3, 0, 0, 102, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, +108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 245, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 100, 1, 0, 0, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 8, +0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 12, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 232, +1, 0, 0, 8, 1, 0, 0, 247, 1, 0, 0, 40, 1, 0, 0, 6, 2, 0, 0, 40, 1, 0, 0, 18, 2, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, +0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 240, 0, 0, 0, 132, 1, 0, 0, 6, 0, 0, 0, 148, 1, 0, 0, 240, 0, 0, 0, 220, 1, 0, 0, 64, 2, 0, 0, 4, +0, 0, 0, 80, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 1, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, +44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 7, 128, 2, +0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, +0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 80, 1, 0, 0, 64, +0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, +0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, +16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, +0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, +44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, +0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, +0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -366,7 +374,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -374,273 +382,223 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, -0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 179, 154, 95, 31, 253, 5, 74, 76, 157, 242, -177, 234, 82, 163, 35, 186, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 244, 255, 195, 78, 220, 92, 83, 71, 128, 23, 0, 238, 206, 173, 252, 43, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, -101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, -2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, 3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, +99, 0, 0, 143, 154, 3, 0, 31, 105, 3, 0, 233, 240, 2, 0, 82, 155, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, -101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, -101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, -58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, -116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, -95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, -66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, -48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, -46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, -32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, -32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, -41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, -116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, -10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 14, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, -97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 97, 52, 101, 54, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 99, 220, 22, 137, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, -0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 117, 192, 247, 227, 89, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, +79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, +115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, +48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, +43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, +101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, +32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, +114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, +105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, +117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 164, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, +92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 0, 99, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, +100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 100, 98, 97, 50, 54, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 134, 191, 219, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 58, 5, 190, 176, 239, 9, 0, 0, 1, +0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, -10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, -0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 204, 3, 0, 0, 0, 0, -0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, 16, 0, 0, 116, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, 0, -0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, -220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, -4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, -220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 200, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 10, 12, 128, 136, 40, 8, 0, 13, 32, 1, 128, -156, 12, 128, 136, 0, 0, 42, 0, 77, 17, 52, 3, 0, 0, 196, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 8, 0, 9, 27, 13, 53, 1, 128, 156, 12, 128, 136, 0, 0, 0, 0, 54, 0, 77, 17, 92, 3, 0, 0, 192, 3, 0, 0, 2, 16, -0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 156, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, -0, 0, 1, 0, 0, 0, 16, 1, 165, 95, 147, 40, 192, 223, 191, 125, 108, 82, 45, 147, 97, 56, 255, 117, 0, 0, 242, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 129, 0, -0, 128, 116, 0, 0, 0, 129, 0, 0, 0, 136, 0, 0, 0, 129, 0, 0, 128, 136, 0, 0, 0, 129, 0, 0, 0, 156, 0, 0, 0, 123, 0, 0, 128, 156, 0, 0, 0, 123, 0, 0, 0, 216, 0, 0, 0, 123, 0, 0, 128, 216, 0, 0, 0, 123, 0, 0, 0, 8, 1, 0, 0, 123, 0, -0, 128, 8, 1, 0, 0, 123, 0, 0, 0, 36, 1, 0, 0, 129, 0, 0, 128, 36, 1, 0, 0, 129, 0, 0, 0, 56, 1, 0, 0, 129, 0, 0, 128, 56, 1, 0, 0, 129, 0, 0, 0, 76, 1, 0, 0, 129, 0, 0, 128, 76, 1, 0, 0, 129, 0, 0, 0, 5, 0, 24, 0, 5, 0, -24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 95, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 200, 1, 0, 0, 10, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, -0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, -83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, -5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, -111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, -0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 148, 128, 1, 0, 138, 207, 3, 0, 64, 168, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, +82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, +52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 204, 3, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, 16, 0, 0, 116, +0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, +0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, +0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, +0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, +0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, +0, 220, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 116, +0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, +0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 116, +0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 200, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 10, 12, 128, 136, 40, 8, 0, 13, 32, 1, 128, 156, 12, 128, 136, 0, 0, 42, 0, 77, 17, 52, 3, 0, 0, 196, 3, 0, 0, 1, +16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 8, 0, 9, 27, 13, 53, 1, 128, 156, 12, 128, 136, 0, 0, 0, 0, 54, 0, 77, 17, 92, 3, 0, 0, 192, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, +13, 107, 1, 128, 156, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 100, 74, 125, 240, 195, 252, 162, 72, 19, 251, 144, +184, 185, 124, 245, 248, 0, 0, 242, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 114, 0, 0, 128, 116, 0, 0, 0, 114, 0, 0, 0, 136, 0, 0, 0, 114, 0, 0, 128, 136, +0, 0, 0, 114, 0, 0, 0, 156, 0, 0, 0, 108, 0, 0, 128, 156, 0, 0, 0, 108, 0, 0, 0, 216, 0, 0, 0, 108, 0, 0, 128, 216, 0, 0, 0, 108, 0, 0, 0, 8, 1, 0, 0, 108, 0, 0, 128, 8, 1, 0, 0, 108, 0, 0, 0, 36, 1, 0, 0, 114, 0, 0, 128, 36, +1, 0, 0, 114, 0, 0, 0, 56, 1, 0, 0, 114, 0, 0, 128, 56, 1, 0, 0, 114, 0, 0, 0, 76, 1, 0, 0, 114, 0, 0, 128, 76, 1, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, +0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, +16, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 13, 16, 0, 0, 23, 0, 1, 0, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, -101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, -58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, -116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, -95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, -86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, -66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, -48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, -46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 54, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 54, 57, 41, 59, 10, 32, 32, 32, -32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, -32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, -41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, -116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, -10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, -255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, -0, 0, 10, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, -101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 216, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, +0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, +0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, +16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, +0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, +21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, +80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, +0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, +0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 30, 167, 1, 0, 206, 172, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, -0, 0, 10, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, -101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, +79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, +115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, +48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, +43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, +101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, +32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, +114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, +105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, +117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, +0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, +0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, +114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, -1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 3, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, -0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, -255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, -114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 55, 70, 53, 53, 65, 52, 69, 54, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 186, 180, 142, 105, 1, 0, 0, 0, 179, 154, 95, 31, 253, 5, 74, 76, 157, 242, -177, 234, 82, 163, 35, 186, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 55, 102, 53, 53, 97, 52, 101, 54, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 0, 2, 0, 0, 111, 1, 0, 0, 156, 0, -0, 0, 0, 0, 0, 0, 62, 13, 0, 0, 128, 0, 0, 0, 89, 12, 0, 0, 8, 5, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 34, 0, 0, 0, 20, 0, 0, 0, 33, 0, 0, 0, 27, 0, -0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, -0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 21, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -648,29 +606,47 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 3, 0, 0, 0, +0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, +118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, +64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 244, 255, 195, 78, 220, 92, 83, 71, 128, 23, 0, 238, 206, 173, 252, 43, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, +0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, +92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 100, 98, 97, 50, 54, 56, 0, 4, 0, 0, +0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 16, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 212, 10, 0, 0, 128, 0, 0, 0, 239, 9, 0, 0, 8, +5, 0, 0, 68, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, +0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, +0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, -0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, -254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, -0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, -82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, +32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, +0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, +0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, + }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs index 74f5f2f41f..8905dce0e3 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -16,101 +16,88 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, -93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, -24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 152, 125, 156, 155, 102, 27, 190, 176, 60, 205, 167, 118, 128, 139, 0, 83, 0, 253, 8, 0, 0, 68, -88, 66, 67, 105, 222, 61, 200, 62, 222, 130, 78, 218, 190, 85, 175, 241, 135, 121, 182, 1, 0, 0, 0, 253, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 9, 1, 0, 0, 21, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, -95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, -3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 224, 6, 0, 0, 96, 0, 0, 0, 184, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 200, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 175, 1, 0, 0, -11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, -196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, -255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 91, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, -72, 160, 144, 145, 129, 144, 64, 49, 65, 112, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, -0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, -0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, -3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, -0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, -52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, -109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, -96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, -16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 30, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, -1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, -2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 35, 0, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 133, 98, 160, 6, 0, 0, 128, 146, 40, 132, 2, 1, 121, 24, 0, 0, 123, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, -99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 35, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 10, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, -186, 58, 185, 50, 152, 9, 2, 177, 76, 16, 20, 102, 130, 64, 52, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, -152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 225, 108, 16, 8, 138, 2, 220, 220, 4, 129, 200, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 10, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, -67, 79, 79, 82, 68, 19, 132, 70, 155, 32, 52, 208, 134, 32, 152, 32, 52, 210, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, 2, 50, 0, 54, 4, 196, 4, 161, 217, 54, 44, 132, 24, 140, 1, 25, 160, 129, 25, 16, 105, 64, 144, 1, 176, 33, 96, 38, 8, 77, 180, 97, 97, 196, -96, 12, 200, 96, 13, 204, 128, 96, 3, 134, 12, 128, 13, 195, 25, 168, 65, 27, 48, 153, 178, 250, 162, 10, 147, 59, 43, 163, 155, 32, 52, 220, 134, 37, 120, 131, 49, 128, 131, 50, 32, 3, 34, 13, 2, 50, 0, 54, 4, 113, 176, 97, 112, 3, 57, 0, 56, 6, 85, 73, 69, 102, 102, 101, -99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 142, 14, 230, 128, 3, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 162, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 169, -9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 128, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 184, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 182, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, -115, 83, 2, 48, 168, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 160, 3, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 130, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, -178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 27, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 141, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, -226, 182, 1, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 220, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 78, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 129, 227, 69, 88, 246, 64, 35, 6, 9, 0, 130, 96, 224, 124, 82, 166, 61, 209, 136, 65, -2, 128, 32, 24, 56, 96, 48, 105, 219, 35, 141, 24, 36, 0, 8, 130, 129, 19, 6, 212, 198, 61, 211, 136, 65, 2, 128, 32, 24, 56, 98, 80, 97, 221, 68, 141, 24, 36, 0, 8, 130, 65, 36, 6, 80, 228, 121, 216, 136, 65, 2, 128, 32, 24, 68, 99, 16, 85, 223, 151, 141, 24, 60, 0, -8, 130, 193, 52, 6, 80, 32, 36, 72, 20, 93, 215, 21, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 12, 55, 32, 84, 48, 221, 64, 20, 193, 116, 3, 97, 8, 211, 13, 196, 49, 24, 2, 73, 192, 8, 72, 2, 70, 64, 18, 48, 2, 146, 192, 136, 65, 2, 128, 32, 24, -80, 111, 176, 181, 65, 27, 140, 1, 49, 98, 144, 0, 32, 8, 6, 212, 27, 108, 109, 208, 6, 98, 48, 140, 24, 36, 0, 8, 130, 1, 245, 6, 91, 27, 180, 65, 24, 8, 35, 6, 9, 0, 130, 96, 64, 189, 193, 214, 6, 109, 0, 6, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, -0, 0, 1, 14, 70, 255, 142, 29, 31, 250, 44, 38, 196, 28, 169, 108, 101, 160, 81, 0, 7, 9, 0, 0, 68, 88, 66, 67, 54, 36, 105, 211, 102, 104, 128, 1, 45, 38, 214, 138, 212, 77, 103, 176, 1, 0, 0, 0, 7, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, -248, 0, 0, 0, 175, 1, 0, 0, 19, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, -2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, -115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 92, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, -0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, -0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 236, 5, 0, 0, 96, 0, 1, 0, 123, 1, 0, 0, 68, 88, 73, 76, 0, -1, 0, 0, 16, 0, 0, 0, 212, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 114, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, -72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, -255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, -10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, -8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, -3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, -7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, -144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, -9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 3, 2, 0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, -16, 205, 85, 39, 61, 34, 0, 0, 0, 40, 133, 98, 160, 3, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 114, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, 54, 32, 129, 48, -4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, 133, 130, 221, 220, -4, 129, 152, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 131, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, -1, 49, 65, 56, 170, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 225, 108, 8, 196, 96, 130, 112, 40, 27, 22, 49, 176, 46, 108, 12, 48, 130, 12, 196, 0, 3, 54, 16, 155, 23, 6, 101, 176, 97, 9, -172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 130, 12, 62, 12, 224, 50, 101, 245, 5, 245, 54, 151, 70, 151, 246, 230, 54, 65, 56, 152, 13, 139, 24, 168, 193, 181, 6, 89, 71, 116, 98, 128, 1, 27, 136, 51, 64, 131, 52, -96, 131, 13, 131, 25, 180, 1, 192, 49, 168, 74, 42, 50, 51, 43, 27, 163, 155, 66, 11, 35, 43, 147, 227, 161, 147, 171, 43, 243, 113, 177, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 68, 111, 224, 6, 16, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, -112, 84, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 32, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 74, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 65, 83, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 240, 84, 34, 195, -115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 80, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 111, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, -242, 122, 217, 231, 178, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 0, 0, 0, 97, 32, 0, 0, 87, 0, 0, 0, 19, -4, 193, 136, 65, 2, 128, 32, 24, 32, 213, 35, 73, 141, 51, 98, 144, 0, 32, 8, 6, 136, 5, 77, 83, 243, 140, 24, 36, 0, 8, 130, 1, 114, 69, 19, 245, 64, 35, 6, 9, 0, 130, 96, 128, 96, 18, 85, 61, 209, 136, 65, 2, 128, 32, 24, 32, 217, 84, 89, 143, 52, 98, 144, 0, -32, 8, 6, 136, 70, 89, 215, 51, 141, 24, 36, 0, 8, 130, 1, 178, 85, 15, 54, 81, 35, 6, 9, 0, 130, 96, 128, 112, 22, 148, 77, 213, 136, 65, 2, 128, 32, 24, 32, 221, 21, 105, 147, 53, 98, 144, 0, 32, 8, 6, 136, 135, 73, 219, 116, 141, 24, 36, 0, 8, 130, 1, 242, 101, -18, 119, 97, 86, 72, 18, 176, 98, 146, 128, 21, 148, 4, 108, 160, 32, 96, 67, 5, 1, 27, 44, 8, 216, 50, 72, 192, 150, 65, 2, 182, 12, 18, 176, 33, 131, 128, 13, 26, 4, 108, 216, 32, 96, 209, 32, 1, 139, 6, 9, 88, 52, 72, 96, 196, 32, 1, 64, 16, 12, 18, 55, 240, 196, -128, 13, 206, 0, 27, 49, 72, 0, 16, 4, 131, 196, 13, 60, 49, 96, 3, 51, 184, 70, 12, 18, 0, 4, 193, 32, 113, 3, 79, 12, 216, 160, 12, 172, 17, 131, 4, 0, 65, 48, 72, 220, 192, 19, 3, 54, 32, 131, 106, 196, 32, 1, 64, 16, 12, 18, 55, 240, 216, 128, 13, 206, 64, 27, -49, 72, 0, 16, 4, 131, 196, 13, 60, 54, 96, 3, 51, 200, 70, 12, 18, 0, 4, 193, 32, 113, 3, 111, 13, 216, 224, 12, 134, 17, 131, 4, 0, 65, 48, 72, 220, 192, 91, 3, 54, 48, 3, 97, 196, 32, 1, 64, 16, 12, 18, 55, 240, 214, 128, 13, 202, 32, 24, 49, 72, 0, 16, 4, -131, 196, 13, 188, 53, 96, 3, 50, 136, 70, 12, 18, 0, 4, 193, 32, 113, 3, 111, 12, 216, 224, 12, 32, 4, 0, 0, 0, 0, 0, 0, 1, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, +92, 44, 138, 0, 10, 250, 131, 12, 168, 123, 143, 12, 28, 101, 152, 51, 0, 165, 8, 0, 0, 68, 88, 66, 67, 137, 222, 21, 142, 162, 27, 39, 186, 66, 23, 203, 124, 217, 194, 66, 172, 1, 0, 0, 0, 165, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, +0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, +64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, +255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, +79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, +0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 6, 0, 0, 96, 0, 0, 0, 166, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 6, 0, 0, 66, 67, 192, 222, 33, 12, +0, 0, 157, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, +36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, +6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, +9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, +160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, +24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, +0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, 128, 129, 0, 0, +0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, +7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, +113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, +0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, +25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, 2, 0, 0, 0, +40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, 16, 134, 32, 32, +2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, +100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, 67, 144, 101, 27, +2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, 32, 19, 4, 229, +217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 199, 160, 42, 169, 200, 204, 172, 108, 140, +110, 10, 45, 140, 172, 76, 142, 135, 78, 174, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, 109, 74, 224, 52, 33, +195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, 46, 237, 205, 109, 110, +74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 130, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, +2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 27, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 141, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, +1, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, 210, 133, 61, 209, 136, 65, 2, 128, +32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, 217, 136, 193, 3, 128, 32, 24, 64, +97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, 36, 0, 8, 130, 65, 212, 6, 219, +26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, +1, 164, 179, 85, 37, 28, 243, 21, 181, 58, 52, 132, 154, 126, 102, 214, 232, 0, 159, 8, 0, 0, 68, 88, 66, 67, 51, 98, 248, 14, 78, 222, 169, 151, 180, 193, 108, 137, 163, 189, 192, 229, 1, 0, 0, 0, 159, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, +0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, +0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, +116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, +0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, +0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 5, 0, 0, 96, 0, 1, 0, 102, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 93, 1, 0, +0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, +35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, +0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, 0, 148, 0, 0, +0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, 0, 128, 2, 0, +0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, +14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, +120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, +129, 0, 0, 0, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, 34, 40, 3, 26, +0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, 16, 205, 85, 39, 61, 18, 0, 0, 0, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, 155, 11, 3, 177, +43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 33, 218, 48, 32, 9, 49, 65, 56, 128, +13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 144, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 105, 195, 50, 64, 145, 100, 73, 195, 53, 72, 192, 4, 65, 88, +54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, 2, 113, 108, 88, 56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, 160, 72, 210, 168, +193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, 44, 28, 25, 68, 101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 112, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, 120, 232, 228, 234, +202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, 75, 26, 160, 1, 0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, 50, 185, 41, 129, +81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, 0, 113, 32, 0, +0, 18, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 178, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 160, 26, 46, 223, 121, 124, 105, 114, +34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 0, 0, 0, 97, 32, 0, 0, 87, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 20, 19, 20, 69, 206, 51, 98, 144, 0, 32, 8, 6, 5, 21, 73, 146, 3, 141, 24, 36, 0, 8, 130, 65, 81, 73, 206, 4, 69, 35, 6, 9, 0, 130, +96, 80, 88, 211, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 5, 85, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 69, 214, 67, 141, 24, 36, 0, 8, 130, 65, 145, 89, 207, 69, 85, 35, 6, 9, 0, 130, 96, 80, 104, 23, 132, 81, 214, 136, 65, 2, 128, 32, 24, 20, 27, 22, 101, +211, 53, 98, 144, 0, 32, 8, 6, 5, 151, 73, 218, 132, 141, 24, 36, 0, 8, 130, 65, 209, 105, 210, 134, 101, 86, 72, 18, 176, 98, 146, 128, 21, 148, 4, 108, 160, 32, 96, 67, 5, 1, 27, 44, 8, 216, 50, 72, 192, 150, 65, 2, 182, 12, 18, 176, 33, 131, 128, 13, 26, 4, 108, 216, +32, 96, 209, 32, 1, 139, 6, 9, 88, 52, 72, 96, 196, 32, 1, 64, 16, 12, 12, 54, 240, 196, 96, 13, 208, 0, 27, 49, 72, 0, 16, 4, 3, 131, 13, 60, 49, 88, 131, 51, 184, 70, 12, 18, 0, 4, 193, 192, 96, 3, 79, 12, 214, 160, 12, 172, 17, 131, 4, 0, 65, 48, 48, 216, +192, 19, 131, 53, 32, 131, 106, 196, 32, 1, 64, 16, 12, 12, 54, 240, 214, 96, 13, 208, 64, 27, 49, 72, 0, 16, 4, 3, 131, 13, 188, 53, 88, 131, 51, 200, 70, 12, 18, 0, 4, 193, 192, 96, 3, 207, 12, 214, 0, 13, 134, 17, 131, 4, 0, 65, 48, 48, 216, 192, 51, 131, 53, 56, +3, 97, 196, 32, 1, 64, 16, 12, 12, 54, 240, 204, 96, 13, 202, 32, 24, 49, 72, 0, 16, 4, 3, 131, 13, 60, 51, 88, 3, 50, 136, 70, 12, 18, 0, 4, 193, 192, 96, 3, 111, 12, 214, 0, 13, 32, 4, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index 5d87b5ca02..0345fba734 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -16,271 +16,261 @@ namespace Stride.Graphics internal partial class UIEffect { private static readonly byte[] binaryBytecodeSRgb = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, -93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, -24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 183, 103, 133, 203, 32, 55, 146, 141, 231, 231, 212, 229, 165, 147, 143, 186, 0, 60, 30, 0, 0, 3, -2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, -0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, -0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, -0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, -0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, -0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, -48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, -114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, -116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, -0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, -0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, -54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, -0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, -82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, -108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, -50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, -1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, -108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 81, 1, 0, 0, 85, -73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, -0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 107, -1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, -0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, -0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, 116, 95, 80, -83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, 114, 95, 73, -110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, 0, 0, 0, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, 0, 0, 80, -83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, 0, 0, 0, -0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 186, -1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, -0, 0, 0, 5, 0, 11, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, -0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, -0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, -116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, -0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, -0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, -115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, -119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, -1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, -0, 0, 0, 5, 0, 11, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, -0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, -0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, -1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, -0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, -22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, -69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, -0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, -0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, -65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, -1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, -0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, -0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, -1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, -0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, -0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, -0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, -0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, -0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, -0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, -0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, -0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, -0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, 0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, -0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, -0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, -0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, -0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, -1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, -0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, -0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, -0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, -1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, -1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, -0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, -0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, -1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, -1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, -1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, -1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, -0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, -0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, -0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, -0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, -0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, -0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, -0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, -0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, -1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, -1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, -1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, 0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, -0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, -0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, 0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, -1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, -0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, -1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, 0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, -1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, -0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, -1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, -1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, -1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, -0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, -0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, -1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, -1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, -1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, -1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, -1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, -1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, -80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 183, 103, 133, 203, 32, 55, 146, 141, 231, 231, 212, 229, 165, 147, 143, 186, 0, 60, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 242, 1, 0, 0, 0, 0, 0, 0, 17, 0, -2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 186, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 189, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 178, 1, 0, 0, 180, 1, 0, 0, 182, 1, 0, 0, 176, 1, 0, 0, 188, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 241, 1, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0, 219, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, -0, 0, 205, 1, 0, 0, 208, 1, 0, 0, 209, 1, 0, 0, 211, 1, 0, 0, 204, 1, 0, 0, 206, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 218, 1, 0, 0, 241, 1, 0, 0, 16, 0, 3, 0, 189, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, -116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, -11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 106, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 109, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 116, 0, -0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 124, 0, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, -108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 148, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 149, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 151, 0, 0, 0, 115, 82, 71, 66, 0, 0, -0, 0, 5, 0, 4, 0, 169, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 181, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 239, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, -7, 0, 243, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 14, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 16, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 22, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 63, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 81, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, -83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 82, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 83, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, -60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 133, 1, -0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 157, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 161, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 165, 1, -0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 166, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, -0, 0, 5, 0, 7, 0, 177, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 176, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 179, 1, -0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 178, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 181, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, -102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 183, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 182, 1, 0, 0, 105, 110, -95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 184, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 184, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 184, 1, -0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 184, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 185, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 185, 1, 0, 0, 0, 0, -0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 186, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 186, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 186, 1, -0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 186, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 187, 1, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 188, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 189, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 192, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 195, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 198, 1, -0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 204, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 205, 1, -0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 207, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 206, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, -67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 208, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 209, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, -95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, -6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 214, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -0, 0, 6, 0, 6, 0, 214, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 214, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, -101, 0, 5, 0, 5, 0, 215, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 215, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 215, 1, 0, 0, 1, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 215, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 216, 1, 0, 0, 86, 83, 95, 83, 84, 82, -69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 216, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 216, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 216, 1, -0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 216, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 217, 1, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 218, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 219, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 228, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 6, 0, 239, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 239, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 5, 0, 9, 0, 240, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 176, 1, 0, 0, 30, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 178, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 178, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 180, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, -5, 0, 180, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 182, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, -4, 0, 204, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 205, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 205, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 206, 1, 0, 0, 30, 0, -0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 206, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 208, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 208, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, -79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 209, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 209, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 210, 1, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 211, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 212, 1, -0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 212, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 3, 0, 239, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 0, 0, 0, 0, 35, 0, -0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, -0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, -5, 0, 239, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 239, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 241, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, -0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, -4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, -0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, -0, 0, 82, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 109, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 116, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 115, 0, 0, 0, 4, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 122, 0, -0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 4, 0, 0, 0, 124, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 4, 0, 0, 0, 127, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 130, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, 0, -0, 0, 130, 0, 0, 0, 33, 0, 4, 0, 131, 0, 0, 0, 130, 0, 0, 0, 132, 0, 0, 0, 32, 0, 4, 0, 148, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 4, 0, 147, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 21, 0, 4, 0, 168, 0, 0, 0, 32, 0, -0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 169, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 173, 0, 0, 0, 3, 0, 0, 0, 148, 0, 0, 0, 116, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 181, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 4, 0, -0, 0, 239, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 4, 0, 0, 0, 248, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 4, 0, -0, 0, 14, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 4, 0, 0, 0, 16, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 4, 0, 0, 0, 22, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 4, 0, -0, 0, 32, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 7, 0, 0, 0, 77, 1, 0, 0, 33, 0, 3, 0, 129, 1, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 154, 1, 0, 0, 34, 0, 0, 0, 43, 0, -4, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 177, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 179, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 181, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 32, 0, -4, 0, 183, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 184, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 185, 1, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 186, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, -0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 6, 0, 0, 0, 186, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 195, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 198, 1, -0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 202, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 207, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 214, 1, 0, 0, 38, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 215, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 216, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, -0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 6, 0, 0, 0, 216, 1, 0, 0, 43, 0, 4, 0, 168, 0, 0, 0, 228, 1, 0, 0, 4, 0, 0, 0, 30, 0, 12, 0, 239, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, -0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 240, 1, 0, 0, 2, 0, 0, 0, 239, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 240, 1, 0, 0, 241, 1, 0, 0, 2, 0, -0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 176, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 178, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 180, 1, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 188, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 179, 1, 0, 0, 205, 1, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 207, 1, 0, 0, 206, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 208, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 181, 1, 0, 0, 209, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 177, 1, 0, 0, 210, 1, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 218, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, -0, 0, 147, 0, 0, 0, 55, 0, 3, 0, 148, 0, 0, 0, 149, 0, 0, 0, 248, 0, 2, 0, 150, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 152, 0, 0, 0, 149, 0, 0, 0, 79, 0, 8, 0, 130, 0, -0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 154, 0, 0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 155, 0, -0, 0, 151, 0, 0, 0, 61, 0, 4, 0, 130, 0, 0, 0, 156, 0, 0, 0, 151, 0, 0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 158, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 122, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 158, 0, -0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 160, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 124, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 159, 0, 0, 0, 157, 0, 0, 0, 160, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 161, 0, 0, 0, 155, 0, 0, 0, 159, 0, -0, 0, 80, 0, 6, 0, 130, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 129, 0, 5, 0, 130, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 133, 0, 5, 0, 130, 0, 0, 0, 164, 0, 0, 0, 154, 0, 0, 0, 162, 0, -0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 166, 0, 0, 0, 164, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 164, 0, 0, 0, 2, 0, 0, 0, 65, 0, -5, 0, 116, 0, 0, 0, 170, 0, 0, 0, 149, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 172, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 171, 0, 0, 0, 254, 0, -2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 95, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 115, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 102, 1, -0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 104, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 105, 1, 0, 0, 247, 0, 3, 0, 107, 1, -0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 77, 1, 0, 0, 106, 1, 0, 0, 107, 1, 0, 0, 248, 0, 2, 0, 106, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 109, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 117, 1, 0, 0, 218, 1, -0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 118, 1, 0, 0, 117, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 118, 1, 0, 0, 57, 0, 5, 0, 3, 0, 0, 0, 120, 1, 0, 0, 106, 0, 0, 0, 115, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 120, 1, -0, 0, 249, 0, 2, 0, 107, 1, 0, 0, 248, 0, 2, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 127, 1, -0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 131, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 131, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 129, 1, -0, 0, 248, 0, 2, 0, 132, 1, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 133, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 157, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 148, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, -0, 0, 144, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 151, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 152, 1, 0, 0, 151, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 153, 1, 0, 0, 36, 0, 0, 0, 86, 0, -5, 0, 154, 1, 0, 0, 155, 1, 0, 0, 153, 1, 0, 0, 144, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 156, 1, 0, 0, 155, 1, 0, 0, 152, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 156, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 159, 1, -0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 1, 0, 0, 159, 1, 0, 0, 180, 0, 5, 0, 7, 0, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 161, 1, 0, 0, 247, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 162, 1, -0, 0, 165, 1, 0, 0, 166, 1, 0, 0, 248, 0, 2, 0, 165, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 167, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 167, 1, 0, 0, 249, 0, 2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 166, 1, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 168, 1, 0, 0, 133, 1, 0, 0, 79, 0, 9, 0, 3, 0, 0, 0, 169, 1, 0, 0, 168, 1, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 169, 1, 0, 0, 249, 0, -2, 0, 164, 1, 0, 0, 248, 0, 2, 0, 164, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 170, 1, 0, 0, 163, 1, 0, 0, 62, 0, 3, 0, 157, 1, 0, 0, 170, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 171, 1, 0, 0, 157, 1, 0, 0, 65, 0, 5, 0, 2, 0, -0, 0, 173, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 174, 1, 0, 0, 173, 1, 0, 0, 133, 0, 5, 0, 3, 0, 0, 0, 175, 1, 0, 0, 171, 1, 0, 0, 174, 1, 0, 0, 254, 0, 2, 0, 175, 1, 0, 0, 56, 0, 1, 0, 54, 0, -5, 0, 28, 0, 0, 0, 189, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 190, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 191, 1, 0, 0, 188, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 193, 1, 0, 0, 178, 1, 0, 0, 62, 0, -3, 0, 191, 1, 0, 0, 193, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 194, 1, 0, 0, 188, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 196, 1, 0, 0, 180, 1, 0, 0, 62, 0, 3, 0, 194, 1, 0, 0, 196, 1, 0, 0, 65, 0, 5, 0, 17, 0, -0, 0, 197, 1, 0, 0, 188, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 199, 1, 0, 0, 182, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 200, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 2, 0, -0, 0, 201, 1, 0, 0, 188, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 203, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 176, 1, 0, 0, 203, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 219, 1, 0, 0, 0, 0, -0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 221, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 222, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 222, 1, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 223, 1, 0, 0, 218, 1, 0, 0, 195, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 224, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 225, 1, 0, 0, 218, 1, 0, 0, 198, 1, -0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 226, 1, 0, 0, 209, 1, 0, 0, 62, 0, 3, 0, 225, 1, 0, 0, 226, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 227, 1, 0, 0, 218, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 229, 1, 0, 0, 211, 1, -0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 229, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 230, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 231, 1, 0, 0, 218, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 232, 1, 0, 0, 231, 1, -0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 233, 1, 0, 0, 218, 1, 0, 0, 192, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 62, 0, 3, 0, 206, 1, 0, 0, 234, 1, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 235, 1, 0, 0, 218, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 17, 0, 0, 0, 237, 1, 0, 0, 218, 1, 0, 0, 228, 1, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 238, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, +200, 72, 40, 130, 97, 40, 68, 244, 198, 74, 215, 249, 17, 3, 174, 184, 0, 28, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, +117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, +83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, +0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, +0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, +0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, +0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, +99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, +49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, +0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, +0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, +53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, +0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, +97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, +67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, +95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, +0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, +0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, +62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, +0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, +0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, +0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, +0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, +0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, +62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, +0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, +116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, +67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, +0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, +0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, +87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, +0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, +0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, +0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, +0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, +0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, +0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, +60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, +0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, +0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, +0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, +0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, +0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, +0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, +0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, +0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, +0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, +0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, +0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, +0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, +0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, +0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, +0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, +0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, +0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, +0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, +0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, +0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, +0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, +0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, +0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, +0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, +0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, +0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, +0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, +0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, +0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, +0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, +0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, +0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, +0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, +0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 200, 72, 40, 130, 97, 40, 68, 244, 198, 74, 215, 249, 17, 3, 174, 184, 0, 28, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, +83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, +4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, +86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, +7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, +115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, +116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, +5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, +109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, +121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, +95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, +0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, +5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, +27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, +68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, +46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, +101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, +139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, +171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, +101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, +189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, +116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, +105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, +194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, +0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, +196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, +197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, +208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, +215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, +5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, +122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, +227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, +100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, +117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, +79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, +192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, +3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, +30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, +82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, +3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, +71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, +22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, +8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, +31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, +42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, +69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, +121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, +5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, +153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, +178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, +43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, +43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, +41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, +4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, +173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, +238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, +188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, +214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, +219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, +228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, +135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, +127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, +165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, +168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, +81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, +177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, +153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, +110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, +228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, +126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, +157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, +62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, +167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, +173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, +177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, +202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, +190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, +57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, +253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, +232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, +234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, +228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, +228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, +244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, +246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, +0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index 089ea0062b..e3408d801c 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -16,54 +16,62 @@ namespace Stride.Graphics internal partial class SignedDistanceFieldFontShader { private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, -0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, -115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, -145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, -0, 0, 0, 1, 125, 88, 83, 2, 94, 238, 0, 19, 148, 66, 98, 180, 14, 94, 118, 244, 0, 176, 95, 0, 0, 68, 88, 66, 67, 234, 61, 7, 31, 101, 34, 14, 190, 178, 159, 132, 236, 216, 125, 176, 95, 1, 0, 0, 0, 176, 95, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, -0, 248, 7, 0, 0, 0, 94, 0, 0, 124, 94, 0, 0, 48, 95, 0, 0, 124, 95, 0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, -0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, 85, 71, 40, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, -115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, -114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, -0, 107, 0, 0, 0, 252, 3, 0, 0, 77, 0, 0, 0, 12, 4, 0, 0, 77, 0, 0, 0, 28, 4, 0, 0, 77, 0, 0, 0, 48, 4, 0, 0, 77, 0, 0, 0, 64, 4, 0, 0, 89, 0, 0, 0, 80, 4, 0, 0, 90, 0, 0, 0, 96, 4, 0, 0, 90, 0, 0, 0, 108, 4, 0, -0, 90, 0, 0, 0, 120, 4, 0, 0, 90, 0, 0, 0, 132, 4, 0, 0, 91, 0, 0, 0, 148, 4, 0, 0, 91, 0, 0, 0, 168, 4, 0, 0, 91, 0, 0, 0, 184, 4, 0, 0, 91, 0, 0, 0, 196, 4, 0, 0, 91, 0, 0, 0, 212, 4, 0, 0, 91, 0, 0, 0, 232, 4, 0, -0, 91, 0, 0, 0, 248, 4, 0, 0, 92, 0, 0, 0, 8, 5, 0, 0, 101, 0, 0, 0, 24, 5, 0, 0, 101, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, -171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, -0, 0, 0, 0, 0, 145, 1, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 180, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, -0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, -101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, -0, 0, 0, 1, 0, 2, 0, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -0, 132, 2, 0, 0, 148, 2, 0, 0, 164, 2, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 176, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, -0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 8, 2, 0, 0, 42, 2, 0, 0, 164, 1, 0, -0, 1, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 108, 2, 0, 0, 140, 1, 0, 0, 120, 2, 0, 0, 192, 2, 0, 0, 2, 0, 0, -0, 208, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, -63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, -160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, -128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, -2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, -2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, -3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, -82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, -0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, -0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, -5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, -0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, -0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, -0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, -0, 43, 0, 0, 0, 208, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, +97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, +82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 50, 8, 209, 221, 98, 193, 223, 53, 243, 31, 139, 209, 84, 54, 55, +86, 0, 176, 87, 0, 0, 68, 88, 66, 67, 98, 159, 90, 215, 158, 11, 173, 17, 253, 227, 224, 246, 170, 132, 82, 120, 1, 0, 0, 0, 176, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, 0, 248, 7, 0, 0, 0, 86, 0, 0, 124, 86, 0, 0, 48, 87, 0, 0, 124, 87, +0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, 85, 71, 40, 0, +0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, +110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 70, 49, 48, +48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 93, 0, 0, 0, 252, 3, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 63, 0, +0, 0, 28, 4, 0, 0, 63, 0, 0, 0, 48, 4, 0, 0, 63, 0, 0, 0, 64, 4, 0, 0, 75, 0, 0, 0, 80, 4, 0, 0, 76, 0, 0, 0, 96, 4, 0, 0, 76, 0, 0, 0, 108, 4, 0, 0, 76, 0, 0, 0, 120, 4, 0, 0, 76, 0, 0, 0, 132, 4, 0, 0, 77, 0, +0, 0, 148, 4, 0, 0, 77, 0, 0, 0, 168, 4, 0, 0, 77, 0, 0, 0, 184, 4, 0, 0, 77, 0, 0, 0, 196, 4, 0, 0, 77, 0, 0, 0, 212, 4, 0, 0, 77, 0, 0, 0, 232, 4, 0, 0, 77, 0, 0, 0, 248, 4, 0, 0, 78, 0, 0, 0, 8, 5, 0, 0, 87, 0, +0, 0, 24, 5, 0, 0, 87, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, +0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 145, 1, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, +4, 0, 1, 0, 1, 0, 180, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, +3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, +116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 132, 2, 0, 0, 148, 2, 0, 0, 164, 2, 0, 0, 164, 1, 0, 0, 5, 0, +0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 176, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, +0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 8, 2, 0, 0, 42, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 224, 1, +0, 0, 1, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 108, 2, 0, 0, 140, 1, 0, 0, 120, 2, 0, 0, 192, 2, 0, 0, 2, 0, 0, 0, 208, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, +72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, +64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, +0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, +255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, +170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, +85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, +1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, +16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, +0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, +0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, +16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, +0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, +16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, +128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, +0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, +0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, +68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -71,7 +79,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -79,7 +87,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -87,7 +95,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -95,303 +103,271 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 6, 110, 186, 185, 67, 77, 136, 76, 150, 95, 43, 175, 255, 79, 135, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 88, 150, 35, 61, 119, 137, 217, 67, 166, 47, 24, 91, 29, 8, 149, 92, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, +51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, -117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, -99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, -0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 20, 41, 3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 113, 232, 0, 0, 118, 213, 0, 0, 118, 199, 0, 0, 101, 128, 0, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, +0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, +116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, +32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, +110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, +95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 20, 41, +3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 124, 125, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 138, 227, 2, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, -10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, -71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, -58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, -40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, -95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, -120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, -101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, -116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, -115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, -101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, -114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, -101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, -108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, -101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, -50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, -105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, -100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 51, 44, 32, 95, 49, 52, 54, 44, 32, 95, 49, 53, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, -32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, -103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, -116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, -32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, -32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, -111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, -32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, -43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, -44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, -101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, -102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, -111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, -77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, -101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 48, 32, 61, 32, 115, -105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 95, 50, 57, 54, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 57, 56, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 48, 44, 32, 95, 50, 57, 50, 44, 32, 95, 50, 57, 54, 44, 32, 95, 50, -57, 56, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, -105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, -95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, -115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, -116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 15, 16, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, -110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, -56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, -111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 55, 57, 100, 57, 56, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, -84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 197, 91, 71, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 49, 91, 79, 162, 84, 15, 0, -0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, -32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, -115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 216, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, -0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, -0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, -0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, -17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 212, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, -5, 13, 43, 11, 96, 4, 129, 248, 8, 0, 13, 42, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 208, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 68, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 67, 1, 80, 12, 129, 248, 0, 0, 54, 0, 77, -17, 60, 2, 0, 0, 204, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 98, 11, 32, 13, 76, 6, 14, 12, 129, 212, 36, 8, 0, 9, 34, 13, 97, 1, 80, 6, 15, 3, 0, 9, 19, 13, 75, 6, 14, 12, 129, 212, 36, 0, 0, 58, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, -105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, -0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 8, 0, 0, 0, 110, 0, 77, 17, 100, 2, 0, -0, 200, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, -21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, -116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, -0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, -0, 16, 1, 157, 6, 247, 135, 167, 84, 62, 45, 200, 204, 20, 87, 58, 78, 147, 156, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 135, 0, 0, 128, 80, 0, 0, -0, 135, 0, 0, 0, 116, 0, 0, 0, 135, 0, 0, 128, 116, 0, 0, 0, 135, 0, 0, 0, 144, 0, 0, 0, 135, 0, 0, 128, 144, 0, 0, 0, 135, 0, 0, 0, 172, 0, 0, 0, 135, 0, 0, 128, 172, 0, 0, 0, 135, 0, 0, 0, 200, 0, 0, 0, 135, 0, 0, 128, 200, 0, 0, -0, 135, 0, 0, 0, 228, 0, 0, 0, 135, 0, 0, 128, 228, 0, 0, 0, 135, 0, 0, 0, 248, 0, 0, 0, 135, 0, 0, 128, 248, 0, 0, 0, 135, 0, 0, 0, 12, 1, 0, 0, 135, 0, 0, 128, 12, 1, 0, 0, 135, 0, 0, 0, 48, 1, 0, 0, 135, 0, 0, 128, 48, 1, 0, -0, 135, 0, 0, 0, 84, 1, 0, 0, 135, 0, 0, 128, 84, 1, 0, 0, 135, 0, 0, 0, 112, 1, 0, 0, 135, 0, 0, 128, 112, 1, 0, 0, 135, 0, 0, 0, 152, 1, 0, 0, 135, 0, 0, 128, 152, 1, 0, 0, 135, 0, 0, 0, 180, 1, 0, 0, 135, 0, 0, 128, 180, 1, 0, -0, 135, 0, 0, 0, 216, 1, 0, 0, 135, 0, 0, 128, 216, 1, 0, 0, 135, 0, 0, 0, 244, 1, 0, 0, 135, 0, 0, 128, 244, 1, 0, 0, 135, 0, 0, 0, 16, 2, 0, 0, 135, 0, 0, 128, 16, 2, 0, 0, 135, 0, 0, 0, 44, 2, 0, 0, 135, 0, 0, 128, 44, 2, 0, -0, 135, 0, 0, 0, 72, 2, 0, 0, 138, 0, 0, 128, 72, 2, 0, 0, 138, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, -0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, -0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 1, 16, 0, -0, 0, 0, 0, 0, 119, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 106, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, -21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 248, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, -0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, -241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, -0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, -83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, -21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, -0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, -0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, -0, 3, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, +95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, +116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 32, +83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, +114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, +120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, +98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, +48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, +121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, +115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, +104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, +111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, +121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, +99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, +105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, +110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, +114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, +116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, +114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, +40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, +10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, +103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, +44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 55, +32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 95, 51, 48, 51, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 53, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 55, 44, 32, 95, 50, 57, 57, 44, 32, 95, 51, 48, 51, +44, 32, 95, 51, 48, 53, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, +80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, +97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, +110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, +97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, +61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, -108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, -115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, -116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, -110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, -105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, -116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, -97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, -116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, -32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, -57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, -115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, -114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, -32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 51, 44, 32, 95, 49, 52, 54, 44, 32, 95, 49, 53, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, -68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, -100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, -109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, -105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, -97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, -103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, -76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, -100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, -111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, -108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, -114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, -10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, -114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, -57, 48, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 54, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 57, 56, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 48, 44, 32, 95, 50, 57, 50, 44, 32, 95, 50, -57, 54, 44, 32, 95, 50, 57, 56, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, -114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, -83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, -32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, -103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, -32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, -94, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, +83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 70, 49, 48, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, +117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, +50, 51, 102, 48, 52, 52, 102, 102, 49, 48, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, +83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 79, 33, 58, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 43, 119, 102, 243, 235, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, +109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, +108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 216, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, +0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, +252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, +4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, +62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 212, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 43, 11, 96, 4, 129, 248, 8, 0, 13, 42, 1, 80, 12, 129, 248, 0, 0, +0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 208, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 68, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 67, 1, 80, 12, 129, 248, 0, 0, 54, 0, 77, 17, 60, 2, 0, 0, 204, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 98, +11, 32, 13, 76, 6, 14, 12, 129, 212, 36, 8, 0, 9, 34, 13, 97, 1, 80, 6, 15, 3, 0, 9, 19, 13, 75, 6, 14, 12, 129, 212, 36, 0, 0, 58, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, +4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 8, 0, 0, 0, 110, 0, 77, 17, 100, 2, 0, 0, 200, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, +13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, +6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, 0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, +36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, +105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, +0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 239, 201, 134, 38, 233, 252, 116, 41, 62, 121, 173, 120, 77, 98, 3, 4, +0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 121, 0, 0, 128, 80, 0, 0, 0, 121, 0, 0, 0, 116, 0, 0, 0, 121, 0, 0, 128, 116, 0, 0, 0, 121, 0, +0, 0, 144, 0, 0, 0, 121, 0, 0, 128, 144, 0, 0, 0, 121, 0, 0, 0, 172, 0, 0, 0, 121, 0, 0, 128, 172, 0, 0, 0, 121, 0, 0, 0, 200, 0, 0, 0, 121, 0, 0, 128, 200, 0, 0, 0, 121, 0, 0, 0, 228, 0, 0, 0, 121, 0, 0, 128, 228, 0, 0, 0, 121, 0, +0, 0, 248, 0, 0, 0, 121, 0, 0, 128, 248, 0, 0, 0, 121, 0, 0, 0, 12, 1, 0, 0, 121, 0, 0, 128, 12, 1, 0, 0, 121, 0, 0, 0, 48, 1, 0, 0, 121, 0, 0, 128, 48, 1, 0, 0, 121, 0, 0, 0, 84, 1, 0, 0, 121, 0, 0, 128, 84, 1, 0, 0, 121, 0, +0, 0, 112, 1, 0, 0, 121, 0, 0, 128, 112, 1, 0, 0, 121, 0, 0, 0, 152, 1, 0, 0, 121, 0, 0, 128, 152, 1, 0, 0, 121, 0, 0, 0, 180, 1, 0, 0, 121, 0, 0, 128, 180, 1, 0, 0, 121, 0, 0, 0, 216, 1, 0, 0, 121, 0, 0, 128, 216, 1, 0, 0, 121, 0, +0, 0, 244, 1, 0, 0, 121, 0, 0, 128, 244, 1, 0, 0, 121, 0, 0, 0, 16, 2, 0, 0, 121, 0, 0, 128, 16, 2, 0, 0, 121, 0, 0, 0, 44, 2, 0, 0, 121, 0, 0, 128, 44, 2, 0, 0, 121, 0, 0, 0, 72, 2, 0, 0, 124, 0, 0, 128, 72, 2, 0, 0, 124, 0, +0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 92, 0, +0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, -0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, -83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, -241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 248, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 22, 0, +27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, +5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, +1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, +8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, +0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, +1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, -96, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, -83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, -241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, +102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, +123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, +97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, +123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, +48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, +107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, +67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, +99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, +32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, +32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, +111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, +68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, +114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, +116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, +112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, +101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, +61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, +108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, +109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, +44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 95, 50, 57, 55, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 51, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 53, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 55, 44, 32, 95, 50, 57, 57, +44, 32, 95, 51, 48, 51, 44, 32, 95, 51, 48, 53, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, +104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, +70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, +114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, +101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, +32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, +32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, +93, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, +1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, +80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, +1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, +1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, +80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, +1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, -255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, +0, 0, 38, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, -0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, -104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 55, 57, 68, 57, 56, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 6, 110, 186, 185, 67, 77, 136, 76, 150, 95, 43, 175, 255, 79, 135, 4, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, -102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, -110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 55, 57, 100, 57, 56, -56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 48, 2, 0, 0, 111, 1, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 63, 16, 0, 0, 128, 0, 0, 0, 84, 15, 0, -0, 36, 7, 0, 0, 108, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 39, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 38, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, -0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, -0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 0, 0, 37, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, 0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, +255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, +101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, +70, 70, 49, 48, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 88, 150, 35, 61, 119, 137, 217, 67, 166, 47, 24, 91, 29, 8, 149, 92, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, +101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, +115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 102, 49, 48, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, +0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 48, 2, 0, 0, 111, 1, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 214, 13, 0, 0, 128, 0, 0, 0, 235, 12, 0, 0, 36, 7, 0, 0, 108, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 56, 2, +0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, +0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, +0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -399,37 +375,37 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, -110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, -32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, -84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 123, 111, 206, 225, 51, 58, 230, 97, 249, 76, 255, 62, 18, 93, 50, 252, 0, 100, 75, 0, 0, 68, 88, 66, 67, 56, 98, 251, 155, 244, 209, 89, 251, 28, 236, 68, 226, 166, 43, 88, 150, 1, 0, 0, 0, 100, 75, 0, -0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 73, 0, 0, 56, 74, 0, 0, 132, 74, 0, 0, 244, 74, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, -0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, -0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, -101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 95, 0, 0, -0, 112, 2, 0, 0, 97, 0, 0, 0, 132, 2, 0, 0, 99, 0, 0, 0, 144, 2, 0, 0, 95, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, -0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, -0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, -0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, -171, 120, 1, 0, 0, 216, 0, 0, 0, 135, 1, 0, 0, 248, 0, 0, 0, 150, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, -0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 0, 0, 0, 0, 192, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 1, 0, 0, 192, 0, 0, 0, 108, 1, 0, 0, 188, 1, 0, 0, 3, 0, 0, 0, 204, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, -82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, -144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, -82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, -3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, -0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, -0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, +103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, +0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, +171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 186, 156, 53, +68, 143, 7, 48, 178, 195, 41, 116, 176, 193, 11, 48, 143, 0, 100, 67, 0, 0, 68, 88, 66, 67, 233, 43, 140, 116, 146, 209, 173, 70, 16, 70, 204, 229, 50, 153, 24, 50, 1, 0, 0, 0, 100, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 65, +0, 0, 56, 66, 0, 0, 132, 66, 0, 0, 244, 66, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, +254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, +115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, +48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 80, 0, 0, 0, 112, 2, 0, 0, 82, 0, 0, 0, 132, 2, 0, 0, 84, 0, 0, 0, 144, 2, +0, 0, 80, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, +171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, +3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, +116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 120, 1, 0, 0, 216, 0, 0, 0, 135, 1, 0, 0, 248, 0, 0, 0, 150, 1, +0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 0, 0, 0, 0, 192, 0, +0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 1, 0, 0, 192, 0, 0, 0, 108, 1, 0, 0, 188, 1, 0, 0, 3, 0, 0, 0, 204, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, +105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, +228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, 0, 0, 95, 0, 0, 3, 50, 16, +16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, +0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, +0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 0, 0, +0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -437,7 +413,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -445,7 +421,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -453,7 +429,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -461,160 +437,137 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 107, 188, 61, 33, 59, 10, 94, 66, 176, 171, 178, 210, 106, 247, 64, 6, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 240, 56, 223, 166, 13, 104, 110, 77, 178, 48, 203, 74, 118, 108, 166, 216, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, -117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, -107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, -101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, -0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, +32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, +79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, -79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, -99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, -120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, -99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, -99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, -58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, -10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, -101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, -59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, -97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, -41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, -116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 43, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, -99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, -52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, -57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 97, 48, 98, 55, 48, 50, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 212, 5, 75, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, -1, 191, 137, 74, 219, 112, 9, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, +97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, +78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, +111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, +32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, +110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, 118, 111, 105, +100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, +120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, +116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, +105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, +111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, +117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 193, 7, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, +114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, +116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, +64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 55, 49, 99, 49, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 160, 164, 61, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 37, 43, 96, 147, 6, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, -105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, -84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, -0, 64, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, -0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, -0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, -0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, -0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, -0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, -17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, -0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, -0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 133, 63, 204, 184, 201, 98, 73, 178, 223, -206, 130, 141, 56, 171, 235, 204, 0, 0, 242, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 105, 0, 0, 128, 84, 0, 0, 0, 105, 0, 0, 0, 104, 0, 0, 0, 105, 0, 0, -128, 104, 0, 0, 0, 105, 0, 0, 0, 124, 0, 0, 0, 105, 0, 0, 128, 124, 0, 0, 0, 105, 0, 0, 0, 144, 0, 0, 0, 105, 0, 0, 128, 144, 0, 0, 0, 105, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, -0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 80, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, -0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, -108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, -110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, -110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, -83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, -115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, +104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, +95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, +110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, +4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, +64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, +4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, +117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 84, 0, +0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 254, 226, 66, 242, 228, 132, 125, 7, 121, 105, 10, 74, 59, 30, 74, 161, 0, 0, 242, 0, 0, 0, 120, 0, 0, 0, 0, 0, +0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 90, 0, 0, 128, 84, 0, 0, 0, 90, 0, 0, 0, 104, 0, 0, 0, 90, 0, 0, 128, 104, 0, 0, 0, 90, 0, 0, 0, 124, 0, 0, 0, 90, 0, 0, 128, 124, 0, +0, 0, 90, 0, 0, 0, 144, 0, 0, 0, 90, 0, 0, 128, 144, 0, 0, 0, 90, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 80, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, +0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, +0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, +83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, +3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, +0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, -41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, -84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, -112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, -67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, -116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, -77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, -118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, -95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, -105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, -116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, -115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, -86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, -95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, -108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, +115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, +95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, +95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, +101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -628,52 +581,47 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, -255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, -255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, -0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 2, 0, 9, 0, 8, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, -96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, -0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, -101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 65, 48, 66, 55, 48, 50, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 205, 180, 142, 105, 1, 0, 0, 0, 107, 188, 61, 33, 59, 10, 94, 66, 176, 171, 178, 210, 106, 247, 64, 6, 137, 0, 0, -0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, -99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, -52, 50, 97, 48, 98, 55, 48, 50, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, -0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 8, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, +0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, +115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, +48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 240, 56, 223, 166, 13, 104, 110, 77, 178, 48, 203, 74, 118, 108, 166, 216, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, +115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, +114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 55, 49, 99, 49, 97, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, +0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 136, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 91, 10, 0, -0, 128, 0, 0, 0, 112, 9, 0, 0, 188, 3, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 18, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, -0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, -0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 136, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 241, 7, 0, 0, 128, 0, 0, 0, 6, 7, 0, 0, 188, 3, 0, 0, 44, 0, 0, 0, 0, 0, +0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 25, 0, 0, 0, 17, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, +0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -697,18 +645,13 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, -0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, -0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, -105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, +32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, +67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs index 4311a428cf..5d6c8f55fa 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -16,99 +16,86 @@ namespace Stride.Graphics internal partial class SignedDistanceFieldFontShader { private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, -57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 155, 120, 66, 107, 24, 37, 183, 215, 254, 65, 187, 5, 119, 92, 146, 66, 0, 180, 9, -0, 0, 68, 88, 66, 67, 231, 29, 8, 161, 222, 96, 65, 162, 167, 250, 97, 230, 191, 32, 140, 110, 1, 0, 0, 0, 180, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 192, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, -0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 216, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, -0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 68, 88, 73, 76, 236, 7, 0, 0, 96, 0, 0, 0, 251, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 212, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 242, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, -4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, -24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, -96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 99, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 5, 0, 0, 0, 192, -29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, -57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, -0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, -0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 66, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 1, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 160, 24, 11, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 48, 16, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, -160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, -7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, -7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, -200, 99, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 46, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, -128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 43, 164, 50, 34, 0, 0, 0, 128, 49, 130, -214, 156, 115, 246, 23, 136, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 8, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 34, 0, 0, 0, 40, 7, 2, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 8, 0, 0, 0, 74, -129, 26, 0, 0, 0, 74, 162, 16, 10, 4, 0, 0, 0, 0, 121, 24, 0, 0, 120, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 144, 9, 194, 112, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 201, 4, 129, 80, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 99, 97, 68, -85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 12, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 209, 76, 16, 20, 103, 130, 64, 60, 27, 132, 192, 217, 144, 4, 202, -18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 1, 109, 16, 8, 138, 2, 220, -220, 4, 129, 232, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 166, 12, 38, 8, 141, 180, 33, 8, 38, 8, 13, 181, 97, 9, 196, -96, 12, 200, 160, 12, 204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 204, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 132, 51, 80, 3, 38, 83, 86, 95, 84, 97, 114, 103, 101, 116, 19, 132, 230, 12, 54, 44, 1, 27, 140, 65, 27, 148, 1, 25, 16, -105, 16, 144, 1, 176, 33, 112, 131, 13, 195, 26, 188, 1, 64, 54, 152, 74, 59, 115, 43, 35, 35, 74, 155, 163, 11, 115, 27, 43, 51, 74, 43, 99, 35, 51, 122, 115, 163, 155, 66, 11, 35, 43, 147, 115, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 113, 0, -7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, 202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, -69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, 151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 65, 28, 0, 113, 32, 0, 0, 33, 0, 0, 0, 6, 192, -6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 159, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 210, 112, 249, 206, 227, 11, 17, 1, 76, 68, 8, 52, -195, 66, 216, 0, 52, 92, 190, 243, 248, 18, 192, 60, 11, 225, 23, 183, 109, 4, 208, 112, 249, 206, 227, 7, 72, 3, 68, 152, 95, 220, 182, 21, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 155, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, -0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 103, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, 24, 56, 104, 144, 133, 65, 24, 88, 216, 136, 65, 2, 128, 32, 24, 56, 105, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 106, 176, -137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 107, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 108, 208, 145, 65, 25, 96, 220, 136, 65, 2, 128, 32, 24, 68, 108, 128, 101, 102, 96, 6, 96, 48, 98, 144, 0, 32, 8, 6, 81, 27, 100, 221, 25, 156, 65, 24, 140, 24, -60, 0, 8, 130, 193, 212, 6, 88, 32, 32, 71, 150, 125, 223, 151, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 140, 24, 28, 0, 8, 130, 1, 21, 7, 28, 49, 140, 24, 28, 0, 8, 130, 1, 37, 7, 92, 65, 140, 24, 28, 0, 8, 130, 1, 53, 7, 94, 64, 140, 24, -28, 0, 8, 130, 1, 69, 7, 222, 16, 88, 224, 65, 96, 196, 192, 0, 64, 16, 12, 170, 58, 240, 130, 17, 3, 3, 0, 65, 48, 168, 236, 192, 11, 70, 12, 12, 0, 4, 193, 160, 186, 3, 111, 24, 49, 48, 0, 16, 4, 131, 10, 15, 192, 32, 176, 96, 128, 128, 5, 96, 32, 1, 19, 62, -9, 24, 34, 64, 192, 2, 129, 2, 35, 6, 6, 0, 130, 96, 80, 249, 65, 24, 4, 22, 6, 129, 4, 44, 40, 3, 8, 216, 16, 72, 192, 136, 64, 2, 22, 4, 18, 176, 47, 144, 128, 125, 130, 4, 236, 27, 36, 96, 31, 33, 129, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, -246, 128, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 65, 15, 134, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 242, 64, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 1, 15, 2, 4, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 88, 60, 223, -63, 124, 199, 114, 208, 220, 100, 142, 71, 141, 94, 33, 63, 0, 201, 7, 0, 0, 68, 88, 66, 67, 232, 45, 32, 27, 33, 167, 79, 198, 224, 161, 134, 23, 150, 228, 74, 190, 1, 0, 0, 0, 201, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, -0, 0, 125, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, -0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 24, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, -0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 68, 5, 0, 0, 96, 0, 1, 0, 81, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 44, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 72, 1, 0, 0, 11, 130, 32, 0, 2, -0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, -33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, -130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 34, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 192, 204, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, -4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 138, 81, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, -0, 64, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 64, 6, 0, 0, 0, 3, 1, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, -14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, -122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, -0, 0, 0, 0, 134, 60, 9, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 16, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 128, 66, 152, 1, 160, 3, -0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 133, 98, 160, 3, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 107, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 136, 9, 194, 48, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 197, 4, 129, 48, -54, 32, 129, 48, 4, 1, 81, 0, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, 152, 49, 25, 152, 148, 13, 193, 177, 65, 32, 130, 9, 2, 113, 108, 16, 8, -133, 130, 221, 220, 4, 129, 120, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 65, 1, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 3, 154, 32, 28, 201, 134, 32, 152, 32, 28, 203, 134, 37, 176, 46, 44, 195, 8, -45, 192, 128, 13, 1, 49, 65, 56, 162, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 162, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 13, 195, 230, 133, 193, 134, 37, 176, 46, 44, 211, 8, 45, 192, 128, 13, 11, 97, 93, 24, 167, 17, 29, 129, 1, 92, 166, 172, -190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 7, 179, 97, 249, 202, 224, 50, 131, 172, 35, 186, 15, 3, 54, 12, 99, 64, 6, 103, 176, 97, 16, 3, 52, 0, 200, 6, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, -100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 72, 13, 210, 0, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 142, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 164, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, -64, 169, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 104, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 158, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 2, 170, 14, 25, 158, 75, 153, 27, 157, -92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 13, 0, 0, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 255, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, -60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 97, 32, 0, 0, 60, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 209, 226, 56, 137, 50, 98, 144, 0, 32, 8, 6, 136, 196, 60, 79, -178, 140, 24, 36, 0, 8, 130, 1, 50, 53, 15, 180, 48, 35, 6, 9, 0, 130, 96, 128, 80, 14, 20, 45, 205, 136, 65, 2, 128, 32, 24, 32, 213, 19, 73, 139, 51, 98, 144, 0, 32, 8, 6, 136, 5, 73, 211, 242, 140, 24, 36, 0, 8, 130, 1, 114, 69, 11, 245, 64, 35, 6, 9, 0, -130, 96, 128, 96, 18, 83, 61, 209, 136, 65, 2, 128, 32, 24, 32, 217, 212, 88, 143, 52, 98, 144, 0, 32, 8, 6, 136, 70, 57, 215, 51, 141, 24, 36, 0, 8, 130, 65, 162, 57, 15, 54, 33, 35, 6, 9, 0, 130, 96, 144, 104, 206, 131, 73, 199, 136, 65, 2, 128, 32, 24, 36, 154, 243, -96, 145, 49, 98, 144, 0, 32, 8, 6, 137, 230, 60, 24, 84, 140, 24, 36, 0, 8, 130, 65, 162, 57, 24, 54, 41, 35, 6, 9, 0, 130, 96, 144, 104, 14, 134, 73, 201, 136, 65, 2, 128, 32, 24, 36, 154, 115, 97, 19, 49, 98, 144, 0, 32, 8, 6, 137, 230, 92, 152, 52, 140, 24, 36, -0, 8, 130, 65, 162, 57, 23, 22, 9, 35, 6, 9, 0, 130, 96, 144, 104, 206, 133, 65, 1, 2, 0, 0, 0, 0, 0, 1, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, +101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, +239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, +0, 0, 1, 78, 45, 129, 4, 69, 150, 26, 206, 173, 86, 103, 253, 74, 248, 95, 173, 0, 92, 9, 0, 0, 68, 88, 66, 67, 82, 32, 71, 205, 2, 201, 188, 247, 239, 236, 190, 108, 196, 241, 77, 4, 1, 0, 0, 0, 92, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, +166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, +0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, +71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 200, 0, 0, 0, +36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 164, 7, 0, 0, 96, 0, 0, 0, 233, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 140, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 224, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, +7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, +66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, +3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 96, 205, 17, +128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, +24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, +0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, +72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, +0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, +109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, +96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, +16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, 51, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, +8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, +25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 104, 0, 0, 0, 96, 140, 64, +103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, 162, 16, 10, 4, 0, 121, 24, 0, 0, 110, 0, 0, 0, 26, 3, 76, 144, +70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, +192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, +38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 50, 6, 19, 4, 5, 218, 16, 4, 19, +4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 82, 6, 27, 150, 224, 12, 60, 52, 0, 131, 143, 32, 131, +224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 200, 6, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, 13, 214, 224, 2, +170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, +205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, 128, 13, 0, 0, 113, 32, 0, 0, 33, 0, 0, 0, 6, 192, 6, 44, +98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 159, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 210, 112, 249, 206, 227, 11, 17, 1, 76, 68, 8, 52, 195, 66, +216, 0, 52, 92, 190, 243, 248, 18, 192, 60, 11, 225, 23, 183, 109, 4, 208, 112, 249, 206, 227, 7, 72, 3, 68, 152, 95, 220, 182, 21, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 155, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 0, 0, +97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, 97, 128, 105, 35, +6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, 1, 150, 145, 1, 25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, 32, 8, 6, 208, +26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, 98, 112, 0, 32, 8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, 32, 8, 6, 145, +28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, 14, 188, 97, 196, 192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, 136, 0, 1, 11, +4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, 246, 9, 18, 176, 111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, 98, 196, 32, 1, +64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 155, 241, 82, 41, 74, +209, 136, 53, 172, 71, 81, 139, 220, 76, 49, 17, 0, 97, 7, 0, 0, 68, 88, 66, 67, 142, 41, 74, 179, 176, 33, 67, 173, 13, 207, 191, 178, 146, 233, 121, 65, 1, 0, 0, 0, 97, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, +105, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, +0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, +0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, +0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 240, 4, 0, +0, 96, 0, 1, 0, 60, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 216, 4, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 51, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, +12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, +0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, +144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, 0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, +16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, 0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, +14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, +116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 16, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, +24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, 34, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 92, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, +155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 161, 217, 48, 32, 9, +49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 112, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 103, 195, 50, 64, 145, 100, 73, 195, 53, 72, +192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 13, 67, 133, 109, 27, 22, 2, 138, 164, 137, 26, 40, 66, 2, 54, 44, 3, 20, 73, 22, 53, 92, 131, 4, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 16, 202, 134, 37, 251, 34, 48, 152, 174, +225, 202, 36, 96, 195, 208, 121, 97, 176, 97, 224, 196, 0, 32, 27, 76, 165, 157, 185, 149, 145, 17, 165, 205, 209, 133, 185, 141, 149, 25, 165, 149, 177, 145, 25, 189, 185, 209, 77, 161, 133, 145, 149, 201, 185, 88, 77, 53, 133, 165, 185, 125, 93, 201, 133, 193, 193, 149, 201, 109, 40, 22, 50, 24, +3, 0, 168, 194, 198, 102, 215, 230, 146, 70, 86, 230, 70, 55, 37, 8, 170, 144, 225, 185, 216, 149, 201, 205, 165, 189, 185, 77, 9, 136, 38, 100, 120, 46, 118, 97, 108, 118, 101, 114, 83, 2, 163, 14, 25, 158, 203, 28, 90, 24, 89, 153, 92, 211, 27, 89, 25, 219, 148, 32, 169, 68, 134, 231, +66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 112, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 200, 0, 113, 32, 0, 0, 18, 0, 0, 0, 6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, +51, 177, 7, 48, 16, 145, 255, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 97, 32, 0, 0, 60, 0, 0, 0, 19, 4, 193, +136, 65, 2, 128, 32, 24, 20, 15, 211, 52, 202, 50, 98, 144, 0, 32, 8, 6, 5, 212, 56, 142, 194, 140, 24, 36, 0, 8, 130, 65, 17, 57, 202, 195, 52, 35, 6, 9, 0, 130, 96, 80, 72, 207, 2, 49, 206, 136, 65, 2, 128, 32, 24, 20, 19, 196, 68, 203, 51, 98, 144, 0, 32, 8, +6, 5, 21, 53, 210, 2, 141, 24, 36, 0, 8, 130, 65, 81, 73, 203, 4, 69, 35, 6, 9, 0, 130, 96, 80, 88, 19, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 213, 84, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 57, 214, 67, 141, 24, 36, 0, 8, 130, 129, 129, 57, 207, 69, +33, 35, 6, 9, 0, 130, 96, 96, 96, 206, 115, 77, 199, 136, 65, 2, 128, 32, 24, 24, 152, 243, 92, 145, 49, 98, 144, 0, 32, 8, 6, 6, 230, 60, 23, 84, 140, 24, 36, 0, 8, 130, 129, 129, 57, 215, 69, 41, 35, 6, 9, 0, 130, 96, 96, 96, 206, 117, 77, 201, 136, 65, 2, 128, +32, 24, 24, 152, 35, 93, 20, 49, 98, 144, 0, 32, 8, 6, 6, 230, 72, 215, 52, 140, 24, 36, 0, 8, 130, 129, 129, 57, 210, 21, 9, 35, 6, 9, 0, 130, 96, 96, 96, 142, 116, 65, 1, 2, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 9e788c21cf..ea0392654d 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -16,290 +16,282 @@ namespace Stride.Graphics internal partial class SignedDistanceFieldFontShader { private static readonly byte[] signedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, -8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, -101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 0, 0, 0, -8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, -101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 56, 0, 0, 0, 8, 0, 0, 0, -1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, -114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, -117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, -69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, -57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 106, 241, 116, 115, 62, 248, 116, 0, 146, 201, 139, 213, 179, 227, 100, 215, 0, 128, 32, -0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 117, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, -0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 63, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 51, 1, 0, 0, 53, 1, 0, 0, 49, 1, 0, 0, 59, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 102, 1, 0, 0, 15, 0, 15, 0, 0, 0, -0, 0, 84, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 73, 1, 0, 0, 76, 1, 0, 0, 77, 1, 0, 0, 72, 1, 0, 0, 74, 1, 0, 0, 78, 1, 0, 0, 83, 1, 0, 0, 102, 1, 0, 0, 16, 0, 3, 0, 63, 1, 0, 0, 7, 0, -0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, -105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, -0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, -0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 105, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 106, 0, -0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 109, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -0, 0, 5, 0, 3, 0, 110, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 111, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 112, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 126, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -52, 0, 5, 0, 6, 0, 127, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 128, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, -114, 0, 5, 0, 6, 0, 130, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 136, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, -7, 0, 138, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 139, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 140, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, -99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 144, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 149, 0, 0, 0, 105, 110, 116, 95, 49, 0, -0, 0, 5, 0, 4, 0, 153, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 163, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 166, 0, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 168, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 180, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 177, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, -5, 0, 183, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 189, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 193, 0, -0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 178, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 223, 0, -0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 224, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 225, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, -83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 28, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 29, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 30, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 32, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 50, 1, 0, 0, 112, 116, 114, 95, 79, 117, -116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 49, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 52, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, -116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 51, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 54, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 53, 1, -0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 55, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 55, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 1, -0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 56, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 56, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 57, 1, -0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 57, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 57, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, -5, 0, 57, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 58, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 115, 116, 114, 101, 97, 109, -115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 60, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 61, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 62, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 14, 0, 63, 1, 0, 0, 83, 105, -103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 8, 0, 72, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 73, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 75, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, -0, 0, 5, 0, 6, 0, 74, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 76, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 77, 1, 0, 0, 105, 110, 95, 86, 83, 95, -67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 0, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 79, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 86, 83, -95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 80, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 80, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, -5, 0, 80, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 81, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 81, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 0, 6, 0, 6, 0, 81, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 81, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 81, 1, 0, 0, 3, 0, 0, 0, 67, 111, -108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 82, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 84, 1, -0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 91, 1, 0, 0, 105, 110, 116, 95, 51, 0, -0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, -0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 101, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, -4, 0, 102, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, 0, 49, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 51, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 51, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, -82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 53, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 53, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 72, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 73, 1, -0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 73, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 74, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 74, 1, 0, 0, 3, 22, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 76, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 77, 1, 0, 0, 30, 0, 0, 0, 2, 0, -0, 0, 0, 22, 5, 0, 77, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 78, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 100, 1, -0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, -0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, -5, 0, 100, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 100, 1, -0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 102, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, -0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, -0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, -0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, -9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, -0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 32, 0, 4, 0, 109, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 108, 0, 0, 0, 4, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 109, 0, -0, 0, 32, 0, 4, 0, 126, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 7, 0, 125, 0, 0, 0, 3, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 109, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, -4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 141, 0, 0, 0, 205, 204, 204, 62, 43, 0, -4, 0, 133, 0, 0, 0, 149, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 153, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 166, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 43, 0, -4, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 255, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 25, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 30, 1, -0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 50, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 52, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 54, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 55, 1, 0, 0, 38, 0, -0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 56, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 57, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 6, 0, 0, 0, 57, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 60, 1, -0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 61, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 62, 1, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 75, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 79, 1, 0, 0, 38, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 80, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 81, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 1, 0, 0, 6, 0, -0, 0, 81, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 91, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 100, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, -0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 101, 1, 0, 0, 2, 0, 0, 0, 100, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 101, 1, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, -0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 49, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 51, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 53, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 59, 1, -0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 72, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 75, 1, 0, 0, 74, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 76, 1, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 77, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 82, 1, 0, 0, 83, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 105, 0, -0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 110, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 112, 0, 0, 0, 248, 0, 2, 0, 113, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 0, -0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 0, 0, 0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 116, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 114, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 118, 0, 0, 0, 110, 0, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 0, 0, 0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 121, 0, 0, 0, 112, 0, 0, 0, 12, 0, -7, 0, 4, 0, 0, 0, 122, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 123, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 116, 0, 0, 0, 122, 0, 0, 0, 254, 0, 2, 0, 123, 0, 0, 0, 56, 0, -1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, 0, 125, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 127, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 128, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 129, 0, 0, 0, 55, 0, 3, 0, 109, 0, -0, 0, 130, 0, 0, 0, 248, 0, 2, 0, 131, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 138, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 140, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 144, 0, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 109, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 148, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 152, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 159, 0, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 109, 0, 0, 0, 163, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 183, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 109, 0, 0, 0, 193, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 202, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 0, 0, 0, 130, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 12, 0, -8, 0, 4, 0, 0, 0, 137, 0, 0, 0, 117, 0, 0, 0, 43, 0, 0, 0, 132, 0, 0, 0, 135, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 130, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 138, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 142, 0, -0, 0, 130, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 141, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 143, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 146, 0, 0, 0, 127, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 147, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 147, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 150, 0, 0, 0, 127, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 151, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 148, 0, -0, 0, 151, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 154, 0, 0, 0, 127, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 155, 0, 0, 0, 154, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 155, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 158, 0, -0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 161, 0, 0, 0, 140, 0, 0, 0, 131, 0, -5, 0, 4, 0, 0, 0, 162, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, 0, 62, 0, 3, 0, 159, 0, 0, 0, 162, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 164, 0, 0, 0, 159, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 133, 0, -5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 163, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 169, 0, 0, 0, 163, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 163, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 172, 0, 0, 0, 159, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 173, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, -3, 0, 168, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 62, 0, -3, 0, 168, 0, 0, 0, 176, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 179, 0, 0, 0, 130, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 182, 0, 0, 0, 179, 0, 0, 0, 180, 0, 0, 0, 247, 0, 3, 0, 178, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 182, 0, -0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 248, 0, 2, 0, 177, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 130, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 187, 0, 0, 0, 185, 0, -0, 0, 186, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 184, 0, 0, 0, 187, 0, 0, 0, 62, 0, 3, 0, 183, 0, 0, 0, 188, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 190, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, -0, 0, 183, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 62, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 138, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 0, -0, 0, 189, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 196, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 197, 0, 0, 0, 136, 0, 5, 0, 4, 0, -0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, 0, 183, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 62, 0, 3, 0, 193, 0, 0, 0, 201, 0, 0, 0, 111, 0, -4, 0, 4, 0, 0, 0, 203, 0, 0, 0, 134, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 204, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 193, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 206, 0, 0, 0, 117, 0, 0, 0, 49, 0, -0, 0, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 202, 0, 0, 0, 206, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 207, 0, 0, 0, 129, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 208, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 209, 0, 0, 0, 202, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 210, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 207, 0, 0, 0, 208, 0, -0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 211, 0, 0, 0, 249, 0, 2, 0, 178, 0, 0, 0, 248, 0, 2, 0, 178, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 212, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 168, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 3, 0, -0, 0, 216, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 127, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 217, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 217, 0, 0, 0, 56, 0, -1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 236, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 243, 0, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 245, 0, 0, 0, 83, 1, -0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 246, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, -2, 0, 248, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 253, 0, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 1, 1, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 1, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, -5, 0, 3, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 248, 0, 2, 0, 2, 1, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 28, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, -0, 0, 32, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, -0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 15, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 22, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 23, 1, 0, 0, 22, 1, 0, 0, 61, 0, -4, 0, 34, 0, 0, 0, 24, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 25, 1, 0, 0, 26, 1, 0, 0, 24, 1, 0, 0, 15, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 27, 1, 0, 0, 26, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 3, 1, -0, 0, 27, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 31, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 28, 1, 0, 0, 31, 1, 0, 0, 62, 0, 3, 0, 32, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 3, 0, -0, 0, 37, 1, 0, 0, 3, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 37, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 40, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 41, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 38, 1, -0, 0, 41, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 43, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 32, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 57, 0, -8, 0, 3, 0, 0, 0, 48, 1, 0, 0, 106, 0, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 254, 0, 2, 0, 48, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, -2, 0, 64, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 65, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 66, 1, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 67, 1, -0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 68, 1, 0, 0, 53, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 68, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 69, 1, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 70, 1, -0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 49, 1, 0, 0, 71, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 29, 0, -0, 0, 248, 0, 2, 0, 85, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 86, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 87, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 2, 0, -0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 88, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 92, 1, 0, 0, 77, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 92, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 93, 1, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 94, 1, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 61, 0, -4, 0, 3, 0, 0, 0, 95, 1, 0, 0, 94, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 96, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 97, 1, 0, 0, 96, 1, 0, 0, 62, 0, -3, 0, 74, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 1, 0, 0, 98, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 99, 1, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 106, 241, 116, 115, 62, 248, 116, 0, 146, 201, 139, 213, 179, 227, 100, 215, 0, 128, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 103, 1, 0, -0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 117, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 63, 1, 0, 0, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 51, 1, 0, 0, 53, 1, 0, 0, 49, 1, 0, 0, 59, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 102, 1, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 84, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 73, 1, 0, 0, 76, 1, 0, 0, 77, 1, 0, 0, 72, 1, 0, 0, 74, 1, 0, 0, 78, 1, 0, 0, 83, 1, 0, 0, 102, 1, 0, 0, 16, 0, 3, 0, 63, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, -97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, -116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, -97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, -0, 5, 0, 10, 0, 105, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 106, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 109, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 110, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, -0, 111, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 112, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 126, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 127, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 128, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 129, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 130, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, -104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 136, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, -103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 139, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 140, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 144, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 149, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 153, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, -0, 5, 0, 4, 0, 159, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 163, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 166, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 168, 0, 0, -0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 180, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 177, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, -0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 189, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 193, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, -0, 202, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 178, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 223, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 224, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, -83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 225, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, -0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 28, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 29, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 30, 1, 0, -0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 32, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 50, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, -0, 49, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 52, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 51, 1, 0, 0, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 54, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 53, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, -0, 55, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 55, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, -0, 56, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 56, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 57, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, -0, 57, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 57, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 57, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 5, 0, 8, 0, 58, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 60, 1, 0, 0, 105, 110, 116, -95, 48, 0, 0, 0, 5, 0, 4, 0, 61, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 62, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 14, 0, 63, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, -70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 8, 0, 72, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, -0, 73, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 75, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 74, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 76, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 77, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 78, 1, 0, 0, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 79, 1, 0, -0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 79, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 80, 1, 0, -0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 80, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 5, 0, 5, 0, 81, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 81, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 81, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 81, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 82, 1, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 84, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 91, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, -111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 100, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, -101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 101, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 4, -0, 49, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 51, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 51, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 53, 1, 0, 0, 30, 0, 0, -0, 1, 0, 0, 0, 0, 22, 5, 0, 53, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 72, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 73, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 73, 1, 0, -0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 74, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 74, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, -0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 76, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 77, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 77, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, -79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 78, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 100, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 0, 0, 0, -0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, -0, 24, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, -0, 72, 0, 5, 0, 100, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 100, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 71, 0, 4, -0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 102, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, -0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, -0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, -0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, -0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, -0, 0, 0, 0, 0, 82, 0, 0, 0, 32, 0, 4, 0, 109, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 108, 0, 0, 0, 4, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 109, 0, 0, 0, 32, 0, 4, 0, 126, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, -0, 33, 0, 7, 0, 125, 0, 0, 0, 3, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 126, 0, 0, 0, 109, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, -0, 4, 0, 0, 0, 136, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 141, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 149, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 133, 0, 0, 0, 153, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 166, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, -0, 255, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 25, 1, 0, 0, 34, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 30, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 50, 1, 0, 0, 3, 0, 0, -0, 3, 0, 0, 0, 32, 0, 4, 0, 52, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 54, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 55, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 56, 1, 0, 0, 3, 0, 0, -0, 30, 0, 5, 0, 57, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 6, 0, 0, 0, 57, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 60, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 61, 1, 0, -0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 62, 1, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 75, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 79, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 80, 1, 0, -0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 81, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 82, 1, 0, 0, 6, 0, 0, 0, 81, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 91, 1, 0, -0, 3, 0, 0, 0, 30, 0, 12, 0, 100, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 101, 1, 0, 0, 2, 0, 0, -0, 100, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 101, 1, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 49, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 51, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 53, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 59, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 72, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 75, 1, 0, 0, 74, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 76, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 54, 1, 0, 0, 77, 1, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 82, 1, 0, 0, 83, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 105, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, -0, 110, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 111, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 112, 0, 0, 0, 248, 0, 2, 0, 113, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 0, 0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 0, 0, -0, 111, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 116, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, 0, 114, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 118, 0, 0, 0, 110, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 0, 0, 0, 111, 0, 0, -0, 12, 0, 7, 0, 4, 0, 0, 0, 120, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 118, 0, 0, 0, 119, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 121, 0, 0, 0, 112, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 122, 0, 0, 0, 117, 0, 0, 0, 37, 0, 0, -0, 120, 0, 0, 0, 121, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 123, 0, 0, 0, 117, 0, 0, 0, 40, 0, 0, 0, 116, 0, 0, 0, 122, 0, 0, 0, 254, 0, 2, 0, 123, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 106, 0, 0, 0, 0, 0, 0, -0, 125, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 127, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 128, 0, 0, 0, 55, 0, 3, 0, 126, 0, 0, 0, 129, 0, 0, 0, 55, 0, 3, 0, 109, 0, 0, 0, 130, 0, 0, 0, 248, 0, 2, 0, 131, 0, 0, 0, 59, 0, 4, -0, 109, 0, 0, 0, 138, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 140, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 144, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, -0, 109, 0, 0, 0, 148, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 152, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 159, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 163, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, -0, 109, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 183, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 193, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, -0, 109, 0, 0, 0, 202, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 0, 0, 0, 130, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 135, 0, 0, 0, 134, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 137, 0, 0, 0, 117, 0, 0, 0, 43, 0, 0, -0, 132, 0, 0, 0, 135, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 130, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 138, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 142, 0, 0, 0, 130, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, -0, 141, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 140, 0, 0, 0, 143, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 146, 0, 0, 0, 127, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 147, 0, 0, 0, 146, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, -0, 147, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 150, 0, 0, 0, 127, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 151, 0, 0, 0, 150, 0, 0, 0, 62, 0, 3, 0, 148, 0, 0, 0, 151, 0, 0, 0, 65, 0, 5, 0, 109, 0, 0, 0, 154, 0, 0, -0, 127, 0, 0, 0, 153, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 155, 0, 0, 0, 154, 0, 0, 0, 62, 0, 3, 0, 152, 0, 0, 0, 155, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 158, 0, 0, 0, 105, 0, 0, 0, 145, 0, 0, 0, 148, 0, 0, 0, 152, 0, 0, -0, 62, 0, 3, 0, 144, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 160, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 161, 0, 0, 0, 140, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 162, 0, 0, 0, 160, 0, 0, 0, 161, 0, 0, -0, 62, 0, 3, 0, 159, 0, 0, 0, 162, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 164, 0, 0, 0, 159, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 165, 0, 0, 0, 164, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, -0, 62, 0, 3, 0, 163, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 169, 0, 0, 0, 163, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 171, 0, 0, 0, 163, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 172, 0, 0, 0, 159, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 173, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 174, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 176, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 179, 0, 0, 0, 130, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 182, 0, 0, 0, 179, 0, 0, 0, 180, 0, 0, 0, 247, 0, 3, 0, 178, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 182, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 248, 0, 2, 0, 177, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 130, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, -0, 184, 0, 0, 0, 187, 0, 0, 0, 62, 0, 3, 0, 183, 0, 0, 0, 188, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 190, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 183, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 192, 0, 0, -0, 190, 0, 0, 0, 191, 0, 0, 0, 62, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 0, 0, 0, 138, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 0, 0, 0, 189, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 196, 0, 0, -0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 197, 0, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 200, 0, 0, 0, 183, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 62, 0, 3, 0, 193, 0, 0, 0, 201, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 203, 0, 0, 0, 134, 0, 0, 0, 111, 0, 4, -0, 4, 0, 0, 0, 204, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 193, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 206, 0, 0, 0, 117, 0, 0, 0, 49, 0, 0, 0, 203, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, -0, 202, 0, 0, 0, 206, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 207, 0, 0, 0, 129, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 208, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 0, 0, 0, 202, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, -0, 210, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 209, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 211, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 207, 0, 0, 0, 208, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 211, 0, 0, -0, 249, 0, 2, 0, 178, 0, 0, 0, 248, 0, 2, 0, 178, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 212, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 213, 0, 0, 0, 128, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 214, 0, 0, 0, 168, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 216, 0, 0, 0, 117, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, -0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 127, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 217, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 217, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, -0, 29, 0, 0, 0, 248, 0, 2, 0, 236, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 243, 0, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 245, 0, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 246, 0, 0, -0, 245, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 246, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 248, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 253, 0, 0, -0, 59, 1, 0, 0, 60, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 1, 1, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 1, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, -0, 248, 0, 2, 0, 2, 1, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 28, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 32, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, -0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 126, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 109, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, -0, 15, 1, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 22, 1, 0, 0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 23, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 24, 1, 0, 0, 36, 0, 0, 0, 86, 0, 5, -0, 25, 1, 0, 0, 26, 1, 0, 0, 24, 1, 0, 0, 15, 1, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 27, 1, 0, 0, 26, 1, 0, 0, 23, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 27, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 31, 1, 0, -0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 28, 1, 0, 0, 31, 1, 0, 0, 62, 0, 3, 0, 32, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 37, 1, 0, 0, 3, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, -0, 37, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 40, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 41, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 38, 1, 0, 0, 41, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 43, 1, 0, -0, 28, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 32, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 57, 0, 8, 0, 3, 0, 0, 0, 48, 1, 0, 0, 106, 0, 0, 0, 36, 1, 0, -0, 38, 1, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 254, 0, 2, 0, 48, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 63, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 64, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 65, 1, 0, -0, 59, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 66, 1, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 67, 1, 0, 0, 59, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, -0, 68, 1, 0, 0, 53, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 68, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 69, 1, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 70, 1, 0, 0, 59, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, -0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 49, 1, 0, 0, 71, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 85, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, -0, 86, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 87, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 62, 1, 0, 0, 61, 0, 4, -0, 3, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 88, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 92, 1, 0, 0, 77, 1, 0, 0, 62, 0, 3, -0, 90, 1, 0, 0, 92, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 93, 1, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 94, 1, 0, 0, 83, 1, 0, 0, 60, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 95, 1, 0, 0, 94, 1, 0, 0, 62, 0, 3, -0, 72, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 96, 1, 0, 0, 83, 1, 0, 0, 61, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 97, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, -0, 98, 1, 0, 0, 83, 1, 0, 0, 91, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 99, 1, 0, 0, 98, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 99, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, +0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, +0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, +101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, +239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, +0, 0, 1, 149, 78, 118, 157, 84, 228, 107, 89, 7, 114, 154, 228, 121, 240, 170, 112, 0, 208, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, +76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 71, 1, 0, 0, +80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 1, 0, 0, 64, 1, 0, 0, 60, 1, 0, 0, 70, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 95, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, +101, 114, 0, 0, 84, 1, 0, 0, 87, 1, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 85, 1, 0, 0, 89, 1, 0, 0, 94, 1, 0, 0, 16, 0, 3, 0, 71, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, +3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, +115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, +0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 19, 0, 223, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 225, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 225, 0, 0, 0, 7, 0, 21, 0, 56, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 59, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, +0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, +103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, +112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, +5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, +141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, +5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, +99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, +115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, +182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, +105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, +105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, +231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 10, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 35, 1, 0, 0, +98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 39, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 0, 5, 0, 7, 0, 61, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, +63, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 62, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 65, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, +116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 64, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 66, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 66, 1, 0, 0, 0, 0, 0, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 66, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 68, 1, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 68, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 69, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, +77, 83, 0, 0, 5, 0, 5, 0, 70, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 71, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 74, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, +5, 0, 8, 0, 83, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 84, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, +112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 5, 0, 5, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 89, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, +0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 1, 0, 0, 2, 0, 0, 0, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 91, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 1, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 92, 1, 0, 0, +0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, +0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 93, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, +115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 95, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, +0, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, +116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 60, 1, 0, 0, +30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 64, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 5, 0, 64, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 84, 1, 0, 0, 3, 22, 0, 0, +84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, +1, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 88, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, +71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, +32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, +32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, +25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, +2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, +32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, +7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, +0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, +1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, +0, 0, 0, 64, 33, 0, 3, 0, 6, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 32, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, +61, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 63, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 65, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 66, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, +67, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 68, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 69, 1, 0, 0, 6, 0, 0, 0, 68, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, +138, 0, 0, 0, 77, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 90, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, +30, 0, 5, 0, 91, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 92, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 93, 1, 0, 0, 6, 0, 0, 0, 92, 1, 0, 0, 43, 0, 4, 0, +138, 0, 0, 0, 102, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 60, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +63, 1, 0, 0, 62, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 64, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 69, 1, 0, 0, 70, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 83, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +63, 1, 0, 0, 84, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +61, 1, 0, 0, 89, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 93, 1, 0, 0, 94, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, +114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, +5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, +125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, +12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, +131, 0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, +7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, +141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, +62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, +114, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, +163, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, +167, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, +172, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, +164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, +186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, +62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, +62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, +188, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, +154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, +214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, +248, 0, 2, 0, 183, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, +173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, +62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +243, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 250, 0, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 252, 0, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, +250, 0, 0, 0, 253, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 255, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 4, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 4, 1, 0, 0, 8, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 248, 0, 2, 0, 9, 1, 0, 0, +59, 0, 4, 0, 131, 0, 0, 0, 10, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 35, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 39, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 43, 1, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 131, 0, 0, 0, 45, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 49, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 22, 1, 0, 0, 87, 0, 0, 0, +65, 0, 5, 0, 74, 0, 0, 0, 29, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 31, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 32, 1, 0, 0, 33, 1, 0, 0, +31, 1, 0, 0, 22, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 10, 1, 0, 0, 34, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 36, 1, 0, 0, 36, 1, 0, 0, +36, 1, 0, 0, 37, 1, 0, 0, 62, 0, 3, 0, 35, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 39, 1, 0, 0, 36, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 44, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 43, 1, 0, 0, 44, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 47, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 48, 1, 0, 0, 47, 1, 0, 0, 62, 0, 3, 0, 45, 1, 0, 0, 48, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 50, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, +49, 1, 0, 0, 50, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 52, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 52, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 55, 1, 0, 0, 111, 0, 0, 0, 43, 1, 0, 0, 45, 1, 0, 0, 49, 1, 0, 0, +51, 1, 0, 0, 254, 0, 2, 0, 55, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 71, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 72, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 73, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 75, 1, 0, 0, 62, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 75, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 76, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 78, 1, 0, 0, 64, 1, 0, 0, +62, 0, 3, 0, 76, 1, 0, 0, 78, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 79, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 80, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 82, 1, 0, 0, 80, 1, 0, 0, +62, 0, 3, 0, 60, 1, 0, 0, 82, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 96, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 97, 1, 0, 0, 94, 1, 0, 0, +74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 98, 1, 0, 0, 84, 1, 0, 0, 62, 0, 3, 0, 97, 1, 0, 0, 98, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 1, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 1, 0, 0, +87, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 94, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, +57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 83, 1, 0, 0, 106, 1, 0, 0, +65, 0, 5, 0, 74, 0, 0, 0, 107, 1, 0, 0, 94, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 108, 1, 0, 0, 107, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 108, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 94, 1, 0, 0, +102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 110, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 110, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, +0, 1, 149, 78, 118, 157, 84, 228, 107, 89, 7, 114, 154, 228, 121, 240, 170, 112, 0, 208, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, +69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 71, 1, 0, 0, 80, +83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 1, 0, 0, 64, 1, 0, 0, 60, 1, 0, 0, 70, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 95, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, +114, 0, 0, 84, 1, 0, 0, 87, 1, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 85, 1, 0, 0, 89, 1, 0, 0, 94, 1, 0, 0, 16, 0, 3, 0, 71, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, +47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, +0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, +114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, +108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, +105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, +0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 19, 0, 223, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, +83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 225, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, +100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, +0, 0, 0, 225, 0, 0, 0, 7, 0, 21, 0, 56, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, +101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, +47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 59, 1, 0, 0, 67, +58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, +116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, +0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, +46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, +110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, +0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, +108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, +110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 112, +116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, 112, +116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, +0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 141, +0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, +0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, +101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, 115, +105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 182, +0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, 105, +115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, +102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, +0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, +101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 10, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 35, 1, 0, 0, 98, +111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 39, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, +115, 115, 0, 5, 0, 7, 0, 61, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 63, +1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 62, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 65, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, +95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 64, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 66, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 66, 1, 0, 0, 0, 0, 0, 0, 84, +101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 66, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 68, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 68, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 69, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, +83, 0, 0, 5, 0, 5, 0, 70, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 71, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 74, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, +0, 8, 0, 83, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 84, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, +116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 5, 0, 5, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 89, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, +0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 1, 0, 0, 2, 0, 0, 0, 67, +111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 91, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 92, 1, 0, 0, 0, +0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, +0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 93, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 115, +116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 95, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, +101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 60, 1, 0, 0, 30, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 64, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, +22, 5, 0, 64, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 84, 1, 0, 0, 3, 22, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 1, +0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 88, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, +0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, +0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, +0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, +0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, +0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, +0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, +0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, +0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, +0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, +0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, +0, 0, 64, 33, 0, 3, 0, 6, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 32, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 61, +1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 63, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 65, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 66, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 67, +1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 68, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 69, 1, 0, 0, 6, 0, 0, 0, 68, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, +0, 0, 0, 77, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 90, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, +0, 5, 0, 91, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 92, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 93, 1, 0, 0, 6, 0, 0, 0, 92, 1, 0, 0, 43, 0, 4, 0, 138, +0, 0, 0, 102, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 60, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 63, +1, 0, 0, 62, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 64, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 69, 1, 0, 0, 70, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 83, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 63, +1, 0, 0, 84, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 61, +1, 0, 0, 89, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 93, 1, 0, 0, 94, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, +0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, +0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, +0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, +0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, +0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, 141, +0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, +0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, +0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 167, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, +0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, 186, +0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, +0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, +0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, +0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, +0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 154, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, 61, +0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, +0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, +0, 2, 0, 183, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, +0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, +0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 243, +0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 250, 0, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 252, 0, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 250, +0, 0, 0, 253, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 255, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 4, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 57, +0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 4, 1, 0, 0, 8, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 248, 0, 2, 0, 9, 1, 0, 0, 59, +0, 4, 0, 131, 0, 0, 0, 10, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 35, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 39, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 43, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 131, 0, 0, 0, 45, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 49, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 22, 1, 0, 0, 87, 0, 0, 0, 65, +0, 5, 0, 74, 0, 0, 0, 29, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 31, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 32, 1, 0, 0, 33, 1, 0, 0, 31, +1, 0, 0, 22, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 10, 1, 0, 0, 34, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 36, 1, 0, 0, 36, 1, 0, 0, 36, +1, 0, 0, 37, 1, 0, 0, 62, 0, 3, 0, 35, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 39, 1, 0, 0, 36, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 44, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 43, 1, 0, 0, 44, 1, 0, 0, 65, 0, 5, 0, 3, +0, 0, 0, 47, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 48, 1, 0, 0, 47, 1, 0, 0, 62, 0, 3, 0, 45, 1, 0, 0, 48, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 50, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 49, +1, 0, 0, 50, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 52, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 52, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 55, 1, 0, 0, 111, 0, 0, 0, 43, 1, 0, 0, 45, 1, 0, 0, 49, 1, 0, 0, 51, +1, 0, 0, 254, 0, 2, 0, 55, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 71, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 72, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 73, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, +0, 4, 0, 42, 0, 0, 0, 75, 1, 0, 0, 62, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 75, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 76, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 78, 1, 0, 0, 64, 1, 0, 0, 62, +0, 3, 0, 76, 1, 0, 0, 78, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 79, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 80, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 82, 1, 0, 0, 80, 1, 0, 0, 62, +0, 3, 0, 60, 1, 0, 0, 82, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 96, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 97, 1, 0, 0, 94, 1, 0, 0, 74, +1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 98, 1, 0, 0, 84, 1, 0, 0, 62, 0, 3, 0, 97, 1, 0, 0, 98, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 1, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 1, 0, 0, 87, +1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 94, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, 57, +0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 83, 1, 0, 0, 106, 1, 0, 0, 65, +0, 5, 0, 74, 0, 0, 0, 107, 1, 0, 0, 94, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 108, 1, 0, 0, 107, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 108, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 94, 1, 0, 0, 102, +1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 110, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 110, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index 143e883f51..d397a6a3c2 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -16,57 +16,69 @@ namespace Stride.Graphics internal partial class SpriteSignedDistanceFieldFontShader { private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, -114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, -101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, -1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, -93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, -194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 42, 221, 214, 87, 40, 204, 27, 223, 36, 113, 16, 94, 252, 222, 94, 128, 0, 192, 95, 0, 0, 68, 88, 66, 67, 63, 195, 153, 107, 204, 58, 8, 205, 203, 164, 112, 73, 93, 251, 97, -115, 1, 0, 0, 0, 192, 95, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 94, 0, 0, 140, 94, 0, 0, 64, 95, 0, 0, 140, 95, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, -0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, -0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, -115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, -255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, 255, 0, 4, 0, 0, 77, 0, 0, 0, 12, 4, 0, 0, 82, 0, 0, 0, 28, 4, 0, 0, 82, 0, 0, 0, 44, 4, 0, 0, 82, 0, 0, 0, 64, 4, 0, 0, 82, 0, 0, 0, 80, 4, 0, 0, 94, 0, 0, -0, 96, 4, 0, 0, 95, 0, 0, 0, 112, 4, 0, 0, 95, 0, 0, 0, 124, 4, 0, 0, 95, 0, 0, 0, 136, 4, 0, 0, 95, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 164, 4, 0, 0, 96, 0, 0, 0, 184, 4, 0, 0, 96, 0, 0, 0, 200, 4, 0, 0, 96, 0, 0, -0, 212, 4, 0, 0, 96, 0, 0, 0, 228, 4, 0, 0, 96, 0, 0, 0, 248, 4, 0, 0, 96, 0, 0, 0, 8, 5, 0, 0, 97, 0, 0, 0, 24, 5, 0, 0, 106, 0, 0, 0, 40, 5, 0, 0, 106, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, -105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, -0, 1, 0, 0, 0, 0, 0, 0, 0, 193, 1, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 228, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, -0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 148, 2, 0, 0, 164, 2, 0, 0, 180, 2, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, -0, 192, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 160, 1, 0, 0, 1, 0, 0, -0, 176, 1, 0, 0, 0, 0, 0, 0, 188, 1, 0, 0, 236, 1, 0, 0, 1, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 16, 2, 0, 0, 2, 0, 0, 0, 32, 2, 0, 0, 56, 2, 0, 0, 90, 2, 0, 0, 212, 1, 0, 0, 1, 0, 0, 0, 104, 2, 0, -0, 0, 0, 0, 0, 116, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 124, 2, 0, 0, 188, 1, 0, 0, 136, 2, 0, 0, 208, 2, 0, 0, 2, 0, 0, 0, 224, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, -101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, -0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, -129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, -128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, -4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, -4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, -128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, -4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, -0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, -0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, -0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, -0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, -7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, -0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, -64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 86, 0, 0, 77, 105, 99, -114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, +97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, +114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, +0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, +120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, +0, 0, 0, 5, 0, 0, 0, 1, 15, 102, 239, 211, 137, 37, 226, 132, 109, 210, 47, 74, 195, 187, 131, 207, 0, 192, 87, 0, 0, 68, 88, 66, 67, 55, 13, 237, 178, 214, 112, 53, 7, 236, 35, 51, 252, 228, 190, 248, 29, 1, 0, 0, 0, 192, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, +0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 86, 0, 0, 140, 86, 0, 0, 64, 87, 0, 0, 140, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, +0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, 0, 67, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, +255, 0, 4, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 68, 0, 0, 0, 28, 4, 0, 0, 68, 0, 0, 0, 44, 4, 0, 0, 68, 0, 0, 0, 64, 4, 0, 0, 68, 0, 0, 0, 80, 4, 0, 0, 80, 0, 0, 0, 96, 4, 0, 0, 81, 0, 0, 0, 112, 4, 0, 0, 81, 0, 0, +0, 124, 4, 0, 0, 81, 0, 0, 0, 136, 4, 0, 0, 81, 0, 0, 0, 148, 4, 0, 0, 82, 0, 0, 0, 164, 4, 0, 0, 82, 0, 0, 0, 184, 4, 0, 0, 82, 0, 0, 0, 200, 4, 0, 0, 82, 0, 0, 0, 212, 4, 0, 0, 82, 0, 0, 0, 228, 4, 0, 0, 82, 0, 0, +0, 248, 4, 0, 0, 82, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 40, 5, 0, 0, 92, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, +105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, +0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 193, 1, 0, 0, 212, 1, 0, +0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 228, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, +255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, +0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, +0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 148, 2, 0, 0, 164, 2, 0, 0, 180, 2, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 192, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, +255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 160, 1, 0, 0, 1, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 188, 1, 0, 0, 236, 1, 0, +0, 1, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 16, 2, 0, 0, 2, 0, 0, 0, 32, 2, 0, 0, 56, 2, 0, 0, 90, 2, 0, 0, 212, 1, 0, 0, 1, 0, 0, 0, 104, 2, 0, 0, 0, 0, 0, 0, 116, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, +0, 124, 2, 0, 0, 188, 1, 0, 0, 136, 2, 0, 0, 208, 2, 0, 0, 2, 0, 0, 0, 224, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, +0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, +2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, +128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, +128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, +128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, +160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, +176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, +3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, +0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, +0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, +5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, +128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, +0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, +0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, +0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, +32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -74,372 +86,340 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, -0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, -0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 53, 29, 21, 23, 245, 244, 228, +69, 128, 13, 182, 224, 135, 53, 196, 207, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, +114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, +111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, +111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, +0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 124, 125, 2, +0, 28, 221, 1, 0, 214, 154, 2, 0, 138, 227, 2, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, -1, 204, 180, 142, 105, 1, 0, 0, 0, 166, 252, 70, 235, 64, 149, 14, 77, 164, 61, 105, 101, 153, 85, 245, 94, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, +10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, +117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, +73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, +59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, +97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, +10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, +111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, +114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, +111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, +116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, +53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 95, 50, 50, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 50, 50, 44, 32, 95, 50, 50, 53, 44, 32, 95, +50, 50, 57, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, +32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, +41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, +32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, +47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, +105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, +108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, +32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 95, 51, 50, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 54, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 51, 48, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 51, 51, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 54, 44, 32, 95, 51, 50, 48, 44, 32, 95, 51, 50, 54, 44, 32, 95, 51, 51, 48, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 51, 51, 59, 10, +125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, +83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, +32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, +32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, -0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, -0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 113, 232, 0, 0, 28, 221, 1, 0, 214, 154, 2, 0, 101, 128, 0, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, -117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, -115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, -101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, -58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, -40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, -10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, -108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, -115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, -105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, -114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, -114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, -108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, -52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, -110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, -99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, -32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, -48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, -114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 54, 32, 61, -32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, -97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 51, 44, 32, 95, 50, 49, 54, 44, 32, 95, 50, 50, 48, 41, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, -115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, -99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, -104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, -109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, -101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, -101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, -110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 53, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 53, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, -102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 49, 57, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, -70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 48, 53, 44, 32, 95, 51, 48, 57, 44, 32, 95, 51, 49, 53, 44, 32, 95, 51, 49, 57, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 50, 59, 10, 125, 10, 10, 118, 111, 105, 100, -32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, -111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, -67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, -32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, -239, 1, 0, 0, 0, 174, 15, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, -51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, -97, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, -115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, -1, 128, 0, 0, 0, 108, 90, 59, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 86, 98, 187, 113, 243, 14, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, -0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, -46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, -105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 5, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, -1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, -109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, -0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, -0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 12, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 96, 4, 129, 248, 8, 0, 13, 23, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, -0, 8, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 74, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 73, 1, 80, 12, 129, 248, 0, 0, 50, 0, 77, 17, 60, 2, 0, 0, 4, 5, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 39, 11, 32, 13, 76, 6, 8, 12, 129, 212, -36, 8, 0, 9, 19, 13, 38, 1, 80, 6, 9, 3, 0, 13, 75, 6, 8, 12, 129, 212, 36, 38, 0, 77, 17, 100, 2, 0, 0, 84, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 80, 12, 36, 0, 0, 0, 0, 74, 0, 62, -17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, -0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 8, 0, 0, 0, 2, 0, 78, 17, 110, 0, 77, 17, 100, 2, 0, 0, 0, 5, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, -76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, -6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, -0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, -17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, -9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 18, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, -17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 146, 224, 37, 145, 93, 203, 233, 81, 174, 233, 104, 45, 135, 143, 95, 34, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, -0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 137, 0, 0, 128, 80, 0, 0, 0, 137, 0, 0, 0, 116, 0, 0, 0, 137, 0, 0, 128, 116, 0, 0, 0, 137, 0, 0, 0, 144, 0, 0, 0, 137, 0, 0, 128, 144, 0, 0, 0, 137, 0, 0, -0, 172, 0, 0, 0, 137, 0, 0, 128, 172, 0, 0, 0, 137, 0, 0, 0, 200, 0, 0, 0, 137, 0, 0, 128, 200, 0, 0, 0, 137, 0, 0, 0, 228, 0, 0, 0, 137, 0, 0, 128, 228, 0, 0, 0, 137, 0, 0, 0, 248, 0, 0, 0, 137, 0, 0, 128, 248, 0, 0, 0, 137, 0, 0, -0, 12, 1, 0, 0, 137, 0, 0, 128, 12, 1, 0, 0, 137, 0, 0, 0, 48, 1, 0, 0, 137, 0, 0, 128, 48, 1, 0, 0, 137, 0, 0, 0, 84, 1, 0, 0, 137, 0, 0, 128, 84, 1, 0, 0, 137, 0, 0, 0, 112, 1, 0, 0, 137, 0, 0, 128, 112, 1, 0, 0, 137, 0, 0, -0, 152, 1, 0, 0, 137, 0, 0, 128, 152, 1, 0, 0, 137, 0, 0, 0, 180, 1, 0, 0, 137, 0, 0, 128, 180, 1, 0, 0, 137, 0, 0, 0, 216, 1, 0, 0, 137, 0, 0, 128, 216, 1, 0, 0, 137, 0, 0, 0, 244, 1, 0, 0, 137, 0, 0, 128, 244, 1, 0, 0, 137, 0, 0, -0, 16, 2, 0, 0, 137, 0, 0, 128, 16, 2, 0, 0, 137, 0, 0, 0, 44, 2, 0, 0, 137, 0, 0, 128, 44, 2, 0, 0, 137, 0, 0, 0, 72, 2, 0, 0, 140, 0, 0, 128, 72, 2, 0, 0, 140, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 69, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, +105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 54, 48, 102, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, +85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, +73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 79, 33, 58, 42, 88, 187, 220, 1, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 141, 40, 225, 179, 138, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, +30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, +97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 5, 0, +0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, +1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, +0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, +101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, +0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, +0, 38, 0, 77, 17, 136, 0, 0, 0, 12, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 96, 4, 129, 248, 8, 0, 13, 23, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 8, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 74, 11, +32, 4, 129, 248, 8, 0, 9, 29, 13, 73, 1, 80, 12, 129, 248, 0, 0, 50, 0, 77, 17, 60, 2, 0, 0, 4, 5, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 39, 11, 32, 13, 76, 6, 8, 12, 129, 212, 36, 8, 0, 9, 19, 13, 38, 1, 80, 6, 9, 3, 0, 13, 75, 6, +8, 12, 129, 212, 36, 38, 0, 77, 17, 100, 2, 0, 0, 84, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 80, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, +0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 8, 0, 0, +0, 2, 0, 78, 17, 110, 0, 77, 17, 100, 2, 0, 0, 0, 5, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, +0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, +105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, +17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, +0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 18, 16, 0, +0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, +0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 103, 72, 54, 195, 243, 107, 57, 242, 190, 90, 201, 47, 149, 66, 230, 217, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, +0, 80, 0, 0, 0, 123, 0, 0, 128, 80, 0, 0, 0, 123, 0, 0, 0, 116, 0, 0, 0, 123, 0, 0, 128, 116, 0, 0, 0, 123, 0, 0, 0, 144, 0, 0, 0, 123, 0, 0, 128, 144, 0, 0, 0, 123, 0, 0, 0, 172, 0, 0, 0, 123, 0, 0, 128, 172, 0, 0, 0, 123, 0, 0, +0, 200, 0, 0, 0, 123, 0, 0, 128, 200, 0, 0, 0, 123, 0, 0, 0, 228, 0, 0, 0, 123, 0, 0, 128, 228, 0, 0, 0, 123, 0, 0, 0, 248, 0, 0, 0, 123, 0, 0, 128, 248, 0, 0, 0, 123, 0, 0, 0, 12, 1, 0, 0, 123, 0, 0, 128, 12, 1, 0, 0, 123, 0, 0, +0, 48, 1, 0, 0, 123, 0, 0, 128, 48, 1, 0, 0, 123, 0, 0, 0, 84, 1, 0, 0, 123, 0, 0, 128, 84, 1, 0, 0, 123, 0, 0, 0, 112, 1, 0, 0, 123, 0, 0, 128, 112, 1, 0, 0, 123, 0, 0, 0, 152, 1, 0, 0, 123, 0, 0, 128, 152, 1, 0, 0, 123, 0, 0, +0, 180, 1, 0, 0, 123, 0, 0, 128, 180, 1, 0, 0, 123, 0, 0, 0, 216, 1, 0, 0, 123, 0, 0, 128, 216, 1, 0, 0, 123, 0, 0, 0, 244, 1, 0, 0, 123, 0, 0, 128, 244, 1, 0, 0, 123, 0, 0, 0, 16, 2, 0, 0, 123, 0, 0, 128, 16, 2, 0, 0, 123, 0, 0, +0, 44, 2, 0, 0, 123, 0, 0, 128, 44, 2, 0, 0, 123, 0, 0, 0, 72, 2, 0, 0, 126, 0, 0, 128, 72, 2, 0, 0, 126, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, -0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, -0, 246, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 121, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 4, 16, 0, -0, 0, 0, 0, 0, 86, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, -21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 21, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 32, 106, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, -1, 56, 0, 0, 0, 0, 16, 0, 0, 26, 16, 0, 0, 8, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 8, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, -0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, -110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, -21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, -0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, -18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 32, 106, 0, 0, 242, 241, 41, 75, 0, -0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, 0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, -53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, -108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, -111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, -99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, -116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, -82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, -10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, -84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, -116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, -10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, -100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, -97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, -117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, -102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -95, 50, 49, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 48, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 51, 44, 32, 95, 50, 49, 54, 44, 32, 95, 50, -50, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, -32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, -59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, -32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, -32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, -116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, -111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, -32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 53, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -95, 51, 48, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 53, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, -102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 49, 57, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, -101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 48, 53, 44, 32, 95, 51, 48, 57, 44, 32, 95, 51, 49, 53, 44, 32, 95, 51, 49, 57, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 50, 59, 10, 125, -10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, -80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, -115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 186, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, -1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, 0, 236, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, -0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, -105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, -0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, -83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, -0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, -105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, -0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, -255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, +0, 0, 0, 0, 0, 112, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, +0, 67, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 21, 16, 0, +0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 26, 16, 0, 0, 8, 2, 0, +0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 8, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, +21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, +110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, +0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, +95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, +0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 8, 0, +0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, +0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 240, 112, 0, 0, 242, 241, 41, 75, 0, 0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, +0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, -17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 22, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 25, 16, 0, -0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, +40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, +114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, +98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, +109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, +111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, +115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, +115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, +53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 50, 50, 44, 32, 95, +50, 50, 53, 44, 32, 95, 50, 50, 57, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, +53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, +105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, +32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, +42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, +110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, +114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, +101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, +116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, +32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, +10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, +116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 54, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 51, 48, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 51, 51, 32, 61, 32, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 54, 44, 32, 95, 51, 50, 48, 44, 32, 95, 51, 50, 54, 44, 32, 95, 51, 51, 48, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, +95, 51, 51, 51, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, +83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, +40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, +114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, +95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, +41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, +0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, 0, 236, 0, 0, +0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, +22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, +108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, +0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, +22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, +108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, +0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, -255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, -110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, -0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 65, 56, 0, 254, 239, 254, -239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, -1, 204, 180, 142, 105, 1, 0, 0, 0, 166, 252, 70, 235, 64, 149, 14, 77, 164, 61, 105, 101, 153, 85, 245, 94, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, -115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, -51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 53, 50, 55, 48, 97, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, -0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, -0, 32, 0, 0, 0, 229, 0, 0, 0, 64, 2, 0, 0, 111, 1, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 222, 15, 0, 0, 128, 0, 0, 0, 243, 14, 0, 0, 104, 7, 0, 0, 112, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, -0, 3, 0, 0, 0, 38, 0, 0, 0, 23, 0, 0, 0, 22, 0, 0, 0, 37, 0, 0, 0, 31, 0, 0, 0, 16, 0, 0, 0, 6, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 17, 0, 0, 0, 8, 0, 0, -0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 32, 0, 0, 0, 33, 0, 0, 0, 34, 0, 0, -0, 36, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, +0, 38, 0, 81, 17, 22, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 25, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, +116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, +107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, +96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, +0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, +0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, +97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 53, 29, 21, 23, 245, 244, 228, +69, 128, 13, 182, 224, 135, 53, 196, 207, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 54, 48, 102, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, +0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 64, 2, 0, 0, 111, 1, 0, +0, 36, 1, 0, 0, 0, 0, 0, 0, 117, 13, 0, 0, 128, 0, 0, 0, 138, 12, 0, 0, 104, 7, 0, 0, 112, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, +0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, +0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, -84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, -0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, -48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, -0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 88, 84, 127, 211, 244, 81, 196, 106, 171, 92, 171, 170, -219, 201, 197, 206, 0, 120, 77, 0, 0, 68, 88, 66, 67, 204, 198, 217, 28, 190, 139, 216, 132, 209, 169, 155, 35, 3, 58, 149, 247, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, -0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, 0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 1, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, 0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, -100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, -48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 86, 0, 0, 0, 56, 3, 0, 0, 86, 0, 0, 0, 72, 3, 0, 0, 86, 0, 0, -0, 88, 3, 0, 0, 86, 0, 0, 0, 104, 3, 0, 0, 100, 0, 0, 0, 120, 3, 0, 0, 100, 0, 0, 0, 140, 3, 0, 0, 102, 0, 0, 0, 152, 3, 0, 0, 104, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, -0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 52, 1, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 8, 0, 255, 255, 7, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, -255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 9, 0, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 164, 1, 0, 0, 248, 0, 0, 0, 179, 1, 0, 0, 24, 1, 0, 0, 194, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, -0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 171, 171, 38, 2, 0, 0, 24, 1, 0, 0, 54, 2, 0, 0, 248, 0, 0, 0, 63, 2, 0, 0, 24, 1, 0, 0, 72, 2, 0, 0, 24, 1, 0, 0, 5, 0, 0, -0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, 0, 4, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 76, 1, 0, 0, 5, 0, 0, -0, 92, 1, 0, 0, 224, 0, 0, 0, 152, 1, 0, 0, 232, 1, 0, 0, 3, 0, 0, 0, 248, 1, 0, 0, 0, 0, 0, 0, 28, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, -83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, -192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, -192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 1, -0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, -0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, -0, 70, 30, 16, 0, 2, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, -0, 1, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, -0, 1, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, -0, 176, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, +0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, +255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, +72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, +0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 136, 207, 217, 232, 43, 133, 4, 191, 97, 128, 87, 175, 215, 44, 158, 219, 0, 120, 77, 0, 0, 68, 88, 66, 67, 206, 105, 142, +150, 35, 105, 251, 25, 51, 50, 237, 25, 174, 254, 221, 178, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, 0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, +0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, +0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, +101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, 70, 69, 51, 56, +0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 72, 0, 0, 0, 56, 3, 0, 0, 72, 0, 0, 0, 72, 3, 0, 0, 72, 0, 0, 0, 88, 3, 0, 0, 72, 0, 0, 0, 104, 3, 0, 0, 86, 0, 0, +0, 120, 3, 0, 0, 86, 0, 0, 0, 140, 3, 0, 0, 88, 0, 0, 0, 152, 3, 0, 0, 90, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, +0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, +0, 40, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 52, 1, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 8, 0, 255, 255, 7, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 9, 0, 9, 0, 0, +0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, +110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 164, 1, 0, 0, 248, 0, 0, 0, 179, 1, 0, 0, 24, 1, 0, 0, 194, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, +255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, +116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 171, 171, 38, 2, 0, 0, 24, 1, 0, 0, 54, 2, 0, 0, 248, 0, 0, 0, 63, 2, 0, 0, 24, 1, 0, 0, 72, 2, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, 0, 4, 0, 0, +0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 76, 1, 0, 0, 5, 0, 0, 0, 92, 1, 0, 0, 224, 0, 0, 0, 152, 1, 0, 0, 232, 1, 0, +0, 3, 0, 0, 0, 248, 1, 0, 0, 0, 0, 0, 0, 28, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, +49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, +128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, +2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 1, 0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, +0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, +0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, +0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, +0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, +66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -447,7 +427,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -455,215 +435,231 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 186, 183, 128, 100, 234, 17, 138, 73, 142, 102, 213, 35, 218, 214, 112, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 204, 180, 142, 105, 1, 0, 0, 0, 165, 1, 241, 92, 160, 53, 1, 76, 186, 205, 211, 92, 206, 95, 190, 22, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, +115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, +32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, +83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 48, 59, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, +0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, -114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, -101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, -107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, -101, 116, 40, 99, 49, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, -41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, -0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, +77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, +82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, +48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, +102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, +79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, +95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, +115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, +117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, +116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, +110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, +116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 39, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, +104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, 70, 69, 51, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, +51, 102, 48, 52, 54, 55, 102, 101, 51, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, +97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 221, 146, 60, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 0, 106, 138, 126, 108, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, -10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, -125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, -97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, -99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, -116, 40, 99, 48, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 41, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 49, 46, 122, 41, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, -101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, -101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, -83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, -32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, -48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, -116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, -73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, -59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, -79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, -97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, -59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, -32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, -110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, -116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, -32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 144, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 0, 99, -58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, -92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 207, 223, 61, 148, 168, 156, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 39, 5, 143, 25, 213, 9, 0, 0, 1, 0, 0, -0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, -32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, -48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 96, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 8, 16, 0, 0, 100, 0, 0, -0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, -0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, -0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, -117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, -0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, -0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, -0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, -0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 92, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 8, 12, 128, 128, 40, 8, 0, 13, 23, 1, 128, 140, 12, 128, 128, 0, -0, 42, 0, 77, 17, 4, 3, 0, 0, 88, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 40, 8, 0, 9, 33, 13, 82, 1, 128, 140, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, -0, 1, 0, 0, 0, 16, 1, 70, 50, 7, 101, 25, 7, 89, 250, 189, 40, 242, 8, 125, 92, 183, 48, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 110, 0, 0, -128, 100, 0, 0, 0, 110, 0, 0, 0, 120, 0, 0, 0, 110, 0, 0, 128, 120, 0, 0, 0, 110, 0, 0, 0, 140, 0, 0, 0, 105, 0, 0, 128, 140, 0, 0, 0, 105, 0, 0, 0, 172, 0, 0, 0, 105, 0, 0, 128, 172, 0, 0, 0, 105, 0, 0, 0, 204, 0, 0, 0, 105, 0, 0, -128, 204, 0, 0, 0, 105, 0, 0, 0, 236, 0, 0, 0, 105, 0, 0, 128, 236, 0, 0, 0, 105, 0, 0, 0, 12, 1, 0, 0, 110, 0, 0, 128, 12, 1, 0, 0, 110, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, -0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, -0, 85, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, +112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, +69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 96, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 8, 16, 0, 0, 100, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, +0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, +0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, +0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, +17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, +0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, +0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, +0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, +0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, +0, 1, 0, 172, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 92, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 8, 12, 128, 128, 40, 8, 0, 13, 23, 1, 128, 140, 12, 128, 128, 0, 0, 42, 0, 77, 17, 4, 3, 0, 0, 88, 3, 0, 0, 1, 16, 0, +0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 40, 8, 0, 9, 33, 13, 82, 1, 128, 140, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 163, 81, 188, 104, 12, 83, 156, 246, 0, +178, 239, 190, 114, 55, 253, 77, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 96, 0, 0, 128, 100, 0, 0, 0, 96, 0, 0, 0, 120, 0, 0, 0, 96, 0, 0, +128, 120, 0, 0, 0, 96, 0, 0, 0, 140, 0, 0, 0, 91, 0, 0, 128, 140, 0, 0, 0, 91, 0, 0, 0, 172, 0, 0, 0, 91, 0, 0, 128, 172, 0, 0, 0, 91, 0, 0, 0, 204, 0, 0, 0, 91, 0, 0, 128, 204, 0, 0, 0, 91, 0, 0, 0, 236, 0, 0, 0, 91, 0, 0, +128, 236, 0, 0, 0, 91, 0, 0, 0, 12, 1, 0, 0, 96, 0, 0, 128, 12, 1, 0, 0, 96, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, +0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 180, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, -0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, -18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, -0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, -0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, -0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, -241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, -0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 180, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, +21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, +241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, +0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, +16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 50, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, -108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 51, 46, 122, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, -84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 84, 101, 120, 116, 117, 114, 101, -57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 52, 46, 122, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, -41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, -102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, -76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, -58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, -86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, -32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, -115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, -116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, -46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, -41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, -112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, -112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, -0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, +10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, +110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, +105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, +117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 94, 0, 0, 0, +93, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, +22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, +22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, -0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, -105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, +110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, -0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, -105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, +255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, +110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, +70, 69, 51, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 186, 183, 128, 100, 234, 17, 138, 73, 142, 102, 213, 35, 218, 214, 112, 47, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, +114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, +104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 54, 55, 102, 101, 51, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, +0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, -68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 236, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 87, 8, 0, 0, 128, 0, 0, 0, 108, 7, 0, 0, 124, 4, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, +0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, +0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -671,31 +667,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, -0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, -115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, -114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 204, 180, 142, 105, 1, 0, 0, 0, 165, 1, 241, 92, 160, 53, 1, 76, 186, 205, 211, 92, 206, 95, 190, 22, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, -110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, -116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 54, 52, 50, 55, 54, 52, 48, 57, 56, 56, 0, 4, 0, -0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 236, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 192, 10, 0, 0, 128, 0, 0, 0, 213, 9, 0, 0, 124, 4, 0, -0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 31, 0, 0, 0, 18, 0, 0, 0, 30, 0, 0, 0, 24, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, -0, 23, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 29, 0, 0, -0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -711,16 +691,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, -0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, -102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, -0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, -171, 1, +0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, +68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, +101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, +0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, +0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs index 61d175a8fb..290ac6cfdf 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -16,112 +16,102 @@ namespace Stride.Graphics internal partial class SpriteSignedDistanceFieldFontShader { private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, -116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, -114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, -223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, -1, 75, 232, 212, 98, 177, 92, 143, 80, 82, 224, 27, 220, 221, 195, 119, 120, 0, 192, 9, 0, 0, 68, 88, 66, 67, 8, 194, 56, 206, 130, 168, 158, 248, 193, 94, 8, 161, 221, 107, 150, 96, 1, 0, 0, 0, 192, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, -0, 0, 224, 0, 0, 0, 192, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, -50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 216, 0, 0, 0, 36, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 248, 7, 0, 0, 96, 0, 0, 0, 254, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 224, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 245, 1, -0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, -33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, -255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 99, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, -184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, -0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, -8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, -0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, -24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 66, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 148, 1, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 160, 24, 11, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 48, 16, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, -114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, -109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, -33, 35, 69, 66, 128, 33, 15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 80, 64, 0, 4, 0, -0, 0, 0, 0, 0, 0, 48, 228, 169, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, 99, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 46, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, -2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 2, 0, -0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 43, 164, 50, 34, 0, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 136, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 8, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 34, 0, 0, -0, 40, 7, 2, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 8, 0, 0, 0, 74, 129, 26, 0, 0, 0, 74, 162, 16, 10, 4, 0, 0, 0, 0, 121, 24, 0, 0, 122, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 144, 9, 194, 112, 240, 56, 98, 123, 19, 11, 99, 155, -155, 32, 16, 201, 4, 129, 80, 54, 32, 129, 48, 4, 1, 81, 0, 19, 4, 99, 97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 12, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, -185, 50, 152, 9, 2, 209, 76, 16, 20, 103, 130, 64, 60, 27, 132, 192, 217, 144, 4, 202, 18, 4, 4, 211, 60, 84, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 25, 27, 151, 24, 23, 152, 22, 178, 50, 187, 50, 54, 16, 148, 179, 52, 186, 150, 50, 178, 24, 28, 152, 176, -152, 49, 25, 152, 148, 13, 65, 180, 65, 32, 130, 9, 2, 1, 109, 16, 8, 138, 2, 220, 220, 4, 129, 232, 54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, -79, 82, 68, 19, 132, 166, 12, 38, 8, 141, 180, 33, 8, 38, 8, 13, 181, 97, 9, 196, 96, 12, 200, 160, 12, 204, 128, 48, 131, 128, 12, 128, 13, 1, 49, 65, 104, 204, 96, 195, 66, 136, 193, 24, 144, 1, 26, 152, 1, 145, 6, 4, 25, 0, 27, 132, 51, 80, 3, 38, 83, 86, 95, 84, -97, 114, 103, 101, 116, 19, 132, 230, 12, 54, 44, 1, 27, 140, 65, 27, 148, 1, 25, 16, 105, 16, 144, 1, 176, 33, 112, 131, 13, 195, 26, 188, 1, 64, 57, 152, 130, 147, 75, 163, 43, 155, 74, 59, 115, 43, 35, 35, 74, 155, 163, 11, 115, 27, 43, 51, 74, 43, 99, 35, 51, 122, 115, 163, -155, 66, 11, 35, 43, 147, 115, 129, 154, 106, 10, 75, 115, 251, 186, 146, 11, 131, 131, 43, 147, 219, 80, 116, 113, 0, 7, 28, 80, 133, 141, 205, 174, 205, 37, 141, 172, 204, 141, 110, 74, 16, 85, 33, 195, 115, 177, 43, 147, 155, 75, 123, 115, 155, 18, 72, 77, 200, 240, 92, 236, 194, 216, 236, -202, 228, 166, 4, 84, 29, 50, 60, 151, 57, 180, 48, 178, 50, 185, 166, 55, 178, 50, 182, 41, 193, 85, 134, 12, 207, 69, 174, 108, 238, 173, 78, 110, 172, 108, 110, 74, 176, 85, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 128, 65, 29, 50, 60, -151, 50, 55, 58, 185, 60, 168, 183, 52, 55, 186, 185, 41, 65, 28, 0, 0, 0, 113, 32, 0, 0, 34, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 41, 107, 2, 72, 243, 195, 17, 240, -60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 0, 13, 151, 239, 60, 126, 128, 52, 64, 132, 249, 197, 109, 91, -193, 51, 92, 190, 243, 248, 84, 3, 68, 152, 95, 220, 182, 25, 84, 195, 229, 59, 143, 47, 77, 78, 68, 160, 212, 244, 80, 147, 95, 220, 54, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 103, 128, 129, 1, 24, 88, 215, 136, 65, 2, 128, 32, -24, 56, 104, 144, 133, 65, 24, 88, 216, 136, 65, 2, 128, 32, 24, 56, 105, 160, 133, 129, 24, 96, 217, 136, 65, 2, 128, 32, 24, 56, 106, 176, 137, 193, 24, 96, 218, 136, 65, 2, 128, 32, 24, 56, 107, 192, 141, 1, 25, 96, 219, 136, 65, 2, 128, 32, 24, 56, 108, 208, 145, 65, 25, 96, -220, 136, 65, 2, 128, 32, 24, 68, 108, 128, 101, 102, 96, 6, 96, 48, 98, 144, 0, 32, 8, 6, 81, 27, 100, 221, 25, 156, 65, 24, 140, 24, 60, 0, 8, 130, 193, 212, 6, 88, 32, 32, 71, 150, 125, 223, 151, 141, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 140, 24, 28, -0, 8, 130, 1, 21, 7, 28, 49, 140, 24, 28, 0, 8, 130, 1, 37, 7, 92, 65, 140, 24, 28, 0, 8, 130, 1, 53, 7, 94, 64, 140, 24, 28, 0, 8, 130, 1, 69, 7, 222, 16, 88, 224, 65, 96, 196, 192, 0, 64, 16, 12, 170, 58, 240, 130, 17, 3, 3, 0, 65, 48, 168, 236, 192, -11, 70, 12, 12, 0, 4, 193, 160, 186, 3, 111, 24, 49, 48, 0, 16, 4, 131, 10, 15, 192, 32, 176, 96, 128, 128, 5, 96, 32, 1, 19, 62, 9, 24, 34, 64, 192, 2, 129, 2, 35, 6, 6, 0, 130, 96, 80, 249, 65, 24, 4, 22, 6, 129, 4, 44, 40, 3, 8, 216, 16, 72, 192, 136, -64, 2, 22, 4, 18, 176, 47, 144, 128, 125, 130, 4, 236, 27, 36, 96, 31, 33, 129, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 246, 128, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 65, 15, 134, 17, 131, 4, 0, 65, 48, 176, 78, 33, 13, 74, 161, 20, 242, -64, 24, 49, 72, 0, 16, 4, 3, 235, 20, 210, 160, 20, 74, 1, 15, 2, 4, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 136, 128, 103, 144, 24, 53, 93, 2, 142, 232, 27, 153, 37, 11, 4, 182, 0, 17, 10, 0, 0, 68, 88, 66, 67, 143, 14, 115, 78, 42, 197, 186, 101, 82, 45, -55, 134, 208, 14, 83, 50, 1, 0, 0, 0, 17, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, 141, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, -0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, -0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, -82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 40, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 2, -0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, -0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, -88, 73, 76, 124, 7, 0, 0, 96, 0, 1, 0, 223, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 100, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 214, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, -16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, -174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, -76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 5, 0, 0, 0, 192, 29, 224, 226, -4, 192, 34, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 33, 0, 0, 0, 0, 238, 72, 137, 168, 139, 0, 11, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, -0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, -19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, -0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, -115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, -208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, -134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, -0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 208, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 12, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 130, 146, 35, 6, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, -41, 160, 2, 43, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 116, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, -1, 85, 38, 71, 36, 23, 118, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 213, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 198, 198, 37, 198, 5, 166, 133, 172, 204, 174, 140, 13, 4, 229, 44, 141, 174, 165, 140, 44, 6, 7, 38, 44, 102, 76, 6, 38, 101, 67, -176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 178, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 180, 9, 130, 210, 108, 8, -130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 101, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 19, 4, 34, 218, 16, 140, 193, 134, 101, 12, 180, 141, 35, 3, 142, 8, 131, 49, 224, 128, 13, 195, 39, 6, 101, 176, 97, 9, 180, 141, 235, 60, -194, 11, 56, 96, 195, 66, 104, 27, 7, 6, 30, 17, 6, 4, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 101, 12, 210, 96, 83, 131, 46, 12, 136, 48, 24, 3, 14, 216, 48, 156, 1, 26, 172, 193, 134, 193, 12, 216, 0, 160, 28, 76, 193, 201, 165, 209, -149, 77, 165, 157, 185, 149, 145, 17, 165, 205, 209, 133, 185, 141, 149, 25, 165, 149, 177, 145, 25, 189, 185, 209, 77, 161, 133, 145, 149, 201, 185, 88, 77, 53, 133, 165, 185, 125, 93, 201, 133, 193, 193, 149, 201, 109, 40, 42, 55, 104, 3, 10, 168, 194, 198, 102, 215, 230, 146, 70, 86, 230, 70, 55, -37, 88, 170, 144, 225, 185, 216, 149, 201, 205, 165, 189, 185, 77, 9, 152, 38, 100, 120, 46, 118, 97, 108, 118, 101, 114, 83, 2, 167, 14, 25, 158, 203, 28, 90, 24, 89, 153, 92, 211, 27, 89, 25, 219, 148, 32, 42, 67, 134, 231, 34, 87, 54, 247, 86, 39, 55, 86, 54, 55, 37, 152, 42, 145, -225, 185, 208, 229, 193, 149, 5, 185, 185, 189, 209, 133, 209, 165, 189, 185, 205, 77, 9, 176, 58, 100, 120, 46, 101, 110, 116, 114, 121, 80, 111, 105, 110, 116, 115, 83, 2, 55, 0, 113, 32, 0, 0, 29, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, -16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, -84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 0, 97, 32, 0, 0, 133, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 91, 100, 89, 15, 52, 98, 144, 0, 32, 8, 6, -11, 39, 93, 215, 19, 141, 24, 36, 0, 8, 130, 193, 210, 77, 23, 22, 73, 35, 6, 9, 0, 130, 96, 176, 120, 20, 150, 69, 211, 136, 65, 2, 128, 32, 24, 44, 95, 149, 105, 17, 53, 98, 144, 0, 32, 8, 6, 11, 24, 88, 218, 22, 85, 35, 6, 9, 0, 130, 96, 176, 132, 193, 21, 113, -149, 53, 98, 144, 0, 32, 8, 6, 139, 24, 96, 82, 87, 93, 35, 6, 9, 0, 130, 96, 176, 140, 65, 54, 121, 21, 54, 98, 144, 0, 32, 8, 6, 11, 25, 104, 212, 87, 101, 35, 6, 9, 0, 130, 96, 240, 144, 1, 117, 125, 223, 84, 97, 192, 225, 136, 193, 1, 128, 32, 24, 68, 101, 64, -9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 157, 1, 6, 21, 140, 1, 142, 24, 28, 0, 8, 130, 65, 196, 6, 91, 18, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 148, 27, 120, 80, 129, 26, 224, 136, 193, 1, 128, 32, 24, 68, 115, 32, 6, -80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 117, 64, 6, 80, 65, 28, 224, 136, 193, 1, 128, 32, 24, 68, 122, 144, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 96, 86, 24, 72, 192, 32, 49, 144, 128, 41, 99, 32, 1, 35, 200, 64, -2, 182, 153, 129, 4, 44, 40, 32, 96, 22, 26, 72, 192, 2, 3, 2, 22, 169, 129, 4, 44, 56, 32, 96, 12, 27, 72, 192, 2, 4, 2, 70, 6, 111, 32, 1, 11, 16, 8, 216, 23, 7, 18, 176, 0, 129, 128, 105, 115, 32, 1, 11, 16, 8, 88, 85, 7, 18, 176, 0, 129, 128, 181, 1, -30, 72, 192, 2, 4, 2, 134, 6, 122, 32, 1, 11, 16, 8, 216, 24, 240, 129, 4, 44, 64, 32, 96, 158, 31, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 180, 2, 46, 196, 194, 49, 98, 144, 0, 32, 8, 6, 146, 46, 152, 66, 43, 224, 2, 44, 20, 35, 6, 9, -0, 130, 96, 32, 233, 130, 41, 180, 2, 46, 188, 194, 48, 98, 144, 0, 32, 8, 6, 146, 46, 152, 66, 43, 224, 130, 43, 4, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 224, 2, 46, 196, 130, 40, 140, 24, 36, 0, 8, 130, 129, 164, 11, 166, 128, 11, 184, 0, 11, 161, 48, 98, 144, 0, -32, 8, 6, 146, 46, 152, 194, 45, 224, 66, 44, 240, 193, 136, 65, 2, 128, 32, 24, 72, 186, 96, 10, 183, 128, 11, 176, 176, 7, 35, 6, 9, 0, 130, 96, 32, 233, 130, 41, 220, 2, 46, 188, 130, 30, 140, 24, 36, 0, 8, 130, 129, 164, 11, 166, 112, 11, 184, 224, 10, 121, 128, 0, 0, -0, 0, 0, 1, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, +57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, +10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, +67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 72, 98, 250, 225, 204, 222, 93, 206, 84, 106, 176, 150, 83, 33, 56, 28, 0, 104, 9, 0, 0, 68, 88, 66, 67, 47, 49, 107, 184, 209, 56, 46, 22, 101, 148, 97, 181, 122, 116, 74, 52, 1, 0, 0, 0, 104, 9, 0, +0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, +114, 103, 101, 116, 0, 80, 83, 86, 48, 200, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 176, 7, 0, 0, 96, 0, 0, 0, 236, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 152, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 227, 1, 0, +0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, +35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, +255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, +64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 96, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, +122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, +1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 3, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, +7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, +109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, +8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, +51, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, +0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, 0, 0, 0, 160, +80, 3, 138, 161, 76, 3, 104, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, 162, 16, 10, 4, +0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, 232, 234, 228, 210, +220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, +110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, +41, 162, 9, 130, 50, 6, 19, 4, 5, 218, 16, 4, 19, 4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, +82, 6, 27, 150, 224, 12, 60, 52, 0, 131, 143, 32, 131, 224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, 13, 214, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, 67, 134, 231, 50, +135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, +221, 220, 148, 128, 13, 0, 0, 0, 0, 113, 32, 0, 0, 34, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, +47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 0, 13, 151, 239, 60, 126, 128, 52, 64, 132, 249, 197, 109, 91, 193, 51, 92, 190, 243, 248, 84, 3, 68, +152, 95, 220, 182, 25, 84, 195, 229, 59, 143, 47, 77, 78, 68, 160, 212, 244, 80, 147, 95, 220, 54, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, 216, 136, 65, 2, +128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, 1, 150, 145, 1, +25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, 32, 8, 6, 208, 26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, 98, 112, 0, 32, +8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, 32, 8, 6, 145, 28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, 14, 188, 97, 196, +192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, 136, 0, 1, 11, 4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, 246, 9, 18, 176, +111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, 98, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, +24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 51, 252, 223, 215, 16, 58, 169, 160, 66, 54, 166, 105, 117, 33, 208, 250, 0, 185, 9, 0, 0, 68, 88, 66, 67, 108, 34, 100, 210, 67, 201, 128, 38, 53, 94, 175, 77, 13, 75, 159, 20, 1, 0, 0, +0, 185, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, 125, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, +0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, +3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, +105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 24, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, +68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 52, 7, 0, 0, 96, 0, 1, 0, 205, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, +0, 0, 28, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 196, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, +65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, +168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, +133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, +4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, +0, 128, 0, 0, 0, 128, 0, 0, 0, 32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, +160, 24, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, +122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, +160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, 0, 0, 50, 30, +152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 57, 74, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, +43, 144, 2, 42, 176, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 0, 0, 121, 24, 0, 0, 107, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, +131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 184, 54, 12, 76, 19, 108, 8, 140, 13, +4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 3, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 178, 13, 11, 97, 93, 24, 135, +17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 13, 195, 230, 133, 193, 134, 37, 176, 46, 44, 211, 8, 45, 192, 128, 13, 11, 97, 93, 24, 167, 17, 29, 129, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 135, 179, 97, 249, +202, 224, 50, 131, 172, 35, 186, 15, 3, 54, 12, 99, 64, 6, 103, 176, 97, 16, 3, 52, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, +110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 72, 13, 210, 0, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 142, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 164, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 64, 169, 67, 134, 231, 50, 135, 22, 70, +86, 38, 215, 244, 70, 86, 198, 54, 37, 104, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 158, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 2, 170, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, +64, 13, 0, 0, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, +136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, +0, 0, 97, 32, 0, 0, 133, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 89, 68, 81, 15, 52, 98, 144, 0, 32, 8, 6, 136, 38, 85, 213, 19, 141, 24, 36, 0, 8, 130, 1, 178, 77, 149, 21, 73, 35, 6, 9, 0, 130, 96, 128, 112, 148, 117, 69, 211, 136, 65, 2, 128, +32, 24, 32, 93, 117, 97, 17, 53, 98, 144, 0, 32, 8, 6, 136, 103, 97, 89, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 145, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, 38, 109, 213, 53, 98, 144, 0, 32, 8, 6, 72, 24, 100, 19, 87, 97, 35, 6, 9, 0, 130, 96, 128, 136, +129, 70, 117, 85, 54, 98, 144, 0, 32, 8, 6, 140, 24, 80, 151, 231, 77, 245, 113, 56, 98, 112, 0, 32, 8, 6, 206, 24, 80, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 101, 128, 65, 5, 99, 128, 35, 6, 7, 0, 130, 96, 224, 168, 193, 150, 4, 163, 9, +1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 197, 6, 30, 84, 160, 6, 56, 98, 112, 0, 32, 8, 6, 78, 28, 136, 1, 20, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 28, 144, 1, 84, 16, 7, 56, 98, 112, 0, 32, 8, 6, 14, 30, 164, 193, 21, 140, +38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 152, 21, 6, 18, 48, 72, 12, 36, 96, 202, 24, 72, 192, 8, 50, 144, 128, 109, 102, 32, 1, 11, 10, 8, 152, 133, 6, 18, 176, 192, 128, 128, 69, 106, 32, 1, 11, 14, 8, 24, 195, 6, 18, 176, 0, 129, 128, 145, 193, 27, 72, +192, 2, 4, 2, 246, 197, 129, 4, 44, 64, 32, 96, 218, 28, 72, 192, 2, 4, 2, 86, 213, 129, 4, 44, 64, 32, 96, 109, 128, 7, 18, 176, 0, 129, 128, 161, 129, 30, 72, 192, 2, 4, 2, 54, 6, 124, 32, 1, 11, 16, 8, 152, 231, 7, 18, 176, 0, 129, 192, 136, 65, 2, 128, 32, +24, 60, 184, 96, 10, 173, 96, 11, 177, 112, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 0, 11, 197, 136, 65, 2, 128, 32, 24, 60, 184, 96, 10, 173, 96, 11, 175, 48, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 224, 10, 193, 136, 65, 2, 128, 32, 24, 60, +184, 96, 10, 182, 96, 11, 177, 32, 10, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 216, 130, 45, 192, 66, 40, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 80, 11, 182, 16, 11, 124, 48, 98, 144, 0, 32, 8, 6, 15, 46, 152, 66, 45, 216, 2, 44, 236, 193, 136, 65, 2, 128, 32, 24, +60, 184, 96, 10, 181, 96, 11, 175, 160, 7, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 212, 130, 45, 184, 66, 30, 32, 0, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index dfa477b04b..50a766bb6c 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -16,301 +16,310 @@ namespace Stride.Graphics internal partial class SpriteSignedDistanceFieldFontShader { private static readonly byte[] spriteSignedDistanceFieldFontBytecode = new byte[] { -8, 192, 254, 239, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, -114, 97, 119, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 80, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 0, 8, 0, 0, 0, 1, 1, -1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, -49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 8, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, -101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 16, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, -1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 24, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, -3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, -101, 108, 83, 105, 122, 101, 32, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, -120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 40, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 48, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, -1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, -122, 101, 56, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, -105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 64, 0, 0, 0, 8, 0, 0, 0, 1, 1, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 27, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 17, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 72, 0, 0, 0, 8, 0, 0, 0, 1, 1, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, -0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, -0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, -116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, -114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, -223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, -1, 131, 237, 166, 246, 238, 248, 125, 128, 31, 77, 41, 72, 186, 209, 157, 207, 0, 128, 33, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 187, 0, 0, 0, 71, 76, 83, 76, 46, 115, -116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 83, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 71, 1, 0, 0, 73, 1, 0, 0, 69, 1, 0, 0, 79, 1, -0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 122, 1, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 104, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 93, 1, 0, 0, 96, 1, 0, 0, 97, 1, 0, 0, 92, 1, 0, 0, 94, 1, 0, 0, 98, 1, -0, 0, 103, 1, 0, 0, 111, 0, 0, 0, 122, 1, 0, 0, 16, 0, 3, 0, 83, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, -112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, -0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, -119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, -120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 175, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, -11, 0, 176, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 179, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, -108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 180, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 181, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 182, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, -108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 197, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, -67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 200, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 204, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, -0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 97, 120, 105, 115, 68, 105, -115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 214, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, -116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 233, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 236, 0, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 250, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 247, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, -0, 0, 5, 0, 5, 0, 253, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 3, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, -5, 0, 7, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 248, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, -13, 0, 39, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 0, 5, 0, 4, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 70, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 69, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 71, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, -7, 0, 74, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 73, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 75, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, -0, 0, 6, 0, 6, 0, 75, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 76, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, -0, 0, 6, 0, 6, 0, 76, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 77, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 77, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 77, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 77, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 79, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 80, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, -116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 15, 0, 83, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, -114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 8, 0, 92, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 93, 1, 0, 0, 105, 110, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 95, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 94, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, -6, 0, 96, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 97, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 98, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, -0, 0, 5, 0, 5, 0, 99, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 99, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 100, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 100, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, -103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 100, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 101, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 101, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, -6, 0, 101, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 101, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 102, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 103, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 104, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 111, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 120, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, -0, 0, 5, 0, 9, 0, 121, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 122, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, -0, 0, 71, 0, 4, 0, 69, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 71, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 71, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 73, 1, -0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 73, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 92, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 93, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, -6, 0, 93, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 94, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 94, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, -4, 0, 96, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 96, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 97, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 97, 1, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 98, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 98, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 120, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 120, 1, -0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 3, 0, -0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 6, 0, 0, 0, 35, 0, -0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 7, 0, 0, 0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, -0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, -0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, -4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, 0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, -0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, -0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, 0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, -0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, -4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, 0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, -0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, -0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, 0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 179, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 178, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 179, 0, -0, 0, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, 0, 33, 0, 7, 0, 195, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 179, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 43, 0, -4, 0, 4, 0, 0, 0, 206, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 4, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 211, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, -4, 0, 133, 0, 0, 0, 223, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 236, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 64, 43, 0, -4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 63, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 70, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 72, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, -4, 0, 74, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, 0, 75, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 76, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 77, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, -4, 0, 78, 1, 0, 0, 6, 0, 0, 0, 77, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 81, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 32, 0, -4, 0, 95, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, 0, 99, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 101, 1, 0, 0, 3, 0, -0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 6, 0, 0, 0, 101, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 120, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, -0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 121, 1, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, -4, 0, 121, 1, 0, 0, 122, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 69, 1, 0, 0, 3, 0, 0, 0, 59, 0, -4, 0, 72, 1, 0, 0, 71, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 78, 1, 0, 0, 79, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 92, 1, 0, 0, 3, 0, 0, 0, 59, 0, -4, 0, 72, 1, 0, 0, 93, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 94, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 96, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 97, 1, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 70, 1, 0, 0, 98, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 103, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, -0, 0, 128, 0, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 130, 0, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, -0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, -5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 39, 1, 0, 0, 62, 0, -3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, -5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, -0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, 0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 55, 0, -3, 0, 179, 0, 0, 0, 180, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 181, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 182, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 185, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 186, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 188, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 189, 0, -0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 190, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 188, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 182, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 192, 0, 0, 0, 187, 0, -0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 193, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 186, 0, 0, 0, 192, 0, 0, 0, 254, 0, 2, 0, 193, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, -0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 197, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 198, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 199, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 200, 0, 0, 0, 248, 0, 2, 0, 201, 0, -0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 208, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 210, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 215, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 222, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 229, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 233, 0, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 253, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 7, 1, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 204, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 207, 0, 0, 0, 187, 0, -0, 0, 43, 0, 0, 0, 202, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 207, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 200, 0, 0, 0, 131, 0, 5, 0, 4, 0, -0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, 0, 210, 0, 0, 0, 213, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 216, 0, 0, 0, 62, 0, -3, 0, 215, 0, 0, 0, 217, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 220, 0, 0, 0, 197, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 221, 0, 0, 0, 65, 0, 5, 0, 179, 0, -0, 0, 224, 0, 0, 0, 197, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, 0, 224, 0, 0, 0, 62, 0, 3, 0, 222, 0, 0, 0, 225, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 228, 0, 0, 0, 175, 0, 0, 0, 215, 0, 0, 0, 218, 0, -0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 230, 0, -0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 0, 0, 0, 229, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 235, 0, -0, 0, 236, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 237, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 233, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 233, 0, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 243, 0, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 243, 0, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 244, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 245, 0, 0, 0, 238, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 246, 0, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 249, 0, 0, 0, 200, 0, 0, 0, 186, 0, 5, 0, 7, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 247, 0, 3, 0, 248, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 252, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 248, 0, -2, 0, 247, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 255, 0, 0, 0, 200, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 129, 0, 5, 0, 4, 0, -0, 0, 2, 1, 0, 0, 254, 0, 0, 0, 1, 1, 0, 0, 62, 0, 3, 0, 253, 0, 0, 0, 2, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 5, 1, 0, 0, 253, 0, 0, 0, 131, 0, 5, 0, 4, 0, -0, 0, 6, 1, 0, 0, 4, 1, 0, 0, 5, 1, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 6, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 3, 1, 0, 0, 133, 0, 5, 0, 4, 0, -0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 12, 1, 0, 0, 11, 1, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 13, 1, 0, 0, 10, 1, 0, 0, 12, 1, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 253, 0, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 15, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 1, 0, 0, 204, 0, -0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 18, 1, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 1, 0, 0, 7, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 20, 1, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 19, 1, -0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 20, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 21, 1, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 1, 0, 0, 16, 1, 0, 0, 80, 0, -7, 0, 3, 0, 0, 0, 24, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 25, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 198, 0, -0, 0, 25, 1, 0, 0, 249, 0, 2, 0, 248, 0, 0, 0, 248, 0, 2, 0, 248, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 26, 1, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 27, 1, 0, 0, 198, 0, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 238, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 30, 1, 0, 0, 187, 0, 0, 0, 46, 0, -0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 197, 0, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 31, 1, 0, 0, 197, 0, 0, 0, 254, 0, 2, 0, 31, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 39, 1, -0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 46, 1, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 55, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 61, 1, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 65, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 54, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 54, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 59, 1, 0, 0, 79, 1, 0, 0, 81, 1, -0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, 60, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 64, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 61, 1, -0, 0, 64, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 62, 1, 0, 0, 57, 0, 8, 0, 3, 0, 0, 0, 68, 1, 0, 0, 176, 0, 0, 0, 51, 1, 0, 0, 55, 1, 0, 0, 61, 1, 0, 0, 65, 1, 0, 0, 254, 0, 2, 0, 68, 1, 0, 0, 56, 0, 1, 0, 54, 0, -5, 0, 28, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 84, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 85, 1, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 86, 1, 0, 0, 71, 1, 0, 0, 62, 0, -3, 0, 85, 1, 0, 0, 86, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 87, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 88, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 87, 1, 0, 0, 88, 1, 0, 0, 57, 0, 4, 0, 28, 0, -0, 0, 89, 1, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 90, 1, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 91, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 69, 1, 0, 0, 91, 1, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 104, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 105, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 106, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 107, 1, 0, 0, 93, 1, -0, 0, 62, 0, 3, 0, 106, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 108, 1, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 109, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 109, 1, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 110, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 112, 1, 0, 0, 97, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 112, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 113, 1, 0, 0, 112, 0, 0, 0, 65, 0, -5, 0, 2, 0, 0, 0, 114, 1, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 115, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 115, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 82, 1, -0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 117, 1, 0, 0, 116, 1, 0, 0, 62, 0, 3, 0, 94, 1, 0, 0, 117, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 118, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 119, 1, 0, 0, 118, 1, -0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 119, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 131, 237, 166, 246, 238, 248, 125, 128, 31, 77, 41, 72, 186, 209, 157, 207, -0, 128, 33, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 187, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, -0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 83, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 71, 1, 0, 0, 73, 1, 0, 0, 69, 1, 0, 0, 79, 1, 0, 0, 36, 0, 0, 0, 83, 0, 0, 0, 122, 1, 0, 0, 15, 0, 16, -0, 0, 0, 0, 0, 104, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 93, 1, 0, 0, 96, 1, 0, 0, 97, 1, 0, 0, 92, 1, 0, 0, 94, 1, 0, 0, 98, 1, 0, 0, 103, 1, 0, 0, 111, 0, 0, 0, 122, 1, 0, 0, 16, 0, 3, -0, 83, 1, 0, 0, 7, 0, 0, 0, 5, 0, 7, 0, 2, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 6, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, -0, 5, 0, 7, 0, 17, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 21, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 33, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 36, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, -0, 5, 0, 7, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 58, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, -95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 11, 0, 64, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 70, 0, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 81, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, -0, 83, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 107, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 107, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, -114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 112, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 113, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, -105, 110, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 111, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 117, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 132, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 134, 0, 0, 0, 105, 110, 116, -95, 48, 0, 0, 0, 5, 0, 10, 0, 175, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 176, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 179, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 180, 0, 0, 0, 114, 0, 0, -0, 5, 0, 3, 0, 181, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 182, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 197, 0, 0, 0, 115, 97, 109, -112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 200, 0, 0, 0, 98, 111, 114, -100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 204, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, -115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 211, 0, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 214, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, -95, 50, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 233, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, -0, 238, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 250, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 247, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 253, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, -97, 110, 99, 101, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 3, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 7, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, -0, 5, 0, 6, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 248, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 39, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, -100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, -0, 5, 0, 7, 0, 70, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 69, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 72, 1, 0, -0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 71, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 74, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, -108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 73, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 75, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 75, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 75, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 76, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 76, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 77, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 77, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 77, 1, 0, 0, 1, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 77, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, -0, 5, 0, 5, 0, 79, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 4, 0, 80, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, -95, 49, 0, 0, 0, 5, 0, 15, 0, 83, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -0, 5, 0, 8, 0, 92, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 93, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 95, 1, 0, -0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 94, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 96, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, -105, 111, 110, 0, 0, 5, 0, 5, 0, 97, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 98, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 99, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, -84, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 99, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 99, 1, 0, 0, 2, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 100, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 100, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 100, 1, 0, -0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 100, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 101, 1, 0, -0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 101, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 101, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, -110, 0, 0, 0, 0, 6, 0, 5, 0, 101, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 102, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 103, 1, 0, -0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 104, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 111, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 6, 0, 120, 1, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 2, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 3, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 4, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 5, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 6, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 7, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 8, 0, 0, 0, 84, 101, 120, -116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 6, 0, 8, 0, 120, 1, 0, 0, 9, 0, 0, 0, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 0, 0, 0, 5, 0, 9, 0, 121, 1, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 122, 1, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 107, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 69, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 71, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 71, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 73, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 73, 1, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 92, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 93, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 93, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 94, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 94, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 96, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, -0, 96, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 97, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 97, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 98, 1, 0, -0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 98, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 3, 0, 120, 1, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 5, -0, 120, 1, 0, 0, 1, 0, 0, 0, 35, 0, 0, 0, 8, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 24, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, -0, 4, 0, 0, 0, 35, 0, 0, 0, 32, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 5, 0, 0, 0, 35, 0, 0, 0, 40, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 6, 0, 0, 0, 35, 0, 0, 0, 48, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 7, 0, 0, -0, 35, 0, 0, 0, 56, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 8, 0, 0, 0, 35, 0, 0, 0, 64, 0, 0, 0, 72, 0, 5, 0, 120, 1, 0, 0, 9, 0, 0, 0, 35, 0, 0, 0, 72, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, -0, 0, 0, 0, 0, 72, 0, 4, 0, 107, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 107, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 36, 0, 0, -0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 122, 1, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 83, 0, 0, -0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 111, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 4, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 3, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 20, 0, 2, 0, 7, 0, 0, 0, 32, 0, 4, 0, 6, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 32, 0, 4, 0, 17, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 21, 0, 4, -0, 22, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 21, 0, 0, 0, 6, 0, 0, 0, 22, 0, 0, 0, 19, 0, 2, 0, 28, 0, 0, 0, 33, 0, 3, 0, 29, 0, 0, 0, 28, 0, 0, 0, 25, 0, 9, 0, 34, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, -0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 33, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 23, 0, 4, 0, 38, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 2, 0, 0, -0, 38, 0, 0, 0, 25, 0, 9, 0, 59, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 58, 0, 0, 0, 0, 0, 0, 0, 59, 0, 0, 0, 25, 0, 9, 0, 65, 0, 0, -0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 64, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 32, 0, 4, 0, 70, 0, 0, 0, 6, 0, 0, 0, 38, 0, 0, 0, 26, 0, 2, -0, 82, 0, 0, 0, 32, 0, 4, 0, 81, 0, 0, 0, 0, 0, 0, 0, 82, 0, 0, 0, 24, 0, 4, 0, 108, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 107, 0, 0, 0, 108, 0, 0, 0, 32, 0, 4, 0, 117, 0, 0, 0, 2, 0, 0, 0, 107, 0, 0, -0, 32, 0, 4, 0, 132, 0, 0, 0, 2, 0, 0, 0, 108, 0, 0, 0, 21, 0, 4, 0, 133, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 134, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 146, 0, 0, 0, 3, 0, 0, 0, 27, 0, 3, -0, 170, 0, 0, 0, 34, 0, 0, 0, 32, 0, 4, 0, 179, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 6, 0, 178, 0, 0, 0, 4, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 179, 0, 0, 0, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 3, 0, 0, -0, 33, 0, 7, 0, 195, 0, 0, 0, 3, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 196, 0, 0, 0, 179, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 206, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, -0, 4, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 4, 0, 0, 0, 211, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 133, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 223, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, -0, 4, 0, 0, 0, 236, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 4, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 4, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, -0, 4, 0, 0, 0, 63, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 70, 1, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 72, 1, 0, 0, 1, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 74, 1, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 30, 0, 4, -0, 75, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 3, 0, 76, 1, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 77, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 78, 1, 0, 0, 6, 0, 0, 0, 77, 1, 0, 0, 43, 0, 4, -0, 133, 0, 0, 0, 80, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 81, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 32, 0, 4, 0, 95, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 30, 0, 5, -0, 99, 1, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 30, 0, 5, 0, 100, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 30, 0, 6, 0, 101, 1, 0, 0, 3, 0, 0, 0, 38, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, -0, 102, 1, 0, 0, 6, 0, 0, 0, 101, 1, 0, 0, 43, 0, 4, 0, 133, 0, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 30, 0, 12, 0, 120, 1, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, -0, 38, 0, 0, 0, 38, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 121, 1, 0, 0, 2, 0, 0, 0, 120, 1, 0, 0, 59, 0, 4, 0, 33, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 121, 1, 0, 0, 122, 1, 0, 0, 2, 0, 0, 0, 59, 0, 4, -0, 81, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 117, 0, 0, 0, 111, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 69, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 72, 1, 0, 0, 71, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 74, 1, 0, 0, 73, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 78, 1, 0, 0, 79, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 92, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 72, 1, 0, 0, 93, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 95, 1, 0, 0, 94, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 96, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 74, 1, 0, 0, 97, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 98, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 102, 1, 0, 0, 103, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 28, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 248, 0, 2, 0, 121, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 128, 0, 0, 0, 103, 1, 0, 0, 80, 1, 0, 0, 65, 0, 5, -0, 2, 0, 0, 0, 130, 0, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 131, 0, 0, 0, 130, 0, 0, 0, 65, 0, 5, 0, 132, 0, 0, 0, 135, 0, 0, 0, 111, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 108, 0, 0, 0, 136, 0, 0, -0, 135, 0, 0, 0, 145, 0, 5, 0, 3, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 131, 0, 0, 0, 62, 0, 3, 0, 128, 0, 0, 0, 137, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, -0, 248, 0, 2, 0, 139, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 144, 0, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 57, 0, 4, 0, 3, 0, 0, 0, 148, 0, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 148, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 3, 0, 0, 0, 114, 0, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 149, 0, 0, 0, 61, 0, 4, 0, 82, 0, 0, 0, 160, 0, 0, 0, 83, 0, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 167, 0, 0, 0, 79, 1, 0, 0, 82, 1, 0, -0, 61, 0, 4, 0, 38, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 61, 0, 4, 0, 34, 0, 0, 0, 169, 0, 0, 0, 36, 0, 0, 0, 86, 0, 5, 0, 170, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 160, 0, 0, 0, 87, 0, 6, 0, 3, 0, 0, 0, 172, 0, 0, -0, 171, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 172, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 178, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 180, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, -0, 181, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 182, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 184, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 185, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, -0, 186, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 188, 0, 0, 0, 180, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 189, 0, 0, 0, 181, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 190, 0, 0, -0, 187, 0, 0, 0, 40, 0, 0, 0, 188, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 0, 0, 0, 182, 0, 0, 0, 12, 0, 7, 0, 4, 0, 0, 0, 192, 0, 0, 0, 187, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, -0, 4, 0, 0, 0, 193, 0, 0, 0, 187, 0, 0, 0, 40, 0, 0, 0, 186, 0, 0, 0, 192, 0, 0, 0, 254, 0, 2, 0, 193, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 176, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, -0, 197, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 198, 0, 0, 0, 55, 0, 3, 0, 196, 0, 0, 0, 199, 0, 0, 0, 55, 0, 3, 0, 179, 0, 0, 0, 200, 0, 0, 0, 248, 0, 2, 0, 201, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 208, 0, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 179, 0, 0, 0, 210, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 215, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 179, 0, 0, 0, 222, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 229, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 233, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 179, 0, 0, 0, 253, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 205, 0, 0, 0, 204, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 207, 0, 0, 0, 187, 0, 0, 0, 43, 0, 0, 0, 202, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, -0, 62, 0, 3, 0, 200, 0, 0, 0, 207, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 200, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 213, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, -0, 210, 0, 0, 0, 213, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 216, 0, 0, 0, 197, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 215, 0, 0, 0, 217, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, -0, 220, 0, 0, 0, 197, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 221, 0, 0, 0, 65, 0, 5, 0, 179, 0, 0, 0, 224, 0, 0, 0, 197, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 225, 0, 0, 0, 224, 0, 0, 0, 62, 0, 3, 0, 222, 0, 0, 0, 225, 0, 0, 0, 57, 0, 7, 0, 4, 0, 0, 0, 228, 0, 0, 0, 175, 0, 0, 0, 215, 0, 0, 0, 218, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 228, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 230, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 229, 0, 0, 0, 232, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 0, 0, 0, 229, 0, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 237, 0, 0, 0, 235, 0, 0, 0, 236, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 237, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 239, 0, 0, 0, 233, 0, 0, 0, 127, 0, 4, 0, 4, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 241, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, -0, 12, 0, 8, 0, 4, 0, 0, 0, 243, 0, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 244, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 245, 0, 0, 0, 238, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 246, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 249, 0, 0, 0, 200, 0, 0, 0, 186, 0, 5, -0, 7, 0, 0, 0, 252, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 247, 0, 3, 0, 248, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 252, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 248, 0, 2, 0, 247, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, -0, 210, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 255, 0, 0, 0, 200, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 2, 1, 0, 0, 254, 0, 0, 0, 1, 1, 0, 0, 62, 0, 3, -0, 253, 0, 0, 0, 2, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 4, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 5, 1, 0, 0, 253, 0, 0, 0, 131, 0, 5, 0, 4, 0, 0, 0, 6, 1, 0, 0, 4, 1, 0, 0, 5, 1, 0, 0, 62, 0, 3, -0, 3, 1, 0, 0, 6, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 3, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 209, 0, 4, 0, 4, 0, 0, 0, 12, 1, 0, 0, 11, 1, 0, 0, 136, 0, 5, 0, 4, 0, 0, 0, 13, 1, 0, 0, 10, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 14, 1, 0, 0, 253, 0, 0, -0, 129, 0, 5, 0, 4, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 15, 1, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 17, 1, 0, 0, 204, 0, 0, 0, 111, 0, 4, 0, 4, 0, 0, 0, 18, 1, 0, 0, 219, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 1, 0, 0, 7, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 20, 1, 0, 0, 187, 0, 0, 0, 49, 0, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 20, 1, 0, 0, 61, 0, 4, -0, 3, 0, 0, 0, 21, 1, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 22, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 1, 0, 0, 16, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 24, 1, 0, 0, 23, 1, 0, 0, 23, 1, 0, -0, 23, 1, 0, 0, 23, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 25, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 21, 1, 0, 0, 22, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 25, 1, 0, 0, 249, 0, 2, 0, 248, 0, 0, 0, 248, 0, 2, -0, 248, 0, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 26, 1, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 250, 0, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 27, 1, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 238, 0, 0, -0, 80, 0, 7, 0, 3, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 28, 1, 0, 0, 12, 0, 8, 0, 3, 0, 0, 0, 30, 1, 0, 0, 187, 0, 0, 0, 46, 0, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, -0, 197, 0, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 31, 1, 0, 0, 197, 0, 0, 0, 254, 0, 2, 0, 31, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 3, 0, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 146, 0, 0, 0, 248, 0, 2, 0, 46, 1, 0, -0, 59, 0, 4, 0, 196, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 55, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 61, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 179, 0, 0, 0, 65, 1, 0, 0, 7, 0, 0, -0, 57, 0, 4, 0, 3, 0, 0, 0, 54, 1, 0, 0, 114, 0, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 54, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 59, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 60, 1, 0, 0, 59, 1, 0, -0, 62, 0, 3, 0, 55, 1, 0, 0, 60, 1, 0, 0, 80, 0, 7, 0, 3, 0, 0, 0, 64, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 62, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 61, 1, 0, 0, 64, 1, 0, 0, 62, 0, 3, 0, 65, 1, 0, 0, 62, 1, 0, -0, 57, 0, 8, 0, 3, 0, 0, 0, 68, 1, 0, 0, 176, 0, 0, 0, 51, 1, 0, 0, 55, 1, 0, 0, 61, 1, 0, 0, 65, 1, 0, 0, 254, 0, 2, 0, 68, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 83, 1, 0, 0, 0, 0, 0, 0, 29, 0, 0, -0, 248, 0, 2, 0, 84, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 85, 1, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 86, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 86, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, -0, 87, 1, 0, 0, 79, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 88, 1, 0, 0, 73, 1, 0, 0, 62, 0, 3, 0, 87, 1, 0, 0, 88, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 89, 1, 0, 0, 113, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, -0, 90, 1, 0, 0, 79, 1, 0, 0, 80, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 91, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 69, 1, 0, 0, 91, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 28, 0, 0, 0, 104, 1, 0, 0, 0, 0, 0, -0, 29, 0, 0, 0, 248, 0, 2, 0, 105, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 106, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 107, 1, 0, 0, 93, 1, 0, 0, 62, 0, 3, 0, 106, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, -0, 2, 0, 0, 0, 108, 1, 0, 0, 103, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 109, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 110, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, -0, 61, 0, 4, 0, 3, 0, 0, 0, 112, 1, 0, 0, 97, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 112, 1, 0, 0, 57, 0, 4, 0, 28, 0, 0, 0, 113, 1, 0, 0, 112, 0, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 114, 1, 0, 0, 103, 1, 0, 0, 80, 1, 0, -0, 61, 0, 4, 0, 3, 0, 0, 0, 115, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 115, 1, 0, 0, 65, 0, 5, 0, 70, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 117, 1, 0, 0, 116, 1, 0, -0, 62, 0, 3, 0, 94, 1, 0, 0, 117, 1, 0, 0, 65, 0, 5, 0, 2, 0, 0, 0, 118, 1, 0, 0, 103, 1, 0, 0, 111, 1, 0, 0, 61, 0, 4, 0, 3, 0, 0, 0, 119, 1, 0, 0, 118, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 119, 1, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +9, 192, 254, 239, 0, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, +0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, +1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, +21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, +127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, +0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, +0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, +84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, +57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, +10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, +67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 172, 31, 37, 223, 167, 75, 230, 241, 177, 145, 157, 123, 125, 33, 17, 255, 0, 120, 35, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 136, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, +0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 196, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, +0, 15, 0, 13, 0, 4, 0, 0, 0, 96, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 87, 1, 0, 0, 89, 1, 0, 0, 85, 1, 0, 0, 95, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 120, 1, 0, +0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 109, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 108, 1, 0, 0, 110, 1, 0, 0, 114, 1, 0, 0, 119, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 96, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, +0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, +66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, +0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, +0, 7, 0, 23, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 19, 0, 41, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 43, 1, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, +101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 0, 0, 7, 0, 21, 0, 80, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, +100, 115, 108, 0, 0, 7, 0, 20, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, +100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, +108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, +0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, +114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, +0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, +0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, +80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, +0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 184, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 188, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 189, 0, 0, +0, 114, 0, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 205, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 206, 0, 0, +0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 207, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 209, 0, 0, +0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 213, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 115, 104, 97, +114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 218, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, +0, 220, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 223, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 228, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 232, 0, 0, +0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 242, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, +0, 5, 0, 4, 0, 247, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 0, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 6, 1, 0, 0, 102, 97, 114, +68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 9, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 12, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, +105, 110, 101, 0, 0, 5, 0, 6, 0, 25, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 50, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, +97, 116, 95, 49, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 85, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, +0, 88, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 90, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 91, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, +0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 93, 1, 0, +0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 96, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, +97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 99, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 106, 1, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 8, 0, 108, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 109, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, +0, 111, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 112, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, +111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 114, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 115, 1, 0, 0, 86, 83, 95, +73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 115, 1, 0, +0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 116, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, +0, 116, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, +0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 117, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 118, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, +0, 119, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 120, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 127, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, +0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, +0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 108, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 109, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 112, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 112, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 5, 0, 113, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, +0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, +0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, +0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, +0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, +0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 188, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 33, 0, 6, 0, 187, 0, 0, 0, 5, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 32, 0, 4, 0, 205, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 204, 0, 0, 0, 4, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, +0, 188, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, +0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 232, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, +0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 90, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 91, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 92, 1, 0, 0, 4, 0, 0, +0, 30, 0, 5, 0, 93, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 99, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 102, 1, 0, +0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 111, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 115, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, +0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 117, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 118, 1, 0, 0, 6, 0, 0, 0, 117, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 127, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 108, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 109, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 111, 1, 0, 0, 110, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 113, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 114, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 118, 1, 0, 0, 119, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, +0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, +0, 50, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, +0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, +0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, +0, 187, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 189, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 191, 0, 0, 0, 248, 0, 2, 0, 192, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, +0, 201, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 202, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 195, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, +0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 206, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 209, 0, 0, +0, 248, 0, 2, 0, 210, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 217, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 219, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 223, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, +0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, +0, 242, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 247, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 6, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 12, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, +0, 16, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 25, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 209, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 213, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, +0, 216, 0, 0, 0, 196, 0, 0, 0, 43, 0, 0, 0, 211, 0, 0, 0, 214, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 209, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 217, 0, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 209, 0, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 222, 0, 0, 0, 220, 0, 0, 0, 221, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 222, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 225, 0, 0, 0, 206, 0, 0, 0, 213, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 0, 0, +0, 225, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 226, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 229, 0, 0, 0, 206, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 230, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 230, 0, 0, +0, 65, 0, 5, 0, 188, 0, 0, 0, 233, 0, 0, 0, 206, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 234, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 237, 0, 0, 0, 184, 0, 0, +0, 224, 0, 0, 0, 227, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 223, 0, 0, 0, 237, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 241, 0, 0, 0, 239, 0, 0, 0, 240, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 0, 0, 0, 238, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, +0, 246, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 242, 0, 0, 0, 246, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 242, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 250, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 238, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 252, 0, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, +0, 252, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 247, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, +0, 255, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 209, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 4, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 247, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 4, 1, 0, 0, 0, 1, 0, +0, 1, 1, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 1, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 209, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, +0, 129, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 7, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 6, 1, 0, 0, 11, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 13, 1, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 6, 1, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 12, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 217, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 12, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 12, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 20, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 22, 1, 0, +0, 19, 1, 0, 0, 21, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 24, 1, 0, 0, 22, 1, 0, 0, 23, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 24, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, +0, 26, 1, 0, 0, 213, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 16, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 29, 1, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 26, 1, 0, +0, 27, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 25, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, +0, 25, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 34, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 30, 1, 0, 0, 31, 1, 0, 0, 33, 1, 0, +0, 62, 0, 3, 0, 207, 0, 0, 0, 34, 1, 0, 0, 249, 0, 2, 0, 1, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 36, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 247, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 39, 1, 0, +0, 196, 0, 0, 0, 46, 0, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 39, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 40, 1, 0, 0, 206, 0, 0, 0, 254, 0, 2, 0, 40, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, +0, 4, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 57, 1, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 66, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, +0, 72, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 76, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 65, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 65, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 70, 1, 0, +0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 66, 1, 0, 0, 71, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 75, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 74, 1, 0, +0, 62, 0, 3, 0, 72, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 73, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 79, 1, 0, 0, 185, 0, 0, 0, 62, 1, 0, 0, 66, 1, 0, 0, 72, 1, 0, 0, 76, 1, 0, 0, 254, 0, 2, 0, 79, 1, 0, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 100, 1, 0, +0, 87, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, +0, 57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 107, 1, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 121, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 122, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 123, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 123, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 112, 1, 0, 0, 62, 0, 3, 0, 124, 1, 0, +0, 125, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 126, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 128, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 126, 1, 0, 0, 128, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 129, 1, 0, +0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 130, 1, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 131, 1, 0, 0, 130, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 131, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 132, 1, 0, +0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 133, 1, 0, 0, 132, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 133, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 135, 1, 0, 0, 134, 1, 0, 0, 62, 0, 3, 0, 114, 1, 0, 0, 135, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 172, 31, 37, 223, 167, 75, 230, 241, 177, +145, 157, 123, 125, 33, 17, 255, 0, 120, 35, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 136, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, +0, 0, 0, 0, 11, 0, 6, 0, 196, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 96, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, +101, 114, 0, 0, 87, 1, 0, 0, 89, 1, 0, 0, 85, 1, 0, 0, 95, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 120, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 109, 1, 0, 0, 112, 1, 0, 0, +113, 1, 0, 0, 108, 1, 0, 0, 110, 1, 0, 0, 114, 1, 0, 0, 119, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 96, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, +36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, +116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, +108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 19, 0, 41, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 43, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 0, 0, 7, 0, 21, 0, 80, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, +82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, +102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, +85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, +114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, +5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 184, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 7, 0, 188, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 189, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, +98, 0, 0, 0, 5, 0, 7, 0, 205, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 206, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 207, 0, 0, 0, +116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 213, 0, 0, 0, +105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 218, 0, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 223, 0, 0, 0, +109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 228, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 232, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, +5, 0, 5, 0, 242, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 247, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 3, 1, 0, 0, +102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 0, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 6, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 9, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, +5, 0, 6, 0, 12, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 25, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, +121, 0, 0, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 50, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, +100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, +108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 85, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 88, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, +5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 90, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 80, +83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 91, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 1, 0, 0, 0, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 93, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, +2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, +5, 0, 15, 0, 96, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, +99, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 106, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 108, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 109, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 111, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, +5, 0, 6, 0, 110, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 112, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 0, 5, 0, 6, 0, 114, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 115, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, +111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 115, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 79, +85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 116, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, +116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 117, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 8, 0, 118, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 119, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 120, 1, 0, 0, +83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 127, 1, 0, 0, 105, 110, 116, 95, +51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, +97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, +89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 108, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 109, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, +79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 112, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 6, 0, 112, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 113, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, +114, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, +34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, +32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, +18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, +25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, +2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, +0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, +74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, +32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, +33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 188, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 187, 0, 0, 0, 5, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, +32, 0, 4, 0, 205, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 204, 0, 0, 0, 4, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 215, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, +138, 0, 0, 0, 232, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, +5, 0, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, +90, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 91, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 92, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 93, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 99, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +111, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 115, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 117, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 118, 1, 0, 0, 6, 0, 0, 0, 117, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 127, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, +85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +90, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 108, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 109, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +111, 1, 0, 0, 110, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 114, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +118, 1, 0, 0, 119, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 135, 0, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, +140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 50, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, +54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, +176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 189, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, +190, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 191, 0, 0, 0, 248, 0, 2, 0, 192, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, +195, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, +196, 0, 0, 0, 40, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 201, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 12, 0, 7, 0, +5, 0, 0, 0, 202, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 195, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, +206, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 209, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 217, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 188, 0, 0, 0, 219, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 223, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 188, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 242, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 247, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 188, 0, 0, 0, 6, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 12, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 25, 1, 0, 0, 7, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 209, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 213, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 216, 0, 0, 0, 196, 0, 0, 0, 43, 0, 0, 0, 211, 0, 0, 0, 214, 0, 0, 0, 215, 0, 0, 0, +62, 0, 3, 0, 209, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 217, 0, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 209, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 222, 0, 0, 0, 220, 0, 0, 0, 221, 0, 0, 0, 62, 0, 3, 0, +219, 0, 0, 0, 222, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 225, 0, 0, 0, 206, 0, 0, 0, 213, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 0, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 226, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, +229, 0, 0, 0, 206, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 230, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 233, 0, 0, 0, 206, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 234, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 237, 0, 0, 0, 184, 0, 0, 0, 224, 0, 0, 0, 227, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 223, 0, 0, 0, 237, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 239, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 239, 0, 0, 0, 240, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 241, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 243, 0, 0, 0, 238, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 242, 0, 0, 0, 246, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 242, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 238, 0, 0, 0, +12, 0, 8, 0, 5, 0, 0, 0, 252, 0, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, 0, 252, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 254, 0, 0, 0, 247, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, 0, 255, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 209, 0, 0, 0, 186, 0, 5, 0, +8, 0, 0, 0, 4, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 247, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 4, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 1, 0, 0, +219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 209, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 7, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, +6, 1, 0, 0, 11, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 13, 1, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 6, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, +12, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 217, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 12, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 20, 1, 0, 0, 12, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 20, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 22, 1, 0, 0, 19, 1, 0, 0, 21, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 6, 1, 0, 0, +129, 0, 5, 0, 5, 0, 0, 0, 24, 1, 0, 0, 22, 1, 0, 0, 23, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 24, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 26, 1, 0, 0, 213, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 228, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 16, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 29, 1, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 25, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 30, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 25, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, +32, 1, 0, 0, 32, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 34, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 30, 1, 0, 0, 31, 1, 0, 0, 33, 1, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 34, 1, 0, 0, 249, 0, 2, 0, 1, 1, 0, 0, 248, 0, 2, 0, +1, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 247, 0, 0, 0, +80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 39, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, +206, 0, 0, 0, 39, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 40, 1, 0, 0, 206, 0, 0, 0, 254, 0, 2, 0, 40, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 57, 1, 0, 0, +59, 0, 4, 0, 205, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 66, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 76, 1, 0, 0, 7, 0, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 65, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 65, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 70, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, +62, 0, 3, 0, 66, 1, 0, 0, 71, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 75, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 74, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 73, 1, 0, 0, +57, 0, 8, 0, 4, 0, 0, 0, 79, 1, 0, 0, 185, 0, 0, 0, 62, 1, 0, 0, 66, 1, 0, 0, 72, 1, 0, 0, 76, 1, 0, 0, 254, 0, 2, 0, 79, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 100, 1, 0, 0, 87, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +101, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +105, 1, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 121, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 122, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 123, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 123, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 124, 1, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 112, 1, 0, 0, 62, 0, 3, 0, 124, 1, 0, 0, 125, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 126, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 128, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 126, 1, 0, 0, 128, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 129, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 130, 1, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 131, 1, 0, 0, 130, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 131, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 132, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 133, 1, 0, 0, 132, 1, 0, 0, +62, 0, 3, 0, 110, 1, 0, 0, 133, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 135, 1, 0, 0, 134, 1, 0, 0, 62, 0, 3, 0, 114, 1, 0, 0, 135, 1, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs index 83ae943248..ef19111491 100644 --- a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs @@ -356,16 +356,18 @@ internal struct DescriptorSetInfo private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateDescription) { // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler - var resourceGroups = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList(); + var resourceGroups = pipelineStateDescription.EffectBytecode.Reflection.ResourceGroups.Select(g => g.Name).ToList(); ResourceGroupCount = resourceGroups.Count; var layouts = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts; - // Get binding indices used by the shader - var destinationBindings = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings - .ToDictionary(x => x.KeyInfo.KeyName, x => x); + // Get binding indices used by the shader (from ResourceGroups entries) + var destinationBindings = new Dictionary(); + foreach (var group in pipelineStateDescription.EffectBytecode.Reflection.ResourceGroups) + foreach (var entry in group.Entries) + destinationBindings[entry.KeyInfo.KeyName] = entry; - var maxBindingIndex = destinationBindings.Max(x => x.Value.SlotStart + x.Value.SlotCount); + var maxBindingIndex = destinationBindings.Count > 0 ? destinationBindings.Max(x => x.Value.SlotStart + x.Value.SlotCount) : 0; var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex]; DescriptorBindingMapping = new List(); @@ -391,7 +393,7 @@ private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateD throw new NotImplementedException(); destinationEntries[destinationBinding.SlotStart] = sourceEntry; - // No need to umpdate immutable samplers + // No need to update immutable samplers if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null) { continue; diff --git a/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs index 2846c2641c..b3ecca7d1d 100644 --- a/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs @@ -626,7 +626,21 @@ public override void PrepareEffectPermutations(RenderDrawContext context) if (descriptorSet.Layout == null) continue; - var constantBufferReflection = effectBytecode.Reflection.ConstantBuffers.FirstOrDefault(x => x.Name == descriptorSet.Name); + var resourceGroup = effectBytecode.Reflection.FindResourceGroup(descriptorSet.Name); + var constantBufferReflection = resourceGroup?.ConstantBuffer; + + // For the default set slot, also check unnamed/Globals groups for a cbuffer + if (constantBufferReflection == null && descriptorSet.Name == "PerFrame") + { + foreach (var fallbackGroup in effectBytecode.Reflection.ResourceGroups) + { + if (fallbackGroup.Name is null or "Globals" && fallbackGroup.ConstantBuffer != null) + { + constantBufferReflection = fallbackGroup.ConstantBuffer; + break; + } + } + } renderEffectReflection.ResourceGroupDescriptions[index] = new ResourceGroupDescription(descriptorSet.Layout, constantBufferReflection); } diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index 01df1e05a0..04682a4876 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -293,6 +293,12 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl ValidateConstantBufferReflection(constantBuffer, ref constantBufferDesc, linkBuffer, log); } + // Build a lookup index for ResourceGroups entries by RawName (avoids O(n) search per resource) + var resourceEntryIndex = new Dictionary(); + foreach (var group in effectReflection.ResourceGroups) + for (int idx = 0; idx < group.Entries.Count; idx++) + resourceEntryIndex[group.Entries[idx].RawName] = (group, idx); + // Bound Resources for (uint i = 0; i < shaderReflectionDesc.BoundResources; ++i) { @@ -331,6 +337,9 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl binding.ElementType = elementType; effectReflection.ResourceBindings.Add(binding); + + // Update stage flags on the new ResourceGroups structure + UpdateResourceGroupStageFlags(resourceEntryIndex, resourceName, shaderBytecode.Stage, binding.SlotStart); } } @@ -735,6 +744,21 @@ static ComPtr ToComPtr(T* comPtr) where T : unmanaged, IComVtbl { return new ComPtr { Handle = comPtr }; } + + static void UpdateResourceGroupStageFlags(Dictionary index, string resourceName, ShaderStage stage, int slotStart) + { + if (!index.TryGetValue(resourceName, out var loc)) + return; + + var entry = loc.Group.Entries[loc.Index]; + if (entry.SlotStart != slotStart) + throw new InvalidOperationException( + $"Resource '{resourceName}' has slot {slotStart} in {stage} " + + $"but slot {entry.SlotStart} was expected (from SDSL compiler). " + + $"Cross-stage slot mismatch is not supported."); + entry.Stages |= stage.ToFlag(); + loc.Group.Entries[loc.Index] = entry; + } } } } diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index 90f3ae6332..f27b41ede6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -1,5 +1,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Stride.Core; [assembly: DisableRuntimeMarshalling] @@ -148,10 +149,14 @@ public enum ValidatorVersion public static partial class Spv2DXIL { + static Spv2DXIL() + { + NativeLibraryHelper.PreloadLibrary("spirv_to_dxil", typeof(Spv2DXIL)); + } // Import user32.dll (containing the function we need) and define // the method corresponding to the native function. - [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)] + [LibraryImport("spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] [return: MarshalAs(UnmanagedType.Bool)] public static unsafe partial bool spirv_to_dxil( @@ -169,6 +174,6 @@ out DXILSpirvObject out_dxil ); - [LibraryImport("./native/spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] + [LibraryImport("spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] public static partial ulong spirv_to_dxil_get_version(); } diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 3e3b9bbf57..317657998f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -263,7 +263,7 @@ public override TaskOrResult Compile(ShaderMixinSo } // Remove unused reflection data, as it is entirely resolved at compile time. - CleanupReflection(bytecode.Reflection); + //CleanupReflection(bytecode.Reflection); } // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) @@ -393,13 +393,113 @@ public override TaskOrResult Compile(ShaderMixinSo if (bytecode.Reflection.ResourceBindings.Count > 0) { - builder.AppendLine("****** Resources ******"); + builder.AppendLine("******** Resources ********"); builder.AppendLine("***************************"); + + // Build sampler state lookup from ResourceGroups entries + var samplerStateByRawName = new Dictionary(); + foreach (var group in bytecode.Reflection.ResourceGroups) + foreach (var entry in group.Entries) + if (entry.SamplerStateDescription.HasValue) + samplerStateByRawName[entry.RawName] = entry.SamplerStateDescription.Value; + + // Aggregate stages per resource (keyed by RawName) so we can show a bitfield instead of duplicates + var stagesByRawName = new Dictionary Stages)>(); foreach (var resource in bytecode.Reflection.ResourceBindings) { - builder.AppendLine($"@R {resource.RawName} => {resource.KeyInfo.KeyName} [ResourceGroup: {resource.ResourceGroup} LogicalGroup: {resource.LogicalGroup} Stage: {resource.Stage}, Slot: ({resource.SlotStart}-{resource.SlotStart + resource.SlotCount - 1})]"); + if (resource.Stage == ShaderStage.None) + continue; // metadata-only entry, will be merged via KeyName + if (!stagesByRawName.TryGetValue(resource.RawName, out var entry)) + stagesByRawName[resource.RawName] = (resource, new List { resource.Stage }); + else + entry.Stages.Add(resource.Stage); } - builder.AppendLine("***************************"); + // For resources that only have Stage:None (no per-stage entry), include them too + foreach (var resource in bytecode.Reflection.ResourceBindings) + { + if (resource.Stage == ShaderStage.None && !stagesByRawName.ContainsKey(resource.RawName)) + stagesByRawName[resource.RawName] = (resource, new List()); + } + + // Build cbuffer lookup by name + var cbuffersByName = new Dictionary(); + foreach (var cb in bytecode.Reflection.ConstantBuffers) + cbuffersByName[cb.Name] = cb; + + // Group by ResourceGroup, then LogicalGroup + var byResourceGroup = new Dictionary>(); + foreach (var (rawName, (binding, stages)) in stagesByRawName) + { + var rgKey = binding.ResourceGroup ?? ""; + if (!byResourceGroup.TryGetValue(rgKey, out var list)) + byResourceGroup[rgKey] = list = new(); + var stageStr = stages.Count > 0 ? string.Join("|", stages.Select(s => s switch { ShaderStage.Vertex => "VS", ShaderStage.Hull => "HS", ShaderStage.Domain => "DS", ShaderStage.Geometry => "GS", ShaderStage.Pixel => "PS", ShaderStage.Compute => "CS", _ => s.ToString() })) : "None"; + list.Add((binding, stageStr)); + } + + foreach (var (resourceGroup, resources) in byResourceGroup) + { + builder.AppendLine($"ResourceGroup: {(string.IsNullOrEmpty(resourceGroup) ? "(Default)" : resourceGroup)}"); + + // Group by LogicalGroup + var byLogicalGroup = new Dictionary>(); + foreach (var r in resources) + { + var lgKey = r.Binding.LogicalGroup ?? ""; + if (!byLogicalGroup.TryGetValue(lgKey, out var list)) + byLogicalGroup[lgKey] = list = new(); + list.Add(r); + } + + foreach (var (logicalGroup, lgResources) in byLogicalGroup) + { + builder.AppendLine($" LogicalGroup: {(string.IsNullOrEmpty(logicalGroup) ? "(Default)" : logicalGroup)}"); + + foreach (var (binding, stageStr) in lgResources) + { + if (binding.Class == EffectParameterClass.ConstantBuffer && cbuffersByName.TryGetValue(binding.RawName, out var cb)) + { + // Find members belonging to this logical group and compute offset/size range + var lgMembers = new List(); + foreach (var m in cb.Members) + { + var memberLg = m.LogicalGroup ?? ""; + if (memberLg == logicalGroup) + lgMembers.Add(m); + } + if (lgMembers.Count > 0) + { + var minOffset = lgMembers.Min(m => m.Offset); + var maxEnd = lgMembers.Max(m => m.Offset + m.Size); + builder.AppendLine($" cbuffer {cb.Name} [slot: {binding.SlotStart}-{binding.SlotStart + binding.SlotCount - 1}, offset: {minOffset}, size: {maxEnd - minOffset}, stage: {stageStr}]"); + foreach (var m in lgMembers) + builder.AppendLine($" {m.RawName} => {m.KeyInfo.KeyName} (offset: {m.Offset}, size: {m.Size})"); + } + else + { + builder.AppendLine($" cbuffer {cb.Name} [slot: {binding.SlotStart}-{binding.SlotStart + binding.SlotCount - 1}, stage: {stageStr}]"); + } + } + else + { + // Texture, sampler, buffer, etc. + var slotPrefix = binding.Class switch + { + EffectParameterClass.ShaderResourceView => "t", + EffectParameterClass.UnorderedAccessView => "u", + EffectParameterClass.Sampler => "s", + _ => $"slot {binding.SlotStart}" + }; + var slotStr = slotPrefix is "t" or "u" or "s" ? $"{slotPrefix}{binding.SlotStart}" : slotPrefix; + var samplerInfo = binding.Class == EffectParameterClass.Sampler && samplerStateByRawName.TryGetValue(binding.RawName, out var sd) + ? $" {{Filter={sd.Filter}, Compare={sd.CompareFunction}}}" + : binding.Class == EffectParameterClass.Sampler ? " {NO SAMPLER STATE}" : ""; + builder.AppendLine($" {binding.RawName} => {binding.KeyInfo.KeyName} [{slotStr}, stage: {stageStr}]{samplerInfo}"); + } + } + } + } + builder.AppendLine("****************************"); } if (bytecode.HashSources.Count > 0) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 1328f52ea1..26b57eb07d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -1,5 +1,6 @@ using CommunityToolkit.HighPerformance.Buffers; using Stride.Core.Extensions; +using Stride.Core.Mathematics; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; @@ -436,7 +437,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon Offset = constantBufferOffset, Size = memberSize, LogicalGroup = metadata.LogicalGroup, - DefaultValue = metadata.DefaultValue, + DefaultValue = ConvertDefaultValue(metadata.DefaultValue), }; if (metadata.Color) { @@ -451,7 +452,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon SpirvBuilder.PadOffsetAfterArray(member.Type, member.TypeModifier, memberInfos[index].Offset, ref constantBufferOffset, SpirvBuilder.AlignmentRules.CBuffer); } - globalContext.Reflection.ConstantBuffers.Add(new EffectConstantBufferDescription + var cbufferDesc = new EffectConstantBufferDescription { Name = context.Names[cbuffer.VariableId], // Round buffer size to next multiple of 16 bytes @@ -459,7 +460,12 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon Type = ConstantBufferType.ConstantBuffer, Members = memberInfos, - }); + }; + globalContext.Reflection.ConstantBuffers.Add(cbufferDesc); + + // Also attach to the matching resource group + var group = globalContext.Reflection.GetOrCreateGroup(cbufferDesc.Name); + group.ConstantBuffer = cbufferDesc; } } @@ -585,5 +591,41 @@ private static void ConvertBoolCBufferMembers(SpirvContext context, SpirvBuffer } } } + + /// + /// Converts compiler-internal to serializable CLR types + /// that the engine expects (Vector2/3/4, Int2/3/4, etc.). + /// Scalars (float, int, uint, bool) pass through unchanged. + /// + private static object ConvertDefaultValue(object value) + { + if (value is not ConstantVector cv) + return value; + + var v = cv.Values; + return v[0] switch + { + float => v.Length switch + { + 2 => new Vector2((float)v[0], (float)v[1]), + 3 => new Vector3((float)v[0], (float)v[1], (float)v[2]), + 4 => (object)new Vector4((float)v[0], (float)v[1], (float)v[2], (float)v[3]), + _ => throw new NotSupportedException($"Unsupported float vector size: {v.Length}"), + }, + int => v.Length switch + { + 2 => new Int2((int)v[0], (int)v[1]), + 3 => new Int3((int)v[0], (int)v[1], (int)v[2]), + 4 => (object)new Int4((int)v[0], (int)v[1], (int)v[2], (int)v[3]), + _ => throw new NotSupportedException($"Unsupported int vector size: {v.Length}"), + }, + uint => v.Length switch + { + 4 => (object)new UInt4((uint)v[0], (uint)v[1], (uint)v[2], (uint)v[3]), + _ => throw new NotSupportedException($"Unsupported uint vector size: {v.Length}"), + }, + _ => throw new NotSupportedException($"Unsupported constant composite element type: {v[0]?.GetType()}"), + }; + } } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index e1b9250789..2acb53036b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -300,7 +300,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon if (variableType is TextureType t) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Type = (t, t.Multisampled, t.Sampled == 2) switch { @@ -313,21 +313,27 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon (Texture2DType, false, true) => EffectParameterType.RWTexture2D, (Texture3DType, false, true) => EffectParameterType.RWTexture3D, }, - }); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + EmitResourceEntry(globalContext, resolved); } else if (variableType is BufferType bufferType) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Type = bufferType.WriteAllowed ? EffectParameterType.RWBuffer : EffectParameterType.Buffer, - }); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + EmitResourceEntry(globalContext, resolved); } else if (variableType is StructuredBufferType structuredBufferType) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Type = structuredBufferType.WriteAllowed ? EffectParameterType.RWStructuredBuffer : EffectParameterType.StructuredBuffer, - }); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + EmitResourceEntry(globalContext, resolved); // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves StructuredBuffer type context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, $"{(structuredBufferType.WriteAllowed ? "rw" : "")}structuredbuffer:<{structuredBufferType.BaseType.ToId().ToLowerInvariant()}>")); @@ -340,10 +346,12 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } else if (variableType is ByteAddressBufferType byteAddressBufferType) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Type = byteAddressBufferType.WriteAllowed ? EffectParameterType.RWByteAddressBuffer : EffectParameterType.ByteAddressBuffer, - }); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + EmitResourceEntry(globalContext, resolved); // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves ByteAddressBuffer type context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, byteAddressBufferType.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); @@ -353,33 +361,43 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } else if (variableType is SamplerType) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Class = EffectParameterClass.Sampler, Type = EffectParameterType.Sampler, SlotStart = samplerSlot, SlotCount = 1, - }); - - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [samplerSlot])); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + Graphics.SamplerStateDescription? samplerDesc = null; if (samplerStates.TryGetValue(variable.ResultId, out var samplerState)) + { globalContext.Reflection.SamplerStates.Add( new EffectSamplerStateBinding(linkName, samplerState)); + samplerDesc = samplerState; + } + + EmitResourceEntry(globalContext, resolved, samplerDesc); + + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [samplerSlot])); samplerSlot++; } else if (variableType is ConstantBufferSymbol) { - globalContext.Reflection.ResourceBindings.Add(effectResourceBinding with + var resolved = effectResourceBinding with { Class = EffectParameterClass.ConstantBuffer, Type = EffectParameterType.ConstantBuffer, SlotStart = cbufferSlot, SlotCount = 1, ResourceGroup = name, - }); + }; + globalContext.Reflection.ResourceBindings.Add(resolved); + // cbuffer entry is emitted first in the group (before textures/samplers) + EmitResourceEntry(globalContext, resolved); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.DescriptorSet, [0])); context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.Binding, [cbufferSlot])); @@ -390,4 +408,14 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon } } } + + /// + /// Emits an into the appropriate . + /// + private static void EmitResourceEntry(MixinGlobalContext globalContext, in EffectResourceBindingDescription binding, Graphics.SamplerStateDescription? samplerState = null) + { + var groupName = binding.ResourceGroup ?? "Globals"; + var group = globalContext.Reflection.GetOrCreateGroup(groupName); + group.Entries.Add(new EffectResourceEntry(binding, samplerState)); + } } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 6ff21e136c..1a7a526c4a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -152,6 +152,17 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o // Process reflection ProcessReflection(globalContext, context, temp, options); + // Ensure each resource group has cbuffer entries first (ordering expected by consumers) + foreach (var group in globalContext.Reflection.ResourceGroups) + { + group.Entries.Sort((a, b) => + { + var aIsCb = a.Class == EffectParameterClass.ConstantBuffer ? 0 : 1; + var bIsCb = b.Class == EffectParameterClass.ConstantBuffer ? 0 : 1; + return aIsCb.CompareTo(bIsCb); + }); + } + SimplifyNotSupportedConstantsInShader(context, temp); foreach (var inst in context) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 0a8f7fbdf2..8f925b0a0e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -161,7 +161,6 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object return false; } - // For now we assume it's a vector type (but we would need to revisit that later if we handle more advanced constants such as matrix or arrays) value = new ConstantVector { Values = constants }; return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 9d07556ff9..4a908ebffb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -122,7 +122,24 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte } variable && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) { + // Keep cbuffer alive if any resource in its resource group is used, + // matching the logic for resources at line 141. + // This ensures shadow pass effects keep the PerMaterial cbuffer entry + // even when no cbuffer members are referenced. + bool resourceGroupUsed = false; if (!cbufferInfo.UsedAnyStage) + { + foreach (var rg in analysisResult.ResourceGroups.Values) + { + if (rg.Name == cbufferInfo.Name && rg.Used) + { + resourceGroupUsed = true; + break; + } + } + } + + if (!cbufferInfo.UsedAnyStage && !resourceGroupUsed) { removedIds.Add(variable.ResultId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index a27466ffc4..e04c296bc7 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -749,7 +749,11 @@ private unsafe void ApplyParameters() if (resourceType == "cbuffer") { - var cbReflection = EffectReflection.ConstantBuffers.Single(x => x.Name == resourceName); + Shaders.EffectConstantBufferDescription cbReflection = null; + foreach (var group in EffectReflection.ResourceGroups) + if (group.ConstantBuffer?.Name == resourceName) + { cbReflection = group.ConstantBuffer; break; } + cbReflection ??= EffectReflection.ConstantBuffers.Single(x => x.Name == resourceName); var cbufferData = new byte[cbReflection.Size]; foreach (var cbufferParameter in TestHeaderParser.ParseParameters(param.Value)) { diff --git a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs index 8d34f41b5b..c75ee2340e 100644 --- a/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Tests/ShaderLoader.cs @@ -43,7 +43,7 @@ public override bool LoadExternalFileContent(string name, out string filename, o return false; } - protected override bool LoadFromCode(string filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer) + protected override bool LoadFromCode(string? filename, string code, ObjectId hash, ReadOnlySpan macros, out ShaderBuffers buffer, bool registerInCache = true) { var result = base.LoadFromCode(filename, code, hash, macros, out buffer, registerInCache); if (result) diff --git a/sources/shaders/Stride.Shaders/EffectBytecode.cs b/sources/shaders/Stride.Shaders/EffectBytecode.cs index fa590bdb99..df5e8799dc 100644 --- a/sources/shaders/Stride.Shaders/EffectBytecode.cs +++ b/sources/shaders/Stride.Shaders/EffectBytecode.cs @@ -22,7 +22,7 @@ public sealed class EffectBytecode /// A constant value representing the magic header stored in front of an Effect bytecode /// to avoid reading old versions. /// - public const uint MagicHeader = 0xEFFEC008; // NOTE: If EffectBytecode is changed, this number must be changed manually + public const uint MagicHeader = 0xEFFEC009; // NOTE: If EffectBytecode is changed, this number must be changed manually /// diff --git a/sources/shaders/Stride.Shaders/EffectReflection.cs b/sources/shaders/Stride.Shaders/EffectReflection.cs index afb3dcbedd..e01648252e 100644 --- a/sources/shaders/Stride.Shaders/EffectReflection.cs +++ b/sources/shaders/Stride.Shaders/EffectReflection.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using System.Collections.Generic; +using System.Linq; using Stride.Core; using Stride.Core.Collections; using Stride.Core.Serialization; @@ -26,6 +27,12 @@ public EffectReflection() InputAttributes = []; } + /// + /// Resource groups organized by descriptor set (e.g. "PerFrame", "PerView", "PerDraw", "PerMaterial"). + /// Each group contains its entries pre-ordered (cbuffer first) and its constant buffer description. + /// + public List ResourceGroups { get; set; } = []; + /// /// Gets or sets the sampler states. /// @@ -63,5 +70,41 @@ public EffectReflection() public int StreamOutputRasterizedStream { get; set; } public List InputAttributes { get; set; } + + /// + /// Finds a resource group by name, with fallback for the default set slot ("Globals"). + /// + public EffectResourceGroupDescription FindResourceGroup(string name, string defaultSetSlot = null) + { + foreach (var group in ResourceGroups) + { + if (group.Name == name || + (defaultSetSlot != null && name == defaultSetSlot && group.Name is null or "Globals")) + return group; + } + return null; + } + + /// + /// Finds or creates a resource group with the given name. + /// + public EffectResourceGroupDescription GetOrCreateGroup(string name) + { + foreach (var group in ResourceGroups) + { + if (group.Name == name) + return group; + } + var newGroup = new EffectResourceGroupDescription { Name = name }; + ResourceGroups.Add(newGroup); + return newGroup; + } + + /// + public override string ToString() + { + var groups = string.Join(", ", ResourceGroups.Select(g => $"{g.Name}({g.Entries.Count})")); + return $"EffectReflection [{groups}]"; + } } } diff --git a/sources/shaders/Stride.Shaders/EffectResourceEntry.cs b/sources/shaders/Stride.Shaders/EffectResourceEntry.cs new file mode 100644 index 0000000000..ec0e473858 --- /dev/null +++ b/sources/shaders/Stride.Shaders/EffectResourceEntry.cs @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Core; +using Stride.Graphics; + +namespace Stride.Shaders; + +/// +/// Describes a single resource entry within a resource group. +/// Replaces the per-stage duplicated approach +/// with a single entry per resource using to indicate active stages. +/// +[DataContract] +public struct EffectResourceEntry +{ + public EffectResourceEntry(in EffectResourceBindingDescription binding, SamplerStateDescription? samplerState = null) + { + KeyInfo = binding.KeyInfo; + Class = binding.Class; + Type = binding.Type; + ElementType = binding.ElementType; + RawName = binding.RawName; + Stages = ShaderStageFlags.None; + SlotStart = binding.SlotStart; + SlotCount = binding.SlotCount; + LogicalGroup = binding.LogicalGroup; + SamplerStateDescription = samplerState; + } + + public EffectParameterKeyInfo KeyInfo; + + public EffectParameterClass Class; + + public EffectParameterType Type; + + public EffectTypeDescription ElementType; + + public string RawName; + + /// + /// Which shader stages use this resource (bitfield). + /// means the resource is declared but unused by any compiled stage. + /// + public ShaderStageFlags Stages; + + /// + /// The binding slot for this resource. Same across all stages (enforced by the EffectCompiler). + /// + public int SlotStart; + + public int SlotCount; + + public string LogicalGroup; + + /// + /// For sampler resources, the immutable sampler state description. Null for non-sampler resources. + /// + public SamplerStateDescription? SamplerStateDescription; + + /// + public override readonly string ToString() + { + var stages = Stages != ShaderStageFlags.None ? $", stages: {Stages}" : ""; + var name = KeyInfo.Key?.Name ?? KeyInfo.KeyName ?? RawName ?? ""; + return $"{name} ({Class} {Type}, slot {SlotStart}{stages})"; + } +} diff --git a/sources/shaders/Stride.Shaders/EffectResourceGroupDescription.cs b/sources/shaders/Stride.Shaders/EffectResourceGroupDescription.cs new file mode 100644 index 0000000000..2d7ee366ed --- /dev/null +++ b/sources/shaders/Stride.Shaders/EffectResourceGroupDescription.cs @@ -0,0 +1,38 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.Generic; +using System.Text; +using Stride.Core; + +namespace Stride.Shaders; + +/// +/// Describes a resource group (descriptor set) and all its resource entries. +/// Entries are ordered: ConstantBuffer first (if present), then textures/samplers/UAVs. +/// +[DataContract] +public class EffectResourceGroupDescription +{ + /// + /// The resource group name (e.g. "PerFrame", "PerView", "PerDraw", "PerMaterial", "Globals"). + /// + public string Name { get; set; } + + /// + /// The constant buffer description for this group, or null if the group has no constant buffer. + /// + public EffectConstantBufferDescription ConstantBuffer { get; set; } + + /// + /// All resource entries in this group, ordered: ConstantBuffer entry first, then other resources. + /// + public List Entries { get; set; } = []; + + /// + public override string ToString() + { + var cb = ConstantBuffer != null ? $", cbuffer: {ConstantBuffer.Name} [{ConstantBuffer.Size} bytes]" : ""; + return $"ResourceGroup '{Name}' ({Entries.Count} entries{cb})"; + } +} diff --git a/sources/shaders/Stride.Shaders/ShaderStage.cs b/sources/shaders/Stride.Shaders/ShaderStage.cs index 0be41b5258..5a5fa84658 100644 --- a/sources/shaders/Stride.Shaders/ShaderStage.cs +++ b/sources/shaders/Stride.Shaders/ShaderStage.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; using Stride.Core; namespace Stride.Shaders; @@ -46,3 +47,43 @@ public enum ShaderStage /// Compute = 6 } + +/// +/// Flags enum for combining multiple shader stages. +/// +[Flags] +[DataContract] +public enum ShaderStageFlags +{ + None = 0, + Vertex = 1 << 0, + Hull = 1 << 1, + Domain = 1 << 2, + Geometry = 1 << 3, + Pixel = 1 << 4, + Compute = 1 << 5, +} + +public static class ShaderStageExtensions +{ + public static ShaderStageFlags ToFlag(this ShaderStage stage) => stage switch + { + ShaderStage.Vertex => ShaderStageFlags.Vertex, + ShaderStage.Hull => ShaderStageFlags.Hull, + ShaderStage.Domain => ShaderStageFlags.Domain, + ShaderStage.Geometry => ShaderStageFlags.Geometry, + ShaderStage.Pixel => ShaderStageFlags.Pixel, + ShaderStage.Compute => ShaderStageFlags.Compute, + _ => ShaderStageFlags.None, + }; + + public static void ForEach(this ShaderStageFlags flags, Action action) + { + if ((flags & ShaderStageFlags.Vertex) != 0) action(ShaderStage.Vertex); + if ((flags & ShaderStageFlags.Hull) != 0) action(ShaderStage.Hull); + if ((flags & ShaderStageFlags.Domain) != 0) action(ShaderStage.Domain); + if ((flags & ShaderStageFlags.Geometry) != 0) action(ShaderStage.Geometry); + if ((flags & ShaderStageFlags.Pixel) != 0) action(ShaderStage.Pixel); + if ((flags & ShaderStageFlags.Compute) != 0) action(ShaderStage.Compute); + } +} From c53972728ed4f1e3c7359393ffe852330271f1a2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 15:57:31 +0900 Subject: [PATCH 0985/1182] SDSL: Fixed Graphics tests build --- .../Compiler/CubemapEffect.sdfx | 50 ------------------- .../Compiler/CustomEffect.sdfx | 10 +++- .../Compiler/CustomShader.sdsl | 3 -- .../Stride.Graphics.Tests.Windows.csproj | 3 -- .../Stride.Graphics.Tests/TestCustomEffect.cs | 2 +- 5 files changed, 9 insertions(+), 59 deletions(-) delete mode 100644 sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx b/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx deleted file mode 100644 index d21fb15817..0000000000 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CubemapEffect.sdfx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect CubemapDisplayEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - mixin AlbedoFlatShading; - mixin compose albedoDiffuse = ComputeColorTextureCubeBasic; - }; - - effect CubemapEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - mixin AlbedoFlatShading; - - if (MaterialParameters.AlbedoDiffuse != null) - mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; - else - mixin compose albedoDiffuse = ComputeColorTextureCubeReflect; - }; - - effect CubemapGeomEffect - { - using params MaterialParameters; - - mixin ShaderBase; - mixin TransformationWAndVP; - - mixin macro MAX_VERTEX_COUNT = 9; - mixin CameraCube; - - mixin AlbedoFlatShading; - - if (MaterialParameters.AlbedoDiffuse != null) - mixin compose albedoDiffuse = MaterialParameters.AlbedoDiffuse; - }; - - effect CubemapIBLEffect - { - mixin StrideBaseShader; - mixin child StrideGBufferShaderPass; - }; -} diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx b/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx index e6b7acbdaa..37b4ecbf7c 100644 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx +++ b/sources/engine/Stride.Graphics.Tests/Compiler/CustomEffect.sdfx @@ -2,11 +2,17 @@ // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. namespace Stride.Graphics.Tests { + params CustomEffectParameters + { + // factor used by CustomEffect + float SwitchEffectLevel; + } + partial effect CustomSubEffect { - using params CustomShaderKeys; + using params CustomEffectParameters; - if (CustomShaderKeys.SwitchEffectLevel < 10) + if (CustomEffectParameters.SwitchEffectLevel < 10) { mixin CustomShader; } diff --git a/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl b/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl index 2c4fe84f4b..6e6afad379 100644 --- a/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl +++ b/sources/engine/Stride.Graphics.Tests/Compiler/CustomShader.sdsl @@ -4,9 +4,6 @@ namespace Stride.Graphics.Tests { shader CustomShader : SpriteBase { - // factor used by CustomEffect - stage float SwitchEffectLevel; - cbuffer PerPass { [Link("MyCustomShader.ColorFactor2")] diff --git a/sources/engine/Stride.Graphics.Tests/Stride.Graphics.Tests.Windows.csproj b/sources/engine/Stride.Graphics.Tests/Stride.Graphics.Tests.Windows.csproj index 765495640e..182eb6812d 100644 --- a/sources/engine/Stride.Graphics.Tests/Stride.Graphics.Tests.Windows.csproj +++ b/sources/engine/Stride.Graphics.Tests/Stride.Graphics.Tests.Windows.csproj @@ -18,9 +18,6 @@ - - - diff --git a/sources/engine/Stride.Graphics.Tests/TestCustomEffect.cs b/sources/engine/Stride.Graphics.Tests/TestCustomEffect.cs index 3c0558366f..211b7f17ae 100644 --- a/sources/engine/Stride.Graphics.Tests/TestCustomEffect.cs +++ b/sources/engine/Stride.Graphics.Tests/TestCustomEffect.cs @@ -53,7 +53,7 @@ private void DrawCustomEffect() GraphicsContext.CommandList.SetRenderTargetAndViewport(GraphicsDevice.Presenter.DepthStencilBuffer, GraphicsDevice.Presenter.BackBuffer); effectInstance.Parameters.Set(MyCustomShaderKeys.ColorFactor2, (Vector4)Color.Red); - effectInstance.Parameters.Set(CustomShaderKeys.SwitchEffectLevel, switchEffectLevel); + effectInstance.Parameters.Set(CustomEffectParameters.SwitchEffectLevel, switchEffectLevel); effectInstance.Parameters.Set(TexturingKeys.Texture0, UVTexture); switchEffectLevel++; // TODO: Add switch Effect to test and capture frames From fe9151391217a352910947a2cf1722c01161f8f8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 17:03:36 +0900 Subject: [PATCH 0986/1182] SDSL: Materials: allow material cbuffer/resources to have different layout in the same frame (when rendered with different effects) --- .../Rendering/ParticleEmitterRenderFeature.cs | 5 +- .../Materials/MaterialRenderFeature.cs | 153 ++++++++++++------ 2 files changed, 104 insertions(+), 54 deletions(-) diff --git a/sources/engine/Stride.Particles/Rendering/ParticleEmitterRenderFeature.cs b/sources/engine/Stride.Particles/Rendering/ParticleEmitterRenderFeature.cs index 5c87936f83..b4976c911a 100644 --- a/sources/engine/Stride.Particles/Rendering/ParticleEmitterRenderFeature.cs +++ b/sources/engine/Stride.Particles/Rendering/ParticleEmitterRenderFeature.cs @@ -223,11 +223,12 @@ public override unsafe void Prepare(RenderDrawContext context) var materialInfo = renderParticleEmitter.ParticleMaterialInfo; var materialParameters = material.Parameters; - if (!MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters)) + var resources = MaterialRenderFeature.UpdateMaterial(RenderSystem, context, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters); + if (resources == null) continue; var descriptorSetPoolOffset = ComputeResourceGroupOffset(renderNodeReference); - resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources; + resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = resources; } particleBufferContext.AllocateBuffers(context, totalVertexBufferSize, highestIndexCount); diff --git a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs index 820176a493..c0ec9e8594 100644 --- a/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/Materials/MaterialRenderFeature.cs @@ -6,6 +6,7 @@ using System.Threading; using Stride.Core; using Stride.Core.Diagnostics; +using Stride.Core.Storage; using Stride.Core.Threading; using Stride.Extensions; using Stride.Graphics; @@ -31,27 +32,53 @@ public class MaterialRenderFeature : SubRenderFeature private static readonly ProfilingKey PrepareEffectPermutationsKey = new ProfilingKey("MaterialRenderFeature.PrepareEffectPermutations"); - public class MaterialInfoBase + public class LayoutVariant { - public int LastFrameUsed; - public SpinLock UpdateLock; - - // Any matching effect public ResourceGroupLayout PerMaterialLayout; - - /// - /// true if MaterialParameters instance was changed - /// - public bool ParametersChanged; - public ParameterCollection ParameterCollection = new ParameterCollection(); public ParameterCollectionLayout ParameterCollectionLayout; public ParameterCollection.Copier ParameterCollectionCopier; - - // PerMaterial public ResourceGroup Resources = new ResourceGroup(); public int ResourceCount; public EffectConstantBufferDescription ConstantBufferReflection; + internal int LastParametersVersion = -1; + internal int LastFrameProcessed; + } + + public class MaterialInfoBase + { + public SpinLock UpdateLock; + + /// + /// Incremented when the source MaterialParameters instance changes (e.g. editor hot reload). + /// Each tracks the version it last built its copier against. + /// + public int ParametersVersion; + + // Inline fast path for the common single-variant case + internal ObjectId SingleVariantHash; + internal LayoutVariant SingleVariant; + internal Dictionary ExtraVariants; + + internal LayoutVariant GetOrAddVariant(ObjectId hash) + { + if (SingleVariant == null) + { + SingleVariantHash = hash; + SingleVariant = new LayoutVariant(); + return SingleVariant; + } + if (SingleVariantHash == hash) + return SingleVariant; + + ExtraVariants ??= new Dictionary(); + if (!ExtraVariants.TryGetValue(hash, out var variant)) + { + variant = new LayoutVariant(); + ExtraVariants[hash] = variant; + } + return variant; + } } /// @@ -242,7 +269,8 @@ public override void PrepareEffectPermutations(RenderDrawContext context) materialInfo.UseDitheredShadows = material.Parameters.Get(MaterialKeys.UseDitheredShadows); materialInfo.MaterialParameters = material.Parameters; - materialInfo.ParametersChanged = isMaterialParametersChanged; + if (isMaterialParametersChanged) + materialInfo.ParametersVersion++; materialInfo.PermutationCounter = material.Parameters.PermutationCounter; } } @@ -301,8 +329,6 @@ public override void Prepare(RenderDrawContext context) continue; // Collect materials and create associated MaterialInfo (includes reflection) first time - // TODO: We assume same material will generate same ResourceGroup (i.e. same resources declared in same order) - // Need to offer some protection if this invariant is violated (or support it if it can actually happen in real scenario) var material = renderMesh.MaterialPass; var materialInfo = renderMesh.MaterialInfo; var materialParameters = material.Parameters; @@ -310,11 +336,12 @@ public override void Prepare(RenderDrawContext context) // Register resources usage Context.StreamingManager?.StreamResources(materialParameters); - if (!UpdateMaterial(RenderSystem, threadContext, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters)) + var resources = UpdateMaterial(RenderSystem, threadContext, materialInfo, perMaterialDescriptorSetSlot.Index, renderNode.RenderEffect, materialParameters); + if (resources == null) continue; var descriptorSetPoolOffset = ((RootEffectRenderFeature)RootRenderFeature).ComputeResourceGroupOffset(renderNodeReference); - resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = materialInfo.Resources; + resourceGroupPool[descriptorSetPoolOffset + perMaterialDescriptorSetSlot.Index] = resources; } }); } @@ -343,64 +370,86 @@ public override void Draw(RenderDrawContext context, RenderView renderView, Rend } } - public static unsafe bool UpdateMaterial(RenderSystem renderSystem, RenderDrawContext context, MaterialInfoBase materialInfo, int materialSlotIndex, RenderEffect renderEffect, ParameterCollection materialParameters) + public static ResourceGroup UpdateMaterial(RenderSystem renderSystem, RenderDrawContext context, MaterialInfoBase materialInfo, int materialSlotIndex, RenderEffect renderEffect, ParameterCollection materialParameters) { var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex]; if (resourceGroupDescription.DescriptorSetLayout == null) - return false; + return null; - // Check if this material was encountered for the first time this frame and mark it as used - if (Interlocked.Exchange(ref materialInfo.LastFrameUsed, renderSystem.FrameCounter) == renderSystem.FrameCounter) - return true; + var hash = resourceGroupDescription.Hash; - // First time we use the material with a valid effect, let's update layouts - if (materialInfo.PerMaterialLayout == null || materialInfo.PerMaterialLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex].Hash) - { - materialInfo.PerMaterialLayout = ResourceGroupLayout.New(renderSystem.GraphicsDevice, resourceGroupDescription); + // Lock-free fast path: single variant already processed this frame + var single = materialInfo.SingleVariant; + if (single != null && materialInfo.SingleVariantHash == hash && single.LastFrameProcessed == renderSystem.FrameCounter) + return single.Resources; - var parameterCollectionLayout = materialInfo.ParameterCollectionLayout = new ParameterCollectionLayout(); - parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout); - materialInfo.ResourceCount = parameterCollectionLayout.ResourceCount; + bool lockTaken = false; + try + { + materialInfo.UpdateLock.Enter(ref lockTaken); - // Process material cbuffer (if any) - if (resourceGroupDescription.ConstantBufferReflection != null) + var variant = materialInfo.GetOrAddVariant(hash); + if (variant.PerMaterialLayout == null) + SetupVariantLayout(renderSystem, variant, resourceGroupDescription); + if (variant.LastFrameProcessed != renderSystem.FrameCounter) { - materialInfo.ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection; - parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection); + ProcessVariantData(variant, materialInfo, materialParameters, context); + variant.LastFrameProcessed = renderSystem.FrameCounter; } - materialInfo.ParametersChanged = true; + return variant.Resources; + } + finally + { + if (lockTaken) + materialInfo.UpdateLock.Exit(); + } + } + + private static void SetupVariantLayout(RenderSystem renderSystem, LayoutVariant variant, ResourceGroupDescription resourceGroupDescription) + { + variant.PerMaterialLayout = ResourceGroupLayout.New(renderSystem.GraphicsDevice, resourceGroupDescription); + + var parameterCollectionLayout = variant.ParameterCollectionLayout = new ParameterCollectionLayout(); + parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout); + variant.ResourceCount = parameterCollectionLayout.ResourceCount; + + if (resourceGroupDescription.ConstantBufferReflection != null) + { + variant.ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection; + parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection); } - // If the parameters collection instance changed, we need to update it - if (materialInfo.ParametersChanged) + variant.ParameterCollection.UpdateLayout(variant.ParameterCollectionLayout); + } + + private static unsafe void ProcessVariantData(LayoutVariant variant, MaterialInfoBase materialInfo, ParameterCollection materialParameters, RenderDrawContext context) + { + // Rebuild copier if layout just changed or source parameters instance changed + if (variant.LastParametersVersion != materialInfo.ParametersVersion) { - materialInfo.ParameterCollection.UpdateLayout(materialInfo.ParameterCollectionLayout); - materialInfo.ParameterCollectionCopier = new ParameterCollection.Copier(materialInfo.ParameterCollection, materialParameters); - materialInfo.ParametersChanged = false; + variant.ParameterCollectionCopier = new ParameterCollection.Copier(variant.ParameterCollection, materialParameters); + variant.LastParametersVersion = materialInfo.ParametersVersion; } - // Copy back to ParameterCollection - // TODO GRAPHICS REFACTOR directly copy to resource group? - materialInfo.ParameterCollectionCopier.Copy(); + // Copy from source material parameters + variant.ParameterCollectionCopier.Copy(); // Allocate resource groups - context.ResourceGroupAllocator.PrepareResourceGroup(materialInfo.PerMaterialLayout, BufferPoolAllocationType.UsedMultipleTime, materialInfo.Resources); + context.ResourceGroupAllocator.PrepareResourceGroup(variant.PerMaterialLayout, BufferPoolAllocationType.UsedMultipleTime, variant.Resources); // Set resource bindings in PerMaterial resource set - for (int resourceSlot = 0; resourceSlot < materialInfo.ResourceCount; ++resourceSlot) + for (int resourceSlot = 0; resourceSlot < variant.ResourceCount; ++resourceSlot) { - materialInfo.Resources.DescriptorSet.SetValue(resourceSlot, materialInfo.ParameterCollection.ObjectValues[resourceSlot]); + variant.Resources.DescriptorSet.SetValue(resourceSlot, variant.ParameterCollection.ObjectValues[resourceSlot]); } // Process PerMaterial cbuffer - if (materialInfo.ConstantBufferReflection != null) + if (variant.ConstantBufferReflection != null) { - var mappedCB = (byte*)materialInfo.Resources.ConstantBuffer.Data; - fixed (byte* dataValues = materialInfo.ParameterCollection.DataValues) - MemoryUtilities.CopyWithAlignmentFallback(mappedCB, dataValues, (uint)materialInfo.Resources.ConstantBuffer.Size); + var mappedCB = (byte*)variant.Resources.ConstantBuffer.Data; + fixed (byte* dataValues = variant.ParameterCollection.DataValues) + MemoryUtilities.CopyWithAlignmentFallback(mappedCB, dataValues, (uint)variant.Resources.ConstantBuffer.Size); } - - return true; } private struct TessellationState : IDisposable From 9d853d961c17f6d1a179f3d426bd4126c3455489 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 22:08:16 +0900 Subject: [PATCH 0987/1182] Graphics: Disable LogDebugNames by default (extremely slow with VS attached) --- .../engine/Stride.Graphics/Direct3D/DebugHelpers.Direct3D.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sources/engine/Stride.Graphics/Direct3D/DebugHelpers.Direct3D.cs b/sources/engine/Stride.Graphics/Direct3D/DebugHelpers.Direct3D.cs index ea727ad7db..af505f753a 100644 --- a/sources/engine/Stride.Graphics/Direct3D/DebugHelpers.Direct3D.cs +++ b/sources/engine/Stride.Graphics/Direct3D/DebugHelpers.Direct3D.cs @@ -22,7 +22,8 @@ internal static unsafe class DebugHelpers /// /// A flag indicating whether to log debug names for Direct3D objects whenever they are set. /// - public const bool LogDebugNames = true; + /// Debugging will be extremely slow with Visual Studio. + public static bool LogDebugNames { get; set; } = false; // From d3dcommon.h in Windows SDK (WKPDID_D3DDebugObjectName) From c9bc954b8584c786ef803e336c2565e4fcb5b892 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 00:50:55 +0900 Subject: [PATCH 0988/1182] SDSL: reenable async effect compilation --- sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs index 762226a152..9f8696b61a 100644 --- a/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs +++ b/sources/shaders/Stride.Shaders/Compiler/EffectCompilerCache.cs @@ -52,7 +52,7 @@ public class EffectCompilerCache : EffectCompilerChain public EffectCompilerCache(EffectCompilerBase compiler, DatabaseFileProvider database, TaskSchedulerSelector taskSchedulerSelector = null) : base(compiler) { - CompileEffectAsynchronously = false; + CompileEffectAsynchronously = true; this.database = database ?? throw new ArgumentNullException(nameof(database), "Using the cache requires a database."); this.taskSchedulerSelector = taskSchedulerSelector; } From db48a1b59747e81493bd8f93ae8dae1f373be699 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 09:55:19 +0900 Subject: [PATCH 0989/1182] SDSL: Use direct ResourceGroup reference for cbuffer dead code removal --- .../Interfaces/Analysis/StreamAnalyzer.cs | 12 +++++++----- .../Interfaces/Cleanup/DeadCodeRemover.cs | 17 ++--------------- .../Interfaces/Models/ResourceInfo.cs | 1 + 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index 1d316f0aa6..e5a892e2ce 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -138,15 +138,17 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) { var n = m.To(); + if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) + resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); + if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) { - if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) - resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); - resourceGroup.Resources.Add(resourceInfo); - resourceInfo.ResourceGroup = resourceGroup; - + } + else if (cbuffers.TryGetValue(resourceGroupIdDecorate.Target, out var cbufferInfo)) + { + cbufferInfo.ResourceGroup = resourceGroup; } } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 4a908ebffb..6ec67fcba8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -123,23 +123,10 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte && analysisResult.CBuffers.TryGetValue(variable, out var cbufferInfo)) { // Keep cbuffer alive if any resource in its resource group is used, - // matching the logic for resources at line 141. + // matching the logic for resources. // This ensures shadow pass effects keep the PerMaterial cbuffer entry // even when no cbuffer members are referenced. - bool resourceGroupUsed = false; - if (!cbufferInfo.UsedAnyStage) - { - foreach (var rg in analysisResult.ResourceGroups.Values) - { - if (rg.Name == cbufferInfo.Name && rg.Used) - { - resourceGroupUsed = true; - break; - } - } - } - - if (!cbufferInfo.UsedAnyStage && !resourceGroupUsed) + if (!cbufferInfo.UsedAnyStage && cbufferInfo.ResourceGroup is not { Used: true }) { removedIds.Add(variable.ResultId); SpirvBuilder.SetOpNop(i.Data.Memory.Span); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs index 37f1eff8d0..f21bad8fa3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs @@ -28,6 +28,7 @@ internal record class CBufferInfo(string name) { public string Name { get; } = name; + public ResourceGroup ResourceGroup { get; set; } public string? LogicalGroup { get; set; } /// From afa2e0a3b2c1317c98c97304b7ee33158145dcc4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 09:38:53 +0900 Subject: [PATCH 0990/1182] SDSL: Tests shaders against spirv-val --- .../Spirv/Tools/Validator.cs | 83 ++++++++++++++++++- .../Stride.Shaders.Tests/RenderingTests.cs | 12 +++ .../Stride.Shaders.Tests/StrideShaderTests.cs | 4 + 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs index 7baa47b920..586e58b445 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs @@ -1,8 +1,85 @@ -namespace Stride.Shaders.Spirv.Tools; +using System.Diagnostics; +using System.Text; +namespace Stride.Shaders.Spirv.Tools; +public readonly record struct ValidationResult(bool IsValid, string Output) +{ + public override string ToString() => IsValid ? "Valid" : Output; +} -public struct SpirvVal +public static partial class Spv { - // public List Passes = []; + static string? FindSpirvVal() + { + // 1. Check VULKAN_SDK env var + var vulkanSdk = Environment.GetEnvironmentVariable("VULKAN_SDK"); + if (!string.IsNullOrEmpty(vulkanSdk)) + { + var path = Path.Combine(vulkanSdk, "Bin", "spirv-val.exe"); + if (File.Exists(path)) + return path; + // Linux/macOS + path = Path.Combine(vulkanSdk, "bin", "spirv-val"); + if (File.Exists(path)) + return path; + } + + // 2. Assume it's on PATH + return "spirv-val"; + } + + /// + /// Validates a SPIR-V file using the spirv-val tool from the Vulkan SDK. + /// + /// Path to a .spv file. + /// A indicating whether the bytecode is valid. + public static ValidationResult ValidateFile(string filePath) + { + var exe = FindSpirvVal(); + + using var process = new Process(); + process.StartInfo = new ProcessStartInfo + { + FileName = exe, + Arguments = filePath, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + }; + + process.Start(); + + var stdout = process.StandardOutput.ReadToEnd(); + var stderr = process.StandardError.ReadToEnd(); + process.WaitForExit(); + + var output = new StringBuilder(); + if (stdout.Length > 0) + output.Append(stdout); + if (stderr.Length > 0) + output.Append(stderr); + + return new ValidationResult(process.ExitCode == 0, output.ToString().Trim()); + } + + /// + /// Validates SPIR-V bytecode using the spirv-val tool from the Vulkan SDK. + /// + /// Raw SPIR-V bytecode as a byte span. + /// A indicating whether the bytecode is valid. + public static ValidationResult ValidateBinary(ReadOnlySpan spirvBytes) + { + var tempFile = Path.GetTempFileName(); + try + { + File.WriteAllBytes(tempFile, spirvBytes.ToArray()); + return ValidateFile(tempFile); + } + finally + { + try { File.Delete(tempFile); } catch { } + } + } } diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 0be459cdd5..2dd93933a6 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -47,6 +47,10 @@ public void ComputeTest1(string shaderName) File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + // Validate SPIR-V + var validationResult = Spv.ValidateFile($"{shaderName}.spv"); + Assert.True(validationResult.IsValid, validationResult.Output); + // Convert to GLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); @@ -96,6 +100,10 @@ public void RenderTest1(string shaderName) File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + // Validate SPIR-V + var validationResult = Spv.ValidateFile($"{shaderName}.spv"); + Assert.True(validationResult.IsValid, validationResult.Output); + // Convert to HLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); @@ -166,6 +174,10 @@ public void StreamOutTest1(string shaderName) File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + // Validate SPIR-V + var validationResult = Spv.ValidateFile($"{shaderName}.spv"); + Assert.True(validationResult.IsValid, validationResult.Output); + // Convert to HLSL var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); diff --git a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs index d1bf19b6e2..93d1492482 100644 --- a/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/StrideShaderTests.cs @@ -535,6 +535,10 @@ private static void TestCore(string shaderName, ShaderMixinSource shaderSource, File.WriteAllBytes($"{shaderName}.spv", bytecode); File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + // Validate SPIR-V + var validationResult = Spv.ValidateFile($"{shaderName}.spv"); + Assert.True(validationResult.IsValid, validationResult.Output); + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); var entryPoints = translator.GetEntryPoints(); foreach (var entryPoint in entryPoints) From ec8ac574046f2052b88ff40d39af1e4b8d40339f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 17:01:06 +0900 Subject: [PATCH 0991/1182] SDSL: Fix dangling variable IDs in OpEntryPoint after GenerateDefaultCBuffer Filter out old variable IDs when wrapping bare uniforms into Globals cbuffer, and skip unused stream variables in entry point interface. --- .../SDSL/ShaderMixer.CBuffers.cs | 12 ++++++++++-- .../Generation/EntryPointWrapperGenerator.cs | 12 ++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 26b57eb07d..4df28dcd26 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -117,12 +117,20 @@ private void GenerateDefaultCBuffer(MixinNode rootMixin, MixinGlobalContext glob } } - // Update entry points to include this cbuffer + // Update entry points to include this cbuffer and remove old variable IDs foreach (var i in context) { if (i.Op == Op.OpEntryPoint && (OpEntryPoint)i is { } entryPoint) { - entryPoint.InterfaceIds = new([.. entryPoint.InterfaceIds, cbufferVariable.ResultId]); + var ids = entryPoint.InterfaceIds.Elements.Span; + var newIds = new List(ids.Length + 1); + foreach (var id in ids) + { + if (!variableToMemberIndices.ContainsKey(id)) + newIds.Add(id); + } + newIds.Add(cbufferVariable.ResultId); + entryPoint.InterfaceIds = new([.. newIds]); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 1defaa04bc..8a0150c8c3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -405,13 +405,17 @@ void ProcessTessellationArguments(Symbol function, Span arguments) Span entryPointInterfaceVariables = stackalloc int[streamLayout.InputStreams.Count + streamLayout.OutputStreams.Count + streamLayout.PatchInputStreams.Count + streamLayout.PatchOutputStreams.Count + 1 + analysisResult.Variables.Count + analysisResult.CBuffers.Count + analysisResult.Resources.Count + entryPointExtraVariables.Count]; int pvariableIndex = 0; foreach (var inputStream in streamLayout.InputStreams) - entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; + if (inputStream.Info.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; foreach (var outputStream in streamLayout.OutputStreams) - entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + if (outputStream.Info.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; foreach (var inputStream in streamLayout.PatchInputStreams) - entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; + if (inputStream.Info.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = inputStream.Id; foreach (var outputStream in streamLayout.PatchOutputStreams) - entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; + if (outputStream.Info.UsedThisStage) + entryPointInterfaceVariables[pvariableIndex++] = outputStream.Id; entryPointInterfaceVariables[pvariableIndex++] = streamLayout.StreamsVariableId; foreach (var variable in analysisResult.Variables) { From 3459e5301d3e39dca195160dbe7d57d8031eb6c4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 17:01:19 +0900 Subject: [PATCH 0992/1182] SDSL: Add ImageGatherExtended capability when Offset image operand is used (also reorganized when/how capabilities are added) --- .../SDSL/ShaderMixer.cs | 97 ++++++++++++------- 1 file changed, 63 insertions(+), 34 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 1a7a526c4a..5d3c35c030 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -85,40 +85,6 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o return; } - // Add optional capabilities - foreach (var i in context) - { - if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 0 or 1) - { - context.Add(new OpCapability(Capability.SampledBuffer)); - break; - } - } - foreach (var i in context) - { - if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 2) - { - context.Add(new OpCapability(Capability.ImageBuffer)); - break; - } - } - foreach (var i in context) - { - if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.ImageFormat == ImageFormat.Unknown) - { - context.Add(new OpCapability(Capability.StorageImageWriteWithoutFormat)); - break; - } - } - foreach (var i in temp) - { - if (i.Op is Op.OpImageQuerySizeLod or Op.OpImageQuerySize or Op.OpImageQueryLevels or Op.OpImageQuerySamples) - { - context.Add(new OpCapability(Capability.ImageQuery)); - break; - } - } - // Process streams and remove unused code/cbuffer/variable/resources var interfaceProcessor = new InterfaceProcessor { @@ -165,6 +131,8 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o SimplifyNotSupportedConstantsInShader(context, temp); + AddRequiredCapabilities(context, temp); + foreach (var inst in context) temp.Add(inst.Data); @@ -178,6 +146,67 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o usedHashSources = shaderLoader.Sources; } + private static void AddRequiredCapabilities(SpirvContext context, SpirvBuffer temp) + { + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 0 or 1) + { + context.Add(new OpCapability(Capability.SampledBuffer)); + break; + } + } + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 2) + { + context.Add(new OpCapability(Capability.ImageBuffer)); + break; + } + } + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.ImageFormat == ImageFormat.Unknown) + { + context.Add(new OpCapability(Capability.StorageImageWriteWithoutFormat)); + break; + } + } + foreach (var i in temp) + { + if (i.Op is Op.OpImageQuerySizeLod or Op.OpImageQuerySize or Op.OpImageQueryLevels or Op.OpImageQuerySamples) + { + context.Add(new OpCapability(Capability.ImageQuery)); + break; + } + } + foreach (var i in temp) + { + // ImageGatherExtended is required when Offset (0x10) or ConstOffsets (0x20) image operands are used + // The ImageOperands word position varies by instruction layout + var imageOperandsIndex = i.Op switch + { + Op.OpImageSampleImplicitLod or Op.OpImageSampleExplicitLod + or Op.OpImageSampleProjImplicitLod or Op.OpImageSampleProjExplicitLod + or Op.OpImageFetch or Op.OpImageRead => 5, + Op.OpImageSampleDrefImplicitLod or Op.OpImageSampleDrefExplicitLod + or Op.OpImageSampleProjDrefImplicitLod or Op.OpImageSampleProjDrefExplicitLod + or Op.OpImageGather or Op.OpImageDrefGather => 6, + Op.OpImageWrite => 4, + _ => -1 + }; + if (imageOperandsIndex >= 0) + { + var span = i.Data.Memory.Span; + if (span.Length > imageOperandsIndex && (span[imageOperandsIndex] & ((int)ImageOperandsMask.Offset | (int)ImageOperandsMask.ConstOffsets)) != 0) + { + context.Add(new OpCapability(Capability.ImageGatherExtended)); + break; + } + } + } + } + class MixinGlobalContext(SymbolTable table, ILogger log) { public SymbolTable Table { get; } = table; From be6edb4fcb67be060c162711ebc43020fb9fcf57 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 17:19:04 +0900 Subject: [PATCH 0993/1182] SDSL: Use OpImageFetch instead of OpImageRead for read-only Buffer types --- .../SDSL/AST/BufferMethodsImplementations.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs index a3ea620dc9..21dd1d083d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs @@ -10,8 +10,18 @@ public class BufferMethodsImplementations : BufferMethodsDeclarations public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue x, SpirvValue? status = null) { - var loadResult = builder.Insert(new OpImageRead(context.GetOrRegister(functionType.ReturnType), context.Bound++, buffer.Id, x.Id, null, [])); - return new(loadResult.ResultId, loadResult.ResultType); + var bufferType = (BufferType)context.ReverseTypes[buffer.TypeId]; + var resultTypeId = context.GetOrRegister(functionType.ReturnType); + if (bufferType.WriteAllowed) + { + var loadResult = builder.Insert(new OpImageRead(resultTypeId, context.Bound++, buffer.Id, x.Id, null, [])); + return new(loadResult.ResultId, loadResult.ResultType); + } + else + { + var loadResult = builder.Insert(new OpImageFetch(resultTypeId, context.Bound++, buffer.Id, x.Id, null, [])); + return new(loadResult.ResultId, loadResult.ResultType); + } } public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue width) From e047f7461d54188cf7348620a9947d90cf3f2b27 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 24 Mar 2026 17:01:36 +0900 Subject: [PATCH 0994/1182] SDSL: Fix matrix swizzle: add missing OpLoad before OpCompositeExtract on pointer --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 730cfe5f28..4134639a65 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1104,6 +1104,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso var (builder, context) = compiler; EmitOpAccessChain(accessChainIds, i - 1); + result = new(builder.InsertData(new OpLoad(context.GetOrRegister(m), context.Bound++, result.Id, null, []))); (result, accessor.Type) = builder.ApplyMatrixSwizzles(context, result, m, swizzles.AsSpan()); } else From 5aa2d61f42cdf84590c072a2815e93a712f6252b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 12:31:11 +0900 Subject: [PATCH 0995/1182] SDSL: Wait for info queue task before disposing D3D11 device --- sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs index e04c296bc7..23a555d257 100644 --- a/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs +++ b/sources/shaders/Stride.Shaders.Tests/FrameRenderer.D3D11.cs @@ -85,6 +85,7 @@ float4 main(vs_out input) : SV_TARGET { "; private CancellationTokenSource cts; + private Task infoQueueTask; //Vertex data, uploaded to the VBO. private static readonly float[] Vertices = @@ -180,7 +181,7 @@ ref deviceContext if (OperatingSystem.IsWindows()) { // Log debug messages for this device (given that we've enabled the debug flag). Don't do this in release code! - device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint)msg.PDescription)), cts.Token); + infoQueueTask = device.SetInfoQueueCallback(msg => Console.WriteLine(SilkMarshal.PtrToString((nint)msg.PDescription)), cts.Token); } // Create our swapchain. @@ -253,6 +254,7 @@ public void PresentAndFinish() swapchain.Present(1, 0); cts.Cancel(); + try { infoQueueTask?.Wait(); } catch (AggregateException) { } cts.Dispose(); window.Close(); From 4a4e80c6230009093fe782c08b7c09fe6dc7b3b8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 13:24:09 +0900 Subject: [PATCH 0996/1182] SDSL: Fix dead code removal for unpatched methods --- .../Processing/Interfaces/Cleanup/DeadCodeRemover.cs | 2 +- .../Spirv/Processing/Interfaces/InterfaceProcessor.cs | 11 +++++++++++ .../Processing/Interfaces/Models/LiveAnalysis.cs | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs index 6ec67fcba8..2b26938636 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Cleanup/DeadCodeRemover.cs @@ -99,7 +99,7 @@ public static void RemoveUnreferencedCode(SpirvBuffer buffer, SpirvContext conte var i = buffer[index]; if (i.Op == Op.OpFunction && (OpFunction)i is { } function) { - bool isReferenced = liveAnalysis.ReferencedMethods.ContainsKey(function.ResultId) + bool isReferenced = (liveAnalysis.ReferencedMethods.TryGetValue(function.ResultId, out var methodInfo) && methodInfo.UsedAnyStage) || liveAnalysis.ExtraReferencedMethods.Contains(function.ResultId); if (!isReferenced) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index b28f35b629..5035a69231 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -121,6 +121,17 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex buffer.Add(new OpExecutionMode(psEntry.Id, ExecutionMode.OriginUpperLeft, [])); } + else + { + // No PS wrapper generated — undo UsedAnyStage for methods marked during PS analysis + // (otherwise they survive dead code removal with unpatched OpStreamsSDSL instructions) + // Safe to clear UsedAnyStage since PS is always the first stage analyzed + foreach (var method in liveAnalysis.ReferencedMethods) + { + method.Value.UsedThisStage = false; + method.Value.UsedAnyStage = false; + } + } // Those semantic variables are implicit in pixel shader, no need to forward them from previous stages foreach (var stream in streams) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs index 40b48930bd..08a2168f1d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs @@ -12,7 +12,7 @@ internal class MethodInfo /// /// Used at all (in any stage) /// - public bool UsedAnyStage { get; private set; } + public bool UsedAnyStage { get; internal set; } public List? OriginalMethodCode { get; set; } public int? ThisStageMethodId { get; set; } From abee37848eacbee7924bfa60f179c9369fb897cb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 14:16:17 +0900 Subject: [PATCH 0997/1182] SDSL: Add Float16 capability when half type is used --- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 5d3c35c030..d54033f71b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -148,6 +148,14 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o private static void AddRequiredCapabilities(SpirvContext context, SpirvBuffer temp) { + foreach (var i in context) + { + if (i.Op == Op.OpTypeFloat && ((OpTypeFloat)i).Width == 16) + { + context.Add(new OpCapability(Capability.Float16)); + break; + } + } foreach (var i in context) { if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Dim == Dim.Buffer && typeImage.Sampled is 0 or 1) From 48a300e027740d5851ea24a68e9b2619c8ee8790 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 14:16:24 +0900 Subject: [PATCH 0998/1182] SDSL: Emit OutputTriangleStrip/LineStrip/Points execution mode for geometry shaders --- .../Generation/EntryPointWrapperGenerator.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 8a0150c8c3..6008100fb0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -351,6 +351,11 @@ void ProcessTessellationArguments(Symbol function, Span arguments) var executionMode = entryPointFunctionType.ParameterTypes[0].Modifiers; if (executionMode == ParameterModifiers.None) throw new InvalidOperationException("Execution mode primitive is missing for first parameter of geometry shader"); + + // Extract output topology from the GeometryStreamType parameter before removing it + var outputStreamType = ((PointerType)entryPointFunctionType.ParameterTypes[1].Type).BaseType as GeometryStreamType + ?? throw new InvalidOperationException("Second parameter of geometry shader must be a GeometryStreamType"); + entryPointFunctionType.ParameterTypes[0] = entryPointFunctionType.ParameterTypes[0] with { Modifiers = ParameterModifiers.None }; entryPointFunctionType.ParameterTypes.RemoveAt(1); @@ -363,6 +368,12 @@ void ProcessTessellationArguments(Symbol function, Span arguments) ParameterModifiers.Triangle => ExecutionMode.Triangles, ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, }, [])); + context.Add(new OpExecutionMode(entryPoint.IdRef, outputStreamType.Kind switch + { + GeometryStreamOutputKindSDSL.Point => ExecutionMode.OutputPoints, + GeometryStreamOutputKindSDSL.Line => ExecutionMode.OutputLineStrip, + GeometryStreamOutputKindSDSL.Triangle => ExecutionMode.OutputTriangleStrip, + }, [])); arguments[0] = inputsVariable; From 900ded13d6d110c306fa36830fff9ab38bc2040d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 16:07:56 +0900 Subject: [PATCH 0999/1182] SDSL: During sampling/fetch, adjust use Offset and try to promote to ConstOffset when possible (simple case only) --- .../SDSL/AST/TextureMethodsImplementations.cs | 178 ++++++++++++++---- 1 file changed, 137 insertions(+), 41 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index e22fa1417d..58a95f1b46 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -72,7 +72,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde var lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(coordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); - TextureGenerateImageOperands(lod, o, s, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, lod, o, s, out var imask, out var imParams); var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); return new(loadResult.ResultId, loadResult.ResultType); @@ -80,7 +80,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde else { // No LOD component (e.g. RWTexture): use coord directly - TextureGenerateImageOperands(null, o, s, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, null, o, s, out var imask, out var imParams); var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); return new(loadResult.ResultId, loadResult.ResultType); @@ -98,7 +98,7 @@ public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder buil var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); @@ -116,7 +116,7 @@ public override SpirvValue CompileSampleBias(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, bias: bias); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, bias: bias); var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); @@ -134,7 +134,7 @@ public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(lod, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, lod, o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); @@ -152,7 +152,7 @@ public override SpirvValue CompileSampleGrad(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, ddx, ddy); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, ddx, ddy); var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); @@ -169,7 +169,7 @@ public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder b var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -185,7 +185,7 @@ public override SpirvValue CompileSampleCmpBias(SpirvContext context, SpirvBuild var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, bias: bias); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, bias: bias); var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -201,7 +201,7 @@ public override SpirvValue CompileSampleCmpGrad(SpirvContext context, SpirvBuild var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams, ddx, ddy); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, ddx, ddy); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -217,7 +217,7 @@ public override SpirvValue CompileSampleCmpLevel(SpirvContext context, SpirvBuil var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(lod, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, lod, o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue!.Value.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -233,7 +233,7 @@ public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, Spirv var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context.CompileConstant(0.0f), o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, context.CompileConstant(0.0f), o, null, out var imask, out var imParams); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); @@ -452,7 +452,7 @@ private SpirvValue CompileGatherComponent(SpirvContext context, SpirvBuilder bui var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); var componentConstant = context.CompileConstant(component); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); var gather = builder.Insert(new OpImageGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, imask, imParams)); return new(gather.ResultId, gather.ResultType); } @@ -461,21 +461,42 @@ private SpirvValue CompileGatherComponentConstOffsets(SpirvContext context, Spir { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - var componentConstant = context.CompileConstant(component); + var resultTypeId = context.GetOrRegister(functionType.ReturnType); + + // Try to promote all 4 offsets to constants (handles inline int2(x,y) constructors) + var co1 = TryPromoteToConstant(context, builder, o1.Id); + var co2 = TryPromoteToConstant(context, builder, o2.Id); + var co3 = TryPromoteToConstant(context, builder, o3.Id); + var co4 = TryPromoteToConstant(context, builder, o4.Id); + if (co1 >= 0 && co2 >= 0 && co3 >= 0 && co4 >= 0) + { + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + var int2Type = new VectorType(ScalarType.Int, 2); + var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); + var constOffsetsId = context.Bound++; + context.AddData(new OpConstantComposite(arrayType, constOffsetsId, [co1, co2, co3, co4])); + + Span operands = [constOffsetsId]; + var gather = builder.Insert(new OpImageGather(resultTypeId, context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, ImageOperandsMask.ConstOffsets, new EnumerantParameters(operands))); + return new(gather.ResultId, gather.ResultType); + } - // Build ConstOffsets: array of 4 vec2 constant - var int2Type = new VectorType(ScalarType.Int, 2); - var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); - var constOffsetsId = context.Bound++; - builder.InsertData(new OpConstantComposite(arrayType, constOffsetsId, [o1.Id, o2.Id, o3.Id, o4.Id])); - - Span operands = [constOffsetsId]; - var imask = ImageOperandsMask.ConstOffsets; - var imParams = new EnumerantParameters(operands); - var gather = builder.Insert(new OpImageGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, imask, imParams)); - return new(gather.ResultId, gather.ResultType); + // Fallback: 4 separate gathers with Offset, extract component 3 from each + var float4TypeId = resultTypeId; + var floatTypeId = context.GetOrRegister(ScalarType.Float); + var int3 = context.CompileConstant(3).Id; + Span components = stackalloc int[4]; + foreach (var (offset, i) in new[] { (o1, 0), (o2, 1), (o3, 2), (o4, 3) }) + { + var si = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + Span ops = [offset.Id]; + var gather = builder.Insert(new OpImageGather(float4TypeId, context.Bound++, si.ResultId, x.Id, componentConstant.Id, ImageOperandsMask.Offset, new EnumerantParameters(ops))); + // Extract component 3: the texel at the exact offset location + components[i] = builder.Insert(new OpCompositeExtract(floatTypeId, context.Bound++, gather.ResultId, [3])).ResultId; + } + var result = builder.Insert(new OpCompositeConstruct(float4TypeId, context.Bound++, [components[0], components[1], components[2], components[3]])); + return new(result.ResultId, result.ResultType); } private SpirvValue CompileGatherDref(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o) @@ -484,7 +505,7 @@ private SpirvValue CompileGatherDref(SpirvContext context, SpirvBuilder builder, var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); var gather = builder.Insert(new OpImageDrefGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(gather.ResultId, gather.ResultType); } @@ -493,19 +514,84 @@ private SpirvValue CompileGatherDrefConstOffsets(SpirvContext context, SpirvBuil { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); - var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + var resultTypeId = context.GetOrRegister(functionType.ReturnType); + + // Try to promote all 4 offsets to constants (handles inline int2(x,y) constructors) + var co1 = TryPromoteToConstant(context, builder, o1.Id); + var co2 = TryPromoteToConstant(context, builder, o2.Id); + var co3 = TryPromoteToConstant(context, builder, o3.Id); + var co4 = TryPromoteToConstant(context, builder, o4.Id); + if (co1 >= 0 && co2 >= 0 && co3 >= 0 && co4 >= 0) + { + var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + var int2Type = new VectorType(ScalarType.Int, 2); + var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); + var constOffsetsId = context.Bound++; + context.AddData(new OpConstantComposite(arrayType, constOffsetsId, [co1, co2, co3, co4])); + + Span operands = [constOffsetsId]; + var gather = builder.Insert(new OpImageDrefGather(resultTypeId, context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, ImageOperandsMask.ConstOffsets, new EnumerantParameters(operands))); + return new(gather.ResultId, gather.ResultType); + } - // Build ConstOffsets: array of 4 vec2 constant - var int2Type = new VectorType(ScalarType.Int, 2); - var arrayType = context.GetOrRegister(new ArrayType(int2Type, 4)); - var constOffsetsId = context.Bound++; - builder.InsertData(new OpConstantComposite(arrayType, constOffsetsId, [o1.Id, o2.Id, o3.Id, o4.Id])); + // Fallback: 4 separate gathers with Offset, extract component 3 from each + var float4TypeId = resultTypeId; + var floatTypeId = context.GetOrRegister(ScalarType.Float); + Span components = stackalloc int[4]; + foreach (var (offset, i) in new[] { (o1, 0), (o2, 1), (o3, 2), (o4, 3) }) + { + var si = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); + Span ops = [offset.Id]; + var gather = builder.Insert(new OpImageDrefGather(float4TypeId, context.Bound++, si.ResultId, x.Id, compareValue.Id, ImageOperandsMask.Offset, new EnumerantParameters(ops))); + components[i] = builder.Insert(new OpCompositeExtract(floatTypeId, context.Bound++, gather.ResultId, [3])).ResultId; + } + var result = builder.Insert(new OpCompositeConstruct(float4TypeId, context.Bound++, [components[0], components[1], components[2], components[3]])); + return new(result.ResultId, result.ResultType); + } - Span operands = [constOffsetsId]; - var imask = ImageOperandsMask.ConstOffsets; - var imParams = new EnumerantParameters(operands); - var gather = builder.Insert(new OpImageDrefGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); - return new(gather.ResultId, gather.ResultType); + /// + /// Returns true if the given ID refers to a constant instruction (OpConstant, OpConstantComposite, etc.) in context. + /// + private static bool IsConstantInContext(SpirvContext context, int id) + { + if (!context.GetBuffer().TryGetInstructionById(id, out var inst)) + return false; + return inst.Op is Op.OpConstant or Op.OpConstantTrue or Op.OpConstantFalse + or Op.OpConstantComposite or Op.OpConstantNull + or Op.OpSpecConstantComposite; + } + + /// + /// Tries to promote a value to a constant in context for use as ConstOffset. + /// Handles the simple case: OpCompositeConstruct in builder where all constituents are already constants in context. + /// Also handles scalar constants already in context. + /// Returns the constant ID if successful, or -1 if the value cannot be promoted. + /// + private static int TryPromoteToConstant(SpirvContext context, SpirvBuilder builder, int id) + { + // Already a constant in context + if (IsConstantInContext(context, id)) + return id; + + // Check builder buffer for OpCompositeConstruct with all-constant constituents + var buf = builder.GetBuffer(); + if (!buf.TryGetInstructionById(id, out var inst) || inst.Op != Op.OpCompositeConstruct) + return -1; + + var span = inst.Data.Memory.Span; + for (int j = 3; j < span.Length; j++) + { + if (!IsConstantInContext(context, span[j])) + return -1; + } + + // All constituents are constants — emit OpConstantComposite in context + var resultType = span[1]; + var constId = context.Bound++; + Span constituents = stackalloc int[span.Length - 3]; + span[3..].CopyTo(constituents); + context.AddData(new OpConstantComposite(resultType, constId, new(constituents))); + return constId; } private static void StoreQueryComponent(SpirvContext context, SpirvBuilder builder, int uintTypeId, int sizeResultId, int sizeComponents, int componentIndex, SpirvValue outParam) @@ -542,13 +628,13 @@ private static void StoreConvertedValue(SpirvContext context, SpirvBuilder build } } - private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null, SpirvValue? bias = null) + private void TextureGenerateImageOperands(SpirvContext context, SpirvBuilder builder, SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null, SpirvValue? bias = null) { imask = ImageOperandsMask.None; // Allocate for worst case (6 operands: bias + grad(2) + lod + offset + sample) Span operands = stackalloc int[6]; int operandCount = 0; - // Operands must appear in bit-order: Bias(0x1) < Lod(0x2) < Grad(0x4) < Offset(0x10) < Sample(0x40) + // Operands must appear in bit-order: Bias(0x1) < Lod(0x2) < Grad(0x4) < ConstOffset(0x8) < Offset(0x10) < Sample(0x40) if (bias != null) { imask |= ImageOperandsMask.Bias; @@ -567,8 +653,18 @@ private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, S } if (offset != null) { - imask |= ImageOperandsMask.Offset; - operands[operandCount++] = offset.Value.Id; + // Try to promote to constant (handles int2(1,3) style inline constructors) + var constId = TryPromoteToConstant(context, builder, offset.Value.Id); + if (constId >= 0) + { + imask |= ImageOperandsMask.ConstOffset; + operands[operandCount++] = constId; + } + else + { + imask |= ImageOperandsMask.Offset; + operands[operandCount++] = offset.Value.Id; + } } if (sampleIndex != null) { From d5590ead68748db7a35cc7eb1a6a71621e5f2991 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 16:09:34 +0900 Subject: [PATCH 1000/1182] SDSL: Properly infer size for unsized array with initializer --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index 60632e5591..81cf328f0d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -110,6 +110,9 @@ public override void ProcessSymbol(SymbolTable table) TypeName.ProcessSymbol(table); valueType = TypeName.Type; Value?.ProcessSymbol(table, TypeName.Type); + // If type was unsized array (e.g. int2[]) and initializer inferred the size, use that + if (valueType is ArrayType { Size: -1 } && Value?.ValueType is ArrayType { Size: > 0 } inferred) + valueType = inferred; } Type = new PointerType(valueType, Specification.StorageClass.Function); Variable.Type = Type; From a937162eeb16ee0e13a561a295589a50f7056fd8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 17:12:07 +0900 Subject: [PATCH 1001/1182] SDSL: Fix duplicate NonWritable/UserTypeGOOGLE decorations and use OpImageRead for storage textures --- .../SDSL/ShaderMixer.Reflection.cs | 10 ++----- .../SDSL/AST/TextureMethodsImplementations.cs | 30 +++++++++---------- 2 files changed, 17 insertions(+), 23 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 2acb53036b..18318d6ce3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -335,10 +335,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon globalContext.Reflection.ResourceBindings.Add(resolved); EmitResourceEntry(globalContext, resolved); - // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves StructuredBuffer type - context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, $"{(structuredBufferType.WriteAllowed ? "rw" : "")}structuredbuffer:<{structuredBufferType.BaseType.ToId().ToLowerInvariant()}>")); - if (!structuredBufferType.WriteAllowed) - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.NonWritable, [])); + // UserTypeGOOGLE and NonWritable decorations are already added during shader compilation var baseType = structuredBufferType.BaseType; // This will add array stride and offsets decorations @@ -353,10 +350,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon globalContext.Reflection.ResourceBindings.Add(resolved); EmitResourceEntry(globalContext, resolved); - // Add UserTypeGOOGLE decoration so SPIRV-Cross preserves ByteAddressBuffer type - context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, byteAddressBufferType.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); - if (!byteAddressBufferType.WriteAllowed) - context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.NonWritable, [])); + // UserTypeGOOGLE and NonWritable decorations are already added during shader compilation } } else if (variableType is SamplerType) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index 58a95f1b46..b50c5adf7b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -61,30 +61,30 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde var (vec4TypeId, needsExtract) = GetImageSampleResultType(context, functionType, textureType); - if (imageCoordSize > textureDim) + // Extract LOD from coords if present (sampled images only, not storage) + SpirvValue? lod = null; + if (textureType.Sampled != 2 && imageCoordSize > textureDim) { - // Coord has extra component (LOD): extract it and strip from coord var coordType = imageCoordType.GetElementType().GetVectorOrScalar(imageCoordSize - 1); Span shuffleIndices = stackalloc int[imageCoordSize - 1]; for (int i = 0; i < shuffleIndices.Length; ++i) shuffleIndices[i] = i; - var lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); + lod = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(ScalarType.Int), context.Bound++, x.Id, [imageCoordSize - 1]))); x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(coordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); - - TextureGenerateImageOperands(context, builder, lod, o, s, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); - if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); - return new(loadResult.ResultId, loadResult.ResultType); } + + TextureGenerateImageOperands(context, builder, lod, o, s, out var imask, out var imParams); + + // Storage images (RWTexture, Sampled=2) use OpImageRead; sampled images use OpImageFetch + int loadResultId; + if (textureType.Sampled == 2) + loadResultId = builder.Insert(new OpImageRead(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)).ResultId; else - { - // No LOD component (e.g. RWTexture): use coord directly - TextureGenerateImageOperands(context, builder, null, o, s, out var imask, out var imParams); - var loadResult = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)); - if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResult.ResultId); - return new(loadResult.ResultId, loadResult.ResultType); - } + loadResultId = builder.Insert(new OpImageFetch(vec4TypeId, context.Bound++, texture.Id, x.Id, imask, imParams)).ResultId; + + if (needsExtract) return ExtractFromVec4(context, builder, functionType, loadResultId); + return new(loadResultId, vec4TypeId); } public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) From 530eb302df343a3c38ce234fc67d86075024e298 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 17:18:17 +0900 Subject: [PATCH 1002/1182] SDSL: Fixed StreamGS test --- sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl b/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl index 7636c1dddf..17b69e214d 100644 --- a/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl +++ b/sources/shaders/assets/SDSL/StreamOutTests/StreamGS.sdsl @@ -1,4 +1,4 @@ -// GSMain(ExpectedPrimitiveCount=1, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) +// GSMain(ExpectedPrimitiveCount=3, stream.EXTRA_COLOR=(0.498 0.498 0.498 0.498)) namespace Stride.Shaders.Tests; From 6aa7f4b9c18ac095656e8559c3bff7d3c1f457fd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 17:37:37 +0900 Subject: [PATCH 1003/1182] SDSL: Include full error info in ShaderLoaderBase exception messages --- sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 2f14b8cc8c..ae143bdab7 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -177,7 +177,7 @@ protected virtual bool LoadFromCode(string? filename, string code, ObjectId hash if (!sdslc.Compile(filename, text, hash, macros, log, out buffer, registerInCache)) { if (log is LoggerResult loggerResult && loggerResult.HasErrors) - throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.Text))); + throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.ToString()))); return false; } return true; From 540709a45bca49f30368d90b4feb1638b37e5c3b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 25 Mar 2026 19:16:12 +0900 Subject: [PATCH 1004/1182] SDSL: Move static compilingGenericShaders to instance-level GenericShaderCache Prevents cross-test contamination from shared static cache. The new GenericShaderCache lives on IExternalShaderLoader, scoped to the loader's lifetime. --- .../SDSL/ShaderMixer.cs | 1 + .../ShaderLoaderBase.cs | 1 + .../Spirv/Building/Builder.Class.cs | 50 ++++--------------- .../Spirv/Building/Context.cs | 45 +++++++++++++++++ 4 files changed, 56 insertions(+), 41 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index d54033f71b..81a75d0f69 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1245,6 +1245,7 @@ public class CaptureLoadedShaders(IExternalShaderLoader inner) : IExternalShader /// /// Expects hash to be stored. public IShaderCache Cache => inner.Cache; + public GenericShaderCache GenericCache => inner.GenericCache; public HashSourceCollection Sources { get; } = new(); diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index ae143bdab7..386d2ef6e5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -17,6 +17,7 @@ namespace Stride.Shaders.Compilers; public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShaderLoader { public IShaderCache Cache => fileCache; + public GenericShaderCache GenericCache { get; } = new(); /// /// Ensures only one thread compiles a given shader at a time. Other threads wait for the result. diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index c6bdbe3d73..1bf1ac7748 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -10,7 +10,6 @@ using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; @@ -818,22 +817,6 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, return GetOrLoadShader(shaderLoader, className, new GenericResolverFromValues(genericValues), macros); } - /// - /// Ensures only one thread instantiates a given generic shader at a time. - /// - private static readonly ConcurrentDictionary<(string Name, string? Generics, int MacrosHash), Lazy<(ShaderBuffers Buffer, ObjectId Hash)>> compilingGenericShaders = new(); - - private static int ComputeMacrosHash(ReadOnlySpan macros) - { - unchecked - { - int hash = 0; - foreach (var m in macros) - hash = hash * 397 ^ m.GetHashCode(); - return hash; - } - } - private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, GenericResolver genericResolver, ReadOnlySpan macros) { var shaderBuffers = GetOrLoadShader(shaderLoader, className, macros, out var hash, out var isFromCache); @@ -851,18 +834,16 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, } else { - // Coordinate parallel instantiations: only one thread instantiates a given generic shader. - var macrosHash = ComputeMacrosHash(macros); var macrosArray = macros.ToArray(); - var key = (className, genericArguments, macrosHash); - - var lazy = compilingGenericShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(() => + var localShaderBuffers = shaderBuffers; + var localHash = hash; + var result = shaderLoader.GenericCache.GetOrInstantiate(className, genericArguments, macros, () => { // Double-check cache if (cache.TryLoadFromCache(className, genericArguments, macrosArray, out var buf, out var h)) return (buf, h); - var localBuffers = shaderBuffers; + var localBuffers = localShaderBuffers; InstantiateMemberNames(ref localBuffers, className, genericResolver, shaderLoader, macrosArray); // Copy buffers (we don't want to edit original non-instantiated code as it might be reloaded through caching) @@ -877,25 +858,12 @@ private static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, InstantiateGenericShader(ref localBuffers, classNameWithGenerics, genericResolver, shaderLoader, macrosArray); - cache.RegisterShader(className, genericArguments, macrosArray, localBuffers, hash); - return (localBuffers, hash); - }, LazyThreadSafetyMode.ExecutionAndPublication)); + cache.RegisterShader(className, genericArguments, macrosArray, localBuffers, localHash); + return (localBuffers, localHash); + }); - try - { - var result = lazy.Value; - shaderBuffers = result.Buffer; - hash = result.Hash; - } - catch - { - compilingGenericShaders.TryRemove(key, out _); - throw; - } - finally - { - compilingGenericShaders.TryRemove(key, out _); - } + shaderBuffers = result.Buffer; + hash = result.Hash; } // Run in all cases (even if cached) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index b87affb225..f72978dd60 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -7,6 +7,7 @@ using Stride.Shaders.Spirv.Processing; using Stride.Shaders.Spirv.Tools; using System; +using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.InteropServices; @@ -15,6 +16,49 @@ namespace Stride.Shaders.Spirv.Building; +/// +/// Coordinates parallel generic shader instantiations so only one thread compiles a given (name, generics, macros) combination. +/// +public class GenericShaderCache +{ + private readonly ConcurrentDictionary<(string Name, string? Generics, int MacrosHash), Lazy<(ShaderBuffers Buffer, ObjectId Hash)>> compilingShaders = new(); + + private static int ComputeMacrosHash(ReadOnlySpan macros) + { + unchecked + { + int hash = 0; + foreach (var m in macros) + hash = hash * 397 ^ m.GetHashCode(); + return hash; + } + } + + public (ShaderBuffers Buffer, ObjectId Hash) GetOrInstantiate( + string name, string? generics, ReadOnlySpan macros, + Func<(ShaderBuffers Buffer, ObjectId Hash)> factory) + { + var macrosHash = ComputeMacrosHash(macros); + var key = (name, generics, macrosHash); + + var lazy = compilingShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(factory, LazyThreadSafetyMode.ExecutionAndPublication)); + + try + { + return lazy.Value; + } + catch + { + compilingShaders.TryRemove(key, out _); + throw; + } + finally + { + compilingShaders.TryRemove(key, out _); + } + } +} + public interface IShaderCache { public void RegisterShader(string name, string? generics, ReadOnlySpan defines, ShaderBuffers bytecode, ObjectId? hash); @@ -83,6 +127,7 @@ public bool TryLoadFromCache(string name, string? generics, ReadOnlySpan Date: Wed, 25 Mar 2026 22:04:56 +0900 Subject: [PATCH 1005/1182] SDSL: Store full return type in OpTypeImage and remove UserTypeGOOGLE for texture dedup --- .../SDSL/ShaderMixer.cs | 47 +++++++++++--- .../Parsing/SDSL/AST/Shader.cs | 45 +------------- .../Spirv/Building/Context.ExtractBuffers.cs | 31 +--------- .../Spirv/Building/SpirvContext.Types.cs | 27 +++----- .../Spirv/Processing/TypeDuplicatesRemover.cs | 62 ++++++------------- 5 files changed, 71 insertions(+), 141 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 81a75d0f69..a0e3af2d2a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -133,6 +133,11 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o AddRequiredCapabilities(context, temp); + // Normalize OpTypeImage: replace full return types (e.g. float4) with scalar base types + // as required by SPIR-V spec, then dedup any resulting identical types. + NormalizeImageSampledTypes(context); + new TypeDuplicateHelper(context).RemoveDuplicateImageTypes(temp); + foreach (var inst in context) temp.Add(inst.Data); @@ -215,6 +220,40 @@ or Op.OpImageSampleProjDrefImplicitLod or Op.OpImageSampleProjDrefExplicitLod } } + /// + /// SPIR-V requires OpTypeImage's SampledType to be a scalar. + /// During compilation we store the full return type (e.g. float4) to keep textures structurally distinct. + /// This normalizes SampledType back to scalar. Runs on context before copy to temp. + /// + private static void NormalizeImageSampledTypes(SpirvContext context) + { + for (var idx = 0; idx < context.Count; idx++) + { + var inst = context[idx]; + if (inst.Op != Op.OpTypeImage) + continue; + + var typeImage = (OpTypeImage)inst; + if (!context.ReverseTypes.TryGetValue(typeImage.SampledType, out var sampledSymbol)) + continue; + + var scalarType = sampledSymbol switch + { + VectorType v => (SymbolType)v.BaseType, + MatrixType m => (SymbolType)m.BaseType, + _ => null + }; + + if (scalarType == null) + continue; // already scalar + + if (!context.Types.TryGetValue(scalarType, out var scalarId)) + continue; + + typeImage.SampledType = scalarId; + } + } + class MixinGlobalContext(SymbolTable table, ILogger log) { public SymbolTable Table { get; } = table; @@ -498,14 +537,8 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } else { - // For OpTypeImage: find UserTypeGOOGLE decoration (already in context from earlier processing) - // so CheckForDuplicates can distinguish textures with different return types. - string? sourceUserTypeGOOGLE = null; - if (i2.Op == Op.OpTypeImage && i2.IdResult.HasValue) - sourceUserTypeGOOGLE = typeDuplicateInserter.FindUserTypeGOOGLE(i2.IdResult.Value); - // Check if type already exists in context (deduplicate them) - if (typeDuplicateInserter.CheckForDuplicates(i2, sourceUserTypeGOOGLE, out var existingInstruction)) + if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) { if (i2.IdResult is int id) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index eed8b31f8e..a1b08e39c7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -107,33 +107,6 @@ void RegisterName(int target, string name) _ => null, }; - // Parse spec-compliant "texture2d:" format. - static SymbolType? ParseTextureReturnType(string s) - { - var colonIdx = s.IndexOf(':'); - if (colonIdx >= 0 && s.Length > colonIdx + 2 && s[colonIdx + 1] == '<' && s[^1] == '>') - return ParseReturnType(s[(colonIdx + 2)..^1]); - return null; - } - - // Pre-pass: collect UserTypeGOOGLE decorations on texture types so we can - // recover the exact ReturnType (e.g. float2) when reading OpTypeImage. - var textureReturnTypes = new Dictionary(); - for (var i = start; i < end; i++) - { - var inst = context[i]; - if (inst.Op == Op.OpDecorateString) - { - OpDecorateString dec = inst; - if (dec.Decoration == Decoration.UserTypeGOOGLE) - { - var symbolType = ParseTextureReturnType(dec.Value); - if (symbolType != null) - textureReturnTypes[dec.Target] = symbolType; - } - } - } - var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); var importedShaders = new Dictionary(); @@ -263,26 +236,14 @@ void RegisterName(int target, string name) } else if (instruction.Op == Op.OpTypeImage && new OpTypeImage(instruction) is { } typeImage) { - var sampledType = (ScalarType)context.ReverseTypes[typeImage.SampledType]; + // SampledType now stores the full return type (e.g. float4) during compilation. + var returnType = context.ReverseTypes[typeImage.SampledType]; if (typeImage.Dim == Dim.Buffer) { - RegisterType(typeImage.ResultId, new BufferType(sampledType, typeImage.Sampled == 2)); + RegisterType(typeImage.ResultId, new BufferType(returnType is ScalarType s ? s : ScalarType.Float, typeImage.Sampled == 2)); } else { - // Prefer UserTypeGOOGLE decoration (exact ReturnType from compilation). - // Fall back to ImageFormat for RW textures, or float4 for sampled (HLSL convention). - SymbolType returnType = textureReturnTypes.TryGetValue(typeImage.ResultId, out var userType) - ? userType - : (typeImage.Sampled == 2 - ? typeImage.ImageFormat switch - { - Specification.ImageFormat.Rg32f or Specification.ImageFormat.Rg32i or Specification.ImageFormat.Rg32ui => new VectorType(sampledType, 2), - Specification.ImageFormat.Rgba32f or Specification.ImageFormat.Rgba32i or Specification.ImageFormat.Rgba32ui => new VectorType(sampledType, 4), - _ => (SymbolType)sampledType, - } - : new VectorType(sampledType, 4)); - TextureType textureType = typeImage.Dim switch { Dim.Dim1D => new Texture1DType(returnType), diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index 9e7c1b7b49..f95b8a66d0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -44,30 +44,9 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI // Also detect raw GenericParameter leaked from parent contexts. var isGenericLike = NormalizeGenericForDedup(ref iData, out var isGenericReference); - // For OpTypeImage: find the UserTypeGOOGLE decoration in the source buffer so CheckForDuplicates - // can distinguish e.g. Texture2D vs Texture2D (same binary, different return type). - // IdResult is still the original source ID here because RemapIds does not remap the current instruction's own result. - string? sourceUserTypeGOOGLE = null; - if (iData.Op == Specification.Op.OpTypeImage && iData.IdResult.HasValue) - { - var originalId = iData.IdResult.Value; - foreach (var inst in source) - { - if (inst.Op == Specification.Op.OpDecorateString) - { - Spirv.Core.OpDecorateString dec = inst; - if (dec.Decoration == Specification.Decoration.UserTypeGOOGLE && dec.Target == originalId) - { - sourceUserTypeGOOGLE = dec.Value; - break; - } - } - } - } - // Note: we try to avoid duplicating the last (constant) instruction if there is a desired ID (so that it keeps its name/identity) if ((TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(iData.Op) || TypeDuplicateHelper.OpCheckDuplicateForConstant(iData.Op) || isGenericLike) - && typeDuplicateInserter.CheckForDuplicates(iData, sourceUserTypeGOOGLE, out var existingData) + && typeDuplicateInserter.CheckForDuplicates(iData, out var existingData) && (index != lastResultIndex || desiredResultId == null)) { // Make sure this data is declared at current index, otherwise move it. @@ -99,14 +78,6 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI iData.IdResult = resultId; typeDuplicateInserter.InsertInstruction(instructionIndex++, iData); - // For OpTypeImage: also insert the UserTypeGOOGLE decoration so it stays - // paired with the type during future deduplication in the mixer. - if (sourceUserTypeGOOGLE != null) - { - var dec = new OpDecorateString(resultId, Specification.Decoration.UserTypeGOOGLE, sourceUserTypeGOOGLE); - typeDuplicateInserter.InsertInstruction(instructionIndex++, new OpData(dec.InstructionMemory)); - } - lastResultId = resultId; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 3670fec43b..54715b567e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -164,13 +164,16 @@ public int RegisterType(SymbolType type, int id) StructType st => RegisterStructuredType(st.ToId(), st), FunctionType f => RegisterFunctionType(f, id), PointerType p => RegisterPointerType(p, id), - Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + // SampledType stores the full return type (e.g. float4, not just float) so that + // Texture and Texture produce structurally distinct OpTypeImage during merge. + // ShaderMixer normalizes SampledType back to scalar before final SPIR-V emission. + Texture1DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, - Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + Texture2DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, - Texture3DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + Texture3DType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, - TextureCubeType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType.GetElementType()), t.Dimension, + TextureCubeType t => Buffer.AddData(new OpTypeImage(id, GetOrRegister(t.ReturnType), t.Dimension, t.Depth, t.Arrayed ? 1 : 0, t.Multisampled ? 1 : 0, t.Sampled, t.Sampled == 2 ? GetStorageImageFormat(t.ReturnType) : t.Format, null)).IdResult, SamplerType st => Buffer.AddData(new OpTypeSampler(id)).IdResult, BufferType b => Buffer.AddData(new OpTypeImage(id, GetOrRegister(b.BaseType), Specification.Dim.Buffer, @@ -187,22 +190,6 @@ public int RegisterType(SymbolType type, int id) // StructSymbol st => RegisterStruct(st), _ => throw new NotImplementedException($"Can't add type {type}") }; - if (type is TextureType texType && instruction.HasValue) - { - var prefix = texType.Sampled == 2 ? "rw" : ""; - var dim = texType.Dimension switch - { - Specification.Dim.Dim1D => "texture1d", - Specification.Dim.Dim2D => "texture2d", - Specification.Dim.Dim3D => "texture3d", - Specification.Dim.Cube => "texturecube", - _ => throw new NotSupportedException($"Unsupported texture dimension {texType.Dimension}") - }; - var ms = texType.Multisampled ? "ms" : ""; - var array = texType.Arrayed ? "array" : ""; - Buffer.Add(new OpDecorateString(instruction.Value, Specification.Decoration.UserTypeGOOGLE, $"{prefix}{dim}{ms}{array}:<{texType.ReturnType.ToId()}>")); - } - Types[type] = instruction ?? -1; ReverseTypes[instruction ?? -1] = type; return instruction ?? -1; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs index c4ac9c1cca..9809730236 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs @@ -45,7 +45,6 @@ public int[] FindItemsWithTypes(SpirvBuffer buffer, params Span ops) // Note: Target is only for OpName and OpMember record struct InstructionSortHelper(Op Op, int Index, OpData Data) { - public string? UserTypeGOOGLE { get; set; } public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Index: {Index}"; @@ -119,21 +118,6 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) comparison = MemoryExtensions.SequenceCompareTo(x.Data.Memory.Span[2..], y.Data.Memory.Span[2..]); if (comparison != 0) return comparison; - - // For OpTypeImage, also compare UserTypeGOOGLE decoration to distinguish e.g. Texture2D vs Texture2D. - // x.UserTypeGOOGLE is used as an override (set on search keys that have Index=-1 and can't look up the buffer). - if (x.Op == Op.OpTypeImage && Helper != null) - { - var xUserType = x.UserTypeGOOGLE ?? (x.Index >= 0 ? Helper.FindUserTypeGOOGLE(x.Data.IdResult ?? 0) : null); - var yUserType = y.UserTypeGOOGLE ?? (y.Index >= 0 ? Helper.FindUserTypeGOOGLE(y.Data.IdResult ?? 0) : null); - // Only treat as conflicting when both sides have the decoration; null means "unknown/old binary" → compatible. - if (xUserType != null && yUserType != null) - { - comparison = string.Compare(xUserType, yUserType, StringComparison.Ordinal); - if (comparison != 0) - return comparison; - } - } } else if (x.Op == Op.OpName || x.Op == Op.OpDecorate || x.Op == Op.OpDecorateString || x.Op == Op.OpMemberName || x.Op == Op.OpMemberDecorate || x.Op == Op.OpMemberDecorateString) { @@ -193,7 +177,7 @@ public TypeDuplicateHelper(SpirvContext context) namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(context, false, this); // UserTypeGOOGLE override in search key covers Index=-1 case + comparerInsert = new OperationComparer(context, false, this); } public OpDataIndex InsertInstruction(int index, OpData data) @@ -429,29 +413,9 @@ public static bool OpCheckDuplicateForConstant(Op op) return mismatches; } - public string? FindUserTypeGOOGLE(int typeId) - { - var (start, end) = FindDecorationRange(typeId); - var span = CollectionsMarshal.AsSpan(namesByOp); - var buffer = context.GetBuffer(); - for (int i = start; i < end; i++) - { - if (span[i].Op == Op.OpDecorateString) - { - OpDecorateString dec = new OpDataIndex(span[i].Index, buffer); - if (dec.Decoration == Decoration.UserTypeGOOGLE) - return dec.Value; - } - } - return null; - } - public bool CheckForDuplicates(OpData data, out OpDataIndex foundData) - => CheckForDuplicates(data, null, out foundData); - - public bool CheckForDuplicates(OpData data, string? userTypeGOOGLE, out OpDataIndex foundData) { - var searchKey = new InstructionSortHelper { Op = data.Op, Index = -1, Data = data, UserTypeGOOGLE = userTypeGOOGLE }; + var searchKey = new InstructionSortHelper { Op = data.Op, Index = -1, Data = data }; var index = instructionsByOp.BinarySearch(searchKey, comparerInsert); if (index >= 0) @@ -464,6 +428,14 @@ public bool CheckForDuplicates(OpData data, string? userTypeGOOGLE, out OpDataIn return false; } + public void RemoveDuplicateImageTypes(params SpirvBuffer[] additionalBuffers) + { + var buffer = context.GetBuffer(); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeImage, Op.OpTypeImage, true, comparerSort, additionalBuffers); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypeSampledImage, Op.OpTypeSampledImage, true, comparerSort, additionalBuffers); + ProcessInstructions(buffer, instructionsByOp, Op.OpTypePointer, Op.OpTypePointer, true, comparerSort, additionalBuffers); + } + public void RemoveDuplicates() { var buffer = context.GetBuffer(); @@ -489,7 +461,7 @@ public void RemoveDuplicates() ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparerSort); } - private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer) + private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer, SpirvBuffer[]? additionalBuffers = null) { var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }, comparer); var end = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = endOp, Index = int.MaxValue }, comparer); @@ -500,10 +472,10 @@ private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer) + private static void ProcessSortedInstructions(SpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer, SpirvBuffer[]? additionalBuffers = null) { for (var firstIndex = start; firstIndex < end;) { @@ -541,7 +513,13 @@ private static void ProcessSortedInstructions(SpirvBuffer buffer, List Date: Wed, 25 Mar 2026 23:32:42 +0900 Subject: [PATCH 1006/1182] SDSL: Fix OpDecorate cast bug --- sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index a0e3af2d2a..4efb00653c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -1179,14 +1179,14 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont || i.Op == Op.OpSDSLFunctionInfo || i.Op == Op.OpSourceHashSDSL) return true; - if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && ((OpDecorate)i).Decoration is + if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && (Decoration)i.Data.Memory.Span[2] is Decoration.FunctionParameterDefaultValueSDSL or Decoration.ShaderConstantSDSL or Decoration.PatchConstantFuncSDSL or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL or Decoration.ResourceGroupIdSDSL or Decoration.SamplerStateSDSL) return true; - if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && ((OpMemberDecorate)i).Decoration is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) + if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && (Decoration)i.Data.Memory.Span[3] is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) return true; // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) From 67b5eb52a200ea53ca828e3809dba82ca0e44f86 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 00:41:06 +0900 Subject: [PATCH 1007/1182] SDSL: Fix texture indexer type mismatch when coords need int conversion When tex[float2Coord] compiles to Texture.Load(int3), the extracted float scalars must be converted to int before OpCompositeConstruct. --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 4134639a65..714ea1cab2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -925,8 +925,13 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Intrinsic expects more components than input (e.g. Texture2D.Load takes int3 = coord + LOD) // Decompose input coord, append LOD=0, recompose Span values = stackalloc int[texcoordSize]; + var sourceElementType = context.ReverseTypes[indexValue.TypeId].GetElementType(); + var targetElementType = texcoordType.GetElementType(); for (int j = 0; j < inputSize; ++j) - values[j] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(context.ReverseTypes[indexValue.TypeId].GetElementType()), context.Bound++, indexValue.Id, [j])).ResultId; + { + var extractedValue = new SpirvValue(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, indexValue.Id, [j]))); + values[j] = builder.Convert(context, extractedValue, targetElementType).Id; + } for (int j = inputSize; j < texcoordSize; ++j) values[j] = context.CompileConstant((int)0).Id; indexValue = new(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(texcoordType), context.Bound++, [.. values]))); From f64b1d1975bac02fe9d68a5e76c273c2256601fe Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 00:44:44 +0900 Subject: [PATCH 1008/1182] SDSL: Add StorageImageExtendedFormats capability for non-core image formats --- .../Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 4efb00653c..b7466007ea 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -185,6 +185,19 @@ private static void AddRequiredCapabilities(SpirvContext context, SpirvBuffer te break; } } + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.ImageFormat is + ImageFormat.Rg32f or ImageFormat.Rg16f or ImageFormat.R11fG11fB10f or ImageFormat.R16f or + ImageFormat.Rgba16 or ImageFormat.Rgb10A2 or ImageFormat.Rg16 or ImageFormat.Rg8 or ImageFormat.R16 or ImageFormat.R8 or + ImageFormat.Rgba16Snorm or ImageFormat.Rg16Snorm or ImageFormat.Rg8Snorm or ImageFormat.R16Snorm or ImageFormat.R8Snorm or + ImageFormat.Rg32i or ImageFormat.Rg16i or ImageFormat.Rg8i or ImageFormat.R16i or ImageFormat.R8i or + ImageFormat.Rgb10a2ui or ImageFormat.Rg32ui or ImageFormat.Rg16ui or ImageFormat.Rg8ui or ImageFormat.R16ui or ImageFormat.R8ui) + { + context.Add(new OpCapability(Capability.StorageImageExtendedFormats)); + break; + } + } foreach (var i in temp) { if (i.Op is Op.OpImageQuerySizeLod or Op.OpImageQuerySize or Op.OpImageQueryLevels or Op.OpImageQuerySamples) From 27464e491ced67f54a7411e3d3ad1f3f12402ebb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 08:21:07 +0900 Subject: [PATCH 1009/1182] SDSL: Implement firstbitlow, fma, sincos, isfinite, frexp, asdouble, and 16-bit bitcast intrinsics --- .../SDSL/AST/IntrinsicImplementations.cs | 72 ++++++++++++++++--- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 20087c9692..a638f60c3c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -23,10 +23,39 @@ public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder buil throw new NotImplementedException(); } - public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => throw new NotImplementedException(); - public override SpirvValue CompileAsfloat16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileAsint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileAsuint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) + { + // asdouble(uint, uint) -> double OR asdouble(uint2, uint2) -> double2 + // Each pair of uints is packed into uint2 then bitcast to double + var inputType = context.ReverseTypes[x.TypeId]; + var uint2Type = context.GetOrRegister(new VectorType(ScalarType.UInt, 2)); + var doubleType = context.GetOrRegister(ScalarType.Double); + + if (inputType is ScalarType) + { + var packed = builder.Insert(new OpCompositeConstruct(uint2Type, context.Bound++, [x.Id, y.Id])); + var result = builder.Insert(new OpBitcast(doubleType, context.Bound++, packed.ResultId)); + return new(result.ResultId, result.ResultType); + } + else if (inputType is VectorType v) + { + var uintType = context.GetOrRegister(ScalarType.UInt); + var components = new int[v.Size]; + for (int i = 0; i < v.Size; i++) + { + var xi = builder.Insert(new OpCompositeExtract(uintType, context.Bound++, x.Id, [i])); + var yi = builder.Insert(new OpCompositeExtract(uintType, context.Bound++, y.Id, [i])); + var packed = builder.Insert(new OpCompositeConstruct(uint2Type, context.Bound++, [xi.ResultId, yi.ResultId])); + components[i] = builder.Insert(new OpBitcast(doubleType, context.Bound++, packed.ResultId)).ResultId; + } + var result = new SpirvValue(builder.InsertData(new OpCompositeConstruct(context.GetOrRegister(functionType.ReturnType), context.Bound++, [.. components]))); + return result; + } + throw new InvalidOperationException($"Unexpected type {inputType} for asdouble"); + } + public override SpirvValue CompileAsfloat16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsuint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); // Trigo public override SpirvValue CompileSin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); @@ -39,7 +68,15 @@ public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder buil public override SpirvValue CompileTanh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); public override SpirvValue CompileAtan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); public override SpirvValue CompileAtan2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); - public override SpirvValue CompileSincos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c) => throw new NotImplementedException(); + public override SpirvValue CompileSincos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c) + { + // sincos(x, out s, out c): compute sin and cos separately, store to out params + var sinVal = CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); + var cosVal = CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + builder.Insert(new OpStore(s.Id, sinVal.Id, null, [])); + builder.Insert(new OpStore(c.Id, cosVal.Id, null, [])); + return new(); + } // Derivatives public override SpirvValue CompileDdx(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdx, x); @@ -409,10 +446,27 @@ public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder bu } throw new InvalidOperationException($"Unexpected type {inputType} for f32tof16"); } - public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) => throw new NotImplementedException(); - public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); - public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); + public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFindILsb, x); + public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) + { + var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, c.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) + { + var instruction = builder.Insert(new GLSLFrexp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, exp.Id)); + return new(instruction.ResultId, instruction.ResultType); + } + public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + { + // isfinite(x) = !(isinf(x) || isnan(x)) + var boolType = context.GetOrRegister(functionType.ReturnType); + var isInf = builder.Insert(new OpIsInf(boolType, context.Bound++, x.Id)); + var isNan = builder.Insert(new OpIsNan(boolType, context.Bound++, x.Id)); + var infOrNan = builder.Insert(new OpLogicalOr(boolType, context.Bound++, isInf.ResultId, isNan.ResultId)); + var result = builder.Insert(new OpLogicalNot(boolType, context.Bound++, infOrNan.ResultId)); + return new(result.ResultId, result.ResultType); + } public override SpirvValue CompileIsnormal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); public override SpirvValue CompileLdexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); public override SpirvValue CompileLit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m) => throw new NotImplementedException(); From 5e458cc2253fbc0984a0f2aa6cb9311d31cd950f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 11:02:20 +0900 Subject: [PATCH 1010/1182] SDSL: Fix namesByOp sorted invariant in MergeTypeDecorations --- ...atesRemover.cs => TypeDuplicatesHelper.cs} | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) rename sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/{TypeDuplicatesRemover.cs => TypeDuplicatesHelper.cs} (94%) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs similarity index 94% rename from sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs rename to sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs index 9809730236..1f663146f8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesRemover.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs @@ -375,7 +375,16 @@ public static bool OpCheckDuplicateForConstant(Op op) // OpName mismatches are harmless — just adopt the remove-side name onto keepId var clone = new OpData(rInst.Data.Memory.Span); clone.Memory.Span[1] = keepId; - namesByOp.Add(new InstructionSortHelper { Op = clone.Op, Index = -1, Data = clone }); + var insertIndex = keepStart < namesByOp.Count ? namesByOp[keepStart].Index : 0; + namesByOp.Insert(keepEnd, new InstructionSortHelper { Op = clone.Op, Index = insertIndex, Data = clone }); + keepEnd++; + // Inserting before the remove range shifts its indices + if (keepEnd <= removeStart + 1) // +1 because keepEnd was just incremented + { + removeStart++; + removeEnd++; + r++; + } span = CollectionsMarshal.AsSpan(namesByOp); // re-acquire after mutation } else @@ -461,6 +470,11 @@ public void RemoveDuplicates() ProcessInstructions(buffer, namesByOp, Op.OpName, Op.OpName, true, comparerSort); } + /// + /// Finds all instructions in the [startOp..endOp] range using binary search on the sorted list, + /// optionally re-sorts them (needed after previous ReplaceRefs may have changed operand values), + /// then delegates to ProcessSortedInstructions for dedup. + /// private static void ProcessInstructions(SpirvBuffer buffer, List instructionsByOp, Op startOp, Op endOp, bool sort, OperationComparer comparer, SpirvBuffer[]? additionalBuffers = null) { var start = ~instructionsByOp.BinarySearch(new InstructionSortHelper { Op = startOp, Index = -1 }, comparer); @@ -475,6 +489,13 @@ private static void ProcessInstructions(SpirvBuffer buffer, List + /// Walks a sorted range of instructions, groups consecutive duplicates (same opcode and operands), + /// keeps the first of each group, NOPs the rest, and rewrites all IdRef references in the buffer + /// (and any additionalBuffers) to point to the kept instruction's IdResult. + /// For decoration ops (OpName, OpDecorate, etc.), duplicates are simply NOPed without ref replacement + /// since they use Target rather than IdResult. + /// private static void ProcessSortedInstructions(SpirvBuffer buffer, List instructionsByOp, int start, int end, OperationComparer comparer, SpirvBuffer[]? additionalBuffers = null) { for (var firstIndex = start; firstIndex < end;) From b00e92ae48d4ca433d8d49ab0a5eed4ba2e80b10 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 10:53:43 +0900 Subject: [PATCH 1011/1182] SDSL: Removed commented-out dead code files --- .../Parsing/SDFX/Parsers/EffectFileParsers.cs | 36 -- .../Parsing/SDSL/AST/AssignOperator.cs | 76 --- .../Parsing/SDSL/AST/Operator.cs | 153 ------ .../Spirv/Processing/BoundReducer.cs | 88 --- .../Spirv/Processing/CapabilitiesCompute.cs | 62 --- .../Spirv/Processing/CompressBuffer.cs | 30 -- .../Processing/FunctionVariableOrderer.cs | 57 -- .../Spirv/Processing/INanoPass.cs | 17 - .../Spirv/Processing/IOReplace.cs | 74 --- .../Spirv/Processing/IOVariableDecorator.cs | 505 ------------------ .../Spirv/Processing/IPostProcessorSubPass.cs | 14 - .../Spirv/Processing/IdRefOffsetter.cs | 41 -- .../MemoryModelDuplicatesRemover.cs | 42 -- .../Spirv/Processing/MixinMerger.cs | 36 -- .../Spirv/Processing/PostProcessor.cs | 25 - .../Spirv/Processing/SDSLOpRemover.cs | 18 - .../Spirv/Processing/TypeDuplicatesHelper.cs | 1 - 17 files changed, 1275 deletions(-) delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs deleted file mode 100644 index b97a9fe1cd..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectFileParsers.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Stride.Shaders.Parsing.SDFX.AST; -using Stride.Shaders.Parsing.SDSL; - -namespace Stride.Shaders.Parsing.SDFX; - -// public record struct EffectFileParser : IParser -// { -// public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectFile parsed, in ParseError? orError = null) -// where TScanner : struct, IScanner -// { -// var position = scanner.Position; - -// CommonParsers.Spaces0(ref scanner, result, out _); -// throw new NotImplementedException(); -// } -// } - - -// public record struct EffectNamespaceParser : IParser -// { -// public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner -// { -// var position = scanner.Position; - -// if(Terminals.Literal("namespace", ref scanner, advance: true) && CommonParsers.Spaces1(ref scanner, result, out _)) -// { -// do -// { - -// } -// while (!scanner.IsEof && !Terminals.Char(';', ref scanner) && Terminals.Char('.', ref scanner, advance: true)); -// } -// return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs deleted file mode 100644 index ea14973e3a..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AssignOperator.cs +++ /dev/null @@ -1,76 +0,0 @@ -// namespace Stride.Shaders.Parsing.SDSL; - -// public enum AssignOperator -// { -// NOp, -// Simple, -// Plus, -// Minus, -// Mul, -// Div, -// Mod, -// RightShift, -// LeftShift, -// AND, -// OR, -// XOR -// } - - -// public static class StringAssignOperatorExtensions -// { -// public static AssignOperator ToAssignOperator(this ReadOnlySpan s) -// { -// return s switch -// { -// "+=" => AssignOperator.Plus, -// "-=" => AssignOperator.Minus, -// "*=" => AssignOperator.Mul, -// "/=" => AssignOperator.Div, -// "%=" => AssignOperator.Mod, -// ">>=" => AssignOperator.RightShift, -// "<<=" => AssignOperator.LeftShift, -// "&=" => AssignOperator.AND, -// "|=" => AssignOperator.OR, -// "^=" => AssignOperator.XOR, -// _ => AssignOperator.NOp -// }; -// } -// public static AssignOperator ToAssignOperator(this string s) -// { -// return s switch -// { -// "=" => AssignOperator.Simple, -// "+=" => AssignOperator.Plus, -// "-=" => AssignOperator.Minus, -// "*=" => AssignOperator.Mul, -// "/=" => AssignOperator.Div, -// "%=" => AssignOperator.Mod, -// ">>=" => AssignOperator.RightShift, -// "<<=" => AssignOperator.LeftShift, -// "&=" => AssignOperator.AND, -// "|=" => AssignOperator.OR, -// "^=" => AssignOperator.XOR, -// _ => AssignOperator.NOp -// }; -// } -// public static string ToAssignSymbol(this AssignOperator s) -// { -// return s switch -// { -// AssignOperator.Simple => "=", -// AssignOperator.Plus => "+=", -// AssignOperator.Minus => "-=", -// AssignOperator.Mul => "*=", -// AssignOperator.Div => "/=", -// AssignOperator.Mod => "%=", -// AssignOperator.RightShift => ">>=", -// AssignOperator.LeftShift => "<<=", -// AssignOperator.AND => "&=", -// AssignOperator.OR => "|=", -// AssignOperator.XOR => "^=", -// _ => "NOp" -// }; -// } -// } - diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs deleted file mode 100644 index e1623d0931..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Operator.cs +++ /dev/null @@ -1,153 +0,0 @@ -// namespace Stride.Shaders.Parsing.SDSL; - -// public enum Operator -// { -// Nop, -// Cast, -// Positive, -// Negative, -// Not, -// /// -// /// Bitwise not -// /// -// BitwiseNot, -// /// -// /// Increment -// /// -// Inc, -// /// -// /// Decrement -// /// -// Dec, -// Plus, -// Minus, -// Mul, -// Div, -// Mod, -// RightShift, -// LeftShift, -// AND, -// OR, -// XOR, -// Greater, -// Lower, -// GreaterOrEqual, -// LowerOrEqual, -// NotEquals, -// Equals, -// LogicalAND, -// LogicalOR, -// Accessor, -// Indexer -// } - -// public static class StringOperatorExtensions -// { -// public static Operator ToOperator(this ReadOnlySpan s) -// { -// return s switch -// { -// "!" => Operator.Not, -// "~" => Operator.BitwiseNot, -// "++" => Operator.Inc, -// "--" => Operator.Dec, -// "+" => Operator.Plus, -// "-" => Operator.Minus, -// "*" => Operator.Mul, -// "/" => Operator.Div, -// "%" => Operator.Mod, -// ">>" => Operator.RightShift, -// "<<" => Operator.LeftShift, -// "&" => Operator.AND, -// "|" => Operator.OR, -// "^" => Operator.XOR, -// ">" => Operator.Greater, -// "<" => Operator.Lower, -// ">=" => Operator.GreaterOrEqual, -// "<=" => Operator.LowerOrEqual, -// "==" => Operator.Equals, -// "!=" => Operator.NotEquals, -// "&&" => Operator.LogicalAND, -// "||" => Operator.LogicalOR, -// _ => Operator.Nop, -// }; -// } -// public static Operator ToOperator(this string s) -// { -// return s switch -// { -// "!" => Operator.Not, -// "~" => Operator.BitwiseNot, -// "++" => Operator.Inc, -// "--" => Operator.Dec, -// "+" => Operator.Plus, -// "-" => Operator.Minus, -// "*" => Operator.Mul, -// "/" => Operator.Div, -// "%" => Operator.Mod, -// ">>" => Operator.RightShift, -// "<<" => Operator.LeftShift, -// "&" => Operator.AND, -// "|" => Operator.OR, -// "^" => Operator.XOR, -// ">" => Operator.Greater, -// "<" => Operator.Lower, -// ">=" => Operator.GreaterOrEqual, -// "<=" => Operator.LowerOrEqual, -// "==" => Operator.Equals, -// "!=" => Operator.NotEquals, -// "&&" => Operator.LogicalAND, -// "||" => Operator.LogicalOR, -// _ => Operator.Nop, -// }; -// } -// public static string ToSymbol(this Operator s) -// { -// return s switch -// { -// Operator.Not => "!", -// Operator.BitwiseNot => "~", -// Operator.Inc => "++", -// Operator.Dec => "--", -// Operator.Plus => "+", -// Operator.Minus => "-", -// Operator.Mul => "*", -// Operator.Div => "/", -// Operator.Mod => "%", -// Operator.RightShift => ">>", -// Operator.LeftShift => "<<", -// Operator.AND => "&", -// Operator.OR => "|", -// Operator.XOR => "^", -// Operator.Greater => ">", -// Operator.Lower => "<", -// Operator.GreaterOrEqual => ">=", -// Operator.LowerOrEqual => "<=", -// Operator.Equals => "==", -// Operator.NotEquals => "!=", -// Operator.LogicalAND => "&&", -// Operator.LogicalOR => "||", -// _ => "NOp" -// }; -// } - -// public static Operator ToOperator(this char c) -// { -// return c switch -// { -// '!' => Operator.Not, -// '~' => Operator.BitwiseNot, -// '+' => Operator.Plus, -// '-' => Operator.Minus, -// '*' => Operator.Mul, -// '/' => Operator.Div, -// '%' => Operator.Mod, -// '&' => Operator.AND, -// '|' => Operator.OR, -// '^' => Operator.XOR, -// '>' => Operator.Greater, -// '<' => Operator.Lower, -// _ => Operator.Nop, -// }; -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs deleted file mode 100644 index 10b0105c5d..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/BoundReducer.cs +++ /dev/null @@ -1,88 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - - - -/// -/// Makes sure indices used in spirv module are all continuous. -/// -public struct BoundReducer() : INanoPass -{ - - public readonly void Apply(SpirvBuffer buffer) - { - // First step is to find the next idResult - // If it's previous + 1 then it's okay, previous is now updated - // If it's above previous + 1, then it's not okay and we switch - - var finished = false; - var previousId = 0; - OpData? next = null!; - var countIds = 0; - - foreach (var i in buffer) - countIds += i.Data.IdResult != null ? 1 : 0; - while (!finished && previousId < countIds) - { - var countAbove = 0; - foreach (var i in buffer) - { - if (i.Data.IdResult == previousId + 1) - { - countAbove += 1; - previousId += 1; - next = i.Data; - break; - } - else if (next is null && i.Data.IdResult > previousId + 1) - { - countAbove += 1; - next = i.Data; - } - else if (next is not null && i.Data.IdResult > previousId + 1 && i.Data.IdResult < (next?.IdResult ?? 0)) - { - countAbove += 1; - next = i.Data; - } - } - if (countAbove == 0) - finished = true; - else if (next is OpData && (next?.IdResult ?? 0) > previousId + 1) - { - next?.IdResult = previousId + 1; - ReplaceRefs(next?.IdResult ?? -1, previousId + 1, buffer); - } - } - - - - } - static void ReplaceRefs(int from, int to, SpirvBuffer buffer) - { - foreach (var i in buffer) - { - foreach (var op in i.Data) - { - if (op.Kind == OperandKind.IdRef || op.Kind == OperandKind.IdResultType || op.Kind == OperandKind.IdScope || op.Kind == OperandKind.IdMemorySemantics) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairIdRefLiteralInteger) - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - else if (op.Kind == OperandKind.PairLiteralIntegerIdRef) - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - else if (op.Kind == OperandKind.PairIdRefIdRef) - { - op.Words[0] = op.Words[0] == from ? to : op.Words[0]; - op.Words[1] = op.Words[1] == from ? to : op.Words[1]; - } - } - } - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs deleted file mode 100644 index 266c4b9d1a..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CapabilitiesCompute.cs +++ /dev/null @@ -1,62 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Core.Parsing; -// using static Stride.Shaders.Spirv.Specification; - -// namespace Stride.Shaders.Spirv.Processing; - -// public struct CapabilitiesCompute : INanoPass -// { -// public void Apply(SpirvBuffer buffer) -// { -// throw new NotImplementedException("Needs to finish checking the spec"); -// } - -// public static void AddCapabilities(Instruction instruction) -// { -// if(instruction.OpCode == Op.OpEntryPoint) -// { -// if(instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.Geometry) -// { -// //Add capability geometry -// } -// else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationControl) -// { -// //Add capability tess - -// } -// else if (instruction.GetOperand("executionModel")?.Words == (int)ExecutionModel.TessellationEvaluation) -// { -// //Add capability tess -// } -// } -// else if(instruction.OpCode == Op.OpTypeFloat && instruction.Words.Span[2] == 16) -// { -// // Add capability Float16 -// } -// else if (instruction.OpCode == Op.OpTypeFloat && instruction.Words.Span[2] == 64) -// { -// // Add capability Float64 -// } -// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 64) -// { -// // Add capability Float64 -// } -// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 16) -// { -// // Add capability Float64 -// } -// else if (instruction.OpCode == Op.OpTypeInt && instruction.Words.Span[2] == 8) -// { -// // Add capability Float64 -// } - -// // TODO : Check if any atomic instructions operates on integers -// // else if (instruction.OpCode == Op.OpAtomic && instruction.Words.Span[2] == 64) -// // { -// // // Add capability Float64 -// // } - - -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs deleted file mode 100644 index 89a27561ea..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/CompressBuffer.cs +++ /dev/null @@ -1,30 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Processing; - -// namespace Stride.Shaders.Spirv.PostProcessing; - -// public struct CompressBuffer : INanoPass -// { -// public void Apply(SpirvBuffer buffer) -// { -// using var tmp = new WordBuffer(); -// foreach (var e in buffer.Declarations.UnorderedInstructions) -// if (e.OpCode != Op.OpNop) -// tmp.Insert(e); -// buffer.Declarations.InstructionSpan.Clear(); -// tmp.InstructionSpan.CopyTo(buffer.Declarations.InstructionSpan); -// buffer.Declarations.RecomputeLength(); -// foreach (var (_, f) in buffer.Functions) -// { -// tmp.InstructionSpan.Clear(); -// tmp.RecomputeLength(); -// foreach (var e in f.UnorderedInstructions) -// if (e.OpCode != Op.OpNop) -// tmp.Insert(e); -// f.InstructionSpan.Clear(); -// tmp.InstructionSpan.CopyTo(f.InstructionSpan); -// f.RecomputeLength(); -// } -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs deleted file mode 100644 index 9f7a2d8275..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/FunctionVariableOrderer.cs +++ /dev/null @@ -1,57 +0,0 @@ -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Core; -// namespace Stride.Shaders.Spirv.Processing; - -// /// -// /// Makes sure variables are created in the beginning of a function definition -// /// -// public struct FunctionVariableOrderer : INanoPass -// { -// public void Apply(SpirvBuffer buffer) -// { -// foreach(var (_,f) in buffer.Functions) -// { -// ProcessFunction(new(f.InstructionSpan)); -// f.RecomputeLength(); -// } -// } -// public static void ProcessFunction(SpirvSpan function) -// { -// using var tmp = new SpirvBuffer(function.Span.Length); -// var enumerator = function.GetEnumerator(); -// enumerator.MoveNext(); -// var opf = enumerator.Current; -// tmp.Insert(tmp.Length, opf.Words); -// foreach(var i in function) -// { -// if(i.OpCode == Op.OpFunctionParameter) -// tmp.Insert(tmp.Length, i.Words); -// } -// while(enumerator.Current.OpCode != Op.OpLabel) -// enumerator.MoveNext(); - -// tmp.Insert(tmp.Length, enumerator.Current.Words); - -// foreach (var i in function) -// { -// if(i.OpCode == Op.OpVariable) -// { -// tmp.Insert(tmp.Length,i.Words); -// } -// } -// while(enumerator.MoveNext()) -// { -// var i = enumerator.Current; -// if (i.OpCode != Op.OpVariable && i.OpCode != Op.OpFunctionParameter) -// { -// tmp.Insert(tmp.Length, i.Words); -// } -// if (i.OpCode == Op.OpSDSLVariable) -// { -// var t = 0; -// } -// } -// function.Span.Clear(); -// tmp.InstructionSpan.CopyTo(function.Span); -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs deleted file mode 100644 index 46a116e959..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/INanoPass.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - -/// -/// Nano pass for the mixin compiler -/// -public interface INanoPass -{ - void Apply(SpirvBuffer buffer); -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs deleted file mode 100644 index eaf7f3a8e7..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOReplace.cs +++ /dev/null @@ -1,74 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Processing; -// using static Stride.Shaders.Spirv.Specification; - -// namespace Stride.Shaders.Spirv.PostProcessing; - -// public struct SDSLVariableReplace : INanoPass -// { -// public void Apply(SpirvBuffer buffer) -// { -// foreach (var i in buffer.Declarations.UnorderedInstructions) -// { -// if (i.OpCode == Op.OpSDSLIOVariable) -// { - -// var sclassv = i.GetOperand("storageclass"); -// var sclass = StorageClass.Private; -// if (sclassv != null) -// sclass = (StorageClass)sclassv.Value.Words; -// var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); -// variable.Operands.Span[1] = i.ResultId ?? -1; -// buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); -// SetOpNop(i.Words.Span); -// } -// else if (i.OpCode == Op.OpSDSLVariable) -// { -// var sclassv = i.GetOperand("storageclass"); -// var sclass = StorageClass.Private; -// if (sclassv != null) -// sclass = (StorageClass)sclassv.Value.Words; -// var variable = buffer.AddOpVariable(i.GetOperand("resultType") ?? -1, sclass, i.GetOperand("initializer")); -// variable.Operands.Span[1] = i.ResultId ?? -1; -// buffer.AddOpName(variable, i.GetOperand("name") ?? $"var{Guid.NewGuid()}"); -// SetOpNop(i.Words.Span); -// } -// } -// foreach (var (n, f) in buffer.Functions) -// { -// foreach (var i in f.UnorderedInstructions) -// { -// if(i.OpCode == Op.OpSDSLFunctionParameter) -// { -// var name = i.GetOperand("name"); -// var resultType = i.ResultType ?? -1; -// var variable = f.AddOpFunctionParameter(resultType); -// variable.Operands.Span[1] = i.ResultId ?? -1; -// buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); -// SetOpNop(i.Words.Span); -// } -// else if (i.OpCode == Op.OpSDSLVariable) -// { - -// var sclassv = i.GetOperand("storageclass"); -// var sclass = StorageClass.Private; -// if (sclassv != null) -// sclass = (StorageClass)sclassv.Value.Words; -// var name = i.GetOperand("name"); -// var resultType = i.ResultType ?? -1; -// var initializer = i.GetOperand("initializer"); -// var variable = f.AddOpVariable(resultType, sclass, initializer); -// variable.Operands.Span[1] = i.ResultId ?? -1; -// buffer.AddOpName(variable, name ?? $"var{Guid.NewGuid()}"); -// SetOpNop(i.Words.Span); -// } -// } -// } -// } -// static void SetOpNop(Span words) -// { -// words[0] = words.Length << 16; -// words[1..].Clear(); -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs deleted file mode 100644 index 874b12a34a..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IOVariableDecorator.cs +++ /dev/null @@ -1,505 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Processing; -// using static Stride.Shaders.Spirv.Specification; - -// namespace Stride.Shaders.Spirv.PostProcessing; - -// public struct IOVariableDecorator : INanoPass -// { -// public void Apply(SpirvBuffer buffer) -// { -// int inputLocation = -1; -// int outputLocation = -1; -// foreach (var i in buffer.Declarations) -// { -// if(i.OpCode == Op.OpSDSLIOVariable) -// { -// var execution = (ExecutionModel)(i.GetOperand("executionModel")?.Words ?? -1); -// var storage = (StorageClass)(i.GetOperand("storageclass")?.Words ?? -1); -// var semantic = i.GetOperand("semantic")?.Value ?? throw new NotImplementedException(); -// if (semantic == "SV_Position") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage,execution) switch -// { -// (StorageClass.Input, ExecutionModel.Fragment) => (int)BuiltIn.FragCoord, -// (StorageClass.Input or StorageClass.Output, _) -// => (int)BuiltIn.Position, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_ClipDistance") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Input or StorageClass.Output, _) -// => (int)BuiltIn.ClipDistance, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_CullDistance") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Input or StorageClass.Output, _) -// => (int)BuiltIn.CullDistance, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_VertexID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Input, ExecutionModel.Vertex) -// => (int)BuiltIn.VertexIndex, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_InstanceID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Input, ExecutionModel.Vertex) -// => (int)BuiltIn.InstanceIndex, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_Depth" || semantic == "SV_DepthGreaterEqual" || semantic == "SV_DepthLessEqual") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Output,ExecutionModel.Fragment) -// => (int)BuiltIn.FragDepth, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_IsFrontFace") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// (StorageClass.Input, ExecutionModel.Fragment) -// => (int)BuiltIn.FrontFacing, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_DispatchThreadID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.GLCompute -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// or ExecutionModel.TaskEXT -// or ExecutionModel.TaskNV -// ) -// => (int)BuiltIn.GlobalInvocationId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_GroupID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.GLCompute -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// or ExecutionModel.TaskEXT -// or ExecutionModel.TaskNV -// ) -// => (int)BuiltIn.WorkgroupId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_GroupThreadID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.GLCompute -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// or ExecutionModel.TaskEXT -// or ExecutionModel.TaskNV -// ) -// => (int)BuiltIn.LocalInvocationId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_GroupIndex") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.GLCompute -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// or ExecutionModel.TaskEXT -// or ExecutionModel.TaskNV -// ) -// => (int)BuiltIn.LocalInvocationIndex, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_OutputControlPointID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.TessellationControl -// ) -// => (int)BuiltIn.InvocationId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_GSInstanceID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Geometry -// ) -// => (int)BuiltIn.InvocationId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_DomainLocation") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.TessellationEvaluation -// ) -// => (int)BuiltIn.TessCoord, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_PrimitiveID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.TessellationControl -// or ExecutionModel.TessellationEvaluation -// or ExecutionModel.Geometry -// or ExecutionModel.Fragment -// ) -// or( -// StorageClass.Output, -// ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// or ExecutionModel.Geometry -// ) -// => (int)BuiltIn.TessCoord, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_TessFactor") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.TessellationControl -// ) -// => (int)BuiltIn.TessLevelOuter, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_InsideTessFactor") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.TessellationControl -// ) -// => (int)BuiltIn.TessLevelInner, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_SampleIndex") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.SampleId, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_StencilRef") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Output, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.FragStencilRefEXT, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_Barycentrics") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.BaryCoordKHR, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_RenderTargetArrayIndex") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// or -// ( -// StorageClass.Output, -// ExecutionModel.Geometry -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// ) -// => (int)BuiltIn.Layer, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_ViewportArrayIndex") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// or -// ( -// StorageClass.Output, -// ExecutionModel.Geometry -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// ) -// => (int)BuiltIn.ViewportIndex, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_Coverage") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input or StorageClass.Output, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.SampleMask, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_InnerCoverage") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.FullyCoveredEXT, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_ViewID") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Input, -// ExecutionModel.Vertex -// or ExecutionModel.TessellationControl -// or ExecutionModel.TessellationEvaluation -// or ExecutionModel.Geometry -// or ExecutionModel.Fragment -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// ) -// => (int)BuiltIn.ViewIndex, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_ShadingRate") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Output, -// ExecutionModel.Vertex -// or ExecutionModel.Geometry -// or ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// ) -// => (int)BuiltIn.PrimitiveShadingRateKHR, -// ( -// StorageClass.Input, -// ExecutionModel.Fragment -// ) -// => (int)BuiltIn.ShadingRateKHR, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else if (semantic == "SV_CullPrimitive") -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.BuiltIn, -// (storage, execution) switch -// { -// ( -// StorageClass.Output, -// ExecutionModel.MeshEXT -// or ExecutionModel.MeshNV -// ) -// => (int)BuiltIn.CullPrimitiveEXT, -// _ => throw new NotImplementedException() -// } -// ); -// } -// else -// { -// buffer.AddOpDecorate( -// i.ResultId ?? -1, -// Decoration.Location, -// (storage, execution) switch -// { -// (StorageClass.Input, _) -// => ++inputLocation, -// (StorageClass.Output, _) -// => ++outputLocation, -// _ => throw new NotImplementedException() -// } -// ); -// } -// } -// } -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs deleted file mode 100644 index 5abc9b895f..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IPostProcessorSubPass.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Stride.Shaders.Spirv.Processing; - -public interface IPostProcessorSubPass -{ - void Apply(SpirvBuffer buffer, Instruction instruction); -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs deleted file mode 100644 index 28ae10d966..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/IdRefOffsetter.cs +++ /dev/null @@ -1,41 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using System; -// using System.Collections.Generic; -// using System.Linq; -// using System.Runtime.CompilerServices; -// using System.Text; -// using System.Threading.Tasks; - -// namespace Stride.Shaders.Spirv.Processing; - - - -// /// -// /// Offsets ids for each mixins inherited -// /// -// public struct IdRefOffsetter : INanoPass -// { -// public IdRefOffsetter() { } - -// public void Apply(SpirvBuffer buffer) -// { -// //int offset = 0; -// //int nextOffset = 0; -// //foreach (var i in buffer) -// //{ -// // // if we hit a mixin name we reset stuff -// // if (i.OpCode == Op.OpSDSLMixinName) -// // { -// // offset += nextOffset; -// // nextOffset = 0; -// // } -// // else -// // { -// // if (i.ResultId != null) -// // nextOffset = i.ResultId.Value; -// // i.AsRef().OffsetIds(offset); -// // } -// //} -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs deleted file mode 100644 index bd51f00fd5..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MemoryModelDuplicatesRemover.cs +++ /dev/null @@ -1,42 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using System; -// using System.Collections.Generic; -// using System.Linq; -// using System.Text; -// using System.Threading.Tasks; - -// namespace Stride.Shaders.Spirv.Processing; - - -// /// -// /// Checks for duplicate memory models in case of multiple entry points -// /// -// public struct MemoryModelDuplicatesRemover : INanoPass -// { - -// public void Apply(SpirvBuffer buffer) -// { -// var found = false; -// var wid = 0; -// var span = buffer.Declarations.InstructionSpan; -// while(wid < buffer.Declarations.Length) -// { -// if ((span[wid] & 0xFFFF) == (int)Op.OpMemoryModel) -// { -// if (!found) -// found = true; -// else -// SetOpNop(span.Slice(wid, span[wid] >> 16)); -// } -// wid += span[wid] >> 16; -// } -// } - -// static void SetOpNop(Span words) -// { -// words[0] = words.Length << 16; -// words[1..].Clear(); -// } - -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs deleted file mode 100644 index a1e7212820..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/MixinMerger.cs +++ /dev/null @@ -1,36 +0,0 @@ -// using Stride.Shaders.Spirv.Core; -// using Stride.Shaders.Spirv.Core.Buffers; -// using Stride.Shaders.Spirv.Core.Parsing; -// using System; -// using System.Collections.Generic; -// using System.Linq; -// using System.Text; -// using System.Threading.Tasks; - -// namespace Stride.Shaders.Spirv.Processing; - - -// public record struct OrderedSpvBuffer(SpirvBuffer Buffer) -// { -// public readonly OrderedEnumerator GetEnumerator() => new(Buffer); -// } - -// /// -// /// Merges mixins into one final spirv file -// /// -// public struct MixinMerger : INanoPass -// { -// public readonly void Apply(SpirvBuffer buffer) -// { -// //var temp = new SpirvBuffer(); -// //var ordered = new OrderedSpvBuffer(buffer); -// //foreach (var e in ordered) -// // if(e.OpCode != Op.OpNop) -// // temp.Add(e.Words.Span); - -// //buffer.Replace(temp, out var dispose); -// //if(dispose) -// // temp.Dispose(); -// //buffer.RecomputeBound(); -// } -// } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs deleted file mode 100644 index a7a2ae000c..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/PostProcessor.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Spirv.Processing; - -namespace Stride.Shaders.Spirv.PostProcessing; - -/// -/// Nano pass merger/optimizer/compiler -/// -public static class SpirvProcessor -{ - public static void Process(SpirvBuffer buffer) - { - //Apply(buffer); - //Apply(buffer); - //Apply(buffer); - } - - static void Apply(SpirvBuffer buffer) - where T : struct, INanoPass - { - var p = new T(); - p.Apply(buffer); - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs deleted file mode 100644 index 6b6660cfa6..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/SDSLOpRemover.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Stride.Shaders.Spirv.Core.Buffers; -using static Stride.Shaders.Spirv.Specification; - -namespace Stride.Shaders.Spirv.Processing; - - -/// -/// Removes SDSL specific instructions -/// -public struct NOPRemover : INanoPass -{ - public readonly void Apply(SpirvBuffer buffer) - { - for (int i = 0; i < buffer.Count; i++) - if (buffer[i].Op == Op.OpNop) - buffer.RemoveAt(i--); - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs index 1f663146f8..4267de6020 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs @@ -18,7 +18,6 @@ namespace Stride.Shaders.Spirv.Processing; /// /// Remove duplicate simple types. -/// Should be applied after the IdRefOffsetter. /// public class TypeDuplicateHelper { From e4ec6de539e3226e015551b044c3f4ad8d06050a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 11:14:32 +0900 Subject: [PATCH 1012/1182] SDSL: Add default case to ConvertSwizzle and remove dead code in UnaryParsers.Postfix --- .../Parsing/SDSL/AST/Expression.cs | 1 + .../ExpressionParsers/UnaryParsers.Postfix.cs | 84 ------------------- 2 files changed, 1 insertion(+), 84 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 714ea1cab2..22b379df6d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1435,6 +1435,7 @@ private static int ConvertSwizzle(char c) 'y' or 'g' => 1, 'z' or 'b' => 2, 'w' or 'a' => 3, + _ => throw new InvalidOperationException($"Invalid swizzle character '{c}'"), }; public override string ToString() => ToString(Accessors.Count); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index b868c93a84..7f56d24ddd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -55,88 +55,4 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - - // public static bool Increment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - // where TScanner : struct, IScanner - // { - // var position = scanner.Position; - // if (Accessor(ref scanner, result, out parsed)) - // { - // var pos2 = scanner.Position; - // CommonParsers.Spaces0(ref scanner, result, out _); - // if (Tokens.Literal("++", ref scanner, advance: true)) - // { - // parsed = new PostfixExpression(parsed, Operator.Inc, scanner[position..scanner.Position]); - // return true; - // } - // else - // { - // scanner.Position = pos2; - // return true; - // } - // } - // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - // } - - // public static bool Accessor(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - // where TScanner : struct, IScanner - // { - // var position = scanner.Position; - // if (Indexer(ref scanner, result, out var expression)) - // { - // var pos2 = scanner.Position; - // CommonParsers.Spaces0(ref scanner, result, out _); - // if ( - // Tokens.Char('.', ref scanner, advance: true) - // && CommonParsers.Spaces0(ref scanner, result, out _) - // && Accessor(ref scanner, result, out var accessed)) - // { - // parsed = new AccessorExpression(expression, accessed, scanner[position..scanner.Position]); - // return true; - // } - // else - // { - // scanner.Position = pos2; - // parsed = expression; - // return true; - // } - // } - // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - // } - - // internal static bool Indexer(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) - // where TScanner : struct, IScanner - // { - // var position = scanner.Position; - - // if (PrimaryParsers.Primary(ref scanner, result, out var expression)) - // { - // var pos2 = scanner.Position; - // CommonParsers.Spaces0(ref scanner, result, out _); - // if (Tokens.Char('[', ref scanner, advance: true)) - // { - // if ( - // CommonParsers.Spaces0(ref scanner, result, out _) - // && ExpressionParser.Expression(ref scanner, result, out var index) - // && CommonParsers.Spaces0(ref scanner, result, out _) - // && Tokens.Char(']', ref scanner, advance: true) - // ) - // { - // parsed = new IndexerExpression(expression, index, scanner[position..scanner.Position]); - // return true; - // } - // else return CommonParsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0021, scanner[position], scanner.Memory)); - - // } - // else - // { - // scanner.Position = pos2; - // parsed = expression; - // return true; - // } - // } - // return CommonParsers.Exit(ref scanner, result, out parsed, position, orError); - // } } - - From dad2ab377a10240642d8ef19fbf9e6065a9a9234 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 11:17:02 +0900 Subject: [PATCH 1013/1182] SDSL: Dispose temp SpirvBuffer with using to prevent leak on error paths --- sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index b7466007ea..9013abaf7e 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -35,7 +35,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o entryPoints = default; // Create new buffer for the merged result - var temp = new SpirvBuffer(); + using var temp = new SpirvBuffer(); // This is the global context for this merge operation var context = new SpirvContext(); From 8514d0927b6653c13fa8b13b303fcb9ac5f81bf5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 12:27:03 +0900 Subject: [PATCH 1014/1182] SDSL: Normalize SPIR-V extension op names (SDSL suffix), add explicit opcodes, remove dead ops - Rename 11 prefix-style ops (OpSDSL*) to suffix-style (Op*SDSL) for consistency - OpSDSLFunctionInfo renamed to OpFunctionMetadataSDSL for clarity - Add explicit opcode field to all instructions in spirv.sdsl.grammar-ext.json - Remove 4 unused/scan-only ops: OpSDSLStage (dead), OpSDSLShaderEnd, OpSDSLCompose, OpStageSDSL - Remove dead stageInstructions variable from ShaderMixer --- .../SDSL/ShaderMixer.CBuffers.cs | 10 +- .../SDSL/ShaderMixer.Reflection.cs | 14 +-- .../SDSL/ShaderMixer.ShaderInfo.cs | 6 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 12 +-- .../SDSL/ShaderMixer.cs | 54 +++++------ .../Core/ConstantExpression.cs | 10 +- .../Parsing/SDSL/AST/Expression.cs | 4 +- .../Parsing/SDSL/AST/Literals.cs | 2 +- .../Parsing/SDSL/AST/Shader.cs | 18 ++-- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 2 +- .../Spirv/Building/Builder.Class.cs | 40 ++++---- .../Spirv/Building/Context.Constants.cs | 2 +- .../Spirv/Building/Context.ExtractBuffers.cs | 8 +- .../Spirv/Building/SpirvContext.Types.cs | 12 +-- .../Spirv/Processing/TypeDuplicatesHelper.cs | 10 +- .../Extensions/spirv.sdsl.grammar-ext.json | 94 +++++++++---------- .../Information/InstructionInfo.Order.cs | 11 +-- 17 files changed, 146 insertions(+), 163 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 4df28dcd26..5b1829c42d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -181,15 +181,15 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex return linkName.LogicalGroup; } - // OpSDSLEffect is emitted for any non-root composition + // OpCompositionSDSL is emitted for any non-root composition var compositionNodes = buffer - .Where(x => x.Op == Op.OpSDSLComposition) - .Select(x => (StartIndex: x.Index, CompositionPath: ((OpSDSLComposition)x).CompositionPath)) + .Where(x => x.Op == Op.OpCompositionSDSL) + .Select(x => (StartIndex: x.Index, CompositionPath: ((OpCompositionSDSL)x).CompositionPath)) .ToList(); var shaders = buffer - .Where(x => x.Op == Op.OpSDSLShader) - .Select(x => (StartIndex: x.Index, ShaderName: ((OpSDSLShader)x).ShaderName)) + .Where(x => x.Op == Op.OpShaderSDSL) + .Select(x => (StartIndex: x.Index, ShaderName: ((OpShaderSDSL)x).ShaderName)) .ToList(); var cbuffersByNames = buffer diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 18318d6ce3..0efe87b150 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -95,16 +95,16 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) // Collect variable infos foreach (var i in buffer) { - if (i.Op == Specification.Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) + if (i.Op == Specification.Op.OpCompositionSDSL && (OpCompositionSDSL)i is { } composition) { compositionPath = composition.CompositionPath; } - else if (i.Op == Specification.Op.OpSDSLCompositionEnd) + else if (i.Op == Specification.Op.OpCompositionEndSDSL) { compositionPath = null; shaderName = null; } - else if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + else if (i.Op == Specification.Op.OpShaderSDSL && (OpShaderSDSL)i is { } shader) { shaderName = shader.ShaderName; } @@ -156,15 +156,15 @@ private void RenameVariables(MixinGlobalContext globalContext, SpirvContext cont Dictionary prefixes = new(); foreach (var i in temp) { - if (i.Op == Specification.Op.OpSDSLComposition && (OpSDSLComposition)i is { } composition) + if (i.Op == Specification.Op.OpCompositionSDSL && (OpCompositionSDSL)i is { } composition) { compositionPath = composition.CompositionPath; } - else if (i.Op == Specification.Op.OpSDSLCompositionEnd) + else if (i.Op == Specification.Op.OpCompositionEndSDSL) { compositionPath = null; } - else if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + else if (i.Op == Specification.Op.OpShaderSDSL && (OpShaderSDSL)i is { } shader) { shaderNameWithComposition = compositionPath != null ? $"{compositionPath}.{shader.ShaderName}" @@ -247,7 +247,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon string currentShaderName = string.Empty; foreach (var i in buffer) { - if (i.Op == Specification.Op.OpSDSLShader && (OpSDSLShader)i is { } shader) + if (i.Op == Specification.Op.OpShaderSDSL && (OpShaderSDSL)i is { } shader) { currentShaderName = shader.ShaderName; } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 21d4528fe3..1b85e9fe79 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -103,7 +103,7 @@ private void PopulateShaderInfo(MixinGlobalContext globalContext, SpirvContext c private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixinNode, ref OpData i, SpirvContext context) { - if (i.Op == Op.OpSDSLImportShader && new OpSDSLImportShader(ref i) is { } importShader) + if (i.Op == Op.OpImportShaderSDSL && new OpImportShaderSDSL(ref i) is { } importShader) { // TODO: some common code to generate name, so that it doesn't deviate from ToClassName() called later when doing ShadersByName lookups var shaderName = importShader.ShaderName; @@ -119,14 +119,14 @@ private void ProcessImportInfo(MixinGlobalContext globalContext, MixinNode mixin globalContext.ExternalShaders.Add(importShader.ResultId, shaderName); } - else if (i.Op == Op.OpSDSLImportFunction && new OpSDSLImportFunction(ref i) is { } importFunction) + else if (i.Op == Op.OpImportFunctionSDSL && new OpImportFunctionSDSL(ref i) is { } importFunction) { if (globalContext.ExternalShaders.ContainsKey(importFunction.Shader)) { globalContext.ExternalFunctions.Add(importFunction.ResultId, (importFunction.Shader, importFunction.FunctionName, importFunction.FunctionType)); } } - else if (i.Op == Op.OpSDSLImportVariable && new OpSDSLImportVariable(ref i) is { } importVariable) + else if (i.Op == Op.OpImportVariableSDSL && new OpImportVariableSDSL(ref i) is { } importVariable) { if (globalContext.ExternalShaders.ContainsKey(importVariable.Shader)) { diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index 1a4f676284..fce4009cf3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -44,7 +44,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha // Copy back updated shader name (in case it had generic parameters) foreach (var i in shaderBuffer.Buffer) { - if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) + if (i.Op == Op.OpShaderSDSL && (OpShaderSDSL)i is { } shaderInstruction) { mixinToMerge2.ClassName = shaderInstruction.ShaderName; break; @@ -77,8 +77,8 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con { // --- Step 1: Pre-scan for shaders needing full import --- // Two sources: - // - OpSDSLMixinInherit with NeedsFullImport: parent shader whose non-stage members are called by a child's stage method - // - OpSDSLFunctionInfo with ReferencesNonStage: shader's own non-stage members are called by its own stage method + // - OpMixinInheritSDSL with NeedsFullImport: parent shader whose non-stage members are called by a child's stage method + // - OpFunctionMetadataSDSL with ReferencesNonStage: shader's own non-stage members are called by its own stage method // The set is shared across root and composition calls so that compositions can contribute. needsFullImport ??= new HashSet(); foreach (var shader in mixinList) @@ -186,7 +186,7 @@ private static void ScanNeedsFullImport(ShaderClassInstantiation shader, HashSet var buf = shader.Buffer.Value; foreach (var i in buf.Context) { - if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit + if (i.Op == Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)i is { } inherit && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is ShaderSymbol lss) { @@ -195,7 +195,7 @@ private static void ScanNeedsFullImport(ShaderClassInstantiation shader, HashSet } foreach (var i in buf.Buffer) { - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } fi + if (i.Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)i is { } fi && (fi.Flags & FunctionFlagsMask.ReferencesNonStage) != 0) { needsFullImport.Add(shader.ClassName); @@ -226,7 +226,7 @@ private static bool HasStageMembersOrCompositions(ShaderBuffers shader) hasStage |= (variable.Flags & VariableFlagsMask.Stage) != 0; } - if (i.Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)i is { } functionInfo) + if (i.Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)i is { } functionInfo) { hasStage |= (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; } diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 9013abaf7e..c524184497 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -287,7 +287,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, { // We emit OPSDSLEffect for any non-root composition if (currentCompositionPath != null) - buffer.Add(new OpSDSLComposition(currentCompositionPath)); + buffer.Add(new OpCompositionSDSL(currentCompositionPath)); var mixinNode = new MixinNode(stage, currentCompositionPath); var contextStart = context.Count; @@ -334,7 +334,7 @@ MixinNode MergeMixinNode(MixinGlobalContext globalContext, SpirvContext context, ProcessMemberAccessAndForeach(globalContext, context, buffer, mixinNode); if (currentCompositionPath != null) - buffer.Add(new OpSDSLCompositionEnd()); + buffer.Add(new OpCompositionEndSDSL()); return mixinNode; } @@ -454,7 +454,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (i.Op == Op.OpSourceHashSDSL) include = false; - if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shader[index + 1] is { } functionInfo) + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; // Note: BuildTypesAndMethodGroups has not been called for this mixin so context.Types/ReverseTypes is not filled @@ -528,7 +528,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS SpirvBuilder.RemapIds(remapIds, ref i2); // Detect when we switch from context to main buffer - if (i2.Op == Op.OpSDSLShader) + if (i2.Op == Op.OpShaderSDSL) { isContext = false; } @@ -538,7 +538,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (TypeDuplicateHelper.OpCheckDuplicateForTypesAndImport(i2.Op)) { // We need to replace those right now (otherwise further types depending on this struct won't get properly translated) - if (i2.Op == Op.OpSDSLImportStruct && new OpSDSLImportStruct(ref i2) is { } importStruct) + if (i2.Op == Op.OpImportStructSDSL && new OpImportStructSDSL(ref i2) is { } importStruct) { var shaderName = globalContext.ExternalShaders[importStruct.Shader]; var shader2 = mixinNode.ShadersByName[shaderName]; @@ -592,7 +592,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS structId = typeStruct2.ResultId; structTypes.Add(structName, structId); // Also add an entry using ToId()-style name for structured buffer types, - // since OpSDSLImportStruct.StructName uses ToId() format (e.g. "StructuredBuffer") + // since OpImportStructSDSL.StructName uses ToId() format (e.g. "StructuredBuffer") // while OpName uses "type.StructuredBuffer.X" format if (structName.StartsWith("type.StructuredBuffer.")) structTypes.TryAdd($"StructuredBuffer<{structName.Substring("type.StructuredBuffer.".Length)}>", structId); @@ -600,7 +600,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS structTypes.TryAdd($"RWStructuredBuffer<{structName.Substring("type.RWStructuredBuffer.".Length)}>", structId); } - // Process OpSDSLImport + // Process OpImport*SDSL ProcessImportInfo(globalContext, mixinNode, ref i2, context); if (addToContext) @@ -666,20 +666,16 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) { var i = temp[index]; - if (i.Data.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderInstruction) + if (i.Data.Op == Op.OpShaderSDSL && (OpShaderSDSL)i is { } shaderInstruction) { //currentShader = mixinNode.ShadersByName[shaderInstruction.ShaderName]; // TODO: better way to find ShaderInfo currentShader = mixinNode.Shaders.First(x => index >= x.StartInstruction && index < x.EndInstruction); } - else if (i.Data.Op == Op.OpSDSLShaderEnd) - { - currentShader = null; - } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) { - if (temp[index + 1].Op == Op.OpSDSLFunctionInfo && - (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) + if (temp[index + 1].Op == Op.OpFunctionMetadataSDSL && + (OpFunctionMetadataSDSL)temp[index + 1] is { } functionInfo) { var functionName = context.Names[function.ResultId]; var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; @@ -692,7 +688,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) methodMixinGroup = methodMixinGroup.Stage; - // If OpSDSLFunctionInfo.Parent is coming from a OpSDSLImportFunction, find the real ID + // If OpFunctionMetadataSDSL.Parent is coming from a OpImportFunctionSDSL, find the real ID if (functionInfo.Parent != 0) { if (globalContext.ExternalFunctions.TryGetValue(functionInfo.Parent, out var parentFunctionInfo)) @@ -732,7 +728,7 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, } else { - // Remove the OpSDSLFunctionInfo + // Remove the OpFunctionMetadataSDSL //SetOpNop(temp[index + 1].Data.Memory.Span); } } @@ -862,7 +858,6 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte var memberAccesses = new Dictionary(); var thisInstructions = new HashSet(); var baseInstructions = new HashSet(); - var stageInstructions = new HashSet(); var compositionArrayAccesses = new Dictionary(); ShaderInfo? currentShader = null; for (var index = mixinNode.StartInstruction; index < mixinNode.EndInstruction; index++) @@ -888,11 +883,6 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte baseInstructions.Add(baseInstruction.ResultId); SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpStageSDSL && (OpStageSDSL)i is { } stageInstruction) - { - stageInstructions.Add(stageInstruction.ResultId); - SetOpNop(i.Data.Memory.Span); - } else if (i.Data.Op == Op.OpAccessChain && (OpAccessChain)i is { } accessChain) { if (mixinNode.CompositionArrays.TryGetValue(accessChain.BaseId, out var compositions) @@ -998,7 +988,7 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte SetOpNop(i.Data.Memory.Span); } - else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function && temp[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)temp[index + 1] is { } functionInfo) + else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function && temp[index + 1].Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)temp[index + 1] is { } functionInfo) { if (!mixinNode.MethodGroups.TryGetValue(function.ResultId, out var methodGroupEntry)) throw new InvalidOperationException($"Can't find method group info for {context.Names[function.ResultId]}"); @@ -1179,17 +1169,17 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont if (i.Op == Op.OpNop) return true; // Also remove some other SDSL specific operators (that we keep late mostly for debug purposes) - if (i.Op == Op.OpSDSLShader - || i.Op == Op.OpSDSLShaderEnd - || i.Op == Op.OpSDSLComposition - || i.Op == Op.OpSDSLCompositionEnd - || i.Op == Op.OpSDSLMixinInherit + if (i.Op == Op.OpShaderSDSL + + || i.Op == Op.OpCompositionSDSL + || i.Op == Op.OpCompositionEndSDSL + || i.Op == Op.OpMixinInheritSDSL || i.Op == Op.OpConstantStringSDSL || i.Op == Op.OpTypeGenericSDSL - || i.Op == Op.OpSDSLImportShader - || i.Op == Op.OpSDSLImportFunction - || i.Op == Op.OpSDSLImportVariable - || i.Op == Op.OpSDSLFunctionInfo + || i.Op == Op.OpImportShaderSDSL + || i.Op == Op.OpImportFunctionSDSL + || i.Op == Op.OpImportVariableSDSL + || i.Op == Op.OpFunctionMetadataSDSL || i.Op == Op.OpSourceHashSDSL) return true; if ((i.Op == Op.OpDecorate || i.Op == Op.OpDecorateString) && (Decoration)i.Data.Memory.Span[2] is diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs index 5c7a505fbb..6bdb8db995 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/ConstantExpression.cs @@ -135,10 +135,10 @@ private static ConstantExpression ParseInstruction(OpDataIndex inst, SpirvBuffer return new StringConstExpr(operand.ToLiteral()); } - case Op.OpSDSLGenericParameter: - case Op.OpSDSLGenericReference: + case Op.OpGenericParameterSDSL: + case Op.OpGenericReferenceSDSL: { - var genParam = (OpSDSLGenericParameter)inst; + var genParam = (OpGenericParameterSDSL)inst; return new GenericParamExpr(genParam.Index, genParam.DeclaringClass); } @@ -321,7 +321,7 @@ public override bool TryEvaluate(out object? value) /// /// Reference to a generic parameter from a (possibly ancestor) shader. -/// Replaces both OpSDSLGenericParameter and OpSDSLGenericReference — +/// Replaces both OpGenericParameterSDSL and OpGenericReferenceSDSL — /// the distinction disappears at the expression level. /// public sealed record GenericParamExpr(int Index, string DeclaringClass) : ConstantExpression @@ -332,7 +332,7 @@ public override int Emit(SpirvContext context) // it references the parent's generic parameter var typeId = context.GetOrRegister(ScalarType.Int); var id = context.Bound++; - context.Add(new OpSDSLGenericReference(typeId, id, Index, DeclaringClass)); + context.Add(new OpGenericReferenceSDSL(typeId, id, Index, DeclaringClass)); return id; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 22b379df6d..e1706bef0d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -238,10 +238,10 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var calleeOwner = functionSymbol.OwnerType; if (calleeOwner != null && calleeOwner != table.CurrentShader) { - // Parent shader: mark its OpSDSLMixinInherit with NeedsFullImport + // Parent shader: mark its OpMixinInheritSDSL with NeedsFullImport foreach (var inst in context) { - if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit + if (inst.Op == Spirv.Specification.Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)inst is { } inherit && table.ResolveShader(inherit.Shader) is { } lss && lss.Name == calleeOwner.Name) { inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index ab409542c3..acd22e27c6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -442,7 +442,7 @@ protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder build { foreach (var inst in context) { - if (inst.Op == Spirv.Specification.Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)inst is { } inherit + if (inst.Op == Spirv.Specification.Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)inst is { } inherit && table.ResolveShader(inherit.Shader) is { } lss && lss.Name == varOwner.Name) { inherit.Flags |= Spirv.Specification.MixinInheritFlagsMask.NeedsFullImport; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index a1b08e39c7..b5835704e7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -286,13 +286,13 @@ void RegisterName(int target, string name) } // Import placeholders — registered here with EmptyShaderImporter during generic instantiation. // When called with allowReplace=true from CreateShaderType, these get upgraded to real ShaderDefinition. - else if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) + else if (instruction.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)instruction is { } importShader) { var classSource = SpirvBuilder.ConvertToShaderClassSource(context, importShader); var shaderSymbol = realShaderImporter.Import(classSource, context); RegisterType(importShader.ResultId, shaderSymbol); } - else if (instruction.Op == Op.OpSDSLImportStruct && (OpSDSLImportStruct)instruction is { } importStruct) + else if (instruction.Op == Op.OpImportStructSDSL && (OpImportStructSDSL)instruction is { } importStruct) { // Register an empty placeholder struct — the real StructuredType is resolved // later via ImportShaderStruct when the shader is imported into the main context. @@ -319,7 +319,7 @@ void RegisterName(int target, string name) } /// - /// Resolves OpSDSLImportShader/OpSDSLImportStruct into SymbolTable.loadedShaders + /// Resolves OpImportShaderSDSL/OpImportStructSDSL into SymbolTable.loadedShaders /// without mutating the cached shader context. /// private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext mainContext, SpirvContext shaderContext) @@ -327,7 +327,7 @@ private static void ResolveImportsIntoTable(SymbolTable table, SpirvContext main for (var i = 0; i < shaderContext.Count; i++) { var instruction = shaderContext[i]; - if (instruction.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)instruction is { } importShader) + if (instruction.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)instruction is { } importShader) { var classSource = SpirvBuilder.ConvertToShaderClassSource(shaderContext, importShader); @@ -452,7 +452,7 @@ private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext if (instruction.Op == Op.OpFunction) { var functionFlags = FunctionFlagsMask.None; - if (shaderBuffers.Buffer[index + 1].Op == Op.OpSDSLFunctionInfo && (OpSDSLFunctionInfo)shaderBuffers.Buffer[index + 1] is { } functionInfo) + if (shaderBuffers.Buffer[index + 1].Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)shaderBuffers.Buffer[index + 1] is { } functionInfo) functionFlags = functionInfo.Flags; OpFunction functionInstruction = instruction; @@ -483,7 +483,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderDefinition shade public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - builder.Insert(new OpSDSLShader(name)); + builder.Insert(new OpShaderSDSL(name)); var openGenerics = new ConstantExpression[Generics != null ? Generics.Parameters.Count : 0]; var currentShader = new ShaderDefinition(Name, openGenerics); @@ -642,7 +642,7 @@ public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int ind table.DeclaredTypes.TryAdd(genericParameterType.ToString(), genericParameterType); var genericParameterTypeId = context.GetOrRegister(genericParameterType); - context.Add(new OpSDSLGenericParameter(genericParameterTypeId, context.Bound, index, Name.Name)); + context.Add(new OpGenericParameterSDSL(genericParameterTypeId, context.Bound, index, Name.Name)); context.AddName(context.Bound, genericParameter.Name); // Note: we skip MemberName because they should have been replaced with the preprocessor during SpirvBuilder.InstantiateMemberNames() step @@ -653,7 +653,7 @@ public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int ind } // If multiple cbuffer with same name, they will be merged - // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpSDSLImportStruct/OpSDSLImportVariable would be ambiguous) + // Still, we rename them internally to avoid name clashes (in HLSL name is skipped so it's OK, but for example OpImportStructSDSL/OpImportVariableSDSL would be ambiguous) private void RenameCBufferVariables() { var cbuffersByNames = Elements.OfType().GroupBy(x => x.Name); @@ -698,7 +698,7 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderDefini table.CurrentShader.InheritedShaders.Add(shaderType); // Mark inherit - context.Add(new OpSDSLMixinInherit(shaderId, Spirv.Specification.MixinInheritFlagsMask.None)); + context.Add(new OpMixinInheritSDSL(shaderId, Spirv.Specification.MixinInheritFlagsMask.None)); } public static ShaderDefinition LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 015f4223ad..f469c79ddc 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -564,7 +564,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler table.Push(SymbolFrame); builder.BeginFunction(context, function); - var functionInfo = new OpSDSLFunctionInfo(Specification.FunctionFlagsMask.None, 0); + var functionInfo = new OpFunctionMetadataSDSL(Specification.FunctionFlagsMask.None, 0); if (IsOverride) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 1bf1ac7748..cac3264c0d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -41,7 +41,7 @@ public static ShaderBuffers CreateFromSpan(Span span) while (wid < span.Length) { var instruction = new OpData(span.Slice(wid, span[wid] >> 16)); - if (instruction.Op == Op.OpSDSLShader) + if (instruction.Op == Op.OpShaderSDSL) isContext = false; (isContext ? context.GetBuffer() : buffer).Add(instruction); wid += span[wid] >> 16; @@ -143,14 +143,14 @@ public static void BuildInheritanceListWithoutSelf(IExternalShaderLoader shaderL foreach (var i in declaringContext) { - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter) { if (genericParameter.Index >= classSource.GenericArguments.Length) throw new NotImplementedException($"Not enough generic parameters specified when instantiating {classSource.ToClassNameWithGenerics()}"); resolvedGenericArgs ??= classSource.GenericArguments; declaringClassName ??= genericParameter.DeclaringClass; } - if (i.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)i is { } importShader) + if (i.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)i is { } importShader) { var shaderClassSource = ConvertToShaderClassSource(declaringContext, importShader); shaderMapping[importShader.ResultId] = shaderClassSource; @@ -173,11 +173,11 @@ ConstantExpression ResolveGenericArg(ConstantExpression arg) // Check inheritance foreach (var i in declaringContext) { - if (i.Op == Op.OpSDSLMixinInherit && (OpSDSLMixinInherit)i is { } inherit) + if (i.Op == Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)i is { } inherit) { if (!shaderMapping.TryGetValue(inherit.Shader, out var shaderName)) { - throw new InvalidOperationException($"BuildInheritanceListWithoutSelf: OpSDSLMixinInherit references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(", ", shaderMapping.Keys)}])"); + throw new InvalidOperationException($"BuildInheritanceListWithoutSelf: OpMixinInheritSDSL references shader ID {inherit.Shader} not found in shaderMapping (shader: {classSource.ToClassNameWithGenerics()}, mapping keys: [{string.Join(", ", shaderMapping.Keys)}])"); } // Resolve generic arguments: substitute own generics + resolve parent references @@ -194,7 +194,7 @@ ConstantExpression ResolveGenericArg(ConstantExpression arg) } } - public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpSDSLImportShader importShader) + public static ShaderClassInstantiation ConvertToShaderClassSource(SpirvContext declaringContext, OpImportShaderSDSL importShader) { var genericIds = importShader.Generics.Elements.Memory; var exprs = new ConstantExpression[genericIds.Length]; @@ -285,7 +285,7 @@ public override bool TryResolveGenericValue(SymbolType genericParameterType, str public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue) { - var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; + var genericParameter = (OpGenericParameterSDSL)context[instructionIndex]; var genericValue = genericValues![genericIndex]; textValue = genericValue; switch (genericParameterType) @@ -343,7 +343,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType { textValue = ResolveGenericAsString(genericIndex); - var genericParameter = (OpSDSLGenericParameter)context[instructionIndex]; + var genericParameter = (OpGenericParameterSDSL)context[instructionIndex]; var expr = classSource.GenericArguments[genericIndex]; // Build a standalone buffer from the expression, then import with the desired result ID. @@ -392,7 +392,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st for (int index = 0; index < shaderBuffers.Context.Count; ++index) { var i = shaderBuffers.Context[index]; - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter) { currentShaderDeclaringClass ??= genericParameter.DeclaringClass; var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; @@ -419,8 +419,8 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } - // Resolve OpSDSLGenericReference by looking up the parent import's argument - if (i.Op == Op.OpSDSLGenericReference) + // Resolve OpGenericReferenceSDSL by looking up the parent import's argument + if (i.Op == Op.OpGenericReferenceSDSL) { // Build import map lazily (after all GenericParameters are resolved above) if (importMap == null) @@ -428,7 +428,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st importMap = new(); foreach (var inst in shaderBuffers.Context) { - if (inst.Op == Op.OpSDSLImportShader && (OpSDSLImportShader)inst is { } import) + if (inst.Op == Op.OpImportShaderSDSL && (OpImportShaderSDSL)inst is { } import) importMap[import.ShaderName] = import.Generics.Elements.Memory.ToArray(); } // Also map the current shader's own resolved generics, so references to @@ -442,8 +442,8 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st } } - // OpSDSLGenericReference has the same layout as OpSDSLGenericParameter - var genRef = (OpSDSLGenericParameter)i; + // OpGenericReferenceSDSL has the same layout as OpGenericParameterSDSL + var genRef = (OpGenericParameterSDSL)i; if (importMap.TryGetValue(genRef.DeclaringClass, out var args) && genRef.Index < args.Length) { var resolvedArgId = args[genRef.Index]; @@ -453,10 +453,10 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st // Resolve the chain before extracting. var visited = new HashSet(); while (shaderBuffers.Context.GetBuffer().TryGetInstructionById(resolvedArgId, out var resolvedInst) - && (resolvedInst.Op == Op.OpSDSLGenericReference || resolvedInst.Op == Op.OpSDSLGenericParameter) + && (resolvedInst.Op == Op.OpGenericReferenceSDSL || resolvedInst.Op == Op.OpGenericParameterSDSL) && visited.Add(resolvedArgId)) { - var innerRef = (OpSDSLGenericParameter)resolvedInst; + var innerRef = (OpGenericParameterSDSL)resolvedInst; if (importMap.TryGetValue(innerRef.DeclaringClass, out var innerArgs) && innerRef.Index < innerArgs.Length) resolvedArgId = innerArgs[innerRef.Index]; else @@ -497,7 +497,7 @@ private static void InstantiateGenericShader(ref ShaderBuffers shaderBuffers, st foreach (var i in shaderBuffers.Buffer) { - if (i.Op == Op.OpSDSLShader && (OpSDSLShader)i is { } shaderDeclaration) + if (i.Op == Op.OpShaderSDSL && (OpShaderSDSL)i is { } shaderDeclaration) shaderDeclaration.ShaderName = classNameWithGenerics; } @@ -561,7 +561,7 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri var genericParameterIndex = 0; foreach (var i in shaderBuffers.Context) { - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter) { var genericParameterName = shaderBuffers.Context.Names[genericParameter.ResultId]; var genericParameterType = shaderBuffers.Context.ReverseTypes[genericParameter.ResultType]; @@ -887,12 +887,12 @@ public static SpirvBuffer CopyBuffer(SpirvBuffer shader) public static List CollectGenerics(SpirvBuffer shader) { - // Collect OpSDSLGenericParameter + // Collect OpGenericParameterSDSL List generics = new(); for (var index = 0; index < shader.Count; index++) { var i = shader[index]; - if (i.Op == Op.OpSDSLGenericParameter && (OpSDSLGenericParameter)i is { } genericParameter) + if (i.Op == Op.OpGenericParameterSDSL && (OpGenericParameterSDSL)i is { } genericParameter) { generics.Add(genericParameter.ResultId); SetOpNop(i.Data.Memory.Span); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 8f925b0a0e..a161cee8f4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -68,7 +68,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object value = null; // Check for unresolved values - if (i.Op == Specification.Op.OpSDSLGenericParameter || i.Op == Specification.Op.OpSDSLGenericReference) + if (i.Op == Specification.Op.OpGenericParameterSDSL || i.Op == Specification.Op.OpGenericReferenceSDSL) { return false; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index f95b8a66d0..44d1c01c64 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -125,10 +125,10 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI /// True if the instruction is a generic-like instruction that participates in dedup. private static bool NormalizeGenericForDedup(ref OpData iData, out bool isGenericReference) { - isGenericReference = iData.Op == Specification.Op.OpSDSLGenericReference; - var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpSDSLGenericParameter; + isGenericReference = iData.Op == Specification.Op.OpGenericReferenceSDSL; + var isRawGenericParameter = !isGenericReference && iData.Op == Specification.Op.OpGenericParameterSDSL; if (isGenericReference) - iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericParameter; + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpGenericParameterSDSL; return isGenericReference || isRawGenericParameter; } @@ -138,7 +138,7 @@ private static bool NormalizeGenericForDedup(ref OpData iData, out bool isGeneri /// private static void RestoreGenericReference(ref OpData iData) { - iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpSDSLGenericReference; + iData.Memory.Span[0] = (int)(iData.Memory.Span[0] & 0xFFFF0000) | (int)Specification.Op.OpGenericReferenceSDSL; } /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 54715b567e..1ad08ece1e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -52,7 +52,7 @@ public int GetOrRegister(SymbolType? type) var emittedArgs = new int[ss.GenericArguments.Length]; for (int i = 0; i < emittedArgs.Length; i++) emittedArgs[i] = ss.GenericArguments[i].Emit(this); - Add(new OpSDSLImportShader(id, new(ss.Name), new(emittedArgs.AsSpan()))); + Add(new OpImportShaderSDSL(id, new(ss.Name), new(emittedArgs.AsSpan()))); AddName(id, ss.Name); shaderImportIds[ss.Name] = id; return id; @@ -63,7 +63,7 @@ public int GetOrRegister(SymbolType? type) } /// - /// Returns the SPIR-V import ID for a shader definition, creating an OpSDSLImportShader + /// Returns the SPIR-V import ID for a shader definition, creating an OpImportShaderSDSL /// instruction if this is the first time this shader is imported in this context. /// Struct types from the shader are registered in Types/ReverseTypes (they are real SPIR-V types). /// @@ -254,7 +254,7 @@ private int ImportShaderType(ShaderDefinition shaderSymbol, string key) var emittedArgs = new int[shaderSymbol.GenericArguments.Length]; for (int i = 0; i < emittedArgs.Length; i++) emittedArgs[i] = shaderSymbol.GenericArguments[i].Emit(this); - Add(new OpSDSLImportShader(id, new(shaderSymbol.Name), new(emittedArgs.AsSpan()))); + Add(new OpImportShaderSDSL(id, new(shaderSymbol.Name), new(emittedArgs.AsSpan()))); AddName(id, shaderSymbol.Name); shaderImportIds[key] = id; @@ -272,7 +272,7 @@ private int ImportShaderType(ShaderDefinition shaderSymbol, string key) private void ImportShaderStruct(int shaderId, StructuredType structType, out int structImportedId) { - var @struct = Add(new OpSDSLImportStruct(Bound++, structType.ToId(), shaderId)); + var @struct = Add(new OpImportStructSDSL(Bound++, structType.ToId(), shaderId)); AddName(@struct.ResultId, structType.Name); // Fill the ID @@ -286,7 +286,7 @@ private void ImportShaderStruct(int shaderId, StructuredType structType, out int public void ImportShaderVariable(int shaderId, ref Symbol symbol, Specification.VariableFlagsMask flags) { symbol.IdRef = Bound++; - Add(new OpSDSLImportVariable(symbol.IdRef, GetOrRegister(symbol.Type), symbol.Id.Name, shaderId, flags)); + Add(new OpImportVariableSDSL(symbol.IdRef, GetOrRegister(symbol.Type), symbol.Id.Name, shaderId, flags)); AddName(symbol.IdRef, symbol.Id.Name); } @@ -296,7 +296,7 @@ public void ImportShaderMethod(int shaderId, ref Symbol symbol, Specification.Fu var functionTypeId = GetOrRegister(functionType); symbol.IdRef = Bound++; - Add(new OpSDSLImportFunction(symbol.IdRef, functionTypeId, symbol.Id.Name, shaderId, flags)); + Add(new OpImportFunctionSDSL(symbol.IdRef, functionTypeId, symbol.Id.Name, shaderId, flags)); AddName(symbol.IdRef, symbol.Id.Name); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs index 4267de6020..941f7e8063 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs @@ -102,7 +102,7 @@ public int Compare(InstructionSortHelper x, InstructionSortHelper y) return comparison; } // Standard ResultType/ResultId instructions: ignore ResultId (Span[2]) and compare the rest - else if (x.Op == Op.OpSDSLGenericParameter || OpCheckDuplicateForConstant(x.Op)) + else if (x.Op == Op.OpGenericParameterSDSL || OpCheckDuplicateForConstant(x.Op)) { comparison = x.Data.Memory.Span[1].CompareTo(y.Data.Memory.Span[1]); if (comparison != 0) @@ -292,10 +292,10 @@ public static bool OpCheckDuplicateForTypesAndImport(Op op) || op == Op.OpTypeStreamsSDSL || op == Op.OpTypeGeometryStreamOutputSDSL || op == Op.OpTypePatchSDSL - || op == Op.OpSDSLImportShader - || op == Op.OpSDSLImportVariable - || op == Op.OpSDSLImportFunction - || op == Op.OpSDSLImportStruct + || op == Op.OpImportShaderSDSL + || op == Op.OpImportVariableSDSL + || op == Op.OpImportFunctionSDSL + || op == Op.OpImportStructSDSL || op == Op.OpExtInstImport; } diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json index e5e2f745ec..c4881cb807 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json @@ -1,8 +1,8 @@ { "instructions": [ { - "opname": "OpSDSLShader", - "opcode" : 8000, + "opname": "OpShaderSDSL", + "opcode": 8000, "class": "Miscellaneous", "operands": [ { @@ -12,11 +12,8 @@ ] }, { - "opname": "OpSDSLShaderEnd", - "class": "Miscellaneous" - }, - { - "opname": "OpSDSLComposition", + "opname": "OpCompositionSDSL", + "opcode": 8002, "class": "Miscellaneous", "operands": [ { @@ -26,11 +23,13 @@ ] }, { - "opname": "OpSDSLCompositionEnd", + "opname": "OpCompositionEndSDSL", + "opcode": 8003, "class": "Miscellaneous" }, { - "opname": "OpSDSLMixinInherit", + "opname": "OpMixinInheritSDSL", + "opcode": 8004, "class": "Miscellaneous", "operands": [ { @@ -44,31 +43,8 @@ ] }, { - "opname": "OpSDSLCompose", - "class": "Miscellaneous", - "operands": [ - { - "kind": "LiteralString", - "name": "mixin" - }, - { - "kind": "LiteralString", - "name": "name" - } - ] - }, - { - "opname": "OpSDSLStage", - "class": "Miscellaneous", - "operands": [ - { - "kind": "IdRef", - "name": "stagedElement" - } - ] - }, - { - "opname": "OpSDSLImportShader", + "opname": "OpImportShaderSDSL", + "opcode": 8007, "class": "Miscellaneous", "operands": [ { @@ -86,7 +62,8 @@ ] }, { - "opname": "OpSDSLImportFunction", + "opname": "OpImportFunctionSDSL", + "opcode": 8008, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -109,7 +86,8 @@ ] }, { - "opname": "OpSDSLImportVariable", + "opname": "OpImportVariableSDSL", + "opcode": 8009, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -129,7 +107,8 @@ ] }, { - "opname": "OpSDSLImportStruct", + "opname": "OpImportStructSDSL", + "opcode": 8010, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -145,6 +124,7 @@ }, { "opname": "OpVariableSDSL", + "opcode": 8011, "class": "Memory", "operands": [ { "kind": "IdResultType" }, @@ -163,6 +143,7 @@ }, { "opname": "OpMemberAccessSDSL", + "opcode": 8012, "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, @@ -179,6 +160,7 @@ }, { "opname": "OpTypeFunctionSDSL", + "opcode": 8013, "class": "Type-Declaration", "operands": [ { "kind": "IdResult" }, @@ -194,7 +176,8 @@ ] }, { - "opname": "OpSDSLFunctionInfo", + "opname": "OpFunctionMetadataSDSL", + "opcode": 8014, "class": "Miscellaneous", "operands": [ { @@ -209,6 +192,7 @@ }, { "opname": "OpBaseSDSL", + "opcode": 8015, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" } @@ -216,13 +200,7 @@ }, { "opname": "OpThisSDSL", - "class": "Miscellaneous", - "operands": [ - { "kind": "IdResult" } - ] - }, - { - "opname": "OpStageSDSL", + "opcode": 8016, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" } @@ -230,13 +208,15 @@ }, { "opname": "OpStreamsSDSL", + "opcode": 8018, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" } ] }, { - "opname": "OpSDSLGenericParameter", + "opname": "OpGenericParameterSDSL", + "opcode": 8019, "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, @@ -252,7 +232,8 @@ ] }, { - "opname": "OpSDSLGenericReference", + "opname": "OpGenericReferenceSDSL", + "opcode": 8020, "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, @@ -269,6 +250,7 @@ }, { "opname": "OpConstantStringSDSL", + "opcode": 8021, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -280,6 +262,7 @@ }, { "opname": "OpTypeGenericSDSL", + "opcode": 8022, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -291,6 +274,7 @@ }, { "opname": "OpTypeStreamsSDSL", + "opcode": 8023, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -302,6 +286,7 @@ }, { "opname": "OpTypeGeometryStreamOutputSDSL", + "opcode": 8024, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -314,6 +299,7 @@ }, { "opname": "OpTypePatchSDSL", + "opcode": 8025, "class": "Miscellaneous", "operands": [ { "kind": "IdResult" }, @@ -330,6 +316,7 @@ }, { "opname": "OpForeachSDSL", + "opcode": 8026, "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, @@ -342,10 +329,12 @@ }, { "opname": "OpForeachEndSDSL", + "opcode": 8027, "class": "Miscellaneous" }, { "opname": "OpUnresolvableShaderSDSL", + "opcode": 8028, "class": "Miscellaneous", "operands": [ { @@ -360,6 +349,7 @@ }, { "opname": "OpEmitVertexSDSL", + "opcode": 8029, "class": "Miscellaneous", "operands": [ { @@ -370,6 +360,7 @@ }, { "opname": "OpBinaryOperationSDSL", + "opcode": 8030, "class": "Miscellaneous", "operands": [ { "kind": "IdResultType" }, @@ -381,6 +372,7 @@ }, { "opname": "OpSourceHashSDSL", + "opcode": 8031, "class": "Miscellaneous", "operands": [ { "kind" : "IdRef", "name" : "'File'" }, @@ -392,7 +384,7 @@ }, { "opname": "OpEffectSDFX", - "opcode" : 9000, + "opcode": 9000, "class": "Miscellaneous", "operands": [ { @@ -403,6 +395,7 @@ }, { "opname": "OpParamsUseSDFX", + "opcode": 9001, "class": "Miscellaneous", "operands": [ { @@ -413,6 +406,7 @@ }, { "opname": "OpParamsSDFX", + "opcode": 9002, "class": "Miscellaneous", "operands": [ { @@ -423,6 +417,7 @@ }, { "opname": "OpParamsFieldSDFX", + "opcode": 9003, "class": "Miscellaneous", "operands": [ { @@ -437,6 +432,7 @@ }, { "opname": "OpMixinSDFX", + "opcode": 9004, "class": "Miscellaneous", "operands": [ { @@ -977,4 +973,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 2a657b423c..7d3b6481af 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -25,10 +25,9 @@ void InitOrder() int group = 0; Span initSDSL = [ Op.OpNop, - Op.OpSDSLShader, + Op.OpShaderSDSL, Op.OpEffectSDFX, - Op.OpCapability, - Op.OpSDSLCompose + Op.OpCapability ]; foreach (var e in initSDSL) OrderGroup[(e, null)] = group; @@ -69,11 +68,11 @@ void InitOrder() OrderGroup[(e, null)] = group; group++; - foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x.ToString().StartsWith("OpSDSLImport") || x == Op.OpSDSLGenericParameter || x == Op.OpSDSLGenericReference)) + foreach (var e in Enum.GetValues().Where(x => x.ToString().StartsWith("OpType") || x.ToString().StartsWith("OpConstant") || x.ToString().StartsWith("OpSpec") || x.ToString().StartsWith("OpImport") || x == Op.OpGenericParameterSDSL || x == Op.OpGenericReferenceSDSL)) OrderGroup[(e, null)] = group; group++; - OrderGroup[(Op.OpSDSLMixinInherit, null)] = group; + OrderGroup[(Op.OpMixinInheritSDSL, null)] = group; group++; foreach (var e in Enum.GetValues().Where(x => x != StorageClass.Function)) @@ -92,8 +91,6 @@ void InitOrder() foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) OrderGroup[(e, null)] = group; OrderGroup[(Op.OpVariable, StorageClass.Function)] = group; - group++; - OrderGroup[(Op.OpSDSLShaderEnd, null)] = group; } /// /// Gets the order group for a given instruction, useful for sorting instructions according to the specification. From bc4b366d7e06dde8dc2876e429a1175bbb827252 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 12:41:54 +0900 Subject: [PATCH 1015/1182] SDSL: cleanup unused code and obsolete --- .../Stride.Shaders.Compilers/Direct3D/DXC.cs | 75 --------------- .../Stride.Shaders.Compilers/Direct3D/FXC.cs | 18 ---- .../EffectCompiler.cs | 71 -------------- .../Stride.Shaders.Compilers/ICompiler.cs | 7 -- .../Stride.Shaders.Compilers/SpirvOpt.cs | 92 ------------------- .../Spirv/Building/CompilerUnit.cs | 17 +--- .../Spirv/Building/Context.cs | 1 - 7 files changed, 5 insertions(+), 276 deletions(-) delete mode 100644 sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs delete mode 100644 sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs delete mode 100644 sources/shaders/Stride.Shaders.Compilers/ICompiler.cs delete mode 100644 sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs deleted file mode 100644 index a16e51ef61..0000000000 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/DXC.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Text; -using Silk.NET.Core; -using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; - -namespace Stride.Shaders.Compilers.Direct3D; - -using DXCBuffer = Silk.NET.Direct3D.Compilers.Buffer; - - - - -public record struct DXCompiler() : ICompiler -{ - - public static string sampleCode = @" -struct PSInput -{ - float4 position : SV_POSITION; - float4 color : COLOR; -}; - -PSInput VSMain(float4 position : POSITION, float4 color : COLOR) -{ - PSInput result; - - result.position = position; - result.color = color; - - return result; -} - -float4 PSMain(PSInput input) : SV_TARGET -{ - return input.color; -} - -"; - static Guid blobGuid = Guid.Parse("3DA636C9-BA71-4024-A301-30CBF125305B"); - static Guid utilsGuid = Guid.Parse("6245D6AF-66E0-48FD-80B4-4D271796748C"); - static Guid compilerGuid = Guid.Parse("73e22d93-e6ce-47f3-b5bf-f0664f39c1b0"); - static Guid compilerArgsGuid = Guid.Parse("3e56ae82-224d-470f-a1a1-fe3016ee9f9d"); - static Guid resultGuid = Guid.Parse("58346CDA-DDE7-4497-9461-6F87AF5E0659"); - static readonly DXC dxc = DXC.GetApi(); - - public bool Compile(string code, out byte[] compiled) - { - throw new NotImplementedException(); - // var content = Encoding.ASCII.GetBytes(Code); - // unsafe - // { - // var compiler = dxc.CreateInstance(ref compilerGuid); - // var utils = dxc.CreateInstance(ref utilsGuid); - // var args = dxc.CreateInstance(ref compilerArgsGuid); - - // // Console.WriteLine($"{(nint)compiler.GetAddressOf()} - {(nint)library.GetAddressOf()}"); - // IDxcBlobEncoding* sourceBlob = null; - - // SilkMarshal.ThrowHResult( - // utils.Get().CreateBlobFromPinned((void*)SilkMarshal.StringToPtr(Code), (uint)Code.Length, 1200, ref sourceBlob) - // ); - // // utils.Get().BuildArguments("mycode", "PSMain", "ps_6_0", (char**)SilkMarshal.StringArrayToPtr(["-spirv", "-T", "ps_6_0"]), 3, null, 0, ref args); - // var buff = new DXCBuffer(sourceBlob, (nuint)Code.Length); - // IDxcOperationResult* result = null; - // string[] parms = ["-spirv", "-T", "ps_6_0", "-E", "PSMain"]; - // SilkMarshal.ThrowHResult( - // compiler.Get().Compile(&buff, parms, (uint)parms.Length, null, ref resultGuid,(void**)result) - // ); - - // // Console.WriteLine((nint)result); - // } - // compiled = Memory.Empty; - // return true; - } -} diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs deleted file mode 100644 index 1d3ba4d3a9..0000000000 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/FXC.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text; -using Silk.NET.Core.Native; -using Silk.NET.Direct3D.Compilers; - -namespace Stride.Shaders.Compilers.Direct3D; - - - - -public record struct FXCompiler() : ICompiler -{ - static D3DCompiler d3d = D3DCompiler.GetApi(); - - public bool Compile(string code, out byte[] compiled) - { - throw new NotImplementedException(); - } -} diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 317657998f..f6d4f443bf 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -261,9 +261,6 @@ public override TaskOrResult Compile(ShaderMixinSo if (shaderStage == ShaderStage.Compute) break; } - - // Remove unused reflection data, as it is entirely resolved at compile time. - //CleanupReflection(bytecode.Reflection); } // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) @@ -530,74 +527,6 @@ public override TaskOrResult Compile(ShaderMixinSo return new EffectBytecodeCompilerResult(bytecode, log); } - private static void CleanupReflection(EffectReflection reflection) - { - // TODO GRAPHICS REFACTOR we hardcode several resource group we want to preserve or optimize completly - // Somehow this should be handled some other place (or probably we shouldn't cleanup reflection at all?) - bool hasMaterialGroup = false; - bool hasLightingGroup = false; - - foreach (var resourceBinding in reflection.ResourceBindings) - { - if (resourceBinding.Stage != ShaderStage.None) - { - if (!hasLightingGroup && resourceBinding.ResourceGroup == "PerLighting") - hasLightingGroup = true; - else if (!hasMaterialGroup && resourceBinding.ResourceGroup == "PerMaterial") - hasMaterialGroup = true; - } - } - - var usedConstantBuffers = new HashSet(); - - for (int i = reflection.ResourceBindings.Count - 1; i >= 0; i--) - { - var resourceBinding = reflection.ResourceBindings[i]; - - // Do not touch anything if there is logical groups - // TODO: We can do better than that: remove only if the full group can be optimized away - if (resourceBinding.LogicalGroup != null) - continue; - - if (resourceBinding.Stage == ShaderStage.None && !(hasMaterialGroup && resourceBinding.ResourceGroup == "PerMaterial") && !(hasLightingGroup && resourceBinding.ResourceGroup == "PerLighting")) - { - reflection.ResourceBindings.RemoveAt(i); - } - else if (resourceBinding.Class == EffectParameterClass.ConstantBuffer - || resourceBinding.Class == EffectParameterClass.TextureBuffer) - { - // Mark associated cbuffer/tbuffer as used - usedConstantBuffers.Add(resourceBinding.RawName); - } - } - - // Remove unused cbuffer - for (int i = reflection.ConstantBuffers.Count - 1; i >= 0; i--) - { - var cbuffer = reflection.ConstantBuffers[i]; - - // Do not touch anything if there is logical groups - // TODO: We can do better than that: remove only if the full group can be optimized away - var hasLogicalGroup = false; - foreach (var member in cbuffer.Members) - { - if (member.LogicalGroup != null) - { - hasLogicalGroup = true; - break; - } - } - - if (hasLogicalGroup) - continue; - - if (!usedConstantBuffers.Contains(cbuffer.Name)) - { - reflection.ConstantBuffers.RemoveAt(i); - } - } - } - #if STRIDE_PLATFORM_DESKTOP /// /// Writes .spv and .spvdis files. Caller must hold WriterLock. diff --git a/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs b/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs deleted file mode 100644 index e81f80f7d5..0000000000 --- a/sources/shaders/Stride.Shaders.Compilers/ICompiler.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Stride.Shaders.Compilers; - - -public interface ICompiler -{ - bool Compile(string code, out byte[] compiled); -} diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs deleted file mode 100644 index 7679abf23e..0000000000 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvOpt.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Runtime.InteropServices; -using Silk.NET.Core.Native; -using Silk.NET.Shaderc; -using Silk.NET.SPIRV.Cross; -using Stride.Shaders.Spirv.Core; -using Stride.Shaders.Spirv.Core.Buffers; -using Stride.Shaders.Compilers.Direct3D; - -namespace Stride.Shaders.Compilers; - -public static class SpirvOptimizer -{ - static Shaderc shaderc = Shaderc.GetApi(); - - public static string CompileAssembly(string code, string entrypoint, SourceLanguage language, OptimizationLevel level, string filename = "source.shader") - { - unsafe - { - var compiler = shaderc.CompilerInitialize(); - var options = shaderc.CompileOptionsInitialize(); - shaderc.CompileOptionsSetSourceLanguage(options, language); - shaderc.CompileOptionsSetOptimizationLevel(options, level); - var compResult = shaderc.CompileIntoSpvAssembly(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); - var err = shaderc.ResultGetErrorMessageS(compResult); - if (string.IsNullOrEmpty(err)) - return shaderc.ResultGetBytesS(compResult); - } - throw new Exception("Failed to compile shader"); - } - public static byte[] Compile(string code, string entrypoint, SourceLanguage language, OptimizationLevel level = OptimizationLevel.Size, string filename = "source.shader") - { - unsafe - { - var compiler = shaderc.CompilerInitialize(); - var options = shaderc.CompileOptionsInitialize(); - shaderc.CompileOptionsSetSourceLanguage(options, language); - shaderc.CompileOptionsSetOptimizationLevel(options, level); - var compResult = shaderc.CompileIntoSpv(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); - var err = shaderc.ResultGetErrorMessageS(compResult); - if (string.IsNullOrEmpty(err)) - { - var bytes = shaderc.ResultGetBytes(compResult); - var length = shaderc.ResultGetLength(compResult); - var res = new byte[length]; - new Span(bytes, (int)length).CopyTo(res.AsSpan()); - SilkMarshal.Free((nint)bytes); - return res; - } - } - throw new Exception("Failed to compile shader"); - } - public static string Translate(string code, string entrypoint, SourceLanguage from, Backend to, OptimizationLevel level = OptimizationLevel.Zero, string filename = "source.shader") - { - unsafe - { - var compiler = shaderc.CompilerInitialize(); - var options = shaderc.CompileOptionsInitialize(); - shaderc.CompileOptionsSetSourceLanguage(options, from); - shaderc.CompileOptionsSetOptimizationLevel(options, level); - var compResult = shaderc.CompileIntoSpv(compiler, code, (nuint)code.Length, ShaderKind.FragmentShader, filename, entrypoint, options); - var err = shaderc.ResultGetErrorMessageS(compResult); - if (string.IsNullOrEmpty(err)) - { - var bytes = shaderc.ResultGetBytes(compResult); - var length = shaderc.ResultGetLength(compResult); - var byteArray = new Span(bytes, (int)length); - var res = MemoryMarshal.Cast(byteArray).ToArray(); - SilkMarshal.Free((nint)bytes); - return new SpirvTranslator(res.AsMemory()).Translate(to); - } - } - throw new Exception("Failed to translate shader"); - } - - public static void Optimize(ReadOnlyMemory words) - { - unsafe - { - var bytes = MemoryMarshal.AsBytes(words.Span); - var compiler = shaderc.CompilerInitialize(); - var options = shaderc.CompileOptionsInitialize(); - shaderc.CompileOptionsSetOptimizationLevel(options, OptimizationLevel.Size); - var compResult = shaderc.CompileIntoSpvAssembly(compiler, DXCompiler.sampleCode, (nuint)DXCompiler.sampleCode.Length, ShaderKind.FragmentShader, "main.hlsl", "PSMain", options); - var err = shaderc.ResultGetErrorMessageS(compResult); - if (string.IsNullOrEmpty(err)) - { - var res = shaderc.ResultGetBytesS(compResult); - Console.WriteLine(res); - } - } - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs index cbe5843a3e..e013f36e08 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs @@ -37,7 +37,6 @@ public void Deconstruct(out SpirvBuilder builder, out SpirvContext context) context = Context; } -#pragma warning disable CS0618 // Type or member is obsolete public SpirvBuffer ToBuffer() { Context.Sort(); @@ -49,15 +48,9 @@ public ShaderBuffers ToShaderBuffers() Context.Sort(); return new(Context, Builder.GetBuffer()); } - // public override string ToString() - // { - // var builder = new StringBuilder(); - // builder - // .AppendLine("Context : ") - // .AppendLine(Spv.Dis(Context.GetBuffer())) - // .AppendLine("Functions : ") - // .AppendLine(Spv.Dis(Builder.GetBuffer())); - // return builder.ToString(); - // } -#pragma warning restore CS0618 // Type or member is obsolete + + public override string ToString() + { + return ToBuffer().GetDebuggerDisplay(); + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index f72978dd60..51131f141b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -328,7 +328,6 @@ public void RemoveNameAndDecorations(HashSet ids) public void Sort() { ThrowIfFrozen(); Buffer.Sort(); } - [Obsolete("Use the insert method instead")] public SpirvBuffer GetBuffer() => Buffer; public SpirvBuffer.Enumerator GetEnumerator() => Buffer.GetEnumerator(); From 29988d7cee2c32d3e806df1d31a4d859979a154b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 14:59:56 +0900 Subject: [PATCH 1016/1182] SDSL: Skip obj/bin when importing Stride shaders in unit tests --- .../Stride.Shaders.Tests/Stride.Shaders.Tests.csproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index 94adaad436..c263bf4799 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -38,12 +38,12 @@ - - - - - - + + + + + + From edd29c42d2b31107dce03915beab8919f88b27b0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 26 Mar 2026 15:28:11 +0900 Subject: [PATCH 1017/1182] SDSL: Fix compiler warnings in Compilers and Parsers --- build/submodules/.editorconfig | 13 ++ .../Direct3D/ShaderCompiler.cs | 20 ++- .../Direct3D/Spv2DXIL.cs | 7 +- .../EffectCompiler.cs | 23 +-- .../SDSL/EffectEvaluator.cs | 3 +- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 3 +- .../SDSL/ShaderMixer.CBuffers.cs | 14 +- .../SDSL/ShaderMixer.Decorations.cs | 1 + .../SDSL/ShaderMixer.MixinNode.cs | 10 +- .../SDSL/ShaderMixer.Reflection.cs | 5 + .../SDSL/ShaderMixer.ShaderInfo.cs | 4 +- .../SDSL/ShaderMixer.ShaderSourceEvaluator.cs | 15 +- .../SDSL/ShaderMixer.cs | 38 ++-- .../ShaderSourceComparer.cs | 4 +- .../ShaderSourceManager.cs | 67 +------ .../SpirvTranslator.cs | 3 +- .../Stride.Shaders.Compilers.csproj | 1 + .../EffectCodeWriter.cs | 21 +-- .../EffectGenerator.cs | 8 +- .../Stride.Shaders.Parsers/Core/Symbol.cs | 2 +- .../Core/SymbolFrame.cs | 3 +- .../Core/SymbolTypes.Visitors.cs | 4 +- .../Core/SymbolTypes.cs | 28 +-- .../Parsing/Analysis/SymbolTable.cs | 9 +- .../Stride.Shaders.Parsers/Parsing/IParser.cs | 3 +- .../PreProcessing/MacroPreProcessor.cs | 5 +- .../Parsing/SDFX/AST/Effect.cs | 8 +- .../Parsing/SDFX/Parsers/EffectParser.cs | 5 +- .../SDFX/Parsers/EffectStatementParsers.cs | 23 +-- .../Parsing/SDFX/Parsers/ParamsParsers.cs | 13 +- .../Parsing/SDSL/AST/Expression.cs | 166 ++++++++++-------- .../Parsing/SDSL/AST/IntrinsicCall.cs | 3 + .../SDSL/AST/IntrinsicImplementations.cs | 12 +- .../SDSL/AST/IntrinsicTemplateExpander.cs | 15 +- .../Parsing/SDSL/AST/Literals.cs | 60 ++++--- .../Parsing/SDSL/AST/Shader.cs | 57 +++--- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 40 +++-- .../Parsing/SDSL/AST/ShaderElements.cs | 25 +-- .../Parsing/SDSL/AST/Statements.Flow.cs | 10 +- .../Parsing/SDSL/AST/Statements.cs | 17 +- .../SDSL/Parsers/Common/CommonParsers.cs | 51 +++--- .../Parsing/SDSL/Parsers/Common/Delegates.cs | 6 +- .../SDSL/Parsers/Common/OptionalParser.cs | 12 -- .../DirectiveBinaryParsers.cs | 47 ++--- .../DirectiveExpressions/DirectiveParsers.cs | 49 +++--- .../DirectivePrimaryExpressionParsers.cs | 13 +- .../DirectiveUnaryParsers.Prefix.cs | 11 +- .../DirectiveUnaryParsers.cs | 13 +- .../ExpressionParsers/BinaryParsers.cs | 77 ++++---- .../PrimaryExpressionParsers.cs | 19 +- .../ExpressionParsers/UnaryParsers.Postfix.cs | 17 +- .../ExpressionParsers/UnaryParsers.Prefix.cs | 19 +- .../Parsers/LiteralParsers/LiteralParsers.cs | 51 +++--- .../Parsers/LiteralParsers/NumberParsers.cs | 9 +- .../ShaderParsers/CompositionParsers.cs | 5 +- .../ShaderParsers/ShaderAttributeParsers.cs | 9 +- .../ShaderParsers/ShaderBufferParsers.cs | 19 +- .../ShaderParsers/ShaderClassParser.cs | 15 +- .../ShaderParsers/ShaderDataParsers.cs | 48 ++--- .../ShaderParsers/ShaderElementParsers.cs | 19 +- .../ShaderParsers/ShaderFileParsers.cs | 15 +- .../ShaderParsers/ShaderMethodParsers.cs | 34 ++-- .../Parsers/ShaderParsers/ShaderParameters.cs | 19 +- .../StatementParsers.Control.cs | 19 +- .../StatementParsers/StatementParsers.Flow.cs | 21 +-- .../StatementParsers.Switch.cs | 7 +- .../StatementParsers/StatementParsers.cs | 57 +++--- .../SDSL/Parsers/Terminals/Terminals.cs | 3 +- .../Spirv/Building/Builder.CBuffer.cs | 3 + .../Spirv/Building/Builder.Class.cs | 21 ++- .../Spirv/Building/Builder.Expressions.cs | 14 +- .../Spirv/Building/Builder.Functions.cs | 3 + .../Spirv/Building/Builder.cs | 1 - .../Spirv/Building/Context.Constants.cs | 7 +- .../Spirv/Building/Context.ExtractBuffers.cs | 2 +- .../Spirv/Building/Context.cs | 2 +- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 4 +- .../Interfaces/Analysis/StreamAnalyzer.cs | 78 ++++---- .../Generation/EntryPointWrapperGenerator.cs | 9 +- .../Interfaces/InterfaceProcessor.cs | 5 +- .../Interfaces/Models/LiveAnalysis.cs | 2 +- .../Interfaces/Models/ResourceInfo.cs | 7 +- .../Transformation/StreamAccessPatcher.cs | 7 +- .../Spirv/Processing/TypeDuplicatesHelper.cs | 6 +- .../Stride.Shaders.Parsers/Spirv/Tools/Dis.cs | 7 +- .../Stride.Shaders.Tests.csproj | 2 +- .../Stride.Shaders/EffectValueDescription.cs | 5 +- .../Stride.Shaders/ShaderMixinObjectId.cs | 14 +- .../Stride.Core.ShellHelper/ShellHelper.cs | 5 +- 89 files changed, 858 insertions(+), 798 deletions(-) create mode 100644 build/submodules/.editorconfig delete mode 100644 sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs diff --git a/build/submodules/.editorconfig b/build/submodules/.editorconfig new file mode 100644 index 0000000000..ea009a8fe1 --- /dev/null +++ b/build/submodules/.editorconfig @@ -0,0 +1,13 @@ +# disable diagnostics for CppNet8 files +[CppNet8/**.cs] +dotnet_diagnostic.CS0114.severity = none +dotnet_diagnostic.CS0164.severity = none +dotnet_diagnostic.CS0219.severity = none +dotnet_diagnostic.CS0472.severity = none +dotnet_diagnostic.CS0642.severity = none +dotnet_diagnostic.CS8600.severity = none +dotnet_diagnostic.CS8602.severity = none +dotnet_diagnostic.CS8603.severity = none +dotnet_diagnostic.CS8604.severity = none +dotnet_diagnostic.CS8618.severity = none +dotnet_diagnostic.CS8625.severity = none diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index 04682a4876..e0a84c84d1 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -205,9 +205,11 @@ HResult Compile() static void ProcessCompilerErrors(ComPtr compileErrors, ShaderBytecodeResult bytecodeResult) { var compileErrorsStr = GetTextFromBlob(compileErrors); + if (compileErrorsStr is null) + return; using (StringReader reader = new StringReader(compileErrorsStr)) { - string line; + string? line; while ((line = reader.ReadLine()) != null) { if (line.Contains(": error")) @@ -232,7 +234,7 @@ string Disassemble(ComPtr bytecode) d3dCompiler.Disassemble(bytecode.GetBufferPointer(), bytecode.GetBufferSize(), Flags: 0, in noComments, ref disassembly); - string shaderDisassembly = GetTextFromBlob(disassembly); + string shaderDisassembly = GetTextFromBlob(disassembly)!; disassembly.Dispose(); return shaderDisassembly; @@ -287,7 +289,7 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl if (constantBufferDesc.Type == D3DCBufferType.D3DCTResourceBindInfo) continue; - string constantBufferName = GetUtf8Span(constantBufferDesc.Name).GetString(); + string constantBufferName = GetUtf8Span(constantBufferDesc.Name).GetString()!; var linkBuffer = effectReflection.ConstantBuffers.First(buffer => buffer.Name == constantBufferName); ValidateConstantBufferReflection(constantBuffer, ref constantBufferDesc, linkBuffer, log); @@ -305,12 +307,12 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl SkipInit(out ShaderInputBindDesc boundResourceDesc); shaderReflection.GetResourceBindingDesc(i, ref boundResourceDesc); - string linkKeyName = null; - string resourceGroup = null; - string logicalGroup = null; + string? linkKeyName = null; + string? resourceGroup = null; + string? logicalGroup = null; var elementType = default(EffectTypeDescription); - var resourceName = GetUtf8Span(boundResourceDesc.Name).GetString(); + string resourceName = GetUtf8Span(boundResourceDesc.Name).GetString()!; foreach (var linkResource in effectReflection.ResourceBindings) { @@ -439,7 +441,7 @@ void ValidateConstantBufferReflection(ComPtr blob) + static string? GetTextFromBlob(ComPtr blob) { if (blob.Handle is null) return null; diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index f27b41ede6..a7b7efea87 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -102,13 +102,10 @@ public struct RuntimeConf public dxil_shader_model shader_model_max; } -[UnmanagedFunctionPointer(CallingConvention.Cdecl)] -public unsafe delegate void MSGCallback(void* priv, string msg); - public unsafe struct DXILSpirvLogger { public void* priv; - public nint log; + public delegate* unmanaged[Cdecl] log; } public unsafe struct DXILSpirvObject @@ -126,12 +123,14 @@ public unsafe struct DXILSpirvObject public void* buffer; public nint size; } +#pragma warning disable CS0169 // Field is never used (interop layout fields) public unsafe struct Specialization { ushort id; void* value; bool defined_on_module; } +#pragma warning restore CS0169 public enum ValidatorVersion { diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index f6d4f443bf..3baa16fd37 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -37,7 +37,7 @@ public partial class EffectCompiler : EffectCompilerBase private bool d3dCompilerLoaded = false; private static readonly Object WriterLock = new Object(); - private FileShaderLoader shaderLoader; + private FileShaderLoader? shaderLoader; private readonly object shaderMixinParserLock = new object(); @@ -143,7 +143,8 @@ public override TaskOrResult Compile(ShaderMixinSo shaderMixinSource.AddMacro("class", "shader"); var shaderMixer = new ShaderMixer(GetFileShaderLoader()); - shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); + if (!shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints)) + return new EffectBytecodeCompilerResult(null, log); // ------------------------------------------------------- // Prepare DynamicCache folder for debug files @@ -166,7 +167,7 @@ public override TaskOrResult Compile(ShaderMixinSo } // Select the correct backend compiler - IShaderCompiler compiler; + IShaderCompiler? compiler; // Set to null if translator is not needed Backend? translatorBackend = null; switch (effectParameters.Platform) @@ -219,6 +220,7 @@ public override TaskOrResult Compile(ShaderMixinSo ExecutionModel.Geometry => ShaderStage.Geometry, ExecutionModel.Fragment => ShaderStage.Pixel, ExecutionModel.GLCompute => ShaderStage.Compute, + _ => throw new NotSupportedException($"Unsupported execution model: {entryPoint.ExecutionModel}"), }; #if STRIDE_PLATFORM_DESKTOP @@ -230,13 +232,14 @@ public override TaskOrResult Compile(ShaderMixinSo ShaderStage.Geometry => "gs", ShaderStage.Pixel => "ps", ShaderStage.Compute => "cs", + _ => throw new NotSupportedException($"Unsupported shader stage: {shaderStage}"), }; stageHlslSources.Add((stageSuffix, code)); - string stageFilename = null; + string? stageFilename = null; #else - string stageFilename = null; + string? stageFilename = null; #endif - var result = compiler.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename); + var result = compiler!.Compile(code, entryPoint.TranslatedName, shaderStage, effectParameters, bytecode.Reflection, stageFilename); result.CopyTo(log); if (result.HasErrors) @@ -247,7 +250,7 @@ public override TaskOrResult Compile(ShaderMixinSo // ------------------------------------------------------- // Append bytecode id to shader log #if STRIDE_PLATFORM_DESKTOP - stageStringBuilder.AppendLine("@G {0} => {1}".ToFormat(shaderStage, result.Bytecode.Id)); + stageStringBuilder.AppendLine($"@G {shaderStage} => {result.Bytecode!.Id}"); if (result.DisassembleText != null) { stageStringBuilder.Append(result.DisassembleText); @@ -292,6 +295,7 @@ public override TaskOrResult Compile(ShaderMixinSo ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, + _ => throw new NotSupportedException($"Unsupported shader stage: {entryPoint.Stage}"), }, entryPoint.Name, ValidatorVersion.DXIL_VALIDATOR_1_4, @@ -360,8 +364,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine("/**************************"); builder.AppendLine("***** Compiler Parameters *****"); builder.AppendLine("***************************"); - builder.Append("@P EffectName: "); - builder.AppendLine(fullEffectName ?? ""); + builder.AppendLine($"@P EffectName: {fullEffectName ?? "(none)"}"); builder.Append(compilerParameters?.ToStringPermutationsDetailed()); builder.AppendLine("***************************"); builder.AppendLine("**** Shader Source ****"); @@ -382,7 +385,7 @@ public override TaskOrResult Compile(ShaderMixinSo builder.AppendLine($"cbuffer {cBuffer.Name} [Size: {cBuffer.Size}]"); foreach (var parameter in cBuffer.Members) { - builder.AppendLine($"@C {parameter.RawName} => {parameter.KeyInfo.KeyName} [LogicalGroup: {parameter.LogicalGroup}]"); + builder.AppendLine($"@C {parameter.RawName} => {parameter.KeyInfo.KeyName} [LogicalGroup: {parameter.LogicalGroup ?? "(none)"}]"); } } builder.AppendLine("***************************"); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs index 2828c9f05b..5bbe688dba 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/EffectEvaluator.cs @@ -1,4 +1,5 @@ -using CommunityToolkit.HighPerformance; +#pragma warning disable CS0162 // Unreachable code detected +using CommunityToolkit.HighPerformance; using Stride.Rendering; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 32acef7e0f..e7f7d71018 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -38,9 +38,8 @@ public readonly bool Compile(string? filename, string code, ObjectId hash, ReadO if (declaration is ShaderClass shader) { var compiler = new CompilerUnit(); - SymbolTable table = new(compiler.Context) + SymbolTable table = new(compiler.Context, ShaderLoader) { - ShaderLoader = ShaderLoader, CurrentMacros = [.. macros], }; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 5b1829c42d..49e79917e3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -194,7 +194,8 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex var cbuffersByNames = buffer .Where(x => x.Op == Op.OpVariableSDSL) - .Select(x => (Index: x.Index, Variable: x)) + .Select(x => (Index: x.Index, Variable: x, StructType: context.ReverseTypes[x.Data.IdResultType!.Value] is PointerType { StorageClass: Specification.StorageClass.Uniform, BaseType: ConstantBufferSymbol s } ? s : null)) + .Where(x => x.StructType != null) // Note: MemberIndexOffset is simply a shift in Members index, not something like a byte offset .Select(x => ( Variable: x.Variable, @@ -202,7 +203,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex CompositionPath: compositionNodes.LastOrDefault(mixinNode => x.Index >= mixinNode.StartIndex).CompositionPath, ShaderName: shaders.LastOrDefault(shader => x.Index >= shader.StartIndex).ShaderName, StructTypePtrId: x.Variable.Data.IdResultType!.Value, - StructType: context.ReverseTypes[x.Variable.Data.IdResultType.Value] is PointerType { StorageClass: Specification.StorageClass.Uniform, BaseType: ConstantBufferSymbol s } ? s : null, + StructType: x.StructType!, MemberIndexOffset: 0, LogicalGroup: GetCBufferLogicalGroup(x.Variable.Data.IdResult.Value))) // TODO: Check Decoration.Block? @@ -210,7 +211,7 @@ private void MergeCBuffers(MixinGlobalContext globalContext, SpirvContext contex .GroupBy(x => ShaderClass.GetCBufferRealName(context.Names[x.VariableId])); // This helper method will transfer decorations from the old structure to the new merged structure - void ProcessDecorations(Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) + void ProcessDecorations(Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct, bool newStructure) { var cbufferStructId = context.Types[cbufferStruct]; int mergedMemberIndex = 0; @@ -234,7 +235,7 @@ void ProcessDecorations(Span<(OpDataIndex Variable, int VariableId, string Compo } // Transfer cbufferMemberLinks to new structure - CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol? StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) + CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpDataIndex Variable, int VariableId, string CompositionPath, string ShaderName, int StructTypePtrId, ConstantBufferSymbol StructType, int MemberIndexOffset, string? LogicalGroup)> cbuffersSpan, ConstantBufferSymbol cbufferStruct) { int mergedMemberIndex = 0; var links = new CBufferMemberMetadata[cbufferStruct.Members.Count]; @@ -400,6 +401,7 @@ EffectTypeDescription ConvertType(SpirvContext context, SymbolType symbolType, T => ConvertType(context, m.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.MatrixColumns, RowCount = m.Columns, ColumnCount = m.Rows }, MatrixType m when typeModifier == TypeModifier.RowMajor => ConvertType(context, m.BaseType, typeModifier, alignmentRules) with { Class = EffectParameterClass.MatrixRows, RowCount = m.Columns, ColumnCount = m.Rows }, + _ => throw new NotSupportedException($"Unsupported symbol type: {symbolType}"), }; } @@ -420,7 +422,7 @@ private void ComputeCBufferReflection(MixinGlobalContext globalContext, SpirvCon foreach (var cbuffer in cbuffers) { int constantBufferOffset = 0; - var cb = cbuffer.StructType; + var cb = cbuffer.StructType!; var structTypeId = context.Types[cb]; var memberInfos = new EffectValueDescription[cb.Members.Count]; @@ -605,7 +607,7 @@ private static void ConvertBoolCBufferMembers(SpirvContext context, SpirvBuffer /// that the engine expects (Vector2/3/4, Int2/3/4, etc.). /// Scalars (float, int, uint, bool) pass through unchanged. /// - private static object ConvertDefaultValue(object value) + private static object? ConvertDefaultValue(object? value) { if (value is not ConstantVector cv) return value; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs index ad7f5cd283..efd75fc951 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -52,6 +52,7 @@ private void EmitArrayStrideDecorations(SpirvContext context, ArrayType a, TypeM { SpirvBuilder.AlignmentRules.CBuffer => (elementSize + 15) / 16 * 16, SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, + _ => throw new NotSupportedException($"Unsupported alignment rules: {alignmentRules}"), }; context.Add(new OpDecorate(typeId, Specification.Decoration.ArrayStride, [arrayStride])); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs index 0fd926e217..0ebe76e383 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.MixinNode.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Stride.Shaders.Core; using Stride.Shaders.Spirv.Building; @@ -68,11 +68,11 @@ static void Recurse(StringBuilder sb, MixinNode node, int indent = 0) } } - class MethodGroup + class MethodGroup(string name, FunctionType functionType, ShaderInfo shader) { - public string Name; - public ShaderInfo Shader; - public FunctionType FunctionType; + public string Name { get; } = name; + public FunctionType FunctionType { get; } = functionType; + public ShaderInfo Shader { get; } = shader; public List<(ShaderInfo Shader, int MethodId, Spirv.Specification.FunctionFlagsMask Flags)> Methods { get; } = new(); public override string ToString() => $"{Name} (shader: {Shader}, function Id: {string.Join(", ", Methods.Select(x => $"{x.Shader.ShaderName} {x.MethodId}"))})"; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 0efe87b150..2d9dc8b577 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -110,6 +110,9 @@ private void ProcessLinks(SpirvContext context, SpirvBuffer buffer) } else if (i.Op == Specification.Op.OpVariableSDSL && (OpVariableSDSL)i is { } variableInstruction) { + if (shaderName is null) + throw new InvalidOperationException($"{nameof(OpVariableSDSL)} {context.Names[variableInstruction.ResultId]} without {nameof(OpShaderSDSL)}, can't figure out owner type"); + bool isStage = (variableInstruction.Flags & Specification.VariableFlagsMask.Stage) != 0; var variablePointerType = (PointerType)context.ReverseTypes[variableInstruction.ResultType]; var variableType = variablePointerType.BaseType; @@ -287,6 +290,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon BufferType b1 => b1.WriteAllowed, StructuredBufferType sb1 => sb1.WriteAllowed, ByteAddressBufferType bab1 => bab1.WriteAllowed, + _ => throw new NotSupportedException($"Unsupported variable type: {variableType}"), }; ref var slot = ref (isUAV ? ref uavSlot : ref srvSlot); effectResourceBinding.Class = isUAV ? EffectParameterClass.UnorderedAccessView : EffectParameterClass.ShaderResourceView; @@ -312,6 +316,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon (Texture1DType, false, true) => EffectParameterType.RWTexture1D, (Texture2DType, false, true) => EffectParameterType.RWTexture2D, (Texture3DType, false, true) => EffectParameterType.RWTexture3D, + _ => throw new NotSupportedException($"Unsupported texture type combination: {t}"), }, }; globalContext.Reflection.ResourceBindings.Add(resolved); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs index 1b85e9fe79..ef55e7ed7f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderInfo.cs @@ -1,4 +1,4 @@ -using Silk.NET.SPIRV.Cross; +using Silk.NET.SPIRV.Cross; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv; @@ -26,7 +26,7 @@ private class ShaderInfo(int shaderIndex, string shaderName, int startInstructio /// public ShaderInfo? Stage { get; set; } - public ShaderDefinition Symbol { get; set; } + public ShaderDefinition? Symbol { get; set; } /// /// Kept for debug purpose. diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs index fce4009cf3..2facac6fa2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.ShaderSourceEvaluator.cs @@ -30,6 +30,7 @@ private ShaderMixinInstantiation EvaluateInheritanceAndCompositions(IExternalSha { ShaderMixinSource mixinSource2 => mixinSource2, ShaderClassSource classSource => new ShaderMixinSource { Mixins = { classSource } }, + _ => throw new NotSupportedException($"Unsupported shader source type: {shaderSource.GetType().Name}"), }; var compositions = new Dictionary(); @@ -146,12 +147,12 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con if (result.Mixins.Contains(shaderName)) continue; - var shader = shaderName.Buffer.Value; + var shaderBuffers = shaderName.Buffer ?? throw new InvalidOperationException($"Shader buffers not loaded for {shaderName.ClassName}"); - bool hasStage = HasStageMembersOrCompositions(shader); + bool hasStage = HasStageMembersOrCompositions(shaderBuffers); // Discover and recursively process compositions - ProcessCompositions(shaderLoader, context, shader, shaderMixinSource, compositions, promoteToParentForCompositions, needsFullImport); + ProcessCompositions(shaderLoader, context, shaderBuffers, shaderMixinSource, compositions, promoteToParentForCompositions, needsFullImport); // Promote to parent level if this shader has stage members or needs full import if (hasStage || needsFullImport.Contains(shaderName.ClassName)) @@ -183,17 +184,17 @@ private void ProcessClasses(IExternalShaderLoader shaderLoader, SpirvContext con /// private static void ScanNeedsFullImport(ShaderClassInstantiation shader, HashSet needsFullImport) { - var buf = shader.Buffer.Value; - foreach (var i in buf.Context) + var shaderBuffers = shader.Buffer ?? throw new InvalidOperationException($"Shader buffers not loaded for {shader.ClassName}"); + foreach (var i in shaderBuffers.Context) { if (i.Op == Op.OpMixinInheritSDSL && (OpMixinInheritSDSL)i is { } inherit && (inherit.Flags & MixinInheritFlagsMask.NeedsFullImport) != 0 - && buf.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is ShaderSymbol lss) + && shaderBuffers.Context.ReverseTypes.TryGetValue(inherit.Shader, out var inheritType) && inheritType is ShaderSymbol lss) { needsFullImport.Add(lss.Name); } } - foreach (var i in buf.Buffer) + foreach (var i in shaderBuffers.Buffer) { if (i.Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)i is { } fi && (fi.Flags & FunctionFlagsMask.ReferencesNonStage) != 0) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index c524184497..e5f7008a7f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -14,6 +14,7 @@ using EntryPoint = Stride.Shaders.Core.EntryPoint; using Stride.Core.Diagnostics; using Stride.Core.UnsafeExtensions; +using System.Diagnostics.CodeAnalysis; namespace Stride.Shaders.Compilers.SDSL; @@ -27,7 +28,7 @@ public record struct Options(bool ResourcesRegisterSeparate); public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; - public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, out Span bytecode, out EffectReflection effectReflection, out HashSourceCollection usedHashSources, out List entryPoints) + public bool MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, out Span bytecode, [MaybeNullWhen(false)] out EffectReflection effectReflection, [MaybeNullWhen(false)] out HashSourceCollection usedHashSources, [MaybeNullWhen(false)] out List entryPoints) { bytecode = default; effectReflection = default; @@ -45,7 +46,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o if (ShaderLoader is ShaderLoaderBase shaderLoaderBase) shaderLoaderBase.Log = log; var shaderLoader = new CaptureLoadedShaders(ShaderLoader); - var table = new SymbolTable(context) { ShaderLoader = shaderLoader }; + var table = new SymbolTable(context, shaderLoader); //var effectEvaluator = new EffectEvaluator(shaderLoader); // We basically put the shader we want to merge through the EffectEvaluator to resolve all mixins/compositions first @@ -74,7 +75,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o catch (Exception e) { log.Error(e.Message, e); - return; + return false; } // If any semantic errors were collected during shader compilation, stop mixing @@ -82,7 +83,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o { foreach (var error in table.Errors) log.Error(error.Message); - return; + return false; } // Process streams and remove unused code/cbuffer/variable/resources @@ -149,6 +150,7 @@ public void MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o effectReflection = globalContext.Reflection; usedHashSources = shaderLoader.Sources; + return true; } private static void AddRequiredCapabilities(SpirvContext context, SpirvBuffer temp) @@ -385,7 +387,7 @@ private ShaderInfo MergeClassInBuffers(MixinGlobalContext globalContext, SpirvCo throw new InvalidOperationException("importing stage-only methods/variables is only possible at the root mixin"); } - var shaderBuffers = shaderClass.Buffer.Value; + var shaderBuffers = shaderClass.Buffer ?? throw new InvalidOperationException($"Shader buffers not loaded for {shaderClass.ClassName}"); var offset = context.Bound; var resourceGroupOffset = context.ResourceGroupBound; @@ -415,7 +417,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // If a stage member is skipped in a composition mixin, we want to remap to the version in the root mixin if (isStage && !isRootMixin) { - var stageShader = mixinNode.Stage.ShadersByName[shaderClass.ToClassNameWithGenerics()]; + var stageShader = mixinNode.Stage!.ShadersByName[shaderClass.ToClassNameWithGenerics()]; var memberOrTypeName = names[memberId]; var stageMemberOrTypeId = stageShader.StructTypes.TryGetValue(memberOrTypeName, out var structTypeId) ? structTypeId @@ -553,15 +555,15 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS // Check if type already exists in context (deduplicate them) if (typeDuplicateInserter.CheckForDuplicates(i2, out var existingInstruction)) { - if (i2.IdResult is int id) + if (i2.IdResult is int duplicateId) { - remapIds.Add(id, existingInstruction.Data.IdResult.Value); - var mismatches = typeDuplicateInserter.MergeTypeDecorations(existingInstruction.Data.IdResult.Value, id); + remapIds.Add(duplicateId, existingInstruction.Data.IdResult!.Value); + var mismatches = typeDuplicateInserter.MergeTypeDecorations(existingInstruction.Data.IdResult.Value, duplicateId); if (mismatches != null) { var details = string.Join("; ", mismatches.Select(m => $"{m.Data} (only on {(m.OnKeepOnly ? "kept" : "removed")} type)")); - globalContext.Log.Warning($"Mismatched decorations when merging type {id} into {existingInstruction.Data.IdResult.Value}: {details}"); + globalContext.Log.Warning($"Mismatched decorations when merging type {duplicateId} into {existingInstruction.Data.IdResult.Value}: {details}"); foreach (var entry in mismatches) if (!entry.OnKeepOnly) entry.Data.Dispose(); } @@ -680,13 +682,16 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, var functionName = context.Names[function.ResultId]; var functionType = (FunctionType)context.ReverseTypes[function.FunctionType]; + if (currentShader is null) + throw new InvalidOperationException($"{nameof(OpFunction)} {functionName} without {nameof(OpShaderSDSL)}, can't figure out owner type"); + // Add symbol for each method in current type (equivalent to implicit this pointer) var symbol = new Symbol(new(functionName, SymbolKind.Method), context.ReverseTypes[function.FunctionType], function.ResultId, OwnerType: currentShader.Symbol); globalContext.Table.CurrentFrame.Add(functionName, symbol); var methodMixinGroup = mixinNode; if (!mixinNode.IsRoot && (functionInfo.Flags & FunctionFlagsMask.Stage) != 0) - methodMixinGroup = methodMixinGroup.Stage; + methodMixinGroup = methodMixinGroup.Stage ?? throw new InvalidOperationException("Can't find stage mixin"); // If OpFunctionMetadataSDSL.Parent is coming from a OpImportFunctionSDSL, find the real ID if (functionInfo.Parent != 0) @@ -701,9 +706,8 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, // Check if it has a parent (and if yes, share the MethodGroup) if (!methodMixinGroup.MethodGroups.TryGetValue(functionInfo.Parent, out var methodGroup)) - methodGroup = new MethodGroup { Name = functionName, FunctionType = functionType }; + methodGroup = new MethodGroup(functionName, functionType, currentShader); - methodGroup.Shader = currentShader; methodGroup.Methods.Add((Shader: currentShader, MethodId: function.ResultId, Flags: functionInfo.Flags)); methodMixinGroup.MethodGroups[function.ResultId] = methodGroup; @@ -904,8 +908,8 @@ private static void ProcessMemberAccessAndForeach(MixinGlobalContext globalConte instanceMixinGroup = mixinNode; else { - if (!compositionArrayAccesses.TryGetValue(memberAccess.Instance, out instanceMixinGroup) - && !mixinNode.Compositions.TryGetValue(memberAccess.Instance, out instanceMixinGroup)) + if (!compositionArrayAccesses.TryGetValue(memberAccess.Instance, out instanceMixinGroup!) + && !mixinNode.Compositions.TryGetValue(memberAccess.Instance, out instanceMixinGroup!)) throw new InvalidOperationException(); } @@ -1141,13 +1145,13 @@ private static void CleanupUnnecessaryInstructions(MixinGlobalContext globalCont // Transform OpTypeFunctionSDSL into OpTypeFunction (we don't need extra info anymore) if (i.Op == Op.OpTypeFunctionSDSL && (OpTypeFunctionSDSL)i is { } functionType) { - Span parameterTypes = stackalloc int[functionType.ParameterTypes.Elements.Span.Length]; + var parameterTypes = new int[functionType.ParameterTypes.Elements.Span.Length]; for (int j = 0; j < functionType.ParameterTypes.Elements.Span.Length; ++j) parameterTypes[j] = functionType.ParameterTypes.Elements.Span[j].Item1; // Make sure to unify same types: they might have different OpTypeFunctionSDSL due to modifiers but end up having the same OpTypeFunction once modifiers info is removed // If two duplicate OpTypeFunction exists, this causes SPIR-V validation errors - var functionTypeWithIds = new FunctionTypeWithIds(functionType.ReturnType, parameterTypes.ToArray()); + var functionTypeWithIds = new FunctionTypeWithIds(functionType.ReturnType, parameterTypes); if (functionTypes.TryGetValue(functionTypeWithIds, out var functionTypeId)) { remapIds.Add(functionType.ResultId, functionTypeId); diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceComparer.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceComparer.cs index bc6a2ffa74..ef1215cdcb 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceComparer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceComparer.cs @@ -17,7 +17,7 @@ public ShaderSourceComparer() compositionComparer = new CompositionComparer(this); } - public override bool Equals(ShaderSource x, ShaderSource y) + public override bool Equals(ShaderSource? x, ShaderSource? y) { if (x == null && y == null) return true; @@ -52,7 +52,7 @@ public override bool Equals(ShaderSource x, ShaderSource y) throw new InvalidOperationException("Invalid ShaderSource comparison."); } - public override int GetHashCode(ShaderSource obj) + public override int GetHashCode(ShaderSource? obj) { if (obj == null) return 0; diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs index 3bae2ce50f..1e0f51c307 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderSourceManager.cs @@ -115,7 +115,7 @@ public static ShaderSourceWithHash CreateShaderSourceWithHash(string type, strin /// Optional shader source code. Can be use for shaders that don't have a source file /// ShaderSourceWithHash. /// If the file was not found - public ShaderSourceWithHash LoadShaderSource(string type, string shaderSourceCode = null) + public ShaderSourceWithHash LoadShaderSource(string type, string? shaderSourceCode = null) { lock (locker) { @@ -131,7 +131,7 @@ public ShaderSourceWithHash LoadShaderSource(string type, string shaderSourceCod if (sourceUrl != null) { shaderSource = new ShaderSourceWithHash(); - if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path)) + if (!UrlToFilePath.TryGetValue(sourceUrl, out shaderSource.Path!)) { shaderSource.Path = sourceUrl; } @@ -151,7 +151,7 @@ public ShaderSourceWithHash LoadShaderSource(string type, string shaderSourceCod if (File.Exists(shaderSourcePath)) { - byte[] fileData = null; + byte[]? fileData = null; for (int tries = 10; tries >= 0; --tries) { try @@ -194,7 +194,7 @@ public ShaderSourceWithHash LoadShaderSource(string type, string shaderSourceCod { sourceStream.Position = 0; var data = new byte[sourceStream.Length]; - sourceStream.Read(data, 0, (int)sourceStream.Length); + sourceStream.ReadExactly(data, 0, (int)sourceStream.Length); shaderSource.Hash = ObjectId.FromBytes(data); } else @@ -231,14 +231,14 @@ public bool IsClassExists(string typeName) return FindFilePath(typeName) != null; } - public string FindFilePath(string type) + public string? FindFilePath(string type) { lock (locker) { if (LookupDirectoryList == null) return null; - string path = null; + string? path = null; if (classNameToPath.TryGetValue(type, out path)) return path; @@ -267,22 +267,9 @@ private bool FileExists(string path) if (UseFileSystem && Platform.Type == PlatformType.Windows) { var fileInfo = new FileInfo(path); - if (fileInfo.Exists) - { - var shaderName = Path.GetFileNameWithoutExtension(path); - var realPath = GetWindowsPhysicalPath(path); - if (!string.IsNullOrWhiteSpace(realPath)) - { - var shaderNameOnDisk = Path.GetFileNameWithoutExtension(realPath); - return string.CompareOrdinal(shaderName, shaderNameOnDisk) == 0; - } - } - } - else - { - return fileProvider.FileExists(path); + return fileInfo.Exists; } - return false; + return fileProvider.FileExists(path); } private Stream OpenStream(string path) @@ -307,44 +294,6 @@ private Stream OpenStream(string path) return fileProvider.OpenStream(path, VirtualFileMode.Open, VirtualFileAccess.Read, VirtualFileShare.Read); } - [DllImport("kernel32.dll", EntryPoint = "GetLongPathNameW", SetLastError = true, CharSet = CharSet.Unicode)] - static extern uint GetLongPathName(string shortPath, StringBuilder sb, int buffer); - - [DllImport("kernel32.dll", EntryPoint = "GetShortPathNameW", SetLastError = true, CharSet = CharSet.Unicode)] - static extern uint GetShortPathName(string longpath, StringBuilder sb, int buffer); - - private static string GetWindowsPhysicalPath(string path) - { - var builder = new StringBuilder(255); - - // names with long extension can cause the short name to be actually larger than - // the long name. - GetShortPathName(path, builder, builder.Capacity); - - path = builder.ToString(); - - uint result = GetLongPathName(path, builder, builder.Capacity); - - if (result > 0 && result < builder.Capacity) - { - //Success retrieved long file name - builder[0] = char.ToLower(builder[0]); - return builder.ToString(0, (int)result); - } - - if (result > 0) - { - //Need more capacity in the buffer - //specified in the result variable - builder = new StringBuilder((int)result); - result = GetLongPathName(path, builder, builder.Capacity); - builder[0] = char.ToLower(builder[0]); - return builder.ToString(0, (int)result); - } - - return null; - } - public struct ShaderSourceWithHash { public string Path; diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs index 745cb5749a..9e7a938d7c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -36,7 +36,6 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) var result = new List<(string RealName, string TranslatedName, ExecutionModel ExecutionModel)>(); EntryPoint* entry_points = null; nuint num_entry_points = 0; - bool entryPointFound = false; cross.CompilerGetEntryPoints(compiler, &entry_points, &num_entry_points); for (int i = 0; i < (int)num_entry_points; ++i) { @@ -102,7 +101,7 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam for (uint i = 0; i < resourcesCount; ++i) { var resource = resourcesList[i]; - var cbufferName = Marshal.PtrToStringAnsi((IntPtr)resource.Name); + var cbufferName = Marshal.PtrToStringAnsi((IntPtr)resource.Name)!; if (cbufferName.StartsWith("type.")) { cbufferName = cbufferName.Substring("type.".Length); diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 70d8d886e9..33c72f92a2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -8,6 +8,7 @@ true --auto-module-initializer enable + enable $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@InstallationFolder) diff --git a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs index 3d8bb5492f..4d6032a760 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectCodeWriter.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Parsing.SDFX.AST; @@ -13,9 +14,7 @@ public class EffectCodeWriter : ShaderWriter private readonly List<(string Message, TextLocation Location)> logging = new(); private Stack contextStack = new(); - private Dictionary blockContexts = new(); - private BlockStatement currentBlock; - private SymbolTable table = new(new()) { ResolveArraySizes = false, ResolveExternalTypes = false }; + private SymbolTable table = new(new(), null!) { ResolveArraySizes = false, ResolveExternalTypes = false }; private bool isProcessingColor = false; @@ -88,13 +87,11 @@ public override void VisitShaderStruct(ShaderStruct shaderStruct) protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Identifier name, Expression? initialValue, List attributes) { isProcessingColor = attributes.OfType().Any(x => x.Name == "Color"); - var isArray = false; - var variableType = attributes.OfType().Where(x => x.Name == "Type").Select(x => ((StringLiteral)x.Parameters[0]).Value).FirstOrDefault(); var variableMap = attributes.OfType().Where(x => x.Name == "Map").Select(x => ((StringLiteral)x.Parameters[0]).Value).FirstOrDefault(); typeName.ProcessSymbol(table); - var type = typeName.Type; + var type = typeName.Type!; // ParameterKey shouldn't contain only the underlying type in case of arrays (we use slots) var parameterType = type; @@ -140,7 +137,7 @@ protected void WriteVariableAsParameterKey(bool isSdfx, TypeName typeName, Ident Write(">("); if (initialValue != null) { - var initialValueString = initialValue.ToString(); + var initialValueString = initialValue.ToString()!; if (initialValueString != "null") { @@ -205,7 +202,7 @@ public override void VisitShaderEffect(ShaderEffect shaderEffect) // Generate the main generate method for each shader block WriteLine("public void Generate(ShaderMixinSource mixin, ShaderMixinContext context)"); { - VisitNode(shaderEffect.Block); + VisitNode(shaderEffect.Block!); } WriteLine(); @@ -325,7 +322,7 @@ public override void VisitAccessorChainExpression(AccessorChainExpression access } } - private bool TryParameters(Expression expression, out string type, out string member, out string? extraPath) + private bool TryParameters(Expression expression, [MaybeNullWhen(false)] out string type, [MaybeNullWhen(false)] out string member, out string? extraPath) { type = null; member = null; @@ -334,7 +331,7 @@ private bool TryParameters(Expression expression, out string type, out string me if (accessorChainExpression == null || accessorChainExpression.Accessors[0] is not IdentifierBase accessMember) return false; - var name = accessorChainExpression.Source.ToString(); + var name = accessorChainExpression.Source.ToString()!; bool foundDeclaredParameters = false; if (IsParameterDeclaredInContext(name)) @@ -409,7 +406,7 @@ public override void VisitTypeName(TypeName typeName) } else if (VectorType.Types.TryGetValue(typeName.Name, out var v2) && v2 is { BaseType.Type: Scalar.Int or Scalar.UInt }) { - Write($"Int{v.Size}"); + Write($"Int{v2.Size}"); } else if (MatrixType.Types.TryGetValue(typeName.Name, out var m) && m is { Columns: 4, Rows: 4, BaseType.Type: Scalar.Float }) { @@ -700,8 +697,6 @@ private class ShaderBlockContext /// private sealed class ShaderBlockVisitor : NodeWalker { - private ShaderBlockContext currentContext; - private readonly EffectCodeWriter parent; public ShaderBlockVisitor(EffectCodeWriter parent) diff --git a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs index a4e32df759..87057feb02 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs @@ -2,6 +2,7 @@ using System.Security.Cryptography; using System.Text; using Microsoft.CodeAnalysis; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Stride.Shaders.Parsing.SDFX; @@ -24,7 +25,7 @@ private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, Addition try { - var preprocessedText = MonoGamePreProcessor.Run(arg2.GetText().ToString(), arg2.Path); + var preprocessedText = MonoGamePreProcessor.Run(arg2.GetText()?.ToString() ?? throw new InvalidOperationException($"Could not read file content for {arg2.Path}"), arg2.Path); var parsed = SDSLParser.Parse(preprocessedText); if (parsed.Errors.Count > 0) { @@ -34,6 +35,11 @@ private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, Addition arg1.AddSource(filename, sb.ToString()); return; } + else if (parsed.AST == null) + { + arg1.AddSource(filename, "#error No AST parsed"); + return; + } var effectCodeWriter = new EffectCodeWriter(); effectCodeWriter.Run(parsed.AST); diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs index 258cacb35f..c4748977f8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/Symbol.cs @@ -50,7 +50,7 @@ public record struct ExternalConstant(ConstantExpression Expression); /// Defines a symbol. /// /// Only used for specific such as -public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, ShaderDefinition? OwnerType = null) +public record Symbol(SymbolID Id, SymbolType Type, int IdRef, int? AccessChain = null, SymbolType? MemberAccessWithImplicitThis = null, ImmutableArray GroupMembers = default, MethodSymbolDefaultParameters? MethodDefaultParameters = null, ExternalConstant? ExternalConstant = null, ShaderDefinition? OwnerType = null) { public int IdRef { get; set; } = IdRef; public SymbolType Type { get; set; } = Type; diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs index 6c93951cf9..fb65b05c6c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolFrame.cs @@ -1,6 +1,7 @@ using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Xml.Linq; @@ -47,7 +48,7 @@ public void Remove(string name) => symbols.Remove(name); public bool ContainsKey(string name) => symbols.ContainsKey(name); public bool ContainsValue(Symbol symbol) => symbols.ContainsValue(symbol); - public bool TryGetValue(string name, out Symbol symbol) + public bool TryGetValue(string name, [MaybeNullWhen(false)] out Symbol symbol) { if (symbols.TryGetValue(name, out symbol)) return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs index 64cd794460..0e554aeb0b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.Visitors.cs @@ -41,7 +41,9 @@ public abstract partial class TypeVisitor { public virtual TResult DefaultVisit(SymbolType node) { - return default; + if (default(TResult) is null) + return default!; + throw new NotImplementedException($"{GetType().Name}.{nameof(DefaultVisit)} must be overridden for non-nullable TResult ({typeof(TResult).Name})"); } public virtual bool DefaultVisit(ref T item) where T : struct, ISymbolTypeItem diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index ec32efea81..dba0245b5a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -55,14 +55,13 @@ public static bool TryGetBufferType(string name, TypeName? templateTypeName, [Ma { case "StructuredBuffer": case "RWStructuredBuffer": - var templateType = templateTypeName!.Type; - result = new StructuredBufferType(templateType, name.StartsWith("RW")); + result = new StructuredBufferType(templateTypeName!.Type!, name.StartsWith("RW")); return true; case "AppendStructuredBuffer": - result = new AppendStructuredBufferType(templateTypeName!.Type); + result = new AppendStructuredBufferType(templateTypeName!.Type!); return true; case "ConsumeStructuredBuffer": - result = new ConsumeStructuredBufferType(templateTypeName!.Type); + result = new ConsumeStructuredBufferType(templateTypeName!.Type!); return true; } @@ -70,7 +69,7 @@ public static bool TryGetBufferType(string name, TypeName? templateTypeName, [Ma // Preserves the full vector/scalar type (e.g. float2 stays float2). Defaults to float4 when no template given (HLSL default). static SymbolType ResolveReturnType(TypeName? templateTypeName) - => templateTypeName == null ? new VectorType(ScalarType.Float, 4) : templateTypeName.Type; + => templateTypeName == null ? new VectorType(ScalarType.Float, 4) : templateTypeName.Type!; // Returns only the scalar element type — required for OpTypeImage sampled type and intrinsic base-type matching. static ScalarType ResolveScalarType(TypeName? templateTypeName) @@ -80,6 +79,7 @@ static ScalarType ResolveScalarType(TypeName? templateTypeName) { VectorType v => v.BaseType, ScalarType s => s, + _ => throw new NotSupportedException($"Unsupported template type {templateType} for scalar resolution"), }; } @@ -608,7 +608,7 @@ public static Symbol ImportSymbol(SymbolTable table, SpirvContext context, Symbo /// /// /// - internal bool TryResolveSymbol(int id, out Symbol symbol) + internal bool TryResolveSymbol(int id, [MaybeNullWhen(false)] out Symbol symbol) { if (TryResolveSymbolNoRecursion(id, out symbol)) return true; @@ -630,7 +630,7 @@ internal bool TryResolveSymbol(int id, out Symbol symbol) /// /// /// - internal bool TryResolveSymbol(string name, out Symbol symbol) + internal bool TryResolveSymbol(string name, [MaybeNullWhen(false)] out Symbol symbol) { if (TryResolveSymbolNoRecursion(name, out symbol)) return true; @@ -644,7 +644,7 @@ internal bool TryResolveSymbol(string name, out Symbol symbol) return false; } - private bool TryResolveSymbolNoRecursion(int id, out Symbol symbol) + private bool TryResolveSymbolNoRecursion(int id, [MaybeNullWhen(false)] out Symbol symbol) { var methods = CollectionsMarshal.AsSpan(Methods); foreach (ref var c in methods) @@ -670,18 +670,19 @@ private bool TryResolveSymbolNoRecursion(int id, out Symbol symbol) return false; } - private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) + private bool TryResolveSymbolNoRecursion(string name, [MaybeNullWhen(false)] out Symbol symbol) { symbol = default; - var found = BuildMethodGroup(name, ref symbol); - if (found) + TryBuildMethodGroup(name, ref symbol); + if (symbol != null) { // If any method is found, let's process inherited classes too: we need all method groups to find proper override foreach (var inheritedClass in InheritedShaders) { - inheritedClass.BuildMethodGroup(name, ref symbol); + inheritedClass.TryBuildMethodGroup(name, ref symbol!); } + return true; } @@ -733,7 +734,7 @@ private bool TryResolveSymbolNoRecursion(string name, out Symbol symbol) return false; } - private bool BuildMethodGroup(string name, ref Symbol symbol) + private bool TryBuildMethodGroup(string name, ref Symbol? symbol) { var found = false; var methods = CollectionsMarshal.AsSpan(Methods); @@ -753,6 +754,7 @@ private bool BuildMethodGroup(string name, ref Symbol symbol) FunctionType => new Symbol(new(name, SymbolKind.MethodGroup, IsStage: symbol.Id.IsStage), new FunctionGroupType(), 0, GroupMembers: [symbol, methodSymbol]), // Third time and later: complete method group FunctionGroupType => symbol with { GroupMembers = symbol.GroupMembers.Add(methodSymbol) }, + _ => throw new NotSupportedException($"Unexpected symbol type {symbol?.Type} when building method group for '{name}'"), }; found = true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index 7f9bffc569..e453dc1ace 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -62,22 +62,23 @@ public partial class SymbolTable : ISymbolProvider // Only valid during compilation (not during ShaderMixin phase) public ShaderDefinition? CurrentShader { get; set; } - public List CurrentMacros { get; set; } + public List CurrentMacros { get; set; } = new(); // Only valid during compilation (not during ShaderMixin phase) - public List InheritedShaders { get; set; } + public List InheritedShaders { get; } = new(); - public SymbolTable(SpirvContext context) + public SymbolTable(SpirvContext context, IExternalShaderLoader shaderLoader) { Context = context; RootSymbols = new(); Push(RootSymbols); + ShaderLoader = shaderLoader; } public void Push() => CurrentSymbols.Add(new()); public void Push(SymbolFrame symbolFrame) => CurrentSymbols.Add(symbolFrame); - public IExternalShaderLoader ShaderLoader { get; set; } + public IExternalShaderLoader ShaderLoader { get; } public SymbolFrame Pop() { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs index 7ba2b60ce9..0b7e9762d1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/IParser.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing; @@ -23,6 +24,6 @@ public interface IParser : IParser /// The error to use in case of a parse error /// Type of the scanner /// - public bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) + public bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs index 5f8bcf11fd..4909276abd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/PreProcessing/MacroPreProcessor.cs @@ -9,7 +9,7 @@ public static string OpenAndRun(string filepath, params ReadOnlySpan<(string Nam { return Run(File.ReadAllText(filepath), Path.GetFileName(filepath), defines); } - public static string Run(string content, string filename, params ReadOnlySpan<(string Name, string Definition)> defines) + public static string Run(string content, string? filename, params ReadOnlySpan<(string Name, string Definition)> defines) { var cpp = new Preprocessor(); cpp.addFeature(Feature.DIGRAPHS); @@ -28,7 +28,8 @@ public static string Run(string content, string filename, params ReadOnlySpan<(s } } } - var inputSource = new StringLexerSource(content, true, filename); + // Note: CppNet is compiled in this project but doesn't support nullable + var inputSource = new StringLexerSource(content, true, filename!); cpp.addInput(inputSource); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs index a6686f7349..7e8834281d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/AST/Effect.cs @@ -14,17 +14,17 @@ public partial class ShaderEffect(TypeName name, bool isPartial, TextLocation in { public TypeName Name { get; set; } = name; - public BlockStatement Block { get; set; } + public BlockStatement? Block { get; set; } public bool IsPartial { get; set; } = isPartial; - public override string ToString() => Block.ToString(); + public override string ToString() => Block?.ToString() ?? "(empty)"; public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; builder.Insert(new OpEffectSDFX(Name.Name)); - Block.Compile(table, compiler); + Block?.Compile(table, compiler); } internal static ConstantExpression[] CompileGenerics(SymbolTable table, SpirvContext context, ShaderExpressionList? generics) @@ -34,7 +34,7 @@ internal static ConstantExpression[] CompileGenerics(SymbolTable table, SpirvCon if (genericCount > 0) { int genericIndex = 0; - foreach (var generic in generics) + foreach (var generic in generics!) { if (generic is not Literal literal) throw new InvalidOperationException($"Generic value {generic} is not a literal"); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs index 4f87daf482..9cb33bb8d4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectParser.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Parsing.SDSL.AST; @@ -7,7 +8,7 @@ namespace Stride.Shaders.Parsing.SDFX; public record struct EffectParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -33,6 +34,6 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Effect(ref TScanner scanner, ParseResult result, out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Effect(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderEffect parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectParser().Match(ref scanner, result, out parsed, orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs index 12ba2d6e50..3c14541c2e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/EffectStatementParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDFX.AST; using Stride.Shaders.Parsing.SDSL; @@ -10,7 +11,7 @@ namespace Stride.Shaders.Parsing.SDFX; public record struct EffectStatementParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (EffectBlock(ref scanner, result, out var block)) @@ -59,23 +60,23 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Statement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new EffectStatementParsers().Match(ref scanner, result, out parsed, orError); - public static bool UsingParams(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool UsingParams(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingParamsParser().Match(ref scanner, result, out parsed, orError); - public static bool Mixin(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Mixin(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MixinParser().Match(ref scanner, result, out parsed, orError); - public static bool EffectBlock(ref TScanner scanner, ParseResult result, out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool EffectBlock(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out BlockStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Tokens.Char('{', ref scanner, advance: true)) { List statements = []; - while (SDSL.Parsers.FollowedByDel(ref scanner, result, Statement, out Statement statement, withSpaces: true, advance: true)) + while (SDSL.Parsers.FollowedByDel(ref scanner, result, Statement, out Statement? statement, withSpaces: true, advance: true)) { - statements.Add(statement); + statements.Add(statement!); } if (!SDSL.Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); @@ -84,7 +85,7 @@ public static bool EffectBlock(ref TScanner scanner, ParseResult resul } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool ShaderSourceDeclaration(ref TScanner scanner, ParseResult result, out ShaderSourceDeclaration parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool ShaderSourceDeclaration(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderSourceDeclaration parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( @@ -104,7 +105,7 @@ public static bool ShaderSourceDeclaration(ref TScanner scanner, Parse public record struct UsingParamsParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out UsingParams parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (SDSL.Parsers.SequenceOf(ref scanner, ["using", "params"], advance: true)) @@ -122,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct MixinParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Mixin parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; var mixinType = Specification.MixinKindSDFX.Default; @@ -165,7 +166,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs index 77174fe826..13e2c91dae 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDFX/Parsers/ParamsParsers.cs @@ -1,12 +1,13 @@ -using Stride.Shaders.Parsing.SDSL; +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDFX.AST; +using Stride.Shaders.Parsing.SDSL; namespace Stride.Shaders.Parsing.SDFX; public record struct ParamsParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Tokens.Literal("params", ref scanner, advance: true) && SDSL.Parsers.Spaces1(ref scanner, result, out _)) @@ -29,7 +30,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else - SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0012, scanner[scanner.Position], scanner.Memory)); + return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0012, scanner[scanner.Position], scanner.Memory)); SDSL.Parsers.Spaces0(ref scanner, result, out _); } } @@ -37,15 +38,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } return SDSL.Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Params(ref TScanner scanner, ParseResult result, out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Params(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out EffectParameters parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParamsParsers().Match(ref scanner, result, out parsed, orError); - public static bool Parameter(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Parameter(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParameterParser().Match(ref scanner, result, out parsed, orError); } public record struct ParameterParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out EffectParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index e1706bef0d..76ebd0a3a1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -8,6 +8,7 @@ using Stride.Shaders.Spirv.Core.Buffers; using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Text; using static Stride.Shaders.Spirv.Specification; @@ -110,10 +111,11 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) AssignOperator.AND => Core.Operator.AND, AssignOperator.OR => Core.Operator.OR, AssignOperator.XOR => Core.Operator.XOR, + _ => throw new NotSupportedException($"Unsupported compound assignment operator {Operator}"), }; var left = builder.AsValue(context, targetVal); - source = builder.BinaryOperation(table, context, left, binaryOperator, source, info); + source = builder.BinaryOperation(table, context, left, binaryOperator, source, Info); } var resultType = targetVal.GetValueType(context); @@ -148,7 +150,7 @@ public partial class MethodCall(Identifier name, ShaderExpressionList arguments, public SymbolType? MemberCallBaseType { get; set; } public SpirvValue? MemberCall { get; set; } - public Symbol ResolvedFunctionSymbol { get; set; } + public Symbol? ResolvedFunctionSymbol { get; set; } private IIntrinsicCompiler? resolvedIntrinsicCompiler; private string? resolvedIntrinsicNamespace; @@ -158,9 +160,9 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { ProcessParameterSymbols(table); - var argumentTypes = new SymbolType[arguments.Values.Count]; - for (int i = 0; i < arguments.Values.Count; ++i) - argumentTypes[i] = arguments.Values[i].Type; + var argumentTypes = new SymbolType[Arguments.Values.Count]; + for (int i = 0; i < Arguments.Values.Count; ++i) + argumentTypes[i] = Arguments.Values[i].Type!; if (TryResolveFunctionSymbol(table, argumentTypes, out var functionSymbol)) { @@ -169,7 +171,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = } else { - if (IntrinsicCallHelper.TryResolveIntrinsic(table, MemberCallBaseType, name, argumentTypes, out var resolvedIntrinsic)) + if (IntrinsicCallHelper.TryResolveIntrinsic(table, MemberCallBaseType, Name, argumentTypes, out var resolvedIntrinsic)) { resolvedIntrinsicCompiler = resolvedIntrinsic.Compiler; resolvedIntrinsicNamespace = resolvedIntrinsic.Namespace; @@ -178,7 +180,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = } else { - table.AddError(new(info, $"Can't find a valid method overload or intrinsic to call for {name}({string.Join(", ", arguments)})")); + table.AddError(new(Info, $"Can't find a valid method overload or intrinsic to call for {Name}({string.Join(", ", Arguments)})")); } } @@ -199,8 +201,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - var functionSymbol = resolvedIntrinsicOverload != null ? null : ShaderDefinition.ImportSymbol(table, context, ResolvedFunctionSymbol); - var functionType = resolvedIntrinsicOverload != null ? resolvedIntrinsicOverload.Value.Type : (FunctionType)functionSymbol.Type; + var functionSymbol = resolvedIntrinsicOverload != null ? null : ShaderDefinition.ImportSymbol(table, context, ResolvedFunctionSymbol!); + var functionType = resolvedIntrinsicOverload != null ? resolvedIntrinsicOverload.Value.Type : (FunctionType)functionSymbol!.Type; Span compiledParams = stackalloc int[functionType.ParameterTypes.Count]; @@ -213,10 +215,13 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) SpirvValue? @this = MemberCall != null ? (MemberCallBaseType is ByteAddressBufferType ? MemberCall.Value : builder.AsValue(context, MemberCall.Value)) : null; - result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler, resolvedIntrinsicNamespace, name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams); + result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler!, resolvedIntrinsicNamespace!, Name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams); } else { + if (functionSymbol is null) + throw new InvalidOperationException(); + int? instance = null; if (MemberCall != null) { @@ -254,7 +259,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Self: mark current function builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; } - table.AddWarning(new(info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage method '{calleeOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + table.AddWarning(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage method '{calleeOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); } result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); @@ -269,10 +274,10 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F { var (builder, context) = compiler; - if (arguments.Values.Count > functionType.ParameterTypes.Count) - throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); + if (Arguments.Values.Count > functionType.ParameterTypes.Count) + throw new InvalidOperationException($"Function {Name} was called with {Arguments.Values.Count} arguments but only {functionType.ParameterTypes.Count} expected"); - for (int i = 0; i < arguments.Values.Count; i++) + for (int i = 0; i < Arguments.Values.Count; i++) { // Wrap param in proper pointer type (function) var paramDefinition = functionType.ParameterTypes[i]; @@ -287,9 +292,9 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F // the actual memory pointer (Workgroup, StorageBuffer, etc.). if (paramDefinition.Modifiers == ParameterModifiers.Ref) { - var paramPointer = arguments.Values[i].Compile(table, compiler); + var paramPointer = Arguments.Values[i].Compile(table, compiler); if (context.ReverseTypes[paramPointer.TypeId] is not PointerType) - table.AddError(new(arguments.Values[i].Info, + table.AddError(new(Arguments.Values[i].Info, $"'ref' parameter at index {i} requires an l-value (pointer), but got {context.ReverseTypes[paramPointer.TypeId]}")); compiledParams[i] = paramPointer.Id; } @@ -301,7 +306,7 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F if (inOutFlags != ParameterModifiers.Out) { - var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + var paramSource = Arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); // Convert type (if necessary) var paramExpectedValueType = paramDefinition.Type; @@ -320,14 +325,14 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F if ((inOutFlags & ParameterModifiers.Out) != 0) throw new InvalidOperationException($"Function {Name} has an out parameter at index {i} but it's not a pointer type"); - var paramSource = arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); + var paramSource = Arguments.Values[i].CompileAsValue(table, compiler, paramDefinition.Type.GetValueType()); paramSource = builder.Convert(context, paramSource, paramDefinition.Type); compiledParams[i] = paramSource.Id; } } // Find default parameters decoration (if any) - var missingParameters = functionType.ParameterTypes.Count - arguments.Values.Count; + var missingParameters = functionType.ParameterTypes.Count - Arguments.Values.Count; var defaultParameters = 0; if (missingParameters > 0 && methodDefaultParameters is { } methodDefaultParametersValue) { @@ -337,7 +342,7 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F // Import missing parameters for (int i = 0; i < missingParameters; ++i) { - var paramDefinition = functionType.ParameterTypes[arguments.Values.Count + i]; + var paramDefinition = functionType.ParameterTypes[Arguments.Values.Count + i]; var expr = methodDefaultParametersValue.DefaultValues[^(missingParameters - i)]; var source = expr.Emit(context); @@ -346,28 +351,28 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F builder.AddFunctionVariable(context.GetOrRegister(paramDefinition.Type), paramVariable); builder.Insert(new OpStore(paramVariable, source, null, [])); - compiledParams[arguments.Values.Count + i] = paramVariable; + compiledParams[Arguments.Values.Count + i] = paramVariable; } missingParameters = 0; } } if (missingParameters > 0) - throw new InvalidOperationException($"Function {Name} was called with {arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected (methodDefaultParameters={(methodDefaultParameters == null ? "null" : $"[{string.Join(",", methodDefaultParameters.Value.DefaultValues)}]({methodDefaultParameters.Value.DefaultValues.Length} values)")}, missing={missingParameters})"); + throw new InvalidOperationException($"Function {Name} was called with {Arguments.Values.Count} arguments but there was {(defaultParameters > 0 ? $"between {functionType.ParameterTypes.Count - defaultParameters} and {functionType.ParameterTypes.Count}" : functionType.ParameterTypes.Count)} expected (methodDefaultParameters={(methodDefaultParameters == null ? "null" : $"[{string.Join(",", methodDefaultParameters.Value.DefaultValues)}]({methodDefaultParameters.Value.DefaultValues.Length} values)")}, missing={missingParameters})"); } protected void ProcessOutputArguments(SymbolTable table, CompilerUnit compiler, FunctionType functionType, Span compiledParams) { var (builder, context) = compiler; - for (int i = 0; i < arguments.Values.Count; i++) + for (int i = 0; i < Arguments.Values.Count; i++) { var paramDefinition = functionType.ParameterTypes[i]; if (paramDefinition.Modifiers.HasFlag(ParameterModifiers.Out)) { var paramDefinitionType = (PointerType)paramDefinition.Type; var paramVariable = compiledParams[i]; - var paramTarget = arguments.Values[i].Compile(table, compiler, paramDefinitionType); + var paramTarget = Arguments.Values[i].Compile(table, compiler, paramDefinitionType); var paramTargetType = (PointerType)context.ReverseTypes[paramTarget.TypeId]; if (paramTargetType.BaseType != paramDefinitionType.BaseType) @@ -413,7 +418,7 @@ public static int OverloadScore(FunctionType functionType, int defaultParameters return score; } - private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTypes, out Symbol functionSymbol) + private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTypes, [MaybeNullWhen(false)] out Symbol functionSymbol) { // Note: for now, TypeId 0 is used for this/base; let's improve that later if (MemberCallBaseType is ShaderSymbol shaderSym && table.ResolveShader(shaderSym) is { } loadedShaderSymbol) @@ -421,7 +426,7 @@ private bool TryResolveFunctionSymbol(SymbolTable table, SymbolType[] argumentTy if (!loadedShaderSymbol.TryResolveSymbol(Name, out functionSymbol)) { functionSymbol = default; - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0109, Name))); + table.AddError(new(Info, string.Format(SDSLErrorMessages.SDSL0109, Name))); return false; } } @@ -451,19 +456,19 @@ static string FormatSignature(string name, FunctionType ft) if (accessibleMethods.Count == 0) { - var callStr = FormatSignature(Name, new FunctionType(null, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); + var callStr = FormatSignature(Name, new FunctionType(ScalarType.Void, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); var candidatesStr = string.Join("\n ", functionSymbol.GroupMembers.Select(x => FormatSignature(Name, (FunctionType)x.Type))); - table.AddError(new(info, $"Can't find a valid method overload for '{callStr}'. Candidates:\n {candidatesStr}")); + table.AddError(new(Info, $"Can't find a valid method overload for '{callStr}'. Candidates:\n {candidatesStr}")); return false; } // Check if there is an ambiguous call (multiple method groups with the lowest score) if (accessibleMethods.Count > 1 && accessibleMethods[0].Key.Score == accessibleMethods[1].Key.Score) { - var callStr = FormatSignature(Name, new FunctionType(null, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); + var callStr = FormatSignature(Name, new FunctionType(ScalarType.Void, [.. argumentTypes.Select(t => new FunctionParameter(t, ParameterModifiers.None))])); var ambiguousStr = string.Join("\n ", accessibleMethods.Where(g => g.Key.Score == accessibleMethods[0].Key.Score) .SelectMany(g => g).Select(x => $"{FormatSignature(Name, (FunctionType)x.Symbol.Type)} [score: {x.Score}]")); - table.AddError(new(info, $"Ambiguous method overload for '{callStr}'. Matching candidates:\n {ambiguousStr}")); + table.AddError(new(Info, $"Ambiguous method overload for '{callStr}'. Matching candidates:\n {ambiguousStr}")); return false; } @@ -499,11 +504,11 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = case Operator.BitwiseNot: case Operator.Plus: case Operator.Minus: - expression.ProcessSymbol(table, expectedType); - Type = expression.ValueType; + Expression.ProcessSymbol(table, expectedType); + Type = Expression.ValueType; break; default: - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0111, $"Prefix operator {Operator}"))); + table.AddError(new(Info, string.Format(SDSLErrorMessages.SDSL0111, $"Prefix operator {Operator}"))); break; } } @@ -542,7 +547,8 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { Operator.Inc => Operator.Plus, Operator.Dec => Operator.Minus, - }, constant1, info); + _ => throw new NotSupportedException($"Unsupported prefix operator {Operator}"), + }, constant1, Info); // We store the modified value back in the variable builder.Insert(new OpStore(expression.Id, result.Id, null, [])); @@ -567,6 +573,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var elementType when elementType.IsFloating() => builder.InsertData(new OpFNegate(valueExpression.TypeId, context.Bound++, valueExpression.Id)), var elementType when elementType.IsInteger() => builder.InsertData(new OpSNegate(valueExpression.TypeId, context.Bound++, valueExpression.Id)), + _ => throw new NotSupportedException($"Unsupported type {valueType} for unary minus operator"), }; Type = valueType; return new(result); @@ -607,7 +614,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; TypeName.ProcessSymbol(table); - var castType = TypeName.Type; + var castType = TypeName.Type!; var value = Expression.CompileAsValue(table, compiler); Type = castType; @@ -658,7 +665,7 @@ public partial class AccessorChainExpression(Expression source, TextLocation inf public Expression Source { get; set; } = source; public List Accessors { get; set; } = []; - private SpirvValue[] intermediateValues; + private SpirvValue[]? intermediateValues; public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvValue rvalue) { @@ -672,12 +679,13 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal // - Swizzles // Process from end + Span shuffleBuffer = stackalloc int[4]; // max vector size for (var i = Accessors.Count - 1; i >= 0; --i) { var accessor = Accessors[i]; var currentValueType = i > 0 ? Accessors[i - 1].Type : Source.Type; var resultValueType = Accessors[i].Type; - var lvalueBase = intermediateValues[1 + i - 1]; + var lvalueBase = intermediateValues![1 + i - 1]; var lvalueResult = intermediateValues[1 + i]; // if lvalue is a pointer, we can simply assign to it @@ -732,7 +740,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal switch (lvalueType) { case VectorType v: - Span shuffleIndices = stackalloc int[v.Size]; + var shuffleIndices = shuffleBuffer[..v.Size]; // Default: lvalue for (int j = 0; j < v.Size; ++j) shuffleIndices[j] = j; @@ -753,7 +761,7 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal if (Source.Type is PointerType expectedType2) { rvalue = builder.Convert(context, rvalue, expectedType2.BaseType); - builder.Insert(new OpStore(intermediateValues[0].Id, rvalue.Id, null, [])); + builder.Insert(new OpStore(intermediateValues![0].Id, rvalue.Id, null, [])); return; } @@ -777,19 +785,15 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Since there are many switch case, we do both ProcessSymbols and Compile in the same functions to make sure to not miss anything (depending on if compiler is set) public SpirvValue CompileHelper(SymbolTable table, CompilerUnit? compiler = null) { + SpirvValue result = default; if (compiler != null) { if (intermediateValues != null) return intermediateValues[^1]; intermediateValues = new SpirvValue[Accessors.Count + 1]; - } - SpirvValue result = default; - - if (compiler != null) - { result = Source.Compile(table, compiler); - intermediateValues[0] = result; + intermediateValues![0] = result; } else { @@ -817,7 +821,7 @@ void EmitOpAccessChain(Span accessChainIds, int? intermediateValueIndex) result = new SpirvValue(accessChain.ResultId, resultType); if (intermediateValueIndex != null) - intermediateValues[1 + intermediateValueIndex.Value] = result; + intermediateValues![1 + intermediateValueIndex.Value] = result; } accessChainIdCount = 0; @@ -837,6 +841,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { ScalarType s => (1, s), VectorType v => (v.Size, v.BaseType), + _ => throw new NotSupportedException($"Unsupported type {vectorOrScalarType} for swizzle coalescing"), }; var swizzleIndices = new int[swizzle1.Length]; @@ -870,6 +875,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // Some accessors push up to 2 values on the stack Span accessChainIds = stackalloc int[Accessors.Count * 2]; + Span swizzleBuffer = stackalloc int[4]; // max swizzle length for (var i = 0; i < Accessors.Count; ++i) { @@ -1030,7 +1036,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { if (!s.TryResolveSymbol(field.Name, out var matchingComponent)) { - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0112, field.Name, new AccessorChainExpression(Source, info) { Accessors = Accessors[0..i] }, currentValueType))); + table.AddError(new(Info, string.Format(SDSLErrorMessages.SDSL0112, field.Name, new AccessorChainExpression(Source, Info) { Accessors = Accessors[0..i] }, currentValueType))); return default; } @@ -1040,7 +1046,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso } var (builder, context) = compiler; - var importedVariable = ShaderDefinition.ImportSymbol(table, context, field.ResolvedSymbol); + var importedVariable = ShaderDefinition.ImportSymbol(table, context, field.ResolvedSymbol!); // Emit OpAccessChain with everything so far EmitOpAccessChain(accessChainIds, i - 1); @@ -1054,7 +1060,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { streamVar.AllowStreamVariables = true; streamVar.ProcessSymbol(table); - accessor.Type = (PointerType)streamVar.Type with { StorageClass = p.StorageClass }; + accessor.Type = (PointerType)streamVar.Type! with { StorageClass = p.StorageClass }; break; } @@ -1064,14 +1070,14 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso EmitOpAccessChain(accessChainIds, i - 1); // Since we cheated a bit by overwriting the accessor.Type, set it back during Compile() - accessor.Type = (PointerType)accessor.Type with { StorageClass = Specification.StorageClass.Private }; + accessor.Type = (PointerType)accessor.Type! with { StorageClass = Specification.StorageClass.Private }; // Since STREAMS struct is built later for each shader, we simply make a reference to variable for now var streamVariableResult = streamVar.Compile(table, compiler); - accessor.Type = (PointerType)accessor.Type with { StorageClass = p.StorageClass }; + accessor.Type = (PointerType)accessor.Type! with { StorageClass = p.StorageClass }; PushAccessChainId(accessChainIds, streamVariableResult.Id); // For same reason as before (we want easy to detect pattern for StreamAccessPatcher), emit again - currentValueType = accessor.Type; + currentValueType = accessor.Type!; EmitOpAccessChain(accessChainIds, i); break; case (PointerType { BaseType: StructType s } p, Identifier field): @@ -1080,7 +1086,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { if (index == -1) { - table.AddError(new(info, string.Format(SDSLErrorMessages.SDSL0113, field.Name, currentValueType))); + table.AddError(new(Info, string.Format(SDSLErrorMessages.SDSL0113, field.Name, currentValueType))); return default; } @@ -1099,7 +1105,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { if (swizzles.Count > 4) { - table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + table.AddError(new(Info, $"more than four positions are referenced in matrix to vector swizzle")); return default; } @@ -1133,7 +1139,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { if (swizzles.Count > 4) { - table.AddError(new(info, $"more than four positions are referenced in matrix to vector swizzle")); + table.AddError(new(Info, $"more than four positions are referenced in matrix to vector swizzle")); return default; } @@ -1159,7 +1165,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(v), context.Bound++, result.Id, null, []))); - Span swizzleIndices = stackalloc int[swizzle.Length]; + var swizzleIndices = swizzleBuffer[..swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); @@ -1190,7 +1196,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } - Span swizzleIndices = stackalloc int[swizzle.Length]; + var swizzleIndices = swizzleBuffer[..swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); @@ -1217,7 +1223,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso EmitOpAccessChain(accessChainIds, i - 1); result = new(builder.InsertData(new OpLoad(context.GetOrRegister(s), context.Bound++, result.Id, null, []))); - Span swizzleIndices = stackalloc int[swizzle.Length]; + var swizzleIndices = swizzleBuffer[..swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); @@ -1249,7 +1255,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso break; } - Span swizzleIndices = stackalloc int[swizzle.Length]; + var swizzleIndices = swizzleBuffer[..swizzle.Length]; for (int j = 0; j < swizzle.Length; ++j) { swizzleIndices[j] = ConvertSwizzle(swizzle[j]); @@ -1296,6 +1302,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { MatrixType m => new VectorType(m.BaseType, m.Rows), VectorType v => v.BaseType, + _ => throw new NotSupportedException($"Unsupported base type {p.BaseType} for indexer"), }, p.StorageClass); break; } @@ -1316,6 +1323,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso MatrixType m => new VectorType(m.BaseType, m.Rows), VectorType v => v.BaseType, ArrayType a => a.BaseType, + _ => throw new NotSupportedException($"Unsupported type {currentValueType} for non-pointer indexer"), }, Specification.StorageClass.Function); break; } @@ -1365,7 +1373,8 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { Operator.Inc => Operator.Plus, Operator.Dec => Operator.Minus, - }, constant1, info); + _ => throw new NotSupportedException($"Unsupported postfix operator {postfix.Operator}"), + }, constant1, Info); // We store the modified value back in the variable builder.Insert(new OpStore(resultPointer.Id, modifiedValue.Id, null, [])); @@ -1376,10 +1385,10 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso throw new NotImplementedException($"unknown accessor {accessor} on type {currentValueType} in expression {this}"); } - currentValueType = accessor.Type; + currentValueType = accessor.Type!; // only if OpAccessChain is emitted (otherwise there is no value) if (compiler != null && accessChainIdCount == 0) - intermediateValues[1 + i] = result; + intermediateValues![1 + i] = result; } if (compiler != null) @@ -1464,7 +1473,7 @@ public partial class BinaryExpression(Expression left, Operator op, Expression r public Expression Left { get; set; } = left; public Expression Right { get; set; } = right; - private SymbolType expectedOperandType; + private SymbolType? expectedOperandType; public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { @@ -1478,15 +1487,15 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = Left.ProcessSymbol(table, expectedOperandType); Right.ProcessSymbol(table, expectedOperandType); - var analysisResult = SpirvBuilder.AnalyzeBinaryOperation(table, Left.ValueType, Op, Right.ValueType, info); + var analysisResult = SpirvBuilder.AnalyzeBinaryOperation(table, Left.ValueType!, Op, Right.ValueType!, Info); // If type is different than expected, try again with proper type // this will help in some cases (i.e. emit literal as float instead of integer, which is necessary for constants) - expectedOperandType = analysisResult?.OperandType; - if (Left.ValueType != expectedOperandType) - Left.ProcessSymbol(table, expectedOperandType); - if (Right.ValueType != expectedOperandType) - Right.ProcessSymbol(table, expectedOperandType); + this.expectedOperandType = analysisResult?.OperandType; + if (Left.ValueType != this.expectedOperandType) + Left.ProcessSymbol(table, this.expectedOperandType); + if (Right.ValueType != this.expectedOperandType) + Right.ProcessSymbol(table, this.expectedOperandType); Type = analysisResult?.ResultType; } @@ -1497,7 +1506,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var right = Right.CompileAsValue(table, compiler, expectedOperandType); var (builder, context) = compiler; - var result = builder.BinaryOperation(table, context, left, Op, right, info); + var result = builder.BinaryOperation(table, context, left, Op, right, Info); Type = context.ReverseTypes[result.TypeId]; return result; } @@ -1518,13 +1527,13 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { Condition.ProcessSymbol(table); - if (Condition.ValueType.GetElementType() is not ScalarType) + if (Condition.ValueType!.GetElementType() is not ScalarType) table.AddError(new(Condition.Info, SDSLErrorMessages.SDSL0106)); Left.ProcessSymbol(table); Right.ProcessSymbol(table); - var scalarType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(Left.ValueType.GetElementType(), Right.ValueType.GetElementType()); + var scalarType = SpirvBuilder.FindCommonBaseTypeForBinaryOperation(Left.ValueType!.GetElementType(), Right.ValueType!.GetElementType()); Type = (Condition.ValueType, Left.ValueType, Right.ValueType) switch { // If condition is a vector, we need to use this vector size instead @@ -1533,6 +1542,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = (ScalarType c, VectorType v1, ScalarType s2) => v1.WithElementType(scalarType), (ScalarType c, ScalarType s1, VectorType v2) => v2.WithElementType(scalarType), (ScalarType c, VectorType v1, VectorType v2) => new VectorType(scalarType, Math.Min(v1.Size, v2.Size)), + _ => throw new NotSupportedException($"Unsupported ternary operand types: condition={Condition.ValueType}, left={Left.ValueType}, right={Right.ValueType}"), }; } @@ -1556,7 +1566,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) if (isBranching) { var resultVariable = context.Bound++; - builder.AddFunctionVariable(context.GetOrRegister(new PointerType(Type, Specification.StorageClass.Function)), resultVariable); + builder.AddFunctionVariable(context.GetOrRegister(new PointerType(Type!, Specification.StorageClass.Function)), resultVariable); var blockMergeId = context.Bound++; var blockTrueId = context.Bound++; @@ -1569,14 +1579,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Block when choosing left value builder.CreateBlock(context, blockTrueId, $"ternary_true"); var leftResult = Left.CompileAsValue(table, compiler); - leftResult = builder.Convert(context, leftResult, Type); + leftResult = builder.Convert(context, leftResult, Type!); builder.Insert(new OpStore(resultVariable, leftResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); // Block when choosing right value builder.CreateBlock(context, blockFalseId, $"ternary_false"); var rightResult = Right.CompileAsValue(table, compiler); - rightResult = builder.Convert(context, rightResult, Type); + rightResult = builder.Convert(context, rightResult, Type!); builder.Insert(new OpStore(resultVariable, rightResult.Id, null, [])); builder.Insert(new OpBranch(blockMergeId)); @@ -1592,14 +1602,14 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) } else if (Condition.ValueType is VectorType condVec2 && (Type is not VectorType resultVec || resultVec.Size != condVec2.Size)) { - table.AddError(new(info, $"Ternary condition is {Condition.ValueType} but result type is {Type}; vector sizes must match")); + table.AddError(new(Info, $"Ternary condition is {Condition.ValueType} but result type is {Type}; vector sizes must match")); return default; } var leftResult = Left.CompileAsValue(table, compiler); - leftResult = builder.Convert(context, leftResult, Type); + leftResult = builder.Convert(context, leftResult, Type!); var rightResult = Right.CompileAsValue(table, compiler); - rightResult = builder.Convert(context, rightResult, Type); + rightResult = builder.Convert(context, rightResult, Type!); var result = builder.Insert(new OpSelect(context.GetOrRegister(Type), context.Bound++, conditionValue.Id, leftResult.Id, rightResult.Id)); return new(result.ResultId, result.ResultType); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index e4122a6cb6..a389a4b4ab 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -92,6 +92,9 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na if (bestOverloadScore == int.MaxValue) return false; + if (intrinsicCompiler == null) + return false; + resolvedIntrinsic = (intrinsicCompiler, templateExpander.Namespace, bestOverload); return true; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index a638f60c3c..e5bcfd7cd3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -19,7 +19,7 @@ internal class IntrinsicImplementations : IntrinsicsDeclarations public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue? d = null, SpirvValue? x = null, SpirvValue? y = null) { if (d == null && y == null) - return CompileBitcastCall(context, builder, functionType, x.Value); + return CompileBitcastCall(context, builder, functionType, x!.Value); throw new NotImplementedException(); } @@ -94,6 +94,7 @@ public override SpirvValue CompileAbs(SpirvContext context, SpirvBuilder builder { ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), ScalarType { Type: Scalar.UInt or Scalar.Int } => builder.InsertData(new GLSLSAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + _ => throw new NotSupportedException($"Unsupported element type for abs: {context.ReverseTypes[x.TypeId].GetElementType()}"), }; return new(instruction); } @@ -107,6 +108,7 @@ public override SpirvValue CompileMin(SpirvContext context, SpirvBuilder builder ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + _ => throw new NotSupportedException($"Unsupported element type for min: {context.ReverseTypes[a.TypeId].GetElementType()}"), }; return new(instruction); } @@ -118,6 +120,7 @@ public override SpirvValue CompileMax(SpirvContext context, SpirvBuilder builder ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMax(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)), + _ => throw new NotSupportedException($"Unsupported element type for max: {context.ReverseTypes[a.TypeId].GetElementType()}"), }; return new(instruction); } @@ -129,6 +132,7 @@ public override SpirvValue CompileClamp(SpirvContext context, SpirvBuilder build ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, min.Id, max.Id)), + _ => throw new NotSupportedException($"Unsupported element type for clamp: {context.ReverseTypes[x.TypeId].GetElementType()}"), }; return new(instruction); } @@ -194,6 +198,7 @@ public override SpirvValue CompileMul(SpirvContext context, SpirvBuilder builder //float2x3 = OpTypeMatrix vec3 x2 = MatrixType(Rows: 3, Columns: 2) // mul(float2x4,float4x3) => float2x3 (MatrixType type1, MatrixType type2) when type1.Rows == type2.Columns => builder.InsertData(new OpMatrixTimesMatrix(context.GetOrRegister(new MatrixType(type1.BaseType, type2.Rows, type1.Columns)), context.Bound++, b.Id, a.Id)), + _ => throw new NotSupportedException($"Unsupported mul operand types: {context.ReverseTypes[a.TypeId]} and {context.ReverseTypes[b.TypeId]}"), }; return new SpirvValue(result); @@ -231,6 +236,7 @@ public override SpirvValue CompileSaturate(SpirvContext context, SpirvBuilder bu ScalarType { Type: Scalar.Float } => builder.InsertData(new GLSLFClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSClamp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, constant0.Id, constant1.Id)), + _ => throw new NotSupportedException($"Unsupported element type for saturate: {functionType.ReturnType.GetElementType()}"), }; return new(instruction); } @@ -241,6 +247,7 @@ public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builde { ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFSign(x.TypeId, context.Bound++, context.GetGLSL(), x.Id)), ScalarType { Type: Scalar.UInt or Scalar.Int or Scalar.UInt64 or Scalar.Int64 } => builder.InsertData(new GLSLSSign(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)), + _ => throw new NotSupportedException($"Unsupported element type for sign: {sourceType.GetElementType()}"), }; // FSign return float whereas HLSL sign() expects int return builder.Convert(context, new(instruction), functionType.ReturnType); @@ -633,7 +640,7 @@ public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuild context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, context.CompileConstant((int)Specification.MemorySemanticsMask.Relaxed).Id, - compare.Value.Id, + compare!.Value.Id, value.Id)); originalValue = new SpirvValue(instruction.ResultId, instruction.ResultType); } @@ -653,6 +660,7 @@ public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuild InterlockedOp.Max => s.IsSigned() ? Specification.Op.OpAtomicSMax : Specification.Op.OpAtomicUMax, InterlockedOp.Min => s.IsSigned() ? Specification.Op.OpAtomicSMin : Specification.Op.OpAtomicUMin, InterlockedOp.Exchange => Specification.Op.OpAtomicExchange, + _ => throw new NotSupportedException($"Unsupported interlocked operation: {op}"), }); originalValue = new SpirvValue(instruction.ResultId, instruction.ResultType); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs index be29cd490e..04969bcb41 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicTemplateExpander.cs @@ -40,7 +40,7 @@ public IEnumerable Generate() record SizePermutation(int Size, SizePermutationGenerator Generator); record BaseTypePermutation(SymbolType Type, BaseTypePermutationGenerator Generator); - record struct SizeValue(int Value, SizePermutationGenerator Generator); + record struct SizeValue(int Value, SizePermutationGenerator? Generator); public record struct IntrinsicOverload(FunctionType Type, List<(int SourceArgument, int TemplateIndex)>? AutoMatrixLoopLocations, int AutoMatrixLoopSize); Dictionary> intrinsicDefinitionsCache = new(); @@ -68,7 +68,7 @@ public bool TryGetOrGenerateIntrinsicsDefinition(string name, [MaybeNullWhen(fal void AddVectorSizePermutation(int argument, int templateIndex, string name) { - SizePermutationGenerator permutation; + SizePermutationGenerator? permutation; // name can be either a value (1,2,3,4,any) or a name (when multiple slots adjusted with same permutation, in which case value is [1,2,3,4]). switch (name) @@ -80,6 +80,7 @@ void AddVectorSizePermutation(int argument, int templateIndex, string name) "2" => [2], "3" => [3], "4" => [4], + _ => throw new NotSupportedException($"Unsupported size permutation value '{name}'"), }, new()); sizePermutationGenerators.Add(permutation); break; @@ -287,6 +288,7 @@ ParameterTypeInfo GetParameterInfo(int index) AppendStructuredBufferType b => new(b.BaseType, new(1, null), default), ConsumeStructuredBufferType b => new(b.BaseType, new(1, null), default), StructuredBufferType b => new(b.BaseType, new(1, null), default), + _ => throw new NotSupportedException($"Unsupported this-type {thisType} for parameter info"), }; } if (index == -3) @@ -328,9 +330,7 @@ ParameterTypeInfo GetParameterInfo(int index) firstIteration = false; - List? autoMatrixLoopArguments = null; SizePermutationGenerator? autoMatrixLoop = null; - FunctionType? autoMatrixLoopType = null; int autoMatrixLoopSize = 0; // Generate real types using sizes @@ -340,14 +340,14 @@ ParameterTypeInfo GetParameterInfo(int index) if (resolvedBaseType.Size1.Value > 1 && resolvedBaseType.Size2.Value > 1) { - if (resolvedBaseType.Size1.Generator.Name == null || resolvedBaseType.Size1.Generator.Name.StartsWith("__any")) + if (resolvedBaseType.Size1.Generator is { } gen1 && (gen1.Name == null || gen1.Name.StartsWith("__any"))) { // If matrix types are generated from a <> size generator (without a specific row/column pattern like in mul()), // we can automatically convert a call to multiple calls on each inner vector. // So we try to remember this info here - if (autoMatrixLoop != null && autoMatrixLoop != resolvedBaseType.Size1.Generator) + if (autoMatrixLoop != null && autoMatrixLoop != gen1) throw new InvalidOperationException("Multiple matrix with different generators"); - autoMatrixLoop = resolvedBaseType.Size1.Generator; + autoMatrixLoop = gen1; autoMatrixLoopSize = resolvedBaseType.Size1.Value; } parameterTypes[index] = new MatrixType((ScalarType)resolvedBaseType.BaseType, resolvedBaseType.Size2.Value, resolvedBaseType.Size1.Value); @@ -381,6 +381,7 @@ ParameterTypeInfo GetParameterInfo(int index) Qualifier.InOut => ParameterModifiers.InOut, Qualifier.Ref => ParameterModifiers.Ref, null => ParameterModifiers.None, + _ => throw new NotSupportedException($"Unsupported qualifier value: {intrinsicDefinition.Parameters[i].Qualifier}"), }; // Wrap out/inout/ref parameters in PointerType, matching user-defined function convention diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index acd22e27c6..628253a2a6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -94,7 +94,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // If expectedType is float, handle it: if (Type is ScalarType { Type: Scalar.Float }) { - return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), value, null, info)); + return compiler.Context.CompileConstantLiteral(new FloatLiteral(new(32, true, true), Value, null, Info)); } return compiler.Context.CompileConstantLiteral(this); @@ -158,7 +158,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; var value = Value.CompileAsValue(table, compiler); - return builder.Convert(context, value, Type); + return builder.Convert(context, value, Type!); } } @@ -169,7 +169,7 @@ public abstract class CompositeLiteral(TextLocation info) : ValueLiteral(info) public bool IsConstant() { foreach (var v in Values) - if (v is not NumberLiteral or BoolLiteral) + if (v is not (NumberLiteral or BoolLiteral)) return false; return true; } @@ -183,6 +183,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) VectorType v => (v.Size, v.Size, v.BaseType), MatrixType m => (m.Columns, m.Columns * m.Rows, m.BaseType), ArrayType t => (t.Size, t.Size, t.BaseType), + _ => throw new NotSupportedException($"Unsupported composite type {Type}"), }; Span values = stackalloc int[totalCount]; @@ -201,14 +202,15 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // We expand elements, because float4 can be created from (float, float2, float), or (float2x2) if (Type is ScalarType or VectorType or MatrixType) { - var sourceElementType = valueType.GetElementType(); - for (int j = 0; j < valueType.GetElementCount(); ++j) + var sourceElementType = valueType!.GetElementType(); + for (int j = 0; j < valueType!.GetElementCount(); ++j) { SpirvValue extractedValue = valueType switch { MatrixType m => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j / m.Columns, j % m.Rows]))), VectorType v => new(builder.InsertData(new OpCompositeExtract(context.GetOrRegister(sourceElementType), context.Bound++, value.Id, [j]))), ScalarType s => value, + _ => throw new NotSupportedException($"Unsupported element type {valueType} in composite extraction"), }; // If too many elments, keep counting so that exception is still thrown a bit later, with total count var currentElementIndex = elementIndex++; @@ -243,6 +245,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) MatrixType m => builder.Insert(new OpCompositeConstruct(context.GetOrRegister(new VectorType(m.BaseType, compositeSize)), context.Bound++, [.. values.Slice(i * compositeSize, compositeSize)])).ResultId, VectorType v => values[i], ArrayType => values[i], + _ => throw new NotSupportedException($"Unsupported composite type {Type} during regrouping"), }; } @@ -257,14 +260,14 @@ public partial class VectorLiteral(TypeName typeName, TextLocation info) : Compo public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { TypeName.ProcessSymbol(table); - var elementType = TypeName.Type.GetElementType(); + var elementType = TypeName.Type!.GetElementType(); foreach (var value in Values) { value.ProcessSymbol(table); - if (value.Type is not PointerType && value.Type.GetElementType() != elementType) + if (value.Type is not PointerType && value.Type!.GetElementType() != elementType) { - var expectedTypeForItem = value.Type.WithElementType(elementType); + var expectedTypeForItem = value.Type!.WithElementType(elementType); value.ProcessSymbol(table, expectedTypeForItem); } } @@ -289,14 +292,14 @@ public partial class MatrixLiteral(TypeName typeName, int rows, int cols, TextLo public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { TypeName.ProcessSymbol(table); - var elementType = TypeName.Type.GetElementType(); + var elementType = TypeName.Type!.GetElementType(); foreach (var value in Values) { value.ProcessSymbol(table); - if (value.Type is not PointerType && value.ValueType.GetElementType() != elementType) + if (value.Type is not PointerType && value.ValueType!.GetElementType() != elementType) { - var expectedTypeForItem = value.Type.WithElementType(elementType); + var expectedTypeForItem = value.Type!.WithElementType(elementType); value.ProcessSymbol(table, expectedTypeForItem); } } @@ -332,7 +335,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = return; if (Type == null && Values.Count > 0) - Type = new ArrayType(Values[0].ValueType, Values.Count); + Type = new ArrayType(Values[0].ValueType!, Values.Count); if (Type != null) { @@ -341,7 +344,7 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = } else { - table.AddError(new(info, "Can't figure out type of array")); + table.AddError(new(Info, "Can't figure out type of array")); return; } @@ -361,7 +364,7 @@ public abstract partial class IdentifierBase(string name, TextLocation info) : L { public string Name { get; set; } = name; - public Symbol ResolvedSymbol { get; set; } + public Symbol? ResolvedSymbol { get; set; } public static SpirvValue EmitSymbol(SpirvBuilder builder, SpirvContext context, Symbol symbol, bool constantOnly, int? instance = null) { @@ -415,8 +418,11 @@ public override void SetValue(SymbolTable table, CompilerUnit compiler, SpirvVal var target = CompileSymbol(table, builder, context, false); if (Type is not PointerType) + { // Throw exception (default behavior) base.SetValue(table, compiler, rvalue); + return; + } rvalue = builder.Convert(context, rvalue, ((PointerType)Type).BaseType); builder.Insert(new OpStore(target.Id, rvalue.Id, null, [])); @@ -431,6 +437,9 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder builder, SpirvContext context, bool constantOnly) { + if (ResolvedSymbol is null) + throw new InvalidOperationException($"{this} could not resolve symbol"); + var symbol = ShaderDefinition.ImportSymbol(table, context, ResolvedSymbol); // Track when a stage method accesses a non-stage variable (without composition qualifier). @@ -454,7 +463,7 @@ protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder build { builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; } - table.AddWarning(new(info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage variable '{varOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + table.AddWarning(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage variable '{varOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); } return EmitSymbol(builder, context, symbol, constantOnly); @@ -477,13 +486,13 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = { if (!table.TryResolveSymbol(Name, out var symbol)) { - symbol = GenericIdentifier.ResolveExternalShader(table, table.Context, info, Name, null); + symbol = GenericIdentifier.ResolveExternalShader(table, table.Context, Info, Name, null); } if (symbol != null) { if (symbol.Id.Storage == Storage.Stream && !AllowStreamVariables) - table.AddError(new(info, $"Streams member {Name} used without an object")); + table.AddError(new(Info, $"Streams member {Name} used without an object")); ResolvedSymbol = symbol; Type = symbol.Type; @@ -600,14 +609,14 @@ static bool TryParseOne(ReadOnlySpan token, int cols, int rows, out (int C public partial class GenericIdentifier(Identifier name, ShaderExpressionList? generics, TextLocation info) : IdentifierBase(name, info) { - public Identifier Name { get; } = name; + public new Identifier Name { get; } = name; public ShaderExpressionList? Generics { get; } = generics; public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = null) { var context = table.Context; - var symbol = ResolveExternalShader(table, context, info, Name, Generics); + var symbol = ResolveExternalShader(table, context, Info, Name, Generics); if (symbol != null) { @@ -643,13 +652,14 @@ public override void ProcessSymbol(SymbolTable table, SymbolType? expectedType = classSource = SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, classSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); for (int i = inheritedShaderCount; i < table.InheritedShaders.Count; ++i) { - table.InheritedShaders[i].Symbol = ShaderClass.LoadAndCacheExternalShaderType(table, context, table.InheritedShaders[i]); - ShaderClass.Inherit(table, context, table.InheritedShaders[i].Symbol, false); + var shaderDefinition = ShaderClass.LoadAndCacheExternalShaderDefinition(table, context, table.InheritedShaders[i]); + table.InheritedShaders[i].Symbol = shaderDefinition; + ShaderClass.Inherit(table, context, shaderDefinition, false); } // We add the typename as a symbol (similar to static access in C#) - var shaderId = context.GetOrImportShader(classSource.Symbol); - symbol = new Symbol(new(classSource.Symbol.Name, SymbolKind.Shader), new PointerType(new ShaderSymbol(classSource.Symbol.Name, classSource.Symbol.GenericArguments), Specification.StorageClass.Private), shaderId); + var shaderId = context.GetOrImportShader(classSource.Symbol!); + symbol = new Symbol(new(classSource.Symbol!.Name, SymbolKind.Shader), new PointerType(new ShaderSymbol(classSource.Symbol.Name, classSource.Symbol.GenericArguments), Specification.StorageClass.Private), shaderId); table.CurrentFrame.Add(classSource.ToClassNameWithGenerics(), symbol); } @@ -715,6 +725,7 @@ or nameof(Specification.StreamsKindSDSL.Constants)) "PointStream" => Specification.GeometryStreamOutputKindSDSL.Point, "LineStream" => Specification.GeometryStreamOutputKindSDSL.Line, "TriangleStream" => Specification.GeometryStreamOutputKindSDSL.Triangle, + _ => throw new NotSupportedException($"Unsupported geometry stream type '{Name}'"), }); } else if (Name == "InputPatch" || Name == "OutputPatch") @@ -723,6 +734,7 @@ or nameof(Specification.StreamsKindSDSL.Constants)) { "InputPatch" => Specification.PatchTypeKindSDSL.Input, "OutputPatch" => Specification.PatchTypeKindSDSL.Output, + _ => throw new NotSupportedException($"Unsupported patch type '{Name}'"), }, ((NumberLiteral)Generics[1]).IntValue); } else if (SymbolType.TryGetNumeric(Name, out var numeric)) @@ -797,7 +809,7 @@ protected SymbolType ResolveType(SymbolTable table, SpirvContext context) { if (!table.ResolveExternalTypes) { - return new ExternalType(name, null); + return new ExternalType(Name, null); } throw new InvalidOperationException($"Could not resolve type [{Name}]"); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index b5835704e7..95ab44d13e 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -1,3 +1,7 @@ +using System; +using System.Reflection; +using System.Reflection.Metadata; +using System.Runtime.InteropServices; using CommunityToolkit.HighPerformance; using CommunityToolkit.HighPerformance.Buffers; using Stride.Shaders.Core; @@ -8,10 +12,7 @@ using Stride.Shaders.Spirv.Core; using Stride.Shaders.Spirv.Core.Buffers; using Stride.Shaders.Spirv.Tools; -using System; -using System.Reflection; -using System.Reflection.Metadata; -using System.Runtime.InteropServices; +using static Stride.Core.Storage.BundleOdbBackend; using static Stride.Shaders.Spirv.Specification; namespace Stride.Shaders.Parsing.SDSL.AST; @@ -90,22 +91,7 @@ void RegisterName(int target, string name) context.Names.TryAdd(target, name); } - static SymbolType? ParseReturnType(string s) => s switch - { - "float" => ScalarType.Float, - "float2" => new VectorType(ScalarType.Float, 2), - "float3" => new VectorType(ScalarType.Float, 3), - "float4" => new VectorType(ScalarType.Float, 4), - "int" => ScalarType.Int, - "int2" => new VectorType(ScalarType.Int, 2), - "int3" => new VectorType(ScalarType.Int, 3), - "int4" => new VectorType(ScalarType.Int, 4), - "uint" => ScalarType.UInt, - "uint2" => new VectorType(ScalarType.UInt, 2), - "uint3" => new VectorType(ScalarType.UInt, 3), - "uint4" => new VectorType(ScalarType.UInt, 4), - _ => null, - }; + var realShaderImporter = shaderImporter ?? new EmptyShaderImporter(); var importedShaders = new Dictionary(); @@ -154,6 +140,7 @@ void RegisterName(int target, string name) (32, false) => ScalarType.UInt, (64, true) => ScalarType.Int64, (64, false) => ScalarType.UInt64, + _ => throw new NotSupportedException($"Unsupported integer type: width={intInstruction.Width}, signed={intInstruction.Signedness == 1}"), }); } else if (instruction.Op == Op.OpTypeBool) @@ -388,7 +375,7 @@ private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext // Load all the inherited shaders List inheritedShaderSymbols = new(); foreach (var inheritedClass in inheritanceList) - inheritedShaderSymbols.Add(LoadAndCacheExternalShaderType(table, context, inheritedClass)); + inheritedShaderSymbols.Add(LoadAndCacheExternalShaderDefinition(table, context, inheritedClass)); var shaderType = new ShaderDefinition(classSource.ClassName, classSource.GenericArguments) { @@ -428,7 +415,7 @@ private static ShaderDefinition CreateShaderType(SymbolTable table, SpirvContext { if (!shaderBuffers.Context.GetBuffer().TryGetInstructionById(target2, out var typeInstruction)) throw new InvalidOperationException(); - var resultType = typeInstruction.Data.IdResultType.Value; + var resultType = typeInstruction.Data.IdResultType!.Value; var constExpr = ConstantExpression.ParseFromBuffer(target2, shaderBuffers.Context.GetBuffer(), shaderBuffers.Context); var symbol = new Symbol(new(constName, SymbolKind.Constant), shaderBuffers.Context.ReverseTypes[resultType], 0, ExternalConstant: new(constExpr), OwnerType: shaderType); variables.Add((symbol, VariableFlagsMask.None)); @@ -483,7 +470,7 @@ private static void RegisterShaderType(SymbolTable table, ShaderDefinition shade public void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - builder.Insert(new OpShaderSDSL(name)); + builder.Insert(new OpShaderSDSL(Name)); var openGenerics = new ConstantExpression[Generics != null ? Generics.Parameters.Count : 0]; var currentShader = new ShaderDefinition(Name, openGenerics); @@ -510,7 +497,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } - var inheritanceList = new List(); + table.InheritedShaders.Clear(); foreach (var mixin in Mixins) { var mixinGenerics = (mixin as GenericIdentifier)?.Generics; @@ -552,18 +539,17 @@ public void Compile(SymbolTable table, CompilerUnit compiler) } } var shaderClassSource = new ShaderClassInstantiation(mixin.Name, generics); - SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), inheritanceList, ResolveStep.Compile); + SpirvBuilder.BuildInheritanceListIncludingSelf(table.ShaderLoader, context, shaderClassSource, table.CurrentMacros.AsSpan(), table.InheritedShaders, ResolveStep.Compile); } RegisterShaderType(table, currentShader); table.CurrentShader = currentShader; - table.InheritedShaders = inheritanceList; var shaderSymbols = new List(); - foreach (var mixin in inheritanceList) + foreach (var mixin in table.InheritedShaders) { - shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderType(table, context, mixin)); + shaderSymbols.Add(mixin.Symbol = LoadAndCacheExternalShaderDefinition(table, context, mixin)); } foreach (var shaderType in shaderSymbols) @@ -623,7 +609,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) builder.Insert(new OpUnresolvableShaderSDSL(Info.Text.ToString(), endOfNameIndex)); } - table.InheritedShaders = null; + table.InheritedShaders.Clear(); table.CurrentShader = null; table.Pop(); } @@ -631,7 +617,7 @@ public void Compile(SymbolTable table, CompilerUnit compiler) public int ProcessGenericSymbol(SymbolTable table, SpirvContext context, int index, ShaderParameter genericParameter) { genericParameter.TypeName.ProcessSymbol(table); - var genericParameterType = genericParameter.TypeName.Type; + var genericParameterType = genericParameter.TypeName.Type!; // Wrap resource types in pointer (same as member variables) if (genericParameterType is TextureType or BufferType) @@ -695,21 +681,18 @@ public static void Inherit(SymbolTable table, SpirvContext context, ShaderDefini if (addToRoot) - table.CurrentShader.InheritedShaders.Add(shaderType); + table.CurrentShader!.InheritedShaders.Add(shaderType); // Mark inherit context.Add(new OpMixinInheritSDSL(shaderId, Spirv.Specification.MixinInheritFlagsMask.None)); } - public static ShaderDefinition LoadAndCacheExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) + public static ShaderDefinition LoadAndCacheExternalShaderDefinition(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { // Already processed? if (table.DeclaredShaders.TryGetValue(classSource.ToClassNameWithGenerics(), out var cachedShader)) return cachedShader; - if (classSource.Buffer == null) - throw new InvalidOperationException($"{nameof(classSource)}.{nameof(classSource.Buffer)} need to be set"); - var shaderType = LoadExternalShaderType(table, context, classSource); return shaderType; } @@ -731,9 +714,9 @@ public static ShaderDefinition LoadAndCacheExternalShaderType(SymbolTable table, public static ShaderDefinition LoadExternalShaderType(SymbolTable table, SpirvContext context, ShaderClassInstantiation classSource) { - var shaderBuffer = classSource.Buffer; + var shaderBuffers = classSource.Buffer ?? throw new InvalidOperationException($"Shader buffers not loaded for {classSource.ClassName}"); - var shaderType = CreateShaderType(table, context, shaderBuffer.Value, classSource); + var shaderType = CreateShaderType(table, context, shaderBuffers, classSource); RegisterShaderType(table, shaderType); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index f469c79ddc..229d1a8acd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -37,7 +37,7 @@ public partial class ShaderSamplerState(Identifier name, TextLocation info) : Me public Identifier Name { get; set; } = name; public List Parameters { get; set; } = []; - public Symbol Symbol { get; private set; } + public Symbol? Symbol { get; private set; } public override void ProcessSymbol(SymbolTable table, SpirvContext context) { @@ -47,7 +47,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var sid = new SymbolID(Name, SymbolKind.SamplerState); Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + table.CurrentShader!.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler) @@ -123,7 +123,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable.ResultId, Name); - Symbol.IdRef = variableId; + Symbol!.IdRef = variableId; RGroup.DecorateVariableLinkInfo(table, shader, context, Info, Name, Attributes, variable); } @@ -174,7 +174,7 @@ public sealed partial class ShaderMember( public StorageClass StorageClass { get; set; } = storageClass; public InterpolationModifier Interpolation { get; set; } = interpolation; - public Symbol Symbol { get; private set; } + public Symbol? Symbol { get; private set; } public override void ProcessSymbol(SymbolTable table, SpirvContext context) { @@ -188,11 +188,11 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var classSource = new ShaderClassInstantiation(TypeName.Name, []); var shader = SpirvBuilder.GetOrLoadShader(table.ShaderLoader, classSource, table.CurrentMacros.AsSpan(), ResolveStep.Compile, context); classSource.Buffer = shader; - var shaderType = ShaderClass.LoadAndCacheExternalShaderType(table, context, classSource); + var shaderType = ShaderClass.LoadAndCacheExternalShaderDefinition(table, context, classSource); // Resolve again (we don't use shaderType directly, because it might lack info such as ArrayType) TypeName.ProcessSymbol(table); - memberType = TypeName.Type; + memberType = TypeName.Type!; } if (memberType is AppendStructuredBufferType or ConsumeStructuredBufferType) @@ -245,8 +245,8 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) }, IsStage: IsStaged ); - Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + Symbol = new Symbol(sid, Type, 0, OwnerType: table.CurrentShader!); + table.CurrentShader!.Variables.Add((Symbol, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); Value?.ProcessSymbol(table, memberType); } @@ -257,7 +257,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var registeredType = context.GetOrRegister(Type); var variable = context.Bound++; - var pointerType = (PointerType)Type; + var pointerType = (PointerType)Type!; var variableFlags = IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None; if (StreamKind == StreamKind.Stream || StreamKind == StreamKind.PatchStream) @@ -300,7 +300,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler context.Add(new OpDecorateString(variable, Specification.Decoration.UserSemantic, Semantic.Name)); context.AddName(variable, Name); - Symbol.IdRef = variable; + Symbol!.IdRef = variable; if (StreamKind == StreamKind.PatchStream) context.Add(new OpDecorate(variable, Specification.Decoration.Patch, [])); @@ -382,13 +382,13 @@ public partial class ShaderMethod( public BlockStatement? Body { get; set; } - public SymbolFrame SymbolFrame { get; private set; } + public SymbolFrame? SymbolFrame { get; private set; } public List ParameterSymbols { get; private set; } = new(); public override void ProcessSymbol(SymbolTable table, SpirvContext context) { ReturnTypeName.ProcessSymbol(table); - var ftype = new FunctionType(ReturnTypeName.Type, []); + var ftype = new FunctionType(ReturnTypeName.Type!, []); function = SpirvBuilder.DeclareFunction(context, Name, ftype, IsStaged); var functionFlags = Specification.FunctionFlagsMask.None; @@ -406,7 +406,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) foreach (var p in Parameters) { p.TypeName.ProcessSymbol(table); - var argSym = p.TypeName.Type; + var argSym = p.TypeName.Type!; table.DeclaredTypes.TryAdd(argSym.ToString(), argSym); p.Type = argSym; var parameterType = GenerateParameterType(p); @@ -458,19 +458,19 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) table.DeclaredTypes.TryAdd(Type.ToString(), Type); SymbolFrame = table.Pop(); - table.CurrentShader.Methods.Add((symbol, functionFlags)); + table.CurrentShader!.Methods.Add((symbol, functionFlags)); } private static PointerType GenerateParameterType(MethodParameter p) { // Default: wrap everything in Function pointer // TODO: what happens if we want to pass texture/sampler around as parameters? - return new PointerType(p.Type, Specification.StorageClass.Function); + return new PointerType(p.Type!, Specification.StorageClass.Function); } public void ProcessSymbolBody(SymbolTable table, SpirvContext context) { - table.Push(SymbolFrame); + table.Push(SymbolFrame!); Body?.ProcessSymbol(table); table.Pop(); } @@ -481,13 +481,14 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Attributes != null) { + Span attrParamBuffer = stackalloc int[8]; // max attribute parameters foreach (var attribute in Attributes) { if (attribute is AnyShaderAttribute anyAttribute) { if (anyAttribute.Name == "numthreads") { - Span parameters = stackalloc int[anyAttribute.Parameters.Count]; + var parameters = attrParamBuffer[..anyAttribute.Parameters.Count]; for (var index = 0; index < anyAttribute.Parameters.Count; index++) { var compiled = anyAttribute.Parameters[index].CompileConstantValue(table, context); @@ -526,6 +527,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler "tri" => Specification.ExecutionMode.Triangles, "quad" => Specification.ExecutionMode.Quads, "isolined" => Specification.ExecutionMode.Isolines, + _ => throw new NotSupportedException($"Unsupported domain value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"), }, [])); } else if (anyAttribute.Name == "partitioning") @@ -536,6 +538,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler "fractional_even" => Specification.ExecutionMode.SpacingFractionalEven, "integer" => Specification.ExecutionMode.SpacingEqual, "pow2" => throw new NotSupportedException("partitioning pow2 is not supported in SPIR-V"), + _ => throw new NotSupportedException($"Unsupported partitioning value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"), }, [])); } else if (anyAttribute.Name == "outputtopology") @@ -547,6 +550,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler { "triangle_cw" => Specification.ExecutionMode.VertexOrderCw, "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw, + _ => throw new NotSupportedException($"Unsupported output topology value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"), }, [])); } } @@ -561,7 +565,7 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler if (Type is not FunctionType ftype) throw new InvalidOperationException(); - table.Push(SymbolFrame); + table.Push(SymbolFrame!); builder.BeginFunction(context, function); var functionInfo = new OpFunctionMetadataSDSL(Specification.FunctionFlagsMask.None, 0); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index f2d46ea9b4..67303b2109 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -148,6 +148,7 @@ public static ParameterModifiers ToParameterModifiers(this string str) "lineadj" => ParameterModifiers.LineAdjacency, "triangle" => ParameterModifiers.Triangle, "triangleadj" => ParameterModifiers.TriangleAdjacency, + _ => throw new NotSupportedException($"Unsupported parameter modifier '{str}'"), }; } } @@ -182,7 +183,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) foreach (var smem in Members) { smem.TypeName.ProcessSymbol(table); - smem.Type = smem.TypeName.Type; + smem.Type = smem.TypeName.Type!; table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); @@ -234,7 +235,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) { smem.TypeName.ProcessSymbol(table); smem.Type = smem.TypeName.Type; - table.DeclaredTypes.TryAdd(smem.Type.ToString(), smem.Type); + table.DeclaredTypes.TryAdd(smem.Type!.ToString(), smem.Type); fields.Add(new(smem.Name, smem.Type, smem.TypeModifier)); } @@ -260,12 +261,12 @@ public override string ToString() public sealed partial class CBuffer(string name, TextLocation info) : ShaderBuffer(name, info) { - public Symbol Symbol { get; private set; } + public Symbol? Symbol { get; private set; } private bool? isStaged; public record struct AttributeAnalysisResult(string? LinkName = null, int? LinkId = null, bool Color = false); - public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, SpirvContext context, TextLocation info, List attributes) + public static AttributeAnalysisResult ProcessAttributes(SymbolTable table, SpirvContext context, TextLocation info, List? attributes) { var result = new AttributeAnalysisResult(); if (attributes != null) @@ -328,7 +329,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) cbMember.Type = cbMember.TypeName.Type; } - var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); + var pointerType = new PointerType(Type!, Specification.StorageClass.Uniform); isStaged = null; for (var index = 0; index < Members.Count; index++) @@ -343,13 +344,13 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) throw new InvalidOperationException($"cbuffer {Name} have a mix of stage and non-stage members"); } - var constantBufferType = (ConstantBufferSymbol)Type; + var constantBufferType = (ConstantBufferSymbol)Type!; // We try to avoid clash in case multiple cbuffer TYPE with same name // The variable itself is handled by adding a .0 .1 etc. in Shader.RenameCBufferVariables() int tryCount = 0; var typeName = constantBufferType.Name; - while (!table.DeclaredTypes.TryAdd(constantBufferType.ToId(), Type)) + while (!table.DeclaredTypes.TryAdd(constantBufferType.ToId(), Type!)) { typeName = $"{typeName}_{++tryCount}"; Type = constantBufferType = constantBufferType with { Name = typeName }; @@ -359,13 +360,13 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var sid = new SymbolID(Name, SymbolKind.CBuffer, Storage.Uniform); Symbol = new Symbol(sid, pointerType, context.Bound++, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((Symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + table.CurrentShader!.Variables.Add((Symbol, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); } public override void Compile(SymbolTable table, ShaderClass shaderClass, CompilerUnit compiler) { var (builder, context) = compiler; - var variable = Symbol.IdRef; + var variable = Symbol!.IdRef; context.AddName(variable, Name); if (LogicalGroup != null) @@ -387,7 +388,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } } - var pointerType = new PointerType(Type, Specification.StorageClass.Uniform); + var pointerType = new PointerType(Type!, Specification.StorageClass.Uniform); builder.Insert(new OpVariableSDSL(context.GetOrRegister(pointerType), variable, Specification.StorageClass.Uniform, (isStaged ?? false) ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); } } @@ -415,7 +416,7 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) var type = new PointerType(member.Type, storageClass); var sid = new SymbolID(member.Name, kind, Storage.Uniform); var symbol = new Symbol(sid, type, 0, OwnerType: table.CurrentShader); - table.CurrentShader.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); + table.CurrentShader!.Variables.Add((symbol, member.IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None)); Symbols.Add(symbol); } } @@ -448,7 +449,7 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile } } - internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass shaderClass, SpirvContext context, TextLocation info, string memberName, List attributes, int variableId) + internal static void DecorateVariableLinkInfo(SymbolTable table, ShaderClass shaderClass, SpirvContext context, TextLocation info, string memberName, List? attributes, int variableId) { var attributesInfo = CBuffer.ProcessAttributes(table, context, info, attributes); if (attributesInfo.LinkId is int linkId) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs index 0c9b70aa53..6d912a6635 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.Flow.cs @@ -59,7 +59,7 @@ public partial class ForEach(TypeName typename, Identifier variable, Expression public Expression Collection { get; set; } = collection; public Statement Body { get; set; } = body; - public SymbolFrame SymbolFrame { get; set; } + public SymbolFrame? SymbolFrame { get; set; } public override void ProcessSymbol(SymbolTable table) { @@ -99,8 +99,8 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) // Since foreach need to be processed and expanded later, we use custom opcode // (we could emit a "For" loop statement, but it would be too complex to write a general decompiler for a "for" loop when processing it later) var variableId = builder.Insert(new OpForeachSDSL(context.GetOrRegister(variableType), context.Bound++, collection.Id)); - table.Push(SymbolFrame); - SymbolFrame.UpdateId(Variable.Name, variableId); + table.Push(SymbolFrame!); + SymbolFrame!.UpdateId(Variable.Name, variableId); Body.Compile(table, compiler); table.Pop(); builder.Insert(new OpForeachEndSDSL()); @@ -192,7 +192,7 @@ public partial class For(Statement initializer, Expression cond, List public Statement Body { get; set; } = body; public ShaderAttribute? Attribute = attribute; public List Annotations { get; set; } = []; - public SymbolFrame SymbolFrame { get; set; } + public SymbolFrame? SymbolFrame { get; set; } public override void ProcessSymbol(SymbolTable table) { @@ -209,7 +209,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) { var (builder, context) = compiler; - table.Push(SymbolFrame); + table.Push(SymbolFrame!); Initializer.Compile(table, compiler); // Prepare blocks ids diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index 81cf328f0d..edea62664a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -102,13 +102,16 @@ public override void ProcessSymbol(SymbolTable table) { Value?.ProcessSymbol(table); if (Value == null) + { table.Errors.Add(new(Info, "can't infer `var` type without a value")); - valueType = Value.ValueType; + return; + } + valueType = Value.ValueType!; } else { TypeName.ProcessSymbol(table); - valueType = TypeName.Type; + valueType = TypeName.Type!; Value?.ProcessSymbol(table, TypeName.Type); // If type was unsized array (e.g. int2[]) and initializer inferred the size, use that if (valueType is ArrayType { Size: -1 } && Value?.ValueType is ArrayType { Size: > 0 } inferred) @@ -161,10 +164,10 @@ public override void ProcessSymbol(SymbolTable table) for (var index = 0; index < Variables.Count; index++) { var declaration = Variables[index]; - declaration.TypeName = new TypeName(TypeName.Name, info) { ArraySize = declaration.ArraySizes }; + declaration.TypeName = new TypeName(TypeName.Name, Info) { ArraySize = declaration.ArraySizes }; declaration.ProcessSymbol(table); - var variableSymbol = new Symbol(new(declaration.Variable, SymbolKind.Variable), declaration.Type, 0, OwnerType: table.CurrentShader); + var variableSymbol = new Symbol(new(declaration.Variable, SymbolKind.Variable), declaration.Type!, 0, OwnerType: table.CurrentShader); table.CurrentFrame.Add(declaration.Variable, variableSymbol); VariableSymbols.Add(variableSymbol); } @@ -181,7 +184,7 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var d = Variables[index]; var variable = context.Bound++; - var variableType = (PointerType)d.Type; + var variableType = (PointerType)d.Type!; var variableValueType = variableType.BaseType; var variableTypeId = context.GetOrRegister(variableType); builder.AddFunctionVariable(variableTypeId, variable); @@ -214,7 +217,7 @@ public partial class BlockStatement(TextLocation info) : Statement(info) { public List Statements { get; set; } = []; - public SymbolFrame SymbolFrame; + public SymbolFrame? SymbolFrame; public override void ProcessSymbol(SymbolTable table) { @@ -226,7 +229,7 @@ public override void ProcessSymbol(SymbolTable table) public override void Compile(SymbolTable table, CompilerUnit compiler) { - table.Push(SymbolFrame); + table.Push(SymbolFrame!); var (builder, context) = compiler; foreach (var s in Statements) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs index 372e8287e2..df95c51482 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/CommonParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using Stride.Shaders.Parsing.SDSL.AST; @@ -8,7 +9,7 @@ namespace Stride.Shaders.Parsing.SDSL; public static class Parsers { - public static bool Exit(ref TScanner scanner, ParseResult result, out TNode parsed, int beginningPosition, in ParseError? orError = null) + public static bool Exit(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TNode parsed, int beginningPosition, in ParseError? orError = null) where TScanner : struct, IScanner where TNode : class { @@ -16,25 +17,25 @@ public static bool Exit(ref TScanner scanner, ParseResult resul { result.Errors.Add(orError.Value); scanner.Position = scanner.End; - parsed = null!; + parsed = null; return false; } scanner.Position = beginningPosition; - parsed = null!; + parsed = null; return false; } - public static bool Spaces0(ref TScanner scanner, ParseResult result, out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) + public static bool Spaces0(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) where TScanner : struct, IScanner => new Space0(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); - public static bool Spaces1(ref TScanner scanner, ParseResult result, out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) + public static bool Spaces1(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out NoNode node, in ParseError? orError = null, bool onlyWhiteSpace = false) where TScanner : struct, IScanner => new Space1(onlyWhiteSpace).Match(ref scanner, result, out node, in orError); - public static bool Alternatives(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null, params ReadOnlySpan> parsers) + public static bool Alternatives(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TResult parsed, in ParseError? orError = null, params ReadOnlySpan> parsers) where TScanner : struct, IScanner where TResult : Node { @@ -44,7 +45,7 @@ public static bool Alternatives(ref TScanner scanner, ParseRe return true; return Exit(ref scanner, result, out parsed, position, orError); } - public static bool Sequences(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null, bool withSPaces = false, string? separator = null, params ReadOnlySpan> parsers) + public static bool Sequences(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out List parsed, in ParseError? orError = null, bool withSPaces = false, string? separator = null, params ReadOnlySpan> parsers) where TScanner : struct, IScanner where TResult : Node { @@ -96,7 +97,7 @@ public static bool MethodModifiers(ref TScanner scanner, ParseResult r "static" ], ref scanner, - out string match, + out string? match, advance: true) && Spaces1(ref scanner, result, out _)) { @@ -155,7 +156,7 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult "columnmajor" ], ref scanner, - out string match, + out string? match, advance: true) && Spaces1(ref scanner, result, out _)) { @@ -208,7 +209,7 @@ public static bool VariableModifiers(ref TScanner scanner, ParseResult } - public static bool IdentifierArraySizeOptionalValue(ref TScanner scanner, ParseResult result, out Identifier identifier, out List arraySizes, out Expression? value, bool advance = true) + public static bool IdentifierArraySizeOptionalValue(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Identifier identifier, out List? arraySizes, [MaybeNullWhen(false)] out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; @@ -248,7 +249,7 @@ public static bool IdentifierArraySizeOptionalValue(ref TScanner scann return false; } } - public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, out TypeName typeName, out Identifier identifier, out Expression? value, bool advance = true) + public static bool TypeNameIdentifierArraySizeValue(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TypeName typeName, [MaybeNullWhen(false)] out Identifier identifier, [MaybeNullWhen(false)] out Expression? value, bool advance = true) where TScanner : struct, IScanner { var position = scanner.Position; @@ -261,7 +262,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann { var tmp = scanner.Position; Spaces0(ref scanner, result, out _); - if (FollowedByDelList(ref scanner, result, ArraySizes, out List arraySize, withSpaces: true, advance: true)) + if (FollowedByDelList(ref scanner, result, ArraySizes, out List? arraySize, withSpaces: true, advance: true)) typeName.ArraySize = arraySize; else scanner.Position = tmp; @@ -284,7 +285,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann scanner.Position = position; if ( LiteralsParser.TypeName(ref scanner, result, out typeName) - && FollowedByDelList(ref scanner, result, ArraySizes, out List sizes, withSpaces: true, advance: true) + && FollowedByDelList(ref scanner, result, ArraySizes, out List? sizes, withSpaces: true, advance: true) && Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out identifier)) { @@ -311,7 +312,7 @@ public static bool TypeNameIdentifierArraySizeValue(ref TScanner scann return false; } - public static bool ArraySizes(ref TScanner scanner, ParseResult result, out List arraySizes, in ParseError? orError = null) + public static bool ArraySizes(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out List arraySizes, in ParseError? orError = null) where TScanner : struct, IScanner { arraySizes = []; @@ -323,9 +324,9 @@ public static bool ArraySizes(ref TScanner scanner, ParseResult result { arraySizes.Add(new EmptyExpression(scanner[(scanner.Position - 1)..(scanner.Position - 1)])); } - else if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression arraySize, withSpaces: true, advance: true)) + else if (FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression? arraySize, withSpaces: true, advance: true)) { - arraySizes.Add(arraySize); + arraySizes.Add(arraySize!); if (!FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true)) return Exit(ref scanner, result, out arraySizes, scanner.Position); } @@ -368,7 +369,7 @@ public static bool FollowedBy(ref TScanner scanner, TTermin scanner.Position = position; return false; } - public static bool FollowedByAny(ref TScanner scanner, ReadOnlySpan literals, out string matched, bool withSpaces = false, bool advance = false) + public static bool FollowedByAny(ref TScanner scanner, ReadOnlySpan literals, [MaybeNullWhen(false)] out string matched, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -384,7 +385,7 @@ public static bool FollowedByAny(ref TScanner scanner, ReadOnlySpan(ref TScanner scanner, ParseResult res scanner.Position = position; return false; } - public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedByDel(ref TScanner scanner, ParseResult result, ParserDelegate func, [MaybeNullWhen(false)] out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -438,7 +439,7 @@ public static bool FollowedByDel(ref TScanner scanner, ParseR scanner.Position = position; return false; } - public static bool FollowedByDelList(ref TScanner scanner, ParseResult result, ParserListDelegate func, out List parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedByDelList(ref TScanner scanner, ParseResult result, ParserListDelegate func, [MaybeNullWhen(false)] out List parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -453,7 +454,7 @@ public static bool FollowedByDelList(ref TScanner scanner, Pa scanner.Position = position; return false; } - public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserDelegate func, out TResult parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedBy(ref TScanner scanner, ParseResult result, ParserDelegate func, [MaybeNullWhen(false)] out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner { var position = scanner.Position; @@ -469,7 +470,7 @@ public static bool FollowedBy(ref TScanner scanner, ParseResu return false; } - public static bool FollowedBy(ref TScanner scanner, TParser parser, ParseResult result, out TResult parsed, bool withSpaces = false, bool advance = false) + public static bool FollowedBy(ref TScanner scanner, TParser parser, ParseResult result, [MaybeNullWhen(false)] out TResult parsed, bool withSpaces = false, bool advance = false) where TScanner : struct, IScanner where TParser : struct, IParser where TResult : Node @@ -548,14 +549,14 @@ public static bool Until(ref Scann } - public static bool Repeat(ref TScanner scanner, TParser parser, ParseResult result, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + public static bool Repeat(ref TScanner scanner, TParser parser, ParseResult result, [MaybeNullWhen(false)] out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) where TScanner : struct, IScanner where TParser : struct, IParser where TNode : Node { - return Repeat(ref scanner, result, (ref TScanner s, ParseResult r, out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), out nodes, minimum, withSpaces, separator, orError); + return Repeat(ref scanner, result, (ref TScanner s, ParseResult r, [MaybeNullWhen(false)] out TNode node, in ParseError? orError) => new TParser().Match(ref s, r, out node, orError), out nodes, minimum, withSpaces, separator, orError); } - public static bool Repeat(ref TScanner scanner, ParseResult result, ParserDelegate parser, out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) + public static bool Repeat(ref TScanner scanner, ParseResult result, ParserDelegate parser, [MaybeNullWhen(false)] out List nodes, int minimum, bool withSpaces = false, string? separator = null, in ParseError? orError = null) where TScanner : struct, IScanner where TNode : Node { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs index 00aa74e2c4..dd4aece608 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/Delegates.cs @@ -1,11 +1,13 @@ +using System.Diagnostics.CodeAnalysis; + namespace Stride.Shaders.Parsing.SDSL; public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result) where TScanner : struct, IScanner; -public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) +public delegate bool ParserDelegate(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner; -public delegate bool ParserListDelegate(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) +public delegate bool ParserListDelegate(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out List parsed, in ParseError? orError = null) where TScanner : struct, IScanner; public delegate bool ParserOptionalDelegate(ref TScanner scanner, ParseResult result, out TResult? parsed, in ParseError? orError = null) where TScanner : struct, IScanner; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs deleted file mode 100644 index 2f54f6cfd0..0000000000 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Common/OptionalParser.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Stride.Shaders.Parsing.SDSL; - -public record struct OptionalParser(TParser Parser) : IParser - where TParser : IParser - where TResult : Node -{ - public readonly bool Match(ref TScanner scanner, ParseResult result, out TResult parsed, in ParseError? orError = null) where TScanner : struct, IScanner - { - Parser.Match(ref scanner, result, out parsed, orError); - return true; - } -} diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs index 1bb7d156ff..60fbe1d908 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveBinaryParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public struct DirectiveExpressionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (Or(ref scanner, result, out parsed)) @@ -18,37 +19,37 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } - public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Expression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveExpressionParser().Match(ref scanner, result, out parsed, in orError); - public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Add(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveAdditionParser().Match(ref scanner, result, out parsed, in orError); - public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Mul(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveMultiplicationParser().Match(ref scanner, result, out parsed, in orError); - public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Shift(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveBitwiseShiftParser().Match(ref scanner, result, out parsed, in orError); - public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Relation(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveRelationalParser().Match(ref scanner, result, out parsed, in orError); - public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Equality(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveEqualityParser().Match(ref scanner, result, out parsed, in orError); - public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool BAnd(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveBitwiseAndParser().Match(ref scanner, result, out parsed, in orError); - public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool BOr(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveBitwiseOrParser().Match(ref scanner, result, out parsed, in orError); - public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool XOr(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveBitwiseXOrParser().Match(ref scanner, result, out parsed, in orError); - public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool And(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveAndParser().Match(ref scanner, result, out parsed, in orError); - public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Or(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveOrParser().Match(ref scanner, result, out parsed, in orError); } @@ -56,7 +57,7 @@ public static bool Or(ref TScanner scanner, ParseResult result, out Ex public record struct DirectiveTernaryParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -95,7 +96,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveOrParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -144,7 +145,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveAndParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -195,7 +196,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveBitwiseOrParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -244,7 +245,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct DirectiveBitwiseXOrParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -293,7 +294,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct DirectiveBitwiseAndParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -345,7 +346,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveEqualityParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -395,7 +396,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveRelationalParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -469,7 +470,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveBitwiseShiftParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -519,7 +520,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveAdditionParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -569,7 +570,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveMultiplicationParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs index 9401451ff8..e5208bdca6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Microsoft.VisualBasic; using Stride.Shaders.Parsing.SDSL.AST; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PreprocessorParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out PreProcessableCode parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out PreProcessableCode parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -17,14 +18,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } - public static bool PreCode(ref TScanner scanner, ParseResult result, out PreProcessableCode parsed, in ParseError? orError = null) + public static bool PreCode(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out PreProcessableCode parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new PreprocessorParser().Match(ref scanner, result, out parsed, orError); } public record struct DirectiveStatementParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out DirectiveStatement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DirectiveStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -51,7 +52,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return false; } - public static bool AnyIf(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + public static bool AnyIf(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (If(ref scanner, result, out var ifDirective)) @@ -72,44 +73,44 @@ public static bool AnyIf(ref TScanner scanner, ParseResult result, out parsed = null!; return false; } - public static bool Define(ref TScanner scanner, ParseResult result, out ObjectDefineDirective parsed, in ParseError? orError = null) + public static bool Define(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ObjectDefineDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ObjectDefineDirectiveParser().Match(ref scanner, result, out parsed, orError); - public static bool DefineFunc(ref TScanner scanner, ParseResult result, out FunctionDefineDirective parsed, in ParseError? orError = null) + public static bool DefineFunc(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out FunctionDefineDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new FunctionDefineDirectiveParser().Match(ref scanner, result, out parsed, orError); - public static bool If(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + public static bool If(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalIfDirectivesParser().Match(ref scanner, result, out parsed, orError); - public static bool IfDef(ref TScanner scanner, ParseResult result, out IfDefDirective parsed, in ParseError? orError = null) + public static bool IfDef(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDefDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalIfDefDirectivesParser().Match(ref scanner, result, out parsed, orError); - public static bool IfNDef(ref TScanner scanner, ParseResult result, out IfNDefDirective parsed, in ParseError? orError = null) + public static bool IfNDef(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfNDefDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalIfNDefDirectivesParser().Match(ref scanner, result, out parsed, orError); - public static bool Elif(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + public static bool Elif(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalElifDirectivesParser().Match(ref scanner, result, out parsed, orError); public static bool Endif(ref TScanner scanner, ParseResult result, in ParseError? orError = null) where TScanner : struct, IScanner => new EndifDirectiveParser().Match(ref scanner, result, out _, orError); - public static bool Code(ref TScanner scanner, ParseResult result, out DirectiveCode parsed, in ParseError? orError = null) + public static bool Code(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DirectiveCode parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveCodeParser().Match(ref scanner, result, out parsed, orError); - public static bool Else(ref TScanner scanner, ParseResult result, out ElseDirective parsed, in ParseError? orError = null) + public static bool Else(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ElseDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalElseDirectivesParser().Match(ref scanner, result, out parsed, orError); - public static bool Conditional(ref TScanner scanner, ParseResult result, out ConditionalDirectives parsed, in ParseError? orError = null) + public static bool Conditional(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalDirectives parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ConditionalDirectivesParser().Match(ref scanner, result, out parsed, orError); - public static bool Statement(ref TScanner scanner, ParseResult result, out DirectiveStatement parsed, in ParseError? orError = null) + public static bool Statement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DirectiveStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveStatementParsers().Match(ref scanner, result, out parsed, orError); } public struct ConditionalDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalDirectives parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalDirectives parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -157,7 +158,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveCodeParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out DirectiveCode parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DirectiveCode parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -197,7 +198,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ConditionalIfDefDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDefDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDefDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -223,7 +224,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct ConditionalIfNDefDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out IfNDefDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfNDefDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -250,7 +251,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ConditionalIfDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -278,7 +279,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ConditionalElifDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out IfDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IfDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -304,7 +305,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct ConditionalElseDirectivesParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ElseDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ElseDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -329,7 +330,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct EndifDirectiveParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out NoNode parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out NoNode parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -355,7 +356,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ObjectDefineDirectiveParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ObjectDefineDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ObjectDefineDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -399,7 +400,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct FunctionDefineDirectiveParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out FunctionDefineDirective parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out FunctionDefineDirective parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs index cc572fa91b..08ad7266d5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectivePrimaryExpressionParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct DirectivePrimaryParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (Parenthesis(ref scanner, result, out parsed)) @@ -27,13 +28,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return false; } } - public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Primary(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectivePrimaryParsers().Match(ref scanner, result, out parsed, in orError); - public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier parsed) + public static bool Identifier(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Identifier parsed) where TScanner : struct, IScanner => new IdentifierParser().Match(ref scanner, result, out parsed); - public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Parenthesis(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveParenthesisExpressionParser().Match(ref scanner, result, out parsed, in orError); } @@ -41,7 +42,7 @@ public static bool Parenthesis(ref TScanner scanner, ParseResult resul public record struct DirectiveParenthesisExpressionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -66,7 +67,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveMethodCallParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs index 7f9d187595..e10e83b5e7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.Prefix.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -6,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct DirectivePrefixParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -38,7 +39,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectivePrefixIncrementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -88,7 +89,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveNotExpressionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -122,7 +123,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveSignExpressionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -158,7 +159,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DirectiveCastExpressionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs index aa5f4aa6e5..d814af6748 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/DirectiveExpressions/DirectiveUnaryParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,22 +6,22 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct DirectiveUnaryParsers { - internal static bool Not(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + internal static bool Not(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression cast, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveNotExpressionParser().Match(ref scanner, result, out cast, in orError); - internal static bool Signed(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + internal static bool Signed(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression cast, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveSignExpressionParser().Match(ref scanner, result, out cast, in orError); - internal static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + internal static bool PrefixIncrement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression cast, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectivePrefixIncrementParser().Match(ref scanner, result, out cast, in orError); - internal static bool Cast(ref TScanner scanner, ParseResult result, out Expression cast, in ParseError? orError = null) + internal static bool Cast(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression cast, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectiveCastExpressionParser().Match(ref scanner, result, out cast, in orError); - public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) + public static bool Prefix(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression prefix, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectivePrefixParser().Match(ref scanner, result, out prefix, in orError); - public static bool Primary(ref TScanner scanner, ParseResult result, out Expression postfix, in ParseError? orError = null) + public static bool Primary(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression postfix, in ParseError? orError = null) where TScanner : struct, IScanner => new DirectivePrimaryParsers().Match(ref scanner, result, out postfix, in orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs index 3a16ca6a3c..5bb2288647 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/BinaryParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -5,11 +6,11 @@ namespace Stride.Shaders.Parsing.SDSL; public struct ExpressionParser : IParser { - public static bool Expression(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Expression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ExpressionParser().Match(ref scanner, result, out parsed, in orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -22,7 +23,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o /// assignment ::= ternary ( assign_op assignment )? /// Right-associative: a = b = c parses as a = (b = c) /// - public static bool Assignment(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Assignment(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -53,7 +54,7 @@ public static bool Assignment(ref TScanner scanner, ParseResult result /// /// add ::= mul ( spaces '+' spaces add)* /// - public static bool Add(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Add(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { char op = '\0'; @@ -86,7 +87,7 @@ public static bool Add(ref TScanner scanner, ParseResult result, out E /// /// mul ::= prefix ( spaces '*' spaces mul)* /// - public static bool Mul(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Mul(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { char op = '\0'; @@ -119,22 +120,22 @@ public static bool Mul(ref TScanner scanner, ParseResult result, out E /// /// shift ::= add ( spaces ('<<' | '>>') spaces shift)* /// - public static bool Shift(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Shift(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (Add(ref scanner, result, out var add)) parsed = new BinaryExpression(parsed, op.ToOperator(), add, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (Add(ref scanner, result, out var add)) parsed = add; @@ -152,22 +153,22 @@ public static bool Shift(ref TScanner scanner, ParseResult result, out /// /// relational ::= shift ( spaces ('<=' | '>=' | '<' | '>') spaces relational)* /// - public static bool Relation(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Relation(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (Shift(ref scanner, result, out var shift)) parsed = new BinaryExpression(parsed, op.ToOperator(), shift, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (Shift(ref scanner, result, out var shift)) parsed = shift; @@ -185,22 +186,22 @@ public static bool Relation(ref TScanner scanner, ParseResult result, /// /// equality ::= relational ( spaces ('==' | '!=') spaces equality)* /// - public static bool Equality(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Equality(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (Relation(ref scanner, result, out var rel)) parsed = new BinaryExpression(parsed, op.ToOperator(), rel, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (Relation(ref scanner, result, out var rel)) parsed = rel; @@ -215,22 +216,22 @@ public static bool Equality(ref TScanner scanner, ParseResult result, /// /// band ::= equality ( spaces '&' spaces band)* /// - public static bool BAnd(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool BAnd(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (Equality(ref scanner, result, out var eq)) parsed = new BinaryExpression(parsed, op.ToOperator(), eq, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (Equality(ref scanner, result, out var eq)) parsed = eq; @@ -250,22 +251,22 @@ public static bool BAnd(ref TScanner scanner, ParseResult result, out /// bor ::= band ( spaces '|' spaces bor)* /// - public static bool BOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool BOr(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (XOr(ref scanner, result, out var xor)) parsed = new BinaryExpression(parsed, op.ToOperator(), xor, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (XOr(ref scanner, result, out var xor)) parsed = xor; @@ -284,22 +285,22 @@ public static bool BOr(ref TScanner scanner, ParseResult result, out E /// xor ::= bor ( spaces '^' spaces xor)* /// - public static bool XOr(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool XOr(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (BAnd(ref scanner, result, out var bAnd)) parsed = new BinaryExpression(parsed, op.ToOperator(), bAnd, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (BAnd(ref scanner, result, out var bAnd)) parsed = bAnd; @@ -318,22 +319,22 @@ public static bool XOr(ref TScanner scanner, ParseResult result, out E /// and ::= xor ( spaces '&&' spaces and)* /// - public static bool And(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool And(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (BOr(ref scanner, result, out var bOr)) parsed = new BinaryExpression(parsed, op.ToOperator(), bOr, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (BOr(ref scanner, result, out var bOr)) parsed = bOr; @@ -348,22 +349,22 @@ public static bool And(ref TScanner scanner, ParseResult result, out E /// /// or ::= and ( spaces '&&' spaces or)* /// - public static bool Or(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Or(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { - string op = ""; + string? op = null; parsed = null!; var position = scanner.Position; do { Parsers.Spaces0(ref scanner, result, out _); - if (op != "" && parsed is not null) + if (op is not null && parsed is not null) { if (And(ref scanner, result, out var and)) parsed = new BinaryExpression(parsed, op.ToOperator(), and, scanner[position..scanner.Position]); else return Parsers.Exit(ref scanner, result, out parsed, position); } - else if (parsed is null && op == "") + else if (parsed is null && op is null) { if (And(ref scanner, result, out var and)) parsed = and; @@ -378,7 +379,7 @@ public static bool Or(ref TScanner scanner, ParseResult result, out Ex /// /// ternary ::= or ( spaces '?' spaces expression spaces ':' spaces expression)* /// - public static bool Ternary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Ternary(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs index 00fe2b111a..59b34619d3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/PrimaryExpressionParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Security.AccessControl; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -8,12 +9,12 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PrimaryParsers : IParser { - public static bool Primary(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Primary(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new PrimaryParsers().Match(ref scanner, result, out parsed, in orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { return Parsers.Alternatives( @@ -26,7 +27,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ); } - public static bool Literal(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Literal(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -39,7 +40,7 @@ public static bool Literal(ref TScanner scanner, ParseResult result, o } - public static bool Method(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Method(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -61,7 +62,7 @@ public static bool Method(ref TScanner scanner, ParseResult result, ou return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Parenthesis(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Parenthesis(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -79,26 +80,26 @@ public static bool Parenthesis(ref TScanner scanner, ParseResult resul else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool ArrayLiteral(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( Tokens.Char('{', ref scanner, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ParameterParsers.Values, out ShaderExpressionList values, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ParameterParsers.Values, out ShaderExpressionList? values, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) ) { parsed = new ArrayLiteral(scanner[position..scanner.Position]) { - Values = values.Values + Values = values!.Values }; return true; } else return Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool IdentifierBase(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool IdentifierBase(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs index 7f56d24ddd..aee8f89362 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Postfix.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -5,11 +6,11 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PostfixParser : IParser { - public static bool Postfix(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Postfix(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new PostfixParser().Match(ref scanner, result, out parsed, in orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -22,25 +23,25 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { if ( matched == "[" - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression indexer, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression? indexer, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(']'), withSpaces: true, advance: true) ) { - ((AccessorChainExpression)parsed).Accessors.Add(new IndexerExpression(indexer, indexer.Info)); + ((AccessorChainExpression)parsed).Accessors.Add(new IndexerExpression(indexer!, indexer!.Info)); } else if ( matched == "." - && Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression call, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Method, out Expression? call, withSpaces: true, advance: true) ) { - ((AccessorChainExpression)parsed).Accessors.Add(call); + ((AccessorChainExpression)parsed).Accessors.Add(call!); } else if ( matched == "." - && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.IdentifierBase, out IdentifierBase accessor, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, LiteralsParser.IdentifierBase, out IdentifierBase? accessor, withSpaces: true, advance: true) ) { - ((AccessorChainExpression)parsed).Accessors.Add(accessor); + ((AccessorChainExpression)parsed).Accessors.Add(accessor!); } else if (matched == "++" || matched == "--") { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 007f249933..6ca6a72fb6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -6,12 +7,12 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct PrefixParser : IParser { - public static bool Prefix(ref TScanner scanner, ParseResult result, out Expression prefix, in ParseError? orError = null) + public static bool Prefix(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression prefix, in ParseError? orError = null) where TScanner : struct, IScanner => new PrefixParser().Match(ref scanner, result, out prefix, in orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { return Parsers.Alternatives( @@ -27,7 +28,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ); } - public static bool Not(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Not(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -47,7 +48,7 @@ public static bool Not(ref TScanner scanner, ParseResult result, out E else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Signed(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Signed(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -66,7 +67,7 @@ public static bool Signed(ref TScanner scanner, ParseResult result, ou return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool PrefixIncrement(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool PrefixIncrement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -95,22 +96,22 @@ public static bool PrefixIncrement(ref TScanner scanner, ParseResult r else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Cast(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool Cast(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; var s1 = Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true); if (!s1) { return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - var s2 = Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typeName, withSpaces: true, advance: true); + var s2 = Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName? typeName, withSpaces: true, advance: true); if (!s2) { scanner.Position = position; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } var s3 = Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true); if (!s3) { scanner.Position = position; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - var s4 = Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression expression, withSpaces: true, advance: true); + var s4 = Parsers.FollowedBy(ref scanner, result, PostfixParser.Postfix, out Expression? expression, withSpaces: true, advance: true); if (!s4) { scanner.Position = position; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - parsed = new CastExpression(typeName, Operator.Cast, expression, scanner[position..scanner.Position]); + parsed = new CastExpression(typeName!, Operator.Cast, expression!, scanner[position..scanner.Position]); return true; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs index 5985bcff97..34fa54595f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/LiteralParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -6,13 +7,13 @@ namespace Stride.Shaders.Parsing.SDSL; public interface ILiteralParser { - public bool Match(ref TScanner scanner, ParseResult result, out TResult literal, in ParseError? error = null) + public bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TResult literal, in ParseError? error = null) where TScanner : struct, IScanner; } public record struct LiteralsParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal literal, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -48,16 +49,16 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out literal, position, orError); } - public static bool Literal(ref TScanner scanner, ParseResult result, out Literal literal, in ParseError? orError = null) + public static bool Literal(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal literal, in ParseError? orError = null) where TScanner : struct, IScanner => new LiteralsParser().Match(ref scanner, result, out literal, in orError); - public static bool Identifier(ref TScanner scanner, ParseResult result, out Identifier identifier, in ParseError? orError = null) + public static bool Identifier(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Identifier identifier, in ParseError? orError = null) where TScanner : struct, IScanner => new IdentifierParser().Match(ref scanner, result, out identifier, orError); - public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) + public static bool GenericIdentifier(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new GenericIdentifierParser().Match(ref scanner, result, out parsed, orError); - public static bool IdentifierBase(ref TScanner scanner, ParseResult result, out IdentifierBase parsed, in ParseError? orError = null) + public static bool IdentifierBase(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out IdentifierBase parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -72,11 +73,10 @@ public static bool IdentifierBase(ref TScanner scanner, ParseResult re return true; } - parsed = default; - return Parsers.Exit(ref scanner, result, out parsed, position, orError); ; + return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool TypeNameLiteral(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -87,7 +87,7 @@ public static bool TypeNameLiteral(ref TScanner scanner, ParseResult r } else return false; } - public static bool TypeName(ref TScanner scanner, ParseResult result, out TypeName name, in ParseError? orError = null) + public static bool TypeName(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out TypeName name, in ParseError? orError = null) where TScanner : struct, IScanner { name = null!; @@ -105,11 +105,12 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, if (Parsers.FollowedBy(ref scanner, Tokens.Char('<'), withSpaces: true, advance: true)) { Parsers.Spaces0(ref scanner, result, out _); - Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List generics, 1, withSpaces: true, separator: ","); + Parsers.Repeat(ref scanner, result, TypeNameOrNumber, out List? generics, 1, withSpaces: true, separator: ","); if (!Parsers.FollowedBy(ref scanner, Tokens.Char('>'), withSpaces: true, advance: true)) return Parsers.Exit(ref scanner, result, out name, position); name.Info = scanner[position..scanner.Position]; - name.Generics = generics; + if (generics != null) + name.Generics = generics; intermediate = scanner.Position; } else @@ -117,7 +118,7 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, scanner.Position = intermediate; } - if (Parsers.FollowedByDelList(ref scanner, result, Parsers.ArraySizes, out List arraySize, withSpaces: true, advance: true)) + if (Parsers.FollowedByDelList(ref scanner, result, Parsers.ArraySizes, out List? arraySize, withSpaces: true, advance: true)) { name.Info = scanner[position..scanner.Position]; name.ArraySize = arraySize; @@ -132,7 +133,7 @@ public static bool TypeName(ref TScanner scanner, ParseResult result, else return Parsers.Exit(ref scanner, result, out name, position, orError); } - public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (TypeName(ref scanner, result, out var typename)) @@ -148,7 +149,7 @@ public static bool TypeNameOrNumber(ref TScanner scanner, ParseResult else return Parsers.Exit(ref scanner, result, out parsed, scanner.Position, orError); } - public static bool Boolean(ref TScanner scanner, ParseResult result, out BoolLiteral number, in ParseError? orError = null) + public static bool Boolean(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out BoolLiteral number, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -159,11 +160,11 @@ public static bool Boolean(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out number, scanner.Position, orError); } - public static bool Number(ref TScanner scanner, ParseResult result, out Literal number, in ParseError? orError = null) + public static bool Number(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal number, in ParseError? orError = null) where TScanner : struct, IScanner => new NumberParser().Match(ref scanner, result, out number, in orError); - public static bool Vector(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool Vector(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -206,11 +207,11 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou } else if ( Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression value, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression? value, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) ) { - parsed = new ExpressionLiteral(value, new TypeName(baseType, scanner[position..tnPos]), scanner[position..scanner.Position]); + parsed = new ExpressionLiteral(value!, new TypeName(baseType, scanner[position..tnPos]), scanner[position..scanner.Position]); return true; } else return Parsers.Exit(ref scanner, result, out parsed, position); @@ -218,14 +219,14 @@ public static bool Vector(ref TScanner scanner, ParseResult result, ou } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Matrix(ref TScanner scanner, ParseResult result, out MatrixLiteral parsed, in ParseError? orError = null) + public static bool Matrix(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out MatrixLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MatrixParser().Match(ref scanner, result, out parsed, in orError); - public static bool Integer(ref TScanner scanner, ParseResult result, out Literal number, in ParseError? orError = null) + public static bool Integer(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal number, in ParseError? orError = null) where TScanner : struct, IScanner => NumberParser.Integer(ref scanner, result, out number, in orError); - public static bool StringLiteral(ref TScanner scanner, ParseResult result, out StringLiteral parsed, in ParseError? orError = null) + public static bool StringLiteral(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out StringLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -371,10 +372,10 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct IdentifierParser() : ILiteralParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Identifier literal, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Identifier literal, in ParseError? orError = null) where TScanner : struct, IScanner { - literal = null!; + literal = null; var position = scanner.Position; if (Tokens.Char('_', ref scanner) || Tokens.Letter(ref scanner)) { @@ -395,7 +396,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct MatrixParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out MatrixLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out MatrixLiteral parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs index cc7dce21f9..0a25bf0cc9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/LiteralParsers/NumberParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; using System.Globalization; @@ -6,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDSL; public struct NumberParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { return Parsers.Alternatives( @@ -21,7 +22,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ); } - public static bool Integer(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool Integer(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -50,7 +51,7 @@ public static bool Integer(ref TScanner scanner, ParseResult result, o } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Float(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool Float(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -107,7 +108,7 @@ public static bool Float(ref TScanner scanner, ParseResult result, out parsed = new FloatLiteral(new(32, true, true), value, exponent, scanner[position..scanner.Position]); return true; } - public static bool Hex(ref TScanner scanner, ParseResult result, out Literal parsed, in ParseError? orError = null) + public static bool Hex(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Literal parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs index fc7b66af20..2640e6015d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/CompositionParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -6,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct CompositionParser() : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -23,7 +24,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0033, scanner[position], scanner.Memory)); parsed = new(name, typeName, typeName.ArraySize is { Count: > 0 }, scanner[position..]) { - Attributes = hasAttributes ? attributes.Attributes : null!, + Attributes = hasAttributes ? attributes!.Attributes : null!, IsStaged = isStaged }; return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs index f5b2a46b5c..8a81deb100 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderAttributeParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; @@ -7,7 +8,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderAttributeListParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -29,15 +30,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool AttributeList(ref TScanner scanner, ParseResult result, out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool AttributeList(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderAttributeList parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderAttributeListParser().Match(ref scanner, result, out parsed, orError); - public static bool Attribute(ref TScanner scanner, ParseResult result, out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public static bool Attribute(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new AttributeParser().Match(ref scanner, result, out parsed, orError); } public record struct AttributeParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderAttribute parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (Tokens.Char('[', ref scanner, advance: true)) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs index a225d37550..7284b6b010 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderBufferParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,11 +6,11 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct BufferParsers : IParser { - public static bool Buffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + public static bool Buffer(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new BufferParsers().Match(ref scanner, result, out parsed, orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { return Parsers.Alternatives( ref scanner, result, out parsed, in orError, @@ -19,7 +20,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ); } - public static bool TBuffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + public static bool TBuffer(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -55,7 +56,7 @@ public static bool TBuffer(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); ; } - public static bool CBuffer(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + public static bool CBuffer(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -94,7 +95,7 @@ public static bool CBuffer(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool RGroup(ref TScanner scanner, ParseResult result, out ShaderBuffer parsed, in ParseError? orError = null) + public static bool RGroup(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderBuffer parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -133,7 +134,7 @@ public static bool RGroup(ref TScanner scanner, ParseResult result, ou return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) + public static bool Member(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { Parsers.Spaces0(ref scanner, result, out _); @@ -156,17 +157,17 @@ public static bool Member(ref TScanner scanner, ParseResult result, ou { parsed = new ShaderMember(typeName, identifier, value, scanner[position..scanner.Position], isStage, streamKind); if (hasAttributes) - parsed.Attributes = attributes.Attributes; + parsed.Attributes = attributes!.Attributes; return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool BufferName(ref TScanner scanner, ParseResult result, out Identifier parsed, in ParseError? orError = null) + public static bool BufferName(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Identifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; - if (Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out List identifiers, 1, true, ".", orError)) + if (Parsers.Repeat(ref scanner, result, LiteralsParser.Identifier, out List? identifiers, 1, true, ".", orError)) { parsed = new Identifier(string.Join(".", identifiers.Select(i => i.Name)), scanner[identifiers[0].Info.Range.Start..identifiers[^1].Info.Range.End]); return true; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs index d6596e34b9..624ba3e0d9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderClassParser.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Stride.Shaders.Parsing.SDSL.AST; @@ -6,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderClassParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (ComplexClass(ref scanner, result, out parsed, in orError)) @@ -14,17 +15,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o else return false; } - public static bool Class(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public static bool Class(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParsers().Match(ref scanner, result, out parsed, in orError); - public static bool ComplexClass(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public static bool ComplexClass(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderClassParser().Match(ref scanner, result, out parsed, in orError); } public record struct SimpleShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -59,7 +60,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ShaderClassParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderClass parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderClass parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -139,7 +140,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct GenericIdentifierParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out GenericIdentifier parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (LiteralsParser.Identifier(ref scanner, result, out var typename) @@ -177,7 +178,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ShaderGenericsDefinitionParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderGenerics parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderGenerics parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs index 91f11fdc7f..70da35c98b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderDataParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Runtime; using System.Security.Cryptography.X509Certificates; using System.Text.RegularExpressions; @@ -7,11 +8,11 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderMemberParser : IParser { - public static bool Member(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) + public static bool Member(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderMemberParser().Match(ref scanner, result, out parsed, in orError); - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; var position = scanner.Position; @@ -37,7 +38,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(typeName, identifier, value, scanner[position..scanner.Position]) { Semantic = semantic, - Attributes = hasAttributes ? attributes.Attributes : null!, + Attributes = hasAttributes ? attributes!.Attributes : null!, IsStaged = isStaged, IsCompose = isCompose, Interpolation = interpolation, @@ -54,7 +55,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct ShaderStructParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( @@ -68,7 +69,8 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new ShaderStruct(identifier, scanner[position..]); Parsers.Repeat(ref scanner, new ShaderStructMemberParser(), result, out var members, 0, withSpaces: true, separator: ";"); Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); - parsed.Members = members; + if (members is not null) + parsed.Members = members; if (Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true)) { Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true); @@ -83,7 +85,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ShaderSamplerStateParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( @@ -96,7 +98,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List? assignments, 0, withSpaces: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) @@ -117,18 +119,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateParameter parsed, in ParseError? orError = null) + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SamplerStateParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier? identifier, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression? expression, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateParameter(identifier, expression, scanner[position..scanner.Position]); + parsed = new SamplerStateParameter(identifier!, expression!, scanner[position..scanner.Position]); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -137,7 +139,7 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P public record struct ShaderSamplerComparisonStateParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderSamplerComparisonState parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderSamplerComparisonState parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( @@ -150,7 +152,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if ( Parsers.FollowedBy(ref scanner, Tokens.Char('{'), withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) - && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List assignments, 0, withSpaces: true) + && Parsers.Repeat(ref scanner, result, SamplerStateValueAssignment, out List? assignments, 0, withSpaces: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('}'), withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) @@ -171,18 +173,18 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, out SamplerStateParameter parsed, in ParseError? orError = null) + public static bool SamplerStateValueAssignment(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SamplerStateParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if ( - Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier? identifier, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char('='), withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression expression, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ExpressionParser.Expression, out Expression? expression, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { - parsed = new SamplerStateParameter(identifier, expression, scanner[position..scanner.Position]); + parsed = new SamplerStateParameter(identifier!, expression!, scanner[position..scanner.Position]); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); @@ -191,7 +193,7 @@ public static bool SamplerStateValueAssignment(ref TScanner scanner, P public record struct ShaderStructMemberParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderStructMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderStructMember parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; var hasAttributes = ShaderAttributeListParser.AttributeList(ref scanner, result, out var attributes); @@ -206,17 +208,17 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ; if ( - Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName? typename, withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _) - && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier? identifier, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true) ) { - parsed = new ShaderStructMember(typename, identifier, scanner[position..scanner.Position]); + parsed = new ShaderStructMember(typename!, identifier!, scanner[position..scanner.Position]); if (hasAttributes) - parsed.Attributes = attributes.Attributes; + parsed.Attributes = attributes!.Attributes; if (hasTypeModifier) - parsed.TypeModifier = typemodifier.ToTypeModifier(); + parsed.TypeModifier = typemodifier!.ToTypeModifier(); return true; } return Parsers.Exit(ref scanner, result, out parsed, position, orError); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs index b2ab627dad..d21e25b073 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderElementParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderElementParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -51,15 +52,15 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } - public static bool Compose(ref TScanner scanner, ParseResult result, out ShaderCompose parsed, in ParseError? orError = null) + public static bool Compose(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderCompose parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new CompositionParser().Match(ref scanner, result, out parsed, in orError); - public static bool Struct(ref TScanner scanner, ParseResult result, out ShaderStruct parsed, in ParseError? orError = null) + public static bool Struct(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderStruct parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderStructParser().Match(ref scanner, result, out parsed, in orError); - public static bool AnySamplers(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + public static bool AnySamplers(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -79,21 +80,21 @@ public static bool AnySamplers(ref TScanner scanner, ParseResult resul } else return Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool SamplerState(ref TScanner scanner, ParseResult result, out ShaderSamplerState parsed, in ParseError? orError = null) + public static bool SamplerState(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderSamplerState parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderSamplerStateParser().Match(ref scanner, result, out parsed, in orError); - public static bool SamplerComparisonState(ref TScanner scanner, ParseResult result, out ShaderSamplerComparisonState parsed, in ParseError? orError = null) + public static bool SamplerComparisonState(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderSamplerComparisonState parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderSamplerComparisonStateParser().Match(ref scanner, result, out parsed, in orError); - public static bool ShaderElement(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + public static bool ShaderElement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderElementParsers().Match(ref scanner, result, out parsed, in orError); - public static bool Method(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public static bool Method(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ShaderMethodParsers().Match(ref scanner, result, out parsed, in orError); - public static bool TypeDef(ref TScanner scanner, ParseResult result, out ShaderElement parsed, in ParseError? orError = null) + public static bool TypeDef(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderElement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs index 5a15774180..a86f0d265c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderFileParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDFX; using Stride.Shaders.Parsing.SDSL.AST; @@ -8,7 +9,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderFileParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderFile parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderFile parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -62,14 +63,14 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = file; return true; } - public static bool UsingNamespace(ref TScanner scanner, ParseResult result, out UsingShaderNamespace parsed, in ParseError? orError = null) + public static bool UsingNamespace(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out UsingShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new UsingNamespaceParser().Match(ref scanner, result, out parsed, orError); } public record struct UsingNamespaceParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out UsingShaderNamespace parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out UsingShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -78,9 +79,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o parsed = new(scanner[..]); do { - if (Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier identifier, withSpaces: true, advance: true)) + if (Parsers.FollowedByDel(ref scanner, result, LiteralsParser.Identifier, out Identifier? identifier, withSpaces: true, advance: true)) { - parsed.NamespacePath.Add(identifier); + parsed.NamespacePath.Add(identifier!); } else return Parsers.Exit(ref scanner, result, out parsed, position, new(SDSLErrorMessages.SDSL0001, scanner[scanner.Position], scanner.Memory)); } @@ -104,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct NamespaceParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -168,7 +169,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Namespace(ref TScanner scanner, ParseResult result, out ShaderNamespace parsed, in ParseError? orError = null) + public static bool Namespace(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderNamespace parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new NamespaceParsers().Match(ref scanner, result, out parsed, orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs index 615f8a6734..c3fa508a8c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderMethodParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ShaderMethodParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner { if (Method(ref scanner, result, out var method, in orError)) @@ -20,20 +21,20 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } } - public static bool Method(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public static bool Method(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new MethodParser().Match(ref scanner, result, out parsed, in orError); - public static bool Simple(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public static bool Simple(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new SimpleMethodParser().Match(ref scanner, result, out parsed, in orError); - public static bool MethodParameters(ref TScanner scanner, ParseResult result, out List parsed, in ParseError? orError = null) + public static bool MethodParameters(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out List parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; -#warning We should not allow void to be a parameter, this is legacy C code + // HLSL compat: accept `(void)` as empty parameter list (legacy C convention) if ( Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true) || @@ -48,7 +49,7 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult } else - if (Parsers.Repeat(ref scanner, result, MethodParameter, out List parameters, 0, withSpaces: true, separator: ",")) + if (Parsers.Repeat(ref scanner, result, MethodParameter, out List? parameters, 0, withSpaces: true, separator: ",")) { parsed = parameters; return true; @@ -56,7 +57,7 @@ public static bool MethodParameters(ref TScanner scanner, ParseResult else return Parsers.Exit(ref scanner, result, out parsed, position); } - public static bool MethodParameter(ref TScanner scanner, ParseResult result, out MethodParameter parsed, in ParseError? orError = null) + public static bool MethodParameter(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out MethodParameter parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -75,7 +76,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r { if ( Parsers.FollowedBy(ref scanner, Tokens.Char(':'), withSpaces: true, advance: true) - && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier semantic, withSpaces: true, advance: true) + && Parsers.FollowedBy(ref scanner, result, LiteralsParser.Identifier, out Identifier? semantic, withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) ) { @@ -95,7 +96,7 @@ public static bool MethodParameter(ref TScanner scanner, ParseResult r public record struct SimpleMethodParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -104,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o && Parsers.Spaces1(ref scanner, result, out _, new(SDSLErrorMessages.SDSL0016, scanner[scanner.Position], scanner.Memory)) && LiteralsParser.Identifier(ref scanner, result, out var methodName) && Parsers.FollowedBy(ref scanner, Tokens.Char('('), withSpaces: true, advance: true) - && Parsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.MethodParameters, out List parameters, withSpaces: true, advance: true) + && Parsers.FollowedByDel(ref scanner, result, ShaderMethodParsers.MethodParameters, out List? parameters, withSpaces: true, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(')'), withSpaces: true, advance: true) && Parsers.Spaces0(ref scanner, result, out _) && StatementParsers.Block(ref scanner, result, out var body, new(SDSLErrorMessages.SDSL0040, scanner[scanner.Position], scanner.Memory)) @@ -112,7 +113,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o { parsed = new ShaderMethod(typename, methodName, scanner[position..scanner.Position]) { - Parameters = parameters, + Parameters = parameters!, Body = (BlockStatement)body }; return true; @@ -124,7 +125,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct MethodParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderMethod parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderMethod parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -158,10 +159,9 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } else { - parsed = new(typename, methodName, scanner[position..scanner.Position], isAbstract: true) - { - Parameters = parameters - }; + parsed = new(typename, methodName, scanner[position..scanner.Position], isAbstract: true); + if (parameters is not null) + parsed.Parameters = parameters; return true; } } @@ -173,7 +173,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o if (ShaderMethodParsers.Simple(ref scanner, result, out parsed, orError)) { if (hasAttributes) - parsed.Attributes = attributes.Attributes; + parsed.Attributes = attributes!.Attributes; parsed.IsStaged = isStaged; parsed.IsClone = isClone; parsed.IsOverride = isOverride; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs index 7e04284dcd..ce76d5c8ff 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ShaderParsers/ShaderParameters.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,21 +6,21 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ParameterParsers : IParser { - public bool Match(ref TScanner scanner, ParseResult result, out ParameterListNode parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ParameterListNode parsed, in ParseError? orError = null) where TScanner : struct, IScanner { throw new NotImplementedException(); } - public static bool Declarations(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) + public static bool Declarations(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderParameterDeclarations parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParameterDeclarationsParser().Match(ref scanner, result, out parsed, in orError); public static bool Values(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new ParameterListParser().Match(ref scanner, result, out parsed, in orError); - public static bool GenericsList(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) + public static bool GenericsList(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new GenericsListParser().Match(ref scanner, result, out parsed, in orError); - public static bool GenericsValue(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) + public static bool GenericsValue(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new GenericsValueParser().Match(ref scanner, result, out parsed, in orError); } @@ -27,7 +28,7 @@ public static bool GenericsValue(ref TScanner scanner, ParseResult res public record struct ParameterDeclarationsParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderParameterDeclarations parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderParameterDeclarations parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; List parameters = []; @@ -35,13 +36,13 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o do { if ( - Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName typename, withSpaces: true, advance: true) + Parsers.FollowedBy(ref scanner, result, LiteralsParser.TypeName, out TypeName? typename, withSpaces: true, advance: true) && Parsers.Spaces1(ref scanner, result, out _) && LiteralsParser.Identifier(ref scanner, result, out var name) && Parsers.Spaces0(ref scanner, result, out _) ) { - parameters.Add(new(typename, name)); + parameters.Add(new(typename!, name)); } else return Parsers.Exit(ref scanner, result, out parsed, position); } @@ -79,7 +80,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct GenericsListParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ShaderExpressionList parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (ParameterParsers.GenericsValue(ref scanner, result, out var parameter)) @@ -104,7 +105,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct GenericsValueParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Expression parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; if (LiteralsParser.Number(ref scanner, result, out var number)) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs index 9f1d65e18f..188dc2cec9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Control.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -6,11 +7,11 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct ControlsParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalFlow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => Control(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool Control(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalFlow parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -34,11 +35,11 @@ public static bool Control(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Control(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) + public static bool Control(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner => Control(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool If(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out If parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -63,11 +64,11 @@ public static bool If(ref TScanner scanner, ParseResult result, out If return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool If(ref TScanner scanner, ParseResult result, out If parsed, ParseError? orError = null) + public static bool If(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out If parsed, ParseError? orError = null) where TScanner : struct, IScanner => If(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool ElseIf(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ElseIf parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -95,11 +96,11 @@ public static bool ElseIf(ref TScanner scanner, ParseResult result, ou return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool ElseIf(ref TScanner scanner, ParseResult result, out ElseIf parsed, ParseError? orError = null) + public static bool ElseIf(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ElseIf parsed, ParseError? orError = null) where TScanner : struct, IScanner => ElseIf(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool Else(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Else parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -115,7 +116,7 @@ public static bool Else(ref TScanner scanner, ParseResult result, out return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Else(ref TScanner scanner, ParseResult result, out Else parsed, ParseError? orError = null) + public static bool Else(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Else parsed, ParseError? orError = null) where TScanner : struct, IScanner => Else(ref scanner, result, out parsed, StatementParsers.Statement, orError); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs index 5905fe3a4c..6400e28080 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Flow.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -7,11 +8,11 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct FlowParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Flow parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Flow parsed, in ParseError? orError = null) where TScanner : struct, IScanner => Flow(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool Flow(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Flow parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -40,11 +41,11 @@ public static bool Flow(ref TScanner scanner, ParseResult result, out else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParseError? orError = null) + public static bool Flow(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Flow parsed, ParseError? orError = null) where TScanner : struct, IScanner => Flow(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool While(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out While parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -70,11 +71,11 @@ public static bool While(ref TScanner scanner, ParseResult result, out return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool While(ref TScanner scanner, ParseResult result, out While parsed, ParseError? orError = null) + public static bool While(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out While parsed, ParseError? orError = null) where TScanner : struct, IScanner => While(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool For(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out For parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -124,11 +125,11 @@ public static bool For(ref TScanner scanner, ParseResult result, out F else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool For(ref TScanner scanner, ParseResult result, out For parsed, ParseError? orError = null) + public static bool For(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out For parsed, ParseError? orError = null) where TScanner : struct, IScanner => For(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool ForEach(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ForEach parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -169,11 +170,11 @@ public static bool ForEach(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool ForEach(ref TScanner scanner, ParseResult result, out ForEach parsed, ParseError? orError = null) + public static bool ForEach(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ForEach parsed, ParseError? orError = null) where TScanner : struct, IScanner => ForEach(ref scanner, result, out parsed, StatementParsers.Statement, orError); - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs index 42363e32ff..8f08d1d75a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.Switch.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Parsing.SDSL.AST; namespace Stride.Shaders.Parsing.SDSL; @@ -5,7 +6,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct SwitchStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out SwitchStatement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SwitchStatement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -40,7 +41,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - public static bool SwitchSection(ref TScanner scanner, ParseResult result, out SwitchSection parsed, ParseError? orError = null) + public static bool SwitchSection(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SwitchSection parsed, ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -78,7 +79,7 @@ public static bool SwitchSection(ref TScanner scanner, ParseResult res return true; } - public static bool SwitchLabel(ref TScanner scanner, ParseResult result, out SwitchLabel parsed, ParseError? orError = null) + public static bool SwitchLabel(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SwitchLabel parsed, ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs index d300f0e631..96f08cfff1 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/StatementParsers/StatementParsers.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Stride.Shaders.Core; using Stride.Shaders.Parsing.SDSL.AST; @@ -6,7 +7,7 @@ namespace Stride.Shaders.Parsing.SDSL; public record struct StatementParsers : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -43,22 +44,22 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool Statement(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + internal static bool Statement(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new StatementParsers().Match(ref scanner, result, out parsed, orError); - internal static bool Empty(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Empty(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new EmptyStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) + internal static bool Block(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner => BlockStatementParser.Block(ref scanner, result, out parsed, statementParser, orError); - internal static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Block(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new BlockStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Break(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Break(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new BreakParser().Match(ref scanner, result, out parsed, orError); - internal static bool Discard(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Discard(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -72,19 +73,19 @@ internal static bool Discard(ref TScanner scanner, ParseResult result, } else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool Return(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Return(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ReturnStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Continue(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Continue(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ContinueParser().Match(ref scanner, result, out parsed, orError); - internal static bool Expression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Expression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ExpressionStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Declare(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool Declare(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new DeclareStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -94,19 +95,19 @@ internal static bool DeclareOrAssign(ref TScanner scanner, ParseResult return true; else return Parsers.Exit(ref scanner, result, out parsed, position, orError); } - internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, out Statement parsed, ParseError? orError = null) + internal static bool AssignOrExpression(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParseError? orError = null) where TScanner : struct, IScanner => Expression(ref scanner, result, out parsed, orError); - internal static bool DeclaredVarAssign(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) + internal static bool DeclaredVarAssign(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner => new DeclaredVariableAssignParser().Match(ref scanner, result, out parsed, orError); - internal static bool Controls(ref TScanner scanner, ParseResult result, out ConditionalFlow parsed, ParseError? orError = null) + internal static bool Controls(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out ConditionalFlow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new ControlsParser().Match(ref scanner, result, out parsed, orError); - internal static bool Switch(ref TScanner scanner, ParseResult result, out SwitchStatement parsed, ParseError? orError = null) + internal static bool Switch(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out SwitchStatement parsed, ParseError? orError = null) where TScanner : struct, IScanner => new SwitchStatementParser().Match(ref scanner, result, out parsed, orError); - internal static bool Flow(ref TScanner scanner, ParseResult result, out Flow parsed, ParseError? orError = null) + internal static bool Flow(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Flow parsed, ParseError? orError = null) where TScanner : struct, IScanner => new FlowParsers().Match(ref scanner, result, out parsed, orError); } @@ -115,7 +116,7 @@ internal static bool Flow(ref TScanner scanner, ParseResult result, ou public record struct EmptyStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { parsed = null!; @@ -132,7 +133,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ReturnStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -152,7 +153,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o return true; } else if ( - Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Parenthesis, out Expression p, advance: true) + Parsers.FollowedByDel(ref scanner, result, PrimaryParsers.Parenthesis, out Expression? p, advance: true) && Parsers.FollowedBy(ref scanner, Tokens.Char(';'), withSpaces: true, advance: true) ) { @@ -177,7 +178,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct BreakParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -195,7 +196,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o } public record struct ContinueParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -214,7 +215,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct ExpressionStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -235,11 +236,11 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct BlockStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner => Block(ref scanner, result, out parsed, StatementParsers.Statement, orError); - public static bool Block(ref TScanner scanner, ParseResult result, out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) + public static bool Block(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, ParserDelegate statementParser, ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -268,7 +269,7 @@ public static bool Block(ref TScanner scanner, ParseResult result, out public record struct DeclaredVariableAssignParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out DeclaredVariableAssign parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -314,7 +315,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o public record struct DeclareStatementParser : IParser { - public readonly bool Match(ref TScanner scanner, ParseResult result, out Statement parsed, in ParseError? orError = null) + public readonly bool Match(ref TScanner scanner, ParseResult result, [MaybeNullWhen(false)] out Statement parsed, in ParseError? orError = null) where TScanner : struct, IScanner { var position = scanner.Position; @@ -329,7 +330,7 @@ public readonly bool Match(ref TScanner scanner, ParseResult result, o ) { - if (Parsers.Repeat(ref scanner, result, StatementParsers.DeclaredVarAssign, out List assigns, 1, true, ",")) + if (Parsers.Repeat(ref scanner, result, StatementParsers.DeclaredVarAssign, out List? assigns, 1, true, ",")) { foreach (var a in assigns) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs index 3502317c65..676758cb71 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs @@ -1,5 +1,6 @@ using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -37,7 +38,7 @@ public static bool Set(string set, ref TScanner scanner, out char chos public static bool Literal(string c, ref TScanner scanner, bool advance = false) where TScanner : struct, IScanner => new LiteralTokenParser(c).Match(ref scanner, advance); - public static bool AnyOf(ReadOnlySpan literals, ref TScanner scanner, out string matched, bool advance = false) + public static bool AnyOf(ReadOnlySpan literals, ref TScanner scanner, [MaybeNullWhen(false)] out string matched, bool advance = false) where TScanner : struct, IScanner { matched = null!; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs index 66b470cb5c..a4c591be7a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs @@ -24,6 +24,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type // HLSL array size: last element is not padded to stride AlignmentRules.CBuffer => ((current.Size + 15) / 16 * 16 * (count - 1) + current.Size, 16), AlignmentRules.StructuredBuffer => (current.Size * count, current.Alignment), + _ => throw new NotSupportedException($"Unsupported AlignmentRules value: {alignmentRules}"), }; return (symbol) switch { @@ -40,6 +41,7 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type // Round up to 16 bytes (size of float4) ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules), a.Size, alignmentRules), // TODO: StructureType + _ => throw new NotSupportedException($"Unsupported type for buffer layout: {symbol}"), }; } @@ -63,6 +65,7 @@ private static (int, int) StructSizeInBuffer(StructuredType s, AlignmentRules al { AlignmentRules.CBuffer => 16, AlignmentRules.StructuredBuffer => maxAlignment, + _ => throw new NotSupportedException($"Unsupported AlignmentRules value: {alignmentRules}"), }; return (offset, alignment); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index cac3264c0d..16cb106ca6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -19,6 +19,7 @@ using Stride.Core.Storage; using static Stride.Shaders.Spirv.Specification; using Stride.Shaders.Spirv.Core.Parsing; +using System.Diagnostics.CodeAnalysis; namespace Stride.Shaders.Spirv.Building; @@ -65,7 +66,7 @@ public record class ShaderClassInstantiation(string ClassName, ConstantExpressio public ConstantExpression[] GenericArguments { get; set; } = GenericArguments; - public ShaderDefinition Symbol { get; set; } + public ShaderDefinition? Symbol { get; set; } public string ToClassNameWithGenerics() { @@ -114,13 +115,14 @@ public override int GetHashCode() // Constant vector (generated by TryGetConstantValue) public class ConstantVector { - public object[] Values; + public required object[] Values; public override string ToString() { var type = Values[0] switch { float => "float", + _ => throw new NotSupportedException($"Unsupported constant vector element type: {Values[0].GetType()}"), }; return $"{type}{Values.Length}({string.Join(",", Values)})"; @@ -237,7 +239,7 @@ abstract class GenericResolver public abstract string ResolveGenericAsString(int genericIndex); - public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value); + public abstract bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, [MaybeNullWhen(false)] out object value); public abstract bool ResolveGenericValueInBuffer(SymbolType genericParameterType, string genericParameterName, int genericIndex, SpirvContext context, ref int instructionIndex, out string textValue); public virtual void ValidateGenericParameters(string classNameWithGenerics, List genericParameters) @@ -256,9 +258,9 @@ public virtual void PostProcess(string classNameWithGenerics) /// /// Instantiate generics using string values (they will be imported in the generic shader being specialized). /// - class GenericResolverFromValues(string[]? genericValues) : GenericResolver + class GenericResolverFromValues(string[] genericValues) : GenericResolver { - public override int GenericArgumentCount => genericValues?.Length ?? 0; + public override int GenericArgumentCount => genericValues.Length; public override string ResolveGenericAsString(int genericIndex) => genericValues[genericIndex]; public override bool TryResolveGenericValue(SymbolType genericParameterType, string genericParameterName, int index, out object value) @@ -296,7 +298,7 @@ public override bool ResolveGenericValueInBuffer(SymbolType genericParameterType if (!ExpressionParser.Expression(ref scanner, pr, out var expression)) throw new InvalidOperationException("Can't parse generic value"); var localContext = new SpirvContext(); - var result = expression.CompileConstantValue(new SymbolTable(localContext), localContext, genericParameterType); + var result = expression.CompileConstantValue(new SymbolTable(localContext, null!), localContext, genericParameterType); context.RemoveAt(instructionIndex); context.InsertWithoutDuplicates(ref instructionIndex, genericParameter.ResultId, localContext.GetBuffer()); return true; @@ -568,7 +570,7 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri if (genericParameterType is GenericParameterType { Kind: GenericParameterKindSDSL.MemberName }) { if (genericResolver.TryResolveGenericValue(genericParameterType, genericParameterName, genericParameterIndex, out var value)) - instantiatedGenericsMacros.Add((shaderBuffers.Context.Names[genericParameter], value.ToString())); + instantiatedGenericsMacros.Add((shaderBuffers.Context.Names[genericParameter], value.ToString()!)); } genericParameterIndex++; } @@ -812,8 +814,11 @@ public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, return GetOrLoadShader(shaderLoader, classSource.ClassName, new GenericResolverFromInstantiatingBuffer(classSource, resolveStep, context), macros); } - public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[] genericValues, ReadOnlySpan macros) + public static ShaderBuffers GetOrLoadShader(IExternalShaderLoader shaderLoader, string className, string[]? genericValues, ReadOnlySpan macros) { + if (genericValues is null) + return GetOrLoadShader(shaderLoader, className, macros, out var hash, out var isFromCache); + return GetOrLoadShader(shaderLoader, className, new GenericResolverFromValues(genericValues), macros); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs index 460d7b2fea..43c3dcbf61 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Expressions.cs @@ -31,6 +31,7 @@ public SpirvValue AsValue(SpirvContext context, SpirvValue result) { ScalarType s => ApplyScalarSwizzles(context, value, s, swizzleIndices), VectorType v => ApplyVectorSwizzles(context, value, v, swizzleIndices), + _ => throw new NotSupportedException($"Unsupported type for swizzle: {valueType}"), }; } @@ -239,6 +240,7 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv StructType otherStructType when otherStructType == structType => Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(member.Type), context.Bound++, otherValue.Id, [i])).ToValue(), ScalarType => otherValue, + _ => throw new NotSupportedException($"Unsupported type in struct binary operation: {otherType}"), }; memberValue = leftType is StructType ? BinaryOperation(table, context, memberValue, op, otherMemberValue, info, name) @@ -267,6 +269,7 @@ public SpirvValue BinaryOperation(SymbolTable table, SpirvContext context, Spirv ArrayType otherArrayType when otherArrayType == arrayType => Buffer.Insert(Position++, new OpCompositeExtract(context.GetOrRegister(arrayType.BaseType), context.Bound++, otherValue.Id, [i])).ToValue(), ScalarType => otherValue, + _ => throw new NotSupportedException($"Unsupported type in array binary operation: {otherType}"), }; arrayValues[i] = leftType is StructType ? BinaryOperation(table, context, memberValue, op, otherMemberValue, info, name).Id @@ -568,14 +571,14 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy throw new InvalidOperationException($"Can't cast from {m1} to {m2} (larger matrix)"); case (MatrixType m1, MatrixType m2) when m1.Rows >= m2.Rows && m1.Columns >= m2.Columns: { + Span shuffleIndices = stackalloc int[m2.Columns]; + for (int j = 0; j < m2.Columns; ++j) + shuffleIndices[j] = j; for (int i = 0; i < m2.Rows; ++i) { values[i] = Insert(new OpCompositeExtract(context.GetOrRegister(new VectorType(m1.BaseType, m1.Columns)), context.Bound++, valueId, [i])).ResultId; if (m1.Columns != m2.Columns) { - Span shuffleIndices = stackalloc int[m2.Columns]; - for (int j = 0; j < m2.Columns; ++j) - shuffleIndices[j] = j; values[i] = Insert(new OpVectorShuffle(context.GetOrRegister(new VectorType(m1.BaseType, m2.Columns)), context.Bound++, values[i], values[i], new(shuffleIndices))).ResultId; } } @@ -592,6 +595,7 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy { ScalarType s => (1, (SymbolType)castType.GetElementType()), VectorType s => (s.Size, new VectorType(castType.GetElementType(), s.Size)), + _ => throw new NotSupportedException($"Unsupported type for element-wise cast: {valueType}"), }; for (int i = 0; i < values.Length; ++i) { @@ -636,6 +640,7 @@ public SpirvValue Convert(SpirvContext context, in SpirvValue value, in SymbolTy // Bitcast (int=>uint or uint=>int) (ScalarType { Type: Scalar.Int }, ScalarType { Type: Scalar.UInt }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), (ScalarType { Type: Scalar.UInt }, ScalarType { Type: Scalar.Int }) => InsertData(new OpBitcast(context.GetOrRegister(castTypeSameSize), context.Bound++, rowValue)), + (ScalarType { Type: var from }, ScalarType { Type: var to }) => throw new NotSupportedException($"Unsupported type cast: {from} to {to}"), }; values[i] = typeCasting.IdResult!.Value; @@ -710,18 +715,21 @@ public static SymbolType GetVectorOrScalar(this ScalarType scalar, int size) ScalarType s => 1, VectorType v => v.Size, MatrixType m => m.Rows * m.Columns, + _ => throw new NotSupportedException($"Unsupported type for GetElementCount: {symbol}"), }; public static ScalarType GetElementType(this SymbolType symbol) => symbol switch { ScalarType s => s, VectorType v => v.BaseType, MatrixType m => m.BaseType, + _ => throw new NotSupportedException($"Unsupported type for GetElementType: {symbol}"), }; public static SymbolType WithElementType(this SymbolType symbol, ScalarType elementType) => symbol switch { ScalarType s => elementType, VectorType v => v.BaseType == elementType ? v : v with { BaseType = elementType }, MatrixType m => m.BaseType == elementType ? m : m with { BaseType = elementType }, + _ => throw new NotSupportedException($"Unsupported type for WithElementType: {symbol}"), }; public static bool IsSignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.Int or Scalar.Int64 }; public static bool IsUnsignedInteger(this SymbolType symbol) => symbol is ScalarType { Type: Scalar.UInt or Scalar.UInt64 }; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs index 5c12eab3e5..9401aeabd6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Functions.cs @@ -28,6 +28,9 @@ public void BeginFunction(SpirvContext context, SpirvFunction function, Function public void EndFunction() { + if (CurrentFunction is null) + throw new InvalidOperationException("Trying to end a function which was not started"); + // If there was no explicit return, add one var lastInstruction = Buffer[Position - 1]; if (!IsBlockTermination(lastInstruction.Op)) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs index 5ea62d67de..d95d24406b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs @@ -97,7 +97,6 @@ public OpData InsertData(in T value) where T : struct, IMemoryInstruction, allows ref struct => Buffer.InsertData(Position++, value); - [Obsolete("Use the insert method instead")] public SpirvBuffer GetBuffer() => Buffer; public Op GetLastInstructionType() diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index a161cee8f4..5a174caafd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -101,6 +101,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object Specification.Op.OpConvertFToU => (uint)(float)convertOperand, Specification.Op.OpConvertSToF => (float)(int)convertOperand, Specification.Op.OpConvertUToF => (float)(uint)convertOperand, + _ => throw new NotSupportedException($"Unsupported conversion op: {op}"), }; break; // Unary operations @@ -115,6 +116,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object // Note: first cast to object is important, otherwise int/float will be cast as float Specification.Op.OpSNegate => (object)(-(int)unaryOperand), Specification.Op.OpFNegate => -(float)unaryOperand, + _ => throw new NotSupportedException($"Unsupported unary op: {op}"), }; break; // Binary operations @@ -141,6 +143,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object Specification.Op.OpFSub => (float)left - (float)right, Specification.Op.OpFMul => (float)left * (float)right, Specification.Op.OpFDiv => (float)left / (float)right, + _ => throw new NotSupportedException($"Unsupported binary op: {op}"), }; break; default: @@ -157,7 +160,7 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object var constants = new object[values.WordCount]; for (int j = 0; j < values.WordCount; ++j) { - if (!TryGetConstantValue(values.Elements.Span[j], out constants[j], out _)) + if (!TryGetConstantValue(values.Elements.Span[j], out constants[j]!, out _)) return false; } @@ -258,6 +261,7 @@ public Literal CreateLiteral(object value, TextLocation location = default) ulong i => new IntegerLiteral(new(64, false, false), (long)i, location), float i => new FloatLiteral(new(32, true, true), i, null, location), double i => new FloatLiteral(new(64, true, true), i, null, location), + _ => throw new NotSupportedException($"Unsupported literal type: {value.GetType()}"), }; } @@ -351,6 +355,7 @@ public static ScalarType ComputeLiteralType(Literal literal) 64 => ScalarType.Double, _ => throw new NotImplementedException("Unsupported float") }, + _ => throw new NotSupportedException($"Unsupported literal type: {literal.GetType()}"), }; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs index 44d1c01c64..41d2628375 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.ExtractBuffers.cs @@ -57,7 +57,7 @@ public int InsertWithoutDuplicates(ref int instructionIndex, int? desiredResultI typeDuplicateInserter.RemoveInstructionAt(existingData.Index, false); existingData = typeDuplicateInserter.InsertInstruction(instructionIndex++, existingDataCopy); } - remapIds.Add(iData.IdResult.Value, existingData.Data.IdResult.Value); + remapIds.Add(iData.IdResult!.Value, existingData.Data.IdResult!.Value); lastResultId = existingData.Data.IdResult.Value; } else diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 51131f141b..313a00c478 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -209,7 +209,7 @@ public int GetGLSL() if (GLSLSet == null) ImportGLSL(); - return GLSLSet.Value; + return GLSLSet!.Value; } /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index 9eba9bd996..dca1be075c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -87,7 +87,7 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont accessChain.Base = load.Pointer; if (streams.TryGetValue(accessChain.Base, out var streamInfo)) { - var streamKind = accessChain.StreamKind.Value; + var streamKind = accessChain.StreamKind!.Value; // If read on input/output stream, we force it to be emitted in the input/output struct if (streamKind == StreamsKindSDSL.Output) @@ -121,7 +121,7 @@ public static bool AnalyzeStreamReadWrites(SpirvBuffer buffer, SpirvContext cont if (streams.TryGetValue(accessChain.Base, out var streamInfo)) { - var streamKind = accessChain.StreamKind.Value; + var streamKind = accessChain.StreamKind!.Value; // Write on input/output stream are not allowed if (streamKind is StreamsKindSDSL.Input or StreamsKindSDSL.Output) throw new InvalidOperationException("Can't write value on input or output struct"); diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs index e5a892e2ce..7fe1d038ec 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/StreamAnalyzer.cs @@ -130,53 +130,55 @@ public static AnalysisResult Analyze(SpirvBuffer buffer, SpirvContext context) } } - // Process ResourceGroupId and build ResourceGroups - Dictionary resourceGroups = new(); + // Collect decoration strings and group IDs by target + Dictionary resourceGroupNamesByTarget = new(); + Dictionary logicalGroupNamesByTarget = new(); + Dictionary groupIdByTarget = new(); foreach (var i in context) { - if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) - { - var n = m.To(); - - if (!resourceGroups.TryGetValue(n.ResourceGroup, out var resourceGroup)) - resourceGroups.Add(n.ResourceGroup, resourceGroup = new()); + if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string groupName } resourceGroupDecorate) + resourceGroupNamesByTarget.TryAdd(resourceGroupDecorate.Target, groupName); + else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.LogicalGroupSDSL, Value: string logicalName } logicalGroupDecorate) + logicalGroupNamesByTarget.TryAdd(logicalGroupDecorate.Target, logicalName); + else if (i.Op == Op.OpDecorate && (OpDecorate)i is { Decoration: Decoration.ResourceGroupIdSDSL, DecorationParameters: { } m } resourceGroupIdDecorate) + groupIdByTarget.TryAdd(resourceGroupIdDecorate.Target, m.To().ResourceGroup); + } - if (resources.TryGetValue(resourceGroupIdDecorate.Target, out var resourceInfo)) - { - resourceGroup.Resources.Add(resourceInfo); - resourceInfo.ResourceGroup = resourceGroup; - } - else if (cbuffers.TryGetValue(resourceGroupIdDecorate.Target, out var cbufferInfo)) - { - cbufferInfo.ResourceGroup = resourceGroup; - } - } + // Resolve group ID → name (first target with both a group ID and a ResourceGroupSDSL name wins) + Dictionary groupNames = new(); + foreach (var (target, groupId) in groupIdByTarget) + { + if (!groupNames.ContainsKey(groupId) && resourceGroupNamesByTarget.TryGetValue(target, out var name)) + groupNames.Add(groupId, name); } - // Process ResourceGroup and LogicalGroup decorations - foreach (var i in context) + // Build ResourceGroups and assign resources/cbuffers + Dictionary resourceGroups = new(); + foreach (var (target, groupId) in groupIdByTarget) { - if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.ResourceGroupSDSL, Value: string m2 } resourceGroupDecorate) + if (!resourceGroups.TryGetValue(groupId, out var resourceGroup)) { - if (resources.TryGetValue(resourceGroupDecorate.Target, out var resourceInfo) - // Note: ResourceGroup should not be null if set - && resourceInfo.ResourceGroup.Name == null) - { - resourceInfo.ResourceGroup.Name = m2; - } + if (!groupNames.TryGetValue(groupId, out var name)) + throw new InvalidOperationException($"ResourceGroup {groupId} has no ResourceGroupSDSL name decoration"); + resourceGroups.Add(groupId, resourceGroup = new(name)); } - else if (i.Op == Op.OpDecorateString && (OpDecorateString)i is { Decoration: Decoration.LogicalGroupSDSL, Value: string m3 } logicalGroupDecorate) + + if (resources.TryGetValue(target, out var resourceInfo)) { - if (resources.TryGetValue(logicalGroupDecorate.Target, out var resourceInfo) - // Note: ResourceGroup should not be null if this decoration is set - && resourceInfo.ResourceGroup.LogicalGroup == null) - { - resourceInfo.ResourceGroup.LogicalGroup = m3; - } - else if (cbuffers.TryGetValue(logicalGroupDecorate.Target, out var cbufferInfo)) - { - cbufferInfo.LogicalGroup = m3; - } + resourceGroup.Resources.Add(resourceInfo); + resourceInfo.ResourceGroup = resourceGroup; + } + else if (cbuffers.TryGetValue(target, out var cbufferInfo)) + { + cbufferInfo.ResourceGroup = resourceGroup; + } + + // Apply LogicalGroup if present + if (logicalGroupNamesByTarget.TryGetValue(target, out var logicalGroup)) + { + resourceGroup.LogicalGroup ??= logicalGroup; + if (cbuffers.TryGetValue(target, out var ci)) + ci.LogicalGroup ??= logicalGroup; } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs index 6008100fb0..301fd29907 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Generation/EntryPointWrapperGenerator.cs @@ -215,7 +215,7 @@ void FillTessellationArguments(Symbol function, Span arguments) case StreamsType t when t.Kind is StreamsKindSDSL.Constants && parameterModifiers is ParameterModifiers.None or ParameterModifiers.In: { // Parameter is "HS_CONSTANTS constants" - var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(streamLayout.ConstantsType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; + var constantVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(streamLayout.ConstantsType!, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = constantVariable; // Copy back values from semantic/builtin variables to Constants struct foreach (var stream in streamLayout.PatchInputStreams) @@ -233,7 +233,8 @@ void FillTessellationArguments(Symbol function, Span arguments) var structType = t.Kind switch { StreamsKindSDSL.Output => streamLayout.OutputType, - StreamsKindSDSL.Constants => streamLayout.ConstantsType, + StreamsKindSDSL.Constants => streamLayout.ConstantsType!, + _ => throw new NotSupportedException($"Unsupported StreamsKindSDSL for output parameter: {t.Kind}"), }; var outVariable = buffer.Insert(variableInsertIndex++, new OpVariable(context.GetOrRegister(new PointerType(structType, Specification.StorageClass.Function)), context.Bound++, Specification.StorageClass.Function, null)).ResultId; arguments[i] = outVariable; @@ -271,7 +272,7 @@ void ProcessTessellationArguments(Symbol function, Span arguments) var outputTargetPtr = streamLayout.ArrayOutputSize != null ? buffer.Add(new OpAccessChain(context.GetOrRegister(new PointerType(stream.Info.Type, Specification.StorageClass.Output)), context.Bound++, stream.Id, - [invocationIdValue.Value])).ResultId + [invocationIdValue!.Value])).ResultId : stream.Id; buffer.Add(new OpStore(outputTargetPtr, outputResult, null, [])); } @@ -367,12 +368,14 @@ void ProcessTessellationArguments(Symbol function, Span arguments) ParameterModifiers.LineAdjacency => ExecutionMode.InputLinesAdjacency, ParameterModifiers.Triangle => ExecutionMode.Triangles, ParameterModifiers.TriangleAdjacency => ExecutionMode.InputTrianglesAdjacency, + _ => throw new NotSupportedException($"Unsupported geometry input execution mode: {executionMode}"), }, [])); context.Add(new OpExecutionMode(entryPoint.IdRef, outputStreamType.Kind switch { GeometryStreamOutputKindSDSL.Point => ExecutionMode.OutputPoints, GeometryStreamOutputKindSDSL.Line => ExecutionMode.OutputLineStrip, GeometryStreamOutputKindSDSL.Triangle => ExecutionMode.OutputTriangleStrip, + _ => throw new NotSupportedException($"Unsupported geometry stream output kind: {outputStreamType.Kind}"), }, [])); arguments[0] = inputsVariable; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 5035a69231..81e0166751 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -184,7 +184,7 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex if (entryPoint.Item1 == ExecutionModel.TessellationControl) { var dsEntryPoint = entryPoints.FirstOrDefault(ep => ep.Model == ExecutionModel.TessellationEvaluation); - if (dsEntryPoint.InterfaceVariables != null) + if (dsEntryPoint?.InterfaceVariables != null) { foreach (var stream in streams) { @@ -399,7 +399,7 @@ private static void GenerateStreamStructTypes(SpirvContext context, ExecutionMod context.DeclareStructuredType(outputType, context.Bound++); context.DeclareStructuredType(streamsType, context.Bound++); if (hasConstants) - context.DeclareStructuredType(constantsType, context.Bound++); + context.DeclareStructuredType(constantsType!, context.Bound++); } private static void GenerateStreamVariables(SpirvContext context, ExecutionModel executionModel, Dictionary streams, int? arrayInputSize, int? arrayOutputSize, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> inputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> outputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchInputStreams, out List<(StreamVariableInfo Info, int Id, SymbolType InterfaceType)> patchOutputStreams) @@ -432,6 +432,7 @@ int RequiredLocations(SymbolType type) ScalarType or VectorType => 1, MatrixType m => m.Columns, ArrayType a => a.Size, + _ => throw new NotSupportedException($"Unsupported type for location counting: {type}"), }; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs index 08a2168f1d..0f89884a33 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/LiveAnalysis.cs @@ -29,7 +29,7 @@ internal class LiveAnalysis public MethodInfo GetOrCreateMethodInfo(int functionId) { - if (!ReferencedMethods.TryGetValue(functionId, out MethodInfo methodInfo)) + if (!ReferencedMethods.TryGetValue(functionId, out var methodInfo)) ReferencedMethods.Add(functionId, methodInfo = new MethodInfo()); return methodInfo; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs index f21bad8fa3..09cd9727c0 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Models/ResourceInfo.cs @@ -4,7 +4,7 @@ internal class ResourceInfo(string name) { public string Name { get; } = name; - public ResourceGroup ResourceGroup { get; set; } + public ResourceGroup? ResourceGroup { get; set; } /// /// Used during current stage being processed? @@ -16,10 +16,9 @@ internal class ResourceInfo(string name) public bool UsedAnyStage { get; private set; } } -internal record class ResourceGroup +internal record class ResourceGroup(string Name) { public bool Used { get; set; } - public string Name { get; set; } public string? LogicalGroup { get; set; } public List Resources { get; } = new(); } @@ -28,7 +27,7 @@ internal record class CBufferInfo(string name) { public string Name { get; } = name; - public ResourceGroup ResourceGroup { get; set; } + public ResourceGroup? ResourceGroup { get; set; } public string? LogicalGroup { get; set; } /// diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs index a679828c16..677fca228d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/StreamAccessPatcher.cs @@ -27,6 +27,7 @@ public override SymbolType VisitStreamsType(StreamsType streamsType) StreamsKindSDSL.Input => inputReplacement, StreamsKindSDSL.Output => outputReplacement, StreamsKindSDSL.Constants => constantsReplacement ?? throw new InvalidOperationException(), + _ => throw new NotSupportedException($"Unsupported StreamsKindSDSL value: {streamsType.Kind}"), }; } @@ -91,7 +92,6 @@ void CheckStreamTypes(int id) } } - int parameterIndex = 0; Span tempIdsForStreamCopy = stackalloc int[streams.Values.Count]; for (int index = methodStart; ; ++index) { @@ -135,8 +135,9 @@ void CheckStreamTypes(int id) var streamStructMemberIndex = streamAccessInfo.Kind switch { StreamsKindSDSL.Streams or StreamsKindSDSL.Constants => streamInfo.StreamStructFieldIndex, - StreamsKindSDSL.Input => streamInfo.InputStructFieldIndex.Value, - StreamsKindSDSL.Output => streamInfo.OutputStructFieldIndex.Value, + StreamsKindSDSL.Input => streamInfo.InputStructFieldIndex!.Value, + StreamsKindSDSL.Output => streamInfo.OutputStructFieldIndex!.Value, + _ => throw new NotSupportedException($"Unsupported StreamsKindSDSL value: {streamAccessInfo.Kind}"), }; // TODO: this won't update accessChain.Memory yet but setting accessChain.Base later will fix that diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs index 941f7e8063..9b3c99fe3d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/TypeDuplicatesHelper.cs @@ -49,7 +49,7 @@ public InstructionSortHelper(OpDataIndex i) : this(i.Op, i.Index, i.Data) { } public override string ToString() => Data.Memory != null ? Data.ToString() : $"{Op} Index: {Index}"; } - class OperationComparer(SpirvContext Context, bool UseIndices, TypeDuplicateHelper? Helper = null) : IComparer + class OperationComparer(SpirvContext Context, bool UseIndices) : IComparer { private static int RemapOp(Op op) { @@ -172,11 +172,11 @@ public TypeDuplicateHelper(SpirvContext context) GetTargetList(i.Data).Add(new InstructionSortHelper(i.Op, i.Index, i.Data)); } - comparerSort = new OperationComparer(context, true, this); + comparerSort = new OperationComparer(context, true); namesByOp.Sort(comparerSort); instructionsByOp.Sort(comparerSort); - comparerInsert = new OperationComparer(context, false, this); + comparerInsert = new OperationComparer(context, false); } public OpDataIndex InsertInstruction(int index, OpData data) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs index 4f11e75364..e52939784f 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs @@ -258,13 +258,14 @@ readonly DisWriter AppendResultId(int? id = null) } - private DisWriter AppendPairLiteralIntegerIdRefs(SpvOperand operand) + private readonly DisWriter AppendPairLiteralIntegerIdRefs(SpvOperand operand) { var count = operand.Quantifier switch { OperandQuantifier.One => 1, OperandQuantifier.ZeroOrMore => operand.Words.Length / 2, OperandQuantifier.ZeroOrOne => operand.Words.Length == 0 ? 0 : 1, + _ => throw new NotSupportedException($"Unsupported operand quantifier: {operand.Quantifier}"), }; for (int i = 0; i < count; ++i) @@ -275,13 +276,14 @@ private DisWriter AppendPairLiteralIntegerIdRefs(SpvOperand operand) return this; } - private DisWriter AppendPairIdRefLiteralIntegers(SpvOperand operand) + private readonly DisWriter AppendPairIdRefLiteralIntegers(SpvOperand operand) { var count = operand.Quantifier switch { OperandQuantifier.One => 1, OperandQuantifier.ZeroOrMore => operand.Words.Length / 2, OperandQuantifier.ZeroOrOne => operand.Words.Length == 0 ? 0 : 1, + _ => throw new NotSupportedException($"Unsupported operand quantifier: {operand.Quantifier}"), }; for (int i = 0; i < count; ++i) @@ -387,6 +389,7 @@ or OperandKind.IdMemorySemantics }, OperandKind.PairIdRefLiteralInteger => AppendPairIdRefLiteralIntegers(operand), OperandKind.PairLiteralIntegerIdRef => AppendPairLiteralIntegerIdRefs(operand), + _ => throw new NotImplementedException("Unsupported operand kind " + operand.Kind), }; } AppendLine(""); diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index c263bf4799..b5ca3f5f00 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -1,4 +1,4 @@ - + $(StrideEditorTargetFramework) diff --git a/sources/shaders/Stride.Shaders/EffectValueDescription.cs b/sources/shaders/Stride.Shaders/EffectValueDescription.cs index 27d961a889..df9a51a56d 100644 --- a/sources/shaders/Stride.Shaders/EffectValueDescription.cs +++ b/sources/shaders/Stride.Shaders/EffectValueDescription.cs @@ -1,3 +1,4 @@ +#nullable enable // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. @@ -24,7 +25,7 @@ public struct EffectValueDescription public int Size; - public object DefaultValue; + public object? DefaultValue; - public string LogicalGroup; + public string? LogicalGroup; } diff --git a/sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs b/sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs index 46cbbfa26b..0ba840a2fe 100644 --- a/sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs +++ b/sources/shaders/Stride.Shaders/ShaderMixinObjectId.cs @@ -48,10 +48,7 @@ public static ObjectId Compute(ShaderMixinSource mixin, EffectCompilerParameters { lock (generatorLock) { - if (generator == null) - { - generator = new ShaderMixinObjectId(); - } + generator ??= new ShaderMixinObjectId(); return generator.ComputeInternal(mixin, effectCompilerParameters); } } @@ -68,10 +65,7 @@ public static ObjectId Compute(string effectName, CompilerParameters compilerPar { lock (generatorLock) { - if (generator == null) - { - generator = new ShaderMixinObjectId(); - } + generator ??= new ShaderMixinObjectId(); return generator.ComputeInternal(effectName, compilerParameters); } } @@ -90,7 +84,7 @@ private unsafe ObjectId ComputeInternal(ShaderMixinSource mixin, EffectCompilerP // Compute hash objectIdBuilder.Reset(); - objectIdBuilder.Write((byte*)buffer, (int)memStream.Position); + objectIdBuilder.Write(new ReadOnlySpan((void*)buffer, (int)memStream.Position)); return objectIdBuilder.ComputeHash(); } @@ -111,7 +105,7 @@ private unsafe ObjectId ComputeInternal(string effectName, CompilerParameters co // Compute hash objectIdBuilder.Reset(); - objectIdBuilder.Write((byte*)buffer, (int)memStream.Position); + objectIdBuilder.Write(new ReadOnlySpan((void*)buffer, (int)memStream.Position)); return objectIdBuilder.ComputeHash(); } diff --git a/sources/shared/Stride.Core.ShellHelper/ShellHelper.cs b/sources/shared/Stride.Core.ShellHelper/ShellHelper.cs index a570e88e8e..9b0a5bf55b 100644 --- a/sources/shared/Stride.Core.ShellHelper/ShellHelper.cs +++ b/sources/shared/Stride.Core.ShellHelper/ShellHelper.cs @@ -73,7 +73,8 @@ public static ProcessOutputs RunProcessAndGetOutput(string command, string param RedirectStandardOutput = true, })) { - process.OutputDataReceived += (_, args) => LockProcessAndAddDataToList(process, outputs.OutputLines, args); + // non null (can only happen when opening documents) + process!.OutputDataReceived += (_, args) => LockProcessAndAddDataToList(process, outputs.OutputLines, args); process.ErrorDataReceived += (_, args) => LockProcessAndAddDataToList(process, outputs.OutputErrors, args); process.BeginOutputReadLine(); process.BeginErrorReadLine(); @@ -99,7 +100,7 @@ public static Process RunProcess(string command, string parameters) CreateNoWindow = true, RedirectStandardError = true, RedirectStandardOutput = true, - }); + })!; // non null (can only happen when opening documents) } public static int RunProcessAndRedirectToLogger(string command, string parameters, string workingDirectory, LoggerResult logger) { From 36a885209002efab58cd2456e654918b24928402 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Mar 2026 16:45:41 +0900 Subject: [PATCH 1018/1182] SDSL: Prevent RenderingTests to run in parallel --- sources/shaders/Stride.Shaders.Tests/D3D11Collection.cs | 4 ++++ sources/shaders/Stride.Shaders.Tests/RenderingTests.cs | 1 + 2 files changed, 5 insertions(+) create mode 100644 sources/shaders/Stride.Shaders.Tests/D3D11Collection.cs diff --git a/sources/shaders/Stride.Shaders.Tests/D3D11Collection.cs b/sources/shaders/Stride.Shaders.Tests/D3D11Collection.cs new file mode 100644 index 0000000000..98812a7aea --- /dev/null +++ b/sources/shaders/Stride.Shaders.Tests/D3D11Collection.cs @@ -0,0 +1,4 @@ +namespace Stride.Shaders.Parsers.Tests; + +[CollectionDefinition("D3D11", DisableParallelization = true)] +public class D3D11Collection; diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 2dd93933a6..d07c7c8fab 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -22,6 +22,7 @@ namespace Stride.Shaders.Parsers.Tests; +[Collection("D3D11")] public partial class RenderingTests { static int width = 1; From 5c930f35b85baf2de1d78a407a4f0bccdf6faaa4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Mar 2026 17:58:17 +0900 Subject: [PATCH 1019/1182] SDSL: Fix non-pointer array indexing in OpAccessChain --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 76ebd0a3a1..77cb731f96 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1330,8 +1330,10 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso // We need to load as a variable to use OpAccessChain var (builder, context) = compiler; - var functionVariable = builder.AddFunctionVariable(context.GetOrRegister(new PointerType(currentValueType, Specification.StorageClass.Function)), context.Bound++); + var ptrType = context.GetOrRegister(new PointerType(currentValueType, Specification.StorageClass.Function)); + var functionVariable = builder.AddFunctionVariable(ptrType, context.Bound++); builder.Insert(new OpStore(functionVariable, result.Id, null, [])); + result = new SpirvValue(functionVariable, ptrType); // Process again the same item with new type var indexerValue = indexer.Index.CompileAsValue(table, compiler); PushAccessChainId(accessChainIds, indexerValue.Id); From bfdbcb356c640915c833e68c0e0a8dd7043c64a8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Mar 2026 19:21:51 +0900 Subject: [PATCH 1020/1182] SDSL: Don't emit Flat decoration on vertex inputs and fragment outputs --- .../Spirv/Processing/Interfaces/InterfaceProcessor.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 81e0166751..b91f8153f5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -460,7 +460,9 @@ int RequiredLocations(SymbolType type) var variable = context.Add(new OpVariable(context.GetOrRegister(streamInputType), variableId, Specification.StorageClass.Input, null)); context.AddName(variable, $"in_{stage}_{stream.Value.Name}"); - if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) + // Flat is required for non-floating-point interpolation, but not valid on vertex shader inputs + if (executionModel != ExecutionModel.Vertex + && stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); if (stream.Value.Patch) @@ -496,7 +498,9 @@ int RequiredLocations(SymbolType type) var variable = context.Add(new OpVariable(context.GetOrRegister(streamOutputType), variableId, Specification.StorageClass.Output, null)); context.AddName(variable, $"out_{stage}_{stream.Value.Name}"); - if (stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) + // Flat is required for non-floating-point interpolation, but not valid on fragment shader outputs + if (executionModel != ExecutionModel.Fragment + && stream.Value.Type is ScalarType or VectorType or MatrixType && !stream.Value.Type.GetElementType().IsFloating()) context.Add(new OpDecorate(variable, Decoration.Flat, [])); if (stream.Value.Patch) From 916e4042d57d0dd121a5572cf6f6899adda89101 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 28 Mar 2026 22:23:39 +0900 Subject: [PATCH 1021/1182] SDSL: Thread SymbolTable+TextLocation through intrinsic compiler, fix texture sample offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add SymbolTable and TextLocation parameters to IIntrinsicCompiler and all generated Compile* methods so intrinsic implementations can report errors with source location context - Replace throw in TextureGenerateImageOperands with table.AddError() for non-constant texture sample offsets - Fold negative literals at parse time (-1 → IntegerLiteral(-1)) instead of emitting OpSNegate, so TryPromoteToConstant works for int2(0, -1) offsets - Extend TryPromoteToConstant to recursively promote constituents - Add negative offset test cases to TextureSampleLevelOffset render test --- .../IntrinsicGenerator.cs | 10 +- ...dStructuredBufferMethodsImplementations.cs | 8 +- .../SDSL/AST/BufferMethodsImplementations.cs | 5 +- ...ByteAddressBufferMethodsImplementations.cs | 53 +-- .../Parsing/SDSL/AST/Expression.cs | 6 +- .../Parsing/SDSL/AST/IntrinsicCall.cs | 24 +- .../SDSL/AST/IntrinsicImplementations.cs | 435 +++++++++--------- .../SDSL/AST/TextureMethodsImplementations.cs | 152 +++--- .../ExpressionParsers/UnaryParsers.Prefix.cs | 12 + .../RenderTests/TextureSampleLevelOffset.sdsl | 19 +- 10 files changed, 379 insertions(+), 345 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index 8f341c5b73..298507b3cc 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -150,12 +150,12 @@ namespace Stride.Shaders.Parsing.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using Stride.Shaders.Parsing.Analysis; - + """); builder.AppendLine("public interface IIntrinsicCompiler"); builder.AppendLine("{"); - builder.AppendLine(" SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams);"); + builder.AppendLine(" SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams, TextLocation location);"); builder.AppendLine("}"); static string IntrinsicDeclarationKey(NamespaceDeclaration arg) @@ -245,10 +245,10 @@ static string NormalizeParameters(string @namespace, string methodName, string p var mandatoryParameters = intrinsicGroup.Value.MandatoryParameters; var optionalParameters = intrinsicGroup.Value.OptionalParameters; - builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SpirvContext context, SpirvBuilder builder, FunctionType functionType{thisParam}{GenerateParameters(mandatoryParameters)}{GenerateParameters(optionalParameters, true)}) => throw new NotImplementedException();"); + builder.AppendLine($"public virtual SpirvValue Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType{thisParam}{GenerateParameters(mandatoryParameters)}{GenerateParameters(optionalParameters, true)}, TextLocation location = default) => throw new NotImplementedException();"); } - builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams) {"); + builder.AppendLine("public SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, string? @namespace, string name, FunctionType functionType, SpirvValue? thisValue, Span compiledParams, TextLocation location) {"); builder.AppendLine("var (builder, context) = compiler;"); builder.AppendLine("return (@namespace, name, compiledParams.Length) switch {"); foreach (var intrinsicGroup in intrinsicGroups) @@ -290,7 +290,7 @@ static string NormalizeParameters(string @namespace, string methodName, string p builder.Append(" ScalarType"); } - builder.AppendLine($" => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}),"); + builder.AppendLine($" => Compile{CapitalizeFirstLetter(intrinsicGroup.Key)}(table, context, builder, functionType{thisArg}{GenerateArguments(mandatoryParameters)}{GenerateArguments(optionalParameters, true, mandatoryParameters.Count)}, location: location),"); } } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs index 82282006ad..5625e50ad8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs @@ -12,7 +12,7 @@ public class AppendStructuredBufferMethodsImplementations : AppendStructuredBuff { public static AppendStructuredBufferMethodsImplementations Instance { get; } = new(); - public override SpirvValue CompileAppend(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue value) + public override SpirvValue CompileAppend(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue value, TextLocation location = default) { // Buffer struct is { T[] }, member 0 is the runtime array // We write to element 0 as a placeholder (no atomic counter implemented) @@ -24,7 +24,7 @@ public override SpirvValue CompileAppend(SpirvContext context, SpirvBuilder buil return default; } - public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue count, SpirvValue stride) + public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue appendStructuredBuffer, SpirvValue count, SpirvValue stride, TextLocation location = default) { var uintType = context.GetOrRegister(ScalarType.UInt); var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, appendStructuredBuffer.Id, 0)); @@ -41,7 +41,7 @@ public class ConsumeStructuredBufferMethodsImplementations : ConsumeStructuredBu { public static ConsumeStructuredBufferMethodsImplementations Instance { get; } = new(); - public override SpirvValue CompileConsume(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer) + public override SpirvValue CompileConsume(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer, TextLocation location = default) { // Read from element 0 as a placeholder (no atomic counter implemented) var const0 = context.CompileConstant((int)0); @@ -52,7 +52,7 @@ public override SpirvValue CompileConsume(SpirvContext context, SpirvBuilder bui return new(loadResult.ResultId, loadResult.ResultType); } - public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer, SpirvValue count, SpirvValue stride) + public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue consumeStructuredBuffer, SpirvValue count, SpirvValue stride, TextLocation location = default) { var uintType = context.GetOrRegister(ScalarType.UInt); var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, consumeStructuredBuffer.Id, 0)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs index 21dd1d083d..3d41180fe7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/BufferMethodsImplementations.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -8,7 +9,7 @@ public class BufferMethodsImplementations : BufferMethodsDeclarations { public static BufferMethodsImplementations Instance { get; } = new(); - public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue x, SpirvValue? status = null) + public override SpirvValue CompileLoad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue x, SpirvValue? status = null, TextLocation location = default) { var bufferType = (BufferType)context.ReverseTypes[buffer.TypeId]; var resultTypeId = context.GetOrRegister(functionType.ReturnType); @@ -24,7 +25,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde } } - public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue width) + public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue buffer, SpirvValue width, TextLocation location = default) { var uintType = context.GetOrRegister(ScalarType.UInt); var sizeResult = builder.Insert(new OpImageQuerySize(uintType, context.Bound++, buffer.Id)); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs index 349bd69659..6b301bcf66 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ByteAddressBufferMethodsImplementations.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; using static Stride.Shaders.Spirv.Specification; @@ -49,7 +50,7 @@ private SpirvValue AccessChainAtByteOffsetPlus(SpirvContext context, SpirvBuilde } // Load(uint byteOffset) -> uint - public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + public override SpirvValue CompileLoad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); @@ -70,33 +71,33 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde } // Load2(uint byteOffset) -> uint2 - public override SpirvValue CompileLoad2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + public override SpirvValue CompileLoad2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); - return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 2); + return LoadN(table, context, builder, functionType, byteAddressBuffer, byteOffset, 2); } // Load3(uint byteOffset) -> uint3 - public override SpirvValue CompileLoad3(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + public override SpirvValue CompileLoad3(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); - return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 3); + return LoadN(table, context, builder, functionType, byteAddressBuffer, byteOffset, 3); } // Load4(uint byteOffset) -> uint4 - public override SpirvValue CompileLoad4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null) + public override SpirvValue CompileLoad4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException("Load with status is not yet supported for ByteAddressBuffer"); - return LoadN(context, builder, functionType, byteAddressBuffer, byteOffset, 4); + return LoadN(table, context, builder, functionType, byteAddressBuffer, byteOffset, 4); } - private SpirvValue LoadN(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue bufferPtr, SpirvValue byteOffset, int count) + private SpirvValue LoadN(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue bufferPtr, SpirvValue byteOffset, int count) { var uintType = context.GetOrRegister(ScalarType.UInt); Span values = stackalloc int[count]; @@ -112,7 +113,7 @@ private SpirvValue LoadN(SpirvContext context, SpirvBuilder builder, FunctionTyp } // Store(uint byteOffset, T value) - public override SpirvValue CompileStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + public override SpirvValue CompileStore(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, TextLocation location = default) { // If the value is not uint, bitcast to uint first var valueType = context.ReverseTypes[value.TypeId]; @@ -128,27 +129,27 @@ public override SpirvValue CompileStore(SpirvContext context, SpirvBuilder build } // Store2(uint byteOffset, uint2 value) - public override SpirvValue CompileStore2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + public override SpirvValue CompileStore2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, TextLocation location = default) { - StoreN(context, builder, byteAddressBuffer, byteOffset, value, 2); + StoreN(table, context, builder, byteAddressBuffer, byteOffset, value, 2); return default; } // Store3(uint byteOffset, uint3 value) - public override SpirvValue CompileStore3(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + public override SpirvValue CompileStore3(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, TextLocation location = default) { - StoreN(context, builder, byteAddressBuffer, byteOffset, value, 3); + StoreN(table, context, builder, byteAddressBuffer, byteOffset, value, 3); return default; } // Store4(uint byteOffset, uint4 value) - public override SpirvValue CompileStore4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value) + public override SpirvValue CompileStore4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, TextLocation location = default) { - StoreN(context, builder, byteAddressBuffer, byteOffset, value, 4); + StoreN(table, context, builder, byteAddressBuffer, byteOffset, value, 4); return default; } - private void StoreN(SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset, SpirvValue value, int count) + private void StoreN(SymbolTable table, SpirvContext context, SpirvBuilder builder, SpirvValue bufferPtr, SpirvValue byteOffset, SpirvValue value, int count) { var uintType = context.GetOrRegister(ScalarType.UInt); for (int i = 0; i < count; i++) @@ -160,7 +161,7 @@ private void StoreN(SpirvContext context, SpirvBuilder builder, SpirvValue buffe } // GetDimensions(out uint width) - returns buffer size in bytes - public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue width) + public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue width, TextLocation location = default) { var uintType = context.GetOrRegister(ScalarType.UInt); // OpArrayLength returns number of elements in the runtime array (member 0) @@ -174,49 +175,49 @@ public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuild } // InterlockedAdd(uint byteOffset, uint value [, out uint original]) - public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedAdd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Add); } // InterlockedMin(uint byteOffset, uint/int value [, out uint original]) - public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.UMin); } // InterlockedMax(uint byteOffset, uint/int value [, out uint original]) - public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.UMax); } // InterlockedAnd(uint byteOffset, uint value [, out uint original]) - public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.And); } // InterlockedOr(uint byteOffset, uint value [, out uint original]) - public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Or); } // InterlockedXor(uint byteOffset, uint value [, out uint original]) - public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null) + public override SpirvValue CompileInterlockedXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue? original = null, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Xor); } // InterlockedExchange(uint byteOffset, uint value, out uint original) - public override SpirvValue CompileInterlockedExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue original) + public override SpirvValue CompileInterlockedExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue value, SpirvValue original, TextLocation location = default) { return CompileAtomicOp(context, builder, byteAddressBuffer, byteOffset, value, original, AtomicOp.Exchange); } // InterlockedCompareStore(uint byteOffset, uint compare, uint value) - public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value) + public override SpirvValue CompileInterlockedCompareStore(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value, TextLocation location = default) { var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); var uintType = context.GetOrRegister(ScalarType.UInt); @@ -228,7 +229,7 @@ public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, } // InterlockedCompareExchange(uint byteOffset, uint compare, uint value, out uint original) - public override SpirvValue CompileInterlockedCompareExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value, SpirvValue original) + public override SpirvValue CompileInterlockedCompareExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue byteAddressBuffer, SpirvValue byteOffset, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) { var ptr = AccessChainAtByteOffset(context, builder, byteAddressBuffer, byteOffset); var uintType = context.GetOrRegister(ScalarType.UInt); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 77cb731f96..4f6efa03dd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -215,7 +215,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) SpirvValue? @this = MemberCall != null ? (MemberCallBaseType is ByteAddressBufferType ? MemberCall.Value : builder.AsValue(context, MemberCall.Value)) : null; - result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler!, resolvedIntrinsicNamespace!, Name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams); + result = IntrinsicCallHelper.CompileIntrinsic(table, compiler, resolvedIntrinsicCompiler!, resolvedIntrinsicNamespace!, Name.Name, resolvedIntrinsicOverload.Value, @this, compiledParams, Info); } else { @@ -953,7 +953,7 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso indexValue = builder.Convert(context, indexValue, texcoordType); } - result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, builder.AsValue(context, result), [indexValue.Id]); + result = resolvedIntrinsic.Compiler.CompileIntrinsic(table, compiler, resolvedIntrinsic.Namespace, "Load", resolvedIntrinsic.Overload.Type, builder.AsValue(context, result), [indexValue.Id], Info); accessor.Type = resolvedIntrinsic.Overload.Type.ReturnType; break; @@ -1414,7 +1414,7 @@ private void TextureGenerateImageOperands(SpirvValue? lod, SpirvValue? offset, S } if (offset != null) { - imask |= ImageOperandsMask.Offset; + imask |= ImageOperandsMask.ConstOffset; operands[operandCount++] = offset.Value.Id; } if (sampleIndex != null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs index a389a4b4ab..4abb894c27 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicCall.cs @@ -99,7 +99,7 @@ static IntrinsicTemplateExpander GetOrCreateExpander(SymbolType type, string @na return true; } - public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, IIntrinsicCompiler intrinsicCompiler, string @namespace, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, SpirvValue? thisValue, Span compiledParams) + public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compiler, IIntrinsicCompiler intrinsicCompiler, string @namespace, string name, IntrinsicTemplateExpander.IntrinsicOverload bestOverload, SpirvValue? thisValue, Span compiledParams, TextLocation location) { var functionType = bestOverload.Type; @@ -116,13 +116,13 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil Span vectorValues = stackalloc int[bestOverload.AutoMatrixLoopLocations.Count * bestOverload.AutoMatrixLoopSize]; for (var index = 0; index < bestOverload.AutoMatrixLoopLocations.Count; index++) { - var location = bestOverload.AutoMatrixLoopLocations[index]; + var loopLocation = bestOverload.AutoMatrixLoopLocations[index]; - if (location.TemplateIndex != 0) + if (loopLocation.TemplateIndex != 0) throw new InvalidOperationException("Matrix loop should only be generated for HLSL row parameter"); // Skip return type for now - if (location.SourceArgument == 0) + if (loopLocation.SourceArgument == 0) { var returnType = (MatrixType)functionType.ReturnType; innerFunctionType = innerFunctionType with @@ -133,14 +133,14 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil continue; } - var parameterType = (MatrixType)functionType.ParameterTypes[location.SourceArgument - 1].Type; + var parameterType = (MatrixType)functionType.ParameterTypes[loopLocation.SourceArgument - 1].Type; var vectorType = new VectorType(parameterType.BaseType, parameterType.Rows); for (int col = 0; col < bestOverload.AutoMatrixLoopSize; col++) { - vectorValues[index * bestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[location.SourceArgument - 1], [col])).ResultId; + vectorValues[index * bestOverload.AutoMatrixLoopSize + col] = builder.Insert(new OpCompositeExtract(context.GetOrRegister(vectorType), context.Bound++, compiledParams[loopLocation.SourceArgument - 1], [col])).ResultId; } - innerFunctionType.ParameterTypes[location.SourceArgument - 1] = innerFunctionType.ParameterTypes[location.SourceArgument - 1] with { Type = vectorType }; + innerFunctionType.ParameterTypes[loopLocation.SourceArgument - 1] = innerFunctionType.ParameterTypes[loopLocation.SourceArgument - 1] with { Type = vectorType }; } // Call core function @@ -149,13 +149,13 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil { for (var index = 0; index < bestOverload.AutoMatrixLoopLocations.Count; index++) { - var location = bestOverload.AutoMatrixLoopLocations[index]; - if (location.SourceArgument == 0) + var loopLocation = bestOverload.AutoMatrixLoopLocations[index]; + if (loopLocation.SourceArgument == 0) continue; - compiledParams[location.SourceArgument - 1] = vectorValues[index * bestOverload.AutoMatrixLoopSize + col]; + compiledParams[loopLocation.SourceArgument - 1] = vectorValues[index * bestOverload.AutoMatrixLoopSize + col]; } - results[col] = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, innerFunctionType, thisValue, compiledParams).Id; + results[col] = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, innerFunctionType, thisValue, compiledParams, location).Id; } // Rebuild return value @@ -174,7 +174,7 @@ public static SpirvValue CompileIntrinsic(SymbolTable table, CompilerUnit compil else { // No auto matrix loop - result = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, functionType, thisValue, compiledParams); + result = intrinsicCompiler.CompileIntrinsic(table, compiler, @namespace, name, functionType, thisValue, compiledParams, location); } return result; diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index e5bcfd7cd3..f2571f5458 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -10,20 +11,20 @@ internal class IntrinsicImplementations : IntrinsicsDeclarations public static IntrinsicImplementations Instance { get; } = new(); // Bool - public override SpirvValue CompileAll(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAll); - public override SpirvValue CompileAny(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBoolToScalarBoolCall(context, builder, functionType, x, Specification.Op.OpAny); + public override SpirvValue CompileAll(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType, x, Specification.Op.OpAll); + public override SpirvValue CompileAny(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType, x, Specification.Op.OpAny); // Cast - public override SpirvValue CompileAsfloat(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsuint(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue? d = null, SpirvValue? x = null, SpirvValue? y = null) + public override SpirvValue CompileAsfloat(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsint(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsuint(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue? d = null, SpirvValue? x = null, SpirvValue? y = null, TextLocation location = default) { if (d == null && y == null) - return CompileBitcastCall(context, builder, functionType, x!.Value); + return CompileBitcastCall(table, context, builder, functionType, x!.Value); throw new NotImplementedException(); } - public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) + public override SpirvValue CompileAsdouble(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) { // asdouble(uint, uint) -> double OR asdouble(uint2, uint2) -> double2 // Each pair of uints is packed into uint2 then bitcast to double @@ -53,42 +54,42 @@ public override SpirvValue CompileAsdouble(SpirvContext context, SpirvBuilder bu } throw new InvalidOperationException($"Unexpected type {inputType} for asdouble"); } - public override SpirvValue CompileAsfloat16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); - public override SpirvValue CompileAsuint16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileBitcastCall(context, builder, functionType, x); + public override SpirvValue CompileAsfloat16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsuint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); // Trigo - public override SpirvValue CompileSin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); - public override SpirvValue CompileSinh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); - public override SpirvValue CompileAsin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); - public override SpirvValue CompileCos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); - public override SpirvValue CompileCosh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); - public override SpirvValue CompileAcos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); - public override SpirvValue CompileTan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTan, x); - public override SpirvValue CompileTanh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); - public override SpirvValue CompileAtan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); - public override SpirvValue CompileAtan2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); - public override SpirvValue CompileSincos(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c) + public override SpirvValue CompileSin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSin, x); + public override SpirvValue CompileSinh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); + public override SpirvValue CompileAsin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); + public override SpirvValue CompileCos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + public override SpirvValue CompileCosh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); + public override SpirvValue CompileAcos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); + public override SpirvValue CompileTan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTan, x); + public override SpirvValue CompileTanh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); + public override SpirvValue CompileAtan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); + public override SpirvValue CompileAtan2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); + public override SpirvValue CompileSincos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c, TextLocation location = default) { // sincos(x, out s, out c): compute sin and cos separately, store to out params - var sinVal = CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSin, x); - var cosVal = CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + var sinVal = CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSin, x); + var cosVal = CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCos, x); builder.Insert(new OpStore(s.Id, sinVal.Id, null, [])); builder.Insert(new OpStore(c.Id, cosVal.Id, null, [])); return new(); } // Derivatives - public override SpirvValue CompileDdx(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdx, x); - public override SpirvValue CompileDdx_coarse(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdxCoarse, x); - public override SpirvValue CompileDdx_fine(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdxFine, x); - public override SpirvValue CompileDdy(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdy, x); - public override SpirvValue CompileDdy_coarse(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdyCoarse, x); - public override SpirvValue CompileDdy_fine(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpDPdyFine, x); - public override SpirvValue CompileFwidth(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpFwidth, x); + public override SpirvValue CompileDdx(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdx, x); + public override SpirvValue CompileDdx_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdxCoarse, x); + public override SpirvValue CompileDdx_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdxFine, x); + public override SpirvValue CompileDdy(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdy, x); + public override SpirvValue CompileDdy_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdyCoarse, x); + public override SpirvValue CompileDdy_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdyFine, x); + public override SpirvValue CompileFwidth(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpFwidth, x); // Per component math - public override SpirvValue CompileAbs(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileAbs(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch { @@ -98,10 +99,10 @@ public override SpirvValue CompileAbs(SpirvContext context, SpirvBuilder builder }; return new(instruction); } - public override SpirvValue CompileFloor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFloor, x); - public override SpirvValue CompileCeil(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCeil, x); - public override SpirvValue CompileTrunc(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLTrunc, x); - public override SpirvValue CompileMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileFloor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFloor, x); + public override SpirvValue CompileCeil(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCeil, x); + public override SpirvValue CompileTrunc(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTrunc, x); + public override SpirvValue CompileMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch { @@ -113,7 +114,7 @@ public override SpirvValue CompileMin(SpirvContext context, SpirvBuilder builder return new(instruction); } - public override SpirvValue CompileMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch { @@ -125,7 +126,7 @@ public override SpirvValue CompileMax(SpirvContext context, SpirvBuilder builder return new(instruction); } - public override SpirvValue CompileClamp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue min, SpirvValue max) + public override SpirvValue CompileClamp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue min, SpirvValue max, TextLocation location = default) { var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch { @@ -137,48 +138,48 @@ public override SpirvValue CompileClamp(SpirvContext context, SpirvBuilder build return new(instruction); } - public override SpirvValue CompileRadians(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRadians, x); - public override SpirvValue CompileDegrees(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLDegrees, x); + public override SpirvValue CompileRadians(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLRadians, x); + public override SpirvValue CompileDegrees(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLDegrees, x); - public override SpirvValue CompileExp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp, x); - public override SpirvValue CompileExp2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLExp2, x); - public override SpirvValue CompileLog(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog, x); - public override SpirvValue CompileLog10(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => MultiplyConstant(context, builder, functionType, CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog2, x), (float)Math.Log10(2.0)); - public override SpirvValue CompileLog2(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLLog2, x); - public override SpirvValue CompilePow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLPow, x, y); + public override SpirvValue CompileExp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLExp, x); + public override SpirvValue CompileExp2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLExp2, x); + public override SpirvValue CompileLog(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog, x); + public override SpirvValue CompileLog10(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => MultiplyConstant(table, context, builder, functionType, CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog2, x), (float)Math.Log10(2.0)); + public override SpirvValue CompileLog2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog2, x); + public override SpirvValue CompilePow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLPow, x, y); // Vector math - public override SpirvValue CompileDistance(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileDistance(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = builder.Insert(new GLSLDistance(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileDot(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileDot(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = builder.Insert(new OpDot(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileCross(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLCross, a, b); + public override SpirvValue CompileCross(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCross, a, b); - public override SpirvValue CompileDeterminant(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileDeterminant(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var instruction = builder.Insert(new GLSLDeterminant(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileLength(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileLength(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var instruction = builder.Insert(new GLSLLength(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileNormalize(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileNormalize(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var instruction = builder.Insert(new GLSLNormalize(x.TypeId, context.Bound++, context.GetGLSL(), x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileMul(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileMul(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { // Version on https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-mul // Note: SPIR-V and HLSL have opposite meaning for Rows/Columns and multiplication order need to be swapped @@ -204,28 +205,28 @@ public override SpirvValue CompileMul(SpirvContext context, SpirvBuilder builder return new SpirvValue(result); } - public override SpirvValue CompileReflect(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n) + public override SpirvValue CompileReflect(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n, TextLocation location = default) { var instruction = builder.Insert(new GLSLReflect(i.TypeId, context.Bound++, context.GetGLSL(), i.Id, n.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileRefract(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n, SpirvValue ri) + public override SpirvValue CompileRefract(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue i, SpirvValue n, SpirvValue ri, TextLocation location = default) { var instruction = builder.Insert(new GLSLRefract(i.TypeId, context.Bound++, context.GetGLSL(), i.Id, n.Id, ri.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileFaceforward(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue N, SpirvValue I, SpirvValue Ng) + public override SpirvValue CompileFaceforward(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue N, SpirvValue I, SpirvValue Ng, TextLocation location = default) { var instruction = builder.Insert(new GLSLFaceForward(N.TypeId, context.Bound++, context.GetGLSL(), N.Id, I.Id, Ng.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileRound(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLRound, x); - public override SpirvValue CompileRsqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLInverseSqrt, x); - public override SpirvValue CompileSqrt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLSqrt, x); - public override SpirvValue CompileStep(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue x) => CompileGLSLFloatBinaryCall(context, builder, functionType, Specification.GLSLOp.GLSLStep, a, x); - public override SpirvValue CompileSaturate(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileRound(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLRound, x); + public override SpirvValue CompileRsqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLInverseSqrt, x); + public override SpirvValue CompileSqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSqrt, x); + public override SpirvValue CompileStep(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue x, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLStep, a, x); + public override SpirvValue CompileSaturate(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // Ensure 0.0 amd 1.0 constants have same type as x var constant0 = builder.Convert(context, context.CompileConstant(0.0f), functionType.ReturnType); @@ -240,7 +241,7 @@ public override SpirvValue CompileSaturate(SpirvContext context, SpirvBuilder bu }; return new(instruction); } - public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileSign(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var sourceType = context.ReverseTypes[x.TypeId]; var instruction = sourceType.GetElementType() switch @@ -253,80 +254,80 @@ public override SpirvValue CompileSign(SpirvContext context, SpirvBuilder builde return builder.Convert(context, new(instruction), functionType.ReturnType); } - public override SpirvValue CompileSmoothstep(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue x) + public override SpirvValue CompileSmoothstep(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue x, TextLocation location = default) { var instruction = builder.Insert(new GLSLSmoothStep(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileLerp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue s) + public override SpirvValue CompileLerp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue s, TextLocation location = default) { var instruction = builder.Insert(new GLSLFMix(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, s.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileFmod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) + public override SpirvValue CompileFmod(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = builder.Insert(new OpFRem(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileFrac(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFract, x); + public override SpirvValue CompileFrac(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFract, x); - public override SpirvValue CompileRcp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileRcp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var constant1 = builder.Convert(context, context.CompileConstant(1.0f), functionType.ReturnType); var instruction = builder.Insert(new OpFDiv(context.GetOrRegister(functionType.ReturnType), context.Bound++, constant1.Id, x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileMad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) + public override SpirvValue CompileMad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c, TextLocation location = default) { var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, c.Id)); return new(instruction.ResultId, instruction.ResultType); } // Float checks - public override SpirvValue CompileIsnan(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsNan, x); - public override SpirvValue CompileIsinf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpIsInf, x); + public override SpirvValue CompileIsnan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpIsNan, x); + public override SpirvValue CompileIsinf(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpIsInf, x); // Bit operations - public override SpirvValue CompileCountbits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileFloatUnaryCall(context, builder, functionType, Specification.Op.OpBitCount, x); - public override SpirvValue CompileFirstbithigh(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileCountbits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpBitCount, x); + public override SpirvValue CompileFirstbithigh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var op = context.ReverseTypes[x.TypeId].GetElementType() switch { ScalarType { Type: Scalar.UInt } => Specification.GLSLOp.GLSLFindUMsb, _ => Specification.GLSLOp.GLSLFindSMsb, }; - return CompileGLSLFloatUnaryCall(context, builder, functionType, op, x); + return CompileGLSLFloatUnaryCall(table, context, builder, functionType, op, x); } // Compute Barriers const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask GroupMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.AcquireRelease; - public override SpirvValue CompileAllMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileAllMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileDeviceMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileGroupMemoryBarrier(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileMemoryBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => CompileControlBarrierCall(context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileAllMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileAllMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); // Compute interlocked - public override SpirvValue CompileInterlockedAdd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Add, result, value, original); - public override SpirvValue CompileInterlockedMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Min, result, value, original); - public override SpirvValue CompileInterlockedMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Max, result, value, original); - public override SpirvValue CompileInterlockedAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.And, result, value, original); - public override SpirvValue CompileInterlockedOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Or, result, value, original); - public override SpirvValue CompileInterlockedXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Xor, result, value, original); - public override SpirvValue CompileInterlockedExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.Exchange, result, value, original); - public override SpirvValue CompileInterlockedCompareStore(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareStore, result, value, null, compare); - public override SpirvValue CompileInterlockedCompareExchange(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => CompileInterlockedCall(context, builder, functionType, InterlockedOp.CompareExchange, result, value, original, compare); - public override SpirvValue CompileInterlockedCompareStoreFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileInterlockedCompareExchangeFloatBitwise(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original) => throw new NotImplementedException(); + public override SpirvValue CompileInterlockedAdd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Add, result, value, original); + public override SpirvValue CompileInterlockedMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Min, result, value, original); + public override SpirvValue CompileInterlockedMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Max, result, value, original); + public override SpirvValue CompileInterlockedAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.And, result, value, original); + public override SpirvValue CompileInterlockedOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Or, result, value, original); + public override SpirvValue CompileInterlockedXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Xor, result, value, original); + public override SpirvValue CompileInterlockedExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Exchange, result, value, original); + public override SpirvValue CompileInterlockedCompareStore(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.CompareStore, result, value, null, compare); + public override SpirvValue CompileInterlockedCompareExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.CompareExchange, result, value, original, compare); + public override SpirvValue CompileInterlockedCompareStoreFloatBitwise(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileInterlockedCompareExchangeFloatBitwise(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) => throw new NotImplementedException(); // Misc - public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileClip(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // clip(x) discards the pixel if any component of x is less than zero. // Equivalent to: if (any(x < 0)) discard; @@ -364,20 +365,20 @@ public override SpirvValue CompileClip(SpirvContext context, SpirvBuilder builde return new(); } - public override SpirvValue CompileAbort(SpirvContext context, SpirvBuilder builder, FunctionType functionType) + public override SpirvValue CompileAbort(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) { builder.Insert(new OpTerminateInvocation()); return new(); } - public override SpirvValue CompileD3DCOLORtoUBYTE4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileGetRenderTargetSampleCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileGetRenderTargetSamplePosition(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s) => throw new NotImplementedException(); - public override SpirvValue CompileEvaluateAttributeAtSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue index) => throw new NotImplementedException(); - public override SpirvValue CompileEvaluateAttributeCentroid(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileEvaluateAttributeSnapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset) => throw new NotImplementedException(); - public override SpirvValue CompileGetAttributeAtVertex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue VertexID) => throw new NotImplementedException(); - public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileD3DCOLORtoUBYTE4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGetRenderTargetSampleCount(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGetRenderTargetSamplePosition(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeAtSample(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue index, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeCentroid(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileEvaluateAttributeSnapped(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue offset, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGetAttributeAtVertex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue VertexID, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileF16tof32(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // f16tof32(uint) -> float: UnpackHalf2x16 returns float2, extract .x // For vector variants: decompose, apply per-element, recompose @@ -414,7 +415,7 @@ public override SpirvValue CompileF16tof32(SpirvContext context, SpirvBuilder bu } throw new InvalidOperationException($"Unexpected type {inputType} for f16tof32"); } - public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileF32tof16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // f32tof16(float) -> uint: PackHalf2x16(float2(x, 0.0)) -> uint // For vector variants: decompose, apply per-element, recompose @@ -453,18 +454,18 @@ public override SpirvValue CompileF32tof16(SpirvContext context, SpirvBuilder bu } throw new InvalidOperationException($"Unexpected type {inputType} for f32tof16"); } - public override SpirvValue CompileFirstbitlow(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => CompileGLSLFloatUnaryCall(context, builder, functionType, Specification.GLSLOp.GLSLFindILsb, x); - public override SpirvValue CompileFma(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c) + public override SpirvValue CompileFirstbitlow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFindILsb, x); + public override SpirvValue CompileFma(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c, TextLocation location = default) { var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, c.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileFrexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) + public override SpirvValue CompileFrexp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp, TextLocation location = default) { var instruction = builder.Insert(new GLSLFrexp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, exp.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileIsfinite(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // isfinite(x) = !(isinf(x) || isnan(x)) var boolType = context.GetOrRegister(functionType.ReturnType); @@ -474,127 +475,127 @@ public override SpirvValue CompileIsfinite(SpirvContext context, SpirvBuilder bu var result = builder.Insert(new OpLogicalNot(boolType, context.Bound++, infOrNan.ResultId)); return new(result.ResultId, result.ResultType); } - public override SpirvValue CompileIsnormal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileLdexp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp) => throw new NotImplementedException(); - public override SpirvValue CompileLit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m) => throw new NotImplementedException(); - public override SpirvValue CompileModf(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue ip) => throw new NotImplementedException(); - public override SpirvValue CompileMsad4(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue reference, SpirvValue source, SpirvValue accum) => throw new NotImplementedException(); - public override SpirvValue CompileProcess2DQuadTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcess2DQuadTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcess2DQuadTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcessIsolineTessFactors(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawDetailFactor, SpirvValue RawDensityFactor, SpirvValue RoundedDetailFactorr, SpirvValue RoundedDensityFactor) => throw new NotImplementedException(); - public override SpirvValue CompileProcessQuadTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcessQuadTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcessQuadTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors) => throw new NotImplementedException(); - public override SpirvValue CompileProcessTriTessFactorsAvg(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); - public override SpirvValue CompileProcessTriTessFactorsMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); - public override SpirvValue CompileProcessTriTessFactorsMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor) => throw new NotImplementedException(); - public override SpirvValue CompileReversebits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileSource_mark(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileTranspose(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public override SpirvValue CompileIsnormal(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileLdexp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue exp, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileLit(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue l, SpirvValue h, SpirvValue m, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileModf(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue ip, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileMsad4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue reference, SpirvValue source, SpirvValue accum, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsAvg(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcess2DQuadTessFactorsMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessIsolineTessFactors(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawDetailFactor, SpirvValue RawDensityFactor, SpirvValue RoundedDetailFactorr, SpirvValue RoundedDensityFactor, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsAvg(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessQuadTessFactorsMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactors, SpirvValue UnroundedInsideFactors, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsAvg(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileProcessTriTessFactorsMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue RawEdgeFactors, SpirvValue InsideScale, SpirvValue RoundedEdgeFactors, SpirvValue RoundedInsideFactor, SpirvValue UnroundedInsideFactor, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileReversebits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileSource_mark(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTranspose(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var returnTypeId = context.GetOrRegister(functionType.ReturnType); var result = builder.Insert(new OpTranspose(returnTypeId, context.Bound++, x.Id)); return new(result.ResultId, result.ResultType); } - public override SpirvValue CompileCheckAccessFullyMapped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue status) => throw new NotImplementedException(); - public override SpirvValue CompileAddUint64(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); - public override SpirvValue CompileNonUniformResourceIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue index) => throw new NotImplementedException(); - public override SpirvValue CompileQuadReadLaneAt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue quadLane) => throw new NotImplementedException(); - public override SpirvValue CompileQuadReadAcrossX(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileQuadReadAcrossY(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileQuadReadAcrossDiagonal(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileQuadAny(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); - public override SpirvValue CompileQuadAll(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); - public override SpirvValue CompileGetGroupWaveIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileGetGroupWaveCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileTraceRay(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue AccelerationStructure, SpirvValue RayFlags, SpirvValue InstanceInclusionMask, SpirvValue RayContributionToHitGroupIndex, SpirvValue MultiplierForGeometryContributionToHitGroupIndex, SpirvValue MissShaderIndex, SpirvValue Ray, SpirvValue Payload) => throw new NotImplementedException(); - public override SpirvValue CompileReportHit(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue THit, SpirvValue HitKind, SpirvValue Attributes) => throw new NotImplementedException(); - public override SpirvValue CompileCallShader(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue ShaderIndex, SpirvValue Parameter) => throw new NotImplementedException(); - public override SpirvValue CompileIgnoreHit(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileAcceptHitAndEndSearch(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileDispatchRaysIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileDispatchRaysDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWorldRayOrigin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWorldRayDirection(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileObjectRayOrigin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileObjectRayDirection(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileRayTMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileRayTCurrent(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompilePrimitiveIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileInstanceID(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileInstanceIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileGeometryIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileHitKind(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileRayFlags(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileObjectToWorld(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWorldToObject(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileObjectToWorld3x4(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWorldToObject3x4(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileObjectToWorld4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWorldToObject4x3(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); + public override SpirvValue CompileCheckAccessFullyMapped(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue status, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileAddUint64(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileNonUniformResourceIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue index, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadLaneAt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue quadLane, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossX(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossY(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadReadAcrossDiagonal(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadAny(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileQuadAll(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGetGroupWaveIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGetGroupWaveCount(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTraceRay(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue AccelerationStructure, SpirvValue RayFlags, SpirvValue InstanceInclusionMask, SpirvValue RayContributionToHitGroupIndex, SpirvValue MultiplierForGeometryContributionToHitGroupIndex, SpirvValue MissShaderIndex, SpirvValue Ray, SpirvValue Payload, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileReportHit(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue THit, SpirvValue HitKind, SpirvValue Attributes, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileCallShader(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue ShaderIndex, SpirvValue Parameter, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileIgnoreHit(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileAcceptHitAndEndSearch(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileDispatchRaysIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileDispatchRaysDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWorldRayOrigin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWorldRayDirection(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileObjectRayOrigin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileObjectRayDirection(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileRayTMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileRayTCurrent(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompilePrimitiveIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileInstanceID(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileInstanceIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileGeometryIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileHitKind(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileRayFlags(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld3x4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject3x4(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileObjectToWorld4x3(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWorldToObject4x3(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); // Wave - public override SpirvValue CompileWaveIsFirstLane(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWaveGetLaneIndex(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWaveGetLaneCount(SpirvContext context, SpirvBuilder builder, FunctionType functionType) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveAnyTrue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveAllTrue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveAllEqual(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveBallot(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond) => throw new NotImplementedException(); - public override SpirvValue CompileWaveReadLaneAt(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue lane) => throw new NotImplementedException(); - public override SpirvValue CompileWaveReadLaneFirst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveBitAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveBitOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveBitXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveMin(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveActiveMax(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWavePrefixCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWavePrefixSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWavePrefixProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMatch(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixBitAnd(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixBitOr(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixBitXor(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixCountBits(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixProduct(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); - public override SpirvValue CompileWaveMultiPrefixSum(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask) => throw new NotImplementedException(); + public override SpirvValue CompileWaveIsFirstLane(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveGetLaneIndex(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveGetLaneCount(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAnyTrue(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAllTrue(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveAllEqual(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBallot(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue cond, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveReadLaneAt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue lane, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveReadLaneFirst(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveCountBits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveSum(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveProduct(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveBitXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveActiveMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixCountBits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixSum(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWavePrefixProduct(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMatch(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixBitXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixCountBits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixProduct(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileWaveMultiPrefixSum(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, SpirvValue mask, TextLocation location = default) => throw new NotImplementedException(); // Obsolete - public override SpirvValue CompileDst(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b) => throw new NotImplementedException(); - public override SpirvValue CompileTex1D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex1Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex1Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex1Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex1Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex2D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex2Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex2Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex2Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex2Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex3D(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex3Dbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex3Dgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTex3Dlod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTex3Dproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBE(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBEbias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBEgrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBElod(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - public override SpirvValue CompileTexCUBEproj(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x) => throw new NotImplementedException(); - - - public static SpirvValue CompileFloatUnaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.Op op, SpirvValue x) + public override SpirvValue CompileDst(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex1D(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dbias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dgrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dlod(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex1Dproj(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex2D(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dbias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dgrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dlod(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex2Dproj(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex3D(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dbias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dgrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dlod(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTex3Dproj(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBE(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue? ddx, SpirvValue? ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEbias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEgrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBElod(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + public override SpirvValue CompileTexCUBEproj(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); + + + public static SpirvValue CompileFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.Op op, SpirvValue x) { var instruction = builder.Insert(new OpFwidth(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileGLSLFloatUnaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x) + public static SpirvValue CompileGLSLFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x) { var instruction = builder.Insert(new GLSLExp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); // Adjust OpCode only since Exp/Exp2/Log/Log2 share the same operands @@ -602,7 +603,7 @@ public static SpirvValue CompileGLSLFloatUnaryCall(SpirvContext context, SpirvBu return new SpirvValue(instruction.ResultId, instruction.ResultType); } - public static SpirvValue MultiplyConstant(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, float multiplyConstant) + public static SpirvValue MultiplyConstant(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, float multiplyConstant) { var constant = context.CompileConstant(multiplyConstant); constant = builder.Convert(context, constant, context.ReverseTypes[value.TypeId]); @@ -610,7 +611,7 @@ public static SpirvValue MultiplyConstant(SpirvContext context, SpirvBuilder bui return new SpirvValue(instruction2.ResultId, instruction2.ResultType); } - public static SpirvValue CompileGLSLFloatBinaryCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) + public static SpirvValue CompileGLSLFloatBinaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) { var instruction = builder.Insert(new GLSLPow(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, y.Id)); // Adjust OpCode only since Pow/Atan2/etc. share the same operands @@ -618,13 +619,13 @@ public static SpirvValue CompileGLSLFloatBinaryCall(SpirvContext context, SpirvB return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileBitcastCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public static SpirvValue CompileBitcastCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) { var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) + public static SpirvValue CompileInterlockedCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) { var destType = context.ReverseTypes[dest.TypeId]; if (destType is not PointerType pointerType || pointerType.BaseType is not ScalarType { Type: Scalar.UInt or Scalar.Int } s) @@ -679,18 +680,18 @@ public static SpirvValue CompileInterlockedCall(SpirvContext context, SpirvBuild return new(); } - public static SpirvValue CompileMemoryBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + public static SpirvValue CompileMemoryBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) { builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } - public static SpirvValue CompileControlBarrierCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + public static SpirvValue CompileControlBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) { builder.Insert(new OpControlBarrier(context.CompileConstant((int)Specification.Scope.Workgroup).Id, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } - public static SpirvValue CompileBoolToScalarBoolCall(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, Specification.Op op) + public static SpirvValue CompileBoolToScalarBoolCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, Specification.Op op) { // We handle matrix specifically in this case (auto loop doesn't work since it's not per item) // So we simply run OpAny/OpAll on each column and then get a vector with all the bool to run through the normal path diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs index b50c5adf7b..0d63dfe310 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/TextureMethodsImplementations.cs @@ -1,4 +1,5 @@ using Stride.Shaders.Core; +using Stride.Shaders.Parsing.Analysis; using Stride.Shaders.Spirv; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core; @@ -48,7 +49,7 @@ private static SpirvValue ExtractFromVec4(SpirvContext context, SpirvBuilder bui } } - public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? s = null) + public override SpirvValue CompileLoad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? s = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); @@ -74,7 +75,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde x = new(builder.InsertData(new OpVectorShuffle(context.GetOrRegister(coordType), context.Bound++, x.Id, x.Id, new(shuffleIndices)))); } - TextureGenerateImageOperands(context, builder, lod, o, s, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, lod, o, s, out var imask, out var imParams, location: location); // Storage images (RWTexture, Sampled=2) use OpImageRead; sampled images use OpImageFetch int loadResultId; @@ -87,7 +88,7 @@ public override SpirvValue CompileLoad(SpirvContext context, SpirvBuilder builde return new(loadResultId, vec4TypeId); } - public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSample(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -98,14 +99,14 @@ public override SpirvValue CompileSample(SpirvContext context, SpirvBuilder buil var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, location: location); var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleBias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSampleBias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -116,14 +117,14 @@ public override SpirvValue CompileSampleBias(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, bias: bias); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, bias: bias, location: location); var sample = builder.Insert(new OpImageSampleImplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null) + public override SpirvValue CompileSampleLevel(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue lod, SpirvValue? o = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); @@ -134,14 +135,14 @@ public override SpirvValue CompileSampleLevel(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, lod, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, lod, o, null, out var imask, out var imParams, location: location); var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleGrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSampleGrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -152,14 +153,14 @@ public override SpirvValue CompileSampleGrad(SpirvContext context, SpirvBuilder var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, ddx, ddy); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, ddx, ddy, location: location); var sample = builder.Insert(new OpImageSampleExplicitLod(vec4TypeId, context.Bound++, sampledImage.ResultId, x.Id, imask, imParams)); if (needsExtract) return ExtractFromVec4(context, builder, functionType, sample.ResultId); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSampleCmp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -169,13 +170,13 @@ public override SpirvValue CompileSampleCmp(SpirvContext context, SpirvBuilder b var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, location: location); var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleCmpBias(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSampleCmpBias(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue bias, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -185,13 +186,13 @@ public override SpirvValue CompileSampleCmpBias(SpirvContext context, SpirvBuild var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, bias: bias); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, bias: bias, location: location); var sample = builder.Insert(new OpImageSampleDrefImplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleCmpGrad(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null) + public override SpirvValue CompileSampleCmpGrad(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue ddx, SpirvValue ddy, SpirvValue? o = null, SpirvValue? clamp = null, SpirvValue? status = null, TextLocation location = default) { if (clamp != null || status != null) throw new NotImplementedException(); @@ -201,13 +202,13 @@ public override SpirvValue CompileSampleCmpGrad(SpirvContext context, SpirvBuild var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams, ddx, ddy); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, ddx, ddy, location: location); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleCmpLevel(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? compareValue = null, SpirvValue? lod = null, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? c = null) + public override SpirvValue CompileSampleCmpLevel(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? compareValue = null, SpirvValue? lod = null, SpirvValue? o = null, SpirvValue? status = null, SpirvValue? c = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); @@ -217,13 +218,13 @@ public override SpirvValue CompileSampleCmpLevel(SpirvContext context, SpirvBuil var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, lod, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, lod, o, null, out var imask, out var imParams, location: location); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue!.Value.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null) + public override SpirvValue CompileSampleCmpLevelZero(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); @@ -233,13 +234,13 @@ public override SpirvValue CompileSampleCmpLevelZero(SpirvContext context, Spirv var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, context.CompileConstant(0.0f), o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, context.CompileConstant(0.0f), o, null, out var imask, out var imParams, location: location); var sample = builder.Insert(new OpImageSampleDrefExplicitLod(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(sample.ResultId, sample.ResultType); } - public override SpirvValue CompileCalculateLevelOfDetail(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x) + public override SpirvValue CompileCalculateLevelOfDetail(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; @@ -255,7 +256,7 @@ public override SpirvValue CompileCalculateLevelOfDetail(SpirvContext context, S return new(result.ResultId, result.ResultType); } - public override SpirvValue CompileCalculateLevelOfDetailUnclamped(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x) + public override SpirvValue CompileCalculateLevelOfDetailUnclamped(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; @@ -272,93 +273,93 @@ public override SpirvValue CompileCalculateLevelOfDetailUnclamped(SpirvContext c } // Gather: component 0 (same as GatherRed) - public override SpirvValue CompileGather(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null) + public override SpirvValue CompileGather(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); - return CompileGatherComponent(context, builder, functionType, texture, s, x, 0, o); + return CompileGatherComponent(table, context, builder, functionType, texture, s, x, 0, o, location); } - public override SpirvValue CompileGatherRed(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherRed(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 0, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherComponent(context, builder, functionType, texture, s, x, 0, o); + return CompileGatherComponentConstOffsets(table, context, builder, functionType, texture, s, x, 0, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherComponent(table, context, builder, functionType, texture, s, x, 0, o, location); } - public override SpirvValue CompileGatherGreen(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherGreen(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 1, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherComponent(context, builder, functionType, texture, s, x, 1, o); + return CompileGatherComponentConstOffsets(table, context, builder, functionType, texture, s, x, 1, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherComponent(table, context, builder, functionType, texture, s, x, 1, o, location); } - public override SpirvValue CompileGatherBlue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherBlue(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 2, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherComponent(context, builder, functionType, texture, s, x, 2, o); + return CompileGatherComponentConstOffsets(table, context, builder, functionType, texture, s, x, 2, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherComponent(table, context, builder, functionType, texture, s, x, 2, o, location); } - public override SpirvValue CompileGatherAlpha(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherAlpha(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherComponentConstOffsets(context, builder, functionType, texture, s, x, 3, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherComponent(context, builder, functionType, texture, s, x, 3, o); + return CompileGatherComponentConstOffsets(table, context, builder, functionType, texture, s, x, 3, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherComponent(table, context, builder, functionType, texture, s, x, 3, o, location); } - public override SpirvValue CompileGatherCmp(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null) + public override SpirvValue CompileGatherCmp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); - return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + return CompileGatherDref(table, context, builder, functionType, texture, s, x, compareValue, o, location); } - public override SpirvValue CompileGatherCmpRed(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherCmpRed(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + return CompileGatherDrefConstOffsets(table, context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherDref(table, context, builder, functionType, texture, s, x, compareValue, o, location); } - public override SpirvValue CompileGatherCmpGreen(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherCmpGreen(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + return CompileGatherDrefConstOffsets(table, context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherDref(table, context, builder, functionType, texture, s, x, compareValue, o, location); } - public override SpirvValue CompileGatherCmpBlue(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherCmpBlue(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + return CompileGatherDrefConstOffsets(table, context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherDref(table, context, builder, functionType, texture, s, x, compareValue, o, location); } - public override SpirvValue CompileGatherCmpAlpha(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null) + public override SpirvValue CompileGatherCmpAlpha(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o = null, SpirvValue? o1 = null, SpirvValue? o2 = null, SpirvValue? o3 = null, SpirvValue? o4 = null, SpirvValue? status = null, TextLocation location = default) { if (status != null) throw new NotImplementedException(); if (o1 != null) - return CompileGatherDrefConstOffsets(context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value); - return CompileGatherDref(context, builder, functionType, texture, s, x, compareValue, o); + return CompileGatherDrefConstOffsets(table, context, builder, functionType, texture, s, x, compareValue, o1.Value, o2!.Value, o3!.Value, o4!.Value, location); + return CompileGatherDref(table, context, builder, functionType, texture, s, x, compareValue, o, location); } - public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue? x = null, SpirvValue? width = null, SpirvValue? levels = null, SpirvValue? elements = null, SpirvValue? height = null, SpirvValue? samples = null, SpirvValue? depth = null) + public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue? x = null, SpirvValue? width = null, SpirvValue? levels = null, SpirvValue? elements = null, SpirvValue? height = null, SpirvValue? samples = null, SpirvValue? depth = null, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var uintType = context.GetOrRegister(ScalarType.UInt); @@ -445,19 +446,19 @@ public override SpirvValue CompileGetDimensions(SpirvContext context, SpirvBuild return default; } - private SpirvValue CompileGatherComponent(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue? o) + private SpirvValue CompileGatherComponent(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue? o, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); var componentConstant = context.CompileConstant(component); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, location: location); var gather = builder.Insert(new OpImageGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, componentConstant.Id, imask, imParams)); return new(gather.ResultId, gather.ResultType); } - private SpirvValue CompileGatherComponentConstOffsets(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4) + private SpirvValue CompileGatherComponentConstOffsets(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, uint component, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); @@ -499,18 +500,18 @@ private SpirvValue CompileGatherComponentConstOffsets(SpirvContext context, Spir return new(result.ResultId, result.ResultType); } - private SpirvValue CompileGatherDref(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o) + private SpirvValue CompileGatherDref(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue? o, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); var sampledImage = builder.Insert(new OpSampledImage(typeSampledImage, context.Bound++, texture.Id, s.Id)); - TextureGenerateImageOperands(context, builder, null, o, null, out var imask, out var imParams); + TextureGenerateImageOperands(table, context, builder, null, o, null, out var imask, out var imParams, location: location); var gather = builder.Insert(new OpImageDrefGather(context.GetOrRegister(functionType.ReturnType), context.Bound++, sampledImage.ResultId, x.Id, compareValue.Id, imask, imParams)); return new(gather.ResultId, gather.ResultType); } - private SpirvValue CompileGatherDrefConstOffsets(SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4) + private SpirvValue CompileGatherDrefConstOffsets(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue texture, SpirvValue s, SpirvValue x, SpirvValue compareValue, SpirvValue o1, SpirvValue o2, SpirvValue o3, SpirvValue o4, TextLocation location = default) { var textureType = (TextureType)context.ReverseTypes[texture.TypeId]; var typeSampledImage = context.GetOrRegister(new SampledImage(textureType)); @@ -573,25 +574,31 @@ private static int TryPromoteToConstant(SpirvContext context, SpirvBuilder build if (IsConstantInContext(context, id)) return id; - // Check builder buffer for OpCompositeConstruct with all-constant constituents var buf = builder.GetBuffer(); - if (!buf.TryGetInstructionById(id, out var inst) || inst.Op != Op.OpCompositeConstruct) + if (!buf.TryGetInstructionById(id, out var inst)) return -1; - var span = inst.Data.Memory.Span; - for (int j = 3; j < span.Length; j++) + // OpCompositeConstruct with all-constant constituents + if (inst.Op == Op.OpCompositeConstruct) { - if (!IsConstantInContext(context, span[j])) - return -1; + var cspan = inst.Data.Memory.Span; + Span constituents = stackalloc int[cspan.Length - 3]; + for (int j = 3; j < cspan.Length; j++) + { + var promoted = TryPromoteToConstant(context, builder, cspan[j]); + if (promoted < 0) + return -1; + constituents[j - 3] = promoted; + } + + // All constituents are constants — emit OpConstantComposite in context + var cResultType = cspan[1]; + var cConstId = context.Bound++; + context.AddData(new OpConstantComposite(cResultType, cConstId, new(constituents))); + return cConstId; } - // All constituents are constants — emit OpConstantComposite in context - var resultType = span[1]; - var constId = context.Bound++; - Span constituents = stackalloc int[span.Length - 3]; - span[3..].CopyTo(constituents); - context.AddData(new OpConstantComposite(resultType, constId, new(constituents))); - return constId; + return -1; } private static void StoreQueryComponent(SpirvContext context, SpirvBuilder builder, int uintTypeId, int sizeResultId, int sizeComponents, int componentIndex, SpirvValue outParam) @@ -628,7 +635,7 @@ private static void StoreConvertedValue(SpirvContext context, SpirvBuilder build } } - private void TextureGenerateImageOperands(SpirvContext context, SpirvBuilder builder, SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null, SpirvValue? bias = null) + private void TextureGenerateImageOperands(SymbolTable table, SpirvContext context, SpirvBuilder builder, SpirvValue? lod, SpirvValue? offset, SpirvValue? sampleIndex, out ImageOperandsMask imask, out EnumerantParameters imParams, SpirvValue? ddx = null, SpirvValue? ddy = null, SpirvValue? bias = null, TextLocation location = default) { imask = ImageOperandsMask.None; // Allocate for worst case (6 operands: bias + grad(2) + lod + offset + sample) @@ -662,8 +669,7 @@ private void TextureGenerateImageOperands(SpirvContext context, SpirvBuilder bui } else { - imask |= ImageOperandsMask.Offset; - operands[operandCount++] = offset.Value.Id; + table.AddError(new(location, "Texture sample offset must be a constant expression (non-constant Offset requires Vulkan maintenance8)")); } } if (sampleIndex != null) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs index 6ca6a72fb6..6198bc776b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/ExpressionParsers/UnaryParsers.Prefix.cs @@ -59,6 +59,18 @@ public static bool Signed(ref TScanner scanner, ParseResult result, [M Parsers.Spaces0(ref scanner, result, out _); if (Prefix(ref scanner, result, out var lit)) { + // Fold -literal at parse time into a negated literal + if (op == Operator.Minus && lit is IntegerLiteral intLit) + { + parsed = new IntegerLiteral(intLit.Suffix, -intLit.Value, scanner[position..scanner.Position]); + return true; + } + if (op == Operator.Minus && lit is FloatLiteral floatLit) + { + parsed = new FloatLiteral(floatLit.Suffix, -floatLit.DoubleValue, floatLit.Exponent, scanner[position..scanner.Position]); + return true; + } + parsed = new PrefixExpression(op, lit, scanner[position..scanner.Position]); return true; } diff --git a/sources/shaders/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl b/sources/shaders/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl index f1decbc6bd..d88c5b4aae 100644 --- a/sources/shaders/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl +++ b/sources/shaders/assets/SDSL/RenderTests/TextureSampleLevelOffset.sdsl @@ -1,4 +1,6 @@ -// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD) +// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD, cbuffer.Test=(OffsetMode=0)) +// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD, cbuffer.Test=(OffsetMode=1)) +// PSMain(ExpectedResult=#5713CDAB, texture.Texture1=#1357ABCD, cbuffer.Test=(OffsetMode=2)) namespace Stride.Shaders.Tests; @@ -10,8 +12,19 @@ shader TextureSampleLevelOffset stage Texture2D Texture1; stage SamplerState Sampler1; + cbuffer Test + { + int OffsetMode; + } + void PSMain() { - streams.ColorTarget = Texture1.SampleLevel(Sampler1, streams.TexCoord, 0.0, int2(3, 2)).yxwz; + streams.ColorTarget = float4(1.0 / 255.0, 2.0 / 255.0, 3.0 / 255.0, 4.0 / 255.0); + if (OffsetMode == 0) + streams.ColorTarget = Texture1.SampleLevel(Sampler1, streams.TexCoord, 0.0, int2(3, 2)).yxwz; + else if (OffsetMode == 1) + streams.ColorTarget = Texture1.SampleLevel(Sampler1, streams.TexCoord, 0.0, int2(0, -1)).yxwz; + else if (OffsetMode == 2) + streams.ColorTarget = Texture1.SampleLevel(Sampler1, streams.TexCoord, 0.0, -1).yxwz; } -} \ No newline at end of file +} From 41db248ced7080988d850061317e27f088ee9835 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 29 Mar 2026 00:01:04 +0900 Subject: [PATCH 1022/1182] SDSL: Better error validation for SPIRV --- .../Stride.Graphics/Vulkan/PipelineState.Vulkan.cs | 12 ++++++++++-- .../Stride.Shaders.Compilers/EffectCompiler.cs | 14 ++++++++++++++ .../Spirv/Tools/Validator.cs | 14 ++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs index ef19111491..f6a9248e9b 100644 --- a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs @@ -47,8 +47,16 @@ internal PipelineState(GraphicsDevice graphicsDevice, PipelineStateDescription p private unsafe void Recreate() { // Note: important to pin this so that stages[x].Name is valid during this whole function - fixed (void* defaultEntryPointData = defaultEntryPoint) // null if array is empty or null - RecreateInner(); + try + { + fixed (void* defaultEntryPointData = defaultEntryPoint) // null if array is empty or null + RecreateInner(); + } + catch (InvalidOperationException ex) when (Description.EffectBytecode?.Stages is { Length: > 0 } stages) + { + var entryPoints = string.Join(", ", stages.Select(s => $"{s.Stage}:{Encoding.UTF8.GetString(s.EntryPoint).TrimEnd('\0')}")); + throw new InvalidOperationException($"{ex.Message} (bytecode {stages[0].Id} [{entryPoints}])", ex); + } } private unsafe void RecreateInner() diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 3baa16fd37..792370d7bd 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -48,6 +48,12 @@ public partial class EffectCompiler : EffectCompilerBase public override IVirtualFileProvider FileProvider { get; set; } public bool UseFileSystem { get; set; } + /// + /// When true, runs spirv-val on the SPIR-V bytecode after MergeSDSL. + /// Validation errors are logged as warnings (they do not block compilation). + /// + public bool ValidateSpirv { get; set; } + public EffectCompiler(IVirtualFileProvider fileProvider) { FileProvider = fileProvider; @@ -146,6 +152,14 @@ public override TaskOrResult Compile(ShaderMixinSo if (!shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints)) return new EffectBytecodeCompilerResult(null, log); + // Optional SPIR-V validation (requires spirv-val from Vulkan SDK) + if (ValidateSpirv && spirvBytecode is { Length: > 0 }) + { + var validationResult = Spirv.Tools.Spv.ValidateBinary(spirvBytecode, targetVulkan: effectParameters.Platform is GraphicsPlatform.Vulkan); + if (!validationResult.IsValid) + log.Error($"SPIR-V validation failed for effect {fullEffectName} (id: {mixinObjectId}): {validationResult.Output}"); + } + // ------------------------------------------------------- // Prepare DynamicCache folder for debug files #if STRIDE_PLATFORM_DESKTOP diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs index 586e58b445..3782600712 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs @@ -33,16 +33,21 @@ public static partial class Spv /// Validates a SPIR-V file using the spirv-val tool from the Vulkan SDK. /// /// Path to a .spv file. + /// When true, validates against Vulkan 1.4 with relaxed layout rules. /// A indicating whether the bytecode is valid. - public static ValidationResult ValidateFile(string filePath) + public static ValidationResult ValidateFile(string filePath, bool targetVulkan = false) { var exe = FindSpirvVal(); + var args = targetVulkan + ? $"--target-env vulkan1.4 --relax-block-layout --uniform-buffer-standard-layout {filePath}" + : filePath; + using var process = new Process(); process.StartInfo = new ProcessStartInfo { FileName = exe, - Arguments = filePath, + Arguments = args, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, @@ -68,14 +73,15 @@ public static ValidationResult ValidateFile(string filePath) /// Validates SPIR-V bytecode using the spirv-val tool from the Vulkan SDK. /// /// Raw SPIR-V bytecode as a byte span. + /// When true, validates against Vulkan 1.4 with relaxed layout rules. /// A indicating whether the bytecode is valid. - public static ValidationResult ValidateBinary(ReadOnlySpan spirvBytes) + public static ValidationResult ValidateBinary(ReadOnlySpan spirvBytes, bool targetVulkan = false) { var tempFile = Path.GetTempFileName(); try { File.WriteAllBytes(tempFile, spirvBytes.ToArray()); - return ValidateFile(tempFile); + return ValidateFile(tempFile, targetVulkan); } finally { From c54964c344f12458a50c2d33f7aef21092be196a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 29 Mar 2026 00:20:16 +0900 Subject: [PATCH 1023/1182] SDSL: Pass opaque types (texture/sampler) as UniformConstant pointers in function calls Vulkan forbids OpStore to OpTypeImage/OpTypeSampler (VUID-StandaloneSpirv-OpTypeImage-06924). Previously, texture/sampler function parameters used Function storage class with copy-in via OpStore. Now they use UniformConstant pointers passed directly, matching Vulkan requirements. Also fix ReadWriteAnalyzer to mark resources passed as OpFunctionCall arguments as used, preventing DeadCodeRemover from eliminating referenced texture/sampler variables. --- .../Parsing/SDSL/AST/Expression.cs | 13 ++++++++----- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 8 ++++++-- .../Interfaces/Analysis/ReadWriteAnalyzer.cs | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 4f6efa03dd..84819e2e32 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -285,12 +285,15 @@ protected void ProcessInputArguments(SymbolTable table, CompilerUnit compiler, F // Note: "in" is implicit, so we match in all cases except if out var inOutFlags = paramDefinition.Modifiers & ParameterModifiers.InOut; - if (paramDefinition.Type is PointerType) + if (paramDefinition.Type is PointerType pointerParamType) { - // For ref params, pass the original pointer directly. - // Required for atomic intrinsics (InterlockedAdd, etc.) that need - // the actual memory pointer (Workgroup, StorageBuffer, etc.). - if (paramDefinition.Modifiers == ParameterModifiers.Ref) + // For ref params or opaque types (image/sampler), pass the original pointer directly. + // - ref: required for atomic intrinsics (InterlockedAdd, etc.) that need + // the actual memory pointer (Workgroup, StorageBuffer, etc.). + // - opaque types: Vulkan forbids OpStore to these types (VUID-StandaloneSpirv-OpTypeImage-06924), + // so they cannot be copied into Function-storage variables. + if (paramDefinition.Modifiers == ParameterModifiers.Ref + || pointerParamType.BaseType is TextureType or SamplerType) { var paramPointer = Arguments.Values[i].Compile(table, compiler); if (context.ReverseTypes[paramPointer.TypeId] is not PointerType) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 229d1a8acd..36384b97dd 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -463,8 +463,12 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) private static PointerType GenerateParameterType(MethodParameter p) { - // Default: wrap everything in Function pointer - // TODO: what happens if we want to pass texture/sampler around as parameters? + // Opaque types (image/sampler) must use UniformConstant storage class — + // Vulkan forbids OpStore to these types (VUID-StandaloneSpirv-OpTypeImage-06924), + // so they cannot be copied into Function-storage variables. + if (p.Type is TextureType or SamplerType) + return new PointerType(p.Type!, Specification.StorageClass.UniformConstant); + return new PointerType(p.Type!, Specification.StorageClass.Function); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs index dca1be075c..ef1e48a9bb 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Analysis/ReadWriteAnalyzer.cs @@ -208,6 +208,20 @@ or Op.OpAtomicExchange or Op.OpAtomicCompareExchange or Op.OpAtomicLoad or Op.Op } else if (i.Op == Op.OpFunctionCall && new OpFunctionCall(ref i) is { } call) { + // Mark any resource/variable/cbuffer passed as function argument as used + // (e.g. texture/sampler passed by UniformConstant pointer) + var argSpan = i.Memory.Span; + for (int argIdx = 4; argIdx < argSpan.Length; argIdx++) + { + var argId = argSpan[argIdx]; + if (analysisResult.Resources.TryGetValue(argId, out var argResourceInfo)) + argResourceInfo.UsedThisStage = true; + if (variables.TryGetValue(argId, out var argVariableInfo)) + argVariableInfo.UsedThisStage = true; + if (analysisResult.CBuffers.TryGetValue(argId, out var argCBufferInfo)) + argCBufferInfo.UsedThisStage = true; + } + // Process call methodInfo.HasStreamAccess |= AnalyzeStreamReadWrites(buffer, context, call.Function, analysisResult, liveAnalysis); } From 04d586f54a955012f43460bb0c106d77734a186f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 11:16:59 +0900 Subject: [PATCH 1024/1182] SDSL: Strip SPV_GOOGLE_user_type from final SPIR-V bytecode (only for Vulkan, we keep it for SPIRV-Cross) --- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 668 +++++++++--------- ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 668 +++++++++--------- .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 340 +++++---- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 472 ++++++------- .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 470 ++++++------ ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 514 +++++++------- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 558 ++++++++------- .../EffectCompiler.cs | 6 +- .../SDSL/ShaderMixer.cs | 18 +- 9 files changed, 1850 insertions(+), 1864 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index ef53fe7e73..13ba91884d 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -34,347 +34,343 @@ public partial class SpriteBatch 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 29, 179, 72, 201, 228, 187, 147, 193, 184, 189, 228, 44, 171, 184, 227, 246, 0, 88, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, 0, 40, 0, -0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 82, 2, -0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, -110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, -0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, -101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, -47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, -108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, -97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, -47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, -115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, -101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, -0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 40, 2, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, -101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, -116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, -11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, -0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, 111, 114, 85, -116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 206, 0, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, 95, 70, 117, -110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, -4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, -48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, -5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 106, 1, -0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, -4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 164, 1, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, -95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, -114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, -4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, -0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, -0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, -103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, -116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, -5, 0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, -6, 0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, -6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, -100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, -0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, -4, 0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, -4, 0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, -0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, -6, 0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, -122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, -0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, -5, 0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, -5, 0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, -114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, -105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, -0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, -0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, -69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, -110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, -0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, -3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, -0, 0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, -6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, -4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, -0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 165, 40, 204, 249, 226, 179, 69, 107, 49, 251, 74, 154, 222, 65, 188, 240, 0, 216, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, 0, 7, 0, +0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, +0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, +47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, +115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, +115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, +46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, +0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, +105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 43, 2, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, +112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, +0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, +119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, +120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, +0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 212, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, 66, 97, 0, +0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, +54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, +110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, +111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, +0, 0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, +50, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, +4, 0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, +0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, +51, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, +7, 0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, +114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, +116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, +112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, +0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, +0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, +0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, +5, 0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, +8, 0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, +0, 0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, +97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, +95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, +0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, +97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, +0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, +0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, +6, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, +7, 0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, +115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, +0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, +12, 0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, +3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, +0, 0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, +6, 0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, +4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, +0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, -0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, -0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, -4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, -0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, -0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, -0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, -4, 0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, -4, 0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, -4, 0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, -128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, -184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, -78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, -4, 0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, -4, 0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, -4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, -4, 0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, -4, 0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, -4, 0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, -0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, -0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, -0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, -0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, -0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, -0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, -5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, -0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, -0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, -0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, -0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, -0, 0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, -0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, -0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, -0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, -0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, -0, 0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, -0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, -2, 0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, -0, 0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, -0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, -0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, -0, 0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, -0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, -3, 0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, -2, 0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, -0, 0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, -0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, -4, 0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, -0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, -0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, -3, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, -4, 0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, -0, 0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, -5, 0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, -0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, -2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, -6, 0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, -0, 0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, -0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, -0, 0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, -0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, -0, 0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, -4, 0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, -3, 0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, -0, 0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, -0, 0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, -0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, -5, 0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, -0, 0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, -4, 0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, -5, 0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, -0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 29, 179, 72, 201, 228, 187, 147, 193, 184, 189, 228, 44, 171, 184, 227, 246, 0, 88, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, -0, 117, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, -48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, -0, 57, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, -0, 78, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, -0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, -83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, -0, 7, 0, 20, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, -0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, -0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, -97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, -110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, -0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, -0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, -114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, -0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, -110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, -0, 5, 0, 7, 0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, -0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, -95, 51, 0, 0, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, -52, 55, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, -0, 5, 0, 5, 0, 106, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, -52, 53, 0, 0, 0, 5, 0, 4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, -0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, -0, 181, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, -0, 211, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, -0, 110, 88, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 3, 0, 248, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, -0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, -0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, -0, 44, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, -0, 50, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 0, 0, 5, 0, 5, 0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, -85, 84, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, -0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, -0, 5, 0, 5, 0, 57, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 5, 0, 4, 0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, -95, 52, 0, 0, 0, 5, 0, 4, 0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 5, 0, 6, 0, 80, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 0, 0, 0, 0, 5, 0, 6, 0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, -86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, -0, 5, 0, 5, 0, 88, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, -110, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, -122, 122, 108, 101, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, -0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, -0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 6, 0, 6, 0, 90, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, -62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, -0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, -116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, -0, 50, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, -0, 76, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, -0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, -78, 0, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, -0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, -0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, +0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, +0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, +4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, +0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, +0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, +0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, +4, 0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, +4, 0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, +4, 0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, +128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, +184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, +78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, +4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, +4, 0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, +4, 0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, +4, 0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, +4, 0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, +4, 0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, +0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, +0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, +0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, +0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, +5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, +0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, +0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, +0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, +0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, +0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, +0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, +0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, +0, 0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, +0, 0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, +0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, +0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, +2, 0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, +0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, +0, 0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, +0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, +3, 0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, +2, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, +0, 0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, +0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, +4, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, +0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, +0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, +3, 0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, +4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, +0, 0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, +5, 0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, +0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, +2, 0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, +6, 0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, +0, 0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, +0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, +0, 0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, +0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, +0, 0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, +4, 0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, +3, 0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, +0, 0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, +0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, +0, 0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, +4, 0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, +5, 0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, +0, 0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 165, 40, 204, 249, 226, 179, 69, 107, 49, 251, 74, 154, 222, 65, 188, 240, 0, 216, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, +0, 118, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, +0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, +0, 59, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, +0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, +0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, +0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, +0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, +0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, +0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, +114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, +0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, +0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, +0, 189, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, +51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, +0, 5, 0, 7, 0, 212, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, +0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, +0, 96, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, +0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, +62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, +95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, +0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, +0, 110, 89, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, +0, 5, 0, 4, 0, 5, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, +0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, +108, 111, 114, 0, 0, 5, 0, 7, 0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, +0, 48, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, +0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, +0, 54, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, +0, 6, 0, 5, 0, 54, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +0, 5, 0, 5, 0, 56, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, +122, 122, 108, 101, 0, 5, 0, 8, 0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, +0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, +0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, +0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, +0, 82, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, +0, 5, 0, 6, 0, 85, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, +0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, +0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, +0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 6, 0, 7, 0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, +0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, +0, 91, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, +86, 83, 0, 0, 0, 5, 0, 12, 0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, +95, 53, 0, 0, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, +0, 51, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, +0, 77, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, +78, 0, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 5, 0, 85, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, +0, 71, 0, 4, 0, 87, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, +0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, -0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, -0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, -0, 5, 0, 0, 0, 33, 0, 4, 0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, -0, 194, 44, 77, 60, 23, 0, 4, 0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, -0, 4, 0, 0, 0, 33, 0, 4, 0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, -0, 4, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, -0, 76, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, -0, 106, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, -0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, -0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, -0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, -0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, -0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, -0, 42, 0, 0, 0, 32, 0, 4, 0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 104, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, -0, 45, 2, 0, 0, 44, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 52, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 49, 2, 0, 0, 83, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 91, 2, 0, 0, 92, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 135, 0, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, -0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, -0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, -0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, -0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, -0, 59, 0, 4, 0, 211, 0, 0, 0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 62, 0, 3, 0, 230, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, -0, 209, 0, 0, 0, 237, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, -0, 129, 0, 5, 0, 209, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, -0, 129, 0, 5, 0, 209, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, -0, 5, 0, 0, 0, 245, 0, 0, 0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 250, 0, 0, 0, 249, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, -0, 180, 1, 0, 0, 181, 1, 0, 0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 194, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, -0, 181, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, -0, 210, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, -0, 28, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, -0, 12, 0, 6, 0, 5, 0, 0, 0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, -0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, -0, 211, 1, 0, 0, 248, 0, 2, 0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 226, 1, 0, 0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, -0, 230, 1, 0, 0, 229, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, -0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, -0, 231, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, -0, 240, 1, 0, 0, 62, 0, 3, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, -0, 250, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, -0, 255, 1, 0, 0, 251, 1, 0, 0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, -0, 1, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 6, 2, 0, 0, 248, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, -0, 223, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, -0, 15, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, -0, 18, 2, 0, 0, 10, 2, 0, 0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, -0, 4, 0, 0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, -0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 31, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, -0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 38, 2, 0, 0, 28, 2, 0, 0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, -0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, -0, 48, 2, 0, 0, 62, 0, 3, 0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, -0, 93, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, -0, 96, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, -0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 102, 2, 0, 0, 83, 2, 0, 0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, -0, 105, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, -0, 108, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, -0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 114, 2, 0, 0, 113, 2, 0, 0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, -0, 116, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, +0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, +0, 5, 0, 0, 0, 33, 0, 4, 0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, +0, 194, 44, 77, 60, 23, 0, 4, 0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, +0, 4, 0, 0, 0, 33, 0, 4, 0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 5, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, +0, 77, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, +0, 107, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, +0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, +0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, +0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, +0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, +0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, +0, 43, 0, 0, 0, 32, 0, 4, 0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, +0, 139, 0, 0, 0, 105, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, +0, 46, 2, 0, 0, 45, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 53, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 80, 2, 0, 0, 79, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 50, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 92, 2, 0, 0, 93, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 136, 0, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, +0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, +0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, +0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, +0, 59, 0, 4, 0, 212, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 62, 0, 3, 0, 231, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, +0, 210, 0, 0, 0, 238, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, +0, 129, 0, 5, 0, 210, 0, 0, 0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, +0, 129, 0, 5, 0, 210, 0, 0, 0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, +0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 251, 0, 0, 0, 250, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, +0, 181, 1, 0, 0, 182, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 195, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, +0, 182, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, +0, 211, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, +0, 29, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, +0, 12, 0, 6, 0, 5, 0, 0, 0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, +0, 213, 1, 0, 0, 214, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, +0, 212, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, +0, 231, 1, 0, 0, 230, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, +0, 235, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, +0, 232, 1, 0, 0, 239, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, +0, 241, 1, 0, 0, 62, 0, 3, 0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, +0, 251, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, +0, 0, 2, 0, 0, 252, 1, 0, 0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, +0, 2, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 7, 2, 0, 0, 249, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, +0, 224, 1, 0, 0, 248, 0, 2, 0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, +0, 16, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, +0, 19, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, +0, 4, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, +0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 32, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, +0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 39, 2, 0, 0, 29, 2, 0, 0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, +0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, +0, 49, 2, 0, 0, 62, 0, 3, 0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, +0, 94, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, +0, 97, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, +0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 103, 2, 0, 0, 84, 2, 0, 0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, +0, 106, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, +0, 109, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, +0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 115, 2, 0, 0, 114, 2, 0, 0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, +0, 117, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index 7f6caabd5a..03ea01f007 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -34,346 +34,342 @@ public partial class SpriteBatch 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 252, 110, 213, 113, 247, 170, 72, 161, 233, 148, 96, 217, 253, 21, 143, 230, 0, 84, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, -3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, 0, 40, 0, -0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 82, 2, -0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, -110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, -0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, -101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, -47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, -108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, -97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, -47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, -115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, -101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, -0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 40, 2, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, -101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, -116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, -11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, -108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, -0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, 111, 114, 85, -116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 206, 0, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, 95, 70, 117, -110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, -4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, -48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, -5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 106, 1, -0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, -4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 109, 101, 114, -103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, -0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, 114, 110, 97, 114, -121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 234, 1, -0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, 0, 0, 110, 90, -0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, -95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, -0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, 116, 95, 80, 83, -95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, 95, 80, 83, 95, -67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 53, 2, -0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 53, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 54, 2, -0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, -6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, -0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, 0, 0, 115, 116, -114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 61, 2, -0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 74, 2, -0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, 0, 0, 105, 110, -95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 83, 2, -0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, -0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, 0, 0, 86, 83, -95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 89, 2, -0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, -101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 4, 0, -0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, -0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, -0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, -0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, -4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, -0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 81, 2, -0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, -0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, -0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 44, 225, 151, 85, 178, 127, 173, 116, 18, 195, 115, 152, 31, 157, 21, 243, 0, 212, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, 0, 7, 0, +0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, +0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, +47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, +115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, +101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, +115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, +46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, +0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, +105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 43, 2, +0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, +112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, +0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, +119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, +120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, +0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 212, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, 66, 97, 0, +0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, +54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, 0, 102, 108, +111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, +103, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, +0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, +6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, +5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 241, 1, +0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, 0, 0, 105, 110, +116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, +5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 46, 2, +0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, 114, 95, 73, 110, +112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, +0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, +102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 3, 0, +0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, 0, 0, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, +0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 57, 2, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, +104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, +4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, +0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, 95, 86, 83, 95, +67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, 0, 0, 111, 117, +116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, +0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, +108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, +0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 91, 2, +0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, 0, 0, 83, 119, +105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 94, 2, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 113, 0, +0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, +4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, 0, 0, 67, 79, +76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 2, +0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 82, 2, +0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, +0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, 0, 0, 30, 0, +0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, +0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, +0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, -0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, -0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, -0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, -4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, -0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, -0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 194, 0, -0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 209, 0, -0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 226, 0, -0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 128, 63, 43, 0, -4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, 184, 60, 43, 0, -4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, 78, 65, 43, 0, -4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, -0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, -0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, -0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 52, 2, -0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, -0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, -0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 87, 2, -0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, -0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, 0, 0, 5, 0, -0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, 0, 0, 6, 0, -0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 92, 2, -0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, -0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, -5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, -0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, -0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, -0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 230, 0, -0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, 0, 0, 232, 0, -0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, 0, 0, 201, 0, -0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, 0, 238, 0, -0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, 0, 241, 0, -0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 243, 0, -0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 80, 0, -7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 176, 1, -0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, 0, 0, 248, 0, -2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, 0, 0, 62, 0, -3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, 0, 0, 65, 0, -5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 206, 1, -0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, 0, 248, 0, -2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 210, 1, -0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 211, 1, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, 0, 0, 225, 1, -0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, 0, 0, 208, 1, -0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, -0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, 0, 0, 65, 0, -5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 244, 1, -0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 246, 1, -0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, 0, 5, 0, -0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, 0, 0, 254, 1, -0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, 5, 0, 5, 0, -0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, 0, 0, 133, 0, -5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, 2, 0, 223, 1, -0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, 6, 0, 5, 0, -0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, 0, 0, 11, 2, -0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 22, 2, -0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, 0, 0, 24, 2, -0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 2, -0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, 0, 0, 57, 2, -0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, 0, 0, 254, 0, -2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, -0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, 3, 0, 63, 2, -0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 69, 2, -0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 73, 2, -0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, 0, 0, 31, 0, -0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, 5, 0, 3, 0, -0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, 0, 0, 62, 0, -3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, 4, 0, 30, 0, -0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, 5, 0, 74, 0, -0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, 0, 0, 62, 0, -3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 252, 110, 213, 113, 247, 170, 72, 161, 233, 148, 96, 217, 253, 21, 143, 230, 0, 84, 42, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 117, 2, 0, -0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 9, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, -0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 58, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 46, 2, 0, 0, 48, 2, 0, 0, 50, 2, 0, 0, 51, 2, 0, 0, 44, 2, 0, 0, 57, 2, 0, -0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 93, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 77, 2, 0, 0, 80, 2, 0, 0, 81, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, -0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 92, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 58, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 182, 0, 0, 0, 7, 0, 21, 0, 155, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 1, 0, 0, 7, 0, 21, 0, 39, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, -0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, -116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, -0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, -97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, -0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, -105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, -119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 67, 111, 108, -111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 195, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, -111, 97, 116, 0, 0, 5, 0, 7, 0, 201, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, -0, 206, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 227, 0, 0, 0, 112, 116, 114, -95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 228, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 230, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 62, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, -49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 71, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, -0, 5, 0, 5, 0, 93, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 95, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 101, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, -0, 106, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 111, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 142, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, -0, 5, 0, 4, 0, 157, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 163, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 164, 1, 0, -0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 180, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, -109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 200, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 208, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 49, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 116, 101, 114, -110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 227, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 222, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 231, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, -0, 234, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 239, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 240, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 245, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 248, 1, 0, -0, 110, 90, 0, 0, 5, 0, 4, 0, 0, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 4, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 7, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 223, 1, 0, -0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 15, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 10, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, -101, 95, 50, 0, 0, 5, 0, 5, 0, 28, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 44, 2, 0, 0, 111, 117, 116, -95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 47, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 46, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 0, 0, 5, 0, 7, 0, 49, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 48, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 50, 2, 0, 0, 105, 110, 95, -80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 52, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, -0, 53, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 53, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, -0, 53, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 53, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, -0, 54, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -0, 6, 0, 6, 0, 55, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, -100, 0, 0, 0, 0, 6, 0, 5, 0, 55, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 56, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 57, 2, 0, -0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 58, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, -0, 61, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 64, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 67, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 70, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, -0, 74, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 80, 2, 0, -0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 82, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, -0, 83, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 85, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 0, 0, 5, 0, 7, 0, 87, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 86, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 88, 2, 0, -0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, -0, 88, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 88, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 88, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, -0, 89, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 89, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, -122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, -0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 91, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 5, 0, 5, 0, 92, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 93, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 104, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, -0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, -0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 44, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 46, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 46, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, -0, 71, 0, 4, 0, 48, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 48, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 50, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 50, 2, 0, 0, 3, 22, 0, -0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 51, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 11, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 77, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 80, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, -0, 81, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 81, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, -79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 85, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 86, 2, 0, -0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, -0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, -0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, +0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, +0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, +0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, +4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, +0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, +0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 195, 0, +0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 210, 0, +0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 227, 0, +0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 128, 63, 43, 0, +4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, 184, 60, 43, 0, +4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, 78, 65, 43, 0, +4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, +0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, +0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, +0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 53, 2, +0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, +0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, +0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 88, 2, +0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, +0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, 0, 0, 5, 0, +0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, 0, 0, 6, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 93, 2, +0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, +0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, +0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, +0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, +0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, 0, 0, 231, 0, +0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 233, 0, +0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, 0, 0, 202, 0, +0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, 0, 239, 0, +0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, 0, 242, 0, +0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, +0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 80, 0, +7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 177, 1, +0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, 0, 0, 248, 0, +2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, 0, 0, 62, 0, +3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, 0, 0, 65, 0, +5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 207, 1, +0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, 0, 0, 248, 0, +2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 211, 1, +0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 212, 1, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 226, 1, +0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, 0, 0, 209, 1, +0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, 4, 0, 5, 0, +0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, 0, 0, 65, 0, +5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 245, 1, +0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 247, 1, +0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, 4, 0, 5, 0, +0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, 0, 0, 255, 1, +0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, 5, 0, 5, 0, +0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, 0, 0, 133, 0, +5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, 2, 0, 224, 1, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, 0, 0, 12, 2, +0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 2, +0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, 0, 0, 25, 2, +0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 2, +0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 58, 2, +0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, 0, 0, 254, 0, +2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, +0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, 3, 0, 64, 2, +0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 70, 2, +0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 74, 2, +0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 31, 0, +0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 62, 0, +3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, 4, 0, 30, 0, +0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, 5, 0, 75, 0, +0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, 0, 0, 62, 0, +3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 44, 225, 151, 85, 178, 127, 173, 116, 18, 195, 115, 152, 31, 157, 21, 243, 0, 212, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, +0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, +0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, +0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, +0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, +0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, +0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, +0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, +119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, +0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, +68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, +97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, +0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, +49, 49, 0, 0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, +0, 212, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, +66, 97, 0, 0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, +53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, +0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, +105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, +100, 105, 110, 103, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, +0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, +0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, +0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, 0, +0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, +0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, +0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, 114, +95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, +0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, 0, +0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, +0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, +0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, +97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, +0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, 0, +0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, +0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, +0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, +0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, +0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, 0, +0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, +0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, +0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, +0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, 0, +0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, +0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, -0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, -0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, -0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, -0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, -0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 188, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 195, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, -0, 194, 0, 0, 0, 5, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, -0, 209, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 7, 0, 0, 0, 209, 0, 0, 0, 33, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 211, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, -0, 226, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 248, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 252, 0, 0, 0, 4, 0, 0, 0, 227, 0, 0, 0, 195, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 128, -63, 43, 0, 4, 0, 5, 0, 0, 0, 62, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 66, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 71, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 76, 1, 0, 0, 54, 168, 184, -60, 43, 0, 4, 0, 5, 0, 0, 0, 93, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 95, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 101, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 106, 1, 0, 0, 82, 184, 78, -65, 43, 0, 4, 0, 5, 0, 0, 0, 111, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 142, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 157, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, -0, 5, 0, 0, 0, 208, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 234, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 240, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 245, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 4, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, -0, 5, 0, 0, 0, 15, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 45, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 47, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 49, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, -0, 52, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 53, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 54, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 55, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 56, 2, 0, 0, 6, 0, 0, 0, 55, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 61, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 64, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 67, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 70, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, -0, 87, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 88, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 5, 0, 0, 0, 30, 0, 8, 0, 90, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 91, 2, 0, 0, 6, 0, 0, 0, 90, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 104, 2, 0, -0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 44, 2, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 46, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 48, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 50, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 51, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 2, 0, 0, 57, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 47, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 80, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 82, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 49, 2, 0, 0, 83, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 45, 2, 0, 0, 84, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 52, 2, 0, 0, 85, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 2, 0, 0, 86, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 2, 0, 0, 92, 2, 0, -0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, -0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, -0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 164, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, -0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, -0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 55, 0, 3, 0, 227, 0, 0, 0, 228, 0, 0, 0, 248, 0, 2, 0, 229, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, -0, 230, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 79, 0, 8, 0, 209, 0, 0, 0, 232, 0, 0, 0, 231, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 230, 0, 0, -0, 232, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 233, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 234, 0, 0, 0, 230, 0, 0, 0, 61, 0, 4, 0, 209, 0, 0, 0, 235, 0, 0, 0, 230, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 237, 0, 0, -0, 201, 0, 0, 0, 201, 0, 0, 0, 201, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 236, 0, 0, 0, 235, 0, 0, 0, 237, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, -0, 238, 0, 0, 0, 236, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 240, 0, 0, 0, 234, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 209, 0, 0, 0, 242, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 129, 0, 5, 0, 209, 0, 0, -0, 241, 0, 0, 0, 240, 0, 0, 0, 242, 0, 0, 0, 133, 0, 5, 0, 209, 0, 0, 0, 243, 0, 0, 0, 233, 0, 0, 0, 241, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, -0, 243, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 249, 0, 0, 0, 228, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, -0, 80, 0, 7, 0, 4, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 250, 0, 0, 0, 254, 0, 2, 0, 251, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 163, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, -0, 176, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 191, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 179, 1, 0, 0, 117, 0, 0, 0, 247, 0, 3, 0, 181, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 157, 1, 0, 0, 180, 1, 0, 0, 181, 1, 0, -0, 248, 0, 2, 0, 180, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 185, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 193, 1, 0, 0, 92, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 194, 1, 0, 0, 193, 1, 0, -0, 62, 0, 3, 0, 191, 1, 0, 0, 194, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 196, 1, 0, 0, 185, 0, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 185, 1, 0, 0, 196, 1, 0, 0, 249, 0, 2, 0, 181, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 199, 1, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 200, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 210, 1, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 195, 0, 0, 0, 231, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 239, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 195, 0, 0, 0, 248, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 28, 2, 0, 0, 7, 0, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 202, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 203, 1, 0, 0, 202, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 205, 1, 0, 0, 203, 1, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, -0, 206, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 205, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 209, 1, 0, 0, 206, 1, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 211, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 209, 1, 0, 0, 212, 1, 0, 0, 213, 1, 0, -0, 248, 0, 2, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 216, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 217, 1, 0, 0, 216, 1, 0, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, -0, 210, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 220, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 220, 1, 0, 0, 249, 0, 2, 0, 211, 1, 0, 0, 248, 0, 2, -0, 211, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 210, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 221, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 225, 1, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 1, 0, -0, 225, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 228, 1, 0, 0, 226, 1, 0, 0, 227, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 229, 1, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 228, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 230, 1, 0, 0, 229, 1, 0, -0, 208, 1, 0, 0, 247, 0, 3, 0, 223, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 230, 1, 0, 0, 222, 1, 0, 0, 223, 1, 0, 0, 248, 0, 2, 0, 222, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 235, 1, 0, 0, 200, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 236, 1, 0, 0, 235, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 238, 1, 0, -0, 65, 0, 5, 0, 195, 0, 0, 0, 241, 1, 0, 0, 200, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 227, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, -0, 244, 1, 0, 0, 243, 1, 0, 0, 204, 1, 0, 0, 62, 0, 3, 0, 239, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 246, 1, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 240, 1, 0, 0, 62, 0, 3, -0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 231, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 252, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 239, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 254, 1, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 251, 1, 0, -0, 254, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 1, 2, 0, 0, 9, 1, 0, 0, 43, 0, 0, 0, 255, 1, 0, 0, 0, 2, 0, 0, 204, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 2, 2, 0, 0, 9, 1, 0, 0, 31, 0, 0, 0, 1, 2, 0, 0, 131, 0, 5, -0, 5, 0, 0, 0, 3, 2, 0, 0, 204, 1, 0, 0, 2, 2, 0, 0, 62, 0, 3, 0, 248, 1, 0, 0, 3, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 5, 2, 0, 0, 200, 1, 0, 0, 4, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 6, 2, 0, 0, 248, 1, 0, -0, 133, 0, 5, 0, 5, 0, 0, 0, 8, 2, 0, 0, 6, 2, 0, 0, 7, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 7, 2, 0, 0, 62, 0, 3, 0, 5, 2, 0, 0, 9, 2, 0, 0, 249, 0, 2, 0, 223, 1, 0, 0, 248, 0, 2, -0, 223, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 13, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 2, 0, 0, 13, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 2, 0, 0, 14, 2, 0, 0, 15, 2, 0, 0, 12, 0, 6, -0, 5, 0, 0, 0, 17, 2, 0, 0, 9, 1, 0, 0, 4, 0, 0, 0, 16, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 18, 2, 0, 0, 17, 2, 0, 0, 208, 1, 0, 0, 247, 0, 3, 0, 11, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 18, 2, 0, 0, 10, 2, 0, -0, 11, 2, 0, 0, 248, 0, 2, 0, 10, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 21, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 22, 2, 0, 0, 200, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 23, 2, 0, 0, 22, 2, 0, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 24, 2, 0, 0, 200, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 25, 2, 0, -0, 24, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 25, 2, 0, 0, 65, 0, 5, 0, 195, 0, 0, 0, 26, 2, 0, 0, 200, 1, 0, 0, 245, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, -0, 27, 2, 0, 0, 240, 1, 0, 0, 62, 0, 3, 0, 26, 2, 0, 0, 27, 2, 0, 0, 249, 0, 2, 0, 11, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 200, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 31, 2, 0, -0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 2, 0, 0, 31, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 33, 2, 0, 0, 29, 2, 0, 0, 32, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 35, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 2, 0, 0, 35, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 37, 2, 0, 0, 33, 2, 0, 0, 36, 2, 0, 0, 62, 0, 3, 0, 28, 2, 0, 0, 37, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 38, 2, 0, 0, 28, 2, 0, -0, 254, 0, 2, 0, 38, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 58, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 59, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 60, 2, 0, 0, 57, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 62, 2, 0, 0, 46, 2, 0, 0, 62, 0, 3, 0, 60, 2, 0, 0, 62, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 63, 2, 0, 0, 57, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 65, 2, 0, 0, 48, 2, 0, 0, 62, 0, 3, -0, 63, 2, 0, 0, 65, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 2, 0, 0, 57, 2, 0, 0, 67, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 68, 2, 0, 0, 50, 2, 0, 0, 62, 0, 3, 0, 66, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 69, 2, 0, 0, 57, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 71, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 69, 2, 0, 0, 71, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 72, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 73, 2, 0, 0, 57, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 75, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 44, 2, 0, 0, 75, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 93, 2, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 94, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 95, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 96, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 96, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 97, 2, 0, 0, 92, 2, 0, 0, 64, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 2, 0, 0, 80, 2, 0, 0, 62, 0, 3, 0, 97, 2, 0, 0, 98, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 99, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 102, 2, 0, 0, 83, 2, 0, -0, 62, 0, 3, 0, 101, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 103, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 105, 2, 0, 0, 85, 2, 0, 0, 62, 0, 3, 0, 103, 2, 0, 0, 105, 2, 0, 0, 57, 0, 4, -0, 30, 0, 0, 0, 106, 2, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 107, 2, 0, 0, 92, 2, 0, 0, 74, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 108, 2, 0, 0, 65, 0, 5, -0, 74, 0, 0, 0, 109, 2, 0, 0, 92, 2, 0, 0, 61, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 110, 2, 0, 0, 109, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 110, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 2, 0, 0, 92, 2, 0, 0, 67, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 2, 0, 0, 111, 2, 0, 0, 62, 0, 3, 0, 82, 2, 0, 0, 112, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 113, 2, 0, 0, 92, 2, 0, 0, 70, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 114, 2, 0, 0, 113, 2, 0, -0, 62, 0, 3, 0, 84, 2, 0, 0, 114, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 115, 2, 0, 0, 92, 2, 0, 0, 104, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 116, 2, 0, 0, 115, 2, 0, 0, 62, 0, 3, 0, 86, 2, 0, 0, 116, 2, 0, 0, 253, 0, 1, +0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, +0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, +0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, +0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, +0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, +0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, +0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, +0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 128, +63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, 184, +60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, 78, +65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, +0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, +0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, +0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, +0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, +0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, 0, +0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, 0, +0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, +0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, +0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, +0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, +0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, +0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, 0, +0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, +0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, 0, +0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, +0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, +0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, +0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, +0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, +0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, 0, +0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, 0, +0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, +0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, 0, +0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, +0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, +0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, +0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, 0, +0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, 0, +0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, +0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, 0, +0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, 5, +0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, 2, +0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, 6, +0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, 0, +0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, 0, +0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, +0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, +0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, 0, +0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, +0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, 3, +0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, +0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, 5, +0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, 0, +0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index 1b39f92fe3..2275039ade 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -38,179 +38,175 @@ public partial class SpriteEffect 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, -1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 232, 235, 99, 87, 159, 250, 240, 73, -55, 165, 190, 209, 145, 166, 215, 143, 0, 68, 21, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, -101, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 216, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 209, 0, 0, 0, 207, 0, 0, 0, 215, 0, 0, 0, 192, 0, 0, 0, 40, 0, 0, -0, 87, 0, 0, 0, 250, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 236, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 226, 0, 0, 0, 229, 0, 0, 0, 225, 0, 0, 0, 227, 0, 0, 0, 235, 0, 0, 0, 116, 0, 0, 0, 250, 0, 0, -0, 16, 0, 3, 0, 216, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, -0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, -108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 203, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 228, 13, 54, 98, 231, 53, 171, 232, +53, 251, 148, 122, 53, 33, 81, 141, 0, 192, 20, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 217, 0, 0, +0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 210, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 251, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 237, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 251, 0, 0, 0, 16, 0, 3, 0, 217, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, -100, 115, 108, 0, 0, 7, 0, 20, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, -97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, -116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, -97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, -0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, -105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, -83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, -0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 188, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, -116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 193, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 208, 0, 0, -0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 210, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 209, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 211, 0, 0, -0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, -0, 213, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 213, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, -0, 5, 0, 8, 0, 214, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 216, 0, 0, 0, 83, 112, 114, -105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 225, 0, 0, -0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 226, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 227, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 230, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, -0, 5, 0, 6, 0, 229, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 231, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 233, 0, 0, -0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 233, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, -110, 0, 0, 0, 0, 5, 0, 8, 0, 234, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 235, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 236, 0, 0, -0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 248, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, -115, 0, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 249, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 250, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, -0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, -116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 207, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 209, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 209, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 225, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 226, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, -0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 229, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 229, 0, 0, -0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 248, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, -0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, -0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, -0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, -0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, -0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, -0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, -0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, -0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, -0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, -0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 194, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, -0, 193, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 210, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 211, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, -0, 213, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 214, 0, 0, 0, 6, 0, 0, 0, 213, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 228, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 230, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 231, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, -0, 233, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 234, 0, 0, 0, 6, 0, 0, 0, 233, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 241, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 248, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, -0, 249, 0, 0, 0, 2, 0, 0, 0, 248, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, -0, 249, 0, 0, 0, 250, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 207, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 214, 0, 0, 0, 215, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 208, 0, 0, 0, 225, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 226, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 227, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 230, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 234, 0, 0, 0, 235, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 135, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, -0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, -0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 188, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, -0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, -0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 197, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, -0, 119, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 251, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, -0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 217, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 218, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 220, 0, 0, 0, 209, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 220, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 221, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 222, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 224, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 224, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 237, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, -0, 238, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 239, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 239, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 240, 0, 0, 0, 242, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 243, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 244, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 245, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 246, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, -0, 227, 0, 0, 0, 247, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 232, 235, 99, 87, 159, 250, 240, 73, 55, 165, 190, 209, 145, 166, 215, 143, 0, 68, 21, 0, 0, -3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 216, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 209, 0, 0, 0, 207, 0, 0, 0, 215, 0, 0, 0, 192, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 250, 0, 0, 0, 15, 0, 14, 0, -0, 0, 0, 0, 236, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 226, 0, 0, 0, 229, 0, 0, 0, 225, 0, 0, 0, 227, 0, 0, 0, 235, 0, 0, 0, 116, 0, 0, 0, 250, 0, 0, 0, 16, 0, 3, 0, 216, 0, 0, 0, 7, 0, 0, 0, -7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, -0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, -100, 115, 108, 0, 7, 0, 20, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 21, 0, 203, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 204, 0, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, -115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, -84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, -111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, -46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, -110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, -116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 188, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, -5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 193, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, -108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 210, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, -5, 0, 6, 0, 209, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 211, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 211, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 213, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 214, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 216, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 219, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 223, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 225, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 226, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, -5, 0, 6, 0, 227, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 230, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 229, 0, 0, 0, 105, 110, 95, 86, -83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 231, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 231, 0, 0, 0, -1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 232, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, -6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 233, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 234, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 235, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 236, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, -46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 241, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 248, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, -0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 249, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, -0, 0, 0, 0, 5, 0, 4, 0, 250, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, -116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, -2, 0, 0, 0, 71, 0, 4, 0, 207, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 209, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 209, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, -225, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 226, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, -0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 229, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 229, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, -0, 0, 0, 0, 71, 0, 3, 0, 248, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 248, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, -87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, -250, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 250, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, -6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, -5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, -0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, -113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, -189, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 194, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 193, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, -3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 210, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 211, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 213, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, -32, 0, 4, 0, 214, 0, 0, 0, 6, 0, 0, 0, 213, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 223, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, -32, 0, 4, 0, 230, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 231, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 233, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 234, 0, 0, 0, 6, 0, 0, 0, 233, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 241, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 248, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 249, 0, 0, 0, 2, 0, 0, 0, 248, 0, 0, 0, -59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 249, 0, 0, 0, 250, 0, 0, 0, 2, 0, 0, 0, -59, 0, 4, 0, 208, 0, 0, 0, 207, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 210, 0, 0, 0, 209, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 214, 0, 0, 0, 215, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 225, 0, 0, 0, 3, 0, 0, 0, -59, 0, 4, 0, 210, 0, 0, 0, 226, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 227, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 230, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 234, 0, 0, 0, 235, 0, 0, 0, 6, 0, 0, 0, -54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 235, 0, 0, 0, -241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, -142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 149, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 188, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, -0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, -172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, -254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 197, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 200, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, -251, 0, 0, 0, 250, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 251, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, -30, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 217, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 218, 0, 0, 0, 215, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 220, 0, 0, 0, 209, 0, 0, 0, 62, 0, 3, 0, -218, 0, 0, 0, 220, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 221, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 222, 0, 0, 0, 215, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 224, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, -207, 0, 0, 0, 224, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 237, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 238, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 239, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 239, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 0, 0, 0, 229, 0, 0, 0, -62, 0, 3, 0, 240, 0, 0, 0, 242, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 243, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 244, 0, 0, 0, 235, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, -62, 0, 3, 0, 225, 0, 0, 0, 245, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 246, 0, 0, 0, 235, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 247, 0, 0, 0, 253, 0, 1, 0, -56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, +0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 206, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, +0, 7, 0, 20, 0, 207, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, +0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, +101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, +0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, +114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, +0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, +0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 189, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 190, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 209, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 111, 117, 116, +95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, +85, 84, 0, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 214, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 214, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 214, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 215, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 5, 0, 5, 0, 216, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 217, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 220, 0, 0, +0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 224, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 226, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 227, 0, 0, +0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 229, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 228, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 5, 0, 7, 0, 231, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 230, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 232, 0, 0, +0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, +0, 233, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 5, 0, 5, 0, 234, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 234, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 234, 0, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 234, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 235, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 237, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, +0, 242, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 249, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, +0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 250, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, +0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 208, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 210, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 210, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 228, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 228, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 230, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 230, 0, 0, 0, 3, 22, 0, +0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 249, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, +0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, +0, 2, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, +0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, +0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, +0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, +0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, +0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, +0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, +0, 38, 0, 0, 0, 32, 0, 4, 0, 190, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 195, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, +0, 32, 0, 4, 0, 209, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 213, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 214, 0, 0, +0, 4, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 215, 0, 0, 0, 6, 0, 0, 0, 214, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 229, 0, 0, +0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 231, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 233, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 234, 0, 0, +0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 235, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 242, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 249, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 250, 0, 0, +0, 2, 0, 0, 0, 249, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 250, 0, 0, +0, 251, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, 208, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 215, 0, 0, 0, 216, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, +0, 226, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 227, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 229, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 231, 0, 0, 0, 230, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 235, 0, 0, +0, 236, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 136, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, +0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, +0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 189, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, +0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, +0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, +0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 198, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 120, 0, 0, +0, 65, 0, 5, 0, 190, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 203, 0, 0, 0, 201, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 218, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 219, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 221, 0, 0, +0, 210, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 221, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 222, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 223, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, +0, 223, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 225, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 238, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 239, 0, 0, +0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 240, 0, 0, 0, 227, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 240, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 243, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 241, 0, 0, 0, 243, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 244, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 226, 0, 0, 0, 246, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 247, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 248, 0, 0, 0, 247, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, +0, 248, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 228, 13, 54, 98, 231, 53, 171, 232, 53, 251, 148, 122, 53, 33, 81, 141, 0, 192, 20, 0, 0, 3, 2, 35, 7, +0, 4, 1, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 217, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, +210, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 251, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 237, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 226, 0, 0, 0, +228, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 251, 0, 0, 0, 16, 0, 3, 0, 217, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, +7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, +3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, +115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, +7, 0, 21, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 207, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, +5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, +111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, +120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, +46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, +189, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 190, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 194, 0, 0, 0, +102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 209, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, +5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 73, +78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 214, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 214, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 214, 0, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 215, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, +83, 0, 0, 0, 5, 0, 9, 0, 217, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 220, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 224, 0, 0, 0, +105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 226, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 227, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +5, 0, 7, 0, 229, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 228, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 231, 0, 0, 0, 112, 116, 114, 95, +73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 230, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, +232, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 234, 0, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 234, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 234, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +234, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 235, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 115, 116, 114, 101, +97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 237, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 242, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, +249, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, +250, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, +208, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 210, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 210, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 11, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 228, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, +228, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 230, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 230, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, +249, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, +72, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 34, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, +20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, +6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, +24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, +139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 190, 0, 0, 0, 2, 0, 0, 0, +4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 195, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 32, 0, 4, 0, 209, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, +32, 0, 4, 0, 211, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 213, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 214, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 215, 0, 0, 0, +6, 0, 0, 0, 214, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 229, 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 231, 0, 0, 0, +1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 233, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 234, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +235, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 242, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 249, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 250, 0, 0, 0, 2, 0, 0, 0, 249, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, +41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 250, 0, 0, 0, 251, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, +208, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 215, 0, 0, 0, 216, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, 226, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, +227, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 229, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 231, 0, 0, 0, 230, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 235, 0, 0, 0, 236, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, +118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, +137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, +216, 0, 0, 0, 224, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 189, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, +248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, +38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, +56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 198, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 120, 0, 0, 0, 65, 0, 5, 0, 190, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, +224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 203, 0, 0, 0, 201, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 217, 0, 0, 0, +0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 218, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 219, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 221, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 221, 0, 0, 0, +57, 0, 4, 0, 30, 0, 0, 0, 222, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 223, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, 0, 223, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 225, 0, 0, 0, +253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 238, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 239, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, +240, 0, 0, 0, 227, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 240, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 241, 0, 0, 0, +243, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 244, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 226, 0, 0, 0, +246, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 247, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 248, 0, 0, 0, 247, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 248, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, +0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index 6768993f5e..ba637b3834 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -28,249 +28,245 @@ internal partial class UIEffect 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -71, 236, 145, 150, 195, 240, 161, 2, 171, 253, 209, 255, 135, 45, 216, 175, 0, 44, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, -117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, -83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, -0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, -0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, -0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, -0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, -99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, -49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, -0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, -0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, -53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, -0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, -102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, -0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, -0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, -0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, -0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, -108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, -80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, -0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, -0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, -0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, -100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, -0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, -0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, -95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, -0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, -122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, -83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, -0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, -0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, -116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, -116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, -0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, -0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, -0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, -76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, +138, 19, 107, 122, 199, 8, 163, 87, 21, 65, 113, 115, 15, 239, 117, 147, 0, 172, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, +100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, +0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, +0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, +0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, +0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, +0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, +108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, +0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, +101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, +0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, +114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, +0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, +55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, +0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, +0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, +0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, +0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, +0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, +101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, +116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, +122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, +110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, +0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, +0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, +84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, +122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, +0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, +0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, +0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, +0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, +105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, +0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, +0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, +0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, +0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, +114, 0, 0, 0, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, +0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, +76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, -0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, -0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, -64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, -63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, -0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, -0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, -0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, -0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, -0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, -0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, -0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, -0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, -0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, -0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, -0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, -0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, -0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, -0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, -0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, -0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, -0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, -0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, -0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, -0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, -0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, -0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, -0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, -0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, -0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, -0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, -0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, -0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, -0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, -0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, -0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, -0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, -0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 71, 236, 145, 150, 195, 240, 161, 2, 171, 253, 209, 255, 135, 45, 216, 175, 0, 44, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, -0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, -14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, -87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, -228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, -0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, -121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, -5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, -5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, -102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, -87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, -102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, -49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, -137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, -97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, -56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, -102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, -102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, -0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, -5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, -101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, -111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, -112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, -194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, -195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, -196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, -6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, -97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 202, 1, 0, 0, -105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, -111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, -117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, -219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, -5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, -78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, -2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, -225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, -6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, -114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, -115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, -238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, -117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, -3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, -71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, -67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, -2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, -71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, +0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, +64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, +63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, +0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, +0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, +0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, +0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, +0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, +0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, +0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, +0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, +0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, +0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, +0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, +0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, +0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, +0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, +0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, +0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, +0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, +0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, +0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, +0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, +0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, +0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, +0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, +0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, +0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, +0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, +0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, +0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, +0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, +0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, +0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, +0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, +0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 138, 19, 107, 122, 199, 8, 163, 87, 21, 65, 113, 115, 15, 239, 117, 147, 0, 172, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, +0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, +105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, 0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, +101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, +109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, +116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, +7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, +5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, +5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, +112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, +116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, +49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, +154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, +105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, +52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, +48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, +48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, +5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, +97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, +115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, +116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, +5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, +112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, +111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, +83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, +1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, +101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, +209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, +216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, +5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, +122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, +228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, +3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, +11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, +71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, +67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, +2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, +71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, -63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, -85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, -137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, -173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, -43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, -43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, -43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, -38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, -42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, -173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, -224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, -4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, -87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, -192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, -216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, -221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, -153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, -157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, -135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, -165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, -168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, -170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, -154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, -54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, -65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, -83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, -248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, -59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, -65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, -159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, -248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, -139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, -170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, -205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, -0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, -65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, -208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, -212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, -228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, -236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, -239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, -242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, -228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, +64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, +86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, +138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, +174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, +43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, +43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, +43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, +38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, +43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, +174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, +225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, +4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, +88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, +193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, +217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, +222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, +154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, +158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, +136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, +166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, +169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, +171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, +155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, +54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, +84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, +248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, +59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, +65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, +160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, +248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, +140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, +171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, +206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, +0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, +209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, +213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, +229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, +240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, +243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, +229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index 0345fba734..62b2307eb6 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -28,248 +28,244 @@ internal partial class UIEffect 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -200, 72, 40, 130, 97, 40, 68, 244, 198, 74, 215, 249, 17, 3, 174, 184, 0, 28, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, -117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, -83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, -0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, -0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, -0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, -0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, -99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, -49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, -0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, -0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, -53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, -0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, -97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, -95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, -0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, -0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, -62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, -0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, -0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, -0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, -0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, -0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, -0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, -62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, -0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, -116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, -67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, -0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, -0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, -87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, +10, 120, 114, 143, 194, 186, 206, 247, 240, 97, 17, 133, 2, 25, 30, 123, 0, 156, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, +100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, +0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, +0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, +0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, +0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, +0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, +108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, +0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, +101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, +0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, +114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, +0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, +55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, +0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, +0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, +0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, +0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, +0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, +77, 97, 105, 110, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, +0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, +111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, +115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, +0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, +0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, +0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, +0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, +0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, +101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, +95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, +95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, +102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, +0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, +0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, +84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, +0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, +0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, +101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, +95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, +67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, +0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, +0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, +87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, -0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, -0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, -0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, -0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, -60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, -0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, -0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, -0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, -0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, -0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, -0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, -0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, -0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, -0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, -0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, -0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, 228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, -0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, -0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, -0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, -0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, -0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, -0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, -0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, -0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, -0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, -0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, -0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, -0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, -0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, -0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, -0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, -0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, -0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, -0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, -0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, -0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, -0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, -0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, -0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, 246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 200, 72, 40, 130, 97, 40, 68, 244, 198, 74, 215, 249, 17, 3, 174, 184, 0, 28, 30, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, -83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, -4, 0, 0, 0, 199, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 188, 1, 0, 0, 190, 1, 0, 0, 192, 1, 0, 0, 186, 1, 0, 0, 198, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 229, 1, 0, 0, -86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 215, 1, 0, 0, 218, 1, 0, 0, 219, 1, 0, 0, 221, 1, 0, 0, 214, 1, 0, 0, 216, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 228, 1, 0, 0, 16, 0, 3, 0, 199, 1, 0, 0, 7, 0, 0, 0, -7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, -115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 7, 0, 21, 0, 182, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, -97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, -5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, -109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, -121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, -95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, -0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, -5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, -27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, -68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, -46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, -101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, -139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, -171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, -101, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 186, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, -189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 191, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, -116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 193, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 192, 1, 0, 0, -105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 194, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, -194, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 194, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, -0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, -196, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 196, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, -197, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 198, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 199, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 202, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, -208, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 212, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 214, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, -215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 217, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 218, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 220, 1, 0, 0, 111, 117, 116, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 221, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 223, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, -5, 0, 6, 0, 222, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 0, 0, 6, 0, 6, 0, 224, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 224, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, -122, 108, 101, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -226, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, -227, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 229, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 238, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, -100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, -117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 188, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, -79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 190, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 190, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 192, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, -192, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 215, 1, 0, 0, -3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, -30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 218, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 219, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, -82, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 221, 1, 0, 0, -3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, -71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, +0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, +0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, +0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, +0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, +60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, +0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, +0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, +0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, +0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, +0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, +0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, +0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, +0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, +0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, +0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, +0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, +0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, +0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, +0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, +0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, +0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, +0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, +0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, +0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, +0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, +0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, +0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, +0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, +0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, +0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, +0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, +0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, +0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, +0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, +0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, +0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, +0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, +0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, +0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, +0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 10, 120, 114, 143, 194, 186, 206, 247, 240, 97, 17, 133, 2, 25, 30, 123, 0, 156, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, +192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, +191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, 0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, +222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, +0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, +36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, +7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, +46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, +128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, +95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, +102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, +5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, +102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, +116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, +84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, +101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, +105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, +115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, +116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, +52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, +189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, +78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, +83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, +2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, +5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, +5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, +112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, +105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, +225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, +6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, +226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, +3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, +5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, +79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, +193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, +3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, +30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, +82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, +3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, +71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, -42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, -69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, -121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, -5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, -153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, -178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, -43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, -43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, -41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 3, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 191, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 194, 1, 0, 0, 42, 0, 0, 0, -4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 195, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 196, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 197, 1, 0, 0, 6, 0, 0, 0, 196, 1, 0, 0, 43, 0, 4, 0, -173, 0, 0, 0, 202, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 205, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 212, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -217, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 224, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 4, 0, 0, 0, -42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 226, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 227, 1, 0, 0, 6, 0, 0, 0, 226, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, -238, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, -188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 190, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 192, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 197, 1, 0, 0, 198, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, -214, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 217, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, 218, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 191, 1, 0, 0, -219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 220, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 221, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 222, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 227, 1, 0, 0, -228, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, -135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, -127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, -165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, -168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, -81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, -177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, -153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 228, 1, 0, 0, 212, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, -110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, -228, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, -126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, -56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 198, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, -157, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, -62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, -167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, -173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, -177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 199, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 201, 1, 0, 0, 198, 1, 0, 0, -202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 203, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 203, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 204, 1, 0, 0, 198, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 206, 1, 0, 0, -190, 1, 0, 0, 62, 0, 3, 0, 204, 1, 0, 0, 206, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 207, 1, 0, 0, 198, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 209, 1, 0, 0, -57, 0, 4, 0, 30, 0, 0, 0, 210, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 211, 1, 0, 0, 198, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 213, 1, 0, 0, -253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, -232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 1, 0, 0, 228, 1, 0, 0, 205, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 234, 1, 0, 0, 218, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, -234, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 235, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 236, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 235, 1, 0, 0, 236, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 237, 1, 0, 0, -228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 221, 1, 0, 0, 62, 0, 3, 0, 237, 1, 0, 0, 239, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 240, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, -228, 1, 0, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 214, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 202, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, -244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 244, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 1, 0, 0, 228, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 1, 0, 0, 245, 1, 0, 0, 62, 0, 3, 0, 220, 1, 0, 0, -246, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 238, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 247, 1, 0, 0, 62, 0, 3, 0, 222, 1, 0, 0, 248, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, +43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, +70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, +122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, +5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, +154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, +179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, +43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, +43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, +41, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, +4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, +174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, +43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, +239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, +189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, +215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, +220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, +229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, +136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, +128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, +166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, +169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, +81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, +178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, +154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, +111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, +229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, +127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, +158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, +62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, +168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, +174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, +178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, +203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, +191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, +57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, +253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, +233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, +235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, +229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, +229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, +245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, +247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index ea0392654d..de311e9754 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -28,270 +28,266 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, -0, 0, 1, 149, 78, 118, 157, 84, 228, 107, 89, 7, 114, 154, 228, 121, 240, 170, 112, 0, 208, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, -76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 71, 1, 0, 0, -80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 1, 0, 0, 64, 1, 0, 0, 60, 1, 0, 0, 70, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 95, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, -101, 114, 0, 0, 84, 1, 0, 0, 87, 1, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 85, 1, 0, 0, 89, 1, 0, 0, 94, 1, 0, 0, 16, 0, 3, 0, 71, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +0, 0, 1, 152, 19, 190, 249, 47, 157, 209, 201, 185, 214, 254, 218, 145, 246, 217, 253, 0, 80, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 112, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 123, 0, 0, 0, 71, 76, 83, 76, +46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 72, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 63, 1, 0, 0, 65, 1, 0, 0, 61, 1, 0, 0, +71, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 96, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 85, 1, 0, 0, 88, 1, 0, 0, 89, 1, 0, 0, 84, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, +95, 1, 0, 0, 16, 0, 3, 0, 72, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, +0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, +36, 0, 0, 0, 7, 0, 23, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 19, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, +226, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 7, 0, 21, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, -3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, -115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, -0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 19, 0, 223, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 225, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 225, 0, 0, 0, 7, 0, 21, 0, 56, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 59, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, -0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, -103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, -97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, -112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, -112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, -112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, -5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, -141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, -5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, -99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, -115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, -182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, -105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, -105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, -231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, -99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 10, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 35, 1, 0, 0, -98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 39, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, -101, 115, 115, 0, 5, 0, 7, 0, 61, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, -63, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 62, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 65, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, -116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 64, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 66, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 66, 1, 0, 0, 0, 0, 0, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 66, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 68, 1, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 68, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 69, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 0, 0, 5, 0, 5, 0, 70, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 71, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, -77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 74, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, -5, 0, 8, 0, 83, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 84, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, -112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 5, 0, 5, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 89, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, -0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 1, 0, 0, 2, 0, 0, 0, -67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 91, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 1, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 92, 1, 0, 0, -0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, -0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 93, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, -115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 95, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, -0, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, -116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 60, 1, 0, 0, -30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 64, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, -0, 22, 5, 0, 64, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 84, 1, 0, 0, 3, 22, 0, 0, -84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, -1, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 88, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, -71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, +7, 0, 20, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 59, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 60, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, +5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, +109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 112, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 115, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, +114, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 118, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 133, 0, 0, 0, +115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 136, 0, 0, 0, +98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 142, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 144, 0, 0, 0, 115, 104, 97, 114, +112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 146, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, +147, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 150, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 155, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, +105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 165, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 169, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 172, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, +5, 0, 4, 0, 174, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 97, 114, 68, +105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 195, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, +110, 101, 0, 0, 5, 0, 6, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 184, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, +104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 233, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, +5, 0, 7, 0, 11, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 36, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, +5, 0, 4, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 40, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 62, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, +52, 0, 0, 0, 5, 0, 7, 0, 61, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 64, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, +63, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 67, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 69, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, +77, 83, 0, 0, 6, 0, 6, 0, 69, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 69, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 69, 1, 0, 0, 2, 0, 0, 0, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 70, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 71, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, +72, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 75, 1, 0, 0, 105, 110, 116, 95, +49, 0, 0, 0, 5, 0, 4, 0, 78, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 86, 1, 0, 0, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, +90, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, +6, 0, 6, 0, 91, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 7, 0, 92, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 2, 0, 0, 0, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 93, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 93, 1, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, +94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 96, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 61, 1, 0, 0, +30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 63, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 5, 0, 65, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, +84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 86, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, +1, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, +71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, -25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, -2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, -32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, -7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, -0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, -1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, -0, 0, 0, 64, 33, 0, 3, 0, 6, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 32, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, -61, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 63, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 65, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 66, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, -67, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 68, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 69, 1, 0, 0, 6, 0, 0, 0, 68, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, -138, 0, 0, 0, 77, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 90, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, -30, 0, 5, 0, 91, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 92, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 93, 1, 0, 0, 6, 0, 0, 0, 92, 1, 0, 0, 43, 0, 4, 0, -138, 0, 0, 0, 102, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 60, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -63, 1, 0, 0, 62, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 64, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 69, 1, 0, 0, 70, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 83, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -63, 1, 0, 0, 84, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -61, 1, 0, 0, 89, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 93, 1, 0, 0, 94, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, -114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, -5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, -125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, -12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, -131, 0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, -7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, -141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, -62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, -114, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, -163, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, -167, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, -172, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, -164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, -186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, -62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, -62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, -188, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, -154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, -214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, -248, 0, 2, 0, 183, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, -173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, -62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -243, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 250, 0, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 252, 0, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, -250, 0, 0, 0, 253, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 255, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 4, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 4, 1, 0, 0, 8, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 248, 0, 2, 0, 9, 1, 0, 0, -59, 0, 4, 0, 131, 0, 0, 0, 10, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 35, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 39, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 43, 1, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 131, 0, 0, 0, 45, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 49, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 22, 1, 0, 0, 87, 0, 0, 0, -65, 0, 5, 0, 74, 0, 0, 0, 29, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 31, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 32, 1, 0, 0, 33, 1, 0, 0, -31, 1, 0, 0, 22, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 10, 1, 0, 0, 34, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 36, 1, 0, 0, 36, 1, 0, 0, -36, 1, 0, 0, 37, 1, 0, 0, 62, 0, 3, 0, 35, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 39, 1, 0, 0, 36, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 44, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 43, 1, 0, 0, 44, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 47, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 48, 1, 0, 0, 47, 1, 0, 0, 62, 0, 3, 0, 45, 1, 0, 0, 48, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 50, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, -49, 1, 0, 0, 50, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 52, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 52, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 55, 1, 0, 0, 111, 0, 0, 0, 43, 1, 0, 0, 45, 1, 0, 0, 49, 1, 0, 0, -51, 1, 0, 0, 254, 0, 2, 0, 55, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 71, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 72, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 73, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 75, 1, 0, 0, 62, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 75, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 76, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 78, 1, 0, 0, 64, 1, 0, 0, -62, 0, 3, 0, 76, 1, 0, 0, 78, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 79, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 80, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 82, 1, 0, 0, 80, 1, 0, 0, -62, 0, 3, 0, 60, 1, 0, 0, 82, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 96, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 97, 1, 0, 0, 94, 1, 0, 0, -74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 98, 1, 0, 0, 84, 1, 0, 0, 62, 0, 3, 0, 97, 1, 0, 0, 98, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 1, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 1, 0, 0, -87, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 94, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, -57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 83, 1, 0, 0, 106, 1, 0, 0, -65, 0, 5, 0, 74, 0, 0, 0, 107, 1, 0, 0, 94, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 108, 1, 0, 0, 107, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 108, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 94, 1, 0, 0, -102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 110, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 110, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, -0, 1, 149, 78, 118, 157, 84, 228, 107, 89, 7, 114, 154, 228, 121, 240, 170, 112, 0, 208, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, -69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 71, 1, 0, 0, 80, -83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 62, 1, 0, 0, 64, 1, 0, 0, 60, 1, 0, 0, 70, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 95, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, -114, 0, 0, 84, 1, 0, 0, 87, 1, 0, 0, 88, 1, 0, 0, 83, 1, 0, 0, 85, 1, 0, 0, 89, 1, 0, 0, 94, 1, 0, 0, 16, 0, 3, 0, 71, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, -47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, -0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, -105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, -114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, -108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, -105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, -0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 19, 0, 223, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, -83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 225, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, -100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, -0, 0, 0, 225, 0, 0, 0, 7, 0, 21, 0, 56, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, -101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, -47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 59, 1, 0, 0, 67, -58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, -99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, -116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, -0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, -110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, -0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, -108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, -110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 112, -116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, 112, -116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, -0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 141, -0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, -0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, -101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, 115, -105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 182, -0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, 105, -115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, -102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, -0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, -101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 10, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 35, 1, 0, 0, 98, -111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 39, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, -115, 115, 0, 5, 0, 7, 0, 61, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 63, -1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 62, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 65, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, -95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 64, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 66, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 66, 1, 0, 0, 0, 0, 0, 0, 84, -101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 66, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 68, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 68, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 69, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 0, 0, 5, 0, 5, 0, 70, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 71, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 74, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 77, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 81, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, -0, 8, 0, 83, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 84, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, -116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, -110, 0, 0, 5, 0, 5, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 89, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, -0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 90, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 90, 1, 0, 0, 2, 0, 0, 0, 67, -111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 91, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 92, 1, 0, 0, 0, -0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, -0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 93, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 115, -116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 95, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, -101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 4, 0, 60, 1, 0, 0, 30, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 62, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 62, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 64, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, -22, 5, 0, 64, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 84, 1, 0, 0, 3, 22, 0, 0, 84, -69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 1, -0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 88, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, -0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, +25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, +2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, +32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 32, 0, 4, 0, 115, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 114, 0, 0, 0, 5, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, +7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 131, 0, 0, 0, 4, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 115, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, +0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 142, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 155, 0, 0, 0, +1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 159, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 172, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 192, 0, 0, 0, +0, 0, 0, 64, 33, 0, 3, 0, 7, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 33, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, +62, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 66, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 67, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, +68, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 69, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 70, 1, 0, 0, 6, 0, 0, 0, 69, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, +139, 0, 0, 0, 78, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 91, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, +30, 0, 5, 0, 92, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 93, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, +139, 0, 0, 0, 103, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 61, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +64, 1, 0, 0, 63, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 65, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 71, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +64, 1, 0, 0, 85, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +62, 1, 0, 0, 90, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, +115, 0, 0, 0, 117, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 118, 0, 0, 0, 248, 0, 2, 0, 119, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 121, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, +5, 0, 0, 0, 122, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 125, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, +126, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 124, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 118, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 126, 0, 0, 0, 127, 0, 0, 0, +12, 0, 7, 0, 5, 0, 0, 0, 129, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 122, 0, 0, 0, 128, 0, 0, 0, 254, 0, 2, 0, 129, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 55, 0, 3, 0, +132, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 135, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 136, 0, 0, 0, 248, 0, 2, 0, 137, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 144, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 154, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 158, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 165, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 174, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 195, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 199, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 208, 0, 0, 0, +7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 138, 0, 0, 0, 136, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 143, 0, 0, 0, 123, 0, 0, 0, 43, 0, 0, 0, 138, 0, 0, 0, 141, 0, 0, 0, +142, 0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 143, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 148, 0, 0, 0, 136, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 149, 0, 0, 0, 147, 0, 0, 0, 148, 0, 0, 0, +62, 0, 3, 0, 146, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 152, 0, 0, 0, 133, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, +115, 0, 0, 0, 156, 0, 0, 0, 133, 0, 0, 0, 155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 157, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 160, 0, 0, 0, 133, 0, 0, 0, 159, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 161, 0, 0, 0, 160, 0, 0, 0, 62, 0, 3, 0, 158, 0, 0, 0, 161, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 164, 0, 0, 0, 111, 0, 0, 0, 151, 0, 0, 0, 154, 0, 0, 0, 158, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, +164, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 0, 0, 0, 146, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 168, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 62, 0, 3, 0, 165, 0, 0, 0, +168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 165, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 169, 0, 0, 0, +173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 169, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 178, 0, 0, 0, +165, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 179, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 179, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 174, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 181, 0, 0, 0, 174, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 182, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 136, 0, 0, 0, +186, 0, 5, 0, 8, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 247, 0, 3, 0, 184, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 187, 0, 0, 0, 183, 0, 0, 0, 184, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +190, 0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 136, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 193, 0, 0, 0, +62, 0, 3, 0, 189, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, +62, 0, 3, 0, 195, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 195, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 195, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 203, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 205, 0, 0, 0, 202, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, +189, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 207, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 199, 0, 0, 0, 207, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 140, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, +155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 199, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 212, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 212, 0, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 216, 0, 0, 0, 215, 0, 0, 0, +215, 0, 0, 0, 215, 0, 0, 0, 215, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 217, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 217, 0, 0, 0, 249, 0, 2, 0, 184, 0, 0, 0, +248, 0, 2, 0, 184, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 219, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, +174, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 222, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 218, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, +62, 0, 3, 0, 133, 0, 0, 0, 222, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 223, 0, 0, 0, 133, 0, 0, 0, 254, 0, 2, 0, 223, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +244, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 253, 0, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, +251, 0, 0, 0, 254, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 5, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 5, 1, 0, 0, 9, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 248, 0, 2, 0, 10, 1, 0, 0, +59, 0, 4, 0, 132, 0, 0, 0, 11, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 40, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 132, 0, 0, 0, 46, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 52, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 23, 1, 0, 0, 88, 0, 0, 0, +65, 0, 5, 0, 75, 0, 0, 0, 30, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 31, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 32, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 33, 1, 0, 0, 34, 1, 0, 0, +32, 1, 0, 0, 23, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 11, 1, 0, 0, 35, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, +37, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 40, 1, 0, 0, 37, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 48, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 48, 1, 0, 0, 62, 0, 3, 0, 46, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 51, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, +50, 1, 0, 0, 51, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 53, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 52, 1, 0, 0, 53, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 56, 1, 0, 0, 112, 0, 0, 0, 44, 1, 0, 0, 46, 1, 0, 0, 50, 1, 0, 0, +52, 1, 0, 0, 254, 0, 2, 0, 56, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 73, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 74, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, +61, 0, 4, 0, 43, 0, 0, 0, 76, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 77, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 79, 1, 0, 0, 65, 1, 0, 0, +62, 0, 3, 0, 77, 1, 0, 0, 79, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 80, 1, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 81, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 83, 1, 0, 0, 81, 1, 0, 0, +62, 0, 3, 0, 61, 1, 0, 0, 83, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, +75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 99, 1, 0, 0, 85, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 99, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, +88, 1, 0, 0, 62, 0, 3, 0, 100, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 95, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, +57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 107, 1, 0, 0, +65, 0, 5, 0, 75, 0, 0, 0, 108, 1, 0, 0, 95, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 109, 1, 0, 0, 108, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 95, 1, 0, 0, +103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 111, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, +0, 1, 152, 19, 190, 249, 47, 157, 209, 201, 185, 214, 254, 218, 145, 246, 217, 253, 0, 80, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 112, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 123, 0, 0, 0, 71, 76, 83, 76, 46, +115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 72, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 63, 1, 0, 0, 65, 1, 0, 0, 61, 1, 0, 0, 71, +1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 96, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 85, 1, 0, 0, 88, 1, 0, 0, 89, 1, 0, 0, 84, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 95, +1, 0, 0, 16, 0, 3, 0, 72, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, +118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, +0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, +114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, +114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, +0, 0, 0, 7, 0, 23, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, +83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 19, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, +114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 226, +0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 7, 0, 21, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, +47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, +0, 20, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 59, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 60, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, +116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, +116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, +110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, +114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, +116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, +0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, +112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 112, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, +116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 115, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 114, +0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 118, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 133, 0, 0, 0, 115, +97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 136, 0, 0, 0, 98, +111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 142, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 144, 0, 0, 0, 115, 104, 97, 114, 112, +110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 146, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 147, +0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 150, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 155, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, 105, +110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 165, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 169, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 172, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, +0, 4, 0, 174, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 97, 114, 68, 105, +115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 195, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, +101, 0, 0, 5, 0, 6, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 184, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, +116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, +97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 233, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, +0, 7, 0, 11, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 36, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, +0, 4, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 40, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 62, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, +0, 0, 0, 5, 0, 7, 0, 61, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 64, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 63, +1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, +111, 114, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 67, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, +0, 0, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 69, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, +83, 0, 0, 6, 0, 6, 0, 69, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 69, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 69, 1, 0, 0, 2, 0, 0, 0, 67, +111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 70, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 71, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 72, +1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 75, 1, 0, 0, 105, 110, 116, 95, 49, +0, 0, 0, 5, 0, 4, 0, 78, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 86, 1, 0, 0, 111, +117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 90, +1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, +0, 6, 0, 91, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, +0, 7, 0, 92, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 2, 0, 0, 0, 67, +111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 93, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 93, 1, 0, 0, 1, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, +1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 96, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, +116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 61, 1, 0, 0, 30, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 63, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, +22, 5, 0, 65, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 86, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 1, +0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, +0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, +0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, -0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, -0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, -0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, -0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, -0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, -0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, -0, 0, 64, 33, 0, 3, 0, 6, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 32, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 61, -1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 63, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 65, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 66, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 67, -1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 68, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 69, 1, 0, 0, 6, 0, 0, 0, 68, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 74, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, -0, 0, 0, 77, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 81, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 90, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, -0, 5, 0, 91, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 92, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 93, 1, 0, 0, 6, 0, 0, 0, 92, 1, 0, 0, 43, 0, 4, 0, 138, -0, 0, 0, 102, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 60, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 63, -1, 0, 0, 62, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 64, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 69, 1, 0, 0, 70, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 61, 1, 0, 0, 83, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 63, -1, 0, 0, 84, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 65, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 61, -1, 0, 0, 89, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 93, 1, 0, 0, 94, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, -0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, -0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, -0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, -0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, -0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, 141, -0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, -0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, -0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 167, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, -0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, 186, -0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, -0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, -0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, -0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, -0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 154, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, 61, -0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, -0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, -0, 2, 0, 183, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, -0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, -0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 243, -0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 250, 0, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 252, 0, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 253, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 250, -0, 0, 0, 253, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 255, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 4, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 57, -0, 4, 0, 4, 0, 0, 0, 8, 1, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 4, 1, 0, 0, 8, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 248, 0, 2, 0, 9, 1, 0, 0, 59, -0, 4, 0, 131, 0, 0, 0, 10, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 35, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 39, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 43, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 131, 0, 0, 0, 45, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 49, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 51, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 22, 1, 0, 0, 87, 0, 0, 0, 65, -0, 5, 0, 74, 0, 0, 0, 29, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 31, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 32, 1, 0, 0, 33, 1, 0, 0, 31, -1, 0, 0, 22, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 30, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 10, 1, 0, 0, 34, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 36, 1, 0, 0, 36, 1, 0, 0, 36, -1, 0, 0, 37, 1, 0, 0, 62, 0, 3, 0, 35, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 39, 1, 0, 0, 36, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 44, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 43, 1, 0, 0, 44, 1, 0, 0, 65, 0, 5, 0, 3, -0, 0, 0, 47, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 48, 1, 0, 0, 47, 1, 0, 0, 62, 0, 3, 0, 45, 1, 0, 0, 48, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 50, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 49, -1, 0, 0, 50, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 52, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 51, 1, 0, 0, 52, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 55, 1, 0, 0, 111, 0, 0, 0, 43, 1, 0, 0, 45, 1, 0, 0, 49, 1, 0, 0, 51, -1, 0, 0, 254, 0, 2, 0, 55, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 71, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 72, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 73, 1, 0, 0, 70, 1, 0, 0, 74, 1, 0, 0, 61, -0, 4, 0, 42, 0, 0, 0, 75, 1, 0, 0, 62, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 75, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 76, 1, 0, 0, 70, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 78, 1, 0, 0, 64, 1, 0, 0, 62, -0, 3, 0, 76, 1, 0, 0, 78, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 79, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 80, 1, 0, 0, 70, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 82, 1, 0, 0, 80, 1, 0, 0, 62, -0, 3, 0, 60, 1, 0, 0, 82, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 95, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 96, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 97, 1, 0, 0, 94, 1, 0, 0, 74, -1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 98, 1, 0, 0, 84, 1, 0, 0, 62, 0, 3, 0, 97, 1, 0, 0, 98, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 1, 0, 0, 94, 1, 0, 0, 77, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 1, 0, 0, 87, -1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 94, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, 57, -0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 94, 1, 0, 0, 81, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 83, 1, 0, 0, 106, 1, 0, 0, 65, -0, 5, 0, 74, 0, 0, 0, 107, 1, 0, 0, 94, 1, 0, 0, 74, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 108, 1, 0, 0, 107, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 108, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 94, 1, 0, 0, 102, -1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 110, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 110, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, +0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, +0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, +0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 32, 0, 4, 0, 115, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 114, 0, 0, 0, 5, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, +0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 131, 0, 0, 0, 4, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 115, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, +0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 142, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 155, 0, 0, 0, 1, +0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 159, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 172, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 192, 0, 0, 0, 0, +0, 0, 64, 33, 0, 3, 0, 7, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 33, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 62, +1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 66, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 67, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 68, +1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 69, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 70, 1, 0, 0, 6, 0, 0, 0, 69, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, +0, 0, 0, 78, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 91, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, +0, 5, 0, 92, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 93, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 139, +0, 0, 0, 103, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 61, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 64, +1, 0, 0, 63, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 65, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 71, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 64, +1, 0, 0, 85, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 62, +1, 0, 0, 90, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 115, +0, 0, 0, 117, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 118, 0, 0, 0, 248, 0, 2, 0, 119, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 121, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, +0, 0, 0, 122, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 125, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 126, +0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 124, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 118, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 126, 0, 0, 0, 127, 0, 0, 0, 12, +0, 7, 0, 5, 0, 0, 0, 129, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 122, 0, 0, 0, 128, 0, 0, 0, 254, 0, 2, 0, 129, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 55, 0, 3, 0, 132, +0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 135, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 136, 0, 0, 0, 248, 0, 2, 0, 137, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 144, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 154, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 158, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 165, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 174, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 195, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 199, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 208, 0, 0, 0, 7, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 138, 0, 0, 0, 136, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 143, 0, 0, 0, 123, 0, 0, 0, 43, 0, 0, 0, 138, 0, 0, 0, 141, 0, 0, 0, 142, +0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 143, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 148, 0, 0, 0, 136, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 149, 0, 0, 0, 147, 0, 0, 0, 148, 0, 0, 0, 62, +0, 3, 0, 146, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 152, 0, 0, 0, 133, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, 115, +0, 0, 0, 156, 0, 0, 0, 133, 0, 0, 0, 155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 157, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 160, 0, 0, 0, 133, 0, 0, 0, 159, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 161, 0, 0, 0, 160, 0, 0, 0, 62, 0, 3, 0, 158, 0, 0, 0, 161, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 164, 0, 0, 0, 111, 0, 0, 0, 151, 0, 0, 0, 154, 0, 0, 0, 158, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 164, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 0, 0, 0, 146, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 168, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 62, 0, 3, 0, 165, 0, 0, 0, 168, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 165, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 169, 0, 0, 0, 173, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 169, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 178, 0, 0, 0, 165, +0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 179, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 179, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 174, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 181, 0, 0, 0, 174, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 182, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 136, 0, 0, 0, 186, +0, 5, 0, 8, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 247, 0, 3, 0, 184, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 187, 0, 0, 0, 183, 0, 0, 0, 184, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, +0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 136, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 193, 0, 0, 0, 62, +0, 3, 0, 189, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 62, +0, 3, 0, 195, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 195, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 195, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 203, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 205, 0, 0, 0, 202, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 189, +0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 207, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 199, 0, 0, 0, 207, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 140, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 155, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 199, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 212, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, +0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 216, 0, 0, 0, 215, 0, 0, 0, 215, +0, 0, 0, 215, 0, 0, 0, 215, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 217, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 217, 0, 0, 0, 249, 0, 2, 0, 184, 0, 0, 0, 248, +0, 2, 0, 184, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 219, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, 174, +0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 222, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 218, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 62, +0, 3, 0, 133, 0, 0, 0, 222, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 223, 0, 0, 0, 133, 0, 0, 0, 254, 0, 2, 0, 223, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 244, +0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 253, 0, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 251, +0, 0, 0, 254, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 5, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 57, +0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 5, 1, 0, 0, 9, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 248, 0, 2, 0, 10, 1, 0, 0, 59, +0, 4, 0, 132, 0, 0, 0, 11, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 40, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 132, 0, 0, 0, 46, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 52, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 23, 1, 0, 0, 88, 0, 0, 0, 65, +0, 5, 0, 75, 0, 0, 0, 30, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 31, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 32, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 33, 1, 0, 0, 34, 1, 0, 0, 32, +1, 0, 0, 23, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 11, 1, 0, 0, 35, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, +1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 40, 1, 0, 0, 37, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 65, 0, 5, 0, 3, +0, 0, 0, 48, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 48, 1, 0, 0, 62, 0, 3, 0, 46, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 51, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 50, +1, 0, 0, 51, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 53, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 52, 1, 0, 0, 53, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 56, 1, 0, 0, 112, 0, 0, 0, 44, 1, 0, 0, 46, 1, 0, 0, 50, 1, 0, 0, 52, +1, 0, 0, 254, 0, 2, 0, 56, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 73, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 74, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, +0, 4, 0, 43, 0, 0, 0, 76, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 77, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 79, 1, 0, 0, 65, 1, 0, 0, 62, +0, 3, 0, 77, 1, 0, 0, 79, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 80, 1, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 81, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 83, 1, 0, 0, 81, 1, 0, 0, 62, +0, 3, 0, 61, 1, 0, 0, 83, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 75, +1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 99, 1, 0, 0, 85, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 99, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 88, +1, 0, 0, 62, 0, 3, 0, 100, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 95, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, 57, +0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 107, 1, 0, 0, 65, +0, 5, 0, 75, 0, 0, 0, 108, 1, 0, 0, 95, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 109, 1, 0, 0, 108, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 95, 1, 0, 0, 103, +1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 111, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 50a766bb6c..4386f1b49b 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -34,291 +34,287 @@ internal partial class SpriteSignedDistanceFieldFontShader 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, -67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 172, 31, 37, 223, 167, 75, 230, 241, 177, 145, 157, 123, 125, 33, 17, 255, 0, 120, 35, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 136, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, -0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, 0, 0, 0, 0, 11, 0, 6, 0, 196, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, -0, 15, 0, 13, 0, 4, 0, 0, 0, 96, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 87, 1, 0, 0, 89, 1, 0, 0, 85, 1, 0, 0, 95, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 120, 1, 0, -0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 109, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 108, 1, 0, 0, 110, 1, 0, 0, 114, 1, 0, 0, 119, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 96, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, -0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, -0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, -0, 7, 0, 23, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, -103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 19, 0, 41, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 43, 1, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, -101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 0, 0, 7, 0, 21, 0, 80, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, -100, 115, 108, 0, 0, 7, 0, 20, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, -100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, -108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, -0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, -114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, -116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, -0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, -0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, -80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, -0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 184, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 188, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 189, 0, 0, -0, 114, 0, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 205, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 206, 0, 0, -0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 207, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 209, 0, 0, -0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 213, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 115, 104, 97, -114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 218, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, -0, 220, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 223, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 228, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 232, 0, 0, -0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 242, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, -0, 5, 0, 4, 0, 247, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 0, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 6, 1, 0, 0, 102, 97, 114, -68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 9, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 12, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, -105, 110, 101, 0, 0, 5, 0, 6, 0, 25, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 50, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, -97, 116, 95, 49, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 85, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, -0, 88, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 90, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 91, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, -0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 93, 1, 0, -0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 96, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, -97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 99, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 106, 1, 0, 0, 105, 110, 116, -95, 48, 0, 0, 0, 5, 0, 8, 0, 108, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 109, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, -0, 111, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 112, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, -111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 114, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 115, 1, 0, 0, 86, 83, 95, -73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 115, 1, 0, -0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 116, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, -0, 116, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, -0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 117, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 118, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, -0, 119, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 120, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 127, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, -0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, -0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 108, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 109, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 112, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 112, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 5, 0, 113, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, -0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, +67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 9, 158, 143, 78, 52, 171, 165, 186, 6, 208, 204, 34, 59, 136, 189, 143, 0, 248, 34, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, +0, 11, 0, 6, 0, 197, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 97, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 88, 1, 0, 0, 90, 1, 0, 0, 86, 1, 0, 0, 96, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 121, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 110, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, +0, 109, 1, 0, 0, 111, 1, 0, 0, 115, 1, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 97, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, +0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, +97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, +0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 19, 0, 42, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 44, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, +115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 83, 1, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, +115, 100, 115, 108, 0, 7, 0, 20, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 85, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, +97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, +0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, +83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, +0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 186, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, +0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 192, 0, 0, 0, 98, 0, 0, +0, 5, 0, 7, 0, 206, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 207, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 116, 101, 120, +116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 214, 0, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 218, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 219, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 224, 0, 0, 0, 109, 101, 100, +105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 233, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, +0, 243, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 246, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 7, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 10, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, +0, 13, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 17, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 26, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, +0, 5, 0, 5, 0, 2, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 51, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 75, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 52, 0, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 89, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, +0, 88, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 91, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 94, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 6, 0, 6, 0, 94, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 94, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 94, 1, 0, 0, 2, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 95, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 96, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, +0, 97, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 100, 1, 0, +0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 107, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 112, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, +0, 111, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +0, 5, 0, 6, 0, 115, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, +85, 84, 0, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, +0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 118, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 118, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, +0, 118, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 118, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 118, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 5, 0, 8, 0, 119, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 120, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 121, 1, 0, 0, 83, 112, 114, +105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 128, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 111, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 111, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 113, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 115, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 115, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, +0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, -0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, -0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 188, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 33, 0, 6, 0, 187, 0, 0, 0, 5, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 32, 0, 4, 0, 205, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 204, 0, 0, 0, 4, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, -0, 188, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, -0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 232, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, -0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 90, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 91, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 92, 1, 0, 0, 4, 0, 0, -0, 30, 0, 5, 0, 93, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 99, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 102, 1, 0, -0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 111, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 115, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, -0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 117, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 118, 1, 0, 0, 6, 0, 0, 0, 117, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 127, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 108, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 109, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 111, 1, 0, 0, 110, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 113, 1, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 114, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 118, 1, 0, 0, 119, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, -0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, -0, 50, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, -0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, -0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, -0, 187, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 189, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 191, 0, 0, 0, 248, 0, 2, 0, 192, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, -0, 201, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 202, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 195, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, -0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 206, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 209, 0, 0, -0, 248, 0, 2, 0, 210, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 217, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 219, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 223, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, -0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, -0, 242, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 247, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 6, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 12, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, -0, 16, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 25, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 209, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 213, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, -0, 216, 0, 0, 0, 196, 0, 0, 0, 43, 0, 0, 0, 211, 0, 0, 0, 214, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 209, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 217, 0, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 209, 0, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 222, 0, 0, 0, 220, 0, 0, 0, 221, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 222, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 225, 0, 0, 0, 206, 0, 0, 0, 213, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 0, 0, -0, 225, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 226, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 229, 0, 0, 0, 206, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 230, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 230, 0, 0, -0, 65, 0, 5, 0, 188, 0, 0, 0, 233, 0, 0, 0, 206, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 234, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 237, 0, 0, 0, 184, 0, 0, -0, 224, 0, 0, 0, 227, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 223, 0, 0, 0, 237, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, -0, 241, 0, 0, 0, 239, 0, 0, 0, 240, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 241, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 0, 0, 0, 238, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, -0, 246, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 242, 0, 0, 0, 246, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 242, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 250, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 238, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 252, 0, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, -0, 252, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 247, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, -0, 255, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 209, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 4, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 247, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 4, 1, 0, 0, 0, 1, 0, -0, 1, 1, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 1, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 209, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, -0, 129, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 7, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, 6, 1, 0, 0, 11, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 13, 1, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 6, 1, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, 12, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 217, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 12, 1, 0, -0, 133, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 12, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 20, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 22, 1, 0, -0, 19, 1, 0, 0, 21, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 24, 1, 0, 0, 22, 1, 0, 0, 23, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 24, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, -0, 26, 1, 0, 0, 213, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 16, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 29, 1, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 26, 1, 0, -0, 27, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 25, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, -0, 25, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 34, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 30, 1, 0, 0, 31, 1, 0, 0, 33, 1, 0, -0, 62, 0, 3, 0, 207, 0, 0, 0, 34, 1, 0, 0, 249, 0, 2, 0, 1, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 36, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 247, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 39, 1, 0, -0, 196, 0, 0, 0, 46, 0, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 39, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 40, 1, 0, 0, 206, 0, 0, 0, 254, 0, 2, 0, 40, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, -0, 4, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 57, 1, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 66, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, -0, 72, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 76, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 65, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 65, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 70, 1, 0, -0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 66, 1, 0, 0, 71, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 75, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 74, 1, 0, -0, 62, 0, 3, 0, 72, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 73, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 79, 1, 0, 0, 185, 0, 0, 0, 62, 1, 0, 0, 66, 1, 0, 0, 72, 1, 0, 0, 76, 1, 0, 0, 254, 0, 2, 0, 79, 1, 0, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 100, 1, 0, -0, 87, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 101, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, -0, 57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 1, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 107, 1, 0, -0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 121, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 122, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, -0, 123, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 123, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 112, 1, 0, 0, 62, 0, 3, 0, 124, 1, 0, -0, 125, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 126, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 128, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 126, 1, 0, 0, 128, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 129, 1, 0, -0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 130, 1, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 131, 1, 0, 0, 130, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 131, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 132, 1, 0, -0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 133, 1, 0, 0, 132, 1, 0, 0, 62, 0, 3, 0, 110, 1, 0, 0, 133, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 135, 1, 0, 0, 134, 1, 0, 0, 62, 0, 3, 0, 114, 1, 0, 0, 135, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 172, 31, 37, 223, 167, 75, 230, 241, 177, -145, 157, 123, 125, 33, 17, 255, 0, 120, 35, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 136, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 10, 0, 7, 0, 83, 80, 86, 95, 71, 79, 79, 71, 76, 69, 95, 117, 115, 101, 114, 95, 116, 121, 112, 101, -0, 0, 0, 0, 11, 0, 6, 0, 196, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 96, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, -101, 114, 0, 0, 87, 1, 0, 0, 89, 1, 0, 0, 85, 1, 0, 0, 95, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 120, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 109, 1, 0, 0, 112, 1, 0, 0, -113, 1, 0, 0, 108, 1, 0, 0, 110, 1, 0, 0, 114, 1, 0, 0, 119, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 96, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, -36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, -110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 7, 0, 21, 0, 178, 0, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 182, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, -108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182, 0, 0, 0, 7, 0, 19, 0, 41, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 43, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 0, 0, 7, 0, 21, 0, 80, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, -82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, -110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, -84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, -102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, -85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, -85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, -114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, -83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, -115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, -5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 184, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 7, 0, 188, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 189, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, -98, 0, 0, 0, 5, 0, 7, 0, 205, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 206, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 207, 0, 0, 0, -116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 213, 0, 0, 0, -105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 217, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 218, 0, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 220, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 223, 0, 0, 0, -109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 228, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 232, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 238, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, -5, 0, 5, 0, 242, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 247, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 3, 1, 0, 0, -102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 0, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 6, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 9, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, -5, 0, 6, 0, 12, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 16, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 25, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, -121, 0, 0, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 50, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, -100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 86, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, -108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 85, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 88, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, -5, 0, 6, 0, 87, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 90, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 80, -83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 91, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 1, 0, 0, 0, -67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 93, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, -2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, -5, 0, 15, 0, 96, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, -99, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 102, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 106, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 108, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 109, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 111, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, -5, 0, 6, 0, 110, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 112, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, -108, 111, 114, 0, 5, 0, 6, 0, 114, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 115, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, -111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 115, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 115, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 79, -85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 116, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, -116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, -6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 117, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 8, 0, 118, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 119, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 120, 1, 0, 0, -83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 127, 1, 0, 0, 105, 110, 116, 95, -51, 0, 0, 0, 0, 22, 8, 0, 38, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 50, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 0, 22, 9, 0, 63, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 99, 117, 98, 101, 58, 60, 102, 108, 111, -97, 116, 52, 62, 0, 0, 0, 0, 0, 22, 8, 0, 69, 0, 0, 0, 4, 22, 0, 0, 116, 101, 120, 116, 117, 114, 101, 51, 100, 58, 60, 102, 108, 111, 97, 116, 52, 62, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 87, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 87, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, -89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 108, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 109, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, -79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 112, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, -0, 22, 6, 0, 112, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 113, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, -114, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, +0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, +0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, +0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 33, 0, 6, 0, 188, 0, 0, 0, 5, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 32, 0, 4, 0, 206, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 205, 0, 0, 0, 4, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, +0, 189, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 216, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, +0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 233, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, +0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 75, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 89, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 91, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 92, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 93, 1, 0, 0, 4, 0, 0, +0, 30, 0, 5, 0, 94, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 95, 1, 0, 0, 6, 0, 0, 0, 94, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 103, 1, 0, +0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 107, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 112, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 117, 1, 0, +0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 118, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 119, 1, 0, 0, 6, 0, 0, 0, 118, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 128, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 96, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 109, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 110, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 112, 1, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 114, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 115, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 119, 1, 0, 0, 120, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, +0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, +0, 51, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, +0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, +0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, +0, 188, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 191, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 248, 0, 2, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 199, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 200, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 198, 0, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 192, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, +0, 202, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 196, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, +0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 209, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 210, 0, 0, +0, 248, 0, 2, 0, 211, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, +0, 225, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 232, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, +0, 243, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 248, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, +0, 17, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 26, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, +0, 217, 0, 0, 0, 197, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 215, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 210, 0, 0, 0, 217, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 222, 0, 0, 0, 210, 0, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 223, 0, 0, 0, 221, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 226, 0, 0, 0, 207, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, +0, 226, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 230, 0, 0, 0, 207, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, +0, 65, 0, 5, 0, 189, 0, 0, 0, 234, 0, 0, 0, 207, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 62, 0, 3, 0, 232, 0, 0, 0, 235, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 238, 0, 0, 0, 185, 0, 0, +0, 225, 0, 0, 0, 228, 0, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 220, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 242, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 239, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, +0, 247, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 251, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 0, 0, 0, 239, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 253, 0, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, +0, 253, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 248, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, +0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 210, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 5, 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 247, 0, 3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 5, 1, 0, 0, 1, 1, 0, +0, 2, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 210, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 9, 1, 0, 0, 10, 1, 0, +0, 129, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 8, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 7, 1, 0, +0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 16, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 13, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 20, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 13, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 21, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 23, 1, 0, +0, 20, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 7, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 25, 1, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 17, 1, 0, 0, 25, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, +0, 27, 1, 0, 0, 214, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 17, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 30, 1, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 27, 1, 0, +0, 28, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 26, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, +0, 26, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 35, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 34, 1, 0, +0, 62, 0, 3, 0, 208, 0, 0, 0, 35, 1, 0, 0, 249, 0, 2, 0, 2, 1, 0, 0, 248, 0, 2, 0, 2, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 36, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 37, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 248, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 40, 1, 0, +0, 197, 0, 0, 0, 46, 0, 0, 0, 36, 1, 0, 0, 37, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 40, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 41, 1, 0, 0, 207, 0, 0, 0, 254, 0, 2, 0, 41, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, +0, 4, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 58, 1, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 63, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 67, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, +0, 73, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 77, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 66, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 63, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, +0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 72, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 72, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 76, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 75, 1, 0, +0, 62, 0, 3, 0, 73, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 77, 1, 0, 0, 74, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 80, 1, 0, 0, 186, 0, 0, 0, 63, 1, 0, 0, 67, 1, 0, 0, 73, 1, 0, 0, 77, 1, 0, 0, 254, 0, 2, 0, 80, 1, 0, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 98, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 99, 1, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 101, 1, 0, +0, 88, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, +0, 57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 108, 1, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 121, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 123, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, +0, 124, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 123, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 125, 1, 0, +0, 126, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 127, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 129, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 129, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 130, 1, 0, +0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 131, 1, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 1, 0, 0, 131, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 132, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 133, 1, 0, +0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 134, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 111, 1, 0, 0, 134, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 136, 1, 0, 0, 135, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 136, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 9, 158, 143, 78, 52, 171, 165, 186, 6, +208, 204, 34, 59, 136, 189, 143, 0, 248, 34, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 197, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, +14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 97, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 88, 1, 0, 0, 90, 1, 0, 0, 86, 1, 0, 0, 96, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, +15, 0, 15, 0, 0, 0, 0, 0, 121, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 110, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 109, 1, 0, 0, 111, 1, 0, 0, 115, 1, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, +97, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, +0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, +109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, +116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, +7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 19, 0, 42, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, +100, 115, 108, 0, 7, 0, 26, 0, 44, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 7, 0, 21, 0, +81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, +97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, +85, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, +95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, +6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, +5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, +0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, +186, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, +97, 116, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 192, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 206, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, +97, 116, 52, 0, 5, 0, 6, 0, 207, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, +108, 111, 114, 0, 5, 0, 6, 0, 210, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 214, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, +5, 0, 7, 0, 218, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 219, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, +97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 224, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, +49, 0, 0, 0, 5, 0, 4, 0, 233, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 243, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 246, 0, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, +5, 0, 5, 0, 7, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 10, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 13, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, +17, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 26, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 2, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, +51, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, +5, 0, 4, 0, 75, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 89, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, +91, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, +6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 94, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 94, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 0, 6, 0, 6, 0, 94, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 94, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 95, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 96, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 97, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, +70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 100, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, +5, 0, 4, 0, 107, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 112, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 111, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, +113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 115, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, +5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, +0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 118, 1, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 118, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 118, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +118, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 118, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 119, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 120, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 121, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, +116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 128, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, +90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, +79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 111, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 111, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 6, 0, 113, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, +115, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 115, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, +4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, +34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, -25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, -2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, -0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, -74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, -32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, -33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 188, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 187, 0, 0, 0, 5, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, 188, 0, 0, 0, -32, 0, 4, 0, 205, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 204, 0, 0, 0, 4, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 215, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, -138, 0, 0, 0, 232, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, -5, 0, 0, 0, 73, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 86, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, -90, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 91, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 92, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 93, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 99, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 102, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -111, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 115, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 117, 1, 0, 0, 4, 0, 0, 0, -42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 118, 1, 0, 0, 6, 0, 0, 0, 117, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 127, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, -85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 85, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 87, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -90, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 108, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 109, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -111, 1, 0, 0, 110, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 90, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 86, 1, 0, 0, 114, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -118, 1, 0, 0, 119, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 135, 0, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, -140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 144, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 50, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, -54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, -176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 189, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, -190, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 191, 0, 0, 0, 248, 0, 2, 0, 192, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, -195, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 193, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, -196, 0, 0, 0, 40, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 201, 0, 0, 0, 196, 0, 0, 0, 37, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 12, 0, 7, 0, -5, 0, 0, 0, 202, 0, 0, 0, 196, 0, 0, 0, 40, 0, 0, 0, 195, 0, 0, 0, 201, 0, 0, 0, 254, 0, 2, 0, 202, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, -206, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 205, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 188, 0, 0, 0, 209, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 217, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 188, 0, 0, 0, 219, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 223, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 188, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 238, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 242, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 247, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 188, 0, 0, 0, 6, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 12, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 16, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 25, 1, 0, 0, 7, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 209, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 213, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 216, 0, 0, 0, 196, 0, 0, 0, 43, 0, 0, 0, 211, 0, 0, 0, 214, 0, 0, 0, 215, 0, 0, 0, -62, 0, 3, 0, 209, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 217, 0, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 209, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 222, 0, 0, 0, 220, 0, 0, 0, 221, 0, 0, 0, 62, 0, 3, 0, -219, 0, 0, 0, 222, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 225, 0, 0, 0, 206, 0, 0, 0, 213, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 226, 0, 0, 0, 225, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 226, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, -229, 0, 0, 0, 206, 0, 0, 0, 228, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 230, 0, 0, 0, 229, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 188, 0, 0, 0, 233, 0, 0, 0, 206, 0, 0, 0, 232, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 234, 0, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 234, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 237, 0, 0, 0, 184, 0, 0, 0, 224, 0, 0, 0, 227, 0, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 223, 0, 0, 0, 237, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 239, 0, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 219, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 239, 0, 0, 0, 240, 0, 0, 0, 62, 0, 3, 0, 238, 0, 0, 0, 241, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 243, 0, 0, 0, 238, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 242, 0, 0, 0, 246, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 242, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 238, 0, 0, 0, -12, 0, 8, 0, 5, 0, 0, 0, 252, 0, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 249, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, 0, 252, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 254, 0, 0, 0, 247, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 247, 0, 0, 0, 255, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 209, 0, 0, 0, 186, 0, 5, 0, -8, 0, 0, 0, 4, 1, 0, 0, 2, 1, 0, 0, 3, 1, 0, 0, 247, 0, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 4, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 1, 0, 0, -219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 209, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 10, 1, 0, 0, 8, 1, 0, 0, 9, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 7, 1, 0, 0, 10, 1, 0, 0, 62, 0, 3, 0, -6, 1, 0, 0, 11, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 13, 1, 0, 0, 223, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 6, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 15, 1, 0, 0, 13, 1, 0, 0, 14, 1, 0, 0, 62, 0, 3, 0, -12, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 217, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 12, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 17, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 20, 1, 0, 0, 12, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 20, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 22, 1, 0, 0, 19, 1, 0, 0, 21, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 6, 1, 0, 0, -129, 0, 5, 0, 5, 0, 0, 0, 24, 1, 0, 0, 22, 1, 0, 0, 23, 1, 0, 0, 62, 0, 3, 0, 16, 1, 0, 0, 24, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 26, 1, 0, 0, 213, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 228, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 16, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 29, 1, 0, 0, 196, 0, 0, 0, 49, 0, 0, 0, 26, 1, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 62, 0, 3, 0, 25, 1, 0, 0, 29, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 30, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 25, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 32, 1, 0, 0, -32, 1, 0, 0, 32, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 34, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 30, 1, 0, 0, 31, 1, 0, 0, 33, 1, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 34, 1, 0, 0, 249, 0, 2, 0, 1, 1, 0, 0, 248, 0, 2, 0, -1, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 3, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 36, 1, 0, 0, 207, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 247, 0, 0, 0, -80, 0, 7, 0, 4, 0, 0, 0, 38, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 39, 1, 0, 0, 196, 0, 0, 0, 46, 0, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, -206, 0, 0, 0, 39, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 40, 1, 0, 0, 206, 0, 0, 0, 254, 0, 2, 0, 40, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 50, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 57, 1, 0, 0, -59, 0, 4, 0, 205, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 66, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 205, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 188, 0, 0, 0, 76, 1, 0, 0, 7, 0, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 65, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 65, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 70, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 71, 1, 0, 0, 70, 1, 0, 0, -62, 0, 3, 0, 66, 1, 0, 0, 71, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 75, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 73, 1, 0, 0, 74, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 73, 1, 0, 0, -57, 0, 8, 0, 4, 0, 0, 0, 79, 1, 0, 0, 185, 0, 0, 0, 62, 1, 0, 0, 66, 1, 0, 0, 72, 1, 0, 0, 76, 1, 0, 0, 254, 0, 2, 0, 79, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 100, 1, 0, 0, 87, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 100, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -101, 1, 0, 0, 95, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 103, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 104, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -105, 1, 0, 0, 95, 1, 0, 0, 106, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 105, 1, 0, 0, 62, 0, 3, 0, 85, 1, 0, 0, 107, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 120, 1, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 248, 0, 2, 0, 121, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 122, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 123, 1, 0, 0, 109, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 123, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 124, 1, 0, 0, 119, 1, 0, 0, 102, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 112, 1, 0, 0, 62, 0, 3, 0, 124, 1, 0, 0, 125, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 126, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 128, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 126, 1, 0, 0, 128, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 129, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 130, 1, 0, 0, 119, 1, 0, 0, 106, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 131, 1, 0, 0, 130, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 131, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 132, 1, 0, 0, 119, 1, 0, 0, 99, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 133, 1, 0, 0, 132, 1, 0, 0, -62, 0, 3, 0, 110, 1, 0, 0, 133, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 119, 1, 0, 0, 127, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 135, 1, 0, 0, 134, 1, 0, 0, 62, 0, 3, 0, 114, 1, 0, 0, 135, 1, 0, 0, 253, 0, 1, 0, +25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, +2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, +0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, +75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, +32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, +33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 188, 0, 0, 0, 5, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, +32, 0, 4, 0, 206, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 205, 0, 0, 0, 4, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 189, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 216, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, +139, 0, 0, 0, 233, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, +5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 75, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 89, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, +91, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 92, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 93, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 94, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +95, 1, 0, 0, 6, 0, 0, 0, 94, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 103, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 107, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +112, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 117, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 118, 1, 0, 0, 4, 0, 0, 0, +43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 119, 1, 0, 0, 6, 0, 0, 0, 118, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 128, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, +86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +91, 1, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 96, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 109, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 110, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +112, 1, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 114, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 115, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +119, 1, 0, 0, 120, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 136, 0, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, +141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, +54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, +61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, +177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, +191, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 248, 0, 2, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, +196, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 200, 0, 0, 0, +197, 0, 0, 0, 40, 0, 0, 0, 198, 0, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 192, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 202, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 12, 0, 7, 0, +5, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 196, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, +207, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 209, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 210, 0, 0, 0, 248, 0, 2, 0, 211, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 189, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 225, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 189, 0, 0, 0, 232, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 243, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 248, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 189, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 17, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 26, 1, 0, 0, 7, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 217, 0, 0, 0, 197, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 215, 0, 0, 0, 216, 0, 0, 0, +62, 0, 3, 0, 210, 0, 0, 0, 217, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 222, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 223, 0, 0, 0, 221, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, +220, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 226, 0, 0, 0, 207, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, +230, 0, 0, 0, 207, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 234, 0, 0, 0, 207, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 62, 0, 3, 0, 232, 0, 0, 0, 235, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 238, 0, 0, 0, 185, 0, 0, 0, 225, 0, 0, 0, 228, 0, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 238, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 220, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 242, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 239, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 247, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 0, 0, 0, 239, 0, 0, 0, +12, 0, 8, 0, 5, 0, 0, 0, 253, 0, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, 0, 253, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 255, 0, 0, 0, 248, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 210, 0, 0, 0, 186, 0, 5, 0, +8, 0, 0, 0, 5, 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 247, 0, 3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 5, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, +220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 210, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 9, 1, 0, 0, 10, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 8, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, +7, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 7, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 62, 0, 3, 0, +13, 1, 0, 0, 16, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 13, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 20, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 21, 1, 0, 0, 13, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 21, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 23, 1, 0, 0, 20, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 7, 1, 0, 0, +129, 0, 5, 0, 5, 0, 0, 0, 25, 1, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 17, 1, 0, 0, 25, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 214, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 229, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 17, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 30, 1, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 26, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 31, 1, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 26, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, +33, 1, 0, 0, 33, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 35, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 35, 1, 0, 0, 249, 0, 2, 0, 2, 1, 0, 0, 248, 0, 2, 0, +2, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 36, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 248, 0, 0, 0, +80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 40, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 36, 1, 0, 0, 37, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, +207, 0, 0, 0, 40, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 41, 1, 0, 0, 207, 0, 0, 0, 254, 0, 2, 0, 41, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 58, 1, 0, 0, +59, 0, 4, 0, 206, 0, 0, 0, 63, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 67, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 73, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 77, 1, 0, 0, 7, 0, 0, 0, +57, 0, 4, 0, 4, 0, 0, 0, 66, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 63, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 72, 1, 0, 0, 71, 1, 0, 0, +62, 0, 3, 0, 67, 1, 0, 0, 72, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 76, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 77, 1, 0, 0, 74, 1, 0, 0, +57, 0, 8, 0, 4, 0, 0, 0, 80, 1, 0, 0, 186, 0, 0, 0, 63, 1, 0, 0, 67, 1, 0, 0, 73, 1, 0, 0, 77, 1, 0, 0, 254, 0, 2, 0, 80, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 98, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 99, 1, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 101, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +102, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +106, 1, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 108, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 121, 1, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 123, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 124, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 123, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 125, 1, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 125, 1, 0, 0, 126, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 127, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 129, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 129, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 130, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 131, 1, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 132, 1, 0, 0, 131, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 132, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 133, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 134, 1, 0, 0, 133, 1, 0, 0, +62, 0, 3, 0, 111, 1, 0, 0, 134, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 1, 0, 0, 135, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 136, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 792370d7bd..75471e110f 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -149,7 +149,9 @@ public override TaskOrResult Compile(ShaderMixinSo shaderMixinSource.AddMacro("class", "shader"); var shaderMixer = new ShaderMixer(GetFileShaderLoader()); - if (!shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(effectParameters.Platform is not GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints)) + if (!shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options( + ResourcesRegisterSeparate: effectParameters.Platform is not GraphicsPlatform.Vulkan, + StripGoogleUserType: effectParameters.Platform is GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints)) return new EffectBytecodeCompilerResult(null, log); // Optional SPIR-V validation (requires spirv-val from Vulkan SDK) @@ -326,7 +328,7 @@ public override TaskOrResult Compile(ShaderMixinSo else { var spirvBytecodeArray = spirvBytecode.ToArray(); - var spirvBytecodeId = ObjectId.FromBytes(spirvBytecode); + var spirvBytecodeId = ObjectId.FromBytes(spirvBytecodeArray); foreach (var entryPoint in entryPoints) { var entryPointName = new byte[Encoding.UTF8.GetByteCount(entryPoint.Name) + 1]; diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index e5f7008a7f..34a16c5df5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -24,7 +24,8 @@ public partial class ShaderMixer(IExternalShaderLoader shaderLoader) /// /// /// For D3D11/12: t, b and s registers are separate (and should be kept as low as possible so we number them from 0 in each category). - public record struct Options(bool ResourcesRegisterSeparate); + /// Strip SPV_GOOGLE_user_type extension and UserTypeGOOGLE decorations (needed for Vulkan, which rejects the extension unless VK_GOOGLE_user_type is supported). + public record struct Options(bool ResourcesRegisterSeparate, bool StripGoogleUserType = false); public IExternalShaderLoader ShaderLoader { get; } = shaderLoader; @@ -142,7 +143,7 @@ public bool MergeSDSL(ShaderSource shaderSource, Options options, ILogger log, o foreach (var inst in context) temp.Add(inst.Data); - CleanupUnnecessaryInstructions(globalContext, context, temp); + CleanupUnnecessaryInstructions(globalContext, context, temp, options); temp.Sort(); @@ -1135,7 +1136,7 @@ private static void RemoveInstructionWhere(SpirvBuffer buffer, Func(); @@ -1196,6 +1197,17 @@ or Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decor if ((i.Op == Op.OpMemberDecorate || i.Op == Op.OpMemberDecorateString) && (Decoration)i.Data.Memory.Span[3] is Decoration.LinkIdSDSL or Decoration.LinkSDSL or Decoration.ColorSDSL or Decoration.LogicalGroupSDSL or Decoration.ResourceGroupSDSL) return true; + // Strip SPV_GOOGLE_user_type for Vulkan (requires VK_GOOGLE_user_type which most drivers don't support) + if (options.StripGoogleUserType) + { + if (i.Op == Op.OpExtension && ((OpExtension)i).Name == "SPV_GOOGLE_user_type") + return true; + if (i.Op == Op.OpDecorateString && (Decoration)i.Data.Memory.Span[2] is Decoration.UserTypeGOOGLE) + return true; + if (i.Op == Op.OpMemberDecorateString && (Decoration)i.Data.Memory.Span[3] is Decoration.UserTypeGOOGLE) + return true; + } + // Remove SPIR-V about pointer types to other shaders (variable and types themselves are removed as well) if (i.Op == Op.OpTypePointer && (OpTypePointer)i is { } typePointer) { From de29cacce8d9921e0d2de8e5c3fcb209725f8bdc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 11:27:37 +0900 Subject: [PATCH 1025/1182] SDSL: Set Buffer ElementType in reflection to fix Vulkan texel buffer format mismatch --- .../SDSL/ShaderMixer.Reflection.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs index 2d9dc8b577..21e0e6b19d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Reflection.cs @@ -327,6 +327,7 @@ private unsafe void ProcessReflection(MixinGlobalContext globalContext, SpirvCon var resolved = effectResourceBinding with { Type = bufferType.WriteAllowed ? EffectParameterType.RWBuffer : EffectParameterType.Buffer, + ElementType = new EffectTypeDescription { Type = ScalarToEffectParameterType(bufferType.BaseType) }, }; globalContext.Reflection.ResourceBindings.Add(resolved); EmitResourceEntry(globalContext, resolved); @@ -417,4 +418,15 @@ private static void EmitResourceEntry(MixinGlobalContext globalContext, in Effec var group = globalContext.Reflection.GetOrCreateGroup(groupName); group.Entries.Add(new EffectResourceEntry(binding, samplerState)); } + + private static EffectParameterType ScalarToEffectParameterType(ScalarType scalarType) => scalarType.Type switch + { + Scalar.Float => EffectParameterType.Float, + Scalar.Half => EffectParameterType.Float, + Scalar.Double => EffectParameterType.Double, + Scalar.Int => EffectParameterType.Int, + Scalar.UInt => EffectParameterType.UInt, + Scalar.Boolean => EffectParameterType.Bool, + _ => EffectParameterType.Void, + }; } From bf79352344c08364f2e31ba7a6061a53b11522a4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 11:29:41 +0900 Subject: [PATCH 1026/1182] Vulkan: Fix viewport Y flip to match Vulkan 1.1 negative height convention --- sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index 9fe40d92e5..45a7778d5e 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -230,7 +230,7 @@ private unsafe void SetViewportImpl() // Since Vulkan 1.1, we can use negative viewport instead of doing gl_Position.y = -gl_Position.y in the shader // Note: we mutate viewportCopy _after_ vkCmdSetScissor has been called - viewportCopy.Y = viewportCopy.Height - viewportCopy.Y; + viewportCopy.Y = viewportCopy.Y + viewportCopy.Height; viewportCopy.Height = -viewportCopy.Height; if (viewportDirty) { From 5d5c9821e4edb4a60f43963660885b078e01e700 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 12:06:48 +0900 Subject: [PATCH 1027/1182] SDSL: Use MemberName instead of float4x4 in TransformationMatrix.sdsl --- .../Rendering/Transformation/TransformationMatrix.sdsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl index a9b3f9b4c3..0bd255d28c 100644 --- a/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Transformation/TransformationMatrix.sdsl @@ -6,7 +6,7 @@ /// /// TRANSFORMATION_MATRIX: generic float4x4 - The transformation matrix. /// -shader TransformationMatrix : TransformationBase, PositionStream4, PositionHStream4 +shader TransformationMatrix : TransformationBase, PositionStream4, PositionHStream4 { stage override void PostTransformPosition() { From 281b47f26f60a6bc462115d785077ef825a2ecf6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 27 Mar 2026 15:21:05 +0900 Subject: [PATCH 1028/1182] SDSL: Add SPIR-V debug info (OpLine/OpSource) for .sdsl source mapping and SPIRV-Cross #line directives --- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 22 ++++++-- .../SDSL/ShaderMixer.cs | 56 +++++++++++++++++++ .../ShaderLoaderBase.cs | 5 +- .../SpirvTranslator.cs | 12 +++- .../Parsing/SDSL/AST/Shader.cs | 14 +++++ .../Parsing/SDSL/AST/Statements.cs | 2 + .../Spirv/Building/Builder.Class.cs | 18 +++++- .../Spirv/Building/Builder.cs | 9 +++ .../Spirv/Building/CompilerUnit.cs | 1 + .../Spirv/Building/Context.cs | 3 + .../Stride.Shaders.Parsers/Spirv/Tools/Dis.cs | 24 +++++++- .../Information/InstructionInfo.Order.cs | 5 -- 12 files changed, 152 insertions(+), 19 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index e7f7d71018..90b9ccb2fb 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -15,9 +15,19 @@ namespace Stride.Shaders.Compilers.SDSL; +public record struct CompileOptions() +{ + /// Whether to register the compiled shader in the cache. + public bool RegisterInCache { get; init; } = true; + /// Whether to emit OpSourceHashSDSL for cache validation. + public bool EmitSourceHash { get; init; } = true; + /// Original source code before preprocessing, used for OpSource debug info. Falls back to preprocessed code if null. + public string? OriginalCode { get; init; } +} + public record struct SDSLC(IExternalShaderLoader ShaderLoader) { - public readonly bool Compile(string? filename, string code, ObjectId hash, ReadOnlySpan macros, ILogger log, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer, bool registerInCache = true) + public readonly bool Compile(string? filename, string code, ObjectId hash, ReadOnlySpan macros, ILogger log, [MaybeNullWhen(false)] out ShaderBuffers lastBuffer, CompileOptions options = default) { lastBuffer = default; @@ -43,13 +53,15 @@ public readonly bool Compile(string? filename, string code, ObjectId hash, ReadO CurrentMacros = [.. macros], }; - // Add OpSource (skip for MemberName recompilations that have no real file) + // Add debug source info (OpString/OpSource for debug mapping, OpSourceHashSDSL for cache validation) if (filename != null) { var filenameId = compiler.Context.Add(new OpString(compiler.Context.Bound++, filename)).ResultId; // TODO: Add SourceLanguage.SDSL - compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, null)); - compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); + compiler.Context.Add(new OpSource(Spirv.Specification.SourceLanguage.Unknown, 0, filenameId, options.OriginalCode ?? code)); + if (options.EmitSourceHash) + compiler.Context.Add(new OpSourceHashSDSL(filenameId, (int)hash.Hash1, (int)hash.Hash2, (int)hash.Hash3, (int)hash.Hash4)); + compiler.SourceFileId = filenameId; } // TODO: Do we want to record macros with a custom OpMacroSDSL? (mostly for debug purposes) @@ -100,7 +112,7 @@ public readonly bool Compile(string? filename, string code, ObjectId hash, ReadO // (e.g. names for imported IDs, or types from InsertWithoutDuplicates). ShaderClass.ProcessNameAndTypes(lastBuffer.Context); - if (registerInCache) + if (options.RegisterInCache) ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); } else if (declaration is ShaderEffect or EffectParameters) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 34a16c5df5..719083a5e2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -279,6 +279,9 @@ class MixinGlobalContext(SymbolTable table, ILogger log) public Dictionary ExternalShaders { get; } = new(); public Dictionary ExternalFunctions { get; } = new(); public Dictionary ExternalVariables { get; } = new(); + + /// Maps source filename to merged OpString ID, used to deduplicate OpString/OpSource during merge. + public Dictionary SourceFileStrings { get; } = new(); } class MixinNodeContext @@ -436,6 +439,7 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } var structTypes = new Dictionary(); + OpData? pendingOpLine = null; // Defer OpLine until the next included instruction // Copy instructions to main buffer foreach (var shader in new[] { shaderBuffers.Context.GetBuffer(), shaderBuffers.Buffer }) @@ -457,6 +461,34 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS if (i.Op == Op.OpSourceHashSDSL) include = false; + // Deduplicate OpString/OpSource: keep only one per unique filename + if (i.Op == Op.OpString) + { + var opString = (OpString)i; + var offsetId = opString.ResultId + offset; + if (globalContext.SourceFileStrings.TryGetValue(opString.Value, out var existingId)) + { + remapIds[offsetId] = existingId; + include = false; + } + else + { + globalContext.SourceFileStrings[opString.Value] = offsetId; + } + } + if (i.Op == Op.OpSource) + { + // OpSource references an OpString via file ID; skip if that OpString was deduplicated + var fileOperand = i.Data.Memory.Span; + // OpSource layout: [wordcount|op, sourcelanguage, version, file?, source?] + if (fileOperand.Length > 3) + { + var fileId = fileOperand[3] + offset; + if (remapIds.ContainsKey(fileId)) + include = false; + } + } + if (i.Op == Op.OpFunction && (OpFunction)i is { } function && shader[index + 1].Op == Op.OpFunctionMetadataSDSL && (OpFunctionMetadataSDSL)shader[index + 1] is { } functionInfo) { var isStage = (functionInfo.Flags & FunctionFlagsMask.Stage) != 0; @@ -505,6 +537,10 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS } } + // Discard pending OpLine — the instruction it was meant for was skipped + pendingOpLine?.Dispose(); + pendingOpLine = null; + // Go to next instruction continue; } @@ -575,14 +611,32 @@ bool ProcessStageMemberOrType(int memberId, FunctionType? functionType, bool isS addToContext = true; } } + // Instruction goes to context or is deduplicated — discard any pending OpLine + pendingOpLine?.Dispose(); + pendingOpLine = null; } // Does this belong in context or buffer? else if (isContext) { addToContext = true; + // Instruction goes to context — discard any pending OpLine (OpLine belongs in function bodies only) + pendingOpLine?.Dispose(); + pendingOpLine = null; + } + else if (i2.Op == Op.OpLine) + { + // Defer OpLine — only emit when the next non-OpLine instruction is actually included + pendingOpLine?.Dispose(); + pendingOpLine = i2; } else { + // Flush pending OpLine before emitting a real instruction + if (pendingOpLine is { } pending) + { + buffer.Add(pending); + pendingOpLine = null; + } buffer.Add(i2); } @@ -1316,4 +1370,6 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, o public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache) => inner.LoadExternalBuffer(name, filename, code, defines, out bytecode, out hash, out isFromCache); + + public bool SuppressSourceHash { get => inner.SuppressSourceHash; set => inner.SuppressSourceHash = value; } } diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index 386d2ef6e5..bcc36a09c3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -18,6 +18,7 @@ public abstract class ShaderLoaderBase(IShaderCache fileCache) : IExternalShader { public IShaderCache Cache => fileCache; public GenericShaderCache GenericCache { get; } = new(); + public bool SuppressSourceHash { get; set; } /// /// Ensures only one thread compiles a given shader at a time. Other threads wait for the result. @@ -175,7 +176,9 @@ protected virtual bool LoadFromCode(string? filename, string code, ObjectId hash // Use provided logger, or a temporary one that throws on errors var log = Log ?? new LoggerResult(); - if (!sdslc.Compile(filename, text, hash, macros, log, out buffer, registerInCache)) + var emitSourceHash = !SuppressSourceHash; + SuppressSourceHash = false; // Reset after use + if (!sdslc.Compile(filename, text, hash, macros, log, out buffer, new() { RegisterInCache = registerInCache, EmitSourceHash = emitSourceHash, OriginalCode = code })) { if (log is LoggerResult loggerResult && loggerResult.HasErrors) throw new InvalidOperationException(string.Join(Environment.NewLine, loggerResult.Messages.Where(m => m.Type >= LogMessageType.Error).Select(m => m.ToString()))); diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs index 9e7a938d7c..4b7b25320a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -73,12 +73,18 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) throw new Exception($"{cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler)} : could not create compiler"); - if (backend == Backend.Hlsl) { CompilerOptions* compilerOptions = null; cross.CompilerCreateCompilerOptions(compiler, ref compilerOptions); - cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50); - cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.HlslPreserveStructuredBuffers, 1); + // Don't emit #line directives — they reference original .sdsl files which confuse + // RenderDoc's shader viewer when displaying the cross-compiled HLSL/GLSL. + // OpLine in the SPIR-V is preserved for Vulkan/RenderDoc callstacks. + cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.EmitLineDirectives, 0); + if (backend == Backend.Hlsl) + { + cross.CompilerOptionsSetUint(compilerOptions, CompilerOption.HlslShaderModel, 50); + cross.CompilerOptionsSetBool(compilerOptions, CompilerOption.HlslPreserveStructuredBuffers, 1); + } cross.CompilerInstallCompilerOptions(compiler, compilerOptions); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index 95ab44d13e..b3f543c9f4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -591,14 +591,28 @@ public void Compile(SymbolTable table, CompilerUnit compiler) { if (member.TypeModifier == TypeModifier.Const) continue; + if (compiler.SourceFileId is int fid1) + builder.EmitLine(fid1, member.Info.Line, member.Info.Column); member.Compile(table, this, compiler); } foreach (var member in Elements.OfType()) + { + if (compiler.SourceFileId is int fid2) + builder.EmitLine(fid2, member.Info.Line, member.Info.Column); member.Compile(table, this, compiler); + } foreach (var member in Elements.OfType()) + { + if (compiler.SourceFileId is int fid3) + builder.EmitLine(fid3, member.Info.Line, member.Info.Column); member.Compile(table, this, compiler); + } foreach (var method in Elements.OfType()) + { + if (compiler.SourceFileId is int fid4) + builder.EmitLine(fid4, method.Info.Line, method.Info.Column); method.Compile(table, this, compiler, hasUnresolvableGenerics); + } if (hasUnresolvableGenerics) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs index edea62664a..57083247da 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Statements.cs @@ -233,6 +233,8 @@ public override void Compile(SymbolTable table, CompilerUnit compiler) var (builder, context) = compiler; foreach (var s in Statements) { + if (compiler.SourceFileId is int fileId && s is not EmptyStatement) + builder.EmitLine(fileId, s.Info.Line, s.Info.Column); s.Compile(table, compiler); if (SpirvBuilder.IsBlockTermination(builder.GetLastInstructionType())) break; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs index 16cb106ca6..ab2cf9dff9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.Class.cs @@ -559,6 +559,17 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri if (!hasUnresolvableShader) return; + // Extract original filename from context (for debug info in recompiled shader) + string? originalFilename = null; + foreach (var i in shaderBuffers.Context) + { + if (i.Op == Specification.Op.OpString) + { + originalFilename = ((OpString)i).Value; + break; + } + } + var instantiatedGenericsMacros = new List<(string Name, string Definition)>(); var genericParameterIndex = 0; foreach (var i in shaderBuffers.Context) @@ -593,9 +604,10 @@ private static void InstantiateMemberNames(ref ShaderBuffers shaderBuffers, stri shaderName = cacheKey; } - // filename: null — no OpSource emitted (this is a MemberName recompilation, not a real file) - // registerInCache: false — we register under the cache key ourselves - if (!shaderLoader.LoadExternalBuffer(shaderName, null, code, macros, out shaderBuffers, out var compiledHash, out _)) + // Use original filename for debug info (OpString/OpSource) but skip OpSourceHashSDSL + // since the hash would be of the macro-expanded code, not the original file + shaderLoader.SuppressSourceHash = true; + if (!shaderLoader.LoadExternalBuffer(shaderName, originalFilename, code, macros, out shaderBuffers, out var compiledHash, out _)) throw new InvalidOperationException(); // Register under the MemberName cache key (e.g. "Foo_PerMaterial") diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs index d95d24406b..b1688bedd7 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.cs @@ -14,6 +14,7 @@ namespace Stride.Shaders.Spirv.Building; public partial class SpirvBuilder() { private int position; + private (int FileId, int Line)? lastEmittedLine; SpirvBuffer buffer = new(); SpirvBuffer Buffer { get => buffer; init => buffer = value; } @@ -21,6 +22,14 @@ public partial class SpirvBuilder() public SpirvBlock? CurrentBlock { get; internal set; } public ref int Position => ref position; + public void EmitLine(int fileId, int line, int column) + { + if (lastEmittedLine == (fileId, line)) + return; + lastEmittedLine = (fileId, line); + Insert(new OpLine(fileId, line, column)); + } + public int AddFunctionVariable(int paramType, int paramVariable) { if (CurrentFunction is not SpirvFunction f) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs index e013f36e08..4ad829d117 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/CompilerUnit.cs @@ -15,6 +15,7 @@ public class CompilerUnit public SpirvBuilder Builder { get; } public List Arguments { get; } + public int? SourceFileId { get; set; } public List Macros { get; } = []; public CompilerUnit() diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs index 313a00c478..297c99e141 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.cs @@ -133,6 +133,9 @@ public interface IExternalShaderLoader public bool LoadExternalFileContent(string name, out string filename, out string code, out ObjectId hash); public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); public bool LoadExternalBuffer(string name, string? filename, string code, ReadOnlySpan defines, [MaybeNullWhen(false)] out ShaderBuffers bytecode, out ObjectId hash, out bool isFromCache); + + /// When set to true, suppresses OpSourceHashSDSL emission for the next compilation (used by MemberName recompilations). + bool SuppressSourceHash { get; set; } } // Should contain internal data not seen by the client but helpful for the generation like type symbols and other diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs index e52939784f..36a86f2993 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Dis.cs @@ -168,14 +168,34 @@ readonly DisWriter AppendEnums(OperandKind kind, SpvOperand operand) readonly DisWriter AppendLiteralString(LiteralValue value, bool dispose = true) { - Append('"', ConsoleColor.Green).Append(value.Value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); + AppendLiteralString(value.Value); if (dispose) value.Dispose(); return this; } readonly DisWriter AppendLiteralString(string value) { - Append('"', ConsoleColor.Green).Append(value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); + const int maxLength = 80; + var newlineIndex = value.IndexOf('\n'); + if (newlineIndex >= 0 || value.Length > maxLength) + { + var truncateAt = newlineIndex >= 0 ? Math.Min(newlineIndex, maxLength) : maxLength; + var preview = value[..truncateAt].TrimEnd('\r'); + var remaining = value.Length - truncateAt; + var lines = 0; + foreach (var c in value.AsSpan(truncateAt)) + if (c == '\n') lines++; + Append('"', ConsoleColor.Green).Append(preview, ConsoleColor.Green); + Append($"... ({remaining} more chars", ConsoleColor.DarkGray); + if (lines > 0) + Append($", {lines} more lines", ConsoleColor.DarkGray); + Append(")", ConsoleColor.DarkGray); + Append('"', ConsoleColor.Green).Append(' '); + } + else + { + Append('"', ConsoleColor.Green).Append(value, ConsoleColor.Green).Append('"', ConsoleColor.Green).Append(' '); + } return this; } diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs index 7d3b6481af..cd2e63a422 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Information/InstructionInfo.Order.cs @@ -82,11 +82,6 @@ void InitOrder() OrderGroup[(Op.OpUndef, null)] = group; - group++; - OrderGroup[(Op.OpLine, null)] = group; - OrderGroup[(Op.OpNoLine, null)] = group; - - group++; group++; foreach (var e in Enum.GetValues().Except(OrderGroup.Keys.Select(x => x.Item1))) OrderGroup[(e, null)] = group; From 190df617e922263e7575df88194a98bcc4f9fe22 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 17:55:34 +0900 Subject: [PATCH 1029/1182] SDSL: Fix SPIR-V LiteralString encoding to use UTF-8 instead of raw char values --- .../Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs | 6 +++--- .../shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs index 68d28bfa74..928f20e236 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Literals/LiteralValue.cs @@ -168,12 +168,12 @@ void UpdateMemory() } else if (Value is string s) { - for (int i = 0; i < s.Length; i++) + var utf8 = Encoding.UTF8.GetBytes(s); + for (int i = 0; i < utf8.Length; i++) { var pos = i / 4; var shift = 8 * (i % 4); - var value = i < s.Length ? s[i] : '\0'; - MemoryOwner.Span[pos] |= value << shift; + MemoryOwner.Span[pos] |= utf8[i] << shift; } } } diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs b/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs index 7d834fec82..3bd8826d28 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Core/WordsExtensions.cs @@ -21,9 +21,7 @@ public static int LengthOfString(this Span ints) } public static int GetWordCount(this string s) { - var length = s.Length + 1; // +1 for the null terminator - if (length % 4 == 0) - return length / 4; - return (length / 4) + 1; + var length = System.Text.Encoding.UTF8.GetByteCount(s) + 1; // +1 for the null terminator + return (length + 3) / 4; } } From 7bc567fe20168c16557606c5e7fef4ca997576f2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 17:55:57 +0900 Subject: [PATCH 1030/1182] SDSL: Easier to understand error in case of undeclared stream variable access --- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index 84819e2e32..ed9ba7b26a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -1063,7 +1063,9 @@ void CoalesceSwizzles(int i, SymbolType currentValueType, ref Expression accesso { streamVar.AllowStreamVariables = true; streamVar.ProcessSymbol(table); - accessor.Type = (PointerType)streamVar.Type! with { StorageClass = p.StorageClass }; + if (streamVar.Type is not PointerType) + throw new InvalidOperationException($"Use of undeclared stream variable '{streamVar.Name}'"); + accessor.Type = (PointerType)streamVar.Type with { StorageClass = p.StorageClass }; break; } From 2b1bc17e8cacd64318148ac620396171bd9f6b91 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 30 Mar 2026 22:33:11 +0900 Subject: [PATCH 1031/1182] SDSL: Replace Console.WriteLine with Logger in SpirvTranslator, remove dead code in ShaderMixer --- .../shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 2 -- .../shaders/Stride.Shaders.Compilers/SpirvTranslator.cs | 8 ++++++-- .../Interfaces/Transformation/MethodDuplicator.cs | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 719083a5e2..20697914df 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -725,8 +725,6 @@ private static void BuildTypesAndMethodGroups(MixinGlobalContext globalContext, var i = temp[index]; if (i.Data.Op == Op.OpShaderSDSL && (OpShaderSDSL)i is { } shaderInstruction) { - //currentShader = mixinNode.ShadersByName[shaderInstruction.ShaderName]; - // TODO: better way to find ShaderInfo currentShader = mixinNode.Shaders.First(x => index >= x.StartInstruction && index < x.EndInstruction); } else if (i.Data.Op == Op.OpFunction && (OpFunction)i is { } function) diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs index 4b7b25320a..496f1391dd 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -1,6 +1,7 @@ using Silk.NET.Core.Native; using Silk.NET.SPIRV; using Silk.NET.SPIRV.Cross; +using Stride.Core.Diagnostics; using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Text; @@ -12,6 +13,7 @@ namespace Stride.Shaders.Compilers; public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { static readonly Cross cross = Cross.GetApi(); + static readonly Logger Log = GlobalLogger.GetLogger("SpirvTranslator"); public List<(string RealName, string TranslatedName, ExecutionModel ExecutionModel)> GetEntryPoints(Backend backend = Backend.Hlsl) { @@ -27,7 +29,8 @@ public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => { var error = Marshal.PtrToStringAnsi((IntPtr)errorData); - Console.WriteLine(error); + if (error != null) + Log.Error(error); }), null); if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) @@ -67,7 +70,8 @@ public readonly string Translate(Backend backend = Backend.Hlsl, (string RealNam cross.ContextSetErrorCallback(context, new((void* userData, byte* errorData) => { var error = Marshal.PtrToStringAnsi((IntPtr)errorData); - Console.WriteLine(error); + if (error != null) + Log.Error(error); }), null); if (cross.ContextCreateCompiler(context, backend, ir, CaptureMode.Copy, &compiler) != Result.Success) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs index 6f595783b8..6ee8cc9403 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/Transformation/MethodDuplicator.cs @@ -71,7 +71,6 @@ public static void DuplicateMethodIfNecessary( liveAnalysis.ExtraReferencedMethods.Add(methodInfo.ThisStageMethodId.Value); - // TODO: adjust mixin instructions ranges buffer.InsertRange(methodEnd, CollectionsMarshal.AsSpan(copiedInstructions)); codeInserted?.Invoke(methodEnd, copiedInstructions.Count); } From 05ed999614fc0af2285946b704f96ac5d567114d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 31 Mar 2026 10:20:27 +0900 Subject: [PATCH 1032/1182] SDSL: Removed obsolete Stride.Shaders.Tests.Windows project --- build/Stride.Tests.Simple.slnf | 1 - build/Stride.sln | 13 - .../BenchmarkShaderSystems.cs | 150 ----- .../GameAssets/Compiler/SimpleEffect.sdfx | 9 - .../GameAssets/Compiler/SimpleShader.sdsl | 20 - .../GameAssets/Compiler/TestStream.sdsl | 26 - .../GameAssets/Compiler/ToGlslEffect.sdfx | 9 - .../GameAssets/Compiler/ToGlslShader.sdsl | 20 - .../GameAssets/GameSettings.sdgamesettings | 38 -- .../GameAssets/Mixins/A.sdsl | 18 - .../GameAssets/Mixins/B.sdsl | 5 - .../GameAssets/Mixins/C.sdsl | 5 - .../GameAssets/Mixins/C1.sdsl | 5 - .../GameAssets/Mixins/TestComputeColor.sdsl | 9 - .../GameAssets/Mixins/TestComputeColor2.sdsl | 12 - .../Mixins/TestComputeColorRedirect.sdsl | 11 - .../Mixins/test_mixin_complex_params.sdfx | 47 -- .../Mixins/test_mixin_compose_keys.sdfx | 37 -- .../GameAssets/Mixins/test_mixin_simple.sdfx | 11 - .../Mixins/test_mixin_simple_child.sdfx | 18 - .../test_mixin_simple_child_params.sdfx | 33 - .../Mixins/test_mixin_simple_clone.sdfx | 19 - .../Mixins/test_mixin_simple_compose.sdfx | 12 - .../Mixins/test_mixin_simple_params.sdfx | 38 -- .../GameAssets/Shaders/BaseTestChild.sdsl | 15 - .../GameAssets/Shaders/BaseTestInter.sdsl | 10 - .../GameAssets/Shaders/BaseTestParent.sdsl | 8 - .../GameAssets/Shaders/BasicMixin.sdsl | 16 - .../GameAssets/Shaders/BasicMixin2.sdsl | 8 - .../GameAssets/Shaders/Child.sdsl | 15 - .../GameAssets/Shaders/ChildError.sdsl | 9 - .../GameAssets/Shaders/CloneTestBase.sdsl | 6 - .../GameAssets/Shaders/CloneTestExtern.sdsl | 9 - .../GameAssets/Shaders/CloneTestRoot.sdsl | 12 - .../Shaders/ConstantBufferTest.sdsl | 22 - .../GameAssets/Shaders/CyclicTest.sdsl | 6 - .../GameAssets/Shaders/DeepExtern.sdsl | 6 - .../GameAssets/Shaders/DeepExternTest.sdsl | 12 - .../GameAssets/Shaders/ExternClone.sdsl | 8 - .../GameAssets/Shaders/ExternCloneTest.sdsl | 15 - .../GameAssets/Shaders/ExternMixin.sdsl | 11 - .../GameAssets/Shaders/ExternTest.sdsl | 14 - .../GameAssets/Shaders/ForEachTest.sdsl | 16 - .../GameAssets/Shaders/GenericCall.sdsl | 5 - .../GameAssets/Shaders/GenericClass.sdsl | 25 - .../GameAssets/Shaders/GenericClass2.sdsl | 23 - .../GameAssets/Shaders/GenericExtern.sdsl | 6 - .../GameAssets/Shaders/GenericTexcoord.sdsl | 6 - .../Shaders/GeometryShaderTest.sdsl | 8 - .../GameAssets/Shaders/InterfaceTest.sdsl | 9 - .../Shaders/InternalReferenceMixin.sdsl | 11 - .../GameAssets/Shaders/MacroTest.sdsl | 9 - .../GameAssets/Shaders/MacroTestBase.sdsl | 9 - .../GameAssets/Shaders/MacroTestChild.sdsl | 6 - .../Shaders/MixinFunctionParamaterTest.sdsl | 8 - .../GameAssets/Shaders/MixinNameClash.sdsl | 9 - .../GameAssets/Shaders/MixinNoNameClash.sdsl | 9 - .../Shaders/NonStageStreamTest.sdsl | 12 - .../GameAssets/Shaders/Parent.sdsl | 14 - .../GameAssets/Shaders/SemanticTest.sdsl | 15 - .../GameAssets/Shaders/Simple.sdsl | 6 - .../GameAssets/Shaders/StageBase.sdsl | 7 - .../GameAssets/Shaders/StageCallExtern.sdsl | 10 - .../GameAssets/Shaders/StageDecl.sdsl | 6 - .../Shaders/StageValueReference.sdsl | 12 - .../GameAssets/Shaders/StageValueTest.sdsl | 11 - .../GameAssets/Shaders/StaticCallMixin.sdsl | 10 - .../GameAssets/Shaders/StaticMixin.sdsl | 10 - .../Shaders/StaticStageCallTest.sdsl | 10 - .../GameAssets/Shaders/StreamChild.sdsl | 9 - .../GameAssets/Shaders/StreamError.sdsl | 16 - .../GameAssets/Shaders/StreamParent0.sdsl | 6 - .../GameAssets/Shaders/StreamParent1.sdsl | 6 - .../GameAssets/Shaders/StreamParent2.sdsl | 7 - .../Shaders/StreamSolverExternTest.sdsl | 10 - .../GameAssets/Shaders/StreamTest.sdsl | 70 -- .../Shaders/StructuredBufferTest.sdsl | 14 - .../GameAssets/Shaders/TessellationTest.sdsl | 22 - .../GameAssets/Shaders/TestComputeShader.sdsl | 56 -- .../GameAssets/Shaders/TestErrors.sdsl | 50 -- .../GameAssets/Shaders/TestExternArray.sdsl | 22 - .../Shaders/TestGenericComplex.sdsl | 9 - .../GameAssets/Shaders/TestGenericMacro.sdsl | 9 - .../GameAssets/Shaders/TestGenerics.sdsl | 11 - .../GameAssets/Shaders/TestMacros.sdsl | 15 - .../GameAssets/Shaders/TestMacrosArray.sdsl | 13 - .../Shaders/TestMultipleStatic.sdsl | 12 - .../GameAssets/Shaders/TestPixelStream.sdsl | 11 - .../Shaders/TestScreenPosition.sdsl | 6 - .../GameAssets/Shaders/TestStreams.sdsl | 10 - .../Shaders/TestStructInheritance.sdsl | 11 - .../TestStructInheritanceExtensions.cs | 9 - .../GameAssets/Shaders/TestStructure.sdsl | 14 - .../GameAssets/Shaders/TestVertexStream.sdsl | 12 - .../Stride.Shaders.Tests.Windows.csproj | 33 - .../Stride.Shaders.Tests.Windows.sdpkg | 9 - .../Stride.Shaders.Tests/TestCodeGen.cs | 71 -- .../Stride.Shaders.Tests/TestGenericClass.cs | 118 ---- .../engine/Stride.Shaders.Tests/TestHelper.cs | 17 - .../Stride.Shaders.Tests/TestMixinCompiler.cs | 248 ------- .../TestMixinGenerator.Extensions.cs | 73 --- .../TestMixinGenerator.Helpers.cs | 35 - .../TestMixinGenerator.cs | 156 ----- .../TestParallelShaderMixer.cs | 95 --- .../Stride.Shaders.Tests/TestRealMix.cs | 251 -------- .../Stride.Shaders.Tests/TestShaderLoading.cs | 65 -- .../TestShaderLoadingString.cs | 81 --- .../Stride.Shaders.Tests/TestShaderMixer.cs | 414 ------------ .../Stride.Shaders.Tests/TestShaderMixer2.cs | 107 --- .../Stride.Shaders.Tests/TestShaderParsing.cs | 609 ------------------ .../TestShaderReflection.cs | 329 ---------- .../engine/Stride.Shaders.Tests/app.config | 3 - 112 files changed, 4194 deletions(-) delete mode 100644 sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/GameSettings.sdgamesettings delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritanceExtensions.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl delete mode 100644 sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj delete mode 100644 sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.sdpkg delete mode 100644 sources/engine/Stride.Shaders.Tests/TestCodeGen.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestGenericClass.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestHelper.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Extensions.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Helpers.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestMixinGenerator.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestParallelShaderMixer.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestRealMix.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderLoading.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderLoadingString.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderMixer.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderMixer2.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderParsing.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/TestShaderReflection.cs delete mode 100644 sources/engine/Stride.Shaders.Tests/app.config diff --git a/build/Stride.Tests.Simple.slnf b/build/Stride.Tests.Simple.slnf index f4e1553025..8b21359c83 100644 --- a/build/Stride.Tests.Simple.slnf +++ b/build/Stride.Tests.Simple.slnf @@ -12,7 +12,6 @@ "..\\sources\\core\\Stride.Core.Yaml.Tests\\Stride.Core.Yaml.Tests.csproj", "..\\sources\\editor\\Stride.Core.Assets.Editor.Tests\\Stride.Core.Assets.Editor.Tests.csproj", "..\\sources\\editor\\Stride.GameStudio.Tests\\Stride.GameStudio.Tests.csproj", - "..\\sources\\engine\\Stride.Shaders.Tests\\Stride.Shaders.Tests.Windows.csproj", "..\\sources\\presentation\\Stride.Core.Presentation.Quantum.Tests\\Stride.Core.Presentation.Quantum.Tests.csproj", "..\\sources\\presentation\\Stride.Core.Presentation.Tests\\Stride.Core.Presentation.Tests.csproj", "..\\sources\\presentation\\Stride.Core.Quantum.Tests\\Stride.Core.Quantum.Tests.csproj" diff --git a/build/Stride.sln b/build/Stride.sln index 9376018efa..2daa5690dd 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -162,8 +162,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compilers", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Tests.Windows", "..\sources\engine\Stride.Shaders.Tests\Stride.Shaders.Tests.Windows.csproj", "{1BE90177-FE4D-4519-839E-7EB7D78AC973}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Assets", "..\sources\assets\Stride.Core.Assets\Stride.Core.Assets.csproj", "{1E54A9A2-4439-4444-AE57-6D2ED3C0DC47}" @@ -607,16 +605,6 @@ Global {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|Mixed Platforms.Build.0 = Release|Any CPU {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|Win32.ActiveCfg = Release|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Debug|Win32.ActiveCfg = Debug|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Release|Any CPU.Build.0 = Release|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {1BE90177-FE4D-4519-839E-7EB7D78AC973}.Release|Win32.ActiveCfg = Release|Any CPU {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|Any CPU.Build.0 = Debug|Any CPU {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -1611,7 +1599,6 @@ Global {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} - {1BE90177-FE4D-4519-839E-7EB7D78AC973} = {A7ED9F01-7D78-4381-90A6-D50E51C17250} {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E} = {4C142567-C42B-40F5-B092-798882190209} {1E54A9A2-4439-4444-AE57-6D2ED3C0DC47} = {A2A4342E-024B-4063-B10C-1DA96CA3046D} {3E7B5D96-CF71-41EE-8CF0-70D090873390} = {9D5D9861-AE68-429C-8B21-2263F9DA07A1} diff --git a/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs b/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs deleted file mode 100644 index 7192dc107d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/BenchmarkShaderSystems.cs +++ /dev/null @@ -1,150 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Text; -using Stride.Core.IO; -using Stride.Core.Storage; -using Stride.Core.Serialization.Contents; -using Stride.Shaders.Compiler; -using Stride.Shaders.Compilers.SDSL; -using Xunit; -using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Engines; -using BenchmarkDotNet.Jobs; -using BenchmarkDotNet.Running; -using BenchmarkDotNet.Validators; - -namespace Stride.Shaders.Tests -{ - // Temporary test for old vs new shader system - public class BenchmarkShaderSystems - { - EffectCompiler compiler; - ShaderMixinSource shaderMixinSource; - - public BenchmarkShaderSystems() - { - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var database = new DatabaseFileProvider(objDatabase); - compiler = new EffectCompiler(database); - compiler.SourceDirectories.Add(EffectCompilerBase.DefaultSourceShaderFolder); - - shaderMixinSource = new ShaderMixinSource - { - Mixins = - { - new ShaderClassSource("ShaderBase"), - new ShaderClassSource("ShadingBase"), - new ShaderClassSource("TransformationBase"), - new ShaderClassSource("NormalStream"), - new ShaderClassSource("TransformationWAndVP"), - new ShaderClassSource("NormalFromMesh"), - new ShaderClassSource("MaterialSurfacePixelStageCompositor"), - }, - Compositions = - { - ["directLightGroups"] = new ShaderArraySource - { - new ShaderMixinSource - { - Mixins = - { - new ShaderClassSource("LightDirectionalGroup", "1"), - new ShaderClassSource("ShadowMapReceiverDirectional", "1", "1", "true", "true", "false", "false"), - new ShaderClassSource("ShadowMapFilterDefault", "PerView.Lighting"), - }, - }, - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("LightClusteredPointGroup") }, - }, - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("LightClusteredSpotGroup") }, - }, - }, - ["environmentLights"] = new ShaderArraySource - { - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("LightSimpleAmbient") }, - }, - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("EnvironmentLight") }, - }, - }, - ["materialPixelStage"] = new ShaderMixinSource - { - Mixins = { new ShaderClassSource("MaterialSurfaceArray") }, - Compositions = - { - ["layers"] = new ShaderArraySource - { - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("MaterialSurfaceDiffuse") }, - Compositions = { ["diffuseMap"] = new ShaderClassSource("ComputeColorConstantColorLink", "Material.DiffuseValue") }, - }, - new ShaderMixinSource - { - Mixins = { new ShaderClassSource("MaterialSurfaceLightingAndShading") }, - Compositions = - { - ["surfaces"] = new ShaderArraySource - { - new ShaderClassSource("MaterialSurfaceShadingDiffuseLambert", "false"), - }, - }, - }, - }, - }, - }, - ["streamInitializerPixelStage"] = new ShaderMixinSource - { - Mixins = - { - new ShaderClassSource("MaterialStream"), - new ShaderClassSource("MaterialPixelShadingStream"), - }, - }, - }, - }; - } - - [Benchmark] - public void NewSystem() - { - // New system - var shaderMixer = new ShaderMixer(new EffectCompiler.ShaderLoader(compiler.FileProvider)); - shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options(false), out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints); - } - } - - public class BenchmarkProgram - { - public static void Main(string[] args) - { - /*var test = new TestShaderSystems(); - for (int i = 0; i < 5; ++i) - test.OldSystem(); - for (int i = 0; i < 5; ++i) - test.NewSystem(); - - return;*/ - // TODO: somehow iteration count is not respected, need to review that - var config = new DebugInProcessConfig() - // Enable for debug mode - //.WithOptions(ConfigOptions.DisableOptimizationsValidator) - .AddJob(Job.Default - .WithWarmupCount(0) - .WithIterationCount(1) - .WithInvocationCount(1) - .WithUnrollFactor(1) - .AsDefault()); - - var summary = BenchmarkRunner.Run(typeof(BenchmarkProgram).Assembly, config); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx deleted file mode 100644 index 2d9b914c4f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleEffect.sdfx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect SimpleEffect - { - mixin SimpleShader; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl deleted file mode 100644 index 221a8aff7e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/SimpleShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SimpleShader : ShaderBase, Texturing -{ - stage stream float2 Position : POSITION; - - float4 BaseColor; - - //stage float4 TestColor; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor + Texture0.Sample(PointRepeatSampler, streams.Position); // + TestColor; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl deleted file mode 100644 index 295f9f3e98..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/TestStream.sdsl +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStream : ShaderBase -{ - stage stream float2 Position : POSITION; - stage stream float blend; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - var backup = streams; - Toto(backup); - - streams.ColorTarget = float4(streams.Position, 0, 1); - } - - - void Toto(Streams backup) - { - streams.Position = lerp(streams.Position, backup.Position, backup.blend); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx deleted file mode 100644 index 104a0887c4..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslEffect.sdfx +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test -{ - effect ToGlslEffect - { - mixin ToGlslShader; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl deleted file mode 100644 index 7f63bf41fd..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Compiler/ToGlslShader.sdsl +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ToGlslShader : ShaderBase, Texturing -{ - stage stream float2 Position : POSITION; - - float4 BaseColor; - - float TestArray[4]; - - stage override void VSMain() - { - streams.ShadingPosition = float4(streams.Position, 0.0f, 1.0f); - } - - stage override void PSMain() - { - streams.ColorTarget = float4(1, 0, 0, 1) + BaseColor*TestArray[0]*TestArray[1] + Texture0.Sample(PointRepeatSampler, streams.Position); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/GameSettings.sdgamesettings b/sources/engine/Stride.Shaders.Tests/GameAssets/GameSettings.sdgamesettings deleted file mode 100644 index cf6d83da6d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/GameSettings.sdgamesettings +++ /dev/null @@ -1,38 +0,0 @@ -!GameSettingsAsset -Id: ff5448d9-1102-418e-980e-a7f15a491e0c -SerializedVersion: {Stride: 2.1.0.3} -Tags: [] -DefaultScene: null -GraphicsCompositor: null -SplashScreenTexture: null -SplashScreenColor: {R: 0, G: 0, B: 0, A: 255} -Defaults: - - !Stride.Graphics.RenderingSettings,Stride.Graphics - DefaultBackBufferWidth: 800 - DefaultBackBufferHeight: 480 - AdaptBackBufferToScreen: false - DefaultGraphicsProfile: Level_9_1 - ColorSpace: Linear - DisplayOrientation: Default - - !Stride.Assets.EditorSettings,Stride.Assets - RenderingMode: HDR - - !Stride.Assets.Textures.TextureSettings,Stride.Assets - TextureQuality: Fast - - !Stride.Audio.AudioEngineSettings,Stride.Audio - HrtfSupport: false - - !Stride.Streaming.StreamingSettings,Stride.Engine - Enabled: false - ManagerUpdatesInterval: 0:00:00:00.0330000 - ResourceLiveTimeout: 0:00:00:08.0000000 -Overrides: [] -PlatformFilters: - - PowerVR SGX 54[0-9] - - Adreno \(TM\) 2[0-9][0-9] - - Adreno (TM) 320 - - Adreno (TM) 330 - - Adreno \(TM\) 4[0-9][0-9] - - NVIDIA Tegra - - Intel(R) HD Graphics - - ^Mali\-4 - - ^Mali\-T6 - - ^Mali\-T7 diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl deleted file mode 100644 index 5a64860ce0..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/A.sdsl +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader A : ShaderBase -{ - compose ComputeColor SubCompute1; - compose ComputeColor SubCompute2; - compose ComputeColor SubComputes[]; - - override stage void PSMain() - { - streams.ColorTarget = SubCompute1.Compute(float4(1,1,1,1)) + SubCompute2.Compute(float4(1,1,1,1)); - - foreach(var subCompute in SubComputes) - { - streams.ColorTarget = subCompute.Compute(streams.ColorTarget); - } - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl deleted file mode 100644 index 86cd4a796d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/B.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader B -{ -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl deleted file mode 100644 index fb03f434ea..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader C -{ -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl deleted file mode 100644 index 269864958f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/C1.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader C1 -{ -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl deleted file mode 100644 index 79a70a2305..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColor -{ - float4 Compute(float4 color) - { - return color; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl deleted file mode 100644 index 4fe2cdd536..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColor2.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColor2 : ComputeColor -{ - [Color] - float4 Color; - - override float4 Compute(float4 color) - { - return Color + color * 1; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl deleted file mode 100644 index 6d3ff13808..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/TestComputeColorRedirect.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ComputeColorRedirect : ComputeColor -{ - compose TestComputeColor ColorRedirect; - - override float4 Compute(float4 color) - { - return ColorRedirect.Compute(color) + color * 1; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx deleted file mode 100644 index fe2209c02e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_complex_params.sdfx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test1 -{ - params SubParameters - { - bool param1; - int param2 = 1; - string param3 = "ok"; - }; - - params TestParameters - { - SubParameters subParam1; - SubParameters subParameters[]; - }; - - effect DefaultComplexParams - { - using params TestParameters; - using params SubParameters; - - mixin A; - mixin B; - mixin C; - - int x = 1; - foreach (params TestParameters.subParameters) - { - if (SubParameters.param1) - { - mixin "C" + x; - } - - x++; - } - - using params TestParameters.subParam1 - { - - if (SubParameters.param2 == 1) - { - mixin D; - } - } - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx deleted file mode 100644 index 3a39780d00..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_compose_keys.sdfx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace TestABC -{ - params TestParameters - { - bool UseComputeColor2; - bool UseComputeColorRedirect; - }; - - partial effect ABCSubEffect - { - using params TestParameters; - - if (TestParameters.UseComputeColor2) - { - mixin TestComputeColor2; - } - else if (TestParameters.UseComputeColorRedirect) - { - mixin TestComputeColorRedirect; - mixin compose ColorRedirect = TestComputeColor2; - } - else - { - mixin TestComputeColor; - } - }; - - effect test_mixin_compose_keys - { - mixin A; - mixin compose SubCompute1 = ABCSubEffect; - mixin compose SubCompute2 = ABCSubEffect; - mixin compose SubComputes += ABCSubEffect; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx deleted file mode 100644 index 30fb4c9eb3..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple.sdfx +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test2 -{ - effect DefaultSimple - { - mixin A; - mixin B; - mixin C; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx deleted file mode 100644 index 28d5b83253..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child.sdfx +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test3 -{ - partial effect ChildMixin - { - mixin C1; - mixin C2; - }; - - effect DefaultSimpleChild - { - mixin A; - mixin B; - mixin C; - mixin ChildMixin; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx deleted file mode 100644 index a52d477a80..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_child_params.sdfx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test4 -{ - params TestParameters - { - int TestCount; - bool UseComputeColorEffect; - }; - - partial effect ChildParamsMixin - { - using params TestParameters; - - TestParameters.TestCount = 1; - if (TestParameters.TestCount == 1) - mixin C1; - }; - - effect DefaultSimpleChildParams - { - using params TestParameters; - - mixin A; - if (TestParameters.TestCount == 0) - mixin B; - - mixin child ChildParamsMixin; - - if (TestParameters.TestCount == 0) - mixin C; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx deleted file mode 100644 index 69b66d7057..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_clone.sdfx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test5 -{ - effect ChildClone - { - mixin C1; - mixin C2; - }; - - effect DefaultSimpleClone - { - mixin A; - mixin B; - mixin C; - // Rename the sub child as Test - mixin child Test = ChildClone; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx deleted file mode 100644 index c740522705..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_compose.sdfx +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test6 -{ - effect DefaultSimpleCompose - { - mixin A; - mixin B; - mixin C; - mixin compose x = X; - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx b/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx deleted file mode 100644 index 140291221c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Mixins/test_mixin_simple_params.sdfx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Test7 -{ - params TestParameters - { - bool param1; - int param2 = 1; - string param3 = "ok"; - }; - - effect DefaultSimpleParams - { - using params TestParameters; - - mixin A; - mixin B; - - // Include a simple test of a boolean - if (TestParameters.param1) - { - // Conditional mixin - mixin C; - - // Simple test of macro - mixin macro TestParameters.param2; - - // Simple test of composition - mixin compose x = X; - } - else - { - mixin D; - mixin macro Test = TestParameters.param3; - mixin compose y = Y; - } - }; -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl deleted file mode 100644 index 6989375ea0..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestChild.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestChild : BaseTestInter -{ - override void test1() - { - base.test1(); - } - - override void test2() - { - this.test1(); - base.test2(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl deleted file mode 100644 index 3ca4eef00c..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestInter.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestInter : BaseTestParent -{ - override void test1() - { - this.test2(); - base.test1(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl deleted file mode 100644 index b5bf42275b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BaseTestParent.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BaseTestParent -{ - void test1(){} - - void test2(){} -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl deleted file mode 100644 index 06fd04207b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BasicMixin -{ - float myFloat = 0.2f; - stage float3 myPosition : register(b); - stream float2 screenPosition : register(vs, b); - - abstract void myFunc(); - float myFunc2() - { - var a = myFloat; - return a; - } - abstract stage void myFunc3(); -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl deleted file mode 100644 index 6ebef4b2f8..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/BasicMixin2.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader BasicMixin2 -{ - float myFloat = 0.2f; - - void myFunc4() {} -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl deleted file mode 100644 index f3527309d1..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Child.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Child : Parent -{ - SamplerState childSampler; - Texture2D childTexture; - - override float AddBaseValue(float inValue) - { - childTexture.Sample(childSampler, float2(0.0f, 0.0f)); - parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); - Parent.parentTexture.Sample(childSampler, float2(0.0f, 0.0f)); - return inValue + baseValue + base.AddBaseValue(inValue); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl deleted file mode 100644 index c7dc21c5e3..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ChildError.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ChildError : Parent -{ - float AddBaseValue(float inValue) - { - return inValue + base.AddBaseValue(inValue); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl deleted file mode 100644 index 63775da982..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestBase.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestBase -{ - stage void testFunc() {} -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl deleted file mode 100644 index ec06d0ee40..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestExtern.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestExtern : CloneTestBase -{ - override stage clone void testFunc() - { - base.testFunc(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl deleted file mode 100644 index ab31eb2406..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CloneTestRoot.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CloneTestRoot : CloneTestBase -{ - compose CloneTestExtern extern0; - compose CloneTestExtern extern1; - - override stage void testFunc() - { - base.testFunc(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl deleted file mode 100644 index fd0251196e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ConstantBufferTest.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ConstantBufferTest -{ - cbuffer PerVertex - { - float a; - float c; - }; - - cbuffer PerVertex - { - float b; - }; - - cbuffer PerPixel - { - float d; - }; - - float e; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl deleted file mode 100644 index 919664c10d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/CyclicTest.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader CyclicTest : CyclicTest -{ - -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl deleted file mode 100644 index 1b378d8113..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExtern.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader DeepExtern -{ - compose ExternMixin myExtern; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl deleted file mode 100644 index 8b2fca2f23..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/DeepExternTest.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader DeepExternTest -{ - compose DeepExtern myExtern; - - float externCall() - { - myExtern.myExtern.externFunc(); - return myExtern.myExtern.externMember; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl deleted file mode 100644 index f30dc65da8..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternClone.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternClone -{ - clone void test() - { - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl deleted file mode 100644 index af0015bebf..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternCloneTest.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternCloneTest -{ - compose DeepExtern ext0; - compose DeepExtern ext1; - - void Test() - { - float fext0 = ext0.myExtern.externMember; - float fext1 = ext1.myExtern.externMember; - ext0.myExtern.externFunc(); - ext1.myExtern.externFunc(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl deleted file mode 100644 index 56dcf2ea5a..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternMixin.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternMixin -{ - float externMember = 1.0f; - - void externFunc() - { - float a = 0.0f; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl deleted file mode 100644 index f83715581a..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ExternTest.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ExternTest -{ - compose ExternMixin myExtern; - - void externFunc(){} - - float externCall() - { - myExtern.externFunc(); - return myExtern.externMember; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl deleted file mode 100644 index 3f9b08c2af..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/ForEachTest.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader ForEachTest -{ - float collec[5]; - - float test() - { - float res = 0.0; - foreach (var val in collec) - { - res += val; - } - return res; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl deleted file mode 100644 index e08c997320..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericCall.sdsl +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericCall : TestGenerics<1.000000> -{ -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl deleted file mode 100644 index 938068ca99..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass.sdsl +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericClass< - Texture2D Texture,// = Texturing.Texture0, - SamplerState Sampler,// = Texturing.Sampler, - Semantic NAME, // = TEXCOORD0 - LinkType myLink, - unorm float constFloat, - int2 constInt2, - uint3 constUInt3, - float4 constUNormFloat4, - float linkVariable -> : TestBaseClass -{ - [Link("GenericLink.myLink")] - stage float3 uniformVariable; - - stage stream float2 texCoord : NAME; - - float genericCompute() - { - float4 value0 = TestBaseClass.Value; - return streams.texCoord.x * Texture.Sample(Sampler, streams.texCoord).x; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl deleted file mode 100644 index 6d724ee1dd..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericClass2.sdsl +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericClass2 -< - Texture2D Texture, - Semantic TEXCOORD_INDEX, - float4 scale -> : ShaderBase, Texturing -{ - stage stream float2 texcoord0 : TEXCOORD_INDEX; - Texture2D TextureAll = Texturing.Texture3; - - stage override void VSMain() - { - streams.ShadingPosition = float4(1,1,1,1) * Texture.SampleLevel(Sampler, streams.texcoord0, 0); - } - - stage override void PSMain() - { - streams.ColorTarget = scale * float4(1,1,1,1) * streams.ShadingPosition * Texturing.Texture1.Sample(Sampler, streams.texcoord0); - streams.ColorTarget = streams.ColorTarget * GenericClass.genericCompute(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl deleted file mode 100644 index 655f2afb72..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericExtern.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericExtern -{ - compose GenericTexcoord myExtern; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl deleted file mode 100644 index 6ce943dc08..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GenericTexcoord.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GenericTexcoord -{ - float2 coords : T; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl deleted file mode 100644 index 17f90de8ce..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/GeometryShaderTest.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader GeometryShaderTest : TestStructure -{ - void testGS0(point Input input[1], TriangleStream param){} - void testGS1(LineStream param){} - void testGS2(PointStream param){} -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl deleted file mode 100644 index f90b316241..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InterfaceTest.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader InterfaceTest -{ - interface myInterface - { - abstract void test(); - }; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl deleted file mode 100644 index c337ce8bbe..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/InternalReferenceMixin.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader InternalReferenceMixin -{ - float myValue = 2.0f; - - float test() - { - return myValue; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl deleted file mode 100644 index c23fcc2b58..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTest.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#ifndef MACRO_TEST -# define MACRO_TEST float -#endif -shader MacroTest -{ - MACRO_TEST u; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl deleted file mode 100644 index b8a411cac5..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestBase.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MacroTestBase -{ - float4 GetValue() - { - return float4(0,0,0,0); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl deleted file mode 100644 index 1bf53ae07d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MacroTestChild.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MacroTestChild : MacroTest -{ - -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl deleted file mode 100644 index 041feeb5b8..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinFunctionParamaterTest.sdsl +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinFunctionParamaterTest -{ - abstract ExternMixin test0(); - - abstract void test1(ExternMixin ext); -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl deleted file mode 100644 index 2b56f2ad0e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNameClash.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinNameClash : BasicMixin, BasicMixin2 -{ - void test() - { - float i = myFloat; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl deleted file mode 100644 index 4bc0d30555..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/MixinNoNameClash.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader MixinNoNameClash : BasicMixin, BasicMixin2 -{ - void test() - { - float i = BasicMixin.myFloat + BasicMixin2.myFloat; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl deleted file mode 100644 index 8bf84f7428..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/NonStageStreamTest.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader NonStageStreamTest -{ - compose StreamParent2 ext0; - compose StreamParent2 ext1; - - float test() - { - return streams.ext0.parentStream + streams.ext1.parentStream + streams.ext0.stageStream + streams.ext1.stageStream; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl deleted file mode 100644 index e58652e647..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Parent.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Parent -{ - float baseValue = 2.0f; - Texture2D parentTexture; - - float AddBaseValue(float inValue) - { - float a0 = 0.0f, - a1 = 1.0f; - return inValue + baseValue + a0 + a1; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl deleted file mode 100644 index a6097376aa..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/SemanticTest.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader SemanticTest -{ - cbuffer PerFrame - { - float sem0 : POSITION; - float sem1 : POSITION; - } - - float test() - { - return sem0 + sem1; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl deleted file mode 100644 index 65cf152d21..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/Simple.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader Simple -{ - float test; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl deleted file mode 100644 index d4a4d22e00..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageBase.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageBase -{ - abstract stage void stageCall(); - stage float stageMember = 1.0f; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl deleted file mode 100644 index a65e6bb714..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageCallExtern.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageCallExtern : StageBase -{ - void test() - { - float u = stageMember; - stageCall(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl deleted file mode 100644 index b7186c6c75..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageDecl.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageDecl -{ - stage int myStageVar = 1; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl deleted file mode 100644 index f152267982..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueReference.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageValueReference -{ - compose StageValueTest myStageVar = stage; - - void test() - { - myStageVar.test(); - float u = myStageVar.testFloat; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl deleted file mode 100644 index 8234eabb92..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StageValueTest.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StageValueTest -{ - compose StageValueReference myExtern; - float testFloat; - - void test() - { - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl deleted file mode 100644 index 664bed071d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticCallMixin.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticCallMixin -{ - void call() - { - StaticMixin.staticCall(); - float a = -StaticMixin.staticMember; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl deleted file mode 100644 index 911790092d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticMixin.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticMixin -{ - float staticMember; - - void staticCall() - { - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl deleted file mode 100644 index c2e581c111..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StaticStageCallTest.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StaticStageCallTest : StageBase -{ - compose StageCallExtern myExtern; - - stage void stageCall() - { - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl deleted file mode 100644 index 180e55db59..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamChild.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamChild : StreamParent0, StreamParent1 -{ - float test() - { - return streams.StreamParent0.parentStream + streams.StreamParent1.parentStream; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl deleted file mode 100644 index 61577f7001..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamError.sdsl +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamError -{ - stream float myStream; - - void test0(inout float value) - { - value = 2.0*value; - } - - void test1() - { - test0(streams.myStream); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl deleted file mode 100644 index 8f2b752f80..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent0.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent0 -{ - stream float parentStream = 0.0f; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl deleted file mode 100644 index f97b938f0d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent1.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent1 -{ - stream float parentStream = 0.0f; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl deleted file mode 100644 index b55c0f6d3d..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamParent2.sdsl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamParent2 -{ - stream float parentStream = 0.0f; - stage stream float stageStream = 0.0f; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl deleted file mode 100644 index 020d4a5d28..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamSolverExternTest.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamSolverExternTest -{ - compose StreamChild myExtern; - float func() - { - return streams.myExtern.StreamParent0.parentStream + streams.myExtern.StreamParent1.parentStream; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl deleted file mode 100644 index 6918d24a02..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StreamTest.sdsl +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StreamTest -{ - stream float2 PositionIn : Position; - stream float4 PositionOut; - stream float4 Color; - patchstream float3 patchstreamParam; - - void test() - { - streams.PositionOut = 2.0f*streams.PositionOut; - } - - void VSMain() - { - streams.PositionOut = float4(streams.PositionIn, 0.0f, 1.0f); - test(); - test(); - float4 a = streams.PositionOut; - } - - void PSMain() - { - streams.Color = streams.PositionOut; - //streams.Color = float4(0,0,0,0); - } - - void GSMain(point Input input[1], inout PointStream outStream) - { - streams = input[0]; - - streams.PositionOut = 0.5f * streams.PositionOut; - - outStream.Append(streams); - - for (int i = 0; i < 2; ++i) - { - outStream.Append(streams); - } - - outStream.RestartStrip(); - } - - void HSMain(InputPatch input, out Output output) - { - streams = input[0]; - //streams.PositionOut = 0.5f * streams.PositionOut; - output.PositionOut = 0.5f * input[0].PositionOut; - - output = streams; - - // TODO: using this syntax should be possible too - // TODO: add corresponding StreamUsage - //output.PositionOut = 0.5f * input[0].PositionOut; - } - - void HSConstantMain(InputPatch input, const OutputPatch output, out Constants constants) - { - constants.patchstreamParam = 1.0f; - } - - void DSMain(const OutputPatch input, out Output output, in Constants constants, float3 f3BarycentricCoords : SV_DomainLocation) - { - streams = input[0]; - //streams.PositionOut = 0.5f * streams.PositionOut * constants.patchstreamParam.x; - streams = 0.5f * streams;// * constants.patchstreamParam.x; - output = streams; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl deleted file mode 100644 index 2479ccc773..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/StructuredBufferTest.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader StructuredBufferTest -{ - StructuredBuffer sbtest; - RWStructuredBuffer rwsbtest; - - void test() - { - uint numStructs; - uint stride; - sbtest.GetDimensions(numStructs, stride); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl deleted file mode 100644 index 161b4bc557..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TessellationTest.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TessellationTest -{ - patchstream float tessFactor[3] : SV_TessFactor; - patchstream float insideTessFactor : SV_InsideTessFactor; - - float test(Constants constants) - { - return constants.tessFactor[0] + constants.insideTessFactor; - } - - float test2(InputPatch input, OutputPatch output, inout Constants constants) - { - return 0.0f; - } - - float test3(InputPatch input, OutputPatch output, inout Constants constants) - { - return test2(input, output, constants); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl deleted file mode 100644 index 4cfbb18e4b..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestComputeShader.sdsl +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#ifndef ThreadCountX -# define ThreadCountX 10 -#endif -#ifndef ThreadCountY -# define ThreadCountY 5 -#endif -#ifndef ThreadCountZ -# define ThreadCountZ 2 -#endif - -shader TestComputeShader -{ - stage stream uint3 GroupId : SV_GroupID; - stage stream uint3 DispatchThreadId : SV_DispatchThreadID; - stage stream uint3 GroupThreadId : SV_GroupThreadID; - stage stream uint GroupIndex : SV_GroupIndex; - - stage stream uint3 ThreadGroupCount; - stage stream uint ThreadCountPerGroup; - stage stream uint ThreadGroupIndex; - - cbuffer PerDispatch { - //[Link("Stride.Effects.ComputeShaderPluginKeys.ThreadGroupCount")] - stage uint3 ThreadGroupCountGlobal; - }; - - cbuffer ParticleCountBuffer { - uint ParticleCount; - uint ParticleStartIndex; - }; - - stage RWStructuredBuffer ParticleSortBuffer; - [Link("ParticleSortBuffer")] - stage StructuredBuffer ParticleSortBufferRO; - - [numthreads(ThreadCountX, ThreadCountY, ThreadCountZ)] - void CSMain() - { - streams.ThreadCountPerGroup = ThreadCountX * ThreadCountY * ThreadCountZ; - streams.ThreadGroupCount = ThreadGroupCountGlobal; - streams.ThreadGroupIndex = (streams.GroupId.z * streams.ThreadGroupCount.y + streams.GroupId.y) * streams.ThreadGroupCount.x + streams.GroupId.x; - Compute(); - } - - void Compute() - { - ParticleSortBuffer[0] = uint2(0,1); - uint numStructs; - uint stride; - ParticleSortBufferRO.GetDimensions(numStructs, stride); - ParticleSortBuffer.IncrementCounter(); - ParticleSortBuffer.DecrementCounter(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl deleted file mode 100644 index 352ad88626..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestErrors.sdsl +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestErrors -{ - abstract override void test0(); // 1 error + 1 error - override void test1(); // 2 errors + 1 error - abstract void test2(){} // 1 error - - stream float myStream; - float nonStream; - - extern int falseExtern = stage; // 2 errors - - extern ExternMixin myExtern; - - void test3() - { - test3(); // cyclic error - this.testNone(); // this error + 1 type inference - test1(); // 1 error call to declaration - - streams.myStream = myStream + 1.0f; // 1 error - streams.myStream = streams.nonStream; // 2 errors - streams.myStream = stage.noMember; // stage use error + stage name error + 2 types errors - - var varVar; // 1 error - - myExtern.falseCall(); // 1 no member error + 2 function not found errors - } - - void test4() - { - base.test4(); // no base mixin + base error + 1 type inferences - } - - float test5(float param) - { - return param; - } - int test5(int param) - { - return param; - } - - float test6() - { - var varIn; // 1 error - var varOut = test5(param); // 1 var error + 2 function error - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl deleted file mode 100644 index d1225b19c6..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestExternArray.sdsl +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestExternArray -{ - compose ExternMixin externArray[]; - - float test() - { - externArray[0].externFunc(); - externArray[1].externFunc(); - - float a = externArray[0].externMember + externArray[1].externMember; - - foreach (var ext in externArray) - { - ext.externFunc(); - a += ext.externMember; - } - - return a; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl deleted file mode 100644 index 2519535b95..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericComplex.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenericComplex -{ - float test0() - { - return TestGenericMacro.test(); - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl deleted file mode 100644 index 30d55dc807..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenericMacro.sdsl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenericMacro -{ - float test() - { - return MACRO; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl deleted file mode 100644 index c96d51ee3a..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestGenerics.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestGenerics -{ - float myMember = 2.0f; - - float test() - { - return myMember + myGen; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl deleted file mode 100644 index ad4ff21633..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacros.sdsl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMacros : PositionVertexTransform, ShadingBase -{ - compose MacroTest macros0; - compose MacroTest macros1; - compose MacroTest macros2; - - stage override void PSMain() - { - base.PSMain(); - float4 color = macros0.u * streams.ColorTarget + macros1.u * macros2.u; - streams.ColorTarget = color; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl deleted file mode 100644 index fbf4bf4b1f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMacrosArray.sdsl +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMacrosArray : PositionVertexTransform, ShadingBase -{ - compose MacroTest macrosArray[]; - - stage override void PSMain() - { - base.PSMain(); - float4 color = macrosArray[0].u * streams.ColorTarget + macrosArray[1].u * macrosArray[2].u; - streams.ColorTarget = color; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl deleted file mode 100644 index a3bc389325..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestMultipleStatic.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestMultipleStatic -{ - compose StaticCallMixin staticExtern; - - void test() - { - StaticMixin.staticCall(); - float u = StaticMixin.staticMember; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl deleted file mode 100644 index 1934dae119..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestPixelStream.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestPixelStream : TestScreenPosition -{ - stream float4 OutputColor; - - void PSMain() - { - streams.OutputColor = streams.ScreenPosition; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl deleted file mode 100644 index 64bf3fc629..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestScreenPosition.sdsl +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestScreenPosition -{ - stream float4 ScreenPosition; -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl deleted file mode 100644 index 27b2b8ebc6..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStreams.sdsl +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStreams : TestVertexStream, TestPixelStream -{ - void test0(Input input) - { - streams = input; - float4 a = streams.Position; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl deleted file mode 100644 index e1e3303443..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritance.sdsl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStructInheritance : TestStructure -{ - myStruct member; - - float test2() - { - return member.structFloat; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritanceExtensions.cs b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritanceExtensions.cs deleted file mode 100644 index 13fb6946c6..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructInheritanceExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -namespace Stride.Rendering -{ - public struct myStruct - { - - } -} diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl deleted file mode 100644 index 90a066bd71..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestStructure.sdsl +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestStructure -{ - struct myStruct - { - float structFloat; - }; - - float test(myStruct param) - { - return param.structFloat; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl b/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl deleted file mode 100644 index ca183348e1..0000000000 --- a/sources/engine/Stride.Shaders.Tests/GameAssets/Shaders/TestVertexStream.sdsl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -shader TestVertexStream : TestScreenPosition -{ - stream float4 Position; - - void VSMain() - { - // TODO: remove extra code for this type check (float * floatX) - streams.ScreenPosition = 2.0*streams.Position; - } -}; diff --git a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj deleted file mode 100644 index 63334491ae..0000000000 --- a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - $(StrideEditorTargetFramework) - win-x64 - Stride.Shaders.Tests - Stride.Shaders.Tests - * - true - true - - true - - - xunit.runner.stride.Program - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.sdpkg b/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.sdpkg deleted file mode 100644 index 5d85cdfcc2..0000000000 --- a/sources/engine/Stride.Shaders.Tests/Stride.Shaders.Tests.Windows.sdpkg +++ /dev/null @@ -1,9 +0,0 @@ -!Package -Id: 04ed1618-1a06-4a69-ac34-1006a978af11 -SerializedVersion: {Assets: 3.1.0.0} -AssetFolders: - - Path: !dir GameAssets -ExplicitFolders: [] -Bundles: [] -TemplateFolders: [] -RootAssets: [] diff --git a/sources/engine/Stride.Shaders.Tests/TestCodeGen.cs b/sources/engine/Stride.Shaders.Tests/TestCodeGen.cs deleted file mode 100644 index e19132aea6..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestCodeGen.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.IO; -using System.Text; - -using Xunit; - -using Stride.Shaders.Parser.Mixins; - -namespace Stride.Shaders.Tests -{ - /// - /// Code used to regenerate all cs files from sdsl/sdfx in the project - /// - public class TestCodeGen - { - //[Fact] - public void Test() - { - var filePath = @"D:\Code\Stride\sources\engine\Stride.Shaders.Tests\GameAssets\Mixins\A.sdsl"; - var source = File.ReadAllText(filePath); - var content = ShaderMixinCodeGen.GenerateCsharp(source, filePath.Replace("C:", "D:")); - } - - //[Fact] // Decomment this line to regenerate all files (sources and samples) - public void RebuildAllXkfxXksl() - { - RegenerateDirectory(Path.Combine(Environment.CurrentDirectory, @"..\..\sources")); - RegenerateDirectory(Path.Combine(Environment.CurrentDirectory, @"..\..\samples")); - } - - private static void RegenerateDirectory(string directory) - { - //foreach (var sdsl in Directory.EnumerateFiles(directory, "*.sdsl", SearchOption.AllDirectories)) - //{ - // RebuildFile(sdsl); - //} - foreach (var sdfx in Directory.EnumerateFiles(directory, "*.sdfx", SearchOption.AllDirectories)) - { - RebuildFile(sdfx); - } - } - - private static void RebuildFile(string filePath) - { - try - { - var source = File.ReadAllText(filePath); - var content = ShaderMixinCodeGen.GenerateCsharp(source, filePath); - - // Sometimes, we have a collision with the .cs file, so generated filename might be postfixed with 1 - var destPath = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + "1.cs"); - if (!File.Exists(destPath)) - destPath = Path.ChangeExtension(filePath, ".cs"); - if (!File.Exists(destPath)) - { - Console.WriteLine("Target file {0} doesn't exist", destPath); - return; - } - File.WriteAllText(destPath, content, Encoding.UTF8); - Console.WriteLine("File generated {0}", filePath); - } - catch (Exception ex) - { - Console.WriteLine("Unexpected error {0}: {1}", filePath, ex); - } - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestGenericClass.cs b/sources/engine/Stride.Shaders.Tests/TestGenericClass.cs deleted file mode 100644 index 5380025c20..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestGenericClass.cs +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Xunit; -using System.Linq; -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Games; -using Stride.Graphics; -using Stride.Shaders.Compiler; -using Stride.Shaders.Parser.Mixins; -using Stride.Core.Shaders.Ast; -using Stride.Core.Shaders.Ast.Hlsl; - -namespace Stride.Shaders.Tests -{ - public class TestGenericClass - { - private ShaderSourceManager manager; - private Stride.Core.Shaders.Utility.LoggerResult logger; - private ShaderLoader loader; - - private void Init() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - manager = new ShaderSourceManager(databaseFileProvider); - manager.LookupDirectoryList.Add("shaders"); - logger = new Stride.Core.Shaders.Utility.LoggerResult(); - loader = new ShaderLoader(manager); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestParsing() - { - Init(); - - var generics = new object[9]; - generics[0] = "Texturing.Texture1"; - generics[1] = "Texturing.Sampler1"; - generics[2] = "TEXCOORD0"; - generics[3] = "CustomLink"; - generics[4] = "1.2f"; - generics[5] = "int2(1,2)"; - generics[6] = "uint3(0,1,2)"; - generics[7] = "float4(5,4,3,2)"; - generics[8] = "StaticClass.staticFloat"; - var shaderClass = loader.LoadClassSource(new ShaderClassSource("GenericClass", generics), null, logger, false)?.Type; - - Assert.NotNull(shaderClass); - - Assert.Equal(10, shaderClass.Members.Count); - Assert.Equal(4, shaderClass.Members.OfType().Count(x => x.Qualifiers.Contains(Stride.Core.Shaders.Ast.Hlsl.StorageQualifier.Static))); - Assert.Empty(shaderClass.ShaderGenerics); - Assert.Empty(shaderClass.GenericArguments); - Assert.Empty(shaderClass.GenericParameters); - Assert.Single(shaderClass.BaseClasses); - - var linkVar = shaderClass.Members[0] as Variable; - Assert.NotNull(linkVar); - var linkName = linkVar.Attributes.OfType().Where(x => x.Name.Text == "Link").Select(x => x.Parameters[0].Text).FirstOrDefault(); - Assert.Equal("GenericLink.CustomLink", linkName); - - var baseClass = shaderClass.BaseClasses[0].Name as IdentifierGeneric; - Assert.NotNull(baseClass); - Assert.Equal(3, baseClass.Identifiers.Count); - Assert.Equal("TEXCOORD0", baseClass.Identifiers[0].Text); - Assert.Equal("CustomLink", baseClass.Identifiers[1].Text); - Assert.Equal("float4(5,4,3,2)", baseClass.Identifiers[2].Text); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestShaderCompilation() - { - Init(); - - var generics = new string[3]; - generics[0] = "Texturing.Texture1"; - generics[1] = "TEXCOORD0"; - generics[2] = "float4(2.0,1,1,1)"; - - var compilerParameters = new CompilerParameters(); - compilerParameters.Set(EffectSourceCodeKeys.Enable, true); - compilerParameters.EffectParameters.Profile = GraphicsProfile.Level_11_0; - - var mixinSource = new ShaderMixinSource { Name = "TestShaderCompilationGenericClass" }; - mixinSource.Mixins.Add(new ShaderClassSource("GenericClass2", generics)); - - var log = new CompilerResults(); - - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider); - compiler.SourceDirectories.Add("shaders"); - - var effectBytecode = compiler.Compile(mixinSource, compilerParameters.EffectParameters, compilerParameters); - } - - - private void Run() - { - TestParsing(); - //TestShaderCompilation(); - } - - private static void Main5() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var assetIndexMap = ContentIndexMap.Load(VirtualFileSystem.ApplicationDatabaseIndexPath); - var databaseFileProvider = new DatabaseFileProvider(assetIndexMap, objDatabase); - - var test = new TestGenericClass(); - test.Run(); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestHelper.cs b/sources/engine/Stride.Shaders.Tests/TestHelper.cs deleted file mode 100644 index 7a65dbf151..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestHelper.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using Stride.Core.IO; -using Stride.Core.Storage; - -namespace Stride.Shaders.Tests -{ - static class TestHelper - { - public static IDatabaseFileProviderService CreateDatabaseProvider() - { - VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath); - return new DatabaseFileProviderService(new DatabaseFileProvider(ObjectDatabase.CreateDefaultDatabase())); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs b/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs deleted file mode 100644 index ce85bb3142..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestMixinCompiler.cs +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -using Xunit; - -using Stride.Core.Assets; -using Stride.Core.IO; -using Stride.Core.Mathematics; -using Stride.Core.Serialization; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Assets.Materials; -using Stride.Rendering.Materials.ComputeColors; -using Stride.Rendering; -using Stride.Rendering.Materials; -using Stride.Graphics; -using Stride.Shaders.Compiler; -using Stride.Shaders.Parser.Mixins; - -namespace Stride.Shaders.Tests -{ - /// - /// Tests for the mixins code generation and runtime API. - /// - public partial class TestMixinCompiler - { - /// - /// Tests mixin and compose keys with compilation. - /// - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestMaterial() - { - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Core")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Lights")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shadows")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Materials\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Materials\ComputeColors\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Skinning")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shading")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Transformation")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Utils")); - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.Direct3D11); - - var layers = new MaterialBlendLayers(); - layers.Add(new MaterialBlendLayer - { - BlendMap = new ComputeFloat(0.5f), - Material = AttachedReferenceManager.CreateProxyObject(AssetId.Empty, "fake") - }); - - var materialAsset = new MaterialAsset - { - Attributes = new MaterialAttributes() - { - Diffuse = new MaterialDiffuseMapFeature() - { - DiffuseMap = new ComputeColor(Color4.White) - }, - DiffuseModel = new MaterialDiffuseLambertModelFeature() - }, - Layers = layers - }; - - var fakeAsset = new MaterialAsset - { - Attributes = new MaterialAttributes() - { - Diffuse = new MaterialDiffuseMapFeature() - { - DiffuseMap = new ComputeColor(Color.Blue) - }, - } - }; - - var context = new MaterialGeneratorContext { FindAsset = reference => fakeAsset }; - var result = MaterialGenerator.Generate(new MaterialDescriptor { Attributes = materialAsset.Attributes, Layers = materialAsset.Layers }, context, "TestMaterial"); - - compilerParameters.Set(MaterialKeys.PixelStageSurfaceShaders, result.Material.Passes[0].Parameters.Get(MaterialKeys.PixelStageSurfaceShaders)); - var directionalLightGroup = new ShaderClassSource("LightDirectionalGroup", 1); - compilerParameters.Set(LightingKeys.DirectLightGroups, new ShaderSourceCollection { directionalLightGroup }); - //compilerParameters.Set(LightingKeys.CastShadows, false); - //compilerParameters.Set(MaterialParameters.HasSkinningPosition, true); - //compilerParameters.Set(MaterialParameters.HasSkinningNormal, true); - compilerParameters.Set(MaterialKeys.HasNormalMap, true); - - var results = compiler.Compile(new ShaderMixinGeneratorSource("StrideEffectBase"), compilerParameters); - - Assert.False(results.HasErrors); - } - - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestStream() - { - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Shaders.Tests\GameAssets\Compiler")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Core")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Lights")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shadows")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Materials\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Materials\ComputeColors\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Skinning")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Shading")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Transformation")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Engine\Rendering\Utils")); - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.Direct3D11); - var results = compiler.Compile(new ShaderClassSource("TestStream"), compilerParameters); - - Assert.False(results.HasErrors); - } - - - /// - /// Tests mixin and compose keys with compilation. - /// - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestMixinAndComposeKeys() - { - var compiler = new EffectCompiler(TestHelper.CreateDatabaseProvider().FileProvider) { UseFileSystem = true }; - var currentPath = Stride.Core.PlatformFolders.ApplicationBinaryDirectory; - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Graphics\Shaders")); - compiler.SourceDirectories.Add(Path.Combine(currentPath, @"..\..\sources\engine\Stride.Shaders.Tests\GameAssets\Mixins")); - - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.Direct3D11); - - var subCompute1Key = TestABC.TestParameters.UseComputeColor2.ComposeWith("SubCompute1"); - var subCompute2Key = TestABC.TestParameters.UseComputeColor2.ComposeWith("SubCompute2"); - var subComputesKey = TestABC.TestParameters.UseComputeColorRedirect.ComposeWith("SubComputes[0]"); - - compilerParameters.Set(subCompute1Key, true); - compilerParameters.Set(subComputesKey, true); - - var results = compiler.Compile(new ShaderMixinGeneratorSource("test_mixin_compose_keys"), compilerParameters); - - Assert.False(results.HasErrors); - - var mainBytecode = results.Bytecode.WaitForResult(); - Assert.False(mainBytecode.CompilationLog.HasErrors); - - Assert.NotNull(mainBytecode.Bytecode.Reflection.ConstantBuffers); - Assert.Single(mainBytecode.Bytecode.Reflection.ConstantBuffers); - var cbuffer = mainBytecode.Bytecode.Reflection.ConstantBuffers[0]; - - Assert.NotNull(cbuffer.Members); - Assert.Equal(2, cbuffer.Members.Length); - - - // Check that ComputeColor2.Color is correctly composed for variables - var computeColorSubCompute2 = ComputeColor2Keys.Color.ComposeWith("SubCompute1"); - var computeColorSubComputes = ComputeColor2Keys.Color.ComposeWith("ColorRedirect.SubComputes[0]"); - - var members = cbuffer.Members.Select(member => member.KeyInfo.KeyName).ToList(); - Assert.Contains(computeColorSubCompute2.Name, members); - Assert.Contains(computeColorSubComputes.Name, members); - } - - private void CopyStream(DatabaseFileProvider database, string fromFilePath) - { - var shaderFilename = string.Format("shaders/{0}", Path.GetFileName(fromFilePath)); - using (var outStream = database.OpenStream(shaderFilename, VirtualFileMode.Create, VirtualFileAccess.Write, VirtualFileShare.Write)) - { - using (var inStream = new FileStream(fromFilePath, FileMode.Open, FileAccess.Read)) - { - inStream.CopyTo(outStream); - } - } - } - - /// - /// Tests a simple mixin. - /// - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestReal() - { - // TODO: review this tet - if (Directory.Exists("data")) - { - Directory.Delete("data", true); - } - - CompilerResults results01; - CompilerResults results02; - - // Test this with a new database completely clean - TestNoClean(out results01, out results02); - Assert.Equal(results02.Bytecode, results01.Bytecode); - - // Test with the database with already the bytecode generated by previous step - CompilerResults results11; - CompilerResults results12; - TestNoClean(out results11, out results12); - Assert.Equal(results12.Bytecode, results11.Bytecode); - - // Check previous result - //Assert.Equal(results11.MainBytecode.Time, results01.MainBytecode.Time); -> crash, MainBytecode == null - } - - private void TestNoClean(out CompilerResults left, out CompilerResults right) - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - using (var assetIndexMap = ContentIndexMap.Load(VirtualFileSystem.ApplicationDatabaseIndexPath)) - { - var database = new DatabaseFileProvider(assetIndexMap, objDatabase); - - foreach (var shaderName in Directory.EnumerateFiles(@"..\..\sources\shaders", "*.sdsl")) - CopyStream(database, shaderName); - - foreach (var shaderName in Directory.EnumerateFiles(@"..\..\sources\engine\Stride.Shaders.Tests\GameAssets\Compiler", "*.sdsl")) - CopyStream(database, shaderName); - - var compiler = new EffectCompiler(database); - compiler.SourceDirectories.Add("assets/shaders"); - var compilerCache = new EffectCompilerCache(compiler, database); - - var compilerParameters = CreateCompilerParameters(GraphicsPlatform.Direct3D11); - - left = compilerCache.Compile(new ShaderMixinGeneratorSource("SimpleEffect"), compilerParameters); - right = compilerCache.Compile(new ShaderMixinGeneratorSource("SimpleEffect"), compilerParameters); - } - } - - - /// - /// Creates the compiler parameters for the specified graphics platform. - /// - /// The graphics platform. - /// The created . - private static CompilerParameters CreateCompilerParameters(GraphicsPlatform platform) - { - var compilerParameters = new CompilerParameters(); - compilerParameters.EffectParameters.Platform = platform; - return compilerParameters; - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Extensions.cs b/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Extensions.cs deleted file mode 100644 index 665c5e6215..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Extensions.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Linq; - -using Xunit; - -namespace Stride.Shaders.Tests -{ - /// - /// Extension methods used by - /// - static class TestMixinGeneratorExtensions - { - /// - /// Checks a mixin contains the specific names. - /// - /// The mixin. - /// The names to check. - public static void CheckMixin(this ShaderMixinSource mixin, params string[] names) - { - var expectingNames = string.Join(",", names); - var resultNames = string.Join(",", mixin.Mixins.Select(source => source.ToString())); - - var messageMixins = string.Format("Invalid result for mixin: [{0}] Expecting [{1}]", resultNames, expectingNames); - - Assert.True(resultNames == expectingNames, messageMixins); - } - - /// - /// Checks the composition is declared in the mixin. - /// - /// The mixin. - /// The key. - /// The value. - public static void CheckComposition(this ShaderMixinSource mixin, string key, string value) - { - ShaderSource source; - Assert.True(mixin.Compositions.TryGetValue(key, out source), $"Unable to find key [{key}] in mixin compositions"); - - Assert.True(source != null, $"Source composition for key [{key}] cannot be null"); - - var classSource = source as ShaderClassCode; - if (classSource != null) - { - var sourceString = classSource.ToClassName(); - Assert.True(sourceString == value, $"Invalid composition for key [{key}]: [{sourceString}] expecting [{value}]"); - } - else - { - var mixinSource = source as ShaderMixinSource; - if (mixinSource != null) - { - mixinSource.CheckMixin(value); - } - } - } - - /// - /// Checks the macro is declared in the mixin - /// - /// The mixin. - /// The key. - /// The value. - public static void CheckMacro(this ShaderMixinSource mixin, string key, object value) - { - var macro = mixin.Macros.FirstOrDefault(tuple => tuple.Name == key); - Assert.True(macro.Name != null, $"Invalid macro [{key}] cannot be null"); - - var macroValue = macro.Definition.ToString(); - Assert.True(value.ToString() == macroValue, $"Invalid macro [{key}] value [{macroValue}] != Expecting [{value}]"); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Helpers.cs b/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Helpers.cs deleted file mode 100644 index 3086f2d4e5..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.Helpers.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Collections.Generic; - -using Xunit; - -using Stride.Rendering; - -namespace Stride.Shaders.Tests -{ - /// - /// Helper methods for TestMixinGenerator - /// - public partial class TestMixinGenerator - { - /// - /// Generates the mixin. - /// - /// Name of the mixin. - /// The properties that the mixin will use. - /// ShaderMixinSource. - private static ShaderMixinSource GenerateMixin(string mixinName, ParameterCollection properties) - { - var mixin = ShaderMixinManager.Generate(mixinName, properties); - - // Verify that output used properties are a subset of input properties - //Assert.That(usedProperties.IsSubsetOf(properties), Is.True); - - //foreach(var usedProps in allUsedProperties) - // Assert.That(usedProps.IsSubsetOf(properties), Is.True); - - return mixin; - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.cs b/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.cs deleted file mode 100644 index 6e591c7623..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestMixinGenerator.cs +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.IO; -using System.Linq; - -using Xunit; - -using Stride.Core.Serialization; -using Stride.Rendering; - -namespace Stride.Shaders.Tests -{ - /// - /// Tests for the mixins code generation and runtime API. - /// - public partial class TestMixinGenerator - { - /// - /// Tests a simple mixin. - /// - [Fact] - public void TestSimple() - { - var properties = new ShaderMixinParameters(); - - var mixin = GenerateMixin("DefaultSimple", properties); - mixin.CheckMixin("A", "B", "C"); - } - - /// - /// Tests with a child mixin. - /// - [Fact] - public void TestSimpleChild() - { - var properties = new ShaderMixinParameters(); - - var mixin = GenerateMixin("DefaultSimpleChild", properties); - mixin.CheckMixin("A", "B", "C", "C1", "C2"); - } - - /// - /// Tests a simple composition - /// - [Fact] - public void TestSimpleCompose() - { - var properties = new ShaderMixinParameters(); - - var mixin = GenerateMixin("DefaultSimpleCompose", properties); - mixin.CheckMixin("A", "B", "C"); - mixin.CheckComposition("x", "X"); - } - - /// - /// Tests simgple parameters usage - /// - [Fact] - public void TestSimpleParams() - { - var properties = new ShaderMixinParameters(); - - var mixin = GenerateMixin("DefaultSimpleParams", properties); - mixin.CheckMixin("A", "B", "D"); - mixin.CheckComposition("y", "Y"); - mixin.CheckMacro("Test", "ok"); - - // Set a key to modify the mixin - properties.Set(Test7.TestParameters.param1, true); - - mixin = GenerateMixin("DefaultSimpleParams", properties); - mixin.CheckMixin("A", "B", "C"); - mixin.CheckComposition("x", "X"); - mixin.CheckMacro("param2", 1); - } - - /// - /// Tests clone. - /// - [Fact] - public void TestSimpleClone() - { - var properties = new ShaderMixinParameters(); - - var mixin = GenerateMixin("DefaultSimpleClone", properties); - mixin.CheckMixin("A", "B", "C"); - - var childMixin = GenerateMixin("DefaultSimpleClone.Test", properties); - childMixin.CheckMixin("A", "B", "C", "C1", "C2"); - } - - - /// - /// Test parameters - /// - [Fact] - public void TestMixinAndComposeKeys() - { - var properties = new ShaderMixinParameters(); - - var subCompute1Key = TestABC.TestParameters.UseComputeColor2.ComposeWith("SubCompute1"); - var subCompute2Key = TestABC.TestParameters.UseComputeColor2.ComposeWith("SubCompute2"); - var subComputesKey = TestABC.TestParameters.UseComputeColorRedirect.ComposeWith("SubComputes[0]"); - - properties.Set(subCompute1Key, true); - properties.Set(subComputesKey, true); - - var mixin = GenerateMixin("test_mixin_compose_keys", properties); - mixin.CheckMixin("A"); - - Assert.Equal(3, mixin.Compositions.Count); - - Assert.True(mixin.Compositions.ContainsKey("SubCompute1")); - Assert.True(mixin.Compositions.ContainsKey("SubCompute2")); - Assert.True(mixin.Compositions.ContainsKey("SubComputes")); - - Assert.Equal("mixin TestComputeColor2", mixin.Compositions["SubCompute1"].ToString()); - Assert.Equal("mixin TestComputeColor", mixin.Compositions["SubCompute2"].ToString()); - Assert.Equal("[mixin TestComputeColorRedirect [{ColorRedirect = mixin TestComputeColor2}]]", mixin.Compositions["SubComputes"].ToString()); - } - - /// - /// Tests the complex parameters (array and nested using) - /// - [Fact] - public void TestComplexParams() - { - var properties = new ShaderMixinParameters(); - - // Populate the the properties used by the mixin - var subParam1 = new Test1.SubParameters(); - var subParameters = new Test1.SubParameters[4]; - for (int i = 0; i < subParameters.Length; i++) - { - subParameters[i] = new Test1.SubParameters(); - } - - properties.Set(Test1.TestParameters.subParam1, subParam1); - properties.Set(Test1.TestParameters.subParameters, subParameters); - - // Generate the mixin with default properties - var mixin = GenerateMixin("DefaultComplexParams", properties); - mixin.CheckMixin("A", "B", "C", "D"); - - // Modify properties in order to modify mixin - for (int i = 0; i < subParameters.Length; i++) - { - subParameters[i].Set(Test1.SubParameters.param1, (i & 1) == 0); - } - subParam1.Set(Test1.SubParameters.param2, 2); - - mixin = GenerateMixin("DefaultComplexParams", properties); - mixin.CheckMixin("A", "B", "C", "C1", "C3"); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestParallelShaderMixer.cs b/sources/engine/Stride.Shaders.Tests/TestParallelShaderMixer.cs deleted file mode 100644 index 7349f56309..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestParallelShaderMixer.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; - -using Xunit; - -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Graphics; -using Stride.Shaders.Compiler; - -namespace Stride.Shaders.Tests -{ - public class TestParallelShaderMixer - { - private static EffectCompiler compiler; - - private static int NumThreads = 15; - - public static void Main3() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var assetIndexMap = ContentIndexMap.Load(VirtualFileSystem.ApplicationDatabaseIndexPath); - var databaseFileProvider = new DatabaseFileProvider(assetIndexMap, objDatabase); - - compiler = new EffectCompiler(databaseFileProvider); - compiler.SourceDirectories.Add("shaders"); - var shaderMixinSource = new ShaderMixinSource(); - shaderMixinSource.Mixins.Add(new ShaderClassSource("ShaderBase")); - shaderMixinSource.Mixins.Add(new ShaderClassSource("TransformationWVP")); - shaderMixinSource.Mixins.Add(new ShaderClassSource("ShadingBase")); - - var shaderMixinSource2 = new ShaderMixinSource(); - shaderMixinSource2.Mixins.Add(new ShaderClassSource("ShaderBase")); - shaderMixinSource2.Mixins.Add(new ShaderClassSource("TransformationWVP")); - shaderMixinSource2.Mixins.Add(new ShaderClassSource("ShadingBase")); - shaderMixinSource2.Mixins.Add(new ShaderClassSource("ShadingOverlay")); - - var allThreads = new List(); - - for (int i = 0; i < NumThreads; ++i) - { - CompilerThread compilerThread; - if (i % 2 == 0) - compilerThread = new CompilerThread(compiler, shaderMixinSource); - else - compilerThread = new CompilerThread(compiler, shaderMixinSource2); - allThreads.Add(new Thread(compilerThread.Compile)); - } - - foreach (var thread in allThreads) - { - thread.Start(); - } - } - - } - - public class CompilerThread - { - private volatile EffectCompiler effectCompiler; - - private volatile ShaderMixinSource mixinSource; - - public CompilerThread(EffectCompiler compiler, ShaderMixinSource source) - { - effectCompiler = compiler; - mixinSource = source; - } - - public void Compile() - { - Console.WriteLine(@"Inside Thread"); - - var parameters = new CompilerParameters(); - parameters.EffectParameters.Platform = GraphicsPlatform.Direct3D11; - parameters.EffectParameters.Profile = GraphicsProfile.Level_11_0; - - var mixinTree = new ShaderMixinSource() { Name = "TestParallelMix" }; - - var result = effectCompiler.Compile(mixinTree, parameters.EffectParameters, parameters).WaitForResult(); - - Assert.False(result.CompilationLog.HasErrors); - - Console.WriteLine(@"Thread end"); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestRealMix.cs b/sources/engine/Stride.Shaders.Tests/TestRealMix.cs deleted file mode 100644 index de2e63655e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestRealMix.cs +++ /dev/null @@ -1,251 +0,0 @@ -/* -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Xunit; - -using Stride.Rendering; -using Stride.Engine.Shaders.Mixins; -using Stride.Core.IO; -using Stride.Shaders.Compiler; -using Stride.Core.Shaders.Utility; - -namespace Stride.Core.Shaders.Tests -{ - class TestRealMix - { - private ShaderSourceManager sourceManager; - private ShaderLoader shaderLoader; - - [SetUp] - public void Init() - { - sourceManager = new ShaderSourceManager(); - sourceManager.LookupDirectoryList.Add(@"../../../../../shaders"); - shaderLoader = new ShaderLoader(sourceManager); - } - [Fact] - public void TestModule() // simple mix with inheritance - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("AlbedoDiffuseBase"), - new ShaderClassSource("AlbedoFlatShading"), - new ShaderClassSource("AlbedoSpecularBase"), - new ShaderClassSource("AmbientShading"), - new ShaderClassSource("BRDFDiffuseBase"), - new ShaderClassSource("BRDFSpecularBase"), - new ShaderClassSource("Camera"), - new ShaderClassSource("ColorBase"), - new ShaderClassSource("ComposeToneMap"), - new ShaderClassSource("ComputeBRDFColor"), - new ShaderClassSource("ComputeBRDFColorFresnel"), - new ShaderClassSource("ComputeBRDFColorSpecularBlinnPhong"), - new ShaderClassSource("ComputeBRDFDiffuseLambert"), - new ShaderClassSource("ComputeColor"), - new ShaderClassSource("ComputeColor3"), - new ShaderClassSource("ComputeColorAdd"), - new ShaderClassSource("ComputeColorAdd3"), - new ShaderClassSource("ComputeColorCave"), - new ShaderClassSource("ComputeColorFixed"), - new ShaderClassSource("ComputeColorLerpAlpha"), - new ShaderClassSource("ComputeColorMachoLifebar"), - new ShaderClassSource("ComputeColorMultiply"), - new ShaderClassSource("ComputeColorOutdoor"), - new ShaderClassSource("ComputeColorOverlay"), - new ShaderClassSource("ComputeColorScaler"), - new ShaderClassSource("ComputeColorStream"), - new ShaderClassSource("ComputeColorSubstituteAlpha"), - new ShaderClassSource("ComputeColorSynthetic"), - new ShaderClassSource("ComputeColorTexture"), - new ShaderClassSource("ComputeColorTextureDisplacement"), - new ShaderClassSource("ComputeColorTextureRepeat"), - new ShaderClassSource("ComputeColorTextureRepeatMacho"), - new ShaderClassSource("ComputeFloat"), - new ShaderClassSource("ComputeMagmaNormals"), - new ShaderClassSource("ComputeShaderBase"), - new ShaderClassSource("ComputeSkyboxColor"), - new ShaderClassSource("ComputeSkyboxDomeColorTexture"), - new ShaderClassSource("ComputeSkyboxGroundColorTexture"), - new ShaderClassSource("ComputeToneMap"), - new ShaderClassSource("DepthBase"), - new ShaderClassSource("DiscardTransparent"), - new ShaderClassSource("EditorIcon"), - new ShaderClassSource("GBuffer"), - new ShaderClassSource("GBufferBase"), - new ShaderClassSource("Global"), - new ShaderClassSource("LightDeferredShading"), - new ShaderClassSource("LightDirectionalBase"), - new ShaderClassSource("LightDirectionalComputeColor"), - new ShaderClassSource("LightDirectionalShading"), - new ShaderClassSource("LightDirectionalShadingTerrain"), - new ShaderClassSource("LightMultiDirectionalShadingDiffusePerPixel"), - new ShaderClassSource("LightMultiDirectionalShadingPerPixel"), - new ShaderClassSource("LightMultiDirectionalShadingPerVertex"), - new ShaderClassSource("LightMultiDirectionalShadingSpecularPerPixel"), - new ShaderClassSource("LightPrepass"), - new ShaderClassSource("LightPrepassDebug"), - new ShaderClassSource("LightShadingBase"), - new ShaderClassSource("Material"), - new ShaderClassSource("MinMaxBounding"), - new ShaderClassSource("Noise2dBase"), - new ShaderClassSource("Noise3dBase"), - new ShaderClassSource("Noise4dBase"), - new ShaderClassSource("NoiseBase"), - new ShaderClassSource("NormalMapTexture"), - new ShaderClassSource("NormalPack"), - new ShaderClassSource("NormalSkinning"), - new ShaderClassSource("NormalStream"), - new ShaderClassSource("NormalBase"), - new ShaderClassSource("NormalVSGBuffer"), - new ShaderClassSource("NormalVSStream"), - new ShaderClassSource("Particle"), - new ShaderClassSource("ParticleBase"), - new ShaderClassSource("ParticleBillboard"), - new ShaderClassSource("ParticleBitonicSort1", 0), - new ShaderClassSource("ParticleBitonicSort2", 1), - new ShaderClassSource("ParticleRenderBase"), - new ShaderClassSource("ParticleRenderTest1"), - new ShaderClassSource("ParticleSimpleDataBase"), - new ShaderClassSource("ParticleSortInitializer"), - new ShaderClassSource("ParticleUpdaterBase", 0), - - new ShaderClassSource("ParticleUpdaterTest1"), - new ShaderClassSource("PickingGBuffer"), - new ShaderClassSource("PickingGS"), - new ShaderClassSource("PickingRasterizer"), - new ShaderClassSource("PositionHStream4"), - new ShaderClassSource("PositionStream"), - new ShaderClassSource("PositionStream2"), - new ShaderClassSource("PositionStream4"), - new ShaderClassSource("PositionVSBase"), - new ShaderClassSource("PositionVSGBuffer"), - new ShaderClassSource("PositionVertexTransform"), - new ShaderClassSource("PostEffectBase"), - new ShaderClassSource("PostEffectBilateralGaussian"), - new ShaderClassSource("PostEffectBlur"), - new ShaderClassSource("PostEffectBlur5x5"), - new ShaderClassSource("PostEffectBlurHVsm"), - new ShaderClassSource("PostEffectBoundingRay"), - new ShaderClassSource("PostEffectBrightFilter"), - new ShaderClassSource("PostEffectBrightPass"), - new ShaderClassSource("PostEffectFXAA"), - new ShaderClassSource("PostEffectHBAO"), - new ShaderClassSource("PostEffectHBAOBlur"), - new ShaderClassSource("PostEffectHeatShimmer"), - new ShaderClassSource("PostEffectHeatShimmerDisplay"), - new ShaderClassSource("PostEffectLightShafts"), - new ShaderClassSource("PostEffectLightShaftsNoise"), - new ShaderClassSource("PostEffectMinMax"), - new ShaderClassSource("PostEffectTexturing"), - new ShaderClassSource("PostEffectTexturing2"), - new ShaderClassSource("PostEffectTransition"), - new ShaderClassSource("ShaderBase"), - new ShaderClassSource("ShaderBaseTessellation"), - new ShaderClassSource("ShadingBase"), - new ShaderClassSource("ShadingColor"), - new ShaderClassSource("ShadingOverlay"), - new ShaderClassSource("ShadowBase"), - new ShaderClassSource("ShadowMap"), - new ShaderClassSource("ShadowMapBase"), - new ShaderClassSource("ShadowMapCascadeBase"), - new ShaderClassSource("ShadowMapCasterBase"), - new ShaderClassSource("ShadowMapColor"), - new ShaderClassSource("ShadowMapFilterBase"), - new ShaderClassSource("ShadowMapFilterDefault"), - new ShaderClassSource("ShadowMapFilterPcf"), - new ShaderClassSource("ShadowMapFilterVsm"), - new ShaderClassSource("ShadowMapReceiver"), - new ShaderClassSource("ShadowMapUtils"), - new ShaderClassSource("SimplexNoise"), - new ShaderClassSource("SkyBox"), - new ShaderClassSource("SkyBoxDomeDragon"), - new ShaderClassSource("SpecularPowerBase"), - new ShaderClassSource("SpecularPowerGBuffer"), - new ShaderClassSource("SpecularPowerPerMesh"), - new ShaderClassSource("SwapUV"), - new ShaderClassSource("TangentSkinning"), - new ShaderClassSource("TessellationAEN"), - new ShaderClassSource("TessellationDisplacement"), - //new ShaderClassSource("TessellationDisplacementAEN"), - new ShaderClassSource("TessellationFlat"), - new ShaderClassSource("TessellationPN"), - new ShaderClassSource("TextureKey"), - new ShaderClassSource("TextureStream"), - new ShaderClassSource("Texturing"), - new ShaderClassSource("Transformation"), - new ShaderClassSource("TransformationBase"), - new ShaderClassSource("TransformationSkinning"), - new ShaderClassSource("TransformationWVP"), - new ShaderClassSource("TransformationZero"), - new ShaderClassSource("TransparentShading"), - new ShaderClassSource("TurbulenceDynamicNoise"), - new ShaderClassSource("TurbulenceNoiseBase"), - new ShaderClassSource("Utilities"), - new ShaderClassSource("Wireframe") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - if (mcm.ErrorWarningLog.HasErrors) - { - Console.WriteLine("----------------------------ERRORS FOUND-----------------------------------"); - foreach (var message in mcm.ErrorWarningLog.Messages.Where(x => x.Level == ReportMessageLevel.Error)) - Console.WriteLine(message); - Console.WriteLine("-----------------------------ERRORS END------------------------------------"); - - Console.WriteLine("----------------------------WARNINGS FOUND-----------------------------------"); - foreach (var message in mcm.ErrorWarningLog.Messages.Where(x => x.Level == ReportMessageLevel.Warning)) - Console.WriteLine(message); - Console.WriteLine("-----------------------------WARNINGS END------------------------------------"); - } - - Assert.False(mcm.ErrorWarningLog.HasErrors); - } - - [Fact] - public void TestModuleShort() // simple mix with inheritance - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("TessellationDisplacement", 100, 8), - new ShaderClassSource("ShaderBaseTessellation"), - new ShaderClassSource("TessellationFlat"), - new ShaderClassSource("ShaderBase"), - new ShaderClassSource("Texturing"), - new ShaderClassSource("NormalBase"), - new ShaderClassSource("NormalVSStream"), - new ShaderClassSource("NormalStream"), - new ShaderClassSource("ComputeColor"), - new ShaderClassSource("PositionVertexTransform"), - new ShaderClassSource("Transformation"), - new ShaderClassSource("TransformationBase"), - new ShaderClassSource("PositionVSBase"), - new ShaderClassSource("PositionStream"), - new ShaderClassSource("PositionStream4"), - new ShaderClassSource("Camera"), - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - if (mcm.ErrorWarningLog.HasErrors) - { - Console.WriteLine("----------------------------ERRORS FOUND-----------------------------------"); - foreach (var message in mcm.ErrorWarningLog.Messages.Where(x => x.Level == ReportMessageLevel.Error)) - Console.WriteLine(message); - Console.WriteLine("-----------------------------ERRORS END------------------------------------"); - - Console.WriteLine("----------------------------WARNINGS FOUND-----------------------------------"); - foreach (var message in mcm.ErrorWarningLog.Messages.Where(x => x.Level == ReportMessageLevel.Warning)) - Console.WriteLine(message); - Console.WriteLine("-----------------------------WARNINGS END------------------------------------"); - } - - Assert.False(mcm.ErrorWarningLog.HasErrors); - } - } -} -*/ \ No newline at end of file diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderLoading.cs b/sources/engine/Stride.Shaders.Tests/TestShaderLoading.cs deleted file mode 100644 index 688e7072a2..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderLoading.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.IO; - -using Xunit; - -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Games; -using Stride.Shaders.Parser.Mixins; - -using LoggerResult = Stride.Core.Shaders.Utility.LoggerResult; - -namespace Stride.Shaders.Tests -{ - public class TestShaderLoading - { - private ShaderSourceManager sourceManager; - private ShaderLoader shaderLoader; - - public TestShaderLoading() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - sourceManager = new ShaderSourceManager(databaseFileProvider); - sourceManager.LookupDirectoryList.Add(@"shaders"); - shaderLoader = new ShaderLoader(sourceManager); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestSimple() - { - var simple = sourceManager.LoadShaderSource("Simple"); - - // Make sure that SourceManager will fail if type is not found - Assert.Throws(() => sourceManager.LoadShaderSource("BiduleNotFound")); - - // Reload it and check that it is not loaded twice - var simple2 = sourceManager.LoadShaderSource("Simple"); - - //TODO: cannot compare structure references - //Assert.That(ReferenceEquals(simple, simple2), Is.True); - Assert.Equal(simple, simple2); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestLoadAst() - { - var log = new LoggerResult(); - - var simple = shaderLoader.LoadClassSource(new ShaderClassSource("Simple"), new Stride.Core.Shaders.Parser.ShaderMacro[0], log, false)?.Type; - - Assert.Single(simple.Members); - - var simple2 = shaderLoader.LoadClassSource(new ShaderClassSource("Simple"), new Stride.Core.Shaders.Parser.ShaderMacro[0], log, false)?.Type; - - // Make sure that a class is not duplicated in memory - Assert.True(ReferenceEquals(simple, simple2)); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderLoadingString.cs b/sources/engine/Stride.Shaders.Tests/TestShaderLoadingString.cs deleted file mode 100644 index 8b0e152c53..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderLoadingString.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.IO; - -using Xunit; - -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Core.Mathematics; -using Stride.Games; -using Stride.Shaders.Parser.Mixins; - -using LoggerResult = Stride.Core.Shaders.Utility.LoggerResult; - -namespace Stride.Shaders.Tests -{ - public class TestShaderLoadingString - { - private ShaderSourceManager sourceManager; - private ShaderLoader shaderLoader; - - - const string ShaderSourceName = "ConstantCol"; - const string ShaderSourceCode = -@"shader ConstantCol : TestComputeColor -{ - override float4 Compute() - { - return Value; - } -};"; - - public TestShaderLoadingString() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - sourceManager = new ShaderSourceManager(databaseFileProvider); - sourceManager.LookupDirectoryList.Add(@"shaders"); - shaderLoader = new ShaderLoader(sourceManager); - } - - [Fact] - public void TestSimple() - { - var simple = sourceManager.LoadShaderSource(ShaderSourceName, ShaderSourceCode); - - // Make sure that SourceManager will fail if type is not found - Assert.Throws(() => sourceManager.LoadShaderSource("BiduleNotFound")); - - // Reload it and check that it is not loaded twice - var simple2 = sourceManager.LoadShaderSource(ShaderSourceName, ShaderSourceCode); - - //TODO: cannot compare structure references - //Assert.That(ReferenceEquals(simple, simple2), Is.True); - Assert.Equal(simple, simple2); - } - - [Fact] - public void TestLoadAst() - { - var log = new LoggerResult(); - - var shaderClassString = new ShaderClassString(ShaderSourceName, ShaderSourceCode, new Vector4(1, 1, 1, 1)); - - var simple = shaderLoader.LoadClassSource(shaderClassString, new Stride.Core.Shaders.Parser.ShaderMacro[0], log, false)?.Type; - - Assert.Equal(2, simple.Members.Count); - - var shaderClassString2 = new ShaderClassString(ShaderSourceName, ShaderSourceCode, new Vector4(1, 1, 1, 1)); - - var simple2 = shaderLoader.LoadClassSource(shaderClassString2, new Stride.Core.Shaders.Parser.ShaderMacro[0], log, false)?.Type; - - // Make sure that a class is not duplicated in memory - Assert.True(ReferenceEquals(simple, simple2)); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderMixer.cs b/sources/engine/Stride.Shaders.Tests/TestShaderMixer.cs deleted file mode 100644 index a0eb18e550..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderMixer.cs +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -/* -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -using Xunit; - -using Stride.Rendering; -using Stride.Engine.Shaders.Mixins; -using Stride.Core.IO; -using Stride.Shaders.Compiler; -using Stride.Core.Shaders.Ast; - -namespace Stride.Core.Shaders.Tests -{ - public class TestShaderMixer - { - private ShaderSourceManager sourceManager; - private ShaderLoader shaderLoader; - - public TestShaderMixer() - { - sourceManager = new ShaderSourceManager(); - sourceManager.LookupDirectoryList.Add(@"..\..\Shaders"); - shaderLoader = new ShaderLoader(sourceManager); - } - - [Fact] - public void TestRenameBasic() // simple mix with inheritance - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("Parent"), - new ShaderClassSource("Child") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixer = new StrideShaderMixer(mcm.Mixins["Child"], mcm.Mixins, null); - mixer.Mix(); - - //var childMixinInfo = mcm.Mixins["Child"].ParsingInfo; - //Assert.Equal("Child_AddBaseValue", childMixinInfo.MethodDeclarations.First().Name.Text); - //Assert.Equal("Parent_AddBaseValue", (childMixinInfo.BaseMethodCalls.First().Target as VariableReferenceExpression).Name.Text); - //Assert.Equal("Parent_baseValue", childMixinInfo.VariableReferenceExpressions[0].Name.Text); - } - - [Fact] - public void TestRenameStatic() // mix with call to a static method - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StaticMixin"), - new ShaderClassSource("StaticCallMixin") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixer = new StrideShaderMixer(mcm.Mixins["StaticCallMixin"], mcm.Mixins, null); - mixer.Mix(); - - //var staticCallMixinInfo = mcm.Mixins["StaticCallMixin"].ParsingInfo; - //Assert.Equal("StaticMixin_staticCall", (staticCallMixinInfo.MethodCalls.First().Target as VariableReferenceExpression).Name.Text); - //Assert.Equal("StaticMixin_staticMember", ((staticCallMixinInfo.StaticMemberReferences.First().Node as UnaryExpression).Expression as VariableReferenceExpression).Name.Text); - } - - [Fact] - public void TestBasicExternMix() // mix with an extern class - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ExternMixin"), - new ShaderClassSource("ExternTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var externDictionary = new Dictionary>(); - externDictionary.Add(mcmFinal.Mixins["ExternTest"].VariableDependencies.First().Key, new List{ mcm.Mixins["ExternMixin"].DeepClone() }); - - var mixer = new StrideShaderMixer(mcmFinal.Mixins["ExternTest"], mcmFinal.Mixins, externDictionary); - mixer.Mix(); - - //var externTestMixinInfo = mcmFinal.Mixins["ExternTest"].ParsingInfo; - //Assert.Equal("ExternTest_myExtern_ExternMixin_externFunc", (externTestMixinInfo.ExternMethodCalls.First().MethodInvocation.Target as VariableReferenceExpression).Name.Text); - //Assert.Equal("ExternTest_myExtern_ExternMixin_externMember", ((externTestMixinInfo.ExternMemberReferences.First().Node as ReturnStatement).Value as VariableReferenceExpression).Name.Text); - } - - [Fact] - public void TestDeepMix() // mix with multiple levels of extern classes - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ExternMixin"), - new ShaderClassSource("DeepExtern"), - new ShaderClassSource("DeepExternTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var depext = mcm.Mixins["DeepExtern"].DeepClone(); - var deepDictionary = new Dictionary>(); - deepDictionary.Add(mcmFinal.Mixins["DeepExternTest"].VariableDependencies.First().Key, new List { depext }); - deepDictionary.Add(depext.VariableDependencies.First().Key, new List { mcm.Mixins["ExternMixin"].DeepClone() }); - var mixer = new StrideShaderMixer(mcmFinal.Mixins["DeepExternTest"], mcmFinal.Mixins, deepDictionary); - mixer.Mix(); - - //var externDeepTest = mcmFinal.Mixins["DeepExternTest"].ParsingInfo; - //Assert.Equal("DeepExternTest_myExtern_DeepExtern_myExtern_ExternMixin_externFunc", (externDeepTest.ExternMethodCalls.First().MethodInvocation.Target as VariableReferenceExpression).Name.Text); - //Assert.Equal("DeepExternTest_myExtern_DeepExtern_myExtern_ExternMixin_externMember", ((externDeepTest.ExternMemberReferences.First().Node as ReturnStatement).Value as VariableReferenceExpression).Name.Text); - } - - [Fact] - public void TestMultipleStatic() // check that static calls only written once - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StaticMixin"), - new ShaderClassSource("StaticCallMixin"), - new ShaderClassSource("TestMultipleStatic"), - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var extDictionary = new Dictionary>(); - extDictionary.Add(mcmFinal.Mixins["TestMultipleStatic"].VariableDependencies.First().Key, new List{ mcm.Mixins["StaticCallMixin"].DeepClone() }); - var mixer = new StrideShaderMixer(mcmFinal.Mixins["TestMultipleStatic"], mcmFinal.Mixins, extDictionary); - mixer.Mix(); - - //Assert.Equal(1, mixer.MixedShader.Members.OfType().Count(x => x.Name.Text == "StaticMixin_staticCall")); - //Assert.Equal(1, mixer.MixedShader.Members.OfType().Count(x => x.Name.Text == "StaticMixin_staticMember")); - } - - [Fact] - public void TestStageCall() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StageBase"), - new ShaderClassSource("StageCallExtern"), - new ShaderClassSource("StaticStageCallTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var extDictionary = new Dictionary>(); - extDictionary.Add(mcmFinal.Mixins["StaticStageCallTest"].VariableDependencies.First().Key, new List{mcm.Mixins["StageCallExtern"].DeepClone()}); - var mixer = new StrideShaderMixer(mcmFinal.Mixins["StaticStageCallTest"], mcmFinal.Mixins, extDictionary); - mixer.Mix(); - - //var extPI = mcmExtern.Mixins["StageCallExtern"].ParsingInfo; - //var finalPI = mcmFinal.Mixins["StaticStageCallTest"].ParsingInfo; - - //Assert.Equal(1, extPI.StageMethodCalls.Count); - //Assert.Equal(1, finalPI.MethodDeclarations.Count); - //Assert.Equal(finalPI.MethodDeclarations[0], extPI.StageMethodCalls[0].Target.TypeInference.Declaration); - //Assert.Equal(finalPI.MethodDeclarations[0].Name.Text, (extPI.StageMethodCalls[0].Target as VariableReferenceExpression).Name.Text); - - //Assert.Equal(1, extPI.VariableReferenceExpressions.Count); - //Assert.Equal(2, finalPI.Variables.Count); - //Assert.Equal(finalPI.Variables[1], extPI.VariableReferenceExpressions[0].TypeInference.Declaration); - //Assert.Equal(finalPI.Variables[1].Name.Text, extPI.VariableReferenceExpressions[0].TypeInference.Declaration.Name.Text); - } - - [Fact] - public void TestMergeSemantics() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("SemanticTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixer = new StrideShaderMixer(mcm.Mixins["SemanticTest"], mcm.Mixins, null); - mixer.Mix(); - - //Assert.Equal(1, mixer.MixedShader.Members.OfType().Count()); - } - - [Fact] - public void TestStreams() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StreamTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixer = new StrideShaderMixer(mcm.Mixins["StreamTest"], mcm.Mixins, null); - mixer.Mix(); - } - - [Fact] - public void TestStageAssignement() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StageValueReference"), - new ShaderClassSource("StageValueTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var extDictionary = new Dictionary>(); - extDictionary.Add(mcmFinal.Mixins["StageValueTest"].VariableDependencies.First().Key, new List{ mcm.Mixins["StageValueReference"].DeepClone() }); - var mixerFinal = new StrideShaderMixer(mcmFinal.Mixins["StageValueTest"], mcmFinal.Mixins, extDictionary); - mixerFinal.Mix(); - } - - [Fact] - public void TestClone() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("CloneTestBase"), - new ShaderClassSource("CloneTestRoot"), - new ShaderClassSource("CloneTestExtern") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var extDictionary = new Dictionary>(); - var keys = mcmFinal.Mixins["CloneTestRoot"].VariableDependencies.Keys.ToList(); - extDictionary.Add(keys[0], new List{ mcm.Mixins["CloneTestExtern"].DeepClone() }); - extDictionary.Add(keys[1], new List{ mcm.Mixins["CloneTestExtern"].DeepClone() }); - var mixerFinal = new StrideShaderMixer(mcmFinal.Mixins["CloneTestRoot"], mcmFinal.Mixins, extDictionary); - mixerFinal.Mix(); - } - - [Fact] - public void TestBaseThis() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("BaseTestChild"), - new ShaderClassSource("BaseTestInter"), - new ShaderClassSource("BaseTestParent") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixerFinal = new StrideShaderMixer(mcm.Mixins["BaseTestChild"], mcm.Mixins, null); - mixerFinal.Mix(); - } - - [Fact] - public void TestForEachStatementExpand() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ForEachTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixerFinal = new StrideShaderMixer(mcm.Mixins["ForEachTest"], mcm.Mixins, null); - mixerFinal.Mix(); - } - - [Fact] - public void TestStreamSolver() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StreamChild"), - new ShaderClassSource("StreamParent0"), - new ShaderClassSource("StreamParent1") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixerFinal = new StrideShaderMixer(mcm.Mixins["StreamChild"], mcm.Mixins, null); - mixerFinal.Mix(); - } - - [Fact] - public void TestNonStageStream() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("NonStageStreamTest"), - new ShaderClassSource("StreamParent2"), - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - var extDictionary = new Dictionary>(); - var keys = mcmFinal.Mixins["NonStageStreamTest"].VariableDependencies.Keys.ToList(); - extDictionary.Add(keys[0], new List { mcm.Mixins["StreamParent2"].DeepClone() }); - extDictionary.Add(keys[1], new List { mcm.Mixins["StreamParent2"].DeepClone() }); - var mixerFinal = new StrideShaderMixer(mcmFinal.Mixins["NonStageStreamTest"], mcmFinal.Mixins, extDictionary); - mixerFinal.Mix(); - } - - [Fact] - public void TestStreamSolverExtern() - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("StreamChild"), - new ShaderClassSource("StreamParent0"), - new ShaderClassSource("StreamParent1"), - new ShaderClassSource("StreamSolverExternTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - - var extDictionary = new Dictionary>(); - extDictionary.Add(mcmFinal.Mixins["StreamSolverExternTest"].VariableDependencies.First().Key, new List{ mcm.Mixins["StreamChild"].DeepClone() }); - var mixerFinal = new StrideShaderMixer(mcmFinal.Mixins["StreamSolverExternTest"], mcmFinal.Mixins, extDictionary); - mixerFinal.Mix(); - } - - [Fact] - public void TestExternArray() // check behavior with a array of compositions - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ExternMixin"), - new ShaderClassSource("TestExternArray") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mcmFinal = mcm.DeepClone(); - - var extDictionary = new Dictionary>(); - var mixins = new List { mcm.Mixins["ExternMixin"].DeepClone(), mcm.Mixins["ExternMixin"].DeepClone() }; - extDictionary.Add(mcmFinal.Mixins["TestExternArray"].VariableDependencies.First().Key, mixins); - var mixerFinal = new StrideShaderMixer(mcmFinal.Mixins["TestExternArray"], mcmFinal.Mixins, extDictionary); - mixerFinal.Mix(); - } - - [Fact] - public void TestConstantBuffer() // check behavior with a array of compositions - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ConstantBufferTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixerFinal = new StrideShaderMixer(mcm.Mixins["ConstantBufferTest"], mcm.Mixins, null); - mixerFinal.Mix(); - } - - [Fact] - public void TestComputeShader() // check behavior with a array of compositions - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("TestComputeShader") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - var mixerFinal = new StrideShaderMixer(mcm.Mixins["TestComputeShader"], mcm.Mixins, null); - mixerFinal.Mix(); - } - } -} -*/ diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderMixer2.cs b/sources/engine/Stride.Shaders.Tests/TestShaderMixer2.cs deleted file mode 100644 index 6453411ce0..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderMixer2.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Xunit; - -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Serialization.Contents; -using Stride.Core.Storage; -using Stride.Graphics; -using Stride.Shaders.Compiler; - -namespace Stride.Shaders.Tests -{ - public class TestShaderMixer2 - { - public EffectCompiler Compiler; - - public LoggerResult ResultLogger; - - public CompilerParameters MixinParameters; - - private void Init() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - Compiler = new EffectCompiler(databaseFileProvider); - Compiler.SourceDirectories.Add("shaders"); - MixinParameters = new CompilerParameters(); - MixinParameters.EffectParameters.Platform = GraphicsPlatform.Direct3D11; - MixinParameters.EffectParameters.Profile = GraphicsProfile.Level_11_0; - ResultLogger = new LoggerResult(); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestRenaming() - { - Init(); - - var color1Mixin = new ShaderClassSource("ComputeColorFixed", "Material.DiffuseColorValue"); - var color2Mixin = new ShaderClassSource("ComputeColorFixed", "Material.SpecularColorValue"); - - var compMixin = new ShaderMixinSource(); - compMixin.Mixins.Add(new ShaderClassSource("ComputeColorMultiply")); - compMixin.AddComposition("color1", color1Mixin); - compMixin.AddComposition("color2", color2Mixin); - - var mixinSource = new ShaderMixinSource { Name = "testRenaming" }; - mixinSource.Mixins.Add(new ShaderClassSource("ShadingBase")); - mixinSource.Mixins.Add(new ShaderClassSource("AlbedoFlatShading")); - mixinSource.AddComposition("albedoDiffuse", compMixin); - - var bytecode = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - Assert.NotEqual(default, bytecode); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestRenaming2() - { - Init(); - - var color1Mixin = new ShaderMixinSource(); - color1Mixin.Mixins.Add(new ShaderClassSource("ComputeColorFixed", "Material.DiffuseColorValue")); - var color2Mixin = new ShaderMixinSource(); - color2Mixin.Mixins.Add(new ShaderClassSource("ComputeColorFixed", "Material.SpecularColorValue")); - - var compMixin = new ShaderMixinSource(); - compMixin.Mixins.Add(new ShaderClassSource("ComputeColorMultiply")); - compMixin.AddComposition("color1", color1Mixin); - compMixin.AddComposition("color2", color2Mixin); - - var mixinSource = new ShaderMixinSource { Name = "TestRenaming2" }; - mixinSource.Mixins.Add(new ShaderClassSource("ShadingBase")); - mixinSource.Mixins.Add(new ShaderClassSource("AlbedoFlatShading")); - mixinSource.AddComposition("albedoDiffuse", compMixin); - - var bytecode = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - Assert.NotEqual(default, bytecode); - } - - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestRenamingBoth() - { - Init(); - - TestRenaming(); - TestRenaming2(); - } - [Fact(Skip = "This test fixture is unmaintained and currently doesn't pass")] - public void TestRenamingBothInverse() - { - Init(); - - TestRenaming2(); - TestRenaming(); - } - - internal static void Main4() - { - var testClass = new TestShaderMixer2(); - testClass.Init(); - testClass.TestRenaming(); - testClass.TestRenaming2(); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderParsing.cs b/sources/engine/Stride.Shaders.Tests/TestShaderParsing.cs deleted file mode 100644 index f4671dd8fa..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderParsing.cs +++ /dev/null @@ -1,609 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Linq; -using Xunit; - -using Stride.Core.IO; -using Stride.Core.Serialization.Assets; -using Stride.Core.Storage; -using Stride.Shaders; -using Stride.Shaders.Parser; -using Stride.Shaders.Parser.Ast; -using Stride.Shaders.Parser.Mixins; - -namespace Stride.Engine.Tests -{ - class TestShaderParsing - { - private ShaderSourceManager sourceManager; - private ShaderLoader shaderLoader; - private ShaderMixinParser shaderMixinParser; - - [SetUp] - public void Init() - { - // Create and mount database file system - var objDatabase = new ObjectDatabase("/data/db", "index", "/local/db"); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - AssetManager.GetFileProvider = () => databaseFileProvider; - - sourceManager = new ShaderSourceManager(); - sourceManager.LookupDirectoryList.Add(@"shaders"); - shaderLoader = new ShaderLoader(sourceManager); - shaderMixinParser = new ShaderMixinParser(AssetManager.FileProvider); - shaderMixinParser.SourceManager.LookupDirectoryList.Add(@"shaders"); - } - - [Fact] - public void TestSimpleRead() // check that the list is correctly filled - { - var moduleMixin = GetAnalyzedMixin("BasicMixin"); - var mixin = moduleMixin.Mixin; - - Assert.Equal(1, mixin.ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Stage))); - Assert.Equal(1, mixin.ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Stream))); - Assert.Equal(3, mixin.ParsingInfo.ClassReferences.VariablesReferences.Count); - Assert.Equal(0, mixin.ParsingInfo.ClassReferences.MethodsReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Clone))); - Assert.Equal(0, mixin.BaseMixins.Count); - Assert.Equal(1, mixin.ParsingInfo.ClassReferences.MethodsReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Stage))); - Assert.Equal(3, mixin.ParsingInfo.ClassReferences.MethodsReferences.Count); - } - - [Fact] - public void TestInternalReference() // check that the list is correctly filled - { - var moduleMixin = GetAnalyzedMixin("Parent"); - var mixin = moduleMixin.Mixin; - Assert.IsNotNull(mixin); - - Assert.Equal(2, mixin.ParsingInfo.ClassReferences.VariablesReferences.Count); - Assert.Equal(1, mixin.ParsingInfo.ClassReferences.MethodsReferences.Count); - //Assert.Equal(mixin.ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(), mixin.ParsingInfo.VariableReferenceExpressions.FirstOrDefault(x => x.Name.Text == "baseValue").TypeInference.Declaration); - } - - [Fact] - public void TestInheritance() // check that the base call is correct - { - var moduleMixinChild = GetAnalyzedMixin("Child"); - var mixinChild = moduleMixinChild.Mixin; - - Assert.Equal(1, mixinChild.BaseMixins.Count); - - var varDecl = GetAnalyzedMixin("Parent").Mixin.ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(); - Assert.Equal(1, mixinChild.ParsingInfo.ClassReferences.VariablesReferences.Where(x => x.Key == varDecl).Select(x => x.Value).Count()); - } - - [Fact] - public void TestNameConflictSolved() // check that infered declaration are correct - { - var moduleMixinBase1 = GetAnalyzedMixin("BasicMixin"); - var moduleMixinBase2 = GetAnalyzedMixin("BasicMixin2"); - var moduleMixinSolved = GetAnalyzedMixin("MixinNoNameClash"); - - var def1 = moduleMixinBase1.Mixin.VirtualTable.Variables.FirstOrDefault(x => x.Variable.Name == "myFloat").Variable; - var def2 = moduleMixinBase2.Mixin.VirtualTable.Variables.FirstOrDefault(x => x.Variable.Name == "myFloat").Variable; - - Assert.Equal(1, moduleMixinSolved.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Where(x => x.Key == def1).Select(x => x.Value).Count()); - Assert.Equal(1, moduleMixinSolved.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Where(x => x.Key == def2).Select(x => x.Value).Count()); - } - - [Fact] - public void TestBaseLink() // check that infered declaration are correct - { - // TODO: redo this test - var moduleMixinChild = GetAnalyzedMixin("BaseTestChild"); - var moduleMixinInter = GetAnalyzedMixin("BaseTestInter"); - var moduleMixinParent = GetAnalyzedMixin("BaseTestParent"); - - Assert.Equal(2, moduleMixinParent.Mixin.LocalVirtualTable.Methods.Count); - var baseMethod1Def = moduleMixinParent.Mixin.LocalVirtualTable.Methods.ToList()[0].Method; - var baseMethod2Def = moduleMixinParent.Mixin.LocalVirtualTable.Methods.ToList()[1].Method; - - Assert.Equal(1, moduleMixinInter.Mixin.LocalVirtualTable.Methods.Count); - var overrideMethod1Def = moduleMixinInter.Mixin.LocalVirtualTable.Methods.ToList()[0].Method; - - Assert.Equal(2, moduleMixinChild.Mixin.LocalVirtualTable.Methods.Count); - var overrideFinalMethod1Def = moduleMixinChild.Mixin.LocalVirtualTable.Methods.ToList()[0].Method; - var overrideFinalMethod2Def = moduleMixinChild.Mixin.LocalVirtualTable.Methods.ToList()[0].Method; - - Assert.Equal(1, moduleMixinInter.Mixin.ParsingInfo.BaseMethodCalls.Count); - var baseOverrideMethod1Call = moduleMixinInter.Mixin.ParsingInfo.BaseMethodCalls.First(); - Assert.Equal(baseMethod1Def, baseOverrideMethod1Call.TypeInference.Declaration); - - Assert.Equal(3, moduleMixinInter.Mixin.ParsingInfo.ClassReferences.MethodsReferences.Select(x => x.Key).Count()); - Assert.Equal(1, moduleMixinInter.Mixin.ParsingInfo.ThisMethodCalls.Count); - - Assert.Equal(2, moduleMixinChild.Mixin.ParsingInfo.BaseMethodCalls.Count); - var baseFinalMethod1Call = moduleMixinChild.Mixin.ParsingInfo.BaseMethodCalls.ToList()[0]; - var baseFinalMethod2Call = moduleMixinChild.Mixin.ParsingInfo.BaseMethodCalls.ToList()[1]; - //Assert.Equal(overrideMethod1Def, baseFinalMethod1Call.TypeInference.Declaration); - //Assert.Equal(baseMethod2Def, baseFinalMethod2Call.TypeInference.Declaration); - - Assert.Equal(1, moduleMixinChild.Mixin.ParsingInfo.ThisMethodCalls.Count); - } - - /*[Fact] - public void TestExtern() // check type inference of the extern method call - { - var moduleMixin = GetAnalyzedMixin("ExternMixin"); - var moduleMixinTest = GetAnalyzedMixin("ExternTest"); - - Assert.IsNotNull(moduleMixin.Mixin); - Assert.IsNotNull(moduleMixinTest.Mixin); - - Assert.Equal(1, moduleMixinTest.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Extern))); - var externVar = moduleMixinTest.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(); - - var externDef = moduleMixin.Mixin.Shader; - var externMethodDef = externDef.Members.OfType().FirstOrDefault(); - var externVariableDef = externDef.Members.OfType().FirstOrDefault(); - - Assert.Equal(1, moduleMixinTest.Mixin.ParsingInfo.ExternReferences.MethodsReferences.Select(x => x.Key).Count()); - //Assert.Equal(externVar, moduleMixinTest.Mixin.ParsingInfo.ExternReferences.VariablesReferences.FirstOrDefault().Key); - - Assert.Equal(1, moduleMixinTest.Mixin.ParsingInfo.ExternReferences.VariablesReferences.Count); - Assert.Equal(1, moduleMixinTest.Mixin.ParsingInfo.ExternReferences.MethodsReferences.Count); - Assert.True(moduleMixinTest.Mixin.ParsingInfo.ExternReferences.VariablesReferences.All(x => x.Key == externVar)); - - Assert.Equal(1,moduleMixinTest.Mixin.ParsingInfo.ExternReferences.VariablesReferences.Select(x => x.Key).Count()); - Assert.Equal(externVariableDef, moduleMixinTest.Mixin.ParsingInfo.ExternReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault()); - }*/ - /* - [Fact] - public void TestDeepExtern() // check type inference of the deep extern method call - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("ExternMixin"), - new ShaderClassSource("DeepExtern"), - new ShaderClassSource("DeepExternTest") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - Assert.Equal(2, mcm.Mixins["DeepExternTest"].ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Extern))); - var externVar = mcm.Mixins["DeepExternTest"].ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(); - - Assert.Equal(1, mcm.Mixins["DeepExtern"].ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.Extern))); - var externVar2 = mcm.Mixins["DeepExtern"].ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(); - - var externDef = mcm.Mixins["ExternMixin"].Shader; - var externMethodDef = externDef.Members.OfType().FirstOrDefault(); - var externVariableDef = externDef.Members.OfType().FirstOrDefault(); - - Assert.Equal(1, mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferences.MethodsReferences.Select(x => x.Key).Count()); - Assert.Equal(externMethodDef, mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferences.MethodsReferences.Select(x => x.Key).FirstOrDefault()); - - //Assert.Equal(2, mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferenceExpressions.Count); - //Assert.True(mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferenceExpressions.All(x => x.TypeInference.Declaration == externVar)); - - Assert.Equal(1, mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferences.VariablesReferences.Select(x => x.Key).Count()); - Assert.Equal(externVariableDef, mcm.Mixins["DeepExternTest"].ParsingInfo.ExternReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault()); - } - [Fact] - public void TestExternArray() // check behavior with a array of compositions - { - var moduleMixin = GetAnalyzedMixin("TestExternArray"); - } - */ - [Fact] - public void TestStaticCall() // check that the type inference is correct - { - var moduleMixin = GetAnalyzedMixin("StaticMixin"); - var moduleMixinCall = GetAnalyzedMixin("StaticCallMixin"); - - var methodDef = moduleMixin.Mixin.ParsingInfo.ClassReferences.MethodsReferences.Select(x => x.Key).FirstOrDefault(); - var variableDef = moduleMixin.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).FirstOrDefault(); - var methodCall = moduleMixinCall.Mixin.ParsingInfo.StaticReferences.MethodsReferences.FirstOrDefault().Value.FirstOrDefault(); - - Assert.AreNotEqual(null, methodCall); - Assert.Equal(methodDef, methodCall.TypeInference.Declaration); - Assert.Equal(1, moduleMixinCall.Mixin.ParsingInfo.StaticReferences.VariablesReferences.Select(x => x.Key).Count()); - Assert.Equal(variableDef, moduleMixinCall.Mixin.ParsingInfo.StaticReferences.VariablesReferences.First().Value.First().Expression.TypeInference.Declaration); - } - /* - [Fact] - public void TestGenerics() // test the behavior with generics - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("TestGenerics", new object[] { 1.0f } ) - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - // TODO: change test - Irrelevant - Assert.DoesNotThrow(mcm.Run); - Assert.False(mcm.ErrorWarningLog.HasErrors); - } - /* - [Fact] - public void TestGenericsCall() // test the behavior with inheritance and generics - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("GenericCall"), - new ShaderClassSource("TestGenerics"), - new ShaderClassSource("TestGenerics", new object[] { 1.0 }), - new ShaderClassSource("TestGenerics", new object[] { 2.0 }), - new ShaderClassSource("TestGenerics", new object[] { "2.000000" }), // TODO: prevent this class to be loaded twice - new ShaderClassSource("GenericTexcoord", new object[] { "TEXCOORD0" }), - new ShaderClassSource("GenericExtern") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - - Assert.Equal(7, mcm.ClassSources.Count); - //Assert.Equal(2, mcm.UninstanciatedMixinInfos.Count); - - Assert.Equal(3, mcm.ClassSources.OfType().Count(x => x.ClassName == "TestGenerics")); - Assert.Equal(2, mcm.ClassSources.OfType().Count(x => x.ClassName == "GenericTexcoord")); - Assert.Equal(1, mcm.ClassSources.OfType().Count(x => x.ClassName == "GenericCall")); - Assert.Equal(1, mcm.ClassSources.OfType().Count(x => x.ClassName == "GenericExtern")); - - - ////////////////////////////////////////////////////////////////////////////////////////// - - // test generics with more complex identifier (IdentifierDot) - var shaderClassSourceList2 = new HashSet - { - new ShaderClassSource("TestGenericComplex"), - new ShaderClassSource("TestGenericMacro"), - new ShaderClassSource("StaticMixin") - }; - var mcm2 = new ShaderCompilationContext(shaderClassSourceList2, shaderLoader.LoadClassSource); - mcm2.Run(); - - Assert.False(mcm2.ErrorWarningLog.HasErrors); - } - - [Fact] - public void TestStageValueInitializer() // test "= stage" - { - // TODO: hangs - var moduleMixinRef = GetAnalyzedMixin("StageValueReference"); - - Assert.Equal(1, moduleMixinRef.Mixin.ParsingInfo.StageInitializedVariables.Count); - } - */ - [Fact] - public void TestStreams() // test streams input/output - nothing for now - { - var moduleMixin = GetAnalyzedMixin("TestStreams"); - - Assert.Equal(1, moduleMixin.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Select(x => x.Key).Count()); - Assert.Equal(1, moduleMixin.Mixin.ParsingInfo.ClassReferences.VariablesReferences.FirstOrDefault().Value.Count); - } - - [Fact] - public void TestExternClone() // test extern cloning and correct redirection - do nothing for now - { - var moduleMixin = GetAnalyzedMixin("ExternCloneTest"); - } - - [Fact] - public void TestStructure() // test structure type inference - { - var moduleMixinStr = GetAnalyzedMixin("TestStructure"); - var moduleMixinStrIn = GetAnalyzedMixin("TestStructInheritance"); - - Assert.Equal(1, moduleMixinStr.Mixin.ParsingInfo.StructureDefinitions.Count); - Assert.Equal(1, moduleMixinStr.Mixin.LocalVirtualTable.StructureTypes.Count); - Assert.Equal(1, moduleMixinStr.Mixin.VirtualTable.StructureTypes.Count); - - Assert.Equal(0, moduleMixinStrIn.Mixin.ParsingInfo.StructureDefinitions.Count); - Assert.Equal(0, moduleMixinStrIn.Mixin.LocalVirtualTable.StructureTypes.Count); - Assert.Equal(1, moduleMixinStrIn.Mixin.VirtualTable.StructureTypes.Count); - } - /* - [Fact] - public void TestGeometryShader() // test structures inheritance in geometry shader - { - var shaderClassSourceList = new HashSet - { - new ShaderClassSource("GeometryShaderTest"), - new ShaderClassSource("TestStructure") - }; - var mcm = new ShaderCompilationContext(shaderClassSourceList, shaderLoader.LoadClassSource); - mcm.Run(); - - Assert.False(mcm.ErrorWarningLog.HasErrors); - }*/ - - [Fact] - public void TestTessellation() // test tessellation shader, patchstream - { - var moduleMixin = GetAnalyzedMixin("TessellationTest"); - Assert.Equal(2, moduleMixin.Mixin.ParsingInfo.ClassReferences.VariablesReferences.Count(x => x.Key.Qualifiers.Contains(StrideStorageQualifier.PatchStream))); - } - - [Fact] - public void TestStageCall() - { - var moduleMixin = GetAnalyzedMixin("StageCallExtern"); - Assert.Equal(1, moduleMixin.Mixin.ParsingInfo.StageMethodCalls.Count); - } - - [Fact] - public void TestForEachStatement() - { - var moduleMixin = GetAnalyzedMixin("ForEachTest"); - Assert.Equal(1, moduleMixin.Mixin.ParsingInfo.ForEachStatements.Count); - } - /* - [Fact] - public void TestErrors() - { - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // check that a cyclic definition throws an error - var shaderClassSourceCyclic = new HashSet - { - new ShaderClassSource("CyclicTest") - }; - var mcmCyclic = new ShaderCompilationContext(shaderClassSourceCyclic, shaderLoader.LoadClassSource); - mcmCyclic.Run(); - - Assert.Equal(1, mcmCyclic.ErrorWarningLog.Messages.Count); - Assert.Equal(StrideMessageCode.ErrorCyclicDependency.Code, mcmCyclic.ErrorWarningLog.Messages[0].Code); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // check that a missing mixin throws an error - var shaderClassSourceMissing = new HashSet - { - new ShaderClassSource("Child") - }; - var mcmMissing = new ShaderCompilationContext(shaderClassSourceMissing, shaderLoader.LoadClassSource); - mcmMissing.Run(); - - Assert.Equal(1, mcmMissing.ErrorWarningLog.Messages.Count); - Assert.Equal(StrideMessageCode.ErrorDependencyNotInModule.Code, mcmMissing.ErrorWarningLog.Messages[0].Code); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // should throw an error: missing override keyword - var shaderClassSourceOverride = new HashSet - { - new ShaderClassSource("Parent"), - new ShaderClassSource("ChildError") - }; - var mcmOverride = new ShaderCompilationContext(shaderClassSourceOverride, shaderLoader.LoadClassSource); - mcmOverride.Run(); - - Assert.Equal(1, mcmOverride.ErrorWarningLog.Messages.Count); - Assert.Equal(StrideMessageCode.ErrorMissingOverride.Code, mcmOverride.ErrorWarningLog.Messages[0].Code); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // should create an error: name ambiguous - var shaderClassSourceAmbiguous = new HashSet - { - new ShaderClassSource("BasicMixin"), - new ShaderClassSource("BasicMixin2"), - new ShaderClassSource("MixinNameClash") - }; - var mcmAmbiguous = new ShaderCompilationContext(shaderClassSourceAmbiguous, shaderLoader.LoadClassSource); - mcmAmbiguous.Run(); - - Assert.Equal(1, mcmAmbiguous.ErrorWarningLog.Messages.Count); - Assert.Equal(StrideMessageCode.ErrorVariableNameAmbiguity.Code, mcmAmbiguous.ErrorWarningLog.Messages[0].Code); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // test what happens if an interface is declared - var shaderClassSourceInterface = new HashSet - { - new ShaderClassSource("InterfaceTest") - }; - var mcmInterface = new ShaderCompilationContext(shaderClassSourceInterface, shaderLoader.LoadClassSource); - mcmInterface.Run(); - - Assert.True(mcmInterface.ErrorWarningLog.HasErrors); - Assert.Equal(1, mcmInterface.ErrorWarningLog.Messages.Count); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // test what happens when a mixin is a parameter or a return value inside a function - var shaderClassSourceParamReturn = new HashSet - { - new ShaderClassSource("ExternMixin"), - new ShaderClassSource("MixinFunctionParamaterTest") - }; - var mcmParamReturn = new ShaderCompilationContext(shaderClassSourceParamReturn, shaderLoader.LoadClassSource); - mcmParamReturn.Run(); - - Assert.Equal(3, mcmParamReturn.ErrorWarningLog.Messages.Count); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - // test that it is impossible to put a shaderclass as a generic value - var shaderClassSourceGenerics = new HashSet - { - new ShaderClassSource("StructuredBufferTest"), - new ShaderClassSource("StaticMixin") - }; - var mcmGenerics = new ShaderCompilationContext(shaderClassSourceGenerics, shaderLoader.LoadClassSource); - mcmGenerics.Run(); - - Assert.True(mcmGenerics.ErrorWarningLog.HasErrors); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - var shaderClassSourceFunc = new HashSet - { - new ShaderClassSource("TestErrors"), - new ShaderClassSource("ExternMixin") - }; - var mcmFunc = new ShaderCompilationContext(shaderClassSourceFunc, shaderLoader.LoadClassSource); - mcmFunc.Run(); - - // TODO: separate tests or check messages/error code - Assert.Equal(27, mcmFunc.ErrorWarningLog.Messages.Count); - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - var shaderClassSourceStream = new HashSet - { - new ShaderClassSource("StreamError") - }; - var mcmStream = new ShaderCompilationContext(shaderClassSourceStream, shaderLoader.LoadClassSource); - mcmStream.Run(); - - Assert.Equal(1, mcmStream.ErrorWarningLog.Messages.Count); - Assert.Equal(StrideMessageCode.ErrorInOutStream.Code, mcmStream.ErrorWarningLog.Messages[0].Code); - } - - [Fact] - public void TestShaderLibrary() - { - var shaderClassSourceList = new HashSet - { - "BaseTestParent", - "BaseTestParent", - "StaticMixin", - "MacroTest", - "MacroTestChild" - }; - - var lib = new StrideShaderLibrary(shaderClassSourceList); - lib.LoadClass = shaderLoader.LoadClassSource; - - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(0, lib.MixinInfos.Count); - var context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MAC0", "0") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(4, lib.MixinInfos.Count); - Assert.Equal(4, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MAC1", "1") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(8, lib.MixinInfos.Count); - Assert.Equal(4, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MAC0", "1") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(12, lib.MixinInfos.Count); - Assert.Equal(4, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MAC0", "0") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(12, lib.MixinInfos.Count); - Assert.Equal(4, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(16, lib.MixinInfos.Count); - Assert.Equal(4, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MACRO_TEST", "int") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(20, lib.MixinInfos.Count); - Assert.Equal(5, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); - - context = lib.GetContextFromMacros(new ShaderMacro[] { new ShaderMacro("MACRO_TEST", "float") }); - Assert.Equal(4, context.Count); - Assert.Equal(4, lib.AvailableShaders.Count); - Assert.Equal(24, lib.MixinInfos.Count); - Assert.Equal(6, lib.MixinInfos.Select(x => x.Mixin).Distinct().Count()); // TODO: should be 4! - - } - - [Fact] - public void TestSingle() - { - VirtualFileSystem.MountFileSystem("/assets/shaders", "../../../../../shaders"); - - var className = "ComputeColorFixed"; - Console.WriteLine(@"Loading effect " + className); - - var effectCompiler = EffectCompiler.New(EffectCompilerTarget.Direct3D11, GraphicsProfile.Level_11_1) as EffectCompilerHlsl; - - if (effectCompiler != null) - { - var mixin = new ShaderMixinSource(); - mixin.Mixins.Add(new ShaderClassSource(className, "float4(0.0,1.0, 0.5, 2.0)")); - effectCompiler.CompileEffectShaderPass("test.hlsl", mixin, null); - } - } - - private void TestSingleClass(EffectCompilerHlsl effectCompiler, string className) - { - var mixin = new ShaderMixinSource(); - mixin.Mixins.Add(new ShaderClassSource(className)); - try - { - if (className == "LightMultiDirectionalShadingPerPixel") - mixin.Mixins[0].GenericParameters = new object[] {4}; - effectCompiler.CompileEffectShaderPass("test.hlsl", mixin, null); - } - catch (Exception exp) - { - Console.WriteLine(@"---EXCEPTION---"); - Console.WriteLine(exp.Message); - } - } - - [Fact] - public void TestWarnings() - { - //VirtualFileSystem.MountFileSystem("/assets/shaders", "../../../../../shaders"); - VirtualFileSystem.MountFileSystem("/assets/shaders", "C:\\Users\\aurelien.serandour\\Desktop\\Shaders"); - foreach (var file in VirtualFileSystem.ListFiles("/assets/shaders", "*.sdsl", VirtualSearchOption.TopDirectoryOnly).Result) - { - var fileParts = file.Split('.', '/'); - var className = fileParts[fileParts.Length - 2]; - Console.WriteLine(); - Console.WriteLine(@"Loading effect " + className); - var effectCompiler = EffectCompiler.New(EffectCompilerTarget.Direct3D11, GraphicsProfile.Level_11_1) as EffectCompilerHlsl; - - if (effectCompiler != null) - TestSingleClass(effectCompiler, className); - } - - var effectCompiler0 = EffectCompiler.New(EffectCompilerTarget.Direct3D11, GraphicsProfile.Level_11_1) as EffectCompilerHlsl; - TestSingleClass(effectCompiler0, "PostEffectFXAA"); - } - - - [Fact] - public void TestMayaWarnings() - { - VirtualFileSystem.MountFileSystem("/assets/shaders", "../../../../../shaders"); - //VirtualFileSystem.MountFileSystem("/assets/shaders", "C:\\Users\\aurelien.serandour\\Desktop\\Shaders\\Maya"); - foreach (var file in VirtualFileSystem.ListFiles("/assets/shaders", "*.sdsl", VirtualSearchOption.TopDirectoryOnly).Result) - { - var fileParts = file.Split('.', '/'); - var className = fileParts[fileParts.Length - 2]; - Console.WriteLine(); - Console.WriteLine(@"Loading effect " + className); - var effectCompiler = EffectCompiler.New(EffectCompilerTarget.Direct3D11, GraphicsProfile.Level_11_1) as EffectCompilerHlsl; - - if (effectCompiler != null) - TestSingleClass(effectCompiler, className); - } - }*/ - - public ModuleMixinInfo GetAnalyzedMixin(string mixinName) - { - var source = new ShaderMixinSource(); - source.Mixins.Add(new ShaderClassSource(mixinName)); - shaderMixinParser.Parse(source, new Stride.Shaders.ShaderMacro[0]); - - var moduleMixin = shaderMixinParser.GetMixin(mixinName); - Assert.IsNotNull(moduleMixin); - Assert.False(moduleMixin.Log.HasErrors); - Assert.IsNotNull(moduleMixin.Mixin); - - return moduleMixin; - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/TestShaderReflection.cs b/sources/engine/Stride.Shaders.Tests/TestShaderReflection.cs deleted file mode 100644 index b8221ab65f..0000000000 --- a/sources/engine/Stride.Shaders.Tests/TestShaderReflection.cs +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using Xunit; - -using Stride.Core.Diagnostics; -using Stride.Core.IO; -using Stride.Core.Storage; -using Stride.Graphics; -using Stride.Shaders.Compiler; -using System.Linq; -using Stride.Rendering; -using System; -using System.Collections.Generic; -using System.Text; -using Stride.Core.Shaders.Ast; -using Stride.Core.Mathematics; - -namespace Stride.Shaders.Tests -{ - public class TestShaderReflection - { - public EffectCompiler Compiler; - - public LoggerResult ResultLogger; - - public CompilerParameters MixinParameters; - - private void Init() - { - // Create and mount database file system - var objDatabase = ObjectDatabase.CreateDefaultDatabase(); - var databaseFileProvider = new DatabaseFileProvider(objDatabase); - - Compiler = new EffectCompiler(databaseFileProvider); - Compiler.SourceDirectories.Add("shaders"); - MixinParameters = new CompilerParameters(); - MixinParameters.EffectParameters.Platform = GraphicsPlatform.Direct3D11; - MixinParameters.EffectParameters.Profile = GraphicsProfile.Level_11_0; - ResultLogger = new LoggerResult(); - } - - /// - /// Tests whether default values defined in a shader are present in the shader reflection. - /// The shader source code is generated on the fly to ensure that the generated keys haven't been - /// created beforehand by the shader key generator tool. - /// - [Fact] - public void TestDefaultValuesBeingPresentInReflection() - { - Init(); - - var shaderClassName = "DefaultValuesTest"; - - var variables = new List<(string name, string type, string value, object clrValue)>(); - variables.Add((name: "floatVar", type: "float", value: "1", clrValue: 1f)); - variables.Add((name: "doubleVar", type: "double", value: "1", clrValue: 1d)); - variables.Add((name: "intVar", type: "int", value: "1", clrValue: 1)); - variables.Add((name: "uintVar", type: "uint", value: "1", clrValue: 1u)); - variables.Add((name: "boolVar", type: "bool", value: "true", clrValue: true)); - AddVectorVariable(VectorType.Float2, 1f, Vector2.One); - AddVectorVariable(VectorType.Float3, 1f, Vector3.One); - AddVectorVariable(VectorType.Float4, 1f, Vector4.One); - AddVectorVariable(VectorType.Double2, 1d, Double2.One); - AddVectorVariable(VectorType.Double3, 1d, Double3.One); - AddVectorVariable(VectorType.Double4, 1d, Double4.One); - // error X3650: global variables cannot use the 'half' type in vs_5_0. To treat this variable as a float, use the backwards compatibility flag. - //AddVectorVariable(VectorType.Half2, (Half)1f, Half2.One); - //AddVectorVariable(VectorType.Half3, (Half)1f, Half3.One); - //AddVectorVariable(VectorType.Half4, (Half)1f, Half4.One); - AddVectorVariable(VectorType.Int2, 1, Int2.One); - AddVectorVariable(VectorType.Int3, 1, Int3.One); - AddVectorVariable(VectorType.Int4, 1, Int4.One); - AddVectorVariable(VectorType.UInt4, 1u, UInt4.One); - AddVectorVariable(new MatrixType(ScalarType.Float, 4, 4), 1f, new Matrix(1f)); - - var assignments = new StringBuilder(); - foreach (var v in variables) - { - assignments.AppendLine($"{v.type} {v.name} = {v.value};"); - } - - var mixinSource = new ShaderMixinSource() { Name = shaderClassName }; - mixinSource.Mixins.Add(CreateShaderClassCode(shaderClassName, assignments.ToString())); - var bytecodeTask = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - - Assert.False(bytecodeTask.Result.CompilationLog.HasErrors); - - var bytecode = bytecodeTask.Result.Bytecode; - var members = bytecode.Reflection.ConstantBuffers[0].Members; - foreach (var v in variables) - { - var defaultValue = members.FirstOrDefault(k => k.KeyInfo.KeyName == $"{shaderClassName}.{v.name}").DefaultValue; - Assert.NotNull(defaultValue); - Assert.Equal(v.clrValue, defaultValue); - } - - unsafe void AddVectorVariable(TypeBase type, TComponent scalarValue, TVector vectorValue) - where TVector : unmanaged - where TComponent : unmanaged - { - var name = $"{typeof(TVector).Name}Var"; - var dimension = sizeof(TVector) / sizeof(TComponent); - var components = string.Join(", ", Enumerable.Repeat(scalarValue, dimension)); - variables.Add(( - name: name, - type: type.ToString(), - value: $"{type}({components})", - clrValue: vectorValue)); - - variables.Add(( - name: $"{name}_Promoted", - type: type.ToString(), - value: $"{scalarValue}", - clrValue: vectorValue)); - - variables.Add(( - name: $"{name}_Array", - type: type.ToString(), - value: $"{{{components}}}", - clrValue: vectorValue)); - - var aliasType = - type is MatrixType m ? $"{m.Type}{m.RowCount}x{m.ColumnCount}" : - type is VectorType v ? $"{v.Type}{v.Dimension}" : - default; - if (aliasType != null) - { - // Check type alias like float4 for vector - variables.Add(( - name: $"{name}_Alias", - type: aliasType, - value: $"{{{components}}}", - clrValue: vectorValue)); - } - } - } - - /// - /// Tests whether default values defined in a shader are being updated after modifications to the shader. - /// - [Fact] - public void TestDefaultValuesGettingUpdatedAfterRecompile() - { - Init(); - - var shaderClassName = "DefaultValuesBeingUpdatedTest"; - var variableName = "floatVar"; - - // First register the key as it would've been done by the generator - var initialKey = ParameterKeys.NewValue(1f, $"{shaderClassName}.{variableName}"); - ParameterKeys.Merge(initialKey, ownerType: null, initialKey.Name); - - GenerateAndCheck("1", 1f); - - Compiler.ResetCache(new HashSet() { shaderClassName }); - - GenerateAndCheck("2", 2f); - - void GenerateAndCheck(string stringValue, float value) - { - var variables = new List<(string name, TypeBase type, string value, object clrValue)>(); - variables.Add((name: variableName, type: ScalarType.Float, value: stringValue, clrValue: value)); - - var assignments = new StringBuilder(); - foreach (var v in variables) - assignments.AppendLine($"{v.type} {v.name} = {v.value};"); - - var mixinSource = new ShaderMixinSource() { Name = shaderClassName }; - mixinSource.Mixins.Add(CreateShaderClassCode(shaderClassName, assignments.ToString())); - var bytecodeTask = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - - Assert.False(bytecodeTask.Result.CompilationLog.HasErrors); - - var bytecode = bytecodeTask.Result.Bytecode; - using (var graphicsDevice = GraphicsDevice.New()) - { - // The effect constructor updates the effect reflection - var effect = new Effect(graphicsDevice, bytecode); - - var members = bytecode.Reflection.ConstantBuffers[0].Members; - foreach (var v in variables) - { - // Fetch the default value via the key - the previous test already checked whether the default value is present in the value description - var effectValueDescription = members.FirstOrDefault(k => k.KeyInfo.KeyName == $"{shaderClassName}.{v.name}"); - var defaultValue = effectValueDescription.KeyInfo.Key.DefaultValueMetadata.GetDefaultValue(); - Assert.NotNull(defaultValue); - Assert.Equal(v.clrValue, defaultValue); - } - } - } - } - - /// - /// Tests whether unary expressions are evaluated correctly. For example float x = -1 - /// Regression test for https://github.com/stride3d/stride/issues/1963 - /// - [Fact] - public void TestDefaultValuesWithUnaryExpressionGetEvaluatedCorrectly() - { - Init(); - - var shaderClassName = "DefaultValuesUsingUnaryExpressionTest"; - - var variables = new List<(string name, string type, string value, object clrValue)>(); - variables.Add((name: "floatVar", type: "float", value: "-1", clrValue: -1f)); - variables.Add((name: "doubleVar", type: "double", value: "-1", clrValue: -1d)); - variables.Add((name: "intVar", type: "int", value: "-1", clrValue: -1)); - variables.Add((name: "uintVar", type: "uint", value: "~1", clrValue: ~1u)); - variables.Add((name: "boolVar", type: "bool", value: "!true", clrValue: !true)); - AddVectorVariable(VectorType.Float2, -1f, "-1", Vector2.One * -1); - AddVectorVariable(VectorType.Float3, -1f, "-1", Vector3.One * -1); - AddVectorVariable(VectorType.Float4, -1f, "-1", Vector4.One * -1); - AddVectorVariable(VectorType.Double2, -1d, "-1", Double2.One * -1); - AddVectorVariable(VectorType.Double3, -1d, "-1", Double3.One * -1); - AddVectorVariable(VectorType.Double4, -1d, "-1", Double4.One * -1); - // error X3650: global variables cannot use the 'half' type in vs_5_0. To treat this variable as a float, use the backwards compatibility flag. - //AddVectorVariable(VectorType.Half2, (Half)-1f, Half2.One * -1); - //AddVectorVariable(VectorType.Half3, (Half)-1f, Half3.One * -1); - //AddVectorVariable(VectorType.Half4, (Half)-1f, Half4.One * -1); - AddVectorVariable(VectorType.Int2, -1, "-1", Int2.One * -1); - AddVectorVariable(VectorType.Int3, -1, "-1", Int3.One * -1); - AddVectorVariable(VectorType.Int4, -1, "-1", Int4.One * -1); - AddVectorVariable(VectorType.UInt4, ~1u, "~1", new UInt4(~1u)); - AddVectorVariable(new MatrixType(ScalarType.Float, 4, 4), -1f, "-1", new Matrix(1f) * -1); - - var assignments = new StringBuilder(); - foreach (var v in variables) - { - assignments.AppendLine($"{v.type} {v.name} = {v.value};"); - } - - var mixinSource = new ShaderMixinSource() { Name = shaderClassName }; - mixinSource.Mixins.Add(CreateShaderClassCode(shaderClassName, assignments.ToString())); - var bytecodeTask = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - - Assert.False(bytecodeTask.Result.CompilationLog.HasErrors); - - var bytecode = bytecodeTask.Result.Bytecode; - var members = bytecode.Reflection.ConstantBuffers[0].Members; - foreach (var v in variables) - { - var defaultValue = members.FirstOrDefault(k => k.KeyInfo.KeyName == $"{shaderClassName}.{v.name}").DefaultValue; - Assert.NotNull(defaultValue); - Assert.Equal(v.clrValue, defaultValue); - } - - unsafe void AddVectorVariable(TypeBase type, TComponent component, string literal, TVector vectorValue) - where TVector : unmanaged - where TComponent : unmanaged - { - var name = $"{typeof(TVector).Name}Var"; - var dimension = sizeof(TVector) / sizeof(TComponent); - var components = string.Join(", ", Enumerable.Repeat(literal, dimension)); - variables.Add(( - name: name, - type: type.ToString(), - value: $"{type}({components})", - clrValue: vectorValue)); - - variables.Add(( - name: $"{name}_Promoted", - type: type.ToString(), - value: $"{literal}", - clrValue: vectorValue)); - - variables.Add(( - name: $"{name}_Array", - type: type.ToString(), - value: $"{{{components}}}", - clrValue: vectorValue)); - - var aliasType = - type is MatrixType m ? $"{m.Type}{m.RowCount}x{m.ColumnCount}" : - type is VectorType v ? $"{v.Type}{v.Dimension}" : - default; - if (aliasType != null) - { - // Check type alias like float4 for vector - variables.Add(( - name: $"{name}_Alias", - type: aliasType, - value: $"{{{components}}}", - clrValue: vectorValue)); - } - } - } - - /// - /// Tests whether unkown expressions in an intializer are ignored in the default value. For example float x = 1 + 3 should result in DefaultValue = null - /// - [Fact] - public void TestDefaultValuesWithUnknownExpressionAreIgnored() - { - Init(); - - var shaderClassName = "DefaultValuesWithUnknownExpressionAreIgnoredTest"; - - var mixinSource = new ShaderMixinSource() { Name = shaderClassName }; - mixinSource.Mixins.Add(CreateShaderClassCode(shaderClassName, "float x = 3 + 4;")); - var bytecodeTask = Compiler.Compile(mixinSource, MixinParameters.EffectParameters, MixinParameters); - - Assert.False(bytecodeTask.Result.CompilationLog.HasErrors); - - var bytecode = bytecodeTask.Result.Bytecode; - var member = bytecode.Reflection.ConstantBuffers[0].Members[0]; - Assert.Null(member.DefaultValue); - } - - static ShaderClassCode CreateShaderClassCode(string className, string initializer) - { - return new ShaderClassString(className, @" -shader " + className + @" -{ - // Use a logical group which prevents the variables from being optimized away by EffectCompiler - cbuffer Globals.Test - { -" + initializer + @" - } - - // Declare Vertex shader main method - stage void VSMain() {} - - // Declare Pixel shader main method - stage void PSMain() {} -}; - "); - } - } -} diff --git a/sources/engine/Stride.Shaders.Tests/app.config b/sources/engine/Stride.Shaders.Tests/app.config deleted file mode 100644 index 99ddf3e08e..0000000000 --- a/sources/engine/Stride.Shaders.Tests/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file From c4b6fec7e350ef167834d82958e1c8329a8cb63f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 31 Mar 2026 21:58:33 +0900 Subject: [PATCH 1033/1182] SDFX: Replace ColorTransformKeys string Shader + object[] GenericArguments with ShaderSource --- .../ColorTransforms/ColorTransformBase.cs | 26 +++---------------- .../ColorTransformGroupEffect.sdfx | 2 +- .../ColorTransforms/ColorTransformKeys.cs | 9 +++---- .../LuminanceToChannelTransform.cs | 4 +-- 4 files changed, 10 insertions(+), 31 deletions(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs index 7ed8e93018..2a0d0f976a 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs @@ -6,6 +6,7 @@ using System.Reflection; using Stride.Core; +using Stride.Shaders; namespace Stride.Rendering.Images { @@ -30,7 +31,7 @@ protected ColorTransformBase(string colorTransformShader) // Initialize all Parameters with values coming from each ParameterKey InitializeProperties(); - Shader = colorTransformShader; + Shader = new ShaderClassSource(colorTransformShader); } /// @@ -40,11 +41,10 @@ protected ColorTransformBase(string colorTransformShader) public ColorTransformGroup Group { get; internal set; } /// - /// Gets or sets the name of the shader. + /// Gets or sets the shader source for this color transform. /// - /// The name of the shader. [DataMemberIgnore] - public string Shader + public ShaderSource Shader { get { @@ -62,24 +62,6 @@ public string Shader } } - /// - /// Gets or sets the generic arguments used by the shader. Default is null. - /// - /// The generic arguments used by the shader. Default is null - [DataMemberIgnore] - public object[] GenericArguments - { - get - { - return Parameters.Get(ColorTransformKeys.GenericArguments); - } - set - { - Parameters.Set(ColorTransformKeys.GenericArguments, value); - Group?.NotifyPermutationChange(); - } - } - /// /// Gets the parameters. /// diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx index 31e7995459..5fbe61d2ea 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformGroupEffect.sdfx @@ -9,7 +9,7 @@ namespace Stride.Rendering.Images { using params ColorTransformKeys; - mixin ColorTransformKeys.Shader; + mixin (ColorTransformKeys.Shader); }; effect ColorTransformGroupEffect diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformKeys.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformKeys.cs index f267c32a21..09df492de9 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformKeys.cs +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformKeys.cs @@ -1,5 +1,7 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Shaders; + namespace Stride.Rendering.Images { /// @@ -15,11 +17,6 @@ internal static class ColorTransformKeys /// /// The shader used by . /// - public static readonly PermutationParameterKey Shader = ParameterKeys.NewPermutation("ColorTransformShader"); - - /// - /// The shader used by . - /// - public static readonly PermutationParameterKey GenericArguments = ParameterKeys.NewPermutation((object[])null); + public static readonly PermutationParameterKey Shader = ParameterKeys.NewPermutation(new ShaderClassSource("ColorTransformShader")); } } diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelTransform.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelTransform.cs index cfdce30e98..3ccf1c7651 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelTransform.cs +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/LuminanceToChannelTransform.cs @@ -1,10 +1,10 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using System.ComponentModel; -using System.Globalization; using Stride.Core; using Stride.Rendering.Materials; +using Stride.Shaders; namespace Stride.Rendering.Images { @@ -47,7 +47,7 @@ public ColorChannel ColorChannel set { colorChannel = value; - GenericArguments = new object[] { value.ToString().ToLowerInvariant() }; + Shader = new ShaderClassSource("LuminanceToChannelShader", value.ToString().ToLowerInvariant()); } } } From 5900f0c35793e1c3cb442be1f3e703bed309e6a7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 12:01:50 +0900 Subject: [PATCH 1034/1182] fix: migrate sdsl-rewrite shader projects to new SDK build system - Replace legacy Stride.props imports with Stride.Build.Sdk imports - Replace $(StrideSdkTargets) with explicit SDK path - Migrate Stride.Shaders.Tests to Stride.Build.Sdk.Tests - Restore Stride.Graphics.targets (removed OpenGL, Android defaults to Vulkan) --- .../Sdk/Stride.Graphics.targets | 101 ++++++++++++++++++ .../Stride.Shaders.Compilers.csproj | 4 +- .../Stride.Shaders.Parsers.csproj | 4 +- .../Stride.Shaders.Spirv.Core.csproj | 4 +- .../Stride.Shaders.Tests.csproj | 9 +- .../Stride.Shaders/Stride.Shaders.csproj | 4 - sources/targets/Stride.UnitTests.props | 31 ++++++ 7 files changed, 142 insertions(+), 15 deletions(-) create mode 100644 sources/sdk/Stride.Build.Sdk/Sdk/Stride.Graphics.targets create mode 100644 sources/targets/Stride.UnitTests.props diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Graphics.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Graphics.targets new file mode 100644 index 0000000000..9e29be5743 --- /dev/null +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Graphics.targets @@ -0,0 +1,101 @@ + + + + + + + + + + Direct3D11;Direct3D12;Vulkan + + $(StrideGraphicsApis.Split(';', StringSplitOptions.RemoveEmptyEntries)[0]) + Direct3D11 + Vulkan + Vulkan + + + + + false + false + false + $(StrideDefaultGraphicsApi) + + + + + $(StrideDefaultGraphicsApiDesignTime) + $(StrideDefaultGraphicsApi) + + + + + + + STRIDE_GRAPHICS_API_DIRECT3D;STRIDE_GRAPHICS_API_DIRECT3D11 + + + + STRIDE_GRAPHICS_API_DIRECT3D;STRIDE_GRAPHICS_API_DIRECT3D12 + + + + STRIDE_GRAPHICS_API_NULL + + + + STRIDE_GRAPHICS_API_VULKAN + + + + + $(DefineConstants);$(StrideGraphicsApiDefines) + + + + + + + + false + false + obj\$(Configuration)\$(TargetFramework)\$(StrideGraphicsApi)\ + bin\$(Configuration)\$(TargetFramework)\$(StrideGraphicsApi)\ + + + + + + + SDL + $(StrideUI);WINFORMS;WPF + + $(DefineConstants);STRIDE_UI_SDL + $(DefineConstants);STRIDE_UI_WINFORMS + $(DefineConstants);STRIDE_UI_WPF + + + + + + + + + diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 33c72f92a2..4a63b3df46 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -1,8 +1,8 @@  + true - * true @@ -52,5 +52,5 @@ - + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj index 696fd1e7ab..2ab4f90b06 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj +++ b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj @@ -1,8 +1,8 @@  + true - @@ -27,5 +27,5 @@ True Stride.Shaders - + diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 2d690907fa..449111b081 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,8 +1,8 @@  + true - enable enable @@ -26,5 +26,5 @@ - + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index b5ca3f5f00..ee5bb24e0d 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -1,14 +1,13 @@ - - + + - $(StrideEditorTargetFramework) + $(StrideXplatEditorTargetFramework) win-x64 * enable enable false - true True false @@ -50,5 +49,5 @@ - + diff --git a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj index b3af20170d..e092d9c263 100644 --- a/sources/shaders/Stride.Shaders/Stride.Shaders.csproj +++ b/sources/shaders/Stride.Shaders/Stride.Shaders.csproj @@ -2,12 +2,8 @@ true - - - * true - true true --serialization --parameter-key diff --git a/sources/targets/Stride.UnitTests.props b/sources/targets/Stride.UnitTests.props new file mode 100644 index 0000000000..7f81c0d97d --- /dev/null +++ b/sources/targets/Stride.UnitTests.props @@ -0,0 +1,31 @@ + + + + + + + + + + + + Windows + WinExe + + $(StridePlatform) + $(StridePlatformFullName)-$(StrideBuildDirExtension) + + false + false + obj\ + true + + + true + + + + + + + From 1e31580ad7e3919014837fe557b22ae1dfb52f5f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 12:13:14 +0900 Subject: [PATCH 1035/1182] fix: add shader file auto-discovery to SDK, fix xunit v3 conflict in tests --- sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets | 10 ++++++++-- .../Stride.Shaders.Tests/Stride.Shaders.Tests.csproj | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets index 292d267877..4a534294ec 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets @@ -77,9 +77,15 @@ - + + + + + + + diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index ee5bb24e0d..ced8016bdf 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -10,6 +10,8 @@ false True false + true + false true From eb1d2b0385efa646ff2d9a5c3765e4fd0e3bde9a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 12:50:12 +0900 Subject: [PATCH 1036/1182] fix: shader test output path and asset copying for new SDK --- .../Stride.Shaders.Tests.csproj | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index ced8016bdf..a55c610333 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -9,6 +9,8 @@ false True + false + $(StrideRoot)bin\Tests\$(MSBuildProjectName)\$(StridePlatform)\ false true false @@ -36,15 +38,18 @@ - - - - - - - - - + + + + + + + + + + + + From 5481691c9213270f25c9e5c105488d3576c41094 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 15:20:09 +0900 Subject: [PATCH 1037/1182] fix: register object[] serializer for ParameterCollection.ObjectValues The serializer was previously generated as a side-effect of the now-removed PermutationParameterKey GenericArguments key. Also remove OpenGL references from TesselationTest (OpenGL removed in sdsl-rewrite). --- sources/engine/Stride.Engine.Tests/TesselationTest.cs | 2 -- sources/engine/Stride/Rendering/ParameterCollection.cs | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sources/engine/Stride.Engine.Tests/TesselationTest.cs b/sources/engine/Stride.Engine.Tests/TesselationTest.cs index d610097a73..6d04fca131 100644 --- a/sources/engine/Stride.Engine.Tests/TesselationTest.cs +++ b/sources/engine/Stride.Engine.Tests/TesselationTest.cs @@ -210,8 +210,6 @@ private void ChangeMaterial(int i) [SkippableFact] public void RunTestGame() { - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGL); - SkipTestForGraphicPlatform(GraphicsPlatform.OpenGLES); SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); // Note: D3D12 WARP tessellation is limited to first frame only (see RegisterTests) diff --git a/sources/engine/Stride/Rendering/ParameterCollection.cs b/sources/engine/Stride/Rendering/ParameterCollection.cs index 4b50a54f9f..1fd504a338 100644 --- a/sources/engine/Stride/Rendering/ParameterCollection.cs +++ b/sources/engine/Stride/Rendering/ParameterCollection.cs @@ -17,6 +17,7 @@ namespace Stride.Rendering /// [DataSerializer(typeof(ParameterCollection.Serializer))] [DataSerializerGlobal(null, typeof(List))] + [DataSerializerGlobal(null, typeof(object[]))] [DebuggerTypeProxy(typeof(ParameterCollection.DebugView))] public class ParameterCollection { From 5641785d36ef87b0d696927db18255fc11364b23 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 16:42:26 +0900 Subject: [PATCH 1038/1182] feat: add per-test image comparison tolerance (ImageComparisonTolerance) --- .../engine/Stride.Graphics.Regression/GameTestBase.cs | 8 +++++++- .../engine/Stride.Graphics.Regression/ImageTester.cs | 11 +++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs index 27c57e1934..3c2992bcda 100644 --- a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs +++ b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs @@ -75,6 +75,12 @@ public abstract class GameTestBase : Game /// public int StopOnFrameCount { get; set; } + /// + /// Maximum per-channel color difference (0-255) allowed when comparing images. + /// Default is 2. Increase for tests with expected minor numerical differences. + /// + public int ImageComparisonTolerance { get; set; } = 2; + /// /// Gets or sets the name of the test. It will be reflected in the saved images. /// @@ -777,7 +783,7 @@ public void SendImage(Image image, string? testName) ImageTester.SaveImage(image, testLocalFileName); comparisonMissingMessages.Add($"* {testLocalFileName} (current)"); } - else if (!testFileNames.Any(file => ImageTester.CompareImage(image, file))) + else if (!testFileNames.Any(file => ImageTester.CompareImage(image, file, ImageComparisonTolerance))) { // Comparison failed, save current version so that user can compare / promote it manually ImageTester.SaveImage(image, testLocalFileName); diff --git a/sources/engine/Stride.Graphics.Regression/ImageTester.cs b/sources/engine/Stride.Graphics.Regression/ImageTester.cs index 80e0054994..39b9fd9ae6 100644 --- a/sources/engine/Stride.Graphics.Regression/ImageTester.cs +++ b/sources/engine/Stride.Graphics.Regression/ImageTester.cs @@ -43,7 +43,15 @@ public static void SaveImage(Image image, string testFilename) /// /// The image to send. /// The expected filename. - public static bool CompareImage(Image image, string testFilename) + public static bool CompareImage(Image image, string testFilename) => CompareImage(image, testFilename, 2); + + /// + /// Send the data of the test to the server. + /// + /// The image to send. + /// The expected filename. + /// Maximum per-channel difference allowed before a pixel is considered different. + public static bool CompareImage(Image image, string testFilename, int allowedDiff) { // Compare using (var stream = File.OpenRead(testFilename)) @@ -77,7 +85,6 @@ public static bool CompareImage(Image image, string testFilename) bool checkAlpha = buffer.Format.AlphaSizeInBits > 0; // Compare remaining bytes. - int allowedDiff = 2; int differentPixels = 0; unsafe { From 53c6ad5947061e918184a73b78122ffa269b6bc9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 9 Apr 2026 18:16:18 +0900 Subject: [PATCH 1039/1182] fix: only emit immutable SamplerStateSDSL for samplers with inline state Samplers declared without explicit parameters (e.g. "stage SamplerState Sampler;") are dynamic and should be settable at runtime via Parameters.Set(). Previously the SDSL compiler emitted a SamplerStateSDSL decoration with default values (Linear/Clamp), making the sampler immutable and ignoring runtime overrides. --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 36384b97dd..28ae923f02 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -116,10 +116,16 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler throw new NotImplementedException($"SamplerState parameter '{parameter.Name}' not implemented"); } } - context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateSDSL, [ - filter, addressU, addressV, addressW, mipLODBias, maxAnisotropy, comparisonFunc, minLOD, maxLOD, - borderR, borderG, borderB, borderA - ])); + // Only emit immutable sampler state when the declaration has explicit parameters. + // Samplers without inline state (e.g. "stage SamplerState Sampler;") are dynamic + // and set at runtime via Parameters.Set(). + if (Parameters.Count > 0) + { + context.Add(new OpDecorate(variableId, Specification.Decoration.SamplerStateSDSL, [ + filter, addressU, addressV, addressW, mipLODBias, maxAnisotropy, comparisonFunc, minLOD, maxLOD, + borderR, borderG, borderB, borderA + ])); + } var variable = builder.Insert(new OpVariableSDSL(registeredType, variableId, Specification.StorageClass.UniformConstant, IsStaged ? Specification.VariableFlagsMask.Stage : Specification.VariableFlagsMask.None, null)); context.AddName(variable.ResultId, Name); From c0707f48c7d49e8eb7a298e2514d0ff0496cb4d3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 10 Apr 2026 02:19:05 +0900 Subject: [PATCH 1040/1182] fix: redirect ApplicationCache to build path during asset compilation --- .../assets/Stride.Core.Assets.CompilerApp/PackageBuilder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/assets/Stride.Core.Assets.CompilerApp/PackageBuilder.cs b/sources/assets/Stride.Core.Assets.CompilerApp/PackageBuilder.cs index 712552d696..3b6aed1529 100644 --- a/sources/assets/Stride.Core.Assets.CompilerApp/PackageBuilder.cs +++ b/sources/assets/Stride.Core.Assets.CompilerApp/PackageBuilder.cs @@ -100,6 +100,9 @@ private BuildResultCode BuildMaster() var buildDirectory = builderOptions.BuildDirectory; var outputDirectory = builderOptions.OutputDirectory; + // Redirect ApplicationCache to the build directory so shader caches are per-project + ((FileSystemProvider)VirtualFileSystem.ApplicationCache).ChangeBasePath(Path.Combine(buildDirectory, "cache")); + // Process game settings asset var gameSettingsAsset = package.GetGameSettingsAsset(); if (gameSettingsAsset == null) @@ -324,6 +327,7 @@ private BuildResultCode BuildSlave() { // Mount build path ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory); + ((FileSystemProvider)VirtualFileSystem.ApplicationCache).ChangeBasePath(Path.Combine(builderOptions.BuildDirectory, "cache")); VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath); From 0be7c76dfee92735a0f7ca6500f4afce305f6f42 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 10 Apr 2026 08:40:14 +0900 Subject: [PATCH 1041/1182] fix: add /q flag to rmdir in CompileShaders scripts --- .../engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd | 2 +- .../Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index 693774cb9e..661e0913f0 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -2,7 +2,7 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -rmdir /s %~dp0obj\ +rmdir /s /q %~dp0obj\ 2>nul %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd index 693774cb9e..661e0913f0 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd @@ -2,7 +2,7 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -rmdir /s %~dp0obj\ +rmdir /s /q %~dp0obj\ 2>nul %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg From 548ee0f0940c668d647449597a33657c6e333125 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 10 Apr 2026 08:46:04 +0900 Subject: [PATCH 1042/1182] regenerate shader bytecodes with dynamic sampler fix --- ...riteBatch.bytecode.Direct3D11.Level_9_1.cs | 996 ++++++++------- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 1074 +++++++++++------ ...Batch.bytecodeSRgb.Direct3D11.Level_9_1.cs | 1028 ++++++++-------- ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 1074 +++++++++++------ ...iteEffect.bytecode.Direct3D11.Level_9_1.cs | 660 +++++----- .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 587 ++++++--- .../UIEffect.bytecode.Direct3D11.Level_9_1.cs | 698 ++++++----- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 820 +++++++++---- ...ffect.bytecodeSRgb.Direct3D11.Level_9_1.cs | 742 ++++++------ .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 819 +++++++++---- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 80 +- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 846 +++++++++---- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 98 +- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 888 +++++++++----- 14 files changed, 6396 insertions(+), 4014 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs index 99a954247b..6fec54d81b 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -21,72 +21,70 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, -97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, -114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, -0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, -114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, -193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, -54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 157, 124, 117, 145, 120, 218, 0, 73, 20, 130, 190, 217, 127, 164, 168, 138, 0, 212, 89, 0, 0, 68, 88, 66, 67, 134, 248, 72, 118, 248, 51, 205, 98, 109, 185, 203, 178, 177, 242, 240, 4, 1, 0, 0, 0, 212, 89, -0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, -40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, -0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, -255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, -0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, -0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, 0, 0, 104, 0, -0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, 0, 0, 105, 0, -0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 52, 0, 171, 171, 171, 1, 0, -3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, -0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, -255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, -255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, -0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, -0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, -0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, -67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, -0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, -0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, -228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, -0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, -0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, -170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, -85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, -8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, -15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, -0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, -16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, -0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, -0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, -0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, -16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, -16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, -128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, -16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, -16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, -16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, -0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, +79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, +84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, +115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, +145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, +65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 174, 205, 158, 188, 123, 235, 202, 149, 71, 78, 196, 231, 105, 150, 145, 241, 0, 212, 89, 0, 0, 68, 88, 66, 67, 203, 64, 10, 185, 180, 138, 80, 98, 98, 89, 110, 95, 238, 6, 39, 127, 1, 0, +0, 0, 212, 89, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, +40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, +0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, +121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, 49, 56, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, +0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, +0, 0, 92, 0, 0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, +0, 0, 97, 0, 0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, +0, 0, 104, 0, 0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, +0, 0, 105, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 49, 0, 171, +171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, +0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, +95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, +1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, +2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, +0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, +0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, +0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, +100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, +0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, +228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, +3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, +85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, +85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, +85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, +255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, +0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, +0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, +16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, +0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, +204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, +0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, +0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, +0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, +0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, +0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, +0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, +0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, +0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, +0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -94,7 +92,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -102,7 +100,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -110,7 +108,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -118,322 +116,322 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 251, 64, 95, 64, 131, 117, 74, 76, 174, 16, 216, 201, 202, 180, 228, 219, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 95, 142, 239, 253, 41, 117, 123, 65, 170, 59, 244, 190, 114, 112, 136, 242, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, -1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 224, 110, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 230, 247, 1, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, -97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, -111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, -49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, -32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, -46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, -32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, -114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, -10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, -115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, -32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, -46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, -32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, -101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, -32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, -122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, -105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 109, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, -0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, -115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 49, 102, 100, 102, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 111, 222, 218, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 82, 155, 10, 88, 184, 11, -0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, -116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, -112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, -0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, -4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, -84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 62, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 61, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, -0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, -13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, -3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, -9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, -5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, -40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, -6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, -0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, -0, 0, 16, 1, 26, 200, 105, 104, 217, 102, 98, 165, 136, 234, 14, 33, 45, 167, 214, 5, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, 0, 128, 104, 0, -0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, 0, 128, 236, 0, -0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, 0, 128, 44, 1, -0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, 0, 128, 188, 1, -0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, 0, 128, 40, 2, -0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, 0, 128, 152, 2, -0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, -0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, +0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 46, 126, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 235, 30, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, +10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, +48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, +120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, +32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, +32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, +102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, +97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, +10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, +105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, +83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, +95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, +83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 109, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, +49, 56, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, +100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 56, 54, 49, 56, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 62, 17, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 76, 199, +113, 166, 184, 11, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, +111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, +103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, +0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, +88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, +6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 62, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 61, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, +0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, +6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, +13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, +6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, +80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, +115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, +0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, +0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, +9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, +62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, +77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, +0, 0, 1, 0, 0, 0, 16, 1, 143, 60, 217, 68, 175, 128, 234, 231, 70, 160, 178, 129, 0, 115, 60, 198, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, +0, 128, 104, 0, 0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, +0, 128, 236, 0, 0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, +0, 128, 44, 1, 0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, +0, 128, 188, 1, 0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, +0, 128, 40, 2, 0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, +0, 128, 152, 2, 0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, +0, 0, 76, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, +0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, +116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, +3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, +1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, +24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 32, 80, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, +0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 112, 123, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, -0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, -242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, -0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, -8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, -0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 64, 78, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, -23, 21, 0, 0, 0, 0, 10, 2, 64, 78, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, +10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, +48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, +120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, +32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, +32, 45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +110, 88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, +102, 41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, +97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, +10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, +105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, +83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, +111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, +95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, +83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, -97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, -111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, -49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, -32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, -46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, -32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, -114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, -10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, -115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, -32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, -46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, -32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, -101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, -32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, -122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, -105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, +0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, +0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, -0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, +0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, -0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, +0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, -255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, +47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, +0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, +0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, 49, 56, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 95, 142, 239, 253, 41, 117, 123, 65, 170, 59, 244, 190, 114, 112, 136, 242, 134, 0, 0, 0, 47, 76, +105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 56, 54, +49, 56, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, -0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, -92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, -100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 49, 70, 68, 70, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 251, 64, 95, 64, 131, 117, 74, 76, 174, 16, 216, 201, 202, 180, 228, 219, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, -110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 49, 102, 100, 102, 56, 0, -4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 157, 12, 0, 0, 128, 0, +0, 0, 184, 11, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, +0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, +0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 157, 12, 0, 0, 128, 0, 0, 0, 184, 11, -0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 24, 0, -0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, -0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, +112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, +1, 0, 0, 0, 1, 23, 131, 166, 24, 217, 203, 25, 144, 208, 41, 94, 196, 172, 114, 40, 12, 0, 76, 87, 0, 0, 68, 88, 66, 67, 235, 87, 8, 75, 164, 122, 157, 160, 171, 179, 75, 16, 88, 194, 82, 81, 1, 0, 0, 0, 76, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, +0, 0, 168, 6, 0, 0, 176, 84, 0, 0, 44, 85, 0, 0, 252, 85, 0, 0, 172, 86, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, +48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, +0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 65, 66, 48, 57, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, +255, 255, 20, 4, 0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 90, 0, 0, 0, 44, 4, 0, 0, 90, 0, 0, 0, 60, 4, 0, 0, 90, 0, 0, 0, 76, 4, 0, 0, 90, 0, 0, 0, 92, 4, 0, 0, 124, 0, 0, 0, 108, 4, 0, 0, 124, 0, 0, 0, 128, 4, 0, 0, 126, 0, +0, 0, 140, 4, 0, 0, 126, 0, 0, 0, 152, 4, 0, 0, 128, 0, 0, 0, 164, 4, 0, 0, 129, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, +0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 5, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 56, 1, 0, 0, 88, 1, 0, 0, 104, 1, +0, 0, 120, 1, 0, 0, 56, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 132, 1, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 11, 0, +0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 13, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 14, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, +0, 171, 28, 2, 0, 0, 24, 1, 0, 0, 43, 2, 0, 0, 56, 1, 0, 0, 58, 2, 0, 0, 56, 1, 0, 0, 70, 2, 0, 0, 56, 1, 0, 0, 85, 2, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 4, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 226, 2, 0, 0, 56, 1, +0, 0, 242, 2, 0, 0, 24, 1, 0, 0, 251, 2, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 56, 1, 0, 0, 10, 3, 0, 0, 56, 1, 0, 0, 19, 3, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 28, 3, 0, 0, 6, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 172, 1, 0, 0, 7, 0, 0, 0, 188, 1, 0, 0, 0, 1, 0, 0, 16, 2, 0, 0, 140, 2, 0, 0, 5, 0, +0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 76, 3, 0, 0, 3, 0, 0, 0, 92, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, +49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, +0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, +0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, +228, 144, 1, 0, 0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, +0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, +16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, +0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, +0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, +0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, +0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, -105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, -114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, -82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, -1, 126, 48, 116, 243, 51, 240, 117, 229, 225, 171, 194, 108, 72, 39, 156, 65, 0, 76, 87, 0, 0, 68, 88, 66, 67, 189, 198, 129, 17, 136, 147, 20, 199, 106, 227, 136, 204, 59, 219, 183, 4, 1, 0, 0, 0, 76, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, 0, 0, 168, 6, -0, 0, 176, 84, 0, 0, 44, 85, 0, 0, 252, 85, 0, 0, 172, 86, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, -0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, 0, 0, 0, 1, -0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, -92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, 49, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, -0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 90, 0, 0, 0, 44, 4, 0, 0, 90, 0, 0, 0, 60, 4, 0, 0, 90, 0, 0, 0, 76, 4, 0, 0, 90, 0, 0, 0, 92, 4, 0, 0, 124, 0, 0, 0, 108, 4, 0, 0, 124, 0, 0, 0, 128, 4, 0, 0, 126, 0, 0, 0, 140, 4, -0, 0, 126, 0, 0, 0, 152, 4, 0, 0, 128, 0, 0, 0, 164, 4, 0, 0, 129, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, -0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, -0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 5, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 56, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 120, 1, -0, 0, 56, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 132, 1, 0, 0, 5, 0, 0, 0, 255, 255, 255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 11, 0, 0, 0, 0, 0, -1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 13, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 14, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 28, 2, -0, 0, 24, 1, 0, 0, 43, 2, 0, 0, 56, 1, 0, 0, 58, 2, 0, 0, 56, 1, 0, 0, 70, 2, 0, 0, 56, 1, 0, 0, 85, 2, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 100, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 4, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 226, 2, 0, 0, 56, 1, 0, 0, 242, 2, -0, 0, 24, 1, 0, 0, 251, 2, 0, 0, 56, 1, 0, 0, 4, 3, 0, 0, 56, 1, 0, 0, 10, 3, 0, 0, 56, 1, 0, 0, 19, 3, 0, 0, 104, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 28, 3, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, -255, 255, 7, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 0, 1, 0, 0, 172, 1, 0, 0, 7, 0, 0, 0, 188, 1, 0, 0, 0, 1, 0, 0, 16, 2, 0, 0, 140, 2, 0, 0, 5, 0, 0, 0, 156, 2, -0, 0, 0, 0, 0, 0, 216, 2, 0, 0, 76, 3, 0, 0, 3, 0, 0, 0, 92, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, -0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, 0, 3, 0, 0, -4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, -3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, -0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 104, 1, 0, 0, 64, 0, 1, 0, 90, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, -16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, -0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, -0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, -16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, -16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, -68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -441,7 +439,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -449,159 +447,159 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 133, 228, 159, 76, 56, 213, 48, 75, 139, 10, 183, 67, 222, 135, 216, 253, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, -51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 135, 248, 128, 150, 34, 27, 38, 73, 182, 255, 68, 231, 244, 93, 4, 150, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, -101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, -50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 103, 159, 1, 0, 193, 33, 3, 0, 65, 185, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, +32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, +115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 103, 159, 1, 0, 193, 33, 3, 0, 65, 185, +2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, -101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, -50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, -110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, -100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, -76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, -32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, -58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, -82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, -53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, -32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, -108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, -40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, -116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, -95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, -95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, -83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, -111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, +32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, +115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, +116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, +111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, +58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, +122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, +99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, +115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, +48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, +41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, +32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 50, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, +109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, +105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, +100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, +32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, +108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, +117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 26, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, -83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, 49, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, -101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 49, 56, -102, 54, 50, 49, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 213, 11, 221, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 228, 52, 138, 92, 101, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 26, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 65, 66, 48, 57, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, +111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, +97, 56, 51, 101, 97, 98, 48, 57, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 21, 176, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 195, 56, 168, 248, 101, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, -109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, -108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 124, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, -0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, 0, 0, 1, 0, -212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, -4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, -212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, -4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 148, 0, -0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 148, 0, -0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, -0, 0, 120, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 37, 6, 12, 12, 128, 128, 80, 8, 0, 13, 36, 1, 128, 228, 12, 128, 128, 0, 0, 38, 0, 77, 17, 244, 3, 0, 0, 116, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 2, 12, 128, 128, 80, 8, 0, -13, 23, 1, 128, 228, 12, 128, 128, 0, 0, 42, 0, 77, 17, 28, 4, 0, 0, 112, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 80, 8, 0, 9, 33, 13, 82, 1, 128, 228, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, -78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 56, 159, 94, 2, 31, 111, 248, 71, 170, 144, 244, 59, 253, 212, 114, 240, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, 0, 0, 18, 0, -0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 138, 0, 0, 128, 148, 0, 0, 0, 138, 0, 0, 0, 168, 0, 0, 0, 138, 0, 0, 128, 168, 0, 0, 0, 138, 0, 0, 0, 188, 0, 0, 0, 138, 0, 0, 128, 188, 0, 0, 0, 138, 0, 0, 0, 208, 0, 0, 0, 138, 0, 0, 128, 208, 0, -0, 0, 138, 0, 0, 0, 228, 0, 0, 0, 131, 0, 0, 128, 228, 0, 0, 0, 131, 0, 0, 0, 4, 1, 0, 0, 131, 0, 0, 128, 4, 1, 0, 0, 131, 0, 0, 0, 36, 1, 0, 0, 131, 0, 0, 128, 36, 1, 0, 0, 131, 0, 0, 0, 68, 1, 0, 0, 131, 0, 0, 128, 68, 1, -0, 0, 131, 0, 0, 0, 100, 1, 0, 0, 138, 0, 0, 128, 100, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 100, 0, -0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 11, 16, 0, 0, 1, 0, -1, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, +114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, +0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 124, 4, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 8, 16, 0, 0, 148, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, +62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 148, 0, +0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 60, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 40, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 148, 0, 0, 0, 1, 0, +212, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, +4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 148, 0, 0, 0, 1, 0, 212, 0, 8, 0, 0, 0, 38, 0, +77, 17, 136, 0, 0, 0, 120, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 37, 6, 12, 12, 128, 128, 80, 8, 0, 13, 36, 1, 128, 228, 12, 128, 128, 0, 0, 38, 0, 77, 17, 244, 3, 0, 0, 116, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 2, 12, 128, +128, 80, 8, 0, 13, 23, 1, 128, 228, 12, 128, 128, 0, 0, 42, 0, 77, 17, 28, 4, 0, 0, 112, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 80, 8, 0, 9, 33, 13, 82, 1, 128, 228, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, +78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 144, 164, 192, 113, 223, 255, 144, 9, 149, 242, 17, 6, 199, 220, 171, 211, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 104, 1, 0, 0, 0, 0, +0, 0, 18, 0, 0, 0, 228, 0, 0, 0, 148, 0, 0, 0, 138, 0, 0, 128, 148, 0, 0, 0, 138, 0, 0, 0, 168, 0, 0, 0, 138, 0, 0, 128, 168, 0, 0, 0, 138, 0, 0, 0, 188, 0, 0, 0, 138, 0, 0, 128, 188, 0, 0, 0, 138, 0, 0, 0, 208, 0, 0, 0, 138, 0, +0, 128, 208, 0, 0, 0, 138, 0, 0, 0, 228, 0, 0, 0, 131, 0, 0, 128, 228, 0, 0, 0, 131, 0, 0, 0, 4, 1, 0, 0, 131, 0, 0, 128, 4, 1, 0, 0, 131, 0, 0, 0, 36, 1, 0, 0, 131, 0, 0, 128, 36, 1, 0, 0, 131, 0, 0, 0, 68, 1, 0, 0, 131, 0, +0, 128, 68, 1, 0, 0, 131, 0, 0, 0, 100, 1, 0, 0, 138, 0, 0, 128, 100, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, +0, 0, 100, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 11, 16, +0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 16, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 22, 0, -27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, -242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, -3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, -0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 18, 216, 0, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 14, 16, 0, 0, 16, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 56, 0, 0, 0, 56, 0, 0, 0, 8, 0, 0, 0, 64, 0, 0, 0, 0, 0, +0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, +105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, +0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, +242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, +24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 18, 216, 0, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -609,71 +607,71 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, -110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, -100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, -76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, -32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, -58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, -95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, -82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, -53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, -32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, -108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, -40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, -116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, -95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, -61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, -32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, -95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, -83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, -111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, +116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, +111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, +58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, +122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, +99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, +115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, +48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, +41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, +114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, +32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 50, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, +109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, +105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, +100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, +32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, +110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, +108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, +117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, +101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, -1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, -0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, +0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, +77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, -1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, -0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 104, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, +0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, +77, 97, 105, 110, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -681,15 +679,15 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 13, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, -97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 13, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, +105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -697,31 +695,31 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, -101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 49, 56, 70, 54, 50, -49, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, +1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, +69, 65, 66, 48, 57, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 133, 228, 159, 76, 56, 213, 48, 75, 139, 10, 183, 67, 222, 135, 216, 253, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, -101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, -115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 49, 56, 102, 54, 50, 49, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, -17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 135, 248, 128, 150, 34, 27, 38, 73, 182, 255, 68, 231, 244, 93, 4, 150, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, +104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, +105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 97, 98, 48, 57, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, +0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 72, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 74, 13, 0, 0, 128, 0, 0, 0, 101, 12, 0, 0, 212, 5, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 44, 2, -0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 16, 0, -0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 22, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 33, 0, -0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 72, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 74, 13, 0, 0, 128, 0, 0, 0, 101, 12, 0, 0, 212, 5, 0, 0, 64, 0, 0, 0, 20, 0, 0, 0, 40, 0, +0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 35, 0, 0, 0, 21, 0, 0, 0, 20, 0, 0, 0, 34, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, +0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 7, 0, 0, 0, 22, 0, 0, 0, 29, 0, 0, 0, 30, 0, 0, 0, 31, 0, +0, 0, 33, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -737,17 +735,17 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, -114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, -100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, -0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, -171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, -0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, +0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, +32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, +0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, +90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index 13ba91884d..ffa470a8d9 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -34,343 +34,745 @@ public partial class SpriteBatch 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 165, 40, 204, 249, 226, 179, 69, 107, 49, 251, 74, 154, 222, 65, 188, 240, 0, 216, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, 0, 7, 0, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, -0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, -47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, -115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, -115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, -0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, -110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, -105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 43, 2, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, -112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, -0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, -119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, -120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, -0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 212, 0, -0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, 66, 97, 0, -0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, -54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, -110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, -111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, -0, 0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, -50, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, -4, 0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, -0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, -51, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, -7, 0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, -114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, -116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, -112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, -0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, -0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, -0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, -5, 0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, -8, 0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, -0, 0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, -95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, -97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, -95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, -0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, -97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, -0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, -0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, -6, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, -7, 0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, -115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, -0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, -12, 0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, -3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, -0, 0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, -6, 0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, -4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, -0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, -4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, -3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, -0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, -0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, -0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, -4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, -0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, -0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, -0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, -4, 0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, -4, 0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, -4, 0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, -128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, -184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, -78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, -4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, -4, 0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, -4, 0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, -4, 0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, -4, 0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, -4, 0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, -0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, -0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, -0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, -0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, -0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, -0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, -0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, -5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, -0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, -0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, -0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, -0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, -0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, -0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, -0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, -0, 0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, -0, 0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, -0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, -0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, -2, 0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, -0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, -0, 0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, -0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, -0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, -0, 0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, -0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, -3, 0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, -2, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, -0, 0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, -0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, -4, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, -0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, -0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, -3, 0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, -4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, -0, 0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, -5, 0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, -0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, -2, 0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, -6, 0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, -0, 0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, -0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, -0, 0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, -0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, -0, 0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, -4, 0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, -3, 0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, -0, 0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, -0, 0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, -0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, -5, 0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, -0, 0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, -4, 0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, -5, 0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, -0, 0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, -1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 165, 40, 204, 249, 226, 179, 69, 107, 49, 251, 74, 154, 222, 65, 188, 240, 0, 216, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, -0, 118, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, -0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, -0, 59, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, -0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, -0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, -0, 7, 0, 20, 0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, -0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, -0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, -116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, -116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, -114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, -0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, -0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, -0, 189, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, -51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, -0, 5, 0, 7, 0, 212, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, -0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, -0, 96, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, -0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, -62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, -95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, -0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, -0, 110, 89, 0, 0, 5, 0, 4, 0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, -0, 5, 0, 4, 0, 5, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, -0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, -108, 111, 114, 0, 0, 5, 0, 7, 0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, -0, 48, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, -0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, -0, 54, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, -0, 6, 0, 5, 0, 54, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -0, 5, 0, 5, 0, 56, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, -122, 122, 108, 101, 0, 5, 0, 8, 0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, -0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, -0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, -0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, -0, 82, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, -0, 5, 0, 6, 0, 85, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, -0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, -0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, -0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 6, 0, 7, 0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, -0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, -0, 91, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, -86, 83, 0, 0, 0, 5, 0, 12, 0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, -95, 53, 0, 0, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, -0, 51, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, -0, 77, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, -0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, -78, 0, 0, 0, 0, 71, 0, 4, 0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 5, 0, 85, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, -0, 71, 0, 4, 0, 87, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, -0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, -0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, -0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, -0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, -0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, -0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, -0, 5, 0, 0, 0, 33, 0, 4, 0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, -0, 194, 44, 77, 60, 23, 0, 4, 0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, -0, 4, 0, 0, 0, 33, 0, 4, 0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, -0, 5, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, -0, 77, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, -0, 107, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, -0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, -0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, -0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, -0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, -0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, -0, 43, 0, 0, 0, 32, 0, 4, 0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, -0, 139, 0, 0, 0, 105, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, -0, 46, 2, 0, 0, 45, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 53, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 80, 2, 0, 0, 79, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 50, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 92, 2, 0, 0, 93, 2, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 136, 0, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, -0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, -0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, -0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, -0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, -0, 59, 0, 4, 0, 212, 0, 0, 0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 62, 0, 3, 0, 231, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, -0, 210, 0, 0, 0, 238, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, -0, 129, 0, 5, 0, 210, 0, 0, 0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, -0, 129, 0, 5, 0, 210, 0, 0, 0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, -0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 251, 0, 0, 0, 250, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, -0, 181, 1, 0, 0, 182, 1, 0, 0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 195, 1, 0, 0, 194, 1, 0, 0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, -0, 182, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, -0, 211, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, -0, 29, 2, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, -0, 12, 0, 6, 0, 5, 0, 0, 0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, -0, 213, 1, 0, 0, 214, 1, 0, 0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, -0, 212, 1, 0, 0, 248, 0, 2, 0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, -0, 231, 1, 0, 0, 230, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, -0, 235, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, -0, 232, 1, 0, 0, 239, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, -0, 241, 1, 0, 0, 62, 0, 3, 0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, -0, 251, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, -0, 0, 2, 0, 0, 252, 1, 0, 0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, -0, 2, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 7, 2, 0, 0, 249, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, -0, 224, 1, 0, 0, 248, 0, 2, 0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, -0, 16, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, -0, 19, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, -0, 4, 0, 0, 0, 26, 2, 0, 0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, -0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 32, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, -0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 39, 2, 0, 0, 29, 2, 0, 0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, -0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, -0, 49, 2, 0, 0, 62, 0, 3, 0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, -0, 94, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, -0, 97, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, -0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 103, 2, 0, 0, 84, 2, 0, 0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, -0, 106, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, -0, 109, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, -0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 115, 2, 0, 0, 114, 2, 0, 0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, -0, 117, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, +100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, +47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, +105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, +46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, +95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, +38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, +80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, +105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, +73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, +101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, +103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, +32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, +117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, +115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, +102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, +101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, +78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, +32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, +105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, +32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, +97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, +100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, +0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, +110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, +114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, +77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, +101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, +115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, +122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, +101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, +54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, +67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, +98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, +47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, +79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, +78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, +69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, +77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, +67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, +32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, +32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, +10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, +111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, +105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, +111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, +102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, +117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, +77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, +105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, +70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, +112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, +115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, +69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, +111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, +116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, +50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, +101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, +42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, +32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, +56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, +101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, +116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, +97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, +111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, +97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, +108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, +32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, +105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, +49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, +101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, +40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, +83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, +32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, +55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, +32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, +48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, +117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, +111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, +32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, +52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, +101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, +41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, +32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, +111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, +40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, +108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, +102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, +13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, +32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, +77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, +67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, +32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, +32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, +58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, +101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, +104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, +120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, +99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, +45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, +45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, +32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, +111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, +97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, +40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, +101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, +46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, +59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, +7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, +7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, +0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, +84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, +0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, +0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, +114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, +4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, +83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, +101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, +49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, +108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, +0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, +0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, +0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, +97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, +6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, +67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, +95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, +0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, +0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, +0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, +6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, +83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, +4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, +6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, +116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, +6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, +0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, +0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, +6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, +0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, +105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, +0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, +5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, +0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, +0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, +0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, +0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, +0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, +0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, +0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, +0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, +0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, +4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, +0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, +0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, +2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, +0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, +3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, +0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, +0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, +4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, +4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, +4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, +0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, +0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, +0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, +0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, +0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, +0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, +0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, +0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, +0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, +0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, +0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, +0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, +0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, +0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, +0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, +0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, +6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, +6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, +5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, +0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, +0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, +0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, +0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, +0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, +0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, +4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, +0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, +4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, +0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, +5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, +0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, +2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, +0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, +5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, +0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, +0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, +0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, +0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, +0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, +0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, +0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, +0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, +0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, +0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, +0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, +0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, +5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, +2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, +0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, +0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, +0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, +0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, +0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, +3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, +0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, +0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, +3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, +0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, +0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, +111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, +115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, +116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, +78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, +68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, +47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, +32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, +83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, +104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, +112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, +117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, +76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, +73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, +97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, +41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, +47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, +115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, +116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, +47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, +116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, +0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, +108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, +108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, +117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, +80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, +95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, +13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, +101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, +65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, +109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, +79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, +10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, +116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, +101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, +101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, +32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, +125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, +97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, +115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, +111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, +109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, +32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, +32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, +80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, +116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, +69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, +104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, +99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, +76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, +114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, +13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, +105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, +46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, +112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, +71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, +10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, +103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, +99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, +108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, +97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, +40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, +82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, +99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, +13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, +84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, +108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, +113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, +114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, +102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, +110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, +98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, +32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, +44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, +115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, +111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, +108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, +48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, +0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, +101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, +112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, +73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, +115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, +82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, +32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, +109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, +117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, +102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, +114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, +115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, +115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, +32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, +105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, +115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, +32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, +32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, +97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, +101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, +97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, +13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, +0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, +0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, +0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, +105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, +0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, +111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, +0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, +0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, +62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, +116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, +97, 116, 95, 49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, +95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, +95, 49, 0, 0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, +0, 242, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, +95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, +102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, +0, 5, 0, 6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, +0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, +0, 45, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, +0, 46, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, +0, 47, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 6, 0, 6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, +62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +0, 5, 0, 6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, +0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, +0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, +95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, +0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, +0, 80, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +0, 6, 0, 6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, +100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, +0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, +83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, +0, 0, 22, 5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, +0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, +0, 73, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, +0, 3, 0, 0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, +0, 77, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, +0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, +0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, +0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, +0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, +0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, +0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, +0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, +0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, +0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, +0, 5, 0, 0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, +0, 208, 0, 0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, +63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, +63, 43, 0, 4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, +59, 43, 0, 4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, +0, 5, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, +0, 5, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, +0, 37, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, +0, 45, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, +0, 48, 2, 0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, +0, 80, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, +0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, +0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, +0, 6, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, +0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, +0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, +0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, +0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, +0, 66, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, +0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, +0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, +0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, +0, 227, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, +0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, +0, 80, 0, 6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, +0, 80, 0, 6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, +0, 81, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, +0, 192, 0, 0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, +0, 248, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, +0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, +0, 173, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, +0, 9, 0, 0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 182, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, +0, 4, 0, 0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, +0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, +0, 8, 0, 4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, +0, 200, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, +0, 250, 0, 4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, +0, 217, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, +0, 226, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, +0, 248, 0, 2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, +0, 5, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, +0, 65, 0, 5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 241, 1, 0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, +0, 5, 0, 0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 247, 1, 0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, +0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, +0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, +0, 152, 1, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, +0, 4, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, +0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, +0, 5, 0, 0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, +0, 8, 2, 0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, +0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, +0, 197, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, +0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, +0, 8, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 29, 2, 0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, +0, 129, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, +0, 254, 0, 2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, +0, 55, 2, 0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 61, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 65, 2, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, +0, 62, 0, 3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, +0, 74, 0, 0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, +0, 62, 0, 3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs index d060e74911..d4ff445b13 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -21,72 +21,70 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, -97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, -114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, -0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, -83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, -114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, -193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, -54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 230, 110, 102, 238, 206, 20, 39, 1, 180, 20, 102, 188, 241, 12, 105, 41, 0, 212, 89, 0, 0, 68, 88, 66, 67, 41, 58, 3, 77, 142, 179, 65, 127, 140, 95, 49, 109, 120, 241, 116, 92, 1, 0, 0, 0, 212, 89, -0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, -40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, -0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, -255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, -0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, -0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, 0, 0, 104, 0, -0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, 0, 0, 105, 0, -0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 52, 0, 171, 171, 171, 1, 0, -3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, -0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 10, 0, -255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, 2, 0, 255, 255, -255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, 0, 0, 1, 0, -0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, 0, 0, 68, 2, -0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, 0, 0, 20, 2, -0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, -67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, -0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, -0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, 3, 128, 1, 0, -228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 85, 128, 4, 0, -0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, -0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, 85, 128, 0, 0, -170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, 255, 129, 0, 0, -85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, 0, 4, 0, 0, -8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, 0, 2, 0, 8, -15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, -0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 10, 114, 0, -16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, 204, 61, 0, 0, -0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 54, 0, -0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, 0, 1, 50, 0, -0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, 0, 7, 146, 0, -16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, -16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, -128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, 0, 9, 194, 0, -16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, -16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, 0, 0, 70, 30, -16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, -0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, +79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, 0, 13, 66, 65, +84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, +115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, +145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, +65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 44, 221, 241, 81, 241, 33, 215, 45, 200, 53, 238, 148, 98, 130, 170, 208, 0, 212, 89, 0, 0, 68, 88, 66, 67, 111, 133, 219, 51, 141, 56, 50, 214, 61, 220, 173, 190, 134, 58, 210, 67, 1, 0, +0, 0, 212, 89, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, +40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, +0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, +121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, 65, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, +0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, +0, 0, 92, 0, 0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, +0, 0, 97, 0, 0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, +0, 0, 104, 0, 0, 0, 48, 6, 0, 0, 104, 0, 0, 0, 60, 6, 0, 0, 104, 0, 0, 0, 72, 6, 0, 0, 104, 0, 0, 0, 84, 6, 0, 0, 104, 0, 0, 0, 104, 6, 0, 0, 105, 0, 0, 0, 124, 6, 0, 0, 105, 0, 0, 0, 136, 6, 0, 0, 105, 0, 0, 0, 148, 6, +0, 0, 105, 0, 0, 0, 168, 6, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 95, 52, 54, 49, 0, 171, +171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 171, 34, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 25, 2, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 2, 0, 0, 35, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 110, 88, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, +0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 255, 255, 255, 255, 0, 0, 255, 255, 110, 89, 0, 171, 13, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 110, 90, 0, 171, 19, 0, 0, 0, 255, 255, 0, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, +95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 171, 171, 171, 156, 2, 0, 0, 172, 2, 0, 0, 188, 2, 0, 0, 224, 1, 0, 0, 200, 2, 0, 0, 224, 1, 0, 0, 215, 2, 0, 0, 84, 2, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 232, 2, 0, 0, 2, 0, 0, 0, 0, 0, +1, 0, 10, 0, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 4, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 33, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 171, 171, 171, 20, 0, 0, 0, 255, 255, +2, 0, 255, 255, 255, 255, 22, 0, 0, 0, 255, 255, 2, 0, 255, 255, 255, 255, 23, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 30, 0, 0, 0, 255, 255, 1, 0, 2, 0, 255, 255, 31, 0, 0, 0, 255, 255, 255, 255, 255, 255, 3, 0, 0, 0, 0, 0, 168, 1, 0, 0, 188, 1, +0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 20, 2, 0, 0, 52, 2, 0, 0, 1, 0, +0, 0, 68, 2, 0, 0, 0, 0, 0, 0, 80, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 100, 2, 0, 0, 0, 0, 0, 0, 112, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 116, 2, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 84, 2, 0, 0, 1, 0, 0, 0, 132, 2, +0, 0, 20, 2, 0, 0, 144, 2, 0, 0, 8, 3, 0, 0, 4, 0, 0, 0, 24, 3, 0, 0, 0, 0, 0, 0, 72, 3, 0, 0, 224, 1, 0, 0, 5, 0, 0, 0, 88, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, +100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 0, 0, 128, 191, 205, 204, 204, 61, 0, 0, 0, 192, 0, 0, 0, 64, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 63, 0, 0, 64, 192, 0, 0, 0, 0, 0, 0, +0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 128, 2, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, +228, 160, 2, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 160, 35, 0, 0, 2, 1, 0, 1, 128, 1, 0, 255, 128, 2, 0, 0, 3, 1, 0, 2, 128, 0, 0, 170, 176, 0, 0, 0, 160, 35, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 2, 0, 0, 3, 1, 0, +3, 128, 1, 0, 228, 129, 0, 0, 85, 160, 88, 0, 0, 4, 0, 0, 15, 128, 1, 0, 85, 128, 0, 0, 0, 128, 0, 0, 228, 128, 4, 0, 0, 4, 1, 0, 2, 128, 0, 0, 85, 128, 0, 0, 255, 160, 0, 0, 0, 160, 5, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, +85, 128, 4, 0, 0, 4, 1, 0, 4, 128, 0, 0, 0, 128, 0, 0, 255, 160, 0, 0, 0, 160, 4, 0, 0, 4, 1, 0, 18, 128, 1, 0, 170, 128, 1, 0, 170, 128, 1, 0, 85, 128, 7, 0, 0, 2, 1, 0, 2, 128, 1, 0, 85, 128, 6, 0, 0, 2, 1, 0, 2, 128, 1, 0, +85, 128, 2, 0, 0, 3, 1, 0, 2, 128, 1, 0, 85, 129, 0, 0, 0, 161, 4, 0, 0, 4, 1, 0, 2, 128, 1, 0, 85, 128, 1, 0, 0, 160, 1, 0, 0, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 88, 0, 0, 4, 2, 0, 2, 128, 1, 0, 0, 128, 1, 0, +85, 128, 0, 0, 170, 128, 88, 0, 0, 4, 2, 0, 4, 128, 1, 0, 0, 128, 1, 0, 170, 128, 0, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 0, 0, 170, 176, 1, 0, 85, 160, 35, 0, 0, 2, 2, 0, 8, 128, 2, 0, 255, 128, 2, 0, 0, 3, 2, 0, 8, 128, 2, 0, +255, 129, 0, 0, 85, 160, 1, 0, 0, 2, 1, 0, 4, 128, 0, 0, 0, 161, 1, 0, 0, 2, 2, 0, 1, 128, 0, 0, 85, 128, 1, 0, 0, 2, 1, 0, 3, 128, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 6, 128, 2, 0, 255, 128, 1, 0, 210, 128, 2, 0, 210, 128, 88, 0, +0, 4, 0, 0, 8, 128, 2, 0, 255, 128, 1, 0, 170, 128, 2, 0, 170, 128, 1, 0, 0, 2, 0, 0, 1, 128, 1, 0, 85, 128, 1, 0, 0, 2, 1, 0, 15, 128, 1, 0, 228, 176, 4, 0, 0, 4, 0, 0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 128, 2, 0, 228, 176, 1, 0, +0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 192, 2, 0, 0, 64, 0, 0, 0, 176, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, +16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, 0, 0, 0, +0, 10, 114, 0, 16, 0, 0, 0, 0, 0, 166, 26, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 192, 0, 0, 64, 192, 0, 0, 0, 0, 29, 0, 0, 11, 114, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 205, 204, 204, 61, 205, 204, 204, 61, 205, 204, +204, 61, 0, 0, 0, 0, 70, 2, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 31, 0, 4, 3, 10, 0, 16, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, +0, 0, 54, 0, 0, 5, 242, 0, 16, 0, 2, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 18, 0, 0, 1, 69, 0, 0, 9, 242, 0, 16, 0, 2, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 21, 0, +0, 1, 50, 0, 0, 15, 146, 0, 16, 0, 0, 0, 0, 0, 6, 4, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 2, 64, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 191, 56, 0, +0, 7, 146, 0, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 6, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 18, 0, 16, 0, 0, 0, +0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 128, 65, 0, 0, 0, 0, 0, 0, 0, 1, 64, +0, 0, 0, 0, 128, 63, 50, 0, 0, 9, 66, 0, 16, 0, 1, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 1, 64, 0, 0, 0, 0, 0, 63, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 55, 0, +0, 9, 194, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, 0, 0, 0, 166, 14, 16, 0, 1, 0, 0, 0, 166, 14, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 66, 0, 16, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, 54, 0, 0, 5, 34, 0, 16, 0, 1, 0, +0, 0, 26, 0, 16, 0, 2, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 2, 0, 0, 0, 166, 10, 16, 0, 0, 0, 0, 0, 6, 8, 16, 0, 2, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 50, 0, 0, 9, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 2, 0, +0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, +0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -94,7 +92,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -102,7 +100,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -110,7 +108,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -118,326 +116,326 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 144, 133, 76, 21, 226, 153, 238, 70, 128, 57, 7, 56, 78, 252, 242, 26, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 156, 151, 27, 141, 196, 84, 124, 68, 132, 141, 120, 231, 213, 56, 231, 134, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, -1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 84, 60, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 66, 179, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, -97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, -111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, -52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, -49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, -32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, -48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, -40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, -46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, -32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, -116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, -123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, -120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, -102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, -114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, -32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, -122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 107, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, -0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, -115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 97, 56, 100, 50, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, -116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 4, 27, 216, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 180, 163, 63, 131, 182, 11, -0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, -116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, -112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 8, 16, -0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 36, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 104, 0, -0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, -4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 10, 12, 130, -84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 61, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 60, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, 0, 0, 140, 6, -0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, 6, 4, 3, 60, -13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, 13, 5, 6, 2, -3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, 6, 2, 3, 32, -9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, 80, 17, 0, 0, -5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, -80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, 0, 0, 1, 0, -40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, -6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, 77, 17, 220, 2, -0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, -0, 0, 16, 1, 82, 3, 152, 165, 246, 198, 226, 74, 24, 39, 198, 133, 161, 74, 251, 149, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, 0, 128, 104, 0, -0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, 0, 128, 236, 0, -0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, 0, 128, 44, 1, -0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, 0, 128, 188, 1, -0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, 0, 128, 40, 2, -0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, 0, 128, 152, 2, -0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, -0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, +0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 226, 82, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 235, 30, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, +10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, +49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, +59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, +45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, +88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, +111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, +41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, +98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, +32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, +119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, +100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, +104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, +114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, +83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, +117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 107, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, +65, 69, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, +100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 102, 97, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, +59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 62, 17, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 44, 203, +120, 44, 182, 11, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, +111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, +103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 152, 6, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 88, 2, +0, 0, 8, 16, 0, 0, 104, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 24, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 104, 0, 0, 0, 1, 0, +88, 2, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, +4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 8, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 104, 0, 0, 0, 1, 0, 88, 2, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 148, 6, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, +6, 10, 12, 130, 84, 0, 8, 0, 13, 23, 1, 104, 12, 130, 84, 0, 0, 0, 38, 0, 77, 17, 140, 2, 0, 0, 144, 6, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 61, 11, 32, 4, 130, 84, 8, 0, 9, 29, 13, 60, 1, 104, 12, 130, 84, 0, 0, 222, 0, 77, 17, 180, 2, +0, 0, 140, 6, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 72, 6, 38, 3, 0, 6, 35, 3, 84, 9, 9, 13, 41, 11, 76, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 36, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 9, 13, 50, 6, 10, 3, 4, 13, 73, +6, 4, 3, 60, 13, 44, 6, 2, 3, 128, 136, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 13, 78, 6, 2, 12, 36, 76, 8, 0, 9, 13, 13, 36, 1, 104, 6, 11, 3, 0, 9, 9, 13, 71, 3, 40, 9, 5, 13, 72, 6, 35, 3, 44, 9, 16, 13, 35, 11, 76, 9, 5, +13, 5, 6, 2, 3, 36, 9, 16, 13, 35, 6, 6, 3, 24, 9, 5, 13, 5, 6, 2, 3, 36, 9, 20, 13, 49, 6, 10, 3, 4, 9, 51, 13, 57, 6, 4, 3, 60, 9, 38, 13, 58, 3, 28, 9, 32, 13, 71, 3, 28, 9, 27, 13, 72, 3, 28, 9, 20, 3, 20, 9, 26, 13, 43, +6, 2, 3, 32, 9, 5, 13, 5, 6, 2, 3, 36, 6, 10, 3, 56, 9, 25, 13, 77, 6, 2, 12, 36, 76, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 54, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 0, 1, 0, 0, 1, 0, 192, 1, 4, 0, 36, 0, 32, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 36, 0, 0, 0, 26, 0, +80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 0, 1, 0, 0, 1, 0, 96, 1, 4, 0, 36, 0, 40, 0, 0, 0, 26, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 0, 1, 0, 0, 1, 0, 152, 1, 4, 0, 36, 0, 44, 0, 0, 0, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, +115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 20, 2, 0, 0, 1, 0, 132, 0, 24, 0, +0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 76, 2, 0, 0, 1, 0, 76, 0, 28, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 36, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 152, 2, +0, 0, 1, 0, 40, 0, 40, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 152, 2, 0, 0, 1, 0, 40, 0, 44, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 104, 1, 0, 0, 1, 0, 28, 0, 12, 0, 0, 0, 42, 0, 62, 17, 64, 0, 0, 0, 0, 0, 110, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 240, 1, 0, 0, 1, 0, 208, 0, 0, 0, 0, 0, 38, 0, 77, 17, 220, 2, 0, 0, 92, 6, 0, 0, 3, 16, 0, 0, 7, 0, +9, 5, 13, 76, 6, 2, 12, 36, 96, 8, 0, 9, 12, 13, 75, 1, 128, 200, 12, 36, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, +62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 236, 0, 0, 0, 1, 0, 20, 0, 16, 0, 0, 0, 2, 0, 78, 17, 38, 0, +77, 17, 220, 2, 0, 0, 136, 6, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 2, 12, 36, 128, 156, 8, 0, 9, 12, 13, 75, 1, 129, 4, 12, 36, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, +0, 0, 1, 0, 0, 0, 16, 1, 44, 141, 92, 112, 59, 203, 54, 23, 144, 245, 239, 67, 41, 8, 151, 107, 0, 0, 242, 0, 0, 0, 40, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 2, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 28, 2, 0, 0, 104, 0, 0, 0, 130, 0, +0, 128, 104, 0, 0, 0, 130, 0, 0, 0, 144, 0, 0, 0, 130, 0, 0, 128, 144, 0, 0, 0, 130, 0, 0, 0, 188, 0, 0, 0, 130, 0, 0, 128, 188, 0, 0, 0, 130, 0, 0, 0, 200, 0, 0, 0, 130, 0, 0, 128, 200, 0, 0, 0, 130, 0, 0, 0, 236, 0, 0, 0, 130, 0, +0, 128, 236, 0, 0, 0, 130, 0, 0, 0, 0, 1, 0, 0, 130, 0, 0, 128, 0, 1, 0, 0, 130, 0, 0, 0, 4, 1, 0, 0, 130, 0, 0, 128, 4, 1, 0, 0, 130, 0, 0, 0, 40, 1, 0, 0, 130, 0, 0, 128, 40, 1, 0, 0, 130, 0, 0, 0, 44, 1, 0, 0, 130, 0, +0, 128, 44, 1, 0, 0, 130, 0, 0, 0, 104, 1, 0, 0, 130, 0, 0, 128, 104, 1, 0, 0, 130, 0, 0, 0, 132, 1, 0, 0, 130, 0, 0, 128, 132, 1, 0, 0, 130, 0, 0, 0, 160, 1, 0, 0, 130, 0, 0, 128, 160, 1, 0, 0, 130, 0, 0, 0, 188, 1, 0, 0, 130, 0, +0, 128, 188, 1, 0, 0, 130, 0, 0, 0, 208, 1, 0, 0, 130, 0, 0, 128, 208, 1, 0, 0, 130, 0, 0, 0, 240, 1, 0, 0, 130, 0, 0, 128, 240, 1, 0, 0, 130, 0, 0, 0, 20, 2, 0, 0, 130, 0, 0, 128, 20, 2, 0, 0, 130, 0, 0, 0, 40, 2, 0, 0, 130, 0, +0, 128, 40, 2, 0, 0, 130, 0, 0, 0, 76, 2, 0, 0, 130, 0, 0, 128, 76, 2, 0, 0, 130, 0, 0, 0, 96, 2, 0, 0, 130, 0, 0, 128, 96, 2, 0, 0, 130, 0, 0, 0, 116, 2, 0, 0, 130, 0, 0, 128, 116, 2, 0, 0, 130, 0, 0, 0, 152, 2, 0, 0, 130, 0, +0, 128, 152, 2, 0, 0, 130, 0, 0, 0, 188, 2, 0, 0, 133, 0, 0, 128, 188, 2, 0, 0, 133, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 115, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 3, 16, 0, 0, 0, 0, +0, 0, 76, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, +0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, +116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, +3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, +1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, +24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 76, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, +0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 112, 123, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 212, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, -0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, -242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, -0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, -8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, -0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 112, 82, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, -23, 21, 0, 0, 0, 0, 10, 2, 112, 82, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, +58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, +10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, +49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, +59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 49, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 49, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, +45, 32, 50, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, +88, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, +111, 108, 111, 114, 46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, +41, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, +98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, +32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 120, 120, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, +119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, +100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, +104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, +114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, +115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, +83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, +117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, -88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, -97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, -111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, -52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, -49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 120, 120, 120, 120, 59, 10, 32, 32, -32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 54, 52, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 54, 52, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 46, -48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, -40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, -46, 121, 32, 42, 32, 50, 46, 48, 102, 41, 32, 45, 32, 49, 46, 48, 102, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, 102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 46, 48, 102, 32, 45, 32, 115, 113, 114, 116, 40, 99, 108, 97, 109, 112, 40, 40, 110, 88, 32, 42, 32, 110, 88, 41, 32, 43, 32, 40, 110, 89, 32, 42, 32, 110, 89, 41, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 41, 59, 10, -32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 122, 32, 61, 32, 40, 110, 90, 32, 42, 32, 48, 46, 53, 102, 41, 32, 43, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, -116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 46, 48, 102, 41, 32, 60, 61, 32, 48, 46, 49, 48, 48, 48, 48, 48, 48, 48, 49, 52, 57, 48, 49, 49, 54, 49, 49, 57, 51, 56, 52, 55, 54, 53, 54, 50, 53, 102, 41, 10, 32, 32, 32, 32, -123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, -120, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 120, 120, 46, 121, 44, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 119, 32, 61, 32, -102, 108, 111, 97, 116, 40, 49, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 40, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 41, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, -114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, -32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, -122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, +0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, +0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 132, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, -0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, +0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, -0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, +0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, -255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, +47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, +0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, +0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, 65, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 156, 151, 27, 141, 196, 84, 124, 68, 132, 141, 120, 231, 213, 56, 231, 134, 134, 0, 0, 0, 47, 76, +105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 102, +97, 101, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 156, 6, -0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, -92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, -100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 65, 56, 68, 50, 65, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 144, 133, 76, 21, 226, 153, 238, 70, 128, 57, 7, 56, 78, 252, 242, 26, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, -110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 97, 56, 100, 50, 97, 48, 0, -4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 155, 12, 0, 0, 128, 0, +0, 0, 182, 11, 0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, +0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, +0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 12, 2, 0, 0, 111, 1, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 155, 12, 0, 0, 128, 0, 0, 0, 182, 11, -0, 0, 68, 9, 0, 0, 88, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 14, 0, 0, 0, 6, 0, 0, 0, 24, 0, -0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 15, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, -0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, +120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, +112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, +88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, +1, 0, 0, 0, 1, 29, 116, 212, 60, 199, 159, 70, 117, 135, 226, 199, 201, 222, 184, 128, 203, 0, 88, 88, 0, 0, 68, 88, 66, 67, 168, 0, 210, 170, 66, 231, 81, 30, 33, 105, 195, 86, 70, 242, 200, 250, 1, 0, 0, 0, 88, 88, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, +0, 0, 180, 7, 0, 0, 188, 85, 0, 0, 56, 86, 0, 0, 8, 87, 0, 0, 184, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, +48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, +0, 0, 32, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, 0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, +255, 255, 76, 4, 0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 90, 0, 0, 0, 112, 4, 0, 0, 96, 0, 0, 0, 128, 4, 0, 0, 96, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 168, 4, 0, 0, 90, 0, 0, 0, 184, 4, 0, 0, 90, 0, +0, 0, 200, 4, 0, 0, 90, 0, 0, 0, 216, 4, 0, 0, 124, 0, 0, 0, 232, 4, 0, 0, 124, 0, 0, 0, 252, 4, 0, 0, 126, 0, 0, 0, 8, 5, 0, 0, 126, 0, 0, 0, 20, 5, 0, 0, 96, 0, 0, 0, 32, 5, 0, 0, 129, 0, 0, 0, 44, 5, 0, 0, 109, 97, +105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, +0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, +110, 0, 37, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 88, 1, 0, 0, 120, 1, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 88, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 164, 1, 0, 0, 6, 0, 0, 0, 255, 255, +255, 255, 13, 0, 255, 255, 9, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 13, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 15, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 16, 0, 0, 0, 255, 255, 255, 255, 10, 0, +255, 255, 17, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 18, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, +105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 72, 2, 0, 0, 56, 1, 0, 0, 87, 2, 0, 0, 88, 1, 0, 0, 102, 2, +0, 0, 88, 1, 0, 0, 114, 2, 0, 0, 88, 1, 0, 0, 129, 2, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 144, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, +0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 5, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, +111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 14, 3, 0, 0, 88, 1, 0, 0, 30, 3, 0, 0, 56, 1, 0, 0, 39, 3, 0, 0, 88, 1, 0, 0, 48, 3, +0, 0, 88, 1, 0, 0, 54, 3, 0, 0, 88, 1, 0, 0, 63, 3, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 72, 3, 0, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 11, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 12, 0, +0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 32, 1, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 220, 1, 0, 0, 32, 1, 0, 0, 60, 2, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 200, 2, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 120, 3, 0, 0, 3, 0, +0, 0, 136, 3, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, +77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, +15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 1, 0, +7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, +3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, +0, 2, 2, 0, 15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, +16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, +0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, +16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, +0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, +77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, +0, 0, 70, 30, 16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, +32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, +32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, +0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 22, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, -105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, -114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, -82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, -1, 187, 67, 94, 69, 16, 128, 187, 174, 140, 86, 231, 247, 12, 157, 171, 5, 0, 88, 88, 0, 0, 68, 88, 66, 67, 175, 44, 248, 4, 18, 108, 254, 90, 234, 183, 239, 103, 250, 116, 180, 166, 1, 0, 0, 0, 88, 88, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 180, 7, -0, 0, 188, 85, 0, 0, 56, 86, 0, 0, 8, 87, 0, 0, 184, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, -0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, 0, 0, 32, 1, -0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, -92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, 0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, 255, 255, 76, 4, -0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 90, 0, 0, 0, 112, 4, 0, 0, 96, 0, 0, 0, 128, 4, 0, 0, 96, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 168, 4, 0, 0, 90, 0, 0, 0, 184, 4, 0, 0, 90, 0, 0, 0, 200, 4, -0, 0, 90, 0, 0, 0, 216, 4, 0, 0, 124, 0, 0, 0, 232, 4, 0, 0, 124, 0, 0, 0, 252, 4, 0, 0, 126, 0, 0, 0, 8, 5, 0, 0, 126, 0, 0, 0, 20, 5, 0, 0, 96, 0, 0, 0, 32, 5, 0, 0, 129, 0, 0, 0, 44, 5, 0, 0, 109, 97, 105, 110, 0, 111, -117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, -0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 37, 1, -0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 104, 1, 0, 0, 88, 1, 0, 0, 120, 1, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 88, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 164, 1, 0, 0, 6, 0, 0, 0, 255, 255, 255, 255, 13, 0, -255, 255, 9, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 13, 0, 0, 0, 11, 0, 12, 0, 255, 255, 255, 255, 14, 0, 0, 0, 255, 255, 255, 255, 255, 255, 14, 0, 15, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 16, 0, 0, 0, 255, 255, 255, 255, 10, 0, 255, 255, 17, 0, -0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 18, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, -105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 72, 2, 0, 0, 56, 1, 0, 0, 87, 2, 0, 0, 88, 1, 0, 0, 102, 2, 0, 0, 88, 1, -0, 0, 114, 2, 0, 0, 88, 1, 0, 0, 129, 2, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 15, 0, 1, 0, 5, 0, 144, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, -7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 11, 0, 12, 0, 13, 0, 5, 0, 0, 0, 14, 0, 255, 255, 255, 255, 255, 255, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, -0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 83, 119, 105, 122, 122, 108, 101, 0, 171, 14, 3, 0, 0, 88, 1, 0, 0, 30, 3, 0, 0, 56, 1, 0, 0, 39, 3, 0, 0, 88, 1, 0, 0, 48, 3, 0, 0, 88, 1, -0, 0, 54, 3, 0, 0, 88, 1, 0, 0, 63, 3, 0, 0, 136, 1, 0, 0, 5, 0, 0, 0, 1, 0, 19, 0, 1, 0, 6, 0, 72, 3, 0, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 11, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 12, 0, 0, 0, 255, 255, -255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 32, 1, 0, 0, 204, 1, 0, 0, 8, 0, 0, 0, 220, 1, 0, 0, 32, 1, 0, 0, 60, 2, 0, 0, 184, 2, 0, 0, 5, 0, 0, 0, 200, 2, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 120, 3, 0, 0, 3, 0, 0, 0, 136, 3, -0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 5, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, 44, 77, 60, 0, 0, -0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 31, 0, 0, 2, 5, 0, 4, 128, 4, 0, 15, 144, 9, 0, -0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 5, 0, 0, 160, 5, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 5, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, -228, 128, 2, 0, 228, 144, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, -170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 4, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 2, 0, -15, 224, 3, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 248, 1, 0, 0, 64, 0, 1, 0, 126, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, -0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 3, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 4, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, -0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 2, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 3, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, -0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 4, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, 0, 0, 0, 2, 64, -0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, 44, 77, 60, 0, 0, -0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, -16, 0, 3, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, -0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 3, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, -0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, -0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -445,7 +443,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -453,7 +451,7 @@ public partial class SpriteBatch 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -461,7 +459,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -469,151 +467,151 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 45, 212, 199, 15, 241, 225, 180, 72, 181, 71, 25, 182, 177, 197, 31, 246, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 220, 126, 48, 133, 88, 175, 203, 75, 184, 174, 116, 9, 14, 175, 210, 78, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, -32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 31, 105, -3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, +102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 117, 131, 1, 0, 198, 90, 0, 0, 214, 195, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 139, 218, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, +0, 0, 31, 105, 3, 0, 233, 240, 2, 0, 116, 39, 1, 0, 103, 159, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, -32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, -97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, -116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, -119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, -83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, -110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, -40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, -54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, -10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, -10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, -32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, -111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, -108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, -122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, -123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, -105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, -116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, -32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, -32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, -110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, -112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, -119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 99, 98, 117, +102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, +41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, +32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, +57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, +59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, +110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 50, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, +118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, +119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, +32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, +100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, +40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, +105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 23, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, -100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, -115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, -120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 102, 99, 99, 53, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, -95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 181, 52, 220, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 138, 47, 163, 182, 98, 12, 0, 0, 1, 0, 0, 0, 90, 0, -0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 23, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 0, 99, 58, 92, +100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 102, 100, 52, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 87, 215, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 236, 101, 107, 69, 98, 12, 0, 0, 1, 0, +0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, -83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, -101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, 0, 0, 1, 0, -160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 156, 0, -0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, -5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, -0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, 4, 0, 156, 0, -0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 48, 0, -4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, -92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, -4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, -80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, -92, 1, 8, 0, 0, 0, 50, 0, 77, 17, 136, 0, 0, 0, 220, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 36, 6, 12, 12, 128, 136, 40, 12, 128, 128, 128, 176, 8, 0, 13, 35, 1, 128, 196, 12, 128, 136, 0, 12, 128, 128, 128, 176, 0, 0, 0, 66, 0, 77, 17, 244, 3, -0, 0, 216, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 9, 5, 13, 24, 6, 9, 12, 128, 128, 128, 176, 8, 0, 9, 27, 13, 53, 1, 128, 196, 6, 8, 12, 128, 136, 0, 9, 5, 13, 23, 6, 9, 12, 128, 128, 128, 176, 0, 0, 0, 54, 0, -77, 17, 40, 4, 0, 0, 164, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 196, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 42, 0, 77, 17, 40, 4, -0, 0, 212, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 128, 216, 8, 0, 9, 33, 13, 82, 1, 129, 116, 12, 128, 128, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, -0, 0, 16, 1, 206, 253, 16, 195, 255, 2, 68, 226, 90, 0, 130, 233, 146, 246, 37, 224, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 138, 0, 0, 128, 156, 0, -0, 0, 138, 0, 0, 0, 176, 0, 0, 0, 138, 0, 0, 128, 176, 0, 0, 0, 138, 0, 0, 0, 196, 0, 0, 0, 131, 0, 0, 128, 196, 0, 0, 0, 131, 0, 0, 0, 0, 1, 0, 0, 131, 0, 0, 128, 0, 1, 0, 0, 131, 0, 0, 0, 48, 1, 0, 0, 131, 0, 0, 128, 48, 1, -0, 0, 131, 0, 0, 0, 76, 1, 0, 0, 138, 0, 0, 128, 76, 1, 0, 0, 138, 0, 0, 0, 96, 1, 0, 0, 138, 0, 0, 128, 96, 1, 0, 0, 138, 0, 0, 0, 116, 1, 0, 0, 131, 0, 0, 128, 116, 1, 0, 0, 131, 0, 0, 0, 148, 1, 0, 0, 131, 0, 0, 128, 148, 1, -0, 0, 131, 0, 0, 0, 180, 1, 0, 0, 131, 0, 0, 128, 180, 1, 0, 0, 131, 0, 0, 0, 212, 1, 0, 0, 131, 0, 0, 128, 212, 1, 0, 0, 131, 0, 0, 0, 244, 1, 0, 0, 138, 0, 0, 128, 244, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, -24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, -16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2, 16, 0, 0, 0, 0, -0, 0, 94, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, +41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, +95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 4, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 8, 16, 0, 0, 156, 0, +0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, +80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 156, 0, 0, 0, 1, 0, +92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 52, 0, +4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 64, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, +117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 44, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 48, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 48, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 52, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 52, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 56, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 56, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 60, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 156, 0, +0, 0, 1, 0, 92, 1, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, +5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 28, 0, +0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 92, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 156, 0, +0, 0, 1, 0, 92, 1, 8, 0, 0, 0, 50, 0, 77, 17, 136, 0, 0, 0, 220, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 36, 6, 12, 12, 128, 136, 40, 12, 128, 128, 128, 176, 8, 0, 13, 35, 1, 128, 196, 12, 128, 136, 0, 12, 128, 128, 128, 176, 0, 0, 0, 66, 0, +77, 17, 244, 3, 0, 0, 216, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 9, 5, 13, 24, 6, 9, 12, 128, 128, 128, 176, 8, 0, 9, 27, 13, 53, 1, 128, 196, 6, 8, 12, 128, 136, 0, 9, 5, 13, 23, 6, 9, 12, 128, 128, 128, 176, 0, +0, 0, 54, 0, 77, 17, 40, 4, 0, 0, 164, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, 13, 107, 1, 128, 196, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 42, 0, +77, 17, 40, 4, 0, 0, 212, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 128, 216, 8, 0, 9, 33, 13, 82, 1, 129, 116, 12, 128, 128, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, +0, 0, 1, 0, 0, 0, 16, 1, 229, 245, 219, 140, 199, 93, 142, 88, 229, 189, 112, 98, 10, 64, 208, 84, 0, 0, 242, 0, 0, 0, 56, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 248, 1, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 44, 1, 0, 0, 156, 0, 0, 0, 138, 0, +0, 128, 156, 0, 0, 0, 138, 0, 0, 0, 176, 0, 0, 0, 138, 0, 0, 128, 176, 0, 0, 0, 138, 0, 0, 0, 196, 0, 0, 0, 131, 0, 0, 128, 196, 0, 0, 0, 131, 0, 0, 0, 0, 1, 0, 0, 131, 0, 0, 128, 0, 1, 0, 0, 131, 0, 0, 0, 48, 1, 0, 0, 131, 0, +0, 128, 48, 1, 0, 0, 131, 0, 0, 0, 76, 1, 0, 0, 138, 0, 0, 128, 76, 1, 0, 0, 138, 0, 0, 0, 96, 1, 0, 0, 138, 0, 0, 128, 96, 1, 0, 0, 138, 0, 0, 0, 116, 1, 0, 0, 131, 0, 0, 128, 116, 1, 0, 0, 131, 0, 0, 0, 148, 1, 0, 0, 131, 0, +0, 128, 148, 1, 0, 0, 131, 0, 0, 0, 180, 1, 0, 0, 131, 0, 0, 128, 180, 1, 0, 0, 131, 0, 0, 0, 212, 1, 0, 0, 131, 0, 0, 128, 212, 1, 0, 0, 131, 0, 0, 0, 244, 1, 0, 0, 138, 0, 0, 128, 244, 1, 0, 0, 138, 0, 0, 0, 5, 0, 24, 0, 5, 0, +24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, +15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 2, 16, +0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 89, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, -0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, -0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, +8, 16, 12, 16, 0, 0, 23, 0, 1, 0, 11, 16, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, +0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 56, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, 0, 0, 8, 0, -0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, 3, 18, 13, 21, -3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, -105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, -101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, 3, 0, 0, 16, -0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, -5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, -1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 181, 177, 2, 0, 64, 168, 2, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 17, 16, 0, 0, 56, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 68, 0, 0, 0, 68, 0, +0, 0, 8, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 134, 0, +3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, +0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 243, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 56, 0, 105, 110, 95, 86, 83, 95, 83, 119, +105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 5, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 134, 0, 3, 18, 13, 21, +3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 44, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, +242, 241, 42, 0, 5, 21, 5, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, +0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 181, 177, 2, 0, 64, 168, 2, 0, 100, 88, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -621,71 +619,71 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, -97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, -116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, -119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, -83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, -110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, -40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, -54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, -10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, -10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, -32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, -111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, -108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, -122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, -123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, -105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, -116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, -32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, -32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, -110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, -112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, -119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, +32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, +41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, +32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, +57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, +59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, +110, 40, 41, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 52, 50, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 52, 52, 50, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, +118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, +119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, +32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, +100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, +40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, +105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, +86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, +0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, -0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, -116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, +0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, -0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 95, -116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 248, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, +0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 10, 16, +0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -693,15 +691,15 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 16, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, -119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 16, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, +114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -709,31 +707,31 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 4, 0, 0, 0, 0, 0, 0, 156, 1, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, -2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, -105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, -48, 48, 48, 49, 69, 65, 51, 48, 70, 67, 67, 53, 67, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 4, 0, 0, 0, 0, +0, 0, 156, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, +48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 45, 212, 199, 15, 241, 225, 180, 72, 181, 71, 25, 182, 177, 197, 31, 246, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, -101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, -100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 102, 99, 99, 53, 99, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, -1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 220, 126, 48, 133, 88, 175, 203, 75, 184, 174, 116, 9, 14, 175, 210, 78, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, +47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, +115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 102, 100, 52, 97, 48, 0, 4, 0, 0, 0, +6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 112, 2, 0, 0, 111, 1, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 71, 13, 0, 0, 128, 0, 0, 0, 98, 12, 0, 0, 140, 6, 0, 0, 76, 0, -0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, -0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, -0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 112, 2, 0, 0, 111, 1, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 71, 13, 0, 0, 128, 0, 0, 0, 98, 12, 0, 0, 140, 6, +0, 0, 76, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, +0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, +0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -741,17 +739,17 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, -0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, -40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, -84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 137, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, +0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, +111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 168, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 146, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 15, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, +82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 152, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 128, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 128, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 128, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, +0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index 03ea01f007..abc0f2e655 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -34,343 +34,745 @@ public partial class SpriteBatch 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 44, 225, 151, 85, 178, 127, 173, 116, 18, 195, 115, 152, 31, 157, 21, 243, 0, 212, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, 0, 7, 0, +90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, +0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, +112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, -0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, -47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, -115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, -101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, -115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, -46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, -114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, -0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, -110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, -105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 43, 2, -0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, -101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, -120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, -112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, -0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, -119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, -120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, -0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 212, 0, -0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, 66, 97, 0, -0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, -54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, 0, 102, 108, -111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, 105, 116, 101, -66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, -103, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, -0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, -6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, -5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 241, 1, -0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, 0, 0, 105, 110, -116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, -5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 46, 2, -0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, 114, 95, 73, 110, -112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, -0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, -102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, 0, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 3, 0, -0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, 0, 0, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, -0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 57, 2, -0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, -104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, -4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, -0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, 95, 86, 83, 95, -67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, 0, 0, 111, 117, -116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, -0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, -114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, 0, 67, 111, -108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, 0, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 90, 2, -0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 91, 2, -0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, 0, 0, 83, 119, -105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 94, 2, -0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 113, 0, -0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, -4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, 0, 0, 67, 79, -76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 2, -0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 82, 2, -0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, -0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, 0, 0, 30, 0, -0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, -0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, -0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, -4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, -0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, -0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, -0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, -4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, -0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, -0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 195, 0, -0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 210, 0, -0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 227, 0, -0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 128, 63, 43, 0, -4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, 184, 60, 43, 0, -4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, 78, 65, 43, 0, -4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, -0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, -0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, -0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 53, 2, -0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, -0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, -0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 88, 2, -0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, -0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, 0, 0, 5, 0, -0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, 0, 0, 6, 0, -0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 93, 2, -0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, -0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, -5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, -0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, -0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, -0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, 0, 0, 231, 0, -0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 233, 0, -0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, 0, 0, 202, 0, -0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, 0, 239, 0, -0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, 0, 242, 0, -0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, 0, 244, 0, -0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 80, 0, -7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 177, 1, -0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, 0, 0, 248, 0, -2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, 0, 0, 62, 0, -3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, 0, 0, 65, 0, -5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 207, 1, -0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, 0, 0, 248, 0, -2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 211, 1, -0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 212, 1, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, 0, 226, 1, -0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, 0, 0, 209, 1, -0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, 4, 0, 5, 0, -0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, 0, 0, 65, 0, -5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 245, 1, -0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 247, 1, -0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, 4, 0, 5, 0, -0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, 0, 0, 255, 1, -0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, 5, 0, 5, 0, -0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, 0, 0, 133, 0, -5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, 2, 0, 224, 1, -0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, 6, 0, 5, 0, -0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, 0, 0, 12, 2, -0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 23, 2, -0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, 0, 0, 25, 2, -0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 2, -0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 58, 2, -0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, 0, 0, 254, 0, -2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, -0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, 3, 0, 64, 2, -0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 70, 2, -0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 74, 2, -0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, 0, 0, 31, 0, -0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, 0, 3, 0, -0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 62, 0, -3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, 4, 0, 30, 0, -0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, 5, 0, 75, 0, -0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, 0, 0, 62, 0, -3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 44, 225, 151, 85, 178, 127, 173, 116, 18, 195, 115, 152, 31, 157, 21, 243, 0, 212, 41, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 118, 2, 0, -0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 10, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 59, 2, 0, 0, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 47, 2, 0, 0, 49, 2, 0, 0, 51, 2, 0, 0, 52, 2, 0, 0, 45, 2, 0, 0, 58, 2, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 94, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 2, 0, 0, 81, 2, 0, 0, 82, 2, 0, 0, 84, 2, 0, 0, 86, 2, 0, 0, 77, 2, 0, 0, 79, 2, 0, 0, 83, 2, 0, 0, 85, 2, 0, 0, 87, 2, 0, 0, 93, 2, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 59, 2, 0, -0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, -0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 156, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 1, 0, 0, 7, 0, 21, 0, 40, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 41, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 42, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, -0, 43, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 20, 0, 44, 2, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, -0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, -119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, -0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, -68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, -97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 186, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, -0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 196, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, -49, 49, 0, 0, 0, 5, 0, 7, 0, 204, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 207, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, -0, 212, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 228, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 229, 0, 0, 0, 115, 82, 71, -66, 97, 0, 0, 0, 5, 0, 4, 0, 231, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 249, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 5, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 67, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 72, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, -53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 77, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 94, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 96, 1, 0, -0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 102, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 107, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 112, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 143, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 158, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 164, 1, 0, 0, 83, 112, 114, -105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 165, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, -100, 105, 110, 103, 0, 5, 0, 5, 0, 181, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 182, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 201, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, -114, 0, 0, 0, 0, 5, 0, 4, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 209, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 213, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, -0, 5, 0, 6, 0, 214, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 228, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, -0, 5, 0, 5, 0, 223, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 232, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 235, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 240, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, -0, 241, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 246, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 249, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 1, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 5, 2, 0, -0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 16, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, -0, 5, 0, 5, 0, 11, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 12, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 29, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, -0, 46, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 45, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 48, 2, 0, 0, 112, 116, 114, -95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 47, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 50, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, -52, 0, 0, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 51, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 53, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 52, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 54, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 0, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 54, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 54, 2, 0, -0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 55, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 55, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 56, 2, 0, -0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 56, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, -0, 56, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 56, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 56, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, -0, 57, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 58, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 59, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, -97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 65, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, -0, 5, 0, 4, 0, 68, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 71, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 75, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 77, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 80, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, -116, 50, 0, 0, 0, 5, 0, 6, 0, 79, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 81, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 82, 2, 0, 0, 105, 110, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 83, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 84, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 85, 2, 0, -0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 86, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 88, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, -116, 0, 0, 0, 0, 5, 0, 6, 0, 87, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 89, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 89, 2, 0, 0, 3, 0, 0, -0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 89, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 90, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 90, 2, 0, 0, 0, 0, 0, -0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 90, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, -0, 90, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 90, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 91, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, -0, 91, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 91, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 91, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 91, 2, 0, 0, 5, 0, 0, -0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 92, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 93, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, -0, 94, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 105, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, -0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 45, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 47, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 47, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, -0, 71, 0, 4, 0, 49, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 49, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 51, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 51, 2, 0, 0, 3, 22, 0, -0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 52, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 52, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 11, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 79, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 79, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 81, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 81, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, -0, 82, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 82, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 83, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 83, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, -79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 84, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 85, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 85, 2, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 86, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 86, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 87, 2, 0, -0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 87, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, -0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, -0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, -0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, -0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, -0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, -0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, -0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, -0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, -0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 196, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, -0, 195, 0, 0, 0, 5, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 207, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, -0, 210, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 212, 0, 0, 0, 7, 0, 0, 0, 210, 0, 0, 0, 33, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 212, 0, 0, 0, 32, 0, 4, 0, 228, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, -0, 227, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 249, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 253, 0, 0, 0, 4, 0, 0, 0, 228, 0, 0, 0, 196, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 0, 0, 128, -63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 67, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 72, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 77, 1, 0, 0, 54, 168, 184, -60, 43, 0, 4, 0, 5, 0, 0, 0, 94, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 96, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 102, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 107, 1, 0, 0, 82, 184, 78, -65, 43, 0, 4, 0, 5, 0, 0, 0, 112, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 143, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 158, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, -0, 5, 0, 0, 0, 209, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 228, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 139, 0, 0, 0, 235, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 241, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 139, 0, 0, 0, 246, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 5, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, -0, 5, 0, 0, 0, 16, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 46, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 50, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, -0, 53, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 54, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 55, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 56, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 57, 2, 0, 0, 6, 0, 0, 0, 56, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 62, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 65, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, -0, 139, 0, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 71, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 80, 2, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, -0, 88, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 89, 2, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 90, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 5, 0, 0, 0, 30, 0, 8, 0, 91, 2, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 92, 2, 0, 0, 6, 0, 0, 0, 91, 2, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 105, 2, 0, -0, 5, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 45, 2, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 47, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 49, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 51, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 52, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 57, 2, 0, 0, 58, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 77, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 78, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 80, 2, 0, 0, 79, 2, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 81, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 82, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 83, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 50, 2, 0, 0, 84, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 46, 2, 0, 0, 85, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 53, 2, 0, 0, 86, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 88, 2, 0, 0, 87, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 92, 2, 0, 0, 93, 2, 0, -0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, -0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, -0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 165, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, -0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, -0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, -0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 227, 0, 0, 0, 55, 0, 3, 0, 228, 0, 0, 0, 229, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 59, 0, 4, 0, 212, 0, 0, -0, 231, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 0, 0, 0, 229, 0, 0, 0, 79, 0, 8, 0, 210, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, -0, 233, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 234, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 235, 0, 0, 0, 231, 0, 0, 0, 61, 0, 4, 0, 210, 0, 0, 0, 236, 0, 0, 0, 231, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 238, 0, 0, -0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 237, 0, 0, 0, 236, 0, 0, 0, 238, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 240, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 204, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, -0, 239, 0, 0, 0, 237, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 241, 0, 0, 0, 235, 0, 0, 0, 239, 0, 0, 0, 80, 0, 6, 0, 210, 0, 0, 0, 243, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 207, 0, 0, 0, 129, 0, 5, 0, 210, 0, 0, -0, 242, 0, 0, 0, 241, 0, 0, 0, 243, 0, 0, 0, 133, 0, 5, 0, 210, 0, 0, 0, 244, 0, 0, 0, 234, 0, 0, 0, 242, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 246, 0, 0, -0, 244, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 244, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 250, 0, 0, 0, 229, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, -0, 80, 0, 7, 0, 4, 0, 0, 0, 252, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 251, 0, 0, 0, 254, 0, 2, 0, 252, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 164, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, -0, 177, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 192, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 180, 1, 0, 0, 118, 0, 0, 0, 247, 0, 3, 0, 182, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 158, 1, 0, 0, 181, 1, 0, 0, 182, 1, 0, -0, 248, 0, 2, 0, 181, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 186, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 194, 1, 0, 0, 93, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 195, 1, 0, 0, 194, 1, 0, -0, 62, 0, 3, 0, 192, 1, 0, 0, 195, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 197, 1, 0, 0, 186, 0, 0, 0, 192, 1, 0, 0, 62, 0, 3, 0, 186, 1, 0, 0, 197, 1, 0, 0, 249, 0, 2, 0, 182, 1, 0, 0, 248, 0, 2, 0, 182, 1, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 165, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 200, 1, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 201, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 211, 1, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 196, 0, 0, 0, 232, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 240, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 196, 0, 0, 0, 249, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 228, 0, 0, 0, 29, 2, 0, 0, 7, 0, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 204, 1, 0, 0, 203, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 206, 1, 0, 0, 204, 1, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, -0, 207, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 206, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 210, 1, 0, 0, 207, 1, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 210, 1, 0, 0, 213, 1, 0, 0, 214, 1, 0, -0, 248, 0, 2, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 120, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 218, 1, 0, 0, 217, 1, 0, 0, 217, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, -0, 211, 1, 0, 0, 218, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, 0, 214, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 221, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 211, 1, 0, 0, 221, 1, 0, 0, 249, 0, 2, 0, 212, 1, 0, 0, 248, 0, 2, -0, 212, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 222, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 226, 1, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 1, 0, -0, 226, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 229, 1, 0, 0, 227, 1, 0, 0, 228, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 230, 1, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 229, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 231, 1, 0, 0, 230, 1, 0, -0, 209, 1, 0, 0, 247, 0, 3, 0, 224, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 231, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 248, 0, 2, 0, 223, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 236, 1, 0, 0, 201, 1, 0, 0, 235, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 237, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 239, 1, 0, -0, 65, 0, 5, 0, 196, 0, 0, 0, 242, 1, 0, 0, 201, 1, 0, 0, 241, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 228, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, -0, 245, 1, 0, 0, 244, 1, 0, 0, 205, 1, 0, 0, 62, 0, 3, 0, 240, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 247, 1, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 248, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, -0, 247, 1, 0, 0, 248, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 232, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 250, 1, 0, 0, 251, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 253, 1, 0, 0, 240, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 1, 0, 0, 240, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 255, 1, 0, 0, 253, 1, 0, 0, 254, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 252, 1, 0, -0, 255, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 2, 2, 0, 0, 10, 1, 0, 0, 43, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0, 205, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 3, 2, 0, 0, 10, 1, 0, 0, 31, 0, 0, 0, 2, 2, 0, 0, 131, 0, 5, -0, 5, 0, 0, 0, 4, 2, 0, 0, 205, 1, 0, 0, 3, 2, 0, 0, 62, 0, 3, 0, 249, 1, 0, 0, 4, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 6, 2, 0, 0, 201, 1, 0, 0, 5, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 7, 2, 0, 0, 249, 1, 0, -0, 133, 0, 5, 0, 5, 0, 0, 0, 9, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 10, 2, 0, 0, 9, 2, 0, 0, 8, 2, 0, 0, 62, 0, 3, 0, 6, 2, 0, 0, 10, 2, 0, 0, 249, 0, 2, 0, 224, 1, 0, 0, 248, 0, 2, -0, 224, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 14, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 17, 2, 0, 0, 15, 2, 0, 0, 16, 2, 0, 0, 12, 0, 6, -0, 5, 0, 0, 0, 18, 2, 0, 0, 10, 1, 0, 0, 4, 0, 0, 0, 17, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 19, 2, 0, 0, 18, 2, 0, 0, 209, 1, 0, 0, 247, 0, 3, 0, 12, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 19, 2, 0, 0, 11, 2, 0, -0, 12, 2, 0, 0, 248, 0, 2, 0, 11, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 20, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 22, 2, 0, 0, 20, 2, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 23, 2, 0, 0, 201, 1, 0, 0, 79, 0, 7, 0, 43, 0, 0, 0, 24, 2, 0, 0, 23, 2, 0, 0, 23, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 25, 2, 0, 0, 201, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 26, 2, 0, -0, 25, 2, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 201, 1, 0, 0, 26, 2, 0, 0, 65, 0, 5, 0, 196, 0, 0, 0, 27, 2, 0, 0, 201, 1, 0, 0, 246, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, -0, 28, 2, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 27, 2, 0, 0, 28, 2, 0, 0, 249, 0, 2, 0, 12, 2, 0, 0, 248, 0, 2, 0, 12, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 30, 2, 0, 0, 201, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, -0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 36, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 2, 0, 0, 36, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 38, 2, 0, 0, 34, 2, 0, 0, 37, 2, 0, 0, 62, 0, 3, 0, 29, 2, 0, 0, 38, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 39, 2, 0, 0, 29, 2, 0, -0, 254, 0, 2, 0, 39, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 59, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 60, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 61, 2, 0, 0, 58, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, -0, 43, 0, 0, 0, 63, 2, 0, 0, 47, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 64, 2, 0, 0, 58, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 66, 2, 0, 0, 49, 2, 0, 0, 62, 0, 3, -0, 64, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 67, 2, 0, 0, 58, 2, 0, 0, 68, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 69, 2, 0, 0, 51, 2, 0, 0, 62, 0, 3, 0, 67, 2, 0, 0, 69, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 70, 2, 0, 0, 58, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 72, 2, 0, 0, 52, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 72, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 73, 2, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 74, 2, 0, 0, 58, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 76, 2, 0, 0, 74, 2, 0, 0, 62, 0, 3, 0, 45, 2, 0, 0, 76, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 94, 2, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 95, 2, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 96, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 97, 2, 0, 0, 78, 2, 0, 0, 62, 0, 3, 0, 96, 2, 0, 0, 97, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 98, 2, 0, 0, 93, 2, 0, 0, 65, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 99, 2, 0, 0, 81, 2, 0, 0, 62, 0, 3, 0, 98, 2, 0, 0, 99, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 2, 0, 0, 82, 2, 0, 0, 62, 0, 3, 0, 100, 2, 0, 0, 101, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, -0, 62, 0, 3, 0, 102, 2, 0, 0, 103, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 104, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 106, 2, 0, 0, 86, 2, 0, 0, 62, 0, 3, 0, 104, 2, 0, 0, 106, 2, 0, 0, 57, 0, 4, -0, 30, 0, 0, 0, 107, 2, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 2, 0, 0, 93, 2, 0, 0, 75, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 109, 2, 0, 0, 108, 2, 0, 0, 62, 0, 3, 0, 77, 2, 0, 0, 109, 2, 0, 0, 65, 0, 5, -0, 75, 0, 0, 0, 110, 2, 0, 0, 93, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 111, 2, 0, 0, 110, 2, 0, 0, 62, 0, 3, 0, 79, 2, 0, 0, 111, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 112, 2, 0, 0, 93, 2, 0, 0, 68, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 113, 2, 0, 0, 112, 2, 0, 0, 62, 0, 3, 0, 83, 2, 0, 0, 113, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 114, 2, 0, 0, 93, 2, 0, 0, 71, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 115, 2, 0, 0, 114, 2, 0, -0, 62, 0, 3, 0, 85, 2, 0, 0, 115, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 116, 2, 0, 0, 93, 2, 0, 0, 105, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 117, 2, 0, 0, 116, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 117, 2, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, +100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, +47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, +105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, +46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, +95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, +38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, +80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, +105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, +73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, +101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, +103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, +32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, +117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, +115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, +102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, +101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, +78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, +32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, +105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, +32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, +97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, +100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, +99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, +0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, +110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, +114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, +77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, +101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, +115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, +122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, +101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, +54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, +67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, +98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, +47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, +79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, +78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, +69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, +77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, +67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, +32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, +32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, +10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, +111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, +105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, +111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, +102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, +117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, +77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, +105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, +104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, +70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, +112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, +115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, +69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, +111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, +116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, +50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, +101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, +42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, +32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, +56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, +101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, +116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, +97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, +111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, +97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, +108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, +32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, +105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, +49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, +101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, +40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, +83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, +32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, +55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, +32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, +48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, +117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, +111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, +32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, +52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, +101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, +41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, +116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, +32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, +111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, +40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, +108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, +102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, +13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, +32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, +77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, +67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, +32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, +32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, +58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, +101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, +104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, +120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, +99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, +45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, +45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, +32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, +111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, +97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, +40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, +101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, +46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, +59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, +7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, +114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, +7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, +111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, +0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, +84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, +0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, +109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, +0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, +114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, +51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, +4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, +77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, +0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, +5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, +0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, +3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, 0, 0, 105, 110, +116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, +5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, +0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 38, 2, +0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, 95, 80, 83, 95, +83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 1, 0, +0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, 0, 0, 80, 83, +95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 0, 0, +0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 47, 2, +0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, +69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 62, 2, +0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 69, 2, +0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 77, 2, +0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, +122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, 0, 0, 80, 111, +115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 4, 0, +0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 2, +0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, +5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, +110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, 0, 0, 67, 111, +108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, 114, 95, 80, 114, +105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, +116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 0, 0, +0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 40, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, 0, 0, 3, 0, +0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, +6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, +4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, 0, 0, 3, 22, +0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, +5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, +0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, 0, 0, 66, 65, +84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, +0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, +0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, +0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, +0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, +0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, +0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, +0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, +4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, +0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 198, 0, +0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 7, 0, +0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 0, +0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, +0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, +0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, +0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 224, 1, +0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 253, 1, +0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, 0, 0, 3, 0, +0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, 0, 0, 42, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 6, 0, +0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 62, 2, +0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, 0, 0, 42, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, +4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, 0, 0, 59, 0, +4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, 0, 0, 59, 0, +4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, 0, 0, 59, 0, +4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, +4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, +4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, +5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, +0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, +5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 57, 0, +4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, +0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, 0, 0, 53, 2, +0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, +0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, +0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, 0, 0, 7, 0, +0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, 0, 61, 0, +4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, 6, 0, 206, 0, +0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, 6, 0, 206, 0, +0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, 5, 0, 5, 0, +0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 246, 0, +0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, 0, 0, 56, 0, +1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 59, 0, +4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, +3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, 0, 0, 84, 2, +0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 193, 1, +0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, +5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, +0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, +0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, 0, 0, 201, 1, +0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 206, 1, +0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, 0, 0, 249, 0, +2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, +0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, 0, 0, 6, 1, +0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, 2, 0, 219, 1, +0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 234, 1, +0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, +0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, 0, 0, 240, 1, +0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 244, 1, +0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 228, 1, +0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, +0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, 0, 0, 12, 0, +6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 41, 0, +0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, 0, 0, 129, 0, +5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, 0, 0, 65, 0, +5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 14, 2, +0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 248, 0, +2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 2, 0, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, 0, 0, 79, 0, +9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 65, 0, +5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, 0, 0, 8, 0, +4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 28, 2, +0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, 5, 0, 4, 0, +0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, 2, 0, 35, 2, +0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 54, 2, +0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, 0, 0, 57, 2, +0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, 0, 0, 49, 2, +0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, 0, 0, 49, 2, +0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, +2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 89, 2, +0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, 3, 0, 93, 2, +0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 98, 2, +0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 101, 2, +0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, 3, 0, 76, 2, +0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, +0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, 0, +0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, 0, +0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, +97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, +115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, +111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, +109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, +80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, +32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, +111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, +115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, +115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, +114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, +102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, +116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, +69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, +111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, +73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, +69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, +104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, +99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, +76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, +115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, +101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, +0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, +101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, +112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, +73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, +32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, +108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, +117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, +101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, +32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, +73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, +69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, +32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, +113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, +73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, +59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, +61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, +32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, +87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, +97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, +108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, +47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, +0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, +110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, +100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, +46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, +105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, +102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, +97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, +116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, +13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, +111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, +115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, +116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, +78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, +108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, +46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, +53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, +13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, +32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, +32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, +110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, +32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, +41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, +97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, +46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, +108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, +32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, +110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, +49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, +97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, +82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, +50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, +83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, +54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, +82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, +46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, +116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, +119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, +99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, +32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, +32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, +114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, +117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, 32, +67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, +117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, +105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, +111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, +32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, +97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, +111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, 32, +102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, 32, +105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, +111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, 58, +32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, +97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, 104, +111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, 120, +116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, 99, +111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, +32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, +32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, +61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, 111, +32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, 97, +98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, +97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, +67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, +13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, +0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, +0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, +0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, +114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, +0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, +0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, 114, +95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, +49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, +0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, +0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, +97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, +0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, +0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, +0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, +0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, +0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, +0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 38, 2, 0, +0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 1, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, 0, 0, 80, 83, 95, +79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 0, 0, 0, +0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 47, 2, 0, +0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 62, 2, 0, +0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 69, 2, 0, +0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 77, 2, 0, +0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, +122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 4, 0, 0, +0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 2, 0, +0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, +0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, +114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 40, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, +0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, +0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, +0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, +67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, +0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, +0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, +0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, +0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, +0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, +0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, +0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, +0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, +0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, +0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 7, 0, 0, +0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 0, 0, +0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, +0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, +0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, +0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 224, 1, 0, +0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, +0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, 0, 0, 3, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 6, 0, 0, +0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 62, 2, 0, +0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, +0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, +0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, +0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, +0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 57, 0, 4, +0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, +0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, 0, 0, 53, 2, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, +0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, +0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, +0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, +0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, +0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, +0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, +0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 246, 0, 0, +0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, 0, 0, 56, 0, 1, +0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 59, 0, 4, +0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, +0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, 0, 0, 84, 2, 0, +0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 193, 1, 0, +0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, +0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, 0, 0, 201, 1, 0, +0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 206, 1, 0, +0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, +0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, 0, 0, 6, 1, 0, +0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, 2, 0, 219, 1, 0, +0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 234, 1, 0, +0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, +0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, 0, 0, 240, 1, 0, +0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, +0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, +0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, +0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 41, 0, 0, +0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, 0, 0, 129, 0, 5, +0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, +0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 14, 2, 0, +0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 248, 0, 2, +0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, 0, 0, 79, 0, 9, +0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, +0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, 0, 0, 8, 0, 4, +0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 28, 2, 0, +0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, +0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, 2, 0, 35, 2, 0, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 54, 2, 0, +0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, 0, 0, 57, 2, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, 0, 0, 49, 2, 0, +0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, 0, 0, 49, 2, 0, +0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, +0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 89, 2, 0, +0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, 3, 0, 93, 2, 0, +0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 98, 2, 0, +0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 101, 2, 0, +0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, +0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, +0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs index e4090e38d9..31101eec59 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -23,50 +23,48 @@ public partial class SpriteEffect 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 8, 0, 0, 0, 0, 18, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, -0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, -83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, -10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, -0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, -0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, -68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, -114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, -110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 126, 136, 59, 109, 2, 73, -92, 69, 241, 194, 69, 194, 53, 203, 121, 230, 0, 160, 67, 0, 0, 68, 88, 66, 67, 12, 134, 39, 4, 100, 46, 223, 108, 105, 243, 53, 83, 239, 183, 234, 244, 1, 0, 0, 0, 160, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, 65, 0, 0, 12, -66, 0, 0, 56, 67, 0, 0, 108, 67, 0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, 58, 92, 100, 101, -118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, -64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, 53, 68, 65, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 61, 0, 0, 0, 60, 2, 0, 0, 66, 0, 0, 0, 76, 2, 0, 0, 66, 0, 0, 0, 92, -2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, -83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, -1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, -0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 108, 1, 0, 0, 5, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 196, 0, 0, 0, 1, -0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 4, 1, 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 1, 0, 0, 0, 148, -1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, -8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, 0, 0, 0, 39, -0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, -32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, 0, 0, 0, 70, -14, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, -2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, +0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, +108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, +105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, +68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, +1, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, +0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, +67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 199, 107, +57, 115, 92, 237, 154, 6, 216, 190, 105, 107, 119, 229, 39, 96, 0, 160, 67, 0, 0, 68, 88, 66, 67, 114, 70, 253, 250, 151, 16, 171, 196, 223, 252, 220, 6, 54, 24, 191, 78, 1, 0, 0, 0, 160, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, +65, 0, 0, 12, 66, 0, 0, 56, 67, 0, 0, 108, 67, 0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, +58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, +97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 55, 70, 70, 66, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 61, 0, 0, 0, 60, 2, 0, 0, 66, 0, 0, 0, 76, 2, 0, 0, 66, +0, 0, 0, 92, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, +101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, +0, 0, 0, 9, 1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 92, 1, 0, 0, 108, 1, 0, 0, 5, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 176, 0, 0, 0, 196, +0, 0, 0, 1, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 52, 1, 0, 0, 1, 0, 0, 0, 68, 1, 0, 0, 4, 1, 0, 0, 80, 1, 0, 0, 132, 1, 0, 0, 1, +0, 0, 0, 148, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, +0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 0, 0, 228, 160, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 156, 0, 0, 0, 64, +0, 0, 0, 39, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 1, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 101, +0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 56, 0, 0, 8, 242, 32, 16, 0, 0, +0, 0, 0, 70, 14, 16, 0, 0, 0, 0, 0, 70, 142, 32, 0, 1, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, +0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -74,7 +72,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -82,7 +80,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -90,7 +88,7 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -98,95 +96,95 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 74, 171, 189, 113, 252, 234, 158, 74, 163, 70, 4, 131, 230, 180, 93, 106, 0, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 217, 166, 216, 1, 195, 137, 74, 79, 142, 199, 70, 123, 175, 149, 10, 181, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, -49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, -102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, -103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, -115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, 251, 3, 0, 138, -183, 3, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 105, 127, 2, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, +101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, +251, 3, 0, 138, 183, 3, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 254, 80, 0, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, -49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, -102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, -103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, -116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, -115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, -32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, -83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, -110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, -112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, -101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 117, 6, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, -115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, -53, 68, 65, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, -111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 50, 53, 100, 97, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 218, 184, 215, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 53, -251, 236, 50, 192, 5, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, +101, 114, 40, 98, 49, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, +101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, +10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, +65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, +111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, +117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, +32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 117, 6, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, +117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, +56, 51, 57, 55, 70, 70, 66, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, +121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 55, 102, 102, 98, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, +117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 65, 162, 99, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, +226, 48, 1, 53, 251, 236, 50, 192, 5, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, -114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, -114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 72, -0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 2, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, -0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, -0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 34, 0, 77, 17, 136, 0, 0, 0, 12, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 64, 4, 68, 8, 0, 13, 23, 1, 84, 12, 68, 0, 0, 38, 0, 77, 17, 180, 1, 0, 0, 8, -3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 51, 11, 32, 4, 68, 8, 0, 9, 29, 13, 50, 1, 84, 12, 68, 0, 0, 0, 0, 42, 0, 77, 17, 216, 1, 0, 0, 4, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 50, 11, 32, 4, 68, 8, 0, 9, 12, 13, 31, 1, -84, 3, 0, 13, 49, 12, 32, 36, 0, 0, 0, 38, 0, 77, 17, 0, 2, 0, 0, 0, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 84, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, -0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, 0, 0, 0, 1, -0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, -1, 235, 52, 182, 140, 55, 209, 158, 126, 139, 180, 56, 79, 213, 124, 128, 116, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 128, 84, 0, 0, 0, 84, -0, 0, 0, 120, 0, 0, 0, 84, 0, 0, 128, 120, 0, 0, 0, 84, 0, 0, 0, 152, 0, 0, 0, 87, 0, 0, 128, 152, 0, 0, 0, 87, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 52, -0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 20, -0, 0, 0, 56, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 148, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, -0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 38, 0, 5, 21, 1, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 2, -16, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, -0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, -0, 1, 0, 3, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, 0, 1, 0, 14, -0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 192, 82, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, -0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, +101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, +115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 3, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, +0, 0, 0, 72, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 2, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 58, 0, 62, 17, 7, +16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, +0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 8, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 72, 0, 12, 0, 0, 0, 34, 0, 77, 17, 136, 0, 0, 0, 12, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 64, 4, 68, 8, 0, 13, 23, 1, 84, 12, 68, 0, 0, 38, 0, 77, 17, 180, +1, 0, 0, 8, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 51, 11, 32, 4, 68, 8, 0, 9, 29, 13, 50, 1, 84, 12, 68, 0, 0, 0, 0, 42, 0, 77, 17, 216, 1, 0, 0, 4, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 50, 11, 32, 4, 68, 8, 0, 9, +12, 13, 31, 1, 84, 3, 0, 13, 49, 12, 32, 36, 0, 0, 0, 38, 0, 77, 17, 0, 2, 0, 0, 0, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 84, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, +0, 60, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 120, +0, 0, 0, 1, 0, 32, 0, 8, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 120, 0, 0, 0, 1, 0, 32, 0, 12, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, +0, 0, 0, 16, 1, 235, 52, 182, 140, 55, 209, 158, 126, 139, 180, 56, 79, 213, 124, 128, 116, 0, 0, 242, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 156, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 128, 84, +0, 0, 0, 84, 0, 0, 0, 120, 0, 0, 0, 84, 0, 0, 128, 120, 0, 0, 0, 84, 0, 0, 0, 152, 0, 0, 0, 87, 0, 0, 128, 152, 0, 0, 0, 87, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, +0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 16, 0, 0, 0, 0, +0, 0, 0, 20, 0, 0, 0, 56, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 21, 16, 0, 0, 148, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, +255, 3, 0, 0, 0, 0, 0, 84, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 30, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, +0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 38, 0, 5, 21, 1, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, +0, 0, 0, 2, 16, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, +243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, +16, 0, 0, 23, 0, 1, 0, 3, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, +0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 48, 80, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, +16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -194,95 +192,95 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, -32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 71, 108, 111, 98, -97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, -80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, -83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, -110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, -112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, -101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, +111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, +71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, +101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, +117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, +32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, +101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 124, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, -0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, -101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 124, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, +255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, +16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, -101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 16, 0, 0, 0, 8, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, +112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 34, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 13, +16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 97, 0, 0, 0, 1, 0, 0, 0, 57, -0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 32, 0, 0, 0, 20, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 97, 0, 0, 0, 1, +0, 0, 0, 57, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 34, 0, 81, 17, 14, 16, 0, 0, 8, 0, 1, 0, 0, -0, 255, 255, 255, 255, 255, 255, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 38, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, -0, 81, 17, 20, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 34, 0, 81, 17, 14, 16, 0, 0, 8, +0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 38, 0, 81, 17, 17, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, +48, 0, 0, 38, 0, 81, 17, 20, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, -9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, +255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, -0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -0, 9, 0, 20, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, -0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, -115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 50, 53, 68, 65, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, +0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 2, 0, 9, 0, 20, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, +0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, +0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, +99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 55, 70, 70, 66, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 74, 171, 189, 113, 252, 234, 158, 74, 163, 70, 4, 131, 230, 180, 93, 106, 134, 0, 0, 0, 47, -76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, -115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 50, -53, 100, 97, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 217, 166, 216, 1, 195, 137, 74, 79, 142, 199, 70, 123, 175, 149, 10, 181, 134, +0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, +117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, +56, 51, 57, 55, 102, 102, 98, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, +0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 204, 1, 0, 0, 111, 1, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 165, 6, 0, 0, 128, -0, 0, 0, 192, 5, 0, 0, 236, 3, 0, 0, 92, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 11, 0, 0, 0, 6, 0, 0, 0, 17, -0, 0, 0, 18, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 204, 1, 0, 0, 111, 1, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 165, +6, 0, 0, 128, 0, 0, 0, 192, 5, 0, 0, 236, 3, 0, 0, 92, 0, 0, 0, 24, 0, 0, 0, 40, 0, 0, 0, 68, 2, 0, 0, 44, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 15, 0, 0, 0, 25, 0, 0, 0, 19, 0, 0, 0, 11, 0, 0, 0, 6, +0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -306,42 +304,42 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 36, 1, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 252, 0, 0, 0, 124, -0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 161, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, -114, 101, 48, 0, 71, 108, 111, 98, 97, 108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 1, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 71, -108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, -114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, -0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 232, 117, 61, 182, 112, 233, 130, 47, 238, 0, -255, 1, 115, 70, 101, 247, 0, 156, 68, 0, 0, 68, 88, 66, 67, 234, 238, 238, 130, 230, 199, 134, 215, 10, 138, 216, 132, 193, 237, 108, 157, 1, 0, 0, 0, 156, 68, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 66, 0, 0, 32, 67, 0, 0, 240, -67, 0, 0, 68, 68, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, -114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 68, 0, 0, 0, 200, 2, 0, 0, 68, 0, 0, 0, 216, 2, 0, 0, 68, 0, 0, 0, 232, 2, 0, 0, 68, -0, 0, 0, 248, 2, 0, 0, 80, 0, 0, 0, 8, 3, 0, 0, 80, 0, 0, 0, 28, 3, 0, 0, 82, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, -0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 20, -1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 112, 1, 0, 0, 232, 0, 0, 0, 127, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 144, 1, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, 116, 105, -111, 110, 0, 210, 1, 0, 0, 4, 1, 0, 0, 226, 1, 0, 0, 232, 0, 0, 0, 235, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, 1, 0, 0, 3, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, 255, 1, 0, 255, -255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 36, 1, 0, 0, 4, 0, 0, 0, 52, 1, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 160, 1, 0, 0, 2, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 200, 1, 0, 0, 12, -2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, -0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, -0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 228, -0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 103, -0, 0, 4, 242, 32, 16, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, -0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, -0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, -83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 36, 1, 0, 0, 1, 0, 0, 0, 172, 0, 0, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 252, +0, 0, 0, 124, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 142, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, +0, 0, 0, 161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, +101, 120, 116, 117, 114, 101, 48, 0, 71, 108, 111, 98, 97, 108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 1, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 236, 0, 0, 0, 0, +0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, +112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, +83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 20, 195, 225, 173, 168, 60, +37, 23, 113, 191, 200, 150, 34, 0, 176, 172, 0, 156, 68, 0, 0, 68, 88, 66, 67, 180, 123, 155, 208, 110, 141, 206, 166, 197, 254, 73, 199, 6, 231, 3, 166, 1, 0, 0, 0, 156, 68, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 66, 0, 0, 32, +67, 0, 0, 240, 67, 0, 0, 68, 68, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, +118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, +64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 68, 0, 0, 0, 200, 2, 0, 0, 68, 0, 0, 0, 216, 2, 0, 0, 68, 0, 0, 0, 232, +2, 0, 0, 68, 0, 0, 0, 248, 2, 0, 0, 80, 0, 0, 0, 8, 3, 0, 0, 80, 0, 0, 0, 28, 3, 0, 0, 82, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, +0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, +0, 2, 0, 20, 1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, +117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 112, 1, 0, 0, 232, 0, 0, 0, 127, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 144, +1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, +115, 105, 116, 105, 111, 110, 0, 210, 1, 0, 0, 4, 1, 0, 0, 226, 1, 0, 0, 232, 0, 0, 0, 235, 1, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 244, 1, 0, 0, 3, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 4, 0, 0, 0, 255, +255, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 36, 1, 0, 0, 4, 0, 0, 0, 52, 1, 0, 0, 208, 0, 0, 0, 100, 1, 0, 0, 160, 1, 0, 0, 2, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 200, +1, 0, 0, 12, 2, 0, 0, 3, 0, 0, 0, 28, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, +0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, +0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 255, 255, 0, 0, 83, +72, 68, 82, 228, 0, 0, 0, 64, 0, 1, 0, 57, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, +0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 1, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, +0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, +0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, +43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -349,7 +347,7 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -357,15 +355,15 @@ public partial class SpriteEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, -255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, +0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -373,103 +371,103 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 14, 52, 52, 242, 232, -78, 253, 70, 182, 151, 161, 65, 206, 34, 147, 237, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 167, +86, 179, 223, 5, 40, 95, 76, 134, 19, 103, 253, 128, 48, 252, 65, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, -114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, -116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 117, 131, 1, 0, 198, 90, 0, 0, 125, 123, 1, 0, 8, 104, 0, 0, 38, -247, 2, 0, 118, 42, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, +80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, +41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 117, 131, 1, 0, 198, 90, 0, 0, 125, 123, 1, 0, 8, +104, 0, 0, 38, 247, 2, 0, 118, 42, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, -114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, 41, 10, 123, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, -116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, -116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, -32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, -105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, -110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, +85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, +80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 71, 108, 111, 98, 97, 108, 115, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 49, +41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, +116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 253, 6, 0, 0, 0, 67, 58, 92, 100, -101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, -114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, -99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 99, 98, 55, 55, 101, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 143, 5, 219, 37, 88, 187, 220, 1, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 18, 137, 140, 72, 6, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 253, 6, 0, 0, 0, +67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, +97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 98, 48, 51, 48, 49, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, +85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 16, 149, 103, 140, 60, +200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, +0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 18, 137, 140, 72, 6, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, -0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, -70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 156, -2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, -0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, -0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, -108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 152, 2, 0, 0, 0, -16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 6, 12, 128, 128, 20, 8, 0, 13, 23, 1, 96, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 68, 2, 0, 0, 148, 2, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 20, 8, 0, 9, 33, 13, 82, 1, 96, 12, -128, 128, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 150, 151, 40, 233, 9, 246, 86, 99, 124, 194, 182, 35, 212, 190, 112, 227, 0, 0, 242, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 228, -0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 88, 0, 0, 128, 76, 0, 0, 0, 88, 0, 0, 0, 96, 0, 0, 0, 84, 0, 0, 128, 96, 0, 0, 0, 84, 0, 0, 0, 128, 0, 0, 0, 84, 0, 0, 128, 128, 0, 0, 0, 84, 0, 0, 0, 160, -0, 0, 0, 84, 0, 0, 128, 160, 0, 0, 0, 84, 0, 0, 0, 192, 0, 0, 0, 84, 0, 0, 128, 192, 0, 0, 0, 84, 0, 0, 0, 224, 0, 0, 0, 88, 0, 0, 128, 224, 0, 0, 0, 88, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, -0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 67, -0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 132, -1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, -0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, -0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, -0, 0, 0, 3, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, -0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, -0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, 0, 0, 0, 4, -0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, +1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, +104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, +0, 0, 0, 156, 2, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 8, 16, 0, 0, 76, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 76, +0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, +110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 16, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 76, 0, 0, 0, 1, +0, 152, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 76, 0, 0, 0, 1, 0, 152, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 152, +2, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 6, 12, 128, 128, 20, 8, 0, 13, 23, 1, 96, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 68, 2, 0, 0, 148, 2, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 20, 8, 0, 9, 33, 13, +82, 1, 96, 12, 128, 128, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 150, 151, 40, 233, 9, 246, 86, 99, 124, 194, 182, 35, 212, 190, 112, 227, 0, 0, 242, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 1, +0, 1, 0, 228, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 156, 0, 0, 0, 76, 0, 0, 0, 88, 0, 0, 128, 76, 0, 0, 0, 88, 0, 0, 0, 96, 0, 0, 0, 84, 0, 0, 128, 96, 0, 0, 0, 84, 0, 0, 0, 128, 0, 0, 0, 84, 0, 0, 128, 128, 0, 0, 0, 84, +0, 0, 0, 160, 0, 0, 0, 84, 0, 0, 128, 160, 0, 0, 0, 84, 0, 0, 0, 192, 0, 0, 0, 84, 0, 0, 128, 192, 0, 0, 0, 84, 0, 0, 0, 224, 0, 0, 0, 88, 0, 0, 128, 224, 0, 0, 0, 88, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, +0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 1, 16, 0, 0, 0, +0, 0, 0, 67, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, +16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, +243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 58, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, +16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, +0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, +0, 242, 241, 42, 0, 5, 21, 2, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, +16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, 0, 4, +0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -477,95 +475,95 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, -59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, -116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, -116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, -32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, -105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, -110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, -90, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, +110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, +49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, +116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, +0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, -0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, -0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, +16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, +0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, -0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 228, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, +0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, -0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, +2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, -110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, +0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, -0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, -0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, -0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, -0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, -83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 67, 66, 55, 55, 69, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, +0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 228, +0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, +186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, +255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 14, 52, 52, 242, 232, -78, 253, 70, 182, 151, 161, 65, 206, 34, 147, 237, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, -101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, -114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 99, 98, 55, 55, 101, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, -0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 167, +86, 179, 223, 5, 40, 95, 76, 134, 19, 103, 253, 128, 48, 252, 65, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, +99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 98, 48, 51, 48, 49, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, +0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, -1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 45, 7, 0, 0, 128, 0, 0, 0, 72, 6, 0, 0, 160, 3, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 16, 0, 0, 0, 26, -0, 0, 0, 20, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 21, 0, 0, 0, 22, -0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, +1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 45, 7, 0, 0, 128, 0, 0, 0, 72, 6, 0, 0, 160, 3, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 27, 0, 0, 0, 16, +0, 0, 0, 26, 0, 0, 0, 20, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 17, 0, 0, 0, 21, +0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -581,15 +579,15 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, -0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, -0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, -0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 76, -0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, -79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 6, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, +0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, +0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, +102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, +83, 71, 78, 76, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 171, 171, 79, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 65, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index 2275039ade..f5679a1ff2 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -38,175 +38,430 @@ public partial class SpriteEffect 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, -1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 228, 13, 54, 98, 231, 53, 171, 232, -53, 251, 148, 122, 53, 33, 81, 141, 0, 192, 20, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 217, 0, 0, -0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 210, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 251, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 237, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 226, 0, 0, 0, 228, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 251, 0, 0, 0, 16, 0, 3, 0, 217, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 202, 222, 150, 118, 190, 241, 200, 207, +222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 209, 0, 0, +0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 243, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, 209, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, -100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, -0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 21, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 206, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, -0, 7, 0, 20, 0, 207, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, -0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, -101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, -0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, -114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, -0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, -0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 189, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 190, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 194, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 209, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 111, 117, 116, -95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, -85, 84, 0, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 214, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 214, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 214, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 215, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, -0, 5, 0, 5, 0, 216, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 217, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 220, 0, 0, -0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 224, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 226, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 227, 0, 0, -0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 229, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 228, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 5, 0, 7, 0, 231, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 230, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 232, 0, 0, -0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, -0, 233, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 5, 0, 5, 0, 234, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 234, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 234, 0, 0, 0, 1, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 234, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 235, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 237, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, -0, 242, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 249, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, -0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 250, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, -0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 208, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 210, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 210, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 228, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 228, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 230, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 230, 0, 0, 0, 3, 22, 0, -0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 249, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, -0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, -0, 2, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, -0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, -0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, -0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, -0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, -0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, -0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, -0, 38, 0, 0, 0, 32, 0, 4, 0, 190, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 195, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, -0, 32, 0, 4, 0, 209, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 211, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 213, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 214, 0, 0, -0, 4, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 215, 0, 0, 0, 6, 0, 0, 0, 214, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 229, 0, 0, -0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 231, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 233, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 234, 0, 0, -0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 235, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 242, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 249, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 250, 0, 0, -0, 2, 0, 0, 0, 249, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 250, 0, 0, -0, 251, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, 208, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 215, 0, 0, 0, 216, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, -0, 226, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 227, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 229, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 231, 0, 0, 0, 230, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 235, 0, 0, -0, 236, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 136, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, -0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, -0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 189, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, -0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, -0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, -0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 198, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 120, 0, 0, -0, 65, 0, 5, 0, 190, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 203, 0, 0, 0, 201, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 218, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 219, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 221, 0, 0, -0, 210, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 221, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 222, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 223, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, -0, 223, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 225, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 238, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 239, 0, 0, -0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 240, 0, 0, 0, 227, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 240, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 243, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 241, 0, 0, 0, 243, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 244, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 226, 0, 0, 0, 246, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 247, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 248, 0, 0, 0, 247, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, -0, 248, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 228, 13, 54, 98, 231, 53, 171, 232, 53, 251, 148, 122, 53, 33, 81, 141, 0, 192, 20, 0, 0, 3, 2, 35, 7, -0, 4, 1, 0, 0, 0, 0, 0, 253, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 217, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, -210, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 251, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 237, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 227, 0, 0, 0, 230, 0, 0, 0, 226, 0, 0, 0, -228, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 251, 0, 0, 0, 16, 0, 3, 0, 217, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, -7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, -3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, -115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, -7, 0, 21, 0, 204, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 205, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 206, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 207, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, +0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, +114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, +108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, +117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, +99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, +97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, +86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, +116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, +70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, +32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, +114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, +99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, +10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, +104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, +116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, +46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, +110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, +41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, +32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, +104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, +101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, +125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, +97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, +69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, +104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, +99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, +76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, +114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, +99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, +101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, +112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, +71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, +117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, +83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, +61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, +112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, +114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, +121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, +32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, +1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, +110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, +32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, +111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, +114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, +114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, +105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, +109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, +111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, +101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, +100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, +100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, +98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, +100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, +116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, +114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, +114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, +0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, +0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, +0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, +86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, +0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, +103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 190, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, 0, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 206, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 207, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, +116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 216, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 222, 0, 0, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, +0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, +0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, +102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, +0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, +111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, +0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, +0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, +0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, +0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, +0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, +0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, +0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, +0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, +0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, +0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, +0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 204, 0, 0, +0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 207, 0, 0, 0, 6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, 0, 1, 0, 0, +0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, +0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 234, 0, 0, +0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, +0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, +0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 228, 0, 0, +0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, +0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, +0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, +0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, +0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, +0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, +0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 213, 0, 0, 0, 202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, +0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, 0, 219, 0, 0, +0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, 0, 65, 0, 5, +0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 202, 222, 150, 118, 190, 241, 200, 207, 222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, +14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 209, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 243, 0, 0, 0, +15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, 209, 0, 0, 0, +7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, +117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, +58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, +117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, +83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, +83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, +32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, +47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, +116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, +86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, +97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, +117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, +116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, +101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, +100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, +110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, +32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, +32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, +105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, +104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, +32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, +104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, +35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, +111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, +67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, +101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, +111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, +111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, +114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, +95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, +76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, +10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, +115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, +82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, +112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, +80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, +101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, +114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, +32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, +98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, +97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, +59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, +47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, +116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, +116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, +46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, +100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, +99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, +32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, +86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, +111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, +101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, +32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, +84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, +116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, +111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, +73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, +32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, 32, 115, 112, 114, +105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, -111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, -120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, -46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, -189, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 190, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 194, 0, 0, 0, -102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 209, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, -5, 0, 7, 0, 211, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 210, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 80, 83, 95, 73, -78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 212, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 213, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 213, 0, 0, 0, 0, 0, 0, 0, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 214, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 214, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 214, 0, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 215, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, -83, 0, 0, 0, 5, 0, 9, 0, 217, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 220, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 224, 0, 0, 0, -105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 226, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 227, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -5, 0, 7, 0, 229, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 228, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 231, 0, 0, 0, 112, 116, 114, 95, -73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 230, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 232, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, -232, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 232, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 233, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, -6, 0, 7, 0, 233, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 233, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 234, 0, 0, 0, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 234, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 234, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -234, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 235, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 236, 0, 0, 0, 115, 116, 114, 101, -97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 237, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 242, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, -249, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, -250, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 251, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, -208, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 210, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 210, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 226, 0, 0, 0, 11, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 227, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 227, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 228, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, -228, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 230, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 230, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, -249, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, -72, 0, 5, 0, 249, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 34, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 251, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, +117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, +111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, +119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, +46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, +185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 190, 0, 0, 0, +102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, +5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 80, 83, 95, 73, +78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, 0, 0, 0, 0, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 206, 0, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 207, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, +83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 216, 0, 0, 0, +105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, 112, 116, 114, 95, +73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 222, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, +224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, 115, 116, 114, 101, +97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, +241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, +242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, +200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 11, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, +220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, +241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, +72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 34, 0, 0, 0, +0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, -6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, -24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, -139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 190, 0, 0, 0, 2, 0, 0, 0, -4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 195, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 194, 0, 0, 0, 32, 0, 4, 0, 209, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, -32, 0, 4, 0, 211, 0, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 212, 0, 0, 0, 43, 0, 0, 0, 30, 0, 3, 0, 213, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 214, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 215, 0, 0, 0, -6, 0, 0, 0, 214, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 220, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 224, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 229, 0, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 231, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 232, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 233, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 234, 0, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -235, 0, 0, 0, 6, 0, 0, 0, 234, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 242, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 249, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 250, 0, 0, 0, 2, 0, 0, 0, 249, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, -41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 250, 0, 0, 0, 251, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, -208, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, 210, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 215, 0, 0, 0, 216, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 209, 0, 0, 0, 226, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 211, 0, 0, 0, -227, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 229, 0, 0, 0, 228, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 231, 0, 0, 0, 230, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 235, 0, 0, 0, 236, 0, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, -118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, -137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, -216, 0, 0, 0, 224, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 189, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, -248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, -38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, -56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 189, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 198, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 201, 0, 0, 0, 120, 0, 0, 0, 65, 0, 5, 0, 190, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, -224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 0, 0, 0, 252, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 203, 0, 0, 0, 201, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 217, 0, 0, 0, -0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 218, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 219, 0, 0, 0, 216, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 221, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 219, 0, 0, 0, 221, 0, 0, 0, -57, 0, 4, 0, 30, 0, 0, 0, 222, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 223, 0, 0, 0, 216, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 225, 0, 0, 0, 223, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 225, 0, 0, 0, -253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 237, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 238, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 239, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, -240, 0, 0, 0, 227, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 240, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 0, 0, 0, 236, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 241, 0, 0, 0, -243, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 244, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 245, 0, 0, 0, 236, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 62, 0, 3, 0, 226, 0, 0, 0, -246, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 247, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 248, 0, 0, 0, 247, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 248, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, -0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, +24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, +138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 2, 0, 0, 0, +4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, +32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 204, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 207, 0, 0, 0, +6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, +1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, +40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, +200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, +219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, +228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, +61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, +28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, +208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, +4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, +172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, +87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, +5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 119, 0, 0, 0, +65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, +56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 213, 0, 0, 0, +202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, +215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 0, 0, 0, +228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, 0, 219, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, +240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs index a19d232f82..b2f96d9fbd 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -19,45 +19,43 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, -108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, -0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, -90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 132, 19, 121, 167, 249, 219, 0, 200, 135, 138, 10, 186, 134, 37, 106, 0, 0, 76, -76, 0, 0, 68, 88, 66, 67, 176, 53, 22, 232, 65, 34, 46, 61, 237, 16, 218, 78, 85, 126, 100, 8, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, 0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, 76, 0, 0, 65, -111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, -2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, 54, 66, 48, 0, 171, 171, 171, 40, -0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 70, 0, 0, 0, 212, 2, 0, 0, 72, 0, 0, 0, 228, 2, 0, 0, 79, 0, 0, 0, 244, 2, 0, 0, 81, 0, 0, 0, 8, 3, 0, 0, 81, 0, 0, 0, 24, -3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, -52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, 1, 0, 0, 12, -1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 64, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, -0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 156, 1, 0, 0, 172, 1, 0, 0, 12, 1, 0, 0, 184, 1, 0, 0, 200, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 216, 1, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 28, 1, 0, 0, 0, 0, 0, 0, 40, -1, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 116, 1, 0, 0, 40, 1, 0, 0, 128, 1, 0, 0, 240, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, -32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, -8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, -0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, -85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, -0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, -0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, -80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, +0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, +109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, +46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 85, 208, 2, 0, 69, 134, 201, 202, 91, 45, 231, 205, 231, 137, +111, 84, 0, 76, 76, 0, 0, 68, 88, 66, 67, 128, 59, 86, 242, 120, 156, 74, 158, 136, 228, 50, 166, 221, 47, 10, 237, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, 0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, +76, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, +0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 57, 57, 66, 56, 0, +171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 70, 0, 0, 0, 212, 2, 0, 0, 72, 0, 0, 0, 228, 2, 0, 0, 79, 0, 0, 0, 244, 2, 0, 0, 81, 0, 0, 0, 8, 3, 0, 0, 81, +0, 0, 0, 24, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, +0, 3, 0, 95, 52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, +1, 0, 0, 12, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 64, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, +122, 122, 108, 101, 0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 156, 1, 0, 0, 172, 1, 0, 0, 12, 1, 0, 0, 184, 1, 0, 0, 200, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 216, 1, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 248, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 28, 1, 0, 0, 0, +0, 0, 0, 40, 1, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 100, 1, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 116, 1, 0, 0, 40, 1, 0, 0, 128, 1, 0, 0, 240, 1, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 77, 105, 99, 114, 111, +115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, +0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, +0, 15, 128, 0, 0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, +0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, +0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, +0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, +0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -65,7 +63,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -73,7 +71,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -81,7 +79,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -89,63 +87,63 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 156, 99, 6, 68, 59, 240, 200, 69, 146, 131, 182, 227, 96, 235, 238, 102, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, -81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 228, 193, 33, 179, 194, 143, 143, 76, 179, 140, 76, 235, 217, 41, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, -10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, -108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 142, -5, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, +122, 108, 101, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, +83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, +107, 3, 0, 142, 5, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, -10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, -111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, -108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, -116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, -95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, -101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, -105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, -125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, -102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, -125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, -105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, -105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, +80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, +122, 108, 101, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, +83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, +10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, +110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, +114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, +32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, +32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, +83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -153,55 +151,55 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 192, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, 54, 66, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, -99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, -98, 97, 56, 54, 98, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 143, 5, 217, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 62, 245, 67, 219, 11, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 192, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 57, 57, 66, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, +115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, +57, 97, 56, 51, 57, 54, 57, 57, 98, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, +80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 60, 217, 99, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 62, 245, 67, 219, 11, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, -111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, -115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, -16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, -0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, -0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, -16, 0, 0, 7, 0, 9, 5, 13, 34, 6, 8, 12, 128, 128, 0, 8, 0, 13, 33, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 59, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 58, 1, 92, 12, 128, -128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, -3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, -0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, -0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 209, 220, 250, 101, 106, 67, 151, -55, 132, 146, 64, 71, 126, 136, 126, 22, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, 0, 0, 0, 103, -0, 0, 128, 120, 0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, 0, 16, 0, 5, -0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, -0, 0, 0, 85, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, +101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, +49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, +0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, +0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, +0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, +0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, +3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 34, 6, 8, 12, 128, 128, 0, 8, 0, 13, 33, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 59, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 58, +1, 92, 12, 128, 128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, +13, 90, 6, 5, 3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, +0, 5, 0, 8, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, +0, 32, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 209, 220, 250, +101, 106, 67, 151, 55, 132, 146, 64, 71, 126, 136, 126, 22, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, +0, 0, 0, 103, 0, 0, 128, 120, 0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, +0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, +16, 0, 0, 0, 0, 0, 0, 85, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, -0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, -80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, -0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, -0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, -243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, -16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, -0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 170, 243, 1, 0, 72, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, +0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, +0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, +16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, +112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, +0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, +16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 170, 243, 1, 0, 72, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -209,55 +207,55 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, -67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, -116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, -95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, -83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, -101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, -105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, -125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, -114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, -102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, -125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, -105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, -105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, -110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, +32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, +10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, +110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, +114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, +97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, +32, 32, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, +111, 114, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 32, 61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, +32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, +32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, +83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 108, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, -0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, -0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 108, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, +0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, +105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, -0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 42, -0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, +0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 80, 83, 77, 97, +105, 110, 0, 42, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 243, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -265,15 +263,15 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, -48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, +116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -281,31 +279,31 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, -255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 65, 56, -54, 66, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, +0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, +51, 57, 54, 57, 57, 66, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 156, 99, 6, 68, 59, 240, 200, 69, 146, 131, 182, 227, 96, 235, 238, 102, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, -100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, -92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 97, 56, 54, 98, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, -0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 228, 193, 33, 179, 194, 143, 143, 76, 179, 140, 76, 235, 217, 41, 160, 0, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, +47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, +104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 57, 57, 98, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 240, 8, 0, 0, 128, 0, 0, 0, 11, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, -2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, -0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 240, 8, 0, 0, 128, 0, 0, 0, 11, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, +0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, +0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -329,40 +327,40 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, -110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, -0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, -0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 135, 221, 54, 159, 230, 55, 150, 185, 146, 186, 63, 39, 241, 96, 42, 12, 0, 76, 76, 0, 0, 68, 88, 66, 67, 234, 178, 68, 251, 216, 50, 142, 58, 243, 21, 245, 44, 111, 103, 12, 48, 1, -0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 74, 0, 0, 224, 74, 0, 0, 44, 75, 0, 0, 196, 75, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, -0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 2, -0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, -66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, -2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 102, 0, 0, 0, 224, 2, 0, 0, 104, 0, 0, 0, 244, 2, 0, 0, 104, 0, 0, 0, 0, 3, 0, 0, 106, 0, 0, 0, 12, 3, 0, 0, 102, 0, 0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, -83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, -1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 68, 1, 0, 0, 4, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 5, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 7, 0, 0, 0, 2, -0, 3, 0, 4, 0, 5, 0, 8, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 188, 1, 0, 0, 232, 0, 0, 0, 203, 1, 0, 0, 8, 1, 0, 0, 218, 1, 0, 0, 8, 1, 0, 0, 230, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, -0, 4, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 208, 0, 0, 0, 100, -1, 0, 0, 5, 0, 0, 0, 116, 1, 0, 0, 208, 0, 0, 0, 176, 1, 0, 0, 20, 2, 0, 0, 4, 0, 0, 0, 36, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, -114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, -0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, -72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, -0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, -16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, -0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, -0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, +116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, +0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, +0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 164, 242, 206, 148, 101, 151, 120, 104, 93, 47, 113, 96, 33, 115, 193, 164, 0, 76, 76, 0, 0, 68, 88, 66, 67, 81, 191, 6, 99, 252, 117, 156, 87, 62, 77, 89, 204, 54, +36, 181, 180, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 74, 0, 0, 224, 74, 0, 0, 44, 75, 0, 0, 196, 75, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, +0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, +0, 0, 0, 2, 0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, +101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, +0, 255, 255, 200, 2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 102, 0, 0, 0, 224, 2, 0, 0, 104, 0, 0, 0, 244, 2, 0, 0, 104, 0, 0, 0, 0, 3, 0, 0, 106, 0, 0, 0, 12, 3, 0, 0, 102, 0, 0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, +117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, +1, 0, 0, 56, 1, 0, 0, 8, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 68, 1, 0, 0, 4, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 5, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 7, +0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 8, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 188, 1, 0, 0, 232, 0, 0, 0, 203, 1, 0, 0, 8, 1, 0, 0, 218, 1, 0, 0, 8, 1, 0, 0, 230, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, +0, 11, 0, 1, 0, 4, 0, 244, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 3, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 208, +0, 0, 0, 100, 1, 0, 0, 5, 0, 0, 0, 116, 1, 0, 0, 208, 0, 0, 0, 176, 1, 0, 0, 20, 2, 0, 0, 4, 0, 0, 0, 36, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, +112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, +0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, +255, 0, 0, 83, 72, 68, 82, 192, 0, 0, 0, 64, 0, 1, 0, 48, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, +0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, +0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, +30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, +0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -370,7 +368,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -378,7 +376,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -386,7 +384,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -394,23 +392,23 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 11, 82, 101, 68, 46, 124, 64, 75, 161, 217, 238, 229, 178, 163, 235, 11, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 214, 190, 179, 45, 213, 59, 117, 77, 145, 229, 23, 78, 36, 189, 184, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, -122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, +97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -418,144 +416,145 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, -122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, -110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, -32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, -117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, -82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, -51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, -50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, -125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, -10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, -116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 167, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, -105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, -48, 48, 48, 49, 101, 97, 51, 48, 101, 99, 97, 49, 48, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, -83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 134, 191, 219, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 183, 74, 243, 36, 242, 9, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, +97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, +32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, +54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, +48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, +104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, +32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, +61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, +110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 167, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 0, 99, 58, 92, 100, 101, 118, +92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, +48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 54, 55, 99, 102, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 246, 49, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 183, 74, 243, 36, 242, 9, 0, 0, 1, 0, 0, 0, 90, +0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, +76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, +108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 8, 16, 0, 0, 108, 0, 0, 0, 1, +0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, +0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, +0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, +0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, +0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, +0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, +0, 84, 0, 8, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 133, 244, 175, 170, 177, 52, 113, 157, 86, 176, 18, 112, 12, 19, 68, 215, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, +0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 114, 0, 0, 128, 108, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 114, 0, 0, 128, 128, 0, 0, 0, 114, 0, 0, 0, 148, 0, 0, 0, 114, 0, 0, 128, 148, 0, 0, 0, 114, 0, 0, 0, 168, 0, 0, 0, 114, +0, 0, 128, 168, 0, 0, 0, 114, 0, 0, 0, 188, 0, 0, 0, 114, 0, 0, 128, 188, 0, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, +0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, -83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, -108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 52, 3, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 8, 16, 0, 0, 108, 0, 0, 0, 1, 0, 160, 109, 97, -105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, -0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, -0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, -0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 48, 0, 0, 0, 58, -0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 28, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 40, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 108, -0, 0, 0, 1, 0, 84, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 0, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 108, 0, 0, 0, 1, 0, 84, 0, 8, -0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 133, 244, 175, 170, 177, 52, 113, 157, 86, 176, 18, 112, 12, 19, 68, 215, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 192, 0, 0, 0, 0, 0, 0, 0, 10, -0, 0, 0, 132, 0, 0, 0, 108, 0, 0, 0, 114, 0, 0, 128, 108, 0, 0, 0, 114, 0, 0, 0, 128, 0, 0, 0, 114, 0, 0, 128, 128, 0, 0, 0, 114, 0, 0, 0, 148, 0, 0, 0, 114, 0, 0, 128, 148, 0, 0, 0, 114, 0, 0, 0, 168, 0, 0, 0, 114, 0, 0, 128, 168, -0, 0, 0, 114, 0, 0, 0, 188, 0, 0, 0, 114, 0, 0, 128, 188, 0, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, -0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, +0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, +21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, +0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, +82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, +16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, +116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, +0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 132, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, -0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, -16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, -114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, -0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, -0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, -16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, +79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, +86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, +32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, +54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, +48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, +104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, +32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, +61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, +99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, +97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, +110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, +116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, -117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, -111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, -82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, -51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, -50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 102, 97, 108, 115, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, -114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, 32, 32, 32, 32, 125, 10, -125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, -97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, -105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, -10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, -116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, -10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -569,48 +568,49 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 56, 3, 0, 0, 0, 0, 0, 0, 196, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, +0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, +114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, -0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 56, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, -0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, -92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, -49, 69, 65, 51, 48, 69, 67, 65, 49, 48, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 214, 190, 179, 45, 213, 59, 117, 77, 145, 229, 23, 78, 36, 189, 184, 47, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, +109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, +105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 54, 55, 99, 102, 56, 0, 4, 0, 0, 0, 6, 0, 0, +0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 11, 82, 101, 68, 46, 124, 64, 75, 161, 217, 238, 229, 178, 163, 235, 11, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, -47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, -103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 101, 99, 97, 49, 48, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, -0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 215, 10, 0, 0, 128, 0, 0, 0, 242, 9, 0, 0, 4, 4, 0, 0, 44, +0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, +0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 188, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 215, 10, 0, 0, 128, 0, 0, 0, 242, 9, 0, 0, 4, 4, 0, 0, 44, 0, 0, 0, 0, -0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 14, -0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -632,16 +632,14 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, -76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, -0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, -0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, +32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, +3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, +0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, 0, 0, 0, 8, +0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, +0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index ba637b3834..2ce138736e 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -28,245 +28,587 @@ internal partial class UIEffect 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -138, 19, 107, 122, 199, 8, 163, 87, 21, 65, 113, 115, 15, 239, 117, 147, 0, 172, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, -100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, -0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, -0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, -0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, -0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, -108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, -0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, -101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, -0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, -114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, -0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, -55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, -0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, -0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, -0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, -0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, -0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, -101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, -116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, -122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, -110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, -0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, -0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, -84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, -122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, -0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, -0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, -0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, -0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, -105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, -119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, -0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, -0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, -0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, -0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, -0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, -114, 0, 0, 0, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, -0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, -0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, -76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, -0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, -0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, -0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, -0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, -0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, -64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, -63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, -0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, -0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, -0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, -0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, -0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, -0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, -0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, -0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, -0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, -0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, -0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, -0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, -0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, -0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, -0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, -0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, -0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, -0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, -0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, -0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, -0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, -0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, -0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, -0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, -0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, -0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, -0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, -0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, -0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, -0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, -0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, -0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, -0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, -0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, -0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, -0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 138, 19, 107, 122, 199, 8, 163, 87, 21, 65, 113, 115, 15, 239, 117, 147, 0, 172, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, -0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, -105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, 0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, -101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, -116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, -7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, -5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, -102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, -5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, -111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, -85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, -112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, -116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, -49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, -154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, -105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, -52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, -48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, -48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, -5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, -97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, -115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, -116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, -5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, -112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, -111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, -83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, -1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, -101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, -209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, -216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, -5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, -122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, -228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, -3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, -71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, -67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, -2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, -71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, -0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, -64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, -86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, -138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, -174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, -43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, -43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, -43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, -38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, -43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, -174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, -225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, -4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, -88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, -193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, -217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, -222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, -154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, -158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, -136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, -166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, -169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, -171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, -155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, -54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, -65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, -84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, -248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, -59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, -65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, -160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, -248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, -140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, -171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, -206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, -0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, -65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, -209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, -213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, -229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, -237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, -240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, -243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, -229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, +100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, +0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, +0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, +67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, +117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, +105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, +111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, +109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, +71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, +73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, +103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, +101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, +76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, +112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, +114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, +76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, +73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, +0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, +115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, +104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, +80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, +0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, +110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, +41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, +32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, +104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, +116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, +50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, +101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, +105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, +59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, +32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, +80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, +32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, +111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, +116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, +65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, +10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, +32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, +116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, +114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, +109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, +114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, +116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, +115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, +116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, +108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, +104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, +108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, +32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, +48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, +97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, +71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, +51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, +111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, +97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, +110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, +97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, +111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, +32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, +48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, +67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, +102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, +32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, +66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, +53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, +32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, +103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, +32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, +97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, +112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, +102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, +1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, +110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, +32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, +111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, +72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, +115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, +105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, +109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, +32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, +111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, +0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, +0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, +111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, +111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, +0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, +95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, +49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, +0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, +0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, +0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, +0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, +104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, +67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, +95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, +0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, +117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, +0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, +101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, +0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, +0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, +0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, +0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, +102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, +0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, +0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, +0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, +0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, +0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, +0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, +0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, +0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, +0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, +0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, +0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, +0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, +0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, +0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, +0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, +0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, +0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, +0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, +0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, +0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, +0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, +0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, +0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, +0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, +0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, +0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, +0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, +0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, +0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, +0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, +0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, +0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, +0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, +0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, +0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, +0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, +0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, +0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, +0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, +0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, +0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, +0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, +0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, +0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, +0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, +0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, +0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, +0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, +0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, +11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, +184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, +215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, +0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, +32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, +117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, +111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, +32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, +13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, +60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, +32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, +97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, +116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, +116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, +97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, +0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, +117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, +32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, +114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, +111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, +112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, +101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, +32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, +117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, +58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, +117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, +83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, +116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, +32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, +101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, +101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, +117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, +32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, +95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, +66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, +32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, +101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, +83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, +110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, +73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, +32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, +116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, +0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, +100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, +114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, +111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, +32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, +109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, +48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, +115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, +41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, +54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, +111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, +71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, +109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, +97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, +97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, +112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, +110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, +32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, +98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, +49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, +50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, +49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, +46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, +32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, +41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, +61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, +32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, +97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, +103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, +48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, +114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, +32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, +110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, +10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, +110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, +98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, +84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, +100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, +40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, +101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, +102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, +85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, +114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, +54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, +97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, +5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, +248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, +77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, +83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, +5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, +5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, +109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, +5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, +73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, +188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, +6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, +191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, +6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, +5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, +50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, +216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, +108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, +3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, +221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, +222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, +122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 225, 1, 0, 0, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, +30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, +71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, +30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, +84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, +216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, +218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, +33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, +23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, +42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, +5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, +86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, +121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, +3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, +153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, +186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, +2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, +32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, +27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, +187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, +192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, +2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, +5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, +59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, +59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, +59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, +54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, +158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, +156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, +129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, +132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, +0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, +26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, +10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, +7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, +113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, +204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, +249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, +137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, +139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, +150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, +160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, +9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, +170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, +170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, +35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, +4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, +197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, +203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, +182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, +62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, +18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, +62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs index 08b57ecd6b..543c6cbc4a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -19,45 +19,43 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, -108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, -0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, -90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, -182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, -62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 46, 32, 228, 6, 251, 177, 93, 246, 133, 15, 251, 122, 98, 177, 33, 174, 0, 72, -76, 0, 0, 68, 88, 66, 67, 60, 211, 228, 5, 120, 180, 199, 224, 249, 196, 224, 120, 231, 126, 120, 60, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, 0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, 76, 0, 0, 65, -111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, 0, 0, 0, 120, -2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, 171, 171, 171, 40, -0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 70, 0, 0, 0, 208, 2, 0, 0, 72, 0, 0, 0, 224, 2, 0, 0, 79, 0, 0, 0, 240, 2, 0, 0, 81, 0, 0, 0, 4, 3, 0, 0, 81, 0, 0, 0, 20, -3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 50, 51, 0, -171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, 1, 0, 0, 5, -0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 60, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 171, 0, -0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 168, 1, 0, 0, 8, 1, 0, 0, 180, 1, 0, 0, 196, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, -0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 36, 1, 0, 0, 68, -1, 0, 0, 1, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 112, 1, 0, 0, 36, 1, 0, 0, 124, 1, 0, 0, 236, 1, 0, 0, 2, 0, 0, 0, 252, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, -32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, -0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 128, 1, -0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, -16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, 0, 16, 0, 0, -0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, 0, 16, 0, 1, -0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, -70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, +0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, +83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, +109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, +46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 92, 151, 44, 227, 56, 86, 47, 168, 45, 133, 11, 224, 190, 181, +173, 14, 0, 72, 76, 0, 0, 68, 88, 66, 67, 214, 58, 108, 183, 213, 193, 42, 143, 34, 165, 105, 72, 235, 243, 83, 178, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, 0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, +76, 0, 0, 65, 111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, +0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, 54, 68, 48, 0, +171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 70, 0, 0, 0, 208, 2, 0, 0, 72, 0, 0, 0, 224, 2, 0, 0, 79, 0, 0, 0, 240, 2, 0, 0, 81, 0, 0, 0, 4, 3, 0, 0, 81, +0, 0, 0, 20, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, +52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, +1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 60, 1, 0, 0, 7, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, +0, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 152, 1, 0, 0, 168, 1, 0, 0, 8, 1, 0, 0, 180, 1, 0, 0, 196, 1, 0, 0, 5, 0, 0, 0, 1, 0, 7, 0, 1, 0, 3, 0, 212, 1, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 6, 0, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 200, 0, 0, 0, 228, 0, 0, 0, 1, 0, 0, 0, 244, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 24, 1, 0, 0, 0, 0, 0, 0, 36, +1, 0, 0, 68, 1, 0, 0, 1, 0, 0, 0, 84, 1, 0, 0, 0, 0, 0, 0, 96, 1, 0, 0, 8, 1, 0, 0, 1, 0, 0, 0, 112, 1, 0, 0, 36, 1, 0, 0, 124, 1, 0, 0, 236, 1, 0, 0, 2, 0, 0, 0, 252, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, +32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 7, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, +8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 5, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 176, 0, 0, 170, 176, 88, 0, 0, 4, 0, 0, 14, 128, 1, 0, 255, 129, 0, 0, 228, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, +0, 228, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 224, 0, 0, 0, 64, 0, 0, 0, 56, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, +85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 66, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 2, 0, 0, 0, 24, 0, 0, 7, 18, +0, 16, 0, 0, 0, 0, 0, 42, 16, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 1, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 226, +0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 86, 14, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, +80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -65,7 +63,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -73,7 +71,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -81,7 +79,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -89,175 +87,175 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 27, 227, 109, 42, 194, 68, 17, 68, 135, 27, 15, 241, 78, 81, 40, 62, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 96, 9, 128, 56, 129, 214, 178, 78, 129, 44, 132, 90, 220, 199, 198, 67, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, +81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 142, +5, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 117, 131, 1, 0, 198, 90, 0, 0, 173, 175, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 142, 5, 3, 0, 149, -49, 3, 0, 125, 218, 1, 0, 152, 113, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, +108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, +116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, +108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, +122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, +10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, +61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, -10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, -10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, -108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, -122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, -32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, -100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, -105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, -69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, -46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, -77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, -32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 188, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, +92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, 54, 68, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, +57, 100, 99, 54, 100, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 4, 195, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 35, 239, 192, 163, 7, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 188, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, -100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, -101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 52, 53, 50, -51, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 218, 184, 215, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 35, 239, 192, 163, 7, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, +111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, +115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, +16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, +0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, +0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, +0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, +0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, +16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 8, 12, 128, 128, 0, 8, 0, 13, 32, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 58, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 57, 1, 92, 12, 128, +128, 0, 0, 78, 0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, +3, 28, 9, 5, 13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, +0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, +0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 162, 230, 18, 107, 157, 250, 40, +101, 185, 28, 2, 100, 78, 148, 241, 36, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, 0, 0, 0, 103, +0, 0, 128, 120, 0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, 0, 16, 0, 5, +0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, +0, 0, 0, 85, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, -108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, -116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 224, 3, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, 0, 8, 16, 0, 0, 92, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, -0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, -0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 92, -0, 0, 0, 1, 0, 132, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, -0, 5, 0, 24, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, -0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 92, 0, 0, 0, 1, 0, 132, 0, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 220, 3, 0, 0, 0, 16, 0, 0, 7, -0, 9, 5, 13, 33, 6, 8, 12, 128, 128, 0, 8, 0, 13, 32, 1, 92, 12, 128, 128, 0, 0, 0, 38, 0, 77, 17, 44, 2, 0, 0, 216, 3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 58, 11, 32, 4, 128, 128, 8, 0, 9, 29, 13, 57, 1, 92, 12, 128, 128, 0, 0, 78, -0, 77, 17, 84, 2, 0, 0, 212, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 34, 11, 96, 13, 91, 6, 5, 3, 28, 13, 5, 6, 18, 3, 36, 13, 43, 6, 4, 12, 28, 36, 8, 0, 9, 9, 13, 33, 1, 92, 6, 19, 3, 0, 9, 27, 13, 90, 6, 5, 3, 28, 9, 5, -13, 5, 6, 18, 3, 36, 9, 12, 13, 42, 6, 4, 12, 28, 36, 50, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 156, 0, 0, 0, 1, 0, 68, 0, 16, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 156, -0, 0, 0, 1, 0, 36, 0, 24, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 156, 0, 0, 0, 1, 0, 36, 0, 28, 0, 0, 0, 42, 0, 62, 17, 1, 16, 0, 0, 8, 0, 95, 52, 50, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 20, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 24, 0, 0, 0, 22, -0, 80, 17, 0, 0, 5, 0, 12, 0, 4, 0, 192, 0, 0, 0, 1, 0, 32, 0, 28, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 162, 230, 18, 107, 157, 250, 40, 101, 185, 28, 2, -100, 78, 148, 241, 36, 0, 0, 242, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 224, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 132, 0, 0, 0, 92, 0, 0, 0, 103, 0, 0, 128, 92, 0, 0, 0, 103, 0, 0, 0, 120, 0, 0, 0, 103, 0, 0, 128, 120, -0, 0, 0, 103, 0, 0, 0, 156, 0, 0, 0, 103, 0, 0, 128, 156, 0, 0, 0, 103, 0, 0, 0, 192, 0, 0, 0, 103, 0, 0, 128, 192, 0, 0, 0, 103, 0, 0, 0, 220, 0, 0, 0, 106, 0, 0, 128, 220, 0, 0, 0, 106, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, -0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 85, -0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, +0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, +0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, +0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, +243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, +16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, +0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 20, 209, 2, 0, 170, 56, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 20, 16, 0, 0, 184, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 8, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, -0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 3, -0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, -95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, -0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, -8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, -0, 24, 21, 15, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 2, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 41, 75, 0, 0, 20, 209, 2, 0, 170, 56, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, +67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, +116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, +123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, +46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, +108, 115, 101, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, +122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, +10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, +61, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, +101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, +95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, +101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, -68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, -80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, -108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, -122, 122, 108, 101, 32, 61, 61, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 101, 108, 115, 101, 10, -32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 95, 52, 50, 51, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 120, 120, 120, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, -100, 67, 111, 108, 111, 114, 32, 61, 32, 95, 52, 50, 51, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 118, 111, -105, 100, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 85, 73, -69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, -46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, -77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, -117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, -32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, -117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 104, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, +0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, +0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 104, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, -0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, -0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, +0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, +0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, -0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 80, 83, 77, 97, 105, 110, 0, 241, 38, 0, 1, 22, 0, -0, 0, 0, 13, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -265,15 +263,15 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, -0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 16, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, +48, 0, 0, 38, 0, 81, 17, 19, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -281,31 +279,31 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, -0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 50, 69, 66, 52, 53, 50, 51, 56, 0, -0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, +255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, +54, 68, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 27, 227, 109, 42, 194, 68, 17, 68, 135, 27, 15, 241, 78, 81, 40, 62, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, -108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, -100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 50, 101, 98, 52, 53, 50, 51, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, -0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 96, 9, 128, 56, 129, 214, 178, 78, 129, 44, 132, 90, 220, 199, 198, 67, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, +100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, +92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 100, 99, 54, 100, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 236, 8, 0, 0, 128, 0, 0, 0, 7, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, -0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, -0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 240, 1, 0, 0, 111, 1, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 236, 8, 0, 0, 128, 0, 0, 0, 7, 8, 0, 0, 220, 4, 0, 0, 88, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 56, +2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 30, 0, 0, 0, 18, 0, 0, 0, 29, 0, 0, 0, 23, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, +0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 19, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 28, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -329,44 +327,44 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, -68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, -0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, -0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, -86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 29, 161, 12, 2, 233, 165, 178, 83, 112, 105, 229, 242, 0, 142, 46, 113, 0, 88, 77, 0, 0, 68, 88, 66, 67, 110, 135, 218, 8, 57, 42, 60, 65, 13, 102, 64, 206, 48, 224, 56, 141, 1, 0, 0, 0, 88, -77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 75, 0, 0, 236, 75, 0, 0, 56, 76, 0, 0, 208, 76, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, 0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, -0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 128, -2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, -99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 0, -0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 76, 0, 0, 0, 36, 3, 0, 0, 76, 0, 0, 0, 56, 3, 0, 0, 76, 0, 0, 0, 76, 3, 0, 0, 102, 0, 0, 0, 92, 3, 0, 0, 104, 0, 0, 0, 112, 3, 0, 0, 104, 0, 0, 0, 124, 3, 0, 0, 76, -0, 0, 0, 136, 3, 0, 0, 102, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, -108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 245, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 100, 1, 0, 0, 7, 0, 0, 0, 2, 0, 3, 0, 4, 0, 255, 255, 8, -0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 12, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 232, -1, 0, 0, 8, 1, 0, 0, 247, 1, 0, 0, 40, 1, 0, 0, 6, 2, 0, 0, 40, 1, 0, 0, 18, 2, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, 0, 0, 0, 2, -0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 240, 0, 0, 0, 132, 1, 0, 0, 6, 0, 0, 0, 148, 1, 0, 0, 240, 0, 0, 0, 220, 1, 0, 0, 64, 2, 0, 0, 4, -0, 0, 0, 80, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 1, 0, 15, 160, 18, 81, 156, 62, 196, 162, 46, 63, 194, -44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, 0, 7, 128, 2, -0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, -0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 80, 1, 0, 0, 64, -0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, -0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, -16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, 81, 156, 62, 0, -0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, 44, 77, 60, 194, -44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, -0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, -0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, +0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, +0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 52, 177, 78, 146, 1, 233, 45, 107, 92, 124, 24, 100, 170, 252, 158, 33, 0, 88, 77, 0, 0, 68, 88, 66, 67, 43, 242, 205, 80, 27, 132, 245, 245, 164, 110, 209, 218, 110, 176, 62, 232, 1, +0, 0, 0, 88, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 75, 0, 0, 236, 75, 0, 0, 56, 76, 0, 0, 208, 76, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, 0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, +0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, +0, 0, 0, 128, 2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, +66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, +3, 0, 0, 0, 0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 76, 0, 0, 0, 36, 3, 0, 0, 76, 0, 0, 0, 56, 3, 0, 0, 76, 0, 0, 0, 76, 3, 0, 0, 102, 0, 0, 0, 92, 3, 0, 0, 104, 0, 0, 0, 112, 3, 0, 0, 104, 0, 0, 0, 124, +3, 0, 0, 76, 0, 0, 0, 136, 3, 0, 0, 102, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, +83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 0, 245, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 56, 1, 0, 0, 72, 1, 0, 0, 88, 1, 0, 0, 40, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 100, 1, 0, 0, 7, 0, 0, 0, 2, 0, 3, 0, 4, +0, 255, 255, 8, 0, 0, 0, 7, 0, 8, 0, 255, 255, 255, 255, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 255, 255, 255, 255, 6, 0, 255, 255, 11, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 12, 0, 0, 0, 255, 255, 255, 255, 9, 0, 10, 0, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 232, 1, 0, 0, 8, 1, 0, 0, 247, 1, 0, 0, 40, 1, 0, 0, 6, 2, 0, 0, 40, 1, 0, 0, 18, 2, 0, 0, 72, 1, 0, 0, 5, 0, 0, 0, 1, 0, 11, 0, 1, 0, 4, 0, 32, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 2, +0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 3, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 4, 0, 0, 0, 10, 0, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 240, 0, 0, 0, 132, 1, 0, 0, 6, 0, 0, 0, 148, 1, 0, 0, 240, 0, 0, 0, 220, 1, 0, 0, 64, +2, 0, 0, 4, 0, 0, 0, 80, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 1, 0, 15, 160, 18, 81, 156, 62, 196, +162, 46, 63, 194, 44, 77, 60, 0, 0, 0, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 31, 0, 0, 2, 5, 0, 3, 128, 3, 0, 15, 144, 4, 0, 0, 4, 0, +0, 7, 128, 2, 0, 228, 144, 1, 0, 0, 160, 1, 0, 85, 160, 4, 0, 0, 4, 0, 0, 7, 128, 2, 0, 228, 144, 0, 0, 228, 128, 1, 0, 170, 160, 5, 0, 0, 3, 1, 0, 7, 224, 0, 0, 228, 128, 2, 0, 228, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, +0, 228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 0, 0, 4, 224, 3, 0, 0, 144, 1, 0, 0, 2, 1, 0, 8, 224, 2, 0, 255, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 80, +1, 0, 0, 64, 0, 1, 0, 84, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 95, 0, 0, 3, 18, 16, 16, 0, 3, 0, 0, 0, 101, 0, 0, 3, 50, +32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 66, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, +0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 66, 32, 16, 0, 0, 0, 0, 0, 10, 16, 16, 0, 3, 0, 0, 0, 50, 0, 0, 15, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 2, 64, 0, 0, 18, 81, 156, 62, 18, 81, 156, 62, 18, +81, 156, 62, 0, 0, 0, 0, 2, 64, 0, 0, 196, 162, 46, 63, 196, 162, 46, 63, 196, 162, 46, 63, 0, 0, 0, 0, 50, 0, 0, 12, 114, 0, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 194, 44, 77, 60, 194, +44, 77, 60, 194, 44, 77, 60, 0, 0, 0, 0, 56, 0, 0, 7, 114, 32, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 70, 18, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 1, 0, 0, 0, 58, 16, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, +32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, +0, 0, 0, 35, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -374,7 +372,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -382,7 +380,7 @@ internal partial class UIEffect 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -390,7 +388,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -398,111 +396,111 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 244, 255, 195, 78, 220, 92, 83, 71, 128, 23, 0, 238, 206, 173, 252, 43, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 211, 69, 4, 66, 89, 54, 16, 69, 144, 245, 60, 186, 23, 224, 116, 68, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, -59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, -99, 0, 0, 143, 154, 3, 0, 31, 105, 3, 0, 233, 240, 2, 0, 82, 155, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, +110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 117, 131, 1, 0, 198, 90, 0, 0, 152, 91, 1, 0, 8, 104, 0, 0, 38, 247, 2, 0, 130, 243, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, +133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 31, 105, 3, 0, 233, 240, 2, 0, 82, 155, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, -115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, -95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, -59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, 115, 116, 114, 117, -99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, -79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, -115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, -48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, -43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, -101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, -83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, -32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, -114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, -102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, -105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, -117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 164, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, -92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 0, 99, 58, -92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, -100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 100, 98, 97, 50, 54, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, -115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 134, 191, 219, 37, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 58, 5, 190, 176, 239, 9, 0, 0, 1, -0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, +125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, +50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, +110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, +111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 10, +115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, +32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, +120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, +53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, +32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, +116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 164, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, +103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, +0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, +92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 102, 57, 99, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, +125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 155, 124, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 58, 5, 190, 176, 239, +9, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, -82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, -52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 204, 3, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, 16, 0, 0, 116, -0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, -0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, -0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, -0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, -0, 220, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 116, -0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, -0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, -0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 116, -0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 200, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 10, 12, 128, 136, 40, 8, 0, 13, 32, 1, 128, 156, 12, 128, 136, 0, 0, 42, 0, 77, 17, 52, 3, 0, 0, 196, 3, 0, 0, 1, -16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 8, 0, 9, 27, 13, 53, 1, 128, 156, 12, 128, 136, 0, 0, 0, 0, 54, 0, 77, 17, 92, 3, 0, 0, 192, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, 8, 0, 9, 36, -13, 107, 1, 128, 156, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 100, 74, 125, 240, 195, 252, 162, 72, 19, 251, 144, -184, 185, 124, 245, 248, 0, 0, 242, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 114, 0, 0, 128, 116, 0, 0, 0, 114, 0, 0, 0, 136, 0, 0, 0, 114, 0, 0, 128, 136, -0, 0, 0, 114, 0, 0, 0, 156, 0, 0, 0, 108, 0, 0, 128, 156, 0, 0, 0, 108, 0, 0, 0, 216, 0, 0, 0, 108, 0, 0, 128, 216, 0, 0, 0, 108, 0, 0, 0, 8, 1, 0, 0, 108, 0, 0, 128, 8, 1, 0, 0, 108, 0, 0, 0, 36, 1, 0, 0, 114, 0, 0, 128, 36, -1, 0, 0, 114, 0, 0, 0, 56, 1, 0, 0, 114, 0, 0, 128, 56, 1, 0, 0, 114, 0, 0, 0, 76, 1, 0, 0, 114, 0, 0, 128, 76, 1, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, -0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, -16, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, +102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, +0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 49, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 204, 3, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 8, +16, 0, 0, 116, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 116, +0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, +0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, +0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 40, 0, 4, 0, 116, +0, 0, 0, 1, 0, 220, 0, 48, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, +0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 40, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 16, 0, 0, 0, 22, +0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 116, 0, 0, 0, 1, +0, 220, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, +0, 4, 0, 116, 0, 0, 0, 1, 0, 220, 0, 8, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 200, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 33, 6, 10, 12, 128, 136, 40, 8, 0, 13, 32, 1, 128, 156, 12, 128, 136, 0, 0, 42, 0, 77, 17, 52, 3, 0, 0, 196, +3, 0, 0, 1, 16, 0, 0, 7, 0, 9, 9, 13, 54, 6, 10, 12, 128, 136, 40, 8, 0, 9, 27, 13, 53, 1, 128, 156, 12, 128, 136, 0, 0, 0, 0, 54, 0, 77, 17, 92, 3, 0, 0, 192, 3, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 128, 160, 6, 4, 12, 128, 136, 40, +8, 0, 9, 36, 13, 107, 1, 128, 156, 3, 0, 9, 27, 13, 128, 148, 3, 60, 9, 19, 13, 128, 149, 12, 28, 48, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 100, 74, 125, 240, 195, 252, 162, +72, 19, 251, 144, 184, 185, 124, 245, 248, 0, 0, 242, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 80, 1, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 204, 0, 0, 0, 116, 0, 0, 0, 114, 0, 0, 128, 116, 0, 0, 0, 114, 0, 0, 0, 136, 0, 0, 0, 114, +0, 0, 128, 136, 0, 0, 0, 114, 0, 0, 0, 156, 0, 0, 0, 108, 0, 0, 128, 156, 0, 0, 0, 108, 0, 0, 0, 216, 0, 0, 0, 108, 0, 0, 128, 216, 0, 0, 0, 108, 0, 0, 0, 8, 1, 0, 0, 108, 0, 0, 128, 8, 1, 0, 0, 108, 0, 0, 0, 36, 1, 0, 0, 114, +0, 0, 128, 36, 1, 0, 0, 114, 0, 0, 0, 56, 1, 0, 0, 114, 0, 0, 128, 56, 1, 0, 0, 114, 0, 0, 0, 76, 1, 0, 0, 114, 0, 0, 128, 76, 1, 0, 0, 114, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, +0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 90, +0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 13, 16, 0, 0, 23, 0, 1, 0, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 8, 16, 13, 16, 0, 0, 23, 0, 1, 0, 12, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -510,15 +508,15 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 216, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, -0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 106, -0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, -16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, -0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, -21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, 0, 103, 108, 95, -80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, -0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, -0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 30, 167, 1, 0, 206, 172, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 216, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, +0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, +243, 242, 241, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, +21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 13, 21, 3, 0, 64, 0, 0, 0, 40, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 38, 0, 5, 21, 4, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 106, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, +0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 64, 0, 0, 0, 24, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 28, +0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 4, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, +16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, +0, 0, 0, 10, 0, 1, 18, 1, 0, 0, 0, 1, 16, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 148, 128, 1, 0, 30, 167, 1, 0, 206, 172, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -526,61 +524,56 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, -79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, -111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, -97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, -115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, -48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 41, 32, -43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, 73, 69, 102, 102, -101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, -83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, 53, 41, 59, 10, -32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, -114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 85, 73, 69, 102, -102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 10, 10, -83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, -111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, -105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, -117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, -0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, +32, 67, 79, 76, 79, 82, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, +86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 50, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, +115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 120, 121, 122, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, 32, 40, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 55, 51, 57, 56, 56, 51, 52, 50, 50, 56, 53, 49, 53, 54, 50, 53, 102, 46, 120, 120, 120, 41, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 48, 54, 51, 51, 56, 53, 48, 48, 57, 55, 54, 53, 54, 50, 53, 102, 46, 120, 120, +120, 41, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 49, 50, 53, 51, 48, 57, 57, 52, 52, 49, 53, 50, 56, 51, 50, 48, 51, 49, 50, 53, 102, 46, 120, 120, 120, 41, 44, 32, 115, 82, 71, 66, 97, 46, 119, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 85, +73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 116, 114, 117, 101, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 55, 53, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 40, 95, 51, 55, +53, 41, 59, 10, 32, 32, 32, 32, 125, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, +67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 119, 105, 122, 122, 108, 101, 59, +10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, +32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 118, 101, 114, +116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 12, -0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, -114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, +0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, +104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 80, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, +0, 0, 96, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 38, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, +104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 86, 83, 77, 97, 105, 110, 0, 241, 34, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 95, 84, 111, 76, 105, 110, 101, 97, 114, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -590,63 +583,68 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, 3, 0, 0, 0, -0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, -118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, -64, 48, 120, 48, 48, 48, 48, 48, 49, 69, 65, 51, 48, 68, 66, 65, 50, 54, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 66, 48, 194, 105, 1, 0, 0, 0, 244, 255, 195, 78, 220, 92, 83, 71, 128, 23, 0, 238, 206, 173, 252, 43, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, -0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, -92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 101, 97, 51, 48, 100, 98, 97, 50, 54, 56, 0, 4, 0, 0, -0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 16, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 212, 10, 0, 0, 128, 0, 0, 0, 239, 9, 0, 0, 8, -5, 0, 0, 68, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 21, 0, 0, 0, 22, -0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, -0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 208, +3, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, +58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, +97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 211, 69, 4, 66, 89, 54, 16, 69, 144, 245, 60, 186, 23, 224, 116, 68, 134, 0, 0, 0, 47, 76, 105, 110, 107, +73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, +103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 102, 57, 99, 101, 56, +0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 226, 0, 0, 0, 16, 2, 0, 0, 111, 1, 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, 212, 10, 0, 0, 128, 0, 0, 0, 239, +9, 0, 0, 8, 5, 0, 0, 68, 0, 0, 0, 20, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 19, 0, 0, 0, 18, 0, 0, 0, 31, 0, 0, 0, 25, 0, 0, 0, 13, 0, 0, 0, 6, 0, 0, 0, 21, +0, 0, 0, 22, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 26, 0, 0, 0, 27, +0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, -32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, 0, 0, 0, 4, -0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, - +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 8, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, +115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 144, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, +0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 128, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 171, 171, 79, 83, 71, 78, 128, +0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 11, 0, 0, 104, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, +171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index 62b2307eb6..d76733756f 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -28,245 +28,586 @@ internal partial class UIEffect 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -10, 120, 114, 143, 194, 186, 206, 247, 240, 97, 17, 133, 2, 25, 30, 123, 0, 156, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, -100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, 191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, -0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, -0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, -0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, -66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, -115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, -0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, -0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, -108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, -0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, -101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, -0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, -114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, -0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, -55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, -0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, -0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, -0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, -0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, -0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, -77, 97, 105, 110, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, -0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, -111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, -115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, -0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, -0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, -0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, -0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, -0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, -101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, -95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, -95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, -102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, -0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, -0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, -84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, -0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, -0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, -101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, -95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, -67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, -0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, -0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, -87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, -0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, -0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, -0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, -0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, -0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, -0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, -0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, -60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, 154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, -0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, -0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, -0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, -0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, -0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, -0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, -0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, -0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, -0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, -0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, -0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, 229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, -0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, -0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, -0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, -0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, 166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, -0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, -0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, -0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, -0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, 111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, -0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, -0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, -0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, -0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, 158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, -0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, 168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, -0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, -0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, -0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, -0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, 178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, -0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, -0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, 191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, -0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, -0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, -0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, -0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, 235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, -0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, 247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 10, 120, 114, 143, 194, 186, 206, 247, 240, 97, 17, 133, 2, 25, 30, 123, 0, 156, 29, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 250, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, -192, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 200, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 189, 1, 0, 0, -191, 1, 0, 0, 193, 1, 0, 0, 187, 1, 0, 0, 199, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 230, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 216, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, -222, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 221, 1, 0, 0, 223, 1, 0, 0, 229, 1, 0, 0, 16, 0, 3, 0, 200, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, -0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, -36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, -110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 82, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, -100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 1, 0, 0, 7, 0, 21, 0, 183, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 184, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, -7, 0, 19, 0, 185, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 186, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, -102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, -116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 112, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, -46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 115, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 122, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, -128, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 130, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 133, 0, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 138, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 154, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, -95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 155, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 157, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 175, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 187, 0, 0, 0, -102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 245, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 249, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, -5, 0, 7, 0, 254, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 3, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 20, 1, 0, 0, -102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 22, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 28, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 33, 1, 0, 0, 102, 108, 111, 97, -116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 84, 1, 0, 0, -84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, -101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 90, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, -105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 140, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 164, 1, 0, 0, -115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 168, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 173, 1, 0, 0, -116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 188, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, -52, 0, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 190, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, -189, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 192, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 191, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, -108, 111, 114, 0, 5, 0, 6, 0, 194, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 193, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 195, 1, 0, 0, 80, 83, 95, 73, -78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 195, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 195, 1, 0, 0, 2, 0, 0, 0, -83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 196, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 196, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 197, 1, 0, 0, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 197, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 197, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, -2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 197, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 198, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, -5, 0, 5, 0, 199, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 200, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -5, 0, 4, 0, 203, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 206, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 209, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 213, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, -5, 0, 8, 0, 215, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 216, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 218, 1, 0, 0, -112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 219, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 221, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 222, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, -105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 224, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 223, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, -225, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 225, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, -6, 0, 5, 0, 225, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 225, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 226, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, -226, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, -114, 0, 0, 0, 6, 0, 5, 0, 226, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 227, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 227, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 227, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 227, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, -3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 227, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 228, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, -5, 0, 5, 0, 229, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 230, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -5, 0, 4, 0, 239, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 187, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 189, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 189, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, -79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 191, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 191, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 193, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, -193, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 216, 1, 0, 0, -3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 217, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 219, 1, 0, 0, -30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 219, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 220, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 220, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, -82, 0, 0, 0, 71, 0, 4, 0, 221, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 221, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 222, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 222, 1, 0, 0, -3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 223, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 223, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, -71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, -22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, -8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, -31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, -43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, -70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 115, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, -122, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 121, 0, 0, 0, 5, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 128, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 130, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, -5, 0, 0, 0, 133, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 136, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 33, 0, 4, 0, 137, 0, 0, 0, 136, 0, 0, 0, 138, 0, 0, 0, 32, 0, 4, 0, -154, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 153, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 21, 0, 4, 0, 174, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 175, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, -179, 0, 0, 0, 4, 0, 0, 0, 154, 0, 0, 0, 122, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 187, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 160, 34, 47, 63, -43, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 154, 153, 25, 64, -43, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 230, 174, 37, 61, -41, 0, 3, 0, 8, 0, 0, 0, 84, 1, 0, 0, 33, 0, 3, 0, 136, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 161, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 168, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 188, 1, 0, 0, 3, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 190, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 192, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 194, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 195, 1, 0, 0, 43, 0, 0, 0, -4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 196, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 197, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 198, 1, 0, 0, 6, 0, 0, 0, 197, 1, 0, 0, 43, 0, 4, 0, -174, 0, 0, 0, 203, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 206, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 209, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -218, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 224, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 225, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 226, 1, 0, 0, 4, 0, 0, 0, -43, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 227, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 228, 1, 0, 0, 6, 0, 0, 0, 227, 1, 0, 0, 43, 0, 4, 0, 174, 0, 0, 0, -239, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 187, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, -189, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 191, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 193, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 198, 1, 0, 0, 199, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, -215, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 190, 1, 0, 0, 216, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 218, 1, 0, 0, 217, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, 219, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 192, 1, 0, 0, -220, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 188, 1, 0, 0, 221, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 194, 1, 0, 0, 222, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 224, 1, 0, 0, 223, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 228, 1, 0, 0, -229, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 153, 0, 0, 0, 55, 0, 3, 0, 154, 0, 0, 0, 155, 0, 0, 0, 248, 0, 2, 0, 156, 0, 0, 0, 59, 0, 4, 0, 138, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 158, 0, 0, 0, 155, 0, 0, 0, 79, 0, 8, 0, 136, 0, 0, 0, 159, 0, 0, 0, 158, 0, 0, 0, 158, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 159, 0, 0, 0, 61, 0, 4, 0, -136, 0, 0, 0, 160, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 161, 0, 0, 0, 157, 0, 0, 0, 61, 0, 4, 0, 136, 0, 0, 0, 162, 0, 0, 0, 157, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 164, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, -128, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 163, 0, 0, 0, 162, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 166, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 130, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 165, 0, 0, 0, 163, 0, 0, 0, -166, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 167, 0, 0, 0, 161, 0, 0, 0, 165, 0, 0, 0, 80, 0, 6, 0, 136, 0, 0, 0, 169, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 133, 0, 0, 0, 129, 0, 5, 0, 136, 0, 0, 0, 168, 0, 0, 0, 167, 0, 0, 0, -169, 0, 0, 0, 133, 0, 5, 0, 136, 0, 0, 0, 170, 0, 0, 0, 160, 0, 0, 0, 168, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 1, 0, 0, 0, -81, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 170, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 122, 0, 0, 0, 176, 0, 0, 0, 155, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, -178, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 173, 0, 0, 0, 177, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 102, 1, 0, 0, 59, 0, 4, 0, -154, 0, 0, 0, 122, 1, 0, 0, 7, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 109, 1, 0, 0, 229, 1, 0, 0, 213, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 111, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 112, 1, 0, 0, -111, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 112, 1, 0, 0, 247, 0, 3, 0, 114, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 84, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 116, 1, 0, 0, -229, 1, 0, 0, 209, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 124, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 125, 1, 0, 0, 124, 1, 0, 0, 62, 0, 3, 0, 122, 1, 0, 0, 125, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, -127, 1, 0, 0, 112, 0, 0, 0, 122, 1, 0, 0, 62, 0, 3, 0, 116, 1, 0, 0, 127, 1, 0, 0, 249, 0, 2, 0, 114, 1, 0, 0, 248, 0, 2, 0, 114, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 248, 0, 2, 0, 129, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 138, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 134, 1, 0, 0, 138, 1, 0, 0, 253, 0, 1, 0, -56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 136, 1, 0, 0, 248, 0, 2, 0, 139, 1, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 140, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 154, 0, 0, 0, 164, 1, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 154, 0, 0, 0, 170, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 151, 1, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 158, 1, 0, 0, 199, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 159, 1, 0, 0, -158, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 160, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 161, 1, 0, 0, 162, 1, 0, 0, 160, 1, 0, 0, 151, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 163, 1, 0, 0, 162, 1, 0, 0, 159, 1, 0, 0, 0, 0, 0, 0, -62, 0, 3, 0, 140, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 166, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 166, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 169, 1, 0, 0, 167, 1, 0, 0, -168, 1, 0, 0, 247, 0, 3, 0, 171, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 169, 1, 0, 0, 172, 1, 0, 0, 173, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 140, 1, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, -174, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 175, 1, 0, 0, 140, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 176, 1, 0, 0, 175, 1, 0, 0, 175, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 170, 1, 0, 0, 176, 1, 0, 0, 249, 0, 2, 0, 171, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 170, 1, 0, 0, 62, 0, 3, 0, 164, 1, 0, 0, 177, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 178, 1, 0, 0, 164, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 180, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 181, 1, 0, 0, 180, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 182, 1, 0, 0, -178, 1, 0, 0, 181, 1, 0, 0, 254, 0, 2, 0, 182, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 201, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 202, 1, 0, 0, 199, 1, 0, 0, -203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 204, 1, 0, 0, 189, 1, 0, 0, 62, 0, 3, 0, 202, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 205, 1, 0, 0, 199, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 207, 1, 0, 0, -191, 1, 0, 0, 62, 0, 3, 0, 205, 1, 0, 0, 207, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 208, 1, 0, 0, 199, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 1, 0, 0, 193, 1, 0, 0, 62, 0, 3, 0, 208, 1, 0, 0, 210, 1, 0, 0, -57, 0, 4, 0, 30, 0, 0, 0, 211, 1, 0, 0, 89, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 212, 1, 0, 0, 199, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 1, 0, 0, 212, 1, 0, 0, 62, 0, 3, 0, 187, 1, 0, 0, 214, 1, 0, 0, -253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 231, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 232, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, -233, 1, 0, 0, 216, 1, 0, 0, 62, 0, 3, 0, 232, 1, 0, 0, 233, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 234, 1, 0, 0, 229, 1, 0, 0, 206, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 1, 0, 0, 219, 1, 0, 0, 62, 0, 3, 0, 234, 1, 0, 0, -235, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 236, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 237, 1, 0, 0, 220, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 237, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 238, 1, 0, 0, -229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 1, 0, 0, 222, 1, 0, 0, 62, 0, 3, 0, 238, 1, 0, 0, 240, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 241, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 242, 1, 0, 0, -229, 1, 0, 0, 213, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 243, 1, 0, 0, 242, 1, 0, 0, 62, 0, 3, 0, 215, 1, 0, 0, 243, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 244, 1, 0, 0, 229, 1, 0, 0, 203, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, -245, 1, 0, 0, 244, 1, 0, 0, 62, 0, 3, 0, 217, 1, 0, 0, 245, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 246, 1, 0, 0, 229, 1, 0, 0, 209, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 247, 1, 0, 0, 246, 1, 0, 0, 62, 0, 3, 0, 221, 1, 0, 0, -247, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 248, 1, 0, 0, 229, 1, 0, 0, 239, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 248, 1, 0, 0, 62, 0, 3, 0, 223, 1, 0, 0, 249, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, -0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +88, 177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, +100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, +0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, +0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, +67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, +117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, +105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, +111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, +109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, +71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, +73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, +103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, +101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, +76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, +112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, +114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, +76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, +73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, +0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, +115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, +104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, +80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, +0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, +105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, +110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, +41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, +32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, +104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, +116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, +50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, +101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, +105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, +59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, +32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, +80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, +32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, +111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, +116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, +65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, +10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, +32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, +116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, +114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, +109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, +114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, +114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, +116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, +115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, +116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, +108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, +104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, +108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, +32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, +48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, +97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, +71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, +51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, +111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, +97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, +110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, +97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, +111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, +32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, +48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, +67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, +102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, +32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, +66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, +53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, +32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, +103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, +32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, +97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, +112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, +102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, +1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, +110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, +32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, +111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, +104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, +72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, +97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, +115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, +105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, +109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, +32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, +111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, +0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, +0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, +95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, +111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, +111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, +0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, +95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, +0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, +49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, +0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, +0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, +0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, +102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, +0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, +0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, +0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, +0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, +0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, +0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, +0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, +0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, +0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, +86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, +0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, +122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, +85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, +0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, +0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, +0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, +83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, +0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, +0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, +0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, +87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, +0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, +0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, +0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, +0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, +0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, +0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, +0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, +0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, +0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, +0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, +0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, +0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, +0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, +0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, +0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, +0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, +0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, +0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, +0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, +0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, +0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, +0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, +0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, +0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, +0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, +0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, +0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, +0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, +0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, +0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, +0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, +0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, +0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, +0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, +0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, +0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, +0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, +0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, +0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, +0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, +0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 88, +177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, +46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, 0, +194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, +216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, +111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, +110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, +99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, +114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, +13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, +82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, +76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, +97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, +108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, +79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, +83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, +116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, +47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, +116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, +101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, +101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, +110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, +115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, +26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, +111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, +67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, +101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, +111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, +104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, +97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, +105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, +35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, +116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, +32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, +68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, +101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, +47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, +101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, +101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, +116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, +32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, +84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, +68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, +110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, +105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, +76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, +65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, +116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, +114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, +87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, +82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, +61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, +111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, +105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, +105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, +101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, +105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, +105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, +116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, +46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, +49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, +116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, +49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, +99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, +66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, +48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, +97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, +46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, +101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, +46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, +114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, +115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, +54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, +111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, +108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, +48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, +97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, +35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, +115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, +98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, +108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, +114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, +40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, +41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, 1, +0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, +32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, +117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, +111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, +95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, +109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, +46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, +116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, +115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, +48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, +108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, +114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, +97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, +132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, +70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, +5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, +50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, +5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, +32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, +5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, +5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, +5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, +5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, +117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, +0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, +105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, +190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, +190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, +192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, +6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, +105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, +83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, +105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, +108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, +116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, +84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, +2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, +6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, +3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, +2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, +71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, +3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, +0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, +73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, +33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, +7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, +30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, +37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, +205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, +196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, +137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, +3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, +248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, +21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, +68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, +190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, +192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, +0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, +221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, +43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, +59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, +59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, +248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, +158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, +156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, +135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, +135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, +135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, +172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, +171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, +8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, +87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, +224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, +18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, +57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, +25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, +194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, +4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, +169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, +42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, +158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, +4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, +30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, +197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, +203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, +62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, +62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index e3408d801c..fa4ffdb3b5 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -30,12 +30,12 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, -103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 50, 8, 209, 221, 98, 193, 223, 53, 243, 31, 139, 209, 84, 54, 55, -86, 0, 176, 87, 0, 0, 68, 88, 66, 67, 98, 159, 90, 215, 158, 11, 173, 17, 253, 227, 224, 246, 170, 132, 82, 120, 1, 0, 0, 0, 176, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, 0, 248, 7, 0, 0, 0, 86, 0, 0, 124, 86, 0, 0, 48, 87, 0, 0, 124, 87, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 54, 67, 254, 59, 57, 53, 190, 195, 40, 178, 220, 97, 132, 102, 97, +29, 0, 176, 87, 0, 0, 68, 88, 66, 67, 67, 121, 8, 66, 69, 60, 175, 110, 94, 8, 210, 5, 46, 132, 244, 193, 1, 0, 0, 0, 176, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, 0, 248, 7, 0, 0, 0, 86, 0, 0, 124, 86, 0, 0, 48, 87, 0, 0, 124, 87, 0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, 85, 71, 40, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, -110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 70, 49, 48, -48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 93, 0, 0, 0, 252, 3, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 63, 0, +110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 52, 54, 53, +56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 93, 0, 0, 0, 252, 3, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 63, 0, 0, 0, 28, 4, 0, 0, 63, 0, 0, 0, 48, 4, 0, 0, 63, 0, 0, 0, 64, 4, 0, 0, 75, 0, 0, 0, 80, 4, 0, 0, 76, 0, 0, 0, 96, 4, 0, 0, 76, 0, 0, 0, 108, 4, 0, 0, 76, 0, 0, 0, 120, 4, 0, 0, 76, 0, 0, 0, 132, 4, 0, 0, 77, 0, 0, 0, 148, 4, 0, 0, 77, 0, 0, 0, 168, 4, 0, 0, 77, 0, 0, 0, 184, 4, 0, 0, 77, 0, 0, 0, 196, 4, 0, 0, 77, 0, 0, 0, 212, 4, 0, 0, 77, 0, 0, 0, 232, 4, 0, 0, 77, 0, 0, 0, 248, 4, 0, 0, 78, 0, 0, 0, 8, 5, 0, 0, 87, 0, 0, 0, 24, 5, 0, 0, 87, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, @@ -103,7 +103,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 88, 150, 35, 61, 119, 137, 217, 67, 166, 47, 24, 91, 29, 8, 149, 92, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 101, 172, 148, 56, 6, 121, 111, 74, 182, 211, 205, 109, 42, 91, 96, 58, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -120,7 +120,7 @@ internal partial class SignedDistanceFieldFontShader 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 20, 41, -3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 124, 125, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 138, 227, 2, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 223, 101, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 231, 242, 2, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -165,11 +165,11 @@ internal partial class SignedDistanceFieldFontShader 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, -44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 55, -32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 95, 51, 48, 51, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 53, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 55, 44, 32, 95, 50, 57, 57, 44, 32, 95, 51, 48, 51, -44, 32, 95, 51, 48, 53, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, +44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 54, +32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, 95, 50, 57, 56, 44, 32, 95, 51, 48, 50, +44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, @@ -184,15 +184,15 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, -83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 70, 49, 48, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, +83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 52, 54, 53, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, -50, 51, 102, 48, 52, 52, 102, 102, 49, 48, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +50, 57, 51, 97, 97, 50, 54, 52, 54, 53, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 79, 33, 58, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 43, 119, 102, 243, 235, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 111, 214, 223, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 206, 254, 205, 56, 235, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -218,7 +218,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, 0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, -0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 239, 201, 134, 38, 233, 252, 116, 41, 62, 121, 173, 120, 77, 98, 3, 4, +0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 206, 133, 155, 45, 155, 186, 30, 169, 229, 194, 182, 63, 124, 126, 159, 10, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 121, 0, 0, 128, 80, 0, 0, 0, 121, 0, 0, 0, 116, 0, 0, 0, 121, 0, 0, 128, 116, 0, 0, 0, 121, 0, 0, 0, 144, 0, 0, 0, 121, 0, 0, 128, 144, 0, 0, 0, 121, 0, 0, 0, 172, 0, 0, 0, 121, 0, 0, 128, 172, 0, 0, 0, 121, 0, 0, 0, 200, 0, 0, 0, 121, 0, 0, 128, 200, 0, 0, 0, 121, 0, 0, 0, 228, 0, 0, 0, 121, 0, 0, 128, 228, 0, 0, 0, 121, 0, 0, 0, 248, 0, 0, 0, 121, 0, 0, 128, 248, 0, 0, 0, 121, 0, 0, 0, 12, 1, 0, 0, 121, 0, 0, 128, 12, 1, 0, 0, 121, 0, 0, 0, 48, 1, 0, 0, 121, 0, 0, 128, 48, 1, 0, 0, 121, 0, 0, 0, 84, 1, 0, 0, 121, 0, 0, 128, 84, 1, 0, 0, 121, 0, @@ -231,7 +231,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -246,7 +246,7 @@ internal partial class SignedDistanceFieldFontShader 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, -0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, +0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -281,10 +281,10 @@ internal partial class SignedDistanceFieldFontShader 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 95, 50, 57, 55, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 57, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 51, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 53, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 55, 44, 32, 95, 50, 57, 57, -44, 32, 95, 51, 48, 51, 44, 32, 95, 51, 48, 53, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, +52, 32, 95, 50, 57, 54, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, 95, 50, 57, 56, +44, 32, 95, 51, 48, 50, 44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, @@ -293,8 +293,8 @@ internal partial class SignedDistanceFieldFontShader 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, -93, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 186, 0, 0, 0, +93, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, @@ -347,14 +347,14 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, 0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, -101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, -70, 70, 49, 48, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, +54, 52, 54, 53, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 88, 150, 35, 61, 119, 137, 217, 67, 166, 47, 24, 91, 29, 8, 149, 92, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, +0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 101, 172, 148, 56, 6, 121, 111, 74, 182, 211, 205, 109, 42, 91, 96, 58, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, -115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 102, 49, 48, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, -0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 52, 54, 53, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, +0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -381,12 +381,12 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, -171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 186, 156, 53, -68, 143, 7, 48, 178, 195, 41, 116, 176, 193, 11, 48, 143, 0, 100, 67, 0, 0, 68, 88, 66, 67, 233, 43, 140, 116, 146, 209, 173, 70, 16, 70, 204, 229, 50, 153, 24, 50, 1, 0, 0, 0, 100, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 65, +171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 213, 173, 154, +222, 25, 165, 76, 67, 10, 134, 213, 141, 158, 184, 169, 173, 0, 100, 67, 0, 0, 68, 88, 66, 67, 47, 117, 61, 184, 133, 136, 144, 187, 52, 61, 201, 9, 132, 86, 139, 127, 1, 0, 0, 0, 100, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 65, 0, 0, 56, 66, 0, 0, 132, 66, 0, 0, 244, 66, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, -48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 80, 0, 0, 0, 112, 2, 0, 0, 82, 0, 0, 0, 132, 2, 0, 0, 84, 0, 0, 0, 144, 2, +48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 80, 0, 0, 0, 112, 2, 0, 0, 82, 0, 0, 0, 132, 2, 0, 0, 84, 0, 0, 0, 144, 2, 0, 0, 80, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, @@ -437,7 +437,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 240, 56, 223, 166, 13, 104, 110, 77, 178, 48, 203, 74, 118, 108, 166, 216, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 213, 209, 7, 57, 253, 94, 237, 76, 147, 126, 206, 225, 16, 9, 113, 247, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -494,14 +494,14 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 193, 7, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, -114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, +114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, -64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 55, 49, 99, 49, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, +64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 51, 55, 99, 54, 99, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 160, 164, 61, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 212, 75, 226, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 37, 43, 96, 147, 6, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -556,7 +556,7 @@ internal partial class SignedDistanceFieldFontShader 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -602,12 +602,12 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, -48, 48, 50, 51, 70, 48, 52, 55, 49, 67, 49, 65, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, +48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 240, 56, 223, 166, 13, 104, 110, 77, 178, 48, 203, 74, 118, 108, 166, 216, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 213, 209, 7, 57, 253, 94, 237, 76, 147, 126, 206, 225, 16, 9, 113, 247, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, -114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 55, 49, 99, 49, 97, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, +114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 51, 55, 99, 54, 99, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index de311e9754..50c3453b06 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -28,266 +28,592 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, -0, 0, 1, 152, 19, 190, 249, 47, 157, 209, 201, 185, 214, 254, 218, 145, 246, 217, 253, 0, 80, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 112, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 123, 0, 0, 0, 71, 76, 83, 76, -46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 72, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 63, 1, 0, 0, 65, 1, 0, 0, 61, 1, 0, 0, -71, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 96, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 85, 1, 0, 0, 88, 1, 0, 0, 89, 1, 0, 0, 84, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, -95, 1, 0, 0, 16, 0, 3, 0, 72, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, -0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, -71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, -36, 0, 0, 0, 7, 0, 23, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 19, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, -226, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 7, 0, 21, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, -7, 0, 20, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 59, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 60, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, -97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, -5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, -109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 112, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 115, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, -114, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 118, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 133, 0, 0, 0, -115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 136, 0, 0, 0, -98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 142, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 144, 0, 0, 0, 115, 104, 97, 114, -112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 146, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, -147, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 150, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 155, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, -105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 165, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 169, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 172, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, -5, 0, 4, 0, 174, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 97, 114, 68, -105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 195, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, -110, 101, 0, 0, 5, 0, 6, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 184, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, -104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 233, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, -5, 0, 7, 0, 11, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 36, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, -5, 0, 4, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 40, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 62, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, -52, 0, 0, 0, 5, 0, 7, 0, 61, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 64, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, -63, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, -108, 111, 114, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 67, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 69, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 0, 0, 6, 0, 6, 0, 69, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 69, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 69, 1, 0, 0, 2, 0, 0, 0, -67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 70, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 71, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, -72, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 75, 1, 0, 0, 105, 110, 116, 95, -49, 0, 0, 0, 5, 0, 4, 0, 78, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 86, 1, 0, 0, -111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, -90, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, -6, 0, 6, 0, 91, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, -6, 0, 7, 0, 92, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 2, 0, 0, 0, -67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 93, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 93, 1, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, -94, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 96, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 61, 1, 0, 0, -30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 63, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, -0, 22, 5, 0, 65, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, -84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 86, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, -1, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, -71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, -32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, -32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, -25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, -2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, -32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 32, 0, 4, 0, 115, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 114, 0, 0, 0, 5, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, -7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 131, 0, 0, 0, 4, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 115, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, -0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 142, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 155, 0, 0, 0, -1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 159, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 172, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 192, 0, 0, 0, -0, 0, 0, 64, 33, 0, 3, 0, 7, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 33, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, -62, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 66, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 67, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, -68, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 69, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 70, 1, 0, 0, 6, 0, 0, 0, 69, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, -139, 0, 0, 0, 78, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 91, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, -30, 0, 5, 0, 92, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 93, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, -139, 0, 0, 0, 103, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 61, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -64, 1, 0, 0, 63, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 65, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 71, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -64, 1, 0, 0, 85, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -62, 1, 0, 0, 90, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, -115, 0, 0, 0, 117, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 118, 0, 0, 0, 248, 0, 2, 0, 119, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 121, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, -5, 0, 0, 0, 122, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 125, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, -126, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 124, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 118, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 126, 0, 0, 0, 127, 0, 0, 0, -12, 0, 7, 0, 5, 0, 0, 0, 129, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 122, 0, 0, 0, 128, 0, 0, 0, 254, 0, 2, 0, 129, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 55, 0, 3, 0, -132, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 135, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 136, 0, 0, 0, 248, 0, 2, 0, 137, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 144, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 154, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 158, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 165, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 174, 0, 0, 0, -7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 195, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 199, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 208, 0, 0, 0, -7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 138, 0, 0, 0, 136, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 143, 0, 0, 0, 123, 0, 0, 0, 43, 0, 0, 0, 138, 0, 0, 0, 141, 0, 0, 0, -142, 0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 143, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 148, 0, 0, 0, 136, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 149, 0, 0, 0, 147, 0, 0, 0, 148, 0, 0, 0, -62, 0, 3, 0, 146, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 152, 0, 0, 0, 133, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, -115, 0, 0, 0, 156, 0, 0, 0, 133, 0, 0, 0, 155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 157, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 160, 0, 0, 0, 133, 0, 0, 0, 159, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 161, 0, 0, 0, 160, 0, 0, 0, 62, 0, 3, 0, 158, 0, 0, 0, 161, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 164, 0, 0, 0, 111, 0, 0, 0, 151, 0, 0, 0, 154, 0, 0, 0, 158, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, -164, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 0, 0, 0, 146, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 168, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 62, 0, 3, 0, 165, 0, 0, 0, -168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 165, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 169, 0, 0, 0, -173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 169, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 178, 0, 0, 0, -165, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 179, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 179, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 174, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 181, 0, 0, 0, 174, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 182, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 136, 0, 0, 0, -186, 0, 5, 0, 8, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 247, 0, 3, 0, 184, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 187, 0, 0, 0, 183, 0, 0, 0, 184, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -190, 0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 136, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 193, 0, 0, 0, -62, 0, 3, 0, 189, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, -62, 0, 3, 0, 195, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 195, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 195, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 203, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 205, 0, 0, 0, 202, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, -189, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 207, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 199, 0, 0, 0, 207, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 140, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, -155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 199, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 212, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 212, 0, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 216, 0, 0, 0, 215, 0, 0, 0, -215, 0, 0, 0, 215, 0, 0, 0, 215, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 217, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 217, 0, 0, 0, 249, 0, 2, 0, 184, 0, 0, 0, -248, 0, 2, 0, 184, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 219, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, -174, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 222, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 218, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, -62, 0, 3, 0, 133, 0, 0, 0, 222, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 223, 0, 0, 0, 133, 0, 0, 0, 254, 0, 2, 0, 223, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -244, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 253, 0, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, -251, 0, 0, 0, 254, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 5, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 5, 1, 0, 0, 9, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 248, 0, 2, 0, 10, 1, 0, 0, -59, 0, 4, 0, 132, 0, 0, 0, 11, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 40, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 132, 0, 0, 0, 46, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 52, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 23, 1, 0, 0, 88, 0, 0, 0, -65, 0, 5, 0, 75, 0, 0, 0, 30, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 31, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 32, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 33, 1, 0, 0, 34, 1, 0, 0, -32, 1, 0, 0, 23, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 11, 1, 0, 0, 35, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, -37, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 40, 1, 0, 0, 37, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 48, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 48, 1, 0, 0, 62, 0, 3, 0, 46, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 51, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, -50, 1, 0, 0, 51, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 53, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 52, 1, 0, 0, 53, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 56, 1, 0, 0, 112, 0, 0, 0, 44, 1, 0, 0, 46, 1, 0, 0, 50, 1, 0, 0, -52, 1, 0, 0, 254, 0, 2, 0, 56, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 73, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 74, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, -61, 0, 4, 0, 43, 0, 0, 0, 76, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 77, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 79, 1, 0, 0, 65, 1, 0, 0, -62, 0, 3, 0, 77, 1, 0, 0, 79, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 80, 1, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 81, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 83, 1, 0, 0, 81, 1, 0, 0, -62, 0, 3, 0, 61, 1, 0, 0, 83, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, -75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 99, 1, 0, 0, 85, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 99, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, -88, 1, 0, 0, 62, 0, 3, 0, 100, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 95, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, -57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 107, 1, 0, 0, -65, 0, 5, 0, 75, 0, 0, 0, 108, 1, 0, 0, 95, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 109, 1, 0, 0, 108, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 95, 1, 0, 0, -103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 111, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, -0, 1, 152, 19, 190, 249, 47, 157, 209, 201, 185, 214, 254, 218, 145, 246, 217, 253, 0, 80, 32, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 112, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 123, 0, 0, 0, 71, 76, 83, 76, 46, -115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 72, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 63, 1, 0, 0, 65, 1, 0, 0, 61, 1, 0, 0, 71, -1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 96, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 85, 1, 0, 0, 88, 1, 0, 0, 89, 1, 0, 0, 84, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 95, -1, 0, 0, 16, 0, 3, 0, 72, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, -105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, -118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, -0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, -114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, -114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, -0, 0, 0, 7, 0, 23, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, -83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 19, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, -114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 24, 0, 226, -0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 7, 0, 21, 0, 57, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, -47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, -0, 20, 0, 58, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 59, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, -105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 60, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, -116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, -116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, -110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, -114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, -116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, -0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, -112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 112, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, -116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 115, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 114, -0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 118, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 133, 0, 0, 0, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 136, 0, 0, 0, 98, -111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 142, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 144, 0, 0, 0, 115, 104, 97, 114, 112, -110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 145, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 146, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 147, -0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 150, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 155, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 159, 0, 0, 0, 105, -110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 165, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 169, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 172, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, -0, 4, 0, 174, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 189, 0, 0, 0, 102, 97, 114, 68, 105, -115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 192, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 195, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 199, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, -101, 0, 0, 5, 0, 6, 0, 208, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 184, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, -116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 232, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, -97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 233, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, -0, 7, 0, 11, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 36, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, -0, 4, 0, 38, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 40, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 62, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, -0, 0, 0, 5, 0, 7, 0, 61, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 64, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 63, -1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 66, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, -111, 114, 0, 5, 0, 5, 0, 67, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 67, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 67, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, -0, 0, 0, 5, 0, 5, 0, 68, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 68, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 69, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, -83, 0, 0, 6, 0, 6, 0, 69, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 69, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 69, 1, 0, 0, 2, 0, 0, 0, 67, -111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 70, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 71, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 72, -1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 75, 1, 0, 0, 105, 110, 116, 95, 49, -0, 0, 0, 5, 0, 4, 0, 78, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 82, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 0, 0, 5, 0, 6, 0, 85, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 86, 1, 0, 0, 111, -117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 90, -1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 91, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 91, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, -0, 6, 0, 91, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 91, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 92, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, -0, 7, 0, 92, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 92, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 2, 0, 0, 0, 67, -111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 93, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 93, 1, 0, 0, 1, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 93, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 94, -1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 95, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 96, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, -116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 61, 1, 0, 0, 30, -0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 63, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 63, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 65, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, -22, 5, 0, 65, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 85, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 85, 1, 0, 0, 3, 22, 0, 0, 84, -69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 86, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 1, -0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 89, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 89, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, -0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, -0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, -0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, -0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, -0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, -0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 32, 0, 4, 0, 115, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 114, 0, 0, 0, 5, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 115, 0, 0, 0, 32, 0, 4, 0, 132, 0, 0, 0, 7, -0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 131, 0, 0, 0, 4, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 115, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, -0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 142, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 155, 0, 0, 0, 1, -0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 159, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 172, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 192, 0, 0, 0, 0, -0, 0, 64, 33, 0, 3, 0, 7, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 33, 1, 0, 0, 38, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 62, -1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 66, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 67, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 68, -1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 69, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 70, 1, 0, 0, 6, 0, 0, 0, 69, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 75, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, -0, 0, 0, 78, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 82, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 91, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, -0, 5, 0, 92, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 93, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 94, 1, 0, 0, 6, 0, 0, 0, 93, 1, 0, 0, 43, 0, 4, 0, 139, -0, 0, 0, 103, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 61, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 64, -1, 0, 0, 63, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 65, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 70, 1, 0, 0, 71, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 62, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 64, -1, 0, 0, 85, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 66, 1, 0, 0, 89, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 62, -1, 0, 0, 90, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 94, 1, 0, 0, 95, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 114, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 115, -0, 0, 0, 117, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 118, 0, 0, 0, 248, 0, 2, 0, 119, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 121, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, -0, 0, 0, 122, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 120, 0, 0, 0, 121, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 125, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 126, -0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 124, 0, 0, 0, 125, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 118, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 123, 0, 0, 0, 37, 0, 0, 0, 126, 0, 0, 0, 127, 0, 0, 0, 12, -0, 7, 0, 5, 0, 0, 0, 129, 0, 0, 0, 123, 0, 0, 0, 40, 0, 0, 0, 122, 0, 0, 0, 128, 0, 0, 0, 254, 0, 2, 0, 129, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, 0, 55, 0, 3, 0, 132, -0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 132, 0, 0, 0, 135, 0, 0, 0, 55, 0, 3, 0, 115, 0, 0, 0, 136, 0, 0, 0, 248, 0, 2, 0, 137, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 144, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 146, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 151, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 154, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 158, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 165, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 169, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 174, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 189, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 195, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 199, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 208, 0, 0, 0, 7, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 138, 0, 0, 0, 136, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 143, 0, 0, 0, 123, 0, 0, 0, 43, 0, 0, 0, 138, 0, 0, 0, 141, 0, 0, 0, 142, -0, 0, 0, 62, 0, 3, 0, 136, 0, 0, 0, 143, 0, 0, 0, 62, 0, 3, 0, 144, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 148, 0, 0, 0, 136, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 149, 0, 0, 0, 147, 0, 0, 0, 148, 0, 0, 0, 62, -0, 3, 0, 146, 0, 0, 0, 149, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 152, 0, 0, 0, 133, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 153, 0, 0, 0, 152, 0, 0, 0, 62, 0, 3, 0, 151, 0, 0, 0, 153, 0, 0, 0, 65, 0, 5, 0, 115, -0, 0, 0, 156, 0, 0, 0, 133, 0, 0, 0, 155, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 157, 0, 0, 0, 156, 0, 0, 0, 62, 0, 3, 0, 154, 0, 0, 0, 157, 0, 0, 0, 65, 0, 5, 0, 115, 0, 0, 0, 160, 0, 0, 0, 133, 0, 0, 0, 159, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 161, 0, 0, 0, 160, 0, 0, 0, 62, 0, 3, 0, 158, 0, 0, 0, 161, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 164, 0, 0, 0, 111, 0, 0, 0, 151, 0, 0, 0, 154, 0, 0, 0, 158, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 164, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 167, 0, 0, 0, 146, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 168, 0, 0, 0, 166, 0, 0, 0, 167, 0, 0, 0, 62, 0, 3, 0, 165, 0, 0, 0, 168, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 165, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 170, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 173, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 62, 0, 3, 0, 169, 0, 0, 0, 173, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 169, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 169, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 178, 0, 0, 0, 165, -0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 179, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 178, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 179, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 174, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 181, 0, 0, 0, 174, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 182, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 62, 0, 3, 0, 174, 0, 0, 0, 182, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 136, 0, 0, 0, 186, -0, 5, 0, 8, 0, 0, 0, 187, 0, 0, 0, 185, 0, 0, 0, 186, 0, 0, 0, 247, 0, 3, 0, 184, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 187, 0, 0, 0, 183, 0, 0, 0, 184, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, -0, 0, 0, 146, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 136, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 191, 0, 0, 0, 192, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 193, 0, 0, 0, 62, -0, 3, 0, 189, 0, 0, 0, 194, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 150, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 189, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 198, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 62, -0, 3, 0, 195, 0, 0, 0, 198, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 144, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 195, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 195, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 204, 0, 0, 0, 203, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 205, 0, 0, 0, 202, 0, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 206, 0, 0, 0, 189, -0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 207, 0, 0, 0, 205, 0, 0, 0, 206, 0, 0, 0, 62, 0, 3, 0, 199, 0, 0, 0, 207, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 140, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 155, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 199, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 212, 0, 0, 0, 123, 0, 0, 0, 49, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 211, 0, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, -0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 135, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 214, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 216, 0, 0, 0, 215, 0, 0, 0, 215, -0, 0, 0, 215, 0, 0, 0, 215, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 217, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 213, 0, 0, 0, 214, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 217, 0, 0, 0, 249, 0, 2, 0, 184, 0, 0, 0, 248, -0, 2, 0, 184, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 218, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 219, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 220, 0, 0, 0, 174, -0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 221, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 220, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 222, 0, 0, 0, 123, 0, 0, 0, 46, 0, 0, 0, 218, 0, 0, 0, 219, 0, 0, 0, 221, 0, 0, 0, 62, -0, 3, 0, 133, 0, 0, 0, 222, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 223, 0, 0, 0, 133, 0, 0, 0, 254, 0, 2, 0, 223, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 244, -0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 253, 0, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 254, 0, 0, 0, 253, 0, 0, 0, 62, 0, 3, 0, 251, -0, 0, 0, 254, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 232, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 0, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 5, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 57, -0, 4, 0, 4, 0, 0, 0, 9, 1, 0, 0, 233, 0, 0, 0, 62, 0, 3, 0, 5, 1, 0, 0, 9, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 233, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 248, 0, 2, 0, 10, 1, 0, 0, 59, -0, 4, 0, 132, 0, 0, 0, 11, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 36, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 40, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 132, 0, 0, 0, 46, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 132, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 115, 0, 0, 0, 52, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 23, 1, 0, 0, 88, 0, 0, 0, 65, -0, 5, 0, 75, 0, 0, 0, 30, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 31, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 32, 1, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 33, 1, 0, 0, 34, 1, 0, 0, 32, -1, 0, 0, 23, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 31, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 11, 1, 0, 0, 35, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 37, 1, 0, 0, 37, 1, 0, 0, 37, -1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 36, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 40, 1, 0, 0, 37, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 45, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 45, 1, 0, 0, 65, 0, 5, 0, 3, -0, 0, 0, 48, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 48, 1, 0, 0, 62, 0, 3, 0, 46, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 51, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 50, -1, 0, 0, 51, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 53, 1, 0, 0, 40, 1, 0, 0, 62, 0, 3, 0, 52, 1, 0, 0, 53, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 56, 1, 0, 0, 112, 0, 0, 0, 44, 1, 0, 0, 46, 1, 0, 0, 50, 1, 0, 0, 52, -1, 0, 0, 254, 0, 2, 0, 56, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 72, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 73, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 74, 1, 0, 0, 71, 1, 0, 0, 75, 1, 0, 0, 61, -0, 4, 0, 43, 0, 0, 0, 76, 1, 0, 0, 63, 1, 0, 0, 62, 0, 3, 0, 74, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 77, 1, 0, 0, 71, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 79, 1, 0, 0, 65, 1, 0, 0, 62, -0, 3, 0, 77, 1, 0, 0, 79, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 80, 1, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 81, 1, 0, 0, 71, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 83, 1, 0, 0, 81, 1, 0, 0, 62, -0, 3, 0, 61, 1, 0, 0, 83, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 96, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 97, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 98, 1, 0, 0, 95, 1, 0, 0, 75, -1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 99, 1, 0, 0, 85, 1, 0, 0, 62, 0, 3, 0, 98, 1, 0, 0, 99, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 95, 1, 0, 0, 78, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 88, -1, 0, 0, 62, 0, 3, 0, 100, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 95, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, 57, -0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 107, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 107, 1, 0, 0, 65, -0, 5, 0, 75, 0, 0, 0, 108, 1, 0, 0, 95, 1, 0, 0, 75, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 109, 1, 0, 0, 108, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 109, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 95, 1, 0, 0, 103, -1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 90, 1, 0, 0, 111, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 0, 1, 101, 22, 45, 2, 121, 85, 249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, +46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, 55, 1, 0, 0, +65, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 84, 1, 0, 0, +89, 1, 0, 0, 16, 0, 3, 0, 66, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, +32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, +111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, +119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, +101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, +13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, +65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, +95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, +104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, +32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, +114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, +116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, +116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, +68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, +47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, +32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, +108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, +68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, +111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, +110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, +99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, +114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, +110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, +100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, +3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, +115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, +105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, +116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, +116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, +99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, +115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, +68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, +101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, +32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, +77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, +97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, +73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, +114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, +112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, +54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, +82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, +101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, +111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, +110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, +99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, +114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, +32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, +44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, +32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, +110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, +116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, +100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, +104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, +40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, +110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, +104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, +97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, +68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, +68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, +114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, +115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, +97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, +32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, +116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, +116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, +46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, +100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, +105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, +32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, +100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, +114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, +114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, +115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, +114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, 97, 108, 117, 101, +115, 32, 99, 97, 110, 32, 103, 111, 32, 105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, +40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, +101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, +32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, +7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, +40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, +117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, +98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, +116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, +105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, +109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, +5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, +102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, +5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, +121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, +77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, +83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, +110, 99, 101, 0, 5, 0, 5, 0, 34, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 38, 1, 0, 0, +98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, +60, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, +6, 0, 6, 0, 61, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 6, 0, 62, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 0, 6, 0, 6, 0, 63, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, +76, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 82, 1, 0, 0, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, +85, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, +6, 0, 5, 0, 85, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 0, 6, 0, 6, 0, 86, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, +77, 83, 0, 0, 6, 0, 7, 0, 87, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 87, 1, 0, 0, +2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, +77, 83, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 57, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, +78, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 0, 22, 6, 0, 80, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, +0, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 84, 1, 0, 0, +3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, +32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, +19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, +0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, +7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, +131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, +5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 31, 1, 0, 0, +37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 1, 0, 0, 0, +42, 0, 0, 0, 32, 0, 4, 0, 60, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 76, 1, 0, 0, +0, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, +87, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 59, 1, 0, 0, +1, 0, 0, 0, 59, 0, 4, 0, 64, 1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, +3, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 89, 1, 0, 0, +6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, +0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, +9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, +127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 132, 0, 0, 0, +55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, +114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, +114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, +114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, +137, 0, 0, 0, 140, 0, 0, 0, 141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, +9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 25, 0, 0, 0, +9, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 155, 0, 0, 0, +132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, +62, 0, 3, 0, 164, 0, 0, 0, 167, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, +5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, +5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, +175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +184, 0, 0, 0, 135, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, +191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, +149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 38, 0, 0, 0, +13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 129, 0, 5, 0, +5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, +5, 0, 0, 0, 209, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, +207, 0, 0, 0, 211, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, +215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, +185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, +219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 46, 0, 0, 0, +9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 224, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, 8, 0, 4, 0, +224, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 0, 0, 0, +251, 0, 0, 0, 62, 0, 3, 0, 249, 0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, +254, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, +7, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, +9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, +44, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, +21, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, +31, 1, 0, 0, 32, 1, 0, 0, 30, 1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 34, 0, 0, 0, +9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, +38, 1, 0, 0, 35, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 46, 1, 0, 0, +65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, 49, 1, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 51, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, 254, 0, 2, 0, +54, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, +70, 1, 0, 0, 57, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 71, 1, 0, 0, +73, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, +77, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, +42, 0, 0, 0, 93, 1, 0, 0, 79, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 62, 0, 3, 0, +94, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, +99, 1, 0, 0, 229, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, +102, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 101, 22, 45, 2, 121, 85, +249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, +0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, 55, 1, 0, 0, 65, 1, 0, 0, 40, 0, 0, 0, 87, +0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 84, 1, 0, 0, 89, 1, 0, 0, 16, 0, 3, 0, 66, +1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, +101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, +32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, +116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, +110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, +67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, +115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, +108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, +32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, +84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, +32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, +105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, +58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, +32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, +86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, +117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, +32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, +116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, +99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, +115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, +114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, +40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, +114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, +119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, +101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, +10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, +58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, +109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, +47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, +0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, +47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, +105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, +32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, +114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, +32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, +105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, +120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, +101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, +115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, +120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, +117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, +77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, +73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, +114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, +101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, +78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, +108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, +84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, +101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, +112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, +59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, +105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, +112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, +104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, +13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, +101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, +40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, +114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, +119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, +101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, +10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, +116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, +32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, +32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, +115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, +108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, +32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, +61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, +110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, +117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, +105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, +32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, +100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, +111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, +13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, +32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, +32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, +116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, +114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, +32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, +109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, +100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, +101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, +47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, +104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, +67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, +101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, +47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, +32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, +101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, +116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, +100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, +105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, +101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, +101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, 97, 108, 117, 101, 115, 32, 99, 97, 110, 32, 103, 111, 32, +105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, +32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, +116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, +105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, +114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, +105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, +114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, +110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, +52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, +115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, +108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, +0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, +0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, +0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, +0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, +0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, +116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, +114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, +0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, +105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, +0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, +0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, +116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 34, +1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 38, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, +99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, +0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 112, 116, 114, 95, 73, +110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 61, 1, 0, 0, 0, +0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 62, 1, 0, 0, 0, +0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 63, +1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, +82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, +46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 76, 1, 0, 0, 105, 110, 116, 95, 48, +0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, +1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 82, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, +105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 85, 1, 0, 0, 86, 83, 95, 73, 78, +80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 85, 1, 0, 0, 2, +0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 86, +1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 87, +1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 87, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, +105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 89, +1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 57, 1, 0, 0, 3, +22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 11, 0, 0, 0, 0, +0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 80, +1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 83, +1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 84, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, +0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, +0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, +0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, +0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, +0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, +0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, +0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, +0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, +0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, +153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 31, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, +0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 60, +1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, +1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 81, +1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 87, 1, 0, 0, 4, 0, 0, 0, 42, +0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, +0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 59, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, +1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 60, +1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 89, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, +0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, +0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, +0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, +0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, +0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, +0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, +0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, +0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, +0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, +0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 17, 0, 0, 0, 9, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, 141, +0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 114, +0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, +0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 27, 0, 0, 0, 9, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 167, +0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, +0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, +0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, +0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, 186, +0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 36, +0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, +0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, +0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, +0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 154, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, 8, +0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, +0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, +0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, +0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, +0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, +0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 10, +0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 17, 0, 0, 0, 9, +0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 249, +0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 224, +0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 7, 1, 0, 0, 253, 0, 1, 0, 56, +0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 59, +0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 21, 1, 0, 0, 87, 0, 0, 0, 65, +0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 31, 1, 0, 0, 32, 1, 0, 0, 30, +1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, +0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 38, 1, 0, 0, 35, 1, 0, 0, 8, +0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 46, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, +0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 51, +1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, 254, 0, 2, 0, 54, 1, 0, 0, 56, 0, 1, 0, 54, +0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 70, 1, 0, 0, 57, 1, 0, 0, 62, +0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 71, 1, 0, 0, 73, 1, 0, 0, 57, 0, 4, 0, 30, +0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, 77, 1, 0, 0, 253, 0, 1, 0, 56, +0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 93, 1, 0, 0, 79, +1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 62, 0, 3, 0, 94, 1, 0, 0, 95, 1, 0, 0, 65, +0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 99, 1, 0, 0, 229, 0, 0, 0, 65, +0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 102, 1, 0, 0, 89, 1, 0, 0, 69, +1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 105, 1, 0, 0, 104, +1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index d397a6a3c2..8712e837bf 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -38,11 +38,11 @@ internal partial class SpriteSignedDistanceFieldFontShader 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, -0, 0, 0, 5, 0, 0, 0, 1, 15, 102, 239, 211, 137, 37, 226, 132, 109, 210, 47, 74, 195, 187, 131, 207, 0, 192, 87, 0, 0, 68, 88, 66, 67, 55, 13, 237, 178, 214, 112, 53, 7, 236, 35, 51, 252, 228, 190, 248, 29, 1, 0, 0, 0, 192, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, +0, 0, 0, 5, 0, 0, 0, 1, 80, 109, 219, 15, 96, 184, 225, 224, 222, 136, 131, 142, 184, 139, 83, 200, 0, 192, 87, 0, 0, 68, 88, 66, 67, 18, 50, 113, 103, 3, 233, 179, 222, 15, 80, 16, 70, 41, 78, 99, 3, 1, 0, 0, 0, 192, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 86, 0, 0, 140, 86, 0, 0, 64, 87, 0, 0, 140, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, -104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, 255, 0, 4, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 68, 0, 0, 0, 28, 4, 0, 0, 68, 0, 0, 0, 44, 4, 0, 0, 68, 0, 0, 0, 64, 4, 0, 0, 68, 0, 0, 0, 80, 4, 0, 0, 80, 0, 0, 0, 96, 4, 0, 0, 81, 0, 0, 0, 112, 4, 0, 0, 81, 0, 0, 0, 124, 4, 0, 0, 81, 0, 0, 0, 136, 4, 0, 0, 81, 0, 0, 0, 148, 4, 0, 0, 82, 0, 0, 0, 164, 4, 0, 0, 82, 0, 0, 0, 184, 4, 0, 0, 82, 0, 0, 0, 200, 4, 0, 0, 82, 0, 0, 0, 212, 4, 0, 0, 82, 0, 0, 0, 228, 4, 0, 0, 82, 0, 0, 0, 248, 4, 0, 0, 82, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 40, 5, 0, 0, 92, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, @@ -110,8 +110,8 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 53, 29, 21, 23, 245, 244, 228, -69, 128, 13, 182, 224, 135, 53, 196, 207, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 158, 94, 53, 220, 30, 44, 109, +65, 154, 2, 226, 233, 146, 64, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -127,8 +127,8 @@ internal partial class SpriteSignedDistanceFieldFontShader 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, -0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 124, 125, 2, -0, 28, 221, 1, 0, 214, 154, 2, 0, 138, 227, 2, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 223, 101, 2, +0, 28, 221, 1, 0, 214, 154, 2, 0, 231, 242, 2, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -157,10 +157,10 @@ internal partial class SpriteSignedDistanceFieldFontShader 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, -53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 95, 50, 50, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 50, 50, 44, 32, 95, 50, 50, 53, 44, 32, 95, -50, 50, 57, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, +53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 57, 44, 32, 95, 50, 50, 50, 44, 32, 95, +50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, @@ -172,10 +172,10 @@ internal partial class SpriteSignedDistanceFieldFontShader 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, -114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 95, 51, 50, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 54, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 51, 48, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 51, 51, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, -99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 54, 44, 32, 95, 51, 50, 48, 44, 32, 95, 51, 50, 54, 44, 32, 95, 51, 51, 48, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 51, 51, 59, 10, +114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, @@ -192,15 +192,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 69, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, -105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 54, 48, 102, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, +105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 50, 100, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 79, 33, 58, 42, 88, 187, 220, 1, 1, 0, 0, +111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 111, 214, 223, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 141, 40, 225, 179, 138, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 157, 209, 167, 70, 138, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -227,7 +227,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 18, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, -0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 103, 72, 54, 195, 243, 107, 57, 242, 190, 90, 201, 47, 149, 66, 230, 217, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, +0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 26, 218, 106, 51, 227, 246, 25, 34, 184, 43, 161, 176, 211, 114, 225, 141, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 123, 0, 0, 128, 80, 0, 0, 0, 123, 0, 0, 0, 116, 0, 0, 0, 123, 0, 0, 128, 116, 0, 0, 0, 123, 0, 0, 0, 144, 0, 0, 0, 123, 0, 0, 128, 144, 0, 0, 0, 123, 0, 0, 0, 172, 0, 0, 0, 123, 0, 0, 128, 172, 0, 0, 0, 123, 0, 0, 0, 200, 0, 0, 0, 123, 0, 0, 128, 200, 0, 0, 0, 123, 0, 0, 0, 228, 0, 0, 0, 123, 0, 0, 128, 228, 0, 0, 0, 123, 0, 0, 0, 248, 0, 0, 0, 123, 0, 0, 128, 248, 0, 0, 0, 123, 0, 0, 0, 12, 1, 0, 0, 123, 0, 0, 128, 12, 1, 0, 0, 123, 0, 0, 0, 48, 1, 0, 0, 123, 0, 0, 128, 48, 1, 0, 0, 123, 0, 0, 0, 84, 1, 0, 0, 123, 0, 0, 128, 84, 1, 0, 0, 123, 0, 0, 0, 112, 1, 0, 0, 123, 0, 0, 128, 112, 1, 0, 0, 123, 0, 0, 0, 152, 1, 0, 0, 123, 0, 0, 128, 152, 1, 0, 0, 123, 0, 0, @@ -239,7 +239,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 67, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 21, 16, 0, -0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 240, 112, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -254,7 +254,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, -0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 240, 112, 0, 0, 242, 241, 41, 75, 0, 0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, +0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 208, 115, 0, 0, 242, 241, 41, 75, 0, 0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, 0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -272,10 +272,10 @@ internal partial class SpriteSignedDistanceFieldFontShader 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, -53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 50, 50, 44, 32, 95, -50, 50, 53, 44, 32, 95, 50, 50, 57, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, +53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 57, 44, 32, 95, +50, 50, 50, 44, 32, 95, 50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, @@ -287,11 +287,11 @@ internal partial class SpriteSignedDistanceFieldFontShader 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, -116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 48, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 54, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 51, 48, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 51, 51, 32, 61, 32, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 54, 44, 32, 95, 51, 50, 48, 44, 32, 95, 51, 50, 54, 44, 32, 95, 51, 51, 48, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -95, 51, 51, 51, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, +116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, +48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, +95, 51, 50, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, @@ -300,7 +300,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, -0, 0, 94, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, 0, 236, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, @@ -355,14 +355,14 @@ internal partial class SpriteSignedDistanceFieldFontShader 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, -97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 52, 70, 54, 48, 70, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, +97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 53, 29, 21, 23, 245, 244, 228, -69, 128, 13, 182, 224, 135, 53, 196, 207, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 158, 94, 53, 220, 30, 44, 109, +65, 154, 2, 226, 233, 146, 64, 64, 17, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 52, 102, 54, 48, 102, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, -0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 50, 100, 97, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, +0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -389,11 +389,11 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 136, 207, 217, 232, 43, 133, 4, 191, 97, 128, 87, 175, 215, 44, 158, 219, 0, 120, 77, 0, 0, 68, 88, 66, 67, 206, 105, 142, -150, 35, 105, 251, 25, 51, 50, 237, 25, 174, 254, 221, 178, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, 0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 63, 218, 217, 37, 32, 162, 116, 125, 221, 209, 13, 1, 180, 237, 26, 9, 0, 120, 77, 0, 0, 68, 88, 66, 67, 145, 94, 181, +7, 109, 13, 98, 195, 199, 5, 186, 118, 80, 46, 162, 146, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, 0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, 0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, 0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, -101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, 70, 69, 51, 56, +101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, 70, 51, 67, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 72, 0, 0, 0, 56, 3, 0, 0, 72, 0, 0, 0, 72, 3, 0, 0, 72, 0, 0, 0, 88, 3, 0, 0, 72, 0, 0, 0, 104, 3, 0, 0, 86, 0, 0, 0, 120, 3, 0, 0, 86, 0, 0, 0, 140, 3, 0, 0, 88, 0, 0, 0, 152, 3, 0, 0, 90, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, @@ -451,7 +451,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 186, 183, 128, 100, 234, 17, 138, 73, 142, 102, 213, 35, 218, 214, 112, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, +0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 45, 182, 148, 233, 23, 112, 203, 78, 148, 200, 178, 55, 161, 209, 117, 253, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -508,14 +508,14 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 39, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, -104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, 70, 69, 51, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, +104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, 70, 51, 67, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, -51, 102, 48, 52, 54, 55, 102, 101, 51, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +57, 51, 97, 57, 99, 55, 102, 51, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, -97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 221, 146, 60, 42, 88, 187, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 83, 70, 228, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 0, 106, 138, 126, 108, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -579,8 +579,8 @@ internal partial class SpriteSignedDistanceFieldFontShader 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, -117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 94, 0, 0, 0, -93, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, +93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -639,13 +639,13 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, -110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 70, 48, 52, 54, 55, -70, 69, 51, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, +70, 51, 67, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 148, 46, 49, 1, 73, 48, 194, 105, 1, 0, 0, 0, 186, 183, 128, 100, 234, 17, 138, 73, 142, 102, 213, 35, 218, 214, 112, 47, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, +0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 45, 182, 148, 233, 23, 112, 203, 78, 148, 200, 178, 55, 161, 209, 117, 253, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, -104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 51, 102, 48, 52, 54, 55, 102, 101, 51, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, +104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 57, 99, 55, 102, 51, 99, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 4386f1b49b..0847185093 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -34,288 +34,612 @@ internal partial class SpriteSignedDistanceFieldFontShader 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, -67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 9, 158, 143, 78, 52, 171, 165, 186, 6, 208, 204, 34, 59, 136, 189, 143, 0, 248, 34, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, -0, 11, 0, 6, 0, 197, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 97, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -0, 88, 1, 0, 0, 90, 1, 0, 0, 86, 1, 0, 0, 96, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 121, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 110, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, -0, 109, 1, 0, 0, 111, 1, 0, 0, 115, 1, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, 97, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, -0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, 109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, -97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, -0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 19, 0, 42, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 26, 0, 44, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, -115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 83, 1, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, -115, 100, 115, 108, 0, 7, 0, 20, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, 85, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, -46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, -97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, -116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, -97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, -0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, -105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, -83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, -0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, -110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 186, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, -0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 192, 0, 0, 0, 98, 0, 0, -0, 5, 0, 7, 0, 206, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 207, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 116, 101, 120, -116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 210, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 214, 0, 0, 0, 105, 110, 116, -95, 48, 0, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 218, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 219, 0, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 224, 0, 0, 0, 109, 101, 100, -105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 233, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, -0, 243, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 246, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 7, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 10, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, -0, 13, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 17, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 26, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, -0, 5, 0, 5, 0, 2, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 51, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 75, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, -116, 52, 0, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 89, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, -0, 88, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 91, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 94, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 6, 0, 6, 0, 94, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 94, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 94, 1, 0, 0, 2, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 95, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 96, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, -0, 97, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 100, 1, 0, -0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 107, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 112, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, -0, 111, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, -0, 5, 0, 6, 0, 115, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, -85, 84, 0, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, -0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 118, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 118, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, -0, 118, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 118, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 118, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 5, 0, 8, 0, 119, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 120, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 121, 1, 0, 0, 83, 112, 114, -105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 128, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 111, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 111, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 113, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, -0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 115, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 115, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, -0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, -0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, -0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, 75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, -0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, -0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 33, 0, 6, 0, 188, 0, 0, 0, 5, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 32, 0, 4, 0, 206, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 205, 0, 0, 0, 4, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, -0, 189, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 216, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, -0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 233, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, -0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 75, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 89, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, 91, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 92, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 93, 1, 0, 0, 4, 0, 0, -0, 30, 0, 5, 0, 94, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 95, 1, 0, 0, 6, 0, 0, 0, 94, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 103, 1, 0, -0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 107, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 112, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 117, 1, 0, -0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 118, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 119, 1, 0, 0, 6, 0, 0, 0, 118, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 128, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 96, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 109, 1, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 110, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 112, 1, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 114, 1, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 115, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 119, 1, 0, 0, 120, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 136, 0, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, -0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, -0, 51, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, -0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, -0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, 177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, -0, 188, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 191, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 248, 0, 2, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 199, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 200, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 198, 0, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 192, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, -0, 202, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 196, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, -0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 207, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 209, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 210, 0, 0, -0, 248, 0, 2, 0, 211, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, -0, 225, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 232, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, -0, 243, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 248, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, -0, 17, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 26, 1, 0, 0, 7, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, -0, 217, 0, 0, 0, 197, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 215, 0, 0, 0, 216, 0, 0, 0, 62, 0, 3, 0, 210, 0, 0, 0, 217, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 222, 0, 0, 0, 210, 0, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 223, 0, 0, 0, 221, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 226, 0, 0, 0, 207, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, -0, 226, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 230, 0, 0, 0, 207, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, -0, 65, 0, 5, 0, 189, 0, 0, 0, 234, 0, 0, 0, 207, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 62, 0, 3, 0, 232, 0, 0, 0, 235, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 238, 0, 0, 0, 185, 0, 0, -0, 225, 0, 0, 0, 228, 0, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 238, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 220, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, -0, 242, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 242, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 239, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, -0, 247, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 247, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 251, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 0, 0, 0, 239, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 253, 0, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, -0, 253, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 248, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, -0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 210, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 5, 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 247, 0, 3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 5, 1, 0, 0, 1, 1, 0, -0, 2, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 210, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 9, 1, 0, 0, 10, 1, 0, -0, 129, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 8, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 7, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 7, 1, 0, -0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 16, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 13, 1, 0, -0, 133, 0, 5, 0, 5, 0, 0, 0, 20, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 13, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 21, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 23, 1, 0, -0, 20, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 7, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 25, 1, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 17, 1, 0, 0, 25, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, -0, 27, 1, 0, 0, 214, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 17, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 30, 1, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 27, 1, 0, -0, 28, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 26, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 31, 1, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, -0, 26, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 35, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 34, 1, 0, -0, 62, 0, 3, 0, 208, 0, 0, 0, 35, 1, 0, 0, 249, 0, 2, 0, 2, 1, 0, 0, 248, 0, 2, 0, 2, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 36, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 37, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 248, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 40, 1, 0, -0, 197, 0, 0, 0, 46, 0, 0, 0, 36, 1, 0, 0, 37, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 40, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 41, 1, 0, 0, 207, 0, 0, 0, 254, 0, 2, 0, 41, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, -0, 4, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 58, 1, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 63, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 67, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, -0, 73, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 77, 1, 0, 0, 7, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 66, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 63, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, -0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 72, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 67, 1, 0, 0, 72, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 76, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 75, 1, 0, -0, 62, 0, 3, 0, 73, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 77, 1, 0, 0, 74, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 80, 1, 0, 0, 186, 0, 0, 0, 63, 1, 0, 0, 67, 1, 0, 0, 73, 1, 0, 0, 77, 1, 0, 0, 254, 0, 2, 0, 80, 1, 0, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 98, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 99, 1, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 101, 1, 0, -0, 88, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 102, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, -0, 57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 106, 1, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 108, 1, 0, -0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 121, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 123, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, -0, 124, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 123, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 125, 1, 0, -0, 126, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 127, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 129, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 129, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 130, 1, 0, -0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 131, 1, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 132, 1, 0, 0, 131, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 132, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 133, 1, 0, -0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 134, 1, 0, 0, 133, 1, 0, 0, 62, 0, 3, 0, 111, 1, 0, 0, 134, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 136, 1, 0, 0, 135, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 136, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 9, 158, 143, 78, 52, 171, 165, 186, 6, -208, 204, 34, 59, 136, 189, 143, 0, 248, 34, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 197, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, -14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 97, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 88, 1, 0, 0, 90, 1, 0, 0, 86, 1, 0, 0, 96, 1, 0, 0, 41, 0, 0, 0, 88, 0, 0, 0, -15, 0, 15, 0, 0, 0, 0, 0, 121, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 110, 1, 0, 0, 113, 1, 0, 0, 114, 1, 0, 0, 109, 1, 0, 0, 111, 1, 0, 0, 115, 1, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 16, 0, 3, 0, -97, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, -100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, -0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 7, 0, 21, 0, 34, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 19, 0, 36, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 7, 0, 20, 0, -109, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 0, 0, 0, 7, 0, 21, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 180, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, -116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, -7, 0, 19, 0, 181, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 23, 0, 183, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 0, 0, 0, 7, 0, 19, 0, 42, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, -100, 115, 108, 0, 7, 0, 26, 0, 44, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 7, 0, 21, 0, -81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, -97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 7, 0, 20, 0, 82, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 19, 0, 83, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, -103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 7, 0, 20, 0, 84, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, -101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 7, 0, 23, 0, -85, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 37, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 42, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 63, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, -111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 69, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, -116, 52, 0, 0, 5, 0, 7, 0, 75, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 86, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, -95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 88, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 113, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, -6, 0, 7, 0, 113, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, -83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 120, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 117, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, -5, 0, 9, 0, 123, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 138, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, -0, 0, 0, 0, 5, 0, 4, 0, 140, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 185, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, -186, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 189, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, -97, 116, 0, 0, 5, 0, 3, 0, 190, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 191, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 192, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 206, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, -97, 116, 52, 0, 5, 0, 6, 0, 207, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 209, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, -108, 111, 114, 0, 5, 0, 6, 0, 210, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 214, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 216, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, -5, 0, 7, 0, 218, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 219, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, -97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 221, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 224, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, -49, 0, 0, 0, 5, 0, 4, 0, 233, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 239, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 243, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 246, 0, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 248, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 4, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 1, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, -5, 0, 5, 0, 7, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 10, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 13, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, -17, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 26, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 2, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, -51, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 74, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, -5, 0, 4, 0, 75, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 87, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 86, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 89, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 88, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, -91, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 92, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, -6, 0, 6, 0, 92, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 92, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 93, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, -6, 0, 6, 0, 93, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 94, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 94, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 0, 6, 0, 6, 0, 94, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 94, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 95, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 96, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 97, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, -70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 100, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 103, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, -5, 0, 4, 0, 107, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 110, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 112, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 111, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, -113, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 114, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 115, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, -5, 0, 5, 0, 116, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 116, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, -0, 0, 0, 0, 6, 0, 5, 0, 116, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 117, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 117, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 117, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 117, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 118, 1, 0, 0, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 118, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 118, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -118, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 118, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 119, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 120, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 121, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, -116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 128, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 113, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 86, 1, 0, 0, 30, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 88, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 88, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 90, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, -90, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 109, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 110, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 110, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, -79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 111, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 111, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 113, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, -0, 22, 6, 0, 113, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 114, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 114, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, -115, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 115, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 113, 0, 0, 0, 0, 0, 0, 0, -4, 0, 0, 0, 72, 0, 5, 0, 113, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 41, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, -34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 88, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 117, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, -32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, -18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, -25, 0, 9, 0, 38, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 37, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 23, 0, 4, 0, 43, 0, 0, 0, 5, 0, 0, 0, -2, 0, 0, 0, 32, 0, 4, 0, 42, 0, 0, 0, 2, 0, 0, 0, 43, 0, 0, 0, 25, 0, 9, 0, 64, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 63, 0, 0, 0, -0, 0, 0, 0, 64, 0, 0, 0, 25, 0, 9, 0, 70, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 69, 0, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 32, 0, 4, 0, -75, 0, 0, 0, 6, 0, 0, 0, 43, 0, 0, 0, 26, 0, 2, 0, 87, 0, 0, 0, 32, 0, 4, 0, 86, 0, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 24, 0, 4, 0, 114, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 113, 0, 0, 0, 114, 0, 0, 0, -32, 0, 4, 0, 123, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 138, 0, 0, 0, 2, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 139, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 140, 0, 0, 0, 0, 0, 0, 0, -33, 0, 3, 0, 152, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 176, 0, 0, 0, 38, 0, 0, 0, 32, 0, 4, 0, 189, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 188, 0, 0, 0, 5, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, 189, 0, 0, 0, -32, 0, 4, 0, 206, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 205, 0, 0, 0, 4, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 206, 0, 0, 0, 189, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 214, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 216, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 221, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 139, 0, 0, 0, 229, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, -139, 0, 0, 0, 233, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, -5, 0, 0, 0, 74, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 75, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 87, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 89, 1, 0, 0, 1, 0, 0, 0, 43, 0, 0, 0, 32, 0, 4, 0, -91, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 92, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 93, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 94, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -95, 1, 0, 0, 6, 0, 0, 0, 94, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 103, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 107, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -112, 1, 0, 0, 3, 0, 0, 0, 43, 0, 0, 0, 30, 0, 5, 0, 116, 1, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 117, 1, 0, 0, 4, 0, 0, 0, 43, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 118, 1, 0, 0, 4, 0, 0, 0, -43, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 119, 1, 0, 0, 6, 0, 0, 0, 118, 1, 0, 0, 43, 0, 4, 0, 139, 0, 0, 0, 128, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 37, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, -86, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 123, 0, 0, 0, 117, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 86, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 88, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -91, 1, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 95, 1, 0, 0, 96, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 109, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 89, 1, 0, 0, 110, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -112, 1, 0, 0, 111, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 113, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 91, 1, 0, 0, 114, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 87, 1, 0, 0, 115, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -119, 1, 0, 0, 120, 1, 0, 0, 6, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 127, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 134, 0, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 136, 0, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 137, 0, 0, 0, 136, 0, 0, 0, 65, 0, 5, 0, 138, 0, 0, 0, 141, 0, 0, 0, 117, 0, 0, 0, 140, 0, 0, 0, 61, 0, 4, 0, 114, 0, 0, 0, 142, 0, 0, 0, -141, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 143, 0, 0, 0, 142, 0, 0, 0, 137, 0, 0, 0, 62, 0, 3, 0, 134, 0, 0, 0, 143, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 145, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 150, 0, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 154, 0, 0, 0, 51, 1, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 154, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, -54, 0, 5, 0, 4, 0, 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 61, 0, 4, 0, 87, 0, 0, 0, 166, 0, 0, 0, 88, 0, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 173, 0, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, -61, 0, 4, 0, 43, 0, 0, 0, 174, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 38, 0, 0, 0, 175, 0, 0, 0, 41, 0, 0, 0, 86, 0, 5, 0, 176, 0, 0, 0, 177, 0, 0, 0, 175, 0, 0, 0, 166, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 178, 0, 0, 0, -177, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 178, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 190, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, -191, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 192, 0, 0, 0, 248, 0, 2, 0, 193, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, -196, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 190, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 191, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 200, 0, 0, 0, -197, 0, 0, 0, 40, 0, 0, 0, 198, 0, 0, 0, 199, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 201, 0, 0, 0, 192, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 202, 0, 0, 0, 197, 0, 0, 0, 37, 0, 0, 0, 200, 0, 0, 0, 201, 0, 0, 0, 12, 0, 7, 0, -5, 0, 0, 0, 203, 0, 0, 0, 197, 0, 0, 0, 40, 0, 0, 0, 196, 0, 0, 0, 202, 0, 0, 0, 254, 0, 2, 0, 203, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, -207, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 208, 0, 0, 0, 55, 0, 3, 0, 206, 0, 0, 0, 209, 0, 0, 0, 55, 0, 3, 0, 189, 0, 0, 0, 210, 0, 0, 0, 248, 0, 2, 0, 211, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 218, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 189, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 225, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 189, 0, 0, 0, 232, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 243, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 248, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 189, 0, 0, 0, 7, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 17, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 26, 1, 0, 0, 7, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 217, 0, 0, 0, 197, 0, 0, 0, 43, 0, 0, 0, 212, 0, 0, 0, 215, 0, 0, 0, 216, 0, 0, 0, -62, 0, 3, 0, 210, 0, 0, 0, 217, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 219, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 222, 0, 0, 0, 210, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 223, 0, 0, 0, 221, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, -220, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 226, 0, 0, 0, 207, 0, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 225, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, -230, 0, 0, 0, 207, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 65, 0, 5, 0, 189, 0, 0, 0, 234, 0, 0, 0, 207, 0, 0, 0, 233, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 235, 0, 0, 0, 234, 0, 0, 0, 62, 0, 3, 0, 232, 0, 0, 0, 235, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 238, 0, 0, 0, 185, 0, 0, 0, 225, 0, 0, 0, 228, 0, 0, 0, 232, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 238, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 220, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 241, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 242, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 239, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 247, 0, 0, 0, 245, 0, 0, 0, 246, 0, 0, 0, 62, 0, 3, 0, 243, 0, 0, 0, 247, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 249, 0, 0, 0, 243, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 249, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 243, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 252, 0, 0, 0, 239, 0, 0, 0, -12, 0, 8, 0, 5, 0, 0, 0, 253, 0, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 250, 0, 0, 0, 251, 0, 0, 0, 252, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, 0, 253, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 254, 0, 0, 0, 248, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 255, 0, 0, 0, 248, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 0, 1, 0, 0, 255, 0, 0, 0, 254, 0, 0, 0, 62, 0, 3, 0, 248, 0, 0, 0, 0, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 1, 0, 0, 210, 0, 0, 0, 186, 0, 5, 0, -8, 0, 0, 0, 5, 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 247, 0, 3, 0, 2, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 5, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 248, 0, 2, 0, 1, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 8, 1, 0, 0, -220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 9, 1, 0, 0, 210, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 11, 1, 0, 0, 9, 1, 0, 0, 10, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 8, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, -7, 1, 0, 0, 12, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 224, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 7, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 62, 0, 3, 0, -13, 1, 0, 0, 16, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 218, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 13, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 20, 1, 0, 0, 18, 1, 0, 0, 19, 1, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 21, 1, 0, 0, 13, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 22, 1, 0, 0, 21, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 23, 1, 0, 0, 20, 1, 0, 0, 22, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 7, 1, 0, 0, -129, 0, 5, 0, 5, 0, 0, 0, 25, 1, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 62, 0, 3, 0, 17, 1, 0, 0, 25, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 214, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 28, 1, 0, 0, 229, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 17, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 30, 1, 0, 0, 197, 0, 0, 0, 49, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 29, 1, 0, 0, 62, 0, 3, 0, 26, 1, 0, 0, 30, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 31, 1, 0, 0, 209, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 32, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 33, 1, 0, 0, 26, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 34, 1, 0, 0, 33, 1, 0, 0, 33, 1, 0, 0, -33, 1, 0, 0, 33, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 35, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 31, 1, 0, 0, 32, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 208, 0, 0, 0, 35, 1, 0, 0, 249, 0, 2, 0, 2, 1, 0, 0, 248, 0, 2, 0, -2, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 36, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 4, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 1, 0, 0, 208, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 38, 1, 0, 0, 248, 0, 0, 0, -80, 0, 7, 0, 4, 0, 0, 0, 39, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 38, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 40, 1, 0, 0, 197, 0, 0, 0, 46, 0, 0, 0, 36, 1, 0, 0, 37, 1, 0, 0, 39, 1, 0, 0, 62, 0, 3, 0, -207, 0, 0, 0, 40, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 41, 1, 0, 0, 207, 0, 0, 0, 254, 0, 2, 0, 41, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 4, 0, 0, 0, 51, 1, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 248, 0, 2, 0, 58, 1, 0, 0, -59, 0, 4, 0, 206, 0, 0, 0, 63, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 67, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 206, 0, 0, 0, 73, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 189, 0, 0, 0, 77, 1, 0, 0, 7, 0, 0, 0, -57, 0, 4, 0, 4, 0, 0, 0, 66, 1, 0, 0, 120, 0, 0, 0, 62, 0, 3, 0, 63, 1, 0, 0, 66, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 72, 1, 0, 0, 71, 1, 0, 0, -62, 0, 3, 0, 67, 1, 0, 0, 72, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 76, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 74, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 73, 1, 0, 0, 76, 1, 0, 0, 62, 0, 3, 0, 77, 1, 0, 0, 74, 1, 0, 0, -57, 0, 8, 0, 4, 0, 0, 0, 80, 1, 0, 0, 186, 0, 0, 0, 63, 1, 0, 0, 67, 1, 0, 0, 73, 1, 0, 0, 77, 1, 0, 0, 254, 0, 2, 0, 80, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 98, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 99, 1, 0, 0, 96, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 101, 1, 0, 0, 88, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -102, 1, 0, 0, 96, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 1, 0, 0, 90, 1, 0, 0, 62, 0, 3, 0, 102, 1, 0, 0, 104, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 105, 1, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -106, 1, 0, 0, 96, 1, 0, 0, 107, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 108, 1, 0, 0, 106, 1, 0, 0, 62, 0, 3, 0, 86, 1, 0, 0, 108, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 121, 1, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 248, 0, 2, 0, 122, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 123, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 124, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 123, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 125, 1, 0, 0, 120, 1, 0, 0, 103, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 113, 1, 0, 0, 62, 0, 3, 0, 125, 1, 0, 0, 126, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 127, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 129, 1, 0, 0, 114, 1, 0, 0, 62, 0, 3, 0, 127, 1, 0, 0, 129, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 130, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 131, 1, 0, 0, 120, 1, 0, 0, 107, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 132, 1, 0, 0, 131, 1, 0, 0, 62, 0, 3, 0, 109, 1, 0, 0, 132, 1, 0, 0, 65, 0, 5, 0, 75, 0, 0, 0, 133, 1, 0, 0, 120, 1, 0, 0, 100, 1, 0, 0, 61, 0, 4, 0, 43, 0, 0, 0, 134, 1, 0, 0, 133, 1, 0, 0, -62, 0, 3, 0, 111, 1, 0, 0, 134, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 1, 0, 0, 120, 1, 0, 0, 128, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 1, 0, 0, 135, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 136, 1, 0, 0, 253, 0, 1, 0, -56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 46, 19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, +0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, 86, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, 0, 104, 1, 0, +0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, 110, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, +0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, +97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, +115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, +32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, +73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, +102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, +70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, +13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, +86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, +83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, +0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, +104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, +110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, +32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, +111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, +104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, +86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, +68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, +13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, +110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, +100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, +46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, +105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, +10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, +121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, +32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, +116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, +59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, +115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, +101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, +97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, +117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, +67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, +116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, +77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, +10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, +97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, +97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, +109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, +0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, +101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, +112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, +73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, +32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, +32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, +97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, +97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, +109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, +115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, +98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, +100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, +116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, +114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, +40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, +105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, +119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, +102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, +32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, +32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, +32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, +50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, +101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, +97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, +110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, +100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, +111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, +116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, +32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, +97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, +68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, +105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, +99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, +44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, +32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 26, 0, 39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, +0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, +83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, +100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, +103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, 0, 3, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, +0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, +97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, +0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, +119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, 0, 83, 105, 103, +110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, +116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 185, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, +0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, +0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, +0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, +0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, +0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, 0, 115, 105, 103, +68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, +0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, 0, 102, 108, 111, +97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, +112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 254, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, +110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, +0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 1, 0, +0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 84, 1, 0, +0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, +0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, +80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, 0, 105, 110, 95, +86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 105, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 0, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, +0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, 0, 3, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, +0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 118, 1, 0, +0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, 0, 3, 22, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 101, 1, 0, +0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 104, 1, 0, +0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 104, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, +0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, +0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, +0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, +0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, +0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, +0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, +0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, +0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 185, 0, 0, +0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 184, 0, 0, 0, 5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, 0, 202, 0, 0, +0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, +0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, +0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, +0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, +0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 84, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, 0, 43, 0, 4, +0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, +0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, +0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, +0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, +0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, +0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 57, 0, 4, +0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, +0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, 0, 90, 1, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, +0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 55, 0, 3, +0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, +0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 188, 0, 0, +0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, +0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 204, 0, 0, +0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, +0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, +0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, +0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, 0, 238, 0, 0, +0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 241, 0, 0, +0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 243, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, +0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, +0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 186, 0, 5, +0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 36, 0, 0, +0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, +0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, 0, 209, 0, 4, +0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, 0, 19, 1, 0, +0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 21, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 225, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, 13, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, 0, 8, 0, 4, +0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, 0, 80, 0, 7, +0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 204, 0, 0, +0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 12, 0, 8, +0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, 37, 1, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 46, 1, 0, +0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 53, 1, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, 0, 7, 0, 0, +0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, +0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, 0, 72, 1, 0, +0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, +0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, 0, 62, 0, 3, +0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, +0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, +0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, 0, 65, 0, 5, +0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 125, 1, 0, 0, 62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 46, +19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, +46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, 86, 1, 0, 0, +40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, 0, 104, 1, 0, 0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, 110, 1, 0, 0, +116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, +32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, +111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, +119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, +101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, +13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, +65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, +95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, +104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, +32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, +114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, +116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, +116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, +68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, +47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, +32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, +108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, +68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, +111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, +110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, +116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, +99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, +114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, +97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, +110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, +100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, +101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, +3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, +115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, +105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, +116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, +116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, +99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, +115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, +68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, +101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, +32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, +77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, +97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, +73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, +114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, +112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, +54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, +82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, +101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, +32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, +32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, +105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, +104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, +97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, +73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, +32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, +97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, +101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, +117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, +111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, +120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, +179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, +111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, +67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, +101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, +111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, +123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, +114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, +97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, +108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, +98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, +111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, +32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, +32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, +109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, +108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, +101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, +42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, +105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, +32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, +116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, +116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, +13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, +105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 26, 0, +39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, +32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, +111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, +119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, +101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, +13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, +100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, +40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, +114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, +22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, +62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, +116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, +83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, +5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 185, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, +5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, +212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, +5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, +99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, 116, 114, 97, 110, +115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, +253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, 115, 105, 103, 68, +105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 254, 0, 0, 0, +105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, +5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, +76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, 105, 110, 95, 80, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, +82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, +83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 84, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, +84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, +5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, 83, 112, 114, 105, +116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, +5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, +5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, 111, 117, 116, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 105, 1, 0, 0, +111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, +107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, 1, 0, 0, 0, +84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 118, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, +2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, +80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 101, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, +71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 104, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 104, 1, 0, 0, +3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, +0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, +33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, +33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, +7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, +30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, +37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, +4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, +43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 185, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 184, 0, 0, 0, +5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, 43, 0, 4, 0, +138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, +138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, +79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 84, 1, 0, 0, +4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, +138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, +4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, +77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, +141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, +149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, +61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, +177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, +187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, +187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 188, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, +37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 14, 0, 0, 0, +5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, +185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 206, 0, 0, 0, +111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, 8, 0, 4, 0, +179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, +219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, +224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, +234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, 0, 238, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 243, 0, 0, 0, +8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, 8, 0, 4, 0, +179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, +62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, +247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, +216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, 62, 0, 3, 0, +3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, +12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, 136, 0, 5, 0, +5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, 0, 19, 1, 0, 0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 21, 1, 0, 0, +8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, 13, 1, 0, 0, +12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, +29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 204, 0, 0, 0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, 248, 0, 2, 0, +254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, 204, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, +32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, 37, 1, 0, 0, +56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 46, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 53, 1, 0, 0, +59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, +8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, +71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, 0, 72, 1, 0, 0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, +30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, 62, 0, 3, 0, +89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, +95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, +54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, 100, 1, 0, 0, +62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 125, 1, 0, 0, +62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } From e1a8929c826b283ff62d4a3a93a39cac421e978b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 10 Apr 2026 16:05:16 +0900 Subject: [PATCH 1043/1182] fix: use ShaderMixinGeneratorSource for SDFX effect names in ColorTransformBase --- .../Rendering/Images/ColorTransforms/ColorTransformBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs index 2a0d0f976a..c7bb1e902d 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs +++ b/sources/engine/Stride.Rendering/Rendering/Images/ColorTransforms/ColorTransformBase.cs @@ -31,7 +31,7 @@ protected ColorTransformBase(string colorTransformShader) // Initialize all Parameters with values coming from each ParameterKey InitializeProperties(); - Shader = new ShaderClassSource(colorTransformShader); + Shader = new ShaderMixinGeneratorSource(colorTransformShader); } /// From 9e5ead63fcd7a6b0c7c1283c929c4d12f1508731 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 11 Apr 2026 22:01:02 +0900 Subject: [PATCH 1044/1182] fix: resolve StructType identity across shader cache boundaries When a generic shader (e.g. LightSpotGroup) is instantiated, the SpirvContext is copied and ProcessNameAndTypes creates fresh StructType objects. These are content-identical but reference-different from the original, causing SpirvContext.Types dictionary lookups to fail. Three changes: - Add value equality (Equals/GetHashCode) to StructType, comparing by Name + SequenceEqual(Members), matching the FunctionType pattern - Add IShaderImporter.ResolveStructType to resolve OpImportStructSDSL placeholders to real struct types (with members) from the owning shader's cached buffer - Redirect ApplicationCache to build path during asset compilation so shader caches are per-project, not global to the compiler --- .../FileShaderCache.cs | 10 ++++- .../FileShaderLoader.cs | 13 +++++- .../Stride.Shaders.Compilers/SDSL/SDSLC.cs | 2 +- .../Core/SymbolTypes.cs | 23 +++++++++++ .../Parsing/SDSL/AST/Shader.cs | 41 +++++++++++++++++-- 5 files changed, 81 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs index e07dc20e7a..9a3dd62a57 100644 --- a/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderCache.cs @@ -18,6 +18,12 @@ namespace Stride.Shaders.Compilers; /// public class FileShaderCache(IVirtualFileProvider fileProvider, string basePath = "shaders") : IShaderCache { + /// + /// Optional importer for resolving struct types from imported shaders during deserialization. + /// Set after construction to break the circular dependency with the shader loader. + /// + internal IShaderImporter? ShaderImporter { get; set; } + private readonly object lockObject = new(); private readonly ShaderCache memoryCache = new(); @@ -140,7 +146,7 @@ private static void Serialize(BinaryWriter writer, ShaderBuffers buffers, Object writer.Write(bytecode); } - private static ShaderBuffers Deserialize(BinaryReader reader, out ObjectId hash) + private ShaderBuffers Deserialize(BinaryReader reader, out ObjectId hash) { var buffer = new byte[reader.BaseStream.Length]; reader.ReadExactly(buffer); @@ -158,7 +164,7 @@ private static ShaderBuffers Deserialize(BinaryReader reader, out ObjectId hash) } } - ShaderClass.ProcessNameAndTypes(result.Context); + ShaderClass.ProcessNameAndTypes(result.Context, ShaderImporter); return result; } diff --git a/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs index e23ed7b0ef..5fec43a4b2 100644 --- a/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs +++ b/sources/shaders/Stride.Shaders.Compilers/FileShaderLoader.cs @@ -1,12 +1,21 @@ using Stride.Core.IO; using Stride.Core.Storage; +using Stride.Shaders.Parsing.SDSL.AST; using Stride.Shaders.Spirv.Building; namespace Stride.Shaders.Compilers; -public class FileShaderLoader(IVirtualFileProvider FileProvider) : ShaderLoaderBase(new FileShaderCache(VirtualFileSystem.ApplicationCache)) +public class FileShaderLoader : ShaderLoaderBase { - public ShaderSourceManager SourceManager { get; } = new(FileProvider); + public ShaderSourceManager SourceManager { get; } + + public FileShaderLoader(IVirtualFileProvider fileProvider) : base(new FileShaderCache(VirtualFileSystem.ApplicationCache)) + { + SourceManager = new ShaderSourceManager(fileProvider); + // Wire up the importer so the file cache can resolve struct types during deserialization + if (Cache is FileShaderCache fsc) + fsc.ShaderImporter = new ShaderLoaderImporter(this); + } protected override bool ExternalFileExists(string name) => SourceManager.IsClassExists(name); diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index 90b9ccb2fb..b601cd95d6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -110,7 +110,7 @@ public readonly bool Compile(string? filename, string code, ObjectId hash, ReadO // Ensure all names and types from OpName/OpType instructions are registered // in the context dictionaries. The compiler may not explicitly register everything // (e.g. names for imported IDs, or types from InsertWithoutDuplicates). - ShaderClass.ProcessNameAndTypes(lastBuffer.Context); + ShaderClass.ProcessNameAndTypes(lastBuffer.Context, new ShaderLoaderImporter(ShaderLoader)); if (options.RegisterInCache) ShaderLoader.Cache.RegisterShader(shader.Name, null, macros, lastBuffer, hash); diff --git a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs index dba0245b5a..16decd5ad6 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Core/SymbolTypes.cs @@ -241,6 +241,7 @@ public partial record StructuredType(string Name, List Mem public override string ToId() => Name; public override string ToString() => Name; + public bool TryGetFieldType(string name, [MaybeNullWhen(false)] out SymbolType type) { foreach (var field in Members) @@ -270,6 +271,28 @@ public int TryGetFieldIndex(string name) public sealed partial record StructType(string Name, List Members) : StructuredType(Name, Members) { + // Value equality by Name + Members (matching the FunctionType pattern). + // Multiple StructType instances for the same struct can exist when: + // - generic shader instantiation copies the SpirvContext (Builder.Class.cs) + // - shader cache deserialization creates fresh objects (FileShaderCache) + // Without this, SpirvContext.Types dictionary lookups fail because + // the default record equality uses List<> reference equality. + public bool Equals(StructType? other) + { + if (other is null) return false; + if (ReferenceEquals(this, other)) return true; + return Name == other.Name && Members.SequenceEqual(other.Members); + } + + public override int GetHashCode() + { + int hash = 17; + hash = hash * 31 + (Name?.GetHashCode() ?? 0); + foreach (var member in Members) + hash = hash * 31 + member.GetHashCode(); + return hash; + } + public override string ToString() => base.ToString(); } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs index b3f543c9f4..8a82387575 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Shader.cs @@ -22,6 +22,12 @@ namespace Stride.Shaders.Parsing.SDSL.AST; public interface IShaderImporter { SymbolType Import(ShaderClassInstantiation classSource, SpirvContext declaringContext); + + /// + /// Resolves an imported struct type by name from a shader. + /// Returns the full with members, or null if not available. + /// + StructuredType? ResolveStructType(ShaderSymbol shader, string structName); } public class EmptyShaderImporter : IShaderImporter @@ -30,6 +36,28 @@ public SymbolType Import(ShaderClassInstantiation classSource, SpirvContext decl { return new ShaderSymbol(classSource.ClassName, classSource.GenericArguments); } + + public virtual StructuredType? ResolveStructType(ShaderSymbol shader, string structName) => null; +} + +/// +/// An that resolves struct types by loading shader buffers +/// from an . +/// +public class ShaderLoaderImporter(IExternalShaderLoader loader) : EmptyShaderImporter +{ + public override StructuredType? ResolveStructType(ShaderSymbol shader, string structName) + { + if (loader.LoadExternalBuffer(shader.Name, [], out var buffer, out _, out _)) + { + foreach (var (_, symbolType) in buffer.Context.ReverseTypes) + { + if (symbolType is StructuredType st && st.ToId() == structName) + return st; + } + } + return null; + } } public partial class ShaderClass(Identifier name, TextLocation info) : ShaderDeclaration(info) @@ -281,9 +309,16 @@ void RegisterName(int target, string name) } else if (instruction.Op == Op.OpImportStructSDSL && (OpImportStructSDSL)instruction is { } importStruct) { - // Register an empty placeholder struct — the real StructuredType is resolved - // later via ImportShaderStruct when the shader is imported into the main context. - RegisterType(importStruct.ResultId, new StructType(importStruct.StructName, [])); + // Resolve the imported struct to the real type (with members) from the owning shader. + // Without this, an empty placeholder StructType("Name", []) is created, which + // wouldn't match the full struct when used in function type parameters. + StructuredType? resolved = null; + if (context.ReverseTypes.TryGetValue(importStruct.Shader, out var shaderType) + && shaderType is ShaderSymbol shaderSym) + { + resolved = realShaderImporter.ResolveStructType(shaderSym, importStruct.StructName); + } + RegisterType(importStruct.ResultId, resolved ?? new StructType(importStruct.StructName, [])); } } From 94e683a226b9c44ad4c26f7526107932ee7b9ab3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 14 Apr 2026 18:08:17 +0900 Subject: [PATCH 1045/1182] fix: update solution filters for sdsl-rewrite project paths --- build/Stride.Android.slnf | 12 +++++++----- build/Stride.Runtime.slnf | 16 +++++++++------- build/Stride.iOS.slnf | 12 +++++++----- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/build/Stride.Android.slnf b/build/Stride.Android.slnf index bb99599a8f..3db845c146 100644 --- a/build/Stride.Android.slnf +++ b/build/Stride.Android.slnf @@ -18,15 +18,17 @@ "..\\sources\\engine\\Stride.Particles\\Stride.Particles.csproj", "..\\sources\\engine\\Stride.Physics\\Stride.Physics.csproj", "..\\sources\\engine\\Stride.Rendering\\Stride.Rendering.csproj", - "..\\sources\\engine\\Stride.Shaders\\Stride.Shaders.csproj", - "..\\sources\\engine\\Stride.Shaders.Compiler\\Stride.Shaders.Compiler.csproj", - "..\\sources\\engine\\Stride.Shaders.Parser\\Stride.Shaders.Parser.csproj", "..\\sources\\engine\\Stride.SpriteStudio.Runtime\\Stride.SpriteStudio.Runtime.csproj", "..\\sources\\engine\\Stride.UI\\Stride.UI.csproj", "..\\sources\\engine\\Stride.Video\\Stride.Video.csproj", "..\\sources\\engine\\Stride.VirtualReality\\Stride.VirtualReality.csproj", - "..\\sources\\shaders\\Irony\\Irony.csproj", - "..\\sources\\shaders\\Stride.Core.Shaders\\Stride.Core.Shaders.csproj" + "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj" ] } } diff --git a/build/Stride.Runtime.slnf b/build/Stride.Runtime.slnf index 55f5299efd..ecc1a96a82 100644 --- a/build/Stride.Runtime.slnf +++ b/build/Stride.Runtime.slnf @@ -17,18 +17,20 @@ "..\\sources\\engine\\Stride.Particles\\Stride.Particles.csproj", "..\\sources\\engine\\Stride.Physics\\Stride.Physics.csproj", "..\\sources\\engine\\Stride.Rendering\\Stride.Rendering.csproj", - "..\\sources\\engine\\Stride.Shaders.Compiler\\Stride.Shaders.Compiler.csproj", - "..\\sources\\engine\\Stride.Shaders.Parser\\Stride.Shaders.Parser.csproj", - "..\\sources\\engine\\Stride.Shaders\\Stride.Shaders.csproj", "..\\sources\\engine\\Stride.SpriteStudio.Runtime\\Stride.SpriteStudio.Runtime.csproj", "..\\sources\\engine\\Stride.UI\\Stride.UI.csproj", "..\\sources\\engine\\Stride.Video\\Stride.Video.csproj", "..\\sources\\engine\\Stride.VirtualReality\\Stride.VirtualReality.csproj", "..\\sources\\engine\\Stride.Voxels\\Stride.Voxels.csproj", "..\\sources\\engine\\Stride\\Stride.csproj", - "..\\sources\\tools\\Stride.FreeImage\\Stride.FreeImage.csproj", - "..\\sources\\shaders\\Irony\\Irony.csproj", - "..\\sources\\shaders\\Stride.Core.Shaders\\Stride.Core.Shaders.csproj" + "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj", + "..\\sources\\tools\\Stride.FreeImage\\Stride.FreeImage.csproj" ] } -} \ No newline at end of file +} diff --git a/build/Stride.iOS.slnf b/build/Stride.iOS.slnf index bb99599a8f..3db845c146 100644 --- a/build/Stride.iOS.slnf +++ b/build/Stride.iOS.slnf @@ -18,15 +18,17 @@ "..\\sources\\engine\\Stride.Particles\\Stride.Particles.csproj", "..\\sources\\engine\\Stride.Physics\\Stride.Physics.csproj", "..\\sources\\engine\\Stride.Rendering\\Stride.Rendering.csproj", - "..\\sources\\engine\\Stride.Shaders\\Stride.Shaders.csproj", - "..\\sources\\engine\\Stride.Shaders.Compiler\\Stride.Shaders.Compiler.csproj", - "..\\sources\\engine\\Stride.Shaders.Parser\\Stride.Shaders.Parser.csproj", "..\\sources\\engine\\Stride.SpriteStudio.Runtime\\Stride.SpriteStudio.Runtime.csproj", "..\\sources\\engine\\Stride.UI\\Stride.UI.csproj", "..\\sources\\engine\\Stride.Video\\Stride.Video.csproj", "..\\sources\\engine\\Stride.VirtualReality\\Stride.VirtualReality.csproj", - "..\\sources\\shaders\\Irony\\Irony.csproj", - "..\\sources\\shaders\\Stride.Core.Shaders\\Stride.Core.Shaders.csproj" + "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", + "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj" ] } } From deac031f8755cbd064c067b9870f548ebed5d9a8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 14 Apr 2026 18:25:08 +0900 Subject: [PATCH 1046/1182] ci: add submodules: true to workflow checkouts for SPIR-V headers --- .github/workflows/build-android.yml | 1 + .github/workflows/build-ios.yml | 1 + .github/workflows/build-linux-runtime.yml | 1 + .github/workflows/build-vs-package.yml | 1 + .github/workflows/build-windows-full.yml | 1 + .github/workflows/build-windows-runtime.yml | 1 + .github/workflows/test-linux-game.yml | 3 +++ .github/workflows/test-linux-simple.yml | 2 ++ .github/workflows/test-windows-game.yml | 2 ++ .github/workflows/test-windows-simple.yml | 1 + 10 files changed, 14 insertions(+) diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index 80600dc4d5..be984fe1db 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -49,6 +49,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml index 3dcc3e8c4c..94257e1de2 100644 --- a/.github/workflows/build-ios.yml +++ b/.github/workflows/build-ios.yml @@ -49,6 +49,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/build-linux-runtime.yml b/.github/workflows/build-linux-runtime.yml index b3c1604246..5099b8ac55 100644 --- a/.github/workflows/build-linux-runtime.yml +++ b/.github/workflows/build-linux-runtime.yml @@ -49,6 +49,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/build-vs-package.yml b/.github/workflows/build-vs-package.yml index 2cc561a42e..bc0ba094c2 100644 --- a/.github/workflows/build-vs-package.yml +++ b/.github/workflows/build-vs-package.yml @@ -32,6 +32,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/build-windows-full.yml b/.github/workflows/build-windows-full.yml index 220c16998d..51d1b95388 100644 --- a/.github/workflows/build-windows-full.yml +++ b/.github/workflows/build-windows-full.yml @@ -44,6 +44,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/build-windows-runtime.yml b/.github/workflows/build-windows-runtime.yml index 88c48d2b23..bbd7ba8727 100644 --- a/.github/workflows/build-windows-runtime.yml +++ b/.github/workflows/build-windows-runtime.yml @@ -60,6 +60,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index afa13f37c1..38a3a5cf34 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -37,6 +37,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' @@ -113,6 +114,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' @@ -187,6 +189,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/test-linux-simple.yml b/.github/workflows/test-linux-simple.yml index adac66f471..a93043268d 100644 --- a/.github/workflows/test-linux-simple.yml +++ b/.github/workflows/test-linux-simple.yml @@ -35,6 +35,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' @@ -66,6 +67,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index 3cf18bf8a3..dbd2db6f4e 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -49,6 +49,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' @@ -110,6 +111,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' diff --git a/.github/workflows/test-windows-simple.yml b/.github/workflows/test-windows-simple.yml index efa7503db9..1e3feb07fb 100644 --- a/.github/workflows/test-windows-simple.yml +++ b/.github/workflows/test-windows-simple.yml @@ -34,6 +34,7 @@ jobs: - uses: actions/checkout@v4 with: lfs: true + submodules: true - uses: actions/setup-dotnet@v4 with: dotnet-version: '10.0.x' From b9a5955b48a3567a7dc51a85b810ad14633de735 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 14 Apr 2026 23:43:53 +0900 Subject: [PATCH 1047/1182] ci: replace dorny/test-reporter with phoenix-actions/test-reporting for fork PR support --- .github/workflows/test-linux-game.yml | 14 ++++++-------- .github/workflows/test-linux-simple.yml | 9 +++------ .github/workflows/test-windows-game.yml | 14 ++++++-------- .github/workflows/test-windows-simple.yml | 9 +++------ 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index 38a3a5cf34..cc3bbf2817 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -16,10 +16,6 @@ on: default: Debug type: string -permissions: - checks: write - contents: read - concurrency: group: test-linux-game-${{ github.event.pull_request.number || github.ref }}-${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} @@ -162,12 +158,13 @@ jobs: -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Linux Game Common' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 @@ -233,12 +230,13 @@ jobs: -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Linux Game GPU (Vulkan)' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test-linux-simple.yml b/.github/workflows/test-linux-simple.yml index a93043268d..a9fac581ec 100644 --- a/.github/workflows/test-linux-simple.yml +++ b/.github/workflows/test-linux-simple.yml @@ -16,10 +16,6 @@ on: default: Debug type: string -permissions: - checks: write - contents: read - concurrency: group: test-linux-simple-${{ github.event.pull_request.number || github.ref }}-${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} @@ -91,9 +87,10 @@ jobs: --logger:trx --ResultsDirectory:TestResults - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Linux Simple' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index dbd2db6f4e..22cf837338 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -25,10 +25,6 @@ on: default: Debug type: string -permissions: - checks: write - contents: read - concurrency: group: test-windows-game-${{ github.event.pull_request.number || github.ref }}-${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} @@ -73,12 +69,13 @@ jobs: -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Windows Game Common' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 @@ -174,12 +171,13 @@ jobs: -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Windows Game ${{ matrix.graphics-api }}' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' - name: Collect symbols for crash analysis if: always() shell: pwsh diff --git a/.github/workflows/test-windows-simple.yml b/.github/workflows/test-windows-simple.yml index 1e3feb07fb..7b429efb34 100644 --- a/.github/workflows/test-windows-simple.yml +++ b/.github/workflows/test-windows-simple.yml @@ -16,10 +16,6 @@ on: default: Debug type: string -permissions: - checks: write - contents: read - concurrency: group: test-windows-simple-${{ github.event.pull_request.number || github.ref }}-${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} @@ -56,9 +52,10 @@ jobs: -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} - name: Publish Test Report if: always() - uses: dorny/test-reporter@v1 + uses: phoenix-actions/test-reporting@v15 with: name: 'Test Report: Windows Simple' path: TestResults/*.trx reporter: dotnet-trx - token: ${{ secrets.GITHUB_TOKEN }} + output-to: step-summary + list-tests: 'failed' From a523529f90c076ccfd22bd06fc06cc8f3d710b88 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 00:24:14 +0900 Subject: [PATCH 1048/1182] test: Updated gold images --- .../Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png | 3 +++ .../Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png | 3 +++ .../Linux.Vulkan/SwiftShader/SpriteTestGame.png | 3 +++ .../Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontJapanese.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontVarious.f1.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontVarious.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestImageLoad.png | 3 +++ .../Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png | 3 +++ .../Linux.Vulkan/SwiftShader/TestLightShafts.png | 3 +++ .../Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png | 3 +++ .../Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png | 4 ++-- .../Windows.Direct3D11/WARP/TestLightShafts.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ClickTests.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/ClickTests.f2.png | 3 +++ .../Linux.Vulkan/SwiftShader/ClickTests.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ClickTests.f4.png | 3 +++ .../Linux.Vulkan/SwiftShader/ClickTests.f5.png | 3 +++ .../Linux.Vulkan/SwiftShader/ClickTests.f6.png | 3 +++ .../Linux.Vulkan/SwiftShader/ClickTests.png | 3 +++ .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.png | 3 +++ .../Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png | 4 ++-- .../Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png | 4 ++-- .../Linux.Vulkan/SwiftShader/DynamicFontTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f10.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f11.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f4.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f5.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f6.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f7.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f8.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.f9.png | 4 ++-- .../Linux.Vulkan/SwiftShader/EditTextTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRegionTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ImageRotatedTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png | 2 +- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png | 3 +++ .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png | 3 +++ .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png | 3 +++ .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png | 3 +++ .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png | 3 +++ .../Linux.Vulkan/SwiftShader/SliderTest.f1.png | 3 +++ .../Linux.Vulkan/SwiftShader/SliderTest.f2.png | 3 +++ .../Linux.Vulkan/SwiftShader/TextBlockTest.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f10.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f11.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f12.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f13.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f14.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f4.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f5.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f6.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f7.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f8.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.f9.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockTest.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png | 4 ++-- .../Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png | 4 ++-- 97 files changed, 219 insertions(+), 141 deletions(-) create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png new file mode 100644 index 0000000000..fa3a724e16 --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba89080019d106875c2a6f0bfc7a1bf5211c5a6deea9b5d4870059e84e8f250d +size 302163 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png new file mode 100644 index 0000000000..056b3f43c5 --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce1ae0208bc268363fd258c7a0fb251a2e45174c66d3e64c92c109f69ee34f42 +size 263085 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png new file mode 100644 index 0000000000..f04bb06bc6 --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f2575618a54487b56c8bcb4c54aa75a11d750eef42c8d0d6d5e6d145d4e56b9d +size 227263 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png new file mode 100644 index 0000000000..91246090df --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86cb8e2166621d7e754f647c99aa7b41735aef1314a6b297a369abf5b328d8a6 +size 53458 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png new file mode 100644 index 0000000000..32adad4ae1 --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02ef2c1eb01ae21584226e890f19b92017b5b55e970cdc355a9410051eaffc61 +size 53359 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png new file mode 100644 index 0000000000..a06441836a --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6c92ef8c4e0f2af22d9f1e2a57584016e32e16ec7395a08d5594c86fa74f8ad3 +size 60158 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png index 6b2fdb39da..7732ef9946 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cda44732103516415b428e6a086274f279141fd7a0e36425c68165cc7a340ce3 -size 59637 +oid sha256:9e9902492277988d001e53ae3fa51a374b10d029aa37e54155833dc7f3e76be1 +size 60213 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png index d4bc96a399..38d6ddc812 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8343c2c0fd3ddb15127087c2b78f03d7dad0caa0dc55d523ee2926f2eb8ddada -size 65352 +oid sha256:cefe5766fd77d4130e0e9b84f15d78395579e8a12ffb19e2d5bd68b1dca739cf +size 65940 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png index 8ca1ab9d33..e454edbc5d 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d994e03f801439bb67e3b3d696eb3a4508e6548b07828330dfa581864ba87b7 -size 58540 +oid sha256:2a71157ff1a61364663bd95d27a155aafd0f188a9792df653f4ea5c6d58c9089 +size 59263 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png index a625e6623e..ffbd218fa8 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93bca12d459cef479b1698e0687a5b0c3409dd790240df5c86de1d31fc6ee0e5 -size 100824 +oid sha256:f93a94cc9ca69583b6b60208e3c84454f8291c8367b301d5234725b461816080 +size 100864 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png index 0113966b6d..eca50f67d1 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f60ccebd0d50ac900a56e26d84becd4a7713babff2ca6ea5f1678b8f65b0be47 -size 17981 +oid sha256:092e27e97d83615745ed1ae26f2f5e862633e4a3c223b0b34856137d05456575 +size 18061 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png index d7226a1993..4540a5267e 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bf33b87c0ff38ec4b3d04aa24439e43710ca73c683e0baf407d82c77927b89e -size 18591 +oid sha256:75ed59fab9696a07e066ce4fb37700e09d74c1cdd5812a043babe5448534c4f5 +size 18797 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png index 1452785e86..3a394b29bc 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1821dd8fd06789ff6968a6bfe7bf98f3959a85fd1c8844382fc96a5eff8edfab -size 10125 +oid sha256:c66b33a6f652e04d7d2c9b1cb9cdfd88b3c4641b6de4522c949d4fd62f4b0c3e +size 10151 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png new file mode 100644 index 0000000000..ed6121de5b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cdee621ce660f8d47f6296b65c5ff81a3aa304189515c259d1d8d308cdf25c2 +size 140707 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png new file mode 100644 index 0000000000..594da6f63a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb5e3e0c7a8f897ac7714494e23cc490017ae1d12899ee1be89afd957410093 +size 101142 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png new file mode 100644 index 0000000000..a087a2c6ee --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d40cfdb69ef7ae194635940c4c05822bc144edf0401d4c42da39fe2ed986b66e +size 120613 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png index 2e94f15de9..fc2da95fe5 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:994cd11206f74a5b00a2c04bb6f4988aba173ee108cbe79d8a33e95111dc947b -size 25546 +oid sha256:dbfe3a50eb5727f069056e81037e33c4f2c68c445d17230d45aa71f2eaaadb68 +size 25572 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png index e989e20b27..c4dc3cd8ef 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:651360d30281afea675f5630e374899d17d3da14053cd8029fe7ca3049a7839f -size 31025 +oid sha256:18581a89cfe2bb56b55a42faab12bc89c26043cb60a6b51c2031a33cabb7eb98 +size 31044 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png new file mode 100644 index 0000000000..a878cee0f7 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73d23c270d0a53681997832eafd973c8015d5aa7cc3db7e6b27c892a06a3fe12 +size 24965 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png index 4f56882903..42733aa510 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdc6387eb49c9b64c2706bfab8ce4682f7e40f7e220f19d1fc83e88948c5b842 -size 129055 +oid sha256:d6e59633bb5ee32b8566c37db36756d507851871d3adfd30688b850cf415ebc3 +size 129061 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png index c0ba9f64b8..9cfbabc050 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ee03afd20d1085488a7b7cd02e8066086d6cb5c95d522cc1a5d00a79ecc5bd3 -size 34138 +oid sha256:4115a649f943acb3fc8745b29fc376adb8d3e29256bfcfe791c7bf109e9a5462 +size 34162 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png index ec4e8e9ba3..e99b9c0ed6 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c73ea2e71afe4d841b31cce044dcb370df2cd3852167106471e135b96b3a39d -size 80543 +oid sha256:b0ae9f8817078e1d15d55efb18b72abfc95e662bae82a290a8f1449e85bc8fb4 +size 80876 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png index e233584161..055befbd0f 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c9e9810799b4690ee4ed31d4ee35b5f410a8b0976d5c5aaa5c6282e5a7c6497 -size 34968 +oid sha256:8a87943f79a7eb95b66ab3a22b14413ba93f86168ac3e72223a499b2cab5593b +size 34997 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png index ad5934ff1f..60bd710a45 100644 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a82831dd932dbd2712e8cb4b60f57b69846614b0de564e2cac1351a66a87211c -size 60450 +oid sha256:afc288161291c67f074757ebc8a153d9c27ef3922d10ba65add15be68a146768 +size 60468 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png index a4aaeeaa7f..4a083c889f 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:368b81b7ad7b33b3a3aef2ac03108788e25a3158969d60bed62ff0b555ac5b40 -size 101332 +oid sha256:e095f06416640128f704ab5dbb377982e37ced3a3729a91c25ab0bab77203649 +size 101346 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png index d70436e0b9..699571ad26 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de15d7eb940b4a92179ce81da2685b7adc94fbd3aef6371be8bc105d067df80d -size 120790 +oid sha256:762896ba2d913778aeace81bb907fa1bca35b27587751aa17c15d4540e830f9c +size 120791 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png new file mode 100644 index 0000000000..43bb575b16 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8cb5e7f07920fd993eb1db8c2dff44a5439c57ebb03632d4300308f9e5c9c545 +size 36138 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png new file mode 100644 index 0000000000..b8db6a1472 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9a08617f4acf70b76d3a9fabe6f00f2f1a322e99065f527b351f5411280ea8c +size 36088 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png index 2a4d8df806..d2759bf941 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e99be63b211990d91cca0ec0eb3c9126fe43e4897025c983ee9bc8091c8bb1c5 -size 37267 +oid sha256:1aabfcb969386e07cd0dd809e2f2650f139e767bb87f619369571821c12b5924 +size 37377 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png new file mode 100644 index 0000000000..3d4826c3f0 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:02bf63222918c69a57852c4b2a57f3927059d76df6c53ae7e94fddd4c7efafd5 +size 32278 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png new file mode 100644 index 0000000000..a84b4a94c2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce018e0b0c9024183ba02b6c88983a9ee6da378d70039fca9352574bd268de40 +size 39422 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png new file mode 100644 index 0000000000..72a80b2398 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb31f17474a381a4abfc412289061c723bf0c63c71b6f48402921be1e249a930 +size 38232 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png new file mode 100644 index 0000000000..996d3191e6 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5d69f07b2d0d27c17def6287e607feb88f7f266636e41b821a354a0d312a505 +size 35979 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png new file mode 100644 index 0000000000..e67728e09f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef833d3a35bd1864eac795e9cefe41105138f9f71259885e62eacedaddbfbce7 +size 3432 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png index 25d7b9fa6f..d8b52ec3c2 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:430072d31620d1c647716baa00b68957e11bca9040ce1277557fc325628a8d46 -size 3640 +oid sha256:666b97df810f96cf58b19653ade33eeeb918caa496e5f87debbdc0577b912a9a +size 3731 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png new file mode 100644 index 0000000000..c2c4e0810e --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f3721d78f8212d61c4bbe4954221213b1e21e9f1819971db2631e64c113abc5 +size 3058 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png index 13b90c52c0..84cc99b3b3 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:771fe010b8560270b2eb4f90e3045967d582060c11f1a282a9ce51107fcf8b25 -size 4082 +oid sha256:c3f881445abe8c8d3533b3fcf54056aa4afb793b3b90332d17bcebf191af4599 +size 4027 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png index c372ab1192..181b578482 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1f693ad1080bbd3b8ff8a2bd08d6637805f6a1ff4df84574a64d932a5256a4b6 -size 4130 +oid sha256:118a71ccb255309a2520e65b797e66260e88a58bbcf0149092632ba889297967 +size 4098 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png index 3413fd9df8..192df3ab88 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56c7660a4b723b26d2c2233774ef9f4c6808e9569388ac135ad64178f8ede54f -size 6880 +oid sha256:50d975752ec0a8c9b4c2426b83402d6878a95be15a799f82300bd29a9ebc5167 +size 6923 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png index 1c9edeab2b..dae7dd64c6 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:365c25776505a33322d29e90ae79e4a8585214b499c431cda801091c5e82e5ac -size 3976 +oid sha256:553976191265286f5a71bfe61866a64e6d5f1f0afed8041613db525daf966a6b +size 3980 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png index b474dcd218..0264c56424 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eed8e7879bfc98eec4508f77abd4ad14c658f4084f5aff618557433110d27205 -size 4194 +oid sha256:c641b164872d6fdd56bfd0f36969cc881f237ac63d1223044c58b26502e9245e +size 4223 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png index 1b59247825..6d6ca6e816 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b4d25ccc6cfc71d809b96256519c019638445f6739d56fe99daed1b96a8630db -size 3113 +oid sha256:9492c12cdd73902786481b91041d25409125aedd9a09cbdd82d0163736a7e9c7 +size 3165 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png index bdc0513914..c552952d71 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98111f6e7f200448f64361754c307ade61d932fe96a18d673460515a9c3d10c9 -size 7515 +oid sha256:0339361bb7dbfa7fee8ba722554327fbbd327e41d3a92198cb02d50409631298 +size 7553 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png index 2a69febdfa..05a3701728 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa36139859cb52f90ef4a82c6f283e3c0cfaeca8d63accc4ff1ed62af5030e23 -size 8359 +oid sha256:be32fcdb528804acb3a486873d2cabdd28171f96a21068af70be1223a32f4d28 +size 8461 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png index 4484ca07e1..0d6ef1f0f6 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9846de81d881814f86562b80f799ffdef491105343e0d1fdbaf5798eff31e5c9 -size 8358 +oid sha256:065dc953193b989c6fef22e79c98482b79f8d9af3d816f303ac5e23ed1c0ff25 +size 8463 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png index 416dea5e52..d37c9273a0 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31148c4ba2502b60cdec70e98af1ce0e54502b87e6e684de820d6dbc04a9f88e -size 7673 +oid sha256:c4edb69ec532277ce8056ce44f1f6800e728bf1b6fba418b23c566b4134e297e +size 7731 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png index c0c454bae3..cca3ceaf8a 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83d4cdea63a34e65451f1fb0f50a5b094edae49a38e883e476d5b9b5fcaffea2 -size 7666 +oid sha256:52ddb7a70cac86cbdbfab171de0d332733b72ff9a8844ecbc25bfabe4ae5dab4 +size 7725 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png index d5cb0f1d0e..4615b9a0c0 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f39004a8ee7f375b849190167a13c1bad64d681dc89a4d9ae97739bdd3c38a3a -size 7877 +oid sha256:301692b58dddcfac3bee52f6a57e65481c20b296b792fbfe6bbd1b4efeb03fb0 +size 7974 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png index e81e9dc7a2..dc95ed93b8 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5ed7e7cc597405b8c401401dfd664991763997a21dc773cc31816713a786cf5 -size 7939 +oid sha256:67539bde2e6455d14aeb98835be42d2fd2af3c003a0eb770dbf69ac7d6a29771 +size 8042 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png index e923c91b2f..0786bfe43e 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ee2c2e13083e5d4d8c959473d9871da7c5112b3888e3ec0cdb7329f4a2eb10d -size 7947 +oid sha256:90d2a27d78dd648e2c387848d79aa289c5ad15232a598a980819bc4302919e6c +size 8052 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png index 6675611746..77967ada36 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c27bb4562efc780d50b20619cedc3707fe722a11f5800531acc08d953f77b235 -size 6386 +oid sha256:243972c80df061fef5d04a50073966b718f3fa9cb00d27815455e0a78c89d987 +size 6489 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png index 0d26ded113..3fe3fc416b 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:356c0c40794d03c470d2f14e964f763d9f5e46b0278af55f1822a1abafb66a35 -size 8355 +oid sha256:32908a4dac1d9cd83ea586879b5812dd7eed8cdc6f470f6a043b9042835f24db +size 8462 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png index 694954e810..54eb29de34 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f013cb52baab8551ae6123a860bc2a0195bb2bb4120b8ae2bc7820f9e326dc5c -size 8370 +oid sha256:f306a923f27ebceeefa29226ce24d81e0c12e6ca63b4f8f8225c3de3fda2cd3e +size 8468 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png index 6892732fa9..6a648bcb55 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e68f1349020cc274ba6810f1407847318cae83204b8141eeed21108d11a2508 -size 7512 +oid sha256:44643121343000108e1b56beb8a7147dac4af66a23551853c5c4cf6258e17e06 +size 7550 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png index ac4c45919b..5c92293e86 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c03e4451163d5c2a7e9b1d395f416a7b8158033cbcfd9192156317d3b924b262 -size 9502 +oid sha256:669c472bf70fb009aedd44e20e07f2b36bc3c533aea3cdd8d8efae93ffef6eb3 +size 9504 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png index bf5040f48c..ebc3598cb8 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82e18a35416c33fa199af5d3e966a5f8fb9d0abbac11fea72ad593baa739bb71 -size 11652 +oid sha256:af7dcdfae006d3737b2b7e3441b9167d2cf2f6359cd79d74f1809441b5765380 +size 11655 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png index 66aff9fb68..5a783f0be7 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6debf7e26efd54c5bf28329a73a8f686d4abb20d1bba78a635cc3b11e5b7743b -size 9693 +oid sha256:4b8524568f2d72307ff224a3479b4bf4ce1ad1a4929d4087579e29b87d64d133 +size 9703 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png index dd26beb140..30183bbe88 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ae4eb6a8b9b8b864c6701871b06f0ed910fc993141c21d82e3a3d206e9752b4 -size 10039 +oid sha256:1de96b5b6103793ee5b04e308aaaa7d306ba2ddb14f36020d8948079a8fd4d8e +size 10042 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png index 9d0cdc8ac6..d98671718b 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:258a14fde3f51b1d59398b10ee78c02d32ec52e2253c8b91c2896f65a7b8e355 -size 36330 +oid sha256:83fcfe62fc4bacd5bd6e6196f38a3fbd9b55e365ab9d56ed67514b03c4c22e8b +size 36308 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png index e9c283be4d..a0a1af6c14 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6221858c3cc24f669183e1b384b67c90ed317a28bcba066723977d128ff79958 -size 388719 +oid sha256:2ee5fc13b7e5ba9351176055b7530f56e7870e6f41bf508b33ac6621b943b47d +size 388855 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png index 2d3a785ae6..372a6df521 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:765dfe0a149a2f8edb8e2dda145d42a4153c61f0636f34e5d7c7566386b1f972 -size 16044 +oid sha256:982dee31eebd541e013eeb7419b68e8aa57da6a6c0328b7e844b407641f911aa +size 16043 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png index b25f8a2115..968160a212 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:679c5316c1779cca525b130f6ad97ca0dd2006f12b7d5a73c226db71379931db +oid sha256:2c5187ee66519fa61b162567fb2092a7d042b43df94a1291ad4e8ff3560fcdb0 size 16027 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png index 78df0c52c9..a4e24e232c 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ad28c45ad37ca9817b277f78287fd37ca8b2dca61896c2059bff92f77216450 -size 17812 +oid sha256:c974cd3104b4b2ccd4ffc8197b25f26e14852922c29589d5d82fcbb5c7536317 +size 17807 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png index 6363bf8a81..ca0ccb985c 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:122fdd75c122593e0bdc84c6f54193408769831ced932b47640f1b5adc0aac28 -size 16634 +oid sha256:46b307aed2c00a89bfe478edc02f9992294226ce668b00da004e77ab3fd3d3d1 +size 16630 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png new file mode 100644 index 0000000000..23fb1be543 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff +size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png new file mode 100644 index 0000000000..ca8a617607 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03f22a166e20bd200f8ae58067c3879e612da463749caf6c97cbbcc5af24bb6d +size 2760 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png new file mode 100644 index 0000000000..23fb1be543 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff +size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png new file mode 100644 index 0000000000..c547da862f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7cade8d4ac33fb838549cd92049397c4ec61357dacf63a3f333faacfdfb7d5b +size 2413 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png new file mode 100644 index 0000000000..6d946ffb39 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d9e78c0783d9949fb0313a728701b274d28f6cd18d0c97a79faac685fe63cad +size 2969 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png new file mode 100644 index 0000000000..9357f712ee --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9abb3d93cc2888794a375c0afa63c4a7c2be25fc6207726714c4ecfe4f850b52 +size 2922 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png new file mode 100644 index 0000000000..4ef6060c15 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:483c651ef70c62fb0ef7fd4001f888b3c1e1c3f0a6ffeb340f041623138a708a +size 11769 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png new file mode 100644 index 0000000000..0caf40524c --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af786b3b910edf96d6779b7db4d2721b333116c837ae70f32c8897143daaba27 +size 11256 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png index 9445dde23a..3e97f38b50 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31a9328a598f5d57513e2db6fed000b3f0c17ca3d74d40b8492b6000f1c09e61 -size 5152 +oid sha256:577c0bd61c024db0613fd83947d1f8d6d5a27408c92fdac3545b34d0314fd4fc +size 5355 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png index e2e03f80f7..094cc8c98f 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e764121c3c36d255fc7bc7634247abb102d9eafbcc0c489a9649a10571c9b04 -size 5258 +oid sha256:574531ba486693db9986f7dc47878c1902a4bddb5c388d09d777de626bf73fae +size 5455 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png index 487955fe1a..22140adf00 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ead5d7e70122126fc8a0dc95e665e679b9a729666190961755223bd342a63e22 -size 8227 +oid sha256:a67521fe9222e2e7d35dfe04b83bf9a01ab74699f7c3b7449cd655ed32b6d1a9 +size 8307 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png index 9644b064c2..91854e8d30 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d7284385bab1ee022c03f9dc0ebfa8773d97d6d1e4395009d226882daea414d -size 3537 +oid sha256:2a4550a7c43a9d557fccd1e52711dde5280540e763161c9170cc410a344aebd3 +size 3637 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png index e0c6267f4e..c24e734f41 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:62dadb3e18c3cd38b581c306f40a0c0cbe77cb3c3fc75eb548f16ccfd558826d -size 7993 +oid sha256:027f4e2fca2d6771090168b795f8b86b28df210063a80207357fbf0ef9975262 +size 7963 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png index 7f95c9d9d2..3510536b08 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7ef7e86bb82b13a020523e83382c97cdcdc8561b64f0d9b58ed162fcdd53b8b5 -size 3541 +oid sha256:5c86b6f27533be773396bc858780b37617b22293a0e7c63984d5b66bd443f8d4 +size 3640 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png index 053ebaaf96..1afac80daa 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9164d940ff9812d2475119bd4f42a40fbdd0464a87b1f9dae35b143f2104bf92 -size 5113 +oid sha256:94af79354cde36f52647b5eba57ae6ad4845eed2d50d861cd2c874a1e9bb8a95 +size 5296 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png index 7186ff6d9a..818f757882 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:027b3cffaff205b188bcdf850050e51f64a53750a7469b4e4a119117cf39efd7 -size 5187 +oid sha256:cdff10b00e080b78504ba2f5da612a5d24704ad916d84e9fc397e4ec647696fa +size 5379 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png index d230e6c2f4..b121db208b 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:556a9249183fda3958d5ad1fd0f5e08a5e0614d45b32edb28781b216c70576f2 -size 5187 +oid sha256:d4bf96dd0da227b95d7f7b00d7eae32d96d6decc540fdb819394c6a2d5350801 +size 5379 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png index 429201e972..41d1c254cb 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:edb11bcbfc2b9864709b2a6f61d384e9d26980144d426342b519f63471782d03 -size 5193 +oid sha256:0c8a76965949ebd9202cec029c2de4d69722919d313ffc6f415e22f183821f2a +size 5385 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png index 9258c23032..1e37f62eac 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c20c0655d47652c9c31fc037ba47cef5263500ecf434e90633bf1f5631e9b7f -size 5234 +oid sha256:a2bc4ffae2dc84b4c9b5481a66d200cabe107532f809ce1c95bd43b4800432dd +size 5427 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png index 5424e9c3e5..b565bcc783 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:496af2a9c936e62c4860dbe7b05dce54ceb7301042fc5d646a75bc006040a627 -size 5209 +oid sha256:458dd91ce0131a5e29559588ca1bae96979527e360ca44cccff0a0d78a3aaf48 +size 5406 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png index ea535ea584..50ab631529 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43b127e68744fdf5c6d1fa491a344d29e1786277194a09211c9d26c1f481d908 -size 5248 +oid sha256:78a45c5874ffb1b3493ff50b02ff9f6d9c96346d43cfc0f87e36d12cd501faa1 +size 5451 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png index 09ac2ae7f7..2a96760733 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ceb0ba8bac6260d46a1db3fb454a8cff06ff665906d30ee0a03c426f5de834f -size 5239 +oid sha256:22e7fabda82eadfdb9536951572853fabbca191a5298f069bf75ca19a92ae63f +size 5446 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png index d4ac84a043..190c3cc6db 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77784f64e047c42d040c3eaaebce94022c5c355a5813e741ee624c5f1c8b3771 -size 5180 +oid sha256:8f33a162a348a629fd3c435a1d701bacebc6fe3956fd6350645737fca5568fe3 +size 5372 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png index 466fde1919..adafa94526 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1db4db37f9540969f1f4bcbb616e230a291c2f92cbca33d608716cefad18af3b -size 9592 +oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png index 8c0db66c63..70b3ff2879 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d8d5517b3024e5b26f580b328335b8179275e45276b996aa9fde3ed1e2914017 -size 9588 +oid sha256:cef39ecbe7030a44cb7322d1e24c41919024dc7bd1f37b775333e0689069e360 +size 9890 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png index 101c0a035f..5dc7545f0e 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ce216955ec8cb33a449c789362c5702ac280b0c1d83fdca4b9b18ee1d4c8aa3 -size 9598 +oid sha256:de6562593cf7497d8163a4cb349d9e8d521d18e0159b42bcf879de444989ebf6 +size 9902 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png index 466fde1919..adafa94526 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1db4db37f9540969f1f4bcbb616e230a291c2f92cbca33d608716cefad18af3b -size 9592 +oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png index 466fde1919..adafa94526 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1db4db37f9540969f1f4bcbb616e230a291c2f92cbca33d608716cefad18af3b -size 9592 +oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png index 466fde1919..adafa94526 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1db4db37f9540969f1f4bcbb616e230a291c2f92cbca33d608716cefad18af3b -size 9592 +oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png index 466fde1919..adafa94526 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1db4db37f9540969f1f4bcbb616e230a291c2f92cbca33d608716cefad18af3b -size 9592 +oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png index cf82e1ca73..a913a9816b 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:011f54cd0fcbccc4a98db250e45eb17fecb582cd9bc0531e02cf686c88a09626 -size 9587 +oid sha256:9f9f25a409bfa9fb6280251e04efc71586ca9de68124b01971a0c82bd8c6e876 +size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png index 25e0241cab..e764bc7605 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f9e5665066db69752089a3a771d2762cb8f7bb245de6b61c5156df08d9618a0 -size 9582 +oid sha256:9607a953a09c7e54c92885551e02b22a2c83d349b137ccba7c35f71185716edc +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png index 344360ecae..9c74063882 100644 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0df0d6cb547c63d7d563e49a35baca3c230faae47851553921f346f38e174e7b -size 8024 +oid sha256:3355dca71ecdad22a6c4529d2f7359981647ed0a24fba8fb3e90421f0846f675 +size 8366 From 6a7838c0195e2ac3f5c37575598866045fbe35f8 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 10:08:11 +0900 Subject: [PATCH 1049/1182] fix: Remove broken TestScene --- .../engine/Stride.Graphics.Tests/TestScene.cs | 111 ------------------ 1 file changed, 111 deletions(-) delete mode 100644 sources/engine/Stride.Graphics.Tests/TestScene.cs diff --git a/sources/engine/Stride.Graphics.Tests/TestScene.cs b/sources/engine/Stride.Graphics.Tests/TestScene.cs deleted file mode 100644 index 6db54a8da1..0000000000 --- a/sources/engine/Stride.Graphics.Tests/TestScene.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Threading.Tasks; - -using Xunit; -using Stride.Core; -using Stride.Core.Mathematics; -using Stride.Rendering.Materials.ComputeColors; -using Stride.Engine; -using Stride.Rendering; -using Stride.Rendering.Compositing; -using Stride.Rendering.Materials; -using Stride.Rendering.ProceduralModels; -using Stride.Games; - -namespace Stride.Graphics.Tests -{ - public class TestScene : GraphicTestGameBase - { - private Entity cubeEntity; - - protected override async Task LoadContent() - { - await base.LoadContent(); - - Window.AllowUserResizing = true; - - // Instantiate a scene with a single entity and model component - var scene = new Scene(); - - // Create a cube entity - cubeEntity = new Entity(); - - // Create a procedural model with a diffuse material - var model = new Model(); - var material = Material.New(GraphicsDevice, new MaterialDescriptor - { - Attributes = - { - Diffuse = new MaterialDiffuseMapFeature(new ComputeColor(Color.White)), - DiffuseModel = new MaterialDiffuseLambertModelFeature() - } - }); - model.Materials.Add(material); - cubeEntity.Add(new ModelComponent(model)); - - var modelDescriptor = new ProceduralModelDescriptor(new CubeProceduralModel()); - modelDescriptor.GenerateModel(Services, model); - - // Add the cube to the scene - scene.Entities.Add(cubeEntity); - - // Use this graphics compositor - SceneSystem.GraphicsCompositor = GraphicsCompositorHelper.CreateDefault(false, graphicsProfile: GraphicsProfile.Level_9_1); - - // Create a camera entity and add it to the scene - var cameraEntity = new Entity { new CameraComponent { Slot = Services.GetSafeServiceAs().GraphicsCompositor.Cameras[0].ToSlotId() } }; - cameraEntity.Transform.Position = new Vector3(0, 0, 5); - scene.Entities.Add(cameraEntity); - - // Create a light - var lightEntity = new Entity() - { - new LightComponent() - }; - - lightEntity.Transform.Position = new Vector3(0, 0, 1); - lightEntity.Transform.Rotation = Quaternion.RotationY(MathUtil.DegreesToRadians(45)); - scene.Entities.Add(lightEntity); - - // Create a scene instance - SceneSystem.SceneInstance = new SceneInstance(Services, scene); - } - - protected override void Draw(GameTime gameTime) - { - base.Draw(gameTime); - - var time = (float)gameTime.Total.TotalSeconds; - cubeEntity.Transform.Rotation = Quaternion.RotationY(time) * Quaternion.RotationX(time * 0.5f); - - //if (!ScreenShotAutomationEnabled) - // DrawCustomEffect(); - } - - //private void DrawCustomEffect() - //{ - // GraphicsDevice.Clear(GraphicsDevice.BackBuffer, Color.Black); - // GraphicsDevice.Clear(GraphicsDevice.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer); - // GraphicsDevice.SetDepthAndRenderTarget(GraphicsDevice.DepthStencilBuffer, GraphicsDevice.BackBuffer); - - // effectParameters.Set(MyCustomShaderKeys.ColorFactor2, (Vector4)Color.Red); - // effectParameters.Set(CustomShaderKeys.SwitchEffectLevel, switchEffectLevel); - // effectParameters.Set(TexturingKeys.Texture0, UVTexture); - // // TODO: Add switch Effect to test and capture frames - // //switchEffectLevel++; - // dynamicEffectCompiler.Update(effectInstance, null); - - // GraphicsDevice.DrawQuad(effectInstance.Effect, effectParameters); - //} - - /// - /// Run the test - /// - [Fact] - public void RunSceneTests() - { - RunGameTest(new TestScene()); - } - } -} From 8c1d299eb5c808c7f05139c9bf0008eb7c6100c9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 09:13:16 +0900 Subject: [PATCH 1050/1182] ci: add Stride.Dependencies.SpirvCross build workflow and NuGet package --- .github/workflows/dep-spirv-cross.yml | 122 ++++++++++++++++++ .../Stride.Dependencies.SpirvCross.nuspec | 18 +++ sources/Directory.Packages.props | 2 + .../Stride.Shaders.Compilers.csproj | 5 + 4 files changed, 147 insertions(+) create mode 100644 .github/workflows/dep-spirv-cross.yml create mode 100644 build/deps/spirv-cross/Stride.Dependencies.SpirvCross.nuspec diff --git a/.github/workflows/dep-spirv-cross.yml b/.github/workflows/dep-spirv-cross.yml new file mode 100644 index 0000000000..c65ac4e4a1 --- /dev/null +++ b/.github/workflows/dep-spirv-cross.yml @@ -0,0 +1,122 @@ +name: "Dep: Build & Deploy SPIRV-Cross" + +on: + workflow_dispatch: + inputs: + version: + description: NuGet package version (leave empty for date-based) + required: false + branch: + description: SPIRV-Cross branch to build + default: hlsl_tessel_shader + required: false + +jobs: + build-windows: + name: Build SPIRV-Cross (Windows x64) + runs-on: windows-2025-vs2026 + steps: + - name: Checkout Stride + uses: actions/checkout@v4 + + - name: Checkout SPIRV-Cross + uses: actions/checkout@v4 + with: + repository: stride3d/SPIRV-Cross + ref: ${{ github.event.inputs.branch || 'hlsl_tessel_shader' }} + path: spirv-cross-src + + - name: Build + shell: pwsh + run: | + cmake -S spirv-cross-src -B spirv-cross-build -Thost=x64 ` + -DSPIRV_CROSS_SHARED=ON ` + -DSPIRV_CROSS_CLI=OFF ` + -DSPIRV_CROSS_ENABLE_TESTS=OFF + cmake --build spirv-cross-build --config Release --target spirv-cross-c-shared + + - name: Upload build output + uses: actions/upload-artifact@v4 + with: + name: spirv-cross-win-x64 + path: spirv-cross-build/Release/spirv-cross-c-shared.dll + + pack: + name: Pack & Publish NuGet + needs: [build-windows] + runs-on: windows-2025-vs2026 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Checkout SPIRV-Cross (for commit hash) + uses: actions/checkout@v4 + with: + repository: stride3d/SPIRV-Cross + ref: ${{ github.event.inputs.branch || 'hlsl_tessel_shader' }} + path: spirv-cross-src + fetch-depth: 1 + + - name: Download Windows artifact + uses: actions/download-artifact@v4 + with: + name: spirv-cross-win-x64 + path: artifacts/win-x64 + + - name: Prepare package contents + shell: pwsh + run: | + $destDir = "build/deps/spirv-cross" + New-Item -Path "$destDir/win-x64" -ItemType Directory -Force | Out-Null + # Silk.NET expects the DLL named "spirv-cross" + Copy-Item artifacts/win-x64/spirv-cross-c-shared.dll "$destDir/win-x64/spirv-cross.dll" + + - name: Pack NuGet + shell: pwsh + run: | + $commitHash = git -C spirv-cross-src rev-parse --short HEAD + $version = "${{ github.event.inputs.version }}" + if (-not $version) { $version = (Get-Date -Format "yyyy.M.d") } + nuget pack build/deps/spirv-cross/Stride.Dependencies.SpirvCross.nuspec ` + -Version $version ` + -Properties "commit=$commitHash" ` + -OutputDirectory nupkg + echo "PACKAGE_VERSION=$version" >> $env:GITHUB_ENV + + - name: Upload package artifact + uses: actions/upload-artifact@v4 + with: + name: Stride.Dependencies.SpirvCross.nupkg + path: nupkg/*.nupkg + + publish: + name: Sign & Publish to NuGet.org + needs: pack + runs-on: windows-2025-vs2026 + environment: production + steps: + - name: Install signing tool + run: dotnet tool install sign --tool-path ./sign-tool --version 0.9.0-beta.23127.3 + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: Stride.Dependencies.SpirvCross.nupkg + + - name: Sign NuGet package + shell: pwsh + run: | + ./sign-tool/sign code azure-key-vault *.nupkg ` + --description "Stride" ` + --description-url "https://stride3d.net" ` + --publisher-name "Stride" ` + --azure-key-vault-tenant-id "${{ secrets.STRIDE_SIGN_TENANT_ID }}" ` + --azure-key-vault-client-id "${{ secrets.STRIDE_SIGN_CLIENT_ID }}" ` + --azure-key-vault-client-secret "${{ secrets.STRIDE_SIGN_CLIENT_SECRET }}" ` + --azure-key-vault-certificate "${{ secrets.STRIDE_SIGN_KEYVAULT_CERTIFICATE }}" ` + --azure-key-vault-url "https://${{ secrets.STRIDE_SIGN_KEYVAULT_NAME }}.vault.azure.net/" ` + -v Information + + - name: Publish + run: | + dotnet nuget push *.nupkg --api-key "${{ secrets.STRIDE_NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/build/deps/spirv-cross/Stride.Dependencies.SpirvCross.nuspec b/build/deps/spirv-cross/Stride.Dependencies.SpirvCross.nuspec new file mode 100644 index 0000000000..bce2ba9600 --- /dev/null +++ b/build/deps/spirv-cross/Stride.Dependencies.SpirvCross.nuspec @@ -0,0 +1,18 @@ + + + + Stride.Dependencies.SpirvCross + $version$ + Stride Contributors + SPIRV-Cross shared library for Stride SPIR-V to HLSL/GLSL translation. Built from stride3d/SPIRV-Cross commit $commit$. + Apache-2.0 + + + + + + + diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index bc59d20925..ed16f80e86 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -35,6 +35,7 @@ + @@ -101,6 +102,7 @@ + diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 4a63b3df46..64ad0ecb0b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -24,7 +24,12 @@ + + + From df26fdbfc0ab517a43592ef6c8bd3d9c03c5bf6a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 10:26:26 +0900 Subject: [PATCH 1051/1182] tools: show Stride root in CompareGold header, make header/panel sticky --- build/tools/CompareGold/Program.cs | 4 ++++ build/tools/CompareGold/wwwroot/app.js | 7 +++++++ build/tools/CompareGold/wwwroot/index.html | 1 + build/tools/CompareGold/wwwroot/style.css | 5 +++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/build/tools/CompareGold/Program.cs b/build/tools/CompareGold/Program.cs index 163e51d78a..d7577a863e 100644 --- a/build/tools/CompareGold/Program.cs +++ b/build/tools/CompareGold/Program.cs @@ -65,6 +65,10 @@ catch { } Console.WriteLine(ghAvailable ? "GitHub CLI: authenticated" : $"GitHub CLI: {ghError}"); +// === Info API === + +app.MapGet("/api/info", () => new { StrideRoot = strideRoot }); + // === Gold API === app.MapGet("/api/suites", () => diff --git a/build/tools/CompareGold/wwwroot/app.js b/build/tools/CompareGold/wwwroot/app.js index 08a8e93535..842c1a1f68 100644 --- a/build/tools/CompareGold/wwwroot/app.js +++ b/build/tools/CompareGold/wwwroot/app.js @@ -14,6 +14,13 @@ let cellStats = {}; // {`${sourceId}:${suite}:${name}`: stats} // === Init === async function init() { + // Show Stride root path + try { + const infoRes = await fetch('/api/info'); + const info = await infoRes.json(); + document.getElementById('strideRoot').textContent = info.strideRoot; + } catch {} + const res = await fetch('/api/suites'); allSuites = await res.json(); diff --git a/build/tools/CompareGold/wwwroot/index.html b/build/tools/CompareGold/wwwroot/index.html index ff921aac69..683c9f4be1 100644 --- a/build/tools/CompareGold/wwwroot/index.html +++ b/build/tools/CompareGold/wwwroot/index.html @@ -9,6 +9,7 @@

CompareGold

Stride Image Comparison Tool +
diff --git a/build/tools/CompareGold/wwwroot/style.css b/build/tools/CompareGold/wwwroot/style.css index cbf92f4224..c5dd78c01a 100644 --- a/build/tools/CompareGold/wwwroot/style.css +++ b/build/tools/CompareGold/wwwroot/style.css @@ -1,11 +1,12 @@ * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; background: #1a1a2e; color: #e0e0e0; font-size: 13px; } -header { background: #16213e; padding: 12px 20px; display: flex; align-items: center; gap: 16px; border-bottom: 1px solid #333; } +header { background: #16213e; padding: 12px 20px; display: flex; align-items: center; gap: 16px; border-bottom: 1px solid #333; position: sticky; top: 0; z-index: 100; } header h1 { font-size: 18px; color: #4fc3f7; } header .subtitle { color: #666; font-size: 12px; } +header .stride-root { margin-left: auto; font-size: 12px; color: #4fc3f7; background: #1a2a4a; padding: 4px 12px; border-radius: 4px; font-family: monospace; } -.panel { padding: 12px 20px; background: #1a1a2e; border-bottom: 1px solid #333; } +.panel { padding: 12px 20px; background: #1a1a2e; border-bottom: 1px solid #333; position: sticky; top: 48px; z-index: 99; } .panel-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 8px; } .panel-row:last-child { margin-bottom: 0; } From cf9456a04a82a867eae1e916da69875430c436fd Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 10:32:45 +0900 Subject: [PATCH 1052/1182] ci: split crash-dumps into separate artifact so test images have consistent paths --- .github/workflows/test-windows-game.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index 22cf837338..9847183663 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -194,7 +194,12 @@ jobs: uses: actions/upload-artifact@v4 with: name: test-artifacts-game-${{ matrix.graphics-api }} - path: | - tests/local/ - crash-dumps/ + path: tests/local/ + if-no-files-found: ignore + - name: Upload crash dumps + if: always() + uses: actions/upload-artifact@v4 + with: + name: crash-dumps-game-${{ matrix.graphics-api }} + path: crash-dumps/ if-no-files-found: ignore From ed7063a10767338db88b6b9235644936f83fd8a4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 11:49:23 +0900 Subject: [PATCH 1053/1182] fix: Updated bytecode (incl. fixed SamplerState for Vulkan) --- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 1466 ++++++++--------- ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 1464 ++++++++-------- .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 854 +++++----- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 1158 +++++++------ .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 1154 +++++++------ 5 files changed, 3043 insertions(+), 3053 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index ffa470a8d9..895262d66a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -21,758 +21,756 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, -0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, -105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, -0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, +4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, +121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, +0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, +0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, +70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, +112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, +115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, +69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, +51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, +32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, +102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, +32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, +115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, +95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, +116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, +111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, +104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, +101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, +116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, +97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, +99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, +103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, +46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, +32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, +47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, +32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, +101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, +115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, +0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, +47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, +111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, +116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, +32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, +115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, +122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, +53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, +116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, +73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, +80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, +59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, +76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, +69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, +97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, +82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, +114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, +108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, +116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, +10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, -46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, -95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, -38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, -80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, -105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, -73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, -101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, -103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, -32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, -117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, -115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, -102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, -101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, -99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, +46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, +32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, +100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, +46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, +105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, +32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, -32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, -97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, -100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, +32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, +101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, +101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, +108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, +48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, +115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, +82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, +13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, +114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, +32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, +115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, +102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, +71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, +32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, +40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, +47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, +108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, +98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, +56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, +32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, +41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, +115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, +113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, +48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, +32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, +101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, +103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, +41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, +114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, +116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, +108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, +32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, +52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, -101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, -115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, -101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, -122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, -101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, -47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, -79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, -78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, -32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, -69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, -67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, -32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, -10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, -111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, -105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, -111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, -102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, -117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, -77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, -105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, -125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, -70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, -112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, -115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, -69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, -111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, -116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, -50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, -101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, -42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, -32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, -56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, -101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, -116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, -97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, -111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, -97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, -108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, -32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, -105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, -49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, -101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, -40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, -83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, -32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, -13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, -55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, -32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, -48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, -117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, -111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, -32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, -52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, -51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, -101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, -32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, -111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, -40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, -108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, -102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, -13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, -32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, -77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, -32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, -32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, -58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, -104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, -120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, -99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, -45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, -45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, -32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, -111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, -97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, -40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, -101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, -59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, -7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, -7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, -0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, -84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, -0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, -0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, -114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, -4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, -83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, -101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, -49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, -108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, -0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, -0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, -0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, -97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, -6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, -67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, -95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, -0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, -0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, -0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, -6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, -83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, -4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, -6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, -116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, -6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, -95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, -0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, -0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, -6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, -0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, -105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, -0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, -114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, -100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, -0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, -5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, -0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, -0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, -0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, -0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, -0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, -0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, -0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, -0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, -0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, -4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, -0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, -0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, -2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, -0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, -3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, -0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, -0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, -0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, -4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, -4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, -4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, -0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, -0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, -0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, -0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, -0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, -0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, -0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, -0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, -0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, -0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, -0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, -0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, -0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, -0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, -0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, -0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, -0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, -0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, -0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, -0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, -0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, -0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, -6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, -6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, -5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, -0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, -0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, -0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, -0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, -0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, -0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, -0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, -0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, -0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, -4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, -4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, -0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, -4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, -0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, -5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, -0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, -2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, -0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, -5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, -0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, -0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, -0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, -0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, -0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, -0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, -0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, -0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, -0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, -0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, -0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, -0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, -0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, -0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, -0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, -5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, -2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, -0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, -0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, -0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, -0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, -0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, -0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, -3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, -0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, -0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, -4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, -3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, -1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, -0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, -97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, -0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, +101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, +109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, +79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, +100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, +97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, +32, 117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, +32, 102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, +114, 114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, +40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, +105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, +101, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, +32, 105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, +32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, +42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, +61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, +111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, +32, 97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, +110, 101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, +105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, +101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, +0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, +0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, +101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, +7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, +97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, +105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, +116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, +0, 0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, +7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, +101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, +95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, +111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, +121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, +101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, +4, 0, 242, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, +101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, +95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, +0, 0, 5, 0, 6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, +95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, +0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, +5, 0, 45, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, +5, 0, 46, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, +6, 0, 47, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, +0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, +101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, +101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, +0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, +0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, +100, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, +116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, +0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, +5, 0, 80, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, +110, 0, 6, 0, 6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, +100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, +103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, +0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, +0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, +104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, +0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, +0, 0, 0, 22, 5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, +0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, +5, 0, 73, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, +0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, +4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, +0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, +0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, +4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, +0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, +0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, +0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, +0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, +9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, +0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, +0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, +0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, +4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, +4, 0, 208, 0, 0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, +4, 0, 138, 0, 0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, +41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, +135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, +77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, +4, 0, 5, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, +4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, +4, 0, 37, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, +6, 0, 45, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, +4, 0, 48, 2, 0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, +4, 0, 138, 0, 0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, +7, 0, 80, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, +0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, +0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, +0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, +0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, +0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, +0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, +0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, +0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, +0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, +0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, +0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, +0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, +4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, +0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, +0, 0, 66, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, +0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, +0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, +6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, +0, 0, 227, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, +0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, +0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, +0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, +0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, +5, 0, 192, 0, 0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, +2, 0, 248, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, +0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, +0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, +2, 0, 173, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, +0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 182, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, +5, 0, 4, 0, 0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, +0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, +0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, +0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, +0, 0, 200, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, +0, 0, 250, 0, 4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, +0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 226, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, +0, 0, 248, 0, 2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, +5, 0, 5, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, +0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, +0, 0, 241, 1, 0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, +4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, +0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, +5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, +0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, +4, 0, 152, 1, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, +0, 0, 4, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, +0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, +6, 0, 5, 0, 0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, +0, 0, 8, 2, 0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, +0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, +0, 0, 197, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, +0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, +2, 0, 8, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, +0, 0, 29, 2, 0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, +0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, +0, 0, 254, 0, 2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, +4, 0, 42, 0, 0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, +3, 0, 55, 2, 0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, +0, 0, 61, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 65, 2, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, +0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, +5, 0, 3, 0, 0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, +0, 0, 62, 0, 3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, +4, 0, 30, 0, 0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, +5, 0, 74, 0, 0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, +0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, +0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, +1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 211, 212, 111, 4, 21, 128, 64, 218, 65, 228, 242, 134, 59, 18, 242, 244, 0, 20, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, +0, 109, 2, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, +0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, +0, 50, 2, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, +69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, +104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, +99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, +76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, +66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, +97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, +69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, +32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, +101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, +101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, +80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, +32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, +97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, +101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, +97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, +73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, +116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, +46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, +83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, +46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, +101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, +100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, +110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, +0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, +117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, +101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, +102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, +114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, +108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, +111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, +84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, +71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, +95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, +100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, +97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, +76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, +32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, +83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, +112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, +114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, +32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, +97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, +105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, +10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, +57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, -78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, -32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, -32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, -68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, -47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, -32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, -83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, -104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, -84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, -112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, -117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, -76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, -73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, -97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, +78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, +114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, +10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, +32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, +118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, +97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, +115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, -116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, -47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, -116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, -0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, +104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, +112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, +104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, +32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, +97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, +110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, +56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, +66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, +49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, +108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, +97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, +46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, +109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, +112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, +115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, +104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, +103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, +32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, +71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, +32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, +61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, +50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, +32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, +111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, +50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, +103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, +118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, +101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, +97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, +48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, +110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, +0, 152, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, -109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, -108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, -101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, -108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, -84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, -117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, -101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, -80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, -95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, -13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, -101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, -65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, -109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, -79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, -10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, -116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, -101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, -101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, -32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, -32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, -100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, -125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, -97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, -115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, -111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, -109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, -66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, -32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, -47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, -32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, -80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, -116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, -123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, -32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, -69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, -104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, -99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, -76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, -114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, -105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, -46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, -112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, -71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, -10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, -103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, -48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, -99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, -108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, -97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, -40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, -82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, -99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, -13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, -84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, -108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, -113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, -114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, -102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, -125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, -110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, -98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, -32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, -51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, -44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, -115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, -111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, -108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, -48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, -101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, -0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, -101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, -112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, -73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, -32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, -115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, -109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, -82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, -47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, -32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, -109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, -117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, -102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, -114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, -115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, -115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, -32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, -105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, -115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, -32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, -32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, -114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, -97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, -101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, -97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, -13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, -0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, -0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, -95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, -0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, -114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, -105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, -95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, -0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, -111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, -0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, -0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, -62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, -116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, -97, 116, 95, 49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, -95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, -95, 49, 0, 0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, -0, 242, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, -95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, -102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, -0, 5, 0, 6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, -80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, -0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, -0, 45, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, -0, 46, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, -0, 47, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, -0, 6, 0, 6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, -95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, -62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, -0, 5, 0, 6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, -95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, -0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, -0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, -95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, -0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, -0, 80, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -0, 6, 0, 6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, -100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, -0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, -83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, -0, 0, 22, 5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, -0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, -0, 0, 0, 0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 48, 0, 0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, -0, 73, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, -0, 3, 0, 0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, -0, 77, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, -0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, -0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, -0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, -0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, -0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, -0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, -0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, -0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, -0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, -0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, -0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, -0, 5, 0, 0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, -0, 208, 0, 0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, -63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, -63, 43, 0, 4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, -59, 43, 0, 4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, -0, 5, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, -0, 5, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, -0, 37, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, -0, 45, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, -0, 48, 2, 0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, -0, 80, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, -0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, -0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, -0, 6, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, -0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, -0, 3, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, -0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, -0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, -0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, -0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, -0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, -0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, -0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, -0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, -0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, -0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, -0, 66, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, -0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, -0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, -0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, -0, 227, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, -0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, -0, 80, 0, 6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, -0, 80, 0, 6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, -0, 81, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, -0, 192, 0, 0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, -0, 248, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, -0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, -0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, -0, 173, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, -0, 9, 0, 0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 182, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, -0, 4, 0, 0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, -0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, -0, 8, 0, 4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, -0, 200, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, -0, 250, 0, 4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, -0, 217, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, -0, 65, 0, 5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, -0, 226, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, -0, 248, 0, 2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, -0, 5, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, -0, 65, 0, 5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, -0, 241, 1, 0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, -0, 5, 0, 0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 247, 1, 0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, -0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, -0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, -0, 152, 1, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, -0, 4, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, -0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, -0, 5, 0, 0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, -0, 8, 2, 0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, -0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, -0, 197, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, -0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, -0, 8, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 29, 2, 0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, -0, 129, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, -0, 254, 0, 2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, -0, 55, 2, 0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 61, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 65, 2, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, -0, 62, 0, 3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, -0, 30, 0, 0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, -0, 74, 0, 0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, -0, 62, 0, 3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, -0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, +114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, +67, 79, 76, 79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, +32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, +118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, +116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, +32, 119, 101, 32, 117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, +101, 116, 115, 32, 102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, +41, 46, 114, 114, 114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, +97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, +32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, +32, 116, 104, 101, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, +108, 111, 119, 32, 105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, +88, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, +46, 103, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +110, 90, 32, 61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, +67, 111, 108, 111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, +32, 105, 115, 32, 97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, +104, 97, 110, 110, 101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, +61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, +115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, +108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, +0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, +114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, +116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, +0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, +0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, +80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, +0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, +0, 192, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, +110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, +66, 0, 0, 0, 0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, +0, 5, 0, 7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, +0, 98, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, +0, 139, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, +97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 11, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 5, 0, 177, 1, 0, +0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, +0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, +110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, +116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, +0, 5, 0, 4, 0, 242, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, +0, 4, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, +116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, +112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +50, 0, 0, 0, 0, 5, 0, 6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, +0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, +0, 43, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 5, 0, 45, 2, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, +0, 5, 0, 5, 0, 46, 2, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, +0, 6, 0, 6, 0, 47, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, +111, 114, 0, 0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, +118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, +97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 0, 0, 5, 0, 6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, +0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, +0, 74, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 65, 100, 100, 0, 5, 0, 6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, +0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, +0, 80, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, +0, 6, 0, 5, 0, 80, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, +111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, +0, 82, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, +0, 83, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, +97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, +0, 36, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, +0, 1, 0, 0, 0, 0, 22, 5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, +0, 43, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 5, 0, 73, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, +0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, +0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, +0, 78, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, +0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, +0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, +0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, +0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, +0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, +0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, +0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, +0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, +0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, +0, 43, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, +0, 32, 0, 4, 0, 208, 0, 0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, +0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, +0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, +0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, +0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, +61, 43, 0, 4, 0, 5, 0, 0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, +0, 43, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, +64, 32, 0, 4, 0, 37, 2, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, +0, 30, 0, 6, 0, 45, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, +0, 32, 0, 4, 0, 48, 2, 0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, +0, 43, 0, 4, 0, 138, 0, 0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, +0, 30, 0, 7, 0, 80, 2, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, +0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, +0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, +0, 38, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, +0, 49, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, +0, 72, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, +0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, +0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, +0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, +0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, +0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, +0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, +0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, +0, 84, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, +0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, +0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, +0, 49, 2, 0, 0, 66, 2, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, +0, 172, 0, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, +0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, +0, 208, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, +0, 231, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, +0, 234, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, +0, 235, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, +0, 238, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, +0, 65, 0, 5, 0, 192, 0, 0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, +0, 254, 0, 2, 0, 248, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 179, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 152, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 173, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 182, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, +0, 57, 0, 5, 0, 4, 0, 0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, +0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, +0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, +0, 202, 1, 0, 0, 200, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, +0, 0, 0, 0, 0, 250, 0, 4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, +0, 207, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, +0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, +0, 5, 0, 0, 0, 226, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, +0, 220, 1, 0, 0, 248, 0, 2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, +0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, +0, 5, 0, 0, 0, 241, 1, 0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, +0, 111, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, +0, 253, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, +0, 8, 0, 4, 0, 152, 1, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, +0, 3, 2, 0, 0, 4, 2, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 45, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, +0, 12, 0, 6, 0, 5, 0, 0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, +0, 7, 2, 0, 0, 8, 2, 0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, +0, 16, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 21, 2, 0, 0, 197, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 48, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, +0, 248, 0, 2, 0, 8, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 29, 2, 0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, +0, 32, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, +0, 25, 2, 0, 0, 254, 0, 2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, +0, 62, 0, 3, 0, 55, 2, 0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, +0, 18, 0, 0, 0, 61, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 65, 2, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, +0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, +0, 75, 2, 0, 0, 62, 0, 3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, +0, 57, 0, 4, 0, 30, 0, 0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, +0, 65, 0, 5, 0, 74, 0, 0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, +0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, +0, 105, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, +0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index abc0f2e655..351bf58257 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -21,758 +21,756 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, -0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, -105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, -0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, -112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, -0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, +4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, +121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, +0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, +95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, +0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, +70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, +112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, +115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, +69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, +83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, +51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, +32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, +102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, +32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, +115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, +95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, +116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, +111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, +104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, +101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, +116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, +97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, +99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, +103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, +46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, +32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, +47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, +32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, +101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, +115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, +0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, +47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, +111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, +116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, +32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, +115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, +122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, +101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, +53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, +116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, +32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, +111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, +116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, +73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, +80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, +59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, +76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, +69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, +97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, +82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, +114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, +108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, +116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, +10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, +114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, -46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, -95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, -38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, -80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, -105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, -73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, -101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, -101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, -103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, -32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, -117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, -115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, -102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, -101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, -99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, +46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, +32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, +100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, +46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, +105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, +32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, -32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, -97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, -100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, -100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, -99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, +32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, +101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, +101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, +108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, +48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, +115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, +82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, +13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, +114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, +32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, +115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, +102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, +71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, +32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, +40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, +47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, +108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, +98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, +56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, +32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, +41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, +115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, +113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, +48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, +32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, +101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, +103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, +41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, +114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, +116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, +108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, +108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, +32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, +52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, +110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, -101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, -115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, -114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, -101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, -122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, -101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, -54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, -116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, -32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, -98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, -47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, -79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, -78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, -32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, -69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, -67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, -32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, -32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, -10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, -111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, -105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, -111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, -102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, -117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, -77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, -105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, -125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, -104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, -70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, -112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, -115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, -69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, -111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, -116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, -50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, -101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, -42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, -32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, -56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, -101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, -116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, -97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, -111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, -97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, -108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, -32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, -105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, -49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, -101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, -40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, -83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, -32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, -13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, -55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, -32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, -48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, -117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, -111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, -32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, -52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, -51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, -101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, -116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, -116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, -32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, -111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, -40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, -108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, -102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, -13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, -32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, -77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, -32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, -32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, -58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, -104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, -120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, -99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, -122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, -45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, -45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, -32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, -111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, -97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, -40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, -101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, -59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, -7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, -114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, -7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, -111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, -0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, -84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, -0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, -109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, -0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, -114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, -51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, -4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, -0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, -111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, -77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, -0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, -5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, -0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, -3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, 0, 0, 105, 110, -116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, 111, 97, 116, 95, -48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, -5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, -0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 38, 2, -0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, -114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, 95, 80, 83, 95, -83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 1, 0, -0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, 0, 0, 80, 83, -95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 0, 0, -0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 47, 2, -0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, -69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 62, 2, -0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 69, 2, -0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, -67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, 116, 95, 86, 83, -95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 77, 2, -0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, -122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, 0, 0, 80, 111, -115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 4, 0, -0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 2, -0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, -5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, -110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, 0, 0, 67, 111, -108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, 114, 95, 80, 114, -105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, -116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 0, 0, -0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 40, 2, -0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, 0, 0, 3, 0, -0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, -6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, -4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, 0, 0, 3, 22, -0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, -5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, -0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, 0, 0, 66, 65, -84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, -0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, -0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, -0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, -0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, -0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, -0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, -0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, -4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, -0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 198, 0, -0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 7, 0, -0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 0, -0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, -0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, -0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, -0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 224, 1, -0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 253, 1, -0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, 0, 0, 3, 0, -0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, 0, 0, 42, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 6, 0, -0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 62, 2, -0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, 0, 0, 42, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, -0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, -4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, 0, 0, 59, 0, -4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, 0, 0, 59, 0, -4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, -4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, -4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, -5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 65, 0, -5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, -0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, -5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 57, 0, -4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, -0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, 0, 0, 53, 2, -0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, -0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, -0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, 0, 0, 7, 0, -0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, 0, 61, 0, -4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, 6, 0, 206, 0, -0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, 6, 0, 206, 0, -0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, 5, 0, 5, 0, -0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 246, 0, -0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, 0, 0, 56, 0, -1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, 0, 0, 5, 0, -0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 59, 0, -4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, -3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, 0, 0, 84, 2, -0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 193, 1, -0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, -5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, -0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, -0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, 0, 0, 201, 1, -0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 206, 1, -0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, 0, 0, 249, 0, -2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, -0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, 0, 0, 6, 1, -0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, 2, 0, 219, 1, -0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 234, 1, -0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, -0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, 0, 0, 240, 1, -0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 244, 1, -0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 228, 1, -0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, -0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, 0, 0, 12, 0, -6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 41, 0, -0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, 0, 0, 129, 0, -5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, 0, 0, 65, 0, -5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 14, 2, -0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 248, 0, -2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 2, 0, -0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, 0, 0, 79, 0, -9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 65, 0, -5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, 0, 0, 8, 0, -4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 28, 2, -0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, 5, 0, 4, 0, -0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, 2, 0, 35, 2, -0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 54, 2, -0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, 0, 0, 57, 2, -0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, 0, 0, 49, 2, -0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, 0, 0, 49, 2, -0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, -2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 89, 2, -0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, 3, 0, 93, 2, -0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 98, 2, -0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 101, 2, -0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, -0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, 3, 0, 76, 2, -0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, -0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, 0, 0, 0, 0, -0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, 0, 7, 0, 0, -0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, +101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, +101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, +109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, +79, 82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, +100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, +97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, +32, 117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, +32, 102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, +114, 114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, +40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, +105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, +101, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, +32, 105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, +32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, +42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, +61, 32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, +111, 114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, +32, 97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, +110, 101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, +105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, +101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, +0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, +0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, +0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, +101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, +7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, +116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, +97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, +105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, +116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, +0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, +108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, +0, 0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, +7, 0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, +0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, +62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, +101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, +49, 0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, +108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, +0, 0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, +0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, +111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, +0, 0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, +97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, +6, 0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, +67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, +95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, +0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, +0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, +0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, +6, 0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, +95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, +4, 0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, +6, 0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, +116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, +6, 0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, +95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, +0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, +0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, +6, 0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, +0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, +105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, +0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, +114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, +100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, +0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, +5, 0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, +0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, +0, 0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, +0, 0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, +0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, +0, 0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, +0, 0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, +0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, +0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, +0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, +0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, +4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, +0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, +0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, +2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, +0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, +3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, +0, 0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, +0, 0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, +4, 0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, +4, 0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, +4, 0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, +0, 0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, +0, 0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, +0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, +0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, +0, 0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, +0, 0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, +0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, +0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, +0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, +0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, +0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, +0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, +0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, +0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, +0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, +0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, +0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, +0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, +0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, +4, 0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, +0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, +0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, +6, 0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, +6, 0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, +5, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, +0, 0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, +0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, +0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, +0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, +0, 0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, +0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, +0, 0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, +0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, +4, 0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, +4, 0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, +0, 0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, +4, 0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, +0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, +5, 0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, +0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, +2, 0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, +0, 0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, +5, 0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, +0, 0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, +0, 0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, +0, 0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, +0, 0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, +0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, +0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, +0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, +0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, +0, 0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, +0, 0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, +0, 0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, +0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, +0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, +0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, +0, 0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, +5, 0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, +2, 0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, +0, 0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, +0, 0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, +0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, +0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, +0, 0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, +0, 0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, +3, 0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, +0, 0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, +0, 0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, +4, 0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, +3, 0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, +1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 216, 186, 37, 215, 174, 125, 94, 149, 227, 241, 56, 175, 214, 49, 253, 195, 0, 16, 92, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 109, 2, 0, +0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 6, 1, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 15, 0, 4, 0, 0, 0, 50, 2, 0, 0, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 38, 2, 0, 0, 40, 2, 0, 0, 42, 2, 0, 0, 43, 2, 0, 0, 36, 2, 0, 0, 49, 2, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 19, 0, 0, 0, 0, 0, 85, 2, 0, 0, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 69, 2, 0, 0, 72, 2, 0, 0, 73, 2, 0, 0, 75, 2, 0, 0, 77, 2, 0, 0, 68, 2, 0, 0, 70, 2, 0, 0, 74, 2, 0, 0, 76, 2, 0, 0, 78, 2, 0, 0, 84, 2, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 50, 2, 0, +0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, +111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, +115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, +116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, +78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, +68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, +47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, +32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, +83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, +104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, +97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, +112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, +117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, +76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, +73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, +97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, +41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, +47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, +115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, +116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, +47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, +116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, +0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, +32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, +104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, +108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, +108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, +84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, +117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, +80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, +95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, +13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, +101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, +65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, +109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, +79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, +10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, +116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, +101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, +101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, +32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, +125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, +115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, -109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, -80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, -32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, -111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, -115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, -115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, -114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, -102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, -116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, -69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, -111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, -73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, +109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, +32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, +32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, +80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, +116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, +32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, -76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, -115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, +76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, +114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, +13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, +105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, +46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, +112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, +71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, +10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, +103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, +99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, +108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, +97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, +40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, +82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, +99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, +13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, +84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, +50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, +108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, +13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, +113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, +114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, +102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, +125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, +110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, +98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, +32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, +44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, +115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, +111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, +108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, +48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, -32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, -32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, -101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, -108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, -84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, -117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, -101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, -120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, -32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, -73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, -69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, -32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, -113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, -73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, -59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, -61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, -32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, -97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, -108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, -47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, -0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, -114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, -110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, -100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, -46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, -105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, -102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, -97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, -116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, -13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, -97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, -111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, -115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, -116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, -78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, -108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, -46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, -53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, -32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, -32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, -110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, -32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, -97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, -46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, -108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, -32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, -110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, -49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, -97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, -82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, -50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, -83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, -10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, -54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, -82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, -46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, -116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, -119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, -99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, -32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, -32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, -114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, -59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 152, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 22, 2, 0, 0, 0, 0, 0, 0, 0, 0, 152, 1, 0, 0, 47, 47, 32, -67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, -117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, -104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, -105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, -111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, -10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, -32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, 82, 49, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, -97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, -111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, 117, 115, 101, 32, -102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, 102, 105, 120, 32, -105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 67, -111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, 114, 114, 32, 58, -32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, -97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, 115, 32, 115, 104, -111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, 32, 116, 101, 120, -116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, 105, 115, 32, 99, -111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, 115, 119, 105, 122, -122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, 32, 50, 32, 45, -32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, 32, 49, 32, 45, -32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 98, 32, -61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, 97, 108, 115, 111, -32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, 101, 108, 32, 97, -98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, -97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, -67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, -67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, -13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, -0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, -0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, -97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, -0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, -0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, -0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, 0, 112, 116, 114, -95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, -49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, -0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, -0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 63, 1, 0, -0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, 0, 102, 108, 111, -97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, -97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, -0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 5, -0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, -0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, 0, 5, 0, 3, -0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, 0, 0, 105, 110, 116, -95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, 111, 97, 116, 95, 48, -46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, 0, 5, 0, 5, -0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, -0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 38, 2, 0, -0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, -0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, 95, 80, 83, 95, 83, -119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 1, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, 0, 0, 80, 83, 95, -79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, 0, 0, 0, 0, 0, -0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 47, 2, 0, -0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 62, 2, 0, -0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 69, 2, 0, -0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, -111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, -67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, 0, 77, 2, 0, -0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, -122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 4, 0, 0, -0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 81, 2, 0, -0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, -0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, -0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, -114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 40, 2, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, -0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, 0, 0, 3, 22, 0, -0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 5, -0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, 0, 0, 30, 0, 0, -0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, -67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, -0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, -0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, -0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, -0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, -0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, -0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, -0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, -0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, -0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 198, 0, 0, -0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, 0, 7, 0, 0, -0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 245, 0, 0, -0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, -0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, -0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, -0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, 0, 224, 1, 0, -0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 253, 1, 0, -0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, 0, 0, 3, 0, 0, -0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, 0, 0, 42, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, 0, 6, 0, 0, -0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 62, 2, 0, -0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, 0, 0, 42, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, -0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, -0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, -0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, 0, 0, 57, 0, 4, -0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, -0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, 0, 0, 53, 2, 0, -0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, -0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, -0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, 0, 0, 7, 0, 0, -0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, -0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, -0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, -0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, -0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 246, 0, 0, -0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, 0, 0, 56, 0, 1, -0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, 0, 0, 59, 0, 4, -0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, -0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, 0, 0, 84, 2, 0, -0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 193, 1, 0, -0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, -0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, -0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, 0, 0, 201, 1, 0, -0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 206, 1, 0, -0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, 0, 0, 249, 0, 2, -0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, 0, 0, 6, 1, 0, -0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, 2, 0, 219, 1, 0, -0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 234, 1, 0, -0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, -0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, 0, 0, 240, 1, 0, -0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, -0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, 0, 228, 1, 0, -0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 251, 1, 0, -0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, 0, 0, 12, 0, 6, -0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 41, 0, 0, -0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, 0, 0, 129, 0, 5, -0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, -0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 14, 2, 0, -0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, 0, 248, 0, 2, -0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, 0, 0, 79, 0, 9, -0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, -0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, 0, 0, 8, 0, 4, -0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, 0, 28, 2, 0, -0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, 5, 0, 4, 0, 0, -0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, 2, 0, 35, 2, 0, -0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 54, 2, 0, -0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, 0, 0, 57, 2, 0, -0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, 0, 0, 49, 2, 0, -0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, 0, 0, 49, 2, 0, -0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, -0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 89, 2, 0, -0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, 3, 0, 93, 2, 0, -0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 98, 2, 0, -0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 101, 2, 0, -0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, 3, 0, 76, 2, 0, -0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, -0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, +13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, +115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 32, 58, 32, 67, 79, 76, 79, +82, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, +32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 40, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, +109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 66, 101, 99, 97, 117, 115, 101, 32, 119, 101, 32, +117, 115, 101, 32, 102, 108, 111, 97, 116, 32, 105, 110, 112, 117, 116, 32, 118, 97, 108, 117, 101, 115, 32, 119, 101, 32, 115, 104, 111, 117, 108, 100, 32, 97, 108, 108, 111, 119, 32, 99, 101, 114, 116, 97, 105, 110, 32, 116, 104, 114, 101, 115, 104, 111, 108, 100, 32, 45, 32, 108, 101, 116, 115, 32, +102, 105, 120, 32, 105, 116, 32, 97, 116, 32, 48, 46, 49, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 108, 112, 104, 97, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, +122, 108, 101, 67, 111, 108, 111, 114, 32, 61, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 49, 41, 32, 60, 61, 32, 48, 46, 49, 41, 32, 63, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 46, 114, 114, +114, 114, 32, 58, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 78, 111, 114, 109, 97, 108, 32, 109, 97, 112, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 97, 98, 115, 40, +115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 50, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 79, 68, 79, 32, 84, 104, 105, +115, 32, 115, 104, 111, 117, 108, 100, 32, 99, 104, 97, 110, 103, 101, 32, 105, 102, 32, 119, 101, 32, 109, 111, 118, 101, 32, 116, 104, 101, 32, 102, 108, 97, 103, 115, 32, 40, 114, 101, 99, 111, 110, 115, 116, 114, 117, 99, 116, 32, 90, 44, 32, 101, 116, 99, 41, 32, 116, 111, 32, 116, 104, 101, +32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 32, 70, 111, 114, 32, 110, 111, 119, 32, 106, 117, 115, 116, 32, 97, 115, 115, 117, 109, 101, 32, 116, 104, 101, 32, 102, 111, 114, 109, 117, 108, 97, 32, 98, 101, 108, 111, 119, 32, +105, 115, 32, 99, 111, 114, 114, 101, 99, 116, 32, 40, 119, 111, 114, 107, 115, 32, 102, 111, 114, 32, 57, 48, 37, 32, 111, 102, 32, 116, 101, 104, 32, 99, 97, 115, 101, 115, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 88, 32, 61, 32, +115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 32, 42, 32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 89, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 32, 42, +32, 50, 32, 45, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 110, 90, 32, 61, +32, 49, 32, 45, 32, 115, 113, 114, 116, 40, 115, 97, 116, 117, 114, 97, 116, 101, 40, 110, 88, 32, 42, 32, 110, 88, 32, 43, 32, 110, 89, 32, 42, 32, 110, 89, 41, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, +114, 46, 98, 32, 61, 32, 110, 90, 32, 42, 32, 48, 46, 53, 102, 32, 43, 32, 48, 46, 53, 102, 59, 32, 47, 47, 32, 68, 111, 110, 39, 116, 32, 102, 111, 114, 103, 101, 116, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 90, 45, 99, 111, 109, 112, 111, 110, 101, 110, 116, 32, 105, 115, 32, +97, 108, 115, 111, 32, 105, 110, 32, 116, 104, 101, 32, 114, 97, 110, 103, 101, 32, 40, 45, 49, 44, 32, 49, 41, 32, 115, 111, 32, 97, 108, 108, 32, 110, 111, 114, 109, 97, 108, 32, 116, 101, 120, 116, 117, 114, 101, 115, 32, 104, 97, 118, 101, 32, 66, 108, 117, 101, 32, 99, 104, 97, 110, 110, +101, 108, 32, 97, 98, 111, 118, 101, 32, 48, 46, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 79, 112, 97, 113, 117, 101, 32, 103, 114, 97, 121, 115, 99, 97, 108, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +105, 102, 32, 40, 97, 98, 115, 40, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 45, 32, 51, 41, 32, 60, 61, 32, 48, 46, 49, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, +122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 103, 98, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 114, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 46, 97, 32, 61, 32, 49, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 32, 61, 32, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, +97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 43, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 65, 100, 100, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, +13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, +0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, +0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, +0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, +105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, +95, 48, 0, 0, 0, 5, 0, 8, 0, 182, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 192, 0, 0, +0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 198, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 208, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, +111, 97, 116, 51, 0, 5, 0, 7, 0, 224, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 225, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 227, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, +0, 5, 0, 4, 0, 245, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 1, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 59, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, +0, 63, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 73, 1, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 90, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 92, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 98, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 103, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 108, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 139, 1, 0, +0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 154, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 160, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, +46, 86, 83, 77, 97, 105, 110, 0, 0, 5, 0, 10, 0, 161, 1, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 5, 0, 177, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, +95, 48, 0, 0, 0, 5, 0, 5, 0, 178, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 197, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, +0, 5, 0, 5, 0, 205, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 49, 0, 0, 0, 5, 0, 6, 0, 209, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 210, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, +115, 101, 0, 0, 0, 5, 0, 6, 0, 208, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 4, 0, 224, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 5, 0, 219, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 49, 0, 0, +0, 5, 0, 3, 0, 228, 1, 0, 0, 110, 88, 0, 0, 5, 0, 4, 0, 231, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 3, 0, 236, 1, 0, 0, 110, 89, 0, 0, 5, 0, 4, 0, 237, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 242, 1, 0, +0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 3, 0, 245, 1, 0, 0, 110, 90, 0, 0, 5, 0, 4, 0, 253, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 1, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 5, 0, 4, 2, 0, 0, 102, 108, 111, +97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 49, 0, 0, 5, 0, 4, 0, 12, 2, 0, 0, 102, 108, 111, 97, 116, 95, 51, 0, 5, 0, 5, 0, 7, 2, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 50, 0, 0, +0, 5, 0, 5, 0, 8, 2, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 50, 0, 0, 5, 0, 5, 0, 25, 2, 0, 0, 102, 105, 110, 97, 108, 67, 111, 108, 111, 114, 0, 0, 5, 0, 7, 0, 37, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, +116, 52, 0, 0, 0, 5, 0, 7, 0, 36, 2, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 39, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, +0, 38, 2, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 41, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 40, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, +111, 108, 111, 114, 0, 5, 0, 6, 0, 42, 2, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 44, 2, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 43, 2, 0, 0, 105, 110, 95, +80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 45, 2, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, +0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 45, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 45, 2, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 46, 2, 0, +0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 46, 2, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 47, 2, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 47, 2, 0, +0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 47, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, +0, 47, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 47, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 48, 2, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 49, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 50, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 53, 2, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 56, 2, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 59, 2, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, +0, 62, 2, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 5, 0, 4, 0, 66, 2, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 68, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, +0, 69, 2, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 71, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 70, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, +84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 72, 2, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 73, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 74, 2, 0, 0, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 75, 2, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 5, 0, 6, 0, 76, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 5, 0, 6, +0, 77, 2, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 79, 2, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 78, 2, 0, 0, 111, 117, 116, 95, 86, 83, 95, +83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 80, 2, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 1, 0, 0, +0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 80, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 80, 2, 0, +0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 81, 2, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 81, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, +0, 81, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 81, 2, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 81, 2, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, +0, 6, 0, 5, 0, 81, 2, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 82, 2, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 82, 2, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, +116, 105, 111, 110, 0, 6, 0, 6, 0, 82, 2, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 3, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 6, 0, 82, 2, 0, 0, 4, 0, 0, 0, 67, 111, 108, 111, 114, 65, 100, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 2, 0, 0, 5, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 83, 2, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 84, 2, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 85, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, +101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 96, 2, 0, 0, 105, 110, 116, 95, 53, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 36, 2, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 38, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 38, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 40, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, +0, 40, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 42, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 42, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 43, 2, 0, 0, 30, 0, 0, +0, 3, 0, 0, 0, 0, 22, 7, 0, 43, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 68, 2, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 69, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 0, 22, 6, 0, 69, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 70, 2, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 70, 2, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 72, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 72, 2, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 73, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 73, 2, 0, +0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 74, 2, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 74, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 75, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, +0, 0, 22, 5, 0, 75, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 76, 2, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 76, 2, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 49, 0, 0, 71, 0, 4, 0, 77, 2, 0, +0, 30, 0, 0, 0, 4, 0, 0, 0, 0, 22, 7, 0, 77, 2, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 78, 2, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 78, 2, 0, 0, 3, 22, 0, +0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, +0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, +0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, +0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, +0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, +0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, +0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, +0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, +0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, +0, 175, 0, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 192, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 191, 0, 0, 0, 5, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 198, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 206, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 208, 0, 0, +0, 7, 0, 0, 0, 206, 0, 0, 0, 33, 0, 4, 0, 207, 0, 0, 0, 206, 0, 0, 0, 208, 0, 0, 0, 32, 0, 4, 0, 224, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 223, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, +0, 245, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 249, 0, 0, 0, 4, 0, 0, 0, 224, 0, 0, 0, 192, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 1, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 59, 1, 0, 0, 2, 121, 41, 63, 43, 0, 4, +0, 5, 0, 0, 0, 63, 1, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 73, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 90, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, +0, 5, 0, 0, 0, 92, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 98, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 103, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 108, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, +0, 5, 0, 0, 0, 139, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 154, 1, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 201, 1, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 205, 204, 204, 61, 43, 0, 4, 0, 5, 0, 0, +0, 224, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 138, 0, 0, 0, 231, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 237, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 242, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 253, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 1, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 12, 2, 0, 0, 0, 0, 64, 64, 32, 0, 4, 0, 37, 2, 0, +0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 39, 2, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 41, 2, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 44, 2, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 45, 2, 0, +0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 46, 2, 0, 0, 4, 0, 0, 0, 30, 0, 7, 0, 47, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 48, 2, 0, +0, 6, 0, 0, 0, 47, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 53, 2, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 56, 2, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 59, 2, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, +0, 62, 2, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 66, 2, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 71, 2, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 79, 2, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 80, 2, 0, +0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 81, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 8, 0, 82, 2, 0, 0, 4, 0, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 83, 2, 0, 0, 6, 0, 0, 0, 82, 2, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 96, 2, 0, 0, 5, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, +0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 36, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 38, 2, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 41, 2, 0, 0, 40, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 42, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 44, 2, 0, 0, 43, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 48, 2, 0, 0, 49, 2, 0, 0, 6, 0, 0, +0, 59, 0, 4, 0, 37, 2, 0, 0, 68, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 39, 2, 0, 0, 69, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 71, 2, 0, 0, 70, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 72, 2, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 41, 2, 0, 0, 73, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 74, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 41, 2, 0, 0, 75, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 37, 2, 0, 0, 76, 2, 0, 0, 3, 0, 0, +0, 59, 0, 4, 0, 44, 2, 0, 0, 77, 2, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 79, 2, 0, 0, 78, 2, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 83, 2, 0, 0, 84, 2, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 84, 2, 0, 0, 66, 2, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, +0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 49, 2, 0, 0, 66, 2, 0, +0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 161, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, +0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 49, 2, 0, +0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, +0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 179, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 55, 0, 3, 0, 224, 0, 0, 0, 225, 0, 0, 0, 248, 0, 2, 0, 226, 0, 0, 0, 59, 0, 4, 0, 208, 0, 0, 0, 227, 0, 0, +0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 228, 0, 0, 0, 225, 0, 0, 0, 79, 0, 8, 0, 206, 0, 0, 0, 229, 0, 0, 0, 228, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 62, 0, 3, 0, 227, 0, 0, 0, 229, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 230, 0, 0, 0, 227, 0, 0, 0, 61, 0, 4, 0, 206, 0, 0, 0, 231, 0, 0, 0, 227, 0, 0, +0, 61, 0, 4, 0, 206, 0, 0, 0, 232, 0, 0, 0, 227, 0, 0, 0, 80, 0, 6, 0, 206, 0, 0, 0, 234, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 198, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 233, 0, 0, 0, 232, 0, 0, 0, 234, 0, 0, 0, 80, 0, 6, +0, 206, 0, 0, 0, 236, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 200, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 235, 0, 0, 0, 233, 0, 0, 0, 236, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 237, 0, 0, 0, 231, 0, 0, 0, 235, 0, 0, 0, 80, 0, 6, +0, 206, 0, 0, 0, 239, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 203, 0, 0, 0, 129, 0, 5, 0, 206, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 239, 0, 0, 0, 133, 0, 5, 0, 206, 0, 0, 0, 240, 0, 0, 0, 230, 0, 0, 0, 238, 0, 0, 0, 81, 0, 5, +0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 242, 0, 0, 0, 240, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 240, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, +0, 246, 0, 0, 0, 225, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 246, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 248, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 243, 0, 0, 0, 247, 0, 0, 0, 254, 0, 2, 0, 248, 0, 0, +0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 47, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 9, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 160, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 173, 1, 0, +0, 59, 0, 4, 0, 224, 0, 0, 0, 188, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 176, 1, 0, 0, 117, 0, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, +0, 247, 0, 3, 0, 178, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 154, 1, 0, 0, 177, 1, 0, 0, 178, 1, 0, 0, 248, 0, 2, 0, 177, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 182, 1, 0, +0, 84, 2, 0, 0, 59, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 190, 1, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 191, 1, 0, 0, 190, 1, 0, 0, 62, 0, 3, 0, 188, 1, 0, 0, 191, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, +0, 193, 1, 0, 0, 182, 0, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 193, 1, 0, 0, 249, 0, 2, 0, 178, 1, 0, 0, 248, 0, 2, 0, 178, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 152, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 4, 0, 0, 0, 161, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 197, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 207, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 192, 0, 0, 0, 228, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 236, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 192, 0, 0, 0, 245, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 224, 0, 0, 0, 25, 2, 0, 0, 7, 0, 0, 0, 8, 0, 4, +0, 152, 1, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 199, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 1, 0, 0, 199, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 202, 1, 0, 0, 200, 1, 0, +0, 201, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 203, 1, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 202, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 206, 1, 0, 0, 203, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, +0, 206, 1, 0, 0, 209, 1, 0, 0, 210, 1, 0, 0, 248, 0, 2, 0, 209, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 213, 1, 0, 0, 119, 0, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 214, 1, 0, 0, 213, 1, 0, 0, 213, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 214, 1, 0, 0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 210, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 217, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 207, 1, 0, 0, 217, 1, 0, +0, 249, 0, 2, 0, 208, 1, 0, 0, 248, 0, 2, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 218, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, +0, 18, 0, 0, 0, 222, 1, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 1, 0, 0, 222, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 225, 1, 0, 0, 223, 1, 0, 0, 224, 1, 0, 0, 12, 0, 6, 0, 5, 0, 0, 0, 226, 1, 0, +0, 6, 1, 0, 0, 4, 0, 0, 0, 225, 1, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 227, 1, 0, 0, 226, 1, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 220, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 227, 1, 0, 0, 219, 1, 0, 0, 220, 1, 0, 0, 248, 0, 2, +0, 219, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 232, 1, 0, 0, 197, 1, 0, 0, 231, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 233, 1, 0, 0, 232, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, +0, 234, 1, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 235, 1, 0, 0, 234, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 228, 1, 0, 0, 235, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, +0, 192, 0, 0, 0, 238, 1, 0, 0, 197, 1, 0, 0, 237, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 239, 1, 0, 0, 238, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 241, 1, 0, +0, 240, 1, 0, 0, 201, 1, 0, 0, 62, 0, 3, 0, 236, 1, 0, 0, 241, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 243, 1, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, +0, 244, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 243, 1, 0, 0, 244, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 40, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 246, 1, 0, 0, 228, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 1, 0, +0, 228, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 248, 1, 0, 0, 246, 1, 0, 0, 247, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 249, 1, 0, 0, 236, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 1, 0, 0, 236, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, +0, 251, 1, 0, 0, 249, 1, 0, 0, 250, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 252, 1, 0, 0, 248, 1, 0, 0, 251, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 254, 1, 0, 0, 6, 1, 0, 0, 43, 0, 0, 0, 252, 1, 0, 0, 253, 1, 0, 0, 201, 1, 0, +0, 12, 0, 6, 0, 5, 0, 0, 0, 255, 1, 0, 0, 6, 1, 0, 0, 31, 0, 0, 0, 254, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 0, 2, 0, 0, 201, 1, 0, 0, 255, 1, 0, 0, 62, 0, 3, 0, 245, 1, 0, 0, 0, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, +0, 41, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 192, 0, 0, 0, 2, 2, 0, 0, 197, 1, 0, 0, 1, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 3, 2, 0, 0, 245, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 5, 2, 0, 0, 3, 2, 0, 0, 4, 2, 0, +0, 129, 0, 5, 0, 5, 0, 0, 0, 6, 2, 0, 0, 5, 2, 0, 0, 4, 2, 0, 0, 62, 0, 3, 0, 2, 2, 0, 0, 6, 2, 0, 0, 249, 0, 2, 0, 220, 1, 0, 0, 248, 0, 2, 0, 220, 1, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 45, 0, 0, 0, 9, 0, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 10, 2, 0, 0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 2, 0, 0, 10, 2, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 13, 2, 0, 0, 11, 2, 0, 0, 12, 2, 0, 0, 12, 0, 6, 0, 5, 0, 0, +0, 14, 2, 0, 0, 6, 1, 0, 0, 4, 0, 0, 0, 13, 2, 0, 0, 188, 0, 5, 0, 8, 0, 0, 0, 15, 2, 0, 0, 14, 2, 0, 0, 205, 1, 0, 0, 247, 0, 3, 0, 8, 2, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 15, 2, 0, 0, 7, 2, 0, 0, 8, 2, 0, +0, 248, 0, 2, 0, 7, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 47, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 16, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 18, 2, 0, 0, 16, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, +0, 2, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 19, 2, 0, 0, 197, 1, 0, 0, 79, 0, 7, 0, 42, 0, 0, 0, 20, 2, 0, 0, 19, 2, 0, 0, 19, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 21, 2, 0, 0, 197, 1, 0, +0, 79, 0, 9, 0, 4, 0, 0, 0, 22, 2, 0, 0, 21, 2, 0, 0, 20, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 22, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 48, 0, 0, 0, 13, 0, 0, +0, 65, 0, 5, 0, 192, 0, 0, 0, 23, 2, 0, 0, 197, 1, 0, 0, 242, 1, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 2, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 23, 2, 0, 0, 24, 2, 0, 0, 249, 0, 2, 0, 8, 2, 0, 0, 248, 0, 2, 0, 8, 2, 0, +0, 8, 0, 4, 0, 152, 1, 0, 0, 52, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 26, 2, 0, 0, 197, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 28, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 29, 2, 0, +0, 28, 2, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 30, 2, 0, 0, 26, 2, 0, 0, 29, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 32, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 2, 0, 0, 32, 2, 0, 0, 129, 0, 5, +0, 4, 0, 0, 0, 34, 2, 0, 0, 30, 2, 0, 0, 33, 2, 0, 0, 62, 0, 3, 0, 25, 2, 0, 0, 34, 2, 0, 0, 8, 0, 4, 0, 152, 1, 0, 0, 53, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 35, 2, 0, 0, 25, 2, 0, 0, 254, 0, 2, +0, 35, 2, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 50, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 51, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 52, 2, 0, 0, 49, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 54, 2, 0, 0, 38, 2, 0, 0, 62, 0, 3, 0, 52, 2, 0, 0, 54, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 55, 2, 0, 0, 49, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 57, 2, 0, 0, 40, 2, 0, 0, 62, 0, 3, 0, 55, 2, 0, +0, 57, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 58, 2, 0, 0, 49, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 60, 2, 0, 0, 42, 2, 0, 0, 62, 0, 3, 0, 58, 2, 0, 0, 60, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 61, 2, 0, +0, 49, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 63, 2, 0, 0, 43, 2, 0, 0, 62, 0, 3, 0, 61, 2, 0, 0, 63, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 64, 2, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 65, 2, 0, +0, 49, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 2, 0, 0, 65, 2, 0, 0, 62, 0, 3, 0, 36, 2, 0, 0, 67, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 85, 2, 0, 0, 0, 0, 0, 0, 31, 0, 0, +0, 248, 0, 2, 0, 86, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 87, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 88, 2, 0, 0, 69, 2, 0, 0, 62, 0, 3, 0, 87, 2, 0, 0, 88, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 89, 2, 0, 0, 84, 2, 0, 0, 56, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 90, 2, 0, 0, 72, 2, 0, 0, 62, 0, 3, 0, 89, 2, 0, 0, 90, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 91, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 92, 2, 0, 0, 73, 2, 0, 0, 62, 0, 3, 0, 91, 2, 0, 0, 92, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 93, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 2, 0, 0, 75, 2, 0, 0, 62, 0, 3, +0, 93, 2, 0, 0, 94, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 95, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 97, 2, 0, 0, 77, 2, 0, 0, 62, 0, 3, 0, 95, 2, 0, 0, 97, 2, 0, 0, 57, 0, 4, 0, 30, 0, 0, +0, 98, 2, 0, 0, 160, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 99, 2, 0, 0, 84, 2, 0, 0, 66, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 100, 2, 0, 0, 99, 2, 0, 0, 62, 0, 3, 0, 68, 2, 0, 0, 100, 2, 0, 0, 65, 0, 5, 0, 74, 0, 0, +0, 101, 2, 0, 0, 84, 2, 0, 0, 53, 2, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 102, 2, 0, 0, 101, 2, 0, 0, 62, 0, 3, 0, 70, 2, 0, 0, 102, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 103, 2, 0, 0, 84, 2, 0, 0, 59, 2, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 104, 2, 0, 0, 103, 2, 0, 0, 62, 0, 3, 0, 74, 2, 0, 0, 104, 2, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 105, 2, 0, 0, 84, 2, 0, 0, 62, 2, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 106, 2, 0, 0, 105, 2, 0, 0, 62, 0, 3, +0, 76, 2, 0, 0, 106, 2, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 107, 2, 0, 0, 84, 2, 0, 0, 96, 2, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 108, 2, 0, 0, 107, 2, 0, 0, 62, 0, 3, 0, 78, 2, 0, 0, 108, 2, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index f5679a1ff2..61c2347c87 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -23,445 +23,443 @@ public partial class SpriteEffect 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, -0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, -2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, -0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, -97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, -1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 202, 222, 150, 118, 190, 241, 200, 207, -222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 209, 0, 0, -0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 243, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, 209, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, -0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, +0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, +108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, +0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, +16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, +79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, +114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 202, 222, 150, 118, +190, 241, 200, 207, 222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, +0, 209, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 243, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, 209, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, +100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, +98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, +100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, +116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, +114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, +13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, +102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, +95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, +102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, +116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, +100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, +68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, +108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, +0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, +66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, +100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, +46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, +13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, +105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, +108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, +40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, +32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, +46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, +41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, +47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, +115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, +116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, +104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, +109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, +101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, +108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, +98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, +10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, +68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, +101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, +116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, +78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, +83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, +115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, +111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, +116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, +73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, +13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, +105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, +125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, +101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, +108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, +98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, +84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, -99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, -97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, -86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, -116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, -70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, -32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, -114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, -99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, -10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, -84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, -32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, -104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, -116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, -0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, -46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, +99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, +101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, +47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, +47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, +32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, +115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, +100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, +120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, +0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, +99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, -104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, -101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, -125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, -97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, -112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, -69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, -104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, -99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, -76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, -114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, -99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, -101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, -101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, -32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, -112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, -71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, -108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, -100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, -117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, -83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, -61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, -112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, -114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, -13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, -121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, -32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, -79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, -79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, -1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, -104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, -110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, -32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, -111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, -114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, -114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, -116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, -105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, -114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, -109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, -111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, -32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, -101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, -100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, -100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, -98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, -100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, -116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, -114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, -114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, -32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, -97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, -0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, -97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, -0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, -116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, -0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, -86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, -0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, -95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, -103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 190, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, -50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, 0, 80, 83, 95, -83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 206, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 207, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, -116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 216, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, -116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 222, 0, 0, -0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, -0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, -100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, -0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, -102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, -0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, -111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, 0, 30, 0, 0, -0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, -0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, -0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, -0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, -0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, -0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, -0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, -0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, -0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, -0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, -0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, -0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, -0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, -0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 204, 0, 0, -0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 207, 0, 0, 0, 6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, 0, 1, 0, 0, -0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, -0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 234, 0, 0, -0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, -0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, -0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, -0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 228, 0, 0, -0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, -0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, -0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, -0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, -0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, -0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, -0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, -0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 213, 0, 0, 0, 202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, -0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, 0, 219, 0, 0, -0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, 0, 57, 0, 4, -0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, 0, 65, 0, 5, -0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 202, 222, 150, 118, 190, 241, 200, 207, 222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, -14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 209, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 243, 0, 0, 0, -15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, 209, 0, 0, 0, -7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, +104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, +101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, +116, 117, 114, 110, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, +0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, +95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, +0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, +0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, +97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, +105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, +0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, +97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 190, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, +95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, +108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, +0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 206, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, +0, 207, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, +102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 216, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, +95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, +102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, +0, 222, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 6, 0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, +0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, +0, 5, 0, 8, 0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, +105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, 241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, +0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, 242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, +101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, +0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, +0, 0, 22, 6, 0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, +0, 71, 0, 4, 0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, 241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, +0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, +0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, +0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, +0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, +0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, +0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, +0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, +0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, +0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, +0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, +63, 44, 0, 7, 0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, +0, 204, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 207, 0, 0, 0, 6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, +0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, +0, 234, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, +0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, +0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, +0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, +0, 185, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, +0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, +0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, +0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, +0, 151, 0, 0, 0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 119, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, +0, 31, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 213, 0, 0, 0, 202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, +0, 219, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, +0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, +0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 202, 222, 150, 118, 190, 241, 200, 207, 222, 16, 185, 33, 171, 124, 82, 37, 0, 168, 52, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, +1, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 209, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 202, 0, 0, 0, 200, 0, 0, 0, 208, 0, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, +243, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 229, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 219, 0, 0, 0, 222, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 228, 0, 0, 0, 116, 0, 0, 0, 243, 0, 0, 0, 16, 0, 3, 0, +209, 0, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, +84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, +116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, +111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, +73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, +97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, +117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, +67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, +32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, +32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, +32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, +83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, +83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, +116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, +111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, +108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, +112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, +110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, +110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, +32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, +111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, +119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, +101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, +13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, +32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, +32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, +0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, +100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, +114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, +111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, +101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, +116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, +101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, +95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, +77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, +101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, +114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, +73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, +67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, +79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, +97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, +125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, +109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, +101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, +103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, +59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, +100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, -83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, -115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, -83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, -32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, -47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, -116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, -86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, -97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, -97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, -109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, -117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, -116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, -101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, -100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, -110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, +83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, +32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, +47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, +32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, +111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, +109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, +112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, +32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, +13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, -104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, -32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, -104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, -35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, -111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, -67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, -101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, -111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, -111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, -83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, -101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, -67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, -95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, -76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, -10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, -115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, -82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, -112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, -97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, -80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, -101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, -114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, -98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, -97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, -59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, -47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, -116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, -116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, -46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, -100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, -99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, -32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, -86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, -111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, -101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, -32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 20, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 115, 100, 115, 108, 0, 0, 3, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, -84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, -116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, -111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, -73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, -32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, 32, 115, 112, 114, -105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, 10, 13, 10, 32, -32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, -5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, -111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, -119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, -46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, -185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, 190, 0, 0, 0, -102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, -5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 80, 83, 95, 73, -78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, 0, 0, 0, 0, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 206, 0, 0, 0, -1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 207, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, -83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 216, 0, 0, 0, -105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, 112, 116, 114, 95, -73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 222, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, -224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, -6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, 115, 116, 114, 101, -97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 6, 0, -241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 9, 0, -242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, -200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, 11, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, -220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 3, 0, -241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, -72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 34, 0, 0, 0, -0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, -20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, -6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, -24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, -138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, 2, 0, 0, 0, -4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, -32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 204, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 207, 0, 0, 0, -6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 223, 0, 0, 0, -1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, -40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, -200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, -219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, -8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, -21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, -25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, -31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, -110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, -22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, -228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, -61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, -28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, -208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, -4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, -172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, -87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, -5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, 119, 0, 0, 0, -65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, -56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 213, 0, 0, 0, -202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 217, 0, 0, 0, -215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 231, 0, 0, 0, -228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, 0, 219, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, -235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, -238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, -240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, +97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 108, 111, 114, 32, 117, 115, 101, 100, 32, 116, 111, 32, 116, 105, 110, 116, 32, 116, 104, 101, +32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 91, 67, 111, 108, 111, 114, 93, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 49, 44, 49, 44, 49, 44, 49, 41, 59, 13, +10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, +110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 32, 42, 32, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, +0, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, +18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, +41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, +84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, +97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, +5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, +116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, +5, 0, 8, 0, 185, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, 5, 0, 7, 0, 186, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 4, 0, +190, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 201, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 200, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 0, 0, 5, 0, 7, 0, 203, 0, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 202, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, +80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 204, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 205, 0, 0, 0, +0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 206, 0, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 206, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, +206, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 8, 0, 207, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 208, 0, 0, 0, 115, 116, 114, 101, +97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 9, 0, 209, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 212, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, +216, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 218, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 219, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 5, 0, 7, 0, 221, 0, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 7, 0, 223, 0, 0, 0, +112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 6, 0, 222, 0, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 224, 0, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, +6, 0, 6, 0, 224, 0, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 224, 0, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 5, 0, 225, 0, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, +84, 0, 0, 0, 6, 0, 7, 0, 225, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 225, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 5, 0, 5, 0, 226, 0, 0, 0, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 226, 0, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 226, 0, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, +6, 0, 6, 0, 226, 0, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 5, 0, 8, 0, 227, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 228, 0, 0, 0, +115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 9, 0, 229, 0, 0, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, +5, 0, 6, 0, 241, 0, 0, 0, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, +5, 0, 9, 0, 242, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 5, 0, 4, 0, 243, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, +71, 0, 4, 0, 200, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 202, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 202, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 218, 0, 0, 0, +11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 219, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 219, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 220, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, +0, 22, 6, 0, 220, 0, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 222, 0, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 222, 0, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, +71, 0, 3, 0, 241, 0, 0, 0, 2, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, +16, 0, 0, 0, 72, 0, 5, 0, 241, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, +34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, +34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 243, 0, 0, 0, 33, 0, 0, 0, 3, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, +4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, +3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, +86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, +21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 186, 0, 0, 0, +2, 0, 0, 0, 4, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 0, 0, 128, 63, 44, 0, 7, 0, 4, 0, 0, 0, 191, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 190, 0, 0, 0, 32, 0, 4, 0, 201, 0, 0, 0, 3, 0, 0, 0, +4, 0, 0, 0, 32, 0, 4, 0, 203, 0, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 204, 0, 0, 0, 42, 0, 0, 0, 30, 0, 3, 0, 205, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 206, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, +207, 0, 0, 0, 6, 0, 0, 0, 206, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 212, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 221, 0, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, +223, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 224, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 225, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 226, 0, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, +32, 0, 4, 0, 227, 0, 0, 0, 6, 0, 0, 0, 226, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 234, 0, 0, 0, 2, 0, 0, 0, 30, 0, 3, 0, 241, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 242, 0, 0, 0, 2, 0, 0, 0, 241, 0, 0, 0, 59, 0, 4, 0, +36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 242, 0, 0, 0, 243, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, +201, 0, 0, 0, 200, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 203, 0, 0, 0, 202, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 207, 0, 0, 0, 208, 0, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 201, 0, 0, 0, 218, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, +203, 0, 0, 0, 219, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 221, 0, 0, 0, 220, 0, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 0, 0, 0, 222, 0, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 227, 0, 0, 0, 228, 0, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, +35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +133, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, +139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, +108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +149, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 185, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, +54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, +74, 0, 0, 0, 172, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, +165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, +10, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 194, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 12, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 197, 0, 0, 0, +119, 0, 0, 0, 65, 0, 5, 0, 186, 0, 0, 0, 244, 0, 0, 0, 243, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 198, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 199, 0, 0, 0, 197, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, +199, 0, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 209, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 210, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 211, 0, 0, 0, 208, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, +213, 0, 0, 0, 202, 0, 0, 0, 62, 0, 3, 0, 211, 0, 0, 0, 213, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 214, 0, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 215, 0, 0, 0, 208, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +217, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 200, 0, 0, 0, 217, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 230, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, +231, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 232, 0, 0, 0, 219, 0, 0, 0, 62, 0, 3, 0, 231, 0, 0, 0, 232, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 233, 0, 0, 0, 228, 0, 0, 0, 234, 0, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 235, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 233, 0, 0, 0, 235, 0, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 0, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 0, 0, 0, 228, 0, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, +4, 0, 0, 0, 238, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 218, 0, 0, 0, 238, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 0, 0, 0, 228, 0, 0, 0, 212, 0, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 0, 0, 0, 239, 0, 0, 0, 62, 0, 3, 0, +220, 0, 0, 0, 240, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index 2ce138736e..b33fbc9c42 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -19,596 +19,594 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, -116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, -100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, -0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, -0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, +121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, +9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, +0, 0, 0, 1, 12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, +76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, +0, 182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, +0, 212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, +101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, +112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, +73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, +116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, +73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, +80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, +44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, +59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, +112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, +101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, +105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, +0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, +117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, +101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, +102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, +114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, +101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, +97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, +0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, +100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, +46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, +13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, +105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, +101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, +97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, +67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, +120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, +116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, +32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, +13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, +110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, +112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, +76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, +32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, +101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, +114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, +109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, -111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, -71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, -73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, -103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, -101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, -32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, -76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, -32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, -112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, -114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, -76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, -73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, -0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, -100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, -32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, -104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, -109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, -115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, -104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, -80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, -0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, -110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, -41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, -32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, -104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, -47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, -116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, -84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, -32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, -101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, -51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, -105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, -59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, -32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, -80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, -32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, -116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, -65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, -10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, -116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, -116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, -54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, -114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, -116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, -115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, -115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, -116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, -108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, -104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, -108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, -32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, -48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, -97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, +111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, +32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, +45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, +111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, +43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, +114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, +42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, +32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, +40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, +110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, -111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, -97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, -110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, -97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, -111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, -32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, -48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, -67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, -102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, -32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, -66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, -53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, -32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, -103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, -32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, -97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, -112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, -102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, -1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, -104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, -110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, -32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, -111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, -105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, -32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, -111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, -0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, -0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, -111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, -111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, -0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, -95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, -49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, -0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, -0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, -0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, -0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, -104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, -95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, -0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, -117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, -0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, -111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, -67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, -101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, -95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, -0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, -0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, -0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, -100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, -0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, -0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, -95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, -102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, -0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, -79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, -0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, -0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, -0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, -0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, -0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, -0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, -0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, -0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, -0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, -0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, -0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, -0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, -0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, -0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, -0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, -0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, -0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, -0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, -0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, -0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, -0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, -0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, -0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, -0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, -0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, -0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, -0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, -0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, -0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, -0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, -0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, -0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, -0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, -0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, -0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, -0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, -0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, -0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, -0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, -0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, -0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, -0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, -0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, -0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, -0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, -0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, -0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, -0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, -0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, -0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, -0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, -0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, -0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, -11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, -184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, -215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, -0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, +32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, +82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, +83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, +44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, +108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, +114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, +111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, +10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, +103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, +76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, +114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, +32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, +117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, +114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, +108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, +117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, +99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, +32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, +66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, +114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, +32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, +116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, +101, 32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, +108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, +0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, +0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, +0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, +110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, +0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, +0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, +52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, +0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, +52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, +0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, +101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, +112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, +110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, +0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, +95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, +52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, +0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, +0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, +102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, +0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, +0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, +0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, +0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, +67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, +65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, +0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, +0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, +0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, +0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, +0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, +0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, +0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, +0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, +0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, +0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, +0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, +0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, +0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, +0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, +0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, +0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, +0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, +0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, +0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, +0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, +0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, +0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, +0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, +0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, +0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, +0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, +0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, +0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, +0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, +0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, +0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, +0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, +0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, +0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, +0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, +0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, +0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, +0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, +0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, +0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, +0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, +0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, +0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, +0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, +0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, +0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, +0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, +0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 12, 215, 74, 63, 44, 253, 243, 60, 7, 200, 140, 206, 136, 243, 35, 243, 0, 96, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, +1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, +101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, +214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, +3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, +115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, +105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, +116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, +116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, +100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, +83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, +105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, +73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, +105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, +111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, +101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, +83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, +71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, +112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, +115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, +116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, +32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, +68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, +101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, +32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, +47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, +13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, +105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, +104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, +84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, +116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, +111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, +73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, +32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, +97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, +101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, +59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, +120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, +117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, +95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, +101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, +100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, +110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, +97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, +32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, +32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, +123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, +32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, +105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, +0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, -111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, -83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, -32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, -13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, -60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, -32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, -97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, -116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, -97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, -116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, -97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, -0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, -117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, -32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, -114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, -111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, -112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, -101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, -32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, -32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, -117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, -58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, -117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, -83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, -116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, -32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, -50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, -116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, -10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, -101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, -117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, -32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, -95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, -32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, -115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, -32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, -101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, -83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, -110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, -73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, -32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, -116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, -0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, -58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, -100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, -114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, -111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, -32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, -109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, -48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, -115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, -41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, -54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, -111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, +115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, +114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, +118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, +115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, +43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, +32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, +32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, +97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, +32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, +103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, +111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, -59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, -109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, -97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, -13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, -97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, -112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, -110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, -32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, -32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, -98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, -49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, -50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, -49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, -46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, -32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, -41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, -61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, -32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, -97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, -103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, -48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, -116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, -114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, -67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, -100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, -32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, -110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, -10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, -110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, -98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, -32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, -123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, -84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, -100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, -40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, -101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, -102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, -84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, -102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, -85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, -85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, -114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, -112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, -54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, -97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, -5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, -248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, -116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, -77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, -83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, -5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, -5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, -109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, -5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, -73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, -188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, -6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, -191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, -6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, -5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, 85, 73, 69, 102, -102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, -50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, -111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, -111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, -216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, -108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, -3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, -221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, -222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, -0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, -122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, 225, 1, 0, 0, -85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, -30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, -0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, -71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, -30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, -84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, -216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, -218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, -33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, -23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, -42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, -5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, -86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, -121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, -3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, -153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, -186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, -2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, -32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, -27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, -187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, -192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, -2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, -5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, -42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, -59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, -59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, -59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, -59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, -54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, -21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, -158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, -156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, -129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, -132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, -0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, -26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, -60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, -10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, -7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, -113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, -204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, -249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, -137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, -139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, -150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, -160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, -9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, -170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, -170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, -35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, -4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, -197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, -203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, -182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, -62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, -18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, -62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, -56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, +97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, +114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, +48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, +50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, +118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, +111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, +82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, +104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, +32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, +47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, +105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, +81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, +116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, +32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, +101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, +106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, +108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, +100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, +73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, +105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, +32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, +109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, +97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, +5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, +109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, +121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, +116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, +95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, +0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, +5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, +102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, +27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, +68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 10, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, +62, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 88, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, +102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, +95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, +116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, +97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, +112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, +5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, +122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 12, 0, 195, 1, 0, 0, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, +105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, +115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, +212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, +5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, +117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, +0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, +220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, +6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, +5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, +111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, +83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 12, 0, +225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, 115, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, +182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, +1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, +69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, +212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, +80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, +0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, +71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, +5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, +21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, +1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, +2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, +69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, +26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, +5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, +5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, +4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, +5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, +5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, +5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 42, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, +4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, +32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, +30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, +201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, +3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, +4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, +1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, +1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, +3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, +5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, +156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, +161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, +129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, +132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, +169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, +174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, +108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, +121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, +112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, +224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, +126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, +133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, +153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, +86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, +86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, +33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, +247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, +249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, +81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, +133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, +74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, +62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, +62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, +198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, +214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, +65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, +198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, +241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, +253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index d76733756f..c536709ed1 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -19,595 +19,593 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, -116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -88, 177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, -100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, -0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, -0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, +121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, +9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, +0, 0, 0, 1, 88, 177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, +76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, +0, 182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, +0, 212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, +101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, +112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, +73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, +32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, +116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, +73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, +80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, +44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, +59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, +116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, +101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, +108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, +97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, +116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, +112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, +101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, +105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, +111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, +0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, +117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, +101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, +102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, +114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, +101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, +97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, +0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, +120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, +100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, +46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, +13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, +105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, +101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, +117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, +97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, +67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, +120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, +114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, +116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, +116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, +116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, +32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, +13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, +65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, +110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, +112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, +115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, +114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, +76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, +32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, +101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, +114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, +109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, +79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, +101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, -111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, -109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, -71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, -73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, -103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, -101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, -32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, -76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, -32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, -52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, -116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, -112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, -114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, -76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, -73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, -101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, -0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, -100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, -32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, -104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, -109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, -115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, -104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, -80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, -0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, -105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, -110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, -41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, -32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, -104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, -47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, -116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, -84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, -117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, -32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, -101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, -51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, -105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, -59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, -32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, -80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, -32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, -111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, -116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, -32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, -116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, -65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, -10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, -32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, -116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, -114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, -116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, -50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, -54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, -114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, -114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, -116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, -115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, -115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, -116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, -108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, -104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, -108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, -50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, -32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, -48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, -97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, +111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, +32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, +45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, +48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, +111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, +43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, +114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, +42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, +32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, +40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, +110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, -111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, -97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, -110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, -97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, -111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, -32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, -48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, -67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, -102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, -108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, -32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, -66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, -53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, -32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, -103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, -32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, -32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, -97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, -112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, -102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, -1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, -104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, -110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, -32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, -111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, -72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, -97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, -105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, -109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, -32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, -111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, -0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, -0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, -95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, -67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, -111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, -111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, -0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, -95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, -0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, -49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, -0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, -0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, -0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, -102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, -0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, -0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, -0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, -50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, -0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, -0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, -0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, -0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, -0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, -83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, -0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, -0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, -86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, -0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, -122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, -85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, -0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, -0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, -0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, -83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, -95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, -0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, -0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, -0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, -0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, -0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, -0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, -87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, -0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, -0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, -0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, -0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, -0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, -0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, -0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, -0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, -0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, -0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, -0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, -0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, -0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, -0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, -0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, -0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, -0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, -0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, -0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, -0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, -0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, -0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, -0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, -0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, -0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, -0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, -0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, -0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, -0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, -0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, -0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, -0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, -0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, -0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, -0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, -0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, -0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, -0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, -0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, -0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, -0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, -0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, -0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, -0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, -0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, -0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, -0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, -0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 88, -177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, -46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, 182, 1, 0, 0, -194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, 212, 1, 0, 0, -216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, +32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, +82, 103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, +83, 49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, +44, 32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, +108, 47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, +114, 32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, +111, 119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, +10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, +103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, +13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, +76, 105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, +114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, +32, 115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, +117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, +114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, +108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, +117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, +99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, +32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, +66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, +114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, +32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, +116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, +101, 32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, +108, 101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, +0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, +97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, +0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, +116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, +102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, +0, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, +110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, +0, 5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, +0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, +95, 51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, +46, 54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, +52, 55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, +0, 5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, +52, 53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, +0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, +103, 0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, +114, 0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, +101, 0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, +95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, +108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, +0, 186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, +0, 5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, +0, 6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, +0, 5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, +0, 208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, +0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, +0, 217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, +83, 119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, +0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, +79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, +0, 221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, +0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, +110, 0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, +95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, +77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, +0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, +0, 0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, +68, 48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, +0, 215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, +0, 3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, +67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, +0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, +0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, +0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, +0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, +0, 114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, +0, 129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, +0, 135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, +0, 174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, +0, 5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, +0, 5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, +0, 5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, +0, 30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, +0, 6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, +0, 208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, +0, 30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, +0, 222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, +0, 6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, +0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, +0, 3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, +0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, +0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, +0, 154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, +0, 135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, +0, 159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, +0, 133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, +0, 133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, +0, 133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, +0, 5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, +0, 170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, +0, 81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, +0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, +0, 81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, +0, 124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, +0, 81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, +0, 133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, +0, 153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, +0, 161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, +0, 171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, +0, 79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, +0, 61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, +0, 54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, +0, 62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, +0, 18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, +0, 3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, +0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, +0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, +0, 217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, +0, 237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, +0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, +0, 0, 1, 88, 177, 238, 45, 79, 228, 144, 127, 1, 80, 112, 128, 65, 138, 45, 217, 0, 80, 72, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 191, 0, 0, 0, 71, 76, 83, 76, +46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 14, 0, 4, 0, 0, 0, 195, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 184, 1, 0, 0, 186, 1, 0, 0, 188, 1, 0, 0, +182, 1, 0, 0, 194, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 225, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 211, 1, 0, 0, 214, 1, 0, 0, 215, 1, 0, 0, 217, 1, 0, 0, 210, 1, 0, 0, +212, 1, 0, 0, 216, 1, 0, 0, 218, 1, 0, 0, 224, 1, 0, 0, 16, 0, 3, 0, 195, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, +47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, +116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, +46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, +84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, +105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, +114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, +68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, +82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, +32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, +13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, +32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, +116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, +32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, +116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, +112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, +110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, +117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, +0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, +100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, +114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, +111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, +115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, +120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, +114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, +7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, +116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, +32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, +110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, +10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, +110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, +32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, +32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, +101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, +50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, +117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, +117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, +116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, +117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, +97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, +32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, +97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, +67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, +10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, +10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, +110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, +105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, +108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, +85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, +73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, +125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, +115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, +99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, +116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, +108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, +79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, -114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, -13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, -82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, -76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, -97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, -108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, -79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, -83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, -116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, -116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, -47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, -116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, -101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, -101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, -110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, -115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, -26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, -111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, -67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, -101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, -111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, -104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, -97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, -105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, -35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, -110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, -116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, -32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, -68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, -101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, -47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, -101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, -101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, -114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, -101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, -116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, -32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, -84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, -68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, -83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, -110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, -13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, -76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, -65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, -32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, -32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, -116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, -114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, -87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, -82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, -61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, -111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, -32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, -116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, -101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 115, 100, 115, 108, 0, 0, 3, 0, 176, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, -105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, -105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, -58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, -101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, -105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, -105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 104, -116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, 104, 108, 115, 108, -46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, -49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, -116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, -49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, -99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, +114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, +116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +47, 47, 32, 104, 116, 116, 112, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 106, 112, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, 114, 45, +104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, +46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, +108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, +32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 114, 103, 98, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, +32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, +32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, +32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, +32, 32, 32, 32, 47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, +40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, +82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 76, 105, 110, 101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, +115, 45, 102, 111, 114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, -47, 47, 32, 115, 105, 109, 112, 108, 101, 32, 115, 99, 114, 101, 101, 110, 32, 103, 97, 109, 109, 97, 32, 99, 111, 110, 118, 101, 114, 115, 105, 111, 110, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 71, 97, 109, 109, 97, 84, 111, 76, 105, 110, 101, 97, 114, 32, 40, 102, 108, 111, -97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, -46, 114, 103, 98, 44, 32, 49, 46, 48, 47, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, -101, 97, 114, 84, 111, 71, 97, 109, 109, 97, 32, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 44, 32, 102, 108, 111, 97, 116, 32, 71, 97, 109, 109, 97, 32, 61, 32, 50, 46, 50, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, -46, 114, 103, 98, 32, 61, 32, 112, 111, 119, 40, 82, 71, 66, 97, 46, 114, 103, 98, 44, 32, 71, 97, 109, 109, 97, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 99, 104, 105, 108, 108, 105, 97, 110, 116, 46, 98, 108, 111, 103, 115, 112, 111, 116, 46, 99, 111, 109, 47, 50, 48, 49, 50, 47, 48, 56, 47, 115, 114, 103, 98, 45, 97, 112, 112, 114, 111, 120, 105, 109, 97, 116, 105, 111, 110, 115, 45, 102, 111, -114, 45, 104, 108, 115, 108, 46, 104, 116, 109, 108, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 115, 82, 71, 66, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 82, 71, 66, 32, 61, 32, -115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 40, 115, 82, 71, 66, 32, 42, 32, 48, 46, 51, 48, 53, 51, 48, -54, 48, 49, 49, 32, 43, 32, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 41, 32, 43, 32, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 41, 44, 32, 115, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, -111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 40, 102, -108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, -97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, 49, 32, 43, 32, -48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, 32, 82, 71, 66, -97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, 47, 51, 57, 53, -35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, 32, 116, 111, 32, -115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, 119, 40, 114, 103, -98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, 13, 10, 32, 32, -32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, -108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, 105, 110, 101, 97, -114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, -40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, -41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, -117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 74, 1, -0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, -116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, -32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, -117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, -111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, 58, 32, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, -95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, -109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, 101, 97, 109, 115, -46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, -116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, -111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, -123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, -115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, 32, 61, 61, 32, -48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, -108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, -5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, -112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, -84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, -111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, 67, 111, 108, 111, -114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, -97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, 5, 0, 7, 0, -132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, 112, 116, 114, 95, -70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, -5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 52, 49, -50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 0, 0, 0, -5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, 5, 0, 5, 0, -32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, 53, 0, 0, 0, -5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, 85, 73, 69, 102, -102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 0, -5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, -5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, 0, 0, 0, 0, -5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, -117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, -0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 186, 1, 0, 0, -105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 5, 0, -190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, -190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, -192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, -6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, 208, 1, 0, 0, -105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, -5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, 105, 110, 95, 86, -83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, 217, 1, 0, 0, -105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, -108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, -116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, -84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, -2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, 0, 0, 0, 0, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, -6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 95, -87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 184, 1, 0, 0, -3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, 30, 0, 0, 0, -2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, -71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 215, 1, 0, 0, -3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, -0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, -73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, -33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, -7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, -30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, -37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 114, 0, 0, 0, -205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, 129, 0, 0, 0, -196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, 135, 0, 0, 0, -137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 174, 0, 0, 0, -3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, 5, 0, 0, 0, -248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, 5, 0, 0, 0, -21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, 5, 0, 0, 0, -68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 30, 0, 5, 0, -190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, 6, 0, 0, 0, -192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 208, 1, 0, 0, -0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, -221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, 222, 1, 0, 0, -43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, 3, 0, 0, 0, -59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, 6, 0, 0, 0, -59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, 1, 0, 0, 0, -59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, 3, 0, 0, 0, -59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, -8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, 154, 0, 0, 0, -248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, 135, 0, 0, 0, -158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 159, 0, 0, 0, -156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 133, 0, 5, 0, -135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, 133, 0, 5, 0, -135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, 133, 0, 5, 0, -135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, -172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, 170, 0, 0, 0, -171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, -40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, -8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, -87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 108, 1, 0, 0, -224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, -18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, 124, 1, 0, 0, -57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, -25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 1, 0, 0, -194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, -4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, -169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, -42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, 161, 1, 0, 0, -158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, 171, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, 79, 0, 9, 0, -4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, -30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, 62, 0, 3, 0, -197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, -203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, -207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, 0, 0, 0, 0, -31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, 217, 1, 0, 0, -62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, 237, 1, 0, 0, -62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 110, 32, 108, 105, 110, 101, 97, 114, 32, 99, 111, 108, 111, 114, 32, 116, 111, 32, 115, 82, 71, 66, 32, 115, 112, 97, 99, 101, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, +103, 98, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 82, 71, 66, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 49, 32, 61, 32, 115, 113, 114, 116, 40, 82, 71, 66, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 83, 50, 32, 61, 32, 115, 113, 114, 116, 40, 83, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 102, 108, 111, 97, 116, 51, 32, 83, 51, 32, 61, 32, 115, 113, 114, 116, 40, 83, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 102, 32, 42, 32, 83, +49, 32, 43, 32, 48, 46, 54, 56, 52, 49, 50, 50, 48, 54, 48, 102, 32, 42, 32, 83, 50, 32, 45, 32, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 102, 32, 42, 32, 83, 51, 32, 45, 32, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, 55, 48, 102, 32, 42, 32, 82, 71, 66, 44, +32, 82, 71, 66, 97, 46, 97, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 104, 116, 116, 112, 115, 58, 47, 47, 103, 105, 116, 104, 117, 98, 46, 99, 111, 109, 47, 118, 118, 118, 118, 47, 86, 76, 46, 83, 116, 114, 105, 100, 101, 47, 112, 117, 108, 108, +47, 51, 57, 53, 35, 105, 115, 115, 117, 101, 99, 111, 109, 109, 101, 110, 116, 45, 55, 54, 48, 50, 53, 51, 57, 53, 54, 13, 10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 108, 105, 110, 101, 97, 114, +32, 116, 111, 32, 115, 82, 71, 66, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 76, 105, 110, 101, 97, 114, 84, 111, 83, 82, 103, 98, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 114, 103, 98, 32, 61, 32, 82, 71, 66, 97, 46, 114, 103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 49, 46, 48, 53, 53, 32, 42, 32, 112, 111, +119, 40, 114, 103, 98, 44, 32, 49, 46, 48, 47, 50, 46, 52, 41, 32, 45, 32, 48, 46, 48, 53, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 114, 103, 98, 32, 42, 32, 49, 50, 46, 57, 50, 102, 59, 13, 10, +13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, 115, 116, 101, 112, 40, 114, 103, 98, 44, 32, 48, 46, 48, 48, 51, 49, 51, 48, 56, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 82, 71, 66, 97, 46, 114, 103, +98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, 116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 67, 111, 110, 118, 101, 114, 116, 115, 32, 97, 32, 99, 111, 108, 111, 114, 32, 102, 114, 111, 109, 32, 115, 82, 71, 66, 32, 116, 111, 32, 108, 105, 110, 101, 97, 114, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 82, 103, 98, 84, 111, 76, +105, 110, 101, 97, 114, 80, 114, 101, 99, 105, 115, 101, 40, 102, 108, 111, 97, 116, 52, 32, 115, 82, 71, 66, 97, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 115, 114, 103, 98, 32, 61, 32, 115, 82, 71, 66, 97, 46, 114, +103, 98, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 104, 105, 103, 104, 101, 114, 32, 61, 32, 112, 111, 119, 40, 40, 115, 114, 103, 98, 32, 43, 32, 48, 46, 48, 53, 53, 41, 32, 47, 32, 49, 46, 48, 53, 53, 44, 32, 50, 46, 52, 41, 59, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 108, 111, 119, 101, 114, 32, 61, 32, 115, 114, 103, 98, 32, 47, 32, 49, 50, 46, 57, 50, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 51, 32, 99, 117, 116, 111, 102, 102, 32, 61, 32, +115, 116, 101, 112, 40, 115, 114, 103, 98, 44, 32, 48, 46, 48, 52, 48, 52, 53, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 82, 71, 66, 97, 46, 114, 103, 98, 32, 61, 32, 108, 101, 114, 112, 40, 104, 105, 103, 104, 101, 114, 44, 32, 108, 111, 119, 101, 114, 44, 32, 99, 117, +116, 111, 102, 102, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 82, 71, 66, 97, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 21, 0, 81, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, +101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 0, +3, 0, 74, 1, 0, 0, 0, 0, 0, 0, 0, 0, 81, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, +115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, +105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, +116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, +116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 98, 111, 111, 108, 32, 84, 83, 82, 103, 98, 62, 32, +58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, +65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, +116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 84, 83, 82, 103, 98, 41, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 32, 61, 32, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 40, 115, 116, 114, +101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, +115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, +46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, +114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 119, 105, 122, 122, 108, 101, +32, 61, 61, 32, 48, 63, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 58, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 114, 114, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 119, 105, 122, 122, 108, +101, 100, 67, 111, 108, 111, 114, 32, 42, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, +22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, +116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, +62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, +97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, +111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 8, 0, 111, 0, 0, 0, +67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 46, 84, 111, 76, 105, 110, 101, 97, 114, 0, 0, 0, 5, 0, 5, 0, 114, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 50, 0, 0, 0, 5, 0, 7, 0, 121, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, +95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 7, 0, 127, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 48, 53, 51, 48, 54, 48, 49, 49, 0, 0, 0, 5, 0, 7, 0, 129, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 56, 50, 49, 55, 49, 49, 49, 49, 0, 0, 0, +5, 0, 7, 0, 132, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 49, 50, 53, 50, 50, 56, 55, 56, 0, 0, 0, 5, 0, 7, 0, 137, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 51, 0, 5, 0, 7, 0, 153, 0, 0, 0, +112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 4, 0, 154, 0, 0, 0, 115, 82, 71, 66, 97, 0, 0, 0, 5, 0, 4, 0, 156, 0, 0, 0, 115, 82, 71, 66, 0, 0, 0, 0, 5, 0, 4, 0, 174, 0, 0, 0, 105, 110, 116, 95, +51, 0, 0, 0, 5, 0, 4, 0, 186, 0, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 244, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 54, 54, 50, 48, 48, 50, 54, 56, 55, 0, 0, 0, 5, 0, 7, 0, 248, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, +54, 56, 52, 49, 50, 50, 48, 54, 0, 0, 0, 0, 5, 0, 7, 0, 253, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 51, 50, 51, 53, 56, 51, 54, 48, 49, 0, 0, 0, 5, 0, 7, 0, 2, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 50, 50, 53, 52, 49, 49, 52, +55, 0, 0, 0, 5, 0, 5, 0, 19, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 46, 48, 53, 53, 0, 5, 0, 5, 0, 21, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 46, 52, 0, 0, 0, 5, 0, 5, 0, 27, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 53, 53, 0, +5, 0, 5, 0, 32, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 50, 46, 57, 50, 0, 5, 0, 6, 0, 37, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 48, 51, 49, 51, 48, 56, 0, 5, 0, 6, 0, 68, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 48, 52, 48, 52, +53, 0, 0, 0, 5, 0, 4, 0, 83, 1, 0, 0, 84, 83, 82, 103, 98, 0, 0, 0, 5, 0, 9, 0, 87, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, 97, 105, 110, 0, 5, 0, 9, 0, 88, 1, 0, 0, +85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 0, 5, 0, 10, 0, 89, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 83, 104, 97, 100, 105, 110, 103, +0, 0, 0, 0, 5, 0, 5, 0, 112, 1, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 113, 1, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 6, 0, 139, 1, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, +0, 0, 0, 0, 5, 0, 6, 0, 163, 1, 0, 0, 115, 119, 105, 122, 122, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 4, 0, 167, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 6, 0, 171, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 116, 114, 117, 101, +0, 0, 0, 0, 5, 0, 6, 0, 172, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 102, 97, 108, 115, 101, 0, 0, 0, 5, 0, 6, 0, 170, 1, 0, 0, 116, 101, 114, 110, 97, 114, 121, 95, 109, 101, 114, 103, 101, 0, 0, 0, 5, 0, 7, 0, 183, 1, 0, 0, 112, 116, 114, 95, +79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 182, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 185, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, +111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 184, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 187, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, +186, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 189, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 5, 0, 6, 0, 188, 1, 0, 0, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, +5, 0, 5, 0, 190, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 190, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 190, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, +6, 0, 5, 0, 190, 1, 0, 0, 2, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 191, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 191, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, +5, 0, 5, 0, 192, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 192, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 192, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, +0, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 192, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 193, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 194, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 11, 0, 195, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 80, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 198, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 201, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 204, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 5, 0, 4, 0, +208, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 210, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 211, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, +114, 100, 0, 0, 5, 0, 7, 0, 213, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 212, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 214, 1, 0, 0, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 215, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 216, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 6, 0, +217, 1, 0, 0, 105, 110, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 0, 0, 5, 0, 7, 0, 219, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 0, 0, 0, 0, 5, 0, 6, 0, 218, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, +119, 105, 122, 122, 108, 101, 0, 0, 5, 0, 5, 0, 220, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 220, 1, 0, 0, 1, 0, 0, 0, +80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 220, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 221, 1, 0, 0, 86, 83, 95, 79, +85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 221, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 221, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, +221, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 221, 1, 0, 0, 3, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 5, 0, 222, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 222, 1, 0, 0, +0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 222, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 222, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, +0, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 6, 0, 5, 0, 222, 1, 0, 0, 4, 0, 0, 0, 83, 119, 105, 122, 122, 108, 101, 0, 5, 0, 8, 0, 223, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 224, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 11, 0, 225, 1, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, 101, 62, 46, 86, 83, 77, +97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 5, 0, 4, 0, 234, 1, 0, 0, 105, 110, 116, 95, 52, 0, 0, 0, 71, 0, 4, 0, 182, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 184, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, +184, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 186, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 186, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 188, 1, 0, 0, +30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 188, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 210, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 211, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 0, 22, 6, 0, 211, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 212, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 212, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, +48, 0, 0, 0, 71, 0, 4, 0, 214, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 214, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 215, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, +215, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 216, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 216, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 217, 1, 0, 0, 30, 0, 0, 0, +3, 0, 0, 0, 0, 22, 7, 0, 217, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 218, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 7, 0, 218, 1, 0, 0, 3, 22, 0, 0, 66, 65, 84, 67, +72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, +32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, +19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, +0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, +114, 0, 0, 0, 205, 204, 12, 64, 32, 0, 4, 0, 121, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 4, 0, 120, 0, 0, 0, 5, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 127, 0, 0, 0, 18, 81, 156, 62, 43, 0, 4, 0, 5, 0, 0, 0, +129, 0, 0, 0, 196, 162, 46, 63, 43, 0, 4, 0, 5, 0, 0, 0, 132, 0, 0, 0, 194, 44, 77, 60, 23, 0, 4, 0, 135, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 7, 0, 0, 0, 135, 0, 0, 0, 33, 0, 4, 0, 136, 0, 0, 0, +135, 0, 0, 0, 137, 0, 0, 0, 32, 0, 4, 0, 153, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 4, 0, 152, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 21, 0, 4, 0, 173, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, +174, 0, 0, 0, 3, 0, 0, 0, 33, 0, 5, 0, 178, 0, 0, 0, 4, 0, 0, 0, 153, 0, 0, 0, 121, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 186, 0, 0, 0, 0, 0, 128, 63, 43, 0, 4, 0, 5, 0, 0, 0, 244, 0, 0, 0, 2, 121, 41, 63, 43, 0, 4, 0, +5, 0, 0, 0, 248, 0, 0, 0, 160, 34, 47, 63, 43, 0, 4, 0, 5, 0, 0, 0, 253, 0, 0, 0, 192, 172, 165, 62, 43, 0, 4, 0, 5, 0, 0, 0, 2, 1, 0, 0, 54, 168, 184, 60, 43, 0, 4, 0, 5, 0, 0, 0, 19, 1, 0, 0, 61, 10, 135, 63, 43, 0, 4, 0, +5, 0, 0, 0, 21, 1, 0, 0, 154, 153, 25, 64, 43, 0, 4, 0, 5, 0, 0, 0, 27, 1, 0, 0, 174, 71, 97, 61, 43, 0, 4, 0, 5, 0, 0, 0, 32, 1, 0, 0, 82, 184, 78, 65, 43, 0, 4, 0, 5, 0, 0, 0, 37, 1, 0, 0, 28, 46, 77, 59, 43, 0, 4, 0, +5, 0, 0, 0, 68, 1, 0, 0, 230, 174, 37, 61, 41, 0, 3, 0, 8, 0, 0, 0, 83, 1, 0, 0, 33, 0, 3, 0, 135, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 160, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 167, 1, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 183, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 185, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 187, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 189, 1, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, +30, 0, 5, 0, 190, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 3, 0, 191, 1, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 192, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 193, 1, 0, 0, +6, 0, 0, 0, 192, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 198, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 201, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 204, 1, 0, 0, 3, 0, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, +208, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 213, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 219, 1, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 30, 0, 6, 0, 220, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, +30, 0, 6, 0, 221, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 30, 0, 7, 0, 222, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 32, 0, 4, 0, 223, 1, 0, 0, 6, 0, 0, 0, +222, 1, 0, 0, 43, 0, 4, 0, 173, 0, 0, 0, 234, 1, 0, 0, 4, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 182, 1, 0, 0, +3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 184, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 186, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 193, 1, 0, 0, 194, 1, 0, 0, +6, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 210, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 185, 1, 0, 0, 211, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 213, 1, 0, 0, 212, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 214, 1, 0, 0, +1, 0, 0, 0, 59, 0, 4, 0, 187, 1, 0, 0, 215, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 183, 1, 0, 0, 216, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 189, 1, 0, 0, 217, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 219, 1, 0, 0, 218, 1, 0, 0, +3, 0, 0, 0, 59, 0, 4, 0, 223, 1, 0, 0, 224, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, +11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 6, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 0, 55, 0, 3, 0, 153, 0, 0, 0, +154, 0, 0, 0, 248, 0, 2, 0, 155, 0, 0, 0, 59, 0, 4, 0, 137, 0, 0, 0, 156, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 157, 0, 0, 0, 154, 0, 0, 0, 79, 0, 8, 0, +135, 0, 0, 0, 158, 0, 0, 0, 157, 0, 0, 0, 157, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 62, 0, 3, 0, 156, 0, 0, 0, 158, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, +159, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 160, 0, 0, 0, 156, 0, 0, 0, 61, 0, 4, 0, 135, 0, 0, 0, 161, 0, 0, 0, 156, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 163, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, 127, 0, 0, 0, +133, 0, 5, 0, 135, 0, 0, 0, 162, 0, 0, 0, 161, 0, 0, 0, 163, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 165, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 164, 0, 0, 0, 162, 0, 0, 0, 165, 0, 0, 0, +133, 0, 5, 0, 135, 0, 0, 0, 166, 0, 0, 0, 160, 0, 0, 0, 164, 0, 0, 0, 80, 0, 6, 0, 135, 0, 0, 0, 168, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 132, 0, 0, 0, 129, 0, 5, 0, 135, 0, 0, 0, 167, 0, 0, 0, 166, 0, 0, 0, 168, 0, 0, 0, +133, 0, 5, 0, 135, 0, 0, 0, 169, 0, 0, 0, 159, 0, 0, 0, 167, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 0, 0, 0, 0, 81, 0, 5, 0, 5, 0, 0, 0, 171, 0, 0, 0, 169, 0, 0, 0, 1, 0, 0, 0, 81, 0, 5, 0, +5, 0, 0, 0, 172, 0, 0, 0, 169, 0, 0, 0, 2, 0, 0, 0, 65, 0, 5, 0, 121, 0, 0, 0, 175, 0, 0, 0, 154, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 175, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 177, 0, 0, 0, +170, 0, 0, 0, 171, 0, 0, 0, 172, 0, 0, 0, 176, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 32, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +108, 0, 0, 0, 40, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 47, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 60, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 72, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, +81, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, +30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 101, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 121, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +108, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 110, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 111, 1, 0, 0, 110, 1, 0, 0, 62, 0, 3, 0, 108, 1, 0, 0, 111, 1, 0, 0, 8, 0, 4, 0, +81, 1, 0, 0, 18, 0, 0, 0, 9, 0, 0, 0, 247, 0, 3, 0, 113, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 83, 1, 0, 0, 112, 1, 0, 0, 113, 1, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 20, 0, 0, 0, 13, 0, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 123, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 121, 1, 0, 0, +124, 1, 0, 0, 57, 0, 5, 0, 4, 0, 0, 0, 126, 1, 0, 0, 111, 0, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 126, 1, 0, 0, 249, 0, 2, 0, 113, 1, 0, 0, 248, 0, 2, 0, 113, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, +81, 1, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 88, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 128, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +133, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 137, 1, 0, 0, 89, 1, 0, 0, 62, 0, 3, 0, 133, 1, 0, 0, 137, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 81, 1, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, +54, 0, 5, 0, 4, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 135, 1, 0, 0, 248, 0, 2, 0, 138, 1, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 139, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 153, 0, 0, 0, 163, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, +153, 0, 0, 0, 169, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 32, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 150, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 157, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 158, 1, 0, 0, 157, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 159, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 160, 1, 0, 0, 161, 1, 0, 0, 159, 1, 0, 0, 150, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 162, 1, 0, 0, +161, 1, 0, 0, 158, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 139, 1, 0, 0, 162, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 165, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 166, 1, 0, 0, 165, 1, 0, 0, 180, 0, 5, 0, 8, 0, 0, 0, 168, 1, 0, 0, 166, 1, 0, 0, 167, 1, 0, 0, 247, 0, 3, 0, 170, 1, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 168, 1, 0, 0, 171, 1, 0, 0, 172, 1, 0, 0, 248, 0, 2, 0, +171, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 173, 1, 0, 0, 139, 1, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 173, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 172, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 174, 1, 0, 0, 139, 1, 0, 0, +79, 0, 9, 0, 4, 0, 0, 0, 175, 1, 0, 0, 174, 1, 0, 0, 174, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 169, 1, 0, 0, 175, 1, 0, 0, 249, 0, 2, 0, 170, 1, 0, 0, 248, 0, 2, 0, 170, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 176, 1, 0, 0, 169, 1, 0, 0, 62, 0, 3, 0, 163, 1, 0, 0, 176, 1, 0, 0, 8, 0, 4, 0, 81, 1, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 177, 1, 0, 0, 163, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 179, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 180, 1, 0, 0, 179, 1, 0, 0, 133, 0, 5, 0, 4, 0, 0, 0, 181, 1, 0, 0, 177, 1, 0, 0, 180, 1, 0, 0, 254, 0, 2, 0, 181, 1, 0, 0, 56, 0, 1, 0, +54, 0, 5, 0, 30, 0, 0, 0, 195, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 196, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 197, 1, 0, 0, 194, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 199, 1, 0, 0, 184, 1, 0, 0, +62, 0, 3, 0, 197, 1, 0, 0, 199, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 200, 1, 0, 0, 194, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 202, 1, 0, 0, 186, 1, 0, 0, 62, 0, 3, 0, 200, 1, 0, 0, 202, 1, 0, 0, 65, 0, 5, 0, +18, 0, 0, 0, 203, 1, 0, 0, 194, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 1, 0, 0, 188, 1, 0, 0, 62, 0, 3, 0, 203, 1, 0, 0, 205, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 206, 1, 0, 0, 88, 1, 0, 0, 65, 0, 5, 0, +3, 0, 0, 0, 207, 1, 0, 0, 194, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 209, 1, 0, 0, 207, 1, 0, 0, 62, 0, 3, 0, 182, 1, 0, 0, 209, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 225, 1, 0, 0, +0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 226, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 227, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 228, 1, 0, 0, 211, 1, 0, 0, 62, 0, 3, 0, 227, 1, 0, 0, 228, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 229, 1, 0, 0, 224, 1, 0, 0, 201, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 230, 1, 0, 0, 214, 1, 0, 0, 62, 0, 3, 0, 229, 1, 0, 0, 230, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 231, 1, 0, 0, 224, 1, 0, 0, +204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 232, 1, 0, 0, 215, 1, 0, 0, 62, 0, 3, 0, 231, 1, 0, 0, 232, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 233, 1, 0, 0, 224, 1, 0, 0, 234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 235, 1, 0, 0, +217, 1, 0, 0, 62, 0, 3, 0, 233, 1, 0, 0, 235, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 236, 1, 0, 0, 87, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 237, 1, 0, 0, 224, 1, 0, 0, 208, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 238, 1, 0, 0, +237, 1, 0, 0, 62, 0, 3, 0, 210, 1, 0, 0, 238, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 239, 1, 0, 0, 224, 1, 0, 0, 198, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 240, 1, 0, 0, 239, 1, 0, 0, 62, 0, 3, 0, 212, 1, 0, 0, 240, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 241, 1, 0, 0, 224, 1, 0, 0, 204, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 242, 1, 0, 0, 241, 1, 0, 0, 62, 0, 3, 0, 216, 1, 0, 0, 242, 1, 0, 0, 65, 0, 5, 0, 18, 0, 0, 0, 243, 1, 0, 0, 224, 1, 0, 0, +234, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 244, 1, 0, 0, 243, 1, 0, 0, 62, 0, 3, 0, 218, 1, 0, 0, 244, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } From 14399fa4c6dc8b089bd3b4bb5ef17863f361aa70 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 12:01:59 +0900 Subject: [PATCH 1054/1182] ci: pass StrideGraphicsApi to Windows game test matrix Without the singular form, Stride.Graphics.props defaults it to Direct3D11 before the test SDK can derive it from StrideGraphicsApis. --- .github/workflows/test-windows-game.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index 9847183663..ce01956503 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -160,7 +160,8 @@ jobs: -v:m -p:WarningLevel=0 ` -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} ` -p:StridePlatforms=Windows ` - -p:StrideGraphicsApis=${{ matrix.graphics-api }} + -p:StrideGraphicsApis=${{ matrix.graphics-api }} ` + -p:StrideGraphicsApi=${{ matrix.graphics-api }} - name: Test run: | dotnet test build\Stride.Tests.Game.GPU.slnf ` @@ -168,6 +169,7 @@ jobs: --logger:trx --results-directory TestResults ` -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} ` -p:StrideGraphicsApis=${{ matrix.graphics-api }} ` + -p:StrideGraphicsApi=${{ matrix.graphics-api }} ` -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() From 6c6e31c5306175365ffddf1cdeaeacbdd3577544 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 17:37:58 +0900 Subject: [PATCH 1055/1182] chore: regenerated default shaders bytecodes --- .../Shaders.Bytecodes/CompileShaders.cmd | 7 +- ...riteBatch.bytecode.Direct3D11.Level_9_1.cs | 56 +- ...riteBatch.bytecode.Direct3D12.Level_9_1.cs | 208 ++- .../SpriteBatch.bytecode.Vulkan.Level_9_1.cs | 2 +- ...Batch.bytecodeSRgb.Direct3D11.Level_9_1.cs | 52 +- ...Batch.bytecodeSRgb.Direct3D12.Level_9_1.cs | 212 ++- ...riteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs | 2 +- ...iteEffect.bytecode.Direct3D11.Level_9_1.cs | 62 +- ...iteEffect.bytecode.Direct3D12.Level_9_1.cs | 168 ++- .../SpriteEffect.bytecode.Vulkan.Level_9_1.cs | 2 +- .../UIEffect.bytecode.Direct3D11.Level_9_1.cs | 50 +- .../UIEffect.bytecode.Direct3D12.Level_9_1.cs | 154 +-- .../UIEffect.bytecode.Vulkan.Level_9_1.cs | 2 +- ...ffect.bytecodeSRgb.Direct3D11.Level_9_1.cs | 52 +- ...ffect.bytecodeSRgb.Direct3D12.Level_9_1.cs | 156 ++- .../UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs | 2 +- .../Shaders093.Bytecodes/CompileShaders.cmd | 6 +- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 796 ++++++----- ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 152 +- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 1188 ++++++++-------- ...eFieldFontBytecode.Direct3D11.Level_9_3.cs | 886 ++++++------ ...eFieldFontBytecode.Direct3D12.Level_9_3.cs | 180 ++- ...tanceFieldFontBytecode.Vulkan.Level_9_3.cs | 1222 ++++++++--------- 23 files changed, 2797 insertions(+), 2820 deletions(-) diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd index 32aadf5087..661e0913f0 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/CompileShaders.cmd @@ -2,8 +2,7 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -rmdir /s /q %~dp0obj\ +rmdir /s /q %~dp0obj\ 2>nul %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs index 6fec54d81b..f9710d217f 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -36,11 +36,11 @@ public partial class SpriteBatch 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, -65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 174, 205, 158, 188, 123, 235, 202, 149, 71, 78, 196, 231, 105, 150, 145, 241, 0, 212, 89, 0, 0, 68, 88, 66, 67, 203, 64, 10, 185, 180, 138, 80, 98, 98, 89, 110, 95, 238, 6, 39, 127, 1, 0, +65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 89, 186, 101, 79, 222, 60, 218, 51, 177, 175, 81, 169, 181, 249, 111, 151, 0, 212, 89, 0, 0, 68, 88, 66, 67, 189, 13, 12, 241, 249, 70, 243, 103, 122, 245, 131, 85, 44, 153, 84, 57, 1, 0, 0, 0, 212, 89, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, -121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, 49, 56, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, +121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 56, 51, 57, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, 0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, @@ -116,7 +116,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 95, 142, 239, 253, 41, 117, 123, 65, 170, 59, 244, 190, 114, 112, 136, 242, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 18, 44, 7, 181, 213, 204, 99, 78, 169, 78, 58, 99, 51, 249, 121, 65, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -133,7 +133,7 @@ public partial class SpriteBatch 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, -0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 46, 126, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 235, 30, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 124, 13, 1, 0, 149, 49, 3, 0, 125, 218, 1, 0, 106, 139, 0, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -189,14 +189,14 @@ public partial class SpriteBatch 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 109, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, -49, 56, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, -100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 56, 54, 49, 56, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 56, +51, 57, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, +100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 48, 102, 102, 56, 51, 57, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 62, 17, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 114, 94, 190, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 76, 199, 113, 166, 184, 11, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -259,8 +259,8 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, -24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 32, 80, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, -0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 112, 123, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 32, 96, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, +0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 32, 96, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 63, 184, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -302,7 +302,7 @@ public partial class SpriteBatch 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -361,13 +361,13 @@ public partial class SpriteBatch 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, -92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 56, 54, 49, 56, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 56, 51, 57, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 95, 142, 239, 253, 41, 117, 123, 65, 170, 59, 244, 190, 114, 112, 136, 242, 134, 0, 0, 0, 47, 76, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 18, 44, 7, 181, 213, 204, 99, 78, 169, 78, 58, 99, 51, 249, 121, 65, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 56, 54, -49, 56, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, +92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 48, 102, 102, 56, +51, 57, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -396,11 +396,11 @@ public partial class SpriteBatch 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, -1, 0, 0, 0, 1, 23, 131, 166, 24, 217, 203, 25, 144, 208, 41, 94, 196, 172, 114, 40, 12, 0, 76, 87, 0, 0, 68, 88, 66, 67, 235, 87, 8, 75, 164, 122, 157, 160, 171, 179, 75, 16, 88, 194, 82, 81, 1, 0, 0, 0, 76, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, +1, 0, 0, 0, 1, 242, 213, 10, 130, 56, 86, 125, 12, 93, 29, 180, 196, 243, 19, 110, 238, 0, 76, 87, 0, 0, 68, 88, 66, 67, 222, 15, 22, 31, 190, 217, 21, 254, 85, 2, 171, 254, 69, 63, 255, 39, 1, 0, 0, 0, 76, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 56, 5, 0, 0, 168, 6, 0, 0, 176, 84, 0, 0, 44, 85, 0, 0, 252, 85, 0, 0, 172, 86, 0, 0, 65, 111, 110, 57, 244, 4, 0, 0, 244, 4, 0, 0, 0, 2, 254, 255, 192, 4, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 250, 0, 68, 66, 85, 71, 40, 0, 0, 0, 188, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 15, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 128, 3, 0, 0, 0, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 65, 66, 48, 57, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 52, 65, 48, 50, 53, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 0, 0, 255, 255, 252, 3, 0, 0, 0, 0, 255, 255, 8, 4, 0, 0, 0, 0, 255, 255, 20, 4, 0, 0, 0, 0, 255, 255, 32, 4, 0, 0, 90, 0, 0, 0, 44, 4, 0, 0, 90, 0, 0, 0, 60, 4, 0, 0, 90, 0, 0, 0, 76, 4, 0, 0, 90, 0, 0, 0, 92, 4, 0, 0, 124, 0, 0, 0, 108, 4, 0, 0, 124, 0, 0, 0, 128, 4, 0, 0, 126, 0, 0, 0, 140, 4, 0, 0, 126, 0, 0, 0, 152, 4, 0, 0, 128, 0, 0, 0, 164, 4, 0, 0, 129, 0, 0, 0, 176, 4, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, @@ -463,7 +463,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 135, 248, 128, 150, 34, 27, 38, 73, 182, 255, 68, 231, 244, 93, 4, 150, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 80, 137, 20, 131, 189, 72, 111, 69, 143, 48, 111, 82, 44, 240, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -544,14 +544,14 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 26, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, -105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 65, 66, 48, 57, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, -111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, -97, 56, 51, 101, 97, 98, 48, 57, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 52, 65, 48, 50, 53, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, +111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, +100, 52, 49, 52, 97, 48, 50, 53, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 21, 176, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 0, 71, 192, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 195, 56, 168, 248, 101, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -644,7 +644,7 @@ public partial class SpriteBatch 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 3, 16, 0, 0, 100, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 12, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 20, 0, 0, 0, 0, 0, @@ -699,13 +699,13 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 128, 4, 0, 0, 0, 0, 0, 0, 72, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 104, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 104, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, -99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, -69, 65, 66, 48, 57, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, +52, 65, 48, 50, 53, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 135, 248, 128, 150, 34, 27, 38, 73, 182, 255, 68, 231, 244, 93, 4, 150, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 80, 137, 20, 131, 189, 72, 111, 69, 143, 48, 111, 82, 44, 240, 0, 100, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, -105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 97, 98, 48, 57, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, +105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 52, 97, 48, 50, 53, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs index 8d59faecba..b9156b2de0 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Direct3D12.Level_9_1.cs @@ -21,111 +21,109 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, -0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, -105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 163, 199, 239, 174, 159, 178, 84, 108, 213, 29, 36, 80, 46, 217, 119, 84, 0, 230, 10, 0, 0, 68, 88, 66, 67, 132, 21, 53, 37, 64, 61, 183, 172, 137, 120, 56, 16, 111, 194, -17, 150, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, -0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, -0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, -20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, -7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, -73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, -65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, -62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, 0, 0, 24, 0, -0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, 12, 4, 0, 0, -19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, -48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, -7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 30, 32, 0, 4, -0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, -0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 0, -0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, 134, 6, 0, 0, -0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, 130, 96, 48, 162, -42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, 108, 16, 2, 101, -67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, 112, 115, 19, 4, -160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, -16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, 128, 13, 132, 24, -148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 120, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 102, 97, 108, -115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, -0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, -92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 232, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, -197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 158, 225, 242, 157, 199, 167, 26, 32, 194, 252, 226, 182, 109, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 35, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 173, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, -165, 166, 135, 154, 252, 226, 182, 1, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, -156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, 101, 192, 121, 35, -6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, 224, 130, 97, 150, -33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, 70, 19, 6, 97, -52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, 96, 52, 33, 0, -70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, 129, 29, 109, 32, -1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, 49, 75, 96, 12, -84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, 17, 117, 32, 1, -35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 97, 22, 132, 17, -131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 117, 113, 5, 93, 209, 38, 77, 200, 125, 107, 234, 233, 96, 184, 112, 97, 0, 181, 11, 0, 0, 68, 88, 66, 67, 67, 154, 77, 181, 29, 94, 23, 148, 252, 83, 211, 156, -25, 235, 105, 219, 1, 0, 0, 0, 181, 11, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, -69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, -67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, -0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, -0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 0, 8, 0, 0, 96, 0, 1, 0, 0, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 232, 7, 0, 0, 66, 67, 192, -222, 33, 12, 0, 0, 247, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, -8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, -32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, -80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, -0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, -32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, -109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, -32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, -0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, -71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, 2, 43, 133, 98, -160, 3, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 121, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, -185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 192, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, -27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 35, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 180, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, -124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, 2, 101, 130, 112, 48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, 11, 203, 52, 66, -11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, 152, 129, 24, 96, 0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, 136, 78, 193, 128, -13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 158, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, 153, 28, 143, 89, 24, 219, 92, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, 56, 128, 128, 42, -108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, 102, 87, 38, 55, 37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, 46, 114, 101, 115, -111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 112, 6, -83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 235, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 164, 225, 242, 157, 199, 23, 34, 2, 152, 136, 16, 104, -134, 133, 176, 129, 109, 184, 124, 231, 241, 133, 128, 42, 10, 34, 42, 29, 96, 40, 9, 3, 16, 48, 191, 184, 109, 35, 168, 134, 203, 119, 30, 95, 154, 156, 136, 64, 169, 233, 161, 38, 191, 184, 109, 0, 0, 97, 32, 0, 0, 171, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 154, -84, 85, 80, 52, 98, 144, 0, 32, 8, 6, 200, 54, 89, 22, 36, 141, 24, 36, 0, 8, 130, 1, 194, 81, 214, 37, 77, 35, 6, 9, 0, 130, 96, 128, 116, 213, 133, 73, 212, 136, 65, 2, 128, 32, 24, 32, 158, 133, 101, 82, 53, 98, 144, 0, 32, 8, 6, 200, 119, 101, 154, 100, 141, 24, -36, 0, 8, 130, 1, 2, 6, 152, 180, 89, 215, 136, 65, 2, 128, 32, 24, 32, 97, 144, 77, 156, 133, 141, 24, 36, 0, 8, 130, 1, 34, 6, 26, 213, 89, 217, 136, 65, 2, 128, 32, 24, 32, 99, 176, 85, 158, 165, 141, 24, 36, 0, 8, 130, 1, 66, 6, 92, 245, 105, 219, 136, 65, 2, -128, 32, 24, 32, 101, 208, 89, 96, 160, 113, 35, 6, 9, 0, 130, 96, 128, 152, 129, 119, 133, 129, 214, 141, 24, 36, 0, 8, 130, 1, 114, 6, 31, 38, 6, 154, 55, 98, 144, 0, 32, 8, 6, 8, 26, 128, 1, 24, 140, 129, 247, 141, 24, 36, 0, 8, 130, 1, 131, 6, 89, 71, 6, 100, -128, 85, 25, 136, 1, 142, 24, 28, 0, 8, 130, 129, 147, 6, 153, 16, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 26, 116, 80, 65, 26, 224, 136, 193, 1, 128, 32, 24, 56, 112, 0, 6, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 114, -48, 6, 80, 1, 28, 224, 136, 193, 1, 128, 32, 24, 56, 119, 112, 6, 80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 121, 144, 6, 80, 193, 29, 224, 136, 193, 1, 128, 32, 24, 56, 126, 224, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, -96, 150, 25, 72, 192, 160, 51, 144, 128, 41, 104, 32, 1, 35, 210, 64, 2, 182, 173, 129, 4, 44, 40, 32, 96, 86, 27, 72, 192, 2, 3, 2, 22, 189, 129, 4, 44, 56, 32, 96, 76, 28, 72, 192, 2, 4, 2, 70, 6, 116, 32, 1, 11, 16, 8, 216, 103, 7, 18, 176, 0, 129, 128, 105, -120, 32, 1, 11, 16, 8, 88, 165, 7, 18, 176, 0, 129, 128, 181, 65, 31, 72, 192, 2, 4, 2, 134, 6, 127, 32, 1, 11, 16, 8, 216, 24, 132, 130, 4, 44, 64, 32, 96, 222, 40, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 220, 194, 49, 98, 144, -0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 130, 45, 20, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 212, 194, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 2, 45, 4, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 240, 2, 47, 220, 194, 41, 140, 24, 36, 0, -8, 130, 193, 227, 11, 171, 192, 11, 188, 96, 11, 166, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 46, 240, 194, 45, 132, 194, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 187, 192, 11, 182, 0, 10, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 236, 2, 47, 212, 194, 31, 140, 24, 36, -0, 8, 130, 193, 227, 11, 171, 176, 11, 188, 64, 11, 126, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 44, 240, 194, 45, 244, 193, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 179, 192, 11, 182, 192, 7, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 204, 2, 47, 212, 194, 30, 140, 24, -36, 0, 8, 130, 193, 227, 11, 171, 48, 11, 188, 64, 11, 122, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 130, 44, 240, 194, 45, 228, 1, 2, 0, 0, 0, 0, 0, 1, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, +4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, +121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 163, 199, 239, 174, 159, 178, 84, 108, 213, 29, 36, 80, 46, 217, 119, 84, 0, 230, 10, 0, 0, 68, 88, 66, 67, 132, 21, 53, 37, 64, 61, 183, 172, 137, 120, +56, 16, 111, 194, 17, 150, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, +0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, +0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, +2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, +25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, +9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, +129, 144, 64, 49, 65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, +7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, +0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, +12, 4, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, +113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, +160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, +30, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, +1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, +196, 127, 129, 0, 0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, +134, 6, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, +130, 96, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, +108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, +112, 115, 19, 4, 160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, +65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, +128, 13, 132, 24, 148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 120, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, +60, 102, 97, 108, 115, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, +93, 153, 220, 148, 0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, +75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 232, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, +46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 158, 225, 242, 157, 199, 167, 26, 32, 194, 252, 226, 182, 109, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 35, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 173, 160, 26, 46, 223, 121, 124, +105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, +0, 130, 96, 176, 156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, +101, 192, 121, 35, 6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, +224, 130, 97, 150, 33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, +70, 19, 6, 97, 52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, +96, 52, 33, 0, 70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, +129, 29, 109, 32, 1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, +49, 75, 96, 12, 84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, +17, 117, 32, 1, 35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, +97, 22, 132, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 117, 113, 5, 93, 209, 38, 77, 200, 125, 107, 234, 233, 96, 184, 112, 97, 0, 181, 11, 0, 0, 68, 88, 66, 67, 67, 154, 77, 181, 29, 94, 23, 148, +252, 83, 211, 156, 25, 235, 105, 219, 1, 0, 0, 0, 181, 11, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, +5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, +15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, +0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, +0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, +0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 0, 8, 0, 0, 96, 0, 1, 0, 0, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 232, 7, 0, +0, 66, 67, 192, 222, 33, 12, 0, 0, 247, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, +96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, +255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, +160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, +0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, +128, 0, 0, 0, 32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, +7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, +109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, +8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, +144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, +2, 43, 133, 98, 160, 3, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 121, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, +16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 192, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, +1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 35, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 180, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, +4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, 2, 101, 130, 112, 48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, +11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, 152, 129, 24, 96, 0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, +136, 78, 193, 128, 13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 158, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, 153, 28, 143, 89, 24, 219, 92, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, +56, 128, 128, 42, 108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, 102, 87, 38, 55, 37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, +46, 114, 101, 115, 111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, 231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 0, 0, 0, 113, 32, 0, 0, 28, 0, 0, +0, 5, 112, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 158, 57, 204, 158, 151, 125, 46, 235, 180, 25, 78, 187, 191, 87, 121, 24, 14, 47, 203, 45, 96, 26, 46, 223, 121, 252, 197, 1, 6, 177, 121, 168, 201, 47, 110, 219, 4, 164, 225, 242, 157, 199, 23, 34, 2, +152, 136, 16, 104, 134, 133, 176, 129, 109, 184, 124, 231, 241, 133, 128, 42, 10, 34, 42, 29, 96, 40, 9, 3, 16, 48, 191, 184, 109, 35, 168, 134, 203, 119, 30, 95, 154, 156, 136, 64, 169, 233, 161, 38, 191, 184, 109, 0, 0, 97, 32, 0, 0, 171, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, +32, 24, 32, 154, 84, 85, 80, 52, 98, 144, 0, 32, 8, 6, 200, 54, 89, 22, 36, 141, 24, 36, 0, 8, 130, 1, 194, 81, 214, 37, 77, 35, 6, 9, 0, 130, 96, 128, 116, 213, 133, 73, 212, 136, 65, 2, 128, 32, 24, 32, 158, 133, 101, 82, 53, 98, 144, 0, 32, 8, 6, 200, 119, 101, +154, 100, 141, 24, 36, 0, 8, 130, 1, 2, 6, 152, 180, 89, 215, 136, 65, 2, 128, 32, 24, 32, 97, 144, 77, 156, 133, 141, 24, 36, 0, 8, 130, 1, 34, 6, 26, 213, 89, 217, 136, 65, 2, 128, 32, 24, 32, 99, 176, 85, 158, 165, 141, 24, 36, 0, 8, 130, 1, 66, 6, 92, 245, 105, +219, 136, 65, 2, 128, 32, 24, 32, 101, 208, 89, 96, 160, 113, 35, 6, 9, 0, 130, 96, 128, 152, 129, 119, 133, 129, 214, 141, 24, 36, 0, 8, 130, 1, 114, 6, 31, 38, 6, 154, 55, 98, 144, 0, 32, 8, 6, 8, 26, 128, 1, 24, 140, 129, 247, 141, 24, 36, 0, 8, 130, 1, 131, 6, +89, 71, 6, 100, 128, 85, 25, 136, 1, 142, 24, 28, 0, 8, 130, 129, 147, 6, 153, 16, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 26, 116, 80, 65, 26, 224, 136, 193, 1, 128, 32, 24, 56, 112, 0, 6, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, +9, 196, 80, 114, 48, 6, 80, 1, 28, 224, 136, 193, 1, 128, 32, 24, 56, 119, 112, 6, 80, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 121, 144, 6, 80, 193, 29, 224, 136, 193, 1, 128, 32, 24, 56, 126, 224, 6, 87, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, +8, 163, 9, 196, 96, 150, 25, 72, 192, 160, 51, 144, 128, 41, 104, 32, 1, 35, 210, 64, 2, 182, 173, 129, 4, 44, 40, 32, 96, 86, 27, 72, 192, 2, 3, 2, 22, 189, 129, 4, 44, 56, 32, 96, 76, 28, 72, 192, 2, 4, 2, 70, 6, 116, 32, 1, 11, 16, 8, 216, 103, 7, 18, 176, +0, 129, 128, 105, 120, 32, 1, 11, 16, 8, 88, 165, 7, 18, 176, 0, 129, 128, 181, 65, 31, 72, 192, 2, 4, 2, 134, 6, 127, 32, 1, 11, 16, 8, 216, 24, 132, 130, 4, 44, 64, 32, 96, 222, 40, 72, 192, 2, 4, 2, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 220, +194, 49, 98, 144, 0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 130, 45, 20, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 228, 2, 47, 212, 194, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 66, 46, 240, 2, 45, 4, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 240, 2, 47, 220, 194, 41, +140, 24, 36, 0, 8, 130, 193, 227, 11, 171, 192, 11, 188, 96, 11, 166, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 46, 240, 194, 45, 132, 194, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 187, 192, 11, 182, 0, 10, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 236, 2, 47, 212, 194, +31, 140, 24, 36, 0, 8, 130, 193, 227, 11, 171, 176, 11, 188, 64, 11, 126, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 194, 44, 240, 194, 45, 244, 193, 136, 65, 2, 128, 32, 24, 60, 190, 176, 10, 179, 192, 11, 182, 192, 7, 35, 6, 9, 0, 130, 96, 240, 248, 194, 42, 204, 2, 47, 212, +194, 30, 140, 24, 36, 0, 8, 130, 193, 227, 11, 171, 48, 11, 188, 64, 11, 122, 48, 98, 144, 0, 32, 8, 6, 143, 47, 172, 130, 44, 240, 194, 45, 228, 1, 2, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs index 895262d66a..ccbbf077e0 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs index d4ff445b13..05494aae6d 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -36,11 +36,11 @@ public partial class SpriteBatch 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, -65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 44, 221, 241, 81, 241, 33, 215, 45, 200, 53, 238, 148, 98, 130, 170, 208, 0, 212, 89, 0, 0, 68, 88, 66, 67, 111, 133, 219, 51, 141, 56, 50, 214, 61, 220, 173, 190, 134, 58, 210, 67, 1, 0, +65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 1, 214, 116, 200, 1, 100, 205, 233, 57, 189, 251, 96, 169, 175, 250, 38, 0, 212, 89, 0, 0, 68, 88, 66, 67, 162, 177, 194, 174, 205, 14, 84, 167, 136, 33, 76, 190, 47, 36, 252, 146, 1, 0, 0, 0, 212, 89, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 36, 7, 0, 0, 236, 9, 0, 0, 244, 87, 0, 0, 112, 88, 0, 0, 36, 89, 0, 0, 160, 89, 0, 0, 65, 111, 110, 57, 224, 6, 0, 0, 224, 6, 0, 0, 0, 2, 255, 255, 184, 6, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 29, 1, 68, 66, 85, 71, 40, 0, 0, 0, 72, 4, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 36, 0, 0, 0, 136, 0, 0, 0, 9, 0, 0, 0, 148, 3, 0, 0, 20, 2, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, -121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, 65, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, +121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 52, 53, 54, 48, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 124, 4, 0, 0, 0, 0, 255, 255, 148, 4, 0, 0, 0, 0, 255, 255, 172, 4, 0, 0, 0, 0, 255, 255, 184, 4, 0, 0, 0, 0, 255, 255, 196, 4, 0, 0, 0, 0, 255, 255, 208, 4, 0, 0, 77, 0, 0, 0, 220, 4, 0, 0, 92, 0, 0, 0, 236, 4, 0, 0, 92, 0, 0, 0, 252, 4, 0, 0, 83, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 36, 5, 0, 0, 90, 0, 0, 0, 52, 5, 0, 0, 95, 0, 0, 0, 72, 5, 0, 0, 97, 0, 0, 0, 92, 5, 0, 0, 94, 0, 0, 0, 108, 5, 0, 0, 97, 0, 0, 0, 128, 5, 0, 0, 97, 0, 0, 0, 148, 5, 0, 0, 97, 0, 0, 0, 160, 5, 0, 0, 97, 0, 0, 0, 172, 5, 0, 0, 98, 0, 0, 0, 188, 5, 0, 0, 99, 0, 0, 0, 208, 5, 0, 0, 99, 0, 0, 0, 220, 5, 0, 0, 99, 0, 0, 0, 240, 5, 0, 0, 100, 0, 0, 0, 4, 6, 0, 0, 100, 0, 0, 0, 20, 6, 0, 0, 100, 0, 0, 0, 32, 6, @@ -116,7 +116,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 156, 151, 27, 141, 196, 84, 124, 68, 132, 141, 120, 231, 213, 56, 231, 134, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 252, 248, 92, 46, 196, 255, 185, 73, 146, 173, 91, 174, 224, 104, 198, 54, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -133,7 +133,7 @@ public partial class SpriteBatch 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 117, 131, 1, 0, 198, 90, 0, 0, 39, 151, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, -0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 226, 82, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 235, 30, 3, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 211, 19, 3, 0, 149, 49, 3, 0, 125, 218, 1, 0, 227, 138, 2, 0, 184, 232, 1, 0, 140, 144, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -189,14 +189,14 @@ public partial class SpriteBatch 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 107, 12, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, -65, 69, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, -100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 102, 97, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 52, 53, +54, 48, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, +100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 48, 52, 53, 54, 48, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 62, 17, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 128, 55, 190, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 44, 203, 120, 44, 182, 11, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -259,8 +259,8 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 44, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, -24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 76, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, -0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 112, 123, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 16, 96, 0, 0, 242, 241, 10, 0, 24, 21, 14, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, +0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 16, 96, 0, 0, 242, 241, 10, 0, 24, 21, 17, 16, 0, 0, 1, 0, 1, 0, 41, 75, 0, 0, 152, 7, 0, 0, 169, 67, 0, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -302,7 +302,7 @@ public partial class SpriteBatch 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -361,13 +361,13 @@ public partial class SpriteBatch 9, 0, 156, 6, 0, 0, 0, 0, 0, 0, 152, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, -92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 70, 65, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 52, 53, 54, 48, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 156, 151, 27, 141, 196, 84, 124, 68, 132, 141, 120, 231, 213, 56, 231, 134, 134, 0, 0, 0, 47, 76, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 252, 248, 92, 46, 196, 255, 185, 73, 146, 173, 91, 174, 224, 104, 198, 54, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 102, -97, 101, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, +92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 48, 52, 53, +54, 48, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -396,11 +396,11 @@ public partial class SpriteBatch 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 116, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 104, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 104, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, -1, 0, 0, 0, 1, 29, 116, 212, 60, 199, 159, 70, 117, 135, 226, 199, 201, 222, 184, 128, 203, 0, 88, 88, 0, 0, 68, 88, 66, 67, 168, 0, 210, 170, 66, 231, 81, 30, 33, 105, 195, 86, 70, 242, 200, 250, 1, 0, 0, 0, 88, 88, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, +1, 0, 0, 0, 1, 116, 28, 77, 89, 12, 253, 234, 3, 250, 89, 126, 122, 144, 94, 153, 224, 0, 88, 88, 0, 0, 68, 88, 66, 67, 12, 253, 152, 69, 16, 148, 24, 112, 105, 12, 122, 163, 30, 216, 30, 193, 1, 0, 0, 0, 88, 88, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 180, 5, 0, 0, 180, 7, 0, 0, 188, 85, 0, 0, 56, 86, 0, 0, 8, 87, 0, 0, 184, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 254, 255, 60, 5, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 5, 1, 68, 66, 85, 71, 40, 0, 0, 0, 232, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 19, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 172, 3, 0, 0, 32, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, -111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, 0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, +111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 67, 57, 48, 55, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 28, 4, 0, 0, 0, 0, 255, 255, 52, 4, 0, 0, 0, 0, 255, 255, 64, 4, 0, 0, 0, 0, 255, 255, 76, 4, 0, 0, 0, 0, 255, 255, 88, 4, 0, 0, 0, 0, 255, 255, 100, 4, 0, 0, 90, 0, 0, 0, 112, 4, 0, 0, 96, 0, 0, 0, 128, 4, 0, 0, 96, 0, 0, 0, 148, 4, 0, 0, 96, 0, 0, 0, 168, 4, 0, 0, 90, 0, 0, 0, 184, 4, 0, 0, 90, 0, 0, 0, 200, 4, 0, 0, 90, 0, 0, 0, 216, 4, 0, 0, 124, 0, 0, 0, 232, 4, 0, 0, 124, 0, 0, 0, 252, 4, 0, 0, 126, 0, 0, 0, 8, 5, 0, 0, 126, 0, 0, 0, 20, 5, 0, 0, 96, 0, 0, 0, 32, 5, 0, 0, 129, 0, 0, 0, 44, 5, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, @@ -467,7 +467,7 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 220, 126, 48, 133, 88, 175, 203, 75, 184, 174, 116, 9, 14, 175, 210, 78, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 125, 186, 45, 192, 63, 21, 27, 67, 176, 4, 200, 211, 136, 96, 244, 18, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -548,14 +548,14 @@ public partial class SpriteBatch 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 23, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 0, 99, 58, 92, +83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 67, 57, 48, 55, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 102, 100, 52, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 53, 99, 57, 48, 55, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 87, 215, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 27, 226, 48, 1, 128, 0, 0, 0, 186, 145, 192, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 236, 101, 107, 69, 98, 12, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -656,7 +656,7 @@ public partial class SpriteBatch 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 65, 100, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, -0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 90, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 4, 16, 0, 0, 136, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, @@ -712,12 +712,12 @@ public partial class SpriteBatch 0, 0, 156, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 248, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 248, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, -48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 69, 70, 68, 52, 65, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, +48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 67, 57, 48, 55, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 220, 126, 48, 133, 88, 175, 203, 75, 184, 174, 116, 9, 14, 175, 210, 78, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 125, 186, 45, 192, 63, 21, 27, 67, 176, 4, 200, 211, 136, 96, 244, 18, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, -115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 101, 102, 100, 52, 97, 48, 0, 4, 0, 0, 0, +115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 53, 99, 57, 48, 55, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs index 78d9f8939c..142198267a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -21,113 +21,111 @@ public partial class SpriteBatch 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, 4, 0, 0, 0, -0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, 83, 104, 97, 100, -101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, -105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, -90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 234, 105, 136, 35, 1, 148, 245, 75, 50, 184, 129, 147, 118, 56, 51, 106, 0, 230, 10, 0, 0, 68, 88, 66, 67, 172, 15, 200, 65, 127, 177, 110, 83, 54, 176, 161, 139, 87, 51, -100, 18, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, -0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, -0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 84, 69, 88, -67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, -20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, -7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, -73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, -65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, -62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, 0, 0, 24, 0, -0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, 12, 4, 0, 0, -19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, -48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, -7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, 30, 32, 0, 4, -0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, -0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, 196, 127, 129, 0, -0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, 134, 6, 0, 0, -0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, 130, 96, 48, 162, -42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, 108, 16, 2, 101, -67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, 112, 115, 19, 4, -160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, -16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, 128, 13, 132, 24, -148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 104, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 60, 116, 114, 117, -101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, -170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, -30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 208, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, 139, -3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 219, 128, 52, 92, 190, 243, 248, 66, 68, 0, 19, 17, 2, 205, 176, 16, 70, 0, 13, 151, 239, 60, 190, 4, 48, 207, 66, 248, 197, 109, 91, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, -77, 15, 53, 249, 197, 109, 3, 0, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, -156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, 101, 192, 121, 35, -6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, 224, 130, 97, 150, -33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, 70, 19, 6, 97, -52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, 96, 52, 33, 0, -70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, 129, 29, 109, 32, -1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, 49, 75, 96, 12, -84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, 17, 117, 32, 1, -35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 97, 22, 132, 17, -131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 243, 209, 253, 213, 32, 128, 64, 13, 87, 75, 30, 43, 219, 231, 72, 85, 0, 21, 12, 0, 0, 68, 88, 66, 67, 0, 178, 107, 234, 243, 13, 57, 236, 150, 80, 222, 151, -230, 179, 195, 194, 1, 0, 0, 0, 21, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, 5, 0, 0, 0, -8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, -69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, -67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, -0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, 0, 46, 0, 0, -0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 96, 8, 0, 0, 96, 0, 1, 0, 24, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 72, 8, 0, 0, 66, 67, 192, -222, 33, 12, 0, 0, 15, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, -8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, -32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, -80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, -0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, -32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, 0, 4, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, -109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, -32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, -0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, -71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, 2, 35, 0, 0, -0, 128, 49, 2, 25, 165, 241, 244, 27, 35, 32, 109, 180, 151, 191, 49, 2, 209, 92, 117, 210, 35, 2, 0, 0, 128, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 121, 24, 0, 0, 120, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, -146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, -145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 216, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 131, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, -46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 186, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, 2, 101, 130, 112, -48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, 152, 129, 24, 96, -0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, 136, 78, 193, 128, 13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 154, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, 153, 28, 15, 157, -92, 93, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, 56, 128, 128, 42, 108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, 102, 87, 38, 55, -37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, 46, 114, 101, 115, 111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, 231, 82, 230, 70, -39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 214, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, 190, 243, 248, -139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 72, 195, 229, 59, 143, 47, 68, 4, 48, 17, 33, 208, 12, 11, 97, 3, 219, 112, 249, 206, 227, 11, 1, 85, 20, 68, 84, 58, 192, 80, 18, 6, 32, 96, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, -113, 219, 0, 0, 0, 97, 32, 0, 0, 189, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 93, 133, 97, 19, 53, 98, 144, 0, 32, 8, 6, 136, 103, 101, 217, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 153, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, 166, 109, 213, 53, -98, 144, 0, 32, 8, 6, 72, 24, 100, 27, 87, 97, 35, 6, 9, 0, 130, 96, 128, 136, 129, 198, 117, 85, 54, 98, 144, 0, 32, 8, 6, 200, 24, 108, 149, 151, 105, 35, 6, 9, 0, 130, 96, 128, 144, 1, 103, 125, 217, 54, 98, 144, 0, 32, 8, 6, 72, 25, 116, 23, 24, 100, 220, 136, -65, 2, 128, 32, 24, 32, 102, 224, 97, 97, 144, 117, 35, 6, 9, 0, 130, 96, 128, 156, 193, 135, 137, 65, 231, 141, 24, 36, 0, 8, 130, 1, 130, 6, 96, 144, 141, 65, 247, 141, 24, 36, 0, 8, 130, 1, 146, 6, 97, 160, 145, 65, 7, 6, 35, 6, 9, 0, 130, 96, 128, 168, 129, 24, -108, 101, 208, 133, 193, 136, 65, 2, 128, 32, 24, 32, 107, 48, 6, 99, 96, 6, 97, 32, 6, 35, 6, 9, 0, 130, 96, 192, 172, 1, 7, 6, 103, 112, 6, 91, 161, 65, 25, 224, 136, 193, 1, 128, 32, 24, 56, 108, 192, 9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, -67, 185, 1, 24, 64, 5, 108, 128, 35, 6, 7, 0, 130, 96, 224, 204, 193, 24, 36, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 213, 129, 25, 64, 5, 115, 128, 35, 6, 7, 0, 130, 96, 224, 232, 129, 26, 64, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, -38, 16, 67, 241, 1, 27, 64, 5, 122, 128, 35, 6, 7, 0, 130, 96, 224, 132, 66, 28, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 102, 32, 1, 131, 206, 64, 2, 166, 160, 129, 4, 140, 72, 3, 9, 216, 182, 6, 18, 176, 160, 128, 128, 89, 109, 32, 1, -11, 12, 8, 88, 244, 6, 18, 176, 224, 128, 128, 49, 113, 32, 1, 11, 16, 8, 24, 25, 208, 129, 4, 44, 64, 32, 96, 159, 29, 72, 192, 2, 4, 2, 166, 225, 129, 4, 44, 64, 32, 96, 149, 30, 72, 192, 2, 4, 2, 214, 6, 125, 32, 1, 11, 16, 8, 24, 26, 252, 129, 4, 44, 64, -32, 96, 99, 16, 10, 18, 176, 0, 129, 128, 121, 163, 32, 1, 11, 16, 8, 88, 40, 184, 130, 4, 44, 20, 94, 65, 2, 22, 10, 176, 32, 1, 27, 96, 1, 2, 54, 196, 2, 4, 108, 144, 5, 8, 216, 41, 12, 18, 176, 83, 24, 36, 96, 167, 48, 72, 192, 134, 90, 128, 128, 13, 182, 0, -1, 27, 110, 1, 2, 214, 10, 131, 4, 172, 21, 6, 9, 88, 43, 12, 18, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, 220, 33, 29, 172, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 208, 129, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, 220, 225, 28, 164, -17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 204, 1, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 193, 29, 220, 33, 29, 108, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 119, 112, 7, 116, 168, 133, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, 29, 210, 97, 24, -49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 1, 29, 132, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, 29, 206, 33, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 193, 28, 90, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 133, 114, 112, 135, 116, 96, 133, 17, -131, 4, 0, 65, 48, 120, 224, 65, 23, 202, 193, 29, 208, 97, 21, 70, 12, 18, 0, 4, 193, 224, 129, 7, 93, 40, 7, 119, 56, 7, 85, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 28, 220, 193, 28, 82, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 114, 112, 135, 116, 64, 5, -4, 0, 0, 0, 0, 1, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 1, 0, 0, 0, +4, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 6, 0, 0, 0, 17, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, 1, 187, 86, 151, 200, 110, 133, 38, 54, 91, 146, 64, 132, 108, 88, 33, 116, 16, +83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, +120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, +121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 234, 105, 136, 35, 1, 148, 245, 75, 50, 184, 129, 147, 118, 56, 51, 106, 0, 230, 10, 0, 0, 68, 88, 66, 67, 172, 15, 200, 65, 127, 177, 110, 83, 54, 176, +161, 139, 87, 51, 100, 18, 1, 0, 0, 0, 230, 10, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 50, 1, 0, 0, 94, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, +0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, +0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 36, 1, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 4, 1, 0, 4, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 128, 8, 0, 0, 96, 0, 0, 0, 32, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 104, 8, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 23, 2, 0, 0, 11, 130, 32, 0, +2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, +25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, +9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 89, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, +129, 144, 64, 49, 65, 80, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, +7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 101, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 32, 5, 0, 0, 128, 123, 134, 203, 159, 176, 135, 144, 252, 16, 104, 134, 133, 64, 65, 3, 0, 0, 64, 49, 28, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 110, 26, 46, 127, 194, 30, 66, 242, 87, 66, 90, 137, 201, 47, 110, 27, 21, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 133, 129, 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 112, 0, +0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 40, 6, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 192, 0, 0, 0, 0, 37, 0, 0, 0, +12, 4, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, +113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, +160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 121, +30, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 48, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, +1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 3, 26, 0, 0, 0, 24, 35, 0, 65, 16, +196, 127, 129, 0, 0, 0, 0, 138, 129, 6, 0, 0, 0, 198, 8, 90, 115, 206, 121, 143, 0, 0, 0, 0, 74, 142, 6, 0, 0, 0, 102, 0, 8, 0, 0, 0, 160, 240, 104, 0, 0, 0, 96, 140, 0, 4, 65, 16, 4, 135, 49, 2, 16, 4, 65, 16, 12, 8, 0, 0, 0, 160, 28, 10, +134, 6, 0, 0, 0, 198, 8, 64, 16, 4, 241, 111, 140, 0, 4, 65, 16, 254, 198, 8, 64, 16, 4, 73, 112, 32, 0, 0, 0, 128, 82, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 0, 0, 121, 24, 0, 0, 119, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 142, 9, +130, 96, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 200, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 36, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 128, 50, 65, 56, 150, 9, 2, 192, +108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 64, 179, 65, 32, 32, 10, +112, 115, 19, 4, 160, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 48, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 34, 6, 19, 4, 229, 217, 16, 4, 19, 4, 37, 218, 176, 4, 157, 247, 129, +65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 99, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 1, 178, 97, 65, 58, 239, 51, 131, 48, 32, 200, 0, 249, 128, 9, 2, 48, 109, 8, 208, 96, 130, 160, 64, 27, 22, 52, 232, 188, 47, 13, 194, 128, 80, 3, 52, 248, +128, 13, 132, 24, 148, 193, 25, 172, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 66, 6, 27, 150, 160, 13, 60, 55, 0, 131, 143, 32, 131, 224, 3, 54, 4, 111, 176, 97, 96, 3, 56, 0, 104, 6, 83, 112, 114, 105, 116, 101, 66, 97, 116, 99, 104, 83, 104, 97, 100, 101, 114, +60, 116, 114, 117, 101, 62, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 76, 14, 226, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, +153, 220, 148, 0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, +153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, 64, 14, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 208, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, 92, +190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 219, 128, 52, 92, 190, 243, 248, 66, 68, 0, 19, 17, 2, 205, 176, 16, 70, 0, 13, 151, 239, 60, 190, 4, 48, 207, 66, 248, 197, 109, 91, 65, 53, 92, 190, 243, 248, 210, +228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 97, 32, 0, 0, 144, 0, 0, 0, 19, 4, 199, 136, 65, 2, 128, 32, 24, 44, 100, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 82, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 102, 160, 125, 96, 128, 101, 35, 6, 9, +0, 130, 96, 176, 156, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 160, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 164, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 176, 168, 129, 23, 6, 100, 192, 117, 35, 6, 9, 0, 130, 96, 176, 172, 193, 39, 6, +101, 192, 121, 35, 6, 9, 0, 130, 96, 176, 176, 1, 24, 140, 129, 25, 112, 223, 136, 65, 2, 128, 32, 24, 44, 109, 16, 6, 100, 112, 6, 28, 24, 140, 24, 36, 0, 8, 130, 193, 226, 6, 98, 192, 161, 1, 24, 132, 129, 5, 28, 4, 70, 12, 12, 0, 4, 193, 128, 121, 3, 46, 24, 110, +224, 130, 97, 150, 33, 16, 130, 17, 131, 4, 0, 65, 48, 120, 224, 128, 11, 3, 54, 96, 3, 52, 24, 49, 72, 0, 16, 4, 131, 39, 14, 186, 50, 104, 131, 54, 72, 131, 17, 131, 7, 0, 65, 48, 136, 226, 128, 11, 4, 232, 233, 186, 51, 56, 131, 51, 232, 70, 19, 2, 96, 52, 65, 8, +70, 19, 6, 97, 52, 129, 24, 102, 9, 134, 17, 131, 4, 0, 65, 48, 120, 238, 96, 12, 208, 96, 14, 230, 224, 13, 70, 12, 18, 0, 4, 193, 224, 193, 3, 50, 96, 3, 58, 160, 3, 56, 24, 49, 120, 0, 16, 4, 131, 8, 15, 198, 32, 16, 46, 139, 12, 200, 192, 13, 220, 192, 13, 200, +96, 52, 33, 0, 70, 19, 132, 96, 52, 97, 16, 70, 19, 136, 97, 150, 96, 24, 168, 24, 172, 0, 17, 6, 42, 6, 44, 64, 132, 129, 138, 65, 11, 16, 97, 160, 98, 224, 2, 68, 48, 107, 13, 32, 48, 98, 96, 0, 32, 8, 6, 12, 41, 196, 65, 48, 220, 16, 7, 193, 48, 203, 64, 20, +129, 29, 109, 32, 1, 11, 234, 0, 2, 134, 188, 129, 4, 44, 184, 3, 8, 216, 48, 72, 192, 4, 65, 2, 38, 4, 16, 24, 49, 48, 0, 16, 4, 3, 166, 21, 230, 32, 24, 49, 48, 0, 16, 4, 3, 198, 21, 230, 32, 176, 57, 8, 34, 96, 193, 28, 72, 192, 2, 58, 128, 192, 44, 129, +49, 75, 96, 12, 84, 12, 2, 33, 6, 197, 64, 197, 224, 14, 132, 24, 20, 118, 6, 118, 0, 129, 17, 3, 3, 0, 65, 48, 96, 106, 65, 20, 130, 225, 6, 81, 8, 134, 233, 6, 236, 10, 166, 27, 50, 67, 152, 110, 232, 3, 99, 176, 173, 14, 36, 96, 68, 29, 72, 192, 136, 58, 144, 128, +17, 117, 32, 1, 35, 234, 0, 2, 70, 212, 1, 4, 140, 168, 3, 8, 24, 81, 7, 16, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, 161, 22, 136, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 104, 97, 24, 49, 72, 0, 16, 4, 3, 233, 23, 70, 161, 23, 122, +97, 22, 132, 17, 131, 4, 0, 65, 48, 144, 126, 97, 20, 122, 161, 23, 100, 33, 64, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 243, 209, 253, 213, 32, 128, 64, 13, 87, 75, 30, 43, 219, 231, 72, 85, 0, 21, 12, 0, 0, 68, 88, 66, 67, 0, 178, 107, 234, 243, 13, 57, 236, +150, 80, 222, 151, 230, 179, 195, 194, 1, 0, 0, 0, 21, 12, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 33, 1, 0, 0, 1, 2, 0, 0, 173, 3, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 213, 0, 0, 0, +5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, +15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, +15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 216, 0, 0, 0, 5, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 15, 240, 0, +0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 164, 1, 0, 0, 36, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, +0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 68, 0, 3, 0, 0, 0, 37, 0, 0, 0, 4, 0, 0, 0, 1, 4, 65, 0, 3, 0, 0, +0, 46, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 55, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 2, 0, 0, 73, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 2, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 96, 8, 0, 0, 96, 0, 1, 0, 24, 2, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 72, 8, 0, +0, 66, 67, 192, 222, 33, 12, 0, 0, 15, 2, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, +96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, +255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, +160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, 4, 72, 49, 0, 0, +0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, 0, 128, 0, 0, 0, +128, 0, 0, 0, 32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, 160, 24, 5, 0, 0, +0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, +7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, +109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 4, +8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, +144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 131, 146, 163, 4, 0, 0, 128, 17, 0, 34, 0, 0, 0, 40, 187, 2, 41, 160, +2, 35, 0, 0, 0, 128, 49, 2, 25, 165, 241, 244, 27, 35, 32, 109, 180, 151, 191, 49, 2, 209, 92, 117, 210, 35, 2, 0, 0, 128, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 121, 24, 0, 0, 120, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, +128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, +32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 216, 54, 12, 76, 19, 108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 131, 155, 32, 28, 203, 134, 32, 152, 32, 28, +205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 186, 13, 11, 97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 9, 2, 1, 109, 8, 196, 96, 195, 34, 6, 214, 133, 141, 1, 70, 116, 98, 128, 1, 27, +2, 101, 130, 112, 48, 27, 22, 197, 186, 176, 50, 192, 8, 51, 80, 48, 96, 67, 177, 121, 97, 64, 6, 103, 176, 97, 9, 172, 11, 203, 52, 66, 11, 48, 96, 195, 66, 88, 23, 198, 105, 68, 71, 96, 192, 134, 229, 179, 46, 12, 12, 52, 162, 251, 48, 96, 195, 34, 6, 214, 133, 141, 129, 70, +152, 129, 24, 96, 0, 151, 41, 171, 47, 168, 183, 185, 52, 186, 180, 55, 183, 9, 194, 225, 108, 88, 148, 54, 184, 220, 32, 235, 136, 78, 193, 128, 13, 69, 26, 168, 193, 26, 176, 193, 27, 108, 24, 208, 0, 14, 0, 154, 193, 20, 156, 92, 26, 93, 153, 80, 24, 221, 24, 218, 20, 90, 24, 89, +153, 28, 15, 157, 92, 93, 153, 143, 139, 213, 84, 83, 88, 154, 219, 215, 149, 92, 24, 28, 92, 153, 220, 134, 34, 146, 131, 56, 128, 128, 42, 108, 108, 118, 109, 46, 105, 100, 101, 110, 116, 83, 130, 163, 10, 25, 158, 139, 93, 153, 220, 92, 218, 155, 219, 148, 0, 105, 66, 134, 231, 98, 23, 198, +102, 87, 38, 55, 37, 80, 234, 144, 225, 185, 204, 161, 133, 145, 149, 201, 53, 189, 145, 149, 177, 77, 9, 154, 50, 100, 120, 46, 114, 101, 115, 111, 117, 114, 99, 101, 115, 83, 130, 167, 18, 25, 158, 11, 93, 30, 92, 89, 144, 155, 219, 27, 93, 24, 93, 218, 155, 219, 220, 148, 128, 170, 67, 134, +231, 82, 230, 70, 39, 151, 7, 245, 150, 230, 70, 55, 55, 37, 144, 3, 0, 113, 32, 0, 0, 28, 0, 0, 0, 5, 96, 6, 83, 184, 60, 77, 47, 11, 195, 244, 49, 122, 138, 14, 147, 203, 114, 30, 93, 94, 47, 251, 92, 214, 105, 51, 156, 118, 127, 175, 242, 48, 28, 94, 150, 91, 192, 52, +92, 190, 243, 248, 139, 3, 12, 98, 243, 80, 147, 95, 220, 182, 9, 72, 195, 229, 59, 143, 47, 68, 4, 48, 17, 33, 208, 12, 11, 97, 3, 219, 112, 249, 206, 227, 11, 1, 85, 20, 68, 84, 58, 192, 80, 18, 6, 32, 96, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, +211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 189, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 93, 133, 97, 19, 53, 98, 144, 0, 32, 8, 6, 136, 103, 101, 217, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 153, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, +166, 109, 213, 53, 98, 144, 0, 32, 8, 6, 72, 24, 100, 27, 87, 97, 35, 6, 9, 0, 130, 96, 128, 136, 129, 198, 117, 85, 54, 98, 144, 0, 32, 8, 6, 200, 24, 108, 149, 151, 105, 35, 6, 9, 0, 130, 96, 128, 144, 1, 103, 125, 217, 54, 98, 144, 0, 32, 8, 6, 72, 25, 116, 23, +24, 100, 220, 136, 65, 2, 128, 32, 24, 32, 102, 224, 97, 97, 144, 117, 35, 6, 9, 0, 130, 96, 128, 156, 193, 135, 137, 65, 231, 141, 24, 36, 0, 8, 130, 1, 130, 6, 96, 144, 141, 65, 247, 141, 24, 36, 0, 8, 130, 1, 146, 6, 97, 160, 145, 65, 7, 6, 35, 6, 9, 0, 130, 96, +128, 168, 129, 24, 108, 101, 208, 133, 193, 136, 65, 2, 128, 32, 24, 32, 107, 48, 6, 99, 96, 6, 97, 32, 6, 35, 6, 9, 0, 130, 96, 192, 172, 1, 7, 6, 103, 112, 6, 91, 161, 65, 25, 224, 136, 193, 1, 128, 32, 24, 56, 108, 192, 9, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, +32, 140, 38, 16, 67, 185, 1, 24, 64, 5, 108, 128, 35, 6, 7, 0, 130, 96, 224, 204, 193, 24, 36, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 213, 129, 25, 64, 5, 115, 128, 35, 6, 7, 0, 130, 96, 224, 232, 129, 26, 64, 193, 104, 66, 0, 140, 38, 8, 193, +104, 194, 32, 140, 38, 16, 67, 241, 1, 27, 64, 5, 122, 128, 35, 6, 7, 0, 130, 96, 224, 132, 66, 28, 92, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 131, 89, 102, 32, 1, 131, 206, 64, 2, 166, 160, 129, 4, 140, 72, 3, 9, 216, 182, 6, 18, 176, 160, 128, 128, +89, 109, 32, 1, 11, 12, 8, 88, 244, 6, 18, 176, 224, 128, 128, 49, 113, 32, 1, 11, 16, 8, 24, 25, 208, 129, 4, 44, 64, 32, 96, 159, 29, 72, 192, 2, 4, 2, 166, 225, 129, 4, 44, 64, 32, 96, 149, 30, 72, 192, 2, 4, 2, 214, 6, 125, 32, 1, 11, 16, 8, 24, 26, 252, +129, 4, 44, 64, 32, 96, 99, 16, 10, 18, 176, 0, 129, 128, 121, 163, 32, 1, 11, 16, 8, 88, 40, 184, 130, 4, 44, 20, 94, 65, 2, 22, 10, 176, 32, 1, 27, 96, 1, 2, 54, 196, 2, 4, 108, 144, 5, 8, 216, 41, 12, 18, 176, 83, 24, 36, 96, 167, 48, 72, 192, 134, 90, 128, +128, 13, 182, 0, 1, 27, 110, 1, 2, 214, 10, 131, 4, 172, 21, 6, 9, 88, 43, 12, 18, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, 220, 33, 29, 172, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 208, 129, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 97, 29, +220, 225, 28, 164, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 214, 193, 29, 204, 1, 26, 49, 72, 0, 16, 4, 131, 7, 30, 116, 193, 29, 220, 33, 29, 108, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 119, 112, 7, 116, 168, 133, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, +29, 210, 97, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 1, 29, 132, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 218, 193, 29, 206, 33, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 29, 220, 193, 28, 90, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 133, 114, 112, 135, +116, 96, 133, 17, 131, 4, 0, 65, 48, 120, 224, 65, 23, 202, 193, 29, 208, 97, 21, 70, 12, 18, 0, 4, 193, 224, 129, 7, 93, 40, 7, 119, 56, 7, 85, 24, 49, 72, 0, 16, 4, 131, 7, 30, 116, 161, 28, 220, 193, 28, 82, 97, 196, 32, 1, 64, 16, 12, 30, 120, 208, 5, 114, 112, +135, 116, 64, 5, 4, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs index 351bf58257..7a238df985 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteBatch.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteBatch] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs index 31101eec59..38fdf077ea 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -41,12 +41,12 @@ public partial class SpriteEffect 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, -116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 199, 107, -57, 115, 92, 237, 154, 6, 216, 190, 105, 107, 119, 229, 39, 96, 0, 160, 67, 0, 0, 68, 88, 66, 67, 114, 70, 253, 250, 151, 16, 171, 196, 223, 252, 220, 6, 54, 24, 191, 78, 1, 0, 0, 0, 160, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, +116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 25, 178, +126, 69, 130, 163, 191, 22, 58, 236, 47, 214, 156, 62, 170, 199, 0, 160, 67, 0, 0, 68, 88, 66, 67, 158, 197, 177, 163, 49, 172, 205, 23, 237, 130, 75, 10, 14, 180, 71, 95, 1, 0, 0, 0, 160, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 228, 2, 0, 0, 136, 3, 0, 0, 144, 65, 0, 0, 12, 66, 0, 0, 56, 67, 0, 0, 108, 67, 0, 0, 65, 111, 110, 57, 160, 2, 0, 0, 160, 2, 0, 0, 0, 2, 255, 255, 108, 2, 0, 0, 52, 0, 0, 0, 1, 0, 40, 0, 0, 0, 52, 0, 0, 0, 52, 0, 1, 0, 36, 0, 0, 0, 52, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 135, 0, 68, 66, 85, 71, 40, 0, 0, 0, 240, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 5, 0, 0, 0, 136, 0, 0, 0, 4, 0, 0, 0, 160, 1, 0, 0, 4, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, -97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 55, 70, 70, 66, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 61, 0, 0, 0, 60, 2, 0, 0, 66, 0, 0, 0, 76, 2, 0, 0, 66, +97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 52, 52, 53, 50, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 36, 2, 0, 0, 0, 0, 255, 255, 48, 2, 0, 0, 61, 0, 0, 0, 60, 2, 0, 0, 66, 0, 0, 0, 76, 2, 0, 0, 66, 0, 0, 0, 92, 2, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 3, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 1, 0, 0, 28, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 44, 1, 0, 0, 4, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, @@ -96,7 +96,7 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 217, 166, 216, 1, 195, 137, 74, 79, 142, 199, 70, 123, 175, 149, 10, 181, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 94, 237, 27, 133, 63, 124, 23, 70, 178, 225, 225, 165, 228, 150, 217, 52, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -113,7 +113,7 @@ public partial class SpriteEffect 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 117, 131, 1, 0, 200, 4, 3, 0, 8, 104, 0, 0, 30, 194, 2, 0, 198, 90, 0, 0, 110, 41, 1, 0, 193, 195, 0, 0, 49, -251, 3, 0, 138, 183, 3, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 254, 80, 0, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, +251, 3, 0, 138, 183, 3, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 221, 8, 3, 0, 11, 107, 3, 0, 65, 185, 2, 0, 29, 190, 2, 0, 213, 255, 0, 0, 98, 163, 2, 0, 200, 81, 2, 0, 62, 3, 3, 0, 220, 192, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -145,14 +145,14 @@ public partial class SpriteEffect 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 117, 6, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, -117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, -56, 51, 57, 55, 70, 70, 66, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, -121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 55, 102, 102, 98, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, +52, 49, 48, 52, 52, 53, 50, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, +121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 48, 52, 52, 53, 50, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 65, 162, 99, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 64, 233, 189, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 53, 251, 236, 50, 192, 5, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -182,7 +182,7 @@ public partial class SpriteEffect 0, 0, 0, 2, 16, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 34, 0, 3, 18, 13, 21, 3, 0, 4, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 3, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 4, 16, 0, 0, 1, -0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 48, 80, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, +0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 4, 16, 0, 0, 3, 2, 224, 95, 0, 0, 242, 241, 10, 0, 24, 21, 15, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 16, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 0, 0, 0, 242, 241, 10, 0, 24, 21, 18, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 75, 0, 0, 152, 7, 0, 0, 122, 207, 2, 0, 176, 220, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -202,7 +202,7 @@ public partial class SpriteEffect 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, +84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -261,13 +261,13 @@ public partial class SpriteEffect 0, 0, 0, 2, 0, 9, 0, 20, 3, 0, 0, 0, 0, 0, 0, 196, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 156, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 156, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, -99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 55, 70, 70, 66, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, +99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 52, 52, 53, 50, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 217, 166, 216, 1, 195, 137, 74, 79, 142, 199, 70, 123, 175, 149, 10, 181, 134, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 94, 237, 27, 133, 63, 124, 23, 70, 178, 225, 225, 165, 228, 150, 217, 52, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, -117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, -56, 51, 57, 55, 102, 102, 98, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, +117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, +52, 49, 48, 52, 52, 53, 50, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -312,12 +312,12 @@ public partial class SpriteEffect 101, 120, 116, 117, 114, 101, 48, 0, 71, 108, 111, 98, 97, 108, 115, 0, 171, 171, 171, 161, 0, 0, 0, 1, 0, 0, 0, 196, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 236, 0, 0, 0, 0, 0, 0, 0, 71, 108, 111, 98, 97, 108, 115, 95, 49, 95, 67, 111, 108, 111, 114, 0, 1, 0, 3, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, -83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 20, 195, 225, 173, 168, 60, -37, 23, 113, 191, 200, 150, 34, 0, 176, 172, 0, 156, 68, 0, 0, 68, 88, 66, 67, 180, 123, 155, 208, 110, 141, 206, 166, 197, 254, 73, 199, 6, 231, 3, 166, 1, 0, 0, 0, 156, 68, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 66, 0, 0, 32, +83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 158, 191, 125, 186, 2, 233, +181, 174, 148, 174, 104, 40, 126, 182, 44, 139, 0, 156, 68, 0, 0, 68, 88, 66, 67, 140, 17, 203, 196, 102, 14, 128, 206, 164, 89, 93, 14, 160, 4, 246, 238, 1, 0, 0, 0, 156, 68, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 176, 3, 0, 0, 156, 4, 0, 0, 164, 66, 0, 0, 32, 67, 0, 0, 240, 67, 0, 0, 68, 68, 0, 0, 65, 111, 110, 57, 108, 3, 0, 0, 108, 3, 0, 0, 0, 2, 254, 255, 56, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 64, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, -64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 68, 0, 0, 0, 200, 2, 0, 0, 68, 0, 0, 0, 216, 2, 0, 0, 68, 0, 0, 0, 232, +64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 50, 56, 66, 49, 53, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 68, 0, 0, 0, 200, 2, 0, 0, 68, 0, 0, 0, 216, 2, 0, 0, 68, 0, 0, 0, 232, 2, 0, 0, 68, 0, 0, 0, 248, 2, 0, 0, 80, 0, 0, 0, 8, 3, 0, 0, 80, 0, 0, 0, 28, 3, 0, 0, 82, 0, 0, 0, 40, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 4, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 20, 1, 0, 0, 2, 0, 0, 0, 255, 255, 255, 255, 4, 0, 255, 255, 6, 0, 0, 0, 2, 0, 3, 0, 255, 255, 255, 255, 7, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 8, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, @@ -371,8 +371,8 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 167, -86, 179, 223, 5, 40, 95, 76, 134, 19, 103, 253, 128, 48, 252, 65, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 24, +173, 160, 96, 214, 204, 187, 79, 133, 200, 185, 199, 170, 139, 163, 64, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -429,14 +429,14 @@ public partial class SpriteEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 253, 6, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, -104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, -97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 98, 48, 51, 48, 49, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 50, 56, 66, 49, 53, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, +97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 50, 56, 98, 49, 53, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 16, 149, 103, 140, 60, -200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 27, 226, 48, 1, 128, 0, 0, 0, 226, 248, 191, 192, 176, +204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 214, 18, 137, 140, 72, 6, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -488,7 +488,7 @@ public partial class SpriteEffect 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, -0, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 180, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, @@ -544,14 +544,14 @@ public partial class SpriteEffect 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 160, 2, 0, 0, 0, 0, 0, 0, 244, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 228, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, -105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 66, 48, 51, 48, 49, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, +105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 50, 56, 66, 49, 53, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 167, -86, 179, 223, 5, 40, 95, 76, 134, 19, 103, 253, 128, 48, 252, 65, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 24, +173, 160, 96, 214, 204, 187, 79, 133, 200, 185, 199, 170, 139, 163, 64, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, -104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 98, 48, 51, 48, 49, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, -0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 50, 56, 98, 49, 53, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, +0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs index d261d06a76..4c96d8ddda 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Direct3D12.Level_9_1.cs @@ -23,91 +23,89 @@ public partial class SpriteEffect 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 3, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, -112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, -101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, -101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 10, 0, -0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, -101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, 0, 0, 0, 1, -0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, 16, 0, 0, 0, -2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, -0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, 100, 101, 114, 66, -97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, -1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 147, 133, 148, 56, 208, 35, 91, 182, -8, 112, 227, 62, 62, 199, 25, 46, 0, 67, 8, 0, 0, 68, 88, 66, 67, 28, 217, 146, 72, 171, 203, 196, 188, 163, 49, 235, 5, 244, 153, 195, 36, 1, 0, 0, 0, 67, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 125, 0, 0, 0, 183, 0, 0, 0, 107, 1, 0, -0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 49, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, -103, 101, 116, 0, 80, 83, 86, 48, 172, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 1, 0, 0, 0, -0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 208, 6, 0, 0, -96, 0, 0, 0, 180, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 184, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 171, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, -37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, -81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, -137, 32, 0, 0, 104, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 1, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, 161, 32, 0, 0, -0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, 60, 148, 131, 28, -144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, -0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, 224, 166, 225, 242, -39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 163, 134, 203, 159, 176, 135, 144, 124, 110, 163, 138, 149, 152, 252, 226, 182, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 8, 10, 0, 0, 0, 2, 0, 0, 0, 8, 0, -0, 0, 2, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, -122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, -208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 15, 3, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 84, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, 48, 228, 177, 128, -0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 31, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 16, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, 34, 0, 0, 0, -40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 1, 34, 0, 0, 0, 40, 57, 106, 0, 0, 0, 40, 3, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 163, 6, 0, 0, 128, 34, 32, 2, 0, 0, 128, 178, 43, 133, -98, 160, 6, 0, 0, 128, 146, 40, 144, 66, 0, 0, 121, 24, 0, 0, 109, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 4, 81, 0, 19, 4, 67, 97, 68, 85, 134, -71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, 4, 202, 18, 4, -4, 211, 60, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 208, 54, 12, 214, 21, -108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 102, 155, 32, 52, 209, 134, 32, 152, 32, 52, 215, 134, 37, 16, 131, 49, 32, 131, 50, 48, 3, 194, 12, -2, 50, 0, 54, 4, 103, 192, 100, 202, 234, 139, 42, 76, 238, 172, 140, 110, 130, 208, 112, 19, 132, 166, 219, 176, 4, 105, 48, 6, 106, 80, 6, 100, 64, 172, 65, 64, 6, 192, 134, 128, 13, 54, 12, 104, 208, 6, 0, 183, 41, 56, 185, 52, 186, 178, 34, 51, 179, 178, 49, 58, 23, 168, 169, -166, 176, 52, 183, 175, 43, 185, 48, 56, 184, 50, 185, 13, 69, 247, 6, 110, 192, 1, 85, 216, 216, 236, 218, 92, 210, 200, 202, 220, 232, 166, 4, 81, 21, 50, 60, 23, 187, 50, 185, 185, 180, 55, 183, 41, 129, 212, 132, 12, 207, 197, 46, 140, 205, 174, 76, 110, 74, 64, 213, 33, 195, 115, 153, -67, 11, 35, 43, 147, 107, 122, 35, 43, 99, 155, 18, 92, 101, 200, 240, 92, 228, 202, 230, 222, 234, 228, 198, 202, 230, 166, 4, 91, 37, 50, 60, 23, 186, 60, 184, 178, 32, 55, 183, 55, 186, 48, 186, 180, 55, 183, 185, 41, 1, 24, 212, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, -163, 155, 155, 18, 188, 1, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, -192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 176, 13, 151, 239, 60, 190, 16, 80, 69, 65, 68, 165, 3, 12, 37, 97, 0, 2, 230, 23, 183, 109, 5, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 0, -97, 32, 0, 0, 49, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 221, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 142, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 65, 228, 53, 76, 150, 77, 35, 6, 9, 0, 130, 96, 16, 125, 14, 164, 105, 212, 136, 193, 3, 128, 32, 24, -76, 31, 19, 8, 196, 208, 52, 146, 36, 53, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 35, 6, 9, 0, 130, 96, 16, 149, 1, 5, 129, 193, 167, 85, 24, 100, 56, 98, 112, 0, 32, 8, 6, 85, 25, 68, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, -196, 96, 11, 33, 1, 91, 8, 9, 216, 66, 72, 192, 22, 66, 2, 35, 6, 9, 0, 130, 96, 96, 181, 65, 182, 6, 107, 16, 6, 196, 136, 65, 2, 128, 32, 24, 88, 109, 144, 173, 193, 26, 128, 193, 48, 98, 144, 0, 32, 8, 6, 86, 27, 100, 107, 176, 6, 155, 48, 98, 144, 0, 32, 8, -6, 86, 27, 100, 107, 176, 6, 94, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 15, 153, 208, 250, 118, 99, 11, 83, 14, 171, 63, 32, 250, 99, 193, 228, 0, 167, 8, 0, 0, 68, 88, 66, 67, 236, 16, 247, 227, 62, 183, 101, 30, 126, 64, 124, 165, 71, 63, 7, 138, -1, 0, 0, 0, 167, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 11, 1, 0, 0, 243, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, -0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, -84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 93, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 224, 0, 0, 0, 36, -0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, -0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 68, 3, 3, 4, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 172, 6, 0, 0, 96, 0, 1, 0, 171, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 148, 6, 0, 0, 66, -67, 192, 222, 33, 12, 0, 0, 162, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, -41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, -255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, -113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 9, 0, 0, 0, 0, 238, 0, 23, 39, 0, 22, 9, 5, 5, 0, -0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, 44, 4, 10, 26, -0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, -1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, -3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, -7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, -144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 72, 64, 0, 12, -0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 23, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 41, 132, 25, 0, 82, -0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, 43, 160, 2, 43, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 100, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, -80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 113, 196, 246, 38, 22, 198, 54, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 201, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, 13, 68, 166, 198, -69, 198, 197, 6, 4, 229, 44, 141, 174, 133, 198, 198, 236, 230, 70, 108, 70, 6, 230, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 174, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, 44, 107, 67, 112, -109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 176, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 37, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 27, 132, 79, 12, 54, 44, 129, 182, 113, 157, -71, 120, 1, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 133, 40, 131, 205, 12, 186, 48, 32, 194, 128, 224, 128, 13, 2, 25, 156, 193, 134, 97, 12, 208, 0, 224, 54, 5, 39, 151, 70, 87, 86, 100, 102, 86, 54, 70, 231, 98, 53, 213, 20, 150, 230, 246, -117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 212, 32, 13, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, 104, 97, 100, 101, -114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 212, -0, 0, 0, 113, 32, 0, 0, 24, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, -44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 97, 32, 0, 0, 103, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 217, 67, 81, -141, 51, 98, 144, 0, 32, 8, 6, 139, 6, 85, 85, 243, 140, 24, 36, 0, 8, 130, 193, 178, 69, 149, 245, 64, 35, 6, 9, 0, 130, 96, 176, 112, 146, 117, 61, 209, 136, 65, 2, 128, 32, 24, 44, 221, 116, 97, 143, 52, 98, 144, 0, 32, 8, 6, 139, 71, 97, 217, 51, 141, 24, 36, 0, -8, 130, 193, 227, 61, 145, 166, 57, 181, 89, 56, 98, 112, 0, 32, 8, 6, 209, 247, 8, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 133, 65, 7, 21, 116, 56, 98, 112, 0, 32, 8, 6, 145, 25, 88, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, -196, 80, 104, 160, 65, 5, 100, 128, 35, 6, 7, 0, 130, 96, 16, 181, 65, 7, 5, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 245, 6, 96, 0, 21, 172, 1, 142, 24, 28, 0, 8, 130, 65, 68, 7, 100, 112, 5, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, -64, 12, 102, 117, 18, 48, 200, 147, 128, 41, 159, 4, 140, 0, 3, 9, 216, 38, 6, 18, 176, 160, 128, 128, 89, 100, 32, 1, 11, 12, 8, 88, 100, 6, 18, 176, 224, 128, 128, 49, 104, 32, 1, 11, 16, 8, 24, 25, 172, 129, 4, 44, 64, 32, 96, 95, 27, 72, 192, 2, 4, 2, 166, 189, -129, 4, 44, 64, 32, 96, 85, 28, 72, 192, 2, 4, 2, 214, 6, 116, 32, 1, 11, 16, 8, 24, 26, 216, 129, 4, 44, 64, 32, 96, 99, 128, 7, 18, 176, 0, 129, 128, 121, 122, 32, 1, 11, 16, 8, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 176, 10, 199, 136, 65, 2, -128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 170, 80, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 144, 10, 195, 136, 65, 2, 128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 168, 16, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 32, 11, 178, 176, 10, 126, 48, 98, 144, 0, 32, -8, 6, 18, 45, 136, 130, 44, 200, 130, 42, 244, 1, 2, 0, 0, 0, 0, 0, 0, 1, +84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, +0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 71, 108, 111, 98, 97, +108, 115, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 7, 71, 108, 111, 98, 97, 108, 115, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, +101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 16, 0, 0, 0, 1, 0, +0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 18, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 46, 67, 111, 108, 111, 114, 0, 5, 67, 111, 108, 111, 114, 0, 0, 0, 0, +16, 0, 0, 0, 2, 209, 15, 106, 29, 26, 10, 67, 77, 5, 87, 97, 193, 94, 82, 250, 73, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, +79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 0, 5, 0, 0, 0, 12, 83, 112, 114, 105, 116, 101, 69, 102, 102, 101, 99, 116, 1, 228, 169, 204, 216, 98, 12, 48, 30, 207, 43, 118, 171, 103, 83, 247, 189, 16, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, +114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 147, 133, 148, 56, +208, 35, 91, 182, 8, 112, 227, 62, 62, 199, 25, 46, 0, 67, 8, 0, 0, 68, 88, 66, 67, 28, 217, 146, 72, 171, 203, 196, 188, 163, 49, 235, 5, 244, 153, 195, 36, 1, 0, 0, 0, 67, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 125, 0, 0, 0, 183, 0, 0, +0, 107, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 49, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, +95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 172, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, +2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, +1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, +208, 6, 0, 0, 96, 0, 0, 0, 180, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 184, 6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 171, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, +146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, +40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, +0, 0, 0, 0, 137, 32, 0, 0, 104, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 205, 0, 36, 1, 0, 0, 0, 192, 29, 224, 226, 4, 192, 34, +161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 224, 38, 105, 138, 40, 97, 242, 89, 128, 121, 22, 34, 98, 39, 96, 34, 80, 64, 0, 0, 0, 64, 5, 0, 0, 0, 74, 0, 0, 0, 0, 48, 83, 24, 140, 3, 59, 132, 195, 60, 204, 131, 27, 208, 66, 57, 224, 3, 61, 212, 131, +60, 148, 131, 28, 144, 2, 31, 216, 67, 57, 140, 3, 61, 188, 131, 60, 240, 129, 57, 176, 195, 59, 132, 3, 61, 176, 1, 24, 208, 129, 31, 248, 1, 10, 14, 0, 0, 0, 8, 1, 0, 0, 96, 142, 32, 24, 1, 40, 193, 2, 0, 0, 192, 28, 1, 82, 12, 0, 0, 0, 0, 2, 0, 0, +0, 2, 0, 0, 0, 2, 0, 0, 128, 6, 0, 0, 0, 2, 0, 0, 0, 106, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 60, 0, 0, 0, 20, 3, 2, 0, 0, 128, 0, 0, 0, 160, 1, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 64, 1, 0, 0, +224, 166, 225, 242, 39, 236, 33, 36, 127, 37, 164, 149, 152, 252, 226, 182, 81, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 80, 24, 9, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 128, 163, 134, 203, 159, 176, 135, 144, 124, 110, 163, 138, 149, 152, 252, 226, 182, 17, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 8, 10, 0, 0, 0, 2, 0, +0, 0, 8, 0, 0, 0, 2, 0, 0, 128, 98, 44, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 192, 64, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, +14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, +122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, +15, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 30, 7, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 17, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 38, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 84, 64, 0, 8, 0, 0, 0, 0, 0, 0, 0, +48, 228, 177, 128, 0, 24, 0, 0, 0, 0, 0, 0, 0, 32, 11, 4, 31, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 16, 50, 0, 0, 0, 152, 1, 160, 4, 0, 0, 128, 25, 0, +34, 0, 0, 0, 40, 2, 82, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 146, 40, 132, 25, 0, 106, 0, 0, 0, 24, 1, 40, 1, 34, 0, 0, 0, 40, 57, 106, 0, 0, 0, 40, 3, 2, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 194, 163, 6, 0, 0, 128, 34, 32, 2, 0, 0, +128, 178, 43, 133, 98, 160, 6, 0, 0, 128, 146, 40, 144, 66, 0, 0, 121, 24, 0, 0, 109, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 142, 9, 194, 96, 240, 56, 98, 123, 19, 11, 99, 155, 155, 32, 16, 200, 4, 129, 72, 54, 32, 129, 48, 4, 4, 81, 0, 19, 4, 67, +97, 68, 85, 134, 71, 87, 39, 151, 230, 118, 230, 50, 21, 214, 6, 199, 86, 38, 183, 1, 9, 14, 36, 8, 136, 0, 152, 32, 36, 11, 37, 170, 50, 60, 186, 58, 185, 52, 183, 51, 23, 170, 50, 60, 186, 58, 185, 50, 152, 9, 2, 193, 76, 16, 148, 102, 130, 64, 56, 27, 132, 192, 217, 144, +4, 202, 18, 4, 4, 211, 60, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 65, 180, 65, 32, 130, 9, 2, 241, 108, 16, 8, 138, 2, 220, 220, 4, 129, 208, +54, 12, 214, 21, 108, 8, 160, 13, 129, 177, 33, 72, 54, 16, 25, 160, 109, 19, 132, 11, 216, 0, 108, 24, 2, 207, 219, 16, 124, 27, 6, 162, 3, 3, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 102, 155, 32, 52, 209, 134, 32, 152, 32, 52, 215, 134, 37, 16, 131, 49, 32, 131, 50, +48, 3, 194, 12, 2, 50, 0, 54, 4, 103, 192, 100, 202, 234, 139, 42, 76, 238, 172, 140, 110, 130, 208, 112, 19, 132, 166, 219, 176, 4, 105, 48, 6, 106, 80, 6, 100, 64, 172, 65, 64, 6, 192, 134, 128, 13, 54, 12, 104, 208, 6, 0, 183, 41, 56, 185, 52, 186, 178, 34, 51, 179, 178, 49, +58, 23, 168, 169, 166, 176, 52, 183, 175, 43, 185, 48, 56, 184, 50, 185, 13, 69, 247, 6, 110, 192, 1, 85, 216, 216, 236, 218, 92, 210, 200, 202, 220, 232, 166, 4, 81, 21, 50, 60, 23, 187, 50, 185, 185, 180, 55, 183, 41, 129, 212, 132, 12, 207, 197, 46, 140, 205, 174, 76, 110, 74, 64, 213, +33, 195, 115, 153, 67, 11, 35, 43, 147, 107, 122, 35, 43, 99, 155, 18, 92, 101, 200, 240, 92, 228, 202, 230, 222, 234, 228, 198, 202, 230, 166, 4, 91, 37, 50, 60, 23, 186, 60, 184, 178, 32, 55, 183, 55, 186, 48, 186, 180, 55, 183, 185, 41, 1, 24, 212, 33, 195, 115, 41, 115, 163, 147, 203, +131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 113, 32, 0, 0, 28, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, +60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 176, 13, 151, 239, 60, 190, 16, 80, 69, 65, 68, 165, 3, 12, 37, 97, 0, 2, 230, 23, 183, 109, 5, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, +183, 13, 0, 0, 97, 32, 0, 0, 49, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 56, 221, 115, 93, 141, 51, 98, 144, 0, 32, 8, 6, 142, 7, 97, 88, 243, 140, 24, 36, 0, 8, 130, 65, 228, 53, 76, 150, 77, 35, 6, 9, 0, 130, 96, 16, 125, 14, 164, 105, 212, 136, 193, +3, 128, 32, 24, 76, 31, 19, 8, 196, 208, 52, 146, 36, 53, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 35, 6, 9, 0, 130, 96, 16, 149, 1, 5, 129, 193, 167, 85, 24, 100, 56, 98, 112, 0, 32, 8, 6, 85, 25, 68, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, +48, 8, 163, 9, 196, 96, 11, 33, 1, 91, 8, 9, 216, 66, 72, 192, 22, 66, 2, 35, 6, 9, 0, 130, 96, 96, 181, 65, 182, 6, 107, 16, 6, 196, 136, 65, 2, 128, 32, 24, 88, 109, 144, 173, 193, 26, 128, 193, 48, 98, 144, 0, 32, 8, 6, 86, 27, 100, 107, 176, 6, 155, 48, 98, +144, 0, 32, 8, 6, 86, 27, 100, 107, 176, 6, 94, 128, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 15, 153, 208, 250, 118, 99, 11, 83, 14, 171, 63, 32, 250, 99, 193, 228, 0, 167, 8, 0, 0, 68, 88, 66, 67, 236, 16, 247, 227, 62, 183, 101, 30, 126, 64, 124, 165, +71, 63, 7, 138, 1, 0, 0, 0, 167, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 11, 1, 0, 0, 243, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, +8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, +0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 93, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 224, +0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, +0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 68, 3, 3, +4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 172, 6, 0, 0, 96, 0, 1, 0, 171, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 148, +6, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 162, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, +224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, +240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 65, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, +18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 80, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 32, 9, 0, 0, 0, 0, 238, 0, 23, 39, 0, 22, +9, 5, 5, 0, 0, 0, 100, 0, 0, 0, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 10, 0, 0, 0, 4, 0, 0, 0, 115, 4, 1, 41, 0, 0, 0, 220, 51, 92, 254, 132, 61, 132, 228, 135, 64, 51, +44, 4, 10, 26, 0, 0, 0, 138, 225, 0, 0, 0, 64, 0, 0, 0, 160, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 192, 0, 0, 0, 112, 212, 112, 249, 19, 246, 16, 146, 207, 109, 84, 177, 18, 147, 95, 220, 54, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 10, 1, 1, 0, 0, 64, 0, 0, 0, 224, 0, 0, 0, 64, 0, 0, 0, 80, 12, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 24, 8, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, +104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, +160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, +7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 15, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 34, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, +72, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 23, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 0, 58, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 2, 41, +132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 34, 0, 0, 0, 40, 57, 98, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, 43, 160, 2, 43, 133, 98, 32, 5, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 100, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, +32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 19, 132, 35, 225, 113, 196, 246, 38, 22, 198, 54, 55, 65, 32, 148, 13, 8, 113, 32, 1, 65, 36, 0, 201, 160, 169, 108, 46, 12, 196, 174, 76, 110, 46, 237, 205, +13, 68, 166, 198, 69, 198, 197, 6, 4, 229, 44, 141, 174, 133, 198, 198, 236, 230, 70, 108, 70, 6, 230, 38, 101, 67, 176, 108, 16, 136, 96, 130, 64, 44, 27, 4, 194, 161, 96, 55, 55, 65, 32, 174, 13, 3, 20, 5, 27, 4, 67, 217, 64, 0, 192, 4, 76, 16, 38, 96, 3, 176, 97, 8, +44, 107, 67, 112, 109, 24, 136, 10, 35, 66, 85, 132, 53, 244, 244, 36, 69, 52, 65, 80, 176, 9, 130, 210, 108, 8, 130, 9, 130, 242, 108, 88, 2, 109, 227, 58, 142, 240, 2, 14, 216, 16, 16, 19, 4, 37, 219, 176, 16, 218, 198, 129, 1, 71, 132, 1, 193, 1, 27, 132, 79, 12, 54, 44, +129, 182, 113, 157, 71, 120, 1, 7, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 40, 208, 134, 133, 40, 131, 205, 12, 186, 48, 32, 194, 128, 224, 128, 13, 2, 25, 156, 193, 134, 97, 12, 208, 0, 224, 54, 5, 39, 151, 70, 87, 86, 100, 102, 86, 54, 70, 231, 98, 53, 213, +20, 150, 230, 246, 117, 37, 23, 6, 7, 87, 38, 183, 161, 168, 212, 32, 13, 40, 160, 10, 27, 155, 93, 155, 75, 26, 89, 153, 27, 221, 148, 96, 169, 66, 134, 231, 98, 87, 38, 55, 151, 246, 230, 54, 37, 96, 154, 144, 225, 185, 216, 133, 177, 217, 149, 201, 77, 9, 156, 58, 100, 120, 46, 115, +104, 97, 100, 101, 114, 77, 111, 100, 101, 108, 83, 130, 168, 12, 25, 158, 139, 92, 217, 220, 91, 157, 220, 88, 217, 220, 148, 96, 170, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 192, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, +205, 77, 9, 212, 0, 0, 0, 113, 32, 0, 0, 24, 0, 0, 0, 6, 176, 177, 79, 132, 76, 132, 87, 20, 132, 48, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, +68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 97, 32, 0, 0, 103, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, +44, 217, 67, 81, 141, 51, 98, 144, 0, 32, 8, 6, 139, 6, 85, 85, 243, 140, 24, 36, 0, 8, 130, 193, 178, 69, 149, 245, 64, 35, 6, 9, 0, 130, 96, 176, 112, 146, 117, 61, 209, 136, 65, 2, 128, 32, 24, 44, 221, 116, 97, 143, 52, 98, 144, 0, 32, 8, 6, 139, 71, 97, 217, 51, +141, 24, 36, 0, 8, 130, 193, 227, 61, 145, 166, 57, 181, 89, 56, 98, 112, 0, 32, 8, 6, 209, 247, 8, 193, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 67, 133, 65, 7, 21, 116, 56, 98, 112, 0, 32, 8, 6, 145, 25, 88, 73, 48, 154, 16, 0, 163, 9, 66, 48, 154, +48, 8, 163, 9, 196, 80, 104, 160, 65, 5, 100, 128, 35, 6, 7, 0, 130, 96, 16, 181, 65, 7, 5, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 245, 6, 96, 0, 21, 172, 1, 142, 24, 28, 0, 8, 130, 65, 68, 7, 100, 112, 5, 163, 9, 1, 48, 154, 32, 4, 163, +9, 131, 48, 154, 64, 12, 102, 117, 18, 48, 200, 147, 128, 41, 159, 4, 140, 0, 3, 9, 216, 38, 6, 18, 176, 160, 128, 128, 89, 100, 32, 1, 11, 12, 8, 88, 100, 6, 18, 176, 224, 128, 128, 49, 104, 32, 1, 11, 16, 8, 24, 25, 172, 129, 4, 44, 64, 32, 96, 95, 27, 72, 192, 2, +4, 2, 166, 189, 129, 4, 44, 64, 32, 96, 85, 28, 72, 192, 2, 4, 2, 214, 6, 116, 32, 1, 11, 16, 8, 24, 26, 216, 129, 4, 44, 64, 32, 96, 99, 128, 7, 18, 176, 0, 129, 128, 121, 122, 32, 1, 11, 16, 8, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 176, 10, +199, 136, 65, 2, 128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 170, 80, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 16, 11, 178, 144, 10, 195, 136, 65, 2, 128, 32, 24, 72, 180, 32, 10, 177, 32, 11, 168, 16, 140, 24, 36, 0, 8, 130, 129, 68, 11, 162, 32, 11, 178, 176, 10, 126, 48, +98, 144, 0, 32, 8, 6, 18, 45, 136, 130, 44, 200, 130, 42, 244, 1, 2, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs index 61c2347c87..fe6911780b 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/SpriteEffect.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [SpriteEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs index b2f96d9fbd..cc3d4af59b 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -28,11 +28,11 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, -46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 85, 208, 2, 0, 69, 134, 201, 202, 91, 45, 231, 205, 231, 137, -111, 84, 0, 76, 76, 0, 0, 68, 88, 66, 67, 128, 59, 86, 242, 120, 156, 74, 158, 136, 228, 50, 166, 221, 47, 10, 237, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, 0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, +46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 5, 246, 99, 227, 92, 48, 32, 117, 63, 56, 187, 105, 150, 28, +15, 213, 0, 76, 76, 0, 0, 68, 88, 66, 67, 178, 219, 229, 143, 15, 43, 96, 40, 97, 188, 2, 75, 219, 202, 50, 188, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 124, 4, 0, 0, 132, 74, 0, 0, 0, 75, 0, 0, 180, 75, 0, 0, 24, 76, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 255, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 24, 2, 0, 0, 40, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 57, 57, 66, 56, 0, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 69, 70, 50, 53, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 70, 0, 0, 0, 212, 2, 0, 0, 72, 0, 0, 0, 228, 2, 0, 0, 79, 0, 0, 0, 244, 2, 0, 0, 81, 0, 0, 0, 8, 3, 0, 0, 81, 0, 0, 0, 24, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 102, 97, 108, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 45, @@ -87,7 +87,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 228, 193, 33, 179, 194, 143, 143, 76, 179, 140, 76, 235, 217, 41, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 135, 185, 135, 134, 98, 196, 34, 76, 153, 106, 200, 18, 174, 234, 240, 98, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -152,14 +152,14 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 192, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 54, 57, 57, 66, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, -115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, -57, 97, 56, 51, 57, 54, 57, 57, 98, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 48, 69, 70, 50, 53, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, +115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, +57, 100, 52, 49, 48, 101, 102, 50, 53, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 60, 217, 99, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 180, 250, 190, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 62, 245, 67, 219, 11, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -226,7 +226,7 @@ internal partial class UIEffect 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, +101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 180, 0, 0, 0, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -283,13 +283,13 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, -51, 57, 54, 57, 57, 66, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, +114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, +49, 48, 69, 70, 50, 53, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 228, 193, 33, 179, 194, 143, 143, 76, 179, 140, 76, 235, 217, 41, 160, 0, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 135, 185, 135, 134, 98, 196, 34, 76, 153, 106, 200, 18, 174, 234, 240, 98, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, -104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 54, 57, 57, 98, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, +104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 48, 101, 102, 50, 53, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -334,11 +334,11 @@ internal partial class UIEffect 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 164, 242, 206, 148, 101, 151, 120, 104, 93, 47, 113, 96, 33, 115, 193, 164, 0, 76, 76, 0, 0, 68, 88, 66, 67, 81, 191, 6, 99, 252, 117, 156, 87, 62, 77, 89, 204, 54, -36, 181, 180, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 74, 0, 0, 224, 74, 0, 0, 44, 75, 0, 0, 196, 75, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, +0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 37, 183, 20, 7, 202, 254, 2, 212, 127, 93, 93, 102, 153, 138, 1, 80, 0, 76, 76, 0, 0, 68, 88, 66, 67, 8, 150, 176, 82, 55, 192, 142, 141, 228, 146, 243, 177, 150, +101, 87, 152, 1, 0, 0, 0, 76, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 148, 3, 0, 0, 92, 4, 0, 0, 100, 74, 0, 0, 224, 74, 0, 0, 44, 75, 0, 0, 196, 75, 0, 0, 65, 111, 110, 57, 80, 3, 0, 0, 80, 3, 0, 0, 0, 2, 254, 255, 40, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 170, 0, 68, 66, 85, 71, 40, 0, 0, 0, 124, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 9, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 84, 2, 0, 0, 208, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, -101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, +101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 69, 48, 68, 54, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 176, 2, 0, 0, 0, 0, 255, 255, 188, 2, 0, 0, 0, 0, 255, 255, 200, 2, 0, 0, 0, 0, 255, 255, 212, 2, 0, 0, 102, 0, 0, 0, 224, 2, 0, 0, 104, 0, 0, 0, 244, 2, 0, 0, 104, 0, 0, 0, 0, 3, 0, 0, 106, 0, 0, 0, 12, 3, 0, 0, 102, 0, 0, 0, 24, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 213, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, @@ -392,7 +392,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 214, 190, 179, 45, 213, 59, 117, 77, 145, 229, 23, 78, 36, 189, 184, 47, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 11, 255, 147, 115, 39, 178, 75, 79, 176, 128, 231, 196, 196, 181, 210, 20, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -457,14 +457,14 @@ internal partial class UIEffect 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 167, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 0, 99, 58, 92, 100, 101, 118, +105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 69, 48, 68, 54, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, -48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 54, 55, 99, 102, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 53, 101, 48, 100, 54, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 246, 49, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 15, 110, 192, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 183, 74, 243, 36, 242, 9, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -539,7 +539,7 @@ internal partial class UIEffect 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -589,12 +589,12 @@ internal partial class UIEffect 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 192, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, -48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 54, 55, 67, 70, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, +48, 48, 48, 48, 50, 57, 68, 52, 49, 53, 69, 48, 68, 54, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 214, 190, 179, 45, 213, 59, 117, 77, 145, 229, 23, 78, 36, 189, 184, 47, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 11, 255, 147, 115, 39, 178, 75, 79, 176, 128, 231, 196, 196, 181, 210, 20, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, -105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 54, 55, 99, 102, 56, 0, 4, 0, 0, 0, 6, 0, 0, +105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 53, 101, 48, 100, 54, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs index 1506a4d722..6e8e4ee03e 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Direct3D12.Level_9_1.cs @@ -19,84 +19,82 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, -116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -93, 42, 7, 223, 187, 80, 30, 215, 184, 137, 23, 133, 11, 41, 233, 90, 0, 169, 8, 0, 0, 68, 88, 66, 67, 63, 72, 10, 31, 174, 6, 95, 98, 208, 223, 126, 16, 24, 192, 5, 21, 1, 0, 0, 0, 169, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, -0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, -64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, -79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, -0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 156, 6, 0, 0, 96, 0, 0, 0, 167, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 132, 6, 0, 0, 66, 67, 192, 222, 33, 12, -0, 0, 158, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, -36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, -6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, -9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, -160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, -24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, -0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, 128, 129, 0, 0, -0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, -7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, -113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, -0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, -25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, 2, 0, 0, 0, -40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 113, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, 16, 134, 32, 32, -2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, -100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, 67, 144, 101, 27, -2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, 32, 19, 4, 229, -217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 201, 160, 42, 169, 200, 204, 172, 108, 140, -110, 10, 45, 140, 172, 76, 142, 199, 44, 140, 109, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, 109, 74, 224, 52, -33, 195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, 46, 237, 205, 109, -110, 74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 0, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 65, 167, 205, 112, 218, 253, 189, 202, -195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, -67, 77, 126, 113, 219, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, 210, 133, 61, 209, -136, 65, 2, 128, 32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, 217, 136, 193, 3, -128, 32, 24, 64, 97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, 36, 0, 8, 130, -65, 212, 6, 219, 26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1, 38, 80, 102, 132, 127, 82, 13, 213, 245, 215, 76, 218, 16, 130, 201, 158, 0, 47, 8, 0, 0, 68, 88, 66, 67, 51, 9, 79, 152, 140, 60, 134, 143, 127, 116, 210, 3, 229, 153, 197, 148, 1, 0, 0, 0, 47, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, -0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, -0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, -84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, -80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, -0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, -0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, -0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, -0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 40, 5, 0, 0, 96, 0, 1, 0, 74, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 16, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, -0, 65, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, -72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, -0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, -0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, -0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, -32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, -7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, -0, 0, 0, 100, 129, 0, 0, 0, 0, 17, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, -34, 40, 131, 82, 40, 6, 34, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, 155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, -17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 193, 217, 48, 32, 9, 49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, -120, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 8, 104, 195, 50, 64, 145, 100, 73, 195, 53, 72, 192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, 2, 113, 108, 88, -56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, 160, 72, 210, 168, 193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, 44, 28, 25, 68, -101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 144, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, 120, 204, 194, 216, 230, 202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, 75, 26, 160, 1, -0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, 50, 185, 41, 129, 81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, 34, 195, 115, 161, -203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, -188, 236, 115, 89, 167, 205, 112, 218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 66, 0, 0, 0, 19, 4, 193, -136, 65, 2, 128, 32, 24, 20, 80, 227, 56, 11, 51, 98, 144, 0, 32, 8, 6, 69, 228, 60, 207, 210, 140, 24, 36, 0, 8, 130, 65, 33, 61, 11, 212, 56, 35, 6, 9, 0, 130, 96, 80, 76, 16, 19, 53, 207, 136, 65, 2, 128, 32, 24, 20, 84, 212, 72, 12, 52, 98, 144, 0, 32, 8, -6, 69, 37, 57, 19, 19, 141, 24, 36, 0, 8, 130, 65, 97, 77, 12, 21, 73, 35, 6, 9, 0, 130, 96, 80, 92, 84, 83, 69, 211, 136, 65, 2, 128, 32, 24, 20, 88, 229, 88, 16, 53, 98, 144, 0, 32, 8, 6, 69, 102, 61, 23, 84, 141, 24, 36, 0, 8, 130, 65, 161, 93, 15, 86, -89, 35, 6, 9, 0, 130, 96, 96, 104, 15, 148, 89, 201, 136, 65, 2, 128, 32, 24, 24, 218, 3, 101, 21, 50, 98, 144, 0, 32, 8, 6, 134, 246, 64, 217, 116, 140, 24, 36, 0, 8, 130, 129, 161, 61, 80, 38, 25, 35, 6, 9, 0, 130, 96, 96, 104, 79, 150, 89, 203, 136, 65, 2, 128, -32, 24, 24, 218, 147, 101, 149, 50, 98, 144, 0, 32, 8, 6, 134, 246, 80, 153, 85, 140, 24, 36, 0, 8, 130, 129, 161, 61, 84, 86, 17, 35, 6, 9, 0, 130, 96, 96, 104, 15, 149, 77, 195, 136, 65, 2, 128, 32, 24, 24, 218, 67, 101, 146, 48, 98, 144, 0, 32, 8, 6, 134, 246, 68, -153, 21, 32, 0, 0, 0, 0, 0, 0, 1, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, +121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, +9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, +0, 0, 0, 1, 93, 42, 7, 223, 187, 80, 30, 215, 184, 137, 23, 133, 11, 41, 233, 90, 0, 169, 8, 0, 0, 68, 88, 66, 67, 63, 72, 10, 31, 174, 6, 95, 98, 208, 223, 126, 16, 24, 192, 5, 21, 1, 0, 0, 0, 169, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, +0, 207, 0, 0, 0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, +0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 156, 6, 0, 0, 96, 0, 0, 0, 167, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 132, 6, 0, 0, 66, 67, +192, 222, 33, 12, 0, 0, 158, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, +200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, +3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, +194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, +121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, +128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, +0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, +128, 129, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, +144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, +14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, +12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, +3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, +2, 0, 0, 0, 40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 113, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, +16, 134, 32, 32, 2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, +64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, +67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, +32, 19, 4, 229, 217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 201, 160, 42, 169, 200, +204, 172, 108, 140, 110, 10, 45, 140, 172, 76, 142, 199, 44, 140, 109, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, +109, 74, 224, 52, 33, 195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, +46, 237, 205, 109, 110, 74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 0, 0, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 204, 97, 246, 188, 236, 115, 65, 167, 205, 112, +218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 80, 13, 151, 239, 60, 190, 52, 57, +17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, +210, 133, 61, 209, 136, 65, 2, 128, 32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, +217, 136, 193, 3, 128, 32, 24, 64, 97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, +36, 0, 8, 130, 65, 212, 6, 219, 26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 1, 0, 0, 0, 1, 38, 80, 102, 132, 127, 82, 13, 213, 245, 215, 76, 218, 16, 130, 201, 158, 0, 47, 8, 0, 0, 68, 88, 66, 67, 51, 9, 79, 152, 140, 60, 134, 143, 127, 116, 210, 3, 229, 153, 197, 148, 1, 0, 0, 0, 47, 8, 0, 0, 5, 0, 0, 0, 52, 0, +0, 0, 68, 0, 0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, +0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, +79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, +0, 64, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, +0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, +0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 40, 5, 0, 0, 96, 0, 1, 0, 74, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 16, 5, 0, 0, 66, 67, 192, +222, 33, 12, 0, 0, 65, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, +8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, +32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, +49, 65, 144, 140, 0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, +0, 96, 0, 0, 0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, +120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, +160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, +0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 17, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, +1, 0, 0, 128, 34, 40, 131, 82, 40, 6, 34, 0, 0, 0, 40, 137, 66, 0, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, 155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, +177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 193, 217, 48, 32, 9, 49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, +20, 209, 4, 129, 120, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 8, 104, 195, 50, 64, 145, 100, 73, 195, 53, 72, 192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, +2, 113, 108, 88, 56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, 160, 72, 210, 168, 193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, +44, 28, 25, 68, 101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 144, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, 120, 204, 194, 216, 230, 202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, +75, 26, 160, 1, 0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, 50, 185, 41, 129, 81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, +34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 64, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, +243, 204, 97, 246, 188, 236, 115, 89, 167, 205, 112, 218, 253, 189, 202, 195, 112, 120, 89, 110, 1, 211, 112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 80, 13, 151, 239, 60, 190, 52, 57, 17, 129, 82, 211, 67, 77, 126, 113, 219, 0, 0, 0, 97, 32, 0, 0, 66, 0, 0, +0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 20, 80, 227, 56, 11, 51, 98, 144, 0, 32, 8, 6, 69, 228, 60, 207, 210, 140, 24, 36, 0, 8, 130, 65, 33, 61, 11, 212, 56, 35, 6, 9, 0, 130, 96, 80, 76, 16, 19, 53, 207, 136, 65, 2, 128, 32, 24, 20, 84, 212, 72, 12, 52, 98, +144, 0, 32, 8, 6, 69, 37, 57, 19, 19, 141, 24, 36, 0, 8, 130, 65, 97, 77, 12, 21, 73, 35, 6, 9, 0, 130, 96, 80, 92, 84, 83, 69, 211, 136, 65, 2, 128, 32, 24, 20, 88, 229, 88, 16, 53, 98, 144, 0, 32, 8, 6, 69, 102, 61, 23, 84, 141, 24, 36, 0, 8, 130, 65, +161, 93, 15, 86, 89, 35, 6, 9, 0, 130, 96, 96, 104, 15, 148, 89, 201, 136, 65, 2, 128, 32, 24, 24, 218, 3, 101, 21, 50, 98, 144, 0, 32, 8, 6, 134, 246, 64, 217, 116, 140, 24, 36, 0, 8, 130, 129, 161, 61, 80, 38, 25, 35, 6, 9, 0, 130, 96, 96, 104, 79, 150, 89, 203, +136, 65, 2, 128, 32, 24, 24, 218, 147, 101, 149, 50, 98, 144, 0, 32, 8, 6, 134, 246, 80, 153, 85, 140, 24, 36, 0, 8, 130, 129, 161, 61, 84, 86, 17, 35, 6, 9, 0, 130, 96, 96, 104, 15, 149, 77, 195, 136, 65, 2, 128, 32, 24, 24, 218, 67, 101, 146, 48, 98, 144, 0, 32, 8, +6, 134, 246, 68, 153, 21, 32, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs index b33fbc9c42..60acc76e32 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecode.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs index 543c6cbc4a..64ffe073e0 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D11.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // @@ -28,11 +28,11 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, -46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 92, 151, 44, 227, 56, 86, 47, 168, 45, 133, 11, 224, 190, 181, -173, 14, 0, 72, 76, 0, 0, 68, 88, 66, 67, 214, 58, 108, 183, 213, 193, 42, 143, 34, 165, 105, 72, 235, 243, 83, 178, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, 0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, +46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 58, 41, 165, 108, 49, 221, 117, 25, 252, 17, 140, 150, 47, 73, +144, 194, 0, 72, 76, 0, 0, 68, 88, 66, 67, 19, 190, 145, 150, 6, 129, 170, 108, 143, 226, 88, 94, 52, 170, 138, 167, 1, 0, 0, 0, 72, 76, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 144, 3, 0, 0, 120, 4, 0, 0, 128, 74, 0, 0, 252, 74, 0, 0, 176, 75, 0, 0, 20, 76, 0, 0, 65, 111, 110, 57, 76, 3, 0, 0, 76, 3, 0, 0, 0, 2, 255, 255, 36, 3, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 2, 255, 255, 254, 255, 169, 0, 68, 66, 85, 71, 40, 0, 0, 0, 120, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 8, 0, 0, 0, 136, 0, 0, 0, 5, 0, 0, 0, 20, 2, 0, 0, 36, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, -105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, 54, 68, 48, 0, +105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 69, 51, 67, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 172, 2, 0, 0, 0, 0, 255, 255, 184, 2, 0, 0, 0, 0, 255, 255, 196, 2, 0, 0, 70, 0, 0, 0, 208, 2, 0, 0, 72, 0, 0, 0, 224, 2, 0, 0, 79, 0, 0, 0, 240, 2, 0, 0, 81, 0, 0, 0, 4, 3, 0, 0, 81, 0, 0, 0, 20, 3, 0, 0, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 95, 116, 114, 117, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 95, 52, 50, 51, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 255, 255, 1, 0, 2, 0, 3, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 41, 1, 0, 0, 8, @@ -87,7 +87,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 96, 9, 128, 56, 129, 214, 178, 78, 129, 44, 132, 90, 220, 199, 198, 67, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 253, 254, 190, 66, 58, 180, 248, 66, 155, 70, 145, 241, 79, 92, 198, 72, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -152,14 +152,14 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 188, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, -92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, 54, 68, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, -99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, -57, 100, 99, 54, 100, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, +92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 69, 51, 67, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 48, +102, 102, 101, 51, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 4, 195, 100, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 64, 233, 189, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 35, 239, 192, 163, 7, 8, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -226,7 +226,7 @@ internal partial class UIEffect 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, -97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 91, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -283,14 +283,14 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 228, 3, 0, 0, 0, 0, 0, 0, 232, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, -92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 57, 68, 67, -54, 68, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 48, 70, 70, 69, +51, 67, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 96, 9, 128, 56, 129, 214, 178, 78, 129, 44, 132, 90, 220, 199, 198, 67, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, +0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 253, 254, 190, 66, 58, 180, 248, 66, 155, 70, 145, 241, 79, 92, 198, 72, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, -92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 57, 100, 99, 54, 100, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, -0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 48, 102, 102, 101, 51, 99, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, +0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -334,11 +334,11 @@ internal partial class UIEffect 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 92, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 80, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, -0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 52, 177, 78, 146, 1, 233, 45, 107, 92, 124, 24, 100, 170, 252, 158, 33, 0, 88, 77, 0, 0, 68, 88, 66, 67, 43, 242, 205, 80, 27, 132, 245, 245, 164, 110, 209, 218, 110, 176, 62, 232, 1, +0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 91, 241, 33, 86, 4, 176, 174, 250, 218, 214, 103, 181, 51, 224, 90, 177, 0, 88, 77, 0, 0, 68, 88, 66, 67, 220, 175, 2, 166, 45, 113, 193, 207, 150, 29, 169, 119, 206, 20, 55, 99, 1, 0, 0, 0, 88, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 16, 4, 0, 0, 104, 5, 0, 0, 112, 75, 0, 0, 236, 75, 0, 0, 56, 76, 0, 0, 208, 76, 0, 0, 65, 111, 110, 57, 204, 3, 0, 0, 204, 3, 0, 0, 0, 2, 254, 255, 164, 3, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 0, 2, 254, 255, 254, 255, 181, 0, 68, 66, 85, 71, 40, 0, 0, 0, 168, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 13, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 128, 2, 0, 0, 240, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, -66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, +66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 52, 56, 70, 70, 66, 48, 0, 171, 171, 171, 40, 0, 0, 0, 0, 0, 255, 255, 220, 2, 0, 0, 0, 0, 255, 255, 244, 2, 0, 0, 0, 0, 255, 255, 0, 3, 0, 0, 0, 0, 255, 255, 12, 3, 0, 0, 0, 0, 255, 255, 24, 3, 0, 0, 76, 0, 0, 0, 36, 3, 0, 0, 76, 0, 0, 0, 56, 3, 0, 0, 76, 0, 0, 0, 76, 3, 0, 0, 102, 0, 0, 0, 92, 3, 0, 0, 104, 0, 0, 0, 112, 3, 0, 0, 104, 0, 0, 0, 124, 3, 0, 0, 76, 0, 0, 0, 136, 3, 0, 0, 102, 0, 0, 0, 148, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, @@ -396,7 +396,7 @@ internal partial class UIEffect 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 211, 69, 4, 66, 89, 54, 16, 69, 144, 245, 60, 186, 23, 224, 116, 68, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 213, 1, 226, 71, 42, 25, 32, 79, 152, 105, 15, 64, 23, 54, 176, 232, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -461,14 +461,14 @@ internal partial class UIEffect 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 164, 10, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, -103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, +103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 52, 56, 70, 70, 66, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, -92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 102, 57, 99, 101, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 52, 56, 102, 102, 98, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 155, 124, 104, 140, 60, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 27, 226, 48, 1, 128, 0, 0, 0, 15, 110, 192, 192, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 91, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 58, 5, 190, 176, 239, 9, 0, 0, 1, 0, 0, 0, 90, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -551,7 +551,7 @@ internal partial class UIEffect 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 83, 119, 105, 122, 122, 108, 101, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 90, 0, 0, 0, 180, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 91, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -609,13 +609,13 @@ internal partial class UIEffect 3, 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 80, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 80, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, -97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 65, 56, 51, 67, 70, 57, 67, 69, 56, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, +97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 68, 52, 49, 52, 56, 70, 70, 66, 48, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 105, 209, 215, 105, 1, 0, 0, 0, 211, 69, 4, 66, 89, 54, 16, 69, 144, 245, 60, 186, 23, 224, 116, 68, 134, 0, 0, 0, 47, 76, 105, 110, 107, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 91, 74, 223, 105, 1, 0, 0, 0, 213, 1, 226, 71, 42, 25, 32, 79, 152, 105, 15, 64, 23, 54, 176, 232, 134, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, -103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 49, 57, 97, 56, 51, 99, 102, 57, 99, 101, 56, -0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, +103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 100, 52, 49, 52, 56, 102, 102, 98, 48, +0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs index 8905dce0e3..84816a592a 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Direct3D12.Level_9_1.cs @@ -19,85 +19,83 @@ internal partial class UIEffect 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, 121, 109, 16, 83, -104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, -116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, -92, 44, 138, 0, 10, 250, 131, 12, 168, 123, 143, 12, 28, 101, 152, 51, 0, 165, 8, 0, 0, 68, 88, 66, 67, 137, 222, 21, 142, 162, 27, 39, 186, 66, 23, 203, 124, 217, 194, 66, 172, 1, 0, 0, 0, 165, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, -0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, -0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, -64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, -255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, 69, 88, 67, 79, -79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, -0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 6, 0, 0, 96, 0, 0, 0, 166, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 6, 0, 0, 66, 67, 192, 222, 33, 12, -0, 0, 157, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, -36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, -6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, -9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, -160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, -24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, -0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, 128, 129, 0, 0, -0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, -7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, -113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, -0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, -25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, 2, 0, 0, 0, -40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, 16, 134, 32, 32, -2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, -100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, 67, 144, 101, 27, -2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, 32, 19, 4, 229, -217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 199, 160, 42, 169, 200, 204, 172, 108, 140, -110, 10, 45, 140, 172, 76, 142, 135, 78, 174, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, 109, 74, 224, 52, 33, -195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, 46, 237, 205, 109, 110, -74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 130, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, -2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 27, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 141, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, -1, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, 210, 133, 61, 209, 136, 65, 2, 128, -32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, 217, 136, 193, 3, 128, 32, 24, 64, -97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, 36, 0, 8, 130, 65, 212, 6, 219, -26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 164, 179, 85, 37, 28, 243, 21, 181, 58, 52, 132, 154, 126, 102, 214, 232, 0, 159, 8, 0, 0, 68, 88, 66, 67, 51, 98, 248, 14, 78, 222, 169, 151, 180, 193, 108, 137, 163, 189, 192, 229, 1, 0, 0, 0, 159, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 248, 0, -0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, -0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, -0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, -79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, -116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 84, 69, -88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 4, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, -0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, -0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 5, 0, 0, 96, 0, 1, 0, 102, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 93, 1, 0, -0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, -35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, -0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, 0, 148, 0, 0, -0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, 0, 128, 2, 0, -0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, -14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, -120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, -129, 0, 0, 0, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, 34, 40, 3, 26, -0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, 16, 205, 85, 39, 61, 18, 0, 0, 0, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, 155, 11, 3, 177, -43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 33, 218, 48, 32, 9, 49, 65, 56, 128, -13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 144, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 105, 195, 50, 64, 145, 100, 73, 195, 53, 72, 192, 4, 65, 88, -54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, 2, 113, 108, 88, 56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, 160, 72, 210, 168, -193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, 44, 28, 25, 68, 101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 112, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, 120, 232, 228, 234, -202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, 75, 26, 160, 1, 0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, 50, 185, 41, 129, -81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, 0, 113, 32, 0, -0, 18, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 178, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 160, 26, 46, 223, 121, 124, 105, 114, -34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 0, 0, 0, 97, 32, 0, 0, 87, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 20, 19, 20, 69, 206, 51, 98, 144, 0, 32, 8, 6, 5, 21, 73, 146, 3, 141, 24, 36, 0, 8, 130, 65, 81, 73, 206, 4, 69, 35, 6, 9, 0, 130, -96, 80, 88, 211, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 5, 85, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 69, 214, 67, 141, 24, 36, 0, 8, 130, 65, 145, 89, 207, 69, 85, 35, 6, 9, 0, 130, 96, 80, 104, 23, 132, 81, 214, 136, 65, 2, 128, 32, 24, 20, 27, 22, 101, -211, 53, 98, 144, 0, 32, 8, 6, 5, 151, 73, 218, 132, 141, 24, 36, 0, 8, 130, 65, 209, 105, 210, 134, 101, 86, 72, 18, 176, 98, 146, 128, 21, 148, 4, 108, 160, 32, 96, 67, 5, 1, 27, 44, 8, 216, 50, 72, 192, 150, 65, 2, 182, 12, 18, 176, 33, 131, 128, 13, 26, 4, 108, 216, -32, 96, 209, 32, 1, 139, 6, 9, 88, 52, 72, 96, 196, 32, 1, 64, 16, 12, 12, 54, 240, 196, 96, 13, 208, 0, 27, 49, 72, 0, 16, 4, 3, 131, 13, 60, 49, 88, 131, 51, 184, 70, 12, 18, 0, 4, 193, 192, 96, 3, 79, 12, 214, 160, 12, 172, 17, 131, 4, 0, 65, 48, 48, 216, -192, 19, 131, 53, 32, 131, 106, 196, 32, 1, 64, 16, 12, 12, 54, 240, 214, 96, 13, 208, 64, 27, 49, 72, 0, 16, 4, 3, 131, 13, 188, 53, 88, 131, 51, 200, 70, 12, 18, 0, 4, 193, 192, 96, 3, 207, 12, 214, 0, 13, 134, 17, 131, 4, 0, 65, 48, 48, 216, 192, 51, 131, 53, 56, -3, 97, 196, 32, 1, 64, 16, 12, 12, 54, 240, 204, 96, 13, 202, 32, 24, 49, 72, 0, 16, 4, 3, 131, 13, 60, 51, 88, 3, 50, 136, 70, 12, 18, 0, 4, 193, 192, 96, 3, 111, 12, 214, 0, 13, 32, 4, 0, 0, 0, 0, 0, 0, 1, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 3, 0, 0, 0, 0, 13, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 0, 0, 0, 0, 0, 5, 0, 0, 0, 14, 85, 73, 69, 102, 102, 101, 99, 116, 83, 104, 97, 100, 101, 114, 1, 106, 42, 7, 162, 27, 237, 106, 222, 50, 98, 90, 162, 184, 250, +121, 109, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, +9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 12, 67, 111, 108, 111, 114, 85, 116, 105, 108, 105, 116, 121, 1, 250, 224, 90, 153, 6, 127, 65, 54, 117, 58, 54, 245, 183, 57, 88, 202, 0, 2, 0, 0, 0, 0, 5, +0, 0, 0, 1, 92, 44, 138, 0, 10, 250, 131, 12, 168, 123, 143, 12, 28, 101, 152, 51, 0, 165, 8, 0, 0, 68, 88, 66, 67, 137, 222, 21, 142, 162, 27, 39, 186, 66, 23, 203, 124, 217, 194, 66, 172, 1, 0, 0, 0, 165, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, +0, 207, 0, 0, 0, 9, 1, 0, 0, 5, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, +0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 244, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 3, 1, 0, 3, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 84, +69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, +0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 6, 0, 0, 96, 0, 0, 0, 166, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 6, 0, 0, 66, 67, +192, 222, 33, 12, 0, 0, 157, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, +200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, +3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 86, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, +194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 64, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, +121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, +128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, +0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 197, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 0, 0, 24, 0, 0, 0, 160, 4, 0, 0, +128, 129, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, +144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, +14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, +12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 28, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, +3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 163, 1, 0, 0, 128, 17, 0, +2, 0, 0, 0, 40, 133, 98, 32, 5, 0, 0, 128, 146, 40, 132, 2, 1, 0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 140, 9, 130, 80, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 199, 6, 36, +16, 134, 32, 32, 2, 96, 130, 96, 32, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 64, 50, 65, 56, 148, 9, 2, 176, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, +64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 0, 179, 65, 32, 32, 10, 112, 115, 19, 4, 224, 218, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 32, 1, 27, 128, 13, +67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 130, 77, 16, 20, 103, 67, 16, 76, 16, 20, 104, 195, 18, 116, 222, 7, 6, 97, 64, 132, 65, 240, 1, 27, 2, 98, 130, 160, 100, 27, 22, 162, 243, 190, 49, 8, 3, 130, 12, 136, 15, 216, 16, +32, 19, 4, 229, 217, 176, 32, 157, 247, 153, 65, 24, 16, 103, 128, 124, 192, 134, 65, 12, 202, 0, 13, 152, 76, 89, 125, 81, 133, 201, 157, 149, 209, 77, 16, 20, 109, 195, 18, 168, 129, 183, 6, 96, 240, 17, 100, 16, 124, 192, 134, 128, 13, 54, 12, 105, 208, 6, 0, 199, 160, 42, 169, 200, +204, 172, 108, 140, 110, 10, 45, 140, 172, 76, 142, 135, 78, 174, 174, 204, 199, 5, 106, 170, 41, 44, 205, 237, 235, 74, 46, 12, 14, 174, 76, 110, 67, 129, 189, 129, 27, 92, 64, 21, 54, 54, 187, 54, 151, 52, 178, 50, 55, 186, 41, 65, 83, 133, 12, 207, 197, 174, 76, 110, 46, 237, 205, 109, +74, 224, 52, 33, 195, 115, 177, 11, 99, 179, 43, 147, 155, 18, 64, 117, 200, 240, 92, 230, 208, 194, 200, 202, 228, 154, 222, 200, 202, 216, 166, 4, 83, 25, 50, 60, 23, 185, 178, 185, 183, 58, 185, 177, 178, 185, 41, 129, 85, 137, 12, 207, 133, 46, 15, 174, 44, 200, 205, 237, 141, 46, 140, 46, +237, 205, 109, 110, 74, 176, 213, 33, 195, 115, 41, 115, 163, 147, 203, 131, 122, 75, 115, 163, 155, 155, 18, 188, 1, 0, 113, 32, 0, 0, 25, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 130, 78, 155, 225, 180, 251, 123, 149, 135, +225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 64, 26, 46, 223, 121, 124, 33, 34, 128, 137, 8, 129, 102, 88, 8, 27, 128, 134, 203, 119, 30, 95, 2, 152, 103, 33, 252, 226, 182, 141, 160, 26, 46, 223, 121, 124, 105, 114, 34, 2, 165, 166, 135, +154, 252, 226, 182, 1, 0, 97, 32, 0, 0, 59, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 218, 83, 85, 141, 51, 98, 144, 0, 32, 8, 6, 203, 6, 89, 86, 243, 140, 24, 36, 0, 8, 130, 193, 194, 69, 214, 245, 64, 35, 6, 9, 0, 130, 96, 176, 116, 210, 133, 61, 209, +136, 65, 2, 128, 32, 24, 44, 222, 132, 101, 143, 52, 98, 144, 0, 32, 8, 6, 203, 71, 101, 218, 51, 141, 24, 36, 0, 8, 130, 193, 2, 6, 21, 182, 77, 212, 136, 65, 2, 128, 32, 24, 56, 96, 0, 69, 28, 135, 141, 24, 36, 0, 8, 130, 129, 19, 6, 81, 213, 117, 217, 136, 193, 3, +128, 32, 24, 64, 97, 0, 5, 66, 130, 68, 209, 117, 93, 209, 104, 66, 0, 140, 38, 8, 193, 104, 194, 32, 140, 38, 16, 195, 112, 3, 66, 5, 211, 13, 68, 17, 76, 55, 16, 134, 48, 221, 64, 28, 131, 33, 144, 4, 140, 128, 36, 96, 4, 36, 1, 35, 32, 9, 140, 24, 36, 0, 8, 130, +65, 212, 6, 219, 26, 172, 193, 24, 16, 35, 6, 9, 0, 130, 96, 16, 181, 193, 182, 6, 107, 32, 6, 195, 136, 65, 2, 128, 32, 24, 68, 109, 176, 173, 193, 26, 132, 129, 48, 98, 144, 0, 32, 8, 6, 81, 27, 108, 107, 176, 6, 96, 16, 32, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, +1, 0, 0, 0, 1, 164, 179, 85, 37, 28, 243, 21, 181, 58, 52, 132, 154, 126, 102, 214, 232, 0, 159, 8, 0, 0, 68, 88, 66, 67, 51, 98, 248, 14, 78, 222, 169, 151, 180, 193, 108, 137, 163, 189, 192, 229, 1, 0, 0, 0, 159, 8, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, +0, 0, 248, 0, 0, 0, 175, 1, 0, 0, 255, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 172, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, +84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 175, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 145, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 1, 254, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, +80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 72, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, +0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, +0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, +0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 3, 0, 0, 0, 1, 3, 65, 0, 3, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 46, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 55, 0, 0, 0, 2, 0, 0, +0, 1, 2, 65, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 152, 5, 0, 0, 96, 0, 1, 0, 102, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 128, 5, 0, 0, 66, 67, 192, 222, 33, 12, 0, +0, 93, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, +72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, +0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, +0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, +0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, +32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, +7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, +0, 0, 0, 100, 129, 0, 0, 0, 0, 24, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, +34, 40, 3, 26, 0, 0, 0, 24, 35, 144, 81, 26, 79, 191, 49, 2, 210, 70, 123, 249, 27, 35, 16, 205, 85, 39, 61, 18, 0, 0, 0, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 0, 0, 121, 24, 0, 0, 99, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, +155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 33, 218, 48, 32, 9, +49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 144, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 105, 195, 50, 64, 145, 100, 73, 195, 53, 72, +192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 9, 130, 192, 108, 8, 184, 9, 2, 113, 108, 88, 56, 40, 146, 58, 105, 240, 56, 9, 216, 64, 84, 216, 246, 109, 88, 8, 40, 146, 38, 106, 160, 8, 9, 216, 176, 12, 80, 36, 89, 212, 112, 13, 18, 176, 97, 201, +160, 72, 210, 168, 193, 203, 36, 128, 203, 148, 213, 23, 212, 219, 92, 26, 93, 218, 155, 219, 4, 129, 80, 54, 44, 28, 25, 68, 101, 48, 93, 195, 197, 73, 192, 6, 34, 12, 196, 96, 12, 204, 96, 195, 0, 6, 103, 0, 112, 12, 170, 146, 138, 204, 204, 202, 198, 232, 166, 208, 194, 200, 202, 228, +120, 232, 228, 234, 202, 124, 92, 172, 166, 154, 194, 210, 220, 190, 174, 228, 194, 224, 224, 202, 228, 54, 20, 75, 26, 160, 1, 0, 84, 97, 99, 179, 107, 115, 73, 35, 43, 115, 163, 155, 18, 4, 85, 200, 240, 92, 236, 202, 228, 230, 210, 222, 220, 166, 4, 68, 19, 50, 60, 23, 187, 48, 54, 187, +50, 185, 41, 129, 81, 135, 12, 207, 101, 14, 45, 140, 172, 76, 174, 233, 141, 172, 140, 109, 74, 144, 84, 34, 195, 115, 161, 203, 131, 43, 11, 114, 115, 123, 163, 11, 163, 75, 123, 115, 155, 155, 18, 56, 117, 200, 240, 92, 202, 220, 232, 228, 242, 160, 222, 210, 220, 232, 230, 166, 4, 105, 0, 0, +0, 113, 32, 0, 0, 18, 0, 0, 0, 5, 48, 6, 213, 100, 209, 108, 46, 143, 233, 83, 116, 152, 92, 150, 243, 232, 242, 122, 217, 231, 178, 78, 155, 225, 180, 251, 123, 149, 135, 225, 240, 178, 220, 2, 166, 225, 242, 157, 199, 95, 28, 96, 16, 155, 135, 154, 252, 226, 182, 77, 160, 26, 46, 223, +121, 124, 105, 114, 34, 2, 165, 166, 135, 154, 252, 226, 182, 1, 0, 0, 0, 97, 32, 0, 0, 87, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 20, 19, 20, 69, 206, 51, 98, 144, 0, 32, 8, 6, 5, 21, 73, 146, 3, 141, 24, 36, 0, 8, 130, 65, 81, 73, 206, 4, 69, 35, +6, 9, 0, 130, 96, 80, 88, 211, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 5, 85, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 69, 214, 67, 141, 24, 36, 0, 8, 130, 65, 145, 89, 207, 69, 85, 35, 6, 9, 0, 130, 96, 80, 104, 23, 132, 81, 214, 136, 65, 2, 128, 32, 24, +20, 27, 22, 101, 211, 53, 98, 144, 0, 32, 8, 6, 5, 151, 73, 218, 132, 141, 24, 36, 0, 8, 130, 65, 209, 105, 210, 134, 101, 86, 72, 18, 176, 98, 146, 128, 21, 148, 4, 108, 160, 32, 96, 67, 5, 1, 27, 44, 8, 216, 50, 72, 192, 150, 65, 2, 182, 12, 18, 176, 33, 131, 128, 13, +26, 4, 108, 216, 32, 96, 209, 32, 1, 139, 6, 9, 88, 52, 72, 96, 196, 32, 1, 64, 16, 12, 12, 54, 240, 196, 96, 13, 208, 0, 27, 49, 72, 0, 16, 4, 3, 131, 13, 60, 49, 88, 131, 51, 184, 70, 12, 18, 0, 4, 193, 192, 96, 3, 79, 12, 214, 160, 12, 172, 17, 131, 4, 0, +65, 48, 48, 216, 192, 19, 131, 53, 32, 131, 106, 196, 32, 1, 64, 16, 12, 12, 54, 240, 214, 96, 13, 208, 64, 27, 49, 72, 0, 16, 4, 3, 131, 13, 188, 53, 88, 131, 51, 200, 70, 12, 18, 0, 4, 193, 192, 96, 3, 207, 12, 214, 0, 13, 134, 17, 131, 4, 0, 65, 48, 48, 216, 192, +51, 131, 53, 56, 3, 97, 196, 32, 1, 64, 16, 12, 12, 54, 240, 204, 96, 13, 202, 32, 24, 49, 72, 0, 16, 4, 3, 131, 13, 60, 51, 88, 3, 50, 136, 70, 12, 18, 0, 4, 193, 192, 96, 3, 111, 12, 214, 0, 13, 32, 4, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs index c536709ed1..7e9a9c9e9f 100644 --- a/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs +++ b/sources/engine/Stride.Graphics/Shaders.Bytecodes/UIEffect.bytecodeSRgb.Vulkan.Level_9_1.cs @@ -3,7 +3,7 @@ // Stride Effect Compiler File Generated: // Effect [UIEffect] // -// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=obj/app_data --build-path=obj/build_app_data --package-file=Graphics.sdpkg +// Command Line: C:\dev\stride\sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.dll --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\app_data --build-path=C:\dev\stride\sources\engine\Stride.Graphics\Shaders.Bytecodes\obj\build_app_data --package-file=Graphics.sdpkg // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd index 3f466d2f8c..661e0913f0 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/CompileShaders.cmd @@ -2,7 +2,7 @@ setlocal set StrideSdkDir=%~dp0..\..\..\..\ set StrideAssetCompiler=%StrideSdkDir%sources\assets\Stride.Core.Assets.CompilerApp\bin\Debug\net10.0\Stride.Core.Assets.CompilerApp.exe -rmdir /s /q %~dp0obj\ +rmdir /s /q %~dp0obj\ 2>nul %StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D11 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengl --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg -%StrideAssetCompiler% --platform=Windows --property:RuntimeIdentifier=win-opengles --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Direct3D12 --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg +%StrideAssetCompiler% --platform=Windows --property:StrideGraphicsApi=Vulkan --output-path=%~dp0obj\app_data --build-path=%~dp0obj\build_app_data --package-file=Graphics.sdpkg diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index fa4ffdb3b5..bcc6764f8e 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -19,59 +19,57 @@ internal partial class SignedDistanceFieldFontShader 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, -116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, -108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, -97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, -82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, -103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 54, 67, 254, 59, 57, 53, 190, 195, 40, 178, 220, 97, 132, 102, 97, -29, 0, 176, 87, 0, 0, 68, 88, 66, 67, 67, 121, 8, 66, 69, 60, 175, 110, 94, 8, 210, 5, 46, 132, 244, 193, 1, 0, 0, 0, 176, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, 0, 248, 7, 0, 0, 0, 86, 0, 0, 124, 86, 0, 0, 48, 87, 0, 0, 124, 87, -0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, 85, 71, 40, 0, -0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, -110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 52, 54, 53, -56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 93, 0, 0, 0, 252, 3, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 63, 0, -0, 0, 28, 4, 0, 0, 63, 0, 0, 0, 48, 4, 0, 0, 63, 0, 0, 0, 64, 4, 0, 0, 75, 0, 0, 0, 80, 4, 0, 0, 76, 0, 0, 0, 96, 4, 0, 0, 76, 0, 0, 0, 108, 4, 0, 0, 76, 0, 0, 0, 120, 4, 0, 0, 76, 0, 0, 0, 132, 4, 0, 0, 77, 0, -0, 0, 148, 4, 0, 0, 77, 0, 0, 0, 168, 4, 0, 0, 77, 0, 0, 0, 184, 4, 0, 0, 77, 0, 0, 0, 196, 4, 0, 0, 77, 0, 0, 0, 212, 4, 0, 0, 77, 0, 0, 0, 232, 4, 0, 0, 77, 0, 0, 0, 248, 4, 0, 0, 78, 0, 0, 0, 8, 5, 0, 0, 87, 0, -0, 0, 24, 5, 0, 0, 87, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, -0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 145, 1, 0, 0, 164, 1, 0, 0, 5, 0, 0, 0, 1, 0, -4, 0, 1, 0, 1, 0, 180, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, -255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, -3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, -116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 132, 2, 0, 0, 148, 2, 0, 0, 164, 2, 0, 0, 164, 1, 0, 0, 5, 0, -0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 176, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, -0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 8, 2, 0, 0, 42, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 224, 1, -0, 0, 1, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 108, 2, 0, 0, 140, 1, 0, 0, 120, 2, 0, 0, 192, 2, 0, 0, 2, 0, 0, 0, 208, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, -72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, -64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, -0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, -255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, -170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, -85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, -1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, -16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, -0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, -0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, -16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, -0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, -16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, -128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, -0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, -0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, -68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, +83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, +93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, +24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 166, 140, 232, 18, 44, 72, 166, 25, 85, 63, 103, +141, 42, 253, 103, 138, 0, 176, 87, 0, 0, 68, 88, 66, 67, 32, 244, 151, 4, 32, 85, 15, 229, 253, 0, 218, 57, 246, 72, 77, 132, 1, 0, 0, 0, 176, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 164, 5, 0, 0, 248, 7, 0, 0, 0, 86, 0, 0, 124, 86, 0, 0, 48, 87, +0, 0, 124, 87, 0, 0, 65, 111, 110, 57, 96, 5, 0, 0, 96, 5, 0, 0, 0, 2, 255, 255, 56, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 232, 0, 68, 66, +85, 71, 40, 0, 0, 0, 116, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 232, 2, 0, 0, 140, 1, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, +101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 48, +67, 70, 50, 68, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 168, 3, 0, 0, 0, 0, 255, 255, 192, 3, 0, 0, 0, 0, 255, 255, 216, 3, 0, 0, 0, 0, 255, 255, 228, 3, 0, 0, 0, 0, 255, 255, 240, 3, 0, 0, 93, 0, 0, 0, 252, 3, 0, 0, 63, 0, 0, 0, 12, 4, +0, 0, 63, 0, 0, 0, 28, 4, 0, 0, 63, 0, 0, 0, 48, 4, 0, 0, 63, 0, 0, 0, 64, 4, 0, 0, 75, 0, 0, 0, 80, 4, 0, 0, 76, 0, 0, 0, 96, 4, 0, 0, 76, 0, 0, 0, 108, 4, 0, 0, 76, 0, 0, 0, 120, 4, 0, 0, 76, 0, 0, 0, 132, 4, +0, 0, 77, 0, 0, 0, 148, 4, 0, 0, 77, 0, 0, 0, 168, 4, 0, 0, 77, 0, 0, 0, 184, 4, 0, 0, 77, 0, 0, 0, 196, 4, 0, 0, 77, 0, 0, 0, 212, 4, 0, 0, 77, 0, 0, 0, 232, 4, 0, 0, 77, 0, 0, 0, 248, 4, 0, 0, 78, 0, 0, 0, 8, 5, +0, 0, 87, 0, 0, 0, 24, 5, 0, 0, 87, 0, 0, 0, 40, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, +0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 145, 1, 0, 0, 164, 1, 0, 0, 5, 0, +0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 180, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 22, 0, +0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, 0, 0, 0, +1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 132, 2, 0, 0, 148, 2, 0, 0, 164, 2, 0, 0, 164, 1, +0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 176, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, +0, 0, 140, 1, 0, 0, 188, 1, 0, 0, 1, 0, 0, 0, 204, 1, 0, 0, 0, 0, 0, 0, 216, 1, 0, 0, 224, 1, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 8, 2, 0, 0, 42, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 56, 2, 0, 0, 0, 0, 0, 0, 68, 2, +0, 0, 224, 1, 0, 0, 1, 0, 0, 0, 76, 2, 0, 0, 0, 0, 0, 0, 88, 2, 0, 0, 164, 1, 0, 0, 1, 0, 0, 0, 108, 2, 0, 0, 140, 1, 0, 0, 120, 2, 0, 0, 192, 2, 0, 0, 2, 0, 0, 0, 208, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, +40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, +0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, +228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, +0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, +2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, +17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, +0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, +0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, +0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, +16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, +0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, +0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, +89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, +128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, +0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, +16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, +0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -79,7 +77,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -87,7 +85,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -95,7 +93,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -103,151 +101,151 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 101, 172, 148, 56, 6, 121, 111, 74, 182, 211, 205, 109, 42, 91, 96, 58, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, -51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 33, 149, 193, 163, 183, 35, 84, 68, 147, 93, 175, 219, 220, 42, 202, 233, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, -116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, -116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, -32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, -105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, -110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, -111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, -95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 20, 41, -3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 223, 101, 2, 0, 118, 213, 0, 0, 118, 199, 0, 0, 231, 242, 2, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, +116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, +114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, +32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, +101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, +97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, +115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, +80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, +3, 0, 20, 41, 3, 0, 183, 112, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 252, 157, 2, 0, 145, 142, 1, 0, 118, 213, 0, 0, 118, 199, 0, 0, 133, 250, 1, 0, 50, 237, 0, 0, 184, 172, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, -59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, -65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, -105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, -84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, -95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, -116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, -84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, -32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 32, -83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, -114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, -99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, -120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, -98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, -48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, -121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, -115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, -104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, -111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, -121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, -99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, -105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, -110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, -114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, -116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, -114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, -40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, -10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, -103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, -32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, -44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 54, -32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, 95, 50, 57, 56, 44, 32, 95, 51, 48, 50, -44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, -80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, -97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, -110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, -97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, -46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, -95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, -61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, +83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, +111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, +100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, +86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, +114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, +101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, +95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, +117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, +111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, +83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, +111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, +32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, +52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, +32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, +48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, +108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, +32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, +105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, +119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, +32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, +97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, +115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, +101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, +111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, +102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, +67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, +108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, +114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, +108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, +48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +95, 50, 57, 54, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, 95, 50, 57, 56, 44, 32, +95, 51, 48, 50, 44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, +100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, +110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, +32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, +68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, +116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, +103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, -83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 52, 54, 53, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, -117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, -50, 57, 51, 97, 97, 50, 54, 52, 54, 53, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, -83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 111, 214, 223, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 206, 254, 205, 56, 235, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, -109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, -108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 216, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, -0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, -252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, -4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, -62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 212, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 43, 11, 96, 4, 129, 248, 8, 0, 13, 42, 1, 80, 12, 129, 248, 0, 0, -0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 208, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 68, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 67, 1, 80, 12, 129, 248, 0, 0, 54, 0, 77, 17, 60, 2, 0, 0, 204, 4, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 98, -11, 32, 13, 76, 6, 14, 12, 129, 212, 36, 8, 0, 9, 34, 13, 97, 1, 80, 6, 15, 3, 0, 9, 19, 13, 75, 6, 14, 12, 129, 212, 36, 0, 0, 58, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, -4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 8, 0, 0, 0, 110, 0, 77, 17, 100, 2, 0, 0, 200, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, -13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, -6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, 0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, -36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, -105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, -0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 206, 133, 155, 45, 155, 186, 30, 169, 229, 194, 182, 63, 124, 126, 159, 10, -0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 121, 0, 0, 128, 80, 0, 0, 0, 121, 0, 0, 0, 116, 0, 0, 0, 121, 0, 0, 128, 116, 0, 0, 0, 121, 0, -0, 0, 144, 0, 0, 0, 121, 0, 0, 128, 144, 0, 0, 0, 121, 0, 0, 0, 172, 0, 0, 0, 121, 0, 0, 128, 172, 0, 0, 0, 121, 0, 0, 0, 200, 0, 0, 0, 121, 0, 0, 128, 200, 0, 0, 0, 121, 0, 0, 0, 228, 0, 0, 0, 121, 0, 0, 128, 228, 0, 0, 0, 121, 0, -0, 0, 248, 0, 0, 0, 121, 0, 0, 128, 248, 0, 0, 0, 121, 0, 0, 0, 12, 1, 0, 0, 121, 0, 0, 128, 12, 1, 0, 0, 121, 0, 0, 0, 48, 1, 0, 0, 121, 0, 0, 128, 48, 1, 0, 0, 121, 0, 0, 0, 84, 1, 0, 0, 121, 0, 0, 128, 84, 1, 0, 0, 121, 0, -0, 0, 112, 1, 0, 0, 121, 0, 0, 128, 112, 1, 0, 0, 121, 0, 0, 0, 152, 1, 0, 0, 121, 0, 0, 128, 152, 1, 0, 0, 121, 0, 0, 0, 180, 1, 0, 0, 121, 0, 0, 128, 180, 1, 0, 0, 121, 0, 0, 0, 216, 1, 0, 0, 121, 0, 0, 128, 216, 1, 0, 0, 121, 0, -0, 0, 244, 1, 0, 0, 121, 0, 0, 128, 244, 1, 0, 0, 121, 0, 0, 0, 16, 2, 0, 0, 121, 0, 0, 128, 16, 2, 0, 0, 121, 0, 0, 0, 44, 2, 0, 0, 121, 0, 0, 128, 44, 2, 0, 0, 121, 0, 0, 0, 72, 2, 0, 0, 124, 0, 0, 128, 72, 2, 0, 0, 124, 0, -0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, -15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, -15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 92, 0, -0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 166, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, +105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 48, 67, 70, 50, 68, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, +101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, +48, 48, 48, 48, 50, 52, 55, 49, 99, 48, 99, 102, 50, 100, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, +99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, +116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 217, 229, 127, 184, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 206, 254, 205, 56, 235, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, +114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, +0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 216, 4, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, +62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, +0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, +0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, +252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 212, 4, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 43, 11, 96, 4, 129, 248, 8, 0, 13, 42, 1, 80, 12, +129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 208, 4, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 68, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 67, 1, 80, 12, 129, 248, 0, 0, 54, 0, 77, 17, 60, 2, 0, 0, 204, 4, 0, 0, 2, 16, 0, 0, 7, 0, +9, 5, 13, 98, 11, 32, 13, 76, 6, 14, 12, 129, 212, 36, 8, 0, 9, 34, 13, 97, 1, 80, 6, 15, 3, 0, 9, 19, 13, 75, 6, 14, 12, 129, 212, 36, 0, 0, 58, 0, 62, 17, 1, 16, 0, 0, 8, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, +110, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, +5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 132, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 56, 0, 8, 0, 0, 0, 110, 0, 77, 17, 100, 2, 0, 0, 200, 4, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, +6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, +9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 32, 3, 0, 0, 196, 4, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 45, +6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 17, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, +4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 206, 133, 155, 45, 155, 186, 30, 169, 229, 194, 182, 63, +124, 126, 159, 10, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, 0, 80, 0, 0, 0, 121, 0, 0, 128, 80, 0, 0, 0, 121, 0, 0, 0, 116, 0, 0, 0, 121, 0, 0, 128, 116, 0, +0, 0, 121, 0, 0, 0, 144, 0, 0, 0, 121, 0, 0, 128, 144, 0, 0, 0, 121, 0, 0, 0, 172, 0, 0, 0, 121, 0, 0, 128, 172, 0, 0, 0, 121, 0, 0, 0, 200, 0, 0, 0, 121, 0, 0, 128, 200, 0, 0, 0, 121, 0, 0, 0, 228, 0, 0, 0, 121, 0, 0, 128, 228, 0, +0, 0, 121, 0, 0, 0, 248, 0, 0, 0, 121, 0, 0, 128, 248, 0, 0, 0, 121, 0, 0, 0, 12, 1, 0, 0, 121, 0, 0, 128, 12, 1, 0, 0, 121, 0, 0, 0, 48, 1, 0, 0, 121, 0, 0, 128, 48, 1, 0, 0, 121, 0, 0, 0, 84, 1, 0, 0, 121, 0, 0, 128, 84, 1, +0, 0, 121, 0, 0, 0, 112, 1, 0, 0, 121, 0, 0, 128, 112, 1, 0, 0, 121, 0, 0, 0, 152, 1, 0, 0, 121, 0, 0, 128, 152, 1, 0, 0, 121, 0, 0, 0, 180, 1, 0, 0, 121, 0, 0, 128, 180, 1, 0, 0, 121, 0, 0, 0, 216, 1, 0, 0, 121, 0, 0, 128, 216, 1, +0, 0, 121, 0, 0, 0, 244, 1, 0, 0, 121, 0, 0, 128, 244, 1, 0, 0, 121, 0, 0, 0, 16, 2, 0, 0, 121, 0, 0, 128, 16, 2, 0, 0, 121, 0, 0, 0, 44, 2, 0, 0, 121, 0, 0, 128, 44, 2, 0, 0, 121, 0, 0, 0, 72, 2, 0, 0, 124, 0, 0, 128, 72, 2, +0, 0, 124, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, +16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 105, 0, 0, 0, 2, 16, 0, 0, 0, 0, +0, 0, 92, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 67, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 68, 0, 0, 242, 241, 10, 0, 24, 21, 22, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 248, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 22, 0, -27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, -86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, -5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, -1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, -8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, -0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, 0, 0, 1, 0, -1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 25, 16, 0, 0, 248, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 0, 0, +0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, +83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, +242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, +0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, +1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 14, 16, 0, 0, 18, 0, 1, 18, 3, 0, +0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 17, 16, 0, 0, 23, 0, 3, 0, 16, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 68, 0, 0, 242, 241, 10, 0, 24, 21, 19, 16, +0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 41, 75, 0, 0, 147, 199, 1, 0, 236, 252, 0, 0, 110, 155, 0, 0, 215, 58, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -255,71 +253,71 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, -102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, -123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, -97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, -123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, -48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, -107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, -67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, -99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, -32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, -32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, -111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, -68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, -116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, -114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, -116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, -112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, -101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, -61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, -109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, -44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -52, 32, 95, 50, 57, 54, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, 95, 50, 57, 56, -44, 32, 95, 51, 48, 50, 44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, -104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, -70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, -114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, -101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, -101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, -32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, -32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 186, 0, 0, 0, -93, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, -1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, -80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, -1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, +83, 59, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, +32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, +32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, +115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, +48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, +84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 52, 56, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 49, 32, 61, 32, 115, 97, 109, +112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 49, 53, 53, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, +115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 49, 52, 56, 44, 32, 95, 49, 53, 49, 44, 32, 95, 49, 53, 53, 41, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, +111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, +99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, +32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, +32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, +102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, +103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, +104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, +98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, +108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, +101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, +103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, +48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 52, 32, 95, 50, 57, 54, 32, 61, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 50, 57, 56, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, +108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 50, 32, 61, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 48, 52, 32, 61, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, +110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 48, 56, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 50, 57, 54, 44, 32, +95, 50, 57, 56, 44, 32, 95, 51, 48, 50, 44, 32, 95, 51, 48, 52, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 48, 56, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, +105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, +120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, +83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, +110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, +186, 0, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 5, 16, 0, 0, 220, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 20, 0, 0, 0, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, +0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, +100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, +242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 22, 0, -1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, -80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 242, 241, 46, 0, -1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 20, 0, 0, 0, 8, 0, 0, 0, 28, 0, 0, 0, 0, 0, +0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, +100, 101, 114, 95, 80, 83, 77, 97, 105, 110, 0, 243, 242, 241, 50, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, +242, 241, 46, 0, 1, 22, 0, 0, 0, 0, 15, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 18, 16, 0, 0, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -327,15 +325,15 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, -0, 0, 38, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 38, 0, 81, 17, 21, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, +117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 24, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -343,31 +341,31 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, 0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, -255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, -101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, -54, 52, 54, 53, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 220, 4, 0, 0, 0, 0, 0, 0, 56, 2, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, +1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, +99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, +55, 49, 67, 48, 67, 70, 50, 68, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 101, 172, 148, 56, 6, 121, 111, 74, 182, 211, 205, 109, 42, 91, 96, 58, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, -101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, -115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 52, 54, 53, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 0, 0, -0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 33, 149, 193, 163, 183, 35, 84, 68, 147, 93, 175, 219, 220, 42, 202, 233, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, +104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, +105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 48, 99, 102, 50, 100, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 30, +0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 48, 2, 0, 0, 111, 1, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 214, 13, 0, 0, 128, 0, 0, 0, 235, 12, 0, 0, 36, 7, 0, 0, 108, 0, 0, 0, 28, 0, 0, 0, 40, 0, 0, 0, 56, 2, -0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, -0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, -0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 48, 2, 0, 0, 111, 1, 0, 0, 20, 1, 0, 0, 0, 0, 0, 0, 214, 13, 0, 0, 128, 0, 0, 0, 235, 12, 0, 0, 36, 7, 0, 0, 108, 0, 0, 0, 28, 0, 0, 0, 40, 0, +0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, +0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, +0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -375,37 +373,37 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, -0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, -103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, -0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, -171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 213, 173, 154, -222, 25, 165, 76, 67, 10, 134, 213, 141, 158, 184, 169, 173, 0, 100, 67, 0, 0, 68, 88, 66, 67, 47, 117, 61, 184, 133, 136, 144, 187, 52, 61, 201, 9, 132, 86, 139, 127, 1, 0, 0, 0, 100, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, 0, 0, 188, 65, -0, 0, 56, 66, 0, 0, 132, 66, 0, 0, 244, 66, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, 0, 0, 1, 2, -254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, -115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, -48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 80, 0, 0, 0, 112, 2, 0, 0, 82, 0, 0, 0, 132, 2, 0, 0, 84, 0, 0, 0, 144, 2, -0, 0, 80, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, -171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, -3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, -116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 120, 1, 0, 0, 216, 0, 0, 0, 135, 1, 0, 0, 248, 0, 0, 0, 150, 1, -0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 0, 0, 0, 0, 192, 0, -0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 1, 0, 0, 192, 0, 0, 0, 108, 1, 0, 0, 188, 1, 0, 0, 3, 0, 0, 0, 204, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, -105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, 228, 160, 1, 0, -228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, 0, 0, 95, 0, 0, 3, 50, 16, -16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, -0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, -0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, 0, 0, 0, 0, -0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, +117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, +0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, +82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, +1, 81, 49, 68, 163, 212, 254, 182, 141, 158, 113, 161, 11, 50, 189, 8, 175, 0, 100, 67, 0, 0, 68, 88, 66, 67, 182, 146, 87, 1, 240, 21, 39, 145, 164, 96, 220, 224, 90, 39, 166, 98, 1, 0, 0, 0, 100, 67, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 24, 3, 0, 0, 180, 3, +0, 0, 188, 65, 0, 0, 56, 66, 0, 0, 132, 66, 0, 0, 244, 66, 0, 0, 65, 111, 110, 57, 212, 2, 0, 0, 212, 2, 0, 0, 0, 2, 254, 255, 172, 2, 0, 0, 40, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 36, 0, 1, 0, 36, 0, 0, 0, +0, 0, 1, 2, 254, 255, 254, 255, 145, 0, 68, 66, 85, 71, 40, 0, 0, 0, 24, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 7, 0, 0, 0, 136, 0, 0, 0, 2, 0, 0, 0, 240, 1, 0, 0, 192, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, +120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 50, 52, 66, 49, 68, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 76, 2, 0, 0, 0, 0, 255, 255, 88, 2, 0, 0, 0, 0, 255, 255, 100, 2, 0, 0, 80, 0, 0, 0, 112, 2, 0, 0, 82, 0, 0, 0, 132, 2, 0, 0, 84, 0, +0, 0, 144, 2, 0, 0, 80, 0, 0, 0, 156, 2, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, +111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 197, 0, 0, 0, 216, 0, 0, 0, 232, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, +10, 0, 1, 0, 3, 0, 20, 1, 0, 0, 3, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 4, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 5, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 0, 255, 255, 255, 255, 8, 0, 9, 0, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 120, 1, 0, 0, 216, 0, 0, 0, 135, 1, 0, 0, 248, 0, +0, 0, 150, 1, 0, 0, 248, 0, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 164, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 0, 0, +0, 0, 192, 0, 0, 0, 44, 1, 0, 0, 4, 0, 0, 0, 60, 1, 0, 0, 192, 0, 0, 0, 108, 1, 0, 0, 188, 1, 0, 0, 3, 0, 0, 0, 204, 1, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, +67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 4, 0, 0, 4, 0, 0, 3, 192, 1, 0, 255, 144, 0, 0, +228, 160, 1, 0, 228, 144, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 1, 0, 0, 2, 0, 0, 12, 192, 1, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 148, 0, 0, 0, 64, 0, 1, 0, 37, 0, 0, 0, 95, 0, +0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, +16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 2, 0, 0, 0, 70, 30, +16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 62, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 31, 0, 0, 0, 156, 0, +0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -413,7 +411,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 224, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -421,7 +419,7 @@ internal partial class SignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -429,7 +427,7 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -437,23 +435,23 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 213, 209, 7, 57, 253, 94, 237, 76, 147, 126, 206, 225, 16, 9, 113, 247, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 83, 118, 168, 214, 64, 212, 150, 69, 169, 118, 125, 171, 18, 75, 158, 206, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, -59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, -32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, -111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, -79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, -79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, +111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, +32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, +111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -461,112 +459,113 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, -32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, -59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, -111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, -97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, -32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, -78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, -111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, -32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, -110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, 10, 118, 111, 105, -100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, -101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, -108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, -120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, -116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, -103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, -105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, -111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, -117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, +111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, +108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, +101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, +73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, +116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, +95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, +97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, +83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 10, +10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, +83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, +116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, +83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, +117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, +32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, +116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, +103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, +116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, +32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 193, 7, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, -114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, -116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, -64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 51, 55, 99, 54, 99, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, -108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, -115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 212, 75, 226, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 37, 43, 96, 147, 6, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 193, 7, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, +100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 50, 52, 66, 49, 68, 48, 0, 0, 99, 58, 92, 100, +101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, +97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 50, 52, 98, 49, 100, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, +32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, +125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 184, 8, 130, 184, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 37, 43, 96, 147, 6, 7, 0, 0, 1, 0, 0, 0, 93, 0, +0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, +83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, +101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, +160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, +0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, +0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, +5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, +32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, +64, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, +4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, +80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 254, 226, 66, 242, 228, 132, 125, 7, 121, 105, 10, 74, 59, 30, 74, 161, 0, 0, 242, 0, 0, 0, 120, 0, +0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 90, 0, 0, 128, 84, 0, 0, 0, 90, 0, 0, 0, 104, 0, 0, 0, 90, 0, 0, 128, 104, 0, 0, 0, 90, 0, 0, 0, 124, 0, 0, 0, 90, 0, +0, 128, 124, 0, 0, 0, 90, 0, 0, 0, 144, 0, 0, 0, 90, 0, 0, 128, 144, 0, 0, 0, 90, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, +0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 80, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, +0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, +3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, +105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, +0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, +0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, +24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, -104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, -95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 8, 16, 0, 0, 84, 0, 0, 0, 1, 0, 160, 109, 97, 105, -110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, -4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, -80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, -64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, -4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, -117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 28, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 44, 0, -0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 84, 0, -0, 0, 1, 0, 64, 0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, -5, 0, 4, 0, 4, 0, 84, 0, 0, 0, 1, 0, 64, 0, 4, 0, 0, 0, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 254, 226, 66, 242, 228, 132, 125, 7, 121, 105, 10, 74, 59, 30, 74, 161, 0, 0, 242, 0, 0, 0, 120, 0, 0, 0, 0, 0, -0, 0, 1, 0, 1, 0, 148, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 108, 0, 0, 0, 84, 0, 0, 0, 90, 0, 0, 128, 84, 0, 0, 0, 90, 0, 0, 0, 104, 0, 0, 0, 90, 0, 0, 128, 104, 0, 0, 0, 90, 0, 0, 0, 124, 0, 0, 0, 90, 0, 0, 128, 124, 0, -0, 0, 90, 0, 0, 0, 144, 0, 0, 0, 90, 0, 0, 128, 144, 0, 0, 0, 90, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 4, 0, 0, 0, 0, 0, -0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 9, 16, 0, 0, 80, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 36, 0, 0, 0, 36, 0, 0, 0, 8, 0, 0, 0, 44, 0, -0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, -0, 0, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, -83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, -3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, -103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, -0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, +111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, +97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, +111, 110, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, +61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, +108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, +112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, +117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, +100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, +114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, -86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, -115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, -125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, -95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, -115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, -95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, -101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, -116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, -111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 8, 0, 0, 0, 8, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -580,48 +579,49 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 8, 3, 0, 0, 0, 0, 0, 0, 172, 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, +2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, +105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, +120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 50, 52, 66, 49, 68, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, -0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 8, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 1, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, -0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 148, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, -115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, -48, 48, 50, 57, 51, 65, 65, 51, 55, 67, 54, 67, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 83, 118, 168, 214, 64, 212, 150, 69, 169, 118, 125, 171, 18, 75, 158, 206, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, +101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, +100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 50, 52, 98, 49, 100, 48, 0, 4, 0, 0, 0, 6, +0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 213, 209, 7, 57, 253, 94, 237, 76, 147, 126, 206, 225, 16, 9, 113, 247, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, -115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, -114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 51, 55, 99, 54, 99, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, -0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 136, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 241, 7, 0, 0, 128, 0, 0, 0, 6, 7, 0, 0, 188, 3, 0, 0, 44, 0, +0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 25, 0, 0, 0, 17, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, +0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 136, 1, 0, 0, 111, 1, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 241, 7, 0, 0, 128, 0, 0, 0, 6, 7, 0, 0, 188, 3, 0, 0, 44, 0, 0, 0, 0, 0, -0, 0, 40, 0, 0, 0, 32, 2, 0, 0, 44, 0, 0, 0, 20, 0, 0, 0, 3, 0, 0, 0, 26, 0, 0, 0, 16, 0, 0, 0, 25, 0, 0, 0, 17, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, -0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 7, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 22, 0, 0, 0, 24, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -643,15 +643,13 @@ internal partial class SignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, -32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, -67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, -0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 28, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, +72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, +0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, +73, 79, 78, 0, 67, 79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, +0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs index 5d6c8f55fa..cade12f9d3 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -19,83 +19,81 @@ internal partial class SignedDistanceFieldFontShader 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, -101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, -239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, -0, 0, 1, 78, 45, 129, 4, 69, 150, 26, 206, 173, 86, 103, 253, 74, 248, 95, 173, 0, 92, 9, 0, 0, 68, 88, 66, 67, 82, 32, 71, 205, 2, 201, 188, 247, 239, 236, 190, 108, 196, 241, 77, 4, 1, 0, 0, 0, 92, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, -166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, -71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 200, 0, 0, 0, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 164, 7, 0, 0, 96, 0, 0, 0, 233, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 140, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 224, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, -7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, -66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, -3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 96, 205, 17, -128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, -24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, -0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, -72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, -0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, -109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, -96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, -16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, 51, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, -8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, -25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 104, 0, 0, 0, 96, 140, 64, -103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, 162, 16, 10, 4, 0, 121, 24, 0, 0, 110, 0, 0, 0, 26, 3, 76, 144, -70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, -192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, -38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 50, 6, 19, 4, 5, 218, 16, 4, 19, -4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 82, 6, 27, 150, 224, 12, 60, 52, 0, 131, 143, 32, 131, -224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 200, 6, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, 13, 214, 224, 2, -170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, -205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, 128, 13, 0, 0, 113, 32, 0, 0, 33, 0, 0, 0, 6, 192, 6, 44, -98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 159, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 210, 112, 249, 206, 227, 11, 17, 1, 76, 68, 8, 52, 195, 66, -216, 0, 52, 92, 190, 243, 248, 18, 192, 60, 11, 225, 23, 183, 109, 4, 208, 112, 249, 206, 227, 7, 72, 3, 68, 152, 95, 220, 182, 21, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 155, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, 0, 0, 0, -97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, 97, 128, 105, 35, -6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, 1, 150, 145, 1, 25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, 32, 8, 6, 208, -26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, 98, 112, 0, 32, 8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, 32, 8, 6, 145, -28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, 14, 188, 97, 196, 192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, 136, 0, 1, 11, -4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, 246, 9, 18, 176, 111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, 98, 196, 32, 1, -64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 155, 241, 82, 41, 74, -209, 136, 53, 172, 71, 81, 139, 220, 76, 49, 17, 0, 97, 7, 0, 0, 68, 88, 66, 67, 142, 41, 74, 179, 176, 33, 67, 173, 13, 207, 191, 178, 146, 233, 121, 65, 1, 0, 0, 0, 97, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, -105, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, -0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, -0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, -0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, -0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 240, 4, 0, -0, 96, 0, 1, 0, 60, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 216, 4, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 51, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, -12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, -0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, -144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, 0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, -16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, 0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, -14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, -116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 16, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, -24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, 34, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 92, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 68, 50, 104, 42, -155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 161, 217, 48, 32, 9, -49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 112, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 103, 195, 50, 64, 145, 100, 73, 195, 53, 72, -192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 13, 67, 133, 109, 27, 22, 2, 138, 164, 137, 26, 40, 66, 2, 54, 44, 3, 20, 73, 22, 53, 92, 131, 4, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 16, 202, 134, 37, 251, 34, 48, 152, 174, -225, 202, 36, 96, 195, 208, 121, 97, 176, 97, 224, 196, 0, 32, 27, 76, 165, 157, 185, 149, 145, 17, 165, 205, 209, 133, 185, 141, 149, 25, 165, 149, 177, 145, 25, 189, 185, 209, 77, 161, 133, 145, 149, 201, 185, 88, 77, 53, 133, 165, 185, 125, 93, 201, 133, 193, 193, 149, 201, 109, 40, 22, 50, 24, -3, 0, 168, 194, 198, 102, 215, 230, 146, 70, 86, 230, 70, 55, 37, 8, 170, 144, 225, 185, 216, 149, 201, 205, 165, 189, 185, 77, 9, 136, 38, 100, 120, 46, 118, 97, 108, 118, 101, 114, 83, 2, 163, 14, 25, 158, 203, 28, 90, 24, 89, 153, 92, 211, 27, 89, 25, 219, 148, 32, 169, 68, 134, 231, -66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 112, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 200, 0, 113, 32, 0, 0, 18, 0, 0, 0, 6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, -51, 177, 7, 48, 16, 145, 255, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 97, 32, 0, 0, 60, 0, 0, 0, 19, 4, 193, -136, 65, 2, 128, 32, 24, 20, 15, 211, 52, 202, 50, 98, 144, 0, 32, 8, 6, 5, 212, 56, 142, 194, 140, 24, 36, 0, 8, 130, 65, 17, 57, 202, 195, 52, 35, 6, 9, 0, 130, 96, 80, 72, 207, 2, 49, 206, 136, 65, 2, 128, 32, 24, 20, 19, 196, 68, 203, 51, 98, 144, 0, 32, 8, -6, 5, 21, 53, 210, 2, 141, 24, 36, 0, 8, 130, 65, 81, 73, 203, 4, 69, 35, 6, 9, 0, 130, 96, 80, 88, 19, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 213, 84, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 57, 214, 67, 141, 24, 36, 0, 8, 130, 129, 129, 57, 207, 69, -33, 35, 6, 9, 0, 130, 96, 96, 96, 206, 115, 77, 199, 136, 65, 2, 128, 32, 24, 24, 152, 243, 92, 145, 49, 98, 144, 0, 32, 8, 6, 6, 230, 60, 23, 84, 140, 24, 36, 0, 8, 130, 129, 129, 57, 215, 69, 41, 35, 6, 9, 0, 130, 96, 96, 96, 206, 117, 77, 201, 136, 65, 2, 128, -32, 24, 24, 152, 35, 93, 20, 49, 98, 144, 0, 32, 8, 6, 6, 230, 72, 215, 52, 140, 24, 36, 0, 8, 130, 129, 129, 57, 210, 21, 9, 35, 6, 9, 0, 130, 96, 96, 96, 142, 116, 65, 1, 2, 0, 0, 0, 0, 0, 1, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, +114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, +110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, +0, 0, 5, 0, 0, 0, 1, 78, 45, 129, 4, 69, 150, 26, 206, 173, 86, 103, 253, 74, 248, 95, 173, 0, 92, 9, 0, 0, 68, 88, 66, 67, 82, 32, 71, 205, 2, 201, 188, 247, 239, 236, 190, 108, 196, 241, 77, 4, 1, 0, 0, 0, 92, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, +68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, +68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, +200, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 164, 7, 0, 0, 96, 0, 0, 0, 233, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 140, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 224, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, +20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, +7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, +73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, +65, 96, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, +62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, +67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 20, 0, 0, 0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, +7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, +114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, +0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, 51, 1, 1, 48, 0, 0, 0, 0, 0, +0, 0, 64, 22, 8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, +128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, 0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 104, 0, 0, +0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, 162, 16, 10, 4, 0, 121, 24, 0, 0, 110, 0, 0, 0, +26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, 232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, +202, 96, 38, 8, 192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, +205, 6, 129, 8, 38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, 41, 162, 9, 130, 50, 6, 19, 4, 5, +218, 16, 4, 19, 4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, 82, 6, 27, 150, 224, 12, 60, 52, 0, +131, 143, 32, 131, 224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 200, 6, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, +13, 214, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, 67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, +225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, 128, 13, 0, 0, 113, 32, 0, 0, 33, 0, 0, 0, +6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, 196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 159, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 210, 112, 249, 206, 227, 11, 17, 1, 76, 68, +8, 52, 195, 66, 216, 0, 52, 92, 190, 243, 248, 18, 192, 60, 11, 225, 23, 183, 109, 4, 208, 112, 249, 206, 227, 7, 72, 3, 68, 152, 95, 220, 182, 21, 60, 195, 229, 59, 143, 79, 53, 64, 132, 249, 197, 109, 155, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, +3, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, 216, 136, 65, 2, 128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, +97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, 1, 150, 145, 1, 25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, +32, 8, 6, 208, 26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, 98, 112, 0, 32, 8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, +32, 8, 6, 145, 28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, 14, 188, 97, 196, 192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, +136, 0, 1, 11, 4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, 246, 9, 18, 176, 111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, +98, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 155, +241, 82, 41, 74, 209, 136, 53, 172, 71, 81, 139, 220, 76, 49, 17, 0, 97, 7, 0, 0, 68, 88, 66, 67, 142, 41, 74, 179, 176, 33, 67, 173, 13, 207, 191, 178, 146, 233, 121, 65, 1, 0, 0, 0, 97, 7, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, +93, 1, 0, 0, 105, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, +3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, +15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 4, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, +79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, +0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, +76, 240, 4, 0, 0, 96, 0, 1, 0, 60, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 216, 4, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 51, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, +57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, +16, 40, 140, 12, 0, 81, 24, 0, 0, 6, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 18, 0, 0, 73, 24, 0, 0, 2, 0, 0, 0, 19, 130, 96, 66, 32, 0, 0, 0, 137, 32, 0, 0, 28, 0, 0, 0, 50, 34, 8, +20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 144, 140, 0, 148, 0, 0, 0, 0, 96, 142, 0, 12, 102, 0, 230, 8, 144, 98, 12, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, +8, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 20, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 128, 0, 0, 0, 96, 0, 0, 0, 128, 2, 0, 0, 0, 6, 2, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, +80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, +7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, +33, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 2, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 6, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 100, 129, 0, 0, 0, 0, 16, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, +18, 0, 0, 0, 24, 1, 40, 132, 25, 0, 34, 0, 0, 0, 24, 1, 40, 1, 18, 0, 0, 0, 40, 1, 34, 0, 0, 0, 40, 130, 50, 32, 1, 0, 0, 128, 34, 40, 133, 98, 32, 2, 0, 0, 128, 146, 40, 4, 0, 121, 24, 0, 0, 92, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, +68, 50, 104, 42, 155, 11, 3, 177, 43, 147, 155, 75, 123, 115, 3, 145, 169, 113, 145, 113, 177, 1, 65, 57, 75, 163, 107, 161, 177, 49, 187, 185, 17, 155, 145, 129, 185, 73, 217, 16, 4, 19, 4, 1, 153, 32, 8, 195, 6, 97, 32, 38, 8, 2, 177, 65, 24, 12, 10, 118, 115, 19, 4, 161, +217, 48, 32, 9, 49, 65, 56, 128, 13, 192, 134, 129, 96, 152, 13, 65, 179, 97, 24, 22, 135, 8, 85, 17, 214, 208, 211, 147, 20, 209, 4, 129, 112, 38, 8, 132, 177, 33, 32, 38, 8, 68, 178, 97, 33, 160, 72, 154, 164, 129, 34, 36, 96, 67, 48, 76, 16, 136, 103, 195, 50, 64, 145, 100, +73, 195, 53, 72, 192, 4, 65, 88, 54, 4, 217, 134, 37, 131, 34, 73, 147, 134, 43, 147, 128, 13, 67, 133, 109, 27, 22, 2, 138, 164, 137, 26, 40, 66, 2, 54, 44, 3, 20, 73, 22, 53, 92, 131, 4, 112, 153, 178, 250, 130, 122, 155, 75, 163, 75, 123, 115, 155, 32, 16, 202, 134, 37, 251, +34, 48, 152, 174, 225, 202, 36, 96, 195, 208, 121, 97, 176, 97, 224, 196, 0, 32, 27, 76, 165, 157, 185, 149, 145, 17, 165, 205, 209, 133, 185, 141, 149, 25, 165, 149, 177, 145, 25, 189, 185, 209, 77, 161, 133, 145, 149, 201, 185, 88, 77, 53, 133, 165, 185, 125, 93, 201, 133, 193, 193, 149, 201, 109, +40, 22, 50, 24, 3, 0, 168, 194, 198, 102, 215, 230, 146, 70, 86, 230, 70, 55, 37, 8, 170, 144, 225, 185, 216, 149, 201, 205, 165, 189, 185, 77, 9, 136, 38, 100, 120, 46, 118, 97, 108, 118, 101, 114, 83, 2, 163, 14, 25, 158, 203, 28, 90, 24, 89, 153, 92, 211, 27, 89, 25, 219, 148, 32, +169, 68, 134, 231, 66, 151, 7, 87, 22, 228, 230, 246, 70, 23, 70, 151, 246, 230, 54, 55, 37, 112, 234, 144, 225, 185, 148, 185, 209, 201, 229, 65, 189, 165, 185, 209, 205, 77, 9, 200, 0, 113, 32, 0, 0, 18, 0, 0, 0, 6, 192, 6, 44, 98, 52, 196, 208, 33, 210, 4, 52, 2, 241, 33, +196, 50, 124, 78, 51, 177, 7, 48, 16, 145, 255, 178, 38, 128, 52, 63, 28, 1, 207, 67, 68, 22, 48, 13, 151, 239, 60, 254, 226, 0, 131, 216, 60, 212, 228, 23, 183, 109, 2, 213, 112, 249, 206, 227, 75, 147, 19, 17, 40, 53, 61, 212, 228, 23, 183, 13, 0, 97, 32, 0, 0, 60, 0, 0, +0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 20, 15, 211, 52, 202, 50, 98, 144, 0, 32, 8, 6, 5, 212, 56, 142, 194, 140, 24, 36, 0, 8, 130, 65, 17, 57, 202, 195, 52, 35, 6, 9, 0, 130, 96, 80, 72, 207, 2, 49, 206, 136, 65, 2, 128, 32, 24, 20, 19, 196, 68, 203, 51, 98, +144, 0, 32, 8, 6, 5, 21, 53, 210, 2, 141, 24, 36, 0, 8, 130, 65, 81, 73, 203, 4, 69, 35, 6, 9, 0, 130, 96, 80, 88, 19, 67, 65, 210, 136, 65, 2, 128, 32, 24, 20, 23, 213, 84, 207, 52, 98, 144, 0, 32, 8, 6, 5, 86, 57, 214, 67, 141, 24, 36, 0, 8, 130, 129, +129, 57, 207, 69, 33, 35, 6, 9, 0, 130, 96, 96, 96, 206, 115, 77, 199, 136, 65, 2, 128, 32, 24, 24, 152, 243, 92, 145, 49, 98, 144, 0, 32, 8, 6, 6, 230, 60, 23, 84, 140, 24, 36, 0, 8, 130, 129, 129, 57, 215, 69, 41, 35, 6, 9, 0, 130, 96, 96, 96, 206, 117, 77, 201, +136, 65, 2, 128, 32, 24, 24, 152, 35, 93, 20, 49, 98, 144, 0, 32, 8, 6, 6, 230, 72, 215, 52, 140, 24, 36, 0, 8, 130, 129, 129, 57, 210, 21, 9, 35, 6, 9, 0, 130, 96, 96, 96, 142, 116, 65, 1, 2, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 50c3453b06..65cf69f9e0 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SignedDistanceFieldFontShader.signedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -19,601 +19,599 @@ internal partial class SignedDistanceFieldFontShader 9, 192, 254, 239, 0, 0, 1, 0, 0, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 1, 1, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, -0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -255, 255, 127, 255, 255, 255, 127, 127, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, -0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, -101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, -239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, -0, 0, 1, 101, 22, 45, 2, 121, 85, 249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, -46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, 55, 1, 0, 0, -65, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 84, 1, 0, 0, -89, 1, 0, 0, 16, 0, 3, 0, 66, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, -32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, -111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, -119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, -101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, -13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, -65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, -95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, -104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, -32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, -114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, -116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, -116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, -97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, -116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, -68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, -47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, -32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, -108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, -68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, -111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, -110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, -116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, -99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, -114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, -110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, -100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, -3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, -115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, -105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, -116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, -116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, -116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, -83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, -101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, -99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, -115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, -68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, -101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, -13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, -108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, -97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, -73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, -114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, -112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, -54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, -82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, -101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, -111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, -110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, -116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, -99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, -114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, -32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, -32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, -44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, -32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, -110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, -116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, -100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, -104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, -40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, -110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, -104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, -97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, -68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, -68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, -114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, -115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, -97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, -32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, -116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, -116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, -46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, -100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, -10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, -32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, -100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, -114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, -114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, -104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, -115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, -114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, 97, 108, 117, 101, -115, 32, 99, 97, 110, 32, 103, 111, 32, 105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, -40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, -32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, -7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, -80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, -40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, -85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, -117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, -97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, -115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, -98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, -116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, -105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, -102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, -109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, -5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, -102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, -5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, -121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, -77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, -83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, -110, 99, 101, 0, 5, 0, 5, 0, 34, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 38, 1, 0, 0, -98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, -60, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, -6, 0, 6, 0, 61, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, -6, 0, 6, 0, 62, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 0, 6, 0, 6, 0, 63, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, -97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, -76, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, -114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 82, 1, 0, 0, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, -85, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, -6, 0, 5, 0, 85, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, -105, 111, 110, 0, 6, 0, 6, 0, 86, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 0, 0, 6, 0, 7, 0, 87, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 87, 1, 0, 0, -2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, -77, 83, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, -77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -0, 22, 6, 0, 57, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, -78, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, -0, 0, 0, 0, 0, 22, 6, 0, 80, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, -0, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 84, 1, 0, 0, -3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, -87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, -32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, -19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, -0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, -7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, -131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, -5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 31, 1, 0, 0, -37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 1, 0, 0, 0, -42, 0, 0, 0, 32, 0, 4, 0, 60, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, -4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 76, 1, 0, 0, -0, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, -87, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, -0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 59, 1, 0, 0, -1, 0, 0, 0, 59, 0, 4, 0, 64, 1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, -3, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 89, 1, 0, 0, -6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, -5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, -11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, -11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, -11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, -11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, -11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, -0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, -9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, -127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 132, 0, 0, 0, -55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, -114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, -114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, -114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, -108, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, -137, 0, 0, 0, 140, 0, 0, 0, 141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, -9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 25, 0, 0, 0, -9, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 155, 0, 0, 0, -132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, 8, 0, 4, 0, -108, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, -62, 0, 3, 0, 164, 0, 0, 0, 167, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, -5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, -5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, -175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -184, 0, 0, 0, 135, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, -8, 0, 4, 0, 108, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, -191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, -149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 38, 0, 0, 0, -13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 129, 0, 5, 0, -5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, -5, 0, 0, 0, 209, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, -207, 0, 0, 0, 211, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, -215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, -185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, -219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 46, 0, 0, 0, -9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, -8, 0, 4, 0, 224, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, 8, 0, 4, 0, -224, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 0, 0, 0, -251, 0, 0, 0, 62, 0, 3, 0, 249, 0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, -254, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, -7, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, -9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, -44, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, -21, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, -31, 1, 0, 0, 32, 1, 0, 0, 30, 1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 34, 0, 0, 0, -9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, -38, 1, 0, 0, 35, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 46, 1, 0, 0, -65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, 49, 1, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 51, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, 254, 0, 2, 0, -54, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, -70, 1, 0, 0, 57, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 71, 1, 0, 0, -73, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, -77, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, -42, 0, 0, 0, 93, 1, 0, 0, 79, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 62, 0, 3, 0, -94, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, -99, 1, 0, 0, 229, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, -102, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 101, 22, 45, 2, 121, 85, -249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, -0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, 55, 1, 0, 0, 65, 1, 0, 0, 40, 0, 0, 0, 87, -0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 84, 1, 0, 0, 89, 1, 0, 0, 16, 0, 3, 0, 66, -1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, -101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, -32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, -116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, -110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, -67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, -115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, -108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, -84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, -32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, -105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, -58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, -32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, -114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, -86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, -114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, -117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, -32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, -116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, -99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, -115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, -114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, -40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, -114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, -119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, -101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, -10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, -58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, -109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, -47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, -0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, -47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, -105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, -32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, -114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, -32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, -105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, -120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, -101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, -120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, -108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, -115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, -120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, -117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, -32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, -123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, -73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, -114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, -101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, -78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, -108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, -84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, -101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, -112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, -59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, -105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, -112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, -101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, -104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, -10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, -111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, -114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, -13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, -101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, -40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, -114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, -119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, -101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, -10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, -116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, -32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, -32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, -32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, -115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, -108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, -32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, -61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, -110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, -117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, -105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, -32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, -100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, -111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, -13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, -32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, -32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, -116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, -114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, -32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, -109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, -100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, -101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, -47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, -104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, -67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, -101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, -47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, -32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, -101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, -116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, -47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, -100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, -105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, -115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, -10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, -101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, -101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, 97, 108, 117, 101, 115, 32, 99, 97, 110, 32, 103, 111, 32, -105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, -32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, -116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, -105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, -114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, -105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, -114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, -110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, -52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, -115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, -108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, -0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, -0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, -0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, -0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, -0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, -116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, -114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, -0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, -105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, -0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, -0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, -116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 34, -1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 38, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, -99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, -0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 112, 116, 114, 95, 73, -110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 61, 1, 0, 0, 0, -0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 62, 1, 0, 0, 0, -0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 63, -1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, -82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, -46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 76, 1, 0, 0, 105, 110, 116, 95, 48, -0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, -1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 82, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, -105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 85, 1, 0, 0, 86, 83, 95, 73, 78, -80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 85, 1, 0, 0, 2, -0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 86, -1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 87, -1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 87, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, -105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 89, -1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, -112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 57, 1, 0, 0, 3, -22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 11, 0, 0, 0, 0, -0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 80, -1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 83, -1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 84, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, -0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, -0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, -0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, -0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, -0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, -0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, -0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, -0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, -0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, -0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, -153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 31, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, -0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 60, -1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, -1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 81, -1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 87, 1, 0, 0, 4, 0, 0, 0, 42, -0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, -0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 59, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, -1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 60, -1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 89, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, -0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, -0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, -0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, -0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, -0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, -0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, -0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, -0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, -0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, -0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, -0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, -0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 17, 0, 0, 0, 9, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, 141, -0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, -0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 114, -0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, -0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, -0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 27, 0, 0, 0, 9, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 167, -0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, -0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, -0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, -0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, 186, -0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 36, -0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, -0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, -0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, -0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, -0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, -0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 154, -0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, 8, -0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, -0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, -0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, -0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, -0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, -0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 10, -0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 17, 0, 0, 0, 9, -0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 249, -0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 224, -0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 7, 1, 0, 0, 253, 0, 1, 0, 56, -0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 59, -0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 21, 1, 0, 0, 87, 0, 0, 0, 65, -0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 31, 1, 0, 0, 32, 1, 0, 0, 30, -1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, -0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 38, 1, 0, 0, 35, 1, 0, 0, 8, -0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 46, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, -0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 51, -1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, 254, 0, 2, 0, 54, 1, 0, 0, 56, 0, 1, 0, 54, -0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 70, 1, 0, 0, 57, 1, 0, 0, 62, -0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 71, 1, 0, 0, 73, 1, 0, 0, 57, 0, 4, 0, 30, -0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, 77, 1, 0, 0, 253, 0, 1, 0, 56, -0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 93, 1, 0, 0, 79, -1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 62, 0, 3, 0, 94, 1, 0, 0, 95, 1, 0, 0, 65, -0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 99, 1, 0, 0, 229, 0, 0, 0, 65, -0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 102, 1, 0, 0, 89, 1, 0, 0, 69, -1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 105, 1, 0, 0, 104, -1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, +10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, +79, 82, 0, 0, 0, 0, 0, 5, 0, 0, 0, 29, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 31, 192, 73, 143, 103, 192, 229, 14, 88, 61, 50, 131, 62, 10, 108, 101, 16, 83, 104, 97, 100, 101, +114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, +110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, +0, 0, 5, 0, 0, 0, 1, 101, 22, 45, 2, 121, 85, 249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, +71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, +55, 1, 0, 0, 65, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, +84, 1, 0, 0, 89, 1, 0, 0, 16, 0, 3, 0, 66, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, +105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, +105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, +101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, +105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, +73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, +69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, +101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, +10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, +32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, +117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, +83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, +32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, +114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, +113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, +101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, +110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, +47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, +116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, +46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, +84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, +105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, +114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, +32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, +32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, +100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, +117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, +32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, +114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, +111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, +108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, +117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, +115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, +117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, +120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, +108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, +101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, +83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, +114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, +97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, +79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, +59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, +105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, +105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, +32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, +110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, +97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, +97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, +47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, +116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, +46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, +84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, +105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, +10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, +108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, +44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, +102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, +101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, +102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, +32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, +100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, +104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, +32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, +101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, +103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, +97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, +56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, +32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, +101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, +105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, +101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, +111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, +117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, +58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, +117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, +83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, +110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, +115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, +79, 76, 79, 82, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, +120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, +61, 32, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, +32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, +100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, +101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, +97, 108, 117, 101, 115, 32, 99, 97, 110, 32, 103, 111, 32, 105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, +111, 97, 116, 52, 40, 48, 44, 32, 48, 44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, +108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, +112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, +5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, +84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, +101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 114, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, +117, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 131, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, +133, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, +139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, +144, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, +149, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, +105, 115, 116, 0, 5, 0, 5, 0, 168, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, +185, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, +116, 95, 50, 0, 5, 0, 6, 0, 194, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, +97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, +231, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, +105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 5, 0, 34, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, +38, 1, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, +5, 0, 7, 0, 60, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, +0, 0, 0, 0, 6, 0, 6, 0, 61, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, +84, 0, 0, 0, 6, 0, 6, 0, 62, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 63, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, +80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, +101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, +5, 0, 4, 0, 76, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, +120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, +82, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, +5, 0, 5, 0, 85, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, +0, 0, 0, 0, 6, 0, 5, 0, 85, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, +111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 86, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 87, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, +87, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, +84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 89, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 0, 22, 6, 0, 57, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, +71, 0, 4, 0, 78, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, +30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 80, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, +84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 83, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, +84, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, +71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, +8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, +23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, +36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, +0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, +114, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, +131, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, +43, 0, 4, 0, 5, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, +43, 0, 4, 0, 5, 0, 0, 0, 171, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, +31, 1, 0, 0, 37, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, +1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 60, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 64, 1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, +76, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, +30, 0, 6, 0, 87, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, +40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, +59, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 64, 1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, +80, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, +89, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, +30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, +10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, +109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, +110, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, +120, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 126, 0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, +121, 0, 0, 0, 127, 0, 0, 0, 254, 0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, +132, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 114, 0, 0, 0, 145, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 114, 0, 0, 0, 157, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, +59, 0, 4, 0, 114, 0, 0, 0, 188, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, +43, 0, 0, 0, 137, 0, 0, 0, 140, 0, 0, 0, 141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, +155, 0, 0, 0, 132, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 160, 0, 0, 0, 159, 0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, +166, 0, 0, 0, 62, 0, 3, 0, 164, 0, 0, 0, 167, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, +133, 0, 5, 0, 5, 0, 0, 0, 172, 0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, +127, 0, 4, 0, 5, 0, 0, 0, 175, 0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, +49, 0, 0, 0, 175, 0, 0, 0, 176, 0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 180, 0, 0, 0, 173, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 184, 0, 0, 0, 135, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, +182, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, +190, 0, 0, 0, 191, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +195, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 202, 0, 0, 0, 194, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, +129, 0, 5, 0, 5, 0, 0, 0, 206, 0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, +111, 0, 4, 0, 5, 0, 0, 0, 209, 0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, +62, 0, 3, 0, 207, 0, 0, 0, 211, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 214, 0, 0, 0, 207, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, +213, 0, 0, 0, 215, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, +185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, +219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, +46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, +5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, +8, 0, 4, 0, 224, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, +252, 0, 0, 0, 251, 0, 0, 0, 62, 0, 3, 0, 249, 0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, +248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, +3, 1, 0, 0, 7, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, +131, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, +131, 0, 0, 0, 44, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, +86, 0, 0, 0, 21, 1, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, +86, 0, 5, 0, 31, 1, 0, 0, 32, 1, 0, 0, 30, 1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, +34, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, +62, 0, 3, 0, 38, 1, 0, 0, 35, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, +46, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, +49, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 51, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, +254, 0, 2, 0, 54, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, +42, 0, 0, 0, 70, 1, 0, 0, 57, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, +71, 1, 0, 0, 73, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, +55, 1, 0, 0, 77, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, +61, 0, 4, 0, 42, 0, 0, 0, 93, 1, 0, 0, 79, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, +62, 0, 3, 0, 94, 1, 0, 0, 95, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, +30, 0, 0, 0, 99, 1, 0, 0, 229, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, +74, 0, 0, 0, 102, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 105, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 101, 22, +45, 2, 121, 85, 249, 7, 135, 138, 64, 122, 110, 150, 137, 48, 0, 8, 73, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 106, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 122, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, +52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 66, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 57, 1, 0, 0, 59, 1, 0, 0, 55, 1, 0, 0, 65, 1, 0, 0, 40, +0, 0, 0, 87, 0, 0, 0, 15, 0, 14, 0, 0, 0, 0, 0, 90, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 79, 1, 0, 0, 82, 1, 0, 0, 83, 1, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 84, 1, 0, 0, 89, 1, 0, 0, 16, +0, 3, 0, 66, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, +83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, +46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, +38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, +108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, +101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, +47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, +101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, +73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, +13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, +115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, +114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, +97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, +114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, +114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, +67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, +32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, +53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, +84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, +99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, +95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, +115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, +86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, +100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, +103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, +111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, +47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, +46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, +111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, +97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, +104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, +97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, +114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, +0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, +116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, +83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, +110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, +116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, +116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, +105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, +120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, +101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, +50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, +115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, +101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, +13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, +77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, +32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, +65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, +111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, +109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, +71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, +32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, +78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, +97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, +32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, +32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, +116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, +97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, +32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, +59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, +82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, +82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, +120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, +82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 23, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, +83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, +103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, +111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, +47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, +46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, +111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, +101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, +108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, +59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, +103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, +97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, +120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, +32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, +32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, +45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, +100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, +116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, +100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, +110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, +97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, +103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, +111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, +100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, +32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, +40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, +97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 24, 0, 224, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, +114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, +111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 3, 0, 115, 1, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, +97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, +51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, +112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, +101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, +99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, +47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, +32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, +80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 83, 119, 105, 122, 122, 108, 101, 32, 58, 32, 66, 65, 84, 67, 72, 95, 83, 87, 73, 90, 90, 76, 69, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, +32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, +32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, +32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, +46, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 105, 120, 101, 108, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, +114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, +103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 105, 115, 32, 115, 104, 111, 117, 108, 100, 32, 98, 101, 32, 97, 32, 51, 45, 99, 104, 97, 110, 110, 101, 108, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, +101, 32, 102, 105, 101, 108, 100, 32, 116, 101, 120, 116, 117, 114, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, +97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 84, 104, 101, 115, 101, 32, 118, 97, 108, 117, 101, 115, 32, 99, 97, 110, +32, 103, 111, 32, 105, 110, 116, 111, 32, 115, 116, 114, 101, 97, 109, 115, 32, 108, 97, 116, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 32, 48, +44, 32, 48, 44, 32, 49, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 48, 46, 102, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, +101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, +116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, +116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, +101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, +114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, +108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, +121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 10, 0, 110, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, +101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 111, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, +0, 7, 0, 114, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 115, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 116, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 117, 0, 0, 0, 98, 0, 0, 0, 5, +0, 7, 0, 131, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 132, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 133, 0, 0, 0, 116, 101, 120, 116, 67, +111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 134, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 135, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, +0, 0, 0, 5, 0, 5, 0, 141, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 143, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 144, 0, 0, 0, 102, 108, 111, 97, 116, +95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 145, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 146, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 149, 0, 0, 0, 109, 101, 100, 105, 97, +110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 154, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 158, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 164, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 168, +0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 171, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 173, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 185, 0, 0, 0, 102, 108, 111, 97, 116, +95, 48, 0, 5, 0, 5, 0, 182, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 188, 0, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 191, 0, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 194, +0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 198, 0, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 207, 0, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, +0, 5, 0, 183, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 12, 0, 229, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 0, +0, 0, 0, 5, 0, 12, 0, 230, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 0, 5, 0, 12, 0, 231, 0, 0, 0, 83, 105, 103, 110, 101, +100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 0, 5, 0, 7, 0, 9, 1, 0, 0, 115, 105, 103, 110, 101, 100, 77, 117, 108, 116, 105, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, +0, 5, 0, 34, 1, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 4, 0, 35, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 36, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 6, 0, 38, 1, 0, 0, 98, 111, 114, 100, 101, +114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 7, 0, 56, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 55, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 0, 0, 5, 0, 7, 0, 58, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 57, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 60, 1, 0, 0, 112, +116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 59, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 61, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 61, +1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 61, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 62, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 62, +1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 63, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 63, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, +0, 6, 0, 63, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 63, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 64, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, +83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 65, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 14, 0, 66, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, +97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 69, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 72, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 76, 1, 0, 0, 105, +110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 78, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 79, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, +0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 80, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 82, 1, 0, 0, 105, 110, 95, 86, 83, +95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 84, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 85, 1, 0, 0, 86, +83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 85, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 85, +1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 86, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, +0, 6, 0, 86, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 86, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 87, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, +0, 7, 0, 87, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 87, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 87, 1, 0, 0, 2, 0, 0, 0, 80, +111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 87, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 88, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, +0, 5, 0, 89, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 14, 0, 90, 1, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, +87, 114, 97, 112, 112, 101, 114, 0, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 4, 0, 55, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 57, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 57, +1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 59, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 59, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 11, +0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 79, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 79, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, +22, 6, 0, 80, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 82, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 82, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, +0, 4, 0, 83, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 83, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 84, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 84, 1, 0, 0, 3, 22, 0, 0, 67, +79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, +0, 0, 0, 1, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, +0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, +0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, +0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, +0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 32, 0, 4, 0, 114, 0, 0, 0, 7, 0, 0, 0, 5, +0, 0, 0, 33, 0, 6, 0, 113, 0, 0, 0, 5, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 114, 0, 0, 0, 32, 0, 4, 0, 131, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 130, 0, 0, 0, 4, 0, 0, 0, 131, 0, 0, 0, 131, 0, 0, 0, 131, +0, 0, 0, 114, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 141, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 144, +0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 146, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 154, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 158, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 171, +0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 185, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 64, 33, 0, 3, 0, 5, 1, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 31, 1, 0, 0, 37, 0, 0, 0, 43, +0, 4, 0, 5, 0, 0, 0, 35, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 36, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 56, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 58, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, +0, 4, 0, 60, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 61, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 62, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 63, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, +0, 4, 0, 64, 1, 0, 0, 6, 0, 0, 0, 63, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 69, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 72, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 76, 1, 0, 0, 0, 0, 0, 0, 32, +0, 4, 0, 81, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 85, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 86, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 87, 1, 0, 0, 4, +0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 88, 1, 0, 0, 6, 0, 0, 0, 87, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, +0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 55, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 57, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 59, 1, 0, 0, 1, 0, 0, 0, 59, +0, 4, 0, 64, 1, 0, 0, 65, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 78, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 58, 1, 0, 0, 79, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 3, 0, 0, 0, 59, +0, 4, 0, 60, 1, 0, 0, 82, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 60, 1, 0, 0, 83, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 56, 1, 0, 0, 84, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 88, 1, 0, 0, 89, 1, 0, 0, 6, 0, 0, 0, 8, +0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, +0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 113, +0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 115, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 116, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 117, 0, 0, 0, 248, 0, 2, 0, 118, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 119, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 120, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 121, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 119, 0, 0, 0, 120, 0, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 123, 0, 0, 0, 115, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 124, 0, 0, 0, 116, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 125, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 123, 0, 0, 0, 124, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 126, +0, 0, 0, 117, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 127, 0, 0, 0, 122, 0, 0, 0, 37, 0, 0, 0, 125, 0, 0, 0, 126, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 128, 0, 0, 0, 122, 0, 0, 0, 40, 0, 0, 0, 121, 0, 0, 0, 127, 0, 0, 0, 254, +0, 2, 0, 128, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 132, 0, 0, 0, 55, 0, 3, 0, 131, +0, 0, 0, 133, 0, 0, 0, 55, 0, 3, 0, 131, 0, 0, 0, 134, 0, 0, 0, 55, 0, 3, 0, 114, 0, 0, 0, 135, 0, 0, 0, 248, 0, 2, 0, 136, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 143, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 145, +0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 149, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 150, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 153, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 157, +0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 164, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 168, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 173, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 188, +0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 194, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 198, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 207, 0, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 17, +0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 137, 0, 0, 0, 135, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 140, 0, 0, 0, 139, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 142, 0, 0, 0, 122, 0, 0, 0, 43, 0, 0, 0, 137, 0, 0, 0, 140, +0, 0, 0, 141, 0, 0, 0, 62, 0, 3, 0, 135, 0, 0, 0, 142, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 143, 0, 0, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 147, 0, 0, 0, 135, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 148, 0, 0, 0, 146, 0, 0, 0, 147, 0, 0, 0, 62, 0, 3, 0, 145, 0, 0, 0, 148, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, +0, 5, 0, 114, 0, 0, 0, 151, 0, 0, 0, 132, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 152, 0, 0, 0, 151, 0, 0, 0, 62, 0, 3, 0, 150, 0, 0, 0, 152, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 155, 0, 0, 0, 132, 0, 0, 0, 154, +0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 156, 0, 0, 0, 155, 0, 0, 0, 62, 0, 3, 0, 153, 0, 0, 0, 156, 0, 0, 0, 65, 0, 5, 0, 114, 0, 0, 0, 159, 0, 0, 0, 132, 0, 0, 0, 158, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 160, 0, 0, 0, 159, +0, 0, 0, 62, 0, 3, 0, 157, 0, 0, 0, 160, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 163, 0, 0, 0, 110, 0, 0, 0, 150, 0, 0, 0, 153, 0, 0, 0, 157, 0, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 163, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 27, +0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 165, 0, 0, 0, 149, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 166, 0, 0, 0, 145, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 167, 0, 0, 0, 165, 0, 0, 0, 166, 0, 0, 0, 62, 0, 3, 0, 164, +0, 0, 0, 167, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 169, 0, 0, 0, 164, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 170, 0, 0, 0, 169, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 172, +0, 0, 0, 170, 0, 0, 0, 171, 0, 0, 0, 62, 0, 3, 0, 168, 0, 0, 0, 172, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 174, 0, 0, 0, 168, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 175, +0, 0, 0, 174, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 176, 0, 0, 0, 168, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 177, 0, 0, 0, 164, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 178, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 175, 0, 0, 0, 176, +0, 0, 0, 177, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 178, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 179, 0, 0, 0, 173, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 180, 0, 0, 0, 173, +0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 180, 0, 0, 0, 179, 0, 0, 0, 62, 0, 3, 0, 173, 0, 0, 0, 181, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 184, 0, 0, 0, 135, +0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 186, 0, 0, 0, 184, 0, 0, 0, 185, 0, 0, 0, 247, 0, 3, 0, 183, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 186, 0, 0, 0, 182, 0, 0, 0, 183, 0, 0, 0, 248, 0, 2, 0, 182, 0, 0, 0, 8, 0, 4, 0, 108, +0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 189, 0, 0, 0, 145, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 135, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 192, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 129, +0, 5, 0, 5, 0, 0, 0, 193, 0, 0, 0, 189, 0, 0, 0, 192, 0, 0, 0, 62, 0, 3, 0, 188, 0, 0, 0, 193, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 149, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 196, 0, 0, 0, 188, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 197, 0, 0, 0, 195, 0, 0, 0, 196, 0, 0, 0, 62, 0, 3, 0, 194, 0, 0, 0, 197, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, +0, 4, 0, 5, 0, 0, 0, 199, 0, 0, 0, 143, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 200, 0, 0, 0, 194, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 201, 0, 0, 0, 199, 0, 0, 0, 200, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 202, 0, 0, 0, 194, +0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 203, 0, 0, 0, 202, 0, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 204, 0, 0, 0, 201, 0, 0, 0, 203, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 205, 0, 0, 0, 188, 0, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 206, +0, 0, 0, 204, 0, 0, 0, 205, 0, 0, 0, 62, 0, 3, 0, 198, 0, 0, 0, 206, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 139, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 209, +0, 0, 0, 154, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 210, 0, 0, 0, 198, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 211, 0, 0, 0, 122, 0, 0, 0, 49, 0, 0, 0, 208, 0, 0, 0, 209, 0, 0, 0, 210, 0, 0, 0, 62, 0, 3, 0, 207, 0, 0, 0, 211, +0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 212, 0, 0, 0, 134, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 213, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 214, 0, 0, 0, 207, +0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 215, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 214, 0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 216, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 212, 0, 0, 0, 213, 0, 0, 0, 215, 0, 0, 0, 62, +0, 3, 0, 133, 0, 0, 0, 216, 0, 0, 0, 249, 0, 2, 0, 183, 0, 0, 0, 248, 0, 2, 0, 183, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 217, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, +0, 0, 0, 185, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 218, 0, 0, 0, 133, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 219, 0, 0, 0, 173, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 220, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, 0, 0, 0, 219, +0, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 221, 0, 0, 0, 122, 0, 0, 0, 46, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 220, 0, 0, 0, 62, 0, 3, 0, 132, 0, 0, 0, 221, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, +0, 4, 0, 4, 0, 0, 0, 222, 0, 0, 0, 132, 0, 0, 0, 254, 0, 2, 0, 222, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, +0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 229, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 242, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 17, +0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 249, 0, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 251, 0, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 62, +0, 3, 0, 249, 0, 0, 0, 252, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, +0, 4, 0, 224, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 3, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 7, 1, 0, 0, 231, 0, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 7, 1, 0, 0, 253, +0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 224, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 231, 0, 0, 0, 0, 0, 0, 0, 5, 1, 0, 0, 248, 0, 2, 0, 8, 1, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 9, 1, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 34, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 38, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 42, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 44, 1, 0, 0, 7, +0, 0, 0, 59, 0, 4, 0, 131, 0, 0, 0, 48, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 114, 0, 0, 0, 50, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 21, 1, 0, 0, 87, +0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 28, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 29, 1, 0, 0, 28, 1, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 30, 1, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 31, 1, 0, 0, 32, +1, 0, 0, 30, 1, 0, 0, 21, 1, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 33, 1, 0, 0, 32, 1, 0, 0, 29, 1, 0, 0, 0, 0, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 33, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 80, +0, 7, 0, 4, 0, 0, 0, 37, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 35, 1, 0, 0, 36, 1, 0, 0, 62, 0, 3, 0, 34, 1, 0, 0, 37, 1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 38, 1, 0, 0, 35, +1, 0, 0, 8, 0, 4, 0, 224, 0, 0, 0, 37, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 43, 1, 0, 0, 9, 1, 0, 0, 62, 0, 3, 0, 42, 1, 0, 0, 43, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 46, 1, 0, 0, 65, 1, 0, 0, 72, +1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 47, 1, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 44, 1, 0, 0, 47, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 49, 1, 0, 0, 34, 1, 0, 0, 62, 0, 3, 0, 48, 1, 0, 0, 49, 1, 0, 0, 61, 0, 4, 0, 5, +0, 0, 0, 51, 1, 0, 0, 38, 1, 0, 0, 62, 0, 3, 0, 50, 1, 0, 0, 51, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 54, 1, 0, 0, 111, 0, 0, 0, 42, 1, 0, 0, 44, 1, 0, 0, 48, 1, 0, 0, 50, 1, 0, 0, 254, 0, 2, 0, 54, 1, 0, 0, 56, +0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 66, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 67, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 68, 1, 0, 0, 65, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 70, 1, 0, 0, 57, +1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 70, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 73, 1, 0, 0, 59, 1, 0, 0, 62, 0, 3, 0, 71, 1, 0, 0, 73, 1, 0, 0, 57, +0, 4, 0, 30, 0, 0, 0, 74, 1, 0, 0, 230, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 75, 1, 0, 0, 65, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 77, 1, 0, 0, 75, 1, 0, 0, 62, 0, 3, 0, 55, 1, 0, 0, 77, 1, 0, 0, 253, +0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 90, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 91, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 92, 1, 0, 0, 89, 1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 93, +1, 0, 0, 79, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 93, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 94, 1, 0, 0, 89, 1, 0, 0, 72, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 95, 1, 0, 0, 82, 1, 0, 0, 62, 0, 3, 0, 94, 1, 0, 0, 95, +1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 83, 1, 0, 0, 62, 0, 3, 0, 96, 1, 0, 0, 98, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 99, 1, 0, 0, 229, +0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 100, 1, 0, 0, 89, 1, 0, 0, 76, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 101, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 78, 1, 0, 0, 101, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 102, 1, 0, 0, 89, +1, 0, 0, 69, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 103, 1, 0, 0, 102, 1, 0, 0, 62, 0, 3, 0, 80, 1, 0, 0, 103, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 104, 1, 0, 0, 89, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 105, +1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 84, 1, 0, 0, 105, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs index 8712e837bf..5990210e08 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D11.Level_9_3.cs @@ -21,64 +21,62 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, -84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, -97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, -114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, -114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, -0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, -120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, -0, 0, 0, 5, 0, 0, 0, 1, 80, 109, 219, 15, 96, 184, 225, 224, 222, 136, 131, 142, 184, 139, 83, 200, 0, 192, 87, 0, 0, 68, 88, 66, 67, 18, 50, 113, 103, 3, 233, 179, 222, 15, 80, 16, 70, 41, 78, 99, 3, 1, 0, 0, 0, 192, 87, 0, 0, 7, 0, 0, 0, 60, 0, 0, -0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 86, 0, 0, 140, 86, 0, 0, 64, 87, 0, 0, 140, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, 0, 1, 0, 36, -0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, 0, 67, 58, 92, -100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, -104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, 0, 0, 0, 255, -255, 0, 4, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 68, 0, 0, 0, 28, 4, 0, 0, 68, 0, 0, 0, 44, 4, 0, 0, 68, 0, 0, 0, 64, 4, 0, 0, 68, 0, 0, 0, 80, 4, 0, 0, 80, 0, 0, 0, 96, 4, 0, 0, 81, 0, 0, 0, 112, 4, 0, 0, 81, 0, 0, -0, 124, 4, 0, 0, 81, 0, 0, 0, 136, 4, 0, 0, 81, 0, 0, 0, 148, 4, 0, 0, 82, 0, 0, 0, 164, 4, 0, 0, 82, 0, 0, 0, 184, 4, 0, 0, 82, 0, 0, 0, 200, 4, 0, 0, 82, 0, 0, 0, 212, 4, 0, 0, 82, 0, 0, 0, 228, 4, 0, 0, 82, 0, 0, -0, 248, 4, 0, 0, 82, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 40, 5, 0, 0, 92, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, -105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, -0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 193, 1, 0, 0, 212, 1, 0, -0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 228, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, -255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 171, 23, 0, 0, -0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, 0, 1, 0, 2, -0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 148, 2, 0, 0, 164, 2, 0, 0, 180, 2, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 192, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, -255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 160, 1, 0, 0, 1, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 188, 1, 0, 0, 236, 1, 0, -0, 1, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 16, 2, 0, 0, 2, 0, 0, 0, 32, 2, 0, 0, 56, 2, 0, 0, 90, 2, 0, 0, 212, 1, 0, 0, 1, 0, 0, 0, 104, 2, 0, 0, 0, 0, 0, 0, 116, 2, 0, 0, 16, 2, 0, 0, 1, 0, 0, -0, 124, 2, 0, 0, 188, 1, 0, 0, 136, 2, 0, 0, 208, 2, 0, 0, 2, 0, 0, 0, 224, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, -0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, 176, 31, 0, 0, -2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, 128, 0, 0, 255, -128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, 2, 0, 0, 2, -128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, 160, 0, 0, 0, -128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, 160, 1, 0, 85, -160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, 128, 1, 0, 228, -176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, 16, 0, -3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 70, 126, 16, -0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, 0, 6, 3, 16, -0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, 190, 11, 0, 0, -5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 26, 0, 16, -128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, -0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, -0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, -0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, -32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, +110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 5, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, +0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 77, 97, 116, +114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, 84, 69, 88, 67, +79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, 57, 199, 222, 82, +168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, 10, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, 67, 85, 255, 23, +129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 206, 49, 107, 15, 29, 46, 66, 166, 212, 248, 9, 249, 48, 20, 73, 34, 0, 192, 87, 0, 0, 68, 88, 66, 67, 140, 18, 185, 74, 41, 2, 241, 125, 60, 62, 62, 230, 238, 128, 161, 114, 1, 0, 0, 0, 192, 87, 0, 0, 7, 0, 0, +0, 60, 0, 0, 0, 180, 5, 0, 0, 8, 8, 0, 0, 16, 86, 0, 0, 140, 86, 0, 0, 64, 87, 0, 0, 140, 87, 0, 0, 65, 111, 110, 57, 112, 5, 0, 0, 112, 5, 0, 0, 0, 2, 255, 255, 72, 5, 0, 0, 40, 0, 0, 0, 0, 0, 40, 0, 0, 0, 40, 0, 0, 0, 40, +0, 1, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 1, 2, 255, 255, 254, 255, 236, 0, 68, 66, 85, 71, 40, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 25, 0, 0, 0, 136, 0, 0, 0, 7, 0, 0, 0, 248, 2, 0, 0, 188, 1, 0, +0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, +101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 48, 67, 68, 57, 66, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 184, 3, 0, 0, 0, 0, 255, 255, 208, 3, 0, 0, 0, 0, 255, 255, 232, 3, 0, 0, 0, 0, 255, 255, 244, 3, 0, +0, 0, 0, 255, 255, 0, 4, 0, 0, 63, 0, 0, 0, 12, 4, 0, 0, 68, 0, 0, 0, 28, 4, 0, 0, 68, 0, 0, 0, 44, 4, 0, 0, 68, 0, 0, 0, 64, 4, 0, 0, 68, 0, 0, 0, 80, 4, 0, 0, 80, 0, 0, 0, 96, 4, 0, 0, 81, 0, 0, 0, 112, 4, 0, +0, 81, 0, 0, 0, 124, 4, 0, 0, 81, 0, 0, 0, 136, 4, 0, 0, 81, 0, 0, 0, 148, 4, 0, 0, 82, 0, 0, 0, 164, 4, 0, 0, 82, 0, 0, 0, 184, 4, 0, 0, 82, 0, 0, 0, 200, 4, 0, 0, 82, 0, 0, 0, 212, 4, 0, 0, 82, 0, 0, 0, 228, 4, 0, +0, 82, 0, 0, 0, 248, 4, 0, 0, 82, 0, 0, 0, 8, 5, 0, 0, 83, 0, 0, 0, 24, 5, 0, 0, 92, 0, 0, 0, 40, 5, 0, 0, 92, 0, 0, 0, 56, 5, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +95, 109, 101, 100, 105, 97, 110, 0, 171, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 255, 255, 255, 255, 255, 255, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 171, 1, 0, 3, 0, 1, 0, 4, +0, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 255, 255, 109, 97, 105, 110, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 193, 1, 0, +0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 4, 0, 1, 0, 1, 0, 228, 1, 0, 0, 24, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 255, +255, 255, 255, 255, 255, 22, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, +171, 23, 0, 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 115, 105, 103, 68, 105, 115, 116, 0, 10, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 1, 0, 3, +0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 148, 2, 0, 0, 164, 2, 0, 0, 180, 2, 0, 0, 212, 1, 0, 0, 5, 0, 0, 0, 1, 0, 6, 0, 1, 0, 2, 0, 192, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, +0, 255, 255, 255, 255, 3, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 80, 1, 0, 0, 112, 1, 0, 0, 1, 0, 0, 0, 128, 1, 0, 0, 0, 0, 0, 0, 140, 1, 0, 0, 160, 1, 0, 0, 1, 0, 0, 0, 176, 1, 0, 0, 0, 0, 0, 0, 188, 1, 0, +0, 236, 1, 0, 0, 1, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 16, 2, 0, 0, 2, 0, 0, 0, 32, 2, 0, 0, 56, 2, 0, 0, 90, 2, 0, 0, 212, 1, 0, 0, 1, 0, 0, 0, 104, 2, 0, 0, 0, 0, 0, 0, 116, 2, 0, 0, 16, 2, 0, +0, 1, 0, 0, 0, 124, 2, 0, 0, 188, 1, 0, 0, 136, 2, 0, 0, 208, 2, 0, 0, 2, 0, 0, 0, 224, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, +49, 48, 46, 49, 0, 81, 0, 0, 5, 0, 0, 15, 160, 205, 204, 204, 190, 154, 153, 217, 63, 154, 153, 89, 63, 0, 0, 0, 0, 81, 0, 0, 5, 1, 0, 15, 160, 0, 0, 0, 192, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 2, 0, 0, 0, 128, 0, 0, 3, +176, 31, 0, 0, 2, 0, 0, 0, 128, 1, 0, 15, 176, 31, 0, 0, 2, 0, 0, 0, 144, 0, 8, 15, 160, 66, 0, 0, 3, 0, 0, 15, 128, 0, 0, 228, 176, 0, 8, 228, 160, 2, 0, 0, 3, 0, 0, 8, 128, 0, 0, 85, 129, 0, 0, 0, 128, 88, 0, 0, 4, 0, 0, 3, +128, 0, 0, 255, 128, 0, 0, 225, 128, 0, 0, 228, 128, 10, 0, 0, 3, 1, 0, 8, 128, 0, 0, 170, 128, 0, 0, 85, 128, 11, 0, 0, 3, 2, 0, 8, 128, 0, 0, 0, 128, 1, 0, 255, 128, 2, 0, 0, 3, 0, 0, 1, 128, 2, 0, 255, 128, 0, 0, 0, 160, 91, 0, 0, +2, 0, 0, 2, 128, 0, 0, 0, 128, 92, 0, 0, 2, 0, 0, 4, 128, 0, 0, 0, 128, 35, 0, 0, 2, 0, 0, 6, 128, 0, 0, 228, 128, 2, 0, 0, 3, 0, 0, 2, 128, 0, 0, 170, 128, 0, 0, 85, 128, 4, 0, 0, 4, 0, 0, 1, 128, 0, 0, 85, 128, 0, 0, 170, +160, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 2, 128, 0, 0, 85, 128, 0, 0, 85, 160, 6, 0, 0, 2, 0, 0, 2, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 17, 128, 0, 0, 85, 128, 0, 0, 0, 128, 4, 0, 0, 4, 0, 0, 2, 128, 0, 0, 0, 128, 1, 0, 0, +160, 1, 0, 85, 160, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 85, 128, 5, 0, 0, 3, 0, 0, 1, 128, 0, 0, 0, 128, 0, 0, 0, 128, 5, 0, 0, 3, 0, 0, 15, 128, 0, 0, 0, +128, 1, 0, 228, 176, 1, 0, 0, 2, 0, 8, 15, 128, 0, 0, 228, 128, 255, 255, 0, 0, 83, 72, 68, 82, 76, 2, 0, 0, 64, 0, 0, 0, 147, 0, 0, 0, 90, 0, 0, 3, 0, 96, 16, 0, 0, 0, 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, +0, 98, 16, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 98, 16, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 1, 0, 0, 0, 69, 0, 0, 9, 242, 0, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, +0, 70, 126, 16, 0, 0, 0, 0, 0, 0, 96, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 130, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 51, 0, 0, 7, 82, 0, 16, 0, 0, 0, 0, 0, 86, 6, 16, 0, 0, 0, 0, +0, 6, 3, 16, 0, 0, 0, 0, 0, 52, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 205, 204, 204, +190, 11, 0, 0, 5, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 5, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, +0, 26, 0, 16, 128, 129, 0, 0, 0, 0, 0, 0, 0, 50, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 89, 63, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, +0, 0, 0, 0, 0, 1, 64, 0, 0, 154, 153, 217, 63, 14, 0, 0, 10, 34, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 26, 0, 16, 0, 0, 0, 0, 0, 56, 32, 0, 7, 18, 0, 16, 0, 0, 0, 0, +0, 26, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 50, 0, 0, 9, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 192, 1, 64, 0, 0, 0, 0, 64, 64, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, +0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, +0, 10, 0, 16, 0, 0, 0, 0, 0, 56, 0, 0, 7, 242, 32, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, 0, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, 66, 0, 78, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, +32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 39, 0, 0, 0, 196, 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -86,7 +84,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 128, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -94,15 +92,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, -255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, +0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -110,271 +108,271 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 158, 94, 53, 220, 30, 44, 109, -65, 154, 2, 226, 233, 146, 64, 64, 17, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 111, 69, 122, +17, 107, 199, 187, 79, 145, 201, 6, 238, 4, 89, 99, 19, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, -114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, -111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, -111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, -117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, 0, 38, 247, 2, -0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, 0, 223, 101, 2, -0, 28, 221, 1, 0, 214, 154, 2, 0, 231, 242, 2, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, +105, 115, 116, 101, 114, 40, 116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, +99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, +99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, +80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, +10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 117, 131, 1, 0, 198, 90, 0, 0, 172, 5, 3, 0, 8, 104, 0, +0, 38, 247, 2, 0, 31, 34, 3, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 233, 240, 2, 0, 11, 107, 3, 0, 119, 53, 0, 0, 20, 41, 3, 0, 113, 55, 2, 0, 101, 38, 2, 0, 146, 230, 3, 0, 81, 92, 0, +0, 145, 142, 1, 0, 28, 221, 1, 0, 214, 154, 2, 0, 133, 250, 1, 0, 162, 254, 2, 0, 228, 199, 3, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, -103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, -123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, -111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, -110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 116, 48, 41, 59, -10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, -117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, -100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, -73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 10, 125, -59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, -32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, -46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, -97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 10, 125, -10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, -111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 32, 98, 111, -114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 102, 108, -111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, -116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, 57, 48, 54, 50, -53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, -32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 57, 44, 32, 95, 50, 50, 50, 44, 32, 95, -50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, 59, 10, 32, 32, -32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 10, -32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, 123, 10, 32, 32, -32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 46, 48, 102, -41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, -32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, -47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, -105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, -108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 125, 10, 32, 32, -32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, 114, -101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, -114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, -32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, -99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, 50, 57, 59, 10, -125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, 114, 105, 116, 101, -83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, -32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, -95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 115, 116, 114, -101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, -32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, -10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, -32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, -97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 69, 13, 0, 0, 0, 67, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, -105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 50, 100, 97, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, -85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, -10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, -73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 111, 214, 223, 30, 36, 200, 220, 1, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 157, 209, 167, 70, 138, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, -30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, -97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 16, 5, 0, -0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, -1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, -0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, -101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, -0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 12, 0, 0, -0, 38, 0, 77, 17, 136, 0, 0, 0, 12, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 96, 4, 129, 248, 8, 0, 13, 23, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 8, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 74, 11, -32, 4, 129, 248, 8, 0, 9, 29, 13, 73, 1, 80, 12, 129, 248, 0, 0, 50, 0, 77, 17, 60, 2, 0, 0, 4, 5, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 39, 11, 32, 13, 76, 6, 8, 12, 129, 212, 36, 8, 0, 9, 19, 13, 38, 1, 80, 6, 9, 3, 0, 13, 75, 6, -8, 12, 129, 212, 36, 38, 0, 77, 17, 100, 2, 0, 0, 84, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 80, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, 116, 101, 66, 97, -115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, -0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 8, 0, 0, -0, 2, 0, 78, 17, 110, 0, 77, 17, 100, 2, 0, 0, 0, 5, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, 12, 28, 28, 8, -0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 115, -105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, 0, 46, 0, 62, -17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, 0, 1, 0, 60, -0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, 17, 18, 16, 0, -0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, -0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 26, 218, 106, 51, 227, 246, 25, 34, 184, 43, 161, 176, 211, 114, 225, 141, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 188, 1, 0, -0, 80, 0, 0, 0, 123, 0, 0, 128, 80, 0, 0, 0, 123, 0, 0, 0, 116, 0, 0, 0, 123, 0, 0, 128, 116, 0, 0, 0, 123, 0, 0, 0, 144, 0, 0, 0, 123, 0, 0, 128, 144, 0, 0, 0, 123, 0, 0, 0, 172, 0, 0, 0, 123, 0, 0, 128, 172, 0, 0, 0, 123, 0, 0, -0, 200, 0, 0, 0, 123, 0, 0, 128, 200, 0, 0, 0, 123, 0, 0, 0, 228, 0, 0, 0, 123, 0, 0, 128, 228, 0, 0, 0, 123, 0, 0, 0, 248, 0, 0, 0, 123, 0, 0, 128, 248, 0, 0, 0, 123, 0, 0, 0, 12, 1, 0, 0, 123, 0, 0, 128, 12, 1, 0, 0, 123, 0, 0, -0, 48, 1, 0, 0, 123, 0, 0, 128, 48, 1, 0, 0, 123, 0, 0, 0, 84, 1, 0, 0, 123, 0, 0, 128, 84, 1, 0, 0, 123, 0, 0, 0, 112, 1, 0, 0, 123, 0, 0, 128, 112, 1, 0, 0, 123, 0, 0, 0, 152, 1, 0, 0, 123, 0, 0, 128, 152, 1, 0, 0, 123, 0, 0, -0, 180, 1, 0, 0, 123, 0, 0, 128, 180, 1, 0, 0, 123, 0, 0, 0, 216, 1, 0, 0, 123, 0, 0, 128, 216, 1, 0, 0, 123, 0, 0, 0, 244, 1, 0, 0, 123, 0, 0, 128, 244, 1, 0, 0, 123, 0, 0, 0, 16, 2, 0, 0, 123, 0, 0, 128, 16, 2, 0, 0, 123, 0, 0, -0, 44, 2, 0, 0, 123, 0, 0, 128, 44, 2, 0, 0, 123, 0, 0, 0, 72, 2, 0, 0, 126, 0, 0, 128, 72, 2, 0, 0, 126, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, -0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, -0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, -0, 0, 0, 0, 0, 112, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, -0, 67, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 21, 16, 0, -0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 208, 115, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 26, 16, 0, 0, 8, 2, 0, -0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 8, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, -21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, -110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, -0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, 80, 73, 82, 86, -95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, -0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 8, 0, -0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, -0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 208, 115, 0, 0, 242, 241, 41, 75, 0, 0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, 0, 74, 255, 1, -0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, +10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, +114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, +80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, +84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, +104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 84, 101, 120, 116, 117, 114, 101, 50, 68, 60, 102, 108, 111, 97, 116, 52, 62, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, +116, 48, 41, 59, 10, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 115, 48, 41, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, +116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, +116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, +67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, +48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, +10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, +109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, +32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, +41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, +108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, +116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, +44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, +97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, 53, 51, +57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, 32, 102, +108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 57, 44, 32, 95, 50, 50, +50, 44, 32, 95, 50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, 53, 102, +59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, +116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, 32, 32, +123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, +50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, +101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, +101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, +79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, +120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, 32, 32, +125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, +32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, +104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, 102, 108, +111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, +44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, +115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 95, 51, +50, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 112, +114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, +10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 32, +61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, +110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, +111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, 41, 59, +10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, 67, 111, +108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 69, 13, 0, 0, 0, 67, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, +83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 48, 67, 68, 57, 66, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, +114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 48, 99, 100, 57, 98, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, +95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, +84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, +32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 217, 229, 127, 184, 176, 204, 220, +1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 157, 209, 167, 70, 138, 12, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, +0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, +115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 112, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, +0, 16, 5, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 0, 0, 0, 0, 252, 1, 0, 0, 8, 16, 0, 0, 80, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, +0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, +0, 16, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 28, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, +118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 0, 0, 0, 0, 22, 0, 80, +17, 2, 0, 5, 0, 4, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 4, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 8, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, 1, 8, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 80, 0, 0, 0, 1, 0, 252, +1, 12, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 12, 5, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 11, 96, 4, 129, 248, 8, 0, 13, 23, 1, 80, 12, 129, 248, 0, 0, 0, 0, 38, 0, 77, 17, 20, 2, 0, 0, 8, 5, 0, 0, 1, 16, 0, 0, 7, 0, 9, +5, 13, 74, 11, 32, 4, 129, 248, 8, 0, 9, 29, 13, 73, 1, 80, 12, 129, 248, 0, 0, 50, 0, 77, 17, 60, 2, 0, 0, 4, 5, 0, 0, 2, 16, 0, 0, 7, 0, 9, 5, 13, 39, 11, 32, 13, 76, 6, 8, 12, 129, 212, 36, 8, 0, 9, 19, 13, 38, 1, 80, 6, 9, 3, +0, 13, 75, 6, 8, 12, 129, 212, 36, 38, 0, 77, 17, 100, 2, 0, 0, 84, 3, 0, 0, 3, 16, 0, 0, 7, 0, 9, 5, 13, 76, 11, 32, 4, 36, 8, 0, 9, 12, 13, 75, 1, 80, 12, 36, 0, 0, 0, 0, 74, 0, 62, 17, 12, 16, 0, 0, 136, 0, 60, 83, 112, 114, 105, +116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, +17, 0, 0, 5, 0, 0, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 4, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, 0, 4, 0, 0, 0, 22, 0, 80, 17, 0, 0, 5, 0, 8, 0, 4, 0, 116, 0, 0, 0, 1, 0, 28, +0, 8, 0, 0, 0, 2, 0, 78, 17, 110, 0, 77, 17, 100, 2, 0, 0, 0, 5, 0, 0, 4, 16, 0, 0, 7, 0, 9, 5, 13, 76, 6, 14, 3, 36, 13, 50, 6, 2, 3, 84, 13, 68, 6, 2, 3, 28, 13, 65, 6, 2, 3, 76, 13, 23, 6, 2, 3, 128, 224, 13, 60, 6, 18, +12, 28, 28, 8, 0, 9, 28, 13, 75, 1, 116, 6, 27, 3, 0, 9, 21, 13, 49, 6, 2, 3, 84, 9, 24, 13, 38, 6, 2, 3, 28, 9, 21, 13, 64, 6, 2, 3, 76, 9, 5, 13, 22, 6, 2, 3, 128, 224, 9, 20, 13, 59, 6, 18, 12, 28, 28, 46, 0, 62, 17, 64, 0, 0, +0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 228, 0, 0, 0, 1, 0, 112, 0, 0, 0, 0, +0, 46, 0, 62, 17, 64, 0, 0, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 16, 2, 0, +0, 1, 0, 60, 0, 0, 0, 0, 0, 50, 0, 77, 17, 88, 3, 0, 0, 252, 4, 0, 0, 5, 16, 0, 0, 7, 0, 9, 5, 13, 45, 6, 2, 12, 84, 36, 8, 0, 9, 31, 13, 39, 1, 116, 3, 0, 9, 27, 13, 43, 3, 28, 9, 12, 13, 44, 12, 28, 28, 0, 0, 86, 0, 62, +17, 18, 16, 0, 0, 128, 0, 60, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 0, 0, 1, 0, 0, 0, 4, 0, 200, 0, 0, 0, 1, 0, 28, 0, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 78, +17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 26, 218, 106, 51, 227, 246, 25, 34, 184, 43, 161, 176, 211, 114, 225, 141, 0, 0, 242, 0, 0, 0, 200, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 76, 2, 0, 0, 0, 0, 0, 0, 36, 0, 0, +0, 188, 1, 0, 0, 80, 0, 0, 0, 123, 0, 0, 128, 80, 0, 0, 0, 123, 0, 0, 0, 116, 0, 0, 0, 123, 0, 0, 128, 116, 0, 0, 0, 123, 0, 0, 0, 144, 0, 0, 0, 123, 0, 0, 128, 144, 0, 0, 0, 123, 0, 0, 0, 172, 0, 0, 0, 123, 0, 0, 128, 172, 0, 0, +0, 123, 0, 0, 0, 200, 0, 0, 0, 123, 0, 0, 128, 200, 0, 0, 0, 123, 0, 0, 0, 228, 0, 0, 0, 123, 0, 0, 128, 228, 0, 0, 0, 123, 0, 0, 0, 248, 0, 0, 0, 123, 0, 0, 128, 248, 0, 0, 0, 123, 0, 0, 0, 12, 1, 0, 0, 123, 0, 0, 128, 12, 1, 0, +0, 123, 0, 0, 0, 48, 1, 0, 0, 123, 0, 0, 128, 48, 1, 0, 0, 123, 0, 0, 0, 84, 1, 0, 0, 123, 0, 0, 128, 84, 1, 0, 0, 123, 0, 0, 0, 112, 1, 0, 0, 123, 0, 0, 128, 112, 1, 0, 0, 123, 0, 0, 0, 152, 1, 0, 0, 123, 0, 0, 128, 152, 1, 0, +0, 123, 0, 0, 0, 180, 1, 0, 0, 123, 0, 0, 128, 180, 1, 0, 0, 123, 0, 0, 0, 216, 1, 0, 0, 123, 0, 0, 128, 216, 1, 0, 0, 123, 0, 0, 0, 244, 1, 0, 0, 123, 0, 0, 128, 244, 1, 0, 0, 123, 0, 0, 0, 16, 2, 0, 0, 123, 0, 0, 128, 16, 2, 0, +0, 123, 0, 0, 0, 44, 2, 0, 0, 123, 0, 0, 128, 44, 2, 0, 0, 123, 0, 0, 0, 72, 2, 0, 0, 126, 0, 0, 128, 72, 2, 0, 0, 126, 0, 0, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, +0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, +0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, +0, 0, 16, 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 107, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 3, 16, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 4, 16, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 5, 16, 0, +0, 0, 0, 0, 0, 67, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 24, 21, 20, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, +21, 21, 16, 0, 0, 1, 0, 0, 2, 14, 0, 23, 21, 0, 0, 0, 0, 10, 2, 0, 68, 0, 0, 242, 241, 10, 0, 24, 21, 23, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 24, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 26, 16, 0, +0, 8, 2, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 8, 0, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, +241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 54, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, +0, 8, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 242, 241, 38, 0, 5, 21, 2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, +0, 3, 16, 0, 0, 34, 0, 3, 18, 13, 21, 3, 0, 1, 16, 0, 0, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 243, 242, 241, 42, 0, 5, 21, 1, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 83, +80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, +16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 10, 0, 24, 21, 1, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, +0, 23, 8, 0, 0, 3, 0, 0, 0, 22, 0, 1, 18, 4, 0, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 1, 16, 0, 0, 64, 0, 0, 0, 14, 0, 8, 16, 12, 16, 0, 0, 23, 0, 4, 0, 15, 16, 0, 0, 18, 0, 1, 18, 3, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, +0, 64, 0, 0, 0, 10, 0, 24, 21, 64, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 18, 16, 0, 0, 23, 0, 3, 0, 17, 16, 0, 0, 14, 0, 23, 21, 1, 16, 0, 0, 3, 2, 0, 68, 0, 0, 242, 241, 41, 75, 0, 0, 152, 7, 0, 0, 246, 138, 0, 0, 211, 33, 3, +0, 74, 255, 1, 0, 48, 35, 1, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, -101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, -40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, -101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, -114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, -98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 115, 97, -109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, -111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, -115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, -115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, 52, 52, 55, 55, -53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, 10, 32, 32, 32, -32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 122, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, 57, 44, 32, 95, -50, 50, 50, 44, 32, 95, 50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, 49, 53, 54, 50, -53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, -105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, 41, 10, 32, 32, -32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, -42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, -110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, -114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, -101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, -116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, 10, 32, 32, -32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, 59, -10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, -116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 32, 32, 32, 32, -102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, 44, 32, 48, 46, -48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, -95, 51, 50, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, -83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, -40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, -114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, -32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, -95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 84, 101, 120, -67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, 97, 105, 110, 40, -41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 80, 83, 95, -67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, -0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, +84, 97, 114, 103, 101, 116, 48, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 59, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, +100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 44, +32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 102, 108, +111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 10, 123, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, +103, 41, 44, 32, 98, 41, 41, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, +52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, 116, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 105, 110, 111, 117, +116, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 10, 123, 10, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, +99, 107, 110, 101, 115, 115, 44, 32, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 48, 46, 50, 48, 48, 48, 48, 48, 48, 48, 50, 57, 56, 48, 50, 51, 50, 50, 51, 56, 55, 54, 57, 53, 51, 49, 50, 53, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, +112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 48, 48, 48, 48, 48, 48, 48, 53, 57, 54, 48, 52, 54, +52, 52, 55, 55, 53, 51, 57, 48, 54, 50, 53, 102, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 49, 57, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 120, 59, +10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 50, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 121, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 50, 50, 54, 32, 61, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, +122, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 40, 95, 50, 49, +57, 44, 32, 95, 50, 50, 50, 44, 32, 95, 50, 50, 54, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, +101, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 48, 48, 48, 48, 48, 50, 51, 56, 52, 49, 56, 53, 55, 57, 49, 48, +49, 53, 54, 50, 53, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, +115, 105, 103, 68, 105, 115, 116, 41, 59, 10, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 10, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 46, 48, 102, +41, 10, 32, 32, 32, 32, 123, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 32, 42, 32, 50, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, +105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 40, 40, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, +115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 47, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, +98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 102, 108, 111, 97, 116, 40, 48, 41, 44, 32, 102, 108, 111, 97, 116, 40, 49, 41, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 10, 32, 32, 32, 32, +32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 46, 120, 120, 120, 120, 41, +59, 10, 32, 32, 32, 32, 125, 10, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 48, 46, 48, 102, 46, 120, 120, 120, 120, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 46, 120, 120, +120, 120, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 102, 108, 111, 97, 116, 52, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, +100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 50, 32, 61, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, +32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 49, 54, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 50, 32, 61, 32, 102, 108, 111, 97, 116, 52, 40, 48, 46, 48, 102, +44, 32, 48, 46, 48, 102, 44, 32, 48, 46, 48, 102, 44, 32, 49, 46, 48, 102, 41, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 95, 51, 50, 54, 32, 61, 32, 48, 46, 48, 102, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 95, 51, 50, 57, 32, 61, 32, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 95, 51, 49, 50, 44, 32, 95, 51, 49, 54, 44, 32, 95, 51, 50, 50, 44, 32, 95, 51, 50, 54, 41, 59, 10, 32, 32, 32, 32, 114, 101, 116, +117, 114, 110, 32, 95, 51, 50, 57, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 32, 61, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 102, 114, 97, 103, 95, +109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, +67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, +114, 103, 101, 116, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 80, 83, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, +114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, +95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 102, 114, 97, 103, 95, 109, +97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, +10, 0, 7, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, 0, 236, 0, 0, -0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, -22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, -108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, -0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 6, 16, 0, +0, 236, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, +241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, +101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, +0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, -22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, -108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, 0, 16, 16, 0, -0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, -105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 76, 2, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 24, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 102, 114, 97, 103, 95, 109, 97, 105, 110, 0, 242, +241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 80, 83, 77, 97, 105, 110, 0, 242, 241, 54, 0, 1, 22, 0, 0, 0, 0, 13, 16, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, +101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 95, 83, 104, 97, 100, 105, 110, 103, 0, 30, 0, 1, 22, 0, 0, 0, 0, 14, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 83, 104, 97, 100, 105, 110, 103, 0, 241, 46, 0, 1, 22, 0, 0, 0, +0, 16, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 242, 241, 42, 0, 1, 22, 0, 0, 0, 0, 19, 16, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, +110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 95, 109, 101, 100, 105, 97, 110, 0, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 24, 0, 0, 0, 16, 2, 0, +0, 1, 0, 0, 0, 1, 0, 0, 0, 61, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, -0, 38, 0, 81, 17, 22, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 25, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 84, 101, 120, -116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, +97, 105, 110, 0, 0, 38, 0, 81, 17, 22, 16, 0, 0, 7, 0, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 38, 0, 81, 17, 25, 16, 0, 0, 6, 0, 255, 255, 255, 255, 255, 255, 0, 0, 255, +255, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, -107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, -96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, -0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, -0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, -97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 65, 50, 54, 50, 68, 65, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, +142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, +0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 20, 5, 0, 0, 0, 0, 0, 0, 68, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, +241, 1, 0, 0, 0, 0, 0, 0, 0, 76, 2, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 0, 0, 0, 0, 76, 2, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, +255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, +115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 48, 67, 68, 57, 66, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 158, 94, 53, 220, 30, 44, 109, -65, 154, 2, 226, 233, 146, 64, 64, 17, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, -92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, -101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 97, 50, 54, 50, 100, 97, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, -0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 111, 69, 122, +17, 107, 199, 187, 79, 145, 201, 6, 238, 4, 89, 99, 19, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, +92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, +115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 48, 99, 100, 57, 98, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, +0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 64, 2, 0, 0, 111, 1, 0, -0, 36, 1, 0, 0, 0, 0, 0, 0, 117, 13, 0, 0, 128, 0, 0, 0, 138, 12, 0, 0, 104, 7, 0, 0, 112, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, 0, 21, 0, 0, -0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 13, 0, 0, -0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 64, 2, 0, +0, 111, 1, 0, 0, 36, 1, 0, 0, 0, 0, 0, 0, 117, 13, 0, 0, 128, 0, 0, 0, 138, 12, 0, 0, 104, 7, 0, 0, 112, 0, 0, 0, 32, 0, 0, 0, 40, 0, 0, 0, 56, 2, 0, 0, 44, 0, 0, 0, 100, 0, 0, 0, 3, 0, 0, 0, 36, 0, 0, 0, 22, 0, 0, +0, 21, 0, 0, 0, 35, 0, 0, 0, 29, 0, 0, 0, 15, 0, 0, 0, 6, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 26, 0, 0, 0, 27, 0, 0, 0, 28, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, +0, 13, 0, 0, 0, 14, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 7, 0, 0, 0, 23, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0, 0, 32, 0, 0, 0, 34, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -382,36 +380,36 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, -0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, -255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, -72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, -0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 63, 218, 217, 37, 32, 162, 116, 125, 221, 209, 13, 1, 180, 237, 26, 9, 0, 120, 77, 0, 0, 68, 88, 66, 67, 145, 94, 181, -7, 109, 13, 98, 195, 199, 5, 186, 118, 80, 46, 162, 146, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, 0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, 0, 232, 3, 0, -0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, 71, 40, 0, 0, -0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, -101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, 70, 51, 67, 48, -0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 72, 0, 0, 0, 56, 3, 0, 0, 72, 0, 0, 0, 72, 3, 0, 0, 72, 0, 0, 0, 88, 3, 0, 0, 72, 0, 0, 0, 104, 3, 0, 0, 86, 0, 0, -0, 120, 3, 0, 0, 86, 0, 0, 0, 140, 3, 0, 0, 88, 0, 0, 0, 152, 3, 0, 0, 90, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, -0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, -0, 40, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 52, 1, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 8, 0, 255, 255, 7, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 9, 0, 9, 0, 0, -0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 105, -110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 164, 1, 0, 0, 248, 0, 0, 0, 179, 1, 0, 0, 24, 1, 0, 0, 194, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, -255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 80, 111, 115, 105, -116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 171, 171, 38, 2, 0, 0, 24, 1, 0, 0, 54, 2, 0, 0, 248, 0, 0, 0, 63, 2, 0, 0, 24, 1, 0, 0, 72, 2, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, 0, 4, 0, 0, -0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 76, 1, 0, 0, 5, 0, 0, 0, 92, 1, 0, 0, 224, 0, 0, 0, 152, 1, 0, 0, 232, 1, 0, -0, 3, 0, 0, 0, 248, 1, 0, 0, 0, 0, 0, 0, 28, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, -49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, 3, 0, 0, 1, -128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, 128, 1, 0, 0, -2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 1, 0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, 0, 0, 0, 0, -0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, 0, 1, 0, 0, -0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 17, 0, 0, 8, 18, 32, 16, -0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, 8, 66, 32, 16, -0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, 1, 83, 80, 68, -66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 18, 0, 0, 0, 1, 0, 0, +0, 0, 0, 0, 0, 3, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 68, 69, 70, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, +0, 28, 0, 0, 0, 0, 4, 255, 255, 1, 1, 0, 0, 129, 0, 0, 0, 92, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 110, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, +0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 13, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, +40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 171, 171, 73, 83, 71, 78, 68, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, +0, 0, 0, 0, 0, 3, 3, 0, 0, 56, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, 86, 95, 84, 97, 114, 103, 101, 116, 0, 171, 171, 1, 0, 1, 0, 0, 0, 1, 1, 61, 130, 199, 60, 123, 221, 228, 79, 140, 144, 78, 12, 108, 232, 253, 0, 120, 77, 0, 0, 68, 88, 66, +67, 188, 16, 244, 65, 214, 225, 122, 105, 227, 102, 47, 98, 205, 223, 22, 44, 1, 0, 0, 0, 120, 77, 0, 0, 7, 0, 0, 0, 60, 0, 0, 0, 44, 4, 0, 0, 68, 5, 0, 0, 76, 75, 0, 0, 200, 75, 0, 0, 152, 76, 0, 0, 8, 77, 0, 0, 65, 111, 110, 57, 232, 3, 0, +0, 232, 3, 0, 0, 0, 2, 254, 255, 180, 3, 0, 0, 52, 0, 0, 0, 1, 0, 36, 0, 0, 0, 48, 0, 0, 0, 48, 0, 0, 0, 36, 0, 1, 0, 48, 0, 0, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 254, 255, 254, 255, 195, 0, 68, 66, 85, +71, 40, 0, 0, 0, 224, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 132, 0, 0, 0, 11, 0, 0, 0, 136, 0, 0, 0, 3, 0, 0, 0, 164, 2, 0, 0, 224, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, +110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 50, 69, +49, 52, 54, 56, 0, 40, 0, 0, 0, 0, 0, 255, 255, 20, 3, 0, 0, 0, 0, 255, 255, 32, 3, 0, 0, 0, 0, 255, 255, 44, 3, 0, 0, 72, 0, 0, 0, 56, 3, 0, 0, 72, 0, 0, 0, 72, 3, 0, 0, 72, 0, 0, 0, 88, 3, 0, 0, 72, 0, 0, 0, 104, 3, 0, +0, 86, 0, 0, 0, 120, 3, 0, 0, 86, 0, 0, 0, 140, 3, 0, 0, 88, 0, 0, 0, 152, 3, 0, 0, 90, 0, 0, 0, 164, 3, 0, 0, 109, 97, 105, 110, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 2, +0, 1, 0, 0, 0, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 229, 0, 0, 0, 248, 0, 0, 0, 8, 1, 0, +0, 24, 1, 0, 0, 40, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 52, 1, 0, 0, 3, 0, 0, 0, 255, 255, 255, 255, 8, 0, 255, 255, 7, 0, 0, 0, 6, 0, 7, 0, 255, 255, 255, 255, 8, 0, 0, 0, 255, 255, 255, 255, 255, 255, 9, +0, 9, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, 255, 10, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, +111, 110, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 171, 171, 164, 1, 0, 0, 248, 0, 0, 0, 179, 1, 0, 0, 24, 1, 0, 0, 194, 1, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 10, 0, 1, 0, 3, 0, 208, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, +0, 255, 255, 255, 255, 1, 0, 0, 0, 2, 0, 3, 0, 4, 0, 5, 0, 2, 0, 0, 0, 6, 0, 7, 0, 8, 0, 9, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, +80, 111, 115, 105, 116, 105, 111, 110, 0, 67, 111, 108, 111, 114, 0, 171, 171, 38, 2, 0, 0, 24, 1, 0, 0, 54, 2, 0, 0, 248, 0, 0, 0, 63, 2, 0, 0, 24, 1, 0, 0, 72, 2, 0, 0, 24, 1, 0, 0, 5, 0, 0, 0, 1, 0, 14, 0, 1, 0, 4, 0, 80, 2, 0, +0, 4, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 255, 255, 1, 0, 255, 255, 255, 255, 6, 0, 0, 0, 255, 255, 255, 255, 3, 0, 255, 255, 0, 0, 0, 0, 224, 0, 0, 0, 76, 1, 0, 0, 5, 0, 0, 0, 92, 1, 0, 0, 224, 0, 0, 0, 152, 1, 0, +0, 232, 1, 0, 0, 3, 0, 0, 0, 248, 1, 0, 0, 0, 0, 0, 0, 28, 2, 0, 0, 112, 2, 0, 0, 3, 0, 0, 0, 128, 2, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, +108, 101, 114, 32, 49, 48, 46, 49, 0, 31, 0, 0, 2, 5, 0, 0, 128, 0, 0, 15, 144, 31, 0, 0, 2, 5, 0, 1, 128, 1, 0, 15, 144, 31, 0, 0, 2, 5, 0, 2, 128, 2, 0, 15, 144, 9, 0, 0, 3, 0, 0, 4, 192, 1, 0, 228, 144, 3, 0, 228, 160, 9, 0, 0, +3, 0, 0, 1, 128, 1, 0, 228, 144, 1, 0, 228, 160, 9, 0, 0, 3, 0, 0, 2, 128, 1, 0, 228, 144, 2, 0, 228, 160, 9, 0, 0, 3, 0, 0, 4, 128, 1, 0, 228, 144, 4, 0, 228, 160, 4, 0, 0, 4, 0, 0, 3, 192, 0, 0, 170, 128, 0, 0, 228, 160, 0, 0, 228, +128, 1, 0, 0, 2, 0, 0, 8, 192, 0, 0, 170, 128, 1, 0, 0, 2, 0, 0, 3, 224, 0, 0, 228, 144, 1, 0, 0, 2, 1, 0, 15, 224, 2, 0, 228, 144, 255, 255, 0, 0, 83, 72, 68, 82, 16, 1, 0, 0, 64, 0, 1, 0, 68, 0, 0, 0, 89, 0, 0, 4, 70, 142, 32, +0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 3, 50, 16, 16, 0, 0, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 1, 0, 0, 0, 95, 0, 0, 3, 242, 16, 16, 0, 2, 0, 0, 0, 101, 0, 0, 3, 50, 32, 16, 0, 0, 0, 0, 0, 101, 0, 0, 3, 242, 32, 16, +0, 1, 0, 0, 0, 103, 0, 0, 4, 242, 32, 16, 0, 2, 0, 0, 0, 1, 0, 0, 0, 54, 0, 0, 5, 50, 32, 16, 0, 0, 0, 0, 0, 70, 16, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 242, 32, 16, 0, 1, 0, 0, 0, 70, 30, 16, 0, 2, 0, 0, 0, 17, 0, 0, +8, 18, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 8, 34, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 17, 0, 0, +8, 66, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 2, 0, 0, 0, 17, 0, 0, 8, 130, 32, 16, 0, 2, 0, 0, 0, 70, 30, 16, 0, 1, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 62, 0, 0, +1, 83, 80, 68, 66, 0, 70, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 67, 47, 67, 43, 43, 32, 77, 83, 70, 32, 55, 46, 48, 48, 13, 10, 26, 68, 83, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -419,7 +417,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -427,7 +425,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 56, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, @@ -435,7 +433,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +255, 255, 255, 255, 255, 255, 255, 255, 255, 5, 0, 0, 0, 32, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -443,7 +441,7 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -451,215 +449,216 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 45, 182, 148, 233, 23, 112, 203, 78, 148, 200, 178, 55, 161, 209, 117, 253, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 164, 49, 233, 74, 157, 73, 68, 77, 180, 8, 235, 70, 84, 85, 167, 132, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, -32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, -32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, -115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, -32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, -110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, -83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, -114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, -79, 82, 68, 48, 59, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, 0, 177, 197, 0, -0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, +114, 117, 99, 116, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, +100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, +114, 101, 103, 105, 115, 116, 101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, +114, 109, 32, 58, 32, 112, 97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, +116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, +105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, +67, 111, 108, 111, 114, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, +69, 88, 67, 79, 79, 82, 68, 48, 59, 117, 131, 1, 0, 198, 90, 0, 0, 174, 73, 0, 0, 8, 104, 0, 0, 38, 247, 2, 0, 255, 49, 2, 0, 193, 195, 0, 0, 49, 251, 3, 0, 168, 209, 0, 0, 80, 133, 1, 0, 211, 99, 0, 0, 143, 154, 3, 0, 103, 159, 1, 0, 90, 28, 0, +0, 177, 197, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, -10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, 84, 82, 69, 65, -77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, -111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, -111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 83, 84, -82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, 101, 114, 40, 98, -48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, 97, 99, 107, 111, -102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, -101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, -116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 10, 115, 116, -114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, -32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 67, -79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, -32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, -95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, 111, 105, 100, 32, -83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, -115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 10, 123, 10, -32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 32, -61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, 105, 116, 101, 66, -97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 111, -117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, -83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, -116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, -80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, -110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, -111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, -116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, -67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, +59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 83, +84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, +115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, +105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, +83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 32, 58, 32, 114, 101, 103, 105, 115, 116, +101, 114, 40, 98, 48, 41, 10, 123, 10, 32, 32, 32, 32, 99, 111, 108, 117, 109, 110, 95, 109, 97, 106, 111, 114, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 32, 58, 32, 112, +97, 99, 107, 111, 102, 102, 115, 101, 116, 40, 99, 48, 41, 59, 10, 125, 59, 10, 10, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, +86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, +80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 115, 116, 97, 116, 105, 99, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, +10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, +68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, +111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, 10, 118, +111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, +114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, +41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, +105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, 112, 114, +105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, +32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 114, 101, +97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, 101, 95, +105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 105, 110, +95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, 97, +103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 115, 116, +97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, +95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 39, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, -104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, 70, 51, 67, 48, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, -114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, -57, 51, 97, 57, 99, 55, 102, 51, 99, 48, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, -111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, -95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, -116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, -80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, -97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 83, 70, 228, 30, 36, 200, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 0, 106, 138, 126, 108, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 239, 254, 239, 1, 0, 0, 0, 39, 8, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, +99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 67, 50, 69, 49, 52, 54, 56, 0, 0, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, +92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, +48, 48, 48, 50, 52, 55, 49, 99, 50, 101, 49, 52, 54, 56, 0, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, +32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 80, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, +116, 32, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, +102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 73, 78, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 102, 108, 111, +97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 86, 83, 95, 79, 85, 84, 80, 85, 84, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, +52, 32, 83, 104, 97, 100, 105, 110, 103, 27, 226, 48, 1, 128, 0, 0, 0, 101, 182, 131, 184, 176, 204, 220, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 94, 0, 0, 0, 40, 0, 0, 0, 27, 226, 48, 1, 0, 106, 138, 126, 108, 7, 0, 0, 1, 0, 0, 0, 93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, -112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, 104, 108, 115, 108, -69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 96, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 8, 16, 0, 0, 100, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, 17, 3, 16, 0, -0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, -0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 12, 0, 4, -0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, -17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, -0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, -0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, -0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, -0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, -0, 1, 0, 172, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 92, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 8, 12, 128, 128, 40, 8, 0, 13, 23, 1, 128, 140, 12, 128, 128, 0, 0, 42, 0, 77, 17, 4, 3, 0, 0, 88, 3, 0, 0, 1, 16, 0, -0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 40, 8, 0, 9, 33, 13, 82, 1, 128, 140, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 163, 81, 188, 104, 12, 83, 156, 246, 0, -178, 239, 190, 114, 55, 253, 77, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 96, 0, 0, 128, 100, 0, 0, 0, 96, 0, 0, 0, 120, 0, 0, 0, 96, 0, 0, -128, 120, 0, 0, 0, 96, 0, 0, 0, 140, 0, 0, 0, 91, 0, 0, 128, 140, 0, 0, 0, 91, 0, 0, 0, 172, 0, 0, 0, 91, 0, 0, 128, 172, 0, 0, 0, 91, 0, 0, 0, 204, 0, 0, 0, 91, 0, 0, 128, 204, 0, 0, 0, 91, 0, 0, 0, 236, 0, 0, 0, 91, 0, 0, -128, 236, 0, 0, 0, 91, 0, 0, 0, 12, 1, 0, 0, 96, 0, 0, 128, 12, 1, 0, 0, 96, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, -0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 66, 0, 60, 17, 16, 1, 0, 0, 0, 1, 10, 0, 1, 0, 25, 30, 244, 101, 10, 0, 1, 0, 25, 30, 244, 101, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, +32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 0, 0, 62, 0, 61, 17, 1, 104, 108, 115, 108, 70, 108, 97, 103, 115, 0, 48, 120, 49, 0, 104, 108, 115, 108, 84, 97, 114, 103, 101, 116, 0, 118, 115, 95, 52, 95, 48, 95, 108, 101, 118, 101, 108, 95, 57, 95, 51, 0, +104, 108, 115, 108, 69, 110, 116, 114, 121, 0, 109, 97, 105, 110, 0, 0, 0, 42, 0, 16, 17, 0, 0, 0, 0, 96, 3, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 8, 16, 0, 0, 100, 0, 0, 0, 1, 0, 160, 109, 97, 105, 110, 0, 50, 0, 62, +17, 3, 16, 0, 0, 9, 0, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, +0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 4, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, +0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 24, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, +0, 22, 0, 80, 17, 1, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 28, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, +0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 1, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 58, 0, 62, 17, 7, 16, 0, 0, 136, 0, 60, 109, 97, 105, 110, 32, 114, 101, 116, 117, 114, 110, 32, 118, 97, 108, 117, 101, 62, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 24, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 32, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 28, 0, 4, +0, 100, 0, 0, 0, 1, 0, 172, 0, 36, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 32, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 40, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 36, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 44, 0, 0, 0, 22, 0, 80, +17, 2, 0, 5, 0, 8, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 16, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 12, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 20, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 16, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, +0, 24, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 20, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 28, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 0, 0, 4, 0, 100, 0, 0, 0, 1, 0, 172, 0, 0, 0, 0, 0, 22, 0, 80, 17, 2, 0, 5, 0, 4, 0, 4, +0, 100, 0, 0, 0, 1, 0, 172, 0, 4, 0, 0, 0, 38, 0, 77, 17, 136, 0, 0, 0, 92, 3, 0, 0, 0, 16, 0, 0, 7, 0, 9, 5, 13, 24, 6, 8, 12, 128, 128, 40, 8, 0, 13, 23, 1, 128, 140, 12, 128, 128, 0, 0, 42, 0, 77, 17, 4, 3, 0, 0, 88, 3, 0, +0, 1, 16, 0, 0, 7, 0, 9, 5, 13, 83, 6, 2, 12, 128, 128, 40, 8, 0, 9, 33, 13, 82, 1, 128, 140, 12, 128, 128, 0, 0, 0, 0, 2, 0, 78, 17, 2, 0, 78, 17, 2, 0, 6, 0, 244, 0, 0, 0, 24, 0, 0, 0, 1, 0, 0, 0, 16, 1, 163, 81, 188, 104, 12, +83, 156, 246, 0, 178, 239, 190, 114, 55, 253, 77, 0, 0, 242, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 16, 1, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 180, 0, 0, 0, 100, 0, 0, 0, 96, 0, 0, 128, 100, 0, 0, 0, 96, 0, 0, 0, 120, 0, 0, +0, 96, 0, 0, 128, 120, 0, 0, 0, 96, 0, 0, 0, 140, 0, 0, 0, 91, 0, 0, 128, 140, 0, 0, 0, 91, 0, 0, 0, 172, 0, 0, 0, 91, 0, 0, 128, 172, 0, 0, 0, 91, 0, 0, 0, 204, 0, 0, 0, 91, 0, 0, 128, 204, 0, 0, 0, 91, 0, 0, 0, 236, 0, 0, +0, 91, 0, 0, 128, 236, 0, 0, 0, 91, 0, 0, 0, 12, 1, 0, 0, 96, 0, 0, 128, 12, 1, 0, 0, 96, 0, 0, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 24, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 16, +0, 5, 0, 15, 0, 5, 0, 16, 0, 5, 0, 15, 0, 5, 0, 24, 0, 5, 0, 24, 0, 246, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 76, 0, 0, 0, 1, 16, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, +0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 180, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, +0, 22, 0, 27, 21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, +110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, +111, 114, 0, 242, 241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, +0, 0, 16, 0, 0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, +115, 105, 116, 105, 111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, +0, 14, 0, 8, 16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, +21, 64, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 15, 16, 0, 0, 180, 1, 0, 0, 10, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 60, 0, 0, 0, 60, 0, 0, 0, 8, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 22, 0, 27, -21, 64, 0, 0, 0, 2, 0, 0, 0, 8, 0, 102, 108, 111, 97, 116, 50, 0, 243, 242, 241, 22, 0, 27, 21, 64, 0, 0, 0, 4, 0, 0, 0, 16, 0, 102, 108, 111, 97, 116, 52, 0, 243, 242, 241, 82, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, 0, 0, 0, 105, 110, 95, 86, 83, -95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 243, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 242, -241, 38, 0, 5, 21, 3, 0, 0, 0, 2, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 0, 10, 0, 1, 18, 1, 0, 0, 0, 3, 16, 0, 0, 78, 0, 3, 18, 13, 21, 3, 0, 0, 16, 0, -0, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 242, 241, 13, 21, 3, 0, 1, 16, 0, 0, 8, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 241, 13, 21, 3, 0, 1, 16, 0, 0, 24, 0, 103, 108, 95, 80, 111, 115, 105, 116, 105, -111, 110, 0, 242, 241, 42, 0, 5, 21, 3, 0, 0, 0, 5, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 0, 243, 242, 241, 10, 0, 24, 21, 6, 16, 0, 0, 1, 0, 1, 0, 14, 0, 8, -16, 7, 16, 0, 0, 23, 0, 1, 0, 4, 16, 0, 0, 10, 0, 24, 21, 3, 0, 0, 0, 1, 0, 1, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 0, 0, 0, 3, 0, 0, 0, 14, 0, 8, 16, 9, 16, 0, 0, 23, 8, 0, 0, 3, 0, 0, 0, 30, 0, 28, 21, 64, 0, 0, -0, 4, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 0, 64, 0, 102, 108, 111, 97, 116, 52, 120, 52, 0, 10, 0, 24, 21, 12, 16, 0, 0, 1, 0, 1, 0, 10, 0, 24, 21, 13, 16, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 148, 128, 1, 0, 212, 149, 2, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, +95, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, +83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, +32, 102, 108, 111, 97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, +86, 83, 59, 10, 10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, +109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, +95, 109, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, +46, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, +32, 32, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, +105, 111, 110, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, +61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, +115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, +32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, +32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, +112, 117, 116, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, +117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, +94, 0, 0, 0, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, -111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 10, 125, 59, 10, 10, 115, 116, 114, 117, 99, 116, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 10, 123, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 50, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, -120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 52, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 10, 32, 32, 32, 32, 102, 108, 111, -97, 116, 52, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 125, 59, 10, 10, 115, 116, 97, 116, 105, 99, 32, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 59, 10, -10, 118, 111, 105, 100, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, -115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 10, 125, 10, 10, 118, 111, 105, 100, 32, 118, 101, 114, 116, 95, 109, 97, 105, -110, 40, 41, 10, 123, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 80, 111, 115, -105, 116, 105, 111, 110, 32, 61, 32, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 32, 61, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 83, -112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 59, -10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 114, 101, 97, 109, 115, 86, 83, 46, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, 116, -114, 101, 97, 109, 115, 86, 83, 46, 67, 111, 108, 111, 114, 59, 10, 125, 10, 10, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, 109, 97, 105, 110, 40, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 73, 110, 112, 117, 116, 32, 115, 116, 97, 103, -101, 95, 105, 110, 112, 117, 116, 41, 10, 123, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, -105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 115, 116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 115, -116, 97, 103, 101, 95, 105, 110, 112, 117, 116, 46, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 118, 101, 114, 116, 95, 109, 97, 105, 110, 40, 41, 59, 10, 32, 32, 32, 32, 83, 80, 73, 82, 86, 95, 67, 114, 111, 115, 115, 95, 79, 117, 116, 112, 117, 116, 32, -115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 103, 108, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 59, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 46, 111, -117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 32, 61, 32, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 59, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 116, 97, 103, 101, 95, 111, 117, 116, 112, 117, 116, 59, 10, 125, 10, 0, 7, 0, 0, 0, 1, 0, 0, 0, -93, 0, 0, 0, 94, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, +0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 11, 202, 49, 1, 56, 0, 0, 0, 0, 16, 0, 0, 2, 16, 0, 0, 56, 0, 0, 0, 11, 0, 255, 255, 4, 0, 0, 0, 255, 255, 3, 0, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, -22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, +0, 22, 0, 1, 22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 68, 51, 68, 83, 72, 68, 82, 0, 16, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 96, 8, 0, 0, 0, 8, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 22, 0, 1, -22, 0, 0, 0, 0, 10, 16, 0, 0, 118, 101, 114, 116, 95, 109, 97, 105, 110, 0, 242, 241, 30, 0, 1, 22, 0, 0, 0, 0, 11, 16, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 95, 86, 83, 77, 97, 105, 110, 0, 242, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 16, 0, 0, 0, 12, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, +120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 18, 0, 37, 17, 0, 0, 0, 0, 136, 0, 0, 0, 1, 0, 109, 97, 105, 110, 0, 0, 46, 0, 81, 17, 14, 16, 0, 0, 8, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, -110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 26, 9, 47, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, +0, 255, 255, 255, 255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, +101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, +49, 67, 50, 69, 49, 52, 54, 56, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 255, 255, 255, 255, 119, 9, 49, 1, 1, 0, 0, 0, 13, 0, 20, 142, 14, 0, 20, 107, 15, 0, 1, 0, 76, 0, 0, 0, 32, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 9, 0, 100, 3, 0, 0, 0, 0, 0, 0, 12, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 109, 97, 105, 110, 0, 110, 111, 110, 101, 0, 0, 0, 45, 186, 46, 241, 1, 0, 0, 0, 0, 0, 0, 0, 16, 1, 0, 0, 32, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 7, 0, 0, 0, 0, 0, 1, 0, 255, 255, 255, -255, 0, 0, 0, 0, 16, 1, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 67, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, -110, 103, 105, 110, 101, 92, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 92, 83, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 66, 121, 116, 101, 99, 111, 100, 101, 115, 92, 83, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 65, 57, 67, 55, -70, 51, 67, 48, 0, 254, 239, 254, 239, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 12, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 46, 49, 1, 77, 74, 223, 105, 1, 0, 0, 0, 164, 49, 233, 74, 157, 73, 68, 77, 180, 8, 235, 70, 84, 85, 167, 132, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, +101, 97, 100, 101, 114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, +99, 115, 92, 115, 104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 52, 55, 49, 99, 50, 101, 49, 52, 54, 56, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 58, 0, +0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 148, 46, 49, 1, 109, 168, 215, 105, 1, 0, 0, 0, 45, 182, 148, 233, 23, 112, 203, 78, 148, 200, 178, 55, 161, 209, 117, 253, 137, 0, 0, 0, 47, 76, 105, 110, 107, 73, 110, 102, 111, 0, 47, 110, 97, 109, 101, 115, 0, 47, 115, 114, 99, 47, 104, 101, 97, 100, 101, -114, 98, 108, 111, 99, 107, 0, 47, 115, 114, 99, 47, 102, 105, 108, 101, 115, 47, 99, 58, 92, 100, 101, 118, 92, 115, 116, 114, 105, 100, 101, 92, 115, 111, 117, 114, 99, 101, 115, 92, 101, 110, 103, 105, 110, 101, 92, 115, 116, 114, 105, 100, 101, 46, 103, 114, 97, 112, 104, 105, 99, 115, 92, 115, -104, 97, 100, 101, 114, 115, 48, 57, 51, 46, 98, 121, 116, 101, 99, 111, 100, 101, 115, 92, 115, 104, 97, 100, 101, 114, 64, 48, 120, 48, 48, 48, 48, 48, 50, 57, 51, 97, 57, 99, 55, 102, 51, 99, 48, 0, 4, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 27, 0, 0, 0, 0, 0, -0, 0, 34, 0, 0, 0, 8, 0, 0, 0, 17, 0, 0, 0, 7, 0, 0, 0, 10, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 220, 81, 51, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 236, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 87, 8, 0, 0, 128, 0, 0, 0, 108, 7, 0, 0, 124, 4, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, +0, 44, 2, 0, 0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, +0, 10, 0, 0, 0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 16, 0, 0, 0, 32, 0, 0, 0, 229, 0, 0, 0, 236, 1, 0, 0, 111, 1, 0, 0, 112, 0, 0, 0, 0, 0, 0, 0, 87, 8, 0, 0, 128, 0, 0, 0, 108, 7, 0, 0, 124, 4, 0, 0, 68, 0, 0, 0, 16, 0, 0, 0, 40, 0, 0, 0, 44, 2, 0, -0, 44, 0, 0, 0, 68, 0, 0, 0, 3, 0, 0, 0, 29, 0, 0, 0, 17, 0, 0, 0, 28, 0, 0, 0, 22, 0, 0, 0, 12, 0, 0, 0, 6, 0, 0, 0, 19, 0, 0, 0, 20, 0, 0, 0, 21, 0, 0, 0, 13, 0, 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, -0, 11, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 7, 0, 0, 0, 18, 0, 0, 0, 23, 0, 0, 0, 24, 0, 0, 0, 25, 0, 0, 0, 27, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -690,16 +689,15 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, 0, 80, 101, 114, -68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, -101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, 79, 76, 79, 82, -0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, -0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, +0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 82, 68, 69, 70, 200, 0, 0, 0, 1, 0, 0, 0, 68, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 254, 255, 1, 1, 0, 0, 160, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 1, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 60, 0, 0, 0, 1, 0, 0, 0, 92, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 2, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, +0, 80, 101, 114, 68, 114, 97, 119, 95, 49, 95, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 171, 171, 3, 0, 3, 0, 4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, +83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 89, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 15, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 15, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 67, +79, 76, 79, 82, 0, 79, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 12, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, +0, 15, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 171, 171, 171, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs index 290ac6cfdf..5770edd353 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Direct3D12.Level_9_3.cs @@ -21,97 +21,95 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, -57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, -10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, -67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 72, 98, 250, 225, 204, 222, 93, 206, 84, 106, 176, 150, 83, 33, 56, 28, 0, 104, 9, 0, 0, 68, 88, 66, 67, 47, 49, 107, 184, 209, 56, 46, 22, 101, 148, 97, 181, 122, 116, 74, 52, 1, 0, 0, 0, 104, 9, 0, -0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 72, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, -68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, 86, 95, 84, 97, -114, 103, 101, 116, 0, 80, 83, 86, 48, 200, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 176, 7, 0, 0, 96, 0, 0, 0, 236, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 152, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 227, 1, 0, -0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, -35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, -255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, -64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 96, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, 133, 114, 192, 7, -122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, 3, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, -1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, 0, 0, 3, 0, -0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, 48, 7, 114, 160, -7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, 7, 115, 32, 7, -109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 158, 5, -8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, 0, 0, 96, 200, -51, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, 0, 40, 2, 58, -0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, 0, 0, 0, 160, -80, 3, 138, 161, 76, 3, 104, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, 162, 16, 10, 4, -0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, 232, 234, 228, 210, -220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, 104, 108, 204, 110, -110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, 172, 161, 167, 39, -41, 162, 9, 130, 50, 6, 19, 4, 5, 218, 16, 4, 19, 4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, 50, 186, 9, 130, -82, 6, 27, 150, 224, 12, 60, 52, 0, 131, 143, 32, 131, 224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, -77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, 13, 214, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, 67, 134, 231, 50, -135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, -221, 220, 148, 128, 13, 0, 0, 0, 0, 113, 32, 0, 0, 34, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, -47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 0, 13, 151, 239, 60, 126, 128, 52, 64, 132, 249, 197, 109, 91, 193, 51, 92, 190, 243, 248, 84, 3, 68, -152, 95, 220, 182, 25, 84, 195, 229, 59, 143, 47, 77, 78, 68, 160, 212, 244, 80, 147, 95, 220, 54, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, 216, 136, 65, 2, -128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, 1, 150, 145, 1, -25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, 32, 8, 6, 208, 26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, 98, 112, 0, 32, -8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, 32, 8, 6, 145, 28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, 14, 188, 97, 196, -192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, 136, 0, 1, 11, 4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, 246, 9, 18, 176, -111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, 98, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, -24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 51, 252, 223, 215, 16, 58, 169, 160, 66, 54, 166, 105, 117, 33, 208, 250, 0, 185, 9, 0, 0, 68, 88, 66, 67, 108, 34, 100, 210, 67, 201, 128, 38, 53, 94, 175, 77, 13, 75, 159, 20, 1, 0, 0, -0, 185, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, 125, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, -0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 134, 0, 0, 0, -3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, -15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, 95, 80, 111, 115, -105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 24, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 2, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, -0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, 0, 0, 1, 2, -68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 52, 7, 0, 0, 96, 0, 1, 0, 205, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, -0, 0, 28, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 196, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, -65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, -168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, -133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, 0, 0, 0, 115, -4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, 0, 224, 0, 0, -0, 128, 0, 0, 0, 128, 0, 0, 0, 32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, 128, 0, 0, 0, -160, 24, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, -122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, -160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, 0, 0, 50, 30, -152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 57, 74, 0, 0, 0, 24, 1, 32, 2, 0, 0, 128, 178, -43, 144, 2, 42, 176, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 0, 0, 121, 24, 0, 0, 107, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, 1, 81, 0, 36, -131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 184, 54, 12, 76, 19, 108, 8, 140, 13, -4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 3, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 178, 13, 11, 97, 93, 24, 135, -17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 13, 195, 230, 133, 193, 134, 37, 176, 46, 44, 211, 8, 45, 192, 128, 13, 11, 97, 93, 24, 167, 17, 29, 129, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, 135, 179, 97, 249, -202, 224, 50, 131, 172, 35, 186, 15, 3, 54, 12, 99, 64, 6, 103, 176, 97, 16, 3, 52, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, -110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 72, 13, 210, 0, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 142, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 164, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 64, 169, 67, 134, 231, 50, 135, 22, 70, -86, 38, 215, 244, 70, 86, 198, 54, 37, 104, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 158, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 2, 170, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, 27, 221, 220, 148, -64, 13, 0, 0, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, 227, 47, 14, 48, -136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, 249, 197, 109, 3, -0, 0, 97, 32, 0, 0, 133, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 89, 68, 81, 15, 52, 98, 144, 0, 32, 8, 6, 136, 38, 85, 213, 19, 141, 24, 36, 0, 8, 130, 1, 178, 77, 149, 21, 73, 35, 6, 9, 0, 130, 96, 128, 112, 148, 117, 69, 211, 136, 65, 2, 128, -32, 24, 32, 93, 117, 97, 17, 53, 98, 144, 0, 32, 8, 6, 136, 103, 97, 89, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 145, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, 38, 109, 213, 53, 98, 144, 0, 32, 8, 6, 72, 24, 100, 19, 87, 97, 35, 6, 9, 0, 130, 96, 128, 136, -129, 70, 117, 85, 54, 98, 144, 0, 32, 8, 6, 140, 24, 80, 151, 231, 77, 245, 113, 56, 98, 112, 0, 32, 8, 6, 206, 24, 80, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 101, 128, 65, 5, 99, 128, 35, 6, 7, 0, 130, 96, 224, 168, 193, 150, 4, 163, 9, -1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 197, 6, 30, 84, 160, 6, 56, 98, 112, 0, 32, 8, 6, 78, 28, 136, 1, 20, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 28, 144, 1, 84, 16, 7, 56, 98, 112, 0, 32, 8, 6, 14, 30, 164, 193, 21, 140, -38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 152, 21, 6, 18, 48, 72, 12, 36, 96, 202, 24, 72, 192, 8, 50, 144, 128, 109, 102, 32, 1, 11, 10, 8, 152, 133, 6, 18, 176, 192, 128, 128, 69, 106, 32, 1, 11, 14, 8, 24, 195, 6, 18, 176, 0, 129, 128, 145, 193, 27, 72, -192, 2, 4, 2, 246, 197, 129, 4, 44, 64, 32, 96, 218, 28, 72, 192, 2, 4, 2, 86, 213, 129, 4, 44, 64, 32, 96, 109, 128, 7, 18, 176, 0, 129, 128, 161, 129, 30, 72, 192, 2, 4, 2, 54, 6, 124, 32, 1, 11, 16, 8, 152, 231, 7, 18, 176, 0, 129, 192, 136, 65, 2, 128, 32, -24, 60, 184, 96, 10, 173, 96, 11, 177, 112, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 0, 11, 197, 136, 65, 2, 128, 32, 24, 60, 184, 96, 10, 173, 96, 11, 175, 48, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 224, 10, 193, 136, 65, 2, 128, 32, 24, 60, -184, 96, 10, 182, 96, 11, 177, 32, 10, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 216, 130, 45, 192, 66, 40, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 80, 11, 182, 16, 11, 124, 48, 98, 144, 0, 32, 8, 6, 15, 46, 152, 66, 45, 216, 2, 44, 236, 193, 136, 65, 2, 128, 32, 24, -60, 184, 96, 10, 181, 96, 11, 175, 160, 7, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 212, 130, 45, 184, 66, 30, 32, 0, 0, 0, 0, 0, 0, 0, 1, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, +110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, +153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, +224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, +11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 72, 98, 250, 225, 204, 222, 93, 206, 84, 106, 176, 150, 83, 33, 56, 28, 0, 104, 9, 0, 0, 68, 88, 66, 67, 47, 49, 107, 184, 209, 56, 46, 22, 101, 148, 97, 181, 122, 116, 74, 52, 1, 0, 0, +0, 104, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 166, 0, 0, 0, 224, 0, 0, 0, 176, 1, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 90, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, +0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, +67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, 50, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 83, +86, 95, 84, 97, 114, 103, 101, 116, 0, 80, 83, 86, 48, 200, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 2, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 68, 16, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 176, 7, 0, 0, 96, 0, 0, 0, 236, 1, 0, 0, 68, 88, 73, 76, 0, 1, 0, 0, 16, 0, 0, 0, 152, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, +0, 227, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, 114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, +72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, 255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, +99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 94, 0, 0, 0, 50, 34, 8, 20, 1, 132, 172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, +38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 96, 205, 17, 128, 193, 77, 210, 20, 81, 194, 228, 179, 0, 243, 44, 68, 196, 78, 192, 68, 160, 0, 0, 0, 0, 128, 2, 0, 0, 0, 102, 0, 148, 96, 0, 0, 0, 96, 166, 48, 24, 7, 118, 8, 135, 121, 152, 7, 55, 160, +133, 114, 192, 7, 122, 168, 7, 121, 40, 7, 57, 32, 5, 62, 176, 135, 114, 24, 7, 122, 120, 7, 121, 224, 3, 115, 96, 135, 119, 8, 7, 122, 96, 3, 48, 160, 3, 63, 240, 3, 20, 16, 0, 0, 0, 80, 1, 0, 0, 192, 28, 65, 48, 2, 80, 2, 4, 0, 0, 128, 57, 2, 164, 24, +3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 164, 0, 0, 0, 112, 207, 112, 249, 19, 246, 16, 146, 31, 2, 205, 176, 16, 40, 96, 0, 0, 0, 40, 70, 3, 0, 0, 0, 0, 0, 0, 128, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 192, 1, 0, 0, 192, 77, 195, 229, 79, 216, 67, 72, 254, 74, 72, 43, 49, 249, 197, 109, 163, 98, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0, 160, 48, 15, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 13, 0, 0, 0, 3, 0, +0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 133, 24, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 24, 0, 0, 0, 40, 195, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 64, 49, 16, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 40, 1, 0, 0, 96, 32, 0, 0, 0, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, 14, 109, 0, 15, 122, +48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, 230, 16, 7, 118, 160, +7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 79, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 67, 158, 5, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 14, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 32, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 68, 64, 0, 4, 0, 0, 0, 0, 0, 0, 0, 48, 228, 145, 128, 0, 8, 0, 0, 0, 0, 0, +0, 0, 96, 200, 51, 1, 1, 48, 0, 0, 0, 0, 0, 0, 0, 64, 22, 8, 0, 0, 0, 43, 0, 0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 18, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 17, 128, 18, 32, 3, 0, 0, 128, 25, 0, 2, 0, 0, +0, 40, 2, 58, 0, 0, 0, 24, 1, 32, 0, 0, 0, 128, 146, 40, 132, 25, 0, 82, 0, 0, 0, 24, 1, 40, 129, 34, 40, 3, 2, 0, 0, 0, 40, 57, 26, 0, 0, 0, 152, 1, 32, 0, 0, 0, 128, 194, 43, 164, 50, 162, 1, 0, 0, 128, 49, 130, 214, 156, 115, 246, 23, 8, +0, 0, 0, 160, 80, 3, 138, 161, 76, 3, 104, 0, 0, 0, 96, 140, 64, 103, 205, 185, 254, 198, 8, 64, 16, 4, 73, 48, 24, 35, 208, 89, 115, 238, 63, 2, 0, 0, 0, 40, 7, 26, 0, 0, 0, 24, 35, 0, 65, 16, 4, 193, 129, 0, 0, 0, 0, 74, 129, 20, 0, 0, 0, 74, +162, 16, 10, 4, 0, 121, 24, 0, 0, 112, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 0, 144, 9, 130, 112, 48, 162, 42, 195, 163, 171, 147, 75, 115, 59, 115, 153, 10, 107, 131, 99, 43, 147, 155, 32, 0, 201, 6, 36, 16, 134, 32, 32, 2, 96, 130, 96, 40, 148, 168, 202, 240, +232, 234, 228, 210, 220, 206, 92, 168, 202, 240, 232, 234, 228, 202, 96, 38, 8, 192, 50, 65, 56, 152, 9, 2, 208, 108, 16, 2, 101, 67, 18, 24, 71, 16, 16, 72, 178, 144, 12, 154, 202, 230, 194, 64, 236, 202, 228, 230, 210, 222, 220, 64, 100, 106, 92, 100, 92, 108, 64, 80, 206, 210, 232, 90, +104, 108, 204, 110, 110, 196, 102, 100, 96, 110, 82, 54, 4, 205, 6, 129, 8, 38, 8, 128, 179, 65, 32, 32, 10, 112, 115, 19, 4, 96, 219, 48, 72, 83, 176, 33, 96, 54, 4, 197, 6, 162, 2, 0, 107, 130, 64, 1, 27, 128, 13, 67, 144, 101, 27, 2, 109, 195, 64, 96, 27, 17, 170, 34, +172, 161, 167, 39, 41, 162, 9, 130, 50, 6, 19, 4, 5, 218, 16, 4, 19, 4, 69, 218, 176, 4, 157, 247, 129, 65, 24, 16, 97, 16, 124, 192, 134, 128, 152, 32, 40, 100, 176, 97, 33, 58, 239, 27, 131, 48, 32, 200, 128, 248, 128, 13, 130, 24, 148, 1, 147, 41, 171, 47, 170, 48, 185, 179, +50, 186, 9, 130, 82, 6, 27, 150, 224, 12, 60, 52, 0, 131, 143, 32, 131, 224, 3, 54, 4, 105, 176, 97, 48, 3, 53, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 10, 140, 13, 214, 224, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 154, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 167, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 0, 170, +67, 134, 231, 50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 152, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 172, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 130, 173, 14, 25, 158, 75, 153, 27, 157, 92, 30, +212, 91, 154, 27, 221, 220, 148, 128, 13, 0, 0, 0, 0, 113, 32, 0, 0, 34, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 41, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, +112, 249, 206, 227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 64, 195, 229, 59, 143, 47, 1, 204, 179, 16, 126, 113, 219, 70, 0, 13, 151, 239, 60, 126, 128, 52, 64, 132, 249, 197, 109, 91, 193, 51, 92, 190, 243, +248, 84, 3, 68, 152, 95, 220, 182, 25, 84, 195, 229, 59, 143, 47, 77, 78, 68, 160, 212, 244, 80, 147, 95, 220, 54, 0, 0, 0, 97, 32, 0, 0, 90, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 44, 101, 128, 121, 158, 117, 141, 24, 36, 0, 8, 130, 193, 98, 6, 217, 247, 89, +216, 136, 65, 2, 128, 32, 24, 44, 103, 160, 125, 96, 128, 101, 35, 6, 9, 0, 130, 96, 176, 160, 193, 6, 6, 97, 128, 105, 35, 6, 9, 0, 130, 96, 176, 164, 1, 23, 6, 98, 128, 109, 35, 6, 9, 0, 130, 96, 176, 168, 65, 39, 6, 99, 128, 113, 35, 6, 9, 0, 130, 96, 224, 168, +1, 150, 145, 1, 25, 128, 193, 136, 65, 2, 128, 32, 24, 56, 107, 144, 117, 101, 80, 6, 97, 48, 98, 240, 0, 32, 8, 6, 208, 26, 96, 129, 128, 28, 89, 246, 125, 95, 54, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 48, 98, 112, 0, 32, 8, 6, 209, 27, 112, 196, 48, +98, 112, 0, 32, 8, 6, 17, 28, 112, 5, 49, 98, 112, 0, 32, 8, 6, 81, 28, 120, 1, 49, 98, 112, 0, 32, 8, 6, 145, 28, 120, 67, 96, 129, 7, 129, 17, 3, 3, 0, 65, 48, 144, 230, 192, 11, 70, 12, 12, 0, 4, 193, 64, 162, 3, 47, 24, 49, 48, 0, 16, 4, 3, 169, +14, 188, 97, 196, 192, 0, 64, 16, 12, 36, 59, 0, 131, 192, 130, 1, 2, 22, 128, 129, 4, 76, 248, 36, 96, 136, 0, 1, 11, 4, 10, 140, 24, 24, 0, 8, 130, 129, 196, 7, 97, 16, 88, 24, 4, 18, 176, 160, 12, 32, 96, 67, 32, 1, 35, 2, 9, 88, 16, 72, 192, 190, 64, 2, +246, 9, 18, 176, 111, 144, 128, 125, 132, 4, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 216, 3, 98, 196, 32, 1, 64, 16, 12, 166, 82, 72, 131, 81, 24, 5, 61, 24, 70, 12, 18, 0, 4, 193, 96, 42, 133, 52, 24, 133, 81, 200, 3, 97, 196, 32, 1, 64, 16, 12, 166, +82, 72, 131, 81, 24, 5, 60, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 51, 252, 223, 215, 16, 58, 169, 160, 66, 54, 166, 105, 117, 33, 208, 250, 0, 185, 9, 0, 0, 68, 88, 66, 67, 108, 34, 100, 210, 67, 201, 128, 38, 53, 94, 175, 77, 13, 75, 159, +20, 1, 0, 0, 0, 185, 9, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 68, 0, 0, 0, 207, 0, 0, 0, 93, 1, 0, 0, 125, 2, 0, 0, 83, 70, 73, 48, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 83, 71, 49, 131, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, +0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 122, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 79, 83, 71, 49, +134, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, +1, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 15, 240, 0, 0, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 83, 86, +95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 80, 83, 86, 48, 24, 1, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 1, 0, 0, 0, 16, 0, +0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, 79, 82, 68, 0, 84, 69, 88, 67, 79, +79, 82, 68, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 0, 0, 0, 19, 0, 0, 0, 2, 0, +0, 0, 1, 2, 68, 0, 3, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 1, 0, 66, 0, 3, 2, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 1, 1, 68, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 68, 3, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 88, 73, 76, 52, 7, 0, 0, 96, 0, 1, 0, 205, 1, 0, 0, 68, 88, 73, 76, 0, 1, +0, 0, 16, 0, 0, 0, 28, 7, 0, 0, 66, 67, 192, 222, 33, 12, 0, 0, 196, 1, 0, 0, 11, 130, 32, 0, 2, 0, 0, 0, 20, 0, 0, 0, 7, 129, 35, 145, 65, 200, 4, 73, 6, 16, 50, 57, 146, 1, 132, 12, 37, 5, 8, 25, 30, 4, 139, 98, 128, 64, 161, 72, 64, 72, +114, 65, 136, 64, 65, 200, 80, 224, 32, 96, 44, 41, 200, 8, 20, 68, 36, 72, 10, 144, 33, 35, 196, 82, 128, 12, 25, 33, 114, 36, 7, 200, 8, 20, 66, 12, 21, 20, 21, 200, 24, 62, 88, 174, 72, 16, 40, 140, 12, 0, 81, 24, 0, 0, 9, 0, 0, 0, 27, 140, 224, 255, 255, 255, +255, 7, 64, 2, 168, 13, 134, 240, 255, 255, 255, 255, 3, 32, 1, 213, 6, 99, 248, 255, 255, 255, 255, 1, 144, 0, 9, 0, 0, 0, 73, 24, 0, 0, 3, 0, 0, 0, 19, 130, 96, 66, 32, 76, 8, 6, 0, 0, 0, 0, 137, 32, 0, 0, 59, 0, 0, 0, 50, 34, 8, 20, 1, 132, +172, 144, 96, 2, 133, 144, 18, 18, 76, 160, 144, 113, 194, 80, 72, 10, 9, 38, 80, 200, 184, 64, 72, 160, 144, 145, 129, 144, 64, 49, 65, 32, 205, 0, 36, 4, 0, 0, 0, 192, 29, 41, 17, 117, 17, 96, 161, 32, 0, 0, 0, 128, 4, 0, 0, 0, 230, 8, 192, 96, 4, 160, 4, 5, +0, 0, 0, 115, 4, 72, 49, 0, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 8, 0, 0, 0, 230, 8, 2, 58, 0, 0, 0, 184, 103, 184, 252, 9, 123, 8, 201, 15, 129, 102, 88, 8, 20, 40, 0, 0, 0, 20, 99, 1, 0, 0, 128, 0, 0, +0, 224, 0, 0, 0, 128, 0, 0, 0, 128, 0, 0, 0, 32, 1, 0, 0, 224, 168, 225, 242, 39, 236, 33, 36, 159, 219, 168, 98, 37, 38, 191, 184, 109, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 162, 1, 0, 0, 128, 0, 0, 0, 96, 1, 0, 0, +128, 0, 0, 0, 160, 24, 5, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 48, 16, 0, 0, 19, 20, 114, 192, 135, 116, 96, 135, 54, 104, 135, 121, 104, 3, 114, 192, 135, 13, 175, 80, 14, 109, 208, 14, 122, 80, +14, 109, 0, 15, 122, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 113, 160, 7, 115, 32, 7, 109, 144, 14, 120, 160, 7, 115, 32, 7, 109, 144, 14, 113, 96, 7, 122, 48, 7, 114, 208, 6, 233, 48, 7, 114, 160, 7, 115, 32, 7, 109, 144, 14, 118, 64, 7, 122, 96, 7, 116, 208, 6, +230, 16, 7, 118, 160, 7, 115, 32, 7, 109, 96, 14, 115, 32, 7, 122, 48, 7, 114, 208, 6, 230, 96, 7, 116, 160, 7, 118, 64, 7, 109, 224, 14, 120, 160, 7, 113, 96, 7, 122, 48, 7, 114, 160, 7, 118, 64, 7, 58, 15, 36, 144, 33, 35, 69, 66, 128, 33, 143, 1, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 67, 30, 4, 8, 128, 0, 0, 0, 0, 0, 0, 0, 0, 134, 60, 12, 16, 0, 2, 0, 0, 0, 0, 0, 0, 0, 12, 121, 28, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 24, 242, 60, 64, 0, 12, 0, 0, 0, 0, 0, 0, 0, 144, 5, 2, 0, 21, 0, +0, 0, 50, 30, 152, 20, 25, 17, 76, 144, 140, 9, 38, 71, 198, 4, 67, 26, 0, 0, 0, 152, 1, 32, 2, 0, 0, 128, 17, 128, 18, 40, 192, 128, 66, 152, 1, 160, 3, 0, 0, 128, 17, 128, 18, 40, 130, 50, 32, 2, 0, 0, 128, 34, 40, 57, 74, 0, 0, 0, 24, 1, 32, 2, +0, 0, 128, 178, 43, 144, 2, 42, 176, 82, 40, 6, 58, 0, 0, 0, 40, 137, 66, 0, 0, 0, 121, 24, 0, 0, 107, 0, 0, 0, 26, 3, 76, 144, 70, 2, 19, 52, 65, 32, 140, 9, 194, 80, 240, 128, 42, 147, 35, 146, 11, 187, 155, 32, 16, 199, 4, 129, 64, 54, 32, 129, 48, 4, +1, 81, 0, 36, 131, 166, 178, 185, 48, 16, 187, 50, 185, 185, 180, 55, 55, 16, 153, 26, 23, 25, 23, 27, 16, 148, 179, 52, 186, 22, 26, 27, 179, 155, 27, 177, 25, 25, 152, 155, 148, 13, 193, 177, 65, 32, 130, 9, 2, 145, 108, 16, 8, 133, 130, 221, 220, 4, 129, 184, 54, 12, 76, 19, +108, 8, 140, 13, 4, 0, 60, 192, 4, 1, 2, 54, 0, 27, 134, 64, 146, 54, 4, 211, 134, 129, 136, 40, 34, 84, 69, 88, 67, 79, 79, 82, 68, 19, 132, 3, 155, 32, 28, 203, 134, 32, 152, 32, 28, 205, 134, 37, 176, 46, 44, 195, 8, 45, 192, 128, 13, 1, 49, 65, 56, 178, 13, 11, +97, 93, 24, 135, 17, 29, 129, 1, 19, 4, 226, 217, 16, 124, 27, 150, 207, 186, 48, 48, 192, 136, 238, 195, 128, 13, 195, 230, 133, 193, 134, 37, 176, 46, 44, 211, 8, 45, 192, 128, 13, 11, 97, 93, 24, 167, 17, 29, 129, 1, 92, 166, 172, 190, 160, 222, 230, 210, 232, 210, 222, 220, 38, 8, +135, 179, 97, 249, 202, 224, 50, 131, 172, 35, 186, 15, 3, 54, 12, 99, 64, 6, 103, 176, 97, 16, 3, 52, 0, 40, 7, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, +83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 27, 138, 72, 13, 210, 0, 2, 170, 176, 177, 217, 181, 185, 164, 145, 149, 185, 209, 77, 9, 142, 42, 100, 120, 46, 118, 101, 114, 115, 105, 111, 110, 83, 2, 164, 9, 25, 158, 139, 93, 24, 155, 93, 153, 220, 148, 64, 169, 67, 134, 231, +50, 135, 22, 70, 86, 38, 215, 244, 70, 86, 198, 54, 37, 104, 202, 144, 225, 185, 200, 149, 205, 189, 213, 201, 141, 149, 205, 77, 9, 158, 74, 100, 120, 46, 116, 121, 112, 101, 65, 110, 110, 111, 116, 97, 116, 105, 111, 110, 115, 83, 2, 170, 14, 25, 158, 75, 153, 27, 157, 92, 30, 212, 91, 154, +27, 221, 220, 148, 64, 13, 0, 0, 0, 0, 113, 32, 0, 0, 29, 0, 0, 0, 6, 32, 7, 236, 19, 33, 19, 193, 34, 70, 67, 12, 29, 34, 77, 64, 35, 16, 31, 66, 44, 195, 231, 52, 19, 123, 0, 3, 17, 249, 47, 107, 2, 72, 243, 195, 17, 240, 60, 68, 100, 1, 211, 112, 249, 206, +227, 47, 14, 48, 136, 205, 67, 77, 126, 113, 219, 38, 32, 13, 151, 239, 60, 190, 16, 17, 192, 68, 132, 64, 51, 44, 132, 13, 108, 195, 229, 59, 143, 47, 4, 84, 81, 16, 81, 233, 0, 67, 73, 24, 128, 128, 249, 197, 109, 27, 65, 53, 92, 190, 243, 248, 210, 228, 68, 4, 74, 77, 15, 53, +249, 197, 109, 3, 0, 0, 97, 32, 0, 0, 133, 0, 0, 0, 19, 4, 193, 136, 65, 2, 128, 32, 24, 32, 89, 68, 81, 15, 52, 98, 144, 0, 32, 8, 6, 136, 38, 85, 213, 19, 141, 24, 36, 0, 8, 130, 1, 178, 77, 149, 21, 73, 35, 6, 9, 0, 130, 96, 128, 112, 148, 117, 69, 211, +136, 65, 2, 128, 32, 24, 32, 93, 117, 97, 17, 53, 98, 144, 0, 32, 8, 6, 136, 103, 97, 89, 84, 141, 24, 36, 0, 8, 130, 1, 242, 93, 145, 86, 89, 35, 6, 9, 0, 130, 96, 128, 128, 1, 38, 109, 213, 53, 98, 144, 0, 32, 8, 6, 72, 24, 100, 19, 87, 97, 35, 6, 9, 0, +130, 96, 128, 136, 129, 70, 117, 85, 54, 98, 144, 0, 32, 8, 6, 140, 24, 80, 151, 231, 77, 245, 113, 56, 98, 112, 0, 32, 8, 6, 206, 24, 80, 66, 48, 154, 16, 0, 163, 9, 66, 48, 154, 48, 8, 163, 9, 196, 80, 101, 128, 65, 5, 99, 128, 35, 6, 7, 0, 130, 96, 224, 168, 193, +150, 4, 163, 9, 1, 48, 154, 32, 4, 163, 9, 131, 48, 154, 64, 12, 197, 6, 30, 84, 160, 6, 56, 98, 112, 0, 32, 8, 6, 78, 28, 136, 1, 20, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 212, 28, 144, 1, 84, 16, 7, 56, 98, 112, 0, 32, 8, 6, 14, 30, +164, 193, 21, 140, 38, 4, 192, 104, 130, 16, 140, 38, 12, 194, 104, 2, 49, 152, 21, 6, 18, 48, 72, 12, 36, 96, 202, 24, 72, 192, 8, 50, 144, 128, 109, 102, 32, 1, 11, 10, 8, 152, 133, 6, 18, 176, 192, 128, 128, 69, 106, 32, 1, 11, 14, 8, 24, 195, 6, 18, 176, 0, 129, 128, +145, 193, 27, 72, 192, 2, 4, 2, 246, 197, 129, 4, 44, 64, 32, 96, 218, 28, 72, 192, 2, 4, 2, 86, 213, 129, 4, 44, 64, 32, 96, 109, 128, 7, 18, 176, 0, 129, 128, 161, 129, 30, 72, 192, 2, 4, 2, 54, 6, 124, 32, 1, 11, 16, 8, 152, 231, 7, 18, 176, 0, 129, 192, 136, +65, 2, 128, 32, 24, 60, 184, 96, 10, 173, 96, 11, 177, 112, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 0, 11, 197, 136, 65, 2, 128, 32, 24, 60, 184, 96, 10, 173, 96, 11, 175, 48, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 208, 10, 182, 224, 10, 193, 136, 65, 2, +128, 32, 24, 60, 184, 96, 10, 182, 96, 11, 177, 32, 10, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 216, 130, 45, 192, 66, 40, 140, 24, 36, 0, 8, 130, 193, 131, 11, 166, 80, 11, 182, 16, 11, 124, 48, 98, 144, 0, 32, 8, 6, 15, 46, 152, 66, 45, 216, 2, 44, 236, 193, 136, 65, +2, 128, 32, 24, 60, 184, 96, 10, 181, 96, 11, 175, 160, 7, 35, 6, 9, 0, 130, 96, 240, 224, 130, 41, 212, 130, 45, 184, 66, 30, 32, 0, 0, 0, 0, 0, 0, 0, 1, }; } } diff --git a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs index 0847185093..4ad58aeb2a 100644 --- a/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs +++ b/sources/engine/Stride.Graphics/Shaders093.Bytecodes/SpriteSignedDistanceFieldFontShader.spriteSignedDistanceFieldFontBytecode.Vulkan.Level_9_3.cs @@ -21,625 +21,623 @@ internal partial class SpriteSignedDistanceFieldFontShader 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 7, 71, 108, 111, 98, 97, 108, 115, 1, 0, 2, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, -0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, -21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, 127, 0, 1, 0, 0, 0, 0, 0, 17, 84, 101, 120, 116, -117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 21, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 255, 255, 255, 127, -127, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 18, 84, 101, -120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 10, 0, 0, -0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, -46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 8, -84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, -105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, 153, 167, 56, 93, -57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, 224, 65, 139, 24, -10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, 11, 245, 228, 123, -67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 46, 19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, -0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, 86, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, 0, 104, 1, 0, -0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, 110, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, -0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, +0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 9, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, +0, 18, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 84, 101, 120, 116, 117, 114, 101, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 8, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 17, 84, 101, 120, 116, 117, 114, 105, 110, 103, 95, 83, 97, 109, 112, 108, 101, 114, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, 80, 101, 114, 68, 114, 97, +119, 10, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 7, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, +0, 1, 0, 1, 0, 0, 0, 0, 0, 7, 80, 101, 114, 68, 114, 97, 119, 64, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 1, 0, 26, 83, 112, 114, 105, 116, 101, +66, 97, 115, 101, 46, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 15, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 0, 0, 0, 64, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, +0, 0, 0, 8, 84, 69, 88, 67, 79, 79, 82, 68, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 67, 79, 76, 79, 82, 0, 0, 0, 0, 0, 6, 0, 0, 0, 35, 83, 112, 114, 105, 116, 101, 83, 105, 103, +110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 1, 93, 72, 168, 105, 216, 89, 33, 246, 96, 57, 136, 221, 62, 180, 54, 83, 16, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 1, 183, 5, 182, +153, 167, 56, 93, 57, 199, 222, 82, 168, 209, 63, 57, 120, 10, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 1, 78, 203, 205, 37, 40, 182, 74, 121, 238, 190, 129, 168, 99, 137, 45, 140, 9, 84, 101, 120, 116, 117, 114, 105, 110, 103, 1, 145, 239, 48, 17, 193, 7, 28, 46, 93, 65, 205, 62, +224, 65, 139, 24, 10, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 1, 90, 122, 169, 223, 213, 181, 199, 97, 48, 83, 244, 246, 108, 121, 202, 13, 23, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 1, 37, 1, 181, 194, 176, 158, 66, +11, 245, 228, 123, 67, 85, 255, 23, 129, 0, 2, 0, 0, 0, 0, 5, 0, 0, 0, 1, 46, 19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, +0, 1, 0, 0, 0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, 86, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, +0, 104, 1, 0, 0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, 110, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, +0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, +117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, +101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, +102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, +100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, +97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, +10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, +82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, +111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, +32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, +47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, +111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, +32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, +52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, +116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, +101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, +101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, +32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, +101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, +115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, +0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, +114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, +108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, +117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, +99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, +99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, +97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, +32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, +13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, +97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, +97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, +115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, +111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, +109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, +105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, +101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, +97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, +59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, +117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, +84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, +101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, +120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, +32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, +98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, +32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, +103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, +32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, +109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, +78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, +100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, +112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, +61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, +115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, +10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, +101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, +82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, +101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, +77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, +97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, +32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, +116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, +101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, +83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, +112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, +32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, +116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, +54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, +101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, +0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, -109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, -97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, -115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, -32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, -73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, -102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, -70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, -102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, -84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, -84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, -108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, -32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, -13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, -102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, -86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, -83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, -100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, -0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, -104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, -110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, -32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, -111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, -104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, -86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, -68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, -13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, -115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, -110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, -100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, -46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, -105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, -10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, -121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, -84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, -117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, -84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, -101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, -120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, -32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, -116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, -116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, -101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, -108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, -114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, -59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, -115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, -101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, -97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, -117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, -32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, -97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, -67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, -116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, -100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, -77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, -97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, -97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, -109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, -101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, -83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, -112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, -32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, -84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, -110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, -0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, -101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, -112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, -73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, -32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, -32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, -47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, -32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, -97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, -59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, -97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, -13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, -109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, -111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, -115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, -98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, -100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, -116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, -114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, -111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, -40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, -105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, -119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, -102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, -32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, -32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, -32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, -50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, -101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, -97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, -110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, -100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, -111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, -116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, -32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, -97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, -101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, -68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, -105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, -13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, -99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, -44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, -32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 26, 0, 39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, -115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, -0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, -100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, -32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, -104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, -109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, -83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, -67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, -100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, -103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, 0, 3, 0, 0, -0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, -118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, -116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, -102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, -0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, -0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, -97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, -0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, -105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, -119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, 0, 83, 105, 103, -110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, -116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 185, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, -0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, -0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, -0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, -0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, -0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, 0, 115, 105, 103, -68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, -0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, 0, 102, 108, 111, -97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, -112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 254, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, -110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, -112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, -50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, -0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 1, 0, -0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 84, 1, 0, -0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, -0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, -80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, -0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, -83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, -116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, 0, 105, 110, 95, -86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 105, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 0, 0, 0, -0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, -0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, -0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, -116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, 0, 3, 0, 0, -0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, -0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 118, 1, 0, -0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, 0, 3, 22, 0, -0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, -0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 101, 1, 0, -0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 104, 1, 0, -0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 104, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, -0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, -0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, -0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, -0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, -0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, -0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, -0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, -0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 185, 0, 0, -0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 184, 0, 0, 0, 5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, 0, 202, 0, 0, -0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, -0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, -0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, -0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, -0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 84, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, -0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, 0, 43, 0, 4, -0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, -0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, -0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, -0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, -0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, -0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, -0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 57, 0, 4, -0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, -0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, 0, 90, 1, 0, -0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, -0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 55, 0, 3, -0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, -0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 188, 0, 0, -0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, -0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 204, 0, 0, -0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, -0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, -0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 61, 0, 4, -0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, -0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, 0, 238, 0, 0, -0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 241, 0, 0, -0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 243, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, -0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, -0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 186, 0, 5, -0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 36, 0, 0, -0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, -0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, -0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, 0, 209, 0, 4, -0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, 0, 19, 1, 0, -0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 21, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 225, 0, 0, -0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, 13, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, 0, 8, 0, 4, -0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, 0, 80, 0, 7, -0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 204, 0, 0, -0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 12, 0, 8, -0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, -0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, 37, 1, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 46, 1, 0, -0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 53, 1, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, 0, 7, 0, 0, -0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, 0, 65, 0, 5, -0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, -0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, 0, 72, 1, 0, -0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, -0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, 0, 62, 0, 3, -0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, -0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, -0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, -0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, 0, 57, 0, 4, -0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, 0, 65, 0, 5, -0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, -0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 125, 1, 0, 0, 62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, 0, 0, 1, 46, -19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, 46, 115, 116, 100, -46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, 86, 1, 0, 0, -40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, 0, 104, 1, 0, 0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, 110, 1, 0, 0, -116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, -32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, -111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, -119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, -101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, -13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, -32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, -97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, -65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, 69, 86, 69, 76, -95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, 101, 32, 111, 116, -104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, 10, 32, 32, 32, -32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, 32, 73, 115, 70, -114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, 117, 116, 112, 117, -116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, -116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, -103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, -111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, -114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, 83, 86, 95, 84, -97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, 10, 32, 32, 32, -32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, -116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, 32, 83, 86, 95, -68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 59, 32, 47, -47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, -32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, -108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, -68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, -47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 47, 47, 32, 67, -111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, -110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, -116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, -99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, -114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, -97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, -110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, 32, 115, 104, 97, -100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, 67, 58, 47, 100, -101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, 100, 115, 108, 0, -3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, -115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, -105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, -116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, -116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, -116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 13, 10, 32, -32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, 83, 105, 122, 101, -59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, 101, 120, 101, 108, -83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 50, 84, -101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, -114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, -101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, -102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, 13, 10, 32, 32, -32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 57, 59, -13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, -99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, -114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, 115, 108, 111, 116, -115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, -68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, -101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 59, -13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, -32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 83, 97, 109, 112, -108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, -77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, -86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 67, 108, -97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, 79, 78, 95, 77, -73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, -114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, -10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, -114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 82, 101, -112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, -115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, 32, 61, 32, 49, -54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, -32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, -32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, -82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, -32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, -97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, 97, 109, 112, 108, -101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, -109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, -101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, 32, 32, 32, 32, -115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 53, 59, 13, 10, -32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, -55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, -112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, -97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, 32, 32, 32, 115, -116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, -116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, 32, 58, 32, 84, -69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, -104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, -32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, -32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, -105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, -104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, -97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, -73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, -32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, -97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, -101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, -117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, -111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, -105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, -120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, -105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, -179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, -111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, -67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, -101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, -111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, -123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, -114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, -97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, -108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, -98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, -111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, -13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, -32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, -32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, -109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, -47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, -10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, -108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, -101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, -42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, -105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, -32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, -102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, -32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, -32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, -116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, -98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, -116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, -13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, -105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 26, 0, -39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, -105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, +109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, +32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, +111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, 79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, +101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, 116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, +102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, 101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, +115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, +32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, +105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, +101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, +100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, +116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, +110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, +41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, +32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, +104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, +101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, +32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, 111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, +32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, 105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, +104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, 115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, +114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, +108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, +108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, +105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, 102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, +114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, +44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, +32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, 32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, +101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, 53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, +104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, +105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, +108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, +103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, +111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, +40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, +13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, 116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, +105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, +32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, +32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, +41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, +114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, +48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, +114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 7, 0, 26, 0, 39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, +112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, +0, 0, 0, 0, 0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, +115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, +117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, +101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, +102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, +114, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, +97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, +101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, +97, 100, 105, 110, 103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, +0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, +95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, +67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, +95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, +0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, +97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, +110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, +0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, +0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, +114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, +0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, +46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 185, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, +0, 5, 0, 3, 0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, +0, 5, 0, 5, 0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, +0, 5, 0, 4, 0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, 212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, +0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, +0, 5, 0, 6, 0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, +0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, +0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, 253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, +0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, +100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 254, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, +108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, 5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, +95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, 76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, +108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, 105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, +0, 80, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, 82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, +0, 82, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, +0, 84, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, 84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, +0, 6, 0, 5, 0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, +101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, +112, 101, 114, 0, 0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, +95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, +102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, +0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 105, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, +0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, +0, 107, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, 107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, +100, 0, 0, 0, 0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, +80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, +0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, +0, 5, 0, 15, 0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, +0, 118, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, +0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, +0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, +0, 101, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, +0, 104, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 104, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, +79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, +0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, +0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, +0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, +0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, +0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, +0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, +0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, +0, 185, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 184, 0, 0, 0, 5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, +0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, +63, 43, 0, 4, 0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, 138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, +63, 43, 0, 4, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, +63, 32, 0, 4, 0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, +0, 30, 0, 3, 0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 84, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, +0, 43, 0, 4, 0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, +0, 4, 0, 0, 0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, +0, 43, 0, 4, 0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, +0, 59, 0, 4, 0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, +0, 59, 0, 4, 0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, +0, 59, 0, 4, 0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, +0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, +0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, +0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, +0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, +0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, +0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, +0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, +0, 55, 0, 3, 0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, +0, 194, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, +0, 188, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, +0, 199, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, +0, 204, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, +0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, +0, 212, 0, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, +0, 185, 0, 0, 0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, +0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, 224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, +0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, 234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, +0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, +0, 238, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, +0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 243, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, +0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, +0, 248, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, +0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, +0, 186, 0, 5, 0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, 247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, +0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, +0, 5, 0, 0, 0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, 62, 0, 3, 0, 3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, +0, 5, 0, 0, 0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, +0, 209, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, 136, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, +0, 19, 1, 0, 0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 21, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, +0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, 13, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, +0, 8, 0, 4, 0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, +0, 80, 0, 7, 0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, +0, 204, 0, 0, 0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, 248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, +0, 0, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, +0, 12, 0, 8, 0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, +0, 4, 0, 0, 0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, 37, 1, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, +0, 46, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 53, 1, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, +0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, +0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, +0, 69, 1, 0, 0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, +0, 72, 1, 0, 0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, +0, 61, 0, 4, 0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, 62, 0, 3, 0, 89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, +0, 62, 0, 3, 0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, +0, 62, 0, 3, 0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, +0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, 100, 1, 0, 0, 62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, +0, 103, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, +0, 57, 0, 4, 0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, +0, 65, 0, 5, 0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, +0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 125, 1, 0, 0, 62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 1, 0, +0, 0, 1, 46, 19, 248, 14, 233, 173, 226, 212, 178, 15, 42, 136, 235, 143, 43, 151, 0, 128, 75, 0, 0, 3, 2, 35, 7, 0, 4, 1, 0, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 0, 0, 17, 0, 2, 0, 1, 0, 0, 0, 11, 0, 6, 0, 193, 0, 0, 0, 71, 76, 83, 76, +46, 115, 116, 100, 46, 52, 53, 48, 0, 0, 0, 0, 14, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 15, 0, 13, 0, 4, 0, 0, 0, 87, 1, 0, 0, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 78, 1, 0, 0, 80, 1, 0, 0, 76, 1, 0, 0, +86, 1, 0, 0, 40, 0, 0, 0, 87, 0, 0, 0, 15, 0, 15, 0, 0, 0, 0, 0, 111, 1, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 100, 1, 0, 0, 103, 1, 0, 0, 104, 1, 0, 0, 99, 1, 0, 0, 101, 1, 0, 0, 105, 1, 0, 0, +110, 1, 0, 0, 116, 0, 0, 0, 16, 0, 3, 0, 87, 1, 0, 0, 7, 0, 0, 0, 7, 0, 21, 0, 2, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 46, 115, 100, 115, 108, 0, 0, 3, 0, 142, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, +105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, +105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, +101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, +105, 111, 110, 46, 13, 10, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 111, 114, 32, 97, 32, 115, 104, 97, 100, 101, 114, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, +10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 83, 86, 95, 80, 111, 115, 105, 116, 105, 111, 110, 59, 13, 10, 13, 10, 35, 105, 102, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, +73, 67, 83, 95, 65, 80, 73, 95, 68, 73, 82, 69, 67, 84, 51, 68, 32, 38, 38, 32, 83, 84, 82, 73, 68, 69, 95, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 32, 60, 32, 71, 82, 65, 80, 72, 73, 67, 83, 95, 80, 82, 79, 70, 73, 76, 69, 95, 76, +69, 86, 69, 76, 95, 49, 48, 95, 48, 13, 10, 32, 32, 32, 32, 47, 47, 32, 80, 111, 115, 105, 116, 105, 118, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 44, 32, 110, 101, 103, 97, 116, 105, 118, +101, 32, 111, 116, 104, 101, 114, 119, 105, 115, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 86, 70, 65, 67, 69, 59, 13, 10, 35, 101, 108, 115, 101, 13, +10, 32, 32, 32, 32, 47, 47, 32, 84, 114, 117, 101, 32, 105, 102, 32, 116, 104, 105, 115, 32, 102, 97, 99, 101, 32, 105, 115, 32, 97, 32, 102, 114, 111, 110, 116, 32, 102, 97, 99, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 98, 111, 111, 108, +32, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 32, 58, 32, 83, 86, 95, 73, 115, 70, 114, 111, 110, 116, 70, 97, 99, 101, 59, 13, 10, 35, 101, 110, 100, 105, 102, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 67, 79, 76, 79, 82, 32, 111, +117, 116, 112, 117, 116, 115, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 58, 32, 83, 86, 95, 84, +97, 114, 103, 101, 116, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 49, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 49, 59, 13, 10, 32, 32, 32, +32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 50, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, +109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 51, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, +111, 114, 84, 97, 114, 103, 101, 116, 52, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 53, 32, 58, 32, +83, 86, 95, 84, 97, 114, 103, 101, 116, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 54, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 54, 59, 13, +10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 55, 32, 58, 32, 83, 86, 95, 84, 97, 114, 103, 101, 116, 55, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 68, 69, 80, 84, 72, 32, 111, 117, 116, 112, 117, 116, 32, 102, 111, 114, 32, 80, 83, 32, 115, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 32, 58, +32, 83, 86, 95, 68, 101, 112, 116, 104, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, 114, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 71, 114, 101, 97, 116, 101, +114, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 32, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, +113, 117, 97, 108, 32, 58, 32, 83, 86, 95, 68, 101, 112, 116, 104, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 32, 47, 47, 32, 83, 112, 101, 99, 105, 97, 108, 32, 111, 117, 116, 112, 117, 116, 32, 97, 102, 116, 101, 114, 32, 80, 83, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, +101, 102, 97, 117, 108, 116, 32, 73, 110, 115, 116, 97, 110, 99, 101, 73, 100, 32, 102, 111, 114, 32, 86, 83, 47, 71, 83, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 117, 105, 110, 116, 32, 73, 110, 115, 116, 97, +110, 99, 101, 73, 68, 32, 58, 32, 83, 86, 95, 73, 110, 115, 116, 97, 110, 99, 101, 73, 68, 59, 13, 10, 125, 59, 13, 10, 0, 0, 0, 0, 7, 0, 20, 0, 26, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, +103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, +47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, +116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, +46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, +84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, +105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 47, 47, 32, 66, 97, 115, 101, 32, 115, 104, 97, 100, 101, 114, 32, 102, 111, 114, 32, 97, 108, 108, 32, 116, 104, 101, 32, 103, 114, 97, 112, 104, 105, 99, 115, 32, 115, 104, 97, 100, 101, 114, 115, 13, 10, 115, 104, 97, 100, 101, +114, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 83, 116, 114, 101, 97, 109, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 86, 101, 114, 116, 101, 120, 32, 115, 104, 97, 100, 101, 114, +32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 99, 108, 97, 114, 101, 32, 80, 105, 120, 101, 108, +32, 115, 104, 97, 100, 101, 114, 32, 109, 97, 105, 110, 32, 109, 101, 116, 104, 111, 100, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 32, 123, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 19, 0, 35, 0, 0, 0, +67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 115, +100, 115, 108, 0, 3, 0, 148, 3, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, +117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, +32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, +114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, +111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, +102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 115, 108, 111, 116, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, +108, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 48, 84, 101, 120, 101, 108, +83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 49, 84, +101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, +114, 101, 50, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, +101, 120, 116, 117, 114, 101, 51, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, +116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 52, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 53, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, +97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 54, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 55, 59, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 55, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, 114, 101, 56, 59, +13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 56, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 50, 68, 32, 84, 101, 120, 116, 117, +114, 101, 57, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 116, 117, 114, 101, 57, 84, 101, 120, 101, 108, 83, 105, 122, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, +117, 114, 101, 32, 99, 117, 98, 101, 32, 115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, +101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 50, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 32, 84, 101, 120, 116, 117, 114, 101, 67, 117, 98, 101, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 116, 101, 120, 116, 117, 114, 101, 32, 51, 68, 32, +115, 108, 111, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, +117, 114, 101, 51, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 84, 101, 120, 116, 117, 114, 101, 51, 68, 32, 84, 101, +120, 116, 117, 114, 101, 51, 68, 51, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 115, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, +108, 101, 114, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, +101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, +83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, 97, 114, 66, 111, 114, 100, 101, 114, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, +114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, +114, 101, 115, 115, 86, 32, 61, 32, 66, 111, 114, 100, 101, 114, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 83, 116, 97, 116, 101, 32, 76, 105, 110, 101, +97, 114, 67, 108, 97, 109, 112, 67, 111, 109, 112, 97, 114, 101, 76, 101, 115, 115, 69, 113, 117, 97, 108, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 67, 79, 77, 80, 65, 82, 73, 83, +79, 78, 95, 77, 73, 78, 95, 77, 65, 71, 95, 76, 73, 78, 69, 65, 82, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, +32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 67, 108, 97, 109, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 70, 117, 110, 99, 32, 61, 32, 76, 101, 115, 115, 69, 113, 117, 97, 108, 59, 13, 10, 13, 10, 32, 32, 32, 32, 125, +59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, +105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 65, 110, 105, 115, 111, 116, 114, 111, 112, +105, 99, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 65, 78, 73, 83, 79, 84, 82, 79, 80, 73, 67, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, +100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 77, 97, 120, 65, 110, 105, 115, 111, 116, 114, 111, 112, 121, +32, 61, 32, 49, 54, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 80, 111, 105, 110, 116, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, +32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 80, 79, 73, 78, 84, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, +59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 76, 105, +110, 101, 97, 114, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 70, 105, 108, 116, 101, 114, 32, 61, 32, 77, 73, 78, 95, 77, 65, 71, 95, 77, 73, 80, 95, 76, 73, 78, 69, 65, 82, 59, 13, 10, +32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, +32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 82, 101, 112, 101, 97, 116, 83, 97, 109, 112, 108, 101, 114, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 85, 32, 61, 32, 87, 114, +97, 112, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 65, 100, 100, 114, 101, 115, 115, 86, 32, 61, 32, 87, 114, 97, 112, 59, 13, 10, 32, 32, 32, 32, 125, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 68, 101, 102, 97, 117, 108, 116, 32, 99, 117, 115, 116, 111, 109, 32, 115, +97, 109, 112, 108, 101, 114, 115, 32, 45, 32, 109, 105, 103, 104, 116, 32, 98, 101, 32, 97, 117, 116, 111, 109, 97, 116, 105, 99, 97, 108, 108, 121, 32, 117, 115, 101, 100, 32, 98, 121, 32, 116, 104, 101, 32, 109, 97, 116, 101, 114, 105, 97, 108, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 49, 59, 13, 10, 32, 32, 32, 32, +115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 50, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 51, 59, 13, 10, +32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, +53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 54, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, +112, 108, 101, 114, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, 32, 83, 97, 109, 112, 108, 101, 114, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 83, 97, 109, 112, 108, 101, 114, 83, 116, 97, 116, 101, +32, 83, 97, 109, 112, 108, 101, 114, 57, 59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 84, 101, 120, 99, 111, 111, 114, 100, 32, 97, 116, 116, 114, 105, 98, 117, 116, 101, 32, 105, 110, 112, 117, 116, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, +32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 48, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 49, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 49, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 50, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 50, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 51, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 51, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 52, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 52, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 53, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 53, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 54, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 54, 59, 13, 10, 32, +32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 55, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 55, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, +102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 56, 32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 56, 59, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 50, 32, 84, 101, 120, 67, 111, 111, 114, 100, 57, +32, 58, 32, 84, 69, 88, 67, 79, 79, 82, 68, 57, 59, 13, 10, 125, 59, 13, 10, 0, 7, 0, 20, 0, 108, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, +71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 115, 100, 115, 108, 0, 0, 0, 0, 3, 0, 46, 1, 0, 0, 0, 0, 0, 0, 0, 0, 108, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, -13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, 105, 103, 110, 101, -100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, 59, 13, 10, 13, -10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, 100, 105, 110, 103, -40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, -114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, -116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, 5, 0, 7, 0, -22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, -116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, -62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, -97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, -111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, 112, 0, 0, 0, -116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 86, -83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 0, 0, -5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, 112, 116, 114, 95, -85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, -111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, 185, 0, 0, 0, -112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, 202, 0, 0, 0, -112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, 114, 0, 0, 0, -5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 5, 0, -212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 53, 0, 0, 0, -5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, -99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, 116, 114, 97, 110, -115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 5, 0, -253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, 115, 105, 103, 68, -105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, 254, 0, 0, 0, -105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, 105, 110, 103, 0, -5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 5, 0, 7, 0, -76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, 105, 110, 95, 80, -83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 5, 0, -82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, -83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 84, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 6, 0, -84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, -5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, 83, 112, 114, 105, -116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, -5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, -5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, 111, 117, 116, 95, -86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 105, 1, 0, 0, -111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, -106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 7, 0, -107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, -114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, 1, 0, 0, 0, -84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, 109, 1, 0, 0, -112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, -68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 118, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, 112, 0, 0, 0, -2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, -80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, -0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 101, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, -71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 104, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, 104, 1, 0, 0, -3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, -0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, -33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, -33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, 32, 0, 4, 0, -7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, 19, 0, 2, 0, -30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, 0, 0, 0, 0, -37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, -68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, 4, 0, 0, 0, -4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, -43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 185, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, 184, 0, 0, 0, -5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, 43, 0, 4, 0, -138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, 43, 0, 4, 0, -138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, -5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, -79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 84, 1, 0, 0, -4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, -138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, -4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, -79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, -77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, -35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, -108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, 142, 0, 0, 0, -141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, -248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, 62, 0, 3, 0, -149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, 8, 0, 4, 0, -108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, 172, 0, 0, 0, -61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 254, 0, 2, 0, -177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, -187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 195, 0, 0, 0, -187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 188, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, 193, 0, 0, 0, -37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 14, 0, 0, 0, -5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, 55, 0, 3, 0, -185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, 7, 0, 0, 0, -59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, 206, 0, 0, 0, -111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, 8, 0, 4, 0, -179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, -219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, 61, 0, 4, 0, -5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, 62, 0, 3, 0, -224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, 5, 0, 0, 0, -234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, 220, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, 0, 238, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, 9, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, 243, 0, 0, 0, -8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, 239, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, 8, 0, 4, 0, -179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, 250, 0, 0, 0, -62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, 0, 1, 0, 0, -247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 4, 1, 0, 0, -216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, 62, 0, 3, 0, -3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, -12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, -15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, 136, 0, 5, 0, -5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, 0, 19, 1, 0, 0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, 21, 1, 0, 0, -8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, 13, 1, 0, 0, -12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, -4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, -29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 204, 0, 0, 0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, 248, 0, 2, 0, -254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, 204, 0, 0, 0, -61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, -32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, 37, 1, 0, 0, -56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 46, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 53, 1, 0, 0, -59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, 7, 0, 0, 0, -8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, -61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, 68, 1, 0, 0, -71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, 0, 72, 1, 0, 0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, 54, 0, 5, 0, -30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, 62, 0, 3, 0, -89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, -95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, -54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, 100, 1, 0, 0, -62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, 65, 0, 5, 0, -3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, -61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, 125, 1, 0, 0, -62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, +13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 32, 58, 32, 83, 104, 97, 100, 101, 114, 66, 97, 115, 101, 44, 32, 84, 101, 120, 116, 117, 114, 105, 110, 103, 13, 10, 123, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 115, 116, 114, 101, 97, 109, 115, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 80, 111, 115, 105, 116, 105, 111, 110, 32, 58, 32, 80, +79, 83, 73, 84, 73, 79, 78, 59, 13, 10, 13, 10, 32, 32, 32, 32, 99, 98, 117, 102, 102, 101, 114, 32, 80, 101, 114, 68, 114, 97, 119, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 117, 110, 105, 102, 111, 114, 109, 115, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, +45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 65, 32, 103, 101, 110, 101, 114, 97, 108, 32, 116, 114, 97, 110, 115, 102, 111, 114, 109, 97, +116, 105, 111, 110, 32, 109, 97, 116, 114, 105, 120, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 120, 52, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 47, 47, 32, 86, 101, 114, 116, +101, 120, 83, 104, 97, 100, 101, 114, 13, 10, 32, 32, 32, 32, 47, 47, 32, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, +101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 86, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, +32, 61, 32, 109, 117, 108, 40, 115, 116, 114, 101, 97, 109, 115, 46, 80, 111, 115, 105, 116, 105, 111, 110, 44, 32, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, +105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 118, 111, 105, 100, 32, 80, 83, 77, 97, 105, 110, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 115, 116, 114, 101, 97, 109, 115, 46, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 32, 61, 32, 83, 104, 97, 100, 105, 110, 103, 40, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, +83, 104, 97, 100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 84, 101, 120, 116, 117, 114, 101, 48, 46, 83, 97, 109, 112, 108, 101, 40, 83, 97, 109, 112, 108, 101, 114, 44, 32, 115, 116, 114, 101, 97, 109, +115, 46, 84, 101, 120, 67, 111, 111, 114, 100, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 0, 7, 0, 23, 0, 179, 0, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, +47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 2, 2, 0, 0, 0, 0, +0, 0, 0, 0, 179, 0, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, 105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, +100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, +114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, 101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, +111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110, 46, 13, 10, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 32, 58, 32, 84, 101, 120, 116, 117, 114, 105, +110, 103, 13, 10, 123, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 115, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 111, 102, 32, 51, 32, 118, 97, 108, 117, 101, 115, 13, 10, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 40, 102, 108, +111, 97, 116, 32, 114, 44, 32, 102, 108, 111, 97, 116, 32, 103, 44, 32, 102, 108, 111, 97, 116, 32, 98, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 109, 97, 120, 40, 109, 105, 110, 40, 114, 44, 32, 103, 41, 44, 32, 109, +105, 110, 40, 109, 97, 120, 40, 114, 44, 32, 103, 41, 44, 32, 98, 41, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 82, 101, 116, 114, 105, 101, 118, 101, 115, 32, 116, 104, 101, 32, 112, 105, 120, 101, 108, 39, 115, 32, 99, 111, 108, 111, 114, 32, +115, 97, 109, 112, 108, 101, 100, 32, 102, 114, 111, 109, 32, 97, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, 101, 108, 100, 32, 102, 111, 110, 116, 32, 116, 101, 120, 116, 117, 114, 101, 44, 32, 119, 105, 116, 104, 32, 102, 111, 110, 116, 32, 99, 111, 108, +111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 32, 97, 110, 100, 32, 115, 104, 97, 100, 111, 119, 115, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 102, 108, 111, 97, 116, 52, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 102, 108, 111, 97, 116, 52, 32, 115, 97, 109, 112, 108, 101, +100, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 32, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, +101, 115, 115, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 45, 48, 46, 53, 32, 116, 111, 32, 43, 48, 46, 53, 32, 105, 115, 32, 116, 104, 101, 32, 109, 97, 120, 105, 109, 117, 109, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 109, 115, 100, +102, 103, 101, 110, 32, 99, 97, 110, 32, 112, 114, 111, 100, 117, 99, 101, 44, 32, 98, 117, 116, 32, 105, 116, 39, 115, 32, 98, 108, 117, 114, 114, 121, 32, 115, 111, 32, 99, 97, 112, 32, 116, 104, 101, 32, 98, 111, 114, 100, 101, 114, 32, 97, 116, 32, 48, 46, 50, 53, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 61, 32, 99, 108, 97, 109, 112, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 44, 32, 48, 44, 32, 48, 46, 50, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, +32, 32, 47, 47, 32, 72, 105, 103, 104, 101, 114, 32, 40, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 49, 41, 32, 45, 32, 115, 104, 97, 114, 112, 101, 114, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 76, 111, 119, 101, 114, 32, 40, 108, 101, 115, 115, 32, 116, 104, 97, 110, +32, 49, 44, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 48, 41, 32, 45, 32, 98, 108, 117, 114, 114, 121, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 61, 32, 48, 46, +53, 102, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 48, 46, 52, 32, 45, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 59, 13, 10, 13, 10, 32, 32, 32, 32, +32, 32, 32, 32, 47, 47, 32, 71, 101, 116, 32, 116, 104, 101, 32, 109, 101, 100, 105, 97, 110, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 101, 110, 99, 111, 100, 101, 100, 32, 105, 110, 32, 116, 104, 101, 32, 115, 105, 103, 110, 101, 100, 32, 100, 105, 115, 116, 97, 110, 99, 101, 32, 102, 105, +101, 108, 100, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 109, 101, 100, 105, 97, 110, 40, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 114, 44, 32, 115, 97, 109, 112, 108, +101, 100, 67, 111, 108, 111, 114, 46, 103, 44, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 46, 98, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, +116, 97, 110, 99, 101, 32, 45, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 32, 61, 32, 102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, +115, 116, 41, 32, 42, 32, 48, 46, 56, 53, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 111, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 45, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 44, 32, 116, 114, 97, +110, 115, 105, 116, 105, 111, 110, 44, 32, 115, 105, 103, 68, 105, 115, 116, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 111, 112, 97, 99, 105, 116, 121, 32, 42, 61, 32, 111, 112, 97, 99, 105, 116, 121, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 47, 47, 32, 68, 101, +116, 101, 99, 116, 32, 101, 100, 103, 101, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 105, 102, 32, 40, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 62, 32, 48, 41, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, +32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 32, 61, 32, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 32, 43, 32, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 32, 42, 32, 50, 59, 13, 10, 32, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 32, 61, 32, 109, 101, 100, 105, 97, 110, 68, 105, 115, 116, 97, 110, 99, 101, 32, 45, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 13, 10, 32, 32, +32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, 111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 32, 61, 32, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 32, 42, 32, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 47, +102, 119, 105, 100, 116, 104, 40, 115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 41, 32, 43, 32, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 59, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 102, 108, +111, 97, 116, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 32, 61, 32, 115, 109, 111, 111, 116, 104, 115, 116, 101, 112, 40, 48, 44, 32, 49, 44, 32, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 41, 59, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, +32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, +32, 32, 32, 125, 13, 10, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 32, 61, 32, 108, 101, 114, 112, 40, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 48, 41, 44, 32, 116, 101, 120, 116, 67, 111, 108, 111, 114, 44, 32, +111, 112, 97, 99, 105, 116, 121, 41, 59, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, +7, 0, 26, 0, 39, 1, 0, 0, 67, 58, 47, 100, 101, 118, 47, 115, 116, 114, 105, 100, 101, 47, 115, 111, 117, 114, 99, 101, 115, 47, 101, 110, 103, 105, 110, 101, 47, 83, 116, 114, 105, 100, 101, 46, 71, 114, 97, 112, 104, 105, 99, 115, 47, 83, 104, 97, 100, 101, 114, 115, 47, 83, 112, 114, +105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 115, 100, 115, 108, 0, 0, 0, 3, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 1, 0, 0, 47, 47, 32, 67, 111, 112, 121, 114, +105, 103, 104, 116, 32, 40, 99, 41, 32, 46, 78, 69, 84, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110, 32, 97, 110, 100, 32, 67, 111, 110, 116, 114, 105, 98, 117, 116, 111, 114, 115, 32, 40, 104, 116, 116, 112, 115, 58, 47, 47, 100, 111, 116, 110, 101, 116, 102, 111, 117, 110, 100, 97, 116, +105, 111, 110, 46, 111, 114, 103, 47, 32, 38, 32, 104, 116, 116, 112, 115, 58, 47, 47, 115, 116, 114, 105, 100, 101, 51, 100, 46, 110, 101, 116, 41, 32, 97, 110, 100, 32, 83, 105, 108, 105, 99, 111, 110, 32, 83, 116, 117, 100, 105, 111, 32, 67, 111, 114, 112, 46, 32, 40, 104, 116, 116, 112, 115, +58, 47, 47, 119, 119, 119, 46, 115, 105, 108, 105, 99, 111, 110, 115, 116, 117, 100, 105, 111, 46, 99, 111, 46, 106, 112, 41, 13, 10, 47, 47, 32, 68, 105, 115, 116, 114, 105, 98, 117, 116, 101, 100, 32, 117, 110, 100, 101, 114, 32, 116, 104, 101, 32, 77, 73, 84, 32, 108, 105, 99, 101, 110, 115, +101, 46, 32, 83, 101, 101, 32, 116, 104, 101, 32, 76, 73, 67, 69, 78, 83, 69, 46, 109, 100, 32, 102, 105, 108, 101, 32, 105, 110, 32, 116, 104, 101, 32, 112, 114, 111, 106, 101, 99, 116, 32, 114, 111, 111, 116, 32, 102, 111, 114, 32, 109, 111, 114, 101, 32, 105, 110, 102, 111, 114, 109, 97, 116, +105, 111, 110, 46, 13, 10, 115, 104, 97, 100, 101, 114, 32, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 32, 58, 32, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 44, 32, 83, +105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 13, 10, 123, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 115, 116, 114, 101, 97, 109, 32, 102, 108, 111, 97, 116, 52, 32, 67, 111, 108, 111, 114, 32, 58, 32, 67, 79, 76, 79, 82, +59, 13, 10, 13, 10, 32, 32, 32, 32, 47, 47, 32, 83, 104, 97, 100, 105, 110, 103, 32, 111, 102, 32, 116, 104, 101, 32, 115, 112, 114, 105, 116, 101, 13, 10, 32, 32, 32, 32, 115, 116, 97, 103, 101, 32, 111, 118, 101, 114, 114, 105, 100, 101, 32, 102, 108, 111, 97, 116, 52, 32, 83, 104, 97, +100, 105, 110, 103, 40, 41, 13, 10, 32, 32, 32, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 70, 111, 110, 116, 67, 111, 108, 111, 114, 40, 98, 97, 115, 101, 46, 83, 104, 97, 100, 105, 110, 103, 40, 41, 44, 32, 115, 116, 114, 101, 97, 109, 115, 46, +67, 111, 108, 111, 114, 44, 32, 102, 108, 111, 97, 116, 52, 40, 48, 44, 48, 44, 48, 44, 49, 41, 44, 32, 48, 46, 102, 41, 59, 13, 10, 32, 32, 32, 32, 125, 13, 10, 125, 59, 13, 10, 0, 0, 5, 0, 7, 0, 3, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 7, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 98, 111, 111, 108, 0, 0, 0, 0, 5, 0, 7, 0, 18, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 0, 0, 0, +5, 0, 7, 0, 22, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 117, 105, 110, 116, 0, 0, 0, 0, 5, 0, 11, 0, 36, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, +102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 40, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 84, 101, 120, 116, 117, 114, 101, 48, 0, 0, 5, 0, 7, 0, 41, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 50, 0, 0, +5, 0, 11, 0, 62, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 11, 0, 68, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 67, +111, 110, 115, 116, 97, 110, 116, 95, 84, 101, 120, 116, 117, 114, 101, 95, 102, 108, 111, 97, 116, 52, 0, 0, 5, 0, 7, 0, 74, 0, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 102, 108, 111, 97, 116, 50, 0, 0, 5, 0, 11, 0, 85, 0, 0, 0, 112, 116, 114, 95, +85, 110, 105, 102, 111, 114, 109, 67, 111, 110, 115, 116, 97, 110, 116, 95, 116, 121, 112, 101, 95, 115, 97, 109, 112, 108, 101, 114, 0, 0, 0, 0, 5, 0, 7, 0, 87, 0, 0, 0, 84, 101, 120, 116, 117, 114, 105, 110, 103, 46, 83, 97, 109, 112, 108, 101, 114, 0, 0, 0, 5, 0, 6, 0, +112, 0, 0, 0, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 6, 0, 7, 0, 112, 0, 0, 0, 0, 0, 0, 0, 77, 97, 116, 114, 105, 120, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 5, 0, 7, 0, 117, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, +115, 101, 46, 86, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 118, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 80, 83, 77, 97, 105, 110, 0, 0, 0, 5, 0, 7, 0, 119, 0, 0, 0, 83, 112, 114, 105, 116, 101, 66, 97, 115, 101, 46, 83, 104, 97, 100, 105, +110, 103, 0, 0, 5, 0, 4, 0, 116, 0, 0, 0, 80, 101, 114, 68, 114, 97, 119, 0, 5, 0, 9, 0, 122, 0, 0, 0, 112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 116, 121, 112, 101, 46, 80, 101, 114, 68, 114, 97, 119, 0, 0, 0, 0, 5, 0, 8, 0, 137, 0, 0, 0, +112, 116, 114, 95, 85, 110, 105, 102, 111, 114, 109, 95, 102, 108, 111, 97, 116, 52, 120, 52, 0, 0, 0, 0, 5, 0, 4, 0, 139, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 10, 0, 181, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, +101, 108, 100, 70, 111, 110, 116, 46, 109, 101, 100, 105, 97, 110, 0, 0, 5, 0, 11, 0, 182, 0, 0, 0, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 46, 70, 111, 110, 116, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 7, 0, +185, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 0, 0, 5, 0, 3, 0, 186, 0, 0, 0, 114, 0, 0, 0, 5, 0, 3, 0, 187, 0, 0, 0, 103, 0, 0, 0, 5, 0, 3, 0, 188, 0, 0, 0, 98, 0, 0, 0, 5, 0, 7, 0, +202, 0, 0, 0, 112, 116, 114, 95, 70, 117, 110, 99, 116, 105, 111, 110, 95, 102, 108, 111, 97, 116, 52, 0, 5, 0, 6, 0, 203, 0, 0, 0, 115, 97, 109, 112, 108, 101, 100, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 204, 0, 0, 0, 116, 101, 120, 116, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 5, 0, 205, 0, 0, 0, 98, 111, 114, 100, 101, 114, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, 206, 0, 0, 0, 98, 111, 114, 100, 101, 114, 84, 104, 105, 99, 107, 110, 101, 115, 115, 0, 5, 0, 4, 0, 210, 0, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, +5, 0, 5, 0, 212, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 50, 0, 0, 0, 5, 0, 7, 0, 214, 0, 0, 0, 115, 104, 97, 114, 112, 110, 101, 115, 115, 77, 97, 103, 110, 105, 116, 117, 100, 101, 0, 0, 5, 0, 5, 0, 215, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, +53, 0, 0, 0, 5, 0, 6, 0, 216, 0, 0, 0, 97, 120, 105, 115, 68, 105, 115, 116, 97, 110, 99, 101, 0, 0, 0, 0, 5, 0, 5, 0, 217, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 52, 0, 0, 0, 5, 0, 6, 0, 220, 0, 0, 0, 109, 101, 100, 105, 97, 110, 68, 105, +115, 116, 97, 110, 99, 101, 0, 0, 5, 0, 4, 0, 225, 0, 0, 0, 105, 110, 116, 95, 49, 0, 0, 0, 5, 0, 4, 0, 229, 0, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 235, 0, 0, 0, 115, 105, 103, 68, 105, 115, 116, 0, 5, 0, 5, 0, 239, 0, 0, 0, +116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 242, 0, 0, 0, 102, 108, 111, 97, 116, 95, 48, 46, 56, 53, 0, 0, 5, 0, 4, 0, 244, 0, 0, 0, 111, 112, 97, 99, 105, 116, 121, 0, 5, 0, 4, 0, 0, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, +5, 0, 5, 0, 253, 0, 0, 0, 105, 102, 95, 116, 114, 117, 101, 95, 48, 0, 0, 0, 5, 0, 5, 0, 3, 1, 0, 0, 102, 97, 114, 68, 105, 115, 116, 97, 110, 99, 101, 0, 5, 0, 4, 0, 6, 1, 0, 0, 102, 108, 111, 97, 116, 95, 50, 0, 5, 0, 6, 0, 9, 1, 0, 0, +115, 105, 103, 68, 105, 115, 116, 66, 111, 114, 100, 101, 114, 0, 0, 0, 5, 0, 5, 0, 13, 1, 0, 0, 98, 111, 114, 100, 101, 114, 76, 105, 110, 101, 0, 0, 5, 0, 6, 0, 22, 1, 0, 0, 98, 111, 114, 100, 101, 114, 79, 112, 97, 99, 105, 116, 121, 0, 0, 0, 5, 0, 5, 0, +254, 0, 0, 0, 105, 102, 95, 109, 101, 114, 103, 101, 95, 48, 0, 0, 5, 0, 13, 0, 46, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 83, 104, 97, 100, +105, 110, 103, 0, 5, 0, 4, 0, 69, 1, 0, 0, 102, 108, 111, 97, 116, 95, 48, 0, 5, 0, 4, 0, 70, 1, 0, 0, 102, 108, 111, 97, 116, 95, 49, 0, 5, 0, 7, 0, 77, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, +5, 0, 7, 0, 76, 1, 0, 0, 111, 117, 116, 95, 80, 83, 95, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 0, 5, 0, 7, 0, 79, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 0, 5, 0, 6, 0, 78, 1, 0, 0, +105, 110, 95, 80, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 81, 1, 0, 0, 112, 116, 114, 95, 73, 110, 112, 117, 116, 95, 102, 108, 111, 97, 116, 52, 0, 0, 0, 0, 5, 0, 5, 0, 80, 1, 0, 0, 105, 110, 95, 80, 83, 95, 67, 111, 108, 111, 114, 0, +5, 0, 5, 0, 82, 1, 0, 0, 80, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 82, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 82, 1, 0, 0, 1, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, +5, 0, 5, 0, 83, 1, 0, 0, 80, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, 6, 0, 6, 0, 83, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 5, 0, 5, 0, 84, 1, 0, 0, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, +6, 0, 6, 0, 84, 1, 0, 0, 0, 0, 0, 0, 67, 111, 108, 111, 114, 84, 97, 114, 103, 101, 116, 0, 6, 0, 6, 0, 84, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 84, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, +114, 0, 0, 0, 5, 0, 8, 0, 85, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 80, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 86, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 80, 83, 0, 0, 0, 5, 0, 15, 0, 87, 1, 0, 0, +83, 112, 114, 105, 116, 101, 83, 105, 103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 80, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 90, 1, 0, 0, 105, 110, 116, 95, +49, 0, 0, 0, 5, 0, 4, 0, 93, 1, 0, 0, 105, 110, 116, 95, 50, 0, 0, 0, 5, 0, 4, 0, 97, 1, 0, 0, 105, 110, 116, 95, 48, 0, 0, 0, 5, 0, 8, 0, 99, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, +111, 110, 0, 0, 5, 0, 6, 0, 100, 1, 0, 0, 105, 110, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 5, 0, 7, 0, 102, 1, 0, 0, 112, 116, 114, 95, 79, 117, 116, 112, 117, 116, 95, 102, 108, 111, 97, 116, 50, 0, 0, 0, 5, 0, 6, 0, 101, 1, 0, 0, +111, 117, 116, 95, 86, 83, 95, 84, 101, 120, 67, 111, 111, 114, 100, 0, 5, 0, 6, 0, 103, 1, 0, 0, 105, 110, 95, 86, 83, 95, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 5, 0, 5, 0, 104, 1, 0, 0, 105, 110, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 5, 0, 6, 0, +105, 1, 0, 0, 111, 117, 116, 95, 86, 83, 95, 67, 111, 108, 111, 114, 0, 0, 0, 0, 5, 0, 5, 0, 106, 1, 0, 0, 86, 83, 95, 73, 78, 80, 85, 84, 0, 0, 0, 0, 6, 0, 6, 0, 106, 1, 0, 0, 0, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, +6, 0, 6, 0, 106, 1, 0, 0, 1, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 106, 1, 0, 0, 2, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 107, 1, 0, 0, 86, 83, 95, 79, 85, 84, 80, 85, 84, 0, 0, 0, +6, 0, 7, 0, 107, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 107, 1, 0, 0, 1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 5, 0, 107, 1, 0, 0, 2, 0, 0, 0, +67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 5, 0, 108, 1, 0, 0, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 6, 0, 7, 0, 108, 1, 0, 0, 0, 0, 0, 0, 83, 104, 97, 100, 105, 110, 103, 80, 111, 115, 105, 116, 105, 111, 110, 0, 6, 0, 6, 0, 108, 1, 0, 0, +1, 0, 0, 0, 84, 101, 120, 67, 111, 111, 114, 100, 0, 0, 0, 0, 6, 0, 6, 0, 108, 1, 0, 0, 2, 0, 0, 0, 80, 111, 115, 105, 116, 105, 111, 110, 0, 0, 0, 0, 6, 0, 5, 0, 108, 1, 0, 0, 3, 0, 0, 0, 67, 111, 108, 111, 114, 0, 0, 0, 5, 0, 8, 0, +109, 1, 0, 0, 112, 116, 114, 95, 80, 114, 105, 118, 97, 116, 101, 95, 86, 83, 95, 83, 84, 82, 69, 65, 77, 83, 0, 0, 5, 0, 5, 0, 110, 1, 0, 0, 115, 116, 114, 101, 97, 109, 115, 86, 83, 0, 0, 0, 5, 0, 15, 0, 111, 1, 0, 0, 83, 112, 114, 105, 116, 101, 83, 105, +103, 110, 101, 100, 68, 105, 115, 116, 97, 110, 99, 101, 70, 105, 101, 108, 100, 70, 111, 110, 116, 83, 104, 97, 100, 101, 114, 46, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, 0, 5, 0, 4, 0, 118, 1, 0, 0, 105, 110, 116, 95, 51, 0, 0, 0, 71, 0, 3, 0, +112, 0, 0, 0, 2, 0, 0, 0, 71, 0, 4, 0, 76, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 78, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 78, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, +71, 0, 4, 0, 80, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 80, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 99, 1, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 100, 1, 0, 0, 30, 0, 0, 0, +0, 0, 0, 0, 0, 22, 6, 0, 100, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, 48, 0, 0, 0, 71, 0, 4, 0, 101, 1, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 22, 6, 0, 101, 1, 0, 0, 3, 22, 0, 0, 84, 69, 88, 67, 79, 79, 82, 68, +48, 0, 0, 0, 71, 0, 4, 0, 103, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 6, 0, 103, 1, 0, 0, 3, 22, 0, 0, 80, 79, 83, 73, 84, 73, 79, 78, 0, 0, 0, 0, 71, 0, 4, 0, 104, 1, 0, 0, 30, 0, 0, 0, 2, 0, 0, 0, 0, 22, 5, 0, +104, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 71, 0, 4, 0, 105, 1, 0, 0, 30, 0, 0, 0, 1, 0, 0, 0, 0, 22, 5, 0, 105, 1, 0, 0, 3, 22, 0, 0, 67, 79, 76, 79, 82, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, +35, 0, 0, 0, 0, 0, 0, 0, 72, 0, 4, 0, 112, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 72, 0, 5, 0, 112, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 16, 0, 0, 0, 71, 0, 4, 0, 40, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +40, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, 87, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 71, 0, 4, 0, 116, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 71, 0, 4, 0, +116, 0, 0, 0, 33, 0, 0, 0, 2, 0, 0, 0, 22, 0, 3, 0, 5, 0, 0, 0, 32, 0, 0, 0, 23, 0, 4, 0, 4, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 3, 0, 0, 0, 6, 0, 0, 0, 4, 0, 0, 0, 20, 0, 2, 0, 8, 0, 0, 0, +32, 0, 4, 0, 7, 0, 0, 0, 6, 0, 0, 0, 8, 0, 0, 0, 32, 0, 4, 0, 18, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 21, 0, 4, 0, 23, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 22, 0, 0, 0, 6, 0, 0, 0, 23, 0, 0, 0, +19, 0, 2, 0, 30, 0, 0, 0, 33, 0, 3, 0, 31, 0, 0, 0, 30, 0, 0, 0, 25, 0, 9, 0, 37, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 36, 0, 0, 0, +0, 0, 0, 0, 37, 0, 0, 0, 23, 0, 4, 0, 42, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 32, 0, 4, 0, 41, 0, 0, 0, 2, 0, 0, 0, 42, 0, 0, 0, 25, 0, 9, 0, 63, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 62, 0, 0, 0, 0, 0, 0, 0, 63, 0, 0, 0, 25, 0, 9, 0, 69, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, +32, 0, 4, 0, 68, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 32, 0, 4, 0, 74, 0, 0, 0, 6, 0, 0, 0, 42, 0, 0, 0, 26, 0, 2, 0, 86, 0, 0, 0, 32, 0, 4, 0, 85, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 24, 0, 4, 0, 113, 0, 0, 0, +4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 112, 0, 0, 0, 113, 0, 0, 0, 32, 0, 4, 0, 122, 0, 0, 0, 2, 0, 0, 0, 112, 0, 0, 0, 32, 0, 4, 0, 137, 0, 0, 0, 2, 0, 0, 0, 113, 0, 0, 0, 21, 0, 4, 0, 138, 0, 0, 0, 32, 0, 0, 0, +1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 33, 0, 3, 0, 151, 0, 0, 0, 4, 0, 0, 0, 27, 0, 3, 0, 175, 0, 0, 0, 37, 0, 0, 0, 32, 0, 4, 0, 185, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 33, 0, 6, 0, +184, 0, 0, 0, 5, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 185, 0, 0, 0, 32, 0, 4, 0, 202, 0, 0, 0, 7, 0, 0, 0, 4, 0, 0, 0, 33, 0, 7, 0, 201, 0, 0, 0, 4, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 202, 0, 0, 0, 185, 0, 0, 0, +43, 0, 4, 0, 138, 0, 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 212, 0, 0, 0, 205, 204, 76, 62, 43, 0, 4, 0, 5, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 63, 43, 0, 4, 0, 5, 0, 0, 0, 217, 0, 0, 0, 205, 204, 204, 62, +43, 0, 4, 0, 138, 0, 0, 0, 225, 0, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 229, 0, 0, 0, 2, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 242, 0, 0, 0, 154, 153, 89, 63, 43, 0, 4, 0, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, +43, 0, 4, 0, 5, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 64, 43, 0, 4, 0, 5, 0, 0, 0, 69, 1, 0, 0, 0, 0, 0, 0, 43, 0, 4, 0, 5, 0, 0, 0, 70, 1, 0, 0, 0, 0, 128, 63, 32, 0, 4, 0, 77, 1, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, +32, 0, 4, 0, 79, 1, 0, 0, 1, 0, 0, 0, 42, 0, 0, 0, 32, 0, 4, 0, 81, 1, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 30, 0, 4, 0, 82, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 3, 0, 83, 1, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, +84, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 85, 1, 0, 0, 6, 0, 0, 0, 84, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 90, 1, 0, 0, 1, 0, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 93, 1, 0, 0, 2, 0, 0, 0, +43, 0, 4, 0, 138, 0, 0, 0, 97, 1, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 102, 1, 0, 0, 3, 0, 0, 0, 42, 0, 0, 0, 30, 0, 5, 0, 106, 1, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 30, 0, 5, 0, 107, 1, 0, 0, 4, 0, 0, 0, +42, 0, 0, 0, 4, 0, 0, 0, 30, 0, 6, 0, 108, 1, 0, 0, 4, 0, 0, 0, 42, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 32, 0, 4, 0, 109, 1, 0, 0, 6, 0, 0, 0, 108, 1, 0, 0, 43, 0, 4, 0, 138, 0, 0, 0, 118, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 36, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 85, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 59, 0, 4, 0, 122, 0, 0, 0, 116, 0, 0, 0, 2, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 76, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 79, 1, 0, 0, 78, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 80, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 85, 1, 0, 0, 86, 1, 0, 0, 6, 0, 0, 0, 59, 0, 4, 0, 77, 1, 0, 0, 99, 1, 0, 0, 3, 0, 0, 0, +59, 0, 4, 0, 79, 1, 0, 0, 100, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 102, 1, 0, 0, 101, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 103, 1, 0, 0, 1, 0, 0, 0, 59, 0, 4, 0, 81, 1, 0, 0, 104, 1, 0, 0, 1, 0, 0, 0, +59, 0, 4, 0, 77, 1, 0, 0, 105, 1, 0, 0, 3, 0, 0, 0, 59, 0, 4, 0, 109, 1, 0, 0, 110, 1, 0, 0, 6, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 26, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 2, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 2, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 26, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 26, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 6, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 7, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 9, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 11, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 12, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 13, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 14, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 15, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 17, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 18, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 19, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 20, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 21, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 23, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 24, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 25, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 29, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 30, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 31, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 34, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 35, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 36, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 37, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 114, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 115, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 116, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 117, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 118, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 119, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 120, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 121, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 122, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 123, 0, 0, 0, 5, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 40, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 42, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 47, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 52, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 59, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 68, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 73, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 81, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 88, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 95, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 102, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 103, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 104, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 105, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 106, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 107, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 35, 0, 0, 0, 108, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 109, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 110, 0, 0, 0, 11, 0, 0, 0, 8, 0, 4, 0, 35, 0, 0, 0, 111, 0, 0, 0, 11, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 10, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 22, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 117, 0, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 126, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 24, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 133, 0, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 135, 0, 0, 0, 110, 1, 0, 0, +93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 136, 0, 0, 0, 135, 0, 0, 0, 65, 0, 5, 0, 137, 0, 0, 0, 140, 0, 0, 0, 116, 0, 0, 0, 139, 0, 0, 0, 61, 0, 4, 0, 113, 0, 0, 0, 141, 0, 0, 0, 140, 0, 0, 0, 145, 0, 5, 0, 4, 0, 0, 0, +142, 0, 0, 0, 141, 0, 0, 0, 136, 0, 0, 0, 62, 0, 3, 0, 133, 0, 0, 0, 142, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 30, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, +31, 0, 0, 0, 248, 0, 2, 0, 144, 0, 0, 0, 8, 0, 4, 0, 108, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 149, 0, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 153, 0, 0, 0, 46, 1, 0, 0, +62, 0, 3, 0, 149, 0, 0, 0, 153, 0, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 8, 0, 4, 0, 108, 0, 0, 0, 33, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 119, 0, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, 154, 0, 0, 0, +8, 0, 4, 0, 108, 0, 0, 0, 35, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 86, 0, 0, 0, 165, 0, 0, 0, 87, 0, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 172, 0, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 173, 0, 0, 0, +172, 0, 0, 0, 61, 0, 4, 0, 37, 0, 0, 0, 174, 0, 0, 0, 40, 0, 0, 0, 86, 0, 5, 0, 175, 0, 0, 0, 176, 0, 0, 0, 174, 0, 0, 0, 165, 0, 0, 0, 87, 0, 6, 0, 4, 0, 0, 0, 177, 0, 0, 0, 176, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, +254, 0, 2, 0, 177, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 5, 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 186, 0, 0, 0, 55, 0, 3, 0, +185, 0, 0, 0, 187, 0, 0, 0, 55, 0, 3, 0, 185, 0, 0, 0, 188, 0, 0, 0, 248, 0, 2, 0, 189, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 190, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 191, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 192, 0, 0, 0, 193, 0, 0, 0, 37, 0, 0, 0, 190, 0, 0, 0, 191, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 194, 0, 0, 0, 186, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +195, 0, 0, 0, 187, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 196, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 194, 0, 0, 0, 195, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 197, 0, 0, 0, 188, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 198, 0, 0, 0, +193, 0, 0, 0, 37, 0, 0, 0, 196, 0, 0, 0, 197, 0, 0, 0, 12, 0, 7, 0, 5, 0, 0, 0, 199, 0, 0, 0, 193, 0, 0, 0, 40, 0, 0, 0, 192, 0, 0, 0, 198, 0, 0, 0, 254, 0, 2, 0, 199, 0, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 179, 0, 0, 0, +14, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 182, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 203, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 204, 0, 0, 0, 55, 0, 3, 0, 202, 0, 0, 0, 205, 0, 0, 0, +55, 0, 3, 0, 185, 0, 0, 0, 206, 0, 0, 0, 248, 0, 2, 0, 207, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 214, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 216, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 220, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 221, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 224, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 228, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 235, 0, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 239, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 244, 0, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 3, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 9, 1, 0, 0, +7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 13, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 22, 1, 0, 0, 7, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 17, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 208, 0, 0, 0, +206, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 211, 0, 0, 0, 210, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 213, 0, 0, 0, 193, 0, 0, 0, 43, 0, 0, 0, 208, 0, 0, 0, 211, 0, 0, 0, 212, 0, 0, 0, 62, 0, 3, 0, 206, 0, 0, 0, 213, 0, 0, 0, +8, 0, 4, 0, 179, 0, 0, 0, 21, 0, 0, 0, 9, 0, 0, 0, 62, 0, 3, 0, 214, 0, 0, 0, 215, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 22, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 218, 0, 0, 0, 206, 0, 0, 0, 131, 0, 5, 0, +5, 0, 0, 0, 219, 0, 0, 0, 217, 0, 0, 0, 218, 0, 0, 0, 62, 0, 3, 0, 216, 0, 0, 0, 219, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 25, 0, 0, 0, 9, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 222, 0, 0, 0, 203, 0, 0, 0, 210, 0, 0, 0, +61, 0, 4, 0, 5, 0, 0, 0, 223, 0, 0, 0, 222, 0, 0, 0, 62, 0, 3, 0, 221, 0, 0, 0, 223, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 226, 0, 0, 0, 203, 0, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 227, 0, 0, 0, 226, 0, 0, 0, +62, 0, 3, 0, 224, 0, 0, 0, 227, 0, 0, 0, 65, 0, 5, 0, 185, 0, 0, 0, 230, 0, 0, 0, 203, 0, 0, 0, 229, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 231, 0, 0, 0, 230, 0, 0, 0, 62, 0, 3, 0, 228, 0, 0, 0, 231, 0, 0, 0, 57, 0, 7, 0, +5, 0, 0, 0, 234, 0, 0, 0, 181, 0, 0, 0, 221, 0, 0, 0, 224, 0, 0, 0, 228, 0, 0, 0, 62, 0, 3, 0, 220, 0, 0, 0, 234, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 27, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 236, 0, 0, 0, +220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 237, 0, 0, 0, 216, 0, 0, 0, 131, 0, 5, 0, 5, 0, 0, 0, 238, 0, 0, 0, 236, 0, 0, 0, 237, 0, 0, 0, 62, 0, 3, 0, 235, 0, 0, 0, 238, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 29, 0, 0, 0, +9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 240, 0, 0, 0, 235, 0, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 243, 0, 0, 0, 241, 0, 0, 0, 242, 0, 0, 0, 62, 0, 3, 0, 239, 0, 0, 0, +243, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 30, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 245, 0, 0, 0, 239, 0, 0, 0, 127, 0, 4, 0, 5, 0, 0, 0, 246, 0, 0, 0, 245, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 247, 0, 0, 0, +239, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 248, 0, 0, 0, 235, 0, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 249, 0, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 246, 0, 0, 0, 247, 0, 0, 0, 248, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 249, 0, 0, 0, +8, 0, 4, 0, 179, 0, 0, 0, 31, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 250, 0, 0, 0, 244, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 251, 0, 0, 0, 244, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 252, 0, 0, 0, 251, 0, 0, 0, +250, 0, 0, 0, 62, 0, 3, 0, 244, 0, 0, 0, 252, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 34, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 255, 0, 0, 0, 206, 0, 0, 0, 186, 0, 5, 0, 8, 0, 0, 0, 1, 1, 0, 0, 255, 0, 0, 0, +0, 1, 0, 0, 247, 0, 3, 0, 254, 0, 0, 0, 0, 0, 0, 0, 250, 0, 4, 0, 1, 1, 0, 0, 253, 0, 0, 0, 254, 0, 0, 0, 248, 0, 2, 0, 253, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 36, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, +4, 1, 0, 0, 216, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 5, 1, 0, 0, 206, 0, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 7, 1, 0, 0, 5, 1, 0, 0, 6, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 8, 1, 0, 0, 4, 1, 0, 0, 7, 1, 0, 0, +62, 0, 3, 0, 3, 1, 0, 0, 8, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 37, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 10, 1, 0, 0, 220, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 11, 1, 0, 0, 3, 1, 0, 0, 131, 0, 5, 0, +5, 0, 0, 0, 12, 1, 0, 0, 10, 1, 0, 0, 11, 1, 0, 0, 62, 0, 3, 0, 9, 1, 0, 0, 12, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 38, 0, 0, 0, 13, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 14, 1, 0, 0, 214, 0, 0, 0, 61, 0, 4, 0, +5, 0, 0, 0, 15, 1, 0, 0, 9, 1, 0, 0, 133, 0, 5, 0, 5, 0, 0, 0, 16, 1, 0, 0, 14, 1, 0, 0, 15, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 17, 1, 0, 0, 9, 1, 0, 0, 209, 0, 4, 0, 5, 0, 0, 0, 18, 1, 0, 0, 17, 1, 0, 0, +136, 0, 5, 0, 5, 0, 0, 0, 19, 1, 0, 0, 16, 1, 0, 0, 18, 1, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 20, 1, 0, 0, 3, 1, 0, 0, 129, 0, 5, 0, 5, 0, 0, 0, 21, 1, 0, 0, 19, 1, 0, 0, 20, 1, 0, 0, 62, 0, 3, 0, 13, 1, 0, 0, +21, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 39, 0, 0, 0, 13, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 23, 1, 0, 0, 210, 0, 0, 0, 111, 0, 4, 0, 5, 0, 0, 0, 24, 1, 0, 0, 225, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 25, 1, 0, 0, +13, 1, 0, 0, 12, 0, 8, 0, 5, 0, 0, 0, 26, 1, 0, 0, 193, 0, 0, 0, 49, 0, 0, 0, 23, 1, 0, 0, 24, 1, 0, 0, 25, 1, 0, 0, 62, 0, 3, 0, 22, 1, 0, 0, 26, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 41, 0, 0, 0, 13, 0, 0, 0, +61, 0, 4, 0, 4, 0, 0, 0, 27, 1, 0, 0, 205, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 28, 1, 0, 0, 204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 29, 1, 0, 0, 22, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 30, 1, 0, 0, 29, 1, 0, 0, +29, 1, 0, 0, 29, 1, 0, 0, 29, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 31, 1, 0, 0, 193, 0, 0, 0, 46, 0, 0, 0, 27, 1, 0, 0, 28, 1, 0, 0, 30, 1, 0, 0, 62, 0, 3, 0, 204, 0, 0, 0, 31, 1, 0, 0, 249, 0, 2, 0, 254, 0, 0, 0, +248, 0, 2, 0, 254, 0, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 44, 0, 0, 0, 9, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 32, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 33, 1, 0, 0, +204, 0, 0, 0, 61, 0, 4, 0, 5, 0, 0, 0, 34, 1, 0, 0, 244, 0, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 35, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 34, 1, 0, 0, 12, 0, 8, 0, 4, 0, 0, 0, 36, 1, 0, 0, 193, 0, 0, 0, +46, 0, 0, 0, 32, 1, 0, 0, 33, 1, 0, 0, 35, 1, 0, 0, 62, 0, 3, 0, 203, 0, 0, 0, 36, 1, 0, 0, 8, 0, 4, 0, 179, 0, 0, 0, 46, 0, 0, 0, 9, 0, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 37, 1, 0, 0, 203, 0, 0, 0, 254, 0, 2, 0, +37, 1, 0, 0, 56, 0, 1, 0, 8, 0, 4, 0, 39, 1, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 54, 0, 5, 0, 4, 0, 0, 0, 46, 1, 0, 0, 0, 0, 0, 0, 151, 0, 0, 0, 248, 0, 2, 0, +53, 1, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 58, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 62, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 202, 0, 0, 0, 68, 1, 0, 0, 7, 0, 0, 0, 59, 0, 4, 0, 185, 0, 0, 0, 72, 1, 0, 0, +7, 0, 0, 0, 8, 0, 4, 0, 39, 1, 0, 0, 10, 0, 0, 0, 9, 0, 0, 0, 57, 0, 4, 0, 4, 0, 0, 0, 61, 1, 0, 0, 119, 0, 0, 0, 62, 0, 3, 0, 58, 1, 0, 0, 61, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 66, 1, 0, 0, 86, 1, 0, 0, +93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 67, 1, 0, 0, 66, 1, 0, 0, 62, 0, 3, 0, 62, 1, 0, 0, 67, 1, 0, 0, 80, 0, 7, 0, 4, 0, 0, 0, 71, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 69, 1, 0, 0, 70, 1, 0, 0, 62, 0, 3, 0, +68, 1, 0, 0, 71, 1, 0, 0, 62, 0, 3, 0, 72, 1, 0, 0, 69, 1, 0, 0, 57, 0, 8, 0, 4, 0, 0, 0, 75, 1, 0, 0, 182, 0, 0, 0, 58, 1, 0, 0, 62, 1, 0, 0, 68, 1, 0, 0, 72, 1, 0, 0, 254, 0, 2, 0, 75, 1, 0, 0, 56, 0, 1, 0, +54, 0, 5, 0, 30, 0, 0, 0, 87, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 88, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 89, 1, 0, 0, 86, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 91, 1, 0, 0, 78, 1, 0, 0, +62, 0, 3, 0, 89, 1, 0, 0, 91, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 92, 1, 0, 0, 86, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 94, 1, 0, 0, 80, 1, 0, 0, 62, 0, 3, 0, 92, 1, 0, 0, 94, 1, 0, 0, 57, 0, 4, 0, +30, 0, 0, 0, 95, 1, 0, 0, 118, 0, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 96, 1, 0, 0, 86, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 98, 1, 0, 0, 96, 1, 0, 0, 62, 0, 3, 0, 76, 1, 0, 0, 98, 1, 0, 0, 253, 0, 1, 0, +56, 0, 1, 0, 54, 0, 5, 0, 30, 0, 0, 0, 111, 1, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 248, 0, 2, 0, 112, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 113, 1, 0, 0, 110, 1, 0, 0, 90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 114, 1, 0, 0, +100, 1, 0, 0, 62, 0, 3, 0, 113, 1, 0, 0, 114, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 115, 1, 0, 0, 110, 1, 0, 0, 93, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 116, 1, 0, 0, 103, 1, 0, 0, 62, 0, 3, 0, 115, 1, 0, 0, 116, 1, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 117, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 119, 1, 0, 0, 104, 1, 0, 0, 62, 0, 3, 0, 117, 1, 0, 0, 119, 1, 0, 0, 57, 0, 4, 0, 30, 0, 0, 0, 120, 1, 0, 0, 117, 0, 0, 0, +65, 0, 5, 0, 3, 0, 0, 0, 121, 1, 0, 0, 110, 1, 0, 0, 97, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 122, 1, 0, 0, 121, 1, 0, 0, 62, 0, 3, 0, 99, 1, 0, 0, 122, 1, 0, 0, 65, 0, 5, 0, 74, 0, 0, 0, 123, 1, 0, 0, 110, 1, 0, 0, +90, 1, 0, 0, 61, 0, 4, 0, 42, 0, 0, 0, 124, 1, 0, 0, 123, 1, 0, 0, 62, 0, 3, 0, 101, 1, 0, 0, 124, 1, 0, 0, 65, 0, 5, 0, 3, 0, 0, 0, 125, 1, 0, 0, 110, 1, 0, 0, 118, 1, 0, 0, 61, 0, 4, 0, 4, 0, 0, 0, 126, 1, 0, 0, +125, 1, 0, 0, 62, 0, 3, 0, 105, 1, 0, 0, 126, 1, 0, 0, 253, 0, 1, 0, 56, 0, 1, 0, 0, 15, 0, 0, 0, 86, 83, 77, 97, 105, 110, 95, 87, 114, 97, 112, 112, 101, 114, 0, }; } } From 7c82d1727fa49b211fc28892bb904928c5cbdf35 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 17:38:40 +0900 Subject: [PATCH 1056/1182] test: Renamed CompareGold to Stride.CompareGold (and kill other instance on startup) --- .../tools/{CompareGold => Stride.CompareGold}/Program.cs | 9 +++++++++ .../Stride.CompareGold.csproj} | 0 .../{CompareGold => Stride.CompareGold}/wwwroot/app.js | 0 .../{CompareGold => Stride.CompareGold}/wwwroot/diff.js | 0 .../wwwroot/index.html | 0 .../wwwroot/style.css | 0 tests/GPU-TESTING.md | 2 +- tests/compare-gold.cmd | 2 +- 8 files changed, 11 insertions(+), 2 deletions(-) rename build/tools/{CompareGold => Stride.CompareGold}/Program.cs (98%) rename build/tools/{CompareGold/CompareGold.csproj => Stride.CompareGold/Stride.CompareGold.csproj} (100%) rename build/tools/{CompareGold => Stride.CompareGold}/wwwroot/app.js (100%) rename build/tools/{CompareGold => Stride.CompareGold}/wwwroot/diff.js (100%) rename build/tools/{CompareGold => Stride.CompareGold}/wwwroot/index.html (100%) rename build/tools/{CompareGold => Stride.CompareGold}/wwwroot/style.css (100%) diff --git a/build/tools/CompareGold/Program.cs b/build/tools/Stride.CompareGold/Program.cs similarity index 98% rename from build/tools/CompareGold/Program.cs rename to build/tools/Stride.CompareGold/Program.cs index d7577a863e..818ecca349 100644 --- a/build/tools/CompareGold/Program.cs +++ b/build/tools/Stride.CompareGold/Program.cs @@ -2,6 +2,15 @@ using System.Diagnostics; using System.Text.Json; +// Kill any existing CompareGold process (from any Stride checkout) to free the port +foreach (var proc in Process.GetProcessesByName("Stride.CompareGold")) +{ + if (proc.Id != Environment.ProcessId) + { + try { proc.Kill(); proc.WaitForExit(3000); } catch { } + } +} + var builder = WebApplication.CreateBuilder(args); builder.WebHost.UseUrls("http://localhost:5555"); builder.Services.AddSingleton(); diff --git a/build/tools/CompareGold/CompareGold.csproj b/build/tools/Stride.CompareGold/Stride.CompareGold.csproj similarity index 100% rename from build/tools/CompareGold/CompareGold.csproj rename to build/tools/Stride.CompareGold/Stride.CompareGold.csproj diff --git a/build/tools/CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js similarity index 100% rename from build/tools/CompareGold/wwwroot/app.js rename to build/tools/Stride.CompareGold/wwwroot/app.js diff --git a/build/tools/CompareGold/wwwroot/diff.js b/build/tools/Stride.CompareGold/wwwroot/diff.js similarity index 100% rename from build/tools/CompareGold/wwwroot/diff.js rename to build/tools/Stride.CompareGold/wwwroot/diff.js diff --git a/build/tools/CompareGold/wwwroot/index.html b/build/tools/Stride.CompareGold/wwwroot/index.html similarity index 100% rename from build/tools/CompareGold/wwwroot/index.html rename to build/tools/Stride.CompareGold/wwwroot/index.html diff --git a/build/tools/CompareGold/wwwroot/style.css b/build/tools/Stride.CompareGold/wwwroot/style.css similarity index 100% rename from build/tools/CompareGold/wwwroot/style.css rename to build/tools/Stride.CompareGold/wwwroot/style.css diff --git a/tests/GPU-TESTING.md b/tests/GPU-TESTING.md index 2e32eda0ed..a3b50d3459 100644 --- a/tests/GPU-TESTING.md +++ b/tests/GPU-TESTING.md @@ -48,7 +48,7 @@ A visual comparison tool for reviewing gold image differences: tests\compare-gold.cmd # Or directly: -dotnet run --project build/tools/CompareGold +dotnet run --project build/tools/Stride.CompareGold ``` ### Features diff --git a/tests/compare-gold.cmd b/tests/compare-gold.cmd index d45753a9bb..78b83a545c 100644 --- a/tests/compare-gold.cmd +++ b/tests/compare-gold.cmd @@ -1,2 +1,2 @@ @echo off -dotnet run --project "%~dp0..\build\tools\CompareGold" +dotnet run --project "%~dp0..\build\tools\Stride.CompareGold" From f761901c620f3192da0a5cf6b68349ccd40a5eaa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 17:41:40 +0900 Subject: [PATCH 1057/1182] test: updated gold images --- tests/GPU-TESTING.md | 2 +- .../Linux.Vulkan/SwiftShader/AnimatedModelTests.f3.png | 3 --- .../SwiftShader/SpriteRenderer2DTests.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/SpriteTestGame.png | 3 --- .../SwiftShader/SpriteRenderer2DTests.f1.png | 4 ++-- .../SwiftShader/SpriteRenderer2DTests.png | 0 .../SwiftShader/SpriteRenderer3DTests.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/SpriteTestGame.png | 4 ++-- tests/Stride.Engine.Tests/thresholds.jsonc | 9 +++++++++ .../Linux.Vulkan/SwiftShader/FixedAspectRatioTests.png | 3 --- .../Linux.Vulkan/SwiftShader/TestCustomEffect.png | 3 --- .../Linux.Vulkan/SwiftShader/TestDrawQuad.png | 3 --- .../SwiftShader/TestDynamicSpriteFont.f1.png | 3 --- .../SwiftShader/TestDynamicSpriteFont.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png | 3 --- .../SwiftShader/TestDynamicSpriteFontJapanese.png | 3 --- .../SwiftShader/TestDynamicSpriteFontVarious.f1.png | 3 --- .../SwiftShader/TestDynamicSpriteFontVarious.f2.png | 3 --- .../SwiftShader/TestDynamicSpriteFontVarious.png | 3 --- .../SwiftShader/TestGeometricPrimitives.f1.png | 3 --- .../SwiftShader/TestGeometricPrimitives.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/TestGeometricPrimitives.png | 3 --- .../Linux.Vulkan/SwiftShader/TestImageLoad.png | 3 --- .../SwiftShader/TestLambertPrefilteringSH.png | 3 --- .../Linux.Vulkan/SwiftShader/TestLightShafts.png | 3 --- .../SwiftShader/TestPrecompiledSpriteFont.f1.png | 3 --- .../SwiftShader/TestPrecompiledSpriteFont.f2.png | 3 --- .../SwiftShader/TestPrecompiledSpriteFont.png | 3 --- .../Linux.Vulkan/SwiftShader/TestRenderToTexture.png | 3 --- .../Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/TestSpriteBatch.png | 3 --- .../Linux.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png | 3 --- .../SwiftShader/TestSpriteBatchResolution.f1.png | 3 --- .../SwiftShader/TestSpriteBatchResolution.f2.png | 3 --- .../SwiftShader/TestSpriteBatchResolution.f3.png | 3 --- .../SwiftShader/TestSpriteBatchResolution.png | 3 --- .../SwiftShader/TestSpriteBatchToTexture.png | 3 --- .../Linux.Vulkan/SwiftShader/TestSpriteFontAlignment.png | 3 --- .../Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/TestStaticSpriteFont.png | 3 --- .../SwiftShader/TestTexture.TestLoadDraw(Dds).png | 3 --- .../SwiftShader/TestTexture.TestLoadDraw(Gif).png | 3 --- .../SwiftShader/TestTexture.TestLoadDraw(Png).png | 3 --- .../SwiftShader/TestTexture.TestLoadDraw(Stride).png | 3 --- .../SwiftShader/TestTexture.TestLoadDraw(Tiff).png | 3 --- .../Windows.Direct3D11/WARP/TestLightShafts.png | 4 ++-- .../Windows.Direct3D12/WARP/FixedAspectRatioTests.png | 3 +++ .../WARP/LightingTests.ScenePointLightShadowCubeMap.png | 3 +++ .../WARP/TestGeometricPrimitives.f1.png | 3 +++ .../WARP/TestGeometricPrimitives.f2.png | 3 +++ .../Windows.Direct3D12/WARP/TestGeometricPrimitives.png} | 4 ++-- .../Windows.Direct3D12/WARP/TestLightShafts.png | 3 +++ .../SwiftShader/TestDynamicSpriteFont.f1.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFont.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontJapanese.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontVarious.f1.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontVarious.f2.png | 4 ++-- .../SwiftShader/TestDynamicSpriteFontVarious.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TestImageLoad.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TestLightShafts.png | 4 ++-- .../SwiftShader/TestPrecompiledSpriteFont.f1.png | 4 ++-- .../SwiftShader/TestPrecompiledSpriteFont.f2.png | 4 ++-- .../SwiftShader/TestPrecompiledSpriteFont.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png | 4 ++-- .../SwiftShader/TestSpriteBatchResolution.f2.png | 4 ++-- .../SwiftShader/TestSpriteBatchResolution.png | 4 ++-- .../SwiftShader/TestStaticSpriteFont.f1.png | 4 ++-- .../Linux.Vulkan/SwiftShader/ClickTests.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.f3.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.f4.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.f5.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.f6.png | 3 --- .../Linux.Vulkan/SwiftShader/ClickTests.png | 3 --- .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/ContentDecoratorTest.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f10.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f11.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f3.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f4.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f5.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f6.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f7.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f8.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.f9.png | 3 --- .../Linux.Vulkan/SwiftShader/EditTextTest.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRegionTest.png | 3 --- .../Linux.Vulkan/SwiftShader/ImageRotatedTest.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollViewerTest.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png | 3 --- .../Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png | 3 --- .../Linux.Vulkan/SwiftShader/SliderTest.f1.png | 3 --- .../Linux.Vulkan/SwiftShader/SliderTest.f2.png | 3 --- .../Windows.Vulkan/SwiftShader/ClickTests.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.f5.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.f6.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ClickTests.png | 4 ++-- .../SwiftShader/ContentDecoratorTest.f1.png | 4 ++-- .../SwiftShader/ContentDecoratorTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ContentDecoratorTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png | 4 ++-- .../Windows.Vulkan/SwiftShader/DynamicFontTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f10.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f11.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f12.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f13.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f14.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f5.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f6.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f7.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f8.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.f9.png | 4 ++-- .../Windows.Vulkan/SwiftShader/EditTextTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRegionTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ImageRotatedTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png | 2 +- .../Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollViewerTest.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png | 4 ++-- .../Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png | 4 ++-- .../Windows.Vulkan/SwiftShader/SliderTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/SliderTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f1.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f10.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f11.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f12.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f13.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f14.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f2.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f3.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f4.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f5.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f6.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f7.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f8.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.f9.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockTest.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f1.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f2.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f3.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f4.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f5.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f6.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f7.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f8.png | 4 ++-- .../SwiftShader/TextBlockWrappingTest.f9.png | 4 ++-- .../Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png | 4 ++-- tests/compare-gold.cmd | 2 +- 190 files changed, 221 insertions(+), 446 deletions(-) delete mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/AnimatedModelTests.f3.png delete mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png delete mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png delete mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png delete mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png rename tests/Stride.Engine.Tests/{Linux.Vulkan => Windows.Vulkan}/SwiftShader/SpriteRenderer2DTests.png (100%) delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/FixedAspectRatioTests.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestCustomEffect.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDrawQuad.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestRenderToTexture.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchToTexture.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteFontAlignment.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Gif).png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png delete mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Tiff).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/FixedAspectRatioTests.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png rename tests/{Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png => Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.png} (81%) create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png diff --git a/tests/GPU-TESTING.md b/tests/GPU-TESTING.md index a3b50d3459..2e32eda0ed 100644 --- a/tests/GPU-TESTING.md +++ b/tests/GPU-TESTING.md @@ -48,7 +48,7 @@ A visual comparison tool for reviewing gold image differences: tests\compare-gold.cmd # Or directly: -dotnet run --project build/tools/Stride.CompareGold +dotnet run --project build/tools/CompareGold ``` ### Features diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/AnimatedModelTests.f3.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/AnimatedModelTests.f3.png deleted file mode 100644 index 862463d1a5..0000000000 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/AnimatedModelTests.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:742f089bea8a05fe5a9db6c428a0ec87ee19bd97d34d85f9a74617630b802de3 -size 19948 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png deleted file mode 100644 index fa3a724e16..0000000000 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba89080019d106875c2a6f0bfc7a1bf5211c5a6deea9b5d4870059e84e8f250d -size 302163 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png deleted file mode 100644 index 91246090df..0000000000 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86cb8e2166621d7e754f647c99aa7b41735aef1314a6b297a369abf5b328d8a6 -size 53458 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png deleted file mode 100644 index 32adad4ae1..0000000000 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02ef2c1eb01ae21584226e890f19b92017b5b55e970cdc355a9410051eaffc61 -size 53359 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png b/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png deleted file mode 100644 index a06441836a..0000000000 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteTestGame.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c92ef8c4e0f2af22d9f1e2a57584016e32e16ec7395a08d5594c86fa74f8ad3 -size 60158 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png index 8e10f06b17..fa3a724e16 100644 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:534aa8eef4d5907ffb32eb7474adf51bd17ac48be4033fab301ab585f9b9d082 -size 302020 +oid sha256:ba89080019d106875c2a6f0bfc7a1bf5211c5a6deea9b5d4870059e84e8f250d +size 302163 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png similarity index 100% rename from tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer2DTests.png rename to tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png index c461fc849e..f04bb06bc6 100644 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fc2b79494db4f1aaef5ce2683a3f9d8a9f8bb42b61c4f6a41000aad087a5fd53 -size 227265 +oid sha256:f2575618a54487b56c8bcb4c54aa75a11d750eef42c8d0d6d5e6d145d4e56b9d +size 227263 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png index 65ae327023..91246090df 100644 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba810222211da07cc7abb803c853fb42f1508ef4e7328bf123aaac97cc737f83 -size 53449 +oid sha256:86cb8e2166621d7e754f647c99aa7b41735aef1314a6b297a369abf5b328d8a6 +size 53458 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png index 34cc5d23bd..32adad4ae1 100644 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e225cd861edf140288796623876bc6344daf728054fc050d8276f6ed45e4b811 -size 53349 +oid sha256:02ef2c1eb01ae21584226e890f19b92017b5b55e970cdc355a9410051eaffc61 +size 53359 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png index 7bb03efcf9..a06441836a 100644 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2430e3a6f7d10f24bebb6266fd07d2fe01951b15cc0f87f1c7867e917374d447 -size 60156 +oid sha256:6c92ef8c4e0f2af22d9f1e2a57584016e32e16ec7395a08d5594c86fa74f8ad3 +size 60158 diff --git a/tests/Stride.Engine.Tests/thresholds.jsonc b/tests/Stride.Engine.Tests/thresholds.jsonc index 098d96f8a0..a728175b0d 100644 --- a/tests/Stride.Engine.Tests/thresholds.jsonc +++ b/tests/Stride.Engine.Tests/thresholds.jsonc @@ -17,5 +17,14 @@ "api": "Vulkan", "device": "SwiftShader", "allow": { "3-70": 1, "71+": 0 } + }, + { + // Single pixel at X:347 Y:183 (knight's hand) flickers due to sub-pixel + // rasterization on the geometry edge in SwiftShader on Linux. + "image": "AnimatedModelTests.f3.png", + "platform": "Windows", + "api": "Direct3D12", + "device": "WARP", + "allow": { "3-70": 1, "71+": 0 } } ] diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/FixedAspectRatioTests.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/FixedAspectRatioTests.png deleted file mode 100644 index dd339a103b..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/FixedAspectRatioTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:81afdc6d2e19cc8ad17add402124ce612ff0d9fb600517596d19b7df493645be -size 30254 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestCustomEffect.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestCustomEffect.png deleted file mode 100644 index 491c6a3eba..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestCustomEffect.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ff4d1ee266ba6e55bc3483c87fe9fca68f7424b636d6869cf0d073dbc03ca570 -size 13184 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDrawQuad.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDrawQuad.png deleted file mode 100644 index 9ce9fe8754..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDrawQuad.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7d46ea58f3312c0cd3a2c24430831aaa0556ff736893fc5ca50ccd5c79881297 -size 27654 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png deleted file mode 100644 index 7732ef9946..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e9902492277988d001e53ae3fa51a374b10d029aa37e54155833dc7f3e76be1 -size 60213 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png deleted file mode 100644 index 38d6ddc812..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cefe5766fd77d4130e0e9b84f15d78395579e8a12ffb19e2d5bd68b1dca739cf -size 65940 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png deleted file mode 100644 index e454edbc5d..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2a71157ff1a61364663bd95d27a155aafd0f188a9792df653f4ea5c6d58c9089 -size 59263 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png deleted file mode 100644 index ffbd218fa8..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f93a94cc9ca69583b6b60208e3c84454f8291c8367b301d5234725b461816080 -size 100864 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png deleted file mode 100644 index eca50f67d1..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:092e27e97d83615745ed1ae26f2f5e862633e4a3c223b0b34856137d05456575 -size 18061 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png deleted file mode 100644 index 4540a5267e..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75ed59fab9696a07e066ce4fb37700e09d74c1cdd5812a043babe5448534c4f5 -size 18797 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png deleted file mode 100644 index 3a394b29bc..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c66b33a6f652e04d7d2c9b1cb9cdfd88b3c4641b6de4522c949d4fd62f4b0c3e -size 10151 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png deleted file mode 100644 index d8536f8b37..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7ac8f22a9c7d1de8f7e9c919eb5a5cccfa4f7dd1e2d549b75b9a2de22c6929c -size 85172 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png deleted file mode 100644 index 2fb16b0519..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2fd028ce437e3da0780ffe330632adccac5a365d62998b572602755e93cc125c -size 82306 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.png deleted file mode 100644 index 52de8bb238..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestGeometricPrimitives.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c45922bf3976c87ae5e17a5cc2c12318dd292374f21ef735e0c3acddeb0626fa -size 88288 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png deleted file mode 100644 index ed6121de5b..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestImageLoad.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0cdee621ce660f8d47f6296b65c5ff81a3aa304189515c259d1d8d308cdf25c2 -size 140707 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png deleted file mode 100644 index 594da6f63a..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLambertPrefilteringSH.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4eb5e3e0c7a8f897ac7714494e23cc490017ae1d12899ee1be89afd957410093 -size 101142 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png deleted file mode 100644 index a087a2c6ee..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestLightShafts.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d40cfdb69ef7ae194635940c4c05822bc144edf0401d4c42da39fe2ed986b66e -size 120613 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png deleted file mode 100644 index fc2da95fe5..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dbfe3a50eb5727f069056e81037e33c4f2c68c445d17230d45aa71f2eaaadb68 -size 25572 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png deleted file mode 100644 index c4dc3cd8ef..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:18581a89cfe2bb56b55a42faab12bc89c26043cb60a6b51c2031a33cabb7eb98 -size 31044 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png deleted file mode 100644 index a878cee0f7..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73d23c270d0a53681997832eafd973c8015d5aa7cc3db7e6b27c892a06a3fe12 -size 24965 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestRenderToTexture.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestRenderToTexture.png deleted file mode 100644 index a8ef57208b..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestRenderToTexture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5ce2b4ec89468a8d64c92bf254e93016db63a4777253e2989e7ded41db13e440 -size 56695 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png deleted file mode 100644 index 42733aa510..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6e59633bb5ee32b8566c37db36756d507851871d3adfd30688b850cf415ebc3 -size 129061 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.png deleted file mode 100644 index bce796ef83..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c38ff3685f3b609e77d2f0a0d7f9524df2bb9229f42210567c687caa6430a92 -size 130802 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png deleted file mode 100644 index f37e87404d..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:858cf04a6536ece5919c28b7eac62b4fb4393d381f709122f0aca2159312631f -size 38284 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png deleted file mode 100644 index 9cfbabc050..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatch3D.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4115a649f943acb3fc8745b29fc376adb8d3e29256bfcfe791c7bf109e9a5462 -size 34162 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png deleted file mode 100644 index c8809d75d3..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:320befe65bcdba3bf3db2ca1167aefc2fcd2fae8af5f4cf42d4740d2c056e4e1 -size 20433 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png deleted file mode 100644 index e99b9c0ed6..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b0ae9f8817078e1d15d55efb18b72abfc95e662bae82a290a8f1449e85bc8fb4 -size 80876 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png deleted file mode 100644 index 2b2ab09fbd..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:320d430eba1b5521f9c944ac0ee98f9ec88574c57a896513b6e9cc56075e2164 -size 20697 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png deleted file mode 100644 index 055befbd0f..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchResolution.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a87943f79a7eb95b66ab3a22b14413ba93f86168ac3e72223a499b2cab5593b -size 34997 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchToTexture.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchToTexture.png deleted file mode 100644 index a225496640..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteBatchToTexture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8bd6da663a48f7d2feaceb380e8b46e8f75d7f17d2500910bc50aeba438de535 -size 53542 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteFontAlignment.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteFontAlignment.png deleted file mode 100644 index 89b9c23933..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestSpriteFontAlignment.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d126ef86b9b1fec1c557b38e5188888cce59f9db5286bd9f1cdb07c33b9789ef -size 23002 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png deleted file mode 100644 index 60bd710a45..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:afc288161291c67f074757ebc8a153d9c27ef3922d10ba65add15be68a146768 -size 60468 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png deleted file mode 100644 index cf9f09c361..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:25176f7a396b3c7884b38630ae87b85fa85cc534505a062fb96b5aa8144f6e17 -size 65308 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.png deleted file mode 100644 index c3026fbeaf..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestStaticSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:30d949221b6e96c315767a7bd551283ad06d76d905c59373fbc6d5bf60dd6813 -size 59396 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png deleted file mode 100644 index 1525c56bd4..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9c3e92d54674e58ecb07107077664555ac351f470e441e14ad63fed33c3fe98 -size 76548 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Gif).png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Gif).png deleted file mode 100644 index 85851ffbaf..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Gif).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bec81bb85d89ee549e05f4b7821af0e5f403b2d52ed6f8635c3f8c6e06a02b3e -size 87585 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png deleted file mode 100644 index 8e2f85b0ef..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac5e46614aa9b1b1a7719e408b45ce1dfca045db3739c69547bb122b3d2f7441 -size 107711 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png deleted file mode 100644 index 1525c56bd4..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9c3e92d54674e58ecb07107077664555ac351f470e441e14ad63fed33c3fe98 -size 76548 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Tiff).png b/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Tiff).png deleted file mode 100644 index 2776a7aa1d..0000000000 --- a/tests/Stride.Graphics.Tests/Linux.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Tiff).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1029869b4edaaea203ad97c97f4f6afddabc3cca62ab54f65e879b7f6f473e11 -size 98994 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png index 699571ad26..d70436e0b9 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:762896ba2d913778aeace81bb907fa1bca35b27587751aa17c15d4540e830f9c -size 120791 +oid sha256:de15d7eb940b4a92179ce81da2685b7adc94fbd3aef6371be8bc105d067df80d +size 120790 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/FixedAspectRatioTests.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/FixedAspectRatioTests.png new file mode 100644 index 0000000000..6d381ac9ba --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/FixedAspectRatioTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8fef179bcc56d672f9b6683b544262f55b68b4829cf9ff41b76825d6255f85c4 +size 31085 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png new file mode 100644 index 0000000000..4938a3c7dd --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ac8a3a0dc1cf7f81a376891c987ca13ca1ccadf01d9a3d2ebae463bbf452fb6 +size 228498 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png new file mode 100644 index 0000000000..e0d943558f --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4ea4be5e4688a3913ee2e0a1bd888564384f4444d7f1ad5d9a3fb188ba60d8a +size 85254 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png new file mode 100644 index 0000000000..953b674855 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d0598c82d08ac3fabc1030608e16e87fbe3bd1f8cc163bba99048708358863f +size 82522 diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.png similarity index 81% rename from tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png rename to tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.png index f04bb06bc6..e94c9cc0c0 100644 --- a/tests/Stride.Engine.Tests/Linux.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f2575618a54487b56c8bcb4c54aa75a11d750eef42c8d0d6d5e6d145d4e56b9d -size 227263 +oid sha256:c7c814acad24e26d7d4e97775caef6b11f4915749dc2e014c92d4770c0b50212 +size 88315 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png new file mode 100644 index 0000000000..aab02773b6 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:740a4cadf0b6c530cf74b1057a67076b3e28b34131a915a57b6b40c38f77d45c +size 120674 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png index 6b2fdb39da..7732ef9946 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cda44732103516415b428e6a086274f279141fd7a0e36425c68165cc7a340ce3 -size 59637 +oid sha256:9e9902492277988d001e53ae3fa51a374b10d029aa37e54155833dc7f3e76be1 +size 60213 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png index d4bc96a399..38d6ddc812 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8343c2c0fd3ddb15127087c2b78f03d7dad0caa0dc55d523ee2926f2eb8ddada -size 65352 +oid sha256:cefe5766fd77d4130e0e9b84f15d78395579e8a12ffb19e2d5bd68b1dca739cf +size 65940 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png index 8ca1ab9d33..e454edbc5d 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d994e03f801439bb67e3b3d696eb3a4508e6548b07828330dfa581864ba87b7 -size 58540 +oid sha256:2a71157ff1a61364663bd95d27a155aafd0f188a9792df653f4ea5c6d58c9089 +size 59263 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png index a625e6623e..ffbd218fa8 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93bca12d459cef479b1698e0687a5b0c3409dd790240df5c86de1d31fc6ee0e5 -size 100824 +oid sha256:f93a94cc9ca69583b6b60208e3c84454f8291c8367b301d5234725b461816080 +size 100864 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png index 0113966b6d..eca50f67d1 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f60ccebd0d50ac900a56e26d84becd4a7713babff2ca6ea5f1678b8f65b0be47 -size 17981 +oid sha256:092e27e97d83615745ed1ae26f2f5e862633e4a3c223b0b34856137d05456575 +size 18061 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png index d7226a1993..4540a5267e 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4bf33b87c0ff38ec4b3d04aa24439e43710ca73c683e0baf407d82c77927b89e -size 18591 +oid sha256:75ed59fab9696a07e066ce4fb37700e09d74c1cdd5812a043babe5448534c4f5 +size 18797 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png index 1452785e86..3a394b29bc 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1821dd8fd06789ff6968a6bfe7bf98f3959a85fd1c8844382fc96a5eff8edfab -size 10125 +oid sha256:c66b33a6f652e04d7d2c9b1cb9cdfd88b3c4641b6de4522c949d4fd62f4b0c3e +size 10151 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png index 8f7e66a654..ed6121de5b 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6dc6228ef4fcfdef46af3a8b9e41936b0ab1b9f7f11694fa007659d8eda69009 -size 140602 +oid sha256:0cdee621ce660f8d47f6296b65c5ff81a3aa304189515c259d1d8d308cdf25c2 +size 140707 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png index 3a3167585e..a087a2c6ee 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7639e6ca4ce4ff927e2241117182145b4f8c6da91a9028ea83e649d580e39795 -size 120223 +oid sha256:d40cfdb69ef7ae194635940c4c05822bc144edf0401d4c42da39fe2ed986b66e +size 120613 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png index 2e94f15de9..fc2da95fe5 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:994cd11206f74a5b00a2c04bb6f4988aba173ee108cbe79d8a33e95111dc947b -size 25546 +oid sha256:dbfe3a50eb5727f069056e81037e33c4f2c68c445d17230d45aa71f2eaaadb68 +size 25572 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png index e989e20b27..c4dc3cd8ef 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:651360d30281afea675f5630e374899d17d3da14053cd8029fe7ca3049a7839f -size 31025 +oid sha256:18581a89cfe2bb56b55a42faab12bc89c26043cb60a6b51c2031a33cabb7eb98 +size 31044 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png index 7d39122522..a878cee0f7 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7f559c697491bd05e03f61bfbcd1104dbd84c25ebe7a1f89d4e6bbdce400a26f -size 24942 +oid sha256:73d23c270d0a53681997832eafd973c8015d5aa7cc3db7e6b27c892a06a3fe12 +size 24965 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png index 4f56882903..42733aa510 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cdc6387eb49c9b64c2706bfab8ce4682f7e40f7e220f19d1fc83e88948c5b842 -size 129055 +oid sha256:d6e59633bb5ee32b8566c37db36756d507851871d3adfd30688b850cf415ebc3 +size 129061 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png index c0ba9f64b8..9cfbabc050 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ee03afd20d1085488a7b7cd02e8066086d6cb5c95d522cc1a5d00a79ecc5bd3 -size 34138 +oid sha256:4115a649f943acb3fc8745b29fc376adb8d3e29256bfcfe791c7bf109e9a5462 +size 34162 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png index ec4e8e9ba3..e99b9c0ed6 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c73ea2e71afe4d841b31cce044dcb370df2cd3852167106471e135b96b3a39d -size 80543 +oid sha256:b0ae9f8817078e1d15d55efb18b72abfc95e662bae82a290a8f1449e85bc8fb4 +size 80876 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png index e233584161..055befbd0f 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c9e9810799b4690ee4ed31d4ee35b5f410a8b0976d5c5aaa5c6282e5a7c6497 -size 34968 +oid sha256:8a87943f79a7eb95b66ab3a22b14413ba93f86168ac3e72223a499b2cab5593b +size 34997 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png index ad5934ff1f..60bd710a45 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a82831dd932dbd2712e8cb4b60f57b69846614b0de564e2cac1351a66a87211c -size 60450 +oid sha256:afc288161291c67f074757ebc8a153d9c27ef3922d10ba65add15be68a146768 +size 60468 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png deleted file mode 100644 index 43bb575b16..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8cb5e7f07920fd993eb1db8c2dff44a5439c57ebb03632d4300308f9e5c9c545 -size 36138 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png deleted file mode 100644 index b8db6a1472..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f9a08617f4acf70b76d3a9fabe6f00f2f1a322e99065f527b351f5411280ea8c -size 36088 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png deleted file mode 100644 index d2759bf941..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1aabfcb969386e07cd0dd809e2f2650f139e767bb87f619369571821c12b5924 -size 37377 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png deleted file mode 100644 index 3d4826c3f0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02bf63222918c69a57852c4b2a57f3927059d76df6c53ae7e94fddd4c7efafd5 -size 32278 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png deleted file mode 100644 index a84b4a94c2..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce018e0b0c9024183ba02b6c88983a9ee6da378d70039fca9352574bd268de40 -size 39422 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png deleted file mode 100644 index 72a80b2398..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb31f17474a381a4abfc412289061c723bf0c63c71b6f48402921be1e249a930 -size 38232 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png deleted file mode 100644 index 996d3191e6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClickTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5d69f07b2d0d27c17def6287e607feb88f7f266636e41b821a354a0d312a505 -size 35979 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png deleted file mode 100644 index e67728e09f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ef833d3a35bd1864eac795e9cefe41105138f9f71259885e62eacedaddbfbce7 -size 3432 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png deleted file mode 100644 index d8b52ec3c2..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:666b97df810f96cf58b19653ade33eeeb918caa496e5f87debbdc0577b912a9a -size 3731 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png deleted file mode 100644 index c2c4e0810e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ContentDecoratorTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f3721d78f8212d61c4bbe4954221213b1e21e9f1819971db2631e64c113abc5 -size 3058 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png deleted file mode 100644 index c552952d71..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0339361bb7dbfa7fee8ba722554327fbbd327e41d3a92198cb02d50409631298 -size 7553 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png deleted file mode 100644 index 05a3701728..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:be32fcdb528804acb3a486873d2cabdd28171f96a21068af70be1223a32f4d28 -size 8461 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png deleted file mode 100644 index 0d6ef1f0f6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:065dc953193b989c6fef22e79c98482b79f8d9af3d816f303ac5e23ed1c0ff25 -size 8463 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png deleted file mode 100644 index d37c9273a0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4edb69ec532277ce8056ce44f1f6800e728bf1b6fba418b23c566b4134e297e -size 7731 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png deleted file mode 100644 index cca3ceaf8a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:52ddb7a70cac86cbdbfab171de0d332733b72ff9a8844ecbc25bfabe4ae5dab4 -size 7725 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png deleted file mode 100644 index 4615b9a0c0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:301692b58dddcfac3bee52f6a57e65481c20b296b792fbfe6bbd1b4efeb03fb0 -size 7974 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png deleted file mode 100644 index dc95ed93b8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:67539bde2e6455d14aeb98835be42d2fd2af3c003a0eb770dbf69ac7d6a29771 -size 8042 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png deleted file mode 100644 index 0786bfe43e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90d2a27d78dd648e2c387848d79aa289c5ad15232a598a980819bc4302919e6c -size 8052 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png deleted file mode 100644 index 77967ada36..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:243972c80df061fef5d04a50073966b718f3fa9cb00d27815455e0a78c89d987 -size 6489 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png deleted file mode 100644 index 3fe3fc416b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:32908a4dac1d9cd83ea586879b5812dd7eed8cdc6f470f6a043b9042835f24db -size 8462 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png deleted file mode 100644 index 54eb29de34..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f306a923f27ebceeefa29226ce24d81e0c12e6ca63b4f8f8225c3de3fda2cd3e -size 8468 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png deleted file mode 100644 index 6a648bcb55..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/EditTextTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44643121343000108e1b56beb8a7147dac4af66a23551853c5c4cf6258e17e06 -size 7550 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png deleted file mode 100644 index 5c92293e86..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:669c472bf70fb009aedd44e20e07f2b36bc3c533aea3cdd8d8efae93ffef6eb3 -size 9504 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png deleted file mode 100644 index ebc3598cb8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af7dcdfae006d3737b2b7e3441b9167d2cf2f6359cd79d74f1809441b5765380 -size 11655 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png deleted file mode 100644 index 5a783f0be7..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b8524568f2d72307ff224a3479b4bf4ce1ad1a4929d4087579e29b87d64d133 -size 9703 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png deleted file mode 100644 index 30183bbe88..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1de96b5b6103793ee5b04e308aaaa7d306ba2ddb14f36020d8948079a8fd4d8e -size 10042 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png deleted file mode 100644 index d98671718b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRegionTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83fcfe62fc4bacd5bd6e6196f38a3fbd9b55e365ab9d56ed67514b03c4c22e8b -size 36308 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png deleted file mode 100644 index a0a1af6c14..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageRotatedTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ee5fc13b7e5ba9351176055b7530f56e7870e6f41bf508b33ac6621b943b47d -size 388855 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png deleted file mode 100644 index 372a6df521..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:982dee31eebd541e013eeb7419b68e8aa57da6a6c0328b7e844b407641f911aa -size 16043 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png deleted file mode 100644 index 968160a212..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c5187ee66519fa61b162567fb2092a7d042b43df94a1291ad4e8ff3560fcdb0 -size 16027 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png deleted file mode 100644 index a4e24e232c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f14.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c974cd3104b4b2ccd4ffc8197b25f26e14852922c29589d5d82fcbb5c7536317 -size 17807 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png deleted file mode 100644 index ca0ccb985c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46b307aed2c00a89bfe478edc02f9992294226ce668b00da004e77ab3fd3d3d1 -size 16630 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png deleted file mode 100644 index 23fb1be543..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff -size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png deleted file mode 100644 index ca8a617607..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:03f22a166e20bd200f8ae58067c3879e612da463749caf6c97cbbcc5af24bb6d -size 2760 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png deleted file mode 100644 index 23fb1be543..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff -size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png deleted file mode 100644 index c547da862f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7cade8d4ac33fb838549cd92049397c4ec61357dacf63a3f333faacfdfb7d5b -size 2413 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png deleted file mode 100644 index 6d946ffb39..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d9e78c0783d9949fb0313a728701b274d28f6cd18d0c97a79faac685fe63cad -size 2969 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png deleted file mode 100644 index 9357f712ee..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollingTextTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9abb3d93cc2888794a375c0afa63c4a7c2be25fc6207726714c4ecfe4f850b52 -size 2922 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png deleted file mode 100644 index 4ef6060c15..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:483c651ef70c62fb0ef7fd4001f888b3c1e1c3f0a6ffeb340f041623138a708a -size 11769 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png deleted file mode 100644 index 0caf40524c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af786b3b910edf96d6779b7db4d2721b333116c837ae70f32c8897143daaba27 -size 11256 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png index ffa6bad264..43bb575b16 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00ee3e05aae92660489ae750cf31aa9d4a5663f254704d5e031e3d54ed2c1170 -size 35956 +oid sha256:8cb5e7f07920fd993eb1db8c2dff44a5439c57ebb03632d4300308f9e5c9c545 +size 36138 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png index aa9ddd89d9..b8db6a1472 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e101b0849a0b199040df2f6fc3884d91a22815ae02407e3102af7448317ea70c -size 35899 +oid sha256:f9a08617f4acf70b76d3a9fabe6f00f2f1a322e99065f527b351f5411280ea8c +size 36088 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png index 2a4d8df806..d2759bf941 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e99be63b211990d91cca0ec0eb3c9126fe43e4897025c983ee9bc8091c8bb1c5 -size 37267 +oid sha256:1aabfcb969386e07cd0dd809e2f2650f139e767bb87f619369571821c12b5924 +size 37377 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png index abc007ab0c..3d4826c3f0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:772d9b6bc3f402d4dcf5b010ec825354b2e75a9d74565058aa725bbb8a22d05a -size 32196 +oid sha256:02bf63222918c69a57852c4b2a57f3927059d76df6c53ae7e94fddd4c7efafd5 +size 32278 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png index 640418a6e8..a84b4a94c2 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c53edb916da3596cd7e1c57c777635015010b15def8cb1042b5451e01a32c96b -size 39270 +oid sha256:ce018e0b0c9024183ba02b6c88983a9ee6da378d70039fca9352574bd268de40 +size 39422 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png index 20e2cdee27..72a80b2398 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67d291ad9d314d43b598876cb86f1fb627c69ea7358acce11568600b8f61310c -size 38105 +oid sha256:cb31f17474a381a4abfc412289061c723bf0c63c71b6f48402921be1e249a930 +size 38232 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png index 5a8851ba4f..996d3191e6 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cfa42e9ded86e1982801806740ac90cee77da6275eaebee028cac4c6c0de53b -size 35817 +oid sha256:c5d69f07b2d0d27c17def6287e607feb88f7f266636e41b821a354a0d312a505 +size 35979 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png index 4c23dc2d39..e67728e09f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c08381ac7e01855202137b564647e544b00944d33fb2940f385a7d276094331b -size 3377 +oid sha256:ef833d3a35bd1864eac795e9cefe41105138f9f71259885e62eacedaddbfbce7 +size 3432 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png index 25d7b9fa6f..d8b52ec3c2 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:430072d31620d1c647716baa00b68957e11bca9040ce1277557fc325628a8d46 -size 3640 +oid sha256:666b97df810f96cf58b19653ade33eeeb918caa496e5f87debbdc0577b912a9a +size 3731 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png index 697b83bead..c2c4e0810e 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0233db506576d3bfaa968fd3a25a0bf53278738d74a3ffc4652fc4e9401dbe5e -size 2969 +oid sha256:3f3721d78f8212d61c4bbe4954221213b1e21e9f1819971db2631e64c113abc5 +size 3058 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png index e3346cf05a..b8825b6db4 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6bc3ffce180e6c0c28b4a8f88b02076736d9db44e7e2bb14fb3404b885e0caa -size 4065 +oid sha256:20b34c618fed7392fafd7742c891756356095a48a727beae15d50d98e24bf805 +size 4017 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png index e3346cf05a..b8825b6db4 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6bc3ffce180e6c0c28b4a8f88b02076736d9db44e7e2bb14fb3404b885e0caa -size 4065 +oid sha256:20b34c618fed7392fafd7742c891756356095a48a727beae15d50d98e24bf805 +size 4017 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png index 65bada2992..410a3d75d9 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45774ecadf41532224f6d58f8e5dab65e861eabc23d013fab6f83e251ae27da9 -size 6818 +oid sha256:8a37556b07ea144e30d4ec43bc1942da1f041f2cb3d591935934dff6cd9efe86 +size 6887 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png index 6a3c0bb6c7..c959a8c96b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0562294e410c09924b144e02060c0abcc3129889469e9dbdf57d617ade6263b1 -size 3953 +oid sha256:ccd5f14345dd14634d4edc3673c88ec3fa1246d602f78b6a342c750b929c1a2a +size 4024 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png index 2c5f50c99e..12a6b0e3b2 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5dd092e0a6ac80d68a51dd3cebad963ec4b812700c1ad4c66ee4c971dc1ddcab -size 4110 +oid sha256:0665d97aa62bfc25e442a6efc6d326b404d243978dc26608e7a55caec3fa99ae +size 4099 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png index 899ffc2dd1..e83675a6c4 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77619319f9427b24bc3e39ed7e48a6917b5f82612a57a9c828b68cc090a7b0ca -size 3118 +oid sha256:34305feba0ec4fae52b3fba0ac6e5b74ea187b35d6a20505c66fe6beae679e30 +size 3203 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png index bdc0513914..c552952d71 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98111f6e7f200448f64361754c307ade61d932fe96a18d673460515a9c3d10c9 -size 7515 +oid sha256:0339361bb7dbfa7fee8ba722554327fbbd327e41d3a92198cb02d50409631298 +size 7553 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png index 2a69febdfa..05a3701728 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fa36139859cb52f90ef4a82c6f283e3c0cfaeca8d63accc4ff1ed62af5030e23 -size 8359 +oid sha256:be32fcdb528804acb3a486873d2cabdd28171f96a21068af70be1223a32f4d28 +size 8461 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png index 4484ca07e1..0d6ef1f0f6 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9846de81d881814f86562b80f799ffdef491105343e0d1fdbaf5798eff31e5c9 -size 8358 +oid sha256:065dc953193b989c6fef22e79c98482b79f8d9af3d816f303ac5e23ed1c0ff25 +size 8463 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png index 7df21f198d..dbe681f1d0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b01893dee26986257e89bb99fff00d30d8eca4420e1c6a5ad7850320d4cc8af -size 8349 +oid sha256:1ac3c9dfd59a874a091235c76fdbd66b17109e5fe3793278ca5b51ba0f5d0e3a +size 8453 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png index c2f6f01175..e85b7daf48 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d21238c3590780df9d3f261bf8c7486975ef9114f582977358bfdcb6d557843 -size 8433 +oid sha256:cb488a5ec9a769042aa2a9f83efe3f13c2227557638e2454cea46df8ad903e6a +size 8537 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png index eb07b90261..d050e3379d 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:583965b89c61f736d9beddfd00fa18651d9547784dc4f575581937326762881b -size 8446 +oid sha256:e76163efb8bf87d49af98f09bcee0c953e51285b4448a95e83b0506ec92633ed +size 8552 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png index 416dea5e52..d37c9273a0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:31148c4ba2502b60cdec70e98af1ce0e54502b87e6e684de820d6dbc04a9f88e -size 7673 +oid sha256:c4edb69ec532277ce8056ce44f1f6800e728bf1b6fba418b23c566b4134e297e +size 7731 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png index c0c454bae3..cca3ceaf8a 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83d4cdea63a34e65451f1fb0f50a5b094edae49a38e883e476d5b9b5fcaffea2 -size 7666 +oid sha256:52ddb7a70cac86cbdbfab171de0d332733b72ff9a8844ecbc25bfabe4ae5dab4 +size 7725 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png index d5cb0f1d0e..4615b9a0c0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f39004a8ee7f375b849190167a13c1bad64d681dc89a4d9ae97739bdd3c38a3a -size 7877 +oid sha256:301692b58dddcfac3bee52f6a57e65481c20b296b792fbfe6bbd1b4efeb03fb0 +size 7974 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png index e81e9dc7a2..dc95ed93b8 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5ed7e7cc597405b8c401401dfd664991763997a21dc773cc31816713a786cf5 -size 7939 +oid sha256:67539bde2e6455d14aeb98835be42d2fd2af3c003a0eb770dbf69ac7d6a29771 +size 8042 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png index e923c91b2f..0786bfe43e 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6ee2c2e13083e5d4d8c959473d9871da7c5112b3888e3ec0cdb7329f4a2eb10d -size 7947 +oid sha256:90d2a27d78dd648e2c387848d79aa289c5ad15232a598a980819bc4302919e6c +size 8052 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png index 6675611746..77967ada36 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c27bb4562efc780d50b20619cedc3707fe722a11f5800531acc08d953f77b235 -size 6386 +oid sha256:243972c80df061fef5d04a50073966b718f3fa9cb00d27815455e0a78c89d987 +size 6489 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png index 0d26ded113..3fe3fc416b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:356c0c40794d03c470d2f14e964f763d9f5e46b0278af55f1822a1abafb66a35 -size 8355 +oid sha256:32908a4dac1d9cd83ea586879b5812dd7eed8cdc6f470f6a043b9042835f24db +size 8462 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png index 694954e810..54eb29de34 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f013cb52baab8551ae6123a860bc2a0195bb2bb4120b8ae2bc7820f9e326dc5c -size 8370 +oid sha256:f306a923f27ebceeefa29226ce24d81e0c12e6ca63b4f8f8225c3de3fda2cd3e +size 8468 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png index 6892732fa9..6a648bcb55 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1e68f1349020cc274ba6810f1407847318cae83204b8141eeed21108d11a2508 -size 7512 +oid sha256:44643121343000108e1b56beb8a7147dac4af66a23551853c5c4cf6258e17e06 +size 7550 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png index ac4c45919b..5c92293e86 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c03e4451163d5c2a7e9b1d395f416a7b8158033cbcfd9192156317d3b924b262 -size 9502 +oid sha256:669c472bf70fb009aedd44e20e07f2b36bc3c533aea3cdd8d8efae93ffef6eb3 +size 9504 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png index bf5040f48c..ebc3598cb8 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:82e18a35416c33fa199af5d3e966a5f8fb9d0abbac11fea72ad593baa739bb71 -size 11652 +oid sha256:af7dcdfae006d3737b2b7e3441b9167d2cf2f6359cd79d74f1809441b5765380 +size 11655 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png index 66aff9fb68..5a783f0be7 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6debf7e26efd54c5bf28329a73a8f686d4abb20d1bba78a635cc3b11e5b7743b -size 9693 +oid sha256:4b8524568f2d72307ff224a3479b4bf4ce1ad1a4929d4087579e29b87d64d133 +size 9703 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png index dd26beb140..30183bbe88 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ae4eb6a8b9b8b864c6701871b06f0ed910fc993141c21d82e3a3d206e9752b4 -size 10039 +oid sha256:1de96b5b6103793ee5b04e308aaaa7d306ba2ddb14f36020d8948079a8fd4d8e +size 10042 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png index 9d0cdc8ac6..d98671718b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:258a14fde3f51b1d59398b10ee78c02d32ec52e2253c8b91c2896f65a7b8e355 -size 36330 +oid sha256:83fcfe62fc4bacd5bd6e6196f38a3fbd9b55e365ab9d56ed67514b03c4c22e8b +size 36308 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png index e9c283be4d..a0a1af6c14 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6221858c3cc24f669183e1b384b67c90ed317a28bcba066723977d128ff79958 -size 388719 +oid sha256:2ee5fc13b7e5ba9351176055b7530f56e7870e6f41bf508b33ac6621b943b47d +size 388855 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png index 2d3a785ae6..372a6df521 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:765dfe0a149a2f8edb8e2dda145d42a4153c61f0636f34e5d7c7566386b1f972 -size 16044 +oid sha256:982dee31eebd541e013eeb7419b68e8aa57da6a6c0328b7e844b407641f911aa +size 16043 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png index b25f8a2115..968160a212 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:679c5316c1779cca525b130f6ad97ca0dd2006f12b7d5a73c226db71379931db +oid sha256:2c5187ee66519fa61b162567fb2092a7d042b43df94a1291ad4e8ff3560fcdb0 size 16027 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png index 78df0c52c9..a4e24e232c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2ad28c45ad37ca9817b277f78287fd37ca8b2dca61896c2059bff92f77216450 -size 17812 +oid sha256:c974cd3104b4b2ccd4ffc8197b25f26e14852922c29589d5d82fcbb5c7536317 +size 17807 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png index 6363bf8a81..ca0ccb985c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:122fdd75c122593e0bdc84c6f54193408769831ced932b47640f1b5adc0aac28 -size 16634 +oid sha256:46b307aed2c00a89bfe478edc02f9992294226ce668b00da004e77ab3fd3d3d1 +size 16630 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png index f7872febd7..23fb1be543 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb658fe42bbaf6bd3c33d818d8deb702c88931e226eaec76ba607a474cd128ff -size 2797 +oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff +size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png index 92432c069f..ca8a617607 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10ed8a7e54963242c106a7e41edba8593815db15445fb8d0d1faf63093eba251 -size 2774 +oid sha256:03f22a166e20bd200f8ae58067c3879e612da463749caf6c97cbbcc5af24bb6d +size 2760 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png index f7872febd7..23fb1be543 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb658fe42bbaf6bd3c33d818d8deb702c88931e226eaec76ba607a474cd128ff -size 2797 +oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff +size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png index a2beabfb6a..c547da862f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2171ed0ce53645cebfd1363f4899dc7f90f3468f7921a87149f7e01259a149e8 -size 2422 +oid sha256:b7cade8d4ac33fb838549cd92049397c4ec61357dacf63a3f333faacfdfb7d5b +size 2413 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png index bcaee6f5de..6d946ffb39 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2327757ba7d77ed66bc245f7535c3d4fb849e2c285709bdf66b4b52dac06b160 -size 2949 +oid sha256:9d9e78c0783d9949fb0313a728701b274d28f6cd18d0c97a79faac685fe63cad +size 2969 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png index 1d3b37a99f..9357f712ee 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fe752b8de446e201a704b31217991f6d076389f56e9e711ba23c5b9fc3e73b8 -size 2897 +oid sha256:9abb3d93cc2888794a375c0afa63c4a7c2be25fc6207726714c4ecfe4f850b52 +size 2922 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png index 80d6ef9e56..4ef6060c15 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:479c17540efb01bcd701c284ff129508b5e8f92f16a2b4d01214802688651ff6 -size 11773 +oid sha256:483c651ef70c62fb0ef7fd4001f888b3c1e1c3f0a6ffeb340f041623138a708a +size 11769 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png index 4ae8cb213c..0caf40524c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6727f45358b45067a115cae3503eeb045751fdc9eeed37257c071c695be6fc2f -size 11259 +oid sha256:af786b3b910edf96d6779b7db4d2721b333116c837ae70f32c8897143daaba27 +size 11256 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png index 267f2cc1d7..8e5e5bdff3 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8cbca36c272d623bb8f7564eba04e8a137bba27e9a84617109bff46f591e3344 -size 5064 +oid sha256:57ed9695175b3af83edb92e764b753cbb040b56fd3c18ad3428d55f411fef490 +size 5249 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png index 7aec3ed24f..5214d9ef04 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dba716c7c6042eb8f9ed7d4c17546fd1d2e6f89c615c32c9b4755b540c3ec9cf -size 5177 +oid sha256:5268b55759ce00309235db4a1e00bf359010603bf1cc70f47a8a73e7a8ed9948 +size 5356 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png index e429839119..bf608ec850 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91fdc0a2e29e4367df8af065d25f685ab5e444a1cbe9a1cb8a49353f9241f415 -size 8316 +oid sha256:9679cb29860a83d68134af2f04ad3bee0ac33effcdc0c702b6f6e00de6e9c7f9 +size 8342 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png index 3df2b8b367..363529de09 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9d1a98e572aba86f17bf64e773ba525afa0dc9122ccce12245f33ea31139991 -size 3568 +oid sha256:c4b83b04aa7b927c77838df9c37c7140c90c996c2087ec853b53184f04171b1e +size 3656 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png index e429839119..bf608ec850 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:91fdc0a2e29e4367df8af065d25f685ab5e444a1cbe9a1cb8a49353f9241f415 -size 8316 +oid sha256:9679cb29860a83d68134af2f04ad3bee0ac33effcdc0c702b6f6e00de6e9c7f9 +size 8342 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png index 3df2b8b367..363529de09 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9d1a98e572aba86f17bf64e773ba525afa0dc9122ccce12245f33ea31139991 -size 3568 +oid sha256:c4b83b04aa7b927c77838df9c37c7140c90c996c2087ec853b53184f04171b1e +size 3656 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png index 5198d08a93..5486e76326 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dd102edfbf0b8a25a08eaa74d6dec7a96231e90392e63327c4593e59c53e23d -size 5035 +oid sha256:4ea2de02d1c264927e21e605e429d089cdfe5d645b63448fd72b7d1598fdf310 +size 5209 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png index ad3ad102b3..511d689c7f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9cb75b5c289884023a8bce3e13d83d1d7bde11e25417ba94d4535d35f94f8f27 -size 5107 +oid sha256:4e40285703c9b1d6837a6d688e5c7ef3d938a6985b31cf10a75e19201db697ae +size 5288 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png index 367cfdba56..e496e68cf5 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe4207bd782cb3597274c01ca087ea896fd39efe02e0a5979ff64768a4ec5254 -size 5107 +oid sha256:9c541acc9eeeabc9876ec9aa530cae01c041c0c33c380973c19aa07d51ee7c40 +size 5288 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png index 8439ea021b..b345bf1a90 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00d62f28a6d86687c244f29b8003d0aaa2ec3e8ed72fa3d28466c6b5a5af716c -size 5113 +oid sha256:71f455aacf5b0c0d3230a24ad2642f62197cd874dacbec6227f9eb92e434dd80 +size 5294 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png index 3c1fb75ce6..be5458325c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e39928b801a8b0c5b684b3c5db994c6723e47f291ae45c8f1214ecdef6c067a6 -size 5156 +oid sha256:a47e3be6a383a0c56491687de1d87087d1078dc350d6c65f1c438b7b771137e3 +size 5330 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png index 85af66768d..8b5b309e01 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4b45ec639012993551ac4c0249331eb3a71439681956ac03cea6bfebde00d47e -size 5128 +oid sha256:103c0b16acfbb9ea57846a58ab483febc680067ef3bdeaefaadb2bed28844c85 +size 5308 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png index 6449d647d9..283b823c85 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2d61f7fbf79b1b356d3d06d7da57b7d0d002fa258368d7a6e584ba042021d36b -size 5168 +oid sha256:8762ec4292f71e06d6a1e006dde6b905b652155d4a630b75c55271ee5884e65f +size 5352 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png index 0303821170..d42ad62cd6 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7abcd35b2ffb68032a55e3eeefe710cba724d41518eed6b69c561bb39829eadb -size 5163 +oid sha256:2d35e0ad3b8b4bc9657bab5e425587c9df2e766d5aeb7b0bd7ac129eac583bbe +size 5349 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png index cabdc22adb..846bdc11d3 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b5e7d58cf9feef8c271ee75612474d10756f7a2acd57dd66dea1f9af997d87e2 -size 5101 +oid sha256:85527a1062b9a7e43bc41a77b1305b9eb760fb51d74d28212bc88fd66a48a50e +size 5281 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png index b1f8314eec..26dc75d616 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f88c7e65d707e6ee987b95beb4e8727e617d842821720504e40e1a0f6ba0925a -size 9590 +oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png index 258d4c7662..6cf047c5e1 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:065aa0c57a7a528cb8741d77fe82e8011ab4bd02e39fe42c10068a7efd655acd -size 9584 +oid sha256:fdc90a82cbf25a71057acff68ba217043fe41ac5ce621e27327a7af57718ab1a +size 9890 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png index 46df8167f8..3f0b0bcdbd 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ce7f26d07efc4e315be74b02bfacab458b3e6b49c483bdd934255156cb274dd -size 9595 +oid sha256:899cfa2f035f4569b2d0f3f17c280bbae3ebb88b3bdd26bf9f880efabe4c6d52 +size 9899 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png index b1f8314eec..26dc75d616 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f88c7e65d707e6ee987b95beb4e8727e617d842821720504e40e1a0f6ba0925a -size 9590 +oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png index b1f8314eec..26dc75d616 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f88c7e65d707e6ee987b95beb4e8727e617d842821720504e40e1a0f6ba0925a -size 9590 +oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png index b1f8314eec..26dc75d616 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f88c7e65d707e6ee987b95beb4e8727e617d842821720504e40e1a0f6ba0925a -size 9590 +oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png index b1f8314eec..26dc75d616 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f88c7e65d707e6ee987b95beb4e8727e617d842821720504e40e1a0f6ba0925a -size 9590 +oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png index 6bc9d97ea7..3d85b23e3c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e70a87206a3a20431db7629e9b4b68d930e9a0b6f6185d0138ac45ab9d98e801 -size 9585 +oid sha256:a44df91e96732871fe93539475c86cd8cab1bb4fe2981c9661d5f18bdbe0252f +size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png index 98bf11871b..4e98909946 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:00db7ced1da58c02aaf05fda8ee85accc223558e1cac523c26cb69dfdbfba0af -size 9579 +oid sha256:a9b9a7ea7926e4c6c6fb6931149a66764d24ac7147ebedad94f7a1674c7ab378 +size 9889 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png index 6a8cb5d6ef..a57a226519 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc9ae9bd6716d3f0efe29b0ca927d95662b9a52b9c224e673a4d75cdd36694ff -size 8020 +oid sha256:5b538103eeefc5ce32ece5a7a31bb1723d50d8b6f102169dc4219bcde994854c +size 8365 diff --git a/tests/compare-gold.cmd b/tests/compare-gold.cmd index 78b83a545c..d45753a9bb 100644 --- a/tests/compare-gold.cmd +++ b/tests/compare-gold.cmd @@ -1,2 +1,2 @@ @echo off -dotnet run --project "%~dp0..\build\tools\Stride.CompareGold" +dotnet run --project "%~dp0..\build\tools\CompareGold" From 8c33a2e3d5071dccf6feb646c4c83069820fadaa Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 15 Apr 2026 18:50:27 +0900 Subject: [PATCH 1058/1182] ci: gold image tool propose better gold fallback --- build/tools/Stride.CompareGold/Program.cs | 44 +++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/build/tools/Stride.CompareGold/Program.cs b/build/tools/Stride.CompareGold/Program.cs index 818ecca349..a848e04c98 100644 --- a/build/tools/Stride.CompareGold/Program.cs +++ b/build/tools/Stride.CompareGold/Program.cs @@ -115,8 +115,10 @@ var primarySet = new HashSet(primary); // Find fallback gold from other platforms (matching test framework behavior) - var seen = new HashSet(primarySet); - var fallbacks = new List(); + // Prefer: same API + same renderer class > same API > same class > any + var requestedApi = parts[0]; + var requestedIsSw = IsSoftwareRenderer(parts[1]); + var fallbackBest = new Dictionary(); var suiteDir = Path.Combine(testsDir, suite); if (Directory.Exists(suiteDir)) { @@ -126,17 +128,23 @@ if (pName == "local") continue; foreach (var dDir in Directory.GetDirectories(pDir)) { - var fallbackPlatform = $"{pName}/{Path.GetFileName(dDir)}"; + var device = Path.GetFileName(dDir); + var fallbackPlatform = $"{pName}/{device}"; if (fallbackPlatform == platform) continue; + int score = 0; + if (pName == requestedApi) score += 2; + if (IsSoftwareRenderer(device) == requestedIsSw) score += 1; foreach (var f in Directory.GetFiles(dDir, "*.png")) { var name = Path.GetFileName(f); - if (seen.Add(name)) - fallbacks.Add(new { Name = name, FallbackPlatform = fallbackPlatform }); + if (primarySet.Contains(name)) continue; + if (!fallbackBest.TryGetValue(name, out var existing) || score > existing.score) + fallbackBest[name] = (fallbackPlatform, score); } } } } + var fallbacks = fallbackBest.Select(kv => (object)new { Name = kv.Key, FallbackPlatform = kv.Value.platform }).ToList(); return Results.Ok(new { @@ -153,15 +161,31 @@ var filePath = Path.Combine(testsDir, suite, parts[0], parts[1], name); if (File.Exists(filePath)) return Results.File(filePath, "image/png"); - // Fallback: search all platforms in this suite + // Fallback: search all platforms in this suite, preferring closest match var suiteDir = Path.Combine(testsDir, suite); if (Directory.Exists(suiteDir)) + { + var requestedIsSw = IsSoftwareRenderer(parts[1]); + var requestedApi = parts[0]; // e.g. "Windows.Direct3D11" + string? bestPath = null; + int bestScore = -1; foreach (var pDir in Directory.GetDirectories(suiteDir)) + { + var pName = Path.GetFileName(pDir); + if (pName == "local") continue; foreach (var dDir in Directory.GetDirectories(pDir)) { var candidate = Path.Combine(dDir, name); - if (File.Exists(candidate)) return Results.File(candidate, "image/png"); + if (!File.Exists(candidate)) continue; + var device = Path.GetFileName(dDir); + int score = 0; + if (pName == requestedApi) score += 2; // same API + if (IsSoftwareRenderer(device) == requestedIsSw) score += 1; // same renderer class + if (score > bestScore) { bestScore = score; bestPath = candidate; } } + } + if (bestPath != null) return Results.File(bestPath, "image/png"); + } return Results.NotFound(); }); @@ -434,6 +458,12 @@ static List ListPngs(string dir) } +static bool IsSoftwareRenderer(string device) +{ + var d = device.ToLowerInvariant(); + return d.Contains("warp") || d.Contains("swiftshader"); +} + static IResult ServeImage(string baseDir, string suite, string platform, string name) { var parts = platform.Split('/', 2); From 5dd66a513d455511ac04496280b5ff7a3ffc5e63 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 09:40:39 +0900 Subject: [PATCH 1059/1182] tools: CompareGold improvements - Gold fallback prefers SW renderer when source is SW - Gold dropdown options colored green/red based on threshold check - Add fixable detection: hint when alternate gold would pass - Add Select Fixable button and Delete Gold action - Add /api/gold/delete endpoint - Kill previous instance via compare-gold.cmd before rebuild --- build/tools/Stride.CompareGold/Program.cs | 69 ++- .../Stride.CompareGold.csproj | 1 + build/tools/Stride.CompareGold/wwwroot/app.js | 492 ++++++++++++++---- .../Stride.CompareGold/wwwroot/favicon.ico | Bin 0 -> 333902 bytes .../Stride.CompareGold/wwwroot/index.html | 5 +- .../Stride.CompareGold/wwwroot/style.css | 4 + tests/compare-gold.cmd | 3 +- 7 files changed, 448 insertions(+), 126 deletions(-) create mode 100644 build/tools/Stride.CompareGold/wwwroot/favicon.ico diff --git a/build/tools/Stride.CompareGold/Program.cs b/build/tools/Stride.CompareGold/Program.cs index a848e04c98..c0462d0c11 100644 --- a/build/tools/Stride.CompareGold/Program.cs +++ b/build/tools/Stride.CompareGold/Program.cs @@ -2,15 +2,6 @@ using System.Diagnostics; using System.Text.Json; -// Kill any existing CompareGold process (from any Stride checkout) to free the port -foreach (var proc in Process.GetProcessesByName("Stride.CompareGold")) -{ - if (proc.Id != Environment.ProcessId) - { - try { proc.Kill(); proc.WaitForExit(3000); } catch { } - } -} - var builder = WebApplication.CreateBuilder(args); builder.WebHost.UseUrls("http://localhost:5555"); builder.Services.AddSingleton(); @@ -115,8 +106,9 @@ var primarySet = new HashSet(primary); // Find fallback gold from other platforms (matching test framework behavior) - // Prefer: same API + same renderer class > same API > same class > any + // Prefer: same OS+API + same renderer class > same gfx API > same class > any var requestedApi = parts[0]; + var requestedGfx = GetGfxApi(requestedApi); var requestedIsSw = IsSoftwareRenderer(parts[1]); var fallbackBest = new Dictionary(); var suiteDir = Path.Combine(testsDir, suite); @@ -131,9 +123,12 @@ var device = Path.GetFileName(dDir); var fallbackPlatform = $"{pName}/{device}"; if (fallbackPlatform == platform) continue; + var candidateIsSw = IsSoftwareRenderer(device); + if (requestedIsSw && !candidateIsSw) continue; int score = 0; - if (pName == requestedApi) score += 2; - if (IsSoftwareRenderer(device) == requestedIsSw) score += 1; + if (pName == requestedApi) score += 4; + if (GetGfxApi(pName) == requestedGfx) score += 2; + if (candidateIsSw == requestedIsSw) score += 1; foreach (var f in Directory.GetFiles(dDir, "*.png")) { var name = Path.GetFileName(f); @@ -167,6 +162,7 @@ { var requestedIsSw = IsSoftwareRenderer(parts[1]); var requestedApi = parts[0]; // e.g. "Windows.Direct3D11" + var requestedGfx = GetGfxApi(requestedApi); // e.g. "Direct3D11" string? bestPath = null; int bestScore = -1; foreach (var pDir in Directory.GetDirectories(suiteDir)) @@ -178,9 +174,13 @@ var candidate = Path.Combine(dDir, name); if (!File.Exists(candidate)) continue; var device = Path.GetFileName(dDir); + var candidateIsSw = IsSoftwareRenderer(device); + // If source is SW, require SW gold (skip HW); if HW, accept any + if (requestedIsSw && !candidateIsSw) continue; int score = 0; - if (pName == requestedApi) score += 2; // same API - if (IsSoftwareRenderer(device) == requestedIsSw) score += 1; // same renderer class + if (pName == requestedApi) score += 4; // same OS + API + if (GetGfxApi(pName) == requestedGfx) score += 2; // same graphics API (cross-OS) + if (candidateIsSw == requestedIsSw) score += 1; // same renderer class if (score > bestScore) { bestScore = score; bestPath = candidate; } } } @@ -417,6 +417,30 @@ return Results.Ok(new { Promoted = promoted, Details = details }); }); +app.MapPost("/api/gold/delete", async (HttpRequest request) => +{ + var body = await JsonSerializer.DeserializeAsync(request.Body); + if (body == null) return Results.BadRequest("Invalid body"); + + var parts = body.Platform.Split('/', 2); + if (parts.Length != 2) return Results.BadRequest("Invalid platform"); + + var goldDir = Path.Combine(testsDir, body.Suite, parts[0], parts[1]); + int deleted = 0; + foreach (var name in body.Names) + { + var file = Path.Combine(goldDir, name); + if (File.Exists(file)) + { + File.Delete(file); + deleted++; + Console.WriteLine($" Deleted: {file}"); + } + } + Console.WriteLine($"Delete gold: {deleted}/{body.Names.Length} from {goldDir}"); + return Results.Ok(new { Deleted = deleted }); +}); + app.Run(); // === Helpers === @@ -458,6 +482,13 @@ static List ListPngs(string dir) } +static string GetGfxApi(string platformApi) +{ + // "Windows.Direct3D11" → "Direct3D11", "Linux.Vulkan" → "Vulkan" + var dot = platformApi.IndexOf('.'); + return dot >= 0 ? platformApi[(dot + 1)..] : platformApi; +} + static bool IsSoftwareRenderer(string device) { var d = device.ToLowerInvariant(); @@ -503,6 +534,16 @@ record PromoteRequest public string[] Names { get; set; } = []; } +record DeleteGoldRequest +{ + [System.Text.Json.Serialization.JsonPropertyName("suite")] + public string Suite { get; set; } = ""; + [System.Text.Json.Serialization.JsonPropertyName("platform")] + public string Platform { get; set; } = ""; + [System.Text.Json.Serialization.JsonPropertyName("names")] + public string[] Names { get; set; } = []; +} + // === Source Manager === class Source diff --git a/build/tools/Stride.CompareGold/Stride.CompareGold.csproj b/build/tools/Stride.CompareGold/Stride.CompareGold.csproj index 03bcd144a1..97f4313a40 100644 --- a/build/tools/Stride.CompareGold/Stride.CompareGold.csproj +++ b/build/tools/Stride.CompareGold/Stride.CompareGold.csproj @@ -8,5 +8,6 @@ false false false + wwwroot\favicon.ico diff --git a/build/tools/Stride.CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js index 842c1a1f68..2b48dd9322 100644 --- a/build/tools/Stride.CompareGold/wwwroot/app.js +++ b/build/tools/Stride.CompareGold/wwwroot/app.js @@ -33,7 +33,10 @@ async function init() { const platforms = [...allPlatforms].sort(); const sel = document.getElementById('platformSelect'); sel.innerHTML = platforms.map(p => ``).join(''); - currentPlatform = platforms[0] || ''; + // Use platform from restoreState() if valid, otherwise default to first + if (!currentPlatform || !platforms.includes(currentPlatform)) + currentPlatform = platforms[0] || ''; + sel.value = currentPlatform; sel.onchange = onPlatformChange; document.getElementById('statusFilter').onchange = () => render(); @@ -147,6 +150,7 @@ function render() { renderSourceTags(); renderPromoteSourceSelect(); renderTable(); + updateActionCounts(); } function renderSourceTags() { @@ -232,7 +236,8 @@ function renderTable() { }); } - const failCount = images.filter(i => i.status === 'fail' || i.status === 'new' || i.status === 'pending').length; + const failCount = images.filter(i => i.status === 'fail' || i.status === 'new').length; + const pendingCount = images.filter(i => i.status === 'pending').length; const isCollapsed = collapsedSuites.has(suite); const shortSuite = suite.replace('Stride.', '').replace('.Tests', '').replace('.Regression', ''); @@ -250,7 +255,7 @@ function renderTable() { ${isCollapsed ? '▶' : '▼'} ${esc(shortSuite)} ${images.length} tests - ${failCount > 0 ? `${failCount} failing` : ''} + 0 ? '' : 'style="display:none"'}>${failCount} failing 0 ? '' : 'style="display:none"'}>${pendingCount} pending `; suiteTr.onclick = () => { toggleSuite(suite); }; tbody.appendChild(suiteTr); @@ -263,60 +268,11 @@ function renderTable() { totalVisible++; const key = `${img.suite}:${img.name}`; const isExp = expanded.has(key); - const isLoading = loading.has(key); - const isSel = selected.has(key); const tr = document.createElement('tr'); tr.className = `row ${isExp ? 'expanded' : ''}`; tr.dataset.kbKey = key; - // Gold thumbnail - let goldThumb = ''; - if (img.hasGold && sources.length > 0) { - const thumbUrl = `/api/gold/image?suite=${enc(img.suite)}&platform=${enc(currentPlatform)}&name=${enc(img.name)}`; - goldThumb = `
`; - } - - let cells = ` - - ${isExp ? '▼' : '▶'} ${esc(img.name)}${isLoading ? ' ' : ''} - ${img.hasGold ? (img.goldFallback ? 'fb' : 'ref') : '—'}${img.hasGold ? ` ${esc(img.goldFallback || currentPlatform)}` : ''}${goldThumb}`; - - const activeRef = compareRight[key] || `src:${getSourceForKey(key)}`; - for (const src of sources) { - const has = img.sourcesWithImage[src.id]; - const isActive = activeRef === `src:${src.id}`; - const statsKey = `${src.id}:${img.suite}:${img.name}`; - const stats = cellStats[statsKey]; - let cellHtml; - if (!has) { - cellHtml = ''; - } else if (!img.hasGold) { - cellHtml = '○ new'; - } else if (stats) { - const result = checkCellThreshold(img.suite, img.name, stats); - const cls = result.passed ? 'pass' : 'fail'; - const brief = formatThresholdBrief(result); - cellHtml = `${cls === 'pass' ? '✓' : '✗'} ${brief}`; - } else { - cellHtml = `...`; - computeCellStats(src.id, img.suite, img.name); - } - // Show source thumbnail + diff canvas for failing/new items - if (has) { - const thumbSrc = `/api/source/${src.id}/image?suite=${enc(img.suite)}&platform=${enc(currentPlatform)}&name=${enc(img.name)}`; - if (img.hasGold) { - const thumbId = `thumb-${css(src.id)}-${css(key)}`; - cellHtml += `
`; - // Queue thumbnail diff computation - requestAnimationFrame(() => computeThumbDiff(img.suite, img.name, src.id, thumbId)); - } else { - cellHtml += `
`; - } - } - cells += `${cellHtml}`; - } - - tr.innerHTML = cells; + tr.innerHTML = buildRowCells(img, key); tr.onmousedown = (e) => { tr._clickX = e.clientX; tr._clickY = e.clientY; }; tr.onclick = (e) => { if (Math.abs(e.clientX - tr._clickX) > 3 || Math.abs(e.clientY - tr._clickY) > 3) return; @@ -341,6 +297,97 @@ function renderTable() { updateSelectedCount(); } +function buildRowCells(img, key) { + const isExp = expanded.has(key); + const isLoading = loading.has(key); + const isSel = selected.has(key); + + let goldThumb = ''; + if (img.hasGold && sources.length > 0) { + const thumbUrl = `/api/gold/image?suite=${enc(img.suite)}&platform=${enc(currentPlatform)}&name=${enc(img.name)}`; + goldThumb = `
`; + } + + let cells = ` + + ${isExp ? '▼' : '▶'} ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? `${fixableVia[key] ? 'failing (fixable)' : 'failing'}` : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} + ${img.hasGold ? (img.goldFallback ? 'fb' : 'ref') : '—'}${img.hasGold ? ` ${esc(img.goldFallback || currentPlatform)}` : ''}${goldThumb}`; + + const activeRef = compareRight[key] || `src:${getSourceForKey(key)}`; + for (const src of sources) { + const has = img.sourcesWithImage[src.id]; + const isActive = activeRef === `src:${src.id}`; + const statsKey = `${src.id}:${img.suite}:${img.name}`; + const stats = cellStats[statsKey]; + let cellHtml; + if (!has) { + cellHtml = ''; + } else if (!img.hasGold) { + cellHtml = '○ new'; + } else if (stats) { + const result = checkCellThreshold(img.suite, img.name, stats); + const cls = result.passed ? 'pass' : 'fail'; + const brief = formatThresholdBrief(result); + cellHtml = `${cls === 'pass' ? '✓' : '✗'} ${brief}`; + } else { + cellHtml = `...`; + computeCellStats(src.id, img.suite, img.name); + } + if (has) { + const thumbSrc = `/api/source/${src.id}/image?suite=${enc(img.suite)}&platform=${enc(currentPlatform)}&name=${enc(img.name)}`; + if (img.hasGold) { + const thumbId = `thumb-${css(src.id)}-${css(key)}`; + cellHtml += `
`; + requestAnimationFrame(() => computeThumbDiff(img.suite, img.name, src.id, thumbId)); + } else { + cellHtml += `
`; + } + } + cells += `${cellHtml}`; + } + return cells; +} + +function renderRow(key) { + const suite = key.substring(0, key.indexOf(':')); + const data = suiteData[suite]; + if (!data) return; + const images = buildSuiteImages(suite); + const img = images.find(i => `${i.suite}:${i.name}` === key); + if (!img) return; + + const existingTr = document.querySelector(`tr.row[data-kb-key="${CSS.escape(key)}"]`); + if (!existingTr) return; + + const isExp = expanded.has(key); + existingTr.className = `row ${isExp ? 'expanded' : ''}`; + existingTr.innerHTML = buildRowCells(img, key); + existingTr.onmousedown = (e) => { existingTr._clickX = e.clientX; existingTr._clickY = e.clientY; }; + existingTr.onclick = (e) => { + if (Math.abs(e.clientX - existingTr._clickX) > 3 || Math.abs(e.clientY - existingTr._clickY) > 3) return; + toggleExpand(key); + }; + + // Handle detail row + const nextTr = existingTr.nextElementSibling; + const hasDetailRow = nextTr && !nextTr.classList.contains('row') && !nextTr.classList.contains('suite-row'); + if (isExp && !hasDetailRow) { + const detailTr = document.createElement('tr'); + const colspan = 3 + sources.length; + detailTr.innerHTML = ` +
+
Loading...
+
+ `; + existingTr.after(detailTr); + loadDetail(img.suite, img.name); + } else if (!isExp && hasDetailRow) { + nextTr.remove(); + } + updateSelectedCount(); + saveState(); +} + function toggleSuite(suite) { if (collapsedSuites.has(suite)) collapsedSuites.delete(suite); else collapsedSuites.add(suite); @@ -432,14 +479,14 @@ async function loadDetail(suite, name) { loading.delete(key); expanded.add(key); preloaded[key] = { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }; - render(); // re-render creates the container, loadDetail re-enters and uses preloaded + renderRow(key); // re-render this row creates the container, loadDetail re-enters and uses preloaded return; } fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }); } -function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }) { +async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }) { detailVersion[key] = ver; const container = document.getElementById(`images-${id}`); if (!container) return; @@ -497,16 +544,39 @@ function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatform const otherRef = sel === leftSel ? rightRef : leftRef; const otherImgForStats = sel === leftSel ? rightImg : leftImg; if (!otherImgForStats) continue; - for (const opt of sel.options) { - if (!opt.value.startsWith('gold:')) continue; + const goldOpts = [...sel.options].filter(o => o.value.startsWith('gold:')); + // Compute diffs for all gold options, then auto-select best passing one + const optResults = []; + await Promise.all(goldOpts.map(async (opt) => { const plat = opt.value.slice(5); - loadImg(`/api/gold/image?suite=${enc(suite)}&platform=${enc(plat)}&name=${enc(name)}`).then(gImg => { + try { + const gImg = await loadImg(`/api/gold/image?suite=${enc(suite)}&platform=${enc(plat)}&name=${enc(name)}`); if (detailVersion[key] !== ver) return; const tmpCanvas = new OffscreenCanvas(gImg.width, gImg.height); const s = computeImageDiff(gImg, otherImgForStats, tmpCanvas); - opt.textContent = `${plat} (d=${s.maxDiff} px=${s.diffPixels})`; - }).catch(() => {}); + const result = checkCellThreshold(suite, name, s); + const icon = result.passed ? '\u2713' : '\u2717'; + opt.textContent = `${icon} ${plat} (d=${s.maxDiff} px=${s.diffPixels})`; + opt.dataset.passed = result.passed ? '1' : '0'; + opt.style.color = result.passed ? '#4caf50' : '#f44336'; + optResults.push({ opt, result, diffPixels: s.diffPixels }); + } catch {} + })); + // If currently selected gold fails, auto-switch to best passing one + const selOpt = sel.options[sel.selectedIndex]; + if (selOpt?.dataset.passed === '0') { + const passing = optResults.filter(r => r.result.passed).sort((a, b) => a.diffPixels - b.diffPixels); + if (passing.length > 0) { + passing[0].opt.selected = true; + sel.dispatchEvent(new Event('change')); + } } + const updateSelColor = () => { + const so = sel.options[sel.selectedIndex]; + sel.style.color = so?.style.color || ''; + }; + updateSelColor(); + sel.addEventListener('change', updateSelColor); } } } @@ -514,6 +584,8 @@ function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatform // === Background cell stats === const statsQueue = new Set(); let statsRunning = false; +// Maps "suite:name" → { platform, goldFallback } when a failing image has a passing alternate gold +const fixableVia = {}; function computeCellStats(srcId, suite, name) { const key = `${srcId}:${suite}:${name}`; @@ -524,33 +596,51 @@ function computeCellStats(srcId, suite, name) { async function runStatsQueue() { statsRunning = true; + const BATCH = 8; while (statsQueue.size > 0) { - const key = statsQueue.values().next().value; - statsQueue.delete(key); - const parts = key.split(':'); - const srcId = parts[0]; - const suite = parts[1]; - const name = parts.slice(2).join(':'); - - try { - - const goldUrl = `/api/gold/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; - const srcUrl = `/api/source/${srcId}/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; - - const [goldImg, srcImg] = await Promise.all([loadImage(goldUrl), loadImage(srcUrl)]); - const canvas = new OffscreenCanvas(goldImg.width, goldImg.height); - const stats = computeImageDiff(goldImg, srcImg, canvas); - cellStats[key] = stats; - // Update just the cell inline instead of re-rendering everything - updateCellInline(key, stats); - } catch (e) { - // Skip failed comparisons + const batch = []; + for (const key of statsQueue) { + batch.push(key); + if (batch.length >= BATCH) break; } - await new Promise(r => setTimeout(r, 10)); + batch.forEach(k => statsQueue.delete(k)); + + await Promise.all(batch.map(async (key) => { + const parts = key.split(':'); + const srcId = parts[0]; + const suite = parts[1]; + const name = parts.slice(2).join(':'); + try { + const goldUrl = `/api/gold/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; + const srcUrl = `/api/source/${srcId}/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; + const [goldImg, srcImg] = await Promise.all([loadImg(goldUrl), loadImg(srcUrl)]); + const canvas = new OffscreenCanvas(goldImg.width, goldImg.height); + const stats = computeImageDiff(goldImg, srcImg, canvas); + cellStats[key] = stats; + updateCellInline(key, stats); + // If failing, check fixable inline before updating row tag + const result = checkCellThreshold(suite, name, stats); + if (!result.passed) { + const fixKey = `${suite}:${name}`; + await checkFixableVia(suite, name, srcImg, fixKey); + // Now set the row tag with final status + const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(fixKey)}"]`); + if (tagEl) { + tagEl.innerHTML = fixableVia[fixKey] + ? 'failing (fixable)' + : 'failing'; + } + scheduleCountUpdate(); + } + } catch (e) { + // Skip failed comparisons + } + })); } statsRunning = false; - // Re-render to update suite badges and filter counts now that all stats are available - render(); + // Final count/badge update (no full render — everything was updated inline) + updateActionCounts(); + updateSuiteBadges(); } function checkCellThreshold(suite, name, stats) { @@ -578,7 +668,63 @@ function updateCellInline(key, stats) { el.removeAttribute('style'); el.removeAttribute('data-stats-key'); const brief = formatThresholdBrief(result); - el.textContent = `${cls === 'pass' ? '✓' : '✗'} ${brief}`; + el.innerHTML = `${cls === 'pass' ? '✓' : '✗'} ${brief}`; + // Update the row tag once all sources for this image are resolved + const rowKey = `${suite}:${name}`; + const data = suiteData[suite]; + if (data) { + let allResolved = true, anyFail = false; + for (const src of sources) { + if (!(data.sourceImages[src.id] || []).some(s => s.name === name)) continue; + const s = cellStats[`${src.id}:${suite}:${name}`]; + if (!s) { allResolved = false; break; } + if (!checkCellThreshold(suite, name, s).passed) anyFail = true; + } + if (allResolved && !anyFail) { + const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(rowKey)}"]`); + if (tagEl) tagEl.innerHTML = ''; + // Hide row if it no longer matches the active filter + const filter = document.getElementById('statusFilter').value; + if (filter && filter !== 'pass') { + const tr = document.querySelector(`tr.row[data-kb-key="${CSS.escape(rowKey)}"]`); + if (tr) { + tr.style.display = 'none'; + // Also hide detail row if expanded + const next = tr.nextElementSibling; + if (next && !next.classList.contains('row') && !next.classList.contains('suite-row')) + next.style.display = 'none'; + } + } + scheduleCountUpdate(); + } + } +} + +async function checkFixableVia(suite, name, srcImg, fixKey) { + if (fixableVia[fixKey]) return; // already checked + try { + const platforms = await fetch(`/api/gold/all?suite=${enc(suite)}&name=${enc(name)}`).then(r => r.json()); + for (const p of platforms) { + if (p.platform === currentPlatform) continue; + try { + const gImg = await loadImg(`/api/gold/image?suite=${enc(suite)}&platform=${enc(p.platform)}&name=${enc(name)}`); + const canvas = new OffscreenCanvas(gImg.width, gImg.height); + const s = computeImageDiff(gImg, srcImg, canvas); + const r = checkCellThreshold(suite, name, s); + if (r.passed) { + const device = p.platform.split('/')[1] || p.platform; + fixableVia[fixKey] = { platform: p.platform, goldFallback: currentPlatform }; + if (cellEl) { + cellEl.innerHTML += ` (\u2713 ${esc(device)})`; + } + const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(fixKey)}"]`); + if (tagEl) tagEl.innerHTML = 'failing (fixable)'; + scheduleCountUpdate(); + return; + } + } catch {} + } + } catch {} } async function computeThumbDiff(suite, name, srcId, canvasId) { @@ -586,7 +732,7 @@ async function computeThumbDiff(suite, name, srcId, canvasId) { const goldUrl = `/api/gold/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; const srcUrl = `/api/source/${srcId}/image?suite=${enc(suite)}&platform=${enc(currentPlatform)}&name=${enc(name)}`; - const [goldImg, srcImg] = await Promise.all([loadImage(goldUrl), loadImage(srcUrl)]); + const [goldImg, srcImg] = await Promise.all([loadImg(goldUrl), loadImg(srcUrl)]); const canvas = document.getElementById(canvasId); if (!canvas) return; const stats = computeImageDiff(goldImg, srcImg, canvas); @@ -595,32 +741,23 @@ async function computeThumbDiff(suite, name, srcId, canvasId) { } catch { } } -function loadImage(url) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.crossOrigin = 'anonymous'; - img.onload = () => resolve(img); - img.onerror = reject; - img.src = url; - }); -} // === Actions === function toggleExpand(key) { - if (expanded.has(key)) { expanded.delete(key); loading.delete(key); render(); } - else if (loading.has(key)) { loading.delete(key); render(); } + if (expanded.has(key)) { expanded.delete(key); loading.delete(key); renderRow(key); } + else if (loading.has(key)) { loading.delete(key); renderRow(key); } else startExpand(key); } function expandWith(key, srcId) { - if (expanded.has(key)) { expanded.delete(key); loading.delete(key); render(); } - else if (loading.has(key)) { loading.delete(key); render(); } + if (expanded.has(key)) { expanded.delete(key); loading.delete(key); renderRow(key); } + else if (loading.has(key)) { loading.delete(key); renderRow(key); } else { compareRight[key] = `src:${srcId}`; startExpand(key); } } function startExpand(key) { loading.add(key); - render(); + renderRow(key); const [suite, name] = [key.substring(0, key.indexOf(':')), key.substring(key.indexOf(':') + 1)]; loadDetail(suite, name); } @@ -665,22 +802,26 @@ function switchDetailSide(key, side, value) { function toggleSelect(name) { if (selected.has(name)) selected.delete(name); else selected.add(name); - render(); + updateSelectedCount(); + saveState(); } function toggleSelectSuite(suite, checked) { const filter = document.getElementById('statusFilter').value; let images = buildSuiteImages(suite); - if (filter) images = images.filter(i => i.status === filter); + if (filter) images = images.filter(i => i.status === filter || (filter === 'fail' && i.status === 'pending')); images.forEach(i => { const key = `${i.suite}:${i.name}`; if (checked) selected.add(key); else selected.delete(key); }); - render(); + syncCheckboxes(); + updateSelectedCount(); + saveState(); } function toggleSelectAll() { - const checked = document.getElementById('selectAll').checked; + const cb = document.getElementById('selectAll'); + const checked = cb.checked; const filter = document.getElementById('statusFilter').value; for (const suite of Object.keys(suiteData)) { let images = buildSuiteImages(suite); @@ -690,7 +831,9 @@ function toggleSelectAll() { if (checked) selected.add(key); else selected.delete(key); }); } - render(); + syncCheckboxes(); + updateSelectedCount(); + saveState(); } function getMaxDiffForImage(img) { @@ -702,11 +845,63 @@ function getMaxDiffForImage(img) { } function selectAllFailing() { + selected.clear(); for (const suite of Object.keys(suiteData)) { const images = buildSuiteImages(suite); images.filter(i => i.status === 'fail' || i.status === 'new').forEach(i => selected.add(`${i.suite}:${i.name}`)); } - render(); + syncCheckboxes(); + updateSelectedCount(); + saveState(); +} + +function selectFixable() { + selected.clear(); + for (const suite of Object.keys(suiteData)) { + const images = buildSuiteImages(suite); + images.filter(i => i.status === 'fail').forEach(i => { + const fixKey = `${i.suite}:${i.name}`; + if (fixableVia[fixKey]) selected.add(fixKey); + }); + } + syncCheckboxes(); + updateSelectedCount(); + saveState(); +} + +async function deleteSelectedGold() { + if (selected.size === 0) return alert('No images selected.'); + // Group fixable images by the platform whose gold should be deleted + const toDelete = {}; + for (const key of selected) { + const fix = fixableVia[key]; + if (!fix) continue; + const [suite, ...nameParts] = key.split(':'); + const name = nameParts.join(':'); + // Delete the gold for the current platform (the failing one) + const k = `${suite}|${fix.goldFallback}`; + if (!toDelete[k]) toDelete[k] = { suite, platform: fix.goldFallback, names: [] }; + toDelete[k].names.push(name); + } + const entries = Object.values(toDelete); + if (entries.length === 0) return alert('No fixable images selected. Select images that show a green checkmark hint.'); + const total = entries.reduce((s, e) => s + e.names.length, 0); + if (!confirm(`Delete ${total} device-specific gold image(s)? They will fall back to a passing alternate.`)) return; + let totalDeleted = 0; + for (const entry of entries) { + const res = await fetch('/api/gold/delete', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ suite: entry.suite, platform: entry.platform, names: entry.names }) + }); + const result = await res.json(); + totalDeleted += result.deleted; + } + alert(`Deleted ${totalDeleted} gold image(s).`); + selected.clear(); + cellStats = {}; + Object.keys(fixableVia).forEach(k => delete fixableVia[k]); + await reload(); } function expandAllFailing() { @@ -769,8 +964,67 @@ async function promoteSelected() { await reload(); } +function syncCheckboxes() { + // Sync individual row checkboxes + document.querySelectorAll('tr.row[data-kb-key]').forEach(tr => { + const key = tr.dataset.kbKey; + const cb = tr.querySelector('input[type=checkbox]'); + if (cb) cb.checked = selected.has(key); + }); + // Sync suite-level checkboxes + document.querySelectorAll('tr.suite-row[data-kb-key]').forEach(tr => { + const suite = tr.dataset.kbKey; + const cb = tr.querySelector('input[type=checkbox]'); + if (!cb) return; + const images = buildSuiteImages(suite); + const filter = document.getElementById('statusFilter').value; + const filtered = filter ? images.filter(i => i.status === filter || (filter === 'fail' && i.status === 'pending')) : images; + const keys = filtered.map(i => `${i.suite}:${i.name}`); + const allSel = keys.length > 0 && keys.every(k => selected.has(k)); + const someSel = !allSel && keys.some(k => selected.has(k)); + cb.checked = allSel; + cb.indeterminate = someSel; + }); +} + function updateSelectedCount() { document.getElementById('selectedCount').textContent = selected.size; + document.getElementById('selectedCount2').textContent = selected.size; +} + +let _countUpdateTimer = null; +function scheduleCountUpdate() { + if (_countUpdateTimer) return; + _countUpdateTimer = setTimeout(() => { + _countUpdateTimer = null; + updateActionCounts(); + updateSuiteBadges(); + }, 300); +} + +function updateSuiteBadges() { + for (const suite of Object.keys(suiteData)) { + const images = buildSuiteImages(suite); + const failCount = images.filter(i => i.status === 'fail' || i.status === 'new').length; + const pendingCount = images.filter(i => i.status === 'pending').length; + const failEl = document.querySelector(`[data-suite-fail="${CSS.escape(suite)}"]`); + const pendEl = document.querySelector(`[data-suite-pending="${CSS.escape(suite)}"]`); + if (failEl) { failEl.textContent = `${failCount} failing`; failEl.style.display = failCount > 0 ? '' : 'none'; } + if (pendEl) { pendEl.textContent = `${pendingCount} pending`; pendEl.style.display = pendingCount > 0 ? '' : 'none'; } + } +} + +function updateActionCounts() { + let failCount = 0, fixableCount = 0; + for (const suite of Object.keys(suiteData)) { + const images = buildSuiteImages(suite); + for (const i of images) { + if (i.status === 'fail' || i.status === 'new') failCount++; + if (i.status === 'fail' && fixableVia[`${i.suite}:${i.name}`]) fixableCount++; + } + } + document.getElementById('failingCount').textContent = failCount; + document.getElementById('fixableCount').textContent = fixableCount; } // === Utils === @@ -779,17 +1033,35 @@ function isSoftwareRenderer(platform) { return p.includes('swiftshader') || p.includes('warp'); } +function getGfxApi(platform) { + // "Windows.Direct3D11/WARP" → "Direct3D11", "Linux.Vulkan/SwiftShader" → "Vulkan" + const platApi = platform.split('/')[0]; + const dot = platApi.indexOf('.'); + return dot >= 0 ? platApi.substring(dot + 1) : platApi; +} + function pickBestGoldPlatform(platforms, currentPlatform) { if (!platforms || platforms.length === 0) return currentPlatform; // Exact match const exact = platforms.find(p => p.platform === currentPlatform); if (exact) return exact.platform; - // Same class (software/hardware) + // Score each candidate: same graphics API > same renderer class > any + const currentPlatApi = currentPlatform.split('/')[0]; + const currentGfx = getGfxApi(currentPlatform); const currentIsSw = isSoftwareRenderer(currentPlatform); - const sameClass = platforms.find(p => isSoftwareRenderer(p.platform) === currentIsSw); - if (sameClass) return sameClass.platform; - // Any - return platforms[0].platform; + let best = null, bestScore = -1; + for (const p of platforms) { + const gfx = getGfxApi(p.platform); + const sw = isSoftwareRenderer(p.platform); + // If source is SW, skip HW gold + if (currentIsSw && !sw) continue; + let score = 0; + if (p.platform.split('/')[0] === currentPlatApi) score += 4; // same OS + API + if (gfx === currentGfx) score += 2; // same graphics API (cross-OS) + if (sw === currentIsSw) score += 1; // same renderer class + if (score > bestScore) { bestScore = score; best = p.platform; } + } + return best || platforms[0].platform; } function enc(s) { return encodeURIComponent(s); } diff --git a/build/tools/Stride.CompareGold/wwwroot/favicon.ico b/build/tools/Stride.CompareGold/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f2c5b30f896f9eacffa28cc754a05a7dbb5afcdd GIT binary patch literal 333902 zcmeHwON=DRby&80$)*5{JqBrbY!I$K$N*3724}iwX|Gjd@j`%F>~Lp#X1FrJ6%Cud z7(1|FfPf8EEl8L$Ab1ysZODM2xe@Y7hEKk+gax!0Lvs@Z81NP$fV`PaU$$qvw$krK z=F55+6_FW{8To&O>50tvym;|`@gm|?R1_UVzZ#vKM3A0De|#&7{vwK^Tae=Wzj!5z ze)n%g(b-vA{`aEjXMZ!w)&CFwFkk=THvs^Au>F@$UWxwbK@{D;pT7S_6#dz=S90+F z@Beru`tq04{{BuB{g=OdB?o`||6Yl1-%iSZ?^mMe$A_PZzWBxD{eONoivIquekOHmzAd94_@mX;E1fT5uj0!8VogJpSy02j?+wOXH*z%Q!sV zj_T+s!7Jkl!m_n3gF)rCw5)GlZi2zb%8@PqDq;))ggNTg*50LwTlhEOYJGR?kHr2nR|{xY*#^@`=_QmhZEUk1J2G9<_B% zId0U3=kaITnDu<##^ss%wWY4(=XekwbeJ3;D&u+jbCteLcyPGXub%Qcb^GNw;ImE- z-j|Mt-Zs=b;b7_;^Foi=hBuCv#@uGVIzDyB8*dkJyqU-G)o~oJ4&!)v5O1SsaUDgo z^}+J^>S#UN9AC}1U;V?M$G?2(KkEVV zOKmAdm^xf4!<5?dyrTNN9zJut^l=p7&Ec5Z5e}5{et27araF2`V~Yzi;40R!xtk68^Owi=8SJut~uMXb4 z@6!H2#(8~w-e`7Ee^+&ibVF;e>U-(|w&5RLhHdmA8OgN;8rx)e1G#LU#p~tpCwVWB2OV!}&tZmmw)KPkaro4~o?2xJ zc%;|WVRHDs&qa7szZ@pz*;0hZ>(jGt|0us|YLgWcUc3)exiQb68)*NiE{Ey+OfXzi z4&Sv6)#GjH8SMr=`=le|C~jFTNW5h|u`k=tDANlVd73(#PUQl;Q3} ze`T8uvSP){Aji5)*=XT{H`OuHLzfqWtT^k9!Ee|Ayp4etgp*HNgujhGR+{VMPTy@Z z<%6fKt_lB8c-fD3T82p`~HM~CYq1^5em|Mg!#fb#3;`^Sji^}+h^1*S(UHID09GLGxll5t!^ z;O8-v->ePeSft~DHc$l`K)Qky@^ReQPYmtV_+j7(2Wd4|=}J9A@MlWD4FrK=`F571 z3EkWH-s-2Y-(Wibf{`@-LA@hCr>YNI1xem7^`E6R*EL1>C|VorX4W?^tLYQ#co_TO z{TZG^@T8E|hCWSrRufdEV7GaN$WAtRi|A(XFVRE^qj*!&2`K z{=4qCD*iaMGvScIVzkD3#3yQ_c&+Ka@;gh~QG1`1%N4bwydwTm9Zad6Ppb2S!{M;; z*~DwECqDgde(PUnc3$s?;OP0;yUvqz--y~3rNrY5mciao`=UCk%+ns5Xs!3bY3x$J zNH%C3E^rhc27StO#XzSFcSAes8`G?w4TeddG};>Nm)4H=$)9cgb6Qh!iTi>sw+k{IFo<=hleaPB7%yrZ!PqDpe%o$vpTp03AJmG!0JQvd1 z(5DGc(|F4IHp;MLezEkavO1Ockj@unuuID|UDC%| z_Fk1IRmNO|i>p3_?w8|KI?rhH0dE`fd5O z-JbschW&e8n+N}L-=F>Gi+J&SL%c6s?>rvwa3&b1Auc54#){_!=Lx$L~l#)1-KNgt8iSrzoKWNcZNI2a#4L- z8Kl6J&$}LV-pofO`Mwoy+Ih90v2}$LCLe0k&WfpFYKF zRpcWS5DJWt0-N*4Z{OT`^CPbN{29x(cOTD3ICL43P++nYczJ$#R;2gb2B>FQ6HHcC zWZ>hWfXUb2({`G<)rB>I>~XDu$*wH?F}N(^Ct@!QwmP&QNUAtWi5vE^`FiQXcHuca5DN`G*CIuo1pG9pFm;=i?n0BWpbW3ZN2CIfW#1vSI_m4$r@kup6h=8 zSz-uveHqic`1+#zd40FgLt+TWr1p`V=UL>Ot%IHPVnX#LhH&^MKzx1C`?_{bVhD$6 z2ju&CqWg7qKi6Jj2nS&ZWQ{L+pVQmWYZi$i?4=!$^E}b}M)jWA5w$lUF@(La1G2^! zy>CnJ_xh0-!cJ{~`1+#zdpgPH>9)!whOk{TuzmIET)v+ty5E+5yYwS5gw5Lk@%2UL zU39VAIub+Jge8#kJkkAb_1cgAH+LRA|M>LvlO}XwN-$-O?~tntUM50kZd5<^&M2*lSH-5i`;*jnOMK!~VhCl8-!Hwtxp@41bNAspYF%oP zP0`bKcsAx3LUo=8_bQ1jwIfSqbiTRs&5u65_vQ)h#>DgQ-nuz|v@B~Ul+J}-IwI-0gn^t*>yt}#caM_mLhVBP_f0;MBn>X-0$<^0)zWR&AQ;w@V=lP7h+unKj zMwxz0rCipLdHE>Qmm!=9NetmWPy1@K`(kHaoPA$t(YU)VM{U+5i3}`j4`y)}nVW->HqSx^raMF@&wyY_bCro&R+?%l4;;E(1=(%o`6*a9*~~8=O7? z^grtdV7Z(p=={^)hiKPBt?`x3c3lsN{%4{?djo1N;_^L^XOy21-_t4d^-Z)0ssAZ_ zyr(8UeR?ZnPQ{00EO0-O3GW`|;l6BL-tFznx{Ocse^0W8_T8e8^G2oLOlUy=cWZ)2 zi#-N;X7t&vhw#;q9NspYY=h{(Rhow2Lxzx_O7jNE52g+2Kh4>pe(SDJd%mG;_V(4M z^GY_G_$T^r)qg5LJD~VQH0wk9l?N~C`inTePc9xmt0g}z=s(#3v@=7GAw)R}wJ-bW zoy+GLZK}$o=s&4>VcHiTGT6Lvars7Vy(gJ#c>d=yo}3drTGZVe=z^aid^HqOV+;oI z!Z#KDFVuUzFp-;X&X+pdBPx@r7WJQO0otxmF@%lZBNND1tGvc9;-BchuHsJbt$w!% z?#T?{>j#}TxJ-4R|6~VnP0-i#!ce|i?fn_fEB#sY-$~zXmDC=g>shN#`;zxi^3%w? z!Ex_W|5H5r7DE{9dls%S7@QwI&!Yb})%MB{9eWx|esF%w=1L#A@TuDa{l_u(A%-y6 z8XxYu4z@p2#7ohCFFh}+9AZx?g#0w>FPdbjC;Fe+Ilw2xn!sm`hrZg)oy+@0^5Ig3 zylX}8iI1ZHE^P6tQ{|j_Fup#?4Nv=~|0!;ve(SF2Zpl!5Yu#oO|3v@2bla!0Yy40s zU%%CPgX9O(p6dT@P0-AFVW{6j2@-?B`Qh^{`tPICmFn7J&Dw2dLw z1S&TC-djO_2PwNh$wbq(@9lVnzBhnAV~G1&vpbyHk`-G&1JHl61EFFFefiJp zcjoJx_$T_$S=0D4+JU;AG=83El9QsmA?ZJjBfvd`RruIg3P_!p2V8^lIMV zayCT$2mIA}VN3GgJDW}XYiazQD9lJYExp5uc-d7tQ2pm?f)INHCUHZXz3KDsoQwXO z*w&l8-p(7`)(l<$)3Jn#Aw=O(zFO0N-(*$dVneSMQ{7`gtF4uy;%Y~_2ICSK`zqW@kx8>(_|V)t};sPaA$ z{USC`J<&;V-VanQ_+7Xy{%hmG`_w` zHm9opK#Nc@gcujz_&tP1-pT%7UEMBf-}~4-lT7&LO<4c=njpk^q3d_XvwnSfrPr7F zzes&+m5tKZ*X0M_MgOz&`cN^1q3@Hk+6&SDS~_lOJgC?`lRo?AiT-E$k9sz!7(&s1 zlL}YL8}%B$$R>#X=k$L!*M^B9ta6{+4u_IhLec+9x~?~xjIVF91ET*H{SO>N*u?M9 ziT>-V?DanQ*gcaz`{s%M7wbRJv$rvXqW@m{PL(I?>zizY=zppHlRq9bhA_mv0;2z< z(#~n`?r<{cWSe=S|IYePb|7R7A;5f*!S&_4=)b$(xAmJWzC7%@zUaTd{--?a{Jc=~ zzf}Ll*Du>ce)5wtBI5pNI z|4Es3FkJh zD!kzLiZFh?Les%Ek=VV!x{vli^uJa8Cp&<2e|h?iN$GD@!z1T;4d^}j0;2!j=zmK8 zQ0IkJb*smq^0xv?u5c=p^-|C95-=ME=vK!!EmC3-(#pQ!cMolmzFQ^T|VRNe{<)XA8i7}j5K_v?-Wp$};eQ1PfL zhHxU^?GCjs%XMjp&wbIQq2UoK4kYOPN%$Rt)7MYx%Hfz}2t(QIx-{-f`=RMw*Z78- zH=Ne^Rej{Uj}~>;1Sp?liXj|h>|O{P(zQMfrGK0^Ld5Q&ufJ)*$5w0k0N+m;LkwXk zn;k;m`UYbt`qvensP`da_tYA{i~ExT-Cr}r7((RTm}B=s*pjaFY6$&?nl~Et^&Qs; zq3*OCLJXm-@!c)M5cIHZ98rEkoaf=3?{l8l^f;6A!pnEurNdm4&I_Byw+j4FHrqV% z@#R*b@mSl0nm6j6=QU5?5ylW!ygzAt8tpft=4H+847+PQLdEV4>HZ|V(=ya~p|YKh zYmtz=4rR0bv}QcDL-JyfutLS|U0lA=Ctu%{7s;BS{&^v-2^74R>_Dg(jPYo*|43Zr zWNh_9%^Usq_1*lhA;l2N8sA^fZ7s&8*Dm7;HE#rs-D_#iETvD6V+cdpY@04jF~3wE z`XZMB@CY?;^x-_ONxp?z6QDkYh#^G14`s8bsN+RrZc>i=0y~kP%lk!ia4ADyzm3?v z{?IMZ?_#UpD5!Q1VJMsJ!rv*@>5Hs2fk!BRQLXX2h}{d|^8}$QtO-K=F1Ak$A@VLn z48|07+Gor`44jj^2PHBR?H-z&m9M?(2(zOpa%qo{E?G5C0) z`^3HB5NpLD#qNcsVO4lj{9WuZ*^R1v??by#^M?HPp<9fQjpuY;I3~TA%2;eX?Q_2P z`t|g+Dc**PA)Jct^CA5*B8Anmbox@laEG08y-k8FT%+x z+V>E#d$?AR*u8LkX^a2f{ouXK0e;K4Vf7h2cyGQ`SYL~;KLLHMAQxq_m#hiu-%UPv zC2ep3Wjv@;9yE6E;_-_*xJcXK+8~J`Y|a2Qp%=2oAFi%7ArHY|N(^CeLlBHNssAUw zzUY2vnc9OVF@(YFz#eU@uHyp5?%{WRJYukY`I+vA;uP?eGCIQ{C4C~r@OqjM0bfH%ozeMccFfNQSR7oNtUa|YE8Ty ztqJ6A^7Qxr@Vl1x-aN?}h6*p+SD(%$c29Jl&nbO=Mp?bNc>17%sE?+}CO{0O{ARA` ze4q8a6gOBCygdEJ*=Ury#ev9O9HRTB`ZbXChQtuM8xC3Hi{6h#@A)_+hOpQMh_5et z&-G=r&k{qJGX%*w{^eq{{2qvpD)evH{>qvF&IryQzb*Uv?aH0#d4K3V)inXm`J(sz zkwdWwUGriZcazH+ziT;@{(EifMtnDUeDCrEXfJo|%6@=+XQ4m_#vDVaYyjA}UfbXT z-U!~}KeQzSxIW(AeLT-?mXGA+=HAo$;tPl_wWUjg?q|f`EBfT_o6nTLBXh3!#3BP$ z8NjQ`Ue$r``18HiL2p{xmHO)x-TP<;LBdat*{^Fmn@h%eCBIbO#r#P3|` zIw0>+baO6i0$tYRy+3wQeEsIF6z&atdhz7B$bEn0e(JnH-}L6r<^ATRUwR-4NDQIq zf7fMUO)9W1Xi>rkna_VEzoU&`1&CViO7(*!M1jDxl61&%mx{R_DSrZIb|7DFoN|o$nP!dBp z96KPsekUq2iB2Vku)lUdV)rJYf}IaiVhH@0LmIUcY!P*a!t|6bQN|kk~yN znI&H+&}$0RSrdq_-)q(iazX)T3i!qlO6;C9X{Dl2U=S3*y@9g3$>lt65Udm=g#wi+ zV2U9`UtePPDw9+i3Izs70bCP6tj`OH-5VV1Dj^)_KigUUU4Oei(sT0fSBLp`{cRQL zIr;Y}n&&g}Z`&xE<#Y0H*HKi6;5v#9@-6ajOQ2ysC;x^dp69dp+Xl;zc~1WM3d;*9 zw8ruR1eaJIE%HEjZ$KUV%yv2XC!h{~tOzRf3J_eW=5`9D#Wn;}^sES`=vi5~CioT# zEvekX!mQZLLdCqKj*&tsb+Cp}#@0z&{NIS+a#wDmP(~fBHqSE--!kf8xdB0jo{@zs zY?poZ;b%qaVWC&Zp=V%W4m|^f)_M4QO0dkA@3BxT)+xl8m(-l)2aux<*3ekEPFn5$ z*I2mRm84HO3Tf2ADszs&9(o!J_t4W=xJo-^Ne)4lpFJ`J4d~@qs4*`A!DMWm0c8)2 zg)5f5d)yIVm&czn3K^(_^=1UXKpia4Sh&Ww{ZB@r<$jsUN#Pr*gB4N)E$C$|w4j$E zxKf>^|M8a;L0){A1GYd6bLbuAkWmQcm^aJSR^=MRCF>5s$2o{`yxx^3_;HB9bJktT z00t3chJl+Y_#7hU?BLInat3h$IjgKfQp_MKgw|A^2_R)85|M$+1b9Uij^mGC?&vv- zUnD(b6q?5$UN15P7x8;Zc{ZdtKDwS0f(P+7?SUu+IY-yWaSHAzhUet7Ob~#aqw7N& z&vCq_@^w-^i`Pfj03>;Xj;K5x(mY-sUBle5R26`dRGuOTIZzHzu>1h}q4H!%*fW%; z2m&&@@)fo?0?eU2MG(Pc?bVPl2g<=TV{JquD~H@92g?CXc*9y*xf&7<49gXQs+X)B zTc{i?N6erp^tmfvr#V=zD5Ti1D~D{AgXOAgMWtOiP-uZ@t8%EBP2WsKLvZSe%vb(Kl6^6h1)K_@n5xYrn_ewE~~P-;M;7kN)8ZX`rG;5Jp~uRRLRopjJOD!UP1H3jU+u$3 z7G~v3LpiXJ%2Vb+r5$`kkjjZVxpF{|$}{wMdtf1zuc&)o4lJbdtTIu8}u*v?D|h=n^GwAp0e_^=frfvEUdRr3({({y>cRb z(#>M8oDiGiZ)3*J*N&< z(A($H%TWm1Yv|<=#B#5E9 zJZa7?U#=z**oI)npj@lnONw5+b4hk(_>`g-+Zddpm)lce5Hby-DTI~bV(KaGrq7|G(Y=$QPtovFf4F?wL>7lqB^Uuwl) zh7sR~za{(~L?`e+eD16Nd-EUOYqi1eo1MOX(i@~&KqNkWaPsM$%jb0Wj{5%Y-A9Y~ z^y#e@y6>!u`1I?yHW!x*8n>R_+eJN$0+%hPY1HHc1Y zpi$PH$F2QFE`A4ns5+tRxRKA=cujQ@+i>|#YYYp}5$bqVo||Z(@<1p0ZX3LG+=2Hd zTHM@u^t^965lYrg<2B{cd>KGgYk^SX1{-C&$1)6P?xG#L|Lc;rRx~*3%<1~$@=sTxD@3Bd7!tb_My}Oe55<>Tp z=dO6vxyOTOUPNcjyp_Htba?na!S+d&jvMST+Emmt>>T-ibMf>6N2Dt4u|NI0jW~C~ zKGTB3ukvjAE@crdOg!K=b^FzC&kzp<7vh*QepG zE)$&-`3T2<8b79_r)XzMpQ)V7x=Bxp#=ooo)(d^zulm&N1@>9Cw@7$3ohp0d@LP^< z;|IHddQq@XUPk98`Oj%-lf4};)3Ky_?lt~QC-(QraqdvMm%=sm*M$D_vAgg<$IEy8 z)E>uT)QR&)OPjCK)cCg-mv10!!p$eGI{vH=!@6JjkOtp9^!R;cJ;RyFXzlT*u&nbX zvq2%pUu0)Zn=eC*zlx6A#*X6t@uj-HZJuI#F%i6I#}Z4yN@P$zsm84J2cxwE^{4loGz7 zQXDtm^P#?9o?qt9c@uxS+FG0AYFdj>pDrnfRrlG%1Jtd|Z?Mhd6>JX5e2DuD>y8=Q zBM)5G!C04cRo|y8U28KvG11wD*QPpk#&46oPc9xm%XrT4=6zwgzi<1^k90jUjmamE z`L;GX`;608*JsRF*Ccx(=1-e%`{}*6-qUr z6)vx5^KGk)%e4*f-}G#=vrYL83J1^$-8Q(6$G4to%#>%7btr#9b(%~=__k&AFyW7~ zuG`rVI&SK#ERW{PvT;-`=lz>>9N{)9>z4VEeNG>(9aVqkJ~41*HLHdjLoYp z=tP}3VqAMDnd;lPJn=F4kgoF3)ZUC2A3evb!#4RVuH&bAKI>4u|E}I`^EQpCO4`I8 zRcQLyeDf;fHMI$~M-_V92rq=Jo5pO)D~d^IVr)e)QPy=o&4hCkdFTgsHBU65<5g&s z=)|LC5syNbnSApqxQA@h%6w^vdkHy)5U`qfst7L-S+E!+Nj%VRZOBUPsS<6dljv>x0$1t1r#q3f^dW^$Y-iK3aZt z4e52XJYGV&j+Td*uA=3^3R1lD0O|qYWd!X2=n~;TCrgA2ox(qb2c!$?AJSt8kilkO z`ciT;*0ZAs@1{FgBlt~pxQx~dNIxG%ui`LYRaZ)EqAPVJ)#hNO=&(78-~;7<7t?vX zfoe#w%^Fjn!wOTNEGE!@a&<;DOW$YdT^)<$>K>>E_^WoRA`*TH?{i33kS-vF{uQGD z^CNi0k0$7FQRU|Z_?|)2I3xU`vx}zA6he$k$qMXiy7*4`eTufe7g{#9s%HlzQ(fvtk*qlJ z0rzDB?#Y+Yn#vnFr>eQ9PPi4NRb|DM7g(>(o_G=N+#dSiQ>AXA8~fjpDZoqGHjwx&R#M6kzXdexVQIWpar+xRq?0sss6yO>HBs_AM^!sa;4#)l^N_J$|~`T z`pVG)#*gjm;!m(CCBA03rTwUP8~$k>w2LM`)JTg4@JGJx(cA-n9HYq(B_5k-5`z9F zzMA?XdBFO{ayC}e+6LRH@v(Y!@Gq1V)<=eGiTq^scw5j7E>mRxsBTsKxeXv#rD+xX zX)M~khh+bJ@pqOL>X)Z=@CP_bc2XE*FI-cU6scGdEt%7j=;(l$RU~M;UIajhZVBcjFX|g?#R&aPooc>j&|1mHH}8 z@}{C6#PP@HI{vQ@ovE(L2I@Ffd2d6eLij;tV{1aD^m)DvhY;nu|4aP$Nl{kxyY)ig z<_d%SUmu*YF5+#vd%?Be(DjP;&GfN#AuF!qEjl+qns*hC?utLwOYH6LzKy2rp$|?~ z>b^XGaE387P0>6F69an18weZ16n`rdQw$Ts6r+(Kh47;}rVzJujOiMqmmpnXm=dHo zxCO+YU^Kx`r??OjiK!Lr4)Wz=3|2Nk0dxB>n7JG{=4+%nK@AMbC~9zpH3<@E)dz zOEs1&2=l^mT-{E_arG=2$1hjraj5aYIFc|e=zj_0n=5=2G8m?%=%B*1APZp6;19#J z7Ajq?fO}*Yrih_aQ{Ndm8EZ2Toc*M z@2R@v)#W3G7Z)dQYajX^+*6B9}C^}Jy9E-C?D~vx)+7Mfbs_{xY%$edqg$9+Gt6E_#%dQNa$Q(B+sW7YTn2_DITF86A^2KO}4 z`8?L=<5T0RfFJcsscnCs$_YP8P5Z94JDaM|kNVZeO8rwx_2_*s)qF3LE>^|Q#U_^G z2XaX~r@i>S^^_-nNpAOO!E7Iux!^~2b>B;^mw>*m^g~|aoiGH?CH28Cg9kWqo5FRP z;PF(+ScUy_v=;=&=bW1Gbn(5a%x}7#CLB$&Pq-LUhy7TW-&NqSb$h6Eh@Bbevd`Pn zvu%7dPM$jBr=7p)I;7h>l6}I7Qa%rHJZ#Tp_~~OUvxoZkHRxV0{M-S&Ca~CzV~U7?VW!bNo!atm?bw#sKz?`(MH(pdH=4@-gCW18{7DF+v^Rl6%l5#Ac$CFyrnf9r#Hm)QUMv(ay>^mEbQQt6pGK8w~Vo_~dX!Qao| zZvlUByr%F%e6c@#N4R+YG>1Ptf5Lij9)`zm5u86IrDK8XH zY

@KJ~o1JSnBMtFHk2@;>Vlq&1f=~fBfTd+ zo&7E*7rzqcA5-iQ%>mSxp8CvNCRo^>?`xoZAkFZP^H<+bPsaRkNp#0G61JiDqLg3} zt+6iGMf`447C#NTPyD5IL{YnmT$X(YgKK)ibp-^7w30@f`Js zpO5S70N3w?A*}(X^)7x}|AYtbL(v{A_w&p8=RD3}8SG7I|7ja;kI|1Wl0O@*bv#fX z5Dxw+-7?_E+a$7K-&087xSe5gJw%yt@}~j6BL7g?o{}+`^oi5fW(#>cn~WFrkM!j> zugw1-`=$8exOZpjAKUYI$8y= z#byglePbT3+xhusIj!CHpwJfb`N`Hl_MuW`GtpK!=#;I`cr%AkRR~R8Lm2S#0Kihued=2&~zM$$HE{|5PoXl3YZ!cDFAH^$x@d0dE{I3+o8el-( zV}ObKHVYMIyoMVL@s>)su@d(wZo}Uh{AK$TzXC56Kgx~+FMMpSOIOA@u);iN>I>&M zHD4KQm+w5r;rq;CKJ%2376#mncC%m}!ubdF*VrzFPrhgA9AVK3qwWH1lZ`gb0j~21 z=_b}E-%-u&cM~5R&k$+7nAL^fk|o=foaNcq>YUH`oSjJmees>nR3X+ScOPetcNQ99 zd;091DKhxPCoVf=qg7b}{2U%!b`0>TA0AhLe6-ywUFb6cJ#cJAb@-Zs=zwX`r+JNJ zn)6bhc5nS^k~M^%){nFC0$ou5N#?N*>NJ$U*ralVd87-7gN-IwPlwO(Kz<+}dEYu; z5k}F6;3FP%4rb-E#&gnzBKW$Gp2<9iWqJ0oqkA%Mfyrq_&zxqau_zzAU{8bKl%*I) zYJyLBBok$D^m3CN6HGld*+(57f9LY1!zy}Las_sQ!^%BF8QIMuIAvw1TYMh&p+y;N zDkuBMb(+eG()dF-2!j(KI0l0=qB)#D9Y@PsN73rlNk+}@@ zUD;M`-Z9rM&ei=F)GfZRSloJ7YO-y*{Lnt(uGRjNlPzPm!Zwc}WSi|GnM0XZ&kP>o ztmM-$ubTWCUB*cENXDtJ{gLi+5D)$vy@>br;-8$p{0HAYL*D{xV&7DU_+Pfi%6W^v z`fl#X@0ZYigbkjFCmdeJXS5ON`3u@c6Fi$w@bdhvGn{*fZUj@k8|2)!m#W)8BhQ!* zNLs zvuL$`7X9*bx1!DAEts3$hy1f>`Sw}#?&q$eA0A#szX!Qg7ry7K+HN5~e(y@nS9q9r z0)I4bMXwZLkS`;9rLU9nwajn2e7eq0*eBMt$}-q0(|n}X$A<4&q7KtpC5MT;)iLM$ zct(2!`i?O4G7d+{C;X<5vKhEu2mL@=5Dm%qPwc=GHAnFF_?)91wb$l1)UD0khwt#V zCfecp8e??%*m2&__ka|RsSQ?X9MGFrD&|Ml0Bx`$w zLv479?TN0YaVY!^cykzv<^~y1ZF6IL^qjuS!`mai`aGt$&E5eQ-j<$2*(XkK>Jw!d z<(&F*Nfi%D?9XNnu~jpO&pLvO1P-I + CompareGold — Stride Image Comparison @@ -36,8 +37,10 @@

CompareGold

- + + + diff --git a/build/tools/Stride.CompareGold/wwwroot/style.css b/build/tools/Stride.CompareGold/wwwroot/style.css index c5dd78c01a..bb0b26d378 100644 --- a/build/tools/Stride.CompareGold/wwwroot/style.css +++ b/build/tools/Stride.CompareGold/wwwroot/style.css @@ -49,6 +49,7 @@ tr.suite-row td { padding: 10px 12px; border-bottom: 2px solid #333; } .suite-toggle { margin-right: 6px; color: #888; } .suite-badge { font-size: 11px; color: #888; background: #2a2a4a; padding: 2px 8px; border-radius: 8px; margin-left: 8px; } .suite-badge.fail { color: #ef5350; background: #3a1a1a; } +.suite-badge.pending { color: #888; background: #2a2a3a; } .cb { width: 24px; text-align: center; } .cb input { cursor: pointer; } @@ -58,6 +59,9 @@ tr.suite-row td { padding: 10px 12px; border-bottom: 2px solid #333; } .cell.pass { color: #66bb6a; } .cell.fail { color: #ef5350; } .cell.new { color: #ffa726; } +.tag-fail { font-size: 10px; background: #5a1a1a; color: #ef5350; padding: 1px 6px; border-radius: 3px; margin-left: 6px; } +.tag-new { font-size: 10px; background: #4a3a1a; color: #ffa726; padding: 1px 6px; border-radius: 3px; margin-left: 6px; } +.tag-pending { font-size: 10px; background: #2a2a3a; color: #888; padding: 1px 6px; border-radius: 3px; margin-left: 6px; } .cell.miss { color: #555; } .cell.ref { color: #888; } diff --git a/tests/compare-gold.cmd b/tests/compare-gold.cmd index d45753a9bb..4ab04ecca1 100644 --- a/tests/compare-gold.cmd +++ b/tests/compare-gold.cmd @@ -1,2 +1,3 @@ @echo off -dotnet run --project "%~dp0..\build\tools\CompareGold" +taskkill /F /IM Stride.CompareGold.exe >nul 2>&1 +dotnet run --project "%~dp0..\build\tools\Stride.CompareGold" From c11a76a1c31504379ce083750e07f81065bd4242 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 15:07:36 +0900 Subject: [PATCH 1060/1182] fix: Remove HDR clamp in range compress/decompress shaders Remove the 2047/2048 f16 clamp that capped HDR values on all platforms. Replaced with a denominator > 0 NaN guard in the decompressor to handle the edge case where maxComponent rounds to 1.0 in f16 (e.g. on SwiftShader). --- .../Images/RangeConversion/RangeCompressorShader.sdsl | 11 +---------- .../RangeConversion/RangeDecompressorShader.sdsl | 7 ++----- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl index f9644ee726..2c8c87d18f 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeCompressorShader.sdsl @@ -18,16 +18,7 @@ namespace Stride.Rendering.Images float targetRange = 1.0; float maxComponent = max(max(color.r, color.g), color.b); // http://graphicrants.blogspot.jp/2013/12/tone-mapping.html - float3 brianKarisToned = color / (1 + maxComponent / targetRange); - - // Clamp to prevent NaN in RangeDecompressorShader's inverse (division by 1 - maxComponent). - // Result is stored in RGBA16F: values too close to 1.0 may round up to 1.0 in half-float, - // causing division by zero. This is quite brittle — software renderers like SwiftShader - // easily round to 1.0, while GPU hardware needs values close to 1.0 for high HDR precision. - // 2047/2048 is the best compromise: it's the largest half-float value that stays below 1.0. - // TODO: This range compression/decompression approach should be reevaluated to avoid - // relying on half-float precision edge cases. - float3 mapped = min(brianKarisToned, 2047.0f / 2048.0f); + float3 mapped = color / (1 + maxComponent / targetRange); // and we don't apply gamma. because of big outlining artefact around [0-1] range objects in front of high [10-80] range emissive objects. // write output for FXAA: diff --git a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl index 3f8b3de072..d242209e50 100644 --- a/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Images/RangeConversion/RangeDecompressorShader.sdsl @@ -9,14 +9,11 @@ namespace Stride.Rendering.Images { float3 color = Texture0.Sample(PointSampler, streams.TexCoord).rgb; - float3 linearColor = color; - // reverse karis tone map: float targetRange = 1.0; - float maxComponent = max(max(linearColor.r, linearColor.g), linearColor.b); - maxComponent = min(maxComponent, 2047.0f / 2048.0f); + float maxComponent = max(max(color.r, color.g), color.b); float denominator = 1 - maxComponent / targetRange; - float3 reverseKaris = linearColor / denominator; + float3 reverseKaris = denominator > 0 ? color / denominator : color; // write output for the rest of the post effects: return float4(reverseKaris, 1.0); From e4f3f91d3a0af6eff3d89a50a560b26c3ac36fb4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 15:07:36 +0900 Subject: [PATCH 1061/1182] fix: SDSL cache double-check validation The lazy inner double-check in ShaderLoaderBase.LoadExternalBuffer skipped ValidateCachedHashes, so when the outer check detected a source hash mismatch and fell through, the inner check would hit the same (memory-cached) stale entry and return it unchanged. Now the inner check also validates hashes. --- sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs index bcc36a09c3..e62c804347 100644 --- a/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs +++ b/sources/shaders/Stride.Shaders.Compilers/ShaderLoaderBase.cs @@ -60,7 +60,7 @@ public bool LoadExternalBuffer(string name, ReadOnlySpan defines, [ var lazy = compilingShaders.GetOrAdd(key, _ => new Lazy<(ShaderBuffers, ObjectId)>(() => { // Double-check cache (another thread may have finished between our check and this factory) - if (Cache.TryLoadFromCache(name, null, macrosArray, out var buf, out var h)) + if (Cache.TryLoadFromCache(name, null, macrosArray, out var buf, out var h) && ValidateCachedHashes(buf)) return (buf, h); if (!ExternalFileExists(name)) From e91a6cc3dec1ac12ffc8410683ce50f89289ab9f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 14:42:10 +0900 Subject: [PATCH 1062/1182] ci: add workflow to build spirv_to_dxil.dll from Mesa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reproducible Windows x64 build of Mesa's spirv_to_dxil library. Workflow produces an artifact that can be downloaded and checked in to sources/shaders/Stride.Shaders.Compilers/native/. Minimal Meson config (no LLVM, no Vulkan drivers, no Gallium) — only builds the spirv_to_dxil target. --- .github/workflows/dep-freetype.yml | 7 +- .github/workflows/dep-spirv-to-dxil.yml | 121 +++++++++++++ build/deps/spirv-to-dxil/mesa-pipeline.patch | 175 +++++++++++++++++++ 3 files changed, 301 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/dep-spirv-to-dxil.yml create mode 100644 build/deps/spirv-to-dxil/mesa-pipeline.patch diff --git a/.github/workflows/dep-freetype.yml b/.github/workflows/dep-freetype.yml index 2b5c02acea..1fc70dc252 100644 --- a/.github/workflows/dep-freetype.yml +++ b/.github/workflows/dep-freetype.yml @@ -227,7 +227,7 @@ jobs: needs: [build-windows, build-linux, build-macos, build-android, build-ios] runs-on: ubuntu-24.04 steps: - - name: Checkout (for version info) + - name: Checkout FreeType (for version info) uses: actions/checkout@v4 with: repository: freetype/freetype @@ -262,9 +262,12 @@ jobs: # Version info COMMIT=$(git -C freetype-src rev-parse HEAD) - printf 'FreeType %s\nRepository: https://github.com/freetype/freetype\nCommit: %s\nBuilt: %s\nWorkflow: %s\n' \ + URL=$(git -C freetype-src config --get remote.origin.url) + printf 'FreeType %s\nRepository: %s\nCommit: %s\nStride: %s/%s @ %s\nBuilt: %s\nWorkflow: %s\n' \ "${{ github.event.inputs.freetype-version }}" \ + "$URL" \ "$COMMIT" \ + "${{ github.server_url }}" "${{ github.repository }}" "${{ github.sha }}" \ "$(date -u +%Y-%m-%d)" \ "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \ > $OUT/VERSION.txt diff --git a/.github/workflows/dep-spirv-to-dxil.yml b/.github/workflows/dep-spirv-to-dxil.yml new file mode 100644 index 0000000000..aa60f9ce53 --- /dev/null +++ b/.github/workflows/dep-spirv-to-dxil.yml @@ -0,0 +1,121 @@ +name: "Dep: Build spirv_to_dxil (Mesa)" + +on: + workflow_dispatch: + inputs: + repository: + description: Mesa git URL + default: https://gitlab.freedesktop.org/mesa/mesa.git + required: false + branch: + description: Mesa branch/ref to build + default: main + required: false + +jobs: + build-windows: + name: Build spirv_to_dxil (Windows x64) + runs-on: windows-2025-vs2026 + steps: + - name: Checkout Stride (for patch file) + uses: actions/checkout@v4 + with: + path: stride-src + sparse-checkout: build/deps/spirv-to-dxil + + - name: Clone Mesa + shell: pwsh + run: | + git clone --depth 1 --branch "${{ github.event.inputs.branch || 'main' }}" ` + "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" mesa-src + + - name: Apply Stride patch + shell: pwsh + working-directory: mesa-src + run: | + git apply --verbose "${{ github.workspace }}/stride-src/build/deps/spirv-to-dxil/mesa-pipeline.patch" + + - name: Install build dependencies + shell: pwsh + run: | + python -m pip install --upgrade pip + python -m pip install meson ninja mako pyyaml packaging + + - name: Setup MSVC environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: Configure Mesa + shell: cmd + working-directory: mesa-src + run: | + set PYTHONUTF8=1 + meson setup _build ^ + --default-library=shared ^ + --buildtype=release ^ + --wrap-mode=default ^ + -Dc_args="/wd4189" ^ + -Dcpp_args="/wd4189" ^ + -Dshared-glapi=disabled ^ + -Dgles1=disabled ^ + -Dgles2=disabled ^ + -Dopengl=false ^ + -Degl=disabled ^ + -Dglx=disabled ^ + -Dvulkan-drivers= ^ + -Dgallium-drivers= ^ + -Dplatforms= ^ + -Dmicrosoft-clc=disabled ^ + -Dspirv-to-dxil=true ^ + -Dbuild-tests=false ^ + -Dllvm=disabled + + - name: Build + shell: cmd + working-directory: mesa-src + run: | + set PYTHONUTF8=1 + meson compile -C _build src/microsoft/spirv_to_dxil/spirv_to_dxil:shared_library + + - name: Install UPX + shell: pwsh + run: | + $ver = "4.2.4" + $url = "https://github.com/upx/upx/releases/download/v${ver}/upx-${ver}-win64.zip" + Invoke-WebRequest -Uri $url -OutFile upx.zip + Expand-Archive upx.zip -DestinationPath upx + echo "$PWD\upx\upx-${ver}-win64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Compress DLL + shell: pwsh + run: | + $dll = Get-ChildItem -Recurse mesa-src/_build -Filter spirv_to_dxil.dll | Select-Object -First 1 + $before = (Get-Item $dll.FullName).Length + upx --best --lzma $dll.FullName + $after = (Get-Item $dll.FullName).Length + Write-Host "Before: $([math]::Round($before/1MB,2)) MB" + Write-Host "After: $([math]::Round($after/1MB,2)) MB" + + - name: Collect DLL + shell: pwsh + run: | + New-Item -ItemType Directory -Force -Path out | Out-Null + $dll = Get-ChildItem -Recurse mesa-src/_build -Filter spirv_to_dxil.dll | Select-Object -First 1 + Copy-Item $dll.FullName out/spirv_to_dxil.dll + $pdb = Get-ChildItem -Recurse mesa-src/_build -Filter spirv_to_dxil.pdb -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($pdb) { Copy-Item $pdb.FullName out/spirv_to_dxil.pdb } + # Record commits for traceability + $mesaCommit = git -C mesa-src rev-parse HEAD + $mesaUrl = git -C mesa-src config --get remote.origin.url + @( + "Mesa: $mesaUrl @ $mesaCommit" + "Stride: ${{ github.server_url }}/${{ github.repository }} @ ${{ github.sha }} (for workflow and build/deps/spirv-to-dxil/mesa-pipeline.patch)" + ) | Out-File out/VERSION.txt + Get-ChildItem out + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: spirv_to_dxil-win-x64 + path: out/ diff --git a/build/deps/spirv-to-dxil/mesa-pipeline.patch b/build/deps/spirv-to-dxil/mesa-pipeline.patch new file mode 100644 index 0000000000..ba055a7834 --- /dev/null +++ b/build/deps/spirv-to-dxil/mesa-pipeline.patch @@ -0,0 +1,175 @@ +diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +index 1a8e6e2..3408de3 100644 +--- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c ++++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +@@ -126,3 +126,125 @@ spirv_to_dxil_get_version() + } + return 0; + } ++ ++/* ++ * Stride addition: multi-stage linked compile. ++ * ++ * Compiles all stages of a pipeline together so that dead-code elimination ++ * of inter-stage varyings doesn't break the DXIL I/O signature matching. ++ */ ++bool ++spirv_to_dxil_pipeline(const struct spirv_to_dxil_stage_input *stages, ++ unsigned stage_count, ++ enum dxil_validator_version validator_version_max, ++ const struct dxil_spirv_runtime_conf *conf, ++ const struct dxil_spirv_logger *logger, ++ struct dxil_spirv_object *out_dxils) ++{ ++ if (stage_count == 0 || stage_count > MESA_SHADER_STAGES) ++ return false; ++ ++ glsl_type_singleton_init_or_ref(); ++ ++ struct nir_to_dxil_options opts = { ++ .environment = DXIL_ENVIRONMENT_VULKAN, ++ .shader_model_max = conf->shader_model_max, ++ .validator_version_max = validator_version_max, ++ }; ++ ++ const struct spirv_to_nir_options *spirv_opts = dxil_spirv_nir_get_spirv_options(); ++ nir_shader_compiler_options nir_options; ++ const unsigned supported_bit_sizes = 16 | 32 | 64; ++ dxil_get_nir_compiler_options(&nir_options, conf->shader_model_max, supported_bit_sizes, supported_bit_sizes); ++ nir_options.lower_base_vertex = conf->first_vertex_and_base_instance_mode != DXIL_SPIRV_SYSVAL_TYPE_ZERO; ++ ++ /* Map stage->nir and original input index (to write output back) */ ++ nir_shader *nirs[MESA_SHADER_STAGES] = { NULL }; ++ int input_index_by_stage[MESA_SHADER_STAGES]; ++ for (int i = 0; i < MESA_SHADER_STAGES; ++i) ++ input_index_by_stage[i] = -1; ++ ++ bool success = true; ++ ++ /* Parse all stages */ ++ for (unsigned i = 0; i < stage_count; ++i) { ++ dxil_spirv_shader_stage stage = stages[i].stage; ++ if (stage == DXIL_SPIRV_SHADER_NONE || stage == DXIL_SPIRV_SHADER_KERNEL || ++ stage >= MESA_SHADER_STAGES) { ++ success = false; ++ goto cleanup; ++ } ++ if (nirs[stage]) { ++ /* Duplicate stage */ ++ success = false; ++ goto cleanup; ++ } ++ nir_shader *nir = spirv_to_nir( ++ stages[i].words, stages[i].word_count, NULL, 0, ++ (mesa_shader_stage)stage, stages[i].entry_point_name, ++ spirv_opts, &nir_options); ++ if (!nir) { ++ success = false; ++ goto cleanup; ++ } ++ nir_validate_shader(nir, "Validate SPIR-V to NIR output"); ++ dxil_spirv_nir_prep(nir); ++ nirs[stage] = nir; ++ input_index_by_stage[stage] = (int)i; ++ } ++ ++ /* Run per-stage passes */ ++ struct dxil_spirv_metadata metadata[MESA_SHADER_STAGES] = { 0 }; ++ for (int stage = 0; stage < MESA_SHADER_STAGES; ++stage) { ++ if (nirs[stage]) ++ dxil_spirv_nir_passes(nirs[stage], conf, &metadata[stage]); ++ } ++ ++ /* Link consecutive stages (later -> earlier). For each stage with a ++ * previous stage present, call dxil_spirv_nir_link. This removes unused ++ * outputs/inputs and reassigns driver_location consistently across stage ++ * boundaries, matching what spirv2dxil.c does. ++ */ ++ for (int cur = MESA_SHADER_FRAGMENT; cur >= MESA_SHADER_VERTEX; --cur) { ++ if (!nirs[cur]) ++ continue; ++ for (int prev = cur - 1; prev >= MESA_SHADER_VERTEX; --prev) { ++ if (!nirs[prev]) ++ continue; ++ struct dxil_spirv_metadata link_meta = { 0 }; ++ dxil_spirv_nir_link(nirs[cur], nirs[prev], conf, &link_meta); ++ break; ++ } ++ } ++ ++ struct dxil_logger logger_inner = { ++ .priv = logger->priv, ++ .log = logger->log, ++ }; ++ ++ /* Emit DXIL for each stage in pipeline order */ ++ for (int stage = 0; stage < MESA_SHADER_STAGES; ++stage) { ++ if (!nirs[stage]) ++ continue; ++ int out_index = input_index_by_stage[stage]; ++ struct blob dxil_blob; ++ if (!nir_to_dxil(nirs[stage], &opts, &logger_inner, &dxil_blob)) { ++ if (dxil_blob.allocated) ++ blob_finish(&dxil_blob); ++ success = false; ++ goto cleanup; ++ } ++ out_dxils[out_index].metadata = metadata[stage]; ++ blob_finish_get_buffer(&dxil_blob, &out_dxils[out_index].binary.buffer, ++ &out_dxils[out_index].binary.size); ++ } ++ ++cleanup: ++ for (int stage = 0; stage < MESA_SHADER_STAGES; ++stage) { ++ if (nirs[stage]) ++ ralloc_free(nirs[stage]); ++ } ++ glsl_type_singleton_decref(); ++ ++ return success; ++} +diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.def b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def +index 62851f2..1c6f26c 100644 +--- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.def ++++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def +@@ -2,3 +2,4 @@ EXPORTS + spirv_to_dxil + spirv_to_dxil_free + spirv_to_dxil_get_version ++ spirv_to_dxil_pipeline +diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h +index 00b1884..902716c 100644 +--- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h ++++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h +@@ -236,6 +236,31 @@ spirv_to_dxil(const uint32_t *words, size_t word_count, + const struct dxil_spirv_logger *logger, + struct dxil_spirv_object *out_dxil); + ++/** ++ * Input descriptor for a single stage in a linked pipeline compile. ++ */ ++struct spirv_to_dxil_stage_input { ++ const uint32_t *words; ++ size_t word_count; ++ dxil_spirv_shader_stage stage; ++ const char *entry_point_name; ++}; ++ ++/** ++ * Compile all shader stages of a pipeline together, linking between ++ * stages so that unused varyings are stripped consistently and DXIL ++ * I/O signatures match across stage boundaries. ++ * ++ * out_dxils[i] receives the compiled DXIL for stages[i]. ++ */ ++bool ++spirv_to_dxil_pipeline(const struct spirv_to_dxil_stage_input *stages, ++ unsigned stage_count, ++ enum dxil_validator_version validator_version_max, ++ const struct dxil_spirv_runtime_conf *conf, ++ const struct dxil_spirv_logger *logger, ++ struct dxil_spirv_object *out_dxils); ++ + /** + * Free the buffer allocated by spirv_to_dxil. + */ From 3609c84d73b5e8fa52658fa67d70be83caa4706e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 17:01:07 +0900 Subject: [PATCH 1063/1182] fix: use spirv_to_dxil_pipeline for linked multi-stage D3D12 compile --- .../Direct3D/Spv2DXIL.cs | 39 ++++++ .../EffectCompiler.cs | 114 ++++++++++++------ .../native/spirv_to_dxil.VERSION.txt | 2 + .../native/spirv_to_dxil.dll | 4 +- 4 files changed, 119 insertions(+), 40 deletions(-) create mode 100644 sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs index a7b7efea87..87c274e398 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/Spv2DXIL.cs @@ -175,4 +175,43 @@ out DXILSpirvObject out_dxil [LibraryImport("spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf16, SetLastError = true)] public static partial ulong spirv_to_dxil_get_version(); + + // Linked multi-stage compile — required for correct I/O signature matching when some + // stages don't read all outputs from the previous stage (e.g. PS that doesn't use normalWS + // from VS). Without linking, spirv_to_dxil strips unused inputs and compacts Locations, + // causing the PS signature to no longer match the VS output signature. + // + // This function is a Stride-specific addition to the Mesa fork. Expected signature: + // bool spirv_to_dxil_pipeline( + // const SpirvStageInput* stages, + // int stage_count, + // ValidatorVersion validator_version_max, + // RuntimeConf* conf, + // DXILSpirvLogger* logger, + // DXILSpirvObject* outputs // array of size stage_count + // ); + [LibraryImport("spirv_to_dxil.dll", StringMarshalling = StringMarshalling.Utf8, SetLastError = true)] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] + [return: MarshalAs(UnmanagedType.Bool)] + public static unsafe partial bool spirv_to_dxil_pipeline( + SpirvStageInput* stages, + int stage_count, + ValidatorVersion validator_version_max, + ref RuntimeConf conf, + ref DXILSpirvLogger logger, + DXILSpirvObject* outputs + ); +} + +/// +/// Input descriptor for a single shader stage in a linked pipeline compile. +/// +[StructLayout(LayoutKind.Sequential)] +public unsafe struct SpirvStageInput +{ + public uint* words; + public nint word_count; + public ShaderStage stage; + /// UTF-8 null-terminated entry point name. + public byte* entry_point_name; } diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 75471e110f..a6479500d5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -23,6 +23,7 @@ using Stride.Shaders.Compilers.SDSL; using Stride.Shaders.Spirv.Building; using Stride.Shaders.Spirv.Core.Buffers; +using Stride.Shaders.Spirv.Processing.Interfaces; using Stride.Shaders.Spirv.Tools; using Encoding = System.Text.Encoding; using LoggerResult = Stride.Core.Diagnostics.LoggerResult; @@ -286,44 +287,7 @@ public override TaskOrResult Compile(ShaderMixinSo { // Check API Spv2DXIL.spirv_to_dxil_get_version(); - foreach (var entryPoint in entryPoints) - { - unsafe - { - fixed (byte* shaderData = spirvBytecode) - { - var debugOptions = new DebugOptions(); - var runtimeConf = new RuntimeConf - { - runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, - //first_vertex_and_base_instance_mode = SysvalType.Zero, - yzflip_mode = FlipMode.YZFlipNone, - shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, - }; - var logger = new DXILSpirvLogger(); - var result = Spv2DXIL.spirv_to_dxil((uint*)shaderData, spirvBytecode.Length / 4, - null, 0, - entryPoint.Stage switch - { - ShaderStage.Vertex => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_VERTEX, - ShaderStage.Hull => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, - ShaderStage.Domain => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, - ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, - ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, - ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, - _ => throw new NotSupportedException($"Unsupported shader stage: {entryPoint.Stage}"), - }, - entryPoint.Name, - ValidatorVersion.DXIL_VALIDATOR_1_4, - ref debugOptions, ref runtimeConf, ref logger, out var dxil); - - Span dxilSpan = new(dxil.buffer, (int)dxil.size); - fixed (byte* dxilSpanPtr = dxilSpan) - DxilHash.ComputeHashRetail(&dxilSpanPtr[20], (uint)(dxilSpan.Length - 20), &dxilSpanPtr[4]); - shaderStageBytecodes.Add(new ShaderBytecode(entryPoint.Stage, ObjectId.FromBytes(dxilSpan), dxilSpan.ToArray())); - } - } - } + CompileDxilPipeline(spirvBytecode, entryPoints, shaderStageBytecodes); } else { @@ -550,6 +514,80 @@ public override TaskOrResult Compile(ShaderMixinSo /// /// Writes .spv and .spvdis files. Caller must hold WriterLock. /// + /// + /// Compile SPIR-V to DXIL for all stages in a single linked call. Needed so spirv_to_dxil + /// can match PS inputs to VS outputs correctly when some varyings are unused. + /// + private static unsafe void CompileDxilPipeline(ReadOnlySpan spirvBytecode, List entryPoints, List shaderStageBytecodes) + { + var runtimeConf = new RuntimeConf + { + runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, + yzflip_mode = FlipMode.YZFlipNone, + shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, + }; + var logger = new DXILSpirvLogger(); + + // Allocate native buffers for entry point names (UTF-8 null-terminated) + var entryPointNameBuffers = new byte[entryPoints.Count][]; + for (int i = 0; i < entryPoints.Count; i++) + { + var name = entryPoints[i].Name; + var bytes = new byte[Encoding.UTF8.GetByteCount(name) + 1]; + Encoding.UTF8.GetBytes(name, bytes); + entryPointNameBuffers[i] = bytes; + } + + var stages = stackalloc SpirvStageInput[entryPoints.Count]; + var outputs = stackalloc DXILSpirvObject[entryPoints.Count]; + + fixed (byte* shaderData = spirvBytecode) + { + // Pin entry point name buffers + var nameHandles = new System.Runtime.InteropServices.GCHandle[entryPoints.Count]; + try + { + for (int i = 0; i < entryPoints.Count; i++) + { + nameHandles[i] = System.Runtime.InteropServices.GCHandle.Alloc(entryPointNameBuffers[i], System.Runtime.InteropServices.GCHandleType.Pinned); + stages[i] = new SpirvStageInput + { + words = (uint*)shaderData, + word_count = spirvBytecode.Length / 4, + stage = entryPoints[i].Stage switch + { + ShaderStage.Vertex => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_VERTEX, + ShaderStage.Hull => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_CTRL, + ShaderStage.Domain => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_TESS_EVAL, + ShaderStage.Geometry => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_GEOMETRY, + ShaderStage.Pixel => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_FRAGMENT, + ShaderStage.Compute => Compilers.Direct3D.ShaderStage.DXIL_SPIRV_SHADER_COMPUTE, + _ => throw new NotSupportedException($"Unsupported shader stage: {entryPoints[i].Stage}"), + }, + entry_point_name = (byte*)nameHandles[i].AddrOfPinnedObject(), + }; + } + + if (!Spv2DXIL.spirv_to_dxil_pipeline(stages, entryPoints.Count, ValidatorVersion.DXIL_VALIDATOR_1_4, ref runtimeConf, ref logger, outputs)) + throw new InvalidOperationException("spirv_to_dxil_pipeline failed"); + + for (int i = 0; i < entryPoints.Count; i++) + { + var dxil = outputs[i]; + Span dxilSpan = new(dxil.buffer, (int)dxil.size); + fixed (byte* dxilSpanPtr = dxilSpan) + DxilHash.ComputeHashRetail(&dxilSpanPtr[20], (uint)(dxilSpan.Length - 20), &dxilSpanPtr[4]); + shaderStageBytecodes.Add(new ShaderBytecode(entryPoints[i].Stage, ObjectId.FromBytes(dxilSpan), dxilSpan.ToArray())); + } + } + finally + { + for (int i = 0; i < entryPoints.Count; i++) + if (nameHandles[i].IsAllocated) nameHandles[i].Free(); + } + } + } + private static void WriteSpvDebugFiles(string effectDir, string hashName, byte[] spirvBytecode) { var baseFilename = Path.Combine(effectDir, hashName); diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt new file mode 100644 index 0000000000..da3b85e5e9 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt @@ -0,0 +1,2 @@ +Mesa: https://gitlab.freedesktop.org/mesa/mesa.git @ 477c44ba93986e9aa4feae20f7e3777586a50ed1 +Stride: https://github.com/xen2/stride @ e91a6cc3dec1ac12ffc8410683ce50f89289ab9f (for workflow and build/deps/spirv-to-dxil/mesa-pipeline.patch) diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll index 3005432c94..9be68fd8a9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d297308f57af16ca5913232e5b9fa8e1f30fcde9073622883bc811a7413a32b6 -size 7740416 +oid sha256:c45921fd43e8283597a33f96090ff563f24d9cf8cf33e938a25d21c403110f6e +size 665600 From b3e575b1875039ff5df69595d0b00ba93db3b8e5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 17:30:18 +0900 Subject: [PATCH 1064/1182] test: Updated gold image for Vulkan TestImageEffect --- .../Windows.Vulkan/SwiftShader/TestImageEffect.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png index a586bc3ab0..f7386cedee 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d01c93567617b320087d0221f400a3f1cd7e26f7315d4d690808ea24ca0a247 -size 469071 +oid sha256:c4315cc16a8580bba0e90331392601c11cf6d556247c0b9c07a640fa03c446c3 +size 437116 From 077e6de11e6cf93828395f8d8a1805079c631d92 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 16 Apr 2026 17:40:13 +0900 Subject: [PATCH 1065/1182] fix: iOS build was broken due to missing #if --- .../EffectCompiler.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index a6479500d5..ba7e0020ee 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -285,9 +285,18 @@ public override TaskOrResult Compile(ShaderMixinSo // TODO: Move that code inside ShaderCompiler (need a new interface for processing SPIR-V) else if (effectParameters.Platform == GraphicsPlatform.Direct3D12) { - // Check API - Spv2DXIL.spirv_to_dxil_get_version(); - CompileDxilPipeline(spirvBytecode, entryPoints, shaderStageBytecodes); +#if STRIDE_PLATFORM_DESKTOP + if (OperatingSystem.IsWindows()) + { + // Check API + Spv2DXIL.spirv_to_dxil_get_version(); + CompileDxilPipeline(spirvBytecode, entryPoints, shaderStageBytecodes); + } + else +#endif + { + throw new NotImplementedException("D3D12 shader compilation is not supported on this platform"); + } } else { @@ -511,9 +520,6 @@ public override TaskOrResult Compile(ShaderMixinSo } #if STRIDE_PLATFORM_DESKTOP - /// - /// Writes .spv and .spvdis files. Caller must hold WriterLock. - /// /// /// Compile SPIR-V to DXIL for all stages in a single linked call. Needed so spirv_to_dxil /// can match PS inputs to VS outputs correctly when some varyings are unused. @@ -588,6 +594,9 @@ private static unsafe void CompileDxilPipeline(ReadOnlySpan spirvBytecode, } } + /// + /// Writes .spv and .spvdis files. Caller must hold WriterLock. + /// private static void WriteSpvDebugFiles(string effectDir, string hashName, byte[] spirvBytecode) { var baseFilename = Path.Combine(effectDir, hashName); From 3ceb55508b2ebd347630413b18a06169499af381 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 18 Apr 2026 01:27:29 +0900 Subject: [PATCH 1066/1182] fix: resolve Result ambiguity with Android.App.Result in SpirvTranslator --- sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs index 496f1391dd..7a2b3ca1a3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SpirvTranslator.cs @@ -9,6 +9,7 @@ namespace Stride.Shaders.Compilers; using Compiler = Silk.NET.SPIRV.Cross.Compiler; +using Result = Silk.NET.SPIRV.Cross.Result; public unsafe record struct SpirvTranslator(ReadOnlyMemory Words) { From 5f8f8d3d026719637700ba9f45a03b4232a9b358 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 18 Apr 2026 01:42:59 +0900 Subject: [PATCH 1067/1182] fix: SPIR-V: emit TES-only tessellation modes on DSMain per spec --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 28ae923f02..9e88c072d8 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -467,6 +467,24 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) table.CurrentShader!.Methods.Add((symbol, functionFlags)); } + // SPIR-V spec: SpacingX / VertexOrderX / PointMode execution modes are only valid on + // TessellationEvaluation entry points. HLSL places them on the hull shader function, + // so for spec compliance we emit them on DSMain's function id instead. Throws if + // no DSMain method is declared — a tessellation control shader without a matching + // evaluation shader cannot produce valid SPIR-V anyway. + private static int GetTessEvaluationFunctionId(SymbolTable table, int fallbackId) + { + if (table.CurrentShader != null) + { + foreach (var (symbol, _) in table.CurrentShader.Methods) + { + if (symbol.Id.Name == "DSMain") + return symbol.IdRef; + } + } + return fallbackId; + } + private static PointerType GenerateParameterType(MethodParameter p) { // Opaque types (image/sampler) must use UniformConstant storage class — @@ -532,17 +550,28 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler } else if (anyAttribute.Name == "domain") { - context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + // Triangles/Quads/Isolines are valid on either TCS or TES per spec. + // We emit them only on DSMain (TES), matching glslang's convention + // and keeping the SPIR-V minimal. HLSL's [domain] on HS is therefore + // skipped here; HLSL also requires [domain] on DS, so DSMain's own + // [domain] attribute guarantees the mode ends up in the module. + if (EntryPoint != EntryPoint.HullShader) { - "tri" => Specification.ExecutionMode.Triangles, - "quad" => Specification.ExecutionMode.Quads, - "isolined" => Specification.ExecutionMode.Isolines, - _ => throw new NotSupportedException($"Unsupported domain value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"), - }, [])); + context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + { + "tri" => Specification.ExecutionMode.Triangles, + "quad" => Specification.ExecutionMode.Quads, + "isolined" => Specification.ExecutionMode.Isolines, + _ => throw new NotSupportedException($"Unsupported domain value '{((StringLiteral)anyAttribute.Parameters[0]).Value}'"), + }, [])); + } } else if (anyAttribute.Name == "partitioning") { - context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + // Spacing execution modes are only valid on TessellationEvaluation + // per SPIR-V spec, but HLSL puts [partitioning] on the hull shader. + // Emit the mode on DSMain's function id so the SPIR-V is spec-compliant. + context.Add(new OpExecutionMode(GetTessEvaluationFunctionId(table, function.Id), ((StringLiteral)anyAttribute.Parameters[0]).Value switch { "fractional_odd" => Specification.ExecutionMode.SpacingFractionalOdd, "fractional_even" => Specification.ExecutionMode.SpacingFractionalEven, @@ -556,7 +585,9 @@ public void Compile(SymbolTable table, ShaderClass shader, CompilerUnit compiler var value = ((StringLiteral)anyAttribute.Parameters[0]).Value; if (value != "line") { - context.Add(new OpExecutionMode(function.Id, ((StringLiteral)anyAttribute.Parameters[0]).Value switch + // VertexOrderCw/Ccw are only valid on TessellationEvaluation per + // SPIR-V spec; route to DSMain (same reason as partitioning above). + context.Add(new OpExecutionMode(GetTessEvaluationFunctionId(table, function.Id), ((StringLiteral)anyAttribute.Parameters[0]).Value switch { "triangle_cw" => Specification.ExecutionMode.VertexOrderCw, "triangle_ccw" => Specification.ExecutionMode.VertexOrderCcw, From ccbf28319d65448510cd80da2b9f31fbaa7aef84 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 18 Apr 2026 01:43:00 +0900 Subject: [PATCH 1068/1182] build: pin CompilerApp ProjectReference to xplat TFM to fix VS GetTargetPath error --- sources/sdk/Stride.Build.Sdk.Tests/Sdk/Sdk.targets | 2 +- sources/targets/Stride.UnitTests.targets | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/sdk/Stride.Build.Sdk.Tests/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk.Tests/Sdk/Sdk.targets index 056607a57c..42960241b4 100644 --- a/sources/sdk/Stride.Build.Sdk.Tests/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk.Tests/Sdk/Sdk.targets @@ -70,7 +70,7 @@ false false - TargetFramework + TargetFramework=$(StrideXplatEditorTargetFramework) true diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index 202f2ce2fd..cb5bab817d 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -21,7 +21,7 @@ false false - TargetFramework + TargetFramework=$(StrideXplatEditorTargetFramework) true From 170d82c62a499a18fc8483c217bb7e08992461fe Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 18 Apr 2026 15:19:18 +0900 Subject: [PATCH 1069/1182] ci: fetch Mesa by ref (branch/tag/SHA/MR) and included latest local changes --- .github/workflows/dep-spirv-to-dxil.yml | 16 ++- build/deps/spirv-to-dxil/mesa-pipeline.patch | 115 ++++++++++++++++++- 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dep-spirv-to-dxil.yml b/.github/workflows/dep-spirv-to-dxil.yml index aa60f9ce53..4324961ec9 100644 --- a/.github/workflows/dep-spirv-to-dxil.yml +++ b/.github/workflows/dep-spirv-to-dxil.yml @@ -7,8 +7,8 @@ on: description: Mesa git URL default: https://gitlab.freedesktop.org/mesa/mesa.git required: false - branch: - description: Mesa branch/ref to build + ref: + description: Mesa ref to build (branch, tag, SHA, or refs/merge-requests//head) default: main required: false @@ -26,14 +26,18 @@ jobs: - name: Clone Mesa shell: pwsh run: | - git clone --depth 1 --branch "${{ github.event.inputs.branch || 'main' }}" ` - "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" mesa-src + $url = "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" + $ref = "${{ github.event.inputs.ref || 'main' }}" + git init mesa-src + git -C mesa-src remote add origin $url + git -C mesa-src fetch --depth 1 origin $ref + git -C mesa-src checkout FETCH_HEAD - - name: Apply Stride patch + - name: Apply Stride pipeline patch shell: pwsh working-directory: mesa-src run: | - git apply --verbose "${{ github.workspace }}/stride-src/build/deps/spirv-to-dxil/mesa-pipeline.patch" + git apply --3way --verbose "${{ github.workspace }}/stride-src/build/deps/spirv-to-dxil/mesa-pipeline.patch" - name: Install build dependencies shell: pwsh diff --git a/build/deps/spirv-to-dxil/mesa-pipeline.patch b/build/deps/spirv-to-dxil/mesa-pipeline.patch index ba055a7834..f9cda8f6f2 100644 --- a/build/deps/spirv-to-dxil/mesa-pipeline.patch +++ b/build/deps/spirv-to-dxil/mesa-pipeline.patch @@ -1,8 +1,100 @@ +diff --git a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c +index 460af16..4273abd 100644 +--- a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c ++++ b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c +@@ -103,6 +103,10 @@ dxil_spirv_nir_get_spirv_options(void) + return &spirv_to_nir_options; + } + ++/* Stride: keep I/O variables marked always_active_io alive (forward decl, definition later) */ ++static bool ++dxil_spirv_can_remove_io_var(nir_variable *var, void *data); ++ + /* Logic extracted from vk_spirv_to_nir() so we have the same preparation + * steps for both the vulkan driver and the lib used by the WebGPU + * implementation. +@@ -139,11 +143,17 @@ dxil_spirv_nir_prep(nir_shader *nir) + NIR_PASS(_, nir, nir_split_var_copies); + NIR_PASS(_, nir, nir_split_per_member_structs); + +- NIR_PASS(_, nir, nir_remove_dead_variables, +- nir_var_shader_in | nir_var_shader_out | nir_var_system_value | +- nir_var_shader_call_data | nir_var_ray_hit_attrib, +- NULL); +- ++ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ ++ { ++ static const struct nir_remove_dead_variables_options _opts = { ++ .can_remove_var = dxil_spirv_can_remove_io_var, ++ }; ++ NIR_PASS(_, nir, nir_remove_dead_variables, ++ nir_var_shader_in | nir_var_shader_out | nir_var_system_value | ++ nir_var_shader_call_data | nir_var_ray_hit_attrib, ++ &_opts); ++ } ++ + /* This needs to happen after remove_dead_vars because GLSLang likes to + * insert dead clip/cull vars and we don't want to clip/cull based on + * uninitialized garbage. +@@ -787,6 +797,13 @@ lower_view_index_to_rt_layer(nir_shader *nir) + } + } + ++/* Stride: keep I/O variables marked always_active_io alive */ ++static bool ++dxil_spirv_can_remove_io_var(nir_variable *var, void *data) ++{ ++ return !var->data.always_active_io; ++} ++ + void + dxil_spirv_nir_link(nir_shader *nir, nir_shader *prev_stage_nir, + const struct dxil_spirv_runtime_conf *conf, +@@ -1007,10 +1024,16 @@ dxil_spirv_nir_passes(nir_shader *nir, + + NIR_PASS(_, nir, dxil_spirv_nir_discard_point_size_var); + +- NIR_PASS(_, nir, nir_remove_dead_variables, +- nir_var_shader_in | nir_var_shader_out | +- nir_var_system_value | nir_var_mem_shared, +- NULL); ++ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ ++ { ++ static const struct nir_remove_dead_variables_options _opts2 = { ++ .can_remove_var = dxil_spirv_can_remove_io_var, ++ }; ++ NIR_PASS(_, nir, nir_remove_dead_variables, ++ nir_var_shader_in | nir_var_shader_out | ++ nir_var_system_value | nir_var_mem_shared, ++ &_opts2); ++ } + + uint32_t push_constant_size = 0; + NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_push_const, +@@ -1121,9 +1144,15 @@ dxil_spirv_nir_passes(nir_shader *nir, + NIR_PASS(_, nir, dxil_nir_lower_ubo_array_one_to_static); + NIR_PASS(_, nir, nir_opt_dce); + NIR_PASS(_, nir, nir_remove_dead_derefs); +- NIR_PASS(_, nir, nir_remove_dead_variables, +- nir_var_uniform | nir_var_shader_in | nir_var_shader_out, +- NULL); ++ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ ++ { ++ static const struct nir_remove_dead_variables_options _opts = { ++ .can_remove_var = dxil_spirv_can_remove_io_var, ++ }; ++ NIR_PASS(_, nir, nir_remove_dead_variables, ++ nir_var_uniform | nir_var_shader_in | nir_var_shader_out, ++ &_opts); ++ } + NIR_PASS(_, nir, merge_ubos_and_ssbos); + + if (nir->info.stage == MESA_SHADER_FRAGMENT) { diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c -index 1a8e6e2..3408de3 100644 +index 1a8e6e2..14b0f11 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c -@@ -126,3 +126,125 @@ spirv_to_dxil_get_version() +@@ -126,3 +126,140 @@ spirv_to_dxil_get_version() } return 0; } @@ -68,6 +160,20 @@ index 1a8e6e2..3408de3 100644 + goto cleanup; + } + nir_validate_shader(nir, "Validate SPIR-V to NIR output"); ++ /* Mark all I/O variables as always active so that nir_remove_dead_variables ++ * doesn't strip them. This preserves the I/O signatures across stages, which is ++ * required for D3D12 pipeline state validation (especially for HS<->DS where the ++ * control point and patch constant signatures must match exactly). ++ * ++ * Also keeps HS outputs alive when only read by the patch-constant function ++ * (which the kill pass otherwise treats as unused since they aren't read by DS), ++ * and keeps DS dummy inputs alive (added by Stride to match HS-internal outputs). ++ * ++ * Must happen BEFORE dxil_spirv_nir_prep, since that runs nir_remove_dead_variables ++ * itself and would strip our dummies before they get a chance to be marked. ++ */ ++ nir_foreach_variable_with_modes(var, nir, nir_var_shader_in | nir_var_shader_out) ++ var->data.always_active_io = true; + dxil_spirv_nir_prep(nir); + nirs[stage] = nir; + input_index_by_stage[stage] = (int)i; @@ -76,8 +182,9 @@ index 1a8e6e2..3408de3 100644 + /* Run per-stage passes */ + struct dxil_spirv_metadata metadata[MESA_SHADER_STAGES] = { 0 }; + for (int stage = 0; stage < MESA_SHADER_STAGES; ++stage) { -+ if (nirs[stage]) -+ dxil_spirv_nir_passes(nirs[stage], conf, &metadata[stage]); ++ if (!nirs[stage]) ++ continue; ++ dxil_spirv_nir_passes(nirs[stage], conf, &metadata[stage]); + } + + /* Link consecutive stages (later -> earlier). For each stage with a From 404d2aa694cf81e61ef06c9d8d0edae1bdad13c4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 19 Apr 2026 14:53:52 +0900 Subject: [PATCH 1070/1182] =?UTF-8?q?fix:=20tessellation=20=E2=80=94=20dro?= =?UTF-8?q?p=20degenerate=20patches=20(sphere=20seam=20+=20coincident=20CP?= =?UTF-8?q?s)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GeometricPrimitives/GeometricPrimitive.Sphere.cs | 8 +++++--- .../Rendering/Tessellation/TessellationBase.sdsl | 11 ++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/sources/engine/Stride.Graphics/GeometricPrimitives/GeometricPrimitive.Sphere.cs b/sources/engine/Stride.Graphics/GeometricPrimitives/GeometricPrimitive.Sphere.cs index 561abf54a5..64ea61a831 100644 --- a/sources/engine/Stride.Graphics/GeometricPrimitives/GeometricPrimitive.Sphere.cs +++ b/sources/engine/Stride.Graphics/GeometricPrimitives/GeometricPrimitive.Sphere.cs @@ -120,7 +120,7 @@ public static GeometricMeshData New(float radius = int horizontalSegments = tessellation * 2; var vertices = new VertexPositionNormalTexture[(verticalSegments + 1) * (horizontalSegments + 1)]; - var indices = new int[(verticalSegments) * (horizontalSegments + 1) * 6]; + var indices = new int[verticalSegments * horizontalSegments * 6]; int vertexCount = 0; @@ -180,13 +180,15 @@ public static GeometricMeshData New(float radius = // Fill the index buffer with triangles joining each pair of latitude rings. int stride = horizontalSegments + 1; + // Skip j == horizontalSegments: would produce zero-area seam triangles + // (invisible when rasterized, but tessellators still subdivide them). int indexCount = 0; for (int i = 0; i < verticalSegments; i++) { - for (int j = 0; j <= horizontalSegments; j++) + for (int j = 0; j < horizontalSegments; j++) { int nextI = i + 1; - int nextJ = (j + 1) % stride; + int nextJ = j + 1; indices[indexCount++] = (i * stride + j); indices[indexCount++] = (nextI * stride + j); diff --git a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl index 9be1609af0..4e69ba41f2 100644 --- a/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Tessellation/TessellationBase.sdsl @@ -53,9 +53,14 @@ shader TessellationBase : ShaderBase, TransformationBase, MaterialDomainStream, // However, not sure if we can do tessellation directly through ShadingPosition interpolation (in which case we wouldn't need to do it in domain shader either) float2 screenPosition0 = GetScreenSpacePosition(input[uCPID].PositionWS, ViewSize.x, ViewSize.y); float2 screenPosition1 = GetScreenSpacePosition(input[NextCPID].PositionWS, ViewSize.x, ViewSize.y); - - // Screen space tessellation based on desired triangle size - streams.oppositeEdgeLOD = distance(screenPosition0, screenPosition1) / DesiredTriangleSize; + + // Screen space tessellation based on desired triangle size. Guard against + // degenerate patches whose two CPs are coincident in world space — compare + // input positions directly (exact equality on vertex-buffer inputs is robust + // across backends, whereas fast-math may produce a tiny non-zero value from + // distance() in screen space and leave the patch uncullable). + bool coincident = all(input[uCPID].PositionWS.xyz == input[NextCPID].PositionWS.xyz); + streams.oppositeEdgeLOD = coincident ? 0.0f : distance(screenPosition0, screenPosition1) / DesiredTriangleSize; output = streams; } From b6e6984c77cb75a4542a07cdff509c6cfa6be046 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 18 Apr 2026 15:26:23 +0900 Subject: [PATCH 1071/1182] ci: switch from SwiftShader to Lavapipe to run Vulkan in software mode (swiftshader is in maintenance mode, tessellation and texture3d broken, etc.) --- .github/workflows/dep-lavapipe.yml | 365 +++++++++++++++++- .github/workflows/dep-swiftshader.yml | 214 ---------- .github/workflows/test-linux-game.yml | 69 ++-- .github/workflows/test-windows-game.yml | 20 +- build/deps/lavapipe/Lavapipe.cs | 98 +++++ .../Stride.Dependencies.Lavapipe.csproj | 25 ++ sources/Directory.Packages.props | 2 +- .../Stride.Engine.Tests/TesselationTest.cs | 1 - .../GameTestBase.cs | 2 +- .../Stride.Graphics.Regression/Module.cs | 36 +- .../Stride.Graphics.Regression.csproj | 9 +- .../FixedAspectRatioTests.cs | 1 - .../Stride.Graphics.Tests/TestTexture.cs | 2 - .../engine/Stride.Graphics/AppContextType.cs | 2 +- .../Vulkan/GraphicsAdapterFactory.Vulkan.cs | 2 +- .../SwapChainGraphicsPresenter.Vulkan.cs | 4 +- .../RenderDocManager.cs | 2 +- .../Lavapipe/AnimatedModelTests.f3.png | 3 + .../Lavapipe/AnimatedModelTests.f1.png | 3 + .../Lavapipe/AnimatedModelTests.f2.png | 3 + .../Lavapipe/AnimatedModelTests.f3.png | 3 + .../Lavapipe/AnimatedModelTests.f4.png | 3 + .../Lavapipe/AnimatedModelTests.f5.png | 3 + .../Lavapipe/AnimatedModelTests.png | 3 + .../Lavapipe/SpriteRenderer2DTests.f1.png | 3 + .../Lavapipe/SpriteRenderer3DTests.f1.png | 3 + .../Lavapipe/SpriteRenderer3DTests.png | 3 + .../Lavapipe/SpriteTestGame.f1.png | 3 + .../Lavapipe/SpriteTestGame.f2.png | 3 + .../Lavapipe/SpriteTestGame.png | 3 + .../Lavapipe/TesselationTest.f1.png | 3 + .../Lavapipe/TesselationTest.f2.png | 3 + .../Lavapipe/TesselationTest.f3.png | 3 + .../Lavapipe/TesselationTest.f4.png | 3 + .../Lavapipe/TesselationTest.f5.png | 3 + .../Lavapipe/TesselationTest.png | 3 + .../SwiftShader/AnimatedModelTests.f4.png | 3 - .../SwiftShader/SpriteRenderer2DTests.f1.png | 3 - .../SwiftShader/SpriteRenderer2DTests.png | 3 - .../SwiftShader/SpriteRenderer3DTests.f1.png | 3 - .../SwiftShader/SpriteRenderer3DTests.png | 3 - .../SwiftShader/SpriteTestGame.f1.png | 3 - .../SwiftShader/SpriteTestGame.f2.png | 3 - .../SwiftShader/SpriteTestGame.png | 3 - tests/Stride.Engine.Tests/thresholds.jsonc | 17 +- .../TestDynamicSpriteFontJapanese.png | 3 + .../TestDynamicSpriteFontVarious.f1.png | 3 + .../TestDynamicSpriteFontVarious.f2.png | 3 + .../Lavapipe/TestDynamicSpriteFontVarious.png | 3 + .../Linux.Vulkan/Lavapipe/TestLightShafts.png | 3 + .../Lavapipe/TestSpriteBatchResolution.f2.png | 3 + .../Lavapipe/FixedAspectRatioTests.png | 3 + .../LightingTests.SceneDirectionalLight.png | 3 + ...ceneDirectionalLightShadowFourCascades.png | 3 + ....SceneDirectionalLightShadowOneCascade.png | 3 + ...eneDirectionalLightShadowOneCascadePCF.png | 3 + ...neDirectionalLightShadowOneFourCascade.png | 3 + .../LightingTests.ScenePointLight.png | 3 + ...tingTests.ScenePointLightShadowCubeMap.png | 3 + ...gTests.ScenePointLightShadowParaboloid.png | 3 + .../Lavapipe/LightingTests.SceneSkybox.png | 3 + .../LightingTests.SceneSkyboxMultiple.png | 3 + .../LightingTests.SceneSkyboxRotated.png | 3 + .../Lavapipe/LightingTests.SceneSpotLight.png | 3 + .../LightingTests.SceneSpotLightShadow.png | 3 + ...eneTwoDirectionalLightShadowOneCascade.png | 3 + ...rialTests.MaterialDiffuseTextureCoord1.png | 3 + .../MaterialTests.MaterialEmissive.png | 3 + .../MaterialTests.MaterialLayerAAA.png | 3 + .../MaterialTests.MaterialLayerABA.png | 3 + .../MaterialTests.MaterialLayerABC.png | 3 + .../MaterialTests.MaterialLayerBBB.png | 3 + .../MaterialTests.MaterialMetalness.png | 3 + .../MaterialTests.MaterialSpecular.png | 3 + .../Lavapipe/TestCustomEffect.png | 3 + .../Windows.Vulkan/Lavapipe/TestDrawQuad.png | 3 + .../Lavapipe/TestDynamicSpriteFont.f1.png | 3 + .../Lavapipe/TestDynamicSpriteFont.f2.png | 3 + .../Lavapipe/TestDynamicSpriteFont.png | 3 + .../TestDynamicSpriteFontJapanese.png | 3 + .../TestDynamicSpriteFontVarious.f1.png | 3 + .../TestDynamicSpriteFontVarious.f2.png | 3 + .../Lavapipe/TestDynamicSpriteFontVarious.png | 3 + .../Lavapipe/TestGeometricPrimitives.f1.png | 3 + .../Lavapipe/TestGeometricPrimitives.f2.png | 3 + .../Lavapipe/TestGeometricPrimitives.png | 3 + .../Lavapipe/TestImageEffect.png | 3 + .../Lavapipe/TestLightShafts.png | 3 + .../Lavapipe/TestPrecompiledSpriteFont.f1.png | 3 + .../Lavapipe/TestPrecompiledSpriteFont.f2.png | 3 + .../Lavapipe/TestRenderToTexture.png | 3 + .../Lavapipe/TestSpriteBatch.f1.png | 3 + .../Lavapipe/TestSpriteBatch.png | 3 + .../Lavapipe/TestSpriteBatch3D.f1.png | 3 + .../Lavapipe/TestSpriteBatch3D.png | 3 + .../Lavapipe/TestSpriteBatchResolution.f1.png | 3 + .../Lavapipe/TestSpriteBatchResolution.f2.png | 3 + .../Lavapipe/TestSpriteBatchResolution.f3.png | 3 + .../Lavapipe/TestSpriteBatchResolution.png | 3 + .../Lavapipe/TestSpriteBatchToTexture.png | 3 + .../Lavapipe/TestStaticSpriteFont.f1.png | 3 + .../Lavapipe/TestStaticSpriteFont.f2.png | 3 + .../Lavapipe/TestStaticSpriteFont.png | 3 + .../TestTexture.TestLoadDraw(Bmp).png | 3 + .../TestTexture.TestLoadDraw(Dds).png | 3 + .../TestTexture.TestLoadDraw(Gif).png | 3 + .../TestTexture.TestLoadDraw(Png).png | 3 + .../TestTexture.TestLoadDraw(Stride).png | 3 + .../TestTexture.TestLoadDraw(Tiff).png | 3 + .../SwiftShader/FixedAspectRatioTests.png | 3 - .../LightingTests.SceneDirectionalLight.png | 3 - ...ceneDirectionalLightShadowFourCascades.png | 3 - ....SceneDirectionalLightShadowOneCascade.png | 3 - ...eneDirectionalLightShadowOneCascadePCF.png | 3 - ...neDirectionalLightShadowOneFourCascade.png | 3 - .../LightingTests.ScenePointLight.png | 3 - ...tingTests.ScenePointLightShadowCubeMap.png | 3 - ...gTests.ScenePointLightShadowParaboloid.png | 3 - ...eneTwoDirectionalLightShadowOneCascade.png | 3 - .../MaterialTests.MaterialLayerAAA.png | 3 - .../MaterialTests.MaterialLayerABA.png | 3 - .../MaterialTests.MaterialLayerABC.png | 3 - .../MaterialTests.MaterialLayerBBB.png | 3 - .../MaterialTests.MaterialMetalness.png | 3 - .../MaterialTests.MaterialSpecular.png | 3 - .../SwiftShader/TestBitmapSpriteFont.png | 3 - .../SwiftShader/TestCustomEffect.png | 3 - .../SwiftShader/TestDrawQuad.png | 3 - .../SwiftShader/TestDynamicSpriteFont.f1.png | 3 - .../SwiftShader/TestDynamicSpriteFont.f2.png | 3 - .../SwiftShader/TestDynamicSpriteFont.png | 3 - .../TestDynamicSpriteFontJapanese.png | 3 - .../TestDynamicSpriteFontVarious.f1.png | 3 - .../TestDynamicSpriteFontVarious.f2.png | 3 - .../TestDynamicSpriteFontVarious.png | 3 - .../TestGeometricPrimitives.f1.png | 3 - .../TestGeometricPrimitives.f2.png | 3 - .../SwiftShader/TestGeometricPrimitives.png | 3 - .../SwiftShader/TestImageEffect.png | 3 - .../SwiftShader/TestImageLoad.png | 3 - .../SwiftShader/TestLightShafts.png | 3 - .../TestPrecompiledSpriteFont.f1.png | 3 - .../TestPrecompiledSpriteFont.f2.png | 3 - .../SwiftShader/TestPrecompiledSpriteFont.png | 3 - .../SwiftShader/TestRenderToTexture.png | 3 - .../SwiftShader/TestSpriteBatch.f1.png | 3 - .../SwiftShader/TestSpriteBatch.png | 3 - .../SwiftShader/TestSpriteBatch3D.f1.png | 3 - .../SwiftShader/TestSpriteBatch3D.png | 3 - .../TestSpriteBatchResolution.f1.png | 3 - .../TestSpriteBatchResolution.f2.png | 3 - .../TestSpriteBatchResolution.f3.png | 3 - .../SwiftShader/TestSpriteBatchResolution.png | 3 - .../SwiftShader/TestSpriteBatchToTexture.png | 3 - .../SwiftShader/TestSpriteFontAlignment.png | 3 - .../SwiftShader/TestStaticSpriteFont.f1.png | 3 - .../SwiftShader/TestStaticSpriteFont.f2.png | 3 - .../SwiftShader/TestStaticSpriteFont.png | 3 - .../TestTexture.TestLoadDraw(Dds).png | 3 - .../TestTexture.TestLoadDraw(Png).png | 3 - .../TestTexture.TestLoadDraw(Stride).png | 3 - .../SwiftShader/TestTextureSampling.png | 3 - .../Lavapipe/VisualTestMaterials.png | 3 + .../Lavapipe/VisualTestRibbons.png | 3 + .../Lavapipe/VisualTestSoftEdge.png | 3 + .../SwiftShader/VisualTestMaterials.png | 3 - .../SwiftShader/VisualTestRibbons.png | 3 - .../ComplexLayoutTest.f2.png | 0 .../Lavapipe/ComplexLayoutTest.f3.png | 3 + .../Lavapipe/DynamicFontTest.f1.png | 3 + .../Lavapipe/DynamicFontTest.f2.png | 3 + .../Lavapipe/DynamicFontTest.f3.png | 3 + .../Lavapipe/DynamicFontTest.f4.png | 3 + .../Lavapipe/DynamicFontTest.f5.png | 3 + .../Linux.Vulkan/Lavapipe/DynamicFontTest.png | 3 + .../ScrollViewerAnchorTest.f1.png | 0 .../ScrollViewerAnchorTest.f2.png | 0 .../ScrollViewerAnchorTest.png | 0 .../ScrollViewerTest.f9.png | 0 .../Lavapipe/TextBlockTest.f1.png | 3 + .../Lavapipe/TextBlockTest.f10.png | 3 + .../Lavapipe/TextBlockTest.f11.png | 3 + .../Lavapipe/TextBlockTest.f12.png | 3 + .../Lavapipe/TextBlockTest.f13.png | 3 + .../Lavapipe/TextBlockTest.f14.png | 3 + .../Lavapipe/TextBlockTest.f2.png | 3 + .../Lavapipe/TextBlockTest.f3.png | 3 + .../Lavapipe/TextBlockTest.f4.png | 3 + .../Lavapipe/TextBlockTest.f5.png | 3 + .../Lavapipe/TextBlockTest.f6.png | 3 + .../Lavapipe/TextBlockTest.f7.png | 3 + .../Lavapipe/TextBlockTest.f8.png | 3 + .../Lavapipe/TextBlockTest.f9.png | 3 + .../Linux.Vulkan/Lavapipe/TextBlockTest.png | 3 + .../Lavapipe/TextBlockWrappingTest.f1.png | 3 + .../Lavapipe/TextBlockWrappingTest.f2.png | 3 + .../Lavapipe/TextBlockWrappingTest.f3.png | 3 + .../Lavapipe/TextBlockWrappingTest.f4.png | 3 + .../Lavapipe/TextBlockWrappingTest.f5.png | 3 + .../Lavapipe/TextBlockWrappingTest.f6.png | 3 + .../Lavapipe/TextBlockWrappingTest.f7.png | 3 + .../Lavapipe/TextBlockWrappingTest.f8.png | 3 + .../Lavapipe/TextBlockWrappingTest.f9.png | 3 + .../Lavapipe/TextBlockWrappingTest.png | 3 + .../Lavapipe/TransparencyTest.f1.png | 3 + .../SwiftShader/BillboardModeTests.png | 3 - .../SwiftShader/BorderTest.f1.png | 3 - .../SwiftShader/BorderTest.f2.png | 3 - .../Linux.Vulkan/SwiftShader/BorderTest.png | 3 - .../SwiftShader/CanvasGridTest.png | 3 - .../SwiftShader/ClippingTest.f1.png | 3 - .../SwiftShader/ClippingTest.f10.png | 3 - .../SwiftShader/ClippingTest.f11.png | 3 - .../SwiftShader/ClippingTest.f12.png | 3 - .../SwiftShader/ClippingTest.f2.png | 3 - .../SwiftShader/ClippingTest.f3.png | 3 - .../SwiftShader/ClippingTest.f4.png | 3 - .../SwiftShader/ClippingTest.f5.png | 3 - .../SwiftShader/ClippingTest.f6.png | 3 - .../SwiftShader/ClippingTest.f7.png | 3 - .../SwiftShader/ClippingTest.f8.png | 3 - .../SwiftShader/ClippingTest.f9.png | 3 - .../Linux.Vulkan/SwiftShader/ClippingTest.png | 3 - .../SwiftShader/ComplexLayoutTest.f1.png | 3 - .../SwiftShader/ComplexLayoutTest.f4.png | 3 - .../SwiftShader/ComplexLayoutTest.f5.png | 3 - .../SwiftShader/ComplexLayoutTest.f6.png | 3 - .../SwiftShader/ComplexLayoutTest.f7.png | 3 - .../SwiftShader/ComplexLayoutTest.png | 3 - .../SwiftShader/DynamicFontTest.f1.png | 3 - .../SwiftShader/DynamicFontTest.f2.png | 3 - .../SwiftShader/DynamicFontTest.f3.png | 3 - .../SwiftShader/DynamicFontTest.f4.png | 3 - .../SwiftShader/DynamicFontTest.f5.png | 3 - .../SwiftShader/DynamicFontTest.png | 3 - .../Linux.Vulkan/SwiftShader/ImageTest.f1.png | 3 - .../Linux.Vulkan/SwiftShader/ImageTest.f2.png | 3 - .../Linux.Vulkan/SwiftShader/ImageTest.f3.png | 3 - .../Linux.Vulkan/SwiftShader/ImageTest.f4.png | 3 - .../Linux.Vulkan/SwiftShader/ImageTest.png | 3 - .../SwiftShader/ModalElementTest.f1.png | 3 - .../SwiftShader/ModalElementTest.f2.png | 3 - .../SwiftShader/ModalElementTest.f3.png | 3 - .../SwiftShader/ModalElementTest.f4.png | 3 - .../SwiftShader/ModalElementTest.png | 3 - .../SwiftShader/ScrollViewerTest.f11.png | 3 - .../SwiftShader/ScrollViewerTest.f13.png | 3 - .../SwiftShader/ScrollViewerTest.f15.png | 3 - .../SwiftShader/ScrollViewerTest.f3.png | 3 - .../SwiftShader/ScrollViewerTest.f5.png | 3 - .../SwiftShader/ScrollViewerTest.f6.png | 3 - .../SwiftShader/ScrollViewerTest.f7.png | 3 - .../SwiftShader/SliderTest.f10.png | 3 - .../SwiftShader/TextBlockTest.f1.png | 3 - .../SwiftShader/TextBlockTest.f10.png | 3 - .../SwiftShader/TextBlockTest.f11.png | 3 - .../SwiftShader/TextBlockTest.f12.png | 3 - .../SwiftShader/TextBlockTest.f13.png | 3 - .../SwiftShader/TextBlockTest.f14.png | 3 - .../SwiftShader/TextBlockTest.f2.png | 3 - .../SwiftShader/TextBlockTest.f3.png | 3 - .../SwiftShader/TextBlockTest.f4.png | 3 - .../SwiftShader/TextBlockTest.f5.png | 3 - .../SwiftShader/TextBlockTest.f6.png | 3 - .../SwiftShader/TextBlockTest.f7.png | 3 - .../SwiftShader/TextBlockTest.f8.png | 3 - .../SwiftShader/TextBlockTest.f9.png | 3 - .../SwiftShader/TextBlockTest.png | 3 - .../SwiftShader/TextBlockWrappingTest.f1.png | 3 - .../SwiftShader/TextBlockWrappingTest.f2.png | 3 - .../SwiftShader/TextBlockWrappingTest.f3.png | 3 - .../SwiftShader/TextBlockWrappingTest.f4.png | 3 - .../SwiftShader/TextBlockWrappingTest.f5.png | 3 - .../SwiftShader/TextBlockWrappingTest.f6.png | 3 - .../SwiftShader/TextBlockWrappingTest.f7.png | 3 - .../SwiftShader/TextBlockWrappingTest.f8.png | 3 - .../SwiftShader/TextBlockWrappingTest.f9.png | 3 - .../SwiftShader/TextBlockWrappingTest.png | 3 - .../SwiftShader/TransparencyTest.f2.png | 3 - .../SwiftShader/TransparencyTest.f3.png | 3 - .../SwiftShader/TransparencyTest.png | 3 - .../SwiftShader/UniformGridTest.png | 3 - .../Lavapipe/BillboardModeTests.png | 3 + .../Windows.Vulkan/Lavapipe/BorderTest.f1.png | 3 + .../Windows.Vulkan/Lavapipe/BorderTest.f2.png | 3 + .../Windows.Vulkan/Lavapipe/BorderTest.png | 3 + .../Lavapipe/CanvasGridTest.png | 3 + .../Lavapipe/ClippingTest.f1.png | 3 + .../Lavapipe/ClippingTest.f10.png | 3 + .../Lavapipe/ClippingTest.f11.png | 3 + .../Lavapipe/ClippingTest.f12.png | 3 + .../Lavapipe/ClippingTest.f2.png | 3 + .../Lavapipe/ClippingTest.f3.png | 3 + .../Lavapipe/ClippingTest.f4.png | 3 + .../Lavapipe/ClippingTest.f5.png | 3 + .../Lavapipe/ClippingTest.f6.png | 3 + .../Lavapipe/ClippingTest.f7.png | 3 + .../Lavapipe/ClippingTest.f8.png | 3 + .../Lavapipe/ClippingTest.f9.png | 3 + .../Windows.Vulkan/Lavapipe/ClippingTest.png | 3 + .../Lavapipe/ComplexLayoutTest.f1.png | 3 + .../Lavapipe/ComplexLayoutTest.f4.png | 3 + .../Lavapipe/ComplexLayoutTest.f5.png | 3 + .../Lavapipe/ComplexLayoutTest.f6.png | 3 + .../Lavapipe/ComplexLayoutTest.f7.png | 3 + .../Lavapipe/ComplexLayoutTest.png | 3 + .../Lavapipe/ContentDecoratorTest.f2.png | 3 + .../Lavapipe/DynamicFontTest.f1.png | 3 + .../Lavapipe/DynamicFontTest.f2.png | 3 + .../Lavapipe/DynamicFontTest.f4.png | 3 + .../Lavapipe/DynamicFontTest.f5.png | 3 + .../Lavapipe/DynamicFontTest.png | 3 + .../Lavapipe/EditTextTest.f10.png | 3 + .../Lavapipe/EditTextTest.f11.png | 3 + .../Lavapipe/EditTextTest.f12.png | 3 + .../Lavapipe/EditTextTest.f13.png | 3 + .../Lavapipe/EditTextTest.f14.png | 3 + .../Lavapipe/EditTextTest.f2.png | 3 + .../Lavapipe/EditTextTest.f3.png | 3 + .../Lavapipe/EditTextTest.f5.png | 3 + .../Lavapipe/EditTextTest.f6.png | 3 + .../Lavapipe/EditTextTest.f7.png | 3 + .../Lavapipe/EditTextTest.f8.png | 3 + .../Windows.Vulkan/Lavapipe/EditTextTest.png | 3 + .../Lavapipe/ImageRegionTest.f1.png | 3 + .../Lavapipe/ImageRegionTest.f2.png | 3 + .../Lavapipe/ImageRegionTest.f3.png | 3 + .../Lavapipe/ImageRegionTest.f4.png | 3 + .../Lavapipe/ImageRegionTest.png | 3 + .../Lavapipe/ImageRotatedTest.png | 3 + .../Windows.Vulkan/Lavapipe/ImageTest.f1.png | 3 + .../Windows.Vulkan/Lavapipe/ImageTest.f2.png | 3 + .../Windows.Vulkan/Lavapipe/ImageTest.f3.png | 3 + .../Windows.Vulkan/Lavapipe/ImageTest.f4.png | 3 + .../Windows.Vulkan/Lavapipe/ImageTest.png | 3 + .../Lavapipe/ModalElementTest.f1.png | 3 + .../Lavapipe/ModalElementTest.f2.png | 3 + .../Lavapipe/ModalElementTest.f3.png | 3 + .../Lavapipe/ModalElementTest.f4.png | 3 + .../Lavapipe/ModalElementTest.png | 3 + .../Lavapipe/ScrollViewerTest.f10.png | 3 + .../Lavapipe/ScrollViewerTest.f11.png | 3 + .../Lavapipe/ScrollViewerTest.f12.png | 3 + .../Lavapipe/ScrollViewerTest.f13.png | 3 + .../Lavapipe/ScrollViewerTest.f14.png | 3 + .../Lavapipe/ScrollViewerTest.f15.png | 3 + .../Lavapipe/ScrollViewerTest.f3.png | 3 + .../Lavapipe/ScrollViewerTest.f5.png | 3 + .../Lavapipe/ScrollViewerTest.f6.png | 3 + .../Lavapipe/ScrollViewerTest.f7.png | 3 + .../Lavapipe/ScrollViewerTest.png | 3 + .../Lavapipe/SliderTest.f10.png | 3 + .../Lavapipe/TextBlockTest.f11.png | 3 + .../Lavapipe/TextBlockTest.f12.png | 3 + .../Lavapipe/TextBlockTest.f13.png | 3 + .../Lavapipe/TextBlockTest.f14.png | 3 + .../Lavapipe/TextBlockWrappingTest.f1.png | 3 + .../Lavapipe/TextBlockWrappingTest.f2.png | 3 + .../Lavapipe/TextBlockWrappingTest.f3.png | 3 + .../Lavapipe/TextBlockWrappingTest.f4.png | 3 + .../Lavapipe/TextBlockWrappingTest.f5.png | 3 + .../Lavapipe/TextBlockWrappingTest.f6.png | 3 + .../Lavapipe/TextBlockWrappingTest.f7.png | 3 + .../Lavapipe/TextBlockWrappingTest.f8.png | 3 + .../Lavapipe/TextBlockWrappingTest.f9.png | 3 + .../Lavapipe/TextBlockWrappingTest.png | 3 + .../Lavapipe/TransparencyTest.f2.png | 3 + .../Lavapipe/TransparencyTest.f3.png | 3 + .../Lavapipe/TransparencyTest.png | 3 + .../Lavapipe/UniformGridTest.png | 3 + .../SwiftShader/BillboardModeTests.png | 3 - .../SwiftShader/BorderTest.f1.png | 3 - .../SwiftShader/BorderTest.f2.png | 3 - .../Windows.Vulkan/SwiftShader/BorderTest.png | 3 - .../SwiftShader/CanvasGridTest.png | 3 - .../SwiftShader/ClickTests.f1.png | 3 - .../SwiftShader/ClickTests.f2.png | 3 - .../SwiftShader/ClickTests.f3.png | 3 - .../SwiftShader/ClickTests.f4.png | 3 - .../SwiftShader/ClickTests.f5.png | 3 - .../SwiftShader/ClickTests.f6.png | 3 - .../Windows.Vulkan/SwiftShader/ClickTests.png | 3 - .../SwiftShader/ClippingTest.f1.png | 3 - .../SwiftShader/ClippingTest.f10.png | 3 - .../SwiftShader/ClippingTest.f11.png | 3 - .../SwiftShader/ClippingTest.f12.png | 3 - .../SwiftShader/ClippingTest.f2.png | 3 - .../SwiftShader/ClippingTest.f3.png | 3 - .../SwiftShader/ClippingTest.f4.png | 3 - .../SwiftShader/ClippingTest.f5.png | 3 - .../SwiftShader/ClippingTest.f6.png | 3 - .../SwiftShader/ClippingTest.f7.png | 3 - .../SwiftShader/ClippingTest.f8.png | 3 - .../SwiftShader/ClippingTest.f9.png | 3 - .../SwiftShader/ClippingTest.png | 3 - .../SwiftShader/ComplexLayoutTest.f1.png | 3 - .../SwiftShader/ComplexLayoutTest.f2.png | 3 - .../SwiftShader/ComplexLayoutTest.f3.png | 3 - .../SwiftShader/ComplexLayoutTest.f4.png | 3 - .../SwiftShader/ComplexLayoutTest.f5.png | 3 - .../SwiftShader/ComplexLayoutTest.f6.png | 3 - .../SwiftShader/ComplexLayoutTest.f7.png | 3 - .../SwiftShader/ComplexLayoutTest.png | 3 - .../SwiftShader/ContentDecoratorTest.f1.png | 3 - .../SwiftShader/ContentDecoratorTest.f2.png | 3 - .../SwiftShader/ContentDecoratorTest.png | 3 - .../SwiftShader/DynamicFontTest.f1.png | 3 - .../SwiftShader/DynamicFontTest.f2.png | 3 - .../SwiftShader/DynamicFontTest.f3.png | 3 - .../SwiftShader/DynamicFontTest.f4.png | 3 - .../SwiftShader/DynamicFontTest.f5.png | 3 - .../SwiftShader/DynamicFontTest.png | 3 - .../SwiftShader/EditTextTest.f1.png | 3 - .../SwiftShader/EditTextTest.f10.png | 3 - .../SwiftShader/EditTextTest.f11.png | 3 - .../SwiftShader/EditTextTest.f12.png | 3 - .../SwiftShader/EditTextTest.f13.png | 3 - .../SwiftShader/EditTextTest.f14.png | 3 - .../SwiftShader/EditTextTest.f2.png | 3 - .../SwiftShader/EditTextTest.f3.png | 3 - .../SwiftShader/EditTextTest.f4.png | 3 - .../SwiftShader/EditTextTest.f5.png | 3 - .../SwiftShader/EditTextTest.f6.png | 3 - .../SwiftShader/EditTextTest.f7.png | 3 - .../SwiftShader/EditTextTest.f8.png | 3 - .../SwiftShader/EditTextTest.f9.png | 3 - .../SwiftShader/EditTextTest.png | 3 - .../SwiftShader/ImageRegionTest.f1.png | 3 - .../SwiftShader/ImageRegionTest.f2.png | 3 - .../SwiftShader/ImageRegionTest.f3.png | 3 - .../SwiftShader/ImageRegionTest.f4.png | 3 - .../SwiftShader/ImageRegionTest.png | 3 - .../SwiftShader/ImageRotatedTest.png | 3 - .../SwiftShader/ImageTest.f1.png | 3 - .../SwiftShader/ImageTest.f2.png | 3 - .../SwiftShader/ImageTest.f3.png | 3 - .../SwiftShader/ImageTest.f4.png | 3 - .../Windows.Vulkan/SwiftShader/ImageTest.png | 3 - .../SwiftShader/ModalElementTest.f2.png | 3 - .../SwiftShader/ModalElementTest.f3.png | 3 - .../SwiftShader/ModalElementTest.f4.png | 3 - .../SwiftShader/ScrollViewerTest.f1.png | 3 - .../SwiftShader/ScrollViewerTest.f10.png | 3 - .../SwiftShader/ScrollViewerTest.f11.png | 3 - .../SwiftShader/ScrollViewerTest.f12.png | 3 - .../SwiftShader/ScrollViewerTest.f13.png | 3 - .../SwiftShader/ScrollViewerTest.f14.png | 3 - .../SwiftShader/ScrollViewerTest.f15.png | 3 - .../SwiftShader/ScrollViewerTest.f2.png | 3 - .../SwiftShader/ScrollViewerTest.f3.png | 3 - .../SwiftShader/ScrollViewerTest.f4.png | 3 - .../SwiftShader/ScrollViewerTest.f5.png | 3 - .../SwiftShader/ScrollViewerTest.f6.png | 3 - .../SwiftShader/ScrollViewerTest.f7.png | 3 - .../SwiftShader/ScrollViewerTest.f8.png | 3 - .../SwiftShader/ScrollViewerTest.png | 3 - .../SwiftShader/ScrollingTextTest.f1.png | 3 - .../SwiftShader/ScrollingTextTest.f2.png | 3 - .../SwiftShader/ScrollingTextTest.f3.png | 3 - .../SwiftShader/ScrollingTextTest.f4.png | 3 - .../SwiftShader/ScrollingTextTest.f5.png | 3 - .../SwiftShader/ScrollingTextTest.f6.png | 3 - .../SwiftShader/SliderTest.f1.png | 3 - .../SwiftShader/SliderTest.f10.png | 3 - .../SwiftShader/SliderTest.f2.png | 3 - .../SwiftShader/TextBlockTest.f1.png | 3 - .../SwiftShader/TextBlockTest.f10.png | 3 - .../SwiftShader/TextBlockTest.f11.png | 3 - .../SwiftShader/TextBlockTest.f12.png | 3 - .../SwiftShader/TextBlockTest.f13.png | 3 - .../SwiftShader/TextBlockTest.f14.png | 3 - .../SwiftShader/TextBlockTest.f2.png | 3 - .../SwiftShader/TextBlockTest.f3.png | 3 - .../SwiftShader/TextBlockTest.f4.png | 3 - .../SwiftShader/TextBlockTest.f5.png | 3 - .../SwiftShader/TextBlockTest.f6.png | 3 - .../SwiftShader/TextBlockTest.f7.png | 3 - .../SwiftShader/TextBlockTest.f8.png | 3 - .../SwiftShader/TextBlockTest.f9.png | 3 - .../SwiftShader/TextBlockTest.png | 3 - .../SwiftShader/TextBlockWrappingTest.f1.png | 3 - .../SwiftShader/TextBlockWrappingTest.f2.png | 3 - .../SwiftShader/TextBlockWrappingTest.f3.png | 3 - .../SwiftShader/TextBlockWrappingTest.f4.png | 3 - .../SwiftShader/TextBlockWrappingTest.f5.png | 3 - .../SwiftShader/TextBlockWrappingTest.f6.png | 3 - .../SwiftShader/TextBlockWrappingTest.f7.png | 3 - .../SwiftShader/TextBlockWrappingTest.f8.png | 3 - .../SwiftShader/TextBlockWrappingTest.f9.png | 3 - .../SwiftShader/TextBlockWrappingTest.png | 3 - .../SwiftShader/TransparencyTest.f1.png | 3 - .../SwiftShader/TransparencyTest.png | 3 - .../SwiftShader/UniformGridTest.png | 3 - 493 files changed, 1182 insertions(+), 1099 deletions(-) delete mode 100644 .github/workflows/dep-swiftshader.yml create mode 100644 build/deps/lavapipe/Lavapipe.cs create mode 100644 build/deps/lavapipe/Stride.Dependencies.Lavapipe.csproj create mode 100644 tests/Stride.Engine.Tests/Linux.Vulkan/Lavapipe/AnimatedModelTests.f3.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f2.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f3.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f4.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f5.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer2DTests.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f2.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f2.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f3.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f4.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f5.png create mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/AnimatedModelTests.f4.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png delete mode 100644 tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestLightShafts.png create mode 100644 tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/FixedAspectRatioTests.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLight.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowFourCascades.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascade.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneFourCascade.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLight.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowCubeMap.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowParaboloid.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkybox.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxMultiple.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxRotated.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLight.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLightShadow.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialDiffuseTextureCoord1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialEmissive.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerAAA.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABA.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABC.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerBBB.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialMetalness.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialSpecular.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestCustomEffect.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDrawQuad.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestImageEffect.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestRenderToTexture.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f3.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchToTexture.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f1.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f2.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Bmp).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Dds).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Gif).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Png).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Stride).png create mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Tiff).png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/FixedAspectRatioTests.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLight.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowFourCascades.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascade.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneFourCascade.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLight.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowCubeMap.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowParaboloid.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerAAA.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABA.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABC.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerBBB.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialMetalness.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialSpecular.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestBitmapSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestCustomEffect.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDrawQuad.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestRenderToTexture.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchToTexture.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteFontAlignment.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png delete mode 100644 tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTextureSampling.png create mode 100644 tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestMaterials.png create mode 100644 tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestRibbons.png create mode 100644 tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestSoftEdge.png delete mode 100644 tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestMaterials.png delete mode 100644 tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestRibbons.png rename tests/Stride.UI.Tests.Regression/Linux.Vulkan/{SwiftShader => Lavapipe}/ComplexLayoutTest.f2.png (100%) create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.png rename tests/Stride.UI.Tests.Regression/Linux.Vulkan/{SwiftShader => Lavapipe}/ScrollViewerAnchorTest.f1.png (100%) rename tests/Stride.UI.Tests.Regression/Linux.Vulkan/{SwiftShader => Lavapipe}/ScrollViewerAnchorTest.f2.png (100%) rename tests/Stride.UI.Tests.Regression/Linux.Vulkan/{SwiftShader => Lavapipe}/ScrollViewerAnchorTest.png (100%) rename tests/Stride.UI.Tests.Regression/Linux.Vulkan/{SwiftShader => Lavapipe}/ScrollViewerTest.f9.png (100%) create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f11.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f12.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f13.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f14.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TransparencyTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BillboardModeTests.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/CanvasGridTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f13.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f15.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/UniformGridTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BillboardModeTests.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/CanvasGridTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f10.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f11.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f12.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f8.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f9.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ContentDecoratorTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f10.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f11.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f12.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f13.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f14.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f8.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRotatedTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f10.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f11.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f12.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f13.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f14.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f15.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/SliderTest.f10.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f11.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f12.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f13.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f14.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f2.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f3.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.png create mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/UniformGridTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BillboardModeTests.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/CanvasGridTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f13.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f15.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.f1.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.png delete mode 100644 tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/UniformGridTest.png diff --git a/.github/workflows/dep-lavapipe.yml b/.github/workflows/dep-lavapipe.yml index daedf0b054..9da7eed1f6 100644 --- a/.github/workflows/dep-lavapipe.yml +++ b/.github/workflows/dep-lavapipe.yml @@ -1,8 +1,18 @@ name: "Dep: Build & Deploy Lavapipe" -# Skeleton workflow — the full implementation lives on a feature branch. -# This exists on master only so the workflow is triggerable via workflow_dispatch -# with the expected inputs. Checkout the feature branch ref to run the real build. +# Skeleton — not yet exercised. Notes on per-OS friction at the bottom. +# +# Lavapipe is built from Mesa with: +# meson setup _build -Dvulkan-drivers=swrast -Dgallium-drivers=llvmpipe \ +# -Dgallium-extra-hud=false -Dvideo-codecs= \ +# -Dplatforms=windows|x11,wayland|... \ +# -Dbuildtype=release +# +# Outputs (per OS): +# Windows: vulkan_lvp.dll + lvp_icd.x86_64.json (or lvp_icd.json) +# Linux: libvulkan_lvp.so + lvp_icd.x86_64.json +# macOS: libvulkan_lvp.dylib + lvp_icd.x86_64.json +# The ICD JSON's `library_path` may need rewriting to a side-by-side path. on: workflow_dispatch: @@ -20,11 +30,348 @@ on: required: false jobs: - placeholder: - name: Skeleton (run on feature branch for real build) - runs-on: ubuntu-latest + build-windows: + name: Build Lavapipe (Windows x64) + runs-on: windows-2025-vs2026 steps: - - name: Notice + - name: Checkout Stride + uses: actions/checkout@v4 + with: + path: stride-src + sparse-checkout: build/deps/lavapipe + + - name: Clone Mesa + shell: pwsh + run: | + $url = "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" + $ref = "${{ github.event.inputs.ref || 'main' }}" + git init mesa-src + git -C mesa-src remote add origin $url + git -C mesa-src fetch --depth 1 origin $ref + git -C mesa-src checkout FETCH_HEAD + + - name: Install build dependencies + shell: pwsh + run: | + choco install -y winflexbison3 + python -m pip install --upgrade pip + python -m pip install meson ninja mako pyyaml packaging + + # Provides glslangValidator (and headers/loader we don't strictly need). + - name: Install Vulkan SDK + uses: jakoch/install-vulkan-sdk-action@v1 + with: + vulkan_version: 1.4.304.1 + install_runtime: false + cache: true + stripdown: true + + - name: Setup MSVC environment + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + # LLVM is statically linked into vulkan_lvp.dll so the output has no host-LLVM + # dependency. We build it once per (LLVM version × MSVC version) and cache. + # Bump the cache key suffix to force a rebuild. + # Split restore/save so the built LLVM persists even if later steps fail. + - name: Restore LLVM cache + id: restore-llvm + uses: actions/cache/restore@v4 + with: + path: llvm-install + key: llvm-21.1.0-msvc2026-static-x64-v1 + + - name: Build LLVM (cache miss) + if: steps.restore-llvm.outputs.cache-hit != 'true' + shell: cmd + run: | + git clone --depth 1 --branch llvmorg-21.1.0 https://github.com/llvm/llvm-project.git + cmake -S llvm-project/llvm -B llvm-build -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_INSTALL_PREFIX=%CD%\llvm-install ^ + -DLLVM_BUILD_LLVM_DYLIB=OFF ^ + -DLLVM_LINK_LLVM_DYLIB=OFF ^ + -DLLVM_ENABLE_PROJECTS= ^ + -DLLVM_TARGETS_TO_BUILD=X86;AArch64 ^ + -DLLVM_ENABLE_ASSERTIONS=OFF ^ + -DLLVM_INCLUDE_TESTS=OFF ^ + -DLLVM_INCLUDE_EXAMPLES=OFF ^ + -DLLVM_INCLUDE_BENCHMARKS=OFF + cmake --build llvm-build --target install + + # Save cache immediately after build, independent of subsequent step outcomes. + - name: Save LLVM cache + if: steps.restore-llvm.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + with: + path: llvm-install + key: llvm-21.1.0-msvc2026-static-x64-v1 + + - name: Configure Mesa (Lavapipe only, static LLVM) + shell: cmd + working-directory: mesa-src + env: + LLVM_CONFIG: ${{ github.workspace }}\llvm-install\bin\llvm-config.exe + # choco winflexbison3 installs win_flex.exe / win_bison.exe. Mesa's meson + # looks for `flex`/`bison`; these env vars redirect the lookup. + FLEX: win_flex + LEX: win_flex + BISON: win_bison + YACC: win_bison + run: | + set PYTHONUTF8=1 + set PATH=${{ github.workspace }}\llvm-install\bin;%PATH% + meson setup _build ^ + -Dvulkan-drivers=swrast ^ + -Dgallium-drivers=llvmpipe ^ + -Dplatforms=windows ^ + -Dc_args="/wd4189" ^ + -Dcpp_args="/wd4189" ^ + -Dglx=disabled -Degl=disabled ^ + -Dopengl=false -Dgles1=disabled -Dgles2=disabled ^ + -Dgallium-extra-hud=false ^ + -Dvideo-codecs= ^ + -Dllvm=enabled ^ + -Dshared-llvm=disabled ^ + -Dbuildtype=release + + - name: Build vulkan_lvp.dll + shell: cmd + working-directory: mesa-src + run: | + set PYTHONUTF8=1 + meson compile -C _build src/gallium/targets/lavapipe/vulkan_lvp:shared_library + + - name: Collect output + shell: pwsh + run: | + mkdir lavapipe-out + $dll = Get-ChildItem -Recurse mesa-src/_build -Filter vulkan_lvp.dll | Select-Object -First 1 + if (-not $dll) { throw "vulkan_lvp.dll not found in build output" } + Copy-Item $dll.FullName lavapipe-out/ + # ICD manifest with relative library_path. Windows Vulkan loader requires a + # backslash here — forward-slash `./vulkan_lvp.dll` loads the DLL but every + # subsequent Vulkan call returns VK_ERROR_OUT_OF_HOST_MEMORY. + Set-Content -NoNewline -Path lavapipe-out/lvp_icd.json -Value '{"file_format_version":"1.0.0","ICD":{"library_path":".\\vulkan_lvp.dll","api_version":"1.3.0"}}' + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: lavapipe-win-x64 + path: lavapipe-out/ + + build-linux: + name: Build Lavapipe (Linux x64) + runs-on: ubuntu-24.04 + steps: + - name: Checkout Stride + uses: actions/checkout@v4 + with: + path: stride-src + sparse-checkout: build/deps/lavapipe + + - name: Clone Mesa + run: | + url="${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" + ref="${{ github.event.inputs.ref || 'main' }}" + git init mesa-src + git -C mesa-src remote add origin "$url" + git -C mesa-src fetch --depth 1 origin "$ref" + git -C mesa-src checkout FETCH_HEAD + + - name: Install build dependencies + run: | + sudo apt-get update + # Build with x11,wayland Vulkan WSI so swapchains work under Xvfb/WSLg/etc. + # libxcb/libwayland are dlopen'd lazily — headless callers never pay the cost. + # llvm-dev + libpolly-*-dev because llvm-config emits -lPolly -lPollyISL. + sudo apt-get install -y ninja-build pkg-config bison flex glslang-tools \ + llvm-dev libpolly-18-dev libelf-dev libdrm-dev \ + libx11-xcb-dev libxrandr-dev libxext-dev libxfixes-dev libxxf86vm-dev libxdamage-dev \ + libxcb-randr0-dev libxcb-shm0-dev libxcb-present-dev \ + libxcb-dri3-dev libxcb-dri2-0-dev libxcb-glx0-dev libxcb-sync-dev \ + libxshmfence-dev \ + libwayland-dev wayland-protocols libwayland-egl-backend-dev + # Ubuntu 24.04 ships meson 1.3.2; Mesa requires >= 1.4.0 — use pip. + python3 -m pip install --user --upgrade meson mako packaging pyyaml + echo "$HOME/.local/bin" >> $GITHUB_PATH + + - name: Configure & build + working-directory: mesa-src + run: | + meson setup _build \ + -Dvulkan-drivers=swrast -Dgallium-drivers=llvmpipe \ + -Dplatforms=x11,wayland \ + -Dglx=disabled -Degl=disabled \ + -Dopengl=false -Dgles1=disabled -Dgles2=disabled \ + -Dgallium-extra-hud=false -Dvideo-codecs= \ + -Dllvm=enabled -Dshared-llvm=disabled \ + -Dbuildtype=release + ninja -C _build src/gallium/targets/lavapipe/libvulkan_lvp.so + + - name: Collect output + run: | + mkdir -p lavapipe-out + find mesa-src/_build -name "libvulkan_lvp.so*" -exec cp {} lavapipe-out/ \; + # ICD manifest with relative library_path + printf '%s' '{"file_format_version":"1.0.0","ICD":{"library_path":"./libvulkan_lvp.so","api_version":"1.3.0"}}' > lavapipe-out/lvp_icd.json + ls -la lavapipe-out/ + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: lavapipe-linux-x64 + path: lavapipe-out/ + + build-macos: + name: Build Lavapipe (macOS ARM64) + runs-on: macos-15 + steps: + - name: Checkout Stride + uses: actions/checkout@v4 + with: + path: stride-src + sparse-checkout: build/deps/lavapipe + + - name: Clone Mesa + run: | + url="${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" + ref="${{ github.event.inputs.ref || 'main' }}" + git init mesa-src + git -C mesa-src remote add origin "$url" + git -C mesa-src fetch --depth 1 origin "$ref" + git -C mesa-src checkout FETCH_HEAD + + - name: Install build dependencies + run: | + brew install meson ninja pkg-config llvm bison flex glslang + pip3 install --break-system-packages mako packaging pyyaml + + - name: Configure & build + working-directory: mesa-src + env: + PKG_CONFIG_PATH: /opt/homebrew/opt/llvm/lib/pkgconfig:/opt/homebrew/opt/zstd/lib/pkgconfig + PATH: /opt/homebrew/opt/llvm/bin:/opt/homebrew/opt/bison/bin:/opt/homebrew/opt/flex/bin:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin + LIBRARY_PATH: /opt/homebrew/opt/zstd/lib:/opt/homebrew/opt/llvm/lib + LDFLAGS: -L/opt/homebrew/opt/zstd/lib -L/opt/homebrew/opt/llvm/lib + run: | + # macOS lavapipe is lightly tested — expect rough edges. + # -Dplatforms=macos exposes Mesa's experimental IOSurface-based WSI so + # VK_KHR_swapchain is available alongside MoltenVK when both ICDs load. + meson setup _build \ + -Dvulkan-drivers=swrast -Dgallium-drivers=llvmpipe \ + -Dplatforms=macos \ + -Dglx=disabled -Degl=disabled \ + -Dopengl=false -Dgles1=disabled -Dgles2=disabled \ + -Dgallium-extra-hud=false -Dvideo-codecs= \ + -Dllvm=enabled -Dshared-llvm=disabled \ + -Dbuildtype=release + ninja -C _build src/gallium/targets/lavapipe/libvulkan_lvp.dylib + + - name: Collect output + run: | + mkdir -p lavapipe-out + find mesa-src/_build -name "libvulkan_lvp*.dylib" -exec cp {} lavapipe-out/ \; + # ICD manifest with relative library_path + printf '%s' '{"file_format_version":"1.0.0","ICD":{"library_path":"./libvulkan_lvp.dylib","api_version":"1.3.0"}}' > lavapipe-out/lvp_icd.json + ls -la lavapipe-out/ + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: lavapipe-osx-arm64 + path: lavapipe-out/ + + pack: + name: Pack & Publish NuGet + needs: [build-windows, build-linux, build-macos] + runs-on: windows-2025-vs2026 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Clone Mesa (for commit hash) + shell: pwsh + run: | + $url = "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" + $ref = "${{ github.event.inputs.ref || 'main' }}" + git init mesa-src + git -C mesa-src remote add origin $url + git -C mesa-src fetch --depth 1 origin $ref + git -C mesa-src checkout FETCH_HEAD + + - name: Download Windows artifact + uses: actions/download-artifact@v4 + with: { name: lavapipe-win-x64, path: artifacts/win-x64 } + + - name: Download Linux artifact + uses: actions/download-artifact@v4 + with: { name: lavapipe-linux-x64, path: artifacts/linux-x64 } + + - name: Download macOS artifact + uses: actions/download-artifact@v4 + with: { name: lavapipe-osx-arm64, path: artifacts/osx-arm64 } + + - name: Stage native payload into csproj + shell: pwsh + run: | + $destRoot = "build/deps/lavapipe/runtimes" + foreach ($rid in 'win-x64','linux-x64','osx-arm64') { + $native = "$destRoot/$rid/native" + New-Item -Path $native -ItemType Directory -Force | Out-Null + Copy-Item -Recurse artifacts/$rid/* $native + } + # Note: lvp_icd.json is included but unused — Lavapipe.cs generates + # its own JSON at runtime pointing to an absolute library_path. + + - name: Pack NuGet (dotnet pack) + shell: pwsh + run: | + $commitHash = git -C mesa-src rev-parse --short HEAD + $version = "${{ github.event.inputs.version }}" + if (-not $version) { $version = (Get-Date -Format "yyyy.M.d") } + dotnet pack build/deps/lavapipe/Stride.Dependencies.Lavapipe.csproj ` + -c Release ` + -p:PackageVersion=$version ` + -p:RepositoryCommit=$commitHash ` + -o nupkg + echo "PACKAGE_VERSION=$version" >> $env:GITHUB_ENV + + - name: Upload package artifact + uses: actions/upload-artifact@v4 + with: + name: Stride.Dependencies.Lavapipe.nupkg + path: nupkg/*.nupkg + + publish: + name: Sign & Publish to NuGet.org + needs: pack + runs-on: windows-2025-vs2026 + environment: production + steps: + - name: Install signing tool + run: dotnet tool install sign --tool-path ./sign-tool --version 0.9.0-beta.23127.3 + + - name: Download artifact + uses: actions/download-artifact@v4 + with: + name: Stride.Dependencies.Lavapipe.nupkg + + - name: Sign NuGet package + shell: pwsh + run: | + ./sign-tool/sign code azure-key-vault *.nupkg ` + --description "Stride" ` + --description-url "https://stride3d.net" ` + --publisher-name "Stride" ` + --azure-key-vault-tenant-id "${{ secrets.STRIDE_SIGN_TENANT_ID }}" ` + --azure-key-vault-client-id "${{ secrets.STRIDE_SIGN_CLIENT_ID }}" ` + --azure-key-vault-client-secret "${{ secrets.STRIDE_SIGN_CLIENT_SECRET }}" ` + --azure-key-vault-certificate "${{ secrets.STRIDE_SIGN_KEYVAULT_CERTIFICATE }}" ` + --azure-key-vault-url "https://${{ secrets.STRIDE_SIGN_KEYVAULT_NAME }}.vault.azure.net/" ` + -v Information + + - name: Publish run: | - echo "This is a skeleton. The real build lives on a feature branch." - echo "Trigger this workflow against that branch ref to run the actual build." + dotnet nuget push *.nupkg --api-key "${{ secrets.STRIDE_NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/dep-swiftshader.yml b/.github/workflows/dep-swiftshader.yml deleted file mode 100644 index e25a92f848..0000000000 --- a/.github/workflows/dep-swiftshader.yml +++ /dev/null @@ -1,214 +0,0 @@ -name: "Dep: Build & Deploy SwiftShader" - -on: - workflow_dispatch: - inputs: - version: - description: NuGet package version (leave empty for date-based) - required: false - -jobs: - build-windows: - name: Build SwiftShader (Windows x64) - runs-on: windows-2025-vs2026 - env: - CMAKE_POLICY_VERSION_MINIMUM: "3.5" - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Checkout SwiftShader - uses: actions/checkout@v4 - with: - repository: google/swiftshader - submodules: recursive - path: swiftshader-src - - - name: Build - shell: pwsh - run: | - cmake -S swiftshader-src -B swiftshader-build -Thost=x64 -DSWIFTSHADER_BUILD_TESTS=OFF -DSWIFTSHADER_BUILD_BENCHMARKS=OFF - cmake --build swiftshader-build --config Release --target vk_swiftshader - - - name: Upload build output - uses: actions/upload-artifact@v4 - with: - name: swiftshader-win-x64 - path: | - swiftshader-build/**/vk_swiftshader.dll - swiftshader-build/**/vk_swiftshader_icd.json - - build-linux: - name: Build SwiftShader (Linux x64) - runs-on: ubuntu-24.04 - env: - CMAKE_POLICY_VERSION_MINIMUM: "3.5" - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Checkout SwiftShader - uses: actions/checkout@v4 - with: - repository: google/swiftshader - submodules: recursive - path: swiftshader-src - - - name: Build - run: | - cmake -S swiftshader-src -B swiftshader-build -DCMAKE_BUILD_TYPE=Release -DSWIFTSHADER_BUILD_TESTS=OFF -DSWIFTSHADER_BUILD_BENCHMARKS=OFF - cmake --build swiftshader-build --target vk_swiftshader -- -j$(nproc) - - - name: Collect build output - run: | - mkdir -p swiftshader-out - find swiftshader-build -maxdepth 2 -name "libvk_swiftshader.so" -exec cp {} swiftshader-out/ \; - find swiftshader-build -maxdepth 2 -name "vk_swiftshader_icd.json" -exec cp {} swiftshader-out/ \; - - - name: Upload build output - uses: actions/upload-artifact@v4 - with: - name: swiftshader-linux-x64 - path: swiftshader-out/ - - build-macos: - name: Build SwiftShader (macOS ARM64) - runs-on: macos-15 - env: - CMAKE_POLICY_VERSION_MINIMUM: "3.5" - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Checkout SwiftShader - uses: actions/checkout@v4 - with: - repository: google/swiftshader - submodules: recursive - path: swiftshader-src - - - name: Build - run: | - cmake -S swiftshader-src -B swiftshader-build -DCMAKE_BUILD_TYPE=Release -DSWIFTSHADER_BUILD_TESTS=OFF -DSWIFTSHADER_BUILD_BENCHMARKS=OFF - cmake --build swiftshader-build --target vk_swiftshader -- -j$(sysctl -n hw.ncpu) - - - name: Collect build output - run: | - mkdir -p swiftshader-out - find swiftshader-build -maxdepth 2 -name "libvk_swiftshader.dylib" -exec cp {} swiftshader-out/ \; - find swiftshader-build -maxdepth 2 -name "vk_swiftshader_icd.json" -exec cp {} swiftshader-out/ \; - - - name: Upload build output - uses: actions/upload-artifact@v4 - with: - name: swiftshader-osx-arm64 - path: swiftshader-out/ - - pack: - name: Pack & Publish NuGet - needs: [build-windows, build-linux, build-macos] - runs-on: windows-2025-vs2026 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Checkout SwiftShader (for commit hash) - uses: actions/checkout@v4 - with: - repository: google/swiftshader - path: swiftshader-src - fetch-depth: 1 - - - name: Download Windows artifact - uses: actions/download-artifact@v4 - with: - name: swiftshader-win-x64 - path: artifacts/win-x64 - - - name: Download Linux artifact - uses: actions/download-artifact@v4 - with: - name: swiftshader-linux-x64 - path: artifacts/linux-x64 - - - name: Download macOS artifact - uses: actions/download-artifact@v4 - with: - name: swiftshader-osx-arm64 - path: artifacts/osx-arm64 - - - name: Prepare package contents - shell: pwsh - run: | - $destDir = "build/deps/swiftshader" - - # Windows - New-Item -Path "$destDir/win-x64" -ItemType Directory -Force | Out-Null - $winDll = Get-ChildItem -Recurse -Path artifacts/win-x64 -Filter vk_swiftshader.dll | Select-Object -First 1 - Copy-Item $winDll.FullName "$destDir/win-x64/" - $winIcd = Get-ChildItem -Recurse -Path artifacts/win-x64 -Filter vk_swiftshader_icd.json | Select-Object -First 1 - Copy-Item $winIcd.FullName "$destDir/win-x64/" - - # Linux - New-Item -Path "$destDir/linux-x64" -ItemType Directory -Force | Out-Null - $linuxSo = Get-ChildItem -Recurse -Path artifacts/linux-x64 -Filter libvk_swiftshader.so | Select-Object -First 1 - Copy-Item $linuxSo.FullName "$destDir/linux-x64/" - $linuxIcd = Get-ChildItem -Recurse -Path artifacts/linux-x64 -Filter vk_swiftshader_icd.json | Select-Object -First 1 - Copy-Item $linuxIcd.FullName "$destDir/linux-x64/" - - # macOS - New-Item -Path "$destDir/osx-arm64" -ItemType Directory -Force | Out-Null - $macDylib = Get-ChildItem -Recurse -Path artifacts/osx-arm64 -Filter libvk_swiftshader.dylib | Select-Object -First 1 - Copy-Item $macDylib.FullName "$destDir/osx-arm64/" - $macIcd = Get-ChildItem -Recurse -Path artifacts/osx-arm64 -Filter vk_swiftshader_icd.json | Select-Object -First 1 - Copy-Item $macIcd.FullName "$destDir/osx-arm64/" - - - name: Pack NuGet - shell: pwsh - run: | - $commitHash = git -C swiftshader-src rev-parse --short HEAD - $version = "${{ github.event.inputs.version }}" - if (-not $version) { $version = (Get-Date -Format "yyyy.M.d") } - nuget pack build/deps/swiftshader/Stride.Dependencies.SwiftShader.nuspec ` - -Version $version ` - -Properties "commit=$commitHash" ` - -OutputDirectory nupkg - echo "PACKAGE_VERSION=$version" >> $env:GITHUB_ENV - - - name: Upload package artifact - uses: actions/upload-artifact@v4 - with: - name: Stride.Dependencies.SwiftShader.nupkg - path: nupkg/*.nupkg - - publish: - name: Sign & Publish to NuGet.org - needs: pack - runs-on: windows-2025-vs2026 - environment: production - steps: - - name: Install signing tool - run: dotnet tool install sign --tool-path ./sign-tool --version 0.9.0-beta.23127.3 - - - name: Download artifact - uses: actions/download-artifact@v4 - with: - name: Stride.Dependencies.SwiftShader.nupkg - - - name: Sign NuGet package - shell: pwsh - run: | - ./sign-tool/sign code azure-key-vault *.nupkg ` - --description "Stride" ` - --description-url "https://stride3d.net" ` - --publisher-name "Stride" ` - --azure-key-vault-tenant-id "${{ secrets.STRIDE_SIGN_TENANT_ID }}" ` - --azure-key-vault-client-id "${{ secrets.STRIDE_SIGN_CLIENT_ID }}" ` - --azure-key-vault-client-secret "${{ secrets.STRIDE_SIGN_CLIENT_SECRET }}" ` - --azure-key-vault-certificate "${{ secrets.STRIDE_SIGN_KEYVAULT_CERTIFICATE }}" ` - --azure-key-vault-url "https://${{ secrets.STRIDE_SIGN_KEYVAULT_NAME }}.vault.azure.net/" ` - -v Information - - - name: Publish - run: | - dotnet nuget push *.nupkg --api-key "${{ secrets.STRIDE_NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index cc3bbf2817..2c49e44015 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -44,17 +44,24 @@ jobs: install_runtime: true cache: true stripdown: true - - name: Register SwiftShader ICD + - name: Register Lavapipe ICD (Windows host, for asset compilation) shell: pwsh run: | + # Build runs on Windows (CompilerApp needs Windows-only native libs), but produces + # Linux binaries. CompilerApp invokes a local Vulkan device during asset compilation, + # so it needs a Windows-registered ICD here. The win-x64 Lavapipe .dll is shipped + # inside the same NuGet package consumed by the tests; just register it. dotnet restore build\Stride.Tests.Game.GPU.slnf -p:StrideGraphicsApis=Vulkan -p:StrideGraphicsApi=Vulkan - $icd = Get-ChildItem -Recurse -Path "$env:USERPROFILE\.nuget\packages\stride.dependencies.swiftshader" -Filter vk_swiftshader_icd.json -ErrorAction SilentlyContinue | Where-Object { $_.DirectoryName -match 'win-x64' } | Select-Object -First 1 - if ($icd) { + $dll = Get-ChildItem -Recurse -Path "$env:USERPROFILE\.nuget\packages\stride.dependencies.lavapipe" -Filter vulkan_lvp.dll -ErrorAction SilentlyContinue | Where-Object { $_.DirectoryName -match 'win-x64' } | Select-Object -First 1 + if ($dll) { + $icdPath = Join-Path $dll.DirectoryName "lvp_icd.json" + $dllPath = $dll.FullName -replace '\\', '\\\\' + Set-Content -Path $icdPath -Value "{`"file_format_version`":`"1.0.0`",`"ICD`":{`"library_path`":`"$dllPath`",`"api_version`":`"1.3.0`"}}" New-Item -Path "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers" -Force | Out-Null - New-ItemProperty -Path "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers" -Name $icd.FullName -Value 0 -PropertyType DWord -Force | Out-Null - Write-Host "Registered SwiftShader ICD: $($icd.FullName)" + New-ItemProperty -Path "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers" -Name $icdPath -Value 0 -PropertyType DWord -Force | Out-Null + Write-Host "Registered Lavapipe ICD: $icdPath" } else { - Write-Warning "SwiftShader ICD not found in NuGet cache" + Write-Warning "Lavapipe DLL not found in NuGet cache" } - name: Build GPU tests (targeting Linux/Vulkan) run: | @@ -98,7 +105,7 @@ jobs: retention-days: 1 # Non-GPU game tests (run once, no graphics API dependency) - # Note: some tests still create a GraphicsDevice, so libvulkan1 + SwiftShader are needed. + # Note: some tests still create a GraphicsDevice, so libvulkan1 + Lavapipe are needed. Game-Common: name: Test Game Common (${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }}) needs: Build @@ -132,18 +139,23 @@ jobs: # Artifact download doesn't preserve Unix execute permissions find bin/Tests -name "*.bin" -exec chmod +x {} \; find bin/Tests -name "*.so" -exec chmod +x {} \; - - name: Register SwiftShader ICD + - name: Fetch & register Lavapipe ICD (from NuGet cache) run: | - # Find SwiftShader in any test output and create ICD JSON - LIB=$(find bin/Tests -name libvk_swiftshader.so | head -1) + # Pull the lavapipe NuGet package into the user-level cache without + # needing it copied into bin/Tests. A throwaway project pins the package + # into ~/.nuget/packages/stride.dependencies.lavapipe//. + mkdir -p /tmp/lavapipe-fetch + dotnet new classlib -o /tmp/lavapipe-fetch -n LavapipeFetch --force >/dev/null + dotnet add /tmp/lavapipe-fetch/LavapipeFetch.csproj package Stride.Dependencies.Lavapipe + LIB=$(find ~/.nuget/packages/stride.dependencies.lavapipe -path "*/runtimes/linux-x64/native/libvulkan_lvp.so" | head -1) if [ -n "$LIB" ]; then LIB_ABS=$(readlink -f "$LIB") - ICD_JSON="$PWD/vk_swiftshader_icd.json" - echo "{\"file_format_version\":\"1.0.0\",\"ICD\":{\"library_path\":\"$LIB_ABS\",\"api_version\":\"1.1.0\"}}" > "$ICD_JSON" + ICD_JSON="$PWD/lvp_icd.json" + echo "{\"file_format_version\":\"1.0.0\",\"ICD\":{\"library_path\":\"$LIB_ABS\",\"api_version\":\"1.3.0\"}}" > "$ICD_JSON" echo "VK_DRIVER_FILES=$ICD_JSON" >> $GITHUB_ENV - echo "Registered SwiftShader ICD: $ICD_JSON -> $LIB_ABS" + echo "Registered Lavapipe ICD: $ICD_JSON -> $LIB_ABS" else - echo "::warning::SwiftShader libvk_swiftshader.so not found in test binaries" + echo "::warning::Lavapipe libvulkan_lvp.so not found in NuGet cache" fi - name: Test if: always() @@ -173,7 +185,7 @@ jobs: path: tests/local/ if-no-files-found: ignore - # GPU game tests (Vulkan via SwiftShader) + # GPU game tests (Vulkan via Lavapipe) Game-GPU: name: Test Game Vulkan (${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }}) needs: Build @@ -193,7 +205,13 @@ jobs: - name: Install runtime dependencies run: | sudo apt-get update - sudo apt-get install -y libopenal-dev libfreeimage-dev libvulkan1 + sudo apt-get install -y libopenal-dev libfreeimage-dev libvulkan1 xvfb + - name: Start virtual display + run: | + # Lavapipe's x11 WSI needs a display server to expose VK_KHR_swapchain, + # which Stride's GraphicsDevice requires even for pure offscreen rendering. + Xvfb :99 -screen 0 1920x1080x24 & + echo "DISPLAY=:99" >> $GITHUB_ENV - name: Download test binaries uses: actions/download-artifact@v4 with: @@ -204,17 +222,24 @@ jobs: # Artifact download doesn't preserve Unix execute permissions find bin/Tests -name "*.bin" -exec chmod +x {} \; find bin/Tests -name "*.so" -exec chmod +x {} \; - - name: Register SwiftShader ICD + - name: Fetch & register Lavapipe ICD (from NuGet cache) run: | - LIB=$(find bin/Tests -name libvk_swiftshader.so | head -1) + # The test binaries ship without the 70+ MB vulkan_lvp.so (ExcludeAssets="native"), + # so pull the package into ~/.nuget/packages/ here. Also write an ICD eagerly as a + # safety net — the managed Stride.Dependencies.Lavapipe module initializer would + # otherwise do this at first use, but an explicit export makes CI logs clearer. + mkdir -p /tmp/lavapipe-fetch + dotnet new classlib -o /tmp/lavapipe-fetch -n LavapipeFetch --force >/dev/null + dotnet add /tmp/lavapipe-fetch/LavapipeFetch.csproj package Stride.Dependencies.Lavapipe + LIB=$(find ~/.nuget/packages/stride.dependencies.lavapipe -path "*/runtimes/linux-x64/native/libvulkan_lvp.so" | head -1) if [ -n "$LIB" ]; then LIB_ABS=$(readlink -f "$LIB") - ICD_JSON="$PWD/vk_swiftshader_icd.json" - echo "{\"file_format_version\":\"1.0.0\",\"ICD\":{\"library_path\":\"$LIB_ABS\",\"api_version\":\"1.1.0\"}}" > "$ICD_JSON" + ICD_JSON="$PWD/lvp_icd.json" + echo "{\"file_format_version\":\"1.0.0\",\"ICD\":{\"library_path\":\"$LIB_ABS\",\"api_version\":\"1.3.0\"}}" > "$ICD_JSON" echo "VK_DRIVER_FILES=$ICD_JSON" >> $GITHUB_ENV - echo "Registered SwiftShader ICD: $ICD_JSON -> $LIB_ABS" + echo "Registered Lavapipe ICD: $ICD_JSON -> $LIB_ABS" else - echo "::warning::SwiftShader libvk_swiftshader.so not found in test binaries" + echo "::warning::Lavapipe libvulkan_lvp.so not found in NuGet cache" fi - name: Test if: always() diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index ce01956503..f7486f2cc6 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -131,25 +131,25 @@ jobs: install_runtime: true cache: true stripdown: true - - name: Register SwiftShader ICD + - name: Register Lavapipe ICD if: matrix.graphics-api == 'Vulkan' shell: pwsh run: | - # Restore with StrideGraphicsApi=Vulkan so the conditional SwiftShader PackageReference is evaluated - # (Stride's custom multi-build targets don't run during restore) + # CompilerApp needs a Vulkan device at build time (Skybox asset compilation). + # Runtime tests are served by the Lavapipe module initializer; this step is + # only for the pre-runtime CompilerApp invocation, so we register an ICD here. + # Restore first so the package is in the NuGet cache. dotnet restore build\Stride.Tests.Game.GPU.slnf -p:StrideGraphicsApis=Vulkan -p:StrideGraphicsApi=Vulkan - # Find SwiftShader DLL in NuGet cache and register an ICD before build - # (CompilerApp needs SwiftShader at build time for Skybox asset compilation) - $dll = Get-ChildItem -Recurse -Path "$env:USERPROFILE\.nuget\packages\stride.dependencies.swiftshader" -Filter vk_swiftshader.dll -ErrorAction SilentlyContinue | Select-Object -First 1 + $dll = Get-ChildItem -Recurse -Path "$env:USERPROFILE\.nuget\packages\stride.dependencies.lavapipe" -Filter vulkan_lvp.dll -ErrorAction SilentlyContinue | Where-Object { $_.DirectoryName -match 'win-x64' } | Select-Object -First 1 if ($dll) { - $icdPath = Join-Path $dll.DirectoryName "vk_swiftshader_icd.json" + $icdPath = Join-Path $dll.DirectoryName "lvp_icd.json" $dllPath = $dll.FullName -replace '\\', '\\\\' - Set-Content -Path $icdPath -Value "{`"file_format_version`":`"1.0.0`",`"ICD`":{`"library_path`":`"$dllPath`",`"api_version`":`"1.0.5`"}}" + Set-Content -Path $icdPath -Value "{`"file_format_version`":`"1.0.0`",`"ICD`":{`"library_path`":`"$dllPath`",`"api_version`":`"1.3.0`"}}" New-Item -Path "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers" -Force | Out-Null New-ItemProperty -Path "HKLM:\SOFTWARE\Khronos\Vulkan\Drivers" -Name $icdPath -Value 0 -PropertyType DWord -Force | Out-Null - Write-Host "Registered SwiftShader ICD: $icdPath" + Write-Host "Registered Lavapipe ICD: $icdPath" } else { - Write-Warning "SwiftShader DLL not found in NuGet cache" + Write-Warning "Lavapipe DLL not found in NuGet cache" } - name: Build run: | diff --git a/build/deps/lavapipe/Lavapipe.cs b/build/deps/lavapipe/Lavapipe.cs new file mode 100644 index 0000000000..46cc846f53 --- /dev/null +++ b/build/deps/lavapipe/Lavapipe.cs @@ -0,0 +1,98 @@ +using System; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Stride.Dependencies.Lavapipe; + +/// +/// Auto-configures VK_DRIVER_FILES to point at the packaged lavapipe ICD manifest. +/// +/// +/// The packaged lvp_icd.json uses a relative library_path, so the Vulkan +/// loader resolves vulkan_lvp.dll/libvulkan_lvp.so/libvulkan_lvp.dylib +/// against the manifest's own directory — no runtime rewriting needed. +/// +/// Resolution order: +/// 1. runtimes/<rid>/native/ relative to AppContext.BaseDirectory (normal deployment) +/// 2. Next to this managed DLL (single-file / flat deployment) +/// 3. NuGet package cache (when consumer uses PackageReference ExcludeAssets="runtime") +/// +/// Caller can override by pre-setting VK_DRIVER_FILES before the module loads. +/// +public static class Lavapipe +{ + private const string ManifestName = "lvp_icd.json"; + + [ModuleInitializer] + internal static void AutoInit() + { + if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("VK_DRIVER_FILES"))) + return; + TryConfigure(); + } + + /// Force configuration. Returns true if VK_DRIVER_FILES was set. + public static bool TryConfigure() + { + var manifestPath = LocateManifest(); + if (manifestPath is null) + return false; + Environment.SetEnvironmentVariable("VK_DRIVER_FILES", manifestPath); + return true; + } + + static string? LocateManifest() + { + var rid = GetRid(); + var asmLoc = typeof(Lavapipe).Assembly.Location; + var asmDir = string.IsNullOrEmpty(asmLoc) ? null : Path.GetDirectoryName(asmLoc); + + // In-app candidates (no NuGet cache needed) + string?[] candidates = + [ + Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", ManifestName), + Path.Combine(AppContext.BaseDirectory, ManifestName), + asmDir is null ? null : Path.Combine(asmDir, ManifestName), + // NuGet-cache layout when this dll is loaded directly from the cache: + // ///lib/net10.0/Stride.Dependencies.Lavapipe.dll + // → manifest at ///runtimes//native/ + asmDir is null ? null : Path.GetFullPath(Path.Combine(asmDir, "..", "..", "runtimes", rid, "native", ManifestName)), + ]; + + foreach (var p in candidates) + { + if (!string.IsNullOrEmpty(p) && File.Exists(p)) + return Path.GetFullPath(p); + } + + // Last-resort: scan the NuGet package cache (handles ExcludeAssets="runtime" + // where natives are not copied to output and this dll also may not be). + var nugetRoot = Environment.GetEnvironmentVariable("NUGET_PACKAGES") + ?? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); + var pkgRoot = Path.Combine(nugetRoot, "stride.dependencies.lavapipe"); + if (Directory.Exists(pkgRoot)) + { + foreach (var verDir in Directory.EnumerateDirectories(pkgRoot).OrderByDescending(d => d)) + { + var p = Path.Combine(verDir, "runtimes", rid, "native", ManifestName); + if (File.Exists(p)) + return p; + } + } + + return null; + } + + static string GetRid() + { + if (OperatingSystem.IsWindows()) + return "win-x64"; + if (OperatingSystem.IsLinux()) + return "linux-x64"; + if (OperatingSystem.IsMacOS()) + return RuntimeInformation.ProcessArchitecture == Architecture.Arm64 ? "osx-arm64" : "osx-x64"; + throw new PlatformNotSupportedException(); + } +} diff --git a/build/deps/lavapipe/Stride.Dependencies.Lavapipe.csproj b/build/deps/lavapipe/Stride.Dependencies.Lavapipe.csproj new file mode 100644 index 0000000000..f386b055e9 --- /dev/null +++ b/build/deps/lavapipe/Stride.Dependencies.Lavapipe.csproj @@ -0,0 +1,25 @@ + + + net10.0 + enable + latest + + Stride.Dependencies.Lavapipe + Stride Contributors + Lavapipe software Vulkan ICD (Mesa/llvmpipe) for Stride GPU testing. Auto-configures VK_DRIVER_FILES on load. + MIT + https://github.com/stride3d/stride + git + + + true + + + + + + + + diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index ed16f80e86..cf127724bf 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -103,7 +103,7 @@ - + diff --git a/sources/engine/Stride.Engine.Tests/TesselationTest.cs b/sources/engine/Stride.Engine.Tests/TesselationTest.cs index 6d04fca131..eae4f604d5 100644 --- a/sources/engine/Stride.Engine.Tests/TesselationTest.cs +++ b/sources/engine/Stride.Engine.Tests/TesselationTest.cs @@ -210,7 +210,6 @@ private void ChangeMaterial(int i) [SkippableFact] public void RunTestGame() { - SkipTestForGraphicPlatform(GraphicsPlatform.Vulkan); // Note: D3D12 WARP tessellation is limited to first frame only (see RegisterTests) diff --git a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs index 95029390c7..dd2e528214 100644 --- a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs +++ b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs @@ -881,7 +881,7 @@ private string GetPlatformSpecificDirectory() { deviceName = GraphicsDevice.Platform switch { - GraphicsPlatform.Vulkan => "SwiftShader", + GraphicsPlatform.Vulkan => "Lavapipe", _ => "WARP" }; } diff --git a/sources/engine/Stride.Graphics.Regression/Module.cs b/sources/engine/Stride.Graphics.Regression/Module.cs index f381000959..4aa1108021 100644 --- a/sources/engine/Stride.Graphics.Regression/Module.cs +++ b/sources/engine/Stride.Graphics.Regression/Module.cs @@ -8,8 +8,6 @@ using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; -using Stride.Core; - namespace Stride.Graphics.Regression; internal static class Module @@ -34,7 +32,7 @@ internal static void Initialize() SetErrorMode(0x0001 /* SEM_FAILCRITICALERRORS */ | 0x0002 /* SEM_NOGPFAULTERRORBOX */ | 0x8000 /* SEM_NOOPENFILEERRORBOX */); } - // GPU drivers (including software renderers like WARP and SwiftShader) can crash with + // GPU drivers (including software renderers like WARP and Lavapipe) can crash with // native access violations when used incorrectly (e.g., releasing resources still in use). // These crashes are hard to diagnose: .NET 8+ can't catch them via try/catch, and WER // doesn't trigger because .NET handles the exception dispatch internally. @@ -62,33 +60,13 @@ internal static void Initialize() if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("STRIDE_MAX_PARALLELISM"))) Environment.SetEnvironmentVariable("STRIDE_MAX_PARALLELISM", "8"); - // Auto-configure SwiftShader ICD path for Vulkan software rendering. - // SwiftShader libs are in runtimes/{rid}/native/ — find the right one for this OS. +#if STRIDE_GRAPHICS_API_VULKAN + // Force-load Stride.Dependencies.Lavapipe so its ModuleInitializer runs and + // points VK_DRIVER_FILES at the packaged ICD before any Vulkan instance is created. + // Skip if the caller already set VK_DRIVER_FILES (e.g. benchmarking a different ICD). if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("VK_DRIVER_FILES"))) - { - var (rid, libName) = Platform.Type switch - { - PlatformType.Windows => ("win-x64", "vk_swiftshader.dll"), - PlatformType.Linux => ("linux-x64", "libvk_swiftshader.so"), - PlatformType.macOS => ("osx-arm64", "libvk_swiftshader.dylib"), - _ => throw new PlatformNotSupportedException($"Software rendering not supported on {Platform.Type}") - }; - var libPath = Path.Combine(AppContext.BaseDirectory, "runtimes", rid, "native", libName); - if (File.Exists(libPath)) - { - var icdPath = Path.Combine(AppContext.BaseDirectory, "vk_swiftshader_icd.json"); - File.WriteAllText(icdPath, $$""" - { - "file_format_version": "1.0.0", - "ICD": { - "library_path": "{{libPath.Replace(@"\", @"\\")}}", - "api_version": "1.1.0" - } - } - """); - Environment.SetEnvironmentVariable("VK_DRIVER_FILES", icdPath); - } - } + Stride.Dependencies.Lavapipe.Lavapipe.TryConfigure(); +#endif } } diff --git a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj index a25229c1da..19d308e51e 100644 --- a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj +++ b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj @@ -24,7 +24,14 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/sources/engine/Stride.Graphics.Tests/FixedAspectRatioTests.cs b/sources/engine/Stride.Graphics.Tests/FixedAspectRatioTests.cs index eac9ed1dac..870957d38a 100644 --- a/sources/engine/Stride.Graphics.Tests/FixedAspectRatioTests.cs +++ b/sources/engine/Stride.Graphics.Tests/FixedAspectRatioTests.cs @@ -68,7 +68,6 @@ protected override async Task LoadContent() [Fact] public void TestFixedRatio() { - // Note: SwiftShader produces a 1-pixel black line at the viewport boundary; this is a known SwiftShader rasterization difference RunGameTest(new FixedAspectRatioTests()); } } diff --git a/sources/engine/Stride.Graphics.Tests/TestTexture.cs b/sources/engine/Stride.Graphics.Tests/TestTexture.cs index bc86254a41..006fc3d2b2 100644 --- a/sources/engine/Stride.Graphics.Tests/TestTexture.cs +++ b/sources/engine/Stride.Graphics.Tests/TestTexture.cs @@ -231,8 +231,6 @@ public void TestTexture2DUnorderedAccess() [SkippableFact] public void TestTexture3D() { - Skip.If(Platform.Type == PlatformType.Linux, reason: "SwiftShader does not support 3D textures"); - PerformTest( game => { diff --git a/sources/engine/Stride.Graphics/AppContextType.cs b/sources/engine/Stride.Graphics/AppContextType.cs index e60bc5dbae..6726bd0235 100644 --- a/sources/engine/Stride.Graphics/AppContextType.cs +++ b/sources/engine/Stride.Graphics/AppContextType.cs @@ -81,7 +81,7 @@ public enum AppContextType /// /// The Game runs in headless mode without a window or display. - /// Used for automated testing with software renderers (e.g. SwiftShader). + /// Used for automated testing with software renderers (e.g. Lavapipe). /// Headless, } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs index e320140967..8e7a77ddf8 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs @@ -152,7 +152,7 @@ public unsafe GraphicsAdapterFactoryInstance(bool enableValidation) }; var supportedExtensions = new Span(supportedExtensionNames, 6); var availableExtensionNames = GetAvailableExtensionNames(supportedExtensions); - // Surface extensions are optional at instance creation (not available with headless ICDs like SwiftShader). + // Surface extensions are optional at instance creation (not available with headless ICDs). // They are validated later when a swapchain is actually created. var desiredExtensionNames = new HashSet(); HasSurfaceSupport = availableExtensionNames.Contains(VK_KHR_SURFACE_EXTENSION_NAME); diff --git a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs index 12374b80a0..17f02626e9 100644 --- a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs @@ -510,9 +510,9 @@ private unsafe void CreateSurface() throw new ArgumentException("DeviceWindowHandle cannot be null"); } - // Validate surface extension support (not available with headless ICDs like SwiftShader) + // Validate surface extension support (not available with headless ICDs) if (!GraphicsAdapterFactory.GetInstance(GraphicsDevice.IsDebugMode).HasSurfaceSupport) - throw new InvalidOperationException("Cannot create a swapchain: Vulkan surface extensions are not available. This may happen when using a headless ICD (e.g. SwiftShader)."); + throw new InvalidOperationException("Cannot create a swapchain: Vulkan surface extensions are not available. This may happen when using a headless ICD."); // Create surface #if STRIDE_UI_SDL diff --git a/sources/tools/Stride.Graphics.RenderDocPlugin/RenderDocManager.cs b/sources/tools/Stride.Graphics.RenderDocPlugin/RenderDocManager.cs index 80f6ed5358..deea2de55e 100644 --- a/sources/tools/Stride.Graphics.RenderDocPlugin/RenderDocManager.cs +++ b/sources/tools/Stride.Graphics.RenderDocPlugin/RenderDocManager.cs @@ -131,7 +131,7 @@ private static unsafe nint GetDevicePointer(GraphicsDevice graphicsDevice) devicePointer = (nint) GraphicsMarshal.GetNativeDevice(graphicsDevice).Handle; #elif STRIDE_GRAPHICS_API_VULKAN // RenderDoc Vulkan capture uses NULL (wildcard) for the device pointer. - // Passing VkInstance.Handle crashes with some ICDs (e.g. SwiftShader). + // Passing VkInstance.Handle crashes with some ICDs. #endif return devicePointer; } diff --git a/tests/Stride.Engine.Tests/Linux.Vulkan/Lavapipe/AnimatedModelTests.f3.png b/tests/Stride.Engine.Tests/Linux.Vulkan/Lavapipe/AnimatedModelTests.f3.png new file mode 100644 index 0000000000..a6f610cb24 --- /dev/null +++ b/tests/Stride.Engine.Tests/Linux.Vulkan/Lavapipe/AnimatedModelTests.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0cafec722d4cb4f6dc50d4abefc51cc401afc66d48041b8bc4b56ceb82070a88 +size 19950 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f1.png new file mode 100644 index 0000000000..066d525466 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5637b04cf0d13cb81df8483219a055e0b23fd4da23511c55660be01a0c7ed380 +size 18080 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f2.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f2.png new file mode 100644 index 0000000000..76bf0c8f5a --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c5831f07d7b9943da7c8901f5dcaf6323a5bd1c40f1e0d49ca7bc2140509573 +size 20420 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f3.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f3.png new file mode 100644 index 0000000000..54343b1081 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cac9df6ab38129fb592c0b17c56ca406352e20c42974dfa7121bad5319af4cd4 +size 19948 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f4.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f4.png new file mode 100644 index 0000000000..ea8769f9f6 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:abddd4be348ac4071d092d5f144a94e621740ea09e69355dc2b13d4fc8acf953 +size 35319 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f5.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f5.png new file mode 100644 index 0000000000..fe7d1fc74a --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37b6ace69b094d2acbb6ff963a1064fc6a2ee7d9519428c4efb740890d583ac7 +size 24311 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.png new file mode 100644 index 0000000000..fe7d1fc74a --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/AnimatedModelTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37b6ace69b094d2acbb6ff963a1064fc6a2ee7d9519428c4efb740890d583ac7 +size 24311 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer2DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer2DTests.f1.png new file mode 100644 index 0000000000..8731818dfa --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer2DTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb1d49dc3ae9ec5fd57fc5c6ce73d2f111ffee602d900e42ec58d52028c03e5c +size 302783 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.f1.png new file mode 100644 index 0000000000..f1560deb60 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:87a96ee5ca6967825918593429d8f645043baee8f4f9db51981342d8a5bf1ffb +size 227691 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.png new file mode 100644 index 0000000000..3214754007 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteRenderer3DTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92b14121300088ab302be4eb7937a70851b0bc85f01da1e9a60e988b2ffdc39e +size 266719 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f1.png new file mode 100644 index 0000000000..44d1789f50 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9173e33fdb25da7034bea438d00228860c5774bfb38d8f765c398063f1f1a6bb +size 53517 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f2.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f2.png new file mode 100644 index 0000000000..d096759c19 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f0b7e31acee97a810a65f509b581b25d07a9bee51561a2b9891cc5bc0dfdcc0 +size 53426 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.png new file mode 100644 index 0000000000..8e20f07126 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/SpriteTestGame.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1cd02fa2086b536600e1d52c37127e663e33c0868874d82e8bb7f09abb22baf3 +size 60264 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f1.png new file mode 100644 index 0000000000..151910ed16 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:414c53eb786002096dd55ac09aeaa722752e489bc650481b174c34329b09b049 +size 85870 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f2.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f2.png new file mode 100644 index 0000000000..b20cf66e35 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4babae87e7b4d02392803b9c24cb7aec608a701072c587dff74845005ba37867 +size 53601 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f3.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f3.png new file mode 100644 index 0000000000..f125b30dda --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:175b1f624a8007e61f4d09c1d2ef8c053db8b648adc246ecab6aafa275f8aa2f +size 81085 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f4.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f4.png new file mode 100644 index 0000000000..4ba2423ffd --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a22f793f8a3a3cb287e19e25296cd777efce31f4b11b67c85b15d09b660f9aa5 +size 72216 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f5.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f5.png new file mode 100644 index 0000000000..66c30a4781 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e30a580b737d8ecc57210f9966115dba94f785f07bada0af45fd45ccb8dae415 +size 81199 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.png b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.png new file mode 100644 index 0000000000..4970e51539 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Vulkan/Lavapipe/TesselationTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:049b91256a09bd7a219584376a52a20120f706acbdc8cba7e4f2e5be8c402b7c +size 73944 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/AnimatedModelTests.f4.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/AnimatedModelTests.f4.png deleted file mode 100644 index 34f077e00b..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/AnimatedModelTests.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a8b536d90686e0ed83d199b49963b4361aabb898900f64bea0e7a6a9b15a1ad4 -size 35297 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png deleted file mode 100644 index fa3a724e16..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba89080019d106875c2a6f0bfc7a1bf5211c5a6deea9b5d4870059e84e8f250d -size 302163 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png deleted file mode 100644 index 056b3f43c5..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer2DTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce1ae0208bc268363fd258c7a0fb251a2e45174c66d3e64c92c109f69ee34f42 -size 263085 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png deleted file mode 100644 index f04bb06bc6..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f2575618a54487b56c8bcb4c54aa75a11d750eef42c8d0d6d5e6d145d4e56b9d -size 227263 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.png deleted file mode 100644 index 54c271eaee..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteRenderer3DTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de1c74d7a1ed409b5ae4fda491c023e5eba040b7c1a6efdceaeb4aa876437715 -size 266254 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png deleted file mode 100644 index 91246090df..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:86cb8e2166621d7e754f647c99aa7b41735aef1314a6b297a369abf5b328d8a6 -size 53458 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png deleted file mode 100644 index 32adad4ae1..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02ef2c1eb01ae21584226e890f19b92017b5b55e970cdc355a9410051eaffc61 -size 53359 diff --git a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png b/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png deleted file mode 100644 index a06441836a..0000000000 --- a/tests/Stride.Engine.Tests/Windows.Vulkan/SwiftShader/SpriteTestGame.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6c92ef8c4e0f2af22d9f1e2a57584016e32e16ec7395a08d5594c86fa74f8ad3 -size 60158 diff --git a/tests/Stride.Engine.Tests/thresholds.jsonc b/tests/Stride.Engine.Tests/thresholds.jsonc index a728175b0d..4360667ca0 100644 --- a/tests/Stride.Engine.Tests/thresholds.jsonc +++ b/tests/Stride.Engine.Tests/thresholds.jsonc @@ -10,21 +10,10 @@ // allow - max allowed pixel counts per diff range (e.g. "1-2": 500, "16+": 2) [ { - // Single pixel at X:347 Y:183 (knight's hand) flickers due to sub-pixel - // rasterization on the geometry edge in SwiftShader on Linux. + // Sometime one pixel in knight model flickers due to sub-pixel + // rasterization on a geometry edge; observed across software renderers + // (Lavapipe/WARP on Linux/Windows). Tolerated on all platforms. "image": "AnimatedModelTests.f3.png", - "platform": "Linux", - "api": "Vulkan", - "device": "SwiftShader", - "allow": { "3-70": 1, "71+": 0 } - }, - { - // Single pixel at X:347 Y:183 (knight's hand) flickers due to sub-pixel - // rasterization on the geometry edge in SwiftShader on Linux. - "image": "AnimatedModelTests.f3.png", - "platform": "Windows", - "api": "Direct3D12", - "device": "WARP", "allow": { "3-70": 1, "71+": 0 } } ] diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png new file mode 100644 index 0000000000..88efc493a2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6be5963c3c201f2878986f3083a9d142f1b2dc8b27c1cf3db228d6cd92181fa +size 99786 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png new file mode 100644 index 0000000000..09ec63ffcb --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e720cea0c8f67c952a29910c461ebed233250079cc82d92f243dca43f552302a +size 16928 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png new file mode 100644 index 0000000000..bbc3a35c96 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8d5b0937d206fe2424fb7af9c29b09b28941265b021923b3fc7e263c3d44181 +size 17636 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png new file mode 100644 index 0000000000..8d4f18d3bc --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de8c3dcffcf1b54c8809d74d71bd107f91fba43a370bf535a1133fffd6d4ff30 +size 9273 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestLightShafts.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestLightShafts.png new file mode 100644 index 0000000000..b4faabcb3c --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestLightShafts.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e810b95b34774c34bb7540d32d8aa3d91c73bc39c0d5c2c490319c78b19d2c2 +size 120652 diff --git a/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png new file mode 100644 index 0000000000..0466ad1d91 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Linux.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbafc1d5b941f7f1f9715a845ba88654ee220291332915d53d6dde880d0137fd +size 80106 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/FixedAspectRatioTests.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/FixedAspectRatioTests.png new file mode 100644 index 0000000000..5ee5f30707 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/FixedAspectRatioTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9015a0bbb7c3d676467b7fec11d3593ca7e34aba828e69df6b392ff04de083a +size 30769 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLight.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLight.png new file mode 100644 index 0000000000..d5bf9bc9df --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLight.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60e8b020cd72459c6165203cd3c8c94d0327e797ff182e7480f073af56e1ae99 +size 234199 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowFourCascades.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowFourCascades.png new file mode 100644 index 0000000000..6d5d4c078e --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowFourCascades.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:444d43fbc5952d10443b1bced6a0a74dfe94eaef6be2e6e10474a618d87bdcfe +size 237663 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascade.png new file mode 100644 index 0000000000..abd2a8251b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascade.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:481b96c4f45eb5fe5bd62e191e497897a9d8ddda87188adf75f2fb0d99d3e6d5 +size 237859 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png new file mode 100644 index 0000000000..dabe62455d --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a0f8eb7b6ae4c69dbd819a25f3cf5d97edbdfb62a8b5c7c5b532e47a4d20c209 +size 243308 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneFourCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneFourCascade.png new file mode 100644 index 0000000000..8ea476b759 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneDirectionalLightShadowOneFourCascade.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bfafc0d4ef2ff21839aea82ffe6c9535aa4874ee66df7a9b64fa0b98713b03b +size 241971 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLight.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLight.png new file mode 100644 index 0000000000..7b14e35f8b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLight.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e166e7ab0a58be91eda7331e85548f539a26bc06051987b72813fc73bc8efd44 +size 251312 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowCubeMap.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowCubeMap.png new file mode 100644 index 0000000000..40c644f1cd --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowCubeMap.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e92e0fc8db3a10076726e5530b4624c7dafa4ac76ffaaf038fa997fc809a77b8 +size 229564 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowParaboloid.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowParaboloid.png new file mode 100644 index 0000000000..e9275403f3 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.ScenePointLightShadowParaboloid.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4605d32df05a147d5a09cd82ebebfee345a0c1c9b23e76fae7cd9028e69ec24b +size 220801 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkybox.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkybox.png new file mode 100644 index 0000000000..de4ad43cce --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkybox.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85daed39e352bbddfee605d561452ca010aeced02ab18603f33f08997d3778e8 +size 221924 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxMultiple.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxMultiple.png new file mode 100644 index 0000000000..5f68d83f4f --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxMultiple.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49330b8f09aa558f69b746bc54e3ff79baa1b47bb1a85afe13887f8d0cabb758 +size 226581 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxRotated.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxRotated.png new file mode 100644 index 0000000000..00e39cb771 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSkyboxRotated.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a062ab4f1f1aa76a4810abd71f152d092d2bf507f3fb5ab6ab8f6f6714d4bd8 +size 222163 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLight.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLight.png new file mode 100644 index 0000000000..9f899b1e3a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLight.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8ec179cc2ce7b8647b6b25a70265ebf86bec8b88b782e480f40c46e60d78d34 +size 227439 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLightShadow.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLightShadow.png new file mode 100644 index 0000000000..4593e50efc --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneSpotLightShadow.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df814120d825e9b30f817e70b14df34524d3ce7aa5d5ef97abf2b129fa19e490 +size 227337 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png new file mode 100644 index 0000000000..f011fee15a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd3f0d26ba5e9b37978b06ee877bb0cbf2979b9963ff9c8f23e28ecec9b69c8e +size 250789 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialDiffuseTextureCoord1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialDiffuseTextureCoord1.png new file mode 100644 index 0000000000..d8733adce2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialDiffuseTextureCoord1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ecbfef6053b55c775fdc0b2573437f61bd44ef099eb23a0dc3efe3fd69ab368 +size 196312 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialEmissive.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialEmissive.png new file mode 100644 index 0000000000..1edf76ddfc --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialEmissive.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c65941973a19e0c16a52775beffcd469bd1a50ee9edffff2095c081276b24fb +size 222753 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerAAA.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerAAA.png new file mode 100644 index 0000000000..5b0dc105f2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerAAA.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b8248f38ad1cd27ff3a3931690ff96e882d7017c99bd48c353bb35e0d08b135 +size 143612 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABA.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABA.png new file mode 100644 index 0000000000..bb087cade6 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABA.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09167faae1abb7a2912ac39826a452aee6a7b22a764d3037a79febb204b6fe4a +size 150108 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABC.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABC.png new file mode 100644 index 0000000000..64839b2f16 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerABC.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4bfdfb0f452e7472e5ebd05d164984a8292dd00899b540b7a9505588b467c71 +size 155061 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerBBB.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerBBB.png new file mode 100644 index 0000000000..d487dae0fd --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialLayerBBB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d7c24b588b241e652498a7d25cd13f64070162a5e90b033a35ced12e743f4bb +size 147204 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialMetalness.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialMetalness.png new file mode 100644 index 0000000000..d50ff5d3d3 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialMetalness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:03753398fd19deffe07fe155d876f5794b63601428f007ff223ab29c4b28f0a8 +size 230968 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialSpecular.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialSpecular.png new file mode 100644 index 0000000000..f6f14a1e4e --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/MaterialTests.MaterialSpecular.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3df299c1849510e755cc984469d283a3cb8d84db9144d1e3146769c82ccbe128 +size 192975 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestCustomEffect.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestCustomEffect.png new file mode 100644 index 0000000000..914cae168e --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestCustomEffect.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:196ed3929524d3df202f7f826c6c704933649862f12fdd8381bdc5868fe53ffb +size 13091 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDrawQuad.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDrawQuad.png new file mode 100644 index 0000000000..35424c208d --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDrawQuad.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:31bd124f3258066eb7fb8a6b9c57ecb34e94fa05d51995e61a4753fa80e23acb +size 27472 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f1.png new file mode 100644 index 0000000000..a6d863a7fe --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64f6aa47fb58b854acb5d86fc091a0892a5c5c6a15d6bea783b84a782f69bf28 +size 58737 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f2.png new file mode 100644 index 0000000000..a0389502f5 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a55f9e9cf38d22a7e702106a25dd7e658a5c9d59da2c1e40e84c8f34cfbaa762 +size 64466 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.png new file mode 100644 index 0000000000..6c3d3f8d26 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFont.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74682d40dbb03a46c4b4a2036e67df96098cc6313f0c297570ac1c7cc1c968aa +size 57912 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png new file mode 100644 index 0000000000..baf184692e --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontJapanese.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a431495157801ed099daa80e07d8ff34f4af50981607dfbb69e3f089002b5878 +size 99786 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png new file mode 100644 index 0000000000..20c56c7083 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99b5e5ecaf33ada33fcf144b3bbffa3960261cc07709c070082dfdcf3752288f +size 16903 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png new file mode 100644 index 0000000000..6c1c5984b2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:194c54140cd244ead87c87cbac2f6d3fd16d39d50e095eba97f6c7561a928028 +size 17619 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png new file mode 100644 index 0000000000..f8a1b3343b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestDynamicSpriteFontVarious.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4811c7531ee877b0194a227f9e37018bb29d1ac40ad88ab0f8cbaefabfd3739f +size 9255 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f1.png new file mode 100644 index 0000000000..26bd9b77f4 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d37fe81e011d59c41133b78e36016651d552ed4f3a8ac82ce71c04efc351a49 +size 84995 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f2.png new file mode 100644 index 0000000000..6688018c8b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6b7bf632ae66daa4509b7d091442d0e52be50a686d3a8e1dd5f6900c2dc0eda +size 82382 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.png new file mode 100644 index 0000000000..f3c4d8a4f8 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestGeometricPrimitives.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c679a36073f1793f97f0cba686bd589e50c31b0838ee89515a501d4776768c04 +size 88092 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestImageEffect.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestImageEffect.png new file mode 100644 index 0000000000..4f0236aff1 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestImageEffect.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e35c8b310b84a6e6d7264d0b1c3e8311654e45c706f481796ba66cd6a026dde3 +size 397694 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png new file mode 100644 index 0000000000..ee877b3a4f --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2b3641a56b482b80bc3f472ca918cfacd607f0fdb83d42f80ceebc9c1b1ae8ea +size 120647 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f1.png new file mode 100644 index 0000000000..9002b91f6e --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22bb781724201520e7c5bd4779df7e4e1cd3376babbd1bf034f884c3a739a6d5 +size 21850 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f2.png new file mode 100644 index 0000000000..c467448e6b --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestPrecompiledSpriteFont.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f111a546c3b91a9f168d1c383597f7a3b5cf6ee63f4cb2701080306f79bf6286 +size 27133 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestRenderToTexture.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestRenderToTexture.png new file mode 100644 index 0000000000..0d38846003 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestRenderToTexture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9512b5fc7a11e1e265aa407b547ef407407a466386bd9bf0e680c1c262aad1bb +size 56137 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.f1.png new file mode 100644 index 0000000000..bfccc533a1 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eab1baf3cd2a86cf8194eae8a0ad913f2bc32d625e1e287c96b8b0e262014a8 +size 129231 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.png new file mode 100644 index 0000000000..b959eec1db --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6952f4b64f6fd8023899453ebb4df58588ada78d5b348acbff0fa808f4d1c06a +size 130836 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.f1.png new file mode 100644 index 0000000000..56dcc10f4f --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d7f0f2f58a411cbc0614dd3edb4c437a5c21da1928ae71cd33379b873eac354 +size 38149 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.png new file mode 100644 index 0000000000..96d0406af2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatch3D.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:128d689bc7292a57e8984c83b1c8d14f136954498e3194d551367c0c1f2efe92 +size 33925 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f1.png new file mode 100644 index 0000000000..7b6e2309cd --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4555c505889a678941c135f69036abe4dee97945d4c540a42edc311ec4306f26 +size 19967 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png new file mode 100644 index 0000000000..9ddd90c089 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc17bae967bb7dced3b77489b061404b15c58d20bb6bd840961595921d6a59a1 +size 80094 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f3.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f3.png new file mode 100644 index 0000000000..0320ff60ed --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d4e0f15eb8f6110819e3b3969da47a77bff08af8d75dd1b008b480acd9b0146 +size 20299 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.png new file mode 100644 index 0000000000..9aa232f1cb --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchResolution.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a25f884417dd1dc8193d62b4a3ec4e7e2d3ecdcf161881ddaed3ff51e244da4f +size 34380 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchToTexture.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchToTexture.png new file mode 100644 index 0000000000..1091f1c9d0 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestSpriteBatchToTexture.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7491f672707c3a5d7e1e5591a4e712cdab1cb047c14c015f869f76d1da274a1 +size 53857 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f1.png new file mode 100644 index 0000000000..4e7e785fb4 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ae9173d9731bcf4a545eaa684da59f10f46801989f032981644800df48d50fe +size 59372 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f2.png new file mode 100644 index 0000000000..55f66e758c --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41e4a5363a23733000a0c7ab28d9c6653a8c184e3b695cd9f85fb35d75fe162f +size 63958 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.png new file mode 100644 index 0000000000..8a423b5e4c --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestStaticSpriteFont.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8e8ecff9ce2b91a2952b6294c2b4c3b43c7f6899f4967e25cf9b54f73c739ad +size 58086 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Bmp).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Bmp).png new file mode 100644 index 0000000000..a20e73143a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Bmp).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bbda5634a5cfcf275d04e91907cc56e7f3ef993befb79ca195be76c4be8dc27 +size 99578 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Dds).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Dds).png new file mode 100644 index 0000000000..e6812a325a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Dds).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:504004dea9f1709fbe4c33ddcd5372831dbdf50e7b919785237f211498cdc068 +size 76778 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Gif).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Gif).png new file mode 100644 index 0000000000..0f0ca939a7 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Gif).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c89409ff493aaf011fa51389e11e1529fb6e57f84394678d8b27571fe6d3c59d +size 89966 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Png).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Png).png new file mode 100644 index 0000000000..38dfea14f2 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Png).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1d23dbda0d39bd168939ed615952180f8b19b8cb1650cad6905a63828ffbcea3 +size 109560 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Stride).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Stride).png new file mode 100644 index 0000000000..e6812a325a --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Stride).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:504004dea9f1709fbe4c33ddcd5372831dbdf50e7b919785237f211498cdc068 +size 76778 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Tiff).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Tiff).png new file mode 100644 index 0000000000..2776a7aa1d --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestTexture.TestLoadDraw(Tiff).png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1029869b4edaaea203ad97c97f4f6afddabc3cca62ab54f65e879b7f6f473e11 +size 98994 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/FixedAspectRatioTests.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/FixedAspectRatioTests.png deleted file mode 100644 index dd339a103b..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/FixedAspectRatioTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:81afdc6d2e19cc8ad17add402124ce612ff0d9fb600517596d19b7df493645be -size 30254 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLight.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLight.png deleted file mode 100644 index 5ed8fd84b9..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:85387ffe2d91f6e714c10cfc779c588ad8c3cddaa1c3531a8c6c74ab9874792d -size 233456 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowFourCascades.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowFourCascades.png deleted file mode 100644 index 48b94870f2..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowFourCascades.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83a385b857adab99f313c31aa7dd6420bc819cca836902fd43af64f042cc473d -size 236843 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascade.png deleted file mode 100644 index 3642fd19a0..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascade.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:80a093b3f8e5abcab0560663e4d3ab00d30737919b9ed83f3db7786a0e1afccb -size 236966 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png deleted file mode 100644 index d213bb997d..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e1827677e11e97852bf3ad50af2684dd4d89cb3a473a75af2e6d7a9ecf3a4d92 -size 242315 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneFourCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneFourCascade.png deleted file mode 100644 index 55082f434e..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneDirectionalLightShadowOneFourCascade.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7afba99369844711e99d9ef26d1ab35eaabf087156d6e618f3029f4a8e58d5ff -size 240944 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLight.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLight.png deleted file mode 100644 index 5ac5bfdaeb..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLight.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b7353d65f32104deb87c0b395e8d09dc2cd7be00875e0ff6861d78a1dd94b90 -size 250613 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowCubeMap.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowCubeMap.png deleted file mode 100644 index 968d296131..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowCubeMap.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:acaadf827abab5e360b32b10448c3ad7ac1d1595bc4a2145a13a5e11544f0dae -size 228495 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowParaboloid.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowParaboloid.png deleted file mode 100644 index 6a3a51eaee..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.ScenePointLightShadowParaboloid.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fcd38b06d0c58988b43fe7e52c4f798b0e00433c756bc90ffae728ceedef17a6 -size 219943 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png deleted file mode 100644 index 5710b18230..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c407a65649ea3e3de48e69da090e8bfcdf5941baea9e1ad304d8b592265f2a8c -size 249943 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerAAA.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerAAA.png deleted file mode 100644 index b33cc11fc9..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerAAA.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:04ff608823f3be00562fc2bcd2a724b007d9d5b0bf93cc6faba4e8001e8ee36a -size 143461 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABA.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABA.png deleted file mode 100644 index e6786b7d72..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABA.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:06a66ec8b2650d676efcc1e1f8e1f6a2a338ba014351d4d483b8aa820cc1b1db -size 149926 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABC.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABC.png deleted file mode 100644 index 965b0a847a..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerABC.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3e62e0b2fca10ca0246682b8dda2ec9f0d80bdf2c062e64dcbf8b93eb676c13c -size 154894 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerBBB.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerBBB.png deleted file mode 100644 index e008a1b747..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialLayerBBB.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6099108df03c076a6b4174ee3b2e536eb92e0a9d9605bd284515f2511552ce00 -size 146957 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialMetalness.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialMetalness.png deleted file mode 100644 index c7e4e9efda..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialMetalness.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7207f108d897c822852242d77e426cde42805c204493546a2e8f96f36f248c41 -size 230885 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialSpecular.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialSpecular.png deleted file mode 100644 index bc40ba3e55..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/MaterialTests.MaterialSpecular.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f2293210a8befb965d6f39b5de339c835662e742cdc1f30988e49aa0b63901e5 -size 193238 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestBitmapSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestBitmapSpriteFont.png deleted file mode 100644 index d5dc858b0b..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestBitmapSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:968ce5616e02aa3fa09ebf051d20840e7143060930e04264fc3c884b0dc3d43a -size 10647 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestCustomEffect.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestCustomEffect.png deleted file mode 100644 index 491c6a3eba..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestCustomEffect.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ff4d1ee266ba6e55bc3483c87fe9fca68f7424b636d6869cf0d073dbc03ca570 -size 13184 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDrawQuad.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDrawQuad.png deleted file mode 100644 index 9ce9fe8754..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDrawQuad.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7d46ea58f3312c0cd3a2c24430831aaa0556ff736893fc5ca50ccd5c79881297 -size 27654 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png deleted file mode 100644 index 7732ef9946..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e9902492277988d001e53ae3fa51a374b10d029aa37e54155833dc7f3e76be1 -size 60213 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png deleted file mode 100644 index 38d6ddc812..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cefe5766fd77d4130e0e9b84f15d78395579e8a12ffb19e2d5bd68b1dca739cf -size 65940 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png deleted file mode 100644 index e454edbc5d..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2a71157ff1a61364663bd95d27a155aafd0f188a9792df653f4ea5c6d58c9089 -size 59263 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png deleted file mode 100644 index ffbd218fa8..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontJapanese.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f93a94cc9ca69583b6b60208e3c84454f8291c8367b301d5234725b461816080 -size 100864 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png deleted file mode 100644 index eca50f67d1..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:092e27e97d83615745ed1ae26f2f5e862633e4a3c223b0b34856137d05456575 -size 18061 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png deleted file mode 100644 index 4540a5267e..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75ed59fab9696a07e066ce4fb37700e09d74c1cdd5812a043babe5448534c4f5 -size 18797 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png deleted file mode 100644 index 3a394b29bc..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestDynamicSpriteFontVarious.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c66b33a6f652e04d7d2c9b1cb9cdfd88b3c4641b6de4522c949d4fd62f4b0c3e -size 10151 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png deleted file mode 100644 index d8536f8b37..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e7ac8f22a9c7d1de8f7e9c919eb5a5cccfa4f7dd1e2d549b75b9a2de22c6929c -size 85172 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png deleted file mode 100644 index 2fb16b0519..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2fd028ce437e3da0780ffe330632adccac5a365d62998b572602755e93cc125c -size 82306 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.png deleted file mode 100644 index 52de8bb238..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestGeometricPrimitives.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c45922bf3976c87ae5e17a5cc2c12318dd292374f21ef735e0c3acddeb0626fa -size 88288 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png deleted file mode 100644 index f7386cedee..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageEffect.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4315cc16a8580bba0e90331392601c11cf6d556247c0b9c07a640fa03c446c3 -size 437116 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png deleted file mode 100644 index ed6121de5b..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestImageLoad.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0cdee621ce660f8d47f6296b65c5ff81a3aa304189515c259d1d8d308cdf25c2 -size 140707 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png deleted file mode 100644 index a087a2c6ee..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestLightShafts.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d40cfdb69ef7ae194635940c4c05822bc144edf0401d4c42da39fe2ed986b66e -size 120613 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png deleted file mode 100644 index fc2da95fe5..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dbfe3a50eb5727f069056e81037e33c4f2c68c445d17230d45aa71f2eaaadb68 -size 25572 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png deleted file mode 100644 index c4dc3cd8ef..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:18581a89cfe2bb56b55a42faab12bc89c26043cb60a6b51c2031a33cabb7eb98 -size 31044 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png deleted file mode 100644 index a878cee0f7..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestPrecompiledSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73d23c270d0a53681997832eafd973c8015d5aa7cc3db7e6b27c892a06a3fe12 -size 24965 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestRenderToTexture.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestRenderToTexture.png deleted file mode 100644 index a8ef57208b..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestRenderToTexture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5ce2b4ec89468a8d64c92bf254e93016db63a4777253e2989e7ded41db13e440 -size 56695 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png deleted file mode 100644 index 42733aa510..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d6e59633bb5ee32b8566c37db36756d507851871d3adfd30688b850cf415ebc3 -size 129061 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.png deleted file mode 100644 index bce796ef83..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1c38ff3685f3b609e77d2f0a0d7f9524df2bb9229f42210567c687caa6430a92 -size 130802 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png deleted file mode 100644 index f37e87404d..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:858cf04a6536ece5919c28b7eac62b4fb4393d381f709122f0aca2159312631f -size 38284 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png deleted file mode 100644 index 9cfbabc050..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatch3D.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4115a649f943acb3fc8745b29fc376adb8d3e29256bfcfe791c7bf109e9a5462 -size 34162 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png deleted file mode 100644 index c8809d75d3..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:320befe65bcdba3bf3db2ca1167aefc2fcd2fae8af5f4cf42d4740d2c056e4e1 -size 20433 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png deleted file mode 100644 index e99b9c0ed6..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b0ae9f8817078e1d15d55efb18b72abfc95e662bae82a290a8f1449e85bc8fb4 -size 80876 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png deleted file mode 100644 index 2b2ab09fbd..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:320d430eba1b5521f9c944ac0ee98f9ec88574c57a896513b6e9cc56075e2164 -size 20697 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png deleted file mode 100644 index 055befbd0f..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchResolution.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a87943f79a7eb95b66ab3a22b14413ba93f86168ac3e72223a499b2cab5593b -size 34997 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchToTexture.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchToTexture.png deleted file mode 100644 index a225496640..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteBatchToTexture.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8bd6da663a48f7d2feaceb380e8b46e8f75d7f17d2500910bc50aeba438de535 -size 53542 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteFontAlignment.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteFontAlignment.png deleted file mode 100644 index 89b9c23933..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestSpriteFontAlignment.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d126ef86b9b1fec1c557b38e5188888cce59f9db5286bd9f1cdb07c33b9789ef -size 23002 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png deleted file mode 100644 index 60bd710a45..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:afc288161291c67f074757ebc8a153d9c27ef3922d10ba65add15be68a146768 -size 60468 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png deleted file mode 100644 index cf9f09c361..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:25176f7a396b3c7884b38630ae87b85fa85cc534505a062fb96b5aa8144f6e17 -size 65308 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.png deleted file mode 100644 index c3026fbeaf..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestStaticSpriteFont.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:30d949221b6e96c315767a7bd551283ad06d76d905c59373fbc6d5bf60dd6813 -size 59396 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png deleted file mode 100644 index 1525c56bd4..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Dds).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9c3e92d54674e58ecb07107077664555ac351f470e441e14ad63fed33c3fe98 -size 76548 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png deleted file mode 100644 index 8e2f85b0ef..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Png).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac5e46614aa9b1b1a7719e408b45ce1dfca045db3739c69547bb122b3d2f7441 -size 107711 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png deleted file mode 100644 index 1525c56bd4..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTexture.TestLoadDraw(Stride).png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e9c3e92d54674e58ecb07107077664555ac351f470e441e14ad63fed33c3fe98 -size 76548 diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTextureSampling.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTextureSampling.png deleted file mode 100644 index cf72341023..0000000000 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/SwiftShader/TestTextureSampling.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:93e269824097bec12802f1f7dc71edb1ace156facb94723486aa97e76330b96d -size 41620 diff --git a/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestMaterials.png b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestMaterials.png new file mode 100644 index 0000000000..2c02e5f085 --- /dev/null +++ b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestMaterials.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2fc9e2e1173ebd57f7240c53d16f74f5f614cee3b99f2f01ece99261a5c4bb0 +size 148947 diff --git a/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestRibbons.png b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestRibbons.png new file mode 100644 index 0000000000..064cb1fc11 --- /dev/null +++ b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestRibbons.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40b69e485702a02b4dbd89a76041d640a779322a5dbf1cb9624f90aeb3315796 +size 118841 diff --git a/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestSoftEdge.png b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestSoftEdge.png new file mode 100644 index 0000000000..be5898ac8d --- /dev/null +++ b/tests/Stride.Particles.Tests/Linux.Vulkan/Lavapipe/VisualTestSoftEdge.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2106f33ab04e857a98a08000a05f0c2755420bee3a31945ef518cbc77a44cf69 +size 11174 diff --git a/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestMaterials.png b/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestMaterials.png deleted file mode 100644 index a61fdcefe1..0000000000 --- a/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestMaterials.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bbfab6a39367ec9e60a5283b4ab370ac70c26f2cb88d181cd9f11ee04f4208dc -size 148674 diff --git a/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestRibbons.png b/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestRibbons.png deleted file mode 100644 index e4ede0c228..0000000000 --- a/tests/Stride.Particles.Tests/Linux.Vulkan/SwiftShader/VisualTestRibbons.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3dea2914b37c65c6706fdfa61208b2d29bc4c5d6836120dbb026c033bf2f11c -size 118597 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f2.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f2.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f2.png diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f3.png new file mode 100644 index 0000000000..a57ac36376 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ComplexLayoutTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef8c687467ba87c6993474a747b67964b3381a21f70a33166ee3074243b7d63a +size 7776 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f1.png new file mode 100644 index 0000000000..0e8160aa6f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1070ccff6d8a684e1c7ec5ea6f7c7a4891bc5da59e8a3221b8532fa49e57c299 +size 3255 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f2.png new file mode 100644 index 0000000000..78408bc050 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fce7b73422e9099389513d9e6e72cef749b0e24117fa4ee9fe90a7bcb7bd45e2 +size 3255 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png new file mode 100644 index 0000000000..6f1a1660e9 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9e27ef3291cc39e7fa5d57583392b9382e4933468383e4da056ef8c0f662815 +size 4588 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f4.png new file mode 100644 index 0000000000..69b9320b98 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3799de46bd2863ec74b723590520b96574d5773aecc8aab8773bb9fce58bacf0 +size 3035 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f5.png new file mode 100644 index 0000000000..646518c42f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb47923c601928419140be444e12cbb8ebb0cf8028ba16a9c1cd09e4e9166216 +size 3407 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.png new file mode 100644 index 0000000000..70c007516b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ad977eb8dde81a95c699f9e9c8efdda898fb21282a7f3f402355b3026163cf9 +size 2768 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.f1.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.f1.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.f1.png diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.f2.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.f2.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.f2.png diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerAnchorTest.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerAnchorTest.png diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerTest.f9.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f9.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/ScrollViewerTest.f9.png diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png new file mode 100644 index 0000000000..e22691cf28 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:788ea02837af27753058a13108a0e396bf5a5702d2060dca01ce569a03e4105d +size 3583 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png new file mode 100644 index 0000000000..2b30daa253 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:10f88615dee963b893b215202a1ebf895144f2f082abc53d12cf1b7d28c54c27 +size 3684 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f11.png new file mode 100644 index 0000000000..353b7f2fdf --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3aa0f63439b428c3b3fd731c126343369a02b6959bd1d1734894468abd3c7080 +size 5549 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f12.png new file mode 100644 index 0000000000..19e31df7da --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f12.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4e21c6bee34f827eb1c1dfb0336d3c9327e56158942f4d9d35a145f4a69ca33 +size 2962 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f13.png new file mode 100644 index 0000000000..37cb931cb2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f13.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e775fc2ebbe1d7f50dee830079bcfbf4b4c75d62e5a01b86eb8d1848a99bc2df +size 5511 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f14.png new file mode 100644 index 0000000000..911cc9ccfa --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f14.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bc09259bbc0beb7b35b613316d0115e338c7608900833c60a8ad47a48ae2238e +size 2962 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png new file mode 100644 index 0000000000..babe4fa061 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1da2fb3ccf2a0d966c1cd44c8d8a1b0cd4949938ce9cc249f7e7e1c63095547 +size 3557 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png new file mode 100644 index 0000000000..ba92777edd --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0be87a0baef0fb090c772177720d53f433e01628158633ef632d1d475a9086f +size 3603 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png new file mode 100644 index 0000000000..3e295b2d3c --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89de931eca1a6d7bfb980f9a3ddcd7b1d780028de4bd5c8a2c668a768562d84f +size 3603 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png new file mode 100644 index 0000000000..a68d91d263 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa264a5b909171c17ff533dca306ae6e9182d8c8b4a2828143e831588ac2fc9e +size 3609 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png new file mode 100644 index 0000000000..2cd4661cb8 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcf163d453ac7f9135deae173704a4e604fd5a2f2b9fe13f98ea4ad58304eea1 +size 3654 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png new file mode 100644 index 0000000000..53eb5b3d90 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c2f0c011fcf8d5aa69005a05839839da6482dc5faf1c203ce4989e2e638599c9 +size 3638 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png new file mode 100644 index 0000000000..4b0ee1f20c --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fff10a1f5e3d65e59853bcd28b01e37a1f6a8373ff1428058bc658bd60af33d7 +size 3680 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png new file mode 100644 index 0000000000..761772b03b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61c0c55410a41fc1579ba6f2bece7a63783e8cbc07c1d5a8baa220daa83e6217 +size 3673 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png new file mode 100644 index 0000000000..46b08e89d1 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:667f64654cbe5f8a97a2c74e78825cab30d5ef601f1e73bba5c822172b7acde7 +size 3595 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png new file mode 100644 index 0000000000..9f53ebc244 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afab9e1ebb6e0c8c1572d3dc892e25be2e31201e8c947a8e7f8ebfed2a99b57a +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png new file mode 100644 index 0000000000..29cf62bc6a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f9bf458d12f3721f7d599e5877eb90dc50c32d95e2dbd0a5ecbc3946afa422a +size 6213 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png new file mode 100644 index 0000000000..330283182f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee2c28f84ab4a11260b6ec92d1ccda2b28db1b9ac90a255c5ea07915dc9f5c6 +size 6232 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png new file mode 100644 index 0000000000..9f53ebc244 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afab9e1ebb6e0c8c1572d3dc892e25be2e31201e8c947a8e7f8ebfed2a99b57a +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png new file mode 100644 index 0000000000..9f53ebc244 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afab9e1ebb6e0c8c1572d3dc892e25be2e31201e8c947a8e7f8ebfed2a99b57a +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png new file mode 100644 index 0000000000..9f53ebc244 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afab9e1ebb6e0c8c1572d3dc892e25be2e31201e8c947a8e7f8ebfed2a99b57a +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png new file mode 100644 index 0000000000..9f53ebc244 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:afab9e1ebb6e0c8c1572d3dc892e25be2e31201e8c947a8e7f8ebfed2a99b57a +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png new file mode 100644 index 0000000000..e128bbe497 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a906caf1f4877c8f1cdc75c7208dd4b1f084017cbbe0c6e22cf5c7da0e6bbf1 +size 6213 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png new file mode 100644 index 0000000000..b12d667889 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acce25bffeef49bfb8891fac2ce5b3cd37527dbf7c20626b9512670679e14513 +size 6212 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.png new file mode 100644 index 0000000000..326319c488 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockWrappingTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d7937965a21b4ee9a70d836e35074cbcddaf41bf80374699cff0bf72b47b2df +size 5476 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TransparencyTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TransparencyTest.f1.png new file mode 100644 index 0000000000..624d6250f6 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TransparencyTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfc08800cd192d9eb75ab67961181b2b41c7afb7e64fe0d3007988b008235ddc +size 16641 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BillboardModeTests.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BillboardModeTests.png deleted file mode 100644 index 1f69f08622..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BillboardModeTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d27775dadab1baaa2f2b14599ef17976734704b5e5313ad2c621057fff40aa30 -size 18219 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f1.png deleted file mode 100644 index 38f0f56687..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0e460e021131525bdbeefd2934b5427ef306eb08606ab898950f0df0ed2cb86 -size 15038 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f2.png deleted file mode 100644 index f9945d7fe3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90001f4113e2e51b4f126a10c079f9a9049cb1ae0ddbbe16f3741bac45a28aa7 -size 8986 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.png deleted file mode 100644 index 68a21c432d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/BorderTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7238836058f9c55c98361ffe13df0ca598fdb248ec2d363c5fc4e124b61791a3 -size 8113 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/CanvasGridTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/CanvasGridTest.png deleted file mode 100644 index d61a26b6ac..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/CanvasGridTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c88e7dabdd5d8423d4ecf67ead9a08f813ade1a20eb31e2a54f2a353de1e81ac -size 61304 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f1.png deleted file mode 100644 index 566ce695a8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ebddadc92e9838b1926acca53d8e7bb22807687973ce97f36e2faecddcef1e1 -size 200066 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f10.png deleted file mode 100644 index 9b468ae5bc..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bbc1a3bbced8d8d845de5260dc892da823d6f107a84e7c74dfd45f841fc92c02 -size 194077 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f11.png deleted file mode 100644 index 888aaf2599..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6aa9d7cb9892a69bacab907a3c54d11803305ca208acb6127a2e28fbc60f3be9 -size 193684 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f12.png deleted file mode 100644 index b5325722c3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c17af850b686d885fc4cf0935e461f06dde20541c0a0b4321fc370c1d2cf77cf -size 194557 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f2.png deleted file mode 100644 index 22dc29bbf4..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:883b8d3875a1fef9403028a96382e48c91afef60416cd3c75ea8dfd188802a88 -size 166234 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f3.png deleted file mode 100644 index c91acb2f1d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28f2fc98a09a1abe9b6c8f6a94114c69562cda4bdd54583dcf66740a5854724d -size 206964 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f4.png deleted file mode 100644 index 566ce695a8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ebddadc92e9838b1926acca53d8e7bb22807687973ce97f36e2faecddcef1e1 -size 200066 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f5.png deleted file mode 100644 index 82c822fc45..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e2b02476e17ff0b129a597634ceb8ba328090f522781dc4fc7cd7452c866d5e -size 205512 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f6.png deleted file mode 100644 index 6ceb69ab3a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af01167c28fab272f9a0f7084e97b180c819bf13ec284cf595782470a79e1508 -size 189452 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f7.png deleted file mode 100644 index 6ceb69ab3a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af01167c28fab272f9a0f7084e97b180c819bf13ec284cf595782470a79e1508 -size 189452 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f8.png deleted file mode 100644 index 43cb471824..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43957567713d82ff61af2747e5184f5f8be4b068df993d4486e5c7bb4483aab8 -size 192340 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f9.png deleted file mode 100644 index 98c9596175..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95aeec86c4ffddfd7999347016ced4b68545ac675734357ae9a78f301a4075dd -size 187330 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.png deleted file mode 100644 index 2d515f9691..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ClippingTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d59af896aa8536719645ec058746648c92fc378439d934dff8d3f49d13c6399 -size 156959 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f1.png deleted file mode 100644 index 79112e296f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:059f081557fd0981ad11f68353b71a797b58a5a773c7bdcbe042bea2fde1c24e -size 38804 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f4.png deleted file mode 100644 index 89dfe7191f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:607cb6f47556c1cd2bf4ad6a86fed794c9e5913594bb018b3df076bdd4f677d7 -size 42236 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f5.png deleted file mode 100644 index 84e16d6e3d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b2f23fbf355fdb379ad14a3c1eb2f80190811b705bbce42d3a1102ef91ff174 -size 38837 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f6.png deleted file mode 100644 index b00855651f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccddfec95047e0f5003d178d490718328ac3185b480e112030decf07a81b33d7 -size 38477 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f7.png deleted file mode 100644 index 89dfe7191f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:607cb6f47556c1cd2bf4ad6a86fed794c9e5913594bb018b3df076bdd4f677d7 -size 42236 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.png deleted file mode 100644 index 6503d4f9db..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ComplexLayoutTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:481af769a30e8bb4791e9af5cd7cf2f8c77c03df60c1022fa6701bea6b949506 -size 41710 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png deleted file mode 100644 index 84cc99b3b3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3f881445abe8c8d3533b3fcf54056aa4afb793b3b90332d17bcebf191af4599 -size 4027 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png deleted file mode 100644 index 181b578482..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:118a71ccb255309a2520e65b797e66260e88a58bbcf0149092632ba889297967 -size 4098 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png deleted file mode 100644 index 192df3ab88..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:50d975752ec0a8c9b4c2426b83402d6878a95be15a799f82300bd29a9ebc5167 -size 6923 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png deleted file mode 100644 index dae7dd64c6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:553976191265286f5a71bfe61866a64e6d5f1f0afed8041613db525daf966a6b -size 3980 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png deleted file mode 100644 index 0264c56424..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c641b164872d6fdd56bfd0f36969cc881f237ac63d1223044c58b26502e9245e -size 4223 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png deleted file mode 100644 index 6d6ca6e816..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/DynamicFontTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9492c12cdd73902786481b91041d25409125aedd9a09cbdd82d0163736a7e9c7 -size 3165 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f1.png deleted file mode 100644 index eae56f110b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c6a01316c77db49248cd683afbecfb8eefcbb1c708e9d56be2d53ccb99f62ca -size 16821 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f2.png deleted file mode 100644 index f22c9ae0d8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:48a53c8be53797731cacbda26e7c5525b76cdea7c0ad86a468c11384e79aeed1 -size 8373 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f3.png deleted file mode 100644 index 101b7fb624..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:155e1601c814fb56bba07a827edfd0124d5ddcc5a7acc631482585d3129c8f65 -size 10331 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f4.png deleted file mode 100644 index 3cabcc6462..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ace5fcabeb18fbfedcdd500204b540be97ad6c933d39c0b04544e5cc175bf54c -size 10564 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.png deleted file mode 100644 index f9cbeafe73..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ImageTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56e46e02491f554417f7461679988b546f6763318c813a39211e90a6e2f4d47e -size 20994 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f1.png deleted file mode 100644 index 8fd4aceb6e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:10397fda9135fbe33c5d56cdd18426081e6a9a7ab78823ccd5b9c3d054e4373b -size 381545 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f2.png deleted file mode 100644 index d3ea66821a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e484c3a9b317453759aef1c17532ab0f94607b9e0f23861f6372811d37ee9b39 -size 447918 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f3.png deleted file mode 100644 index d1e11611c3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:00ac17bf96fa56e6d799aead86b06b85ada15ce9e7db3a3f65ab57293c05a24c -size 446761 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f4.png deleted file mode 100644 index 32f56b7acc..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a8d155cf71ede37f17aa2b14f45ef113c2c7cfea894b69db7a36f7987bdd0ec4 -size 499756 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.png deleted file mode 100644 index c26e0f1dd0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ModalElementTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e2fdc28dd6d889962355004b3f0bc28231bcf364764524f8213c0ae6a0469174 -size 382337 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f11.png deleted file mode 100644 index f24605182e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7aa8fbade1e465fcabc6a520d24338f205ca1cf1212a059723f8481cc580f68 -size 16975 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f13.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f13.png deleted file mode 100644 index 3295955054..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f13.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e2e6b3f24ebca48d4c4fb69edcf29c95d19eaa902e324d64fafde9a202001ac -size 16206 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f15.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f15.png deleted file mode 100644 index c75c352eed..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f15.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7ae444dedea991784566e9441292050d399edfab1fde2091dc76028280d12462 -size 20230 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f3.png deleted file mode 100644 index fb0b77635b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5f37157ce47a43db4b12abd06b5d3662aa0500b17ee450dc718abfcb174afb14 -size 368629 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f5.png deleted file mode 100644 index 1fcfc3e72b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61fce0cf4d17f6254b98aa70c580ae19483779b8335161ebc421df3f20bf3771 -size 106179 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f6.png deleted file mode 100644 index 71a252c5b9..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:843fc3458d692562e38eaf67c405fae0c6dc784091ea821045ffc81ae55b768c -size 435902 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f7.png deleted file mode 100644 index cdfca08c24..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/ScrollViewerTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:967b0b43bbbf22b0db7185679b9a10b9d924ae89b724aa2d48e75097aeb8471b -size 180256 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f10.png deleted file mode 100644 index 307d1adfe1..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/SliderTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b0c4eef969c8a8561a54d704b8321d6194b09900886a21a1c7e06d61f214cf4f -size 7281 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png deleted file mode 100644 index 3e97f38b50..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:577c0bd61c024db0613fd83947d1f8d6d5a27408c92fdac3545b34d0314fd4fc -size 5355 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png deleted file mode 100644 index 094cc8c98f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:574531ba486693db9986f7dc47878c1902a4bddb5c388d09d777de626bf73fae -size 5455 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png deleted file mode 100644 index 22140adf00..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a67521fe9222e2e7d35dfe04b83bf9a01ab74699f7c3b7449cd655ed32b6d1a9 -size 8307 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png deleted file mode 100644 index 91854e8d30..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2a4550a7c43a9d557fccd1e52711dde5280540e763161c9170cc410a344aebd3 -size 3637 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png deleted file mode 100644 index c24e734f41..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f13.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:027f4e2fca2d6771090168b795f8b86b28df210063a80207357fbf0ef9975262 -size 7963 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png deleted file mode 100644 index 3510536b08..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f14.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5c86b6f27533be773396bc858780b37617b22293a0e7c63984d5b66bd443f8d4 -size 3640 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png deleted file mode 100644 index 1afac80daa..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:94af79354cde36f52647b5eba57ae6ad4845eed2d50d861cd2c874a1e9bb8a95 -size 5296 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png deleted file mode 100644 index 818f757882..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cdff10b00e080b78504ba2f5da612a5d24704ad916d84e9fc397e4ec647696fa -size 5379 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png deleted file mode 100644 index b121db208b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d4bf96dd0da227b95d7f7b00d7eae32d96d6decc540fdb819394c6a2d5350801 -size 5379 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png deleted file mode 100644 index 41d1c254cb..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0c8a76965949ebd9202cec029c2de4d69722919d313ffc6f415e22f183821f2a -size 5385 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png deleted file mode 100644 index 1e37f62eac..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a2bc4ffae2dc84b4c9b5481a66d200cabe107532f809ce1c95bd43b4800432dd -size 5427 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png deleted file mode 100644 index b565bcc783..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:458dd91ce0131a5e29559588ca1bae96979527e360ca44cccff0a0d78a3aaf48 -size 5406 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png deleted file mode 100644 index 50ab631529..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:78a45c5874ffb1b3493ff50b02ff9f6d9c96346d43cfc0f87e36d12cd501faa1 -size 5451 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png deleted file mode 100644 index 2a96760733..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:22e7fabda82eadfdb9536951572853fabbca191a5298f069bf75ca19a92ae63f -size 5446 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png deleted file mode 100644 index 190c3cc6db..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8f33a162a348a629fd3c435a1d701bacebc6fe3956fd6350645737fca5568fe3 -size 5372 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png deleted file mode 100644 index adafa94526..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png deleted file mode 100644 index 70b3ff2879..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cef39ecbe7030a44cb7322d1e24c41919024dc7bd1f37b775333e0689069e360 -size 9890 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png deleted file mode 100644 index 5dc7545f0e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de6562593cf7497d8163a4cb349d9e8d521d18e0159b42bcf879de444989ebf6 -size 9902 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png deleted file mode 100644 index adafa94526..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png deleted file mode 100644 index adafa94526..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png deleted file mode 100644 index adafa94526..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png deleted file mode 100644 index adafa94526..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:24f2c0747dc94a94191c946bb23f12ce808914667020e716b6b6723c84ab4ebc -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png deleted file mode 100644 index a913a9816b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9f9f25a409bfa9fb6280251e04efc71586ca9de68124b01971a0c82bd8c6e876 -size 9895 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png deleted file mode 100644 index e764bc7605..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9607a953a09c7e54c92885551e02b22a2c83d349b137ccba7c35f71185716edc -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png deleted file mode 100644 index 9c74063882..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TextBlockWrappingTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3355dca71ecdad22a6c4529d2f7359981647ed0a24fba8fb3e90421f0846f675 -size 8366 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f2.png deleted file mode 100644 index 54bcc37279..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4635ed09715a2790fc8745fbc992df729515682fde9e1c8b0177cd7deeffb6d -size 43480 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f3.png deleted file mode 100644 index 791e15b406..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65e3c2383c6e70146184c6dbf1003d2bb4ad75d3f63df01f303ee4755da9fc90 -size 44478 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.png deleted file mode 100644 index 4be23f004b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/TransparencyTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:846555da06378cee709563c3a3c764c91661f339d93140706abf59cb76eb9e64 -size 26536 diff --git a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/UniformGridTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/UniformGridTest.png deleted file mode 100644 index fe222b16c1..0000000000 --- a/tests/Stride.UI.Tests.Regression/Linux.Vulkan/SwiftShader/UniformGridTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:657cafbb822b78211d98a89eb3512f872ad44cd23c4498ed561a4eee4da73c9d -size 24410 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BillboardModeTests.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BillboardModeTests.png new file mode 100644 index 0000000000..1842f468a2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BillboardModeTests.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9e4da07d387b55d559491e4332522c49db4c6c20aca92d3f7d76d90ffbd8089 +size 18060 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f1.png new file mode 100644 index 0000000000..c48d274a62 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:280ca921a775c954ecc8c704a13c20db4746702472e2c14def03f0e7ce5e0c03 +size 14711 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f2.png new file mode 100644 index 0000000000..33c003b355 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f43542e62db34c1c1064ef25c5fa0d816786c4bfde2151b09a3784a0d99f74fb +size 8074 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.png new file mode 100644 index 0000000000..fe00749ef0 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/BorderTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44dedcaf6c2a65e1e2f416a62894132edd24964edf0ef2e3601b0d6118a55fde +size 7765 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/CanvasGridTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/CanvasGridTest.png new file mode 100644 index 0000000000..d081a19bbf --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/CanvasGridTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c201742c4e20c33cc1aad54bcb9eb522ffff7b0952029fba7bc39ddb0634b135 +size 57109 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f1.png new file mode 100644 index 0000000000..22e21fa8e2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8f481f94f57da45b1eb6a8b6a689f275125bc1034f0526badf80b8c8a9daa81 +size 201975 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f10.png new file mode 100644 index 0000000000..87ffa45fa6 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bda7df2c69415edf055a470b40f3873758ae499f668a32c12a70c3c8ca926135 +size 195416 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f11.png new file mode 100644 index 0000000000..9811f18eea --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93605493db86ff18752086cc4f2ceca142bd79fb4de210c04cb69c3fb169fc81 +size 194752 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f12.png new file mode 100644 index 0000000000..c2f6f6b767 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f12.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a82bc0044454c6f909e7b69c7b3ca087328ce9f04b7c878413023acd64ecec1a +size 195967 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f2.png new file mode 100644 index 0000000000..e2c843f396 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63b49c3110202bb90a1c5b5cff88a002f71788e27420be206de1c43e7a0eb425 +size 167400 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f3.png new file mode 100644 index 0000000000..15528d0b66 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13f1f03ed102b53d0f5c361f3fef4a40a095f452eb768963536f9d9c12e89bf8 +size 208340 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f4.png new file mode 100644 index 0000000000..22e21fa8e2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f8f481f94f57da45b1eb6a8b6a689f275125bc1034f0526badf80b8c8a9daa81 +size 201975 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f5.png new file mode 100644 index 0000000000..c2547db144 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb43a71c4bcedacd1fa305bf2d9aaba41823170140305dc2b5622967783d2db6 +size 206911 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f6.png new file mode 100644 index 0000000000..d09cc055bf --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bd194a7bfa1d8bf330378e3d3561bf5bd8a536d196a80cc306375916808f6bf +size 191127 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f7.png new file mode 100644 index 0000000000..d09cc055bf --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bd194a7bfa1d8bf330378e3d3561bf5bd8a536d196a80cc306375916808f6bf +size 191127 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f8.png new file mode 100644 index 0000000000..bba63936ee --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c41b1f644281885a86efb7e6fe157bb4210272a3997d6f4269403f0c28720f10 +size 193950 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f9.png new file mode 100644 index 0000000000..34195bb1d2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.f9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1356c0f4a7e3a70f52c610233d6568b642d95d4c15b1d0eb082bb91fe5bc05b +size 188288 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.png new file mode 100644 index 0000000000..cb54ee2cf9 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ClippingTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d997279314e6e2b63a01e1fdcfc87bb3ffc3c1e72120952ed91c1a1859ed9bf +size 157704 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f1.png new file mode 100644 index 0000000000..8eea36a04a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef2b712eafbcabd7acab96037c12c3fb39e9e936edf1a8a3324f703b9980e4f8 +size 38527 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f4.png new file mode 100644 index 0000000000..a1ac06ed1b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1396716010c4315405d27c06685df1cb74f63c566f67a4bff67c8b758ff29887 +size 41895 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f5.png new file mode 100644 index 0000000000..7d78b0e4b2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b29e8f26b14fb9d78b7320676b4b8aea4d1dd729e15e78fa0a5cf605943640d +size 38467 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f6.png new file mode 100644 index 0000000000..6c3c889774 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8a5a224cd3410227ca39181510442c868d7142b435ba238bff927af79b45c0b +size 37807 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f7.png new file mode 100644 index 0000000000..a1ac06ed1b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1396716010c4315405d27c06685df1cb74f63c566f67a4bff67c8b758ff29887 +size 41895 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.png new file mode 100644 index 0000000000..6f4fa4188b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ComplexLayoutTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73b3022212d0c3965b263701328f51a5724933398391500d51d69a05f0e28b6e +size 41235 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ContentDecoratorTest.f2.png new file mode 100644 index 0000000000..2d9e90c188 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ContentDecoratorTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71548aa044f2d488e0e8b0cfa5474a32b971a1b6bbb82e0309626ef4deb869d8 +size 3151 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f1.png new file mode 100644 index 0000000000..b725f9e371 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50de577554ea1687c2133eab561ea8a7891072cc9d0dc827b5f444af493a69c0 +size 3247 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f2.png new file mode 100644 index 0000000000..b725f9e371 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50de577554ea1687c2133eab561ea8a7891072cc9d0dc827b5f444af493a69c0 +size 3247 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f4.png new file mode 100644 index 0000000000..49f823b0bb --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f11afd223408bae50d33b2bdc857bbda8a63884853a51ee455e1c5a8d81bed60 +size 3034 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f5.png new file mode 100644 index 0000000000..acc12912b2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bf51c5e80406722e238a81684f6c48f473a44664bca3c6c7dde9f36e4220aa2c +size 3413 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.png new file mode 100644 index 0000000000..cb32aa9f67 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ef21cddb0b428e2f818bd96abecdfc1bc98de1f9d22fdbfec4183060bef8932d +size 2762 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f10.png new file mode 100644 index 0000000000..1462bb3a06 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6e5122d66b5ea7a6450eac3735244efe559afadaa8ec0f09f42570af941a7e6 +size 7615 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f11.png new file mode 100644 index 0000000000..f9027319c5 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e0e5868167dfae67524ea2c31d679da793493a66e0e8c75f0060e8a0649f2c57 +size 7627 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f12.png new file mode 100644 index 0000000000..916b8406a2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f12.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca1fd870dd39b9586212b860277e3afc8c1b6b76040bcf71f6b2a4602cd7ff57 +size 7611 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f13.png new file mode 100644 index 0000000000..caf18071bd --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f13.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdd91d04201b3ebd2c27a49b3646849f5c9876b17158b3930c605450f6dd1672 +size 7691 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f14.png new file mode 100644 index 0000000000..060f3692f8 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f14.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c24cf35bc938afdb3deb423fa40536444937fd4c4d3181b9a1e2a668f955c54 +size 7692 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f2.png new file mode 100644 index 0000000000..4843694b82 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a39e775a35741ea3560e792b4e0976bbf1cb2b0e0561ecb51a5c1e56eff8f8c1 +size 7143 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f3.png new file mode 100644 index 0000000000..b08004f050 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d3cdc9ed7aeb8601b7e9fcf1b3f2f160e787700b7dfead0c68783a2aae46a38 +size 7136 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f5.png new file mode 100644 index 0000000000..01dbd1a946 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8a68915b51684feafa6154ad4e4fc788f28f66e99f3b30576841aad88bf6d952 +size 7225 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f6.png new file mode 100644 index 0000000000..a58c434f7f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e9a90490fdc9eb1d00697812f32acd8ff3d7420b001c0f153d27c330c5d42e3 +size 7216 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f7.png new file mode 100644 index 0000000000..00b5c74206 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4f5bc6e81dfa9233e1206349726d3a323ff5edf2b2754859d322f427d77359f +size 5675 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f8.png new file mode 100644 index 0000000000..74b867c858 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.f8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ecf3ed6eb7f3ce07ea85bacfb419deca2c14b47f33f760293cf641fa079254a +size 7598 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.png new file mode 100644 index 0000000000..a604752564 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/EditTextTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5468600a7afb80a12eca82222f404bd644e7745ca2a2f4f8686e21d9ca567c79 +size 6998 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f1.png new file mode 100644 index 0000000000..d39ebf1f1c --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2723b39e0f3f2363d74cf6a8bebc84b782f2cb3d043a28fb4633d39a0a936076 +size 9427 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f2.png new file mode 100644 index 0000000000..da6c9fdb66 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ceec682f104e729a2cf7455571f10d59e3c8051fc4b6a4c4d7687f39ca91389 +size 11549 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f3.png new file mode 100644 index 0000000000..2a924c564f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:543611414973e98d0cbaba0092b1a4b1f20dc9c401766d60ad8d9431385ff8ea +size 9605 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f4.png new file mode 100644 index 0000000000..6b26b2a17a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5e50c538035369201f27f89c85c19088e2238f8812bd4f246eb539c20578146 +size 9986 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.png new file mode 100644 index 0000000000..64ebdedaac --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRegionTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47e378068c780af351b760acecdb6e1ae6c4ebb38bdcfcaafda180e8bfe10aa2 +size 36398 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRotatedTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRotatedTest.png new file mode 100644 index 0000000000..946a6e85a2 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageRotatedTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb9c929822326ab111dd4d9a762fb86685169e1e368002cb761b764496644fcd +size 389074 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f1.png new file mode 100644 index 0000000000..5e042f5971 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:743ec58965acded4143688b933007733e5eab18022ef796a5238454b3888033a +size 16636 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f2.png new file mode 100644 index 0000000000..a2584f170a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a89c2fe0b98e700550762dc1061ce54d20231cb4b241c1b36d2b7fd543ae6e9f +size 8391 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f3.png new file mode 100644 index 0000000000..af694224a0 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b74dbf92a9f85632a16a179c17ce5718cd5de3a09b0415296ae324ee8f195523 +size 10277 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f4.png new file mode 100644 index 0000000000..44950573d5 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c24b104f2c0d2a7df71223e1fd0748626bffc433c53e1f6929f4bc46c79fa791 +size 10516 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.png new file mode 100644 index 0000000000..a5370b876b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ImageTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b7ce0072cfdefc90c0592254ca7b163c96a28d1cbe43f3045e731cc804e15942 +size 20976 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f1.png new file mode 100644 index 0000000000..91bf40944a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d40a4bb956925dbc96b56c9e555b0d870c78f6b9eec83ce9294d3711f148cc9 +size 382093 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f2.png new file mode 100644 index 0000000000..0659f79fee --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99434cdad512de083b8d0e6f1a5714ca7c031d7acbd991915522cdc7d2196365 +size 452189 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f3.png new file mode 100644 index 0000000000..42d583d78f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d70a907cdad00fc9668f2d66fb705d350df39925ec469c8208873cdf4f2a58 +size 451097 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f4.png new file mode 100644 index 0000000000..fbcfe0fddc --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a469b36f22fff0190da1bc71a4320b339280d3f1e4c88d62496bf53fe44ee55b +size 509021 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.png new file mode 100644 index 0000000000..18d425f412 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ModalElementTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33f3e936d43997fff8b2905028b29c24d22d3f19d23ef86933c59091777c6f3d +size 382962 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f10.png new file mode 100644 index 0000000000..17b7d96e7e --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1178609703a5549e4f95ba7e134227ab3c31a0e274fb6661890d469f6a724af4 +size 16031 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f11.png new file mode 100644 index 0000000000..9499459881 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18a3253e3a0736df525893cb8c587f17cdc3fa23978428730234da946c5b467a +size 16585 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f12.png new file mode 100644 index 0000000000..ece56b8250 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f12.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dcc72297352639d7c4a1ae0bfcdd3481e6c03c6a96aa3d632857727fdf71c64 +size 16019 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f13.png new file mode 100644 index 0000000000..3999ffbe0b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f13.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32d0e82c6e00a91a1a3cf66d97025868da0ba91da20c0f43d34ab315707a03a8 +size 16061 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f14.png new file mode 100644 index 0000000000..f9113d4a64 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f14.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ccedcf748bf90e5efc2987583369190bdca56b365a8006dc5d25845e0a14313 +size 17848 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f15.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f15.png new file mode 100644 index 0000000000..8f21a2d39a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f15.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fcbfe2b1ebd35ce8baa0d5664b1f957157f4716e8ce316146a7b2c7c5e717a6 +size 20233 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f3.png new file mode 100644 index 0000000000..61976cb71d --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:accbb466d739021c3bbe2ecd8c6e539221d8e65366f9aa73a5b6c3aba06df920 +size 378733 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f5.png new file mode 100644 index 0000000000..79786effd0 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8b0117bfd6b2823e587a610ca8568f4dbc10b6af23a27b1f48d3dc6f81ae56c7 +size 107866 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f6.png new file mode 100644 index 0000000000..b59317e53b --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3cf7a24a423438d67a3cd47029ea711fbb96a0d91fa355e762ffe5ce43b9b6cb +size 442306 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f7.png new file mode 100644 index 0000000000..52b6784df8 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1860fa9a37b1b13b75557bce29b0fe4010f7a15adf6d69b7e8bfc295c879945c +size 181741 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.png new file mode 100644 index 0000000000..904872be35 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/ScrollViewerTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9014891f1819e430ba4cc895f0014d40d7adbe688c8925603c288c520db847a +size 16619 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/SliderTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/SliderTest.f10.png new file mode 100644 index 0000000000..7a16416e1a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/SliderTest.f10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f93e9ed7babddefd77b45b0d77d922c8c486ca7e2f62a2aa3a3c4a825ea0ae20 +size 7282 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f11.png new file mode 100644 index 0000000000..841b000ba9 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f11.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7acb51734b65e4ef5b3603cfb172c8ff8641df50503e0dae26872ec6f9b45f67 +size 5522 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f12.png new file mode 100644 index 0000000000..1a1ba4cf0d --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f12.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b0a043d4307aa840b05ada386e0e3836d59062cc3dadaf18bcad35024bd939b +size 2954 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f13.png new file mode 100644 index 0000000000..841b000ba9 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f13.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7acb51734b65e4ef5b3603cfb172c8ff8641df50503e0dae26872ec6f9b45f67 +size 5522 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f14.png new file mode 100644 index 0000000000..1a1ba4cf0d --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f14.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1b0a043d4307aa840b05ada386e0e3836d59062cc3dadaf18bcad35024bd939b +size 2954 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png new file mode 100644 index 0000000000..343d84946a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60eff100276ed557b68d1961b9dba9ae578169235831f30b6eb7f3d9c9a74b1 +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png new file mode 100644 index 0000000000..effc108411 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85092134a4e4a3a95cac023ee1d5ae2b31e1ed8920ca56e66086605cb8e280e +size 6214 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png new file mode 100644 index 0000000000..2ee7fda680 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f0858c2576954e4122e0654d631ff56904e6f7a27a5c42b08fdc48160e44d00 +size 6233 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png new file mode 100644 index 0000000000..343d84946a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60eff100276ed557b68d1961b9dba9ae578169235831f30b6eb7f3d9c9a74b1 +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png new file mode 100644 index 0000000000..343d84946a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60eff100276ed557b68d1961b9dba9ae578169235831f30b6eb7f3d9c9a74b1 +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png new file mode 100644 index 0000000000..343d84946a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f6.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60eff100276ed557b68d1961b9dba9ae578169235831f30b6eb7f3d9c9a74b1 +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png new file mode 100644 index 0000000000..343d84946a --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f7.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b60eff100276ed557b68d1961b9dba9ae578169235831f30b6eb7f3d9c9a74b1 +size 6217 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png new file mode 100644 index 0000000000..be0664f893 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:212926b8a5434579a13f65bccd6644ede8cf9d62fed2878c2906781f0c396259 +size 6213 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png new file mode 100644 index 0000000000..066557f773 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.f9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0adac8952691182d57460242a02aff0382584d3a38eaa82179d4ed8bf3c40479 +size 6213 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.png new file mode 100644 index 0000000000..f516daea46 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockWrappingTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6eb347ee668a78d2abf77f622726e95be7629eb985be2bf123561632eba351f3 +size 5475 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f2.png new file mode 100644 index 0000000000..421eae33fc --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eaf9d2d91a4107ad59dd8130bf7bddece6b5337a0149074e717d444e5fc7e3ce +size 41085 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f3.png new file mode 100644 index 0000000000..041ca3f31f --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b8d83d487aa17a075b9fdda30bf0d2e58929a160508e946b857237f1dfb9ca09 +size 42023 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.png new file mode 100644 index 0000000000..9d7ac6a967 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TransparencyTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7a7b7ce59339151991269c39a928d5ad11aaf2f89aa48004a7aec759ceddc732 +size 23854 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/UniformGridTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/UniformGridTest.png new file mode 100644 index 0000000000..a978ee4679 --- /dev/null +++ b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/UniformGridTest.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04a19b92eec62087e826cafb48fa023273cd176fb74a7f7bb43ef49d7216b16f +size 23724 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BillboardModeTests.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BillboardModeTests.png deleted file mode 100644 index 1f69f08622..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BillboardModeTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d27775dadab1baaa2f2b14599ef17976734704b5e5313ad2c621057fff40aa30 -size 18219 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f1.png deleted file mode 100644 index 38f0f56687..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0e460e021131525bdbeefd2934b5427ef306eb08606ab898950f0df0ed2cb86 -size 15038 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f2.png deleted file mode 100644 index f9945d7fe3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90001f4113e2e51b4f126a10c079f9a9049cb1ae0ddbbe16f3741bac45a28aa7 -size 8986 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.png deleted file mode 100644 index 68a21c432d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/BorderTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7238836058f9c55c98361ffe13df0ca598fdb248ec2d363c5fc4e124b61791a3 -size 8113 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/CanvasGridTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/CanvasGridTest.png deleted file mode 100644 index d61a26b6ac..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/CanvasGridTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c88e7dabdd5d8423d4ecf67ead9a08f813ade1a20eb31e2a54f2a353de1e81ac -size 61304 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png deleted file mode 100644 index 43bb575b16..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8cb5e7f07920fd993eb1db8c2dff44a5439c57ebb03632d4300308f9e5c9c545 -size 36138 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png deleted file mode 100644 index b8db6a1472..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f9a08617f4acf70b76d3a9fabe6f00f2f1a322e99065f527b351f5411280ea8c -size 36088 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png deleted file mode 100644 index d2759bf941..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1aabfcb969386e07cd0dd809e2f2650f139e767bb87f619369571821c12b5924 -size 37377 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png deleted file mode 100644 index 3d4826c3f0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02bf63222918c69a57852c4b2a57f3927059d76df6c53ae7e94fddd4c7efafd5 -size 32278 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png deleted file mode 100644 index a84b4a94c2..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce018e0b0c9024183ba02b6c88983a9ee6da378d70039fca9352574bd268de40 -size 39422 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png deleted file mode 100644 index 72a80b2398..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb31f17474a381a4abfc412289061c723bf0c63c71b6f48402921be1e249a930 -size 38232 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png deleted file mode 100644 index 996d3191e6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClickTests.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c5d69f07b2d0d27c17def6287e607feb88f7f266636e41b821a354a0d312a505 -size 35979 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f1.png deleted file mode 100644 index 566ce695a8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ebddadc92e9838b1926acca53d8e7bb22807687973ce97f36e2faecddcef1e1 -size 200066 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f10.png deleted file mode 100644 index 9b468ae5bc..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bbc1a3bbced8d8d845de5260dc892da823d6f107a84e7c74dfd45f841fc92c02 -size 194077 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f11.png deleted file mode 100644 index 888aaf2599..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6aa9d7cb9892a69bacab907a3c54d11803305ca208acb6127a2e28fbc60f3be9 -size 193684 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f12.png deleted file mode 100644 index b5325722c3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c17af850b686d885fc4cf0935e461f06dde20541c0a0b4321fc370c1d2cf77cf -size 194557 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f2.png deleted file mode 100644 index 22dc29bbf4..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:883b8d3875a1fef9403028a96382e48c91afef60416cd3c75ea8dfd188802a88 -size 166234 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f3.png deleted file mode 100644 index c91acb2f1d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28f2fc98a09a1abe9b6c8f6a94114c69562cda4bdd54583dcf66740a5854724d -size 206964 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f4.png deleted file mode 100644 index 566ce695a8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6ebddadc92e9838b1926acca53d8e7bb22807687973ce97f36e2faecddcef1e1 -size 200066 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f5.png deleted file mode 100644 index 82c822fc45..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8e2b02476e17ff0b129a597634ceb8ba328090f522781dc4fc7cd7452c866d5e -size 205512 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f6.png deleted file mode 100644 index 6ceb69ab3a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af01167c28fab272f9a0f7084e97b180c819bf13ec284cf595782470a79e1508 -size 189452 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f7.png deleted file mode 100644 index 6ceb69ab3a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af01167c28fab272f9a0f7084e97b180c819bf13ec284cf595782470a79e1508 -size 189452 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f8.png deleted file mode 100644 index 43cb471824..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:43957567713d82ff61af2747e5184f5f8be4b068df993d4486e5c7bb4483aab8 -size 192340 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f9.png deleted file mode 100644 index 98c9596175..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95aeec86c4ffddfd7999347016ced4b68545ac675734357ae9a78f301a4075dd -size 187330 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.png deleted file mode 100644 index 2d515f9691..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ClippingTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d59af896aa8536719645ec058746648c92fc378439d934dff8d3f49d13c6399 -size 156959 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f1.png deleted file mode 100644 index 79112e296f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:059f081557fd0981ad11f68353b71a797b58a5a773c7bdcbe042bea2fde1c24e -size 38804 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f2.png deleted file mode 100644 index c79770822b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7664245f6b0e19b7e2cacb767b44cf8155c88543463a433c5d9fb1837ebdd6a0 -size 31849 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f3.png deleted file mode 100644 index 204df520e5..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90b9be77b2bfd9b579ccf818a9f3ac3a84d2e408b63b60869d18fcad67a7d352 -size 7759 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f4.png deleted file mode 100644 index 89dfe7191f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:607cb6f47556c1cd2bf4ad6a86fed794c9e5913594bb018b3df076bdd4f677d7 -size 42236 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f5.png deleted file mode 100644 index 84e16d6e3d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8b2f23fbf355fdb379ad14a3c1eb2f80190811b705bbce42d3a1102ef91ff174 -size 38837 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f6.png deleted file mode 100644 index b00855651f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccddfec95047e0f5003d178d490718328ac3185b480e112030decf07a81b33d7 -size 38477 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f7.png deleted file mode 100644 index 89dfe7191f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:607cb6f47556c1cd2bf4ad6a86fed794c9e5913594bb018b3df076bdd4f677d7 -size 42236 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.png deleted file mode 100644 index 6503d4f9db..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ComplexLayoutTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:481af769a30e8bb4791e9af5cd7cf2f8c77c03df60c1022fa6701bea6b949506 -size 41710 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png deleted file mode 100644 index e67728e09f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ef833d3a35bd1864eac795e9cefe41105138f9f71259885e62eacedaddbfbce7 -size 3432 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png deleted file mode 100644 index d8b52ec3c2..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:666b97df810f96cf58b19653ade33eeeb918caa496e5f87debbdc0577b912a9a -size 3731 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png deleted file mode 100644 index c2c4e0810e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ContentDecoratorTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3f3721d78f8212d61c4bbe4954221213b1e21e9f1819971db2631e64c113abc5 -size 3058 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png deleted file mode 100644 index b8825b6db4..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20b34c618fed7392fafd7742c891756356095a48a727beae15d50d98e24bf805 -size 4017 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png deleted file mode 100644 index b8825b6db4..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:20b34c618fed7392fafd7742c891756356095a48a727beae15d50d98e24bf805 -size 4017 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png deleted file mode 100644 index 410a3d75d9..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8a37556b07ea144e30d4ec43bc1942da1f041f2cb3d591935934dff6cd9efe86 -size 6887 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png deleted file mode 100644 index c959a8c96b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccd5f14345dd14634d4edc3673c88ec3fa1246d602f78b6a342c750b929c1a2a -size 4024 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png deleted file mode 100644 index 12a6b0e3b2..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0665d97aa62bfc25e442a6efc6d326b404d243978dc26608e7a55caec3fa99ae -size 4099 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png deleted file mode 100644 index e83675a6c4..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/DynamicFontTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:34305feba0ec4fae52b3fba0ac6e5b74ea187b35d6a20505c66fe6beae679e30 -size 3203 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png deleted file mode 100644 index c552952d71..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0339361bb7dbfa7fee8ba722554327fbbd327e41d3a92198cb02d50409631298 -size 7553 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png deleted file mode 100644 index 05a3701728..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:be32fcdb528804acb3a486873d2cabdd28171f96a21068af70be1223a32f4d28 -size 8461 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png deleted file mode 100644 index 0d6ef1f0f6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:065dc953193b989c6fef22e79c98482b79f8d9af3d816f303ac5e23ed1c0ff25 -size 8463 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png deleted file mode 100644 index dbe681f1d0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ac3c9dfd59a874a091235c76fdbd66b17109e5fe3793278ca5b51ba0f5d0e3a -size 8453 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png deleted file mode 100644 index e85b7daf48..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f13.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb488a5ec9a769042aa2a9f83efe3f13c2227557638e2454cea46df8ad903e6a -size 8537 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png deleted file mode 100644 index d050e3379d..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f14.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e76163efb8bf87d49af98f09bcee0c953e51285b4448a95e83b0506ec92633ed -size 8552 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png deleted file mode 100644 index d37c9273a0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4edb69ec532277ce8056ce44f1f6800e728bf1b6fba418b23c566b4134e297e -size 7731 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png deleted file mode 100644 index cca3ceaf8a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:52ddb7a70cac86cbdbfab171de0d332733b72ff9a8844ecbc25bfabe4ae5dab4 -size 7725 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png deleted file mode 100644 index 4615b9a0c0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:301692b58dddcfac3bee52f6a57e65481c20b296b792fbfe6bbd1b4efeb03fb0 -size 7974 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png deleted file mode 100644 index dc95ed93b8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:67539bde2e6455d14aeb98835be42d2fd2af3c003a0eb770dbf69ac7d6a29771 -size 8042 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png deleted file mode 100644 index 0786bfe43e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90d2a27d78dd648e2c387848d79aa289c5ad15232a598a980819bc4302919e6c -size 8052 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png deleted file mode 100644 index 77967ada36..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:243972c80df061fef5d04a50073966b718f3fa9cb00d27815455e0a78c89d987 -size 6489 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png deleted file mode 100644 index 3fe3fc416b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:32908a4dac1d9cd83ea586879b5812dd7eed8cdc6f470f6a043b9042835f24db -size 8462 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png deleted file mode 100644 index 54eb29de34..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f306a923f27ebceeefa29226ce24d81e0c12e6ca63b4f8f8225c3de3fda2cd3e -size 8468 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png deleted file mode 100644 index 6a648bcb55..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/EditTextTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:44643121343000108e1b56beb8a7147dac4af66a23551853c5c4cf6258e17e06 -size 7550 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png deleted file mode 100644 index 5c92293e86..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:669c472bf70fb009aedd44e20e07f2b36bc3c533aea3cdd8d8efae93ffef6eb3 -size 9504 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png deleted file mode 100644 index ebc3598cb8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af7dcdfae006d3737b2b7e3441b9167d2cf2f6359cd79d74f1809441b5765380 -size 11655 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png deleted file mode 100644 index 5a783f0be7..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b8524568f2d72307ff224a3479b4bf4ce1ad1a4929d4087579e29b87d64d133 -size 9703 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png deleted file mode 100644 index 30183bbe88..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1de96b5b6103793ee5b04e308aaaa7d306ba2ddb14f36020d8948079a8fd4d8e -size 10042 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png deleted file mode 100644 index d98671718b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRegionTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83fcfe62fc4bacd5bd6e6196f38a3fbd9b55e365ab9d56ed67514b03c4c22e8b -size 36308 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png deleted file mode 100644 index a0a1af6c14..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageRotatedTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ee5fc13b7e5ba9351176055b7530f56e7870e6f41bf508b33ac6621b943b47d -size 388855 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f1.png deleted file mode 100644 index eae56f110b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c6a01316c77db49248cd683afbecfb8eefcbb1c708e9d56be2d53ccb99f62ca -size 16821 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f2.png deleted file mode 100644 index f22c9ae0d8..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:48a53c8be53797731cacbda26e7c5525b76cdea7c0ad86a468c11384e79aeed1 -size 8373 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f3.png deleted file mode 100644 index 101b7fb624..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:155e1601c814fb56bba07a827edfd0124d5ddcc5a7acc631482585d3129c8f65 -size 10331 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f4.png deleted file mode 100644 index 3cabcc6462..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ace5fcabeb18fbfedcdd500204b540be97ad6c933d39c0b04544e5cc175bf54c -size 10564 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.png deleted file mode 100644 index f9cbeafe73..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ImageTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:56e46e02491f554417f7461679988b546f6763318c813a39211e90a6e2f4d47e -size 20994 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f2.png deleted file mode 100644 index d3ea66821a..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e484c3a9b317453759aef1c17532ab0f94607b9e0f23861f6372811d37ee9b39 -size 447918 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f3.png deleted file mode 100644 index d1e11611c3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:00ac17bf96fa56e6d799aead86b06b85ada15ce9e7db3a3f65ab57293c05a24c -size 446761 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f4.png deleted file mode 100644 index 32f56b7acc..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ModalElementTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a8d155cf71ede37f17aa2b14f45ef113c2c7cfea894b69db7a36f7987bdd0ec4 -size 499756 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f1.png deleted file mode 100644 index b880863eb9..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9aa2869a74b5ffc3493c37a6917d669164f7a842d893383fee654015649ca46d -size 430236 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png deleted file mode 100644 index 372a6df521..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:982dee31eebd541e013eeb7419b68e8aa57da6a6c0328b7e844b407641f911aa -size 16043 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f11.png deleted file mode 100644 index f24605182e..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7aa8fbade1e465fcabc6a520d24338f205ca1cf1212a059723f8481cc580f68 -size 16975 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png deleted file mode 100644 index 968160a212..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c5187ee66519fa61b162567fb2092a7d042b43df94a1291ad4e8ff3560fcdb0 -size 16027 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f13.png deleted file mode 100644 index 3295955054..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f13.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0e2e6b3f24ebca48d4c4fb69edcf29c95d19eaa902e324d64fafde9a202001ac -size 16206 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png deleted file mode 100644 index a4e24e232c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f14.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c974cd3104b4b2ccd4ffc8197b25f26e14852922c29589d5d82fcbb5c7536317 -size 17807 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f15.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f15.png deleted file mode 100644 index c75c352eed..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f15.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7ae444dedea991784566e9441292050d399edfab1fde2091dc76028280d12462 -size 20230 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f2.png deleted file mode 100644 index b83e7f2d84..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e83149a80ec0dca6ebc64cb46893724aedabf0be83036171799a4ded75e372e -size 428960 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f3.png deleted file mode 100644 index fb0b77635b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5f37157ce47a43db4b12abd06b5d3662aa0500b17ee450dc718abfcb174afb14 -size 368629 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f4.png deleted file mode 100644 index c213f457b0..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0946f2fe937c4ebe23fea012e001e78aad19f235d557139b67005205ef70ea5e -size 426058 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f5.png deleted file mode 100644 index 1fcfc3e72b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61fce0cf4d17f6254b98aa70c580ae19483779b8335161ebc421df3f20bf3771 -size 106179 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f6.png deleted file mode 100644 index 71a252c5b9..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:843fc3458d692562e38eaf67c405fae0c6dc784091ea821045ffc81ae55b768c -size 435902 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f7.png deleted file mode 100644 index cdfca08c24..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:967b0b43bbbf22b0db7185679b9a10b9d924ae89b724aa2d48e75097aeb8471b -size 180256 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f8.png deleted file mode 100644 index b83e7f2d84..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2e83149a80ec0dca6ebc64cb46893724aedabf0be83036171799a4ded75e372e -size 428960 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png deleted file mode 100644 index ca0ccb985c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollViewerTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:46b307aed2c00a89bfe478edc02f9992294226ce668b00da004e77ab3fd3d3d1 -size 16630 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png deleted file mode 100644 index 23fb1be543..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff -size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png deleted file mode 100644 index ca8a617607..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:03f22a166e20bd200f8ae58067c3879e612da463749caf6c97cbbcc5af24bb6d -size 2760 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png deleted file mode 100644 index 23fb1be543..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bfc8cb91f62f876014f05abdad73f82fa2ccf74b138de693c0d38d7022545dff -size 2819 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png deleted file mode 100644 index c547da862f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b7cade8d4ac33fb838549cd92049397c4ec61357dacf63a3f333faacfdfb7d5b -size 2413 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png deleted file mode 100644 index 6d946ffb39..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9d9e78c0783d9949fb0313a728701b274d28f6cd18d0c97a79faac685fe63cad -size 2969 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png deleted file mode 100644 index 9357f712ee..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/ScrollingTextTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9abb3d93cc2888794a375c0afa63c4a7c2be25fc6207726714c4ecfe4f850b52 -size 2922 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png deleted file mode 100644 index 4ef6060c15..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:483c651ef70c62fb0ef7fd4001f888b3c1e1c3f0a6ffeb340f041623138a708a -size 11769 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f10.png deleted file mode 100644 index 307d1adfe1..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b0c4eef969c8a8561a54d704b8321d6194b09900886a21a1c7e06d61f214cf4f -size 7281 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png deleted file mode 100644 index 0caf40524c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/SliderTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af786b3b910edf96d6779b7db4d2721b333116c837ae70f32c8897143daaba27 -size 11256 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png deleted file mode 100644 index 8e5e5bdff3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57ed9695175b3af83edb92e764b753cbb040b56fd3c18ad3428d55f411fef490 -size 5249 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png deleted file mode 100644 index 5214d9ef04..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5268b55759ce00309235db4a1e00bf359010603bf1cc70f47a8a73e7a8ed9948 -size 5356 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png deleted file mode 100644 index bf608ec850..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9679cb29860a83d68134af2f04ad3bee0ac33effcdc0c702b6f6e00de6e9c7f9 -size 8342 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png deleted file mode 100644 index 363529de09..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f12.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4b83b04aa7b927c77838df9c37c7140c90c996c2087ec853b53184f04171b1e -size 3656 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png deleted file mode 100644 index bf608ec850..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f13.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9679cb29860a83d68134af2f04ad3bee0ac33effcdc0c702b6f6e00de6e9c7f9 -size 8342 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png deleted file mode 100644 index 363529de09..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f14.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4b83b04aa7b927c77838df9c37c7140c90c996c2087ec853b53184f04171b1e -size 3656 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png deleted file mode 100644 index 5486e76326..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ea2de02d1c264927e21e605e429d089cdfe5d645b63448fd72b7d1598fdf310 -size 5209 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png deleted file mode 100644 index 511d689c7f..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e40285703c9b1d6837a6d688e5c7ef3d938a6985b31cf10a75e19201db697ae -size 5288 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png deleted file mode 100644 index e496e68cf5..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9c541acc9eeeabc9876ec9aa530cae01c041c0c33c380973c19aa07d51ee7c40 -size 5288 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png deleted file mode 100644 index b345bf1a90..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:71f455aacf5b0c0d3230a24ad2642f62197cd874dacbec6227f9eb92e434dd80 -size 5294 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png deleted file mode 100644 index be5458325c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a47e3be6a383a0c56491687de1d87087d1078dc350d6c65f1c438b7b771137e3 -size 5330 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png deleted file mode 100644 index 8b5b309e01..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:103c0b16acfbb9ea57846a58ab483febc680067ef3bdeaefaadb2bed28844c85 -size 5308 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png deleted file mode 100644 index 283b823c85..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8762ec4292f71e06d6a1e006dde6b905b652155d4a630b75c55271ee5884e65f -size 5352 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png deleted file mode 100644 index d42ad62cd6..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2d35e0ad3b8b4bc9657bab5e425587c9df2e766d5aeb7b0bd7ac129eac583bbe -size 5349 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png deleted file mode 100644 index 846bdc11d3..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:85527a1062b9a7e43bc41a77b1305b9eb760fb51d74d28212bc88fd66a48a50e -size 5281 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png deleted file mode 100644 index 26dc75d616..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png deleted file mode 100644 index 6cf047c5e1..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f2.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fdc90a82cbf25a71057acff68ba217043fe41ac5ce621e27327a7af57718ab1a -size 9890 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png deleted file mode 100644 index 3f0b0bcdbd..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f3.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:899cfa2f035f4569b2d0f3f17c280bbae3ebb88b3bdd26bf9f880efabe4c6d52 -size 9899 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png deleted file mode 100644 index 26dc75d616..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f4.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png deleted file mode 100644 index 26dc75d616..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f5.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png deleted file mode 100644 index 26dc75d616..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f6.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png deleted file mode 100644 index 26dc75d616..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f7.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f207e80770425c37e9e9174f804c683bcfb569c526531ef4f9c9a6f7b09ec91 -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png deleted file mode 100644 index 3d85b23e3c..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f8.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a44df91e96732871fe93539475c86cd8cab1bb4fe2981c9661d5f18bdbe0252f -size 9892 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png deleted file mode 100644 index 4e98909946..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.f9.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9b9a7ea7926e4c6c6fb6931149a66764d24ac7147ebedad94f7a1674c7ab378 -size 9889 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png deleted file mode 100644 index a57a226519..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TextBlockWrappingTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b538103eeefc5ce32ece5a7a31bb1723d50d8b6f102169dc4219bcde994854c -size 8365 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.f1.png deleted file mode 100644 index d44da64a39..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.f1.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4dff181e9b33b792fd9059f77fe30f667859cfa87f76feb159e3d2f9dcfa1ca2 -size 17783 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.png deleted file mode 100644 index 4be23f004b..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/TransparencyTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:846555da06378cee709563c3a3c764c91661f339d93140706abf59cb76eb9e64 -size 26536 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/UniformGridTest.png b/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/UniformGridTest.png deleted file mode 100644 index fe222b16c1..0000000000 --- a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/SwiftShader/UniformGridTest.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:657cafbb822b78211d98a89eb3512f872ad44cd23c4498ed561a4eee4da73c9d -size 24410 From d9e7a63bd72a571ed626455af44a90006aba498e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 19 Apr 2026 17:29:43 +0900 Subject: [PATCH 1072/1182] fix: SPIR-V: emit DepthReplacing execution mode when PS writes SV_Depth --- .../Spirv/Processing/Interfaces/InterfaceProcessor.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index b91f8153f5..785f7ef042 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -120,6 +120,16 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex entryPoints.Add(psEntry); buffer.Add(new OpExecutionMode(psEntry.Id, ExecutionMode.OriginUpperLeft, [])); + + // Vulkan spec VUID-FragDepth-FragDepth-04216: a shader that writes the FragDepth + // builtin must declare the DepthReplacing execution mode. NVIDIA/AMD drivers + // tolerate the omission; strict validators (spirv-val, Lavapipe) reject it. + if (streams.Any(s => s.Value.Write && s.Value.Output + && s.Value.Semantic is { } sem + && sem.Equals("SV_DEPTH", StringComparison.OrdinalIgnoreCase))) + { + buffer.Add(new OpExecutionMode(psEntry.Id, ExecutionMode.DepthReplacing, [])); + } } else { From 92c2867f5e9281a3dad9b85f55a3cde0036aa266 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 19 Apr 2026 17:37:41 +0900 Subject: [PATCH 1073/1182] fix: Vulkan: use DepthStencilReadOnlyOptimal when pipeline doesn't write depth Lets a depth buffer be bound simultaneously as a read-only depth attachment and as a sampled image (e.g. soft-edge particles), matching the render pass initial layout, the image's actual layout, and the descriptor's imageLayout. Clears VUID-vkCmdBeginRenderPass-initialLayout-00900 and VUID-VkDescriptorImageInfo-imageLayout-00344 on strict validators (Lavapipe). --- .../Vulkan/CommandList.Vulkan.cs | 38 +++++++++++++++---- .../Vulkan/PipelineState.Vulkan.cs | 19 ++++++++-- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index 75761eb62e..1711f0d503 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -315,11 +315,25 @@ private void TransitionBoundResources() } } + // If the pipeline disables depth+stencil writes the depth attachment can ride in + // DepthStencilReadOnlyOptimal — matching the render-pass layout picked in + // PipelineState.CreateRenderPass and leaving the image sampleable (soft-edge particles). + var dss = activePipeline.Description.DepthStencilState; + bool depthReadOnly = !dss.DepthBufferWriteEnable + && (!dss.StencilEnable || dss.StencilWriteMask == 0); + var depthAttachmentLayout = depthReadOnly + ? VkImageLayout.DepthStencilReadOnlyOptimal + : VkImageLayout.DepthStencilAttachmentOptimal; + var depthAttachmentBarrier = depthReadOnly + ? BarrierLayout.DepthStencilRead + : BarrierLayout.DepthStencilWrite; + + Texture depthParent = null; if (depthStencilBuffer != null) { - var parent = depthStencilBuffer.ParentTexture ?? depthStencilBuffer; - if (parent.NativeLayout != VkImageLayout.DepthStencilAttachmentOptimal) - ResourceBarrierTransition(depthStencilBuffer, BarrierLayout.DepthStencilWrite); + depthParent = depthStencilBuffer.ParentTexture ?? depthStencilBuffer; + if (depthParent.NativeLayout != depthAttachmentLayout) + ResourceBarrierTransition(depthStencilBuffer, depthAttachmentBarrier); } // Transition sampled/storage textures bound in descriptors @@ -341,9 +355,12 @@ private void TransitionBoundResources() if (parent.NativeLayout == VkImageLayout.PresentSrcKHR) continue; - var expectedLayout = mapping.DescriptorType == VkDescriptorType.SampledImage - ? VkImageLayout.ShaderReadOnlyOptimal - : VkImageLayout.General; + // Skip if this sampled image is the currently bound read-only depth buffer: + // DepthStencilReadOnlyOptimal is already valid for shader reads and moving it + // to ShaderReadOnlyOptimal would break the render pass's attachment layout. + if (depthReadOnly && depthParent != null && parent == depthParent + && mapping.DescriptorType == VkDescriptorType.SampledImage) + continue; // Always call ResourceBarrierTransition — even if the layout matches, the barrier // must be re-issued when the resource was last transitioned by a different command list. @@ -445,7 +462,14 @@ private unsafe void BindDescriptorSets() case VkDescriptorType.SampledImage: { var texture = heapObject.Value as Texture; - descriptorData->ImageInfo = new VkDescriptorImageInfo { imageView = texture?.NativeImageView ?? GraphicsDevice.EmptyTexture.NativeImageView, imageLayout = VkImageLayout.ShaderReadOnlyOptimal }; + // The descriptor's layout field must match the image's actual layout. + // A depth buffer sampled as SRV while still bound as a read-only attachment + // is in DepthStencilReadOnlyOptimal rather than the usual ShaderReadOnlyOptimal. + var nativeLayout = (texture?.ParentTexture ?? texture)?.NativeLayout ?? VkImageLayout.ShaderReadOnlyOptimal; + var imageLayout = nativeLayout == VkImageLayout.DepthStencilReadOnlyOptimal + ? VkImageLayout.DepthStencilReadOnlyOptimal + : VkImageLayout.ShaderReadOnlyOptimal; + descriptorData->ImageInfo = new VkDescriptorImageInfo { imageView = texture?.NativeImageView ?? GraphicsDevice.EmptyTexture.NativeImageView, imageLayout = imageLayout }; write->pImageInfo = &descriptorData->ImageInfo; break; } diff --git a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs index 30680845af..22e69de44b 100644 --- a/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/PipelineState.Vulkan.cs @@ -289,6 +289,19 @@ private unsafe void CreateRenderPass(PipelineStateDescription pipelineStateDescr } } + // A pipeline that disables depth writes AND doesn't write stencil is compatible with + // DepthStencilReadOnlyOptimal, which is also a valid layout for shader sampling. Using + // that layout here lets a depth buffer be bound simultaneously as read-only attachment + // and as a SampledImage (e.g. soft-edge particles sampling the scene depth) without + // triggering VUID-vkCmdBeginRenderPass-initialLayout-00900. + var dss = pipelineStateDescription.DepthStencilState; + bool depthReadOnly = hasDepthStencilAttachment + && !dss.DepthBufferWriteEnable + && (!dss.StencilEnable || dss.StencilWriteMask == 0); + var depthLayout = depthReadOnly + ? VkImageLayout.DepthStencilReadOnlyOptimal + : VkImageLayout.DepthStencilAttachmentOptimal; + if (hasDepthStencilAttachment) { attachments[attachmentCount - 1] = new VkAttachmentDescription @@ -299,8 +312,8 @@ private unsafe void CreateRenderPass(PipelineStateDescription pipelineStateDescr storeOp = VkAttachmentStoreOp.Store, // TODO VULKAN: Only if depth write enabled? stencilLoadOp = VkAttachmentLoadOp.DontCare, // TODO VULKAN: Handle stencil stencilStoreOp = VkAttachmentStoreOp.DontCare, - initialLayout = VkImageLayout.DepthStencilAttachmentOptimal, - finalLayout = VkImageLayout.DepthStencilAttachmentOptimal + initialLayout = depthLayout, + finalLayout = depthLayout }; } @@ -311,7 +324,7 @@ private unsafe void CreateRenderPass(PipelineStateDescription pipelineStateDescr var depthAttachmentReference = new VkAttachmentReference { attachment = (uint)attachments.Length - 1, - layout = VkImageLayout.DepthStencilAttachmentOptimal + layout = depthLayout }; var subpass = new VkSubpassDescription From 687aadc33a113f66ff5583dd3a71ea4373313bb2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 19 Apr 2026 17:54:44 +0900 Subject: [PATCH 1074/1182] tools: CompareGold: fixed detail pane, pixel delta, software-renderer match for Lavapipe/llvmpipe --- build/tools/Stride.CompareGold/Program.cs | 2 +- build/tools/Stride.CompareGold/wwwroot/app.js | 261 +++++++++++------- .../Stride.CompareGold/wwwroot/index.html | 11 +- .../Stride.CompareGold/wwwroot/style.css | 60 +++- 4 files changed, 214 insertions(+), 120 deletions(-) diff --git a/build/tools/Stride.CompareGold/Program.cs b/build/tools/Stride.CompareGold/Program.cs index c0462d0c11..9facb9408c 100644 --- a/build/tools/Stride.CompareGold/Program.cs +++ b/build/tools/Stride.CompareGold/Program.cs @@ -492,7 +492,7 @@ static string GetGfxApi(string platformApi) static bool IsSoftwareRenderer(string device) { var d = device.ToLowerInvariant(); - return d.Contains("warp") || d.Contains("swiftshader"); + return d.Contains("warp") || d.Contains("swiftshader") || d.Contains("lavapipe") || d.Contains("llvmpipe"); } static IResult ServeImage(string baseDir, string suite, string platform, string name) diff --git a/build/tools/Stride.CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js index 2b48dd9322..fd48bf9188 100644 --- a/build/tools/Stride.CompareGold/wwwroot/app.js +++ b/build/tools/Stride.CompareGold/wwwroot/app.js @@ -4,7 +4,7 @@ let currentPlatform = ''; let sources = []; // [{id, type, label}] let sourceDefs = []; // tracks how sources were added for persistence let suiteData = {}; // {suite: {gold: [{name}], sourceImages: {srcId: [{name}]}}} -let expanded = new Set(); // "suite:name" — fully loaded and visible +let focusedKey = null; // "suite:name" — currently selected row shown in bottom detail pane let loading = new Set(); // "suite:name" — loading in progress let selected = new Set(); // "suite:name" let collapsedSuites = new Set(); @@ -133,7 +133,7 @@ async function removeSource(id) { sources = sources.filter(s => s.id !== id); if (idx >= 0) sourceDefs.splice(idx, 1); cellStats = {}; - expanded.clear(); + focusedKey = null; selected.clear(); compareLeft = {}; compareRight = {}; @@ -267,30 +267,17 @@ function renderTable() { for (const img of images) { totalVisible++; const key = `${img.suite}:${img.name}`; - const isExp = expanded.has(key); const tr = document.createElement('tr'); - tr.className = `row ${isExp ? 'expanded' : ''}`; + tr.className = `row${focusedKey === key ? ' kb-focus' : ''}`; tr.dataset.kbKey = key; tr.innerHTML = buildRowCells(img, key); tr.onmousedown = (e) => { tr._clickX = e.clientX; tr._clickY = e.clientY; }; tr.onclick = (e) => { if (Math.abs(e.clientX - tr._clickX) > 3 || Math.abs(e.clientY - tr._clickY) > 3) return; - toggleExpand(key); + focusRow(key); }; tbody.appendChild(tr); - - if (isExp) { - const detailTr = document.createElement('tr'); - const colspan = 3 + sources.length; - detailTr.innerHTML = ` -
-
Loading...
-
- `; - tbody.appendChild(detailTr); - loadDetail(img.suite, img.name); - } } } document.getElementById('emptyMsg').style.display = totalVisible === 0 ? 'block' : 'none'; @@ -298,7 +285,6 @@ function renderTable() { } function buildRowCells(img, key) { - const isExp = expanded.has(key); const isLoading = loading.has(key); const isSel = selected.has(key); @@ -310,7 +296,7 @@ function buildRowCells(img, key) { let cells = ` - ${isExp ? '▼' : '▶'} ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? `${fixableVia[key] ? 'failing (fixable)' : 'failing'}` : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} + ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? `${fixableVia[key] ? 'failing (fixable)' : 'failing'}` : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} ${img.hasGold ? (img.goldFallback ? 'fb' : 'ref') : '—'}${img.hasGold ? ` ${esc(img.goldFallback || currentPlatform)}` : ''}${goldThumb}`; const activeRef = compareRight[key] || `src:${getSourceForKey(key)}`; @@ -359,31 +345,13 @@ function renderRow(key) { const existingTr = document.querySelector(`tr.row[data-kb-key="${CSS.escape(key)}"]`); if (!existingTr) return; - const isExp = expanded.has(key); - existingTr.className = `row ${isExp ? 'expanded' : ''}`; + existingTr.className = `row${focusedKey === key ? ' kb-focus' : ''}`; existingTr.innerHTML = buildRowCells(img, key); existingTr.onmousedown = (e) => { existingTr._clickX = e.clientX; existingTr._clickY = e.clientY; }; existingTr.onclick = (e) => { if (Math.abs(e.clientX - existingTr._clickX) > 3 || Math.abs(e.clientY - existingTr._clickY) > 3) return; - toggleExpand(key); + focusRow(key); }; - - // Handle detail row - const nextTr = existingTr.nextElementSibling; - const hasDetailRow = nextTr && !nextTr.classList.contains('row') && !nextTr.classList.contains('suite-row'); - if (isExp && !hasDetailRow) { - const detailTr = document.createElement('tr'); - const colspan = 3 + sources.length; - detailTr.innerHTML = ` -
-
Loading...
-
- `; - existingTr.after(detailTr); - loadDetail(img.suite, img.name); - } else if (!isExp && hasDetailRow) { - nextTr.remove(); - } updateSelectedCount(); saveState(); } @@ -396,7 +364,6 @@ function toggleSuite(suite) { // === Detail === const detailVersion = {}; // track version to discard stale loads -const preloaded = {}; // cached images from startExpand function resolveImageRef(ref, suite, name) { if (!ref) return null; @@ -443,14 +410,6 @@ async function loadDetail(suite, name) { const key = `${suite}:${name}`; const id = css(key); - // Use preloaded data if available (from startExpand) - const cached = preloaded[key]; - if (cached) { - delete preloaded[key]; - fillDetail(id, key, suite, name, cached); - return; - } - const ver = (detailVersion[key] || 0) + 1; detailVersion[key] = ver; @@ -474,15 +433,6 @@ async function loadDetail(suite, name) { ]); if (detailVersion[key] !== ver) return; - // If no container yet (loading from startExpand), transition to expanded - if (!document.getElementById(`images-${id}`)) { - loading.delete(key); - expanded.add(key); - preloaded[key] = { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }; - renderRow(key); // re-render this row creates the container, loadDetail re-enters and uses preloaded - return; - } - fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }); } @@ -508,11 +458,11 @@ async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPl else html += `
No image
`; html += ``; html += `
Diff
`; - if (leftImg && rightImg) html += `
`; + if (leftImg && rightImg) html += `
`; else html += `
`; html += `
`; html += ''; - html += `
Ctrl+Scroll to zoom · Drag to pan ·
`; + html += ``; container.innerHTML = html; if (leftImg) drawToCanvas(document.getElementById(`left-${id}`), leftImg); @@ -533,6 +483,7 @@ async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPl if (statsEl) statsEl.innerHTML = formatStats(stats, thresholdResult); } initZoomGroup(id); + updatePaneBounds(leftImg || rightImg); // Compute compact stats for gold options vs the other side const otherImg = rightImg || leftImg; @@ -743,22 +694,40 @@ async function computeThumbDiff(suite, name, srcId, canvasId) { // === Actions === -function toggleExpand(key) { - if (expanded.has(key)) { expanded.delete(key); loading.delete(key); renderRow(key); } - else if (loading.has(key)) { loading.delete(key); renderRow(key); } - else startExpand(key); -} - -function expandWith(key, srcId) { - if (expanded.has(key)) { expanded.delete(key); loading.delete(key); renderRow(key); } - else if (loading.has(key)) { loading.delete(key); renderRow(key); } - else { compareRight[key] = `src:${srcId}`; startExpand(key); } +function focusRow(key) { + if (!key) { + focusedKey = null; + kbFocusKey = null; + document.querySelectorAll('tr.kb-focus').forEach(r => r.classList.remove('kb-focus')); + renderDetailPane(null); + saveState(); + return; + } + focusedKey = key; + kbFocusKey = key; + // Update border on rows without full re-render + document.querySelectorAll('tr.kb-focus').forEach(r => r.classList.remove('kb-focus')); + const row = document.querySelector(`tr[data-kb-key="${CSS.escape(key)}"]`); + if (row) { + row.classList.add('kb-focus'); + row.scrollIntoView({ block: 'nearest' }); + } + renderDetailPane(key); + saveState(); } -function startExpand(key) { - loading.add(key); - renderRow(key); - const [suite, name] = [key.substring(0, key.indexOf(':')), key.substring(key.indexOf(':') + 1)]; +function renderDetailPane(key) { + const pane = document.getElementById('detailPaneContent'); + if (!pane) return; + if (!key) { + pane.innerHTML = `
No selection
`; + return; + } + const colon = key.indexOf(':'); + const suite = key.substring(0, colon); + const name = key.substring(colon + 1); + const id = css(key); + pane.innerHTML = `
Loading...
`; loadDetail(suite, name); } @@ -772,8 +741,8 @@ function setActiveSource(key, srcId) { td.classList.toggle('active-source', match && match[1] === srcId); }); } - // If expanded, also update the detail view - if (expanded.has(key)) { + // If this is the focused row, refresh the detail pane + if (focusedKey === key) { const [suite, name] = [key.substring(0, key.indexOf(':')), key.substring(key.indexOf(':') + 1)]; loadDetail(suite, name); } @@ -791,7 +760,7 @@ function switchDetailSide(key, side, value) { const activeSrcId = value.startsWith('src:') ? value.slice(4) : null; const srcCells = row.querySelectorAll('td[onclick]'); srcCells.forEach(td => { - const match = td.getAttribute('onclick')?.match(/expandWith\('[^']*','([^']*)'\)/); + const match = td.getAttribute('onclick')?.match(/setActiveSource\('[^']*','([^']*)'\)/); td.classList.toggle('active-source', match && match[1] === activeSrcId); }); } @@ -904,16 +873,6 @@ async function deleteSelectedGold() { await reload(); } -function expandAllFailing() { - for (const suite of Object.keys(suiteData)) { - const images = buildSuiteImages(suite); - images.filter(i => i.status === 'fail' || i.status === 'new').forEach(i => expanded.add(`${i.suite}:${i.name}`)); - } - render(); -} - -function collapseAll() { expanded.clear(); render(); } - function getSourceForKey(key) { // Use the right-side source from the detail view, or fall back to first source with the image const ref = compareRight[key]; @@ -1218,9 +1177,8 @@ function initZoomGroup(groupId) { const containers = group.querySelectorAll('.zoom-container'); containers.forEach(container => { - // Wheel zoom + // Wheel zoom (scroll anywhere over the image area) container.addEventListener('wheel', (e) => { - if (!e.ctrlKey) return; // plain scroll passes through; Ctrl+scroll zooms e.preventDefault(); const state = zoomState[groupId]; const rect = container.getBoundingClientRect(); @@ -1319,6 +1277,9 @@ document.addEventListener('mousemove', (e) => { // Build inspector content let html = ''; + // Collect full-size entries in order [left, right, diff]; delta is shown only on the diff entry, + // computed as right − left (so the third column reports the inter-image difference). + let leftRGBA = null, rightRGBA = null, entryIdx = 0; for (const ri of relatedImages) { const lblEl = ri.closest('.image-box')?.querySelector('.lbl'); const sel = lblEl?.querySelector('select'); @@ -1362,16 +1323,41 @@ document.addEventListener('mousemove', (e) => { const r = cr, g = cg, b = cb, a = ca; + // Capture left/right RGBA so the diff entry can report right − left. + if (entryIdx === 0) leftRGBA = { r, g, b, a }; + else if (entryIdx === 1) rightRGBA = { r, g, b, a }; + + // Body rows: columns 1 and 2 show absolute RGB; column 3 shows Δ(right − left) only. + let bodyHtml; + if (entryIdx >= 2 && leftRGBA && rightRGBA) { + const dR = rightRGBA.r - leftRGBA.r; + const dG = rightRGBA.g - leftRGBA.g; + const dB = rightRGBA.b - leftRGBA.b; + const dA = rightRGBA.a - leftRGBA.a; + const fmt = (v) => (v > 0 ? '+' : '') + v; + const cls = (v) => v !== 0 ? 'pi-delta-nz' : ''; + bodyHtml = + `
 
` + // spacer to align with the #hex row on columns 1/2 + `
ΔR: ${fmt(dR)}
` + + `
ΔG: ${fmt(dG)}
` + + `
ΔB: ${fmt(dB)}
` + + `
ΔA: ${fmt(dA)}
`; + } else { + bodyHtml = + `
#${r.toString(16).padStart(2,'0')}${g.toString(16).padStart(2,'0')}${b.toString(16).padStart(2,'0')}${a<255?a.toString(16).padStart(2,'0'):''}
` + + `
R: ${String(r).padStart(3)} (${(r/255).toFixed(3)})
` + + `
G: ${String(g).padStart(3)} (${(g/255).toFixed(3)})
` + + `
B: ${String(b).padStart(3)} (${(b/255).toFixed(3)})
` + + `
A: ${String(a).padStart(3)} (${(a/255).toFixed(3)})
`; + } + html += `
${esc(label)}
X:${px} Y:${py}
-
#${r.toString(16).padStart(2,'0')}${g.toString(16).padStart(2,'0')}${b.toString(16).padStart(2,'0')}${a<255?a.toString(16).padStart(2,'0'):''}
-
R: ${String(r).padStart(3)} (${(r/255).toFixed(3)})
-
G: ${String(g).padStart(3)} (${(g/255).toFixed(3)})
-
B: ${String(b).padStart(3)} (${(b/255).toFixed(3)})
-
A: ${String(a).padStart(3)} (${(a/255).toFixed(3)})
+ ${bodyHtml}
`; + entryIdx++; } const inspector = document.getElementById('pixelInspector'); @@ -1421,7 +1407,14 @@ function kbSetFocus(rows, idx) { if (idx >= 0 && idx < rows.length) { rows[idx].classList.add('kb-focus'); rows[idx].scrollIntoView({ block: 'nearest' }); - kbFocusKey = rows[idx].dataset.kbKey || null; + const key = rows[idx].dataset.kbKey || null; + kbFocusKey = key; + // Drive the detail pane when focus lands on a test row (not the suite header). + if (rows[idx].classList.contains('row')) { + focusedKey = key; + renderDetailPane(key); + } + saveState(); } } @@ -1440,8 +1433,6 @@ function kbExpand(row) { } collapsedSuites.delete(key); render(); - } else if (!expanded.has(key) && !loading.has(key)) { - startExpand(key); } } @@ -1451,11 +1442,8 @@ function kbCollapse(row) { if (row.classList.contains('suite-row')) { if (collapsedSuites.has(key)) return; // already collapsed, nowhere to go collapsedSuites.add(key); - } else if (expanded.has(key) || loading.has(key)) { - expanded.delete(key); - loading.delete(key); } else { - // Already collapsed test row — move to parent suite + // Test row — move to parent suite const rows = [...document.querySelectorAll('tr.suite-row, tr.row')]; const idx = rows.indexOf(row); for (let i = idx - 1; i >= 0; i--) { @@ -1484,12 +1472,13 @@ function saveState() { try { localStorage.setItem('compareGold', JSON.stringify({ platform: currentPlatform, - expanded: [...expanded], + selectedKey: focusedKey, collapsedSuites: [...collapsedSuites], statusFilter: document.getElementById('statusFilter')?.value || '', sort: document.getElementById('sortSelect')?.value || 'name', search: document.getElementById('searchFilter')?.value || '', savedSources: sourceDefs, + detailPaneH: document.documentElement.style.getPropertyValue('--detail-pane-h') || '', })); } catch {} } @@ -1498,7 +1487,7 @@ function restoreState() { try { const data = JSON.parse(localStorage.getItem('compareGold') || '{}'); if (data.platform) currentPlatform = data.platform; - if (data.expanded) data.expanded.forEach(k => expanded.add(k)); + if (data.selectedKey) { focusedKey = data.selectedKey; kbFocusKey = data.selectedKey; } if (data.collapsedSuites) data.collapsedSuites.forEach(k => collapsedSuites.add(k)); if (data.statusFilter !== undefined) { const sel = document.getElementById('statusFilter'); @@ -1513,6 +1502,7 @@ function restoreState() { if (el) el.value = data.search; } if (data.savedSources) savedSourceDefs = data.savedSources; + if (data.detailPaneH) document.documentElement.style.setProperty('--detail-pane-h', data.detailPaneH); } catch {} } @@ -1547,6 +1537,59 @@ async function restoreSources() { const _origRender = render; render = function() { _origRender(); saveState(); }; +// === Detail pane resize === +// Hard floor: keep images usable; updatePaneBounds() recomputes ceiling from loaded image aspect. +const PANE_MIN_H = 160; +let paneMaxH = null; + +function updatePaneBounds(refImg) { + const pane = document.getElementById('detailPane'); + if (!pane) return; + const container = pane.querySelector('.zoom-container'); + if (!refImg || !container) { paneMaxH = null; return; } + const aw = refImg.naturalWidth || refImg.width; + const ah = refImg.naturalHeight || refImg.height; + if (!aw || !ah) { paneMaxH = null; return; } + // Image-box width at full pane width. Add non-image overhead (handle, padding, label, footer, margins). + const boxW = container.offsetWidth; + const maxImgH = Math.ceil(boxW * ah / aw); + const overhead = pane.offsetHeight - container.offsetHeight; + const winCap = window.innerHeight - 120; + paneMaxH = Math.min(winCap, Math.max(PANE_MIN_H, maxImgH + overhead)); + // Clamp current height if it exceeds the new bounds. + const cur = pane.offsetHeight; + const clamped = Math.max(PANE_MIN_H, Math.min(paneMaxH, cur)); + if (clamped !== cur) { + document.documentElement.style.setProperty('--detail-pane-h', clamped + 'px'); + saveState(); + } +} + +(function initPaneResize() { + const handle = document.getElementById('detailPaneHandle'); + if (!handle) return; + handle.addEventListener('mousedown', (e) => { + e.preventDefault(); + handle.classList.add('dragging'); + const startY = e.clientY; + const startH = document.getElementById('detailPane').offsetHeight; + const onMove = (ev) => { + const dy = startY - ev.clientY; + const cap = paneMaxH != null ? paneMaxH : (window.innerHeight - 120); + const h = Math.max(PANE_MIN_H, Math.min(cap, startH + dy)); + document.documentElement.style.setProperty('--detail-pane-h', h + 'px'); + }; + const onUp = () => { + handle.classList.remove('dragging'); + document.removeEventListener('mousemove', onMove); + document.removeEventListener('mouseup', onUp); + saveState(); + }; + document.addEventListener('mousemove', onMove); + document.addEventListener('mouseup', onUp); + }); +})(); + // === Start === restoreState(); init().then(async () => { @@ -1564,4 +1607,18 @@ init().then(async () => { } else { await addLocalSource().catch(() => {}); } + // Re-hydrate the detail pane with the restored selection (if it still exists). + if (focusedKey) { + const row = document.querySelector(`tr.row[data-kb-key="${CSS.escape(focusedKey)}"]`); + if (row) { + row.classList.add('kb-focus'); + row.scrollIntoView({ block: 'nearest' }); + renderDetailPane(focusedKey); + } else { + focusedKey = null; + renderDetailPane(null); + } + } else { + renderDetailPane(null); + } }); diff --git a/build/tools/Stride.CompareGold/wwwroot/index.html b/build/tools/Stride.CompareGold/wwwroot/index.html index 1d1f2efaf7..91eca98d99 100644 --- a/build/tools/Stride.CompareGold/wwwroot/index.html +++ b/build/tools/Stride.CompareGold/wwwroot/index.html @@ -27,9 +27,6 @@

CompareGold

- - -
Sources: @@ -53,6 +50,14 @@

CompareGold

Select a suite and platform, then add a source to compare.
+ +
+
+
+
No selection
+
+
+
public PipelineState PipelineState; + /// + /// True if the pipeline writes depth (DepthBufferWriteEnable) or stencil (StencilWriteMask != 0). + /// Captured from the PipelineStateDescription when the PipelineState is first built, used by + /// RenderSystem.Draw to auto-detect a stage's depth access mode before worker fan-out. + /// + public bool WritesDepth; + /// /// Validates if effect needs to be compiled or recompiled. /// diff --git a/sources/engine/Stride.Rendering/Rendering/RenderStage.cs b/sources/engine/Stride.Rendering/Rendering/RenderStage.cs index cd055db3c8..8bb6576210 100644 --- a/sources/engine/Stride.Rendering/Rendering/RenderStage.cs +++ b/sources/engine/Stride.Rendering/Rendering/RenderStage.cs @@ -49,7 +49,7 @@ public sealed class RenderStage : IIdentifiable /// homogeneous in depth access. /// [DataMemberIgnore] - public RenderStageDepthAccess DepthAccess { get; set; } = RenderStageDepthAccess.Write; + public RenderStageDepthAccess DepthAccess { get; set; } = RenderStageDepthAccess.Auto; public RenderStage() { @@ -90,6 +90,8 @@ public override string ToString() /// public enum RenderStageDepthAccess { + /// Detect from the stage's render nodes on each frame (default). See RenderSystem.Draw. + Auto, /// All pipelines in the stage write depth (most opaque, shadow, z-prepass passes). Write, /// All pipelines in the stage only read depth (transparent with depth-test-only). diff --git a/sources/engine/Stride.Rendering/Rendering/RenderSystem.cs b/sources/engine/Stride.Rendering/Rendering/RenderSystem.cs index 79c3c9df3a..54fad75492 100644 --- a/sources/engine/Stride.Rendering/Rendering/RenderSystem.cs +++ b/sources/engine/Stride.Rendering/Rendering/RenderSystem.cs @@ -323,6 +323,31 @@ public unsafe void Prepare(RenderDrawContext context) context.RenderContext.Flush(); } + /// + /// Scans a stage's render nodes for whether any/all pipelines write depth. Used to pick a + /// pre-pass depth layout (Read or Write) on the main CB before worker fan-out so the depth + /// layout transition isn't left to racing workers. + /// + private static RenderStageDepthAccess DetectStageDepthAccess(System.Collections.Generic.List sortedRenderNodes, int renderNodeCount) + { + bool hasRead = false, hasWrite = false; + for (int i = 0; i < renderNodeCount; i++) + { + var nodeRef = sortedRenderNodes[i]; + var node = nodeRef.RootRenderFeature.GetRenderNode(nodeRef.RenderNode); + var effect = node.RenderEffect; + // RootRenderFeatures that don't use RenderEffect (e.g. SpriteRenderFeature) leave + // it null. Conservatively treat those as Mixed — we can't know their depth mode. + if (effect == null) return RenderStageDepthAccess.Mixed; + if (effect.WritesDepth) hasWrite = true; + else hasRead = true; + if (hasWrite && hasRead) return RenderStageDepthAccess.Mixed; + } + if (hasWrite) return RenderStageDepthAccess.Write; + if (hasRead) return RenderStageDepthAccess.Read; + return RenderStageDepthAccess.Mixed; // empty stage: nothing to pre-transition + } + public void Draw(RenderDrawContext renderDrawContext, RenderView renderView, RenderStage renderStage) { using var _ = Profiler.Begin(DrawKey); @@ -360,7 +385,14 @@ public void Draw(RenderDrawContext renderDrawContext, RenderView renderView, Ren if (renderNodeCount == 0) return; - if (!GraphicsDevice.IsDeferred) + // Stages with heterogeneous depth access can't be safely pre-transitioned on the main + // CB before parallel worker dispatch (workers would race on the Write↔Read transition). + // Run them sequentially on the main CB — no cross-CB race by construction. + var stageDepthAccess = renderStage.DepthAccess; + if (stageDepthAccess == RenderStageDepthAccess.Auto) + stageDepthAccess = DetectStageDepthAccess(renderNodes, renderNodeCount); + + if (!GraphicsDevice.IsDeferred || stageDepthAccess == RenderStageDepthAccess.Mixed) { using (Profiler.Begin(DrawRootRenderFeaturesKey)) { @@ -412,16 +444,11 @@ public void Draw(RenderDrawContext renderDrawContext, RenderView renderView, Ren } if (depthStencilBuffer != null) { - switch (renderStage.DepthAccess) - { - case RenderStageDepthAccess.Write: - commandList.ResourceBarrierTransition(depthStencilBuffer, BarrierLayout.DepthStencilWrite); - break; - case RenderStageDepthAccess.Read: - commandList.ResourceBarrierTransition(depthStencilBuffer, BarrierLayout.DepthStencilRead); - break; - // Mixed: skip - } + // stageDepthAccess here is Write or Read (Mixed was routed to the sequential branch above) + commandList.ResourceBarrierTransition(depthStencilBuffer, + stageDepthAccess == RenderStageDepthAccess.Read + ? BarrierLayout.DepthStencilRead + : BarrierLayout.DepthStencilWrite); } // Collect one command list per batch and the main one up to this point diff --git a/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs index b3ecca7d1d..98e7b8302d 100644 --- a/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/RootEffectRenderFeature.cs @@ -860,6 +860,12 @@ public override void Prepare(RenderDrawContext context) mutablePipelineState.Update(); renderEffect.PipelineState = mutablePipelineState.CurrentState; + + // Snapshot depth-write state so RenderSystem.Draw can auto-detect the + // stage's depth access mode (pre-barrier Read vs Write) before dispatch. + var dss = pipelineState.DepthStencilState; + renderEffect.WritesDepth = dss.DepthBufferWriteEnable + || (dss.StencilEnable && dss.StencilWriteMask != 0); } RenderNodes[renderNodeReference.Index] = renderNode; From 05b8a92801cccb7849b18227c1780f294926ebba Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 18:59:18 +0900 Subject: [PATCH 1084/1182] fix: drop DepthStencil flag from shared 1x1 shadow-map placeholder The placeholder is only ever sampled, never attached for depth writes. Keeping the DepthStencil flag made Stride track NativeLayout as DepthStencilAttachmentOptimal while vkCreateImage left the GPU image in Undefined, so the first two workers to sample it in parallel both emitted a stale DSAO->SRO barrier and the second one tripped validation. --- .../engine/Stride.Graphics/GraphicsDeviceExtensions.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sources/engine/Stride.Graphics/GraphicsDeviceExtensions.cs b/sources/engine/Stride.Graphics/GraphicsDeviceExtensions.cs index 2fa7b618c6..6a3c91cca3 100644 --- a/sources/engine/Stride.Graphics/GraphicsDeviceExtensions.cs +++ b/sources/engine/Stride.Graphics/GraphicsDeviceExtensions.cs @@ -158,6 +158,13 @@ static unsafe Texture CreateWhiteTexture(GraphicsDevice device) /// /// The Graphics Device for which to retrieve the shared depth Texture. /// A with a 1x1 depth format. + /// + /// Only is set (no DepthStencil): the placeholder + /// is never attached for depth writes, so we don't want the initial Vulkan layout to be + /// DepthStencilAttachmentOptimal. With ShaderResource-only, Stride's NativeLayout + /// starts at ShaderReadOnlyOptimal, matching how the texture is actually used and avoiding + /// a stale-layout race when multiple worker command buffers first sample it in parallel. + /// public static Texture GetSharedDepthTexture(this GraphicsDevice device) { return device.GetOrCreateSharedData("DepthTexture", static device => @@ -166,7 +173,7 @@ public static Texture GetSharedDepthTexture(this GraphicsDevice device) ? new Texture(device, "DepthTexture") : new Texture(device); - var description = TextureDescription.New2D(1, 1, PixelFormat.D32_Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource); + var description = TextureDescription.New2D(1, 1, PixelFormat.D32_Float, TextureFlags.ShaderResource); texture.InitializeFrom(description); return texture; From e117377b078ce01937af4620c96283566e7ee77c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 18:59:23 +0900 Subject: [PATCH 1085/1182] test: drop stale AllowGpuValidationError on LightingTests No longer needed after the shared 1x1 depth placeholder fix. --- .../engine/Stride.Graphics.Tests.10_0/LightingTests.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sources/engine/Stride.Graphics.Tests.10_0/LightingTests.cs b/sources/engine/Stride.Graphics.Tests.10_0/LightingTests.cs index 23f3bef791..40b0c4d1f1 100644 --- a/sources/engine/Stride.Graphics.Tests.10_0/LightingTests.cs +++ b/sources/engine/Stride.Graphics.Tests.10_0/LightingTests.cs @@ -14,16 +14,6 @@ namespace Stride.Graphics.Tests /// /// Test lighting and shadows. /// - // Vulkan validation layer false positive: the shadow map atlas is transitioned from DepthStencilWrite - // to ShaderReadOnly in a command buffer that is submitted via a separate vkQueueSubmit call (with - // timeline semaphore ordering) before the worker command buffers that sample the shadow map. - // The validation layer doesn't track image layout transitions across timeline-semaphore-ordered - // submissions, so it reports the image as still being in DepthStencilAttachmentOptimal. - // Verified correct with STRIDE_MAX_PARALLELISM=1 (single command buffer, 0 failures in 10 runs). - // Related (but not identical): https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10185 - [AllowGpuValidationError(GraphicsPlatform.Vulkan, - "to be in layout VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL--instead, current layout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL", - Reason = "Validation layer doesn't track image layouts across timeline-semaphore-ordered command buffer submissions (https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/10185)")] public class LightingTests : GameTestBase { public Action SetupLighting { get; set; } From 3c16cfb316b798f27d6766487732c4d566490c9b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 19:05:02 +0900 Subject: [PATCH 1086/1182] tools: CompareGold: match framework any-gold-matches semantics --- build/tools/Stride.CompareGold/Program.cs | 52 ++-- build/tools/Stride.CompareGold/wwwroot/app.js | 246 +++++++++++------- 2 files changed, 191 insertions(+), 107 deletions(-) diff --git a/build/tools/Stride.CompareGold/Program.cs b/build/tools/Stride.CompareGold/Program.cs index 9facb9408c..d4ad14346d 100644 --- a/build/tools/Stride.CompareGold/Program.cs +++ b/build/tools/Stride.CompareGold/Program.cs @@ -105,11 +105,12 @@ var primary = ListPngNames(dir); var primarySet = new HashSet(primary); - // Find fallback gold from other platforms (matching test framework behavior) - // Prefer: same OS+API + same renderer class > same gfx API > same class > any + // Pick the best fallback gold for display. We mirror Graphics.Regression's + // any-match semantics for pass/fail on the client — this score only decides + // which gold the UI shows by default. var requestedApi = parts[0]; - var requestedGfx = GetGfxApi(requestedApi); - var requestedIsSw = IsSoftwareRenderer(parts[1]); + var requestedDevice = parts[1]; + var requestedIsSw = IsSoftwareRenderer(requestedDevice); var fallbackBest = new Dictionary(); var suiteDir = Path.Combine(testsDir, suite); if (Directory.Exists(suiteDir)) @@ -124,11 +125,7 @@ var fallbackPlatform = $"{pName}/{device}"; if (fallbackPlatform == platform) continue; var candidateIsSw = IsSoftwareRenderer(device); - if (requestedIsSw && !candidateIsSw) continue; - int score = 0; - if (pName == requestedApi) score += 4; - if (GetGfxApi(pName) == requestedGfx) score += 2; - if (candidateIsSw == requestedIsSw) score += 1; + var score = ScoreFallback(pName, device, candidateIsSw, requestedApi, requestedDevice, requestedIsSw); foreach (var f in Directory.GetFiles(dDir, "*.png")) { var name = Path.GetFileName(f); @@ -160,9 +157,9 @@ var suiteDir = Path.Combine(testsDir, suite); if (Directory.Exists(suiteDir)) { - var requestedIsSw = IsSoftwareRenderer(parts[1]); - var requestedApi = parts[0]; // e.g. "Windows.Direct3D11" - var requestedGfx = GetGfxApi(requestedApi); // e.g. "Direct3D11" + var requestedApi = parts[0]; + var requestedDevice = parts[1]; + var requestedIsSw = IsSoftwareRenderer(requestedDevice); string? bestPath = null; int bestScore = -1; foreach (var pDir in Directory.GetDirectories(suiteDir)) @@ -175,12 +172,7 @@ if (!File.Exists(candidate)) continue; var device = Path.GetFileName(dDir); var candidateIsSw = IsSoftwareRenderer(device); - // If source is SW, require SW gold (skip HW); if HW, accept any - if (requestedIsSw && !candidateIsSw) continue; - int score = 0; - if (pName == requestedApi) score += 4; // same OS + API - if (GetGfxApi(pName) == requestedGfx) score += 2; // same graphics API (cross-OS) - if (candidateIsSw == requestedIsSw) score += 1; // same renderer class + var score = ScoreFallback(pName, device, candidateIsSw, requestedApi, requestedDevice, requestedIsSw); if (score > bestScore) { bestScore = score; bestPath = candidate; } } } @@ -489,6 +481,30 @@ static string GetGfxApi(string platformApi) return dot >= 0 ? platformApi[(dot + 1)..] : platformApi; } +static string GetOS(string platformApi) +{ + // "Windows.Direct3D11" → "Windows", "Linux.Vulkan" → "Linux" + var dot = platformApi.IndexOf('.'); + return dot >= 0 ? platformApi[..dot] : platformApi; +} + +static int ScoreFallback(string candidatePlatApi, string candidateDevice, bool candidateIsSw, + string requestedPlatApi, string requestedDevice, bool requestedIsSw) +{ + // Higher = closer. Tiers, roughly in order of importance: + // exact OS+API > same OS > same gfx API across OS > same device/renderer > + // same renderer class (SW/HW). + // Same-device (e.g. both WARP, both Lavapipe) matters so D3D12/WARP picks + // D3D11/WARP over Windows.Vulkan/Lavapipe when they'd otherwise tie on OS. + int score = 0; + if (candidatePlatApi == requestedPlatApi) score += 16; + if (GetOS(candidatePlatApi) == GetOS(requestedPlatApi)) score += 8; + if (GetGfxApi(candidatePlatApi) == GetGfxApi(requestedPlatApi)) score += 4; + if (string.Equals(candidateDevice, requestedDevice, StringComparison.OrdinalIgnoreCase)) score += 2; + if (candidateIsSw == requestedIsSw) score += 1; + return score; +} + static bool IsSoftwareRenderer(string device) { var d = device.ToLowerInvariant(); diff --git a/build/tools/Stride.CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js index fd48bf9188..7b432a68ab 100644 --- a/build/tools/Stride.CompareGold/wwwroot/app.js +++ b/build/tools/Stride.CompareGold/wwwroot/app.js @@ -72,6 +72,7 @@ async function reload() { suiteData[suite] = { gold, sourceImages: srcImgs, thresholdRules }; } cellStats = {}; + resetAltGoldState(); render(); } @@ -133,6 +134,7 @@ async function removeSource(id) { sources = sources.filter(s => s.id !== id); if (idx >= 0) sourceDefs.splice(idx, 1); cellStats = {}; + resetAltGoldState(); focusedKey = null; selected.clear(); compareLeft = {}; @@ -151,6 +153,13 @@ function render() { renderPromoteSourceSelect(); renderTable(); updateActionCounts(); + // If the focused row is no longer visible (platform switch, filter, search, etc.), + // clear the detail pane so it doesn't keep showing a stale selection. + if (focusedKey && !document.querySelector(`tr.row[data-kb-key="${CSS.escape(focusedKey)}"]`)) { + focusedKey = null; + kbFocusKey = null; + renderDetailPane(null); + } } function renderSourceTags() { @@ -187,15 +196,19 @@ function buildSuiteImages(suite) { let status = 'pass'; if (!hasGold && Object.values(sourcesWithImage).some(v => v)) status = 'new'; else if (hasGold && Object.values(sourcesWithImage).some(v => v)) { - // Check all sources — fail if ANY source fails the threshold + // Per source: fail only when every gold in the suite fails — mirrors + // Graphics.Regression's any-match semantics. The alternate-gold check + // is lazy (kicked off when the preferred fails), so a cell whose + // preferred gold failed stays "pending" until that completes. let anyFail = false; let anyPending = false; for (const src of sources) { if (!sourcesWithImage[src.id]) continue; const stats = cellStats[`${src.id}:${suite}:${name}`]; if (!stats) { anyPending = true; computeCellStats(src.id, suite, name); continue; } - const result = checkCellThreshold(suite, name, stats); - if (!result.passed) { anyFail = true; } + const r = isCellPassing(src.id, suite, name, stats); + if (r === null) anyPending = true; + else if (!r) anyFail = true; } status = anyFail ? 'fail' : anyPending ? 'pending' : 'pass'; } @@ -296,7 +309,7 @@ function buildRowCells(img, key) { let cells = ` - ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? `${fixableVia[key] ? 'failing (fixable)' : 'failing'}` : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} + ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? 'failing' : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} ${img.hasGold ? (img.goldFallback ? 'fb' : 'ref') : '—'}${img.hasGold ? ` ${esc(img.goldFallback || currentPlatform)}` : ''}${goldThumb}`; const activeRef = compareRight[key] || `src:${getSourceForKey(key)}`; @@ -394,7 +407,14 @@ function buildRefOptions(goldPlatforms, selectedRef) { return html; } -function pickDefaultLeft(goldPlatforms) { +function pickDefaultLeft(goldPlatforms, img) { + // Match the gold the table row shows: primary if it exists for currentPlatform, + // otherwise the fallback the backend resolved. Only fall back to the scoring + // heuristic when the row has no gold at all. + if (img?.hasGold) { + const plat = img.goldFallback || currentPlatform; + if (goldPlatforms.some(p => p.platform === plat)) return `gold:${plat}`; + } const best = pickBestGoldPlatform(goldPlatforms, currentPlatform); return best ? `gold:${best}` : (sources[0] ? `src:${sources[0].id}` : ''); } @@ -421,7 +441,9 @@ async function loadDetail(suite, name) { if (detailVersion[key] !== ver) return; // Resolve left and right refs - const leftRef = compareLeft[key] || pickDefaultLeft(goldPlatforms); + const leftHadUserChoice = compareLeft[key] != null; + const rightHadUserChoice = compareRight[key] != null; + const leftRef = compareLeft[key] || pickDefaultLeft(goldPlatforms, img); const rightRef = compareRight[key] || pickDefaultRight(img); const leftUrl = resolveImageRef(leftRef, suite, name); const rightUrl = resolveImageRef(rightRef, suite, name); @@ -433,10 +455,10 @@ async function loadDetail(suite, name) { ]); if (detailVersion[key] !== ver) return; - fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }); + fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img, leftHadUserChoice, rightHadUserChoice }); } -async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img }) { +async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPlatforms, leftRef, rightRef, img, leftHadUserChoice, rightHadUserChoice }) { detailVersion[key] = ver; const container = document.getElementById(`images-${id}`); if (!container) return; @@ -492,8 +514,10 @@ async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPl const rightSel = container.querySelectorAll(`select`)[1]; for (const sel of [leftSel, rightSel]) { if (!sel) continue; - const otherRef = sel === leftSel ? rightRef : leftRef; - const otherImgForStats = sel === leftSel ? rightImg : leftImg; + const isLeft = sel === leftSel; + const hadUserChoice = isLeft ? leftHadUserChoice : rightHadUserChoice; + const otherRef = isLeft ? rightRef : leftRef; + const otherImgForStats = isLeft ? rightImg : leftImg; if (!otherImgForStats) continue; const goldOpts = [...sel.options].filter(o => o.value.startsWith('gold:')); // Compute diffs for all gold options, then auto-select best passing one @@ -513,13 +537,17 @@ async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPl optResults.push({ opt, result, diffPixels: s.diffPixels }); } catch {} })); - // If currently selected gold fails, auto-switch to best passing one - const selOpt = sel.options[sel.selectedIndex]; - if (selOpt?.dataset.passed === '0') { - const passing = optResults.filter(r => r.result.passed).sort((a, b) => a.diffPixels - b.diffPixels); - if (passing.length > 0) { - passing[0].opt.selected = true; - sel.dispatchEvent(new Event('change')); + // If currently selected gold fails, auto-switch to best passing one — + // but only when the user hasn't explicitly picked this side, otherwise + // we'd override their choice every time loadDetail re-renders. + if (!hadUserChoice) { + const selOpt = sel.options[sel.selectedIndex]; + if (selOpt?.dataset.passed === '0') { + const passing = optResults.filter(r => r.result.passed).sort((a, b) => a.diffPixels - b.diffPixels); + if (passing.length > 0) { + passing[0].opt.selected = true; + sel.dispatchEvent(new Event('change')); + } } } const updateSelColor = () => { @@ -535,9 +563,20 @@ async function fillDetail(id, key, suite, name, { ver, leftImg, rightImg, goldPl // === Background cell stats === const statsQueue = new Set(); let statsRunning = false; -// Maps "suite:name" → { platform, goldFallback } when a failing image has a passing alternate gold +// "srcId:suite:name" → { checked: bool, passingPlatform: string|null }. +// Populated once the preferred gold has been checked against alternates. +// Drives the framework-style "any gold passes → cell passes" verdict. +const altGoldStatus = {}; +// "suite:name" → { platform } when the row has a primary gold at currentPlatform +// that fails while some alternate passes. Used by Delete Gold to clean up the +// now-unneeded primary. const fixableVia = {}; +function resetAltGoldState() { + Object.keys(altGoldStatus).forEach(k => delete altGoldStatus[k]); + Object.keys(fixableVia).forEach(k => delete fixableVia[k]); +} + function computeCellStats(srcId, suite, name) { const key = `${srcId}:${suite}:${name}`; if (cellStats[key] || statsQueue.has(key)) return; @@ -569,18 +608,13 @@ async function runStatsQueue() { const stats = computeImageDiff(goldImg, srcImg, canvas); cellStats[key] = stats; updateCellInline(key, stats); - // If failing, check fixable inline before updating row tag + // If the preferred gold fails, scan the rest of the suite — the + // framework passes the test if any gold matches, so we do too. const result = checkCellThreshold(suite, name, stats); if (!result.passed) { - const fixKey = `${suite}:${name}`; - await checkFixableVia(suite, name, srcImg, fixKey); - // Now set the row tag with final status - const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(fixKey)}"]`); - if (tagEl) { - tagEl.innerHTML = fixableVia[fixKey] - ? 'failing (fixable)' - : 'failing'; - } + await checkAlternateGold(srcId, suite, name, srcImg); + // Re-render cell and row tag with the final verdict (may flip to pass). + updateCellInline(key, stats); scheduleCountUpdate(); } } catch (e) { @@ -607,52 +641,72 @@ function checkCellThreshold(suite, name, stats) { return { passed: stats.diffPixels === 0, details: [] }; } +// Returns true (pass), false (fail), or null (pending) — pending means the +// preferred gold failed but the alternate-gold scan hasn't finished yet. +function isCellPassing(srcId, suite, name, stats) { + if (checkCellThreshold(suite, name, stats).passed) return true; + const alt = altGoldStatus[`${srcId}:${suite}:${name}`]; + if (!alt || !alt.checked) return null; + return alt.passingPlatform != null; +} + function updateCellInline(key, stats) { const el = document.querySelector(`[data-stats-key="${CSS.escape(key)}"]`); - if (!el) return; const parts = key.split(':'); + const srcId = parts[0]; const suite = parts[1]; const name = parts.slice(2).join(':'); const result = checkCellThreshold(suite, name, stats); - const cls = result.passed ? 'pass' : 'fail'; - el.className = `cell ${cls}`; - el.removeAttribute('style'); - el.removeAttribute('data-stats-key'); - const brief = formatThresholdBrief(result); - el.innerHTML = `${cls === 'pass' ? '✓' : '✗'} ${brief}`; + const passing = isCellPassing(srcId, suite, name, stats); + const cls = passing === true ? 'pass' : passing === false ? 'fail' : 'pending'; + if (el) { + el.className = `cell ${cls}`; + el.removeAttribute('style'); + el.removeAttribute('data-stats-key'); + const icon = passing === true ? '✓' : passing === false ? '✗' : '…'; + const brief = formatThresholdBrief(result); + const viaAlt = passing === true && !result.passed ? ' (via alt)' : ''; + el.innerHTML = `${icon} ${brief}${viaAlt}`; + } // Update the row tag once all sources for this image are resolved const rowKey = `${suite}:${name}`; const data = suiteData[suite]; - if (data) { - let allResolved = true, anyFail = false; - for (const src of sources) { - if (!(data.sourceImages[src.id] || []).some(s => s.name === name)) continue; - const s = cellStats[`${src.id}:${suite}:${name}`]; - if (!s) { allResolved = false; break; } - if (!checkCellThreshold(suite, name, s).passed) anyFail = true; - } - if (allResolved && !anyFail) { - const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(rowKey)}"]`); - if (tagEl) tagEl.innerHTML = ''; - // Hide row if it no longer matches the active filter - const filter = document.getElementById('statusFilter').value; - if (filter && filter !== 'pass') { - const tr = document.querySelector(`tr.row[data-kb-key="${CSS.escape(rowKey)}"]`); - if (tr) { - tr.style.display = 'none'; - // Also hide detail row if expanded - const next = tr.nextElementSibling; - if (next && !next.classList.contains('row') && !next.classList.contains('suite-row')) - next.style.display = 'none'; - } + if (!data) return; + let anyFail = false, anyPending = false; + for (const src of sources) { + if (!(data.sourceImages[src.id] || []).some(s => s.name === name)) continue; + const s = cellStats[`${src.id}:${suite}:${name}`]; + if (!s) { anyPending = true; continue; } + const r = isCellPassing(src.id, suite, name, s); + if (r === null) anyPending = true; + else if (!r) anyFail = true; + } + const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(rowKey)}"]`); + if (tagEl) { + if (anyFail) tagEl.innerHTML = 'failing'; + else if (anyPending) tagEl.innerHTML = '...'; + else tagEl.innerHTML = ''; + } + if (!anyFail && !anyPending) { + // Hide row if it no longer matches the active filter + const filter = document.getElementById('statusFilter').value; + if (filter && filter !== 'pass') { + const tr = document.querySelector(`tr.row[data-kb-key="${CSS.escape(rowKey)}"]`); + if (tr) { + tr.style.display = 'none'; + const next = tr.nextElementSibling; + if (next && !next.classList.contains('row') && !next.classList.contains('suite-row')) + next.style.display = 'none'; } - scheduleCountUpdate(); } + scheduleCountUpdate(); } } -async function checkFixableVia(suite, name, srcImg, fixKey) { - if (fixableVia[fixKey]) return; // already checked +async function checkAlternateGold(srcId, suite, name, srcImg) { + const key = `${srcId}:${suite}:${name}`; + if (altGoldStatus[key]?.checked) return; + let passingPlatform = null; try { const platforms = await fetch(`/api/gold/all?suite=${enc(suite)}&name=${enc(name)}`).then(r => r.json()); for (const p of platforms) { @@ -661,21 +715,21 @@ async function checkFixableVia(suite, name, srcImg, fixKey) { const gImg = await loadImg(`/api/gold/image?suite=${enc(suite)}&platform=${enc(p.platform)}&name=${enc(name)}`); const canvas = new OffscreenCanvas(gImg.width, gImg.height); const s = computeImageDiff(gImg, srcImg, canvas); - const r = checkCellThreshold(suite, name, s); - if (r.passed) { - const device = p.platform.split('/')[1] || p.platform; - fixableVia[fixKey] = { platform: p.platform, goldFallback: currentPlatform }; - if (cellEl) { - cellEl.innerHTML += ` (\u2713 ${esc(device)})`; - } - const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(fixKey)}"]`); - if (tagEl) tagEl.innerHTML = 'failing (fixable)'; - scheduleCountUpdate(); - return; + if (checkCellThreshold(suite, name, s).passed) { + passingPlatform = p.platform; + break; } } catch {} } } catch {} + altGoldStatus[key] = { checked: true, passingPlatform }; + // Record a "fixable" hit only when the primary gold lives at currentPlatform + // — deleting a fallback path would either be a no-op or hurt other platforms. + const goldEntry = suiteData[suite]?.gold.find(g => g.name === name); + if (passingPlatform && goldEntry && goldEntry.fallback == null) { + const fixKey = `${suite}:${name}`; + fixableVia[fixKey] = { platform: passingPlatform, goldFallback: currentPlatform }; + } } async function computeThumbDiff(suite, name, srcId, canvasId) { @@ -825,13 +879,15 @@ function selectAllFailing() { } function selectFixable() { + // With the framework's any-match semantics, "fixable" rows now pass (via an + // alternate gold) while still carrying a stale primary gold at the current + // platform. Selecting them lets the user clean up those redundant primaries. selected.clear(); for (const suite of Object.keys(suiteData)) { - const images = buildSuiteImages(suite); - images.filter(i => i.status === 'fail').forEach(i => { - const fixKey = `${i.suite}:${i.name}`; + for (const img of buildSuiteImages(suite)) { + const fixKey = `${img.suite}:${img.name}`; if (fixableVia[fixKey]) selected.add(fixKey); - }); + } } syncCheckboxes(); updateSelectedCount(); @@ -869,7 +925,7 @@ async function deleteSelectedGold() { alert(`Deleted ${totalDeleted} gold image(s).`); selected.clear(); cellStats = {}; - Object.keys(fixableVia).forEach(k => delete fixableVia[k]); + resetAltGoldState(); await reload(); } @@ -918,6 +974,7 @@ async function promoteSelected() { alert(`Promoted ${totalPromoted} image(s).`); selected.clear(); cellStats = {}; + resetAltGoldState(); compareLeft = {}; compareRight = {}; await reload(); @@ -979,7 +1036,7 @@ function updateActionCounts() { const images = buildSuiteImages(suite); for (const i of images) { if (i.status === 'fail' || i.status === 'new') failCount++; - if (i.status === 'fail' && fixableVia[`${i.suite}:${i.name}`]) fixableCount++; + if (fixableVia[`${i.suite}:${i.name}`]) fixableCount++; } } document.getElementById('failingCount').textContent = failCount; @@ -999,25 +1056,36 @@ function getGfxApi(platform) { return dot >= 0 ? platApi.substring(dot + 1) : platApi; } +function getOS(platform) { + const platApi = platform.split('/')[0]; + const dot = platApi.indexOf('.'); + return dot >= 0 ? platApi.substring(0, dot) : platApi; +} + +function scoreFallback(candidate, requested) { + // Mirrors Program.cs ScoreFallback: exact > same OS > same gfx API > + // same device (WARP↔WARP, Lavapipe↔Lavapipe) > same renderer class. + const cPlatApi = candidate.split('/')[0]; + const rPlatApi = requested.split('/')[0]; + const cDevice = candidate.split('/')[1] || ''; + const rDevice = requested.split('/')[1] || ''; + let score = 0; + if (cPlatApi === rPlatApi) score += 16; + if (getOS(cPlatApi) === getOS(rPlatApi)) score += 8; + if (getGfxApi(cPlatApi) === getGfxApi(rPlatApi)) score += 4; + if (cDevice.toLowerCase() === rDevice.toLowerCase()) score += 2; + if (isSoftwareRenderer(candidate) === isSoftwareRenderer(requested)) score += 1; + return score; +} + function pickBestGoldPlatform(platforms, currentPlatform) { if (!platforms || platforms.length === 0) return currentPlatform; // Exact match const exact = platforms.find(p => p.platform === currentPlatform); if (exact) return exact.platform; - // Score each candidate: same graphics API > same renderer class > any - const currentPlatApi = currentPlatform.split('/')[0]; - const currentGfx = getGfxApi(currentPlatform); - const currentIsSw = isSoftwareRenderer(currentPlatform); let best = null, bestScore = -1; for (const p of platforms) { - const gfx = getGfxApi(p.platform); - const sw = isSoftwareRenderer(p.platform); - // If source is SW, skip HW gold - if (currentIsSw && !sw) continue; - let score = 0; - if (p.platform.split('/')[0] === currentPlatApi) score += 4; // same OS + API - if (gfx === currentGfx) score += 2; // same graphics API (cross-OS) - if (sw === currentIsSw) score += 1; // same renderer class + const score = scoreFallback(p.platform, currentPlatform); if (score > bestScore) { bestScore = score; best = p.platform; } } return best || platforms[0].platform; From adc883111ab7fdd460b4fa0d8408b511c34c62b4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 21:15:58 +0900 Subject: [PATCH 1087/1182] tools: CompareGold: strict primary-gold match, fallback only when missing --- build/tools/Stride.CompareGold/wwwroot/app.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/tools/Stride.CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js index 7b432a68ab..cffd105bf6 100644 --- a/build/tools/Stride.CompareGold/wwwroot/app.js +++ b/build/tools/Stride.CompareGold/wwwroot/app.js @@ -645,6 +645,11 @@ function checkCellThreshold(suite, name, stats) { // preferred gold failed but the alternate-gold scan hasn't finished yet. function isCellPassing(srcId, suite, name, stats) { if (checkCellThreshold(suite, name, stats).passed) return true; + // Graphics.Regression only enumerates fallbacks when the primary gold for + // the current platform doesn't exist. If it does exist, that single file is + // the sole judge — a passing alternate doesn't rescue a failing primary. + const goldEntry = suiteData[suite]?.gold.find(g => g.name === name); + if (goldEntry && goldEntry.fallback == null) return false; const alt = altGoldStatus[`${srcId}:${suite}:${name}`]; if (!alt || !alt.checked) return null; return alt.passingPlatform != null; From 19a34790595c40ac77069a7dc90162a479133fea Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 21:18:06 +0900 Subject: [PATCH 1088/1182] tools: CompareGold: restore "failing (fixable)" tag on deletable primary golds --- build/tools/Stride.CompareGold/wwwroot/app.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build/tools/Stride.CompareGold/wwwroot/app.js b/build/tools/Stride.CompareGold/wwwroot/app.js index cffd105bf6..e7d9ab1435 100644 --- a/build/tools/Stride.CompareGold/wwwroot/app.js +++ b/build/tools/Stride.CompareGold/wwwroot/app.js @@ -309,7 +309,7 @@ function buildRowCells(img, key) { let cells = ` - ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? 'failing' : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} + ${esc(img.name)}${isLoading ? ' ' : ''}${img.status === 'fail' ? `${fixableVia[key] ? 'failing (fixable)' : 'failing'}` : img.status === 'new' ? 'new' : img.status === 'pending' ? '...' : ''} ${img.hasGold ? (img.goldFallback ? 'fb' : 'ref') : '—'}${img.hasGold ? ` ${esc(img.goldFallback || currentPlatform)}` : ''}${goldThumb}`; const activeRef = compareRight[key] || `src:${getSourceForKey(key)}`; @@ -688,8 +688,10 @@ function updateCellInline(key, stats) { } const tagEl = document.querySelector(`[data-row-tag="${CSS.escape(rowKey)}"]`); if (tagEl) { - if (anyFail) tagEl.innerHTML = 'failing'; - else if (anyPending) tagEl.innerHTML = '...'; + if (anyFail) { + const label = fixableVia[rowKey] ? 'failing (fixable)' : 'failing'; + tagEl.innerHTML = `${label}`; + } else if (anyPending) tagEl.innerHTML = '...'; else tagEl.innerHTML = ''; } if (!anyFail && !anyPending) { From d5de5ed6b00a79d643341f4ba5aff93d1f5eb41f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 18:59:52 +0900 Subject: [PATCH 1089/1182] test: adjust some golds --- tests/Stride.Engine.Tests/thresholds.jsonc | 2 +- .../Windows.Vulkan/Lavapipe/TestLightShafts.png | 4 ++-- .../Lavapipe/DynamicFontTest.f3.png | 0 .../Lavapipe/TextBlockTest.f1.png | 0 .../Lavapipe/TextBlockTest.f10.png | 0 .../Lavapipe/TextBlockTest.f2.png | 0 .../Lavapipe/TextBlockTest.f3.png | 0 .../Lavapipe/TextBlockTest.f4.png | 0 .../Lavapipe/TextBlockTest.f5.png | 0 .../Lavapipe/TextBlockTest.f6.png | 0 .../Lavapipe/TextBlockTest.f7.png | 0 .../Lavapipe/TextBlockTest.f8.png | 0 .../Lavapipe/TextBlockTest.f9.png | 0 .../Lavapipe/TextBlockTest.png | 0 14 files changed, 3 insertions(+), 3 deletions(-) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/DynamicFontTest.f3.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f1.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f10.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f2.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f3.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f4.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f5.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f6.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f7.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f8.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.f9.png (100%) rename tests/Stride.UI.Tests.Regression/{Windows.Vulkan => Linux.Vulkan}/Lavapipe/TextBlockTest.png (100%) diff --git a/tests/Stride.Engine.Tests/thresholds.jsonc b/tests/Stride.Engine.Tests/thresholds.jsonc index 4360667ca0..ca10116d49 100644 --- a/tests/Stride.Engine.Tests/thresholds.jsonc +++ b/tests/Stride.Engine.Tests/thresholds.jsonc @@ -14,6 +14,6 @@ // rasterization on a geometry edge; observed across software renderers // (Lavapipe/WARP on Linux/Windows). Tolerated on all platforms. "image": "AnimatedModelTests.f3.png", - "allow": { "3-70": 1, "71+": 0 } + "allow": { "3-70": 1, "71+": 1 } } ] diff --git a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png index b9559b5fcd..b4faabcb3c 100644 --- a/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Vulkan/Lavapipe/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1eb77b8cdf658be28e6f8bf0be8a3bf6e6e9a88d37282e51b6884a422c8a48fe -size 120658 +oid sha256:0e810b95b34774c34bb7540d32d8aa3d91c73bc39c0d5c2c490319c78b19d2c2 +size 120652 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/DynamicFontTest.f3.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/DynamicFontTest.f3.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f1.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f1.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f10.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f10.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f2.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f2.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f3.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f3.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f4.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f4.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f5.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f5.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f6.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f6.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f7.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f7.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f8.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f8.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.f9.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.f9.png diff --git a/tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png similarity index 100% rename from tests/Stride.UI.Tests.Regression/Windows.Vulkan/Lavapipe/TextBlockTest.png rename to tests/Stride.UI.Tests.Regression/Linux.Vulkan/Lavapipe/TextBlockTest.png From b237abadea2d9b2556e47ba9e0805bd2da506379 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 21:29:18 +0900 Subject: [PATCH 1090/1182] fix: D3D11/D3D12: force typeless format for SR-only depth textures --- .../Direct3D11/Texture.Direct3D11.cs | 20 +++++++++++++++---- .../Direct3D12/Texture.Direct3D12.cs | 20 +++++++++++++++---- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/Texture.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/Texture.Direct3D11.cs index 9949fcc052..12d5f4d285 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/Texture.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/Texture.Direct3D11.cs @@ -904,8 +904,11 @@ private Texture1DDesc ConvertToNativeDescription1D() /// The resulting Shader Resource View format. private Format ComputeShaderResourceViewFormat() { - // Special case for Depth-Stencil Shader Resource Views that are bound as Float - var viewFormat = IsDepthStencil + // Depth formats bound as shader resources need a typeless-to-float remap (e.g. + // D32_FLOAT -> R32_FLOAT) to match the typeless storage format the texture was + // created with. Covers both DS+SR and SR-only-depth placeholders. + var needsDepthRemap = IsDepthStencil || (IsShaderResource && IsDepthFormat(ViewFormat)); + var viewFormat = needsDepthRemap ? (Format) ComputeShaderResourceFormatFromDepthFormat(ViewFormat) : (Format) ViewFormat; @@ -970,8 +973,9 @@ private Texture2DDesc ConvertToNativeDescription2D() var format = (Format) textureDescription.Format; var flags = textureDescription.Flags; - // If the Texture is going to be bound as Depth-Stencil, use a typeless format - if (IsDepthStencil) + // Depth formats bound as shader resources must be created as typeless — covers both DS+SR and SR-only. + var needsTypelessDepth = IsDepthStencil || (IsShaderResource && IsDepthFormat(textureDescription.Format)); + if (needsTypelessDepth) { if (IsShaderResource && GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_10_0) { @@ -1168,6 +1172,14 @@ private static int CalculateMipCount(int width, int height, int minimumSizeLastM /// if is a Depth-Stencil format that also contains Stencil data; /// otherwise, . /// + internal static bool IsDepthFormat(PixelFormat format) + { + return format is PixelFormat.D16_UNorm + or PixelFormat.D32_Float + or PixelFormat.D24_UNorm_S8_UInt + or PixelFormat.D32_Float_S8X24_UInt; + } + internal static bool IsStencilFormat(PixelFormat format) { return format switch diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 8ab5dfe836..464e8a6866 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -882,8 +882,11 @@ CpuDescriptorHandle GetUnorderedAccessView(ViewType viewType, int arrayOrDepthSl // Format ComputeShaderResourceViewFormat() { - // Special case for Depth-Stencil Shader Resource View that are bound as Float - var viewFormat = IsDepthStencil + // Depth formats bound as shader resources need a typeless-to-float remap (e.g. + // D32_FLOAT -> R32_FLOAT) to match the typeless storage format the texture was + // created with. Covers both DS+SR and SR-only-depth placeholders. + var needsDepthRemap = IsDepthStencil || (IsShaderResource && IsDepthFormat(ViewFormat)); + var viewFormat = needsDepthRemap ? (Format) ComputeShaderResourceFormatFromDepthFormat(ViewFormat) : (Format) ViewFormat; @@ -1061,8 +1064,9 @@ internal ResourceDesc ConvertToNativeDescription2D() var format = (Format) textureDescription.Format; var flags = textureDescription.Flags; - // If the Texture is going to be bound on the Depth-Stencil, use Typeless format - if (IsDepthStencil) + // Depth formats bound as shader resources must be created as typeless — covers both DS+SR and SR-only. + var needsTypelessDepth = IsDepthStencil || (IsShaderResource && IsDepthFormat(textureDescription.Format)); + if (needsTypelessDepth) { if (IsShaderResource && GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_10_0) { @@ -1123,6 +1127,14 @@ internal ResourceDesc ConvertToNativeDescription2D() /// The View format corresponding to , /// or if no compatible format could be computed. /// + internal static bool IsDepthFormat(PixelFormat format) + { + return format is PixelFormat.D16_UNorm + or PixelFormat.D32_Float + or PixelFormat.D24_UNorm_S8_UInt + or PixelFormat.D32_Float_S8X24_UInt; + } + internal static PixelFormat ComputeShaderResourceFormatFromDepthFormat(PixelFormat format) { var viewFormat = format switch From 485b3456875314934c1b1fd70bc43a6879d16841 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 21:35:59 +0900 Subject: [PATCH 1091/1182] fix: Dispatcher: don't fail-fast when a worker batch throws --- sources/core/Stride.Core/Threading/Dispatcher.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sources/core/Stride.Core/Threading/Dispatcher.cs b/sources/core/Stride.Core/Threading/Dispatcher.cs index 2a3f94ff8f..36d996ce60 100644 --- a/sources/core/Stride.Core/Threading/Dispatcher.cs +++ b/sources/core/Stride.Core/Threading/Dispatcher.cs @@ -9,6 +9,7 @@ using System.Reflection; #endif // PROFILING_SCOPES using System.Runtime.CompilerServices; +using System.Runtime.ExceptionServices; using Stride.Core.Collections; using Stride.Core.Diagnostics; @@ -84,7 +85,7 @@ public static unsafe void ForBatched(int items, TJob batchJob) where TJob var ex = Interlocked.Exchange(ref batch.ExceptionThrown, null); if (ex != null) - throw ex; + ExceptionDispatchInfo.Capture(ex).Throw(); } finally { @@ -126,7 +127,9 @@ private static void ProcessBatch(TJob job, BatchState state) where T catch (Exception e) { Interlocked.Exchange(ref state.ExceptionThrown, e); - throw; + // Unblock the waiter; it rethrows via ExceptionDispatchInfo. Rethrowing here would + // escape the worker thread's root callback and fail-fast the process. + state.Finished.Set(); } } From 18e4f926ee8ebcd683306fc7341c374ebffcac84 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 21:39:32 +0900 Subject: [PATCH 1092/1182] fix: preserve stack trace when rethrowing cross-thread exceptions --- .../Compilers/TestBuildDependencyManager.cs | 3 ++- .../engine/Stride.Video/Android/MediaCodecExtractorBase.cs | 4 ++-- .../NUnitAsync/StaSynchronizationContext.cs | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sources/assets/Stride.Core.Assets.Tests/Compilers/TestBuildDependencyManager.cs b/sources/assets/Stride.Core.Assets.Tests/Compilers/TestBuildDependencyManager.cs index a9add1e810..f0ace04a90 100644 --- a/sources/assets/Stride.Core.Assets.Tests/Compilers/TestBuildDependencyManager.cs +++ b/sources/assets/Stride.Core.Assets.Tests/Compilers/TestBuildDependencyManager.cs @@ -1,3 +1,4 @@ +using System.Runtime.ExceptionServices; using Stride.Core.Assets.Analysis; using Stride.Core.Assets.Compiler; using Stride.Core.BuildEngine; @@ -171,7 +172,7 @@ private static void RethrowAssertsFromThread(Exception? ex) { if (ex != null) { - throw ex; + ExceptionDispatchInfo.Capture(ex).Throw(); } } diff --git a/sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs b/sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs index 048e16968e..67bffb5e7d 100644 --- a/sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs +++ b/sources/engine/Stride.Video/Android/MediaCodecExtractorBase.cs @@ -133,10 +133,10 @@ public void Initialize(IServiceRegistry services, string url, long startPosition StartWorker(); } - catch (Exception e) + catch (Exception) { Release(); - throw e; + throw; } } diff --git a/sources/presentation/Stride.Core.Presentation.Tests/NUnitAsync/StaSynchronizationContext.cs b/sources/presentation/Stride.Core.Presentation.Tests/NUnitAsync/StaSynchronizationContext.cs index ea73c2eab4..b73b4be362 100644 --- a/sources/presentation/Stride.Core.Presentation.Tests/NUnitAsync/StaSynchronizationContext.cs +++ b/sources/presentation/Stride.Core.Presentation.Tests/NUnitAsync/StaSynchronizationContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Runtime.ExceptionServices; using System.Threading; using System.Threading.Tasks; @@ -37,7 +38,7 @@ public override void Send(SendOrPostCallback d, object state) // if there was an exception, throw it on the caller thread, not the // sta thread. if (item.ExecutedWithException) - throw item.Exception; + ExceptionDispatchInfo.Capture(item.Exception).Throw(); } public override void Post(SendOrPostCallback d, object state) From 8a31aac84374183d7d7e9c339b4e5eef5baceb23 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 20 Apr 2026 22:57:58 +0900 Subject: [PATCH 1093/1182] build: reference Stride.Dependencies.Lavapipe unconditionally Restore happens once on the outer project with no StrideGraphicsApi set, so a '$(StrideGraphicsApi)' == 'Vulkan' condition skips restore entirely; the Vulkan inner build then defines STRIDE_GRAPHICS_API_VULKAN and the #if block in Module.cs fails to resolve the namespace. ExcludeAssets='native' still keeps the 70 MB native libs out of output. --- .../Stride.Graphics.Regression.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj index 19d308e51e..3e0db954e9 100644 --- a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj +++ b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj @@ -31,7 +31,7 @@ ExcludeAssets="native" — don't copy it into *this* project's output. PrivateAssets="native" — don't let it flow into transitive consumers (test projects) either. --> - + From a118812056ec252d161fb7a8b52a0840cfb67538 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 00:57:15 +0900 Subject: [PATCH 1094/1182] ci: add hang-dump collection and 20min timeout to test jobs Per-test hang dumps via --blame-hang-timeout 5m --blame-hang-dump-type full (equivalent --Blame:CollectHangDump;TestTimeout=300000;HangDumpType=Full for vstest). Unify all dump types (blame-hang, SEH, .NET unhandled, WER LocalDumps) under TestResults/ and upload as a single test-results- artifact. Job-level timeout-minutes: 20 added to Windows game jobs (Linux and Windows simple already had one). --- .github/workflows/test-linux-game.yml | 16 ++++++++++++ .github/workflows/test-linux-simple.yml | 10 +++++++- .github/workflows/test-windows-game.yml | 30 ++++++++++++++++------- .github/workflows/test-windows-simple.yml | 8 ++++++ 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index 2c49e44015..6a35e8bd01 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -167,6 +167,7 @@ jobs: bin/Tests/Stride.Navigation.Tests/Linux/Vulkan/Stride.Navigation.Tests.dll \ bin/Tests/Stride.Particles.Tests/Linux/Vulkan/Stride.Particles.Tests.dll \ --logger:trx --ResultsDirectory:TestResults \ + '--Blame:CollectHangDump;TestTimeout=300000;HangDumpType=Full' \ -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() @@ -177,6 +178,13 @@ jobs: reporter: dotnet-trx output-to: step-summary list-tests: 'failed' + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-linux-common + path: TestResults/ + if-no-files-found: ignore - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 @@ -252,6 +260,7 @@ jobs: bin/Tests/Stride.Physics.Tests/Linux/Vulkan/Stride.Physics.Tests.dll \ bin/Tests/Stride.UI.Tests/Linux/Vulkan/Stride.UI.Tests.dll \ --logger:trx --ResultsDirectory:TestResults \ + '--Blame:CollectHangDump;TestTimeout=300000;HangDumpType=Full' \ -- RunConfiguration.MaxCpuCount=1 - name: Publish Test Report if: always() @@ -262,6 +271,13 @@ jobs: reporter: dotnet-trx output-to: step-summary list-tests: 'failed' + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-linux-vulkan + path: TestResults/ + if-no-files-found: ignore - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 diff --git a/.github/workflows/test-linux-simple.yml b/.github/workflows/test-linux-simple.yml index a9fac581ec..80c3941da8 100644 --- a/.github/workflows/test-linux-simple.yml +++ b/.github/workflows/test-linux-simple.yml @@ -84,7 +84,8 @@ jobs: bin/Tests/Stride.Core.Assets.Quantum.Tests/Linux/Vulkan/Stride.Core.Assets.Quantum.Tests.dll \ bin/Tests/Stride.Core.Quantum.Tests/Linux/Vulkan/Stride.Core.Quantum.Tests.dll \ bin/Tests/Stride.Core.Presentation.Quantum.Tests/Linux/Vulkan/Stride.Core.Presentation.Quantum.Tests.dll \ - --logger:trx --ResultsDirectory:TestResults + --logger:trx --ResultsDirectory:TestResults \ + '--Blame:CollectHangDump;TestTimeout=300000;HangDumpType=Full' - name: Publish Test Report if: always() uses: phoenix-actions/test-reporting@v15 @@ -94,3 +95,10 @@ jobs: reporter: dotnet-trx output-to: step-summary list-tests: 'failed' + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-linux-simple + path: TestResults/ + if-no-files-found: ignore diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index f7486f2cc6..c00193f03b 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -37,6 +37,7 @@ jobs: Game-Common: name: Test Game Common (${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }}) runs-on: windows-2025-vs2026 + timeout-minutes: 20 env: STRIDE_GRAPHICS_SOFTWARE_RENDERING: "1" STRIDE_TESTS_RENDERDOC: "error" @@ -66,6 +67,7 @@ jobs: dotnet test build\Stride.Tests.Game.slnf ` --no-build ` --logger:trx --results-directory TestResults ` + --blame-hang-timeout 5m --blame-hang-dump-type full ` -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} - name: Publish Test Report if: always() @@ -76,6 +78,13 @@ jobs: reporter: dotnet-trx output-to: step-summary list-tests: 'failed' + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-game-common + path: TestResults/ + if-no-files-found: ignore - name: Upload test artifacts if: always() uses: actions/upload-artifact@v4 @@ -90,6 +99,7 @@ jobs: Game-GraphicsApi: name: Test Game ${{ matrix.graphics-api }} (${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }}) runs-on: windows-2025-vs2026 + timeout-minutes: 20 strategy: fail-fast: false matrix: @@ -98,12 +108,13 @@ jobs: STRIDE_GRAPHICS_SOFTWARE_RENDERING: "1" STRIDE_TESTS_RENDERDOC: "error" STRIDE_MAX_PARALLELISM: "8" - # Crash dump collection (covers 3 crash types): + # Crash dump collection (covers 3 crash types) — all dumps land under TestResults/ + # alongside the .trx logs and the blame-hang dumps from `dotnet test`. STRIDE_TESTS_CRASH_DUMPS: "1" # Type 1: SEHException logging + minidump via FirstChanceException - STRIDE_TESTS_CRASH_DUMP_DIR: "${{ github.workspace }}\\crash-dumps" # Shared dump directory for all crash types + STRIDE_TESTS_CRASH_DUMP_DIR: "${{ github.workspace }}\\TestResults" # Shared dump directory for all crash types DOTNET_DbgEnableMiniDump: "1" # Type 2: .NET unhandled exceptions DOTNET_DbgMiniDumpType: "1" # MiniDumpNormal - DOTNET_DbgMiniDumpName: "${{ github.workspace }}\\crash-dumps\\dotnet_%p.dmp" # Type 2: dump path + DOTNET_DbgMiniDumpName: "${{ github.workspace }}\\TestResults\\dotnet_%p.dmp" # Type 2: dump path steps: - uses: actions/checkout@v4 with: @@ -118,7 +129,7 @@ jobs: # WER DontShowUI: suppress dialogs without disabling dump generation reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting" /v DontShowUI /t REG_DWORD /d 1 /f # WER LocalDumps: capture native crashes (type 3) - $dumpDir = "${{ github.workspace }}\crash-dumps" + $dumpDir = "${{ github.workspace }}\TestResults" New-Item -Path $dumpDir -ItemType Directory -Force | Out-Null reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d $dumpDir /f reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 1 /f @@ -167,6 +178,7 @@ jobs: dotnet test build\Stride.Tests.Game.GPU.slnf ` --no-build ` --logger:trx --results-directory TestResults ` + --blame-hang-timeout 5m --blame-hang-dump-type full ` -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} ` -p:StrideGraphicsApis=${{ matrix.graphics-api }} ` -p:StrideGraphicsApi=${{ matrix.graphics-api }} ` @@ -184,8 +196,8 @@ jobs: if: always() shell: pwsh run: | - $dumpDir = "${{ github.workspace }}\crash-dumps" - if (Get-ChildItem $dumpDir -Filter *.dmp -ErrorAction SilentlyContinue) { + $dumpDir = "${{ github.workspace }}\TestResults" + if (Get-ChildItem $dumpDir -Recurse -Filter *.dmp -ErrorAction SilentlyContinue) { $symDir = Join-Path $dumpDir "symbols" New-Item -Path $symDir -ItemType Directory -Force | Out-Null Get-ChildItem bin -Recurse -Include *.pdb,*.dll,*.exe | Copy-Item -Destination $symDir @@ -198,10 +210,10 @@ jobs: name: test-artifacts-game-${{ matrix.graphics-api }} path: tests/local/ if-no-files-found: ignore - - name: Upload crash dumps + - name: Upload test results if: always() uses: actions/upload-artifact@v4 with: - name: crash-dumps-game-${{ matrix.graphics-api }} - path: crash-dumps/ + name: test-results-game-${{ matrix.graphics-api }} + path: TestResults/ if-no-files-found: ignore diff --git a/.github/workflows/test-windows-simple.yml b/.github/workflows/test-windows-simple.yml index 7b429efb34..780fb1a615 100644 --- a/.github/workflows/test-windows-simple.yml +++ b/.github/workflows/test-windows-simple.yml @@ -49,6 +49,7 @@ jobs: dotnet test build\Stride.Tests.Simple.slnf ` --no-build ` --logger:trx --results-directory TestResults ` + --blame-hang-timeout 5m --blame-hang-dump-type full ` -p:Configuration=${{ github.event.inputs.build-type || inputs.build-type || 'Debug' }} - name: Publish Test Report if: always() @@ -59,3 +60,10 @@ jobs: reporter: dotnet-trx output-to: step-summary list-tests: 'failed' + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-simple + path: TestResults/ + if-no-files-found: ignore From d482e029250018c6a8fc511186a1809db0330165 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 10:12:28 +0900 Subject: [PATCH 1095/1182] fix: Vulkan: copy full subresource (slice * depth) when initializing 3D textures InitializeData was sizing the upload buffer and per-slice memcpy by SlicePitch alone, but for a 3D texture the full subresource is SlicePitch * Depth. Only the first depth slice was copied; the rest of the upload region was whatever stale bytes the bump-allocated staging ring buffer happened to hold. vkCmdCopyBufferToImage then read the full Depth slices from staging, so slices 1..Depth-1 were uploaded as garbage. This was masked locally because a freshly allocated upload buffer is zero-initialized and the existing test happened to use mostly-zero data; on CI / Linux Lavapipe (where prior tests had populated the buffer) the readback assert failed. Also widen the test data to a deterministic non-zero pattern so the upload path is exercised end-to-end and the bug doesn't get masked again. --- .../engine/Stride.Graphics.Tests/TestTexture.cs | 15 +++++++++++---- .../Stride.Graphics/Vulkan/Texture.Vulkan.cs | 14 ++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Graphics.Tests/TestTexture.cs b/sources/engine/Stride.Graphics.Tests/TestTexture.cs index 006fc3d2b2..0eb86e9e99 100644 --- a/sources/engine/Stride.Graphics.Tests/TestTexture.cs +++ b/sources/engine/Stride.Graphics.Tests/TestTexture.cs @@ -236,10 +236,17 @@ public void TestTexture3D() { var device = game.GraphicsDevice; - // Check Texture creation with an array of data, with usage default to later allow SetData - var data = new byte[32 * 32 * 32]; - data[0] = 255; - data[31] = 1; + // Check Texture creation with an array of data, with usage default to later allow SetData. + // Encode (slice, row, col) into each byte so that any misalignment of slice or row + // start in the upload/readback path produces a recognisable mismatch: byte == + // (sliceIndex * 17 ^ rowIndex * 3 ^ colIndex). The 17/3 multipliers keep slice and + // row contributions distinct mod 256. + const int width = 32, height = 32, depth = 32; + var data = new byte[width * height * depth]; + for (int s = 0; s < depth; s++) + for (int r = 0; r < height; r++) + for (int c = 0; c < width; c++) + data[s * width * height + r * width + c] = (byte)((s * 17) ^ (r * 3) ^ c); var texture = Texture.New3D(device, width: 32, height: 32, depth: 32, PixelFormat.R8_UNorm, data, usage: GraphicsResourceUsage.Default); diff --git a/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs index 9bc6eb32b9..bce48e62f8 100644 --- a/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs @@ -306,10 +306,14 @@ private unsafe void InitializeData(DataBox[] dataBoxes) var blockSize = Format.BlockSize; var alignmentMask = (blockSize < 4 ? 4 : blockSize) - 1; + // SlicePitch in a DataBox is the size of one depth slice; for 3D textures the + // full subresource size is SlicePitch * Depth. Account for that or the upload + // buffer is undersized and slices 1..Depth-1 read stale ring-buffer bytes. int totalSize = dataBoxes.Length * alignmentMask; for (int i = 0; i < dataBoxes.Length; i++) { - totalSize += dataBoxes[i].SlicePitch; + var mipSlice = i % MipLevelCount; + totalSize += dataBoxes[i].SlicePitch * GetMipMapDescription(mipSlice).Depth; } var uploadMemory = GraphicsDevice.AllocateUploadBuffer(totalSize, out var uploadResource, out var uploadOffset); @@ -338,12 +342,14 @@ private unsafe void InitializeData(DataBox[] dataBoxes) int arraySlice = i / MipLevelCount; int mipSlice = i % MipLevelCount; var mipMapDescription = GetMipMapDescription(mipSlice); + // Full subresource = one slice (slicePitch) * Depth; for 2D Depth==1. + var subresourceSize = slicePitch * mipMapDescription.Depth; var alignment = ((uploadOffset + alignmentMask) & ~alignmentMask) - uploadOffset; uploadMemory += alignment; uploadOffset += alignment; - MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemory, (void*) (dataBoxes[i].DataPointer), (uint) slicePitch); + MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemory, (void*) (dataBoxes[i].DataPointer), (uint) subresourceSize); if (Usage == GraphicsResourceUsage.Staging) { @@ -373,8 +379,8 @@ private unsafe void InitializeData(DataBox[] dataBoxes) GraphicsDevice.NativeDeviceApi.vkCmdCopyBufferToImage(commandBuffer, uploadResource, NativeImage, VkImageLayout.TransferDstOptimal, regionCount: 1, ©); } - uploadMemory += slicePitch; - uploadOffset += slicePitch; + uploadMemory += subresourceSize; + uploadOffset += subresourceSize; } if (Usage == GraphicsResourceUsage.Staging) From 3ac0de1bb0c6635c9990e3f5f4c2b6d4a09eb7be Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 11:19:30 +0900 Subject: [PATCH 1096/1182] fix: cap CPU-GPU frame lag to bound deferred-release queues D3D12 and Vulkan release dynamic per-frame resources (upload buffers, descriptor pools) via a fence-tagged queue: a resource becomes reusable only after the GPU has finished the frame that last touched it. With a Present-driven swapchain the vsync/present-latency loop keeps the CPU within a few frames of the GPU, but in headless / offscreen rendering there is no such throttle. On software back-ends (WARP, Lavapipe) the CPU submits orders of magnitude faster than the GPU completes, so the queue grows unbounded and eventually triggers E_OUTOFMEMORY on CreateCommittedResource (~17 GB of committed upload-heap resources observed on CI for a single UI regression test run). Block at the frame boundary (GraphicsDevice.End) until the GPU has caught up to MaxFramesInFlight (3) frames behind the CPU, and drain the just-released queue so the pool can reuse. Kept internal: this is a back-end implementation detail, not public API. --- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 7 +++++++ sources/engine/Stride.Graphics/GraphicsDevice.cs | 3 +++ .../engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 9e965cec97..8d903247d0 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -274,6 +274,13 @@ public void End() { FrameFence.Signal(nativeCommandQueue, FrameFence.NextFenceValue); FrameFence.NextFenceValue++; + + // Throttle CPU ahead of GPU so the deferred-release queue stays bounded. + if (FrameFence.NextFenceValue > (ulong)MaxFramesInFlight) + { + FrameFence.WaitForFenceCPUInternal(FrameFence.NextFenceValue - (ulong)MaxFramesInFlight); + FrameTemporaryResources.ReleaseCompleted(FrameFence); + } } /// diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.cs b/sources/engine/Stride.Graphics/GraphicsDevice.cs index d06d3188f0..beed4a5a99 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.cs @@ -483,5 +483,8 @@ internal void RegisterBufferMemoryUsage(long memoryChange) /// A object identifying the Graphics Resource along some related allocation information. /// internal partial void TagResourceAsNotAlive(GraphicsResourceLink resourceLink); + + /// Maximum frames the CPU is allowed to be ahead of the GPU (bounds deferred-release queues). + internal const int MaxFramesInFlight = 3; } } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index 11ec1ce6db..0ad3c061b4 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -220,6 +220,13 @@ public unsafe void End() CheckResult(NativeDeviceApi.vkQueueSubmit(NativeCommandQueue, 1, &submitInfo, VkFence.Null)); } + + // Throttle CPU ahead of GPU so the deferred-release queue stays bounded. + if (FrameFence.NextFenceValue > (ulong)MaxFramesInFlight) + { + FrameFence.WaitForFenceCPUInternal(FrameFence.NextFenceValue - (ulong)MaxFramesInFlight); + graphicsResourceLinkCollector.Release(); + } } /// From a0c2f25cbca79fd02674d667cb14841db31418f6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 15:14:18 +0900 Subject: [PATCH 1097/1182] build: add EnableDefaultStrideShaderItems opt-out for shader auto-discovery The SDK was auto-injecting Stride.Shaders.Generators (net10.0) as an Analyzer ProjectReference for any project containing .sdsl/.sdfx files. MSBuild then failed .NET Framework consumers (Stride.VisualStudio.Package.Tests with its TestGenerator.sdsl sample) with a cross-TFM reference error. Introduce EnableDefaultStrideShaderItems (default true) mirroring the .NET SDK's EnableDefaultCompileItems pattern: projects that contain .sdsl/.sdfx files as test inputs or non-shader content opt out with false. The VS Package tests set it since their .sdsl file is fed to the in-VS Custom Tool generator, not the Roslyn source generator. --- sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets | 12 +++++++++--- .../Stride.VisualStudio.Package.Tests.csproj | 4 ++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets index 4573b793c3..d0f543b327 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets @@ -77,9 +77,15 @@ - - + + + true + + diff --git a/sources/tools/Stride.VisualStudio.Package.Tests/Stride.VisualStudio.Package.Tests.csproj b/sources/tools/Stride.VisualStudio.Package.Tests/Stride.VisualStudio.Package.Tests.csproj index 6381da5cb5..5b6f2c9a17 100644 --- a/sources/tools/Stride.VisualStudio.Package.Tests/Stride.VisualStudio.Package.Tests.csproj +++ b/sources/tools/Stride.VisualStudio.Package.Tests/Stride.VisualStudio.Package.Tests.csproj @@ -10,6 +10,10 @@ true --auto-module-initializer false + + false From 72af300b6a0cecf05c2d3fc208e4d90fa7afe952 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 16:31:39 +0900 Subject: [PATCH 1098/1182] fix: D3D12: defer-release previous ID3D12Resource on Buffer.Recreate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Buffer.Recreate called SetNativeDeviceChild with a new committed resource without releasing the previous one. SetNativeDeviceChild is a transfer- ownership API (no refcount handling), so the prior ID3D12Resource was orphaned with refcount=1 and leaked every time. On long-running UI tests that Recreate dynamic vertex/index buffers per batch, this compounded to the OOM we bandaged with the frames-in-flight cap. Enqueue the previous native resource into FrameTemporaryResources so its Release fires once the GPU fence catches up. Don't go through OnDestroyed because the managed Buffer is still alive — firing the Destroyed event would be misleading. --- .../Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index 28586875ef..0b731e0eb2 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -207,6 +207,14 @@ public void Recreate(IntPtr dataPointer) if (result.IsFailure) result.Throw(); + // Defer-release the previous native resource — SetNativeDeviceChild otherwise + // leaks the prior ref on repeated Recreate. Avoid OnDestroyed so Destroyed doesn't fire. + if (NativeDeviceChild.IsNotNull()) + { + GraphicsDevice.FrameTemporaryResources.Enqueue(GraphicsDevice.FrameFence.NextFenceValue, NativeResource); + UnsetNativeDeviceChild(); + } + SetNativeDeviceChild(buffer.AsDeviceChild()); GPUVirtualAddress = NativeResource.GetGPUVirtualAddress(); From 3224d2db3e20e782993abdac8163eedd269e8350 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 16:37:13 +0900 Subject: [PATCH 1099/1182] fix: D3D shader compiler: report failures that produce no bytecode FXC occasionally returns HRESULT failure with a null or mis-prefixed error blob (e.g. 'internal error: argument pulled into unrelated predicate' lacks the ': error' token), leaving bytecodeResult with no errors and a null Bytecode. EffectCompiler then NRE'd on 'result.Bytecode!.Id'. - Route 'internal error' FXC lines to Error (not Info). - Emit a synthetic error if a failed compile produced no diagnostic. - Guard EffectCompiler against a silent null bytecode with an actionable log message. --- .../Direct3D/ShaderCompiler.cs | 10 +++++++++- .../shaders/Stride.Shaders.Compilers/EffectCompiler.cs | 7 +++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index 7e48bd784a..ff0aede733 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -197,6 +197,13 @@ HResult Compile() { ProcessCompilerErrors(compileErrors, bytecodeResult); } + + // Guarantee at least one error is recorded on failure — FXC occasionally returns + // a failure HRESULT with no blob or with messages we don't recognise as errors. + if (!bytecodeResult.HasErrors) + { + bytecodeResult.Error($"D3D shader compilation failed for stage '{stage}' entry '{entryPoint}' profile '{shaderModel}' (HRESULT 0x{(uint)result.Value:X8}) with no diagnostic from D3DCompiler."); + } } return result; @@ -212,7 +219,8 @@ static void ProcessCompilerErrors(ComPtr compileErrors, ShaderByteco string? line; while ((line = reader.ReadLine()) != null) { - if (line.Contains(": error")) + // FXC emits "internal error: ..." without a ": error" prefix, so match it explicitly. + if (line.Contains(": error") || line.Contains("internal error")) bytecodeResult.Error(line); else if (line.Contains(": warning")) bytecodeResult.Warning(line); diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index ba7e0020ee..00972be61d 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -264,6 +264,13 @@ public override TaskOrResult Compile(ShaderMixinSo continue; } + // Guard against a silent null bytecode (actionable message instead of NRE below). + if (result.Bytecode is null) + { + log.Error($"Shader compilation for stage {shaderStage} (entry '{entryPoint.TranslatedName}') produced no bytecode and no error."); + continue; + } + // ------------------------------------------------------- // Append bytecode id to shader log #if STRIDE_PLATFORM_DESKTOP From 42e31797c5cf900a1c0bb6391c2624391f197571 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 16:37:22 +0900 Subject: [PATCH 1100/1182] fix: SDSL: demote non-stage reference notices from warning to info Stage methods referencing non-stage members are merely flagged as affecting mixin import behaviour; they are not defects in the shader. Report them at Info severity so they do not clutter user builds with warnings on Stride's own builtin shaders. --- sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs | 3 +++ .../Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs | 6 ++++++ .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs | 2 +- .../Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs index b601cd95d6..dca18c9c91 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/SDSLC.cs @@ -92,6 +92,9 @@ public readonly bool Compile(string? filename, string code, ObjectId hash, ReadO } } + foreach (var info in table.Infos) + log.Info(info.ToString()); + foreach (var warning in table.Warnings) log.Warning(warning.ToString()); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs index e453dc1ace..a97dfa6cb3 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/Analysis/SymbolTable.cs @@ -54,6 +54,7 @@ public partial class SymbolTable : ISymbolProvider public RootSymbolFrame RootSymbols { get; } public List Errors { get; } = []; public List Warnings { get; } = []; + public List Infos { get; } = []; // Used by Identifier.ResolveSymbol public SymbolFrame CurrentFrame => CurrentSymbols[^1]; @@ -156,4 +157,9 @@ public void AddWarning(SemanticError warning) { Warnings.Add(warning); } + + public void AddInfo(SemanticError info) + { + Infos.Add(info); + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs index ed9ba7b26a..c7a5c1eca4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Expression.cs @@ -259,7 +259,7 @@ public override SpirvValue CompileImpl(SymbolTable table, CompilerUnit compiler) // Self: mark current function builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; } - table.AddWarning(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage method '{calleeOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + table.AddInfo(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage method '{calleeOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); } result = builder.CallFunction(table, context, functionSymbol, [.. compiledParams]); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs index 628253a2a6..49430ab67b 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/Literals.cs @@ -463,7 +463,7 @@ protected virtual SpirvValue CompileSymbol(SymbolTable table, SpirvBuilder build { builder.CurrentFunction = builder.CurrentFunction.Value with { ReferencesNonStageMembers = true }; } - table.AddWarning(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage variable '{varOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); + table.AddInfo(new(Info, $"Stage method '{table.CurrentShader?.Name}.{builder.CurrentFunction.Value.Name}' references non-stage variable '{varOwner?.Name ?? "?"}.{Name}'. This will cause the shader to be fully imported at root level instead of stage-only when used in a composition.")); } return EmitSymbol(builder, context, symbol, constantOnly); From 4b43ca2f4e8ea31df852a9032fc2819901c619b0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 16:51:41 +0900 Subject: [PATCH 1101/1182] fix: SDFX generator: hard-error on 'shader' declaration in .sdfx file A .sdfx containing 'partial shader Foo' used to silently emit broken C# (mixin syntax inside a generated class, failing with CS0246 on the 'mixin' parameter name). Detect a ShaderClass declaration in a .sdfx file and emit a clear #error directing the user to use 'effect' or 'partial effect' instead. --- .../EffectGenerator.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs index 87057feb02..97e9253c05 100644 --- a/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators/EffectGenerator.cs @@ -22,6 +22,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, AdditionalText arg2) { var filename = GetSafeHintName(arg2.Path); + var isSdfx = Path.GetExtension(arg2.Path).Equals(".sdfx", StringComparison.OrdinalIgnoreCase); try { @@ -41,6 +42,14 @@ private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, Addition return; } + // .sdfx files must declare 'effect', not 'shader' — catch the mistake here + // instead of silently emitting unbuildable C#. + if (isSdfx && parsed.AST is Parsing.ShaderFile sdfxFile && HasShaderClassDeclaration(sdfxFile)) + { + arg1.AddSource(filename, $"#error '{Path.GetFileName(arg2.Path)}' contains a 'shader' declaration. Use 'effect' (or 'partial effect') inside .sdfx files; 'shader' / 'partial shader' belongs in .sdsl."); + return; + } + var effectCodeWriter = new EffectCodeWriter(); effectCodeWriter.Run(parsed.AST); arg1.AddSource(filename, effectCodeWriter.Text); @@ -53,6 +62,18 @@ private void GenerateShaderKeysAndEffects(SourceProductionContext arg1, Addition } } + private static bool HasShaderClassDeclaration(Parsing.ShaderFile ast) + { + foreach (var d in ast.RootDeclarations) + if (d is Parsing.SDSL.AST.ShaderClass) + return true; + foreach (var ns in ast.Namespaces) + foreach (var d in ns.Declarations) + if (d is Parsing.SDSL.AST.ShaderClass) + return true; + return false; + } + public static string GetSafeHintName(string absolutePath) { // 1. Get the file name without extension (e.g., "MyConfig") From 37c0dbd06b52e84e15524815a00906bd25c8ba24 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 17:24:48 +0900 Subject: [PATCH 1102/1182] fix: SPIR-V generator: emit SPV0001 diagnostic and treat CS8785 as error --- .../Stride.Shaders.Spirv.Core.csproj | 2 ++ .../SPVGenerator.Helpers.Preprocessing.cs | 8 +------ .../SPVGenerator.cs | 24 +++++++++++++++++-- .../Stride.Shaders.Spirv.Generators.csproj | 2 ++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 449111b081..45e6463607 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -7,6 +7,8 @@ enable enable * + + $(WarningsAsErrors);CS8785 diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 04032e68f0..5c643dce87 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -24,13 +24,7 @@ public static bool IsSpirvSpecification(AdditionalText file) public SpirvGrammar PreProcessGrammar(ImmutableArray files, CancellationToken _) { - var fileNames = new HashSet(files.Select(f => Path.GetFileName(f.Path))); - var missing = RequiredFiles.Where(r => !fileNames.Contains(r)).ToArray(); - // TODO: Proper Roslyn diagnostics - if (missing.Length > 0) - throw new InvalidOperationException( - $"Missing SPIR-V specification files: {string.Join(", ", missing)}. Ensure git submodules are fetched (git submodule update --init)."); - + // Note: Missing files are reported as SPV0001 via the RegisterSourceOutput check in Initialize SpirvGrammar grammar = new(); foreach (var file in files) { diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 0fda57a4b6..82a667ad88 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -12,6 +12,14 @@ public partial class SPVGenerator : IIncrementalGenerator { static readonly JsonSerializerOptions options = new(); + internal static readonly DiagnosticDescriptor MissingSpecDiagnostic = new( + id: "SPV0001", + title: "Missing SPIR-V specification files", + messageFormat: "Missing SPIR-V specification files: {0}. Run 'git submodule update --init --recursive'.", + category: "SpirvGenerator", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + public void Initialize(IncrementalGeneratorInitializationContext context) { if (!options.Converters.Any(x => x is EquatableListJsonConverter)) @@ -26,11 +34,23 @@ public void Initialize(IncrementalGeneratorInitializationContext context) options.Converters.Add(new EquatableListJsonConverter()); if (!options.Converters.Any(x => x is EquatableListJsonConverter)) options.Converters.Add(new EquatableListJsonConverter()); - var grammarData = + var files = context .AdditionalTextsProvider .Where(IsSpirvSpecification) - .Collect() + .Collect(); + + // Emit SPV0001 if any required grammar file is missing (submodule not fetched). + context.RegisterSourceOutput(files, static (spc, texts) => + { + var fileNames = new HashSet(texts.Select(f => Path.GetFileName(f.Path))); + var missing = RequiredFiles.Where(r => !fileNames.Contains(r)).ToArray(); + if (missing.Length > 0) + spc.ReportDiagnostic(Diagnostic.Create(MissingSpecDiagnostic, Location.None, string.Join(", ", missing))); + }); + + var grammarData = + files .Select(PreProcessGrammar) .Select(PreProcessEnumerants) .Select(PreProcessInstructions); diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 356816918e..4577a57a01 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -6,6 +6,8 @@ enable enable true + + $(NoWarn);RS2008 From c2a1e2ddc26715b2127edf8e7a7a5ecc5a339093 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 17:24:53 +0900 Subject: [PATCH 1103/1182] fix: shader intrinsics generator: emit SHG0001 when gen_intrin_main.txt is missing --- .../IntrinsicGenerator.cs | 15 +++++++++++++++ .../Stride.Shaders.Generators.Internal.csproj | 2 ++ 2 files changed, 17 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs index 298507b3cc..834eac1d0b 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/IntrinsicGenerator.cs @@ -12,8 +12,23 @@ namespace Stride.Shaders.Generators; [Generator] internal class IntrinsicsGenerator : IIncrementalGenerator { + internal static readonly DiagnosticDescriptor MissingIntrinsicsDiagnostic = new( + id: "SHG0001", + title: "Missing intrinsics definition file", + messageFormat: "'gen_intrin_main.txt' was not supplied to the intrinsics generator. Expected as an AdditionalFiles entry.", + category: "ShaderGenerator", + defaultSeverity: DiagnosticSeverity.Error, + isEnabledByDefault: true); + public void Initialize(IncrementalGeneratorInitializationContext context) { + var allTexts = context.AdditionalTextsProvider.Collect(); + context.RegisterSourceOutput(allTexts, static (spc, texts) => + { + if (!texts.Any(x => x.Path.EndsWith("gen_intrin_main.txt"))) + spc.ReportDiagnostic(Diagnostic.Create(MissingIntrinsicsDiagnostic, Location.None)); + }); + var file = context .AdditionalTextsProvider diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj b/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj index f1288c5cc2..a59c0d1f00 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj +++ b/sources/shaders/Stride.Shaders.Generators.Internal/Stride.Shaders.Generators.Internal.csproj @@ -7,6 +7,8 @@ enable true Stride.Shaders.Generators + + $(NoWarn);RS2008 From 1c3cbb64aec4bb8fa2523921569fe2087c802630 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 21:44:45 +0900 Subject: [PATCH 1104/1182] fix: emit StorageImageReadWithoutFormat capability when shader reads format-less storage image --- .../Stride.Shaders.Compilers/SDSL/ShaderMixer.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs index 20697914df..9ea82cfb1a 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.cs @@ -188,6 +188,22 @@ private static void AddRequiredCapabilities(SpirvContext context, SpirvBuffer te break; } } + { + bool hasImageRead = false; + foreach (var i in temp) + if (i.Op == Op.OpImageRead) { hasImageRead = true; break; } + if (hasImageRead) + { + foreach (var i in context) + { + if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.Sampled is 2 && typeImage.ImageFormat == ImageFormat.Unknown) + { + context.Add(new OpCapability(Capability.StorageImageReadWithoutFormat)); + break; + } + } + } + } foreach (var i in context) { if (i.Op == Op.OpTypeImage && (OpTypeImage)i is { } typeImage && typeImage.ImageFormat is From caaedd4fb9fbf91de856816c2bb4c4425aa16232 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 18:25:15 +0900 Subject: [PATCH 1105/1182] build: setup SpirvTools workflow to be used as a native dependency --- .github/workflows/dep-spirv-tools.yml | 348 +++++++++++++++++- .github/workflows/main.yml | 54 +-- build/deps/spirv-tools/CMakeLists.txt | 57 +++ .../Stride.Dependencies.SPIRVTools.csproj | 26 ++ build/deps/spirv-tools/stride_spvopt_shim.cpp | 88 +++++ .../Spirv/Tools/SpirvTools.cs | 312 ++++++++++++++++ .../Spirv/Tools/Validator.cs | 83 +---- .../Stride.Shaders.Parsers.csproj | 2 + 8 files changed, 863 insertions(+), 107 deletions(-) create mode 100644 build/deps/spirv-tools/CMakeLists.txt create mode 100644 build/deps/spirv-tools/Stride.Dependencies.SPIRVTools.csproj create mode 100644 build/deps/spirv-tools/stride_spvopt_shim.cpp create mode 100644 sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs diff --git a/.github/workflows/dep-spirv-tools.yml b/.github/workflows/dep-spirv-tools.yml index 2803c382aa..0e93300c68 100644 --- a/.github/workflows/dep-spirv-tools.yml +++ b/.github/workflows/dep-spirv-tools.yml @@ -1,8 +1,22 @@ name: "Dep: Build & Deploy SPIRV-Tools" -# Skeleton workflow — the full implementation lives on a feature branch. -# This exists on master only so the workflow is triggerable via workflow_dispatch -# with the expected inputs. Checkout the feature branch ref to run the real build. +# Ships a single combined library — stride_spirv_tools — that bundles +# SPIRV-Tools-static + SPIRV-Tools-opt + a thin C shim (stride_spvopt_shim.cpp), +# re-exporting both the upstream libspirv.h C API (validator, etc.) and our +# stride_spv* optimizer entry points. See build/deps/spirv-tools/CMakeLists.txt. +# +# Upstream: https://github.com/KhronosGroup/SPIRV-Tools +# Dependencies fetched via `python utils/git-sync-deps` (gets SPIRV-Headers). +# +# Output per OS — one DLL to ship per RID: +# Windows: stride_spirv_tools.dll +# Linux: libstride_spirv_tools.so +# macOS: libstride_spirv_tools.dylib +# iOS: libstride_spirv_tools.dylib (cross-compiled on macOS) +# Android: libstride_spirv_tools.so (cross-compiled via NDK) +# +# RIDs covered: win-x64, win-arm64, linux-x64, osx-arm64, ios-arm64, +# android-arm64, android-x64. on: workflow_dispatch: @@ -20,11 +34,327 @@ on: required: false jobs: - placeholder: - name: Skeleton (run on feature branch for real build) - runs-on: ubuntu-latest + # --------------------------------------------------------------------------- + # Windows x64 + # --------------------------------------------------------------------------- + build-windows-x64: + name: Build SPIRV-Tools (Windows x64) + runs-on: windows-2025-vs2026 steps: - - name: Notice + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + shell: pwsh + run: | + $url = "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + $ref = "${{ github.event.inputs.ref || 'main' }}" + git init spirv-tools-src + git -C spirv-tools-src remote add origin $url + git -C spirv-tools-src fetch --depth 1 origin $ref + git -C spirv-tools-src checkout FETCH_HEAD + python spirv-tools-src/utils/git-sync-deps + + - uses: ilammy/msvc-dev-cmd@v1 + with: { arch: x64 } + + - name: Configure & build stride_spirv_tools + shell: cmd + run: | + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DSPIRV_TOOLS_SOURCE_DIR=%CD%/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + shell: pwsh + run: | + mkdir spirv-tools-out + Copy-Item _build/stride_spirv_tools.dll spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: { name: spirv-tools-win-x64, path: spirv-tools-out/ } + + # --------------------------------------------------------------------------- + # Windows ARM64 — same host, MSVC ARM64 cross-compile. + # --------------------------------------------------------------------------- + build-windows-arm64: + name: Build SPIRV-Tools (Windows ARM64) + runs-on: windows-2025-vs2026 + steps: + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + shell: pwsh + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + python spirv-tools-src/utils/git-sync-deps + + - uses: ilammy/msvc-dev-cmd@v1 + with: { arch: amd64_arm64 } + + - name: Configure & build stride_spirv_tools + shell: cmd + run: | + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DSPIRV_TOOLS_SOURCE_DIR=%CD%/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + shell: pwsh + run: | + mkdir spirv-tools-out + Copy-Item _build/stride_spirv_tools.dll spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: { name: spirv-tools-win-arm64, path: spirv-tools-out/ } + + # --------------------------------------------------------------------------- + # Linux x64 + # --------------------------------------------------------------------------- + build-linux-x64: + name: Build SPIRV-Tools (Linux x64) + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + python3 spirv-tools-src/utils/git-sync-deps + + - name: Install build dependencies + run: sudo apt-get update && sudo apt-get install -y ninja-build cmake + + - name: Configure & build stride_spirv_tools + run: | + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DSPIRV_TOOLS_SOURCE_DIR=$PWD/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + run: | + mkdir -p spirv-tools-out + cp _build/libstride_spirv_tools.so spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: { name: spirv-tools-linux-x64, path: spirv-tools-out/ } + + # --------------------------------------------------------------------------- + # macOS ARM64 + # --------------------------------------------------------------------------- + build-macos-arm64: + name: Build SPIRV-Tools (macOS ARM64) + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + python3 spirv-tools-src/utils/git-sync-deps + + - name: Configure & build stride_spirv_tools + run: | + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DSPIRV_TOOLS_SOURCE_DIR=$PWD/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + run: | + mkdir -p spirv-tools-out + cp _build/libstride_spirv_tools.dylib spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: { name: spirv-tools-osx-arm64, path: spirv-tools-out/ } + + # --------------------------------------------------------------------------- + # iOS ARM64 — cross-compiled on macOS. + # Note: BUILD_SHARED_LIBS on iOS produces dylibs; if App Store requires + # static-only or .framework bundles, revisit once integration lands. + # --------------------------------------------------------------------------- + build-ios-arm64: + name: Build SPIRV-Tools (iOS ARM64) + runs-on: macos-15 + steps: + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + python3 spirv-tools-src/utils/git-sync-deps + + - name: Configure & build stride_spirv_tools + run: | + # Ninja, not Xcode: SPIRV-Tools' build-version.inc custom command is + # attached to both SPIRV-Tools-shared and SPIRV-Tools-static, which + # the Xcode "new build system" rejects (no common dependency). + # CMAKE_OSX_SYSROOT must be set explicitly because Ninja doesn't + # auto-detect the iOS SDK path like the Xcode generator does. + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=iOS \ + -DCMAKE_OSX_ARCHITECTURES=arm64 \ + -DCMAKE_OSX_SYSROOT=iphoneos \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=13.0 \ + -DSPIRV_TOOLS_SOURCE_DIR=$PWD/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + run: | + mkdir -p spirv-tools-out + cp _build/libstride_spirv_tools.dylib spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: { name: spirv-tools-ios-arm64, path: spirv-tools-out/ } + + # --------------------------------------------------------------------------- + # Android — one job per ABI, cross-compiled via NDK toolchain file. + # --------------------------------------------------------------------------- + build-android: + name: Build SPIRV-Tools (Android ${{ matrix.abi }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - { abi: arm64-v8a, rid: android-arm64 } + - { abi: x86_64, rid: android-x64 } + steps: + - uses: actions/checkout@v4 + with: { path: stride-src, sparse-checkout: build/deps/spirv-tools } + + - name: Clone SPIRV-Tools + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + python3 spirv-tools-src/utils/git-sync-deps + + - name: Install build dependencies + run: sudo apt-get update && sudo apt-get install -y ninja-build cmake + + - name: Configure & build stride_spirv_tools + run: | + cmake -S stride-src/build/deps/spirv-tools -B _build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \ + -DANDROID_ABI=${{ matrix.abi }} \ + -DANDROID_PLATFORM=android-24 \ + -DSPIRV_TOOLS_SOURCE_DIR=$PWD/spirv-tools-src + cmake --build _build --target stride_spirv_tools + + - name: Collect output + run: | + mkdir -p spirv-tools-out + cp _build/libstride_spirv_tools.so spirv-tools-out/ + + - uses: actions/upload-artifact@v4 + with: + name: spirv-tools-${{ matrix.rid }} + path: spirv-tools-out/ + + # --------------------------------------------------------------------------- + # Pack NuGet from all artifacts. + # --------------------------------------------------------------------------- + pack: + name: Pack & Publish NuGet + needs: + - build-windows-x64 + - build-windows-arm64 + - build-linux-x64 + - build-macos-arm64 + - build-ios-arm64 + - build-android + runs-on: windows-2025-vs2026 + steps: + - uses: actions/checkout@v4 + + - name: Clone SPIRV-Tools (for commit hash) + shell: pwsh + run: | + git init spirv-tools-src + git -C spirv-tools-src remote add origin "${{ github.event.inputs.repository || 'https://github.com/KhronosGroup/SPIRV-Tools.git' }}" + git -C spirv-tools-src fetch --depth 1 origin "${{ github.event.inputs.ref || 'main' }}" + git -C spirv-tools-src checkout FETCH_HEAD + + - name: Download artifacts + uses: actions/download-artifact@v4 + with: { path: artifacts, pattern: spirv-tools-* } + + - name: Stage native payload into csproj + shell: pwsh + run: | + $destRoot = "build/deps/spirv-tools/runtimes" + $rids = 'win-x64','win-arm64','linux-x64','osx-arm64','ios-arm64','android-arm64','android-x64' + foreach ($rid in $rids) { + $native = "$destRoot/$rid/native" + New-Item -Path $native -ItemType Directory -Force | Out-Null + Copy-Item -Recurse "artifacts/spirv-tools-$rid/*" $native + } + + - name: Pack NuGet (dotnet pack) + shell: pwsh + run: | + $commitHash = git -C spirv-tools-src rev-parse --short HEAD + $version = "${{ github.event.inputs.version }}" + if (-not $version) { $version = (Get-Date -Format "yyyy.M.d") } + dotnet pack build/deps/spirv-tools/Stride.Dependencies.SPIRVTools.csproj ` + -c Release ` + -p:PackageVersion=$version ` + -p:RepositoryCommit=$commitHash ` + -o nupkg + + - uses: actions/upload-artifact@v4 + with: { name: Stride.Dependencies.SPIRVTools.nupkg, path: nupkg/*.nupkg } + + publish: + name: Sign & Publish to NuGet.org + needs: pack + runs-on: windows-2025-vs2026 + environment: production + steps: + - name: Install signing tool + run: dotnet tool install sign --tool-path ./sign-tool --version 0.9.0-beta.23127.3 + + - uses: actions/download-artifact@v4 + with: { name: Stride.Dependencies.SPIRVTools.nupkg } + + - name: Sign NuGet package + shell: pwsh + run: | + ./sign-tool/sign code azure-key-vault *.nupkg ` + --description "Stride" ` + --description-url "https://stride3d.net" ` + --publisher-name "Stride" ` + --azure-key-vault-tenant-id "${{ secrets.STRIDE_SIGN_TENANT_ID }}" ` + --azure-key-vault-client-id "${{ secrets.STRIDE_SIGN_CLIENT_ID }}" ` + --azure-key-vault-client-secret "${{ secrets.STRIDE_SIGN_CLIENT_SECRET }}" ` + --azure-key-vault-certificate "${{ secrets.STRIDE_SIGN_KEYVAULT_CERTIFICATE }}" ` + --azure-key-vault-url "https://${{ secrets.STRIDE_SIGN_KEYVAULT_NAME }}.vault.azure.net/" ` + -v Information + + - name: Publish run: | - echo "This is a skeleton. The real build lives on a feature branch." - echo "Trigger this workflow against that branch ref to run the actual build." + dotnet nuget push *.nupkg --api-key "${{ secrets.STRIDE_NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 194db56dcf..4553829256 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,32 +1,32 @@ name: CI -on: - push: - branches: - - master - paths: - - '.github/workflows/**' - - 'build/**' - - 'deps/**' - - 'sources/**' - - '!**/.all-contributorsrc' - - '!**/.editorconfig' - - '!**/.gitignore' - - '!**/*.md' - - '!crowdin.yml' - pull_request: - paths: - - '.github/workflows/**' - - 'build/**' - - 'deps/**' - - 'sources/**' - - '!**/.all-contributorsrc' - - '!**/.editorconfig' - - '!**/.gitignore' - - '!**/*.md' - - '!crowdin.yml' - types: [opened, synchronize, reopened, ready_for_review] - workflow_dispatch: +#on: +# push: +# branches: +# - master +# paths: +# - '.github/workflows/**' +# - 'build/**' +# - 'deps/**' +# - 'sources/**' +# - '!**/.all-contributorsrc' +# - '!**/.editorconfig' +# - '!**/.gitignore' +# - '!**/*.md' +# - '!crowdin.yml' +# pull_request: +# paths: +# - '.github/workflows/**' +# - 'build/**' +# - 'deps/**' +# - 'sources/**' +# - '!**/.all-contributorsrc' +# - '!**/.editorconfig' +# - '!**/.gitignore' +# - '!**/*.md' +# - '!crowdin.yml' +# types: [opened, synchronize, reopened, ready_for_review] +# workflow_dispatch: permissions: checks: write diff --git a/build/deps/spirv-tools/CMakeLists.txt b/build/deps/spirv-tools/CMakeLists.txt new file mode 100644 index 0000000000..2f911ad4c2 --- /dev/null +++ b/build/deps/spirv-tools/CMakeLists.txt @@ -0,0 +1,57 @@ +# Bundles SPIRV-Tools-static + SPIRV-Tools-opt + the C shim into a single +# shared library, stride_spirv_tools, re-exporting both the upstream libspirv.h +# C API and the shim's stride_spv* entry points. +# +# Usage (from dep-spirv-tools.yml): +# cmake -S build/deps/spirv-tools -B _build \ +# -DSPIRV_TOOLS_SOURCE_DIR= +# cmake --build _build + +cmake_minimum_required(VERSION 3.15) +project(stride_spirv_tools LANGUAGES C CXX) + +if(NOT DEFINED SPIRV_TOOLS_SOURCE_DIR) + message(FATAL_ERROR "Set -DSPIRV_TOOLS_SOURCE_DIR to the cloned SPIRV-Tools source tree.") +endif() + +# Force the upstream build to produce static archives we can absorb. +set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) +set(SPIRV_SKIP_TESTS ON CACHE BOOL "" FORCE) +set(SPIRV_SKIP_EXECUTABLES ON CACHE BOOL "" FORCE) +set(SPIRV_WERROR OFF CACHE BOOL "" FORCE) + +# SPIRV-Tools' SPIRV_TOOLS_EXPORT macro only activates when SPIRV_TOOLS_SHAREDLIB +# is defined; SPIRV_TOOLS_IMPLEMENTATION then flips it from dllimport to dllexport. +# Both must be defined when compiling the static libs so their C API symbols get +# __declspec(dllexport) and end up in our shared output's export table. +add_compile_definitions(SPIRV_TOOLS_IMPLEMENTATION SPIRV_TOOLS_SHAREDLIB) + +add_subdirectory(${SPIRV_TOOLS_SOURCE_DIR} spirv-tools-build EXCLUDE_FROM_ALL) + +add_library(stride_spirv_tools SHARED stride_spvopt_shim.cpp) +set_target_properties(stride_spirv_tools PROPERTIES + CXX_STANDARD 17 + CXX_STANDARD_REQUIRED ON + POSITION_INDEPENDENT_CODE ON + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON) + +target_include_directories(stride_spirv_tools PRIVATE + ${SPIRV_TOOLS_SOURCE_DIR}/include) + +# Whole-archive both static libs so no public symbol gets dropped by dead-code +# stripping. The SPIRV_TOOLS_EXPORT/STRIDE_SPV_EXPORT attributes drive what's +# actually exposed in the final symbol table. +if(WIN32) + target_link_options(stride_spirv_tools PRIVATE + /WHOLEARCHIVE:$ + /WHOLEARCHIVE:$) + target_link_libraries(stride_spirv_tools PRIVATE SPIRV-Tools-static SPIRV-Tools-opt) +elseif(APPLE) + target_link_libraries(stride_spirv_tools PRIVATE + -Wl,-force_load $ + -Wl,-force_load $) +else() + target_link_libraries(stride_spirv_tools PRIVATE + -Wl,--whole-archive SPIRV-Tools-static SPIRV-Tools-opt -Wl,--no-whole-archive) +endif() diff --git a/build/deps/spirv-tools/Stride.Dependencies.SPIRVTools.csproj b/build/deps/spirv-tools/Stride.Dependencies.SPIRVTools.csproj new file mode 100644 index 0000000000..f370ecfa26 --- /dev/null +++ b/build/deps/spirv-tools/Stride.Dependencies.SPIRVTools.csproj @@ -0,0 +1,26 @@ + + + net10.0 + enable + latest + + Stride.Dependencies.SPIRVTools + Stride Contributors + SPIRV-Tools shared libraries (spirv-opt + spirv-val C APIs) for Stride runtime SPIR-V constant folding and validation. + Apache-2.0 + https://github.com/stride3d/stride + git + + true + + + + + + + + + + + + diff --git a/build/deps/spirv-tools/stride_spvopt_shim.cpp b/build/deps/spirv-tools/stride_spvopt_shim.cpp new file mode 100644 index 0000000000..ac408b959c --- /dev/null +++ b/build/deps/spirv-tools/stride_spvopt_shim.cpp @@ -0,0 +1,88 @@ +// C-callable wrappers around spvtools::Optimizer. Upstream SPIRV-Tools exposes +// the optimizer only via optimizer.hpp (C++), which P/Invoke can't reach +// because of name mangling. This shim compiles into stride_spirv_tools and +// exports stable C entry points that the managed bindings call. + +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) + #define STRIDE_SPV_EXPORT __declspec(dllexport) +#else + #define STRIDE_SPV_EXPORT __attribute__((visibility("default"))) +#endif + +extern "C" { + +STRIDE_SPV_EXPORT void* stride_spvOptimizerCreate(spv_target_env env) { + return static_cast(new spvtools::Optimizer(env)); +} + +STRIDE_SPV_EXPORT void stride_spvOptimizerDestroy(void* optimizer) { + delete static_cast(optimizer); +} + +STRIDE_SPV_EXPORT void stride_spvOptimizerRegisterLegalizationPasses(void* optimizer) { + static_cast(optimizer)->RegisterLegalizationPasses(); +} + +// Same legalization recipe, but with preserve_interface=true so that unused +// Input/Output variables aren't stripped. Needed because Stride runs legalize +// on a merged multi-stage module: dropping an Output in the predecessor stage +// while keeping an Input with the same Location in the successor leaves FXC +// assigning mismatched hardware registers to the same semantic, which D3D11's +// runtime signature check then rejects ("Semantic X defined for mismatched +// hardware registers"). See EffectCompiler.cs for the full picture. +STRIDE_SPV_EXPORT void stride_spvOptimizerRegisterLegalizationPassesPreserveInterface(void* optimizer) { + static_cast(optimizer)->RegisterLegalizationPasses(true); +} + +STRIDE_SPV_EXPORT void stride_spvOptimizerRegisterPerformancePasses(void* optimizer) { + static_cast(optimizer)->RegisterPerformancePasses(); +} + +// Register a single pass by its spirv-opt CLI flag (e.g. "--eliminate-dead-code-aggressive", +// "--scalar-replacement=0"). Returns non-zero on success. Lets managed code assemble +// custom pass pipelines without requiring a new shim export per recipe. +STRIDE_SPV_EXPORT int stride_spvOptimizerRegisterPassFromFlag( + void* optimizer, const char* flag, int preserve_interface) { + return static_cast(optimizer) + ->RegisterPassFromFlag(flag, preserve_interface != 0) ? 1 : 0; +} + +STRIDE_SPV_EXPORT spv_result_t stride_spvOptimizerRun( + void* optimizer, + const uint32_t* input_binary, size_t input_word_count, + uint32_t** output_binary, size_t* output_word_count) { + + auto* opt = static_cast(optimizer); + std::vector result; + if (!opt->Run(input_binary, input_word_count, &result)) { + *output_binary = nullptr; + *output_word_count = 0; + return SPV_ERROR_INTERNAL; + } + // Transfer ownership to caller via malloc so the managed side can pair it + // with stride_spvOptimizerFreeBinary (std::free) — no CRT boundary risk. + const size_t byte_count = result.size() * sizeof(uint32_t); + auto* buffer = static_cast(std::malloc(byte_count)); + if (!buffer) { + *output_binary = nullptr; + *output_word_count = 0; + return SPV_ERROR_OUT_OF_MEMORY; + } + std::memcpy(buffer, result.data(), byte_count); + *output_binary = buffer; + *output_word_count = result.size(); + return SPV_SUCCESS; +} + +STRIDE_SPV_EXPORT void stride_spvOptimizerFreeBinary(uint32_t* binary) { + std::free(binary); +} + +} // extern "C" diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs new file mode 100644 index 0000000000..47761b3ea2 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs @@ -0,0 +1,312 @@ +using System.Runtime.InteropServices; + +namespace Stride.Shaders.Spirv.Tools; + +/// +/// Hand-rolled P/Invoke surface for the SPIRV-Tools validator and optimizer, +/// backed by the Stride.Dependencies.SPIRVTools native payload. +/// +/// Validator bindings are the stable C API from spirv-tools/libspirv.h. Optimizer +/// bindings target the stride_spv* C shim that wraps spvtools::Optimizer +/// — upstream's optimizer.hpp is C++ only. Both live in the single combined +/// stride_spirv_tools library; see build/deps/spirv-tools/. +/// +/// +public static unsafe class SpirvTools +{ + const string Lib = "stride_spirv_tools"; + + public enum TargetEnv + { + Universal_1_0 = 0, + Vulkan_1_0 = 1, + Universal_1_1 = 2, + Universal_1_2 = 11, + Universal_1_3 = 18, + Vulkan_1_1 = 19, + Universal_1_4 = 21, + Vulkan_1_1_SpirV_1_4 = 22, + Universal_1_5 = 23, + Vulkan_1_2 = 24, + Universal_1_6 = 25, + Vulkan_1_3 = 26, + Vulkan_1_4 = 27, + } + + public enum Result + { + Success = 0, + Unsupported = 1, + EndOfStream = 2, + Warning = 3, + FailedMatch = 4, + RequestedTermination = 5, + InternalError = -1, + OutOfMemory = -2, + InvalidPointer = -3, + InvalidBinary = -4, + InvalidText = -5, + InvalidTable = -6, + InvalidValue = -7, + InvalidDiagnostic = -8, + InvalidLookup = -9, + InvalidId = -10, + InvalidCfg = -11, + InvalidLayout = -12, + InvalidCapability = -13, + InvalidData = -14, + MissingExtension = -15, + WrongVersion = -16, + } + + [Flags] + public enum ValidatorOptions + { + None = 0, + /// Relax block-layout rules (Vulkan VK_KHR_relaxed_block_layout equivalent). + RelaxBlockLayout = 1 << 0, + /// Allow UBO standard layout (Vulkan VK_KHR_uniform_buffer_standard_layout equivalent). + UniformBufferStandardLayout = 1 << 1, + /// Allow scalar block layout (Vulkan VK_EXT_scalar_block_layout equivalent). + ScalarBlockLayout = 1 << 2, + } + + [StructLayout(LayoutKind.Sequential)] + struct Position { public nuint Line; public nuint Column; public nuint Index; } + + [StructLayout(LayoutKind.Sequential)] + struct Diagnostic { public Position Position; public byte* Error; public byte IsTextSource; } + + // ---- Core / validator (spirv-tools/libspirv.h) ------------------------- + [DllImport(Lib, EntryPoint = "spvContextCreate")] + static extern IntPtr ContextCreate(TargetEnv env); + + [DllImport(Lib, EntryPoint = "spvContextDestroy")] + static extern void ContextDestroy(IntPtr context); + + [DllImport(Lib, EntryPoint = "spvValidateBinary")] + static extern Result ValidateBinary(IntPtr context, uint* code, nuint wordCount, Diagnostic** diagnostic); + + [DllImport(Lib, EntryPoint = "spvValidateWithOptions")] + static extern Result ValidateWithOptions(IntPtr context, IntPtr options, ConstBinary* binary, Diagnostic** diagnostic); + + [DllImport(Lib, EntryPoint = "spvDiagnosticDestroy")] + static extern void DiagnosticDestroy(Diagnostic* diagnostic); + + [DllImport(Lib, EntryPoint = "spvValidatorOptionsCreate")] + static extern IntPtr ValidatorOptionsCreate(); + + [DllImport(Lib, EntryPoint = "spvValidatorOptionsDestroy")] + static extern void ValidatorOptionsDestroy(IntPtr options); + + [DllImport(Lib, EntryPoint = "spvValidatorOptionsSetRelaxBlockLayout")] + static extern void ValidatorOptionsSetRelaxBlockLayout(IntPtr options, byte val); + + [DllImport(Lib, EntryPoint = "spvValidatorOptionsSetUniformBufferStandardLayout")] + static extern void ValidatorOptionsSetUniformBufferStandardLayout(IntPtr options, byte val); + + [DllImport(Lib, EntryPoint = "spvValidatorOptionsSetScalarBlockLayout")] + static extern void ValidatorOptionsSetScalarBlockLayout(IntPtr options, byte val); + + [StructLayout(LayoutKind.Sequential)] + struct ConstBinary { public uint* Code; public nuint WordCount; } + + /// + /// Validates a SPIR-V binary. Returns null on success; otherwise a diagnostic message. + /// + public static string? Validate(ReadOnlySpan words, TargetEnv env = TargetEnv.Vulkan_1_3, ValidatorOptions options = ValidatorOptions.None) + { + var ctx = ContextCreate(env); + if (ctx == IntPtr.Zero) + throw new InvalidOperationException("spvContextCreate failed"); + try + { + IntPtr opts = IntPtr.Zero; + if (options != ValidatorOptions.None) + { + opts = ValidatorOptionsCreate(); + if ((options & ValidatorOptions.RelaxBlockLayout) != 0) + ValidatorOptionsSetRelaxBlockLayout(opts, 1); + if ((options & ValidatorOptions.UniformBufferStandardLayout) != 0) + ValidatorOptionsSetUniformBufferStandardLayout(opts, 1); + if ((options & ValidatorOptions.ScalarBlockLayout) != 0) + ValidatorOptionsSetScalarBlockLayout(opts, 1); + } + + try + { + Diagnostic* diag = null; + fixed (uint* code = words) + { + Result r; + if (opts == IntPtr.Zero) + { + r = ValidateBinary(ctx, code, (nuint)words.Length, &diag); + } + else + { + var bin = new ConstBinary { Code = code, WordCount = (nuint)words.Length }; + r = ValidateWithOptions(ctx, opts, &bin, &diag); + } + if (r == Result.Success) + return null; + try + { + var msg = diag != null && diag->Error != null + ? Marshal.PtrToStringAnsi((IntPtr)diag->Error) + : null; + return msg ?? $"SPIR-V validation failed: {r}"; + } + finally + { + if (diag != null) DiagnosticDestroy(diag); + } + } + } + finally + { + if (opts != IntPtr.Zero) ValidatorOptionsDestroy(opts); + } + } + finally + { + ContextDestroy(ctx); + } + } + + /// + public static string? Validate(ReadOnlySpan bytes, TargetEnv env = TargetEnv.Vulkan_1_3, ValidatorOptions options = ValidatorOptions.None) + => Validate(MemoryMarshal.Cast(bytes), env, options); + + // ---- Optimizer (C shim over spvtools::Optimizer) ---------------------- + [DllImport(Lib, EntryPoint = "stride_spvOptimizerCreate")] + static extern IntPtr OptimizerCreate(TargetEnv env); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerDestroy")] + static extern void OptimizerDestroy(IntPtr optimizer); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterLegalizationPasses")] + static extern void OptimizerRegisterLegalizationPasses(IntPtr optimizer); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterLegalizationPassesPreserveInterface")] + static extern void OptimizerRegisterLegalizationPassesPreserveInterface(IntPtr optimizer); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterPerformancePasses")] + static extern void OptimizerRegisterPerformancePasses(IntPtr optimizer); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterPassFromFlag")] + static extern int OptimizerRegisterPassFromFlag(IntPtr optimizer, byte* flag, int preserveInterface); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerRun")] + static extern Result OptimizerRun( + IntPtr optimizer, + uint* inputBinary, + nuint inputWordCount, + uint** outputBinary, + nuint* outputWordCount); + + [DllImport(Lib, EntryPoint = "stride_spvOptimizerFreeBinary")] + static extern void OptimizerFreeBinary(uint* binary); + + enum PassMode { Legalize, LegalizePreserveInterface, Performance } + + /// + /// Runs the SPIRV-Cross-tuned legalization pass list with preserve_interface=true + /// — constant folding, DCE, CCP, structured-CFG cleanup, but no pruning of unused + /// Input/Output variables. Use this before handing SPIR-V to SPIRV-Cross + /// for HLSL/MSL/GLSL emission. + /// + /// Interface preservation is a stopgap: Stride feeds a single merged module + /// containing every stage to the optimizer, and spirv-opt has no cross-stage + /// awareness. Letting DCE strip outputs independently per stage leaves downstream + /// stages holding inputs whose producers vanished, which FXC then maps to + /// mismatched hardware registers. The proper long-term fix is cross-stage DCE + /// driven back-to-front (PS → DS/GS → VS). + /// + /// + public static uint[] LegalizeForHlsl(ReadOnlySpan words, TargetEnv env = TargetEnv.Vulkan_1_3) + => RunOptimizer(words, env, PassMode.LegalizePreserveInterface); + + /// + /// Runs the performance pass list (equivalent to spirv-opt -O). Produces + /// smaller, faster SPIR-V with no semantic change. Don't use before SPIRV-Cross + /// — the aggressive inlining and reordering hurts HLSL output quality. + /// + public static uint[] OptimizeForPerformance(ReadOnlySpan words, TargetEnv env = TargetEnv.Vulkan_1_3) + => RunOptimizer(words, env, PassMode.Performance); + + /// + /// Runs a caller-supplied pass pipeline, specified as spirv-opt CLI flags + /// (e.g. "--eliminate-dead-code-aggressive", "--scalar-replacement=0"). + /// maps to the preserve_interface flag + /// threaded into passes that can strip unused Input/Output variables. + /// + public static uint[] Optimize(ReadOnlySpan words, IEnumerable flags, bool preserveInterface = false, TargetEnv env = TargetEnv.Vulkan_1_3) + { + var opt = OptimizerCreate(env); + if (opt == IntPtr.Zero) + throw new InvalidOperationException("spvOptimizerCreate failed"); + try + { + foreach (var flag in flags) + RegisterFlag(opt, flag, preserveInterface); + return RunAndCopy(opt, words); + } + finally + { + OptimizerDestroy(opt); + } + } + + static uint[] RunOptimizer(ReadOnlySpan words, TargetEnv env, PassMode mode) + { + var opt = OptimizerCreate(env); + if (opt == IntPtr.Zero) + throw new InvalidOperationException("spvOptimizerCreate failed"); + try + { + switch (mode) + { + case PassMode.Legalize: OptimizerRegisterLegalizationPasses(opt); break; + case PassMode.LegalizePreserveInterface: OptimizerRegisterLegalizationPassesPreserveInterface(opt); break; + case PassMode.Performance: OptimizerRegisterPerformancePasses(opt); break; + } + return RunAndCopy(opt, words); + } + finally + { + OptimizerDestroy(opt); + } + } + + static uint[] RunAndCopy(IntPtr opt, ReadOnlySpan words) + { + uint* outPtr = null; + nuint outCount = 0; + fixed (uint* inPtr = words) + { + var r = OptimizerRun(opt, inPtr, (nuint)words.Length, &outPtr, &outCount); + if (r != Result.Success) + throw new InvalidOperationException($"spvOptimizerRun failed: {r}"); + } + try + { + var result = new uint[(int)outCount]; + new ReadOnlySpan(outPtr, (int)outCount).CopyTo(result); + return result; + } + finally + { + if (outPtr != null) OptimizerFreeBinary(outPtr); + } + } + + static void RegisterFlag(IntPtr opt, string flag, bool preserveInterface) + { + var buf = stackalloc byte[Encoding.ASCII.GetMaxByteCount(flag.Length) + 1]; + int n = Encoding.ASCII.GetBytes(flag, new Span(buf, flag.Length * 2)); + buf[n] = 0; + if (OptimizerRegisterPassFromFlag(opt, buf, preserveInterface ? 1 : 0) == 0) + throw new InvalidOperationException($"spvOptimizerRegisterPassFromFlag rejected '{flag}'"); + } +} diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs index 3782600712..0ee04f29d4 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/Validator.cs @@ -1,6 +1,3 @@ -using System.Diagnostics; -using System.Text; - namespace Stride.Shaders.Spirv.Tools; public readonly record struct ValidationResult(bool IsValid, string Output) @@ -10,82 +7,26 @@ public readonly record struct ValidationResult(bool IsValid, string Output) public static partial class Spv { - static string? FindSpirvVal() - { - // 1. Check VULKAN_SDK env var - var vulkanSdk = Environment.GetEnvironmentVariable("VULKAN_SDK"); - if (!string.IsNullOrEmpty(vulkanSdk)) - { - var path = Path.Combine(vulkanSdk, "Bin", "spirv-val.exe"); - if (File.Exists(path)) - return path; - // Linux/macOS - path = Path.Combine(vulkanSdk, "bin", "spirv-val"); - if (File.Exists(path)) - return path; - } - - // 2. Assume it's on PATH - return "spirv-val"; - } - /// - /// Validates a SPIR-V file using the spirv-val tool from the Vulkan SDK. + /// Validates a SPIR-V file using the in-process SPIRV-Tools validator. /// /// Path to a .spv file. - /// When true, validates against Vulkan 1.4 with relaxed layout rules. - /// A indicating whether the bytecode is valid. + /// When true, validates against Vulkan 1.4 with relaxed block layout and UBO standard layout. public static ValidationResult ValidateFile(string filePath, bool targetVulkan = false) - { - var exe = FindSpirvVal(); - - var args = targetVulkan - ? $"--target-env vulkan1.4 --relax-block-layout --uniform-buffer-standard-layout {filePath}" - : filePath; - - using var process = new Process(); - process.StartInfo = new ProcessStartInfo - { - FileName = exe, - Arguments = args, - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true, - }; - - process.Start(); - - var stdout = process.StandardOutput.ReadToEnd(); - var stderr = process.StandardError.ReadToEnd(); - process.WaitForExit(); - - var output = new StringBuilder(); - if (stdout.Length > 0) - output.Append(stdout); - if (stderr.Length > 0) - output.Append(stderr); - - return new ValidationResult(process.ExitCode == 0, output.ToString().Trim()); - } + => ValidateBinary(File.ReadAllBytes(filePath), targetVulkan); /// - /// Validates SPIR-V bytecode using the spirv-val tool from the Vulkan SDK. + /// Validates SPIR-V bytecode using the in-process SPIRV-Tools validator. /// - /// Raw SPIR-V bytecode as a byte span. - /// When true, validates against Vulkan 1.4 with relaxed layout rules. - /// A indicating whether the bytecode is valid. public static ValidationResult ValidateBinary(ReadOnlySpan spirvBytes, bool targetVulkan = false) { - var tempFile = Path.GetTempFileName(); - try - { - File.WriteAllBytes(tempFile, spirvBytes.ToArray()); - return ValidateFile(tempFile, targetVulkan); - } - finally - { - try { File.Delete(tempFile); } catch { } - } + var env = targetVulkan ? SpirvTools.TargetEnv.Vulkan_1_4 : SpirvTools.TargetEnv.Universal_1_6; + var options = targetVulkan + ? SpirvTools.ValidatorOptions.RelaxBlockLayout | SpirvTools.ValidatorOptions.UniformBufferStandardLayout + : SpirvTools.ValidatorOptions.None; + var message = SpirvTools.Validate(spirvBytes, env, options); + return message is null + ? new ValidationResult(true, "") + : new ValidationResult(false, message); } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj index 2ab4f90b06..0abcd076ec 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj +++ b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj @@ -18,6 +18,8 @@ + + From ae6aa351cff4c7d810eae21d0bed6801c515f05f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 09:56:27 +0900 Subject: [PATCH 1106/1182] fix: Adjust mesa-pipeline.patch to latest MR 41028 --- .github/workflows/dep-spirv-to-dxil.yml | 4 + build/deps/spirv-to-dxil/.gitattributes | 1 + build/deps/spirv-to-dxil/mesa-pipeline.patch | 98 +------------------- 3 files changed, 8 insertions(+), 95 deletions(-) create mode 100644 build/deps/spirv-to-dxil/.gitattributes diff --git a/.github/workflows/dep-spirv-to-dxil.yml b/.github/workflows/dep-spirv-to-dxil.yml index 4324961ec9..9f6e79c9e2 100644 --- a/.github/workflows/dep-spirv-to-dxil.yml +++ b/.github/workflows/dep-spirv-to-dxil.yml @@ -29,6 +29,10 @@ jobs: $url = "${{ github.event.inputs.repository || 'https://gitlab.freedesktop.org/mesa/mesa.git' }}" $ref = "${{ github.event.inputs.ref || 'main' }}" git init mesa-src + # Keep LF line endings — our patch is LF, and on Windows runners + # autocrlf=true would otherwise add CR which breaks `git apply`. + git -C mesa-src config core.autocrlf false + git -C mesa-src config core.eol lf git -C mesa-src remote add origin $url git -C mesa-src fetch --depth 1 origin $ref git -C mesa-src checkout FETCH_HEAD diff --git a/build/deps/spirv-to-dxil/.gitattributes b/build/deps/spirv-to-dxil/.gitattributes new file mode 100644 index 0000000000..9812ceb1ff --- /dev/null +++ b/build/deps/spirv-to-dxil/.gitattributes @@ -0,0 +1 @@ +*.patch text eol=lf diff --git a/build/deps/spirv-to-dxil/mesa-pipeline.patch b/build/deps/spirv-to-dxil/mesa-pipeline.patch index f9cda8f6f2..abaf8fb70c 100644 --- a/build/deps/spirv-to-dxil/mesa-pipeline.patch +++ b/build/deps/spirv-to-dxil/mesa-pipeline.patch @@ -1,97 +1,5 @@ -diff --git a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c -index 460af16..4273abd 100644 ---- a/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c -+++ b/src/microsoft/spirv_to_dxil/dxil_spirv_nir.c -@@ -103,6 +103,10 @@ dxil_spirv_nir_get_spirv_options(void) - return &spirv_to_nir_options; - } - -+/* Stride: keep I/O variables marked always_active_io alive (forward decl, definition later) */ -+static bool -+dxil_spirv_can_remove_io_var(nir_variable *var, void *data); -+ - /* Logic extracted from vk_spirv_to_nir() so we have the same preparation - * steps for both the vulkan driver and the lib used by the WebGPU - * implementation. -@@ -139,11 +143,17 @@ dxil_spirv_nir_prep(nir_shader *nir) - NIR_PASS(_, nir, nir_split_var_copies); - NIR_PASS(_, nir, nir_split_per_member_structs); - -- NIR_PASS(_, nir, nir_remove_dead_variables, -- nir_var_shader_in | nir_var_shader_out | nir_var_system_value | -- nir_var_shader_call_data | nir_var_ray_hit_attrib, -- NULL); -- -+ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ -+ { -+ static const struct nir_remove_dead_variables_options _opts = { -+ .can_remove_var = dxil_spirv_can_remove_io_var, -+ }; -+ NIR_PASS(_, nir, nir_remove_dead_variables, -+ nir_var_shader_in | nir_var_shader_out | nir_var_system_value | -+ nir_var_shader_call_data | nir_var_ray_hit_attrib, -+ &_opts); -+ } -+ - /* This needs to happen after remove_dead_vars because GLSLang likes to - * insert dead clip/cull vars and we don't want to clip/cull based on - * uninitialized garbage. -@@ -787,6 +797,13 @@ lower_view_index_to_rt_layer(nir_shader *nir) - } - } - -+/* Stride: keep I/O variables marked always_active_io alive */ -+static bool -+dxil_spirv_can_remove_io_var(nir_variable *var, void *data) -+{ -+ return !var->data.always_active_io; -+} -+ - void - dxil_spirv_nir_link(nir_shader *nir, nir_shader *prev_stage_nir, - const struct dxil_spirv_runtime_conf *conf, -@@ -1007,10 +1024,16 @@ dxil_spirv_nir_passes(nir_shader *nir, - - NIR_PASS(_, nir, dxil_spirv_nir_discard_point_size_var); - -- NIR_PASS(_, nir, nir_remove_dead_variables, -- nir_var_shader_in | nir_var_shader_out | -- nir_var_system_value | nir_var_mem_shared, -- NULL); -+ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ -+ { -+ static const struct nir_remove_dead_variables_options _opts2 = { -+ .can_remove_var = dxil_spirv_can_remove_io_var, -+ }; -+ NIR_PASS(_, nir, nir_remove_dead_variables, -+ nir_var_shader_in | nir_var_shader_out | -+ nir_var_system_value | nir_var_mem_shared, -+ &_opts2); -+ } - - uint32_t push_constant_size = 0; - NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_push_const, -@@ -1121,9 +1144,15 @@ dxil_spirv_nir_passes(nir_shader *nir, - NIR_PASS(_, nir, dxil_nir_lower_ubo_array_one_to_static); - NIR_PASS(_, nir, nir_opt_dce); - NIR_PASS(_, nir, nir_remove_dead_derefs); -- NIR_PASS(_, nir, nir_remove_dead_variables, -- nir_var_uniform | nir_var_shader_in | nir_var_shader_out, -- NULL); -+ /* Stride: keep I/O variables marked always_active_io alive (signature matching) */ -+ { -+ static const struct nir_remove_dead_variables_options _opts = { -+ .can_remove_var = dxil_spirv_can_remove_io_var, -+ }; -+ NIR_PASS(_, nir, nir_remove_dead_variables, -+ nir_var_uniform | nir_var_shader_in | nir_var_shader_out, -+ &_opts); -+ } - NIR_PASS(_, nir, merge_ubos_and_ssbos); - - if (nir->info.stage == MESA_SHADER_FRAGMENT) { diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c -index 1a8e6e2..14b0f11 100644 +index 1a8e6e2dee3..14b0f115dc8 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.c +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.c @@ -126,3 +126,140 @@ spirv_to_dxil_get_version() @@ -236,7 +144,7 @@ index 1a8e6e2..14b0f11 100644 + return success; +} diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.def b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def -index 62851f2..1c6f26c 100644 +index 62851f2160b..1c6f26c7a3a 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.def +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.def @@ -2,3 +2,4 @@ EXPORTS @@ -245,7 +153,7 @@ index 62851f2..1c6f26c 100644 spirv_to_dxil_get_version + spirv_to_dxil_pipeline diff --git a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h -index 00b1884..902716c 100644 +index 00b18849e41..902716c6221 100644 --- a/src/microsoft/spirv_to_dxil/spirv_to_dxil.h +++ b/src/microsoft/spirv_to_dxil/spirv_to_dxil.h @@ -236,6 +236,31 @@ spirv_to_dxil(const uint32_t *words, size_t word_count, From 2359563028bff4914b141568e14db00859ee9968 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 11:07:09 +0900 Subject: [PATCH 1107/1182] chore: updated spirv_to_dxil.dll --- .../Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt | 4 ++-- .../shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt index da3b85e5e9..c62c3f24b0 100644 --- a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt @@ -1,2 +1,2 @@ -Mesa: https://gitlab.freedesktop.org/mesa/mesa.git @ 477c44ba93986e9aa4feae20f7e3777586a50ed1 -Stride: https://github.com/xen2/stride @ e91a6cc3dec1ac12ffc8410683ce50f89289ab9f (for workflow and build/deps/spirv-to-dxil/mesa-pipeline.patch) +Mesa: https://gitlab.freedesktop.org/mesa/mesa.git @ aa2bc8d2d88e65dcfb046a8ff11db1f0000d4a8a +Stride: https://github.com/stride3d/stride @ ae6aa351cff4c7d810eae21d0bed6801c515f05f (for workflow and build/deps/spirv-to-dxil/mesa-pipeline.patch) diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll index 9be68fd8a9..d89e916e7b 100644 --- a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c45921fd43e8283597a33f96090ff563f24d9cf8cf33e938a25d21c403110f6e -size 665600 +oid sha256:2c2d707cb986570917f7435db32bb7761476500efa43920a9ca669b70814ef02 +size 666112 From 0f4e01580c21df0e62c9388c29f7d6f37e0eb7eb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 21 Apr 2026 19:18:46 +0900 Subject: [PATCH 1108/1182] build: wire SPIRVTools legalization before SPIRV-Cross HLSL emission --- sources/Directory.Packages.props | 1 + .../EffectCompiler.cs | 24 +++++-- .../Spirv/Tools/SpirvTools.cs | 67 ++++++++++++++++++- 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index cf127724bf..dd78af986e 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -103,6 +103,7 @@ + diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 00972be61d..5df66952e3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -51,9 +51,13 @@ public partial class EffectCompiler : EffectCompilerBase /// /// When true, runs spirv-val on the SPIR-V bytecode after MergeSDSL. - /// Validation errors are logged as warnings (they do not block compilation). + /// Validation errors block the compile via log.Error. + /// Default: on in Debug builds, off in Release. /// public bool ValidateSpirv { get; set; } +#if DEBUG + = true; +#endif public EffectCompiler(IVirtualFileProvider fileProvider) { @@ -183,10 +187,10 @@ public override TaskOrResult Compile(ShaderMixinSo return new EffectBytecodeCompilerResult(null, log); } - // Select the correct backend compiler + // Select the correct backend compiler. D3D11 is the only platform that needs + // SPIRV→HLSL via SPIRV-Cross today; Vulkan/D3D12 consume SPIR-V directly. IShaderCompiler? compiler; - // Set to null if translator is not needed - Backend? translatorBackend = null; + bool useSpirvCrossToHlsl = false; switch (effectParameters.Platform) { #if STRIDE_PLATFORM_DESKTOP @@ -194,7 +198,7 @@ public override TaskOrResult Compile(ShaderMixinSo if (Platform.Type != PlatformType.Windows && Platform.Type != PlatformType.UWP) throw new NotSupportedException(); compiler = new Direct3D.ShaderCompiler(); - translatorBackend = Backend.Hlsl; + useSpirvCrossToHlsl = true; break; #endif case GraphicsPlatform.Vulkan: @@ -219,9 +223,15 @@ public override TaskOrResult Compile(ShaderMixinSo try { - if (translatorBackend != null) + if (useSpirvCrossToHlsl) { - var translator = new SpirvTranslator(spirvBytecode.ToArray().AsMemory().Cast()); + // Run SPIRV-Cross-tuned legalization before handing SPIR-V off: + // folds constants, kills dead branches, legalizes structured CFG. + // Required to stop SPIRV-Cross emitting `if (true)`-style dead code + // when generic template values collapse to constants. + var spirvWords = spirvBytecode.ToArray().AsMemory().Cast(); + var legalized = Spirv.Tools.SpirvTools.LegalizeForHlsl(spirvWords.Span); + var translator = new SpirvTranslator(legalized.AsMemory()); var translatorEntryPoints = translator.GetEntryPoints(); foreach (var entryPoint in translatorEntryPoints) { diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs index 47761b3ea2..ef2b261264 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs @@ -1,4 +1,5 @@ using System.Runtime.InteropServices; +using System.Text; namespace Stride.Shaders.Spirv.Tools; @@ -155,7 +156,13 @@ struct ConstBinary { public uint* Code; public nuint WordCount; } var msg = diag != null && diag->Error != null ? Marshal.PtrToStringAnsi((IntPtr)diag->Error) : null; - return msg ?? $"SPIR-V validation failed: {r}"; + msg ??= $"SPIR-V validation failed: {r}"; + if (diag != null) + { + var location = ResolveSourceLocation(words, diag->Position.Index); + if (location != null) msg = $"{location}: {msg}"; + } + return msg; } finally { @@ -178,6 +185,64 @@ struct ConstBinary { public uint* Code; public nuint WordCount; } public static string? Validate(ReadOnlySpan bytes, TargetEnv env = TargetEnv.Vulkan_1_3, ValidatorOptions options = ValidatorOptions.None) => Validate(MemoryMarshal.Cast(bytes), env, options); + /// + /// Walks a SPIR-V binary up to (zero-based + /// instruction ordinal of the failing instruction, as reported by + /// spvValidateBinary in spv_diagnostic.position.index) and resolves + /// the most recent OpLine + OpString into a file:line:col + /// prefix. Returns null if no debug info is available before the error. + /// + static string? ResolveSourceLocation(ReadOnlySpan words, nuint errorInstructionIndex) + { + const uint OpString = 7; + const uint OpLine = 8; + const uint OpNoLine = 317; + const int HeaderSize = 5; + + if (words.Length < HeaderSize) return null; + + Dictionary? strings = null; + uint lastFileId = 0, lastLine = 0, lastColumn = 0; + bool lineActive = false; + + int i = HeaderSize; + nuint instIndex = 0; + while (i < words.Length && instIndex < errorInstructionIndex) + { + uint firstWord = words[i]; + int wordCount = (int)(firstWord >> 16); + uint opcode = firstWord & 0xFFFF; + if (wordCount == 0 || i + wordCount > words.Length) break; + + if (opcode == OpString && wordCount >= 3) + { + uint resultId = words[i + 1]; + var bytes = MemoryMarshal.AsBytes(words.Slice(i + 2, wordCount - 2)); + int nullIdx = bytes.IndexOf((byte)0); + var s = nullIdx >= 0 ? Encoding.UTF8.GetString(bytes[..nullIdx]) : Encoding.UTF8.GetString(bytes); + (strings ??= new()).Add(resultId, s); + } + else if (opcode == OpLine && wordCount == 4) + { + lastFileId = words[i + 1]; + lastLine = words[i + 2]; + lastColumn = words[i + 3]; + lineActive = true; + } + else if (opcode == OpNoLine) + { + lineActive = false; + } + + i += wordCount; + instIndex++; + } + + if (!lineActive || strings is null || !strings.TryGetValue(lastFileId, out var file)) + return null; + return $"{file}:{lastLine}:{lastColumn}"; + } + // ---- Optimizer (C shim over spvtools::Optimizer) ---------------------- [DllImport(Lib, EntryPoint = "stride_spvOptimizerCreate")] static extern IntPtr OptimizerCreate(TargetEnv env); From 7a86917e90cbd68996a0a7160b66dc958c90757b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 11:28:33 +0900 Subject: [PATCH 1109/1182] build: extend SPIRV-Tools legalization to D3D12 DXIL path Previously only SPIRV-Cross (D3D11 HLSL) received legalized SPIR-V; spirv_to_dxil got the raw module and failed to lower tessellation pipelines. Also bumps Stride.Dependencies.SpirvCross to 2026.4.22 and Stride.Dependencies.SPIRVTools to 2026.4.23, and drops the orphan PassMode/RunOptimizer path from SpirvTools.cs. --- sources/Directory.Packages.props | 4 +- .../EffectCompiler.cs | 23 ++-- .../Spirv/Tools/SpirvTools.cs | 100 ++++++++++++------ 3 files changed, 82 insertions(+), 45 deletions(-) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index dd78af986e..6174ec2608 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -102,8 +102,8 @@ - - + + diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 5df66952e3..85ca29d9f9 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -6,6 +6,7 @@ using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using CommunityToolkit.HighPerformance; @@ -221,17 +222,23 @@ public override TaskOrResult Compile(ShaderMixinSo var spirvBytecodeForDebug = spirvBytecode.ToArray(); #endif + // Run SPIRV-Cross-tuned legalization on the merged SPIR-V module before + // any downstream consumer (SPIRV-Cross for D3D11 HLSL, or spirv-to-dxil + // for D3D12 DXIL). Folds constants, kills dead branches, legalizes + // structured CFG. Required to stop SPIRV-Cross emitting `if (true)`-style + // dead code when generic template values collapse to constants, and to + // give spirv-to-dxil a cleaner input. + // preserve_interface=true keeps Input/Output variables alive across stages + // — per-stage DCE otherwise leaves VS/HS outputs and PS/DS inputs out of + // sync, which FXC maps to mismatched hardware registers. The proper + // long-term fix is cross-stage DCE driven back-to-front (PS → DS/GS → VS). + var legalizedSpirv = Spirv.Tools.SpirvTools.LegalizeForHlsl(MemoryMarshal.Cast(spirvBytecode)); + try { if (useSpirvCrossToHlsl) { - // Run SPIRV-Cross-tuned legalization before handing SPIR-V off: - // folds constants, kills dead branches, legalizes structured CFG. - // Required to stop SPIRV-Cross emitting `if (true)`-style dead code - // when generic template values collapse to constants. - var spirvWords = spirvBytecode.ToArray().AsMemory().Cast(); - var legalized = Spirv.Tools.SpirvTools.LegalizeForHlsl(spirvWords.Span); - var translator = new SpirvTranslator(legalized.AsMemory()); + var translator = new SpirvTranslator(legalizedSpirv.AsMemory()); var translatorEntryPoints = translator.GetEntryPoints(); foreach (var entryPoint in translatorEntryPoints) { @@ -307,7 +314,7 @@ public override TaskOrResult Compile(ShaderMixinSo { // Check API Spv2DXIL.spirv_to_dxil_get_version(); - CompileDxilPipeline(spirvBytecode, entryPoints, shaderStageBytecodes); + CompileDxilPipeline(MemoryMarshal.AsBytes(legalizedSpirv), entryPoints, shaderStageBytecodes); } else #endif diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs index ef2b261264..f9c82c6f94 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs @@ -250,12 +250,6 @@ struct ConstBinary { public uint* Code; public nuint WordCount; } [DllImport(Lib, EntryPoint = "stride_spvOptimizerDestroy")] static extern void OptimizerDestroy(IntPtr optimizer); - [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterLegalizationPasses")] - static extern void OptimizerRegisterLegalizationPasses(IntPtr optimizer); - - [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterLegalizationPassesPreserveInterface")] - static extern void OptimizerRegisterLegalizationPassesPreserveInterface(IntPtr optimizer); - [DllImport(Lib, EntryPoint = "stride_spvOptimizerRegisterPerformancePasses")] static extern void OptimizerRegisterPerformancePasses(IntPtr optimizer); @@ -273,24 +267,68 @@ static extern Result OptimizerRun( [DllImport(Lib, EntryPoint = "stride_spvOptimizerFreeBinary")] static extern void OptimizerFreeBinary(uint* binary); - enum PassMode { Legalize, LegalizePreserveInterface, Performance } + // Mirrors upstream Optimizer::RegisterLegalizationPasses(preserve_interface=true) + // with two differences: + // - `--remove-unused-interface-variables` is omitted: it isn't controlled by + // the preserve_interface flag and would strip stage I/O variables anyway, + // re-introducing the cross-stage signature mismatch we're trying to avoid. + // - `CreateInvocationInterlockPlacementPass` is dropped because + // spirv-opt's RegisterPassFromFlag has no flag mapping for it (only + // relevant to SPV_KHR_fragment_shader_interlock, which Stride doesn't use). + // Keep this list synced with upstream source/opt/optimizer.cpp when updating + // the SPIRV-Tools package. + static readonly string[] LegalizeForHlslKeepInterface = + { + "--wrap-opkill", + "--eliminate-dead-branches", + "--merge-return", + "--inline-entry-points-exhaustive", + "--eliminate-dead-functions", + "--private-to-local", + "--fix-storage-class", + "--eliminate-local-single-block", + "--eliminate-local-single-store", + "--eliminate-dead-code-aggressive", + "--scalar-replacement=0", + "--eliminate-local-single-block", + "--eliminate-local-single-store", + "--eliminate-dead-code-aggressive", + "--eliminate-local-multi-store", + "--combine-access-chains", + "--eliminate-dead-code-aggressive", + "--legalize-multidim-array", + "--ccp", + "--loop-unroll", + "--eliminate-dead-branches", + "--simplify-instructions", + "--eliminate-dead-code-aggressive", + "--copy-propagate-arrays", + "--vector-dce", + "--eliminate-dead-inserts", + "--reduce-load-size", + "--eliminate-dead-code-aggressive", + "--interpolate-fixup", + "--fix-opextinst-opcodes", + }; /// - /// Runs the SPIRV-Cross-tuned legalization pass list with preserve_interface=true - /// — constant folding, DCE, CCP, structured-CFG cleanup, but no pruning of unused - /// Input/Output variables. Use this before handing SPIR-V to SPIRV-Cross - /// for HLSL/MSL/GLSL emission. + /// Runs a legalization pass list tuned for SPIRV-Cross HLSL emission — + /// constant folding, DCE, CCP, structured-CFG cleanup — while keeping every + /// stage's Input/Output variables alive. /// - /// Interface preservation is a stopgap: Stride feeds a single merged module + /// Interface preservation is a stopgap. Stride feeds a single merged module /// containing every stage to the optimizer, and spirv-opt has no cross-stage - /// awareness. Letting DCE strip outputs independently per stage leaves downstream - /// stages holding inputs whose producers vanished, which FXC then maps to - /// mismatched hardware registers. The proper long-term fix is cross-stage DCE - /// driven back-to-front (PS → DS/GS → VS). + /// awareness. Letting interface pruning run independently per stage leaves + /// downstream stages holding inputs whose producers vanished, which FXC then + /// maps to mismatched hardware registers (D3D11 rejects with "Semantic X + /// defined for mismatched hardware registers", or "Signatures between stages + /// are different lengths" for HS/DS). The proper long-term fix is cross-stage + /// DCE driven back-to-front (PS → DS/GS → VS) so each predecessor's outputs + /// match its successor's surviving inputs exactly. /// /// public static uint[] LegalizeForHlsl(ReadOnlySpan words, TargetEnv env = TargetEnv.Vulkan_1_3) - => RunOptimizer(words, env, PassMode.LegalizePreserveInterface); + => Optimize(words, LegalizeForHlslKeepInterface, preserveInterface: true, env); /// /// Runs the performance pass list (equivalent to spirv-opt -O). Produces @@ -298,23 +336,13 @@ public static uint[] LegalizeForHlsl(ReadOnlySpan words, TargetEnv env = T /// — the aggressive inlining and reordering hurts HLSL output quality. /// public static uint[] OptimizeForPerformance(ReadOnlySpan words, TargetEnv env = TargetEnv.Vulkan_1_3) - => RunOptimizer(words, env, PassMode.Performance); - - /// - /// Runs a caller-supplied pass pipeline, specified as spirv-opt CLI flags - /// (e.g. "--eliminate-dead-code-aggressive", "--scalar-replacement=0"). - /// maps to the preserve_interface flag - /// threaded into passes that can strip unused Input/Output variables. - /// - public static uint[] Optimize(ReadOnlySpan words, IEnumerable flags, bool preserveInterface = false, TargetEnv env = TargetEnv.Vulkan_1_3) { var opt = OptimizerCreate(env); if (opt == IntPtr.Zero) throw new InvalidOperationException("spvOptimizerCreate failed"); try { - foreach (var flag in flags) - RegisterFlag(opt, flag, preserveInterface); + OptimizerRegisterPerformancePasses(opt); return RunAndCopy(opt, words); } finally @@ -323,19 +351,21 @@ public static uint[] Optimize(ReadOnlySpan words, IEnumerable flag } } - static uint[] RunOptimizer(ReadOnlySpan words, TargetEnv env, PassMode mode) + /// + /// Runs a caller-supplied pass pipeline, specified as spirv-opt CLI flags + /// (e.g. "--eliminate-dead-code-aggressive", "--scalar-replacement=0"). + /// maps to the preserve_interface flag + /// threaded into passes that can strip unused Input/Output variables. + /// + public static uint[] Optimize(ReadOnlySpan words, IEnumerable flags, bool preserveInterface = false, TargetEnv env = TargetEnv.Vulkan_1_3) { var opt = OptimizerCreate(env); if (opt == IntPtr.Zero) throw new InvalidOperationException("spvOptimizerCreate failed"); try { - switch (mode) - { - case PassMode.Legalize: OptimizerRegisterLegalizationPasses(opt); break; - case PassMode.LegalizePreserveInterface: OptimizerRegisterLegalizationPassesPreserveInterface(opt); break; - case PassMode.Performance: OptimizerRegisterPerformancePasses(opt); break; - } + foreach (var flag in flags) + RegisterFlag(opt, flag, preserveInterface); return RunAndCopy(opt, words); } finally From 354944d7eb9af89d937dbc7be1974d8eaf6e994b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 11:53:59 +0900 Subject: [PATCH 1110/1182] SDSL: fix StructuredBuffer layout to satisfy Vulkan std430 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apply std430 base alignment to vector members and round ArrayStride up to struct alignment when emitting [RW]StructuredBuffer element types. Relaxed block layout allows scalar-aligned vectors but forbids them straddling 16-byte boundaries, and requires array-of-struct stride to match the struct's base alignment. Previously RWStructuredBuffer where Test = { float3 A1; float2 A2 } emitted ArrayStride=20 with A2 at offset 12 — valid D3D packing but rejected by spirv-val. --- .../SDSL/ShaderMixer.Decorations.cs | 5 +- ...dStructuredBufferMethodsImplementations.cs | 2 +- .../Spirv/Building/Builder.CBuffer.cs | 50 +++++++++++++++++++ .../Spirv/Building/SpirvContext.Types.cs | 4 +- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs index efd75fc951..e543b8cf71 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.Decorations.cs @@ -47,11 +47,10 @@ private void EmitArrayStrideDecorations(SpirvContext context, ArrayType a, TypeM return; } - var elementSize = SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size; arrayStride = alignmentRules switch { - SpirvBuilder.AlignmentRules.CBuffer => (elementSize + 15) / 16 * 16, - SpirvBuilder.AlignmentRules.StructuredBuffer => elementSize, + SpirvBuilder.AlignmentRules.CBuffer => (SpirvBuilder.TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules).Size + 15) / 16 * 16, + SpirvBuilder.AlignmentRules.StructuredBuffer => SpirvBuilder.StorageBufferArrayStride(a.BaseType, typeModifier), _ => throw new NotSupportedException($"Unsupported alignment rules: {alignmentRules}"), }; context.Add(new OpDecorate(typeId, Specification.Decoration.ArrayStride, [arrayStride])); diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs index 5625e50ad8..d46add2c13 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/AppendStructuredBufferMethodsImplementations.cs @@ -30,7 +30,7 @@ public override SpirvValue CompileGetDimensions(SymbolTable table, SpirvContext var arrayLen = builder.Insert(new OpArrayLength(uintType, context.Bound++, appendStructuredBuffer.Id, 0)); builder.Insert(new OpStore(count.Id, arrayLen.ResultId, null, [])); var baseType = functionType.ParameterTypes[0].Type; - var elementSize = SpirvBuilder.TypeSizeInBuffer(baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var elementSize = SpirvBuilder.StorageBufferArrayStride(baseType); var strideConst = context.CompileConstant((uint)elementSize); builder.Insert(new OpStore(stride.Id, strideConst.Id, null, [])); return default; diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs index a4c591be7a..10c67417a9 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs @@ -31,6 +31,13 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Boolean } => (4, 4), ScalarType { Type: Scalar.Int64 or Scalar.UInt64 or Scalar.Double } => (8, 8), StructuredType s => StructSizeInBuffer(s, alignmentRules), + // StructuredBuffer uses std430 vector alignment (2×scalar for vec2, 4×scalar for vec3/vec4) + // to satisfy Vulkan's relaxed block layout rule that a vector must not straddle a + // 16-byte boundary. CBuffer keeps scalar alignment — ComputeBufferOffset handles the + // "vector crossing 16-byte boundary" bump separately for that path. + VectorType v when alignmentRules == AlignmentRules.StructuredBuffer + => (TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules).Size * v.Size, + TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules).Alignment * (v.Size == 2 ? 2 : 4)), VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules), v.Size), // Note: this is HLSL-style so Rows/Columns meaning is swapped // Note: HLSL default is ColumnMajor @@ -108,4 +115,47 @@ public static void PadOffsetAfterArray(SymbolType type, TypeModifier typeModifie constantBufferOffset = paddedEnd; } } + + /// + /// Computes the std430 base alignment of a type as required by Vulkan's storage buffer layout + /// (vec2 → 2×scalar, vec3/vec4 → 4×scalar, struct → max member alignment). Used to round the + /// ArrayStride of a [RW]StructuredBuffer element type so the SPIR-V validates under relaxed + /// block layout. Relaxed rules allow scalar-aligned offsets for vector members, but an array + /// of structs still needs its stride aligned to the struct's base alignment. + /// + public static int StorageBufferBaseAlignment(SymbolType type, TypeModifier typeModifier = TypeModifier.None) => type switch + { + ScalarType { Type: Scalar.Int or Scalar.UInt or Scalar.Float or Scalar.Boolean or Scalar.Half } => 4, + ScalarType { Type: Scalar.Int64 or Scalar.UInt64 or Scalar.Double } => 8, + VectorType { Size: 2, BaseType: var bt } => 2 * StorageBufferBaseAlignment(bt), + VectorType { Size: 3 or 4, BaseType: var bt } => 4 * StorageBufferBaseAlignment(bt), + MatrixType m when typeModifier == TypeModifier.RowMajor + => StorageBufferBaseAlignment(new VectorType(m.BaseType, m.Columns)), + MatrixType m + => StorageBufferBaseAlignment(new VectorType(m.BaseType, m.Rows)), + ArrayType a => StorageBufferBaseAlignment(a.BaseType, typeModifier), + StructuredType s => MaxMemberAlignment(s), + _ => throw new NotSupportedException($"Unsupported type for storage buffer alignment: {type}"), + }; + + static int MaxMemberAlignment(StructuredType s) + { + var max = 4; + foreach (var member in s.Members) + max = Math.Max(max, StorageBufferBaseAlignment(member.Type, member.TypeModifier)); + return max; + } + + /// + /// Returns the ArrayStride required for when used as the element + /// of a [RW]StructuredBuffer's runtime array. The value is the packed size (via + /// ) rounded up to the type's std430 base alignment, so that the + /// emitted SPIR-V validates under relaxed block layout. + /// + public static int StorageBufferArrayStride(SymbolType elementType, TypeModifier typeModifier = TypeModifier.None) + { + var size = TypeSizeInBuffer(elementType, typeModifier, AlignmentRules.StructuredBuffer).Size; + var alignment = StorageBufferBaseAlignment(elementType, typeModifier); + return (size + alignment - 1) / alignment * alignment; + } } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs index 1ad08ece1e..63ec868f1c 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/SpirvContext.Types.cs @@ -197,7 +197,7 @@ public int RegisterType(SymbolType type, int id) private int RegisterStructuredBufferType(StructuredBufferType structuredBufferType) { - var elementSize = SpirvBuilder.TypeSizeInBuffer(structuredBufferType.BaseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var elementSize = SpirvBuilder.StorageBufferArrayStride(structuredBufferType.BaseType); var runtimeArrayType = GetOrCreateRuntimeArray(GetOrRegister(structuredBufferType.BaseType), elementSize); var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; @@ -210,7 +210,7 @@ private int RegisterStructuredBufferType(StructuredBufferType structuredBufferTy private int RegisterAppendOrConsumeStructuredBufferType(string prefix, SymbolType baseType) { - var elementSize = SpirvBuilder.TypeSizeInBuffer(baseType, TypeModifier.None, SpirvBuilder.AlignmentRules.StructuredBuffer).Size; + var elementSize = SpirvBuilder.StorageBufferArrayStride(baseType); var runtimeArrayType = GetOrCreateRuntimeArray(GetOrRegister(baseType), elementSize); var bufferType = Buffer.Add(new OpTypeStruct(Bound++, [runtimeArrayType])).ResultId; From 7462e7dfe9a0a16d9f9c90ad7e7870101247d033 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 11:55:31 +0900 Subject: [PATCH 1111/1182] ci: enable automatic CI again --- .github/workflows/main.yml | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4553829256..194db56dcf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,32 +1,32 @@ name: CI -#on: -# push: -# branches: -# - master -# paths: -# - '.github/workflows/**' -# - 'build/**' -# - 'deps/**' -# - 'sources/**' -# - '!**/.all-contributorsrc' -# - '!**/.editorconfig' -# - '!**/.gitignore' -# - '!**/*.md' -# - '!crowdin.yml' -# pull_request: -# paths: -# - '.github/workflows/**' -# - 'build/**' -# - 'deps/**' -# - 'sources/**' -# - '!**/.all-contributorsrc' -# - '!**/.editorconfig' -# - '!**/.gitignore' -# - '!**/*.md' -# - '!crowdin.yml' -# types: [opened, synchronize, reopened, ready_for_review] -# workflow_dispatch: +on: + push: + branches: + - master + paths: + - '.github/workflows/**' + - 'build/**' + - 'deps/**' + - 'sources/**' + - '!**/.all-contributorsrc' + - '!**/.editorconfig' + - '!**/.gitignore' + - '!**/*.md' + - '!crowdin.yml' + pull_request: + paths: + - '.github/workflows/**' + - 'build/**' + - 'deps/**' + - 'sources/**' + - '!**/.all-contributorsrc' + - '!**/.editorconfig' + - '!**/.gitignore' + - '!**/*.md' + - '!crowdin.yml' + types: [opened, synchronize, reopened, ready_for_review] + workflow_dispatch: permissions: checks: write From 677d45e1cdc682209cc63ba7f66729aa2eedb442 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 12:08:56 +0900 Subject: [PATCH 1112/1182] SDSL: fix matrix size miscalculation in StructuredBuffer layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MatrixType in TypeSizeInBuffer had a stray * 4 in the StructuredBuffer branch, so float4x4 reported 256 bytes instead of 64. Any RWStructuredBuffer would have emitted a broken ArrayStride — luckily the only real user is InstanceTransform, a float4x4 inside its own struct, and that path wasn't validated by a unit test. Replace the formula with std430 strict matrix layout: each column (ColumnMajor) or row (RowMajor) is padded to its std430 base alignment. Covers non-square matrices correctly under Vulkan relaxed block layout. Adds CSMatrix.sdsl regression test covering RWStructuredBuffer where Transform = { float4x4 Matrix; float3 Scale }. --- .../Spirv/Building/Builder.CBuffer.cs | 28 +++++++++++++++++-- .../assets/SDSL/ComputeTests/CSMatrix.sdsl | 24 ++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 sources/shaders/assets/SDSL/ComputeTests/CSMatrix.sdsl diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs index 10c67417a9..29ce3bbd8d 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Builder.CBuffer.cs @@ -41,10 +41,15 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type VectorType v => MultiplySize(TypeSizeInBuffer(v.BaseType, typeModifier, alignmentRules), v.Size), // Note: this is HLSL-style so Rows/Columns meaning is swapped // Note: HLSL default is ColumnMajor + // StructuredBuffer uses std430 strict matrix layout: each column (ColumnMajor) or row + // (RowMajor) is padded to its std430 base alignment, matching how the Vulkan validator + // expects matrix layout under relaxed block layout. + MatrixType m when alignmentRules == AlignmentRules.StructuredBuffer + => StructuredBufferMatrixSize(m, typeModifier), MatrixType m when typeModifier == TypeModifier.ColumnMajor || typeModifier == TypeModifier.None - => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), alignmentRules == AlignmentRules.CBuffer ? (4 * (m.Rows - 1)) + m.Columns : m.Rows * m.Columns * 4), + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), (4 * (m.Rows - 1)) + m.Columns), MatrixType m when typeModifier == TypeModifier.RowMajor - => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), alignmentRules == AlignmentRules.CBuffer ? (4 * (m.Columns - 1)) + m.Rows : m.Rows * m.Columns * 4), + => MultiplySize(TypeSizeInBuffer(m.BaseType, typeModifier, alignmentRules), (4 * (m.Columns - 1)) + m.Rows), // Round up to 16 bytes (size of float4) ArrayType a => Array(TypeSizeInBuffer(a.BaseType, typeModifier, alignmentRules), a.Size, alignmentRules), // TODO: StructureType @@ -52,6 +57,25 @@ public static (int Size, int Alignment) TypeSizeInBuffer(SymbolType symbol, Type }; } + /// + /// Computes std430 size and alignment for a matrix in a StorageBuffer. + /// ColumnMajor: matrix is an array of Columns column-vectors of dimension Rows. + /// RowMajor: matrix is an array of Rows row-vectors of dimension Columns. + /// Each element vector is laid out at its std430 base-alignment stride, so non-square matrices + /// get trailing padding on the short axis. + /// + private static (int Size, int Alignment) StructuredBufferMatrixSize(MatrixType m, TypeModifier typeModifier) + { + var (vecDim, vecCount) = typeModifier == TypeModifier.RowMajor + ? (m.Columns, m.Rows) + : (m.Rows, m.Columns); + var scalarSize = TypeSizeInBuffer(m.BaseType, typeModifier, AlignmentRules.StructuredBuffer).Size; + var vecSize = scalarSize * vecDim; + var vecAlignment = StorageBufferBaseAlignment(new VectorType(m.BaseType, vecDim)); + var vecStride = (vecSize + vecAlignment - 1) / vecAlignment * vecAlignment; + return (vecStride * vecCount, vecAlignment); + } + private static (int, int) StructSizeInBuffer(StructuredType s, AlignmentRules alignmentRules) { var offset = 0; diff --git a/sources/shaders/assets/SDSL/ComputeTests/CSMatrix.sdsl b/sources/shaders/assets/SDSL/ComputeTests/CSMatrix.sdsl new file mode 100644 index 0000000000..28811c2c6b --- /dev/null +++ b/sources/shaders/assets/SDSL/ComputeTests/CSMatrix.sdsl @@ -0,0 +1,24 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +shader CSMatrix +{ + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + + struct Transform + { + float4x4 Matrix; + float3 Scale; + }; + + RWTexture2D Output; + RWStructuredBuffer Output2; + + [numthreads(1, 1, 1)] + void CSMain() + { + Output[int2(0, 0)] = float4(0, 0, 0, 0); + Output2[0].Scale = float3(0, 0, 0); + } +} From 4d4dda5a7b29be03e42092449881fcd559d79645 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 13:09:08 +0900 Subject: [PATCH 1113/1182] build: remove legacy Custom Tool wiring for .sdsl/.sdfx Reintroduced when Stride.Build.Sdk was merged from master (PR #3085); sdsl-rewrite had already switched to the Roslyn source generator. The stale wiring caused VS to regenerate .sdsl.cs/.sdfx.cs on disk, which then collided with the Roslyn-emitted obj/ files (CS0111/CS0579 duplicate types). --- sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets index d0f543b327..cae06c35c1 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets @@ -92,10 +92,6 @@ - - - - From fab9410b0a49d9b9860e8fde2edded5f8635acb3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 14:50:32 +0900 Subject: [PATCH 1114/1182] ci: use nuget version of D3D WARP so that graphics tests are more easily reproducible --- sources/Directory.Packages.props | 1 + .../Stride.Graphics.Regression.csproj | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index 6174ec2608..cb433d0e05 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -105,6 +105,7 @@ + diff --git a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj index 3e0db954e9..c4d41425ee 100644 --- a/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj +++ b/sources/engine/Stride.Graphics.Regression/Stride.Graphics.Regression.csproj @@ -33,6 +33,17 @@ --> + + + + From 456f444af6ebef0d199e7677aeed44e6d605dc33 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 16:21:13 +0900 Subject: [PATCH 1115/1182] ci: bumped gold to new D3D nuget WARP --- sources/engine/Stride.Engine.Tests/TesselationTest.cs | 2 -- .../Windows.Direct3D11/WARP/TesselationTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/TesselationTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/TesselationTest.f3.png | 4 ++-- .../Windows.Direct3D11/WARP/TesselationTest.f4.png | 4 ++-- .../Windows.Direct3D11/WARP/TesselationTest.f5.png | 4 ++-- .../Windows.Direct3D11/WARP/TesselationTest.png | 4 ++-- .../Windows.Direct3D12/WARP/TesselationTest.f1.png | 3 +++ .../Windows.Direct3D12/WARP/TesselationTest.f2.png | 3 +++ .../Windows.Direct3D12/WARP/TesselationTest.f3.png | 3 +++ .../Windows.Direct3D12/WARP/TesselationTest.f4.png | 3 +++ .../Windows.Direct3D12/WARP/TesselationTest.f5.png | 3 +++ .../Windows.Direct3D12/WARP/TesselationTest.png | 4 ++-- .../LightingTests.SceneDirectionalLightShadowOneCascade.png | 4 ++-- ...LightingTests.SceneDirectionalLightShadowOneCascadePCF.png | 4 ++-- ...ightingTests.SceneDirectionalLightShadowOneFourCascade.png | 4 ++-- .../WARP/LightingTests.ScenePointLightShadowCubeMap.png | 4 ++-- ...LightingTests.SceneTwoDirectionalLightShadowOneCascade.png | 4 ++-- .../Windows.Direct3D11/WARP/TestDynamicSpriteFontJapanese.png | 4 ++-- .../WARP/TestDynamicSpriteFontVarious.f1.png | 4 ++-- .../WARP/TestDynamicSpriteFontVarious.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.png | 4 ++-- .../Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png | 4 ++-- .../Windows.Direct3D11/WARP/TestLightShafts.png | 4 ++-- .../Windows.Direct3D11/WARP/TestSpriteBatch3D.png | 4 ++-- .../Windows.Direct3D11/WARP/TestSpriteBatchResolution.f2.png | 4 ++-- .../WARP/LightingTests.ScenePointLightShadowCubeMap.png | 4 ++-- .../Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png | 4 ++-- .../Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png | 4 ++-- .../Windows.Direct3D12/WARP/TestLambertPrefilteringSH.png | 3 +++ .../Windows.Direct3D12/WARP/TestLightShafts.png | 4 ++-- .../Windows.Direct3D11/WARP/ContentDecoratorTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/ContentDecoratorTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/ContentDecoratorTest.png | 4 ++-- .../Windows.Direct3D11/WARP/DynamicFontTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/DynamicFontTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/DynamicFontTest.f4.png | 4 ++-- .../Windows.Direct3D11/WARP/DynamicFontTest.f5.png | 4 ++-- .../Windows.Direct3D11/WARP/DynamicFontTest.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollViewerTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollViewerTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollViewerTest.f8.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f3.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f4.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f5.png | 4 ++-- .../Windows.Direct3D11/WARP/ScrollingTextTest.f6.png | 4 ++-- .../Windows.Direct3D11/WARP/SliderTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/SliderTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f10.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f11.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f12.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f13.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f14.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f3.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f4.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f5.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f6.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f7.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f8.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.f9.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockTest.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f1.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f2.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f3.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f4.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f5.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f6.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f7.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f8.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.f9.png | 4 ++-- .../Windows.Direct3D11/WARP/TextBlockWrappingTest.png | 4 ++-- 75 files changed, 154 insertions(+), 138 deletions(-) create mode 100644 tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png create mode 100644 tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f2.png create mode 100644 tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f3.png create mode 100644 tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f4.png create mode 100644 tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f5.png create mode 100644 tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLambertPrefilteringSH.png diff --git a/sources/engine/Stride.Engine.Tests/TesselationTest.cs b/sources/engine/Stride.Engine.Tests/TesselationTest.cs index 9753c2a353..2fd458338b 100644 --- a/sources/engine/Stride.Engine.Tests/TesselationTest.cs +++ b/sources/engine/Stride.Engine.Tests/TesselationTest.cs @@ -202,8 +202,6 @@ private void ChangeMaterial(int i) [SkippableFact] public void RunTestGame() { - SkipTestForGraphicPlatform(GraphicsPlatform.Direct3D12, "tessellation pipeline state creation fails"); - RunGameTest(new TesselationTest()); } diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f1.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f1.png index e862a0fd9e..415e00f768 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f1.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b48bbc3343fe80c1b689ca5d5eb8ece7cf869cd26228705d703d9008e0526bd1 -size 83028 +oid sha256:5cc72d6072c4429dac561e7e8709c8a7be186ab949571a3109aab96d124ab60e +size 83023 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f2.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f2.png index 101d6f3bf6..60c7ed8df4 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f2.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba269e707b416dd05fcad7c54bf840cd58406d63a1cff322501ac764c7a328d3 -size 54026 +oid sha256:e2f800269806826b455eab67e790922235410b0c03cd624f1f7364ef90b825bb +size 54029 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f3.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f3.png index a9f9d893f0..914a243385 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f3.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c32109d3f52de60e02597e2611b5d6f8f9f06215a273bbfc004cafeaa6850dab -size 77118 +oid sha256:b0fc270c884f4361850fcbe63e8459a2f4ff1875a0ed96414ca71ac26dfe576a +size 77119 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f4.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f4.png index cc8a0b9f06..5205fad556 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f4.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a97bf805d06a1616a0e4a977427530d2012ea4530417c48a019e9803c514e5c9 -size 70432 +oid sha256:3edd6bc3fc6ff8f9f4260b63f05c16250984dbda5087f6dc6eda0901c563d1b5 +size 70453 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f5.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f5.png index 37c2e5df72..6f68fcb7a5 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f5.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7403e9aa25ca2aadca9aea90d0b1afd68c88fbc9ac93256a3a88879e9c76266f -size 81567 +oid sha256:9e862677254651f39a8268e9399b4e40dcdf6b509e3f48ea376e89d0b6f1fb83 +size 81562 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.png b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.png index c867ec762a..670a5b7d74 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D11/WARP/TesselationTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5d3d26c077709777334294704ef9d466bce1d506b82d8ed094daecbf54b0220 -size 70294 +oid sha256:04f81c0e04562a31f7e86a4f7e124c6519bb69f1f40d67887265c270f8585fab +size 70291 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png new file mode 100644 index 0000000000..2f36580345 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4aa6347e1ee634c029adf07657ec3fc4232d9316307e3fb8b97fe38bbdc17c97 +size 80710 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f2.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f2.png new file mode 100644 index 0000000000..d57e21e927 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc2651aad855e84e9e190a29939cf27cea3436027e14958fbb65d722df170f95 +size 47102 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f3.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f3.png new file mode 100644 index 0000000000..d6f095bb13 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aa5bca8b7ec039a6ed9f5dcf32ab9a7204952638f4988ae5c1ebe9028079c03c +size 80173 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f4.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f4.png new file mode 100644 index 0000000000..a5b494e22a --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce00857265639afa0892c79a22a8b6ca87a374218389e9b46f9280c894e8e9f1 +size 69234 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f5.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f5.png new file mode 100644 index 0000000000..b5078a5bc8 --- /dev/null +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04ec9acb36b8cb0dac9bdf1cb7734223a9efbd72f8907d5d5017f12470b5a204 +size 72559 diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.png index 29df54cd29..944f4c4def 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6d2528d5d532de4c64fe6cecc7677643ffc9ea28dfa85149c76757f8a123eacb -size 73604 +oid sha256:8d8827d85ab0f5b8315b0c578eead400e6d092023fac1a0d5518c872121e735b +size 73638 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascade.png index 86f9d011ff..29a00a812c 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascade.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascade.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a14240956df1f832654dbb0b60690d4bffeb34eb35deef341a6c68895e3c1e38 -size 236750 +oid sha256:28852e6336cfbe3cbc8cc84bc474b8deed8b0ea95dbb3fd3f917e839e5a6d3fd +size 236729 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png index e90c246d12..180b6cfd39 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneCascadePCF.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:225004d1c5105ebc3a765f354982ffc19894e5622e4137dc60023cd34defa961 -size 242042 +oid sha256:ad11cd85d56ff654a5bf295a4d62b9bea610caa44d03a7d0213874720a4039c1 +size 242028 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneFourCascade.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneFourCascade.png index 3ac786e628..9b2c0f9887 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneFourCascade.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneDirectionalLightShadowOneFourCascade.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae9743c6fe12a857f760518820b8a9bf74aa810bce3779b81421a6c1db40ce1e -size 240802 +oid sha256:159a49fa2ef8d3a7f296ed05e4d0ea340806b477d8bb139ae14fdeca1754024c +size 240791 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.ScenePointLightShadowCubeMap.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.ScenePointLightShadowCubeMap.png index 341e54ee18..7a95a3bd9a 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.ScenePointLightShadowCubeMap.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.ScenePointLightShadowCubeMap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8cd794f2d77eb1393ccd15cebe21b139f0ed039dd928d4475e9d9cedfe477e7e -size 228524 +oid sha256:d10d224bec242229af3d467b89cbf4d9ae6d09fc89107fc8c3e5ee53a1a9b864 +size 228494 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png index 23c6e61466..25410b247c 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/LightingTests.SceneTwoDirectionalLightShadowOneCascade.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ef00ec4ae8e9a01cab972b48e820cd3c6b7ce92f5e28c1beb9ef974d0c388b97 -size 249597 +oid sha256:d648feb55f94ec625f1b9a8ef6f279900f41f7aa8c23db8029056b80a8ac672a +size 249615 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontJapanese.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontJapanese.png index a2334bf538..fdf7da6ebe 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontJapanese.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontJapanese.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4922b3cc5a9bc5a4543cf7ae2580b848ed7734caac77f4b4ee22c71681ed5a3 -size 99488 +oid sha256:8ded3857e604e754577ae1104cd4ea4db8409ff64cf636e319fffd920c0fc0e9 +size 99546 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f1.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f1.png index b4438e1f52..84bf73b13e 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:29a77f8e2b3f78a4ea32f15a260f7c58ae275d2f159c74627e36dc931b15890f -size 17071 +oid sha256:48afd2f9637721d1d1d5dd3fef0e6c4ef4f8ae4684bee9eda35986272ffb463e +size 17119 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f2.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f2.png index 939ef8ef8b..ff5a92ede4 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:270ab731598e0e04efb366bff53fe95dbff7e5e0606415f2120f65f47017b11c -size 17853 +oid sha256:74d91f82b00717fb2f6a3f29eca0f28e72ed7436ce7c4506c9547eff64bfc530 +size 17892 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.png index 3d392f306e..d4cfa3ef88 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestDynamicSpriteFontVarious.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bf4a0ca4f60570b2a2a87d5a91f53b73ede8f61c94f2c4a6414951a133b94329 -size 9401 +oid sha256:1a216acf2993edb6c73895548d35c301d1c16869fe780bc56ae511902491f732 +size 9460 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png index 4a083c889f..094133f567 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLambertPrefilteringSH.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e095f06416640128f704ab5dbb377982e37ced3a3729a91c25ab0bab77203649 -size 101346 +oid sha256:e5107092cebed2494ecc764c8c010972899fd2283bc40bfd70fab8e337a8c723 +size 101336 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png index d70436e0b9..b9ff8f8ee7 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:de15d7eb940b4a92179ce81da2685b7adc94fbd3aef6371be8bc105d067df80d -size 120790 +oid sha256:3606d0cb692ffdae58d01a6866f8b0a25def810f4ff8093370e4e958cd4a1734 +size 120580 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatch3D.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatch3D.png index 5d7e4cd913..da59bac26c 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatch3D.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatch3D.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dc3e94c2c3983276a4f8d52312e99a33719e51cc60312b6117397f5c15f121c6 -size 34067 +oid sha256:72cf99d22f297f7e6671fb6d0348b69aad987f365c7d6fe3bedf3560451fb77b +size 34095 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatchResolution.f2.png b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatchResolution.f2.png index d80890c72d..803a3becd1 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatchResolution.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D11/WARP/TestSpriteBatchResolution.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb7e471d1615e73aa7a68e948a401f6a3b9a69c94ebea6841205b53e25973946 -size 80066 +oid sha256:d2b649a4e22ed91636910797799f9313e7228276acd0f1387b9c1a2e9fd4f4af +size 80073 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png index 4938a3c7dd..55c4f2ecc1 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/LightingTests.ScenePointLightShadowCubeMap.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ac8a3a0dc1cf7f81a376891c987ca13ca1ccadf01d9a3d2ebae463bbf452fb6 -size 228498 +oid sha256:f2745b002ef1fc8822ecade38091f1f0c0bd90c75d786114c81ad6c7436a6c35 +size 228488 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png index e0d943558f..282664370c 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c4ea4be5e4688a3913ee2e0a1bd888564384f4444d7f1ad5d9a3fb188ba60d8a -size 85254 +oid sha256:c708c7085a6f7527d0bcc9e72ddd99d8c332ebfcd004f402c2a014a40f1de75c +size 85249 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png index 953b674855..5a92e749ff 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestGeometricPrimitives.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d0598c82d08ac3fabc1030608e16e87fbe3bd1f8cc163bba99048708358863f -size 82522 +oid sha256:95283c33d06d9a618dc4d125ab39755d0646e9b1664db58af5b9b115b26d8347 +size 82531 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLambertPrefilteringSH.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLambertPrefilteringSH.png new file mode 100644 index 0000000000..8937955c79 --- /dev/null +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLambertPrefilteringSH.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b8b7748daa956d6d9dd906584e41255255825fc796d3ce3fb4f5339fa6a0ebf +size 101344 diff --git a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png index aab02773b6..45a9d4dc54 100644 --- a/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png +++ b/tests/Stride.Graphics.Tests/Windows.Direct3D12/WARP/TestLightShafts.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:740a4cadf0b6c530cf74b1057a67076b3e28b34131a915a57b6b40c38f77d45c -size 120674 +oid sha256:553ac23d847b4a7eeb857ba1f1d1e75e84145d4ce85c3fb10b0201ab5ae6b886 +size 120972 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f1.png index 53f9b611ab..2b6029f37e 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:207057febf6be3565bf2776fd7b418020e5b1029744871db14cbb025a5f306c2 -size 3186 +oid sha256:ea72a8382af6b47c8ef586c45dc84e7c25cbfe32698545410f823941f4f03f08 +size 3180 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f2.png index a73299db76..f62b2bbac5 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ff970420b40bb90d5d76ea47adde71edb635ee346402e225e9c8f878c082bc6 -size 3567 +oid sha256:e3f1379e33502ae7bcff6ae98945b9c0abda4658180ab8e3e1cf2d66ad426a54 +size 3555 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.png index e64305e0bd..72b71952e0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ContentDecoratorTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f2aaf321796878bd960da6938d17267b43d5fac1bd9f9a53691dcfb03803adf -size 2777 +oid sha256:5b664822c77eaf42b68bc936b3ff52021a6d65f55e4a75c6c2d2ae01cc886327 +size 2824 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f1.png index 8981c0bd0a..9d17fb055b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d71be399909ab88b81f9db8157ec42b2469f8c42d89c90be165cbd29aa7dbea -size 3561 +oid sha256:dd5ad83541d7a5685b633c81d7abe996f1af4f89926050eac68abe3d8452bbaf +size 3633 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f2.png index 8981c0bd0a..9d17fb055b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d71be399909ab88b81f9db8157ec42b2469f8c42d89c90be165cbd29aa7dbea -size 3561 +oid sha256:dd5ad83541d7a5685b633c81d7abe996f1af4f89926050eac68abe3d8452bbaf +size 3633 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f4.png index e16e7f7362..679470e41a 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d02d473f6554aaf0756a3bf0547ee35442872d07fa836e634dbb17f92b60432e -size 3441 +oid sha256:acdef7ffae6db27448e4d2cd2e3c4bf64a26d77b0b6b7252c2664edb9a73197f +size 3496 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f5.png index b995e00012..3dd90c7ea6 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69d1907b747587f75fced84b537909539b60f7b11b086eb80928d9e7d0c6c1f4 -size 3564 +oid sha256:1018e835c5b5814e5a3258473e6fa17e14b22baf1471090d02329abfe2420402 +size 3644 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.png index b9b6e2962d..77f6f5f71f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/DynamicFontTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2344e3b2425e66bed63ee06ed2f241c490f94372d7b6a8d20432e32cfe0d51a9 -size 2995 +oid sha256:ea22e26b87410a910e61cf31e9717a22e0c1624396686fbcb8595fbe7cb77acb +size 3014 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f1.png index ee73a55a0b..113e833ea8 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ffd94760748adb9c72282659317b741aa29c669e6faa07e29ffb39602ce49b56 -size 437428 +oid sha256:fa46debdfb1bb420ffd1049d5d93e597286e47713454abb1c3860a6245c14c79 +size 437454 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f2.png index d7ba3e4653..e3f4b3bc86 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8584166c9c720dd03ad4f20551b6acda06b9dcc36e7a60d40be48d1d5af12c6d -size 436096 +oid sha256:8697b09a9160a5311cfc776768ef136a7704c6d2fd5a9bf20c4c8cca2bbb0056 +size 436089 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f8.png index d7ba3e4653..e3f4b3bc86 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollViewerTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8584166c9c720dd03ad4f20551b6acda06b9dcc36e7a60d40be48d1d5af12c6d -size 436096 +oid sha256:8697b09a9160a5311cfc776768ef136a7704c6d2fd5a9bf20c4c8cca2bbb0056 +size 436089 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f1.png index 42b4ad74e5..00f929e58b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f01194dd87724395042294a218450c7417b53bf59b516da4f45dfca62f7dd50c -size 2718 +oid sha256:21b2b88fbb4eee5f75d541814a22ec3f7c4dde77ae14a9ecdeaeb8e99c1c8e84 +size 2734 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f2.png index 44997efb07..9310aecaed 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd23659874f557d8eff3cfaa6568f8a5bf8cffd25d20f2368a08c0e03b233bd1 -size 2717 +oid sha256:68754f0225d107649956241fdf44560004c429dfb732196f9d958fc04d4b11d6 +size 2736 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f3.png index 42b4ad74e5..00f929e58b 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f01194dd87724395042294a218450c7417b53bf59b516da4f45dfca62f7dd50c -size 2718 +oid sha256:21b2b88fbb4eee5f75d541814a22ec3f7c4dde77ae14a9ecdeaeb8e99c1c8e84 +size 2734 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f4.png index 4bd1b9457e..c55f89754e 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b55945a11a658745b1fcf50dfd324406b66cc7c69cb70010e9e7bf87dd35ecf -size 2426 +oid sha256:f4c2b67f8b83e400e5dbb02a707c82733e521a0a155cbcf2b4134a61f39a97cb +size 2418 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f5.png index bbbe4e6a62..b4156728ed 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3ad44d39d3f4f5f3913b1191466c68ea301d1aff080d707eda41ccd83d4296c2 -size 3093 +oid sha256:1bf74903ef30766308152a3fdee4907e511708c410d7a291858ffbd5d949a068 +size 3055 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f6.png index 189b6a1bc9..1ef59f3799 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/ScrollingTextTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1244a37c67f9534bdd38416df479ca62c236169485760a3f718834fcd7561501 -size 2858 +oid sha256:f22fb3bfc927e9e18b8d0df44a5206664b9536197c68bd746e4f3c2c65e42698 +size 2865 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f1.png index a3433ef342..266aa3aea9 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0c0476e91b3cbe30abda3a63de31b386afb244cd5c30a2166f68daa347f0bd7 -size 11575 +oid sha256:889d6d58776584e95a14d0e6d31315d8ef17672ce53ccb8d56ccdf0f509a0306 +size 11572 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f2.png index ced30fc0e7..c4dff3a9e6 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/SliderTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:125970f459b53ab717d6b22538a030ad378d64c9c6317f74096821832c19928f -size 11022 +oid sha256:784f5e5b93634335aee797437933c7313c5bd0b3740572d5fbbec46c650e559f +size 11018 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f1.png index 8d055dbe81..79e15a63ca 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f3b7d0f1272d7f50caeac03b5d17a177695df75056c5cb9ecf3f809090d2abc -size 4387 +oid sha256:ecc3c8f766a117840636101a142e1680493073298a71fd0c90e04a03c64f1c2b +size 4432 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f10.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f10.png index 67fe7eb240..6cd9b4fd84 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f10.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f10.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:10e06346390570a7a65a0dbae65798dda347ad719dff3c12beee8ccedfa1bf2d -size 4540 +oid sha256:50f36adf5d5abc45f853c9a66fa326a28557924a103d5d509b90d0ce9671a664 +size 4583 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f11.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f11.png index 8d5d66c153..25ce1a419f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f11.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f11.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad0eddcd6e1ea672855e0e9955ff124a26c66bf14c0b83f850e412aa0edc1245 -size 7044 +oid sha256:733d2c89273bc1f426c9819d8834c1801acfc14b62cabcf158d8c047e61fb535 +size 6995 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f12.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f12.png index 5784cb238b..a1c860cf36 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f12.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f12.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8968ff8fe1065b918c16c1e62de463926ac774ae31477ff5d0faadbcdf47360f -size 3395 +oid sha256:fadd198b8119abbeb26c4a9372e47487cc904f58ed08bab45d139a58985d0e94 +size 3414 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f13.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f13.png index 8d5d66c153..25ce1a419f 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f13.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f13.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad0eddcd6e1ea672855e0e9955ff124a26c66bf14c0b83f850e412aa0edc1245 -size 7044 +oid sha256:733d2c89273bc1f426c9819d8834c1801acfc14b62cabcf158d8c047e61fb535 +size 6995 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f14.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f14.png index 5784cb238b..a1c860cf36 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f14.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f14.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8968ff8fe1065b918c16c1e62de463926ac774ae31477ff5d0faadbcdf47360f -size 3395 +oid sha256:fadd198b8119abbeb26c4a9372e47487cc904f58ed08bab45d139a58985d0e94 +size 3414 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f2.png index f6f682bcd1..044f98cb11 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a5a33e4f019621f54087a0fd82401b27759122fb495a55dff429ba6abb5a52a7 -size 4244 +oid sha256:8b1c282c6bfe5070c714919c8310e9f660466d69fe9f3d039c95a81f89410159 +size 4273 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f3.png index a909d7e80a..c0874367f7 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c22f85a222a814beeb92686753a0a28a087c9baf19134fdf147a2f39510a0086 -size 4400 +oid sha256:9b5334de0215c5d599a5e5eacb6fda208b72e168039652033f10e74c49d2403b +size 4402 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f4.png index b48755d37e..3e4f25ce67 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0533c832c6d51343020cc2b397e7ced788e6bad41a2c0e633290fb280104b161 -size 4587 +oid sha256:56555cd7269ae4af407c824ce2cfb518a2547e0d99ea13e0d16f6d58a84b0642 +size 4527 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f5.png index 29158cb858..68d6a93bc0 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d2e135304b1ca86ea2c92ec491e8610b8a476e05597954ce8633a88f4aeae0db -size 4491 +oid sha256:fada6e7c9a4defb4ab93504de5194a905d83fe86731310b6b61acf6e1cc5fc29 +size 4518 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f6.png index b9127bed4b..f67b016f62 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:116642b1960219a213b0c895f72fcc6f1a96c9a43074ab9d4857aaf59ac1f925 -size 4531 +oid sha256:dd4475b37398d1692968a68e5076c0c0e1eb7f99d1d773c5b09848457885c615 +size 4569 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f7.png index 77658dc67d..6b59c6839c 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dae4b7b5ff73012c893401c04960d75ee24b1b01b58763b3a3b4a024fe4ec86e -size 4469 +oid sha256:1a18516897073aaf593727e6e0d776e1922f155f0a7718e83d2594922ae13acd +size 4527 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f8.png index 06ce1ede19..92f3566e40 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98635334eae3c7db7609498976401643ee8249f7a9cddc2b2d5c4444d1a8fdcf -size 4515 +oid sha256:76aec431aeb0250ed8082ee1a925b18867646e63bd36fe91e1c4391dd0f416bc +size 4576 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f9.png index 02e62c6369..8d90f64acc 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb388a5ccb49ee9b063ac974c88eb0266be6e291e55d12c2809eac9d4bf7de8d -size 4537 +oid sha256:4e3d3b5021db6cda5d5bd3d4e1309674f24c3a52c7c5bb917856081ca4c6e7db +size 4575 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.png index 2c153e3195..b18da8b820 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d97ab8fed91d51a83c922880d46ae4c7f739d078482f8220a6d5eebf866db907 -size 4394 +oid sha256:78af77409ff22885bfbb53fc2375a351f26f2ab65dfdf317410e97b2b3066994 +size 4395 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f1.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f1.png index daedf80d56..d30c259f92 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f1.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d40b70a7380a6c69eee4f489f0bd300e53a77acca83ebdd982781a3804ebc9 -size 8153 +oid sha256:8a7102f8d010a7df63612178817bed65cb9d51e8ceb7817c7b0d0362a0d07ce5 +size 8208 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f2.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f2.png index 9328d00814..cda3a2eaba 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f2.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f2.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed59006ab49f17d8598083be9d29cf47c00b6edf04182e4941bc10f20a0f0a5c -size 8179 +oid sha256:142db7e3fccbd659245b40dc00bea6b92245feb9ce10cc51b0f8c2e2905a4042 +size 8213 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f3.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f3.png index cbd88a025b..81357517ab 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f3.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:98d8f75aec39f4037269991453b0f95db03245136a33cc3e67a1fe6cea483661 -size 8139 +oid sha256:1070011fa54526f7ce23a214c46864bb06f0f8f55250eee16d3ff0f507130e70 +size 8192 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f4.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f4.png index daedf80d56..d30c259f92 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f4.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f4.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d40b70a7380a6c69eee4f489f0bd300e53a77acca83ebdd982781a3804ebc9 -size 8153 +oid sha256:8a7102f8d010a7df63612178817bed65cb9d51e8ceb7817c7b0d0362a0d07ce5 +size 8208 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f5.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f5.png index daedf80d56..d30c259f92 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f5.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d40b70a7380a6c69eee4f489f0bd300e53a77acca83ebdd982781a3804ebc9 -size 8153 +oid sha256:8a7102f8d010a7df63612178817bed65cb9d51e8ceb7817c7b0d0362a0d07ce5 +size 8208 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f6.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f6.png index daedf80d56..d30c259f92 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f6.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f6.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d40b70a7380a6c69eee4f489f0bd300e53a77acca83ebdd982781a3804ebc9 -size 8153 +oid sha256:8a7102f8d010a7df63612178817bed65cb9d51e8ceb7817c7b0d0362a0d07ce5 +size 8208 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f7.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f7.png index daedf80d56..d30c259f92 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f7.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f7.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d40b70a7380a6c69eee4f489f0bd300e53a77acca83ebdd982781a3804ebc9 -size 8153 +oid sha256:8a7102f8d010a7df63612178817bed65cb9d51e8ceb7817c7b0d0362a0d07ce5 +size 8208 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f8.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f8.png index 4a7d168c46..50f83e18f4 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f8.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0860c0e8574887f48da4af3d751c6a87f4a89471f32161030e624488e5167a7 -size 8201 +oid sha256:2d6d20b2543ec124af8c053ab847138db3016ec21e2e379c035cb0b884a39348 +size 8235 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f9.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f9.png index 28005d318f..3868729c31 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f9.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.f9.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7194d0557f5afb2ae4d5946cdd33e3d12dace427f02b5f9561bda93d1d116d10 -size 8146 +oid sha256:7f368690c1e8d3e45ed7643d7ec5a1ad506e1da95d423334a9e81621d6a480c8 +size 8186 diff --git a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.png b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.png index 69a503f8ce..0c3c597795 100644 --- a/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.png +++ b/tests/Stride.UI.Tests.Regression/Windows.Direct3D11/WARP/TextBlockWrappingTest.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a39368a9df400bbb62f3643401cfff8bbd3b121e1d4ca2bdd8ace31711510dac -size 7040 +oid sha256:7b751deb062dba2450fa7091bae4a20369ab0bce79af321f54ce3df1cf1dbc74 +size 7020 From 0fc5a335b7319faf3a4d8d85d60d9ccbb6faa12f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 18:22:33 +0900 Subject: [PATCH 1116/1182] fix: some SpirvTools.TargetEnv enum were shifted by one --- .../Spirv/Tools/SpirvTools.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs index f9c82c6f94..f1eaaf07ff 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs @@ -22,16 +22,16 @@ public enum TargetEnv Universal_1_0 = 0, Vulkan_1_0 = 1, Universal_1_1 = 2, - Universal_1_2 = 11, - Universal_1_3 = 18, - Vulkan_1_1 = 19, - Universal_1_4 = 21, - Vulkan_1_1_SpirV_1_4 = 22, - Universal_1_5 = 23, - Vulkan_1_2 = 24, - Universal_1_6 = 25, - Vulkan_1_3 = 26, - Vulkan_1_4 = 27, + Universal_1_2 = 10, + Universal_1_3 = 17, + Vulkan_1_1 = 18, + Universal_1_4 = 20, + Vulkan_1_1_SpirV_1_4 = 21, + Universal_1_5 = 22, + Vulkan_1_2 = 23, + Universal_1_6 = 24, + Vulkan_1_3 = 25, + Vulkan_1_4 = 26, } public enum Result From 29409a3ef466608003493abb0b999e60f1d6a18f Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 18:29:37 +0900 Subject: [PATCH 1117/1182] test: allow slight divergence on tessellation graphics tests (wireframe + CPU rounding differences) --- tests/Stride.Engine.Tests/thresholds.jsonc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Stride.Engine.Tests/thresholds.jsonc b/tests/Stride.Engine.Tests/thresholds.jsonc index ca10116d49..081cfa29a9 100644 --- a/tests/Stride.Engine.Tests/thresholds.jsonc +++ b/tests/Stride.Engine.Tests/thresholds.jsonc @@ -15,5 +15,19 @@ // (Lavapipe/WARP on Linux/Windows). Tolerated on all platforms. "image": "AnimatedModelTests.f3.png", "allow": { "3-70": 1, "71+": 1 } + }, + // Some slight pixel edges/aliasing differences (probably due to CPU floating point divergence) + // Allow them: it's quite minor if only so few pixels for wireframe + { + "image": "TesselationTest.f3.png", + "allow": { "3+": 10 } + }, + { + "image": "TesselationTest.f4.png", + "allow": { "3+": 15 } + }, + { + "image": "TesselationTest.f5.png", + "allow": { "3+": 50 } } ] From 3bf61f2da7d0ede93d11ab5246c07fb6b6278196 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 15:39:25 +0900 Subject: [PATCH 1118/1182] fix: D3D12 skip upload/readback resources by heap type, not state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TransitionDescriptorResources skipped resources whose NativeResourceState was GenericRead or CopyDest, treating those states as upload/readback heap markers. That conflates heap type (a lifetime property of Upload/ Readback heaps) with transient state (a Default-heap resource can be in CopyDest after a Copy/Resolve/UpdateSubresource). The skip silently dropped the binding-time transition and left stale layouts leaking into the next SRV/Present — D3D12 GPU validation 'Incompatible texture barrier layout', SRV sampling in LEGACY_COPY_DEST, WARP 1.0.18 missing glyphs in dynamic sprite font tests, back-buffer Present failing in COPY_SOURCE on RenderToWindow. Track heap type explicitly: add IsHostVisibleHeap on GraphicsResource, set at resource creation (Upload/Readback → true, Default → false). Draw prep skips on that flag, not on state. Default-heap resources in CopyDest/CopySource/GenericRead after a copy go through the normal transition to ShaderResource at next bind — single barrier, no reliance on a post-copy Common transition and on barrier coalescing to merge it. --- .../Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs | 3 +++ .../Direct3D12/CommandList.Direct3D12.cs | 8 +++++--- .../Direct3D12/GraphicsResource.Direct3D12.cs | 11 +++++++++++ .../Stride.Graphics/Direct3D12/Texture.Direct3D12.cs | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index 0b731e0eb2..611e3fc653 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -176,6 +176,7 @@ public void Recreate(IntPtr dataPointer) NativeResourceState |= ResourceStates.IndirectArgument; var heapType = HeapType.Default; + IsHostVisibleHeap = false; if (Usage == GraphicsResourceUsage.Staging) { // Per our own definition of staging resource (read-back only) @@ -184,11 +185,13 @@ public void Recreate(IntPtr dataPointer) heapType = HeapType.Readback; NativeResourceState = ResourceStates.CopyDest; + IsHostVisibleHeap = true; } else if (Usage == GraphicsResourceUsage.Dynamic) { heapType = HeapType.Upload; NativeResourceState = ResourceStates.GenericRead; + IsHostVisibleHeap = true; } // TODO: D3D12: Move to a global allocator in bigger committed resources diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index 7947888d7c..cd9e2d18e5 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -430,9 +430,11 @@ private void TransitionDescriptorResources() if (resource is null) continue; - // Skip resources on upload/readback heaps (GenericRead/CopyDest) — they can't be transitioned - if (resource.NativeResourceState == ResourceStates.GenericRead || - resource.NativeResourceState == ResourceStates.CopyDest) + // Skip resources on CPU-visible heaps (Upload/Readback) — they have a fixed + // D3D12 state for their lifetime and cannot be transitioned. Must check by heap + // type, not by state: default-heap resources can be in CopyDest/GenericRead + // transiently after a copy and must still go through the transition. + if (resource.IsHostVisibleHeap) continue; if (isUAV[j]) diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs index 527ff0ab6d..5584f40292 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs @@ -36,6 +36,16 @@ public abstract partial class GraphicsResource /// internal ResourceStates NativeResourceState; + /// + /// Whether this resource is on a CPU-visible heap (Upload or Readback). + /// Resources on these heaps have a fixed D3D12 state ( + /// or ) for their lifetime and cannot be transitioned — + /// lazy barrier code must skip them. This is a heap-type property; don't confuse it with the + /// transient (default-heap resources can legitimately be in + /// CopyDest after a copy). + /// + internal bool IsHostVisibleHeap; + /// /// Gets a value indicating whether the Graphics Resource is in "Debug mode". /// @@ -75,6 +85,7 @@ internal override void SwapInternal(GraphicsResourceBase other) (NativeShaderResourceView, otherResource.NativeShaderResourceView) = (otherResource.NativeShaderResourceView, NativeShaderResourceView); (NativeUnorderedAccessView, otherResource.NativeUnorderedAccessView) = (otherResource.NativeUnorderedAccessView, NativeUnorderedAccessView); (NativeResourceState, otherResource.NativeResourceState) = (otherResource.NativeResourceState, NativeResourceState); + (IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap); } } } diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 464e8a6866..3f14c40680 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -228,6 +228,7 @@ private partial void InitializeFromImpl(DataBox[] dataBoxes) void InitializeStagingTexture() { NativeResourceState = ResourceStates.CopyDest; + IsHostVisibleHeap = true; LayoutTracker.Initialize(BarrierLayout.CopyDest, ArraySize * MipLevelCount); NativeTextureDescription = GetTextureDescription(Dimension); From b8a6d2859901411e72a7528bf45a3c32bc92027e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 21:24:11 +0900 Subject: [PATCH 1119/1182] fix: D3D11 shader reflection: check HRESULT and zero-init descriptors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ignoring GetDesc failures left Name as stack garbage, so GetUtf8Span's unbounded scan walked off into unmapped memory and crashed the test host with an AccessViolation — seen under heavy CI concurrency in runs/24770969751. --- .../Direct3D/ShaderCompiler.cs | 46 +++++++++++++++---- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs index ff0aede733..7676823ac6 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/Direct3D/ShaderCompiler.cs @@ -277,8 +277,14 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl ComPtr shaderReflection = Reflect(bytecode); - SkipInit(out ShaderDesc shaderReflectionDesc); - shaderReflection.GetDesc(ref shaderReflectionDesc); + ShaderDesc shaderReflectionDesc = default; + HResult getShaderDescResult = shaderReflection.GetDesc(ref shaderReflectionDesc); + if (getShaderDescResult.IsFailure) + { + log.Error($"ID3D11ShaderReflection::GetDesc failed (HRESULT 0x{(uint)getShaderDescResult.Value:X8})"); + shaderReflection.Dispose(); + return; + } // Adjust the Constant Buffer size, and compute the offsets and sizes of its members foreach (var constantBuffer in effectReflection.ConstantBuffers) @@ -293,8 +299,13 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl // It is a child interface whose lifetime is tied to the parent ID3D11ShaderReflection. var constantBuffer = shaderReflection.GetConstantBufferByIndex(i); - SkipInit(out ShaderBufferDesc constantBufferDesc); - constantBuffer->GetDesc(ref constantBufferDesc); + ShaderBufferDesc constantBufferDesc = default; + HResult getCbDescResult = constantBuffer->GetDesc(ref constantBufferDesc); + if (getCbDescResult.IsFailure) + { + log.Error($"ID3D11ShaderReflectionConstantBuffer::GetDesc failed at index {i} (HRESULT 0x{(uint)getCbDescResult.Value:X8})"); + continue; + } if (constantBufferDesc.Type == D3DCBufferType.D3DCTResourceBindInfo) continue; @@ -314,8 +325,13 @@ void UpdateReflection(ShaderBytecode shaderBytecode, EffectReflection effectRefl // Bound Resources for (uint i = 0; i < shaderReflectionDesc.BoundResources; ++i) { - SkipInit(out ShaderInputBindDesc boundResourceDesc); - shaderReflection.GetResourceBindingDesc(i, ref boundResourceDesc); + ShaderInputBindDesc boundResourceDesc = default; + HResult getBindDescResult = shaderReflection.GetResourceBindingDesc(i, ref boundResourceDesc); + if (getBindDescResult.IsFailure) + { + log.Error($"ID3D11ShaderReflection::GetResourceBindingDesc failed at index {i} (HRESULT 0x{(uint)getBindDescResult.Value:X8})"); + continue; + } string? linkKeyName = null; string? resourceGroup = null; @@ -444,13 +460,23 @@ void ValidateConstantBufferReflection(ID3D11ShaderReflectionConstantBuffer* cons { var variable = constantBufferRaw->GetVariableByIndex(i); - SkipInit(out ShaderVariableDesc variableDescription); - variable->GetDesc(ref variableDescription); + ShaderVariableDesc variableDescription = default; + HResult getVarDescResult = variable->GetDesc(ref variableDescription); + if (getVarDescResult.IsFailure) + { + log.Error($"ID3D11ShaderReflectionVariable::GetDesc failed at index {i} in Constant Buffer [{constantBuffer.Name}] (HRESULT 0x{(uint)getVarDescResult.Value:X8})"); + continue; + } var variableType = variable->GetType(); - SkipInit(out ShaderTypeDesc variableTypeDescription); - variableType->GetDesc(ref variableTypeDescription); + ShaderTypeDesc variableTypeDescription = default; + HResult getVarTypeDescResult = variableType->GetDesc(ref variableTypeDescription); + if (getVarTypeDescResult.IsFailure) + { + log.Error($"ID3D11ShaderReflectionType::GetDesc failed at index {i} in Constant Buffer [{constantBuffer.Name}] (HRESULT 0x{(uint)getVarTypeDescResult.Value:X8})"); + continue; + } var variableName = GetUtf8Span(variableDescription.Name).GetString()!; if (variableTypeDescription.Offset != 0) From f058e05bddb0b10821d0c2785f9163d79ac82e35 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 21:24:43 +0900 Subject: [PATCH 1120/1182] D3D12: require Enhanced Barriers, drop legacy ResourceBarrier fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stride's D3D12 backend carried two parallel runtime-barrier paths (legacy ResourceStates and enhanced BarrierLayout) plus dual per-resource state tracking (NativeResourceState + LayoutTracker). The legacy path brings the full D3D12 quirk set — implicit state promotion, decay at ExecuteCommandLists, COMMON == PRESENT == 0x0 ambiguity — which don't exist in the enhanced model or in Vulkan. Enhanced Barriers are supported everywhere Stride actually targets (NVIDIA 531.18+, AMD 23.5.2+, Intel Arc 31.0.101.4032+, WARP, Xbox Series), so the fallback is technical debt. Also found: the existing SupportsEnhancedBarriers detection was reading EnhancedBarriersSupported at the wrong struct offset (8 instead of 4) and the oversized 64-byte buffer made CheckFeatureSupport return E_INVALIDARG on some devices. Net result was the enhanced flush path had never actually run in production — legacy was silently in use, which is where the GPU-validation regressions that prompted this lived. Fixed by using Silk.NET's FeatureDataD3D12Options12 struct directly. Changes: * GraphicsDevice.Direct3D12: throw GraphicsDeviceException at init if Enhanced Barriers unsupported. SupportsEnhancedBarriers field gone. * CommandList.Direct3D12: delete FlushResourceBarriersLegacy. Delete the legacy/enhanced branch in FlushResourceBarriers — enhanced is the only path. Delete obsolete ResourceBarrierTransition(GraphicsResourceState) overload. Replace sort+merge coalesce with an order-preserving Dictionary<(Resource, Subresource), int> dedup — no reliance on List.Sort stability and no GetHashCode collision edge cases. * GraphicsResource.Direct3D12: delete NativeResourceState field and IsTransitionNeeded(ResourceStates) method — no runtime consumers after legacy removal. LayoutTracker is now the single source of truth for per-subresource state. * Buffer / Texture / BarrierMapping: rename local NativeResourceState writes to desiredResourceState. ResourceStates is now creation-only (CreateCommittedResource and the init-time copy-queue barriers); ToBarrierLayout remains as the creation-to-runtime bridge, annotated as such. ToResourceStates had zero callers after the runtime cleanup — removed. Result: one runtime barrier path, Vulkan-shaped (BarrierLayout drives access/sync derivation at flush time). Smaller surface, fewer places where field-vs-tracker drift or sort-stability matter. --- .../Direct3D12/BarrierMapping.Direct3D12.cs | 25 +---- .../Direct3D12/Buffer.Direct3D12.cs | 27 ++--- .../Direct3D12/CommandList.Direct3D12.cs | 100 ++++++------------ .../Direct3D12/GraphicsDevice.Direct3D12.cs | 46 ++++---- .../Direct3D12/GraphicsResource.Direct3D12.cs | 37 ++----- .../Direct3D12/Texture.Direct3D12.cs | 22 ++-- 6 files changed, 87 insertions(+), 170 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs index 01305c9279..ba0cbb2a96 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs @@ -12,29 +12,14 @@ namespace Stride.Graphics; /// internal static class BarrierMapping { - /// - /// Converts a to a legacy D3D12 . - /// - internal static ResourceStates ToResourceStates(BarrierLayout layout) => layout switch - { - BarrierLayout.Undefined => ResourceStates.Common, - BarrierLayout.Common => ResourceStates.Common, - BarrierLayout.RenderTarget => ResourceStates.RenderTarget, - BarrierLayout.DepthStencilWrite => ResourceStates.DepthWrite, - BarrierLayout.DepthStencilRead => ResourceStates.DepthRead, - BarrierLayout.ShaderResource => ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource, - BarrierLayout.UnorderedAccess => ResourceStates.UnorderedAccess, - BarrierLayout.CopySource => ResourceStates.CopySource, - BarrierLayout.CopyDest => ResourceStates.CopyDest, - BarrierLayout.Present => ResourceStates.Common, // Present == Common in D3D12 - BarrierLayout.ResolveSource => ResourceStates.ResolveSource, - BarrierLayout.ResolveDest => ResourceStates.ResolveDest, - _ => ResourceStates.Common, - }; - /// /// Converts a legacy D3D12 to a . /// + /// + /// Creation-boundary bridge only. Used to seed LayoutTracker from the + /// value the resource was created in. Runtime barriers must + /// not call this — the runtime path operates on directly. + /// internal static BarrierLayout ToBarrierLayout(ResourceStates state) => state switch { ResourceStates.RenderTarget => BarrierLayout.RenderTarget, diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index 611e3fc653..2440bb32e3 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -150,21 +150,24 @@ public void Recreate(IntPtr dataPointer) { bool hasInitData = dataPointer != IntPtr.Zero; - // TODO: D3D12: Where should that go longer term? Should it be precomputed for future use? (cost would likely be additional check on SetDescriptorSets/Draw) - NativeResourceState = ResourceStates.Common; + // Compute the buffer's final post-init state from its flags. Only used for + // CreateCommittedResource + the init-time copy-queue barrier (legacy ResourceStates + // surface is intrinsic to D3D12 resource creation). Runtime transitions go through + // LayoutTracker / BarrierLayout — see ResourceBarrierTransition. var bufferFlags = bufferDescription.BufferFlags; + var desiredResourceState = ResourceStates.Common; if (bufferFlags.HasFlag(BufferFlags.ConstantBuffer)) - NativeResourceState |= ResourceStates.VertexAndConstantBuffer; + desiredResourceState |= ResourceStates.VertexAndConstantBuffer; if (bufferFlags.HasFlag(BufferFlags.IndexBuffer)) - NativeResourceState |= ResourceStates.IndexBuffer; + desiredResourceState |= ResourceStates.IndexBuffer; if (bufferFlags.HasFlag(BufferFlags.VertexBuffer)) - NativeResourceState |= ResourceStates.VertexAndConstantBuffer; + desiredResourceState |= ResourceStates.VertexAndConstantBuffer; if (bufferFlags.HasFlag(BufferFlags.ShaderResource)) - NativeResourceState |= ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource; + desiredResourceState |= ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource; if (bufferFlags.HasFlag(BufferFlags.StructuredBuffer)) { @@ -173,7 +176,7 @@ public void Recreate(IntPtr dataPointer) } if (bufferFlags.HasFlag(BufferFlags.ArgumentBuffer)) - NativeResourceState |= ResourceStates.IndirectArgument; + desiredResourceState |= ResourceStates.IndirectArgument; var heapType = HeapType.Default; IsHostVisibleHeap = false; @@ -184,20 +187,20 @@ public void Recreate(IntPtr dataPointer) throw new InvalidOperationException("D3D12: Staging buffers can't be created with initial data."); heapType = HeapType.Readback; - NativeResourceState = ResourceStates.CopyDest; + desiredResourceState = ResourceStates.CopyDest; IsHostVisibleHeap = true; } else if (Usage == GraphicsResourceUsage.Dynamic) { heapType = HeapType.Upload; - NativeResourceState = ResourceStates.GenericRead; + desiredResourceState = ResourceStates.GenericRead; IsHostVisibleHeap = true; } // TODO: D3D12: Move to a global allocator in bigger committed resources var heap = new HeapProperties { Type = heapType }; - var initialResourceState = heapType != HeapType.Default ? NativeResourceState : ResourceStates.Common; + var initialResourceState = heapType != HeapType.Default ? desiredResourceState : ResourceStates.Common; // If the resource must be initialized with data, it is initially in the state // CopyDest so we can copy from an upload buffer @@ -278,7 +281,7 @@ public void Recreate(IntPtr dataPointer) // Once initialized, transition the Buffer to its final state resourceBarrier.Transition.StateBefore = hasInitData ? ResourceStates.CopyDest : initialResourceState; - resourceBarrier.Transition.StateAfter = NativeResourceState; + resourceBarrier.Transition.StateAfter = desiredResourceState; commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); @@ -294,7 +297,7 @@ public void Recreate(IntPtr dataPointer) } } - LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(NativeResourceState), 1); + LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(desiredResourceState), 1); NativeShaderResourceView = GetShaderResourceView(ViewFormat); NativeUnorderedAccessView = GetUnorderedAccessView(ViewFormat); diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index cd9e2d18e5..9466c16e20 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -39,6 +39,8 @@ public unsafe partial class CommandList private DescriptorSet[] boundDescriptorSets; private readonly ID3D12DescriptorHeap*[] descriptorHeaps = new ID3D12DescriptorHeap*[2]; private readonly List pendingBarriers = new(16); + // Scratch map for FlushResourceBarriers coalescing. Reused to avoid per-flush allocs. + private readonly Dictionary<(GraphicsResource, uint), int> barrierCoalesceMap = new(16); // Mappings from CPU-side Descriptor Handles to GPU-side Descriptor Handles private readonly Dictionary srvMapping = []; @@ -625,22 +627,17 @@ public void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout n } resource.LayoutTracker.Set(subresource, newLayout); - resource.NativeResourceState = BarrierMapping.ToResourceStates(newLayout); } } - [Obsolete("Use BarrierLayout overload instead.")] - public void ResourceBarrierTransition(GraphicsResource resource, GraphicsResourceState newState) - { - ResourceBarrierTransition(resource, BarrierMapping.ToBarrierLayout((ResourceStates)newState)); - } - /// - /// Flushes all pending Graphics Resource barriers. + /// Flushes all pending Graphics Resource barriers using D3D12 Enhanced Barriers. /// /// - /// This method processes all pending resource barriers, applying them. This is to to ensure - /// that all queued resource transitions are executed. + /// Redundant or no-op entries for the same (resource, subresource) are folded in one + /// O(n) pass over — insertion order preserved, no sort + /// needed. Coalescing removes redundant layout/access/sync transitions and runs + /// unconditionally. /// private unsafe void FlushResourceBarriers() { @@ -648,83 +645,48 @@ private unsafe void FlushResourceBarriers() if (count == 0) return; - // Coalesce duplicate barriers for the same resource+subresource. - // Sort by (Resource, Subresource), then merge consecutive entries: - // keep the first LayoutBefore and the last LayoutAfter, drop no-ops. + // Dictionary-keyed dedup on (resource, subresource). For repeat entries, keep the + // first LayoutBefore and overwrite LayoutAfter — A→B followed by B→C collapses to + // A→C; A→B→A collapses to A→A (dropped below). Order-stable without sorting. if (count > 1) { - pendingBarriers.Sort(static (a, b) => - { - int cmp = RuntimeHelpers.GetHashCode(a.Resource).CompareTo(RuntimeHelpers.GetHashCode(b.Resource)); - return cmp != 0 ? cmp : a.Subresource.CompareTo(b.Subresource); - }); - + barrierCoalesceMap.Clear(); int write = 0; - for (int read = 1; read < count; read++) + for (int read = 0; read < count; read++) { - if (pendingBarriers[write].Resource == pendingBarriers[read].Resource && - pendingBarriers[write].Subresource == pendingBarriers[read].Subresource) + var desc = pendingBarriers[read]; + var key = (desc.Resource, desc.Subresource); + if (barrierCoalesceMap.TryGetValue(key, out int existing)) { - // Merge: keep LayoutBefore from [write], take LayoutAfter from [read] - var merged = pendingBarriers[write]; - merged.LayoutAfter = pendingBarriers[read].LayoutAfter; - pendingBarriers[write] = merged; + var merged = pendingBarriers[existing]; + merged.LayoutAfter = desc.LayoutAfter; + pendingBarriers[existing] = merged; } else { - // Keep previous entry only if it's not a no-op (A→B→A) - if (pendingBarriers[write].LayoutBefore != pendingBarriers[write].LayoutAfter) - write++; - pendingBarriers[write] = pendingBarriers[read]; + barrierCoalesceMap[key] = write; + pendingBarriers[write++] = desc; } } - // Final entry: keep if not a no-op - count = pendingBarriers[write].LayoutBefore != pendingBarriers[write].LayoutAfter ? write + 1 : write; + // Drop no-ops in-place. + int finalCount = 0; + for (int i = 0; i < write; i++) + { + var desc = pendingBarriers[i]; + if (desc.LayoutBefore != desc.LayoutAfter) + pendingBarriers[finalCount++] = desc; + } + + count = finalCount; if (count < pendingBarriers.Count) pendingBarriers.RemoveRange(count, pendingBarriers.Count - count); } - count = pendingBarriers.Count; if (count == 0) return; - if (GraphicsDevice.SupportsEnhancedBarriers) - FlushResourceBarriersEnhanced(count); - else - FlushResourceBarriersLegacy(count); - } - - private unsafe void FlushResourceBarriersLegacy(int count) - { - scoped Span barriers = stackalloc ResourceBarrier[count]; - - for (int i = 0; i < count; i++) - { - var desc = pendingBarriers[i]; - - barriers[i] = new ResourceBarrier - { - Type = ResourceBarrierType.Transition, - Flags = ResourceBarrierFlags.None, - Transition = new ResourceTransitionBarrier - { - PResource = desc.Resource.NativeResource, - Subresource = desc.Subresource, - StateBefore = BarrierMapping.ToResourceStates(desc.LayoutBefore), - StateAfter = BarrierMapping.ToResourceStates(desc.LayoutAfter), - } - }; - } - - pendingBarriers.Clear(); - - currentCommandList.NativeCommandList.ResourceBarrier(NumBarriers: (uint)count, barriers); - } - - private unsafe void FlushResourceBarriersEnhanced(int count) - { - // Separate texture and buffer barriers + // Split texture and buffer barriers — D3D12 Enhanced requires separate BarrierGroups. scoped Span textureBarriers = stackalloc D3D12TextureBarrier[count]; scoped Span bufferBarriers = stackalloc D3D12BufferBarrier[count]; int textureCount = 0; diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 8d903247d0..806fa20f0b 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -46,11 +46,6 @@ public unsafe partial class GraphicsDevice private bool simulateReset = false; private string rendererName; - /// - /// Whether D3D12 Enhanced Barriers are supported by the device. - /// - internal bool SupportsEnhancedBarriers; - private ID3D12Device* nativeDevice; private ID3D12CommandQueue* nativeCommandQueue; @@ -422,7 +417,7 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP CurrentFeatureLevel = featureLevel; // Check Enhanced Barriers support (D3D12_FEATURE_D3D12_OPTIONS12 = 41) - CheckEnhancedBarriersSupport(); + RequireEnhancedBarriersSupport(); break; } @@ -578,30 +573,27 @@ void EnableDebugLayer() } // - // Checks if the device supports D3D12 Enhanced Barriers. + // Requires D3D12 Enhanced Barriers. Throws if unsupported — Stride's runtime + // barrier code no longer ships a legacy ResourceBarrier fallback. // - void CheckEnhancedBarriersSupport() + // Minimum requirements: Windows 10 1909+ with Agility SDK, or Windows 11. Driver + // floors: NVIDIA 531.18+, AMD 23.5.2+, Intel 31.0.101.4032+. WARP and Xbox + // Series X|S are supported. + // + void RequireEnhancedBarriersSupport() { - // D3D12_FEATURE_D3D12_OPTIONS12 = 41 - // The struct has EnhancedBarriersSupported as a BOOL at a known offset. - // Since Silk.NET may not have this struct, we use raw CheckFeatureSupport. - const int D3D12_FEATURE_D3D12_OPTIONS12 = 41; - - // D3D12_FEATURE_DATA_D3D12_OPTIONS12 is a large struct; EnhancedBarriersSupported - // is at byte offset 8 (after MSAAAlignedCountSupported and RelaxedFormatCasting BoolS). - // We allocate enough space and read the BOOL at offset 8. - Span options12 = stackalloc byte[64]; // oversized to be safe - options12.Clear(); - - fixed (byte* pOptions = options12) + // CheckFeatureSupport validates the struct size exactly — passing an oversized + // buffer returns E_INVALIDARG and the query silently fails. Use the Silk.NET + // struct + ref overload so size and field offsets stay correct. + var options12 = default(FeatureDataD3D12Options12); + HResult hr = nativeDevice->CheckFeatureSupport(Silk.NET.Direct3D12.Feature.D3D12Options12, ref options12, + (uint) sizeof(FeatureDataD3D12Options12)); + if (!hr.IsSuccess || !options12.EnhancedBarriersSupported) { - HResult hr = nativeDevice->CheckFeatureSupport((Silk.NET.Direct3D12.Feature) D3D12_FEATURE_D3D12_OPTIONS12, - pOptions, (uint) options12.Length); - if (hr.IsSuccess) - { - // EnhancedBarriersSupported is a BOOL (4 bytes) at offset 8 - SupportsEnhancedBarriers = *(int*)(pOptions + 8) != 0; - } + throw new GraphicsDeviceException( + "D3D12 Enhanced Barriers are required but not supported by this device/driver. " + + "Update to a recent GPU driver (NVIDIA 531.18+, AMD 23.5.2+, Intel 31.0.101.4032+) " + + "or run on Windows 11 / Windows 10 with the Agility SDK."); } } } diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs index 5584f40292..c3ba42382f 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs @@ -32,17 +32,12 @@ public abstract partial class GraphicsResource internal CpuDescriptorHandle NativeUnorderedAccessView; /// - /// The current Direct3D 12 Resource State of the Graphics Resource. - /// - internal ResourceStates NativeResourceState; - - /// - /// Whether this resource is on a CPU-visible heap (Upload or Readback). - /// Resources on these heaps have a fixed D3D12 state ( - /// or ) for their lifetime and cannot be transitioned — - /// lazy barrier code must skip them. This is a heap-type property; don't confuse it with the - /// transient (default-heap resources can legitimately be in - /// CopyDest after a copy). + /// Whether this resource is on a CPU-visible heap (Upload or Readback). Resources on + /// these heaps have a fixed D3D12 state ( or + /// ) for their lifetime and cannot be transitioned — + /// lazy barrier code must skip them. This is a heap-type property: don't confuse it + /// with transient state (default-heap resources + /// can legitimately be in CopyDest after a copy). /// internal bool IsHostVisibleHeap; @@ -54,25 +49,6 @@ public abstract partial class GraphicsResource /// protected bool IsDebugMode => GraphicsDevice?.IsDebugMode == true; - - /// - /// Determines if the Graphics Resource needs to perform a state transition in order to reach the target state. - /// - /// The destination Graphics Resource state. - /// - /// if a transition is needed to reach the target state; - /// otherwise, . - /// - internal bool IsTransitionNeeded(ResourceStates targeState) - { - // If 'targeState' is a subset of 'before', then there's no need for a transition - - // NOTE: ResourceStates.Common is an oddball state that doesn't follow the ResourceStates - // pattern of having exactly one bit set so we need to special case these - return NativeResourceState != targeState && - ((NativeResourceState | targeState) != NativeResourceState || targeState == ResourceStates.Common); - } - /// internal override void SwapInternal(GraphicsResourceBase other) { @@ -84,7 +60,6 @@ internal override void SwapInternal(GraphicsResourceBase other) (UpdatingCommandList, otherResource.UpdatingCommandList) = (otherResource.UpdatingCommandList, UpdatingCommandList); (NativeShaderResourceView, otherResource.NativeShaderResourceView) = (otherResource.NativeShaderResourceView, NativeShaderResourceView); (NativeUnorderedAccessView, otherResource.NativeUnorderedAccessView) = (otherResource.NativeUnorderedAccessView, NativeUnorderedAccessView); - (NativeResourceState, otherResource.NativeResourceState) = (otherResource.NativeResourceState, NativeResourceState); (IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap); } } diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 3f14c40680..169dcf184d 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -227,7 +227,6 @@ private partial void InitializeFromImpl(DataBox[] dataBoxes) // void InitializeStagingTexture() { - NativeResourceState = ResourceStates.CopyDest; IsHostVisibleHeap = true; LayoutTracker.Initialize(BarrierLayout.CopyDest, ArraySize * MipLevelCount); NativeTextureDescription = GetTextureDescription(Dimension); @@ -237,7 +236,7 @@ void InitializeStagingTexture() HeapProperties heap = new HeapProperties { Type = HeapType.Readback }; - HResult result = NativeDevice.CreateCommittedResource(in heap, HeapFlags.None, in nativeDescription, NativeResourceState, pOptimizedClearValue: null, + HResult result = NativeDevice.CreateCommittedResource(in heap, HeapFlags.None, in nativeDescription, ResourceStates.CopyDest, pOptimizedClearValue: null, out ComPtr stagingTextureResource); if (result.IsFailure) result.Throw(); @@ -364,19 +363,21 @@ void InitializeTexture(DataBox[] initialData) var nativeDescription = NativeTextureDescription = GetTextureDescription(Dimension); - // Initialize resource state based on texture usage. + // Compute the texture's final post-init state from its flags. Only used for + // CreateCommittedResource + the init-time copy-queue barriers (legacy + // ResourceStates surface is intrinsic to D3D12 resource creation). Runtime + // transitions go through LayoutTracker / BarrierLayout. + ResourceStates desiredResourceState; if (Usage == GraphicsResourceUsage.Staging) - NativeResourceState = ResourceStates.CopyDest; + desiredResourceState = ResourceStates.CopyDest; else if (ViewFlags.HasFlag(TextureFlags.DepthStencil)) - NativeResourceState = ResourceStates.DepthWrite; + desiredResourceState = ResourceStates.DepthWrite; else if (ViewFlags.HasFlag(TextureFlags.RenderTarget)) - NativeResourceState = ResourceStates.RenderTarget; + desiredResourceState = ResourceStates.RenderTarget; else if (ViewFlags.HasFlag(TextureFlags.ShaderResource)) - NativeResourceState = ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource; + desiredResourceState = ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource; else - NativeResourceState = ResourceStates.Common; - - var desiredResourceState = NativeResourceState; + desiredResourceState = ResourceStates.Common; bool hasInitData = initialData?.Length > 0; @@ -491,7 +492,6 @@ ref rowSizeInBytes.GetReference(), } } - NativeResourceState = desiredResourceState; LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(desiredResourceState), ArraySize * MipLevelCount); } From dbee994d777d9e3823e614904697322dfa86b759 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 21:40:07 +0900 Subject: [PATCH 1121/1182] graphics: share IsHostVisibleHeap and Texture initial-layout across backends MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - IsHostVisibleHeap moved from Direct3D12 to GraphicsResource base; Vulkan sets it for Staging/Dynamic buffers and Staging textures. - Texture.GetInitialBarrierLayout consolidates the Usage/flags → BarrierLayout ladder; D3D12 and Vulkan init both call it. - Re-adds BarrierMapping.ToResourceStates (D3D12) to bridge shared BarrierLayout back to the ResourceStates CreateCommittedResource needs. --- .../Direct3D12/BarrierMapping.Direct3D12.cs | 28 +++++++++++++++---- .../Direct3D12/Buffer.Direct3D12.cs | 8 +++--- .../Direct3D12/CommandList.Direct3D12.cs | 11 ++------ .../Direct3D12/GraphicsDevice.Direct3D12.cs | 3 +- .../Direct3D12/GraphicsResource.Direct3D12.cs | 10 ------- .../Direct3D12/Texture.Direct3D12.cs | 21 ++++---------- .../Stride.Graphics/GraphicsResource.cs | 9 ++++++ sources/engine/Stride.Graphics/Texture.cs | 18 ++++++++++++ .../Stride.Graphics/Vulkan/Buffer.Vulkan.cs | 1 + .../Vulkan/GraphicsResource.Vulkan.cs | 1 + .../Stride.Graphics/Vulkan/Texture.Vulkan.cs | 11 +++----- 11 files changed, 67 insertions(+), 54 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs index ba0cbb2a96..d4b611f149 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs @@ -13,13 +13,29 @@ namespace Stride.Graphics; internal static class BarrierMapping { /// - /// Converts a legacy D3D12 to a . + /// Maps a to the value to pass + /// to CreateCommittedResource. Creation-boundary bridge only — the runtime + /// barrier path operates on directly via the Enhanced + /// mapping methods below. + /// + internal static ResourceStates ToResourceStates(BarrierLayout layout) => layout switch + { + BarrierLayout.RenderTarget => ResourceStates.RenderTarget, + BarrierLayout.DepthStencilWrite => ResourceStates.DepthWrite, + BarrierLayout.DepthStencilRead => ResourceStates.DepthRead, + BarrierLayout.ShaderResource => ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource, + BarrierLayout.UnorderedAccess => ResourceStates.UnorderedAccess, + BarrierLayout.CopySource => ResourceStates.CopySource, + BarrierLayout.CopyDest => ResourceStates.CopyDest, + BarrierLayout.ResolveSource => ResourceStates.ResolveSource, + BarrierLayout.ResolveDest => ResourceStates.ResolveDest, + _ => ResourceStates.Common, + }; + + /// + /// Seeds a from the value a + /// resource was created in. Creation-boundary bridge only. /// - /// - /// Creation-boundary bridge only. Used to seed LayoutTracker from the - /// value the resource was created in. Runtime barriers must - /// not call this — the runtime path operates on directly. - /// internal static BarrierLayout ToBarrierLayout(ResourceStates state) => state switch { ResourceStates.RenderTarget => BarrierLayout.RenderTarget, diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index 2440bb32e3..0f1c548caa 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -150,10 +150,10 @@ public void Recreate(IntPtr dataPointer) { bool hasInitData = dataPointer != IntPtr.Zero; - // Compute the buffer's final post-init state from its flags. Only used for - // CreateCommittedResource + the init-time copy-queue barrier (legacy ResourceStates - // surface is intrinsic to D3D12 resource creation). Runtime transitions go through - // LayoutTracker / BarrierLayout — see ResourceBarrierTransition. + // Final post-init state derived from the buffer's flags. Consumed by + // CreateCommittedResource and the init-time copy-queue barrier — D3D12 creation + // is a ResourceStates API. Runtime transitions go through LayoutTracker / + // BarrierLayout in ResourceBarrierTransition. var bufferFlags = bufferDescription.BufferFlags; var desiredResourceState = ResourceStates.Common; diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index 9466c16e20..97db78b9f9 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -633,21 +633,14 @@ public void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout n /// /// Flushes all pending Graphics Resource barriers using D3D12 Enhanced Barriers. /// - /// - /// Redundant or no-op entries for the same (resource, subresource) are folded in one - /// O(n) pass over — insertion order preserved, no sort - /// needed. Coalescing removes redundant layout/access/sync transitions and runs - /// unconditionally. - /// private unsafe void FlushResourceBarriers() { int count = pendingBarriers.Count; if (count == 0) return; - // Dictionary-keyed dedup on (resource, subresource). For repeat entries, keep the - // first LayoutBefore and overwrite LayoutAfter — A→B followed by B→C collapses to - // A→C; A→B→A collapses to A→A (dropped below). Order-stable without sorting. + // Dedup on (resource, subresource) in O(n) with insertion order preserved. + // A→B followed by B→C collapses to A→C; A→B→A collapses to A→A (dropped below). if (count > 1) { barrierCoalesceMap.Clear(); diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 806fa20f0b..31bfc16fa6 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -573,8 +573,7 @@ void EnableDebugLayer() } // - // Requires D3D12 Enhanced Barriers. Throws if unsupported — Stride's runtime - // barrier code no longer ships a legacy ResourceBarrier fallback. + // Requires D3D12 Enhanced Barriers. Throws if unsupported. // // Minimum requirements: Windows 10 1909+ with Agility SDK, or Windows 11. Driver // floors: NVIDIA 531.18+, AMD 23.5.2+, Intel 31.0.101.4032+. WARP and Xbox diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs index c3ba42382f..4cdb2ca9a2 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs @@ -31,16 +31,6 @@ public abstract partial class GraphicsResource /// internal CpuDescriptorHandle NativeUnorderedAccessView; - /// - /// Whether this resource is on a CPU-visible heap (Upload or Readback). Resources on - /// these heaps have a fixed D3D12 state ( or - /// ) for their lifetime and cannot be transitioned — - /// lazy barrier code must skip them. This is a heap-type property: don't confuse it - /// with transient state (default-heap resources - /// can legitimately be in CopyDest after a copy). - /// - internal bool IsHostVisibleHeap; - /// /// Gets a value indicating whether the Graphics Resource is in "Debug mode". /// diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 169dcf184d..80b0c40b9e 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -363,21 +363,10 @@ void InitializeTexture(DataBox[] initialData) var nativeDescription = NativeTextureDescription = GetTextureDescription(Dimension); - // Compute the texture's final post-init state from its flags. Only used for - // CreateCommittedResource + the init-time copy-queue barriers (legacy - // ResourceStates surface is intrinsic to D3D12 resource creation). Runtime - // transitions go through LayoutTracker / BarrierLayout. - ResourceStates desiredResourceState; - if (Usage == GraphicsResourceUsage.Staging) - desiredResourceState = ResourceStates.CopyDest; - else if (ViewFlags.HasFlag(TextureFlags.DepthStencil)) - desiredResourceState = ResourceStates.DepthWrite; - else if (ViewFlags.HasFlag(TextureFlags.RenderTarget)) - desiredResourceState = ResourceStates.RenderTarget; - else if (ViewFlags.HasFlag(TextureFlags.ShaderResource)) - desiredResourceState = ResourceStates.PixelShaderResource | ResourceStates.NonPixelShaderResource; - else - desiredResourceState = ResourceStates.Common; + // Post-init layout. Drives both the ResourceStates for CreateCommittedResource + // (D3D12 creation is a ResourceStates API) and the LayoutTracker seed. + var desiredLayout = GetInitialBarrierLayout(); + var desiredResourceState = BarrierMapping.ToResourceStates(desiredLayout); bool hasInitData = initialData?.Length > 0; @@ -492,7 +481,7 @@ ref rowSizeInBytes.GetReference(), } } - LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(desiredResourceState), ArraySize * MipLevelCount); + LayoutTracker.Initialize(desiredLayout, ArraySize * MipLevelCount); } // diff --git a/sources/engine/Stride.Graphics/GraphicsResource.cs b/sources/engine/Stride.Graphics/GraphicsResource.cs index 1c6ab86879..9c3b4b1c70 100644 --- a/sources/engine/Stride.Graphics/GraphicsResource.cs +++ b/sources/engine/Stride.Graphics/GraphicsResource.cs @@ -15,6 +15,15 @@ public abstract partial class GraphicsResource : GraphicsResourceBase /// internal SubresourceLayoutTracker LayoutTracker; + /// + /// Whether this resource lives on a CPU-visible heap (Upload / Readback on D3D12, host-visible + /// memory on Vulkan). The native resource state on such heaps is a fixed lifetime property + /// (D3D12: GENERIC_READ or COPY_DEST; Vulkan: no layout transitions needed for + /// buffers, and staging textures are handled separately). Barrier code must skip these. + /// Set once at resource creation — do not flip at runtime. + /// + internal bool IsHostVisibleHeap; + /// /// Initializes a new instance of the class. /// diff --git a/sources/engine/Stride.Graphics/Texture.cs b/sources/engine/Stride.Graphics/Texture.cs index 12180c026a..7f0a6d4468 100644 --- a/sources/engine/Stride.Graphics/Texture.cs +++ b/sources/engine/Stride.Graphics/Texture.cs @@ -262,6 +262,24 @@ public TextureDimension ViewDimension /// public bool IsUnorderedAccess => ViewFlags.HasFlag(TextureFlags.UnorderedAccess); + /// + /// Computes the initial a texture should be created in + /// based on its and . Used by + /// platform backends to seed LayoutTracker at resource creation. + /// + internal BarrierLayout GetInitialBarrierLayout() + { + if (Usage == GraphicsResourceUsage.Staging) + return BarrierLayout.CopyDest; + if (IsDepthStencil) + return BarrierLayout.DepthStencilWrite; + if (IsRenderTarget) + return BarrierLayout.RenderTarget; + if (IsShaderResource) + return BarrierLayout.ShaderResource; + return BarrierLayout.Common; + } + /// /// Gets a value indicating if the Texture is a multi-sampled Texture. /// diff --git a/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs index 26a1b74d6a..e02a283c24 100644 --- a/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs @@ -159,6 +159,7 @@ public unsafe void Recreate(IntPtr dataPointer) if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic) { memoryProperties = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent; + IsHostVisibleHeap = true; } GraphicsDevice.NativeDeviceApi.vkGetBufferMemoryRequirements(GraphicsDevice.NativeDevice, NativeBuffer, out var memoryRequirements); diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs index 485fede7b0..3c23aa34f6 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs @@ -112,6 +112,7 @@ internal override void SwapInternal(GraphicsResourceBase other) (UpdatingCommandList, otherResource.UpdatingCommandList) = (otherResource.UpdatingCommandList, UpdatingCommandList); (NativeMemory, otherResource.NativeMemory) = (otherResource.NativeMemory, NativeMemory); (NativePipelineStageMask, otherResource.NativePipelineStageMask) = (otherResource.NativePipelineStageMask, NativePipelineStageMask); + (IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap); } } } diff --git a/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs index bce48e62f8..c1d450f14f 100644 --- a/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs @@ -127,6 +127,7 @@ private partial void InitializeFromImpl(DataBox[] dataBoxes = null) if (isNotOwningResources) throw new InvalidOperationException(); + IsHostVisibleHeap = true; NativeAccessMask = VkAccessFlags.HostRead | VkAccessFlags.HostWrite; NativePipelineStageMask = VkPipelineStageFlags.Host; @@ -152,13 +153,9 @@ private partial void InitializeFromImpl(DataBox[] dataBoxes = null) if (NativeImage != VkImage.Null) throw new InvalidOperationException(); - NativeLayout = - IsRenderTarget ? VkImageLayout.ColorAttachmentOptimal : - IsDepthStencil ? VkImageLayout.DepthStencilAttachmentOptimal : - IsShaderResource ? VkImageLayout.ShaderReadOnlyOptimal : - VkImageLayout.General; - - LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(NativeLayout), ArraySize * MipLevelCount); + var initialLayout = GetInitialBarrierLayout(); + NativeLayout = BarrierMapping.ToVkImageLayout(initialLayout); + LayoutTracker.Initialize(initialLayout, ArraySize * MipLevelCount); if (NativeLayout == VkImageLayout.TransferDstOptimal) NativeAccessMask = VkAccessFlags.TransferRead; From 74c440cb55b08791323afca4eca75e3ca022f012 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 22 Apr 2026 23:08:59 +0900 Subject: [PATCH 1122/1182] fix: D3D12 create default-heap resources in COMMON for Enhanced Barrier interop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI (strict WARP on 26100) reported ~750 "does not support barrier interop" errors across the D3D12 test suite: enhanced Barrier rejects resources whose current state was set via legacy ResourceBarrier to anything other than COMMON / BARRIER_LAYOUT_COMMON. Textures and Buffers on default heaps now create in ResourceStates.Common, and the init-time copy-queue uploads transition Common → CopyDest → Common instead of leaving the resource in its "desired" state. The first runtime enhanced Barrier then transitions Common → (RT/DS/SR/UAV/…) as needed, which is what the interop check allows. LayoutTracker seeds at BarrierLayout.Common for default-heap. Upload/Readback heaps stay in their creation-time state and are skipped via IsHostVisibleHeap. --- .../Direct3D12/Buffer.Direct3D12.cs | 47 +++++++++---------- .../Direct3D12/Texture.Direct3D12.cs | 41 +++++++--------- 2 files changed, 38 insertions(+), 50 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index 0f1c548caa..ea8125dd60 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -241,18 +241,15 @@ public void Recreate(IntPtr dataPointer) NativeResource.Unmap(Subresource: 0, pWrittenRange: ref NullRef()); } } - else if (heapType == HeapType.Default) + else if (heapType == HeapType.Default && hasInitData) { - ComPtr uploadResource = default; - int uploadOffset = 0; - - if (hasInitData) - { - // Copy data to the upload heap for later inter-resource copy - // TODO: D3D12: Move that to a shared upload heap - var uploadMemory = GraphicsDevice.AllocateUploadBuffer(SizeInBytes, out uploadResource, out uploadOffset); - MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemory, (void*) dataPointer, (uint) SizeInBytes); - } + // Default-heap buffer with init data: upload via the copy queue through + // Common → CopyDest → Common. The resource must end in Common so the first + // runtime enhanced Barrier can take over — non-Common initial states are + // rejected by the D3D12 enhanced/legacy interop check. + // TODO: D3D12: Move that to a shared upload heap + var uploadMemory = GraphicsDevice.AllocateUploadBuffer(SizeInBytes, out var uploadResource, out var uploadOffset); + MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemory, (void*) dataPointer, (uint) SizeInBytes); var commandList = GraphicsDevice.NativeCopyCommandList; @@ -268,21 +265,16 @@ public void Recreate(IntPtr dataPointer) resourceBarrier.Transition.PResource = NativeResource; resourceBarrier.Transition.Subresource = 0; - if (hasInitData) - { - // Switch resource to CopyDest state - resourceBarrier.Transition.StateBefore = initialResourceState; - resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; - commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); - - // Copy from the upload heap to the actual resource - commandList.CopyBufferRegion(NativeResource, DstOffset: 0, uploadResource, (ulong) uploadOffset, (ulong) SizeInBytes); - } + // Common → CopyDest + resourceBarrier.Transition.StateBefore = ResourceStates.Common; + resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; + commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); - // Once initialized, transition the Buffer to its final state - resourceBarrier.Transition.StateBefore = hasInitData ? ResourceStates.CopyDest : initialResourceState; - resourceBarrier.Transition.StateAfter = desiredResourceState; + commandList.CopyBufferRegion(NativeResource, DstOffset: 0, uploadResource, (ulong) uploadOffset, (ulong) SizeInBytes); + // CopyDest → Common + resourceBarrier.Transition.StateBefore = ResourceStates.CopyDest; + resourceBarrier.Transition.StateAfter = ResourceStates.Common; commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); result = commandList.Close(); @@ -297,7 +289,12 @@ public void Recreate(IntPtr dataPointer) } } - LayoutTracker.Initialize(BarrierMapping.ToBarrierLayout(desiredResourceState), 1); + // Default-heap buffers live in Common — non-default heaps live in their + // creation-time state (GenericRead for Upload / CopyDest for Readback) and + // are skipped by runtime barrier code via IsHostVisibleHeap. + LayoutTracker.Initialize(heapType == HeapType.Default + ? BarrierLayout.Common + : BarrierMapping.ToBarrierLayout(desiredResourceState), 1); NativeShaderResourceView = GetShaderResourceView(ViewFormat); NativeUnorderedAccessView = GetUnorderedAccessView(ViewFormat); diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 80b0c40b9e..6c5ad3e1ba 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -363,21 +363,16 @@ void InitializeTexture(DataBox[] initialData) var nativeDescription = NativeTextureDescription = GetTextureDescription(Dimension); - // Post-init layout. Drives both the ResourceStates for CreateCommittedResource - // (D3D12 creation is a ResourceStates API) and the LayoutTracker seed. - var desiredLayout = GetInitialBarrierLayout(); - var desiredResourceState = BarrierMapping.ToResourceStates(desiredLayout); - + // Create default-heap textures in COMMON. Enhanced Barriers only accept + // interop with legacy state tracking when the resource is in COMMON / BARRIER_LAYOUT_COMMON; + // any other initial state would cause the first runtime enhanced Barrier to be rejected + // with "does not support barrier interop" on strict D3D12 runtimes. bool hasInitData = initialData?.Length > 0; - // Always create in the desired state. For textures with init data that aren't - // already in CopyDest, we'll transition explicitly within the command list. - var initialResourceState = desiredResourceState; - // TODO: D3D12: Move that to a global allocator in bigger committed resources var heap = new HeapProperties { Type = HeapType.Default }; - HResult result = NativeDevice.CreateCommittedResource(in heap, HeapFlags.None, in nativeDescription, initialResourceState, + HResult result = NativeDevice.CreateCommittedResource(in heap, HeapFlags.None, in nativeDescription, ResourceStates.Common, in clearValueRef, out ComPtr textureResource); if (result.IsFailure) result.Throw(); @@ -401,13 +396,10 @@ void InitializeTexture(DataBox[] initialData) resourceBarrier.Transition.PResource = NativeResource; resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - // Transition to CopyDest for the upload - if (initialResourceState != ResourceStates.CopyDest) - { - resourceBarrier.Transition.StateBefore = initialResourceState; - resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; - commandList.ResourceBarrier(1, in resourceBarrier); - } + // Common → CopyDest for the upload + resourceBarrier.Transition.StateBefore = ResourceStates.Common; + resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; + commandList.ResourceBarrier(1, in resourceBarrier); var subresourceCount = initialData.Length; scoped Span placedSubresources = stackalloc PlacedSubresourceFootprint[subresourceCount]; @@ -461,13 +453,10 @@ ref rowSizeInBytes.GetReference(), commandList.CopyTextureRegion(in dest, DstX: 0, DstY: 0, DstZ: 0, in src, pSrcBox: in NullRef()); } - // Transition back to the desired state - if (initialResourceState != ResourceStates.CopyDest) - { - resourceBarrier.Transition.StateBefore = ResourceStates.CopyDest; - resourceBarrier.Transition.StateAfter = desiredResourceState; - commandList.ResourceBarrier(1, in resourceBarrier); - } + // CopyDest → Common so the first runtime Enhanced Barrier can take over. + resourceBarrier.Transition.StateBefore = ResourceStates.CopyDest; + resourceBarrier.Transition.StateAfter = ResourceStates.Common; + commandList.ResourceBarrier(1, in resourceBarrier); result = commandList.Close(); @@ -481,7 +470,9 @@ ref rowSizeInBytes.GetReference(), } } - LayoutTracker.Initialize(desiredLayout, ArraySize * MipLevelCount); + // Seed the tracker at Common — that is where the texture actually sits after init. + // The first runtime enhanced Barrier will transition it to whatever state it needs. + LayoutTracker.Initialize(BarrierLayout.Common, ArraySize * MipLevelCount); } // From f2878cb5ec1c21df4136fd07e2e09fedb0a468a3 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 09:59:13 +0900 Subject: [PATCH 1123/1182] D3D12: fix "only Barrier commands" perf warnings and no-draw Presents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The D3D12 debug layer flags ExecuteCommandLists calls whose CLs contain only barriers, and Stride was tripping it routinely: (a) GameBase unconditionally pushed a back-buffer → Present transition every frame, even on ticks that rendered nothing (test-framework init, SuppressDraw, minimized-without-DrawWhileMinimized); (b) CommandList.SetRenderTargets pushed RT/DS transitions at bind time, so ClearState during game init produced a barrier-only CL. Three interlocking changes: - GameBase.RawTick passes drawFrame (not hardcoded true) to EndDraw. No-draw ticks now skip Present entirely — avoids re-presenting undefined/stale back-buffer content on flip-model swap chains (D3D11/12/Vulkan all benefit) and avoids emitting a barrier-only CL. - Back-buffer → Present transition moves out of GameBase.EndDraw into each GraphicsPresenter.EndDraw, gated on the present flag. Swap-chain presenters do the transition; headless RenderTargetGraphicsPresenter (test framework) no-ops since there is no Present. - CommandList.SetRenderTargetsImpl (D3D12) no longer pushes RT/DS transitions at bind time. PrepareDraw now calls TransitionBoundRenderTargets just before draw submission, so a ClearState with no following draw records no barriers. Full D3D12 test suite (WARP): 394 passed, 0 failed. Vulkan unchanged. --- sources/engine/Stride.Games/GameBase.cs | 17 +++--- .../SwapChainGraphicsPresenter.Direct3D.cs | 5 ++ .../Direct3D12/CommandList.Direct3D12.cs | 59 ++++++++++++------- .../SwapChainGraphicsPresenter.Vulkan.cs | 4 ++ 4 files changed, 56 insertions(+), 29 deletions(-) diff --git a/sources/engine/Stride.Games/GameBase.cs b/sources/engine/Stride.Games/GameBase.cs index 5c28dd23c9..9dc569a8a1 100644 --- a/sources/engine/Stride.Games/GameBase.cs +++ b/sources/engine/Stride.Games/GameBase.cs @@ -674,7 +674,11 @@ protected void RawTick(TimeSpan elapsedTimePerUpdate, int updateCount = 1, float { using (Profiler.Begin(GameProfilingKeys.GameEndDraw)) { - EndDraw(true); + // Only Present if we actually drew this frame. Skipping Present on + // no-draw ticks avoids re-presenting undefined/stale back-buffer content + // (flip-model discards after Present) and, on D3D12, avoids emitting a + // barrier-only command list that trips the perf warning. + EndDraw(drawFrame); } } @@ -815,13 +819,10 @@ protected virtual void EndDraw(bool present) { if (beginDrawOk) { - if (GraphicsDevice.Presenter != null) - { - // Perform end of frame presenter operations - GraphicsDevice.Presenter.EndDraw(GraphicsContext.CommandList, present); - - GraphicsContext.CommandList.ResourceBarrierTransition(GraphicsDevice.Presenter.BackBuffer, BarrierLayout.Present); - } + // Each presenter handles its own back-buffer transition in EndDraw — swap-chain + // presenters transition to Present, render-target (headless) presenters skip + // since there is no Present call. Keeps this method presenter-agnostic. + GraphicsDevice.Presenter?.EndDraw(GraphicsContext.CommandList, present); GraphicsContext.ResourceGroupAllocator.Flush(); diff --git a/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs b/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs index 4ee16a55ae..0537fe3c97 100644 --- a/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs +++ b/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs @@ -350,6 +350,11 @@ public override void BeginDraw(CommandList commandList) /// public override void EndDraw(CommandList commandList, bool present) { + // Transition the back-buffer to Present so the upcoming IDXGISwapChain::Present sees + // it in the required layout. Skipped when the caller won't Present (no-draw frames, + // headless tests) — the back buffer stays in its current layout for next frame. + if (present) + commandList.ResourceBarrierTransition(BackBuffer, BarrierLayout.Present); } /// diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index 97db78b9f9..212d775992 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -188,8 +188,6 @@ void ResetCommandList() /// public partial void Flush() { - FlushResourceBarriers(); - var commandList = Close(); GraphicsDevice.ExecuteCommandList(commandList); } @@ -277,17 +275,9 @@ private void ResetTargetsImpl() { } /// The Render Targets to bind. private partial void SetRenderTargetsImpl(Texture depthStencilBuffer, ReadOnlySpan renderTargetViews) { - // Transition render targets and depth-stencil to the correct state - for (int i = 0; i < renderTargetViews.Length; ++i) - { - var rt = renderTargetViews[i]; - ResourceBarrierTransition(rt, BarrierLayout.RenderTarget, GetTextureSubresource(rt)); - } - - if (depthStencilBuffer is not null) - ResourceBarrierTransition(depthStencilBuffer, BarrierLayout.DepthStencilWrite, GetTextureSubresource(depthStencilBuffer)); - - FlushResourceBarriers(); + // RT/DS state transitions are deferred to PrepareDraw (see TransitionBoundRenderTargets) + // so a bare SetRenderTargets without any subsequent draw (e.g. ClearState during init) + // doesn't produce a command list with only barrier commands. int renderTargetCount = renderTargetViews.Length; @@ -402,11 +392,33 @@ private unsafe partial void SetScissorRectanglesImpl(ReadOnlySpan sci /// private void PrepareDraw() { + TransitionBoundRenderTargets(); TransitionDescriptorResources(); FlushResourceBarriers(); SetViewportImpl(); } + /// + /// Transitions the currently-bound render targets and depth-stencil buffer to their + /// render-writable states (RenderTarget / DepthStencilWrite). Done at draw time rather + /// than at SetRenderTargets time so a bind without any subsequent draw (e.g. ClearState + /// during game init) doesn't leave a barrier-only command list to submit. + /// + private void TransitionBoundRenderTargets() + { + var rts = RenderTargets; + for (int i = 0; i < rts.Length; ++i) + { + var rt = rts[i]; + if (rt is not null) + ResourceBarrierTransition(rt, BarrierLayout.RenderTarget, GetTextureSubresource(rt)); + } + + var ds = DepthStencilBuffer; + if (ds is not null) + ResourceBarrierTransition(ds, BarrierLayout.DepthStencilWrite, GetTextureSubresource(ds)); + } + /// /// Transitions all resources bound in descriptor sets to the correct state for shader access. /// SRV resources are transitioned to PixelShaderResource | NonPixelShaderResource, @@ -689,14 +701,19 @@ private unsafe void FlushResourceBarriers() { var desc = pendingBarriers[i]; + var syncBefore = BarrierMapping.ToEnhancedSync(desc.LayoutBefore); + var syncAfter = BarrierMapping.ToEnhancedSync(desc.LayoutAfter); + var accessBefore = BarrierMapping.ToEnhancedAccess(desc.LayoutBefore); + var accessAfter = BarrierMapping.ToEnhancedAccess(desc.LayoutAfter); + if (desc.Resource is Texture) { textureBarriers[textureCount++] = new D3D12TextureBarrier { - SyncBefore = BarrierMapping.ToEnhancedSync(desc.LayoutBefore), - SyncAfter = BarrierMapping.ToEnhancedSync(desc.LayoutAfter), - AccessBefore = BarrierMapping.ToEnhancedAccess(desc.LayoutBefore), - AccessAfter = BarrierMapping.ToEnhancedAccess(desc.LayoutAfter), + SyncBefore = syncBefore, + SyncAfter = syncAfter, + AccessBefore = accessBefore, + AccessAfter = accessAfter, LayoutBefore = BarrierMapping.ToEnhancedLayout(desc.LayoutBefore), LayoutAfter = BarrierMapping.ToEnhancedLayout(desc.LayoutAfter), PResource = desc.Resource.NativeResource, @@ -708,10 +725,10 @@ private unsafe void FlushResourceBarriers() { bufferBarriers[bufferCount++] = new D3D12BufferBarrier { - SyncBefore = BarrierMapping.ToEnhancedSync(desc.LayoutBefore), - SyncAfter = BarrierMapping.ToEnhancedSync(desc.LayoutAfter), - AccessBefore = BarrierMapping.ToEnhancedAccess(desc.LayoutBefore), - AccessAfter = BarrierMapping.ToEnhancedAccess(desc.LayoutAfter), + SyncBefore = syncBefore, + SyncAfter = syncAfter, + AccessBefore = accessBefore, + AccessAfter = accessAfter, PResource = desc.Resource.NativeResource, Offset = 0, Size = ulong.MaxValue, // Entire buffer diff --git a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs index 17f02626e9..30a100a1e1 100644 --- a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs @@ -266,6 +266,10 @@ public override void BeginDraw(CommandList commandList) public override void EndDraw(CommandList commandList, bool present) { + // Transition the back-buffer to Present before vkQueuePresentKHR sees it. + // Skipped when the caller won't actually Present (no-draw frames, headless tests). + if (present) + commandList.ResourceBarrierTransition(BackBuffer, BarrierLayout.Present); } protected override void OnNameChanged() From 8d98e8b1507b7554b4ffb4cec592dbc623a53c39 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 09:49:21 +0900 Subject: [PATCH 1124/1182] fix: warn when D3D11/D3D12 debug layer is silenced by RenderDoc RenderDoc replaces ID3D11InfoQueue / ID3D12InfoQueue with a stub that drops every call, so AddStorageFilterEntries and GetMessage silently do nothing and validation output disappears with no indication. --- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 12 ++++++++++++ .../Direct3D12/GraphicsDevice.Direct3D12.cs | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index ae4ab2ebad..7426990c97 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -338,6 +338,18 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP if (result.IsSuccess && infoQueue.IsNotNull()) { + // RenderDoc intercepts ID3D11InfoQueue with a stub that drops every call (see + // DummyID3D11InfoQueue in renderdoc/driver/d3d11/d3d11_device.cpp). The filter + // install and message drain below will appear to succeed but emit nothing, + // so warn the user upfront. Vulkan does not have this limitation — RenderDoc + // wraps vkCreateDebugUtilsMessengerEXT and forwards messages when the + // DebugOutputMute capture option is off. + if (Win32.GetModuleHandle("renderdoc.dll") != 0) + { + Log.Warning("[D3D11] RenderDoc detected — D3D11 debug-layer messages will not surface through the logger " + + "(RenderDoc returns a stub ID3D11InfoQueue). Use Vulkan to keep validation output under RenderDoc."); + } + nativeInfoQueue = infoQueue; infoQueue.SetMessageCountLimit(1000); diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 31bfc16fa6..b46580d99d 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -461,6 +461,18 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP if (result.IsSuccess && infoQueue.IsNotNull()) { + // RenderDoc intercepts ID3D12InfoQueue with a stub that drops every call (see + // DummyID3D12InfoQueue in renderdoc/driver/d3d12/d3d12_device.h). The filter + // install and message drain below will appear to succeed but emit nothing, + // so warn the user upfront. Vulkan does not have this limitation — RenderDoc + // wraps vkCreateDebugUtilsMessengerEXT and forwards messages when the + // DebugOutputMute capture option is off. + if (Win32.GetModuleHandle("renderdoc.dll") != 0) + { + Log.Warning("[D3D12] RenderDoc detected — D3D12 debug-layer messages will not surface through the logger " + + "(RenderDoc returns a stub ID3D12InfoQueue). Use Vulkan to keep validation output under RenderDoc."); + } + var disabledMessages = stackalloc MessageID[] { // These happens when a Render Target's or Depth-Stencil Buffer's clear values are different From 8357e915463c997cc286b42061dc94cae9ef6ee0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 11:49:00 +0900 Subject: [PATCH 1125/1182] D3D12: store command lists as ID3D12GraphicsCommandList7 Promotes the stored native command list type in GraphicsDevice, CommandList pool, CompiledCommandList, QueryPool, and WinPixNative from ID3D12GraphicsCommandList to ID3D12GraphicsCommandList7 (which inherits from it). Drops the runtime cast around the enhanced-barrier Barrier() call and keeps the enhanced-only API available everywhere without ad-hoc casting. --- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 7 ++----- .../Direct3D12/CommandList.Direct3D12.cs | 9 ++++----- .../CompiledCommandList.Direct3D12.cs | 2 +- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 17 +++++++---------- .../Direct3D12/QueryPool.Direct3D12.cs | 2 +- .../Stride.Graphics/Direct3D12/WinPixNative.cs | 6 +++--- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index 7426990c97..ed88d9050c 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -341,13 +341,10 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP // RenderDoc intercepts ID3D11InfoQueue with a stub that drops every call (see // DummyID3D11InfoQueue in renderdoc/driver/d3d11/d3d11_device.cpp). The filter // install and message drain below will appear to succeed but emit nothing, - // so warn the user upfront. Vulkan does not have this limitation — RenderDoc - // wraps vkCreateDebugUtilsMessengerEXT and forwards messages when the - // DebugOutputMute capture option is off. + // so warn the user upfront. if (Win32.GetModuleHandle("renderdoc.dll") != 0) { - Log.Warning("[D3D11] RenderDoc detected — D3D11 debug-layer messages will not surface through the logger " - + "(RenderDoc returns a stub ID3D11InfoQueue). Use Vulkan to keep validation output under RenderDoc."); + Log.Warning("[D3D11] RenderDoc detected — D3D11 debug-layer messages will not surface through the logger (RenderDoc returns a stub ID3D11InfoQueue)"); } nativeInfoQueue = infoQueue; diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index 212d775992..a167c1f2bd 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -46,7 +46,7 @@ public unsafe partial class CommandList private readonly Dictionary srvMapping = []; private readonly Dictionary samplerMapping = []; - internal readonly Queue> NativeCommandLists = new(); + internal readonly Queue> NativeCommandLists = new(); private CompiledCommandList currentCommandList; @@ -159,7 +159,7 @@ void ResetCommandList() { scoped ref var nullInitialPipelineState = ref NullRef(); - if (NativeCommandLists.TryDequeue(out ComPtr nativeCommandList)) + if (NativeCommandLists.TryDequeue(out ComPtr nativeCommandList)) { currentCommandList.NativeCommandList = nativeCommandList; @@ -172,7 +172,7 @@ void ResetCommandList() { var commandAllocator = currentCommandList.NativeCommandAllocator; HResult result = NativeDevice.CreateCommandList(nodeMask: 0, CommandListType.Direct, commandAllocator, ref nullInitialPipelineState, - out ComPtr commandList); + out ComPtr commandList); if (result.IsFailure) result.Throw(); @@ -767,8 +767,7 @@ private unsafe void FlushResourceBarriers() if (groupCount > 0) { - var commandList7 = (ID3D12GraphicsCommandList7*)currentCommandList.NativeCommandList.Handle; - commandList7->Barrier((uint)groupCount, (BarrierGroup*)groups); + currentCommandList.NativeCommandList.Barrier((uint)groupCount, (BarrierGroup*)groups); } } } diff --git a/sources/engine/Stride.Graphics/Direct3D12/CompiledCommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CompiledCommandList.Direct3D12.cs index 4abdf03ac3..dbf4202231 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CompiledCommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CompiledCommandList.Direct3D12.cs @@ -20,7 +20,7 @@ public unsafe partial struct CompiledCommandList /// /// The internal native Direct3D 12 Command List for graphics commands. /// - internal ComPtr NativeCommandList; + internal ComPtr NativeCommandList; /// /// The internal native Direct3D 12 Command Allocator for graphics commands. /// diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index b46580d99d..04afe4ff70 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -98,7 +98,7 @@ public unsafe partial class GraphicsDevice /// internal ComPtr NativeCopyCommandAllocator => ToComPtr(nativeCopyCommandAllocator); - private ID3D12GraphicsCommandList* nativeCopyCommandList; + private ID3D12GraphicsCommandList7* nativeCopyCommandList; /// /// Gets the internal Direct3D 12 Command List used for copy commands. @@ -107,7 +107,7 @@ public unsafe partial class GraphicsDevice /// If the reference is going to be kept, use to increment the internal /// reference count, and when no longer needed to release the object. /// - internal ComPtr NativeCopyCommandList => ToComPtr(nativeCopyCommandList); + internal ComPtr NativeCopyCommandList => ToComPtr(nativeCopyCommandList); internal object NativeCopyCommandListLock = new(); @@ -316,7 +316,7 @@ public void ExecuteCommandLists(int count, CompiledCommandList[] commandLists) for (int index = 0; index < count; index++) { var commandList = commandLists[index]; - commandListToExecute[index] = commandList.NativeCommandList.AsComPtr(); + commandListToExecute[index] = commandList.NativeCommandList.AsComPtr(); RecycleCommandListResources(commandList, commandListFenceValue + 1); } @@ -464,13 +464,10 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP // RenderDoc intercepts ID3D12InfoQueue with a stub that drops every call (see // DummyID3D12InfoQueue in renderdoc/driver/d3d12/d3d12_device.h). The filter // install and message drain below will appear to succeed but emit nothing, - // so warn the user upfront. Vulkan does not have this limitation — RenderDoc - // wraps vkCreateDebugUtilsMessengerEXT and forwards messages when the - // DebugOutputMute capture option is off. + // so warn the user upfront. if (Win32.GetModuleHandle("renderdoc.dll") != 0) { - Log.Warning("[D3D12] RenderDoc detected — D3D12 debug-layer messages will not surface through the logger " - + "(RenderDoc returns a stub ID3D12InfoQueue). Use Vulkan to keep validation output under RenderDoc."); + Log.Warning("[D3D12] RenderDoc detected — D3D12 debug-layer messages will not surface through the logger (RenderDoc returns a stub ID3D12InfoQueue)"); } var disabledMessages = stackalloc MessageID[] @@ -531,7 +528,7 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP nativeCopyCommandAllocator = commandAllocator; result = nativeDevice->CreateCommandList(nodeMask: 0, CommandListType.Direct, commandAllocator, pInitialState: ref NullRef(), - out ComPtr commandList); + out ComPtr commandList); if (result.IsFailure) result.Throw(); @@ -925,7 +922,7 @@ internal ulong ExecuteCommandListInternal(CompiledCommandList commandList) CommandListFence.Wait(NativeCommandQueue, commandListFenceValue); // Submit and signal fence - var nativeCommandList = commandList.NativeCommandList.AsComPtr(); + var nativeCommandList = commandList.NativeCommandList.AsComPtr(); nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, ref nativeCommandList); // Wait on GPU side to complete so that the next Command List (i.e. for a draw) diff --git a/sources/engine/Stride.Graphics/Direct3D12/QueryPool.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/QueryPool.Direct3D12.cs index ce2fdc8138..f06f771190 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/QueryPool.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/QueryPool.Direct3D12.cs @@ -101,7 +101,7 @@ public unsafe bool TryGetData(long[] dataArray) if (result.IsFailure) result.Throw(); - var copyCommandList = commandList.AsComPtr(); + var copyCommandList = commandList.AsComPtr(); var commandQueue = GraphicsDevice.NativeCommandQueue; commandQueue.ExecuteCommandLists(NumCommandLists: 1, ref copyCommandList); diff --git a/sources/engine/Stride.Graphics/Direct3D12/WinPixNative.cs b/sources/engine/Stride.Graphics/Direct3D12/WinPixNative.cs index df6b7b3de1..2202ffb0b4 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/WinPixNative.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/WinPixNative.cs @@ -119,7 +119,7 @@ static string GetLatestWinPixGpuCapturerPath() /// The Direct3D 12 Command List on which to end the PIX event. Must not be . /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void PIXEndEventOnCommandList(ComPtr commandList) + internal static unsafe void PIXEndEventOnCommandList(ComPtr commandList) { PIXEndEventOnCommandList((nint) commandList.Handle); } @@ -178,7 +178,7 @@ internal static unsafe void PIXEndEventOnCommandQueue(ComPtr /// The name of the event to display in PIX. Can be or empty if no name is desired. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void PIXBeginEventOnCommandList(ComPtr commandList, Color4 profileColor, string? name) + internal static unsafe void PIXBeginEventOnCommandList(ComPtr commandList, Color4 profileColor, string? name) { PIXBeginEventOnCommandList((nint) commandList.Handle, (uint) profileColor.ToBgra(), name); } @@ -224,7 +224,7 @@ private static extern void PIXBeginEventOnCommandQueue( /// The name of the marker to display in PIX. Can be or empty if no name is desired. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void PIXSetMarkerOnCommandList(ComPtr commandList, Color4 profileColor, string? name) + internal static unsafe void PIXSetMarkerOnCommandList(ComPtr commandList, Color4 profileColor, string? name) { PIXSetMarkerOnCommandList((nint) commandList.Handle, (uint) profileColor.ToBgra(), name); } From 8ffacee194b1b05857eb3b35ad98fc2efac57e7c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 11:55:31 +0900 Subject: [PATCH 1126/1182] D3D12: use enhanced barriers for init-time texture uploads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Init-time texture uploads on the copy command list were using legacy ResourceBarrier() for the Common → CopyDest transition, which mixed legacy and enhanced barriers on the same resource. Strict runtimes (WARP 1.0.18) did not propagate the legacy transition into the enhanced-barrier layout tracker, so the first runtime enhanced Barrier on the direct queue saw a layout mismatch ("Barrier layout(COPY_DEST) does not match expected layout (SHADER_RESOURCE)") across asset-loaded textures in most rendering tests. Use an enhanced Barrier for the Common → CopyDest transition and seed LayoutTracker at CopyDest afterwards; the first runtime enhanced Barrier now transitions from CopyDest to the needed layout. Drops the post-upload CopyDest → Common transition, which just added a round-trip. Buffers drop their explicit barriers entirely: buffers implicitly promote to CopyDest and always decay back to Common at ExecuteCommandLists. --- .../Direct3D12/Buffer.Direct3D12.cs | 16 ++------- .../Direct3D12/EnhancedBarriers.Direct3D12.cs | 34 +++++++++++++++++++ .../Direct3D12/Texture.Direct3D12.cs | 26 +++++--------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index ea8125dd60..dde75a3ea7 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -261,22 +261,10 @@ public void Recreate(IntPtr dataPointer) if (result.IsFailure) result.Throw(); - var resourceBarrier = new ResourceBarrier { Type = ResourceBarrierType.Transition }; - resourceBarrier.Transition.PResource = NativeResource; - resourceBarrier.Transition.Subresource = 0; - - // Common → CopyDest - resourceBarrier.Transition.StateBefore = ResourceStates.Common; - resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; - commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); - + // Buffers implicitly promote to CopyDest and decay back to Common at + // ExecuteCommandLists — no explicit barriers needed. commandList.CopyBufferRegion(NativeResource, DstOffset: 0, uploadResource, (ulong) uploadOffset, (ulong) SizeInBytes); - // CopyDest → Common - resourceBarrier.Transition.StateBefore = ResourceStates.CopyDest; - resourceBarrier.Transition.StateAfter = ResourceStates.Common; - commandList.ResourceBarrier(NumBarriers: 1, in resourceBarrier); - result = commandList.Close(); if (result.IsFailure) diff --git a/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs index fd18b7be49..79ca162a6b 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs @@ -142,4 +142,38 @@ internal unsafe struct D3D12BarrierGroup public void* PBarriers; } +internal static unsafe class EnhancedBarriers +{ + /// + /// Emits a single-texture enhanced Barrier on the given command list (all subresources). + /// + public static void TextureBarrier( + ID3D12GraphicsCommandList7* commandList, + ID3D12Resource* resource, + D3D12BarrierSync syncBefore, D3D12BarrierSync syncAfter, + D3D12BarrierAccess accessBefore, D3D12BarrierAccess accessAfter, + NativeBarrierLayout layoutBefore, NativeBarrierLayout layoutAfter) + { + var barrier = new D3D12TextureBarrier + { + SyncBefore = syncBefore, + SyncAfter = syncAfter, + AccessBefore = accessBefore, + AccessAfter = accessAfter, + LayoutBefore = layoutBefore, + LayoutAfter = layoutAfter, + PResource = resource, + Subresources = D3D12SubresourceRange.All, + Flags = 0, + }; + var group = new D3D12BarrierGroup + { + Type = D3D12BarrierType.Texture, + NumBarriers = 1, + PBarriers = &barrier, + }; + commandList->Barrier(1, (BarrierGroup*)&group); + } +} + #endif diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 6c5ad3e1ba..247bee30d5 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -391,15 +391,12 @@ void InitializeTexture(DataBox[] initialData) if (result.IsFailure) result.Throw(); - const uint D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES = 0xFFFFFFFF; - var resourceBarrier = new ResourceBarrier { Type = ResourceBarrierType.Transition }; - resourceBarrier.Transition.PResource = NativeResource; - resourceBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; - - // Common → CopyDest for the upload - resourceBarrier.Transition.StateBefore = ResourceStates.Common; - resourceBarrier.Transition.StateAfter = ResourceStates.CopyDest; - commandList.ResourceBarrier(1, in resourceBarrier); + // Enhanced Barrier Common → CopyDest for the upload. + EnhancedBarriers.TextureBarrier(commandList, + NativeResource, + syncBefore: D3D12BarrierSync.None, syncAfter: D3D12BarrierSync.Copy, + accessBefore: D3D12BarrierAccess.NoAccess, accessAfter: D3D12BarrierAccess.CopyDest, + layoutBefore: Silk.NET.Direct3D12.BarrierLayout.Common, layoutAfter: Silk.NET.Direct3D12.BarrierLayout.CopyDest); var subresourceCount = initialData.Length; scoped Span placedSubresources = stackalloc PlacedSubresourceFootprint[subresourceCount]; @@ -453,11 +450,6 @@ ref rowSizeInBytes.GetReference(), commandList.CopyTextureRegion(in dest, DstX: 0, DstY: 0, DstZ: 0, in src, pSrcBox: in NullRef()); } - // CopyDest → Common so the first runtime Enhanced Barrier can take over. - resourceBarrier.Transition.StateBefore = ResourceStates.CopyDest; - resourceBarrier.Transition.StateAfter = ResourceStates.Common; - commandList.ResourceBarrier(1, in resourceBarrier); - result = commandList.Close(); if (result.IsFailure) @@ -470,9 +462,9 @@ ref rowSizeInBytes.GetReference(), } } - // Seed the tracker at Common — that is where the texture actually sits after init. - // The first runtime enhanced Barrier will transition it to whatever state it needs. - LayoutTracker.Initialize(BarrierLayout.Common, ArraySize * MipLevelCount); + // Seed tracker at the post-init layout: CopyDest after an upload, Common otherwise. + LayoutTracker.Initialize(hasInitData ? BarrierLayout.CopyDest : BarrierLayout.Common, + ArraySize * MipLevelCount); } // From c4a6a68d1f1719e02b60129300257fe9ad060d77 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 12:20:00 +0900 Subject: [PATCH 1127/1182] D3D12: emit per-subresource enhanced Barriers when tracker tracks them FlushResourceBarriers was emitting every texture barrier with D3D12SubresourceRange.All regardless of the ResourceBarrierDescription's Subresource field. For textures under per-subresource tracking (cubemaps, mipmapped textures) that meant individual subresource transitions got broadcast across all subresources, and the runtime correctly rejected them because LayoutBefore matched only some subresources. --- .../Direct3D12/CommandList.Direct3D12.cs | 4 +++- .../Direct3D12/EnhancedBarriers.Direct3D12.cs | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index a167c1f2bd..e6ddadbd05 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -717,7 +717,9 @@ private unsafe void FlushResourceBarriers() LayoutBefore = BarrierMapping.ToEnhancedLayout(desc.LayoutBefore), LayoutAfter = BarrierMapping.ToEnhancedLayout(desc.LayoutAfter), PResource = desc.Resource.NativeResource, - Subresources = D3D12SubresourceRange.All, + Subresources = desc.Subresource == uint.MaxValue + ? D3D12SubresourceRange.All + : D3D12SubresourceRange.Single(desc.Subresource), Flags = 0, }; } diff --git a/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs index 79ca162a6b..c31ce5e0ad 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/EnhancedBarriers.Direct3D12.cs @@ -128,6 +128,21 @@ internal struct D3D12SubresourceRange FirstPlane = 0, NumPlanes = 0, }; + + /// + /// A range targeting a single subresource by its flat index. + /// + public static D3D12SubresourceRange Single(uint subresourceIndex) => new() + { + // Per D3D12 spec: when NumMipLevels is 0, IndexOrFirstMipLevel is interpreted as a + // single flat subresource index (matches D3D12_RESOURCE_BARRIER semantics). + IndexOrFirstMipLevel = subresourceIndex, + NumMipLevels = 0, + FirstArraySlice = 0, + NumArraySlices = 0, + FirstPlane = 0, + NumPlanes = 0, + }; } /// From 7d8d3e7660c2a7616447c9bc2c7b214775885b9a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 13:07:57 +0900 Subject: [PATCH 1128/1182] graphics: swap LayoutTracker in GraphicsResource.SwapInternal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Texture.Swap (used by streaming textures to hot-swap in newly loaded mip pyramids) called SwapInternal to swap native resource handles but didn't swap the LayoutTracker. After a swap, each texture's tracker described the layout of the OTHER resource's state — so the next barrier emitted carried a LayoutBefore that didn't match the actual resource's state, producing "barrier layout does not match expected" validation errors on the first frame after a stream-in. --- .../Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs | 1 + sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs index 4cdb2ca9a2..ac6b709f54 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsResource.Direct3D12.cs @@ -51,6 +51,7 @@ internal override void SwapInternal(GraphicsResourceBase other) (NativeShaderResourceView, otherResource.NativeShaderResourceView) = (otherResource.NativeShaderResourceView, NativeShaderResourceView); (NativeUnorderedAccessView, otherResource.NativeUnorderedAccessView) = (otherResource.NativeUnorderedAccessView, NativeUnorderedAccessView); (IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap); + (LayoutTracker, otherResource.LayoutTracker) = (otherResource.LayoutTracker, LayoutTracker); } } } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs index 3c23aa34f6..468d7a183b 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsResource.Vulkan.cs @@ -113,6 +113,7 @@ internal override void SwapInternal(GraphicsResourceBase other) (NativeMemory, otherResource.NativeMemory) = (otherResource.NativeMemory, NativeMemory); (NativePipelineStageMask, otherResource.NativePipelineStageMask) = (otherResource.NativePipelineStageMask, NativePipelineStageMask); (IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap); + (LayoutTracker, otherResource.LayoutTracker) = (otherResource.LayoutTracker, LayoutTracker); } } } From 6dc801069067c29773789bb56877d09df02d1d12 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 14:07:21 +0900 Subject: [PATCH 1129/1182] D3D12: add per-CL layout dict to decouple barrier reads from shared state MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ResourceBarrierTransition now reads/writes a per-CommandList Dictionary, seeded from the shared GraphicsResource.LayoutTracker on first touch of each resource in the CL. This matches the per-CB map that Vulkan added in 03a246a1b8 and insulates the read path from concurrent mutations of the shared tracker. Writes still mirror to the shared tracker — a later migration will drop the mirror and commit back at CL close/submit so the shared state only moves in submit order. Adds SubresourceLayoutTracker.Clone so the CL-local copy doesn't alias the shared tracker's perSubresource array. --- .../Direct3D12/CommandList.Direct3D12.cs | 24 +++++++++++++++---- .../SubresourceLayoutTracker.cs | 11 +++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index e6ddadbd05..d9219bfd49 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -42,6 +42,11 @@ public unsafe partial class CommandList // Scratch map for FlushResourceBarriers coalescing. Reused to avoid per-flush allocs. private readonly Dictionary<(GraphicsResource, uint), int> barrierCoalesceMap = new(16); + // Per-CL layout state. Seeded from GraphicsResource.LayoutTracker on first touch; used by + // ResourceBarrierTransition so the read path can't race concurrent writes. Writes still + // mirror to the shared tracker (matches Vulkan 03a246a1b8). + private readonly Dictionary cbLayouts = new(); + // Mappings from CPU-side Descriptor Handles to GPU-side Descriptor Handles private readonly Dictionary srvMapping = []; private readonly Dictionary samplerMapping = []; @@ -141,6 +146,8 @@ public unsafe partial void Reset() srvMapping.Clear(); samplerMapping.Clear(); + cbLayouts.Clear(); + currentCommandList.Builder = this; currentCommandList.SrvHeaps = GraphicsDevice.DescriptorHeapLists.Acquire(); currentCommandList.SamplerHeaps = GraphicsDevice.DescriptorHeapLists.Acquire(); @@ -612,13 +619,19 @@ public void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout n if (resource is Texture { ParentTexture: not null } textureView) resource = textureView.ParentTexture; - if (resource.LayoutTracker.NeedsTransition(subresource, newLayout)) + // Seed CL-local tracker from shared on first touch; Clone to avoid aliasing its + // perSubresource array. + ref var tracker = ref System.Runtime.InteropServices.CollectionsMarshal.GetValueRefOrAddDefault(cbLayouts, resource, out bool exists); + if (!exists) + tracker = resource.LayoutTracker.Clone(); + + if (tracker.NeedsTransition(subresource, newLayout)) { // When per-subresource tracking is active and a whole-resource transition is requested, // only emit barriers for subresources that actually differ - if (subresource == uint.MaxValue && resource.LayoutTracker.HasPerSubresourceTracking) + if (subresource == uint.MaxValue && tracker.HasPerSubresourceTracking) { - var layouts = resource.LayoutTracker.PerSubresourceLayouts; + var layouts = tracker.PerSubresourceLayouts; for (int i = 0; i < layouts.Length; i++) { if (layouts[i] != newLayout) @@ -632,13 +645,14 @@ public void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout n } else { - pendingBarriers.Add(new ResourceBarrierDescription(resource, resource.LayoutTracker.Get(subresource), newLayout) + pendingBarriers.Add(new ResourceBarrierDescription(resource, tracker.Get(subresource), newLayout) { Subresource = subresource }); } - resource.LayoutTracker.Set(subresource, newLayout); + tracker.Set(subresource, newLayout); + resource.LayoutTracker = tracker; } } diff --git a/sources/engine/Stride.Graphics/SubresourceLayoutTracker.cs b/sources/engine/Stride.Graphics/SubresourceLayoutTracker.cs index f6ae536e07..b0aa8a5657 100644 --- a/sources/engine/Stride.Graphics/SubresourceLayoutTracker.cs +++ b/sources/engine/Stride.Graphics/SubresourceLayoutTracker.cs @@ -94,4 +94,15 @@ public readonly bool NeedsTransition(uint subresource, BarrierLayout target) /// Gets the per-subresource array. Only valid when is true. /// internal readonly ReadOnlySpan PerSubresourceLayouts => perSubresource; + + /// + /// Returns an independent copy (a plain struct copy aliases the array). + /// + public readonly SubresourceLayoutTracker Clone() + { + var clone = this; + if (perSubresource != null) + clone.perSubresource = (BarrierLayout[])perSubresource.Clone(); + return clone; + } } From 49e9874f33f267b91d1bce6d2f4d0969c317a74c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 14:51:12 +0900 Subject: [PATCH 1130/1182] D3D12: init uploaded textures at their resting layout instead of CopyDest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uploaded textures now transition to their resting layout (ShaderResource for shader-readable, RenderTarget / DepthStencilWrite for write-only targets, etc.) at the end of the init copy CL instead of stopping at CopyDest. LayoutTracker is seeded at that layout so the texture is immediately usable without another transition on first runtime use. Removes a first-frame CopyDest→ShaderResource transition that was auto-emitted by TransitionDescriptorResources for every content-loaded texture — a transition that races with itself across parallel workers in Dispatcher.For-based render passes, producing intermittent BARRIER_LAYOUT_COPY_DEST vs BARRIER_LAYOUT_SHADER_RESOURCE validation errors on strict WARP. Uses the existing Texture.GetInitialBarrierLayout() for the target layout. Textures without init data keep the Common seed — their first runtime enhanced Barrier transitions Common → desired, which is the standard legacy-to-enhanced interop path and matches actual state. --- .../Direct3D12/Texture.Direct3D12.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 247bee30d5..9347e44f3a 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -363,12 +363,14 @@ void InitializeTexture(DataBox[] initialData) var nativeDescription = NativeTextureDescription = GetTextureDescription(Dimension); - // Create default-heap textures in COMMON. Enhanced Barriers only accept - // interop with legacy state tracking when the resource is in COMMON / BARRIER_LAYOUT_COMMON; - // any other initial state would cause the first runtime enhanced Barrier to be rejected - // with "does not support barrier interop" on strict D3D12 runtimes. + // Textures settle at their "resting" layout right after init (SR for shader-readable, + // RenderTarget/DepthStencilWrite for write-only targets, etc.). Renderers transition + // to/from the write state explicitly at pass boundaries. + var desiredLayout = GetInitialBarrierLayout(); bool hasInitData = initialData?.Length > 0; + // CreateCommittedResource must use COMMON so the subsequent enhanced Barrier on the + // copy CL is valid (legacy-to-enhanced barrier interop requires COMMON). // TODO: D3D12: Move that to a global allocator in bigger committed resources var heap = new HeapProperties { Type = HeapType.Default }; @@ -450,6 +452,15 @@ ref rowSizeInBytes.GetReference(), commandList.CopyTextureRegion(in dest, DstX: 0, DstY: 0, DstZ: 0, in src, pSrcBox: in NullRef()); } + // Transition to the resting layout so the texture is immediately usable + // without any further transition for its primary purpose (SR for shader- + // readable textures, RT/DSWrite for write targets, etc.). + EnhancedBarriers.TextureBarrier(commandList, + NativeResource, + syncBefore: D3D12BarrierSync.Copy, syncAfter: D3D12BarrierSync.None, + accessBefore: D3D12BarrierAccess.CopyDest, accessAfter: D3D12BarrierAccess.NoAccess, + layoutBefore: Silk.NET.Direct3D12.BarrierLayout.CopyDest, layoutAfter: BarrierMapping.ToEnhancedLayout(desiredLayout)); + result = commandList.Close(); if (result.IsFailure) @@ -462,8 +473,10 @@ ref rowSizeInBytes.GetReference(), } } - // Seed tracker at the post-init layout: CopyDest after an upload, Common otherwise. - LayoutTracker.Initialize(hasInitData ? BarrierLayout.CopyDest : BarrierLayout.Common, + // If no upload CL ran, the resource is still in COMMON (its creation state). + // Seed the tracker accordingly; the first runtime enhanced Barrier will transition + // from Common to whatever the renderer needs (standard interop). + LayoutTracker.Initialize(hasInitData ? desiredLayout : BarrierLayout.Common, ArraySize * MipLevelCount); } From ab4c9c5d10d1888e3541b47f6d0051f03c2a1208 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 15:24:35 +0900 Subject: [PATCH 1131/1182] D3D12: also transition no-data textures to their resting layout on init MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends 49e9874f33 to textures created without init data (e.g. GetSharedDepthTexture, render targets allocated empty). Any non-Common resting layout now triggers a short init CL that runs Common → desired on the copy CL. Avoids the parallel-worker race where two workers both emit the Common → ShaderResource transition on first sample. --- .../Direct3D12/Texture.Direct3D12.cs | 124 ++++++++++-------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs index 9347e44f3a..0e83042827 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs @@ -382,7 +382,11 @@ void InitializeTexture(DataBox[] initialData) SetNativeDeviceChild(textureResource.AsDeviceChild()); GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes); - if (hasInitData) + // Submit an init CL whenever we need to move the texture off Common — either to + // upload data or to reach the resting layout for no-data textures (so a parallel + // worker's first SRV bind doesn't race with the Common → resting transition). + bool needsInitCL = hasInitData || desiredLayout != BarrierLayout.Common; + if (needsInitCL) { var commandList = GraphicsDevice.NativeCopyCommandList; lock (GraphicsDevice.NativeCopyCommandListLock) @@ -393,73 +397,80 @@ void InitializeTexture(DataBox[] initialData) if (result.IsFailure) result.Throw(); - // Enhanced Barrier Common → CopyDest for the upload. - EnhancedBarriers.TextureBarrier(commandList, - NativeResource, - syncBefore: D3D12BarrierSync.None, syncAfter: D3D12BarrierSync.Copy, - accessBefore: D3D12BarrierAccess.NoAccess, accessAfter: D3D12BarrierAccess.CopyDest, - layoutBefore: Silk.NET.Direct3D12.BarrierLayout.Common, layoutAfter: Silk.NET.Direct3D12.BarrierLayout.CopyDest); - - var subresourceCount = initialData.Length; - scoped Span placedSubresources = stackalloc PlacedSubresourceFootprint[subresourceCount]; - scoped Span rowCounts = stackalloc uint[subresourceCount]; - scoped Span rowSizeInBytes = stackalloc ulong[subresourceCount]; - - ulong textureCopySize = 0; - - NativeDevice.GetCopyableFootprints(in nativeDescription, FirstSubresource: 0, (uint) subresourceCount, BaseOffset: 0, - ref placedSubresources.GetReference(), - ref rowCounts.GetReference(), - ref rowSizeInBytes.GetReference(), - ref textureCopySize); - - nint uploadMemory = GraphicsDevice.AllocateUploadBuffer((int) textureCopySize, - out ComPtr uploadResource, - out int uploadOffset, - D3D12.TextureDataPlacementAlignment); - for (int i = 0; i < subresourceCount; ++i) + if (hasInitData) { - scoped ref readonly var databox = ref initialData[i]; - scoped ref var placedSubresource = ref placedSubresources[i]; + // Enhanced Barrier Common → CopyDest for the upload. + EnhancedBarriers.TextureBarrier(commandList, + NativeResource, + syncBefore: D3D12BarrierSync.None, syncAfter: D3D12BarrierSync.Copy, + accessBefore: D3D12BarrierAccess.NoAccess, accessAfter: D3D12BarrierAccess.CopyDest, + layoutBefore: Silk.NET.Direct3D12.BarrierLayout.Common, layoutAfter: Silk.NET.Direct3D12.BarrierLayout.CopyDest); + + var subresourceCount = initialData.Length; + scoped Span placedSubresources = stackalloc PlacedSubresourceFootprint[subresourceCount]; + scoped Span rowCounts = stackalloc uint[subresourceCount]; + scoped Span rowSizeInBytes = stackalloc ulong[subresourceCount]; + + ulong textureCopySize = 0; + + NativeDevice.GetCopyableFootprints(in nativeDescription, FirstSubresource: 0, (uint) subresourceCount, BaseOffset: 0, + ref placedSubresources.GetReference(), + ref rowCounts.GetReference(), + ref rowSizeInBytes.GetReference(), + ref textureCopySize); + + nint uploadMemory = GraphicsDevice.AllocateUploadBuffer((int) textureCopySize, + out ComPtr uploadResource, + out int uploadOffset, + D3D12.TextureDataPlacementAlignment); + for (int i = 0; i < subresourceCount; ++i) + { + scoped ref readonly var databox = ref initialData[i]; + scoped ref var placedSubresource = ref placedSubresources[i]; - var dataPointer = databox.DataPointer; + var dataPointer = databox.DataPointer; - var rowCount = rowCounts[i]; - var sliceCount = placedSubresource.Footprint.Depth; - var rowSize = (int) rowSizeInBytes[i]; - var destRowPitch = placedSubresource.Footprint.RowPitch; + var rowCount = rowCounts[i]; + var sliceCount = placedSubresource.Footprint.Depth; + var rowSize = (int) rowSizeInBytes[i]; + var destRowPitch = placedSubresource.Footprint.RowPitch; - // Copy the init data to the upload buffer - for (int zSlice = 0; zSlice < sliceCount; zSlice++) - { - var uploadMemoryCurrent = uploadMemory + (int) placedSubresource.Offset + zSlice * destRowPitch * rowCount; - var dataPointerCurrent = dataPointer + zSlice * databox.SlicePitch; - - for (int row = 0; row < rowCount; ++row) + // Copy the init data to the upload buffer + for (int zSlice = 0; zSlice < sliceCount; zSlice++) { - MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemoryCurrent, (void*) dataPointerCurrent, (uint) rowSize); - uploadMemoryCurrent += destRowPitch; - dataPointerCurrent += databox.RowPitch; + var uploadMemoryCurrent = uploadMemory + (int) placedSubresource.Offset + zSlice * destRowPitch * rowCount; + var dataPointerCurrent = dataPointer + zSlice * databox.SlicePitch; + + for (int row = 0; row < rowCount; ++row) + { + MemoryUtilities.CopyWithAlignmentFallback((void*) uploadMemoryCurrent, (void*) dataPointerCurrent, (uint) rowSize); + uploadMemoryCurrent += destRowPitch; + dataPointerCurrent += databox.RowPitch; + } } - } - // Adjust upload offset (circular dependency between GetCopyableFootprints and AllocateUploadBuffer) - placedSubresource.Offset += (ulong) uploadOffset; + // Adjust upload offset (circular dependency between GetCopyableFootprints and AllocateUploadBuffer) + placedSubresource.Offset += (ulong) uploadOffset; - var dest = new TextureCopyLocation { Type = TextureCopyType.SubresourceIndex, PResource = NativeResource, SubresourceIndex = (uint) i }; - var src = new TextureCopyLocation { Type = TextureCopyType.PlacedFootprint, PResource = uploadResource, PlacedFootprint = placedSubresource }; + var dest = new TextureCopyLocation { Type = TextureCopyType.SubresourceIndex, PResource = NativeResource, SubresourceIndex = (uint) i }; + var src = new TextureCopyLocation { Type = TextureCopyType.PlacedFootprint, PResource = uploadResource, PlacedFootprint = placedSubresource }; - commandList.CopyTextureRegion(in dest, DstX: 0, DstY: 0, DstZ: 0, in src, pSrcBox: in NullRef()); + commandList.CopyTextureRegion(in dest, DstX: 0, DstY: 0, DstZ: 0, in src, pSrcBox: in NullRef()); + } } // Transition to the resting layout so the texture is immediately usable // without any further transition for its primary purpose (SR for shader- - // readable textures, RT/DSWrite for write targets, etc.). + // readable textures, RT/DSWrite for write targets, etc.). The LayoutBefore + // is CopyDest when we uploaded, or Common (creation state) when we didn't. + var preLayout = hasInitData ? Silk.NET.Direct3D12.BarrierLayout.CopyDest : Silk.NET.Direct3D12.BarrierLayout.Common; + var preAccess = hasInitData ? D3D12BarrierAccess.CopyDest : D3D12BarrierAccess.NoAccess; + var preSync = hasInitData ? D3D12BarrierSync.Copy : D3D12BarrierSync.None; EnhancedBarriers.TextureBarrier(commandList, NativeResource, - syncBefore: D3D12BarrierSync.Copy, syncAfter: D3D12BarrierSync.None, - accessBefore: D3D12BarrierAccess.CopyDest, accessAfter: D3D12BarrierAccess.NoAccess, - layoutBefore: Silk.NET.Direct3D12.BarrierLayout.CopyDest, layoutAfter: BarrierMapping.ToEnhancedLayout(desiredLayout)); + syncBefore: preSync, syncAfter: D3D12BarrierSync.None, + accessBefore: preAccess, accessAfter: D3D12BarrierAccess.NoAccess, + layoutBefore: preLayout, layoutAfter: BarrierMapping.ToEnhancedLayout(desiredLayout)); result = commandList.Close(); @@ -473,10 +484,9 @@ ref rowSizeInBytes.GetReference(), } } - // If no upload CL ran, the resource is still in COMMON (its creation state). - // Seed the tracker accordingly; the first runtime enhanced Barrier will transition - // from Common to whatever the renderer needs (standard interop). - LayoutTracker.Initialize(hasInitData ? desiredLayout : BarrierLayout.Common, + // needsInitCL transitioned the texture to its resting layout; otherwise it stays + // at Common and the first runtime enhanced Barrier will transition it from there. + LayoutTracker.Initialize(needsInitCL ? desiredLayout : BarrierLayout.Common, ArraySize * MipLevelCount); } From 4ca57345d1cd7aba8c4eecd6d3bd8a444ee25f77 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 16:21:18 +0900 Subject: [PATCH 1132/1182] graphics: transition lightClusters back to ShaderResource after UpdateSubResource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UpdateSubResource leaves its destination in CopyDest. The lightClusters 3D texture is updated on the main render thread every frame and then sampled by parallel worker CLs. When those workers each emit their own CopyDest → ShaderResource transition at first bind, the barriers race — the first worker's CL transitions the resource, subsequent workers' barriers then have LayoutBefore=CopyDest but the actual state is ShaderResource, tripping the D3D12 debug layer. Transition on the main thread right after the upload so parallel workers see ShaderResource on first touch (no barrier emitted). --- .../Rendering/Lights/LightClusteredPointSpotGroupRenderer.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointSpotGroupRenderer.cs b/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointSpotGroupRenderer.cs index e32f429dbb..f224bdfc50 100644 --- a/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointSpotGroupRenderer.cs +++ b/sources/engine/Stride.Rendering/Rendering/Lights/LightClusteredPointSpotGroupRenderer.cs @@ -524,6 +524,9 @@ public override unsafe void UpdateViewResources(RenderDrawContext context, int v fixed (Int2* dataPtr = renderViewInfo.LightClusters) context.CommandList.UpdateSubResource(clusteredGroupRenderer.lightClusters, 0, new DataBox((IntPtr)dataPtr, sizeof(Int2) * renderViewInfo.ClusterCount.X, sizeof(Int2) * renderViewInfo.ClusterCount.X * renderViewInfo.ClusterCount.Y), new ResourceRegion(0, 0, 0, renderViewInfo.ClusterCount.X, renderViewInfo.ClusterCount.Y, ClusterSlices)); + // Transition back to SR on the main-thread CL so parallel worker CLs don't + // race on the lazy CopyDest → ShaderResource transition at first bind. + context.CommandList.ResourceBarrierTransition(clusteredGroupRenderer.lightClusters, Graphics.BarrierLayout.ShaderResource); } // PointLights: Ensure size and update From 21741f85ceb2b4f1be3c986efc115a6244a9b7a4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 16:39:41 +0900 Subject: [PATCH 1133/1182] D3D12: drop auto-transition of RTs and SRVs at draw time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PrepareDraw used to call TransitionBoundRenderTargets and TransitionDescriptorResources, which implicitly transitioned every bound render target / SRV / UAV to its expected state before each draw. That worked single-threaded but races when multiple worker CLs (Dispatcher.For) touch the same resource: each worker emits its own X → ShaderResource barrier based on its own seed from shared state, and the second-in-order CL's barrier has a LayoutBefore that no longer matches the actual state after the first CL's barrier ran. Transitions are now explicit — owned by the renderer code that has the context (ShadowMapAtlas, ImageEffect, etc., and the recent LightClustered UpdateSubResource → SR transition). Stride.Graphics's draw path no longer second-guesses layouts. --- .../Direct3D12/CommandList.Direct3D12.cs | 67 ------------------- 1 file changed, 67 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index d9219bfd49..63f2ff7f19 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -282,10 +282,6 @@ private void ResetTargetsImpl() { } /// The Render Targets to bind. private partial void SetRenderTargetsImpl(Texture depthStencilBuffer, ReadOnlySpan renderTargetViews) { - // RT/DS state transitions are deferred to PrepareDraw (see TransitionBoundRenderTargets) - // so a bare SetRenderTargets without any subsequent draw (e.g. ClearState during init) - // doesn't produce a command list with only barrier commands. - int renderTargetCount = renderTargetViews.Length; var renderTargetHandles = stackalloc CpuDescriptorHandle[renderTargetCount]; @@ -399,73 +395,10 @@ private unsafe partial void SetScissorRectanglesImpl(ReadOnlySpan sci /// private void PrepareDraw() { - TransitionBoundRenderTargets(); - TransitionDescriptorResources(); FlushResourceBarriers(); SetViewportImpl(); } - /// - /// Transitions the currently-bound render targets and depth-stencil buffer to their - /// render-writable states (RenderTarget / DepthStencilWrite). Done at draw time rather - /// than at SetRenderTargets time so a bind without any subsequent draw (e.g. ClearState - /// during game init) doesn't leave a barrier-only command list to submit. - /// - private void TransitionBoundRenderTargets() - { - var rts = RenderTargets; - for (int i = 0; i < rts.Length; ++i) - { - var rt = rts[i]; - if (rt is not null) - ResourceBarrierTransition(rt, BarrierLayout.RenderTarget, GetTextureSubresource(rt)); - } - - var ds = DepthStencilBuffer; - if (ds is not null) - ResourceBarrierTransition(ds, BarrierLayout.DepthStencilWrite, GetTextureSubresource(ds)); - } - - /// - /// Transitions all resources bound in descriptor sets to the correct state for shader access. - /// SRV resources are transitioned to PixelShaderResource | NonPixelShaderResource, - /// UAV resources are transitioned to UnorderedAccess. - /// - private void TransitionDescriptorResources() - { - if (boundDescriptorSets is null) - return; - - for (int i = 0; i < boundDescriptorSets.Length; i++) - { - var tracking = boundDescriptorSets[i].Tracking; - if (tracking is null) - continue; - - var resources = tracking.Resources; - var isUAV = tracking.IsUAV; - - for (int j = 0; j < resources.Length; j++) - { - var resource = resources[j]; - if (resource is null) - continue; - - // Skip resources on CPU-visible heaps (Upload/Readback) — they have a fixed - // D3D12 state for their lifetime and cannot be transitioned. Must check by heap - // type, not by state: default-heap resources can be in CopyDest/GenericRead - // transiently after a copy and must still go through the transition. - if (resource.IsHostVisibleHeap) - continue; - - if (isUAV[j]) - ResourceBarrierTransition(resource, BarrierLayout.UnorderedAccess); - else - ResourceBarrierTransition(resource, BarrierLayout.ShaderResource); - } - } - } - /// /// Computes the D3D12 subresource index for a texture or texture view. /// Returns for whole-resource (non-view) textures. From dac9ef637a115c8be45e88365d0df82856d1fb3c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 16:47:58 +0900 Subject: [PATCH 1134/1182] D3D12: serialize main-queue submit with QueueLock; GPU-wait CopyFence Replaces the CPU wait added in the previous HEAD with proper GPU-side synchronization. Main-queue submits lock around fence inc + Execute + Signal (Vulkan parity) and insert a CopyFence GPU-wait if the copy queue has advanced since the last observed value, so the next draw is ordered after in-flight init uploads without a CPU stall. Also filters the NonOptimalBarrierOnlyExecuteCommandLists perf hint, which can still fire in edge cases (e.g. end-of-frame flushes). --- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 106 ++++++++++++------ 1 file changed, 71 insertions(+), 35 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 04afe4ff70..72d0c34dfb 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -67,6 +67,18 @@ public unsafe partial class GraphicsDevice /// internal ComPtr NativeCommandQueue => ToComPtr(nativeCommandQueue); + /// + /// Serializes the native-queue submit sequence (fence inc + ExecuteCommandLists + Signal) + /// across all paths that submit to it. Mirrors Vulkan's QueueLock. + /// + internal readonly object QueueLock = new(); + + /// + /// Highest value already waited on from a main-queue submit. + /// Starts at 1 so the first submit doesn't wait on an unsignaled value. + /// + private ulong lastGPUSyncCopyFenceToCommandFence = 1; + /// /// The requested graphics profile for the Graphics Device. /// @@ -309,24 +321,33 @@ public void ExecuteCommandLists(int count, CompiledCommandList[] commandLists) ArgumentNullException.ThrowIfNull(commandLists); ArgumentOutOfRangeException.ThrowIfGreaterThan(count, commandLists.Length); - var commandListFenceValue = CommandListFence.NextFenceValue++; - - // Recycle resources var commandListToExecute = stackalloc ID3D12CommandList*[count]; - for (int index = 0; index < count; index++) + + lock (QueueLock) { - var commandList = commandLists[index]; - commandListToExecute[index] = commandList.NativeCommandList.AsComPtr(); - RecycleCommandListResources(commandList, commandListFenceValue + 1); - } + var commandListFenceValue = CommandListFence.NextFenceValue++; + + for (int index = 0; index < count; index++) + { + var commandList = commandLists[index]; + commandListToExecute[index] = commandList.NativeCommandList.AsComPtr(); + RecycleCommandListResources(commandList, commandListFenceValue + 1); + } - if (commandListFenceValue > 0) - CommandListFence.Wait(NativeCommandQueue, commandListFenceValue); + if (commandListFenceValue > 0) + CommandListFence.Wait(NativeCommandQueue, commandListFenceValue); - // Submit and signal the fence - nativeCommandQueue->ExecuteCommandLists((uint) count, commandListToExecute); + var copyFenceValue = CopyFence.NextFenceValue; + if (copyFenceValue > lastGPUSyncCopyFenceToCommandFence) + { + CopyFence.Wait(NativeCommandQueue, copyFenceValue); + lastGPUSyncCopyFenceToCommandFence = copyFenceValue; + } + + nativeCommandQueue->ExecuteCommandLists((uint) count, commandListToExecute); - CommandListFence.Signal(NativeCommandQueue, commandListFenceValue + 1); + CommandListFence.Signal(NativeCommandQueue, commandListFenceValue + 1); + } if (IsDebugMode) FlushDebugMessages(); @@ -483,7 +504,12 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP // These happen when capturing with VS diagnostics MessageID.MapInvalidNullrange, - MessageID.UnmapInvalidNullrange + MessageID.UnmapInvalidNullrange, + + // Perf hint when a submitted CL contains only barrier commands; happens e.g. at + // frame end after a screenshot flushes the CL and only the Present transition + // remains. + MessageID.NonOptimalBarrierOnlyExecuteCommandLists, }; // Disable irrelevant debug layer warnings @@ -492,7 +518,7 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP AllowList = new Silk.NET.Direct3D12.InfoQueueFilterDesc(), DenyList = new Silk.NET.Direct3D12.InfoQueueFilterDesc { - NumIDs = 5, + NumIDs = 6, PIDList = disabledMessages } }; @@ -701,19 +727,22 @@ internal IntPtr AllocateUploadBuffer(int size, out ComPtr resour /// internal ulong ExecuteAndWaitCopyQueueGPU() { - var copyFenceValue = CopyFence.NextFenceValue++; - var nextCopyFenceValue = copyFenceValue + 1; + lock (QueueLock) + { + var copyFenceValue = CopyFence.NextFenceValue++; + var nextCopyFenceValue = copyFenceValue + 1; - // For now, we execute everything on the non-copy Command Queue otherwise ResourceBarrier won't work - // Improvement: on Copy Queue: we'll need to make sure to use only Common/Copy (and go back to Common before transfer); then a Signal - // on Graphics Queue: Wait for Signal and then ResourceBarrier - // https://learn.microsoft.com/en-us/windows/win32/direct3d12/user-mode-heap-synchronization - var commandList = (ID3D12CommandList*) nativeCopyCommandList; - nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, in commandList); + // For now, we execute everything on the non-copy Command Queue otherwise ResourceBarrier won't work + // Improvement: on Copy Queue: we'll need to make sure to use only Common/Copy (and go back to Common before transfer); then a Signal + // on Graphics Queue: Wait for Signal and then ResourceBarrier + // https://learn.microsoft.com/en-us/windows/win32/direct3d12/user-mode-heap-synchronization + var commandList = (ID3D12CommandList*) nativeCopyCommandList; + nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, in commandList); - CopyFence.Signal(NativeCommandQueue, nextCopyFenceValue); + CopyFence.Signal(NativeCommandQueue, nextCopyFenceValue); - return nextCopyFenceValue; + return nextCopyFenceValue; + } } /// @@ -916,20 +945,27 @@ internal void LogDredData() /// internal ulong ExecuteCommandListInternal(CompiledCommandList commandList) { - var commandListFenceValue = CommandListFence.NextFenceValue++; + ulong commandListFenceValue; + lock (QueueLock) + { + commandListFenceValue = CommandListFence.NextFenceValue++; + + if (commandListFenceValue > 0) + CommandListFence.Wait(NativeCommandQueue, commandListFenceValue); - if (commandListFenceValue > 0) - CommandListFence.Wait(NativeCommandQueue, commandListFenceValue); + var copyFenceValue = CopyFence.NextFenceValue; + if (copyFenceValue > lastGPUSyncCopyFenceToCommandFence) + { + CopyFence.Wait(NativeCommandQueue, copyFenceValue); + lastGPUSyncCopyFenceToCommandFence = copyFenceValue; + } - // Submit and signal fence - var nativeCommandList = commandList.NativeCommandList.AsComPtr(); - nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, ref nativeCommandList); + var nativeCommandList = commandList.NativeCommandList.AsComPtr(); + nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, ref nativeCommandList); - // Wait on GPU side to complete so that the next Command List (i.e. for a draw) - // can access the newly copied resources - CommandListFence.Signal(NativeCommandQueue, commandListFenceValue + 1); + CommandListFence.Signal(NativeCommandQueue, commandListFenceValue + 1); + } - // Recycle resources RecycleCommandListResources(commandList, commandListFenceValue + 1); return commandListFenceValue + 1; From 66b29bd431817a6b81d7b8ed9ff2260afce91ef5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 19:25:36 +0900 Subject: [PATCH 1135/1182] graphics: transition backbuffer to RenderTarget in Presenter.BeginDraw Moves the backbuffer RenderTarget transition out of the D3D12-specific bind-time path (gone) and out of the caller, into the base Presenter BeginDraw. D3D11/D3D12 SwapChainGraphicsPresenter drops its no-op override; Vulkan presenter calls base before its own reset. Clears two stale comments in GameBase/GameTestBase about transitions that are now handled here. --- sources/engine/Stride.Games/GameBase.cs | 1 - sources/engine/Stride.Graphics.Regression/GameTestBase.cs | 2 +- .../Direct3D/SwapChainGraphicsPresenter.Direct3D.cs | 5 ----- sources/engine/Stride.Graphics/GraphicsPresenter.cs | 1 + .../Vulkan/SwapChainGraphicsPresenter.Vulkan.cs | 2 +- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/sources/engine/Stride.Games/GameBase.cs b/sources/engine/Stride.Games/GameBase.cs index 9dc569a8a1..bb5563d769 100644 --- a/sources/engine/Stride.Games/GameBase.cs +++ b/sources/engine/Stride.Games/GameBase.cs @@ -785,7 +785,6 @@ protected virtual bool BeginDraw() // Perform begin of frame presenter operations if (GraphicsDevice.Presenter != null) { - // Note: RT/DS transitions are handled by SetRenderTargetsImpl when targets are bound. GraphicsDevice.Presenter.BeginDraw(GraphicsContext.CommandList); } diff --git a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs index dd2e528214..b1dec0ec7a 100644 --- a/sources/engine/Stride.Graphics.Regression/GameTestBase.cs +++ b/sources/engine/Stride.Graphics.Regression/GameTestBase.cs @@ -19,6 +19,7 @@ using Stride.Core.Mathematics; using Stride.Engine; using Stride.Games; +using Stride.Graphics; using Stride.Input; using Stride.Rendering; using Stride.Rendering.Compositing; @@ -234,7 +235,6 @@ public void SaveBackBuffer(string? testName = null) { TestGameLogger.Info(@"Saving the Back-Buffer"); - // TODO: GRAPHICS REFACTOR: Switched to presenter backbuffer, need to check if it's good var backBuffer = GraphicsDevice.Presenter.BackBuffer; using var image = backBuffer.GetDataAsImage(GraphicsContext.CommandList); SaveImage(image, testName); diff --git a/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs b/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs index 0537fe3c97..df34ee8bd4 100644 --- a/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs +++ b/sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs @@ -342,11 +342,6 @@ private void SetFullscreenState(bool isFullScreen) #endif } - /// - public override void BeginDraw(CommandList commandList) - { - } - /// public override void EndDraw(CommandList commandList, bool present) { diff --git a/sources/engine/Stride.Graphics/GraphicsPresenter.cs b/sources/engine/Stride.Graphics/GraphicsPresenter.cs index 8d248d9f14..eb98929304 100644 --- a/sources/engine/Stride.Graphics/GraphicsPresenter.cs +++ b/sources/engine/Stride.Graphics/GraphicsPresenter.cs @@ -176,6 +176,7 @@ public PresentInterval PresentInterval /// public virtual void BeginDraw(CommandList commandList) { + commandList.ResourceBarrierTransition(BackBuffer, BarrierLayout.RenderTarget); } /// diff --git a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs index 30a100a1e1..736904be8c 100644 --- a/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/SwapChainGraphicsPresenter.Vulkan.cs @@ -260,7 +260,7 @@ private unsafe void AcquireNextImage(bool recreateIfFails) public override void BeginDraw(CommandList commandList) { - // Backbuffer needs to be cleared + base.BeginDraw(commandList); backBuffer.IsInitialized = false; } From 542600126a44acae8ccae1a26621ad80e1347ed7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 22:12:56 +0900 Subject: [PATCH 1136/1182] graphics: transition font atlas back to ShaderResource after UpdateSubResource MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors 4ca57345d1 (lightClusters). UpdateSubResource leaves the atlas in CopyDest; with auto-transitions removed in 21741f85ce, the next sprite-batch sample reads a CopyDest-state texture. On D3D12 with Enhanced Barriers this doesn't trip a hard validation error — just returns undefined content — so glyphs uploaded later in the frame (CJK rows in TestDynamicSpriteFontVarious) render blank. --- sources/engine/Stride.Graphics/Font/FontCacheManager.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/engine/Stride.Graphics/Font/FontCacheManager.cs b/sources/engine/Stride.Graphics/Font/FontCacheManager.cs index 411d36504f..4d4f0728b8 100644 --- a/sources/engine/Stride.Graphics/Font/FontCacheManager.cs +++ b/sources/engine/Stride.Graphics/Font/FontCacheManager.cs @@ -125,6 +125,10 @@ public void UploadCharacterBitmap(CommandList commandList, CharacterSpecificatio } } ArrayPool.Shared.Return(expandedBuffer); + + // UpdateSubResource leaves the atlas in CopyDest; transition back so the next + // sprite-batch sample sees ShaderResource without relying on a lazy transition. + commandList.ResourceBarrierTransition(cacheTextures[0], BarrierLayout.ShaderResource); } // update the glyph data From 7091b24407e2b0e1b1352aaeef1d81cd15317299 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 23 Apr 2026 23:50:58 +0900 Subject: [PATCH 1137/1182] =?UTF-8?q?test:=20allow=20=E2=89=A410=20diff=20?= =?UTF-8?q?pixels=20on=20TestLightShafts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PostEffectBoundingRay uses a FP-hash-based jitter (HashXYZ * FastRandom) that flips a handful of pixels run-to-run when their view-space position lands near integer hash boundaries. Lavapipe exposes it; real GPUs are deterministic enough to mask it. --- tests/Stride.Graphics.Tests/thresholds.jsonc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/Stride.Graphics.Tests/thresholds.jsonc diff --git a/tests/Stride.Graphics.Tests/thresholds.jsonc b/tests/Stride.Graphics.Tests/thresholds.jsonc new file mode 100644 index 0000000000..1b2f3819b7 --- /dev/null +++ b/tests/Stride.Graphics.Tests/thresholds.jsonc @@ -0,0 +1,19 @@ +// Image comparison thresholds for Stride.Graphics.Tests +// Built-in default (no file needed): any pixel with diff >= 3 fails. +// Only add entries here for images that need relaxed thresholds. +// +// Format: +// image - image filename (required, or omit for suite-wide default) +// platform - "Windows", "Linux", "macOS" (optional, omit = any) +// api - "Vulkan", "Direct3D11", "Direct3D12" (optional, omit = any) +// device - "SwiftShader", "WARP", GPU name (optional, omit = any) +// allow - max allowed pixel counts per diff range (e.g. "1-2": 500, "16+": 2) +[ + { + // Jittered ray-marching in PostEffectBoundingRay samples a hash of view-space + // position; a handful of pixels land near integer hash boundaries and flip + // run-to-run, most visibly on Lavapipe. + "image": "TestLightShafts.png", + "allow": { "3+": 10 } + } +] From 9a70c883fcc28cd9f316a55ecfe14ff188286deb Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 24 Apr 2026 10:42:07 +0900 Subject: [PATCH 1138/1182] tests: split launchSettings into console/interactive, run xunit headlessly when not interactive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Avalonia UI used to fire whenever STRIDE_TESTS_GPU=1, conflating the GPU-vs-software backend choice with whether to launch the runner UI. Now keyed off STRIDE_TESTS_INTERACTIVE=1; Test Explorer / dotnet test / CI all bypass our Main entirely and stay headless. Each test project's launchSettings.json gets four profiles: Software/GPU each in (console) and (interactive) variants. Default first profile is Software (console), so F5 from VS runs xunit in-process via XunitFrontController + a console-printing sink and exits with status — matches what direct exe invocation produces under dotnet test. --- .../Properties/launchSettings.json | 19 ++++++- .../Properties/launchSettings.json | 19 ++++++- .../Properties/launchSettings.json | 19 ++++++- .../Properties/launchSettings.json | 19 ++++++- .../Properties/launchSettings.json | 19 ++++++- .../Properties/launchSettings.json | 19 ++++++- .../xunit.runner.stride/StrideXunitRunner.cs | 57 +++++++++++++++++-- 7 files changed, 153 insertions(+), 18 deletions(-) diff --git a/sources/engine/Stride.Engine.Tests/Properties/launchSettings.json b/sources/engine/Stride.Engine.Tests/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.Engine.Tests/Properties/launchSettings.json +++ b/sources/engine/Stride.Engine.Tests/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/engine/Stride.Graphics.Tests.10_0/Properties/launchSettings.json b/sources/engine/Stride.Graphics.Tests.10_0/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.Graphics.Tests.10_0/Properties/launchSettings.json +++ b/sources/engine/Stride.Graphics.Tests.10_0/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/engine/Stride.Graphics.Tests.11_0/Properties/launchSettings.json b/sources/engine/Stride.Graphics.Tests.11_0/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.Graphics.Tests.11_0/Properties/launchSettings.json +++ b/sources/engine/Stride.Graphics.Tests.11_0/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/engine/Stride.Graphics.Tests/Properties/launchSettings.json b/sources/engine/Stride.Graphics.Tests/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.Graphics.Tests/Properties/launchSettings.json +++ b/sources/engine/Stride.Graphics.Tests/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/engine/Stride.Particles.Tests/Properties/launchSettings.json b/sources/engine/Stride.Particles.Tests/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.Particles.Tests/Properties/launchSettings.json +++ b/sources/engine/Stride.Particles.Tests/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/engine/Stride.UI.Tests/Properties/launchSettings.json b/sources/engine/Stride.UI.Tests/Properties/launchSettings.json index 26edd5bd18..3e978f8adb 100644 --- a/sources/engine/Stride.UI.Tests/Properties/launchSettings.json +++ b/sources/engine/Stride.UI.Tests/Properties/launchSettings.json @@ -1,15 +1,30 @@ { "profiles": { - "Software": { + "Software (console)": { "commandName": "Project", "nativeDebugging": true }, - "GPU": { + "Software (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true + }, + "GPU (console)": { "commandName": "Project", "environmentVariables": { "STRIDE_TESTS_GPU": "1" }, "nativeDebugging": true + }, + "GPU (interactive)": { + "commandName": "Project", + "environmentVariables": { + "STRIDE_TESTS_GPU": "1", + "STRIDE_TESTS_INTERACTIVE": "1" + }, + "nativeDebugging": true } } } diff --git a/sources/tests/xunit.runner.stride/StrideXunitRunner.cs b/sources/tests/xunit.runner.stride/StrideXunitRunner.cs index 6cf97085e7..ded4cef9b4 100644 --- a/sources/tests/xunit.runner.stride/StrideXunitRunner.cs +++ b/sources/tests/xunit.runner.stride/StrideXunitRunner.cs @@ -1,9 +1,12 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System.Reflection; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Xunit; +using Xunit.Abstractions; namespace xunit.runner.stride; @@ -14,12 +17,10 @@ public static class StrideXunitRunner // yet and stuff might break. public static void Main(string[] _, Action? setInteractiveMode = null, Action? setForceSaveImage = null) { - // Skip Avalonia UI on headless systems (no display). - // Tests will be run by dotnet test / xunit adapter instead. if (IsHeadless()) { - // Signal non-interactive mode so tests use headless rendering setInteractiveMode?.Invoke(false); + Environment.ExitCode = RunHeadless(); return; } @@ -31,11 +32,55 @@ public static void Main(string[] _, Action? setInteractiveMode = null, Act } } + // Discover and run all tests in the entry assembly via XunitFrontController, printing a + // compact summary so direct exe invocation isn't a no-op. Test Explorer / dotnet test + // route through the xunit adapter and bypass this path entirely. + private static int RunHeadless() + { + var assemblyFileName = Assembly.GetEntryAssembly()!.Location; + using var controller = new XunitFrontController(AppDomainSupport.Denied, assemblyFileName); + + using var discoverySink = new TestDiscoverySink(); + controller.Find(includeSourceInformation: false, discoverySink, TestFrameworkOptions.ForDiscovery()); + discoverySink.Finished.WaitOne(); + + Console.WriteLine($"Discovered {discoverySink.TestCases.Count} tests in {Path.GetFileName(assemblyFileName)}"); + + using var executionSink = new ConsoleExecutionSink(); + controller.RunTests(discoverySink.TestCases, executionSink, TestFrameworkOptions.ForExecution()); + executionSink.Finished.WaitOne(); + + Console.WriteLine($"Total: {executionSink.Total}, Passed: {executionSink.Passed}, Failed: {executionSink.Failed}, Skipped: {executionSink.Skipped}, Time: {executionSink.ExecutionTime:F2}s"); + return executionSink.Failed > 0 ? 1 : 0; + } + + private sealed class ConsoleExecutionSink : TestMessageSink + { + public int Total; + public int Passed; + public int Failed; + public int Skipped; + public decimal ExecutionTime; + public ManualResetEvent Finished { get; } = new(initialState: false); + + public ConsoleExecutionSink() + { + Execution.TestPassedEvent += a => { Interlocked.Increment(ref Passed); Interlocked.Increment(ref Total); }; + Execution.TestSkippedEvent += a => { Interlocked.Increment(ref Skipped); Interlocked.Increment(ref Total); + Console.WriteLine($" SKIP {a.Message.Test.DisplayName}: {a.Message.Reason}"); }; + Execution.TestFailedEvent += a => { Interlocked.Increment(ref Failed); Interlocked.Increment(ref Total); + Console.WriteLine($" FAIL {a.Message.Test.DisplayName}"); + if (a.Message.Messages is { Length: > 0 } msgs) Console.WriteLine($" {msgs[0]}"); + if (a.Message.StackTraces is { Length: > 0 } st && st[0] is { Length: > 0 }) Console.WriteLine($" {st[0].Replace("\n", "\n ")}"); }; + Execution.TestAssemblyFinishedEvent += a => { ExecutionTime = a.Message.ExecutionTime; Finished.Set(); }; + } + } + private static bool IsHeadless() { - // Non-interactive when STRIDE_TESTS_GPU is not set to "1" (software rendering mode). - // In this mode, tests use headless rendering and don't need the Avalonia UI. - return Environment.GetEnvironmentVariable("STRIDE_TESTS_GPU") != "1"; + // Avalonia UI shows only when STRIDE_TESTS_INTERACTIVE=1 (set by per-project + // launchSettings.json profiles). Test Explorer / dotnet test / CI default to headless. + return Environment.GetEnvironmentVariable("STRIDE_TESTS_INTERACTIVE") != "1"; } // Avalonia configuration, don't remove; also used by visual designer. From 916d9a8312e8ed3ca4d069091c7174334bf8e056 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 24 Apr 2026 11:24:46 +0900 Subject: [PATCH 1139/1182] shaders: run --legalize-hlsl for FXC path only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop D3D12 spirv_to_dxil and Vulkan from the legalization step — they consume raw SPIR-V directly and don't need the HLSL-oriented rewrite. Limit LegalizeForHlsl to the SPIRV-Cross → FXC path where it's needed to prevent SPIRV-Cross emitting if(true)-style dead branches (from generic-template constants) and FXC's 'argument pulled into unrelated predicate' on shaders with Prepare/Compute helpers over a static stream struct. --- sources/Directory.Packages.props | 2 +- .../EffectCompiler.cs | 20 +++++++------------ .../Spirv/Tools/SpirvTools.cs | 10 ++++++++-- .../WARP/TesselationTest.f1.png | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sources/Directory.Packages.props b/sources/Directory.Packages.props index cb433d0e05..65deec986d 100644 --- a/sources/Directory.Packages.props +++ b/sources/Directory.Packages.props @@ -102,7 +102,7 @@ - + diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index 85ca29d9f9..d842a3f1eb 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -222,22 +222,16 @@ public override TaskOrResult Compile(ShaderMixinSo var spirvBytecodeForDebug = spirvBytecode.ToArray(); #endif - // Run SPIRV-Cross-tuned legalization on the merged SPIR-V module before - // any downstream consumer (SPIRV-Cross for D3D11 HLSL, or spirv-to-dxil - // for D3D12 DXIL). Folds constants, kills dead branches, legalizes - // structured CFG. Required to stop SPIRV-Cross emitting `if (true)`-style - // dead code when generic template values collapse to constants, and to - // give spirv-to-dxil a cleaner input. - // preserve_interface=true keeps Input/Output variables alive across stages - // — per-stage DCE otherwise leaves VS/HS outputs and PS/DS inputs out of - // sync, which FXC maps to mismatched hardware registers. The proper - // long-term fix is cross-stage DCE driven back-to-front (PS → DS/GS → VS). - var legalizedSpirv = Spirv.Tools.SpirvTools.LegalizeForHlsl(MemoryMarshal.Cast(spirvBytecode)); - try { if (useSpirvCrossToHlsl) { + // Legalize for SPIRV-Cross HLSL emission: const folding, DCE, + // SSA promotion, inlining. Avoids SPIRV-Cross emitting + // `if (true)` dead code from generic-template constants and + // FXC's 'argument pulled into unrelated predicate' on + // Prepare/Compute helpers over a static stream struct. + var legalizedSpirv = SpirvTools.LegalizeForHlsl(MemoryMarshal.Cast(spirvBytecode)); var translator = new SpirvTranslator(legalizedSpirv.AsMemory()); var translatorEntryPoints = translator.GetEntryPoints(); foreach (var entryPoint in translatorEntryPoints) @@ -314,7 +308,7 @@ public override TaskOrResult Compile(ShaderMixinSo { // Check API Spv2DXIL.spirv_to_dxil_get_version(); - CompileDxilPipeline(MemoryMarshal.AsBytes(legalizedSpirv), entryPoints, shaderStageBytecodes); + CompileDxilPipeline(spirvBytecode, entryPoints, shaderStageBytecodes); } else #endif diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs index f1eaaf07ff..1dac6047a5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Tools/SpirvTools.cs @@ -313,8 +313,14 @@ static extern Result OptimizerRun( /// /// Runs a legalization pass list tuned for SPIRV-Cross HLSL emission — - /// constant folding, DCE, CCP, structured-CFG cleanup — while keeping every - /// stage's Input/Output variables alive. + /// constant folding, DCE, CCP, structured-CFG cleanup, SSA promotion and + /// inlining — while keeping every stage's Input/Output + /// variables alive. Equivalent to spirv-opt --legalize-hlsl. + /// + /// Without the inlining + SSA passes here FXC can hit + /// 'internal error: argument pulled into unrelated predicate' on shaders + /// that call Prepare/Compute helpers through a static stream struct. + /// /// /// Interface preservation is a stopgap. Stride feeds a single merged module /// containing every stage to the optimizer, and spirv-opt has no cross-stage diff --git a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png index 2f36580345..35432648ac 100644 --- a/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png +++ b/tests/Stride.Engine.Tests/Windows.Direct3D12/WARP/TesselationTest.f1.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4aa6347e1ee634c029adf07657ec3fc4232d9316307e3fb8b97fe38bbdc17c97 -size 80710 +oid sha256:1727038c68e924f3cac7ec576b134bf9f9af6a9a409d6d3bbaedbb0401ad0428 +size 80706 From ad8b696d432dd1be2b27471891d5ec33c8f33830 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 24 Apr 2026 16:04:14 +0900 Subject: [PATCH 1140/1182] shaders: strip Silk.NET.SPIRV.Cross.Native files from consumers --- .../build/Stride.Shaders.Compilers.targets | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets index 2ba67558dd..630177fa03 100644 --- a/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets +++ b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets @@ -12,4 +12,12 @@ + + + + + + + + From 628e5c3de9a6c2c24ff55e7f91a2c6d7ea248f30 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 02:03:55 +0900 Subject: [PATCH 1141/1182] SDSL: emit UserTypeGOOGLE + NonWritable on rgroup StructuredBuffer vars Stage-scoped StructuredBuffer declarations in ShaderMember.Compile already emit these decorations so SPIRV-Cross maps them to the correct HLSL type. The rgroup path forgot to, leaving rgroup-declared read-only StructuredBuffer (e.g. TransformationInstancing.InstanceWorld) to drop through SPIRV-Cross as RWByteAddressBuffer on a UAV register. Regression-tested via CSStructuredBuffer + rgroup. --- .../Parsing/SDSL/AST/ShaderElements.cs | 11 +++++++ .../Stride.Shaders.Tests/RenderingTests.cs | 27 ++++++++++++++++ .../SDSL/ComputeTests/CSStructuredBuffer.sdsl | 31 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 sources/shaders/assets/SDSL/ComputeTests/CSStructuredBuffer.sdsl diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs index 67303b2109..bdab209bee 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.cs @@ -440,6 +440,17 @@ public override void Compile(SymbolTable table, ShaderClass shaderClass, Compile DecorateVariableLinkInfo(table, shaderClass, context, Info, member.Name, member.Attributes, variable.ResultId); + // Match the stage-variable path in ShaderMember.Compile: emit UserTypeGOOGLE / + // NonWritable so SPIRV-Cross emits StructuredBuffer / ByteAddressBuffer on SRV + // registers instead of defaulting to RWByteAddressBuffer on UAV registers. + if (type.BaseType is StructuredBufferType sb) + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, $"{(sb.WriteAllowed ? "rw" : "")}structuredbuffer:<{sb.BaseType.ToId().ToLowerInvariant()}>")); + else if (type.BaseType is ByteAddressBufferType bab) + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.UserTypeGOOGLE, bab.WriteAllowed ? "rwbyteaddressbuffer" : "byteaddressbuffer")); + + if (type.BaseType is ByteAddressBufferType { WriteAllowed: false } or StructuredBufferType { WriteAllowed: false }) + context.Add(new OpDecorate(variable.ResultId, Specification.Decoration.NonWritable, [])); + context.Add(new OpDecorateString(variable.ResultId, Specification.Decoration.ResourceGroupSDSL, Name)); // We also store an ID because multiple rgroup might have the same name, // but we still want to know which one was in the same "block" when we try to optimize them (we can only optimize a resource if all the resource in the same rgroup block can be optimized) diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index d07c7c8fab..9ec95191f7 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -78,6 +78,33 @@ public void ComputeTest1(string shaderName) } } + [Fact] + public void StructuredBufferEmitsStructuredBufferHlsl() + { + // Regression: StructuredBuffer/RWStructuredBuffer must reach HLSL as the + // matching types, not RWByteAddressBuffer. Requires NonWritable + UserTypeGOOGLE + // decorations to survive ShaderMixer / type-duplicate elimination. + const string shaderName = "CSStructuredBuffer"; + var shaderMixer = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); + shaderMixer.ShaderLoader.LoadExternalBuffer(shaderName, [], out _, out _, out _); + + var log = new Stride.Core.Diagnostics.LoggerResult(); + Assert.True(shaderMixer.MergeSDSL(new ShaderClassSource(shaderName), new ShaderMixer.Options(true), log, out var bytecode, out _, out _, out _), + string.Join(Environment.NewLine, log.Messages.Select(m => m.Text))); + + File.WriteAllBytes($"{shaderName}.spv", bytecode); + File.WriteAllText($"{shaderName}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + + var translator = new SpirvTranslator(bytecode.ToArray().AsMemory().Cast()); + var entryPoint = translator.GetEntryPoints().First(x => x.ExecutionModel == ExecutionModel.GLCompute); + var hlsl = translator.Translate(Backend.Hlsl, entryPoint); + File.WriteAllText($"{shaderName}.hlsl", hlsl); + + Assert.Contains("StructuredBuffer", hlsl); + Assert.Contains("RWStructuredBuffer", hlsl); + Assert.DoesNotContain("ByteAddressBuffer", hlsl); + } + [Theory] [MemberData(nameof(GetRenderTestFiles))] public void RenderTest1(string shaderName) diff --git a/sources/shaders/assets/SDSL/ComputeTests/CSStructuredBuffer.sdsl b/sources/shaders/assets/SDSL/ComputeTests/CSStructuredBuffer.sdsl new file mode 100644 index 0000000000..379f434a1d --- /dev/null +++ b/sources/shaders/assets/SDSL/ComputeTests/CSStructuredBuffer.sdsl @@ -0,0 +1,31 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +// Base shader holding the StructuredBuffer declarations. Matches the +// TransformationInstancing pattern where buffers live on a dependency class. +shader CSStructuredBufferBase +{ + struct Entry + { + float4x4 Matrix; + }; + + rgroup PerDraw.Test + { + stage StructuredBuffer InEntries; + stage RWStructuredBuffer OutEntries; + } +}; + +shader CSStructuredBuffer : CSStructuredBufferBase +{ + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + + [numthreads(1, 1, 1)] + void CSMain() + { + uint i = streams.DispatchThreadId.x; + OutEntries[i].Matrix = InEntries[i].Matrix; + } +}; From 99c9821c1f66d4b2e4ba8e75157c8122bc24bf88 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 10:17:54 +0900 Subject: [PATCH 1142/1182] build: strip StrideSkipAutoPack on CompilerApp ref in Stride.UnitTests.targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the fix on Stride.Build.Sdk.Tests/Sdk/Sdk.targets so test projects routed through the legacy targets path don't propagate StrideSkipAutoPack=true into CompilerApp — without packing, AssetCompiler can't resolve the test's package graph at runtime. --- sources/targets/Stride.UnitTests.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets index cb5bab817d..c3c7b81b02 100644 --- a/sources/targets/Stride.UnitTests.targets +++ b/sources/targets/Stride.UnitTests.targets @@ -22,6 +22,9 @@ false false TargetFramework=$(StrideXplatEditorTargetFramework) + + StrideSkipAutoPack true From 15df70baf15b9c40c26a3f47aee4417cf27fe292 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 11:22:24 +0900 Subject: [PATCH 1143/1182] SDSL: drop .N suffix from surviving cbuffer in MergeCBuffers count==1 path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a shader class declares two cbuffers with the same name (e.g. Transformation.PerDraw split across two blocks) RenameCBufferVariables suffixes them as `.0` / `.1`. ShaderMixer.MergeCBuffers groups them back by GetCBufferRealName but the count==1 branch — taken when one of the duplicates was DCE'd before the merge — only updated the in- memory Names dict; the OpName instruction in the buffer kept the suffixed name and the surviving struct type kept its `type.X_1` name. SPIRV-Cross derives the HLSL cbuffer name from the struct type (`type.X` → `cbuffer X`), so the rendered HLSL ended up with `cbuffer PerDraw_1 : register(b0)` while EffectReflection looked up `PerDraw`, throwing 'No matching element' at ShaderCompiler.UpdateReflection (DecalShader and similar effects). Use SetName for the variable's OpName and rename the surviving struct type back to the unsuffixed form. Regression-tested via CSCBufferRename. --- .../SDSL/ShaderMixer.CBuffers.cs | 11 +++++- .../Stride.Shaders.Tests/RenderingTests.cs | 29 ++++++++++++++ .../SDSL/ComputeTests/CSCBufferRename.sdsl | 39 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 sources/shaders/assets/SDSL/ComputeTests/CSCBufferRename.sdsl diff --git a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs index 49e79917e3..3e19faf9dc 100644 --- a/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs +++ b/sources/shaders/Stride.Shaders.Compilers/SDSL/ShaderMixer.CBuffers.cs @@ -258,11 +258,18 @@ CBufferMemberMetadata[] GenerateCBufferLinks(int cbufferVariableId, Span<(OpData var cbuffersSpan = CollectionsMarshal.AsSpan(cbuffers); // In all cases, we update name to one without .0 .1 suffix - // (we do it even for case count == 1 because all buffer except one might have been optimized away) - context.Names[cbuffersSpan[0].VariableId] = cbuffersEntry.Key; + // (we do it even for case count == 1 because all buffer except one might have been optimized away). + // SetName updates both the Names dict and the corresponding OpName instruction in the buffer. + context.SetName(cbuffersSpan[0].VariableId, cbuffersEntry.Key); if (cbuffersEntry.Count() == 1) { + // SPIRV-Cross derives the HLSL cbuffer name from the struct type name + // (`type.X` → `cbuffer X`), not the variable name. Rename the surviving + // struct type back to the unsuffixed form too, otherwise we get e.g. + // `cbuffer Settings_1 : register(b0)` which mismatches reflection's + // `Settings` lookup at ShaderCompiler.UpdateReflection. + context.SetName(context.Types[cbuffersSpan[0].StructType], $"type.{cbuffersEntry.Key}"); ProcessDecorations(cbuffersSpan, cbuffersEntry.First().StructType, false); } // More than 1 cbuffers with same name diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 9ec95191f7..6f56575d29 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -78,6 +78,35 @@ public void ComputeTest1(string shaderName) } } + [Fact] + public void DuplicateCBufferNameSurvivesMixerRename() + { + // Regression: when two shader classes declare a cbuffer with the same + // source-level name (e.g. PerDraw / Settings), MergeCBuffers groups + // them by GetCBufferRealName but for count==1 (after one is optimized + // out) it must rewrite the surviving variable's OpName back to the + // unsuffixed original. Otherwise SPIRV-Cross emits e.g. `Settings_1` + // which mismatches EffectReflection's `Settings` lookup at + // ShaderCompiler.UpdateReflection. + const string shaderName2 = "CSCBufferRename"; + var shaderMixer2 = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); + shaderMixer2.ShaderLoader.LoadExternalBuffer(shaderName2, [], out _, out _, out _); + + var log2 = new Stride.Core.Diagnostics.LoggerResult(); + Assert.True(shaderMixer2.MergeSDSL(new ShaderClassSource(shaderName2), new ShaderMixer.Options(true), log2, out var bytecode2, out _, out _, out _), + string.Join(Environment.NewLine, log2.Messages.Select(m => m.Text))); + + File.WriteAllBytes($"{shaderName2}.spv", bytecode2); + File.WriteAllText($"{shaderName2}.spvdis", Spv.Dis(SpirvBytecode.CreateFromSpan(bytecode2), DisassemblerFlags.Name | DisassemblerFlags.Id | DisassemblerFlags.InstructionIndex, true)); + var translator2 = new SpirvTranslator(bytecode2.ToArray().AsMemory().Cast()); + var entryPoint2 = translator2.GetEntryPoints().First(x => x.ExecutionModel == ExecutionModel.GLCompute); + var hlsl2 = translator2.Translate(Backend.Hlsl, entryPoint2); + File.WriteAllText($"{shaderName2}.hlsl", hlsl2); + + Assert.Contains("cbuffer Settings ", hlsl2); + Assert.DoesNotContain("cbuffer Settings_", hlsl2); + } + [Fact] public void StructuredBufferEmitsStructuredBufferHlsl() { diff --git a/sources/shaders/assets/SDSL/ComputeTests/CSCBufferRename.sdsl b/sources/shaders/assets/SDSL/ComputeTests/CSCBufferRename.sdsl new file mode 100644 index 0000000000..76586fb497 --- /dev/null +++ b/sources/shaders/assets/SDSL/ComputeTests/CSCBufferRename.sdsl @@ -0,0 +1,39 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +// A single shader class declaring two cbuffers with the same source-level name +// — same pattern as Stride.Rendering's Transformation.sdsl which splits PerDraw +// into two blocks. Each declaration gets a `.0` / `.1` suffix at parse time +// (RenameCBufferVariables); ShaderMixer.MergeCBuffers must fold the surviving +// variable's OpName back to the unsuffixed original. Otherwise SPIRV-Cross +// emits e.g. `cbuffer Settings_1` which mismatches EffectReflection's +// `Settings` lookup at ShaderCompiler.UpdateReflection. +shader CSCBufferRenameBase +{ + cbuffer Settings + { + stage float4x4 World; + }; + + cbuffer Settings + { + stage float4 Tint; + }; +}; + +shader CSCBufferRename : CSCBufferRenameBase +{ + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + + RWStructuredBuffer Out; + + [numthreads(1, 1, 1)] + void CSMain() + { + // Only Tint is used → World cbuffer (Settings.0) is DCE'd before + // MergeCBuffers, leaving cbuffersByNames with a count==1 group on + // the surviving Settings.1 variable. + Out[streams.DispatchThreadId.x] = Tint; + } +}; From 4647502b06d2ac8116b271056bbadb0832013074 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 11:37:08 +0900 Subject: [PATCH 1144/1182] SDSL: handle OpBitcast in OpSpecConstantOp constant folding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TryGetConstantValue switch fell through to NotImplementedException when a SpecConstant chain reinterpret-cast bits between scalar types (e.g. int↔uint, float↔int via asfloat/asuint pattern in a constant context). Reinterpret via BitConverter on the underlying 32-bit pattern and dispatch on the result type's scalar. --- .../Spirv/Building/Context.Constants.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs index 5a174caafd..04f0e413f2 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Building/Context.Constants.cs @@ -104,6 +104,27 @@ public bool TryGetConstantValue(OpDataIndex i, [MaybeNullWhen(false)] out object _ => throw new NotSupportedException($"Unsupported conversion op: {op}"), }; break; + // Bitcast: reinterpret the operand's bits as the target scalar type. + case Specification.Op.OpBitcast: + if (!TryGetConstantValue(i.Data.Memory.Span[4], out var bitcastOperand, out _)) + return false; + if (ReverseTypes[resultType] is not ScalarType { Type: var bitcastTargetScalar }) + throw new NotSupportedException($"OpBitcast result type {ReverseTypes[resultType]} is not a scalar"); + var bitcastBits = bitcastOperand switch + { + int v => (uint)v, + uint v => v, + float v => BitConverter.SingleToUInt32Bits(v), + _ => throw new NotSupportedException($"OpBitcast operand type {bitcastOperand.GetType()} is not supported"), + }; + value = bitcastTargetScalar switch + { + Scalar.Int => (object)(int)bitcastBits, + Scalar.UInt => bitcastBits, + Scalar.Float => BitConverter.UInt32BitsToSingle(bitcastBits), + _ => throw new NotSupportedException($"OpBitcast target scalar {bitcastTargetScalar} is not supported"), + }; + break; // Unary operations case Specification.Op.OpSNegate: case Specification.Op.OpFNegate: From 88986318bbba473dd8ced8cb144ec463c7445fa5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 12:08:09 +0900 Subject: [PATCH 1145/1182] SDSL: infer array size from initializer for static const member arrays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `static const uint info[] = {...};` left the symbol's type as ArrayType(Size=-1) even though the initializer fixed the count, so indexing the constant later allocated a Function temp typed as OpTypeRuntimeArray and then OpStored the OpSpecConstantComposite (of sized OpTypeArray) into it — SPIR-V validation rejected the type mismatch (e.g. SinglePassWireframeShader's infoA/infoB lookup tables). Mirror the inference logic from local DeclareStatement: after compiling the initializer, swap the unsized member type for the value's inferred sized type before registering the symbol. --- .../SDSL/AST/ShaderElements.MethodOrMember.cs | 5 +++++ .../Stride.Shaders.Tests/RenderingTests.cs | 21 ++++++++++++++++++ .../SDSL/ComputeTests/CSConstArrayInfer.sdsl | 22 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 sources/shaders/assets/SDSL/ComputeTests/CSConstArrayInfer.sdsl diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs index 9e88c072d8..3584b8aef5 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/ShaderElements.MethodOrMember.cs @@ -225,6 +225,11 @@ public override void ProcessSymbol(SymbolTable table, SpirvContext context) // Constant: compile right away var constantValue = Value.CompileConstantValue(table, context, memberType); + // Infer size for unsized arrays (e.g. `static const uint info[] = {...};`) from + // the initializer; otherwise indexing the constant later allocates a temp variable + // typed as runtime array, mismatching the OpSpecConstantComposite's sized OpTypeArray. + if (memberType is ArrayType { Size: -1 } && Value.ValueType is ArrayType { Size: > 0 } inferred) + memberType = inferred; context.SetName(constantValue.Id, Name); var constant = new Symbol(new(Name, SymbolKind.Constant), memberType, constantValue.Id, OwnerType: table.CurrentShader); table.CurrentFrame.Add(Name, constant); diff --git a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs index 6f56575d29..3f16b645d9 100644 --- a/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs +++ b/sources/shaders/Stride.Shaders.Tests/RenderingTests.cs @@ -107,6 +107,27 @@ public void DuplicateCBufferNameSurvivesMixerRename() Assert.DoesNotContain("cbuffer Settings_", hlsl2); } + [Fact] + public void UnsizedConstArrayInfersSizeForIndexing() + { + // Regression: `static const uint info[] = {...};` was kept as ArrayType + // with Size=-1 even after the initializer fixed the count, so indexing + // `info[i]` allocated a Function temp typed as OpTypeRuntimeArray and + // then OpStored the OpSpecConstantComposite of OpTypeArray<7> into it — + // SPIR-V validation rejects the type mismatch. + const string shaderName3 = "CSConstArrayInfer"; + var shaderMixer3 = new ShaderMixer(new ShaderLoader("./assets/SDSL/ComputeTests")); + shaderMixer3.ShaderLoader.LoadExternalBuffer(shaderName3, [], out _, out _, out _); + + var log3 = new Stride.Core.Diagnostics.LoggerResult(); + Assert.True(shaderMixer3.MergeSDSL(new ShaderClassSource(shaderName3), new ShaderMixer.Options(true), log3, out var bytecode3, out _, out _, out _), + string.Join(Environment.NewLine, log3.Messages.Select(m => m.Text))); + + File.WriteAllBytes($"{shaderName3}.spv", bytecode3); + var validation = Spv.ValidateFile($"{shaderName3}.spv"); + Assert.True(validation.IsValid, validation.Output); + } + [Fact] public void StructuredBufferEmitsStructuredBufferHlsl() { diff --git a/sources/shaders/assets/SDSL/ComputeTests/CSConstArrayInfer.sdsl b/sources/shaders/assets/SDSL/ComputeTests/CSConstArrayInfer.sdsl new file mode 100644 index 0000000000..0846e25df9 --- /dev/null +++ b/sources/shaders/assets/SDSL/ComputeTests/CSConstArrayInfer.sdsl @@ -0,0 +1,22 @@ +// PSMain(ExpectedResult=#00000000) + +namespace Stride.Shaders.Tests; + +// Regression: an unsized const array (size inferred from initializer) used as +// the source of a dynamic indexing must yield a sized array temp, not a +// runtime-array temp — otherwise OpStore on the materialization fails SPIR-V +// validation with "OpStore Pointer's type does not match Object's type". +shader CSConstArrayInfer +{ + static const uint info[] = { 0, 1, 2, 3, 4, 5, 6 }; + + stage stream uint3 DispatchThreadId : SV_DispatchThreadID; + RWStructuredBuffer Out; + + [numthreads(1, 1, 1)] + void CSMain() + { + uint idx = streams.DispatchThreadId.x; + Out[idx] = info[idx]; + } +}; From 0e2fcf5ed2fcbad7348df031bb20cbf5d30d389b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 12:53:25 +0900 Subject: [PATCH 1146/1182] build: drop unused glslangValidator binary and references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No C# code launches glslangValidator — the binary was only being copied into output by the legacy Stride.Shaders.Compiler.csproj and the active Stride.Shaders.Compilers.csproj. Drop both entries, the deps/glslang/ payload, the test-linux-game cleanup line that deleted it from outputs, and update the leftover comment in RestoreHelper that named it as an example. --- .gitattributes | 1 - .github/workflows/test-linux-game.yml | 3 +- deps/glslang/LICENSE.txt | 292 ------------------ deps/glslang/README.md | 5 - deps/glslang/linux-x64/glslangValidator.bin | 3 - deps/glslang/osx-x64/glslangValidator.bin | 3 - deps/glslang/win-x64/glslangValidator.exe | 3 - .../Stride.Shaders.Compiler.csproj | 5 - .../Stride.Shaders.Compilers.csproj | 5 - .../Stride.NuGetResolver/RestoreHelper.cs | 2 +- 10 files changed, 2 insertions(+), 320 deletions(-) delete mode 100644 deps/glslang/LICENSE.txt delete mode 100644 deps/glslang/README.md delete mode 100644 deps/glslang/linux-x64/glslangValidator.bin delete mode 100644 deps/glslang/osx-x64/glslangValidator.bin delete mode 100644 deps/glslang/win-x64/glslangValidator.exe diff --git a/.gitattributes b/.gitattributes index 69d610003e..a8d4fe7cb9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -25,7 +25,6 @@ *.so filter=lfs diff=lfs merge=lfs -text *.dylib filter=lfs diff=lfs merge=lfs -text *.pdb filter=lfs diff=lfs merge=lfs -text -glslangValidator filter=lfs diff=lfs merge=lfs -text # setup *.msi filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/test-linux-game.yml b/.github/workflows/test-linux-game.yml index c4b72a5fa5..02768c90f8 100644 --- a/.github/workflows/test-linux-game.yml +++ b/.github/workflows/test-linux-game.yml @@ -91,8 +91,7 @@ jobs: # Remove Windows/macOS native libs that are useless on Linux Get-ChildItem bin/Tests -Recurse -Include ` 'd3dcompiler_47.dll','freeimage.dll','FreeImage.dll','freetype.dll', ` - 'Silk.NET.Direct3D11.dll','Silk.NET.Direct3D12.dll','Silk.NET.Direct3D.Compilers.dll', ` - 'glslangValidator.exe' | + 'Silk.NET.Direct3D11.dll','Silk.NET.Direct3D12.dll','Silk.NET.Direct3D.Compilers.dll' | Remove-Item -Force # Remove macOS dylibs and Windows PDBs for native libs Get-ChildItem bin/Tests -Recurse -Include '*.dylib','freetype.pdb' | diff --git a/deps/glslang/LICENSE.txt b/deps/glslang/LICENSE.txt deleted file mode 100644 index 3e9f5e5656..0000000000 --- a/deps/glslang/LICENSE.txt +++ /dev/null @@ -1,292 +0,0 @@ -Copyright (c) 2015-2016 Valve Corporation -Copyright (c) 2015-2016 LunarG, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -==================== -Copyright (c) 2014-2016 The Khronos Group Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and/or associated documentation files (the "Materials"), to -deal in the Materials without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Materials, and to permit persons to whom the Materials are -furnished to do so, subject to the following conditions: - -The above copyright notice(s) and this permission notice shall be included in -all copies or substantial portions of the Materials. - -THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE -USE OR OTHER DEALINGS IN THE MATERIALS. - -==================== -Copyright 2015 The Android Open Source Project -Copyright (C) 2015 Valve Corporation - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -==================== -Copyright 2000-2009 Kitware, Inc., Insight Software Consortium -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -* Neither the names of Kitware, Inc., the Insight Software Consortium, - nor the names of their contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -==================== -Copyright (c) 2011 Fredrik Höglund -Copyright (c) 2008 Helio Chissini de Castro, -Copyright (c) 2007 Matthias Kretz, - -Redistribution and use is allowed according to the terms of the BSD license. - -==================== -Copyright (c) 2015-2016 The Khronos Group Inc. -Copyright (c) 2014-2016 Valve Corporation -Copyright (c) 2015-2016 LunarG, Inc. -Copyright (c) 2009 Dave Gamble - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -==================== -Copyright Kevlin Henney, 1997, 2003, 2012. All rights reserved. -Copyright (c) 2015 The Khronos Group Inc. -Copyright (c) 2015 Valve Corporation -Copyright (c) 2015 LunarG, Inc. - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose is hereby granted without fee, provided -that this copyright and permissions notice appear in all copies and -derivatives. - -This software is supplied "as is" without express or implied warranty. - -==================== -Copyright (c) 2015-2016 The Khronos Group Inc. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and/or associated documentation files (the -"Materials"), to deal in the Materials without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Materials, and to -permit persons to whom the Materials are furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Materials. - -THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. - -==================== -Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -==================== -Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. -Copyright (c) 2014, Valve Software. All rights reserved. - * -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of NVIDIA CORPORATION nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -==================== -Copyright 2007-2009 Kitware, Inc. -Copyright 2007-2008 Miguel A. Figueroa-Villanueva - -Distributed under the OSI-approved BSD License (the "License"); -see accompanying file Copyright_cmake.txt for details. - -This software is distributed WITHOUT ANY WARRANTY; without even the -implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -See the License for more information. - -==================== -RenderDoc License -RenderDoc is licensed under the MIT License: - The MIT License (MIT) - Copyright (c) 2015-2016 Baldur Karlsson - Copyright (c) 2014 Crytek - Permission is hereby granted, free of charge, to any person obtaining a copy of this - software and associated documentation files (the "Software"), to deal in the Software - without restriction, including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons - to whom the Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all copies or - substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE - FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - RenderDoc also uses several external libraries and components which include their own - licenses, linked below: - - http://codefromthe70s.org/mhook23.aspx - mhook distributed under the MIT license. Copyright Marton Anka 2007-2012, - portions Copyright 2007 Matt Conover. - - http://www.codeproject.com/Articles/23746/TreeView-with-Columns - http://www.codeproject.com/info/cpol10.aspx - TreeView with Columns distributed under the CPOL license. - - http://dockpanelsuite.com/ - Dock Panel Suite distributed under the MIT license. Copyright 2007 Weifen Luo. - - http://www.famfamfam.com/lab/icons/silk/ - famfamfam silk icons distributed under Creative Commons Attribution 2.5. Authored by - Mark James. - - http://scintillanet.codeplex.com/ - ScintillaNET (and Scintilla) distributed under the MIT license. ScintillaNET Copyright - 2002-2006 Garrett Serack, Scintilla Copyright 1998-2006 Neil Hodgson. - - https://code.google.com/p/google-breakpad/ - Google Breakpad distributed under the New BSD License (3 Clause). Copyright 2006 - Google Inc. - - https://code.google.com/p/miniz/ - miniz released to the Public Domain by Rich Geldreich. - - https://github.com/openexr/openexr/tree/master/IlmBase/Half - ILM's half implementation distributed under BSD license. Copyright 2002 Industrial Light - & Magic, a division of Lucas Digital Ltd. LLC - - https://code.google.com/p/jpeg-compressor/ - jpeg-compressor released to the Public Domain by Rich Geldreich. - - https://code.google.com/p/lz4/ - lz4 distributed under the New BSD License (3 Clause). Copyright 2013 Yann Collet. - - https://github.com/nothings/stb - released to the Public Domain by Sean Barrett. - - https://github.com/adobe-fonts/source-code-pro - distributed under the SIL Open Font License 1.1. Copyright 2010, 2012 Adobe Systems - Incorporated. - - http://ironpython.net/ - IronPython distributed under the Apache 2.0 License. Copyright IronPython Team. - - https://github.com/syoyo/tinyexr - tinyexr distributed under the New BSD License (3 Clause). Copyright 2014 Syoyo Fujita. - - https://github.com/KhronosGroup/glslang - glslang distributed under the New BSD License (3 Clause). Copyright 2002-2005 3Dlabs Inc. - Ltd. 2012-2013 LunarG, Inc. - - http://www.qt.io/ - Qt distributed under the GNU Lesser General Public License (LGPL) version 2.1. Copyright - 2015 The Qt Company Ltd. diff --git a/deps/glslang/README.md b/deps/glslang/README.md deleted file mode 100644 index bc644b96d0..0000000000 --- a/deps/glslang/README.md +++ /dev/null @@ -1,5 +0,0 @@ -glslang -======= - -Downloaded from https://github.com/KhronosGroup/glslang/releases/tag/7.11.3214 -Release versions diff --git a/deps/glslang/linux-x64/glslangValidator.bin b/deps/glslang/linux-x64/glslangValidator.bin deleted file mode 100644 index 53893ab44b..0000000000 --- a/deps/glslang/linux-x64/glslangValidator.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:82aff71e096ebee938455fa2e3dbccbc5504709bd7ef73aa3f1bf2642fb02fb8 -size 5757268 diff --git a/deps/glslang/osx-x64/glslangValidator.bin b/deps/glslang/osx-x64/glslangValidator.bin deleted file mode 100644 index 810ed2ead0..0000000000 --- a/deps/glslang/osx-x64/glslangValidator.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac7394700b3cd860ac7503485f43281693c20e0ad0563230087de47898d09b70 -size 6104252 diff --git a/deps/glslang/win-x64/glslangValidator.exe b/deps/glslang/win-x64/glslangValidator.exe deleted file mode 100644 index cc9b635bf5..0000000000 --- a/deps/glslang/win-x64/glslangValidator.exe +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1995da26768ef6aa55aea28e3ad6e3c20f47e4072b52e3406850058dcb955e10 -size 4182528 diff --git a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj index 4539187952..debcbb953e 100644 --- a/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj +++ b/sources/engine/Stride.Shaders.Compiler/Stride.Shaders.Compiler.csproj @@ -27,11 +27,6 @@ runtimes\win-%(RecursiveDir)native\%(Filename)%(Extension) PreserveNewest - - runtimes\%(RecursiveDir)native\%(Filename)%(Extension) - runtimes\%(RecursiveDir)native\%(Filename)%(Extension) - PreserveNewest - diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 64ad0ecb0b..54c532bc13 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -40,11 +40,6 @@ runtimes\win-%(RecursiveDir)native\%(Filename)%(Extension) PreserveNewest - - runtimes\%(RecursiveDir)native\%(Filename)%(Extension) - runtimes\%(RecursiveDir)native\%(Filename)%(Extension) - PreserveNewest - runtimes\win-x64\native\%(Filename)%(Extension) runtimes\win-x64\native\%(Filename)%(Extension) diff --git a/sources/shared/Stride.NuGetResolver/RestoreHelper.cs b/sources/shared/Stride.NuGetResolver/RestoreHelper.cs index 71ec6244b9..23c2ff9992 100644 --- a/sources/shared/Stride.NuGetResolver/RestoreHelper.cs +++ b/sources/shared/Stride.NuGetResolver/RestoreHelper.cs @@ -114,7 +114,7 @@ static bool IsValidNativeLibraryFile(string path) { return true; } - // Also handle executables (i.e. glslangValidator) + // Also handle executables shipped as native deps if (path.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".bin", StringComparison.OrdinalIgnoreCase)) { From 53e4282734af21e5a03b442e602c03f39d270936 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 18:16:09 +0900 Subject: [PATCH 1147/1182] Compositing: add ZPrepass sub-effect for depth-only GBuffer pass The light-probe Z-prepass binds DSV only and was reusing StrideForwardShadingEffect.ShadowMapCaster, which works but is semantically a shadow caster. Add a dedicated ZPrepass mixin child (same alpha-discard branching as ShadowMapCaster) and switch the GBuffer render stage in DefaultGraphicsCompositorLevel10 to it. Also move the ShadowMapCaster*/ZPrepass child declarations before mixin StrideLighting in StrideForwardShadingEffect: depth-only sub-effects don't need lighting, so the alpha-discard variants no longer drag the lighting compose chain through base.PSMain(). --- ...DefaultGraphicsCompositorLevel10.sdgfxcomp | 2 +- .../Rendering/Compositing/ForwardRenderer.cs | 1 - .../Rendering/Compositing/ZPrepass.sdfx | 27 +++++++++++++++++++ .../Rendering/StrideForwardShadingEffect.sdfx | 11 +++++--- 4 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 sources/engine/Stride.Rendering/Rendering/Compositing/ZPrepass.sdfx diff --git a/sources/engine/Stride.Engine/AssetPackage/Assets/Shared/DefaultGraphicsCompositorLevel10.sdgfxcomp b/sources/engine/Stride.Engine/AssetPackage/Assets/Shared/DefaultGraphicsCompositorLevel10.sdgfxcomp index 9fbce52bcb..242b77339d 100644 --- a/sources/engine/Stride.Engine/AssetPackage/Assets/Shared/DefaultGraphicsCompositorLevel10.sdgfxcomp +++ b/sources/engine/Stride.Engine/AssetPackage/Assets/Shared/DefaultGraphicsCompositorLevel10.sdgfxcomp @@ -55,7 +55,7 @@ RenderFeatures: EffectName: StrideForwardShadingEffect.ShadowMapCasterCubeMap 106341b76db9fcda6a033dad16aa708b: !Stride.Rendering.MeshTransparentRenderStageSelector,Stride.Rendering OpaqueRenderStage: ref!! ecab139e-5f55-42b5-a324-310c195a9c89 - EffectName: StrideForwardShadingEffect.ShadowMapCaster + EffectName: StrideForwardShadingEffect.ZPrepass PipelineProcessors: d70f5aee0616e4ab25081ceaf643290c: !Stride.Rendering.MeshPipelineProcessor,Stride.Rendering TransparentRenderStage: ref!! 0fa30591-02ee-486d-9347-2b6aee83d035 diff --git a/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs b/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs index a5772f3d2e..871eb102f0 100644 --- a/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs +++ b/sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs @@ -498,7 +498,6 @@ protected virtual void DrawView(RenderContext context, RenderDrawContext drawCon // Note: Baking lightprobe before GBuffer prepass because we are updating some cbuffer parameters needed by Opaque pass that GBuffer pass might upload early PrepareLightprobeConstantBuffer(context); - // TODO: Temporarily using ShadowMap shader using (drawContext.QueryManager.BeginProfile(Color.Green, CompositingProfilingKeys.GBuffer)) using (drawContext.PushRenderTargetsAndRestore()) { diff --git a/sources/engine/Stride.Rendering/Rendering/Compositing/ZPrepass.sdfx b/sources/engine/Stride.Rendering/Rendering/Compositing/ZPrepass.sdfx new file mode 100644 index 0000000000..3f2e2f52a2 --- /dev/null +++ b/sources/engine/Stride.Rendering/Rendering/Compositing/ZPrepass.sdfx @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using Stride.Rendering.Materials; +using Stride.Rendering.Shadows; + +namespace Stride.Rendering.Compositing +{ + // Spawn a sub-effect for the depth-only Z prepass (no color render target bound) + partial effect ZPrepass + { + using params MaterialKeys; + + // For cut off and blend materials we still need a pixel shader to perform the alpha test + if(MaterialKeys.UseDitheredShadows) + { + mixin ShadowMapCasterAlphaDithered; + } + else if(MaterialKeys.UsePixelShaderWithDepthPass) + { + mixin ShadowMapCasterAlphaDiscard; + } + else + { + mixin ShadowMapCasterNoPixelShader; + } + }; +} diff --git a/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx b/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx index 662ebee230..3cd3d5a8fa 100644 --- a/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx +++ b/sources/engine/Stride.Rendering/Rendering/StrideForwardShadingEffect.sdfx @@ -65,13 +65,16 @@ namespace Stride.Rendering mixin child GBuffer; } + // Depth-only sub-effects don't need lighting; declare them before StrideLighting + // so alpha-discard variants don't pull the lighting chain through base.PSMain(). + mixin child ShadowMapCaster; + mixin child ShadowMapCasterParaboloid; + mixin child ShadowMapCasterCubeMap; + mixin child ZPrepass; + // ----------------------------------------------- // Add direct and environment light groups // ----------------------------------------------- mixin StrideLighting; - - mixin child ShadowMapCaster; - mixin child ShadowMapCasterParaboloid; - mixin child ShadowMapCasterCubeMap; }; } From 1a4b3f19d6a0a24328318650a373695fc5eec15d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 19:07:59 +0900 Subject: [PATCH 1148/1182] Shadows: drop SV_Target0 from alpha-discard shadow caster shaders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ShadowMapCasterAlphaDiscard / ShadowMapCasterAlphaDithered used to chain through base.PSMain(), which writes streams.ColorTarget — that declared SV_Target0 in the PS output signature. Since shadow casting and the light-probe Z prepass bind only a depth target, every draw on those shaders would emit the D3D11 "PS expects RT View bound to slot 0, but none is bound" warning. Refactor both shaders to call this.Shading() directly to populate streams.shadingColorAlpha through the material surface chain, then clip without ever touching ColorTarget. The merged-effect Shading() override (MaterialSurfacePixelStageCompositor) runs the layered material chain identically to the regular pass, so per-layer contributions to the alpha are preserved. InterfaceProcessor previously dropped the Fragment entry point when nothing wrote SV_Target/SV_Depth, which would silently strip these shaders' PS entirely (clip never runs, transparent cutout pixels write depth). Detect "empty PSMain" by inspecting the SPIR-V function body instead — only the no-op PS case (e.g. ShadowMapCasterNoPixelShader) is dropped, preserving the depth-only fast path. Any side-effecting body (clip()/discard, stores, calls) keeps the PS bound. --- .../Shadows/ShadowMapCasterAlphaDiscard.sdsl | 11 +++++----- .../Shadows/ShadowMapCasterAlphaDithered.sdsl | 10 +++++---- .../Interfaces/InterfaceProcessor.cs | 21 ++++++++++++++++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl index e9186ce9cd..6c636c22de 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDiscard.sdsl @@ -1,17 +1,18 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. namespace Stride.Rendering.Shadows { /// /// Shadow map caster with pixel shader performing alpha discard test. + /// Runs the material surface chain to populate shadingColorAlpha but never writes ColorTarget, + /// so the resulting PS has no SV_Target output (depth-only). /// - shader ShadowMapCasterAlphaDiscard : Transformation, ShaderBase, PositionStream, MaterialPixelStream + shader ShadowMapCasterAlphaDiscard : Transformation, ShadingBase, PositionStream, MaterialPixelStream, MaterialPixelShadingStream { override stage void PSMain() { - base.PSMain(); - - clip(streams.ColorTarget.a - streams.matAlphaDiscard); + this.Shading(); + clip(streams.shadingColorAlpha - streams.matAlphaDiscard); } }; } diff --git a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl index f17f58ea6e..f2dee6c53c 100644 --- a/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl +++ b/sources/engine/Stride.Rendering/Rendering/Shadows/ShadowMapCasterAlphaDithered.sdsl @@ -4,10 +4,12 @@ namespace Stride.Rendering.Shadows { /// /// Shadow map caster with pixel shader performing a dithered alpha discard test. + /// Runs the material surface chain to populate shadingColorAlpha but never writes ColorTarget, + /// so the resulting PS has no SV_Target output (depth-only). /// - shader ShadowMapCasterAlphaDithered : Transformation, ShaderBase, PositionStream, MaterialPixelStream + shader ShadowMapCasterAlphaDithered : Transformation, ShadingBase, PositionStream, MaterialPixelStream, MaterialPixelShadingStream { - static const float BayerMatrix[16] = + static const float BayerMatrix[16] = { 0, 0.53333336, @@ -29,11 +31,11 @@ namespace Stride.Rendering.Shadows override stage void PSMain() { - base.PSMain(); + this.Shading(); int2 coord = int2(streams.ShadingPosition.xy % 4.0); float bayer = BayerMatrix[coord.x+coord.y*4]; - clip( -1.01 + bayer + streams.ColorTarget.a * 1.01 ); + clip( -1.01 + bayer + streams.shadingColorAlpha * 1.01 ); } }; } diff --git a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs index 785f7ef042..5f7d727729 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Spirv/Processing/Interfaces/InterfaceProcessor.cs @@ -112,9 +112,24 @@ public Result Process(SymbolTable table, SpirvBuffer buffer, SpirvContext contex } } - // Check if there is any output - // (if PSMain has been overriden with an empty method, it means we don't want to output anything and remove the pixel shader, i.e. for shadow caster) - if (streams.Any(x => x.Value.Output)) + // SDSL convention: `override stage void PSMain() { }` at the leaf of the mixin chain (with no + // further override) means "no pixel shader needed" — drop the Fragment entry point entirely. + // Detect this by inspecting the resolved PSMain body in SPIR-V: if it contains only structural + // instructions, the source body is empty and the convention applies. Anything else (clip/discard + // → OpKill, function calls, stores, atomics, etc.) keeps the PS. + var (psStart, psEnd) = SpirvBuilder.FindMethodBounds(buffer, entryPointPS.IdRef); + bool psBodyIsEmpty = true; + for (int idx = psStart; idx < psEnd; idx++) + { + var op = buffer[idx].Op; + if (op is not (Op.OpFunction or Op.OpFunctionParameter or Op.OpLabel or Op.OpReturn or Op.OpReturnValue or Op.OpFunctionEnd)) + { + psBodyIsEmpty = false; + break; + } + } + + if (!psBodyIsEmpty) { var psEntry = GenerateStreamWrapper(table, buffer, context, ExecutionModel.Fragment, entryPointPS, analysisResult, liveAnalysis, false); entryPoints.Add(psEntry); From 5b7f62caaddf46b538083e86b5d6be758b545f22 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sat, 25 Apr 2026 23:00:11 +0900 Subject: [PATCH 1149/1182] ci: capture full-memory dumps on test crashes Mini-dumps don't include the managed heap, so post-mortem analysis of shader-compiler AVs can't dereference any of the captured pointers. Switch all three Windows test crash-dump paths to full memory: - DOTNET_DbgMiniDumpType: 1 (Normal) -> 4 (FullMemory) - WER LocalDumps DumpType: 1 (Mini) -> 2 (Full) - Stride FirstChance SEH: add MiniDumpWithFullMemory and MiniDumpWithHandleData to the previous flag set (the existing MiniDumpWithFullMemoryInfo only captures region descriptors, not pages) Linux test workflow has no dump env vars set, so it's unchanged. --- .github/workflows/test-windows-game.yml | 4 ++-- sources/engine/Stride.Graphics.Regression/Module.cs | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-windows-game.yml b/.github/workflows/test-windows-game.yml index ee637aaedd..8e43da32d3 100644 --- a/.github/workflows/test-windows-game.yml +++ b/.github/workflows/test-windows-game.yml @@ -113,7 +113,7 @@ jobs: STRIDE_TESTS_CRASH_DUMPS: "1" # Type 1: SEHException logging + minidump via FirstChanceException STRIDE_TESTS_CRASH_DUMP_DIR: "${{ github.workspace }}\\TestResults" # Shared dump directory for all crash types DOTNET_DbgEnableMiniDump: "1" # Type 2: .NET unhandled exceptions - DOTNET_DbgMiniDumpType: "1" # MiniDumpNormal + DOTNET_DbgMiniDumpType: "4" # MiniDumpWithFullMemory DOTNET_DbgMiniDumpName: "${{ github.workspace }}\\TestResults\\dotnet_%p.dmp" # Type 2: dump path steps: - uses: actions/checkout@v4 @@ -132,7 +132,7 @@ jobs: $dumpDir = "${{ github.workspace }}\TestResults" New-Item -Path $dumpDir -ItemType Directory -Force | Out-Null reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d $dumpDir /f - reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 1 /f + reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f - name: Install Vulkan SDK if: matrix.graphics-api == 'Vulkan' diff --git a/sources/engine/Stride.Graphics.Regression/Module.cs b/sources/engine/Stride.Graphics.Regression/Module.cs index 4aa1108021..f35c8648af 100644 --- a/sources/engine/Stride.Graphics.Regression/Module.cs +++ b/sources/engine/Stride.Graphics.Regression/Module.cs @@ -97,10 +97,13 @@ private static void WriteMiniDump(string tag) var path = Path.Combine(crashDumpDir, $"{tag}_{Environment.ProcessId}_{DateTime.UtcNow:yyyyMMdd_HHmmss}.dmp"); using var fs = File.Create(path); var process = Process.GetCurrentProcess(); - const uint MiniDumpWithThreadInfo = 0x00001000; + const uint MiniDumpWithFullMemory = 0x00000002; const uint MiniDumpWithFullMemoryInfo = 0x00000800; + const uint MiniDumpWithHandleData = 0x00000004; + const uint MiniDumpWithThreadInfo = 0x00001000; bool ok = MiniDumpWriteDump(process.Handle, (uint)process.Id, fs.SafeFileHandle.DangerousGetHandle(), - MiniDumpWithThreadInfo | MiniDumpWithFullMemoryInfo, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); + MiniDumpWithFullMemory | MiniDumpWithFullMemoryInfo | MiniDumpWithHandleData | MiniDumpWithThreadInfo, + IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); Console.Error.WriteLine(ok ? $"[CrashDiag] Dump written: {path}" : $"[CrashDiag] Dump failed: error {Marshal.GetLastWin32Error()}"); From df2321e2ee0c421dcd1a7c3ba61021d3120a963a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 26 Apr 2026 10:38:14 +0900 Subject: [PATCH 1150/1182] upgrader: rename legacy .sdsl.cs / .sdfx.cs siblings to .bak on 4.4 These were written next to the source by the old custom MSBuild tool; they are now produced by the Roslyn source generator into obj/. The on-disk siblings are dead weight (excluded from build but still in source trees and version control). The 4.3 -> 4.4 step in StridePackageUpgrader: - Renames .sdsl.cs / .sdfx.cs to .bak in the project tree (skipping obj/ and bin/) so users can recover without git. - Strips leftover csproj item nodes referencing those paths. - Strips obsolete / metadata from .sdsl and .sdfx items. Drop the now-unnecessary rules from Stride.Shaders.Compilers.targets. The rules for .sdsl and .sdfx source files stay -- they keep source files out of the default glob. --- .../Stride.Assets/StridePackageUpgrader.cs | 76 +++++++++++++++++++ .../build/Stride.Shaders.Compilers.targets | 2 - 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/sources/engine/Stride.Assets/StridePackageUpgrader.cs b/sources/engine/Stride.Assets/StridePackageUpgrader.cs index 7343e8c57a..2100590bc5 100644 --- a/sources/engine/Stride.Assets/StridePackageUpgrader.cs +++ b/sources/engine/Stride.Assets/StridePackageUpgrader.cs @@ -299,6 +299,82 @@ public override bool UpgradeBeforeAssembliesLoaded(PackageLoadParameters loadPar } } + if (dependency.Version.MinVersion < new PackageVersion("4.4.0.0") && solutionProject != null) + { + // .sdsl/.sdfx generated C# files used to be written next to the source by a custom + // MSBuild tool. They are now produced by a Roslyn source generator into obj/. Rename + // the on-disk siblings to .bak (recoverable, inert in build) and strip leftover + // csproj items / Generator metadata. + var projectDir = projectFullPath.GetFullDirectory().ToOSPath(); + int renamedCount = 0; + foreach (var file in Directory.EnumerateFiles(projectDir, "*.cs", SearchOption.AllDirectories)) + { + if (!(file.EndsWith(".sdsl.cs", StringComparison.OrdinalIgnoreCase) + || file.EndsWith(".sdfx.cs", StringComparison.OrdinalIgnoreCase))) + continue; + + // Skip build output (Roslyn-generated copies live in obj/, copies may be staged in bin/) + var rel = Path.GetRelativePath(projectDir, file).Replace('\\', '/'); + if (rel.StartsWith("obj/", StringComparison.OrdinalIgnoreCase) + || rel.StartsWith("bin/", StringComparison.OrdinalIgnoreCase) + || rel.Contains("/obj/", StringComparison.OrdinalIgnoreCase) + || rel.Contains("/bin/", StringComparison.OrdinalIgnoreCase)) + continue; + + try + { + File.Move(file, file + ".bak", overwrite: true); + log.Info($"Renamed legacy generated shader file: {rel} -> {rel}.bak"); + renamedCount++; + } + catch (Exception e) + { + log.Warning($"Could not rename legacy generated shader file [{rel}]", e); + } + } + + // Strip leftover csproj item nodes referencing .sdsl.cs / .sdfx.cs paths + foreach (var item in project.Xml.ItemGroups + .SelectMany(g => g.Items) + .Where(x => + { + var path = x.Include ?? x.Update ?? string.Empty; + return path.EndsWith(".sdsl.cs", StringComparison.OrdinalIgnoreCase) + || path.EndsWith(".sdfx.cs", StringComparison.OrdinalIgnoreCase); + }) + .ToArray()) + { + item.Parent.RemoveChild(item); + isProjectDirty = true; + } + + // Strip obsolete Generator/LastGenOutput metadata from .sdsl/.sdfx items. + // Walk the project XML directly — project.Items returns evaluated items + // (including ones from imported SDK props), which can't be mutated. + foreach (var item in project.Xml.ItemGroups + .SelectMany(g => g.Items) + .Where(x => + { + var path = x.Include ?? x.Update ?? string.Empty; + return path.EndsWith(".sdsl", StringComparison.OrdinalIgnoreCase) + || path.EndsWith(".sdfx", StringComparison.OrdinalIgnoreCase); + }) + .ToArray()) + { + foreach (var metadata in item.Metadata.ToArray()) + { + if (metadata.Name == "Generator" || metadata.Name == "LastGenOutput") + { + item.RemoveChild(metadata); + isProjectDirty = true; + } + } + } + + if (renamedCount > 0) + log.Info($"Renamed {renamedCount} legacy generated shader file(s) to .bak. The Roslyn source generator now produces these into obj/. Delete the .bak files when you've verified the upgrade."); + } + if (isProjectDirty) project.Save(); diff --git a/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets index 630177fa03..423f654deb 100644 --- a/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets +++ b/sources/shaders/Stride.Shaders.Compilers/build/Stride.Shaders.Compilers.targets @@ -5,8 +5,6 @@ ***************************************************************************************************************************** --> - - From 28fa4fac36b16cba7e2bb91589b41cd108e4819c Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 26 Apr 2026 17:41:27 +0900 Subject: [PATCH 1151/1182] sdsl: fix sincos result type to match input float, not function void CompileSincos was passing the sincos function's FunctionType to the GLSL Sin/Cos helpers, which take their result type from functionType.ReturnType. sincos returns void, so the emitted SPIR-V was OpExtInst %void Sin %x -- rejected by spirv-val with "GLSL.std.450 Sin: expected Result Type to be a 16 or 32-bit scalar or vector float type". Synthesize a function type whose ReturnType is x's float type and use that for the Sin/Cos extinsts. --- .../Parsing/SDSL/AST/IntrinsicImplementations.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index f2571f5458..338cba3d7a 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -72,8 +72,9 @@ public override SpirvValue CompileAsdouble(SymbolTable table, SpirvContext conte public override SpirvValue CompileSincos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c, TextLocation location = default) { // sincos(x, out s, out c): compute sin and cos separately, store to out params - var sinVal = CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSin, x); - var cosVal = CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCos, x); + var sinCosType = functionType with { ReturnType = context.ReverseTypes[x.TypeId] }; + var sinVal = CompileGLSLFloatUnaryCall(table, context, builder, sinCosType, Specification.GLSLOp.GLSLSin, x); + var cosVal = CompileGLSLFloatUnaryCall(table, context, builder, sinCosType, Specification.GLSLOp.GLSLCos, x); builder.Insert(new OpStore(s.Id, sinVal.Id, null, [])); builder.Insert(new OpStore(c.Id, cosVal.Id, null, [])); return new(); From a2549ccb344577d110ee9e585957f354760859b6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Sun, 26 Apr 2026 17:47:18 +0900 Subject: [PATCH 1152/1182] sdsl: take SymbolType resultType in intrinsic helpers, drop unused FunctionType The static intrinsic helpers (CompileFloatUnaryCall, CompileGLSLFloatUnaryCall, CompileGLSLFloatBinaryCall, CompileBitcastCall, MultiplyConstant, CompileBoolToScalarBoolCall) took FunctionType only to read functionType.ReturnType. That coupled the result-type decision to the intrinsic's declared return type, which is wrong for void-returning intrinsics like sincos and forced a "functionType with { ReturnType = ... }" workaround at the call site. Take SymbolType resultType directly so the result-type intent is local to each call site. CompileSincos can now pass the float type without synthesizing a function type. CompileInterlockedCall, CompileMemoryBarrierCall and CompileControlBarrierCall never used FunctionType at all -- drop the parameter. --- .../SDSL/AST/IntrinsicImplementations.cs | 160 +++++++++--------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs index 338cba3d7a..6b7bb2e605 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs +++ b/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs @@ -11,16 +11,16 @@ internal class IntrinsicImplementations : IntrinsicsDeclarations public static IntrinsicImplementations Instance { get; } = new(); // Bool - public override SpirvValue CompileAll(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType, x, Specification.Op.OpAll); - public override SpirvValue CompileAny(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType, x, Specification.Op.OpAny); + public override SpirvValue CompileAll(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType.ReturnType, x, Specification.Op.OpAll); + public override SpirvValue CompileAny(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBoolToScalarBoolCall(table, context, builder, functionType.ReturnType, x, Specification.Op.OpAny); // Cast - public override SpirvValue CompileAsfloat(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); - public override SpirvValue CompileAsint(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsfloat(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType.ReturnType, x); + public override SpirvValue CompileAsint(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType.ReturnType, x); public override SpirvValue CompileAsuint(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue? d = null, SpirvValue? x = null, SpirvValue? y = null, TextLocation location = default) { if (d == null && y == null) - return CompileBitcastCall(table, context, builder, functionType, x!.Value); + return CompileBitcastCall(table, context, builder, functionType.ReturnType, x!.Value); throw new NotImplementedException(); } @@ -54,40 +54,40 @@ public override SpirvValue CompileAsdouble(SymbolTable table, SpirvContext conte } throw new InvalidOperationException($"Unexpected type {inputType} for asdouble"); } - public override SpirvValue CompileAsfloat16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); - public override SpirvValue CompileAsint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); - public override SpirvValue CompileAsuint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType, x); + public override SpirvValue CompileAsfloat16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType.ReturnType, x); + public override SpirvValue CompileAsint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType.ReturnType, x); + public override SpirvValue CompileAsuint16(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileBitcastCall(table, context, builder, functionType.ReturnType, x); // Trigo - public override SpirvValue CompileSin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSin, x); - public override SpirvValue CompileSinh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSinh, x); - public override SpirvValue CompileAsin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAsin, x); - public override SpirvValue CompileCos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCos, x); - public override SpirvValue CompileCosh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCosh, x); - public override SpirvValue CompileAcos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAcos, x); - public override SpirvValue CompileTan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTan, x); - public override SpirvValue CompileTanh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTanh, x); - public override SpirvValue CompileAtan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAtan, x); - public override SpirvValue CompileAtan2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLAtan2, x, y); + public override SpirvValue CompileSin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLSin, x); + public override SpirvValue CompileSinh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLSinh, x); + public override SpirvValue CompileAsin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLAsin, x); + public override SpirvValue CompileCos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCos, x); + public override SpirvValue CompileCosh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCosh, x); + public override SpirvValue CompileAcos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLAcos, x); + public override SpirvValue CompileTan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLTan, x); + public override SpirvValue CompileTanh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLTanh, x); + public override SpirvValue CompileAtan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLAtan, x); + public override SpirvValue CompileAtan2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLAtan2, x, y); public override SpirvValue CompileSincos(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue s, SpirvValue c, TextLocation location = default) { // sincos(x, out s, out c): compute sin and cos separately, store to out params - var sinCosType = functionType with { ReturnType = context.ReverseTypes[x.TypeId] }; - var sinVal = CompileGLSLFloatUnaryCall(table, context, builder, sinCosType, Specification.GLSLOp.GLSLSin, x); - var cosVal = CompileGLSLFloatUnaryCall(table, context, builder, sinCosType, Specification.GLSLOp.GLSLCos, x); + var resultType = context.ReverseTypes[x.TypeId]; + var sinVal = CompileGLSLFloatUnaryCall(table, context, builder, resultType, Specification.GLSLOp.GLSLSin, x); + var cosVal = CompileGLSLFloatUnaryCall(table, context, builder, resultType, Specification.GLSLOp.GLSLCos, x); builder.Insert(new OpStore(s.Id, sinVal.Id, null, [])); builder.Insert(new OpStore(c.Id, cosVal.Id, null, [])); return new(); } // Derivatives - public override SpirvValue CompileDdx(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdx, x); - public override SpirvValue CompileDdx_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdxCoarse, x); - public override SpirvValue CompileDdx_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdxFine, x); - public override SpirvValue CompileDdy(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdy, x); - public override SpirvValue CompileDdy_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdyCoarse, x); - public override SpirvValue CompileDdy_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpDPdyFine, x); - public override SpirvValue CompileFwidth(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpFwidth, x); + public override SpirvValue CompileDdx(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdx, x); + public override SpirvValue CompileDdx_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdxCoarse, x); + public override SpirvValue CompileDdx_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdxFine, x); + public override SpirvValue CompileDdy(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdy, x); + public override SpirvValue CompileDdy_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdyCoarse, x); + public override SpirvValue CompileDdy_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdyFine, x); + public override SpirvValue CompileFwidth(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpFwidth, x); // Per component math public override SpirvValue CompileAbs(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) @@ -100,9 +100,9 @@ public override SpirvValue CompileAbs(SymbolTable table, SpirvContext context, S }; return new(instruction); } - public override SpirvValue CompileFloor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFloor, x); - public override SpirvValue CompileCeil(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCeil, x); - public override SpirvValue CompileTrunc(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLTrunc, x); + public override SpirvValue CompileFloor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLFloor, x); + public override SpirvValue CompileCeil(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCeil, x); + public override SpirvValue CompileTrunc(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLTrunc, x); public override SpirvValue CompileMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) { var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch @@ -139,15 +139,15 @@ public override SpirvValue CompileClamp(SymbolTable table, SpirvContext context, return new(instruction); } - public override SpirvValue CompileRadians(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLRadians, x); - public override SpirvValue CompileDegrees(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLDegrees, x); + public override SpirvValue CompileRadians(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLRadians, x); + public override SpirvValue CompileDegrees(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLDegrees, x); - public override SpirvValue CompileExp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLExp, x); - public override SpirvValue CompileExp2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLExp2, x); - public override SpirvValue CompileLog(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog, x); - public override SpirvValue CompileLog10(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => MultiplyConstant(table, context, builder, functionType, CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog2, x), (float)Math.Log10(2.0)); - public override SpirvValue CompileLog2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLLog2, x); - public override SpirvValue CompilePow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLPow, x, y); + public override SpirvValue CompileExp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLExp, x); + public override SpirvValue CompileExp2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLExp2, x); + public override SpirvValue CompileLog(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLLog, x); + public override SpirvValue CompileLog10(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => MultiplyConstant(table, context, builder, functionType.ReturnType, CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLLog2, x), (float)Math.Log10(2.0)); + public override SpirvValue CompileLog2(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLLog2, x); + public override SpirvValue CompilePow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, SpirvValue y, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLPow, x, y); // Vector math public override SpirvValue CompileDistance(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) @@ -160,7 +160,7 @@ public override SpirvValue CompileDot(SymbolTable table, SpirvContext context, S var instruction = builder.Insert(new OpDot(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileCross(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLCross, a, b); + public override SpirvValue CompileCross(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCross, a, b); public override SpirvValue CompileDeterminant(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { @@ -223,10 +223,10 @@ public override SpirvValue CompileFaceforward(SymbolTable table, SpirvContext co return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileRound(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLRound, x); - public override SpirvValue CompileRsqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLInverseSqrt, x); - public override SpirvValue CompileSqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLSqrt, x); - public override SpirvValue CompileStep(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue x, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLStep, a, x); + public override SpirvValue CompileRound(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLRound, x); + public override SpirvValue CompileRsqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLInverseSqrt, x); + public override SpirvValue CompileSqrt(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLSqrt, x); + public override SpirvValue CompileStep(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue x, TextLocation location = default) => CompileGLSLFloatBinaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLStep, a, x); public override SpirvValue CompileSaturate(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { // Ensure 0.0 amd 1.0 constants have same type as x @@ -272,7 +272,7 @@ public override SpirvValue CompileFmod(SymbolTable table, SpirvContext context, var instruction = builder.Insert(new OpFRem(context.GetOrRegister(functionType.ReturnType), context.Bound++, a.Id, b.Id)); return new(instruction.ResultId, instruction.ResultType); } - public override SpirvValue CompileFrac(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFract, x); + public override SpirvValue CompileFrac(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLFract, x); public override SpirvValue CompileRcp(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { @@ -288,11 +288,11 @@ public override SpirvValue CompileMad(SymbolTable table, SpirvContext context, S } // Float checks - public override SpirvValue CompileIsnan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpIsNan, x); - public override SpirvValue CompileIsinf(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpIsInf, x); + public override SpirvValue CompileIsnan(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpIsNan, x); + public override SpirvValue CompileIsinf(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpIsInf, x); // Bit operations - public override SpirvValue CompileCountbits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType, Specification.Op.OpBitCount, x); + public override SpirvValue CompileCountbits(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpBitCount, x); public override SpirvValue CompileFirstbithigh(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) { var op = context.ReverseTypes[x.TypeId].GetElementType() switch @@ -300,30 +300,30 @@ public override SpirvValue CompileFirstbithigh(SymbolTable table, SpirvContext c ScalarType { Type: Scalar.UInt } => Specification.GLSLOp.GLSLFindUMsb, _ => Specification.GLSLOp.GLSLFindSMsb, }; - return CompileGLSLFloatUnaryCall(table, context, builder, functionType, op, x); + return CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, op, x); } // Compute Barriers const Specification.MemorySemanticsMask AllMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask DeviceMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.ImageMemory | Specification.MemorySemanticsMask.UniformMemory | Specification.MemorySemanticsMask.AcquireRelease; const Specification.MemorySemanticsMask GroupMemoryBarrierMemorySemanticsMask = Specification.MemorySemanticsMask.WorkgroupMemory | Specification.MemorySemanticsMask.AcquireRelease; - public override SpirvValue CompileAllMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileAllMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, AllMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileDeviceMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, DeviceMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileGroupMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); - public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, functionType, GroupMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileAllMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileAllMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, AllMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileDeviceMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, DeviceMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrier(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileMemoryBarrierCall(table, context, builder, GroupMemoryBarrierMemorySemanticsMask); + public override SpirvValue CompileGroupMemoryBarrierWithGroupSync(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, TextLocation location = default) => CompileControlBarrierCall(table, context, builder, GroupMemoryBarrierMemorySemanticsMask); // Compute interlocked - public override SpirvValue CompileInterlockedAdd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Add, result, value, original); - public override SpirvValue CompileInterlockedMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Min, result, value, original); - public override SpirvValue CompileInterlockedMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Max, result, value, original); - public override SpirvValue CompileInterlockedAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.And, result, value, original); - public override SpirvValue CompileInterlockedOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Or, result, value, original); - public override SpirvValue CompileInterlockedXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Xor, result, value, original); - public override SpirvValue CompileInterlockedExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.Exchange, result, value, original); - public override SpirvValue CompileInterlockedCompareStore(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.CompareStore, result, value, null, compare); - public override SpirvValue CompileInterlockedCompareExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, functionType, InterlockedOp.CompareExchange, result, value, original, compare); + public override SpirvValue CompileInterlockedAdd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Add, result, value, original); + public override SpirvValue CompileInterlockedMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Min, result, value, original); + public override SpirvValue CompileInterlockedMax(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Max, result, value, original); + public override SpirvValue CompileInterlockedAnd(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.And, result, value, original); + public override SpirvValue CompileInterlockedOr(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Or, result, value, original); + public override SpirvValue CompileInterlockedXor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue? original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Xor, result, value, original); + public override SpirvValue CompileInterlockedExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.Exchange, result, value, original); + public override SpirvValue CompileInterlockedCompareStore(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.CompareStore, result, value, null, compare); + public override SpirvValue CompileInterlockedCompareExchange(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) => CompileInterlockedCall(table, context, builder, InterlockedOp.CompareExchange, result, value, original, compare); public override SpirvValue CompileInterlockedCompareStoreFloatBitwise(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, TextLocation location = default) => throw new NotImplementedException(); public override SpirvValue CompileInterlockedCompareExchangeFloatBitwise(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue result, SpirvValue compare, SpirvValue value, SpirvValue original, TextLocation location = default) => throw new NotImplementedException(); @@ -455,7 +455,7 @@ public override SpirvValue CompileF32tof16(SymbolTable table, SpirvContext conte } throw new InvalidOperationException($"Unexpected type {inputType} for f32tof16"); } - public override SpirvValue CompileFirstbitlow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType, Specification.GLSLOp.GLSLFindILsb, x); + public override SpirvValue CompileFirstbitlow(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLFindILsb, x); public override SpirvValue CompileFma(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, SpirvValue c, TextLocation location = default) { var instruction = builder.Insert(new GLSLFma(a.TypeId, context.Bound++, context.GetGLSL(), a.Id, b.Id, c.Id)); @@ -589,44 +589,44 @@ public override SpirvValue CompileTranspose(SymbolTable table, SpirvContext cont public override SpirvValue CompileTexCUBEproj(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue s, SpirvValue x, TextLocation location = default) => throw new NotImplementedException(); - public static SpirvValue CompileFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.Op op, SpirvValue x) + public static SpirvValue CompileFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, Specification.Op op, SpirvValue x) { - var instruction = builder.Insert(new OpFwidth(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpFwidth(context.GetOrRegister(resultType), context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileGLSLFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x) + public static SpirvValue CompileGLSLFloatUnaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, Specification.GLSLOp op, SpirvValue x) { - var instruction = builder.Insert(new GLSLExp(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)); + var instruction = builder.Insert(new GLSLExp(context.GetOrRegister(resultType), context.Bound++, context.GetGLSL(), x.Id)); // Adjust OpCode only since Exp/Exp2/Log/Log2 share the same operands instruction.InstructionMemory.Span[4] = (int)op; return new SpirvValue(instruction.ResultId, instruction.ResultType); } - public static SpirvValue MultiplyConstant(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue value, float multiplyConstant) + public static SpirvValue MultiplyConstant(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, SpirvValue value, float multiplyConstant) { var constant = context.CompileConstant(multiplyConstant); constant = builder.Convert(context, constant, context.ReverseTypes[value.TypeId]); - var instruction2 = builder.Insert(new OpFMul(context.GetOrRegister(functionType.ReturnType), context.Bound++, value.Id, constant.Id)); + var instruction2 = builder.Insert(new OpFMul(context.GetOrRegister(resultType), context.Bound++, value.Id, constant.Id)); return new SpirvValue(instruction2.ResultId, instruction2.ResultType); } - public static SpirvValue CompileGLSLFloatBinaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) + public static SpirvValue CompileGLSLFloatBinaryCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, Specification.GLSLOp op, SpirvValue x, SpirvValue y) { - var instruction = builder.Insert(new GLSLPow(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id, y.Id)); + var instruction = builder.Insert(new GLSLPow(context.GetOrRegister(resultType), context.Bound++, context.GetGLSL(), x.Id, y.Id)); // Adjust OpCode only since Pow/Atan2/etc. share the same operands instruction.InstructionMemory.Span[4] = (int)op; return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileBitcastCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x) + public static SpirvValue CompileBitcastCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, SpirvValue x) { - var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpBitcast(context.GetOrRegister(resultType), context.Bound++, x.Id)); return new(instruction.ResultId, instruction.ResultType); } - public static SpirvValue CompileInterlockedCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) + public static SpirvValue CompileInterlockedCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, InterlockedOp op, SpirvValue dest, SpirvValue value, SpirvValue? originalLocation = null, SpirvValue? compare = null) { var destType = context.ReverseTypes[dest.TypeId]; if (destType is not PointerType pointerType || pointerType.BaseType is not ScalarType { Type: Scalar.UInt or Scalar.Int } s) @@ -681,18 +681,18 @@ public static SpirvValue CompileInterlockedCall(SymbolTable table, SpirvContext return new(); } - public static SpirvValue CompileMemoryBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + public static SpirvValue CompileMemoryBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, Specification.MemorySemanticsMask memorySemanticsMask) { builder.Insert(new OpMemoryBarrier(context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } - public static SpirvValue CompileControlBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, Specification.MemorySemanticsMask memorySemanticsMask) + public static SpirvValue CompileControlBarrierCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, Specification.MemorySemanticsMask memorySemanticsMask) { builder.Insert(new OpControlBarrier(context.CompileConstant((int)Specification.Scope.Workgroup).Id, context.CompileConstant((int)Specification.Scope.Device).Id, context.CompileConstant((int)memorySemanticsMask).Id)); return new(); } - public static SpirvValue CompileBoolToScalarBoolCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, Specification.Op op) + public static SpirvValue CompileBoolToScalarBoolCall(SymbolTable table, SpirvContext context, SpirvBuilder builder, SymbolType resultType, SpirvValue x, Specification.Op op) { // We handle matrix specifically in this case (auto loop doesn't work since it's not per item) // So we simply run OpAny/OpAll on each column and then get a vector with all the bool to run through the normal path @@ -716,7 +716,7 @@ public static SpirvValue CompileBoolToScalarBoolCall(SymbolTable table, SpirvCon var parameterType = context.ReverseTypes[x.TypeId].WithElementType(ScalarType.Boolean); x = builder.Convert(context, x, parameterType); - var instruction = builder.Insert(new OpAny(context.GetOrRegister(functionType.ReturnType), context.Bound++, x.Id)); + var instruction = builder.Insert(new OpAny(context.GetOrRegister(resultType), context.Bound++, x.Id)); instruction.InstructionMemory.Span[0] = (int)(instruction.InstructionMemory.Span[0] & 0xFFFF0000) | (int)op; return new(instruction.ResultId, instruction.ResultType); } From 889f5b8a8b3c75d70471cd72211be90f143d645a Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 28 Apr 2026 22:46:16 +0900 Subject: [PATCH 1153/1182] sdk: auto-bootstrapped Stride.Local.props for per-dev build settings --- .gitignore | 3 +++ build/Stride.Android.sln | 1 + build/Stride.Runtime.sln | 1 + build/Stride.iOS.sln | 1 + build/Stride.sln | 2 ++ sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets | 16 ++++++++++++++++ .../Sdk/Stride.Local.props.template | 19 +++++++++++++++++++ .../Sdk/Stride.Platform.props | 17 +++++++++++++++++ 8 files changed, 60 insertions(+) create mode 100644 sources/sdk/Stride.Build.Sdk/Sdk/Stride.Local.props.template diff --git a/.gitignore b/.gitignore index ba22695add..9430de1181 100644 --- a/.gitignore +++ b/.gitignore @@ -160,3 +160,6 @@ fastlane/report.xml fastlane/screenshots *.user project.lock.json + +# Auto-generated local developer settings (Stride.Platform.props bootstrap) +/build/Stride.Local.props diff --git a/build/Stride.Android.sln b/build/Stride.Android.sln index fb07069452..ebf9057adf 100644 --- a/build/Stride.Android.sln +++ b/build/Stride.Android.sln @@ -35,6 +35,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targets.Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" ProjectSection(SolutionItems) = preProject Stride.build = Stride.build + Stride.Local.props = Stride.Local.props Stride.Build.props = Stride.Build.props Stride.Build.targets = Stride.Build.targets Stride.Core.Build.props = Stride.Core.Build.props diff --git a/build/Stride.Runtime.sln b/build/Stride.Runtime.sln index 8973d3ad2e..a545652c80 100644 --- a/build/Stride.Runtime.sln +++ b/build/Stride.Runtime.sln @@ -35,6 +35,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targets.Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" ProjectSection(SolutionItems) = preProject Stride.build = Stride.build + Stride.Local.props = Stride.Local.props Stride.Build.props = Stride.Build.props Stride.Build.targets = Stride.Build.targets Stride.Core.Build.props = Stride.Core.Build.props diff --git a/build/Stride.iOS.sln b/build/Stride.iOS.sln index 655dc39f22..226fec6f56 100644 --- a/build/Stride.iOS.sln +++ b/build/Stride.iOS.sln @@ -35,6 +35,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targets.Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" ProjectSection(SolutionItems) = preProject Stride.build = Stride.build + Stride.Local.props = Stride.Local.props Stride.Build.props = Stride.Build.props Stride.Build.targets = Stride.Build.targets Stride.Core.Build.props = Stride.Core.Build.props diff --git a/build/Stride.sln b/build/Stride.sln index 0e637d6de7..7490e7e0fe 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -49,6 +49,7 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Build", "00-Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" ProjectSection(SolutionItems) = preProject Stride.build = Stride.build + Stride.Local.props = Stride.Local.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "30-CoreDesign", "30-CoreDesign", "{25F10A0B-7259-404C-86BE-FD2363C92F72}" @@ -334,6 +335,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Build.Sdk", "Stride. ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Frameworks.targets = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Frameworks.targets ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Graphics.props = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Graphics.props ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.GraphicsApi.InnerBuild.targets = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.GraphicsApi.InnerBuild.targets + ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Local.props.template = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Local.props.template ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.NativeBuildMode.props = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.NativeBuildMode.props ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.PackageInfo.targets = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.PackageInfo.targets ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Platform.props = ..\sources\sdk\Stride.Build.Sdk\Sdk\Stride.Platform.props diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets index 362b882668..eac6e76fb4 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets @@ -243,6 +243,22 @@ + + + + + + + + + diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Local.props.template b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Local.props.template new file mode 100644 index 0000000000..b48ee0ff72 --- /dev/null +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Local.props.template @@ -0,0 +1,19 @@ + + + + + Windows + false + + + + + Direct3D11 + + diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Platform.props b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Platform.props index 3cb4179b46..4e6f9add3d 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Platform.props +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.Platform.props @@ -46,6 +46,23 @@ iOS + + + + + + <_StrideRepoRoot>$([MSBuild]::GetDirectoryNameOfFileAbove('$(MSBuildThisFileDirectory)', 'crowdin.yml')) + <_StrideLocalProps Condition="'$(_StrideRepoRoot)' != ''">$(_StrideRepoRoot)\build\Stride.Local.props + <_StrideLocalPropsTemplate>$(MSBuildThisFileDirectory)Stride.Local.props.template + + + + From 725ce76dbcdc64a6a7408a2546f44eb23fb23ed0 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 28 Apr 2026 23:16:38 +0900 Subject: [PATCH 1154/1182] build: remove orphaned mobile .sln files and UnitTests build scaffolding --- README.md | 2 +- build/Stride.Android.sln | 288 -------------- build/Stride.Build.props | 14 - build/Stride.Runtime.sln | 9 - build/Stride.UnitTests.Build.targets | 10 - build/Stride.iOS.sln | 486 ----------------------- sources/targets/Stride.UnitTests.props | 31 -- sources/targets/Stride.UnitTests.targets | 118 ------ 8 files changed, 1 insertion(+), 957 deletions(-) delete mode 100644 build/Stride.Android.sln delete mode 100644 build/Stride.Build.props delete mode 100644 build/Stride.UnitTests.Build.targets delete mode 100644 build/Stride.iOS.sln delete mode 100644 sources/targets/Stride.UnitTests.props delete mode 100644 sources/targets/Stride.UnitTests.targets diff --git a/README.md b/README.md index 074a4677ef..c239e28fca 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ Our [Roadmap](https://doc.stride3d.net/latest/en/contributors/roadmap.html) comm 2. **Open the solution:** - Open `\build\Stride.sln` with Visual Studio 2026. - Build the `Stride.GameStudio` project in the `60-Editor` solution folder (it should be the default startup project) or run it directly from Visual Studio's toolbar. - - _Optionally_, open and build `Stride.Android.sln`, `Stride.iOS.sln`, etc. + - For mobile work, open `Stride.Android.slnf` or `Stride.iOS.slnf` (filtered subsets of `Stride.sln`). > [!WARNING] > **Do NOT use GitHub -> Code -> Download ZIP** option, as this won't include the LFS files. diff --git a/build/Stride.Android.sln b/build/Stride.Android.sln deleted file mode 100644 index ebf9057adf..0000000000 --- a/build/Stride.Android.sln +++ /dev/null @@ -1,288 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.0.11205.157 -MinimumVisualStudioVersion = 18.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "10-CoreRuntime", "10-CoreRuntime", "{2E93E2B5-4500-4E47-9B65-E705218AB578}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "20-StrideRuntime", "20-StrideRuntime", "{4C142567-C42B-40F5-B092-798882190209}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Private", "00-Targets.Private", "{97978864-95DD-43A6-9159-AA1C881BE99F}" - ProjectSection(SolutionItems) = preProject - ..\sources\native\Stride.Native.targets = ..\sources\native\Stride.Native.targets - ..\sources\targets\Stride.Core.PostSettings.Dependencies.targets = ..\sources\targets\Stride.Core.PostSettings.Dependencies.targets - ..\sources\targets\Stride.Core.props = ..\sources\targets\Stride.Core.props - ..\sources\targets\Stride.Core.targets = ..\sources\targets\Stride.Core.targets - ..\sources\targets\Stride.GraphicsApi.Dev.targets = ..\sources\targets\Stride.GraphicsApi.Dev.targets - ..\sources\targets\Stride.GraphicsApi.PackageReference.targets = ..\sources\targets\Stride.GraphicsApi.PackageReference.targets - ..\sources\targets\Stride.PackageVersion.targets = ..\sources\targets\Stride.PackageVersion.targets - ..\sources\targets\Stride.props = ..\sources\targets\Stride.props - ..\sources\targets\Stride.targets = ..\sources\targets\Stride.targets - ..\sources\targets\Stride.UnitTests.CrossTargeting.targets = ..\sources\targets\Stride.UnitTests.CrossTargeting.targets - ..\sources\targets\Stride.UnitTests.DisableBuild.targets = ..\sources\targets\Stride.UnitTests.DisableBuild.targets - ..\sources\targets\Stride.UnitTests.props = ..\sources\targets\Stride.UnitTests.props - ..\sources\targets\Stride.UnitTests.targets = ..\sources\targets\Stride.UnitTests.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "80-Shaders", "80-Shaders", "{10D145AF-C8AE-428F-A80F-CA1B591D0DB2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Config", "00-Config", "{7662CECF-2A3D-4DBA-AB3D-77FD8536E7A3}" - ProjectSection(SolutionItems) = preProject - ..\sources\shared\SharedAssemblyInfo.cs = ..\sources\shared\SharedAssemblyInfo.cs - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shared", "Stride.Shared", "{1AC70118-C90F-4EC6-9D8B-C628BDF900F7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targets.Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" - ProjectSection(SolutionItems) = preProject - Stride.build = Stride.build - Stride.Local.props = Stride.Local.props - Stride.Build.props = Stride.Build.props - Stride.Build.targets = Stride.Build.targets - Stride.Core.Build.props = Stride.Core.Build.props - Stride.Core.Build.targets = Stride.Core.Build.targets - Stride.UnitTests.Build.targets = Stride.UnitTests.Build.targets - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Engine", "..\sources\engine\Stride.Engine\Stride.Engine.csproj", "{C121A566-555E-42B9-9B0A-1696529A9088}" - ProjectSection(ProjectDependencies) = postProject - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} = {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Graphics", "..\sources\engine\Stride.Graphics\Stride.Graphics.csproj", "{FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Shaders", "..\sources\shaders\Stride.Core.Shaders\Stride.Core.Shaders.csproj", "{F2D52EDB-BC17-4243-B06D-33CD20F87A7F}" - ProjectSection(ProjectDependencies) = postProject - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {5210FB81-B807-49BB-AF0D-31FB6A83A572} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Irony", "..\sources\shaders\Irony\Irony.csproj", "{D81F5C91-D7DB-46E5-BC99-49488FB6814C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Games", "..\sources\engine\Stride.Games\Stride.Games.csproj", "{42780CBD-3FE7-48E3-BD5B-59945EA20137}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core", "..\sources\core\Stride.Core\Stride.Core.csproj", "{0E916AB7-5A6C-4820-8AB1-AA492FE66D68}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Mathematics", "..\sources\core\Stride.Core.Mathematics\Stride.Core.Mathematics.csproj", "{1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}" - ProjectSection(ProjectDependencies) = postProject - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {5210FB81-B807-49BB-AF0D-31FB6A83A572} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Serialization", "..\sources\core\Stride.Core.Serialization\Stride.Core.Serialization.csproj", "{5210FB81-B807-49BB-AF0D-31FB6A83A572}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.MicroThreading", "..\sources\core\Stride.Core.MicroThreading\Stride.Core.MicroThreading.csproj", "{1320F627-EE43-4115-8E89-19D1753E51F2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\sources\core\Stride.Core.IO\Stride.Core.IO.csproj", "{1DE01410-22C9-489B-9796-1ADDAB1F64E5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.UI", "..\sources\engine\Stride.UI\Stride.UI.csproj", "{BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}" - ProjectSection(ProjectDependencies) = postProject - {C121A566-555E-42B9-9B0A-1696529A9088} = {C121A566-555E-42B9-9B0A-1696529A9088} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Physics", "..\sources\engine\Stride.Physics\Stride.Physics.csproj", "{DD592516-B341-40FE-9100-1B0FA784A060}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.SpriteStudio.Runtime", "..\sources\engine\Stride.SpriteStudio.Runtime\Stride.SpriteStudio.Runtime.csproj", "{9BC63BEC-F305-451D-BB31-262938EA964D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Particles", "..\sources\engine\Stride.Particles\Stride.Particles.csproj", "{F32FDA80-B6DD-47A8-8681-437E2C0D3F31}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Native", "..\sources\engine\Stride.Native\Stride.Native.csproj", "{1DBBC150-F085-43EF-B41D-27C72D133770}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Stride.Refactor", "..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.shproj", "{B33E576F-2279-4BFC-A438-D9B84343B56B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.VirtualReality", "..\sources\engine\Stride.VirtualReality\Stride.VirtualReality.csproj", "{53782603-3096-40C2-ABD3-F8F311BAE4BE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Navigation", "..\sources\engine\Stride.Navigation\Stride.Navigation.csproj", "{FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Localization", "00-Localization", "{FC791F56-C1F1-4C41-A193-868D8197F8E2}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\Stride.Assets.Presentation.pot = ..\sources\localization\Stride.Assets.Presentation.pot - ..\sources\localization\Stride.Core.Assets.Editor.pot = ..\sources\localization\Stride.Core.Assets.Editor.pot - ..\sources\localization\Stride.Core.Presentation.pot = ..\sources\localization\Stride.Core.Presentation.pot - ..\sources\localization\Stride.GameStudio.pot = ..\sources\localization\Stride.GameStudio.pot - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ja", "ja", "{B4EABB0D-E495-405C-B7B1-E2A7A3711AF5}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\ja\Stride.Assets.Presentation.ja.po = ..\sources\localization\ja\Stride.Assets.Presentation.ja.po - ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po = ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po - ..\sources\localization\ja\Stride.Core.Presentation.ja.po = ..\sources\localization\ja\Stride.Core.Presentation.ja.po - ..\sources\localization\ja\Stride.GameStudio.ja.po = ..\sources\localization\ja\Stride.GameStudio.ja.po - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Video", "..\sources\engine\Stride.Video\Stride.Video.csproj", "{DA355C86-866F-4843-9B4D-63A173C750FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fr", "fr", "{62E9A8E4-79AF-4081-84D5-FEC5A0B28598}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\fr\Stride.Assets.Presentation.fr.po = ..\sources\localization\fr\Stride.Assets.Presentation.fr.po - ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po = ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po - ..\sources\localization\fr\Stride.Core.Presentation.fr.po = ..\sources\localization\fr\Stride.Core.Presentation.fr.po - ..\sources\localization\fr\Stride.GameStudio.fr.po = ..\sources\localization\fr\Stride.GameStudio.fr.po - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Rendering", "..\sources\engine\Stride.Rendering\Stride.Rendering.csproj", "{AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{b33e576f-2279-4bfc-a438-d9b84343b56b}*SharedItemsImports = 13 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{c121a566-555e-42b9-9b0a-1696529a9088}*SharedItemsImports = 5 - ..\sources\shared\Stride.Core.ShellHelper\Stride.Core.ShellHelper.projitems*{e8b3553f-a79f-4e50-b75b-acee771c320c}*SharedItemsImports = 5 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{fb06c76a-6bb7-40be-9afa-fec13b045fb5}*SharedItemsImports = 5 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Android = Debug|Android - Release|Android = Release|Android - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|Android.ActiveCfg = Debug|Any CPU - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|Android.Build.0 = Debug|Any CPU - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|Android.ActiveCfg = Release|Any CPU - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|Android.Build.0 = Release|Any CPU - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|Android.ActiveCfg = Debug|Any CPU - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|Android.Build.0 = Debug|Any CPU - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|Android.ActiveCfg = Release|Any CPU - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|Android.Build.0 = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Android.ActiveCfg = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Android.Build.0 = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|Android.Deploy.0 = Debug|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Android.ActiveCfg = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Android.Build.0 = Release|Any CPU - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|Android.Deploy.0 = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Android.ActiveCfg = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Android.Build.0 = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|Android.Deploy.0 = Debug|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Android.ActiveCfg = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Android.Build.0 = Release|Any CPU - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|Android.Deploy.0 = Release|Any CPU - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|Android.ActiveCfg = Debug|Any CPU - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|Android.Build.0 = Debug|Any CPU - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|Android.ActiveCfg = Release|Any CPU - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|Android.Build.0 = Release|Any CPU - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|Android.ActiveCfg = Debug|Any CPU - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|Android.Build.0 = Debug|Any CPU - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|Android.ActiveCfg = Release|Any CPU - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|Android.Build.0 = Release|Any CPU - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|Android.ActiveCfg = Debug|Any CPU - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|Android.Build.0 = Debug|Any CPU - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|Android.ActiveCfg = Release|Any CPU - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|Android.Build.0 = Release|Any CPU - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|Android.ActiveCfg = Debug|Any CPU - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|Android.Build.0 = Debug|Any CPU - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|Android.ActiveCfg = Release|Any CPU - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|Android.Build.0 = Release|Any CPU - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|Android.ActiveCfg = Debug|Any CPU - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|Android.Build.0 = Debug|Any CPU - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|Android.ActiveCfg = Release|Any CPU - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|Android.Build.0 = Release|Any CPU - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|Android.ActiveCfg = Debug|Any CPU - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|Android.Build.0 = Debug|Any CPU - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|Android.ActiveCfg = Release|Any CPU - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|Android.Build.0 = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Android.ActiveCfg = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|Android.Build.0 = Debug|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Android.ActiveCfg = Release|Any CPU - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|Android.Build.0 = Release|Any CPU - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|Android.ActiveCfg = Debug|Any CPU - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|Android.Build.0 = Debug|Any CPU - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|Android.ActiveCfg = Release|Any CPU - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|Android.Build.0 = Release|Any CPU - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|Android.ActiveCfg = Debug|Any CPU - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|Android.Build.0 = Debug|Any CPU - {DE042125-C270-4D1D-9270-0759C167567A}.Release|Android.ActiveCfg = Release|Any CPU - {DE042125-C270-4D1D-9270-0759C167567A}.Release|Android.Build.0 = Release|Any CPU - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|Android.ActiveCfg = Debug|Any CPU - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|Android.Build.0 = Debug|Any CPU - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|Android.ActiveCfg = Release|Any CPU - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|Android.Build.0 = Release|Any CPU - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|Android.ActiveCfg = Debug|Any CPU - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|Android.Build.0 = Debug|Any CPU - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|Android.ActiveCfg = Release|Any CPU - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|Android.Build.0 = Release|Any CPU - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|Android.ActiveCfg = Debug|Any CPU - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|Android.Build.0 = Debug|Any CPU - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|Android.ActiveCfg = Release|Any CPU - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|Android.Build.0 = Release|Any CPU - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|Android.ActiveCfg = Debug|Any CPU - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|Android.Build.0 = Debug|Any CPU - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|Android.ActiveCfg = Release|Any CPU - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|Android.Build.0 = Release|Any CPU - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|Android.ActiveCfg = Debug|Any CPU - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|Android.Build.0 = Debug|Any CPU - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|Android.ActiveCfg = Release|Any CPU - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|Android.Build.0 = Release|Any CPU - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|Android.ActiveCfg = Debug|Any CPU - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|Android.Build.0 = Debug|Any CPU - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|Android.ActiveCfg = Release|Any CPU - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|Android.Build.0 = Release|Any CPU - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|Android.ActiveCfg = Debug|Any CPU - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|Android.Build.0 = Debug|Any CPU - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|Android.ActiveCfg = Release|Any CPU - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|Android.Build.0 = Release|Any CPU - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|Android.ActiveCfg = Debug|Any CPU - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|Android.Build.0 = Debug|Any CPU - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|Android.ActiveCfg = Release|Any CPU - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|Android.Build.0 = Release|Any CPU - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|Android.ActiveCfg = Debug|Any CPU - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|Android.Build.0 = Debug|Any CPU - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|Android.ActiveCfg = Release|Any CPU - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|Android.Build.0 = Release|Any CPU - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|Android.ActiveCfg = Debug|Any CPU - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|Android.Build.0 = Debug|Any CPU - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|Android.ActiveCfg = Release|Any CPU - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|Android.Build.0 = Release|Any CPU - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|Android.ActiveCfg = Debug|Any CPU - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|Android.Build.0 = Debug|Any CPU - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|Android.ActiveCfg = Release|Any CPU - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|Android.Build.0 = Release|Any CPU - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|Android.ActiveCfg = Debug|Any CPU - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|Android.Build.0 = Debug|Any CPU - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|Android.ActiveCfg = Release|Any CPU - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|Android.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1AC70118-C90F-4EC6-9D8B-C628BDF900F7} = {4C142567-C42B-40F5-B092-798882190209} - {C121A566-555E-42B9-9B0A-1696529A9088} = {4C142567-C42B-40F5-B092-798882190209} - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5} = {4C142567-C42B-40F5-B092-798882190209} - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} - {D81F5C91-D7DB-46E5-BC99-49488FB6814C} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} - {42780CBD-3FE7-48E3-BD5B-59945EA20137} = {4C142567-C42B-40F5-B092-798882190209} - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1320F627-EE43-4115-8E89-19D1753E51F2} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1DE01410-22C9-489B-9796-1ADDAB1F64E5} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {14A47447-2A24-4ECD-B24D-6571499DCD4C} = {4C142567-C42B-40F5-B092-798882190209} - {273BDD15-7392-4078-91F0-AF23594A3D7B} = {4C142567-C42B-40F5-B092-798882190209} - {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} - {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} - {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {4C142567-C42B-40F5-B092-798882190209} - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E} = {4C142567-C42B-40F5-B092-798882190209} - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3} = {4C142567-C42B-40F5-B092-798882190209} - {DD592516-B341-40FE-9100-1B0FA784A060} = {4C142567-C42B-40F5-B092-798882190209} - {9BC63BEC-F305-451D-BB31-262938EA964D} = {4C142567-C42B-40F5-B092-798882190209} - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31} = {4C142567-C42B-40F5-B092-798882190209} - {1DBBC150-F085-43EF-B41D-27C72D133770} = {4C142567-C42B-40F5-B092-798882190209} - {B33E576F-2279-4BFC-A438-D9B84343B56B} = {1AC70118-C90F-4EC6-9D8B-C628BDF900F7} - {53782603-3096-40C2-ABD3-F8F311BAE4BE} = {4C142567-C42B-40F5-B092-798882190209} - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088} = {4C142567-C42B-40F5-B092-798882190209} - {B4EABB0D-E495-405C-B7B1-E2A7A3711AF5} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} - {DA355C86-866F-4843-9B4D-63A173C750FB} = {4C142567-C42B-40F5-B092-798882190209} - {62E9A8E4-79AF-4081-84D5-FEC5A0B28598} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4} = {4C142567-C42B-40F5-B092-798882190209} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {FF877973-604D-4EA7-B5F5-A129961F9EF2} - EndGlobalSection -EndGlobal diff --git a/build/Stride.Build.props b/build/Stride.Build.props deleted file mode 100644 index 75f98464c0..0000000000 --- a/build/Stride.Build.props +++ /dev/null @@ -1,14 +0,0 @@ - - - - Stride - Windows - Linux - - - Direct3D11 - - - Vulkan - - diff --git a/build/Stride.Runtime.sln b/build/Stride.Runtime.sln index a545652c80..4b38861065 100644 --- a/build/Stride.Runtime.sln +++ b/build/Stride.Runtime.sln @@ -17,10 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Private", "00-Ta ..\sources\targets\Stride.PackageVersion.targets = ..\sources\targets\Stride.PackageVersion.targets ..\sources\targets\Stride.props = ..\sources\targets\Stride.props ..\sources\targets\Stride.targets = ..\sources\targets\Stride.targets - ..\sources\targets\Stride.UnitTests.CrossTargeting.targets = ..\sources\targets\Stride.UnitTests.CrossTargeting.targets - ..\sources\targets\Stride.UnitTests.DisableBuild.targets = ..\sources\targets\Stride.UnitTests.DisableBuild.targets - ..\sources\targets\Stride.UnitTests.props = ..\sources\targets\Stride.UnitTests.props - ..\sources\targets\Stride.UnitTests.targets = ..\sources\targets\Stride.UnitTests.targets EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "80-Shaders", "80-Shaders", "{10D145AF-C8AE-428F-A80F-CA1B591D0DB2}" @@ -36,11 +32,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targ ProjectSection(SolutionItems) = preProject Stride.build = Stride.build Stride.Local.props = Stride.Local.props - Stride.Build.props = Stride.Build.props - Stride.Build.targets = Stride.Build.targets - Stride.Core.Build.props = Stride.Core.Build.props - Stride.Core.Build.targets = Stride.Core.Build.targets - Stride.UnitTests.Build.targets = Stride.UnitTests.Build.targets EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Engine", "..\sources\engine\Stride.Engine\Stride.Engine.csproj", "{C121A566-555E-42B9-9B0A-1696529A9088}" diff --git a/build/Stride.UnitTests.Build.targets b/build/Stride.UnitTests.Build.targets deleted file mode 100644 index 596166fd6e..0000000000 --- a/build/Stride.UnitTests.Build.targets +++ /dev/null @@ -1,10 +0,0 @@ - - - - Vulkan - - - Direct3D11 - - - diff --git a/build/Stride.iOS.sln b/build/Stride.iOS.sln deleted file mode 100644 index 226fec6f56..0000000000 --- a/build/Stride.iOS.sln +++ /dev/null @@ -1,486 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.0.11205.157 -MinimumVisualStudioVersion = 18.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "10-CoreRuntime", "10-CoreRuntime", "{2E93E2B5-4500-4E47-9B65-E705218AB578}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "20-StrideRuntime", "20-StrideRuntime", "{4C142567-C42B-40F5-B092-798882190209}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Private", "00-Targets.Private", "{97978864-95DD-43A6-9159-AA1C881BE99F}" - ProjectSection(SolutionItems) = preProject - ..\sources\native\Stride.Native.targets = ..\sources\native\Stride.Native.targets - ..\sources\targets\Stride.Core.PostSettings.Dependencies.targets = ..\sources\targets\Stride.Core.PostSettings.Dependencies.targets - ..\sources\targets\Stride.Core.props = ..\sources\targets\Stride.Core.props - ..\sources\targets\Stride.Core.targets = ..\sources\targets\Stride.Core.targets - ..\sources\targets\Stride.GraphicsApi.Dev.targets = ..\sources\targets\Stride.GraphicsApi.Dev.targets - ..\sources\targets\Stride.GraphicsApi.PackageReference.targets = ..\sources\targets\Stride.GraphicsApi.PackageReference.targets - ..\sources\targets\Stride.PackageVersion.targets = ..\sources\targets\Stride.PackageVersion.targets - ..\sources\targets\Stride.props = ..\sources\targets\Stride.props - ..\sources\targets\Stride.targets = ..\sources\targets\Stride.targets - ..\sources\targets\Stride.UnitTests.CrossTargeting.targets = ..\sources\targets\Stride.UnitTests.CrossTargeting.targets - ..\sources\targets\Stride.UnitTests.DisableBuild.targets = ..\sources\targets\Stride.UnitTests.DisableBuild.targets - ..\sources\targets\Stride.UnitTests.props = ..\sources\targets\Stride.UnitTests.props - ..\sources\targets\Stride.UnitTests.targets = ..\sources\targets\Stride.UnitTests.targets - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "80-Shaders", "80-Shaders", "{10D145AF-C8AE-428F-A80F-CA1B591D0DB2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Config", "00-Config", "{7662CECF-2A3D-4DBA-AB3D-77FD8536E7A3}" - ProjectSection(SolutionItems) = preProject - ..\sources\shared\SharedAssemblyInfo.cs = ..\sources\shared\SharedAssemblyInfo.cs - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Stride.Shared", "Stride.Shared", "{1AC70118-C90F-4EC6-9D8B-C628BDF900F7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Targets.Build", "00-Targets.Build", "{0B81090E-4066-4723-A658-8AEDBEADE619}" - ProjectSection(SolutionItems) = preProject - Stride.build = Stride.build - Stride.Local.props = Stride.Local.props - Stride.Build.props = Stride.Build.props - Stride.Build.targets = Stride.Build.targets - Stride.Core.Build.props = Stride.Core.Build.props - Stride.Core.Build.targets = Stride.Core.Build.targets - Stride.UnitTests.Build.targets = Stride.UnitTests.Build.targets - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Engine", "..\sources\engine\Stride.Engine\Stride.Engine.csproj", "{C121A566-555E-42B9-9B0A-1696529A9088}" - ProjectSection(ProjectDependencies) = postProject - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} = {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Graphics", "..\sources\engine\Stride.Graphics\Stride.Graphics.csproj", "{FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Shaders", "..\sources\shaders\Stride.Core.Shaders\Stride.Core.Shaders.csproj", "{F2D52EDB-BC17-4243-B06D-33CD20F87A7F}" - ProjectSection(ProjectDependencies) = postProject - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {5210FB81-B807-49BB-AF0D-31FB6A83A572} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Irony", "..\sources\shaders\Irony\Irony.csproj", "{D81F5C91-D7DB-46E5-BC99-49488FB6814C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Games", "..\sources\engine\Stride.Games\Stride.Games.csproj", "{42780CBD-3FE7-48E3-BD5B-59945EA20137}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core", "..\sources\core\Stride.Core\Stride.Core.csproj", "{0E916AB7-5A6C-4820-8AB1-AA492FE66D68}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Mathematics", "..\sources\core\Stride.Core.Mathematics\Stride.Core.Mathematics.csproj", "{1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}" - ProjectSection(ProjectDependencies) = postProject - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {5210FB81-B807-49BB-AF0D-31FB6A83A572} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.Serialization", "..\sources\core\Stride.Core.Serialization\Stride.Core.Serialization.csproj", "{5210FB81-B807-49BB-AF0D-31FB6A83A572}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.MicroThreading", "..\sources\core\Stride.Core.MicroThreading\Stride.Core.MicroThreading.csproj", "{1320F627-EE43-4115-8E89-19D1753E51F2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\sources\core\Stride.Core.IO\Stride.Core.IO.csproj", "{1DE01410-22C9-489B-9796-1ADDAB1F64E5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Parser", "..\sources\engine\Stride.Shaders.Parser\Stride.Shaders.Parser.csproj", "{14A47447-2A24-4ECD-B24D-6571499DCD4C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Compiler", "..\sources\shaders\Stride.Shaders.Compilers\Stride.Shaders.Compilers.csproj", "{E8B3553F-A79F-4E50-B75B-ACEE771C320C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Input", "..\sources\engine\Stride.Input\Stride.Input.csproj", "{84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.UI", "..\sources\engine\Stride.UI\Stride.UI.csproj", "{BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}" - ProjectSection(ProjectDependencies) = postProject - {C121A566-555E-42B9-9B0A-1696529A9088} = {C121A566-555E-42B9-9B0A-1696529A9088} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Physics", "..\sources\engine\Stride.Physics\Stride.Physics.csproj", "{DD592516-B341-40FE-9100-1B0FA784A060}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.SpriteStudio.Runtime", "..\sources\engine\Stride.SpriteStudio.Runtime\Stride.SpriteStudio.Runtime.csproj", "{9BC63BEC-F305-451D-BB31-262938EA964D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Particles", "..\sources\engine\Stride.Particles\Stride.Particles.csproj", "{F32FDA80-B6DD-47A8-8681-437E2C0D3F31}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Native", "..\sources\engine\Stride.Native\Stride.Native.csproj", "{1DBBC150-F085-43EF-B41D-27C72D133770}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Stride.Refactor", "..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.shproj", "{B33E576F-2279-4BFC-A438-D9B84343B56B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.VirtualReality", "..\sources\engine\Stride.VirtualReality\Stride.VirtualReality.csproj", "{53782603-3096-40C2-ABD3-F8F311BAE4BE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Navigation", "..\sources\engine\Stride.Navigation\Stride.Navigation.csproj", "{FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00-Localization", "00-Localization", "{FC791F56-C1F1-4C41-A193-868D8197F8E2}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\Stride.Assets.Presentation.pot = ..\sources\localization\Stride.Assets.Presentation.pot - ..\sources\localization\Stride.Core.Assets.Editor.pot = ..\sources\localization\Stride.Core.Assets.Editor.pot - ..\sources\localization\Stride.Core.Presentation.pot = ..\sources\localization\Stride.Core.Presentation.pot - ..\sources\localization\Stride.GameStudio.pot = ..\sources\localization\Stride.GameStudio.pot - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ja", "ja", "{B4EABB0D-E495-405C-B7B1-E2A7A3711AF5}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\ja\Stride.Assets.Presentation.ja.po = ..\sources\localization\ja\Stride.Assets.Presentation.ja.po - ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po = ..\sources\localization\ja\Stride.Core.Assets.Editor.ja.po - ..\sources\localization\ja\Stride.Core.Presentation.ja.po = ..\sources\localization\ja\Stride.Core.Presentation.ja.po - ..\sources\localization\ja\Stride.GameStudio.ja.po = ..\sources\localization\ja\Stride.GameStudio.ja.po - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Video", "..\sources\engine\Stride.Video\Stride.Video.csproj", "{DA355C86-866F-4843-9B4D-63A173C750FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "fr", "fr", "{62E9A8E4-79AF-4081-84D5-FEC5A0B28598}" - ProjectSection(SolutionItems) = preProject - ..\sources\localization\fr\Stride.Assets.Presentation.fr.po = ..\sources\localization\fr\Stride.Assets.Presentation.fr.po - ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po = ..\sources\localization\fr\Stride.Core.Assets.Editor.fr.po - ..\sources\localization\fr\Stride.Core.Presentation.fr.po = ..\sources\localization\fr\Stride.Core.Presentation.fr.po - ..\sources\localization\fr\Stride.GameStudio.fr.po = ..\sources\localization\fr\Stride.GameStudio.fr.po - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Rendering", "..\sources\engine\Stride.Rendering\Stride.Rendering.csproj", "{AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}" -EndProject -Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{b33e576f-2279-4bfc-a438-d9b84343b56b}*SharedItemsImports = 13 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{c121a566-555e-42b9-9b0a-1696529a9088}*SharedItemsImports = 4 - ..\sources\shared\Stride.Core.ShellHelper\Stride.Core.ShellHelper.projitems*{e8b3553f-a79f-4e50-b75b-acee771c320c}*SharedItemsImports = 4 - ..\sources\engine\Stride.Shared\Refactor\Stride.Refactor.projitems*{fb06c76a-6bb7-40be-9afa-fec13b045fb5}*SharedItemsImports = 4 - EndGlobalSection - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|iPhone = Debug|iPhone - Debug|iPhoneSimulator = Debug|iPhoneSimulator - Release|iPhone = Release|iPhone - Release|iPhoneSimulator = Release|iPhoneSimulator - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhone.ActiveCfg = Debug|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhone.Build.0 = Debug|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhone.Deploy.0 = Debug|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {C121A566-555E-42B9-9B0A-1696529A9088}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhone.ActiveCfg = Release|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhone.Build.0 = Release|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhone.Deploy.0 = Release|iPhone - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {C121A566-555E-42B9-9B0A-1696529A9088}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhone.ActiveCfg = Debug|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhone.Build.0 = Debug|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhone.Deploy.0 = Debug|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhone.ActiveCfg = Release|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhone.Build.0 = Release|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhone.Deploy.0 = Release|iPhone - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhone.ActiveCfg = Debug|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhone.Build.0 = Debug|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhone.Deploy.0 = Debug|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhone.ActiveCfg = Release|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhone.Build.0 = Release|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhone.Deploy.0 = Release|iPhone - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhone.ActiveCfg = Debug|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhone.Build.0 = Debug|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhone.Deploy.0 = Debug|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhone.ActiveCfg = Release|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhone.Build.0 = Release|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhone.Deploy.0 = Release|iPhone - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {D81F5C91-D7DB-46E5-BC99-49488FB6814C}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhone.ActiveCfg = Debug|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhone.Build.0 = Debug|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhone.Deploy.0 = Debug|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhone.ActiveCfg = Release|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhone.Build.0 = Release|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhone.Deploy.0 = Release|iPhone - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {42780CBD-3FE7-48E3-BD5B-59945EA20137}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhone.ActiveCfg = Debug|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhone.Build.0 = Debug|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhone.Deploy.0 = Debug|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhone.ActiveCfg = Release|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhone.Build.0 = Release|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhone.Deploy.0 = Release|iPhone - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhone.ActiveCfg = Debug|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhone.Build.0 = Debug|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhone.Deploy.0 = Debug|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhone.ActiveCfg = Release|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhone.Build.0 = Release|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhone.Deploy.0 = Release|iPhone - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhone.ActiveCfg = Debug|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhone.Build.0 = Debug|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhone.Deploy.0 = Debug|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhone.ActiveCfg = Release|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhone.Build.0 = Release|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhone.Deploy.0 = Release|iPhone - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {5210FB81-B807-49BB-AF0D-31FB6A83A572}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhone.ActiveCfg = Debug|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhone.Build.0 = Debug|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhone.Deploy.0 = Debug|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhone.ActiveCfg = Release|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhone.Build.0 = Release|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhone.Deploy.0 = Release|iPhone - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {1320F627-EE43-4115-8E89-19D1753E51F2}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhone.ActiveCfg = Debug|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhone.Build.0 = Debug|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhone.Deploy.0 = Debug|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhone.ActiveCfg = Release|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhone.Build.0 = Release|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhone.Deploy.0 = Release|iPhone - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {1DE01410-22C9-489B-9796-1ADDAB1F64E5}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhone.ActiveCfg = Debug|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhone.Build.0 = Debug|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhone.Deploy.0 = Debug|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhone.ActiveCfg = Release|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhone.Build.0 = Release|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhone.Deploy.0 = Release|iPhone - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {14A47447-2A24-4ECD-B24D-6571499DCD4C}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhone.ActiveCfg = Debug|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhone.Build.0 = Debug|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhone.Deploy.0 = Debug|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhone.ActiveCfg = Release|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhone.Build.0 = Release|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhone.Deploy.0 = Release|iPhone - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhone.ActiveCfg = Debug|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhone.Build.0 = Debug|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhone.Deploy.0 = Debug|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhone.ActiveCfg = Release|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhone.Build.0 = Release|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhone.Deploy.0 = Release|iPhone - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {DE042125-C270-4D1D-9270-0759C167567A}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhone.ActiveCfg = Debug|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhone.Build.0 = Debug|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhone.Deploy.0 = Debug|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhone.ActiveCfg = Release|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhone.Build.0 = Release|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhone.Deploy.0 = Release|iPhone - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {72390339-B2A1-4F61-A800-31ED0975B515}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhone.ActiveCfg = Debug|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhone.Build.0 = Debug|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhone.Deploy.0 = Debug|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhone.ActiveCfg = Release|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhone.Build.0 = Release|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhone.Deploy.0 = Release|iPhone - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {E8B3553F-A79F-4E50-B75B-ACEE771C320C}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhone.ActiveCfg = Debug|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhone.Build.0 = Debug|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhone.Deploy.0 = Debug|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhone.ActiveCfg = Release|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhone.Build.0 = Release|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhone.Deploy.0 = Release|iPhone - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhone.ActiveCfg = Debug|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhone.Build.0 = Debug|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhone.Deploy.0 = Debug|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhone.ActiveCfg = Release|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhone.Build.0 = Release|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhone.Deploy.0 = Release|iPhone - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhone.ActiveCfg = Debug|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhone.Build.0 = Debug|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhone.Deploy.0 = Debug|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhone.ActiveCfg = Release|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhone.Build.0 = Release|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhone.Deploy.0 = Release|iPhone - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {DD592516-B341-40FE-9100-1B0FA784A060}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhone.ActiveCfg = Debug|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhone.Build.0 = Debug|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhone.Deploy.0 = Debug|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhone.ActiveCfg = Release|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhone.Build.0 = Release|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhone.Deploy.0 = Release|iPhone - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {9BC63BEC-F305-451D-BB31-262938EA964D}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhone.ActiveCfg = Debug|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhone.Build.0 = Debug|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhone.Deploy.0 = Debug|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhone.ActiveCfg = Release|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhone.Build.0 = Release|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhone.Deploy.0 = Release|iPhone - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhone.ActiveCfg = Debug|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhone.Build.0 = Debug|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhone.Deploy.0 = Debug|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhone.ActiveCfg = Release|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhone.Build.0 = Release|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhone.Deploy.0 = Release|iPhone - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {1DBBC150-F085-43EF-B41D-27C72D133770}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhone.ActiveCfg = Debug|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhone.Build.0 = Debug|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhone.Deploy.0 = Debug|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhone.ActiveCfg = Release|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhone.Build.0 = Release|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhone.Deploy.0 = Release|iPhone - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {53782603-3096-40C2-ABD3-F8F311BAE4BE}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhone.ActiveCfg = Debug|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhone.Build.0 = Debug|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhone.Deploy.0 = Debug|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhone.ActiveCfg = Release|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhone.Build.0 = Release|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhone.Deploy.0 = Release|iPhone - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhone.ActiveCfg = Debug|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhone.Build.0 = Debug|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhone.Deploy.0 = Debug|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhone.ActiveCfg = Release|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhone.Build.0 = Release|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhone.Deploy.0 = Release|iPhone - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {DA355C86-866F-4843-9B4D-63A173C750FB}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhone.ActiveCfg = Debug|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhone.Build.0 = Debug|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhone.Deploy.0 = Debug|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhone.ActiveCfg = Release|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhone.Build.0 = Release|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhone.Deploy.0 = Release|iPhone - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {1AC70118-C90F-4EC6-9D8B-C628BDF900F7} = {4C142567-C42B-40F5-B092-798882190209} - {C121A566-555E-42B9-9B0A-1696529A9088} = {4C142567-C42B-40F5-B092-798882190209} - {FB06C76A-6BB7-40BE-9AFA-FEC13B045FB5} = {4C142567-C42B-40F5-B092-798882190209} - {F2D52EDB-BC17-4243-B06D-33CD20F87A7F} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} - {D81F5C91-D7DB-46E5-BC99-49488FB6814C} = {10D145AF-C8AE-428F-A80F-CA1B591D0DB2} - {42780CBD-3FE7-48E3-BD5B-59945EA20137} = {4C142567-C42B-40F5-B092-798882190209} - {0E916AB7-5A6C-4820-8AB1-AA492FE66D68} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1677B922-CCF0-44DE-B57E-1CDD3D2B8E8A} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {5210FB81-B807-49BB-AF0D-31FB6A83A572} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1320F627-EE43-4115-8E89-19D1753E51F2} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {1DE01410-22C9-489B-9796-1ADDAB1F64E5} = {2E93E2B5-4500-4E47-9B65-E705218AB578} - {14A47447-2A24-4ECD-B24D-6571499DCD4C} = {4C142567-C42B-40F5-B092-798882190209} - {273BDD15-7392-4078-91F0-AF23594A3D7B} = {4C142567-C42B-40F5-B092-798882190209} - {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} - {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} - {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {4C142567-C42B-40F5-B092-798882190209} - {84DEB606-77ED-49CD-9AED-D2B13C1F5A1E} = {4C142567-C42B-40F5-B092-798882190209} - {BB9DEEEF-F18C-40D8-B016-6434CC71B8C3} = {4C142567-C42B-40F5-B092-798882190209} - {DD592516-B341-40FE-9100-1B0FA784A060} = {4C142567-C42B-40F5-B092-798882190209} - {9BC63BEC-F305-451D-BB31-262938EA964D} = {4C142567-C42B-40F5-B092-798882190209} - {F32FDA80-B6DD-47A8-8681-437E2C0D3F31} = {4C142567-C42B-40F5-B092-798882190209} - {1DBBC150-F085-43EF-B41D-27C72D133770} = {4C142567-C42B-40F5-B092-798882190209} - {B33E576F-2279-4BFC-A438-D9B84343B56B} = {1AC70118-C90F-4EC6-9D8B-C628BDF900F7} - {53782603-3096-40C2-ABD3-F8F311BAE4BE} = {4C142567-C42B-40F5-B092-798882190209} - {FBE1FA7B-E699-4BB2-9C8F-41F4C9F3F088} = {4C142567-C42B-40F5-B092-798882190209} - {B4EABB0D-E495-405C-B7B1-E2A7A3711AF5} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} - {DA355C86-866F-4843-9B4D-63A173C750FB} = {4C142567-C42B-40F5-B092-798882190209} - {62E9A8E4-79AF-4081-84D5-FEC5A0B28598} = {FC791F56-C1F1-4C41-A193-868D8197F8E2} - {AD4FDC24-B64D-4ED7-91AA-62C9EDA12FA4} = {4C142567-C42B-40F5-B092-798882190209} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {FF877973-604D-4EA7-B5F5-A129961F9EF2} - EndGlobalSection -EndGlobal diff --git a/sources/targets/Stride.UnitTests.props b/sources/targets/Stride.UnitTests.props deleted file mode 100644 index 7f81c0d97d..0000000000 --- a/sources/targets/Stride.UnitTests.props +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - Windows - WinExe - - $(StridePlatform) - $(StridePlatformFullName)-$(StrideBuildDirExtension) - - false - false - obj\ - true - - - true - - - - - - - diff --git a/sources/targets/Stride.UnitTests.targets b/sources/targets/Stride.UnitTests.targets deleted file mode 100644 index c3c7b81b02..0000000000 --- a/sources/targets/Stride.UnitTests.targets +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - true - - $(StrideGraphicsApisTest) - - - Direct3D11;Direct3D12;Vulkan - Direct3D11 - - - $(StrideGraphicsApis.Split(';', StringSplitOptions.RemoveEmptyEntries)[0]) - - - - - false - false - TargetFramework=$(StrideXplatEditorTargetFramework) - - StrideSkipAutoPack - true - - - - - - - - false - false - - - - - true - --compile-property:BuildProjectReferences=false - - - - $(MSBuildThisFileDirectory)..\..\bin\Tests\$(AssemblyName)\$(StridePlatform)\ - $(BaseIntermediateOutputPath)$(StridePlatform)\$(Configuration)\ - - - $(MSBuildThisFileDirectory)..\..\bin\Tests\$(AssemblyName)\$(StridePlatform)\$(StrideGraphicsApi)\ - $(BaseIntermediateOutputPath)$(StridePlatform)-$(StrideGraphicsApi)\$(Configuration)\ - - - - true - - - xunit.runner.stride.Program - - - - LauncherSimple.Desktop.cs - - - LauncherGame.Desktop.cs - - - - - - - - $(PlatformTarget) - - - - - - - - - - - - - - true - CS8785;$(WarningsAsErrors) - - - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - From 2cfb04781b288064ef390efeea969703a775e3ec Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 28 Apr 2026 23:33:15 +0900 Subject: [PATCH 1155/1182] sdk: dedupe TFMs in GetTargetFrameworks for multi-API projects --- .../Sdk/Stride.GraphicsApi.InnerBuild.targets | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.GraphicsApi.InnerBuild.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.GraphicsApi.InnerBuild.targets index c68f1167d6..7fd502c2bc 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Stride.GraphicsApi.InnerBuild.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Stride.GraphicsApi.InnerBuild.targets @@ -82,6 +82,35 @@ + + + + + + + <_StrideInnerBuildProjectsTfmOnly Include="$(MSBuildProjectFile)"> + TargetFramework=%(_TargetFrameworkNormalized.Identity) + + + + + + + + From b38a9c864c6024aaa36d7957007fc12fc19a704b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 29 Apr 2026 09:05:30 +0900 Subject: [PATCH 1156/1182] =?UTF-8?q?d3d12:=20enhanced=20barrier=20Undefin?= =?UTF-8?q?ed=E2=86=92NoAccess/None?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs index d4b611f149..cf8ff6f37a 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/BarrierMapping.Direct3D12.cs @@ -77,6 +77,9 @@ internal static class BarrierMapping /// internal static D3D12BarrierAccess ToEnhancedAccess(BarrierLayout layout) => layout switch { + // LayoutBefore=UNDEFINED requires AccessBefore=NO_ACCESS (with SyncBefore=NONE). + // The same pairing is required when used as the After side. + BarrierLayout.Undefined => D3D12BarrierAccess.NoAccess, BarrierLayout.RenderTarget => D3D12BarrierAccess.RenderTarget, BarrierLayout.DepthStencilWrite => D3D12BarrierAccess.DepthStencilWrite, BarrierLayout.DepthStencilRead => D3D12BarrierAccess.DepthStencilRead, @@ -94,6 +97,7 @@ internal static class BarrierMapping /// internal static D3D12BarrierSync ToEnhancedSync(BarrierLayout layout) => layout switch { + BarrierLayout.Undefined => D3D12BarrierSync.None, BarrierLayout.RenderTarget => D3D12BarrierSync.RenderTarget, BarrierLayout.DepthStencilWrite => D3D12BarrierSync.DepthStencil, BarrierLayout.DepthStencilRead => D3D12BarrierSync.DepthStencil, From 158fe0d352a4ea0f32748ec61a5ef901f791310b Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 29 Apr 2026 09:05:48 +0900 Subject: [PATCH 1157/1182] vulkan: backend correctness, missing format/op/feature mappings --- .../Stride.Graphics/Vulkan/Buffer.Vulkan.cs | 6 +- .../Vulkan/CommandList.Vulkan.cs | 40 +++++++++- .../Vulkan/GraphicsDevice.Vulkan.cs | 12 ++- .../Vulkan/VulkanConvertExtensions.cs | 75 ++++++++++++++++++- 4 files changed, 127 insertions(+), 6 deletions(-) diff --git a/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs index e02a283c24..06c47dfe9b 100644 --- a/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs @@ -244,7 +244,11 @@ private void InitializeViews() viewFormat = PixelFormat.R32_Typeless; } - if ((ViewFlags & (BufferFlags.ShaderResource | BufferFlags.UnorderedAccess)) != 0) + // Structured buffers bind as VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and don't need a + // VkBufferView — only typed (Buffer/RWBuffer) and raw views go through + // VK_DESCRIPTOR_TYPE_*_TEXEL_BUFFER, which require a real VkFormat. + if ((ViewFlags & (BufferFlags.ShaderResource | BufferFlags.UnorderedAccess)) != 0 + && viewFormat != PixelFormat.None) { NativeBufferView = GetShaderResourceView(viewFormat); } diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index 135a623863..af3f3c01c7 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -512,7 +512,10 @@ private unsafe void BindDescriptorSets() case VkDescriptorType.StorageBuffer: buffer = heapObject.Value as Buffer; - descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = (ulong)heapObject.Offset, range = (ulong)(buffer?.SizeInBytes ?? 0)}; + // heapObject.Offset is repurposed to carry InitialCounterOffset for UAVs + // (defaults to -1) and is not the descriptor binding offset; structured / + // raw buffer descriptors always bind from offset 0 over the whole buffer. + descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = 0, range = (ulong)(buffer?.SizeInBytes ?? 0)}; write->pBufferInfo = &descriptorData->BufferInfo; break; @@ -691,6 +694,7 @@ public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) { CleanupRenderPass(); TransitionBoundResources(); + BindPipeline(); BindDescriptorSets(); GraphicsDevice.NativeDeviceApi.vkCmdDispatch(currentCommandList.NativeCommandBuffer, (uint)threadCountX, (uint)threadCountY, (uint)threadCountZ); } @@ -704,6 +708,7 @@ public void Dispatch(Buffer indirectBuffer, int offsetInBytes) { CleanupRenderPass(); TransitionBoundResources(); + BindPipeline(); BindDescriptorSets(); GraphicsDevice.NativeDeviceApi.vkCmdDispatchIndirect(currentCommandList.NativeCommandBuffer, indirectBuffer.NativeBuffer, (ulong)offsetInBytes); } @@ -1374,9 +1379,40 @@ public unsafe void CopyRegion(GraphicsResource source, int sourceSubresource, Re var dstStages2 = FixStagesForAccess(sourceTexture.NativePipelineStageMask | destinationParent.NativePipelineStageMask, sourceParent.NativeAccessMask | destinationParent.NativeAccessMask); GraphicsDevice.NativeDeviceApi.vkCmdPipelineBarrier(currentCommandList.NativeCommandBuffer, VkPipelineStageFlags.Transfer, dstStages2, VkDependencyFlags.None, memoryBarrierCount: 0, memoryBarriers: null, bufferBarrierCount, bufferBarriers, imageBarrierCount, imageBarriers); } + else if (source is Buffer sourceBuffer && destination is Buffer destinationBuffer) + { + CleanupRenderPass(); + + var srcOffset = (ulong)(sourceRegion?.Left ?? 0); + var size = sourceRegion is { } region2 + ? (ulong)(region2.Right - region2.Left) + : (ulong)sourceBuffer.SizeInBytes; + var dstOffset = (ulong)dstX; + + var bufferBarriers = stackalloc VkBufferMemoryBarrier[2]; + bufferBarriers[0] = new VkBufferMemoryBarrier(sourceBuffer.NativeBuffer, sourceBuffer.NativeAccessMask, VkAccessFlags.TransferRead); + bufferBarriers[1] = new VkBufferMemoryBarrier(destinationBuffer.NativeBuffer, destinationBuffer.NativeAccessMask, VkAccessFlags.TransferWrite); + var srcStages = FixStagesForAccess(sourceBuffer.NativePipelineStageMask | destinationBuffer.NativePipelineStageMask, sourceBuffer.NativeAccessMask | destinationBuffer.NativeAccessMask); + GraphicsDevice.NativeDeviceApi.vkCmdPipelineBarrier(currentCommandList.NativeCommandBuffer, srcStages, VkPipelineStageFlags.Transfer, VkDependencyFlags.None, memoryBarrierCount: 0, memoryBarriers: null, bufferMemoryBarrierCount: 2, bufferBarriers, imageMemoryBarrierCount: 0, imageMemoryBarriers: null); + + var copy = new VkBufferCopy { srcOffset = srcOffset, dstOffset = dstOffset, size = size }; + GraphicsDevice.NativeDeviceApi.vkCmdCopyBuffer(currentCommandList.NativeCommandBuffer, sourceBuffer.NativeBuffer, destinationBuffer.NativeBuffer, regionCount: 1, ©); + + if (destinationBuffer.Usage == GraphicsResourceUsage.Staging) + { + destinationBuffer.CommandListFenceValue = null; + destinationBuffer.UpdatingCommandList = this; + currentCommandList.StagingResources.Add(destinationBuffer); + } + + bufferBarriers[0] = new VkBufferMemoryBarrier(sourceBuffer.NativeBuffer, VkAccessFlags.TransferRead, sourceBuffer.NativeAccessMask); + bufferBarriers[1] = new VkBufferMemoryBarrier(destinationBuffer.NativeBuffer, VkAccessFlags.TransferWrite, destinationBuffer.NativeAccessMask); + var dstStages = FixStagesForAccess(sourceBuffer.NativePipelineStageMask | destinationBuffer.NativePipelineStageMask, sourceBuffer.NativeAccessMask | destinationBuffer.NativeAccessMask); + GraphicsDevice.NativeDeviceApi.vkCmdPipelineBarrier(currentCommandList.NativeCommandBuffer, VkPipelineStageFlags.Transfer, dstStages, VkDependencyFlags.None, memoryBarrierCount: 0, memoryBarriers: null, bufferMemoryBarrierCount: 2, bufferBarriers, imageMemoryBarrierCount: 0, imageMemoryBarriers: null); + } else { - throw new NotImplementedException(); + throw new InvalidOperationException("Cannot copy data between Buffers and Textures."); } } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index 0ad3c061b4..8229499d55 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -421,11 +421,18 @@ void SetMaxDescriptorTypeCount(VkDescriptorType type, uint limit) uniformBufferStandardLayoutFeature.sType = VkStructureType.PhysicalDeviceUniformBufferStandardLayoutFeatures; uniformBufferStandardLayoutFeature.uniformBufferStandardLayout = VkBool32.True; + // FP16 in shaders (SPIR-V Float16 capability) — required by some HLSL→SPIR-V output. + var shaderFloat16Int8Features = new VkPhysicalDeviceShaderFloat16Int8Features + { + sType = VkStructureType.PhysicalDeviceShaderFloat16Int8Features, + }; + // Timeline semaphores (core in Vulkan 1.2+, extension in 1.1) // Check if the feature is supported before requesting it var timelineSemaphoreFeatures = new VkPhysicalDeviceTimelineSemaphoreFeatures { sType = VkStructureType.PhysicalDeviceTimelineSemaphoreFeatures, + pNext = &shaderFloat16Int8Features, }; // Needed to keep RenderDoc happy until https://github.com/baldurk/renderdoc/pull/3831 is merged. var multiviewFeatures = new VkPhysicalDeviceMultiviewFeatures @@ -443,7 +450,10 @@ void SetMaxDescriptorTypeCount(VkDescriptorType type, uint limit) if (!timelineSemaphoreFeatures.timelineSemaphore) throw new InvalidOperationException("Vulkan: Timeline semaphores are not supported by this device, but are required by Stride."); timelineSemaphoreFeatures.timelineSemaphore = VkBool32.True; - timelineSemaphoreFeatures.pNext = &uniformBufferStandardLayoutFeature; + // Keep shaderInt8 disabled regardless; only enable shaderFloat16 if supported. + shaderFloat16Int8Features.shaderInt8 = VkBool32.False; + timelineSemaphoreFeatures.pNext = &shaderFloat16Int8Features; + shaderFloat16Int8Features.pNext = &uniformBufferStandardLayoutFeature; // Only keep multiview in the chain when the device supports it; drop the geom/tess sub-features regardless. void* pNextChainHead = &timelineSemaphoreFeatures; diff --git a/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs b/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs index 84429a9064..5018257716 100644 --- a/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs +++ b/sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs @@ -150,6 +150,8 @@ public static VkStencilOp ConvertStencilOperation(StencilOperation operation) return VkStencilOp.Keep; case StencilOperation.Replace: return VkStencilOp.Replace; + case StencilOperation.Zero: + return VkStencilOp.Zero; default: throw new ArgumentOutOfRangeException(); } @@ -224,9 +226,16 @@ public static VkBlendFactor ConvertBlend(Blend blend) VkFormat.R8Snorm => PixelFormat.R8_SNorm, VkFormat.R8Uint => PixelFormat.R8_UInt, VkFormat.R8Sint => PixelFormat.R8_SInt, + VkFormat.R8G8Unorm => PixelFormat.R8G8_UNorm, + VkFormat.R8G8Snorm => PixelFormat.R8G8_SNorm, + VkFormat.R8G8Uint => PixelFormat.R8G8_UInt, + VkFormat.R8G8Sint => PixelFormat.R8G8_SInt, VkFormat.R8G8B8A8Unorm => PixelFormat.R8G8B8A8_UNorm, + VkFormat.R8G8B8A8Snorm => PixelFormat.R8G8B8A8_SNorm, VkFormat.R8G8B8A8Uint => PixelFormat.R8G8B8A8_UInt, VkFormat.R8G8B8A8Sint => PixelFormat.R8G8B8A8_SInt, + VkFormat.R5G6B5UnormPack16 => PixelFormat.B5G6R5_UNorm, + VkFormat.A1R5G5B5UnormPack16 => PixelFormat.B5G5R5A1_UNorm, VkFormat.B8G8R8A8Unorm => PixelFormat.B8G8R8A8_UNorm, VkFormat.R8G8B8A8Srgb => PixelFormat.R8G8B8A8_UNorm_SRgb, VkFormat.B8G8R8A8Srgb => PixelFormat.B8G8R8A8_UNorm_SRgb, @@ -234,18 +243,22 @@ public static VkBlendFactor ConvertBlend(Blend blend) VkFormat.A2R10G10B10UnormPack32 => PixelFormat.R10G10B10A2_UNorm, VkFormat.R16Sfloat => PixelFormat.R16_Float, VkFormat.R16Unorm => PixelFormat.R16_UNorm, + VkFormat.R16Snorm => PixelFormat.R16_SNorm, VkFormat.R16Uint => PixelFormat.R16_UInt, VkFormat.R16Sint => PixelFormat.R16_SInt, VkFormat.R16G16Sfloat => PixelFormat.R16G16_Float, VkFormat.R16G16Snorm => PixelFormat.R16G16_SNorm, VkFormat.R16G16Unorm => PixelFormat.R16G16_UNorm, + VkFormat.B10G11R11UfloatPack32 => PixelFormat.R11G11B10_Float, VkFormat.R16G16B16A16Sfloat => PixelFormat.R16G16B16A16_Float, VkFormat.R16G16B16A16Unorm => PixelFormat.R16G16B16A16_UNorm, VkFormat.R16G16B16A16Snorm => PixelFormat.R16G16B16A16_SNorm, VkFormat.R16G16B16A16Uint => PixelFormat.R16G16B16A16_UInt, VkFormat.R16G16B16A16Sint => PixelFormat.R16G16B16A16_SInt, VkFormat.R32Uint => PixelFormat.R32_UInt, + VkFormat.R32Sint => PixelFormat.R32_SInt, VkFormat.R32Sfloat => PixelFormat.R32_Float, + VkFormat.E5B9G9R9UfloatPack32 => PixelFormat.R9G9B9E5_Sharedexp, VkFormat.R32G32Sfloat => PixelFormat.R32G32_Float, VkFormat.R32G32Uint => PixelFormat.R32G32_UInt, VkFormat.R32G32Sint => PixelFormat.R32G32_SInt, @@ -296,10 +309,31 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form pixelSize = 1; break; + case PixelFormat.R8G8_UNorm: + format = VkFormat.R8G8Unorm; + pixelSize = 2; + break; + case PixelFormat.R8G8_SNorm: + format = VkFormat.R8G8Snorm; + pixelSize = 2; + break; + case PixelFormat.R8G8_UInt: + format = VkFormat.R8G8Uint; + pixelSize = 2; + break; + case PixelFormat.R8G8_SInt: + format = VkFormat.R8G8Sint; + pixelSize = 2; + break; + case PixelFormat.R8G8B8A8_UNorm: format = VkFormat.R8G8B8A8Unorm; pixelSize = 4; break; + case PixelFormat.R8G8B8A8_SNorm: + format = VkFormat.R8G8B8A8Snorm; + pixelSize = 4; + break; case PixelFormat.R8G8B8A8_UInt: format = VkFormat.R8G8B8A8Uint; pixelSize = 4; @@ -309,6 +343,8 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form pixelSize = 4; break; case PixelFormat.B8G8R8A8_UNorm: + case PixelFormat.B8G8R8X8_UNorm: + // X8 is treated as an unused alpha channel. format = VkFormat.B8G8R8A8Unorm; pixelSize = 4; break; @@ -317,10 +353,21 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form pixelSize = 4; break; case PixelFormat.B8G8R8A8_UNorm_SRgb: + case PixelFormat.B8G8R8X8_UNorm_SRgb: format = VkFormat.B8G8R8A8Srgb; pixelSize = 4; break; + // Bit layouts match between DXGI and Vulkan despite reversed channel-order naming. + case PixelFormat.B5G6R5_UNorm: + format = VkFormat.R5G6B5UnormPack16; + pixelSize = 2; + break; + case PixelFormat.B5G5R5A1_UNorm: + format = VkFormat.A1R5G5B5UnormPack16; + pixelSize = 2; + break; + case PixelFormat.R10G10B10A2_UInt: format = VkFormat.A2R10G10B10UintPack32; pixelSize = 4; @@ -342,6 +389,10 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form format = VkFormat.R16Uint; pixelSize = 2; break; + case PixelFormat.R16_SNorm: + format = VkFormat.R16Snorm; + pixelSize = 2; + break; case PixelFormat.R16_SInt: format = VkFormat.R16Sint; pixelSize = 2; @@ -360,11 +411,17 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form pixelSize = 4; break; case PixelFormat.R16G16_SInt: - format = VkFormat.R16G16Snorm; + format = VkFormat.R16G16Sint; pixelSize = 4; break; case PixelFormat.R16G16_UInt: - format = VkFormat.R16G16Unorm; + format = VkFormat.R16G16Uint; + pixelSize = 4; + break; + + case PixelFormat.R11G11B10_Float: + // Bit-compatible with DXGI R11G11B10_FLOAT (Vulkan names channels MSB→LSB). + format = VkFormat.B10G11R11UfloatPack32; pixelSize = 4; break; @@ -393,11 +450,20 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form format = VkFormat.R32Uint; pixelSize = 4; break; + case PixelFormat.R32_SInt: + format = VkFormat.R32Sint; + pixelSize = 4; + break; case PixelFormat.R32_Float: format = VkFormat.R32Sfloat; pixelSize = 4; break; + case PixelFormat.R9G9B9E5_Sharedexp: + format = VkFormat.E5B9G9R9UfloatPack32; + pixelSize = 4; + break; + case PixelFormat.R32G32_Float: format = VkFormat.R32G32Sfloat; pixelSize = 8; @@ -613,6 +679,7 @@ public static VkDescriptorType ConvertDescriptorType(EffectParameterClass @class case EffectParameterType.Buffer: return VkDescriptorType.UniformTexelBuffer; case EffectParameterType.StructuredBuffer: + case EffectParameterType.ByteAddressBuffer: return VkDescriptorType.StorageBuffer; default: @@ -639,6 +706,10 @@ public static VkDescriptorType ConvertDescriptorType(EffectParameterClass @class case EffectParameterType.Buffer: case EffectParameterType.StructuredBuffer: + case EffectParameterType.RWStructuredBuffer: + case EffectParameterType.AppendStructuredBuffer: + case EffectParameterType.ConsumeStructuredBuffer: + case EffectParameterType.RWByteAddressBuffer: return VkDescriptorType.StorageBuffer; default: From d56eb571e6353faa72f32f487e0e1c5743b7ffb6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 29 Apr 2026 09:05:54 +0900 Subject: [PATCH 1158/1182] dxil: unified bindings for D3D12, SM 6.2 floor, mesa logger callback --- .../EffectCompiler.cs | 36 ++++++++++++++++--- .../Stride.Shaders.Compilers.csproj | 5 +++ .../native/spirv_to_dxil.VERSION.txt | 6 ++-- .../native/spirv_to_dxil.dll | 4 +-- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs index d842a3f1eb..5429209c20 100644 --- a/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs +++ b/sources/shaders/Stride.Shaders.Compilers/EffectCompiler.cs @@ -156,7 +156,9 @@ public override TaskOrResult Compile(ShaderMixinSo var shaderMixer = new ShaderMixer(GetFileShaderLoader()); if (!shaderMixer.MergeSDSL(shaderMixinSource, new ShaderMixer.Options( - ResourcesRegisterSeparate: effectParameters.Platform is not GraphicsPlatform.Vulkan, + // D3D12 also goes through SPIR-V (then DXIL via mesa), so it needs the unified + // binding scheme — only D3D11/FXC consumes the per-class b#/t#/u#/s# bank style. + ResourcesRegisterSeparate: effectParameters.Platform is GraphicsPlatform.Direct3D11, StripGoogleUserType: effectParameters.Platform is GraphicsPlatform.Vulkan), log, out var spirvBytecode, out var effectReflection, out var usedHashSources, out var entryPoints)) return new EffectBytecodeCompilerResult(null, log); @@ -546,11 +548,17 @@ private static unsafe void CompileDxilPipeline(ReadOnlySpan spirvBytecode, { var runtimeConf = new RuntimeConf { + // Mesa-injected CBVs for sysvals/push-constants. Both go in a high register space + // so they can't collide with Stride's resources (which all live in space 0). runtime_data_cbv = { base_shader_register = 0, register_space = 31 }, + push_constant_cbv = { base_shader_register = 1, register_space = 31 }, yzflip_mode = FlipMode.YZFlipNone, - shader_model_max = dxil_shader_model.SHADER_MODEL_6_0, + // SM 6.2 minimum so mesa can lower native 16-bit types (Float16/Int16) when a + // shader uses `half`. Mesa only ramps individual shaders up to 6.2 on demand. + shader_model_max = dxil_shader_model.SHADER_MODEL_6_2, }; - var logger = new DXILSpirvLogger(); + _spvLogSink?.Clear(); + var logger = new DXILSpirvLogger { log = &SpvLogCallback }; // Allocate native buffers for entry point names (UTF-8 null-terminated) var entryPointNameBuffers = new byte[entryPoints.Count][]; @@ -593,7 +601,12 @@ private static unsafe void CompileDxilPipeline(ReadOnlySpan spirvBytecode, } if (!Spv2DXIL.spirv_to_dxil_pipeline(stages, entryPoints.Count, ValidatorVersion.DXIL_VALIDATOR_1_4, ref runtimeConf, ref logger, outputs)) - throw new InvalidOperationException("spirv_to_dxil_pipeline failed"); + { + var dumpPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"stride-dxil-fail-{Guid.NewGuid():N}.spv"); + System.IO.File.WriteAllBytes(dumpPath, spirvBytecode.ToArray()); + var diag = _spvLogSink is { Length: > 0 } sb ? sb.ToString().TrimEnd() : "(no diagnostics from spirv_to_dxil)"; + throw new InvalidOperationException($"spirv_to_dxil_pipeline failed; SPIR-V dumped to {dumpPath}\n{diag}"); + } for (int i = 0; i < entryPoints.Count; i++) { @@ -612,6 +625,21 @@ private static unsafe void CompileDxilPipeline(ReadOnlySpan spirvBytecode, } } + // Thread-local sink for messages mesa logs through DXILSpirvLogger.log during a single + // CompileDxilPipeline call. Drained into the exception text on failure. + [ThreadStatic] private static StringBuilder _spvLogSink; + + [System.Runtime.InteropServices.UnmanagedCallersOnly(CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] + private static unsafe void SpvLogCallback(void* priv, byte* message) + { + if (message is null) + return; + var sink = _spvLogSink ??= new StringBuilder(); + int len = 0; + while (message[len] != 0) len++; + sink.AppendLine(Encoding.UTF8.GetString(message, len)); + } + /// /// Writes .spv and .spvdis files. Caller must hold WriterLock. /// diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 54c532bc13..6624e71570 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -45,6 +45,11 @@ runtimes\win-x64\native\%(Filename)%(Extension) PreserveNewest + + runtimes\win-x64\native\%(Filename)%(Extension) + runtimes\win-x64\native\%(Filename)%(Extension) + PreserveNewest + diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt index c62c3f24b0..b4de116c8c 100644 --- a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.VERSION.txt @@ -1,2 +1,4 @@ -Mesa: https://gitlab.freedesktop.org/mesa/mesa.git @ aa2bc8d2d88e65dcfb046a8ff11db1f0000d4a8a -Stride: https://github.com/stride3d/stride @ ae6aa351cff4c7d810eae21d0bed6801c515f05f (for workflow and build/deps/spirv-to-dxil/mesa-pipeline.patch) +Local debug build (debugoptimized, no UPX, with PDB) +Mesa: stride/spirv-to-dxil-tcs-fixes @ 50ab52f135e42f6f52ccbfadf78b00eab0a2b3b6 +Stride patch: build/deps/spirv-to-dxil/mesa-pipeline.patch (applied + spirv_to_nir arity fix) +Built: 2026-04-29 diff --git a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll index d89e916e7b..cd32386825 100644 --- a/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll +++ b/sources/shaders/Stride.Shaders.Compilers/native/spirv_to_dxil.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c2d707cb986570917f7435db32bb7761476500efa43920a9ca669b70814ef02 -size 666112 +oid sha256:8aaa1216e20a643e25e3a30299ef0455e08ca8165afd33ac1fed1041ae1d1003 +size 12090880 From 8f37a2ee3cd79c5c8852b6d5187360c7d0f7c030 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 29 Apr 2026 22:38:20 +0900 Subject: [PATCH 1159/1182] d3d12: raw SRV/UAV views for structured buffers --- .../Direct3D12/Buffer.Direct3D12.cs | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs index dde75a3ea7..bd8ff3c5e9 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs @@ -304,23 +304,32 @@ internal CpuDescriptorHandle GetShaderResourceView(PixelFormat viewFormat) if (ViewFlags.HasFlag(BufferFlags.ShaderResource)) { + // The DXIL produced by mesa's spirv_to_dxil lowers SPIR-V SSBOs to ByteAddressBuffer + // (DXIL_RESOURCE_KIND_RAW_BUFFER) regardless of whether the original SDSL declared + // them as StructuredBuffer. Binding a structured-buffer SRV (StructureByteStride > 0) + // to a ByteAddressBuffer DXIL slot has undefined access bounds per the D3D12 spec — + // observed clamp on NVIDIA is NumElements * 16 bytes, hiding ~3/4 of the buffer. + // Always emit raw SRVs for buffers flagged as ShaderResource so byte-addressed + // access from DXIL covers the full buffer. + bool useRawView = ViewFlags.HasFlag(BufferFlags.RawBuffer) + || ViewFlags.HasFlag(BufferFlags.StructuredBuffer); + var description = new ShaderResourceViewDesc { Shader4ComponentMapping = 0x00001688, - Format = (Format) viewFormat, + Format = useRawView ? Format.FormatR32Typeless : (Format) viewFormat, ViewDimension = SrvDimension.Buffer, Buffer = new() { - NumElements = (uint) ElementCount, FirstElement = 0, - Flags = BufferSrvFlags.None, - StructureByteStride = (uint) StructureByteStride + NumElements = useRawView + ? (uint) (SizeInBytes / 4) + : (uint) ElementCount, + Flags = useRawView ? BufferSrvFlags.Raw : BufferSrvFlags.None, + StructureByteStride = useRawView ? 0u : (uint) StructureByteStride, } }; - if (ViewFlags.HasFlag(BufferFlags.RawBuffer)) - description.Buffer.Flags |= BufferSrvFlags.Raw; - srv = GraphicsDevice.ShaderResourceViewAllocator.Allocate(); NativeDevice.CreateShaderResourceView(NativeResource, in description, srv); } @@ -343,26 +352,27 @@ internal CpuDescriptorHandle GetUnorderedAccessView(PixelFormat viewFormat) if (ViewFlags.HasFlag(BufferFlags.UnorderedAccess)) { + // Mesa's spirv_to_dxil emits writable SSBOs as RWByteAddressBuffer; mirror the + // SRV-side decision and always use raw UAV views for structured / raw buffers. + bool useRawView = ViewFlags.HasFlag(BufferFlags.RawBuffer) + || ViewFlags.HasFlag(BufferFlags.StructuredBuffer); + var description = new UnorderedAccessViewDesc { - Format = (Format) viewFormat, + Format = useRawView ? Format.FormatR32Typeless : (Format) viewFormat, ViewDimension = UavDimension.Buffer, Buffer = new() { - NumElements = (uint) ElementCount, FirstElement = 0, - Flags = BufferUavFlags.None, - StructureByteStride = (uint) StructureByteStride, + NumElements = useRawView + ? (uint) (SizeInBytes / 4) + : (uint) ElementCount, + Flags = useRawView ? BufferUavFlags.Raw : BufferUavFlags.None, + StructureByteStride = useRawView ? 0u : (uint) StructureByteStride, CounterOffsetInBytes = 0 } }; - if (ViewFlags.HasFlag(BufferFlags.RawBuffer)) - { - description.Buffer.Flags |= BufferUavFlags.Raw; - description.Format = Format.FormatR32Typeless; - } - uav = GraphicsDevice.UnorderedAccessViewAllocator.Allocate(1); // TODO: Manage counter value here if Buffer has 'Counter' or 'Append' flag @@ -370,7 +380,7 @@ internal CpuDescriptorHandle GetUnorderedAccessView(PixelFormat viewFormat) NativeDevice.CreateUnorderedAccessView(NativeResource, pCounterResource: null, in description, uav); } return uav; - }} + } } - +} #endif From c00e760af9b8364de9e5c89729a3908da5feeeaf Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 00:53:48 +0900 Subject: [PATCH 1160/1182] graphics: scope-tree debug breadcrumbs --- .../Stride.Graphics/CommandList.DebugScope.cs | 76 +++++++ .../engine/Stride.Graphics/DebugScopeFrame.cs | 54 +++++ .../Direct3D12/CommandList.Direct3D12.cs | 31 ++- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 46 ++++- .../GraphicsDevice.DebugScope.cs | 195 ++++++++++++++++++ 5 files changed, 397 insertions(+), 5 deletions(-) create mode 100644 sources/engine/Stride.Graphics/CommandList.DebugScope.cs create mode 100644 sources/engine/Stride.Graphics/DebugScopeFrame.cs create mode 100644 sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs diff --git a/sources/engine/Stride.Graphics/CommandList.DebugScope.cs b/sources/engine/Stride.Graphics/CommandList.DebugScope.cs new file mode 100644 index 0000000000..f52bc99e24 --- /dev/null +++ b/sources/engine/Stride.Graphics/CommandList.DebugScope.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.Generic; + +namespace Stride.Graphics; + +/// +/// Per-CL portion of the backend-shared scope diagnostics. The CL keeps a small list of +/// per-scope counter buckets; the actual scope tree lives on and +/// is mutated only by the rendering thread that calls BeginProfile/EndProfile. +/// Worker CLs read 's current scope frame at record time (no +/// sync needed — the main thread is blocked while workers run inside Dispatcher.For), bump +/// their own local counter for that frame, and the device aggregates at submit. +/// +public partial class CommandList +{ + private readonly List debugLocalCounters = new(); + + internal enum DebugCounterKind { Draw, Dispatch, Clear, Copy, Barrier } + + internal void RecordDebugCounter(DebugCounterKind kind) + { + var device = GraphicsDevice; + if (device is null || device.IsDebugMode == false) + return; + var frame = device.GetDebugCurrentFrame(); + if (frame is null) + return; + + // Find or create the entry for this frame. List is small (one per scope touched); + // search from the tail since the active frame is usually the most recently touched. + var span = System.Runtime.InteropServices.CollectionsMarshal.AsSpan(debugLocalCounters); + int idx = -1; + for (int i = span.Length - 1; i >= 0; i--) + { + if (ReferenceEquals(span[i].Frame, frame)) { idx = i; break; } + } + if (idx < 0) + { + debugLocalCounters.Add(new DebugPerScopeCounters { Frame = frame }); + idx = debugLocalCounters.Count - 1; + span = System.Runtime.InteropServices.CollectionsMarshal.AsSpan(debugLocalCounters); + } + ref var entry = ref span[idx]; + switch (kind) + { + case DebugCounterKind.Draw: entry.Draws++; break; + case DebugCounterKind.Dispatch: entry.Dispatches++; break; + case DebugCounterKind.Clear: entry.Clears++; break; + case DebugCounterKind.Copy: entry.Copies++; break; + case DebugCounterKind.Barrier: entry.Barriers++; break; + } + } + + /// + /// Detaches this CL's per-scope counters list (called at submit by the device aggregator). + /// + internal List DebugScopeExtractLocalCounters() + { + if (debugLocalCounters.Count == 0) + return null; + var ret = new List(debugLocalCounters); + debugLocalCounters.Clear(); + return ret; + } + + /// + /// Resets the per-CL counter list when a new recording session begins. Backend + /// Reset implementations should call this. + /// + internal void DebugScopeResetForNewRecording() + { + debugLocalCounters.Clear(); + } +} diff --git a/sources/engine/Stride.Graphics/DebugScopeFrame.cs b/sources/engine/Stride.Graphics/DebugScopeFrame.cs new file mode 100644 index 0000000000..e6a798a4b0 --- /dev/null +++ b/sources/engine/Stride.Graphics/DebugScopeFrame.cs @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.Generic; + +namespace Stride.Graphics; + +/// +/// One per-scope counter bucket on a CommandList — written by the CL's recording thread, +/// merged into the device-wide scope tree at submit time. +/// +internal struct DebugPerScopeCounters +{ + public DebugScopeFrame Frame; + public int Draws; + public int Dispatches; + public int Clears; + public int Copies; + public int Barriers; +} + +/// +/// Tree node for a single / pair. +/// Children are recorded in entry order so the tree preserves the temporal sequence of nested scopes. +/// Counters are aggregated from per-CL localCounters at submit time (under the queue lock). +/// +internal sealed class DebugScopeFrame +{ + public string Name; + public DebugScopeFrame Parent; + public List Children; + public int Draws; + public int Dispatches; + public int Clears; + public int Copies; + public int Barriers; + /// + /// Number of distinct CommandLists whose work has been merged into this scope. Set by the + /// submit-time aggregator; 1 in the common single-CL case. Larger when parallel + /// recording (Dispatcher.For etc.) had multiple CLs touch the same scope. + /// + public int ExecutedCLs; + /// + /// once a matching EndProfile ran; if the scope + /// was still open when its containing tree was dumped (= the active scope at error time). + /// + public bool ClosedByPop; + + public void AddChild(DebugScopeFrame child) + { + Children ??= new List(); + Children.Add(child); + } +} diff --git a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs index 63f2ff7f19..596396133a 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs @@ -138,6 +138,8 @@ public unsafe partial void Reset() if (currentCommandList.Builder is not null) return; + DebugScopeResetForNewRecording(); + FlushResourceBarriers(); ResetSrvHeap(createNewHeap: true); ResetSamplerHeap(createNewHeap: true); @@ -393,10 +395,12 @@ private unsafe partial void SetScissorRectanglesImpl(ReadOnlySpan sci /// /// This method is called before each Draw() method to setup the correct Viewport. /// - private void PrepareDraw() + private void PrepareDraw(bool isDispatch = false) { FlushResourceBarriers(); SetViewportImpl(); + + RecordDebugCounter(isDispatch ? DebugCounterKind.Dispatch : DebugCounterKind.Draw); } /// @@ -548,6 +552,8 @@ public void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout n { Debug.Assert(resource is not null, "Resource must not be null."); + RecordDebugCounter(DebugCounterKind.Barrier); + // Texture views share the native resource of their parent; barrier the parent instead if (resource is Texture { ParentTexture: not null } textureView) resource = textureView.ParentTexture; @@ -919,7 +925,7 @@ private void ResetSamplerHeap(bool createNewHeap) /// Number of thread groups in the Z dimension. public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) { - PrepareDraw(); // TODO: PrepareDraw for Compute dispatch? + PrepareDraw(isDispatch: true); // TODO: PrepareDraw for Compute dispatch? currentCommandList.NativeCommandList.Dispatch((uint) threadCountX, (uint) threadCountY, (uint) threadCountZ); } @@ -1094,6 +1100,11 @@ public void WriteTimestamp(QueryPool queryPool, int index) /// public void BeginProfile(Color4 profileColor, string name) { + // Scope tracking lives on GraphicsDevice (single-rendering-thread mutation). + // Tier 1 (stack) is always on — used to annotate validation log messages. + // Tier 2 (tree) is added when IsDebugMode is set. + GraphicsDevice.PushDebugScope(name); + if (!IsDebugMode) return; @@ -1118,6 +1129,8 @@ public void BeginProfile(Color4 profileColor, string name) /// public void EndProfile() { + GraphicsDevice.PopDebugScope(); + if (!IsDebugMode) return; @@ -1162,6 +1175,7 @@ public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, currentCommandList.NativeCommandList.ClearDepthStencilView(depthStencilBuffer.NativeDepthStencilView, (ClearFlags) options, depth, stencil, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1182,6 +1196,7 @@ public void Clear(Texture renderTarget, Color4 color) currentCommandList.NativeCommandList.ClearRenderTargetView(renderTarget.NativeRenderTargetView, ref clearColorFloats, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1209,6 +1224,7 @@ public void ClearReadWrite(Buffer buffer, Vector4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewFloat(gpuHandle, cpuHandle, buffer.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1236,6 +1252,7 @@ public void ClearReadWrite(Buffer buffer, Int4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewUint(gpuHandle, cpuHandle, buffer.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1263,6 +1280,7 @@ public void ClearReadWrite(Buffer buffer, UInt4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewUint(gpuHandle, cpuHandle, buffer.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1290,6 +1308,7 @@ public void ClearReadWrite(Texture texture, Vector4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewFloat(gpuHandle, cpuHandle, texture.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1317,6 +1336,7 @@ public void ClearReadWrite(Texture texture, Int4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewUint(gpuHandle, cpuHandle, texture.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1344,6 +1364,7 @@ public void ClearReadWrite(Texture texture, UInt4 value) currentCommandList.NativeCommandList.ClearUnorderedAccessViewUint(gpuHandle, cpuHandle, texture.NativeResource, ref clearValue, NumRects: 0, in nullRect); + RecordDebugCounter(DebugCounterKind.Clear); } /// @@ -1403,6 +1424,8 @@ public void Copy(GraphicsResource source, GraphicsResource destination) ArgumentNullException.ThrowIfNull(source); ArgumentNullException.ThrowIfNull(destination); + RecordDebugCounter(DebugCounterKind.Copy); + // Copy Texture -> Texture if (source is Texture sourceTexture && destination is Texture destinationTexture) @@ -1625,6 +1648,8 @@ public void CopyMultisample(Texture sourceMultiSampledTexture, int sourceSubReso ArgumentNullException.ThrowIfNull(sourceMultiSampledTexture); ArgumentNullException.ThrowIfNull(destinationTexture); + RecordDebugCounter(DebugCounterKind.Copy); + if (!sourceMultiSampledTexture.IsMultiSampled) throw new ArgumentException("Source Texture is not a MSAA Texture", nameof(sourceMultiSampledTexture)); @@ -1695,6 +1720,8 @@ public void CopyMultisample(Texture sourceMultiSampledTexture, int sourceSubReso public void CopyRegion(GraphicsResource source, int sourceSubResourceIndex, ResourceRegion? sourceRegion, GraphicsResource destination, int destinationSubResourceIndex, int dstX = 0, int dstY = 0, int dstZ = 0) { + RecordDebugCounter(DebugCounterKind.Copy); + if (source is Texture sourceTexture && destination is Texture destinationTexture) { diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 72d0c34dfb..f329ec8f44 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; +using System.Text; using Silk.NET.Core.Native; using Silk.NET.DXGI; @@ -843,6 +844,10 @@ internal void OnDestroyed(bool immediately = false) { } + // Backend implementation of the partial method declared in GraphicsDevice.DebugScope.cs; + // called once per frame when the outermost BeginProfile scope closes. + partial void DrainDebugMessages() => FlushDebugMessages(); + /// /// Drains all pending D3D12 debug messages from the InfoQueue and logs them. /// @@ -852,6 +857,7 @@ internal void FlushDebugMessages() return; var numMessages = nativeInfoQueue->GetNumStoredMessages(); + bool sawDrawIssue = false; for (ulong i = 0; i < numMessages; i++) { nuint messageLength = 0; @@ -868,24 +874,49 @@ internal void FlushDebugMessages() var description = Marshal.PtrToStringAnsi((nint) message->PDescription) ?? "(no description)"; - Debug.WriteLine($"D3D12: {message->Severity} {description}"); + // The native debug layer already prints these to OutputDebugString, so we + // don't echo via Debug.WriteLine — that's a third copy in the same sink. + + // Categories that fire during draw/dispatch recording or GPU execution benefit + // from a scope annotation and tree dump — initialization, shader compile, + // PSO/heap creation messages don't. + bool isDrawCategory = message->Category is MessageCategory.StateSetting + or MessageCategory.Execution + or MessageCategory.ResourceManipulation; + + var prefix = isDrawCategory ? GetDrainTimeScopePrefix() : null; switch (message->Severity) { case MessageSeverity.Corruption: case MessageSeverity.Error: - Log.Error($"[D3D12] {message->Severity}: {description}"); + DebugLog.Error($"{prefix}{description}"); + if (isDrawCategory) sawDrawIssue = true; break; case MessageSeverity.Warning: - Log.Warning($"[D3D12] {description}"); + DebugLog.Warning($"{prefix}{description}"); + if (isDrawCategory) sawDrawIssue = true; break; } } } + if (sawDrawIssue) + DebugDumpTree(); + nativeInfoQueue->ClearStoredMessages(); } + /// + /// Returns a "[scope]: " prefix for log messages — the leaf of the active scope stack. + /// The full path is in the tree dump's "Active scope:" line; per-message we keep it short. + /// + private string GetDrainTimeScopePrefix() + { + if (debugScopeStack.Count == 0) return ""; + return $"[{debugScopeStack.Peek()}]: "; + } + /// /// Logs DRED (Device Removed Extended Data) information after a device removal event. /// @@ -964,6 +995,15 @@ internal ulong ExecuteCommandListInternal(CompiledCommandList commandList) nativeCommandQueue->ExecuteCommandLists(NumCommandLists: 1, ref nativeCommandList); CommandListFence.Signal(NativeCommandQueue, commandListFenceValue + 1); + + if (IsDebugMode) + { + // Aggregate this CL's per-scope counters into the device-wide scope tree. + // We don't drain debug messages here — that happens once per frame in + // PopDebugScope when the outermost scope closes, so the tree is complete + // and no misleading "active scope" annotation is shown on per-message logs. + DebugAggregateLocalCounters(commandList.Builder.DebugScopeExtractLocalCounters()); + } } RecycleCommandListResources(commandList, commandListFenceValue + 1); diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs new file mode 100644 index 0000000000..3a7fbb0d4e --- /dev/null +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -0,0 +1,195 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.Generic; +using System.Text; + +using Stride.Core.Diagnostics; + +namespace Stride.Graphics; + +/// +/// Backend-shared diagnostic state on the device. The active scope stack and the in-progress +/// per-frame scope tree both live here, mutated only by the rendering thread that calls +/// BeginProfile/EndProfile (in Stride: the main rendering thread). +/// +/// Worker CommandLists (e.g. recorded inside Dispatcher.For) never call BeginProfile, +/// so the stack/tree state isn't contended. They simply read the current frame pointer at +/// record time, accumulate per-CL counters, and the device merges them into the tree at submit +/// under the queue lock. +/// +public partial class GraphicsDevice +{ + internal static readonly Logger DebugLog = GlobalLogger.GetLogger("GraphicsDebug"); + + // Active scope stack (Tier 1: always on, including release — used for log annotation). + // Mirrors the active BeginProfile/EndProfile state. + private readonly Stack debugScopeStack = new(); + + // Tier 2: scope tree, only built when IsDebugMode is set. + private DebugScopeFrame debugTreeRoot; + private DebugScopeFrame debugCurrentFrame; + + /// + /// Pushes a scope onto the active scope stack. Backend BeginProfile implementations call + /// this. Tier 1 (stack) is always maintained; Tier 2 (tree) only when IsDebugMode is set. + /// + internal void PushDebugScope(string name) + { + debugScopeStack.Push(name); + if (!IsDebugMode) + return; + + debugTreeRoot ??= new DebugScopeFrame { Name = null }; // synthetic root + var parent = debugCurrentFrame ?? debugTreeRoot; + var frame = new DebugScopeFrame { Name = name, Parent = debugCurrentFrame }; + parent.AddChild(frame); + debugCurrentFrame = frame; + } + + internal void PopDebugScope() + { + if (debugScopeStack.Count > 0) + debugScopeStack.Pop(); + + if (IsDebugMode && debugCurrentFrame is not null) + { + debugCurrentFrame.ClosedByPop = true; + debugCurrentFrame = debugCurrentFrame.Parent; + } + + // Drain pending debug messages once per frame when the outermost scope closes. With + // queue-poll backends (D3D12 InfoQueue, D3D11 InfoQueue) this is the cleanest moment: + // the scope tree is fully built and there's no active scope to mislead the annotation. + // Until ID3D12InfoQueue1 callback mode lands, we accept the latency vs precision trade. + if (IsDebugMode && debugScopeStack.Count == 0) + { + DrainDebugMessages(); + // Always reset — drain only clears the tree if it dumped (errors fired). For clean + // frames the tree would accumulate across frames otherwise. Works headlessly too. + debugTreeRoot = null; + debugCurrentFrame = null; + } + } + + /// + /// Drains backend-specific debug-message queue. Backend partials override / fill this in. + /// No-op by default; D3D12 partial pumps the InfoQueue. + /// + partial void DrainDebugMessages(); + + /// The currently-open scope frame, or if no scope is active. + internal DebugScopeFrame GetDebugCurrentFrame() => debugCurrentFrame; + + /// + /// Returns the active scope path (root → leaf) as a single string, or + /// if no scope is active. Used for annotating validation messages. + /// + internal string GetDebugActiveScopePath() + { + if (debugScopeStack.Count == 0) + return null; + var sb = new StringBuilder(); + bool first = true; + var arr = debugScopeStack.ToArray(); // top → bottom (leaf → root) + for (int i = arr.Length - 1; i >= 0; i--) + { + if (!first) sb.Append(" / "); + sb.Append(arr[i]); + first = false; + } + return sb.ToString(); + } + + /// + /// Aggregates a CL's per-scope counters into the device tree. Caller must hold the queue lock. + /// Increments on each touched frame so the dump + /// can show how many CLs participated when there's parallelism. + /// + internal void DebugAggregateLocalCounters(List entries) + { + if (entries is null) return; + foreach (var e in entries) + { + var f = e.Frame; + f.Draws += e.Draws; + f.Dispatches += e.Dispatches; + f.Clears += e.Clears; + f.Copies += e.Copies; + f.Barriers += e.Barriers; + f.ExecutedCLs++; + } + } + + /// Renders the current scope tree as a multi-line string and resets it. + internal void DebugDumpTree() + { + if (debugTreeRoot is null || debugTreeRoot.Children is not { Count: > 0 }) + return; + + var sb = new StringBuilder(); + sb.AppendLine("Scope tree:"); + foreach (var child in debugTreeRoot.Children) + AppendTree(sb, child, 0); + + var openLeaf = debugCurrentFrame; + if (openLeaf is not null && openLeaf.Name is not null) + { + sb.Append("Active scope: "); + AppendScopePath(sb, openLeaf); + sb.AppendLine(); + } + + DebugLog.Error(sb.ToString().TrimEnd()); + debugTreeRoot = null; + debugCurrentFrame = null; + } + + private static void AppendTree(StringBuilder sb, DebugScopeFrame frame, int depth) + { + sb.Append(' ', depth * 2); + sb.Append(frame.Name ?? "(unnamed)"); + + bool any = (frame.Draws | frame.Dispatches | frame.Clears | frame.Copies | frame.Barriers) != 0 + || frame.ExecutedCLs > 1; + if (any) + { + sb.Append(" ("); + bool first = true; + void AppendStat(string key, int v) + { + if (v == 0) return; + if (!first) sb.Append(", "); + sb.Append(key).Append('=').Append(v); + first = false; + } + AppendStat("Draws", frame.Draws); + AppendStat("Dispatches", frame.Dispatches); + AppendStat("Clears", frame.Clears); + AppendStat("Copies", frame.Copies); + AppendStat("Barriers", frame.Barriers); + // Only show the CL count when it's a multi-CL scope (parallelism marker). + if (frame.ExecutedCLs > 1) + AppendStat("CLs", frame.ExecutedCLs); + sb.Append(')'); + } + if (!frame.ClosedByPop) + sb.Append(" (OPEN)"); + sb.AppendLine(); + + if (frame.Children is not null) + { + foreach (var c in frame.Children) + AppendTree(sb, c, depth + 1); + } + } + + private static void AppendScopePath(StringBuilder sb, DebugScopeFrame leaf) + { + var stack = new Stack(); + for (var f = leaf; f is not null && f.Name is not null; f = f.Parent) + stack.Push(f.Name); + bool first = true; + while (stack.Count > 0) { if (!first) sb.Append(" / "); sb.Append(stack.Pop()); first = false; } + } +} From 39683c102712aa55b45acfc03612ae00380f8ec9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 12:17:42 +0900 Subject: [PATCH 1161/1182] graphics: D3D12 InfoQueue1 callback, error/warning attribution, end-of-frame dump --- sources/engine/Stride.Games/GameBase.cs | 4 + .../engine/Stride.Graphics/DebugScopeFrame.cs | 7 ++ .../Direct3D12/GraphicsDevice.Direct3D12.cs | 104 +++++++++++++++++- .../GraphicsDevice.DebugScope.cs | 36 +++--- 4 files changed, 133 insertions(+), 18 deletions(-) diff --git a/sources/engine/Stride.Games/GameBase.cs b/sources/engine/Stride.Games/GameBase.cs index bb5563d769..6930f08d4b 100644 --- a/sources/engine/Stride.Games/GameBase.cs +++ b/sources/engine/Stride.Games/GameBase.cs @@ -828,6 +828,10 @@ protected virtual void EndDraw(bool present) // Close command list GraphicsContext.CommandList.Flush(); + // After the frame's submits have aggregated their per-CL counters into the + // scope tree, render it (if any validation issue fired) and reset for next frame. + GraphicsDevice.DebugEndFrame(); + // Present (if necessary) graphicsDeviceManager.EndDraw(present); diff --git a/sources/engine/Stride.Graphics/DebugScopeFrame.cs b/sources/engine/Stride.Graphics/DebugScopeFrame.cs index e6a798a4b0..3708eb4ad6 100644 --- a/sources/engine/Stride.Graphics/DebugScopeFrame.cs +++ b/sources/engine/Stride.Graphics/DebugScopeFrame.cs @@ -41,6 +41,13 @@ internal sealed class DebugScopeFrame /// public int ExecutedCLs; /// + /// Validation errors/warnings attributed to this scope (only when running with the + /// ID3D12InfoQueue1 callback path, where the active leaf at message time is known). + /// The queue-poll fallback can't attribute, so these stay zero there. + /// + public int Errors; + public int Warnings; + /// /// once a matching EndProfile ran; if the scope /// was still open when its containing tree was dumped (= the active scope at error time). /// diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index f329ec8f44..06f7f2ab1b 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -34,6 +34,12 @@ public unsafe partial class GraphicsDevice private static bool debugLayerLoaded = false; private ID3D12InfoQueue* nativeInfoQueue; + private ID3D12InfoQueue1* nativeInfoQueue1; + private uint debugMessageCallbackCookie; + private GCHandle debugMessageContext; + // Set by the callback when a draw-relevant validation message arrives within a scope. + // Consumed by DrainDebugMessages at the next scope-empty transition. + private bool debugSawDrawIssue; /// /// Concurrent pool for lists of Graphics Resources that are used for staging operations. @@ -530,6 +536,24 @@ private unsafe partial void InitializePlatformDevice(GraphicsProfile[] graphicsP // Keep reference to drain messages to log nativeInfoQueue = infoQueue; + + // ID3D12InfoQueue1 (Win10 21H2+) lets us register a synchronous callback so + // each message arrives on the API-call thread with the scope stack intact — + // perfect attribution for validation errors. Falls back to queue-poll when + // the interface isn't available. + HResult callbackResult = infoQueue.QueryInterface(out ComPtr infoQueue1); + if (callbackResult.IsSuccess && infoQueue1.IsNotNull()) + { + nativeInfoQueue1 = infoQueue1; + debugMessageContext = GCHandle.Alloc(this, GCHandleType.Weak); + uint cookie = 0; + nativeInfoQueue1->RegisterMessageCallback( + new PfnMessageFunc(&OnDebugMessageCallback), + MessageCallbackFlags.FlagNone, + (void*)(IntPtr)debugMessageContext, + ref cookie); + debugMessageCallbackCookie = cookie; + } } debugDevice.Release(); } @@ -611,9 +635,9 @@ void EnableDebugLayer() // // Requires D3D12 Enhanced Barriers. Throws if unsupported. // - // Minimum requirements: Windows 10 1909+ with Agility SDK, or Windows 11. Driver - // floors: NVIDIA 531.18+, AMD 23.5.2+, Intel 31.0.101.4032+. WARP and Xbox - // Series X|S are supported. + // Minimum requirements: Windows 10 21H2 (build 19044) or Windows 11 — we use the + // system d3d12.dll, no Agility SDK is embedded. Driver floors: NVIDIA 531.18+, + // AMD 23.5.2+, Intel 31.0.101.4032+. WARP and Xbox Series X|S are supported. // void RequireEnhancedBarriersSupport() { @@ -628,7 +652,7 @@ void RequireEnhancedBarriersSupport() throw new GraphicsDeviceException( "D3D12 Enhanced Barriers are required but not supported by this device/driver. " + "Update to a recent GPU driver (NVIDIA 531.18+, AMD 23.5.2+, Intel 31.0.101.4032+) " + - "or run on Windows 11 / Windows 10 with the Agility SDK."); + "and run on Windows 10 21H2 or Windows 11."); } } } @@ -826,6 +850,15 @@ private void ReleaseDevice() debugDevice.Release(); } + if (nativeInfoQueue1 is not null) + { + if (debugMessageCallbackCookie != 0) + nativeInfoQueue1->UnregisterMessageCallback(debugMessageCallbackCookie); + debugMessageCallbackCookie = 0; + SafeRelease(ref nativeInfoQueue1); + } + if (debugMessageContext.IsAllocated) + debugMessageContext.Free(); SafeRelease(ref nativeInfoQueue); } @@ -846,16 +879,77 @@ internal void OnDestroyed(bool immediately = false) // Backend implementation of the partial method declared in GraphicsDevice.DebugScope.cs; // called once per frame when the outermost BeginProfile scope closes. - partial void DrainDebugMessages() => FlushDebugMessages(); + partial void DrainDebugMessages() + { + if (nativeInfoQueue1 is not null) + { + // Callback mode — messages were already logged inline. Just dump the tree if any + // draw-relevant issue fired during this scope cycle, then reset the flag. + if (debugSawDrawIssue) + DebugDumpTree(); + debugSawDrawIssue = false; + return; + } + // Queue-poll fallback for older Windows without ID3D12InfoQueue1. + FlushDebugMessages(); + } + + /// + /// Synchronous callback invoked by the D3D12 debug layer (ID3D12InfoQueue1) on the thread + /// that triggered the validation message. Logs with the active scope leaf as prefix and + /// flags relevant categories so the next DrainDebugMessages dumps the scope tree. + /// + [System.Runtime.InteropServices.UnmanagedCallersOnly(CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })] + private static void OnDebugMessageCallback(MessageCategory category, MessageSeverity severity, MessageID id, byte* description, void* context) + { + if (context is null) return; + var handle = GCHandle.FromIntPtr((IntPtr)context); + if (handle.Target is not GraphicsDevice device) return; + + var desc = Marshal.PtrToStringAnsi((IntPtr)description) ?? "(no description)"; + var scope = device.debugScopeStack.Count > 0 ? $"[{device.debugScopeStack.Peek()}]: " : ""; + bool isDrawCategory = category is MessageCategory.StateSetting + or MessageCategory.Execution + or MessageCategory.ResourceManipulation; + + // Attribute to the active leaf so the tree dump can flag exactly which scope fired + // — particularly useful when several scopes share a name (e.g. ImageMultiScaler's + // chain of "Down2" passes). + var leaf = device.debugCurrentFrame; + + switch (severity) + { + case MessageSeverity.Corruption: + case MessageSeverity.Error: + DebugLog.Error($"{scope}{desc}"); + if (leaf is not null) leaf.Errors++; + if (isDrawCategory) device.debugSawDrawIssue = true; + break; + case MessageSeverity.Warning: + DebugLog.Warning($"{scope}{desc}"); + if (leaf is not null) leaf.Warnings++; + if (isDrawCategory) device.debugSawDrawIssue = true; + break; + } + } /// /// Drains all pending D3D12 debug messages from the InfoQueue and logs them. + /// When the ID3D12InfoQueue1 callback is active, the callback is the authoritative + /// logger and tree-dump trigger — we just clear the queue here so messages don't + /// accumulate (they'd otherwise be reported a second time with mid-frame attribution). /// internal void FlushDebugMessages() { if (nativeInfoQueue is null) return; + if (nativeInfoQueue1 is not null) + { + nativeInfoQueue->ClearStoredMessages(); + return; + } + var numMessages = nativeInfoQueue->GetNumStoredMessages(); bool sawDrawIssue = false; for (ulong i = 0; i < numMessages; i++) diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs index 3a7fbb0d4e..ba633f21cf 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -57,19 +57,21 @@ internal void PopDebugScope() debugCurrentFrame.ClosedByPop = true; debugCurrentFrame = debugCurrentFrame.Parent; } + } - // Drain pending debug messages once per frame when the outermost scope closes. With - // queue-poll backends (D3D12 InfoQueue, D3D11 InfoQueue) this is the cleanest moment: - // the scope tree is fully built and there's no active scope to mislead the annotation. - // Until ID3D12InfoQueue1 callback mode lands, we accept the latency vs precision trade. - if (IsDebugMode && debugScopeStack.Count == 0) - { - DrainDebugMessages(); - // Always reset — drain only clears the tree if it dumped (errors fired). For clean - // frames the tree would accumulate across frames otherwise. Works headlessly too. - debugTreeRoot = null; - debugCurrentFrame = null; - } + /// + /// Marks the end of the rendering frame. Called by the game loop after the frame's + /// command lists have been submitted (so per-CL counter aggregation has already merged + /// into the tree) and before Present. Drains backend debug messages, dumps the + /// scope tree if any error fired, then resets the tree for the next frame. + /// + internal void DebugEndFrame() + { + if (!IsDebugMode) + return; + DrainDebugMessages(); + debugTreeRoot = null; + debugCurrentFrame = null; } /// @@ -148,9 +150,15 @@ internal void DebugDumpTree() private static void AppendTree(StringBuilder sb, DebugScopeFrame frame, int depth) { sb.Append(' ', depth * 2); + // Visual marker so offending scopes pop out at a glance when scanning the tree. + if (frame.Errors > 0) + sb.Append("[!] "); + else if (frame.Warnings > 0) + sb.Append("[?] "); sb.Append(frame.Name ?? "(unnamed)"); - bool any = (frame.Draws | frame.Dispatches | frame.Clears | frame.Copies | frame.Barriers) != 0 + bool any = (frame.Draws | frame.Dispatches | frame.Clears | frame.Copies | frame.Barriers + | frame.Errors | frame.Warnings) != 0 || frame.ExecutedCLs > 1; if (any) { @@ -163,6 +171,8 @@ void AppendStat(string key, int v) sb.Append(key).Append('=').Append(v); first = false; } + AppendStat("Errors", frame.Errors); + AppendStat("Warnings", frame.Warnings); AppendStat("Draws", frame.Draws); AppendStat("Dispatches", frame.Dispatches); AppendStat("Clears", frame.Clears); From 6d0d8d7c444a163675e698a95ca201b2eefe3536 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 12:51:33 +0900 Subject: [PATCH 1162/1182] graphics: Vulkan scope-tree breadcrumbs + D3D12 polish graphics: revert SetMuteDebugOutput, also gates the callback path --- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 20 +++++------- .../GraphicsDevice.DebugScope.cs | 13 ++++++++ .../Vulkan/CommandList.Vulkan.cs | 14 ++++++++ .../Vulkan/GraphicsAdapterFactory.Vulkan.cs | 32 +++++++++++++++++-- .../Vulkan/GraphicsDevice.Vulkan.cs | 28 ++++++++++++++++ 5 files changed, 92 insertions(+), 15 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 06f7f2ab1b..a6c747ea0b 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -39,7 +39,6 @@ public unsafe partial class GraphicsDevice private GCHandle debugMessageContext; // Set by the callback when a draw-relevant validation message arrives within a scope. // Consumed by DrainDebugMessages at the next scope-empty transition. - private bool debugSawDrawIssue; /// /// Concurrent pool for lists of Graphics Resources that are used for staging operations. @@ -907,7 +906,8 @@ private static void OnDebugMessageCallback(MessageCategory category, MessageSeve if (handle.Target is not GraphicsDevice device) return; var desc = Marshal.PtrToStringAnsi((IntPtr)description) ?? "(no description)"; - var scope = device.debugScopeStack.Count > 0 ? $"[{device.debugScopeStack.Peek()}]: " : ""; + var leafName = device.GetDebugLeafScopeName(); + var scope = leafName is not null ? $"[{leafName}]: " : ""; bool isDrawCategory = category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; @@ -978,7 +978,12 @@ internal void FlushDebugMessages() or MessageCategory.Execution or MessageCategory.ResourceManipulation; - var prefix = isDrawCategory ? GetDrainTimeScopePrefix() : null; + string prefix = null; + if (isDrawCategory) + { + var leafName = GetDebugLeafScopeName(); + prefix = leafName is not null ? $"[{leafName}]: " : null; + } switch (message->Severity) { @@ -1001,15 +1006,6 @@ or MessageCategory.Execution nativeInfoQueue->ClearStoredMessages(); } - /// - /// Returns a "[scope]: " prefix for log messages — the leaf of the active scope stack. - /// The full path is in the tree dump's "Active scope:" line; per-message we keep it short. - /// - private string GetDrainTimeScopePrefix() - { - if (debugScopeStack.Count == 0) return ""; - return $"[{debugScopeStack.Peek()}]: "; - } /// /// Logs DRED (Device Removed Extended Data) information after a device removal event. diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs index ba633f21cf..bc85cfde82 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -30,6 +30,12 @@ public partial class GraphicsDevice private DebugScopeFrame debugTreeRoot; private DebugScopeFrame debugCurrentFrame; + /// + /// Set by backend message callbacks/poll loops when a draw-relevant validation issue + /// fires during the current frame. Cleared after dump in . + /// + internal bool debugSawDrawIssue; + /// /// Pushes a scope onto the active scope stack. Backend BeginProfile implementations call /// this. Tier 1 (stack) is always maintained; Tier 2 (tree) only when IsDebugMode is set. @@ -83,6 +89,13 @@ internal void DebugEndFrame() /// The currently-open scope frame, or if no scope is active. internal DebugScopeFrame GetDebugCurrentFrame() => debugCurrentFrame; + /// + /// Name of the innermost active scope, or if no scope is active. + /// Used as a short prefix on individual log messages; + /// gives the full root→leaf path for the tree dump's footer. + /// + internal string GetDebugLeafScopeName() => debugScopeStack.Count > 0 ? debugScopeStack.Peek() : null; + /// /// Returns the active scope path (root → leaf) as a single string, or /// if no scope is active. Used for annotating validation messages. diff --git a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs index af3f3c01c7..83c2b5867f 100644 --- a/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs @@ -83,6 +83,7 @@ public unsafe partial void Reset() // New command list ID so resources know they need to re-issue barriers CommandListId = System.Threading.Interlocked.Increment(ref GraphicsDevice.NextCommandListId); + DebugScopeResetForNewRecording(); CleanupRenderPass(); boundDescriptorSets.Clear(); currentCbLayouts.Clear(); @@ -290,6 +291,8 @@ private unsafe partial void SetScissorRectanglesImpl(ReadOnlySpan sci /// Cannot GraphicsDevice.Draw*() without an effect being previously applied with Effect.Apply() method private unsafe void PrepareDraw() { + RecordDebugCounter(DebugCounterKind.Draw); + // Transition resources to correct layouts before starting the render pass TransitionBoundResources(); @@ -582,6 +585,8 @@ public void SetIndexBuffer(Buffer buffer, int offset, bool is32bits) // to emit precise barriers. Not currently hit by the engine's rendering pipeline. public unsafe void ResourceBarrierTransition(GraphicsResource resource, BarrierLayout newLayout, uint subresource = uint.MaxValue) { + RecordDebugCounter(DebugCounterKind.Barrier); + if (resource is Texture texture) { if (texture.ParentTexture != null) @@ -692,6 +697,7 @@ public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets) /// public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) { + RecordDebugCounter(DebugCounterKind.Dispatch); CleanupRenderPass(); TransitionBoundResources(); BindPipeline(); @@ -706,6 +712,7 @@ public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) /// The offset information bytes. public void Dispatch(Buffer indirectBuffer, int offsetInBytes) { + RecordDebugCounter(DebugCounterKind.Dispatch); CleanupRenderPass(); TransitionBoundResources(); BindPipeline(); @@ -836,6 +843,7 @@ public void DrawInstanced(Buffer argumentsBuffer, int alignedByteOffsetForArgs = /// The name. public unsafe void BeginProfile(Color4 profileColor, string name) { + GraphicsDevice.PushDebugScope(name); if (GraphicsDevice.IsProfilingSupported) { var bytes = System.Text.Encoding.ASCII.GetBytes(name); @@ -858,6 +866,7 @@ public unsafe void BeginProfile(Color4 profileColor, string name) /// public void EndProfile() { + GraphicsDevice.PopDebugScope(); if (GraphicsDevice.IsProfilingSupported) { GraphicsDevice.NativeDeviceApi.vkCmdDebugMarkerEndEXT(currentCommandList.NativeCommandBuffer); @@ -888,6 +897,7 @@ public void ResetQueryPool(QueryPool queryPool) /// public unsafe void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0) { + RecordDebugCounter(DebugCounterKind.Clear); // Barriers need to be global to command buffer CleanupRenderPass(); @@ -923,6 +933,7 @@ public unsafe void Clear(Texture depthStencilBuffer, DepthStencilClearOptions op /// renderTarget public unsafe void Clear(Texture renderTarget, Color4 color) { + RecordDebugCounter(DebugCounterKind.Clear); // TODO VULKAN: Detect if inside render pass. If so, NativeCommandBuffer.ClearAttachments() // Barriers need to be global to command buffer CleanupRenderPass(); @@ -1019,6 +1030,7 @@ public unsafe void ClearReadWrite(Texture texture, UInt4 value) private unsafe void ClearReadWriteImpl(Texture texture, VkClearColorValue clearValue) { ArgumentNullException.ThrowIfNull(texture); + RecordDebugCounter(DebugCounterKind.Clear); CleanupRenderPass(); var clearRange = texture.NativeResourceRange; @@ -1033,6 +1045,7 @@ private unsafe void ClearReadWriteImpl(Texture texture, VkClearColorValue clearV public unsafe void Copy(GraphicsResource source, GraphicsResource destination) { + RecordDebugCounter(DebugCounterKind.Copy); // TODO VULKAN: One copy per mip level if (source is Texture sourceTexture && destination is Texture destinationTexture) @@ -1231,6 +1244,7 @@ public void CopyMultisample(Texture sourceMultisampleTexture, int sourceSubResou public unsafe void CopyRegion(GraphicsResource source, int sourceSubresource, ResourceRegion? sourceRegion, GraphicsResource destination, int destinationSubResource, int dstX = 0, int dstY = 0, int dstZ = 0) { + RecordDebugCounter(DebugCounterKind.Copy); // TODO VULKAN: One copy per mip level if (source is Texture sourceTexture && destination is Texture destinationTexture) diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs index 8e7a77ddf8..72781ce664 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs @@ -281,16 +281,42 @@ private static VkUtf8String GetPlatformRelatedSurfaceExtensionName(HashSetpMessage).ToString(); - Debug.WriteLine($"[Vulkan] {severity}: {message}"); + + // If a GraphicsDevice is active in debug mode, route through its scope-aware logger + // so messages get a "[scope]:" prefix and the leaf gets attribution. Validation + + // Performance categories are draw-relevant; General is mostly init/shutdown noise. + var device = GraphicsDevice.DebugMessengerDevice; + bool isDrawCategory = (types & (VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance)) != 0; + string scopePrefix = ""; + DebugScopeFrame leaf = null; + if (device is not null) + { + leaf = device.GetDebugCurrentFrame(); + var leafName = device.GetDebugLeafScopeName(); + if (leafName is not null) + scopePrefix = $"[{leafName}]: "; + } if (severity >= VkDebugUtilsMessageSeverityFlagsEXT.Error) - Log.Error($"[Vulkan] {message}"); + { + GraphicsDevice.DebugLog.Error($"[Vulkan] {scopePrefix}{message}"); + if (leaf is not null) leaf.Errors++; + if (device is not null && isDrawCategory) device.debugSawDrawIssue = true; + } else if (severity >= VkDebugUtilsMessageSeverityFlagsEXT.Warning) - Log.Warning($"[Vulkan] {message}"); + { + GraphicsDevice.DebugLog.Warning($"[Vulkan] {scopePrefix}{message}"); + if (leaf is not null) leaf.Warnings++; + if (device is not null && isDrawCategory) device.debugSawDrawIssue = true; + } else if (severity >= VkDebugUtilsMessageSeverityFlagsEXT.Info) + { Log.Info($"[Vulkan] {message}"); + } else + { Log.Debug($"[Vulkan] {message}"); + } return VK_FALSE; } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs index 8229499d55..f9e96b2684 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs @@ -33,6 +33,11 @@ public partial class GraphicsDevice private bool simulateReset = false; private string rendererName; + // The instance-level VK_EXT_debug_utils messenger doesn't know which device a validation + // message belongs to, so we keep a single weak reference and route through it. Stride + // typically runs one device; multi-device debugging would need per-device messengers. + internal static GraphicsDevice DebugMessengerDevice; + private VkDevice nativeDevice; private VkDeviceApi nativeDeviceApi; internal VkQueue NativeCommandQueue; @@ -292,6 +297,12 @@ public unsafe void ExecuteCommandLists(int count, CompiledCommandList[] commandL }; CheckResult(NativeDeviceApi.vkQueueSubmit(NativeCommandQueue, 1, &submitInfo, VkFence.Null)); + + if (IsDebugMode) + { + for (int i = 0; i < count; i++) + DebugAggregateLocalCounters(commandLists[i].Builder.DebugScopeExtractLocalCounters()); + } } // Collect resources @@ -315,6 +326,17 @@ internal void CheckResult(VkResult vkResult, [CallerArgumentExpression("vkResult /// private unsafe partial void InitializePostFeatures() { + if (IsDebugMode) + DebugMessengerDevice = this; + } + + // Vulkan messages fire synchronously through the messenger callback, which logs them + // inline. End-of-frame drain just dumps the scope tree if anything fired. + partial void DrainDebugMessages() + { + if (debugSawDrawIssue) + DebugDumpTree(); + debugSawDrawIssue = false; } private partial string GetRendererName() => rendererName; @@ -659,6 +681,9 @@ protected partial void DestroyPlatformDevice() private unsafe void ReleaseDevice() { + if (ReferenceEquals(DebugMessengerDevice, this)) + DebugMessengerDevice = null; + EmptyTexelBufferInt.Dispose(); EmptyTexelBufferInt = null; EmptyTexelBufferFloat.Dispose(); @@ -749,6 +774,9 @@ internal unsafe ulong ExecuteCommandListInternal(CompiledCommandList commandList }; CheckResult(NativeDeviceApi.vkQueueSubmit(NativeCommandQueue, 1, &submitInfo, VkFence.Null)); + + if (IsDebugMode) + DebugAggregateLocalCounters(commandList.Builder.DebugScopeExtractLocalCounters()); } // Collect resources From 6d4f976cd45a4bc9eac45ca25876d77dc2f7b9ce Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 12:57:48 +0900 Subject: [PATCH 1163/1182] graphics: D3D11 scope-tree breadcrumbs + counter recording --- .../Direct3D11/CommandList.Direct3D11.cs | 21 ++++++++-- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 42 +++++++++++++++++-- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs index a79e99df5b..c680e52755 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs @@ -539,8 +539,9 @@ internal void UnsetUnorderedAccessView(GraphicsResource unorderedAccessView) /// /// This method is called before each Draw() method to setup the correct Viewport. /// - private void PrepareDraw() + private void PrepareDraw(bool isDispatch = false) { + RecordDebugCounter(isDispatch ? DebugCounterKind.Dispatch : DebugCounterKind.Draw); SetViewportImpl(); } @@ -687,7 +688,7 @@ public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets) /// Number of thread groups in the Z dimension. public void Dispatch(int threadCountX, int threadCountY, int threadCountZ) { - PrepareDraw(); // TODO: PrepareDraw for Compute dispatch? + PrepareDraw(isDispatch: true); // TODO: PrepareDraw for Compute dispatch? nativeDeviceContext->Dispatch((uint) threadCountX, (uint) threadCountY, (uint) threadCountZ); } @@ -706,7 +707,7 @@ public void Dispatch(Buffer indirectBuffer, int offsetInBytes) { ArgumentNullException.ThrowIfNull(indirectBuffer); - PrepareDraw(); // TODO: PrepareDraw for Compute dispatch? + PrepareDraw(isDispatch: true); // TODO: PrepareDraw for Compute dispatch? nativeDeviceContext->DispatchIndirect(indirectBuffer.NativeBuffer, (uint) offsetInBytes); } @@ -862,6 +863,7 @@ public void WriteTimestamp(QueryPool queryPool, int index) /// public void BeginProfile(Color4 profileColor, string name) { + GraphicsDevice.PushDebugScope(name); // TODO: We only initialize `nativeDeviceProfiler` in debug mode. Should BeginProfile() check this? if (IsDebugMode) nativeDeviceProfiler->BeginEvent(name); @@ -873,6 +875,7 @@ public void BeginProfile(Color4 profileColor, string name) /// public void EndProfile() { + GraphicsDevice.PopDebugScope(); // TODO: We only initialize `nativeDeviceProfiler` in debug mode. Should BeginProfile() check this? if (IsDebugMode) nativeDeviceProfiler->EndEvent(); @@ -892,6 +895,7 @@ public void EndProfile() public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, float depth = 1, byte stencil = 0) { ArgumentNullException.ThrowIfNull(depthStencilBuffer); + RecordDebugCounter(DebugCounterKind.Clear); var flags = options.HasFlag(DepthStencilClearOptions.DepthBuffer) ? ClearFlag.Depth : 0; @@ -916,6 +920,7 @@ public void Clear(Texture depthStencilBuffer, DepthStencilClearOptions options, public void Clear(Texture renderTarget, Color4 color) { ArgumentNullException.ThrowIfNull(renderTarget); + RecordDebugCounter(DebugCounterKind.Clear); scoped Span colorFloats = color.AsSpan(elementCount: 4); nativeDeviceContext->ClearRenderTargetView(renderTarget.NativeRenderTargetView, ref colorFloats.GetReference()); @@ -931,6 +936,7 @@ public void Clear(Texture renderTarget, Color4 color) public unsafe void ClearReadWrite(Buffer buffer, Vector4 value) { ArgumentNullException.ThrowIfNull(buffer); + RecordDebugCounter(DebugCounterKind.Clear); if (buffer.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Buffer supporting UAV", nameof(buffer)); @@ -948,6 +954,7 @@ public unsafe void ClearReadWrite(Buffer buffer, Vector4 value) public unsafe void ClearReadWrite(Buffer buffer, Int4 value) { ArgumentNullException.ThrowIfNull(buffer); + RecordDebugCounter(DebugCounterKind.Clear); if (buffer.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Buffer supporting UAV", nameof(buffer)); @@ -965,6 +972,7 @@ public unsafe void ClearReadWrite(Buffer buffer, Int4 value) public unsafe void ClearReadWrite(Buffer buffer, UInt4 value) { ArgumentNullException.ThrowIfNull(buffer); + RecordDebugCounter(DebugCounterKind.Clear); if (buffer.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Buffer supporting UAV", nameof(buffer)); @@ -982,6 +990,7 @@ public unsafe void ClearReadWrite(Buffer buffer, UInt4 value) public unsafe void ClearReadWrite(Texture texture, Vector4 value) { ArgumentNullException.ThrowIfNull(texture); + RecordDebugCounter(DebugCounterKind.Clear); if (texture.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Texture supporting UAV", nameof(texture)); @@ -999,6 +1008,7 @@ public unsafe void ClearReadWrite(Texture texture, Vector4 value) public unsafe void ClearReadWrite(Texture texture, Int4 value) { ArgumentNullException.ThrowIfNull(texture); + RecordDebugCounter(DebugCounterKind.Clear); if (texture.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Texture supporting UAV", nameof(texture)); @@ -1016,6 +1026,7 @@ public unsafe void ClearReadWrite(Texture texture, Int4 value) public unsafe void ClearReadWrite(Texture texture, UInt4 value) { ArgumentNullException.ThrowIfNull(texture); + RecordDebugCounter(DebugCounterKind.Clear); if (texture.NativeUnorderedAccessView.IsNull()) throw new ArgumentException("Expecting a Texture supporting UAV", nameof(texture)); @@ -1035,6 +1046,7 @@ public void Copy(GraphicsResource source, GraphicsResource destination) { ArgumentNullException.ThrowIfNull(source); ArgumentNullException.ThrowIfNull(destination); + RecordDebugCounter(DebugCounterKind.Copy); nativeDeviceContext->CopyResource(destination.NativeResource, source.NativeResource); } @@ -1100,6 +1112,7 @@ public void CopyMultisample(Texture sourceMultiSampledTexture, int sourceSubReso { ArgumentNullException.ThrowIfNull(sourceMultiSampledTexture); ArgumentNullException.ThrowIfNull(destinationTexture); + RecordDebugCounter(DebugCounterKind.Copy); if (!sourceMultiSampledTexture.IsMultiSampled) throw new ArgumentException("Source Texture is not a MSAA Texture", nameof(sourceMultiSampledTexture)); @@ -1165,6 +1178,7 @@ public void CopyRegion(GraphicsResource source, int sourceSubResourceIndex, Reso { ArgumentNullException.ThrowIfNull(source); ArgumentNullException.ThrowIfNull(destination); + RecordDebugCounter(DebugCounterKind.Copy); if (sourceRegion is ResourceRegion srcResourceRegion) { @@ -1203,6 +1217,7 @@ public void CopyCount(Buffer sourceBuffer, Buffer destinationBuffer, int destina { ArgumentNullException.ThrowIfNull(sourceBuffer); ArgumentNullException.ThrowIfNull(destinationBuffer); + RecordDebugCounter(DebugCounterKind.Copy); nativeDeviceContext->CopyStructureCount(destinationBuffer.NativeBuffer, (uint) destinationOffsetInBytes, sourceBuffer.NativeUnorderedAccessView); } diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index ed88d9050c..e30cf826d3 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -480,17 +480,34 @@ private void OnDeviceInfoQueueMessage(ref readonly Message message) var descriptionSpan = new ReadOnlySpan(message.PDescription, (int) message.DescriptionByteLength); var description = descriptionSpan.GetString(); - Debug.WriteLine($"D3D11: {message.Severity} {description}"); + // Drain happens after the call that fired the message (D3D11 has no callback API). + // The current leaf might be wrong if scopes changed between fire and drain — we use + // it best-effort. Render-hot paths drain at end-of-frame, so attribution works for + // errors that fire near the end of a scope and stay open for the dump. + bool isDrawCategory = message.Category is MessageCategory.StateSetting + or MessageCategory.Execution + or MessageCategory.ResourceManipulation; + string scopePrefix = ""; + DebugScopeFrame leaf = null; + if (isDrawCategory) + { + leaf = GetDebugCurrentFrame(); + var leafName = GetDebugLeafScopeName(); + if (leafName is not null) scopePrefix = $"[{leafName}]: "; + } - // Log warnings and errors to Stride logger switch (message.Severity) { case MessageSeverity.Corruption: case MessageSeverity.Error: - Log.Error($"[D3D11] {message.Severity}: {description}"); + DebugLog.Error($"[D3D11] {scopePrefix}{description}"); + if (leaf is not null) leaf.Errors++; + if (isDrawCategory) debugSawDrawIssue = true; break; case MessageSeverity.Warning: - Log.Warning($"[D3D11] {description}"); + DebugLog.Warning($"[D3D11] {scopePrefix}{description}"); + if (leaf is not null) leaf.Warnings++; + if (isDrawCategory) debugSawDrawIssue = true; break; } @@ -539,6 +556,23 @@ void ProcessMessage(ulong index) } } + // Backend implementation of the partial method declared in GraphicsDevice.DebugScope.cs; + // called once per frame from DebugEndFrame. D3D11 has no synchronous-callback equivalent + // of ID3D12InfoQueue1, so we poll the InfoQueue here. Aggregation of the immediate CL's + // localCounters runs first so the tree has data when the dump fires. + partial void DrainDebugMessages() + { + if (InternalMainCommandList is not null) + DebugAggregateLocalCounters(InternalMainCommandList.DebugScopeExtractLocalCounters()); + + if (nativeInfoQueue is not null) + ProcessInfoQueueMessages(); + + if (debugSawDrawIssue) + DebugDumpTree(); + debugSawDrawIssue = false; + } + /// /// Represents a method that handles messages related to Graphics Device information. /// From 5e19862dbea2b5c5ee7b14a70c6a9a6a869a8781 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 14:19:34 +0900 Subject: [PATCH 1164/1182] graphics: D3D11 per-scope drain for leaf attribution + DebugAlwaysDumpTree toggle --- .../Direct3D11/CommandList.Direct3D11.cs | 10 ++++++++++ .../Direct3D11/GraphicsDevice.Direct3D11.cs | 9 +++++---- .../Stride.Graphics/GraphicsDevice.DebugScope.cs | 10 ++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs index c680e52755..11e29bae27 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/CommandList.Direct3D11.cs @@ -863,6 +863,13 @@ public void WriteTimestamp(QueryPool queryPool, int index) /// public void BeginProfile(Color4 profileColor, string name) { + // Drain the InfoQueue before the scope state changes so any messages queued since + // the last scope transition are attributed to the still-current leaf. D3D11's + // CPU-side validator fires synchronously with the API call, so this is exact. + // (GPU-based validation, if ever enabled, would defer messages and break this — see + // OnDeviceInfoQueueMessage's note.) + if (GraphicsDevice.IsDebugMode) + GraphicsDevice.ProcessInfoQueueMessages(); GraphicsDevice.PushDebugScope(name); // TODO: We only initialize `nativeDeviceProfiler` in debug mode. Should BeginProfile() check this? if (IsDebugMode) @@ -875,6 +882,9 @@ public void BeginProfile(Color4 profileColor, string name) /// public void EndProfile() { + // Drain before pop so the closing scope is still the leaf — see BeginProfile note. + if (GraphicsDevice.IsDebugMode) + GraphicsDevice.ProcessInfoQueueMessages(); GraphicsDevice.PopDebugScope(); // TODO: We only initialize `nativeDeviceProfiler` in debug mode. Should BeginProfile() check this? if (IsDebugMode) diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index e30cf826d3..0a791fd497 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -480,10 +480,11 @@ private void OnDeviceInfoQueueMessage(ref readonly Message message) var descriptionSpan = new ReadOnlySpan(message.PDescription, (int) message.DescriptionByteLength); var description = descriptionSpan.GetString(); - // Drain happens after the call that fired the message (D3D11 has no callback API). - // The current leaf might be wrong if scopes changed between fire and drain — we use - // it best-effort. Render-hot paths drain at end-of-frame, so attribution works for - // errors that fire near the end of a scope and stay open for the dump. + // D3D11 has no synchronous-callback API. CPU-side validation is synchronous with the + // API call, so as long as we drain at every scope transition (BeginProfile/EndProfile) + // the leaf at drain time matches the leaf at message time. If GPU-based validation is + // ever enabled (D3D11_GPU_BASED_VALIDATION), GBV messages arrive asynchronously and + // would be misattributed — we'd need to detect that mode and skip per-leaf increments. bool isDrawCategory = message.Category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs index bc85cfde82..f05dc0e5a2 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -71,10 +71,20 @@ internal void PopDebugScope() /// into the tree) and before Present. Drains backend debug messages, dumps the /// scope tree if any error fired, then resets the tree for the next frame. /// + /// + /// Test toggle: when , the scope tree is dumped every frame even + /// if no validation issue fired. Useful for verifying counter values (e.g. CLs=N + /// parallelism markers) against a known-clean scene. Off by default; flip it from a + /// breakpoint or a debug-only command for ad-hoc inspection. + /// + internal static bool DebugAlwaysDumpTree; + internal void DebugEndFrame() { if (!IsDebugMode) return; + if (DebugAlwaysDumpTree) + debugSawDrawIssue = true; DrainDebugMessages(); debugTreeRoot = null; debugCurrentFrame = null; From 1ba3f2705b15f1f0541370f79021be717245a2b4 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 14:32:06 +0900 Subject: [PATCH 1165/1182] graphics: DebugGpuValidationEnabled flag, skip leaf attribution for async GPU validation --- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 7 ++++--- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 11 ++++++++--- .../Stride.Graphics/GraphicsDevice.DebugScope.cs | 11 +++++++++++ .../Vulkan/GraphicsAdapterFactory.Vulkan.cs | 6 +++++- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index 0a791fd497..c73a7f0c44 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -483,14 +483,15 @@ private void OnDeviceInfoQueueMessage(ref readonly Message message) // D3D11 has no synchronous-callback API. CPU-side validation is synchronous with the // API call, so as long as we drain at every scope transition (BeginProfile/EndProfile) // the leaf at drain time matches the leaf at message time. If GPU-based validation is - // ever enabled (D3D11_GPU_BASED_VALIDATION), GBV messages arrive asynchronously and - // would be misattributed — we'd need to detect that mode and skip per-leaf increments. + // turned on (DebugGpuValidationEnabled = true), GBV messages arrive asynchronously + // via the InfoQueue at fence completion — skip leaf attribution in that mode. bool isDrawCategory = message.Category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; + bool attributable = isDrawCategory && !DebugGpuValidationEnabled; string scopePrefix = ""; DebugScopeFrame leaf = null; - if (isDrawCategory) + if (attributable) { leaf = GetDebugCurrentFrame(); var leafName = GetDebugLeafScopeName(); diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index a6c747ea0b..2efed2139f 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -906,16 +906,21 @@ private static void OnDebugMessageCallback(MessageCategory category, MessageSeve if (handle.Target is not GraphicsDevice device) return; var desc = Marshal.PtrToStringAnsi((IntPtr)description) ?? "(no description)"; - var leafName = device.GetDebugLeafScopeName(); - var scope = leafName is not null ? $"[{leafName}]: " : ""; bool isDrawCategory = category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; + // GPU-based validation messages arrive asynchronously — the active scope at callback + // time isn't the one that issued the offending command. Skip leaf attribution and + // scope prefix in that mode to avoid misleading the user. + bool attributable = !device.DebugGpuValidationEnabled; + var leafName = attributable ? device.GetDebugLeafScopeName() : null; + var scope = leafName is not null ? $"[{leafName}]: " : ""; + // Attribute to the active leaf so the tree dump can flag exactly which scope fired // — particularly useful when several scopes share a name (e.g. ImageMultiScaler's // chain of "Down2" passes). - var leaf = device.debugCurrentFrame; + var leaf = attributable ? device.debugCurrentFrame : null; switch (severity) { diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs index f05dc0e5a2..a5c0215ad9 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -36,6 +36,17 @@ public partial class GraphicsDevice /// internal bool debugSawDrawIssue; + /// + /// When , the backend has GPU-side validation enabled + /// (D3D11/D3D12 GPU-based validation, Vulkan GPU-Assisted Validation). Messages from + /// those modes arrive asynchronously to recording, so per-leaf scope attribution is + /// unreliable. Backends should skip leaf Errors/Warnings increments and the + /// [scope]: log prefix when this is set, but still log the message and dump the + /// tree. Defaults to — Stride doesn't enable any of those modes + /// today. + /// + public bool DebugGpuValidationEnabled { get; set; } + /// /// Pushes a scope onto the active scope stack. Backend BeginProfile implementations call /// this. Tier 1 (stack) is always maintained; Tier 2 (tree) only when IsDebugMode is set. diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs index 72781ce664..3115fab78d 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs @@ -287,9 +287,13 @@ private unsafe static uint DebugReport(VkDebugUtilsMessageSeverityFlagsEXT sever // Performance categories are draw-relevant; General is mostly init/shutdown noise. var device = GraphicsDevice.DebugMessengerDevice; bool isDrawCategory = (types & (VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance)) != 0; + // GPU-Assisted Validation messages arrive on a worker thread after the GPU completes + // the offending draw — scope attribution is meaningless. Skip prefix/leaf bumps when + // that mode is on; the tree dump still fires from the draw-issue flag below. + bool attributable = device is not null && !device.DebugGpuValidationEnabled; string scopePrefix = ""; DebugScopeFrame leaf = null; - if (device is not null) + if (attributable) { leaf = device.GetDebugCurrentFrame(); var leafName = device.GetDebugLeafScopeName(); From 34682f2b407108cce05c5a36b645cbaaf8788c7d Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Thu, 30 Apr 2026 17:02:14 +0900 Subject: [PATCH 1166/1182] graphics: per-message GBV detection, suppress tree dump for GBV-only frames --- .../Direct3D11/GraphicsDevice.Direct3D11.cs | 31 ++++++++++---- .../Direct3D12/GraphicsDevice.Direct3D12.cs | 40 ++++++++++++++----- .../GraphicsDevice.DebugScope.cs | 13 +++--- .../Vulkan/GraphicsAdapterFactory.Vulkan.cs | 22 +++++++--- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs index c73a7f0c44..07410c1f52 100644 --- a/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs +++ b/sources/engine/Stride.Graphics/Direct3D11/GraphicsDevice.Direct3D11.cs @@ -40,6 +40,23 @@ public unsafe partial class GraphicsDevice private ID3D11InfoQueue* nativeInfoQueue; + // GBV message IDs from D3D11_MESSAGE_ID, populated lazily via reflection so the scan + // only runs in debug mode (InfoQueue draining never happens in release → Value is + // never queried). Robust against SDK additions to the GBV enum range. + private static readonly Lazy> gbvMessageIds = new(BuildGbvMessageIdSet); + + private static System.Collections.Generic.HashSet BuildGbvMessageIdSet() + { + var set = new System.Collections.Generic.HashSet(); + foreach (var name in Enum.GetNames()) + { + if (name.Contains("Gpubased", StringComparison.OrdinalIgnoreCase) + && Enum.TryParse(name, out var id)) + set.Add(id); + } + return set; + } + /// /// Gets the internal Direct3D 11 Device. /// @@ -481,14 +498,14 @@ private void OnDeviceInfoQueueMessage(ref readonly Message message) var description = descriptionSpan.GetString(); // D3D11 has no synchronous-callback API. CPU-side validation is synchronous with the - // API call, so as long as we drain at every scope transition (BeginProfile/EndProfile) - // the leaf at drain time matches the leaf at message time. If GPU-based validation is - // turned on (DebugGpuValidationEnabled = true), GBV messages arrive asynchronously - // via the InfoQueue at fence completion — skip leaf attribution in that mode. + // API call, so draining at every BeginProfile/EndProfile gives accurate leaf + // attribution. GBV messages arrive asynchronously and we detect them by ID via the + // reflection-built set. DebugGpuValidationEnabled is the kill-switch override. bool isDrawCategory = message.Category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; - bool attributable = isDrawCategory && !DebugGpuValidationEnabled; + bool isGbv = DebugGpuValidationEnabled || gbvMessageIds.Value.Contains(message.ID); + bool attributable = isDrawCategory && !isGbv; string scopePrefix = ""; DebugScopeFrame leaf = null; if (attributable) @@ -504,12 +521,12 @@ or MessageCategory.Execution case MessageSeverity.Error: DebugLog.Error($"[D3D11] {scopePrefix}{description}"); if (leaf is not null) leaf.Errors++; - if (isDrawCategory) debugSawDrawIssue = true; + if (attributable) debugSawDrawIssue = true; break; case MessageSeverity.Warning: DebugLog.Warning($"[D3D11] {scopePrefix}{description}"); if (leaf is not null) leaf.Warnings++; - if (isDrawCategory) debugSawDrawIssue = true; + if (attributable) debugSawDrawIssue = true; break; } diff --git a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs index 2efed2139f..0a57e94887 100644 --- a/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs +++ b/sources/engine/Stride.Graphics/Direct3D12/GraphicsDevice.Direct3D12.cs @@ -40,6 +40,23 @@ public unsafe partial class GraphicsDevice // Set by the callback when a draw-relevant validation message arrives within a scope. // Consumed by DrainDebugMessages at the next scope-empty transition. + // GBV message IDs from D3D12_MESSAGE_ID, populated lazily via reflection so the scan + // only runs in debug mode (callback never fires in release → Value is never queried). + // Robust against SDK additions to the GBV enum range. + private static readonly Lazy> gbvMessageIds = new(BuildGbvMessageIdSet); + + private static System.Collections.Generic.HashSet BuildGbvMessageIdSet() + { + var set = new System.Collections.Generic.HashSet(); + foreach (var name in Enum.GetNames()) + { + if (name.Contains("Gpubased", StringComparison.OrdinalIgnoreCase) + && Enum.TryParse(name, out var id)) + set.Add(id); + } + return set; + } + /// /// Concurrent pool for lists of Graphics Resources that are used for staging operations. /// @@ -910,10 +927,11 @@ private static void OnDebugMessageCallback(MessageCategory category, MessageSeve or MessageCategory.Execution or MessageCategory.ResourceManipulation; - // GPU-based validation messages arrive asynchronously — the active scope at callback - // time isn't the one that issued the offending command. Skip leaf attribution and - // scope prefix in that mode to avoid misleading the user. - bool attributable = !device.DebugGpuValidationEnabled; + // GBV messages arrive asynchronously, so leaf attribution would be wrong. We detect + // them by ID via the reflection-built set. The DebugGpuValidationEnabled override + // is a kill switch for cases the heuristic misses. + bool isGbv = device.DebugGpuValidationEnabled || gbvMessageIds.Value.Contains(id); + bool attributable = !isGbv; var leafName = attributable ? device.GetDebugLeafScopeName() : null; var scope = leafName is not null ? $"[{leafName}]: " : ""; @@ -922,18 +940,20 @@ or MessageCategory.Execution // chain of "Down2" passes). var leaf = attributable ? device.debugCurrentFrame : null; + // Tree dump only fires for attributable messages — a tree without [!] markers is + // noise, so GBV-only frames stay quiet (just the log lines). switch (severity) { case MessageSeverity.Corruption: case MessageSeverity.Error: DebugLog.Error($"{scope}{desc}"); if (leaf is not null) leaf.Errors++; - if (isDrawCategory) device.debugSawDrawIssue = true; + if (isDrawCategory && attributable) device.debugSawDrawIssue = true; break; case MessageSeverity.Warning: DebugLog.Warning($"{scope}{desc}"); if (leaf is not null) leaf.Warnings++; - if (isDrawCategory) device.debugSawDrawIssue = true; + if (isDrawCategory && attributable) device.debugSawDrawIssue = true; break; } } @@ -982,9 +1002,11 @@ internal void FlushDebugMessages() bool isDrawCategory = message->Category is MessageCategory.StateSetting or MessageCategory.Execution or MessageCategory.ResourceManipulation; + bool isGbv = DebugGpuValidationEnabled || gbvMessageIds.Value.Contains(message->ID); + bool attributable = !isGbv; string prefix = null; - if (isDrawCategory) + if (isDrawCategory && attributable) { var leafName = GetDebugLeafScopeName(); prefix = leafName is not null ? $"[{leafName}]: " : null; @@ -995,11 +1017,11 @@ or MessageCategory.Execution case MessageSeverity.Corruption: case MessageSeverity.Error: DebugLog.Error($"{prefix}{description}"); - if (isDrawCategory) sawDrawIssue = true; + if (isDrawCategory && attributable) sawDrawIssue = true; break; case MessageSeverity.Warning: DebugLog.Warning($"{prefix}{description}"); - if (isDrawCategory) sawDrawIssue = true; + if (isDrawCategory && attributable) sawDrawIssue = true; break; } } diff --git a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs index a5c0215ad9..d8747b6719 100644 --- a/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs +++ b/sources/engine/Stride.Graphics/GraphicsDevice.DebugScope.cs @@ -37,13 +37,12 @@ public partial class GraphicsDevice internal bool debugSawDrawIssue; /// - /// When , the backend has GPU-side validation enabled - /// (D3D11/D3D12 GPU-based validation, Vulkan GPU-Assisted Validation). Messages from - /// those modes arrive asynchronously to recording, so per-leaf scope attribution is - /// unreliable. Backends should skip leaf Errors/Warnings increments and the - /// [scope]: log prefix when this is set, but still log the message and dump the - /// tree. Defaults to — Stride doesn't enable any of those modes - /// today. + /// Kill switch that forces every validation message to be treated as GPU-side and skip + /// leaf attribution / tree-dump triggering. Backends already detect GPU-side messages + /// per-message (D3D11/D3D12 via the D3D*_MESSAGE_ID_GPU_BASED_VALIDATION_* + /// enum entries; Vulkan via pMessageIdName), so this is only needed if those + /// heuristics ever miss a backend's GBV namespace and produce noisy misattributed + /// dumps. Defaults to ; Stride doesn't enable any GBV mode today. /// public bool DebugGpuValidationEnabled { get; set; } diff --git a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs index 3115fab78d..22aa6cdcf9 100644 --- a/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs +++ b/sources/engine/Stride.Graphics/Vulkan/GraphicsAdapterFactory.Vulkan.cs @@ -287,10 +287,20 @@ private unsafe static uint DebugReport(VkDebugUtilsMessageSeverityFlagsEXT sever // Performance categories are draw-relevant; General is mostly init/shutdown noise. var device = GraphicsDevice.DebugMessengerDevice; bool isDrawCategory = (types & (VkDebugUtilsMessageTypeFlagsEXT.Validation | VkDebugUtilsMessageTypeFlagsEXT.Performance)) != 0; - // GPU-Assisted Validation messages arrive on a worker thread after the GPU completes - // the offending draw — scope attribution is meaningless. Skip prefix/leaf bumps when - // that mode is on; the tree dump still fires from the draw-issue flag below. - bool attributable = device is not null && !device.DebugGpuValidationEnabled; + + // GPU-Assisted Validation (instrumented shaders, results read back on a worker) + // arrives asynchronously to recording. The Khronos validation layer tags those with + // ID names containing "GPU-AV"/"GPUAV"/"GPU-Assisted". Skip attribution and the + // tree-dump trigger so GBV-only frames stay quiet. + bool isGbv = device is not null && device.DebugGpuValidationEnabled; + if (!isGbv && pCallbackData->pMessageIdName != null) + { + var idName = new VkUtf8String(pCallbackData->pMessageIdName).ToString(); + isGbv = idName.Contains("GPU-AV", StringComparison.Ordinal) + || idName.Contains("GPUAV", StringComparison.Ordinal) + || idName.Contains("GPU-Assisted", StringComparison.Ordinal); + } + bool attributable = device is not null && !isGbv; string scopePrefix = ""; DebugScopeFrame leaf = null; if (attributable) @@ -305,13 +315,13 @@ private unsafe static uint DebugReport(VkDebugUtilsMessageSeverityFlagsEXT sever { GraphicsDevice.DebugLog.Error($"[Vulkan] {scopePrefix}{message}"); if (leaf is not null) leaf.Errors++; - if (device is not null && isDrawCategory) device.debugSawDrawIssue = true; + if (device is not null && isDrawCategory && attributable) device.debugSawDrawIssue = true; } else if (severity >= VkDebugUtilsMessageSeverityFlagsEXT.Warning) { GraphicsDevice.DebugLog.Warning($"[Vulkan] {scopePrefix}{message}"); if (leaf is not null) leaf.Warnings++; - if (device is not null && isDrawCategory) device.debugSawDrawIssue = true; + if (device is not null && isDrawCategory && attributable) device.debugSawDrawIssue = true; } else if (severity >= VkDebugUtilsMessageSeverityFlagsEXT.Info) { From ccf86bbe405c55f39659dc3f407092bfb438c7d9 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 5 May 2026 12:26:49 +0900 Subject: [PATCH 1167/1182] tests: classify gameplay-state drift as not-a-regression in vision fallback --- .../Tests/Comparator/ClaudeVisionFallback.cs | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/samples/Tests/Comparator/ClaudeVisionFallback.cs b/samples/Tests/Comparator/ClaudeVisionFallback.cs index 52130b7775..01e709e289 100644 --- a/samples/Tests/Comparator/ClaudeVisionFallback.cs +++ b/samples/Tests/Comparator/ClaudeVisionFallback.cs @@ -34,13 +34,28 @@ public static Verdict Compare(string baselinePath, string capturePath, string? e var baselineB64 = Convert.ToBase64String(File.ReadAllBytes(baselinePath)); var captureB64 = Convert.ToBase64String(File.ReadAllBytes(capturePath)); - var prompt = "Compare these two game screenshots — first is the BASELINE (expected), " + - "second is the CAPTURE (this run). Reply YES if they show the same UI state " + - "and same visible content (same text, buttons, characters, scene layout). " + - "Treat noise (particle positions, animation cycle phase, lighting flicker) " + - "as acceptable. Reply NO if there is a meaningful regression (different UI " + - "page, missing element, wrong text, different scene). " + - "Format: \"YES: \" or \"NO: \"."; + var prompt = + "Compare these two Stride engine screenshots — BASELINE (expected) vs CAPTURE " + + "(this run). Both were produced by the same engine code; visible differences are " + + "almost always caused by test-harness timing nondeterminism (variable frame pacing " + + "across graphics APIs), NOT by a rendering regression. A rendering regression looks " + + "broken, not just 'different'. Be tolerant.\n\n" + + "YES (not a regression):\n" + + "- HUD numeric values differ (ammo, score, timer, FPS, health). This is gameplay state.\n" + + "- Character / weapon / camera pose, aim angle, or hand-bob phase differs. Animation phase.\n" + + "- Particle / smoke / fire / cloth / water / lighting / post-process noise differs.\n" + + "- Same overall scene with one element in a slightly different position or animation state.\n" + + "\n" + + "NO (real regression):\n" + + "- Whole-frame color / gamma / brightness shift (capture noticeably darker, desaturated, " + + "washed-out, or with wrong sRGB encoding).\n" + + "- Missing or corrupt geometry (broken meshes, distorted models, holes).\n" + + "- Missing or wrong textures (pink/purple checkerboard, all-black surfaces, wrong materials).\n" + + "- Missing post-process pass (no bloom / shadow / SSAO / tonemapping where baseline has them).\n" + + "- Different UI page, missing UI elements, wrong UI text labels (label text, not numeric values).\n" + + "- Wrong scene entirely (different level, different camera angle by 90°+, missing major objects).\n" + + "\n" + + "Format: \"YES: \" or \"NO: \"."; if (!string.IsNullOrEmpty(extraHint)) prompt += " Additional context for this specific frame: " + extraHint; From 3a4764f23796eacb66fe8e0bb84ad5c6869ace62 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 5 May 2026 13:10:36 +0900 Subject: [PATCH 1168/1182] tests: fix screenshot-runner file race when sample times out - error.log: open with FileShare.ReadWrite|Delete so the orchestrator can copy it while still held - ScreenshotRunner: WaitForExit after Kill so the OS finishes releasing handles before we copy - ci: stop continue-on-error for D3D12/Vulkan now that they should be reliable --- .github/workflows/test-samples-screenshots.yml | 2 -- samples/Tests/Runner/ScreenshotRunner.cs | 4 ++++ .../Stride.Games.AutoTesting/ScreenshotTestRunner.cs | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test-samples-screenshots.yml b/.github/workflows/test-samples-screenshots.yml index 1c592b2939..052b2a67eb 100644 --- a/.github/workflows/test-samples-screenshots.yml +++ b/.github/workflows/test-samples-screenshots.yml @@ -31,8 +31,6 @@ jobs: matrix: graphics-api: [Direct3D11, Direct3D12, Vulkan] runs-on: windows-2025-vs2026 - # TODO: drop continue-on-error once D3D12 and Vulkan captures are stable. - continue-on-error: ${{ matrix.graphics-api != 'Direct3D11' }} env: # Software rendering is the default in the autotesting harness; set STRIDE_TESTS_GPU=1 to opt into the GPU. STRIDE_TESTS_RENDERDOC: "error" diff --git a/samples/Tests/Runner/ScreenshotRunner.cs b/samples/Tests/Runner/ScreenshotRunner.cs index 11172148fa..e53ae81c3c 100644 --- a/samples/Tests/Runner/ScreenshotRunner.cs +++ b/samples/Tests/Runner/ScreenshotRunner.cs @@ -258,6 +258,10 @@ private static bool RunProcess(string fileName, string arguments, string logPath if (!process.WaitForExit(TimeSpan.FromSeconds(timeoutSeconds))) { try { process.Kill(entireProcessTree: true); } catch { } + // Kill returns before the OS finishes tearing down the process and releasing its file + // handles; without this WaitForExit the caller races the kernel and intermittently + // fails to copy / overwrite files the killed process had open. + try { process.WaitForExit(TimeSpan.FromSeconds(10)); } catch { } log.WriteLine($"[runner] killed after {timeoutSeconds}s timeout"); return false; } diff --git a/sources/engine/Stride.Games.AutoTesting/ScreenshotTestRunner.cs b/sources/engine/Stride.Games.AutoTesting/ScreenshotTestRunner.cs index 4c137529d0..dd50341b2a 100644 --- a/sources/engine/Stride.Games.AutoTesting/ScreenshotTestRunner.cs +++ b/sources/engine/Stride.Games.AutoTesting/ScreenshotTestRunner.cs @@ -144,10 +144,16 @@ private void Start() } // Mirror error stream into error.log alongside the test artifacts. + // FileShare.ReadWrite|Delete so the orchestrator can copy / overwrite this file while we + // still hold it open — otherwise a forced timeout-kill races against the orchestrator's + // artifact copy and triggers IOException("file is being used by another process"). try { var errorLogPath = Path.Combine(outputDir, ErrorLogName); - var errorLog = new StreamWriter(File.Create(errorLogPath)) { AutoFlush = true }; + var errorLogStream = new FileStream( + errorLogPath, FileMode.Create, FileAccess.Write, + FileShare.ReadWrite | FileShare.Delete); + var errorLog = new StreamWriter(errorLogStream) { AutoFlush = true }; Console.SetError(new TeeWriter(Console.Error, errorLog)); } catch From 92613b5c493131657e5c1ba03be2b6413c2e8bf5 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 5 May 2026 17:00:11 +0900 Subject: [PATCH 1169/1182] rendering: allow PerView Lighting layout to differ between effects in same view ForwardLightingRenderFeature.Prepare threw when two effects in the same RenderView resolved to different PerView Lighting logical-group layouts (e.g. different light permutation counts). Mirror the per-hash variant pattern from MaterialRenderFeature: keep one ParameterCollectionLayout + ParameterCollection per layout hash inside RenderViewLightData, apply view parameters once per variant per frame, bind each layout's resource group from its matching variant. --- .../Lights/ForwardLightingRenderFeature.cs | 119 +++++++++--------- 1 file changed, 57 insertions(+), 62 deletions(-) diff --git a/sources/engine/Stride.Rendering/Rendering/Lights/ForwardLightingRenderFeature.cs b/sources/engine/Stride.Rendering/Rendering/Lights/ForwardLightingRenderFeature.cs index a32374447e..a756bcf901 100644 --- a/sources/engine/Stride.Rendering/Rendering/Lights/ForwardLightingRenderFeature.cs +++ b/sources/engine/Stride.Rendering/Rendering/Lights/ForwardLightingRenderFeature.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; -using System.Diagnostics; using System.Linq; using System.Threading; using Stride.Core; @@ -44,9 +43,39 @@ public class RenderViewLightData public readonly Dictionary RenderLightsWithShadows; - internal ObjectId ViewLayoutHash; - internal ParameterCollectionLayout ViewParameterLayout; - internal ParameterCollection ViewParameters = new ParameterCollection(); + // Effects in the same view can resolve to different PerView Lighting layouts (e.g. when + // light permutation counts differ). Track one variant per layout hash so each layout's + // resource group gets parameters of its expected shape, instead of throwing. + internal sealed class ViewLayoutVariant + { + public ObjectId Hash; + public ParameterCollectionLayout ParameterCollectionLayout; + public readonly ParameterCollection Parameters = new ParameterCollection(); + public int LastFrameProcessed = -1; + } + + // Inline fast path for the common single-variant case + internal ViewLayoutVariant SingleVariant; + internal Dictionary ExtraVariants; + + internal ViewLayoutVariant GetOrAddVariant(ObjectId hash) + { + if (SingleVariant == null) + { + SingleVariant = new ViewLayoutVariant { Hash = hash }; + return SingleVariant; + } + if (SingleVariant.Hash == hash) + return SingleVariant; + + ExtraVariants ??= new Dictionary(); + if (!ExtraVariants.TryGetValue(hash, out var variant)) + { + variant = new ViewLayoutVariant { Hash = hash }; + ExtraVariants[hash] = variant; + } + return variant; + } public RenderViewLightData() { @@ -342,58 +371,14 @@ public override void Prepare(RenderDrawContext context) if (!renderViewDatas.TryGetValue(view.LightingView ?? view, out renderViewData) || viewFeature.Layouts.Count == 0) continue; - // Find a PerView layout from an effect in normal state - ViewResourceGroupLayout firstViewLayout = null; - foreach (var viewLayout in viewFeature.Layouts) - { - // Only process view layouts in normal state - if (viewLayout.State != RenderEffectState.Normal) - continue; - - var viewLighting = viewLayout.GetLogicalGroup(viewLightingKey); - if (viewLighting.Hash != ObjectId.Empty) - { - firstViewLayout = viewLayout; - break; - } - } - - // Nothing found for this view (no effects in normal state) - if (firstViewLayout == null) - continue; - var viewIndex = renderViews.IndexOf(view); + int frameCounter = RenderSystem.FrameCounter; - var viewParameterLayout = renderViewData.ViewParameterLayout; - var viewParameters = renderViewData.ViewParameters; - var firstViewLighting = firstViewLayout.GetLogicalGroup(viewLightingKey); - - // Prepare layout (should be similar for all PerView) - if (firstViewLighting.Hash != renderViewData.ViewLayoutHash) - { - renderViewData.ViewLayoutHash = firstViewLighting.Hash; - - // Generate layout - viewParameterLayout = renderViewData.ViewParameterLayout = new ParameterCollectionLayout(); - viewParameterLayout.ProcessLogicalGroup(firstViewLayout, ref firstViewLighting); - - viewParameters.UpdateLayout(viewParameterLayout); - } - - // Compute PerView lighting - foreach (var directLightGroup in shaderPermutation.DirectLightGroups) - { - directLightGroup.ApplyViewParameters(context, viewIndex, viewParameters); - } - foreach (var environmentLight in shaderPermutation.EnvironmentLights) - { - environmentLight.ApplyViewParameters(context, viewIndex, viewParameters); - } - - // Update PerView + // Build/refresh one variant per distinct PerView Lighting layout hash, then bind each + // layout's resource group to its matching variant. Light groups' ApplyViewParameters + // is idempotent per (view, parameter collection), so it runs once per variant per frame. foreach (var viewLayout in viewFeature.Layouts) { - // Only process view layouts in normal state if (viewLayout.State != RenderEffectState.Normal) continue; @@ -401,13 +386,25 @@ public override void Prepare(RenderDrawContext context) if (viewLighting.Hash == ObjectId.Empty) continue; - if (viewLighting.Hash != firstViewLighting.Hash) - throw new InvalidOperationException("PerView Lighting layout differs between different RenderObject in the same RenderView"); + var variant = renderViewData.GetOrAddVariant(viewLighting.Hash); + if (variant.ParameterCollectionLayout == null) + { + variant.ParameterCollectionLayout = new ParameterCollectionLayout(); + variant.ParameterCollectionLayout.ProcessLogicalGroup(viewLayout, ref viewLighting); + variant.Parameters.UpdateLayout(variant.ParameterCollectionLayout); + } - var resourceGroup = viewLayout.Entries[view.Index].Resources; + if (variant.LastFrameProcessed != frameCounter) + { + foreach (var directLightGroup in shaderPermutation.DirectLightGroups) + directLightGroup.ApplyViewParameters(context, viewIndex, variant.Parameters); + foreach (var environmentLight in shaderPermutation.EnvironmentLights) + environmentLight.ApplyViewParameters(context, viewIndex, variant.Parameters); + variant.LastFrameProcessed = frameCounter; + } - // Update resources - resourceGroup.UpdateLogicalGroup(ref viewLighting, viewParameters); + var resourceGroup = viewLayout.Entries[view.Index].Resources; + resourceGroup.UpdateLogicalGroup(ref viewLighting, variant.Parameters); } // PerDraw @@ -427,21 +424,19 @@ public override void Prepare(RenderDrawContext context) if (drawLighting.Hash == ObjectId.Empty) return; - // First time, let's build layout + // Rebuild thread-local layout when this node's hash differs from the previous one + // processed on this thread (different effects in the same view can produce different + // PerDraw Lighting layouts). if (drawLighting.Hash != locals.DrawLayoutHash) { locals.DrawLayoutHash = drawLighting.Hash; - // Generate layout var drawParameterLayout = new ParameterCollectionLayout(); drawParameterLayout.ProcessLogicalGroup(drawLayout, ref drawLighting); locals.DrawParameters.UpdateLayout(drawParameterLayout); } - // TODO: Does this ever fail? - Debug.Assert(drawLighting.Hash == locals.DrawLayoutHash, "PerDraw Lighting layout differs between different RenderObject in the same RenderView"); - // Compute PerDraw lighting foreach (var directLightGroup in shaderPermutation.DirectLightGroups) { From f8d02045474085620aac75c1eb7e88b0e7611153 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 11 May 2026 17:48:59 +0900 Subject: [PATCH 1170/1182] editor tests: instantiate sample via TemplateSampleGenerator + clear LoadingStartupSession --- .../Stride.GameStudio.AutoTesting/Program.cs | 10 +++ tests/editor/EditorScreenshotTests.cs | 76 +++++++++++++++++-- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/sources/editor/Stride.GameStudio.AutoTesting/Program.cs b/sources/editor/Stride.GameStudio.AutoTesting/Program.cs index bfb3dc11ae..dadc0d30a7 100644 --- a/sources/editor/Stride.GameStudio.AutoTesting/Program.cs +++ b/sources/editor/Stride.GameStudio.AutoTesting/Program.cs @@ -36,6 +36,16 @@ public static int Main(string[] osArgs) } catch { /* best-effort — failure shows up as the privacy-policy hang */ } + // Clear the "last startup-session load crashed" sticky flag — a previous AutoTesting run + // that timed out / was killed leaves it on, which makes OpenInitialSession pop a "try + // again?" MessageBox with no one to click. Always reset before launching GS. + try + { + Stride.Core.Assets.Editor.Settings.InternalSettings.LoadingStartupSession.SetValue(false); + Stride.Core.Assets.Editor.Settings.InternalSettings.Save(); + } + catch { /* best-effort — at worst we re-prompt on the next run */ } + // Parse our own args. Anything we don't recognise is forwarded to Stride.GameStudio.Run. string? testDll = null; string? testName = null; diff --git a/tests/editor/EditorScreenshotTests.cs b/tests/editor/EditorScreenshotTests.cs index c31ee358af..f1ff25538d 100644 --- a/tests/editor/EditorScreenshotTests.cs +++ b/tests/editor/EditorScreenshotTests.cs @@ -6,6 +6,13 @@ using System.Diagnostics; using System.IO; using System.Linq; +using Stride.Assets.Presentation; +using Stride.Assets.Presentation.Templates; +using Stride.Assets.Templates; +using Stride.Core.Assets; +using Stride.Core.Assets.Templates; +using Stride.Core.Diagnostics; +using Stride.Core.IO; using Stride.GameStudio.AutoTesting; using Stride.Tests.ScreenshotComparator; using Xunit; @@ -35,16 +42,16 @@ public class EditorScreenshotTests public static IEnumerable Fixtures() { - // (fixtureName, optional .sln path relative to worktree, timeout-minutes) - yield return new object?[] { "EmptyEditor", null, 3 }; - yield return new object?[] { "TopDownCreate", null, 8 }; - yield return new object?[] { "TopDownLoad", "samples/Templates/TopDownRPG/TopDownRPG.sln", 5 }; - yield return new object?[] { "NewGameEditor", null, 5 }; + // (fixtureName, optional template GUID to instantiate and upgrade before opening, timeout-minutes) + yield return new object?[] { "EmptyEditor", (Guid?)null, 3 }; + yield return new object?[] { "TopDownCreate", (Guid?)null, 8 }; + yield return new object?[] { "TopDownLoad", (Guid?)new Guid("A363FBC5-89EF-4E7A-B870-6D070813D034"), 5 }; + yield return new object?[] { "NewGameEditor", (Guid?)null, 5 }; } [Theory] [MemberData(nameof(Fixtures))] - public void Capture(string fixtureName, string? slnPathRel, int timeoutMin) + public void Capture(string fixtureName, Guid? templateGuid, int timeoutMin) { var worktree = WorktreeRoot(); var captureRoot = Path.Combine(worktree, "ui-test-out-" + Dpi); @@ -55,7 +62,11 @@ public void Capture(string fixtureName, string? slnPathRel, int timeoutMin) var dll = typeof(EditorScreenshotTests).Assembly.Location; var exe = ResolveAutoTestingExe(dll, worktree); var args = new List { "--test-dll", dll, "--test-name", fixtureName }; - if (slnPathRel is not null) args.Add(Path.Combine(worktree, slnPathRel)); + if (templateGuid is { } guid) + { + var generated = GenerateSampleFromTemplate(guid, fixtureName); + args.Add(generated); + } // Clean the runner-side output dir so stale files from a previous fixture invocation // don't leak into this fixture's capture set. @@ -119,6 +130,57 @@ public void Capture(string fixtureName, string? slnPathRel, int timeoutMin) Assert.Empty(failures); } + /// + /// Instantiates a template sample (by GUID) into a per-fixture temp dir via + /// — the exact path GS's New Project wizard uses + /// internally, so any future generator changes (e.g. silent-upgrade behaviour) flow through. + /// Returns the absolute .sln path the AutoTesting runner should open. + /// + private static string GenerateSampleFromTemplate(Guid templateGuid, string sampleName) + { + var outputDir = Path.Combine(Path.GetTempPath(), "stride-editor-tests", sampleName); + if (Directory.Exists(outputDir)) + Directory.Delete(outputDir, recursive: true); + Directory.CreateDirectory(outputDir); + + PackageSessionPublicHelper.FindAndSetMSBuildVersion(); + + var logger = new LoggerResult(); + var session = new PackageSession(); + var parameters = new SessionTemplateGeneratorParameters { Session = session, Unattended = true }; + TemplateSampleGenerator.SetParameters( + parameters, + AssetRegistry.SupportedPlatforms + .Where(x => x.Type == Core.PlatformType.Windows) + .Select(x => new SelectedSolutionPlatform(x, x.Templates.FirstOrDefault())) + .ToList()); + + StrideDefaultAssetsPlugin.LoadDefaultTemplates(); + var template = TemplateManager.FindTemplates(session).FirstOrDefault(t => t.Id == templateGuid) + ?? throw new InvalidOperationException($"Template {templateGuid} not found in catalog"); + parameters.Description = template; + parameters.Name = sampleName; + parameters.Namespace = sampleName; + parameters.OutputDirectory = outputDir; + parameters.Logger = logger; + + session.SolutionPath = UPath.Combine(outputDir, sampleName + ".sln"); + + var generator = TemplateSampleGenerator.Default; + if (!generator.PrepareForRun(parameters).Result) + throw new InvalidOperationException($"PrepareForRun failed for {sampleName}:\n{logger.ToText()}"); + if (!generator.Run(parameters)) + throw new InvalidOperationException($"Run failed for {sampleName}:\n{logger.ToText()}"); + + // Persist any in-memory asset upgrades the generator triggered (via AddExistingProject's + // null-callback default-Upgrade path) — otherwise GS would re-detect them on open. + session.Save(logger); + if (logger.HasErrors) + throw new InvalidOperationException($"Generating sample {sampleName} produced errors:\n{logger.ToText()}"); + + return session.SolutionPath.ToOSPath(); + } + private static string ResolveAutoTestingExe(string testDllPath, string worktree) { // tests\editor\bin\\\Stride.Editor.Tests.dll → mirror the cfg+tfm into the runner's From 07e7f5fee12ff3981587c307f5ea890c19ac7f63 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Mon, 11 May 2026 17:50:20 +0900 Subject: [PATCH 1171/1182] editor tests: refresh NewGameEditor build-log baseline (sdsl shader warnings) --- .../baselines/dpi100/NewGameEditor/build-log-after-run.png | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/editor/baselines/dpi100/NewGameEditor/build-log-after-run.png b/tests/editor/baselines/dpi100/NewGameEditor/build-log-after-run.png index a9c076dbe8..3cf747cd27 100644 --- a/tests/editor/baselines/dpi100/NewGameEditor/build-log-after-run.png +++ b/tests/editor/baselines/dpi100/NewGameEditor/build-log-after-run.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ce52a0cec812e1239679d91c21ecdf0d506dfee41a32281caa44978e9cc6f6e6 -size 209538 +oid sha256:eb2236d7dfe3e1a31e922203da14ecb6951cc9f1763d9abb3f006e1a628afede +size 177434 From 2a993d130c9368c1163b8108d42b446b4ec621bc Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 12 May 2026 15:15:09 +0900 Subject: [PATCH 1172/1182] build: PrivateAssets=compile for impl-only deps --- .../Stride.Core.Design/Stride.Core.Design.csproj | 2 +- .../Stride.Core.Serialization.csproj | 2 +- .../Stride.Assets.Presentation.csproj | 1 + .../Stride.GameStudio/Stride.GameStudio.csproj | 1 + sources/engine/Stride.Assets/Stride.Assets.csproj | 3 ++- sources/engine/Stride.Games/Stride.Games.csproj | 2 ++ .../engine/Stride.Graphics/Stride.Graphics.csproj | 14 ++++++++------ sources/engine/Stride.Input/Stride.Input.csproj | 1 + .../Stride.Navigation/Stride.Navigation.csproj | 6 +++--- sources/engine/Stride.Video/Stride.Video.csproj | 2 +- .../Stride.VirtualReality.csproj | 5 +++-- .../Stride.Shaders.Compilers.csproj | 12 ++++++------ .../Stride.Shaders.Parsers.csproj | 1 + .../Stride.Shaders.Spirv.Core.csproj | 2 +- .../Stride.Shaders.Tests.csproj | 3 +++ .../Stride.Graphics.RenderDocPlugin.csproj | 1 + 16 files changed, 36 insertions(+), 22 deletions(-) diff --git a/sources/core/Stride.Core.Design/Stride.Core.Design.csproj b/sources/core/Stride.Core.Design/Stride.Core.Design.csproj index 5dde654ed8..9fed5e5b05 100644 --- a/sources/core/Stride.Core.Design/Stride.Core.Design.csproj +++ b/sources/core/Stride.Core.Design/Stride.Core.Design.csproj @@ -23,7 +23,7 @@ - + diff --git a/sources/core/Stride.Core.Serialization/Stride.Core.Serialization.csproj b/sources/core/Stride.Core.Serialization/Stride.Core.Serialization.csproj index dc5130e616..61d298663b 100644 --- a/sources/core/Stride.Core.Serialization/Stride.Core.Serialization.csproj +++ b/sources/core/Stride.Core.Serialization/Stride.Core.Serialization.csproj @@ -21,7 +21,7 @@ - + diff --git a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj index c70412cafe..e77009c4a6 100644 --- a/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj +++ b/sources/editor/Stride.Assets.Presentation/Stride.Assets.Presentation.csproj @@ -23,6 +23,7 @@ + diff --git a/sources/editor/Stride.GameStudio/Stride.GameStudio.csproj b/sources/editor/Stride.GameStudio/Stride.GameStudio.csproj index cfbb7017f8..844632c83d 100644 --- a/sources/editor/Stride.GameStudio/Stride.GameStudio.csproj +++ b/sources/editor/Stride.GameStudio/Stride.GameStudio.csproj @@ -34,6 +34,7 @@ + ..\..\..\deps\AssemblyProcessor\netstandard2.0\Stride.Core.AssemblyProcessor.dll diff --git a/sources/engine/Stride.Assets/Stride.Assets.csproj b/sources/engine/Stride.Assets/Stride.Assets.csproj index e531ebf538..d6257e97e2 100644 --- a/sources/engine/Stride.Assets/Stride.Assets.csproj +++ b/sources/engine/Stride.Assets/Stride.Assets.csproj @@ -17,7 +17,8 @@ - + + ..\..\..\deps\VHACD\VHACDSharp.dll diff --git a/sources/engine/Stride.Games/Stride.Games.csproj b/sources/engine/Stride.Games/Stride.Games.csproj index dbc8bd1dbf..1573c87db2 100644 --- a/sources/engine/Stride.Games/Stride.Games.csproj +++ b/sources/engine/Stride.Games/Stride.Games.csproj @@ -25,6 +25,8 @@ + + diff --git a/sources/engine/Stride.Graphics/Stride.Graphics.csproj b/sources/engine/Stride.Graphics/Stride.Graphics.csproj index f3bcb5a3eb..7fa99491e6 100644 --- a/sources/engine/Stride.Graphics/Stride.Graphics.csproj +++ b/sources/engine/Stride.Graphics/Stride.Graphics.csproj @@ -40,12 +40,14 @@ - - - - - - + + + + + + + diff --git a/sources/engine/Stride.Input/Stride.Input.csproj b/sources/engine/Stride.Input/Stride.Input.csproj index 34ca2b7e33..4b2a1dcf89 100644 --- a/sources/engine/Stride.Input/Stride.Input.csproj +++ b/sources/engine/Stride.Input/Stride.Input.csproj @@ -17,6 +17,7 @@ + diff --git a/sources/engine/Stride.Navigation/Stride.Navigation.csproj b/sources/engine/Stride.Navigation/Stride.Navigation.csproj index d93080e67a..c7451dfa1a 100644 --- a/sources/engine/Stride.Navigation/Stride.Navigation.csproj +++ b/sources/engine/Stride.Navigation/Stride.Navigation.csproj @@ -16,9 +16,9 @@ - - - + + + diff --git a/sources/engine/Stride.Video/Stride.Video.csproj b/sources/engine/Stride.Video/Stride.Video.csproj index 326777bc54..2a60076511 100644 --- a/sources/engine/Stride.Video/Stride.Video.csproj +++ b/sources/engine/Stride.Video/Stride.Video.csproj @@ -40,7 +40,7 @@ - + diff --git a/sources/engine/Stride.VirtualReality/Stride.VirtualReality.csproj b/sources/engine/Stride.VirtualReality/Stride.VirtualReality.csproj index f57faf1e06..705a956ce8 100644 --- a/sources/engine/Stride.VirtualReality/Stride.VirtualReality.csproj +++ b/sources/engine/Stride.VirtualReality/Stride.VirtualReality.csproj @@ -43,8 +43,9 @@ - - + + + diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 6624e71570..93126b7ad5 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -23,16 +23,16 @@ - + - + - - - - + + + + diff --git a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj index 0abcd076ec..ffd38d1938 100644 --- a/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj +++ b/sources/shaders/Stride.Shaders.Parsers/Stride.Shaders.Parsers.csproj @@ -18,6 +18,7 @@ + diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 45e6463607..8e54e9867a 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -12,7 +12,7 @@ - + diff --git a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj index a55c610333..08999931ce 100644 --- a/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj +++ b/sources/shaders/Stride.Shaders.Tests/Stride.Shaders.Tests.csproj @@ -30,6 +30,9 @@ + + + diff --git a/sources/tools/Stride.Graphics.RenderDocPlugin/Stride.Graphics.RenderDocPlugin.csproj b/sources/tools/Stride.Graphics.RenderDocPlugin/Stride.Graphics.RenderDocPlugin.csproj index 0ad4f0e904..d170d87379 100644 --- a/sources/tools/Stride.Graphics.RenderDocPlugin/Stride.Graphics.RenderDocPlugin.csproj +++ b/sources/tools/Stride.Graphics.RenderDocPlugin/Stride.Graphics.RenderDocPlugin.csproj @@ -8,6 +8,7 @@ + From dd44c3bbde259e716b5b331e8406cf1a62f4e391 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 12 May 2026 18:57:27 +0900 Subject: [PATCH 1173/1182] shaders: pre-generate SPV bindings, drop SpirvHeaders/Registry submodules SPVGenerator runs as a standalone console tool fetching SPIRV-Headers / SPIRV-Registry from GitHub at pinned refs. Generated/*.cs is committed. Regenerate via F5 / dotnet run after bumping the refs in Program.cs. --- .gitmodules | 6 - build/submodules/SpirvHeaders | 1 - build/submodules/SpirvRegistry | 1 - .../Generated/EnumerantParameters.gen.cs | 3853 + .../Generated/InstructionInfo.gen.cs | 3327 + .../Generated/Instructions.gen.cs | 133325 +++++++++++++++ .../Generated/OperandKind.gen.cs | 232 + .../Generated/SDSLSpecification.gen.cs | 1332 + .../Generated/SpecificationOp.gen.cs | 886 + .../Stride.Shaders.Spirv.Core.csproj | 23 +- .../Program.cs | 113 + .../Properties/launchSettings.json | 8 + .../SPVGenerator.EnumerantParams.cs | 63 +- .../SPVGenerator.Extensions.cs | 23 - .../SPVGenerator.Helpers.Preprocessing.cs | 14 +- .../SPVGenerator.Info.cs | 168 +- .../SPVGenerator.Instructions.cs | 52 +- .../SPVGenerator.SDSLOp.cs | 36 +- .../SPVGenerator.Specification.cs | 24 +- .../SPVGenerator.cs | 125 +- .../Stride.Shaders.Spirv.Generators/SpvIO.cs | 23 + .../Stride.Shaders.Spirv.Generators.csproj | 38 +- 22 files changed, 143256 insertions(+), 417 deletions(-) delete mode 160000 build/submodules/SpirvHeaders delete mode 160000 build/submodules/SpirvRegistry create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/EnumerantParameters.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/InstructionInfo.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/Instructions.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/OperandKind.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/SDSLSpecification.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Core/Generated/SpecificationOp.gen.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Generators/Properties/launchSettings.json delete mode 100644 sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs create mode 100644 sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs diff --git a/.gitmodules b/.gitmodules index 0fcbc01292..2b27249292 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,3 @@ -[submodule "submodules/SpirvHeaders"] - path = build/submodules/SpirvHeaders - url = https://github.com/KhronosGroup/SPIRV-Headers [submodule "submodules/CppNet8"] path = build/submodules/CppNet8 url = https://github.com/ykafia/CppNet/ -[submodule "submodules/SpirvRegistry"] - path = build/submodules/SpirvRegistry - url = https://github.com/KhronosGroup/Registry-Root-SPIR-V diff --git a/build/submodules/SpirvHeaders b/build/submodules/SpirvHeaders deleted file mode 160000 index 3f17b2af67..0000000000 --- a/build/submodules/SpirvHeaders +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3f17b2af6784bfa2c5aa5dbb8e0e74a607dd8b3b diff --git a/build/submodules/SpirvRegistry b/build/submodules/SpirvRegistry deleted file mode 160000 index a74197a3f0..0000000000 --- a/build/submodules/SpirvRegistry +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a74197a3f0d5400764ce3bec2880f06e27b7b5d3 diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/EnumerantParameters.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/EnumerantParameters.gen.cs new file mode 100644 index 0000000000..a8a9414ca1 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/EnumerantParameters.gen.cs @@ -0,0 +1,3853 @@ +using static Stride.Shaders.Spirv.Specification; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; + +namespace Stride.Shaders.Spirv.Core; +public static class ImageOperandsParams +{ + public ref struct Bias(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static Bias Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Bias + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Lod(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static Lod Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Lod + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Grad(int idRef0, int idRef1) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + public int IdRef1 { get; set; } = idRef1; + + public static Grad Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Grad + { + IdRef0 = reader.ReadInt(), + IdRef1 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ConstOffset(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static ConstOffset Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ConstOffset + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Offset(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static Offset Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Offset + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ConstOffsets(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static ConstOffsets Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ConstOffsets + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Sample(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static Sample Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Sample + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MinLod(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static MinLod Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MinLod + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MakeTexelAvailable(int idscope0) : IEnumerantParameter + { + public int Idscope0 { get; set; } = idscope0; + + public static MakeTexelAvailable Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MakeTexelAvailable + { + Idscope0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MakeTexelVisible(int idscope0) : IEnumerantParameter + { + public int Idscope0 { get; set; } = idscope0; + + public static MakeTexelVisible Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MakeTexelVisible + { + Idscope0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Offsets(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static Offsets Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Offsets + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } +} + +public static class LoopControlParams +{ + public ref struct DependencyLength(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static DependencyLength Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DependencyLength + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MinIterations(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static MinIterations Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MinIterations + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxIterations(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static MaxIterations Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxIterations + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct IterationMultiple(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static IterationMultiple Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new IterationMultiple + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PeelCount(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static PeelCount Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PeelCount + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PartialCount(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static PartialCount Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PartialCount + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct InitiationIntervalINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static InitiationIntervalINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new InitiationIntervalINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxConcurrencyINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static MaxConcurrencyINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxConcurrencyINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct DependencyArrayINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static DependencyArrayINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DependencyArrayINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PipelineEnableINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static PipelineEnableINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PipelineEnableINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LoopCoalesceINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static LoopCoalesceINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LoopCoalesceINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxInterleavingINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static MaxInterleavingINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxInterleavingINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SpeculatedIterationsINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static SpeculatedIterationsINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SpeculatedIterationsINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LoopCountINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static LoopCountINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LoopCountINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxReinvocationDelayINTEL(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static MaxReinvocationDelayINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxReinvocationDelayINTEL + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } +} + +public static class MemoryAccessParams +{ + public ref struct Aligned(int literalinteger0) : IEnumerantParameter + { + public int Literalinteger0 { get; set; } = literalinteger0; + + public static Aligned Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Aligned + { + Literalinteger0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MakePointerAvailable(int idscope0) : IEnumerantParameter + { + public int Idscope0 { get; set; } = idscope0; + + public static MakePointerAvailable Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MakePointerAvailable + { + Idscope0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MakePointerVisible(int idscope0) : IEnumerantParameter + { + public int Idscope0 { get; set; } = idscope0; + + public static MakePointerVisible Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MakePointerVisible + { + Idscope0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct AliasScopeINTELMask(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static AliasScopeINTELMask Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new AliasScopeINTELMask + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NoAliasINTELMask(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static NoAliasINTELMask Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NoAliasINTELMask + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } +} + +public static class ExecutionModeParams +{ + public ref struct Invocations(int numberofInvocationinvocations) : IEnumerantParameter + { + public int NumberofInvocationinvocations { get; set; } = numberofInvocationinvocations; + + public static Invocations Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Invocations + { + NumberofInvocationinvocations = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LocalSize(int xsize, int ysize, int zsize) : IEnumerantParameter + { + public int Xsize { get; set; } = xsize; + public int Ysize { get; set; } = ysize; + public int Zsize { get; set; } = zsize; + + public static LocalSize Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LocalSize + { + Xsize = reader.ReadInt(), + Ysize = reader.ReadInt(), + Zsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LocalSizeHint(int xsize, int ysize, int zsize) : IEnumerantParameter + { + public int Xsize { get; set; } = xsize; + public int Ysize { get; set; } = ysize; + public int Zsize { get; set; } = zsize; + + public static LocalSizeHint Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LocalSizeHint + { + Xsize = reader.ReadInt(), + Ysize = reader.ReadInt(), + Zsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct OutputVertices(int vertexcount) : IEnumerantParameter + { + public int Vertexcount { get; set; } = vertexcount; + + public static OutputVertices Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new OutputVertices + { + Vertexcount = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct VecTypeHint(int vectortype) : IEnumerantParameter + { + public int Vectortype { get; set; } = vectortype; + + public static VecTypeHint Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new VecTypeHint + { + Vectortype = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SubgroupSize(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static SubgroupSize Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SubgroupSize + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SubgroupsPerWorkgroup(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static SubgroupsPerWorkgroup Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SubgroupsPerWorkgroup + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SubgroupsPerWorkgroupId(int subgroupsPerWorkgroup) : IEnumerantParameter + { + public int SubgroupsPerWorkgroup { get; set; } = subgroupsPerWorkgroup; + + public static SubgroupsPerWorkgroupId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SubgroupsPerWorkgroupId + { + SubgroupsPerWorkgroup = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LocalSizeId(int xsize, int ysize, int zsize) : IEnumerantParameter + { + public int Xsize { get; set; } = xsize; + public int Ysize { get; set; } = ysize; + public int Zsize { get; set; } = zsize; + + public static LocalSizeId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LocalSizeId + { + Xsize = reader.ReadInt(), + Ysize = reader.ReadInt(), + Zsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LocalSizeHintId(int xsizehint, int ysizehint, int zsizehint) : IEnumerantParameter + { + public int Xsizehint { get; set; } = xsizehint; + public int Ysizehint { get; set; } = ysizehint; + public int Zsizehint { get; set; } = zsizehint; + + public static LocalSizeHintId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LocalSizeHintId + { + Xsizehint = reader.ReadInt(), + Ysizehint = reader.ReadInt(), + Zsizehint = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct DenormPreserve(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static DenormPreserve Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DenormPreserve + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct DenormFlushToZero(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static DenormFlushToZero Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DenormFlushToZero + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SignedZeroInfNanPreserve(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static SignedZeroInfNanPreserve Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SignedZeroInfNanPreserve + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct RoundingModeRTE(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static RoundingModeRTE Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new RoundingModeRTE + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct RoundingModeRTZ(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static RoundingModeRTZ Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new RoundingModeRTZ + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct IsApiEntryAMDX(int isEntry) : IEnumerantParameter + { + public int IsEntry { get; set; } = isEntry; + + public static IsApiEntryAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new IsApiEntryAMDX + { + IsEntry = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxNodeRecursionAMDX(int numberofrecursions) : IEnumerantParameter + { + public int Numberofrecursions { get; set; } = numberofrecursions; + + public static MaxNodeRecursionAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxNodeRecursionAMDX + { + Numberofrecursions = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct StaticNumWorkgroupsAMDX(int xsize, int ysize, int zsize) : IEnumerantParameter + { + public int Xsize { get; set; } = xsize; + public int Ysize { get; set; } = ysize; + public int Zsize { get; set; } = zsize; + + public static StaticNumWorkgroupsAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new StaticNumWorkgroupsAMDX + { + Xsize = reader.ReadInt(), + Ysize = reader.ReadInt(), + Zsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ShaderIndexAMDX(int shaderIndex) : IEnumerantParameter + { + public int ShaderIndex { get; set; } = shaderIndex; + + public static ShaderIndexAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ShaderIndexAMDX + { + ShaderIndex = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxNumWorkgroupsAMDX(int xsize, int ysize, int zsize) : IEnumerantParameter + { + public int Xsize { get; set; } = xsize; + public int Ysize { get; set; } = ysize; + public int Zsize { get; set; } = zsize; + + public static MaxNumWorkgroupsAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxNumWorkgroupsAMDX + { + Xsize = reader.ReadInt(), + Ysize = reader.ReadInt(), + Zsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SharesInputWithAMDX(int nodeName, int shaderIndex) : IEnumerantParameter + { + public int NodeName { get; set; } = nodeName; + public int ShaderIndex { get; set; } = shaderIndex; + + public static SharesInputWithAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SharesInputWithAMDX + { + NodeName = reader.ReadInt(), + ShaderIndex = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct OutputPrimitivesEXT(int primitivecount) : IEnumerantParameter + { + public int Primitivecount { get; set; } = primitivecount; + + public static OutputPrimitivesEXT Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new OutputPrimitivesEXT + { + Primitivecount = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SharedLocalMemorySizeINTEL(int size) : IEnumerantParameter + { + public int Size { get; set; } = size; + + public static SharedLocalMemorySizeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SharedLocalMemorySizeINTEL + { + Size = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct RoundingModeRTPINTEL(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static RoundingModeRTPINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new RoundingModeRTPINTEL + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct RoundingModeRTNINTEL(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static RoundingModeRTNINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new RoundingModeRTNINTEL + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FloatingPointModeALTINTEL(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static FloatingPointModeALTINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FloatingPointModeALTINTEL + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FloatingPointModeIEEEINTEL(int targetWidth) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + + public static FloatingPointModeIEEEINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FloatingPointModeIEEEINTEL + { + TargetWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxWorkgroupSizeINTEL(int maxxsize, int maxysize, int maxzsize) : IEnumerantParameter + { + public int Maxxsize { get; set; } = maxxsize; + public int Maxysize { get; set; } = maxysize; + public int Maxzsize { get; set; } = maxzsize; + + public static MaxWorkgroupSizeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxWorkgroupSizeINTEL + { + Maxxsize = reader.ReadInt(), + Maxysize = reader.ReadInt(), + Maxzsize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxWorkDimINTEL(int maxdimensions) : IEnumerantParameter + { + public int Maxdimensions { get; set; } = maxdimensions; + + public static MaxWorkDimINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxWorkDimINTEL + { + Maxdimensions = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NumSIMDWorkitemsINTEL(int vectorwidth) : IEnumerantParameter + { + public int Vectorwidth { get; set; } = vectorwidth; + + public static NumSIMDWorkitemsINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NumSIMDWorkitemsINTEL + { + Vectorwidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SchedulerTargetFmaxMhzINTEL(int targetfmax) : IEnumerantParameter + { + public int Targetfmax { get; set; } = targetfmax; + + public static SchedulerTargetFmaxMhzINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SchedulerTargetFmaxMhzINTEL + { + Targetfmax = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FPFastMathDefault(int targetType, int fastMathMode) : IEnumerantParameter + { + public int TargetType { get; set; } = targetType; + public int FastMathMode { get; set; } = fastMathMode; + + public static FPFastMathDefault Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FPFastMathDefault + { + TargetType = reader.ReadInt(), + FastMathMode = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct StreamingInterfaceINTEL(int stallFreeReturn) : IEnumerantParameter + { + public int StallFreeReturn { get; set; } = stallFreeReturn; + + public static StreamingInterfaceINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new StreamingInterfaceINTEL + { + StallFreeReturn = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct RegisterMapInterfaceINTEL(int waitForDoneWrite) : IEnumerantParameter + { + public int WaitForDoneWrite { get; set; } = waitForDoneWrite; + + public static RegisterMapInterfaceINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new RegisterMapInterfaceINTEL + { + WaitForDoneWrite = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NamedBarrierCountINTEL(int barrierCount) : IEnumerantParameter + { + public int BarrierCount { get; set; } = barrierCount; + + public static NamedBarrierCountINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NamedBarrierCountINTEL + { + BarrierCount = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaximumRegistersINTEL(int numberofRegisters) : IEnumerantParameter + { + public int NumberofRegisters { get; set; } = numberofRegisters; + + public static MaximumRegistersINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaximumRegistersINTEL + { + NumberofRegisters = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaximumRegistersIdINTEL(int numberofRegisters) : IEnumerantParameter + { + public int NumberofRegisters { get; set; } = numberofRegisters; + + public static MaximumRegistersIdINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaximumRegistersIdINTEL + { + NumberofRegisters = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NamedMaximumRegistersINTEL(NamedMaximumNumberOfRegisters namedMaximumNumberofRegisters) : IEnumerantParameter + { + public NamedMaximumNumberOfRegisters NamedMaximumNumberofRegisters { get; set; } = namedMaximumNumberofRegisters; + + public static NamedMaximumRegistersINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NamedMaximumRegistersINTEL + { + NamedMaximumNumberofRegisters = reader.ReadEnum(), + }; + return parameter; + } + } +} + +public static class DecorationParams +{ + public ref struct SpecId(int specializationConstantID) : IEnumerantParameter + { + public int SpecializationConstantID { get; set; } = specializationConstantID; + + public static SpecId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SpecId + { + SpecializationConstantID = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ArrayStride(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static ArrayStride Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ArrayStride + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MatrixStride(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static MatrixStride Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MatrixStride + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct BuiltInParameter(BuiltIn value) : IEnumerantParameter + { + public BuiltIn Value { get; set; } = value; + + public static BuiltInParameter Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new BuiltInParameter + { + Value = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct UniformId(int execution) : IEnumerantParameter + { + public int Execution { get; set; } = execution; + + public static UniformId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new UniformId + { + Execution = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Stream(int streamNumber) : IEnumerantParameter + { + public int StreamNumber { get; set; } = streamNumber; + + public static Stream Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Stream + { + StreamNumber = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Location(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static Location Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Location + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Component(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static Component Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Component + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Index(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static Index Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Index + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Binding(int bindingPoint) : IEnumerantParameter + { + public int BindingPoint { get; set; } = bindingPoint; + + public static Binding Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Binding + { + BindingPoint = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct DescriptorSet(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static DescriptorSet Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DescriptorSet + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Offset(int byteOffset) : IEnumerantParameter + { + public int ByteOffset { get; set; } = byteOffset; + + public static Offset Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Offset + { + ByteOffset = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct XfbBuffer(int xFBBufferNumber) : IEnumerantParameter + { + public int XFBBufferNumber { get; set; } = xFBBufferNumber; + + public static XfbBuffer Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new XfbBuffer + { + XFBBufferNumber = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct XfbStride(int xFBStride) : IEnumerantParameter + { + public int XFBStride { get; set; } = xFBStride; + + public static XfbStride Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new XfbStride + { + XFBStride = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FuncParamAttr(FunctionParameterAttribute functionParameterAttribute) : IEnumerantParameter + { + public FunctionParameterAttribute FunctionParameterAttribute { get; set; } = functionParameterAttribute; + + public static FuncParamAttr Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FuncParamAttr + { + FunctionParameterAttribute = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct FPRoundingModeParameter(FPRoundingMode value) : IEnumerantParameter + { + public FPRoundingMode Value { get; set; } = value; + + public static FPRoundingModeParameter Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FPRoundingModeParameter + { + Value = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct FPFastMathModeParameter(FPFastMathModeMask value) : IEnumerantParameter + { + public FPFastMathModeMask Value { get; set; } = value; + + public static FPFastMathModeParameter Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FPFastMathModeParameter + { + Value = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct LinkageAttributes(string name, LinkageType linkageType) : IEnumerantParameter + { + public string Name { get; set; } = name; + public LinkageType LinkageType { get; set; } = linkageType; + + public static LinkageAttributes Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LinkageAttributes + { + Name = reader.ReadString(), + LinkageType = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct InputAttachmentIndex(int attachmentIndex) : IEnumerantParameter + { + public int AttachmentIndex { get; set; } = attachmentIndex; + + public static InputAttachmentIndex Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new InputAttachmentIndex + { + AttachmentIndex = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct Alignment(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static Alignment Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new Alignment + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxByteOffset(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static MaxByteOffset Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxByteOffset + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct AlignmentId(int alignment) : IEnumerantParameter + { + public int Alignment { get; set; } = alignment; + + public static AlignmentId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new AlignmentId + { + Alignment = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxByteOffsetId(int maxByteOffset) : IEnumerantParameter + { + public int MaxByteOffset { get; set; } = maxByteOffset; + + public static MaxByteOffsetId Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxByteOffsetId + { + MaxByteOffset = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NodeSharesPayloadLimitsWithAMDX(int payloadType) : IEnumerantParameter + { + public int PayloadType { get; set; } = payloadType; + + public static NodeSharesPayloadLimitsWithAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NodeSharesPayloadLimitsWithAMDX + { + PayloadType = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NodeMaxPayloadsAMDX(int maxnumberofpayloads) : IEnumerantParameter + { + public int Maxnumberofpayloads { get; set; } = maxnumberofpayloads; + + public static NodeMaxPayloadsAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NodeMaxPayloadsAMDX + { + Maxnumberofpayloads = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PayloadNodeNameAMDX(int nodeName) : IEnumerantParameter + { + public int NodeName { get; set; } = nodeName; + + public static PayloadNodeNameAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PayloadNodeNameAMDX + { + NodeName = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PayloadNodeBaseIndexAMDX(int baseIndex) : IEnumerantParameter + { + public int BaseIndex { get; set; } = baseIndex; + + public static PayloadNodeBaseIndexAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PayloadNodeBaseIndexAMDX + { + BaseIndex = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PayloadNodeArraySizeAMDX(int arraySize) : IEnumerantParameter + { + public int ArraySize { get; set; } = arraySize; + + public static PayloadNodeArraySizeAMDX Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PayloadNodeArraySizeAMDX + { + ArraySize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SecondaryViewportRelativeNV(int offset) : IEnumerantParameter + { + public int Offset { get; set; } = offset; + + public static SecondaryViewportRelativeNV Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SecondaryViewportRelativeNV + { + Offset = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct SIMTCallINTEL(int n) : IEnumerantParameter + { + public int N { get; set; } = n; + + public static SIMTCallINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SIMTCallINTEL + { + N = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ClobberINTEL(string register) : IEnumerantParameter + { + public string Register { get; set; } = register; + + public static ClobberINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ClobberINTEL + { + Register = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct FuncParamIOKindINTEL(int kind) : IEnumerantParameter + { + public int Kind { get; set; } = kind; + + public static FuncParamIOKindINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FuncParamIOKindINTEL + { + Kind = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct GlobalVariableOffsetINTEL(int offset) : IEnumerantParameter + { + public int Offset { get; set; } = offset; + + public static GlobalVariableOffsetINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new GlobalVariableOffsetINTEL + { + Offset = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct CounterBuffer(int value) : IEnumerantParameter + { + public int Value { get; set; } = value; + + public static CounterBuffer Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new CounterBuffer + { + Value = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct UserSemantic(string semantic) : IEnumerantParameter + { + public string Semantic { get; set; } = semantic; + + public static UserSemantic Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new UserSemantic + { + Semantic = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct UserTypeGOOGLE(string userType) : IEnumerantParameter + { + public string UserType { get; set; } = userType; + + public static UserTypeGOOGLE Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new UserTypeGOOGLE + { + UserType = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct FunctionRoundingModeINTEL(int targetWidth, FPRoundingMode fPRoundingMode) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + public FPRoundingMode FPRoundingMode { get; set; } = fPRoundingMode; + + public static FunctionRoundingModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FunctionRoundingModeINTEL + { + TargetWidth = reader.ReadInt(), + FPRoundingMode = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct FunctionDenormModeINTEL(int targetWidth, FPDenormMode fPDenormMode) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + public FPDenormMode FPDenormMode { get; set; } = fPDenormMode; + + public static FunctionDenormModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FunctionDenormModeINTEL + { + TargetWidth = reader.ReadInt(), + FPDenormMode = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct MemoryINTEL(string memoryType) : IEnumerantParameter + { + public string MemoryType { get; set; } = memoryType; + + public static MemoryINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MemoryINTEL + { + MemoryType = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct NumbanksINTEL(int banks) : IEnumerantParameter + { + public int Banks { get; set; } = banks; + + public static NumbanksINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NumbanksINTEL + { + Banks = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct BankwidthINTEL(int bankWidth) : IEnumerantParameter + { + public int BankWidth { get; set; } = bankWidth; + + public static BankwidthINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new BankwidthINTEL + { + BankWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxPrivateCopiesINTEL(int maximumCopies) : IEnumerantParameter + { + public int MaximumCopies { get; set; } = maximumCopies; + + public static MaxPrivateCopiesINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxPrivateCopiesINTEL + { + MaximumCopies = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxReplicatesINTEL(int maximumReplicates) : IEnumerantParameter + { + public int MaximumReplicates { get; set; } = maximumReplicates; + + public static MaxReplicatesINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxReplicatesINTEL + { + MaximumReplicates = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MergeINTEL(string mergeKey, string mergeType) : IEnumerantParameter + { + public string MergeKey { get; set; } = mergeKey; + public string MergeType { get; set; } = mergeType; + + public static MergeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MergeINTEL + { + MergeKey = reader.ReadString(), + MergeType = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct BankBitsINTEL(int bankBits) : IEnumerantParameter + { + public int BankBits { get; set; } = bankBits; + + public static BankBitsINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new BankBitsINTEL + { + BankBits = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ForcePow2DepthINTEL(int forceKey) : IEnumerantParameter + { + public int ForceKey { get; set; } = forceKey; + + public static ForcePow2DepthINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ForcePow2DepthINTEL + { + ForceKey = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct StridesizeINTEL(int strideSize) : IEnumerantParameter + { + public int StrideSize { get; set; } = strideSize; + + public static StridesizeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new StridesizeINTEL + { + StrideSize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct WordsizeINTEL(int wordSize) : IEnumerantParameter + { + public int WordSize { get; set; } = wordSize; + + public static WordsizeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new WordsizeINTEL + { + WordSize = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct CacheSizeINTEL(int cacheSizeinbytes) : IEnumerantParameter + { + public int CacheSizeinbytes { get; set; } = cacheSizeinbytes; + + public static CacheSizeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new CacheSizeINTEL + { + CacheSizeinbytes = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PrefetchINTEL(int prefetcherSizeinbytes) : IEnumerantParameter + { + public int PrefetcherSizeinbytes { get; set; } = prefetcherSizeinbytes; + + public static PrefetchINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PrefetchINTEL + { + PrefetcherSizeinbytes = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MathOpDSPModeINTEL(int mode, int propagate) : IEnumerantParameter + { + public int Mode { get; set; } = mode; + public int Propagate { get; set; } = propagate; + + public static MathOpDSPModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MathOpDSPModeINTEL + { + Mode = reader.ReadInt(), + Propagate = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct AliasScopeINTEL(int aliasingScopesList) : IEnumerantParameter + { + public int AliasingScopesList { get; set; } = aliasingScopesList; + + public static AliasScopeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new AliasScopeINTEL + { + AliasingScopesList = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct NoAliasINTEL(int aliasingScopesList) : IEnumerantParameter + { + public int AliasingScopesList { get; set; } = aliasingScopesList; + + public static NoAliasINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new NoAliasINTEL + { + AliasingScopesList = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct InitiationIntervalINTEL(int cycles) : IEnumerantParameter + { + public int Cycles { get; set; } = cycles; + + public static InitiationIntervalINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new InitiationIntervalINTEL + { + Cycles = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MaxConcurrencyINTEL(int invocations) : IEnumerantParameter + { + public int Invocations { get; set; } = invocations; + + public static MaxConcurrencyINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MaxConcurrencyINTEL + { + Invocations = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct PipelineEnableINTEL(int enable) : IEnumerantParameter + { + public int Enable { get; set; } = enable; + + public static PipelineEnableINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new PipelineEnableINTEL + { + Enable = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct BufferLocationINTEL(int bufferLocationID) : IEnumerantParameter + { + public int BufferLocationID { get; set; } = bufferLocationID; + + public static BufferLocationINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new BufferLocationINTEL + { + BufferLocationID = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct IOPipeStorageINTEL(int iOPipeID) : IEnumerantParameter + { + public int IOPipeID { get; set; } = iOPipeID; + + public static IOPipeStorageINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new IOPipeStorageINTEL + { + IOPipeID = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FunctionFloatingPointModeINTEL(int targetWidth, FPOperationMode fPOperationMode) : IEnumerantParameter + { + public int TargetWidth { get; set; } = targetWidth; + public FPOperationMode FPOperationMode { get; set; } = fPOperationMode; + + public static FunctionFloatingPointModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FunctionFloatingPointModeINTEL + { + TargetWidth = reader.ReadInt(), + FPOperationMode = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct FPMaxErrorDecorationINTEL(float maxError) : IEnumerantParameter + { + public float MaxError { get; set; } = maxError; + + public static FPMaxErrorDecorationINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FPMaxErrorDecorationINTEL + { + MaxError = reader.ReadFloat(), + }; + return parameter; + } + } + + public ref struct LatencyControlLabelINTEL(int latencyLabel) : IEnumerantParameter + { + public int LatencyLabel { get; set; } = latencyLabel; + + public static LatencyControlLabelINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LatencyControlLabelINTEL + { + LatencyLabel = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LatencyControlConstraintINTEL(int relativeTo, int controlType, int relativeCycle) : IEnumerantParameter + { + public int RelativeTo { get; set; } = relativeTo; + public int ControlType { get; set; } = controlType; + public int RelativeCycle { get; set; } = relativeCycle; + + public static LatencyControlConstraintINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LatencyControlConstraintINTEL + { + RelativeTo = reader.ReadInt(), + ControlType = reader.ReadInt(), + RelativeCycle = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceAddressWidthINTEL(int addressWidth) : IEnumerantParameter + { + public int AddressWidth { get; set; } = addressWidth; + + public static MMHostInterfaceAddressWidthINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceAddressWidthINTEL + { + AddressWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceDataWidthINTEL(int dataWidth) : IEnumerantParameter + { + public int DataWidth { get; set; } = dataWidth; + + public static MMHostInterfaceDataWidthINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceDataWidthINTEL + { + DataWidth = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceLatencyINTEL(int latency) : IEnumerantParameter + { + public int Latency { get; set; } = latency; + + public static MMHostInterfaceLatencyINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceLatencyINTEL + { + Latency = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceReadWriteModeINTEL(AccessQualifier readWriteMode) : IEnumerantParameter + { + public AccessQualifier ReadWriteMode { get; set; } = readWriteMode; + + public static MMHostInterfaceReadWriteModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceReadWriteModeINTEL + { + ReadWriteMode = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceMaxBurstINTEL(int maxBurstCount) : IEnumerantParameter + { + public int MaxBurstCount { get; set; } = maxBurstCount; + + public static MMHostInterfaceMaxBurstINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceMaxBurstINTEL + { + MaxBurstCount = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct MMHostInterfaceWaitRequestINTEL(int waitrequest) : IEnumerantParameter + { + public int Waitrequest { get; set; } = waitrequest; + + public static MMHostInterfaceWaitRequestINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new MMHostInterfaceWaitRequestINTEL + { + Waitrequest = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct HostAccessINTEL(HostAccessQualifier access, string name) : IEnumerantParameter + { + public HostAccessQualifier Access { get; set; } = access; + public string Name { get; set; } = name; + + public static HostAccessINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new HostAccessINTEL + { + Access = reader.ReadEnum(), + Name = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct InitModeINTEL(InitializationModeQualifier trigger) : IEnumerantParameter + { + public InitializationModeQualifier Trigger { get; set; } = trigger; + + public static InitModeINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new InitModeINTEL + { + Trigger = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct ImplementInRegisterMapINTEL(int parameter0) : IEnumerantParameter + { + public int Parameter0 { get; set; } = parameter0; + + public static ImplementInRegisterMapINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ImplementInRegisterMapINTEL + { + Parameter0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct CacheControlLoadINTEL(int cacheLevel, LoadCacheControl cacheControl) : IEnumerantParameter + { + public int CacheLevel { get; set; } = cacheLevel; + public LoadCacheControl CacheControl { get; set; } = cacheControl; + + public static CacheControlLoadINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new CacheControlLoadINTEL + { + CacheLevel = reader.ReadInt(), + CacheControl = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct CacheControlStoreINTEL(int cacheLevel, StoreCacheControl cacheControl) : IEnumerantParameter + { + public int CacheLevel { get; set; } = cacheLevel; + public StoreCacheControl CacheControl { get; set; } = cacheControl; + + public static CacheControlStoreINTEL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new CacheControlStoreINTEL + { + CacheLevel = reader.ReadInt(), + CacheControl = reader.ReadEnum(), + }; + return parameter; + } + } + + public ref struct LinkSDSL(string name) : IEnumerantParameter + { + public string Name { get; set; } = name; + + public static LinkSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LinkSDSL + { + Name = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct LinkIdSDSL(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static LinkIdSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LinkIdSDSL + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ColorSDSL(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static ColorSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ColorSDSL + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct ResourceGroupSDSL(string resourceGroup) : IEnumerantParameter + { + public string ResourceGroup { get; set; } = resourceGroup; + + public static ResourceGroupSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ResourceGroupSDSL + { + ResourceGroup = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct ResourceGroupIdSDSL(int resourceGroup) : IEnumerantParameter + { + public int ResourceGroup { get; set; } = resourceGroup; + + public static ResourceGroupIdSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new ResourceGroupIdSDSL + { + ResourceGroup = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct LogicalGroupSDSL(string logicalGroup) : IEnumerantParameter + { + public string LogicalGroup { get; set; } = logicalGroup; + + public static LogicalGroupSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new LogicalGroupSDSL + { + LogicalGroup = reader.ReadString(), + }; + return parameter; + } + } + + public ref struct SamplerStateSDSL(int parameter0, int parameter1, int parameter2, int parameter3, int parameter4, int parameter5, int parameter6, int parameter7, int parameter8, int parameter9, int parameter10, int parameter11, int parameter12) : IEnumerantParameter + { + public int Parameter0 { get; set; } = parameter0; + public int Parameter1 { get; set; } = parameter1; + public int Parameter2 { get; set; } = parameter2; + public int Parameter3 { get; set; } = parameter3; + public int Parameter4 { get; set; } = parameter4; + public int Parameter5 { get; set; } = parameter5; + public int Parameter6 { get; set; } = parameter6; + public int Parameter7 { get; set; } = parameter7; + public int Parameter8 { get; set; } = parameter8; + public int Parameter9 { get; set; } = parameter9; + public int Parameter10 { get; set; } = parameter10; + public int Parameter11 { get; set; } = parameter11; + public int Parameter12 { get; set; } = parameter12; + + public static SamplerStateSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new SamplerStateSDSL + { + Parameter0 = reader.ReadInt(), + Parameter1 = reader.ReadInt(), + Parameter2 = reader.ReadInt(), + Parameter3 = reader.ReadInt(), + Parameter4 = reader.ReadInt(), + Parameter5 = reader.ReadInt(), + Parameter6 = reader.ReadInt(), + Parameter7 = reader.ReadInt(), + Parameter8 = reader.ReadInt(), + Parameter9 = reader.ReadInt(), + Parameter10 = reader.ReadInt(), + Parameter11 = reader.ReadInt(), + Parameter12 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct FunctionParameterDefaultValueSDSL(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static FunctionParameterDefaultValueSDSL Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new FunctionParameterDefaultValueSDSL + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } +} + +public static class TensorAddressingOperandsParams +{ + public ref struct TensorView(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static TensorView Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new TensorView + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } + + public ref struct DecodeFunc(int idRef0) : IEnumerantParameter + { + public int IdRef0 { get; set; } = idRef0; + + public static DecodeFunc Create(Span words) + { + var reader = new EnumerantParametersReader(words); + var parameter = new DecodeFunc + { + IdRef0 = reader.ReadInt(), + }; + return parameter; + } + } +} + +public ref partial struct EnumerantParameters +{ + public static implicit operator EnumerantParameters(ImageOperandsParams.Bias parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.Lod parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.Grad parameter) + { + Span span = [parameter.IdRef0, parameter.IdRef1]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.ConstOffset parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.Offset parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.ConstOffsets parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.Sample parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.MinLod parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.MakeTexelAvailable parameter) + { + Span span = [(int)parameter.Idscope0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.MakeTexelVisible parameter) + { + Span span = [(int)parameter.Idscope0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ImageOperandsParams.Offsets parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.DependencyLength parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.MinIterations parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.MaxIterations parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.IterationMultiple parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.PeelCount parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.PartialCount parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.InitiationIntervalINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.MaxConcurrencyINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.DependencyArrayINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.PipelineEnableINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.LoopCoalesceINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.MaxInterleavingINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.SpeculatedIterationsINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.LoopCountINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(LoopControlParams.MaxReinvocationDelayINTEL parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(MemoryAccessParams.Aligned parameter) + { + Span span = [parameter.Literalinteger0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(MemoryAccessParams.MakePointerAvailable parameter) + { + Span span = [(int)parameter.Idscope0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(MemoryAccessParams.MakePointerVisible parameter) + { + Span span = [(int)parameter.Idscope0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(MemoryAccessParams.AliasScopeINTELMask parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(MemoryAccessParams.NoAliasINTELMask parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.Invocations parameter) + { + Span span = [parameter.NumberofInvocationinvocations]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.LocalSize parameter) + { + Span span = [parameter.Xsize, parameter.Ysize, parameter.Zsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.LocalSizeHint parameter) + { + Span span = [parameter.Xsize, parameter.Ysize, parameter.Zsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.OutputVertices parameter) + { + Span span = [parameter.Vertexcount]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.VecTypeHint parameter) + { + Span span = [parameter.Vectortype]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SubgroupSize parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SubgroupsPerWorkgroup parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SubgroupsPerWorkgroupId parameter) + { + Span span = [parameter.SubgroupsPerWorkgroup]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.LocalSizeId parameter) + { + Span span = [parameter.Xsize, parameter.Ysize, parameter.Zsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.LocalSizeHintId parameter) + { + Span span = [parameter.Xsizehint, parameter.Ysizehint, parameter.Zsizehint]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.DenormPreserve parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.DenormFlushToZero parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SignedZeroInfNanPreserve parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.RoundingModeRTE parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.RoundingModeRTZ parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.IsApiEntryAMDX parameter) + { + Span span = [parameter.IsEntry]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaxNodeRecursionAMDX parameter) + { + Span span = [parameter.Numberofrecursions]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.StaticNumWorkgroupsAMDX parameter) + { + Span span = [parameter.Xsize, parameter.Ysize, parameter.Zsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.ShaderIndexAMDX parameter) + { + Span span = [parameter.ShaderIndex]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaxNumWorkgroupsAMDX parameter) + { + Span span = [parameter.Xsize, parameter.Ysize, parameter.Zsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SharesInputWithAMDX parameter) + { + Span span = [parameter.NodeName, parameter.ShaderIndex]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.OutputPrimitivesEXT parameter) + { + Span span = [parameter.Primitivecount]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SharedLocalMemorySizeINTEL parameter) + { + Span span = [parameter.Size]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.RoundingModeRTPINTEL parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.RoundingModeRTNINTEL parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.FloatingPointModeALTINTEL parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.FloatingPointModeIEEEINTEL parameter) + { + Span span = [parameter.TargetWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaxWorkgroupSizeINTEL parameter) + { + Span span = [parameter.Maxxsize, parameter.Maxysize, parameter.Maxzsize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaxWorkDimINTEL parameter) + { + Span span = [parameter.Maxdimensions]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.NumSIMDWorkitemsINTEL parameter) + { + Span span = [parameter.Vectorwidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.SchedulerTargetFmaxMhzINTEL parameter) + { + Span span = [parameter.Targetfmax]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.FPFastMathDefault parameter) + { + Span span = [parameter.TargetType, parameter.FastMathMode]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.StreamingInterfaceINTEL parameter) + { + Span span = [parameter.StallFreeReturn]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.RegisterMapInterfaceINTEL parameter) + { + Span span = [parameter.WaitForDoneWrite]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.NamedBarrierCountINTEL parameter) + { + Span span = [parameter.BarrierCount]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaximumRegistersINTEL parameter) + { + Span span = [parameter.NumberofRegisters]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.MaximumRegistersIdINTEL parameter) + { + Span span = [parameter.NumberofRegisters]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(ExecutionModeParams.NamedMaximumRegistersINTEL parameter) + { + Span span = [(int)parameter.NamedMaximumNumberofRegisters]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.SpecId parameter) + { + Span span = [parameter.SpecializationConstantID]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ArrayStride parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MatrixStride parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.BuiltInParameter parameter) + { + Span span = [(int)parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.UniformId parameter) + { + Span span = [(int)parameter.Execution]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Stream parameter) + { + Span span = [parameter.StreamNumber]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Location parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Component parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Index parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Binding parameter) + { + Span span = [parameter.BindingPoint]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.DescriptorSet parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Offset parameter) + { + Span span = [parameter.ByteOffset]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.XfbBuffer parameter) + { + Span span = [parameter.XFBBufferNumber]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.XfbStride parameter) + { + Span span = [parameter.XFBStride]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FuncParamAttr parameter) + { + Span span = [(int)parameter.FunctionParameterAttribute]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FPRoundingModeParameter parameter) + { + Span span = [(int)parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FPFastMathModeParameter parameter) + { + Span span = [(int)parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LinkageAttributes parameter) + { + Span span = [..parameter.Name.AsDisposableLiteralValue().Words, (int)parameter.LinkageType]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.InputAttachmentIndex parameter) + { + Span span = [parameter.AttachmentIndex]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.Alignment parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MaxByteOffset parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.AlignmentId parameter) + { + Span span = [parameter.Alignment]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MaxByteOffsetId parameter) + { + Span span = [parameter.MaxByteOffset]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.NodeSharesPayloadLimitsWithAMDX parameter) + { + Span span = [parameter.PayloadType]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.NodeMaxPayloadsAMDX parameter) + { + Span span = [parameter.Maxnumberofpayloads]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.PayloadNodeNameAMDX parameter) + { + Span span = [parameter.NodeName]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.PayloadNodeBaseIndexAMDX parameter) + { + Span span = [parameter.BaseIndex]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.PayloadNodeArraySizeAMDX parameter) + { + Span span = [parameter.ArraySize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.SecondaryViewportRelativeNV parameter) + { + Span span = [parameter.Offset]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.SIMTCallINTEL parameter) + { + Span span = [parameter.N]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ClobberINTEL parameter) + { + Span span = [..parameter.Register.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FuncParamIOKindINTEL parameter) + { + Span span = [parameter.Kind]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.GlobalVariableOffsetINTEL parameter) + { + Span span = [parameter.Offset]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.CounterBuffer parameter) + { + Span span = [parameter.Value]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.UserSemantic parameter) + { + Span span = [..parameter.Semantic.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.UserTypeGOOGLE parameter) + { + Span span = [..parameter.UserType.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FunctionRoundingModeINTEL parameter) + { + Span span = [parameter.TargetWidth, (int)parameter.FPRoundingMode]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FunctionDenormModeINTEL parameter) + { + Span span = [parameter.TargetWidth, (int)parameter.FPDenormMode]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MemoryINTEL parameter) + { + Span span = [..parameter.MemoryType.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.NumbanksINTEL parameter) + { + Span span = [parameter.Banks]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.BankwidthINTEL parameter) + { + Span span = [parameter.BankWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MaxPrivateCopiesINTEL parameter) + { + Span span = [parameter.MaximumCopies]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MaxReplicatesINTEL parameter) + { + Span span = [parameter.MaximumReplicates]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MergeINTEL parameter) + { + Span span = [..parameter.MergeKey.AsDisposableLiteralValue().Words, ..parameter.MergeType.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.BankBitsINTEL parameter) + { + Span span = [parameter.BankBits]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ForcePow2DepthINTEL parameter) + { + Span span = [parameter.ForceKey]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.StridesizeINTEL parameter) + { + Span span = [parameter.StrideSize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.WordsizeINTEL parameter) + { + Span span = [parameter.WordSize]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.CacheSizeINTEL parameter) + { + Span span = [parameter.CacheSizeinbytes]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.PrefetchINTEL parameter) + { + Span span = [parameter.PrefetcherSizeinbytes]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MathOpDSPModeINTEL parameter) + { + Span span = [parameter.Mode, parameter.Propagate]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.AliasScopeINTEL parameter) + { + Span span = [parameter.AliasingScopesList]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.NoAliasINTEL parameter) + { + Span span = [parameter.AliasingScopesList]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.InitiationIntervalINTEL parameter) + { + Span span = [parameter.Cycles]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MaxConcurrencyINTEL parameter) + { + Span span = [parameter.Invocations]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.PipelineEnableINTEL parameter) + { + Span span = [parameter.Enable]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.BufferLocationINTEL parameter) + { + Span span = [parameter.BufferLocationID]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.IOPipeStorageINTEL parameter) + { + Span span = [parameter.IOPipeID]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FunctionFloatingPointModeINTEL parameter) + { + Span span = [parameter.TargetWidth, (int)parameter.FPOperationMode]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FPMaxErrorDecorationINTEL parameter) + { + Span span = [BitConverter.SingleToInt32Bits(parameter.MaxError)]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LatencyControlLabelINTEL parameter) + { + Span span = [parameter.LatencyLabel]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LatencyControlConstraintINTEL parameter) + { + Span span = [parameter.RelativeTo, parameter.ControlType, parameter.RelativeCycle]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceAddressWidthINTEL parameter) + { + Span span = [parameter.AddressWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceDataWidthINTEL parameter) + { + Span span = [parameter.DataWidth]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceLatencyINTEL parameter) + { + Span span = [parameter.Latency]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceReadWriteModeINTEL parameter) + { + Span span = [(int)parameter.ReadWriteMode]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceMaxBurstINTEL parameter) + { + Span span = [parameter.MaxBurstCount]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.MMHostInterfaceWaitRequestINTEL parameter) + { + Span span = [parameter.Waitrequest]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.HostAccessINTEL parameter) + { + Span span = [(int)parameter.Access, ..parameter.Name.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.InitModeINTEL parameter) + { + Span span = [(int)parameter.Trigger]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ImplementInRegisterMapINTEL parameter) + { + Span span = [parameter.Parameter0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.CacheControlLoadINTEL parameter) + { + Span span = [parameter.CacheLevel, (int)parameter.CacheControl]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.CacheControlStoreINTEL parameter) + { + Span span = [parameter.CacheLevel, (int)parameter.CacheControl]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LinkSDSL parameter) + { + Span span = [..parameter.Name.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LinkIdSDSL parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ColorSDSL parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ResourceGroupSDSL parameter) + { + Span span = [..parameter.ResourceGroup.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.ResourceGroupIdSDSL parameter) + { + Span span = [parameter.ResourceGroup]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.LogicalGroupSDSL parameter) + { + Span span = [..parameter.LogicalGroup.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.SamplerStateSDSL parameter) + { + Span span = [parameter.Parameter0, parameter.Parameter1, parameter.Parameter2, parameter.Parameter3, parameter.Parameter4, parameter.Parameter5, parameter.Parameter6, parameter.Parameter7, parameter.Parameter8, parameter.Parameter9, parameter.Parameter10, parameter.Parameter11, parameter.Parameter12]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(DecorationParams.FunctionParameterDefaultValueSDSL parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(TensorAddressingOperandsParams.TensorView parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters(TensorAddressingOperandsParams.DecodeFunc parameter) + { + Span span = [parameter.IdRef0]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, int) tuple) + { + Span span = [tuple.Item1, tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, int, int) tuple) + { + Span span = [tuple.Item1, tuple.Item2, tuple.Item3]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((string, LinkageType) tuple) + { + Span span = [..tuple.Item1.AsDisposableLiteralValue().Words, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, FPRoundingMode) tuple) + { + Span span = [tuple.Item1, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, FPDenormMode) tuple) + { + Span span = [tuple.Item1, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((string, string) tuple) + { + Span span = [..tuple.Item1.AsDisposableLiteralValue().Words, ..tuple.Item2.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, FPOperationMode) tuple) + { + Span span = [tuple.Item1, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((HostAccessQualifier, string) tuple) + { + Span span = [(int)tuple.Item1, ..tuple.Item2.AsDisposableLiteralValue().Words]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, LoadCacheControl) tuple) + { + Span span = [tuple.Item1, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, StoreCacheControl) tuple) + { + Span span = [tuple.Item1, (int)tuple.Item2]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } + + public static implicit operator EnumerantParameters((int, int, int, int, int, int, int, int, int, int, int, int, int) tuple) + { + Span span = [tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, tuple.Item6, tuple.Item7, tuple.Item8, tuple.Item9, tuple.Item10, tuple.Item11, tuple.Item12, tuple.Item13]; + MemoryOwner buffer = MemoryOwner.Allocate(span.Length); + span.CopyTo(buffer.Span); + var result = new EnumerantParameters(buffer); + return result; + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/InstructionInfo.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/InstructionInfo.gen.cs new file mode 100644 index 0000000000..29ef1fac55 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/InstructionInfo.gen.cs @@ -0,0 +1,3327 @@ +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Core; +public partial class InstructionInfo +{ + static InstructionInfo() + { + Instance.Register(Op.OpNop, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpUndef, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpUndef, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpSourceContinued, OperandKind.LiteralString, OperandQuantifier.One, "continuedSource", "Debug", []); + Instance.Register(Op.OpSource, OperandKind.SourceLanguage, OperandQuantifier.One, "sourceLanguage", "Debug", []); + Instance.Register(Op.OpSource, OperandKind.LiteralInteger, OperandQuantifier.One, "version", "Debug", []); + Instance.Register(Op.OpSource, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "file", "Debug", []); + Instance.Register(Op.OpSource, OperandKind.LiteralString, OperandQuantifier.ZeroOrOne, "source", "Debug", []); + Instance.Register(Op.OpSourceExtension, OperandKind.LiteralString, OperandQuantifier.One, "extension", "Debug", []); + Instance.Register(Op.OpName, OperandKind.IdRef, OperandQuantifier.One, "target", "Debug", []); + Instance.Register(Op.OpName, OperandKind.LiteralString, OperandQuantifier.One, "name", "Debug", []); + Instance.Register(Op.OpMemberName, OperandKind.IdRef, OperandQuantifier.One, "type", "Debug", []); + Instance.Register(Op.OpMemberName, OperandKind.LiteralInteger, OperandQuantifier.One, "member", "Debug", []); + Instance.Register(Op.OpMemberName, OperandKind.LiteralString, OperandQuantifier.One, "name", "Debug", []); + Instance.Register(Op.OpString, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Debug", []); + Instance.Register(Op.OpString, OperandKind.LiteralString, OperandQuantifier.One, "value", "Debug", []); + Instance.Register(Op.OpLine, OperandKind.IdRef, OperandQuantifier.One, "file", "Debug", []); + Instance.Register(Op.OpLine, OperandKind.LiteralInteger, OperandQuantifier.One, "line", "Debug", []); + Instance.Register(Op.OpLine, OperandKind.LiteralInteger, OperandQuantifier.One, "column", "Debug", []); + Instance.Register(Op.OpExtension, OperandKind.LiteralString, OperandQuantifier.One, "name", "Extension", []); + Instance.Register(Op.OpExtInstImport, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Extension", []); + Instance.Register(Op.OpExtInstImport, OperandKind.LiteralString, OperandQuantifier.One, "name", "Extension", []); + Instance.Register(Op.OpExtInst, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Extension", []); + Instance.Register(Op.OpExtInst, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Extension", []); + Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.One, "set", "Extension", []); + Instance.Register(Op.OpExtInst, OperandKind.LiteralExtInstInteger, OperandQuantifier.One, "instruction", "Extension", []); + Instance.Register(Op.OpExtInst, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "operands", "Extension", []); + Instance.Register(Op.OpMemoryModel, OperandKind.AddressingModel, OperandQuantifier.One, "addressingModel", "Mode-Setting", []); + Instance.Register(Op.OpMemoryModel, OperandKind.MemoryModel, OperandQuantifier.One, "memoryModel", "Mode-Setting", []); + Instance.Register(Op.OpEntryPoint, OperandKind.ExecutionModel, OperandQuantifier.One, "executionModel", "Mode-Setting", []); + Instance.Register(Op.OpEntryPoint, OperandKind.IdRef, OperandQuantifier.One, "entryPoint", "Mode-Setting", []); + Instance.Register(Op.OpEntryPoint, OperandKind.LiteralString, OperandQuantifier.One, "name", "Mode-Setting", []); + Instance.Register(Op.OpEntryPoint, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "interfaceIds", "Mode-Setting", []); + Instance.Register(Op.OpExecutionMode, OperandKind.IdRef, OperandQuantifier.One, "entryPoint", "Mode-Setting", []); + Instance.Register(Op.OpExecutionMode, OperandKind.ExecutionMode, OperandQuantifier.One, "mode", "Mode-Setting", new() { [new(OperandKind.ExecutionMode, 0)] = [new("numberofInvocationinvocations", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 17)] = [new("xsize", OperandKind.LiteralInteger), new("ysize", OperandKind.LiteralInteger), new("zsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 18)] = [new("xsize", OperandKind.LiteralInteger), new("ysize", OperandKind.LiteralInteger), new("zsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 26)] = [new("vertexcount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 30)] = [new("vectortype", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 35)] = [new("subgroupSize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 36)] = [new("subgroupsPerWorkgroup", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 37)] = [new("subgroupsPerWorkgroup", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 38)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 39)] = [new("xsizehint", OperandKind.IdRef), new("ysizehint", OperandKind.IdRef), new("zsizehint", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 4459)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4460)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4461)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4462)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4463)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5070)] = [new("isEntry", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5071)] = [new("numberofrecursions", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5072)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5073)] = [new("shaderIndex", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5077)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5102)] = [new("nodeName", OperandKind.IdRef), new("shaderIndex", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5270)] = [new("primitivecount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5618)] = [new("size", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5620)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5621)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5622)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5623)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5893)] = [new("maxxsize", OperandKind.LiteralInteger), new("maxysize", OperandKind.LiteralInteger), new("maxzsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5894)] = [new("maxdimensions", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5896)] = [new("vectorwidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5903)] = [new("targetfmax", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6028)] = [new("targetType", OperandKind.IdRef), new("fastMathMode", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 6154)] = [new("stallFreeReturn", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6160)] = [new("waitForDoneWrite", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6417)] = [new("barrierCount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6461)] = [new("numberofRegisters", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6462)] = [new("numberofRegisters", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 6463)] = [new("namedMaximumNumberofRegisters", OperandKind.NamedMaximumNumberOfRegisters)] }); + Instance.Register(Op.OpCapability, OperandKind.Capability, OperandQuantifier.One, "capability", "Mode-Setting", []); + Instance.Register(Op.OpTypeVoid, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeBool, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeInt, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeInt, OperandKind.LiteralInteger, OperandQuantifier.One, "width", "Type-Declaration", []); + Instance.Register(Op.OpTypeInt, OperandKind.LiteralInteger, OperandQuantifier.One, "signedness", "Type-Declaration", []); + Instance.Register(Op.OpTypeFloat, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeFloat, OperandKind.LiteralInteger, OperandQuantifier.One, "width", "Type-Declaration", []); + Instance.Register(Op.OpTypeFloat, OperandKind.FPEncoding, OperandQuantifier.ZeroOrOne, "floatingPointEncoding", "Type-Declaration", []); + Instance.Register(Op.OpTypeVector, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeVector, OperandKind.IdRef, OperandQuantifier.One, "componentType", "Type-Declaration", []); + Instance.Register(Op.OpTypeVector, OperandKind.LiteralInteger, OperandQuantifier.One, "componentCount", "Type-Declaration", []); + Instance.Register(Op.OpTypeMatrix, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeMatrix, OperandKind.IdRef, OperandQuantifier.One, "columnType", "Type-Declaration", []); + Instance.Register(Op.OpTypeMatrix, OperandKind.LiteralInteger, OperandQuantifier.One, "columnCount", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.IdRef, OperandQuantifier.One, "sampledType", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.Dim, OperandQuantifier.One, "dim", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.LiteralInteger, OperandQuantifier.One, "depth", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.LiteralInteger, OperandQuantifier.One, "arrayed", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.LiteralInteger, OperandQuantifier.One, "mS", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.LiteralInteger, OperandQuantifier.One, "sampled", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.ImageFormat, OperandQuantifier.One, "imageFormat", "Type-Declaration", []); + Instance.Register(Op.OpTypeImage, OperandKind.AccessQualifier, OperandQuantifier.ZeroOrOne, "accessQualifier", "Type-Declaration", []); + Instance.Register(Op.OpTypeSampler, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeSampledImage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeSampledImage, OperandKind.IdRef, OperandQuantifier.One, "imageType", "Type-Declaration", []); + Instance.Register(Op.OpTypeArray, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeArray, OperandKind.IdRef, OperandQuantifier.One, "elementType", "Type-Declaration", []); + Instance.Register(Op.OpTypeArray, OperandKind.IdRef, OperandQuantifier.One, "length", "Type-Declaration", []); + Instance.Register(Op.OpTypeRuntimeArray, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeRuntimeArray, OperandKind.IdRef, OperandQuantifier.One, "elementType", "Type-Declaration", []); + Instance.Register(Op.OpTypeStruct, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeStruct, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "memberTypes", "Type-Declaration", []); + Instance.Register(Op.OpTypeOpaque, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeOpaque, OperandKind.LiteralString, OperandQuantifier.One, "thenameoftheopaquetype", "Type-Declaration", []); + Instance.Register(Op.OpTypePointer, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypePointer, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Type-Declaration", []); + Instance.Register(Op.OpTypePointer, OperandKind.IdRef, OperandQuantifier.One, "type", "Type-Declaration", []); + Instance.Register(Op.OpTypeFunction, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeFunction, OperandKind.IdRef, OperandQuantifier.One, "returnType", "Type-Declaration", []); + Instance.Register(Op.OpTypeFunction, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "parameterTypes", "Type-Declaration", []); + Instance.Register(Op.OpTypeEvent, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeDeviceEvent, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeReserveId, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeQueue, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypePipe, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypePipe, OperandKind.AccessQualifier, OperandQuantifier.One, "qualifier", "Type-Declaration", []); + Instance.Register(Op.OpTypeForwardPointer, OperandKind.IdRef, OperandQuantifier.One, "pointerType", "Type-Declaration", []); + Instance.Register(Op.OpTypeForwardPointer, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Type-Declaration", []); + Instance.Register(Op.OpConstantTrue, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantTrue, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstantFalse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantFalse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstant, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstant, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstant, OperandKind.LiteralContextDependentNumber, OperandQuantifier.One, "value", "Constant-Creation", []); + Instance.Register(Op.OpConstantComposite, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantComposite, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstantComposite, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Constant-Creation", []); + Instance.Register(Op.OpConstantSampler, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantSampler, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstantSampler, OperandKind.SamplerAddressingMode, OperandQuantifier.One, "samplerAddressingMode", "Constant-Creation", []); + Instance.Register(Op.OpConstantSampler, OperandKind.LiteralInteger, OperandQuantifier.One, "param", "Constant-Creation", []); + Instance.Register(Op.OpConstantSampler, OperandKind.SamplerFilterMode, OperandQuantifier.One, "samplerFilterMode", "Constant-Creation", []); + Instance.Register(Op.OpConstantNull, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantNull, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantTrue, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantTrue, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantFalse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantFalse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstant, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstant, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstant, OperandKind.LiteralContextDependentNumber, OperandQuantifier.One, "value", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantComposite, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantComposite, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantComposite, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantOp, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantOp, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantOp, OperandKind.LiteralSpecConstantOpInteger, OperandQuantifier.One, "opcode", "Constant-Creation", []); + Instance.Register(Op.OpFunction, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Function", []); + Instance.Register(Op.OpFunction, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Function", []); + Instance.Register(Op.OpFunction, OperandKind.FunctionControl, OperandQuantifier.One, "functionControl", "Function", []); + Instance.Register(Op.OpFunction, OperandKind.IdRef, OperandQuantifier.One, "functionType", "Function", []); + Instance.Register(Op.OpFunctionParameter, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Function", []); + Instance.Register(Op.OpFunctionParameter, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Function", []); + Instance.Register(Op.OpFunctionEnd, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpFunctionCall, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Function", []); + Instance.Register(Op.OpFunctionCall, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Function", []); + Instance.Register(Op.OpFunctionCall, OperandKind.IdRef, OperandQuantifier.One, "function", "Function", []); + Instance.Register(Op.OpFunctionCall, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "arguments", "Function", []); + Instance.Register(Op.OpVariable, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpVariable, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpVariable, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Memory", []); + Instance.Register(Op.OpVariable, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "initializer", "Memory", []); + Instance.Register(Op.OpImageTexelPointer, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpImageTexelPointer, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpImageTexelPointer, OperandKind.IdRef, OperandQuantifier.One, "image", "Memory", []); + Instance.Register(Op.OpImageTexelPointer, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Memory", []); + Instance.Register(Op.OpImageTexelPointer, OperandKind.IdRef, OperandQuantifier.One, "sample", "Memory", []); + Instance.Register(Op.OpLoad, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpLoad, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpLoad, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpLoad, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpStore, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpStore, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Memory", []); + Instance.Register(Op.OpStore, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCopyMemory, OperandKind.IdRef, OperandQuantifier.One, "target", "Memory", []); + Instance.Register(Op.OpCopyMemory, OperandKind.IdRef, OperandQuantifier.One, "source", "Memory", []); + Instance.Register(Op.OpCopyMemory, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCopyMemory, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess1", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCopyMemorySized, OperandKind.IdRef, OperandQuantifier.One, "target", "Memory", []); + Instance.Register(Op.OpCopyMemorySized, OperandKind.IdRef, OperandQuantifier.One, "source", "Memory", []); + Instance.Register(Op.OpCopyMemorySized, OperandKind.IdRef, OperandQuantifier.One, "size", "Memory", []); + Instance.Register(Op.OpCopyMemorySized, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCopyMemorySized, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess1", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpAccessChain, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpAccessChain, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpAccessChain, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpAccessChain, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpInBoundsAccessChain, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpInBoundsAccessChain, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpInBoundsAccessChain, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpInBoundsAccessChain, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpPtrAccessChain, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpPtrAccessChain, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpPtrAccessChain, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpPtrAccessChain, OperandKind.IdRef, OperandQuantifier.One, "element", "Memory", []); + Instance.Register(Op.OpPtrAccessChain, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpArrayLength, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpArrayLength, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpArrayLength, OperandKind.IdRef, OperandQuantifier.One, "structure", "Memory", []); + Instance.Register(Op.OpArrayLength, OperandKind.LiteralInteger, OperandQuantifier.One, "arraymember", "Memory", []); + Instance.Register(Op.OpGenericPtrMemSemantics, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpGenericPtrMemSemantics, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpGenericPtrMemSemantics, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpInBoundsPtrAccessChain, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpInBoundsPtrAccessChain, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpInBoundsPtrAccessChain, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpInBoundsPtrAccessChain, OperandKind.IdRef, OperandQuantifier.One, "element", "Memory", []); + Instance.Register(Op.OpInBoundsPtrAccessChain, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpDecorate, OperandKind.IdRef, OperandQuantifier.One, "target", "Annotation", []); + Instance.Register(Op.OpDecorate, OperandKind.Decoration, OperandQuantifier.One, "decoration", "Annotation", new() { [new(OperandKind.Decoration, 1)] = [new("specializationConstantID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6)] = [new("arrayStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 7)] = [new("matrixStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 11)] = [new("builtin0", OperandKind.BuiltIn)], [new(OperandKind.Decoration, 27)] = [new("execution", OperandKind.IdScope)], [new(OperandKind.Decoration, 29)] = [new("streamNumber", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 30)] = [new("location", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 31)] = [new("component", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 32)] = [new("index", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 33)] = [new("bindingPoint", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 34)] = [new("descriptorSet", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 35)] = [new("byteOffset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 36)] = [new("xFBBufferNumber", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 37)] = [new("xFBStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 38)] = [new("functionParameterAttribute", OperandKind.FunctionParameterAttribute)], [new(OperandKind.Decoration, 39)] = [new("floatingPointRoundingMode", OperandKind.FPRoundingMode)], [new(OperandKind.Decoration, 40)] = [new("fastMathMode", OperandKind.FPFastMathMode)], [new(OperandKind.Decoration, 41)] = [new("name", OperandKind.LiteralString), new("linkageType", OperandKind.LinkageType)], [new(OperandKind.Decoration, 43)] = [new("attachmentIndex", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 44)] = [new("alignment", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 45)] = [new("maxByteOffset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 46)] = [new("alignment", OperandKind.IdRef)], [new(OperandKind.Decoration, 47)] = [new("maxByteOffset", OperandKind.IdRef)], [new(OperandKind.Decoration, 5019)] = [new("payloadType", OperandKind.IdRef)], [new(OperandKind.Decoration, 5020)] = [new("maxnumberofpayloads", OperandKind.IdRef)], [new(OperandKind.Decoration, 5091)] = [new("nodeName", OperandKind.IdRef)], [new(OperandKind.Decoration, 5098)] = [new("baseIndex", OperandKind.IdRef)], [new(OperandKind.Decoration, 5100)] = [new("arraySize", OperandKind.IdRef)], [new(OperandKind.Decoration, 5256)] = [new("offset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5599)] = [new("n", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5607)] = [new("register", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5625)] = [new("kind", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5628)] = [new("offset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5634)] = [new("counterBuffer", OperandKind.IdRef)], [new(OperandKind.Decoration, 5635)] = [new("semantic", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5636)] = [new("userType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5822)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPRoundingMode", OperandKind.FPRoundingMode)], [new(OperandKind.Decoration, 5823)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPDenormMode", OperandKind.FPDenormMode)], [new(OperandKind.Decoration, 5826)] = [new("memoryType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5827)] = [new("banks", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5828)] = [new("bankWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5829)] = [new("maximumCopies", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5832)] = [new("maximumReplicates", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5834)] = [new("mergeKey", OperandKind.LiteralString), new("mergeType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5835)] = [new("bankBits", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5836)] = [new("forceKey", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5883)] = [new("strideSize", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5884)] = [new("wordSize", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5900)] = [new("cacheSizeinbytes", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5902)] = [new("prefetcherSizeinbytes", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5909)] = [new("mode", OperandKind.LiteralInteger), new("propagate", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5914)] = [new("aliasingScopesList", OperandKind.IdRef)], [new(OperandKind.Decoration, 5915)] = [new("aliasingScopesList", OperandKind.IdRef)], [new(OperandKind.Decoration, 5917)] = [new("cycles", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5918)] = [new("invocations", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5919)] = [new("enable", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5921)] = [new("bufferLocationID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5944)] = [new("iOPipeID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6080)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPOperationMode", OperandKind.FPOperationMode)], [new(OperandKind.Decoration, 6170)] = [new("maxError", OperandKind.LiteralFloat)], [new(OperandKind.Decoration, 6172)] = [new("latencyLabel", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6173)] = [new("relativeTo", OperandKind.LiteralInteger), new("controlType", OperandKind.LiteralInteger), new("relativeCycle", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6177)] = [new("addressWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6178)] = [new("dataWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6179)] = [new("latency", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6180)] = [new("readWriteMode", OperandKind.AccessQualifier)], [new(OperandKind.Decoration, 6181)] = [new("maxBurstCount", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6182)] = [new("waitrequest", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6188)] = [new("access", OperandKind.HostAccessQualifier), new("name", OperandKind.LiteralString)], [new(OperandKind.Decoration, 6190)] = [new("trigger", OperandKind.InitializationModeQualifier)], [new(OperandKind.Decoration, 6191)] = [new("parameter0", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6442)] = [new("cacheLevel", OperandKind.LiteralInteger), new("cacheControl", OperandKind.LoadCacheControl)], [new(OperandKind.Decoration, 6443)] = [new("cacheLevel", OperandKind.LiteralInteger), new("cacheControl", OperandKind.StoreCacheControl)], [new(OperandKind.Decoration, 8000)] = [new("name", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8001)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.Decoration, 8002)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.Decoration, 8010)] = [new("resourceGroup", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8011)] = [new("resourceGroup", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 8004)] = [new("logicalGroup", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8020)] = [new("parameter0", OperandKind.LiteralInteger), new("parameter1", OperandKind.LiteralInteger), new("parameter2", OperandKind.LiteralInteger), new("parameter3", OperandKind.LiteralInteger), new("parameter4", OperandKind.LiteralInteger), new("parameter5", OperandKind.LiteralInteger), new("parameter6", OperandKind.LiteralInteger), new("parameter7", OperandKind.LiteralInteger), new("parameter8", OperandKind.LiteralInteger), new("parameter9", OperandKind.LiteralInteger), new("parameter10", OperandKind.LiteralInteger), new("parameter11", OperandKind.LiteralInteger), new("parameter12", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 8040)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpMemberDecorate, OperandKind.IdRef, OperandQuantifier.One, "structureType", "Annotation", []); + Instance.Register(Op.OpMemberDecorate, OperandKind.LiteralInteger, OperandQuantifier.One, "member", "Annotation", []); + Instance.Register(Op.OpMemberDecorate, OperandKind.Decoration, OperandQuantifier.One, "decoration", "Annotation", new() { [new(OperandKind.Decoration, 1)] = [new("specializationConstantID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6)] = [new("arrayStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 7)] = [new("matrixStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 11)] = [new("builtin0", OperandKind.BuiltIn)], [new(OperandKind.Decoration, 27)] = [new("execution", OperandKind.IdScope)], [new(OperandKind.Decoration, 29)] = [new("streamNumber", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 30)] = [new("location", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 31)] = [new("component", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 32)] = [new("index", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 33)] = [new("bindingPoint", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 34)] = [new("descriptorSet", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 35)] = [new("byteOffset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 36)] = [new("xFBBufferNumber", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 37)] = [new("xFBStride", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 38)] = [new("functionParameterAttribute", OperandKind.FunctionParameterAttribute)], [new(OperandKind.Decoration, 39)] = [new("floatingPointRoundingMode", OperandKind.FPRoundingMode)], [new(OperandKind.Decoration, 40)] = [new("fastMathMode", OperandKind.FPFastMathMode)], [new(OperandKind.Decoration, 41)] = [new("name", OperandKind.LiteralString), new("linkageType", OperandKind.LinkageType)], [new(OperandKind.Decoration, 43)] = [new("attachmentIndex", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 44)] = [new("alignment", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 45)] = [new("maxByteOffset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 46)] = [new("alignment", OperandKind.IdRef)], [new(OperandKind.Decoration, 47)] = [new("maxByteOffset", OperandKind.IdRef)], [new(OperandKind.Decoration, 5019)] = [new("payloadType", OperandKind.IdRef)], [new(OperandKind.Decoration, 5020)] = [new("maxnumberofpayloads", OperandKind.IdRef)], [new(OperandKind.Decoration, 5091)] = [new("nodeName", OperandKind.IdRef)], [new(OperandKind.Decoration, 5098)] = [new("baseIndex", OperandKind.IdRef)], [new(OperandKind.Decoration, 5100)] = [new("arraySize", OperandKind.IdRef)], [new(OperandKind.Decoration, 5256)] = [new("offset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5599)] = [new("n", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5607)] = [new("register", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5625)] = [new("kind", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5628)] = [new("offset", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5634)] = [new("counterBuffer", OperandKind.IdRef)], [new(OperandKind.Decoration, 5635)] = [new("semantic", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5636)] = [new("userType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5822)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPRoundingMode", OperandKind.FPRoundingMode)], [new(OperandKind.Decoration, 5823)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPDenormMode", OperandKind.FPDenormMode)], [new(OperandKind.Decoration, 5826)] = [new("memoryType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5827)] = [new("banks", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5828)] = [new("bankWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5829)] = [new("maximumCopies", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5832)] = [new("maximumReplicates", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5834)] = [new("mergeKey", OperandKind.LiteralString), new("mergeType", OperandKind.LiteralString)], [new(OperandKind.Decoration, 5835)] = [new("bankBits", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5836)] = [new("forceKey", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5883)] = [new("strideSize", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5884)] = [new("wordSize", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5900)] = [new("cacheSizeinbytes", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5902)] = [new("prefetcherSizeinbytes", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5909)] = [new("mode", OperandKind.LiteralInteger), new("propagate", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5914)] = [new("aliasingScopesList", OperandKind.IdRef)], [new(OperandKind.Decoration, 5915)] = [new("aliasingScopesList", OperandKind.IdRef)], [new(OperandKind.Decoration, 5917)] = [new("cycles", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5918)] = [new("invocations", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5919)] = [new("enable", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5921)] = [new("bufferLocationID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 5944)] = [new("iOPipeID", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6080)] = [new("targetWidth", OperandKind.LiteralInteger), new("fPOperationMode", OperandKind.FPOperationMode)], [new(OperandKind.Decoration, 6170)] = [new("maxError", OperandKind.LiteralFloat)], [new(OperandKind.Decoration, 6172)] = [new("latencyLabel", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6173)] = [new("relativeTo", OperandKind.LiteralInteger), new("controlType", OperandKind.LiteralInteger), new("relativeCycle", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6177)] = [new("addressWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6178)] = [new("dataWidth", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6179)] = [new("latency", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6180)] = [new("readWriteMode", OperandKind.AccessQualifier)], [new(OperandKind.Decoration, 6181)] = [new("maxBurstCount", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6182)] = [new("waitrequest", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6188)] = [new("access", OperandKind.HostAccessQualifier), new("name", OperandKind.LiteralString)], [new(OperandKind.Decoration, 6190)] = [new("trigger", OperandKind.InitializationModeQualifier)], [new(OperandKind.Decoration, 6191)] = [new("parameter0", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 6442)] = [new("cacheLevel", OperandKind.LiteralInteger), new("cacheControl", OperandKind.LoadCacheControl)], [new(OperandKind.Decoration, 6443)] = [new("cacheLevel", OperandKind.LiteralInteger), new("cacheControl", OperandKind.StoreCacheControl)], [new(OperandKind.Decoration, 8000)] = [new("name", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8001)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.Decoration, 8002)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.Decoration, 8010)] = [new("resourceGroup", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8011)] = [new("resourceGroup", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 8004)] = [new("logicalGroup", OperandKind.LiteralString)], [new(OperandKind.Decoration, 8020)] = [new("parameter0", OperandKind.LiteralInteger), new("parameter1", OperandKind.LiteralInteger), new("parameter2", OperandKind.LiteralInteger), new("parameter3", OperandKind.LiteralInteger), new("parameter4", OperandKind.LiteralInteger), new("parameter5", OperandKind.LiteralInteger), new("parameter6", OperandKind.LiteralInteger), new("parameter7", OperandKind.LiteralInteger), new("parameter8", OperandKind.LiteralInteger), new("parameter9", OperandKind.LiteralInteger), new("parameter10", OperandKind.LiteralInteger), new("parameter11", OperandKind.LiteralInteger), new("parameter12", OperandKind.LiteralInteger)], [new(OperandKind.Decoration, 8040)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpDecorationGroup, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Annotation", []); + Instance.Register(Op.OpGroupDecorate, OperandKind.IdRef, OperandQuantifier.One, "decorationGroup", "Annotation", []); + Instance.Register(Op.OpGroupDecorate, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "targets", "Annotation", []); + Instance.Register(Op.OpGroupMemberDecorate, OperandKind.IdRef, OperandQuantifier.One, "decorationGroup", "Annotation", []); + Instance.Register(Op.OpGroupMemberDecorate, OperandKind.PairIdRefLiteralInteger, OperandQuantifier.ZeroOrMore, "targets", "Annotation", []); + Instance.Register(Op.OpVectorExtractDynamic, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpVectorExtractDynamic, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpVectorExtractDynamic, OperandKind.IdRef, OperandQuantifier.One, "vector", "Composite", []); + Instance.Register(Op.OpVectorExtractDynamic, OperandKind.IdRef, OperandQuantifier.One, "index", "Composite", []); + Instance.Register(Op.OpVectorInsertDynamic, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpVectorInsertDynamic, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpVectorInsertDynamic, OperandKind.IdRef, OperandQuantifier.One, "vector", "Composite", []); + Instance.Register(Op.OpVectorInsertDynamic, OperandKind.IdRef, OperandQuantifier.One, "component", "Composite", []); + Instance.Register(Op.OpVectorInsertDynamic, OperandKind.IdRef, OperandQuantifier.One, "index", "Composite", []); + Instance.Register(Op.OpVectorShuffle, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpVectorShuffle, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpVectorShuffle, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Composite", []); + Instance.Register(Op.OpVectorShuffle, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Composite", []); + Instance.Register(Op.OpVectorShuffle, OperandKind.LiteralInteger, OperandQuantifier.ZeroOrMore, "components", "Composite", []); + Instance.Register(Op.OpCompositeConstruct, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCompositeConstruct, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCompositeConstruct, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Composite", []); + Instance.Register(Op.OpCompositeExtract, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCompositeExtract, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCompositeExtract, OperandKind.IdRef, OperandQuantifier.One, "composite", "Composite", []); + Instance.Register(Op.OpCompositeExtract, OperandKind.LiteralInteger, OperandQuantifier.ZeroOrMore, "indexes", "Composite", []); + Instance.Register(Op.OpCompositeInsert, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCompositeInsert, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCompositeInsert, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Composite", []); + Instance.Register(Op.OpCompositeInsert, OperandKind.IdRef, OperandQuantifier.One, "composite", "Composite", []); + Instance.Register(Op.OpCompositeInsert, OperandKind.LiteralInteger, OperandQuantifier.ZeroOrMore, "indexes", "Composite", []); + Instance.Register(Op.OpCopyObject, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCopyObject, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCopyObject, OperandKind.IdRef, OperandQuantifier.One, "operand", "Composite", []); + Instance.Register(Op.OpTranspose, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpTranspose, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpTranspose, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Composite", []); + Instance.Register(Op.OpSampledImage, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpSampledImage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpSampledImage, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpSampledImage, OperandKind.IdRef, OperandQuantifier.One, "sampler", "Image", []); + Instance.Register(Op.OpImageSampleImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSampleDrefImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSampleDrefExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleProjImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleProjImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleProjImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleProjImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleProjImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleProjExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleProjExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleProjExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleProjExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleProjExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSampleProjDrefExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageFetch, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageFetch, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageFetch, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageFetch, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageFetch, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageGather, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageGather, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageGather, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageGather, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageGather, OperandKind.IdRef, OperandQuantifier.One, "component", "Image", []); + Instance.Register(Op.OpImageGather, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageDrefGather, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageDrefGather, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageDrefGather, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageDrefGather, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageDrefGather, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageDrefGather, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageRead, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageRead, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageRead, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageRead, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageRead, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageWrite, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageWrite, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageWrite, OperandKind.IdRef, OperandQuantifier.One, "texel", "Image", []); + Instance.Register(Op.OpImageWrite, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImage, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImage, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageQueryFormat, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQueryFormat, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQueryFormat, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageQueryOrder, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQueryOrder, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQueryOrder, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageQuerySizeLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQuerySizeLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQuerySizeLod, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageQuerySizeLod, OperandKind.IdRef, OperandQuantifier.One, "levelofDetail", "Image", []); + Instance.Register(Op.OpImageQuerySize, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQuerySize, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQuerySize, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageQueryLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQueryLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQueryLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageQueryLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageQueryLevels, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQueryLevels, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQueryLevels, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageQuerySamples, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageQuerySamples, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageQuerySamples, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpConvertFToU, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertFToU, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertFToU, OperandKind.IdRef, OperandQuantifier.One, "floatValue", "Conversion", []); + Instance.Register(Op.OpConvertFToS, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertFToS, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertFToS, OperandKind.IdRef, OperandQuantifier.One, "floatValue", "Conversion", []); + Instance.Register(Op.OpConvertSToF, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertSToF, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertSToF, OperandKind.IdRef, OperandQuantifier.One, "signedValue", "Conversion", []); + Instance.Register(Op.OpConvertUToF, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertUToF, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertUToF, OperandKind.IdRef, OperandQuantifier.One, "unsignedValue", "Conversion", []); + Instance.Register(Op.OpUConvert, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpUConvert, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpUConvert, OperandKind.IdRef, OperandQuantifier.One, "unsignedValue", "Conversion", []); + Instance.Register(Op.OpSConvert, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpSConvert, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpSConvert, OperandKind.IdRef, OperandQuantifier.One, "signedValue", "Conversion", []); + Instance.Register(Op.OpFConvert, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpFConvert, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpFConvert, OperandKind.IdRef, OperandQuantifier.One, "floatValue", "Conversion", []); + Instance.Register(Op.OpQuantizeToF16, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpQuantizeToF16, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpQuantizeToF16, OperandKind.IdRef, OperandQuantifier.One, "value", "Conversion", []); + Instance.Register(Op.OpConvertPtrToU, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertPtrToU, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertPtrToU, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Conversion", []); + Instance.Register(Op.OpSatConvertSToU, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpSatConvertSToU, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpSatConvertSToU, OperandKind.IdRef, OperandQuantifier.One, "signedValue", "Conversion", []); + Instance.Register(Op.OpSatConvertUToS, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpSatConvertUToS, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpSatConvertUToS, OperandKind.IdRef, OperandQuantifier.One, "unsignedValue", "Conversion", []); + Instance.Register(Op.OpConvertUToPtr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertUToPtr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertUToPtr, OperandKind.IdRef, OperandQuantifier.One, "integerValue", "Conversion", []); + Instance.Register(Op.OpPtrCastToGeneric, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpPtrCastToGeneric, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpPtrCastToGeneric, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtr, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtrExplicit, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtrExplicit, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtrExplicit, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Conversion", []); + Instance.Register(Op.OpGenericCastToPtrExplicit, OperandKind.StorageClass, OperandQuantifier.One, "storage", "Conversion", []); + Instance.Register(Op.OpBitcast, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpBitcast, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpBitcast, OperandKind.IdRef, OperandQuantifier.One, "operand", "Conversion", []); + Instance.Register(Op.OpSNegate, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSNegate, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSNegate, OperandKind.IdRef, OperandQuantifier.One, "operand", "Arithmetic", []); + Instance.Register(Op.OpFNegate, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFNegate, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFNegate, OperandKind.IdRef, OperandQuantifier.One, "operand", "Arithmetic", []); + Instance.Register(Op.OpIAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpIAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpIAdd, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpIAdd, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFAdd, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFAdd, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpISub, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpISub, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpISub, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpISub, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFSub, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFSub, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFSub, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFSub, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpIMul, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpIMul, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpIMul, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpIMul, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFMul, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFMul, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFMul, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFMul, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpUDiv, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpUDiv, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpUDiv, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpUDiv, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpSDiv, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSDiv, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSDiv, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpSDiv, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFDiv, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFDiv, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFDiv, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFDiv, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpUMod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpUMod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpUMod, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpUMod, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpSRem, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSRem, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSRem, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpSRem, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpSMod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSMod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSMod, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpSMod, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFRem, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFRem, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFRem, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFRem, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpFMod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpFMod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpFMod, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpFMod, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesScalar, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesScalar, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesScalar, OperandKind.IdRef, OperandQuantifier.One, "vector", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesScalar, OperandKind.IdRef, OperandQuantifier.One, "scalar", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesScalar, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesScalar, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesScalar, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesScalar, OperandKind.IdRef, OperandQuantifier.One, "scalar", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesMatrix, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesMatrix, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesMatrix, OperandKind.IdRef, OperandQuantifier.One, "vector", "Arithmetic", []); + Instance.Register(Op.OpVectorTimesMatrix, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesVector, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesVector, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesVector, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesVector, OperandKind.IdRef, OperandQuantifier.One, "vector", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesMatrix, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesMatrix, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesMatrix, OperandKind.IdRef, OperandQuantifier.One, "leftMatrix", "Arithmetic", []); + Instance.Register(Op.OpMatrixTimesMatrix, OperandKind.IdRef, OperandQuantifier.One, "rightMatrix", "Arithmetic", []); + Instance.Register(Op.OpOuterProduct, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpOuterProduct, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpOuterProduct, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpOuterProduct, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpDot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpDot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpDot, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpDot, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpIAddCarry, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpIAddCarry, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpIAddCarry, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpIAddCarry, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpISubBorrow, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpISubBorrow, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpISubBorrow, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpISubBorrow, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpUMulExtended, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpUMulExtended, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpUMulExtended, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpUMulExtended, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpSMulExtended, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSMulExtended, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSMulExtended, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Arithmetic", []); + Instance.Register(Op.OpSMulExtended, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Arithmetic", []); + Instance.Register(Op.OpAny, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpAny, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpAny, OperandKind.IdRef, OperandQuantifier.One, "vector", "Relational_and_Logical", []); + Instance.Register(Op.OpAll, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpAll, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpAll, OperandKind.IdRef, OperandQuantifier.One, "vector", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNan, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpIsInf, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpIsInf, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpIsInf, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpIsFinite, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpIsFinite, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpIsFinite, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNormal, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNormal, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpIsNormal, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpSignBitSet, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSignBitSet, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSignBitSet, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpLessOrGreater, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLessOrGreater, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLessOrGreater, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpLessOrGreater, OperandKind.IdRef, OperandQuantifier.One, "y", "Relational_and_Logical", []); + Instance.Register(Op.OpOrdered, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpOrdered, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpOrdered, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpOrdered, OperandKind.IdRef, OperandQuantifier.One, "y", "Relational_and_Logical", []); + Instance.Register(Op.OpUnordered, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpUnordered, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpUnordered, OperandKind.IdRef, OperandQuantifier.One, "x", "Relational_and_Logical", []); + Instance.Register(Op.OpUnordered, OperandKind.IdRef, OperandQuantifier.One, "y", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNotEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNotEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalOr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalOr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalOr, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalOr, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalAnd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalAnd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalAnd, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalAnd, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpLogicalNot, OperandKind.IdRef, OperandQuantifier.One, "operand", "Relational_and_Logical", []); + Instance.Register(Op.OpSelect, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSelect, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSelect, OperandKind.IdRef, OperandQuantifier.One, "condition", "Relational_and_Logical", []); + Instance.Register(Op.OpSelect, OperandKind.IdRef, OperandQuantifier.One, "object1", "Relational_and_Logical", []); + Instance.Register(Op.OpSelect, OperandKind.IdRef, OperandQuantifier.One, "object2", "Relational_and_Logical", []); + Instance.Register(Op.OpIEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpIEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpIEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpIEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpINotEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpINotEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpINotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpINotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpUGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpSGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpULessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpSLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdNotEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdNotEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordNotEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordNotEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThan, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThan, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThan, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordLessThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFOrdGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThanEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThanEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Relational_and_Logical", []); + Instance.Register(Op.OpFUnordGreaterThanEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Relational_and_Logical", []); + Instance.Register(Op.OpShiftRightLogical, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpShiftRightLogical, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpShiftRightLogical, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpShiftRightLogical, OperandKind.IdRef, OperandQuantifier.One, "shift", "Bit", []); + Instance.Register(Op.OpShiftRightArithmetic, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpShiftRightArithmetic, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpShiftRightArithmetic, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpShiftRightArithmetic, OperandKind.IdRef, OperandQuantifier.One, "shift", "Bit", []); + Instance.Register(Op.OpShiftLeftLogical, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpShiftLeftLogical, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpShiftLeftLogical, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpShiftLeftLogical, OperandKind.IdRef, OperandQuantifier.One, "shift", "Bit", []); + Instance.Register(Op.OpBitwiseOr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitwiseOr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitwiseOr, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Bit", []); + Instance.Register(Op.OpBitwiseOr, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Bit", []); + Instance.Register(Op.OpBitwiseXor, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitwiseXor, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitwiseXor, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Bit", []); + Instance.Register(Op.OpBitwiseXor, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Bit", []); + Instance.Register(Op.OpBitwiseAnd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitwiseAnd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitwiseAnd, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Bit", []); + Instance.Register(Op.OpBitwiseAnd, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Bit", []); + Instance.Register(Op.OpNot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpNot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpNot, OperandKind.IdRef, OperandQuantifier.One, "operand", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdRef, OperandQuantifier.One, "insert", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdRef, OperandQuantifier.One, "offset", "Bit", []); + Instance.Register(Op.OpBitFieldInsert, OperandKind.IdRef, OperandQuantifier.One, "count", "Bit", []); + Instance.Register(Op.OpBitFieldSExtract, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitFieldSExtract, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitFieldSExtract, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpBitFieldSExtract, OperandKind.IdRef, OperandQuantifier.One, "offset", "Bit", []); + Instance.Register(Op.OpBitFieldSExtract, OperandKind.IdRef, OperandQuantifier.One, "count", "Bit", []); + Instance.Register(Op.OpBitFieldUExtract, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitFieldUExtract, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitFieldUExtract, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpBitFieldUExtract, OperandKind.IdRef, OperandQuantifier.One, "offset", "Bit", []); + Instance.Register(Op.OpBitFieldUExtract, OperandKind.IdRef, OperandQuantifier.One, "count", "Bit", []); + Instance.Register(Op.OpBitReverse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitReverse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitReverse, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpBitCount, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Bit", []); + Instance.Register(Op.OpBitCount, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Bit", []); + Instance.Register(Op.OpBitCount, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Bit", []); + Instance.Register(Op.OpDPdx, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdx, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdx, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpDPdy, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdy, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdy, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpFwidth, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpFwidth, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpFwidth, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpDPdxFine, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdxFine, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdxFine, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpDPdyFine, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdyFine, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdyFine, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpFwidthFine, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpFwidthFine, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpFwidthFine, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpDPdxCoarse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdxCoarse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdxCoarse, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpDPdyCoarse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpDPdyCoarse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpDPdyCoarse, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpFwidthCoarse, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Derivative", []); + Instance.Register(Op.OpFwidthCoarse, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Derivative", []); + Instance.Register(Op.OpFwidthCoarse, OperandKind.IdRef, OperandQuantifier.One, "p", "Derivative", []); + Instance.Register(Op.OpEmitVertex, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpEndPrimitive, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpEmitStreamVertex, OperandKind.IdRef, OperandQuantifier.One, "stream", "Primitive", []); + Instance.Register(Op.OpEndStreamPrimitive, OperandKind.IdRef, OperandQuantifier.One, "stream", "Primitive", []); + Instance.Register(Op.OpControlBarrier, OperandKind.IdScope, OperandQuantifier.One, "execution", "Barrier", []); + Instance.Register(Op.OpControlBarrier, OperandKind.IdScope, OperandQuantifier.One, "memory", "Barrier", []); + Instance.Register(Op.OpControlBarrier, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Barrier", []); + Instance.Register(Op.OpMemoryBarrier, OperandKind.IdScope, OperandQuantifier.One, "memory", "Barrier", []); + Instance.Register(Op.OpMemoryBarrier, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Barrier", []); + Instance.Register(Op.OpAtomicLoad, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicLoad, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicLoad, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicLoad, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicLoad, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicStore, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicStore, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicStore, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicStore, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicExchange, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdMemorySemantics, OperandQuantifier.One, "equal", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdMemorySemantics, OperandQuantifier.One, "unequal", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchange, OperandKind.IdRef, OperandQuantifier.One, "comparator", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdMemorySemantics, OperandQuantifier.One, "equal", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdMemorySemantics, OperandQuantifier.One, "unequal", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicCompareExchangeWeak, OperandKind.IdRef, OperandQuantifier.One, "comparator", "Atomic", []); + Instance.Register(Op.OpAtomicIIncrement, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicIIncrement, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicIIncrement, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicIIncrement, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicIIncrement, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicIDecrement, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicIDecrement, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicIDecrement, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicIDecrement, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicIDecrement, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicIAdd, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicISub, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicSMin, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicUMin, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicSMax, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicUMax, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicAnd, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicOr, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicXor, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpPhi, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Control-Flow", []); + Instance.Register(Op.OpPhi, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Control-Flow", []); + Instance.Register(Op.OpPhi, OperandKind.PairIdRefIdRef, OperandQuantifier.ZeroOrMore, "variables", "Control-Flow", []); + Instance.Register(Op.OpLoopMerge, OperandKind.IdRef, OperandQuantifier.One, "mergeBlock", "Control-Flow", []); + Instance.Register(Op.OpLoopMerge, OperandKind.IdRef, OperandQuantifier.One, "continueTarget", "Control-Flow", []); + Instance.Register(Op.OpLoopMerge, OperandKind.LoopControl, OperandQuantifier.One, "loopControl", "Control-Flow", new() { [new(OperandKind.LoopControl, 8)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 16)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 32)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 64)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 128)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 256)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 65536)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 131072)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 262144)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 524288)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 1048576)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 2097152)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 4194304)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 16777216)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.LoopControl, 33554432)] = [new("literalinteger0", OperandKind.LiteralInteger)] }); + Instance.Register(Op.OpSelectionMerge, OperandKind.IdRef, OperandQuantifier.One, "mergeBlock", "Control-Flow", []); + Instance.Register(Op.OpSelectionMerge, OperandKind.SelectionControl, OperandQuantifier.One, "selectionControl", "Control-Flow", []); + Instance.Register(Op.OpLabel, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Control-Flow", []); + Instance.Register(Op.OpBranch, OperandKind.IdRef, OperandQuantifier.One, "targetLabel", "Control-Flow", []); + Instance.Register(Op.OpBranchConditional, OperandKind.IdRef, OperandQuantifier.One, "condition", "Control-Flow", []); + Instance.Register(Op.OpBranchConditional, OperandKind.IdRef, OperandQuantifier.One, "trueLabel", "Control-Flow", []); + Instance.Register(Op.OpBranchConditional, OperandKind.IdRef, OperandQuantifier.One, "falseLabel", "Control-Flow", []); + Instance.Register(Op.OpBranchConditional, OperandKind.LiteralInteger, OperandQuantifier.ZeroOrMore, "branchWeights", "Control-Flow", []); + Instance.Register(Op.OpSwitch, OperandKind.IdRef, OperandQuantifier.One, "selector", "Control-Flow", []); + Instance.Register(Op.OpSwitch, OperandKind.IdRef, OperandQuantifier.One, "defaultId", "Control-Flow", []); + Instance.Register(Op.OpSwitch, OperandKind.PairLiteralIntegerIdRef, OperandQuantifier.ZeroOrMore, "targets", "Control-Flow", []); + Instance.Register(Op.OpKill, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpReturn, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpReturnValue, OperandKind.IdRef, OperandQuantifier.One, "value", "Control-Flow", []); + Instance.Register(Op.OpUnreachable, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpLifetimeStart, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Control-Flow", []); + Instance.Register(Op.OpLifetimeStart, OperandKind.LiteralInteger, OperandQuantifier.One, "size", "Control-Flow", []); + Instance.Register(Op.OpLifetimeStop, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Control-Flow", []); + Instance.Register(Op.OpLifetimeStop, OperandKind.LiteralInteger, OperandQuantifier.One, "size", "Control-Flow", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdRef, OperandQuantifier.One, "destination", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdRef, OperandQuantifier.One, "source", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdRef, OperandQuantifier.One, "numElements", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdRef, OperandQuantifier.One, "stride", "Group", []); + Instance.Register(Op.OpGroupAsyncCopy, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Group", []); + Instance.Register(Op.OpGroupWaitEvents, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupWaitEvents, OperandKind.IdRef, OperandQuantifier.One, "numEvents", "Group", []); + Instance.Register(Op.OpGroupWaitEvents, OperandKind.IdRef, OperandQuantifier.One, "eventsList", "Group", []); + Instance.Register(Op.OpGroupAll, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupAll, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupAll, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupAll, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpGroupAny, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupAny, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupAny, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupAny, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpGroupBroadcast, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupBroadcast, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupBroadcast, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupBroadcast, OperandKind.IdRef, OperandQuantifier.One, "value", "Group", []); + Instance.Register(Op.OpGroupBroadcast, OperandKind.IdRef, OperandQuantifier.One, "localId", "Group", []); + Instance.Register(Op.OpGroupIAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupIAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupIAdd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupIAdd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupIAdd, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFAdd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFAdd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFAdd, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFMin, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupUMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupUMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupUMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupUMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupUMin, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupSMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupSMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupSMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupSMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupSMin, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFMax, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupUMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupUMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupUMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupUMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupUMax, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupSMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupSMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupSMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupSMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupSMax, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Pipe", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "index", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReservedReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "index", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReservedWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "numPackets", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "numPackets", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpIsValidReserveId, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpIsValidReserveId, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpIsValidReserveId, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpGetNumPipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpGetNumPipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpGetNumPipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGetNumPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGetNumPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpGetMaxPipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpGetMaxPipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpGetMaxPipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGetMaxPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGetMaxPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdScope, OperandQuantifier.One, "execution", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "numPackets", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGroupReserveReadPipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdScope, OperandQuantifier.One, "execution", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "numPackets", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGroupReserveWritePipePackets, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpGroupCommitReadPipe, OperandKind.IdScope, OperandQuantifier.One, "execution", "Pipe", []); + Instance.Register(Op.OpGroupCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGroupCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpGroupCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGroupCommitReadPipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpGroupCommitWritePipe, OperandKind.IdScope, OperandQuantifier.One, "execution", "Pipe", []); + Instance.Register(Op.OpGroupCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "pipe", "Pipe", []); + Instance.Register(Op.OpGroupCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "reserveId", "Pipe", []); + Instance.Register(Op.OpGroupCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpGroupCommitWritePipe, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdRef, OperandQuantifier.One, "queue", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdRef, OperandQuantifier.One, "numEvents", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdRef, OperandQuantifier.One, "waitEvents", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueMarker, OperandKind.IdRef, OperandQuantifier.One, "retEvent", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "queue", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "flags", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "nDRange", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "numEvents", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "waitEvents", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "retEvent", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpEnqueueKernel, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "localSizes", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdRef, OperandQuantifier.One, "nDRange", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeSubGroupCount, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdRef, OperandQuantifier.One, "nDRange", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelNDrangeMaxSubGroupSize, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelWorkGroupSize, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelPreferredWorkGroupSizeMultiple, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpRetainEvent, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpReleaseEvent, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpCreateUserEvent, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpCreateUserEvent, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpIsValidEvent, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpIsValidEvent, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpIsValidEvent, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpSetUserEventStatus, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpSetUserEventStatus, OperandKind.IdRef, OperandQuantifier.One, "status", "Device-Side_Enqueue", []); + Instance.Register(Op.OpCaptureEventProfilingInfo, OperandKind.IdRef, OperandQuantifier.One, "eventId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpCaptureEventProfilingInfo, OperandKind.IdRef, OperandQuantifier.One, "profilingInfo", "Device-Side_Enqueue", []); + Instance.Register(Op.OpCaptureEventProfilingInfo, OperandKind.IdRef, OperandQuantifier.One, "value", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetDefaultQueue, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetDefaultQueue, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpBuildNDRange, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpBuildNDRange, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpBuildNDRange, OperandKind.IdRef, OperandQuantifier.One, "globalWorkSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpBuildNDRange, OperandKind.IdRef, OperandQuantifier.One, "localWorkSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpBuildNDRange, OperandKind.IdRef, OperandQuantifier.One, "globalWorkOffset", "Device-Side_Enqueue", []); + Instance.Register(Op.OpImageSparseSampleImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSparseSampleDrefExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleProjImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleProjExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefImplicitLod, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSparseSampleProjDrefExplicitLod, OperandKind.ImageOperands, OperandQuantifier.One, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseFetch, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseFetch, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseFetch, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageSparseFetch, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseFetch, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseGather, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseGather, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseGather, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseGather, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseGather, OperandKind.IdRef, OperandQuantifier.One, "component", "Image", []); + Instance.Register(Op.OpImageSparseGather, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.IdRef, OperandQuantifier.One, "dref", "Image", []); + Instance.Register(Op.OpImageSparseDrefGather, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpImageSparseTexelsResident, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseTexelsResident, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseTexelsResident, OperandKind.IdRef, OperandQuantifier.One, "residentCode", "Image", []); + Instance.Register(Op.OpNoLine, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpAtomicFlagTestAndSet, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicFlagTestAndSet, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicFlagTestAndSet, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicFlagTestAndSet, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicFlagTestAndSet, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicFlagClear, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicFlagClear, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicFlagClear, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpImageSparseRead, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSparseRead, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSparseRead, OperandKind.IdRef, OperandQuantifier.One, "image", "Image", []); + Instance.Register(Op.OpImageSparseRead, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSparseRead, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpSizeOf, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpSizeOf, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpSizeOf, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Miscellaneous", []); + Instance.Register(Op.OpTypePipeStorage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpConstantPipeStorage, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpConstantPipeStorage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpConstantPipeStorage, OperandKind.LiteralInteger, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpConstantPipeStorage, OperandKind.LiteralInteger, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpConstantPipeStorage, OperandKind.LiteralInteger, OperandQuantifier.One, "capacity", "Pipe", []); + Instance.Register(Op.OpCreatePipeFromPipeStorage, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpCreatePipeFromPipeStorage, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpCreatePipeFromPipeStorage, OperandKind.IdRef, OperandQuantifier.One, "pipeStorage", "Pipe", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdRef, OperandQuantifier.One, "subgroupCount", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelLocalSizeForSubgroupCount, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdRef, OperandQuantifier.One, "invoke", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdRef, OperandQuantifier.One, "param", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdRef, OperandQuantifier.One, "paramSize", "Device-Side_Enqueue", []); + Instance.Register(Op.OpGetKernelMaxNumSubgroups, OperandKind.IdRef, OperandQuantifier.One, "paramAlign", "Device-Side_Enqueue", []); + Instance.Register(Op.OpTypeNamedBarrier, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpNamedBarrierInitialize, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Barrier", []); + Instance.Register(Op.OpNamedBarrierInitialize, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Barrier", []); + Instance.Register(Op.OpNamedBarrierInitialize, OperandKind.IdRef, OperandQuantifier.One, "subgroupCount", "Barrier", []); + Instance.Register(Op.OpMemoryNamedBarrier, OperandKind.IdRef, OperandQuantifier.One, "namedBarrier", "Barrier", []); + Instance.Register(Op.OpMemoryNamedBarrier, OperandKind.IdScope, OperandQuantifier.One, "memory", "Barrier", []); + Instance.Register(Op.OpMemoryNamedBarrier, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Barrier", []); + Instance.Register(Op.OpModuleProcessed, OperandKind.LiteralString, OperandQuantifier.One, "process", "Debug", []); + Instance.Register(Op.OpExecutionModeId, OperandKind.IdRef, OperandQuantifier.One, "entryPoint", "Mode-Setting", []); + Instance.Register(Op.OpExecutionModeId, OperandKind.ExecutionMode, OperandQuantifier.One, "mode", "Mode-Setting", new() { [new(OperandKind.ExecutionMode, 0)] = [new("numberofInvocationinvocations", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 17)] = [new("xsize", OperandKind.LiteralInteger), new("ysize", OperandKind.LiteralInteger), new("zsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 18)] = [new("xsize", OperandKind.LiteralInteger), new("ysize", OperandKind.LiteralInteger), new("zsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 26)] = [new("vertexcount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 30)] = [new("vectortype", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 35)] = [new("subgroupSize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 36)] = [new("subgroupsPerWorkgroup", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 37)] = [new("subgroupsPerWorkgroup", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 38)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 39)] = [new("xsizehint", OperandKind.IdRef), new("ysizehint", OperandKind.IdRef), new("zsizehint", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 4459)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4460)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4461)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4462)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 4463)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5070)] = [new("isEntry", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5071)] = [new("numberofrecursions", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5072)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5073)] = [new("shaderIndex", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5077)] = [new("xsize", OperandKind.IdRef), new("ysize", OperandKind.IdRef), new("zsize", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5102)] = [new("nodeName", OperandKind.IdRef), new("shaderIndex", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 5270)] = [new("primitivecount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5618)] = [new("size", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5620)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5621)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5622)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5623)] = [new("targetWidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5893)] = [new("maxxsize", OperandKind.LiteralInteger), new("maxysize", OperandKind.LiteralInteger), new("maxzsize", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5894)] = [new("maxdimensions", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5896)] = [new("vectorwidth", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 5903)] = [new("targetfmax", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6028)] = [new("targetType", OperandKind.IdRef), new("fastMathMode", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 6154)] = [new("stallFreeReturn", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6160)] = [new("waitForDoneWrite", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6417)] = [new("barrierCount", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6461)] = [new("numberofRegisters", OperandKind.LiteralInteger)], [new(OperandKind.ExecutionMode, 6462)] = [new("numberofRegisters", OperandKind.IdRef)], [new(OperandKind.ExecutionMode, 6463)] = [new("namedMaximumNumberofRegisters", OperandKind.NamedMaximumNumberOfRegisters)] }); + Instance.Register(Op.OpDecorateId, OperandKind.IdRef, OperandQuantifier.One, "target", "Annotation", []); + Instance.Register(Op.OpDecorateId, OperandKind.Decoration, OperandQuantifier.One, "decoration", "Annotation", []); + Instance.Register(Op.OpDecorateId, OperandKind.IdRef, OperandQuantifier.One, "value", "Annotation", []); + Instance.Register(Op.OpGroupNonUniformElect, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformElect, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformElect, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAll, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAll, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAll, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAll, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAny, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAny, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAny, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAny, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAllEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAllEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAllEqual, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformAllEqual, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcast, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcast, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcast, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcast, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcast, OperandKind.IdRef, OperandQuantifier.One, "id", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcastFirst, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcastFirst, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcastFirst, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBroadcastFirst, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallot, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallot, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformInverseBallot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformInverseBallot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformInverseBallot, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformInverseBallot, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitExtract, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitExtract, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitExtract, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitExtract, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitExtract, OperandKind.IdRef, OperandQuantifier.One, "index", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitCount, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitCount, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitCount, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitCount, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotBitCount, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindLSB, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindLSB, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindLSB, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindLSB, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindMSB, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindMSB, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindMSB, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBallotFindMSB, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffle, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffle, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffle, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffle, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffle, OperandKind.IdRef, OperandQuantifier.One, "id", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleXor, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleXor, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleXor, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleXor, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleXor, OperandKind.IdRef, OperandQuantifier.One, "mask", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleUp, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleUp, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleUp, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleUp, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleUp, OperandKind.IdRef, OperandQuantifier.One, "delta", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleDown, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleDown, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleDown, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleDown, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformShuffleDown, OperandKind.IdRef, OperandQuantifier.One, "delta", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIAdd, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFAdd, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformIMul, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMul, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMin, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMin, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMin, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformSMax, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformUMax, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformFMax, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseAnd, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseOr, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformBitwiseXor, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalAnd, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalOr, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformLogicalXor, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadBroadcast, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadBroadcast, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadBroadcast, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadBroadcast, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadBroadcast, OperandKind.IdRef, OperandQuantifier.One, "index", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadSwap, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadSwap, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadSwap, OperandKind.IdScope, OperandQuantifier.One, "execution", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadSwap, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadSwap, OperandKind.IdRef, OperandQuantifier.One, "direction", "Non-Uniform", []); + Instance.Register(Op.OpCopyLogical, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCopyLogical, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCopyLogical, OperandKind.IdRef, OperandQuantifier.One, "operand", "Composite", []); + Instance.Register(Op.OpPtrEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpPtrEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpPtrEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Memory", []); + Instance.Register(Op.OpPtrEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Memory", []); + Instance.Register(Op.OpPtrNotEqual, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpPtrNotEqual, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpPtrNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Memory", []); + Instance.Register(Op.OpPtrNotEqual, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Memory", []); + Instance.Register(Op.OpPtrDiff, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpPtrDiff, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpPtrDiff, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Memory", []); + Instance.Register(Op.OpPtrDiff, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Memory", []); + Instance.Register(Op.OpColorAttachmentReadEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpColorAttachmentReadEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpColorAttachmentReadEXT, OperandKind.IdRef, OperandQuantifier.One, "attachment", "Image", []); + Instance.Register(Op.OpColorAttachmentReadEXT, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "sample", "Image", []); + Instance.Register(Op.OpDepthAttachmentReadEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpDepthAttachmentReadEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpDepthAttachmentReadEXT, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "sample", "Image", []); + Instance.Register(Op.OpStencilAttachmentReadEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpStencilAttachmentReadEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpStencilAttachmentReadEXT, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "sample", "Image", []); + Instance.Register(Op.OpTerminateInvocation, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpTypeUntypedPointerKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeUntypedPointerKHR, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Type-Declaration", []); + Instance.Register(Op.OpUntypedVariableKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedVariableKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedVariableKHR, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Memory", []); + Instance.Register(Op.OpUntypedVariableKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "dataType", "Memory", []); + Instance.Register(Op.OpUntypedVariableKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "initializer", "Memory", []); + Instance.Register(Op.OpUntypedAccessChainKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedAccessChainKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Memory", []); + Instance.Register(Op.OpUntypedAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpUntypedAccessChainKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsAccessChainKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsAccessChainKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsAccessChainKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpSubgroupBallotKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupBallotKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupBallotKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpSubgroupFirstInvocationKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupFirstInvocationKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupFirstInvocationKHR, OperandKind.IdRef, OperandQuantifier.One, "value", "Group", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Memory", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "element", "Memory", []); + Instance.Register(Op.OpUntypedPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.One, "element", "Memory", []); + Instance.Register(Op.OpUntypedInBoundsPtrAccessChainKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "indexes", "Memory", []); + Instance.Register(Op.OpUntypedArrayLengthKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpUntypedArrayLengthKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpUntypedArrayLengthKHR, OperandKind.IdRef, OperandQuantifier.One, "structure", "Memory", []); + Instance.Register(Op.OpUntypedArrayLengthKHR, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpUntypedArrayLengthKHR, OperandKind.LiteralInteger, OperandQuantifier.One, "arraymember", "Memory", []); + Instance.Register(Op.OpUntypedPrefetchKHR, OperandKind.IdRef, OperandQuantifier.One, "pointerType", "Memory", []); + Instance.Register(Op.OpUntypedPrefetchKHR, OperandKind.IdRef, OperandQuantifier.One, "numBytes", "Memory", []); + Instance.Register(Op.OpUntypedPrefetchKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "rW", "Memory", []); + Instance.Register(Op.OpUntypedPrefetchKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "locality", "Memory", []); + Instance.Register(Op.OpUntypedPrefetchKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "cacheType", "Memory", []); + Instance.Register(Op.OpSubgroupAllKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupAllKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupAllKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpSubgroupAnyKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupAnyKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupAnyKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpSubgroupAllEqualKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupAllEqualKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupAllEqualKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdRef, OperandQuantifier.One, "value", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdRef, OperandQuantifier.One, "delta", "Group", []); + Instance.Register(Op.OpGroupNonUniformRotateKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "clusterSize", "Group", []); + Instance.Register(Op.OpSubgroupReadInvocationKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupReadInvocationKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupReadInvocationKHR, OperandKind.IdRef, OperandQuantifier.One, "value", "Group", []); + Instance.Register(Op.OpSubgroupReadInvocationKHR, OperandKind.IdRef, OperandQuantifier.One, "index", "Group", []); + Instance.Register(Op.OpExtInstWithForwardRefsKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Extension", []); + Instance.Register(Op.OpExtInstWithForwardRefsKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Extension", []); + Instance.Register(Op.OpExtInstWithForwardRefsKHR, OperandKind.IdRef, OperandQuantifier.One, "set", "Extension", []); + Instance.Register(Op.OpExtInstWithForwardRefsKHR, OperandKind.LiteralExtInstInteger, OperandQuantifier.One, "instruction", "Extension", []); + Instance.Register(Op.OpExtInstWithForwardRefsKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "operands", "Extension", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "cullMask", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "sBTOffset", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "sBTStride", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "rayOrigin", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "rayTmin", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "rayDirection", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "rayTmax", "Reserved", []); + Instance.Register(Op.OpTraceRayKHR, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpExecuteCallableKHR, OperandKind.IdRef, OperandQuantifier.One, "sBTIndex", "Reserved", []); + Instance.Register(Op.OpExecuteCallableKHR, OperandKind.IdRef, OperandQuantifier.One, "callableData", "Reserved", []); + Instance.Register(Op.OpConvertUToAccelerationStructureKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertUToAccelerationStructureKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertUToAccelerationStructureKHR, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpIgnoreIntersectionKHR, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpTerminateRayKHR, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpSDot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSDot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSDot, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpSDot, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpSDot, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpUDot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpUDot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpUDot, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpUDot, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpUDot, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpSUDot, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSUDot, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSUDot, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpSUDot, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpSUDot, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "accumulator", "Arithmetic", []); + Instance.Register(Op.OpSDotAccSat, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "accumulator", "Arithmetic", []); + Instance.Register(Op.OpUDotAccSat, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector1", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "vector2", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.IdRef, OperandQuantifier.One, "accumulator", "Arithmetic", []); + Instance.Register(Op.OpSUDotAccSat, OperandKind.PackedVectorFormat, OperandQuantifier.ZeroOrOne, "packedVectorFormat", "Arithmetic", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdRef, OperandQuantifier.One, "componentType", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdScope, OperandQuantifier.One, "scope", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdRef, OperandQuantifier.One, "rows", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdRef, OperandQuantifier.One, "columns", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixKHR, OperandKind.IdRef, OperandQuantifier.One, "use", "Type-Declaration", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.IdRef, OperandQuantifier.One, "memoryLayout", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "stride", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadKHR, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryOperand", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixStoreKHR, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreKHR, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreKHR, OperandKind.IdRef, OperandQuantifier.One, "memoryLayout", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreKHR, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "stride", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreKHR, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryOperand", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.IdRef, OperandQuantifier.One, "a", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.IdRef, OperandQuantifier.One, "b", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.IdRef, OperandQuantifier.One, "c", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixMulAddKHR, OperandKind.CooperativeMatrixOperands, OperandQuantifier.ZeroOrOne, "cooperativeMatrixOperands", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixLengthKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpCooperativeMatrixLengthKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpCooperativeMatrixLengthKHR, OperandKind.IdRef, OperandQuantifier.One, "type", "Miscellaneous", []); + Instance.Register(Op.OpConstantCompositeReplicateEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpConstantCompositeReplicateEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpConstantCompositeReplicateEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantCompositeReplicateEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantCompositeReplicateEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantCompositeReplicateEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Constant-Creation", []); + Instance.Register(Op.OpCompositeConstructReplicateEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCompositeConstructReplicateEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCompositeConstructReplicateEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Composite", []); + Instance.Register(Op.OpTypeRayQueryKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "cullMask", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayOrigin", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayTMin", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayDirection", "Reserved", []); + Instance.Register(Op.OpRayQueryInitializeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayTMax", "Reserved", []); + Instance.Register(Op.OpRayQueryTerminateKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGenerateIntersectionKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGenerateIntersectionKHR, OperandKind.IdRef, OperandQuantifier.One, "hitT", "Reserved", []); + Instance.Register(Op.OpRayQueryConfirmIntersectionKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryProceedKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryProceedKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryProceedKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTypeKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTypeKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTypeKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTypeKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpImageSampleWeightedQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleWeightedQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleWeightedQCOM, OperandKind.IdRef, OperandQuantifier.One, "texture", "Image", []); + Instance.Register(Op.OpImageSampleWeightedQCOM, OperandKind.IdRef, OperandQuantifier.One, "coordinates", "Image", []); + Instance.Register(Op.OpImageSampleWeightedQCOM, OperandKind.IdRef, OperandQuantifier.One, "weights", "Image", []); + Instance.Register(Op.OpImageBoxFilterQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBoxFilterQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBoxFilterQCOM, OperandKind.IdRef, OperandQuantifier.One, "texture", "Image", []); + Instance.Register(Op.OpImageBoxFilterQCOM, OperandKind.IdRef, OperandQuantifier.One, "coordinates", "Image", []); + Instance.Register(Op.OpImageBoxFilterQCOM, OperandKind.IdRef, OperandQuantifier.One, "boxSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "target", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "reference", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "target", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "reference", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchWindowSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSSDQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "targetCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceSampledImage", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "referenceCoordinates", "Image", []); + Instance.Register(Op.OpImageBlockMatchGatherSADQCOM, OperandKind.IdRef, OperandQuantifier.One, "blockSize", "Image", []); + Instance.Register(Op.OpGroupIAddNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupIAddNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupIAddNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupIAddNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupIAddNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFAddNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFAddNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFAddNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFAddNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFAddNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFMinNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFMinNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFMinNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFMinNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFMinNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupUMinNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupUMinNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupUMinNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupUMinNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupUMinNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupSMinNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupSMinNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupSMinNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupSMinNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupSMinNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFMaxNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFMaxNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFMaxNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFMaxNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFMaxNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupUMaxNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupUMaxNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupUMaxNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupUMaxNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupUMaxNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupSMaxNonUniformAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupSMaxNonUniformAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupSMaxNonUniformAMD, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupSMaxNonUniformAMD, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupSMaxNonUniformAMD, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpFragmentMaskFetchAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFragmentMaskFetchAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFragmentMaskFetchAMD, OperandKind.IdRef, OperandQuantifier.One, "image", "Reserved", []); + Instance.Register(Op.OpFragmentMaskFetchAMD, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Reserved", []); + Instance.Register(Op.OpFragmentFetchAMD, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFragmentFetchAMD, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFragmentFetchAMD, OperandKind.IdRef, OperandQuantifier.One, "image", "Reserved", []); + Instance.Register(Op.OpFragmentFetchAMD, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Reserved", []); + Instance.Register(Op.OpFragmentFetchAMD, OperandKind.IdRef, OperandQuantifier.One, "fragmentIndex", "Reserved", []); + Instance.Register(Op.OpReadClockKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpReadClockKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpReadClockKHR, OperandKind.IdScope, OperandQuantifier.One, "scope", "Reserved", []); + Instance.Register(Op.OpAllocateNodePayloadsAMDX, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpAllocateNodePayloadsAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpAllocateNodePayloadsAMDX, OperandKind.IdScope, OperandQuantifier.One, "visibility", "Reserved", []); + Instance.Register(Op.OpAllocateNodePayloadsAMDX, OperandKind.IdRef, OperandQuantifier.One, "payloadCount", "Reserved", []); + Instance.Register(Op.OpAllocateNodePayloadsAMDX, OperandKind.IdRef, OperandQuantifier.One, "nodeIndex", "Reserved", []); + Instance.Register(Op.OpEnqueueNodePayloadsAMDX, OperandKind.IdRef, OperandQuantifier.One, "payloadArray", "Reserved", []); + Instance.Register(Op.OpTypeNodePayloadArrayAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTypeNodePayloadArrayAMDX, OperandKind.IdRef, OperandQuantifier.One, "payloadType", "Reserved", []); + Instance.Register(Op.OpFinishWritingNodePayloadAMDX, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFinishWritingNodePayloadAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFinishWritingNodePayloadAMDX, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpNodePayloadArrayLengthAMDX, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpNodePayloadArrayLengthAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpNodePayloadArrayLengthAMDX, OperandKind.IdRef, OperandQuantifier.One, "payloadArray", "Reserved", []); + Instance.Register(Op.OpIsNodePayloadValidAMDX, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIsNodePayloadValidAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpIsNodePayloadValidAMDX, OperandKind.IdRef, OperandQuantifier.One, "payloadType", "Reserved", []); + Instance.Register(Op.OpIsNodePayloadValidAMDX, OperandKind.IdRef, OperandQuantifier.One, "nodeIndex", "Reserved", []); + Instance.Register(Op.OpConstantStringAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConstantStringAMDX, OperandKind.LiteralString, OperandQuantifier.One, "literalString", "Reserved", []); + Instance.Register(Op.OpSpecConstantStringAMDX, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpSpecConstantStringAMDX, OperandKind.LiteralString, OperandQuantifier.One, "literalString", "Reserved", []); + Instance.Register(Op.OpGroupNonUniformQuadAllKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadAllKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadAllKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadAnyKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadAnyKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformQuadAnyKHR, OperandKind.IdRef, OperandQuantifier.One, "predicate", "Non-Uniform", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitKind", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordOffset", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordStride", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "currentTime", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObjectAttributes", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitKind", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "currentTime", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObjectAttributes", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissMotionNV, OperandKind.IdRef, OperandQuantifier.One, "currentTime", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldToObjectNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldToObjectNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldToObjectNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectToWorldNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectToWorldNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectToWorldNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayDirectionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayDirectionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayDirectionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayOriginNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayOriginNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetObjectRayOriginNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "cullmask", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordOffset", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordStride", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "time", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderRecordBufferHandleNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderRecordBufferHandleNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderRecordBufferHandleNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderBindingTableRecordIndexNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderBindingTableRecordIndexNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetShaderBindingTableRecordIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordEmptyNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "cullmask", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordOffset", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordStride", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectTraceRayNV, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "hitKind", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordOffset", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordStride", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitNV, OperandKind.IdRef, OperandQuantifier.One, "hitObjectAttributes", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "accelerationStructure", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveId", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitKind", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "sBTRecordIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordHitWithIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObjectAttributes", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "sBTIndex", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "origin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "tMin", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "direction", "Reserved", []); + Instance.Register(Op.OpHitObjectRecordMissNV, OperandKind.IdRef, OperandQuantifier.One, "tMax", "Reserved", []); + Instance.Register(Op.OpHitObjectExecuteShaderNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectExecuteShaderNV, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpHitObjectGetCurrentTimeNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetCurrentTimeNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetCurrentTimeNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetAttributesNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetAttributesNV, OperandKind.IdRef, OperandQuantifier.One, "hitObjectAttribute", "Reserved", []); + Instance.Register(Op.OpHitObjectGetHitKindNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetHitKindNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetHitKindNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetPrimitiveIndexNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetPrimitiveIndexNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetPrimitiveIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetGeometryIndexNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetGeometryIndexNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetGeometryIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceIdNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceIdNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceIdNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceCustomIndexNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceCustomIndexNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetInstanceCustomIndexNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayDirectionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayDirectionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayDirectionNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayOriginNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayOriginNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetWorldRayOriginNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMaxNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMaxNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMaxNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMinNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMinNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectGetRayTMinNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectIsEmptyNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectIsEmptyNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectIsEmptyNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectIsHitNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectIsHitNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectIsHitNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpHitObjectIsMissNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpHitObjectIsMissNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpHitObjectIsMissNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpReorderThreadWithHitObjectNV, OperandKind.IdRef, OperandQuantifier.One, "hitObject", "Reserved", []); + Instance.Register(Op.OpReorderThreadWithHitObjectNV, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "hint", "Reserved", []); + Instance.Register(Op.OpReorderThreadWithHitObjectNV, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "bits", "Reserved", []); + Instance.Register(Op.OpReorderThreadWithHintNV, OperandKind.IdRef, OperandQuantifier.One, "hint", "Reserved", []); + Instance.Register(Op.OpReorderThreadWithHintNV, OperandKind.IdRef, OperandQuantifier.One, "bits", "Reserved", []); + Instance.Register(Op.OpTypeHitObjectNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdRef, OperandQuantifier.One, "sampledImage", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdRef, OperandQuantifier.One, "granularity", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.IdRef, OperandQuantifier.One, "coarse", "Image", []); + Instance.Register(Op.OpImageSampleFootprintNV, OperandKind.ImageOperands, OperandQuantifier.ZeroOrOne, "imageOperands", "Image", new() { [new(OperandKind.ImageOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 2)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 4)] = [new("idRef0", OperandKind.IdRef), new("idRef1", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 8)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 16)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 32)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 64)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 128)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.ImageOperands, 256)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 512)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.ImageOperands, 65536)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixConvertNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpCooperativeMatrixConvertNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpCooperativeMatrixConvertNV, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Conversion", []); + Instance.Register(Op.OpEmitMeshTasksEXT, OperandKind.IdRef, OperandQuantifier.One, "groupCountX", "Reserved", []); + Instance.Register(Op.OpEmitMeshTasksEXT, OperandKind.IdRef, OperandQuantifier.One, "groupCountY", "Reserved", []); + Instance.Register(Op.OpEmitMeshTasksEXT, OperandKind.IdRef, OperandQuantifier.One, "groupCountZ", "Reserved", []); + Instance.Register(Op.OpEmitMeshTasksEXT, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "payload", "Reserved", []); + Instance.Register(Op.OpSetMeshOutputsEXT, OperandKind.IdRef, OperandQuantifier.One, "vertexCount", "Reserved", []); + Instance.Register(Op.OpSetMeshOutputsEXT, OperandKind.IdRef, OperandQuantifier.One, "primitiveCount", "Reserved", []); + Instance.Register(Op.OpGroupNonUniformPartitionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformPartitionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Non-Uniform", []); + Instance.Register(Op.OpGroupNonUniformPartitionNV, OperandKind.IdRef, OperandQuantifier.One, "value", "Non-Uniform", []); + Instance.Register(Op.OpWritePackedPrimitiveIndices4x8NV, OperandKind.IdRef, OperandQuantifier.One, "indexOffset", "Reserved", []); + Instance.Register(Op.OpWritePackedPrimitiveIndices4x8NV, OperandKind.IdRef, OperandQuantifier.One, "packedIndices", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveIndex", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexPositionNV, OperandKind.IdRef, OperandQuantifier.One, "barycentric", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdRef, OperandQuantifier.One, "instanceId", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdRef, OperandQuantifier.One, "geometryIndex", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdRef, OperandQuantifier.One, "primitiveIndex", "Reserved", []); + Instance.Register(Op.OpFetchMicroTriangleVertexBarycentricNV, OperandKind.IdRef, OperandQuantifier.One, "barycentric", "Reserved", []); + Instance.Register(Op.OpReportIntersectionKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpReportIntersectionKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpReportIntersectionKHR, OperandKind.IdRef, OperandQuantifier.One, "hit", "Reserved", []); + Instance.Register(Op.OpReportIntersectionKHR, OperandKind.IdRef, OperandQuantifier.One, "hitKind", "Reserved", []); + Instance.Register(Op.OpIgnoreIntersectionNV, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpTerminateRayNV, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "cullMask", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "sBTOffset", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "sBTStride", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "rayOrigin", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmin", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "rayDirection", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmax", "Reserved", []); + Instance.Register(Op.OpTraceNV, OperandKind.IdRef, OperandQuantifier.One, "payloadId", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "cullMask", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTOffset", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTStride", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayOrigin", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmin", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayDirection", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmax", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "time", "Reserved", []); + Instance.Register(Op.OpTraceMotionNV, OperandKind.IdRef, OperandQuantifier.One, "payloadId", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "accel", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayFlags", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "cullMask", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTOffset", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "sBTStride", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "missIndex", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayOrigin", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmin", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayDirection", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "rayTmax", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "time", "Reserved", []); + Instance.Register(Op.OpTraceRayMotionNV, OperandKind.IdRef, OperandQuantifier.One, "payload", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpTypeAccelerationStructureKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpExecuteCallableNV, OperandKind.IdRef, OperandQuantifier.One, "sBTIndex", "Reserved", []); + Instance.Register(Op.OpExecuteCallableNV, OperandKind.IdRef, OperandQuantifier.One, "callableDataId", "Reserved", []); + Instance.Register(Op.OpTypeCooperativeMatrixNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixNV, OperandKind.IdRef, OperandQuantifier.One, "componentType", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixNV, OperandKind.IdScope, OperandQuantifier.One, "execution", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixNV, OperandKind.IdRef, OperandQuantifier.One, "rows", "Type-Declaration", []); + Instance.Register(Op.OpTypeCooperativeMatrixNV, OperandKind.IdRef, OperandQuantifier.One, "columns", "Type-Declaration", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.IdRef, OperandQuantifier.One, "stride", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.IdRef, OperandQuantifier.One, "columnMajor", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLoadNV, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Reserved", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixStoreNV, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixStoreNV, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixStoreNV, OperandKind.IdRef, OperandQuantifier.One, "stride", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixStoreNV, OperandKind.IdRef, OperandQuantifier.One, "columnMajor", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixStoreNV, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Reserved", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixMulAddNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixMulAddNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixMulAddNV, OperandKind.IdRef, OperandQuantifier.One, "a", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixMulAddNV, OperandKind.IdRef, OperandQuantifier.One, "b", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixMulAddNV, OperandKind.IdRef, OperandQuantifier.One, "c", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLengthNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLengthNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixLengthNV, OperandKind.IdRef, OperandQuantifier.One, "type", "Reserved", []); + Instance.Register(Op.OpBeginInvocationInterlockEXT, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpEndInvocationInterlockEXT, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpCooperativeMatrixReduceNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixReduceNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixReduceNV, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixReduceNV, OperandKind.CooperativeMatrixReduce, OperandQuantifier.One, "reduce", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixReduceNV, OperandKind.IdRef, OperandQuantifier.One, "combineFunc", "Arithmetic", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.MemoryAccess, OperandQuantifier.One, "memoryOperand", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixLoadTensorNV, OperandKind.TensorAddressingOperands, OperandQuantifier.One, "tensorAddressingOperands", "Memory", new() { [new(OperandKind.TensorAddressingOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.TensorAddressingOperands, 2)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixStoreTensorNV, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreTensorNV, OperandKind.IdRef, OperandQuantifier.One, "objectId", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreTensorNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Memory", []); + Instance.Register(Op.OpCooperativeMatrixStoreTensorNV, OperandKind.MemoryAccess, OperandQuantifier.One, "memoryOperand", "Memory", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixStoreTensorNV, OperandKind.TensorAddressingOperands, OperandQuantifier.One, "tensorAddressingOperands", "Memory", new() { [new(OperandKind.TensorAddressingOperands, 1)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.TensorAddressingOperands, 2)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpCooperativeMatrixPerElementOpNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Function", []); + Instance.Register(Op.OpCooperativeMatrixPerElementOpNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Function", []); + Instance.Register(Op.OpCooperativeMatrixPerElementOpNV, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Function", []); + Instance.Register(Op.OpCooperativeMatrixPerElementOpNV, OperandKind.IdRef, OperandQuantifier.One, "func", "Function", []); + Instance.Register(Op.OpCooperativeMatrixPerElementOpNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "operands", "Function", []); + Instance.Register(Op.OpTypeTensorLayoutNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorLayoutNV, OperandKind.IdRef, OperandQuantifier.One, "dim", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorLayoutNV, OperandKind.IdRef, OperandQuantifier.One, "clampMode", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorViewNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorViewNV, OperandKind.IdRef, OperandQuantifier.One, "dim", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorViewNV, OperandKind.IdRef, OperandQuantifier.One, "hasDimensions", "Type-Declaration", []); + Instance.Register(Op.OpTypeTensorViewNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "ps", "Type-Declaration", []); + Instance.Register(Op.OpCreateTensorLayoutNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpCreateTensorLayoutNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetDimensionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetDimensionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetDimensionNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetDimensionNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "dims", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetStrideNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetStrideNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetStrideNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetStrideNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "strides", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSliceNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSliceNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSliceNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSliceNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "operands", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetClampValueNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetClampValueNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetClampValueNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetClampValueNV, OperandKind.IdRef, OperandQuantifier.One, "value", "Reserved", []); + Instance.Register(Op.OpCreateTensorViewNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpCreateTensorViewNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorViewSetDimensionNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorViewSetDimensionNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorViewSetDimensionNV, OperandKind.IdRef, OperandQuantifier.One, "tensorView", "Reserved", []); + Instance.Register(Op.OpTensorViewSetDimensionNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "dims", "Reserved", []); + Instance.Register(Op.OpTensorViewSetStrideNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorViewSetStrideNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorViewSetStrideNV, OperandKind.IdRef, OperandQuantifier.One, "tensorView", "Reserved", []); + Instance.Register(Op.OpTensorViewSetStrideNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "strides", "Reserved", []); + Instance.Register(Op.OpDemoteToHelperInvocation, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpIsHelperInvocationEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIsHelperInvocationEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdRef, OperandQuantifier.One, "tensorView", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdRef, OperandQuantifier.One, "clipRowOffset", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdRef, OperandQuantifier.One, "clipRowSpan", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdRef, OperandQuantifier.One, "clipColOffset", "Reserved", []); + Instance.Register(Op.OpTensorViewSetClipNV, OperandKind.IdRef, OperandQuantifier.One, "clipColSpan", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetBlockSizeNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetBlockSizeNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetBlockSizeNV, OperandKind.IdRef, OperandQuantifier.One, "tensorLayout", "Reserved", []); + Instance.Register(Op.OpTensorLayoutSetBlockSizeNV, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "blockSizes", "Reserved", []); + Instance.Register(Op.OpCooperativeMatrixTransposeNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpCooperativeMatrixTransposeNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpCooperativeMatrixTransposeNV, OperandKind.IdRef, OperandQuantifier.One, "matrix", "Conversion", []); + Instance.Register(Op.OpConvertUToImageNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertUToImageNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertUToImageNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpConvertUToSamplerNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertUToSamplerNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertUToSamplerNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpConvertImageToUNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertImageToUNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertImageToUNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpConvertSamplerToUNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertSamplerToUNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertSamplerToUNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpConvertUToSampledImageNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertUToSampledImageNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertUToSampledImageNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpConvertSampledImageToUNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpConvertSampledImageToUNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpConvertSampledImageToUNV, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpSamplerImageAddressingModeNV, OperandKind.LiteralInteger, OperandQuantifier.One, "bitWidth", "Reserved", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdRef, OperandQuantifier.One, "baseId", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdRef, OperandQuantifier.One, "bytestride", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdRef, OperandQuantifier.One, "elementindex", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.IdRef, OperandQuantifier.One, "byteoffset", "Memory", []); + Instance.Register(Op.OpRawAccessChainNV, OperandKind.RawAccessChainOperands, OperandQuantifier.ZeroOrOne, "rawAccessChainOperands", "Memory", []); + Instance.Register(Op.OpSubgroupShuffleINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupShuffleINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupShuffleINTEL, OperandKind.IdRef, OperandQuantifier.One, "data", "Group", []); + Instance.Register(Op.OpSubgroupShuffleINTEL, OperandKind.IdRef, OperandQuantifier.One, "invocationId", "Group", []); + Instance.Register(Op.OpSubgroupShuffleDownINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupShuffleDownINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupShuffleDownINTEL, OperandKind.IdRef, OperandQuantifier.One, "current", "Group", []); + Instance.Register(Op.OpSubgroupShuffleDownINTEL, OperandKind.IdRef, OperandQuantifier.One, "next", "Group", []); + Instance.Register(Op.OpSubgroupShuffleDownINTEL, OperandKind.IdRef, OperandQuantifier.One, "delta", "Group", []); + Instance.Register(Op.OpSubgroupShuffleUpINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupShuffleUpINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupShuffleUpINTEL, OperandKind.IdRef, OperandQuantifier.One, "previous", "Group", []); + Instance.Register(Op.OpSubgroupShuffleUpINTEL, OperandKind.IdRef, OperandQuantifier.One, "current", "Group", []); + Instance.Register(Op.OpSubgroupShuffleUpINTEL, OperandKind.IdRef, OperandQuantifier.One, "delta", "Group", []); + Instance.Register(Op.OpSubgroupShuffleXorINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupShuffleXorINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupShuffleXorINTEL, OperandKind.IdRef, OperandQuantifier.One, "data", "Group", []); + Instance.Register(Op.OpSubgroupShuffleXorINTEL, OperandKind.IdRef, OperandQuantifier.One, "value", "Group", []); + Instance.Register(Op.OpSubgroupBlockReadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupBlockReadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptr", "Group", []); + Instance.Register(Op.OpSubgroupBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptr", "Group", []); + Instance.Register(Op.OpSubgroupBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "data", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockReadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockReadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "image", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "image", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Group", []); + Instance.Register(Op.OpSubgroupImageBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "data", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "image", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "width", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockReadINTEL, OperandKind.IdRef, OperandQuantifier.One, "height", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "image", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "coordinate", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "width", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "height", "Group", []); + Instance.Register(Op.OpSubgroupImageMediaBlockWriteINTEL, OperandKind.IdRef, OperandQuantifier.One, "data", "Group", []); + Instance.Register(Op.OpUCountLeadingZerosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUCountLeadingZerosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUCountLeadingZerosINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpUCountTrailingZerosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUCountTrailingZerosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUCountTrailingZerosINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand", "Reserved", []); + Instance.Register(Op.OpAbsISubINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpAbsISubINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpAbsISubINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpAbsISubINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpAbsUSubINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpAbsUSubINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpAbsUSubINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpAbsUSubINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpIAddSatINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIAddSatINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpIAddSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpIAddSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpUAddSatINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUAddSatINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUAddSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpUAddSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpIAverageINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIAverageINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpIAverageINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpIAverageINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpUAverageINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUAverageINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUAverageINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpUAverageINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpIAverageRoundedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIAverageRoundedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpIAverageRoundedINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpIAverageRoundedINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpUAverageRoundedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUAverageRoundedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUAverageRoundedINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpUAverageRoundedINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpISubSatINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpISubSatINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpISubSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpISubSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpUSubSatINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUSubSatINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUSubSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpUSubSatINTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpIMul32x16INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpIMul32x16INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpIMul32x16INTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpIMul32x16INTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpUMul32x16INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpUMul32x16INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpUMul32x16INTEL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Reserved", []); + Instance.Register(Op.OpUMul32x16INTEL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Reserved", []); + Instance.Register(Op.OpConstantFunctionPointerINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpConstantFunctionPointerINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpConstantFunctionPointerINTEL, OperandKind.IdRef, OperandQuantifier.One, "function", "@exclude", []); + Instance.Register(Op.OpFunctionPointerCallINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFunctionPointerCallINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFunctionPointerCallINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "operands", "@exclude", []); + Instance.Register(Op.OpAsmTargetINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpAsmTargetINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAsmTargetINTEL, OperandKind.LiteralString, OperandQuantifier.One, "asmtarget", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.IdRef, OperandQuantifier.One, "asmtype", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.IdRef, OperandQuantifier.One, "target", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.LiteralString, OperandQuantifier.One, "asminstructions", "@exclude", []); + Instance.Register(Op.OpAsmINTEL, OperandKind.LiteralString, OperandQuantifier.One, "constraints", "@exclude", []); + Instance.Register(Op.OpAsmCallINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpAsmCallINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAsmCallINTEL, OperandKind.IdRef, OperandQuantifier.One, "asm", "@exclude", []); + Instance.Register(Op.OpAsmCallINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "arguments", "@exclude", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicFMinEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicFMaxEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpAssumeTrueKHR, OperandKind.IdRef, OperandQuantifier.One, "condition", "Miscellaneous", []); + Instance.Register(Op.OpExpectKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpExpectKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpExpectKHR, OperandKind.IdRef, OperandQuantifier.One, "value", "Miscellaneous", []); + Instance.Register(Op.OpExpectKHR, OperandKind.IdRef, OperandQuantifier.One, "expectedValue", "Miscellaneous", []); + Instance.Register(Op.OpDecorateString, OperandKind.IdRef, OperandQuantifier.One, "target", "Annotation", []); + Instance.Register(Op.OpDecorateString, OperandKind.Decoration, OperandQuantifier.One, "decoration", "Annotation", []); + Instance.Register(Op.OpDecorateString, OperandKind.LiteralString, OperandQuantifier.One, "value", "Annotation", []); + Instance.Register(Op.OpMemberDecorateString, OperandKind.IdRef, OperandQuantifier.One, "structType", "Annotation", []); + Instance.Register(Op.OpMemberDecorateString, OperandKind.LiteralInteger, OperandQuantifier.One, "member", "Annotation", []); + Instance.Register(Op.OpMemberDecorateString, OperandKind.Decoration, OperandQuantifier.One, "decoration", "Annotation", []); + Instance.Register(Op.OpMemberDecorateString, OperandKind.LiteralString, OperandQuantifier.One, "value", "Annotation", []); + Instance.Register(Op.OpVmeImageINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpVmeImageINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpVmeImageINTEL, OperandKind.IdRef, OperandQuantifier.One, "imageType", "@exclude", []); + Instance.Register(Op.OpVmeImageINTEL, OperandKind.IdRef, OperandQuantifier.One, "sampler", "@exclude", []); + Instance.Register(Op.OpTypeVmeImageINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeVmeImageINTEL, OperandKind.IdRef, OperandQuantifier.One, "imageType", "@exclude", []); + Instance.Register(Op.OpTypeAvcImePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcRefPayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcSicPayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcMcePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcMceResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcImeResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcImeResultSingleReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcImeResultDualReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcImeSingleReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcImeDualReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcRefResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpTypeAvcSicResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "referenceBasePenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedShapePenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "directionCost", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedCostCenterDelta", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedCostTable", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "costPrecision", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "sliceType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "qp", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetAcOnlyHaarINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetAcOnlyHaarINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetAcOnlyHaarINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, OperandKind.IdRef, OperandQuantifier.One, "sourceFieldPolarity", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, OperandKind.IdRef, OperandQuantifier.One, "referenceFieldPolarity", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "forwardReferenceFieldPolarity", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "backwardReferenceFieldPolarity", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImePayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImePayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImeResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImeResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToImeResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefPayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefPayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefPayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToRefResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicPayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicPayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicPayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceConvertToSicResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetMotionVectorsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetMotionVectorsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDistortionsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDistortionsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetBestInterDistortionsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetBestInterDistortionsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetBestInterDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMajorShapeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMajorShapeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMajorShapeINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMinorShapeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMinorShapeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMinorShapeINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDirectionsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDirectionsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterDirectionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMotionVectorCountINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMotionVectorCountINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterMotionVectorCountINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceIdsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceIdsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceIds", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceParameterFieldPolarities", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeInitializeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeInitializeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcCoord", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "partitionMask", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "sADAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetSingleReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetSingleReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "refOffset", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "searchWindowConfig", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefOffset", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefOffset", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "idSearchWindowConfig", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeRefWindowSizeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeRefWindowSizeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeRefWindowSizeINTEL, OperandKind.IdRef, OperandQuantifier.One, "searchWindowConfig", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeRefWindowSizeINTEL, OperandKind.IdRef, OperandQuantifier.One, "dualRef", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdRef, OperandQuantifier.One, "refOffset", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcCoord", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdRef, OperandQuantifier.One, "refWindowSize", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, OperandKind.IdRef, OperandQuantifier.One, "imageSize", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMcePayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMcePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMcePayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, OperandKind.IdRef, OperandQuantifier.One, "maxMotionVectorCount", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, OperandKind.IdRef, OperandQuantifier.One, "threshold", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetWeightedSadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetWeightedSadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetWeightedSadINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedSadWeights", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeSetWeightedSadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "streaminComponents", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "streaminComponents", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "streaminComponents", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "streaminComponents", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMceResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMceResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeConvertToMceResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetDualReferenceStreaminINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetDualReferenceStreaminINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetDualReferenceStreaminINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShape", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetBorderReachedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetBorderReachedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetBorderReachedINTEL, OperandKind.IdRef, OperandQuantifier.One, "imageSelect", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetBorderReachedINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcCoord", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "motionVectors", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShapes", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "minorShapes", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "pixelResolution", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcFmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "sadAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcCoord", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "motionVectors", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "majorShapes", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "minorShapes", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "pixelResolution", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "bidirectionalWeight", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcBmeInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "sadAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMcePayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMcePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMcePayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBilinearFilterEnableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBilinearFilterEnableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefSetBilinearFilterEnableINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceIds", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceIds", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceFieldPolarities", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMceResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMceResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcRefConvertToMceResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicInitializeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicInitializeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicInitializeINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcCoord", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "skipBlockPartitionType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "skipMotionVectorMask", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "motionVectors", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "bidirectionalWeight", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "sadAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureSkcINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "lumaIntraPartitionMask", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "intraNeighbourAvailabilty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "leftEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperLeftCornerLumaPixel", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperRightEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "sadAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "lumaIntraPartitionMask", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "intraNeighbourAvailabilty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "leftEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperLeftCornerLumaPixel", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperRightEdgeLumaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "leftEdgeChromaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperLeftCornerChromaPixel", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "upperEdgeChromaPixels", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "sadAdjustment", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL, OperandKind.IdRef, OperandQuantifier.One, "skipBlockPartitionType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL, OperandKind.IdRef, OperandQuantifier.One, "direction", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMcePayloadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMcePayloadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMcePayloadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedShapePenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "lumaModePenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "lumaPackedNeighborModes", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "lumaPackedNonDcPenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "chromaModeBasePenalty", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBilinearFilterEnableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBilinearFilterEnableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBilinearFilterEnableINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedSadCoefficients", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, OperandKind.IdRef, OperandQuantifier.One, "blockBasedSkipType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateIpeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateIpeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateIpeINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateIpeINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "refImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "fwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "bwdRefImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceIds", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "srcImage", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceIds", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "packedReferenceFieldPolarities", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMceResultINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMceResultINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicConvertToMceResultINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeLumaShapeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeLumaShapeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeLumaShapeINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeChromaModeINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeChromaModeINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetIpeChromaModeINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetInterRawSadsINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetInterRawSadsINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpSubgroupAvcSicGetInterRawSadsINTEL, OperandKind.IdRef, OperandQuantifier.One, "payload", "@exclude", []); + Instance.Register(Op.OpVariableLengthArrayINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpVariableLengthArrayINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpVariableLengthArrayINTEL, OperandKind.IdRef, OperandQuantifier.One, "lenght", "@exclude", []); + Instance.Register(Op.OpSaveMemoryINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpSaveMemoryINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpRestoreMemoryINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptr", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "fromSign", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "fromSign", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastFromIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCastToIntINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatAddINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSubINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatMulINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatDivINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGTINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatGEINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLTINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLEINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatEQINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatRSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCbrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatHypotINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatLog1pINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExp10INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatExpm1INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatASinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatACosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATanPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatATan2INTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m2", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowRINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.IdRef, OperandQuantifier.One, "a", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "m1", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.IdRef, OperandQuantifier.One, "b", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "mout", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "enableSubnormals", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingMode", "@exclude", []); + Instance.Register(Op.OpArbitraryFloatPowNINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "roundingAccuracy", "@exclude", []); + Instance.Register(Op.OpLoopControlINTEL, OperandKind.LiteralInteger, OperandQuantifier.ZeroOrMore, "loopControlParameters", "Reserved", []); + Instance.Register(Op.OpAliasDomainDeclINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAliasDomainDeclINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "name", "@exclude", []); + Instance.Register(Op.OpAliasScopeDeclINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAliasScopeDeclINTEL, OperandKind.IdRef, OperandQuantifier.One, "aliasDomain", "@exclude", []); + Instance.Register(Op.OpAliasScopeDeclINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "name", "@exclude", []); + Instance.Register(Op.OpAliasScopeListDeclINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpAliasScopeListDeclINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "aliasScope1s", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedSqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedRecipINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedRsqrtINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedSinINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedSinCosINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedSinPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedSinCosPiINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedLogINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputType", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "s", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "i", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "rI", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "q", "@exclude", []); + Instance.Register(Op.OpFixedExpINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "o", "@exclude", []); + Instance.Register(Op.OpPtrCastToCrossWorkgroupINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpPtrCastToCrossWorkgroupINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpPtrCastToCrossWorkgroupINTEL, OperandKind.IdRef, OperandQuantifier.One, "pointer", "@exclude", []); + Instance.Register(Op.OpCrossWorkgroupCastToPtrINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "@exclude", []); + Instance.Register(Op.OpCrossWorkgroupCastToPtrINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "@exclude", []); + Instance.Register(Op.OpCrossWorkgroupCastToPtrINTEL, OperandKind.IdRef, OperandQuantifier.One, "pointer", "@exclude", []); + Instance.Register(Op.OpReadPipeBlockingINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpReadPipeBlockingINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpReadPipeBlockingINTEL, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpReadPipeBlockingINTEL, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpWritePipeBlockingINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Pipe", []); + Instance.Register(Op.OpWritePipeBlockingINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Pipe", []); + Instance.Register(Op.OpWritePipeBlockingINTEL, OperandKind.IdRef, OperandQuantifier.One, "packetSize", "Pipe", []); + Instance.Register(Op.OpWritePipeBlockingINTEL, OperandKind.IdRef, OperandQuantifier.One, "packetAlignment", "Pipe", []); + Instance.Register(Op.OpFPGARegINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpFPGARegINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpFPGARegINTEL, OperandKind.IdRef, OperandQuantifier.One, "result", "Reserved", []); + Instance.Register(Op.OpFPGARegINTEL, OperandKind.IdRef, OperandQuantifier.One, "input", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayTMinKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayTMinKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayTMinKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayFlagsKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayFlagsKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetRayFlagsKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionTKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceIdKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceIdKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceIdKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceIdKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionGeometryIndexKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionGeometryIndexKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionGeometryIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionGeometryIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionPrimitiveIndexKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionPrimitiveIndexKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionPrimitiveIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionPrimitiveIndexKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionBarycentricsKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionBarycentricsKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionBarycentricsKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionBarycentricsKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionFrontFaceKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionFrontFaceKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionFrontFaceKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionFrontFaceKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayDirectionKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayDirectionKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayDirectionKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayDirectionKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayOriginKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayOriginKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayOriginKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectRayOriginKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayDirectionKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayDirectionKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayDirectionKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayOriginKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayOriginKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetWorldRayOriginKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectToWorldKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectToWorldKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectToWorldKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionObjectToWorldKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionWorldToObjectKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionWorldToObjectKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionWorldToObjectKHR, OperandKind.IdRef, OperandQuantifier.One, "rayQuery", "Reserved", []); + Instance.Register(Op.OpRayQueryGetIntersectionWorldToObjectKHR, OperandKind.IdRef, OperandQuantifier.One, "intersection", "Reserved", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Atomic", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Atomic", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdRef, OperandQuantifier.One, "pointer", "Atomic", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdScope, OperandQuantifier.One, "memory", "Atomic", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Atomic", []); + Instance.Register(Op.OpAtomicFAddEXT, OperandKind.IdRef, OperandQuantifier.One, "value", "Atomic", []); + Instance.Register(Op.OpTypeBufferSurfaceINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeBufferSurfaceINTEL, OperandKind.AccessQualifier, OperandQuantifier.One, "accessQualifier", "Type-Declaration", []); + Instance.Register(Op.OpTypeStructContinuedINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "memberTypes", "Type-Declaration", []); + Instance.Register(Op.OpConstantCompositeContinuedINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Constant-Creation", []); + Instance.Register(Op.OpSpecConstantCompositeContinuedINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Constant-Creation", []); + Instance.Register(Op.OpCompositeConstructContinuedINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Composite", []); + Instance.Register(Op.OpCompositeConstructContinuedINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Composite", []); + Instance.Register(Op.OpCompositeConstructContinuedINTEL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "constituents", "Composite", []); + Instance.Register(Op.OpConvertFToBF16INTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertFToBF16INTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertFToBF16INTEL, OperandKind.IdRef, OperandQuantifier.One, "floatValue", "Conversion", []); + Instance.Register(Op.OpConvertBF16ToFINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Conversion", []); + Instance.Register(Op.OpConvertBF16ToFINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Conversion", []); + Instance.Register(Op.OpConvertBF16ToFINTEL, OperandKind.IdRef, OperandQuantifier.One, "bFloat16Value", "Conversion", []); + Instance.Register(Op.OpControlBarrierArriveINTEL, OperandKind.IdScope, OperandQuantifier.One, "execution", "Barrier", []); + Instance.Register(Op.OpControlBarrierArriveINTEL, OperandKind.IdScope, OperandQuantifier.One, "memory", "Barrier", []); + Instance.Register(Op.OpControlBarrierArriveINTEL, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Barrier", []); + Instance.Register(Op.OpControlBarrierWaitINTEL, OperandKind.IdScope, OperandQuantifier.One, "execution", "Barrier", []); + Instance.Register(Op.OpControlBarrierWaitINTEL, OperandKind.IdScope, OperandQuantifier.One, "memory", "Barrier", []); + Instance.Register(Op.OpControlBarrierWaitINTEL, OperandKind.IdMemorySemantics, OperandQuantifier.One, "semantics", "Barrier", []); + Instance.Register(Op.OpArithmeticFenceEXT, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpArithmeticFenceEXT, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpArithmeticFenceEXT, OperandKind.IdRef, OperandQuantifier.One, "target", "Miscellaneous", []); + Instance.Register(Op.OpSubgroupBlockPrefetchINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptr", "Group", []); + Instance.Register(Op.OpSubgroupBlockPrefetchINTEL, OperandKind.IdRef, OperandQuantifier.One, "numBytes", "Group", []); + Instance.Register(Op.OpSubgroupBlockPrefetchINTEL, OperandKind.MemoryAccess, OperandQuantifier.ZeroOrOne, "memoryAccess", "Group", new() { [new(OperandKind.MemoryAccess, 2)] = [new("literalinteger0", OperandKind.LiteralInteger)], [new(OperandKind.MemoryAccess, 8)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 16)] = [new("idscope0", OperandKind.IdScope)], [new(OperandKind.MemoryAccess, 65536)] = [new("idRef0", OperandKind.IdRef)], [new(OperandKind.MemoryAccess, 131072)] = [new("idRef0", OperandKind.IdRef)] }); + Instance.Register(Op.OpGroupIMulKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupIMulKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupIMulKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupIMulKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupIMulKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupFMulKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupFMulKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupFMulKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupFMulKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupFMulKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupBitwiseAndKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupBitwiseAndKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupBitwiseAndKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupBitwiseAndKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupBitwiseAndKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupBitwiseOrKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupBitwiseOrKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupBitwiseOrKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupBitwiseOrKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupBitwiseOrKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupBitwiseXorKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupBitwiseXorKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupBitwiseXorKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupBitwiseXorKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupBitwiseXorKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupLogicalAndKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupLogicalAndKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupLogicalAndKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupLogicalAndKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupLogicalAndKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupLogicalOrKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupLogicalOrKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupLogicalOrKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupLogicalOrKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupLogicalOrKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpGroupLogicalXorKHR, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Group", []); + Instance.Register(Op.OpGroupLogicalXorKHR, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Group", []); + Instance.Register(Op.OpGroupLogicalXorKHR, OperandKind.IdScope, OperandQuantifier.One, "execution", "Group", []); + Instance.Register(Op.OpGroupLogicalXorKHR, OperandKind.GroupOperation, OperandQuantifier.One, "operation", "Group", []); + Instance.Register(Op.OpGroupLogicalXorKHR, OperandKind.IdRef, OperandQuantifier.One, "x", "Group", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptrVector", "Memory", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "alignment", "Memory", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.IdRef, OperandQuantifier.One, "mask", "Memory", []); + Instance.Register(Op.OpMaskedGatherINTEL, OperandKind.IdRef, OperandQuantifier.One, "fillEmpty", "Memory", []); + Instance.Register(Op.OpMaskedScatterINTEL, OperandKind.IdRef, OperandQuantifier.One, "inputVector", "Memory", []); + Instance.Register(Op.OpMaskedScatterINTEL, OperandKind.IdRef, OperandQuantifier.One, "ptrVector", "Memory", []); + Instance.Register(Op.OpMaskedScatterINTEL, OperandKind.LiteralInteger, OperandQuantifier.One, "alignment", "Memory", []); + Instance.Register(Op.OpMaskedScatterINTEL, OperandKind.IdRef, OperandQuantifier.One, "mask", "Memory", []); + Instance.Register(Op.OpShaderSDSL, OperandKind.LiteralString, OperandQuantifier.One, "shaderName", "Miscellaneous", []); + Instance.Register(Op.OpCompositionSDSL, OperandKind.LiteralString, OperandQuantifier.One, "compositionPath", "Miscellaneous", []); + Instance.Register(Op.OpCompositionEndSDSL, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpMixinInheritSDSL, OperandKind.IdRef, OperandQuantifier.One, "shader", "Miscellaneous", []); + Instance.Register(Op.OpMixinInheritSDSL, OperandKind.MixinInheritFlags, OperandQuantifier.One, "flags", "Miscellaneous", []); + Instance.Register(Op.OpImportShaderSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpImportShaderSDSL, OperandKind.LiteralString, OperandQuantifier.One, "shaderName", "Miscellaneous", []); + Instance.Register(Op.OpImportShaderSDSL, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "generics", "Miscellaneous", []); + Instance.Register(Op.OpImportFunctionSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpImportFunctionSDSL, OperandKind.IdResultType, OperandQuantifier.One, "functionType", "Miscellaneous", []); + Instance.Register(Op.OpImportFunctionSDSL, OperandKind.LiteralString, OperandQuantifier.One, "functionName", "Miscellaneous", []); + Instance.Register(Op.OpImportFunctionSDSL, OperandKind.IdRef, OperandQuantifier.One, "shader", "Miscellaneous", []); + Instance.Register(Op.OpImportFunctionSDSL, OperandKind.FunctionFlags, OperandQuantifier.One, "flags", "Miscellaneous", []); + Instance.Register(Op.OpImportVariableSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpImportVariableSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpImportVariableSDSL, OperandKind.LiteralString, OperandQuantifier.One, "variableName", "Miscellaneous", []); + Instance.Register(Op.OpImportVariableSDSL, OperandKind.IdRef, OperandQuantifier.One, "shader", "Miscellaneous", []); + Instance.Register(Op.OpImportVariableSDSL, OperandKind.VariableFlags, OperandQuantifier.One, "flags", "Miscellaneous", []); + Instance.Register(Op.OpImportStructSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpImportStructSDSL, OperandKind.LiteralString, OperandQuantifier.One, "structName", "Miscellaneous", []); + Instance.Register(Op.OpImportStructSDSL, OperandKind.IdRef, OperandQuantifier.One, "shader", "Miscellaneous", []); + Instance.Register(Op.OpVariableSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Memory", []); + Instance.Register(Op.OpVariableSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Memory", []); + Instance.Register(Op.OpVariableSDSL, OperandKind.StorageClass, OperandQuantifier.One, "storageClass", "Memory", []); + Instance.Register(Op.OpVariableSDSL, OperandKind.VariableFlags, OperandQuantifier.One, "flags", "Memory", []); + Instance.Register(Op.OpVariableSDSL, OperandKind.IdRef, OperandQuantifier.ZeroOrOne, "methodOrConstantInitializer", "Memory", []); + Instance.Register(Op.OpMemberAccessSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpMemberAccessSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpMemberAccessSDSL, OperandKind.IdRef, OperandQuantifier.One, "instance", "Miscellaneous", []); + Instance.Register(Op.OpMemberAccessSDSL, OperandKind.IdRef, OperandQuantifier.One, "member", "Miscellaneous", []); + Instance.Register(Op.OpTypeFunctionSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Type-Declaration", []); + Instance.Register(Op.OpTypeFunctionSDSL, OperandKind.IdRef, OperandQuantifier.One, "returnType", "Type-Declaration", []); + Instance.Register(Op.OpTypeFunctionSDSL, OperandKind.PairIdRefLiteralInteger, OperandQuantifier.ZeroOrMore, "parameterTypes", "Type-Declaration", []); + Instance.Register(Op.OpFunctionMetadataSDSL, OperandKind.FunctionFlags, OperandQuantifier.One, "flags", "Miscellaneous", []); + Instance.Register(Op.OpFunctionMetadataSDSL, OperandKind.IdRef, OperandQuantifier.One, "parent", "Miscellaneous", []); + Instance.Register(Op.OpBaseSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpThisSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpStreamsSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpGenericParameterSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpGenericParameterSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpGenericParameterSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "index", "Miscellaneous", []); + Instance.Register(Op.OpGenericParameterSDSL, OperandKind.LiteralString, OperandQuantifier.One, "declaringClass", "Miscellaneous", []); + Instance.Register(Op.OpGenericReferenceSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpGenericReferenceSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpGenericReferenceSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "index", "Miscellaneous", []); + Instance.Register(Op.OpGenericReferenceSDSL, OperandKind.LiteralString, OperandQuantifier.One, "declaringClass", "Miscellaneous", []); + Instance.Register(Op.OpConstantStringSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpConstantStringSDSL, OperandKind.LiteralString, OperandQuantifier.One, "literalString", "Miscellaneous", []); + Instance.Register(Op.OpTypeGenericSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpTypeGenericSDSL, OperandKind.GenericParameterKindSDSL, OperandQuantifier.One, "kind", "Miscellaneous", []); + Instance.Register(Op.OpTypeStreamsSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpTypeStreamsSDSL, OperandKind.StreamsKindSDSL, OperandQuantifier.One, "kind", "Miscellaneous", []); + Instance.Register(Op.OpTypeGeometryStreamOutputSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpTypeGeometryStreamOutputSDSL, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Miscellaneous", []); + Instance.Register(Op.OpTypeGeometryStreamOutputSDSL, OperandKind.GeometryStreamOutputKindSDSL, OperandQuantifier.One, "kind", "Miscellaneous", []); + Instance.Register(Op.OpTypePatchSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpTypePatchSDSL, OperandKind.IdRef, OperandQuantifier.One, "baseType", "Miscellaneous", []); + Instance.Register(Op.OpTypePatchSDSL, OperandKind.PatchTypeKindSDSL, OperandQuantifier.One, "kind", "Miscellaneous", []); + Instance.Register(Op.OpTypePatchSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "size", "Miscellaneous", []); + Instance.Register(Op.OpForeachSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpForeachSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpForeachSDSL, OperandKind.IdRef, OperandQuantifier.One, "collection", "Miscellaneous", []); + Instance.Register(Op.OpForeachEndSDSL, OperandKind.None, null, "Debug"); + Instance.Register(Op.OpUnresolvableShaderSDSL, OperandKind.LiteralString, OperandQuantifier.One, "shaderCode", "Miscellaneous", []); + Instance.Register(Op.OpUnresolvableShaderSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "shaderCodeNameEnd", "Miscellaneous", []); + Instance.Register(Op.OpEmitVertexSDSL, OperandKind.IdRef, OperandQuantifier.One, "output", "Miscellaneous", []); + Instance.Register(Op.OpBinaryOperationSDSL, OperandKind.IdResultType, OperandQuantifier.One, "resultType", "Miscellaneous", []); + Instance.Register(Op.OpBinaryOperationSDSL, OperandKind.IdResult, OperandQuantifier.One, "resultId", "Miscellaneous", []); + Instance.Register(Op.OpBinaryOperationSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "operation", "Miscellaneous", []); + Instance.Register(Op.OpBinaryOperationSDSL, OperandKind.IdRef, OperandQuantifier.One, "operand1", "Miscellaneous", []); + Instance.Register(Op.OpBinaryOperationSDSL, OperandKind.IdRef, OperandQuantifier.One, "operand2", "Miscellaneous", []); + Instance.Register(Op.OpSourceHashSDSL, OperandKind.IdRef, OperandQuantifier.One, "file", "Miscellaneous", []); + Instance.Register(Op.OpSourceHashSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "hash1", "Miscellaneous", []); + Instance.Register(Op.OpSourceHashSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "hash2", "Miscellaneous", []); + Instance.Register(Op.OpSourceHashSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "hash3", "Miscellaneous", []); + Instance.Register(Op.OpSourceHashSDSL, OperandKind.LiteralInteger, OperandQuantifier.One, "hash4", "Miscellaneous", []); + Instance.Register(Op.OpEffectSDFX, OperandKind.LiteralString, OperandQuantifier.One, "effectName", "Miscellaneous", []); + Instance.Register(Op.OpParamsUseSDFX, OperandKind.IdRef, OperandQuantifier.One, "paramsName", "Miscellaneous", []); + Instance.Register(Op.OpParamsSDFX, OperandKind.LiteralString, OperandQuantifier.One, "name", "Miscellaneous", []); + Instance.Register(Op.OpParamsFieldSDFX, OperandKind.LiteralString, OperandQuantifier.One, "name", "Miscellaneous", []); + Instance.Register(Op.OpParamsFieldSDFX, OperandKind.LiteralString, OperandQuantifier.One, "cstype", "Miscellaneous", []); + Instance.Register(Op.OpMixinSDFX, OperandKind.MixinKindSDFX, OperandQuantifier.One, "kind", "Miscellaneous", []); + Instance.Register(Op.OpMixinSDFX, OperandKind.IdRef, OperandQuantifier.One, "target", "Miscellaneous", []); + Instance.Register(Op.OpMixinSDFX, OperandKind.IdRef, OperandQuantifier.One, "value", "Miscellaneous", []); + Instance.Register(Op.OpMixinSDFX, OperandKind.IdRef, OperandQuantifier.ZeroOrMore, "generics", "Miscellaneous", []); + Instance.InitOrder(); + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/Instructions.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/Instructions.gen.cs new file mode 100644 index 0000000000..74f3f202ef --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/Instructions.gen.cs @@ -0,0 +1,133325 @@ +#pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. + +using static Stride.Shaders.Spirv.Specification; +using CommunityToolkit.HighPerformance; +using CommunityToolkit.HighPerformance.Buffers; +using Stride.Shaders.Spirv.Core.Buffers; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace Stride.Shaders.Spirv.Core; +public ref partial struct OpNop : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpNop() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpNop | (1 << 16); + } + + public OpNop(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpNop(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpNop]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpNop(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUndef : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUndef() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUndef | (1 << 16); + } + + public OpUndef(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUndef(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUndef inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUndef inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUndef(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUndef, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUndef(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSourceContinued : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSourceContinued() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSourceContinued | (1 << 16); + } + + public OpSourceContinued(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSourceContinued(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string ContinuedSource + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSourceContinued(string continuedSource) + { + ContinuedSource = continuedSource; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSourceContinued, ..ContinuedSource.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "continuedSource": + ContinuedSource = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSourceContinued(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSource : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSource() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSource | (1 << 16); + } + + public OpSource(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSource(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public SourceLanguage SourceLanguage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Version + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? File + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string? Source + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSource(SourceLanguage sourceLanguage, int version, int? file, string? source) + { + SourceLanguage = sourceLanguage; + Version = version; + File = file; + Source = source; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSource, (int)SourceLanguage, ..Version.AsDisposableLiteralValue().Words, ..(File is null ? (Span)[] : [File.Value]), ..(Source is null ? (Span)[] : Source.AsDisposableLiteralValue().Words)]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "sourceLanguage": + SourceLanguage = o.ToEnum(); + break; + case "version": + Version = o.ToLiteral(); + break; + case "file": + if (o.Words.Length > 0) + { + File = o.ToLiteral(); + } + + break; + case "source": + if (o.Words.Length > 0) + { + Source = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSource(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSourceExtension : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSourceExtension() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSourceExtension | (1 << 16); + } + + public OpSourceExtension(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSourceExtension(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string Extension + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSourceExtension(string extension) + { + Extension = extension; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSourceExtension, ..Extension.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "extension": + Extension = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSourceExtension(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpName : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpName() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpName | (1 << 16); + } + + public OpName(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpName(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpName(int target, string name) + { + Target = target; + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpName, Target, ..Name.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "target": + Target = o.ToLiteral(); + break; + case "name": + Name = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpName(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMemberName : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemberName() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemberName | (1 << 16); + } + + public OpMemberName(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemberName(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Type + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Member + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemberName(int type, int member, string name) + { + Type = type; + Member = member; + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemberName, Type, ..Member.AsDisposableLiteralValue().Words, ..Name.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "type": + Type = o.ToLiteral(); + break; + case "member": + Member = o.ToLiteral(); + break; + case "name": + Name = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemberName(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpString : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpString() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpString | (1 << 16); + } + + public OpString(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpString(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpString inst) => inst.ResultId; + public OpString(int resultId, string value) + { + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpString, ResultId, ..Value.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpString(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLine : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLine() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLine | (1 << 16); + } + + public OpLine(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLine(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int File + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Line + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Column + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpLine(int file, int line, int column) + { + File = file; + Line = line; + Column = column; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLine, File, ..Line.AsDisposableLiteralValue().Words, ..Column.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "file": + File = o.ToLiteral(); + break; + case "line": + Line = o.ToLiteral(); + break; + case "column": + Column = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLine(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExtension : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExtension() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtension | (1 << 16); + } + + public OpExtension(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExtension(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpExtension(string name) + { + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtension, ..Name.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "name": + Name = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExtension(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExtInstImport : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExtInstImport() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInstImport | (1 << 16); + } + + public OpExtInstImport(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExtInstImport(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpExtInstImport inst) => inst.ResultId; + public OpExtInstImport(int resultId, string name) + { + ResultId = resultId; + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInstImport, ResultId, ..Name.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "name": + Name = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExtInstImport(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExtInst : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExtInst() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public OpExtInst(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExtInst(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Instruction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Operands + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpExtInst inst) => inst.ResultId; + public static implicit operator SpirvValue(OpExtInst inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpExtInst(int resultType, int resultId, int set, int instruction, LiteralArray operands) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Instruction = instruction; + Operands = operands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, ..Instruction.AsDisposableLiteralValue().Words, ..Operands.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "instruction": + Instruction = o.ToLiteral(); + break; + case "operands": + Operands = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Operands.WordCount == -1) + Operands = new(); + } + + public static implicit operator OpExtInst(OpDataIndex odi) => new(odi); + public void Dispose() + { + Operands.Dispose(); + } +} + +public ref partial struct OpMemoryModel : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemoryModel() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemoryModel | (1 << 16); + } + + public OpMemoryModel(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemoryModel(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public AddressingModel AddressingModel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public MemoryModel MemoryModel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemoryModel(AddressingModel addressingModel, MemoryModel memoryModel) + { + AddressingModel = addressingModel; + MemoryModel = memoryModel; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemoryModel, (int)AddressingModel, (int)MemoryModel]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "addressingModel": + AddressingModel = o.ToEnum(); + break; + case "memoryModel": + MemoryModel = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemoryModel(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEntryPoint : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEntryPoint() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEntryPoint | (1 << 16); + } + + public OpEntryPoint(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEntryPoint(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public ExecutionModel ExecutionModel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EntryPoint + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray InterfaceIds + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEntryPoint(ExecutionModel executionModel, int entryPoint, string name, LiteralArray interfaceIds) + { + ExecutionModel = executionModel; + EntryPoint = entryPoint; + Name = name; + InterfaceIds = interfaceIds; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEntryPoint, (int)ExecutionModel, EntryPoint, ..Name.AsDisposableLiteralValue().Words, ..InterfaceIds.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "executionModel": + ExecutionModel = o.ToEnum(); + break; + case "entryPoint": + EntryPoint = o.ToLiteral(); + break; + case "name": + Name = o.ToLiteral(); + break; + case "interfaceIds": + InterfaceIds = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (InterfaceIds.WordCount == -1) + InterfaceIds = new(); + } + + public static implicit operator OpEntryPoint(OpDataIndex odi) => new(odi); + public void Dispose() + { + InterfaceIds.Dispose(); + } +} + +public ref partial struct OpExecutionMode : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExecutionMode() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExecutionMode | (1 << 16); + } + + public OpExecutionMode(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExecutionMode(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EntryPoint + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ExecutionMode Mode { get; set; } + + public EnumerantParameters ModeParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpExecutionMode(int entryPoint, ExecutionMode mode, EnumerantParameters modeParameters) + { + EntryPoint = entryPoint; + Mode = mode; + ModeParameters = modeParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExecutionMode, EntryPoint, (int)Mode, ..ModeParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "entryPoint": + EntryPoint = o.ToLiteral(); + break; + case "mode": + Mode = o.ToEnum(); + ModeParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExecutionMode(OpDataIndex odi) => new(odi); + public void Dispose() + { + ModeParameters.Dispose(); + } +} + +public ref partial struct OpCapability : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCapability() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCapability | (1 << 16); + } + + public OpCapability(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCapability(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public Capability Capability + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpCapability(Capability capability) + { + Capability = capability; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCapability, (int)Capability]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "capability": + Capability = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCapability(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeVoid : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeVoid() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeVoid | (1 << 16); + } + + public OpTypeVoid(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeVoid(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeVoid inst) => inst.ResultId; + public OpTypeVoid(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeVoid, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeVoid(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeBool : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeBool() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeBool | (1 << 16); + } + + public OpTypeBool(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeBool(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeBool inst) => inst.ResultId; + public OpTypeBool(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeBool, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeBool(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeInt : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeInt() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeInt | (1 << 16); + } + + public OpTypeInt(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeInt(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Width + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Signedness + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeInt inst) => inst.ResultId; + public OpTypeInt(int resultId, int width, int signedness) + { + ResultId = resultId; + Width = width; + Signedness = signedness; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeInt, ResultId, ..Width.AsDisposableLiteralValue().Words, ..Signedness.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "width": + Width = o.ToLiteral(); + break; + case "signedness": + Signedness = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeInt(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeFloat : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeFloat() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeFloat | (1 << 16); + } + + public OpTypeFloat(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeFloat(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Width + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public FPEncoding? FloatingPointEncoding + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeFloat inst) => inst.ResultId; + public OpTypeFloat(int resultId, int width, FPEncoding? floatingPointEncoding) + { + ResultId = resultId; + Width = width; + FloatingPointEncoding = floatingPointEncoding; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeFloat, ResultId, ..Width.AsDisposableLiteralValue().Words, ..(FloatingPointEncoding is null ? (Span)[] : [(int)FloatingPointEncoding.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "width": + Width = o.ToLiteral(); + break; + case "floatingPointEncoding": + if (o.Words.Length > 0) + { + FloatingPointEncoding = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeFloat(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeVector : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeVector() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeVector | (1 << 16); + } + + public OpTypeVector(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeVector(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ComponentType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ComponentCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeVector inst) => inst.ResultId; + public OpTypeVector(int resultId, int componentType, int componentCount) + { + ResultId = resultId; + ComponentType = componentType; + ComponentCount = componentCount; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeVector, ResultId, ComponentType, ..ComponentCount.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "componentType": + ComponentType = o.ToLiteral(); + break; + case "componentCount": + ComponentCount = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeVector(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeMatrix : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeMatrix() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeMatrix | (1 << 16); + } + + public OpTypeMatrix(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeMatrix(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ColumnType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ColumnCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeMatrix inst) => inst.ResultId; + public OpTypeMatrix(int resultId, int columnType, int columnCount) + { + ResultId = resultId; + ColumnType = columnType; + ColumnCount = columnCount; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeMatrix, ResultId, ColumnType, ..ColumnCount.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "columnType": + ColumnType = o.ToLiteral(); + break; + case "columnCount": + ColumnCount = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeMatrix(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeImage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeImage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeImage | (1 << 16); + } + + public OpTypeImage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeImage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Dim Dim + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Depth + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Arrayed + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MS + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Sampled + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageFormat ImageFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public AccessQualifier? AccessQualifier + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeImage inst) => inst.ResultId; + public OpTypeImage(int resultId, int sampledType, Dim dim, int depth, int arrayed, int mS, int sampled, ImageFormat imageFormat, AccessQualifier? accessQualifier) + { + ResultId = resultId; + SampledType = sampledType; + Dim = dim; + Depth = depth; + Arrayed = arrayed; + MS = mS; + Sampled = sampled; + ImageFormat = imageFormat; + AccessQualifier = accessQualifier; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeImage, ResultId, SampledType, (int)Dim, ..Depth.AsDisposableLiteralValue().Words, ..Arrayed.AsDisposableLiteralValue().Words, ..MS.AsDisposableLiteralValue().Words, ..Sampled.AsDisposableLiteralValue().Words, (int)ImageFormat, ..(AccessQualifier is null ? (Span)[] : [(int)AccessQualifier.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledType": + SampledType = o.ToLiteral(); + break; + case "dim": + Dim = o.ToEnum(); + break; + case "depth": + Depth = o.ToLiteral(); + break; + case "arrayed": + Arrayed = o.ToLiteral(); + break; + case "mS": + MS = o.ToLiteral(); + break; + case "sampled": + Sampled = o.ToLiteral(); + break; + case "imageFormat": + ImageFormat = o.ToEnum(); + break; + case "accessQualifier": + if (o.Words.Length > 0) + { + AccessQualifier = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeImage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeSampler : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeSampler() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeSampler | (1 << 16); + } + + public OpTypeSampler(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeSampler(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeSampler inst) => inst.ResultId; + public OpTypeSampler(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeSampler, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeSampler(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeSampledImage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeSampledImage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeSampledImage | (1 << 16); + } + + public OpTypeSampledImage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeSampledImage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ImageType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeSampledImage inst) => inst.ResultId; + public OpTypeSampledImage(int resultId, int imageType) + { + ResultId = resultId; + ImageType = imageType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeSampledImage, ResultId, ImageType]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "imageType": + ImageType = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeSampledImage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeArray : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeArray() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeArray | (1 << 16); + } + + public OpTypeArray(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeArray(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ElementType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Length + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeArray inst) => inst.ResultId; + public OpTypeArray(int resultId, int elementType, int length) + { + ResultId = resultId; + ElementType = elementType; + Length = length; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeArray, ResultId, ElementType, Length]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "elementType": + ElementType = o.ToLiteral(); + break; + case "length": + Length = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeArray(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeRuntimeArray : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeRuntimeArray() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeRuntimeArray | (1 << 16); + } + + public OpTypeRuntimeArray(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeRuntimeArray(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ElementType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeRuntimeArray inst) => inst.ResultId; + public OpTypeRuntimeArray(int resultId, int elementType) + { + ResultId = resultId; + ElementType = elementType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeRuntimeArray, ResultId, ElementType]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "elementType": + ElementType = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeRuntimeArray(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeStruct : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeStruct() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeStruct | (1 << 16); + } + + public OpTypeStruct(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeStruct(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray MemberTypes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeStruct inst) => inst.ResultId; + public OpTypeStruct(int resultId, LiteralArray memberTypes) + { + ResultId = resultId; + MemberTypes = memberTypes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeStruct, ResultId, ..MemberTypes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "memberTypes": + MemberTypes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (MemberTypes.WordCount == -1) + MemberTypes = new(); + } + + public static implicit operator OpTypeStruct(OpDataIndex odi) => new(odi); + public void Dispose() + { + MemberTypes.Dispose(); + } +} + +public ref partial struct OpTypeOpaque : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeOpaque() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeOpaque | (1 << 16); + } + + public OpTypeOpaque(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeOpaque(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Thenameoftheopaquetype + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeOpaque inst) => inst.ResultId; + public OpTypeOpaque(int resultId, string thenameoftheopaquetype) + { + ResultId = resultId; + Thenameoftheopaquetype = thenameoftheopaquetype; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeOpaque, ResultId, ..Thenameoftheopaquetype.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "thenameoftheopaquetype": + Thenameoftheopaquetype = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeOpaque(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypePointer : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypePointer() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypePointer | (1 << 16); + } + + public OpTypePointer(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypePointer(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Type + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypePointer inst) => inst.ResultId; + public OpTypePointer(int resultId, StorageClass storageClass, int type) + { + ResultId = resultId; + StorageClass = storageClass; + Type = type; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypePointer, ResultId, (int)StorageClass, Type]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + case "type": + Type = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypePointer(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeFunction : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeFunction() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeFunction | (1 << 16); + } + + public OpTypeFunction(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeFunction(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReturnType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray ParameterTypes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeFunction inst) => inst.ResultId; + public OpTypeFunction(int resultId, int returnType, LiteralArray parameterTypes) + { + ResultId = resultId; + ReturnType = returnType; + ParameterTypes = parameterTypes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeFunction, ResultId, ReturnType, ..ParameterTypes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "returnType": + ReturnType = o.ToLiteral(); + break; + case "parameterTypes": + ParameterTypes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (ParameterTypes.WordCount == -1) + ParameterTypes = new(); + } + + public static implicit operator OpTypeFunction(OpDataIndex odi) => new(odi); + public void Dispose() + { + ParameterTypes.Dispose(); + } +} + +public ref partial struct OpTypeEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeEvent | (1 << 16); + } + + public OpTypeEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeEvent inst) => inst.ResultId; + public OpTypeEvent(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeEvent, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeDeviceEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeDeviceEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeDeviceEvent | (1 << 16); + } + + public OpTypeDeviceEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeDeviceEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeDeviceEvent inst) => inst.ResultId; + public OpTypeDeviceEvent(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeDeviceEvent, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeDeviceEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeReserveId : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeReserveId() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeReserveId | (1 << 16); + } + + public OpTypeReserveId(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeReserveId(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeReserveId inst) => inst.ResultId; + public OpTypeReserveId(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeReserveId, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeReserveId(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeQueue : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeQueue() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeQueue | (1 << 16); + } + + public OpTypeQueue(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeQueue(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeQueue inst) => inst.ResultId; + public OpTypeQueue(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeQueue, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeQueue(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypePipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypePipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypePipe | (1 << 16); + } + + public OpTypePipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypePipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public AccessQualifier Qualifier + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypePipe inst) => inst.ResultId; + public OpTypePipe(int resultId, AccessQualifier qualifier) + { + ResultId = resultId; + Qualifier = qualifier; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypePipe, ResultId, (int)Qualifier]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "qualifier": + Qualifier = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypePipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeForwardPointer : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeForwardPointer() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeForwardPointer | (1 << 16); + } + + public OpTypeForwardPointer(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeForwardPointer(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int PointerType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTypeForwardPointer(int pointerType, StorageClass storageClass) + { + PointerType = pointerType; + StorageClass = storageClass; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeForwardPointer, PointerType, (int)StorageClass]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointerType": + PointerType = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeForwardPointer(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantTrue : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantTrue() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantTrue | (1 << 16); + } + + public OpConstantTrue(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantTrue(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantTrue inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantTrue inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantTrue(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantTrue, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantTrue(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantFalse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantFalse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantFalse | (1 << 16); + } + + public OpConstantFalse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantFalse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantFalse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantFalse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantFalse(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantFalse, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantFalse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstant : IMemoryInstruction where T : struct, INumber +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstant() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstant | (1 << 16); + } + + public OpConstant(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstant(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public T Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstant inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstant inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstant(int resultType, int resultId, LiteralValue value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstant, ResultType, ResultId, ..Value.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstant(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantComposite : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantComposite() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantComposite | (1 << 16); + } + + public OpConstantComposite(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantComposite(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantComposite inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantComposite inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantComposite(int resultType, int resultId, LiteralArray constituents) + { + ResultType = resultType; + ResultId = resultId; + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantComposite, ResultType, ResultId, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpConstantComposite(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpConstantSampler : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantSampler() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantSampler | (1 << 16); + } + + public OpConstantSampler(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantSampler(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public SamplerAddressingMode SamplerAddressingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public SamplerFilterMode SamplerFilterMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantSampler inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantSampler inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantSampler(int resultType, int resultId, SamplerAddressingMode samplerAddressingMode, int param, SamplerFilterMode samplerFilterMode) + { + ResultType = resultType; + ResultId = resultId; + SamplerAddressingMode = samplerAddressingMode; + Param = param; + SamplerFilterMode = samplerFilterMode; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantSampler, ResultType, ResultId, (int)SamplerAddressingMode, ..Param.AsDisposableLiteralValue().Words, (int)SamplerFilterMode]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "samplerAddressingMode": + SamplerAddressingMode = o.ToEnum(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "samplerFilterMode": + SamplerFilterMode = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantSampler(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantNull : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantNull() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantNull | (1 << 16); + } + + public OpConstantNull(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantNull(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantNull inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantNull inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantNull(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantNull, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantNull(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstantTrue : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantTrue() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantTrue | (1 << 16); + } + + public OpSpecConstantTrue(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantTrue(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantTrue inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstantTrue inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstantTrue(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantTrue, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstantTrue(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstantFalse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantFalse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantFalse | (1 << 16); + } + + public OpSpecConstantFalse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantFalse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantFalse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstantFalse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstantFalse(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantFalse, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstantFalse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstant : IMemoryInstruction where T : struct, INumber +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstant() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstant | (1 << 16); + } + + public OpSpecConstant(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstant(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public T Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstant inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstant inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstant(int resultType, int resultId, LiteralValue value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstant, ResultType, ResultId, ..Value.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstant(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstantComposite : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantComposite() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantComposite | (1 << 16); + } + + public OpSpecConstantComposite(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantComposite(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantComposite inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstantComposite inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstantComposite(int resultType, int resultId, LiteralArray constituents) + { + ResultType = resultType; + ResultId = resultId; + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantComposite, ResultType, ResultId, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpSpecConstantComposite(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpSpecConstantOp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantOp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantOp | (1 << 16); + } + + public OpSpecConstantOp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantOp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Opcode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantOp inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstantOp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstantOp(int resultType, int resultId, int opcode) + { + ResultType = resultType; + ResultId = resultId; + Opcode = opcode; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantOp, ResultType, ResultId, ..Opcode.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "opcode": + Opcode = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstantOp(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFunction : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunction() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunction | (1 << 16); + } + + public OpFunction(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunction(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public FunctionControlMask FunctionControl + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FunctionType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFunction inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFunction inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFunction(int resultType, int resultId, FunctionControlMask functionControl, int functionType) + { + ResultType = resultType; + ResultId = resultId; + FunctionControl = functionControl; + FunctionType = functionType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunction, ResultType, ResultId, (int)FunctionControl, FunctionType]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "functionControl": + FunctionControl = o.ToEnum(); + break; + case "functionType": + FunctionType = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFunction(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFunctionParameter : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunctionParameter() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunctionParameter | (1 << 16); + } + + public OpFunctionParameter(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunctionParameter(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFunctionParameter inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFunctionParameter inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFunctionParameter(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunctionParameter, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFunctionParameter(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFunctionEnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunctionEnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunctionEnd | (1 << 16); + } + + public OpFunctionEnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunctionEnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunctionEnd]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFunctionEnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFunctionCall : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunctionCall() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunctionCall | (1 << 16); + } + + public OpFunctionCall(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunctionCall(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Function + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Arguments + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFunctionCall inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFunctionCall inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFunctionCall(int resultType, int resultId, int function, LiteralArray arguments) + { + ResultType = resultType; + ResultId = resultId; + Function = function; + Arguments = arguments; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunctionCall, ResultType, ResultId, Function, ..Arguments.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "function": + Function = o.ToLiteral(); + break; + case "arguments": + Arguments = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Arguments.WordCount == -1) + Arguments = new(); + } + + public static implicit operator OpFunctionCall(OpDataIndex odi) => new(odi); + public void Dispose() + { + Arguments.Dispose(); + } +} + +public ref partial struct OpVariable : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVariable() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVariable | (1 << 16); + } + + public OpVariable(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVariable(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Initializer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVariable inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVariable inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVariable(int resultType, int resultId, StorageClass storageClass, int? initializer) + { + ResultType = resultType; + ResultId = resultId; + StorageClass = storageClass; + Initializer = initializer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVariable, ResultType, ResultId, (int)StorageClass, ..(Initializer is null ? (Span)[] : [Initializer.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + case "initializer": + if (o.Words.Length > 0) + { + Initializer = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVariable(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageTexelPointer : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageTexelPointer() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageTexelPointer | (1 << 16); + } + + public OpImageTexelPointer(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageTexelPointer(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Sample + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageTexelPointer inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageTexelPointer inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageTexelPointer(int resultType, int resultId, int image, int coordinate, int sample) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + Sample = sample; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageTexelPointer, ResultType, ResultId, Image, Coordinate, Sample]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "sample": + Sample = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageTexelPointer(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLoad : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLoad() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLoad | (1 << 16); + } + + public OpLoad(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLoad(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public MemoryAccessMask? MemoryAccess { get; set; } + + public EnumerantParameters MemoryAccessParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLoad inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLoad inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLoad(int resultType, int resultId, int pointer, MemoryAccessMask? memoryAccess, EnumerantParameters memoryAccessParameters) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + MemoryAccess = memoryAccess; + MemoryAccessParameters = memoryAccessParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLoad, ResultType, ResultId, Pointer, ..(MemoryAccess is null ? (Span)[] : [(int)MemoryAccess.Value, ..MemoryAccessParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memoryAccess": + if (o.Words.Length > 0) + { + MemoryAccess = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + MemoryAccessParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLoad(OpDataIndex odi) => new(odi); + public void Dispose() + { + MemoryAccessParameters.Dispose(); + } +} + +public ref partial struct OpStore : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpStore() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpStore | (1 << 16); + } + + public OpStore(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpStore(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ObjectId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public MemoryAccessMask? MemoryAccess { get; set; } + + public EnumerantParameters MemoryAccessParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpStore(int pointer, int objectId, MemoryAccessMask? memoryAccess, EnumerantParameters memoryAccessParameters) + { + Pointer = pointer; + ObjectId = objectId; + MemoryAccess = memoryAccess; + MemoryAccessParameters = memoryAccessParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpStore, Pointer, ObjectId, ..(MemoryAccess is null ? (Span)[] : [(int)MemoryAccess.Value, ..MemoryAccessParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointer": + Pointer = o.ToLiteral(); + break; + case "objectId": + ObjectId = o.ToLiteral(); + break; + case "memoryAccess": + if (o.Words.Length > 0) + { + MemoryAccess = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + MemoryAccessParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpStore(OpDataIndex odi) => new(odi); + public void Dispose() + { + MemoryAccessParameters.Dispose(); + } +} + +public ref partial struct OpAccessChain : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAccessChain() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAccessChain | (1 << 16); + } + + public OpAccessChain(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAccessChain(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAccessChain inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAccessChain inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAccessChain(int resultType, int resultId, int baseId, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAccessChain, ResultType, ResultId, BaseId, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpAccessChain(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpInBoundsAccessChain : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpInBoundsAccessChain() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpInBoundsAccessChain | (1 << 16); + } + + public OpInBoundsAccessChain(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpInBoundsAccessChain(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpInBoundsAccessChain inst) => inst.ResultId; + public static implicit operator SpirvValue(OpInBoundsAccessChain inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpInBoundsAccessChain(int resultType, int resultId, int baseId, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpInBoundsAccessChain, ResultType, ResultId, BaseId, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpInBoundsAccessChain(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpPtrAccessChain : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrAccessChain() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrAccessChain | (1 << 16); + } + + public OpPtrAccessChain(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrAccessChain(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Element + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrAccessChain inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrAccessChain inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrAccessChain(int resultType, int resultId, int baseId, int element, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Element = element; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrAccessChain, ResultType, ResultId, BaseId, Element, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "element": + Element = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpPtrAccessChain(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpArrayLength : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArrayLength() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArrayLength | (1 << 16); + } + + public OpArrayLength(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArrayLength(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Structure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Arraymember + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArrayLength inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArrayLength inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArrayLength(int resultType, int resultId, int structure, int arraymember) + { + ResultType = resultType; + ResultId = resultId; + Structure = structure; + Arraymember = arraymember; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArrayLength, ResultType, ResultId, Structure, ..Arraymember.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "structure": + Structure = o.ToLiteral(); + break; + case "arraymember": + Arraymember = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArrayLength(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGenericPtrMemSemantics : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGenericPtrMemSemantics() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGenericPtrMemSemantics | (1 << 16); + } + + public OpGenericPtrMemSemantics(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGenericPtrMemSemantics(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGenericPtrMemSemantics inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGenericPtrMemSemantics inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGenericPtrMemSemantics(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGenericPtrMemSemantics, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGenericPtrMemSemantics(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpInBoundsPtrAccessChain : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpInBoundsPtrAccessChain() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpInBoundsPtrAccessChain | (1 << 16); + } + + public OpInBoundsPtrAccessChain(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpInBoundsPtrAccessChain(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Element + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpInBoundsPtrAccessChain inst) => inst.ResultId; + public static implicit operator SpirvValue(OpInBoundsPtrAccessChain inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpInBoundsPtrAccessChain(int resultType, int resultId, int baseId, int element, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Element = element; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpInBoundsPtrAccessChain, ResultType, ResultId, BaseId, Element, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "element": + Element = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpInBoundsPtrAccessChain(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpDecorate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDecorate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDecorate | (1 << 16); + } + + public OpDecorate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDecorate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Decoration Decoration { get; set; } + + public EnumerantParameters DecorationParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpDecorate(int target, Decoration decoration, EnumerantParameters decorationParameters) + { + Target = target; + Decoration = decoration; + DecorationParameters = decorationParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDecorate, Target, (int)Decoration, ..DecorationParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "target": + Target = o.ToLiteral(); + break; + case "decoration": + Decoration = o.ToEnum(); + DecorationParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDecorate(OpDataIndex odi) => new(odi); + public void Dispose() + { + DecorationParameters.Dispose(); + } +} + +public ref partial struct OpMemberDecorate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemberDecorate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemberDecorate | (1 << 16); + } + + public OpMemberDecorate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemberDecorate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int StructureType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Member + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Decoration Decoration { get; set; } + + public EnumerantParameters DecorationParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemberDecorate(int structureType, int member, Decoration decoration, EnumerantParameters decorationParameters) + { + StructureType = structureType; + Member = member; + Decoration = decoration; + DecorationParameters = decorationParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemberDecorate, StructureType, ..Member.AsDisposableLiteralValue().Words, (int)Decoration, ..DecorationParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "structureType": + StructureType = o.ToLiteral(); + break; + case "member": + Member = o.ToLiteral(); + break; + case "decoration": + Decoration = o.ToEnum(); + DecorationParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemberDecorate(OpDataIndex odi) => new(odi); + public void Dispose() + { + DecorationParameters.Dispose(); + } +} + +public ref partial struct OpDecorationGroup : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDecorationGroup() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDecorationGroup | (1 << 16); + } + + public OpDecorationGroup(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDecorationGroup(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDecorationGroup inst) => inst.ResultId; + public OpDecorationGroup(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDecorationGroup, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDecorationGroup(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupDecorate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupDecorate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupDecorate | (1 << 16); + } + + public OpGroupDecorate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupDecorate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int DecorationGroup + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Targets + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpGroupDecorate(int decorationGroup, LiteralArray targets) + { + DecorationGroup = decorationGroup; + Targets = targets; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupDecorate, DecorationGroup, ..Targets.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "decorationGroup": + DecorationGroup = o.ToLiteral(); + break; + case "targets": + Targets = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Targets.WordCount == -1) + Targets = new(); + } + + public static implicit operator OpGroupDecorate(OpDataIndex odi) => new(odi); + public void Dispose() + { + Targets.Dispose(); + } +} + +public ref partial struct OpGroupMemberDecorate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupMemberDecorate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupMemberDecorate | (1 << 16); + } + + public OpGroupMemberDecorate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupMemberDecorate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int DecorationGroup + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray<(int, int)> Targets + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpGroupMemberDecorate(int decorationGroup, LiteralArray<(int, int)> targets) + { + DecorationGroup = decorationGroup; + Targets = targets; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupMemberDecorate, DecorationGroup, ..Targets.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "decorationGroup": + DecorationGroup = o.ToLiteral(); + break; + case "targets": + Targets = o.ToLiteralArray<(int, int)>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Targets.WordCount == -1) + Targets = new(); + } + + public static implicit operator OpGroupMemberDecorate(OpDataIndex odi) => new(odi); + public void Dispose() + { + Targets.Dispose(); + } +} + +public ref partial struct OpVectorExtractDynamic : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVectorExtractDynamic() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVectorExtractDynamic | (1 << 16); + } + + public OpVectorExtractDynamic(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVectorExtractDynamic(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVectorExtractDynamic inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVectorExtractDynamic inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVectorExtractDynamic(int resultType, int resultId, int vector, int index) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + Index = index; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVectorExtractDynamic, ResultType, ResultId, Vector, Index]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVectorExtractDynamic(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVectorInsertDynamic : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVectorInsertDynamic() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVectorInsertDynamic | (1 << 16); + } + + public OpVectorInsertDynamic(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVectorInsertDynamic(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Component + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVectorInsertDynamic inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVectorInsertDynamic inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVectorInsertDynamic(int resultType, int resultId, int vector, int component, int index) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + Component = component; + Index = index; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVectorInsertDynamic, ResultType, ResultId, Vector, Component, Index]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + case "component": + Component = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVectorInsertDynamic(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVectorShuffle : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVectorShuffle() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVectorShuffle | (1 << 16); + } + + public OpVectorShuffle(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVectorShuffle(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Components + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVectorShuffle inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVectorShuffle inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVectorShuffle(int resultType, int resultId, int vector1, int vector2, LiteralArray components) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + Components = components; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVectorShuffle, ResultType, ResultId, Vector1, Vector2, ..Components.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "components": + Components = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Components.WordCount == -1) + Components = new(); + } + + public static implicit operator OpVectorShuffle(OpDataIndex odi) => new(odi); + public void Dispose() + { + Components.Dispose(); + } +} + +public ref partial struct OpCompositeConstruct : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositeConstruct() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositeConstruct | (1 << 16); + } + + public OpCompositeConstruct(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositeConstruct(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCompositeConstruct inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCompositeConstruct inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCompositeConstruct(int resultType, int resultId, LiteralArray constituents) + { + ResultType = resultType; + ResultId = resultId; + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositeConstruct, ResultType, ResultId, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpCompositeConstruct(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpCompositeExtract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositeExtract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositeExtract | (1 << 16); + } + + public OpCompositeExtract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositeExtract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Composite + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCompositeExtract inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCompositeExtract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCompositeExtract(int resultType, int resultId, int composite, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + Composite = composite; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositeExtract, ResultType, ResultId, Composite, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "composite": + Composite = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpCompositeExtract(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpCompositeInsert : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositeInsert() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositeInsert | (1 << 16); + } + + public OpCompositeInsert(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositeInsert(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ObjectId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Composite + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCompositeInsert inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCompositeInsert inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCompositeInsert(int resultType, int resultId, int objectId, int composite, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + ObjectId = objectId; + Composite = composite; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositeInsert, ResultType, ResultId, ObjectId, Composite, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "objectId": + ObjectId = o.ToLiteral(); + break; + case "composite": + Composite = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpCompositeInsert(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpCopyObject : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCopyObject() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCopyObject | (1 << 16); + } + + public OpCopyObject(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCopyObject(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCopyObject inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCopyObject inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCopyObject(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCopyObject, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCopyObject(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTranspose : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTranspose() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTranspose | (1 << 16); + } + + public OpTranspose(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTranspose(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTranspose inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTranspose inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTranspose(int resultType, int resultId, int matrix) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTranspose, ResultType, ResultId, Matrix]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTranspose(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSampledImage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSampledImage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSampledImage | (1 << 16); + } + + public OpSampledImage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSampledImage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Sampler + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSampledImage inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSampledImage inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSampledImage(int resultType, int resultId, int image, int sampler) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Sampler = sampler; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSampledImage, ResultType, ResultId, Image, Sampler]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "sampler": + Sampler = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSampledImage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageSampleImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleImplicitLod | (1 << 16); + } + + public OpImageSampleImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleImplicitLod, ResultType, ResultId, SampledImage, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleExplicitLod | (1 << 16); + } + + public OpImageSampleExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleExplicitLod, ResultType, ResultId, SampledImage, Coordinate, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleDrefImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleDrefImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleDrefImplicitLod | (1 << 16); + } + + public OpImageSampleDrefImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleDrefImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleDrefImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleDrefImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleDrefImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleDrefImplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleDrefImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleDrefExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleDrefExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleDrefExplicitLod | (1 << 16); + } + + public OpImageSampleDrefExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleDrefExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleDrefExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleDrefExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleDrefExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleDrefExplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleDrefExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleProjImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleProjImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleProjImplicitLod | (1 << 16); + } + + public OpImageSampleProjImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleProjImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleProjImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleProjImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleProjImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleProjImplicitLod, ResultType, ResultId, SampledImage, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleProjImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleProjExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleProjExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleProjExplicitLod | (1 << 16); + } + + public OpImageSampleProjExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleProjExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleProjExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleProjExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleProjExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleProjExplicitLod, ResultType, ResultId, SampledImage, Coordinate, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleProjExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleProjDrefImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleProjDrefImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleProjDrefImplicitLod | (1 << 16); + } + + public OpImageSampleProjDrefImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleProjDrefImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleProjDrefImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleProjDrefImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleProjDrefImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleProjDrefImplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleProjDrefImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSampleProjDrefExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleProjDrefExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleProjDrefExplicitLod | (1 << 16); + } + + public OpImageSampleProjDrefExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleProjDrefExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleProjDrefExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleProjDrefExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleProjDrefExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleProjDrefExplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleProjDrefExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageFetch : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageFetch() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageFetch | (1 << 16); + } + + public OpImageFetch(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageFetch(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageFetch inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageFetch inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageFetch(int resultType, int resultId, int image, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageFetch, ResultType, ResultId, Image, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageFetch(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageGather : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageGather() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageGather | (1 << 16); + } + + public OpImageGather(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageGather(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Component + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageGather inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageGather inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageGather(int resultType, int resultId, int sampledImage, int coordinate, int component, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Component = component; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageGather, ResultType, ResultId, SampledImage, Coordinate, Component, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "component": + Component = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageGather(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageDrefGather : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageDrefGather() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageDrefGather | (1 << 16); + } + + public OpImageDrefGather(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageDrefGather(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageDrefGather inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageDrefGather inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageDrefGather(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageDrefGather, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageDrefGather(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageRead : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageRead() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageRead | (1 << 16); + } + + public OpImageRead(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageRead(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageRead inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageRead inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageRead(int resultType, int resultId, int image, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageRead, ResultType, ResultId, Image, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageRead(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageWrite : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageWrite() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageWrite | (1 << 16); + } + + public OpImageWrite(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageWrite(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Texel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpImageWrite(int image, int coordinate, int texel, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + Image = image; + Coordinate = coordinate; + Texel = texel; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageWrite, Image, Coordinate, Texel, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "texel": + Texel = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageWrite(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImage | (1 << 16); + } + + public OpImage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImage inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImage inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImage(int resultType, int resultId, int sampledImage) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImage, ResultType, ResultId, SampledImage]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQueryFormat : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQueryFormat() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQueryFormat | (1 << 16); + } + + public OpImageQueryFormat(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQueryFormat(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQueryFormat inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQueryFormat inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQueryFormat(int resultType, int resultId, int image) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQueryFormat, ResultType, ResultId, Image]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQueryFormat(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQueryOrder : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQueryOrder() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQueryOrder | (1 << 16); + } + + public OpImageQueryOrder(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQueryOrder(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQueryOrder inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQueryOrder inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQueryOrder(int resultType, int resultId, int image) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQueryOrder, ResultType, ResultId, Image]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQueryOrder(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQuerySizeLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQuerySizeLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQuerySizeLod | (1 << 16); + } + + public OpImageQuerySizeLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQuerySizeLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LevelofDetail + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQuerySizeLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQuerySizeLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQuerySizeLod(int resultType, int resultId, int image, int levelofDetail) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + LevelofDetail = levelofDetail; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQuerySizeLod, ResultType, ResultId, Image, LevelofDetail]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "levelofDetail": + LevelofDetail = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQuerySizeLod(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQuerySize : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQuerySize() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQuerySize | (1 << 16); + } + + public OpImageQuerySize(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQuerySize(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQuerySize inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQuerySize inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQuerySize(int resultType, int resultId, int image) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQuerySize, ResultType, ResultId, Image]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQuerySize(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQueryLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQueryLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQueryLod | (1 << 16); + } + + public OpImageQueryLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQueryLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQueryLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQueryLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQueryLod(int resultType, int resultId, int sampledImage, int coordinate) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQueryLod, ResultType, ResultId, SampledImage, Coordinate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQueryLod(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQueryLevels : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQueryLevels() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQueryLevels | (1 << 16); + } + + public OpImageQueryLevels(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQueryLevels(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQueryLevels inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQueryLevels inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQueryLevels(int resultType, int resultId, int image) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQueryLevels, ResultType, ResultId, Image]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQueryLevels(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageQuerySamples : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageQuerySamples() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageQuerySamples | (1 << 16); + } + + public OpImageQuerySamples(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageQuerySamples(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageQuerySamples inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageQuerySamples inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageQuerySamples(int resultType, int resultId, int image) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageQuerySamples, ResultType, ResultId, Image]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageQuerySamples(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertFToU : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertFToU() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertFToU | (1 << 16); + } + + public OpConvertFToU(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertFToU(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FloatValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertFToU inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertFToU inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertFToU(int resultType, int resultId, int floatValue) + { + ResultType = resultType; + ResultId = resultId; + FloatValue = floatValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertFToU, ResultType, ResultId, FloatValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "floatValue": + FloatValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertFToU(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertFToS : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertFToS() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertFToS | (1 << 16); + } + + public OpConvertFToS(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertFToS(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FloatValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertFToS inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertFToS inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertFToS(int resultType, int resultId, int floatValue) + { + ResultType = resultType; + ResultId = resultId; + FloatValue = floatValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertFToS, ResultType, ResultId, FloatValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "floatValue": + FloatValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertFToS(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertSToF : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertSToF() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertSToF | (1 << 16); + } + + public OpConvertSToF(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertSToF(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertSToF inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertSToF inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertSToF(int resultType, int resultId, int signedValue) + { + ResultType = resultType; + ResultId = resultId; + SignedValue = signedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertSToF, ResultType, ResultId, SignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "signedValue": + SignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertSToF(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToF : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToF() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToF | (1 << 16); + } + + public OpConvertUToF(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToF(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UnsignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToF inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToF inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToF(int resultType, int resultId, int unsignedValue) + { + ResultType = resultType; + ResultId = resultId; + UnsignedValue = unsignedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToF, ResultType, ResultId, UnsignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "unsignedValue": + UnsignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToF(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUConvert : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUConvert() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUConvert | (1 << 16); + } + + public OpUConvert(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUConvert(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UnsignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUConvert inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUConvert inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUConvert(int resultType, int resultId, int unsignedValue) + { + ResultType = resultType; + ResultId = resultId; + UnsignedValue = unsignedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUConvert, ResultType, ResultId, UnsignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "unsignedValue": + UnsignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUConvert(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSConvert : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSConvert() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSConvert | (1 << 16); + } + + public OpSConvert(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSConvert(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSConvert inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSConvert inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSConvert(int resultType, int resultId, int signedValue) + { + ResultType = resultType; + ResultId = resultId; + SignedValue = signedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSConvert, ResultType, ResultId, SignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "signedValue": + SignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSConvert(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFConvert : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFConvert() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFConvert | (1 << 16); + } + + public OpFConvert(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFConvert(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FloatValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFConvert inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFConvert inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFConvert(int resultType, int resultId, int floatValue) + { + ResultType = resultType; + ResultId = resultId; + FloatValue = floatValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFConvert, ResultType, ResultId, FloatValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "floatValue": + FloatValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFConvert(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpQuantizeToF16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpQuantizeToF16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpQuantizeToF16 | (1 << 16); + } + + public OpQuantizeToF16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpQuantizeToF16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpQuantizeToF16 inst) => inst.ResultId; + public static implicit operator SpirvValue(OpQuantizeToF16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpQuantizeToF16(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpQuantizeToF16, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpQuantizeToF16(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertPtrToU : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertPtrToU() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertPtrToU | (1 << 16); + } + + public OpConvertPtrToU(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertPtrToU(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertPtrToU inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertPtrToU inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertPtrToU(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertPtrToU, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertPtrToU(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSatConvertSToU : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSatConvertSToU() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSatConvertSToU | (1 << 16); + } + + public OpSatConvertSToU(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSatConvertSToU(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSatConvertSToU inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSatConvertSToU inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSatConvertSToU(int resultType, int resultId, int signedValue) + { + ResultType = resultType; + ResultId = resultId; + SignedValue = signedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSatConvertSToU, ResultType, ResultId, SignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "signedValue": + SignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSatConvertSToU(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSatConvertUToS : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSatConvertUToS() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSatConvertUToS | (1 << 16); + } + + public OpSatConvertUToS(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSatConvertUToS(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UnsignedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSatConvertUToS inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSatConvertUToS inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSatConvertUToS(int resultType, int resultId, int unsignedValue) + { + ResultType = resultType; + ResultId = resultId; + UnsignedValue = unsignedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSatConvertUToS, ResultType, ResultId, UnsignedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "unsignedValue": + UnsignedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSatConvertUToS(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToPtr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToPtr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToPtr | (1 << 16); + } + + public OpConvertUToPtr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToPtr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int IntegerValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToPtr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToPtr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToPtr(int resultType, int resultId, int integerValue) + { + ResultType = resultType; + ResultId = resultId; + IntegerValue = integerValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToPtr, ResultType, ResultId, IntegerValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "integerValue": + IntegerValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToPtr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPtrCastToGeneric : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrCastToGeneric() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrCastToGeneric | (1 << 16); + } + + public OpPtrCastToGeneric(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrCastToGeneric(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrCastToGeneric inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrCastToGeneric inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrCastToGeneric(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrCastToGeneric, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpPtrCastToGeneric(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGenericCastToPtr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGenericCastToPtr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGenericCastToPtr | (1 << 16); + } + + public OpGenericCastToPtr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGenericCastToPtr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGenericCastToPtr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGenericCastToPtr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGenericCastToPtr(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGenericCastToPtr, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGenericCastToPtr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGenericCastToPtrExplicit : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGenericCastToPtrExplicit() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGenericCastToPtrExplicit | (1 << 16); + } + + public OpGenericCastToPtrExplicit(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGenericCastToPtrExplicit(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass Storage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGenericCastToPtrExplicit inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGenericCastToPtrExplicit inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGenericCastToPtrExplicit(int resultType, int resultId, int pointer, StorageClass storage) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Storage = storage; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGenericCastToPtrExplicit, ResultType, ResultId, Pointer, (int)Storage]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "storage": + Storage = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGenericCastToPtrExplicit(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitcast : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitcast() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitcast | (1 << 16); + } + + public OpBitcast(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitcast(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitcast inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitcast inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitcast(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitcast, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitcast(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSNegate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSNegate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSNegate | (1 << 16); + } + + public OpSNegate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSNegate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSNegate inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSNegate inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSNegate(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSNegate, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSNegate(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFNegate : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFNegate() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFNegate | (1 << 16); + } + + public OpFNegate(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFNegate(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFNegate inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFNegate inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFNegate(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFNegate, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFNegate(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIAdd | (1 << 16); + } + + public OpIAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIAdd(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIAdd, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFAdd | (1 << 16); + } + + public OpFAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFAdd(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFAdd, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpISub : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpISub() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpISub | (1 << 16); + } + + public OpISub(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpISub(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpISub inst) => inst.ResultId; + public static implicit operator SpirvValue(OpISub inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpISub(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpISub, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpISub(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFSub : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFSub() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFSub | (1 << 16); + } + + public OpFSub(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFSub(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFSub inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFSub inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFSub(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFSub, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFSub(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIMul : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIMul() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIMul | (1 << 16); + } + + public OpIMul(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIMul(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIMul inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIMul inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIMul(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIMul, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIMul(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFMul : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFMul() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFMul | (1 << 16); + } + + public OpFMul(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFMul(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFMul inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFMul inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFMul(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFMul, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFMul(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUDiv : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUDiv() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUDiv | (1 << 16); + } + + public OpUDiv(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUDiv(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUDiv inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUDiv inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUDiv(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUDiv, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUDiv(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSDiv : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSDiv() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSDiv | (1 << 16); + } + + public OpSDiv(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSDiv(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSDiv inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSDiv inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSDiv(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSDiv, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSDiv(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFDiv : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFDiv() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFDiv | (1 << 16); + } + + public OpFDiv(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFDiv(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFDiv inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFDiv inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFDiv(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFDiv, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFDiv(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUMod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUMod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUMod | (1 << 16); + } + + public OpUMod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUMod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUMod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUMod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUMod(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUMod, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUMod(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSRem : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSRem() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSRem | (1 << 16); + } + + public OpSRem(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSRem(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSRem inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSRem inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSRem(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSRem, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSRem(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSMod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSMod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSMod | (1 << 16); + } + + public OpSMod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSMod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSMod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSMod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSMod(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSMod, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSMod(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFRem : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFRem() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFRem | (1 << 16); + } + + public OpFRem(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFRem(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFRem inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFRem inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFRem(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFRem, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFRem(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFMod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFMod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFMod | (1 << 16); + } + + public OpFMod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFMod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFMod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFMod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFMod(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFMod, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFMod(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVectorTimesScalar : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVectorTimesScalar() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVectorTimesScalar | (1 << 16); + } + + public OpVectorTimesScalar(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVectorTimesScalar(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Scalar + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVectorTimesScalar inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVectorTimesScalar inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVectorTimesScalar(int resultType, int resultId, int vector, int scalar) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + Scalar = scalar; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVectorTimesScalar, ResultType, ResultId, Vector, Scalar]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + case "scalar": + Scalar = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVectorTimesScalar(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMatrixTimesScalar : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMatrixTimesScalar() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMatrixTimesScalar | (1 << 16); + } + + public OpMatrixTimesScalar(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMatrixTimesScalar(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Scalar + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpMatrixTimesScalar inst) => inst.ResultId; + public static implicit operator SpirvValue(OpMatrixTimesScalar inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpMatrixTimesScalar(int resultType, int resultId, int matrix, int scalar) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + Scalar = scalar; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMatrixTimesScalar, ResultType, ResultId, Matrix, Scalar]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + case "scalar": + Scalar = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMatrixTimesScalar(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVectorTimesMatrix : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVectorTimesMatrix() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVectorTimesMatrix | (1 << 16); + } + + public OpVectorTimesMatrix(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVectorTimesMatrix(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVectorTimesMatrix inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVectorTimesMatrix inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVectorTimesMatrix(int resultType, int resultId, int vector, int matrix) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + Matrix = matrix; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVectorTimesMatrix, ResultType, ResultId, Vector, Matrix]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVectorTimesMatrix(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMatrixTimesVector : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMatrixTimesVector() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMatrixTimesVector | (1 << 16); + } + + public OpMatrixTimesVector(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMatrixTimesVector(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpMatrixTimesVector inst) => inst.ResultId; + public static implicit operator SpirvValue(OpMatrixTimesVector inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpMatrixTimesVector(int resultType, int resultId, int matrix, int vector) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + Vector = vector; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMatrixTimesVector, ResultType, ResultId, Matrix, Vector]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMatrixTimesVector(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMatrixTimesMatrix : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMatrixTimesMatrix() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMatrixTimesMatrix | (1 << 16); + } + + public OpMatrixTimesMatrix(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMatrixTimesMatrix(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LeftMatrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RightMatrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpMatrixTimesMatrix inst) => inst.ResultId; + public static implicit operator SpirvValue(OpMatrixTimesMatrix inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpMatrixTimesMatrix(int resultType, int resultId, int leftMatrix, int rightMatrix) + { + ResultType = resultType; + ResultId = resultId; + LeftMatrix = leftMatrix; + RightMatrix = rightMatrix; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMatrixTimesMatrix, ResultType, ResultId, LeftMatrix, RightMatrix]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "leftMatrix": + LeftMatrix = o.ToLiteral(); + break; + case "rightMatrix": + RightMatrix = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMatrixTimesMatrix(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpOuterProduct : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpOuterProduct() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpOuterProduct | (1 << 16); + } + + public OpOuterProduct(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpOuterProduct(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpOuterProduct inst) => inst.ResultId; + public static implicit operator SpirvValue(OpOuterProduct inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpOuterProduct(int resultType, int resultId, int vector1, int vector2) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpOuterProduct, ResultType, ResultId, Vector1, Vector2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpOuterProduct(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDot | (1 << 16); + } + + public OpDot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDot(int resultType, int resultId, int vector1, int vector2) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDot, ResultType, ResultId, Vector1, Vector2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIAddCarry : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIAddCarry() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIAddCarry | (1 << 16); + } + + public OpIAddCarry(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIAddCarry(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIAddCarry inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIAddCarry inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIAddCarry(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIAddCarry, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIAddCarry(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpISubBorrow : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpISubBorrow() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpISubBorrow | (1 << 16); + } + + public OpISubBorrow(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpISubBorrow(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpISubBorrow inst) => inst.ResultId; + public static implicit operator SpirvValue(OpISubBorrow inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpISubBorrow(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpISubBorrow, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpISubBorrow(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUMulExtended : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUMulExtended() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUMulExtended | (1 << 16); + } + + public OpUMulExtended(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUMulExtended(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUMulExtended inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUMulExtended inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUMulExtended(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUMulExtended, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUMulExtended(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSMulExtended : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSMulExtended() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSMulExtended | (1 << 16); + } + + public OpSMulExtended(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSMulExtended(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSMulExtended inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSMulExtended inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSMulExtended(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSMulExtended, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSMulExtended(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAny : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAny() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAny | (1 << 16); + } + + public OpAny(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAny(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAny inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAny inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAny(int resultType, int resultId, int vector) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAny, ResultType, ResultId, Vector]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAny(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAll : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAll() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAll | (1 << 16); + } + + public OpAll(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAll(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAll inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAll inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAll(int resultType, int resultId, int vector) + { + ResultType = resultType; + ResultId = resultId; + Vector = vector; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAll, ResultType, ResultId, Vector]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector": + Vector = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAll(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsNan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsNan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsNan | (1 << 16); + } + + public OpIsNan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsNan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsNan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsNan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsNan(int resultType, int resultId, int x) + { + ResultType = resultType; + ResultId = resultId; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsNan, ResultType, ResultId, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsNan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsInf : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsInf() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsInf | (1 << 16); + } + + public OpIsInf(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsInf(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsInf inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsInf inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsInf(int resultType, int resultId, int x) + { + ResultType = resultType; + ResultId = resultId; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsInf, ResultType, ResultId, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsInf(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsFinite : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsFinite() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsFinite | (1 << 16); + } + + public OpIsFinite(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsFinite(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsFinite inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsFinite inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsFinite(int resultType, int resultId, int x) + { + ResultType = resultType; + ResultId = resultId; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsFinite, ResultType, ResultId, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsFinite(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsNormal : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsNormal() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsNormal | (1 << 16); + } + + public OpIsNormal(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsNormal(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsNormal inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsNormal inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsNormal(int resultType, int resultId, int x) + { + ResultType = resultType; + ResultId = resultId; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsNormal, ResultType, ResultId, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsNormal(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSignBitSet : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSignBitSet() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSignBitSet | (1 << 16); + } + + public OpSignBitSet(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSignBitSet(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSignBitSet inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSignBitSet inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSignBitSet(int resultType, int resultId, int x) + { + ResultType = resultType; + ResultId = resultId; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSignBitSet, ResultType, ResultId, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSignBitSet(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLessOrGreater : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLessOrGreater() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLessOrGreater | (1 << 16); + } + + public OpLessOrGreater(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLessOrGreater(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLessOrGreater inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLessOrGreater inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLessOrGreater(int resultType, int resultId, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLessOrGreater, ResultType, ResultId, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLessOrGreater(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpOrdered : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpOrdered() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpOrdered | (1 << 16); + } + + public OpOrdered(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpOrdered(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpOrdered inst) => inst.ResultId; + public static implicit operator SpirvValue(OpOrdered inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpOrdered(int resultType, int resultId, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpOrdered, ResultType, ResultId, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpOrdered(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUnordered : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUnordered() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUnordered | (1 << 16); + } + + public OpUnordered(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUnordered(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUnordered inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUnordered inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUnordered(int resultType, int resultId, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUnordered, ResultType, ResultId, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUnordered(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLogicalEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLogicalEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLogicalEqual | (1 << 16); + } + + public OpLogicalEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLogicalEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLogicalEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLogicalEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLogicalEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLogicalEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLogicalEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLogicalNotEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLogicalNotEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLogicalNotEqual | (1 << 16); + } + + public OpLogicalNotEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLogicalNotEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLogicalNotEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLogicalNotEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLogicalNotEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLogicalNotEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLogicalNotEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLogicalOr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLogicalOr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLogicalOr | (1 << 16); + } + + public OpLogicalOr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLogicalOr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLogicalOr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLogicalOr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLogicalOr(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLogicalOr, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLogicalOr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLogicalAnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLogicalAnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLogicalAnd | (1 << 16); + } + + public OpLogicalAnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLogicalAnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLogicalAnd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLogicalAnd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLogicalAnd(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLogicalAnd, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLogicalAnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLogicalNot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLogicalNot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLogicalNot | (1 << 16); + } + + public OpLogicalNot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLogicalNot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLogicalNot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpLogicalNot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpLogicalNot(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLogicalNot, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLogicalNot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSelect : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSelect() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSelect | (1 << 16); + } + + public OpSelect(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSelect(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Condition + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Object1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Object2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSelect inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSelect inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSelect(int resultType, int resultId, int condition, int object1, int object2) + { + ResultType = resultType; + ResultId = resultId; + Condition = condition; + Object1 = object1; + Object2 = object2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSelect, ResultType, ResultId, Condition, Object1, Object2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "condition": + Condition = o.ToLiteral(); + break; + case "object1": + Object1 = o.ToLiteral(); + break; + case "object2": + Object2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSelect(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIEqual | (1 << 16); + } + + public OpIEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpINotEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpINotEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpINotEqual | (1 << 16); + } + + public OpINotEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpINotEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpINotEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpINotEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpINotEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpINotEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpINotEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUGreaterThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUGreaterThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUGreaterThan | (1 << 16); + } + + public OpUGreaterThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUGreaterThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUGreaterThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUGreaterThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUGreaterThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUGreaterThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUGreaterThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSGreaterThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSGreaterThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSGreaterThan | (1 << 16); + } + + public OpSGreaterThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSGreaterThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSGreaterThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSGreaterThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSGreaterThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSGreaterThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSGreaterThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUGreaterThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUGreaterThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUGreaterThanEqual | (1 << 16); + } + + public OpUGreaterThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUGreaterThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUGreaterThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUGreaterThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUGreaterThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUGreaterThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUGreaterThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSGreaterThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSGreaterThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSGreaterThanEqual | (1 << 16); + } + + public OpSGreaterThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSGreaterThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSGreaterThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSGreaterThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSGreaterThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSGreaterThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSGreaterThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpULessThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpULessThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpULessThan | (1 << 16); + } + + public OpULessThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpULessThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpULessThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpULessThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpULessThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpULessThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpULessThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSLessThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSLessThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSLessThan | (1 << 16); + } + + public OpSLessThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSLessThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSLessThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSLessThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSLessThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSLessThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSLessThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpULessThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpULessThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpULessThanEqual | (1 << 16); + } + + public OpULessThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpULessThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpULessThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpULessThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpULessThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpULessThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpULessThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSLessThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSLessThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSLessThanEqual | (1 << 16); + } + + public OpSLessThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSLessThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSLessThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSLessThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSLessThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSLessThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSLessThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdEqual | (1 << 16); + } + + public OpFOrdEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordEqual | (1 << 16); + } + + public OpFUnordEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdNotEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdNotEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdNotEqual | (1 << 16); + } + + public OpFOrdNotEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdNotEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdNotEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdNotEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdNotEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdNotEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdNotEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordNotEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordNotEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordNotEqual | (1 << 16); + } + + public OpFUnordNotEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordNotEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordNotEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordNotEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordNotEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordNotEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordNotEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdLessThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdLessThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdLessThan | (1 << 16); + } + + public OpFOrdLessThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdLessThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdLessThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdLessThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdLessThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdLessThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdLessThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordLessThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordLessThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordLessThan | (1 << 16); + } + + public OpFUnordLessThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordLessThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordLessThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordLessThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordLessThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordLessThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordLessThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdGreaterThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdGreaterThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdGreaterThan | (1 << 16); + } + + public OpFOrdGreaterThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdGreaterThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdGreaterThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdGreaterThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdGreaterThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdGreaterThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdGreaterThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordGreaterThan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordGreaterThan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordGreaterThan | (1 << 16); + } + + public OpFUnordGreaterThan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordGreaterThan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordGreaterThan inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordGreaterThan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordGreaterThan(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordGreaterThan, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordGreaterThan(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdLessThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdLessThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdLessThanEqual | (1 << 16); + } + + public OpFOrdLessThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdLessThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdLessThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdLessThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdLessThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdLessThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdLessThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordLessThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordLessThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordLessThanEqual | (1 << 16); + } + + public OpFUnordLessThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordLessThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordLessThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordLessThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordLessThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordLessThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordLessThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFOrdGreaterThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFOrdGreaterThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFOrdGreaterThanEqual | (1 << 16); + } + + public OpFOrdGreaterThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFOrdGreaterThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFOrdGreaterThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFOrdGreaterThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFOrdGreaterThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFOrdGreaterThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFOrdGreaterThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFUnordGreaterThanEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFUnordGreaterThanEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFUnordGreaterThanEqual | (1 << 16); + } + + public OpFUnordGreaterThanEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFUnordGreaterThanEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFUnordGreaterThanEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFUnordGreaterThanEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFUnordGreaterThanEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFUnordGreaterThanEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFUnordGreaterThanEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpShiftRightLogical : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpShiftRightLogical() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpShiftRightLogical | (1 << 16); + } + + public OpShiftRightLogical(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpShiftRightLogical(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shift + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpShiftRightLogical inst) => inst.ResultId; + public static implicit operator SpirvValue(OpShiftRightLogical inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpShiftRightLogical(int resultType, int resultId, int baseId, int shift) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Shift = shift; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpShiftRightLogical, ResultType, ResultId, BaseId, Shift]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "shift": + Shift = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpShiftRightLogical(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpShiftRightArithmetic : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpShiftRightArithmetic() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpShiftRightArithmetic | (1 << 16); + } + + public OpShiftRightArithmetic(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpShiftRightArithmetic(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shift + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpShiftRightArithmetic inst) => inst.ResultId; + public static implicit operator SpirvValue(OpShiftRightArithmetic inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpShiftRightArithmetic(int resultType, int resultId, int baseId, int shift) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Shift = shift; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpShiftRightArithmetic, ResultType, ResultId, BaseId, Shift]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "shift": + Shift = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpShiftRightArithmetic(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpShiftLeftLogical : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpShiftLeftLogical() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpShiftLeftLogical | (1 << 16); + } + + public OpShiftLeftLogical(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpShiftLeftLogical(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shift + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpShiftLeftLogical inst) => inst.ResultId; + public static implicit operator SpirvValue(OpShiftLeftLogical inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpShiftLeftLogical(int resultType, int resultId, int baseId, int shift) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Shift = shift; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpShiftLeftLogical, ResultType, ResultId, BaseId, Shift]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "shift": + Shift = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpShiftLeftLogical(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitwiseOr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitwiseOr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitwiseOr | (1 << 16); + } + + public OpBitwiseOr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitwiseOr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitwiseOr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitwiseOr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitwiseOr(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitwiseOr, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitwiseOr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitwiseXor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitwiseXor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitwiseXor | (1 << 16); + } + + public OpBitwiseXor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitwiseXor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitwiseXor inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitwiseXor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitwiseXor(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitwiseXor, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitwiseXor(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitwiseAnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitwiseAnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitwiseAnd | (1 << 16); + } + + public OpBitwiseAnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitwiseAnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitwiseAnd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitwiseAnd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitwiseAnd(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitwiseAnd, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitwiseAnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpNot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpNot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpNot | (1 << 16); + } + + public OpNot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpNot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpNot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpNot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpNot(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpNot, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpNot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitFieldInsert : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitFieldInsert() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitFieldInsert | (1 << 16); + } + + public OpBitFieldInsert(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitFieldInsert(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Insert + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Offset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Count + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitFieldInsert inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitFieldInsert inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitFieldInsert(int resultType, int resultId, int baseId, int insert, int offset, int count) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Insert = insert; + Offset = offset; + Count = count; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitFieldInsert, ResultType, ResultId, BaseId, Insert, Offset, Count]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "insert": + Insert = o.ToLiteral(); + break; + case "offset": + Offset = o.ToLiteral(); + break; + case "count": + Count = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitFieldInsert(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitFieldSExtract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitFieldSExtract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitFieldSExtract | (1 << 16); + } + + public OpBitFieldSExtract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitFieldSExtract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Offset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Count + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitFieldSExtract inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitFieldSExtract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitFieldSExtract(int resultType, int resultId, int baseId, int offset, int count) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Offset = offset; + Count = count; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitFieldSExtract, ResultType, ResultId, BaseId, Offset, Count]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "offset": + Offset = o.ToLiteral(); + break; + case "count": + Count = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitFieldSExtract(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitFieldUExtract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitFieldUExtract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitFieldUExtract | (1 << 16); + } + + public OpBitFieldUExtract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitFieldUExtract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Offset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Count + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitFieldUExtract inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitFieldUExtract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitFieldUExtract(int resultType, int resultId, int baseId, int offset, int count) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Offset = offset; + Count = count; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitFieldUExtract, ResultType, ResultId, BaseId, Offset, Count]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "offset": + Offset = o.ToLiteral(); + break; + case "count": + Count = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitFieldUExtract(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitReverse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitReverse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitReverse | (1 << 16); + } + + public OpBitReverse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitReverse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitReverse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitReverse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitReverse(int resultType, int resultId, int baseId) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitReverse, ResultType, ResultId, BaseId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitReverse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBitCount : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBitCount() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBitCount | (1 << 16); + } + + public OpBitCount(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBitCount(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBitCount inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBitCount inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBitCount(int resultType, int resultId, int baseId) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBitCount, ResultType, ResultId, BaseId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBitCount(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdx : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdx() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdx | (1 << 16); + } + + public OpDPdx(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdx(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdx inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdx inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdx(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdx, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdx(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdy : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdy() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdy | (1 << 16); + } + + public OpDPdy(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdy(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdy inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdy inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdy(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdy, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdy(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFwidth : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFwidth() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFwidth | (1 << 16); + } + + public OpFwidth(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFwidth(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFwidth inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFwidth inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFwidth(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFwidth, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFwidth(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdxFine : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdxFine() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdxFine | (1 << 16); + } + + public OpDPdxFine(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdxFine(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdxFine inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdxFine inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdxFine(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdxFine, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdxFine(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdyFine : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdyFine() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdyFine | (1 << 16); + } + + public OpDPdyFine(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdyFine(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdyFine inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdyFine inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdyFine(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdyFine, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdyFine(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFwidthFine : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFwidthFine() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFwidthFine | (1 << 16); + } + + public OpFwidthFine(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFwidthFine(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFwidthFine inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFwidthFine inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFwidthFine(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFwidthFine, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFwidthFine(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdxCoarse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdxCoarse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdxCoarse | (1 << 16); + } + + public OpDPdxCoarse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdxCoarse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdxCoarse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdxCoarse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdxCoarse(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdxCoarse, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdxCoarse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDPdyCoarse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDPdyCoarse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDPdyCoarse | (1 << 16); + } + + public OpDPdyCoarse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDPdyCoarse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDPdyCoarse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDPdyCoarse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDPdyCoarse(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDPdyCoarse, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDPdyCoarse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFwidthCoarse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFwidthCoarse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFwidthCoarse | (1 << 16); + } + + public OpFwidthCoarse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFwidthCoarse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFwidthCoarse inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFwidthCoarse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFwidthCoarse(int resultType, int resultId, int p) + { + ResultType = resultType; + ResultId = resultId; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFwidthCoarse, ResultType, ResultId, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFwidthCoarse(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEmitVertex : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEmitVertex() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEmitVertex | (1 << 16); + } + + public OpEmitVertex(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEmitVertex(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEmitVertex]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEmitVertex(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEndPrimitive : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEndPrimitive() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEndPrimitive | (1 << 16); + } + + public OpEndPrimitive(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEndPrimitive(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEndPrimitive]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEndPrimitive(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEmitStreamVertex : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEmitStreamVertex() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEmitStreamVertex | (1 << 16); + } + + public OpEmitStreamVertex(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEmitStreamVertex(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Stream + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEmitStreamVertex(int stream) + { + Stream = stream; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEmitStreamVertex, Stream]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "stream": + Stream = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEmitStreamVertex(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEndStreamPrimitive : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEndStreamPrimitive() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEndStreamPrimitive | (1 << 16); + } + + public OpEndStreamPrimitive(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEndStreamPrimitive(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Stream + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEndStreamPrimitive(int stream) + { + Stream = stream; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEndStreamPrimitive, Stream]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "stream": + Stream = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEndStreamPrimitive(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpControlBarrier : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpControlBarrier() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpControlBarrier | (1 << 16); + } + + public OpControlBarrier(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpControlBarrier(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpControlBarrier(int execution, int memory, int semantics) + { + Execution = execution; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpControlBarrier, Execution, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpControlBarrier(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMemoryBarrier : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemoryBarrier() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemoryBarrier | (1 << 16); + } + + public OpMemoryBarrier(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemoryBarrier(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemoryBarrier(int memory, int semantics) + { + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemoryBarrier, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemoryBarrier(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicLoad : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicLoad() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicLoad | (1 << 16); + } + + public OpAtomicLoad(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicLoad(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicLoad inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicLoad inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicLoad(int resultType, int resultId, int pointer, int memory, int semantics) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicLoad, ResultType, ResultId, Pointer, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicLoad(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicStore : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicStore() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicStore | (1 << 16); + } + + public OpAtomicStore(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicStore(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpAtomicStore(int pointer, int memory, int semantics, int value) + { + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicStore, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicStore(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicExchange : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicExchange() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicExchange | (1 << 16); + } + + public OpAtomicExchange(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicExchange(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicExchange inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicExchange inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicExchange(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicExchange, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicExchange(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicCompareExchange : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicCompareExchange() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicCompareExchange | (1 << 16); + } + + public OpAtomicCompareExchange(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicCompareExchange(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Equal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Unequal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Comparator + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicCompareExchange inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicCompareExchange inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicCompareExchange(int resultType, int resultId, int pointer, int memory, int equal, int unequal, int value, int comparator) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Equal = equal; + Unequal = unequal; + Value = value; + Comparator = comparator; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicCompareExchange, ResultType, ResultId, Pointer, Memory, Equal, Unequal, Value, Comparator]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "equal": + Equal = o.ToLiteral(); + break; + case "unequal": + Unequal = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "comparator": + Comparator = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicCompareExchange(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicCompareExchangeWeak : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicCompareExchangeWeak() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicCompareExchangeWeak | (1 << 16); + } + + public OpAtomicCompareExchangeWeak(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicCompareExchangeWeak(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Equal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Unequal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Comparator + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicCompareExchangeWeak inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicCompareExchangeWeak inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicCompareExchangeWeak(int resultType, int resultId, int pointer, int memory, int equal, int unequal, int value, int comparator) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Equal = equal; + Unequal = unequal; + Value = value; + Comparator = comparator; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicCompareExchangeWeak, ResultType, ResultId, Pointer, Memory, Equal, Unequal, Value, Comparator]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "equal": + Equal = o.ToLiteral(); + break; + case "unequal": + Unequal = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "comparator": + Comparator = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicCompareExchangeWeak(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicIIncrement : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicIIncrement() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicIIncrement | (1 << 16); + } + + public OpAtomicIIncrement(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicIIncrement(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicIIncrement inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicIIncrement inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicIIncrement(int resultType, int resultId, int pointer, int memory, int semantics) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicIIncrement, ResultType, ResultId, Pointer, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicIIncrement(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicIDecrement : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicIDecrement() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicIDecrement | (1 << 16); + } + + public OpAtomicIDecrement(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicIDecrement(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicIDecrement inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicIDecrement inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicIDecrement(int resultType, int resultId, int pointer, int memory, int semantics) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicIDecrement, ResultType, ResultId, Pointer, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicIDecrement(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicIAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicIAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicIAdd | (1 << 16); + } + + public OpAtomicIAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicIAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicIAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicIAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicIAdd(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicIAdd, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicIAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicISub : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicISub() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicISub | (1 << 16); + } + + public OpAtomicISub(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicISub(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicISub inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicISub inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicISub(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicISub, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicISub(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicSMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicSMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicSMin | (1 << 16); + } + + public OpAtomicSMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicSMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicSMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicSMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicSMin(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicSMin, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicSMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicUMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicUMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicUMin | (1 << 16); + } + + public OpAtomicUMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicUMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicUMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicUMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicUMin(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicUMin, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicUMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicSMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicSMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicSMax | (1 << 16); + } + + public OpAtomicSMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicSMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicSMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicSMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicSMax(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicSMax, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicSMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicUMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicUMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicUMax | (1 << 16); + } + + public OpAtomicUMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicUMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicUMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicUMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicUMax(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicUMax, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicUMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicAnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicAnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicAnd | (1 << 16); + } + + public OpAtomicAnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicAnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicAnd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicAnd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicAnd(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicAnd, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicAnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicOr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicOr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicOr | (1 << 16); + } + + public OpAtomicOr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicOr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicOr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicOr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicOr(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicOr, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicOr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicXor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicXor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicXor | (1 << 16); + } + + public OpAtomicXor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicXor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicXor inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicXor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicXor(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicXor, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicXor(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPhi : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPhi() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPhi | (1 << 16); + } + + public OpPhi(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPhi(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray<(int, int)> Variables + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPhi inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPhi inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPhi(int resultType, int resultId, LiteralArray<(int, int)> variables) + { + ResultType = resultType; + ResultId = resultId; + Variables = variables; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPhi, ResultType, ResultId, ..Variables.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "variables": + Variables = o.ToLiteralArray<(int, int)>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Variables.WordCount == -1) + Variables = new(); + } + + public static implicit operator OpPhi(OpDataIndex odi) => new(odi); + public void Dispose() + { + Variables.Dispose(); + } +} + +public ref partial struct OpLoopMerge : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLoopMerge() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLoopMerge | (1 << 16); + } + + public OpLoopMerge(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLoopMerge(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int MergeBlock + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ContinueTarget + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LoopControlMask LoopControl { get; set; } + + public EnumerantParameters LoopControlParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpLoopMerge(int mergeBlock, int continueTarget, LoopControlMask loopControl, EnumerantParameters loopControlParameters) + { + MergeBlock = mergeBlock; + ContinueTarget = continueTarget; + LoopControl = loopControl; + LoopControlParameters = loopControlParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLoopMerge, MergeBlock, ContinueTarget, (int)LoopControl, ..LoopControlParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "mergeBlock": + MergeBlock = o.ToLiteral(); + break; + case "continueTarget": + ContinueTarget = o.ToLiteral(); + break; + case "loopControl": + LoopControl = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + LoopControlParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLoopMerge(OpDataIndex odi) => new(odi); + public void Dispose() + { + LoopControlParameters.Dispose(); + } +} + +public ref partial struct OpSelectionMerge : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSelectionMerge() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSelectionMerge | (1 << 16); + } + + public OpSelectionMerge(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSelectionMerge(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int MergeBlock + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public SelectionControlMask SelectionControl + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSelectionMerge(int mergeBlock, SelectionControlMask selectionControl) + { + MergeBlock = mergeBlock; + SelectionControl = selectionControl; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSelectionMerge, MergeBlock, (int)SelectionControl]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "mergeBlock": + MergeBlock = o.ToLiteral(); + break; + case "selectionControl": + SelectionControl = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSelectionMerge(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLabel : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLabel() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLabel | (1 << 16); + } + + public OpLabel(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLabel(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpLabel inst) => inst.ResultId; + public OpLabel(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLabel, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLabel(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBranch : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBranch() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBranch | (1 << 16); + } + + public OpBranch(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBranch(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int TargetLabel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpBranch(int targetLabel) + { + TargetLabel = targetLabel; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBranch, TargetLabel]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "targetLabel": + TargetLabel = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBranch(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBranchConditional : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBranchConditional() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBranchConditional | (1 << 16); + } + + public OpBranchConditional(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBranchConditional(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Condition + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TrueLabel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FalseLabel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray BranchWeights + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpBranchConditional(int condition, int trueLabel, int falseLabel, LiteralArray branchWeights) + { + Condition = condition; + TrueLabel = trueLabel; + FalseLabel = falseLabel; + BranchWeights = branchWeights; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBranchConditional, Condition, TrueLabel, FalseLabel, ..BranchWeights.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "condition": + Condition = o.ToLiteral(); + break; + case "trueLabel": + TrueLabel = o.ToLiteral(); + break; + case "falseLabel": + FalseLabel = o.ToLiteral(); + break; + case "branchWeights": + BranchWeights = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (BranchWeights.WordCount == -1) + BranchWeights = new(); + } + + public static implicit operator OpBranchConditional(OpDataIndex odi) => new(odi); + public void Dispose() + { + BranchWeights.Dispose(); + } +} + +public ref partial struct OpSwitch : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSwitch() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSwitch | (1 << 16); + } + + public OpSwitch(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSwitch(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Selector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int DefaultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray<(int, int)> Targets + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSwitch(int selector, int defaultId, LiteralArray<(int, int)> targets) + { + Selector = selector; + DefaultId = defaultId; + Targets = targets; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSwitch, Selector, DefaultId, ..Targets.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "selector": + Selector = o.ToLiteral(); + break; + case "defaultId": + DefaultId = o.ToLiteral(); + break; + case "targets": + Targets = o.ToLiteralArray<(int, int)>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Targets.WordCount == -1) + Targets = new(); + } + + public static implicit operator OpSwitch(OpDataIndex odi) => new(odi); + public void Dispose() + { + Targets.Dispose(); + } +} + +public ref partial struct OpKill : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpKill() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpKill | (1 << 16); + } + + public OpKill(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpKill(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpKill]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpKill(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReturn : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReturn() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReturn | (1 << 16); + } + + public OpReturn(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReturn(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReturn]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReturn(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReturnValue : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReturnValue() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReturnValue | (1 << 16); + } + + public OpReturnValue(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReturnValue(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpReturnValue(int value) + { + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReturnValue, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReturnValue(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUnreachable : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUnreachable() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUnreachable | (1 << 16); + } + + public OpUnreachable(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUnreachable(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUnreachable]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUnreachable(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLifetimeStart : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLifetimeStart() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLifetimeStart | (1 << 16); + } + + public OpLifetimeStart(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLifetimeStart(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Size + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpLifetimeStart(int pointer, int size) + { + Pointer = pointer; + Size = size; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLifetimeStart, Pointer, ..Size.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointer": + Pointer = o.ToLiteral(); + break; + case "size": + Size = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLifetimeStart(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLifetimeStop : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLifetimeStop() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLifetimeStop | (1 << 16); + } + + public OpLifetimeStop(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLifetimeStop(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Size + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpLifetimeStop(int pointer, int size) + { + Pointer = pointer; + Size = size; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLifetimeStop, Pointer, ..Size.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointer": + Pointer = o.ToLiteral(); + break; + case "size": + Size = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpLifetimeStop(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupAsyncCopy : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupAsyncCopy() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupAsyncCopy | (1 << 16); + } + + public OpGroupAsyncCopy(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupAsyncCopy(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Destination + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Source + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumElements + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Stride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupAsyncCopy inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupAsyncCopy inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupAsyncCopy(int resultType, int resultId, int execution, int destination, int source, int numElements, int stride, int eventId) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Destination = destination; + Source = source; + NumElements = numElements; + Stride = stride; + EventId = eventId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupAsyncCopy, ResultType, ResultId, Execution, Destination, Source, NumElements, Stride, EventId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "destination": + Destination = o.ToLiteral(); + break; + case "source": + Source = o.ToLiteral(); + break; + case "numElements": + NumElements = o.ToLiteral(); + break; + case "stride": + Stride = o.ToLiteral(); + break; + case "eventId": + EventId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupAsyncCopy(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupWaitEvents : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupWaitEvents() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupWaitEvents | (1 << 16); + } + + public OpGroupWaitEvents(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupWaitEvents(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumEvents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EventsList + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpGroupWaitEvents(int execution, int numEvents, int eventsList) + { + Execution = execution; + NumEvents = numEvents; + EventsList = eventsList; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupWaitEvents, Execution, NumEvents, EventsList]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "numEvents": + NumEvents = o.ToLiteral(); + break; + case "eventsList": + EventsList = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupWaitEvents(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupAll : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupAll() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupAll | (1 << 16); + } + + public OpGroupAll(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupAll(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupAll inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupAll inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupAll(int resultType, int resultId, int execution, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupAll, ResultType, ResultId, Execution, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupAll(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupAny : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupAny() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupAny | (1 << 16); + } + + public OpGroupAny(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupAny(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupAny inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupAny inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupAny(int resultType, int resultId, int execution, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupAny, ResultType, ResultId, Execution, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupAny(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupBroadcast : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupBroadcast() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupBroadcast | (1 << 16); + } + + public OpGroupBroadcast(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupBroadcast(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LocalId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupBroadcast inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupBroadcast inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupBroadcast(int resultType, int resultId, int execution, int value, int localId) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + LocalId = localId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupBroadcast, ResultType, ResultId, Execution, Value, LocalId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "localId": + LocalId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupBroadcast(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupIAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupIAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupIAdd | (1 << 16); + } + + public OpGroupIAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupIAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupIAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupIAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupIAdd(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupIAdd, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupIAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFAdd | (1 << 16); + } + + public OpGroupFAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFAdd(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFAdd, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFMin | (1 << 16); + } + + public OpGroupFMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFMin(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFMin, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupUMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupUMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupUMin | (1 << 16); + } + + public OpGroupUMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupUMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupUMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupUMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupUMin(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupUMin, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupUMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupSMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupSMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupSMin | (1 << 16); + } + + public OpGroupSMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupSMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupSMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupSMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupSMin(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupSMin, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupSMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFMax | (1 << 16); + } + + public OpGroupFMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFMax(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFMax, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupUMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupUMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupUMax | (1 << 16); + } + + public OpGroupUMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupUMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupUMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupUMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupUMax(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupUMax, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupUMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupSMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupSMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupSMax | (1 << 16); + } + + public OpGroupSMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupSMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupSMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupSMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupSMax(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupSMax, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupSMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReadPipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReadPipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReadPipe | (1 << 16); + } + + public OpReadPipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReadPipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReadPipe inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReadPipe inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReadPipe(int resultType, int resultId, int pipe, int pointer, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + Pointer = pointer; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReadPipe, ResultType, ResultId, Pipe, Pointer, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReadPipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpWritePipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpWritePipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpWritePipe | (1 << 16); + } + + public OpWritePipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpWritePipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpWritePipe inst) => inst.ResultId; + public static implicit operator SpirvValue(OpWritePipe inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpWritePipe(int resultType, int resultId, int pipe, int pointer, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + Pointer = pointer; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpWritePipe, ResultType, ResultId, Pipe, Pointer, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpWritePipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReservedReadPipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReservedReadPipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReservedReadPipe | (1 << 16); + } + + public OpReservedReadPipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReservedReadPipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReservedReadPipe inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReservedReadPipe inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReservedReadPipe(int resultType, int resultId, int pipe, int reserveId, int index, int pointer, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + ReserveId = reserveId; + Index = index; + Pointer = pointer; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReservedReadPipe, ResultType, ResultId, Pipe, ReserveId, Index, Pointer, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReservedReadPipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReservedWritePipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReservedWritePipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReservedWritePipe | (1 << 16); + } + + public OpReservedWritePipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReservedWritePipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReservedWritePipe inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReservedWritePipe inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReservedWritePipe(int resultType, int resultId, int pipe, int reserveId, int index, int pointer, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + ReserveId = reserveId; + Index = index; + Pointer = pointer; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReservedWritePipe, ResultType, ResultId, Pipe, ReserveId, Index, Pointer, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReservedWritePipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReserveReadPipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReserveReadPipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReserveReadPipePackets | (1 << 16); + } + + public OpReserveReadPipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReserveReadPipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumPackets + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReserveReadPipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReserveReadPipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReserveReadPipePackets(int resultType, int resultId, int pipe, int numPackets, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + NumPackets = numPackets; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReserveReadPipePackets, ResultType, ResultId, Pipe, NumPackets, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "numPackets": + NumPackets = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReserveReadPipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReserveWritePipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReserveWritePipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReserveWritePipePackets | (1 << 16); + } + + public OpReserveWritePipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReserveWritePipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumPackets + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReserveWritePipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReserveWritePipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReserveWritePipePackets(int resultType, int resultId, int pipe, int numPackets, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + NumPackets = numPackets; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReserveWritePipePackets, ResultType, ResultId, Pipe, NumPackets, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "numPackets": + NumPackets = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReserveWritePipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCommitReadPipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCommitReadPipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCommitReadPipe | (1 << 16); + } + + public OpCommitReadPipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCommitReadPipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpCommitReadPipe(int pipe, int reserveId, int packetSize, int packetAlignment) + { + Pipe = pipe; + ReserveId = reserveId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCommitReadPipe, Pipe, ReserveId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCommitReadPipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCommitWritePipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCommitWritePipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCommitWritePipe | (1 << 16); + } + + public OpCommitWritePipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCommitWritePipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpCommitWritePipe(int pipe, int reserveId, int packetSize, int packetAlignment) + { + Pipe = pipe; + ReserveId = reserveId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCommitWritePipe, Pipe, ReserveId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCommitWritePipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsValidReserveId : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsValidReserveId() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsValidReserveId | (1 << 16); + } + + public OpIsValidReserveId(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsValidReserveId(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsValidReserveId inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsValidReserveId inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsValidReserveId(int resultType, int resultId, int reserveId) + { + ResultType = resultType; + ResultId = resultId; + ReserveId = reserveId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsValidReserveId, ResultType, ResultId, ReserveId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsValidReserveId(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetNumPipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetNumPipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetNumPipePackets | (1 << 16); + } + + public OpGetNumPipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetNumPipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetNumPipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetNumPipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetNumPipePackets(int resultType, int resultId, int pipe, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetNumPipePackets, ResultType, ResultId, Pipe, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetNumPipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetMaxPipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetMaxPipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetMaxPipePackets | (1 << 16); + } + + public OpGetMaxPipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetMaxPipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetMaxPipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetMaxPipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetMaxPipePackets(int resultType, int resultId, int pipe, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Pipe = pipe; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetMaxPipePackets, ResultType, ResultId, Pipe, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetMaxPipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupReserveReadPipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupReserveReadPipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupReserveReadPipePackets | (1 << 16); + } + + public OpGroupReserveReadPipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupReserveReadPipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumPackets + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupReserveReadPipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupReserveReadPipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupReserveReadPipePackets(int resultType, int resultId, int execution, int pipe, int numPackets, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Pipe = pipe; + NumPackets = numPackets; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupReserveReadPipePackets, ResultType, ResultId, Execution, Pipe, NumPackets, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "numPackets": + NumPackets = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupReserveReadPipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupReserveWritePipePackets : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupReserveWritePipePackets() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupReserveWritePipePackets | (1 << 16); + } + + public OpGroupReserveWritePipePackets(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupReserveWritePipePackets(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumPackets + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupReserveWritePipePackets inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupReserveWritePipePackets inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupReserveWritePipePackets(int resultType, int resultId, int execution, int pipe, int numPackets, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Pipe = pipe; + NumPackets = numPackets; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupReserveWritePipePackets, ResultType, ResultId, Execution, Pipe, NumPackets, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "numPackets": + NumPackets = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupReserveWritePipePackets(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupCommitReadPipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupCommitReadPipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupCommitReadPipe | (1 << 16); + } + + public OpGroupCommitReadPipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupCommitReadPipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpGroupCommitReadPipe(int execution, int pipe, int reserveId, int packetSize, int packetAlignment) + { + Execution = execution; + Pipe = pipe; + ReserveId = reserveId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupCommitReadPipe, Execution, Pipe, ReserveId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupCommitReadPipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupCommitWritePipe : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupCommitWritePipe() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupCommitWritePipe | (1 << 16); + } + + public OpGroupCommitWritePipe(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupCommitWritePipe(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pipe + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReserveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpGroupCommitWritePipe(int execution, int pipe, int reserveId, int packetSize, int packetAlignment) + { + Execution = execution; + Pipe = pipe; + ReserveId = reserveId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupCommitWritePipe, Execution, Pipe, ReserveId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "pipe": + Pipe = o.ToLiteral(); + break; + case "reserveId": + ReserveId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupCommitWritePipe(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEnqueueMarker : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEnqueueMarker() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEnqueueMarker | (1 << 16); + } + + public OpEnqueueMarker(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEnqueueMarker(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Queue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumEvents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int WaitEvents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RetEvent + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpEnqueueMarker inst) => inst.ResultId; + public static implicit operator SpirvValue(OpEnqueueMarker inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpEnqueueMarker(int resultType, int resultId, int queue, int numEvents, int waitEvents, int retEvent) + { + ResultType = resultType; + ResultId = resultId; + Queue = queue; + NumEvents = numEvents; + WaitEvents = waitEvents; + RetEvent = retEvent; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEnqueueMarker, ResultType, ResultId, Queue, NumEvents, WaitEvents, RetEvent]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "queue": + Queue = o.ToLiteral(); + break; + case "numEvents": + NumEvents = o.ToLiteral(); + break; + case "waitEvents": + WaitEvents = o.ToLiteral(); + break; + case "retEvent": + RetEvent = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEnqueueMarker(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEnqueueKernel : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEnqueueKernel() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEnqueueKernel | (1 << 16); + } + + public OpEnqueueKernel(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEnqueueKernel(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Queue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NDRange + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumEvents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int WaitEvents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RetEvent + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray LocalSizes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpEnqueueKernel inst) => inst.ResultId; + public static implicit operator SpirvValue(OpEnqueueKernel inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpEnqueueKernel(int resultType, int resultId, int queue, int flags, int nDRange, int numEvents, int waitEvents, int retEvent, int invoke, int param, int paramSize, int paramAlign, LiteralArray localSizes) + { + ResultType = resultType; + ResultId = resultId; + Queue = queue; + Flags = flags; + NDRange = nDRange; + NumEvents = numEvents; + WaitEvents = waitEvents; + RetEvent = retEvent; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + LocalSizes = localSizes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEnqueueKernel, ResultType, ResultId, Queue, Flags, NDRange, NumEvents, WaitEvents, RetEvent, Invoke, Param, ParamSize, ParamAlign, ..LocalSizes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "queue": + Queue = o.ToLiteral(); + break; + case "flags": + Flags = o.ToLiteral(); + break; + case "nDRange": + NDRange = o.ToLiteral(); + break; + case "numEvents": + NumEvents = o.ToLiteral(); + break; + case "waitEvents": + WaitEvents = o.ToLiteral(); + break; + case "retEvent": + RetEvent = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + case "localSizes": + LocalSizes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (LocalSizes.WordCount == -1) + LocalSizes = new(); + } + + public static implicit operator OpEnqueueKernel(OpDataIndex odi) => new(odi); + public void Dispose() + { + LocalSizes.Dispose(); + } +} + +public ref partial struct OpGetKernelNDrangeSubGroupCount : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelNDrangeSubGroupCount() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelNDrangeSubGroupCount | (1 << 16); + } + + public OpGetKernelNDrangeSubGroupCount(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelNDrangeSubGroupCount(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NDRange + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelNDrangeSubGroupCount inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelNDrangeSubGroupCount inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelNDrangeSubGroupCount(int resultType, int resultId, int nDRange, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + NDRange = nDRange; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelNDrangeSubGroupCount, ResultType, ResultId, NDRange, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "nDRange": + NDRange = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelNDrangeSubGroupCount(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetKernelNDrangeMaxSubGroupSize : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelNDrangeMaxSubGroupSize() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelNDrangeMaxSubGroupSize | (1 << 16); + } + + public OpGetKernelNDrangeMaxSubGroupSize(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelNDrangeMaxSubGroupSize(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NDRange + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelNDrangeMaxSubGroupSize inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelNDrangeMaxSubGroupSize inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelNDrangeMaxSubGroupSize(int resultType, int resultId, int nDRange, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + NDRange = nDRange; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelNDrangeMaxSubGroupSize, ResultType, ResultId, NDRange, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "nDRange": + NDRange = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelNDrangeMaxSubGroupSize(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetKernelWorkGroupSize : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelWorkGroupSize() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelWorkGroupSize | (1 << 16); + } + + public OpGetKernelWorkGroupSize(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelWorkGroupSize(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelWorkGroupSize inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelWorkGroupSize inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelWorkGroupSize(int resultType, int resultId, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelWorkGroupSize, ResultType, ResultId, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelWorkGroupSize(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetKernelPreferredWorkGroupSizeMultiple : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelPreferredWorkGroupSizeMultiple() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelPreferredWorkGroupSizeMultiple | (1 << 16); + } + + public OpGetKernelPreferredWorkGroupSizeMultiple(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelPreferredWorkGroupSizeMultiple(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelPreferredWorkGroupSizeMultiple inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelPreferredWorkGroupSizeMultiple inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelPreferredWorkGroupSizeMultiple(int resultType, int resultId, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelPreferredWorkGroupSizeMultiple, ResultType, ResultId, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelPreferredWorkGroupSizeMultiple(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRetainEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRetainEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRetainEvent | (1 << 16); + } + + public OpRetainEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRetainEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRetainEvent(int eventId) + { + EventId = eventId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRetainEvent, EventId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "eventId": + EventId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRetainEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReleaseEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReleaseEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReleaseEvent | (1 << 16); + } + + public OpReleaseEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReleaseEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpReleaseEvent(int eventId) + { + EventId = eventId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReleaseEvent, EventId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "eventId": + EventId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReleaseEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCreateUserEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCreateUserEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCreateUserEvent | (1 << 16); + } + + public OpCreateUserEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCreateUserEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCreateUserEvent inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCreateUserEvent inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCreateUserEvent(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCreateUserEvent, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCreateUserEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsValidEvent : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsValidEvent() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsValidEvent | (1 << 16); + } + + public OpIsValidEvent(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsValidEvent(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsValidEvent inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsValidEvent inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsValidEvent(int resultType, int resultId, int eventId) + { + ResultType = resultType; + ResultId = resultId; + EventId = eventId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsValidEvent, ResultType, ResultId, EventId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "eventId": + EventId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsValidEvent(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSetUserEventStatus : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSetUserEventStatus() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSetUserEventStatus | (1 << 16); + } + + public OpSetUserEventStatus(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSetUserEventStatus(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Status + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSetUserEventStatus(int eventId, int status) + { + EventId = eventId; + Status = status; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSetUserEventStatus, EventId, Status]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "eventId": + EventId = o.ToLiteral(); + break; + case "status": + Status = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSetUserEventStatus(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCaptureEventProfilingInfo : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCaptureEventProfilingInfo() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCaptureEventProfilingInfo | (1 << 16); + } + + public OpCaptureEventProfilingInfo(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCaptureEventProfilingInfo(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EventId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ProfilingInfo + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpCaptureEventProfilingInfo(int eventId, int profilingInfo, int value) + { + EventId = eventId; + ProfilingInfo = profilingInfo; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCaptureEventProfilingInfo, EventId, ProfilingInfo, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "eventId": + EventId = o.ToLiteral(); + break; + case "profilingInfo": + ProfilingInfo = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCaptureEventProfilingInfo(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetDefaultQueue : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetDefaultQueue() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetDefaultQueue | (1 << 16); + } + + public OpGetDefaultQueue(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetDefaultQueue(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetDefaultQueue inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetDefaultQueue inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetDefaultQueue(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetDefaultQueue, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetDefaultQueue(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBuildNDRange : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBuildNDRange() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBuildNDRange | (1 << 16); + } + + public OpBuildNDRange(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBuildNDRange(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GlobalWorkSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LocalWorkSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GlobalWorkOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBuildNDRange inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBuildNDRange inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBuildNDRange(int resultType, int resultId, int globalWorkSize, int localWorkSize, int globalWorkOffset) + { + ResultType = resultType; + ResultId = resultId; + GlobalWorkSize = globalWorkSize; + LocalWorkSize = localWorkSize; + GlobalWorkOffset = globalWorkOffset; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBuildNDRange, ResultType, ResultId, GlobalWorkSize, LocalWorkSize, GlobalWorkOffset]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "globalWorkSize": + GlobalWorkSize = o.ToLiteral(); + break; + case "localWorkSize": + LocalWorkSize = o.ToLiteral(); + break; + case "globalWorkOffset": + GlobalWorkOffset = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBuildNDRange(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageSparseSampleImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleImplicitLod | (1 << 16); + } + + public OpImageSparseSampleImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleImplicitLod, ResultType, ResultId, SampledImage, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleExplicitLod | (1 << 16); + } + + public OpImageSparseSampleExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleExplicitLod, ResultType, ResultId, SampledImage, Coordinate, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleDrefImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleDrefImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleDrefImplicitLod | (1 << 16); + } + + public OpImageSparseSampleDrefImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleDrefImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleDrefImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleDrefImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleDrefImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleDrefImplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleDrefImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleDrefExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleDrefExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleDrefExplicitLod | (1 << 16); + } + + public OpImageSparseSampleDrefExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleDrefExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleDrefExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleDrefExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleDrefExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleDrefExplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleDrefExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleProjImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleProjImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleProjImplicitLod | (1 << 16); + } + + public OpImageSparseSampleProjImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleProjImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleProjImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleProjImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleProjImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleProjImplicitLod, ResultType, ResultId, SampledImage, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleProjImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleProjExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleProjExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleProjExplicitLod | (1 << 16); + } + + public OpImageSparseSampleProjExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleProjExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleProjExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleProjExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleProjExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleProjExplicitLod, ResultType, ResultId, SampledImage, Coordinate, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleProjExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleProjDrefImplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleProjDrefImplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleProjDrefImplicitLod | (1 << 16); + } + + public OpImageSparseSampleProjDrefImplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleProjDrefImplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleProjDrefImplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleProjDrefImplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleProjDrefImplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleProjDrefImplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleProjDrefImplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseSampleProjDrefExplicitLod : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseSampleProjDrefExplicitLod() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseSampleProjDrefExplicitLod | (1 << 16); + } + + public OpImageSparseSampleProjDrefExplicitLod(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseSampleProjDrefExplicitLod(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseSampleProjDrefExplicitLod inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseSampleProjDrefExplicitLod inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseSampleProjDrefExplicitLod(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseSampleProjDrefExplicitLod, ResultType, ResultId, SampledImage, Coordinate, Dref, (int)ImageOperands, ..ImageOperandsParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseSampleProjDrefExplicitLod(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseFetch : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseFetch() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseFetch | (1 << 16); + } + + public OpImageSparseFetch(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseFetch(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseFetch inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseFetch inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseFetch(int resultType, int resultId, int image, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseFetch, ResultType, ResultId, Image, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseFetch(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseGather : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseGather() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseGather | (1 << 16); + } + + public OpImageSparseGather(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseGather(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Component + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseGather inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseGather inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseGather(int resultType, int resultId, int sampledImage, int coordinate, int component, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Component = component; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseGather, ResultType, ResultId, SampledImage, Coordinate, Component, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "component": + Component = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseGather(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseDrefGather : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseDrefGather() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseDrefGather | (1 << 16); + } + + public OpImageSparseDrefGather(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseDrefGather(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseDrefGather inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseDrefGather inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseDrefGather(int resultType, int resultId, int sampledImage, int coordinate, int dref, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Dref = dref; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseDrefGather, ResultType, ResultId, SampledImage, Coordinate, Dref, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "dref": + Dref = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseDrefGather(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpImageSparseTexelsResident : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseTexelsResident() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseTexelsResident | (1 << 16); + } + + public OpImageSparseTexelsResident(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseTexelsResident(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResidentCode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseTexelsResident inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseTexelsResident inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseTexelsResident(int resultType, int resultId, int residentCode) + { + ResultType = resultType; + ResultId = resultId; + ResidentCode = residentCode; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseTexelsResident, ResultType, ResultId, ResidentCode]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "residentCode": + ResidentCode = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseTexelsResident(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpNoLine : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpNoLine() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpNoLine | (1 << 16); + } + + public OpNoLine(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpNoLine(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpNoLine]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpNoLine(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicFlagTestAndSet : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicFlagTestAndSet() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicFlagTestAndSet | (1 << 16); + } + + public OpAtomicFlagTestAndSet(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicFlagTestAndSet(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicFlagTestAndSet inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicFlagTestAndSet inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicFlagTestAndSet(int resultType, int resultId, int pointer, int memory, int semantics) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicFlagTestAndSet, ResultType, ResultId, Pointer, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicFlagTestAndSet(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicFlagClear : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicFlagClear() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicFlagClear | (1 << 16); + } + + public OpAtomicFlagClear(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicFlagClear(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpAtomicFlagClear(int pointer, int memory, int semantics) + { + Pointer = pointer; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicFlagClear, Pointer, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicFlagClear(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageSparseRead : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSparseRead() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSparseRead | (1 << 16); + } + + public OpImageSparseRead(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSparseRead(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSparseRead inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSparseRead inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSparseRead(int resultType, int resultId, int image, int coordinate, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSparseRead, ResultType, ResultId, Image, Coordinate, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSparseRead(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpSizeOf : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSizeOf() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSizeOf | (1 << 16); + } + + public OpSizeOf(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSizeOf(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSizeOf inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSizeOf inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSizeOf(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSizeOf, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSizeOf(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypePipeStorage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypePipeStorage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypePipeStorage | (1 << 16); + } + + public OpTypePipeStorage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypePipeStorage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypePipeStorage inst) => inst.ResultId; + public OpTypePipeStorage(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypePipeStorage, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypePipeStorage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantPipeStorage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantPipeStorage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantPipeStorage | (1 << 16); + } + + public OpConstantPipeStorage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantPipeStorage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Capacity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantPipeStorage inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantPipeStorage inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantPipeStorage(int resultType, int resultId, int packetSize, int packetAlignment, int capacity) + { + ResultType = resultType; + ResultId = resultId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + Capacity = capacity; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantPipeStorage, ResultType, ResultId, ..PacketSize.AsDisposableLiteralValue().Words, ..PacketAlignment.AsDisposableLiteralValue().Words, ..Capacity.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + case "capacity": + Capacity = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantPipeStorage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCreatePipeFromPipeStorage : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCreatePipeFromPipeStorage() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCreatePipeFromPipeStorage | (1 << 16); + } + + public OpCreatePipeFromPipeStorage(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCreatePipeFromPipeStorage(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PipeStorage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCreatePipeFromPipeStorage inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCreatePipeFromPipeStorage inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCreatePipeFromPipeStorage(int resultType, int resultId, int pipeStorage) + { + ResultType = resultType; + ResultId = resultId; + PipeStorage = pipeStorage; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCreatePipeFromPipeStorage, ResultType, ResultId, PipeStorage]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pipeStorage": + PipeStorage = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCreatePipeFromPipeStorage(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetKernelLocalSizeForSubgroupCount : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelLocalSizeForSubgroupCount() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelLocalSizeForSubgroupCount | (1 << 16); + } + + public OpGetKernelLocalSizeForSubgroupCount(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelLocalSizeForSubgroupCount(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SubgroupCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelLocalSizeForSubgroupCount inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelLocalSizeForSubgroupCount inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelLocalSizeForSubgroupCount(int resultType, int resultId, int subgroupCount, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + SubgroupCount = subgroupCount; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelLocalSizeForSubgroupCount, ResultType, ResultId, SubgroupCount, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "subgroupCount": + SubgroupCount = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelLocalSizeForSubgroupCount(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGetKernelMaxNumSubgroups : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGetKernelMaxNumSubgroups() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGetKernelMaxNumSubgroups | (1 << 16); + } + + public OpGetKernelMaxNumSubgroups(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGetKernelMaxNumSubgroups(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Invoke + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Param + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ParamAlign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGetKernelMaxNumSubgroups inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGetKernelMaxNumSubgroups inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGetKernelMaxNumSubgroups(int resultType, int resultId, int invoke, int param, int paramSize, int paramAlign) + { + ResultType = resultType; + ResultId = resultId; + Invoke = invoke; + Param = param; + ParamSize = paramSize; + ParamAlign = paramAlign; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGetKernelMaxNumSubgroups, ResultType, ResultId, Invoke, Param, ParamSize, ParamAlign]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "invoke": + Invoke = o.ToLiteral(); + break; + case "param": + Param = o.ToLiteral(); + break; + case "paramSize": + ParamSize = o.ToLiteral(); + break; + case "paramAlign": + ParamAlign = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGetKernelMaxNumSubgroups(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeNamedBarrier : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeNamedBarrier() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeNamedBarrier | (1 << 16); + } + + public OpTypeNamedBarrier(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeNamedBarrier(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeNamedBarrier inst) => inst.ResultId; + public OpTypeNamedBarrier(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeNamedBarrier, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeNamedBarrier(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpNamedBarrierInitialize : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpNamedBarrierInitialize() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpNamedBarrierInitialize | (1 << 16); + } + + public OpNamedBarrierInitialize(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpNamedBarrierInitialize(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SubgroupCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpNamedBarrierInitialize inst) => inst.ResultId; + public static implicit operator SpirvValue(OpNamedBarrierInitialize inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpNamedBarrierInitialize(int resultType, int resultId, int subgroupCount) + { + ResultType = resultType; + ResultId = resultId; + SubgroupCount = subgroupCount; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpNamedBarrierInitialize, ResultType, ResultId, SubgroupCount]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "subgroupCount": + SubgroupCount = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpNamedBarrierInitialize(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMemoryNamedBarrier : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemoryNamedBarrier() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemoryNamedBarrier | (1 << 16); + } + + public OpMemoryNamedBarrier(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemoryNamedBarrier(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int NamedBarrier + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemoryNamedBarrier(int namedBarrier, int memory, int semantics) + { + NamedBarrier = namedBarrier; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemoryNamedBarrier, NamedBarrier, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "namedBarrier": + NamedBarrier = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemoryNamedBarrier(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpModuleProcessed : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpModuleProcessed() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpModuleProcessed | (1 << 16); + } + + public OpModuleProcessed(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpModuleProcessed(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string Process + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpModuleProcessed(string process) + { + Process = process; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpModuleProcessed, ..Process.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "process": + Process = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpModuleProcessed(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExecutionModeId : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExecutionModeId() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExecutionModeId | (1 << 16); + } + + public OpExecutionModeId(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExecutionModeId(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int EntryPoint + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ExecutionMode Mode { get; set; } + + public EnumerantParameters ModeParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpExecutionModeId(int entryPoint, ExecutionMode mode, EnumerantParameters modeParameters) + { + EntryPoint = entryPoint; + Mode = mode; + ModeParameters = modeParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExecutionModeId, EntryPoint, (int)Mode, ..ModeParameters]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "entryPoint": + EntryPoint = o.ToLiteral(); + break; + case "mode": + Mode = o.ToEnum(); + ModeParameters = new(data.Memory.Span[(o.Offset + 2)..]); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExecutionModeId(OpDataIndex odi) => new(odi); + public void Dispose() + { + ModeParameters.Dispose(); + } +} + +public ref partial struct OpDecorateId : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDecorateId() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDecorateId | (1 << 16); + } + + public OpDecorateId(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDecorateId(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Decoration Decoration + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpDecorateId(int target, Decoration decoration, int value) + { + Target = target; + Decoration = decoration; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDecorateId, Target, (int)Decoration, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "target": + Target = o.ToLiteral(); + break; + case "decoration": + Decoration = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDecorateId(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformElect : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformElect() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformElect | (1 << 16); + } + + public OpGroupNonUniformElect(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformElect(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformElect inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformElect inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformElect(int resultType, int resultId, int execution) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformElect, ResultType, ResultId, Execution]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformElect(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformAll : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformAll() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformAll | (1 << 16); + } + + public OpGroupNonUniformAll(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformAll(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformAll inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformAll inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformAll(int resultType, int resultId, int execution, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformAll, ResultType, ResultId, Execution, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformAll(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformAny : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformAny() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformAny | (1 << 16); + } + + public OpGroupNonUniformAny(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformAny(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformAny inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformAny inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformAny(int resultType, int resultId, int execution, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformAny, ResultType, ResultId, Execution, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformAny(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformAllEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformAllEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformAllEqual | (1 << 16); + } + + public OpGroupNonUniformAllEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformAllEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformAllEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformAllEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformAllEqual(int resultType, int resultId, int execution, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformAllEqual, ResultType, ResultId, Execution, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformAllEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBroadcast : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBroadcast() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBroadcast | (1 << 16); + } + + public OpGroupNonUniformBroadcast(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBroadcast(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Id + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBroadcast inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBroadcast inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBroadcast(int resultType, int resultId, int execution, int value, int id) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Id = id; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBroadcast, ResultType, ResultId, Execution, Value, Id]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "id": + Id = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBroadcast(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBroadcastFirst : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBroadcastFirst() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBroadcastFirst | (1 << 16); + } + + public OpGroupNonUniformBroadcastFirst(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBroadcastFirst(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBroadcastFirst inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBroadcastFirst inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBroadcastFirst(int resultType, int resultId, int execution, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBroadcastFirst, ResultType, ResultId, Execution, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBroadcastFirst(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBallot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBallot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBallot | (1 << 16); + } + + public OpGroupNonUniformBallot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBallot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBallot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBallot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBallot(int resultType, int resultId, int execution, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBallot, ResultType, ResultId, Execution, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBallot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformInverseBallot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformInverseBallot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformInverseBallot | (1 << 16); + } + + public OpGroupNonUniformInverseBallot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformInverseBallot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformInverseBallot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformInverseBallot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformInverseBallot(int resultType, int resultId, int execution, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformInverseBallot, ResultType, ResultId, Execution, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformInverseBallot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBallotBitExtract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBallotBitExtract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBallotBitExtract | (1 << 16); + } + + public OpGroupNonUniformBallotBitExtract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBallotBitExtract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBallotBitExtract inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBallotBitExtract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBallotBitExtract(int resultType, int resultId, int execution, int value, int index) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Index = index; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBallotBitExtract, ResultType, ResultId, Execution, Value, Index]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBallotBitExtract(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBallotBitCount : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBallotBitCount() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBallotBitCount | (1 << 16); + } + + public OpGroupNonUniformBallotBitCount(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBallotBitCount(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBallotBitCount inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBallotBitCount inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBallotBitCount(int resultType, int resultId, int execution, GroupOperation operation, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBallotBitCount, ResultType, ResultId, Execution, (int)Operation, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBallotBitCount(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBallotFindLSB : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBallotFindLSB() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBallotFindLSB | (1 << 16); + } + + public OpGroupNonUniformBallotFindLSB(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBallotFindLSB(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBallotFindLSB inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBallotFindLSB inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBallotFindLSB(int resultType, int resultId, int execution, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBallotFindLSB, ResultType, ResultId, Execution, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBallotFindLSB(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBallotFindMSB : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBallotFindMSB() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBallotFindMSB | (1 << 16); + } + + public OpGroupNonUniformBallotFindMSB(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBallotFindMSB(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBallotFindMSB inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBallotFindMSB inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBallotFindMSB(int resultType, int resultId, int execution, int value) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBallotFindMSB, ResultType, ResultId, Execution, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBallotFindMSB(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformShuffle : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformShuffle() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformShuffle | (1 << 16); + } + + public OpGroupNonUniformShuffle(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformShuffle(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Id + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformShuffle inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformShuffle inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformShuffle(int resultType, int resultId, int execution, int value, int id) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Id = id; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformShuffle, ResultType, ResultId, Execution, Value, Id]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "id": + Id = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformShuffle(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformShuffleXor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformShuffleXor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformShuffleXor | (1 << 16); + } + + public OpGroupNonUniformShuffleXor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformShuffleXor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformShuffleXor inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformShuffleXor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformShuffleXor(int resultType, int resultId, int execution, int value, int mask) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Mask = mask; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformShuffleXor, ResultType, ResultId, Execution, Value, Mask]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "mask": + Mask = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformShuffleXor(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformShuffleUp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformShuffleUp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformShuffleUp | (1 << 16); + } + + public OpGroupNonUniformShuffleUp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformShuffleUp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Delta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformShuffleUp inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformShuffleUp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformShuffleUp(int resultType, int resultId, int execution, int value, int delta) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Delta = delta; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformShuffleUp, ResultType, ResultId, Execution, Value, Delta]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "delta": + Delta = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformShuffleUp(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformShuffleDown : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformShuffleDown() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformShuffleDown | (1 << 16); + } + + public OpGroupNonUniformShuffleDown(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformShuffleDown(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Delta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformShuffleDown inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformShuffleDown inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformShuffleDown(int resultType, int resultId, int execution, int value, int delta) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Delta = delta; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformShuffleDown, ResultType, ResultId, Execution, Value, Delta]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "delta": + Delta = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformShuffleDown(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformIAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformIAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformIAdd | (1 << 16); + } + + public OpGroupNonUniformIAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformIAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformIAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformIAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformIAdd(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformIAdd, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformIAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformFAdd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformFAdd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformFAdd | (1 << 16); + } + + public OpGroupNonUniformFAdd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformFAdd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformFAdd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformFAdd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformFAdd(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformFAdd, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformFAdd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformIMul : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformIMul() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformIMul | (1 << 16); + } + + public OpGroupNonUniformIMul(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformIMul(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformIMul inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformIMul inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformIMul(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformIMul, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformIMul(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformFMul : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformFMul() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformFMul | (1 << 16); + } + + public OpGroupNonUniformFMul(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformFMul(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformFMul inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformFMul inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformFMul(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformFMul, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformFMul(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformSMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformSMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformSMin | (1 << 16); + } + + public OpGroupNonUniformSMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformSMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformSMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformSMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformSMin(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformSMin, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformSMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformUMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformUMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformUMin | (1 << 16); + } + + public OpGroupNonUniformUMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformUMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformUMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformUMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformUMin(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformUMin, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformUMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformFMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformFMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformFMin | (1 << 16); + } + + public OpGroupNonUniformFMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformFMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformFMin inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformFMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformFMin(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformFMin, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformFMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformSMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformSMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformSMax | (1 << 16); + } + + public OpGroupNonUniformSMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformSMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformSMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformSMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformSMax(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformSMax, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformSMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformUMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformUMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformUMax | (1 << 16); + } + + public OpGroupNonUniformUMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformUMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformUMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformUMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformUMax(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformUMax, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformUMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformFMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformFMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformFMax | (1 << 16); + } + + public OpGroupNonUniformFMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformFMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformFMax inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformFMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformFMax(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformFMax, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformFMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBitwiseAnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBitwiseAnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBitwiseAnd | (1 << 16); + } + + public OpGroupNonUniformBitwiseAnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBitwiseAnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBitwiseAnd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBitwiseAnd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBitwiseAnd(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBitwiseAnd, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBitwiseAnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBitwiseOr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBitwiseOr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBitwiseOr | (1 << 16); + } + + public OpGroupNonUniformBitwiseOr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBitwiseOr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBitwiseOr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBitwiseOr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBitwiseOr(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBitwiseOr, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBitwiseOr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformBitwiseXor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformBitwiseXor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformBitwiseXor | (1 << 16); + } + + public OpGroupNonUniformBitwiseXor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformBitwiseXor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformBitwiseXor inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformBitwiseXor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformBitwiseXor(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformBitwiseXor, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformBitwiseXor(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformLogicalAnd : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformLogicalAnd() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformLogicalAnd | (1 << 16); + } + + public OpGroupNonUniformLogicalAnd(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformLogicalAnd(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformLogicalAnd inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformLogicalAnd inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformLogicalAnd(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformLogicalAnd, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformLogicalAnd(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformLogicalOr : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformLogicalOr() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformLogicalOr | (1 << 16); + } + + public OpGroupNonUniformLogicalOr(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformLogicalOr(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformLogicalOr inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformLogicalOr inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformLogicalOr(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformLogicalOr, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformLogicalOr(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformLogicalXor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformLogicalXor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformLogicalXor | (1 << 16); + } + + public OpGroupNonUniformLogicalXor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformLogicalXor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformLogicalXor inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformLogicalXor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformLogicalXor(int resultType, int resultId, int execution, GroupOperation operation, int value, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + Value = value; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformLogicalXor, ResultType, ResultId, Execution, (int)Operation, Value, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformLogicalXor(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformQuadBroadcast : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformQuadBroadcast() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformQuadBroadcast | (1 << 16); + } + + public OpGroupNonUniformQuadBroadcast(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformQuadBroadcast(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformQuadBroadcast inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformQuadBroadcast inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformQuadBroadcast(int resultType, int resultId, int execution, int value, int index) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Index = index; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformQuadBroadcast, ResultType, ResultId, Execution, Value, Index]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformQuadBroadcast(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformQuadSwap : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformQuadSwap() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformQuadSwap | (1 << 16); + } + + public OpGroupNonUniformQuadSwap(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformQuadSwap(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformQuadSwap inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformQuadSwap inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformQuadSwap(int resultType, int resultId, int execution, int value, int direction) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Direction = direction; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformQuadSwap, ResultType, ResultId, Execution, Value, Direction]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformQuadSwap(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCopyLogical : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCopyLogical() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCopyLogical | (1 << 16); + } + + public OpCopyLogical(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCopyLogical(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCopyLogical inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCopyLogical inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCopyLogical(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCopyLogical, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCopyLogical(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPtrEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrEqual | (1 << 16); + } + + public OpPtrEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpPtrEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPtrNotEqual : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrNotEqual() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrNotEqual | (1 << 16); + } + + public OpPtrNotEqual(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrNotEqual(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrNotEqual inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrNotEqual inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrNotEqual(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrNotEqual, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpPtrNotEqual(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPtrDiff : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrDiff() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrDiff | (1 << 16); + } + + public OpPtrDiff(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrDiff(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrDiff inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrDiff inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrDiff(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrDiff, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpPtrDiff(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpColorAttachmentReadEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpColorAttachmentReadEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpColorAttachmentReadEXT | (1 << 16); + } + + public OpColorAttachmentReadEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpColorAttachmentReadEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Attachment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Sample + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpColorAttachmentReadEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpColorAttachmentReadEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpColorAttachmentReadEXT(int resultType, int resultId, int attachment, int? sample) + { + ResultType = resultType; + ResultId = resultId; + Attachment = attachment; + Sample = sample; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpColorAttachmentReadEXT, ResultType, ResultId, Attachment, ..(Sample is null ? (Span)[] : [Sample.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "attachment": + Attachment = o.ToLiteral(); + break; + case "sample": + if (o.Words.Length > 0) + { + Sample = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpColorAttachmentReadEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDepthAttachmentReadEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDepthAttachmentReadEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDepthAttachmentReadEXT | (1 << 16); + } + + public OpDepthAttachmentReadEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDepthAttachmentReadEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Sample + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpDepthAttachmentReadEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpDepthAttachmentReadEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpDepthAttachmentReadEXT(int resultType, int resultId, int? sample) + { + ResultType = resultType; + ResultId = resultId; + Sample = sample; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDepthAttachmentReadEXT, ResultType, ResultId, ..(Sample is null ? (Span)[] : [Sample.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sample": + if (o.Words.Length > 0) + { + Sample = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDepthAttachmentReadEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpStencilAttachmentReadEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpStencilAttachmentReadEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpStencilAttachmentReadEXT | (1 << 16); + } + + public OpStencilAttachmentReadEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpStencilAttachmentReadEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Sample + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpStencilAttachmentReadEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpStencilAttachmentReadEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpStencilAttachmentReadEXT(int resultType, int resultId, int? sample) + { + ResultType = resultType; + ResultId = resultId; + Sample = sample; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpStencilAttachmentReadEXT, ResultType, ResultId, ..(Sample is null ? (Span)[] : [Sample.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sample": + if (o.Words.Length > 0) + { + Sample = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpStencilAttachmentReadEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTerminateInvocation : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTerminateInvocation() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTerminateInvocation | (1 << 16); + } + + public OpTerminateInvocation(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTerminateInvocation(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTerminateInvocation]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTerminateInvocation(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeUntypedPointerKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeUntypedPointerKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeUntypedPointerKHR | (1 << 16); + } + + public OpTypeUntypedPointerKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeUntypedPointerKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeUntypedPointerKHR inst) => inst.ResultId; + public OpTypeUntypedPointerKHR(int resultId, StorageClass storageClass) + { + ResultId = resultId; + StorageClass = storageClass; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeUntypedPointerKHR, ResultId, (int)StorageClass]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeUntypedPointerKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUntypedVariableKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedVariableKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedVariableKHR | (1 << 16); + } + + public OpUntypedVariableKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedVariableKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? DataType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Initializer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedVariableKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedVariableKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedVariableKHR(int resultType, int resultId, StorageClass storageClass, int? dataType, int? initializer) + { + ResultType = resultType; + ResultId = resultId; + StorageClass = storageClass; + DataType = dataType; + Initializer = initializer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedVariableKHR, ResultType, ResultId, (int)StorageClass, ..(DataType is null ? (Span)[] : [DataType.Value]), ..(Initializer is null ? (Span)[] : [Initializer.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + case "dataType": + if (o.Words.Length > 0) + { + DataType = o.ToLiteral(); + } + + break; + case "initializer": + if (o.Words.Length > 0) + { + Initializer = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUntypedVariableKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUntypedAccessChainKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedAccessChainKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedAccessChainKHR | (1 << 16); + } + + public OpUntypedAccessChainKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedAccessChainKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedAccessChainKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedAccessChainKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedAccessChainKHR(int resultType, int resultId, int baseType, int baseId, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseType = baseType; + BaseId = baseId; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedAccessChainKHR, ResultType, ResultId, BaseType, BaseId, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpUntypedAccessChainKHR(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpUntypedInBoundsAccessChainKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedInBoundsAccessChainKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedInBoundsAccessChainKHR | (1 << 16); + } + + public OpUntypedInBoundsAccessChainKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedInBoundsAccessChainKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedInBoundsAccessChainKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedInBoundsAccessChainKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedInBoundsAccessChainKHR(int resultType, int resultId, int baseType, int baseId, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseType = baseType; + BaseId = baseId; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedInBoundsAccessChainKHR, ResultType, ResultId, BaseType, BaseId, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpUntypedInBoundsAccessChainKHR(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpSubgroupBallotKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupBallotKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupBallotKHR | (1 << 16); + } + + public OpSubgroupBallotKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupBallotKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupBallotKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupBallotKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupBallotKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupBallotKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupBallotKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupFirstInvocationKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupFirstInvocationKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupFirstInvocationKHR | (1 << 16); + } + + public OpSubgroupFirstInvocationKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupFirstInvocationKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupFirstInvocationKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupFirstInvocationKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupFirstInvocationKHR(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupFirstInvocationKHR, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupFirstInvocationKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUntypedPtrAccessChainKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedPtrAccessChainKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedPtrAccessChainKHR | (1 << 16); + } + + public OpUntypedPtrAccessChainKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedPtrAccessChainKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Element + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedPtrAccessChainKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedPtrAccessChainKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedPtrAccessChainKHR(int resultType, int resultId, int baseType, int baseId, int element, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseType = baseType; + BaseId = baseId; + Element = element; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedPtrAccessChainKHR, ResultType, ResultId, BaseType, BaseId, Element, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "element": + Element = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpUntypedPtrAccessChainKHR(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpUntypedInBoundsPtrAccessChainKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedInBoundsPtrAccessChainKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedInBoundsPtrAccessChainKHR | (1 << 16); + } + + public OpUntypedInBoundsPtrAccessChainKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedInBoundsPtrAccessChainKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Element + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Indexes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedInBoundsPtrAccessChainKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedInBoundsPtrAccessChainKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedInBoundsPtrAccessChainKHR(int resultType, int resultId, int baseType, int baseId, int element, LiteralArray indexes) + { + ResultType = resultType; + ResultId = resultId; + BaseType = baseType; + BaseId = baseId; + Element = element; + Indexes = indexes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedInBoundsPtrAccessChainKHR, ResultType, ResultId, BaseType, BaseId, Element, ..Indexes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "element": + Element = o.ToLiteral(); + break; + case "indexes": + Indexes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Indexes.WordCount == -1) + Indexes = new(); + } + + public static implicit operator OpUntypedInBoundsPtrAccessChainKHR(OpDataIndex odi) => new(odi); + public void Dispose() + { + Indexes.Dispose(); + } +} + +public ref partial struct OpUntypedArrayLengthKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedArrayLengthKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedArrayLengthKHR | (1 << 16); + } + + public OpUntypedArrayLengthKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedArrayLengthKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Structure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Arraymember + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUntypedArrayLengthKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUntypedArrayLengthKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUntypedArrayLengthKHR(int resultType, int resultId, int structure, int pointer, int arraymember) + { + ResultType = resultType; + ResultId = resultId; + Structure = structure; + Pointer = pointer; + Arraymember = arraymember; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedArrayLengthKHR, ResultType, ResultId, Structure, Pointer, ..Arraymember.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "structure": + Structure = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "arraymember": + Arraymember = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUntypedArrayLengthKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUntypedPrefetchKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUntypedPrefetchKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUntypedPrefetchKHR | (1 << 16); + } + + public OpUntypedPrefetchKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUntypedPrefetchKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int PointerType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumBytes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? RW + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Locality + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? CacheType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpUntypedPrefetchKHR(int pointerType, int numBytes, int? rW, int? locality, int? cacheType) + { + PointerType = pointerType; + NumBytes = numBytes; + RW = rW; + Locality = locality; + CacheType = cacheType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUntypedPrefetchKHR, PointerType, NumBytes, ..(RW is null ? (Span)[] : [RW.Value]), ..(Locality is null ? (Span)[] : [Locality.Value]), ..(CacheType is null ? (Span)[] : [CacheType.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "pointerType": + PointerType = o.ToLiteral(); + break; + case "numBytes": + NumBytes = o.ToLiteral(); + break; + case "rW": + if (o.Words.Length > 0) + { + RW = o.ToLiteral(); + } + + break; + case "locality": + if (o.Words.Length > 0) + { + Locality = o.ToLiteral(); + } + + break; + case "cacheType": + if (o.Words.Length > 0) + { + CacheType = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUntypedPrefetchKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAllKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAllKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAllKHR | (1 << 16); + } + + public OpSubgroupAllKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAllKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAllKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAllKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAllKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAllKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAllKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAnyKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAnyKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAnyKHR | (1 << 16); + } + + public OpSubgroupAnyKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAnyKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAnyKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAnyKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAnyKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAnyKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAnyKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAllEqualKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAllEqualKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAllEqualKHR | (1 << 16); + } + + public OpSubgroupAllEqualKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAllEqualKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAllEqualKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAllEqualKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAllEqualKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAllEqualKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAllEqualKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformRotateKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformRotateKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformRotateKHR | (1 << 16); + } + + public OpGroupNonUniformRotateKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformRotateKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Delta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? ClusterSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformRotateKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformRotateKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformRotateKHR(int resultType, int resultId, int execution, int value, int delta, int? clusterSize) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Value = value; + Delta = delta; + ClusterSize = clusterSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformRotateKHR, ResultType, ResultId, Execution, Value, Delta, ..(ClusterSize is null ? (Span)[] : [ClusterSize.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "delta": + Delta = o.ToLiteral(); + break; + case "clusterSize": + if (o.Words.Length > 0) + { + ClusterSize = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformRotateKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupReadInvocationKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupReadInvocationKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupReadInvocationKHR | (1 << 16); + } + + public OpSubgroupReadInvocationKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupReadInvocationKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupReadInvocationKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupReadInvocationKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupReadInvocationKHR(int resultType, int resultId, int value, int index) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + Index = index; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupReadInvocationKHR, ResultType, ResultId, Value, Index]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupReadInvocationKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExtInstWithForwardRefsKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExtInstWithForwardRefsKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInstWithForwardRefsKHR | (1 << 16); + } + + public OpExtInstWithForwardRefsKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExtInstWithForwardRefsKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Instruction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Operands + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpExtInstWithForwardRefsKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpExtInstWithForwardRefsKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpExtInstWithForwardRefsKHR(int resultType, int resultId, int set, int instruction, LiteralArray operands) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Instruction = instruction; + Operands = operands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInstWithForwardRefsKHR, ResultType, ResultId, Set, ..Instruction.AsDisposableLiteralValue().Words, ..Operands.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "instruction": + Instruction = o.ToLiteral(); + break; + case "operands": + Operands = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Operands.WordCount == -1) + Operands = new(); + } + + public static implicit operator OpExtInstWithForwardRefsKHR(OpDataIndex odi) => new(odi); + public void Dispose() + { + Operands.Dispose(); + } +} + +public ref partial struct OpTraceRayKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTraceRayKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTraceRayKHR | (1 << 16); + } + + public OpTraceRayKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTraceRayKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CullMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayOrigin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayDirection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTraceRayKHR(int accel, int rayFlags, int cullMask, int sBTOffset, int sBTStride, int missIndex, int rayOrigin, int rayTmin, int rayDirection, int rayTmax, int payload) + { + Accel = accel; + RayFlags = rayFlags; + CullMask = cullMask; + SBTOffset = sBTOffset; + SBTStride = sBTStride; + MissIndex = missIndex; + RayOrigin = rayOrigin; + RayTmin = rayTmin; + RayDirection = rayDirection; + RayTmax = rayTmax; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTraceRayKHR, Accel, RayFlags, CullMask, SBTOffset, SBTStride, MissIndex, RayOrigin, RayTmin, RayDirection, RayTmax, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "accel": + Accel = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullMask": + CullMask = o.ToLiteral(); + break; + case "sBTOffset": + SBTOffset = o.ToLiteral(); + break; + case "sBTStride": + SBTStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "rayOrigin": + RayOrigin = o.ToLiteral(); + break; + case "rayTmin": + RayTmin = o.ToLiteral(); + break; + case "rayDirection": + RayDirection = o.ToLiteral(); + break; + case "rayTmax": + RayTmax = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTraceRayKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExecuteCallableKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExecuteCallableKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExecuteCallableKHR | (1 << 16); + } + + public OpExecuteCallableKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExecuteCallableKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int SBTIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CallableData + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpExecuteCallableKHR(int sBTIndex, int callableData) + { + SBTIndex = sBTIndex; + CallableData = callableData; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExecuteCallableKHR, SBTIndex, CallableData]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "sBTIndex": + SBTIndex = o.ToLiteral(); + break; + case "callableData": + CallableData = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExecuteCallableKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToAccelerationStructureKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToAccelerationStructureKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToAccelerationStructureKHR | (1 << 16); + } + + public OpConvertUToAccelerationStructureKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToAccelerationStructureKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToAccelerationStructureKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToAccelerationStructureKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToAccelerationStructureKHR(int resultType, int resultId, int accel) + { + ResultType = resultType; + ResultId = resultId; + Accel = accel; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToAccelerationStructureKHR, ResultType, ResultId, Accel]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "accel": + Accel = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToAccelerationStructureKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIgnoreIntersectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIgnoreIntersectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIgnoreIntersectionKHR | (1 << 16); + } + + public OpIgnoreIntersectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIgnoreIntersectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIgnoreIntersectionKHR]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIgnoreIntersectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTerminateRayKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTerminateRayKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTerminateRayKHR | (1 << 16); + } + + public OpTerminateRayKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTerminateRayKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTerminateRayKHR]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTerminateRayKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSDot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSDot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSDot | (1 << 16); + } + + public OpSDot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSDot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSDot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSDot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSDot(int resultType, int resultId, int vector1, int vector2, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSDot, ResultType, ResultId, Vector1, Vector2, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSDot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUDot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUDot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUDot | (1 << 16); + } + + public OpUDot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUDot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUDot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUDot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUDot(int resultType, int resultId, int vector1, int vector2, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUDot, ResultType, ResultId, Vector1, Vector2, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUDot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSUDot : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSUDot() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSUDot | (1 << 16); + } + + public OpSUDot(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSUDot(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSUDot inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSUDot inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSUDot(int resultType, int resultId, int vector1, int vector2, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSUDot, ResultType, ResultId, Vector1, Vector2, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSUDot(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSDotAccSat : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSDotAccSat() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSDotAccSat | (1 << 16); + } + + public OpSDotAccSat(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSDotAccSat(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accumulator + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSDotAccSat inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSDotAccSat inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSDotAccSat(int resultType, int resultId, int vector1, int vector2, int accumulator, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + Accumulator = accumulator; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSDotAccSat, ResultType, ResultId, Vector1, Vector2, Accumulator, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "accumulator": + Accumulator = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSDotAccSat(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUDotAccSat : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUDotAccSat() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUDotAccSat | (1 << 16); + } + + public OpUDotAccSat(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUDotAccSat(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accumulator + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUDotAccSat inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUDotAccSat inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUDotAccSat(int resultType, int resultId, int vector1, int vector2, int accumulator, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + Accumulator = accumulator; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUDotAccSat, ResultType, ResultId, Vector1, Vector2, Accumulator, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "accumulator": + Accumulator = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUDotAccSat(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSUDotAccSat : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSUDotAccSat() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSUDotAccSat | (1 << 16); + } + + public OpSUDotAccSat(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSUDotAccSat(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Vector2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accumulator + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PackedVectorFormat? PackedVectorFormat + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSUDotAccSat inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSUDotAccSat inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSUDotAccSat(int resultType, int resultId, int vector1, int vector2, int accumulator, PackedVectorFormat? packedVectorFormat) + { + ResultType = resultType; + ResultId = resultId; + Vector1 = vector1; + Vector2 = vector2; + Accumulator = accumulator; + PackedVectorFormat = packedVectorFormat; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSUDotAccSat, ResultType, ResultId, Vector1, Vector2, Accumulator, ..(PackedVectorFormat is null ? (Span)[] : [(int)PackedVectorFormat.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "vector1": + Vector1 = o.ToLiteral(); + break; + case "vector2": + Vector2 = o.ToLiteral(); + break; + case "accumulator": + Accumulator = o.ToLiteral(); + break; + case "packedVectorFormat": + if (o.Words.Length > 0) + { + PackedVectorFormat = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSUDotAccSat(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeCooperativeMatrixKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeCooperativeMatrixKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeCooperativeMatrixKHR | (1 << 16); + } + + public OpTypeCooperativeMatrixKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeCooperativeMatrixKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ComponentType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Scope + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Rows + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Columns + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Use + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeCooperativeMatrixKHR inst) => inst.ResultId; + public OpTypeCooperativeMatrixKHR(int resultId, int componentType, int scope, int rows, int columns, int use) + { + ResultId = resultId; + ComponentType = componentType; + Scope = scope; + Rows = rows; + Columns = columns; + Use = use; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeCooperativeMatrixKHR, ResultId, ComponentType, Scope, Rows, Columns, Use]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "componentType": + ComponentType = o.ToLiteral(); + break; + case "scope": + Scope = o.ToLiteral(); + break; + case "rows": + Rows = o.ToLiteral(); + break; + case "columns": + Columns = o.ToLiteral(); + break; + case "use": + Use = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeCooperativeMatrixKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixMulAddKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixMulAddKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixMulAddKHR | (1 << 16); + } + + public OpCooperativeMatrixMulAddKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixMulAddKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int C + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public CooperativeMatrixOperandsMask? CooperativeMatrixOperands + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixMulAddKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixMulAddKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixMulAddKHR(int resultType, int resultId, int a, int b, int c, CooperativeMatrixOperandsMask? cooperativeMatrixOperands) + { + ResultType = resultType; + ResultId = resultId; + A = a; + B = b; + C = c; + CooperativeMatrixOperands = cooperativeMatrixOperands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixMulAddKHR, ResultType, ResultId, A, B, C, ..(CooperativeMatrixOperands is null ? (Span)[] : [(int)CooperativeMatrixOperands.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "c": + C = o.ToLiteral(); + break; + case "cooperativeMatrixOperands": + if (o.Words.Length > 0) + { + CooperativeMatrixOperands = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixMulAddKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixLengthKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixLengthKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixLengthKHR | (1 << 16); + } + + public OpCooperativeMatrixLengthKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixLengthKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Type + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixLengthKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixLengthKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixLengthKHR(int resultType, int resultId, int type) + { + ResultType = resultType; + ResultId = resultId; + Type = type; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixLengthKHR, ResultType, ResultId, Type]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "type": + Type = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixLengthKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantCompositeReplicateEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantCompositeReplicateEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantCompositeReplicateEXT | (1 << 16); + } + + public OpConstantCompositeReplicateEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantCompositeReplicateEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantCompositeReplicateEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantCompositeReplicateEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantCompositeReplicateEXT(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantCompositeReplicateEXT, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantCompositeReplicateEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstantCompositeReplicateEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantCompositeReplicateEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantCompositeReplicateEXT | (1 << 16); + } + + public OpSpecConstantCompositeReplicateEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantCompositeReplicateEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantCompositeReplicateEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSpecConstantCompositeReplicateEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSpecConstantCompositeReplicateEXT(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantCompositeReplicateEXT, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstantCompositeReplicateEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCompositeConstructReplicateEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositeConstructReplicateEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositeConstructReplicateEXT | (1 << 16); + } + + public OpCompositeConstructReplicateEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositeConstructReplicateEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCompositeConstructReplicateEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCompositeConstructReplicateEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCompositeConstructReplicateEXT(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositeConstructReplicateEXT, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCompositeConstructReplicateEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeRayQueryKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeRayQueryKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeRayQueryKHR | (1 << 16); + } + + public OpTypeRayQueryKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeRayQueryKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeRayQueryKHR inst) => inst.ResultId; + public OpTypeRayQueryKHR(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeRayQueryKHR, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeRayQueryKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryInitializeKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryInitializeKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryInitializeKHR | (1 << 16); + } + + public OpRayQueryInitializeKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryInitializeKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CullMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayOrigin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayDirection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRayQueryInitializeKHR(int rayQuery, int accel, int rayFlags, int cullMask, int rayOrigin, int rayTMin, int rayDirection, int rayTMax) + { + RayQuery = rayQuery; + Accel = accel; + RayFlags = rayFlags; + CullMask = cullMask; + RayOrigin = rayOrigin; + RayTMin = rayTMin; + RayDirection = rayDirection; + RayTMax = rayTMax; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryInitializeKHR, RayQuery, Accel, RayFlags, CullMask, RayOrigin, RayTMin, RayDirection, RayTMax]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "accel": + Accel = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullMask": + CullMask = o.ToLiteral(); + break; + case "rayOrigin": + RayOrigin = o.ToLiteral(); + break; + case "rayTMin": + RayTMin = o.ToLiteral(); + break; + case "rayDirection": + RayDirection = o.ToLiteral(); + break; + case "rayTMax": + RayTMax = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryInitializeKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryTerminateKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryTerminateKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryTerminateKHR | (1 << 16); + } + + public OpRayQueryTerminateKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryTerminateKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRayQueryTerminateKHR(int rayQuery) + { + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryTerminateKHR, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryTerminateKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGenerateIntersectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGenerateIntersectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGenerateIntersectionKHR | (1 << 16); + } + + public OpRayQueryGenerateIntersectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGenerateIntersectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitT + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRayQueryGenerateIntersectionKHR(int rayQuery, int hitT) + { + RayQuery = rayQuery; + HitT = hitT; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGenerateIntersectionKHR, RayQuery, HitT]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "hitT": + HitT = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGenerateIntersectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryConfirmIntersectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryConfirmIntersectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryConfirmIntersectionKHR | (1 << 16); + } + + public OpRayQueryConfirmIntersectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryConfirmIntersectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRayQueryConfirmIntersectionKHR(int rayQuery) + { + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryConfirmIntersectionKHR, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryConfirmIntersectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryProceedKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryProceedKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryProceedKHR | (1 << 16); + } + + public OpRayQueryProceedKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryProceedKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryProceedKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryProceedKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryProceedKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryProceedKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryProceedKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionTypeKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionTypeKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionTypeKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionTypeKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionTypeKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionTypeKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionTypeKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionTypeKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionTypeKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionTypeKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageSampleWeightedQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleWeightedQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleWeightedQCOM | (1 << 16); + } + + public OpImageSampleWeightedQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleWeightedQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Texture + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Weights + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleWeightedQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleWeightedQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleWeightedQCOM(int resultType, int resultId, int texture, int coordinates, int weights) + { + ResultType = resultType; + ResultId = resultId; + Texture = texture; + Coordinates = coordinates; + Weights = weights; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleWeightedQCOM, ResultType, ResultId, Texture, Coordinates, Weights]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "texture": + Texture = o.ToLiteral(); + break; + case "coordinates": + Coordinates = o.ToLiteral(); + break; + case "weights": + Weights = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleWeightedQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBoxFilterQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBoxFilterQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBoxFilterQCOM | (1 << 16); + } + + public OpImageBoxFilterQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBoxFilterQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Texture + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BoxSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBoxFilterQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBoxFilterQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBoxFilterQCOM(int resultType, int resultId, int texture, int coordinates, int boxSize) + { + ResultType = resultType; + ResultId = resultId; + Texture = texture; + Coordinates = coordinates; + BoxSize = boxSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBoxFilterQCOM, ResultType, ResultId, Texture, Coordinates, BoxSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "texture": + Texture = o.ToLiteral(); + break; + case "coordinates": + Coordinates = o.ToLiteral(); + break; + case "boxSize": + BoxSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBoxFilterQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchSSDQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchSSDQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchSSDQCOM | (1 << 16); + } + + public OpImageBlockMatchSSDQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchSSDQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Reference + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchSSDQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchSSDQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchSSDQCOM(int resultType, int resultId, int target, int targetCoordinates, int reference, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + Target = target; + TargetCoordinates = targetCoordinates; + Reference = reference; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchSSDQCOM, ResultType, ResultId, Target, TargetCoordinates, Reference, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "target": + Target = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "reference": + Reference = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchSSDQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchSADQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchSADQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchSADQCOM | (1 << 16); + } + + public OpImageBlockMatchSADQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchSADQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Reference + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchSADQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchSADQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchSADQCOM(int resultType, int resultId, int target, int targetCoordinates, int reference, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + Target = target; + TargetCoordinates = targetCoordinates; + Reference = reference; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchSADQCOM, ResultType, ResultId, Target, TargetCoordinates, Reference, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "target": + Target = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "reference": + Reference = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchSADQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchWindowSSDQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchWindowSSDQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchWindowSSDQCOM | (1 << 16); + } + + public OpImageBlockMatchWindowSSDQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchWindowSSDQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchWindowSSDQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchWindowSSDQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchWindowSSDQCOM(int resultType, int resultId, int targetSampledImage, int targetCoordinates, int referenceSampledImage, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + TargetSampledImage = targetSampledImage; + TargetCoordinates = targetCoordinates; + ReferenceSampledImage = referenceSampledImage; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchWindowSSDQCOM, ResultType, ResultId, TargetSampledImage, TargetCoordinates, ReferenceSampledImage, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "targetSampledImage": + TargetSampledImage = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "referenceSampledImage": + ReferenceSampledImage = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchWindowSSDQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchWindowSADQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchWindowSADQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchWindowSADQCOM | (1 << 16); + } + + public OpImageBlockMatchWindowSADQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchWindowSADQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchWindowSADQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchWindowSADQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchWindowSADQCOM(int resultType, int resultId, int targetSampledImage, int targetCoordinates, int referenceSampledImage, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + TargetSampledImage = targetSampledImage; + TargetCoordinates = targetCoordinates; + ReferenceSampledImage = referenceSampledImage; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchWindowSADQCOM, ResultType, ResultId, TargetSampledImage, TargetCoordinates, ReferenceSampledImage, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "targetSampledImage": + TargetSampledImage = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "referenceSampledImage": + ReferenceSampledImage = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchWindowSADQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchGatherSSDQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchGatherSSDQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchGatherSSDQCOM | (1 << 16); + } + + public OpImageBlockMatchGatherSSDQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchGatherSSDQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchGatherSSDQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchGatherSSDQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchGatherSSDQCOM(int resultType, int resultId, int targetSampledImage, int targetCoordinates, int referenceSampledImage, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + TargetSampledImage = targetSampledImage; + TargetCoordinates = targetCoordinates; + ReferenceSampledImage = referenceSampledImage; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchGatherSSDQCOM, ResultType, ResultId, TargetSampledImage, TargetCoordinates, ReferenceSampledImage, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "targetSampledImage": + TargetSampledImage = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "referenceSampledImage": + ReferenceSampledImage = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchGatherSSDQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageBlockMatchGatherSADQCOM : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageBlockMatchGatherSADQCOM() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageBlockMatchGatherSADQCOM | (1 << 16); + } + + public OpImageBlockMatchGatherSADQCOM(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageBlockMatchGatherSADQCOM(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TargetCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceSampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceCoordinates + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageBlockMatchGatherSADQCOM inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageBlockMatchGatherSADQCOM inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageBlockMatchGatherSADQCOM(int resultType, int resultId, int targetSampledImage, int targetCoordinates, int referenceSampledImage, int referenceCoordinates, int blockSize) + { + ResultType = resultType; + ResultId = resultId; + TargetSampledImage = targetSampledImage; + TargetCoordinates = targetCoordinates; + ReferenceSampledImage = referenceSampledImage; + ReferenceCoordinates = referenceCoordinates; + BlockSize = blockSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageBlockMatchGatherSADQCOM, ResultType, ResultId, TargetSampledImage, TargetCoordinates, ReferenceSampledImage, ReferenceCoordinates, BlockSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "targetSampledImage": + TargetSampledImage = o.ToLiteral(); + break; + case "targetCoordinates": + TargetCoordinates = o.ToLiteral(); + break; + case "referenceSampledImage": + ReferenceSampledImage = o.ToLiteral(); + break; + case "referenceCoordinates": + ReferenceCoordinates = o.ToLiteral(); + break; + case "blockSize": + BlockSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageBlockMatchGatherSADQCOM(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupIAddNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupIAddNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupIAddNonUniformAMD | (1 << 16); + } + + public OpGroupIAddNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupIAddNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupIAddNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupIAddNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupIAddNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupIAddNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupIAddNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFAddNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFAddNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFAddNonUniformAMD | (1 << 16); + } + + public OpGroupFAddNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFAddNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFAddNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFAddNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFAddNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFAddNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFAddNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFMinNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFMinNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFMinNonUniformAMD | (1 << 16); + } + + public OpGroupFMinNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFMinNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFMinNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFMinNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFMinNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFMinNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFMinNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupUMinNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupUMinNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupUMinNonUniformAMD | (1 << 16); + } + + public OpGroupUMinNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupUMinNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupUMinNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupUMinNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupUMinNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupUMinNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupUMinNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupSMinNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupSMinNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupSMinNonUniformAMD | (1 << 16); + } + + public OpGroupSMinNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupSMinNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupSMinNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupSMinNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupSMinNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupSMinNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupSMinNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFMaxNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFMaxNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFMaxNonUniformAMD | (1 << 16); + } + + public OpGroupFMaxNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFMaxNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFMaxNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFMaxNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFMaxNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFMaxNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFMaxNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupUMaxNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupUMaxNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupUMaxNonUniformAMD | (1 << 16); + } + + public OpGroupUMaxNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupUMaxNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupUMaxNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupUMaxNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupUMaxNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupUMaxNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupUMaxNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupSMaxNonUniformAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupSMaxNonUniformAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupSMaxNonUniformAMD | (1 << 16); + } + + public OpGroupSMaxNonUniformAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupSMaxNonUniformAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupSMaxNonUniformAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupSMaxNonUniformAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupSMaxNonUniformAMD(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupSMaxNonUniformAMD, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupSMaxNonUniformAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFragmentMaskFetchAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFragmentMaskFetchAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFragmentMaskFetchAMD | (1 << 16); + } + + public OpFragmentMaskFetchAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFragmentMaskFetchAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFragmentMaskFetchAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFragmentMaskFetchAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFragmentMaskFetchAMD(int resultType, int resultId, int image, int coordinate) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFragmentMaskFetchAMD, ResultType, ResultId, Image, Coordinate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFragmentMaskFetchAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFragmentFetchAMD : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFragmentFetchAMD() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFragmentFetchAMD | (1 << 16); + } + + public OpFragmentFetchAMD(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFragmentFetchAMD(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FragmentIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFragmentFetchAMD inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFragmentFetchAMD inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFragmentFetchAMD(int resultType, int resultId, int image, int coordinate, int fragmentIndex) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + FragmentIndex = fragmentIndex; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFragmentFetchAMD, ResultType, ResultId, Image, Coordinate, FragmentIndex]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "fragmentIndex": + FragmentIndex = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFragmentFetchAMD(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReadClockKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReadClockKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReadClockKHR | (1 << 16); + } + + public OpReadClockKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReadClockKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Scope + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReadClockKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReadClockKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReadClockKHR(int resultType, int resultId, int scope) + { + ResultType = resultType; + ResultId = resultId; + Scope = scope; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReadClockKHR, ResultType, ResultId, Scope]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "scope": + Scope = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReadClockKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAllocateNodePayloadsAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAllocateNodePayloadsAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAllocateNodePayloadsAMDX | (1 << 16); + } + + public OpAllocateNodePayloadsAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAllocateNodePayloadsAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Visibility + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NodeIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAllocateNodePayloadsAMDX inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAllocateNodePayloadsAMDX inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAllocateNodePayloadsAMDX(int resultType, int resultId, int visibility, int payloadCount, int nodeIndex) + { + ResultType = resultType; + ResultId = resultId; + Visibility = visibility; + PayloadCount = payloadCount; + NodeIndex = nodeIndex; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAllocateNodePayloadsAMDX, ResultType, ResultId, Visibility, PayloadCount, NodeIndex]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "visibility": + Visibility = o.ToLiteral(); + break; + case "payloadCount": + PayloadCount = o.ToLiteral(); + break; + case "nodeIndex": + NodeIndex = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAllocateNodePayloadsAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEnqueueNodePayloadsAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEnqueueNodePayloadsAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEnqueueNodePayloadsAMDX | (1 << 16); + } + + public OpEnqueueNodePayloadsAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEnqueueNodePayloadsAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int PayloadArray + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEnqueueNodePayloadsAMDX(int payloadArray) + { + PayloadArray = payloadArray; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEnqueueNodePayloadsAMDX, PayloadArray]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "payloadArray": + PayloadArray = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEnqueueNodePayloadsAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeNodePayloadArrayAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeNodePayloadArrayAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeNodePayloadArrayAMDX | (1 << 16); + } + + public OpTypeNodePayloadArrayAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeNodePayloadArrayAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeNodePayloadArrayAMDX inst) => inst.ResultId; + public OpTypeNodePayloadArrayAMDX(int resultId, int payloadType) + { + ResultId = resultId; + PayloadType = payloadType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeNodePayloadArrayAMDX, ResultId, PayloadType]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payloadType": + PayloadType = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeNodePayloadArrayAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFinishWritingNodePayloadAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFinishWritingNodePayloadAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFinishWritingNodePayloadAMDX | (1 << 16); + } + + public OpFinishWritingNodePayloadAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFinishWritingNodePayloadAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFinishWritingNodePayloadAMDX inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFinishWritingNodePayloadAMDX inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFinishWritingNodePayloadAMDX(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFinishWritingNodePayloadAMDX, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFinishWritingNodePayloadAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpNodePayloadArrayLengthAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpNodePayloadArrayLengthAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpNodePayloadArrayLengthAMDX | (1 << 16); + } + + public OpNodePayloadArrayLengthAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpNodePayloadArrayLengthAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadArray + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpNodePayloadArrayLengthAMDX inst) => inst.ResultId; + public static implicit operator SpirvValue(OpNodePayloadArrayLengthAMDX inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpNodePayloadArrayLengthAMDX(int resultType, int resultId, int payloadArray) + { + ResultType = resultType; + ResultId = resultId; + PayloadArray = payloadArray; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpNodePayloadArrayLengthAMDX, ResultType, ResultId, PayloadArray]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payloadArray": + PayloadArray = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpNodePayloadArrayLengthAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsNodePayloadValidAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsNodePayloadValidAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsNodePayloadValidAMDX | (1 << 16); + } + + public OpIsNodePayloadValidAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsNodePayloadValidAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NodeIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsNodePayloadValidAMDX inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsNodePayloadValidAMDX inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsNodePayloadValidAMDX(int resultType, int resultId, int payloadType, int nodeIndex) + { + ResultType = resultType; + ResultId = resultId; + PayloadType = payloadType; + NodeIndex = nodeIndex; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsNodePayloadValidAMDX, ResultType, ResultId, PayloadType, NodeIndex]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payloadType": + PayloadType = o.ToLiteral(); + break; + case "nodeIndex": + NodeIndex = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsNodePayloadValidAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantStringAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantStringAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantStringAMDX | (1 << 16); + } + + public OpConstantStringAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantStringAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string LiteralString + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantStringAMDX inst) => inst.ResultId; + public OpConstantStringAMDX(int resultId, string literalString) + { + ResultId = resultId; + LiteralString = literalString; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantStringAMDX, ResultId, ..LiteralString.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "literalString": + LiteralString = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantStringAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSpecConstantStringAMDX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantStringAMDX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantStringAMDX | (1 << 16); + } + + public OpSpecConstantStringAMDX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantStringAMDX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string LiteralString + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSpecConstantStringAMDX inst) => inst.ResultId; + public OpSpecConstantStringAMDX(int resultId, string literalString) + { + ResultId = resultId; + LiteralString = literalString; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantStringAMDX, ResultId, ..LiteralString.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "literalString": + LiteralString = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSpecConstantStringAMDX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformQuadAllKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformQuadAllKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformQuadAllKHR | (1 << 16); + } + + public OpGroupNonUniformQuadAllKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformQuadAllKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformQuadAllKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformQuadAllKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformQuadAllKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformQuadAllKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformQuadAllKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformQuadAnyKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformQuadAnyKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformQuadAnyKHR | (1 << 16); + } + + public OpGroupNonUniformQuadAnyKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformQuadAnyKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Predicate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformQuadAnyKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformQuadAnyKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformQuadAnyKHR(int resultType, int resultId, int predicate) + { + ResultType = resultType; + ResultId = resultId; + Predicate = predicate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformQuadAnyKHR, ResultType, ResultId, Predicate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "predicate": + Predicate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformQuadAnyKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordHitMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordHitMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordHitMotionNV | (1 << 16); + } + + public OpHitObjectRecordHitMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordHitMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitKind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CurrentTime + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObjectAttributes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordHitMotionNV(int hitObject, int accelerationStructure, int instanceId, int primitiveId, int geometryIndex, int hitKind, int sBTRecordOffset, int sBTRecordStride, int origin, int tMin, int direction, int tMax, int currentTime, int hitObjectAttributes) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + InstanceId = instanceId; + PrimitiveId = primitiveId; + GeometryIndex = geometryIndex; + HitKind = hitKind; + SBTRecordOffset = sBTRecordOffset; + SBTRecordStride = sBTRecordStride; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + CurrentTime = currentTime; + HitObjectAttributes = hitObjectAttributes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordHitMotionNV, HitObject, AccelerationStructure, InstanceId, PrimitiveId, GeometryIndex, HitKind, SBTRecordOffset, SBTRecordStride, Origin, TMin, Direction, TMax, CurrentTime, HitObjectAttributes]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "primitiveId": + PrimitiveId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "hitKind": + HitKind = o.ToLiteral(); + break; + case "sBTRecordOffset": + SBTRecordOffset = o.ToLiteral(); + break; + case "sBTRecordStride": + SBTRecordStride = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "currentTime": + CurrentTime = o.ToLiteral(); + break; + case "hitObjectAttributes": + HitObjectAttributes = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordHitMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordHitWithIndexMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordHitWithIndexMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordHitWithIndexMotionNV | (1 << 16); + } + + public OpHitObjectRecordHitWithIndexMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordHitWithIndexMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitKind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CurrentTime + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObjectAttributes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordHitWithIndexMotionNV(int hitObject, int accelerationStructure, int instanceId, int primitiveId, int geometryIndex, int hitKind, int sBTRecordIndex, int origin, int tMin, int direction, int tMax, int currentTime, int hitObjectAttributes) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + InstanceId = instanceId; + PrimitiveId = primitiveId; + GeometryIndex = geometryIndex; + HitKind = hitKind; + SBTRecordIndex = sBTRecordIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + CurrentTime = currentTime; + HitObjectAttributes = hitObjectAttributes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordHitWithIndexMotionNV, HitObject, AccelerationStructure, InstanceId, PrimitiveId, GeometryIndex, HitKind, SBTRecordIndex, Origin, TMin, Direction, TMax, CurrentTime, HitObjectAttributes]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "primitiveId": + PrimitiveId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "hitKind": + HitKind = o.ToLiteral(); + break; + case "sBTRecordIndex": + SBTRecordIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "currentTime": + CurrentTime = o.ToLiteral(); + break; + case "hitObjectAttributes": + HitObjectAttributes = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordHitWithIndexMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordMissMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordMissMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordMissMotionNV | (1 << 16); + } + + public OpHitObjectRecordMissMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordMissMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CurrentTime + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordMissMotionNV(int hitObject, int sBTIndex, int origin, int tMin, int direction, int tMax, int currentTime) + { + HitObject = hitObject; + SBTIndex = sBTIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + CurrentTime = currentTime; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordMissMotionNV, HitObject, SBTIndex, Origin, TMin, Direction, TMax, CurrentTime]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "sBTIndex": + SBTIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "currentTime": + CurrentTime = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordMissMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetWorldToObjectNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetWorldToObjectNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetWorldToObjectNV | (1 << 16); + } + + public OpHitObjectGetWorldToObjectNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetWorldToObjectNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetWorldToObjectNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetWorldToObjectNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetWorldToObjectNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetWorldToObjectNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetWorldToObjectNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetObjectToWorldNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetObjectToWorldNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetObjectToWorldNV | (1 << 16); + } + + public OpHitObjectGetObjectToWorldNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetObjectToWorldNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetObjectToWorldNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetObjectToWorldNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetObjectToWorldNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetObjectToWorldNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetObjectToWorldNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetObjectRayDirectionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetObjectRayDirectionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetObjectRayDirectionNV | (1 << 16); + } + + public OpHitObjectGetObjectRayDirectionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetObjectRayDirectionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetObjectRayDirectionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetObjectRayDirectionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetObjectRayDirectionNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetObjectRayDirectionNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetObjectRayDirectionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetObjectRayOriginNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetObjectRayOriginNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetObjectRayOriginNV | (1 << 16); + } + + public OpHitObjectGetObjectRayOriginNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetObjectRayOriginNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetObjectRayOriginNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetObjectRayOriginNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetObjectRayOriginNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetObjectRayOriginNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetObjectRayOriginNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectTraceRayMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectTraceRayMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectTraceRayMotionNV | (1 << 16); + } + + public OpHitObjectTraceRayMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectTraceRayMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Cullmask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Time + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectTraceRayMotionNV(int hitObject, int accelerationStructure, int rayFlags, int cullmask, int sBTRecordOffset, int sBTRecordStride, int missIndex, int origin, int tMin, int direction, int tMax, int time, int payload) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + RayFlags = rayFlags; + Cullmask = cullmask; + SBTRecordOffset = sBTRecordOffset; + SBTRecordStride = sBTRecordStride; + MissIndex = missIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + Time = time; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectTraceRayMotionNV, HitObject, AccelerationStructure, RayFlags, Cullmask, SBTRecordOffset, SBTRecordStride, MissIndex, Origin, TMin, Direction, TMax, Time, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullmask": + Cullmask = o.ToLiteral(); + break; + case "sBTRecordOffset": + SBTRecordOffset = o.ToLiteral(); + break; + case "sBTRecordStride": + SBTRecordStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "time": + Time = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectTraceRayMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetShaderRecordBufferHandleNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetShaderRecordBufferHandleNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetShaderRecordBufferHandleNV | (1 << 16); + } + + public OpHitObjectGetShaderRecordBufferHandleNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetShaderRecordBufferHandleNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetShaderRecordBufferHandleNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetShaderRecordBufferHandleNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetShaderRecordBufferHandleNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetShaderRecordBufferHandleNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetShaderRecordBufferHandleNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetShaderBindingTableRecordIndexNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetShaderBindingTableRecordIndexNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetShaderBindingTableRecordIndexNV | (1 << 16); + } + + public OpHitObjectGetShaderBindingTableRecordIndexNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetShaderBindingTableRecordIndexNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetShaderBindingTableRecordIndexNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetShaderBindingTableRecordIndexNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetShaderBindingTableRecordIndexNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetShaderBindingTableRecordIndexNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetShaderBindingTableRecordIndexNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordEmptyNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordEmptyNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordEmptyNV | (1 << 16); + } + + public OpHitObjectRecordEmptyNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordEmptyNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordEmptyNV(int hitObject) + { + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordEmptyNV, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordEmptyNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectTraceRayNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectTraceRayNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectTraceRayNV | (1 << 16); + } + + public OpHitObjectTraceRayNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectTraceRayNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Cullmask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectTraceRayNV(int hitObject, int accelerationStructure, int rayFlags, int cullmask, int sBTRecordOffset, int sBTRecordStride, int missIndex, int origin, int tMin, int direction, int tMax, int payload) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + RayFlags = rayFlags; + Cullmask = cullmask; + SBTRecordOffset = sBTRecordOffset; + SBTRecordStride = sBTRecordStride; + MissIndex = missIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectTraceRayNV, HitObject, AccelerationStructure, RayFlags, Cullmask, SBTRecordOffset, SBTRecordStride, MissIndex, Origin, TMin, Direction, TMax, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullmask": + Cullmask = o.ToLiteral(); + break; + case "sBTRecordOffset": + SBTRecordOffset = o.ToLiteral(); + break; + case "sBTRecordStride": + SBTRecordStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectTraceRayNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordHitNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordHitNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordHitNV | (1 << 16); + } + + public OpHitObjectRecordHitNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordHitNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitKind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObjectAttributes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordHitNV(int hitObject, int accelerationStructure, int instanceId, int primitiveId, int geometryIndex, int hitKind, int sBTRecordOffset, int sBTRecordStride, int origin, int tMin, int direction, int tMax, int hitObjectAttributes) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + InstanceId = instanceId; + PrimitiveId = primitiveId; + GeometryIndex = geometryIndex; + HitKind = hitKind; + SBTRecordOffset = sBTRecordOffset; + SBTRecordStride = sBTRecordStride; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + HitObjectAttributes = hitObjectAttributes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordHitNV, HitObject, AccelerationStructure, InstanceId, PrimitiveId, GeometryIndex, HitKind, SBTRecordOffset, SBTRecordStride, Origin, TMin, Direction, TMax, HitObjectAttributes]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "primitiveId": + PrimitiveId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "hitKind": + HitKind = o.ToLiteral(); + break; + case "sBTRecordOffset": + SBTRecordOffset = o.ToLiteral(); + break; + case "sBTRecordStride": + SBTRecordStride = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "hitObjectAttributes": + HitObjectAttributes = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordHitNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordHitWithIndexNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordHitWithIndexNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordHitWithIndexNV | (1 << 16); + } + + public OpHitObjectRecordHitWithIndexNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordHitWithIndexNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AccelerationStructure + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitKind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTRecordIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObjectAttributes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordHitWithIndexNV(int hitObject, int accelerationStructure, int instanceId, int primitiveId, int geometryIndex, int hitKind, int sBTRecordIndex, int origin, int tMin, int direction, int tMax, int hitObjectAttributes) + { + HitObject = hitObject; + AccelerationStructure = accelerationStructure; + InstanceId = instanceId; + PrimitiveId = primitiveId; + GeometryIndex = geometryIndex; + HitKind = hitKind; + SBTRecordIndex = sBTRecordIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + HitObjectAttributes = hitObjectAttributes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordHitWithIndexNV, HitObject, AccelerationStructure, InstanceId, PrimitiveId, GeometryIndex, HitKind, SBTRecordIndex, Origin, TMin, Direction, TMax, HitObjectAttributes]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "accelerationStructure": + AccelerationStructure = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "primitiveId": + PrimitiveId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "hitKind": + HitKind = o.ToLiteral(); + break; + case "sBTRecordIndex": + SBTRecordIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + case "hitObjectAttributes": + HitObjectAttributes = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordHitWithIndexNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectRecordMissNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectRecordMissNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectRecordMissNV | (1 << 16); + } + + public OpHitObjectRecordMissNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectRecordMissNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Origin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TMax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectRecordMissNV(int hitObject, int sBTIndex, int origin, int tMin, int direction, int tMax) + { + HitObject = hitObject; + SBTIndex = sBTIndex; + Origin = origin; + TMin = tMin; + Direction = direction; + TMax = tMax; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectRecordMissNV, HitObject, SBTIndex, Origin, TMin, Direction, TMax]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "sBTIndex": + SBTIndex = o.ToLiteral(); + break; + case "origin": + Origin = o.ToLiteral(); + break; + case "tMin": + TMin = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "tMax": + TMax = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectRecordMissNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectExecuteShaderNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectExecuteShaderNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectExecuteShaderNV | (1 << 16); + } + + public OpHitObjectExecuteShaderNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectExecuteShaderNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectExecuteShaderNV(int hitObject, int payload) + { + HitObject = hitObject; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectExecuteShaderNV, HitObject, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectExecuteShaderNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetCurrentTimeNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetCurrentTimeNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetCurrentTimeNV | (1 << 16); + } + + public OpHitObjectGetCurrentTimeNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetCurrentTimeNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetCurrentTimeNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetCurrentTimeNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetCurrentTimeNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetCurrentTimeNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetCurrentTimeNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetAttributesNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetAttributesNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetAttributesNV | (1 << 16); + } + + public OpHitObjectGetAttributesNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetAttributesNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObjectAttribute + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpHitObjectGetAttributesNV(int hitObject, int hitObjectAttribute) + { + HitObject = hitObject; + HitObjectAttribute = hitObjectAttribute; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetAttributesNV, HitObject, HitObjectAttribute]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "hitObjectAttribute": + HitObjectAttribute = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetAttributesNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetHitKindNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetHitKindNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetHitKindNV | (1 << 16); + } + + public OpHitObjectGetHitKindNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetHitKindNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetHitKindNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetHitKindNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetHitKindNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetHitKindNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetHitKindNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetPrimitiveIndexNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetPrimitiveIndexNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetPrimitiveIndexNV | (1 << 16); + } + + public OpHitObjectGetPrimitiveIndexNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetPrimitiveIndexNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetPrimitiveIndexNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetPrimitiveIndexNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetPrimitiveIndexNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetPrimitiveIndexNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetPrimitiveIndexNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetGeometryIndexNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetGeometryIndexNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetGeometryIndexNV | (1 << 16); + } + + public OpHitObjectGetGeometryIndexNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetGeometryIndexNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetGeometryIndexNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetGeometryIndexNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetGeometryIndexNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetGeometryIndexNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetGeometryIndexNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetInstanceIdNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetInstanceIdNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetInstanceIdNV | (1 << 16); + } + + public OpHitObjectGetInstanceIdNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetInstanceIdNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetInstanceIdNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetInstanceIdNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetInstanceIdNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetInstanceIdNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetInstanceIdNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetInstanceCustomIndexNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetInstanceCustomIndexNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetInstanceCustomIndexNV | (1 << 16); + } + + public OpHitObjectGetInstanceCustomIndexNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetInstanceCustomIndexNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetInstanceCustomIndexNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetInstanceCustomIndexNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetInstanceCustomIndexNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetInstanceCustomIndexNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetInstanceCustomIndexNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetWorldRayDirectionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetWorldRayDirectionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetWorldRayDirectionNV | (1 << 16); + } + + public OpHitObjectGetWorldRayDirectionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetWorldRayDirectionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetWorldRayDirectionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetWorldRayDirectionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetWorldRayDirectionNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetWorldRayDirectionNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetWorldRayDirectionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetWorldRayOriginNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetWorldRayOriginNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetWorldRayOriginNV | (1 << 16); + } + + public OpHitObjectGetWorldRayOriginNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetWorldRayOriginNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetWorldRayOriginNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetWorldRayOriginNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetWorldRayOriginNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetWorldRayOriginNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetWorldRayOriginNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetRayTMaxNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetRayTMaxNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetRayTMaxNV | (1 << 16); + } + + public OpHitObjectGetRayTMaxNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetRayTMaxNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetRayTMaxNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetRayTMaxNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetRayTMaxNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetRayTMaxNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetRayTMaxNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectGetRayTMinNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectGetRayTMinNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectGetRayTMinNV | (1 << 16); + } + + public OpHitObjectGetRayTMinNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectGetRayTMinNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectGetRayTMinNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectGetRayTMinNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectGetRayTMinNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectGetRayTMinNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectGetRayTMinNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectIsEmptyNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectIsEmptyNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectIsEmptyNV | (1 << 16); + } + + public OpHitObjectIsEmptyNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectIsEmptyNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectIsEmptyNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectIsEmptyNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectIsEmptyNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectIsEmptyNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectIsEmptyNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectIsHitNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectIsHitNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectIsHitNV | (1 << 16); + } + + public OpHitObjectIsHitNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectIsHitNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectIsHitNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectIsHitNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectIsHitNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectIsHitNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectIsHitNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpHitObjectIsMissNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpHitObjectIsMissNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpHitObjectIsMissNV | (1 << 16); + } + + public OpHitObjectIsMissNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpHitObjectIsMissNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpHitObjectIsMissNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpHitObjectIsMissNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpHitObjectIsMissNV(int resultType, int resultId, int hitObject) + { + ResultType = resultType; + ResultId = resultId; + HitObject = hitObject; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpHitObjectIsMissNV, ResultType, ResultId, HitObject]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hitObject": + HitObject = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpHitObjectIsMissNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReorderThreadWithHitObjectNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReorderThreadWithHitObjectNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReorderThreadWithHitObjectNV | (1 << 16); + } + + public OpReorderThreadWithHitObjectNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReorderThreadWithHitObjectNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int HitObject + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Hint + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Bits + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpReorderThreadWithHitObjectNV(int hitObject, int? hint, int? bits) + { + HitObject = hitObject; + Hint = hint; + Bits = bits; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReorderThreadWithHitObjectNV, HitObject, ..(Hint is null ? (Span)[] : [Hint.Value]), ..(Bits is null ? (Span)[] : [Bits.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hitObject": + HitObject = o.ToLiteral(); + break; + case "hint": + if (o.Words.Length > 0) + { + Hint = o.ToLiteral(); + } + + break; + case "bits": + if (o.Words.Length > 0) + { + Bits = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReorderThreadWithHitObjectNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReorderThreadWithHintNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReorderThreadWithHintNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReorderThreadWithHintNV | (1 << 16); + } + + public OpReorderThreadWithHintNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReorderThreadWithHintNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Hint + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Bits + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpReorderThreadWithHintNV(int hint, int bits) + { + Hint = hint; + Bits = bits; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReorderThreadWithHintNV, Hint, Bits]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "hint": + Hint = o.ToLiteral(); + break; + case "bits": + Bits = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReorderThreadWithHintNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeHitObjectNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeHitObjectNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeHitObjectNV | (1 << 16); + } + + public OpTypeHitObjectNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeHitObjectNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeHitObjectNV inst) => inst.ResultId; + public OpTypeHitObjectNV(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeHitObjectNV, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeHitObjectNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImageSampleFootprintNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImageSampleFootprintNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImageSampleFootprintNV | (1 << 16); + } + + public OpImageSampleFootprintNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImageSampleFootprintNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SampledImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Granularity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coarse + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public ImageOperandsMask? ImageOperands { get; set; } + + public EnumerantParameters ImageOperandsParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImageSampleFootprintNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImageSampleFootprintNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImageSampleFootprintNV(int resultType, int resultId, int sampledImage, int coordinate, int granularity, int coarse, ImageOperandsMask? imageOperands, EnumerantParameters imageOperandsParameters) + { + ResultType = resultType; + ResultId = resultId; + SampledImage = sampledImage; + Coordinate = coordinate; + Granularity = granularity; + Coarse = coarse; + ImageOperands = imageOperands; + ImageOperandsParameters = imageOperandsParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImageSampleFootprintNV, ResultType, ResultId, SampledImage, Coordinate, Granularity, Coarse, ..(ImageOperands is null ? (Span)[] : [(int)ImageOperands.Value, ..ImageOperandsParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sampledImage": + SampledImage = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "granularity": + Granularity = o.ToLiteral(); + break; + case "coarse": + Coarse = o.ToLiteral(); + break; + case "imageOperands": + if (o.Words.Length > 0) + { + ImageOperands = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + ImageOperandsParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImageSampleFootprintNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + ImageOperandsParameters.Dispose(); + } +} + +public ref partial struct OpCooperativeMatrixConvertNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixConvertNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixConvertNV | (1 << 16); + } + + public OpCooperativeMatrixConvertNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixConvertNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixConvertNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixConvertNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixConvertNV(int resultType, int resultId, int matrix) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixConvertNV, ResultType, ResultId, Matrix]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixConvertNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEmitMeshTasksEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEmitMeshTasksEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEmitMeshTasksEXT | (1 << 16); + } + + public OpEmitMeshTasksEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEmitMeshTasksEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int GroupCountX + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GroupCountY + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GroupCountZ + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEmitMeshTasksEXT(int groupCountX, int groupCountY, int groupCountZ, int? payload) + { + GroupCountX = groupCountX; + GroupCountY = groupCountY; + GroupCountZ = groupCountZ; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEmitMeshTasksEXT, GroupCountX, GroupCountY, GroupCountZ, ..(Payload is null ? (Span)[] : [Payload.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "groupCountX": + GroupCountX = o.ToLiteral(); + break; + case "groupCountY": + GroupCountY = o.ToLiteral(); + break; + case "groupCountZ": + GroupCountZ = o.ToLiteral(); + break; + case "payload": + if (o.Words.Length > 0) + { + Payload = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEmitMeshTasksEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSetMeshOutputsEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSetMeshOutputsEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSetMeshOutputsEXT | (1 << 16); + } + + public OpSetMeshOutputsEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSetMeshOutputsEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int VertexCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSetMeshOutputsEXT(int vertexCount, int primitiveCount) + { + VertexCount = vertexCount; + PrimitiveCount = primitiveCount; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSetMeshOutputsEXT, VertexCount, PrimitiveCount]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "vertexCount": + VertexCount = o.ToLiteral(); + break; + case "primitiveCount": + PrimitiveCount = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSetMeshOutputsEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupNonUniformPartitionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupNonUniformPartitionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupNonUniformPartitionNV | (1 << 16); + } + + public OpGroupNonUniformPartitionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupNonUniformPartitionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupNonUniformPartitionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupNonUniformPartitionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupNonUniformPartitionNV(int resultType, int resultId, int value) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupNonUniformPartitionNV, ResultType, ResultId, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupNonUniformPartitionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpWritePackedPrimitiveIndices4x8NV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpWritePackedPrimitiveIndices4x8NV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpWritePackedPrimitiveIndices4x8NV | (1 << 16); + } + + public OpWritePackedPrimitiveIndices4x8NV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpWritePackedPrimitiveIndices4x8NV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int IndexOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedIndices + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpWritePackedPrimitiveIndices4x8NV(int indexOffset, int packedIndices) + { + IndexOffset = indexOffset; + PackedIndices = packedIndices; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpWritePackedPrimitiveIndices4x8NV, IndexOffset, PackedIndices]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "indexOffset": + IndexOffset = o.ToLiteral(); + break; + case "packedIndices": + PackedIndices = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpWritePackedPrimitiveIndices4x8NV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFetchMicroTriangleVertexPositionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFetchMicroTriangleVertexPositionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFetchMicroTriangleVertexPositionNV | (1 << 16); + } + + public OpFetchMicroTriangleVertexPositionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFetchMicroTriangleVertexPositionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Barycentric + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFetchMicroTriangleVertexPositionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFetchMicroTriangleVertexPositionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFetchMicroTriangleVertexPositionNV(int resultType, int resultId, int accel, int instanceId, int geometryIndex, int primitiveIndex, int barycentric) + { + ResultType = resultType; + ResultId = resultId; + Accel = accel; + InstanceId = instanceId; + GeometryIndex = geometryIndex; + PrimitiveIndex = primitiveIndex; + Barycentric = barycentric; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFetchMicroTriangleVertexPositionNV, ResultType, ResultId, Accel, InstanceId, GeometryIndex, PrimitiveIndex, Barycentric]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "accel": + Accel = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "primitiveIndex": + PrimitiveIndex = o.ToLiteral(); + break; + case "barycentric": + Barycentric = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFetchMicroTriangleVertexPositionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFetchMicroTriangleVertexBarycentricNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFetchMicroTriangleVertexBarycentricNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFetchMicroTriangleVertexBarycentricNV | (1 << 16); + } + + public OpFetchMicroTriangleVertexBarycentricNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFetchMicroTriangleVertexBarycentricNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InstanceId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int GeometryIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PrimitiveIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Barycentric + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFetchMicroTriangleVertexBarycentricNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFetchMicroTriangleVertexBarycentricNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFetchMicroTriangleVertexBarycentricNV(int resultType, int resultId, int accel, int instanceId, int geometryIndex, int primitiveIndex, int barycentric) + { + ResultType = resultType; + ResultId = resultId; + Accel = accel; + InstanceId = instanceId; + GeometryIndex = geometryIndex; + PrimitiveIndex = primitiveIndex; + Barycentric = barycentric; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFetchMicroTriangleVertexBarycentricNV, ResultType, ResultId, Accel, InstanceId, GeometryIndex, PrimitiveIndex, Barycentric]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "accel": + Accel = o.ToLiteral(); + break; + case "instanceId": + InstanceId = o.ToLiteral(); + break; + case "geometryIndex": + GeometryIndex = o.ToLiteral(); + break; + case "primitiveIndex": + PrimitiveIndex = o.ToLiteral(); + break; + case "barycentric": + Barycentric = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFetchMicroTriangleVertexBarycentricNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReportIntersectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReportIntersectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReportIntersectionKHR | (1 << 16); + } + + public OpReportIntersectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReportIntersectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Hit + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HitKind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReportIntersectionKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReportIntersectionKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReportIntersectionKHR(int resultType, int resultId, int hit, int hitKind) + { + ResultType = resultType; + ResultId = resultId; + Hit = hit; + HitKind = hitKind; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReportIntersectionKHR, ResultType, ResultId, Hit, HitKind]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "hit": + Hit = o.ToLiteral(); + break; + case "hitKind": + HitKind = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReportIntersectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIgnoreIntersectionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIgnoreIntersectionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIgnoreIntersectionNV | (1 << 16); + } + + public OpIgnoreIntersectionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIgnoreIntersectionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIgnoreIntersectionNV]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIgnoreIntersectionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTerminateRayNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTerminateRayNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTerminateRayNV | (1 << 16); + } + + public OpTerminateRayNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTerminateRayNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTerminateRayNV]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTerminateRayNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTraceNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTraceNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTraceNV | (1 << 16); + } + + public OpTraceNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTraceNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CullMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayOrigin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayDirection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTraceNV(int accel, int rayFlags, int cullMask, int sBTOffset, int sBTStride, int missIndex, int rayOrigin, int rayTmin, int rayDirection, int rayTmax, int payloadId) + { + Accel = accel; + RayFlags = rayFlags; + CullMask = cullMask; + SBTOffset = sBTOffset; + SBTStride = sBTStride; + MissIndex = missIndex; + RayOrigin = rayOrigin; + RayTmin = rayTmin; + RayDirection = rayDirection; + RayTmax = rayTmax; + PayloadId = payloadId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTraceNV, Accel, RayFlags, CullMask, SBTOffset, SBTStride, MissIndex, RayOrigin, RayTmin, RayDirection, RayTmax, PayloadId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "accel": + Accel = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullMask": + CullMask = o.ToLiteral(); + break; + case "sBTOffset": + SBTOffset = o.ToLiteral(); + break; + case "sBTStride": + SBTStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "rayOrigin": + RayOrigin = o.ToLiteral(); + break; + case "rayTmin": + RayTmin = o.ToLiteral(); + break; + case "rayDirection": + RayDirection = o.ToLiteral(); + break; + case "rayTmax": + RayTmax = o.ToLiteral(); + break; + case "payloadId": + PayloadId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTraceNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTraceMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTraceMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTraceMotionNV | (1 << 16); + } + + public OpTraceMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTraceMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CullMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayOrigin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayDirection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Time + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PayloadId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTraceMotionNV(int accel, int rayFlags, int cullMask, int sBTOffset, int sBTStride, int missIndex, int rayOrigin, int rayTmin, int rayDirection, int rayTmax, int time, int payloadId) + { + Accel = accel; + RayFlags = rayFlags; + CullMask = cullMask; + SBTOffset = sBTOffset; + SBTStride = sBTStride; + MissIndex = missIndex; + RayOrigin = rayOrigin; + RayTmin = rayTmin; + RayDirection = rayDirection; + RayTmax = rayTmax; + Time = time; + PayloadId = payloadId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTraceMotionNV, Accel, RayFlags, CullMask, SBTOffset, SBTStride, MissIndex, RayOrigin, RayTmin, RayDirection, RayTmax, Time, PayloadId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "accel": + Accel = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullMask": + CullMask = o.ToLiteral(); + break; + case "sBTOffset": + SBTOffset = o.ToLiteral(); + break; + case "sBTStride": + SBTStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "rayOrigin": + RayOrigin = o.ToLiteral(); + break; + case "rayTmin": + RayTmin = o.ToLiteral(); + break; + case "rayDirection": + RayDirection = o.ToLiteral(); + break; + case "rayTmax": + RayTmax = o.ToLiteral(); + break; + case "time": + Time = o.ToLiteral(); + break; + case "payloadId": + PayloadId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTraceMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTraceRayMotionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTraceRayMotionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTraceRayMotionNV | (1 << 16); + } + + public OpTraceRayMotionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTraceRayMotionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Accel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayFlags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CullMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SBTStride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MissIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayOrigin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmin + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayDirection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayTmax + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Time + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTraceRayMotionNV(int accel, int rayFlags, int cullMask, int sBTOffset, int sBTStride, int missIndex, int rayOrigin, int rayTmin, int rayDirection, int rayTmax, int time, int payload) + { + Accel = accel; + RayFlags = rayFlags; + CullMask = cullMask; + SBTOffset = sBTOffset; + SBTStride = sBTStride; + MissIndex = missIndex; + RayOrigin = rayOrigin; + RayTmin = rayTmin; + RayDirection = rayDirection; + RayTmax = rayTmax; + Time = time; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTraceRayMotionNV, Accel, RayFlags, CullMask, SBTOffset, SBTStride, MissIndex, RayOrigin, RayTmin, RayDirection, RayTmax, Time, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "accel": + Accel = o.ToLiteral(); + break; + case "rayFlags": + RayFlags = o.ToLiteral(); + break; + case "cullMask": + CullMask = o.ToLiteral(); + break; + case "sBTOffset": + SBTOffset = o.ToLiteral(); + break; + case "sBTStride": + SBTStride = o.ToLiteral(); + break; + case "missIndex": + MissIndex = o.ToLiteral(); + break; + case "rayOrigin": + RayOrigin = o.ToLiteral(); + break; + case "rayTmin": + RayTmin = o.ToLiteral(); + break; + case "rayDirection": + RayDirection = o.ToLiteral(); + break; + case "rayTmax": + RayTmax = o.ToLiteral(); + break; + case "time": + Time = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTraceRayMotionNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionTriangleVertexPositionsKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionTriangleVertexPositionsKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionTriangleVertexPositionsKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionTriangleVertexPositionsKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionTriangleVertexPositionsKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionTriangleVertexPositionsKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionTriangleVertexPositionsKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionTriangleVertexPositionsKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionTriangleVertexPositionsKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAccelerationStructureKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAccelerationStructureKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAccelerationStructureKHR | (1 << 16); + } + + public OpTypeAccelerationStructureKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAccelerationStructureKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAccelerationStructureKHR inst) => inst.ResultId; + public OpTypeAccelerationStructureKHR(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAccelerationStructureKHR, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAccelerationStructureKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExecuteCallableNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExecuteCallableNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExecuteCallableNV | (1 << 16); + } + + public OpExecuteCallableNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExecuteCallableNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int SBTIndex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CallableDataId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpExecuteCallableNV(int sBTIndex, int callableDataId) + { + SBTIndex = sBTIndex; + CallableDataId = callableDataId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExecuteCallableNV, SBTIndex, CallableDataId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "sBTIndex": + SBTIndex = o.ToLiteral(); + break; + case "callableDataId": + CallableDataId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExecuteCallableNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeCooperativeMatrixNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeCooperativeMatrixNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeCooperativeMatrixNV | (1 << 16); + } + + public OpTypeCooperativeMatrixNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeCooperativeMatrixNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ComponentType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Rows + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Columns + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeCooperativeMatrixNV inst) => inst.ResultId; + public OpTypeCooperativeMatrixNV(int resultId, int componentType, int execution, int rows, int columns) + { + ResultId = resultId; + ComponentType = componentType; + Execution = execution; + Rows = rows; + Columns = columns; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeCooperativeMatrixNV, ResultId, ComponentType, Execution, Rows, Columns]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "componentType": + ComponentType = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "rows": + Rows = o.ToLiteral(); + break; + case "columns": + Columns = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeCooperativeMatrixNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixMulAddNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixMulAddNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixMulAddNV | (1 << 16); + } + + public OpCooperativeMatrixMulAddNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixMulAddNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int C + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixMulAddNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixMulAddNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixMulAddNV(int resultType, int resultId, int a, int b, int c) + { + ResultType = resultType; + ResultId = resultId; + A = a; + B = b; + C = c; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixMulAddNV, ResultType, ResultId, A, B, C]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "c": + C = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixMulAddNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixLengthNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixLengthNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixLengthNV | (1 << 16); + } + + public OpCooperativeMatrixLengthNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixLengthNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Type + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixLengthNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixLengthNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixLengthNV(int resultType, int resultId, int type) + { + ResultType = resultType; + ResultId = resultId; + Type = type; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixLengthNV, ResultType, ResultId, Type]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "type": + Type = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixLengthNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBeginInvocationInterlockEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBeginInvocationInterlockEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBeginInvocationInterlockEXT | (1 << 16); + } + + public OpBeginInvocationInterlockEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBeginInvocationInterlockEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBeginInvocationInterlockEXT]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBeginInvocationInterlockEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEndInvocationInterlockEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEndInvocationInterlockEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEndInvocationInterlockEXT | (1 << 16); + } + + public OpEndInvocationInterlockEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEndInvocationInterlockEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEndInvocationInterlockEXT]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEndInvocationInterlockEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixReduceNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixReduceNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixReduceNV | (1 << 16); + } + + public OpCooperativeMatrixReduceNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixReduceNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public CooperativeMatrixReduceMask Reduce + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CombineFunc + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixReduceNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixReduceNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixReduceNV(int resultType, int resultId, int matrix, CooperativeMatrixReduceMask reduce, int combineFunc) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + Reduce = reduce; + CombineFunc = combineFunc; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixReduceNV, ResultType, ResultId, Matrix, (int)Reduce, CombineFunc]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + case "reduce": + Reduce = o.ToEnum(); + break; + case "combineFunc": + CombineFunc = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixReduceNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCooperativeMatrixPerElementOpNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixPerElementOpNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixPerElementOpNV | (1 << 16); + } + + public OpCooperativeMatrixPerElementOpNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixPerElementOpNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Func + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Operands + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixPerElementOpNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixPerElementOpNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixPerElementOpNV(int resultType, int resultId, int matrix, int func, LiteralArray operands) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + Func = func; + Operands = operands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixPerElementOpNV, ResultType, ResultId, Matrix, Func, ..Operands.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + case "func": + Func = o.ToLiteral(); + break; + case "operands": + Operands = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Operands.WordCount == -1) + Operands = new(); + } + + public static implicit operator OpCooperativeMatrixPerElementOpNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Operands.Dispose(); + } +} + +public ref partial struct OpTypeTensorLayoutNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeTensorLayoutNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeTensorLayoutNV | (1 << 16); + } + + public OpTypeTensorLayoutNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeTensorLayoutNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dim + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ClampMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeTensorLayoutNV inst) => inst.ResultId; + public OpTypeTensorLayoutNV(int resultId, int dim, int clampMode) + { + ResultId = resultId; + Dim = dim; + ClampMode = clampMode; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeTensorLayoutNV, ResultId, Dim, ClampMode]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "dim": + Dim = o.ToLiteral(); + break; + case "clampMode": + ClampMode = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeTensorLayoutNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeTensorViewNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeTensorViewNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeTensorViewNV | (1 << 16); + } + + public OpTypeTensorViewNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeTensorViewNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Dim + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int HasDimensions + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Ps + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeTensorViewNV inst) => inst.ResultId; + public OpTypeTensorViewNV(int resultId, int dim, int hasDimensions, LiteralArray ps) + { + ResultId = resultId; + Dim = dim; + HasDimensions = hasDimensions; + Ps = ps; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeTensorViewNV, ResultId, Dim, HasDimensions, ..Ps.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "dim": + Dim = o.ToLiteral(); + break; + case "hasDimensions": + HasDimensions = o.ToLiteral(); + break; + case "ps": + Ps = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Ps.WordCount == -1) + Ps = new(); + } + + public static implicit operator OpTypeTensorViewNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Ps.Dispose(); + } +} + +public ref partial struct OpCreateTensorLayoutNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCreateTensorLayoutNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCreateTensorLayoutNV | (1 << 16); + } + + public OpCreateTensorLayoutNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCreateTensorLayoutNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCreateTensorLayoutNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCreateTensorLayoutNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCreateTensorLayoutNV(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCreateTensorLayoutNV, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCreateTensorLayoutNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTensorLayoutSetDimensionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorLayoutSetDimensionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorLayoutSetDimensionNV | (1 << 16); + } + + public OpTensorLayoutSetDimensionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorLayoutSetDimensionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorLayout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Dims + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorLayoutSetDimensionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorLayoutSetDimensionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorLayoutSetDimensionNV(int resultType, int resultId, int tensorLayout, LiteralArray dims) + { + ResultType = resultType; + ResultId = resultId; + TensorLayout = tensorLayout; + Dims = dims; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorLayoutSetDimensionNV, ResultType, ResultId, TensorLayout, ..Dims.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorLayout": + TensorLayout = o.ToLiteral(); + break; + case "dims": + Dims = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Dims.WordCount == -1) + Dims = new(); + } + + public static implicit operator OpTensorLayoutSetDimensionNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Dims.Dispose(); + } +} + +public ref partial struct OpTensorLayoutSetStrideNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorLayoutSetStrideNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorLayoutSetStrideNV | (1 << 16); + } + + public OpTensorLayoutSetStrideNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorLayoutSetStrideNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorLayout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Strides + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorLayoutSetStrideNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorLayoutSetStrideNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorLayoutSetStrideNV(int resultType, int resultId, int tensorLayout, LiteralArray strides) + { + ResultType = resultType; + ResultId = resultId; + TensorLayout = tensorLayout; + Strides = strides; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorLayoutSetStrideNV, ResultType, ResultId, TensorLayout, ..Strides.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorLayout": + TensorLayout = o.ToLiteral(); + break; + case "strides": + Strides = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Strides.WordCount == -1) + Strides = new(); + } + + public static implicit operator OpTensorLayoutSetStrideNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Strides.Dispose(); + } +} + +public ref partial struct OpTensorLayoutSliceNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorLayoutSliceNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorLayoutSliceNV | (1 << 16); + } + + public OpTensorLayoutSliceNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorLayoutSliceNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorLayout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Operands + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorLayoutSliceNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorLayoutSliceNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorLayoutSliceNV(int resultType, int resultId, int tensorLayout, LiteralArray operands) + { + ResultType = resultType; + ResultId = resultId; + TensorLayout = tensorLayout; + Operands = operands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorLayoutSliceNV, ResultType, ResultId, TensorLayout, ..Operands.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorLayout": + TensorLayout = o.ToLiteral(); + break; + case "operands": + Operands = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Operands.WordCount == -1) + Operands = new(); + } + + public static implicit operator OpTensorLayoutSliceNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Operands.Dispose(); + } +} + +public ref partial struct OpTensorLayoutSetClampValueNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorLayoutSetClampValueNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorLayoutSetClampValueNV | (1 << 16); + } + + public OpTensorLayoutSetClampValueNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorLayoutSetClampValueNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorLayout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorLayoutSetClampValueNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorLayoutSetClampValueNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorLayoutSetClampValueNV(int resultType, int resultId, int tensorLayout, int value) + { + ResultType = resultType; + ResultId = resultId; + TensorLayout = tensorLayout; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorLayoutSetClampValueNV, ResultType, ResultId, TensorLayout, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorLayout": + TensorLayout = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTensorLayoutSetClampValueNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCreateTensorViewNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCreateTensorViewNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCreateTensorViewNV | (1 << 16); + } + + public OpCreateTensorViewNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCreateTensorViewNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCreateTensorViewNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCreateTensorViewNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCreateTensorViewNV(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCreateTensorViewNV, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCreateTensorViewNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTensorViewSetDimensionNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorViewSetDimensionNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorViewSetDimensionNV | (1 << 16); + } + + public OpTensorViewSetDimensionNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorViewSetDimensionNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorView + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Dims + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorViewSetDimensionNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorViewSetDimensionNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorViewSetDimensionNV(int resultType, int resultId, int tensorView, LiteralArray dims) + { + ResultType = resultType; + ResultId = resultId; + TensorView = tensorView; + Dims = dims; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorViewSetDimensionNV, ResultType, ResultId, TensorView, ..Dims.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorView": + TensorView = o.ToLiteral(); + break; + case "dims": + Dims = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Dims.WordCount == -1) + Dims = new(); + } + + public static implicit operator OpTensorViewSetDimensionNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Dims.Dispose(); + } +} + +public ref partial struct OpTensorViewSetStrideNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorViewSetStrideNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorViewSetStrideNV | (1 << 16); + } + + public OpTensorViewSetStrideNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorViewSetStrideNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorView + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Strides + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorViewSetStrideNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorViewSetStrideNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorViewSetStrideNV(int resultType, int resultId, int tensorView, LiteralArray strides) + { + ResultType = resultType; + ResultId = resultId; + TensorView = tensorView; + Strides = strides; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorViewSetStrideNV, ResultType, ResultId, TensorView, ..Strides.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorView": + TensorView = o.ToLiteral(); + break; + case "strides": + Strides = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Strides.WordCount == -1) + Strides = new(); + } + + public static implicit operator OpTensorViewSetStrideNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + Strides.Dispose(); + } +} + +public ref partial struct OpDemoteToHelperInvocation : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDemoteToHelperInvocation() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDemoteToHelperInvocation | (1 << 16); + } + + public OpDemoteToHelperInvocation(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDemoteToHelperInvocation(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDemoteToHelperInvocation]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDemoteToHelperInvocation(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIsHelperInvocationEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIsHelperInvocationEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIsHelperInvocationEXT | (1 << 16); + } + + public OpIsHelperInvocationEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIsHelperInvocationEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIsHelperInvocationEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIsHelperInvocationEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIsHelperInvocationEXT(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIsHelperInvocationEXT, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIsHelperInvocationEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTensorViewSetClipNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorViewSetClipNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorViewSetClipNV | (1 << 16); + } + + public OpTensorViewSetClipNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorViewSetClipNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorView + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ClipRowOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ClipRowSpan + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ClipColOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ClipColSpan + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorViewSetClipNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorViewSetClipNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorViewSetClipNV(int resultType, int resultId, int tensorView, int clipRowOffset, int clipRowSpan, int clipColOffset, int clipColSpan) + { + ResultType = resultType; + ResultId = resultId; + TensorView = tensorView; + ClipRowOffset = clipRowOffset; + ClipRowSpan = clipRowSpan; + ClipColOffset = clipColOffset; + ClipColSpan = clipColSpan; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorViewSetClipNV, ResultType, ResultId, TensorView, ClipRowOffset, ClipRowSpan, ClipColOffset, ClipColSpan]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorView": + TensorView = o.ToLiteral(); + break; + case "clipRowOffset": + ClipRowOffset = o.ToLiteral(); + break; + case "clipRowSpan": + ClipRowSpan = o.ToLiteral(); + break; + case "clipColOffset": + ClipColOffset = o.ToLiteral(); + break; + case "clipColSpan": + ClipColSpan = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTensorViewSetClipNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTensorLayoutSetBlockSizeNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTensorLayoutSetBlockSizeNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTensorLayoutSetBlockSizeNV | (1 << 16); + } + + public OpTensorLayoutSetBlockSizeNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTensorLayoutSetBlockSizeNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int TensorLayout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray BlockSizes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTensorLayoutSetBlockSizeNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpTensorLayoutSetBlockSizeNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpTensorLayoutSetBlockSizeNV(int resultType, int resultId, int tensorLayout, LiteralArray blockSizes) + { + ResultType = resultType; + ResultId = resultId; + TensorLayout = tensorLayout; + BlockSizes = blockSizes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTensorLayoutSetBlockSizeNV, ResultType, ResultId, TensorLayout, ..BlockSizes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "tensorLayout": + TensorLayout = o.ToLiteral(); + break; + case "blockSizes": + BlockSizes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (BlockSizes.WordCount == -1) + BlockSizes = new(); + } + + public static implicit operator OpTensorLayoutSetBlockSizeNV(OpDataIndex odi) => new(odi); + public void Dispose() + { + BlockSizes.Dispose(); + } +} + +public ref partial struct OpCooperativeMatrixTransposeNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCooperativeMatrixTransposeNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCooperativeMatrixTransposeNV | (1 << 16); + } + + public OpCooperativeMatrixTransposeNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCooperativeMatrixTransposeNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Matrix + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCooperativeMatrixTransposeNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCooperativeMatrixTransposeNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCooperativeMatrixTransposeNV(int resultType, int resultId, int matrix) + { + ResultType = resultType; + ResultId = resultId; + Matrix = matrix; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCooperativeMatrixTransposeNV, ResultType, ResultId, Matrix]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "matrix": + Matrix = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCooperativeMatrixTransposeNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToImageNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToImageNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToImageNV | (1 << 16); + } + + public OpConvertUToImageNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToImageNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToImageNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToImageNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToImageNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToImageNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToImageNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToSamplerNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToSamplerNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToSamplerNV | (1 << 16); + } + + public OpConvertUToSamplerNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToSamplerNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToSamplerNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToSamplerNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToSamplerNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToSamplerNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToSamplerNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertImageToUNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertImageToUNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertImageToUNV | (1 << 16); + } + + public OpConvertImageToUNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertImageToUNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertImageToUNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertImageToUNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertImageToUNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertImageToUNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertImageToUNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertSamplerToUNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertSamplerToUNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertSamplerToUNV | (1 << 16); + } + + public OpConvertSamplerToUNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertSamplerToUNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertSamplerToUNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertSamplerToUNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertSamplerToUNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertSamplerToUNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertSamplerToUNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertUToSampledImageNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertUToSampledImageNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertUToSampledImageNV | (1 << 16); + } + + public OpConvertUToSampledImageNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertUToSampledImageNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertUToSampledImageNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertUToSampledImageNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertUToSampledImageNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertUToSampledImageNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertUToSampledImageNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertSampledImageToUNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertSampledImageToUNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertSampledImageToUNV | (1 << 16); + } + + public OpConvertSampledImageToUNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertSampledImageToUNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertSampledImageToUNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertSampledImageToUNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertSampledImageToUNV(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertSampledImageToUNV, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertSampledImageToUNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSamplerImageAddressingModeNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSamplerImageAddressingModeNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSamplerImageAddressingModeNV | (1 << 16); + } + + public OpSamplerImageAddressingModeNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSamplerImageAddressingModeNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int BitWidth + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSamplerImageAddressingModeNV(int bitWidth) + { + BitWidth = bitWidth; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSamplerImageAddressingModeNV, ..BitWidth.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "bitWidth": + BitWidth = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSamplerImageAddressingModeNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRawAccessChainNV : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRawAccessChainNV() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRawAccessChainNV | (1 << 16); + } + + public OpRawAccessChainNV(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRawAccessChainNV(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Bytestride + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Elementindex + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Byteoffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public RawAccessChainOperandsMask? RawAccessChainOperands + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRawAccessChainNV inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRawAccessChainNV inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRawAccessChainNV(int resultType, int resultId, int baseId, int bytestride, int elementindex, int byteoffset, RawAccessChainOperandsMask? rawAccessChainOperands) + { + ResultType = resultType; + ResultId = resultId; + BaseId = baseId; + Bytestride = bytestride; + Elementindex = elementindex; + Byteoffset = byteoffset; + RawAccessChainOperands = rawAccessChainOperands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRawAccessChainNV, ResultType, ResultId, BaseId, Bytestride, Elementindex, Byteoffset, ..(RawAccessChainOperands is null ? (Span)[] : [(int)RawAccessChainOperands.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseId": + BaseId = o.ToLiteral(); + break; + case "bytestride": + Bytestride = o.ToLiteral(); + break; + case "elementindex": + Elementindex = o.ToLiteral(); + break; + case "byteoffset": + Byteoffset = o.ToLiteral(); + break; + case "rawAccessChainOperands": + if (o.Words.Length > 0) + { + RawAccessChainOperands = o.ToEnum(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRawAccessChainNV(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupShuffleINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupShuffleINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupShuffleINTEL | (1 << 16); + } + + public OpSubgroupShuffleINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupShuffleINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Data + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InvocationId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupShuffleINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupShuffleINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupShuffleINTEL(int resultType, int resultId, int data, int invocationId) + { + ResultType = resultType; + ResultId = resultId; + Data = data; + InvocationId = invocationId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupShuffleINTEL, ResultType, ResultId, Data, InvocationId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "data": + Data = o.ToLiteral(); + break; + case "invocationId": + InvocationId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupShuffleINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupShuffleDownINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupShuffleDownINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupShuffleDownINTEL | (1 << 16); + } + + public OpSubgroupShuffleDownINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupShuffleDownINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Current + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Next + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Delta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupShuffleDownINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupShuffleDownINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupShuffleDownINTEL(int resultType, int resultId, int current, int next, int delta) + { + ResultType = resultType; + ResultId = resultId; + Current = current; + Next = next; + Delta = delta; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupShuffleDownINTEL, ResultType, ResultId, Current, Next, Delta]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "current": + Current = o.ToLiteral(); + break; + case "next": + Next = o.ToLiteral(); + break; + case "delta": + Delta = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupShuffleDownINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupShuffleUpINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupShuffleUpINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupShuffleUpINTEL | (1 << 16); + } + + public OpSubgroupShuffleUpINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupShuffleUpINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Previous + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Current + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Delta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupShuffleUpINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupShuffleUpINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupShuffleUpINTEL(int resultType, int resultId, int previous, int current, int delta) + { + ResultType = resultType; + ResultId = resultId; + Previous = previous; + Current = current; + Delta = delta; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupShuffleUpINTEL, ResultType, ResultId, Previous, Current, Delta]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "previous": + Previous = o.ToLiteral(); + break; + case "current": + Current = o.ToLiteral(); + break; + case "delta": + Delta = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupShuffleUpINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupShuffleXorINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupShuffleXorINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupShuffleXorINTEL | (1 << 16); + } + + public OpSubgroupShuffleXorINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupShuffleXorINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Data + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupShuffleXorINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupShuffleXorINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupShuffleXorINTEL(int resultType, int resultId, int data, int value) + { + ResultType = resultType; + ResultId = resultId; + Data = data; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupShuffleXorINTEL, ResultType, ResultId, Data, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "data": + Data = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupShuffleXorINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupBlockReadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupBlockReadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupBlockReadINTEL | (1 << 16); + } + + public OpSubgroupBlockReadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupBlockReadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Ptr + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupBlockReadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupBlockReadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupBlockReadINTEL(int resultType, int resultId, int ptr) + { + ResultType = resultType; + ResultId = resultId; + Ptr = ptr; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupBlockReadINTEL, ResultType, ResultId, Ptr]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "ptr": + Ptr = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupBlockReadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupBlockWriteINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupBlockWriteINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupBlockWriteINTEL | (1 << 16); + } + + public OpSubgroupBlockWriteINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupBlockWriteINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Ptr + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Data + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSubgroupBlockWriteINTEL(int ptr, int data) + { + Ptr = ptr; + Data = data; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupBlockWriteINTEL, Ptr, Data]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "ptr": + Ptr = o.ToLiteral(); + break; + case "data": + Data = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupBlockWriteINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupImageBlockReadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupImageBlockReadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupImageBlockReadINTEL | (1 << 16); + } + + public OpSubgroupImageBlockReadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupImageBlockReadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupImageBlockReadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupImageBlockReadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupImageBlockReadINTEL(int resultType, int resultId, int image, int coordinate) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupImageBlockReadINTEL, ResultType, ResultId, Image, Coordinate]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupImageBlockReadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupImageBlockWriteINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupImageBlockWriteINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupImageBlockWriteINTEL | (1 << 16); + } + + public OpSubgroupImageBlockWriteINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupImageBlockWriteINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Data + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSubgroupImageBlockWriteINTEL(int image, int coordinate, int data) + { + Image = image; + Coordinate = coordinate; + Data = data; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupImageBlockWriteINTEL, Image, Coordinate, Data]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "data": + Data = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupImageBlockWriteINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupImageMediaBlockReadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupImageMediaBlockReadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupImageMediaBlockReadINTEL | (1 << 16); + } + + public OpSubgroupImageMediaBlockReadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupImageMediaBlockReadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Width + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Height + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupImageMediaBlockReadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupImageMediaBlockReadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupImageMediaBlockReadINTEL(int resultType, int resultId, int image, int coordinate, int width, int height) + { + ResultType = resultType; + ResultId = resultId; + Image = image; + Coordinate = coordinate; + Width = width; + Height = height; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupImageMediaBlockReadINTEL, ResultType, ResultId, Image, Coordinate, Width, Height]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "width": + Width = o.ToLiteral(); + break; + case "height": + Height = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupImageMediaBlockReadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupImageMediaBlockWriteINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupImageMediaBlockWriteINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupImageMediaBlockWriteINTEL | (1 << 16); + } + + public OpSubgroupImageMediaBlockWriteINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupImageMediaBlockWriteINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Image + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Coordinate + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Width + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Height + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Data + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSubgroupImageMediaBlockWriteINTEL(int image, int coordinate, int width, int height, int data) + { + Image = image; + Coordinate = coordinate; + Width = width; + Height = height; + Data = data; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupImageMediaBlockWriteINTEL, Image, Coordinate, Width, Height, Data]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "image": + Image = o.ToLiteral(); + break; + case "coordinate": + Coordinate = o.ToLiteral(); + break; + case "width": + Width = o.ToLiteral(); + break; + case "height": + Height = o.ToLiteral(); + break; + case "data": + Data = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupImageMediaBlockWriteINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUCountLeadingZerosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUCountLeadingZerosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUCountLeadingZerosINTEL | (1 << 16); + } + + public OpUCountLeadingZerosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUCountLeadingZerosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUCountLeadingZerosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUCountLeadingZerosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUCountLeadingZerosINTEL(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUCountLeadingZerosINTEL, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUCountLeadingZerosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUCountTrailingZerosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUCountTrailingZerosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUCountTrailingZerosINTEL | (1 << 16); + } + + public OpUCountTrailingZerosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUCountTrailingZerosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUCountTrailingZerosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUCountTrailingZerosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUCountTrailingZerosINTEL(int resultType, int resultId, int operand) + { + ResultType = resultType; + ResultId = resultId; + Operand = operand; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUCountTrailingZerosINTEL, ResultType, ResultId, Operand]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand": + Operand = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUCountTrailingZerosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAbsISubINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAbsISubINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAbsISubINTEL | (1 << 16); + } + + public OpAbsISubINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAbsISubINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAbsISubINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAbsISubINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAbsISubINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAbsISubINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAbsISubINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAbsUSubINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAbsUSubINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAbsUSubINTEL | (1 << 16); + } + + public OpAbsUSubINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAbsUSubINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAbsUSubINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAbsUSubINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAbsUSubINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAbsUSubINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAbsUSubINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIAddSatINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIAddSatINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIAddSatINTEL | (1 << 16); + } + + public OpIAddSatINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIAddSatINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIAddSatINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIAddSatINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIAddSatINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIAddSatINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIAddSatINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUAddSatINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUAddSatINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUAddSatINTEL | (1 << 16); + } + + public OpUAddSatINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUAddSatINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUAddSatINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUAddSatINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUAddSatINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUAddSatINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUAddSatINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIAverageINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIAverageINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIAverageINTEL | (1 << 16); + } + + public OpIAverageINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIAverageINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIAverageINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIAverageINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIAverageINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIAverageINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIAverageINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUAverageINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUAverageINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUAverageINTEL | (1 << 16); + } + + public OpUAverageINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUAverageINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUAverageINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUAverageINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUAverageINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUAverageINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUAverageINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIAverageRoundedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIAverageRoundedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIAverageRoundedINTEL | (1 << 16); + } + + public OpIAverageRoundedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIAverageRoundedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIAverageRoundedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIAverageRoundedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIAverageRoundedINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIAverageRoundedINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIAverageRoundedINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUAverageRoundedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUAverageRoundedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUAverageRoundedINTEL | (1 << 16); + } + + public OpUAverageRoundedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUAverageRoundedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUAverageRoundedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUAverageRoundedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUAverageRoundedINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUAverageRoundedINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUAverageRoundedINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpISubSatINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpISubSatINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpISubSatINTEL | (1 << 16); + } + + public OpISubSatINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpISubSatINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpISubSatINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpISubSatINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpISubSatINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpISubSatINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpISubSatINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUSubSatINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUSubSatINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUSubSatINTEL | (1 << 16); + } + + public OpUSubSatINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUSubSatINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUSubSatINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUSubSatINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUSubSatINTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUSubSatINTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUSubSatINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpIMul32x16INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpIMul32x16INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpIMul32x16INTEL | (1 << 16); + } + + public OpIMul32x16INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpIMul32x16INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpIMul32x16INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpIMul32x16INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpIMul32x16INTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpIMul32x16INTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpIMul32x16INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUMul32x16INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUMul32x16INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUMul32x16INTEL | (1 << 16); + } + + public OpUMul32x16INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUMul32x16INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpUMul32x16INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpUMul32x16INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpUMul32x16INTEL(int resultType, int resultId, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUMul32x16INTEL, ResultType, ResultId, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUMul32x16INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantFunctionPointerINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantFunctionPointerINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantFunctionPointerINTEL | (1 << 16); + } + + public OpConstantFunctionPointerINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantFunctionPointerINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Function + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantFunctionPointerINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConstantFunctionPointerINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConstantFunctionPointerINTEL(int resultType, int resultId, int function) + { + ResultType = resultType; + ResultId = resultId; + Function = function; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantFunctionPointerINTEL, ResultType, ResultId, Function]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "function": + Function = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantFunctionPointerINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFunctionPointerCallINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunctionPointerCallINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunctionPointerCallINTEL | (1 << 16); + } + + public OpFunctionPointerCallINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunctionPointerCallINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Operands + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFunctionPointerCallINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFunctionPointerCallINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFunctionPointerCallINTEL(int resultType, int resultId, LiteralArray operands) + { + ResultType = resultType; + ResultId = resultId; + Operands = operands; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunctionPointerCallINTEL, ResultType, ResultId, ..Operands.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operands": + Operands = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Operands.WordCount == -1) + Operands = new(); + } + + public static implicit operator OpFunctionPointerCallINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Operands.Dispose(); + } +} + +public ref partial struct OpAsmTargetINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAsmTargetINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAsmTargetINTEL | (1 << 16); + } + + public OpAsmTargetINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAsmTargetINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Asmtarget + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAsmTargetINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAsmTargetINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAsmTargetINTEL(int resultType, int resultId, string asmtarget) + { + ResultType = resultType; + ResultId = resultId; + Asmtarget = asmtarget; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAsmTargetINTEL, ResultType, ResultId, ..Asmtarget.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "asmtarget": + Asmtarget = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAsmTargetINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAsmINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAsmINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAsmINTEL | (1 << 16); + } + + public OpAsmINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAsmINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Asmtype + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Asminstructions + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Constraints + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAsmINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAsmINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAsmINTEL(int resultType, int resultId, int asmtype, int target, string asminstructions, string constraints) + { + ResultType = resultType; + ResultId = resultId; + Asmtype = asmtype; + Target = target; + Asminstructions = asminstructions; + Constraints = constraints; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAsmINTEL, ResultType, ResultId, Asmtype, Target, ..Asminstructions.AsDisposableLiteralValue().Words, ..Constraints.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "asmtype": + Asmtype = o.ToLiteral(); + break; + case "target": + Target = o.ToLiteral(); + break; + case "asminstructions": + Asminstructions = o.ToLiteral(); + break; + case "constraints": + Constraints = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAsmINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAsmCallINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAsmCallINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAsmCallINTEL | (1 << 16); + } + + public OpAsmCallINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAsmCallINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Asm + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Arguments + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAsmCallINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAsmCallINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAsmCallINTEL(int resultType, int resultId, int asm, LiteralArray arguments) + { + ResultType = resultType; + ResultId = resultId; + Asm = asm; + Arguments = arguments; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAsmCallINTEL, ResultType, ResultId, Asm, ..Arguments.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "asm": + Asm = o.ToLiteral(); + break; + case "arguments": + Arguments = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Arguments.WordCount == -1) + Arguments = new(); + } + + public static implicit operator OpAsmCallINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Arguments.Dispose(); + } +} + +public ref partial struct OpAtomicFMinEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicFMinEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicFMinEXT | (1 << 16); + } + + public OpAtomicFMinEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicFMinEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicFMinEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicFMinEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicFMinEXT(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicFMinEXT, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicFMinEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicFMaxEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicFMaxEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicFMaxEXT | (1 << 16); + } + + public OpAtomicFMaxEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicFMaxEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicFMaxEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicFMaxEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicFMaxEXT(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicFMaxEXT, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicFMaxEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAssumeTrueKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAssumeTrueKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAssumeTrueKHR | (1 << 16); + } + + public OpAssumeTrueKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAssumeTrueKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Condition + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpAssumeTrueKHR(int condition) + { + Condition = condition; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAssumeTrueKHR, Condition]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "condition": + Condition = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAssumeTrueKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpExpectKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpExpectKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExpectKHR | (1 << 16); + } + + public OpExpectKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpExpectKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ExpectedValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpExpectKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpExpectKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpExpectKHR(int resultType, int resultId, int value, int expectedValue) + { + ResultType = resultType; + ResultId = resultId; + Value = value; + ExpectedValue = expectedValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExpectKHR, ResultType, ResultId, Value, ExpectedValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "expectedValue": + ExpectedValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpExpectKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpDecorateString : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpDecorateString() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpDecorateString | (1 << 16); + } + + public OpDecorateString(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpDecorateString(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Decoration Decoration + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpDecorateString(int target, Decoration decoration, string value) + { + Target = target; + Decoration = decoration; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpDecorateString, Target, (int)Decoration, ..Value.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "target": + Target = o.ToLiteral(); + break; + case "decoration": + Decoration = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpDecorateString(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMemberDecorateString : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemberDecorateString() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemberDecorateString | (1 << 16); + } + + public OpMemberDecorateString(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemberDecorateString(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int StructType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Member + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public Decoration Decoration + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMemberDecorateString(int structType, int member, Decoration decoration, string value) + { + StructType = structType; + Member = member; + Decoration = decoration; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemberDecorateString, StructType, ..Member.AsDisposableLiteralValue().Words, (int)Decoration, ..Value.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "structType": + StructType = o.ToLiteral(); + break; + case "member": + Member = o.ToLiteral(); + break; + case "decoration": + Decoration = o.ToEnum(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemberDecorateString(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVmeImageINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVmeImageINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVmeImageINTEL | (1 << 16); + } + + public OpVmeImageINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVmeImageINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ImageType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Sampler + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVmeImageINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVmeImageINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVmeImageINTEL(int resultType, int resultId, int imageType, int sampler) + { + ResultType = resultType; + ResultId = resultId; + ImageType = imageType; + Sampler = sampler; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVmeImageINTEL, ResultType, ResultId, ImageType, Sampler]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "imageType": + ImageType = o.ToLiteral(); + break; + case "sampler": + Sampler = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVmeImageINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeVmeImageINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeVmeImageINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeVmeImageINTEL | (1 << 16); + } + + public OpTypeVmeImageINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeVmeImageINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ImageType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeVmeImageINTEL inst) => inst.ResultId; + public OpTypeVmeImageINTEL(int resultId, int imageType) + { + ResultId = resultId; + ImageType = imageType; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeVmeImageINTEL, ResultId, ImageType]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "imageType": + ImageType = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeVmeImageINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImePayloadINTEL | (1 << 16); + } + + public OpTypeAvcImePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImePayloadINTEL inst) => inst.ResultId; + public OpTypeAvcImePayloadINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImePayloadINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcRefPayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcRefPayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcRefPayloadINTEL | (1 << 16); + } + + public OpTypeAvcRefPayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcRefPayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcRefPayloadINTEL inst) => inst.ResultId; + public OpTypeAvcRefPayloadINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcRefPayloadINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcRefPayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcSicPayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcSicPayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcSicPayloadINTEL | (1 << 16); + } + + public OpTypeAvcSicPayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcSicPayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcSicPayloadINTEL inst) => inst.ResultId; + public OpTypeAvcSicPayloadINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcSicPayloadINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcSicPayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcMcePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcMcePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcMcePayloadINTEL | (1 << 16); + } + + public OpTypeAvcMcePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcMcePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcMcePayloadINTEL inst) => inst.ResultId; + public OpTypeAvcMcePayloadINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcMcePayloadINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcMcePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcMceResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcMceResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcMceResultINTEL | (1 << 16); + } + + public OpTypeAvcMceResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcMceResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcMceResultINTEL inst) => inst.ResultId; + public OpTypeAvcMceResultINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcMceResultINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcMceResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImeResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImeResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImeResultINTEL | (1 << 16); + } + + public OpTypeAvcImeResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImeResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImeResultINTEL inst) => inst.ResultId; + public OpTypeAvcImeResultINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImeResultINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImeResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImeResultSingleReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImeResultSingleReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImeResultSingleReferenceStreamoutINTEL | (1 << 16); + } + + public OpTypeAvcImeResultSingleReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImeResultSingleReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImeResultSingleReferenceStreamoutINTEL inst) => inst.ResultId; + public OpTypeAvcImeResultSingleReferenceStreamoutINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImeResultSingleReferenceStreamoutINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImeResultSingleReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImeResultDualReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImeResultDualReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImeResultDualReferenceStreamoutINTEL | (1 << 16); + } + + public OpTypeAvcImeResultDualReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImeResultDualReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImeResultDualReferenceStreamoutINTEL inst) => inst.ResultId; + public OpTypeAvcImeResultDualReferenceStreamoutINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImeResultDualReferenceStreamoutINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImeResultDualReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImeSingleReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImeSingleReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImeSingleReferenceStreaminINTEL | (1 << 16); + } + + public OpTypeAvcImeSingleReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImeSingleReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImeSingleReferenceStreaminINTEL inst) => inst.ResultId; + public OpTypeAvcImeSingleReferenceStreaminINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImeSingleReferenceStreaminINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImeSingleReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcImeDualReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcImeDualReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcImeDualReferenceStreaminINTEL | (1 << 16); + } + + public OpTypeAvcImeDualReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcImeDualReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcImeDualReferenceStreaminINTEL inst) => inst.ResultId; + public OpTypeAvcImeDualReferenceStreaminINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcImeDualReferenceStreaminINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcImeDualReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcRefResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcRefResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcRefResultINTEL | (1 << 16); + } + + public OpTypeAvcRefResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcRefResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcRefResultINTEL inst) => inst.ResultId; + public OpTypeAvcRefResultINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcRefResultINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcRefResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeAvcSicResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeAvcSicResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeAvcSicResultINTEL | (1 << 16); + } + + public OpTypeAvcSicResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeAvcSicResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeAvcSicResultINTEL inst) => inst.ResultId; + public OpTypeAvcSicResultINTEL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeAvcSicResultINTEL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeAvcSicResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceBasePenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL(int resultType, int resultId, int referenceBasePenalty, int payload) + { + ResultType = resultType; + ResultId = resultId; + ReferenceBasePenalty = referenceBasePenalty; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL, ResultType, ResultId, ReferenceBasePenalty, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "referenceBasePenalty": + ReferenceBasePenalty = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetInterShapePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetInterShapePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetInterShapePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetInterShapePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedShapePenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetInterShapePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetInterShapePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetInterShapePenaltyINTEL(int resultType, int resultId, int packedShapePenalty, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedShapePenalty = packedShapePenalty; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetInterShapePenaltyINTEL, ResultType, ResultId, PackedShapePenalty, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedShapePenalty": + PackedShapePenalty = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetInterShapePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetInterDirectionPenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetInterDirectionPenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetInterDirectionPenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetInterDirectionPenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int DirectionCost + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetInterDirectionPenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetInterDirectionPenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetInterDirectionPenaltyINTEL(int resultType, int resultId, int directionCost, int payload) + { + ResultType = resultType; + ResultId = resultId; + DirectionCost = directionCost; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetInterDirectionPenaltyINTEL, ResultType, ResultId, DirectionCost, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "directionCost": + DirectionCost = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetInterDirectionPenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedCostCenterDelta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedCostTable + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int CostPrecision + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL(int resultType, int resultId, int packedCostCenterDelta, int packedCostTable, int costPrecision, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedCostCenterDelta = packedCostCenterDelta; + PackedCostTable = packedCostTable; + CostPrecision = costPrecision; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL, ResultType, ResultId, PackedCostCenterDelta, PackedCostTable, CostPrecision, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedCostCenterDelta": + PackedCostCenterDelta = o.ToLiteral(); + break; + case "packedCostTable": + PackedCostTable = o.ToLiteral(); + break; + case "costPrecision": + CostPrecision = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SliceType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Qp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL(int resultType, int resultId, int sliceType, int qp) + { + ResultType = resultType; + ResultId = resultId; + SliceType = sliceType; + Qp = qp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL, ResultType, ResultId, SliceType, Qp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sliceType": + SliceType = o.ToLiteral(); + break; + case "qp": + Qp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetAcOnlyHaarINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetAcOnlyHaarINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetAcOnlyHaarINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetAcOnlyHaarINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetAcOnlyHaarINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetAcOnlyHaarINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetAcOnlyHaarINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetAcOnlyHaarINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetAcOnlyHaarINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetAcOnlyHaarINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SourceFieldPolarity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL(int resultType, int resultId, int sourceFieldPolarity, int payload) + { + ResultType = resultType; + ResultId = resultId; + SourceFieldPolarity = sourceFieldPolarity; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL, ResultType, ResultId, SourceFieldPolarity, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "sourceFieldPolarity": + SourceFieldPolarity = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReferenceFieldPolarity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL(int resultType, int resultId, int referenceFieldPolarity, int payload) + { + ResultType = resultType; + ResultId = resultId; + ReferenceFieldPolarity = referenceFieldPolarity; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL, ResultType, ResultId, ReferenceFieldPolarity, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "referenceFieldPolarity": + ReferenceFieldPolarity = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL | (1 << 16); + } + + public OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ForwardReferenceFieldPolarity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BackwardReferenceFieldPolarity + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL(int resultType, int resultId, int forwardReferenceFieldPolarity, int backwardReferenceFieldPolarity, int payload) + { + ResultType = resultType; + ResultId = resultId; + ForwardReferenceFieldPolarity = forwardReferenceFieldPolarity; + BackwardReferenceFieldPolarity = backwardReferenceFieldPolarity; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL, ResultType, ResultId, ForwardReferenceFieldPolarity, BackwardReferenceFieldPolarity, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "forwardReferenceFieldPolarity": + ForwardReferenceFieldPolarity = o.ToLiteral(); + break; + case "backwardReferenceFieldPolarity": + BackwardReferenceFieldPolarity = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToImePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToImePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToImePayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToImePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToImePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToImePayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToImePayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToImePayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToImePayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToImePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToImeResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToImeResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToImeResultINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToImeResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToImeResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToImeResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToImeResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToImeResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToImeResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToImeResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToRefPayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToRefPayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToRefPayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToRefPayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToRefPayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToRefPayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToRefPayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToRefPayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToRefPayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToRefPayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToRefResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToRefResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToRefResultINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToRefResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToRefResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToRefResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToRefResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToRefResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToRefResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToRefResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToSicPayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToSicPayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToSicPayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToSicPayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToSicPayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToSicPayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToSicPayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToSicPayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToSicPayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToSicPayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceConvertToSicResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceConvertToSicResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceConvertToSicResultINTEL | (1 << 16); + } + + public OpSubgroupAvcMceConvertToSicResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceConvertToSicResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceConvertToSicResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceConvertToSicResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceConvertToSicResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceConvertToSicResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceConvertToSicResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetMotionVectorsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetMotionVectorsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetMotionVectorsINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetMotionVectorsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetMotionVectorsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetMotionVectorsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetMotionVectorsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetMotionVectorsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetMotionVectorsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetMotionVectorsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterDistortionsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterDistortionsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterDistortionsINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterDistortionsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterDistortionsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterDistortionsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterDistortionsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterDistortionsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterDistortionsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterDistortionsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetBestInterDistortionsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetBestInterDistortionsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetBestInterDistortionsINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetBestInterDistortionsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetBestInterDistortionsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetBestInterDistortionsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetBestInterDistortionsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetBestInterDistortionsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetBestInterDistortionsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetBestInterDistortionsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterMajorShapeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterMajorShapeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterMajorShapeINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterMajorShapeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterMajorShapeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterMajorShapeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterMajorShapeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterMajorShapeINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterMajorShapeINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterMajorShapeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterMinorShapeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterMinorShapeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterMinorShapeINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterMinorShapeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterMinorShapeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterMinorShapeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterMinorShapeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterMinorShapeINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterMinorShapeINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterMinorShapeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterDirectionsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterDirectionsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterDirectionsINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterDirectionsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterDirectionsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterDirectionsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterDirectionsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterDirectionsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterDirectionsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterDirectionsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterMotionVectorCountINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterMotionVectorCountINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterMotionVectorCountINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterMotionVectorCountINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterMotionVectorCountINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterMotionVectorCountINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterMotionVectorCountINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterMotionVectorCountINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterMotionVectorCountINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterMotionVectorCountINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterReferenceIdsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterReferenceIdsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterReferenceIdsINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterReferenceIdsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterReferenceIdsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterReferenceIdsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterReferenceIdsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterReferenceIdsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterReferenceIdsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterReferenceIdsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL | (1 << 16); + } + + public OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceIds + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceParameterFieldPolarities + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL(int resultType, int resultId, int packedReferenceIds, int packedReferenceParameterFieldPolarities, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedReferenceIds = packedReferenceIds; + PackedReferenceParameterFieldPolarities = packedReferenceParameterFieldPolarities; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL, ResultType, ResultId, PackedReferenceIds, PackedReferenceParameterFieldPolarities, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedReferenceIds": + PackedReferenceIds = o.ToLiteral(); + break; + case "packedReferenceParameterFieldPolarities": + PackedReferenceParameterFieldPolarities = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeInitializeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeInitializeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeInitializeINTEL | (1 << 16); + } + + public OpSubgroupAvcImeInitializeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeInitializeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcCoord + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PartitionMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SADAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeInitializeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeInitializeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeInitializeINTEL(int resultType, int resultId, int srcCoord, int partitionMask, int sADAdjustment) + { + ResultType = resultType; + ResultId = resultId; + SrcCoord = srcCoord; + PartitionMask = partitionMask; + SADAdjustment = sADAdjustment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeInitializeINTEL, ResultType, ResultId, SrcCoord, PartitionMask, SADAdjustment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcCoord": + SrcCoord = o.ToLiteral(); + break; + case "partitionMask": + PartitionMask = o.ToLiteral(); + break; + case "sADAdjustment": + SADAdjustment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeInitializeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetSingleReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetSingleReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetSingleReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetSingleReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetSingleReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SearchWindowConfig + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetSingleReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetSingleReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetSingleReferenceINTEL(int resultType, int resultId, int refOffset, int searchWindowConfig, int payload) + { + ResultType = resultType; + ResultId = resultId; + RefOffset = refOffset; + SearchWindowConfig = searchWindowConfig; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetSingleReferenceINTEL, ResultType, ResultId, RefOffset, SearchWindowConfig, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "refOffset": + RefOffset = o.ToLiteral(); + break; + case "searchWindowConfig": + SearchWindowConfig = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetSingleReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetDualReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetDualReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetDualReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetDualReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetDualReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int IdSearchWindowConfig + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetDualReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetDualReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetDualReferenceINTEL(int resultType, int resultId, int fwdRefOffset, int bwdRefOffset, int idSearchWindowConfig, int payload) + { + ResultType = resultType; + ResultId = resultId; + FwdRefOffset = fwdRefOffset; + BwdRefOffset = bwdRefOffset; + IdSearchWindowConfig = idSearchWindowConfig; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetDualReferenceINTEL, ResultType, ResultId, FwdRefOffset, BwdRefOffset, IdSearchWindowConfig, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "fwdRefOffset": + FwdRefOffset = o.ToLiteral(); + break; + case "bwdRefOffset": + BwdRefOffset = o.ToLiteral(); + break; + case "idSearchWindowConfig": + IdSearchWindowConfig = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetDualReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeRefWindowSizeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeRefWindowSizeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeRefWindowSizeINTEL | (1 << 16); + } + + public OpSubgroupAvcImeRefWindowSizeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeRefWindowSizeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SearchWindowConfig + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int DualRef + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeRefWindowSizeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeRefWindowSizeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeRefWindowSizeINTEL(int resultType, int resultId, int searchWindowConfig, int dualRef) + { + ResultType = resultType; + ResultId = resultId; + SearchWindowConfig = searchWindowConfig; + DualRef = dualRef; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeRefWindowSizeINTEL, ResultType, ResultId, SearchWindowConfig, DualRef]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "searchWindowConfig": + SearchWindowConfig = o.ToLiteral(); + break; + case "dualRef": + DualRef = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeRefWindowSizeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeAdjustRefOffsetINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeAdjustRefOffsetINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeAdjustRefOffsetINTEL | (1 << 16); + } + + public OpSubgroupAvcImeAdjustRefOffsetINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeAdjustRefOffsetINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefOffset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcCoord + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefWindowSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ImageSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeAdjustRefOffsetINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeAdjustRefOffsetINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeAdjustRefOffsetINTEL(int resultType, int resultId, int refOffset, int srcCoord, int refWindowSize, int imageSize) + { + ResultType = resultType; + ResultId = resultId; + RefOffset = refOffset; + SrcCoord = srcCoord; + RefWindowSize = refWindowSize; + ImageSize = imageSize; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeAdjustRefOffsetINTEL, ResultType, ResultId, RefOffset, SrcCoord, RefWindowSize, ImageSize]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "refOffset": + RefOffset = o.ToLiteral(); + break; + case "srcCoord": + SrcCoord = o.ToLiteral(); + break; + case "refWindowSize": + RefWindowSize = o.ToLiteral(); + break; + case "imageSize": + ImageSize = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeAdjustRefOffsetINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeConvertToMcePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeConvertToMcePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeConvertToMcePayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcImeConvertToMcePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeConvertToMcePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeConvertToMcePayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeConvertToMcePayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeConvertToMcePayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeConvertToMcePayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeConvertToMcePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetMaxMotionVectorCountINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetMaxMotionVectorCountINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetMaxMotionVectorCountINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetMaxMotionVectorCountINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MaxMotionVectorCount + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetMaxMotionVectorCountINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetMaxMotionVectorCountINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetMaxMotionVectorCountINTEL(int resultType, int resultId, int maxMotionVectorCount, int payload) + { + ResultType = resultType; + ResultId = resultId; + MaxMotionVectorCount = maxMotionVectorCount; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetMaxMotionVectorCountINTEL, ResultType, ResultId, MaxMotionVectorCount, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "maxMotionVectorCount": + MaxMotionVectorCount = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetMaxMotionVectorCountINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Threshold + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL(int resultType, int resultId, int threshold, int payload) + { + ResultType = resultType; + ResultId = resultId; + Threshold = threshold; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL, ResultType, ResultId, Threshold, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "threshold": + Threshold = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeSetWeightedSadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeSetWeightedSadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeSetWeightedSadINTEL | (1 << 16); + } + + public OpSubgroupAvcImeSetWeightedSadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeSetWeightedSadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedSadWeights + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeSetWeightedSadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeSetWeightedSadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeSetWeightedSadINTEL(int resultType, int resultId, int packedSadWeights, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedSadWeights = packedSadWeights; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeSetWeightedSadINTEL, ResultType, ResultId, PackedSadWeights, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedSadWeights": + PackedSadWeights = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeSetWeightedSadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL(int resultType, int resultId, int srcImage, int refImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL, ResultType, ResultId, SrcImage, RefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithDualReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithDualReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithDualReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithDualReferenceINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithDualReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int StreaminComponents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL(int resultType, int resultId, int srcImage, int refImage, int payload, int streaminComponents) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + StreaminComponents = streaminComponents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL, ResultType, ResultId, SrcImage, RefImage, Payload, StreaminComponents]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "streaminComponents": + StreaminComponents = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int StreaminComponents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload, int streaminComponents) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + StreaminComponents = streaminComponents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload, StreaminComponents]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "streaminComponents": + StreaminComponents = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL(int resultType, int resultId, int srcImage, int refImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL, ResultType, ResultId, SrcImage, RefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int StreaminComponents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL(int resultType, int resultId, int srcImage, int refImage, int payload, int streaminComponents) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + StreaminComponents = streaminComponents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL, ResultType, ResultId, SrcImage, RefImage, Payload, StreaminComponents]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "streaminComponents": + StreaminComponents = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int StreaminComponents + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload, int streaminComponents) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + StreaminComponents = streaminComponents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload, StreaminComponents]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "streaminComponents": + StreaminComponents = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeConvertToMceResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeConvertToMceResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeConvertToMceResultINTEL | (1 << 16); + } + + public OpSubgroupAvcImeConvertToMceResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeConvertToMceResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeConvertToMceResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeConvertToMceResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeConvertToMceResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeConvertToMceResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeConvertToMceResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetSingleReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetSingleReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetSingleReferenceStreaminINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetSingleReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetSingleReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetSingleReferenceStreaminINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetSingleReferenceStreaminINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetSingleReferenceStreaminINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetSingleReferenceStreaminINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetSingleReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetDualReferenceStreaminINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetDualReferenceStreaminINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetDualReferenceStreaminINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetDualReferenceStreaminINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetDualReferenceStreaminINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetDualReferenceStreaminINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetDualReferenceStreaminINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetDualReferenceStreaminINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetDualReferenceStreaminINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetDualReferenceStreaminINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeStripDualReferenceStreamoutINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeStripDualReferenceStreamoutINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeStripDualReferenceStreamoutINTEL | (1 << 16); + } + + public OpSubgroupAvcImeStripDualReferenceStreamoutINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeStripDualReferenceStreamoutINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeStripDualReferenceStreamoutINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeStripDualReferenceStreamoutINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeStripDualReferenceStreamoutINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeStripDualReferenceStreamoutINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeStripDualReferenceStreamoutINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL(int resultType, int resultId, int payload, int majorShape) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL, ResultType, ResultId, Payload, MajorShape]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL(int resultType, int resultId, int payload, int majorShape) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL, ResultType, ResultId, Payload, MajorShape]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL(int resultType, int resultId, int payload, int majorShape) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL, ResultType, ResultId, Payload, MajorShape]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL(int resultType, int resultId, int payload, int majorShape, int direction) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + Direction = direction; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL, ResultType, ResultId, Payload, MajorShape, Direction]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL(int resultType, int resultId, int payload, int majorShape, int direction) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + Direction = direction; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL, ResultType, ResultId, Payload, MajorShape, Direction]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShape + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL(int resultType, int resultId, int payload, int majorShape, int direction) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + MajorShape = majorShape; + Direction = direction; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL, ResultType, ResultId, Payload, MajorShape, Direction]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + case "majorShape": + MajorShape = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetBorderReachedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetBorderReachedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetBorderReachedINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetBorderReachedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetBorderReachedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ImageSelect + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetBorderReachedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetBorderReachedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetBorderReachedINTEL(int resultType, int resultId, int imageSelect, int payload) + { + ResultType = resultType; + ResultId = resultId; + ImageSelect = imageSelect; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetBorderReachedINTEL, ResultType, ResultId, ImageSelect, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "imageSelect": + ImageSelect = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetBorderReachedINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL | (1 << 16); + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcFmeInitializeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcFmeInitializeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcFmeInitializeINTEL | (1 << 16); + } + + public OpSubgroupAvcFmeInitializeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcFmeInitializeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcCoord + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MotionVectors + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShapes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinorShapes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PixelResolution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SadAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcFmeInitializeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcFmeInitializeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcFmeInitializeINTEL(int resultType, int resultId, int srcCoord, int motionVectors, int majorShapes, int minorShapes, int direction, int pixelResolution, int sadAdjustment) + { + ResultType = resultType; + ResultId = resultId; + SrcCoord = srcCoord; + MotionVectors = motionVectors; + MajorShapes = majorShapes; + MinorShapes = minorShapes; + Direction = direction; + PixelResolution = pixelResolution; + SadAdjustment = sadAdjustment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcFmeInitializeINTEL, ResultType, ResultId, SrcCoord, MotionVectors, MajorShapes, MinorShapes, Direction, PixelResolution, SadAdjustment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcCoord": + SrcCoord = o.ToLiteral(); + break; + case "motionVectors": + MotionVectors = o.ToLiteral(); + break; + case "majorShapes": + MajorShapes = o.ToLiteral(); + break; + case "minorShapes": + MinorShapes = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "pixelResolution": + PixelResolution = o.ToLiteral(); + break; + case "sadAdjustment": + SadAdjustment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcFmeInitializeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcBmeInitializeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcBmeInitializeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcBmeInitializeINTEL | (1 << 16); + } + + public OpSubgroupAvcBmeInitializeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcBmeInitializeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcCoord + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MotionVectors + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MajorShapes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinorShapes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PixelResolution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BidirectionalWeight + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SadAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcBmeInitializeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcBmeInitializeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcBmeInitializeINTEL(int resultType, int resultId, int srcCoord, int motionVectors, int majorShapes, int minorShapes, int direction, int pixelResolution, int bidirectionalWeight, int sadAdjustment) + { + ResultType = resultType; + ResultId = resultId; + SrcCoord = srcCoord; + MotionVectors = motionVectors; + MajorShapes = majorShapes; + MinorShapes = minorShapes; + Direction = direction; + PixelResolution = pixelResolution; + BidirectionalWeight = bidirectionalWeight; + SadAdjustment = sadAdjustment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcBmeInitializeINTEL, ResultType, ResultId, SrcCoord, MotionVectors, MajorShapes, MinorShapes, Direction, PixelResolution, BidirectionalWeight, SadAdjustment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcCoord": + SrcCoord = o.ToLiteral(); + break; + case "motionVectors": + MotionVectors = o.ToLiteral(); + break; + case "majorShapes": + MajorShapes = o.ToLiteral(); + break; + case "minorShapes": + MinorShapes = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + case "pixelResolution": + PixelResolution = o.ToLiteral(); + break; + case "bidirectionalWeight": + BidirectionalWeight = o.ToLiteral(); + break; + case "sadAdjustment": + SadAdjustment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcBmeInitializeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefConvertToMcePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefConvertToMcePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefConvertToMcePayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcRefConvertToMcePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefConvertToMcePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefConvertToMcePayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefConvertToMcePayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefConvertToMcePayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefConvertToMcePayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefConvertToMcePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefSetBidirectionalMixDisableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefSetBidirectionalMixDisableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefSetBidirectionalMixDisableINTEL | (1 << 16); + } + + public OpSubgroupAvcRefSetBidirectionalMixDisableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefSetBidirectionalMixDisableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefSetBidirectionalMixDisableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefSetBidirectionalMixDisableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefSetBidirectionalMixDisableINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefSetBidirectionalMixDisableINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefSetBidirectionalMixDisableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefSetBilinearFilterEnableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefSetBilinearFilterEnableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefSetBilinearFilterEnableINTEL | (1 << 16); + } + + public OpSubgroupAvcRefSetBilinearFilterEnableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefSetBilinearFilterEnableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefSetBilinearFilterEnableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefSetBilinearFilterEnableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefSetBilinearFilterEnableINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefSetBilinearFilterEnableINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefSetBilinearFilterEnableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL(int resultType, int resultId, int srcImage, int refImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL, ResultType, ResultId, SrcImage, RefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefEvaluateWithDualReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefEvaluateWithDualReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcRefEvaluateWithDualReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefEvaluateWithDualReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefEvaluateWithDualReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefEvaluateWithDualReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefEvaluateWithDualReferenceINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefEvaluateWithDualReferenceINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefEvaluateWithDualReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceIds + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL(int resultType, int resultId, int srcImage, int packedReferenceIds, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + PackedReferenceIds = packedReferenceIds; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL, ResultType, ResultId, SrcImage, PackedReferenceIds, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "packedReferenceIds": + PackedReferenceIds = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL | (1 << 16); + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceIds + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceFieldPolarities + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL(int resultType, int resultId, int srcImage, int packedReferenceIds, int packedReferenceFieldPolarities, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + PackedReferenceIds = packedReferenceIds; + PackedReferenceFieldPolarities = packedReferenceFieldPolarities; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL, ResultType, ResultId, SrcImage, PackedReferenceIds, PackedReferenceFieldPolarities, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "packedReferenceIds": + PackedReferenceIds = o.ToLiteral(); + break; + case "packedReferenceFieldPolarities": + PackedReferenceFieldPolarities = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcRefConvertToMceResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcRefConvertToMceResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcRefConvertToMceResultINTEL | (1 << 16); + } + + public OpSubgroupAvcRefConvertToMceResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcRefConvertToMceResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcRefConvertToMceResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcRefConvertToMceResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcRefConvertToMceResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcRefConvertToMceResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcRefConvertToMceResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicInitializeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicInitializeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicInitializeINTEL | (1 << 16); + } + + public OpSubgroupAvcSicInitializeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicInitializeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcCoord + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicInitializeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicInitializeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicInitializeINTEL(int resultType, int resultId, int srcCoord) + { + ResultType = resultType; + ResultId = resultId; + SrcCoord = srcCoord; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicInitializeINTEL, ResultType, ResultId, SrcCoord]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcCoord": + SrcCoord = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicInitializeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicConfigureSkcINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicConfigureSkcINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicConfigureSkcINTEL | (1 << 16); + } + + public OpSubgroupAvcSicConfigureSkcINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicConfigureSkcINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SkipBlockPartitionType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SkipMotionVectorMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MotionVectors + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BidirectionalWeight + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SadAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicConfigureSkcINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicConfigureSkcINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicConfigureSkcINTEL(int resultType, int resultId, int skipBlockPartitionType, int skipMotionVectorMask, int motionVectors, int bidirectionalWeight, int sadAdjustment, int payload) + { + ResultType = resultType; + ResultId = resultId; + SkipBlockPartitionType = skipBlockPartitionType; + SkipMotionVectorMask = skipMotionVectorMask; + MotionVectors = motionVectors; + BidirectionalWeight = bidirectionalWeight; + SadAdjustment = sadAdjustment; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicConfigureSkcINTEL, ResultType, ResultId, SkipBlockPartitionType, SkipMotionVectorMask, MotionVectors, BidirectionalWeight, SadAdjustment, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "skipBlockPartitionType": + SkipBlockPartitionType = o.ToLiteral(); + break; + case "skipMotionVectorMask": + SkipMotionVectorMask = o.ToLiteral(); + break; + case "motionVectors": + MotionVectors = o.ToLiteral(); + break; + case "bidirectionalWeight": + BidirectionalWeight = o.ToLiteral(); + break; + case "sadAdjustment": + SadAdjustment = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicConfigureSkcINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicConfigureIpeLumaINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicConfigureIpeLumaINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicConfigureIpeLumaINTEL | (1 << 16); + } + + public OpSubgroupAvcSicConfigureIpeLumaINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicConfigureIpeLumaINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LumaIntraPartitionMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int IntraNeighbourAvailabilty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LeftEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperLeftCornerLumaPixel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperRightEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SadAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicConfigureIpeLumaINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicConfigureIpeLumaINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicConfigureIpeLumaINTEL(int resultType, int resultId, int lumaIntraPartitionMask, int intraNeighbourAvailabilty, int leftEdgeLumaPixels, int upperLeftCornerLumaPixel, int upperEdgeLumaPixels, int upperRightEdgeLumaPixels, int sadAdjustment, int payload) + { + ResultType = resultType; + ResultId = resultId; + LumaIntraPartitionMask = lumaIntraPartitionMask; + IntraNeighbourAvailabilty = intraNeighbourAvailabilty; + LeftEdgeLumaPixels = leftEdgeLumaPixels; + UpperLeftCornerLumaPixel = upperLeftCornerLumaPixel; + UpperEdgeLumaPixels = upperEdgeLumaPixels; + UpperRightEdgeLumaPixels = upperRightEdgeLumaPixels; + SadAdjustment = sadAdjustment; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicConfigureIpeLumaINTEL, ResultType, ResultId, LumaIntraPartitionMask, IntraNeighbourAvailabilty, LeftEdgeLumaPixels, UpperLeftCornerLumaPixel, UpperEdgeLumaPixels, UpperRightEdgeLumaPixels, SadAdjustment, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "lumaIntraPartitionMask": + LumaIntraPartitionMask = o.ToLiteral(); + break; + case "intraNeighbourAvailabilty": + IntraNeighbourAvailabilty = o.ToLiteral(); + break; + case "leftEdgeLumaPixels": + LeftEdgeLumaPixels = o.ToLiteral(); + break; + case "upperLeftCornerLumaPixel": + UpperLeftCornerLumaPixel = o.ToLiteral(); + break; + case "upperEdgeLumaPixels": + UpperEdgeLumaPixels = o.ToLiteral(); + break; + case "upperRightEdgeLumaPixels": + UpperRightEdgeLumaPixels = o.ToLiteral(); + break; + case "sadAdjustment": + SadAdjustment = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicConfigureIpeLumaINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicConfigureIpeLumaChromaINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicConfigureIpeLumaChromaINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL | (1 << 16); + } + + public OpSubgroupAvcSicConfigureIpeLumaChromaINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicConfigureIpeLumaChromaINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LumaIntraPartitionMask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int IntraNeighbourAvailabilty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LeftEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperLeftCornerLumaPixel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperRightEdgeLumaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LeftEdgeChromaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperLeftCornerChromaPixel + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int UpperEdgeChromaPixels + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SadAdjustment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicConfigureIpeLumaChromaINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicConfigureIpeLumaChromaINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicConfigureIpeLumaChromaINTEL(int resultType, int resultId, int lumaIntraPartitionMask, int intraNeighbourAvailabilty, int leftEdgeLumaPixels, int upperLeftCornerLumaPixel, int upperEdgeLumaPixels, int upperRightEdgeLumaPixels, int leftEdgeChromaPixels, int upperLeftCornerChromaPixel, int upperEdgeChromaPixels, int sadAdjustment, int payload) + { + ResultType = resultType; + ResultId = resultId; + LumaIntraPartitionMask = lumaIntraPartitionMask; + IntraNeighbourAvailabilty = intraNeighbourAvailabilty; + LeftEdgeLumaPixels = leftEdgeLumaPixels; + UpperLeftCornerLumaPixel = upperLeftCornerLumaPixel; + UpperEdgeLumaPixels = upperEdgeLumaPixels; + UpperRightEdgeLumaPixels = upperRightEdgeLumaPixels; + LeftEdgeChromaPixels = leftEdgeChromaPixels; + UpperLeftCornerChromaPixel = upperLeftCornerChromaPixel; + UpperEdgeChromaPixels = upperEdgeChromaPixels; + SadAdjustment = sadAdjustment; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicConfigureIpeLumaChromaINTEL, ResultType, ResultId, LumaIntraPartitionMask, IntraNeighbourAvailabilty, LeftEdgeLumaPixels, UpperLeftCornerLumaPixel, UpperEdgeLumaPixels, UpperRightEdgeLumaPixels, LeftEdgeChromaPixels, UpperLeftCornerChromaPixel, UpperEdgeChromaPixels, SadAdjustment, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "lumaIntraPartitionMask": + LumaIntraPartitionMask = o.ToLiteral(); + break; + case "intraNeighbourAvailabilty": + IntraNeighbourAvailabilty = o.ToLiteral(); + break; + case "leftEdgeLumaPixels": + LeftEdgeLumaPixels = o.ToLiteral(); + break; + case "upperLeftCornerLumaPixel": + UpperLeftCornerLumaPixel = o.ToLiteral(); + break; + case "upperEdgeLumaPixels": + UpperEdgeLumaPixels = o.ToLiteral(); + break; + case "upperRightEdgeLumaPixels": + UpperRightEdgeLumaPixels = o.ToLiteral(); + break; + case "leftEdgeChromaPixels": + LeftEdgeChromaPixels = o.ToLiteral(); + break; + case "upperLeftCornerChromaPixel": + UpperLeftCornerChromaPixel = o.ToLiteral(); + break; + case "upperEdgeChromaPixels": + UpperEdgeChromaPixels = o.ToLiteral(); + break; + case "sadAdjustment": + SadAdjustment = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicConfigureIpeLumaChromaINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetMotionVectorMaskINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetMotionVectorMaskINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetMotionVectorMaskINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetMotionVectorMaskINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SkipBlockPartitionType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Direction + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetMotionVectorMaskINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetMotionVectorMaskINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetMotionVectorMaskINTEL(int resultType, int resultId, int skipBlockPartitionType, int direction) + { + ResultType = resultType; + ResultId = resultId; + SkipBlockPartitionType = skipBlockPartitionType; + Direction = direction; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetMotionVectorMaskINTEL, ResultType, ResultId, SkipBlockPartitionType, Direction]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "skipBlockPartitionType": + SkipBlockPartitionType = o.ToLiteral(); + break; + case "direction": + Direction = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetMotionVectorMaskINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicConvertToMcePayloadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicConvertToMcePayloadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicConvertToMcePayloadINTEL | (1 << 16); + } + + public OpSubgroupAvcSicConvertToMcePayloadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicConvertToMcePayloadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicConvertToMcePayloadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicConvertToMcePayloadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicConvertToMcePayloadINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicConvertToMcePayloadINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicConvertToMcePayloadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedShapePenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL(int resultType, int resultId, int packedShapePenalty, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedShapePenalty = packedShapePenalty; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL, ResultType, ResultId, PackedShapePenalty, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedShapePenalty": + PackedShapePenalty = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LumaModePenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LumaPackedNeighborModes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int LumaPackedNonDcPenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL(int resultType, int resultId, int lumaModePenalty, int lumaPackedNeighborModes, int lumaPackedNonDcPenalty, int payload) + { + ResultType = resultType; + ResultId = resultId; + LumaModePenalty = lumaModePenalty; + LumaPackedNeighborModes = lumaPackedNeighborModes; + LumaPackedNonDcPenalty = lumaPackedNonDcPenalty; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL, ResultType, ResultId, LumaModePenalty, LumaPackedNeighborModes, LumaPackedNonDcPenalty, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "lumaModePenalty": + LumaModePenalty = o.ToLiteral(); + break; + case "lumaPackedNeighborModes": + LumaPackedNeighborModes = o.ToLiteral(); + break; + case "lumaPackedNonDcPenalty": + LumaPackedNonDcPenalty = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ChromaModeBasePenalty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL(int resultType, int resultId, int chromaModeBasePenalty, int payload) + { + ResultType = resultType; + ResultId = resultId; + ChromaModeBasePenalty = chromaModeBasePenalty; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL, ResultType, ResultId, ChromaModeBasePenalty, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "chromaModeBasePenalty": + ChromaModeBasePenalty = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetBilinearFilterEnableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetBilinearFilterEnableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetBilinearFilterEnableINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetBilinearFilterEnableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetBilinearFilterEnableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetBilinearFilterEnableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetBilinearFilterEnableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetBilinearFilterEnableINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetBilinearFilterEnableINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetBilinearFilterEnableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedSadCoefficients + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL(int resultType, int resultId, int packedSadCoefficients, int payload) + { + ResultType = resultType; + ResultId = resultId; + PackedSadCoefficients = packedSadCoefficients; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL, ResultType, ResultId, PackedSadCoefficients, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packedSadCoefficients": + PackedSadCoefficients = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL | (1 << 16); + } + + public OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BlockBasedSkipType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL(int resultType, int resultId, int blockBasedSkipType, int payload) + { + ResultType = resultType; + ResultId = resultId; + BlockBasedSkipType = blockBasedSkipType; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL, ResultType, ResultId, BlockBasedSkipType, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "blockBasedSkipType": + BlockBasedSkipType = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicEvaluateIpeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicEvaluateIpeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicEvaluateIpeINTEL | (1 << 16); + } + + public OpSubgroupAvcSicEvaluateIpeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicEvaluateIpeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicEvaluateIpeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicEvaluateIpeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicEvaluateIpeINTEL(int resultType, int resultId, int srcImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicEvaluateIpeINTEL, ResultType, ResultId, SrcImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicEvaluateIpeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL(int resultType, int resultId, int srcImage, int refImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + RefImage = refImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL, ResultType, ResultId, SrcImage, RefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "refImage": + RefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicEvaluateWithDualReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicEvaluateWithDualReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcSicEvaluateWithDualReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicEvaluateWithDualReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BwdRefImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicEvaluateWithDualReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicEvaluateWithDualReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicEvaluateWithDualReferenceINTEL(int resultType, int resultId, int srcImage, int fwdRefImage, int bwdRefImage, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + FwdRefImage = fwdRefImage; + BwdRefImage = bwdRefImage; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicEvaluateWithDualReferenceINTEL, ResultType, ResultId, SrcImage, FwdRefImage, BwdRefImage, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "fwdRefImage": + FwdRefImage = o.ToLiteral(); + break; + case "bwdRefImage": + BwdRefImage = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicEvaluateWithDualReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL | (1 << 16); + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceIds + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL(int resultType, int resultId, int srcImage, int packedReferenceIds, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + PackedReferenceIds = packedReferenceIds; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL, ResultType, ResultId, SrcImage, PackedReferenceIds, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "packedReferenceIds": + PackedReferenceIds = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL | (1 << 16); + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int SrcImage + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceIds + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PackedReferenceFieldPolarities + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL(int resultType, int resultId, int srcImage, int packedReferenceIds, int packedReferenceFieldPolarities, int payload) + { + ResultType = resultType; + ResultId = resultId; + SrcImage = srcImage; + PackedReferenceIds = packedReferenceIds; + PackedReferenceFieldPolarities = packedReferenceFieldPolarities; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL, ResultType, ResultId, SrcImage, PackedReferenceIds, PackedReferenceFieldPolarities, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "srcImage": + SrcImage = o.ToLiteral(); + break; + case "packedReferenceIds": + PackedReferenceIds = o.ToLiteral(); + break; + case "packedReferenceFieldPolarities": + PackedReferenceFieldPolarities = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicConvertToMceResultINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicConvertToMceResultINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicConvertToMceResultINTEL | (1 << 16); + } + + public OpSubgroupAvcSicConvertToMceResultINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicConvertToMceResultINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicConvertToMceResultINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicConvertToMceResultINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicConvertToMceResultINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicConvertToMceResultINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicConvertToMceResultINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetIpeLumaShapeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetIpeLumaShapeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetIpeLumaShapeINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetIpeLumaShapeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetIpeLumaShapeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetIpeLumaShapeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetIpeLumaShapeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetIpeLumaShapeINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetIpeLumaShapeINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetIpeLumaShapeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetPackedIpeLumaModesINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetPackedIpeLumaModesINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetPackedIpeLumaModesINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetPackedIpeLumaModesINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetPackedIpeLumaModesINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetPackedIpeLumaModesINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetPackedIpeLumaModesINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetPackedIpeLumaModesINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetPackedIpeLumaModesINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetPackedIpeLumaModesINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetIpeChromaModeINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetIpeChromaModeINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetIpeChromaModeINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetIpeChromaModeINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetIpeChromaModeINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetIpeChromaModeINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetIpeChromaModeINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetIpeChromaModeINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetIpeChromaModeINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetIpeChromaModeINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupAvcSicGetInterRawSadsINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupAvcSicGetInterRawSadsINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupAvcSicGetInterRawSadsINTEL | (1 << 16); + } + + public OpSubgroupAvcSicGetInterRawSadsINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupAvcSicGetInterRawSadsINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Payload + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSubgroupAvcSicGetInterRawSadsINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSubgroupAvcSicGetInterRawSadsINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSubgroupAvcSicGetInterRawSadsINTEL(int resultType, int resultId, int payload) + { + ResultType = resultType; + ResultId = resultId; + Payload = payload; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupAvcSicGetInterRawSadsINTEL, ResultType, ResultId, Payload]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "payload": + Payload = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupAvcSicGetInterRawSadsINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVariableLengthArrayINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVariableLengthArrayINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVariableLengthArrayINTEL | (1 << 16); + } + + public OpVariableLengthArrayINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVariableLengthArrayINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Lenght + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVariableLengthArrayINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVariableLengthArrayINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVariableLengthArrayINTEL(int resultType, int resultId, int lenght) + { + ResultType = resultType; + ResultId = resultId; + Lenght = lenght; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVariableLengthArrayINTEL, ResultType, ResultId, Lenght]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "lenght": + Lenght = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVariableLengthArrayINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSaveMemoryINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSaveMemoryINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSaveMemoryINTEL | (1 << 16); + } + + public OpSaveMemoryINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSaveMemoryINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpSaveMemoryINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpSaveMemoryINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpSaveMemoryINTEL(int resultType, int resultId) + { + ResultType = resultType; + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSaveMemoryINTEL, ResultType, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSaveMemoryINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRestoreMemoryINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRestoreMemoryINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRestoreMemoryINTEL | (1 << 16); + } + + public OpRestoreMemoryINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRestoreMemoryINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Ptr + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpRestoreMemoryINTEL(int ptr) + { + Ptr = ptr; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRestoreMemoryINTEL, Ptr]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "ptr": + Ptr = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRestoreMemoryINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSinCosPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSinCosPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSinCosPiINTEL | (1 << 16); + } + + public OpArbitraryFloatSinCosPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSinCosPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FromSign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSinCosPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSinCosPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSinCosPiINTEL(int resultType, int resultId, int a, int m1, int mout, int fromSign, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + FromSign = fromSign; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSinCosPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..FromSign.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "fromSign": + FromSign = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSinCosPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCastINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCastINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCastINTEL | (1 << 16); + } + + public OpArbitraryFloatCastINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCastINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCastINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCastINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCastINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCastINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCastINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCastFromIntINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCastFromIntINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCastFromIntINTEL | (1 << 16); + } + + public OpArbitraryFloatCastFromIntINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCastFromIntINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FromSign + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCastFromIntINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCastFromIntINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCastFromIntINTEL(int resultType, int resultId, int a, int mout, int fromSign, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + Mout = mout; + FromSign = fromSign; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCastFromIntINTEL, ResultType, ResultId, A, ..Mout.AsDisposableLiteralValue().Words, ..FromSign.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "fromSign": + FromSign = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCastFromIntINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCastToIntINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCastToIntINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCastToIntINTEL | (1 << 16); + } + + public OpArbitraryFloatCastToIntINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCastToIntINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCastToIntINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCastToIntINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCastToIntINTEL(int resultType, int resultId, int a, int m1, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCastToIntINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCastToIntINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatAddINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatAddINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatAddINTEL | (1 << 16); + } + + public OpArbitraryFloatAddINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatAddINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatAddINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatAddINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatAddINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatAddINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatAddINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSubINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSubINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSubINTEL | (1 << 16); + } + + public OpArbitraryFloatSubINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSubINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSubINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSubINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSubINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSubINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSubINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatMulINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatMulINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatMulINTEL | (1 << 16); + } + + public OpArbitraryFloatMulINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatMulINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatMulINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatMulINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatMulINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatMulINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatMulINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatDivINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatDivINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatDivINTEL | (1 << 16); + } + + public OpArbitraryFloatDivINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatDivINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatDivINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatDivINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatDivINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatDivINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatDivINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatGTINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatGTINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatGTINTEL | (1 << 16); + } + + public OpArbitraryFloatGTINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatGTINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatGTINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatGTINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatGTINTEL(int resultType, int resultId, int a, int m1, int b, int m2) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatGTINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatGTINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatGEINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatGEINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatGEINTEL | (1 << 16); + } + + public OpArbitraryFloatGEINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatGEINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatGEINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatGEINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatGEINTEL(int resultType, int resultId, int a, int m1, int b, int m2) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatGEINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatGEINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLTINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLTINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLTINTEL | (1 << 16); + } + + public OpArbitraryFloatLTINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLTINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLTINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLTINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLTINTEL(int resultType, int resultId, int a, int m1, int b, int m2) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLTINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLTINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLEINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLEINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLEINTEL | (1 << 16); + } + + public OpArbitraryFloatLEINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLEINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLEINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLEINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLEINTEL(int resultType, int resultId, int a, int m1, int b, int m2) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLEINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLEINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatEQINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatEQINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatEQINTEL | (1 << 16); + } + + public OpArbitraryFloatEQINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatEQINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatEQINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatEQINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatEQINTEL(int resultType, int resultId, int a, int m1, int b, int m2) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatEQINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatEQINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatRecipINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatRecipINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatRecipINTEL | (1 << 16); + } + + public OpArbitraryFloatRecipINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatRecipINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatRecipINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatRecipINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatRecipINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatRecipINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatRecipINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatRSqrtINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatRSqrtINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatRSqrtINTEL | (1 << 16); + } + + public OpArbitraryFloatRSqrtINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatRSqrtINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatRSqrtINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatRSqrtINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatRSqrtINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatRSqrtINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatRSqrtINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCbrtINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCbrtINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCbrtINTEL | (1 << 16); + } + + public OpArbitraryFloatCbrtINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCbrtINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCbrtINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCbrtINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCbrtINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCbrtINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCbrtINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatHypotINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatHypotINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatHypotINTEL | (1 << 16); + } + + public OpArbitraryFloatHypotINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatHypotINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatHypotINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatHypotINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatHypotINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatHypotINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatHypotINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSqrtINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSqrtINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSqrtINTEL | (1 << 16); + } + + public OpArbitraryFloatSqrtINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSqrtINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSqrtINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSqrtINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSqrtINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSqrtINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSqrtINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLogINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLogINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLogINTEL | (1 << 16); + } + + public OpArbitraryFloatLogINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLogINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLogINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLogINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLogINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLogINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLogINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLog2INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLog2INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLog2INTEL | (1 << 16); + } + + public OpArbitraryFloatLog2INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLog2INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLog2INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLog2INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLog2INTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLog2INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLog2INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLog10INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLog10INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLog10INTEL | (1 << 16); + } + + public OpArbitraryFloatLog10INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLog10INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLog10INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLog10INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLog10INTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLog10INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLog10INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatLog1pINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatLog1pINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatLog1pINTEL | (1 << 16); + } + + public OpArbitraryFloatLog1pINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatLog1pINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatLog1pINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatLog1pINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatLog1pINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatLog1pINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatLog1pINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatExpINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatExpINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatExpINTEL | (1 << 16); + } + + public OpArbitraryFloatExpINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatExpINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatExpINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatExpINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatExpINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatExpINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatExpINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatExp2INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatExp2INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatExp2INTEL | (1 << 16); + } + + public OpArbitraryFloatExp2INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatExp2INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatExp2INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatExp2INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatExp2INTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatExp2INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatExp2INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatExp10INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatExp10INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatExp10INTEL | (1 << 16); + } + + public OpArbitraryFloatExp10INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatExp10INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatExp10INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatExp10INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatExp10INTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatExp10INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatExp10INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatExpm1INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatExpm1INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatExpm1INTEL | (1 << 16); + } + + public OpArbitraryFloatExpm1INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatExpm1INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatExpm1INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatExpm1INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatExpm1INTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatExpm1INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatExpm1INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSinINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSinINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSinINTEL | (1 << 16); + } + + public OpArbitraryFloatSinINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSinINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSinINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSinINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSinINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSinINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSinINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCosINTEL | (1 << 16); + } + + public OpArbitraryFloatCosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCosINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCosINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSinCosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSinCosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSinCosINTEL | (1 << 16); + } + + public OpArbitraryFloatSinCosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSinCosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSinCosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSinCosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSinCosINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSinCosINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSinCosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatSinPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatSinPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatSinPiINTEL | (1 << 16); + } + + public OpArbitraryFloatSinPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatSinPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatSinPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatSinPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatSinPiINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatSinPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatSinPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatCosPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatCosPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatCosPiINTEL | (1 << 16); + } + + public OpArbitraryFloatCosPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatCosPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatCosPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatCosPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatCosPiINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatCosPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatCosPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatASinINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatASinINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatASinINTEL | (1 << 16); + } + + public OpArbitraryFloatASinINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatASinINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatASinINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatASinINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatASinINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatASinINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatASinINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatASinPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatASinPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatASinPiINTEL | (1 << 16); + } + + public OpArbitraryFloatASinPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatASinPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatASinPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatASinPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatASinPiINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatASinPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatASinPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatACosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatACosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatACosINTEL | (1 << 16); + } + + public OpArbitraryFloatACosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatACosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatACosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatACosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatACosINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatACosINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatACosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatACosPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatACosPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatACosPiINTEL | (1 << 16); + } + + public OpArbitraryFloatACosPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatACosPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatACosPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatACosPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatACosPiINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatACosPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatACosPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatATanINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatATanINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatATanINTEL | (1 << 16); + } + + public OpArbitraryFloatATanINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatATanINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatATanINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatATanINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatATanINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatATanINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatATanINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatATanPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatATanPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatATanPiINTEL | (1 << 16); + } + + public OpArbitraryFloatATanPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatATanPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatATanPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatATanPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatATanPiINTEL(int resultType, int resultId, int a, int m1, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatATanPiINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatATanPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatATan2INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatATan2INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatATan2INTEL | (1 << 16); + } + + public OpArbitraryFloatATan2INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatATan2INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatATan2INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatATan2INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatATan2INTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatATan2INTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatATan2INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatPowINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatPowINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatPowINTEL | (1 << 16); + } + + public OpArbitraryFloatPowINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatPowINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatPowINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatPowINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatPowINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatPowINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatPowINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatPowRINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatPowRINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatPowRINTEL | (1 << 16); + } + + public OpArbitraryFloatPowRINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatPowRINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatPowRINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatPowRINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatPowRINTEL(int resultType, int resultId, int a, int m1, int b, int m2, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + M2 = m2; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatPowRINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..M2.AsDisposableLiteralValue().Words, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "m2": + M2 = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatPowRINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArbitraryFloatPowNINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArbitraryFloatPowNINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArbitraryFloatPowNINTEL | (1 << 16); + } + + public OpArbitraryFloatPowNINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArbitraryFloatPowNINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int M1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mout + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int EnableSubnormals + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingMode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RoundingAccuracy + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArbitraryFloatPowNINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArbitraryFloatPowNINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArbitraryFloatPowNINTEL(int resultType, int resultId, int a, int m1, int b, int mout, int enableSubnormals, int roundingMode, int roundingAccuracy) + { + ResultType = resultType; + ResultId = resultId; + A = a; + M1 = m1; + B = b; + Mout = mout; + EnableSubnormals = enableSubnormals; + RoundingMode = roundingMode; + RoundingAccuracy = roundingAccuracy; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArbitraryFloatPowNINTEL, ResultType, ResultId, A, ..M1.AsDisposableLiteralValue().Words, B, ..Mout.AsDisposableLiteralValue().Words, ..EnableSubnormals.AsDisposableLiteralValue().Words, ..RoundingMode.AsDisposableLiteralValue().Words, ..RoundingAccuracy.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "m1": + M1 = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "mout": + Mout = o.ToLiteral(); + break; + case "enableSubnormals": + EnableSubnormals = o.ToLiteral(); + break; + case "roundingMode": + RoundingMode = o.ToLiteral(); + break; + case "roundingAccuracy": + RoundingAccuracy = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArbitraryFloatPowNINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpLoopControlINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpLoopControlINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpLoopControlINTEL | (1 << 16); + } + + public OpLoopControlINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpLoopControlINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public LiteralArray LoopControlParameters + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpLoopControlINTEL(LiteralArray loopControlParameters) + { + LoopControlParameters = loopControlParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpLoopControlINTEL, ..LoopControlParameters.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "loopControlParameters": + LoopControlParameters = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (LoopControlParameters.WordCount == -1) + LoopControlParameters = new(); + } + + public static implicit operator OpLoopControlINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + LoopControlParameters.Dispose(); + } +} + +public ref partial struct OpAliasDomainDeclINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAliasDomainDeclINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAliasDomainDeclINTEL | (1 << 16); + } + + public OpAliasDomainDeclINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAliasDomainDeclINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAliasDomainDeclINTEL inst) => inst.ResultId; + public OpAliasDomainDeclINTEL(int resultId, int? name) + { + ResultId = resultId; + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAliasDomainDeclINTEL, ResultId, ..(Name is null ? (Span)[] : [Name.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "name": + if (o.Words.Length > 0) + { + Name = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAliasDomainDeclINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAliasScopeDeclINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAliasScopeDeclINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAliasScopeDeclINTEL | (1 << 16); + } + + public OpAliasScopeDeclINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAliasScopeDeclINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int AliasDomain + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAliasScopeDeclINTEL inst) => inst.ResultId; + public OpAliasScopeDeclINTEL(int resultId, int aliasDomain, int? name) + { + ResultId = resultId; + AliasDomain = aliasDomain; + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAliasScopeDeclINTEL, ResultId, AliasDomain, ..(Name is null ? (Span)[] : [Name.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "aliasDomain": + AliasDomain = o.ToLiteral(); + break; + case "name": + if (o.Words.Length > 0) + { + Name = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAliasScopeDeclINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAliasScopeListDeclINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAliasScopeListDeclINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAliasScopeListDeclINTEL | (1 << 16); + } + + public OpAliasScopeListDeclINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAliasScopeListDeclINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray AliasScope1s + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAliasScopeListDeclINTEL inst) => inst.ResultId; + public OpAliasScopeListDeclINTEL(int resultId, LiteralArray aliasScope1s) + { + ResultId = resultId; + AliasScope1s = aliasScope1s; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAliasScopeListDeclINTEL, ResultId, ..AliasScope1s.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "aliasScope1s": + AliasScope1s = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (AliasScope1s.WordCount == -1) + AliasScope1s = new(); + } + + public static implicit operator OpAliasScopeListDeclINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + AliasScope1s.Dispose(); + } +} + +public ref partial struct OpFixedSqrtINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedSqrtINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedSqrtINTEL | (1 << 16); + } + + public OpFixedSqrtINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedSqrtINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedSqrtINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedSqrtINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedSqrtINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedSqrtINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedSqrtINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedRecipINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedRecipINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedRecipINTEL | (1 << 16); + } + + public OpFixedRecipINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedRecipINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedRecipINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedRecipINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedRecipINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedRecipINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedRecipINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedRsqrtINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedRsqrtINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedRsqrtINTEL | (1 << 16); + } + + public OpFixedRsqrtINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedRsqrtINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedRsqrtINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedRsqrtINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedRsqrtINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedRsqrtINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedRsqrtINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedSinINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedSinINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedSinINTEL | (1 << 16); + } + + public OpFixedSinINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedSinINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedSinINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedSinINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedSinINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedSinINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedSinINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedCosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedCosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedCosINTEL | (1 << 16); + } + + public OpFixedCosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedCosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedCosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedCosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedCosINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedCosINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedCosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedSinCosINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedSinCosINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedSinCosINTEL | (1 << 16); + } + + public OpFixedSinCosINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedSinCosINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedSinCosINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedSinCosINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedSinCosINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedSinCosINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedSinCosINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedSinPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedSinPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedSinPiINTEL | (1 << 16); + } + + public OpFixedSinPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedSinPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedSinPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedSinPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedSinPiINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedSinPiINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedSinPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedCosPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedCosPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedCosPiINTEL | (1 << 16); + } + + public OpFixedCosPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedCosPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedCosPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedCosPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedCosPiINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedCosPiINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedCosPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedSinCosPiINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedSinCosPiINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedSinCosPiINTEL | (1 << 16); + } + + public OpFixedSinCosPiINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedSinCosPiINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedSinCosPiINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedSinCosPiINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedSinCosPiINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedSinCosPiINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedSinCosPiINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedLogINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedLogINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedLogINTEL | (1 << 16); + } + + public OpFixedLogINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedLogINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedLogINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedLogINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedLogINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedLogINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedLogINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFixedExpINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFixedExpINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFixedExpINTEL | (1 << 16); + } + + public OpFixedExpINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFixedExpINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int InputType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int S + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RI + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Q + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int O + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFixedExpINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFixedExpINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFixedExpINTEL(int resultType, int resultId, int inputType, int input, int s, int i, int rI, int q, int o) + { + ResultType = resultType; + ResultId = resultId; + InputType = inputType; + Input = input; + S = s; + I = i; + RI = rI; + Q = q; + O = o; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFixedExpINTEL, ResultType, ResultId, InputType, Input, ..S.AsDisposableLiteralValue().Words, ..I.AsDisposableLiteralValue().Words, ..RI.AsDisposableLiteralValue().Words, ..Q.AsDisposableLiteralValue().Words, ..O.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "inputType": + InputType = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + case "s": + S = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "rI": + RI = o.ToLiteral(); + break; + case "q": + Q = o.ToLiteral(); + break; + case "o": + O = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFixedExpINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpPtrCastToCrossWorkgroupINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpPtrCastToCrossWorkgroupINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpPtrCastToCrossWorkgroupINTEL | (1 << 16); + } + + public OpPtrCastToCrossWorkgroupINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpPtrCastToCrossWorkgroupINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpPtrCastToCrossWorkgroupINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpPtrCastToCrossWorkgroupINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpPtrCastToCrossWorkgroupINTEL(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpPtrCastToCrossWorkgroupINTEL, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpPtrCastToCrossWorkgroupINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCrossWorkgroupCastToPtrINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCrossWorkgroupCastToPtrINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCrossWorkgroupCastToPtrINTEL | (1 << 16); + } + + public OpCrossWorkgroupCastToPtrINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCrossWorkgroupCastToPtrINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCrossWorkgroupCastToPtrINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCrossWorkgroupCastToPtrINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCrossWorkgroupCastToPtrINTEL(int resultType, int resultId, int pointer) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCrossWorkgroupCastToPtrINTEL, ResultType, ResultId, Pointer]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCrossWorkgroupCastToPtrINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpReadPipeBlockingINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpReadPipeBlockingINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpReadPipeBlockingINTEL | (1 << 16); + } + + public OpReadPipeBlockingINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpReadPipeBlockingINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpReadPipeBlockingINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpReadPipeBlockingINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpReadPipeBlockingINTEL(int resultType, int resultId, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpReadPipeBlockingINTEL, ResultType, ResultId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpReadPipeBlockingINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpWritePipeBlockingINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpWritePipeBlockingINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpWritePipeBlockingINTEL | (1 << 16); + } + + public OpWritePipeBlockingINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpWritePipeBlockingINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketSize + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PacketAlignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpWritePipeBlockingINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpWritePipeBlockingINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpWritePipeBlockingINTEL(int resultType, int resultId, int packetSize, int packetAlignment) + { + ResultType = resultType; + ResultId = resultId; + PacketSize = packetSize; + PacketAlignment = packetAlignment; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpWritePipeBlockingINTEL, ResultType, ResultId, PacketSize, PacketAlignment]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "packetSize": + PacketSize = o.ToLiteral(); + break; + case "packetAlignment": + PacketAlignment = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpWritePipeBlockingINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpFPGARegINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFPGARegINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFPGARegINTEL | (1 << 16); + } + + public OpFPGARegINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFPGARegINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Result + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Input + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpFPGARegINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpFPGARegINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpFPGARegINTEL(int resultType, int resultId, int result, int input) + { + ResultType = resultType; + ResultId = resultId; + Result = result; + Input = input; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFPGARegINTEL, ResultType, ResultId, Result, Input]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "result": + Result = o.ToLiteral(); + break; + case "input": + Input = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFPGARegINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetRayTMinKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetRayTMinKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetRayTMinKHR | (1 << 16); + } + + public OpRayQueryGetRayTMinKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetRayTMinKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetRayTMinKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetRayTMinKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetRayTMinKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetRayTMinKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetRayTMinKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetRayFlagsKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetRayFlagsKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetRayFlagsKHR | (1 << 16); + } + + public OpRayQueryGetRayFlagsKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetRayFlagsKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetRayFlagsKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetRayFlagsKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetRayFlagsKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetRayFlagsKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetRayFlagsKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionTKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionTKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionTKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionTKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionTKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionTKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionTKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionTKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionTKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionTKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionInstanceCustomIndexKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionInstanceCustomIndexKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionInstanceCustomIndexKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionInstanceCustomIndexKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionInstanceCustomIndexKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionInstanceCustomIndexKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionInstanceCustomIndexKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionInstanceCustomIndexKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionInstanceCustomIndexKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionInstanceIdKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionInstanceIdKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionInstanceIdKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionInstanceIdKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionInstanceIdKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionInstanceIdKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionInstanceIdKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionInstanceIdKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionInstanceIdKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionInstanceIdKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionGeometryIndexKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionGeometryIndexKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionGeometryIndexKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionGeometryIndexKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionGeometryIndexKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionGeometryIndexKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionGeometryIndexKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionGeometryIndexKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionGeometryIndexKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionGeometryIndexKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionPrimitiveIndexKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionPrimitiveIndexKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionPrimitiveIndexKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionPrimitiveIndexKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionPrimitiveIndexKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionPrimitiveIndexKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionPrimitiveIndexKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionPrimitiveIndexKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionPrimitiveIndexKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionPrimitiveIndexKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionBarycentricsKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionBarycentricsKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionBarycentricsKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionBarycentricsKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionBarycentricsKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionBarycentricsKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionBarycentricsKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionBarycentricsKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionBarycentricsKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionBarycentricsKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionFrontFaceKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionFrontFaceKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionFrontFaceKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionFrontFaceKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionFrontFaceKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionFrontFaceKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionFrontFaceKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionFrontFaceKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionFrontFaceKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionFrontFaceKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionCandidateAABBOpaqueKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionCandidateAABBOpaqueKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionCandidateAABBOpaqueKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionCandidateAABBOpaqueKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionCandidateAABBOpaqueKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionCandidateAABBOpaqueKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionCandidateAABBOpaqueKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionCandidateAABBOpaqueKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionCandidateAABBOpaqueKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionCandidateAABBOpaqueKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionObjectRayDirectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionObjectRayDirectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionObjectRayDirectionKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionObjectRayDirectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionObjectRayDirectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionObjectRayDirectionKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionObjectRayDirectionKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionObjectRayDirectionKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionObjectRayDirectionKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionObjectRayDirectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionObjectRayOriginKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionObjectRayOriginKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionObjectRayOriginKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionObjectRayOriginKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionObjectRayOriginKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionObjectRayOriginKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionObjectRayOriginKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionObjectRayOriginKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionObjectRayOriginKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionObjectRayOriginKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetWorldRayDirectionKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetWorldRayDirectionKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetWorldRayDirectionKHR | (1 << 16); + } + + public OpRayQueryGetWorldRayDirectionKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetWorldRayDirectionKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetWorldRayDirectionKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetWorldRayDirectionKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetWorldRayDirectionKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetWorldRayDirectionKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetWorldRayDirectionKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetWorldRayOriginKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetWorldRayOriginKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetWorldRayOriginKHR | (1 << 16); + } + + public OpRayQueryGetWorldRayOriginKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetWorldRayOriginKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetWorldRayOriginKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetWorldRayOriginKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetWorldRayOriginKHR(int resultType, int resultId, int rayQuery) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetWorldRayOriginKHR, ResultType, ResultId, RayQuery]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetWorldRayOriginKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionObjectToWorldKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionObjectToWorldKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionObjectToWorldKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionObjectToWorldKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionObjectToWorldKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionObjectToWorldKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionObjectToWorldKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionObjectToWorldKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionObjectToWorldKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionObjectToWorldKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpRayQueryGetIntersectionWorldToObjectKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpRayQueryGetIntersectionWorldToObjectKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpRayQueryGetIntersectionWorldToObjectKHR | (1 << 16); + } + + public OpRayQueryGetIntersectionWorldToObjectKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpRayQueryGetIntersectionWorldToObjectKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int RayQuery + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Intersection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpRayQueryGetIntersectionWorldToObjectKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpRayQueryGetIntersectionWorldToObjectKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpRayQueryGetIntersectionWorldToObjectKHR(int resultType, int resultId, int rayQuery, int intersection) + { + ResultType = resultType; + ResultId = resultId; + RayQuery = rayQuery; + Intersection = intersection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpRayQueryGetIntersectionWorldToObjectKHR, ResultType, ResultId, RayQuery, Intersection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "rayQuery": + RayQuery = o.ToLiteral(); + break; + case "intersection": + Intersection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpRayQueryGetIntersectionWorldToObjectKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpAtomicFAddEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpAtomicFAddEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpAtomicFAddEXT | (1 << 16); + } + + public OpAtomicFAddEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpAtomicFAddEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Pointer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpAtomicFAddEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpAtomicFAddEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpAtomicFAddEXT(int resultType, int resultId, int pointer, int memory, int semantics, int value) + { + ResultType = resultType; + ResultId = resultId; + Pointer = pointer; + Memory = memory; + Semantics = semantics; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpAtomicFAddEXT, ResultType, ResultId, Pointer, Memory, Semantics, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "pointer": + Pointer = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpAtomicFAddEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeBufferSurfaceINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeBufferSurfaceINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeBufferSurfaceINTEL | (1 << 16); + } + + public OpTypeBufferSurfaceINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeBufferSurfaceINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public AccessQualifier AccessQualifier + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeBufferSurfaceINTEL inst) => inst.ResultId; + public OpTypeBufferSurfaceINTEL(int resultId, AccessQualifier accessQualifier) + { + ResultId = resultId; + AccessQualifier = accessQualifier; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeBufferSurfaceINTEL, ResultId, (int)AccessQualifier]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "accessQualifier": + AccessQualifier = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeBufferSurfaceINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeStructContinuedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeStructContinuedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeStructContinuedINTEL | (1 << 16); + } + + public OpTypeStructContinuedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeStructContinuedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public LiteralArray MemberTypes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpTypeStructContinuedINTEL(LiteralArray memberTypes) + { + MemberTypes = memberTypes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeStructContinuedINTEL, ..MemberTypes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "memberTypes": + MemberTypes = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (MemberTypes.WordCount == -1) + MemberTypes = new(); + } + + public static implicit operator OpTypeStructContinuedINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + MemberTypes.Dispose(); + } +} + +public ref partial struct OpConstantCompositeContinuedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantCompositeContinuedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantCompositeContinuedINTEL | (1 << 16); + } + + public OpConstantCompositeContinuedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantCompositeContinuedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpConstantCompositeContinuedINTEL(LiteralArray constituents) + { + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantCompositeContinuedINTEL, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpConstantCompositeContinuedINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpSpecConstantCompositeContinuedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSpecConstantCompositeContinuedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSpecConstantCompositeContinuedINTEL | (1 << 16); + } + + public OpSpecConstantCompositeContinuedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSpecConstantCompositeContinuedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSpecConstantCompositeContinuedINTEL(LiteralArray constituents) + { + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSpecConstantCompositeContinuedINTEL, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpSpecConstantCompositeContinuedINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpCompositeConstructContinuedINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositeConstructContinuedINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositeConstructContinuedINTEL | (1 << 16); + } + + public OpCompositeConstructContinuedINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositeConstructContinuedINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Constituents + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpCompositeConstructContinuedINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpCompositeConstructContinuedINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpCompositeConstructContinuedINTEL(int resultType, int resultId, LiteralArray constituents) + { + ResultType = resultType; + ResultId = resultId; + Constituents = constituents; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositeConstructContinuedINTEL, ResultType, ResultId, ..Constituents.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "constituents": + Constituents = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Constituents.WordCount == -1) + Constituents = new(); + } + + public static implicit operator OpCompositeConstructContinuedINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Constituents.Dispose(); + } +} + +public ref partial struct OpConvertFToBF16INTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertFToBF16INTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertFToBF16INTEL | (1 << 16); + } + + public OpConvertFToBF16INTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertFToBF16INTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FloatValue + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertFToBF16INTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertFToBF16INTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertFToBF16INTEL(int resultType, int resultId, int floatValue) + { + ResultType = resultType; + ResultId = resultId; + FloatValue = floatValue; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertFToBF16INTEL, ResultType, ResultId, FloatValue]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "floatValue": + FloatValue = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertFToBF16INTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConvertBF16ToFINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConvertBF16ToFINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConvertBF16ToFINTEL | (1 << 16); + } + + public OpConvertBF16ToFINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConvertBF16ToFINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BFloat16Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConvertBF16ToFINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpConvertBF16ToFINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpConvertBF16ToFINTEL(int resultType, int resultId, int bFloat16Value) + { + ResultType = resultType; + ResultId = resultId; + BFloat16Value = bFloat16Value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConvertBF16ToFINTEL, ResultType, ResultId, BFloat16Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "bFloat16Value": + BFloat16Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConvertBF16ToFINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpControlBarrierArriveINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpControlBarrierArriveINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpControlBarrierArriveINTEL | (1 << 16); + } + + public OpControlBarrierArriveINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpControlBarrierArriveINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpControlBarrierArriveINTEL(int execution, int memory, int semantics) + { + Execution = execution; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpControlBarrierArriveINTEL, Execution, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpControlBarrierArriveINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpControlBarrierWaitINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpControlBarrierWaitINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpControlBarrierWaitINTEL | (1 << 16); + } + + public OpControlBarrierWaitINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpControlBarrierWaitINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Memory + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Semantics + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpControlBarrierWaitINTEL(int execution, int memory, int semantics) + { + Execution = execution; + Memory = memory; + Semantics = semantics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpControlBarrierWaitINTEL, Execution, Memory, Semantics]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "execution": + Execution = o.ToLiteral(); + break; + case "memory": + Memory = o.ToLiteral(); + break; + case "semantics": + Semantics = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpControlBarrierWaitINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpArithmeticFenceEXT : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpArithmeticFenceEXT() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpArithmeticFenceEXT | (1 << 16); + } + + public OpArithmeticFenceEXT(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpArithmeticFenceEXT(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpArithmeticFenceEXT inst) => inst.ResultId; + public static implicit operator SpirvValue(OpArithmeticFenceEXT inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpArithmeticFenceEXT(int resultType, int resultId, int target) + { + ResultType = resultType; + ResultId = resultId; + Target = target; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpArithmeticFenceEXT, ResultType, ResultId, Target]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "target": + Target = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpArithmeticFenceEXT(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSubgroupBlockPrefetchINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSubgroupBlockPrefetchINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSubgroupBlockPrefetchINTEL | (1 << 16); + } + + public OpSubgroupBlockPrefetchINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSubgroupBlockPrefetchINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Ptr + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int NumBytes + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public MemoryAccessMask? MemoryAccess { get; set; } + + public EnumerantParameters MemoryAccessParameters + { + get; + set + { + field.Dispose(); + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSubgroupBlockPrefetchINTEL(int ptr, int numBytes, MemoryAccessMask? memoryAccess, EnumerantParameters memoryAccessParameters) + { + Ptr = ptr; + NumBytes = numBytes; + MemoryAccess = memoryAccess; + MemoryAccessParameters = memoryAccessParameters; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSubgroupBlockPrefetchINTEL, Ptr, NumBytes, ..(MemoryAccess is null ? (Span)[] : [(int)MemoryAccess.Value, ..MemoryAccessParameters])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "ptr": + Ptr = o.ToLiteral(); + break; + case "numBytes": + NumBytes = o.ToLiteral(); + break; + case "memoryAccess": + if (o.Words.Length > 0) + { + MemoryAccess = o.ToEnum(); + if (data.Memory.Span.Length > o.Offset + 1) + MemoryAccessParameters = new(data.Memory.Span[(o.Offset + 2)..]); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSubgroupBlockPrefetchINTEL(OpDataIndex odi) => new(odi); + public void Dispose() + { + MemoryAccessParameters.Dispose(); + } +} + +public ref partial struct OpGroupIMulKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupIMulKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupIMulKHR | (1 << 16); + } + + public OpGroupIMulKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupIMulKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupIMulKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupIMulKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupIMulKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupIMulKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupIMulKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupFMulKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupFMulKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupFMulKHR | (1 << 16); + } + + public OpGroupFMulKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupFMulKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupFMulKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupFMulKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupFMulKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupFMulKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupFMulKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupBitwiseAndKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupBitwiseAndKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupBitwiseAndKHR | (1 << 16); + } + + public OpGroupBitwiseAndKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupBitwiseAndKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupBitwiseAndKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupBitwiseAndKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupBitwiseAndKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupBitwiseAndKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupBitwiseAndKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupBitwiseOrKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupBitwiseOrKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupBitwiseOrKHR | (1 << 16); + } + + public OpGroupBitwiseOrKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupBitwiseOrKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupBitwiseOrKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupBitwiseOrKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupBitwiseOrKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupBitwiseOrKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupBitwiseOrKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupBitwiseXorKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupBitwiseXorKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupBitwiseXorKHR | (1 << 16); + } + + public OpGroupBitwiseXorKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupBitwiseXorKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupBitwiseXorKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupBitwiseXorKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupBitwiseXorKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupBitwiseXorKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupBitwiseXorKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupLogicalAndKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupLogicalAndKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupLogicalAndKHR | (1 << 16); + } + + public OpGroupLogicalAndKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupLogicalAndKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupLogicalAndKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupLogicalAndKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupLogicalAndKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupLogicalAndKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupLogicalAndKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupLogicalOrKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupLogicalOrKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupLogicalOrKHR | (1 << 16); + } + + public OpGroupLogicalOrKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupLogicalOrKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupLogicalOrKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupLogicalOrKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupLogicalOrKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupLogicalOrKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupLogicalOrKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGroupLogicalXorKHR : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGroupLogicalXorKHR() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGroupLogicalXorKHR | (1 << 16); + } + + public OpGroupLogicalXorKHR(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGroupLogicalXorKHR(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Execution + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GroupOperation Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGroupLogicalXorKHR inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGroupLogicalXorKHR inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGroupLogicalXorKHR(int resultType, int resultId, int execution, GroupOperation operation, int x) + { + ResultType = resultType; + ResultId = resultId; + Execution = execution; + Operation = operation; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGroupLogicalXorKHR, ResultType, ResultId, Execution, (int)Operation, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "execution": + Execution = o.ToLiteral(); + break; + case "operation": + Operation = o.ToEnum(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGroupLogicalXorKHR(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMaskedGatherINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMaskedGatherINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMaskedGatherINTEL | (1 << 16); + } + + public OpMaskedGatherINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMaskedGatherINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PtrVector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Alignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FillEmpty + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpMaskedGatherINTEL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpMaskedGatherINTEL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpMaskedGatherINTEL(int resultType, int resultId, int ptrVector, int alignment, int mask, int fillEmpty) + { + ResultType = resultType; + ResultId = resultId; + PtrVector = ptrVector; + Alignment = alignment; + Mask = mask; + FillEmpty = fillEmpty; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMaskedGatherINTEL, ResultType, ResultId, PtrVector, ..Alignment.AsDisposableLiteralValue().Words, Mask, FillEmpty]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "ptrVector": + PtrVector = o.ToLiteral(); + break; + case "alignment": + Alignment = o.ToLiteral(); + break; + case "mask": + Mask = o.ToLiteral(); + break; + case "fillEmpty": + FillEmpty = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMaskedGatherINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMaskedScatterINTEL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMaskedScatterINTEL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMaskedScatterINTEL | (1 << 16); + } + + public OpMaskedScatterINTEL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMaskedScatterINTEL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int InputVector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int PtrVector + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Alignment + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Mask + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMaskedScatterINTEL(int inputVector, int ptrVector, int alignment, int mask) + { + InputVector = inputVector; + PtrVector = ptrVector; + Alignment = alignment; + Mask = mask; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMaskedScatterINTEL, InputVector, PtrVector, ..Alignment.AsDisposableLiteralValue().Words, Mask]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "inputVector": + InputVector = o.ToLiteral(); + break; + case "ptrVector": + PtrVector = o.ToLiteral(); + break; + case "alignment": + Alignment = o.ToLiteral(); + break; + case "mask": + Mask = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMaskedScatterINTEL(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLRound : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLRound() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLRound(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLRound(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLRound inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLRound inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLRound(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLRound, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLRound(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLRoundEven : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLRoundEven() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLRoundEven(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLRoundEven(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLRoundEven inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLRoundEven inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLRoundEven(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLRoundEven, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLRoundEven(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLTrunc : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLTrunc() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLTrunc(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLTrunc(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLTrunc inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLTrunc inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLTrunc(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLTrunc, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLTrunc(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFAbs : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFAbs() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFAbs(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFAbs(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFAbs inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFAbs inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFAbs(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFAbs, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFAbs(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSAbs : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSAbs() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSAbs(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSAbs(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSAbs inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSAbs inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSAbs(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSAbs, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSAbs(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFSign : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFSign() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFSign(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFSign(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFSign inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFSign inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFSign(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFSign, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFSign(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSSign : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSSign() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSSign(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSSign(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSSign inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSSign inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSSign(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSSign, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSSign(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFloor : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFloor() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFloor(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFloor(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFloor inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFloor inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFloor(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFloor, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFloor(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLCeil : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLCeil() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLCeil(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLCeil(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLCeil inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLCeil inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLCeil(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLCeil, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLCeil(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFract inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFract(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFract, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFract(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLRadians : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLRadians() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLRadians(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLRadians(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Degrees + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLRadians inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLRadians inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLRadians(int resultType, int resultId, int set, int degrees) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Degrees = degrees; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLRadians, Degrees]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "degrees": + Degrees = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLRadians(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLDegrees : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLDegrees() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLDegrees(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLDegrees(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Radians + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLDegrees inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLDegrees inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLDegrees(int resultType, int resultId, int set, int radians) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Radians = radians; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLDegrees, Radians]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "radians": + Radians = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLDegrees(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSin(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSin, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLCos : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLCos() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLCos(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLCos(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLCos inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLCos inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLCos(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLCos, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLCos(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLTan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLTan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLTan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLTan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLTan inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLTan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLTan(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLTan, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLTan(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAsin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAsin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAsin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAsin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAsin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAsin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAsin(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAsin, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAsin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAcos : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAcos() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAcos(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAcos(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAcos inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAcos inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAcos(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAcos, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAcos(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAtan : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAtan() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAtan(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAtan(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y_over_x + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAtan inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAtan inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAtan(int resultType, int resultId, int set, int y_over_x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Y_over_x = y_over_x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAtan, Y_over_x]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "y_over_x": + Y_over_x = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAtan(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSinh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSinh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSinh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSinh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSinh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSinh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSinh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSinh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSinh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLCosh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLCosh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLCosh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLCosh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLCosh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLCosh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLCosh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLCosh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLCosh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLTanh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLTanh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLTanh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLTanh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLTanh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLTanh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLTanh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLTanh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLTanh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAsinh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAsinh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAsinh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAsinh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAsinh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAsinh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAsinh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAsinh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAsinh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAcosh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAcosh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAcosh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAcosh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAcosh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAcosh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAcosh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAcosh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAcosh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAtanh : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAtanh() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAtanh(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAtanh(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAtanh inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAtanh inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAtanh(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAtanh, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAtanh(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLAtan2 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLAtan2() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLAtan2(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLAtan2(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLAtan2 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLAtan2 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLAtan2(int resultType, int resultId, int set, int y, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Y = y; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLAtan2, Y, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLAtan2(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPow : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPow() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPow(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPow(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPow inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPow inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPow(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPow, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPow(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLExp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLExp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLExp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLExp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLExp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLExp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLExp(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLExp, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLExp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLLog : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLLog() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLLog(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLLog(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLLog inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLLog inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLLog(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLLog, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLLog(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLExp2 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLExp2() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLExp2(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLExp2(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLExp2 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLExp2 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLExp2(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLExp2, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLExp2(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLLog2 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLLog2() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLLog2(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLLog2(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLLog2 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLLog2 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLLog2(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLLog2, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLLog2(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSqrt : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSqrt() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSqrt(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSqrt(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSqrt inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSqrt inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSqrt(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSqrt, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSqrt(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLInverseSqrt : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLInverseSqrt() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLInverseSqrt(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLInverseSqrt(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLInverseSqrt inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLInverseSqrt inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLInverseSqrt(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLInverseSqrt, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLInverseSqrt(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLDeterminant : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLDeterminant() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLDeterminant(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLDeterminant(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLDeterminant inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLDeterminant inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLDeterminant(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLDeterminant, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLDeterminant(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLMatrixInverse : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLMatrixInverse() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLMatrixInverse(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLMatrixInverse(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLMatrixInverse inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLMatrixInverse inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLMatrixInverse(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLMatrixInverse, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLMatrixInverse(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLModf : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLModf() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLModf(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLModf(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLModf inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLModf inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLModf(int resultType, int resultId, int set, int x, int i) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + I = i; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLModf, X, I]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLModf(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLModfStruct : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLModfStruct() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLModfStruct(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLModfStruct(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLModfStruct inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLModfStruct inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLModfStruct(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLModfStruct, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLModfStruct(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFMin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFMin(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFMin, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUMin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUMin(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUMin, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSMin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSMin(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSMin, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFMax inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFMax(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFMax, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUMax inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUMax(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUMax, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSMax inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSMax(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSMax, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFClamp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFClamp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFClamp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFClamp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MaxVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFClamp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFClamp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFClamp(int resultType, int resultId, int set, int x, int minVal, int maxVal) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + MinVal = minVal; + MaxVal = maxVal; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFClamp, X, MinVal, MaxVal]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "minVal": + MinVal = o.ToLiteral(); + break; + case "maxVal": + MaxVal = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFClamp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUClamp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUClamp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUClamp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUClamp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MaxVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUClamp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUClamp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUClamp(int resultType, int resultId, int set, int x, int minVal, int maxVal) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + MinVal = minVal; + MaxVal = maxVal; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUClamp, X, MinVal, MaxVal]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "minVal": + MinVal = o.ToLiteral(); + break; + case "maxVal": + MaxVal = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUClamp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSClamp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSClamp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSClamp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSClamp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MaxVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSClamp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSClamp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSClamp(int resultType, int resultId, int set, int x, int minVal, int maxVal) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + MinVal = minVal; + MaxVal = maxVal; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSClamp, X, MinVal, MaxVal]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "minVal": + MinVal = o.ToLiteral(); + break; + case "maxVal": + MaxVal = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSClamp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFMix : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFMix() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFMix(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFMix(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFMix inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFMix inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFMix(int resultType, int resultId, int set, int x, int y, int a) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + A = a; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFMix, X, Y, A]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFMix(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLIMix : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLIMix() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLIMix(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLIMix(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLIMix inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLIMix inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLIMix(int resultType, int resultId, int set, int x, int y, int a) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + A = a; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLIMix, X, Y, A]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLIMix(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLStep : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLStep() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLStep(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLStep(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Edge + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLStep inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLStep inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLStep(int resultType, int resultId, int set, int edge, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Edge = edge; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLStep, Edge, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "edge": + Edge = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLStep(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLSmoothStep : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLSmoothStep() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLSmoothStep(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLSmoothStep(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Edge0 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Edge1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLSmoothStep inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLSmoothStep inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLSmoothStep(int resultType, int resultId, int set, int edge0, int edge1, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Edge0 = edge0; + Edge1 = edge1; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLSmoothStep, Edge0, Edge1, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "edge0": + Edge0 = o.ToLiteral(); + break; + case "edge1": + Edge1 = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLSmoothStep(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFma : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFma() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFma(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFma(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int A + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int B + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int C + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFma inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFma inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFma(int resultType, int resultId, int set, int a, int b, int c) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + A = a; + B = b; + C = c; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFma, A, B, C]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "a": + A = o.ToLiteral(); + break; + case "b": + B = o.ToLiteral(); + break; + case "c": + C = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFma(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFrexp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFrexp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFrexp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFrexp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Exp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFrexp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFrexp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFrexp(int resultType, int resultId, int set, int x, int exp) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Exp = exp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFrexp, X, Exp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "exp": + Exp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFrexp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFrexpStruct : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFrexpStruct() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFrexpStruct(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFrexpStruct(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFrexpStruct inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFrexpStruct inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFrexpStruct(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFrexpStruct, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFrexpStruct(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLLdexp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLLdexp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLLdexp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLLdexp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Exp + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLLdexp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLLdexp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLLdexp(int resultType, int resultId, int set, int x, int exp) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Exp = exp; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLLdexp, X, Exp]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "exp": + Exp = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLLdexp(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackSnorm4x8 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackSnorm4x8() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackSnorm4x8(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackSnorm4x8(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackSnorm4x8 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackSnorm4x8 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackSnorm4x8(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackSnorm4x8, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackSnorm4x8(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackUnorm4x8 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackUnorm4x8() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackUnorm4x8(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackUnorm4x8(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackUnorm4x8 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackUnorm4x8 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackUnorm4x8(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackUnorm4x8, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackUnorm4x8(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackSnorm2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackSnorm2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackSnorm2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackSnorm2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackSnorm2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackSnorm2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackSnorm2x16(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackSnorm2x16, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackSnorm2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackUnorm2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackUnorm2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackUnorm2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackUnorm2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackUnorm2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackUnorm2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackUnorm2x16(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackUnorm2x16, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackUnorm2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackHalf2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackHalf2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackHalf2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackHalf2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackHalf2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackHalf2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackHalf2x16(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackHalf2x16, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackHalf2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLPackDouble2x32 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLPackDouble2x32() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLPackDouble2x32(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLPackDouble2x32(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLPackDouble2x32 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLPackDouble2x32 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLPackDouble2x32(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLPackDouble2x32, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLPackDouble2x32(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackSnorm2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackSnorm2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackSnorm2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackSnorm2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackSnorm2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackSnorm2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackSnorm2x16(int resultType, int resultId, int set, int p) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackSnorm2x16, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackSnorm2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackUnorm2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackUnorm2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackUnorm2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackUnorm2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackUnorm2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackUnorm2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackUnorm2x16(int resultType, int resultId, int set, int p) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackUnorm2x16, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackUnorm2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackHalf2x16 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackHalf2x16() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackHalf2x16(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackHalf2x16(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackHalf2x16 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackHalf2x16 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackHalf2x16(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackHalf2x16, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackHalf2x16(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackSnorm4x8 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackSnorm4x8() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackSnorm4x8(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackSnorm4x8(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackSnorm4x8 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackSnorm4x8 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackSnorm4x8(int resultType, int resultId, int set, int p) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackSnorm4x8, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackSnorm4x8(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackUnorm4x8 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackUnorm4x8() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackUnorm4x8(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackUnorm4x8(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackUnorm4x8 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackUnorm4x8 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackUnorm4x8(int resultType, int resultId, int set, int p) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + P = p; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackUnorm4x8, P]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "p": + P = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackUnorm4x8(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLUnpackDouble2x32 : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLUnpackDouble2x32() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLUnpackDouble2x32(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLUnpackDouble2x32(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int V + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLUnpackDouble2x32 inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLUnpackDouble2x32 inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLUnpackDouble2x32(int resultType, int resultId, int set, int v) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + V = v; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLUnpackDouble2x32, V]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "v": + V = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLUnpackDouble2x32(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLLength : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLLength() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLLength(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLLength(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLLength inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLLength inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLLength(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLLength, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLLength(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLDistance : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLDistance() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLDistance(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLDistance(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P0 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int P1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLDistance inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLDistance inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLDistance(int resultType, int resultId, int set, int p0, int p1) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + P0 = p0; + P1 = p1; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLDistance, P0, P1]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "p0": + P0 = o.ToLiteral(); + break; + case "p1": + P1 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLDistance(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLCross : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLCross() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLCross(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLCross(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLCross inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLCross inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLCross(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLCross, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLCross(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLNormalize : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLNormalize() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLNormalize(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLNormalize(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLNormalize inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLNormalize inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLNormalize(int resultType, int resultId, int set, int x) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLNormalize, X]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLNormalize(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFaceForward : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFaceForward() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFaceForward(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFaceForward(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int N + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Nref + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFaceForward inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFaceForward inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFaceForward(int resultType, int resultId, int set, int n, int i, int nref) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + N = n; + I = i; + Nref = nref; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFaceForward, N, I, Nref]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "n": + N = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "nref": + Nref = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFaceForward(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLReflect : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLReflect() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLReflect(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLReflect(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int N + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLReflect inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLReflect inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLReflect(int resultType, int resultId, int set, int i, int n) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + I = i; + N = n; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLReflect, I, N]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "n": + N = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLReflect(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLRefract : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLRefract() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLRefract(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLRefract(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int I + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int N + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Eta + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLRefract inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLRefract inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLRefract(int resultType, int resultId, int set, int i, int n, int eta) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + I = i; + N = n; + Eta = eta; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLRefract, I, N, Eta]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "i": + I = o.ToLiteral(); + break; + case "n": + N = o.ToLiteral(); + break; + case "eta": + Eta = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLRefract(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFindILsb : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFindILsb() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFindILsb(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFindILsb(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFindILsb inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFindILsb inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFindILsb(int resultType, int resultId, int set, int value) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFindILsb, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFindILsb(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFindSMsb : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFindSMsb() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFindSMsb(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFindSMsb(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFindSMsb inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFindSMsb inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFindSMsb(int resultType, int resultId, int set, int value) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFindSMsb, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFindSMsb(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLFindUMsb : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLFindUMsb() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLFindUMsb(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLFindUMsb(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLFindUMsb inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLFindUMsb inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLFindUMsb(int resultType, int resultId, int set, int value) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Value = value; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLFindUMsb, Value]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLFindUMsb(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLInterpolateAtCentroid : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLInterpolateAtCentroid() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLInterpolateAtCentroid(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLInterpolateAtCentroid(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Interpolant + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLInterpolateAtCentroid inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLInterpolateAtCentroid inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLInterpolateAtCentroid(int resultType, int resultId, int set, int interpolant) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Interpolant = interpolant; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLInterpolateAtCentroid, Interpolant]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "interpolant": + Interpolant = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLInterpolateAtCentroid(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLInterpolateAtSample : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLInterpolateAtSample() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLInterpolateAtSample(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLInterpolateAtSample(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Interpolant + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Sample + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLInterpolateAtSample inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLInterpolateAtSample inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLInterpolateAtSample(int resultType, int resultId, int set, int interpolant, int sample) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Interpolant = interpolant; + Sample = sample; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLInterpolateAtSample, Interpolant, Sample]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "interpolant": + Interpolant = o.ToLiteral(); + break; + case "sample": + Sample = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLInterpolateAtSample(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLInterpolateAtOffset : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLInterpolateAtOffset() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLInterpolateAtOffset(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLInterpolateAtOffset(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Interpolant + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Offset + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLInterpolateAtOffset inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLInterpolateAtOffset inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLInterpolateAtOffset(int resultType, int resultId, int set, int interpolant, int offset) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + Interpolant = interpolant; + Offset = offset; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLInterpolateAtOffset, Interpolant, Offset]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "interpolant": + Interpolant = o.ToLiteral(); + break; + case "offset": + Offset = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLInterpolateAtOffset(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLNMin : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLNMin() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLNMin(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLNMin(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLNMin inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLNMin inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLNMin(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLNMin, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLNMin(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLNMax : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLNMax() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLNMax(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLNMax(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Y + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLNMax inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLNMax inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLNMax(int resultType, int resultId, int set, int x, int y) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + Y = y; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLNMax, X, Y]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "y": + Y = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLNMax(OpDataIndex odi) => new(odi); +} + +public ref partial struct GLSLNClamp : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public GLSLNClamp() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpExtInst | (1 << 16); + } + + public GLSLNClamp(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public GLSLNClamp(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Set + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int X + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MinVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int MaxVal + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (GLSLNClamp inst) => inst.ResultId; + public static implicit operator SpirvValue(GLSLNClamp inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public GLSLNClamp(int resultType, int resultId, int set, int x, int minVal, int maxVal) + { + ResultType = resultType; + ResultId = resultId; + Set = set; + X = x; + MinVal = minVal; + MaxVal = maxVal; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpExtInst, ResultType, ResultId, Set, (int)GLSLOp.GLSLNClamp, X, MinVal, MaxVal]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "set": + Set = o.ToLiteral(); + break; + case "x": + X = o.ToLiteral(); + break; + case "minVal": + MinVal = o.ToLiteral(); + break; + case "maxVal": + MaxVal = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator GLSLNClamp(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpShaderSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpShaderSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpShaderSDSL | (1 << 16); + } + + public OpShaderSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpShaderSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string ShaderName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpShaderSDSL(string shaderName) + { + ShaderName = shaderName; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpShaderSDSL, ..ShaderName.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "shaderName": + ShaderName = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpShaderSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCompositionSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositionSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositionSDSL | (1 << 16); + } + + public OpCompositionSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositionSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string CompositionPath + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpCompositionSDSL(string compositionPath) + { + CompositionPath = compositionPath; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositionSDSL, ..CompositionPath.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "compositionPath": + CompositionPath = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCompositionSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpCompositionEndSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpCompositionEndSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpCompositionEndSDSL | (1 << 16); + } + + public OpCompositionEndSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpCompositionEndSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpCompositionEndSDSL]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpCompositionEndSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMixinInheritSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMixinInheritSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMixinInheritSDSL | (1 << 16); + } + + public OpMixinInheritSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMixinInheritSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Shader + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public MixinInheritFlagsMask Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMixinInheritSDSL(int shader, MixinInheritFlagsMask flags) + { + Shader = shader; + Flags = flags; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMixinInheritSDSL, Shader, (int)Flags]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "shader": + Shader = o.ToLiteral(); + break; + case "flags": + Flags = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMixinInheritSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImportShaderSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImportShaderSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImportShaderSDSL | (1 << 16); + } + + public OpImportShaderSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImportShaderSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string ShaderName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Generics + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImportShaderSDSL inst) => inst.ResultId; + public OpImportShaderSDSL(int resultId, string shaderName, LiteralArray generics) + { + ResultId = resultId; + ShaderName = shaderName; + Generics = generics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImportShaderSDSL, ResultId, ..ShaderName.AsDisposableLiteralValue().Words, ..Generics.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "shaderName": + ShaderName = o.ToLiteral(); + break; + case "generics": + Generics = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Generics.WordCount == -1) + Generics = new(); + } + + public static implicit operator OpImportShaderSDSL(OpDataIndex odi) => new(odi); + public void Dispose() + { + Generics.Dispose(); + } +} + +public ref partial struct OpImportFunctionSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImportFunctionSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImportFunctionSDSL | (1 << 16); + } + + public OpImportFunctionSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImportFunctionSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int FunctionType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string FunctionName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shader + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public FunctionFlagsMask Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImportFunctionSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImportFunctionSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, FunctionType); + public OpImportFunctionSDSL(int resultId, int functionType, string functionName, int shader, FunctionFlagsMask flags) + { + ResultId = resultId; + FunctionType = functionType; + FunctionName = functionName; + Shader = shader; + Flags = flags; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImportFunctionSDSL, ResultId, FunctionType, ..FunctionName.AsDisposableLiteralValue().Words, Shader, (int)Flags]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "functionType": + FunctionType = o.ToLiteral(); + break; + case "functionName": + FunctionName = o.ToLiteral(); + break; + case "shader": + Shader = o.ToLiteral(); + break; + case "flags": + Flags = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImportFunctionSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImportVariableSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImportVariableSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImportVariableSDSL | (1 << 16); + } + + public OpImportVariableSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImportVariableSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string VariableName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shader + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public VariableFlagsMask Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImportVariableSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpImportVariableSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpImportVariableSDSL(int resultId, int resultType, string variableName, int shader, VariableFlagsMask flags) + { + ResultId = resultId; + ResultType = resultType; + VariableName = variableName; + Shader = shader; + Flags = flags; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImportVariableSDSL, ResultId, ResultType, ..VariableName.AsDisposableLiteralValue().Words, Shader, (int)Flags]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "resultType": + ResultType = o.ToLiteral(); + break; + case "variableName": + VariableName = o.ToLiteral(); + break; + case "shader": + Shader = o.ToLiteral(); + break; + case "flags": + Flags = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImportVariableSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpImportStructSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpImportStructSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpImportStructSDSL | (1 << 16); + } + + public OpImportStructSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpImportStructSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string StructName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Shader + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpImportStructSDSL inst) => inst.ResultId; + public OpImportStructSDSL(int resultId, string structName, int shader) + { + ResultId = resultId; + StructName = structName; + Shader = shader; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpImportStructSDSL, ResultId, ..StructName.AsDisposableLiteralValue().Words, Shader]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "structName": + StructName = o.ToLiteral(); + break; + case "shader": + Shader = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpImportStructSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpVariableSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpVariableSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpVariableSDSL | (1 << 16); + } + + public OpVariableSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpVariableSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StorageClass StorageClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public VariableFlagsMask Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int? MethodOrConstantInitializer + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpVariableSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpVariableSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpVariableSDSL(int resultType, int resultId, StorageClass storageClass, VariableFlagsMask flags, int? methodOrConstantInitializer) + { + ResultType = resultType; + ResultId = resultId; + StorageClass = storageClass; + Flags = flags; + MethodOrConstantInitializer = methodOrConstantInitializer; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpVariableSDSL, ResultType, ResultId, (int)StorageClass, (int)Flags, ..(MethodOrConstantInitializer is null ? (Span)[] : [MethodOrConstantInitializer.Value])]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "storageClass": + StorageClass = o.ToEnum(); + break; + case "flags": + Flags = o.ToEnum(); + break; + case "methodOrConstantInitializer": + if (o.Words.Length > 0) + { + MethodOrConstantInitializer = o.ToLiteral(); + } + + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpVariableSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMemberAccessSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMemberAccessSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMemberAccessSDSL | (1 << 16); + } + + public OpMemberAccessSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMemberAccessSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Instance + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Member + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpMemberAccessSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpMemberAccessSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpMemberAccessSDSL(int resultType, int resultId, int instance, int member) + { + ResultType = resultType; + ResultId = resultId; + Instance = instance; + Member = member; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMemberAccessSDSL, ResultType, ResultId, Instance, Member]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "instance": + Instance = o.ToLiteral(); + break; + case "member": + Member = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpMemberAccessSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeFunctionSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeFunctionSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeFunctionSDSL | (1 << 16); + } + + public OpTypeFunctionSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeFunctionSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ReturnType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray<(int, int)> ParameterTypes + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeFunctionSDSL inst) => inst.ResultId; + public OpTypeFunctionSDSL(int resultId, int returnType, LiteralArray<(int, int)> parameterTypes) + { + ResultId = resultId; + ReturnType = returnType; + ParameterTypes = parameterTypes; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeFunctionSDSL, ResultId, ReturnType, ..ParameterTypes.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "returnType": + ReturnType = o.ToLiteral(); + break; + case "parameterTypes": + ParameterTypes = o.ToLiteralArray<(int, int)>(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (ParameterTypes.WordCount == -1) + ParameterTypes = new(); + } + + public static implicit operator OpTypeFunctionSDSL(OpDataIndex odi) => new(odi); + public void Dispose() + { + ParameterTypes.Dispose(); + } +} + +public ref partial struct OpFunctionMetadataSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpFunctionMetadataSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpFunctionMetadataSDSL | (1 << 16); + } + + public OpFunctionMetadataSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpFunctionMetadataSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public FunctionFlagsMask Flags + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Parent + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpFunctionMetadataSDSL(FunctionFlagsMask flags, int parent) + { + Flags = flags; + Parent = parent; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpFunctionMetadataSDSL, (int)Flags, Parent]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "flags": + Flags = o.ToEnum(); + break; + case "parent": + Parent = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpFunctionMetadataSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBaseSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBaseSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBaseSDSL | (1 << 16); + } + + public OpBaseSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBaseSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBaseSDSL inst) => inst.ResultId; + public OpBaseSDSL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBaseSDSL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBaseSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpThisSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpThisSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpThisSDSL | (1 << 16); + } + + public OpThisSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpThisSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpThisSDSL inst) => inst.ResultId; + public OpThisSDSL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpThisSDSL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpThisSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpStreamsSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpStreamsSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpStreamsSDSL | (1 << 16); + } + + public OpStreamsSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpStreamsSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpStreamsSDSL inst) => inst.ResultId; + public OpStreamsSDSL(int resultId) + { + ResultId = resultId; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpStreamsSDSL, ResultId]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpStreamsSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGenericParameterSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGenericParameterSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGenericParameterSDSL | (1 << 16); + } + + public OpGenericParameterSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGenericParameterSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string DeclaringClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGenericParameterSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGenericParameterSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGenericParameterSDSL(int resultType, int resultId, int index, string declaringClass) + { + ResultType = resultType; + ResultId = resultId; + Index = index; + DeclaringClass = declaringClass; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGenericParameterSDSL, ResultType, ResultId, ..Index.AsDisposableLiteralValue().Words, ..DeclaringClass.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + case "declaringClass": + DeclaringClass = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGenericParameterSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpGenericReferenceSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpGenericReferenceSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpGenericReferenceSDSL | (1 << 16); + } + + public OpGenericReferenceSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpGenericReferenceSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Index + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string DeclaringClass + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpGenericReferenceSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpGenericReferenceSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpGenericReferenceSDSL(int resultType, int resultId, int index, string declaringClass) + { + ResultType = resultType; + ResultId = resultId; + Index = index; + DeclaringClass = declaringClass; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpGenericReferenceSDSL, ResultType, ResultId, ..Index.AsDisposableLiteralValue().Words, ..DeclaringClass.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "index": + Index = o.ToLiteral(); + break; + case "declaringClass": + DeclaringClass = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpGenericReferenceSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpConstantStringSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpConstantStringSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpConstantStringSDSL | (1 << 16); + } + + public OpConstantStringSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpConstantStringSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string LiteralString + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpConstantStringSDSL inst) => inst.ResultId; + public OpConstantStringSDSL(int resultId, string literalString) + { + ResultId = resultId; + LiteralString = literalString; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpConstantStringSDSL, ResultId, ..LiteralString.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "literalString": + LiteralString = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpConstantStringSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeGenericSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeGenericSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeGenericSDSL | (1 << 16); + } + + public OpTypeGenericSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeGenericSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GenericParameterKindSDSL Kind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeGenericSDSL inst) => inst.ResultId; + public OpTypeGenericSDSL(int resultId, GenericParameterKindSDSL kind) + { + ResultId = resultId; + Kind = kind; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeGenericSDSL, ResultId, (int)Kind]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "kind": + Kind = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeGenericSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeStreamsSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeStreamsSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeStreamsSDSL | (1 << 16); + } + + public OpTypeStreamsSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeStreamsSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public StreamsKindSDSL Kind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeStreamsSDSL inst) => inst.ResultId; + public OpTypeStreamsSDSL(int resultId, StreamsKindSDSL kind) + { + ResultId = resultId; + Kind = kind; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeStreamsSDSL, ResultId, (int)Kind]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "kind": + Kind = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeStreamsSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypeGeometryStreamOutputSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypeGeometryStreamOutputSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypeGeometryStreamOutputSDSL | (1 << 16); + } + + public OpTypeGeometryStreamOutputSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypeGeometryStreamOutputSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public GeometryStreamOutputKindSDSL Kind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypeGeometryStreamOutputSDSL inst) => inst.ResultId; + public OpTypeGeometryStreamOutputSDSL(int resultId, int baseType, GeometryStreamOutputKindSDSL kind) + { + ResultId = resultId; + BaseType = baseType; + Kind = kind; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypeGeometryStreamOutputSDSL, ResultId, BaseType, (int)Kind]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "kind": + Kind = o.ToEnum(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypeGeometryStreamOutputSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpTypePatchSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpTypePatchSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpTypePatchSDSL | (1 << 16); + } + + public OpTypePatchSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpTypePatchSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int BaseType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public PatchTypeKindSDSL Kind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Size + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpTypePatchSDSL inst) => inst.ResultId; + public OpTypePatchSDSL(int resultId, int baseType, PatchTypeKindSDSL kind, int size) + { + ResultId = resultId; + BaseType = baseType; + Kind = kind; + Size = size; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpTypePatchSDSL, ResultId, BaseType, (int)Kind, ..Size.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultId": + ResultId = o.ToLiteral(); + break; + case "baseType": + BaseType = o.ToLiteral(); + break; + case "kind": + Kind = o.ToEnum(); + break; + case "size": + Size = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpTypePatchSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpForeachSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpForeachSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpForeachSDSL | (1 << 16); + } + + public OpForeachSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpForeachSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Collection + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpForeachSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpForeachSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpForeachSDSL(int resultType, int resultId, int collection) + { + ResultType = resultType; + ResultId = resultId; + Collection = collection; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpForeachSDSL, ResultType, ResultId, Collection]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "collection": + Collection = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpForeachSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpForeachEndSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpForeachEndSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpForeachEndSDSL | (1 << 16); + } + + public OpForeachEndSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpForeachEndSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpForeachEndSDSL]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpForeachEndSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpUnresolvableShaderSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpUnresolvableShaderSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpUnresolvableShaderSDSL | (1 << 16); + } + + public OpUnresolvableShaderSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpUnresolvableShaderSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string ShaderCode + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ShaderCodeNameEnd + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpUnresolvableShaderSDSL(string shaderCode, int shaderCodeNameEnd) + { + ShaderCode = shaderCode; + ShaderCodeNameEnd = shaderCodeNameEnd; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpUnresolvableShaderSDSL, ..ShaderCode.AsDisposableLiteralValue().Words, ..ShaderCodeNameEnd.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "shaderCode": + ShaderCode = o.ToLiteral(); + break; + case "shaderCodeNameEnd": + ShaderCodeNameEnd = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpUnresolvableShaderSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEmitVertexSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEmitVertexSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEmitVertexSDSL | (1 << 16); + } + + public OpEmitVertexSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEmitVertexSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int Output + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEmitVertexSDSL(int output) + { + Output = output; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEmitVertexSDSL, Output]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "output": + Output = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEmitVertexSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpBinaryOperationSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpBinaryOperationSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpBinaryOperationSDSL | (1 << 16); + } + + public OpBinaryOperationSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpBinaryOperationSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ResultType + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int ResultId + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operation + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Operand2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public static implicit operator int (OpBinaryOperationSDSL inst) => inst.ResultId; + public static implicit operator SpirvValue(OpBinaryOperationSDSL inst) => inst.ToValue(); + public SpirvValue ToValue() => new(ResultId, ResultType); + public OpBinaryOperationSDSL(int resultType, int resultId, int operation, int operand1, int operand2) + { + ResultType = resultType; + ResultId = resultId; + Operation = operation; + Operand1 = operand1; + Operand2 = operand2; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpBinaryOperationSDSL, ResultType, ResultId, ..Operation.AsDisposableLiteralValue().Words, Operand1, Operand2]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "resultType": + ResultType = o.ToLiteral(); + break; + case "resultId": + ResultId = o.ToLiteral(); + break; + case "operation": + Operation = o.ToLiteral(); + break; + case "operand1": + Operand1 = o.ToLiteral(); + break; + case "operand2": + Operand2 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpBinaryOperationSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpSourceHashSDSL : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpSourceHashSDSL() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpSourceHashSDSL | (1 << 16); + } + + public OpSourceHashSDSL(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpSourceHashSDSL(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int File + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Hash1 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Hash2 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Hash3 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Hash4 + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpSourceHashSDSL(int file, int hash1, int hash2, int hash3, int hash4) + { + File = file; + Hash1 = hash1; + Hash2 = hash2; + Hash3 = hash3; + Hash4 = hash4; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpSourceHashSDSL, File, ..Hash1.AsDisposableLiteralValue().Words, ..Hash2.AsDisposableLiteralValue().Words, ..Hash3.AsDisposableLiteralValue().Words, ..Hash4.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "file": + File = o.ToLiteral(); + break; + case "hash1": + Hash1 = o.ToLiteral(); + break; + case "hash2": + Hash2 = o.ToLiteral(); + break; + case "hash3": + Hash3 = o.ToLiteral(); + break; + case "hash4": + Hash4 = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpSourceHashSDSL(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpEffectSDFX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpEffectSDFX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpEffectSDFX | (1 << 16); + } + + public OpEffectSDFX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpEffectSDFX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string EffectName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpEffectSDFX(string effectName) + { + EffectName = effectName; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpEffectSDFX, ..EffectName.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "effectName": + EffectName = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpEffectSDFX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpParamsUseSDFX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpParamsUseSDFX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpParamsUseSDFX | (1 << 16); + } + + public OpParamsUseSDFX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpParamsUseSDFX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public int ParamsName + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpParamsUseSDFX(int paramsName) + { + ParamsName = paramsName; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpParamsUseSDFX, ParamsName]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "paramsName": + ParamsName = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpParamsUseSDFX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpParamsSDFX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpParamsSDFX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpParamsSDFX | (1 << 16); + } + + public OpParamsSDFX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpParamsSDFX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpParamsSDFX(string name) + { + Name = name; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpParamsSDFX, ..Name.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "name": + Name = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpParamsSDFX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpParamsFieldSDFX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpParamsFieldSDFX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpParamsFieldSDFX | (1 << 16); + } + + public OpParamsFieldSDFX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpParamsFieldSDFX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public string Name + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public string Cstype + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpParamsFieldSDFX(string name, string cstype) + { + Name = name; + Cstype = cstype; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpParamsFieldSDFX, ..Name.AsDisposableLiteralValue().Words, ..Cstype.AsDisposableLiteralValue().Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "name": + Name = o.ToLiteral(); + break; + case "cstype": + Cstype = o.ToLiteral(); + break; + // We ignore unrecognized operands + default: + break; + } + } + } + + public static implicit operator OpParamsFieldSDFX(OpDataIndex odi) => new(odi); +} + +public ref partial struct OpMixinSDFX : IMemoryInstruction +{ + private ref OpData opData; + public ref OpData OpData => ref opData; + + public MemoryOwner InstructionMemory + { + get + { + if (!Unsafe.IsNullRef(ref OpData)) + return OpData.Memory; + else + return field; + } + + private set + { + if (!Unsafe.IsNullRef(ref OpData)) + { + OpData.Memory.Dispose(); + OpData.Memory = value; + } + else + field = value; + } + } + + public OpMixinSDFX() + { + InstructionMemory = MemoryOwner.Allocate(1); + InstructionMemory.Span[0] = (int)Op.OpMixinSDFX | (1 << 16); + } + + public OpMixinSDFX(OpDataIndex index) + { + InitializeProperties(ref index.Data); + opData = ref index.Data; + } + + public OpMixinSDFX(ref OpData data) + { + InitializeProperties(ref data); + opData = ref data; + } + + public MixinKindSDFX Kind + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Target + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public int Value + { + get; + set + { + field = value; + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public LiteralArray Generics + { + get; + set + { + field.Assign(value); + if (InstructionMemory is not null) + UpdateInstructionMemory(); + } + } + + public OpMixinSDFX(MixinKindSDFX kind, int target, int value, LiteralArray generics) + { + Kind = kind; + Target = target; + Value = value; + Generics = generics; + UpdateInstructionMemory(); + opData = ref Unsafe.NullRef(); + } + + public void Attach(OpDataIndex index) + { + opData = ref index.Data; + } + + public void UpdateInstructionMemory() + { + InstructionMemory ??= MemoryOwner.Empty; + Span instruction = [(int)Op.OpMixinSDFX, (int)Kind, Target, Value, ..Generics.Words]; + instruction[0] |= instruction.Length << 16; + if (instruction.Length == InstructionMemory.Length) + instruction.CopyTo(InstructionMemory.Span); + else + { + var tmp = MemoryOwner.Allocate(instruction.Length); + instruction.CopyTo(tmp.Span); + InstructionMemory?.Dispose(); + InstructionMemory = tmp; + } + } + + private void InitializeProperties(ref OpData data) + { + foreach (var o in data) + { + switch (o.Name) + { + case "kind": + Kind = o.ToEnum(); + break; + case "target": + Target = o.ToLiteral(); + break; + case "value": + Value = o.ToLiteral(); + break; + case "generics": + Generics = o.ToLiteralArray(); + break; + // We ignore unrecognized operands + default: + break; + } + } + + if (Generics.WordCount == -1) + Generics = new(); + } + + public static implicit operator OpMixinSDFX(OpDataIndex odi) => new(odi); + public void Dispose() + { + Generics.Dispose(); + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/OperandKind.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/OperandKind.gen.cs new file mode 100644 index 0000000000..5febae6498 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/OperandKind.gen.cs @@ -0,0 +1,232 @@ +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv.Core; +public enum OperandKind +{ + None, + ImageOperands, + FPFastMathMode, + SelectionControl, + LoopControl, + FunctionControl, + MemorySemantics, + MemoryAccess, + KernelProfilingInfo, + RayFlags, + FragmentShadingRate, + RawAccessChainOperands, + SourceLanguage, + ExecutionModel, + AddressingModel, + MemoryModel, + ExecutionMode, + StorageClass, + Dim, + SamplerAddressingMode, + SamplerFilterMode, + ImageFormat, + ImageChannelOrder, + ImageChannelDataType, + FPRoundingMode, + FPDenormMode, + QuantizationModes, + FPOperationMode, + OverflowModes, + LinkageType, + AccessQualifier, + HostAccessQualifier, + FunctionParameterAttribute, + Decoration, + BuiltIn, + Scope, + GroupOperation, + KernelEnqueueFlags, + Capability, + RayQueryIntersection, + RayQueryCommittedIntersectionType, + RayQueryCandidateIntersectionType, + PackedVectorFormat, + CooperativeMatrixOperands, + CooperativeMatrixLayout, + CooperativeMatrixUse, + CooperativeMatrixReduce, + TensorClampMode, + TensorAddressingOperands, + InitializationModeQualifier, + LoadCacheControl, + StoreCacheControl, + NamedMaximumNumberOfRegisters, + FPEncoding, + IdResultType, + IdResult, + IdMemorySemantics, + IdScope, + IdRef, + LiteralInteger, + LiteralString, + LiteralFloat, + LiteralContextDependentNumber, + LiteralExtInstInteger, + LiteralSpecConstantOpInteger, + PairLiteralIntegerIdRef, + PairIdRefLiteralInteger, + PairIdRefIdRef, + MixinInheritFlags, + FunctionFlags, + VariableFlags, + GenericParameterKindSDSL, + StreamsKindSDSL, + GeometryStreamOutputKindSDSL, + PatchTypeKindSDSL, + SamplerTextureAddressModeSDSL, + SamplerFilterSDSL, + SamplerComparisonFuncSDSL, + MixinKindSDFX, +} + +public static class OperandKindExtensions +{ + public static bool IsEnum(this OperandKind kind) + { + return kind switch + { + OperandKind.ImageOperands => true, + OperandKind.FPFastMathMode => true, + OperandKind.SelectionControl => true, + OperandKind.LoopControl => true, + OperandKind.FunctionControl => true, + OperandKind.MemorySemantics => true, + OperandKind.MemoryAccess => true, + OperandKind.KernelProfilingInfo => true, + OperandKind.RayFlags => true, + OperandKind.FragmentShadingRate => true, + OperandKind.RawAccessChainOperands => true, + OperandKind.SourceLanguage => true, + OperandKind.ExecutionModel => true, + OperandKind.AddressingModel => true, + OperandKind.MemoryModel => true, + OperandKind.ExecutionMode => true, + OperandKind.StorageClass => true, + OperandKind.Dim => true, + OperandKind.SamplerAddressingMode => true, + OperandKind.SamplerFilterMode => true, + OperandKind.ImageFormat => true, + OperandKind.ImageChannelOrder => true, + OperandKind.ImageChannelDataType => true, + OperandKind.FPRoundingMode => true, + OperandKind.FPDenormMode => true, + OperandKind.QuantizationModes => true, + OperandKind.FPOperationMode => true, + OperandKind.OverflowModes => true, + OperandKind.LinkageType => true, + OperandKind.AccessQualifier => true, + OperandKind.HostAccessQualifier => true, + OperandKind.FunctionParameterAttribute => true, + OperandKind.Decoration => true, + OperandKind.BuiltIn => true, + OperandKind.Scope => true, + OperandKind.GroupOperation => true, + OperandKind.KernelEnqueueFlags => true, + OperandKind.Capability => true, + OperandKind.RayQueryIntersection => true, + OperandKind.RayQueryCommittedIntersectionType => true, + OperandKind.RayQueryCandidateIntersectionType => true, + OperandKind.PackedVectorFormat => true, + OperandKind.CooperativeMatrixOperands => true, + OperandKind.CooperativeMatrixLayout => true, + OperandKind.CooperativeMatrixUse => true, + OperandKind.CooperativeMatrixReduce => true, + OperandKind.TensorClampMode => true, + OperandKind.TensorAddressingOperands => true, + OperandKind.InitializationModeQualifier => true, + OperandKind.LoadCacheControl => true, + OperandKind.StoreCacheControl => true, + OperandKind.NamedMaximumNumberOfRegisters => true, + OperandKind.FPEncoding => true, + OperandKind.MixinInheritFlags => true, + OperandKind.FunctionFlags => true, + OperandKind.VariableFlags => true, + OperandKind.GenericParameterKindSDSL => true, + OperandKind.StreamsKindSDSL => true, + OperandKind.GeometryStreamOutputKindSDSL => true, + OperandKind.PatchTypeKindSDSL => true, + OperandKind.SamplerTextureAddressModeSDSL => true, + OperandKind.SamplerFilterSDSL => true, + OperandKind.SamplerComparisonFuncSDSL => true, + OperandKind.MixinKindSDFX => true, + _ => false + }; + } + + public static string? ConvertEnumValueToString(this OperandKind kind, int value) + { + return kind switch + { + OperandKind.ImageOperands => ((ImageOperandsMask)value).ToString(), + OperandKind.FPFastMathMode => ((FPFastMathModeMask)value).ToString(), + OperandKind.SelectionControl => ((SelectionControlMask)value).ToString(), + OperandKind.LoopControl => ((LoopControlMask)value).ToString(), + OperandKind.FunctionControl => ((FunctionControlMask)value).ToString(), + OperandKind.MemorySemantics => ((MemorySemanticsMask)value).ToString(), + OperandKind.MemoryAccess => ((MemoryAccessMask)value).ToString(), + OperandKind.KernelProfilingInfo => ((KernelProfilingInfoMask)value).ToString(), + OperandKind.RayFlags => ((RayFlagsMask)value).ToString(), + OperandKind.FragmentShadingRate => ((FragmentShadingRateMask)value).ToString(), + OperandKind.RawAccessChainOperands => ((RawAccessChainOperandsMask)value).ToString(), + OperandKind.SourceLanguage => ((SourceLanguage)value).ToString(), + OperandKind.ExecutionModel => ((ExecutionModel)value).ToString(), + OperandKind.AddressingModel => ((AddressingModel)value).ToString(), + OperandKind.MemoryModel => ((MemoryModel)value).ToString(), + OperandKind.ExecutionMode => ((ExecutionMode)value).ToString(), + OperandKind.StorageClass => ((StorageClass)value).ToString(), + OperandKind.Dim => ((Dim)value).ToString(), + OperandKind.SamplerAddressingMode => ((SamplerAddressingMode)value).ToString(), + OperandKind.SamplerFilterMode => ((SamplerFilterMode)value).ToString(), + OperandKind.ImageFormat => ((ImageFormat)value).ToString(), + OperandKind.ImageChannelOrder => ((ImageChannelOrder)value).ToString(), + OperandKind.ImageChannelDataType => ((ImageChannelDataType)value).ToString(), + OperandKind.FPRoundingMode => ((FPRoundingMode)value).ToString(), + OperandKind.FPDenormMode => ((FPDenormMode)value).ToString(), + OperandKind.QuantizationModes => ((QuantizationModes)value).ToString(), + OperandKind.FPOperationMode => ((FPOperationMode)value).ToString(), + OperandKind.OverflowModes => ((OverflowModes)value).ToString(), + OperandKind.LinkageType => ((LinkageType)value).ToString(), + OperandKind.AccessQualifier => ((AccessQualifier)value).ToString(), + OperandKind.HostAccessQualifier => ((HostAccessQualifier)value).ToString(), + OperandKind.FunctionParameterAttribute => ((FunctionParameterAttribute)value).ToString(), + OperandKind.Decoration => ((Decoration)value).ToString(), + OperandKind.BuiltIn => ((BuiltIn)value).ToString(), + OperandKind.Scope => ((Scope)value).ToString(), + OperandKind.GroupOperation => ((GroupOperation)value).ToString(), + OperandKind.KernelEnqueueFlags => ((KernelEnqueueFlags)value).ToString(), + OperandKind.Capability => ((Capability)value).ToString(), + OperandKind.RayQueryIntersection => ((RayQueryIntersection)value).ToString(), + OperandKind.RayQueryCommittedIntersectionType => ((RayQueryCommittedIntersectionType)value).ToString(), + OperandKind.RayQueryCandidateIntersectionType => ((RayQueryCandidateIntersectionType)value).ToString(), + OperandKind.PackedVectorFormat => ((PackedVectorFormat)value).ToString(), + OperandKind.CooperativeMatrixOperands => ((CooperativeMatrixOperandsMask)value).ToString(), + OperandKind.CooperativeMatrixLayout => ((CooperativeMatrixLayout)value).ToString(), + OperandKind.CooperativeMatrixUse => ((CooperativeMatrixUse)value).ToString(), + OperandKind.CooperativeMatrixReduce => ((CooperativeMatrixReduceMask)value).ToString(), + OperandKind.TensorClampMode => ((TensorClampMode)value).ToString(), + OperandKind.TensorAddressingOperands => ((TensorAddressingOperandsMask)value).ToString(), + OperandKind.InitializationModeQualifier => ((InitializationModeQualifier)value).ToString(), + OperandKind.LoadCacheControl => ((LoadCacheControl)value).ToString(), + OperandKind.StoreCacheControl => ((StoreCacheControl)value).ToString(), + OperandKind.NamedMaximumNumberOfRegisters => ((NamedMaximumNumberOfRegisters)value).ToString(), + OperandKind.FPEncoding => ((FPEncoding)value).ToString(), + OperandKind.MixinInheritFlags => ((MixinInheritFlagsMask)value).ToString(), + OperandKind.FunctionFlags => ((FunctionFlagsMask)value).ToString(), + OperandKind.VariableFlags => ((VariableFlagsMask)value).ToString(), + OperandKind.GenericParameterKindSDSL => ((GenericParameterKindSDSL)value).ToString(), + OperandKind.StreamsKindSDSL => ((StreamsKindSDSL)value).ToString(), + OperandKind.GeometryStreamOutputKindSDSL => ((GeometryStreamOutputKindSDSL)value).ToString(), + OperandKind.PatchTypeKindSDSL => ((PatchTypeKindSDSL)value).ToString(), + OperandKind.SamplerTextureAddressModeSDSL => ((SamplerTextureAddressModeSDSL)value).ToString(), + OperandKind.SamplerFilterSDSL => ((SamplerFilterSDSL)value).ToString(), + OperandKind.SamplerComparisonFuncSDSL => ((SamplerComparisonFuncSDSL)value).ToString(), + OperandKind.MixinKindSDFX => ((MixinKindSDFX)value).ToString(), + _ => null + }; + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SDSLSpecification.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SDSLSpecification.gen.cs new file mode 100644 index 0000000000..d680f12970 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SDSLSpecification.gen.cs @@ -0,0 +1,1332 @@ +namespace Stride.Shaders.Spirv; +public static partial class Specification +{ + public static uint MagicNumber { get; } = 0x07230203; + public static uint MajorVersion { get; } = 1; + public static uint MinorVersion { get; } = 6; + public static uint Revision { get; } = 4; + + [Flags] + public enum ImageOperandsMask + { + None = 0, + Bias = 1, + Lod = 2, + Grad = 4, + ConstOffset = 8, + Offset = 16, + ConstOffsets = 32, + Sample = 64, + MinLod = 128, + MakeTexelAvailable = 256, + MakeTexelVisible = 512, + NonPrivateTexel = 1024, + VolatileTexel = 2048, + SignExtend = 4096, + ZeroExtend = 8192, + Nontemporal = 16384, + Offsets = 65536, + } + + [Flags] + public enum FPFastMathModeMask + { + None = 0, + NotNaN = 1, + NotInf = 2, + NSZ = 4, + AllowRecip = 8, + Fast = 16, + AllowContract = 65536, + AllowReassoc = 131072, + AllowTransform = 262144, + } + + [Flags] + public enum SelectionControlMask + { + None = 0, + Flatten = 1, + DontFlatten = 2, + } + + [Flags] + public enum LoopControlMask + { + None = 0, + Unroll = 1, + DontUnroll = 2, + DependencyInfinite = 4, + DependencyLength = 8, + MinIterations = 16, + MaxIterations = 32, + IterationMultiple = 64, + PeelCount = 128, + PartialCount = 256, + InitiationIntervalINTEL = 65536, + MaxConcurrencyINTEL = 131072, + DependencyArrayINTEL = 262144, + PipelineEnableINTEL = 524288, + LoopCoalesceINTEL = 1048576, + MaxInterleavingINTEL = 2097152, + SpeculatedIterationsINTEL = 4194304, + NoFusionINTEL = 8388608, + LoopCountINTEL = 16777216, + MaxReinvocationDelayINTEL = 33554432, + } + + [Flags] + public enum FunctionControlMask + { + None = 0, + Inline = 1, + DontInline = 2, + Pure = 4, + Const = 8, + OptNoneEXT = 65536, + } + + [Flags] + public enum MemorySemanticsMask + { + Relaxed = 0, + Acquire = 2, + Release = 4, + AcquireRelease = 8, + SequentiallyConsistent = 16, + UniformMemory = 64, + SubgroupMemory = 128, + WorkgroupMemory = 256, + CrossWorkgroupMemory = 512, + AtomicCounterMemory = 1024, + ImageMemory = 2048, + OutputMemory = 4096, + MakeAvailable = 8192, + MakeVisible = 16384, + Volatile = 32768, + } + + [Flags] + public enum MemoryAccessMask + { + None = 0, + Volatile = 1, + Aligned = 2, + Nontemporal = 4, + MakePointerAvailable = 8, + MakePointerVisible = 16, + NonPrivatePointer = 32, + AliasScopeINTELMask = 65536, + NoAliasINTELMask = 131072, + } + + [Flags] + public enum KernelProfilingInfoMask + { + None = 0, + CmdExecTime = 1, + } + + [Flags] + public enum RayFlagsMask + { + NoneKHR = 0, + OpaqueKHR = 1, + NoOpaqueKHR = 2, + TerminateOnFirstHitKHR = 4, + SkipClosestHitShaderKHR = 8, + CullBackFacingTrianglesKHR = 16, + CullFrontFacingTrianglesKHR = 32, + CullOpaqueKHR = 64, + CullNoOpaqueKHR = 128, + SkipTrianglesKHR = 256, + SkipAABBsKHR = 512, + ForceOpacityMicromap2StateEXT = 1024, + } + + [Flags] + public enum FragmentShadingRateMask + { + Vertical2Pixels = 1, + Vertical4Pixels = 2, + Horizontal2Pixels = 4, + Horizontal4Pixels = 8, + } + + [Flags] + public enum RawAccessChainOperandsMask + { + None = 0, + RobustnessPerComponentNV = 1, + RobustnessPerElementNV = 2, + } + + public enum SourceLanguage + { + Unknown = 0, + ESSL = 1, + GLSL = 2, + OpenCL_C = 3, + OpenCL_CPP = 4, + HLSL = 5, + CPP_for_OpenCL = 6, + SYCL = 7, + HERO_C = 8, + NZSL = 9, + WGSL = 10, + Slang = 11, + Zig = 12, + } + + public enum ExecutionModel + { + Vertex = 0, + TessellationControl = 1, + TessellationEvaluation = 2, + Geometry = 3, + Fragment = 4, + GLCompute = 5, + Kernel = 6, + TaskNV = 5267, + MeshNV = 5268, + RayGenerationKHR = 5313, + IntersectionKHR = 5314, + AnyHitKHR = 5315, + ClosestHitKHR = 5316, + MissKHR = 5317, + CallableKHR = 5318, + TaskEXT = 5364, + MeshEXT = 5365, + Mixin = 5367, + } + + public enum AddressingModel + { + Logical = 0, + Physical32 = 1, + Physical64 = 2, + PhysicalStorageBuffer64 = 5348, + } + + public enum MemoryModel + { + Simple = 0, + GLSL450 = 1, + OpenCL = 2, + Vulkan = 3, + } + + public enum ExecutionMode + { + Invocations = 0, + SpacingEqual = 1, + SpacingFractionalEven = 2, + SpacingFractionalOdd = 3, + VertexOrderCw = 4, + VertexOrderCcw = 5, + PixelCenterInteger = 6, + OriginUpperLeft = 7, + OriginLowerLeft = 8, + EarlyFragmentTests = 9, + PointMode = 10, + Xfb = 11, + DepthReplacing = 12, + DepthGreater = 14, + DepthLess = 15, + DepthUnchanged = 16, + LocalSize = 17, + LocalSizeHint = 18, + InputPoints = 19, + InputLines = 20, + InputLinesAdjacency = 21, + Triangles = 22, + InputTrianglesAdjacency = 23, + Quads = 24, + Isolines = 25, + OutputVertices = 26, + OutputPoints = 27, + OutputLineStrip = 28, + OutputTriangleStrip = 29, + VecTypeHint = 30, + ContractionOff = 31, + Initializer = 33, + Finalizer = 34, + SubgroupSize = 35, + SubgroupsPerWorkgroup = 36, + SubgroupsPerWorkgroupId = 37, + LocalSizeId = 38, + LocalSizeHintId = 39, + NonCoherentColorAttachmentReadEXT = 4169, + NonCoherentDepthAttachmentReadEXT = 4170, + NonCoherentStencilAttachmentReadEXT = 4171, + SubgroupUniformControlFlowKHR = 4421, + PostDepthCoverage = 4446, + DenormPreserve = 4459, + DenormFlushToZero = 4460, + SignedZeroInfNanPreserve = 4461, + RoundingModeRTE = 4462, + RoundingModeRTZ = 4463, + EarlyAndLateFragmentTestsAMD = 5017, + StencilRefReplacingEXT = 5027, + CoalescingAMDX = 5069, + IsApiEntryAMDX = 5070, + MaxNodeRecursionAMDX = 5071, + StaticNumWorkgroupsAMDX = 5072, + ShaderIndexAMDX = 5073, + MaxNumWorkgroupsAMDX = 5077, + StencilRefUnchangedFrontAMD = 5079, + StencilRefGreaterFrontAMD = 5080, + StencilRefLessFrontAMD = 5081, + StencilRefUnchangedBackAMD = 5082, + StencilRefGreaterBackAMD = 5083, + StencilRefLessBackAMD = 5084, + QuadDerivativesKHR = 5088, + RequireFullQuadsKHR = 5089, + SharesInputWithAMDX = 5102, + OutputLinesEXT = 5269, + OutputPrimitivesEXT = 5270, + DerivativeGroupQuadsKHR = 5289, + DerivativeGroupLinearKHR = 5290, + OutputTrianglesEXT = 5298, + PixelInterlockOrderedEXT = 5366, + PixelInterlockUnorderedEXT = 5367, + SampleInterlockOrderedEXT = 5368, + SampleInterlockUnorderedEXT = 5369, + ShadingRateInterlockOrderedEXT = 5370, + ShadingRateInterlockUnorderedEXT = 5371, + SharedLocalMemorySizeINTEL = 5618, + RoundingModeRTPINTEL = 5620, + RoundingModeRTNINTEL = 5621, + FloatingPointModeALTINTEL = 5622, + FloatingPointModeIEEEINTEL = 5623, + MaxWorkgroupSizeINTEL = 5893, + MaxWorkDimINTEL = 5894, + NoGlobalOffsetINTEL = 5895, + NumSIMDWorkitemsINTEL = 5896, + SchedulerTargetFmaxMhzINTEL = 5903, + MaximallyReconvergesKHR = 6023, + FPFastMathDefault = 6028, + StreamingInterfaceINTEL = 6154, + RegisterMapInterfaceINTEL = 6160, + NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, + } + + public enum StorageClass + { + UniformConstant = 0, + Input = 1, + Uniform = 2, + Output = 3, + Workgroup = 4, + CrossWorkgroup = 5, + Private = 6, + Function = 7, + Generic = 8, + PushConstant = 9, + AtomicCounter = 10, + Image = 11, + StorageBuffer = 12, + TileImageEXT = 4172, + NodePayloadAMDX = 5068, + CallableDataKHR = 5328, + IncomingCallableDataKHR = 5329, + RayPayloadKHR = 5338, + HitAttributeKHR = 5339, + IncomingRayPayloadKHR = 5342, + ShaderRecordBufferKHR = 5343, + PhysicalStorageBuffer = 5349, + HitObjectAttributeNV = 5385, + TaskPayloadWorkgroupEXT = 5402, + CodeSectionINTEL = 5605, + DeviceOnlyINTEL = 5936, + HostOnlyINTEL = 5937, + Params = 8000, + } + + public enum Dim + { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + Cube = 3, + Rect = 4, + Buffer = 5, + SubpassData = 6, + TileImageDataEXT = 4173, + } + + public enum SamplerAddressingMode + { + None = 0, + ClampToEdge = 1, + Clamp = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + public enum SamplerFilterMode + { + Nearest = 0, + Linear = 1, + } + + public enum ImageFormat + { + Unknown = 0, + Rgba32f = 1, + Rgba16f = 2, + R32f = 3, + Rgba8 = 4, + Rgba8Snorm = 5, + Rg32f = 6, + Rg16f = 7, + R11fG11fB10f = 8, + R16f = 9, + Rgba16 = 10, + Rgb10A2 = 11, + Rg16 = 12, + Rg8 = 13, + R16 = 14, + R8 = 15, + Rgba16Snorm = 16, + Rg16Snorm = 17, + Rg8Snorm = 18, + R16Snorm = 19, + R8Snorm = 20, + Rgba32i = 21, + Rgba16i = 22, + Rgba8i = 23, + R32i = 24, + Rg32i = 25, + Rg16i = 26, + Rg8i = 27, + R16i = 28, + R8i = 29, + Rgba32ui = 30, + Rgba16ui = 31, + Rgba8ui = 32, + R32ui = 33, + Rgb10a2ui = 34, + Rg32ui = 35, + Rg16ui = 36, + Rg8ui = 37, + R16ui = 38, + R8ui = 39, + R64ui = 40, + R64i = 41, + } + + public enum ImageChannelOrder + { + R = 0, + A = 1, + RG = 2, + RA = 3, + RGB = 4, + RGBA = 5, + BGRA = 6, + ARGB = 7, + Intensity = 8, + Luminance = 9, + Rx = 10, + RGx = 11, + RGBx = 12, + Depth = 13, + DepthStencil = 14, + sRGB = 15, + sRGBx = 16, + sRGBA = 17, + sBGRA = 18, + ABGR = 19, + } + + public enum ImageChannelDataType + { + SnormInt8 = 0, + SnormInt16 = 1, + UnormInt8 = 2, + UnormInt16 = 3, + UnormShort565 = 4, + UnormShort555 = 5, + UnormInt101010 = 6, + SignedInt8 = 7, + SignedInt16 = 8, + SignedInt32 = 9, + UnsignedInt8 = 10, + UnsignedInt16 = 11, + UnsignedInt32 = 12, + HalfFloat = 13, + Float = 14, + UnormInt24 = 15, + UnormInt101010_2 = 16, + UnsignedIntRaw10EXT = 19, + UnsignedIntRaw12EXT = 20, + UnormInt2_101010EXT = 21, + } + + public enum FPRoundingMode + { + RTE = 0, + RTZ = 1, + RTP = 2, + RTN = 3, + } + + public enum FPDenormMode + { + Preserve = 0, + FlushToZero = 1, + } + + public enum QuantizationModes + { + TRN = 0, + TRN_ZERO = 1, + RND = 2, + RND_ZERO = 3, + RND_INF = 4, + RND_MIN_INF = 5, + RND_CONV = 6, + RND_CONV_ODD = 7, + } + + public enum FPOperationMode + { + IEEE = 0, + ALT = 1, + } + + public enum OverflowModes + { + WRAP = 0, + SAT = 1, + SAT_ZERO = 2, + SAT_SYM = 3, + } + + public enum LinkageType + { + Export = 0, + Import = 1, + LinkOnceODR = 2, + } + + public enum AccessQualifier + { + ReadOnly = 0, + WriteOnly = 1, + ReadWrite = 2, + } + + public enum HostAccessQualifier + { + NoneINTEL = 0, + ReadINTEL = 1, + WriteINTEL = 2, + ReadWriteINTEL = 3, + } + + public enum FunctionParameterAttribute + { + Zext = 0, + Sext = 1, + ByVal = 2, + Sret = 3, + NoAlias = 4, + NoCapture = 5, + NoWrite = 6, + NoReadWrite = 7, + RuntimeAlignedINTEL = 5940, + } + + public enum Decoration + { + RelaxedPrecision = 0, + SpecId = 1, + Block = 2, + BufferBlock = 3, + RowMajor = 4, + ColMajor = 5, + ArrayStride = 6, + MatrixStride = 7, + GLSLShared = 8, + GLSLPacked = 9, + CPacked = 10, + BuiltIn = 11, + NoPerspective = 13, + Flat = 14, + Patch = 15, + Centroid = 16, + Sample = 17, + Invariant = 18, + Restrict = 19, + Aliased = 20, + Volatile = 21, + Constant = 22, + Coherent = 23, + NonWritable = 24, + NonReadable = 25, + Uniform = 26, + UniformId = 27, + SaturatedConversion = 28, + Stream = 29, + Location = 30, + Component = 31, + Index = 32, + Binding = 33, + DescriptorSet = 34, + Offset = 35, + XfbBuffer = 36, + XfbStride = 37, + FuncParamAttr = 38, + FPRoundingMode = 39, + FPFastMathMode = 40, + LinkageAttributes = 41, + NoContraction = 42, + InputAttachmentIndex = 43, + Alignment = 44, + MaxByteOffset = 45, + AlignmentId = 46, + MaxByteOffsetId = 47, + NoSignedWrap = 4469, + NoUnsignedWrap = 4470, + WeightTextureQCOM = 4487, + BlockMatchTextureQCOM = 4488, + BlockMatchSamplerQCOM = 4499, + ExplicitInterpAMD = 4999, + NodeSharesPayloadLimitsWithAMDX = 5019, + NodeMaxPayloadsAMDX = 5020, + TrackFinishWritingAMDX = 5078, + PayloadNodeNameAMDX = 5091, + PayloadNodeBaseIndexAMDX = 5098, + PayloadNodeSparseArrayAMDX = 5099, + PayloadNodeArraySizeAMDX = 5100, + PayloadDispatchIndirectAMDX = 5105, + OverrideCoverageNV = 5248, + PassthroughNV = 5250, + ViewportRelativeNV = 5252, + SecondaryViewportRelativeNV = 5256, + PerPrimitiveEXT = 5271, + PerViewNV = 5272, + PerTaskNV = 5273, + PerVertexKHR = 5285, + NonUniform = 5300, + RestrictPointer = 5355, + AliasedPointer = 5356, + HitObjectShaderRecordBufferNV = 5386, + BindlessSamplerNV = 5398, + BindlessImageNV = 5399, + BoundSamplerNV = 5400, + BoundImageNV = 5401, + SIMTCallINTEL = 5599, + ReferencedIndirectlyINTEL = 5602, + ClobberINTEL = 5607, + SideEffectsINTEL = 5608, + VectorComputeVariableINTEL = 5624, + FuncParamIOKindINTEL = 5625, + VectorComputeFunctionINTEL = 5626, + StackCallINTEL = 5627, + GlobalVariableOffsetINTEL = 5628, + CounterBuffer = 5634, + UserSemantic = 5635, + UserTypeGOOGLE = 5636, + FunctionRoundingModeINTEL = 5822, + FunctionDenormModeINTEL = 5823, + RegisterINTEL = 5825, + MemoryINTEL = 5826, + NumbanksINTEL = 5827, + BankwidthINTEL = 5828, + MaxPrivateCopiesINTEL = 5829, + SinglepumpINTEL = 5830, + DoublepumpINTEL = 5831, + MaxReplicatesINTEL = 5832, + SimpleDualPortINTEL = 5833, + MergeINTEL = 5834, + BankBitsINTEL = 5835, + ForcePow2DepthINTEL = 5836, + StridesizeINTEL = 5883, + WordsizeINTEL = 5884, + TrueDualPortINTEL = 5885, + BurstCoalesceINTEL = 5899, + CacheSizeINTEL = 5900, + DontStaticallyCoalesceINTEL = 5901, + PrefetchINTEL = 5902, + StallEnableINTEL = 5905, + FuseLoopsInFunctionINTEL = 5907, + MathOpDSPModeINTEL = 5909, + AliasScopeINTEL = 5914, + NoAliasINTEL = 5915, + InitiationIntervalINTEL = 5917, + MaxConcurrencyINTEL = 5918, + PipelineEnableINTEL = 5919, + BufferLocationINTEL = 5921, + IOPipeStorageINTEL = 5944, + FunctionFloatingPointModeINTEL = 6080, + SingleElementVectorINTEL = 6085, + VectorComputeCallableFunctionINTEL = 6087, + MediaBlockIOINTEL = 6140, + StallFreeINTEL = 6151, + FPMaxErrorDecorationINTEL = 6170, + LatencyControlLabelINTEL = 6172, + LatencyControlConstraintINTEL = 6173, + ConduitKernelArgumentINTEL = 6175, + RegisterMapKernelArgumentINTEL = 6176, + MMHostInterfaceAddressWidthINTEL = 6177, + MMHostInterfaceDataWidthINTEL = 6178, + MMHostInterfaceLatencyINTEL = 6179, + MMHostInterfaceReadWriteModeINTEL = 6180, + MMHostInterfaceMaxBurstINTEL = 6181, + MMHostInterfaceWaitRequestINTEL = 6182, + StableKernelArgumentINTEL = 6183, + HostAccessINTEL = 6188, + InitModeINTEL = 6190, + ImplementInRegisterMapINTEL = 6191, + CacheControlLoadINTEL = 6442, + CacheControlStoreINTEL = 6443, + LinkSDSL = 8000, + LinkIdSDSL = 8001, + ColorSDSL = 8002, + ResourceGroupSDSL = 8010, + ResourceGroupIdSDSL = 8011, + LogicalGroupSDSL = 8004, + SamplerStateSDSL = 8020, + FunctionParameterDefaultValueSDSL = 8040, + ShaderConstantSDSL = 8060, + PatchConstantFuncSDSL = 8070, + } + + public enum BuiltIn + { + Position = 0, + PointSize = 1, + ClipDistance = 3, + CullDistance = 4, + VertexId = 5, + InstanceId = 6, + PrimitiveId = 7, + InvocationId = 8, + Layer = 9, + ViewportIndex = 10, + TessLevelOuter = 11, + TessLevelInner = 12, + TessCoord = 13, + PatchVertices = 14, + FragCoord = 15, + PointCoord = 16, + FrontFacing = 17, + SampleId = 18, + SamplePosition = 19, + SampleMask = 20, + FragDepth = 22, + HelperInvocation = 23, + NumWorkgroups = 24, + WorkgroupSize = 25, + WorkgroupId = 26, + LocalInvocationId = 27, + GlobalInvocationId = 28, + LocalInvocationIndex = 29, + WorkDim = 30, + GlobalSize = 31, + EnqueuedWorkgroupSize = 32, + GlobalOffset = 33, + GlobalLinearId = 34, + SubgroupSize = 36, + SubgroupMaxSize = 37, + NumSubgroups = 38, + NumEnqueuedSubgroups = 39, + SubgroupId = 40, + SubgroupLocalInvocationId = 41, + VertexIndex = 42, + InstanceIndex = 43, + CoreIDARM = 4160, + CoreCountARM = 4161, + CoreMaxIDARM = 4162, + WarpIDARM = 4163, + WarpMaxIDARM = 4164, + SubgroupEqMask = 4416, + SubgroupGeMask = 4417, + SubgroupGtMask = 4418, + SubgroupLeMask = 4419, + SubgroupLtMask = 4420, + BaseVertex = 4424, + BaseInstance = 4425, + DrawIndex = 4426, + PrimitiveShadingRateKHR = 4432, + DeviceIndex = 4438, + ViewIndex = 4440, + ShadingRateKHR = 4444, + BaryCoordNoPerspAMD = 4992, + BaryCoordNoPerspCentroidAMD = 4993, + BaryCoordNoPerspSampleAMD = 4994, + BaryCoordSmoothAMD = 4995, + BaryCoordSmoothCentroidAMD = 4996, + BaryCoordSmoothSampleAMD = 4997, + BaryCoordPullModelAMD = 4998, + FragStencilRefEXT = 5014, + RemainingRecursionLevelsAMDX = 5021, + ShaderIndexAMDX = 5073, + ViewportMaskNV = 5253, + SecondaryPositionNV = 5257, + SecondaryViewportMaskNV = 5258, + PositionPerViewNV = 5261, + ViewportMaskPerViewNV = 5262, + FullyCoveredEXT = 5264, + TaskCountNV = 5274, + PrimitiveCountNV = 5275, + PrimitiveIndicesNV = 5276, + ClipDistancePerViewNV = 5277, + CullDistancePerViewNV = 5278, + LayerPerViewNV = 5279, + MeshViewCountNV = 5280, + MeshViewIndicesNV = 5281, + BaryCoordKHR = 5286, + BaryCoordNoPerspKHR = 5287, + FragSizeEXT = 5292, + FragInvocationCountEXT = 5293, + PrimitivePointIndicesEXT = 5294, + PrimitiveLineIndicesEXT = 5295, + PrimitiveTriangleIndicesEXT = 5296, + CullPrimitiveEXT = 5299, + LaunchIdKHR = 5319, + LaunchSizeKHR = 5320, + WorldRayOriginKHR = 5321, + WorldRayDirectionKHR = 5322, + ObjectRayOriginKHR = 5323, + ObjectRayDirectionKHR = 5324, + RayTminKHR = 5325, + RayTmaxKHR = 5326, + InstanceCustomIndexKHR = 5327, + ObjectToWorldKHR = 5330, + WorldToObjectKHR = 5331, + HitTNV = 5332, + HitKindKHR = 5333, + CurrentRayTimeNV = 5334, + HitTriangleVertexPositionsKHR = 5335, + HitMicroTriangleVertexPositionsNV = 5337, + HitMicroTriangleVertexBarycentricsNV = 5344, + IncomingRayFlagsKHR = 5351, + RayGeometryIndexKHR = 5352, + WarpsPerSMNV = 5374, + SMCountNV = 5375, + WarpIDNV = 5376, + SMIDNV = 5377, + HitKindFrontFacingMicroTriangleNV = 5405, + HitKindBackFacingMicroTriangleNV = 5406, + CullMaskKHR = 6021, + } + + public enum Scope + { + CrossDevice = 0, + Device = 1, + Workgroup = 2, + Subgroup = 3, + Invocation = 4, + QueueFamily = 5, + ShaderCallKHR = 6, + } + + public enum GroupOperation + { + Reduce = 0, + InclusiveScan = 1, + ExclusiveScan = 2, + ClusteredReduce = 3, + PartitionedReduceNV = 6, + PartitionedInclusiveScanNV = 7, + PartitionedExclusiveScanNV = 8, + } + + public enum KernelEnqueueFlags + { + NoWait = 0, + WaitKernel = 1, + WaitWorkGroup = 2, + } + + public enum Capability + { + Matrix = 0, + Shader = 1, + Geometry = 2, + Tessellation = 3, + Addresses = 4, + Linkage = 5, + Kernel = 6, + Vector16 = 7, + Float16Buffer = 8, + Float16 = 9, + Float64 = 10, + Int64 = 11, + Int64Atomics = 12, + ImageBasic = 13, + ImageReadWrite = 14, + ImageMipmap = 15, + Pipes = 17, + Groups = 18, + DeviceEnqueue = 19, + LiteralSampler = 20, + AtomicStorage = 21, + Int16 = 22, + TessellationPointSize = 23, + GeometryPointSize = 24, + ImageGatherExtended = 25, + StorageImageMultisample = 27, + UniformBufferArrayDynamicIndexing = 28, + SampledImageArrayDynamicIndexing = 29, + StorageBufferArrayDynamicIndexing = 30, + StorageImageArrayDynamicIndexing = 31, + ClipDistance = 32, + CullDistance = 33, + ImageCubeArray = 34, + SampleRateShading = 35, + ImageRect = 36, + SampledRect = 37, + GenericPointer = 38, + Int8 = 39, + InputAttachment = 40, + SparseResidency = 41, + MinLod = 42, + Sampled1D = 43, + Image1D = 44, + SampledCubeArray = 45, + SampledBuffer = 46, + ImageBuffer = 47, + ImageMSArray = 48, + StorageImageExtendedFormats = 49, + ImageQuery = 50, + DerivativeControl = 51, + InterpolationFunction = 52, + TransformFeedback = 53, + GeometryStreams = 54, + StorageImageReadWithoutFormat = 55, + StorageImageWriteWithoutFormat = 56, + MultiViewport = 57, + SubgroupDispatch = 58, + NamedBarrier = 59, + PipeStorage = 60, + GroupNonUniform = 61, + GroupNonUniformVote = 62, + GroupNonUniformArithmetic = 63, + GroupNonUniformBallot = 64, + GroupNonUniformShuffle = 65, + GroupNonUniformShuffleRelative = 66, + GroupNonUniformClustered = 67, + GroupNonUniformQuad = 68, + ShaderLayer = 69, + ShaderViewportIndex = 70, + UniformDecoration = 71, + CoreBuiltinsARM = 4165, + TileImageColorReadAccessEXT = 4166, + TileImageDepthReadAccessEXT = 4167, + TileImageStencilReadAccessEXT = 4168, + CooperativeMatrixLayoutsARM = 4201, + FragmentShadingRateKHR = 4422, + SubgroupBallotKHR = 4423, + DrawParameters = 4427, + WorkgroupMemoryExplicitLayoutKHR = 4428, + WorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + WorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + SubgroupVoteKHR = 4431, + StorageBuffer16BitAccess = 4433, + UniformAndStorageBuffer16BitAccess = 4434, + StoragePushConstant16 = 4435, + StorageInputOutput16 = 4436, + DeviceGroup = 4437, + MultiView = 4439, + VariablePointersStorageBuffer = 4441, + VariablePointers = 4442, + AtomicStorageOps = 4445, + SampleMaskPostDepthCoverage = 4447, + StorageBuffer8BitAccess = 4448, + UniformAndStorageBuffer8BitAccess = 4449, + StoragePushConstant8 = 4450, + DenormPreserve = 4464, + DenormFlushToZero = 4465, + SignedZeroInfNanPreserve = 4466, + RoundingModeRTE = 4467, + RoundingModeRTZ = 4468, + RayQueryProvisionalKHR = 4471, + RayQueryKHR = 4472, + UntypedPointersKHR = 4473, + RayTraversalPrimitiveCullingKHR = 4478, + RayTracingKHR = 4479, + TextureSampleWeightedQCOM = 4484, + TextureBoxFilterQCOM = 4485, + TextureBlockMatchQCOM = 4486, + TextureBlockMatch2QCOM = 4498, + Float16ImageAMD = 5008, + ImageGatherBiasLodAMD = 5009, + FragmentMaskAMD = 5010, + StencilExportEXT = 5013, + ImageReadWriteLodAMD = 5015, + Int64ImageEXT = 5016, + ShaderClockKHR = 5055, + ShaderEnqueueAMDX = 5067, + QuadControlKHR = 5087, + SampleMaskOverrideCoverageNV = 5249, + GeometryShaderPassthroughNV = 5251, + ShaderViewportIndexLayerEXT = 5254, + ShaderViewportMaskNV = 5255, + ShaderStereoViewNV = 5259, + PerViewAttributesNV = 5260, + FragmentFullyCoveredEXT = 5265, + MeshShadingNV = 5266, + ImageFootprintNV = 5282, + MeshShadingEXT = 5283, + FragmentBarycentricKHR = 5284, + ComputeDerivativeGroupQuadsKHR = 5288, + FragmentDensityEXT = 5291, + GroupNonUniformPartitionedNV = 5297, + ShaderNonUniform = 5301, + RuntimeDescriptorArray = 5302, + InputAttachmentArrayDynamicIndexing = 5303, + UniformTexelBufferArrayDynamicIndexing = 5304, + StorageTexelBufferArrayDynamicIndexing = 5305, + UniformBufferArrayNonUniformIndexing = 5306, + SampledImageArrayNonUniformIndexing = 5307, + StorageBufferArrayNonUniformIndexing = 5308, + StorageImageArrayNonUniformIndexing = 5309, + InputAttachmentArrayNonUniformIndexing = 5310, + UniformTexelBufferArrayNonUniformIndexing = 5311, + StorageTexelBufferArrayNonUniformIndexing = 5312, + RayTracingPositionFetchKHR = 5336, + RayTracingNV = 5340, + RayTracingMotionBlurNV = 5341, + VulkanMemoryModel = 5345, + VulkanMemoryModelDeviceScope = 5346, + PhysicalStorageBufferAddresses = 5347, + ComputeDerivativeGroupLinearKHR = 5350, + RayTracingProvisionalKHR = 5353, + CooperativeMatrixNV = 5357, + FragmentShaderSampleInterlockEXT = 5363, + FragmentShaderShadingRateInterlockEXT = 5372, + ShaderSMBuiltinsNV = 5373, + FragmentShaderPixelInterlockEXT = 5378, + DemoteToHelperInvocation = 5379, + DisplacementMicromapNV = 5380, + RayTracingOpacityMicromapEXT = 5381, + ShaderInvocationReorderNV = 5383, + BindlessTextureNV = 5390, + RayQueryPositionFetchKHR = 5391, + AtomicFloat16VectorNV = 5404, + RayTracingDisplacementMicromapNV = 5409, + RawAccessChainsNV = 5414, + CooperativeMatrixReductionsNV = 5430, + CooperativeMatrixConversionsNV = 5431, + CooperativeMatrixPerElementOperationsNV = 5432, + CooperativeMatrixTensorAddressingNV = 5433, + CooperativeMatrixBlockLoadsNV = 5434, + TensorAddressingNV = 5439, + SubgroupShuffleINTEL = 5568, + SubgroupBufferBlockIOINTEL = 5569, + SubgroupImageBlockIOINTEL = 5570, + SubgroupImageMediaBlockIOINTEL = 5579, + RoundToInfinityINTEL = 5582, + FloatingPointModeINTEL = 5583, + IntegerFunctions2INTEL = 5584, + FunctionPointersINTEL = 5603, + IndirectReferencesINTEL = 5604, + AsmINTEL = 5606, + AtomicFloat32MinMaxEXT = 5612, + AtomicFloat64MinMaxEXT = 5613, + AtomicFloat16MinMaxEXT = 5616, + VectorComputeINTEL = 5617, + VectorAnyINTEL = 5619, + ExpectAssumeKHR = 5629, + SubgroupAvcMotionEstimationINTEL = 5696, + SubgroupAvcMotionEstimationIntraINTEL = 5697, + SubgroupAvcMotionEstimationChromaINTEL = 5698, + VariableLengthArrayINTEL = 5817, + FunctionFloatControlINTEL = 5821, + FPGAMemoryAttributesINTEL = 5824, + FPFastMathModeINTEL = 5837, + ArbitraryPrecisionIntegersINTEL = 5844, + ArbitraryPrecisionFloatingPointINTEL = 5845, + UnstructuredLoopControlsINTEL = 5886, + FPGALoopControlsINTEL = 5888, + KernelAttributesINTEL = 5892, + FPGAKernelAttributesINTEL = 5897, + FPGAMemoryAccessesINTEL = 5898, + FPGAClusterAttributesINTEL = 5904, + LoopFuseINTEL = 5906, + FPGADSPControlINTEL = 5908, + MemoryAccessAliasingINTEL = 5910, + FPGAInvocationPipeliningAttributesINTEL = 5916, + FPGABufferLocationINTEL = 5920, + ArbitraryPrecisionFixedPointINTEL = 5922, + USMStorageClassesINTEL = 5935, + RuntimeAlignedAttributeINTEL = 5939, + IOPipesINTEL = 5943, + BlockingPipesINTEL = 5945, + FPGARegINTEL = 5948, + DotProductInputAll = 6016, + DotProductInput4x8Bit = 6017, + DotProductInput4x8BitPacked = 6018, + DotProduct = 6019, + RayCullMaskKHR = 6020, + CooperativeMatrixKHR = 6022, + ReplicatedCompositesEXT = 6024, + BitInstructions = 6025, + GroupNonUniformRotateKHR = 6026, + FloatControls2 = 6029, + AtomicFloat32AddEXT = 6033, + AtomicFloat64AddEXT = 6034, + LongCompositesINTEL = 6089, + OptNoneEXT = 6094, + AtomicFloat16AddEXT = 6095, + DebugInfoModuleINTEL = 6114, + BFloat16ConversionINTEL = 6115, + SplitBarrierINTEL = 6141, + ArithmeticFenceEXT = 6144, + FPGAClusterAttributesV2INTEL = 6150, + FPGAKernelAttributesv2INTEL = 6161, + FPMaxErrorINTEL = 6169, + FPGALatencyControlINTEL = 6171, + FPGAArgumentInterfacesINTEL = 6174, + GlobalVariableHostAccessINTEL = 6187, + GlobalVariableFPGADecorationsINTEL = 6189, + SubgroupBufferPrefetchINTEL = 6220, + GroupUniformArithmeticKHR = 6400, + MaskedGatherScatterINTEL = 6427, + CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, + } + + public enum RayQueryIntersection + { + RayQueryCandidateIntersectionKHR = 0, + RayQueryCommittedIntersectionKHR = 1, + } + + public enum RayQueryCommittedIntersectionType + { + RayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionGeneratedKHR = 2, + } + + public enum RayQueryCandidateIntersectionType + { + RayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionAABBKHR = 1, + } + + public enum PackedVectorFormat + { + PackedVectorFormat4x8Bit = 0, + } + + [Flags] + public enum CooperativeMatrixOperandsMask + { + NoneKHR = 0, + MatrixASignedComponentsKHR = 1, + MatrixBSignedComponentsKHR = 2, + MatrixCSignedComponentsKHR = 4, + MatrixResultSignedComponentsKHR = 8, + SaturatingAccumulationKHR = 16, + } + + public enum CooperativeMatrixLayout + { + RowMajorKHR = 0, + ColumnMajorKHR = 1, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, + } + + public enum CooperativeMatrixUse + { + MatrixAKHR = 0, + MatrixBKHR = 1, + MatrixAccumulatorKHR = 2, + } + + [Flags] + public enum CooperativeMatrixReduceMask + { + Row = 1, + Column = 2, + CooperativeMatrixReduce2x2 = 4, + } + + public enum TensorClampMode + { + Undefined = 0, + Constant = 1, + ClampToEdge = 2, + Repeat = 3, + RepeatMirrored = 4, + } + + [Flags] + public enum TensorAddressingOperandsMask + { + None = 0, + TensorView = 1, + DecodeFunc = 2, + } + + public enum InitializationModeQualifier + { + InitOnDeviceReprogramINTEL = 0, + InitOnDeviceResetINTEL = 1, + } + + public enum LoadCacheControl + { + UncachedINTEL = 0, + CachedINTEL = 1, + StreamingINTEL = 2, + InvalidateAfterReadINTEL = 3, + ConstCachedINTEL = 4, + } + + public enum StoreCacheControl + { + UncachedINTEL = 0, + WriteThroughINTEL = 1, + WriteBackINTEL = 2, + StreamingINTEL = 3, + } + + public enum NamedMaximumNumberOfRegisters + { + AutoINTEL = 0, + } + + public enum FPEncoding + { + } + + [Flags] + public enum MixinInheritFlagsMask + { + None = 0, + NeedsFullImport = 1, + } + + [Flags] + public enum FunctionFlagsMask + { + None = 0, + Stage = 1, + Abstract = 16, + Virtual = 32, + Override = 64, + ReferencesNonStage = 128, + } + + [Flags] + public enum VariableFlagsMask + { + None = 0, + Stage = 1, + Stream = 2, + } + + public enum GenericParameterKindSDSL + { + LinkType = 1, + Semantic = 2, + MemberName = 3, + MemberNameResolved = 4, + } + + public enum StreamsKindSDSL + { + Input = 1, + Streams = 2, + Output = 3, + Constants = 4, + } + + public enum GeometryStreamOutputKindSDSL + { + Point = 1, + Line = 2, + Triangle = 3, + } + + public enum PatchTypeKindSDSL + { + Input = 1, + Output = 2, + } + + public enum SamplerTextureAddressModeSDSL + { + Wrap = 1, + Mirror = 2, + Clamp = 3, + Border = 4, + MirrorOnce = 5, + } + + public enum SamplerFilterSDSL + { + MIN_MAG_MIP_POINT = 0, + MIN_MAG_POINT_MIP_LINEAR = 1, + MIN_POINT_MAG_LINEAR_MIP_POINT = 4, + MIN_POINT_MAG_MIP_LINEAR = 5, + MIN_LINEAR_MAG_MIP_POINT = 16, + MIN_LINEAR_MAG_POINT_MIP_LINEAR = 17, + MIN_MAG_LINEAR_MIP_POINT = 20, + MIN_MAG_MIP_LINEAR = 21, + ANISOTROPIC = 85, + COMPARISON_MIN_MAG_MIP_POINT = 128, + COMPARISON_MIN_MAG_POINT_MIP_LINEAR = 129, + COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT = 132, + COMPARISON_MIN_POINT_MAG_MIP_LINEAR = 133, + COMPARISON_MIN_LINEAR_MAG_MIP_POINT = 144, + COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 145, + COMPARISON_MIN_MAG_LINEAR_MIP_POINT = 148, + COMPARISON_MIN_MAG_MIP_LINEAR = 149, + COMPARISON_ANISOTROPIC = 213, + MINIMUM_MIN_MAG_MIP_POINT = 256, + MINIMUM_MIN_MAG_POINT_MIP_LINEAR = 257, + MINIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 260, + MINIMUM_MIN_POINT_MAG_MIP_LINEAR = 261, + MINIMUM_MIN_LINEAR_MAG_MIP_POINT = 272, + MINIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 273, + MINIMUM_MIN_MAG_LINEAR_MIP_POINT = 276, + MINIMUM_MIN_MAG_MIP_LINEAR = 277, + MINIMUM_ANISOTROPIC = 341, + MAXIMUM_MIN_MAG_MIP_POINT = 384, + MAXIMUM_MIN_MAG_POINT_MIP_LINEAR = 385, + MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT = 388, + MAXIMUM_MIN_POINT_MAG_MIP_LINEAR = 389, + MAXIMUM_MIN_LINEAR_MAG_MIP_POINT = 400, + MAXIMUM_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 401, + MAXIMUM_MIN_MAG_LINEAR_MIP_POINT = 404, + MAXIMUM_MIN_MAG_MIP_LINEAR = 405, + MAXIMUM_ANISOTROPIC = 469, + } + + public enum SamplerComparisonFuncSDSL + { + Never = 1, + Less = 2, + Equal = 3, + LessEqual = 4, + Greater = 5, + NotEqual = 6, + GreaterEqual = 7, + Always = 8, + } + + public enum MixinKindSDFX + { + Default = 0, + ComposeSet = 1, + ComposeAdd = 2, + Child = 3, + Clone = 4, + Remove = 5, + Macro = 6, + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SpecificationOp.gen.cs b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SpecificationOp.gen.cs new file mode 100644 index 0000000000..3d45d1d9c0 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Generated/SpecificationOp.gen.cs @@ -0,0 +1,886 @@ +using static Stride.Shaders.Spirv.Specification; + +namespace Stride.Shaders.Spirv; +public static partial class Specification +{ + public enum Op : int + { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpTypeUntypedPointerKHR = 4417, + OpUntypedVariableKHR = 4418, + OpUntypedAccessChainKHR = 4419, + OpUntypedInBoundsAccessChainKHR = 4420, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpUntypedPtrAccessChainKHR = 4423, + OpUntypedInBoundsPtrAccessChainKHR = 4424, + OpUntypedArrayLengthKHR = 4425, + OpUntypedPrefetchKHR = 4426, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpExtInstWithForwardRefsKHR = 4433, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpUDot = 4451, + OpSUDot = 4452, + OpSDotAccSat = 4453, + OpUDotAccSat = 4454, + OpSUDotAccSat = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpAllocateNodePayloadsAMDX = 5074, + OpEnqueueNodePayloadsAMDX = 5075, + OpTypeNodePayloadArrayAMDX = 5076, + OpFinishWritingNodePayloadAMDX = 5078, + OpNodePayloadArrayLengthAMDX = 5090, + OpIsNodePayloadValidAMDX = 5101, + OpConstantStringAMDX = 5103, + OpSpecConstantStringAMDX = 5104, + OpGroupNonUniformQuadAllKHR = 5110, + OpGroupNonUniformQuadAnyKHR = 5111, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpCooperativeMatrixConvertNV = 5293, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpCooperativeMatrixReduceNV = 5366, + OpCooperativeMatrixLoadTensorNV = 5367, + OpCooperativeMatrixStoreTensorNV = 5368, + OpCooperativeMatrixPerElementOpNV = 5369, + OpTypeTensorLayoutNV = 5370, + OpTypeTensorViewNV = 5371, + OpCreateTensorLayoutNV = 5372, + OpTensorLayoutSetDimensionNV = 5373, + OpTensorLayoutSetStrideNV = 5374, + OpTensorLayoutSliceNV = 5375, + OpTensorLayoutSetClampValueNV = 5376, + OpCreateTensorViewNV = 5377, + OpTensorViewSetDimensionNV = 5378, + OpTensorViewSetStrideNV = 5379, + OpDemoteToHelperInvocation = 5380, + OpIsHelperInvocationEXT = 5381, + OpTensorViewSetClipNV = 5382, + OpTensorLayoutSetBlockSizeNV = 5384, + OpCooperativeMatrixTransposeNV = 5390, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpRawAccessChainNV = 5398, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpMemberDecorateString = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpCompositeConstructContinuedINTEL = 6096, + OpConvertFToBF16INTEL = 6116, + OpConvertBF16ToFINTEL = 6117, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpArithmeticFenceEXT = 6145, + OpSubgroupBlockPrefetchINTEL = 6221, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMaskedGatherINTEL = 6428, + OpMaskedScatterINTEL = 6429, + OpShaderSDSL = 8000, + OpCompositionSDSL = 8002, + OpCompositionEndSDSL = 8003, + OpMixinInheritSDSL = 8004, + OpImportShaderSDSL = 8007, + OpImportFunctionSDSL = 8008, + OpImportVariableSDSL = 8009, + OpImportStructSDSL = 8010, + OpVariableSDSL = 8011, + OpMemberAccessSDSL = 8012, + OpTypeFunctionSDSL = 8013, + OpFunctionMetadataSDSL = 8014, + OpBaseSDSL = 8015, + OpThisSDSL = 8016, + OpStreamsSDSL = 8018, + OpGenericParameterSDSL = 8019, + OpGenericReferenceSDSL = 8020, + OpConstantStringSDSL = 8021, + OpTypeGenericSDSL = 8022, + OpTypeStreamsSDSL = 8023, + OpTypeGeometryStreamOutputSDSL = 8024, + OpTypePatchSDSL = 8025, + OpForeachSDSL = 8026, + OpForeachEndSDSL = 8027, + OpUnresolvableShaderSDSL = 8028, + OpEmitVertexSDSL = 8029, + OpBinaryOperationSDSL = 8030, + OpSourceHashSDSL = 8031, + OpEffectSDFX = 9000, + OpParamsUseSDFX = 9001, + OpParamsSDFX = 9002, + OpParamsFieldSDFX = 9003, + OpMixinSDFX = 9004, + } + + public enum GLSLOp : int + { + GLSLRound = 1, + GLSLRoundEven = 2, + GLSLTrunc = 3, + GLSLFAbs = 4, + GLSLSAbs = 5, + GLSLFSign = 6, + GLSLSSign = 7, + GLSLFloor = 8, + GLSLCeil = 9, + GLSLFract = 10, + GLSLRadians = 11, + GLSLDegrees = 12, + GLSLSin = 13, + GLSLCos = 14, + GLSLTan = 15, + GLSLAsin = 16, + GLSLAcos = 17, + GLSLAtan = 18, + GLSLSinh = 19, + GLSLCosh = 20, + GLSLTanh = 21, + GLSLAsinh = 22, + GLSLAcosh = 23, + GLSLAtanh = 24, + GLSLAtan2 = 25, + GLSLPow = 26, + GLSLExp = 27, + GLSLLog = 28, + GLSLExp2 = 29, + GLSLLog2 = 30, + GLSLSqrt = 31, + GLSLInverseSqrt = 32, + GLSLDeterminant = 33, + GLSLMatrixInverse = 34, + GLSLModf = 35, + GLSLModfStruct = 36, + GLSLFMin = 37, + GLSLUMin = 38, + GLSLSMin = 39, + GLSLFMax = 40, + GLSLUMax = 41, + GLSLSMax = 42, + GLSLFClamp = 43, + GLSLUClamp = 44, + GLSLSClamp = 45, + GLSLFMix = 46, + GLSLIMix = 47, + GLSLStep = 48, + GLSLSmoothStep = 49, + GLSLFma = 50, + GLSLFrexp = 51, + GLSLFrexpStruct = 52, + GLSLLdexp = 53, + GLSLPackSnorm4x8 = 54, + GLSLPackUnorm4x8 = 55, + GLSLPackSnorm2x16 = 56, + GLSLPackUnorm2x16 = 57, + GLSLPackHalf2x16 = 58, + GLSLPackDouble2x32 = 59, + GLSLUnpackSnorm2x16 = 60, + GLSLUnpackUnorm2x16 = 61, + GLSLUnpackHalf2x16 = 62, + GLSLUnpackSnorm4x8 = 63, + GLSLUnpackUnorm4x8 = 64, + GLSLUnpackDouble2x32 = 65, + GLSLLength = 66, + GLSLDistance = 67, + GLSLCross = 68, + GLSLNormalize = 69, + GLSLFaceForward = 70, + GLSLReflect = 71, + GLSLRefract = 72, + GLSLFindILsb = 73, + GLSLFindSMsb = 74, + GLSLFindUMsb = 75, + GLSLInterpolateAtCentroid = 76, + GLSLInterpolateAtSample = 77, + GLSLInterpolateAtOffset = 78, + GLSLNMin = 79, + GLSLNMax = 80, + GLSLNClamp = 81, + } +} \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj index 8e54e9867a..d8b417b18b 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj @@ -1,4 +1,4 @@ - + true @@ -7,26 +7,11 @@ enable enable * - - $(WarningsAsErrors);CS8785 + - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs new file mode 100644 index 0000000000..7c07029061 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs @@ -0,0 +1,113 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) +// Copyright (c) Stride contributors (https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using Stride.Shaders.Spirv.Generators; + +// Pinned upstream refs (tag or SHA). Bump these (and re-run the tool) to refresh Generated/*.cs. +// SPIRV-Headers ships vulkan-sdk-* tags; SPIRV-Registry has no tags so we pin a SHA. +const string SpirvHeadersRef = "vulkan-sdk-1.4.304.0"; +const string SpirvRegistryRef = "a74197a3f0d5400764ce3bec2880f06e27b7b5d3"; + +// Files pulled from KhronosGroup/SPIRV-Headers @ SpirvHeadersRev, under include/spirv/unified1/ +string[] spirvHeadersFiles = +[ + "spirv.json", + "spirv.core.grammar.json", + "extinst.glsl.std.450.grammar.json", + "extinst.opencl.std.100.grammar.json", + "extinst.spv-amd-gcn-shader.grammar.json", + "extinst.spv-amd-shader-ballot.grammar.json", + "extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json", + "extinst.spv-amd-shader-trinary-minmax.grammar.json", +]; + +// Files pulled from KhronosGroup/Registry-Root-SPIR-V @ SpirvRegistryRev, under specs/unified1/ +string[] spirvRegistryFiles = +[ + "SPIRV.html", + "GLSL.std.450.html", +]; + +string? outputDir = null; +string? extraGrammarPath = null; +for (int i = 0; i < args.Length; i++) +{ + switch (args[i]) + { + case "--output" or "-o" when i + 1 < args.Length: + outputDir = args[++i]; + break; + case "--extra" when i + 1 < args.Length: + extraGrammarPath = args[++i]; + break; + case "--help" or "-h": + PrintUsage(); + return 0; + default: + Console.Error.WriteLine($"Unknown argument: {args[i]}"); + PrintUsage(); + return 1; + } +} + +if (outputDir is null) +{ + Console.Error.WriteLine("Missing --output"); + PrintUsage(); + return 1; +} + +// Local cache: %TEMP%/stride-spv-grammar// +var cacheRoot = Path.Combine(Path.GetTempPath(), "stride-spv-grammar"); +using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) }; + +var files = new List(); +foreach (var name in spirvHeadersFiles) + files.Add(await FetchAsync( + $"https://raw.githubusercontent.com/KhronosGroup/SPIRV-Headers/{SpirvHeadersRef}/include/spirv/unified1/{name}", + SpirvHeadersRef, name)); +foreach (var name in spirvRegistryFiles) + files.Add(await FetchAsync( + $"https://raw.githubusercontent.com/KhronosGroup/Registry-Root-SPIR-V/{SpirvRegistryRef}/specs/unified1/{name}", + SpirvRegistryRef, name)); + +if (extraGrammarPath is not null) +{ + if (!File.Exists(extraGrammarPath)) + { + Console.Error.WriteLine($"--extra file not found: {extraGrammarPath}"); + return 1; + } + files.Add(new SpvInputFile(extraGrammarPath, File.ReadAllText(extraGrammarPath))); +} + +var sink = new DiskSpvOutput(outputDir); +SPVGenerator.Run(files, sink); +Console.WriteLine($"Wrote generated files to {outputDir}"); +return 0; + +async Task FetchAsync(string url, string @ref, string fileName) +{ + // Replace path-unfriendly chars in ref (slashes from branch names etc.) + var safeRef = @ref.Replace('/', '_').Replace('\\', '_'); + var cachePath = Path.Combine(cacheRoot, safeRef, fileName); + if (!File.Exists(cachePath)) + { + Directory.CreateDirectory(Path.GetDirectoryName(cachePath)!); + Console.WriteLine($" Fetching {url}"); + var bytes = await http.GetByteArrayAsync(url); + File.WriteAllBytes(cachePath, bytes); + } + return new SpvInputFile(cachePath, File.ReadAllText(cachePath)); +} + +void PrintUsage() +{ + Console.WriteLine("Usage: Stride.Shaders.Spirv.Generators --output [--extra ]"); + Console.WriteLine(); + Console.WriteLine(" --output Directory where generated .cs files are written"); + Console.WriteLine(" --extra Optional Stride-specific grammar extension JSON"); + Console.WriteLine(); + Console.WriteLine($" Pinned: SPIRV-Headers {SpirvHeadersRef}, Registry-Root-SPIR-V {SpirvRegistryRef[..7]}"); +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Properties/launchSettings.json b/sources/shaders/Stride.Shaders.Spirv.Generators/Properties/launchSettings.json new file mode 100644 index 0000000000..6ad8227c10 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Regen Stride.Shaders.Spirv.Core": { + "commandName": "Project", + "commandLineArgs": "--output ../Stride.Shaders.Spirv.Core/Generated --extra ../Stride.Shaders.Spirv.Core/Extensions/spirv.sdsl.grammar-ext.json" + } + } +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs index 7cc1ec1464..234e82273c 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.EnumerantParams.cs @@ -2,54 +2,41 @@ using AngleSharp.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; using System.Text; namespace Stride.Shaders.Spirv.Generators; -public partial class SPVGenerator : IIncrementalGenerator +public partial class SPVGenerator { - - public void CreateEnumerantParameters(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) - { - context.RegisterSourceOutput( - grammarProvider, - GenerateEnumerantParameters - ); - } - - public static void GenerateEnumerantParameters(SourceProductionContext spc, SpirvGrammar grammar) + public static void GenerateEnumerantParameters(ISpvOutput spc, SpirvGrammar grammar) { if (grammar.OperandKinds?.AsDictionary()?.Values?.ToList() is List opkinds) { spc.AddSource( $"EnumerantParameters.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(@$" - using static Stride.Shaders.Spirv.Specification; - using CommunityToolkit.HighPerformance; - using CommunityToolkit.HighPerformance.Buffers; - using Stride.Shaders.Spirv.Core.Buffers; - - namespace Stride.Shaders.Spirv.Core; - - {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateEnumerantParameterSingle(i, grammar)))} - - public ref partial struct EnumerantParameters - {{ - {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateImplicitCasting(i, grammar)))} - {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).SelectMany(k => k.Enumerants?.AsList() ?? []).Select(e => e.Parameters) - .Select(p => new EquatableList(p?.AsList().Select(x => x.Kind.ToCSType()).ToList() ?? [])) - .Where(p => p.Count > 1) - .Distinct() - .Select(i => GenerateImplicitTuples(i, grammar)))} - }} - ") - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) + SyntaxFactory + .ParseCompilationUnit(@$" + using static Stride.Shaders.Spirv.Specification; + using CommunityToolkit.HighPerformance; + using CommunityToolkit.HighPerformance.Buffers; + using Stride.Shaders.Spirv.Core.Buffers; + + namespace Stride.Shaders.Spirv.Core; + + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateEnumerantParameterSingle(i, grammar)))} + + public ref partial struct EnumerantParameters + {{ + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).Select(i => GenerateImplicitCasting(i, grammar)))} + {string.Join("\n", opkinds.Where(k => (k.Enumerants?.AsList() ?? []).Any(e => (e.Parameters?.AsList() ?? []).Count > 0)).SelectMany(k => k.Enumerants?.AsList() ?? []).Select(e => e.Parameters) + .Select(p => new EquatableList(p?.AsList().Select(x => x.Kind.ToCSType()).ToList() ?? [])) + .Where(p => p.Count > 1) + .Distinct() + .Select(i => GenerateImplicitTuples(i, grammar)))} + }} + ") + .NormalizeWhitespace() + .ToFullString() ); } } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs deleted file mode 100644 index 5960acccd4..0000000000 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Extensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; - -namespace Stride.Shaders.Spirv.Generators; - - -public static class SpirvGeneratorExtensions -{ - public static SourceText ToSourceText(this StringBuilder builder) - { - return SourceText.From( - SyntaxFactory - .ParseCompilationUnit(builder.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ); - - } -} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 5c643dce87..98268ba7f9 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -4,13 +4,12 @@ using AngleSharp; using AngleSharp.Common; using AngleSharp.Dom; -using Microsoft.CodeAnalysis; namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator { - static readonly string[] RequiredFiles = + internal static readonly string[] RequiredFiles = [ "spirv.core.grammar.json", "spirv.sdsl.grammar-ext.json", @@ -19,22 +18,21 @@ public partial class SPVGenerator "GLSL.std.450.html" ]; - public static bool IsSpirvSpecification(AdditionalText file) + public static bool IsSpirvSpecification(SpvInputFile file) => Array.IndexOf(RequiredFiles, Path.GetFileName(file.Path)) >= 0; - public SpirvGrammar PreProcessGrammar(ImmutableArray files, CancellationToken _) + public SpirvGrammar PreProcessGrammar(ImmutableArray files, CancellationToken _) { - // Note: Missing files are reported as SPV0001 via the RegisterSourceOutput check in Initialize SpirvGrammar grammar = new(); foreach (var file in files) { if (Path.GetFileName(file.Path) == "SPIRV.html") - grammar.CoreDoc = file.GetText()?.ToString() ?? ""; + grammar.CoreDoc = file.Text; else if (Path.GetFileName(file.Path) == "GLSL.std.450.html") - grammar.GLSLDoc = file.GetText()?.ToString() ?? ""; + grammar.GLSLDoc = file.Text; else { - var parsed = JsonSerializer.Deserialize(file.GetText()?.ToString() ?? "{}", options); + var parsed = JsonSerializer.Deserialize(file.Text, options); if (grammar.MagicNumber == "" && parsed.MagicNumber != "") { grammar.MagicNumber = parsed!.MagicNumber; diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs index 8847293a59..00b1cbde36 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Info.cs @@ -1,6 +1,5 @@ -using Microsoft.CodeAnalysis; -using System.Text; -using Microsoft.CodeAnalysis.Text; +using System.Text; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System; @@ -8,26 +7,7 @@ namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator { - - public void CreateParameterizedFuncs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) - { - - context.RegisterSourceOutput( - grammarProvider, - GenerateParameterizedFunctions - ); - } - public void CreateInfo(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) - { - - GenerateKinds(context, grammarProvider); - context.RegisterSourceOutput( - grammarProvider, - GenerateInstructionInformation - ); - } - - public void GenerateParameterizedFunctions(SourceProductionContext context, SpirvGrammar grammar) + public static void GenerateParameterizedFunctions(ISpvOutput context, SpirvGrammar grammar) { if (grammar.OperandKinds?.AsDictionary() is Dictionary dict) { @@ -69,18 +49,15 @@ public static class ParameterizedFlags code.AppendLine("}"); context.AddSource( "ParameterizedFlags.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString() ); } } - static void GenerateInstructionInformation(SourceProductionContext spc, SpirvGrammar grammar) + public static void GenerateInstructionInformation(ISpvOutput spc, SpirvGrammar grammar) { var code = new StringBuilder(); code @@ -101,90 +78,61 @@ static InstructionInfo() code.AppendLine("Instance.InitOrder();}}"); spc.AddSource( "InstructionInfo.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString() ); } - private void GenerateKinds(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) + public static void GenerateKinds(ISpvOutput spc, SpirvGrammar grammar) { - var kindsProvider = grammarProvider - .Select(static (grammar, _) => grammar.OperandKinds!.Value); - - context.RegisterSourceOutput(kindsProvider, - static (spc, kinds) => - { - var builder = new StringBuilder(); - if (kinds.AsDictionary() is Dictionary dict) - { - builder - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public enum OperandKind") - .AppendLine("{") - .AppendLine(" None,"); - foreach (var kind in dict.Values) - builder.AppendLine($" {kind.Kind},"); - builder - .AppendLine("}"); - - builder.AppendLine() - .AppendLine("public static class OperandKindExtensions") - .AppendLine("{") - .AppendLine("public static bool IsEnum(this OperandKind kind)") - .AppendLine("{") - .AppendLine("return kind switch") - .AppendLine("{"); - foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) - builder.AppendLine($" OperandKind.{kind.Kind} => true,"); - builder.AppendLine(" _ => false") - .AppendLine("};") - .AppendLine("}") - .AppendLine("public static string? ConvertEnumValueToString(this OperandKind kind, int value)") - .AppendLine("{") - .AppendLine("return kind switch") - .AppendLine("{"); - foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) - builder.AppendLine($" OperandKind.{kind.Kind} => (({kind.Kind}{(kind.Category is "BitEnum" ? "Mask" : "")})value).ToString(),"); - builder.AppendLine(" _ => null") - .AppendLine("};") - .AppendLine("}") - .AppendLine("}"); - } - spc.AddSource("OperandKind.gen.cs", SourceText.From( - SyntaxFactory - .ParseCompilationUnit(builder.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - )); - } + var kinds = grammar.OperandKinds!.Value; + var builder = new StringBuilder(); + if (kinds.AsDictionary() is Dictionary dict) + { + builder + .AppendLine("using static Stride.Shaders.Spirv.Specification;") + .AppendLine("") + .AppendLine("namespace Stride.Shaders.Spirv.Core;") + .AppendLine("") + .AppendLine("public enum OperandKind") + .AppendLine("{") + .AppendLine(" None,"); + foreach (var kind in dict.Values) + builder.AppendLine($" {kind.Kind},"); + builder + .AppendLine("}"); + + builder.AppendLine() + .AppendLine("public static class OperandKindExtensions") + .AppendLine("{") + .AppendLine("public static bool IsEnum(this OperandKind kind)") + .AppendLine("{") + .AppendLine("return kind switch") + .AppendLine("{"); + foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) + builder.AppendLine($" OperandKind.{kind.Kind} => true,"); + builder.AppendLine(" _ => false") + .AppendLine("};") + .AppendLine("}") + .AppendLine("public static string? ConvertEnumValueToString(this OperandKind kind, int value)") + .AppendLine("{") + .AppendLine("return kind switch") + .AppendLine("{"); + foreach (var kind in dict.Values.Where(k => k.Category.EndsWith("Enum"))) + builder.AppendLine($" OperandKind.{kind.Kind} => (({kind.Kind}{(kind.Category is "BitEnum" ? "Mask" : "")})value).ToString(),"); + builder.AppendLine(" _ => null") + .AppendLine("};") + .AppendLine("}") + .AppendLine("}"); + } + spc.AddSource("OperandKind.gen.cs", + SyntaxFactory + .ParseCompilationUnit(builder.ToString()) + .NormalizeWhitespace() + .ToFullString() ); - // var code = new StringBuilder() - // .AppendLine("using static Stride.Shaders.Spirv.Specification;") - // .AppendLine("") - // .AppendLine("namespace Stride.Shaders.Spirv.Core;") - // .AppendLine("\n\n") - // .AppendLine("public enum OperandKind") - // .AppendLine("{") - - // .AppendLine("None = 0,"); - // var kinds = spirvCore!.OperandKinds.Select(x => x.Kind); - // foreach (var kind in kinds) - // { - // code.Append(kind).AppendLine(","); - // } - // code.AppendLine("}"); - - // context.RegisterPostInitializationOutput(ctx => ctx.AddSource("OperandKind.gen.cs", code.ToSourceText())); - } public static void GenerateInfo(InstructionData op, StringBuilder code, SpirvGrammar grammar) diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs index 9c0de21016..9433d35d6d 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Instructions.cs @@ -1,7 +1,6 @@ using AngleSharp.Common; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.Text; using System.Collections.Concurrent; using System.Dynamic; using System.Text; @@ -9,7 +8,7 @@ namespace Stride.Shaders.Spirv.Generators; -public partial class SPVGenerator : IIncrementalGenerator +public partial class SPVGenerator { internal class StringBuilderPool { @@ -24,42 +23,31 @@ public static StringBuilder Get() } public static void Return(StringBuilder builder) => Instance.pool.Add(builder); } - public void GenerateStructs(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) - { - context.RegisterImplementationSourceOutput( - grammarProvider, - GenerateInstructionStructs - ); - - } - public static void GenerateInstructionStructs(SourceProductionContext spc, SpirvGrammar grammar) + public static void GenerateInstructionStructs(ISpvOutput spc, SpirvGrammar grammar) { if (grammar.Instructions?.AsList() is List instructions) { spc.AddSource( $"Instructions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(@$" - #pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. - - using static Stride.Shaders.Spirv.Specification; - using CommunityToolkit.HighPerformance; - using CommunityToolkit.HighPerformance.Buffers; - using Stride.Shaders.Spirv.Core.Buffers; - using System.Numerics; - using System.Runtime.CompilerServices; - - namespace Stride.Shaders.Spirv.Core; - - {string.Join("\n", instructions.Select(i => GenerateInstructionStructsSingle(i, grammar)))} - - ") - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) + SyntaxFactory + .ParseCompilationUnit(@$" + #pragma warning disable CS9264 // Non-nullable property must contain a non-null value when exiting constructor. Consider adding the 'required' modifier, or declaring the property as nullable, or safely handling the case where 'field' is null in the 'get' accessor. + + using static Stride.Shaders.Spirv.Specification; + using CommunityToolkit.HighPerformance; + using CommunityToolkit.HighPerformance.Buffers; + using Stride.Shaders.Spirv.Core.Buffers; + using System.Numerics; + using System.Runtime.CompilerServices; + + namespace Stride.Shaders.Spirv.Core; + + {string.Join("\n", instructions.Select(i => GenerateInstructionStructsSingle(i, grammar)))} + + ") + .NormalizeWhitespace() + .ToFullString() ); } } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs index 9f18159358..d7f7f71b68 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.SDSLOp.cs @@ -1,5 +1,4 @@ -using Microsoft.CodeAnalysis; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -9,35 +8,19 @@ using System.Reflection; using System.Text.Json; using System.Security.Claims; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp; using AngleSharp.Common; -using Microsoft.CodeAnalysis.Text; using System.Dynamic; namespace Stride.Shaders.Spirv.Generators; public partial class SPVGenerator { - public void CreateSDSLOp(IncrementalGeneratorInitializationContext context, IncrementalValueProvider grammarProvider) + public static void ExecuteSDSLOpCreation(ISpvOutput ctx, SpirvGrammar grammar) { - - var instructionsProvider = - grammarProvider - .SelectMany(static (grammar, b) => grammar.Instructions?.AsList() ?? []) - .Where(static x => x.OpName is not null) - .Collect() - .Select(static (arr, _) => new EquatableList([.. arr])); - - context.RegisterSourceOutput( - instructionsProvider, - ExecuteSDSLOpCreation - ); - - } - public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList instructionArray) - { - + var instructionArray = grammar.Instructions?.AsList()?.Where(x => x.OpName is not null).ToList() ?? []; var members = instructionArray.ToDictionary(x => x.OpName, y => y.OpCode)!; int lastnum = 0; @@ -78,13 +61,10 @@ public void ExecuteSDSLOpCreation(SourceProductionContext ctx, EquatableList grammarProvider) - { - var sdsloProvider = grammarProvider - .Select(static (grammar, _) => grammar); - - context.RegisterSourceOutput( - sdsloProvider, - GenerateSDSLSpecification - ); - } - public void GenerateSDSLSpecification(SourceProductionContext spc, SpirvGrammar grammar) + public static void GenerateSDSLSpecification(ISpvOutput spc, SpirvGrammar grammar) { var code = new StringBuilder(); code @@ -58,13 +47,10 @@ public void GenerateSDSLSpecification(SourceProductionContext spc, SpirvGrammar spc.AddSource( "SDSLSpecification.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) + SyntaxFactory + .ParseCompilationUnit(code.ToString()) + .NormalizeWhitespace() + .ToFullString() ); } } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 82a667ad88..2005e0ea38 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -1,26 +1,17 @@ -using Microsoft.CodeAnalysis; -using System.Text; +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) +// Copyright (c) Stride contributors (https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System.Collections.Immutable; using System.Text.Json; -using Microsoft.CodeAnalysis.Text; -using Microsoft.CodeAnalysis.CSharp; namespace Stride.Shaders.Spirv.Generators; - -[Generator] -public partial class SPVGenerator : IIncrementalGenerator +public partial class SPVGenerator { static readonly JsonSerializerOptions options = new(); - internal static readonly DiagnosticDescriptor MissingSpecDiagnostic = new( - id: "SPV0001", - title: "Missing SPIR-V specification files", - messageFormat: "Missing SPIR-V specification files: {0}. Run 'git submodule update --init --recursive'.", - category: "SpirvGenerator", - defaultSeverity: DiagnosticSeverity.Error, - isEnabledByDefault: true); - - public void Initialize(IncrementalGeneratorInitializationContext context) + public static void Run(IReadOnlyList files, ISpvOutput output) { if (!options.Converters.Any(x => x is EquatableListJsonConverter)) options.Converters.Add(new EquatableListJsonConverter()); @@ -34,89 +25,25 @@ public void Initialize(IncrementalGeneratorInitializationContext context) options.Converters.Add(new EquatableListJsonConverter()); if (!options.Converters.Any(x => x is EquatableListJsonConverter)) options.Converters.Add(new EquatableListJsonConverter()); - var files = - context - .AdditionalTextsProvider - .Where(IsSpirvSpecification) - .Collect(); - - // Emit SPV0001 if any required grammar file is missing (submodule not fetched). - context.RegisterSourceOutput(files, static (spc, texts) => - { - var fileNames = new HashSet(texts.Select(f => Path.GetFileName(f.Path))); - var missing = RequiredFiles.Where(r => !fileNames.Contains(r)).ToArray(); - if (missing.Length > 0) - spc.ReportDiagnostic(Diagnostic.Create(MissingSpecDiagnostic, Location.None, string.Join(", ", missing))); - }); - - var grammarData = - files - .Select(PreProcessGrammar) - .Select(PreProcessEnumerants) - .Select(PreProcessInstructions); - - CreateEnumerantParameters(context, grammarData); - CreateInfo(context, grammarData); - CreateSDSLOp(context, grammarData); - GenerateStructs(context, grammarData); - CreateSpecification(context, grammarData); - - // context.RegisterImplementationSourceOutput( - // grammarData, - // BufferGeneration - // ); - + var filtered = files.Where(IsSpirvSpecification).ToImmutableArray(); + var presentNames = new HashSet(filtered.Select(f => Path.GetFileName(f.Path))); + var missing = RequiredFiles.Where(r => !presentNames.Contains(r)).ToArray(); + if (missing.Length > 0) + throw new InvalidOperationException( + $"Missing SPIR-V specification files: {string.Join(", ", missing)}. " + + "Run 'git submodule update --init --recursive'."); + + var gen = new SPVGenerator(); + var grammar = gen.PreProcessGrammar(filtered, default); + grammar = gen.PreProcessEnumerants(grammar, default); + grammar = gen.PreProcessInstructions(grammar, default); + + GenerateEnumerantParameters(output, grammar); + GenerateKinds(output, grammar); + GenerateInstructionInformation(output, grammar); + ExecuteSDSLOpCreation(output, grammar); + GenerateInstructionStructs(output, grammar); + GenerateSDSLSpecification(output, grammar); } - - public static void BufferGeneration(SourceProductionContext spc, SpirvGrammar source) - { - - try - { - var code = new StringBuilder(); - code - .AppendLine("using static Stride.Shaders.Spirv.Specification;") - .AppendLine("using Stride.Shaders.Spirv.Core.Buffers;") - .AppendLine("") - .AppendLine("namespace Stride.Shaders.Spirv.Core;") - .AppendLine("") - .AppendLine("public static class SpirvBufferExtensions") - .AppendLine("{"); - foreach (var instruction in source.Instructions?.AsList() ?? []) - { - if (instruction.OpName.StartsWith("Op")) - CreateOperation(instruction, code, source.OperandKinds?.AsDictionary() ?? []); - else - CreateGlslOperation(instruction, code, source.OperandKinds?.AsDictionary() ?? []); - } - code - .AppendLine("}"); - - spc.AddSource("SpirvBufferExtensions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit(code.ToString()) - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - } - catch (Exception ex) - { - spc.AddSource("SpirvBufferExtensions.gen.cs", - SourceText.From( - SyntaxFactory - .ParseCompilationUnit($"/* Error generating SpirvBufferExtensions: {ex.Message} */") - .NormalizeWhitespace() - .ToFullString(), - Encoding.UTF8 - ) - ); - } - - } - - } diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs new file mode 100644 index 0000000000..e2ed6913f3 --- /dev/null +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) +// Copyright (c) Stride contributors (https://stride3d.net) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +namespace Stride.Shaders.Spirv.Generators; + +public interface ISpvOutput +{ + void AddSource(string hint, string source); +} + +public sealed record SpvInputFile(string Path, string Text); + +public sealed class DiskSpvOutput(string outputDir) : ISpvOutput +{ + public string OutputDir { get; } = outputDir; + + public void AddSource(string hint, string source) + { + Directory.CreateDirectory(OutputDir); + File.WriteAllText(System.IO.Path.Combine(OutputDir, hint), source); + } +} diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj index 4577a57a01..06ba6058e3 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Stride.Shaders.Spirv.Generators.csproj @@ -1,13 +1,12 @@ - netstandard2.0 + net10.0 + Exe latest enable enable - true - - $(NoWarn);RS2008 + Stride.Shaders.Spirv.Generators @@ -15,35 +14,8 @@ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + - - $(GetTargetPathDependsOn);GetDependencyTargetPaths - - - - - - - - - - - - - - - From c0bd54d6099db41a6f9aced9cf5a27d82211dfd7 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Tue, 12 May 2026 19:03:35 +0900 Subject: [PATCH 1174/1182] shaders: fix copyright header + stale submodule message in SPV tool --- sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs | 3 +-- .../SPVGenerator.Helpers.Preprocessing.cs | 2 +- .../shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs | 5 ++--- sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs index 7c07029061..e602e381d7 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/Program.cs @@ -1,5 +1,4 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) -// Copyright (c) Stride contributors (https://stride3d.net) +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using Stride.Shaders.Spirv.Generators; diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs index 98268ba7f9..2e35b6a0c7 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.Helpers.Preprocessing.cs @@ -126,7 +126,7 @@ public SpirvGrammar PreProcessInstructions(SpirvGrammar grammar, CancellationTok var extinst = instructions.FirstOrDefault(x => x.OpName == "OpExtInst"); if (extinst.OpName is null) throw new InvalidOperationException( - "OpExtInst not found in SPIR-V grammar. Ensure git submodules are fetched (git submodule update --init). " + "OpExtInst not found in SPIR-V grammar. Check the fetch list in Program.cs. " + $"Found {instructions.Count} instructions: [{string.Join(", ", instructions.Take(5).Select(x => x.OpName))}...]"); // Prebuilt for fast lookup var tableblocksCore = coreDoc!.QuerySelectorAll($"p.tableblock").ToArray(); diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs index 2005e0ea38..5a41123270 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SPVGenerator.cs @@ -1,5 +1,4 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) -// Copyright (c) Stride contributors (https://stride3d.net) +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. using System.Collections.Immutable; @@ -32,7 +31,7 @@ public static void Run(IReadOnlyList files, ISpvOutput output) if (missing.Length > 0) throw new InvalidOperationException( $"Missing SPIR-V specification files: {string.Join(", ", missing)}. " - + "Run 'git submodule update --init --recursive'."); + + "Check the fetch list in Program.cs."); var gen = new SPVGenerator(); var grammar = gen.PreProcessGrammar(filtered, default); diff --git a/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs b/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs index e2ed6913f3..8137617dff 100644 --- a/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs +++ b/sources/shaders/Stride.Shaders.Spirv.Generators/SpvIO.cs @@ -1,5 +1,4 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org) -// Copyright (c) Stride contributors (https://stride3d.net) +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. namespace Stride.Shaders.Spirv.Generators; From 8d08a96af7147acb615ed2fde994346d6988caa2 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 13 May 2026 11:15:01 +0900 Subject: [PATCH 1175/1182] build: strip unused ComInterfaceGenerator from all projects --- sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets index 03937a6f68..c5f66c8d31 100644 --- a/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets +++ b/sources/sdk/Stride.Build.Sdk/Sdk/Sdk.targets @@ -272,6 +272,15 @@ + + + + + + + + + From f1e796f1ffd55c0313eb102ce20ee163ccab79a6 Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 13 May 2026 11:21:46 +0900 Subject: [PATCH 1176/1182] shaders/gen: scope VisitorGenerator to own assembly (~1s on Parsers) --- .../Stride.Shaders.Generators.Internal/VisitorGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs b/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs index 18e03e3b83..c42f0e82eb 100644 --- a/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs +++ b/sources/shaders/Stride.Shaders.Generators.Internal/VisitorGenerator.cs @@ -44,7 +44,7 @@ private string GenerateVisitSuffix(INamedTypeSymbol type) private void GenerateVisitorsBase(SourceProductionContext context, Compilation compilation, bool generateRewriter, string visitorName, Func isNodeType) { var classVisitor = new NodeTypeClassFinder(isNodeType); - classVisitor.Visit(compilation.GlobalNamespace); + classVisitor.Visit(compilation.Assembly.GlobalNamespace); var symbolTypes = classVisitor.SymbolTypes; From 4bdab26dbed8130494984f76926f2a9be9ae1e2e Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 13 May 2026 10:55:06 +0900 Subject: [PATCH 1177/1182] shaders: drop ILRepack from source generator, forward deps via TargetPathWithTargetPlatformMoniker --- .../Stride.Shaders.Compilers.csproj | 11 +++++- .../ILRepack.targets | 37 ------------------- .../Stride.Shaders.Generators.csproj | 24 +++++++++--- 3 files changed, 29 insertions(+), 43 deletions(-) delete mode 100644 sources/shaders/Stride.Shaders.Generators/ILRepack.targets diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index 93126b7ad5..c7650e0197 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -54,8 +54,17 @@ - + + $(TargetsForTfmSpecificContentInPackage);_PackGeneratorAnalyzerFiles + + + + + + \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Generators/ILRepack.targets b/sources/shaders/Stride.Shaders.Generators/ILRepack.targets deleted file mode 100644 index 3a2afde2cd..0000000000 --- a/sources/shaders/Stride.Shaders.Generators/ILRepack.targets +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - $([System.IO.Directory]::GetFiles("%(Directories.Identity)", "*", System.IO.SearchOption.AllDirectories).get_Length()) - - - - - - \ No newline at end of file diff --git a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj index 840af77942..2f079b2e38 100644 --- a/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj +++ b/sources/shaders/Stride.Shaders.Generators/Stride.Shaders.Generators.csproj @@ -10,14 +10,12 @@ true true false + + $(GetTargetPathDependsOn);GetDependencyTargetPaths + $(TargetsForTfmSpecificContentInPackage);_PackGeneratorAnalyzerFiles - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -26,4 +24,20 @@ + + + + + + + + + + + + From 152d15215a5c56e68eff9cc7b9677d0ad71b10ee Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Wed, 13 May 2026 12:39:12 +0900 Subject: [PATCH 1178/1182] shaders: split out Stride.Shaders.Effects, rename Spirv.Core to Spirv Drops source-generator analyzer load surface from 17 to 9 DLLs. --- build/Stride.Android.slnf | 3 ++- build/Stride.Runtime.slnf | 3 ++- build/Stride.iOS.slnf | 3 ++- build/Stride.sln | 15 +++++++++++++- .../Stride.Graphics/Stride.Graphics.csproj | 1 + .../Stride.Shaders.Compilers.csproj | 1 + .../Compiler/CompilerParameters.cs | 0 .../Compiler/CompilerResults.cs | 0 .../Compiler/EffectBytecodeCacheLoadSource.cs | 0 .../Compiler/EffectBytecodeCompilerResult.cs | 0 .../Compiler/EffectCompilerBase.cs | 0 .../Compiler/EffectCompilerCache.cs | 0 .../Compiler/EffectCompilerChain.cs | 0 .../Compiler/EffectCompilerParameters.cs | 0 .../Compiler/EffectPriorityScheduler.cs | 0 .../Compiler/IEffectCompiler.cs | 0 .../Compiler/NullEffectCompiler.cs | 0 .../Compiler/TaskOrResult.cs | 0 .../EffectBytecode.cs | 0 .../EffectConstantBufferDescription.cs | 0 .../EffectParameterKeyInfo.cs | 0 .../EffectReflection.cs | 0 .../EffectResourceBindingDescription.cs | 0 .../EffectResourceEntry.cs | 0 .../EffectResourceGroupDescription.cs | 0 .../EffectSamplerStateBinding.cs | 0 .../EffectSourceCodeKeys.cs | 0 .../EffectValueDescription.cs | 0 .../IShaderMixinBuilder.cs | 0 .../IShaderMixinBuilderExtended.cs | 0 .../ParameterKeyHashSerializer.cs | 0 .../ShaderMixinContext.cs | 0 .../ShaderMixinManager.cs | 0 .../ShaderMixinObjectId.cs | 0 .../ShaderMixinParameters.cs | 0 .../Stride.Shaders.Effects.csproj | 20 +++++++++++++++++++ .../Parsing/SDSL/AST/Shader.cs | 1 - .../Stride.Shaders.Parsers.csproj | 2 +- .../Buffers/IMemoryInstruction.cs | 0 .../Buffers/OpData.cs | 0 .../Buffers/OpDataIndex.cs | 0 .../Buffers/SpirvBuffer.cs | 0 .../Buffers/SpirvBytecode.cs | 0 .../Extensions/spirv.sdsl.grammar-ext.json | 0 .../Generated/EnumerantParameters.gen.cs | 0 .../Generated/InstructionInfo.gen.cs | 0 .../Generated/Instructions.gen.cs | 0 .../Generated/OperandKind.gen.cs | 0 .../Generated/SDSLSpecification.gen.cs | 0 .../Generated/SpecificationOp.gen.cs | 0 .../ISpirvElement.cs | 0 .../IWrapperInstruction.cs | 0 .../Information/InstructionInfo.Order.cs | 0 .../Information/InstructionInfo.cs | 0 .../Information/LogicalOperand.Size.cs | 0 .../Information/LogicalOperand.cs | 0 .../Information/LogicalOperandArray.cs | 0 .../Literals/EnumerantParameters.cs | 0 .../Literals/IFromSpirv.cs | 0 .../Literals/ILiteralNumber.cs | 0 .../Literals/IdMemorySemantics.cs | 0 .../Literals/IdRef.cs | 0 .../Literals/IdResult.cs | 0 .../Literals/IdResultType.cs | 0 .../Literals/IdScope.cs | 0 .../Literals/LiteralArray.cs | 0 .../Literals/LiteralFloat.cs | 0 .../Literals/LiteralInteger.cs | 0 .../Literals/LiteralString.cs | 0 .../Literals/LiteralValue.cs | 0 .../Literals/PairIdRefIdRef.cs | 0 .../Literals/PairIdRefLiteralInteger.cs | 0 .../Literals/PairLiteralIntegerIdRef.cs | 0 .../Literals/ParameterizedFlag.cs | 0 .../Literals/SpvOp.cs | 0 .../MemoryInstruction.cs | 0 .../OperandQuantifier.cs | 0 .../Parsing/InstructionEnumerator.cs | 0 .../Parsing/OpDataEnumerator.cs | 0 .../Parsing/OperandEnumerator.cs | 0 .../Parsing/RefHeader.cs | 0 .../Parsing/SpirvHeader.cs | 0 .../Parsing/SpirvReader.cs | 0 .../SpirvValue.cs | 0 .../SpvLiteral.cs | 0 .../Stride.Shaders.Spirv.csproj} | 0 .../WordsExtensions.cs | 0 .../shaders/Stride.Shaders/ShaderClassCode.cs | 1 - .../Stride.Shaders/ShaderClassSource.cs | 4 ---- .../Stride.Shaders/ShaderClassString.cs | 1 - sources/shaders/Stride.Shaders/ShaderMacro.cs | 1 - .../ShaderStreamOutputDeclarationEntry.cs | 1 - .../Stride.Shaders/Stride.Shaders.csproj | 2 +- 93 files changed, 44 insertions(+), 15 deletions(-) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/CompilerParameters.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/CompilerResults.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectBytecodeCacheLoadSource.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectBytecodeCompilerResult.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectCompilerBase.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectCompilerCache.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectCompilerChain.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectCompilerParameters.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/EffectPriorityScheduler.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/IEffectCompiler.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/NullEffectCompiler.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/Compiler/TaskOrResult.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectBytecode.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectConstantBufferDescription.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectParameterKeyInfo.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectReflection.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectResourceBindingDescription.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectResourceEntry.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectResourceGroupDescription.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectSamplerStateBinding.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectSourceCodeKeys.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/EffectValueDescription.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/IShaderMixinBuilder.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/IShaderMixinBuilderExtended.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/ParameterKeyHashSerializer.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/ShaderMixinContext.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/ShaderMixinManager.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/ShaderMixinObjectId.cs (100%) rename sources/shaders/{Stride.Shaders => Stride.Shaders.Effects}/ShaderMixinParameters.cs (100%) create mode 100644 sources/shaders/Stride.Shaders.Effects/Stride.Shaders.Effects.csproj rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Buffers/IMemoryInstruction.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Buffers/OpData.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Buffers/OpDataIndex.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Buffers/SpirvBuffer.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Buffers/SpirvBytecode.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Extensions/spirv.sdsl.grammar-ext.json (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/EnumerantParameters.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/InstructionInfo.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/Instructions.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/OperandKind.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/SDSLSpecification.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Generated/SpecificationOp.gen.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/ISpirvElement.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/IWrapperInstruction.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Information/InstructionInfo.Order.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Information/InstructionInfo.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Information/LogicalOperand.Size.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Information/LogicalOperand.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Information/LogicalOperandArray.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/EnumerantParameters.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IFromSpirv.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/ILiteralNumber.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IdMemorySemantics.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IdRef.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IdResult.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IdResultType.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/IdScope.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/LiteralArray.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/LiteralFloat.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/LiteralInteger.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/LiteralString.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/LiteralValue.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/PairIdRefIdRef.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/PairIdRefLiteralInteger.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/PairLiteralIntegerIdRef.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/ParameterizedFlag.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Literals/SpvOp.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/MemoryInstruction.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/OperandQuantifier.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/InstructionEnumerator.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/OpDataEnumerator.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/OperandEnumerator.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/RefHeader.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/SpirvHeader.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/Parsing/SpirvReader.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/SpirvValue.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/SpvLiteral.cs (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core/Stride.Shaders.Spirv.Core.csproj => Stride.Shaders.Spirv/Stride.Shaders.Spirv.csproj} (100%) rename sources/shaders/{Stride.Shaders.Spirv.Core => Stride.Shaders.Spirv}/WordsExtensions.cs (100%) diff --git a/build/Stride.Android.slnf b/build/Stride.Android.slnf index 3db845c146..f9a169f0c1 100644 --- a/build/Stride.Android.slnf +++ b/build/Stride.Android.slnf @@ -23,9 +23,10 @@ "..\\sources\\engine\\Stride.Video\\Stride.Video.csproj", "..\\sources\\engine\\Stride.VirtualReality\\Stride.VirtualReality.csproj", "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Effects\\Stride.Shaders.Effects.csproj", "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", - "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv\\Stride.Shaders.Spirv.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj" diff --git a/build/Stride.Runtime.slnf b/build/Stride.Runtime.slnf index ecc1a96a82..133766718c 100644 --- a/build/Stride.Runtime.slnf +++ b/build/Stride.Runtime.slnf @@ -24,9 +24,10 @@ "..\\sources\\engine\\Stride.Voxels\\Stride.Voxels.csproj", "..\\sources\\engine\\Stride\\Stride.csproj", "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Effects\\Stride.Shaders.Effects.csproj", "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", - "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv\\Stride.Shaders.Spirv.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj", diff --git a/build/Stride.iOS.slnf b/build/Stride.iOS.slnf index 3db845c146..f9a169f0c1 100644 --- a/build/Stride.iOS.slnf +++ b/build/Stride.iOS.slnf @@ -23,9 +23,10 @@ "..\\sources\\engine\\Stride.Video\\Stride.Video.csproj", "..\\sources\\engine\\Stride.VirtualReality\\Stride.VirtualReality.csproj", "..\\sources\\shaders\\Stride.Shaders\\Stride.Shaders.csproj", + "..\\sources\\shaders\\Stride.Shaders.Effects\\Stride.Shaders.Effects.csproj", "..\\sources\\shaders\\Stride.Shaders.Compilers\\Stride.Shaders.Compilers.csproj", "..\\sources\\shaders\\Stride.Shaders.Parsers\\Stride.Shaders.Parsers.csproj", - "..\\sources\\shaders\\Stride.Shaders.Spirv.Core\\Stride.Shaders.Spirv.Core.csproj", + "..\\sources\\shaders\\Stride.Shaders.Spirv\\Stride.Shaders.Spirv.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators\\Stride.Shaders.Generators.csproj", "..\\sources\\shaders\\Stride.Shaders.Generators.Internal\\Stride.Shaders.Generators.Internal.csproj", "..\\sources\\shaders\\Stride.Shaders.Spirv.Generators\\Stride.Shaders.Spirv.Generators.csproj" diff --git a/build/Stride.sln b/build/Stride.sln index 4a0ec24df2..11efa53fe0 100644 --- a/build/Stride.sln +++ b/build/Stride.sln @@ -139,6 +139,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Core.IO", "..\source EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders", "..\sources\shaders\Stride.Shaders\Stride.Shaders.csproj", "{273BDD15-7392-4078-91F0-AF23594A3D7B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Effects", "..\sources\shaders\Stride.Shaders.Effects\Stride.Shaders.Effects.csproj", "{3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Audio", "..\sources\engine\Stride.Audio\Stride.Audio.csproj", "{DE042125-C270-4D1D-9270-0759C167567A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride", "..\sources\engine\Stride\Stride.csproj", "{72390339-B2A1-4F61-A800-31ED0975B515}" @@ -315,7 +317,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Generators.I EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Generators", "..\sources\shaders\Stride.Shaders.Spirv.Generators\Stride.Shaders.Spirv.Generators.csproj", "{2618F6D9-685D-FDE1-B467-84BC8C858F51}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv.Core", "..\sources\shaders\Stride.Shaders.Spirv.Core\Stride.Shaders.Spirv.Core.csproj", "{7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Spirv", "..\sources\shaders\Stride.Shaders.Spirv\Stride.Shaders.Spirv.csproj", "{7B8E1D5D-64B3-B768-B2EB-EF2B27DDE2BB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Shaders.Tests", "..\sources\shaders\Stride.Shaders.Tests\Stride.Shaders.Tests.csproj", "{137B0DE2-10F3-3496-6A5B-D3FE538BAA7B}" EndProject @@ -585,6 +587,16 @@ Global {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|Mixed Platforms.Build.0 = Release|Any CPU {273BDD15-7392-4078-91F0-AF23594A3D7B}.Release|Win32.ActiveCfg = Release|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Debug|Win32.ActiveCfg = Debug|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Release|Any CPU.Build.0 = Release|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9}.Release|Win32.ActiveCfg = Release|Any CPU {DE042125-C270-4D1D-9270-0759C167567A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DE042125-C270-4D1D-9270-0759C167567A}.Debug|Any CPU.Build.0 = Debug|Any CPU {DE042125-C270-4D1D-9270-0759C167567A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU @@ -1613,6 +1625,7 @@ Global {1320F627-EE43-4115-8E89-19D1753E51F2} = {2E93E2B5-4500-4E47-9B65-E705218AB578} {1DE01410-22C9-489B-9796-1ADDAB1F64E5} = {2E93E2B5-4500-4E47-9B65-E705218AB578} {273BDD15-7392-4078-91F0-AF23594A3D7B} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} + {3D415F8D-6729-4FC9-82E2-BEA7D76C75C9} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} {DE042125-C270-4D1D-9270-0759C167567A} = {4C142567-C42B-40F5-B092-798882190209} {72390339-B2A1-4F61-A800-31ED0975B515} = {4C142567-C42B-40F5-B092-798882190209} {E8B3553F-A79F-4E50-B75B-ACEE771C320C} = {7E3ACF35-0CCA-4E88-866B-0F008C5A5580} diff --git a/sources/engine/Stride.Graphics/Stride.Graphics.csproj b/sources/engine/Stride.Graphics/Stride.Graphics.csproj index 7fa99491e6..f9eebc4829 100644 --- a/sources/engine/Stride.Graphics/Stride.Graphics.csproj +++ b/sources/engine/Stride.Graphics/Stride.Graphics.csproj @@ -37,6 +37,7 @@ true + diff --git a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj index c7650e0197..689a84d6a3 100644 --- a/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj +++ b/sources/shaders/Stride.Shaders.Compilers/Stride.Shaders.Compilers.csproj @@ -22,6 +22,7 @@ +